From cdcfb7036097c8eb85cd9e66885cc7883aa68b13 Mon Sep 17 00:00:00 2001
From: adrpo <adrpo@20e99eb2-9666-4e79-a4bd-0251279e2d9b>
Date: Sat, 10 Dec 2016 02:06:53 +0000
Subject: [PATCH] - add numpy to OMDev so that one can use the script that
 transforms Buildings reference files to csv

git-svn-id: https://openmodelica.org/svn/OpenModelicaExternal/trunk@198 20e99eb2-9666-4e79-a4bd-0251279e2d9b
---
 tools/msys/mingw32/bin/f2py2.py               |   28 +
 .../python2.7/numpy/__multiarray_api.h        | 1540 ++++
 .../include/python2.7/numpy/__ufunc_api.h     |  320 +
 .../numpy/_neighborhood_iterator_imp.h        |   90 +
 .../include/python2.7/numpy/_numpyconfig.h    |   31 +
 .../include/python2.7/numpy/arrayobject.h     |   11 +
 .../include/python2.7/numpy/arrayscalars.h    |  175 +
 .../include/python2.7/numpy/halffloat.h       |   70 +
 .../python2.7/numpy/multiarray_api.txt        | 2449 +++++
 .../include/python2.7/numpy/ndarrayobject.h   |  246 +
 .../include/python2.7/numpy/ndarraytypes.h    | 1793 ++++
 .../include/python2.7/numpy/noprefix.h        |  209 +
 .../python2.7/numpy/npy_1_7_deprecated_api.h  |  130 +
 .../include/python2.7/numpy/npy_3kcompat.h    |  496 ++
 .../include/python2.7/numpy/npy_common.h      | 1069 +++
 .../mingw32/include/python2.7/numpy/npy_cpu.h |   92 +
 .../include/python2.7/numpy/npy_endian.h      |   61 +
 .../include/python2.7/numpy/npy_interrupt.h   |  117 +
 .../include/python2.7/numpy/npy_math.h        |  529 ++
 .../python2.7/numpy/npy_no_deprecated_api.h   |   19 +
 .../mingw32/include/python2.7/numpy/npy_os.h  |   30 +
 .../include/python2.7/numpy/numpyconfig.h     |   37 +
 .../include/python2.7/numpy/old_defines.h     |  187 +
 .../include/python2.7/numpy/oldnumeric.h      |   23 +
 .../include/python2.7/numpy/ufunc_api.txt     |  321 +
 .../include/python2.7/numpy/ufuncobject.h     |  357 +
 .../mingw32/include/python2.7/numpy/utils.h   |   19 +
 .../numpy-1.11.0-py2.7.egg-info/PKG-INFO      |   47 +
 .../numpy-1.11.0-py2.7.egg-info/SOURCES.txt   | 1054 +++
 .../dependency_links.txt                      |    1 +
 .../numpy-1.11.0-py2.7.egg-info/top_level.txt |    1 +
 .../site-packages/numpy/__config__.py         |   26 +
 .../python2.7/site-packages/numpy/__init__.py |  229 +
 .../site-packages/numpy/_import_tools.py      |  353 +
 .../site-packages/numpy/add_newdocs.py        | 7671 ++++++++++++++++
 .../site-packages/numpy/compat/__init__.py    |   20 +
 .../site-packages/numpy/compat/_inspect.py    |  194 +
 .../site-packages/numpy/compat/py3k.py        |   88 +
 .../site-packages/numpy/compat/setup.py       |   12 +
 .../site-packages/numpy/core/__init__.py      |   90 +
 .../site-packages/numpy/core/_dummy.pyd       |  Bin 0 -> 15360 bytes
 .../site-packages/numpy/core/_internal.py     |  632 ++
 .../site-packages/numpy/core/_methods.py      |  133 +
 .../site-packages/numpy/core/arrayprint.py    |  754 ++
 .../site-packages/numpy/core/cversions.py     |   15 +
 .../site-packages/numpy/core/defchararray.py  | 2689 ++++++
 .../site-packages/numpy/core/fromnumeric.py   | 3100 +++++++
 .../site-packages/numpy/core/function_base.py |  208 +
 .../numpy/core/generate_numpy_api.py          |  253 +
 .../site-packages/numpy/core/getlimits.py     |  308 +
 .../core/include/numpy/__multiarray_api.h     | 1540 ++++
 .../numpy/core/include/numpy/__ufunc_api.h    |  320 +
 .../numpy/_neighborhood_iterator_imp.h        |   90 +
 .../numpy/core/include/numpy/_numpyconfig.h   |   31 +
 .../numpy/core/include/numpy/arrayobject.h    |   11 +
 .../numpy/core/include/numpy/arrayscalars.h   |  175 +
 .../numpy/core/include/numpy/halffloat.h      |   70 +
 .../core/include/numpy/multiarray_api.txt     | 2449 +++++
 .../numpy/core/include/numpy/ndarrayobject.h  |  246 +
 .../numpy/core/include/numpy/ndarraytypes.h   | 1793 ++++
 .../numpy/core/include/numpy/noprefix.h       |  209 +
 .../include/numpy/npy_1_7_deprecated_api.h    |  130 +
 .../numpy/core/include/numpy/npy_3kcompat.h   |  496 ++
 .../numpy/core/include/numpy/npy_common.h     | 1069 +++
 .../numpy/core/include/numpy/npy_cpu.h        |   92 +
 .../numpy/core/include/numpy/npy_endian.h     |   61 +
 .../numpy/core/include/numpy/npy_interrupt.h  |  117 +
 .../numpy/core/include/numpy/npy_math.h       |  529 ++
 .../include/numpy/npy_no_deprecated_api.h     |   19 +
 .../numpy/core/include/numpy/npy_os.h         |   30 +
 .../numpy/core/include/numpy/numpyconfig.h    |   37 +
 .../numpy/core/include/numpy/old_defines.h    |  187 +
 .../numpy/core/include/numpy/oldnumeric.h     |   23 +
 .../numpy/core/include/numpy/ufunc_api.txt    |  321 +
 .../numpy/core/include/numpy/ufuncobject.h    |  357 +
 .../numpy/core/include/numpy/utils.h          |   19 +
 .../site-packages/numpy/core/info.py          |   87 +
 .../numpy/core/lib/npy-pkg-config/mlib.ini    |   12 +
 .../numpy/core/lib/npy-pkg-config/npymath.ini |   20 +
 .../site-packages/numpy/core/machar.py        |  342 +
 .../site-packages/numpy/core/memmap.py        |  311 +
 .../site-packages/numpy/core/multiarray.pyd   |  Bin 0 -> 1492480 bytes
 .../numpy/core/multiarray_tests.pyd           |  Bin 0 -> 67584 bytes
 .../site-packages/numpy/core/numeric.py       | 2996 +++++++
 .../site-packages/numpy/core/numerictypes.py  | 1036 +++
 .../numpy/core/operand_flag_tests.pyd         |  Bin 0 -> 17408 bytes
 .../site-packages/numpy/core/records.py       |  855 ++
 .../site-packages/numpy/core/setup.py         |  964 ++
 .../site-packages/numpy/core/setup_common.py  |  356 +
 .../site-packages/numpy/core/shape_base.py    |  350 +
 .../numpy/core/struct_ufunc_test.pyd          |  Bin 0 -> 17920 bytes
 .../numpy/core/test_rational.pyd              |  Bin 0 -> 86016 bytes
 .../numpy/core/tests/data/astype_copy.pkl     |  Bin 0 -> 716 bytes
 .../core/tests/data/recarray_from_file.fits   |  Bin 0 -> 8640 bytes
 .../numpy/core/tests/test_abc.py              |   47 +
 .../numpy/core/tests/test_api.py              |  515 ++
 .../numpy/core/tests/test_arrayprint.py       |  171 +
 .../numpy/core/tests/test_datetime.py         | 1909 ++++
 .../numpy/core/tests/test_defchararray.py     |  703 ++
 .../numpy/core/tests/test_deprecations.py     |  809 ++
 .../numpy/core/tests/test_dtype.py            |  599 ++
 .../numpy/core/tests/test_einsum.py           |  627 ++
 .../numpy/core/tests/test_errstate.py         |   52 +
 .../numpy/core/tests/test_extint128.py        |  225 +
 .../numpy/core/tests/test_function_base.py    |  155 +
 .../numpy/core/tests/test_getlimits.py        |   77 +
 .../numpy/core/tests/test_half.py             |  436 +
 .../numpy/core/tests/test_indexerrors.py      |  126 +
 .../numpy/core/tests/test_indexing.py         | 1044 +++
 .../numpy/core/tests/test_item_selection.py   |   90 +
 .../numpy/core/tests/test_longdouble.py       |  209 +
 .../numpy/core/tests/test_machar.py           |   29 +
 .../numpy/core/tests/test_mem_overlap.py      |  522 ++
 .../numpy/core/tests/test_memmap.py           |  130 +
 .../numpy/core/tests/test_multiarray.py       | 6386 +++++++++++++
 .../numpy/core/tests/test_multiarray.py.orig  | 6386 +++++++++++++
 .../numpy/core/tests/test_nditer.py           | 2638 ++++++
 .../numpy/core/tests/test_numeric.py          | 2438 +++++
 .../numpy/core/tests/test_numerictypes.py     |  382 +
 .../numpy/core/tests/test_print.py            |  248 +
 .../numpy/core/tests/test_records.py          |  337 +
 .../numpy/core/tests/test_regression.py       | 2187 +++++
 .../numpy/core/tests/test_scalarinherit.py    |   42 +
 .../numpy/core/tests/test_scalarmath.py       |  473 +
 .../numpy/core/tests/test_scalarprint.py      |   30 +
 .../numpy/core/tests/test_shape_base.py       |  319 +
 .../numpy/core/tests/test_ufunc.py            | 1243 +++
 .../numpy/core/tests/test_umath.py            | 2062 +++++
 .../numpy/core/tests/test_umath_complex.py    |  538 ++
 .../numpy/core/tests/test_unicode.py          |  360 +
 .../site-packages/numpy/core/umath.pyd        |  Bin 0 -> 611328 bytes
 .../site-packages/numpy/core/umath_tests.pyd  |  Bin 0 -> 24064 bytes
 .../site-packages/numpy/ctypeslib.py          |  453 +
 .../numpy/distutils/__config__.py             |   26 +
 .../site-packages/numpy/distutils/__init__.py |   23 +
 .../numpy/distutils/__version__.py            |    6 +
 .../numpy/distutils/ccompiler.py              |  689 ++
 .../numpy/distutils/command/__init__.py       |   43 +
 .../numpy/distutils/command/autodist.py       |   96 +
 .../numpy/distutils/command/bdist_rpm.py      |   24 +
 .../numpy/distutils/command/build.py          |   47 +
 .../numpy/distutils/command/build_clib.py     |  295 +
 .../numpy/distutils/command/build_ext.py      |  522 ++
 .../numpy/distutils/command/build_py.py       |   33 +
 .../numpy/distutils/command/build_scripts.py  |   51 +
 .../numpy/distutils/command/build_src.py      |  775 ++
 .../numpy/distutils/command/config.py         |  437 +
 .../distutils/command/config_compiler.py      |  125 +
 .../numpy/distutils/command/develop.py        |   17 +
 .../numpy/distutils/command/egg_info.py       |   19 +
 .../numpy/distutils/command/install.py        |   82 +
 .../numpy/distutils/command/install_clib.py   |   39 +
 .../numpy/distutils/command/install_data.py   |   26 +
 .../distutils/command/install_headers.py      |   27 +
 .../numpy/distutils/command/sdist.py          |   29 +
 .../site-packages/numpy/distutils/compat.py   |   10 +
 .../numpy/distutils/conv_template.py          |  337 +
 .../site-packages/numpy/distutils/core.py     |  210 +
 .../site-packages/numpy/distutils/cpuinfo.py  |  693 ++
 .../numpy/distutils/environment.py            |   72 +
 .../numpy/distutils/exec_command.py           |  651 ++
 .../numpy/distutils/extension.py              |   90 +
 .../numpy/distutils/fcompiler/__init__.py     |  989 +++
 .../numpy/distutils/fcompiler/absoft.py       |  160 +
 .../numpy/distutils/fcompiler/compaq.py       |  128 +
 .../numpy/distutils/fcompiler/g95.py          |   45 +
 .../numpy/distutils/fcompiler/gnu.py          |  391 +
 .../numpy/distutils/fcompiler/hpux.py         |   45 +
 .../numpy/distutils/fcompiler/ibm.py          |   96 +
 .../numpy/distutils/fcompiler/intel.py        |  217 +
 .../numpy/distutils/fcompiler/lahey.py        |   49 +
 .../numpy/distutils/fcompiler/mips.py         |   58 +
 .../numpy/distutils/fcompiler/nag.py          |   45 +
 .../numpy/distutils/fcompiler/none.py         |   31 +
 .../numpy/distutils/fcompiler/pathf95.py      |   38 +
 .../numpy/distutils/fcompiler/pg.py           |   63 +
 .../numpy/distutils/fcompiler/sun.py          |   55 +
 .../numpy/distutils/fcompiler/vast.py         |   56 +
 .../numpy/distutils/from_template.py          |  256 +
 .../site-packages/numpy/distutils/info.py     |    6 +
 .../numpy/distutils/intelccompiler.py         |  105 +
 .../site-packages/numpy/distutils/lib2def.py  |  116 +
 .../numpy/distutils/line_endings.py           |   76 +
 .../site-packages/numpy/distutils/log.py      |   93 +
 .../distutils/mingw/gfortran_vs2003_hack.c    |    6 +
 .../numpy/distutils/mingw32ccompiler.py       |  584 ++
 .../numpy/distutils/misc_util.py              | 2312 +++++
 .../numpy/distutils/msvc9compiler.py          |   25 +
 .../numpy/distutils/msvccompiler.py           |   26 +
 .../numpy/distutils/npy_pkg_config.py         |  450 +
 .../numpy/distutils/numpy_distribution.py     |   19 +
 .../numpy/distutils/pathccompiler.py          |   23 +
 .../site-packages/numpy/distutils/setup.py    |   17 +
 .../numpy/distutils/system_info.py            | 2405 +++++
 .../distutils/tests/test_exec_command.py      |   92 +
 .../distutils/tests/test_fcompiler_gnu.py     |   60 +
 .../distutils/tests/test_fcompiler_intel.py   |   36 +
 .../numpy/distutils/tests/test_misc_util.py   |   79 +
 .../distutils/tests/test_npy_pkg_config.py    |   90 +
 .../numpy/distutils/tests/test_system_info.py |  208 +
 .../numpy/distutils/unixccompiler.py          |  125 +
 .../site-packages/numpy/doc/__init__.py       |   28 +
 .../site-packages/numpy/doc/basics.py         |  185 +
 .../site-packages/numpy/doc/broadcasting.py   |  178 +
 .../site-packages/numpy/doc/byteswapping.py   |  156 +
 .../site-packages/numpy/doc/constants.py      |  393 +
 .../site-packages/numpy/doc/creation.py       |  144 +
 .../site-packages/numpy/doc/glossary.py       |  423 +
 .../site-packages/numpy/doc/indexing.py       |  439 +
 .../site-packages/numpy/doc/internals.py      |  163 +
 .../python2.7/site-packages/numpy/doc/misc.py |  226 +
 .../numpy/doc/structured_arrays.py            |  290 +
 .../site-packages/numpy/doc/subclassing.py    |  560 ++
 .../site-packages/numpy/doc/ufuncs.py         |  138 +
 .../lib/python2.7/site-packages/numpy/dual.py |   71 +
 .../site-packages/numpy/f2py/__init__.py      |   67 +
 .../site-packages/numpy/f2py/__main__.py      |   27 +
 .../site-packages/numpy/f2py/__version__.py   |   10 +
 .../site-packages/numpy/f2py/auxfuncs.py      |  854 ++
 .../site-packages/numpy/f2py/capi_maps.py     |  843 ++
 .../site-packages/numpy/f2py/cb_rules.py      |  554 ++
 .../site-packages/numpy/f2py/cfuncs.py        | 1261 +++
 .../site-packages/numpy/f2py/common_rules.py  |  150 +
 .../site-packages/numpy/f2py/crackfortran.py  | 3311 +++++++
 .../site-packages/numpy/f2py/diagnose.py      |  156 +
 .../site-packages/numpy/f2py/f2py2e.py        |  656 ++
 .../site-packages/numpy/f2py/f2py_testing.py  |   48 +
 .../site-packages/numpy/f2py/f90mod_rules.py  |  272 +
 .../site-packages/numpy/f2py/func2subr.py     |  299 +
 .../site-packages/numpy/f2py/info.py          |    6 +
 .../site-packages/numpy/f2py/rules.py         | 1475 ++++
 .../site-packages/numpy/f2py/setup.py         |  117 +
 .../numpy/f2py/src/fortranobject.c            | 1037 +++
 .../numpy/f2py/src/fortranobject.h            |  162 +
 .../tests/src/array_from_pyobj/wrapmodule.c   |  223 +
 .../f2py/tests/src/assumed_shape/.f2py_f2cmap |    1 +
 .../f2py/tests/src/assumed_shape/foo_free.f90 |   34 +
 .../f2py/tests/src/assumed_shape/foo_mod.f90  |   41 +
 .../f2py/tests/src/assumed_shape/foo_use.f90  |   19 +
 .../tests/src/assumed_shape/precision.f90     |    4 +
 .../numpy/f2py/tests/src/kind/foo.f90         |   20 +
 .../numpy/f2py/tests/src/mixed/foo.f          |    5 +
 .../numpy/f2py/tests/src/mixed/foo_fixed.f90  |    8 +
 .../numpy/f2py/tests/src/mixed/foo_free.f90   |    8 +
 .../numpy/f2py/tests/src/regression/inout.f90 |    9 +
 .../numpy/f2py/tests/src/size/foo.f90         |   44 +
 .../numpy/f2py/tests/test_array_from_pyobj.py |  591 ++
 .../numpy/f2py/tests/test_assumed_shape.py    |   35 +
 .../numpy/f2py/tests/test_callback.py         |  136 +
 .../numpy/f2py/tests/test_kind.py             |   36 +
 .../numpy/f2py/tests/test_mixed.py            |   40 +
 .../numpy/f2py/tests/test_regression.py       |   34 +
 .../numpy/f2py/tests/test_return_character.py |  148 +
 .../numpy/f2py/tests/test_return_complex.py   |  170 +
 .../numpy/f2py/tests/test_return_integer.py   |  180 +
 .../numpy/f2py/tests/test_return_logical.py   |  189 +
 .../numpy/f2py/tests/test_return_real.py      |  206 +
 .../numpy/f2py/tests/test_size.py             |   44 +
 .../site-packages/numpy/f2py/tests/util.py    |  358 +
 .../site-packages/numpy/f2py/use_rules.py     |  115 +
 .../site-packages/numpy/fft/__init__.py       |   11 +
 .../site-packages/numpy/fft/fftpack.py        | 1247 +++
 .../site-packages/numpy/fft/fftpack_lite.pyd  |  Bin 0 -> 44032 bytes
 .../site-packages/numpy/fft/helper.py         |  224 +
 .../python2.7/site-packages/numpy/fft/info.py |  187 +
 .../site-packages/numpy/fft/setup.py          |   19 +
 .../numpy/fft/tests/test_fftpack.py           |  166 +
 .../numpy/fft/tests/test_helper.py            |   78 +
 .../site-packages/numpy/lib/__init__.py       |   46 +
 .../site-packages/numpy/lib/_datasource.py    |  666 ++
 .../site-packages/numpy/lib/_iotools.py       |  930 ++
 .../site-packages/numpy/lib/_version.py       |  156 +
 .../site-packages/numpy/lib/arraypad.py       | 1494 ++++
 .../site-packages/numpy/lib/arraysetops.py    |  480 +
 .../site-packages/numpy/lib/arrayterator.py   |  225 +
 .../site-packages/numpy/lib/financial.py      |  737 ++
 .../site-packages/numpy/lib/format.py         |  813 ++
 .../site-packages/numpy/lib/function_base.py  | 4576 ++++++++++
 .../site-packages/numpy/lib/index_tricks.py   |  874 ++
 .../python2.7/site-packages/numpy/lib/info.py |  158 +
 .../site-packages/numpy/lib/nanfunctions.py   | 1248 +++
 .../site-packages/numpy/lib/npyio.py          | 1995 +++++
 .../site-packages/numpy/lib/polynomial.py     | 1278 +++
 .../site-packages/numpy/lib/recfunctions.py   | 1003 +++
 .../site-packages/numpy/lib/scimath.py        |  566 ++
 .../site-packages/numpy/lib/setup.py          |   12 +
 .../site-packages/numpy/lib/shape_base.py     |  873 ++
 .../site-packages/numpy/lib/stride_tricks.py  |  200 +
 .../numpy/lib/tests/data/py2-objarr.npy       |  Bin 0 -> 258 bytes
 .../numpy/lib/tests/data/py2-objarr.npz       |  Bin 0 -> 366 bytes
 .../numpy/lib/tests/data/py3-objarr.npy       |  Bin 0 -> 341 bytes
 .../numpy/lib/tests/data/py3-objarr.npz       |  Bin 0 -> 449 bytes
 .../numpy/lib/tests/data/python3.npy          |  Bin 0 -> 96 bytes
 .../numpy/lib/tests/data/win64python2.npy     |  Bin 0 -> 96 bytes
 .../numpy/lib/tests/test__datasource.py       |  349 +
 .../numpy/lib/tests/test__iotools.py          |  348 +
 .../numpy/lib/tests/test__version.py          |   70 +
 .../numpy/lib/tests/test_arraypad.py          | 1058 +++
 .../numpy/lib/tests/test_arraysetops.py       |  309 +
 .../numpy/lib/tests/test_arrayterator.py      |   52 +
 .../numpy/lib/tests/test_financial.py         |  163 +
 .../numpy/lib/tests/test_format.py            |  840 ++
 .../numpy/lib/tests/test_function_base.py     | 2824 ++++++
 .../numpy/lib/tests/test_index_tricks.py      |  326 +
 .../site-packages/numpy/lib/tests/test_io.py  | 1888 ++++
 .../numpy/lib/tests/test_nanfunctions.py      |  735 ++
 .../numpy/lib/tests/test_packbits.py          |   27 +
 .../numpy/lib/tests/test_polynomial.py        |  188 +
 .../numpy/lib/tests/test_recfunctions.py      |  724 ++
 .../numpy/lib/tests/test_regression.py        |  261 +
 .../numpy/lib/tests/test_shape_base.py        |  380 +
 .../numpy/lib/tests/test_stride_tricks.py     |  413 +
 .../numpy/lib/tests/test_twodim_base.py       |  535 ++
 .../numpy/lib/tests/test_type_check.py        |  332 +
 .../numpy/lib/tests/test_ufunclike.py         |   65 +
 .../numpy/lib/tests/test_utils.py             |   66 +
 .../site-packages/numpy/lib/twodim_base.py    | 1007 +++
 .../site-packages/numpy/lib/type_check.py     |  596 ++
 .../site-packages/numpy/lib/ufunclike.py      |  177 +
 .../site-packages/numpy/lib/user_array.py     |  294 +
 .../site-packages/numpy/lib/utils.py          | 1122 +++
 .../site-packages/numpy/linalg/__init__.py    |   55 +
 .../numpy/linalg/_umath_linalg.pyd            |  Bin 0 -> 181248 bytes
 .../site-packages/numpy/linalg/info.py        |   37 +
 .../numpy/linalg/lapack_lite.pyd              |  Bin 0 -> 22016 bytes
 .../site-packages/numpy/linalg/linalg.py      | 2409 +++++
 .../site-packages/numpy/linalg/setup.py       |   57 +
 .../numpy/linalg/tests/test_build.py          |   59 +
 .../numpy/linalg/tests/test_deprecations.py   |   26 +
 .../numpy/linalg/tests/test_linalg.py         | 1443 +++
 .../numpy/linalg/tests/test_regression.py     |   95 +
 .../site-packages/numpy/ma/__init__.py        |   56 +
 .../python2.7/site-packages/numpy/ma/bench.py |  131 +
 .../python2.7/site-packages/numpy/ma/core.py  | 7863 +++++++++++++++++
 .../site-packages/numpy/ma/extras.py          | 1819 ++++
 .../site-packages/numpy/ma/mrecords.py        |  796 ++
 .../python2.7/site-packages/numpy/ma/setup.py |   13 +
 .../site-packages/numpy/ma/tests/test_core.py | 4260 +++++++++
 .../numpy/ma/tests/test_extras.py             | 1188 +++
 .../numpy/ma/tests/test_mrecords.py           |  516 ++
 .../numpy/ma/tests/test_old_ma.py             |  821 ++
 .../numpy/ma/tests/test_regression.py         |   80 +
 .../numpy/ma/tests/test_subclassing.py        |  358 +
 .../site-packages/numpy/ma/testutils.py       |  289 +
 .../numpy/ma/timer_comparison.py              |  440 +
 .../site-packages/numpy/ma/version.py         |   14 +
 .../python2.7/site-packages/numpy/matlib.py   |  358 +
 .../site-packages/numpy/matrixlib/__init__.py |   12 +
 .../numpy/matrixlib/defmatrix.py              | 1242 +++
 .../site-packages/numpy/matrixlib/setup.py    |   15 +
 .../numpy/matrixlib/tests/test_defmatrix.py   |  449 +
 .../numpy/matrixlib/tests/test_multiarray.py  |   23 +
 .../numpy/matrixlib/tests/test_numeric.py     |   23 +
 .../numpy/matrixlib/tests/test_regression.py  |   37 +
 .../numpy/polynomial/__init__.py              |   27 +
 .../numpy/polynomial/_polybase.py             |  965 ++
 .../numpy/polynomial/chebyshev.py             | 2080 +++++
 .../site-packages/numpy/polynomial/hermite.py | 1854 ++++
 .../numpy/polynomial/hermite_e.py             | 1851 ++++
 .../numpy/polynomial/laguerre.py              | 1804 ++++
 .../numpy/polynomial/legendre.py              | 1834 ++++
 .../numpy/polynomial/polynomial.py            | 1556 ++++
 .../numpy/polynomial/polyutils.py             |  403 +
 .../site-packages/numpy/polynomial/setup.py   |   11 +
 .../numpy/polynomial/tests/test_chebyshev.py  |  585 ++
 .../numpy/polynomial/tests/test_classes.py    |  579 ++
 .../numpy/polynomial/tests/test_hermite.py    |  547 ++
 .../numpy/polynomial/tests/test_hermite_e.py  |  548 ++
 .../numpy/polynomial/tests/test_laguerre.py   |  529 ++
 .../numpy/polynomial/tests/test_legendre.py   |  548 ++
 .../numpy/polynomial/tests/test_polynomial.py |  504 ++
 .../numpy/polynomial/tests/test_polyutils.py  |  109 +
 .../numpy/polynomial/tests/test_printing.py   |   74 +
 .../site-packages/numpy/random/__init__.py    |  122 +
 .../site-packages/numpy/random/info.py        |  139 +
 .../site-packages/numpy/random/mtrand.pyd     |  Bin 0 -> 677888 bytes
 .../site-packages/numpy/random/randomkit.h    |  226 +
 .../site-packages/numpy/random/setup.py       |   61 +
 .../numpy/random/tests/test_random.py         |  856 ++
 .../numpy/random/tests/test_regression.py     |  117 +
 .../python2.7/site-packages/numpy/setup.py    |   28 +
 .../site-packages/numpy/testing/__init__.py   |   15 +
 .../site-packages/numpy/testing/decorators.py |  272 +
 .../numpy/testing/noseclasses.py              |  340 +
 .../site-packages/numpy/testing/nosetester.py |  516 ++
 .../numpy/testing/print_coercion_tables.py    |   91 +
 .../site-packages/numpy/testing/setup.py      |   20 +
 .../numpy/testing/tests/test_decorators.py    |  182 +
 .../numpy/testing/tests/test_doctesting.py    |   56 +
 .../numpy/testing/tests/test_utils.py         |  848 ++
 .../site-packages/numpy/testing/utils.py      | 1939 ++++
 .../numpy/tests/test_ctypeslib.py             |  106 +
 .../site-packages/numpy/tests/test_matlib.py  |   55 +
 .../numpy/tests/test_numpy_version.py         |   23 +
 .../site-packages/numpy/tests/test_scripts.py |   99 +
 .../python2.7/site-packages/numpy/version.py  |   12 +
 .../share/licenses/python2-numpy/LICENSE.txt  |   30 +
 tools/msys/mingw64/bin/f2py2.py               |   28 +
 .../python2.7/numpy/__multiarray_api.h        | 1540 ++++
 .../include/python2.7/numpy/__ufunc_api.h     |  320 +
 .../numpy/_neighborhood_iterator_imp.h        |   90 +
 .../include/python2.7/numpy/_numpyconfig.h    |   31 +
 .../include/python2.7/numpy/arrayobject.h     |   11 +
 .../include/python2.7/numpy/arrayscalars.h    |  175 +
 .../include/python2.7/numpy/halffloat.h       |   70 +
 .../python2.7/numpy/multiarray_api.txt        | 2449 +++++
 .../include/python2.7/numpy/ndarrayobject.h   |  246 +
 .../include/python2.7/numpy/ndarraytypes.h    | 1793 ++++
 .../include/python2.7/numpy/noprefix.h        |  209 +
 .../python2.7/numpy/npy_1_7_deprecated_api.h  |  130 +
 .../include/python2.7/numpy/npy_3kcompat.h    |  496 ++
 .../include/python2.7/numpy/npy_common.h      | 1069 +++
 .../mingw64/include/python2.7/numpy/npy_cpu.h |   92 +
 .../include/python2.7/numpy/npy_endian.h      |   61 +
 .../include/python2.7/numpy/npy_interrupt.h   |  117 +
 .../include/python2.7/numpy/npy_math.h        |  529 ++
 .../python2.7/numpy/npy_no_deprecated_api.h   |   19 +
 .../mingw64/include/python2.7/numpy/npy_os.h  |   30 +
 .../include/python2.7/numpy/numpyconfig.h     |   37 +
 .../include/python2.7/numpy/old_defines.h     |  187 +
 .../include/python2.7/numpy/oldnumeric.h      |   23 +
 .../include/python2.7/numpy/ufunc_api.txt     |  321 +
 .../include/python2.7/numpy/ufuncobject.h     |  357 +
 .../mingw64/include/python2.7/numpy/utils.h   |   19 +
 .../numpy-1.11.0-py2.7.egg-info/PKG-INFO      |   47 +
 .../numpy-1.11.0-py2.7.egg-info/SOURCES.txt   | 1054 +++
 .../dependency_links.txt                      |    1 +
 .../numpy-1.11.0-py2.7.egg-info/top_level.txt |    1 +
 .../site-packages/numpy/__config__.py         |   26 +
 .../python2.7/site-packages/numpy/__init__.py |  229 +
 .../site-packages/numpy/_import_tools.py      |  353 +
 .../site-packages/numpy/add_newdocs.py        | 7671 ++++++++++++++++
 .../site-packages/numpy/compat/__init__.py    |   20 +
 .../site-packages/numpy/compat/_inspect.py    |  194 +
 .../site-packages/numpy/compat/py3k.py        |   88 +
 .../site-packages/numpy/compat/setup.py       |   12 +
 .../site-packages/numpy/core/__init__.py      |   90 +
 .../site-packages/numpy/core/_dummy.pyd       |  Bin 0 -> 16384 bytes
 .../site-packages/numpy/core/_internal.py     |  632 ++
 .../site-packages/numpy/core/_methods.py      |  133 +
 .../site-packages/numpy/core/arrayprint.py    |  754 ++
 .../site-packages/numpy/core/cversions.py     |   15 +
 .../site-packages/numpy/core/defchararray.py  | 2689 ++++++
 .../site-packages/numpy/core/fromnumeric.py   | 3100 +++++++
 .../site-packages/numpy/core/function_base.py |  208 +
 .../numpy/core/generate_numpy_api.py          |  253 +
 .../site-packages/numpy/core/getlimits.py     |  308 +
 .../core/include/numpy/__multiarray_api.h     | 1540 ++++
 .../numpy/core/include/numpy/__ufunc_api.h    |  320 +
 .../numpy/_neighborhood_iterator_imp.h        |   90 +
 .../numpy/core/include/numpy/_numpyconfig.h   |   31 +
 .../numpy/core/include/numpy/arrayobject.h    |   11 +
 .../numpy/core/include/numpy/arrayscalars.h   |  175 +
 .../numpy/core/include/numpy/halffloat.h      |   70 +
 .../core/include/numpy/multiarray_api.txt     | 2449 +++++
 .../numpy/core/include/numpy/ndarrayobject.h  |  246 +
 .../numpy/core/include/numpy/ndarraytypes.h   | 1793 ++++
 .../numpy/core/include/numpy/noprefix.h       |  209 +
 .../include/numpy/npy_1_7_deprecated_api.h    |  130 +
 .../numpy/core/include/numpy/npy_3kcompat.h   |  496 ++
 .../numpy/core/include/numpy/npy_common.h     | 1069 +++
 .../numpy/core/include/numpy/npy_cpu.h        |   92 +
 .../numpy/core/include/numpy/npy_endian.h     |   61 +
 .../numpy/core/include/numpy/npy_interrupt.h  |  117 +
 .../numpy/core/include/numpy/npy_math.h       |  529 ++
 .../include/numpy/npy_no_deprecated_api.h     |   19 +
 .../numpy/core/include/numpy/npy_os.h         |   30 +
 .../numpy/core/include/numpy/numpyconfig.h    |   37 +
 .../numpy/core/include/numpy/old_defines.h    |  187 +
 .../numpy/core/include/numpy/oldnumeric.h     |   23 +
 .../numpy/core/include/numpy/ufunc_api.txt    |  321 +
 .../numpy/core/include/numpy/ufuncobject.h    |  357 +
 .../numpy/core/include/numpy/utils.h          |   19 +
 .../site-packages/numpy/core/info.py          |   87 +
 .../numpy/core/lib/npy-pkg-config/mlib.ini    |   12 +
 .../numpy/core/lib/npy-pkg-config/npymath.ini |   20 +
 .../site-packages/numpy/core/machar.py        |  342 +
 .../site-packages/numpy/core/memmap.py        |  311 +
 .../site-packages/numpy/core/multiarray.pyd   |  Bin 0 -> 1437696 bytes
 .../numpy/core/multiarray_tests.pyd           |  Bin 0 -> 52224 bytes
 .../site-packages/numpy/core/numeric.py       | 2996 +++++++
 .../site-packages/numpy/core/numerictypes.py  | 1036 +++
 .../numpy/core/operand_flag_tests.pyd         |  Bin 0 -> 18432 bytes
 .../site-packages/numpy/core/records.py       |  855 ++
 .../site-packages/numpy/core/setup.py         |  964 ++
 .../site-packages/numpy/core/setup_common.py  |  356 +
 .../site-packages/numpy/core/shape_base.py    |  350 +
 .../numpy/core/struct_ufunc_test.pyd          |  Bin 0 -> 18944 bytes
 .../numpy/core/test_rational.pyd              |  Bin 0 -> 79360 bytes
 .../numpy/core/tests/data/astype_copy.pkl     |  Bin 0 -> 716 bytes
 .../core/tests/data/recarray_from_file.fits   |  Bin 0 -> 8640 bytes
 .../numpy/core/tests/test_abc.py              |   47 +
 .../numpy/core/tests/test_api.py              |  515 ++
 .../numpy/core/tests/test_arrayprint.py       |  171 +
 .../numpy/core/tests/test_datetime.py         | 1909 ++++
 .../numpy/core/tests/test_defchararray.py     |  703 ++
 .../numpy/core/tests/test_deprecations.py     |  809 ++
 .../numpy/core/tests/test_dtype.py            |  599 ++
 .../numpy/core/tests/test_einsum.py           |  627 ++
 .../numpy/core/tests/test_errstate.py         |   52 +
 .../numpy/core/tests/test_extint128.py        |  225 +
 .../numpy/core/tests/test_function_base.py    |  155 +
 .../numpy/core/tests/test_getlimits.py        |   77 +
 .../numpy/core/tests/test_half.py             |  436 +
 .../numpy/core/tests/test_indexerrors.py      |  126 +
 .../numpy/core/tests/test_indexing.py         | 1044 +++
 .../numpy/core/tests/test_item_selection.py   |   90 +
 .../numpy/core/tests/test_longdouble.py       |  209 +
 .../numpy/core/tests/test_machar.py           |   29 +
 .../numpy/core/tests/test_mem_overlap.py      |  522 ++
 .../numpy/core/tests/test_memmap.py           |  130 +
 .../numpy/core/tests/test_multiarray.py       | 6386 +++++++++++++
 .../numpy/core/tests/test_multiarray.py.orig  | 6386 +++++++++++++
 .../numpy/core/tests/test_nditer.py           | 2638 ++++++
 .../numpy/core/tests/test_numeric.py          | 2438 +++++
 .../numpy/core/tests/test_numerictypes.py     |  382 +
 .../numpy/core/tests/test_print.py            |  248 +
 .../numpy/core/tests/test_records.py          |  337 +
 .../numpy/core/tests/test_regression.py       | 2187 +++++
 .../numpy/core/tests/test_scalarinherit.py    |   42 +
 .../numpy/core/tests/test_scalarmath.py       |  473 +
 .../numpy/core/tests/test_scalarprint.py      |   30 +
 .../numpy/core/tests/test_shape_base.py       |  319 +
 .../numpy/core/tests/test_ufunc.py            | 1243 +++
 .../numpy/core/tests/test_umath.py            | 2062 +++++
 .../numpy/core/tests/test_umath_complex.py    |  538 ++
 .../numpy/core/tests/test_unicode.py          |  360 +
 .../site-packages/numpy/core/umath.pyd        |  Bin 0 -> 787968 bytes
 .../site-packages/numpy/core/umath_tests.pyd  |  Bin 0 -> 26112 bytes
 .../site-packages/numpy/ctypeslib.py          |  453 +
 .../numpy/distutils/__config__.py             |   26 +
 .../site-packages/numpy/distutils/__init__.py |   23 +
 .../numpy/distutils/__version__.py            |    6 +
 .../numpy/distutils/ccompiler.py              |  689 ++
 .../numpy/distutils/command/__init__.py       |   43 +
 .../numpy/distutils/command/autodist.py       |   96 +
 .../numpy/distutils/command/bdist_rpm.py      |   24 +
 .../numpy/distutils/command/build.py          |   47 +
 .../numpy/distutils/command/build_clib.py     |  295 +
 .../numpy/distutils/command/build_ext.py      |  522 ++
 .../numpy/distutils/command/build_py.py       |   33 +
 .../numpy/distutils/command/build_scripts.py  |   51 +
 .../numpy/distutils/command/build_src.py      |  775 ++
 .../numpy/distutils/command/config.py         |  437 +
 .../distutils/command/config_compiler.py      |  125 +
 .../numpy/distutils/command/develop.py        |   17 +
 .../numpy/distutils/command/egg_info.py       |   19 +
 .../numpy/distutils/command/install.py        |   82 +
 .../numpy/distutils/command/install_clib.py   |   39 +
 .../numpy/distutils/command/install_data.py   |   26 +
 .../distutils/command/install_headers.py      |   27 +
 .../numpy/distutils/command/sdist.py          |   29 +
 .../site-packages/numpy/distutils/compat.py   |   10 +
 .../numpy/distutils/conv_template.py          |  337 +
 .../site-packages/numpy/distutils/core.py     |  210 +
 .../site-packages/numpy/distutils/cpuinfo.py  |  693 ++
 .../numpy/distutils/environment.py            |   72 +
 .../numpy/distutils/exec_command.py           |  651 ++
 .../numpy/distutils/extension.py              |   90 +
 .../numpy/distutils/fcompiler/__init__.py     |  989 +++
 .../numpy/distutils/fcompiler/absoft.py       |  160 +
 .../numpy/distutils/fcompiler/compaq.py       |  128 +
 .../numpy/distutils/fcompiler/g95.py          |   45 +
 .../numpy/distutils/fcompiler/gnu.py          |  391 +
 .../numpy/distutils/fcompiler/hpux.py         |   45 +
 .../numpy/distutils/fcompiler/ibm.py          |   96 +
 .../numpy/distutils/fcompiler/intel.py        |  217 +
 .../numpy/distutils/fcompiler/lahey.py        |   49 +
 .../numpy/distutils/fcompiler/mips.py         |   58 +
 .../numpy/distutils/fcompiler/nag.py          |   45 +
 .../numpy/distutils/fcompiler/none.py         |   31 +
 .../numpy/distutils/fcompiler/pathf95.py      |   38 +
 .../numpy/distutils/fcompiler/pg.py           |   63 +
 .../numpy/distutils/fcompiler/sun.py          |   55 +
 .../numpy/distutils/fcompiler/vast.py         |   56 +
 .../numpy/distutils/from_template.py          |  256 +
 .../site-packages/numpy/distutils/info.py     |    6 +
 .../numpy/distutils/intelccompiler.py         |  105 +
 .../site-packages/numpy/distutils/lib2def.py  |  116 +
 .../numpy/distutils/line_endings.py           |   76 +
 .../site-packages/numpy/distutils/log.py      |   93 +
 .../distutils/mingw/gfortran_vs2003_hack.c    |    6 +
 .../numpy/distutils/mingw32ccompiler.py       |  584 ++
 .../numpy/distutils/misc_util.py              | 2312 +++++
 .../numpy/distutils/msvc9compiler.py          |   25 +
 .../numpy/distutils/msvccompiler.py           |   26 +
 .../numpy/distutils/npy_pkg_config.py         |  450 +
 .../numpy/distutils/numpy_distribution.py     |   19 +
 .../numpy/distutils/pathccompiler.py          |   23 +
 .../site-packages/numpy/distutils/setup.py    |   17 +
 .../numpy/distutils/system_info.py            | 2405 +++++
 .../distutils/tests/test_exec_command.py      |   92 +
 .../distutils/tests/test_fcompiler_gnu.py     |   60 +
 .../distutils/tests/test_fcompiler_intel.py   |   36 +
 .../numpy/distutils/tests/test_misc_util.py   |   79 +
 .../distutils/tests/test_npy_pkg_config.py    |   90 +
 .../numpy/distutils/tests/test_system_info.py |  208 +
 .../numpy/distutils/unixccompiler.py          |  125 +
 .../site-packages/numpy/doc/__init__.py       |   28 +
 .../site-packages/numpy/doc/basics.py         |  185 +
 .../site-packages/numpy/doc/broadcasting.py   |  178 +
 .../site-packages/numpy/doc/byteswapping.py   |  156 +
 .../site-packages/numpy/doc/constants.py      |  393 +
 .../site-packages/numpy/doc/creation.py       |  144 +
 .../site-packages/numpy/doc/glossary.py       |  423 +
 .../site-packages/numpy/doc/indexing.py       |  439 +
 .../site-packages/numpy/doc/internals.py      |  163 +
 .../python2.7/site-packages/numpy/doc/misc.py |  226 +
 .../numpy/doc/structured_arrays.py            |  290 +
 .../site-packages/numpy/doc/subclassing.py    |  560 ++
 .../site-packages/numpy/doc/ufuncs.py         |  138 +
 .../lib/python2.7/site-packages/numpy/dual.py |   71 +
 .../site-packages/numpy/f2py/__init__.py      |   67 +
 .../site-packages/numpy/f2py/__main__.py      |   27 +
 .../site-packages/numpy/f2py/__version__.py   |   10 +
 .../site-packages/numpy/f2py/auxfuncs.py      |  854 ++
 .../site-packages/numpy/f2py/capi_maps.py     |  843 ++
 .../site-packages/numpy/f2py/cb_rules.py      |  554 ++
 .../site-packages/numpy/f2py/cfuncs.py        | 1261 +++
 .../site-packages/numpy/f2py/common_rules.py  |  150 +
 .../site-packages/numpy/f2py/crackfortran.py  | 3311 +++++++
 .../site-packages/numpy/f2py/diagnose.py      |  156 +
 .../site-packages/numpy/f2py/f2py2e.py        |  656 ++
 .../site-packages/numpy/f2py/f2py_testing.py  |   48 +
 .../site-packages/numpy/f2py/f90mod_rules.py  |  272 +
 .../site-packages/numpy/f2py/func2subr.py     |  299 +
 .../site-packages/numpy/f2py/info.py          |    6 +
 .../site-packages/numpy/f2py/rules.py         | 1475 ++++
 .../site-packages/numpy/f2py/setup.py         |  117 +
 .../numpy/f2py/src/fortranobject.c            | 1037 +++
 .../numpy/f2py/src/fortranobject.h            |  162 +
 .../tests/src/array_from_pyobj/wrapmodule.c   |  223 +
 .../f2py/tests/src/assumed_shape/.f2py_f2cmap |    1 +
 .../f2py/tests/src/assumed_shape/foo_free.f90 |   34 +
 .../f2py/tests/src/assumed_shape/foo_mod.f90  |   41 +
 .../f2py/tests/src/assumed_shape/foo_use.f90  |   19 +
 .../tests/src/assumed_shape/precision.f90     |    4 +
 .../numpy/f2py/tests/src/kind/foo.f90         |   20 +
 .../numpy/f2py/tests/src/mixed/foo.f          |    5 +
 .../numpy/f2py/tests/src/mixed/foo_fixed.f90  |    8 +
 .../numpy/f2py/tests/src/mixed/foo_free.f90   |    8 +
 .../numpy/f2py/tests/src/regression/inout.f90 |    9 +
 .../numpy/f2py/tests/src/size/foo.f90         |   44 +
 .../numpy/f2py/tests/test_array_from_pyobj.py |  591 ++
 .../numpy/f2py/tests/test_assumed_shape.py    |   35 +
 .../numpy/f2py/tests/test_callback.py         |  136 +
 .../numpy/f2py/tests/test_kind.py             |   36 +
 .../numpy/f2py/tests/test_mixed.py            |   40 +
 .../numpy/f2py/tests/test_regression.py       |   34 +
 .../numpy/f2py/tests/test_return_character.py |  148 +
 .../numpy/f2py/tests/test_return_complex.py   |  170 +
 .../numpy/f2py/tests/test_return_integer.py   |  180 +
 .../numpy/f2py/tests/test_return_logical.py   |  189 +
 .../numpy/f2py/tests/test_return_real.py      |  206 +
 .../numpy/f2py/tests/test_size.py             |   44 +
 .../site-packages/numpy/f2py/tests/util.py    |  358 +
 .../site-packages/numpy/f2py/use_rules.py     |  115 +
 .../site-packages/numpy/fft/__init__.py       |   11 +
 .../site-packages/numpy/fft/fftpack.py        | 1247 +++
 .../site-packages/numpy/fft/fftpack_lite.pyd  |  Bin 0 -> 49152 bytes
 .../site-packages/numpy/fft/helper.py         |  224 +
 .../python2.7/site-packages/numpy/fft/info.py |  187 +
 .../site-packages/numpy/fft/setup.py          |   19 +
 .../numpy/fft/tests/test_fftpack.py           |  166 +
 .../numpy/fft/tests/test_helper.py            |   78 +
 .../site-packages/numpy/lib/__init__.py       |   46 +
 .../site-packages/numpy/lib/_datasource.py    |  666 ++
 .../site-packages/numpy/lib/_iotools.py       |  930 ++
 .../site-packages/numpy/lib/_version.py       |  156 +
 .../site-packages/numpy/lib/arraypad.py       | 1494 ++++
 .../site-packages/numpy/lib/arraysetops.py    |  480 +
 .../site-packages/numpy/lib/arrayterator.py   |  225 +
 .../site-packages/numpy/lib/financial.py      |  737 ++
 .../site-packages/numpy/lib/format.py         |  813 ++
 .../site-packages/numpy/lib/function_base.py  | 4576 ++++++++++
 .../site-packages/numpy/lib/index_tricks.py   |  874 ++
 .../python2.7/site-packages/numpy/lib/info.py |  158 +
 .../site-packages/numpy/lib/nanfunctions.py   | 1248 +++
 .../site-packages/numpy/lib/npyio.py          | 1995 +++++
 .../site-packages/numpy/lib/polynomial.py     | 1278 +++
 .../site-packages/numpy/lib/recfunctions.py   | 1003 +++
 .../site-packages/numpy/lib/scimath.py        |  566 ++
 .../site-packages/numpy/lib/setup.py          |   12 +
 .../site-packages/numpy/lib/shape_base.py     |  873 ++
 .../site-packages/numpy/lib/stride_tricks.py  |  200 +
 .../numpy/lib/tests/data/py2-objarr.npy       |  Bin 0 -> 258 bytes
 .../numpy/lib/tests/data/py2-objarr.npz       |  Bin 0 -> 366 bytes
 .../numpy/lib/tests/data/py3-objarr.npy       |  Bin 0 -> 341 bytes
 .../numpy/lib/tests/data/py3-objarr.npz       |  Bin 0 -> 449 bytes
 .../numpy/lib/tests/data/python3.npy          |  Bin 0 -> 96 bytes
 .../numpy/lib/tests/data/win64python2.npy     |  Bin 0 -> 96 bytes
 .../numpy/lib/tests/test__datasource.py       |  349 +
 .../numpy/lib/tests/test__iotools.py          |  348 +
 .../numpy/lib/tests/test__version.py          |   70 +
 .../numpy/lib/tests/test_arraypad.py          | 1058 +++
 .../numpy/lib/tests/test_arraysetops.py       |  309 +
 .../numpy/lib/tests/test_arrayterator.py      |   52 +
 .../numpy/lib/tests/test_financial.py         |  163 +
 .../numpy/lib/tests/test_format.py            |  840 ++
 .../numpy/lib/tests/test_function_base.py     | 2824 ++++++
 .../numpy/lib/tests/test_index_tricks.py      |  326 +
 .../site-packages/numpy/lib/tests/test_io.py  | 1888 ++++
 .../numpy/lib/tests/test_nanfunctions.py      |  735 ++
 .../numpy/lib/tests/test_packbits.py          |   27 +
 .../numpy/lib/tests/test_polynomial.py        |  188 +
 .../numpy/lib/tests/test_recfunctions.py      |  724 ++
 .../numpy/lib/tests/test_regression.py        |  261 +
 .../numpy/lib/tests/test_shape_base.py        |  380 +
 .../numpy/lib/tests/test_stride_tricks.py     |  413 +
 .../numpy/lib/tests/test_twodim_base.py       |  535 ++
 .../numpy/lib/tests/test_type_check.py        |  332 +
 .../numpy/lib/tests/test_ufunclike.py         |   65 +
 .../numpy/lib/tests/test_utils.py             |   66 +
 .../site-packages/numpy/lib/twodim_base.py    | 1007 +++
 .../site-packages/numpy/lib/type_check.py     |  596 ++
 .../site-packages/numpy/lib/ufunclike.py      |  177 +
 .../site-packages/numpy/lib/user_array.py     |  294 +
 .../site-packages/numpy/lib/utils.py          | 1122 +++
 .../site-packages/numpy/linalg/__init__.py    |   55 +
 .../numpy/linalg/_umath_linalg.pyd            |  Bin 0 -> 201216 bytes
 .../site-packages/numpy/linalg/info.py        |   37 +
 .../numpy/linalg/lapack_lite.pyd              |  Bin 0 -> 24064 bytes
 .../site-packages/numpy/linalg/linalg.py      | 2409 +++++
 .../site-packages/numpy/linalg/setup.py       |   57 +
 .../numpy/linalg/tests/test_build.py          |   59 +
 .../numpy/linalg/tests/test_deprecations.py   |   26 +
 .../numpy/linalg/tests/test_linalg.py         | 1443 +++
 .../numpy/linalg/tests/test_regression.py     |   95 +
 .../site-packages/numpy/ma/__init__.py        |   56 +
 .../python2.7/site-packages/numpy/ma/bench.py |  131 +
 .../python2.7/site-packages/numpy/ma/core.py  | 7863 +++++++++++++++++
 .../site-packages/numpy/ma/extras.py          | 1819 ++++
 .../site-packages/numpy/ma/mrecords.py        |  796 ++
 .../python2.7/site-packages/numpy/ma/setup.py |   13 +
 .../site-packages/numpy/ma/tests/test_core.py | 4260 +++++++++
 .../numpy/ma/tests/test_extras.py             | 1188 +++
 .../numpy/ma/tests/test_mrecords.py           |  516 ++
 .../numpy/ma/tests/test_old_ma.py             |  821 ++
 .../numpy/ma/tests/test_regression.py         |   80 +
 .../numpy/ma/tests/test_subclassing.py        |  358 +
 .../site-packages/numpy/ma/testutils.py       |  289 +
 .../numpy/ma/timer_comparison.py              |  440 +
 .../site-packages/numpy/ma/version.py         |   14 +
 .../python2.7/site-packages/numpy/matlib.py   |  358 +
 .../site-packages/numpy/matrixlib/__init__.py |   12 +
 .../numpy/matrixlib/defmatrix.py              | 1242 +++
 .../site-packages/numpy/matrixlib/setup.py    |   15 +
 .../numpy/matrixlib/tests/test_defmatrix.py   |  449 +
 .../numpy/matrixlib/tests/test_multiarray.py  |   23 +
 .../numpy/matrixlib/tests/test_numeric.py     |   23 +
 .../numpy/matrixlib/tests/test_regression.py  |   37 +
 .../numpy/polynomial/__init__.py              |   27 +
 .../numpy/polynomial/_polybase.py             |  965 ++
 .../numpy/polynomial/chebyshev.py             | 2080 +++++
 .../site-packages/numpy/polynomial/hermite.py | 1854 ++++
 .../numpy/polynomial/hermite_e.py             | 1851 ++++
 .../numpy/polynomial/laguerre.py              | 1804 ++++
 .../numpy/polynomial/legendre.py              | 1834 ++++
 .../numpy/polynomial/polynomial.py            | 1556 ++++
 .../numpy/polynomial/polyutils.py             |  403 +
 .../site-packages/numpy/polynomial/setup.py   |   11 +
 .../numpy/polynomial/tests/test_chebyshev.py  |  585 ++
 .../numpy/polynomial/tests/test_classes.py    |  579 ++
 .../numpy/polynomial/tests/test_hermite.py    |  547 ++
 .../numpy/polynomial/tests/test_hermite_e.py  |  548 ++
 .../numpy/polynomial/tests/test_laguerre.py   |  529 ++
 .../numpy/polynomial/tests/test_legendre.py   |  548 ++
 .../numpy/polynomial/tests/test_polynomial.py |  504 ++
 .../numpy/polynomial/tests/test_polyutils.py  |  109 +
 .../numpy/polynomial/tests/test_printing.py   |   74 +
 .../site-packages/numpy/random/__init__.py    |  122 +
 .../site-packages/numpy/random/info.py        |  139 +
 .../site-packages/numpy/random/mtrand.pyd     |  Bin 0 -> 684544 bytes
 .../site-packages/numpy/random/randomkit.h    |  226 +
 .../site-packages/numpy/random/setup.py       |   61 +
 .../numpy/random/tests/test_random.py         |  856 ++
 .../numpy/random/tests/test_regression.py     |  117 +
 .../python2.7/site-packages/numpy/setup.py    |   28 +
 .../site-packages/numpy/testing/__init__.py   |   15 +
 .../site-packages/numpy/testing/decorators.py |  272 +
 .../numpy/testing/noseclasses.py              |  340 +
 .../site-packages/numpy/testing/nosetester.py |  516 ++
 .../numpy/testing/print_coercion_tables.py    |   91 +
 .../site-packages/numpy/testing/setup.py      |   20 +
 .../numpy/testing/tests/test_decorators.py    |  182 +
 .../numpy/testing/tests/test_doctesting.py    |   56 +
 .../numpy/testing/tests/test_utils.py         |  848 ++
 .../site-packages/numpy/testing/utils.py      | 1939 ++++
 .../numpy/tests/test_ctypeslib.py             |  106 +
 .../site-packages/numpy/tests/test_matlib.py  |   55 +
 .../numpy/tests/test_numpy_version.py         |   23 +
 .../site-packages/numpy/tests/test_scripts.py |   99 +
 .../python2.7/site-packages/numpy/version.py  |   12 +
 .../share/licenses/python2-numpy/LICENSE.txt  |   30 +
 .../desc                                      |   43 +
 .../files                                     |  835 ++
 .../mtree                                     |  Bin 0 -> 47192 bytes
 .../desc                                      |   43 +
 .../files                                     |  835 ++
 .../mtree                                     |  Bin 0 -> 47184 bytes
 800 files changed, 394948 insertions(+)
 create mode 100644 tools/msys/mingw32/bin/f2py2.py
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/__multiarray_api.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/__ufunc_api.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/_neighborhood_iterator_imp.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/_numpyconfig.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/arrayobject.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/arrayscalars.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/halffloat.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/multiarray_api.txt
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/ndarrayobject.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/ndarraytypes.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/noprefix.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_1_7_deprecated_api.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_3kcompat.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_common.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_cpu.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_endian.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_interrupt.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_math.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_no_deprecated_api.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/npy_os.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/numpyconfig.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/old_defines.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/oldnumeric.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/ufunc_api.txt
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/ufuncobject.h
 create mode 100644 tools/msys/mingw32/include/python2.7/numpy/utils.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/__config__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/_import_tools.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/add_newdocs.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/py3k.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_dummy.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_internal.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_methods.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/cversions.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/defchararray.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/function_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/getlimits.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/machar.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/memmap.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numeric.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/records.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup_common.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/shape_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/test_rational.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_api.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_half.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_print.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_records.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ctypeslib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/compat.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/core.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/environment.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/extension.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/log.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/basics.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/constants.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/creation.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/glossary.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/indexing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/internals.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/misc.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/dual.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/rules.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/util.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/helper.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_version.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/financial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/format.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/function_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/npyio.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/scimath.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/type_check.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/user_array.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/utils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/bench.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/core.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/extras.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/testutils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/version.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matlib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/info.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/mtrand.pyd
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/randomkit.h
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_random.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/__init__.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/decorators.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/setup.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/utils.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_matlib.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_scripts.py
 create mode 100644 tools/msys/mingw32/lib/python2.7/site-packages/numpy/version.py
 create mode 100644 tools/msys/mingw32/share/licenses/python2-numpy/LICENSE.txt
 create mode 100644 tools/msys/mingw64/bin/f2py2.py
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/__multiarray_api.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/__ufunc_api.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/_neighborhood_iterator_imp.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/_numpyconfig.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/arrayobject.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/arrayscalars.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/halffloat.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/multiarray_api.txt
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/ndarrayobject.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/ndarraytypes.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/noprefix.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_1_7_deprecated_api.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_3kcompat.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_common.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_cpu.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_endian.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_interrupt.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_math.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_no_deprecated_api.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/npy_os.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/numpyconfig.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/old_defines.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/oldnumeric.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/ufunc_api.txt
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/ufuncobject.h
 create mode 100644 tools/msys/mingw64/include/python2.7/numpy/utils.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/__config__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/_import_tools.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/add_newdocs.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/py3k.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_dummy.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_internal.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_methods.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/cversions.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/defchararray.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/function_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/getlimits.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/machar.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/memmap.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numeric.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/records.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup_common.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/shape_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/test_rational.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_api.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_half.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_print.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_records.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ctypeslib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/compat.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/core.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/environment.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/extension.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/log.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/basics.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/constants.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/creation.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/glossary.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/indexing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/internals.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/misc.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/dual.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/rules.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/util.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/helper.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_version.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/financial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/format.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/function_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/npyio.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/scimath.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/type_check.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/user_array.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/utils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/bench.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/core.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/extras.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/testutils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/version.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matlib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/info.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/mtrand.pyd
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/randomkit.h
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_random.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/__init__.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/decorators.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/setup.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/utils.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_matlib.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_scripts.py
 create mode 100644 tools/msys/mingw64/lib/python2.7/site-packages/numpy/version.py
 create mode 100644 tools/msys/mingw64/share/licenses/python2-numpy/LICENSE.txt
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/desc
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/files
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/mtree
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/desc
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/files
 create mode 100644 tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/mtree

diff --git a/tools/msys/mingw32/bin/f2py2.py b/tools/msys/mingw32/bin/f2py2.py
new file mode 100644
index 0000000000..d623edc17d
--- /dev/null
+++ b/tools/msys/mingw32/bin/f2py2.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python2.exe
+# See http://cens.ioc.ee/projects/f2py2e/
+from __future__ import division, print_function
+
+import os
+import sys
+for mode in ["g3-numpy", "2e-numeric", "2e-numarray", "2e-numpy"]:
+    try:
+        i = sys.argv.index("--" + mode)
+        del sys.argv[i]
+        break
+    except ValueError:
+        pass
+os.environ["NO_SCIPY_IMPORT"] = "f2py"
+if mode == "g3-numpy":
+    sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
+    sys.exit(1)
+elif mode == "2e-numeric":
+    from f2py2e import main
+elif mode == "2e-numarray":
+    sys.argv.append("-DNUMARRAY")
+    from f2py2e import main
+elif mode == "2e-numpy":
+    from numpy.f2py import main
+else:
+    sys.stderr.write("Unknown mode: " + repr(mode) + "\\n")
+    sys.exit(1)
+main()
diff --git a/tools/msys/mingw32/include/python2.7/numpy/__multiarray_api.h b/tools/msys/mingw32/include/python2.7/numpy/__multiarray_api.h
new file mode 100644
index 0000000000..aefb9de029
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/__multiarray_api.h
@@ -0,0 +1,1540 @@
+
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCVersion \
+       (void);
+extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type;
+
+extern NPY_NO_EXPORT int NPY_NUMUSERTYPES;
+
+extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type;
+
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type;
+
+NPY_NO_EXPORT  int PyArray_SetNumericOps \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_GetNumericOps \
+       (void);
+NPY_NO_EXPORT  int PyArray_INCREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_XDECREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  void PyArray_SetStringFunction \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromType \
+       (int);
+NPY_NO_EXPORT  PyObject * PyArray_TypeObjectFromType \
+       (int);
+NPY_NO_EXPORT  char * PyArray_Zero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  char * PyArray_One \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_CastTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CastAnyTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CanCastSafely \
+       (int, int);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTo \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_ObjectType \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromObject \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArrayObject ** PyArray_ConvertToCommonType \
+       (PyObject *, int *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromScalar \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromTypeObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_Size \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Scalar \
+       (void *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_ScalarAsCtype \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_CastScalarToCtype \
+       (PyObject *, void *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_CastScalarDirect \
+       (PyObject *, PyArray_Descr *, void *, int);
+NPY_NO_EXPORT  PyObject * PyArray_ScalarFromObject \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+       (PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromDims \
+       (int, int *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \
+       (int, int *, PyArray_Descr *, char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \
+       (PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromFile \
+       (FILE *, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromString \
+       (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromBuffer \
+       (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \
+       (PyObject *, PyArray_Descr *, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \
+       (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Byteswap \
+       (PyArrayObject *, npy_bool);
+NPY_NO_EXPORT  PyObject * PyArray_Resize \
+       (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_MoveInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyAnyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_ToList \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ToString \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_ToFile \
+       (PyArrayObject *, FILE *, char *, char *);
+NPY_NO_EXPORT  int PyArray_Dump \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Dumps \
+       (PyObject *, int);
+NPY_NO_EXPORT  int PyArray_ValidType \
+       (int);
+NPY_NO_EXPORT  void PyArray_UpdateFlags \
+       (PyArrayObject *, int);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \
+       (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \
+       (PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNew \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewFromType \
+       (int);
+NPY_NO_EXPORT  double PyArray_GetPriority \
+       (PyObject *, double);
+NPY_NO_EXPORT  PyObject * PyArray_IterNew \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterNew \
+       (int, ...);
+NPY_NO_EXPORT  int PyArray_PyIntAsInt \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_PyIntAsIntp \
+       (PyObject *);
+NPY_NO_EXPORT  int PyArray_Broadcast \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  void PyArray_FillObjectArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  int PyArray_FillWithScalar \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CheckStrides \
+       (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewByteorder \
+       (PyArray_Descr *, char);
+NPY_NO_EXPORT  PyObject * PyArray_IterAllButAxis \
+       (PyObject *, int *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromStructInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromArrayAttr \
+       (PyObject *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT  NPY_SCALARKIND PyArray_ScalarKind \
+       (int, PyArrayObject **);
+NPY_NO_EXPORT  int PyArray_CanCoerceScalar \
+       (int, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  PyObject * PyArray_NewFlagsObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastScalar \
+       (PyTypeObject *, PyTypeObject *);
+NPY_NO_EXPORT  int PyArray_CompareUCS4 \
+       (npy_ucs4 *, npy_ucs4 *, size_t);
+NPY_NO_EXPORT  int PyArray_RemoveSmallest \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  int PyArray_ElementStrides \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_Item_INCREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_Item_XDECREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  PyObject * PyArray_FieldNames \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Transpose \
+       (PyArrayObject *, PyArray_Dims *);
+NPY_NO_EXPORT  PyObject * PyArray_TakeFrom \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutTo \
+       (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutMask \
+       (PyArrayObject *, PyObject*, PyObject*);
+NPY_NO_EXPORT  PyObject * PyArray_Repeat \
+       (PyArrayObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Choose \
+       (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  int PyArray_Sort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgSort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_SearchSorted \
+       (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMax \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMin \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Reshape \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Newshape \
+       (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Squeeze \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \
+       (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+NPY_NO_EXPORT  PyObject * PyArray_SwapAxes \
+       (PyArrayObject *, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Max \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Min \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Ptp \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Mean \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Trace \
+       (PyArrayObject *, int, int, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Diagonal \
+       (PyArrayObject *, int, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Clip \
+       (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Conjugate \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Nonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Std \
+       (PyArrayObject *, int, int, PyArrayObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Sum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumSum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Prod \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumProd \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_All \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Any \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Compress \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Flatten \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Ravel \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  npy_intp PyArray_MultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_MultiplyIntList \
+       (int *, int);
+NPY_NO_EXPORT  void * PyArray_GetPtr \
+       (PyArrayObject *, npy_intp*);
+NPY_NO_EXPORT  int PyArray_CompareLists \
+       (npy_intp *, npy_intp *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \
+       (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+NPY_NO_EXPORT  int PyArray_As1D \
+       (PyObject **, char **, int *, int);
+NPY_NO_EXPORT  int PyArray_As2D \
+       (PyObject **, char ***, int *, int *, int);
+NPY_NO_EXPORT  int PyArray_Free \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_Converter \
+       (PyObject *, PyObject **);
+NPY_NO_EXPORT  int PyArray_IntpFromSequence \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Concatenate \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_InnerProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CopyAndTranspose \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  int PyArray_TypestrConvert \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_DescrConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_IntpConverter \
+       (PyObject *, PyArray_Dims *);
+NPY_NO_EXPORT  int PyArray_BufferConverter \
+       (PyObject *, PyArray_Chunk *);
+NPY_NO_EXPORT  int PyArray_AxisConverter \
+       (PyObject *, int *);
+NPY_NO_EXPORT  int PyArray_BoolConverter \
+       (PyObject *, npy_bool *);
+NPY_NO_EXPORT  int PyArray_ByteorderConverter \
+       (PyObject *, char *);
+NPY_NO_EXPORT  int PyArray_OrderConverter \
+       (PyObject *, NPY_ORDER *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Where \
+       (PyObject *, PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Arange \
+       (double, double, double, int);
+NPY_NO_EXPORT  PyObject * PyArray_ArangeObj \
+       (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_SortkindConverter \
+       (PyObject *, NPY_SORTKIND *);
+NPY_NO_EXPORT  PyObject * PyArray_LexSort \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Round \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypenums \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_RegisterDataType \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_RegisterCastFunc \
+       (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+NPY_NO_EXPORT  int PyArray_RegisterCanCast \
+       (PyArray_Descr *, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  void PyArray_InitArrFuncs \
+       (PyArray_ArrFuncs *);
+NPY_NO_EXPORT  PyObject * PyArray_IntTupleFromIntp \
+       (int, npy_intp *);
+NPY_NO_EXPORT  int PyArray_TypeNumFromName \
+       (char *);
+NPY_NO_EXPORT  int PyArray_ClipmodeConverter \
+       (PyObject *, NPY_CLIPMODE *);
+NPY_NO_EXPORT  int PyArray_OutputConverter \
+       (PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  PyObject * PyArray_BroadcastToShape \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  void _PyArray_SigintHandler \
+       (int);
+NPY_NO_EXPORT  void* _PyArray_GetSigintBuf \
+       (void);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_SearchsideConverter \
+       (PyObject *, void *);
+NPY_NO_EXPORT  PyObject * PyArray_CheckAxis \
+       (PyArrayObject *, int *, int);
+NPY_NO_EXPORT  npy_intp PyArray_OverflowMultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_CompareString \
+       (char *, char *, size_t);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterFromObjects \
+       (PyObject **, int, int, ...);
+NPY_NO_EXPORT  int PyArray_GetEndianness \
+       (void);
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCFeatureVersion \
+       (void);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate2 \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject* PyArray_NeighborhoodIterNew \
+       (PyArrayIterObject *, npy_intp *, int, PyArrayObject*);
+extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject NpyIter_Type;
+
+NPY_NO_EXPORT  void PyArray_SetDatetimeParseFunction \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_DatetimeToDatetimeStruct \
+       (npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  void PyArray_TimedeltaToTimedeltaStruct \
+       (npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_DatetimeStructToDatetime \
+       (NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_TimedeltaStructToTimedelta \
+       (NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  NpyIter * NpyIter_New \
+       (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*);
+NPY_NO_EXPORT  NpyIter * NpyIter_MultiNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **);
+NPY_NO_EXPORT  NpyIter * NpyIter_AdvancedNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp);
+NPY_NO_EXPORT  NpyIter * NpyIter_Copy \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Deallocate \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasDelayedBufAlloc \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_EnableExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerStrideArray \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerLoopSizePtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Reset \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_ResetBasePointers \
+       (NpyIter *, char **, char **);
+NPY_NO_EXPORT  int NpyIter_ResetToIterIndexRange \
+       (NpyIter *, npy_intp, npy_intp, char **);
+NPY_NO_EXPORT  int NpyIter_GetNDim \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetNOp \
+       (NpyIter *);
+NPY_NO_EXPORT  NpyIter_IterNextFunc * NpyIter_GetIterNext \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterSize \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetIterIndexRange \
+       (NpyIter *, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIterIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  npy_bool NpyIter_HasMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetShape \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_GotoMultiIndex \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsBuffered \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsGrowInner \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetBufferSize \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetIndexPtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  char ** NpyIter_GetDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArray_Descr ** NpyIter_GetDescrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject ** NpyIter_GetOperandArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject * NpyIter_GetIterView \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  void NpyIter_GetReadFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_GetWriteFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_DebugPrint \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IterationNeedsAPI \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetInnerFixedStrideArray \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveAxis \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetAxisStrideArray \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_bool NpyIter_RequiresBuffering \
+       (NpyIter *);
+NPY_NO_EXPORT  char ** NpyIter_GetInitialDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_CreateCompatibleStrides \
+       (NpyIter *, npy_intp, npy_intp *);
+NPY_NO_EXPORT  int PyArray_CastingConverter \
+       (PyObject *, NPY_CASTING *);
+NPY_NO_EXPORT  npy_intp PyArray_CountNonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_PromoteTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_MinScalarType \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_ResultType \
+       (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastArrayTo \
+       (PyArrayObject *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTypeTo \
+       (PyArray_Descr *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  PyArrayObject * PyArray_EinsteinSum \
+       (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \
+       (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_GetArrayParamsFromObject \
+       (PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *);
+NPY_NO_EXPORT  int PyArray_ConvertClipmodeSequence \
+       (PyObject *, NPY_CLIPMODE *, int);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct2 \
+       (PyObject *, PyObject *, PyArrayObject*);
+NPY_NO_EXPORT  npy_bool NpyIter_IsFirstVisit \
+       (NpyIter *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_CreateSortedStridePerm \
+       (int, npy_intp *, npy_stride_sort_item *);
+NPY_NO_EXPORT  void PyArray_RemoveAxesInPlace \
+       (PyArrayObject *, npy_bool *);
+NPY_NO_EXPORT  void PyArray_DebugPrint \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_FailUnlessWriteable \
+       (PyArrayObject *, const char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  void * PyDataMem_NEW \
+       (size_t);
+NPY_NO_EXPORT  void PyDataMem_FREE \
+       (void *);
+NPY_NO_EXPORT  void * PyDataMem_RENEW \
+       (void *, size_t);
+NPY_NO_EXPORT  PyDataMem_EventHookFunc * PyDataMem_SetEventHook \
+       (PyDataMem_EventHookFunc *, void *, void **);
+extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING;
+
+NPY_NO_EXPORT  void PyArray_MapIterSwapAxes \
+       (PyArrayMapIterObject *, PyArrayObject **, int);
+NPY_NO_EXPORT  PyObject * PyArray_MapIterArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_MapIterNext \
+       (PyArrayMapIterObject *);
+NPY_NO_EXPORT  int PyArray_Partition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgPartition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  int PyArray_SelectkindConverter \
+       (PyObject *, NPY_SELECTKIND *);
+NPY_NO_EXPORT  void * PyDataMem_NEW_ZEROED \
+       (size_t, size_t);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \
+       (PyObject *);
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+#define PyArray_GetNDArrayCVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[40])
+#define PyArray_GetNumericOps \
+        (*(PyObject * (*)(void)) \
+         PyArray_API[41])
+#define PyArray_INCREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[42])
+#define PyArray_XDECREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[43])
+#define PyArray_SetStringFunction \
+        (*(void (*)(PyObject *, int)) \
+         PyArray_API[44])
+#define PyArray_DescrFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+        (*(PyObject * (*)(int)) \
+         PyArray_API[46])
+#define PyArray_Zero \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[47])
+#define PyArray_One \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[48])
+#define PyArray_CastToType \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[49])
+#define PyArray_CastTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[50])
+#define PyArray_CastAnyTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[51])
+#define PyArray_CanCastSafely \
+        (*(int (*)(int, int)) \
+         PyArray_API[52])
+#define PyArray_CanCastTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[53])
+#define PyArray_ObjectType \
+        (*(int (*)(PyObject *, int)) \
+         PyArray_API[54])
+#define PyArray_DescrFromObject \
+        (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+        (*(PyArrayObject ** (*)(PyObject *, int *)) \
+         PyArray_API[56])
+#define PyArray_DescrFromScalar \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[58])
+#define PyArray_Size \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[59])
+#define PyArray_Scalar \
+        (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[60])
+#define PyArray_FromScalar \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+        (*(void (*)(PyObject *, void *)) \
+         PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+        (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+         PyArray_API[63])
+#define PyArray_CastScalarDirect \
+        (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+         PyArray_API[64])
+#define PyArray_ScalarFromObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[65])
+#define PyArray_GetCastFunc \
+        (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+         PyArray_API[66])
+#define PyArray_FromDims \
+        (*(PyObject * (*)(int, int *, int)) \
+         PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+        (*(PyObject * (*)(int, int *, PyArray_Descr *, char *)) \
+         PyArray_API[68])
+#define PyArray_FromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[69])
+#define PyArray_EnsureArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[71])
+#define PyArray_FromFile \
+        (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[72])
+#define PyArray_FromString \
+        (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[73])
+#define PyArray_FromBuffer \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+         PyArray_API[74])
+#define PyArray_FromIter \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+         PyArray_API[75])
+#define PyArray_Return \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[76])
+#define PyArray_GetField \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[77])
+#define PyArray_SetField \
+        (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+         PyArray_API[78])
+#define PyArray_Byteswap \
+        (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+         PyArray_API[79])
+#define PyArray_Resize \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER)) \
+         PyArray_API[80])
+#define PyArray_MoveInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[81])
+#define PyArray_CopyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[82])
+#define PyArray_CopyAnyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[83])
+#define PyArray_CopyObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[84])
+#define PyArray_NewCopy \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[85])
+#define PyArray_ToList \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[86])
+#define PyArray_ToString \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[87])
+#define PyArray_ToFile \
+        (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+         PyArray_API[88])
+#define PyArray_Dump \
+        (*(int (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[89])
+#define PyArray_Dumps \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[90])
+#define PyArray_ValidType \
+        (*(int (*)(int)) \
+         PyArray_API[91])
+#define PyArray_UpdateFlags \
+        (*(void (*)(PyArrayObject *, int)) \
+         PyArray_API[92])
+#define PyArray_New \
+        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
+         PyArray_API[93])
+#define PyArray_NewFromDescr \
+        (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *)) \
+         PyArray_API[94])
+#define PyArray_DescrNew \
+        (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+         PyArray_API[95])
+#define PyArray_DescrNewFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[96])
+#define PyArray_GetPriority \
+        (*(double (*)(PyObject *, double)) \
+         PyArray_API[97])
+#define PyArray_IterNew \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[98])
+#define PyArray_MultiIterNew \
+        (*(PyObject * (*)(int, ...)) \
+         PyArray_API[99])
+#define PyArray_PyIntAsInt \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[101])
+#define PyArray_Broadcast \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[102])
+#define PyArray_FillObjectArray \
+        (*(void (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[103])
+#define PyArray_FillWithScalar \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[104])
+#define PyArray_CheckStrides \
+        (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)) \
+         PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+         PyArray_API[106])
+#define PyArray_IterAllButAxis \
+        (*(PyObject * (*)(PyObject *, int *)) \
+         PyArray_API[107])
+#define PyArray_CheckFromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[108])
+#define PyArray_FromArray \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[109])
+#define PyArray_FromInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[110])
+#define PyArray_FromStructInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[111])
+#define PyArray_FromArrayAttr \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[112])
+#define PyArray_ScalarKind \
+        (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+         PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+        (*(int (*)(int, int, NPY_SCALARKIND)) \
+         PyArray_API[114])
+#define PyArray_NewFlagsObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[115])
+#define PyArray_CanCastScalar \
+        (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+         PyArray_API[116])
+#define PyArray_CompareUCS4 \
+        (*(int (*)(npy_ucs4 *, npy_ucs4 *, size_t)) \
+         PyArray_API[117])
+#define PyArray_RemoveSmallest \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[118])
+#define PyArray_ElementStrides \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[119])
+#define PyArray_Item_INCREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[120])
+#define PyArray_Item_XDECREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[121])
+#define PyArray_FieldNames \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[122])
+#define PyArray_Transpose \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+         PyArray_API[123])
+#define PyArray_TakeFrom \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[124])
+#define PyArray_PutTo \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+         PyArray_API[125])
+#define PyArray_PutMask \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+         PyArray_API[126])
+#define PyArray_Repeat \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+         PyArray_API[127])
+#define PyArray_Choose \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[128])
+#define PyArray_Sort \
+        (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[129])
+#define PyArray_ArgSort \
+        (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[130])
+#define PyArray_SearchSorted \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \
+         PyArray_API[131])
+#define PyArray_ArgMax \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[132])
+#define PyArray_ArgMin \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[133])
+#define PyArray_Reshape \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[134])
+#define PyArray_Newshape \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+         PyArray_API[135])
+#define PyArray_Squeeze \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[136])
+#define PyArray_View \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+         PyArray_API[137])
+#define PyArray_SwapAxes \
+        (*(PyObject * (*)(PyArrayObject *, int, int)) \
+         PyArray_API[138])
+#define PyArray_Max \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[139])
+#define PyArray_Min \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[140])
+#define PyArray_Ptp \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[141])
+#define PyArray_Mean \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[142])
+#define PyArray_Trace \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+         PyArray_API[143])
+#define PyArray_Diagonal \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+         PyArray_API[144])
+#define PyArray_Clip \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+         PyArray_API[145])
+#define PyArray_Conjugate \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[146])
+#define PyArray_Nonzero \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[147])
+#define PyArray_Std \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+         PyArray_API[148])
+#define PyArray_Sum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[149])
+#define PyArray_CumSum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[150])
+#define PyArray_Prod \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[151])
+#define PyArray_CumProd \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[152])
+#define PyArray_All \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[153])
+#define PyArray_Any \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[154])
+#define PyArray_Compress \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+         PyArray_API[155])
+#define PyArray_Flatten \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[156])
+#define PyArray_Ravel \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[157])
+#define PyArray_MultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[158])
+#define PyArray_MultiplyIntList \
+        (*(int (*)(int *, int)) \
+         PyArray_API[159])
+#define PyArray_GetPtr \
+        (*(void * (*)(PyArrayObject *, npy_intp*)) \
+         PyArray_API[160])
+#define PyArray_CompareLists \
+        (*(int (*)(npy_intp *, npy_intp *, int)) \
+         PyArray_API[161])
+#define PyArray_AsCArray \
+        (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+         PyArray_API[162])
+#define PyArray_As1D \
+        (*(int (*)(PyObject **, char **, int *, int)) \
+         PyArray_API[163])
+#define PyArray_As2D \
+        (*(int (*)(PyObject **, char ***, int *, int *, int)) \
+         PyArray_API[164])
+#define PyArray_Free \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[165])
+#define PyArray_Converter \
+        (*(int (*)(PyObject *, PyObject **)) \
+         PyArray_API[166])
+#define PyArray_IntpFromSequence \
+        (*(int (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[167])
+#define PyArray_Concatenate \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[168])
+#define PyArray_InnerProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[169])
+#define PyArray_MatrixProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[171])
+#define PyArray_Correlate \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[172])
+#define PyArray_TypestrConvert \
+        (*(int (*)(int, int)) \
+         PyArray_API[173])
+#define PyArray_DescrConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[174])
+#define PyArray_DescrConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[175])
+#define PyArray_IntpConverter \
+        (*(int (*)(PyObject *, PyArray_Dims *)) \
+         PyArray_API[176])
+#define PyArray_BufferConverter \
+        (*(int (*)(PyObject *, PyArray_Chunk *)) \
+         PyArray_API[177])
+#define PyArray_AxisConverter \
+        (*(int (*)(PyObject *, int *)) \
+         PyArray_API[178])
+#define PyArray_BoolConverter \
+        (*(int (*)(PyObject *, npy_bool *)) \
+         PyArray_API[179])
+#define PyArray_ByteorderConverter \
+        (*(int (*)(PyObject *, char *)) \
+         PyArray_API[180])
+#define PyArray_OrderConverter \
+        (*(int (*)(PyObject *, NPY_ORDER *)) \
+         PyArray_API[181])
+#define PyArray_EquivTypes \
+        (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[182])
+#define PyArray_Zeros \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[183])
+#define PyArray_Empty \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[184])
+#define PyArray_Where \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+         PyArray_API[185])
+#define PyArray_Arange \
+        (*(PyObject * (*)(double, double, double, int)) \
+         PyArray_API[186])
+#define PyArray_ArangeObj \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+         PyArray_API[187])
+#define PyArray_SortkindConverter \
+        (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+         PyArray_API[188])
+#define PyArray_LexSort \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[189])
+#define PyArray_Round \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[190])
+#define PyArray_EquivTypenums \
+        (*(unsigned char (*)(int, int)) \
+         PyArray_API[191])
+#define PyArray_RegisterDataType \
+        (*(int (*)(PyArray_Descr *)) \
+         PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+        (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+         PyArray_API[193])
+#define PyArray_RegisterCanCast \
+        (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+         PyArray_API[194])
+#define PyArray_InitArrFuncs \
+        (*(void (*)(PyArray_ArrFuncs *)) \
+         PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+        (*(PyObject * (*)(int, npy_intp *)) \
+         PyArray_API[196])
+#define PyArray_TypeNumFromName \
+        (*(int (*)(char *)) \
+         PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+         PyArray_API[198])
+#define PyArray_OutputConverter \
+        (*(int (*)(PyObject *, PyArrayObject **)) \
+         PyArray_API[199])
+#define PyArray_BroadcastToShape \
+        (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[200])
+#define _PyArray_SigintHandler \
+        (*(void (*)(int)) \
+         PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+        (*(void* (*)(void)) \
+         PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[204])
+#define PyArray_SearchsideConverter \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[205])
+#define PyArray_CheckAxis \
+        (*(PyObject * (*)(PyArrayObject *, int *, int)) \
+         PyArray_API[206])
+#define PyArray_OverflowMultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[207])
+#define PyArray_CompareString \
+        (*(int (*)(char *, char *, size_t)) \
+         PyArray_API[208])
+#define PyArray_MultiIterFromObjects \
+        (*(PyObject * (*)(PyObject **, int, int, ...)) \
+         PyArray_API[209])
+#define PyArray_GetEndianness \
+        (*(int (*)(void)) \
+         PyArray_API[210])
+#define PyArray_GetNDArrayCFeatureVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[211])
+#define PyArray_Correlate2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[212])
+#define PyArray_NeighborhoodIterNew \
+        (*(PyObject* (*)(PyArrayIterObject *, npy_intp *, int, PyArrayObject*)) \
+         PyArray_API[213])
+#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214])
+#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215])
+#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216])
+#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217])
+#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218])
+#define PyArray_SetDatetimeParseFunction \
+        (*(void (*)(PyObject *)) \
+         PyArray_API[219])
+#define PyArray_DatetimeToDatetimeStruct \
+        (*(void (*)(npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[220])
+#define PyArray_TimedeltaToTimedeltaStruct \
+        (*(void (*)(npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[221])
+#define PyArray_DatetimeStructToDatetime \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[222])
+#define PyArray_TimedeltaStructToTimedelta \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[223])
+#define NpyIter_New \
+        (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \
+         PyArray_API[224])
+#define NpyIter_MultiNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \
+         PyArray_API[225])
+#define NpyIter_AdvancedNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \
+         PyArray_API[226])
+#define NpyIter_Copy \
+        (*(NpyIter * (*)(NpyIter *)) \
+         PyArray_API[227])
+#define NpyIter_Deallocate \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[228])
+#define NpyIter_HasDelayedBufAlloc \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[229])
+#define NpyIter_HasExternalLoop \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[230])
+#define NpyIter_EnableExternalLoop \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[231])
+#define NpyIter_GetInnerStrideArray \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[232])
+#define NpyIter_GetInnerLoopSizePtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[233])
+#define NpyIter_Reset \
+        (*(int (*)(NpyIter *, char **)) \
+         PyArray_API[234])
+#define NpyIter_ResetBasePointers \
+        (*(int (*)(NpyIter *, char **, char **)) \
+         PyArray_API[235])
+#define NpyIter_ResetToIterIndexRange \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \
+         PyArray_API[236])
+#define NpyIter_GetNDim \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[237])
+#define NpyIter_GetNOp \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[238])
+#define NpyIter_GetIterNext \
+        (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[239])
+#define NpyIter_GetIterSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[240])
+#define NpyIter_GetIterIndexRange \
+        (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \
+         PyArray_API[241])
+#define NpyIter_GetIterIndex \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[242])
+#define NpyIter_GotoIterIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[243])
+#define NpyIter_HasMultiIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[244])
+#define NpyIter_GetShape \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[245])
+#define NpyIter_GetGetMultiIndex \
+        (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[246])
+#define NpyIter_GotoMultiIndex \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[247])
+#define NpyIter_RemoveMultiIndex \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[248])
+#define NpyIter_HasIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[249])
+#define NpyIter_IsBuffered \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[250])
+#define NpyIter_IsGrowInner \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[251])
+#define NpyIter_GetBufferSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[252])
+#define NpyIter_GetIndexPtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[253])
+#define NpyIter_GotoIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[254])
+#define NpyIter_GetDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[255])
+#define NpyIter_GetDescrArray \
+        (*(PyArray_Descr ** (*)(NpyIter *)) \
+         PyArray_API[256])
+#define NpyIter_GetOperandArray \
+        (*(PyArrayObject ** (*)(NpyIter *)) \
+         PyArray_API[257])
+#define NpyIter_GetIterView \
+        (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \
+         PyArray_API[258])
+#define NpyIter_GetReadFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[259])
+#define NpyIter_GetWriteFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[260])
+#define NpyIter_DebugPrint \
+        (*(void (*)(NpyIter *)) \
+         PyArray_API[261])
+#define NpyIter_IterationNeedsAPI \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[262])
+#define NpyIter_GetInnerFixedStrideArray \
+        (*(void (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[263])
+#define NpyIter_RemoveAxis \
+        (*(int (*)(NpyIter *, int)) \
+         PyArray_API[264])
+#define NpyIter_GetAxisStrideArray \
+        (*(npy_intp * (*)(NpyIter *, int)) \
+         PyArray_API[265])
+#define NpyIter_RequiresBuffering \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[266])
+#define NpyIter_GetInitialDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[267])
+#define NpyIter_CreateCompatibleStrides \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \
+         PyArray_API[268])
+#define PyArray_CastingConverter \
+        (*(int (*)(PyObject *, NPY_CASTING *)) \
+         PyArray_API[269])
+#define PyArray_CountNonzero \
+        (*(npy_intp (*)(PyArrayObject *)) \
+         PyArray_API[270])
+#define PyArray_PromoteTypes \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[271])
+#define PyArray_MinScalarType \
+        (*(PyArray_Descr * (*)(PyArrayObject *)) \
+         PyArray_API[272])
+#define PyArray_ResultType \
+        (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \
+         PyArray_API[273])
+#define PyArray_CanCastArrayTo \
+        (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[274])
+#define PyArray_CanCastTypeTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[275])
+#define PyArray_EinsteinSum \
+        (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \
+         PyArray_API[276])
+#define PyArray_NewLikeArray \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \
+         PyArray_API[277])
+#define PyArray_GetArrayParamsFromObject \
+        (*(int (*)(PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *)) \
+         PyArray_API[278])
+#define PyArray_ConvertClipmodeSequence \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \
+         PyArray_API[279])
+#define PyArray_MatrixProduct2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \
+         PyArray_API[280])
+#define NpyIter_IsFirstVisit \
+        (*(npy_bool (*)(NpyIter *, int)) \
+         PyArray_API[281])
+#define PyArray_SetBaseObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[282])
+#define PyArray_CreateSortedStridePerm \
+        (*(void (*)(int, npy_intp *, npy_stride_sort_item *)) \
+         PyArray_API[283])
+#define PyArray_RemoveAxesInPlace \
+        (*(void (*)(PyArrayObject *, npy_bool *)) \
+         PyArray_API[284])
+#define PyArray_DebugPrint \
+        (*(void (*)(PyArrayObject *)) \
+         PyArray_API[285])
+#define PyArray_FailUnlessWriteable \
+        (*(int (*)(PyArrayObject *, const char *)) \
+         PyArray_API[286])
+#define PyArray_SetUpdateIfCopyBase \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[287])
+#define PyDataMem_NEW \
+        (*(void * (*)(size_t)) \
+         PyArray_API[288])
+#define PyDataMem_FREE \
+        (*(void (*)(void *)) \
+         PyArray_API[289])
+#define PyDataMem_RENEW \
+        (*(void * (*)(void *, size_t)) \
+         PyArray_API[290])
+#define PyDataMem_SetEventHook \
+        (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \
+         PyArray_API[291])
+#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292])
+#define PyArray_MapIterSwapAxes \
+        (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \
+         PyArray_API[293])
+#define PyArray_MapIterArray \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[294])
+#define PyArray_MapIterNext \
+        (*(void (*)(PyArrayMapIterObject *)) \
+         PyArray_API[295])
+#define PyArray_Partition \
+        (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[296])
+#define PyArray_ArgPartition \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[297])
+#define PyArray_SelectkindConverter \
+        (*(int (*)(PyObject *, NPY_SELECTKIND *)) \
+         PyArray_API[298])
+#define PyDataMem_NEW_ZEROED \
+        (*(void * (*)(size_t, size_t)) \
+         PyArray_API[299])
+#define PyArray_CheckAnyScalarExact \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[300])
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/__ufunc_api.h b/tools/msys/mingw32/include/python2.7/numpy/__ufunc_api.h
new file mode 100644
index 0000000000..bad86bda54
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/__ufunc_api.h
@@ -0,0 +1,320 @@
+
+#ifdef _UMATHMODULE
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndData \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForType \
+       (PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *);
+NPY_NO_EXPORT  int PyUFunc_GenericFunction \
+       (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  void PyUFunc_f_f_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_g_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F_As_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_G_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_gg_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F_As_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_GG_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_On_Om \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_GetPyValues \
+       (char *, int *, int *, PyObject **);
+NPY_NO_EXPORT  int PyUFunc_checkfperr \
+       (int, PyObject *, int *);
+NPY_NO_EXPORT  void PyUFunc_clearfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_getfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_handlefperr \
+       (int, PyObject *, int, int *);
+NPY_NO_EXPORT  int PyUFunc_ReplaceLoopBySignature \
+       (PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *);
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndDataAndSignature \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *);
+NPY_NO_EXPORT  int PyUFunc_SetUsesArraysAsData \
+       (void **, size_t);
+NPY_NO_EXPORT  void PyUFunc_e_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_DefaultTypeResolver \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_ValidateCasting \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForDescr \
+       (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *);
+
+#else
+
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+#else
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+void **PyUFunc_API;
+#else
+static void **PyUFunc_API=NULL;
+#endif
+#endif
+
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+#define PyUFunc_FromFuncAndData \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \
+         PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+        (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *)) \
+         PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+        (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+         PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[4])
+#define PyUFunc_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[5])
+#define PyUFunc_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[6])
+#define PyUFunc_g_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[8])
+#define PyUFunc_F_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[9])
+#define PyUFunc_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[10])
+#define PyUFunc_G_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[11])
+#define PyUFunc_O_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[13])
+#define PyUFunc_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[14])
+#define PyUFunc_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[15])
+#define PyUFunc_gg_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[17])
+#define PyUFunc_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[18])
+#define PyUFunc_FF_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[19])
+#define PyUFunc_GG_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[20])
+#define PyUFunc_OO_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[23])
+#define PyUFunc_On_Om \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+        (*(int (*)(char *, int *, int *, PyObject **)) \
+         PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+        (*(int (*)(int, PyObject *, int *)) \
+         PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+        (*(void (*)(void)) \
+         PyUFunc_API[27])
+#define PyUFunc_getfperr \
+        (*(int (*)(void)) \
+         PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+        (*(int (*)(int, PyObject *, int, int *)) \
+         PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+        (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)) \
+         PyUFunc_API[30])
+#define PyUFunc_FromFuncAndDataAndSignature \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \
+         PyUFunc_API[31])
+#define PyUFunc_SetUsesArraysAsData \
+        (*(int (*)(void **, size_t)) \
+         PyUFunc_API[32])
+#define PyUFunc_e_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[33])
+#define PyUFunc_e_e_As_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[34])
+#define PyUFunc_e_e_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[35])
+#define PyUFunc_ee_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[36])
+#define PyUFunc_ee_e_As_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[37])
+#define PyUFunc_ee_e_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[38])
+#define PyUFunc_DefaultTypeResolver \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \
+         PyUFunc_API[39])
+#define PyUFunc_ValidateCasting \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \
+         PyUFunc_API[40])
+#define PyUFunc_RegisterLoopForDescr \
+        (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \
+         PyUFunc_API[41])
+
+static NPY_INLINE int
+_import_umath(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyUFunc_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
+      return -1;
+  }
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_UMATH_RETVAL NULL
+#else
+#define NUMPY_IMPORT_UMATH_RETVAL
+#endif
+
+#define import_umath() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return NUMPY_IMPORT_UMATH_RETVAL;\
+        }\
+    } while(0)
+
+#define import_umath1(ret) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_umath2(ret, msg) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError, msg);\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_ufunc() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+        }\
+    } while(0)
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/_neighborhood_iterator_imp.h b/tools/msys/mingw32/include/python2.7/numpy/_neighborhood_iterator_imp.h
new file mode 100644
index 0000000000..e8860cbc73
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/_neighborhood_iterator_imp.h
@@ -0,0 +1,90 @@
+#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#error You should not include this header directly
+#endif
+/*
+ * Private API (here for inline)
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter);
+
+/*
+ * Update to next item of the iterator
+ *
+ * Note: this simply increment the coordinates vector, last dimension
+ * incremented first , i.e, for dimension 3
+ * ...
+ * -1, -1, -1
+ * -1, -1,  0
+ * -1, -1,  1
+ *  ....
+ * -1,  0, -1
+ * -1,  0,  0
+ *  ....
+ * 0,  -1, -1
+ * 0,  -1,  0
+ *  ....
+ */
+#define _UPDATE_COORD_ITER(c) \
+    wb = iter->coordinates[c] < iter->bounds[c][1]; \
+    if (wb) { \
+        iter->coordinates[c] += 1; \
+        return 0; \
+    } \
+    else { \
+        iter->coordinates[c] = iter->bounds[c][0]; \
+    }
+
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i, wb;
+
+    for (i = iter->nd - 1; i >= 0; --i) {
+        _UPDATE_COORD_ITER(i)
+    }
+
+    return 0;
+}
+
+/*
+ * Version optimized for 2d arrays, manual loop unrolling
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp wb;
+
+    _UPDATE_COORD_ITER(1)
+    _UPDATE_COORD_ITER(0)
+
+    return 0;
+}
+#undef _UPDATE_COORD_ITER
+
+/*
+ * Advance to the next neighbour
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter)
+{
+    _PyArrayNeighborhoodIter_IncrCoord (iter);
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
+
+/*
+ * Reset functions
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i;
+
+    for (i = 0; i < iter->nd; ++i) {
+        iter->coordinates[i] = iter->bounds[i][0];
+    }
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
diff --git a/tools/msys/mingw32/include/python2.7/numpy/_numpyconfig.h b/tools/msys/mingw32/include/python2.7/numpy/_numpyconfig.h
new file mode 100644
index 0000000000..f12aafb587
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/_numpyconfig.h
@@ -0,0 +1,31 @@
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_FLOAT 4
+#define NPY_SIZEOF_COMPLEX_FLOAT 8
+#define NPY_SIZEOF_DOUBLE 8
+#define NPY_SIZEOF_COMPLEX_DOUBLE 16
+#define NPY_SIZEOF_LONGDOUBLE 12
+#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 24
+#define NPY_SIZEOF_PY_INTPTR_T 4
+#define NPY_SIZEOF_OFF_T 4
+#define NPY_SIZEOF_PY_LONG_LONG 8
+#define NPY_SIZEOF_LONGLONG 8
+#define NPY_NO_SIGNAL 1
+#define NPY_NO_SMP 0
+#define NPY_HAVE_DECL_ISNAN
+#define NPY_HAVE_DECL_ISINF
+#define NPY_HAVE_DECL_ISFINITE
+#define NPY_HAVE_DECL_SIGNBIT
+#define NPY_USE_C99_COMPLEX 1
+#define NPY_HAVE_COMPLEX_DOUBLE 1
+#define NPY_HAVE_COMPLEX_FLOAT 1
+#define NPY_HAVE_COMPLEX_LONG_DOUBLE 1
+#define NPY_USE_C99_FORMATS 1
+#define NPY_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#define NPY_ABI_VERSION 0x01000009
+#define NPY_API_VERSION 0x0000000A
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/arrayobject.h b/tools/msys/mingw32/include/python2.7/numpy/arrayobject.h
new file mode 100644
index 0000000000..4f46d6b1ac
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/arrayobject.h
@@ -0,0 +1,11 @@
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/arrayscalars.h b/tools/msys/mingw32/include/python2.7/numpy/arrayscalars.h
new file mode 100644
index 0000000000..64450e7132
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/arrayscalars.h
@@ -0,0 +1,175 @@
+#ifndef _NPY_ARRAYSCALARS_H_
+#define _NPY_ARRAYSCALARS_H_
+
+#ifndef _MULTIARRAYMODULE
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+#endif
+
+
+typedef struct {
+        PyObject_HEAD
+        signed char obval;
+} PyByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        short obval;
+} PyShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        int obval;
+} PyIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        long obval;
+} PyLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longlong obval;
+} PyLongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned char obval;
+} PyUByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned short obval;
+} PyUShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned int obval;
+} PyUIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned long obval;
+} PyULongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_ulonglong obval;
+} PyULongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_half obval;
+} PyHalfScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        float obval;
+} PyFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        double obval;
+} PyDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longdouble obval;
+} PyLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cfloat obval;
+} PyCFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cdouble obval;
+} PyCDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        PyObject * obval;
+} PyObjectScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_datetime obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyDatetimeScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_timedelta obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyTimedeltaScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        char obval;
+} PyScalarObject;
+
+#define PyStringScalarObject PyStringObject
+#define PyUnicodeScalarObject PyUnicodeObject
+
+typedef struct {
+        PyObject_VAR_HEAD
+        char *obval;
+        PyArray_Descr *descr;
+        int flags;
+        PyObject *base;
+} PyVoidScalarObject;
+
+/* Macros
+     Py<Cls><bitsize>ScalarObject
+     Py<Cls><bitsize>ArrType_Type
+   are defined in ndarrayobject.h
+*/
+
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+        ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i)                  \
+        return Py_INCREF(PyArrayScalar_FromLong(i)), \
+                PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE              \
+        return Py_INCREF(PyArrayScalar_False),  \
+                PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE               \
+        return Py_INCREF(PyArrayScalar_True),   \
+                PyArrayScalar_True
+
+#define PyArrayScalar_New(cls) \
+        Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls)             \
+        ((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+        PyArrayScalar_VAL(obj, cls) = val
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/halffloat.h b/tools/msys/mingw32/include/python2.7/numpy/halffloat.h
new file mode 100644
index 0000000000..ab0d221fb4
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/halffloat.h
@@ -0,0 +1,70 @@
+#ifndef __NPY_HALFFLOAT_H__
+#define __NPY_HALFFLOAT_H__
+
+#include <Python.h>
+#include <numpy/npy_math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Half-precision routines
+ */
+
+/* Conversions */
+float npy_half_to_float(npy_half h);
+double npy_half_to_double(npy_half h);
+npy_half npy_float_to_half(float f);
+npy_half npy_double_to_half(double d);
+/* Comparisons */
+int npy_half_eq(npy_half h1, npy_half h2);
+int npy_half_ne(npy_half h1, npy_half h2);
+int npy_half_le(npy_half h1, npy_half h2);
+int npy_half_lt(npy_half h1, npy_half h2);
+int npy_half_ge(npy_half h1, npy_half h2);
+int npy_half_gt(npy_half h1, npy_half h2);
+/* faster *_nonan variants for when you know h1 and h2 are not NaN */
+int npy_half_eq_nonan(npy_half h1, npy_half h2);
+int npy_half_lt_nonan(npy_half h1, npy_half h2);
+int npy_half_le_nonan(npy_half h1, npy_half h2);
+/* Miscellaneous functions */
+int npy_half_iszero(npy_half h);
+int npy_half_isnan(npy_half h);
+int npy_half_isinf(npy_half h);
+int npy_half_isfinite(npy_half h);
+int npy_half_signbit(npy_half h);
+npy_half npy_half_copysign(npy_half x, npy_half y);
+npy_half npy_half_spacing(npy_half h);
+npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
+
+/*
+ * Half-precision constants
+ */
+
+#define NPY_HALF_ZERO   (0x0000u)
+#define NPY_HALF_PZERO  (0x0000u)
+#define NPY_HALF_NZERO  (0x8000u)
+#define NPY_HALF_ONE    (0x3c00u)
+#define NPY_HALF_NEGONE (0xbc00u)
+#define NPY_HALF_PINF   (0x7c00u)
+#define NPY_HALF_NINF   (0xfc00u)
+#define NPY_HALF_NAN    (0x7e00u)
+
+#define NPY_MAX_HALF    (0x7bffu)
+
+/*
+ * Bit-level conversions
+ */
+
+npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f);
+npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d);
+npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h);
+npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/multiarray_api.txt b/tools/msys/mingw32/include/python2.7/numpy/multiarray_api.txt
new file mode 100644
index 0000000000..3a0683da3c
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/multiarray_api.txt
@@ -0,0 +1,2449 @@
+
+===========
+Numpy C-API
+===========
+::
+
+  unsigned int
+  PyArray_GetNDArrayCVersion(void )
+
+
+Included at the very first so not auto-grabbed and thus not labeled.
+
+::
+
+  int
+  PyArray_SetNumericOps(PyObject *dict)
+
+Set internal structure with number functions that all arrays will use
+
+::
+
+  PyObject *
+  PyArray_GetNumericOps(void )
+
+Get dictionary showing number functions that all arrays will use
+
+::
+
+  int
+  PyArray_INCREF(PyArrayObject *mp)
+
+For object arrays, increment all internal references.
+
+::
+
+  int
+  PyArray_XDECREF(PyArrayObject *mp)
+
+Decrement all internal references for object arrays.
+(or arrays with object fields)
+
+::
+
+  void
+  PyArray_SetStringFunction(PyObject *op, int repr)
+
+Set the array print function to be a Python function.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromType(int type)
+
+Get the PyArray_Descr structure for a type.
+
+::
+
+  PyObject *
+  PyArray_TypeObjectFromType(int type)
+
+Get a typeobject from a type-number -- can return NULL.
+
+New reference
+
+::
+
+  char *
+  PyArray_Zero(PyArrayObject *arr)
+
+Get pointer to zero of correct type for array.
+
+::
+
+  char *
+  PyArray_One(PyArrayObject *arr)
+
+Get pointer to one of correct type for array
+
+::
+
+  PyObject *
+  PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int
+                     is_f_order)
+
+For backward compatibility
+
+Cast an array using typecode structure.
+steals reference to dtype --- cannot be NULL
+
+This function always makes a copy of arr, even if the dtype
+doesn't change.
+
+::
+
+  int
+  PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.
+
+::
+
+  int
+  PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.  Arrays don't have to be "broadcastable"
+Only requirement is they have the same number of elements.
+
+::
+
+  int
+  PyArray_CanCastSafely(int fromtype, int totype)
+
+Check the type coercion rules.
+
+::
+
+  npy_bool
+  PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
+
+leaves reference count alone --- cannot be NULL
+
+PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
+parameter.
+
+::
+
+  int
+  PyArray_ObjectType(PyObject *op, int minimum_type)
+
+Return the typecode of the array a Python object would be converted to
+
+Returns the type number the result should have, or NPY_NOTYPE on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
+
+new reference -- accepts NULL for mintype
+
+::
+
+  PyArrayObject **
+  PyArray_ConvertToCommonType(PyObject *op, int *retn)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromScalar(PyObject *sc)
+
+Return descr object from array scalar.
+
+New reference
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromTypeObject(PyObject *type)
+
+
+::
+
+  npy_intp
+  PyArray_Size(PyObject *op)
+
+Compute the size of an array (in number of items)
+
+::
+
+  PyObject *
+  PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
+
+Get scalar-equivalent to a region of memory described by a descriptor.
+
+::
+
+  PyObject *
+  PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
+
+Get 0-dim array from scalar
+
+0-dim array from array-scalar object
+always contains a copy of the data
+unless outcode is NULL, it is of void type and the referrer does
+not own it either.
+
+steals reference to outcode
+
+::
+
+  void
+  PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
+
+Convert to c-type
+
+no error checking is performed -- ctypeptr must be same type as scalar
+in case of flexible type, the data is not copied
+into ctypeptr which is expected to be a pointer to pointer
+
+::
+
+  int
+  PyArray_CastScalarToCtype(PyObject *scalar, void
+                            *ctypeptr, PyArray_Descr *outcode)
+
+Cast Scalar to c-type
+
+The output buffer must be large-enough to receive the value
+Even for flexible types which is different from ScalarAsCtype
+where only a reference for flexible types is returned
+
+This may not work right on narrow builds for NumPy unicode scalars.
+
+::
+
+  int
+  PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr
+                           *indescr, void *ctypeptr, int outtype)
+
+Cast Scalar to c-type
+
+::
+
+  PyObject *
+  PyArray_ScalarFromObject(PyObject *object)
+
+Get an Array Scalar From a Python Object
+
+Returns NULL if unsuccessful but error is only set if another error occurred.
+Currently only Numeric-like object supported.
+
+::
+
+  PyArray_VectorUnaryFunc *
+  PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
+
+Get a cast function to cast from the input descriptor to the
+output type_number (must be a registered data-type).
+Returns NULL if un-successful.
+
+::
+
+  PyObject *
+  PyArray_FromDims(int nd, int *d, int type)
+
+Construct an empty array from dimensions and typenum
+
+::
+
+  PyObject *
+  PyArray_FromDimsAndDataAndDescr(int nd, int *d, PyArray_Descr
+                                  *descr, char *data)
+
+Like FromDimsAndData but uses the Descr structure instead of typecode
+as input.
+
+::
+
+  PyObject *
+  PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int
+                  min_depth, int max_depth, int flags, PyObject
+                  *context)
+
+Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
+Steals a reference to newtype --- which can be NULL
+
+::
+
+  PyObject *
+  PyArray_EnsureArray(PyObject *op)
+
+This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY)
+that special cases Arrays and PyArray_Scalars up front
+It *steals a reference* to the object
+It also guarantees that the result is PyArray_Type
+Because it decrefs op if any conversion needs to take place
+so it can be used like PyArray_EnsureArray(some_function(...))
+
+::
+
+  PyObject *
+  PyArray_EnsureAnyArray(PyObject *op)
+
+
+::
+
+  PyObject *
+  PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char
+                   *sep)
+
+
+Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
+array corresponding to the data encoded in that file.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+For memory-mapped files, use the buffer interface. No more data than
+necessary is read by this routine.
+
+::
+
+  PyObject *
+  PyArray_FromString(char *data, npy_intp slen, PyArray_Descr
+                     *dtype, npy_intp num, char *sep)
+
+
+Given a pointer to a string ``data``, a string length ``slen``, and
+a ``PyArray_Descr``, return an array corresponding to the data
+encoded in that string.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+If ``slen`` is < 0, then the end of string is used for text data.
+It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs
+would be the norm).
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+::
+
+  PyObject *
+  PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp
+                     count, npy_intp offset)
+
+
+::
+
+  PyObject *
+  PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count)
+
+
+steals a reference to dtype (which cannot be NULL)
+
+::
+
+  PyObject *
+  PyArray_Return(PyArrayObject *mp)
+
+
+Return either an array or the appropriate Python object if the array
+is 0d and matches a Python type.
+steals reference to mp
+
+::
+
+  PyObject *
+  PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int
+                   offset)
+
+Get a subset of bytes from each element of the array
+steals reference to typed, must not be NULL
+
+::
+
+  int
+  PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int
+                   offset, PyObject *val)
+
+Set a subset of bytes from each element of the array
+steals reference to dtype, must not be NULL
+
+::
+
+  PyObject *
+  PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)
+
+
+::
+
+  PyObject *
+  PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int
+                 refcheck, NPY_ORDER order)
+
+Resize (reallocate data).  Only works if nothing else is referencing this
+array and it is contiguous.  If refcheck is 0, then the reference count is
+not checked and assumed to be 1.  You still must own this data and have no
+weak-references and no base object.
+
+::
+
+  int
+  PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src)
+
+Move the memory of one array into another, allowing for overlapping data.
+
+Returns 0 on success, negative on failure.
+
+::
+
+  int
+  PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array.
+Broadcast to the destination shape if necessary.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  int
+  PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array -- memory must not overlap
+Does not require src and dest to have "broadcastable" shapes
+(only the same number of elements).
+
+TODO: For NumPy 2.0, this could accept an order parameter which
+only allows NPY_CORDER and NPY_FORDER.  Could also rename
+this to CopyAsFlat to make the name more intuitive.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
+
+
+::
+
+  PyObject *
+  PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order)
+
+Copy an array.
+
+::
+
+  PyObject *
+  PyArray_ToList(PyArrayObject *self)
+
+To List
+
+::
+
+  PyObject *
+  PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
+
+
+::
+
+  int
+  PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
+
+To File
+
+::
+
+  int
+  PyArray_Dump(PyObject *self, PyObject *file, int protocol)
+
+
+::
+
+  PyObject *
+  PyArray_Dumps(PyObject *self, int protocol)
+
+
+::
+
+  int
+  PyArray_ValidType(int type)
+
+Is the typenum valid?
+
+::
+
+  void
+  PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
+
+Update Several Flags at once.
+
+::
+
+  PyObject *
+  PyArray_New(PyTypeObject *subtype, int nd, npy_intp *dims, int
+              type_num, npy_intp *strides, void *data, int itemsize, int
+              flags, PyObject *obj)
+
+Generic new array creation routine.
+
+::
+
+  PyObject *
+  PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int
+                       nd, npy_intp *dims, npy_intp *strides, void
+                       *data, int flags, PyObject *obj)
+
+Generic new array creation routine.
+
+steals a reference to descr (even on failure)
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNew(PyArray_Descr *base)
+
+base cannot be NULL
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewFromType(int type_num)
+
+
+::
+
+  double
+  PyArray_GetPriority(PyObject *obj, double default_)
+
+Get Priority from object
+
+::
+
+  PyObject *
+  PyArray_IterNew(PyObject *obj)
+
+Get Iterator.
+
+::
+
+  PyObject *
+  PyArray_MultiIterNew(int n, ... )
+
+Get MultiIterator,
+
+::
+
+  int
+  PyArray_PyIntAsInt(PyObject *o)
+
+
+::
+
+  npy_intp
+  PyArray_PyIntAsIntp(PyObject *o)
+
+
+::
+
+  int
+  PyArray_Broadcast(PyArrayMultiIterObject *mit)
+
+
+::
+
+  void
+  PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
+
+Assumes contiguous
+
+::
+
+  int
+  PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
+
+
+::
+
+  npy_bool
+  PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp
+                       offset, npy_intp *dims, npy_intp *newstrides)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+
+
+returns a copy of the PyArray_Descr structure with the byteorder
+altered:
+no arguments:  The byteorder is swapped (in all subfields as well)
+single argument:  The byteorder is forced to the given state
+(in all subfields as well)
+
+Valid states:  ('big', '>') or ('little' or '<')
+('native', or '=')
+
+If a descr structure with | is encountered it's own
+byte-order is not changed but any fields are:
+
+
+Deep bytorder change of a data-type descriptor
+Leaves reference count of self unchanged --- does not DECREF self ***
+
+::
+
+  PyObject *
+  PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
+
+Get Iterator that iterates over all but one axis (don't use this with
+PyArray_ITER_GOTO1D).  The axis will be over-written if negative
+with the axis having the smallest stride.
+
+::
+
+  PyObject *
+  PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int
+                       min_depth, int max_depth, int requires, PyObject
+                       *context)
+
+steals a reference to descr -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int
+                    flags)
+
+steals reference to newtype --- acc. NULL
+
+::
+
+  PyObject *
+  PyArray_FromInterface(PyObject *origin)
+
+
+::
+
+  PyObject *
+  PyArray_FromStructInterface(PyObject *input)
+
+
+::
+
+  PyObject *
+  PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject
+                        *context)
+
+
+::
+
+  NPY_SCALARKIND
+  PyArray_ScalarKind(int typenum, PyArrayObject **arr)
+
+ScalarKind
+
+Returns the scalar kind of a type number, with an
+optional tweak based on the scalar value itself.
+If no scalar is provided, it returns INTPOS_SCALAR
+for both signed and unsigned integers, otherwise
+it checks the sign of any signed integer to choose
+INTNEG_SCALAR when appropriate.
+
+::
+
+  int
+  PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND
+                          scalar)
+
+
+Determines whether the data type 'thistype', with
+scalar kind 'scalar', can be coerced into 'neededtype'.
+
+::
+
+  PyObject *
+  PyArray_NewFlagsObject(PyObject *obj)
+
+
+Get New ArrayFlagsObject
+
+::
+
+  npy_bool
+  PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
+
+See if array scalars can be cast.
+
+TODO: For NumPy 2.0, add a NPY_CASTING parameter.
+
+::
+
+  int
+  PyArray_CompareUCS4(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
+
+
+::
+
+  int
+  PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
+
+Adjusts previously broadcasted iterators so that the axis with
+the smallest sum of iterator strides is not iterated over.
+Returns dimension which is smallest in the range [0,multi->nd).
+A -1 is returned if multi->nd == 0.
+
+don't use with PyArray_ITER_GOTO1D because factors are not adjusted
+
+::
+
+  int
+  PyArray_ElementStrides(PyObject *obj)
+
+
+::
+
+  void
+  PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  void
+  PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  PyObject *
+  PyArray_FieldNames(PyObject *fields)
+
+Return the tuple of ordered field names from a dictionary.
+
+::
+
+  PyObject *
+  PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
+
+Return Transpose.
+
+::
+
+  PyObject *
+  PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int
+                   axis, PyArrayObject *out, NPY_CLIPMODE clipmode)
+
+Take
+
+::
+
+  PyObject *
+  PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject
+                *indices0, NPY_CLIPMODE clipmode)
+
+Put values into an array
+
+::
+
+  PyObject *
+  PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0)
+
+Put values into an array according to a mask.
+
+::
+
+  PyObject *
+  PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis)
+
+Repeat the array.
+
+::
+
+  PyObject *
+  PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject
+                 *out, NPY_CLIPMODE clipmode)
+
+
+::
+
+  int
+  PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+Sort an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+ArgSort an array
+
+::
+
+  PyObject *
+  PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE
+                       side, PyObject *perm)
+
+
+Search the sorted array op1 for the location of the items in op2. The
+result is an array of indexes, one for each element in op2, such that if
+the item were to be inserted in op1 just before that index the array
+would still be in sorted order.
+
+Parameters
+----------
+op1 : PyArrayObject *
+Array to be searched, must be 1-D.
+op2 : PyObject *
+Array of items whose insertion indexes in op1 are wanted
+side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT}
+If NPY_SEARCHLEFT, return first valid insertion indexes
+If NPY_SEARCHRIGHT, return last valid insertion indexes
+perm : PyObject *
+Permutation array that sorts op1 (optional)
+
+Returns
+-------
+ret : PyObject *
+New reference to npy_intp array containing indexes where items in op2
+could be validly inserted into op1. NULL on error.
+
+Notes
+-----
+Binary search is used to find the indexes.
+
+::
+
+  PyObject *
+  PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMax
+
+::
+
+  PyObject *
+  PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMin
+
+::
+
+  PyObject *
+  PyArray_Reshape(PyArrayObject *self, PyObject *shape)
+
+Reshape
+
+::
+
+  PyObject *
+  PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER
+                   order)
+
+New shape for an array
+
+::
+
+  PyObject *
+  PyArray_Squeeze(PyArrayObject *self)
+
+
+return a new view of the array object with all of its unit-length
+dimensions squeezed out if needed, otherwise
+return the same array.
+
+::
+
+  PyObject *
+  PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject
+               *pytype)
+
+View
+steals a reference to type -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2)
+
+SwapAxes
+
+::
+
+  PyObject *
+  PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Max
+
+::
+
+  PyObject *
+  PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Min
+
+::
+
+  PyObject *
+  PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Ptp
+
+::
+
+  PyObject *
+  PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Mean
+
+::
+
+  PyObject *
+  PyArray_Trace(PyArrayObject *self, int offset, int axis1, int
+                axis2, int rtype, PyArrayObject *out)
+
+Trace
+
+::
+
+  PyObject *
+  PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int
+                   axis2)
+
+Diagonal
+
+In NumPy versions prior to 1.7,  this function always returned a copy of
+the diagonal array. In 1.7, the code has been updated to compute a view
+onto 'self', but it still copies this array before returning, as well as
+setting the internal WARN_ON_WRITE flag. In a future version, it will
+simply return a view onto self.
+
+::
+
+  PyObject *
+  PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject
+               *max, PyArrayObject *out)
+
+Clip
+
+::
+
+  PyObject *
+  PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
+
+Conjugate
+
+::
+
+  PyObject *
+  PyArray_Nonzero(PyArrayObject *self)
+
+Nonzero
+
+TODO: In NumPy 2.0, should make the iteration order a parameter.
+
+::
+
+  PyObject *
+  PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out, int variance)
+
+Set variance to 1 to by-pass square-root calculation and return variance
+Std
+
+::
+
+  PyObject *
+  PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out)
+
+Sum
+
+::
+
+  PyObject *
+  PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+                 *out)
+
+CumSum
+
+::
+
+  PyObject *
+  PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Prod
+
+::
+
+  PyObject *
+  PyArray_CumProd(PyArrayObject *self, int axis, int
+                  rtype, PyArrayObject *out)
+
+CumProd
+
+::
+
+  PyObject *
+  PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)
+
+All
+
+::
+
+  PyObject *
+  PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)
+
+Any
+
+::
+
+  PyObject *
+  PyArray_Compress(PyArrayObject *self, PyObject *condition, int
+                   axis, PyArrayObject *out)
+
+Compress
+
+::
+
+  PyObject *
+  PyArray_Flatten(PyArrayObject *a, NPY_ORDER order)
+
+Flatten
+
+::
+
+  PyObject *
+  PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order)
+
+Ravel
+Returns a contiguous array
+
+::
+
+  npy_intp
+  PyArray_MultiplyList(npy_intp *l1, int n)
+
+Multiply a List
+
+::
+
+  int
+  PyArray_MultiplyIntList(int *l1, int n)
+
+Multiply a List of ints
+
+::
+
+  void *
+  PyArray_GetPtr(PyArrayObject *obj, npy_intp*ind)
+
+Produce a pointer into array
+
+::
+
+  int
+  PyArray_CompareLists(npy_intp *l1, npy_intp *l2, int n)
+
+Compare Lists
+
+::
+
+  int
+  PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int
+                   nd, PyArray_Descr*typedescr)
+
+Simulate a C-array
+steals a reference to typedescr -- can be NULL
+
+::
+
+  int
+  PyArray_As1D(PyObject **op, char **ptr, int *d1, int typecode)
+
+Convert to a 1D C-array
+
+::
+
+  int
+  PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, int
+               typecode)
+
+Convert to a 2D C-array
+
+::
+
+  int
+  PyArray_Free(PyObject *op, void *ptr)
+
+Free pointers created if As2D is called
+
+::
+
+  int
+  PyArray_Converter(PyObject *object, PyObject **address)
+
+
+Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
+
+This conversion function can be used with the "O&" argument for
+PyArg_ParseTuple.  It will immediately return an object of array type
+or will convert to a NPY_ARRAY_CARRAY any other object.
+
+If you use PyArray_Converter, you must DECREF the array when finished
+as you get a new reference to it.
+
+::
+
+  int
+  PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
+
+PyArray_IntpFromSequence
+Returns the number of integers converted or -1 if an error occurred.
+vals must be large enough to hold maxvals
+
+::
+
+  PyObject *
+  PyArray_Concatenate(PyObject *op, int axis)
+
+Concatenate
+
+Concatenate an arbitrary Python sequence into an array.
+op is a python object supporting the sequence interface.
+Its elements will be concatenated together to form a single
+multidimensional array. If axis is NPY_MAXDIMS or bigger, then
+each sequence object will be flattened before concatenation
+
+::
+
+  PyObject *
+  PyArray_InnerProduct(PyObject *op1, PyObject *op2)
+
+Numeric.innerproduct(a,v)
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct(PyObject *op1, PyObject *op2)
+
+Numeric.matrixproduct(a,v)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  PyObject *
+  PyArray_CopyAndTranspose(PyObject *op)
+
+Copy and Transpose
+
+Could deprecate this function, as there isn't a speed benefit over
+calling Transpose and then Copy.
+
+::
+
+  PyObject *
+  PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
+
+Numeric.correlate(a1,a2,mode)
+
+::
+
+  int
+  PyArray_TypestrConvert(int itemsize, int gentype)
+
+Typestr converter
+
+::
+
+  int
+  PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
+This function takes a Python object representing a type and converts it
+to a the correct PyArray_Descr * structure to describe the type.
+
+Many objects can be used to represent a data-type which in NumPy is
+quite a flexible concept.
+
+This is the central code that converts Python objects to
+Type-descriptor objects that are used throughout numpy.
+
+Returns a new reference in *at, but the returned should not be
+modified as it may be one of the canonical immutable objects or
+a reference to the input obj.
+
+::
+
+  int
+  PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NULL
+
+::
+
+  int
+  PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)
+
+Get intp chunk from sequence
+
+This function takes a Python sequence object and allocates and
+fills in an intp array with the converted values.
+
+Remember to free the pointer seq.ptr when done using
+PyDimMem_FREE(seq.ptr)**
+
+::
+
+  int
+  PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
+
+Get buffer chunk from object
+
+this function takes a Python object which exposes the (single-segment)
+buffer interface and returns a pointer to the data segment
+
+You should increment the reference count by one of buf->base
+if you will hang on to a reference
+
+You only get a borrowed reference to the object. Do not free the
+memory...
+
+::
+
+  int
+  PyArray_AxisConverter(PyObject *obj, int *axis)
+
+Get axis from an object (possibly None) -- a converter function,
+
+See also PyArray_ConvertMultiAxis, which also handles a tuple of axes.
+
+::
+
+  int
+  PyArray_BoolConverter(PyObject *object, npy_bool *val)
+
+Convert an object to true / false
+
+::
+
+  int
+  PyArray_ByteorderConverter(PyObject *obj, char *endian)
+
+Convert object to endian
+
+::
+
+  int
+  PyArray_OrderConverter(PyObject *object, NPY_ORDER *val)
+
+Convert an object to FORTRAN / C / ANY / KEEP
+
+::
+
+  unsigned char
+  PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+
+This function returns true if the two typecodes are
+equivalent (same basic kind and same itemsize).
+
+::
+
+  PyObject *
+  PyArray_Zeros(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Zeros
+
+steal a reference
+accepts NULL type
+
+::
+
+  PyObject *
+  PyArray_Empty(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Empty
+
+accepts NULL type
+steals referenct to type
+
+::
+
+  PyObject *
+  PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)
+
+Where
+
+::
+
+  PyObject *
+  PyArray_Arange(double start, double stop, double step, int type_num)
+
+Arange,
+
+::
+
+  PyObject *
+  PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject
+                    *step, PyArray_Descr *dtype)
+
+
+ArangeObj,
+
+this doesn't change the references
+
+::
+
+  int
+  PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
+
+Convert object to sort kind
+
+::
+
+  PyObject *
+  PyArray_LexSort(PyObject *sort_keys, int axis)
+
+LexSort an array providing indices that will sort a collection of arrays
+lexicographically.  The first key is sorted on first, followed by the second key
+-- requires that arg"merge"sort is available for each sort_key
+
+Returns an index array that shows the indexes for the lexicographic sort along
+the given axis.
+
+::
+
+  PyObject *
+  PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out)
+
+Round
+
+::
+
+  unsigned char
+  PyArray_EquivTypenums(int typenum1, int typenum2)
+
+
+::
+
+  int
+  PyArray_RegisterDataType(PyArray_Descr *descr)
+
+Register Data type
+Does not change the reference count of descr
+
+::
+
+  int
+  PyArray_RegisterCastFunc(PyArray_Descr *descr, int
+                           totype, PyArray_VectorUnaryFunc *castfunc)
+
+Register Casting Function
+Replaces any function currently stored.
+
+::
+
+  int
+  PyArray_RegisterCanCast(PyArray_Descr *descr, int
+                          totype, NPY_SCALARKIND scalar)
+
+Register a type number indicating that a descriptor can be cast
+to it safely
+
+::
+
+  void
+  PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
+
+Initialize arrfuncs to NULL
+
+::
+
+  PyObject *
+  PyArray_IntTupleFromIntp(int len, npy_intp *vals)
+
+PyArray_IntTupleFromIntp
+
+::
+
+  int
+  PyArray_TypeNumFromName(char *str)
+
+
+::
+
+  int
+  PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)
+
+Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP
+
+::
+
+  int
+  PyArray_OutputConverter(PyObject *object, PyArrayObject **address)
+
+Useful to pass as converter function for O& processing in
+PyArgs_ParseTuple for output arrays
+
+::
+
+  PyObject *
+  PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd)
+
+Get Iterator broadcast to a particular shape
+
+::
+
+  void
+  _PyArray_SigintHandler(int signum)
+
+
+::
+
+  void*
+  _PyArray_GetSigintBuf(void )
+
+
+::
+
+  int
+  PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to DEFAULT type.
+
+any object with the .fields attribute and/or .itemsize attribute (if the
+.fields attribute does not give the total size -- i.e. a partial record
+naming).  If itemsize is given it must be >= size computed from fields
+
+The .fields attribute must return a convertible dictionary if present.
+Result inherits from NPY_VOID.
+
+::
+
+  int
+  PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to NULL.
+
+::
+
+  int
+  PyArray_SearchsideConverter(PyObject *obj, void *addr)
+
+Convert object to searchsorted side
+
+::
+
+  PyObject *
+  PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
+
+PyArray_CheckAxis
+
+check that axis is valid
+convert 0-d arrays to 1-d arrays
+
+::
+
+  npy_intp
+  PyArray_OverflowMultiplyList(npy_intp *l1, int n)
+
+Multiply a List of Non-negative numbers with over-flow detection.
+
+::
+
+  int
+  PyArray_CompareString(char *s1, char *s2, size_t len)
+
+
+::
+
+  PyObject *
+  PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... )
+
+Get MultiIterator from array of Python objects and any additional
+
+PyObject **mps -- array of PyObjects
+int n - number of PyObjects in the array
+int nadd - number of additional arrays to include in the iterator.
+
+Returns a multi-iterator object.
+
+::
+
+  int
+  PyArray_GetEndianness(void )
+
+
+::
+
+  unsigned int
+  PyArray_GetNDArrayCFeatureVersion(void )
+
+Returns the built-in (at compilation time) C API version
+
+::
+
+  PyObject *
+  PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)
+
+correlate(a1,a2,mode)
+
+This function computes the usual correlation (correlate(a1, a2) !=
+correlate(a2, a1), and conjugate the second argument for complex inputs
+
+::
+
+  PyObject*
+  PyArray_NeighborhoodIterNew(PyArrayIterObject *x, npy_intp
+                              *bounds, int mode, PyArrayObject*fill)
+
+A Neighborhood Iterator object.
+
+::
+
+  void
+  PyArray_SetDatetimeParseFunction(PyObject *op)
+
+This function is scheduled to be removed
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *result)
+
+Fill the datetime struct from the value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_TimedeltaToTimedeltaStruct(npy_timedelta val, NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *result)
+
+Fill the timedelta struct from the timedelta value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *d)
+
+Create a datetime value from a filled datetime struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *d)
+
+Create a timdelta value from a filled timedelta struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  NpyIter *
+  NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER
+              order, NPY_CASTING casting, PyArray_Descr*dtype)
+
+Allocate a new iterator for one array object.
+
+::
+
+  NpyIter *
+  NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32
+                   flags, NPY_ORDER order, NPY_CASTING
+                   casting, npy_uint32 *op_flags, PyArray_Descr
+                   **op_request_dtypes)
+
+Allocate a new iterator for more than one array object, using
+standard NumPy broadcasting rules and the default buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32
+                      flags, NPY_ORDER order, NPY_CASTING
+                      casting, npy_uint32 *op_flags, PyArray_Descr
+                      **op_request_dtypes, int oa_ndim, int
+                      **op_axes, npy_intp *itershape, npy_intp
+                      buffersize)
+
+Allocate a new iterator for multiple array objects, and advanced
+options for controlling the broadcasting, shape, and buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_Copy(NpyIter *iter)
+
+Makes a copy of the iterator
+
+::
+
+  int
+  NpyIter_Deallocate(NpyIter *iter)
+
+Deallocate an iterator
+
+::
+
+  npy_bool
+  NpyIter_HasDelayedBufAlloc(NpyIter *iter)
+
+Whether the buffer allocation is being delayed
+
+::
+
+  npy_bool
+  NpyIter_HasExternalLoop(NpyIter *iter)
+
+Whether the iterator handles the inner loop
+
+::
+
+  int
+  NpyIter_EnableExternalLoop(NpyIter *iter)
+
+Removes the inner loop handling (so HasExternalLoop returns true)
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerStrideArray(NpyIter *iter)
+
+Get the array of strides for the inner loop (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerLoopSizePtr(NpyIter *iter)
+
+Get a pointer to the size of the inner loop  (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_Reset(NpyIter *iter, char **errmsg)
+
+Resets the iterator to its initial state
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char
+                            **errmsg)
+
+Resets the iterator to its initial state, with new base data pointers.
+This function requires great caution.
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp
+                                iend, char **errmsg)
+
+Resets the iterator to a new iterator index range
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GetNDim(NpyIter *iter)
+
+Gets the number of dimensions being iterated
+
+::
+
+  int
+  NpyIter_GetNOp(NpyIter *iter)
+
+Gets the number of operands being iterated
+
+::
+
+  NpyIter_IterNextFunc *
+  NpyIter_GetIterNext(NpyIter *iter, char **errmsg)
+
+Compute the specialized iteration function for an iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  npy_intp
+  NpyIter_GetIterSize(NpyIter *iter)
+
+Gets the number of elements being iterated
+
+::
+
+  void
+  NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp
+                            *iend)
+
+Gets the range of iteration indices being iterated
+
+::
+
+  npy_intp
+  NpyIter_GetIterIndex(NpyIter *iter)
+
+Gets the current iteration index
+
+::
+
+  int
+  NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex)
+
+Sets the iterator position to the specified iterindex,
+which matches the iteration order of the iterator.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  npy_bool
+  NpyIter_HasMultiIndex(NpyIter *iter)
+
+Whether the iterator is tracking a multi-index
+
+::
+
+  int
+  NpyIter_GetShape(NpyIter *iter, npy_intp *outshape)
+
+Gets the broadcast shape if a multi-index is being tracked by the iterator,
+otherwise gets the shape of the iteration as Fortran-order
+(fastest-changing index first).
+
+The reason Fortran-order is returned when a multi-index
+is not enabled is that this is providing a direct view into how
+the iterator traverses the n-dimensional space. The iterator organizes
+its memory from fastest index to slowest index, and when
+a multi-index is enabled, it uses a permutation to recover the original
+order.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  NpyIter_GetMultiIndexFunc *
+  NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg)
+
+Compute a specialized get_multi_index function for the iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp *multi_index)
+
+Sets the iterator to the specified multi-index, which must have the
+correct number of entries for 'ndim'.  It is only valid
+when NPY_ITER_MULTI_INDEX was passed to the constructor.  This operation
+fails if the multi-index is out of bounds.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  int
+  NpyIter_RemoveMultiIndex(NpyIter *iter)
+
+Removes multi-index support from an iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_bool
+  NpyIter_HasIndex(NpyIter *iter)
+
+Whether the iterator is tracking an index
+
+::
+
+  npy_bool
+  NpyIter_IsBuffered(NpyIter *iter)
+
+Whether the iterator is buffered
+
+::
+
+  npy_bool
+  NpyIter_IsGrowInner(NpyIter *iter)
+
+Whether the inner loop can grow if buffering is unneeded
+
+::
+
+  npy_intp
+  NpyIter_GetBufferSize(NpyIter *iter)
+
+Gets the size of the buffer, or 0 if buffering is not enabled
+
+::
+
+  npy_intp *
+  NpyIter_GetIndexPtr(NpyIter *iter)
+
+Get a pointer to the index, if it is being tracked
+
+::
+
+  int
+  NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index)
+
+If the iterator is tracking an index, sets the iterator
+to the specified index.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  char **
+  NpyIter_GetDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  PyArray_Descr **
+  NpyIter_GetDescrArray(NpyIter *iter)
+
+Get the array of data type pointers (1 per object being iterated)
+
+::
+
+  PyArrayObject **
+  NpyIter_GetOperandArray(NpyIter *iter)
+
+Get the array of objects being iterated
+
+::
+
+  PyArrayObject *
+  NpyIter_GetIterView(NpyIter *iter, npy_intp i)
+
+Returns a view to the i-th object with the iterator's internal axes
+
+::
+
+  void
+  NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags)
+
+Gets an array of read flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags)
+
+Gets an array of write flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_DebugPrint(NpyIter *iter)
+
+For debugging
+
+::
+
+  npy_bool
+  NpyIter_IterationNeedsAPI(NpyIter *iter)
+
+Whether the iteration loop, and in particular the iternext()
+function, needs API access.  If this is true, the GIL must
+be retained while iterating.
+
+::
+
+  void
+  NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides)
+
+Get an array of strides which are fixed.  Any strides which may
+change during iteration receive the value NPY_MAX_INTP.  Once
+the iterator is ready to iterate, call this to get the strides
+which will always be fixed in the inner loop, then choose optimized
+inner loop functions which take advantage of those fixed strides.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_RemoveAxis(NpyIter *iter, int axis)
+
+Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX
+was set for iterator creation, and does not work if buffering is
+enabled. This function also resets the iterator to its initial state.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetAxisStrideArray(NpyIter *iter, int axis)
+
+Gets the array of strides for the specified axis.
+If the iterator is tracking a multi-index, gets the strides
+for the axis specified, otherwise gets the strides for
+the iteration axis as Fortran order (fastest-changing axis first).
+
+Returns NULL if an error occurs.
+
+::
+
+  npy_bool
+  NpyIter_RequiresBuffering(NpyIter *iter)
+
+Whether the iteration could be done with no buffering.
+
+::
+
+  char **
+  NpyIter_GetInitialDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated),
+directly into the arrays (never pointing to a buffer), for starting
+unbuffered iteration. This always returns the addresses for the
+iterator position as reset to iterator index 0.
+
+These pointers are different from the pointers accepted by
+NpyIter_ResetBasePointers, because the direction along some
+axes may have been reversed, requiring base offsets.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp
+                                  itemsize, npy_intp *outstrides)
+
+Builds a set of strides which are the same as the strides of an
+output array created using the NPY_ITER_ALLOCATE flag, where NULL
+was passed for op_axes.  This is for data packed contiguously,
+but not necessarily in C or Fortran order. This should be used
+together with NpyIter_GetShape and NpyIter_GetNDim.
+
+A use case for this function is to match the shape and layout of
+the iterator and tack on one or more dimensions.  For example,
+in order to generate a vector per input value for a numerical gradient,
+you pass in ndim*itemsize for itemsize, then add another dimension to
+the end with size ndim and stride itemsize.  To do the Hessian matrix,
+you do the same thing but add two dimensions, or take advantage of
+the symmetry and pack it into 1 dimension with a particular encoding.
+
+This function may only be called if the iterator is tracking a multi-index
+and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from
+being iterated in reverse order.
+
+If an array is created with this method, simply adding 'itemsize'
+for each iteration will traverse the new array matching the
+iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  int
+  PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)
+
+Convert any Python object, *obj*, to an NPY_CASTING enum.
+
+::
+
+  npy_intp
+  PyArray_CountNonzero(PyArrayObject *self)
+
+Counts the number of non-zero elements in the array.
+
+Returns -1 on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+Produces the smallest size and lowest kind type to which both
+input types can be cast.
+
+::
+
+  PyArray_Descr *
+  PyArray_MinScalarType(PyArrayObject *arr)
+
+If arr is a scalar (has 0 dimensions) with a built-in number data type,
+finds the smallest type size/kind which can still represent its data.
+Otherwise, returns the array's data type.
+
+
+::
+
+  PyArray_Descr *
+  PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp
+                     ndtypes, PyArray_Descr **dtypes)
+
+Produces the result type of a bunch of inputs, using the UFunc
+type promotion rules. Use this function when you have a set of
+input arrays, and need to determine an output array dtype.
+
+If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
+of the scalars is greater than the maximum "kind" of the arrays, does
+a regular type promotion.
+
+Otherwise, does a type promotion on the MinScalarType
+of all the inputs.  Data types passed directly are treated as array
+types.
+
+
+::
+
+  npy_bool
+  PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr
+                         *to, NPY_CASTING casting)
+
+Returns 1 if the array object may be cast to the given data type using
+the casting rule, 0 otherwise.  This differs from PyArray_CanCastTo in
+that it handles scalar arrays (0 dimensions) specially, by checking
+their value.
+
+::
+
+  npy_bool
+  PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr
+                        *to, NPY_CASTING casting)
+
+Returns true if data of type 'from' may be cast to data of type
+'to' according to the rule 'casting'.
+
+::
+
+  PyArrayObject *
+  PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject
+                      **op_in, PyArray_Descr *dtype, NPY_ORDER
+                      order, NPY_CASTING casting, PyArrayObject *out)
+
+This function provides summation of array elements according to
+the Einstein summation convention.  For example:
+- trace(a)        -> einsum("ii", a)
+- transpose(a)    -> einsum("ji", a)
+- multiply(a,b)   -> einsum(",", a, b)
+- inner(a,b)      -> einsum("i,i", a, b)
+- outer(a,b)      -> einsum("i,j", a, b)
+- matvec(a,b)     -> einsum("ij,j", a, b)
+- matmat(a,b)     -> einsum("ij,jk", a, b)
+
+subscripts: The string of subscripts for einstein summation.
+nop:        The number of operands
+op_in:      The array of operands
+dtype:      Either NULL, or the data type to force the calculation as.
+order:      The order for the calculation/the output axes.
+casting:    What kind of casts should be permitted.
+out:        Either NULL, or an array into which the output should be placed.
+
+By default, the labels get placed in alphabetical order
+at the end of the output. So, if c = einsum("i,j", a, b)
+then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b)
+then c[i,j] = a[j]*b[i].
+
+Alternatively, you can control the output order or prevent
+an axis from being summed/force an axis to be summed by providing
+indices for the output. This allows us to turn 'trace' into
+'diag', for example.
+- diag(a)         -> einsum("ii->i", a)
+- sum(a, axis=0)  -> einsum("i...->", a)
+
+Subscripts at the beginning and end may be specified by
+putting an ellipsis "..." in the middle.  For example,
+the function einsum("i...i", a) takes the diagonal of
+the first and last dimensions of the operand, and
+einsum("ij...,jk...->ik...") takes the matrix product using
+the first two indices of each operand instead of the last two.
+
+When there is only one operand, no axes being summed, and
+no output parameter, this function returns a view
+into the operand instead of making a copy.
+
+::
+
+  PyObject *
+  PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER
+                       order, PyArray_Descr *dtype, int subok)
+
+Creates a new array with the same shape as the provided one,
+with possible memory layout order and data type changes.
+
+prototype - The array the new one should be like.
+order     - NPY_CORDER - C-contiguous result.
+NPY_FORTRANORDER - Fortran-contiguous result.
+NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise.
+NPY_KEEPORDER - Keeps the axis ordering of prototype.
+dtype     - If not NULL, overrides the data type of the result.
+subok     - If 1, use the prototype's array subtype, otherwise
+always create a base-class array.
+
+NOTE: If dtype is not NULL, steals the dtype reference.
+
+::
+
+  int
+  PyArray_GetArrayParamsFromObject(PyObject *op, PyArray_Descr
+                                   *requested_dtype, npy_bool
+                                   writeable, PyArray_Descr
+                                   **out_dtype, int *out_ndim, npy_intp
+                                   *out_dims, PyArrayObject
+                                   **out_arr, PyObject *context)
+
+Retrieves the array parameters for viewing/converting an arbitrary
+PyObject* to a NumPy array. This allows the "innate type and shape"
+of Python list-of-lists to be discovered without
+actually converting to an array.
+
+In some cases, such as structured arrays and the __array__ interface,
+a data type needs to be used to make sense of the object.  When
+this is needed, provide a Descr for 'requested_dtype', otherwise
+provide NULL. This reference is not stolen. Also, if the requested
+dtype doesn't modify the interpretation of the input, out_dtype will
+still get the "innate" dtype of the object, not the dtype passed
+in 'requested_dtype'.
+
+If writing to the value in 'op' is desired, set the boolean
+'writeable' to 1.  This raises an error when 'op' is a scalar, list
+of lists, or other non-writeable 'op'.
+
+Result: When success (0 return value) is returned, either out_arr
+is filled with a non-NULL PyArrayObject and
+the rest of the parameters are untouched, or out_arr is
+filled with NULL, and the rest of the parameters are
+filled.
+
+Typical usage:
+
+PyArrayObject *arr = NULL;
+PyArray_Descr *dtype = NULL;
+int ndim = 0;
+npy_intp dims[NPY_MAXDIMS];
+
+if (PyArray_GetArrayParamsFromObject(op, NULL, 1, &dtype,
+&ndim, dims, &arr, NULL) < 0) {
+return NULL;
+}
+if (arr == NULL) {
+... validate/change dtype, validate flags, ndim, etc ...
+// Could make custom strides here too
+arr = PyArray_NewFromDescr(&PyArray_Type, dtype, ndim,
+dims, NULL,
+is_f_order ? NPY_ARRAY_F_CONTIGUOUS : 0,
+NULL);
+if (arr == NULL) {
+return NULL;
+}
+if (PyArray_CopyObject(arr, op) < 0) {
+Py_DECREF(arr);
+return NULL;
+}
+}
+else {
+... in this case the other parameters weren't filled, just
+validate and possibly copy arr itself ...
+}
+... use arr ...
+
+::
+
+  int
+  PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE
+                                  *modes, int n)
+
+Convert an object to an array of n NPY_CLIPMODE values.
+This is intended to be used in functions where a different mode
+could be applied to each axis, like in ravel_multi_index.
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct2(PyObject *op1, PyObject
+                         *op2, PyArrayObject*out)
+
+Numeric.matrixproduct2(a,v,out)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  npy_bool
+  NpyIter_IsFirstVisit(NpyIter *iter, int iop)
+
+Checks to see whether this is the first time the elements
+of the specified reduction operand which the iterator points at are
+being seen for the first time. The function returns
+a reasonable answer for reduction operands and when buffering is
+disabled. The answer may be incorrect for buffered non-reduction
+operands.
+
+This function is intended to be used in EXTERNAL_LOOP mode only,
+and will produce some wrong answers when that mode is not enabled.
+
+If this function returns true, the caller should also
+check the inner loop stride of the operand, because if
+that stride is 0, then only the first element of the innermost
+external loop is being visited for the first time.
+
+WARNING: For performance reasons, 'iop' is not bounds-checked,
+it is not confirmed that 'iop' is actually a reduction
+operand, and it is not confirmed that EXTERNAL_LOOP
+mode is enabled. These checks are the responsibility of
+the caller, and should be done outside of any inner loops.
+
+::
+
+  int
+  PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)
+
+Sets the 'base' attribute of the array. This steals a reference
+to 'obj'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void
+  PyArray_CreateSortedStridePerm(int ndim, npy_intp
+                                 *strides, npy_stride_sort_item
+                                 *out_strideperm)
+
+
+This function populates the first ndim elements
+of strideperm with sorted descending by their absolute values.
+For example, the stride array (4, -2, 12) becomes
+[(2, 12), (0, 4), (1, -2)].
+
+::
+
+  void
+  PyArray_RemoveAxesInPlace(PyArrayObject *arr, npy_bool *flags)
+
+
+Removes the axes flagged as True from the array,
+modifying it in place. If an axis flagged for removal
+has a shape entry bigger than one, this effectively selects
+index zero for that axis.
+
+WARNING: If an axis flagged for removal has a shape equal to zero,
+the array will point to invalid memory. The caller must
+validate this!
+If an axis flagged for removal has a shape larger then one,
+the aligned flag (and in the future the contiguous flags),
+may need explicite update.
+(check also NPY_RELAXED_STRIDES_CHECKING)
+
+For example, this can be used to remove the reduction axes
+from a reduction result once its computation is complete.
+
+::
+
+  void
+  PyArray_DebugPrint(PyArrayObject *obj)
+
+Prints the raw data of the ndarray in a form useful for debugging
+low-level C issues.
+
+::
+
+  int
+  PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)
+
+
+This function does nothing if obj is writeable, and raises an exception
+(and returns -1) if obj is not writeable. It may also do other
+house-keeping, such as issuing warnings on arrays which are transitioning
+to become views. Always call this function at some point before writing to
+an array.
+
+'name' is a name for the array, used to give better error
+messages. Something like "assignment destination", "output array", or even
+just "array".
+
+::
+
+  int
+  PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base)
+
+
+Precondition: 'arr' is a copy of 'base' (though possibly with different
+strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the
+->base pointer on 'arr', so that when 'arr' is destructed, it will copy any
+changes back to 'base'.
+
+Steals a reference to 'base'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void *
+  PyDataMem_NEW(size_t size)
+
+Allocates memory for array data.
+
+::
+
+  void
+  PyDataMem_FREE(void *ptr)
+
+Free memory for array data.
+
+::
+
+  void *
+  PyDataMem_RENEW(void *ptr, size_t size)
+
+Reallocate/resize memory for array data.
+
+::
+
+  PyDataMem_EventHookFunc *
+  PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void
+                         *user_data, void **old_data)
+
+Sets the allocation event hook for numpy array data.
+Takes a PyDataMem_EventHookFunc *, which has the signature:
+void hook(void *old, void *new, size_t size, void *user_data).
+Also takes a void *user_data, and void **old_data.
+
+Returns a pointer to the previous hook or NULL.  If old_data is
+non-NULL, the previous user_data pointer will be copied to it.
+
+If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW:
+result = PyDataMem_NEW(size)        -> (*hook)(NULL, result, size, user_data)
+PyDataMem_FREE(ptr)                 -> (*hook)(ptr, NULL, 0, user_data)
+result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data)
+
+When the hook is called, the GIL will be held by the calling
+thread.  The hook should be written to be reentrant, if it performs
+operations that might cause new allocation events (such as the
+creation/descruction numpy objects, or creating/destroying Python
+objects which might cause a gc)
+
+::
+
+  void
+  PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject
+                          **ret, int getmap)
+
+
+::
+
+  PyObject *
+  PyArray_MapIterArray(PyArrayObject *a, PyObject *index)
+
+
+Use advanced indexing to iterate an array. Please note
+that most of this public API is currently not guaranteed
+to stay the same between versions. If you plan on using
+it, please consider adding more utility functions here
+to accommodate new features.
+
+::
+
+  void
+  PyArray_MapIterNext(PyArrayMapIterObject *mit)
+
+This function needs to update the state of the map iterator
+and point mit->dataptr to the memory-location of the next object
+
+Note that this function never handles an extra operand but provides
+compatibility for an old (exposed) API.
+
+::
+
+  int
+  PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int
+                    axis, NPY_SELECTKIND which)
+
+Partition an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int
+                       axis, NPY_SELECTKIND which)
+
+ArgPartition an array
+
+::
+
+  int
+  PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind)
+
+Convert object to select kind
+
+::
+
+  void *
+  PyDataMem_NEW_ZEROED(size_t size, size_t elsize)
+
+Allocates zeroed memory for array data.
+
+::
+
+  int
+  PyArray_CheckAnyScalarExact(PyObject *obj)
+
+return true an object is exactly a numpy scalar
+
diff --git a/tools/msys/mingw32/include/python2.7/numpy/ndarrayobject.h b/tools/msys/mingw32/include/python2.7/numpy/ndarrayobject.h
new file mode 100644
index 0000000000..c97a3a797a
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/ndarrayobject.h
@@ -0,0 +1,246 @@
+/*
+ * DON'T INCLUDE THIS DIRECTLY.
+ */
+
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#ifdef __cplusplus
+#define CONFUSE_EMACS {
+#define CONFUSE_EMACS2 }
+extern "C" CONFUSE_EMACS
+#undef CONFUSE_EMACS
+#undef CONFUSE_EMACS2
+/* ... otherwise a semi-smart identer (like emacs) tries to indent
+       everything when you're typing */
+#endif
+
+#include <Python.h>
+#include "ndarraytypes.h"
+
+/* Includes the "function" C-API -- these are all stored in a
+   list of pointers --- one for each file
+   The two lists are concatenated into one in multiarray.
+
+   They are available as import_array()
+*/
+
+#include "__multiarray_api.h"
+
+
+/* C-API that requries previous API to be defined */
+
+#define PyArray_DescrCheck(op) (((PyObject*)(op))->ob_type==&PyArrayDescr_Type)
+
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
+
+#define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
+        ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
+         (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
+         (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
+          Py_NotImplemented))
+
+#define PyArray_HasArrayInterface(op, out)                                    \
+        PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
+                               (PyArray_NDIM((PyArrayObject *)op) == 0))
+
+#define PyArray_IsScalar(obj, cls)                                            \
+        (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
+                                PyArray_IsZeroDim(m))
+#if PY_MAJOR_VERSION >= 3
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyFloat_Check(obj) || PyComplex_Check(obj) ||                        \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj)                       \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) ||                 \
+         PyUnicode_Check(obj))
+#else
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyInt_Check(obj) || PyFloat_Check(obj) || PyComplex_Check(obj) ||    \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyInt_Check(obj)                        \
+              || PyLong_Check(obj)                                            \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyString_Check(obj) ||                \
+         PyUnicode_Check(obj))
+#endif
+
+#define PyArray_IsAnyScalar(obj)                                              \
+        (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
+                                     PyArray_CheckScalar(obj))
+
+
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
+                                  Py_INCREF(m), (m) :                         \
+                                  (PyArrayObject *)(PyArray_Copy(m)))
+
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
+                                  PyArray_CompareLists(PyArray_DIMS(a1),      \
+                                                       PyArray_DIMS(a2),      \
+                                                       PyArray_NDIM(a1)))
+
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
+                                                      NULL)
+
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
+                                PyArray_DescrFromType(type), 0, 0, 0, NULL)
+
+#define PyArray_FROM_OTF(m, type, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
+
+#define PyArray_FROMANY(m, type, min, max, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
+
+#define PyArray_ZEROS(m, dims, type, is_f_order) \
+        PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_EMPTY(m, dims, type, is_f_order) \
+        PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
+                                           PyArray_NBYTES(obj))
+
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
+
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT, NULL)
+
+#define PyArray_EquivArrTypes(a1, a2) \
+        PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+
+#define PyArray_EquivByteorders(b1, b2) \
+        (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+
+#define PyArray_SimpleNew(nd, dims, typenum) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
+                    data, 0, NPY_ARRAY_CARRAY, NULL)
+
+#define PyArray_SimpleNewFromDescr(nd, dims, descr) \
+        PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
+                             NULL, NULL, 0, NULL)
+
+#define PyArray_ToScalar(data, arr) \
+        PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+
+
+/* These might be faster without the dereferencing of obj
+   going on inside -- of course an optimizing compiler should
+   inline the constants inside a for loop making it a moot point
+*/
+
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
+                                         (i)*PyArray_STRIDES(obj)[0]))
+
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1]))
+
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2]))
+
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2] + \
+                                            (l)*PyArray_STRIDES(obj)[3]))
+
+static NPY_INLINE void
+PyArray_XDECREF_ERR(PyArrayObject *arr)
+{
+    if (arr != NULL) {
+        if (PyArray_FLAGS(arr) & NPY_ARRAY_UPDATEIFCOPY) {
+            PyArrayObject *base = (PyArrayObject *)PyArray_BASE(arr);
+            PyArray_ENABLEFLAGS(base, NPY_ARRAY_WRITEABLE);
+            PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
+        }
+        Py_DECREF(arr);
+    }
+}
+
+#define PyArray_DESCR_REPLACE(descr) do { \
+                PyArray_Descr *_new_; \
+                _new_ = PyArray_DescrNew(descr); \
+                Py_XDECREF(descr); \
+                descr = _new_; \
+        } while(0)
+
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+
+#define PyArray_FromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_BEHAVED | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                        max_depth, NPY_ARRAY_ENSURECOPY | \
+                                   NPY_ARRAY_DEFAULT | \
+                                   NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_Cast(mp, type_num)                                            \
+        PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+
+#define PyArray_Take(ap, items, axis)                                         \
+        PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+
+#define PyArray_Put(ap, items, values)                                        \
+        PyArray_PutTo(ap, items, values, NPY_RAISE)
+
+/* Compatibility with old Numeric stuff -- don't use in new code */
+
+#define PyArray_FromDimsAndData(nd, d, type, data)                            \
+        PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
+                                        data)
+
+
+/*
+   Check to see if this key in the dictionary is the "title"
+   entry of the tuple (i.e. a duplicate dictionary entry in the fields
+   dict.
+*/
+
+#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \
+                                   (PyTuple_GET_ITEM((value), 2) == (key)))
+
+
+#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
+#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* NPY_NDARRAYOBJECT_H */
diff --git a/tools/msys/mingw32/include/python2.7/numpy/ndarraytypes.h b/tools/msys/mingw32/include/python2.7/numpy/ndarraytypes.h
new file mode 100644
index 0000000000..f1fe89f1a1
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/ndarraytypes.h
@@ -0,0 +1,1793 @@
+#ifndef NDARRAYTYPES_H
+#define NDARRAYTYPES_H
+
+#include "npy_common.h"
+#include "npy_endian.h"
+#include "npy_cpu.h"
+#include "utils.h"
+
+#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN
+
+/* Only use thread if configured in config and python supports it */
+#if defined WITH_THREAD && !NPY_NO_SMP
+        #define NPY_ALLOW_THREADS 1
+#else
+        #define NPY_ALLOW_THREADS 0
+#endif
+
+
+
+/*
+ * There are several places in the code where an array of dimensions
+ * is allocated statically.  This is the size of that static
+ * allocation.
+ *
+ * The array creation itself could have arbitrary dimensions but all
+ * the places where static allocation is used would need to be changed
+ * to dynamic (including inside of several structures)
+ */
+
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+
+/*
+ * Binary compatibility version number.  This number is increased
+ * whenever the C-API is changed such that binary compatibility is
+ * broken, i.e. whenever a recompile of extension modules is needed.
+ */
+#define NPY_VERSION NPY_ABI_VERSION
+
+/*
+ * Minor API version.  This number is increased whenever a change is
+ * made to the C-API -- whether it breaks binary compatibility or not.
+ * Some changes, such as adding a function pointer to the end of the
+ * function table, can be made without breaking binary compatibility.
+ * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION)
+ * would be increased.  Whenever binary compatibility is broken, both
+ * NPY_VERSION and NPY_FEATURE_VERSION should be increased.
+ */
+#define NPY_FEATURE_VERSION NPY_API_VERSION
+
+enum NPY_TYPES {    NPY_BOOL=0,
+                    NPY_BYTE, NPY_UBYTE,
+                    NPY_SHORT, NPY_USHORT,
+                    NPY_INT, NPY_UINT,
+                    NPY_LONG, NPY_ULONG,
+                    NPY_LONGLONG, NPY_ULONGLONG,
+                    NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+                    NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+                    NPY_OBJECT=17,
+                    NPY_STRING, NPY_UNICODE,
+                    NPY_VOID,
+                    /*
+                     * New 1.6 types appended, may be integrated
+                     * into the above in 2.0.
+                     */
+                    NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF,
+
+                    NPY_NTYPES,
+                    NPY_NOTYPE,
+                    NPY_CHAR,      /* special flag */
+                    NPY_USERDEF=256,  /* leave room for characters */
+
+                    /* The number of types not including the new 1.6 types */
+                    NPY_NTYPES_ABI_COMPATIBLE=21
+};
+
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+
+/* How many floating point types are there (excluding half) */
+#define NPY_NUM_FLOATTYPE 3
+
+/*
+ * These characters correspond to the array type and the struct
+ * module
+ */
+
+enum NPY_TYPECHAR {
+        NPY_BOOLLTR = '?',
+        NPY_BYTELTR = 'b',
+        NPY_UBYTELTR = 'B',
+        NPY_SHORTLTR = 'h',
+        NPY_USHORTLTR = 'H',
+        NPY_INTLTR = 'i',
+        NPY_UINTLTR = 'I',
+        NPY_LONGLTR = 'l',
+        NPY_ULONGLTR = 'L',
+        NPY_LONGLONGLTR = 'q',
+        NPY_ULONGLONGLTR = 'Q',
+        NPY_HALFLTR = 'e',
+        NPY_FLOATLTR = 'f',
+        NPY_DOUBLELTR = 'd',
+        NPY_LONGDOUBLELTR = 'g',
+        NPY_CFLOATLTR = 'F',
+        NPY_CDOUBLELTR = 'D',
+        NPY_CLONGDOUBLELTR = 'G',
+        NPY_OBJECTLTR = 'O',
+        NPY_STRINGLTR = 'S',
+        NPY_STRINGLTR2 = 'a',
+        NPY_UNICODELTR = 'U',
+        NPY_VOIDLTR = 'V',
+        NPY_DATETIMELTR = 'M',
+        NPY_TIMEDELTALTR = 'm',
+        NPY_CHARLTR = 'c',
+
+        /*
+         * No Descriptor, just a define -- this let's
+         * Python users specify an array of integers
+         * large enough to hold a pointer on the
+         * platform
+         */
+        NPY_INTPLTR = 'p',
+        NPY_UINTPLTR = 'P',
+
+        /*
+         * These are for dtype 'kinds', not dtype 'typecodes'
+         * as the above are for.
+         */
+        NPY_GENBOOLLTR ='b',
+        NPY_SIGNEDLTR = 'i',
+        NPY_UNSIGNEDLTR = 'u',
+        NPY_FLOATINGLTR = 'f',
+        NPY_COMPLEXLTR = 'c'
+};
+
+typedef enum {
+        NPY_QUICKSORT=0,
+        NPY_HEAPSORT=1,
+        NPY_MERGESORT=2
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_MERGESORT + 1)
+
+
+typedef enum {
+        NPY_INTROSELECT=0
+} NPY_SELECTKIND;
+#define NPY_NSELECTS (NPY_INTROSELECT + 1)
+
+
+typedef enum {
+        NPY_SEARCHLEFT=0,
+        NPY_SEARCHRIGHT=1
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+
+
+typedef enum {
+        NPY_NOSCALAR=-1,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+
+/* For specifying array memory layout or iteration order */
+typedef enum {
+        /* Fortran order if inputs are all Fortran, C otherwise */
+        NPY_ANYORDER=-1,
+        /* C order */
+        NPY_CORDER=0,
+        /* Fortran order */
+        NPY_FORTRANORDER=1,
+        /* An order as close to the inputs as possible */
+        NPY_KEEPORDER=2
+} NPY_ORDER;
+
+/* For specifying allowed casting in operations which support it */
+typedef enum {
+        /* Only allow identical types */
+        NPY_NO_CASTING=0,
+        /* Allow identical and byte swapped types */
+        NPY_EQUIV_CASTING=1,
+        /* Only allow safe casts */
+        NPY_SAFE_CASTING=2,
+        /* Allow safe casts or casts within the same kind */
+        NPY_SAME_KIND_CASTING=3,
+        /* Allow any casts */
+        NPY_UNSAFE_CASTING=4
+} NPY_CASTING;
+
+typedef enum {
+        NPY_CLIP=0,
+        NPY_WRAP=1,
+        NPY_RAISE=2
+} NPY_CLIPMODE;
+
+/* The special not-a-time (NaT) value */
+#define NPY_DATETIME_NAT NPY_MIN_INT64
+
+/*
+ * Upper bound on the length of a DATETIME ISO 8601 string
+ *   YEAR: 21 (64-bit year)
+ *   MONTH: 3
+ *   DAY: 3
+ *   HOURS: 3
+ *   MINUTES: 3
+ *   SECONDS: 3
+ *   ATTOSECONDS: 1 + 3*6
+ *   TIMEZONE: 5
+ *   NULL TERMINATOR: 1
+ */
+#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
+
+typedef enum {
+        NPY_FR_Y = 0,  /* Years */
+        NPY_FR_M = 1,  /* Months */
+        NPY_FR_W = 2,  /* Weeks */
+        /* Gap where 1.6 NPY_FR_B (value 3) was */
+        NPY_FR_D = 4,  /* Days */
+        NPY_FR_h = 5,  /* hours */
+        NPY_FR_m = 6,  /* minutes */
+        NPY_FR_s = 7,  /* seconds */
+        NPY_FR_ms = 8, /* milliseconds */
+        NPY_FR_us = 9, /* microseconds */
+        NPY_FR_ns = 10,/* nanoseconds */
+        NPY_FR_ps = 11,/* picoseconds */
+        NPY_FR_fs = 12,/* femtoseconds */
+        NPY_FR_as = 13,/* attoseconds */
+        NPY_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */
+} NPY_DATETIMEUNIT;
+
+/*
+ * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS
+ *       is technically one more than the actual number of units.
+ */
+#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1)
+#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC
+
+/*
+ * Business day conventions for mapping invalid business
+ * days to valid business days.
+ */
+typedef enum {
+    /* Go forward in time to the following business day. */
+    NPY_BUSDAY_FORWARD,
+    NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD,
+    /* Go backward in time to the preceding business day. */
+    NPY_BUSDAY_BACKWARD,
+    NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD,
+    /*
+     * Go forward in time to the following business day, unless it
+     * crosses a month boundary, in which case go backward
+     */
+    NPY_BUSDAY_MODIFIEDFOLLOWING,
+    /*
+     * Go backward in time to the preceding business day, unless it
+     * crosses a month boundary, in which case go forward.
+     */
+    NPY_BUSDAY_MODIFIEDPRECEDING,
+    /* Produce a NaT for non-business days. */
+    NPY_BUSDAY_NAT,
+    /* Raise an exception for non-business days. */
+    NPY_BUSDAY_RAISE
+} NPY_BUSDAY_ROLL;
+
+/************************************************************
+ * NumPy Auxiliary Data for inner loops, sort functions, etc.
+ ************************************************************/
+
+/*
+ * When creating an auxiliary data struct, this should always appear
+ * as the first member, like this:
+ *
+ * typedef struct {
+ *     NpyAuxData base;
+ *     double constant;
+ * } constant_multiplier_aux_data;
+ */
+typedef struct NpyAuxData_tag NpyAuxData;
+
+/* Function pointers for freeing or cloning auxiliary data */
+typedef void (NpyAuxData_FreeFunc) (NpyAuxData *);
+typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *);
+
+struct NpyAuxData_tag {
+    NpyAuxData_FreeFunc *free;
+    NpyAuxData_CloneFunc *clone;
+    /* To allow for a bit of expansion without breaking the ABI */
+    void *reserved[2];
+};
+
+/* Macros to use for freeing and cloning auxiliary data */
+#define NPY_AUXDATA_FREE(auxdata) \
+    do { \
+        if ((auxdata) != NULL) { \
+            (auxdata)->free(auxdata); \
+        } \
+    } while(0)
+#define NPY_AUXDATA_CLONE(auxdata) \
+    ((auxdata)->clone(auxdata))
+
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+
+  /*
+   * Macros to define how array, and dimension/strides data is
+   * allocated.
+   */
+
+  /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */
+
+#define NPY_USE_PYMEM 1
+
+#if NPY_USE_PYMEM == 1
+#define PyArray_malloc PyMem_Malloc
+#define PyArray_free PyMem_Free
+#define PyArray_realloc PyMem_Realloc
+#else
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+#endif
+
+/* Dimensions and strides */
+#define PyDimMem_NEW(size)                                         \
+    ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+
+#define PyDimMem_RENEW(ptr,size)                                   \
+        ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+
+/* forward declaration */
+struct _PyArray_Descr;
+
+/* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+                                     npy_intp, int, void *);
+
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+
+
+/*
+ * These assume aligned and notswapped data -- a buffer will be used
+ * before or contiguous data will be obtained
+ */
+
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+                               npy_intp, void *);
+
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+                                       void *);
+
+/*
+ * XXX the ignore argument should be removed next time the API version
+ * is bumped. It used to be the separator.
+ */
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+                               char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+                                  struct _PyArray_Descr *);
+
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
+                                    npy_intp *, npy_intp *,
+                                    void *);
+typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
+                                       npy_intp *, npy_intp *,
+                                       void *);
+
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+
+typedef int (PyArray_ScalarKindFunc)(void *);
+
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in,
+                                       void *values, npy_intp nv);
+typedef int  (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray,
+                                       npy_intp nindarray, npy_intp n_outer,
+                                       npy_intp m_middle, npy_intp nelem,
+                                       NPY_CLIPMODE clipmode);
+
+typedef struct {
+        npy_intp *ptr;
+        int len;
+} PyArray_Dims;
+
+typedef struct {
+        /*
+         * Functions to cast to most other standard types
+         * Can have some NULL entries. The types
+         * DATETIME, TIMEDELTA, and HALF go into the castdict
+         * even though they are built-in.
+         */
+        PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
+
+        /* The next four functions *cannot* be NULL */
+
+        /*
+         * Functions to get and set items with standard Python types
+         * -- not array scalars
+         */
+        PyArray_GetItemFunc *getitem;
+        PyArray_SetItemFunc *setitem;
+
+        /*
+         * Copy and/or swap data.  Memory areas may not overlap
+         * Use memmove first if they might
+         */
+        PyArray_CopySwapNFunc *copyswapn;
+        PyArray_CopySwapFunc *copyswap;
+
+        /*
+         * Function to compare items
+         * Can be NULL
+         */
+        PyArray_CompareFunc *compare;
+
+        /*
+         * Function to select largest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmax;
+
+        /*
+         * Function to compute dot product
+         * Can be NULL
+         */
+        PyArray_DotFunc *dotfunc;
+
+        /*
+         * Function to scan an ASCII file and
+         * place a single value plus possible separator
+         * Can be NULL
+         */
+        PyArray_ScanFunc *scanfunc;
+
+        /*
+         * Function to read a single value from a string
+         * and adjust the pointer; Can be NULL
+         */
+        PyArray_FromStrFunc *fromstr;
+
+        /*
+         * Function to determine if data is zero or not
+         * If NULL a default version is
+         * used at Registration time.
+         */
+        PyArray_NonzeroFunc *nonzero;
+
+        /*
+         * Used for arange.
+         * Can be NULL.
+         */
+        PyArray_FillFunc *fill;
+
+        /*
+         * Function to fill arrays with scalar values
+         * Can be NULL
+         */
+        PyArray_FillWithScalarFunc *fillwithscalar;
+
+        /*
+         * Sorting functions
+         * Can be NULL
+         */
+        PyArray_SortFunc *sort[NPY_NSORTS];
+        PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+
+        /*
+         * Dictionary of additional casting functions
+         * PyArray_VectorUnaryFuncs
+         * which can be populated to support casting
+         * to other registered types. Can be NULL
+         */
+        PyObject *castdict;
+
+        /*
+         * Functions useful for generalizing
+         * the casting rules.
+         * Can be NULL;
+         */
+        PyArray_ScalarKindFunc *scalarkind;
+        int **cancastscalarkindto;
+        int *cancastto;
+
+        PyArray_FastClipFunc *fastclip;
+        PyArray_FastPutmaskFunc *fastputmask;
+        PyArray_FastTakeFunc *fasttake;
+
+        /*
+         * Function to select smallest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmin;
+
+} PyArray_ArrFuncs;
+
+/* The item must be reference counted when it is inserted or extracted. */
+#define NPY_ITEM_REFCOUNT   0x01
+/* Same as needing REFCOUNT */
+#define NPY_ITEM_HASOBJECT  0x01
+/* Convert to list for pickling */
+#define NPY_LIST_PICKLE     0x02
+/* The item is a POINTER  */
+#define NPY_ITEM_IS_POINTER 0x04
+/* memory needs to be initialized for this data-type */
+#define NPY_NEEDS_INIT      0x08
+/* operations need Python C-API so don't give-up thread. */
+#define NPY_NEEDS_PYAPI     0x10
+/* Use f.getitem when extracting elements of this data-type */
+#define NPY_USE_GETITEM     0x20
+/* Use f.setitem when setting creating 0-d array from this data-type.*/
+#define NPY_USE_SETITEM     0x40
+/* A sticky flag specifically for structured arrays */
+#define NPY_ALIGNED_STRUCT  0x80
+
+/*
+ *These are inherited for global data-type if any data-types in the
+ * field have them
+ */
+#define NPY_FROM_FIELDS    (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \
+                            NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \
+                                NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+                                NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+
+#define PyDataType_FLAGCHK(dtype, flag) \
+        (((dtype)->flags & (flag)) == (flag))
+
+#define PyDataType_REFCHK(dtype) \
+        PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+
+typedef struct _PyArray_Descr {
+        PyObject_HEAD
+        /*
+         * the type object representing an
+         * instance of this type -- should not
+         * be two type_numbers with the same type
+         * object.
+         */
+        PyTypeObject *typeobj;
+        /* kind for this type */
+        char kind;
+        /* unique-character representing this type */
+        char type;
+        /*
+         * '>' (big), '<' (little), '|'
+         * (not-applicable), or '=' (native).
+         */
+        char byteorder;
+        /* flags describing data type */
+        char flags;
+        /* number representing this type */
+        int type_num;
+        /* element size (itemsize) for this type */
+        int elsize;
+        /* alignment needed for this type */
+        int alignment;
+        /*
+         * Non-NULL if this type is
+         * is an array (C-contiguous)
+         * of some other type
+         */
+        struct _arr_descr *subarray;
+        /*
+         * The fields dictionary for this type
+         * For statically defined descr this
+         * is always Py_None
+         */
+        PyObject *fields;
+        /*
+         * An ordered tuple of field names or NULL
+         * if no fields are defined
+         */
+        PyObject *names;
+        /*
+         * a table of functions specific for each
+         * basic data descriptor
+         */
+        PyArray_ArrFuncs *f;
+        /* Metadata about this dtype */
+        PyObject *metadata;
+        /*
+         * Metadata specific to the C implementation
+         * of the particular dtype. This was added
+         * for NumPy 1.7.0.
+         */
+        NpyAuxData *c_metadata;
+        /* Cached hash value (-1 if not yet computed).
+         * This was added for NumPy 2.0.0.
+         */
+        npy_hash_t hash;
+} PyArray_Descr;
+
+typedef struct _arr_descr {
+        PyArray_Descr *base;
+        PyObject *shape;       /* a tuple */
+} PyArray_ArrayDescr;
+
+/*
+ * The main array object structure.
+ *
+ * It has been recommended to use the inline functions defined below
+ * (PyArray_DATA and friends) to access fields here for a number of
+ * releases. Direct access to the members themselves is deprecated.
+ * To ensure that your code does not use deprecated access,
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
+ */
+/* This struct will be moved to a private header in a future release */
+typedef struct tagPyArrayObject_fields {
+    PyObject_HEAD
+    /* Pointer to the raw data buffer */
+    char *data;
+    /* The number of dimensions, also called 'ndim' */
+    int nd;
+    /* The size in each dimension, also called 'shape' */
+    npy_intp *dimensions;
+    /*
+     * Number of bytes to jump to get to the
+     * next element in each dimension
+     */
+    npy_intp *strides;
+    /*
+     * This object is decref'd upon
+     * deletion of array. Except in the
+     * case of UPDATEIFCOPY which has
+     * special handling.
+     *
+     * For views it points to the original
+     * array, collapsed so no chains of
+     * views occur.
+     *
+     * For creation from buffer object it
+     * points to an object that shold be
+     * decref'd on deletion
+     *
+     * For UPDATEIFCOPY flag this is an
+     * array to-be-updated upon deletion
+     * of this one
+     */
+    PyObject *base;
+    /* Pointer to type structure */
+    PyArray_Descr *descr;
+    /* Flags describing array -- see below */
+    int flags;
+    /* For weak references */
+    PyObject *weakreflist;
+} PyArrayObject_fields;
+
+/*
+ * To hide the implementation details, we only expose
+ * the Python struct HEAD.
+ */
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+/*
+ * Can't put this in npy_deprecated_api.h like the others.
+ * PyArrayObject field access is deprecated as of NumPy 1.7.
+ */
+typedef PyArrayObject_fields PyArrayObject;
+#else
+typedef struct tagPyArrayObject {
+        PyObject_HEAD
+} PyArrayObject;
+#endif
+
+#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
+
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+        PyObject_HEAD
+        PyObject *arr;
+        int flags;
+} PyArrayFlagsObject;
+
+/* Mirrors buffer object to ptr */
+
+typedef struct {
+        PyObject_HEAD
+        PyObject *base;
+        void *ptr;
+        npy_intp len;
+        int flags;
+} PyArray_Chunk;
+
+typedef struct {
+    NPY_DATETIMEUNIT base;
+    int num;
+} PyArray_DatetimeMetaData;
+
+typedef struct {
+    NpyAuxData base;
+    PyArray_DatetimeMetaData meta;
+} PyArray_DatetimeDTypeMetaData;
+
+/*
+ * This structure contains an exploded view of a date-time value.
+ * NaT is represented by year == NPY_DATETIME_NAT.
+ */
+typedef struct {
+        npy_int64 year;
+        npy_int32 month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+
+/* This is not used internally. */
+typedef struct {
+        npy_int64 day;
+        npy_int32 sec, us, ps, as;
+} npy_timedeltastruct;
+
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+
+/*
+ * Means c-style contiguous (last index varies the fastest). The data
+ * elements right after each other.
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_C_CONTIGUOUS    0x0001
+
+/*
+ * Set if array is a contiguous Fortran array: the first index varies
+ * the fastest in memory (strides array is reverse of C-contiguous
+ * array)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_F_CONTIGUOUS    0x0002
+
+/*
+ * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a
+ * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
+ * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
+ * at the same time if they have either zero or one element.
+ * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
+ * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
+ * and the array is contiguous if ndarray.squeeze() is contiguous.
+ * I.e. dimensions for which `ndarray.shape[dimension] == 1` are
+ * ignored.
+ */
+
+/*
+ * If set, the array owns the data: it will be free'd when the array
+ * is deleted.
+ *
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_OWNDATA         0x0004
+
+/*
+ * An array never has the next four set; they're only used as parameter
+ * flags to the the various FromAny functions
+ *
+ * This flag may be requested in constructor functions.
+ */
+
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_ARRAY_FORCECAST       0x0010
+
+/*
+ * Always copy the array. Returned arrays are always CONTIGUOUS,
+ * ALIGNED, and WRITEABLE.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSURECOPY      0x0020
+
+/*
+ * Make sure the returned array is a base-class ndarray
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSUREARRAY     0x0040
+
+/*
+ * Make sure that the strides are in units of the element size Needed
+ * for some operations with record-arrays.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ELEMENTSTRIDES  0x0080
+
+/*
+ * Array data is aligned on the appropiate memory address for the type
+ * stored according to how the compiler would align things (e.g., an
+ * array of integers (4 bytes each) starts on a memory address that's
+ * a multiple of 4)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_ALIGNED         0x0100
+
+/*
+ * Array data has the native endianness
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_NOTSWAPPED      0x0200
+
+/*
+ * Array data is writeable
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_WRITEABLE       0x0400
+
+/*
+ * If this flag is set, then base contains a pointer to an array of
+ * the same size that should be updated with the current contents of
+ * this array when this array is deallocated
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_UPDATEIFCOPY    0x1000
+
+/*
+ * NOTE: there are also internal flags defined in multiarray/arrayobject.h,
+ * which start at bit 31 and work down.
+ */
+
+#define NPY_ARRAY_BEHAVED      (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE)
+#define NPY_ARRAY_BEHAVED_NS   (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE | \
+                                NPY_ARRAY_NOTSWAPPED)
+#define NPY_ARRAY_CARRAY       (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_CARRAY_RO    (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_FARRAY       (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_FARRAY_RO    (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_DEFAULT      (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_IN_ARRAY     (NPY_ARRAY_CARRAY_RO)
+#define NPY_ARRAY_OUT_ARRAY    (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_INOUT_ARRAY  (NPY_ARRAY_CARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+#define NPY_ARRAY_IN_FARRAY    (NPY_ARRAY_FARRAY_RO)
+#define NPY_ARRAY_OUT_FARRAY   (NPY_ARRAY_FARRAY)
+#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+
+#define NPY_ARRAY_UPDATE_ALL   (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+
+/* This flag is for the array interface, not PyArrayObject */
+#define NPY_ARR_HAS_DESCR  0x0800
+
+
+
+
+/*
+ * Size of internal buffers used for alignment Make BUFSIZE a multiple
+ * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned
+ */
+#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000)
+#define NPY_BUFSIZE 8192
+/* buffer stress test size: */
+/*#define NPY_BUFSIZE 17*/
+
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+
+/*
+ * C API: consists of Macros and functions.  The MACROS are defined
+ * here.
+ */
+
+
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED)
+
+#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS)
+
+/* the variable is used in some places, so always define it */
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+#define NPY_END_THREADS   do { if (_save) \
+                { PyEval_RestoreThread(_save); _save = NULL;} } while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+                { _save = PyEval_SaveThread();} } while (0);
+
+#define NPY_BEGIN_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_BEGIN_THREADS;} while (0);
+
+#define NPY_END_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_END_THREADS; } while (0);
+
+#define NPY_ALLOW_C_API_DEF  PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API      do {__save__ = PyGILState_Ensure();} while (0);
+#define NPY_DISABLE_C_API    do {PyGILState_Release(__save__);} while (0);
+#else
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size)
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+#endif
+
+/**********************************
+ * The nditer object, added in 1.6
+ **********************************/
+
+/* The actual structure of the iterator is an internal detail */
+typedef struct NpyIter_InternalOnly NpyIter;
+
+/* Iterator function pointers that may be specialized */
+typedef int (NpyIter_IterNextFunc)(NpyIter *iter);
+typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter,
+                                      npy_intp *outcoords);
+
+/*** Global flags that may be passed to the iterator constructors ***/
+
+/* Track an index representing C order */
+#define NPY_ITER_C_INDEX                    0x00000001
+/* Track an index representing Fortran order */
+#define NPY_ITER_F_INDEX                    0x00000002
+/* Track a multi-index */
+#define NPY_ITER_MULTI_INDEX                0x00000004
+/* User code external to the iterator does the 1-dimensional innermost loop */
+#define NPY_ITER_EXTERNAL_LOOP              0x00000008
+/* Convert all the operands to a common data type */
+#define NPY_ITER_COMMON_DTYPE               0x00000010
+/* Operands may hold references, requiring API access during iteration */
+#define NPY_ITER_REFS_OK                    0x00000020
+/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */
+#define NPY_ITER_ZEROSIZE_OK                0x00000040
+/* Permits reductions (size-0 stride with dimension size > 1) */
+#define NPY_ITER_REDUCE_OK                  0x00000080
+/* Enables sub-range iteration */
+#define NPY_ITER_RANGED                     0x00000100
+/* Enables buffering */
+#define NPY_ITER_BUFFERED                   0x00000200
+/* When buffering is enabled, grows the inner loop if possible */
+#define NPY_ITER_GROWINNER                  0x00000400
+/* Delay allocation of buffers until first Reset* call */
+#define NPY_ITER_DELAY_BUFALLOC             0x00000800
+/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */
+#define NPY_ITER_DONT_NEGATE_STRIDES        0x00001000
+
+/*** Per-operand flags that may be passed to the iterator constructors ***/
+
+/* The operand will be read from and written to */
+#define NPY_ITER_READWRITE                  0x00010000
+/* The operand will only be read from */
+#define NPY_ITER_READONLY                   0x00020000
+/* The operand will only be written to */
+#define NPY_ITER_WRITEONLY                  0x00040000
+/* The operand's data must be in native byte order */
+#define NPY_ITER_NBO                        0x00080000
+/* The operand's data must be aligned */
+#define NPY_ITER_ALIGNED                    0x00100000
+/* The operand's data must be contiguous (within the inner loop) */
+#define NPY_ITER_CONTIG                     0x00200000
+/* The operand may be copied to satisfy requirements */
+#define NPY_ITER_COPY                       0x00400000
+/* The operand may be copied with UPDATEIFCOPY to satisfy requirements */
+#define NPY_ITER_UPDATEIFCOPY               0x00800000
+/* Allocate the operand if it is NULL */
+#define NPY_ITER_ALLOCATE                   0x01000000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE                 0x02000000
+/* This is a virtual array slot, operand is NULL but temporary data is there */
+#define NPY_ITER_VIRTUAL                    0x04000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST               0x08000000
+/* A mask is being used on this array, affects buffer -> array copy */
+#define NPY_ITER_WRITEMASKED                0x10000000
+/* This array is the mask for all WRITEMASKED operands */
+#define NPY_ITER_ARRAYMASK                  0x20000000
+
+#define NPY_ITER_GLOBAL_FLAGS               0x0000ffff
+#define NPY_ITER_PER_OP_FLAGS               0xffff0000
+
+
+/*****************************
+ * Basic iterator object
+ *****************************/
+
+/* FWD declaration */
+typedef struct PyArrayIterObject_tag PyArrayIterObject;
+
+/*
+ * type of the function which translates a set of coordinates to a
+ * pointer to the data
+ */
+typedef char* (*npy_iter_get_dataptr_t)(PyArrayIterObject* iter, npy_intp*);
+
+struct PyArrayIterObject_tag {
+        PyObject_HEAD
+        int               nd_m1;            /* number of dimensions - 1 */
+        npy_intp          index, size;
+        npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+        npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+        npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+        npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+        npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+        PyArrayObject     *ao;
+        char              *dataptr;        /* pointer to current item*/
+        npy_bool          contiguous;
+
+        npy_intp          bounds[NPY_MAXDIMS][2];
+        npy_intp          limits[NPY_MAXDIMS][2];
+        npy_intp          limits_sizes[NPY_MAXDIMS];
+        npy_iter_get_dataptr_t translate;
+} ;
+
+
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) do { \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        memset(_PyAIT(it)->coordinates, 0, \
+               (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \
+} while (0)
+
+#define _PyArray_ITER_NEXT1(it) do { \
+        (it)->dataptr += _PyAIT(it)->strides[0]; \
+        (it)->coordinates[0]++; \
+} while (0)
+
+#define _PyArray_ITER_NEXT2(it) do { \
+        if ((it)->coordinates[1] < (it)->dims_m1[1]) { \
+                (it)->coordinates[1]++; \
+                (it)->dataptr += (it)->strides[1]; \
+        } \
+        else { \
+                (it)->coordinates[1] = 0; \
+                (it)->coordinates[0]++; \
+                (it)->dataptr += (it)->strides[0] - \
+                        (it)->backstrides[1]; \
+        } \
+} while (0)
+
+#define PyArray_ITER_NEXT(it) do { \
+        _PyAIT(it)->index++; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyArray_ITER_NEXT1(_PyAIT(it)); \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else if (_PyAIT(it)->nd_m1 == 1) { \
+                _PyArray_ITER_NEXT2(_PyAIT(it)); \
+        } \
+        else { \
+                int __npy_i; \
+                for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+                        if (_PyAIT(it)->coordinates[__npy_i] < \
+                            _PyAIT(it)->dims_m1[__npy_i]) { \
+                                _PyAIT(it)->coordinates[__npy_i]++; \
+                                _PyAIT(it)->dataptr += \
+                                        _PyAIT(it)->strides[__npy_i]; \
+                                break; \
+                        } \
+                        else { \
+                                _PyAIT(it)->coordinates[__npy_i] = 0; \
+                                _PyAIT(it)->dataptr -= \
+                                        _PyAIT(it)->backstrides[__npy_i]; \
+                        } \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO(it, destination) do { \
+        int __npy_i; \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \
+                if (destination[__npy_i] < 0) { \
+                        destination[__npy_i] += \
+                                _PyAIT(it)->dims_m1[__npy_i]+1; \
+                } \
+                _PyAIT(it)->dataptr += destination[__npy_i] * \
+                        _PyAIT(it)->strides[__npy_i]; \
+                _PyAIT(it)->coordinates[__npy_i] = \
+                        destination[__npy_i]; \
+                _PyAIT(it)->index += destination[__npy_i] * \
+                        ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \
+                          _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO1D(it, ind) do { \
+        int __npy_i; \
+        npy_intp __npy_ind = (npy_intp) (ind); \
+        if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \
+        _PyAIT(it)->index = __npy_ind; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * _PyAIT(it)->strides[0]; \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+                for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
+                     __npy_i++) { \
+                        _PyAIT(it)->dataptr += \
+                                (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+                                * _PyAIT(it)->strides[__npy_i]; \
+                        __npy_ind %= _PyAIT(it)->factors[__npy_i]; \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+
+
+/*
+ * Any object passed to PyArray_Broadcast must be binary compatible
+ * with this structure.
+ */
+
+typedef struct {
+        PyObject_HEAD
+        int                  numiter;                 /* number of iters */
+        npy_intp             size;                    /* broadcasted size */
+        npy_intp             index;                   /* current index */
+        int                  nd;                      /* number of dims */
+        npy_intp             dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject    *iters[NPY_MAXARGS];     /* iterators */
+} PyArrayMultiIterObject;
+
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) do {                                   \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index = 0;                                             \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;  __npy_mi++) {    \
+                PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]);           \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_NEXT(multi) do {                                    \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index++;                                               \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;   __npy_mi++) {   \
+                PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]);            \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_GOTO(multi, dest) do {                            \
+        int __npy_mi;                                                       \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {   \
+                PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest);    \
+        }                                                                   \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;              \
+} while (0)
+
+#define PyArray_MultiIter_GOTO1D(multi, ind) do {                          \
+        int __npy_mi;                                                      \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {  \
+                PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind);  \
+        }                                                                  \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;             \
+} while (0)
+
+#define PyArray_MultiIter_DATA(multi, i)                \
+        ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+
+#define PyArray_MultiIter_NEXTi(multi, i)               \
+        PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+
+#define PyArray_MultiIter_NOTDONE(multi)                \
+        (_PyMIT(multi)->index < _PyMIT(multi)->size)
+
+
+/*
+ * Store the information needed for fancy-indexing over an array. The
+ * fields are slightly unordered to keep consec, dataptr and subspace
+ * where they were originally.
+ */
+typedef struct {
+        PyObject_HEAD
+        /*
+         * Multi-iterator portion --- needs to be present in this
+         * order to work with PyArray_Broadcast
+         */
+
+        int                   numiter;                 /* number of index-array
+                                                          iterators */
+        npy_intp              size;                    /* size of broadcasted
+                                                          result */
+        npy_intp              index;                   /* current index */
+        int                   nd;                      /* number of dims */
+        npy_intp              dimensions[NPY_MAXDIMS]; /* dimensions */
+        NpyIter               *outer;                  /* index objects
+                                                          iterator */
+        void                  *unused[NPY_MAXDIMS - 2];
+        PyArrayObject         *array;
+        /* Flat iterator for the indexed array. For compatibility solely. */
+        PyArrayIterObject     *ait;
+
+        /*
+         * Subspace array. For binary compatibility (was an iterator,
+         * but only the check for NULL should be used).
+         */
+        PyArrayObject         *subspace;
+
+        /*
+         * if subspace iteration, then this is the array of axes in
+         * the underlying array represented by the index objects
+         */
+        int                   iteraxes[NPY_MAXDIMS];
+        npy_intp              fancy_strides[NPY_MAXDIMS];
+
+        /* pointer when all fancy indices are 0 */
+        char                  *baseoffset;
+
+        /*
+         * after binding consec denotes at which axis the fancy axes
+         * are inserted.
+         */
+        int                   consec;
+        char                  *dataptr;
+
+        int                   nd_fancy;
+        npy_intp              fancy_dims[NPY_MAXDIMS];
+
+        /* Whether the iterator (any of the iterators) requires API */
+        int                   needs_api;
+
+        /*
+         * Extra op information.
+         */
+        PyArrayObject         *extra_op;
+        PyArray_Descr         *extra_op_dtype;         /* desired dtype */
+        npy_uint32            *extra_op_flags;         /* Iterator flags */
+
+        NpyIter               *extra_op_iter;
+        NpyIter_IterNextFunc  *extra_op_next;
+        char                  **extra_op_ptrs;
+
+        /*
+         * Information about the iteration state.
+         */
+        NpyIter_IterNextFunc  *outer_next;
+        char                  **outer_ptrs;
+        npy_intp              *outer_strides;
+
+        /*
+         * Information about the subspace iterator.
+         */
+        NpyIter               *subspace_iter;
+        NpyIter_IterNextFunc  *subspace_next;
+        char                  **subspace_ptrs;
+        npy_intp              *subspace_strides;
+
+        /* Count for the external loop (which ever it is) for API iteration */
+        npy_intp              iter_count;
+
+} PyArrayMapIterObject;
+
+enum {
+    NPY_NEIGHBORHOOD_ITER_ZERO_PADDING,
+    NPY_NEIGHBORHOOD_ITER_ONE_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING,
+    NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING
+};
+
+typedef struct {
+    PyObject_HEAD
+
+    /*
+     * PyArrayIterObject part: keep this in this exact order
+     */
+    int               nd_m1;            /* number of dimensions - 1 */
+    npy_intp          index, size;
+    npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+    npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+    npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+    npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+    npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+    PyArrayObject     *ao;
+    char              *dataptr;        /* pointer to current item*/
+    npy_bool          contiguous;
+
+    npy_intp          bounds[NPY_MAXDIMS][2];
+    npy_intp          limits[NPY_MAXDIMS][2];
+    npy_intp          limits_sizes[NPY_MAXDIMS];
+    npy_iter_get_dataptr_t translate;
+
+    /*
+     * New members
+     */
+    npy_intp nd;
+
+    /* Dimensions is the dimension of the array */
+    npy_intp dimensions[NPY_MAXDIMS];
+
+    /*
+     * Neighborhood points coordinates are computed relatively to the
+     * point pointed by _internal_iter
+     */
+    PyArrayIterObject* _internal_iter;
+    /*
+     * To keep a reference to the representation of the constant value
+     * for constant padding
+     */
+    char* constant;
+
+    int mode;
+} PyArrayNeighborhoodIterObject;
+
+/*
+ * Neighborhood iterator API
+ */
+
+/* General: those work for any mode */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter);
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter);
+#if 0
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
+#endif
+
+/*
+ * Include inline implementations - functions defined there are not
+ * considered public API
+ */
+#define _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#include "_neighborhood_iterator_imp.h"
+#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+
+/* The default array type */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+
+/*
+ * All sorts of useful ways to look into a PyArrayObject. It is recommended
+ * to use PyArrayObject * objects instead of always casting from PyObject *,
+ * for improved type checking.
+ *
+ * In many cases here the macro versions of the accessors are deprecated,
+ * but can't be immediately changed to inline functions because the
+ * preexisting macros accept PyObject * and do automatic casts. Inline
+ * functions accepting PyArrayObject * provides for some compile-time
+ * checking of correctness when working with these objects in C.
+ */
+
+#define PyArray_ISONESEGMENT(m) (PyArray_NDIM(m) == 0 || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS))
+
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \
+                             (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)))
+
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
+                               NPY_ARRAY_F_CONTIGUOUS : 0))
+
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
+/*
+ * Changing access macros into functions, to allow for future hiding
+ * of the internal memory layout. This later hiding will allow the 2.x series
+ * to change the internal representation of arrays without affecting
+ * ABI compatibility.
+ */
+
+static NPY_INLINE int
+PyArray_NDIM(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->nd;
+}
+
+static NPY_INLINE void *
+PyArray_DATA(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE char *
+PyArray_BYTES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_DIMS(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_STRIDES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->strides;
+}
+
+static NPY_INLINE npy_intp
+PyArray_DIM(const PyArrayObject *arr, int idim)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions[idim];
+}
+
+static NPY_INLINE npy_intp
+PyArray_STRIDE(const PyArrayObject *arr, int istride)
+{
+    return ((PyArrayObject_fields *)arr)->strides[istride];
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject *
+PyArray_BASE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->base;
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr *
+PyArray_DESCR(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE int
+PyArray_FLAGS(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->flags;
+}
+
+static NPY_INLINE npy_intp
+PyArray_ITEMSIZE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->elsize;
+}
+
+static NPY_INLINE int
+PyArray_TYPE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->type_num;
+}
+
+static NPY_INLINE int
+PyArray_CHKFLAGS(const PyArrayObject *arr, int flags)
+{
+    return (PyArray_FLAGS(arr) & flags) == flags;
+}
+
+static NPY_INLINE PyObject *
+PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->getitem(
+                                        (void *)itemptr, (PyArrayObject *)arr);
+}
+
+static NPY_INLINE int
+PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->setitem(
+                                                        v, itemptr, arr);
+}
+
+#else
+
+/* These macros are deprecated as of NumPy 1.7. */
+#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd)
+#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags)
+#define PyArray_CHKFLAGS(m, FLAGS) \
+        ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS))
+#define PyArray_ITEMSIZE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->type_num)
+#define PyArray_GETITEM(obj,itemptr) \
+        PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+
+#define PyArray_SETITEM(obj,itemptr,v) \
+        PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \
+                                     (char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+#endif
+
+static NPY_INLINE PyArray_Descr *
+PyArray_DTYPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_SHAPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+/*
+ * Enables the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags |= flags;
+}
+
+/*
+ * Clears the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags &= ~flags;
+}
+
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) ||   \
+                                 ((type) == NPY_USHORT) ||     \
+                                 ((type) == NPY_UINT) ||       \
+                                 ((type) == NPY_ULONG) ||      \
+                                 ((type) == NPY_ULONGLONG))
+
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) ||      \
+                               ((type) == NPY_SHORT) ||        \
+                               ((type) == NPY_INT) ||          \
+                               ((type) == NPY_LONG) ||         \
+                               ((type) == NPY_LONGLONG))
+
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) &&     \
+                                ((type) <= NPY_ULONGLONG))
+
+#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \
+                              ((type) <= NPY_LONGDOUBLE)) || \
+                              ((type) == NPY_HALF))
+
+#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \
+                                  ((type) == NPY_HALF))
+
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) ||    \
+                                  ((type) == NPY_UNICODE))
+
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) &&   \
+                                ((type) <= NPY_CLONGDOUBLE))
+
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) ||      \
+                                  ((type) == NPY_DOUBLE) ||    \
+                                  ((type) == NPY_CDOUBLE) ||   \
+                                  ((type) == NPY_BOOL) ||      \
+                                  ((type) == NPY_OBJECT ))
+
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) &&  \
+                                    ((type) <=NPY_VOID))
+
+#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) &&  \
+                                    ((type) <=NPY_TIMEDELTA))
+
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+                                   ((type) < NPY_USERDEF+     \
+                                    NPY_NUMUSERTYPES))
+
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) ||  \
+                                    PyTypeNum_ISUSERDEF(type))
+
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+
+
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(_PyADt(obj))
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL)
+
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+
+    /*
+     * FIXME: This should check for a flag on the data-type that
+     * states whether or not it is variable length.  Because the
+     * ISFLEXIBLE check is hard-coded to the built-in data-types.
+     */
+#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+
+#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj))
+
+
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#else
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#endif
+
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) &&       \
+                                    PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED)
+
+
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+
+/************************************************************
+ * A struct used by PyArray_CreateSortedStridePerm, new in 1.7.
+ ************************************************************/
+
+typedef struct {
+    npy_intp perm, stride;
+} npy_stride_sort_item;
+
+/************************************************************
+ * This is the form of the struct that's returned pointed by the
+ * PyCObject attribute of an array __array_struct__. See
+ * http://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full
+ * documentation.
+ ************************************************************/
+typedef struct {
+    int two;              /*
+                           * contains the integer 2 as a sanity
+                           * check
+                           */
+
+    int nd;               /* number of dimensions */
+
+    char typekind;        /*
+                           * kind in array --- character code of
+                           * typestr
+                           */
+
+    int itemsize;         /* size of each element */
+
+    int flags;            /*
+                           * how should be data interpreted. Valid
+                           * flags are CONTIGUOUS (1), F_CONTIGUOUS (2),
+                           * ALIGNED (0x100), NOTSWAPPED (0x200), and
+                           * WRITEABLE (0x400).  ARR_HAS_DESCR (0x800)
+                           * states that arrdescr field is present in
+                           * structure
+                           */
+
+    npy_intp *shape;       /*
+                            * A length-nd array of shape
+                            * information
+                            */
+
+    npy_intp *strides;    /* A length-nd array of stride information */
+
+    void *data;           /* A pointer to the first element of the array */
+
+    PyObject *descr;      /*
+                           * A list of fields or NULL (ignored if flags
+                           * does not have ARR_HAS_DESCR flag set)
+                           */
+} PyArrayInterface;
+
+/*
+ * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions.
+ * See the documentation for PyDataMem_SetEventHook.
+ */
+typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
+                                       void *user_data);
+
+/*
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+ */
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
+#endif
+#define NPY_DEPRECATED_INCLUDES
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+#include "npy_1_7_deprecated_api.h"
+#endif
+/*
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ *
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ *
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ *     (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+ */
+#undef NPY_DEPRECATED_INCLUDES
+
+#endif /* NPY_ARRAYTYPES_H */
diff --git a/tools/msys/mingw32/include/python2.7/numpy/noprefix.h b/tools/msys/mingw32/include/python2.7/numpy/noprefix.h
new file mode 100644
index 0000000000..8306170876
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/noprefix.h
@@ -0,0 +1,209 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+
+/*
+ * You can directly include noprefix.h as a backward
+ * compatibility measure
+ */
+#ifndef NPY_NO_PREFIX
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+#endif
+
+#define SIGSETJMP   NPY_SIGSETJMP
+#define SIGLONGJMP  NPY_SIGLONGJMP
+#define SIGJMP_BUF  NPY_SIGJMP_BUF
+
+#define MAX_DIMS NPY_MAXDIMS
+
+#define longlong    npy_longlong
+#define ulonglong   npy_ulonglong
+#define Bool        npy_bool
+#define longdouble  npy_longdouble
+#define byte        npy_byte
+
+#ifndef _BSD_SOURCE
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#endif
+
+#define ubyte       npy_ubyte
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#define cfloat      npy_cfloat
+#define cdouble     npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8        npy_int8
+#define UInt8       npy_uint8
+#define Int16       npy_int16
+#define UInt16      npy_uint16
+#define Int32       npy_int32
+#define UInt32      npy_uint32
+#define Int64       npy_int64
+#define UInt64      npy_uint64
+#define Int128      npy_int128
+#define UInt128     npy_uint128
+#define Int256      npy_int256
+#define UInt256     npy_uint256
+#define Float16     npy_float16
+#define Complex32   npy_complex32
+#define Float32     npy_float32
+#define Complex64   npy_complex64
+#define Float64     npy_float64
+#define Complex128  npy_complex128
+#define Float80     npy_float80
+#define Complex160  npy_complex160
+#define Float96     npy_float96
+#define Complex192  npy_complex192
+#define Float128    npy_float128
+#define Complex256  npy_complex256
+#define intp        npy_intp
+#define uintp       npy_uintp
+#define datetime    npy_datetime
+#define timedelta   npy_timedelta
+
+#define SIZEOF_LONGLONG         NPY_SIZEOF_LONGLONG
+#define SIZEOF_INTP             NPY_SIZEOF_INTP
+#define SIZEOF_UINTP            NPY_SIZEOF_UINTP
+#define SIZEOF_HALF             NPY_SIZEOF_HALF
+#define SIZEOF_LONGDOUBLE       NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_DATETIME         NPY_SIZEOF_DATETIME
+#define SIZEOF_TIMEDELTA        NPY_SIZEOF_TIMEDELTA
+
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX
+
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT   NPY_MAX_INT
+#define MIN_INT   NPY_MIN_INT
+#define MAX_UINT  NPY_MAX_UINT
+#define MAX_LONG  NPY_MAX_LONG
+#define MIN_LONG  NPY_MIN_LONG
+#define MAX_ULONG  NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+#define MIN_DATETIME NPY_MIN_DATETIME
+#define MAX_DATETIME NPY_MAX_DATETIME
+#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA
+#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA
+
+#define BITSOF_BOOL       NPY_BITSOF_BOOL
+#define BITSOF_CHAR       NPY_BITSOF_CHAR
+#define BITSOF_SHORT      NPY_BITSOF_SHORT
+#define BITSOF_INT        NPY_BITSOF_INT
+#define BITSOF_LONG       NPY_BITSOF_LONG
+#define BITSOF_LONGLONG   NPY_BITSOF_LONGLONG
+#define BITSOF_HALF       NPY_BITSOF_HALF
+#define BITSOF_FLOAT      NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE     NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+#define BITSOF_DATETIME   NPY_BITSOF_DATETIME
+#define BITSOF_TIMEDELTA   NPY_BITSOF_TIMEDELTA
+
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS     NPY_BEGIN_THREADS
+#define END_THREADS       NPY_END_THREADS
+#define ALLOW_C_API_DEF   NPY_ALLOW_C_API_DEF
+#define ALLOW_C_API       NPY_ALLOW_C_API
+#define DISABLE_C_API     NPY_DISABLE_C_API
+
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#endif
+
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#endif
+
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+
+#define CONTIGUOUS         NPY_CONTIGUOUS
+#define C_CONTIGUOUS       NPY_C_CONTIGUOUS
+#define FORTRAN            NPY_FORTRAN
+#define F_CONTIGUOUS       NPY_F_CONTIGUOUS
+#define OWNDATA            NPY_OWNDATA
+#define FORCECAST          NPY_FORCECAST
+#define ENSURECOPY         NPY_ENSURECOPY
+#define ENSUREARRAY        NPY_ENSUREARRAY
+#define ELEMENTSTRIDES     NPY_ELEMENTSTRIDES
+#define ALIGNED            NPY_ALIGNED
+#define NOTSWAPPED         NPY_NOTSWAPPED
+#define WRITEABLE          NPY_WRITEABLE
+#define UPDATEIFCOPY       NPY_UPDATEIFCOPY
+#define ARR_HAS_DESCR      NPY_ARR_HAS_DESCR
+#define BEHAVED            NPY_BEHAVED
+#define BEHAVED_NS         NPY_BEHAVED_NS
+#define CARRAY             NPY_CARRAY
+#define CARRAY_RO          NPY_CARRAY_RO
+#define FARRAY             NPY_FARRAY
+#define FARRAY_RO          NPY_FARRAY_RO
+#define DEFAULT            NPY_DEFAULT
+#define IN_ARRAY           NPY_IN_ARRAY
+#define OUT_ARRAY          NPY_OUT_ARRAY
+#define INOUT_ARRAY        NPY_INOUT_ARRAY
+#define IN_FARRAY          NPY_IN_FARRAY
+#define OUT_FARRAY         NPY_OUT_FARRAY
+#define INOUT_FARRAY       NPY_INOUT_FARRAY
+#define UPDATE_ALL         NPY_UPDATE_ALL
+
+#define OWN_DATA          NPY_OWNDATA
+#define BEHAVED_FLAGS     NPY_BEHAVED
+#define BEHAVED_FLAGS_NS  NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO   NPY_CARRAY_RO
+#define CARRAY_FLAGS      NPY_CARRAY
+#define FARRAY_FLAGS      NPY_FARRAY
+#define FARRAY_FLAGS_RO   NPY_FARRAY_RO
+#define DEFAULT_FLAGS     NPY_DEFAULT
+#define UPDATE_ALL_FLAGS  NPY_UPDATE_ALL_FLAGS
+
+#ifndef MIN
+#define MIN PyArray_MIN
+#endif
+#ifndef MAX
+#define MAX PyArray_MAX
+#endif
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_1_7_deprecated_api.h b/tools/msys/mingw32/include/python2.7/numpy/npy_1_7_deprecated_api.h
new file mode 100644
index 0000000000..4c318bc478
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_1_7_deprecated_api.h
@@ -0,0 +1,130 @@
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+#endif
+
+#if defined(_WIN32)
+#define _WARN___STR2__(x) #x
+#define _WARN___STR1__(x) _WARN___STR2__(x)
+#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: "
+#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
+                         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+#elif defined(__GNUC__)
+#warning "Using deprecated NumPy API, disable it by " \
+         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+#endif
+/* TODO: How to do this warning message for other compilers? */
+
+/*
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
+ *
+ * This is an attempt to remove bad API, the proliferation of macros,
+ * and namespace pollution currently produced by the NumPy headers.
+ */
+
+/* These array flags are deprecated as of NumPy 1.7 */
+#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
+
+/*
+ * The consistent NPY_ARRAY_* names which don't pollute the NPY_*
+ * namespace were added in NumPy 1.7.
+ *
+ * These versions of the carray flags are deprecated, but
+ * probably should only be removed after two releases instead of one.
+ */
+#define NPY_C_CONTIGUOUS   NPY_ARRAY_C_CONTIGUOUS
+#define NPY_F_CONTIGUOUS   NPY_ARRAY_F_CONTIGUOUS
+#define NPY_OWNDATA        NPY_ARRAY_OWNDATA
+#define NPY_FORCECAST      NPY_ARRAY_FORCECAST
+#define NPY_ENSURECOPY     NPY_ARRAY_ENSURECOPY
+#define NPY_ENSUREARRAY    NPY_ARRAY_ENSUREARRAY
+#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES
+#define NPY_ALIGNED        NPY_ARRAY_ALIGNED
+#define NPY_NOTSWAPPED     NPY_ARRAY_NOTSWAPPED
+#define NPY_WRITEABLE      NPY_ARRAY_WRITEABLE
+#define NPY_UPDATEIFCOPY   NPY_ARRAY_UPDATEIFCOPY
+#define NPY_BEHAVED        NPY_ARRAY_BEHAVED
+#define NPY_BEHAVED_NS     NPY_ARRAY_BEHAVED_NS
+#define NPY_CARRAY         NPY_ARRAY_CARRAY
+#define NPY_CARRAY_RO      NPY_ARRAY_CARRAY_RO
+#define NPY_FARRAY         NPY_ARRAY_FARRAY
+#define NPY_FARRAY_RO      NPY_ARRAY_FARRAY_RO
+#define NPY_DEFAULT        NPY_ARRAY_DEFAULT
+#define NPY_IN_ARRAY       NPY_ARRAY_IN_ARRAY
+#define NPY_OUT_ARRAY      NPY_ARRAY_OUT_ARRAY
+#define NPY_INOUT_ARRAY    NPY_ARRAY_INOUT_ARRAY
+#define NPY_IN_FARRAY      NPY_ARRAY_IN_FARRAY
+#define NPY_OUT_FARRAY     NPY_ARRAY_OUT_FARRAY
+#define NPY_INOUT_FARRAY   NPY_ARRAY_INOUT_FARRAY
+#define NPY_UPDATE_ALL     NPY_ARRAY_UPDATE_ALL
+
+/* This way of accessing the default type is deprecated as of NumPy 1.7 */
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+
+/* These DATETIME bits aren't used internally */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer(                   \
+                PyDict_GetItemString(                                         \
+                    descr->metadata, NPY_METADATA_DTSTR), NULL))))
+#else
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(                    \
+                PyDict_GetItemString(descr->metadata, NPY_METADATA_DTSTR)))))
+#endif
+
+/*
+ * Deprecated as of NumPy 1.7, this kind of shortcut doesn't
+ * belong in the public API.
+ */
+#define NPY_AO PyArrayObject
+
+/*
+ * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't
+ * belong in the public API.
+ */
+#define fortran fortran_
+
+/*
+ * Deprecated as of NumPy 1.7, as it is a namespace-polluting
+ * macro.
+ */
+#define FORTRAN_IF PyArray_FORTRAN_IF
+
+/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */
+#define NPY_METADATA_DTSTR "__timeunit__"
+
+/*
+ * Deprecated as of NumPy 1.7.
+ * The reasoning:
+ *  - These are for datetime, but there's no datetime "namespace".
+ *  - They just turn NPY_STR_<x> into "<x>", which is just
+ *    making something simple be indirected.
+ */
+#define NPY_STR_Y "Y"
+#define NPY_STR_M "M"
+#define NPY_STR_W "W"
+#define NPY_STR_D "D"
+#define NPY_STR_h "h"
+#define NPY_STR_m "m"
+#define NPY_STR_s "s"
+#define NPY_STR_ms "ms"
+#define NPY_STR_us "us"
+#define NPY_STR_ns "ns"
+#define NPY_STR_ps "ps"
+#define NPY_STR_fs "fs"
+#define NPY_STR_as "as"
+
+/*
+ * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be
+ * removed in the next major release.
+ */
+#include "old_defines.h"
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_3kcompat.h b/tools/msys/mingw32/include/python2.7/numpy/npy_3kcompat.h
new file mode 100644
index 0000000000..db60a312c3
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_3kcompat.h
@@ -0,0 +1,496 @@
+/*
+ * This is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ *
+ * If you want to use this for your own projects, it's recommended to make a
+ * copy of it. Although the stuff below is unlikely to change, we don't provide
+ * strong backwards compatibility guarantees at the moment.
+ */
+
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+
+#include <Python.h>
+#include <stdio.h>
+
+#if PY_VERSION_HEX >= 0x03000000
+#ifndef NPY_PY3K
+#define NPY_PY3K 1
+#endif
+#endif
+
+#include "numpy/npy_common.h"
+#include "numpy/ndarrayobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * PyInt -> PyLong
+ */
+
+#if defined(NPY_PY3K)
+/* Return True only if the long fits in a C long */
+static NPY_INLINE int PyInt_Check(PyObject *op) {
+    int overflow = 0;
+    if (!PyLong_Check(op)) {
+        return 0;
+    }
+    PyLong_AsLongAndOverflow(op, &overflow);
+    return (overflow == 0);
+}
+
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+
+/* NOTE:
+ *
+ * Since the PyLong type is very different from the fixed-range PyInt,
+ * we don't define PyInt_Type -> PyLong_Type.
+ */
+#endif /* NPY_PY3K */
+
+/*
+ * PyString -> PyBytes
+ */
+
+#if defined(NPY_PY3K)
+
+#define PyString_Type PyBytes_Type
+#define PyString_Check PyBytes_Check
+#define PyStringObject PyBytesObject
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define PyString_FromFormat PyBytes_FromFormat
+#define PyString_Concat PyBytes_Concat
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_Size PyBytes_Size
+
+#define PyUString_Type PyUnicode_Type
+#define PyUString_Check PyUnicode_Check
+#define PyUStringObject PyUnicodeObject
+#define PyUString_FromString PyUnicode_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyUString_FromFormat PyUnicode_FromFormat
+#define PyUString_Concat PyUnicode_Concat2
+#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_Size PyUnicode_Size
+#define PyUString_InternFromString PyUnicode_InternFromString
+#define PyUString_Format PyUnicode_Format
+
+#else
+
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytesObject PyStringObject
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_Size PyString_Size
+
+#define PyUString_Type PyString_Type
+#define PyUString_Check PyString_Check
+#define PyUStringObject PyStringObject
+#define PyUString_FromString PyString_FromString
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#define PyUString_FromFormat PyString_FromFormat
+#define PyUString_Concat PyString_Concat
+#define PyUString_ConcatAndDel PyString_ConcatAndDel
+#define PyUString_GET_SIZE PyString_GET_SIZE
+#define PyUString_Size PyString_Size
+#define PyUString_InternFromString PyString_InternFromString
+#define PyUString_Format PyString_Format
+
+#endif /* NPY_PY3K */
+
+
+static NPY_INLINE void
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    Py_DECREF(right);
+    *left = newobj;
+}
+
+static NPY_INLINE void
+PyUnicode_Concat2(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    *left = newobj;
+}
+
+/*
+ * PyFile_* compatibility
+ */
+#if defined(NPY_PY3K)
+/*
+ * Get a FILE* handle to the file represented by the Python object
+ */
+static NPY_INLINE FILE*
+npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
+{
+    int fd, fd2, unbuf;
+    PyObject *ret, *os, *io, *io_raw;
+    npy_off_t pos;
+    FILE *handle;
+
+    /* Flush first to ensure things end up in the file in the correct order */
+    ret = PyObject_CallMethod(file, "flush", "");
+    if (ret == NULL) {
+        return NULL;
+    }
+    Py_DECREF(ret);
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return NULL;
+    }
+
+    /*
+     * The handle needs to be dup'd because we have to call fclose
+     * at the end
+     */
+    os = PyImport_ImportModule("os");
+    if (os == NULL) {
+        return NULL;
+    }
+    ret = PyObject_CallMethod(os, "dup", "i", fd);
+    Py_DECREF(os);
+    if (ret == NULL) {
+        return NULL;
+    }
+    fd2 = PyNumber_AsSsize_t(ret, NULL);
+    Py_DECREF(ret);
+
+    /* Convert to FILE* handle */
+#ifdef _WIN32
+    handle = _fdopen(fd2, mode);
+#else
+    handle = fdopen(fd2, mode);
+#endif
+    if (handle == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "Getting a FILE* from a Python file object failed");
+    }
+
+    /* Record the original raw file handle position */
+    *orig_pos = npy_ftell(handle);
+    if (*orig_pos == -1) {
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return handle;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+            fclose(handle);
+            return NULL;
+        }
+    }
+
+    /* Seek raw handle to the Python-side position */
+    ret = PyObject_CallMethod(file, "tell", "");
+    if (ret == NULL) {
+        fclose(handle);
+        return NULL;
+    }
+    pos = PyLong_AsLongLong(ret);
+    Py_DECREF(ret);
+    if (PyErr_Occurred()) {
+        fclose(handle);
+        return NULL;
+    }
+    if (npy_fseek(handle, pos, SEEK_SET) == -1) {
+        PyErr_SetString(PyExc_IOError, "seeking file failed");
+        fclose(handle);
+        return NULL;
+    }
+    return handle;
+}
+
+/*
+ * Close the dup-ed file handle, and seek the Python one to the current position
+ */
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
+{
+    int fd, unbuf;
+    PyObject *ret, *io, *io_raw;
+    npy_off_t position;
+
+    position = npy_ftell(handle);
+
+    /* Close the FILE* handle */
+    fclose(handle);
+
+    /*
+     * Restore original file handle position, in order to not confuse
+     * Python-side data structures
+     */
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return -1;
+    }
+
+    if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
+
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            return -1;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            return -1;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return 0;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "seeking file failed");
+            return -1;
+        }
+    }
+
+    if (position == -1) {
+        PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+        return -1;
+    }
+
+    /* Seek Python-side handle to the FILE* handle position */
+    ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+static NPY_INLINE int
+npy_PyFile_Check(PyObject *file)
+{
+    int fd;
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        PyErr_Clear();
+        return 0;
+    }
+    return 1;
+}
+
+#else
+
+static NPY_INLINE FILE *
+npy_PyFile_Dup2(PyObject *file,
+                const char *NPY_UNUSED(mode), npy_off_t *NPY_UNUSED(orig_pos))
+{
+    FILE * fp = PyFile_AsFile(file);
+    if (fp == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "first argument must be an open file");
+        return NULL;
+    }
+    return fp;
+}
+
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *NPY_UNUSED(file), FILE* NPY_UNUSED(handle),
+                     npy_off_t NPY_UNUSED(orig_pos))
+{
+    return 0;
+}
+
+#define npy_PyFile_Check PyFile_Check
+
+#endif
+
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+{
+    PyObject *open;
+    open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+    if (open == NULL) {
+        return NULL;
+    }
+    return PyObject_CallFunction(open, "Os", filename, mode);
+}
+
+static NPY_INLINE int
+npy_PyFile_CloseFile(PyObject *file)
+{
+    PyObject *ret;
+
+    ret = PyObject_CallMethod(file, "close", NULL);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+/*
+ * PyObject_Cmp
+ */
+#if defined(NPY_PY3K)
+static NPY_INLINE int
+PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp)
+{
+    int v;
+    v = PyObject_RichCompareBool(i1, i2, Py_LT);
+    if (v == 1) {
+        *cmp = -1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_GT);
+    if (v == 1) {
+        *cmp = 1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_EQ);
+    if (v == 1) {
+        *cmp = 0;
+        return 1;
+    }
+    else {
+        *cmp = 0;
+        return -1;
+    }
+}
+#endif
+
+/*
+ * PyCObject functions adapted to PyCapsules.
+ *
+ * The main job here is to get rid of the improved error handling
+ * of PyCapsules. It's a shame...
+ */
+#if PY_VERSION_HEX >= 0x03000000
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *))
+{
+    PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor);
+    if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) {
+        PyErr_Clear();
+        Py_DECREF(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCapsule_GetContext(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context,
+        void (*dtor)(void *, void *))
+{
+    return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor);
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCObject_GetDesc(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NPY_3KCOMPAT_H_ */
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_common.h b/tools/msys/mingw32/include/python2.7/numpy/npy_common.h
new file mode 100644
index 0000000000..baf5549d97
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_common.h
@@ -0,0 +1,1069 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+
+/* numpconfig.h is auto-generated */
+#include "numpyconfig.h"
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+
+/* need Python.h for npy_intp, npy_uintp */
+#include <Python.h>
+
+/*
+ * gcc does not unroll even with -O3
+ * use with care, unrolling on modern cpus rarely speeds things up
+ */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS
+#define NPY_GCC_UNROLL_LOOPS \
+    __attribute__((optimize("unroll-loops")))
+#else
+#define NPY_GCC_UNROLL_LOOPS
+#endif
+
+/* highest gcc optimization level, enabled autovectorizer */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3
+#define NPY_GCC_OPT_3 __attribute__((optimize("O3")))
+#else
+#define NPY_GCC_OPT_3
+#endif
+
+/*
+ * mark an argument (starting from 1) that must not be NULL and is not checked
+ * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check
+ */
+#ifdef HAVE_ATTRIBUTE_NONNULL
+#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n)))
+#else
+#define NPY_GCC_NONNULL(n)
+#endif
+
+#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS
+#define NPY_HAVE_SSE_INTRINSICS
+#endif
+
+#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD
+#define NPY_HAVE_SSE2_INTRINSICS
+#endif
+
+/*
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ *
+ * if (NPY_UNLIKELY(failure == 0))
+ *    return NULL;
+ *
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+ */
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#endif
+
+#ifdef HAVE___BUILTIN_PREFETCH
+/* unlike _mm_prefetch also works on non-x86 */
+#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc))
+#else
+#ifdef HAVE__MM_PREFETCH
+/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */
+#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \
+                                             (loc == 1 ? _MM_HINT_T2 : \
+                                              (loc == 2 ? _MM_HINT_T1 : \
+                                               (loc == 3 ? _MM_HINT_T0 : -1))))
+#else
+#define NPY_PREFETCH(x, rw,loc)
+#endif
+#endif
+
+#if defined(_MSC_VER)
+        #define NPY_INLINE __inline
+#elif defined(__GNUC__)
+	#if defined(__STRICT_ANSI__)
+		#define NPY_INLINE __inline__
+	#else
+		#define NPY_INLINE inline
+	#endif
+#else
+        #define NPY_INLINE
+#endif
+
+#ifdef HAVE___THREAD
+    #define NPY_TLS __thread
+#else
+    #ifdef HAVE___DECLSPEC_THREAD_
+        #define NPY_TLS __declspec(thread)
+    #else
+        #define NPY_TLS
+    #endif
+#endif
+
+#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE
+  #define NPY_RETURNS_BORROWED_REF \
+    __attribute__((cpychecker_returns_borrowed_ref))
+#else
+  #define NPY_RETURNS_BORROWED_REF
+#endif
+
+#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE
+  #define NPY_STEALS_REF_TO_ARG(n) \
+   __attribute__((cpychecker_steals_reference_to_arg(n)))
+#else
+ #define NPY_STEALS_REF_TO_ARG(n)
+#endif
+
+/* 64 bit file position support, also on win-amd64. Ticket #1660 */
+#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \
+    defined(__MINGW32__) || defined(__MINGW64__)
+    #include <io.h>
+
+/* mingw based on 3.4.5 has lseek but not ftell/fseek */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+extern int __cdecl _fseeki64(FILE *, long long, int);
+extern long long __cdecl _ftelli64(FILE *);
+#endif
+
+    #define npy_fseek _fseeki64
+    #define npy_ftell _ftelli64
+    #define npy_lseek _lseeki64
+    #define npy_off_t npy_int64
+
+    #if NPY_SIZEOF_INT == 8
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_LONG == 8
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_LONGLONG == 8
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#else
+#ifdef HAVE_FSEEKO
+    #define npy_fseek fseeko
+#else
+    #define npy_fseek fseek
+#endif
+#ifdef HAVE_FTELLO
+    #define npy_ftell ftello
+#else
+    #define npy_ftell ftell
+#endif
+    #include <sys/types.h>
+    #define npy_lseek lseek
+    #define npy_off_t off_t
+
+    #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT
+        #define NPY_OFF_T_PYFMT "h"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#endif
+
+/* enums for detected endianness */
+enum {
+        NPY_CPU_UNKNOWN_ENDIAN,
+        NPY_CPU_LITTLE,
+        NPY_CPU_BIG
+};
+
+/*
+ * This is to typedef npy_intp to the appropriate pointer size for this
+ * platform.  Py_intptr_t, Py_uintptr_t are defined in pyport.h.
+ */
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+
+/*
+ * Define sizes that were not defined in numpyconfig.h.
+ */
+#define NPY_SIZEOF_CHAR 1
+#define NPY_SIZEOF_BYTE 1
+#define NPY_SIZEOF_DATETIME 8
+#define NPY_SIZEOF_TIMEDELTA 8
+#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_HALF 2
+#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT
+#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE
+#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE
+
+#ifdef constchar
+#undef constchar
+#endif
+
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+
+/* NPY_INTP_FMT Note:
+ *      Unlike the other NPY_*_FMT macros which are used with
+ *      PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and
+ *      PyString_Format. These functions use different formatting
+ *      codes which are portably specified according to the Python
+ *      documentation. See ticket #1795.
+ *
+ *      On Windows x64, the LONGLONG formatter should be used, but
+ *      in Python 2.6 the %lld formatter is not supported. In this
+ *      case we work around the problem by using the %zd formatter.
+ */
+#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT
+        #define NPY_INTP NPY_INT
+        #define NPY_UINTP NPY_UINT
+        #define PyIntpArrType_Type PyIntArrType_Type
+        #define PyUIntpArrType_Type PyUIntArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_INT
+        #define NPY_MIN_INTP NPY_MIN_INT
+        #define NPY_MAX_UINTP NPY_MAX_UINT
+        #define NPY_INTP_FMT "d"
+#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG
+        #define NPY_INTP NPY_LONG
+        #define NPY_UINTP NPY_ULONG
+        #define PyIntpArrType_Type PyLongArrType_Type
+        #define PyUIntpArrType_Type PyULongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONG
+        #define NPY_MIN_INTP NPY_MIN_LONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONG
+        #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG)
+        #define NPY_INTP NPY_LONGLONG
+        #define NPY_UINTP NPY_ULONGLONG
+        #define PyIntpArrType_Type PyLongLongArrType_Type
+        #define PyUIntpArrType_Type PyULongLongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONGLONG
+        #define NPY_MIN_INTP NPY_MIN_LONGLONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+    #if (PY_VERSION_HEX >= 0x02070000)
+        #define NPY_INTP_FMT "lld"
+    #else
+        #define NPY_INTP_FMT "zd"
+    #endif
+#endif
+
+/*
+ * We can only use C99 formats for npy_int_p if it is the same as
+ * intp_t, hence the condition on HAVE_UNITPTR_T
+ */
+#if (NPY_USE_C99_FORMATS) == 1 \
+        && (defined HAVE_UINTPTR_T) \
+        && (defined HAVE_INTTYPES_H)
+        #include <inttypes.h>
+        #undef NPY_INTP_FMT
+        #define NPY_INTP_FMT PRIdPTR
+#endif
+
+
+/*
+ * Some platforms don't define bool, long long, or long double.
+ * Handle that here.
+ */
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_HALF_FMT "g"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_FMT         "I64d"
+#    define NPY_ULONGLONG_FMT        "I64u"
+#  else
+#    define NPY_LONGLONG_FMT         "lld"
+#    define NPY_ULONGLONG_FMT        "llu"
+#  endif
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_SUFFIX(x)   (x##i64)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##Ui64)
+#  else
+#    define NPY_LONGLONG_SUFFIX(x)   (x##LL)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##ULL)
+#  endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+#  define NPY_LONGLONG_SUFFIX(x)  (x##L)
+#  define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+        typedef double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "g"
+#else
+        typedef long double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+/* These are for completeness */
+typedef char npy_char;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+typedef float npy_float;
+typedef double npy_double;
+
+/*
+ * Hash value compatibility.
+ * As of Python 3.2 hash values are of type Py_hash_t.
+ * Previous versions use C long.
+ */
+#if PY_VERSION_HEX < 0x03020000
+typedef long npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_LONG
+#else
+typedef Py_hash_t npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP
+#endif
+
+/*
+ * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being
+ * able to do .real/.imag. Will have to convert code first.
+ */
+#if 0
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE)
+typedef complex npy_cdouble;
+#else
+typedef struct { double real, imag; } npy_cdouble;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT)
+typedef complex float npy_cfloat;
+#else
+typedef struct { float real, imag; } npy_cfloat;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE)
+typedef complex long double npy_clongdouble;
+#else
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+#endif
+#endif
+#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE
+#error npy_cdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { double real, imag; } npy_cdouble;
+
+#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT
+#error npy_cfloat definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { float real, imag; } npy_cfloat;
+
+#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE
+#error npy_clongdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { npy_longdouble real, imag; } npy_clongdouble;
+
+/*
+ * numarray-style bit-width typedefs
+ */
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define NPY_MIN_DATETIME NPY_MIN_INT64
+#define NPY_MAX_DATETIME NPY_MAX_INT64
+#define NPY_MIN_TIMEDELTA NPY_MIN_INT64
+#define NPY_MAX_TIMEDELTA NPY_MAX_INT64
+
+        /* Need to find the number of bits for each type and
+           make definitions accordingly.
+
+           C states that sizeof(char) == 1 by definition
+
+           So, just using the sizeof keyword won't help.
+
+           It also looks like Python itself uses sizeof(char) quite a
+           bit, which by definition should be 1 all the time.
+
+           Idea: Make Use of CHAR_BIT which should tell us how many
+           BITS per CHARACTER
+        */
+
+        /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT   INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif
+#define NPY_MIN_INT   INT_MIN
+#define NPY_MAX_UINT  UINT_MAX
+#define NPY_MAX_LONG  LONG_MAX
+#define NPY_MIN_LONG  LONG_MIN
+#define NPY_MAX_ULONG  ULONG_MAX
+
+#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT)
+#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT)
+#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT)
+#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT)
+#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT)
+#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT)
+#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT)
+#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT)
+#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT)
+
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+        typedef long npy_int8;
+        typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+        typedef long npy_int16;
+        typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+        typedef long npy_int32;
+        typedef unsigned long npy_uint32;
+        typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+        typedef long npy_int64;
+        typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#define MyPyLong_FromInt64 PyLong_FromLong
+#define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+        typedef long npy_int128;
+        typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#endif
+
+#if NPY_BITSOF_LONGLONG == 8
+#  ifndef NPY_INT8
+#    define NPY_INT8 NPY_LONGLONG
+#    define NPY_UINT8 NPY_ULONGLONG
+        typedef npy_longlong npy_int8;
+        typedef npy_ulonglong npy_uint8;
+#    define PyInt8ScalarObject PyLongLongScalarObject
+#    define PyInt8ArrType_Type PyLongLongArrType_Type
+#    define PyUInt8ScalarObject PyULongLongScalarObject
+#    define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT8
+#  define NPY_MIN_LONGLONG NPY_MIN_INT8
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+#  ifndef NPY_INT16
+#    define NPY_INT16 NPY_LONGLONG
+#    define NPY_UINT16 NPY_ULONGLONG
+        typedef npy_longlong npy_int16;
+        typedef npy_ulonglong npy_uint16;
+#    define PyInt16ScalarObject PyLongLongScalarObject
+#    define PyInt16ArrType_Type PyLongLongArrType_Type
+#    define PyUInt16ScalarObject PyULongLongScalarObject
+#    define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT16
+#  define NPY_MIN_LONGLONG NPY_MIN_INT16
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+#  ifndef NPY_INT32
+#    define NPY_INT32 NPY_LONGLONG
+#    define NPY_UINT32 NPY_ULONGLONG
+        typedef npy_longlong npy_int32;
+        typedef npy_ulonglong npy_uint32;
+        typedef npy_ulonglong npy_ucs4;
+#    define PyInt32ScalarObject PyLongLongScalarObject
+#    define PyInt32ArrType_Type PyLongLongArrType_Type
+#    define PyUInt32ScalarObject PyULongLongScalarObject
+#    define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT32
+#  define NPY_MIN_LONGLONG NPY_MIN_INT32
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+#  ifndef NPY_INT64
+#    define NPY_INT64 NPY_LONGLONG
+#    define NPY_UINT64 NPY_ULONGLONG
+        typedef npy_longlong npy_int64;
+        typedef npy_ulonglong npy_uint64;
+#    define PyInt64ScalarObject PyLongLongScalarObject
+#    define PyInt64ArrType_Type PyLongLongArrType_Type
+#    define PyUInt64ScalarObject PyULongLongScalarObject
+#    define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLongLong
+#    define MyPyLong_AsInt64 PyLong_AsLongLong
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT64
+#  define NPY_MIN_LONGLONG NPY_MIN_INT64
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+#  ifndef NPY_INT128
+#    define NPY_INT128 NPY_LONGLONG
+#    define NPY_UINT128 NPY_ULONGLONG
+        typedef npy_longlong npy_int128;
+        typedef npy_ulonglong npy_uint128;
+#    define PyInt128ScalarObject PyLongLongScalarObject
+#    define PyInt128ArrType_Type PyLongLongArrType_Type
+#    define PyUInt128ScalarObject PyULongLongScalarObject
+#    define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT128
+#  define NPY_MIN_LONGLONG NPY_MIN_INT128
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+#  define NPY_INT256 NPY_LONGLONG
+#  define NPY_UINT256 NPY_ULONGLONG
+        typedef npy_longlong npy_int256;
+        typedef npy_ulonglong npy_uint256;
+#  define PyInt256ScalarObject PyLongLongScalarObject
+#  define PyInt256ArrType_Type PyLongLongArrType_Type
+#  define PyUInt256ScalarObject PyULongLongScalarObject
+#  define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+#  define NPY_MAX_LONGLONG NPY_MAX_INT256
+#  define NPY_MIN_LONGLONG NPY_MIN_INT256
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#endif
+
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+        typedef int npy_int8;
+        typedef unsigned int npy_uint8;
+#    define PyInt8ScalarObject PyIntScalarObject
+#    define PyInt8ArrType_Type PyIntArrType_Type
+#    define PyUInt8ScalarObject PyUIntScalarObject
+#    define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+        typedef int npy_int16;
+        typedef unsigned int npy_uint16;
+#    define PyInt16ScalarObject PyIntScalarObject
+#    define PyInt16ArrType_Type PyIntArrType_Type
+#    define PyUInt16ScalarObject PyIntUScalarObject
+#    define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+        typedef int npy_int32;
+        typedef unsigned int npy_uint32;
+        typedef unsigned int npy_ucs4;
+#    define PyInt32ScalarObject PyIntScalarObject
+#    define PyInt32ArrType_Type PyIntArrType_Type
+#    define PyUInt32ScalarObject PyUIntScalarObject
+#    define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+        typedef int npy_int64;
+        typedef unsigned int npy_uint64;
+#    define PyInt64ScalarObject PyIntScalarObject
+#    define PyInt64ArrType_Type PyIntArrType_Type
+#    define PyUInt64ScalarObject PyUIntScalarObject
+#    define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+        typedef int npy_int128;
+        typedef unsigned int npy_uint128;
+#    define PyInt128ScalarObject PyIntScalarObject
+#    define PyInt128ArrType_Type PyIntArrType_Type
+#    define PyUInt128ScalarObject PyUIntScalarObject
+#    define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#endif
+#endif
+
+#if NPY_BITSOF_SHORT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+        typedef short npy_int8;
+        typedef unsigned short npy_uint8;
+#    define PyInt8ScalarObject PyShortScalarObject
+#    define PyInt8ArrType_Type PyShortArrType_Type
+#    define PyUInt8ScalarObject PyUShortScalarObject
+#    define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+        typedef short npy_int16;
+        typedef unsigned short npy_uint16;
+#    define PyInt16ScalarObject PyShortScalarObject
+#    define PyInt16ArrType_Type PyShortArrType_Type
+#    define PyUInt16ScalarObject PyUShortScalarObject
+#    define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+        typedef short npy_int32;
+        typedef unsigned short npy_uint32;
+        typedef unsigned short npy_ucs4;
+#    define PyInt32ScalarObject PyShortScalarObject
+#    define PyInt32ArrType_Type PyShortArrType_Type
+#    define PyUInt32ScalarObject PyUShortScalarObject
+#    define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+        typedef short npy_int64;
+        typedef unsigned short npy_uint64;
+#    define PyInt64ScalarObject PyShortScalarObject
+#    define PyInt64ArrType_Type PyShortArrType_Type
+#    define PyUInt64ScalarObject PyUShortScalarObject
+#    define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_SHORT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+        typedef short npy_int128;
+        typedef unsigned short npy_uint128;
+#    define PyInt128ScalarObject PyShortScalarObject
+#    define PyInt128ArrType_Type PyShortArrType_Type
+#    define PyUInt128ScalarObject PyUShortScalarObject
+#    define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_CHAR == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+        typedef signed char npy_int8;
+        typedef unsigned char npy_uint8;
+#    define PyInt8ScalarObject PyByteScalarObject
+#    define PyInt8ArrType_Type PyByteArrType_Type
+#    define PyUInt8ScalarObject PyUByteScalarObject
+#    define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+        typedef signed char npy_int16;
+        typedef unsigned char npy_uint16;
+#    define PyInt16ScalarObject PyByteScalarObject
+#    define PyInt16ArrType_Type PyByteArrType_Type
+#    define PyUInt16ScalarObject PyUByteScalarObject
+#    define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+        typedef signed char npy_int32;
+        typedef unsigned char npy_uint32;
+        typedef unsigned char npy_ucs4;
+#    define PyInt32ScalarObject PyByteScalarObject
+#    define PyInt32ArrType_Type PyByteArrType_Type
+#    define PyUInt32ScalarObject PyUByteScalarObject
+#    define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+        typedef signed char npy_int64;
+        typedef unsigned char npy_uint64;
+#    define PyInt64ScalarObject PyByteScalarObject
+#    define PyInt64ArrType_Type PyByteArrType_Type
+#    define PyUInt64ScalarObject PyUByteScalarObject
+#    define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_CHAR == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+        typedef signed char npy_int128;
+        typedef unsigned char npy_uint128;
+#    define PyInt128ScalarObject PyByteScalarObject
+#    define PyInt128ArrType_Type PyByteArrType_Type
+#    define PyUInt128ScalarObject PyUByteScalarObject
+#    define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+        typedef double npy_float32;
+        typedef npy_cdouble npy_complex64;
+#    define PyFloat32ScalarObject PyDoubleScalarObject
+#    define PyComplex64ScalarObject PyCDoubleScalarObject
+#    define PyFloat32ArrType_Type PyDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+        typedef double npy_float64;
+        typedef npy_cdouble npy_complex128;
+#    define PyFloat64ScalarObject PyDoubleScalarObject
+#    define PyComplex128ScalarObject PyCDoubleScalarObject
+#    define PyFloat64ArrType_Type PyDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+        typedef double npy_float80;
+        typedef npy_cdouble npy_complex160;
+#    define PyFloat80ScalarObject PyDoubleScalarObject
+#    define PyComplex160ScalarObject PyCDoubleScalarObject
+#    define PyFloat80ArrType_Type PyDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+        typedef double npy_float96;
+        typedef npy_cdouble npy_complex192;
+#    define PyFloat96ScalarObject PyDoubleScalarObject
+#    define PyComplex192ScalarObject PyCDoubleScalarObject
+#    define PyFloat96ArrType_Type PyDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+        typedef double npy_float128;
+        typedef npy_cdouble npy_complex256;
+#    define PyFloat128ScalarObject PyDoubleScalarObject
+#    define PyComplex256ScalarObject PyCDoubleScalarObject
+#    define PyFloat128ArrType_Type PyDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_FLOAT == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+        typedef float npy_float32;
+        typedef npy_cfloat npy_complex64;
+#    define PyFloat32ScalarObject PyFloatScalarObject
+#    define PyComplex64ScalarObject PyCFloatScalarObject
+#    define PyFloat32ArrType_Type PyFloatArrType_Type
+#    define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+        typedef float npy_float64;
+        typedef npy_cfloat npy_complex128;
+#    define PyFloat64ScalarObject PyFloatScalarObject
+#    define PyComplex128ScalarObject PyCFloatScalarObject
+#    define PyFloat64ArrType_Type PyFloatArrType_Type
+#    define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+        typedef float npy_float80;
+        typedef npy_cfloat npy_complex160;
+#    define PyFloat80ScalarObject PyFloatScalarObject
+#    define PyComplex160ScalarObject PyCFloatScalarObject
+#    define PyFloat80ArrType_Type PyFloatArrType_Type
+#    define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+        typedef float npy_float96;
+        typedef npy_cfloat npy_complex192;
+#    define PyFloat96ScalarObject PyFloatScalarObject
+#    define PyComplex192ScalarObject PyCFloatScalarObject
+#    define PyFloat96ArrType_Type PyFloatArrType_Type
+#    define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+        typedef float npy_float128;
+        typedef npy_cfloat npy_complex256;
+#    define PyFloat128ScalarObject PyFloatScalarObject
+#    define PyComplex256ScalarObject PyCFloatScalarObject
+#    define PyFloat128ArrType_Type PyFloatArrType_Type
+#    define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+#endif
+#endif
+
+/* half/float16 isn't a floating-point type in C */
+#define NPY_FLOAT16 NPY_HALF
+typedef npy_uint16 npy_half;
+typedef npy_half npy_float16;
+
+#if NPY_BITSOF_LONGDOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float32;
+        typedef npy_clongdouble npy_complex64;
+#    define PyFloat32ScalarObject PyLongDoubleScalarObject
+#    define PyComplex64ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float64;
+        typedef npy_clongdouble npy_complex128;
+#    define PyFloat64ScalarObject PyLongDoubleScalarObject
+#    define PyComplex128ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float80;
+        typedef npy_clongdouble npy_complex160;
+#    define PyFloat80ScalarObject PyLongDoubleScalarObject
+#    define PyComplex160ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float96;
+        typedef npy_clongdouble npy_complex192;
+#    define PyFloat96ScalarObject PyLongDoubleScalarObject
+#    define PyComplex192ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float128;
+        typedef npy_clongdouble npy_complex256;
+#    define PyFloat128ScalarObject PyLongDoubleScalarObject
+#    define PyComplex256ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float256;
+        typedef npy_clongdouble npy_complex512;
+#    define PyFloat256ScalarObject PyLongDoubleScalarObject
+#    define PyComplex512ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+#endif
+
+/* datetime typedefs */
+typedef npy_int64 npy_timedelta;
+typedef npy_int64 npy_datetime;
+#define NPY_DATETIME_FMT NPY_INT64_FMT
+#define NPY_TIMEDELTA_FMT NPY_INT64_FMT
+
+/* End of typedefs for numarray style bit-width names */
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_cpu.h b/tools/msys/mingw32/include/python2.7/numpy/npy_cpu.h
new file mode 100644
index 0000000000..60abae4e0b
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_cpu.h
@@ -0,0 +1,92 @@
+/*
+ * This set (target) cpu specific macros:
+ *      - Possible values:
+ *              NPY_CPU_X86
+ *              NPY_CPU_AMD64
+ *              NPY_CPU_PPC
+ *              NPY_CPU_PPC64
+ *              NPY_CPU_PPC64LE
+ *              NPY_CPU_SPARC
+ *              NPY_CPU_S390
+ *              NPY_CPU_IA64
+ *              NPY_CPU_HPPA
+ *              NPY_CPU_ALPHA
+ *              NPY_CPU_ARMEL
+ *              NPY_CPU_ARMEB
+ *              NPY_CPU_SH_LE
+ *              NPY_CPU_SH_BE
+ */
+#ifndef _NPY_CPUARCH_H_
+#define _NPY_CPUARCH_H_
+
+#include "numpyconfig.h"
+#include <string.h> /* for memcpy */
+
+#if defined( __i386__ ) || defined(i386) || defined(_M_IX86)
+    /*
+     * __i386__ is defined by gcc and Intel compiler on Linux,
+     * _M_IX86 by VS compiler,
+     * i386 by Sun compilers on opensolaris at least
+     */
+    #define NPY_CPU_X86
+#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64)
+    /*
+     * both __x86_64__ and __amd64__ are defined by gcc
+     * __x86_64 defined by sun compiler on opensolaris at least
+     * _M_AMD64 defined by MS compiler
+     */
+    #define NPY_CPU_AMD64
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC)
+    /*
+     * __ppc__ is defined by gcc, I remember having seen __powerpc__ once,
+     * but can't find it ATM
+     * _ARCH_PPC is used by at least gcc on AIX
+     */
+    #define NPY_CPU_PPC
+#elif defined(__ppc64le__)
+    #define NPY_CPU_PPC64LE
+#elif defined(__ppc64__)
+    #define NPY_CPU_PPC64
+#elif defined(__sparc__) || defined(__sparc)
+    /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */
+    #define NPY_CPU_SPARC
+#elif defined(__s390__)
+    #define NPY_CPU_S390
+#elif defined(__ia64)
+    #define NPY_CPU_IA64
+#elif defined(__hppa)
+    #define NPY_CPU_HPPA
+#elif defined(__alpha__)
+    #define NPY_CPU_ALPHA
+#elif defined(__arm__) && defined(__ARMEL__)
+    #define NPY_CPU_ARMEL
+#elif defined(__arm__) && defined(__ARMEB__)
+    #define NPY_CPU_ARMEB
+#elif defined(__sh__) && defined(__LITTLE_ENDIAN__)
+    #define NPY_CPU_SH_LE
+#elif defined(__sh__) && defined(__BIG_ENDIAN__)
+    #define NPY_CPU_SH_BE
+#elif defined(__MIPSEL__)
+    #define NPY_CPU_MIPSEL
+#elif defined(__MIPSEB__)
+    #define NPY_CPU_MIPSEB
+#elif defined(__or1k__)
+    #define NPY_CPU_OR1K
+#elif defined(__aarch64__)
+    #define NPY_CPU_AARCH64
+#elif defined(__mc68000__)
+    #define NPY_CPU_M68K
+#else
+    #error Unknown CPU, please report this to numpy maintainers with \
+    information about your platform (OS, CPU and compiler)
+#endif
+
+#define NPY_COPY_PYOBJECT_PTR(dst, src) memcpy(dst, src, sizeof(PyObject *))
+
+#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
+#else
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_endian.h b/tools/msys/mingw32/include/python2.7/numpy/npy_endian.h
new file mode 100644
index 0000000000..a8ec572458
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_endian.h
@@ -0,0 +1,61 @@
+#ifndef _NPY_ENDIAN_H_
+#define _NPY_ENDIAN_H_
+
+/*
+ * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in
+ * endian.h
+ */
+
+#ifdef NPY_HAVE_ENDIAN_H
+    /* Use endian.h if available */
+    #include <endian.h>
+
+    #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    BIG_ENDIAN
+    #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    _BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    _BIG_ENDIAN
+    #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    __BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    __BIG_ENDIAN
+    #endif
+#endif
+
+#ifndef NPY_BYTE_ORDER
+    /* Set endianness info using target CPU */
+    #include "npy_cpu.h"
+
+    #define NPY_LITTLE_ENDIAN 1234
+    #define NPY_BIG_ENDIAN 4321
+
+    #if defined(NPY_CPU_X86)            \
+            || defined(NPY_CPU_AMD64)   \
+            || defined(NPY_CPU_IA64)    \
+            || defined(NPY_CPU_ALPHA)   \
+            || defined(NPY_CPU_ARMEL)   \
+            || defined(NPY_CPU_AARCH64) \
+            || defined(NPY_CPU_SH_LE)   \
+            || defined(NPY_CPU_MIPSEL)  \
+            || defined(NPY_CPU_PPC64LE)
+        #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
+    #elif defined(NPY_CPU_PPC)          \
+            || defined(NPY_CPU_SPARC)   \
+            || defined(NPY_CPU_S390)    \
+            || defined(NPY_CPU_HPPA)    \
+            || defined(NPY_CPU_PPC64)   \
+            || defined(NPY_CPU_ARMEB)   \
+            || defined(NPY_CPU_SH_BE)   \
+            || defined(NPY_CPU_MIPSEB)  \
+            || defined(NPY_CPU_OR1K)    \
+            || defined(NPY_CPU_M68K)
+        #define NPY_BYTE_ORDER NPY_BIG_ENDIAN
+    #else
+        #error Unknown CPU: can not set endianness
+    #endif
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_interrupt.h b/tools/msys/mingw32/include/python2.7/numpy/npy_interrupt.h
new file mode 100644
index 0000000000..f71fd689eb
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_interrupt.h
@@ -0,0 +1,117 @@
+
+/* Signal handling:
+
+This header file defines macros that allow your code to handle
+interrupts received during processing.  Interrupts that
+could reasonably be handled:
+
+SIGINT, SIGABRT, SIGALRM, SIGSEGV
+
+****Warning***************
+
+Do not allow code that creates temporary memory or increases reference
+counts of Python objects to be interrupted unless you handle it
+differently.
+
+**************************
+
+The mechanism for handling interrupts is conceptually simple:
+
+  - replace the signal handler with our own home-grown version
+     and store the old one.
+  - run the code to be interrupted -- if an interrupt occurs
+     the handler should basically just cause a return to the
+     calling function for finish work.
+  - restore the old signal handler
+
+Of course, every code that allows interrupts must account for
+returning via the interrupt and handle clean-up correctly.  But,
+even still, the simple paradigm is complicated by at least three
+factors.
+
+ 1) platform portability (i.e. Microsoft says not to use longjmp
+     to return from signal handling.  They have a __try  and __except
+     extension to C instead but what about mingw?).
+
+ 2) how to handle threads: apparently whether signals are delivered to
+    every thread of the process or the "invoking" thread is platform
+    dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance.  For now, assume the
+    code will not call-back into itself.
+
+Ideas:
+
+ 1) Start by implementing an approach that works on platforms that
+    can use setjmp and longjmp functionality and does nothing
+    on other platforms.
+
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
+
+ 3) Add a default signal_handler function to the C-API but have the rest
+    use macros.
+
+
+Simple Interface:
+
+
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
+[code]
+NPY_SIGINT_OFF
+
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects.  In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
+
+Interrupt handling does not work well with threads.
+
+*/
+
+/* Add signal handling macros
+   Make the global variable and signal handler part of the C-API
+*/
+
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef sigsetjmp
+
+#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF jmp_buf
+
+#else
+
+#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF sigjmp_buf
+
+#endif
+
+#    define NPY_SIGINT_ON {                                             \
+                   PyOS_sighandler_t _npy_sig_save;                     \
+                   _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+                   if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+                                 1) == 0) {                             \
+
+#    define NPY_SIGINT_OFF }                                      \
+        PyOS_setsig(SIGINT, _npy_sig_save);                       \
+        }
+
+#else /* NPY_NO_SIGNAL  */
+
+#define NPY_SIGINT_ON
+#define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
+#endif /* NPY_INTERRUPT_H */
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_math.h b/tools/msys/mingw32/include/python2.7/numpy/npy_math.h
new file mode 100644
index 0000000000..e76508de04
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_math.h
@@ -0,0 +1,529 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#ifdef __SUNPRO_CC
+#include <sunmath.h>
+#endif
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+#include <numpy/npy_common.h>
+
+
+/*
+ * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
+ * for INFINITY)
+ *
+ * XXX: I should test whether INFINITY and NAN are available on the platform
+ */
+NPY_INLINE static float __npy_inff(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nanf(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_pzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL};
+    return __bint.__f;
+}
+
+#define NPY_INFINITYF __npy_inff()
+#define NPY_NANF __npy_nanf()
+#define NPY_PZEROF __npy_pzerof()
+#define NPY_NZEROF __npy_nzerof()
+
+#define NPY_INFINITY ((npy_double)NPY_INFINITYF)
+#define NPY_NAN ((npy_double)NPY_NANF)
+#define NPY_PZERO ((npy_double)NPY_PZEROF)
+#define NPY_NZERO ((npy_double)NPY_NZEROF)
+
+#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF)
+#define NPY_NANL ((npy_longdouble)NPY_NANF)
+#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF)
+#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF)
+
+/*
+ * Useful constants
+ */
+#define NPY_E         2.718281828459045235360287471352662498  /* e */
+#define NPY_LOG2E     1.442695040888963407359924681001892137  /* log_2 e */
+#define NPY_LOG10E    0.434294481903251827651128918916605082  /* log_10 e */
+#define NPY_LOGE2     0.693147180559945309417232121458176568  /* log_e 2 */
+#define NPY_LOGE10    2.302585092994045684017991454684364208  /* log_e 10 */
+#define NPY_PI        3.141592653589793238462643383279502884  /* pi */
+#define NPY_PI_2      1.570796326794896619231321691639751442  /* pi/2 */
+#define NPY_PI_4      0.785398163397448309615660845819875721  /* pi/4 */
+#define NPY_1_PI      0.318309886183790671537767526745028724  /* 1/pi */
+#define NPY_2_PI      0.636619772367581343075535053490057448  /* 2/pi */
+#define NPY_EULER     0.577215664901532860606512090082402431  /* Euler constant */
+#define NPY_SQRT2     1.414213562373095048801688724209698079  /* sqrt(2) */
+#define NPY_SQRT1_2   0.707106781186547524400844362104849039  /* 1/sqrt(2) */
+
+#define NPY_Ef        2.718281828459045235360287471352662498F /* e */
+#define NPY_LOG2Ef    1.442695040888963407359924681001892137F /* log_2 e */
+#define NPY_LOG10Ef   0.434294481903251827651128918916605082F /* log_10 e */
+#define NPY_LOGE2f    0.693147180559945309417232121458176568F /* log_e 2 */
+#define NPY_LOGE10f   2.302585092994045684017991454684364208F /* log_e 10 */
+#define NPY_PIf       3.141592653589793238462643383279502884F /* pi */
+#define NPY_PI_2f     1.570796326794896619231321691639751442F /* pi/2 */
+#define NPY_PI_4f     0.785398163397448309615660845819875721F /* pi/4 */
+#define NPY_1_PIf     0.318309886183790671537767526745028724F /* 1/pi */
+#define NPY_2_PIf     0.636619772367581343075535053490057448F /* 2/pi */
+#define NPY_EULERf    0.577215664901532860606512090082402431F /* Euler constant */
+#define NPY_SQRT2f    1.414213562373095048801688724209698079F /* sqrt(2) */
+#define NPY_SQRT1_2f  0.707106781186547524400844362104849039F /* 1/sqrt(2) */
+
+#define NPY_El        2.718281828459045235360287471352662498L /* e */
+#define NPY_LOG2El    1.442695040888963407359924681001892137L /* log_2 e */
+#define NPY_LOG10El   0.434294481903251827651128918916605082L /* log_10 e */
+#define NPY_LOGE2l    0.693147180559945309417232121458176568L /* log_e 2 */
+#define NPY_LOGE10l   2.302585092994045684017991454684364208L /* log_e 10 */
+#define NPY_PIl       3.141592653589793238462643383279502884L /* pi */
+#define NPY_PI_2l     1.570796326794896619231321691639751442L /* pi/2 */
+#define NPY_PI_4l     0.785398163397448309615660845819875721L /* pi/4 */
+#define NPY_1_PIl     0.318309886183790671537767526745028724L /* 1/pi */
+#define NPY_2_PIl     0.636619772367581343075535053490057448L /* 2/pi */
+#define NPY_EULERl    0.577215664901532860606512090082402431L /* Euler constant */
+#define NPY_SQRT2l    1.414213562373095048801688724209698079L /* sqrt(2) */
+#define NPY_SQRT1_2l  0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+
+/*
+ * C99 double math funcs
+ */
+double npy_sin(double x);
+double npy_cos(double x);
+double npy_tan(double x);
+double npy_sinh(double x);
+double npy_cosh(double x);
+double npy_tanh(double x);
+
+double npy_asin(double x);
+double npy_acos(double x);
+double npy_atan(double x);
+
+double npy_log(double x);
+double npy_log10(double x);
+double npy_exp(double x);
+double npy_sqrt(double x);
+double npy_cbrt(double x);
+
+double npy_fabs(double x);
+double npy_ceil(double x);
+double npy_fmod(double x, double y);
+double npy_floor(double x);
+
+double npy_expm1(double x);
+double npy_log1p(double x);
+double npy_hypot(double x, double y);
+double npy_acosh(double x);
+double npy_asinh(double xx);
+double npy_atanh(double x);
+double npy_rint(double x);
+double npy_trunc(double x);
+double npy_exp2(double x);
+double npy_log2(double x);
+
+double npy_atan2(double x, double y);
+double npy_pow(double x, double y);
+double npy_modf(double x, double* y);
+double npy_frexp(double x, int* y);
+double npy_ldexp(double n, int y);
+
+double npy_copysign(double x, double y);
+double npy_nextafter(double x, double y);
+double npy_spacing(double x);
+
+/*
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+ */
+
+/* use builtins to avoid function calls in tight loops
+ * only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISNAN
+    #define npy_isnan(x) __builtin_isnan(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISNAN
+        #define npy_isnan(x) ((x) != (x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isnan(x) _isnan((x))
+        #else
+            #define npy_isnan(x) isnan(x)
+        #endif
+    #endif
+#endif
+
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISFINITE
+    #define npy_isfinite(x) __builtin_isfinite(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISFINITE
+        #ifdef _MSC_VER
+            #define npy_isfinite(x) _finite((x))
+        #else
+            #define npy_isfinite(x) !npy_isnan((x) + (-x))
+        #endif
+    #else
+        #define npy_isfinite(x) isfinite((x))
+    #endif
+#endif
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISINF
+    #define npy_isinf(x) __builtin_isinf(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISINF
+        #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+        #else
+            #define npy_isinf(x) isinf((x))
+        #endif
+    #endif
+#endif
+
+#ifndef NPY_HAVE_DECL_SIGNBIT
+    int _npy_signbit_f(float x);
+    int _npy_signbit_d(double x);
+    int _npy_signbit_ld(long double x);
+    #define npy_signbit(x) \
+        (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+         : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+         : _npy_signbit_f (x))
+#else
+    #define npy_signbit(x) signbit((x))
+#endif
+
+/*
+ * float C99 math functions
+ */
+
+float npy_sinf(float x);
+float npy_cosf(float x);
+float npy_tanf(float x);
+float npy_sinhf(float x);
+float npy_coshf(float x);
+float npy_tanhf(float x);
+float npy_fabsf(float x);
+float npy_floorf(float x);
+float npy_ceilf(float x);
+float npy_rintf(float x);
+float npy_truncf(float x);
+float npy_sqrtf(float x);
+float npy_cbrtf(float x);
+float npy_log10f(float x);
+float npy_logf(float x);
+float npy_expf(float x);
+float npy_expm1f(float x);
+float npy_asinf(float x);
+float npy_acosf(float x);
+float npy_atanf(float x);
+float npy_asinhf(float x);
+float npy_acoshf(float x);
+float npy_atanhf(float x);
+float npy_log1pf(float x);
+float npy_exp2f(float x);
+float npy_log2f(float x);
+
+float npy_atan2f(float x, float y);
+float npy_hypotf(float x, float y);
+float npy_powf(float x, float y);
+float npy_fmodf(float x, float y);
+
+float npy_modff(float x, float* y);
+float npy_frexpf(float x, int* y);
+float npy_ldexpf(float x, int y);
+
+float npy_copysignf(float x, float y);
+float npy_nextafterf(float x, float y);
+float npy_spacingf(float x);
+
+/*
+ * long double C99 math functions
+ */
+
+npy_longdouble npy_sinl(npy_longdouble x);
+npy_longdouble npy_cosl(npy_longdouble x);
+npy_longdouble npy_tanl(npy_longdouble x);
+npy_longdouble npy_sinhl(npy_longdouble x);
+npy_longdouble npy_coshl(npy_longdouble x);
+npy_longdouble npy_tanhl(npy_longdouble x);
+npy_longdouble npy_fabsl(npy_longdouble x);
+npy_longdouble npy_floorl(npy_longdouble x);
+npy_longdouble npy_ceill(npy_longdouble x);
+npy_longdouble npy_rintl(npy_longdouble x);
+npy_longdouble npy_truncl(npy_longdouble x);
+npy_longdouble npy_sqrtl(npy_longdouble x);
+npy_longdouble npy_cbrtl(npy_longdouble x);
+npy_longdouble npy_log10l(npy_longdouble x);
+npy_longdouble npy_logl(npy_longdouble x);
+npy_longdouble npy_expl(npy_longdouble x);
+npy_longdouble npy_expm1l(npy_longdouble x);
+npy_longdouble npy_asinl(npy_longdouble x);
+npy_longdouble npy_acosl(npy_longdouble x);
+npy_longdouble npy_atanl(npy_longdouble x);
+npy_longdouble npy_asinhl(npy_longdouble x);
+npy_longdouble npy_acoshl(npy_longdouble x);
+npy_longdouble npy_atanhl(npy_longdouble x);
+npy_longdouble npy_log1pl(npy_longdouble x);
+npy_longdouble npy_exp2l(npy_longdouble x);
+npy_longdouble npy_log2l(npy_longdouble x);
+
+npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+
+npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_spacingl(npy_longdouble x);
+
+/*
+ * Non standard functions
+ */
+double npy_deg2rad(double x);
+double npy_rad2deg(double x);
+double npy_logaddexp(double x, double y);
+double npy_logaddexp2(double x, double y);
+double npy_divmod(double x, double y, double *modulus);
+
+float npy_deg2radf(float x);
+float npy_rad2degf(float x);
+float npy_logaddexpf(float x, float y);
+float npy_logaddexp2f(float x, float y);
+float npy_divmodf(float x, float y, float *modulus);
+
+npy_longdouble npy_deg2radl(npy_longdouble x);
+npy_longdouble npy_rad2degl(npy_longdouble x);
+npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+                           npy_longdouble *modulus);
+
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+
+/*
+ * Complex declarations
+ */
+
+/*
+ * C99 specifies that complex numbers have the same representation as
+ * an array of two elements, where the first element is the real part
+ * and the second element is the imaginary part.
+ */
+#define __NPY_CPACK_IMP(x, y, type, ctype)   \
+    union {                                  \
+        ctype z;                             \
+        type a[2];                           \
+    } z1;;                                   \
+                                             \
+    z1.a[0] = (x);                           \
+    z1.a[1] = (y);                           \
+                                             \
+    return z1.z;
+
+static NPY_INLINE npy_cdouble npy_cpack(double x, double y)
+{
+    __NPY_CPACK_IMP(x, y, double, npy_cdouble);
+}
+
+static NPY_INLINE npy_cfloat npy_cpackf(float x, float y)
+{
+    __NPY_CPACK_IMP(x, y, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y)
+{
+    __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CPACK_IMP
+
+/*
+ * Same remark as above, but in the other direction: extract first/second
+ * member of complex number, assuming a C99-compatible representation
+ *
+ * Those are defineds as static inline, and such as a reasonable compiler would
+ * most likely compile this to one or two instructions (on CISC at least)
+ */
+#define __NPY_CEXTRACT_IMP(z, index, type, ctype)   \
+    union {                                         \
+        ctype z;                                    \
+        type a[2];                                  \
+    } __z_repr;                                     \
+    __z_repr.z = z;                                 \
+                                                    \
+    return __z_repr.a[index];
+
+static NPY_INLINE double npy_creal(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble);
+}
+
+static NPY_INLINE double npy_cimag(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble);
+}
+
+static NPY_INLINE float npy_crealf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat);
+}
+
+static NPY_INLINE float npy_cimagf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble);
+}
+
+static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CEXTRACT_IMP
+
+/*
+ * Double precision complex functions
+ */
+double npy_cabs(npy_cdouble z);
+double npy_carg(npy_cdouble z);
+
+npy_cdouble npy_cexp(npy_cdouble z);
+npy_cdouble npy_clog(npy_cdouble z);
+npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y);
+
+npy_cdouble npy_csqrt(npy_cdouble z);
+
+npy_cdouble npy_ccos(npy_cdouble z);
+npy_cdouble npy_csin(npy_cdouble z);
+npy_cdouble npy_ctan(npy_cdouble z);
+
+npy_cdouble npy_ccosh(npy_cdouble z);
+npy_cdouble npy_csinh(npy_cdouble z);
+npy_cdouble npy_ctanh(npy_cdouble z);
+
+npy_cdouble npy_cacos(npy_cdouble z);
+npy_cdouble npy_casin(npy_cdouble z);
+npy_cdouble npy_catan(npy_cdouble z);
+
+npy_cdouble npy_cacosh(npy_cdouble z);
+npy_cdouble npy_casinh(npy_cdouble z);
+npy_cdouble npy_catanh(npy_cdouble z);
+
+/*
+ * Single precision complex functions
+ */
+float npy_cabsf(npy_cfloat z);
+float npy_cargf(npy_cfloat z);
+
+npy_cfloat npy_cexpf(npy_cfloat z);
+npy_cfloat npy_clogf(npy_cfloat z);
+npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y);
+
+npy_cfloat npy_csqrtf(npy_cfloat z);
+
+npy_cfloat npy_ccosf(npy_cfloat z);
+npy_cfloat npy_csinf(npy_cfloat z);
+npy_cfloat npy_ctanf(npy_cfloat z);
+
+npy_cfloat npy_ccoshf(npy_cfloat z);
+npy_cfloat npy_csinhf(npy_cfloat z);
+npy_cfloat npy_ctanhf(npy_cfloat z);
+
+npy_cfloat npy_cacosf(npy_cfloat z);
+npy_cfloat npy_casinf(npy_cfloat z);
+npy_cfloat npy_catanf(npy_cfloat z);
+
+npy_cfloat npy_cacoshf(npy_cfloat z);
+npy_cfloat npy_casinhf(npy_cfloat z);
+npy_cfloat npy_catanhf(npy_cfloat z);
+
+
+/*
+ * Extended precision complex functions
+ */
+npy_longdouble npy_cabsl(npy_clongdouble z);
+npy_longdouble npy_cargl(npy_clongdouble z);
+
+npy_clongdouble npy_cexpl(npy_clongdouble z);
+npy_clongdouble npy_clogl(npy_clongdouble z);
+npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y);
+
+npy_clongdouble npy_csqrtl(npy_clongdouble z);
+
+npy_clongdouble npy_ccosl(npy_clongdouble z);
+npy_clongdouble npy_csinl(npy_clongdouble z);
+npy_clongdouble npy_ctanl(npy_clongdouble z);
+
+npy_clongdouble npy_ccoshl(npy_clongdouble z);
+npy_clongdouble npy_csinhl(npy_clongdouble z);
+npy_clongdouble npy_ctanhl(npy_clongdouble z);
+
+npy_clongdouble npy_cacosl(npy_clongdouble z);
+npy_clongdouble npy_casinl(npy_clongdouble z);
+npy_clongdouble npy_catanl(npy_clongdouble z);
+
+npy_clongdouble npy_cacoshl(npy_clongdouble z);
+npy_clongdouble npy_casinhl(npy_clongdouble z);
+npy_clongdouble npy_catanhl(npy_clongdouble z);
+
+
+/*
+ * Functions that set the floating point error
+ * status word.
+ */
+
+/*
+ * platform-dependent code translates floating point
+ * status to an integer sum of these values
+ */
+#define NPY_FPE_DIVIDEBYZERO  1
+#define NPY_FPE_OVERFLOW      2
+#define NPY_FPE_UNDERFLOW     4
+#define NPY_FPE_INVALID       8
+
+int npy_get_floatstatus(void);
+int npy_clear_floatstatus(void);
+void npy_set_floatstatus_divbyzero(void);
+void npy_set_floatstatus_overflow(void);
+void npy_set_floatstatus_underflow(void);
+void npy_set_floatstatus_invalid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_no_deprecated_api.h b/tools/msys/mingw32/include/python2.7/numpy/npy_no_deprecated_api.h
new file mode 100644
index 0000000000..6183dc2784
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_no_deprecated_api.h
@@ -0,0 +1,19 @@
+/*
+ * This include file is provided for inclusion in Cython *.pyd files where
+ * one would like to define the NPY_NO_DEPRECATED_API macro. It can be
+ * included by
+ *
+ * cdef extern from "npy_no_deprecated_api.h": pass
+ *
+ */
+#ifndef NPY_NO_DEPRECATED_API
+
+/* put this check here since there may be multiple includes in C extensions. */
+#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \
+    defined(OLD_DEFINES_H)
+#error "npy_no_deprecated_api.h" must be first among numpy includes.
+#else
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/npy_os.h b/tools/msys/mingw32/include/python2.7/numpy/npy_os.h
new file mode 100644
index 0000000000..9228c3916e
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/npy_os.h
@@ -0,0 +1,30 @@
+#ifndef _NPY_OS_H_
+#define _NPY_OS_H_
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+    #define NPY_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
+            defined(__OpenBSD__) || defined(__DragonFly__)
+    #define NPY_OS_BSD
+    #ifdef __FreeBSD__
+        #define NPY_OS_FREEBSD
+    #elif defined(__NetBSD__)
+        #define NPY_OS_NETBSD
+    #elif defined(__OpenBSD__)
+        #define NPY_OS_OPENBSD
+    #elif defined(__DragonFly__)
+        #define NPY_OS_DRAGONFLY
+    #endif
+#elif defined(sun) || defined(__sun)
+    #define NPY_OS_SOLARIS
+#elif defined(__CYGWIN__)
+    #define NPY_OS_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+    #define NPY_OS_WIN32
+#elif defined(__APPLE__)
+    #define NPY_OS_DARWIN
+#else
+    #define NPY_OS_UNKNOWN
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/numpyconfig.h b/tools/msys/mingw32/include/python2.7/numpy/numpyconfig.h
new file mode 100644
index 0000000000..cbf4a62b9f
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/numpyconfig.h
@@ -0,0 +1,37 @@
+#ifndef _NPY_NUMPYCONFIG_H_
+#define _NPY_NUMPYCONFIG_H_
+
+#include "_numpyconfig.h"
+
+/*
+ * On Mac OS X, because there is only one configuration stage for all the archs
+ * in universal builds, any macro which depends on the arch needs to be
+ * harcoded
+ */
+#ifdef __APPLE__
+    #undef NPY_SIZEOF_LONG
+    #undef NPY_SIZEOF_PY_INTPTR_T
+
+    #ifdef __LP64__
+        #define NPY_SIZEOF_LONG         8
+        #define NPY_SIZEOF_PY_INTPTR_T  8
+    #else
+        #define NPY_SIZEOF_LONG         4
+        #define NPY_SIZEOF_PY_INTPTR_T  4
+    #endif
+#endif
+
+/**
+ * To help with the NPY_NO_DEPRECATED_API macro, we include API version
+ * numbers for specific versions of NumPy. To exclude all API that was
+ * deprecated as of 1.7, add the following before #including any NumPy
+ * headers:
+ *   #define NPY_NO_DEPRECATED_API  NPY_1_7_API_VERSION
+ */
+#define NPY_1_7_API_VERSION 0x00000007
+#define NPY_1_8_API_VERSION 0x00000008
+#define NPY_1_9_API_VERSION 0x00000008
+#define NPY_1_10_API_VERSION 0x00000008
+#define NPY_1_11_API_VERSION 0x00000008
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/old_defines.h b/tools/msys/mingw32/include/python2.7/numpy/old_defines.h
new file mode 100644
index 0000000000..abf81595ae
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/old_defines.h
@@ -0,0 +1,187 @@
+/* This header is deprecated as of NumPy 1.7 */
+#ifndef OLD_DEFINES_H
+#define OLD_DEFINES_H
+
+#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION
+#error The header "old_defines.h" is deprecated as of NumPy 1.7.
+#endif
+
+#define NDARRAY_VERSION NPY_VERSION
+
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+
+#define PyArray_TYPES       NPY_TYPES
+#define PyArray_BOOL        NPY_BOOL
+#define PyArray_BYTE        NPY_BYTE
+#define PyArray_UBYTE       NPY_UBYTE
+#define PyArray_SHORT       NPY_SHORT
+#define PyArray_USHORT      NPY_USHORT
+#define PyArray_INT         NPY_INT
+#define PyArray_UINT        NPY_UINT
+#define PyArray_LONG        NPY_LONG
+#define PyArray_ULONG       NPY_ULONG
+#define PyArray_LONGLONG    NPY_LONGLONG
+#define PyArray_ULONGLONG   NPY_ULONGLONG
+#define PyArray_HALF        NPY_HALF
+#define PyArray_FLOAT       NPY_FLOAT
+#define PyArray_DOUBLE      NPY_DOUBLE
+#define PyArray_LONGDOUBLE  NPY_LONGDOUBLE
+#define PyArray_CFLOAT      NPY_CFLOAT
+#define PyArray_CDOUBLE     NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT      NPY_OBJECT
+#define PyArray_STRING      NPY_STRING
+#define PyArray_UNICODE     NPY_UNICODE
+#define PyArray_VOID        NPY_VOID
+#define PyArray_DATETIME    NPY_DATETIME
+#define PyArray_TIMEDELTA   NPY_TIMEDELTA
+#define PyArray_NTYPES      NPY_NTYPES
+#define PyArray_NOTYPE      NPY_NOTYPE
+#define PyArray_CHAR        NPY_CHAR
+#define PyArray_USERDEF     NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+
+#define PyArray_INTP        NPY_INTP
+#define PyArray_UINTP       NPY_UINTP
+
+#define PyArray_INT8    NPY_INT8
+#define PyArray_UINT8   NPY_UINT8
+#define PyArray_INT16   NPY_INT16
+#define PyArray_UINT16  NPY_UINT16
+#define PyArray_INT32   NPY_INT32
+#define PyArray_UINT32  NPY_UINT32
+
+#ifdef NPY_INT64
+#define PyArray_INT64   NPY_INT64
+#define PyArray_UINT64  NPY_UINT64
+#endif
+
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#endif
+
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16  NPY_FLOAT16
+#define PyArray_COMPLEX32  NPY_COMPLEX32
+#endif
+
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80  NPY_FLOAT80
+#define PyArray_COMPLEX160  NPY_COMPLEX160
+#endif
+
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96  NPY_FLOAT96
+#define PyArray_COMPLEX192  NPY_COMPLEX192
+#endif
+
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128  NPY_FLOAT128
+#define PyArray_COMPLEX256  NPY_COMPLEX256
+#endif
+
+#define PyArray_FLOAT32    NPY_FLOAT32
+#define PyArray_COMPLEX64  NPY_COMPLEX64
+#define PyArray_FLOAT64    NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+
+
+#define PyArray_TYPECHAR        NPY_TYPECHAR
+#define PyArray_BOOLLTR         NPY_BOOLLTR
+#define PyArray_BYTELTR         NPY_BYTELTR
+#define PyArray_UBYTELTR        NPY_UBYTELTR
+#define PyArray_SHORTLTR        NPY_SHORTLTR
+#define PyArray_USHORTLTR       NPY_USHORTLTR
+#define PyArray_INTLTR          NPY_INTLTR
+#define PyArray_UINTLTR         NPY_UINTLTR
+#define PyArray_LONGLTR         NPY_LONGLTR
+#define PyArray_ULONGLTR        NPY_ULONGLTR
+#define PyArray_LONGLONGLTR     NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR    NPY_ULONGLONGLTR
+#define PyArray_HALFLTR         NPY_HALFLTR
+#define PyArray_FLOATLTR        NPY_FLOATLTR
+#define PyArray_DOUBLELTR       NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR   NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR       NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR      NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR  NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR       NPY_OBJECTLTR
+#define PyArray_STRINGLTR       NPY_STRINGLTR
+#define PyArray_STRINGLTR2      NPY_STRINGLTR2
+#define PyArray_UNICODELTR      NPY_UNICODELTR
+#define PyArray_VOIDLTR         NPY_VOIDLTR
+#define PyArray_DATETIMELTR     NPY_DATETIMELTR
+#define PyArray_TIMEDELTALTR    NPY_TIMEDELTALTR
+#define PyArray_CHARLTR         NPY_CHARLTR
+#define PyArray_INTPLTR         NPY_INTPLTR
+#define PyArray_UINTPLTR        NPY_UINTPLTR
+#define PyArray_GENBOOLLTR      NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR       NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR     NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR     NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR      NPY_COMPLEXLTR
+
+#define PyArray_QUICKSORT   NPY_QUICKSORT
+#define PyArray_HEAPSORT    NPY_HEAPSORT
+#define PyArray_MERGESORT   NPY_MERGESORT
+#define PyArray_SORTKIND    NPY_SORTKIND
+#define PyArray_NSORTS      NPY_NSORTS
+
+#define PyArray_NOSCALAR       NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR    NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR  NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR  NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR   NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR  NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND     NPY_SCALARKIND
+#define PyArray_NSCALARKINDS   NPY_NSCALARKINDS
+
+#define PyArray_ANYORDER     NPY_ANYORDER
+#define PyArray_CORDER       NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER        NPY_ORDER
+
+#define PyDescr_ISBOOL      PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED  PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED    PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER   PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT     PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER    PyDataType_ISNUMBER
+#define PyDescr_ISSTRING    PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX   PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON    PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE  PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF   PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED  PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT    PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS   PyDataType_HASFIELDS
+
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+
+#define PyArray_RemoveLargest PyArray_RemoveSmallest
+
+#define PyArray_UCS4 npy_ucs4
+
+#endif
diff --git a/tools/msys/mingw32/include/python2.7/numpy/oldnumeric.h b/tools/msys/mingw32/include/python2.7/numpy/oldnumeric.h
new file mode 100644
index 0000000000..748f06da31
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/oldnumeric.h
@@ -0,0 +1,23 @@
+#include "arrayobject.h"
+
+#ifndef REFCOUNT
+#  define REFCOUNT NPY_REFCOUNT
+#  define MAX_ELSIZE 16
+#endif
+
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE NPY_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define OWN_DATA NPY_OWNDATA
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
diff --git a/tools/msys/mingw32/include/python2.7/numpy/ufunc_api.txt b/tools/msys/mingw32/include/python2.7/numpy/ufunc_api.txt
new file mode 100644
index 0000000000..172749633f
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/ufunc_api.txt
@@ -0,0 +1,321 @@
+
+=================
+Numpy Ufunc C-API
+=================
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void
+                          **data, char *types, int ntypes, int nin, int
+                          nout, int identity, const char *name, const
+                          char *doc, int unused)
+
+
+::
+
+  int
+  PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int
+                              usertype, PyUFuncGenericFunction
+                              function, int *arg_types, void *data)
+
+
+::
+
+  int
+  PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject
+                          *kwds, PyArrayObject **op)
+
+
+This generic function is called with the ufunc object, the arguments to it,
+and an array of (pointers to) PyArrayObjects which are NULL.
+
+'op' is an array of at least NPY_MAXARGS PyArrayObject *.
+
+::
+
+  void
+  PyUFunc_f_f_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_g_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_F_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_G_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_O_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_gg_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_GG_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_O_O_method(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O_method(char **args, npy_intp *dimensions, npy_intp
+                      *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_On_Om(char **args, npy_intp *dimensions, npy_intp *steps, void
+                *func)
+
+
+::
+
+  int
+  PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject
+                      **errobj)
+
+
+On return, if errobj is populated with a non-NULL value, the caller
+owns a new reference to errobj.
+
+::
+
+  int
+  PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first)
+
+
+::
+
+  void
+  PyUFunc_clearfperr()
+
+
+::
+
+  int
+  PyUFunc_getfperr(void )
+
+
+::
+
+  int
+  PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int
+                      *first)
+
+
+::
+
+  int
+  PyUFunc_ReplaceLoopBySignature(PyUFuncObject
+                                 *func, PyUFuncGenericFunction
+                                 newfunc, int
+                                 *signature, PyUFuncGenericFunction
+                                 *oldfunc)
+
+
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void
+                                      **data, char *types, int
+                                      ntypes, int nin, int nout, int
+                                      identity, const char *name, const
+                                      char *doc, int unused, const char
+                                      *signature)
+
+
+::
+
+  int
+  PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+
+
+::
+
+  void
+  PyUFunc_e_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_f_f(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_ff_f(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  int
+  PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING
+                              casting, PyArrayObject
+                              **operands, PyObject
+                              *type_tup, PyArray_Descr **out_dtypes)
+
+
+This function applies the default type resolution rules
+for the provided ufunc.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING
+                          casting, PyArrayObject
+                          **operands, PyArray_Descr **dtypes)
+
+
+Validates that the input operands can be cast to
+the input types, and the output types can be cast to
+the output operands where provided.
+
+Returns 0 on success, -1 (with exception raised) on validation failure.
+
+::
+
+  int
+  PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr
+                               *user_dtype, PyUFuncGenericFunction
+                               function, PyArray_Descr
+                               **arg_dtypes, void *data)
+
+
diff --git a/tools/msys/mingw32/include/python2.7/numpy/ufuncobject.h b/tools/msys/mingw32/include/python2.7/numpy/ufuncobject.h
new file mode 100644
index 0000000000..1cca64b75b
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/ufuncobject.h
@@ -0,0 +1,357 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+
+#include <numpy/npy_math.h>
+#include <numpy/npy_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The legacy generic inner loop for a standard element-wise or
+ * generalized ufunc.
+ */
+typedef void (*PyUFuncGenericFunction)
+            (char **args,
+             npy_intp *dimensions,
+             npy_intp *strides,
+             void *innerloopdata);
+
+/*
+ * The most generic one-dimensional inner loop for
+ * a masked standard element-wise ufunc. "Masked" here means that it skips
+ * doing calculations on any items for which the maskptr array has a true
+ * value.
+ */
+typedef void (PyUFunc_MaskedStridedInnerLoopFunc)(
+                char **dataptrs, npy_intp *strides,
+                char *maskptr, npy_intp mask_stride,
+                npy_intp count,
+                NpyAuxData *innerloopdata);
+
+/* Forward declaration for the type resolver and loop selector typedefs */
+struct _tagPyUFuncObject;
+
+/*
+ * Given the operands for calling a ufunc, should determine the
+ * calculation input and output data types and return an inner loop function.
+ * This function should validate that the casting rule is being followed,
+ * and fail if it is not.
+ *
+ * For backwards compatibility, the regular type resolution function does not
+ * support auxiliary data with object semantics. The type resolution call
+ * which returns a masked generic function returns a standard NpyAuxData
+ * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros
+ * work.
+ *
+ * ufunc:             The ufunc object.
+ * casting:           The 'casting' parameter provided to the ufunc.
+ * operands:          An array of length (ufunc->nin + ufunc->nout),
+ *                    with the output parameters possibly NULL.
+ * type_tup:          Either NULL, or the type_tup passed to the ufunc.
+ * out_dtypes:        An array which should be populated with new
+ *                    references to (ufunc->nin + ufunc->nout) new
+ *                    dtypes, one for each input and output. These
+ *                    dtypes should all be in native-endian format.
+ *
+ * Should return 0 on success, -1 on failure (with exception set),
+ * or -2 if Py_NotImplemented should be returned.
+ */
+typedef int (PyUFunc_TypeResolutionFunc)(
+                                struct _tagPyUFuncObject *ufunc,
+                                NPY_CASTING casting,
+                                PyArrayObject **operands,
+                                PyObject *type_tup,
+                                PyArray_Descr **out_dtypes);
+
+/*
+ * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc,
+ * and an array of fixed strides (the array will contain NPY_MAX_INTP for
+ * strides which are not necessarily fixed), returns an inner loop
+ * with associated auxiliary data.
+ *
+ * For backwards compatibility, there is a variant of the inner loop
+ * selection which returns an inner loop irrespective of the strides,
+ * and with a void* static auxiliary data instead of an NpyAuxData *
+ * dynamically allocatable auxiliary data.
+ *
+ * ufunc:             The ufunc object.
+ * dtypes:            An array which has been populated with dtypes,
+ *                    in most cases by the type resolution funciton
+ *                    for the same ufunc.
+ * fixed_strides:     For each input/output, either the stride that
+ *                    will be used every time the function is called
+ *                    or NPY_MAX_INTP if the stride might change or
+ *                    is not known ahead of time. The loop selection
+ *                    function may use this stride to pick inner loops
+ *                    which are optimized for contiguous or 0-stride
+ *                    cases.
+ * out_innerloop:     Should be populated with the correct ufunc inner
+ *                    loop for the given type.
+ * out_innerloopdata: Should be populated with the void* data to
+ *                    be passed into the out_innerloop function.
+ * out_needs_api:     If the inner loop needs to use the Python API,
+ *                    should set the to 1, otherwise should leave
+ *                    this untouched.
+ */
+typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyUFuncGenericFunction *out_innerloop,
+                            void **out_innerloopdata,
+                            int *out_needs_api);
+typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyArray_Descr *mask_dtype,
+                            npy_intp *fixed_strides,
+                            npy_intp fixed_mask_stride,
+                            PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
+                            NpyAuxData **out_innerloopdata,
+                            int *out_needs_api);
+
+typedef struct _tagPyUFuncObject {
+        PyObject_HEAD
+        /*
+         * nin: Number of inputs
+         * nout: Number of outputs
+         * nargs: Always nin + nout (Why is it stored?)
+         */
+        int nin, nout, nargs;
+
+        /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */
+        int identity;
+
+        /* Array of one-dimensional core loops */
+        PyUFuncGenericFunction *functions;
+        /* Array of funcdata that gets passed into the functions */
+        void **data;
+        /* The number of elements in 'functions' and 'data' */
+        int ntypes;
+
+        /* Used to be unused field 'check_return' */
+        int reserved1;
+
+        /* The name of the ufunc */
+        const char *name;
+
+        /* Array of type numbers, of size ('nargs' * 'ntypes') */
+        char *types;
+
+        /* Documentation string */
+        const char *doc;
+
+        void *ptr;
+        PyObject *obj;
+        PyObject *userloops;
+
+        /* generalized ufunc parameters */
+
+        /* 0 for scalar ufunc; 1 for generalized ufunc */
+        int core_enabled;
+        /* number of distinct dimension names in signature */
+        int core_num_dim_ix;
+
+        /*
+         * dimension indices of input/output argument k are stored in
+         * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1]
+         */
+
+        /* numbers of core dimensions of each argument */
+        int *core_num_dims;
+        /*
+         * dimension indices in a flatted form; indices
+         * are in the range of [0,core_num_dim_ix)
+         */
+        int *core_dim_ixs;
+        /*
+         * positions of 1st core dimensions of each
+         * argument in core_dim_ixs
+         */
+        int *core_offsets;
+        /* signature string for printing purpose */
+        char *core_signature;
+
+        /*
+         * A function which resolves the types and fills an array
+         * with the dtypes for the inputs and outputs.
+         */
+        PyUFunc_TypeResolutionFunc *type_resolver;
+        /*
+         * A function which returns an inner loop written for
+         * NumPy 1.6 and earlier ufuncs. This is for backwards
+         * compatibility, and may be NULL if inner_loop_selector
+         * is specified.
+         */
+        PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
+        /*
+         * This was blocked off to be the "new" inner loop selector in 1.7,
+         * but this was never implemented. (This is also why the above
+         * selector is called the "legacy" selector.)
+         */
+        void *reserved2;
+        /*
+         * A function which returns a masked inner loop for the ufunc.
+         */
+        PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+
+        /*
+         * List of flags for each operand when ufunc is called by nditer object.
+         * These flags will be used in addition to the default flags for each
+         * operand set by nditer object.
+         */
+        npy_uint32 *op_flags;
+
+        /*
+         * List of global flags used when ufunc is called by nditer object.
+         * These flags will be used in addition to the default global flags
+         * set by nditer object.
+         */
+        npy_uint32 iter_flags;
+} PyUFuncObject;
+
+#include "arrayobject.h"
+
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN   1
+#define UFUNC_ERR_RAISE  2
+#define UFUNC_ERR_CALL   3
+#define UFUNC_ERR_PRINT  4
+#define UFUNC_ERR_LOG    5
+
+        /* Python side integer mask */
+
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW     3
+#define UFUNC_SHIFT_UNDERFLOW    6
+#define UFUNC_SHIFT_INVALID      9
+
+
+#define UFUNC_OBJ_ISOBJECT      1
+#define UFUNC_OBJ_NEEDS_API     2
+
+   /* Default user error mode */
+#define UFUNC_ERR_DEFAULT                               \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) +  \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) +      \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
+
+#if NPY_ALLOW_THREADS
+#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0);
+#define NPY_LOOP_END_THREADS   do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0);
+#else
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+#endif
+
+/*
+ * UFunc has unit of 1, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_One 1
+/*
+ * UFunc has unit of 0, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_Zero 0
+/*
+ * UFunc has no unit, and the order of operations cannot be reordered.
+ * This case does not allow reduction with multiple axes at once.
+ */
+#define PyUFunc_None -1
+/*
+ * UFunc has no unit, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_ReorderableNone -2
+
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+
+
+typedef struct {
+        int nin;
+        int nout;
+        PyObject *callable;
+} PyUFunc_PyFuncData;
+
+/* A linked-list of function information for
+   user-defined 1-d loops.
+ */
+typedef struct _loop1d_info {
+        PyUFuncGenericFunction func;
+        void *data;
+        int *arg_types;
+        struct _loop1d_info *next;
+        int nargs;
+        PyArray_Descr **arg_dtypes;
+} PyUFunc_Loop1d;
+
+
+#include "__ufunc_api.h"
+
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+
+#define UFUNC_CHECK_ERROR(arg) \
+        do {if ((((arg)->obj & UFUNC_OBJ_NEEDS_API) && PyErr_Occurred()) || \
+            ((arg)->errormask && \
+             PyUFunc_checkfperr((arg)->errormask, \
+                                (arg)->errobj, \
+                                &(arg)->first))) \
+                goto fail;} while (0)
+
+
+/* keep in sync with ieee754.c.src */
+#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
+      defined(__NetBSD__) || \
+      defined(__GLIBC__) || defined(__APPLE__) || \
+      defined(__CYGWIN__) || defined(__MINGW32__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version >= 502114)) || \
+      defined(_AIX) || \
+      defined(_MSC_VER) || \
+      defined(__osf__) && defined(__alpha)
+#else
+#define NO_FLOATING_POINT_SUPPORT
+#endif
+
+
+/*
+ * THESE MACROS ARE DEPRECATED.
+ * Use npy_set_floatstatus_* in the npymath library.
+ */
+#define UFUNC_FPE_DIVIDEBYZERO  NPY_FPE_DIVIDEBYZERO
+#define UFUNC_FPE_OVERFLOW      NPY_FPE_OVERFLOW
+#define UFUNC_FPE_UNDERFLOW     NPY_FPE_UNDERFLOW
+#define UFUNC_FPE_INVALID       NPY_FPE_INVALID
+
+#define UFUNC_CHECK_STATUS(ret) \
+    { \
+       ret = npy_clear_floatstatus(); \
+    }
+#define generate_divbyzero_error() npy_set_floatstatus_divbyzero()
+#define generate_overflow_error() npy_set_floatstatus_overflow()
+
+  /* Make sure it gets defined if it isn't already */
+#ifndef UFUNC_NOFPE
+/* Clear the floating point exception default of Borland C++ */
+#if defined(__BORLANDC__)
+#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM);
+#else
+#define UFUNC_NOFPE
+#endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UFUNCOBJECT_H */
diff --git a/tools/msys/mingw32/include/python2.7/numpy/utils.h b/tools/msys/mingw32/include/python2.7/numpy/utils.h
new file mode 100644
index 0000000000..cc968a3544
--- /dev/null
+++ b/tools/msys/mingw32/include/python2.7/numpy/utils.h
@@ -0,0 +1,19 @@
+#ifndef __NUMPY_UTILS_HEADER__
+#define __NUMPY_UTILS_HEADER__
+
+#ifndef __COMP_NPY_UNUSED
+        #if defined(__GNUC__)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        # elif defined(__ICC)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        #else
+                #define __COMP_NPY_UNUSED
+        #endif
+#endif
+
+/* Use this to tag a variable as not used. It will remove unused variable
+ * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable
+ * to avoid accidental use */
+#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
new file mode 100644
index 0000000000..cebc908ba3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
@@ -0,0 +1,47 @@
+Metadata-Version: 1.1
+Name: numpy
+Version: 1.11.0
+Summary: NumPy: array processing for numbers, strings, records, and objects.
+Home-page: http://www.numpy.org
+Author: NumPy Developers
+Author-email: numpy-discussion@scipy.org
+License: BSD
+Download-URL: http://sourceforge.net/projects/numpy/files/NumPy/
+Description: NumPy is a general-purpose array-processing package designed to
+        efficiently manipulate large multi-dimensional arrays of arbitrary
+        records without sacrificing too much speed for small multi-dimensional
+        arrays.  NumPy is built on the Numeric code base and adds features
+        introduced by numarray as well as an extended C-API and the ability to
+        create arrays of arbitrary type which also makes NumPy suitable for
+        interfacing with general-purpose data-base applications.
+        
+        There are also basic facilities for discrete fourier transform,
+        basic linear algebra and random number generation.
+        
+        
+Platform: Windows
+Platform: Linux
+Platform: Solaris
+Platform: Mac OS-X
+Platform: Unix
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Science/Research
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Software Development
+Classifier: Topic :: Scientific/Engineering
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: Unix
+Classifier: Operating System :: MacOS
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
new file mode 100644
index 0000000000..08df5f1808
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
@@ -0,0 +1,1054 @@
+INSTALL.rst.txt
+LICENSE.txt
+MANIFEST.in
+THANKS.txt
+setup.py
+site.cfg.example
+doc/Makefile
+doc/postprocess.py
+doc/f2py/BUGS.txt
+doc/f2py/FAQ.txt
+doc/f2py/HISTORY.txt
+doc/f2py/Makefile
+doc/f2py/OLDNEWS.txt
+doc/f2py/README.txt
+doc/f2py/Release-1.x.txt
+doc/f2py/Release-2.x.txt
+doc/f2py/Release-3.x.txt
+doc/f2py/Release-4.x.txt
+doc/f2py/TESTING.txt
+doc/f2py/THANKS.txt
+doc/f2py/TODO.txt
+doc/f2py/apps.tex
+doc/f2py/bugs.tex
+doc/f2py/collectinput.py
+doc/f2py/commands.tex
+doc/f2py/default.css
+doc/f2py/docutils.conf
+doc/f2py/f2py.1
+doc/f2py/f2py2e.tex
+doc/f2py/fortranobject.tex
+doc/f2py/hello.f
+doc/f2py/index.html
+doc/f2py/intro.tex
+doc/f2py/multiarrays.txt
+doc/f2py/notes.tex
+doc/f2py/oldnews.html
+doc/f2py/options.tex
+doc/f2py/pyforttest.pyf
+doc/f2py/pytest.py
+doc/f2py/python9.tex
+doc/f2py/signaturefile.tex
+doc/f2py/simple.f
+doc/f2py/simple_session.dat
+doc/f2py/using_F_compiler.txt
+doc/f2py/win32_notes.txt
+doc/f2py/ex1/arr.f
+doc/f2py/ex1/bar.f
+doc/f2py/ex1/foo.f
+doc/f2py/ex1/foobar-smart.f90
+doc/f2py/ex1/foobar.f90
+doc/f2py/ex1/foobarmodule.tex
+doc/f2py/ex1/runme
+doc/f2py/f2python9-final/README.txt
+doc/f2py/f2python9-final/aerostructure.jpg
+doc/f2py/f2python9-final/flow.jpg
+doc/f2py/f2python9-final/mk_html.sh
+doc/f2py/f2python9-final/mk_pdf.sh
+doc/f2py/f2python9-final/mk_ps.sh
+doc/f2py/f2python9-final/structure.jpg
+doc/f2py/f2python9-final/src/examples/exp1.f
+doc/f2py/f2python9-final/src/examples/exp1mess.txt
+doc/f2py/f2python9-final/src/examples/exp1session.txt
+doc/f2py/f2python9-final/src/examples/foo.pyf
+doc/f2py/f2python9-final/src/examples/foom.pyf
+doc/f2py/multiarray/array_from_pyobj.c
+doc/f2py/multiarray/bar.c
+doc/f2py/multiarray/foo.f
+doc/f2py/multiarray/fortran_array_from_pyobj.txt
+doc/f2py/multiarray/fun.pyf
+doc/f2py/multiarray/run.pyf
+doc/f2py/multiarray/transpose.txt
+doc/release/1.10.0-notes.rst
+doc/release/1.10.1-notes.rst
+doc/release/1.10.2-notes.rst
+doc/release/1.10.3-notes.rst
+doc/release/1.10.4-notes.rst
+doc/release/1.11.0-notes.rst
+doc/release/1.3.0-notes.rst
+doc/release/1.4.0-notes.rst
+doc/release/1.5.0-notes.rst
+doc/release/1.6.0-notes.rst
+doc/release/1.6.1-notes.rst
+doc/release/1.6.2-notes.rst
+doc/release/1.7.0-notes.rst
+doc/release/1.7.1-notes.rst
+doc/release/1.7.2-notes.rst
+doc/release/1.8.0-notes.rst
+doc/release/1.8.1-notes.rst
+doc/release/1.8.2-notes.rst
+doc/release/1.9.0-notes.rst
+doc/release/1.9.1-notes.rst
+doc/release/1.9.2-notes.rst
+doc/release/time_based_proposal.rst
+doc/scipy-sphinx-theme/.git
+doc/scipy-sphinx-theme/.gitignore
+doc/scipy-sphinx-theme/Makefile
+doc/scipy-sphinx-theme/README.rst
+doc/scipy-sphinx-theme/conf.py
+doc/scipy-sphinx-theme/index.rst
+doc/scipy-sphinx-theme/test_autodoc.rst
+doc/scipy-sphinx-theme/test_autodoc_2.rst
+doc/scipy-sphinx-theme/test_autodoc_3.rst
+doc/scipy-sphinx-theme/test_autodoc_4.rst
+doc/scipy-sphinx-theme/test_optimize.rst
+doc/scipy-sphinx-theme/_static/scipyshiny_small.png
+doc/scipy-sphinx-theme/_theme/scipy/layout.html
+doc/scipy-sphinx-theme/_theme/scipy/searchbox.html
+doc/scipy-sphinx-theme/_theme/scipy/sourcelink.html
+doc/scipy-sphinx-theme/_theme/scipy/theme.conf
+doc/scipy-sphinx-theme/_theme/scipy/static/scipy.css_t
+doc/scipy-sphinx-theme/_theme/scipy/static/css/extend.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/pygments.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/scipy-central.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/spc-bootstrap.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/spc-extend.css
+doc/scipy-sphinx-theme/_theme/scipy/static/img/all-icons.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/contents.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/create-new-account-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon-tiniest.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/glyphicons-halflings-white.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/glyphicons-halflings.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/important-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/information-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/internet-web-browser.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/navigation.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/person-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/person-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipy-logo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipy_org_logo.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipycentral_logo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipyshiny_small.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/send-email-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon-tiniest.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/transparent-pixel.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/ui-anim_basic_16x16.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ad.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ae.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-af.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ag.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ai.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-al.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-am.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ao.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-aq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ar.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-as.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-at.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-au.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-aw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-az.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ba.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-be.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-br.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-by.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ca.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ch.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ci.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ck.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-co.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cx.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-de.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-do.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ec.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ee.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-eg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-er.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-es.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-et.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ga.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ge.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ht.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-id.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ie.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-il.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-im.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-in.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-io.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-iq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ir.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-is.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-it.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-je.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ke.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ki.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-km.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ky.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-la.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-li.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ls.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ly.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ma.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-md.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-me.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ml.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ms.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mx.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-my.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-na.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ne.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ng.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ni.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-no.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-np.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-om.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pe.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ph.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ps.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-py.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-qa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-re.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ro.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-rs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ru.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-rw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-se.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-si.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-so.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-st.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-td.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-th.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-to.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ua.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ug.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-um.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-us.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-uy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-uz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-va.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ve.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-wf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ws.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ye.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-za.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-zm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-zw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/js/copybutton.js
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-bootstrap.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-content.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-extend.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-footer.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-header.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-rightsidebar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-utils.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/accordion.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/alerts.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/bootstrap.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/breadcrumbs.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/button-groups.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/buttons.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/carousel.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/close.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/code.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/component-animations.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/dropdowns.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/forms.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/grid.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/hero-unit.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/labels-badges.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/layouts.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/media.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/mixins.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/modals.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/navbar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/navs.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/pager.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/pagination.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/popovers.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/progress-bars.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/reset.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-1200px-min.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-767px-max.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-768px-979px.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-navbar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-utilities.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/scaffolding.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/sprites.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/tables.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/thumbnails.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/tooltip.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/type.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/utilities.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/variables.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/wells.less
+doc/source/about.rst
+doc/source/bugs.rst
+doc/source/conf.py
+doc/source/contents.rst
+doc/source/glossary.rst
+doc/source/license.rst
+doc/source/release.rst
+doc/source/_templates/indexcontent.html
+doc/source/_templates/indexsidebar.html
+doc/source/_templates/layout.html
+doc/source/_templates/autosummary/class.rst
+doc/source/dev/development_environment.rst
+doc/source/dev/gitwash_links.txt
+doc/source/dev/index.rst
+doc/source/dev/gitwash/configure_git.rst
+doc/source/dev/gitwash/development_setup.rst
+doc/source/dev/gitwash/development_workflow.rst
+doc/source/dev/gitwash/dot2_dot3.rst
+doc/source/dev/gitwash/following_latest.rst
+doc/source/dev/gitwash/forking_button.png
+doc/source/dev/gitwash/git_development.rst
+doc/source/dev/gitwash/git_intro.rst
+doc/source/dev/gitwash/git_links.inc
+doc/source/dev/gitwash/git_resources.rst
+doc/source/dev/gitwash/index.rst
+doc/source/dev/gitwash/pull_button.png
+doc/source/dev/governance/governance.rst
+doc/source/dev/governance/index.rst
+doc/source/dev/governance/people.rst
+doc/source/f2py/advanced.rst
+doc/source/f2py/allocarr.f90
+doc/source/f2py/allocarr_session.dat
+doc/source/f2py/array.f
+doc/source/f2py/array_session.dat
+doc/source/f2py/calculate.f
+doc/source/f2py/calculate_session.dat
+doc/source/f2py/callback.f
+doc/source/f2py/callback2.pyf
+doc/source/f2py/callback_session.dat
+doc/source/f2py/common.f
+doc/source/f2py/common_session.dat
+doc/source/f2py/compile_session.dat
+doc/source/f2py/distutils.rst
+doc/source/f2py/extcallback.f
+doc/source/f2py/extcallback_session.dat
+doc/source/f2py/fib1.f
+doc/source/f2py/fib1.pyf
+doc/source/f2py/fib2.pyf
+doc/source/f2py/fib3.f
+doc/source/f2py/ftype.f
+doc/source/f2py/ftype_session.dat
+doc/source/f2py/getting-started.rst
+doc/source/f2py/index.rst
+doc/source/f2py/moddata.f90
+doc/source/f2py/moddata_session.dat
+doc/source/f2py/python-usage.rst
+doc/source/f2py/run_main_session.dat
+doc/source/f2py/scalar.f
+doc/source/f2py/scalar_session.dat
+doc/source/f2py/setup_example.py
+doc/source/f2py/signature-file.rst
+doc/source/f2py/spam.pyf
+doc/source/f2py/spam_session.dat
+doc/source/f2py/string.f
+doc/source/f2py/string_session.dat
+doc/source/f2py/usage.rst
+doc/source/f2py/var.pyf
+doc/source/f2py/var_session.dat
+doc/source/neps/datetime-proposal.rst
+doc/source/neps/datetime-proposal3.rst
+doc/source/neps/deferred-ufunc-evaluation.rst
+doc/source/neps/generalized-ufuncs.rst
+doc/source/neps/groupby_additions.rst
+doc/source/neps/index.rst
+doc/source/neps/math_config_clean.rst
+doc/source/neps/missing-data.rst
+doc/source/neps/new-iterator-ufunc.rst
+doc/source/neps/newbugtracker.rst
+doc/source/neps/npy-format.rst
+doc/source/neps/structured_array_extensions.rst
+doc/source/neps/ufunc-overrides.rst
+doc/source/neps/warnfix.rst
+doc/source/reference/arrays.classes.rst
+doc/source/reference/arrays.datetime.rst
+doc/source/reference/arrays.dtypes.rst
+doc/source/reference/arrays.indexing.rst
+doc/source/reference/arrays.interface.rst
+doc/source/reference/arrays.ndarray.rst
+doc/source/reference/arrays.nditer.rst
+doc/source/reference/arrays.rst
+doc/source/reference/arrays.scalars.rst
+doc/source/reference/c-api.array.rst
+doc/source/reference/c-api.config.rst
+doc/source/reference/c-api.coremath.rst
+doc/source/reference/c-api.deprecations.rst
+doc/source/reference/c-api.dtype.rst
+doc/source/reference/c-api.generalized-ufuncs.rst
+doc/source/reference/c-api.iterator.rst
+doc/source/reference/c-api.rst
+doc/source/reference/c-api.types-and-structures.rst
+doc/source/reference/c-api.ufunc.rst
+doc/source/reference/distutils.rst
+doc/source/reference/index.rst
+doc/source/reference/internals.code-explanations.rst
+doc/source/reference/internals.rst
+doc/source/reference/maskedarray.baseclass.rst
+doc/source/reference/maskedarray.generic.rst
+doc/source/reference/maskedarray.rst
+doc/source/reference/routines.array-creation.rst
+doc/source/reference/routines.array-manipulation.rst
+doc/source/reference/routines.bitwise.rst
+doc/source/reference/routines.char.rst
+doc/source/reference/routines.ctypeslib.rst
+doc/source/reference/routines.datetime.rst
+doc/source/reference/routines.dtype.rst
+doc/source/reference/routines.dual.rst
+doc/source/reference/routines.emath.rst
+doc/source/reference/routines.err.rst
+doc/source/reference/routines.fft.rst
+doc/source/reference/routines.financial.rst
+doc/source/reference/routines.functional.rst
+doc/source/reference/routines.help.rst
+doc/source/reference/routines.indexing.rst
+doc/source/reference/routines.io.rst
+doc/source/reference/routines.linalg.rst
+doc/source/reference/routines.logic.rst
+doc/source/reference/routines.ma.rst
+doc/source/reference/routines.math.rst
+doc/source/reference/routines.matlib.rst
+doc/source/reference/routines.numarray.rst
+doc/source/reference/routines.oldnumeric.rst
+doc/source/reference/routines.other.rst
+doc/source/reference/routines.padding.rst
+doc/source/reference/routines.polynomials.chebyshev.rst
+doc/source/reference/routines.polynomials.classes.rst
+doc/source/reference/routines.polynomials.hermite.rst
+doc/source/reference/routines.polynomials.hermite_e.rst
+doc/source/reference/routines.polynomials.laguerre.rst
+doc/source/reference/routines.polynomials.legendre.rst
+doc/source/reference/routines.polynomials.package.rst
+doc/source/reference/routines.polynomials.poly1d.rst
+doc/source/reference/routines.polynomials.polynomial.rst
+doc/source/reference/routines.polynomials.rst
+doc/source/reference/routines.random.rst
+doc/source/reference/routines.rst
+doc/source/reference/routines.set.rst
+doc/source/reference/routines.sort.rst
+doc/source/reference/routines.statistics.rst
+doc/source/reference/routines.testing.rst
+doc/source/reference/routines.window.rst
+doc/source/reference/swig.interface-file.rst
+doc/source/reference/swig.rst
+doc/source/reference/swig.testing.rst
+doc/source/reference/ufuncs.rst
+doc/source/reference/figures/dtype-hierarchy.dia
+doc/source/reference/figures/dtype-hierarchy.pdf
+doc/source/reference/figures/dtype-hierarchy.png
+doc/source/reference/figures/threefundamental.fig
+doc/source/reference/figures/threefundamental.pdf
+doc/source/reference/figures/threefundamental.png
+doc/source/user/basics.broadcasting.rst
+doc/source/user/basics.byteswapping.rst
+doc/source/user/basics.creation.rst
+doc/source/user/basics.indexing.rst
+doc/source/user/basics.io.genfromtxt.rst
+doc/source/user/basics.io.rst
+doc/source/user/basics.rec.rst
+doc/source/user/basics.rst
+doc/source/user/basics.subclassing.rst
+doc/source/user/basics.types.rst
+doc/source/user/building.rst
+doc/source/user/c-info.beyond-basics.rst
+doc/source/user/c-info.how-to-extend.rst
+doc/source/user/c-info.python-as-glue.rst
+doc/source/user/c-info.rst
+doc/source/user/c-info.ufunc-tutorial.rst
+doc/source/user/index.rst
+doc/source/user/install.rst
+doc/source/user/misc.rst
+doc/source/user/numpy-for-matlab-users.rst
+doc/source/user/quickstart.rst
+doc/source/user/setting-up.rst
+doc/source/user/whatisnumpy.rst
+doc/sphinxext/.git
+doc/sphinxext/.gitignore
+doc/sphinxext/.travis.yml
+doc/sphinxext/LICENSE.txt
+doc/sphinxext/MANIFEST.in
+doc/sphinxext/README.rst
+doc/sphinxext/setup.py
+doc/sphinxext/numpydoc/__init__.py
+doc/sphinxext/numpydoc/comment_eater.py
+doc/sphinxext/numpydoc/compiler_unparse.py
+doc/sphinxext/numpydoc/docscrape.py
+doc/sphinxext/numpydoc/docscrape_sphinx.py
+doc/sphinxext/numpydoc/linkcode.py
+doc/sphinxext/numpydoc/numpydoc.py
+doc/sphinxext/numpydoc/phantom_import.py
+doc/sphinxext/numpydoc/plot_directive.py
+doc/sphinxext/numpydoc/traitsdoc.py
+doc/sphinxext/numpydoc/tests/test_docscrape.py
+doc/sphinxext/numpydoc/tests/test_linkcode.py
+doc/sphinxext/numpydoc/tests/test_phantom_import.py
+doc/sphinxext/numpydoc/tests/test_plot_directive.py
+doc/sphinxext/numpydoc/tests/test_traitsdoc.py
+numpy/__init__.py
+numpy/_import_tools.py
+numpy/add_newdocs.py
+numpy/ctypeslib.py
+numpy/dual.py
+numpy/matlib.py
+numpy/setup.py
+numpy/version.py
+numpy.egg-info/PKG-INFO
+numpy.egg-info/SOURCES.txt
+numpy.egg-info/dependency_links.txt
+numpy.egg-info/top_level.txt
+numpy/_build_utils/README
+numpy/_build_utils/__init__.py
+numpy/_build_utils/apple_accelerate.py
+numpy/_build_utils/common.py
+numpy/_build_utils/src/apple_sgemv_fix.c
+numpy/compat/__init__.py
+numpy/compat/_inspect.py
+numpy/compat/py3k.py
+numpy/compat/setup.py
+numpy/core/__init__.py
+numpy/core/_internal.py
+numpy/core/_methods.py
+numpy/core/arrayprint.py
+numpy/core/cversions.py
+numpy/core/defchararray.py
+numpy/core/fromnumeric.py
+numpy/core/function_base.py
+numpy/core/getlimits.py
+numpy/core/info.py
+numpy/core/machar.py
+numpy/core/memmap.py
+numpy/core/mlib.ini.in
+numpy/core/npymath.ini.in
+numpy/core/numeric.py
+numpy/core/numerictypes.py
+numpy/core/records.py
+numpy/core/setup.py
+numpy/core/setup_common.py
+numpy/core/shape_base.py
+numpy/core/code_generators/__init__.py
+numpy/core/code_generators/cversions.txt
+numpy/core/code_generators/genapi.py
+numpy/core/code_generators/generate_numpy_api.py
+numpy/core/code_generators/generate_ufunc_api.py
+numpy/core/code_generators/generate_umath.py
+numpy/core/code_generators/numpy_api.py
+numpy/core/code_generators/ufunc_docstrings.py
+numpy/core/include/numpy/_neighborhood_iterator_imp.h
+numpy/core/include/numpy/_numpyconfig.h.in
+numpy/core/include/numpy/arrayobject.h
+numpy/core/include/numpy/arrayscalars.h
+numpy/core/include/numpy/halffloat.h
+numpy/core/include/numpy/ndarrayobject.h
+numpy/core/include/numpy/ndarraytypes.h
+numpy/core/include/numpy/noprefix.h
+numpy/core/include/numpy/npy_1_7_deprecated_api.h
+numpy/core/include/numpy/npy_3kcompat.h
+numpy/core/include/numpy/npy_common.h
+numpy/core/include/numpy/npy_cpu.h
+numpy/core/include/numpy/npy_endian.h
+numpy/core/include/numpy/npy_interrupt.h
+numpy/core/include/numpy/npy_math.h
+numpy/core/include/numpy/npy_no_deprecated_api.h
+numpy/core/include/numpy/npy_os.h
+numpy/core/include/numpy/numpyconfig.h
+numpy/core/include/numpy/old_defines.h
+numpy/core/include/numpy/oldnumeric.h
+numpy/core/include/numpy/ufuncobject.h
+numpy/core/include/numpy/utils.h
+numpy/core/src/dummymodule.c
+numpy/core/src/multiarray/_datetime.h
+numpy/core/src/multiarray/alloc.c
+numpy/core/src/multiarray/alloc.h
+numpy/core/src/multiarray/array_assign.c
+numpy/core/src/multiarray/array_assign.h
+numpy/core/src/multiarray/array_assign_array.c
+numpy/core/src/multiarray/array_assign_scalar.c
+numpy/core/src/multiarray/arrayobject.c
+numpy/core/src/multiarray/arrayobject.h
+numpy/core/src/multiarray/arraytypes.h
+numpy/core/src/multiarray/buffer.c
+numpy/core/src/multiarray/buffer.h
+numpy/core/src/multiarray/calculation.c
+numpy/core/src/multiarray/calculation.h
+numpy/core/src/multiarray/cblasfuncs.c
+numpy/core/src/multiarray/cblasfuncs.h
+numpy/core/src/multiarray/common.c
+numpy/core/src/multiarray/common.h
+numpy/core/src/multiarray/compiled_base.c
+numpy/core/src/multiarray/compiled_base.h
+numpy/core/src/multiarray/conversion_utils.c
+numpy/core/src/multiarray/conversion_utils.h
+numpy/core/src/multiarray/convert.c
+numpy/core/src/multiarray/convert.h
+numpy/core/src/multiarray/convert_datatype.c
+numpy/core/src/multiarray/convert_datatype.h
+numpy/core/src/multiarray/ctors.c
+numpy/core/src/multiarray/ctors.h
+numpy/core/src/multiarray/datetime.c
+numpy/core/src/multiarray/datetime_busday.c
+numpy/core/src/multiarray/datetime_busday.h
+numpy/core/src/multiarray/datetime_busdaycal.c
+numpy/core/src/multiarray/datetime_busdaycal.h
+numpy/core/src/multiarray/datetime_strings.c
+numpy/core/src/multiarray/datetime_strings.h
+numpy/core/src/multiarray/descriptor.c
+numpy/core/src/multiarray/descriptor.h
+numpy/core/src/multiarray/dtype_transfer.c
+numpy/core/src/multiarray/flagsobject.c
+numpy/core/src/multiarray/getset.c
+numpy/core/src/multiarray/getset.h
+numpy/core/src/multiarray/hashdescr.c
+numpy/core/src/multiarray/hashdescr.h
+numpy/core/src/multiarray/item_selection.c
+numpy/core/src/multiarray/item_selection.h
+numpy/core/src/multiarray/iterators.c
+numpy/core/src/multiarray/iterators.h
+numpy/core/src/multiarray/mapping.c
+numpy/core/src/multiarray/mapping.h
+numpy/core/src/multiarray/methods.c
+numpy/core/src/multiarray/methods.h
+numpy/core/src/multiarray/multiarraymodule.c
+numpy/core/src/multiarray/multiarraymodule.h
+numpy/core/src/multiarray/nditer_api.c
+numpy/core/src/multiarray/nditer_constr.c
+numpy/core/src/multiarray/nditer_impl.h
+numpy/core/src/multiarray/nditer_pywrap.c
+numpy/core/src/multiarray/nditer_pywrap.h
+numpy/core/src/multiarray/number.c
+numpy/core/src/multiarray/number.h
+numpy/core/src/multiarray/numpymemoryview.c
+numpy/core/src/multiarray/numpymemoryview.h
+numpy/core/src/multiarray/numpyos.c
+numpy/core/src/multiarray/numpyos.h
+numpy/core/src/multiarray/python_xerbla.c
+numpy/core/src/multiarray/refcount.c
+numpy/core/src/multiarray/refcount.h
+numpy/core/src/multiarray/scalarapi.c
+numpy/core/src/multiarray/scalartypes.h
+numpy/core/src/multiarray/sequence.c
+numpy/core/src/multiarray/sequence.h
+numpy/core/src/multiarray/shape.c
+numpy/core/src/multiarray/shape.h
+numpy/core/src/multiarray/ucsnarrow.c
+numpy/core/src/multiarray/ucsnarrow.h
+numpy/core/src/multiarray/usertypes.c
+numpy/core/src/multiarray/usertypes.h
+numpy/core/src/multiarray/vdot.c
+numpy/core/src/multiarray/vdot.h
+numpy/core/src/npymath/_signbit.c
+numpy/core/src/npymath/halffloat.c
+numpy/core/src/npymath/ieee754.c.src
+numpy/core/src/npymath/npy_math.c.src
+numpy/core/src/npymath/npy_math_common.h
+numpy/core/src/npymath/npy_math_complex.c.src
+numpy/core/src/npymath/npy_math_private.h
+numpy/core/src/npysort/binsearch.c.src
+numpy/core/src/npysort/heapsort.c.src
+numpy/core/src/npysort/mergesort.c.src
+numpy/core/src/npysort/npysort_common.h
+numpy/core/src/npysort/quicksort.c.src
+numpy/core/src/npysort/selection.c.src
+numpy/core/src/private/lowlevel_strided_loops.h
+numpy/core/src/private/mem_overlap.c
+numpy/core/src/private/mem_overlap.h
+numpy/core/src/private/npy_binsearch.h.src
+numpy/core/src/private/npy_cblas.h
+numpy/core/src/private/npy_config.h
+numpy/core/src/private/npy_extint128.h
+numpy/core/src/private/npy_fpmath.h
+numpy/core/src/private/npy_import.h
+numpy/core/src/private/npy_partition.h.src
+numpy/core/src/private/npy_pycompat.h
+numpy/core/src/private/npy_sort.h
+numpy/core/src/private/templ_common.h.src
+numpy/core/src/private/ufunc_override.h
+numpy/core/src/umath/reduction.c
+numpy/core/src/umath/reduction.h
+numpy/core/src/umath/simd.inc.src
+numpy/core/src/umath/ufunc_object.c
+numpy/core/src/umath/ufunc_object.h
+numpy/core/src/umath/ufunc_type_resolution.c
+numpy/core/src/umath/ufunc_type_resolution.h
+numpy/core/src/umath/umathmodule.c
+numpy/distutils/__init__.py
+numpy/distutils/__version__.py
+numpy/distutils/ccompiler.py
+numpy/distutils/compat.py
+numpy/distutils/conv_template.py
+numpy/distutils/core.py
+numpy/distutils/cpuinfo.py
+numpy/distutils/environment.py
+numpy/distutils/exec_command.py
+numpy/distutils/extension.py
+numpy/distutils/from_template.py
+numpy/distutils/info.py
+numpy/distutils/intelccompiler.py
+numpy/distutils/lib2def.py
+numpy/distutils/line_endings.py
+numpy/distutils/log.py
+numpy/distutils/mingw32ccompiler.py
+numpy/distutils/misc_util.py
+numpy/distutils/msvc9compiler.py
+numpy/distutils/msvccompiler.py
+numpy/distutils/npy_pkg_config.py
+numpy/distutils/numpy_distribution.py
+numpy/distutils/pathccompiler.py
+numpy/distutils/setup.py
+numpy/distutils/system_info.py
+numpy/distutils/unixccompiler.py
+numpy/distutils/command/__init__.py
+numpy/distutils/command/autodist.py
+numpy/distutils/command/bdist_rpm.py
+numpy/distutils/command/build.py
+numpy/distutils/command/build_clib.py
+numpy/distutils/command/build_ext.py
+numpy/distutils/command/build_py.py
+numpy/distutils/command/build_scripts.py
+numpy/distutils/command/build_src.py
+numpy/distutils/command/config.py
+numpy/distutils/command/config_compiler.py
+numpy/distutils/command/develop.py
+numpy/distutils/command/egg_info.py
+numpy/distutils/command/install.py
+numpy/distutils/command/install_clib.py
+numpy/distutils/command/install_data.py
+numpy/distutils/command/install_headers.py
+numpy/distutils/command/sdist.py
+numpy/distutils/fcompiler/__init__.py
+numpy/distutils/fcompiler/absoft.py
+numpy/distutils/fcompiler/compaq.py
+numpy/distutils/fcompiler/g95.py
+numpy/distutils/fcompiler/gnu.py
+numpy/distutils/fcompiler/hpux.py
+numpy/distutils/fcompiler/ibm.py
+numpy/distutils/fcompiler/intel.py
+numpy/distutils/fcompiler/lahey.py
+numpy/distutils/fcompiler/mips.py
+numpy/distutils/fcompiler/nag.py
+numpy/distutils/fcompiler/none.py
+numpy/distutils/fcompiler/pathf95.py
+numpy/distutils/fcompiler/pg.py
+numpy/distutils/fcompiler/sun.py
+numpy/distutils/fcompiler/vast.py
+numpy/doc/__init__.py
+numpy/doc/basics.py
+numpy/doc/broadcasting.py
+numpy/doc/byteswapping.py
+numpy/doc/constants.py
+numpy/doc/creation.py
+numpy/doc/glossary.py
+numpy/doc/indexing.py
+numpy/doc/internals.py
+numpy/doc/misc.py
+numpy/doc/structured_arrays.py
+numpy/doc/subclassing.py
+numpy/doc/ufuncs.py
+numpy/f2py/__init__.py
+numpy/f2py/__main__.py
+numpy/f2py/__version__.py
+numpy/f2py/auxfuncs.py
+numpy/f2py/capi_maps.py
+numpy/f2py/cb_rules.py
+numpy/f2py/cfuncs.py
+numpy/f2py/common_rules.py
+numpy/f2py/crackfortran.py
+numpy/f2py/diagnose.py
+numpy/f2py/f2py2e.py
+numpy/f2py/f2py_testing.py
+numpy/f2py/f90mod_rules.py
+numpy/f2py/func2subr.py
+numpy/f2py/info.py
+numpy/f2py/rules.py
+numpy/f2py/setup.py
+numpy/f2py/use_rules.py
+numpy/fft/__init__.py
+numpy/fft/fftpack.c
+numpy/fft/fftpack.h
+numpy/fft/fftpack.py
+numpy/fft/fftpack_litemodule.c
+numpy/fft/helper.py
+numpy/fft/info.py
+numpy/fft/setup.py
+numpy/lib/__init__.py
+numpy/lib/_datasource.py
+numpy/lib/_iotools.py
+numpy/lib/_version.py
+numpy/lib/arraypad.py
+numpy/lib/arraysetops.py
+numpy/lib/arrayterator.py
+numpy/lib/financial.py
+numpy/lib/format.py
+numpy/lib/function_base.py
+numpy/lib/index_tricks.py
+numpy/lib/info.py
+numpy/lib/nanfunctions.py
+numpy/lib/npyio.py
+numpy/lib/polynomial.py
+numpy/lib/recfunctions.py
+numpy/lib/scimath.py
+numpy/lib/setup.py
+numpy/lib/shape_base.py
+numpy/lib/stride_tricks.py
+numpy/lib/twodim_base.py
+numpy/lib/type_check.py
+numpy/lib/ufunclike.py
+numpy/lib/user_array.py
+numpy/lib/utils.py
+numpy/linalg/__init__.py
+numpy/linalg/info.py
+numpy/linalg/lapack_litemodule.c
+numpy/linalg/linalg.py
+numpy/linalg/setup.py
+numpy/linalg/lapack_lite/blas_lite.c
+numpy/linalg/lapack_lite/dlamch.c
+numpy/linalg/lapack_lite/dlapack_lite.c
+numpy/linalg/lapack_lite/f2c.h
+numpy/linalg/lapack_lite/f2c_lite.c
+numpy/linalg/lapack_lite/python_xerbla.c
+numpy/linalg/lapack_lite/zlapack_lite.c
+numpy/ma/__init__.py
+numpy/ma/bench.py
+numpy/ma/core.py
+numpy/ma/extras.py
+numpy/ma/mrecords.py
+numpy/ma/setup.py
+numpy/ma/testutils.py
+numpy/ma/timer_comparison.py
+numpy/ma/version.py
+numpy/matrixlib/__init__.py
+numpy/matrixlib/defmatrix.py
+numpy/matrixlib/setup.py
+numpy/polynomial/__init__.py
+numpy/polynomial/_polybase.py
+numpy/polynomial/chebyshev.py
+numpy/polynomial/hermite.py
+numpy/polynomial/hermite_e.py
+numpy/polynomial/laguerre.py
+numpy/polynomial/legendre.py
+numpy/polynomial/polynomial.py
+numpy/polynomial/polyutils.py
+numpy/polynomial/setup.py
+numpy/random/__init__.py
+numpy/random/info.py
+numpy/random/setup.py
+numpy/random/mtrand/Python.pxi
+numpy/random/mtrand/distributions.c
+numpy/random/mtrand/distributions.h
+numpy/random/mtrand/generate_mtrand_c.py
+numpy/random/mtrand/initarray.c
+numpy/random/mtrand/initarray.h
+numpy/random/mtrand/mt_compat.h
+numpy/random/mtrand/mtrand.c
+numpy/random/mtrand/mtrand.pyx
+numpy/random/mtrand/mtrand_py_helper.h
+numpy/random/mtrand/numpy.pxd
+numpy/random/mtrand/randomkit.c
+numpy/random/mtrand/randomkit.h
+numpy/testing/__init__.py
+numpy/testing/decorators.py
+numpy/testing/noseclasses.py
+numpy/testing/nosetester.py
+numpy/testing/print_coercion_tables.py
+numpy/testing/setup.py
+numpy/testing/utils.py
+tools/swig/Makefile
+tools/swig/README
+tools/swig/numpy.i
+tools/swig/pyfragments.swg
+tools/swig/test/Array.i
+tools/swig/test/Array1.cxx
+tools/swig/test/Array1.h
+tools/swig/test/Array2.cxx
+tools/swig/test/Array2.h
+tools/swig/test/ArrayZ.cxx
+tools/swig/test/ArrayZ.h
+tools/swig/test/Farray.cxx
+tools/swig/test/Farray.h
+tools/swig/test/Farray.i
+tools/swig/test/Flat.cxx
+tools/swig/test/Flat.h
+tools/swig/test/Flat.i
+tools/swig/test/Fortran.cxx
+tools/swig/test/Fortran.h
+tools/swig/test/Fortran.i
+tools/swig/test/Makefile
+tools/swig/test/Matrix.cxx
+tools/swig/test/Matrix.h
+tools/swig/test/Matrix.i
+tools/swig/test/SuperTensor.cxx
+tools/swig/test/SuperTensor.h
+tools/swig/test/SuperTensor.i
+tools/swig/test/Tensor.cxx
+tools/swig/test/Tensor.h
+tools/swig/test/Tensor.i
+tools/swig/test/Vector.cxx
+tools/swig/test/Vector.h
+tools/swig/test/Vector.i
+tools/swig/test/setup.py
+tools/swig/test/testArray.py
+tools/swig/test/testFarray.py
+tools/swig/test/testFlat.py
+tools/swig/test/testFortran.py
+tools/swig/test/testMatrix.py
+tools/swig/test/testSuperTensor.py
+tools/swig/test/testTensor.py
+tools/swig/test/testVector.py
\ No newline at end of file
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
new file mode 100644
index 0000000000..24ce15ab7e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
@@ -0,0 +1 @@
+numpy
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__config__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__config__.py
new file mode 100644
index 0000000000..8d0a522235
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__config__.py
@@ -0,0 +1,26 @@
+# This file is generated by C:/repo/mingw-w64-python-numpy/src/numpy-py2-i686/setup.py
+# It contains system_info results at the time of building this package.
+__all__ = ["get_info","show"]
+
+lapack_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+openblas_lapack_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_mkl_info={}
+openblas_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    
\ No newline at end of file
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__init__.py
new file mode 100644
index 0000000000..0fcd5097d2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/__init__.py
@@ -0,0 +1,229 @@
+"""
+NumPy
+=====
+
+Provides
+  1. An array object of arbitrary homogeneous items
+  2. Fast mathematical operations over arrays
+  3. Linear Algebra, Fourier Transforms, Random Number Generation
+
+How to use the documentation
+----------------------------
+Documentation is available in two forms: docstrings provided
+with the code, and a loose standing reference guide, available from
+`the NumPy homepage <http://www.scipy.org>`_.
+
+We recommend exploring the docstrings using
+`IPython <http://ipython.scipy.org>`_, an advanced Python shell with
+TAB-completion and introspection capabilities.  See below for further
+instructions.
+
+The docstring examples assume that `numpy` has been imported as `np`::
+
+  >>> import numpy as np
+
+Code snippets are indicated by three greater-than signs::
+
+  >>> x = 42
+  >>> x = x + 1
+
+Use the built-in ``help`` function to view a function's docstring::
+
+  >>> help(np.sort)
+  ... # doctest: +SKIP
+
+For some objects, ``np.info(obj)`` may provide additional help.  This is
+particularly true if you see the line "Help on ufunc object:" at the top
+of the help() page.  Ufuncs are implemented in C, not Python, for speed.
+The native Python help() does not know how to view their help, but our
+np.info() function does.
+
+To search for documents containing a keyword, do::
+
+  >>> np.lookfor('keyword')
+  ... # doctest: +SKIP
+
+General-purpose documents like a glossary and help on the basic concepts
+of numpy are available under the ``doc`` sub-module::
+
+  >>> from numpy import doc
+  >>> help(doc)
+  ... # doctest: +SKIP
+
+Available subpackages
+---------------------
+doc
+    Topical documentation on broadcasting, indexing, etc.
+lib
+    Basic functions used by several sub-packages.
+random
+    Core Random Tools
+linalg
+    Core Linear Algebra Tools
+fft
+    Core FFT routines
+polynomial
+    Polynomial tools
+testing
+    Numpy testing tools
+f2py
+    Fortran to Python Interface Generator.
+distutils
+    Enhancements to distutils with support for
+    Fortran compilers support and more.
+
+Utilities
+---------
+test
+    Run numpy unittests
+show_config
+    Show numpy build configuration
+dual
+    Overwrite certain functions with high-performance Scipy tools
+matlib
+    Make everything matrices.
+__version__
+    Numpy version string
+
+Viewing documentation using IPython
+-----------------------------------
+Start IPython with the NumPy profile (``ipython -p numpy``), which will
+import `numpy` under the alias `np`.  Then, use the ``cpaste`` command to
+paste examples into the shell.  To see which functions are available in
+`numpy`, type ``np.<TAB>`` (where ``<TAB>`` refers to the TAB key), or use
+``np.*cos*?<ENTER>`` (where ``<ENTER>`` refers to the ENTER key) to narrow
+down the list.  To view the docstring for a function, use
+``np.cos?<ENTER>`` (to view the docstring) and ``np.cos??<ENTER>`` (to view
+the source code).
+
+Copies vs. in-place operation
+-----------------------------
+Most of the functions in `numpy` return a copy of the array argument
+(e.g., `np.sort`).  In-place versions of these functions are often
+available as array methods, i.e. ``x = np.array([1,2,3]); x.sort()``.
+Exceptions to this rule are documented.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+
+class ModuleDeprecationWarning(DeprecationWarning):
+    """Module deprecation warning.
+
+    The nose tester turns ordinary Deprecation warnings into test failures.
+    That makes it hard to deprecate whole modules, because they get
+    imported by default. So this is a special Deprecation warning that the
+    nose tester will let pass without making tests fail.
+
+    """
+    pass
+
+
+class VisibleDeprecationWarning(UserWarning):
+    """Visible deprecation warning.
+
+    By default, python will not show deprecation warnings, so this class
+    can be used when a very visible warning is helpful, for example because
+    the usage is most likely a user bug.
+
+    """
+    pass
+
+
+class _NoValue:
+    """Special keyword value.
+
+    This class may be used as the default value assigned to a
+    deprecated keyword in order to check if it has been given a user
+    defined value.
+    """
+    pass
+
+
+# oldnumeric and numarray were removed in 1.9. In case some packages import
+# but do not use them, we define them here for backward compatibility.
+oldnumeric = 'removed'
+numarray = 'removed'
+
+
+# We first need to detect if we're being called as part of the numpy setup
+# procedure itself in a reliable manner.
+try:
+    __NUMPY_SETUP__
+except NameError:
+    __NUMPY_SETUP__ = False
+
+
+if __NUMPY_SETUP__:
+    import sys as _sys
+    _sys.stderr.write('Running from numpy source directory.\n')
+    del _sys
+else:
+    try:
+        from numpy.__config__ import show as show_config
+    except ImportError:
+        msg = """Error importing numpy: you should not try to import numpy from
+        its source directory; please exit the numpy source tree, and relaunch
+        your python interpreter from there."""
+        raise ImportError(msg)
+    from .version import git_revision as __git_revision__
+    from .version import version as __version__
+
+    from ._import_tools import PackageLoader
+
+    def pkgload(*packages, **options):
+        loader = PackageLoader(infunc=True)
+        return loader(*packages, **options)
+
+    from . import add_newdocs
+    __all__ = ['add_newdocs',
+               'ModuleDeprecationWarning',
+               'VisibleDeprecationWarning']
+
+    pkgload.__doc__ = PackageLoader.__call__.__doc__
+
+    # We don't actually use this ourselves anymore, but I'm not 100% sure that
+    # no-one else in the world is using it (though I hope not)
+    from .testing import Tester
+    test = testing.nosetester._numpy_tester().test
+    bench = testing.nosetester._numpy_tester().bench
+
+    from . import core
+    from .core import *
+    from . import compat
+    from . import lib
+    from .lib import *
+    from . import linalg
+    from . import fft
+    from . import polynomial
+    from . import random
+    from . import ctypeslib
+    from . import ma
+    from . import matrixlib as _mat
+    from .matrixlib import *
+    from .compat import long
+
+    # Make these accessible from numpy name-space
+    #  but not imported in from numpy import *
+    if sys.version_info[0] >= 3:
+        from builtins import bool, int, float, complex, object, str
+        unicode = str
+    else:
+        from __builtin__ import bool, int, float, complex, object, unicode, str
+
+    from .core import round, abs, max, min
+
+    __all__.extend(['__version__', 'pkgload', 'PackageLoader',
+               'show_config'])
+    __all__.extend(core.__all__)
+    __all__.extend(_mat.__all__)
+    __all__.extend(lib.__all__)
+    __all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma'])
+
+    # Filter annoying Cython warnings that serve no good purpose.
+    import warnings
+    warnings.filterwarnings("ignore", message="numpy.dtype size changed")
+    warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
+    warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/_import_tools.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/_import_tools.py
new file mode 100644
index 0000000000..0d11d699cf
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/_import_tools.py
@@ -0,0 +1,353 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import warnings
+
+__all__ = ['PackageLoader']
+
+class PackageLoader(object):
+    def __init__(self, verbose=False, infunc=False):
+        """ Manages loading packages.
+        """
+
+        if infunc:
+            _level = 2
+        else:
+            _level = 1
+        self.parent_frame = frame = sys._getframe(_level)
+        self.parent_name = eval('__name__', frame.f_globals, frame.f_locals)
+        parent_path = eval('__path__', frame.f_globals, frame.f_locals)
+        if isinstance(parent_path, str):
+            parent_path = [parent_path]
+        self.parent_path = parent_path
+        if '__all__' not in frame.f_locals:
+            exec('__all__ = []', frame.f_globals, frame.f_locals)
+        self.parent_export_names = eval('__all__', frame.f_globals, frame.f_locals)
+
+        self.info_modules = {}
+        self.imported_packages = []
+        self.verbose = None
+
+    def _get_info_files(self, package_dir, parent_path, parent_package=None):
+        """ Return list of (package name,info.py file) from parent_path subdirectories.
+        """
+        from glob import glob
+        files = glob(os.path.join(parent_path, package_dir, 'info.py'))
+        for info_file in glob(os.path.join(parent_path, package_dir, 'info.pyc')):
+            if info_file[:-1] not in files:
+                files.append(info_file)
+        info_files = []
+        for info_file in files:
+            package_name = os.path.dirname(info_file[len(parent_path)+1:])\
+                           .replace(os.sep, '.')
+            if parent_package:
+                package_name = parent_package + '.' + package_name
+            info_files.append((package_name, info_file))
+            info_files.extend(self._get_info_files('*',
+                                                   os.path.dirname(info_file),
+                                                   package_name))
+        return info_files
+
+    def _init_info_modules(self, packages=None):
+        """Initialize info_modules = {<package_name>: <package info.py module>}.
+        """
+        import imp
+        info_files = []
+        info_modules = self.info_modules
+
+        if packages is None:
+            for path in self.parent_path:
+                info_files.extend(self._get_info_files('*', path))
+        else:
+            for package_name in packages:
+                package_dir = os.path.join(*package_name.split('.'))
+                for path in self.parent_path:
+                    names_files = self._get_info_files(package_dir, path)
+                    if names_files:
+                        info_files.extend(names_files)
+                        break
+                else:
+                    try:
+                        exec('import %s.info as info' % (package_name))
+                        info_modules[package_name] = info
+                    except ImportError as msg:
+                        self.warn('No scipy-style subpackage %r found in %s. '\
+                                  'Ignoring: %s'\
+                                  % (package_name, ':'.join(self.parent_path), msg))
+
+        for package_name, info_file in info_files:
+            if package_name in info_modules:
+                continue
+            fullname = self.parent_name +'.'+ package_name
+            if info_file[-1]=='c':
+                filedescriptor = ('.pyc', 'rb', 2)
+            else:
+                filedescriptor = ('.py', 'U', 1)
+
+            try:
+                info_module = imp.load_module(fullname+'.info',
+                                              open(info_file, filedescriptor[1]),
+                                              info_file,
+                                              filedescriptor)
+            except Exception as msg:
+                self.error(msg)
+                info_module = None
+
+            if info_module is None or getattr(info_module, 'ignore', False):
+                info_modules.pop(package_name, None)
+            else:
+                self._init_info_modules(getattr(info_module, 'depends', []))
+                info_modules[package_name] = info_module
+
+        return
+
+    def _get_sorted_names(self):
+        """ Return package names sorted in the order as they should be
+        imported due to dependence relations between packages.
+        """
+
+        depend_dict = {}
+        for name, info_module in self.info_modules.items():
+            depend_dict[name] = getattr(info_module, 'depends', [])
+        package_names = []
+
+        for name in list(depend_dict.keys()):
+            if not depend_dict[name]:
+                package_names.append(name)
+                del depend_dict[name]
+
+        while depend_dict:
+            for name, lst in list(depend_dict.items()):
+                new_lst = [n for n in lst if n in depend_dict]
+                if not new_lst:
+                    package_names.append(name)
+                    del depend_dict[name]
+                else:
+                    depend_dict[name] = new_lst
+
+        return package_names
+
+    def __call__(self,*packages, **options):
+        """Load one or more packages into parent package top-level namespace.
+
+       This function is intended to shorten the need to import many
+       subpackages, say of scipy, constantly with statements such as
+
+         import scipy.linalg, scipy.fftpack, scipy.etc...
+
+       Instead, you can say:
+
+         import scipy
+         scipy.pkgload('linalg','fftpack',...)
+
+       or
+
+         scipy.pkgload()
+
+       to load all of them in one call.
+
+       If a name which doesn't exist in scipy's namespace is
+       given, a warning is shown.
+
+       Parameters
+       ----------
+        *packages : arg-tuple
+             the names (one or more strings) of all the modules one
+             wishes to load into the top-level namespace.
+        verbose= : integer
+             verbosity level [default: -1].
+             verbose=-1 will suspend also warnings.
+        force= : bool
+             when True, force reloading loaded packages [default: False].
+        postpone= : bool
+             when True, don't load packages [default: False]
+
+        """
+        # 2014-10-29, 1.10
+        warnings.warn('pkgload and PackageLoader are obsolete '
+                'and will be removed in a future version of numpy',
+                DeprecationWarning)
+        frame = self.parent_frame
+        self.info_modules = {}
+        if options.get('force', False):
+            self.imported_packages = []
+        self.verbose = verbose = options.get('verbose', -1)
+        postpone = options.get('postpone', None)
+        self._init_info_modules(packages or None)
+
+        self.log('Imports to %r namespace\n----------------------------'\
+                 % self.parent_name)
+
+        for package_name in self._get_sorted_names():
+            if package_name in self.imported_packages:
+                continue
+            info_module = self.info_modules[package_name]
+            global_symbols = getattr(info_module, 'global_symbols', [])
+            postpone_import = getattr(info_module, 'postpone_import', False)
+            if (postpone and not global_symbols) \
+                   or (postpone_import and postpone is not None):
+                continue
+
+            old_object = frame.f_locals.get(package_name, None)
+
+            cmdstr = 'import '+package_name
+            if self._execcmd(cmdstr):
+                continue
+            self.imported_packages.append(package_name)
+
+            if verbose!=-1:
+                new_object = frame.f_locals.get(package_name)
+                if old_object is not None and old_object is not new_object:
+                    self.warn('Overwriting %s=%s (was %s)' \
+                              % (package_name, self._obj2repr(new_object),
+                                 self._obj2repr(old_object)))
+
+            if '.' not in package_name:
+                self.parent_export_names.append(package_name)
+
+            for symbol in global_symbols:
+                if symbol=='*':
+                    symbols = eval('getattr(%s,"__all__",None)'\
+                                   % (package_name),
+                                   frame.f_globals, frame.f_locals)
+                    if symbols is None:
+                        symbols = eval('dir(%s)' % (package_name),
+                                       frame.f_globals, frame.f_locals)
+                        symbols = [s for s in symbols if not s.startswith('_')]
+                else:
+                    symbols = [symbol]
+
+                if verbose!=-1:
+                    old_objects = {}
+                    for s in symbols:
+                        if s in frame.f_locals:
+                            old_objects[s] = frame.f_locals[s]
+
+                cmdstr = 'from '+package_name+' import '+symbol
+                if self._execcmd(cmdstr):
+                    continue
+
+                if verbose!=-1:
+                    for s, old_object in old_objects.items():
+                        new_object = frame.f_locals[s]
+                        if new_object is not old_object:
+                            self.warn('Overwriting %s=%s (was %s)' \
+                                      % (s, self._obj2repr(new_object),
+                                         self._obj2repr(old_object)))
+
+                if symbol=='*':
+                    self.parent_export_names.extend(symbols)
+                else:
+                    self.parent_export_names.append(symbol)
+
+        return
+
+    def _execcmd(self, cmdstr):
+        """ Execute command in parent_frame."""
+        frame = self.parent_frame
+        try:
+            exec (cmdstr, frame.f_globals, frame.f_locals)
+        except Exception as msg:
+            self.error('%s -> failed: %s' % (cmdstr, msg))
+            return True
+        else:
+            self.log('%s -> success' % (cmdstr))
+        return
+
+    def _obj2repr(self, obj):
+        """ Return repr(obj) with"""
+        module = getattr(obj, '__module__', None)
+        file = getattr(obj, '__file__', None)
+        if module is not None:
+            return repr(obj) + ' from ' + module
+        if file is not None:
+            return repr(obj) + ' from ' + file
+        return repr(obj)
+
+    def log(self, mess):
+        if self.verbose>1:
+            print(str(mess), file=sys.stderr)
+    def warn(self, mess):
+        if self.verbose>=0:
+            print(str(mess), file=sys.stderr)
+    def error(self, mess):
+        if self.verbose!=-1:
+            print(str(mess), file=sys.stderr)
+
+    def _get_doc_title(self, info_module):
+        """ Get the title from a package info.py file.
+        """
+        title = getattr(info_module, '__doc_title__', None)
+        if title is not None:
+            return title
+        title = getattr(info_module, '__doc__', None)
+        if title is not None:
+            title = title.lstrip().split('\n', 1)[0]
+            return title
+        return '* Not Available *'
+
+    def _format_titles(self,titles,colsep='---'):
+        display_window_width = 70 # How to determine the correct value in runtime??
+        lengths = [len(name)-name.find('.')-1 for (name, title) in titles]+[0]
+        max_length = max(lengths)
+        lines = []
+        for (name, title) in titles:
+            name = name[name.find('.')+1:]
+            w = max_length - len(name)
+            words = title.split()
+            line = '%s%s %s' % (name, w*' ', colsep)
+            tab = len(line) * ' '
+            while words:
+                word = words.pop(0)
+                if len(line)+len(word)>display_window_width:
+                    lines.append(line)
+                    line = tab
+                line += ' ' + word
+            else:
+                lines.append(line)
+        return '\n'.join(lines)
+
+    def get_pkgdocs(self):
+        """ Return documentation summary of subpackages.
+        """
+        import sys
+        self.info_modules = {}
+        self._init_info_modules(None)
+
+        titles = []
+        symbols = []
+        for package_name, info_module in self.info_modules.items():
+            global_symbols = getattr(info_module, 'global_symbols', [])
+            fullname = self.parent_name +'.'+ package_name
+            note = ''
+            if fullname not in sys.modules:
+                note = ' [*]'
+            titles.append((fullname, self._get_doc_title(info_module) + note))
+            if global_symbols:
+                symbols.append((package_name, ', '.join(global_symbols)))
+
+        retstr = self._format_titles(titles) +\
+               '\n  [*] - using a package requires explicit import (see pkgload)'
+
+
+        if symbols:
+            retstr += """\n\nGlobal symbols from subpackages"""\
+                      """\n-------------------------------\n""" +\
+                      self._format_titles(symbols, '-->')
+
+        return retstr
+
+class PackageLoaderDebug(PackageLoader):
+    def _execcmd(self, cmdstr):
+        """ Execute command in parent_frame."""
+        frame = self.parent_frame
+        print('Executing', repr(cmdstr), '...', end=' ')
+        sys.stdout.flush()
+        exec (cmdstr, frame.f_globals, frame.f_locals)
+        print('ok')
+        sys.stdout.flush()
+        return
+
+if int(os.environ.get('NUMPY_IMPORT_DEBUG', '0')):
+    PackageLoader = PackageLoaderDebug
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/add_newdocs.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/add_newdocs.py
new file mode 100644
index 0000000000..8940f537d5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/add_newdocs.py
@@ -0,0 +1,7671 @@
+"""
+This is only meant to add docs to objects defined in C-extension modules.
+The purpose is to allow easier editing of the docstrings without
+requiring a re-compile.
+
+NOTE: Many of the methods of ndarray have corresponding functions.
+      If you update these docstrings, please keep also the ones in
+      core/fromnumeric.py, core/defmatrix.py up-to-date.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.lib import add_newdoc
+
+###############################################################################
+#
+# flatiter
+#
+# flatiter needs a toplevel description
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'flatiter',
+    """
+    Flat iterator object to iterate over arrays.
+
+    A `flatiter` iterator is returned by ``x.flat`` for any array `x`.
+    It allows iterating over the array as if it were a 1-D array,
+    either in a for-loop or by calling its `next` method.
+
+    Iteration is done in row-major, C-style order (the last
+    index varying the fastest). The iterator can also be indexed using
+    basic slicing or advanced indexing.
+
+    See Also
+    --------
+    ndarray.flat : Return a flat iterator over an array.
+    ndarray.flatten : Returns a flattened copy of an array.
+
+    Notes
+    -----
+    A `flatiter` iterator can not be constructed directly from Python code
+    by calling the `flatiter` constructor.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> type(fl)
+    <type 'numpy.flatiter'>
+    >>> for item in fl:
+    ...     print(item)
+    ...
+    0
+    1
+    2
+    3
+    4
+    5
+
+    >>> fl[2:4]
+    array([2, 3])
+
+    """)
+
+# flatiter attributes
+
+add_newdoc('numpy.core', 'flatiter', ('base',
+    """
+    A reference to the array that is iterated over.
+
+    Examples
+    --------
+    >>> x = np.arange(5)
+    >>> fl = x.flat
+    >>> fl.base is x
+    True
+
+    """))
+
+
+
+add_newdoc('numpy.core', 'flatiter', ('coords',
+    """
+    An N-dimensional tuple of current coordinates.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> fl.coords
+    (0, 0)
+    >>> fl.next()
+    0
+    >>> fl.coords
+    (0, 1)
+
+    """))
+
+
+
+add_newdoc('numpy.core', 'flatiter', ('index',
+    """
+    Current flat index into the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> fl.index
+    0
+    >>> fl.next()
+    0
+    >>> fl.index
+    1
+
+    """))
+
+# flatiter functions
+
+add_newdoc('numpy.core', 'flatiter', ('__array__',
+    """__array__(type=None) Get array from iterator
+
+    """))
+
+
+add_newdoc('numpy.core', 'flatiter', ('copy',
+    """
+    copy()
+
+    Get a copy of the iterator as a 1-D array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> fl = x.flat
+    >>> fl.copy()
+    array([0, 1, 2, 3, 4, 5])
+
+    """))
+
+
+###############################################################################
+#
+# nditer
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'nditer',
+    """
+    Efficient multi-dimensional iterator object to iterate over arrays.
+    To get started using this object, see the
+    :ref:`introductory guide to array iteration <arrays.nditer>`.
+
+    Parameters
+    ----------
+    op : ndarray or sequence of array_like
+        The array(s) to iterate over.
+    flags : sequence of str, optional
+        Flags to control the behavior of the iterator.
+
+          * "buffered" enables buffering when required.
+          * "c_index" causes a C-order index to be tracked.
+          * "f_index" causes a Fortran-order index to be tracked.
+          * "multi_index" causes a multi-index, or a tuple of indices
+            with one per iteration dimension, to be tracked.
+          * "common_dtype" causes all the operands to be converted to
+            a common data type, with copying or buffering as necessary.
+          * "delay_bufalloc" delays allocation of the buffers until
+            a reset() call is made. Allows "allocate" operands to
+            be initialized before their values are copied into the buffers.
+          * "external_loop" causes the `values` given to be
+            one-dimensional arrays with multiple values instead of
+            zero-dimensional arrays.
+          * "grow_inner" allows the `value` array sizes to be made
+            larger than the buffer size when both "buffered" and
+            "external_loop" is used.
+          * "ranged" allows the iterator to be restricted to a sub-range
+            of the iterindex values.
+          * "refs_ok" enables iteration of reference types, such as
+            object arrays.
+          * "reduce_ok" enables iteration of "readwrite" operands
+            which are broadcasted, also known as reduction operands.
+          * "zerosize_ok" allows `itersize` to be zero.
+    op_flags : list of list of str, optional
+        This is a list of flags for each operand. At minimum, one of
+        "readonly", "readwrite", or "writeonly" must be specified.
+
+          * "readonly" indicates the operand will only be read from.
+          * "readwrite" indicates the operand will be read from and written to.
+          * "writeonly" indicates the operand will only be written to.
+          * "no_broadcast" prevents the operand from being broadcasted.
+          * "contig" forces the operand data to be contiguous.
+          * "aligned" forces the operand data to be aligned.
+          * "nbo" forces the operand data to be in native byte order.
+          * "copy" allows a temporary read-only copy if required.
+          * "updateifcopy" allows a temporary read-write copy if required.
+          * "allocate" causes the array to be allocated if it is None
+            in the `op` parameter.
+          * "no_subtype" prevents an "allocate" operand from using a subtype.
+          * "arraymask" indicates that this operand is the mask to use
+            for selecting elements when writing to operands with the
+            'writemasked' flag set. The iterator does not enforce this,
+            but when writing from a buffer back to the array, it only
+            copies those elements indicated by this mask.
+          * 'writemasked' indicates that only elements where the chosen
+            'arraymask' operand is True will be written to.
+    op_dtypes : dtype or tuple of dtype(s), optional
+        The required data type(s) of the operands. If copying or buffering
+        is enabled, the data will be converted to/from their original types.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the iteration order. 'C' means C order, 'F' means
+        Fortran order, 'A' means 'F' order if all the arrays are Fortran
+        contiguous, 'C' order otherwise, and 'K' means as close to the
+        order the array elements appear in memory as possible. This also
+        affects the element memory order of "allocate" operands, as they
+        are allocated to be compatible with iteration order.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur when making a copy
+        or buffering.  Setting this to 'unsafe' is not recommended,
+        as it can adversely affect accumulations.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    op_axes : list of list of ints, optional
+        If provided, is a list of ints or None for each operands.
+        The list of axes for an operand is a mapping from the dimensions
+        of the iterator to the dimensions of the operand. A value of
+        -1 can be placed for entries, causing that dimension to be
+        treated as "newaxis".
+    itershape : tuple of ints, optional
+        The desired shape of the iterator. This allows "allocate" operands
+        with a dimension mapped by op_axes not corresponding to a dimension
+        of a different operand to get a value not equal to 1 for that
+        dimension.
+    buffersize : int, optional
+        When buffering is enabled, controls the size of the temporary
+        buffers. Set to 0 for the default value.
+
+    Attributes
+    ----------
+    dtypes : tuple of dtype(s)
+        The data types of the values provided in `value`. This may be
+        different from the operand data types if buffering is enabled.
+    finished : bool
+        Whether the iteration over the operands is finished or not.
+    has_delayed_bufalloc : bool
+        If True, the iterator was created with the "delay_bufalloc" flag,
+        and no reset() function was called on it yet.
+    has_index : bool
+        If True, the iterator was created with either the "c_index" or
+        the "f_index" flag, and the property `index` can be used to
+        retrieve it.
+    has_multi_index : bool
+        If True, the iterator was created with the "multi_index" flag,
+        and the property `multi_index` can be used to retrieve it.
+    index :
+        When the "c_index" or "f_index" flag was used, this property
+        provides access to the index. Raises a ValueError if accessed
+        and `has_index` is False.
+    iterationneedsapi : bool
+        Whether iteration requires access to the Python API, for example
+        if one of the operands is an object array.
+    iterindex : int
+        An index which matches the order of iteration.
+    itersize : int
+        Size of the iterator.
+    itviews :
+        Structured view(s) of `operands` in memory, matching the reordered
+        and optimized iterator access pattern.
+    multi_index :
+        When the "multi_index" flag was used, this property
+        provides access to the index. Raises a ValueError if accessed
+        accessed and `has_multi_index` is False.
+    ndim : int
+        The iterator's dimension.
+    nop : int
+        The number of iterator operands.
+    operands : tuple of operand(s)
+        The array(s) to be iterated over.
+    shape : tuple of ints
+        Shape tuple, the shape of the iterator.
+    value :
+        Value of `operands` at current iteration. Normally, this is a
+        tuple of array scalars, but if the flag "external_loop" is used,
+        it is a tuple of one dimensional arrays.
+
+    Notes
+    -----
+    `nditer` supersedes `flatiter`.  The iterator implementation behind
+    `nditer` is also exposed by the Numpy C API.
+
+    The Python exposure supplies two iteration interfaces, one which follows
+    the Python iterator protocol, and another which mirrors the C-style
+    do-while pattern.  The native Python approach is better in most cases, but
+    if you need the iterator's coordinates or index, use the C-style pattern.
+
+    Examples
+    --------
+    Here is how we might write an ``iter_add`` function, using the
+    Python iterator protocol::
+
+        def iter_add_py(x, y, out=None):
+            addop = np.add
+            it = np.nditer([x, y, out], [],
+                        [['readonly'], ['readonly'], ['writeonly','allocate']])
+            for (a, b, c) in it:
+                addop(a, b, out=c)
+            return it.operands[2]
+
+    Here is the same function, but following the C-style pattern::
+
+        def iter_add(x, y, out=None):
+            addop = np.add
+
+            it = np.nditer([x, y, out], [],
+                        [['readonly'], ['readonly'], ['writeonly','allocate']])
+
+            while not it.finished:
+                addop(it[0], it[1], out=it[2])
+                it.iternext()
+
+            return it.operands[2]
+
+    Here is an example outer product function::
+
+        def outer_it(x, y, out=None):
+            mulop = np.multiply
+
+            it = np.nditer([x, y, out], ['external_loop'],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']],
+                    op_axes=[range(x.ndim)+[-1]*y.ndim,
+                             [-1]*x.ndim+range(y.ndim),
+                             None])
+
+            for (a, b, c) in it:
+                mulop(a, b, out=c)
+
+            return it.operands[2]
+
+        >>> a = np.arange(2)+1
+        >>> b = np.arange(3)+1
+        >>> outer_it(a,b)
+        array([[1, 2, 3],
+               [2, 4, 6]])
+
+    Here is an example function which operates like a "lambda" ufunc::
+
+        def luf(lamdaexpr, *args, **kwargs):
+            "luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)"
+            nargs = len(args)
+            op = (kwargs.get('out',None),) + args
+            it = np.nditer(op, ['buffered','external_loop'],
+                    [['writeonly','allocate','no_broadcast']] +
+                                    [['readonly','nbo','aligned']]*nargs,
+                    order=kwargs.get('order','K'),
+                    casting=kwargs.get('casting','safe'),
+                    buffersize=kwargs.get('buffersize',0))
+            while not it.finished:
+                it[0] = lamdaexpr(*it[1:])
+                it.iternext()
+            return it.operands[0]
+
+        >>> a = np.arange(5)
+        >>> b = np.ones(5)
+        >>> luf(lambda i,j:i*i + j/2, a, b)
+        array([  0.5,   1.5,   4.5,   9.5,  16.5])
+
+    """)
+
+# nditer methods
+
+add_newdoc('numpy.core', 'nditer', ('copy',
+    """
+    copy()
+
+    Get a copy of the iterator in its current state.
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> y = x + 1
+    >>> it = np.nditer([x, y])
+    >>> it.next()
+    (array(0), array(1))
+    >>> it2 = it.copy()
+    >>> it2.next()
+    (array(1), array(2))
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('debug_print',
+    """
+    debug_print()
+
+    Print the current state of the `nditer` instance and debug info to stdout.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('enable_external_loop',
+    """
+    enable_external_loop()
+
+    When the "external_loop" was not used during construction, but
+    is desired, this modifies the iterator to behave as if the flag
+    was specified.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('iternext',
+    """
+    iternext()
+
+    Check whether iterations are left, and perform a single internal iteration
+    without returning the result.  Used in the C-style pattern do-while
+    pattern.  For an example, see `nditer`.
+
+    Returns
+    -------
+    iternext : bool
+        Whether or not there are iterations left.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('remove_axis',
+    """
+    remove_axis(i)
+
+    Removes axis `i` from the iterator. Requires that the flag "multi_index"
+    be enabled.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('remove_multi_index',
+    """
+    remove_multi_index()
+
+    When the "multi_index" flag was specified, this removes it, allowing
+    the internal iteration structure to be optimized further.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('reset',
+    """
+    reset()
+
+    Reset the iterator to its initial state.
+
+    """))
+
+
+
+###############################################################################
+#
+# broadcast
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'broadcast',
+    """
+    Produce an object that mimics broadcasting.
+
+    Parameters
+    ----------
+    in1, in2, ... : array_like
+        Input parameters.
+
+    Returns
+    -------
+    b : broadcast object
+        Broadcast the input parameters against one another, and
+        return an object that encapsulates the result.
+        Amongst others, it has ``shape`` and ``nd`` properties, and
+        may be used as an iterator.
+
+    Examples
+    --------
+    Manually adding two vectors, using broadcasting:
+
+    >>> x = np.array([[1], [2], [3]])
+    >>> y = np.array([4, 5, 6])
+    >>> b = np.broadcast(x, y)
+
+    >>> out = np.empty(b.shape)
+    >>> out.flat = [u+v for (u,v) in b]
+    >>> out
+    array([[ 5.,  6.,  7.],
+           [ 6.,  7.,  8.],
+           [ 7.,  8.,  9.]])
+
+    Compare against built-in broadcasting:
+
+    >>> x + y
+    array([[5, 6, 7],
+           [6, 7, 8],
+           [7, 8, 9]])
+
+    """)
+
+# attributes
+
+add_newdoc('numpy.core', 'broadcast', ('index',
+    """
+    current index in broadcasted result
+
+    Examples
+    --------
+    >>> x = np.array([[1], [2], [3]])
+    >>> y = np.array([4, 5, 6])
+    >>> b = np.broadcast(x, y)
+    >>> b.index
+    0
+    >>> b.next(), b.next(), b.next()
+    ((1, 4), (1, 5), (1, 6))
+    >>> b.index
+    3
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('iters',
+    """
+    tuple of iterators along ``self``'s "components."
+
+    Returns a tuple of `numpy.flatiter` objects, one for each "component"
+    of ``self``.
+
+    See Also
+    --------
+    numpy.flatiter
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> row, col = b.iters
+    >>> row.next(), col.next()
+    (1, 4)
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('nd',
+    """
+    Number of dimensions of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.nd
+    2
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('numiter',
+    """
+    Number of iterators possessed by the broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.numiter
+    2
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('shape',
+    """
+    Shape of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.shape
+    (3, 3)
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('size',
+    """
+    Total size of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.size
+    9
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('reset',
+    """
+    reset()
+
+    Reset the broadcasted result's iterator(s).
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    None
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]]
+    >>> b = np.broadcast(x, y)
+    >>> b.index
+    0
+    >>> b.next(), b.next(), b.next()
+    ((1, 4), (2, 4), (3, 4))
+    >>> b.index
+    3
+    >>> b.reset()
+    >>> b.index
+    0
+
+    """))
+
+###############################################################################
+#
+# numpy functions
+#
+###############################################################################
+
+add_newdoc('numpy.core.multiarray', 'array',
+    """
+    array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
+
+    Create an array.
+
+    Parameters
+    ----------
+    object : array_like
+        An array, any object exposing the array interface, an
+        object whose __array__ method returns an array, or any
+        (nested) sequence.
+    dtype : data-type, optional
+        The desired data-type for the array.  If not given, then
+        the type will be determined as the minimum type required
+        to hold the objects in the sequence.  This argument can only
+        be used to 'upcast' the array.  For downcasting, use the
+        .astype(t) method.
+    copy : bool, optional
+        If true (default), then the object is copied.  Otherwise, a copy
+        will only be made if __array__ returns a copy, if obj is a
+        nested sequence, or if a copy is needed to satisfy any of the other
+        requirements (`dtype`, `order`, etc.).
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C', then the array
+        will be in C-contiguous order (last-index varies the fastest).
+        If order is 'F', then the returned array will be in
+        Fortran-contiguous order (first-index varies the fastest).
+        If order is 'A' (default), then the returned array may be
+        in any order (either C-, Fortran-contiguous, or even discontiguous),
+        unless a copy is required, in which case it will be C-contiguous.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned array will be forced to be a base-class array (default).
+    ndmin : int, optional
+        Specifies the minimum number of dimensions that the resulting
+        array should have.  Ones will be pre-pended to the shape as
+        needed to meet this requirement.
+
+    Returns
+    -------
+    out : ndarray
+        An array object satisfying the specified requirements.
+
+    See Also
+    --------
+    empty, empty_like, zeros, zeros_like, ones, ones_like, fill
+
+    Examples
+    --------
+    >>> np.array([1, 2, 3])
+    array([1, 2, 3])
+
+    Upcasting:
+
+    >>> np.array([1, 2, 3.0])
+    array([ 1.,  2.,  3.])
+
+    More than one dimension:
+
+    >>> np.array([[1, 2], [3, 4]])
+    array([[1, 2],
+           [3, 4]])
+
+    Minimum dimensions 2:
+
+    >>> np.array([1, 2, 3], ndmin=2)
+    array([[1, 2, 3]])
+
+    Type provided:
+
+    >>> np.array([1, 2, 3], dtype=complex)
+    array([ 1.+0.j,  2.+0.j,  3.+0.j])
+
+    Data-type consisting of more than one element:
+
+    >>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
+    >>> x['a']
+    array([1, 3])
+
+    Creating an array from sub-classes:
+
+    >>> np.array(np.mat('1 2; 3 4'))
+    array([[1, 2],
+           [3, 4]])
+
+    >>> np.array(np.mat('1 2; 3 4'), subok=True)
+    matrix([[1, 2],
+            [3, 4]])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'empty',
+    """
+    empty(shape, dtype=float, order='C')
+
+    Return a new array of given shape and type, without initializing entries.
+
+    Parameters
+    ----------
+    shape : int or tuple of int
+        Shape of the empty array
+    dtype : data-type, optional
+        Desired output data-type.
+    order : {'C', 'F'}, optional
+        Whether to store multi-dimensional data in row-major
+        (C-style) or column-major (Fortran-style) order in
+        memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of uninitialized (arbitrary) data of the given shape, dtype, and
+        order.  Object arrays will be initialized to None.
+
+    See Also
+    --------
+    empty_like, zeros, ones
+
+    Notes
+    -----
+    `empty`, unlike `zeros`, does not set the array values to zero,
+    and may therefore be marginally faster.  On the other hand, it requires
+    the user to manually set all the values in the array, and should be
+    used with caution.
+
+    Examples
+    --------
+    >>> np.empty([2, 2])
+    array([[ -9.74499359e+001,   6.69583040e-309],
+           [  2.13182611e-314,   3.06959433e-309]])         #random
+
+    >>> np.empty([2, 2], dtype=int)
+    array([[-1073741821, -1067949133],
+           [  496041986,    19249760]])                     #random
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'empty_like',
+    """
+    empty_like(a, dtype=None, order='K', subok=True)
+
+    Return a new array with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of the
+        returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if ``a`` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of ``a`` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of uninitialized (arbitrary) data with the same
+        shape and type as `a`.
+
+    See Also
+    --------
+    ones_like : Return an array of ones with shape and type of input.
+    zeros_like : Return an array of zeros with shape and type of input.
+    empty : Return a new uninitialized array.
+    ones : Return a new array setting values to one.
+    zeros : Return a new array setting values to zero.
+
+    Notes
+    -----
+    This function does *not* initialize the returned array; to do that use
+    `zeros_like` or `ones_like` instead.  It may be marginally faster than
+    the functions that do set the array values.
+
+    Examples
+    --------
+    >>> a = ([1,2,3], [4,5,6])                         # a is array-like
+    >>> np.empty_like(a)
+    array([[-1073741821, -1073741821,           3],    #random
+           [          0,           0, -1073741821]])
+    >>> a = np.array([[1., 2., 3.],[4.,5.,6.]])
+    >>> np.empty_like(a)
+    array([[ -2.00000715e+000,   1.48219694e-323,  -2.00000572e+000],#random
+           [  4.38791518e-305,  -2.00000715e+000,   4.17269252e-309]])
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'scalar',
+    """
+    scalar(dtype, obj)
+
+    Return a new scalar array of the given type initialized with obj.
+
+    This function is meant mainly for pickle support. `dtype` must be a
+    valid data-type descriptor. If `dtype` corresponds to an object
+    descriptor, then `obj` can be any object, otherwise `obj` must be a
+    string. If `obj` is not given, it will be interpreted as None for object
+    type and as zeros for all other types.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'zeros',
+    """
+    zeros(shape, dtype=float, order='C')
+
+    Return a new array of given shape and type, filled with zeros.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `numpy.int8`.  Default is
+        `numpy.float64`.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of zeros with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> np.zeros(5)
+    array([ 0.,  0.,  0.,  0.,  0.])
+
+    >>> np.zeros((5,), dtype=np.int)
+    array([0, 0, 0, 0, 0])
+
+    >>> np.zeros((2, 1))
+    array([[ 0.],
+           [ 0.]])
+
+    >>> s = (2,2)
+    >>> np.zeros(s)
+    array([[ 0.,  0.],
+           [ 0.,  0.]])
+
+    >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
+    array([(0, 0), (0, 0)],
+          dtype=[('x', '<i4'), ('y', '<i4')])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'count_nonzero',
+    """
+    count_nonzero(a)
+
+    Counts the number of non-zero values in the array ``a``.
+
+    Parameters
+    ----------
+    a : array_like
+        The array for which to count non-zeros.
+
+    Returns
+    -------
+    count : int or array of int
+        Number of non-zero values in the array.
+
+    See Also
+    --------
+    nonzero : Return the coordinates of all the non-zero values.
+
+    Examples
+    --------
+    >>> np.count_nonzero(np.eye(4))
+    4
+    >>> np.count_nonzero([[0,1,7,0,0],[3,0,0,2,19]])
+    5
+    """)
+
+add_newdoc('numpy.core.multiarray', 'set_typeDict',
+    """set_typeDict(dict)
+
+    Set the internal dictionary that can look up an array type using a
+    registered code.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromstring',
+    """
+    fromstring(string, dtype=float, count=-1, sep='')
+
+    A new 1-D array initialized from raw binary or text data in a string.
+
+    Parameters
+    ----------
+    string : str
+        A string containing the data.
+    dtype : data-type, optional
+        The data type of the array; default: float.  For binary input data,
+        the data must be in exactly this format.
+    count : int, optional
+        Read this number of `dtype` elements from the data.  If this is
+        negative (the default), the count will be determined from the
+        length of the data.
+    sep : str, optional
+        If not provided or, equivalently, the empty string, the data will
+        be interpreted as binary data; otherwise, as ASCII text with
+        decimal numbers.  Also in this latter case, this argument is
+        interpreted as the string separating numbers in the data; extra
+        whitespace between elements is also ignored.
+
+    Returns
+    -------
+    arr : ndarray
+        The constructed array.
+
+    Raises
+    ------
+    ValueError
+        If the string is not the correct size to satisfy the requested
+        `dtype` and `count`.
+
+    See Also
+    --------
+    frombuffer, fromfile, fromiter
+
+    Examples
+    --------
+    >>> np.fromstring('\\x01\\x02', dtype=np.uint8)
+    array([1, 2], dtype=uint8)
+    >>> np.fromstring('1 2', dtype=int, sep=' ')
+    array([1, 2])
+    >>> np.fromstring('1, 2', dtype=int, sep=',')
+    array([1, 2])
+    >>> np.fromstring('\\x01\\x02\\x03\\x04\\x05', dtype=np.uint8, count=3)
+    array([1, 2, 3], dtype=uint8)
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromiter',
+    """
+    fromiter(iterable, dtype, count=-1)
+
+    Create a new 1-dimensional array from an iterable object.
+
+    Parameters
+    ----------
+    iterable : iterable object
+        An iterable object providing data for the array.
+    dtype : data-type
+        The data-type of the returned array.
+    count : int, optional
+        The number of items to read from *iterable*.  The default is -1,
+        which means all data is read.
+
+    Returns
+    -------
+    out : ndarray
+        The output array.
+
+    Notes
+    -----
+    Specify `count` to improve performance.  It allows ``fromiter`` to
+    pre-allocate the output array, instead of resizing it on demand.
+
+    Examples
+    --------
+    >>> iterable = (x*x for x in range(5))
+    >>> np.fromiter(iterable, np.float)
+    array([  0.,   1.,   4.,   9.,  16.])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromfile',
+    """
+    fromfile(file, dtype=float, count=-1, sep='')
+
+    Construct an array from data in a text or binary file.
+
+    A highly efficient way of reading binary data with a known data-type,
+    as well as parsing simply formatted text files.  Data written using the
+    `tofile` method can be read using this function.
+
+    Parameters
+    ----------
+    file : file or str
+        Open file object or filename.
+    dtype : data-type
+        Data type of the returned array.
+        For binary files, it is used to determine the size and byte-order
+        of the items in the file.
+    count : int
+        Number of items to read. ``-1`` means all items (i.e., the complete
+        file).
+    sep : str
+        Separator between items if file is a text file.
+        Empty ("") separator means the file should be treated as binary.
+        Spaces (" ") in the separator match zero or more whitespace characters.
+        A separator consisting only of spaces must match at least one
+        whitespace.
+
+    See also
+    --------
+    load, save
+    ndarray.tofile
+    loadtxt : More flexible way of loading data from a text file.
+
+    Notes
+    -----
+    Do not rely on the combination of `tofile` and `fromfile` for
+    data storage, as the binary files generated are are not platform
+    independent.  In particular, no byte-order or data-type information is
+    saved.  Data can be stored in the platform independent ``.npy`` format
+    using `save` and `load` instead.
+
+    Examples
+    --------
+    Construct an ndarray:
+
+    >>> dt = np.dtype([('time', [('min', int), ('sec', int)]),
+    ...                ('temp', float)])
+    >>> x = np.zeros((1,), dtype=dt)
+    >>> x['time']['min'] = 10; x['temp'] = 98.25
+    >>> x
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    Save the raw data to disk:
+
+    >>> import os
+    >>> fname = os.tmpnam()
+    >>> x.tofile(fname)
+
+    Read the raw data from disk:
+
+    >>> np.fromfile(fname, dtype=dt)
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    The recommended way to store and load data:
+
+    >>> np.save(fname, x)
+    >>> np.load(fname + '.npy')
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'frombuffer',
+    """
+    frombuffer(buffer, dtype=float, count=-1, offset=0)
+
+    Interpret a buffer as a 1-dimensional array.
+
+    Parameters
+    ----------
+    buffer : buffer_like
+        An object that exposes the buffer interface.
+    dtype : data-type, optional
+        Data-type of the returned array; default: float.
+    count : int, optional
+        Number of items to read. ``-1`` means all data in the buffer.
+    offset : int, optional
+        Start reading the buffer from this offset; default: 0.
+
+    Notes
+    -----
+    If the buffer has data that is not in machine byte-order, this should
+    be specified as part of the data-type, e.g.::
+
+      >>> dt = np.dtype(int)
+      >>> dt = dt.newbyteorder('>')
+      >>> np.frombuffer(buf, dtype=dt)
+
+    The data of the resulting array will not be byteswapped, but will be
+    interpreted correctly.
+
+    Examples
+    --------
+    >>> s = 'hello world'
+    >>> np.frombuffer(s, dtype='S1', count=5, offset=6)
+    array(['w', 'o', 'r', 'l', 'd'],
+          dtype='|S1')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'concatenate',
+    """
+    concatenate((a1, a2, ...), axis=0)
+
+    Join a sequence of arrays along an existing axis.
+
+    Parameters
+    ----------
+    a1, a2, ... : sequence of array_like
+        The arrays must have the same shape, except in the dimension
+        corresponding to `axis` (the first, by default).
+    axis : int, optional
+        The axis along which the arrays will be joined.  Default is 0.
+
+    Returns
+    -------
+    res : ndarray
+        The concatenated array.
+
+    See Also
+    --------
+    ma.concatenate : Concatenate function that preserves input masks.
+    array_split : Split an array into multiple sub-arrays of equal or
+                  near-equal size.
+    split : Split array into a list of multiple sub-arrays of equal size.
+    hsplit : Split array into multiple sub-arrays horizontally (column wise)
+    vsplit : Split array into multiple sub-arrays vertically (row wise)
+    dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
+    stack : Stack a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise)
+    vstack : Stack arrays in sequence vertically (row wise)
+    dstack : Stack arrays in sequence depth wise (along third dimension)
+
+    Notes
+    -----
+    When one or more of the arrays to be concatenated is a MaskedArray,
+    this function will return a MaskedArray object instead of an ndarray,
+    but the input masks are *not* preserved. In cases where a MaskedArray
+    is expected as input, use the ma.concatenate function from the masked
+    array module instead.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> b = np.array([[5, 6]])
+    >>> np.concatenate((a, b), axis=0)
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    >>> np.concatenate((a, b.T), axis=1)
+    array([[1, 2, 5],
+           [3, 4, 6]])
+
+    This function will not preserve masking of MaskedArray inputs.
+
+    >>> a = np.ma.arange(3)
+    >>> a[1] = np.ma.masked
+    >>> b = np.arange(2, 5)
+    >>> a
+    masked_array(data = [0 -- 2],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> b
+    array([2, 3, 4])
+    >>> np.concatenate([a, b])
+    masked_array(data = [0 1 2 2 3 4],
+                 mask = False,
+           fill_value = 999999)
+    >>> np.ma.concatenate([a, b])
+    masked_array(data = [0 -- 2 2 3 4],
+                 mask = [False  True False False False False],
+           fill_value = 999999)
+
+    """)
+
+add_newdoc('numpy.core', 'inner',
+    """
+    inner(a, b)
+
+    Inner product of two arrays.
+
+    Ordinary inner product of vectors for 1-D arrays (without complex
+    conjugation), in higher dimensions a sum product over the last axes.
+
+    Parameters
+    ----------
+    a, b : array_like
+        If `a` and `b` are nonscalar, their last dimensions must match.
+
+    Returns
+    -------
+    out : ndarray
+        `out.shape = a.shape[:-1] + b.shape[:-1]`
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` and `b` has different size.
+
+    See Also
+    --------
+    tensordot : Sum products over arbitrary axes.
+    dot : Generalised matrix product, using second last dimension of `b`.
+    einsum : Einstein summation convention.
+
+    Notes
+    -----
+    For vectors (1-D arrays) it computes the ordinary inner-product::
+
+        np.inner(a, b) = sum(a[:]*b[:])
+
+    More generally, if `ndim(a) = r > 0` and `ndim(b) = s > 0`::
+
+        np.inner(a, b) = np.tensordot(a, b, axes=(-1,-1))
+
+    or explicitly::
+
+        np.inner(a, b)[i0,...,ir-1,j0,...,js-1]
+             = sum(a[i0,...,ir-1,:]*b[j0,...,js-1,:])
+
+    In addition `a` or `b` may be scalars, in which case::
+
+       np.inner(a,b) = a*b
+
+    Examples
+    --------
+    Ordinary inner product for vectors:
+
+    >>> a = np.array([1,2,3])
+    >>> b = np.array([0,1,0])
+    >>> np.inner(a, b)
+    2
+
+    A multidimensional example:
+
+    >>> a = np.arange(24).reshape((2,3,4))
+    >>> b = np.arange(4)
+    >>> np.inner(a, b)
+    array([[ 14,  38,  62],
+           [ 86, 110, 134]])
+
+    An example where `b` is a scalar:
+
+    >>> np.inner(np.eye(2), 7)
+    array([[ 7.,  0.],
+           [ 0.,  7.]])
+
+    """)
+
+add_newdoc('numpy.core', 'fastCopyAndTranspose',
+    """_fastCopyAndTranspose(a)""")
+
+add_newdoc('numpy.core.multiarray', 'correlate',
+    """cross_correlate(a,v, mode=0)""")
+
+add_newdoc('numpy.core.multiarray', 'arange',
+    """
+    arange([start,] stop[, step,], dtype=None)
+
+    Return evenly spaced values within a given interval.
+
+    Values are generated within the half-open interval ``[start, stop)``
+    (in other words, the interval including `start` but excluding `stop`).
+    For integer arguments the function is equivalent to the Python built-in
+    `range <http://docs.python.org/lib/built-in-funcs.html>`_ function,
+    but returns an ndarray rather than a list.
+
+    When using a non-integer step, such as 0.1, the results will often not
+    be consistent.  It is better to use ``linspace`` for these cases.
+
+    Parameters
+    ----------
+    start : number, optional
+        Start of interval.  The interval includes this value.  The default
+        start value is 0.
+    stop : number
+        End of interval.  The interval does not include this value, except
+        in some cases where `step` is not an integer and floating point
+        round-off affects the length of `out`.
+    step : number, optional
+        Spacing between values.  For any output `out`, this is the distance
+        between two adjacent values, ``out[i+1] - out[i]``.  The default
+        step size is 1.  If `step` is specified, `start` must also be given.
+    dtype : dtype
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+    Returns
+    -------
+    arange : ndarray
+        Array of evenly spaced values.
+
+        For floating point arguments, the length of the result is
+        ``ceil((stop - start)/step)``.  Because of floating point overflow,
+        this rule may result in the last element of `out` being greater
+        than `stop`.
+
+    See Also
+    --------
+    linspace : Evenly spaced numbers with careful handling of endpoints.
+    ogrid: Arrays of evenly spaced numbers in N-dimensions.
+    mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions.
+
+    Examples
+    --------
+    >>> np.arange(3)
+    array([0, 1, 2])
+    >>> np.arange(3.0)
+    array([ 0.,  1.,  2.])
+    >>> np.arange(3,7)
+    array([3, 4, 5, 6])
+    >>> np.arange(3,7,2)
+    array([3, 5])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', '_get_ndarray_c_version',
+    """_get_ndarray_c_version()
+
+    Return the compile time NDARRAY_VERSION number.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', '_reconstruct',
+    """_reconstruct(subtype, shape, dtype)
+
+    Construct an empty array. Used by Pickles.
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'set_string_function',
+    """
+    set_string_function(f, repr=1)
+
+    Internal method to set a function to be used when pretty printing arrays.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'set_numeric_ops',
+    """
+    set_numeric_ops(op1=func1, op2=func2, ...)
+
+    Set numerical operators for array objects.
+
+    Parameters
+    ----------
+    op1, op2, ... : callable
+        Each ``op = func`` pair describes an operator to be replaced.
+        For example, ``add = lambda x, y: np.add(x, y) % 5`` would replace
+        addition by modulus 5 addition.
+
+    Returns
+    -------
+    saved_ops : list of callables
+        A list of all operators, stored before making replacements.
+
+    Notes
+    -----
+    .. WARNING::
+       Use with care!  Incorrect usage may lead to memory errors.
+
+    A function replacing an operator cannot make use of that operator.
+    For example, when replacing add, you may not use ``+``.  Instead,
+    directly call ufuncs.
+
+    Examples
+    --------
+    >>> def add_mod5(x, y):
+    ...     return np.add(x, y) % 5
+    ...
+    >>> old_funcs = np.set_numeric_ops(add=add_mod5)
+
+    >>> x = np.arange(12).reshape((3, 4))
+    >>> x + x
+    array([[0, 2, 4, 1],
+           [3, 0, 2, 4],
+           [1, 3, 0, 2]])
+
+    >>> ignore = np.set_numeric_ops(**old_funcs) # restore operators
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'where',
+    """
+    where(condition, [x, y])
+
+    Return elements, either from `x` or `y`, depending on `condition`.
+
+    If only `condition` is given, return ``condition.nonzero()``.
+
+    Parameters
+    ----------
+    condition : array_like, bool
+        When True, yield `x`, otherwise yield `y`.
+    x, y : array_like, optional
+        Values from which to choose. `x` and `y` need to have the same
+        shape as `condition`.
+
+    Returns
+    -------
+    out : ndarray or tuple of ndarrays
+        If both `x` and `y` are specified, the output array contains
+        elements of `x` where `condition` is True, and elements from
+        `y` elsewhere.
+
+        If only `condition` is given, return the tuple
+        ``condition.nonzero()``, the indices where `condition` is True.
+
+    See Also
+    --------
+    nonzero, choose
+
+    Notes
+    -----
+    If `x` and `y` are given and input arrays are 1-D, `where` is
+    equivalent to::
+
+        [xv if c else yv for (c,xv,yv) in zip(condition,x,y)]
+
+    Examples
+    --------
+    >>> np.where([[True, False], [True, True]],
+    ...          [[1, 2], [3, 4]],
+    ...          [[9, 8], [7, 6]])
+    array([[1, 8],
+           [3, 4]])
+
+    >>> np.where([[0, 1], [1, 0]])
+    (array([0, 1]), array([1, 0]))
+
+    >>> x = np.arange(9.).reshape(3, 3)
+    >>> np.where( x > 5 )
+    (array([2, 2, 2]), array([0, 1, 2]))
+    >>> x[np.where( x > 3.0 )]               # Note: result is 1D.
+    array([ 4.,  5.,  6.,  7.,  8.])
+    >>> np.where(x < 5, x, -1)               # Note: broadcasting.
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -1.],
+           [-1., -1., -1.]])
+
+    Find the indices of elements of `x` that are in `goodvalues`.
+
+    >>> goodvalues = [3, 4, 7]
+    >>> ix = np.in1d(x.ravel(), goodvalues).reshape(x.shape)
+    >>> ix
+    array([[False, False, False],
+           [ True,  True, False],
+           [False,  True, False]], dtype=bool)
+    >>> np.where(ix)
+    (array([1, 1, 2]), array([0, 1, 1]))
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'lexsort',
+    """
+    lexsort(keys, axis=-1)
+
+    Perform an indirect sort using a sequence of keys.
+
+    Given multiple sorting keys, which can be interpreted as columns in a
+    spreadsheet, lexsort returns an array of integer indices that describes
+    the sort order by multiple columns. The last key in the sequence is used
+    for the primary sort order, the second-to-last key for the secondary sort
+    order, and so on. The keys argument must be a sequence of objects that
+    can be converted to arrays of the same shape. If a 2D array is provided
+    for the keys argument, it's rows are interpreted as the sorting keys and
+    sorting is according to the last row, second last row etc.
+
+    Parameters
+    ----------
+    keys : (k, N) array or tuple containing k (N,)-shaped sequences
+        The `k` different "columns" to be sorted.  The last column (or row if
+        `keys` is a 2D array) is the primary sort key.
+    axis : int, optional
+        Axis to be indirectly sorted.  By default, sort over the last axis.
+
+    Returns
+    -------
+    indices : (N,) ndarray of ints
+        Array of indices that sort the keys along the specified axis.
+
+    See Also
+    --------
+    argsort : Indirect sort.
+    ndarray.sort : In-place sort.
+    sort : Return a sorted copy of an array.
+
+    Examples
+    --------
+    Sort names: first by surname, then by name.
+
+    >>> surnames =    ('Hertz',    'Galilei', 'Hertz')
+    >>> first_names = ('Heinrich', 'Galileo', 'Gustav')
+    >>> ind = np.lexsort((first_names, surnames))
+    >>> ind
+    array([1, 2, 0])
+
+    >>> [surnames[i] + ", " + first_names[i] for i in ind]
+    ['Galilei, Galileo', 'Hertz, Gustav', 'Hertz, Heinrich']
+
+    Sort two columns of numbers:
+
+    >>> a = [1,5,1,4,3,4,4] # First column
+    >>> b = [9,4,0,4,0,2,1] # Second column
+    >>> ind = np.lexsort((b,a)) # Sort by a, then by b
+    >>> print(ind)
+    [2 0 4 6 5 3 1]
+
+    >>> [(a[i],b[i]) for i in ind]
+    [(1, 0), (1, 9), (3, 0), (4, 1), (4, 2), (4, 4), (5, 4)]
+
+    Note that sorting is first according to the elements of ``a``.
+    Secondary sorting is according to the elements of ``b``.
+
+    A normal ``argsort`` would have yielded:
+
+    >>> [(a[i],b[i]) for i in np.argsort(a)]
+    [(1, 9), (1, 0), (3, 0), (4, 4), (4, 2), (4, 1), (5, 4)]
+
+    Structured arrays are sorted lexically by ``argsort``:
+
+    >>> x = np.array([(1,9), (5,4), (1,0), (4,4), (3,0), (4,2), (4,1)],
+    ...              dtype=np.dtype([('x', int), ('y', int)]))
+
+    >>> np.argsort(x) # or np.argsort(x, order=('x', 'y'))
+    array([2, 0, 4, 6, 5, 3, 1])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'can_cast',
+    """
+    can_cast(from, totype, casting = 'safe')
+
+    Returns True if cast between data types can occur according to the
+    casting rule.  If from is a scalar or array scalar, also returns
+    True if the scalar value can be cast without overflow or truncation
+    to an integer.
+
+    Parameters
+    ----------
+    from : dtype, dtype specifier, scalar, or array
+        Data type, scalar, or array to cast from.
+    totype : dtype or dtype specifier
+        Data type to cast to.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+
+    Returns
+    -------
+    out : bool
+        True if cast can occur according to the casting rule.
+
+    Notes
+    -----
+    Starting in NumPy 1.9, can_cast function now returns False in 'safe'
+    casting mode for integer/float dtype and string dtype if the string dtype
+    length is not long enough to store the max integer/float value converted
+    to a string. Previously can_cast in 'safe' mode returned True for
+    integer/float dtype and a string dtype of any length.
+
+    See also
+    --------
+    dtype, result_type
+
+    Examples
+    --------
+    Basic examples
+
+    >>> np.can_cast(np.int32, np.int64)
+    True
+    >>> np.can_cast(np.float64, np.complex)
+    True
+    >>> np.can_cast(np.complex, np.float)
+    False
+
+    >>> np.can_cast('i8', 'f8')
+    True
+    >>> np.can_cast('i8', 'f4')
+    False
+    >>> np.can_cast('i4', 'S4')
+    False
+
+    Casting scalars
+
+    >>> np.can_cast(100, 'i1')
+    True
+    >>> np.can_cast(150, 'i1')
+    False
+    >>> np.can_cast(150, 'u1')
+    True
+
+    >>> np.can_cast(3.5e100, np.float32)
+    False
+    >>> np.can_cast(1000.0, np.float32)
+    True
+
+    Array scalar checks the value, array does not
+
+    >>> np.can_cast(np.array(1000.0), np.float32)
+    True
+    >>> np.can_cast(np.array([1000.0]), np.float32)
+    False
+
+    Using the casting rules
+
+    >>> np.can_cast('i8', 'i8', 'no')
+    True
+    >>> np.can_cast('<i8', '>i8', 'no')
+    False
+
+    >>> np.can_cast('<i8', '>i8', 'equiv')
+    True
+    >>> np.can_cast('<i4', '>i8', 'equiv')
+    False
+
+    >>> np.can_cast('<i4', '>i8', 'safe')
+    True
+    >>> np.can_cast('<i8', '>i4', 'safe')
+    False
+
+    >>> np.can_cast('<i8', '>i4', 'same_kind')
+    True
+    >>> np.can_cast('<i8', '>u4', 'same_kind')
+    False
+
+    >>> np.can_cast('<i8', '>u4', 'unsafe')
+    True
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'promote_types',
+    """
+    promote_types(type1, type2)
+
+    Returns the data type with the smallest size and smallest scalar
+    kind to which both ``type1`` and ``type2`` may be safely cast.
+    The returned data type is always in native byte order.
+
+    This function is symmetric and associative.
+
+    Parameters
+    ----------
+    type1 : dtype or dtype specifier
+        First data type.
+    type2 : dtype or dtype specifier
+        Second data type.
+
+    Returns
+    -------
+    out : dtype
+        The promoted data type.
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    Starting in NumPy 1.9, promote_types function now returns a valid string
+    length when given an integer or float dtype as one argument and a string
+    dtype as another argument. Previously it always returned the input string
+    dtype, even if it wasn't long enough to store the max integer/float value
+    converted to a string.
+
+    See Also
+    --------
+    result_type, dtype, can_cast
+
+    Examples
+    --------
+    >>> np.promote_types('f4', 'f8')
+    dtype('float64')
+
+    >>> np.promote_types('i8', 'f4')
+    dtype('float64')
+
+    >>> np.promote_types('>i8', '<c8')
+    dtype('complex128')
+
+    >>> np.promote_types('i4', 'S8')
+    dtype('S11')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'min_scalar_type',
+    """
+    min_scalar_type(a)
+
+    For scalar ``a``, returns the data type with the smallest size
+    and smallest scalar kind which can hold its value.  For non-scalar
+    array ``a``, returns the vector's dtype unmodified.
+
+    Floating point values are not demoted to integers,
+    and complex values are not demoted to floats.
+
+    Parameters
+    ----------
+    a : scalar or array_like
+        The value whose minimal data type is to be found.
+
+    Returns
+    -------
+    out : dtype
+        The minimal data type.
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    See Also
+    --------
+    result_type, promote_types, dtype, can_cast
+
+    Examples
+    --------
+    >>> np.min_scalar_type(10)
+    dtype('uint8')
+
+    >>> np.min_scalar_type(-260)
+    dtype('int16')
+
+    >>> np.min_scalar_type(3.1)
+    dtype('float16')
+
+    >>> np.min_scalar_type(1e50)
+    dtype('float64')
+
+    >>> np.min_scalar_type(np.arange(4,dtype='f8'))
+    dtype('float64')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'result_type',
+    """
+    result_type(*arrays_and_dtypes)
+
+    Returns the type that results from applying the NumPy
+    type promotion rules to the arguments.
+
+    Type promotion in NumPy works similarly to the rules in languages
+    like C++, with some slight differences.  When both scalars and
+    arrays are used, the array's type takes precedence and the actual value
+    of the scalar is taken into account.
+
+    For example, calculating 3*a, where a is an array of 32-bit floats,
+    intuitively should result in a 32-bit float output.  If the 3 is a
+    32-bit integer, the NumPy rules indicate it can't convert losslessly
+    into a 32-bit float, so a 64-bit float should be the result type.
+    By examining the value of the constant, '3', we see that it fits in
+    an 8-bit integer, which can be cast losslessly into the 32-bit float.
+
+    Parameters
+    ----------
+    arrays_and_dtypes : list of arrays and dtypes
+        The operands of some operation whose result type is needed.
+
+    Returns
+    -------
+    out : dtype
+        The result type.
+
+    See also
+    --------
+    dtype, promote_types, min_scalar_type, can_cast
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    The specific algorithm used is as follows.
+
+    Categories are determined by first checking which of boolean,
+    integer (int/uint), or floating point (float/complex) the maximum
+    kind of all the arrays and the scalars are.
+
+    If there are only scalars or the maximum category of the scalars
+    is higher than the maximum category of the arrays,
+    the data types are combined with :func:`promote_types`
+    to produce the return value.
+
+    Otherwise, `min_scalar_type` is called on each array, and
+    the resulting data types are all combined with :func:`promote_types`
+    to produce the return value.
+
+    The set of int values is not a subset of the uint values for types
+    with the same number of bits, something not reflected in
+    :func:`min_scalar_type`, but handled as a special case in `result_type`.
+
+    Examples
+    --------
+    >>> np.result_type(3, np.arange(7, dtype='i1'))
+    dtype('int8')
+
+    >>> np.result_type('i4', 'c8')
+    dtype('complex128')
+
+    >>> np.result_type(3.0, -2)
+    dtype('float64')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'newbuffer',
+    """
+    newbuffer(size)
+
+    Return a new uninitialized buffer object.
+
+    Parameters
+    ----------
+    size : int
+        Size in bytes of returned buffer object.
+
+    Returns
+    -------
+    newbuffer : buffer object
+        Returned, uninitialized buffer object of `size` bytes.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'getbuffer',
+    """
+    getbuffer(obj [,offset[, size]])
+
+    Create a buffer object from the given object referencing a slice of
+    length size starting at offset.
+
+    Default is the entire buffer. A read-write buffer is attempted followed
+    by a read-only buffer.
+
+    Parameters
+    ----------
+    obj : object
+
+    offset : int, optional
+
+    size : int, optional
+
+    Returns
+    -------
+    buffer_obj : buffer
+
+    Examples
+    --------
+    >>> buf = np.getbuffer(np.ones(5), 1, 3)
+    >>> len(buf)
+    3
+    >>> buf[0]
+    '\\x00'
+    >>> buf
+    <read-write buffer for 0x8af1e70, size 3, offset 1 at 0x8ba4ec0>
+
+    """)
+
+add_newdoc('numpy.core', 'dot',
+    """
+    dot(a, b, out=None)
+
+    Dot product of two arrays.
+
+    For 2-D arrays it is equivalent to matrix multiplication, and for 1-D
+    arrays to inner product of vectors (without complex conjugation). For
+    N dimensions it is a sum product over the last axis of `a` and
+    the second-to-last of `b`::
+
+        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
+
+    Parameters
+    ----------
+    a : array_like
+        First argument.
+    b : array_like
+        Second argument.
+    out : ndarray, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of `a` and `b`.  If `a` and `b` are both
+        scalars or both 1-D arrays then a scalar is returned; otherwise
+        an array is returned.
+        If `out` is given, then it is returned.
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` is not the same size as
+        the second-to-last dimension of `b`.
+
+    See Also
+    --------
+    vdot : Complex-conjugating dot product.
+    tensordot : Sum products over arbitrary axes.
+    einsum : Einstein summation convention.
+    matmul : '@' operator as method with out parameter.
+
+    Examples
+    --------
+    >>> np.dot(3, 4)
+    12
+
+    Neither argument is complex-conjugated:
+
+    >>> np.dot([2j, 3j], [2j, 3j])
+    (-13+0j)
+
+    For 2-D arrays it is the matrix product:
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [[4, 1], [2, 2]]
+    >>> np.dot(a, b)
+    array([[4, 1],
+           [2, 2]])
+
+    >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
+    >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))
+    >>> np.dot(a, b)[2,3,2,1,2,2]
+    499128
+    >>> sum(a[2,3,2,:] * b[1,2,:,2])
+    499128
+
+    """)
+
+add_newdoc('numpy.core', 'matmul',
+    """
+    matmul(a, b, out=None)
+
+    Matrix product of two arrays.
+
+    The behavior depends on the arguments in the following way.
+
+    - If both arguments are 2-D they are multiplied like conventional
+      matrices.
+    - If either argument is N-D, N > 2, it is treated as a stack of
+      matrices residing in the last two indexes and broadcast accordingly.
+    - If the first argument is 1-D, it is promoted to a matrix by
+      prepending a 1 to its dimensions. After matrix multiplication
+      the prepended 1 is removed.
+    - If the second argument is 1-D, it is promoted to a matrix by
+      appending a 1 to its dimensions. After matrix multiplication
+      the appended 1 is removed.
+
+    Multiplication by a scalar is not allowed, use ``*`` instead. Note that
+    multiplying a stack of matrices with a vector will result in a stack of
+    vectors, but matmul will not recognize it as such.
+
+    ``matmul`` differs from ``dot`` in two important ways.
+
+    - Multiplication by scalars is not allowed.
+    - Stacks of matrices are broadcast together as if the matrices
+      were elements.
+
+    .. warning::
+       This function is preliminary and included in Numpy 1.10 for testing
+       and documentation. Its semantics will not change, but the number and
+       order of the optional arguments will.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    a : array_like
+        First argument.
+    b : array_like
+        Second argument.
+    out : ndarray, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of `a` and `b`.  If `a` and `b` are both
+        1-D arrays then a scalar is returned; otherwise an array is
+        returned.  If `out` is given, then it is returned.
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` is not the same size as
+        the second-to-last dimension of `b`.
+
+        If scalar value is passed.
+
+    See Also
+    --------
+    vdot : Complex-conjugating dot product.
+    tensordot : Sum products over arbitrary axes.
+    einsum : Einstein summation convention.
+    dot : alternative matrix product with different broadcasting rules.
+
+    Notes
+    -----
+    The matmul function implements the semantics of the `@` operator introduced
+    in Python 3.5 following PEP465.
+
+    Examples
+    --------
+    For 2-D arrays it is the matrix product:
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [[4, 1], [2, 2]]
+    >>> np.matmul(a, b)
+    array([[4, 1],
+           [2, 2]])
+
+    For 2-D mixed with 1-D, the result is the usual.
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [1, 2]
+    >>> np.matmul(a, b)
+    array([1, 2])
+    >>> np.matmul(b, a)
+    array([1, 2])
+
+
+    Broadcasting is conventional for stacks of arrays
+
+    >>> a = np.arange(2*2*4).reshape((2,2,4))
+    >>> b = np.arange(2*2*4).reshape((2,4,2))
+    >>> np.matmul(a,b).shape
+    (2, 2, 2)
+    >>> np.matmul(a,b)[0,1,1]
+    98
+    >>> sum(a[0,1,:] * b[0,:,1])
+    98
+
+    Vector, vector returns the scalar inner product, but neither argument
+    is complex-conjugated:
+
+    >>> np.matmul([2j, 3j], [2j, 3j])
+    (-13+0j)
+
+    Scalar multiplication raises an error.
+
+    >>> np.matmul([1,2], 3)
+    Traceback (most recent call last):
+    ...
+    ValueError: Scalar operands are not allowed, use '*' instead
+
+    """)
+
+
+add_newdoc('numpy.core', 'einsum',
+    """
+    einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe')
+
+    Evaluates the Einstein summation convention on the operands.
+
+    Using the Einstein summation convention, many common multi-dimensional
+    array operations can be represented in a simple fashion.  This function
+    provides a way to compute such summations. The best way to understand this
+    function is to try the examples below, which show how many common NumPy
+    functions can be implemented as calls to `einsum`.
+
+    Parameters
+    ----------
+    subscripts : str
+        Specifies the subscripts for summation.
+    operands : list of array_like
+        These are the arrays for the operation.
+    out : ndarray, optional
+        If provided, the calculation is done into this array.
+    dtype : data-type, optional
+        If provided, forces the calculation to use the data type specified.
+        Note that you may have to also give a more liberal `casting`
+        parameter to allow the conversions.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the output. 'C' means it should
+        be C contiguous. 'F' means it should be Fortran contiguous,
+        'A' means it should be 'F' if the inputs are all 'F', 'C' otherwise.
+        'K' means it should be as close to the layout as the inputs as
+        is possible, including arbitrarily permuted axes.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur.  Setting this to
+        'unsafe' is not recommended, as it can adversely affect accumulations.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+
+    Returns
+    -------
+    output : ndarray
+        The calculation based on the Einstein summation convention.
+
+    See Also
+    --------
+    dot, inner, outer, tensordot
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    The subscripts string is a comma-separated list of subscript labels,
+    where each label refers to a dimension of the corresponding operand.
+    Repeated subscripts labels in one operand take the diagonal.  For example,
+    ``np.einsum('ii', a)`` is equivalent to ``np.trace(a)``.
+
+    Whenever a label is repeated, it is summed, so ``np.einsum('i,i', a, b)``
+    is equivalent to ``np.inner(a,b)``.  If a label appears only once,
+    it is not summed, so ``np.einsum('i', a)`` produces a view of ``a``
+    with no changes.
+
+    The order of labels in the output is by default alphabetical.  This
+    means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while
+    ``np.einsum('ji', a)`` takes its transpose.
+
+    The output can be controlled by specifying output subscript labels
+    as well.  This specifies the label order, and allows summing to
+    be disallowed or forced when desired.  The call ``np.einsum('i->', a)``
+    is like ``np.sum(a, axis=-1)``, and ``np.einsum('ii->i', a)``
+    is like ``np.diag(a)``.  The difference is that `einsum` does not
+    allow broadcasting by default.
+
+    To enable and control broadcasting, use an ellipsis.  Default
+    NumPy-style broadcasting is done by adding an ellipsis
+    to the left of each term, like ``np.einsum('...ii->...i', a)``.
+    To take the trace along the first and last axes,
+    you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix
+    product with the left-most indices instead of rightmost, you can do
+    ``np.einsum('ij...,jk...->ik...', a, b)``.
+
+    When there is only one operand, no axes are summed, and no output
+    parameter is provided, a view into the operand is returned instead
+    of a new array.  Thus, taking the diagonal as ``np.einsum('ii->i', a)``
+    produces a view.
+
+    An alternative way to provide the subscripts and operands is as
+    ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``. The examples
+    below have corresponding `einsum` calls with the two parameter methods.
+
+    .. versionadded:: 1.10.0
+
+    Views returned from einsum are now writeable whenever the input array
+    is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now
+    have the same effect as ``np.swapaxes(a, 0, 2)`` and
+    ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
+    of a 2D array.
+
+    Examples
+    --------
+    >>> a = np.arange(25).reshape(5,5)
+    >>> b = np.arange(5)
+    >>> c = np.arange(6).reshape(2,3)
+
+    >>> np.einsum('ii', a)
+    60
+    >>> np.einsum(a, [0,0])
+    60
+    >>> np.trace(a)
+    60
+
+    >>> np.einsum('ii->i', a)
+    array([ 0,  6, 12, 18, 24])
+    >>> np.einsum(a, [0,0], [0])
+    array([ 0,  6, 12, 18, 24])
+    >>> np.diag(a)
+    array([ 0,  6, 12, 18, 24])
+
+    >>> np.einsum('ij,j', a, b)
+    array([ 30,  80, 130, 180, 230])
+    >>> np.einsum(a, [0,1], b, [1])
+    array([ 30,  80, 130, 180, 230])
+    >>> np.dot(a, b)
+    array([ 30,  80, 130, 180, 230])
+    >>> np.einsum('...j,j', a, b)
+    array([ 30,  80, 130, 180, 230])
+
+    >>> np.einsum('ji', c)
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+    >>> np.einsum(c, [1,0])
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+    >>> c.T
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+
+    >>> np.einsum('..., ...', 3, c)
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+    >>> np.einsum(3, [Ellipsis], c, [Ellipsis])
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+    >>> np.multiply(3, c)
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+
+    >>> np.einsum('i,i', b, b)
+    30
+    >>> np.einsum(b, [0], b, [0])
+    30
+    >>> np.inner(b,b)
+    30
+
+    >>> np.einsum('i,j', np.arange(2)+1, b)
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+    >>> np.einsum(np.arange(2)+1, [0], b, [1])
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+    >>> np.outer(np.arange(2)+1, b)
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+
+    >>> np.einsum('i...->...', a)
+    array([50, 55, 60, 65, 70])
+    >>> np.einsum(a, [0,Ellipsis], [Ellipsis])
+    array([50, 55, 60, 65, 70])
+    >>> np.sum(a, axis=0)
+    array([50, 55, 60, 65, 70])
+
+    >>> a = np.arange(60.).reshape(3,4,5)
+    >>> b = np.arange(24.).reshape(4,3,2)
+    >>> np.einsum('ijk,jil->kl', a, b)
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3])
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> np.tensordot(a,b, axes=([1,0],[0,1]))
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+
+    >>> a = np.arange(6).reshape((3,2))
+    >>> b = np.arange(12).reshape((4,3))
+    >>> np.einsum('ki,jk->ij', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+    >>> np.einsum('ki,...k->i...', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+    >>> np.einsum('k...,jk', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+
+    >>> # since version 1.10.0
+    >>> a = np.zeros((3, 3))
+    >>> np.einsum('ii->i', a)[:] = 1
+    >>> a
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """)
+
+add_newdoc('numpy.core', 'vdot',
+    """
+    vdot(a, b)
+
+    Return the dot product of two vectors.
+
+    The vdot(`a`, `b`) function handles complex numbers differently than
+    dot(`a`, `b`).  If the first argument is complex the complex conjugate
+    of the first argument is used for the calculation of the dot product.
+
+    Note that `vdot` handles multidimensional arrays differently than `dot`:
+    it does *not* perform a matrix product, but flattens input arguments
+    to 1-D vectors first. Consequently, it should only be used for vectors.
+
+    Parameters
+    ----------
+    a : array_like
+        If `a` is complex the complex conjugate is taken before calculation
+        of the dot product.
+    b : array_like
+        Second argument to the dot product.
+
+    Returns
+    -------
+    output : ndarray
+        Dot product of `a` and `b`.  Can be an int, float, or
+        complex depending on the types of `a` and `b`.
+
+    See Also
+    --------
+    dot : Return the dot product without using the complex conjugate of the
+          first argument.
+
+    Examples
+    --------
+    >>> a = np.array([1+2j,3+4j])
+    >>> b = np.array([5+6j,7+8j])
+    >>> np.vdot(a, b)
+    (70-8j)
+    >>> np.vdot(b, a)
+    (70+8j)
+
+    Note that higher-dimensional arrays are flattened!
+
+    >>> a = np.array([[1, 4], [5, 6]])
+    >>> b = np.array([[4, 1], [2, 2]])
+    >>> np.vdot(a, b)
+    30
+    >>> np.vdot(b, a)
+    30
+    >>> 1*4 + 4*1 + 5*2 + 6*2
+    30
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for ndarray attributes and methods
+#
+##############################################################################
+
+
+##############################################################################
+#
+# ndarray object
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray',
+    """
+    ndarray(shape, dtype=float, buffer=None, offset=0,
+            strides=None, order=None)
+
+    An array object represents a multidimensional, homogeneous array
+    of fixed-size items.  An associated data-type object describes the
+    format of each element in the array (its byte-order, how many bytes it
+    occupies in memory, whether it is an integer, a floating point number,
+    or something else, etc.)
+
+    Arrays should be constructed using `array`, `zeros` or `empty` (refer
+    to the See Also section below).  The parameters given here refer to
+    a low-level method (`ndarray(...)`) for instantiating an array.
+
+    For more information, refer to the `numpy` module and examine the
+    the methods and attributes of an array.
+
+    Parameters
+    ----------
+    (for the __new__ method; see Notes below)
+
+    shape : tuple of ints
+        Shape of created array.
+    dtype : data-type, optional
+        Any object that can be interpreted as a numpy data type.
+    buffer : object exposing buffer interface, optional
+        Used to fill the array with data.
+    offset : int, optional
+        Offset of array data in buffer.
+    strides : tuple of ints, optional
+        Strides of data in memory.
+    order : {'C', 'F'}, optional
+        Row-major (C-style) or column-major (Fortran-style) order.
+
+    Attributes
+    ----------
+    T : ndarray
+        Transpose of the array.
+    data : buffer
+        The array's elements, in memory.
+    dtype : dtype object
+        Describes the format of the elements in the array.
+    flags : dict
+        Dictionary containing information related to memory use, e.g.,
+        'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
+    flat : numpy.flatiter object
+        Flattened version of the array as an iterator.  The iterator
+        allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
+        assignment examples; TODO).
+    imag : ndarray
+        Imaginary part of the array.
+    real : ndarray
+        Real part of the array.
+    size : int
+        Number of elements in the array.
+    itemsize : int
+        The memory use of each array element in bytes.
+    nbytes : int
+        The total number of bytes required to store the array data,
+        i.e., ``itemsize * size``.
+    ndim : int
+        The array's number of dimensions.
+    shape : tuple of ints
+        Shape of the array.
+    strides : tuple of ints
+        The step-size required to move from one element to the next in
+        memory. For example, a contiguous ``(3, 4)`` array of type
+        ``int16`` in C-order has strides ``(8, 2)``.  This implies that
+        to move from element to element in memory requires jumps of 2 bytes.
+        To move from row-to-row, one needs to jump 8 bytes at a time
+        (``2 * 4``).
+    ctypes : ctypes object
+        Class containing properties of the array needed for interaction
+        with ctypes.
+    base : ndarray
+        If the array is a view into another array, that array is its `base`
+        (unless that array is also a view).  The `base` array is where the
+        array data is actually stored.
+
+    See Also
+    --------
+    array : Construct an array.
+    zeros : Create an array, each element of which is zero.
+    empty : Create an array, but leave its allocated memory unchanged (i.e.,
+            it contains "garbage").
+    dtype : Create a data-type.
+
+    Notes
+    -----
+    There are two modes of creating an array using ``__new__``:
+
+    1. If `buffer` is None, then only `shape`, `dtype`, and `order`
+       are used.
+    2. If `buffer` is an object exposing the buffer interface, then
+       all keywords are interpreted.
+
+    No ``__init__`` method is needed because the array is fully initialized
+    after the ``__new__`` method.
+
+    Examples
+    --------
+    These examples illustrate the low-level `ndarray` constructor.  Refer
+    to the `See Also` section above for easier ways of constructing an
+    ndarray.
+
+    First mode, `buffer` is None:
+
+    >>> np.ndarray(shape=(2,2), dtype=float, order='F')
+    array([[ -1.13698227e+002,   4.25087011e-303],
+           [  2.88528414e-306,   3.27025015e-309]])         #random
+
+    Second mode:
+
+    >>> np.ndarray((2,), buffer=np.array([1,2,3]),
+    ...            offset=np.int_().itemsize,
+    ...            dtype=int) # offset = 1*itemsize, i.e. skip first element
+    array([2, 3])
+
+    """)
+
+
+##############################################################################
+#
+# ndarray attributes
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_interface__',
+    """Array protocol: Python side."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_finalize__',
+    """None."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_priority__',
+    """Array priority."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_struct__',
+    """Array protocol: C-struct side."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('_as_parameter_',
+    """Allow the array to be interpreted as a ctypes object by returning the
+    data-memory location as an integer
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('base',
+    """
+    Base object if memory is from some other object.
+
+    Examples
+    --------
+    The base of an array that owns its memory is None:
+
+    >>> x = np.array([1,2,3,4])
+    >>> x.base is None
+    True
+
+    Slicing creates a view, whose memory is shared with x:
+
+    >>> y = x[2:]
+    >>> y.base is x
+    True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ctypes',
+    """
+    An object to simplify the interaction of the array with the ctypes
+    module.
+
+    This attribute creates an object that makes it easier to use arrays
+    when calling shared libraries with the ctypes module. The returned
+    object has, among others, data, shape, and strides attributes (see
+    Notes below) which themselves return ctypes objects that can be used
+    as arguments to a shared library.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    c : Python object
+        Possessing attributes data, shape, strides, etc.
+
+    See Also
+    --------
+    numpy.ctypeslib
+
+    Notes
+    -----
+    Below are the public attributes of this object which were documented
+    in "Guide to NumPy" (we have omitted undocumented public attributes,
+    as well as documented private attributes):
+
+    * data: A pointer to the memory area of the array as a Python integer.
+      This memory area may contain data that is not aligned, or not in correct
+      byte-order. The memory area may not even be writeable. The array
+      flags and data-type of this array should be respected when passing this
+      attribute to arbitrary C-code to avoid trouble that can include Python
+      crashing. User Beware! The value of this attribute is exactly the same
+      as self._array_interface_['data'][0].
+
+    * shape (c_intp*self.ndim): A ctypes array of length self.ndim where
+      the basetype is the C-integer corresponding to dtype('p') on this
+      platform. This base-type could be c_int, c_long, or c_longlong
+      depending on the platform. The c_intp type is defined accordingly in
+      numpy.ctypeslib. The ctypes array contains the shape of the underlying
+      array.
+
+    * strides (c_intp*self.ndim): A ctypes array of length self.ndim where
+      the basetype is the same as for the shape attribute. This ctypes array
+      contains the strides information from the underlying array. This strides
+      information is important for showing how many bytes must be jumped to
+      get to the next element in the array.
+
+    * data_as(obj): Return the data pointer cast to a particular c-types object.
+      For example, calling self._as_parameter_ is equivalent to
+      self.data_as(ctypes.c_void_p). Perhaps you want to use the data as a
+      pointer to a ctypes array of floating-point data:
+      self.data_as(ctypes.POINTER(ctypes.c_double)).
+
+    * shape_as(obj): Return the shape tuple as an array of some other c-types
+      type. For example: self.shape_as(ctypes.c_short).
+
+    * strides_as(obj): Return the strides tuple as an array of some other
+      c-types type. For example: self.strides_as(ctypes.c_longlong).
+
+    Be careful using the ctypes attribute - especially on temporary
+    arrays or arrays constructed on the fly. For example, calling
+    ``(a+b).ctypes.data_as(ctypes.c_void_p)`` returns a pointer to memory
+    that is invalid because the array created as (a+b) is deallocated
+    before the next Python statement. You can avoid this problem using
+    either ``c=a+b`` or ``ct=(a+b).ctypes``. In the latter case, ct will
+    hold a reference to the array until ct is deleted or re-assigned.
+
+    If the ctypes module is not available, then the ctypes attribute
+    of array objects still returns something useful, but ctypes objects
+    are not returned and errors may be raised instead. In particular,
+    the object will still have the as parameter attribute which will
+    return an integer equal to the data attribute.
+
+    Examples
+    --------
+    >>> import ctypes
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+    >>> x.ctypes.data
+    30439712
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
+    <ctypes.LP_c_long object at 0x01F01300>
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long)).contents
+    c_long(0)
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_longlong)).contents
+    c_longlong(4294967296L)
+    >>> x.ctypes.shape
+    <numpy.core._internal.c_long_Array_2 object at 0x01FFD580>
+    >>> x.ctypes.shape_as(ctypes.c_long)
+    <numpy.core._internal.c_long_Array_2 object at 0x01FCE620>
+    >>> x.ctypes.strides
+    <numpy.core._internal.c_long_Array_2 object at 0x01FCE620>
+    >>> x.ctypes.strides_as(ctypes.c_longlong)
+    <numpy.core._internal.c_longlong_Array_2 object at 0x01F01300>
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('data',
+    """Python buffer object pointing to the start of the array's data."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dtype',
+    """
+    Data-type of the array's elements.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    d : numpy dtype object
+
+    See Also
+    --------
+    numpy.dtype
+
+    Examples
+    --------
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+    >>> x.dtype
+    dtype('int32')
+    >>> type(x.dtype)
+    <type 'numpy.dtype'>
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('imag',
+    """
+    The imaginary part of the array.
+
+    Examples
+    --------
+    >>> x = np.sqrt([1+0j, 0+1j])
+    >>> x.imag
+    array([ 0.        ,  0.70710678])
+    >>> x.imag.dtype
+    dtype('float64')
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemsize',
+    """
+    Length of one array element in bytes.
+
+    Examples
+    --------
+    >>> x = np.array([1,2,3], dtype=np.float64)
+    >>> x.itemsize
+    8
+    >>> x = np.array([1,2,3], dtype=np.complex128)
+    >>> x.itemsize
+    16
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flags',
+    """
+    Information about the memory layout of the array.
+
+    Attributes
+    ----------
+    C_CONTIGUOUS (C)
+        The data is in a single, C-style contiguous segment.
+    F_CONTIGUOUS (F)
+        The data is in a single, Fortran-style contiguous segment.
+    OWNDATA (O)
+        The array owns the memory it uses or borrows it from another object.
+    WRITEABLE (W)
+        The data area can be written to.  Setting this to False locks
+        the data, making it read-only.  A view (slice, etc.) inherits WRITEABLE
+        from its base array at creation time, but a view of a writeable
+        array may be subsequently locked while the base array remains writeable.
+        (The opposite is not true, in that a view of a locked array may not
+        be made writeable.  However, currently, locking a base object does not
+        lock any views that already reference it, so under that circumstance it
+        is possible to alter the contents of a locked array via a previously
+        created writeable view onto it.)  Attempting to change a non-writeable
+        array raises a RuntimeError exception.
+    ALIGNED (A)
+        The data and all elements are aligned appropriately for the hardware.
+    UPDATEIFCOPY (U)
+        This array is a copy of some other array. When this array is
+        deallocated, the base array will be updated with the contents of
+        this array.
+    FNC
+        F_CONTIGUOUS and not C_CONTIGUOUS.
+    FORC
+        F_CONTIGUOUS or C_CONTIGUOUS (one-segment test).
+    BEHAVED (B)
+        ALIGNED and WRITEABLE.
+    CARRAY (CA)
+        BEHAVED and C_CONTIGUOUS.
+    FARRAY (FA)
+        BEHAVED and F_CONTIGUOUS and not C_CONTIGUOUS.
+
+    Notes
+    -----
+    The `flags` object can be accessed dictionary-like (as in ``a.flags['WRITEABLE']``),
+    or by using lowercased attribute names (as in ``a.flags.writeable``). Short flag
+    names are only supported in dictionary access.
+
+    Only the UPDATEIFCOPY, WRITEABLE, and ALIGNED flags can be changed by
+    the user, via direct assignment to the attribute or dictionary entry,
+    or by calling `ndarray.setflags`.
+
+    The array flags cannot be set arbitrarily:
+
+    - UPDATEIFCOPY can only be set ``False``.
+    - ALIGNED can only be set ``True`` if the data is truly aligned.
+    - WRITEABLE can only be set ``True`` if the array owns its own memory
+      or the ultimate owner of the memory exposes a writeable buffer
+      interface or is a string.
+
+    Arrays can be both C-style and Fortran-style contiguous simultaneously.
+    This is clear for 1-dimensional arrays, but can also be true for higher
+    dimensional arrays.
+
+    Even for contiguous arrays a stride for a given dimension
+    ``arr.strides[dim]`` may be *arbitrary* if ``arr.shape[dim] == 1``
+    or the array has no elements.
+    It does *not* generally hold that ``self.strides[-1] == self.itemsize``
+    for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for
+    Fortran-style contiguous arrays is true.
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flat',
+    """
+    A 1-D iterator over the array.
+
+    This is a `numpy.flatiter` instance, which acts similarly to, but is not
+    a subclass of, Python's built-in iterator object.
+
+    See Also
+    --------
+    flatten : Return a copy of the array collapsed into one dimension.
+
+    flatiter
+
+    Examples
+    --------
+    >>> x = np.arange(1, 7).reshape(2, 3)
+    >>> x
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> x.flat[3]
+    4
+    >>> x.T
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+    >>> x.T.flat[3]
+    5
+    >>> type(x.flat)
+    <type 'numpy.flatiter'>
+
+    An assignment example:
+
+    >>> x.flat = 3; x
+    array([[3, 3, 3],
+           [3, 3, 3]])
+    >>> x.flat[[1,4]] = 1; x
+    array([[3, 1, 3],
+           [3, 1, 3]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nbytes',
+    """
+    Total bytes consumed by the elements of the array.
+
+    Notes
+    -----
+    Does not include memory consumed by non-element attributes of the
+    array object.
+
+    Examples
+    --------
+    >>> x = np.zeros((3,5,2), dtype=np.complex128)
+    >>> x.nbytes
+    480
+    >>> np.prod(x.shape) * x.itemsize
+    480
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ndim',
+    """
+    Number of array dimensions.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> x.ndim
+    1
+    >>> y = np.zeros((2, 3, 4))
+    >>> y.ndim
+    3
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('real',
+    """
+    The real part of the array.
+
+    Examples
+    --------
+    >>> x = np.sqrt([1+0j, 0+1j])
+    >>> x.real
+    array([ 1.        ,  0.70710678])
+    >>> x.real.dtype
+    dtype('float64')
+
+    See Also
+    --------
+    numpy.real : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('shape',
+    """
+    Tuple of array dimensions.
+
+    Notes
+    -----
+    May be used to "reshape" the array, as long as this would not
+    require a change in the total number of elements
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3, 4])
+    >>> x.shape
+    (4,)
+    >>> y = np.zeros((2, 3, 4))
+    >>> y.shape
+    (2, 3, 4)
+    >>> y.shape = (3, 8)
+    >>> y
+    array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
+    >>> y.shape = (3, 6)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: total size of new array must be unchanged
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('size',
+    """
+    Number of elements in the array.
+
+    Equivalent to ``np.prod(a.shape)``, i.e., the product of the array's
+    dimensions.
+
+    Examples
+    --------
+    >>> x = np.zeros((3, 5, 2), dtype=np.complex128)
+    >>> x.size
+    30
+    >>> np.prod(x.shape)
+    30
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('strides',
+    """
+    Tuple of bytes to step in each dimension when traversing an array.
+
+    The byte offset of element ``(i[0], i[1], ..., i[n])`` in an array `a`
+    is::
+
+        offset = sum(np.array(i) * a.strides)
+
+    A more detailed explanation of strides can be found in the
+    "ndarray.rst" file in the NumPy reference guide.
+
+    Notes
+    -----
+    Imagine an array of 32-bit integers (each 4 bytes)::
+
+      x = np.array([[0, 1, 2, 3, 4],
+                    [5, 6, 7, 8, 9]], dtype=np.int32)
+
+    This array is stored in memory as 40 bytes, one after the other
+    (known as a contiguous block of memory).  The strides of an array tell
+    us how many bytes we have to skip in memory to move to the next position
+    along a certain axis.  For example, we have to skip 4 bytes (1 value) to
+    move to the next column, but 20 bytes (5 values) to get to the same
+    position in the next row.  As such, the strides for the array `x` will be
+    ``(20, 4)``.
+
+    See Also
+    --------
+    numpy.lib.stride_tricks.as_strided
+
+    Examples
+    --------
+    >>> y = np.reshape(np.arange(2*3*4), (2,3,4))
+    >>> y
+    array([[[ 0,  1,  2,  3],
+            [ 4,  5,  6,  7],
+            [ 8,  9, 10, 11]],
+           [[12, 13, 14, 15],
+            [16, 17, 18, 19],
+            [20, 21, 22, 23]]])
+    >>> y.strides
+    (48, 16, 4)
+    >>> y[1,1,1]
+    17
+    >>> offset=sum(y.strides * np.array((1,1,1)))
+    >>> offset/y.itemsize
+    17
+
+    >>> x = np.reshape(np.arange(5*6*7*8), (5,6,7,8)).transpose(2,3,1,0)
+    >>> x.strides
+    (32, 4, 224, 1344)
+    >>> i = np.array([3,5,2,2])
+    >>> offset = sum(i * x.strides)
+    >>> x[3,5,2,2]
+    813
+    >>> offset / x.itemsize
+    813
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('T',
+    """
+    Same as self.transpose(), except that self is returned if
+    self.ndim < 2.
+
+    Examples
+    --------
+    >>> x = np.array([[1.,2.],[3.,4.]])
+    >>> x
+    array([[ 1.,  2.],
+           [ 3.,  4.]])
+    >>> x.T
+    array([[ 1.,  3.],
+           [ 2.,  4.]])
+    >>> x = np.array([1.,2.,3.,4.])
+    >>> x
+    array([ 1.,  2.,  3.,  4.])
+    >>> x.T
+    array([ 1.,  2.,  3.,  4.])
+
+    """))
+
+
+##############################################################################
+#
+# ndarray methods
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array__',
+    """ a.__array__(|dtype) -> reference if type unchanged, copy otherwise.
+
+    Returns either a new reference to self if dtype is not given or a new array
+    of provided data type if dtype is different from the current dtype of the
+    array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_prepare__',
+    """a.__array_prepare__(obj) -> Object of same type as ndarray object obj.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_wrap__',
+    """a.__array_wrap__(obj) -> Object of same type as ndarray object a.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__copy__',
+    """a.__copy__([order])
+
+    Return a copy of the array.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A'}, optional
+        If order is 'C' (False) then the result is contiguous (default).
+        If order is 'Fortran' (True) then the result has fortran order.
+        If order is 'Any' (None) then the result has fortran order
+        only if the array already is in fortran order.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__deepcopy__',
+    """a.__deepcopy__() -> Deep copy of array.
+
+    Used if copy.deepcopy is called on an array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__reduce__',
+    """a.__reduce__()
+
+    For pickling.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__setstate__',
+    """a.__setstate__(version, shape, dtype, isfortran, rawdata)
+
+    For unpickling.
+
+    Parameters
+    ----------
+    version : int
+        optional pickle version. If omitted defaults to 0.
+    shape : tuple
+    dtype : data-type
+    isFortran : bool
+    rawdata : string or list
+        a binary string with the data (or a list if 'a' is an object array)
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
+    """
+    a.all(axis=None, out=None, keepdims=False)
+
+    Returns True if all elements evaluate to True.
+
+    Refer to `numpy.all` for full documentation.
+
+    See Also
+    --------
+    numpy.all : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('any',
+    """
+    a.any(axis=None, out=None, keepdims=False)
+
+    Returns True if any of the elements of `a` evaluate to True.
+
+    Refer to `numpy.any` for full documentation.
+
+    See Also
+    --------
+    numpy.any : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmax',
+    """
+    a.argmax(axis=None, out=None)
+
+    Return indices of the maximum values along the given axis.
+
+    Refer to `numpy.argmax` for full documentation.
+
+    See Also
+    --------
+    numpy.argmax : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin',
+    """
+    a.argmin(axis=None, out=None)
+
+    Return indices of the minimum values along the given axis of `a`.
+
+    Refer to `numpy.argmin` for detailed documentation.
+
+    See Also
+    --------
+    numpy.argmin : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort',
+    """
+    a.argsort(axis=-1, kind='quicksort', order=None)
+
+    Returns the indices that would sort this array.
+
+    Refer to `numpy.argsort` for full documentation.
+
+    See Also
+    --------
+    numpy.argsort : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argpartition',
+    """
+    a.argpartition(kth, axis=-1, kind='introselect', order=None)
+
+    Returns the indices that would partition this array.
+
+    Refer to `numpy.argpartition` for full documentation.
+
+    .. versionadded:: 1.8.0
+
+    See Also
+    --------
+    numpy.argpartition : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('astype',
+    """
+    a.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
+
+    Copy of the array, cast to a specified type.
+
+    Parameters
+    ----------
+    dtype : str or dtype
+        Typecode or data-type to which the array is cast.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout order of the result.
+        'C' means C order, 'F' means Fortran order, 'A'
+        means 'F' order if all the arrays are Fortran contiguous,
+        'C' order otherwise, and 'K' means as close to the
+        order the array elements appear in memory as possible.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur. Defaults to 'unsafe'
+        for backwards compatibility.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through (default), otherwise
+        the returned array will be forced to be a base-class array.
+    copy : bool, optional
+        By default, astype always returns a newly allocated array. If this
+        is set to false, and the `dtype`, `order`, and `subok`
+        requirements are satisfied, the input array is returned instead
+        of a copy.
+
+    Returns
+    -------
+    arr_t : ndarray
+        Unless `copy` is False and the other conditions for returning the input
+        array are satisfied (see description for `copy` input parameter), `arr_t`
+        is a new array of the same shape as the input array, with dtype, order
+        given by `dtype`, `order`.
+
+    Notes
+    -----
+    Starting in NumPy 1.9, astype method now returns an error if the string
+    dtype to cast to is not long enough in 'safe' casting mode to hold the max
+    value of integer/float array that is being casted. Previously the casting
+    was allowed even if the result was truncated.
+
+    Raises
+    ------
+    ComplexWarning
+        When casting from complex to float or int. To avoid this,
+        one should use ``a.real.astype(t)``.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 2.5])
+    >>> x
+    array([ 1. ,  2. ,  2.5])
+
+    >>> x.astype(int)
+    array([1, 2, 2])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('byteswap',
+    """
+    a.byteswap(inplace)
+
+    Swap the bytes of the array elements
+
+    Toggle between low-endian and big-endian data representation by
+    returning a byteswapped array, optionally swapped in-place.
+
+    Parameters
+    ----------
+    inplace : bool, optional
+        If ``True``, swap bytes in-place, default is ``False``.
+
+    Returns
+    -------
+    out : ndarray
+        The byteswapped array. If `inplace` is ``True``, this is
+        a view to self.
+
+    Examples
+    --------
+    >>> A = np.array([1, 256, 8755], dtype=np.int16)
+    >>> map(hex, A)
+    ['0x1', '0x100', '0x2233']
+    >>> A.byteswap(True)
+    array([  256,     1, 13090], dtype=int16)
+    >>> map(hex, A)
+    ['0x100', '0x1', '0x3322']
+
+    Arrays of strings are not swapped
+
+    >>> A = np.array(['ceg', 'fac'])
+    >>> A.byteswap()
+    array(['ceg', 'fac'],
+          dtype='|S3')
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('choose',
+    """
+    a.choose(choices, out=None, mode='raise')
+
+    Use an index array to construct a new array from a set of choices.
+
+    Refer to `numpy.choose` for full documentation.
+
+    See Also
+    --------
+    numpy.choose : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('clip',
+    """
+    a.clip(min=None, max=None, out=None)
+
+    Return an array whose values are limited to ``[min, max]``.
+    One of max or min must be given.
+
+    Refer to `numpy.clip` for full documentation.
+
+    See Also
+    --------
+    numpy.clip : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('compress',
+    """
+    a.compress(condition, axis=None, out=None)
+
+    Return selected slices of this array along given axis.
+
+    Refer to `numpy.compress` for full documentation.
+
+    See Also
+    --------
+    numpy.compress : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conj',
+    """
+    a.conj()
+
+    Complex-conjugate all elements.
+
+    Refer to `numpy.conjugate` for full documentation.
+
+    See Also
+    --------
+    numpy.conjugate : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conjugate',
+    """
+    a.conjugate()
+
+    Return the complex conjugate, element-wise.
+
+    Refer to `numpy.conjugate` for full documentation.
+
+    See Also
+    --------
+    numpy.conjugate : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('copy',
+    """
+    a.copy(order='C')
+
+    Return a copy of the array.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the copy. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible. (Note that this function and :func:numpy.copy are very
+        similar, but have different default values for their order=
+        arguments.)
+
+    See also
+    --------
+    numpy.copy
+    numpy.copyto
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3],[4,5,6]], order='F')
+
+    >>> y = x.copy()
+
+    >>> x.fill(0)
+
+    >>> x
+    array([[0, 0, 0],
+           [0, 0, 0]])
+
+    >>> y
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    >>> y.flags['C_CONTIGUOUS']
+    True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumprod',
+    """
+    a.cumprod(axis=None, dtype=None, out=None)
+
+    Return the cumulative product of the elements along the given axis.
+
+    Refer to `numpy.cumprod` for full documentation.
+
+    See Also
+    --------
+    numpy.cumprod : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumsum',
+    """
+    a.cumsum(axis=None, dtype=None, out=None)
+
+    Return the cumulative sum of the elements along the given axis.
+
+    Refer to `numpy.cumsum` for full documentation.
+
+    See Also
+    --------
+    numpy.cumsum : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('diagonal',
+    """
+    a.diagonal(offset=0, axis1=0, axis2=1)
+
+    Return specified diagonals. In NumPy 1.9 the returned array is a
+    read-only view instead of a copy as in previous NumPy versions.  In
+    a future version the read-only restriction will be removed.
+
+    Refer to :func:`numpy.diagonal` for full documentation.
+
+    See Also
+    --------
+    numpy.diagonal : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dot',
+    """
+    a.dot(b, out=None)
+
+    Dot product of two arrays.
+
+    Refer to `numpy.dot` for full documentation.
+
+    See Also
+    --------
+    numpy.dot : equivalent function
+
+    Examples
+    --------
+    >>> a = np.eye(2)
+    >>> b = np.ones((2, 2)) * 2
+    >>> a.dot(b)
+    array([[ 2.,  2.],
+           [ 2.,  2.]])
+
+    This array method can be conveniently chained:
+
+    >>> a.dot(b).dot(b)
+    array([[ 8.,  8.],
+           [ 8.,  8.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dump',
+    """a.dump(file)
+
+    Dump a pickle of the array to the specified file.
+    The array can be read back with pickle.load or numpy.load.
+
+    Parameters
+    ----------
+    file : str
+        A string naming the dump file.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dumps',
+    """
+    a.dumps()
+
+    Returns the pickle of the array as a string.
+    pickle.loads or numpy.loads will convert the string back to an array.
+
+    Parameters
+    ----------
+    None
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('fill',
+    """
+    a.fill(value)
+
+    Fill the array with a scalar value.
+
+    Parameters
+    ----------
+    value : scalar
+        All elements of `a` will be assigned this value.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2])
+    >>> a.fill(0)
+    >>> a
+    array([0, 0])
+    >>> a = np.empty(2)
+    >>> a.fill(1)
+    >>> a
+    array([ 1.,  1.])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flatten',
+    """
+    a.flatten(order='C')
+
+    Return a copy of the array collapsed into one dimension.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A', 'K'}, optional
+        'C' means to flatten in row-major (C-style) order.
+        'F' means to flatten in column-major (Fortran-
+        style) order. 'A' means to flatten in column-major
+        order if `a` is Fortran *contiguous* in memory,
+        row-major order otherwise. 'K' means to flatten
+        `a` in the order the elements occur in memory.
+        The default is 'C'.
+
+    Returns
+    -------
+    y : ndarray
+        A copy of the input array, flattened to one dimension.
+
+    See Also
+    --------
+    ravel : Return a flattened array.
+    flat : A 1-D flat iterator over the array.
+
+    Examples
+    --------
+    >>> a = np.array([[1,2], [3,4]])
+    >>> a.flatten()
+    array([1, 2, 3, 4])
+    >>> a.flatten('F')
+    array([1, 3, 2, 4])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('getfield',
+    """
+    a.getfield(dtype, offset=0)
+
+    Returns a field of the given array as a certain type.
+
+    A field is a view of the array data with a given data-type. The values in
+    the view are determined by the given type and the offset into the current
+    array in bytes. The offset needs to be such that the view dtype fits in the
+    array dtype; for example an array of dtype complex128 has 16-byte elements.
+    If taking a view with a 32-bit integer (4 bytes), the offset needs to be
+    between 0 and 12 bytes.
+
+    Parameters
+    ----------
+    dtype : str or dtype
+        The data type of the view. The dtype size of the view can not be larger
+        than that of the array itself.
+    offset : int
+        Number of bytes to skip before beginning the element view.
+
+    Examples
+    --------
+    >>> x = np.diag([1.+1.j]*2)
+    >>> x[1, 1] = 2 + 4.j
+    >>> x
+    array([[ 1.+1.j,  0.+0.j],
+           [ 0.+0.j,  2.+4.j]])
+    >>> x.getfield(np.float64)
+    array([[ 1.,  0.],
+           [ 0.,  2.]])
+
+    By choosing an offset of 8 bytes we can select the complex part of the
+    array for our view:
+
+    >>> x.getfield(np.float64, offset=8)
+    array([[ 1.,  0.],
+       [ 0.,  4.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('item',
+    """
+    a.item(*args)
+
+    Copy an element of an array to a standard Python scalar and return it.
+
+    Parameters
+    ----------
+    \\*args : Arguments (variable number and type)
+
+        * none: in this case, the method only works for arrays
+          with one element (`a.size == 1`), which element is
+          copied into a standard Python scalar object and returned.
+
+        * int_type: this argument is interpreted as a flat index into
+          the array, specifying which element to copy and return.
+
+        * tuple of int_types: functions as does a single int_type argument,
+          except that the argument is interpreted as an nd-index into the
+          array.
+
+    Returns
+    -------
+    z : Standard Python scalar object
+        A copy of the specified element of the array as a suitable
+        Python scalar
+
+    Notes
+    -----
+    When the data type of `a` is longdouble or clongdouble, item() returns
+    a scalar array object because there is no available Python scalar that
+    would not lose information. Void arrays return a buffer object for item(),
+    unless fields are defined, in which case a tuple is returned.
+
+    `item` is very similar to a[args], except, instead of an array scalar,
+    a standard Python scalar is returned. This can be useful for speeding up
+    access to elements of the array and doing arithmetic on elements of the
+    array using Python's optimized math.
+
+    Examples
+    --------
+    >>> x = np.random.randint(9, size=(3, 3))
+    >>> x
+    array([[3, 1, 7],
+           [2, 8, 3],
+           [8, 5, 3]])
+    >>> x.item(3)
+    2
+    >>> x.item(7)
+    5
+    >>> x.item((0, 1))
+    1
+    >>> x.item((2, 2))
+    3
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemset',
+    """
+    a.itemset(*args)
+
+    Insert scalar into an array (scalar is cast to array's dtype, if possible)
+
+    There must be at least 1 argument, and define the last argument
+    as *item*.  Then, ``a.itemset(*args)`` is equivalent to but faster
+    than ``a[args] = item``.  The item should be a scalar value and `args`
+    must select a single item in the array `a`.
+
+    Parameters
+    ----------
+    \*args : Arguments
+        If one argument: a scalar, only used in case `a` is of size 1.
+        If two arguments: the last argument is the value to be set
+        and must be a scalar, the first argument specifies a single array
+        element location. It is either an int or a tuple.
+
+    Notes
+    -----
+    Compared to indexing syntax, `itemset` provides some speed increase
+    for placing a scalar into a particular location in an `ndarray`,
+    if you must do this.  However, generally this is discouraged:
+    among other problems, it complicates the appearance of the code.
+    Also, when using `itemset` (and `item`) inside a loop, be sure
+    to assign the methods to a local variable to avoid the attribute
+    look-up at each loop iteration.
+
+    Examples
+    --------
+    >>> x = np.random.randint(9, size=(3, 3))
+    >>> x
+    array([[3, 1, 7],
+           [2, 8, 3],
+           [8, 5, 3]])
+    >>> x.itemset(4, 0)
+    >>> x.itemset((2, 2), 9)
+    >>> x
+    array([[3, 1, 7],
+           [2, 0, 3],
+           [8, 5, 9]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('max',
+    """
+    a.max(axis=None, out=None)
+
+    Return the maximum along a given axis.
+
+    Refer to `numpy.amax` for full documentation.
+
+    See Also
+    --------
+    numpy.amax : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('mean',
+    """
+    a.mean(axis=None, dtype=None, out=None, keepdims=False)
+
+    Returns the average of the array elements along given axis.
+
+    Refer to `numpy.mean` for full documentation.
+
+    See Also
+    --------
+    numpy.mean : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('min',
+    """
+    a.min(axis=None, out=None, keepdims=False)
+
+    Return the minimum along a given axis.
+
+    Refer to `numpy.amin` for full documentation.
+
+    See Also
+    --------
+    numpy.amin : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'shares_memory',
+    """
+    shares_memory(a, b, max_work=None)
+
+    Determine if two arrays share memory
+
+    Parameters
+    ----------
+    a, b : ndarray
+        Input arrays
+    max_work : int, optional
+        Effort to spend on solving the overlap problem (maximum number
+        of candidate solutions to consider). The following special
+        values are recognized:
+
+        max_work=MAY_SHARE_EXACT  (default)
+            The problem is solved exactly. In this case, the function returns
+            True only if there is an element shared between the arrays.
+        max_work=MAY_SHARE_BOUNDS
+            Only the memory bounds of a and b are checked.
+
+    Raises
+    ------
+    numpy.TooHardError
+        Exceeded max_work.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    may_share_memory
+
+    Examples
+    --------
+    >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9]))
+    False
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'may_share_memory',
+    """
+    may_share_memory(a, b, max_work=None)
+
+    Determine if two arrays might share memory
+
+    A return of True does not necessarily mean that the two arrays
+    share any element.  It just means that they *might*.
+
+    Only the memory bounds of a and b are checked by default.
+
+    Parameters
+    ----------
+    a, b : ndarray
+        Input arrays
+    max_work : int, optional
+        Effort to spend on solving the overlap problem.  See
+        `shares_memory` for details.  Default for ``may_share_memory``
+        is to do a bounds check.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    shares_memory
+
+    Examples
+    --------
+    >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9]))
+    False
+    >>> x = np.zeros([3, 4])
+    >>> np.may_share_memory(x[:,0], x[:,1])
+    True
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('newbyteorder',
+    """
+    arr.newbyteorder(new_order='S')
+
+    Return the array with the same data viewed with a different byte order.
+
+    Equivalent to::
+
+        arr.view(arr.dtype.newbytorder(new_order))
+
+    Changes are also made in all fields and sub-arrays of the array data
+    type.
+
+
+
+    Parameters
+    ----------
+    new_order : string, optional
+        Byte order to force; a value from the byte order specifications
+        below. `new_order` codes can be any of:
+
+        * 'S' - swap dtype from current to opposite endian
+        * {'<', 'L'} - little endian
+        * {'>', 'B'} - big endian
+        * {'=', 'N'} - native order
+        * {'|', 'I'} - ignore (no change to byte order)
+
+        The default value ('S') results in swapping the current
+        byte order. The code does a case-insensitive check on the first
+        letter of `new_order` for the alternatives above.  For example,
+        any of 'B' or 'b' or 'biggish' are valid to specify big-endian.
+
+
+    Returns
+    -------
+    new_arr : array
+        New array object with the dtype reflecting given change to the
+        byte order.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nonzero',
+    """
+    a.nonzero()
+
+    Return the indices of the elements that are non-zero.
+
+    Refer to `numpy.nonzero` for full documentation.
+
+    See Also
+    --------
+    numpy.nonzero : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('prod',
+    """
+    a.prod(axis=None, dtype=None, out=None, keepdims=False)
+
+    Return the product of the array elements over the given axis
+
+    Refer to `numpy.prod` for full documentation.
+
+    See Also
+    --------
+    numpy.prod : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ptp',
+    """
+    a.ptp(axis=None, out=None)
+
+    Peak to peak (maximum - minimum) value along a given axis.
+
+    Refer to `numpy.ptp` for full documentation.
+
+    See Also
+    --------
+    numpy.ptp : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('put',
+    """
+    a.put(indices, values, mode='raise')
+
+    Set ``a.flat[n] = values[n]`` for all `n` in indices.
+
+    Refer to `numpy.put` for full documentation.
+
+    See Also
+    --------
+    numpy.put : equivalent function
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'copyto',
+    """
+    copyto(dst, src, casting='same_kind', where=None)
+
+    Copies values from one array to another, broadcasting as necessary.
+
+    Raises a TypeError if the `casting` rule is violated, and if
+    `where` is provided, it selects which elements to copy.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dst : ndarray
+        The array into which values are copied.
+    src : array_like
+        The array from which values are copied.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur when copying.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    where : array_like of bool, optional
+        A boolean array which is broadcasted to match the dimensions
+        of `dst`, and selects elements to copy from `src` to `dst`
+        wherever it contains the value True.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'putmask',
+    """
+    putmask(a, mask, values)
+
+    Changes elements of an array based on conditional and input values.
+
+    Sets ``a.flat[n] = values[n]`` for each n where ``mask.flat[n]==True``.
+
+    If `values` is not the same size as `a` and `mask` then it will repeat.
+    This gives behavior different from ``a[mask] = values``.
+
+    Parameters
+    ----------
+    a : array_like
+        Target array.
+    mask : array_like
+        Boolean mask array. It has to be the same shape as `a`.
+    values : array_like
+        Values to put into `a` where `mask` is True. If `values` is smaller
+        than `a` it will be repeated.
+
+    See Also
+    --------
+    place, put, take, copyto
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> np.putmask(x, x>2, x**2)
+    >>> x
+    array([[ 0,  1,  2],
+           [ 9, 16, 25]])
+
+    If `values` is smaller than `a` it is repeated:
+
+    >>> x = np.arange(5)
+    >>> np.putmask(x, x>1, [-33, -44])
+    >>> x
+    array([  0,   1, -33, -44, -33])
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ravel',
+    """
+    a.ravel([order])
+
+    Return a flattened array.
+
+    Refer to `numpy.ravel` for full documentation.
+
+    See Also
+    --------
+    numpy.ravel : equivalent function
+
+    ndarray.flat : a flat iterator on the array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('repeat',
+    """
+    a.repeat(repeats, axis=None)
+
+    Repeat elements of an array.
+
+    Refer to `numpy.repeat` for full documentation.
+
+    See Also
+    --------
+    numpy.repeat : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('reshape',
+    """
+    a.reshape(shape, order='C')
+
+    Returns an array containing the same data with a new shape.
+
+    Refer to `numpy.reshape` for full documentation.
+
+    See Also
+    --------
+    numpy.reshape : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('resize',
+    """
+    a.resize(new_shape, refcheck=True)
+
+    Change shape and size of array in-place.
+
+    Parameters
+    ----------
+    new_shape : tuple of ints, or `n` ints
+        Shape of resized array.
+    refcheck : bool, optional
+        If False, reference count will not be checked. Default is True.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    ValueError
+        If `a` does not own its own data or references or views to it exist,
+        and the data memory must be changed.
+
+    SystemError
+        If the `order` keyword argument is specified. This behaviour is a
+        bug in NumPy.
+
+    See Also
+    --------
+    resize : Return a new array with the specified shape.
+
+    Notes
+    -----
+    This reallocates space for the data area if necessary.
+
+    Only contiguous arrays (data elements consecutive in memory) can be
+    resized.
+
+    The purpose of the reference count check is to make sure you
+    do not use this array as a buffer for another Python object and then
+    reallocate the memory. However, reference counts can increase in
+    other ways so if you are sure that you have not shared the memory
+    for this array with another Python object, then you may safely set
+    `refcheck` to False.
+
+    Examples
+    --------
+    Shrinking an array: array is flattened (in the order that the data are
+    stored in memory), resized, and reshaped:
+
+    >>> a = np.array([[0, 1], [2, 3]], order='C')
+    >>> a.resize((2, 1))
+    >>> a
+    array([[0],
+           [1]])
+
+    >>> a = np.array([[0, 1], [2, 3]], order='F')
+    >>> a.resize((2, 1))
+    >>> a
+    array([[0],
+           [2]])
+
+    Enlarging an array: as above, but missing entries are filled with zeros:
+
+    >>> b = np.array([[0, 1], [2, 3]])
+    >>> b.resize(2, 3) # new_shape parameter doesn't have to be a tuple
+    >>> b
+    array([[0, 1, 2],
+           [3, 0, 0]])
+
+    Referencing an array prevents resizing...
+
+    >>> c = a
+    >>> a.resize((1, 1))
+    Traceback (most recent call last):
+    ...
+    ValueError: cannot resize an array that has been referenced ...
+
+    Unless `refcheck` is False:
+
+    >>> a.resize((1, 1), refcheck=False)
+    >>> a
+    array([[0]])
+    >>> c
+    array([[0]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('round',
+    """
+    a.round(decimals=0, out=None)
+
+    Return `a` with each element rounded to the given number of decimals.
+
+    Refer to `numpy.around` for full documentation.
+
+    See Also
+    --------
+    numpy.around : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('searchsorted',
+    """
+    a.searchsorted(v, side='left', sorter=None)
+
+    Find indices where elements of v should be inserted in a to maintain order.
+
+    For full documentation, see `numpy.searchsorted`
+
+    See Also
+    --------
+    numpy.searchsorted : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setfield',
+    """
+    a.setfield(val, dtype, offset=0)
+
+    Put a value into a specified place in a field defined by a data-type.
+
+    Place `val` into `a`'s field defined by `dtype` and beginning `offset`
+    bytes into the field.
+
+    Parameters
+    ----------
+    val : object
+        Value to be placed in field.
+    dtype : dtype object
+        Data-type of the field in which to place `val`.
+    offset : int, optional
+        The number of bytes into the field at which to place `val`.
+
+    Returns
+    -------
+    None
+
+    See Also
+    --------
+    getfield
+
+    Examples
+    --------
+    >>> x = np.eye(3)
+    >>> x.getfield(np.float64)
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> x.setfield(3, np.int32)
+    >>> x.getfield(np.int32)
+    array([[3, 3, 3],
+           [3, 3, 3],
+           [3, 3, 3]])
+    >>> x
+    array([[  1.00000000e+000,   1.48219694e-323,   1.48219694e-323],
+           [  1.48219694e-323,   1.00000000e+000,   1.48219694e-323],
+           [  1.48219694e-323,   1.48219694e-323,   1.00000000e+000]])
+    >>> x.setfield(np.eye(3), np.int32)
+    >>> x
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags',
+    """
+    a.setflags(write=None, align=None, uic=None)
+
+    Set array flags WRITEABLE, ALIGNED, and UPDATEIFCOPY, respectively.
+
+    These Boolean-valued flags affect how numpy interprets the memory
+    area used by `a` (see Notes below). The ALIGNED flag can only
+    be set to True if the data is actually aligned according to the type.
+    The UPDATEIFCOPY flag can never be set to True. The flag WRITEABLE
+    can only be set to True if the array owns its own memory, or the
+    ultimate owner of the memory exposes a writeable buffer interface,
+    or is a string. (The exception for string is made so that unpickling
+    can be done without copying memory.)
+
+    Parameters
+    ----------
+    write : bool, optional
+        Describes whether or not `a` can be written to.
+    align : bool, optional
+        Describes whether or not `a` is aligned properly for its type.
+    uic : bool, optional
+        Describes whether or not `a` is a copy of another "base" array.
+
+    Notes
+    -----
+    Array flags provide information about how the memory area used
+    for the array is to be interpreted. There are 6 Boolean flags
+    in use, only three of which can be changed by the user:
+    UPDATEIFCOPY, WRITEABLE, and ALIGNED.
+
+    WRITEABLE (W) the data area can be written to;
+
+    ALIGNED (A) the data and strides are aligned appropriately for the hardware
+    (as determined by the compiler);
+
+    UPDATEIFCOPY (U) this array is a copy of some other array (referenced
+    by .base). When this array is deallocated, the base array will be
+    updated with the contents of this array.
+
+    All flags can be accessed using their first (upper case) letter as well
+    as the full name.
+
+    Examples
+    --------
+    >>> y
+    array([[3, 1, 7],
+           [2, 0, 0],
+           [8, 5, 9]])
+    >>> y.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : True
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+    >>> y.setflags(write=0, align=0)
+    >>> y.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : True
+      WRITEABLE : False
+      ALIGNED : False
+      UPDATEIFCOPY : False
+    >>> y.setflags(uic=1)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: cannot set UPDATEIFCOPY flag to True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
+    """
+    a.sort(axis=-1, kind='quicksort', order=None)
+
+    Sort an array, in-place.
+
+    Parameters
+    ----------
+    axis : int, optional
+        Axis along which to sort. Default is -1, which means sort along the
+        last axis.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm. Default is 'quicksort'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    See Also
+    --------
+    numpy.sort : Return a sorted copy of an array.
+    argsort : Indirect sort.
+    lexsort : Indirect stable sort on multiple keys.
+    searchsorted : Find elements in sorted array.
+    partition: Partial sort.
+
+    Notes
+    -----
+    See ``sort`` for notes on the different sorting algorithms.
+
+    Examples
+    --------
+    >>> a = np.array([[1,4], [3,1]])
+    >>> a.sort(axis=1)
+    >>> a
+    array([[1, 4],
+           [1, 3]])
+    >>> a.sort(axis=0)
+    >>> a
+    array([[1, 3],
+           [1, 4]])
+
+    Use the `order` keyword to specify a field to use when sorting a
+    structured array:
+
+    >>> a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)])
+    >>> a.sort(order='y')
+    >>> a
+    array([('c', 1), ('a', 2)],
+          dtype=[('x', '|S1'), ('y', '<i4')])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('partition',
+    """
+    a.partition(kth, axis=-1, kind='introselect', order=None)
+
+    Rearranges the elements in the array in such a way that value of the
+    element in kth position is in the position it would be in a sorted array.
+    All elements smaller than the kth element are moved before this element and
+    all equal or greater are moved behind it. The ordering of the elements in
+    the two partitions is undefined.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    kth : int or sequence of ints
+        Element index to partition by. The kth element value will be in its
+        final sorted position and all smaller elements will be moved before it
+        and all equal or greater elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all elements
+        indexed by kth of them into their sorted position at once.
+    axis : int, optional
+        Axis along which to sort. Default is -1, which means sort along the
+        last axis.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    See Also
+    --------
+    numpy.partition : Return a parititioned copy of an array.
+    argpartition : Indirect partition.
+    sort : Full sort.
+
+    Notes
+    -----
+    See ``np.partition`` for notes on the different algorithms.
+
+    Examples
+    --------
+    >>> a = np.array([3, 4, 2, 1])
+    >>> a.partition(a, 3)
+    >>> a
+    array([2, 1, 3, 4])
+
+    >>> a.partition((1, 3))
+    array([1, 2, 3, 4])
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('squeeze',
+    """
+    a.squeeze(axis=None)
+
+    Remove single-dimensional entries from the shape of `a`.
+
+    Refer to `numpy.squeeze` for full documentation.
+
+    See Also
+    --------
+    numpy.squeeze : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('std',
+    """
+    a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+
+    Returns the standard deviation of the array elements along given axis.
+
+    Refer to `numpy.std` for full documentation.
+
+    See Also
+    --------
+    numpy.std : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sum',
+    """
+    a.sum(axis=None, dtype=None, out=None, keepdims=False)
+
+    Return the sum of the array elements over the given axis.
+
+    Refer to `numpy.sum` for full documentation.
+
+    See Also
+    --------
+    numpy.sum : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('swapaxes',
+    """
+    a.swapaxes(axis1, axis2)
+
+    Return a view of the array with `axis1` and `axis2` interchanged.
+
+    Refer to `numpy.swapaxes` for full documentation.
+
+    See Also
+    --------
+    numpy.swapaxes : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('take',
+    """
+    a.take(indices, axis=None, out=None, mode='raise')
+
+    Return an array formed from the elements of `a` at the given indices.
+
+    Refer to `numpy.take` for full documentation.
+
+    See Also
+    --------
+    numpy.take : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile',
+    """
+    a.tofile(fid, sep="", format="%s")
+
+    Write array to a file as text or binary (default).
+
+    Data is always written in 'C' order, independent of the order of `a`.
+    The data produced by this method can be recovered using the function
+    fromfile().
+
+    Parameters
+    ----------
+    fid : file or str
+        An open file object, or a string containing a filename.
+    sep : str
+        Separator between array items for text output.
+        If "" (empty), a binary file is written, equivalent to
+        ``file.write(a.tobytes())``.
+    format : str
+        Format string for text file output.
+        Each entry in the array is formatted to text by first converting
+        it to the closest Python type, and then using "format" % item.
+
+    Notes
+    -----
+    This is a convenience function for quick storage of array data.
+    Information on endianness and precision is lost, so this method is not a
+    good choice for files intended to archive data or transport data between
+    machines with different endianness. Some of these problems can be overcome
+    by outputting the data as text files, at the expense of speed and file
+    size.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tolist',
+    """
+    a.tolist()
+
+    Return the array as a (possibly nested) list.
+
+    Return a copy of the array data as a (nested) Python list.
+    Data items are converted to the nearest compatible Python type.
+
+    Parameters
+    ----------
+    none
+
+    Returns
+    -------
+    y : list
+        The possibly nested list of array elements.
+
+    Notes
+    -----
+    The array may be recreated, ``a = np.array(a.tolist())``.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2])
+    >>> a.tolist()
+    [1, 2]
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> list(a)
+    [array([1, 2]), array([3, 4])]
+    >>> a.tolist()
+    [[1, 2], [3, 4]]
+
+    """))
+
+
+tobytesdoc = """
+    a.{name}(order='C')
+
+    Construct Python bytes containing the raw data bytes in the array.
+
+    Constructs Python bytes showing a copy of the raw contents of
+    data memory. The bytes object can be produced in either 'C' or 'Fortran',
+    or 'Any' order (the default is 'C'-order). 'Any' order means C-order
+    unless the F_CONTIGUOUS flag in the array is set, in which case it
+    means 'Fortran' order.
+
+    {deprecated}
+
+    Parameters
+    ----------
+    order : {{'C', 'F', None}}, optional
+        Order of the data for multidimensional arrays:
+        C, Fortran, or the same as for the original array.
+
+    Returns
+    -------
+    s : bytes
+        Python bytes exhibiting a copy of `a`'s raw data.
+
+    Examples
+    --------
+    >>> x = np.array([[0, 1], [2, 3]])
+    >>> x.tobytes()
+    b'\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+    >>> x.tobytes('C') == x.tobytes()
+    True
+    >>> x.tobytes('F')
+    b'\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+
+    """
+
+add_newdoc('numpy.core.multiarray', 'ndarray',
+           ('tostring', tobytesdoc.format(name='tostring',
+                                          deprecated=
+                                          'This function is a compatibility '
+                                          'alias for tobytes. Despite its '
+                                          'name it returns bytes not '
+                                          'strings.')))
+add_newdoc('numpy.core.multiarray', 'ndarray',
+           ('tobytes', tobytesdoc.format(name='tobytes',
+                                         deprecated='.. versionadded:: 1.9.0')))
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('trace',
+    """
+    a.trace(offset=0, axis1=0, axis2=1, dtype=None, out=None)
+
+    Return the sum along diagonals of the array.
+
+    Refer to `numpy.trace` for full documentation.
+
+    See Also
+    --------
+    numpy.trace : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose',
+    """
+    a.transpose(*axes)
+
+    Returns a view of the array with axes transposed.
+
+    For a 1-D array, this has no effect. (To change between column and
+    row vectors, first cast the 1-D array into a matrix object.)
+    For a 2-D array, this is the usual matrix transpose.
+    For an n-D array, if axes are given, their order indicates how the
+    axes are permuted (see Examples). If axes are not provided and
+    ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then
+    ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``.
+
+    Parameters
+    ----------
+    axes : None, tuple of ints, or `n` ints
+
+     * None or no argument: reverses the order of the axes.
+
+     * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s
+       `i`-th axis becomes `a.transpose()`'s `j`-th axis.
+
+     * `n` ints: same as an n-tuple of the same ints (this form is
+       intended simply as a "convenience" alternative to the tuple form)
+
+    Returns
+    -------
+    out : ndarray
+        View of `a`, with axes suitably permuted.
+
+    See Also
+    --------
+    ndarray.T : Array property returning the array transposed.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> a
+    array([[1, 2],
+           [3, 4]])
+    >>> a.transpose()
+    array([[1, 3],
+           [2, 4]])
+    >>> a.transpose((1, 0))
+    array([[1, 3],
+           [2, 4]])
+    >>> a.transpose(1, 0)
+    array([[1, 3],
+           [2, 4]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('var',
+    """
+    a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+
+    Returns the variance of the array elements, along given axis.
+
+    Refer to `numpy.var` for full documentation.
+
+    See Also
+    --------
+    numpy.var : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
+    """
+    a.view(dtype=None, type=None)
+
+    New view of array with the same data.
+
+    Parameters
+    ----------
+    dtype : data-type or ndarray sub-class, optional
+        Data-type descriptor of the returned view, e.g., float32 or int16. The
+        default, None, results in the view having the same data-type as `a`.
+        This argument can also be specified as an ndarray sub-class, which
+        then specifies the type of the returned object (this is equivalent to
+        setting the ``type`` parameter).
+    type : Python type, optional
+        Type of the returned view, e.g., ndarray or matrix.  Again, the
+        default None results in type preservation.
+
+    Notes
+    -----
+    ``a.view()`` is used two different ways:
+
+    ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
+    of the array's memory with a different data-type.  This can cause a
+    reinterpretation of the bytes of memory.
+
+    ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
+    returns an instance of `ndarray_subclass` that looks at the same array
+    (same shape, dtype, etc.)  This does not cause a reinterpretation of the
+    memory.
+
+    For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
+    bytes per entry than the previous dtype (for example, converting a
+    regular array to a structured array), then the behavior of the view
+    cannot be predicted just from the superficial appearance of ``a`` (shown
+    by ``print(a)``). It also depends on exactly how ``a`` is stored in
+    memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
+    defined as a slice or transpose, etc., the view may give different
+    results.
+
+
+    Examples
+    --------
+    >>> x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
+
+    Viewing array data using a different type and dtype:
+
+    >>> y = x.view(dtype=np.int16, type=np.matrix)
+    >>> y
+    matrix([[513]], dtype=int16)
+    >>> print(type(y))
+    <class 'numpy.matrixlib.defmatrix.matrix'>
+
+    Creating a view on a structured array so it can be used in calculations
+
+    >>> x = np.array([(1, 2),(3,4)], dtype=[('a', np.int8), ('b', np.int8)])
+    >>> xv = x.view(dtype=np.int8).reshape(-1,2)
+    >>> xv
+    array([[1, 2],
+           [3, 4]], dtype=int8)
+    >>> xv.mean(0)
+    array([ 2.,  3.])
+
+    Making changes to the view changes the underlying array
+
+    >>> xv[0,1] = 20
+    >>> print(x)
+    [(1, 20) (3, 4)]
+
+    Using a view to convert an array to a recarray:
+
+    >>> z = x.view(np.recarray)
+    >>> z.a
+    array([1], dtype=int8)
+
+    Views share data:
+
+    >>> x[0] = (9, 10)
+    >>> z[0]
+    (9, 10)
+
+    Views that change the dtype size (bytes per entry) should normally be
+    avoided on arrays defined by slices, transposes, fortran-ordering, etc.:
+
+    >>> x = np.array([[1,2,3],[4,5,6]], dtype=np.int16)
+    >>> y = x[:, 0:2]
+    >>> y
+    array([[1, 2],
+           [4, 5]], dtype=int16)
+    >>> y.view(dtype=[('width', np.int16), ('length', np.int16)])
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: new type not compatible with array.
+    >>> z = y.copy()
+    >>> z.view(dtype=[('width', np.int16), ('length', np.int16)])
+    array([[(1, 2)],
+           [(4, 5)]], dtype=[('width', '<i2'), ('length', '<i2')])
+    """))
+
+
+##############################################################################
+#
+# umath functions
+#
+##############################################################################
+
+add_newdoc('numpy.core.umath', 'frompyfunc',
+    """
+    frompyfunc(func, nin, nout)
+
+    Takes an arbitrary Python function and returns a Numpy ufunc.
+
+    Can be used, for example, to add broadcasting to a built-in Python
+    function (see Examples section).
+
+    Parameters
+    ----------
+    func : Python function object
+        An arbitrary Python function.
+    nin : int
+        The number of input arguments.
+    nout : int
+        The number of objects returned by `func`.
+
+    Returns
+    -------
+    out : ufunc
+        Returns a Numpy universal function (``ufunc``) object.
+
+    Notes
+    -----
+    The returned ufunc always returns PyObject arrays.
+
+    Examples
+    --------
+    Use frompyfunc to add broadcasting to the Python function ``oct``:
+
+    >>> oct_array = np.frompyfunc(oct, 1, 1)
+    >>> oct_array(np.array((10, 30, 100)))
+    array([012, 036, 0144], dtype=object)
+    >>> np.array((oct(10), oct(30), oct(100))) # for comparison
+    array(['012', '036', '0144'],
+          dtype='|S4')
+
+    """)
+
+add_newdoc('numpy.core.umath', 'geterrobj',
+    """
+    geterrobj()
+
+    Return the current object that defines floating-point error handling.
+
+    The error object contains all information that defines the error handling
+    behavior in Numpy. `geterrobj` is used internally by the other
+    functions that get and set error handling behavior (`geterr`, `seterr`,
+    `geterrcall`, `seterrcall`).
+
+    Returns
+    -------
+    errobj : list
+        The error object, a list containing three elements:
+        [internal numpy buffer size, error mask, error callback function].
+
+        The error mask is a single integer that holds the treatment information
+        on all four floating point errors. The information for each error type
+        is contained in three bits of the integer. If we print it in base 8, we
+        can see what treatment is set for "invalid", "under", "over", and
+        "divide" (in that order). The printed string can be interpreted with
+
+        * 0 : 'ignore'
+        * 1 : 'warn'
+        * 2 : 'raise'
+        * 3 : 'call'
+        * 4 : 'print'
+        * 5 : 'log'
+
+    See Also
+    --------
+    seterrobj, seterr, geterr, seterrcall, geterrcall
+    getbufsize, setbufsize
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterrobj()  # first get the defaults
+    [10000, 0, None]
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+    >>> old_bufsize = np.setbufsize(20000)
+    >>> old_err = np.seterr(divide='raise')
+    >>> old_handler = np.seterrcall(err_handler)
+    >>> np.geterrobj()
+    [20000, 2, <function err_handler at 0x91dcaac>]
+
+    >>> old_err = np.seterr(all='ignore')
+    >>> np.base_repr(np.geterrobj()[1], 8)
+    '0'
+    >>> old_err = np.seterr(divide='warn', over='log', under='call',
+                            invalid='print')
+    >>> np.base_repr(np.geterrobj()[1], 8)
+    '4351'
+
+    """)
+
+add_newdoc('numpy.core.umath', 'seterrobj',
+    """
+    seterrobj(errobj)
+
+    Set the object that defines floating-point error handling.
+
+    The error object contains all information that defines the error handling
+    behavior in Numpy. `seterrobj` is used internally by the other
+    functions that set error handling behavior (`seterr`, `seterrcall`).
+
+    Parameters
+    ----------
+    errobj : list
+        The error object, a list containing three elements:
+        [internal numpy buffer size, error mask, error callback function].
+
+        The error mask is a single integer that holds the treatment information
+        on all four floating point errors. The information for each error type
+        is contained in three bits of the integer. If we print it in base 8, we
+        can see what treatment is set for "invalid", "under", "over", and
+        "divide" (in that order). The printed string can be interpreted with
+
+        * 0 : 'ignore'
+        * 1 : 'warn'
+        * 2 : 'raise'
+        * 3 : 'call'
+        * 4 : 'print'
+        * 5 : 'log'
+
+    See Also
+    --------
+    geterrobj, seterr, geterr, seterrcall, geterrcall
+    getbufsize, setbufsize
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> old_errobj = np.geterrobj()  # first get the defaults
+    >>> old_errobj
+    [10000, 0, None]
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+    >>> new_errobj = [20000, 12, err_handler]
+    >>> np.seterrobj(new_errobj)
+    >>> np.base_repr(12, 8)  # int for divide=4 ('print') and over=1 ('warn')
+    '14'
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'print', 'invalid': 'ignore', 'under': 'ignore'}
+    >>> np.geterrcall() is err_handler
+    True
+
+    """)
+
+
+##############################################################################
+#
+# compiled_base functions
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'digitize',
+    """
+    digitize(x, bins, right=False)
+
+    Return the indices of the bins to which each value in input array belongs.
+
+    Each index ``i`` returned is such that ``bins[i-1] <= x < bins[i]`` if
+    `bins` is monotonically increasing, or ``bins[i-1] > x >= bins[i]`` if
+    `bins` is monotonically decreasing. If values in `x` are beyond the
+    bounds of `bins`, 0 or ``len(bins)`` is returned as appropriate. If right
+    is True, then the right bin is closed so that the index ``i`` is such
+    that ``bins[i-1] < x <= bins[i]`` or bins[i-1] >= x > bins[i]`` if `bins`
+    is monotonically increasing or decreasing, respectively.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array to be binned. Prior to Numpy 1.10.0, this array had to
+        be 1-dimensional, but can now have any shape.
+    bins : array_like
+        Array of bins. It has to be 1-dimensional and monotonic.
+    right : bool, optional
+        Indicating whether the intervals include the right or the left bin
+        edge. Default behavior is (right==False) indicating that the interval
+        does not include the right edge. The left bin end is open in this
+        case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
+        monotonically increasing bins.
+
+    Returns
+    -------
+    out : ndarray of ints
+        Output array of indices, of same shape as `x`.
+
+    Raises
+    ------
+    ValueError
+        If `bins` is not monotonic.
+    TypeError
+        If the type of the input is complex.
+
+    See Also
+    --------
+    bincount, histogram, unique
+
+    Notes
+    -----
+    If values in `x` are such that they fall outside the bin range,
+    attempting to index `bins` with the indices that `digitize` returns
+    will result in an IndexError.
+
+    .. versionadded:: 1.10.0
+
+    `np.digitize` is  implemented in terms of `np.searchsorted`. This means
+    that a binary search is used to bin the values, which scales much better
+    for larger number of bins than the previous linear search. It also removes
+    the requirement for the input array to be 1-dimensional.
+
+    Examples
+    --------
+    >>> x = np.array([0.2, 6.4, 3.0, 1.6])
+    >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
+    >>> inds = np.digitize(x, bins)
+    >>> inds
+    array([1, 4, 3, 2])
+    >>> for n in range(x.size):
+    ...   print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
+    ...
+    0.0 <= 0.2 < 1.0
+    4.0 <= 6.4 < 10.0
+    2.5 <= 3.0 < 4.0
+    1.0 <= 1.6 < 2.5
+
+    >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
+    >>> bins = np.array([0, 5, 10, 15, 20])
+    >>> np.digitize(x,bins,right=True)
+    array([1, 2, 3, 4, 4])
+    >>> np.digitize(x,bins,right=False)
+    array([1, 3, 3, 4, 5])
+    """)
+
+add_newdoc('numpy.core.multiarray', 'bincount',
+    """
+    bincount(x, weights=None, minlength=None)
+
+    Count number of occurrences of each value in array of non-negative ints.
+
+    The number of bins (of size 1) is one larger than the largest value in
+    `x`. If `minlength` is specified, there will be at least this number
+    of bins in the output array (though it will be longer if necessary,
+    depending on the contents of `x`).
+    Each bin gives the number of occurrences of its index value in `x`.
+    If `weights` is specified the input array is weighted by it, i.e. if a
+    value ``n`` is found at position ``i``, ``out[n] += weight[i]`` instead
+    of ``out[n] += 1``.
+
+    Parameters
+    ----------
+    x : array_like, 1 dimension, nonnegative ints
+        Input array.
+    weights : array_like, optional
+        Weights, array of the same shape as `x`.
+    minlength : int, optional
+        A minimum number of bins for the output array.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    out : ndarray of ints
+        The result of binning the input array.
+        The length of `out` is equal to ``np.amax(x)+1``.
+
+    Raises
+    ------
+    ValueError
+        If the input is not 1-dimensional, or contains elements with negative
+        values, or if `minlength` is non-positive.
+    TypeError
+        If the type of the input is float or complex.
+
+    See Also
+    --------
+    histogram, digitize, unique
+
+    Examples
+    --------
+    >>> np.bincount(np.arange(5))
+    array([1, 1, 1, 1, 1])
+    >>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
+    array([1, 3, 1, 1, 0, 0, 0, 1])
+
+    >>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23])
+    >>> np.bincount(x).size == np.amax(x)+1
+    True
+
+    The input array needs to be of integer dtype, otherwise a
+    TypeError is raised:
+
+    >>> np.bincount(np.arange(5, dtype=np.float))
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    TypeError: array cannot be safely cast to required type
+
+    A possible use of ``bincount`` is to perform sums over
+    variable-size chunks of an array, using the ``weights`` keyword.
+
+    >>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights
+    >>> x = np.array([0, 1, 1, 2, 2, 2])
+    >>> np.bincount(x,  weights=w)
+    array([ 0.3,  0.7,  1.1])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'ravel_multi_index',
+    """
+    ravel_multi_index(multi_index, dims, mode='raise', order='C')
+
+    Converts a tuple of index arrays into an array of flat
+    indices, applying boundary modes to the multi-index.
+
+    Parameters
+    ----------
+    multi_index : tuple of array_like
+        A tuple of integer arrays, one array for each dimension.
+    dims : tuple of ints
+        The shape of array into which the indices from ``multi_index`` apply.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices are handled.  Can specify
+        either one mode or a tuple of modes, one mode per index.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        In 'clip' mode, a negative index which would normally
+        wrap will clip to 0 instead.
+    order : {'C', 'F'}, optional
+        Determines whether the multi-index should be viewed as
+        indexing in row-major (C-style) or column-major
+        (Fortran-style) order.
+
+    Returns
+    -------
+    raveled_indices : ndarray
+        An array of indices into the flattened version of an array
+        of dimensions ``dims``.
+
+    See Also
+    --------
+    unravel_index
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    Examples
+    --------
+    >>> arr = np.array([[3,6,6],[4,5,1]])
+    >>> np.ravel_multi_index(arr, (7,6))
+    array([22, 41, 37])
+    >>> np.ravel_multi_index(arr, (7,6), order='F')
+    array([31, 41, 13])
+    >>> np.ravel_multi_index(arr, (4,6), mode='clip')
+    array([22, 23, 19])
+    >>> np.ravel_multi_index(arr, (4,4), mode=('clip','wrap'))
+    array([12, 13, 13])
+
+    >>> np.ravel_multi_index((3,1,4,1), (6,7,8,9))
+    1621
+    """)
+
+add_newdoc('numpy.core.multiarray', 'unravel_index',
+    """
+    unravel_index(indices, dims, order='C')
+
+    Converts a flat index or array of flat indices into a tuple
+    of coordinate arrays.
+
+    Parameters
+    ----------
+    indices : array_like
+        An integer array whose elements are indices into the flattened
+        version of an array of dimensions ``dims``. Before version 1.6.0,
+        this function accepted just one index value.
+    dims : tuple of ints
+        The shape of the array to use for unraveling ``indices``.
+    order : {'C', 'F'}, optional
+        Determines whether the indices should be viewed as indexing in
+        row-major (C-style) or column-major (Fortran-style) order.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    unraveled_coords : tuple of ndarray
+        Each array in the tuple has the same shape as the ``indices``
+        array.
+
+    See Also
+    --------
+    ravel_multi_index
+
+    Examples
+    --------
+    >>> np.unravel_index([22, 41, 37], (7,6))
+    (array([3, 6, 6]), array([4, 5, 1]))
+    >>> np.unravel_index([31, 41, 13], (7,6), order='F')
+    (array([3, 6, 6]), array([4, 5, 1]))
+
+    >>> np.unravel_index(1621, (6,7,8,9))
+    (3, 1, 4, 1)
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'add_docstring',
+    """
+    add_docstring(obj, docstring)
+
+    Add a docstring to a built-in obj if possible.
+    If the obj already has a docstring raise a RuntimeError
+    If this routine does not know how to add a docstring to the object
+    raise a TypeError
+    """)
+
+add_newdoc('numpy.core.umath', '_add_newdoc_ufunc',
+    """
+    add_ufunc_docstring(ufunc, new_docstring)
+
+    Replace the docstring for a ufunc with new_docstring.
+    This method will only work if the current docstring for
+    the ufunc is NULL. (At the C level, i.e. when ufunc->doc is NULL.)
+
+    Parameters
+    ----------
+    ufunc : numpy.ufunc
+        A ufunc whose current doc is NULL.
+    new_docstring : string
+        The new docstring for the ufunc.
+
+    Notes
+    -----
+    This method allocates memory for new_docstring on
+    the heap. Technically this creates a mempory leak, since this
+    memory will not be reclaimed until the end of the program
+    even if the ufunc itself is removed. However this will only
+    be a problem if the user is repeatedly creating ufuncs with
+    no documentation, adding documentation via add_newdoc_ufunc,
+    and then throwing away the ufunc.
+    """)
+
+add_newdoc('numpy.core.multiarray', 'packbits',
+    """
+    packbits(myarray, axis=None)
+
+    Packs the elements of a binary-valued array into bits in a uint8 array.
+
+    The result is padded to full bytes by inserting zero bits at the end.
+
+    Parameters
+    ----------
+    myarray : array_like
+        An integer type array whose elements should be packed to bits.
+    axis : int, optional
+        The dimension over which bit-packing is done.
+        ``None`` implies packing the flattened array.
+
+    Returns
+    -------
+    packed : ndarray
+        Array of type uint8 whose elements represent bits corresponding to the
+        logical (0 or nonzero) value of the input elements. The shape of
+        `packed` has the same number of dimensions as the input (unless `axis`
+        is None, in which case the output is 1-D).
+
+    See Also
+    --------
+    unpackbits: Unpacks elements of a uint8 array into a binary-valued output
+                array.
+
+    Examples
+    --------
+    >>> a = np.array([[[1,0,1],
+    ...                [0,1,0]],
+    ...               [[1,1,0],
+    ...                [0,0,1]]])
+    >>> b = np.packbits(a, axis=-1)
+    >>> b
+    array([[[160],[64]],[[192],[32]]], dtype=uint8)
+
+    Note that in binary 160 = 1010 0000, 64 = 0100 0000, 192 = 1100 0000,
+    and 32 = 0010 0000.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'unpackbits',
+    """
+    unpackbits(myarray, axis=None)
+
+    Unpacks elements of a uint8 array into a binary-valued output array.
+
+    Each element of `myarray` represents a bit-field that should be unpacked
+    into a binary-valued output array. The shape of the output array is either
+    1-D (if `axis` is None) or the same shape as the input array with unpacking
+    done along the axis specified.
+
+    Parameters
+    ----------
+    myarray : ndarray, uint8 type
+       Input array.
+    axis : int, optional
+       Unpacks along this axis.
+
+    Returns
+    -------
+    unpacked : ndarray, uint8 type
+       The elements are binary-valued (0 or 1).
+
+    See Also
+    --------
+    packbits : Packs the elements of a binary-valued array into bits in a uint8
+               array.
+
+    Examples
+    --------
+    >>> a = np.array([[2], [7], [23]], dtype=np.uint8)
+    >>> a
+    array([[ 2],
+           [ 7],
+           [23]], dtype=uint8)
+    >>> b = np.unpackbits(a, axis=1)
+    >>> b
+    array([[0, 0, 0, 0, 0, 0, 1, 0],
+           [0, 0, 0, 0, 0, 1, 1, 1],
+           [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for ufunc attributes and methods
+#
+##############################################################################
+
+
+##############################################################################
+#
+# ufunc object
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc',
+    """
+    Functions that operate element by element on whole arrays.
+
+    To see the documentation for a specific ufunc, use np.info().  For
+    example, np.info(np.sin).  Because ufuncs are written in C
+    (for speed) and linked into Python with NumPy's ufunc facility,
+    Python's help() function finds this page whenever help() is called
+    on a ufunc.
+
+    A detailed explanation of ufuncs can be found in the "ufuncs.rst"
+    file in the NumPy reference guide.
+
+    Unary ufuncs:
+    =============
+
+    op(X, out=None)
+    Apply op to X elementwise
+
+    Parameters
+    ----------
+    X : array_like
+        Input array.
+    out : array_like
+        An array to store the output. Must be the same shape as `X`.
+
+    Returns
+    -------
+    r : array_like
+        `r` will have the same shape as `X`; if out is provided, `r`
+        will be equal to out.
+
+    Binary ufuncs:
+    ==============
+
+    op(X, Y, out=None)
+    Apply `op` to `X` and `Y` elementwise. May "broadcast" to make
+    the shapes of `X` and `Y` congruent.
+
+    The broadcasting rules are:
+
+    * Dimensions of length 1 may be prepended to either array.
+    * Arrays may be repeated along dimensions of length 1.
+
+    Parameters
+    ----------
+    X : array_like
+        First input array.
+    Y : array_like
+        Second input array.
+    out : array_like
+        An array to store the output. Must be the same shape as the
+        output would have.
+
+    Returns
+    -------
+    r : array_like
+        The return value; if out is provided, `r` will be equal to out.
+
+    """)
+
+
+##############################################################################
+#
+# ufunc attributes
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc', ('identity',
+    """
+    The identity value.
+
+    Data attribute containing the identity element for the ufunc, if it has one.
+    If it does not, the attribute value is None.
+
+    Examples
+    --------
+    >>> np.add.identity
+    0
+    >>> np.multiply.identity
+    1
+    >>> np.power.identity
+    1
+    >>> print(np.exp.identity)
+    None
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nargs',
+    """
+    The number of arguments.
+
+    Data attribute containing the number of arguments the ufunc takes, including
+    optional ones.
+
+    Notes
+    -----
+    Typically this value will be one more than what you might expect because all
+    ufuncs take  the optional "out" argument.
+
+    Examples
+    --------
+    >>> np.add.nargs
+    3
+    >>> np.multiply.nargs
+    3
+    >>> np.power.nargs
+    3
+    >>> np.exp.nargs
+    2
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nin',
+    """
+    The number of inputs.
+
+    Data attribute containing the number of arguments the ufunc treats as input.
+
+    Examples
+    --------
+    >>> np.add.nin
+    2
+    >>> np.multiply.nin
+    2
+    >>> np.power.nin
+    2
+    >>> np.exp.nin
+    1
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nout',
+    """
+    The number of outputs.
+
+    Data attribute containing the number of arguments the ufunc treats as output.
+
+    Notes
+    -----
+    Since all ufuncs can take output arguments, this will always be (at least) 1.
+
+    Examples
+    --------
+    >>> np.add.nout
+    1
+    >>> np.multiply.nout
+    1
+    >>> np.power.nout
+    1
+    >>> np.exp.nout
+    1
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('ntypes',
+    """
+    The number of types.
+
+    The number of numerical NumPy types - of which there are 18 total - on which
+    the ufunc can operate.
+
+    See Also
+    --------
+    numpy.ufunc.types
+
+    Examples
+    --------
+    >>> np.add.ntypes
+    18
+    >>> np.multiply.ntypes
+    18
+    >>> np.power.ntypes
+    17
+    >>> np.exp.ntypes
+    7
+    >>> np.remainder.ntypes
+    14
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('types',
+    """
+    Returns a list with types grouped input->output.
+
+    Data attribute listing the data-type "Domain-Range" groupings the ufunc can
+    deliver. The data-types are given using the character codes.
+
+    See Also
+    --------
+    numpy.ufunc.ntypes
+
+    Examples
+    --------
+    >>> np.add.types
+    ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l',
+    'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D',
+    'GG->G', 'OO->O']
+
+    >>> np.multiply.types
+    ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l',
+    'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D',
+    'GG->G', 'OO->O']
+
+    >>> np.power.types
+    ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
+    'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G',
+    'OO->O']
+
+    >>> np.exp.types
+    ['f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O']
+
+    >>> np.remainder.types
+    ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
+    'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'OO->O']
+
+    """))
+
+
+##############################################################################
+#
+# ufunc methods
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc', ('reduce',
+    """
+    reduce(a, axis=0, dtype=None, out=None, keepdims=False)
+
+    Reduces `a`'s dimension by one, by applying ufunc along one axis.
+
+    Let :math:`a.shape = (N_0, ..., N_i, ..., N_{M-1})`.  Then
+    :math:`ufunc.reduce(a, axis=i)[k_0, ..,k_{i-1}, k_{i+1}, .., k_{M-1}]` =
+    the result of iterating `j` over :math:`range(N_i)`, cumulatively applying
+    ufunc to each :math:`a[k_0, ..,k_{i-1}, j, k_{i+1}, .., k_{M-1}]`.
+    For a one-dimensional array, reduce produces results equivalent to:
+    ::
+
+     r = op.identity # op = ufunc
+     for i in range(len(A)):
+       r = op(r, A[i])
+     return r
+
+    For example, add.reduce() is equivalent to sum().
+
+    Parameters
+    ----------
+    a : array_like
+        The array to act on.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a reduction is performed.
+        The default (`axis` = 0) is perform a reduction over the first
+        dimension of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is `None`, a reduction is performed over all the axes.
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+
+        For operations which are either not commutative or not associative,
+        doing a reduction over multiple axes is not well-defined. The
+        ufuncs do not currently raise an exception in this case, but will
+        likely do so in the future.
+    dtype : data-type code, optional
+        The type used to represent the intermediate results. Defaults
+        to the data-type of the output array if this is provided, or
+        the data-type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided, a
+        freshly-allocated array is returned.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    r : ndarray
+        The reduced array. If `out` was supplied, `r` is a reference to it.
+
+    Examples
+    --------
+    >>> np.multiply.reduce([2,3,5])
+    30
+
+    A multi-dimensional array example:
+
+    >>> X = np.arange(8).reshape((2,2,2))
+    >>> X
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+    >>> np.add.reduce(X, 0)
+    array([[ 4,  6],
+           [ 8, 10]])
+    >>> np.add.reduce(X) # confirm: default axis value is 0
+    array([[ 4,  6],
+           [ 8, 10]])
+    >>> np.add.reduce(X, 1)
+    array([[ 2,  4],
+           [10, 12]])
+    >>> np.add.reduce(X, 2)
+    array([[ 1,  5],
+           [ 9, 13]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('accumulate',
+    """
+    accumulate(array, axis=0, dtype=None, out=None)
+
+    Accumulate the result of applying the operator to all elements.
+
+    For a one-dimensional array, accumulate produces results equivalent to::
+
+      r = np.empty(len(A))
+      t = op.identity        # op = the ufunc being applied to A's  elements
+      for i in range(len(A)):
+          t = op(t, A[i])
+          r[i] = t
+      return r
+
+    For example, add.accumulate() is equivalent to np.cumsum().
+
+    For a multi-dimensional array, accumulate is applied along only one
+    axis (axis zero by default; see Examples below) so repeated use is
+    necessary if one wants to accumulate over multiple axes.
+
+    Parameters
+    ----------
+    array : array_like
+        The array to act on.
+    axis : int, optional
+        The axis along which to apply the accumulation; default is zero.
+    dtype : data-type code, optional
+        The data-type used to represent the intermediate results. Defaults
+        to the data-type of the output array if such is provided, or the
+        the data-type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided a
+        freshly-allocated array is returned.
+
+    Returns
+    -------
+    r : ndarray
+        The accumulated values. If `out` was supplied, `r` is a reference to
+        `out`.
+
+    Examples
+    --------
+    1-D array examples:
+
+    >>> np.add.accumulate([2, 3, 5])
+    array([ 2,  5, 10])
+    >>> np.multiply.accumulate([2, 3, 5])
+    array([ 2,  6, 30])
+
+    2-D array examples:
+
+    >>> I = np.eye(2)
+    >>> I
+    array([[ 1.,  0.],
+           [ 0.,  1.]])
+
+    Accumulate along axis 0 (rows), down columns:
+
+    >>> np.add.accumulate(I, 0)
+    array([[ 1.,  0.],
+           [ 1.,  1.]])
+    >>> np.add.accumulate(I) # no axis specified = axis zero
+    array([[ 1.,  0.],
+           [ 1.,  1.]])
+
+    Accumulate along axis 1 (columns), through rows:
+
+    >>> np.add.accumulate(I, 1)
+    array([[ 1.,  1.],
+           [ 0.,  1.]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('reduceat',
+    """
+    reduceat(a, indices, axis=0, dtype=None, out=None)
+
+    Performs a (local) reduce with specified slices over a single axis.
+
+    For i in ``range(len(indices))``, `reduceat` computes
+    ``ufunc.reduce(a[indices[i]:indices[i+1]])``, which becomes the i-th
+    generalized "row" parallel to `axis` in the final result (i.e., in a
+    2-D array, for example, if `axis = 0`, it becomes the i-th row, but if
+    `axis = 1`, it becomes the i-th column).  There are three exceptions to this:
+
+    * when ``i = len(indices) - 1`` (so for the last index),
+      ``indices[i+1] = a.shape[axis]``.
+    * if ``indices[i] >= indices[i + 1]``, the i-th generalized "row" is
+      simply ``a[indices[i]]``.
+    * if ``indices[i] >= len(a)`` or ``indices[i] < 0``, an error is raised.
+
+    The shape of the output depends on the size of `indices`, and may be
+    larger than `a` (this happens if ``len(indices) > a.shape[axis]``).
+
+    Parameters
+    ----------
+    a : array_like
+        The array to act on.
+    indices : array_like
+        Paired indices, comma separated (not colon), specifying slices to
+        reduce.
+    axis : int, optional
+        The axis along which to apply the reduceat.
+    dtype : data-type code, optional
+        The type used to represent the intermediate results. Defaults
+        to the data type of the output array if this is provided, or
+        the data type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided a
+        freshly-allocated array is returned.
+
+    Returns
+    -------
+    r : ndarray
+        The reduced values. If `out` was supplied, `r` is a reference to
+        `out`.
+
+    Notes
+    -----
+    A descriptive example:
+
+    If `a` is 1-D, the function `ufunc.accumulate(a)` is the same as
+    ``ufunc.reduceat(a, indices)[::2]`` where `indices` is
+    ``range(len(array) - 1)`` with a zero placed
+    in every other element:
+    ``indices = zeros(2 * len(a) - 1)``, ``indices[1::2] = range(1, len(a))``.
+
+    Don't be fooled by this attribute's name: `reduceat(a)` is not
+    necessarily smaller than `a`.
+
+    Examples
+    --------
+    To take the running sum of four successive values:
+
+    >>> np.add.reduceat(np.arange(8),[0,4, 1,5, 2,6, 3,7])[::2]
+    array([ 6, 10, 14, 18])
+
+    A 2-D example:
+
+    >>> x = np.linspace(0, 15, 16).reshape(4,4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+
+    ::
+
+     # reduce such that the result has the following five rows:
+     # [row1 + row2 + row3]
+     # [row4]
+     # [row2]
+     # [row3]
+     # [row1 + row2 + row3 + row4]
+
+    >>> np.add.reduceat(x, [0, 3, 1, 2, 0])
+    array([[ 12.,  15.,  18.,  21.],
+           [ 12.,  13.,  14.,  15.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 24.,  28.,  32.,  36.]])
+
+    ::
+
+     # reduce such that result has the following two columns:
+     # [col1 * col2 * col3, col4]
+
+    >>> np.multiply.reduceat(x, [0, 3], 1)
+    array([[    0.,     3.],
+           [  120.,     7.],
+           [  720.,    11.],
+           [ 2184.,    15.]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('outer',
+    """
+    outer(A, B)
+
+    Apply the ufunc `op` to all pairs (a, b) with a in `A` and b in `B`.
+
+    Let ``M = A.ndim``, ``N = B.ndim``. Then the result, `C`, of
+    ``op.outer(A, B)`` is an array of dimension M + N such that:
+
+    .. math:: C[i_0, ..., i_{M-1}, j_0, ..., j_{N-1}] =
+       op(A[i_0, ..., i_{M-1}], B[j_0, ..., j_{N-1}])
+
+    For `A` and `B` one-dimensional, this is equivalent to::
+
+      r = empty(len(A),len(B))
+      for i in range(len(A)):
+          for j in range(len(B)):
+              r[i,j] = op(A[i], B[j]) # op = ufunc in question
+
+    Parameters
+    ----------
+    A : array_like
+        First array
+    B : array_like
+        Second array
+
+    Returns
+    -------
+    r : ndarray
+        Output array
+
+    See Also
+    --------
+    numpy.outer
+
+    Examples
+    --------
+    >>> np.multiply.outer([1, 2, 3], [4, 5, 6])
+    array([[ 4,  5,  6],
+           [ 8, 10, 12],
+           [12, 15, 18]])
+
+    A multi-dimensional example:
+
+    >>> A = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> A.shape
+    (2, 3)
+    >>> B = np.array([[1, 2, 3, 4]])
+    >>> B.shape
+    (1, 4)
+    >>> C = np.multiply.outer(A, B)
+    >>> C.shape; C
+    (2, 3, 1, 4)
+    array([[[[ 1,  2,  3,  4]],
+            [[ 2,  4,  6,  8]],
+            [[ 3,  6,  9, 12]]],
+           [[[ 4,  8, 12, 16]],
+            [[ 5, 10, 15, 20]],
+            [[ 6, 12, 18, 24]]]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('at',
+    """
+    at(a, indices, b=None)
+
+    Performs unbuffered in place operation on operand 'a' for elements
+    specified by 'indices'. For addition ufunc, this method is equivalent to
+    `a[indices] += b`, except that results are accumulated for elements that
+    are indexed more than once. For example, `a[[0,0]] += 1` will only
+    increment the first element once because of buffering, whereas
+    `add.at(a, [0,0], 1)` will increment the first element twice.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        The array to perform in place operation on.
+    indices : array_like or tuple
+        Array like index object or slice object for indexing into first
+        operand. If first operand has multiple dimensions, indices can be a
+        tuple of array like index objects or slice objects.
+    b : array_like
+        Second operand for ufuncs requiring two operands. Operand must be
+        broadcastable over first operand after indexing or slicing.
+
+    Examples
+    --------
+    Set items 0 and 1 to their negative values:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> np.negative.at(a, [0, 1])
+    >>> print(a)
+    array([-1, -2, 3, 4])
+
+    ::
+
+    Increment items 0 and 1, and increment item 2 twice:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> np.add.at(a, [0, 1, 2, 2], 1)
+    >>> print(a)
+    array([2, 3, 5, 4])
+
+    ::
+
+    Add items 0 and 1 in first array to second array,
+    and store results in first array:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> b = np.array([1, 2])
+    >>> np.add.at(a, [0, 1], b)
+    >>> print(a)
+    array([2, 4, 3, 4])
+
+    """))
+
+##############################################################################
+#
+# Documentation for dtype attributes and methods
+#
+##############################################################################
+
+##############################################################################
+#
+# dtype object
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype',
+    """
+    dtype(obj, align=False, copy=False)
+
+    Create a data type object.
+
+    A numpy array is homogeneous, and contains elements described by a
+    dtype object. A dtype object can be constructed from different
+    combinations of fundamental numeric types.
+
+    Parameters
+    ----------
+    obj
+        Object to be converted to a data type object.
+    align : bool, optional
+        Add padding to the fields to match what a C compiler would output
+        for a similar C-struct. Can be ``True`` only if `obj` is a dictionary
+        or a comma-separated string. If a struct dtype is being created,
+        this also sets a sticky alignment flag ``isalignedstruct``.
+    copy : bool, optional
+        Make a new copy of the data-type object. If ``False``, the result
+        may just be a reference to a built-in data-type object.
+
+    See also
+    --------
+    result_type
+
+    Examples
+    --------
+    Using array-scalar type:
+
+    >>> np.dtype(np.int16)
+    dtype('int16')
+
+    Structured type, one field name 'f1', containing int16:
+
+    >>> np.dtype([('f1', np.int16)])
+    dtype([('f1', '<i2')])
+
+    Structured type, one field named 'f1', in itself containing a structured
+    type with one field:
+
+    >>> np.dtype([('f1', [('f1', np.int16)])])
+    dtype([('f1', [('f1', '<i2')])])
+
+    Structured type, two fields: the first field contains an unsigned int, the
+    second an int32:
+
+    >>> np.dtype([('f1', np.uint), ('f2', np.int32)])
+    dtype([('f1', '<u4'), ('f2', '<i4')])
+
+    Using array-protocol type strings:
+
+    >>> np.dtype([('a','f8'),('b','S10')])
+    dtype([('a', '<f8'), ('b', '|S10')])
+
+    Using comma-separated field formats.  The shape is (2,3):
+
+    >>> np.dtype("i4, (2,3)f8")
+    dtype([('f0', '<i4'), ('f1', '<f8', (2, 3))])
+
+    Using tuples.  ``int`` is a fixed type, 3 the field's shape.  ``void``
+    is a flexible type, here of size 10:
+
+    >>> np.dtype([('hello',(np.int,3)),('world',np.void,10)])
+    dtype([('hello', '<i4', 3), ('world', '|V10')])
+
+    Subdivide ``int16`` into 2 ``int8``'s, called x and y.  0 and 1 are
+    the offsets in bytes:
+
+    >>> np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)}))
+    dtype(('<i2', [('x', '|i1'), ('y', '|i1')]))
+
+    Using dictionaries.  Two fields named 'gender' and 'age':
+
+    >>> np.dtype({'names':['gender','age'], 'formats':['S1',np.uint8]})
+    dtype([('gender', '|S1'), ('age', '|u1')])
+
+    Offsets in bytes, here 0 and 25:
+
+    >>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)})
+    dtype([('surname', '|S25'), ('age', '|u1')])
+
+    """)
+
+##############################################################################
+#
+# dtype attributes
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('alignment',
+    """
+    The required alignment (bytes) of this data-type according to the compiler.
+
+    More information is available in the C-API section of the manual.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('byteorder',
+    """
+    A character indicating the byte-order of this data-type object.
+
+    One of:
+
+    ===  ==============
+    '='  native
+    '<'  little-endian
+    '>'  big-endian
+    '|'  not applicable
+    ===  ==============
+
+    All built-in data-type objects have byteorder either '=' or '|'.
+
+    Examples
+    --------
+
+    >>> dt = np.dtype('i2')
+    >>> dt.byteorder
+    '='
+    >>> # endian is not relevant for 8 bit numbers
+    >>> np.dtype('i1').byteorder
+    '|'
+    >>> # or ASCII strings
+    >>> np.dtype('S2').byteorder
+    '|'
+    >>> # Even if specific code is given, and it is native
+    >>> # '=' is the byteorder
+    >>> import sys
+    >>> sys_is_le = sys.byteorder == 'little'
+    >>> native_code = sys_is_le and '<' or '>'
+    >>> swapped_code = sys_is_le and '>' or '<'
+    >>> dt = np.dtype(native_code + 'i2')
+    >>> dt.byteorder
+    '='
+    >>> # Swapped code shows up as itself
+    >>> dt = np.dtype(swapped_code + 'i2')
+    >>> dt.byteorder == swapped_code
+    True
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('char',
+    """A unique character code for each of the 21 different built-in types."""))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('descr',
+    """
+    Array-interface compliant full description of the data-type.
+
+    The format is that required by the 'descr' key in the
+    `__array_interface__` attribute.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('fields',
+    """
+    Dictionary of named fields defined for this data type, or ``None``.
+
+    The dictionary is indexed by keys that are the names of the fields.
+    Each entry in the dictionary is a tuple fully describing the field::
+
+      (dtype, offset[, title])
+
+    If present, the optional title can be any object (if it is a string
+    or unicode then it will also be a key in the fields dictionary,
+    otherwise it's meta-data). Notice also that the first two elements
+    of the tuple can be passed directly as arguments to the ``ndarray.getfield``
+    and ``ndarray.setfield`` methods.
+
+    See Also
+    --------
+    ndarray.getfield, ndarray.setfield
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
+    >>> print(dt.fields)
+    {'grades': (dtype(('float64',(2,))), 16), 'name': (dtype('|S16'), 0)}
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('flags',
+    """
+    Bit-flags describing how this data type is to be interpreted.
+
+    Bit-masks are in `numpy.core.multiarray` as the constants
+    `ITEM_HASOBJECT`, `LIST_PICKLE`, `ITEM_IS_POINTER`, `NEEDS_INIT`,
+    `NEEDS_PYAPI`, `USE_GETITEM`, `USE_SETITEM`. A full explanation
+    of these flags is in C-API documentation; they are largely useful
+    for user-defined data-types.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('hasobject',
+    """
+    Boolean indicating whether this dtype contains any reference-counted
+    objects in any fields or sub-dtypes.
+
+    Recall that what is actually in the ndarray memory representing
+    the Python object is the memory address of that object (a pointer).
+    Special handling may be required, and this attribute is useful for
+    distinguishing data types that may contain arbitrary Python objects
+    and data-types that won't.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isbuiltin',
+    """
+    Integer indicating how this dtype relates to the built-in dtypes.
+
+    Read-only.
+
+    =  ========================================================================
+    0  if this is a structured array type, with fields
+    1  if this is a dtype compiled into numpy (such as ints, floats etc)
+    2  if the dtype is for a user-defined numpy type
+       A user-defined type uses the numpy C-API machinery to extend
+       numpy to handle a new array type. See
+       :ref:`user.user-defined-data-types` in the Numpy manual.
+    =  ========================================================================
+
+    Examples
+    --------
+    >>> dt = np.dtype('i2')
+    >>> dt.isbuiltin
+    1
+    >>> dt = np.dtype('f8')
+    >>> dt.isbuiltin
+    1
+    >>> dt = np.dtype([('field1', 'f8')])
+    >>> dt.isbuiltin
+    0
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isnative',
+    """
+    Boolean indicating whether the byte order of this dtype is native
+    to the platform.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isalignedstruct',
+    """
+    Boolean indicating whether the dtype is a struct which maintains
+    field alignment. This flag is sticky, so when combining multiple
+    structs together, it is preserved and produces new dtypes which
+    are also aligned.
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('itemsize',
+    """
+    The element size of this data-type object.
+
+    For 18 of the 21 types this number is fixed by the data-type.
+    For the flexible data-types, this number can be anything.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('kind',
+    """
+    A character code (one of 'biufcmMOSUV') identifying the general kind of data.
+
+    =  ======================
+    b  boolean
+    i  signed integer
+    u  unsigned integer
+    f  floating-point
+    c  complex floating-point
+    m  timedelta
+    M  datetime
+    O  object
+    S  (byte-)string
+    U  Unicode
+    V  void
+    =  ======================
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('name',
+    """
+    A bit-width name for this data-type.
+
+    Un-sized flexible data-type objects do not have this attribute.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('names',
+    """
+    Ordered list of field names, or ``None`` if there are no fields.
+
+    The names are ordered according to increasing byte offset. This can be
+    used, for example, to walk through all of the named fields in offset order.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
+    >>> dt.names
+    ('name', 'grades')
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('num',
+    """
+    A unique number for each of the 21 different built-in types.
+
+    These are roughly ordered from least-to-most precision.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('shape',
+    """
+    Shape tuple of the sub-array if this data type describes a sub-array,
+    and ``()`` otherwise.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('str',
+    """The array-protocol typestring of this data-type object."""))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('subdtype',
+    """
+    Tuple ``(item_dtype, shape)`` if this `dtype` describes a sub-array, and
+    None otherwise.
+
+    The *shape* is the fixed shape of the sub-array described by this
+    data type, and *item_dtype* the data type of the array.
+
+    If a field whose dtype object has this attribute is retrieved,
+    then the extra dimensions implied by *shape* are tacked on to
+    the end of the retrieved array.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('type',
+    """The type object used to instantiate a scalar of this data-type."""))
+
+##############################################################################
+#
+# dtype methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('newbyteorder',
+    """
+    newbyteorder(new_order='S')
+
+    Return a new dtype with a different byte order.
+
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    Parameters
+    ----------
+    new_order : string, optional
+        Byte order to force; a value from the byte order specifications
+        below.  The default value ('S') results in swapping the current
+        byte order.  `new_order` codes can be any of:
+
+        * 'S' - swap dtype from current to opposite endian
+        * {'<', 'L'} - little endian
+        * {'>', 'B'} - big endian
+        * {'=', 'N'} - native order
+        * {'|', 'I'} - ignore (no change to byte order)
+
+        The code does a case-insensitive check on the first letter of
+        `new_order` for these alternatives.  For example, any of '>'
+        or 'B' or 'b' or 'brian' are valid to specify big-endian.
+
+    Returns
+    -------
+    new_dtype : dtype
+        New dtype object with the given change to the byte order.
+
+    Notes
+    -----
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    Examples
+    --------
+    >>> import sys
+    >>> sys_is_le = sys.byteorder == 'little'
+    >>> native_code = sys_is_le and '<' or '>'
+    >>> swapped_code = sys_is_le and '>' or '<'
+    >>> native_dt = np.dtype(native_code+'i2')
+    >>> swapped_dt = np.dtype(swapped_code+'i2')
+    >>> native_dt.newbyteorder('S') == swapped_dt
+    True
+    >>> native_dt.newbyteorder() == swapped_dt
+    True
+    >>> native_dt == swapped_dt.newbyteorder('S')
+    True
+    >>> native_dt == swapped_dt.newbyteorder('=')
+    True
+    >>> native_dt == swapped_dt.newbyteorder('N')
+    True
+    >>> native_dt == native_dt.newbyteorder('|')
+    True
+    >>> np.dtype('<i2') == native_dt.newbyteorder('<')
+    True
+    >>> np.dtype('<i2') == native_dt.newbyteorder('L')
+    True
+    >>> np.dtype('>i2') == native_dt.newbyteorder('>')
+    True
+    >>> np.dtype('>i2') == native_dt.newbyteorder('B')
+    True
+
+    """))
+
+
+##############################################################################
+#
+# Datetime-related Methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar',
+    """
+    busdaycalendar(weekmask='1111100', holidays=None)
+
+    A business day calendar object that efficiently stores information
+    defining valid days for the busday family of functions.
+
+    The default valid days are Monday through Friday ("business days").
+    A busdaycalendar object can be specified with any set of weekly
+    valid days, plus an optional "holiday" dates that always will be invalid.
+
+    Once a busdaycalendar object is created, the weekmask and holidays
+    cannot be modified.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates, no matter which
+        weekday they fall upon.  Holiday dates may be specified in any
+        order, and NaT (not-a-time) dates are ignored.  This list is
+        saved in a normalized form that is suited for fast calculations
+        of valid days.
+
+    Returns
+    -------
+    out : busdaycalendar
+        A business day calendar object containing the specified
+        weekmask and holidays values.
+
+    See Also
+    --------
+    is_busday : Returns a boolean array indicating valid days.
+    busday_offset : Applies an offset counted in valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Attributes
+    ----------
+    Note: once a busdaycalendar object is created, you cannot modify the
+    weekmask or holidays.  The attributes return copies of internal data.
+    weekmask : (copy) seven-element array of bool
+    holidays : (copy) sorted array of datetime64[D]
+
+    Examples
+    --------
+    >>> # Some important days in July
+    ... bdd = np.busdaycalendar(
+    ...             holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+    >>> # Default is Monday to Friday weekdays
+    ... bdd.weekmask
+    array([ True,  True,  True,  True,  True, False, False], dtype='bool')
+    >>> # Any holidays already on the weekend are removed
+    ... bdd.holidays
+    array(['2011-07-01', '2011-07-04'], dtype='datetime64[D]')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('weekmask',
+    """A copy of the seven-element boolean mask indicating valid days."""))
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('holidays',
+    """A copy of the holiday array indicating additional invalid days."""))
+
+add_newdoc('numpy.core.multiarray', 'is_busday',
+    """
+    is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None)
+
+    Calculates which of the given dates are valid days, and which are not.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dates : array_like of datetime64[D]
+        The array of dates to process.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of bool, optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of bool
+        An array with the same shape as ``dates``, containing True for
+        each valid day, and False for each invalid day.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    busday_offset : Applies an offset counted in valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Examples
+    --------
+    >>> # The weekdays are Friday, Saturday, and Monday
+    ... np.is_busday(['2011-07-01', '2011-07-02', '2011-07-18'],
+    ...                 holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+    array([False, False,  True], dtype='bool')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busday_offset',
+    """
+    busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)
+
+    First adjusts the date to fall on a valid day according to
+    the ``roll`` rule, then applies offsets to the given dates
+    counted in valid days.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dates : array_like of datetime64[D]
+        The array of dates to process.
+    offsets : array_like of int
+        The array of offsets, which is broadcast with ``dates``.
+    roll : {'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}, optional
+        How to treat dates that do not fall on a valid day. The default
+        is 'raise'.
+
+          * 'raise' means to raise an exception for an invalid day.
+          * 'nat' means to return a NaT (not-a-time) for an invalid day.
+          * 'forward' and 'following' mean to take the first valid day
+            later in time.
+          * 'backward' and 'preceding' mean to take the first valid day
+            earlier in time.
+          * 'modifiedfollowing' means to take the first valid day
+            later in time unless it is across a Month boundary, in which
+            case to take the first valid day earlier in time.
+          * 'modifiedpreceding' means to take the first valid day
+            earlier in time unless it is across a Month boundary, in which
+            case to take the first valid day later in time.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of datetime64[D], optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of datetime64[D]
+        An array with a shape from broadcasting ``dates`` and ``offsets``
+        together, containing the dates with offsets applied.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    is_busday : Returns a boolean array indicating valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Examples
+    --------
+    >>> # First business day in October 2011 (not accounting for holidays)
+    ... np.busday_offset('2011-10', 0, roll='forward')
+    numpy.datetime64('2011-10-03','D')
+    >>> # Last business day in February 2012 (not accounting for holidays)
+    ... np.busday_offset('2012-03', -1, roll='forward')
+    numpy.datetime64('2012-02-29','D')
+    >>> # Third Wednesday in January 2011
+    ... np.busday_offset('2011-01', 2, roll='forward', weekmask='Wed')
+    numpy.datetime64('2011-01-19','D')
+    >>> # 2012 Mother's Day in Canada and the U.S.
+    ... np.busday_offset('2012-05', 1, roll='forward', weekmask='Sun')
+    numpy.datetime64('2012-05-13','D')
+
+    >>> # First business day on or after a date
+    ... np.busday_offset('2011-03-20', 0, roll='forward')
+    numpy.datetime64('2011-03-21','D')
+    >>> np.busday_offset('2011-03-22', 0, roll='forward')
+    numpy.datetime64('2011-03-22','D')
+    >>> # First business day after a date
+    ... np.busday_offset('2011-03-20', 1, roll='backward')
+    numpy.datetime64('2011-03-21','D')
+    >>> np.busday_offset('2011-03-22', 1, roll='backward')
+    numpy.datetime64('2011-03-23','D')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busday_count',
+    """
+    busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)
+
+    Counts the number of valid days between `begindates` and
+    `enddates`, not including the day of `enddates`.
+
+    If ``enddates`` specifies a date value that is earlier than the
+    corresponding ``begindates`` date value, the count will be negative.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    begindates : array_like of datetime64[D]
+        The array of the first dates for counting.
+    enddates : array_like of datetime64[D]
+        The array of the end dates for counting, which are excluded
+        from the count themselves.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of int, optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of int
+        An array with a shape from broadcasting ``begindates`` and ``enddates``
+        together, containing the number of valid days between
+        the begin and end dates.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    is_busday : Returns a boolean array indicating valid days.
+    busday_offset : Applies an offset counted in valid days.
+
+    Examples
+    --------
+    >>> # Number of weekdays in January 2011
+    ... np.busday_count('2011-01', '2011-02')
+    21
+    >>> # Number of weekdays in 2011
+    ...  np.busday_count('2011', '2012')
+    260
+    >>> # Number of Saturdays in 2011
+    ... np.busday_count('2011', '2012', weekmask='Sat')
+    53
+    """)
+
+##############################################################################
+#
+# nd_grid instances
+#
+##############################################################################
+
+add_newdoc('numpy.lib.index_tricks', 'mgrid',
+    """
+    `nd_grid` instance which returns a dense multi-dimensional "meshgrid".
+
+    An instance of `numpy.lib.index_tricks.nd_grid` which returns an dense
+    (or fleshed out) mesh-grid when indexed, so that each returned argument
+    has the same shape.  The dimensions and number of the output arrays are
+    equal to the number of indexing dimensions.  If the step length is not a
+    complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then
+    the integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    Returns
+    ----------
+    mesh-grid `ndarrays` all of the same dimensions
+
+    See Also
+    --------
+    numpy.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects
+    ogrid : like mgrid but returns open (not fleshed out) mesh grids
+    r_ : array concatenator
+
+    Examples
+    --------
+    >>> np.mgrid[0:5,0:5]
+    array([[[0, 0, 0, 0, 0],
+            [1, 1, 1, 1, 1],
+            [2, 2, 2, 2, 2],
+            [3, 3, 3, 3, 3],
+            [4, 4, 4, 4, 4]],
+           [[0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4]]])
+    >>> np.mgrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+
+    """)
+
+add_newdoc('numpy.lib.index_tricks', 'ogrid',
+    """
+    `nd_grid` instance which returns an open multi-dimensional "meshgrid".
+
+    An instance of `numpy.lib.index_tricks.nd_grid` which returns an open
+    (i.e. not fleshed out) mesh-grid when indexed, so that only one dimension
+    of each returned array is greater than 1.  The dimension and number of the
+    output arrays are equal to the number of indexing dimensions.  If the step
+    length is not a complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then
+    the integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    Returns
+    ----------
+    mesh-grid `ndarrays` with only one dimension :math:`\\neq 1`
+
+    See Also
+    --------
+    np.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects
+    mgrid : like `ogrid` but returns dense (or fleshed out) mesh grids
+    r_ : array concatenator
+
+    Examples
+    --------
+    >>> from numpy import ogrid
+    >>> ogrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+    >>> ogrid[0:5,0:5]
+    [array([[0],
+            [1],
+            [2],
+            [3],
+            [4]]), array([[0, 1, 2, 3, 4]])]
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for `generic` attributes and methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.numerictypes', 'generic',
+    """
+    Base class for numpy scalar types.
+
+    Class from which most (all?) numpy scalar types are derived.  For
+    consistency, exposes the same API as `ndarray`, despite many
+    consequent attributes being either "get-only," or completely irrelevant.
+    This is the class from which it is strongly suggested users should derive
+    custom scalar types.
+
+    """)
+
+# Attributes
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('T',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('base',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('data',
+    """Pointer to start of data."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dtype',
+    """Get array data-descriptor."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flags',
+    """The integer value of flags."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flat',
+    """A 1-D view of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('imag',
+    """The imaginary part of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('itemsize',
+    """The length of one element in bytes."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('nbytes',
+    """The length of the scalar in bytes."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ndim',
+    """The number of array dimensions."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('real',
+    """The real part of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('shape',
+    """Tuple of array dimensions."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('size',
+    """The number of elements in the gentype."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('strides',
+    """Tuple of bytes steps in each dimension."""))
+
+# Methods
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('all',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('any',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argmax',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argmin',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argsort',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('astype',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('byteswap',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('choose',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('clip',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('compress',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('conjugate',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('copy',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('cumprod',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('cumsum',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('diagonal',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dump',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dumps',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('fill',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flatten',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('getfield',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('item',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('itemset',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('max',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('mean',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('min',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('newbyteorder',
+    """
+    newbyteorder(new_order='S')
+
+    Return a new `dtype` with a different byte order.
+
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    The `new_order` code can be any from the following:
+
+    * 'S' - swap dtype from current to opposite endian
+    * {'<', 'L'} - little endian
+    * {'>', 'B'} - big endian
+    * {'=', 'N'} - native order
+    * {'|', 'I'} - ignore (no change to byte order)
+
+    Parameters
+    ----------
+    new_order : str, optional
+        Byte order to force; a value from the byte order specifications
+        above.  The default value ('S') results in swapping the current
+        byte order. The code does a case-insensitive check on the first
+        letter of `new_order` for the alternatives above.  For example,
+        any of 'B' or 'b' or 'biggish' are valid to specify big-endian.
+
+
+    Returns
+    -------
+    new_dtype : dtype
+        New `dtype` object with the given change to the byte order.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('nonzero',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('prod',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ptp',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('put',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ravel',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('repeat',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('reshape',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('resize',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('round',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('searchsorted',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('setfield',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('setflags',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('sort',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('squeeze',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('std',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('sum',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('swapaxes',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('take',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tofile',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tolist',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tostring',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('trace',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('transpose',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('var',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('view',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+
+##############################################################################
+#
+# Documentation for other scalar classes
+#
+##############################################################################
+
+add_newdoc('numpy.core.numerictypes', 'bool_',
+    """Numpy's Boolean type.  Character code: ``?``.  Alias: bool8""")
+
+add_newdoc('numpy.core.numerictypes', 'complex64',
+    """
+    Complex number type composed of two 32 bit floats. Character code: 'F'.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'complex128',
+    """
+    Complex number type composed of two 64 bit floats. Character code: 'D'.
+    Python complex compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'complex256',
+    """
+    Complex number type composed of two 128-bit floats. Character code: 'G'.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float32',
+    """
+    32-bit floating-point number. Character code 'f'. C float compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float64',
+    """
+    64-bit floating-point number. Character code 'd'. Python float compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float96',
+    """
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float128',
+    """
+    128-bit floating-point number. Character code: 'g'. C long float
+    compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'int8',
+    """8-bit integer. Character code ``b``. C char compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int16',
+    """16-bit integer. Character code ``h``. C short compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int32',
+    """32-bit integer. Character code 'i'. C int compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int64',
+    """64-bit integer. Character code 'l'. Python int compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'object_',
+    """Any Python object.  Character code: 'O'.""")
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/__init__.py
new file mode 100644
index 0000000000..5b371f5c06
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/__init__.py
@@ -0,0 +1,20 @@
+"""
+Compatibility module.
+
+This module contains duplicated code from Python itself or 3rd party
+extensions, which may be included for the following reasons:
+
+  * compatibility
+  * we may only need a small subset of the copied library/module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import _inspect
+from . import py3k
+from ._inspect import getargspec, formatargspec
+from .py3k import *
+
+__all__ = []
+__all__.extend(_inspect.__all__)
+__all__.extend(py3k.__all__)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.py
new file mode 100644
index 0000000000..c1aa22ec44
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.py
@@ -0,0 +1,194 @@
+"""Subset of inspect module from upstream python
+
+We use this instead of upstream because upstream inspect is slow to import, and
+significanly contributes to numpy import times. Importing this copy has almost
+no overhead.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types
+
+__all__ = ['getargspec', 'formatargspec']
+
+# ----------------------------------------------------------- type-checking
+def ismethod(object):
+    """Return true if the object is an instance method.
+
+    Instance method objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this method was defined
+        im_class        class object in which this method belongs
+        im_func         function object containing implementation of method
+        im_self         instance to which this method is bound, or None
+
+    """
+    return isinstance(object, types.MethodType)
+
+def isfunction(object):
+    """Return true if the object is a user-defined function.
+
+    Function objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this function was defined
+        func_code       code object containing compiled function bytecode
+        func_defaults   tuple of any default values for arguments
+        func_doc        (same as __doc__)
+        func_globals    global namespace in which this function was defined
+        func_name       (same as __name__)
+
+    """
+    return isinstance(object, types.FunctionType)
+
+def iscode(object):
+    """Return true if the object is a code object.
+
+    Code objects provide these attributes:
+        co_argcount     number of arguments (not including * or ** args)
+        co_code         string of raw compiled bytecode
+        co_consts       tuple of constants used in the bytecode
+        co_filename     name of file in which this code object was created
+        co_firstlineno  number of first line in Python source code
+        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
+        co_lnotab       encoded mapping of line numbers to bytecode indices
+        co_name         name with which this code object was defined
+        co_names        tuple of names of local variables
+        co_nlocals      number of local variables
+        co_stacksize    virtual machine stack space required
+        co_varnames     tuple of names of arguments and local variables
+        
+    """
+    return isinstance(object, types.CodeType)
+
+# ------------------------------------------------ argument list extraction
+# These constants are from Python's compile.h.
+CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+
+def getargs(co):
+    """Get information about the arguments accepted by a code object.
+
+    Three things are returned: (args, varargs, varkw), where 'args' is
+    a list of argument names (possibly containing nested lists), and
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+
+    """
+
+    if not iscode(co):
+        raise TypeError('arg is not a code object')
+
+    nargs = co.co_argcount
+    names = co.co_varnames
+    args = list(names[:nargs])
+
+    # The following acrobatics are for anonymous (tuple) arguments.
+    # Which we do not need to support, so remove to avoid importing
+    # the dis module.
+    for i in range(nargs):
+        if args[i][:1] in ['', '.']:
+            raise TypeError("tuple function arguments are not supported")
+    varargs = None
+    if co.co_flags & CO_VARARGS:
+        varargs = co.co_varnames[nargs]
+        nargs = nargs + 1
+    varkw = None
+    if co.co_flags & CO_VARKEYWORDS:
+        varkw = co.co_varnames[nargs]
+    return args, varargs, varkw
+
+def getargspec(func):
+    """Get the names and default values of a function's arguments.
+
+    A tuple of four things is returned: (args, varargs, varkw, defaults).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'defaults' is an n-tuple of the default values of the last n arguments.
+
+    """
+
+    if ismethod(func):
+        func = func.__func__
+    if not isfunction(func):
+        raise TypeError('arg is not a Python function')
+    args, varargs, varkw = getargs(func.__code__)
+    return args, varargs, varkw, func.__defaults__
+
+def getargvalues(frame):
+    """Get information about arguments passed into a particular frame.
+
+    A tuple of four things is returned: (args, varargs, varkw, locals).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'locals' is the locals dictionary of the given frame.
+    
+    """
+    args, varargs, varkw = getargs(frame.f_code)
+    return args, varargs, varkw, frame.f_locals
+
+def joinseq(seq):
+    if len(seq) == 1:
+        return '(' + seq[0] + ',)'
+    else:
+        return '(' + ', '.join(seq) + ')'
+
+def strseq(object, convert, join=joinseq):
+    """Recursively walk a sequence, stringifying each element.
+
+    """
+    if type(object) in [list, tuple]:
+        return join([strseq(_o, convert, join) for _o in object])
+    else:
+        return convert(object)
+
+def formatargspec(args, varargs=None, varkw=None, defaults=None,
+                  formatarg=str,
+                  formatvarargs=lambda name: '*' + name,
+                  formatvarkw=lambda name: '**' + name,
+                  formatvalue=lambda value: '=' + repr(value),
+                  join=joinseq):
+    """Format an argument spec from the 4 values returned by getargspec.
+
+    The first four arguments are (args, varargs, varkw, defaults).  The
+    other four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments.
+
+    """
+    specs = []
+    if defaults:
+        firstdefault = len(args) - len(defaults)
+    for i in range(len(args)):
+        spec = strseq(args[i], formatarg, join)
+        if defaults and i >= firstdefault:
+            spec = spec + formatvalue(defaults[i - firstdefault])
+        specs.append(spec)
+    if varargs is not None:
+        specs.append(formatvarargs(varargs))
+    if varkw is not None:
+        specs.append(formatvarkw(varkw))
+    return '(' + ', '.join(specs) + ')'
+
+def formatargvalues(args, varargs, varkw, locals,
+                    formatarg=str,
+                    formatvarargs=lambda name: '*' + name,
+                    formatvarkw=lambda name: '**' + name,
+                    formatvalue=lambda value: '=' + repr(value),
+                    join=joinseq):
+    """Format an argument spec from the 4 values returned by getargvalues.
+
+    The first four arguments are (args, varargs, varkw, locals).  The
+    next four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments.
+
+    """
+    def convert(name, locals=locals,
+                formatarg=formatarg, formatvalue=formatvalue):
+        return formatarg(name) + formatvalue(locals[name])
+    specs = []
+    for i in range(len(args)):
+        specs.append(strseq(args[i], convert, join))
+    if varargs:
+        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
+    if varkw:
+        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
+    return '(' + ', '.join(specs) + ')'
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/py3k.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/py3k.py
new file mode 100644
index 0000000000..d95a362ca6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/py3k.py
@@ -0,0 +1,88 @@
+"""
+Python 3 compatibility tools.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar',
+           'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested',
+           'asstr', 'open_latin1', 'long', 'basestring', 'sixu',
+           'integer_types']
+
+import sys
+
+if sys.version_info[0] >= 3:
+    import io
+
+    long = int
+    integer_types = (int,)
+    basestring = str
+    unicode = str
+    bytes = bytes
+
+    def asunicode(s):
+        if isinstance(s, bytes):
+            return s.decode('latin1')
+        return str(s)
+
+    def asbytes(s):
+        if isinstance(s, bytes):
+            return s
+        return str(s).encode('latin1')
+
+    def asstr(s):
+        if isinstance(s, bytes):
+            return s.decode('latin1')
+        return str(s)
+
+    def isfileobj(f):
+        return isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter))
+
+    def open_latin1(filename, mode='r'):
+        return open(filename, mode=mode, encoding='iso-8859-1')
+
+    def sixu(s):
+        return s
+
+    strchar = 'U'
+
+
+else:
+    bytes = str
+    long = long
+    basestring = basestring
+    unicode = unicode
+    integer_types = (int, long)
+    asbytes = str
+    asstr = str
+    strchar = 'S'
+
+    def isfileobj(f):
+        return isinstance(f, file)
+
+    def asunicode(s):
+        if isinstance(s, unicode):
+            return s
+        return str(s).decode('ascii')
+
+    def open_latin1(filename, mode='r'):
+        return open(filename, mode=mode)
+
+    def sixu(s):
+        return unicode(s, 'unicode_escape')
+
+
+def getexception():
+    return sys.exc_info()[1]
+
+def asbytes_nested(x):
+    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
+        return [asbytes_nested(y) for y in x]
+    else:
+        return asbytes(x)
+
+def asunicode_nested(x):
+    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
+        return [asunicode_nested(y) for y in x]
+    else:
+        return asunicode(x)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/setup.py
new file mode 100644
index 0000000000..ad1e50c699
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/compat/setup.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('compat', parent_package, top_path)
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/__init__.py
new file mode 100644
index 0000000000..e8719ca75f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/__init__.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+from .info import __doc__
+from numpy.version import version as __version__
+
+# disables OpenBLAS affinity setting of the main thread that limits
+# python threads or processes to one core
+import os
+env_added = []
+for envkey in ['OPENBLAS_MAIN_FREE', 'GOTOBLAS_MAIN_FREE']:
+    if envkey not in os.environ:
+        os.environ[envkey] = '1'
+        env_added.append(envkey)
+from . import multiarray
+for envkey in env_added:
+    del os.environ[envkey]
+del envkey
+del env_added
+del os
+
+from . import umath
+from . import _internal  # for freeze programs
+from . import numerictypes as nt
+multiarray.set_typeDict(nt.sctypeDict)
+from . import numeric
+from .numeric import *
+from . import fromnumeric
+from .fromnumeric import *
+from . import defchararray as char
+from . import records as rec
+from .records import *
+from .memmap import *
+from .defchararray import chararray
+from . import function_base
+from .function_base import *
+from . import machar
+from .machar import *
+from . import getlimits
+from .getlimits import *
+from . import shape_base
+from .shape_base import *
+del nt
+
+from .fromnumeric import amax as max, amin as min, round_ as round
+from .numeric import absolute as abs
+
+__all__ = ['char', 'rec', 'memmap']
+__all__ += numeric.__all__
+__all__ += fromnumeric.__all__
+__all__ += rec.__all__
+__all__ += ['chararray']
+__all__ += function_base.__all__
+__all__ += machar.__all__
+__all__ += getlimits.__all__
+__all__ += shape_base.__all__
+
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
+
+# Make it possible so that ufuncs can be pickled
+#  Here are the loading and unloading functions
+# The name numpy.core._ufunc_reconstruct must be
+#   available for unpickling to work.
+def _ufunc_reconstruct(module, name):
+    # The `fromlist` kwarg is required to ensure that `mod` points to the
+    # inner-most module rather than the parent package when module name is
+    # nested. This makes it possible to pickle non-toplevel ufuncs such as
+    # scipy.special.expit for instance.
+    mod = __import__(module, fromlist=[name])
+    return getattr(mod, name)
+
+def _ufunc_reduce(func):
+    from pickle import whichmodule
+    name = func.__name__
+    return _ufunc_reconstruct, (whichmodule(func, name), name)
+
+
+import sys
+if sys.version_info[0] >= 3:
+    import copyreg
+else:
+    import copy_reg as copyreg
+
+copyreg.pickle(ufunc, _ufunc_reduce, _ufunc_reconstruct)
+# Unclutter namespace (must keep _ufunc_reconstruct for unpickling)
+del copyreg
+del sys
+del _ufunc_reduce
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_dummy.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_dummy.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..887e48c569597b71e5863ba0aa79f011ba77fc9c
GIT binary patch
literal 15360
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
W7eM$d1{?-F1_B@vhEXuQLI40u*6fS`

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_internal.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_internal.py
new file mode 100644
index 0000000000..47c9334111
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_internal.py
@@ -0,0 +1,632 @@
+"""
+A place for code to be called from core C-code.
+
+Some things are more easily handled Python.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import re
+import sys
+
+from numpy.compat import asbytes, basestring
+from .multiarray import dtype, array, ndarray
+import ctypes
+from .numerictypes import object_
+
+if (sys.byteorder == 'little'):
+    _nbo = asbytes('<')
+else:
+    _nbo = asbytes('>')
+
+def _makenames_list(adict, align):
+    allfields = []
+    fnames = list(adict.keys())
+    for fname in fnames:
+        obj = adict[fname]
+        n = len(obj)
+        if not isinstance(obj, tuple) or n not in [2, 3]:
+            raise ValueError("entry not a 2- or 3- tuple")
+        if (n > 2) and (obj[2] == fname):
+            continue
+        num = int(obj[1])
+        if (num < 0):
+            raise ValueError("invalid offset.")
+        format = dtype(obj[0], align=align)
+        if (format.itemsize == 0):
+            raise ValueError("all itemsizes must be fixed.")
+        if (n > 2):
+            title = obj[2]
+        else:
+            title = None
+        allfields.append((fname, format, num, title))
+    # sort by offsets
+    allfields.sort(key=lambda x: x[2])
+    names = [x[0] for x in allfields]
+    formats = [x[1] for x in allfields]
+    offsets = [x[2] for x in allfields]
+    titles = [x[3] for x in allfields]
+
+    return names, formats, offsets, titles
+
+# Called in PyArray_DescrConverter function when
+#  a dictionary without "names" and "formats"
+#  fields is used as a data-type descriptor.
+def _usefields(adict, align):
+    try:
+        names = adict[-1]
+    except KeyError:
+        names = None
+    if names is None:
+        names, formats, offsets, titles = _makenames_list(adict, align)
+    else:
+        formats = []
+        offsets = []
+        titles = []
+        for name in names:
+            res = adict[name]
+            formats.append(res[0])
+            offsets.append(res[1])
+            if (len(res) > 2):
+                titles.append(res[2])
+            else:
+                titles.append(None)
+
+    return dtype({"names": names,
+                  "formats": formats,
+                  "offsets": offsets,
+                  "titles": titles}, align)
+
+
+# construct an array_protocol descriptor list
+#  from the fields attribute of a descriptor
+# This calls itself recursively but should eventually hit
+#  a descriptor that has no fields and then return
+#  a simple typestring
+
+def _array_descr(descriptor):
+    fields = descriptor.fields
+    if fields is None:
+        subdtype = descriptor.subdtype
+        if subdtype is None:
+            if descriptor.metadata is None:
+                return descriptor.str
+            else:
+                new = descriptor.metadata.copy()
+                if new:
+                    return (descriptor.str, new)
+                else:
+                    return descriptor.str
+        else:
+            return (_array_descr(subdtype[0]), subdtype[1])
+
+    names = descriptor.names
+    ordered_fields = [fields[x] + (x,) for x in names]
+    result = []
+    offset = 0
+    for field in ordered_fields:
+        if field[1] > offset:
+            num = field[1] - offset
+            result.append(('', '|V%d' % num))
+            offset += num
+        if len(field) > 3:
+            name = (field[2], field[3])
+        else:
+            name = field[2]
+        if field[0].subdtype:
+            tup = (name, _array_descr(field[0].subdtype[0]),
+                   field[0].subdtype[1])
+        else:
+            tup = (name, _array_descr(field[0]))
+        offset += field[0].itemsize
+        result.append(tup)
+
+    if descriptor.itemsize > offset:
+        num = descriptor.itemsize - offset
+        result.append(('', '|V%d' % num))
+
+    return result
+
+# Build a new array from the information in a pickle.
+# Note that the name numpy.core._internal._reconstruct is embedded in
+# pickles of ndarrays made with NumPy before release 1.0
+# so don't remove the name here, or you'll
+# break backward compatibilty.
+def _reconstruct(subtype, shape, dtype):
+    return ndarray.__new__(subtype, shape, dtype)
+
+
+# format_re was originally from numarray by J. Todd Miller
+
+format_re = re.compile(asbytes(
+                           r'(?P<order1>[<>|=]?)'
+                           r'(?P<repeats> *[(]?[ ,0-9L]*[)]? *)'
+                           r'(?P<order2>[<>|=]?)'
+                           r'(?P<dtype>[A-Za-z0-9.?]*(?:\[[a-zA-Z0-9,.]+\])?)'))
+sep_re = re.compile(asbytes(r'\s*,\s*'))
+space_re = re.compile(asbytes(r'\s+$'))
+
+# astr is a string (perhaps comma separated)
+
+_convorder = {asbytes('='): _nbo}
+
+def _commastring(astr):
+    startindex = 0
+    result = []
+    while startindex < len(astr):
+        mo = format_re.match(astr, pos=startindex)
+        try:
+            (order1, repeats, order2, dtype) = mo.groups()
+        except (TypeError, AttributeError):
+            raise ValueError('format number %d of "%s" is not recognized' %
+                                            (len(result)+1, astr))
+        startindex = mo.end()
+        # Separator or ending padding
+        if startindex < len(astr):
+            if space_re.match(astr, pos=startindex):
+                startindex = len(astr)
+            else:
+                mo = sep_re.match(astr, pos=startindex)
+                if not mo:
+                    raise ValueError(
+                        'format number %d of "%s" is not recognized' %
+                        (len(result)+1, astr))
+                startindex = mo.end()
+
+        if order2 == asbytes(''):
+            order = order1
+        elif order1 == asbytes(''):
+            order = order2
+        else:
+            order1 = _convorder.get(order1, order1)
+            order2 = _convorder.get(order2, order2)
+            if (order1 != order2):
+                raise ValueError(
+                    'inconsistent byte-order specification %s and %s' %
+                    (order1, order2))
+            order = order1
+
+        if order in [asbytes('|'), asbytes('='), _nbo]:
+            order = asbytes('')
+        dtype = order + dtype
+        if (repeats == asbytes('')):
+            newitem = dtype
+        else:
+            newitem = (dtype, eval(repeats))
+        result.append(newitem)
+
+    return result
+
+def _getintp_ctype():
+    val = _getintp_ctype.cache
+    if val is not None:
+        return val
+    char = dtype('p').char
+    if (char == 'i'):
+        val = ctypes.c_int
+    elif char == 'l':
+        val = ctypes.c_long
+    elif char == 'q':
+        val = ctypes.c_longlong
+    else:
+        val = ctypes.c_long
+    _getintp_ctype.cache = val
+    return val
+_getintp_ctype.cache = None
+
+# Used for .ctypes attribute of ndarray
+
+class _missing_ctypes(object):
+    def cast(self, num, obj):
+        return num
+
+    def c_void_p(self, num):
+        return num
+
+class _ctypes(object):
+    def __init__(self, array, ptr=None):
+        try:
+            self._ctypes = ctypes
+        except ImportError:
+            self._ctypes = _missing_ctypes()
+        self._arr = array
+        self._data = ptr
+        if self._arr.ndim == 0:
+            self._zerod = True
+        else:
+            self._zerod = False
+
+    def data_as(self, obj):
+        return self._ctypes.cast(self._data, obj)
+
+    def shape_as(self, obj):
+        if self._zerod:
+            return None
+        return (obj*self._arr.ndim)(*self._arr.shape)
+
+    def strides_as(self, obj):
+        if self._zerod:
+            return None
+        return (obj*self._arr.ndim)(*self._arr.strides)
+
+    def get_data(self):
+        return self._data
+
+    def get_shape(self):
+        if self._zerod:
+            return None
+        return (_getintp_ctype()*self._arr.ndim)(*self._arr.shape)
+
+    def get_strides(self):
+        if self._zerod:
+            return None
+        return (_getintp_ctype()*self._arr.ndim)(*self._arr.strides)
+
+    def get_as_parameter(self):
+        return self._ctypes.c_void_p(self._data)
+
+    data = property(get_data, None, doc="c-types data")
+    shape = property(get_shape, None, doc="c-types shape")
+    strides = property(get_strides, None, doc="c-types strides")
+    _as_parameter_ = property(get_as_parameter, None, doc="_as parameter_")
+
+
+# Given a datatype and an order object
+#  return a new names tuple
+#  with the order indicated
+def _newnames(datatype, order):
+    oldnames = datatype.names
+    nameslist = list(oldnames)
+    if isinstance(order, str):
+        order = [order]
+    if isinstance(order, (list, tuple)):
+        for name in order:
+            try:
+                nameslist.remove(name)
+            except ValueError:
+                raise ValueError("unknown field name: %s" % (name,))
+        return tuple(list(order) + nameslist)
+    raise ValueError("unsupported order value: %s" % (order,))
+
+def _copy_fields(ary):
+    """Return copy of structured array with padding between fields removed.
+
+    Parameters
+    ----------
+    ary : ndarray
+       Structured array from which to remove padding bytes
+
+    Returns
+    -------
+    ary_copy : ndarray
+       Copy of ary with padding bytes removed
+    """
+    dt = ary.dtype
+    copy_dtype = {'names': dt.names,
+                  'formats': [dt.fields[name][0] for name in dt.names]}
+    return array(ary, dtype=copy_dtype, copy=True)
+
+def _getfield_is_safe(oldtype, newtype, offset):
+    """ Checks safety of getfield for object arrays.
+
+    As in _view_is_safe, we need to check that memory containing objects is not
+    reinterpreted as a non-object datatype and vice versa.
+
+    Parameters
+    ----------
+    oldtype : data-type
+        Data type of the original ndarray.
+    newtype : data-type
+        Data type of the field being accessed by ndarray.getfield
+    offset : int
+        Offset of the field being accessed by ndarray.getfield
+
+    Raises
+    ------
+    TypeError
+        If the field access is invalid
+
+    """
+    if newtype.hasobject or oldtype.hasobject:
+        if offset == 0 and newtype == oldtype:
+            return
+        if oldtype.names:
+            for name in oldtype.names:
+                if (oldtype.fields[name][1] == offset and
+                        oldtype.fields[name][0] == newtype):
+                    return
+        raise TypeError("Cannot get/set field of an object array")
+    return
+
+def _view_is_safe(oldtype, newtype):
+    """ Checks safety of a view involving object arrays, for example when
+    doing::
+
+        np.zeros(10, dtype=oldtype).view(newtype)
+
+    Parameters
+    ----------
+    oldtype : data-type
+        Data type of original ndarray
+    newtype : data-type
+        Data type of the view
+
+    Raises
+    ------
+    TypeError
+        If the new type is incompatible with the old type.
+
+    """
+
+    # if the types are equivalent, there is no problem.
+    # for example: dtype((np.record, 'i4,i4')) == dtype((np.void, 'i4,i4'))
+    if oldtype == newtype:
+        return
+
+    if newtype.hasobject or oldtype.hasobject:
+        raise TypeError("Cannot change data-type for object array.")
+    return
+
+# Given a string containing a PEP 3118 format specifier,
+# construct a Numpy dtype
+
+_pep3118_native_map = {
+    '?': '?',
+    'b': 'b',
+    'B': 'B',
+    'h': 'h',
+    'H': 'H',
+    'i': 'i',
+    'I': 'I',
+    'l': 'l',
+    'L': 'L',
+    'q': 'q',
+    'Q': 'Q',
+    'e': 'e',
+    'f': 'f',
+    'd': 'd',
+    'g': 'g',
+    'Zf': 'F',
+    'Zd': 'D',
+    'Zg': 'G',
+    's': 'S',
+    'w': 'U',
+    'O': 'O',
+    'x': 'V',  # padding
+}
+_pep3118_native_typechars = ''.join(_pep3118_native_map.keys())
+
+_pep3118_standard_map = {
+    '?': '?',
+    'b': 'b',
+    'B': 'B',
+    'h': 'i2',
+    'H': 'u2',
+    'i': 'i4',
+    'I': 'u4',
+    'l': 'i4',
+    'L': 'u4',
+    'q': 'i8',
+    'Q': 'u8',
+    'e': 'f2',
+    'f': 'f',
+    'd': 'd',
+    'Zf': 'F',
+    'Zd': 'D',
+    's': 'S',
+    'w': 'U',
+    'O': 'O',
+    'x': 'V',  # padding
+}
+_pep3118_standard_typechars = ''.join(_pep3118_standard_map.keys())
+
+def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
+    fields = {}
+    offset = 0
+    explicit_name = False
+    this_explicit_name = False
+    common_alignment = 1
+    is_padding = False
+
+    dummy_name_index = [0]
+
+    def next_dummy_name():
+        dummy_name_index[0] += 1
+
+    def get_dummy_name():
+        while True:
+            name = 'f%d' % dummy_name_index[0]
+            if name not in fields:
+                return name
+            next_dummy_name()
+
+    # Parse spec
+    while spec:
+        value = None
+
+        # End of structure, bail out to upper level
+        if spec[0] == '}':
+            spec = spec[1:]
+            break
+
+        # Sub-arrays (1)
+        shape = None
+        if spec[0] == '(':
+            j = spec.index(')')
+            shape = tuple(map(int, spec[1:j].split(',')))
+            spec = spec[j+1:]
+
+        # Byte order
+        if spec[0] in ('@', '=', '<', '>', '^', '!'):
+            byteorder = spec[0]
+            if byteorder == '!':
+                byteorder = '>'
+            spec = spec[1:]
+
+        # Byte order characters also control native vs. standard type sizes
+        if byteorder in ('@', '^'):
+            type_map = _pep3118_native_map
+            type_map_chars = _pep3118_native_typechars
+        else:
+            type_map = _pep3118_standard_map
+            type_map_chars = _pep3118_standard_typechars
+
+        # Item sizes
+        itemsize = 1
+        if spec[0].isdigit():
+            j = 1
+            for j in range(1, len(spec)):
+                if not spec[j].isdigit():
+                    break
+            itemsize = int(spec[:j])
+            spec = spec[j:]
+
+        # Data types
+        is_padding = False
+
+        if spec[:2] == 'T{':
+            value, spec, align, next_byteorder = _dtype_from_pep3118(
+                spec[2:], byteorder=byteorder, is_subdtype=True)
+        elif spec[0] in type_map_chars:
+            next_byteorder = byteorder
+            if spec[0] == 'Z':
+                j = 2
+            else:
+                j = 1
+            typechar = spec[:j]
+            spec = spec[j:]
+            is_padding = (typechar == 'x')
+            dtypechar = type_map[typechar]
+            if dtypechar in 'USV':
+                dtypechar += '%d' % itemsize
+                itemsize = 1
+            numpy_byteorder = {'@': '=', '^': '='}.get(byteorder, byteorder)
+            value = dtype(numpy_byteorder + dtypechar)
+            align = value.alignment
+        else:
+            raise ValueError("Unknown PEP 3118 data type specifier %r" % spec)
+
+        #
+        # Native alignment may require padding
+        #
+        # Here we assume that the presence of a '@' character implicitly implies
+        # that the start of the array is *already* aligned.
+        #
+        extra_offset = 0
+        if byteorder == '@':
+            start_padding = (-offset) % align
+            intra_padding = (-value.itemsize) % align
+
+            offset += start_padding
+
+            if intra_padding != 0:
+                if itemsize > 1 or (shape is not None and _prod(shape) > 1):
+                    # Inject internal padding to the end of the sub-item
+                    value = _add_trailing_padding(value, intra_padding)
+                else:
+                    # We can postpone the injection of internal padding,
+                    # as the item appears at most once
+                    extra_offset += intra_padding
+
+            # Update common alignment
+            common_alignment = (align*common_alignment
+                                / _gcd(align, common_alignment))
+
+        # Convert itemsize to sub-array
+        if itemsize != 1:
+            value = dtype((value, (itemsize,)))
+
+        # Sub-arrays (2)
+        if shape is not None:
+            value = dtype((value, shape))
+
+        # Field name
+        this_explicit_name = False
+        if spec and spec.startswith(':'):
+            i = spec[1:].index(':') + 1
+            name = spec[1:i]
+            spec = spec[i+1:]
+            explicit_name = True
+            this_explicit_name = True
+        else:
+            name = get_dummy_name()
+
+        if not is_padding or this_explicit_name:
+            if name in fields:
+                raise RuntimeError("Duplicate field name '%s' in PEP3118 format"
+                                   % name)
+            fields[name] = (value, offset)
+            if not this_explicit_name:
+                next_dummy_name()
+
+        byteorder = next_byteorder
+
+        offset += value.itemsize
+        offset += extra_offset
+
+    # Check if this was a simple 1-item type
+    if (len(fields) == 1 and not explicit_name and
+            fields['f0'][1] == 0 and not is_subdtype):
+        ret = fields['f0'][0]
+    else:
+        ret = dtype(fields)
+
+    # Trailing padding must be explicitly added
+    padding = offset - ret.itemsize
+    if byteorder == '@':
+        padding += (-offset) % common_alignment
+    if is_padding and not this_explicit_name:
+        ret = _add_trailing_padding(ret, padding)
+
+    # Finished
+    if is_subdtype:
+        return ret, spec, common_alignment, byteorder
+    else:
+        return ret
+
+def _add_trailing_padding(value, padding):
+    """Inject the specified number of padding bytes at the end of a dtype"""
+    if value.fields is None:
+        vfields = {'f0': (value, 0)}
+    else:
+        vfields = dict(value.fields)
+
+    if (value.names and value.names[-1] == '' and
+           value[''].char == 'V'):
+        # A trailing padding field is already present
+        vfields[''] = ('V%d' % (vfields[''][0].itemsize + padding),
+                       vfields[''][1])
+        value = dtype(vfields)
+    else:
+        # Get a free name for the padding field
+        j = 0
+        while True:
+            name = 'pad%d' % j
+            if name not in vfields:
+                vfields[name] = ('V%d' % padding, value.itemsize)
+                break
+            j += 1
+
+        value = dtype(vfields)
+        if '' not in vfields:
+            # Strip out the name of the padding field
+            names = list(value.names)
+            names[-1] = ''
+            value.names = tuple(names)
+    return value
+
+def _prod(a):
+    p = 1
+    for x in a:
+        p *= x
+    return p
+
+def _gcd(a, b):
+    """Calculate the greatest common divisor of a and b"""
+    while b:
+        a, b = b, a % b
+    return a
+
+# Exception used in shares_memory()
+class TooHardError(RuntimeError):
+    pass
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_methods.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_methods.py
new file mode 100644
index 0000000000..5fc2bc4450
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/_methods.py
@@ -0,0 +1,133 @@
+"""
+Array methods which are called by both the C-code for the method
+and the Python code for the NumPy-namespace function
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+from numpy.core import multiarray as mu
+from numpy.core import umath as um
+from numpy.core.numeric import asanyarray
+from numpy.core import numerictypes as nt
+
+# save those O(100) nanoseconds!
+umr_maximum = um.maximum.reduce
+umr_minimum = um.minimum.reduce
+umr_sum = um.add.reduce
+umr_prod = um.multiply.reduce
+umr_any = um.logical_or.reduce
+umr_all = um.logical_and.reduce
+
+# avoid keyword arguments to speed up parsing, saves about 15%-20% for very
+# small reductions
+def _amax(a, axis=None, out=None, keepdims=False):
+    return umr_maximum(a, axis, None, out, keepdims)
+
+def _amin(a, axis=None, out=None, keepdims=False):
+    return umr_minimum(a, axis, None, out, keepdims)
+
+def _sum(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_sum(a, axis, dtype, out, keepdims)
+
+def _prod(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_prod(a, axis, dtype, out, keepdims)
+
+def _any(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_any(a, axis, dtype, out, keepdims)
+
+def _all(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_all(a, axis, dtype, out, keepdims)
+
+def _count_reduce_items(arr, axis):
+    if axis is None:
+        axis = tuple(range(arr.ndim))
+    if not isinstance(axis, tuple):
+        axis = (axis,)
+    items = 1
+    for ax in axis:
+        items *= arr.shape[ax]
+    return items
+
+def _mean(a, axis=None, dtype=None, out=None, keepdims=False):
+    arr = asanyarray(a)
+
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up first
+    if rcount == 0:
+        warnings.warn("Mean of empty slice.", RuntimeWarning)
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    ret = umr_sum(arr, axis, dtype, out, keepdims)
+    if isinstance(ret, mu.ndarray):
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(ret / rcount)
+    else:
+        ret = ret / rcount
+
+    return ret
+
+def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    arr = asanyarray(a)
+
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up on top.
+    if ddof >= rcount:
+        warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    # Compute the mean.
+    # Note that if dtype is not of inexact type then arraymean will
+    # not be either.
+    arrmean = umr_sum(arr, axis, dtype, keepdims=True)
+    if isinstance(arrmean, mu.ndarray):
+        arrmean = um.true_divide(
+                arrmean, rcount, out=arrmean, casting='unsafe', subok=False)
+    else:
+        arrmean = arrmean.dtype.type(arrmean / rcount)
+
+    # Compute sum of squared deviations from mean
+    # Note that x may not be inexact and that we need it to be an array,
+    # not a scalar.
+    x = asanyarray(arr - arrmean)
+    if issubclass(arr.dtype.type, nt.complexfloating):
+        x = um.multiply(x, um.conjugate(x), out=x).real
+    else:
+        x = um.multiply(x, x, out=x)
+    ret = umr_sum(x, axis, dtype, out, keepdims)
+
+    # Compute degrees of freedom and make sure it is not negative.
+    rcount = max([rcount - ddof, 0])
+
+    # divide by degrees of freedom
+    if isinstance(ret, mu.ndarray):
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(ret / rcount)
+    else:
+        ret = ret / rcount
+
+    return ret
+
+def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+               keepdims=keepdims)
+
+    if isinstance(ret, mu.ndarray):
+        ret = um.sqrt(ret, out=ret)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(um.sqrt(ret))
+    else:
+        ret = um.sqrt(ret)
+
+    return ret
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.py
new file mode 100644
index 0000000000..282fbd1cfb
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.py
@@ -0,0 +1,754 @@
+"""Array printing function
+
+$Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ["array2string", "set_printoptions", "get_printoptions"]
+__docformat__ = 'restructuredtext'
+
+#
+# Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
+# last revision: 1996-3-13
+# modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details)
+# and by Perry Greenfield 2000-4-1 for numarray
+# and by Travis Oliphant  2005-8-22 for numpy
+
+import sys
+from functools import reduce
+from . import numerictypes as _nt
+from .umath import maximum, minimum, absolute, not_equal, isnan, isinf
+from .multiarray import (array, format_longfloat, datetime_as_string,
+                         datetime_data)
+from .fromnumeric import ravel
+from .numeric import asarray
+
+if sys.version_info[0] >= 3:
+    _MAXINT = sys.maxsize
+    _MININT = -sys.maxsize - 1
+else:
+    _MAXINT = sys.maxint
+    _MININT = -sys.maxint - 1
+
+def product(x, y):
+    return x*y
+
+_summaryEdgeItems = 3     # repr N leading and trailing items of each dimension
+_summaryThreshold = 1000  # total items > triggers array summarization
+
+_float_output_precision = 8
+_float_output_suppress_small = False
+_line_width = 75
+_nan_str = 'nan'
+_inf_str = 'inf'
+_formatter = None  # formatting function for array elements
+
+
+def set_printoptions(precision=None, threshold=None, edgeitems=None,
+                     linewidth=None, suppress=None,
+                     nanstr=None, infstr=None,
+                     formatter=None):
+    """
+    Set printing options.
+
+    These options determine the way floating point numbers, arrays and
+    other NumPy objects are displayed.
+
+    Parameters
+    ----------
+    precision : int, optional
+        Number of digits of precision for floating point output (default 8).
+    threshold : int, optional
+        Total number of array elements which trigger summarization
+        rather than full repr (default 1000).
+    edgeitems : int, optional
+        Number of array items in summary at beginning and end of
+        each dimension (default 3).
+    linewidth : int, optional
+        The number of characters per line for the purpose of inserting
+        line breaks (default 75).
+    suppress : bool, optional
+        Whether or not suppress printing of small floating point values
+        using scientific notation (default False).
+    nanstr : str, optional
+        String representation of floating point not-a-number (default nan).
+    infstr : str, optional
+        String representation of floating point infinity (default inf).
+    formatter : dict of callables, optional
+        If not None, the keys should indicate the type(s) that the respective
+        formatting function applies to.  Callables should return a string.
+        Types that are not specified (by their corresponding keys) are handled
+        by the default formatters.  Individual types for which a formatter
+        can be set are::
+
+            - 'bool'
+            - 'int'
+            - 'timedelta' : a `numpy.timedelta64`
+            - 'datetime' : a `numpy.datetime64`
+            - 'float'
+            - 'longfloat' : 128-bit floats
+            - 'complexfloat'
+            - 'longcomplexfloat' : composed of two 128-bit floats
+            - 'numpy_str' : 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'
+
+    See Also
+    --------
+    get_printoptions, set_string_function, array2string
+
+    Notes
+    -----
+    `formatter` is always reset with a call to `set_printoptions`.
+
+    Examples
+    --------
+    Floating point precision can be set:
+
+    >>> np.set_printoptions(precision=4)
+    >>> print(np.array([1.123456789]))
+    [ 1.1235]
+
+    Long arrays can be summarised:
+
+    >>> np.set_printoptions(threshold=5)
+    >>> print(np.arange(10))
+    [0 1 2 ..., 7 8 9]
+
+    Small results can be suppressed:
+
+    >>> eps = np.finfo(float).eps
+    >>> x = np.arange(4.)
+    >>> x**2 - (x + eps)**2
+    array([ -4.9304e-32,  -4.4409e-16,   0.0000e+00,   0.0000e+00])
+    >>> np.set_printoptions(suppress=True)
+    >>> x**2 - (x + eps)**2
+    array([-0., -0.,  0.,  0.])
+
+    A custom formatter can be used to display array elements as desired:
+
+    >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)})
+    >>> x = np.arange(3)
+    >>> x
+    array([int: 0, int: -1, int: -2])
+    >>> np.set_printoptions()  # formatter gets reset
+    >>> x
+    array([0, 1, 2])
+
+    To put back the default options, you can use:
+
+    >>> np.set_printoptions(edgeitems=3,infstr='inf',
+    ... linewidth=75, nanstr='nan', precision=8,
+    ... suppress=False, threshold=1000, formatter=None)
+    """
+
+    global _summaryThreshold, _summaryEdgeItems, _float_output_precision
+    global _line_width, _float_output_suppress_small, _nan_str, _inf_str
+    global _formatter
+
+    if linewidth is not None:
+        _line_width = linewidth
+    if threshold is not None:
+        _summaryThreshold = threshold
+    if edgeitems is not None:
+        _summaryEdgeItems = edgeitems
+    if precision is not None:
+        _float_output_precision = precision
+    if suppress is not None:
+        _float_output_suppress_small = not not suppress
+    if nanstr is not None:
+        _nan_str = nanstr
+    if infstr is not None:
+        _inf_str = infstr
+    _formatter = formatter
+
+def get_printoptions():
+    """
+    Return the current print options.
+
+    Returns
+    -------
+    print_opts : dict
+        Dictionary of current print options with keys
+
+          - precision : int
+          - threshold : int
+          - edgeitems : int
+          - linewidth : int
+          - suppress : bool
+          - nanstr : str
+          - infstr : str
+          - formatter : dict of callables
+
+        For a full description of these options, see `set_printoptions`.
+
+    See Also
+    --------
+    set_printoptions, set_string_function
+
+    """
+    d = dict(precision=_float_output_precision,
+             threshold=_summaryThreshold,
+             edgeitems=_summaryEdgeItems,
+             linewidth=_line_width,
+             suppress=_float_output_suppress_small,
+             nanstr=_nan_str,
+             infstr=_inf_str,
+             formatter=_formatter)
+    return d
+
+def _leading_trailing(a):
+    from . import numeric as _nc
+    if a.ndim == 1:
+        if len(a) > 2*_summaryEdgeItems:
+            b = _nc.concatenate((a[:_summaryEdgeItems],
+                                     a[-_summaryEdgeItems:]))
+        else:
+            b = a
+    else:
+        if len(a) > 2*_summaryEdgeItems:
+            l = [_leading_trailing(a[i]) for i in range(
+                min(len(a), _summaryEdgeItems))]
+            l.extend([_leading_trailing(a[-i]) for i in range(
+                min(len(a), _summaryEdgeItems), 0, -1)])
+        else:
+            l = [_leading_trailing(a[i]) for i in range(0, len(a))]
+        b = _nc.concatenate(tuple(l))
+    return b
+
+def _boolFormatter(x):
+    if x:
+        return ' True'
+    else:
+        return 'False'
+
+
+def repr_format(x):
+    return repr(x)
+
+def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
+                  prefix="", formatter=None):
+
+    if max_line_width is None:
+        max_line_width = _line_width
+
+    if precision is None:
+        precision = _float_output_precision
+
+    if suppress_small is None:
+        suppress_small = _float_output_suppress_small
+
+    if formatter is None:
+        formatter = _formatter
+
+    if a.size > _summaryThreshold:
+        summary_insert = "..., "
+        data = _leading_trailing(a)
+    else:
+        summary_insert = ""
+        data = ravel(asarray(a))
+
+    formatdict = {'bool': _boolFormatter,
+                  'int': IntegerFormat(data),
+                  'float': FloatFormat(data, precision, suppress_small),
+                  'longfloat': LongFloatFormat(precision),
+                  'complexfloat': ComplexFormat(data, precision,
+                                                 suppress_small),
+                  'longcomplexfloat': LongComplexFormat(precision),
+                  'datetime': DatetimeFormat(data),
+                  'timedelta': TimedeltaFormat(data),
+                  'numpystr': repr_format,
+                  'str': str}
+
+    if formatter is not None:
+        fkeys = [k for k in formatter.keys() if formatter[k] is not None]
+        if 'all' in fkeys:
+            for key in formatdict.keys():
+                formatdict[key] = formatter['all']
+        if 'int_kind' in fkeys:
+            for key in ['int']:
+                formatdict[key] = formatter['int_kind']
+        if 'float_kind' in fkeys:
+            for key in ['float', 'longfloat']:
+                formatdict[key] = formatter['float_kind']
+        if 'complex_kind' in fkeys:
+            for key in ['complexfloat', 'longcomplexfloat']:
+                formatdict[key] = formatter['complex_kind']
+        if 'str_kind' in fkeys:
+            for key in ['numpystr', 'str']:
+                formatdict[key] = formatter['str_kind']
+        for key in formatdict.keys():
+            if key in fkeys:
+                formatdict[key] = formatter[key]
+
+    # find the right formatting function for the array
+    dtypeobj = a.dtype.type
+    if issubclass(dtypeobj, _nt.bool_):
+        format_function = formatdict['bool']
+    elif issubclass(dtypeobj, _nt.integer):
+        if issubclass(dtypeobj, _nt.timedelta64):
+            format_function = formatdict['timedelta']
+        else:
+            format_function = formatdict['int']
+    elif issubclass(dtypeobj, _nt.floating):
+        if issubclass(dtypeobj, _nt.longfloat):
+            format_function = formatdict['longfloat']
+        else:
+            format_function = formatdict['float']
+    elif issubclass(dtypeobj, _nt.complexfloating):
+        if issubclass(dtypeobj, _nt.clongfloat):
+            format_function = formatdict['longcomplexfloat']
+        else:
+            format_function = formatdict['complexfloat']
+    elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
+        format_function = formatdict['numpystr']
+    elif issubclass(dtypeobj, _nt.datetime64):
+        format_function = formatdict['datetime']
+    else:
+        format_function = formatdict['numpystr']
+
+    # skip over "["
+    next_line_prefix = " "
+    # skip over array(
+    next_line_prefix += " "*len(prefix)
+
+    lst = _formatArray(a, format_function, len(a.shape), max_line_width,
+                       next_line_prefix, separator,
+                       _summaryEdgeItems, summary_insert)[:-1]
+    return lst
+
+def _convert_arrays(obj):
+    from . import numeric as _nc
+    newtup = []
+    for k in obj:
+        if isinstance(k, _nc.ndarray):
+            k = k.tolist()
+        elif isinstance(k, tuple):
+            k = _convert_arrays(k)
+        newtup.append(k)
+    return tuple(newtup)
+
+
+def array2string(a, max_line_width=None, precision=None,
+                 suppress_small=None, separator=' ', prefix="",
+                 style=repr, formatter=None):
+    """
+    Return a string representation of an array.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    max_line_width : int, optional
+        The maximum number of columns the string should span. Newline
+        characters splits the string appropriately after array elements.
+    precision : int, optional
+        Floating point precision. Default is the current printing
+        precision (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent very small numbers as zero. A number is "very small" if it
+        is smaller than the current printing precision.
+    separator : str, optional
+        Inserted between elements.
+    prefix : str, optional
+        An array is typically printed as::
+
+          'prefix(' + array2string(a) + ')'
+
+        The length of the prefix string is used to align the
+        output correctly.
+    style : function, optional
+        A function that accepts an ndarray and returns a string.  Used only
+        when the shape of `a` is equal to ``()``, i.e. for 0-D arrays.
+    formatter : dict of callables, optional
+        If not None, the keys should indicate the type(s) that the respective
+        formatting function applies to.  Callables should return a string.
+        Types that are not specified (by their corresponding keys) are handled
+        by the default formatters.  Individual types for which a formatter
+        can be set are::
+
+            - 'bool'
+            - 'int'
+            - 'timedelta' : a `numpy.timedelta64`
+            - 'datetime' : a `numpy.datetime64`
+            - 'float'
+            - 'longfloat' : 128-bit floats
+            - 'complexfloat'
+            - 'longcomplexfloat' : composed of two 128-bit floats
+            - 'numpy_str' : 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'
+
+    Returns
+    -------
+    array_str : str
+        String representation of the array.
+
+    Raises
+    ------
+    TypeError
+        if a callable in `formatter` does not return a string.
+
+    See Also
+    --------
+    array_str, array_repr, set_printoptions, get_printoptions
+
+    Notes
+    -----
+    If a formatter is specified for a certain type, the `precision` keyword is
+    ignored for that type.
+
+    This is a very flexible function; `array_repr` and `array_str` are using
+    `array2string` internally so keywords with the same name should work
+    identically in all three functions.
+
+    Examples
+    --------
+    >>> x = np.array([1e-16,1,2,3])
+    >>> print(np.array2string(x, precision=2, separator=',',
+    ...                       suppress_small=True))
+    [ 0., 1., 2., 3.]
+
+    >>> x  = np.arange(3.)
+    >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x})
+    '[0.00 1.00 2.00]'
+
+    >>> x  = np.arange(3)
+    >>> np.array2string(x, formatter={'int':lambda x: hex(x)})
+    '[0x0L 0x1L 0x2L]'
+
+    """
+
+    if a.shape == ():
+        x = a.item()
+        if isinstance(x, tuple):
+            x = _convert_arrays(x)
+        lst = style(x)
+    elif reduce(product, a.shape) == 0:
+        # treat as a null array if any of shape elements == 0
+        lst = "[]"
+    else:
+        lst = _array2string(a, max_line_width, precision, suppress_small,
+                            separator, prefix, formatter=formatter)
+    return lst
+
+def _extendLine(s, line, word, max_line_len, next_line_prefix):
+    if len(line.rstrip()) + len(word.rstrip()) >= max_line_len:
+        s += line.rstrip() + "\n"
+        line = next_line_prefix
+    line += word
+    return s, line
+
+
+def _formatArray(a, format_function, rank, max_line_len,
+                 next_line_prefix, separator, edge_items, summary_insert):
+    """formatArray is designed for two modes of operation:
+
+    1. Full output
+
+    2. Summarized output
+
+    """
+    if rank == 0:
+        obj = a.item()
+        if isinstance(obj, tuple):
+            obj = _convert_arrays(obj)
+        return str(obj)
+
+    if summary_insert and 2*edge_items < len(a):
+        leading_items = edge_items
+        trailing_items = edge_items
+        summary_insert1 = summary_insert
+    else:
+        leading_items = 0
+        trailing_items = len(a)
+        summary_insert1 = ""
+
+    if rank == 1:
+        s = ""
+        line = next_line_prefix
+        for i in range(leading_items):
+            word = format_function(a[i]) + separator
+            s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+
+        if summary_insert1:
+            s, line = _extendLine(s, line, summary_insert1, max_line_len, next_line_prefix)
+
+        for i in range(trailing_items, 1, -1):
+            word = format_function(a[-i]) + separator
+            s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+
+        word = format_function(a[-1])
+        s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+        s += line + "]\n"
+        s = '[' + s[len(next_line_prefix):]
+    else:
+        s = '['
+        sep = separator.rstrip()
+        for i in range(leading_items):
+            if i > 0:
+                s += next_line_prefix
+            s += _formatArray(a[i], format_function, rank-1, max_line_len,
+                              " " + next_line_prefix, separator, edge_items,
+                              summary_insert)
+            s = s.rstrip() + sep.rstrip() + '\n'*max(rank-1, 1)
+
+        if summary_insert1:
+            s += next_line_prefix + summary_insert1 + "\n"
+
+        for i in range(trailing_items, 1, -1):
+            if leading_items or i != trailing_items:
+                s += next_line_prefix
+            s += _formatArray(a[-i], format_function, rank-1, max_line_len,
+                              " " + next_line_prefix, separator, edge_items,
+                              summary_insert)
+            s = s.rstrip() + sep.rstrip() + '\n'*max(rank-1, 1)
+        if leading_items or trailing_items > 1:
+            s += next_line_prefix
+        s += _formatArray(a[-1], format_function, rank-1, max_line_len,
+                          " " + next_line_prefix, separator, edge_items,
+                          summary_insert).rstrip()+']\n'
+    return s
+
+class FloatFormat(object):
+    def __init__(self, data, precision, suppress_small, sign=False):
+        self.precision = precision
+        self.suppress_small = suppress_small
+        self.sign = sign
+        self.exp_format = False
+        self.large_exponent = False
+        self.max_str_len = 0
+        try:
+            self.fillFormat(data)
+        except (TypeError, NotImplementedError):
+            # if reduce(data) fails, this instance will not be called, just
+            # instantiated in formatdict.
+            pass
+
+    def fillFormat(self, data):
+        from . import numeric as _nc
+
+        with _nc.errstate(all='ignore'):
+            special = isnan(data) | isinf(data)
+            valid = not_equal(data, 0) & ~special
+            non_zero = absolute(data.compress(valid))
+            if len(non_zero) == 0:
+                max_val = 0.
+                min_val = 0.
+            else:
+                max_val = maximum.reduce(non_zero)
+                min_val = minimum.reduce(non_zero)
+                if max_val >= 1.e8:
+                    self.exp_format = True
+                if not self.suppress_small and (min_val < 0.0001
+                                           or max_val/min_val > 1000.):
+                    self.exp_format = True
+
+        if self.exp_format:
+            self.large_exponent = 0 < min_val < 1e-99 or max_val >= 1e100
+            self.max_str_len = 8 + self.precision
+            if self.large_exponent:
+                self.max_str_len += 1
+            if self.sign:
+                format = '%+'
+            else:
+                format = '%'
+            format = format + '%d.%de' % (self.max_str_len, self.precision)
+        else:
+            format = '%%.%df' % (self.precision,)
+            if len(non_zero):
+                precision = max([_digits(x, self.precision, format)
+                                 for x in non_zero])
+            else:
+                precision = 0
+            precision = min(self.precision, precision)
+            self.max_str_len = len(str(int(max_val))) + precision + 2
+            if _nc.any(special):
+                self.max_str_len = max(self.max_str_len,
+                                       len(_nan_str),
+                                       len(_inf_str)+1)
+            if self.sign:
+                format = '%#+'
+            else:
+                format = '%#'
+            format = format + '%d.%df' % (self.max_str_len, precision)
+
+        self.special_fmt = '%%%ds' % (self.max_str_len,)
+        self.format = format
+
+    def __call__(self, x, strip_zeros=True):
+        from . import numeric as _nc
+
+        with _nc.errstate(invalid='ignore'):
+            if isnan(x):
+                if self.sign:
+                    return self.special_fmt % ('+' + _nan_str,)
+                else:
+                    return self.special_fmt % (_nan_str,)
+            elif isinf(x):
+                if x > 0:
+                    if self.sign:
+                        return self.special_fmt % ('+' + _inf_str,)
+                    else:
+                        return self.special_fmt % (_inf_str,)
+                else:
+                    return self.special_fmt % ('-' + _inf_str,)
+
+        s = self.format % x
+        if self.large_exponent:
+            # 3-digit exponent
+            expsign = s[-3]
+            if expsign == '+' or expsign == '-':
+                s = s[1:-2] + '0' + s[-2:]
+        elif self.exp_format:
+            # 2-digit exponent
+            if s[-3] == '0':
+                s = ' ' + s[:-3] + s[-2:]
+        elif strip_zeros:
+            z = s.rstrip('0')
+            s = z + ' '*(len(s)-len(z))
+        return s
+
+
+def _digits(x, precision, format):
+    s = format % x
+    z = s.rstrip('0')
+    return precision - len(s) + len(z)
+
+
+class IntegerFormat(object):
+    def __init__(self, data):
+        try:
+            max_str_len = max(len(str(maximum.reduce(data))),
+                              len(str(minimum.reduce(data))))
+            self.format = '%' + str(max_str_len) + 'd'
+        except (TypeError, NotImplementedError):
+            # if reduce(data) fails, this instance will not be called, just
+            # instantiated in formatdict.
+            pass
+        except ValueError:
+            # this occurs when everything is NA
+            pass
+
+    def __call__(self, x):
+        if _MININT < x < _MAXINT:
+            return self.format % x
+        else:
+            return "%s" % x
+
+class LongFloatFormat(object):
+    # XXX Have to add something to determine the width to use a la FloatFormat
+    # Right now, things won't line up properly
+    def __init__(self, precision, sign=False):
+        self.precision = precision
+        self.sign = sign
+
+    def __call__(self, x):
+        if isnan(x):
+            if self.sign:
+                return '+' + _nan_str
+            else:
+                return ' ' + _nan_str
+        elif isinf(x):
+            if x > 0:
+                if self.sign:
+                    return '+' + _inf_str
+                else:
+                    return ' ' + _inf_str
+            else:
+                return '-' + _inf_str
+        elif x >= 0:
+            if self.sign:
+                return '+' + format_longfloat(x, self.precision)
+            else:
+                return ' ' + format_longfloat(x, self.precision)
+        else:
+            return format_longfloat(x, self.precision)
+
+
+class LongComplexFormat(object):
+    def __init__(self, precision):
+        self.real_format = LongFloatFormat(precision)
+        self.imag_format = LongFloatFormat(precision, sign=True)
+
+    def __call__(self, x):
+        r = self.real_format(x.real)
+        i = self.imag_format(x.imag)
+        return r + i + 'j'
+
+
+class ComplexFormat(object):
+    def __init__(self, x, precision, suppress_small):
+        self.real_format = FloatFormat(x.real, precision, suppress_small)
+        self.imag_format = FloatFormat(x.imag, precision, suppress_small,
+                                       sign=True)
+
+    def __call__(self, x):
+        r = self.real_format(x.real, strip_zeros=False)
+        i = self.imag_format(x.imag, strip_zeros=False)
+        if not self.imag_format.exp_format:
+            z = i.rstrip('0')
+            i = z + 'j' + ' '*(len(i)-len(z))
+        else:
+            i = i + 'j'
+        return r + i
+
+
+class DatetimeFormat(object):
+    def __init__(self, x, unit=None, timezone=None, casting='same_kind'):
+        # Get the unit from the dtype
+        if unit is None:
+            if x.dtype.kind == 'M':
+                unit = datetime_data(x.dtype)[0]
+            else:
+                unit = 's'
+
+        if timezone is None:
+            timezone = 'naive'
+        self.timezone = timezone
+        self.unit = unit
+        self.casting = casting
+
+    def __call__(self, x):
+        return "'%s'" % datetime_as_string(x,
+                                    unit=self.unit,
+                                    timezone=self.timezone,
+                                    casting=self.casting)
+
+class TimedeltaFormat(object):
+    def __init__(self, data):
+        if data.dtype.kind == 'm':
+            nat_value = array(['NaT'], dtype=data.dtype)[0]
+            v = data[not_equal(data, nat_value)].view('i8')
+            if len(v) > 0:
+                # Max str length of non-NaT elements
+                max_str_len = max(len(str(maximum.reduce(v))),
+                                  len(str(minimum.reduce(v))))
+            else:
+                max_str_len = 0
+            if len(v) < len(data):
+                # data contains a NaT
+                max_str_len = max(max_str_len, 5)
+            self.format = '%' + str(max_str_len) + 'd'
+            self._nat = "'NaT'".rjust(max_str_len)
+
+    def __call__(self, x):
+        if x + 1 == x:
+            return self._nat
+        else:
+            return self.format % x.astype('i8')
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/cversions.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/cversions.py
new file mode 100644
index 0000000000..7995dd9931
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/cversions.py
@@ -0,0 +1,15 @@
+"""Simple script to compute the api hash of the current API.
+
+The API has is defined by numpy_api_order and ufunc_api_order.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from os.path import dirname
+
+from code_generators.genapi import fullapi_hash
+from code_generators.numpy_api import full_api
+
+if __name__ == '__main__':
+    curdir = dirname(__file__)
+    print(fullapi_hash(full_api))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/defchararray.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/defchararray.py
new file mode 100644
index 0000000000..e18f912d60
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/defchararray.py
@@ -0,0 +1,2689 @@
+"""
+This module contains a set of functions for vectorized string
+operations and methods.
+
+.. note::
+   The `chararray` class exists for backwards compatibility with
+   Numarray, it is not recommended for new development. Starting from numpy
+   1.4, if one needs arrays of strings, it is recommended to use arrays of
+   `dtype` `object_`, `string_` or `unicode_`, and use the free functions
+   in the `numpy.char` module for fast vectorized string operations.
+
+Some methods will only be available if the corresponding string method is
+available in your version of Python.
+
+The preferred alias for `defchararray` is `numpy.char`.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+from .numerictypes import string_, unicode_, integer, object_, bool_, character
+from .numeric import ndarray, compare_chararrays
+from .numeric import array as narray
+from numpy.core.multiarray import _vec_string
+from numpy.compat import asbytes, long
+import numpy
+
+__all__ = [
+    'chararray', 'equal', 'not_equal', 'greater_equal', 'less_equal',
+    'greater', 'less', 'str_len', 'add', 'multiply', 'mod', 'capitalize',
+    'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+    'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
+    'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
+    'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit',
+    'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
+    'title', 'translate', 'upper', 'zfill', 'isnumeric', 'isdecimal',
+    'array', 'asarray'
+    ]
+
+
+_globalvar = 0
+if sys.version_info[0] >= 3:
+    _unicode = str
+    _bytes = bytes
+else:
+    _unicode = unicode
+    _bytes = str
+_len = len
+
+def _use_unicode(*args):
+    """
+    Helper function for determining the output type of some string
+    operations.
+
+    For an operation on two ndarrays, if at least one is unicode, the
+    result should be unicode.
+    """
+    for x in args:
+        if (isinstance(x, _unicode) or
+                issubclass(numpy.asarray(x).dtype.type, unicode_)):
+            return unicode_
+    return string_
+
+def _to_string_or_unicode_array(result):
+    """
+    Helper function to cast a result back into a string or unicode array
+    if an object array must be used as an intermediary.
+    """
+    return numpy.asarray(result.tolist())
+
+def _clean_args(*args):
+    """
+    Helper function for delegating arguments to Python string
+    functions.
+
+    Many of the Python string operations that have optional arguments
+    do not use 'None' to indicate a default value.  In these cases,
+    we need to remove all `None` arguments, and those following them.
+    """
+    newargs = []
+    for chk in args:
+        if chk is None:
+            break
+        newargs.append(chk)
+    return newargs
+
+def _get_num_chars(a):
+    """
+    Helper function that returns the number of characters per field in
+    a string or unicode array.  This is to abstract out the fact that
+    for a unicode array this is itemsize / 4.
+    """
+    if issubclass(a.dtype.type, unicode_):
+        return a.itemsize // 4
+    return a.itemsize
+
+
+def equal(x1, x2):
+    """
+    Return (x1 == x2) element-wise.
+
+    Unlike `numpy.equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    not_equal, greater_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '==', True)
+
+def not_equal(x1, x2):
+    """
+    Return (x1 != x2) element-wise.
+
+    Unlike `numpy.not_equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, greater_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '!=', True)
+
+def greater_equal(x1, x2):
+    """
+    Return (x1 >= x2) element-wise.
+
+    Unlike `numpy.greater_equal`, this comparison is performed by
+    first stripping whitespace characters from the end of the string.
+    This behavior is provided for backward-compatibility with
+    numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '>=', True)
+
+def less_equal(x1, x2):
+    """
+    Return (x1 <= x2) element-wise.
+
+    Unlike `numpy.less_equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '<=', True)
+
+def greater(x1, x2):
+    """
+    Return (x1 > x2) element-wise.
+
+    Unlike `numpy.greater`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, less_equal, less
+    """
+    return compare_chararrays(x1, x2, '>', True)
+
+def less(x1, x2):
+    """
+    Return (x1 < x2) element-wise.
+
+    Unlike `numpy.greater`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, less_equal, greater
+    """
+    return compare_chararrays(x1, x2, '<', True)
+
+def str_len(a):
+    """
+    Return len(a) element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of integers
+
+    See also
+    --------
+    __builtin__.len
+    """
+    return _vec_string(a, integer, '__len__')
+
+def add(x1, x2):
+    """
+    Return element-wise string concatenation for two arrays of str or unicode.
+
+    Arrays `x1` and `x2` must have the same shape.
+
+    Parameters
+    ----------
+    x1 : array_like of str or unicode
+        Input array.
+    x2 : array_like of str or unicode
+        Input array.
+
+    Returns
+    -------
+    add : ndarray
+        Output array of `string_` or `unicode_`, depending on input types
+        of the same shape as `x1` and `x2`.
+
+    """
+    arr1 = numpy.asarray(x1)
+    arr2 = numpy.asarray(x2)
+    out_size = _get_num_chars(arr1) + _get_num_chars(arr2)
+    dtype = _use_unicode(arr1, arr2)
+    return _vec_string(arr1, (dtype, out_size), '__add__', (arr2,))
+
+def multiply(a, i):
+    """
+    Return (a * i), that is string multiple concatenation,
+    element-wise.
+
+    Values in `i` of less than 0 are treated as 0 (which yields an
+    empty string).
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    i : array_like of ints
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    """
+    a_arr = numpy.asarray(a)
+    i_arr = numpy.asarray(i)
+    if not issubclass(i_arr.dtype.type, integer):
+        raise ValueError("Can only multiply by integers")
+    out_size = _get_num_chars(a_arr) * max(long(i_arr.max()), 0)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, out_size), '__mul__', (i_arr,))
+
+def mod(a, values):
+    """
+    Return (a % i), that is pre-Python 2.6 string formatting
+    (iterpolation), element-wise for a pair of array_likes of str
+    or unicode.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    values : array_like of values
+       These values will be element-wise interpolated into the string.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    See also
+    --------
+    str.__mod__
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, '__mod__', (values,)))
+
+def capitalize(a):
+    """
+    Return a copy of `a` with only the first character of each element
+    capitalized.
+
+    Calls `str.capitalize` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array of strings to capitalize.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input
+        types
+
+    See also
+    --------
+    str.capitalize
+
+    Examples
+    --------
+    >>> c = np.array(['a1b2','1b2a','b2a1','2a1b'],'S4'); c
+    array(['a1b2', '1b2a', 'b2a1', '2a1b'],
+        dtype='|S4')
+    >>> np.char.capitalize(c)
+    array(['A1b2', '1b2a', 'B2a1', '2a1b'],
+        dtype='|S4')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'capitalize')
+
+
+def center(a, width, fillchar=' '):
+    """
+    Return a copy of `a` with its elements centered in a string of
+    length `width`.
+
+    Calls `str.center` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The padding character to use (default is space).
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input
+        types
+
+    See also
+    --------
+    str.center
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'center', (width_arr, fillchar))
+
+
+def count(a, sub, start=0, end=None):
+    """
+    Returns an array with the number of non-overlapping occurrences of
+    substring `sub` in the range [`start`, `end`].
+
+    Calls `str.count` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+       The substring to search for.
+
+    start, end : int, optional
+       Optional arguments `start` and `end` are interpreted as slice
+       notation to specify the range in which to count.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of ints.
+
+    See also
+    --------
+    str.count
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.count(c, 'A')
+    array([3, 1, 1])
+    >>> np.char.count(c, 'aA')
+    array([3, 1, 0])
+    >>> np.char.count(c, 'A', start=1, end=4)
+    array([2, 1, 1])
+    >>> np.char.count(c, 'A', start=1, end=3)
+    array([1, 0, 0])
+
+    """
+    return _vec_string(a, integer, 'count', [sub, start] + _clean_args(end))
+
+
+def decode(a, encoding=None, errors=None):
+    """
+    Calls `str.decode` element-wise.
+
+    The set of available codecs comes from the Python standard library,
+    and may be extended at runtime.  For more information, see the
+    :mod:`codecs` module.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    encoding : str, optional
+       The name of an encoding
+
+    errors : str, optional
+       Specifies how to handle encoding errors
+
+    Returns
+    -------
+    out : ndarray
+
+    See also
+    --------
+    str.decode
+
+    Notes
+    -----
+    The type of the result will depend on the encoding specified.
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.encode(c, encoding='cp037')
+    array(['\\x81\\xc1\\x81\\xc1\\x81\\xc1', '@@\\x81\\xc1@@',
+        '\\x81\\x82\\xc2\\xc1\\xc2\\x82\\x81'],
+        dtype='|S7')
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'decode', _clean_args(encoding, errors)))
+
+
+def encode(a, encoding=None, errors=None):
+    """
+    Calls `str.encode` element-wise.
+
+    The set of available codecs comes from the Python standard library,
+    and may be extended at runtime. For more information, see the codecs
+    module.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    encoding : str, optional
+       The name of an encoding
+
+    errors : str, optional
+       Specifies how to handle encoding errors
+
+    Returns
+    -------
+    out : ndarray
+
+    See also
+    --------
+    str.encode
+
+    Notes
+    -----
+    The type of the result will depend on the encoding specified.
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'encode', _clean_args(encoding, errors)))
+
+
+def endswith(a, suffix, start=0, end=None):
+    """
+    Returns a boolean array which is `True` where the string element
+    in `a` ends with `suffix`, otherwise `False`.
+
+    Calls `str.endswith` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    suffix : str
+
+    start, end : int, optional
+        With optional `start`, test beginning at that position. With
+        optional `end`, stop comparing at that position.
+
+    Returns
+    -------
+    out : ndarray
+        Outputs an array of bools.
+
+    See also
+    --------
+    str.endswith
+
+    Examples
+    --------
+    >>> s = np.array(['foo', 'bar'])
+    >>> s[0] = 'foo'
+    >>> s[1] = 'bar'
+    >>> s
+    array(['foo', 'bar'],
+        dtype='|S3')
+    >>> np.char.endswith(s, 'ar')
+    array([False,  True], dtype=bool)
+    >>> np.char.endswith(s, 'a', start=1, end=2)
+    array([False,  True], dtype=bool)
+
+    """
+    return _vec_string(
+        a, bool_, 'endswith', [suffix, start] + _clean_args(end))
+
+
+def expandtabs(a, tabsize=8):
+    """
+    Return a copy of each string element where all tab characters are
+    replaced by one or more spaces.
+
+    Calls `str.expandtabs` element-wise.
+
+    Return a copy of each string element where all tab characters are
+    replaced by one or more spaces, depending on the current column
+    and the given `tabsize`. The column number is reset to zero after
+    each newline occurring in the string. This doesn't understand other
+    non-printing characters or escape sequences.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array
+    tabsize : int, optional
+        Replace tabs with `tabsize` number of spaces.  If not given defaults
+        to 8 spaces.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.expandtabs
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'expandtabs', (tabsize,)))
+
+
+def find(a, sub, start=0, end=None):
+    """
+    For each element, return the lowest index in the string where
+    substring `sub` is found.
+
+    Calls `str.find` element-wise.
+
+    For each element, return the lowest index in the string where
+    substring `sub` is found, such that `sub` is contained in the
+    range [`start`, `end`].
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+        Optional arguments `start` and `end` are interpreted as in
+        slice notation.
+
+    Returns
+    -------
+    out : ndarray or int
+        Output array of ints.  Returns -1 if `sub` is not found.
+
+    See also
+    --------
+    str.find
+
+    """
+    return _vec_string(
+        a, integer, 'find', [sub, start] + _clean_args(end))
+
+
+def index(a, sub, start=0, end=None):
+    """
+    Like `find`, but raises `ValueError` when the substring is not found.
+
+    Calls `str.index` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+
+    Returns
+    -------
+    out : ndarray
+        Output array of ints.  Returns -1 if `sub` is not found.
+
+    See also
+    --------
+    find, str.find
+
+    """
+    return _vec_string(
+        a, integer, 'index', [sub, start] + _clean_args(end))
+
+def isalnum(a):
+    """
+    Returns true for each element if all characters in the string are
+    alphanumeric and there is at least one character, false otherwise.
+
+    Calls `str.isalnum` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.isalnum
+    """
+    return _vec_string(a, bool_, 'isalnum')
+
+def isalpha(a):
+    """
+    Returns true for each element if all characters in the string are
+    alphabetic and there is at least one character, false otherwise.
+
+    Calls `str.isalpha` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isalpha
+    """
+    return _vec_string(a, bool_, 'isalpha')
+
+def isdigit(a):
+    """
+    Returns true for each element if all characters in the string are
+    digits and there is at least one character, false otherwise.
+
+    Calls `str.isdigit` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isdigit
+    """
+    return _vec_string(a, bool_, 'isdigit')
+
+def islower(a):
+    """
+    Returns true for each element if all cased characters in the
+    string are lowercase and there is at least one cased character,
+    false otherwise.
+
+    Calls `str.islower` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.islower
+    """
+    return _vec_string(a, bool_, 'islower')
+
+def isspace(a):
+    """
+    Returns true for each element if there are only whitespace
+    characters in the string and there is at least one character,
+    false otherwise.
+
+    Calls `str.isspace` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isspace
+    """
+    return _vec_string(a, bool_, 'isspace')
+
+def istitle(a):
+    """
+    Returns true for each element if the element is a titlecased
+    string and there is at least one character, false otherwise.
+
+    Call `str.istitle` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.istitle
+    """
+    return _vec_string(a, bool_, 'istitle')
+
+def isupper(a):
+    """
+    Returns true for each element if all cased characters in the
+    string are uppercase and there is at least one character, false
+    otherwise.
+
+    Call `str.isupper` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isupper
+    """
+    return _vec_string(a, bool_, 'isupper')
+
+def join(sep, seq):
+    """
+    Return a string which is the concatenation of the strings in the
+    sequence `seq`.
+
+    Calls `str.join` element-wise.
+
+    Parameters
+    ----------
+    sep : array_like of str or unicode
+    seq : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    See also
+    --------
+    str.join
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(sep, object_, 'join', (seq,)))
+
+
+def ljust(a, width, fillchar=' '):
+    """
+    Return an array with the elements of `a` left-justified in a
+    string of length `width`.
+
+    Calls `str.ljust` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The character to use for padding
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.ljust
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'ljust', (width_arr, fillchar))
+
+
+def lower(a):
+    """
+    Return an array with the elements converted to lowercase.
+
+    Call `str.lower` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.lower
+
+    Examples
+    --------
+    >>> c = np.array(['A1B C', '1BCA', 'BCA1']); c
+    array(['A1B C', '1BCA', 'BCA1'],
+          dtype='|S5')
+    >>> np.char.lower(c)
+    array(['a1b c', '1bca', 'bca1'],
+          dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'lower')
+
+
+def lstrip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the leading characters
+    removed.
+
+    Calls `str.lstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like, {str, unicode}
+        Input array.
+
+    chars : {str, unicode}, optional
+        The `chars` argument is a string specifying the set of
+        characters to be removed. If omitted or None, the `chars`
+        argument defaults to removing whitespace. The `chars` argument
+        is not a prefix; rather, all combinations of its values are
+        stripped.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.lstrip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+
+    The 'a' variable is unstripped from c[1] because whitespace leading.
+
+    >>> np.char.lstrip(c, 'a')
+    array(['AaAaA', '  aA  ', 'bBABba'],
+        dtype='|S7')
+
+
+    >>> np.char.lstrip(c, 'A') # leaves c unchanged
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, '')).all()
+    ... # XXX: is this a regression? this line now returns False
+    ... # np.char.lstrip(c,'') does not modify c at all.
+    True
+    >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, None)).all()
+    True
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'lstrip', (chars,))
+
+
+def partition(a, sep):
+    """
+    Partition each element in `a` around `sep`.
+
+    Calls `str.partition` element-wise.
+
+    For each element in `a`, split the element as the first
+    occurrence of `sep`, and return 3 strings containing the part
+    before the separator, the separator itself, and the part after
+    the separator. If the separator is not found, return 3 strings
+    containing the string itself, followed by two empty strings.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array
+    sep : {str, unicode}
+        Separator to split each string element in `a`.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type.
+        The output array will have an extra dimension with 3
+        elements per input element.
+
+    See also
+    --------
+    str.partition
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'partition', (sep,)))
+
+
+def replace(a, old, new, count=None):
+    """
+    For each element in `a`, return a copy of the string with all
+    occurrences of substring `old` replaced by `new`.
+
+    Calls `str.replace` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    old, new : str or unicode
+
+    count : int, optional
+        If the optional argument `count` is given, only the first
+        `count` occurrences are replaced.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.replace
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(
+            a, object_, 'replace', [old, new] + _clean_args(count)))
+
+
+def rfind(a, sub, start=0, end=None):
+    """
+    For each element in `a`, return the highest index in the string
+    where substring `sub` is found, such that `sub` is contained
+    within [`start`, `end`].
+
+    Calls `str.rfind` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+        Optional arguments `start` and `end` are interpreted as in
+        slice notation.
+
+    Returns
+    -------
+    out : ndarray
+       Output array of ints.  Return -1 on failure.
+
+    See also
+    --------
+    str.rfind
+
+    """
+    return _vec_string(
+        a, integer, 'rfind', [sub, start] + _clean_args(end))
+
+
+def rindex(a, sub, start=0, end=None):
+    """
+    Like `rfind`, but raises `ValueError` when the substring `sub` is
+    not found.
+
+    Calls `str.rindex` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+
+    Returns
+    -------
+    out : ndarray
+       Output array of ints.
+
+    See also
+    --------
+    rfind, str.rindex
+
+    """
+    return _vec_string(
+        a, integer, 'rindex', [sub, start] + _clean_args(end))
+
+
+def rjust(a, width, fillchar=' '):
+    """
+    Return an array with the elements of `a` right-justified in a
+    string of length `width`.
+
+    Calls `str.rjust` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The character to use for padding
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.rjust
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'rjust', (width_arr, fillchar))
+
+
+def rpartition(a, sep):
+    """
+    Partition (split) each element around the right-most separator.
+
+    Calls `str.rpartition` element-wise.
+
+    For each element in `a`, split the element as the last
+    occurrence of `sep`, and return 3 strings containing the part
+    before the separator, the separator itself, and the part after
+    the separator. If the separator is not found, return 3 strings
+    containing the string itself, followed by two empty strings.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array
+    sep : str or unicode
+        Right-most separator to split each element in array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of string or unicode, depending on input
+        type.  The output array will have an extra dimension with
+        3 elements per input element.
+
+    See also
+    --------
+    str.rpartition
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'rpartition', (sep,)))
+
+
+def rsplit(a, sep=None, maxsplit=None):
+    """
+    For each element in `a`, return a list of the words in the
+    string, using `sep` as the delimiter string.
+
+    Calls `str.rsplit` element-wise.
+
+    Except for splitting from the right, `rsplit`
+    behaves like `split`.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sep : str or unicode, optional
+        If `sep` is not specified or `None`, any whitespace string
+        is a separator.
+    maxsplit : int, optional
+        If `maxsplit` is given, at most `maxsplit` splits are done,
+        the rightmost ones.
+
+    Returns
+    -------
+    out : ndarray
+       Array of list objects
+
+    See also
+    --------
+    str.rsplit, split
+
+    """
+    # This will return an array of lists of different sizes, so we
+    # leave it as an object array
+    return _vec_string(
+        a, object_, 'rsplit', [sep] + _clean_args(maxsplit))
+
+
+def rstrip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the trailing
+    characters removed.
+
+    Calls `str.rstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    chars : str or unicode, optional
+       The `chars` argument is a string specifying the set of
+       characters to be removed. If omitted or None, the `chars`
+       argument defaults to removing whitespace. The `chars` argument
+       is not a suffix; rather, all combinations of its values are
+       stripped.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.rstrip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', 'abBABba'], dtype='S7'); c
+    array(['aAaAaA', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.rstrip(c, 'a')
+    array(['aAaAaA', 'abBABb'],
+        dtype='|S7')
+    >>> np.char.rstrip(c, 'A')
+    array(['aAaAa', 'abBABba'],
+        dtype='|S7')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'rstrip', (chars,))
+
+
+def split(a, sep=None, maxsplit=None):
+    """
+    For each element in `a`, return a list of the words in the
+    string, using `sep` as the delimiter string.
+
+    Calls `str.rsplit` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sep : str or unicode, optional
+       If `sep` is not specified or `None`, any whitespace string is a
+       separator.
+
+    maxsplit : int, optional
+        If `maxsplit` is given, at most `maxsplit` splits are done.
+
+    Returns
+    -------
+    out : ndarray
+        Array of list objects
+
+    See also
+    --------
+    str.split, rsplit
+
+    """
+    # This will return an array of lists of different sizes, so we
+    # leave it as an object array
+    return _vec_string(
+        a, object_, 'split', [sep] + _clean_args(maxsplit))
+
+
+def splitlines(a, keepends=None):
+    """
+    For each element in `a`, return a list of the lines in the
+    element, breaking at line boundaries.
+
+    Calls `str.splitlines` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    keepends : bool, optional
+        Line breaks are not included in the resulting list unless
+        keepends is given and true.
+
+    Returns
+    -------
+    out : ndarray
+        Array of list objects
+
+    See also
+    --------
+    str.splitlines
+
+    """
+    return _vec_string(
+        a, object_, 'splitlines', _clean_args(keepends))
+
+
+def startswith(a, prefix, start=0, end=None):
+    """
+    Returns a boolean array which is `True` where the string element
+    in `a` starts with `prefix`, otherwise `False`.
+
+    Calls `str.startswith` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    prefix : str
+
+    start, end : int, optional
+        With optional `start`, test beginning at that position. With
+        optional `end`, stop comparing at that position.
+
+    Returns
+    -------
+    out : ndarray
+        Array of booleans
+
+    See also
+    --------
+    str.startswith
+
+    """
+    return _vec_string(
+        a, bool_, 'startswith', [prefix, start] + _clean_args(end))
+
+
+def strip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the leading and
+    trailing characters removed.
+
+    Calls `str.rstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    chars : str or unicode, optional
+       The `chars` argument is a string specifying the set of
+       characters to be removed. If omitted or None, the `chars`
+       argument defaults to removing whitespace. The `chars` argument
+       is not a prefix or suffix; rather, all combinations of its
+       values are stripped.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.strip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.strip(c)
+    array(['aAaAaA', 'aA', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.strip(c, 'a') # 'a' unstripped from c[1] because whitespace leads
+    array(['AaAaA', '  aA  ', 'bBABb'],
+        dtype='|S7')
+    >>> np.char.strip(c, 'A') # 'A' unstripped from c[1] because (unprinted) ws trails
+    array(['aAaAa', '  aA  ', 'abBABba'],
+        dtype='|S7')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'strip', _clean_args(chars))
+
+
+def swapcase(a):
+    """
+    Return element-wise a copy of the string with
+    uppercase characters converted to lowercase and vice versa.
+
+    Calls `str.swapcase` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.swapcase
+
+    Examples
+    --------
+    >>> c=np.array(['a1B c','1b Ca','b Ca1','cA1b'],'S5'); c
+    array(['a1B c', '1b Ca', 'b Ca1', 'cA1b'],
+        dtype='|S5')
+    >>> np.char.swapcase(c)
+    array(['A1b C', '1B cA', 'B cA1', 'Ca1B'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'swapcase')
+
+
+def title(a):
+    """
+    Return element-wise title cased version of string or unicode.
+
+    Title case words start with uppercase characters, all remaining cased
+    characters are lowercase.
+
+    Calls `str.title` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.title
+
+    Examples
+    --------
+    >>> c=np.array(['a1b c','1b ca','b ca1','ca1b'],'S5'); c
+    array(['a1b c', '1b ca', 'b ca1', 'ca1b'],
+        dtype='|S5')
+    >>> np.char.title(c)
+    array(['A1B C', '1B Ca', 'B Ca1', 'Ca1B'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'title')
+
+
+def translate(a, table, deletechars=None):
+    """
+    For each element in `a`, return a copy of the string where all
+    characters occurring in the optional argument `deletechars` are
+    removed, and the remaining characters have been mapped through the
+    given translation table.
+
+    Calls `str.translate` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    table : str of length 256
+
+    deletechars : str
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.translate
+
+    """
+    a_arr = numpy.asarray(a)
+    if issubclass(a_arr.dtype.type, unicode_):
+        return _vec_string(
+            a_arr, a_arr.dtype, 'translate', (table,))
+    else:
+        return _vec_string(
+            a_arr, a_arr.dtype, 'translate', [table] + _clean_args(deletechars))
+
+
+def upper(a):
+    """
+    Return an array with the elements converted to uppercase.
+
+    Calls `str.upper` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.upper
+
+    Examples
+    --------
+    >>> c = np.array(['a1b c', '1bca', 'bca1']); c
+    array(['a1b c', '1bca', 'bca1'],
+        dtype='|S5')
+    >>> np.char.upper(c)
+    array(['A1B C', '1BCA', 'BCA1'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'upper')
+
+
+def zfill(a, width):
+    """
+    Return the numeric string left-filled with zeros
+
+    Calls `str.zfill` element-wise.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+    width : int
+        Width of string to left-fill elements in `a`.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.zfill
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'zfill', (width_arr,))
+
+
+def isnumeric(a):
+    """
+    For each element, return True if there are only numeric
+    characters in the element.
+
+    Calls `unicode.isnumeric` element-wise.
+
+    Numeric characters include digit characters, and all characters
+    that have the Unicode numeric value property, e.g. ``U+2155,
+    VULGAR FRACTION ONE FIFTH``.
+
+    Parameters
+    ----------
+    a : array_like, unicode
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Array of booleans of same shape as `a`.
+
+    See also
+    --------
+    unicode.isnumeric
+
+    """
+    if _use_unicode(a) != unicode_:
+        raise TypeError("isnumeric is only available for Unicode strings and arrays")
+    return _vec_string(a, bool_, 'isnumeric')
+
+
+def isdecimal(a):
+    """
+    For each element, return True if there are only decimal
+    characters in the element.
+
+    Calls `unicode.isdecimal` element-wise.
+
+    Decimal characters include digit characters, and all characters
+    that that can be used to form decimal-radix numbers,
+    e.g. ``U+0660, ARABIC-INDIC DIGIT ZERO``.
+
+    Parameters
+    ----------
+    a : array_like, unicode
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Array of booleans identical in shape to `a`.
+
+    See also
+    --------
+    unicode.isdecimal
+
+    """
+    if _use_unicode(a) != unicode_:
+        raise TypeError("isnumeric is only available for Unicode strings and arrays")
+    return _vec_string(a, bool_, 'isdecimal')
+
+
+class chararray(ndarray):
+    """
+    chararray(shape, itemsize=1, unicode=False, buffer=None, offset=0,
+              strides=None, order=None)
+
+    Provides a convenient view on arrays of string and unicode values.
+
+    .. note::
+       The `chararray` class exists for backwards compatibility with
+       Numarray, it is not recommended for new development. Starting from numpy
+       1.4, if one needs arrays of strings, it is recommended to use arrays of
+       `dtype` `object_`, `string_` or `unicode_`, and use the free functions
+       in the `numpy.char` module for fast vectorized string operations.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `.endswith`) and infix operators (e.g. ``"+", "*", "%"``)
+
+    chararrays should be created using `numpy.char.array` or
+    `numpy.char.asarray`, rather than this constructor directly.
+
+    This constructor creates the array, using `buffer` (with `offset`
+    and `strides`) if it is not ``None``. If `buffer` is ``None``, then
+    constructs a new array with `strides` in "C order", unless both
+    ``len(shape) >= 2`` and ``order='Fortran'``, in which case `strides`
+    is in "Fortran order".
+
+    Methods
+    -------
+    astype
+    argsort
+    copy
+    count
+    decode
+    dump
+    dumps
+    encode
+    endswith
+    expandtabs
+    fill
+    find
+    flatten
+    getfield
+    index
+    isalnum
+    isalpha
+    isdecimal
+    isdigit
+    islower
+    isnumeric
+    isspace
+    istitle
+    isupper
+    item
+    join
+    ljust
+    lower
+    lstrip
+    nonzero
+    put
+    ravel
+    repeat
+    replace
+    reshape
+    resize
+    rfind
+    rindex
+    rjust
+    rsplit
+    rstrip
+    searchsorted
+    setfield
+    setflags
+    sort
+    split
+    splitlines
+    squeeze
+    startswith
+    strip
+    swapaxes
+    swapcase
+    take
+    title
+    tofile
+    tolist
+    tostring
+    translate
+    transpose
+    upper
+    view
+    zfill
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of the array.
+    itemsize : int, optional
+        Length of each array element, in number of characters. Default is 1.
+    unicode : bool, optional
+        Are the array elements of type unicode (True) or string (False).
+        Default is False.
+    buffer : int, optional
+        Memory address of the start of the array data.  Default is None,
+        in which case a new array is created.
+    offset : int, optional
+        Fixed stride displacement from the beginning of an axis?
+        Default is 0. Needs to be >=0.
+    strides : array_like of ints, optional
+        Strides for the array (see `ndarray.strides` for full description).
+        Default is None.
+    order : {'C', 'F'}, optional
+        The order in which the array data is stored in memory: 'C' ->
+        "row major" order (the default), 'F' -> "column major"
+        (Fortran) order.
+
+    Examples
+    --------
+    >>> charar = np.chararray((3, 3))
+    >>> charar[:] = 'a'
+    >>> charar
+    chararray([['a', 'a', 'a'],
+           ['a', 'a', 'a'],
+           ['a', 'a', 'a']],
+          dtype='|S1')
+
+    >>> charar = np.chararray(charar.shape, itemsize=5)
+    >>> charar[:] = 'abc'
+    >>> charar
+    chararray([['abc', 'abc', 'abc'],
+           ['abc', 'abc', 'abc'],
+           ['abc', 'abc', 'abc']],
+          dtype='|S5')
+
+    """
+    def __new__(subtype, shape, itemsize=1, unicode=False, buffer=None,
+                offset=0, strides=None, order='C'):
+        global _globalvar
+
+        if unicode:
+            dtype = unicode_
+        else:
+            dtype = string_
+
+        # force itemsize to be a Python long, since using Numpy integer
+        # types results in itemsize.itemsize being used as the size of
+        # strings in the new array.
+        itemsize = long(itemsize)
+
+        if sys.version_info[0] >= 3 and isinstance(buffer, _unicode):
+            # On Py3, unicode objects do not have the buffer interface
+            filler = buffer
+            buffer = None
+        else:
+            filler = None
+
+        _globalvar = 1
+        if buffer is None:
+            self = ndarray.__new__(subtype, shape, (dtype, itemsize),
+                                   order=order)
+        else:
+            self = ndarray.__new__(subtype, shape, (dtype, itemsize),
+                                   buffer=buffer,
+                                   offset=offset, strides=strides,
+                                   order=order)
+        if filler is not None:
+            self[...] = filler
+        _globalvar = 0
+        return self
+
+    def __array_finalize__(self, obj):
+        # The b is a special case because it is used for reconstructing.
+        if not _globalvar and self.dtype.char not in 'SUbc':
+            raise ValueError("Can only create a chararray from string data.")
+
+    def __getitem__(self, obj):
+        val = ndarray.__getitem__(self, obj)
+
+        if isinstance(val, character):
+            temp = val.rstrip()
+            if _len(temp) == 0:
+                val = ''
+            else:
+                val = temp
+
+        return val
+
+    # IMPLEMENTATION NOTE: Most of the methods of this class are
+    # direct delegations to the free functions in this module.
+    # However, those that return an array of strings should instead
+    # return a chararray, so some extra wrapping is required.
+
+    def __eq__(self, other):
+        """
+        Return (self == other) element-wise.
+
+        See also
+        --------
+        equal
+        """
+        return equal(self, other)
+
+    def __ne__(self, other):
+        """
+        Return (self != other) element-wise.
+
+        See also
+        --------
+        not_equal
+        """
+        return not_equal(self, other)
+
+    def __ge__(self, other):
+        """
+        Return (self >= other) element-wise.
+
+        See also
+        --------
+        greater_equal
+        """
+        return greater_equal(self, other)
+
+    def __le__(self, other):
+        """
+        Return (self <= other) element-wise.
+
+        See also
+        --------
+        less_equal
+        """
+        return less_equal(self, other)
+
+    def __gt__(self, other):
+        """
+        Return (self > other) element-wise.
+
+        See also
+        --------
+        greater
+        """
+        return greater(self, other)
+
+    def __lt__(self, other):
+        """
+        Return (self < other) element-wise.
+
+        See also
+        --------
+        less
+        """
+        return less(self, other)
+
+    def __add__(self, other):
+        """
+        Return (self + other), that is string concatenation,
+        element-wise for a pair of array_likes of str or unicode.
+
+        See also
+        --------
+        add
+        """
+        return asarray(add(self, other))
+
+    def __radd__(self, other):
+        """
+        Return (other + self), that is string concatenation,
+        element-wise for a pair of array_likes of `string_` or `unicode_`.
+
+        See also
+        --------
+        add
+        """
+        return asarray(add(numpy.asarray(other), self))
+
+    def __mul__(self, i):
+        """
+        Return (self * i), that is string multiple concatenation,
+        element-wise.
+
+        See also
+        --------
+        multiply
+        """
+        return asarray(multiply(self, i))
+
+    def __rmul__(self, i):
+        """
+        Return (self * i), that is string multiple concatenation,
+        element-wise.
+
+        See also
+        --------
+        multiply
+        """
+        return asarray(multiply(self, i))
+
+    def __mod__(self, i):
+        """
+        Return (self % i), that is pre-Python 2.6 string formatting
+        (iterpolation), element-wise for a pair of array_likes of `string_`
+        or `unicode_`.
+
+        See also
+        --------
+        mod
+        """
+        return asarray(mod(self, i))
+
+    def __rmod__(self, other):
+        return NotImplemented
+
+    def argsort(self, axis=-1, kind='quicksort', order=None):
+        """
+        Return the indices that sort the array lexicographically.
+
+        For full documentation see `numpy.argsort`, for which this method is
+        in fact merely a "thin wrapper."
+
+        Examples
+        --------
+        >>> c = np.array(['a1b c', '1b ca', 'b ca1', 'Ca1b'], 'S5')
+        >>> c = c.view(np.chararray); c
+        chararray(['a1b c', '1b ca', 'b ca1', 'Ca1b'],
+              dtype='|S5')
+        >>> c[c.argsort()]
+        chararray(['1b ca', 'Ca1b', 'a1b c', 'b ca1'],
+              dtype='|S5')
+
+        """
+        return self.__array__().argsort(axis, kind, order)
+    argsort.__doc__ = ndarray.argsort.__doc__
+
+    def capitalize(self):
+        """
+        Return a copy of `self` with only the first character of each element
+        capitalized.
+
+        See also
+        --------
+        char.capitalize
+
+        """
+        return asarray(capitalize(self))
+
+    def center(self, width, fillchar=' '):
+        """
+        Return a copy of `self` with its elements centered in a
+        string of length `width`.
+
+        See also
+        --------
+        center
+        """
+        return asarray(center(self, width, fillchar))
+
+    def count(self, sub, start=0, end=None):
+        """
+        Returns an array with the number of non-overlapping occurrences of
+        substring `sub` in the range [`start`, `end`].
+
+        See also
+        --------
+        char.count
+
+        """
+        return count(self, sub, start, end)
+
+    def decode(self, encoding=None, errors=None):
+        """
+        Calls `str.decode` element-wise.
+
+        See also
+        --------
+        char.decode
+
+        """
+        return decode(self, encoding, errors)
+
+    def encode(self, encoding=None, errors=None):
+        """
+        Calls `str.encode` element-wise.
+
+        See also
+        --------
+        char.encode
+
+        """
+        return encode(self, encoding, errors)
+
+    def endswith(self, suffix, start=0, end=None):
+        """
+        Returns a boolean array which is `True` where the string element
+        in `self` ends with `suffix`, otherwise `False`.
+
+        See also
+        --------
+        char.endswith
+
+        """
+        return endswith(self, suffix, start, end)
+
+    def expandtabs(self, tabsize=8):
+        """
+        Return a copy of each string element where all tab characters are
+        replaced by one or more spaces.
+
+        See also
+        --------
+        char.expandtabs
+
+        """
+        return asarray(expandtabs(self, tabsize))
+
+    def find(self, sub, start=0, end=None):
+        """
+        For each element, return the lowest index in the string where
+        substring `sub` is found.
+
+        See also
+        --------
+        char.find
+
+        """
+        return find(self, sub, start, end)
+
+    def index(self, sub, start=0, end=None):
+        """
+        Like `find`, but raises `ValueError` when the substring is not found.
+
+        See also
+        --------
+        char.index
+
+        """
+        return index(self, sub, start, end)
+
+    def isalnum(self):
+        """
+        Returns true for each element if all characters in the string
+        are alphanumeric and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isalnum
+
+        """
+        return isalnum(self)
+
+    def isalpha(self):
+        """
+        Returns true for each element if all characters in the string
+        are alphabetic and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isalpha
+
+        """
+        return isalpha(self)
+
+    def isdigit(self):
+        """
+        Returns true for each element if all characters in the string are
+        digits and there is at least one character, false otherwise.
+
+        See also
+        --------
+        char.isdigit
+
+        """
+        return isdigit(self)
+
+    def islower(self):
+        """
+        Returns true for each element if all cased characters in the
+        string are lowercase and there is at least one cased character,
+        false otherwise.
+
+        See also
+        --------
+        char.islower
+
+        """
+        return islower(self)
+
+    def isspace(self):
+        """
+        Returns true for each element if there are only whitespace
+        characters in the string and there is at least one character,
+        false otherwise.
+
+        See also
+        --------
+        char.isspace
+
+        """
+        return isspace(self)
+
+    def istitle(self):
+        """
+        Returns true for each element if the element is a titlecased
+        string and there is at least one character, false otherwise.
+
+        See also
+        --------
+        char.istitle
+
+        """
+        return istitle(self)
+
+    def isupper(self):
+        """
+        Returns true for each element if all cased characters in the
+        string are uppercase and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isupper
+
+        """
+        return isupper(self)
+
+    def join(self, seq):
+        """
+        Return a string which is the concatenation of the strings in the
+        sequence `seq`.
+
+        See also
+        --------
+        char.join
+
+        """
+        return join(self, seq)
+
+    def ljust(self, width, fillchar=' '):
+        """
+        Return an array with the elements of `self` left-justified in a
+        string of length `width`.
+
+        See also
+        --------
+        char.ljust
+
+        """
+        return asarray(ljust(self, width, fillchar))
+
+    def lower(self):
+        """
+        Return an array with the elements of `self` converted to
+        lowercase.
+
+        See also
+        --------
+        char.lower
+
+        """
+        return asarray(lower(self))
+
+    def lstrip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the leading characters
+        removed.
+
+        See also
+        --------
+        char.lstrip
+
+        """
+        return asarray(lstrip(self, chars))
+
+    def partition(self, sep):
+        """
+        Partition each element in `self` around `sep`.
+
+        See also
+        --------
+        partition
+        """
+        return asarray(partition(self, sep))
+
+    def replace(self, old, new, count=None):
+        """
+        For each element in `self`, return a copy of the string with all
+        occurrences of substring `old` replaced by `new`.
+
+        See also
+        --------
+        char.replace
+
+        """
+        return asarray(replace(self, old, new, count))
+
+    def rfind(self, sub, start=0, end=None):
+        """
+        For each element in `self`, return the highest index in the string
+        where substring `sub` is found, such that `sub` is contained
+        within [`start`, `end`].
+
+        See also
+        --------
+        char.rfind
+
+        """
+        return rfind(self, sub, start, end)
+
+    def rindex(self, sub, start=0, end=None):
+        """
+        Like `rfind`, but raises `ValueError` when the substring `sub` is
+        not found.
+
+        See also
+        --------
+        char.rindex
+
+        """
+        return rindex(self, sub, start, end)
+
+    def rjust(self, width, fillchar=' '):
+        """
+        Return an array with the elements of `self`
+        right-justified in a string of length `width`.
+
+        See also
+        --------
+        char.rjust
+
+        """
+        return asarray(rjust(self, width, fillchar))
+
+    def rpartition(self, sep):
+        """
+        Partition each element in `self` around `sep`.
+
+        See also
+        --------
+        rpartition
+        """
+        return asarray(rpartition(self, sep))
+
+    def rsplit(self, sep=None, maxsplit=None):
+        """
+        For each element in `self`, return a list of the words in
+        the string, using `sep` as the delimiter string.
+
+        See also
+        --------
+        char.rsplit
+
+        """
+        return rsplit(self, sep, maxsplit)
+
+    def rstrip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the trailing
+        characters removed.
+
+        See also
+        --------
+        char.rstrip
+
+        """
+        return asarray(rstrip(self, chars))
+
+    def split(self, sep=None, maxsplit=None):
+        """
+        For each element in `self`, return a list of the words in the
+        string, using `sep` as the delimiter string.
+
+        See also
+        --------
+        char.split
+
+        """
+        return split(self, sep, maxsplit)
+
+    def splitlines(self, keepends=None):
+        """
+        For each element in `self`, return a list of the lines in the
+        element, breaking at line boundaries.
+
+        See also
+        --------
+        char.splitlines
+
+        """
+        return splitlines(self, keepends)
+
+    def startswith(self, prefix, start=0, end=None):
+        """
+        Returns a boolean array which is `True` where the string element
+        in `self` starts with `prefix`, otherwise `False`.
+
+        See also
+        --------
+        char.startswith
+
+        """
+        return startswith(self, prefix, start, end)
+
+    def strip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the leading and
+        trailing characters removed.
+
+        See also
+        --------
+        char.strip
+
+        """
+        return asarray(strip(self, chars))
+
+    def swapcase(self):
+        """
+        For each element in `self`, return a copy of the string with
+        uppercase characters converted to lowercase and vice versa.
+
+        See also
+        --------
+        char.swapcase
+
+        """
+        return asarray(swapcase(self))
+
+    def title(self):
+        """
+        For each element in `self`, return a titlecased version of the
+        string: words start with uppercase characters, all remaining cased
+        characters are lowercase.
+
+        See also
+        --------
+        char.title
+
+        """
+        return asarray(title(self))
+
+    def translate(self, table, deletechars=None):
+        """
+        For each element in `self`, return a copy of the string where
+        all characters occurring in the optional argument
+        `deletechars` are removed, and the remaining characters have
+        been mapped through the given translation table.
+
+        See also
+        --------
+        char.translate
+
+        """
+        return asarray(translate(self, table, deletechars))
+
+    def upper(self):
+        """
+        Return an array with the elements of `self` converted to
+        uppercase.
+
+        See also
+        --------
+        char.upper
+
+        """
+        return asarray(upper(self))
+
+    def zfill(self, width):
+        """
+        Return the numeric string left-filled with zeros in a string of
+        length `width`.
+
+        See also
+        --------
+        char.zfill
+
+        """
+        return asarray(zfill(self, width))
+
+    def isnumeric(self):
+        """
+        For each element in `self`, return True if there are only
+        numeric characters in the element.
+
+        See also
+        --------
+        char.isnumeric
+
+        """
+        return isnumeric(self)
+
+    def isdecimal(self):
+        """
+        For each element in `self`, return True if there are only
+        decimal characters in the element.
+
+        See also
+        --------
+        char.isdecimal
+
+        """
+        return isdecimal(self)
+
+
+def array(obj, itemsize=None, copy=True, unicode=None, order=None):
+    """
+    Create a `chararray`.
+
+    .. note::
+       This class is provided for numarray backward-compatibility.
+       New code (not concerned with numarray compatibility) should use
+       arrays of type `string_` or `unicode_` and use the free functions
+       in :mod:`numpy.char <numpy.core.defchararray>` for fast
+       vectorized string operations instead.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `str.endswith`) and infix operators (e.g. ``+, *, %``)
+
+    Parameters
+    ----------
+    obj : array of str or unicode-like
+
+    itemsize : int, optional
+        `itemsize` is the number of characters per scalar in the
+        resulting array.  If `itemsize` is None, and `obj` is an
+        object array or a Python list, the `itemsize` will be
+        automatically determined.  If `itemsize` is provided and `obj`
+        is of type str or unicode, then the `obj` string will be
+        chunked into `itemsize` pieces.
+
+    copy : bool, optional
+        If true (default), then the object is copied.  Otherwise, a copy
+        will only be made if __array__ returns a copy, if obj is a
+        nested sequence, or if a copy is needed to satisfy any of the other
+        requirements (`itemsize`, unicode, `order`, etc.).
+
+    unicode : bool, optional
+        When true, the resulting `chararray` can contain Unicode
+        characters, when false only 8-bit characters.  If unicode is
+        `None` and `obj` is one of the following:
+
+          - a `chararray`,
+          - an ndarray of type `str` or `unicode`
+          - a Python str or unicode object,
+
+        then the unicode setting of the output array will be
+        automatically determined.
+
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C' (default), then the
+        array will be in C-contiguous order (last-index varies the
+        fastest).  If order is 'F', then the returned array
+        will be in Fortran-contiguous order (first-index varies the
+        fastest).  If order is 'A', then the returned array may
+        be in any order (either C-, Fortran-contiguous, or even
+        discontiguous).
+    """
+    if isinstance(obj, (_bytes, _unicode)):
+        if unicode is None:
+            if isinstance(obj, _unicode):
+                unicode = True
+            else:
+                unicode = False
+
+        if itemsize is None:
+            itemsize = _len(obj)
+        shape = _len(obj) // itemsize
+
+        if unicode:
+            if sys.maxunicode == 0xffff:
+                # On a narrow Python build, the buffer for Unicode
+                # strings is UCS2, which doesn't match the buffer for
+                # Numpy Unicode types, which is ALWAYS UCS4.
+                # Therefore, we need to convert the buffer.  On Python
+                # 2.6 and later, we can use the utf_32 codec.  Earlier
+                # versions don't have that codec, so we convert to a
+                # numerical array that matches the input buffer, and
+                # then use Numpy to convert it to UCS4.  All of this
+                # should happen in native endianness.
+                if sys.hexversion >= 0x2060000:
+                    obj = obj.encode('utf_32')
+                else:
+                    if isinstance(obj, str):
+                        ascii = numpy.frombuffer(obj, 'u1')
+                        ucs4 = numpy.array(ascii, 'u4')
+                        obj = ucs4.data
+                    else:
+                        ucs2 = numpy.frombuffer(obj, 'u2')
+                        ucs4 = numpy.array(ucs2, 'u4')
+                        obj = ucs4.data
+            else:
+                obj = _unicode(obj)
+        else:
+            # Let the default Unicode -> string encoding (if any) take
+            # precedence.
+            obj = _bytes(obj)
+
+        return chararray(shape, itemsize=itemsize, unicode=unicode,
+                         buffer=obj, order=order)
+
+    if isinstance(obj, (list, tuple)):
+        obj = numpy.asarray(obj)
+
+    if isinstance(obj, ndarray) and issubclass(obj.dtype.type, character):
+        # If we just have a vanilla chararray, create a chararray
+        # view around it.
+        if not isinstance(obj, chararray):
+            obj = obj.view(chararray)
+
+        if itemsize is None:
+            itemsize = obj.itemsize
+            # itemsize is in 8-bit chars, so for Unicode, we need
+            # to divide by the size of a single Unicode character,
+            # which for Numpy is always 4
+            if issubclass(obj.dtype.type, unicode_):
+                itemsize //= 4
+
+        if unicode is None:
+            if issubclass(obj.dtype.type, unicode_):
+                unicode = True
+            else:
+                unicode = False
+
+        if unicode:
+            dtype = unicode_
+        else:
+            dtype = string_
+
+        if order is not None:
+            obj = numpy.asarray(obj, order=order)
+        if (copy or
+                (itemsize != obj.itemsize) or
+                (not unicode and isinstance(obj, unicode_)) or
+                (unicode and isinstance(obj, string_))):
+            obj = obj.astype((dtype, long(itemsize)))
+        return obj
+
+    if isinstance(obj, ndarray) and issubclass(obj.dtype.type, object):
+        if itemsize is None:
+            # Since no itemsize was specified, convert the input array to
+            # a list so the ndarray constructor will automatically
+            # determine the itemsize for us.
+            obj = obj.tolist()
+            # Fall through to the default case
+
+    if unicode:
+        dtype = unicode_
+    else:
+        dtype = string_
+
+    if itemsize is None:
+        val = narray(obj, dtype=dtype, order=order, subok=True)
+    else:
+        val = narray(obj, dtype=(dtype, itemsize), order=order, subok=True)
+    return val.view(chararray)
+
+
+def asarray(obj, itemsize=None, unicode=None, order=None):
+    """
+    Convert the input to a `chararray`, copying the data only if
+    necessary.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `str.endswith`) and infix operators (e.g. ``+``, ``*``,``%``)
+
+    Parameters
+    ----------
+    obj : array of str or unicode-like
+
+    itemsize : int, optional
+        `itemsize` is the number of characters per scalar in the
+        resulting array.  If `itemsize` is None, and `obj` is an
+        object array or a Python list, the `itemsize` will be
+        automatically determined.  If `itemsize` is provided and `obj`
+        is of type str or unicode, then the `obj` string will be
+        chunked into `itemsize` pieces.
+
+    unicode : bool, optional
+        When true, the resulting `chararray` can contain Unicode
+        characters, when false only 8-bit characters.  If unicode is
+        `None` and `obj` is one of the following:
+
+          - a `chararray`,
+          - an ndarray of type `str` or 'unicode`
+          - a Python str or unicode object,
+
+        then the unicode setting of the output array will be
+        automatically determined.
+
+    order : {'C', 'F'}, optional
+        Specify the order of the array.  If order is 'C' (default), then the
+        array will be in C-contiguous order (last-index varies the
+        fastest).  If order is 'F', then the returned array
+        will be in Fortran-contiguous order (first-index varies the
+        fastest).
+    """
+    return array(obj, itemsize, copy=False,
+                 unicode=unicode, order=order)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.py
new file mode 100644
index 0000000000..4faeb557a6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.py
@@ -0,0 +1,3100 @@
+"""Module containing non-deprecated functions borrowed from Numeric.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types
+import warnings
+
+import numpy as np
+from .. import VisibleDeprecationWarning
+from . import multiarray as mu
+from . import umath as um
+from . import numerictypes as nt
+from .numeric import asarray, array, asanyarray, concatenate
+from . import _methods
+
+
+_dt_ = nt.sctype2char
+
+
+# functions that are methods
+__all__ = [
+    'alen', 'all', 'alltrue', 'amax', 'amin', 'any', 'argmax',
+    'argmin', 'argpartition', 'argsort', 'around', 'choose', 'clip',
+    'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean',
+    'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put',
+    'rank', 'ravel', 'repeat', 'reshape', 'resize', 'round_',
+    'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze',
+    'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var',
+    ]
+
+
+try:
+    _gentype = types.GeneratorType
+except AttributeError:
+    _gentype = type(None)
+
+# save away Python sum
+_sum_ = sum
+
+
+# functions that are now methods
+def _wrapit(obj, method, *args, **kwds):
+    try:
+        wrap = obj.__array_wrap__
+    except AttributeError:
+        wrap = None
+    result = getattr(asarray(obj), method)(*args, **kwds)
+    if wrap:
+        if not isinstance(result, mu.ndarray):
+            result = asarray(result)
+        result = wrap(result)
+    return result
+
+
+def take(a, indices, axis=None, out=None, mode='raise'):
+    """
+    Take elements from an array along an axis.
+
+    This function does the same thing as "fancy" indexing (indexing arrays
+    using arrays); however, it can be easier to use if you need elements
+    along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        The source array.
+    indices : array_like
+        The indices of the values to extract.
+
+        .. versionadded:: 1.8.0
+
+        Also allow scalars for indices.
+    axis : int, optional
+        The axis over which to select values. By default, the flattened
+        input array is used.
+    out : ndarray, optional
+        If provided, the result will be placed in this array. It should
+        be of the appropriate shape and dtype.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        'clip' mode means that all indices that are too large are replaced
+        by the index that addresses the last element along that axis. Note
+        that this disables indexing with negative numbers.
+
+    Returns
+    -------
+    subarray : ndarray
+        The returned array has the same type as `a`.
+
+    See Also
+    --------
+    compress : Take elements using a boolean mask
+    ndarray.take : equivalent method
+
+    Examples
+    --------
+    >>> a = [4, 3, 5, 7, 6, 8]
+    >>> indices = [0, 1, 4]
+    >>> np.take(a, indices)
+    array([4, 3, 6])
+
+    In this example if `a` is an ndarray, "fancy" indexing can be used.
+
+    >>> a = np.array(a)
+    >>> a[indices]
+    array([4, 3, 6])
+
+    If `indices` is not one dimensional, the output also has these dimensions.
+
+    >>> np.take(a, [[0, 1], [2, 3]])
+    array([[4, 3],
+           [5, 7]])
+    """
+    try:
+        take = a.take
+    except AttributeError:
+        return _wrapit(a, 'take', indices, axis, out, mode)
+    return take(indices, axis, out, mode)
+
+
+# not deprecated --- copy if necessary, view otherwise
+def reshape(a, newshape, order='C'):
+    """
+    Gives a new shape to an array without changing its data.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be reshaped.
+    newshape : int or tuple of ints
+        The new shape should be compatible with the original shape. If
+        an integer, then the result will be a 1-D array of that length.
+        One shape dimension can be -1. In this case, the value is inferred
+        from the length of the array and remaining dimensions.
+    order : {'C', 'F', 'A'}, optional
+        Read the elements of `a` using this index order, and place the elements
+        into the reshaped array using this index order.  'C' means to
+        read / write the elements using C-like index order, with the last axis
+        index changing fastest, back to the first axis index changing slowest.
+        'F' means to read / write the elements using Fortran-like index order,
+        with the first index changing fastest, and the last index changing
+        slowest.
+        Note that the 'C' and 'F' options take no account of the memory layout
+        of the underlying array, and only refer to the order of indexing.  'A'
+        means to read / write the elements in Fortran-like index order if `a`
+        is Fortran *contiguous* in memory, C-like order otherwise.
+
+    Returns
+    -------
+    reshaped_array : ndarray
+        This will be a new view object if possible; otherwise, it will
+        be a copy.  Note there is no guarantee of the *memory layout* (C- or
+        Fortran- contiguous) of the returned array.
+
+    See Also
+    --------
+    ndarray.reshape : Equivalent method.
+
+    Notes
+    -----
+    It is not always possible to change the shape of an array without
+    copying the data. If you want an error to be raise if the data is copied,
+    you should assign the new shape to the shape attribute of the array::
+
+     >>> a = np.zeros((10, 2))
+     # A transpose make the array non-contiguous
+     >>> b = a.T
+     # Taking a view makes it possible to modify the shape without modifying
+     # the initial object.
+     >>> c = b.view()
+     >>> c.shape = (20)
+     AttributeError: incompatible shape for a non-contiguous array
+
+    The `order` keyword gives the index ordering both for *fetching* the values
+    from `a`, and then *placing* the values into the output array.
+    For example, let's say you have an array:
+
+    >>> a = np.arange(6).reshape((3, 2))
+    >>> a
+    array([[0, 1],
+           [2, 3],
+           [4, 5]])
+
+    You can think of reshaping as first raveling the array (using the given
+    index order), then inserting the elements from the raveled array into the
+    new array using the same kind of index ordering as was used for the
+    raveling.
+
+    >>> np.reshape(a, (2, 3)) # C-like index ordering
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshape
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.reshape(a, (2, 3), order='F') # Fortran-like index ordering
+    array([[0, 4, 3],
+           [2, 1, 5]])
+    >>> np.reshape(np.ravel(a, order='F'), (2, 3), order='F')
+    array([[0, 4, 3],
+           [2, 1, 5]])
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3], [4,5,6]])
+    >>> np.reshape(a, 6)
+    array([1, 2, 3, 4, 5, 6])
+    >>> np.reshape(a, 6, order='F')
+    array([1, 4, 2, 5, 3, 6])
+
+    >>> np.reshape(a, (3,-1))       # the unspecified value is inferred to be 2
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    """
+    try:
+        reshape = a.reshape
+    except AttributeError:
+        return _wrapit(a, 'reshape', newshape, order=order)
+    return reshape(newshape, order=order)
+
+
+def choose(a, choices, out=None, mode='raise'):
+    """
+    Construct an array from an index array and a set of arrays to choose from.
+
+    First of all, if confused or uncertain, definitely look at the Examples -
+    in its full generality, this function is less simple than it might
+    seem from the following code description (below ndi =
+    `numpy.lib.index_tricks`):
+
+    ``np.choose(a,c) == np.array([c[a[I]][I] for I in ndi.ndindex(a.shape)])``.
+
+    But this omits some subtleties.  Here is a fully general summary:
+
+    Given an "index" array (`a`) of integers and a sequence of `n` arrays
+    (`choices`), `a` and each choice array are first broadcast, as necessary,
+    to arrays of a common shape; calling these *Ba* and *Bchoices[i], i =
+    0,...,n-1* we have that, necessarily, ``Ba.shape == Bchoices[i].shape``
+    for each `i`.  Then, a new array with shape ``Ba.shape`` is created as
+    follows:
+
+    * if ``mode=raise`` (the default), then, first of all, each element of
+      `a` (and thus `Ba`) must be in the range `[0, n-1]`; now, suppose that
+      `i` (in that range) is the value at the `(j0, j1, ..., jm)` position
+      in `Ba` - then the value at the same position in the new array is the
+      value in `Bchoices[i]` at that same position;
+
+    * if ``mode=wrap``, values in `a` (and thus `Ba`) may be any (signed)
+      integer; modular arithmetic is used to map integers outside the range
+      `[0, n-1]` back into that range; and then the new array is constructed
+      as above;
+
+    * if ``mode=clip``, values in `a` (and thus `Ba`) may be any (signed)
+      integer; negative integers are mapped to 0; values greater than `n-1`
+      are mapped to `n-1`; and then the new array is constructed as above.
+
+    Parameters
+    ----------
+    a : int array
+        This array must contain integers in `[0, n-1]`, where `n` is the number
+        of choices, unless ``mode=wrap`` or ``mode=clip``, in which cases any
+        integers are permissible.
+    choices : sequence of arrays
+        Choice arrays. `a` and all of the choices must be broadcastable to the
+        same shape.  If `choices` is itself an array (not recommended), then
+        its outermost dimension (i.e., the one corresponding to
+        ``choices.shape[0]``) is taken as defining the "sequence".
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+    mode : {'raise' (default), 'wrap', 'clip'}, optional
+        Specifies how indices outside `[0, n-1]` will be treated:
+
+          * 'raise' : an exception is raised
+          * 'wrap' : value becomes value mod `n`
+          * 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1
+
+    Returns
+    -------
+    merged_array : array
+        The merged result.
+
+    Raises
+    ------
+    ValueError: shape mismatch
+        If `a` and each choice array are not all broadcastable to the same
+        shape.
+
+    See Also
+    --------
+    ndarray.choose : equivalent method
+
+    Notes
+    -----
+    To reduce the chance of misinterpretation, even though the following
+    "abuse" is nominally supported, `choices` should neither be, nor be
+    thought of as, a single array, i.e., the outermost sequence-like container
+    should be either a list or a tuple.
+
+    Examples
+    --------
+
+    >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+    ...   [20, 21, 22, 23], [30, 31, 32, 33]]
+    >>> np.choose([2, 3, 1, 0], choices
+    ... # the first element of the result will be the first element of the
+    ... # third (2+1) "array" in choices, namely, 20; the second element
+    ... # will be the second element of the fourth (3+1) choice array, i.e.,
+    ... # 31, etc.
+    ... )
+    array([20, 31, 12,  3])
+    >>> np.choose([2, 4, 1, 0], choices, mode='clip') # 4 goes to 3 (4-1)
+    array([20, 31, 12,  3])
+    >>> # because there are 4 choice arrays
+    >>> np.choose([2, 4, 1, 0], choices, mode='wrap') # 4 goes to (4 mod 4)
+    array([20,  1, 12,  3])
+    >>> # i.e., 0
+
+    A couple examples illustrating how choose broadcasts:
+
+    >>> a = [[1, 0, 1], [0, 1, 0], [1, 0, 1]]
+    >>> choices = [-10, 10]
+    >>> np.choose(a, choices)
+    array([[ 10, -10,  10],
+           [-10,  10, -10],
+           [ 10, -10,  10]])
+
+    >>> # With thanks to Anne Archibald
+    >>> a = np.array([0, 1]).reshape((2,1,1))
+    >>> c1 = np.array([1, 2, 3]).reshape((1,3,1))
+    >>> c2 = np.array([-1, -2, -3, -4, -5]).reshape((1,1,5))
+    >>> np.choose(a, (c1, c2)) # result is 2x3x5, res[0,:,:]=c1, res[1,:,:]=c2
+    array([[[ 1,  1,  1,  1,  1],
+            [ 2,  2,  2,  2,  2],
+            [ 3,  3,  3,  3,  3]],
+           [[-1, -2, -3, -4, -5],
+            [-1, -2, -3, -4, -5],
+            [-1, -2, -3, -4, -5]]])
+
+    """
+    try:
+        choose = a.choose
+    except AttributeError:
+        return _wrapit(a, 'choose', choices, out=out, mode=mode)
+    return choose(choices, out=out, mode=mode)
+
+
+def repeat(a, repeats, axis=None):
+    """
+    Repeat elements of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    repeats : int or array of ints
+        The number of repetitions for each element.  `repeats` is broadcasted
+        to fit the shape of the given axis.
+    axis : int, optional
+        The axis along which to repeat values.  By default, use the
+        flattened input array, and return a flat output array.
+
+    Returns
+    -------
+    repeated_array : ndarray
+        Output array which has the same shape as `a`, except along
+        the given axis.
+
+    See Also
+    --------
+    tile : Tile an array.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2],[3,4]])
+    >>> np.repeat(x, 2)
+    array([1, 1, 2, 2, 3, 3, 4, 4])
+    >>> np.repeat(x, 3, axis=1)
+    array([[1, 1, 1, 2, 2, 2],
+           [3, 3, 3, 4, 4, 4]])
+    >>> np.repeat(x, [1, 2], axis=0)
+    array([[1, 2],
+           [3, 4],
+           [3, 4]])
+
+    """
+    try:
+        repeat = a.repeat
+    except AttributeError:
+        return _wrapit(a, 'repeat', repeats, axis)
+    return repeat(repeats, axis)
+
+
+def put(a, ind, v, mode='raise'):
+    """
+    Replaces specified elements of an array with given values.
+
+    The indexing works on the flattened target array. `put` is roughly
+    equivalent to:
+
+    ::
+
+        a.flat[ind] = v
+
+    Parameters
+    ----------
+    a : ndarray
+        Target array.
+    ind : array_like
+        Target indices, interpreted as integers.
+    v : array_like
+        Values to place in `a` at target indices. If `v` is shorter than
+        `ind` it will be repeated as necessary.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        'clip' mode means that all indices that are too large are replaced
+        by the index that addresses the last element along that axis. Note
+        that this disables indexing with negative numbers.
+
+    See Also
+    --------
+    putmask, place
+
+    Examples
+    --------
+    >>> a = np.arange(5)
+    >>> np.put(a, [0, 2], [-44, -55])
+    >>> a
+    array([-44,   1, -55,   3,   4])
+
+    >>> a = np.arange(5)
+    >>> np.put(a, 22, -5, mode='clip')
+    >>> a
+    array([ 0,  1,  2,  3, -5])
+
+    """
+    try:
+        put = a.put
+    except AttributeError:
+        raise TypeError("argument 1 must be numpy.ndarray, "
+                        "not {name}".format(name=type(a).__name__))
+
+    return put(ind, v, mode)
+
+
+def swapaxes(a, axis1, axis2):
+    """
+    Interchange two axes of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis1 : int
+        First axis.
+    axis2 : int
+        Second axis.
+
+    Returns
+    -------
+    a_swapped : ndarray
+        For Numpy >= 1.10, if `a` is an ndarray, then a view of `a` is
+        returned; otherwise a new array is created. For earlier Numpy
+        versions a view of `a` is returned only if the order of the
+        axes is changed, otherwise the input array is returned.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3]])
+    >>> np.swapaxes(x,0,1)
+    array([[1],
+           [2],
+           [3]])
+
+    >>> x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]])
+    >>> x
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+
+    >>> np.swapaxes(x,0,2)
+    array([[[0, 4],
+            [2, 6]],
+           [[1, 5],
+            [3, 7]]])
+
+    """
+    try:
+        swapaxes = a.swapaxes
+    except AttributeError:
+        return _wrapit(a, 'swapaxes', axis1, axis2)
+    return swapaxes(axis1, axis2)
+
+
+def transpose(a, axes=None):
+    """
+    Permute the dimensions of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axes : list of ints, optional
+        By default, reverse the dimensions, otherwise permute the axes
+        according to the values given.
+
+    Returns
+    -------
+    p : ndarray
+        `a` with its axes permuted.  A view is returned whenever
+        possible.
+
+    See Also
+    --------
+    moveaxis
+    argsort
+
+    Notes
+    -----
+    Use `transpose(a, argsort(axes))` to invert the transposition of tensors
+    when using the `axes` keyword argument.
+
+    Transposing a 1-D array returns an unchanged view of the original array.
+
+    Examples
+    --------
+    >>> x = np.arange(4).reshape((2,2))
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+
+    >>> np.transpose(x)
+    array([[0, 2],
+           [1, 3]])
+
+    >>> x = np.ones((1, 2, 3))
+    >>> np.transpose(x, (1, 0, 2)).shape
+    (2, 1, 3)
+
+    """
+    try:
+        transpose = a.transpose
+    except AttributeError:
+        return _wrapit(a, 'transpose', axes)
+    return transpose(axes)
+
+
+def partition(a, kth, axis=-1, kind='introselect', order=None):
+    """
+    Return a partitioned copy of an array.
+
+    Creates a copy of the array with its elements rearranged in such a way that
+    the value of the element in kth position is in the position it would be in
+    a sorted array. All elements smaller than the kth element are moved before
+    this element and all equal or greater are moved behind it. The ordering of
+    the elements in the two partitions is undefined.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+    kth : int or sequence of ints
+        Element index to partition by. The kth value of the element will be in
+        its final sorted position and all smaller elements will be moved before
+        it and all equal or greater elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all elements
+        indexed by kth  of them into their sorted position at once.
+    axis : int or None, optional
+        Axis along which to sort. If None, the array is flattened before
+        sorting. The default is -1, which sorts along the last axis.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string.  Not all fields need be specified, but
+        unspecified fields will still be used, in the order in which they
+        come up in the dtype, to break ties.
+
+    Returns
+    -------
+    partitioned_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    ndarray.partition : Method to sort an array in-place.
+    argpartition : Indirect partition.
+    sort : Full sorting
+
+    Notes
+    -----
+    The various selection algorithms are characterized by their average speed,
+    worst case performance, work space size, and whether they are stable. A
+    stable sort keeps items with the same key in the same relative order. The
+    available algorithms have the following properties:
+
+    ================= ======= ============= ============ =======
+       kind            speed   worst case    work space  stable
+    ================= ======= ============= ============ =======
+    'introselect'        1        O(n)           0         no
+    ================= ======= ============= ============ =======
+
+    All the partition algorithms make temporary copies of the data when
+    partitioning along any but the last axis.  Consequently, partitioning
+    along the last axis is faster and uses less space than partitioning
+    along any other axis.
+
+    The sort order for complex numbers is lexicographic. If both the real
+    and imaginary parts are non-nan then the order is determined by the
+    real parts except when they are equal, in which case the order is
+    determined by the imaginary parts.
+
+    Examples
+    --------
+    >>> a = np.array([3, 4, 2, 1])
+    >>> np.partition(a, 3)
+    array([2, 1, 3, 4])
+
+    >>> np.partition(a, (1, 3))
+    array([1, 2, 3, 4])
+
+    """
+    if axis is None:
+        a = asanyarray(a).flatten()
+        axis = 0
+    else:
+        a = asanyarray(a).copy(order="K")
+    a.partition(kth, axis=axis, kind=kind, order=order)
+    return a
+
+
+def argpartition(a, kth, axis=-1, kind='introselect', order=None):
+    """
+    Perform an indirect partition along the given axis using the algorithm
+    specified by the `kind` keyword. It returns an array of indices of the
+    same shape as `a` that index data along the given axis in partitioned
+    order.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array to sort.
+    kth : int or sequence of ints
+        Element index to partition by. The kth element will be in its final
+        sorted position and all smaller elements will be moved before it and
+        all larger elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all of them into
+        their sorted position at once.
+    axis : int or None, optional
+        Axis along which to sort.  The default is -1 (the last axis). If None,
+        the flattened array is used.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    index_array : ndarray, int
+        Array of indices that partition `a` along the specified axis.
+        In other words, ``a[index_array]`` yields a sorted `a`.
+
+    See Also
+    --------
+    partition : Describes partition algorithms used.
+    ndarray.partition : Inplace partition.
+    argsort : Full indirect sort
+
+    Notes
+    -----
+    See `partition` for notes on the different selection algorithms.
+
+    Examples
+    --------
+    One dimensional array:
+
+    >>> x = np.array([3, 4, 2, 1])
+    >>> x[np.argpartition(x, 3)]
+    array([2, 1, 3, 4])
+    >>> x[np.argpartition(x, (1, 3))]
+    array([1, 2, 3, 4])
+
+    >>> x = [3, 4, 2, 1]
+    >>> np.array(x)[np.argpartition(x, 3)]
+    array([2, 1, 3, 4])
+
+    """
+    try:
+        argpartition = a.argpartition
+    except AttributeError:
+        return _wrapit(a, 'argpartition',kth, axis, kind, order)
+    return argpartition(kth, axis, kind=kind, order=order)
+
+
+def sort(a, axis=-1, kind='quicksort', order=None):
+    """
+    Return a sorted copy of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+    axis : int or None, optional
+        Axis along which to sort. If None, the array is flattened before
+        sorting. The default is -1, which sorts along the last axis.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm. Default is 'quicksort'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    sorted_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    ndarray.sort : Method to sort an array in-place.
+    argsort : Indirect sort.
+    lexsort : Indirect stable sort on multiple keys.
+    searchsorted : Find elements in a sorted array.
+    partition : Partial sort.
+
+    Notes
+    -----
+    The various sorting algorithms are characterized by their average speed,
+    worst case performance, work space size, and whether they are stable. A
+    stable sort keeps items with the same key in the same relative
+    order. The three available algorithms have the following
+    properties:
+
+    =========== ======= ============= ============ =======
+       kind      speed   worst case    work space  stable
+    =========== ======= ============= ============ =======
+    'quicksort'    1     O(n^2)            0          no
+    'mergesort'    2     O(n*log(n))      ~n/2        yes
+    'heapsort'     3     O(n*log(n))       0          no
+    =========== ======= ============= ============ =======
+
+    All the sort algorithms make temporary copies of the data when
+    sorting along any but the last axis.  Consequently, sorting along
+    the last axis is faster and uses less space than sorting along
+    any other axis.
+
+    The sort order for complex numbers is lexicographic. If both the real
+    and imaginary parts are non-nan then the order is determined by the
+    real parts except when they are equal, in which case the order is
+    determined by the imaginary parts.
+
+    Previous to numpy 1.4.0 sorting real and complex arrays containing nan
+    values led to undefined behaviour. In numpy versions >= 1.4.0 nan
+    values are sorted to the end. The extended sort order is:
+
+      * Real: [R, nan]
+      * Complex: [R + Rj, R + nanj, nan + Rj, nan + nanj]
+
+    where R is a non-nan real value. Complex values with the same nan
+    placements are sorted according to the non-nan part if it exists.
+    Non-nan values are sorted as before.
+
+    Examples
+    --------
+    >>> a = np.array([[1,4],[3,1]])
+    >>> np.sort(a)                # sort along the last axis
+    array([[1, 4],
+           [1, 3]])
+    >>> np.sort(a, axis=None)     # sort the flattened array
+    array([1, 1, 3, 4])
+    >>> np.sort(a, axis=0)        # sort along the first axis
+    array([[1, 1],
+           [3, 4]])
+
+    Use the `order` keyword to specify a field to use when sorting a
+    structured array:
+
+    >>> dtype = [('name', 'S10'), ('height', float), ('age', int)]
+    >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38),
+    ...           ('Galahad', 1.7, 38)]
+    >>> a = np.array(values, dtype=dtype)       # create a structured array
+    >>> np.sort(a, order='height')                        # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+           ('Lancelot', 1.8999999999999999, 38)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+    Sort by age, then height if ages are equal:
+
+    >>> np.sort(a, order=['age', 'height'])               # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38),
+           ('Arthur', 1.8, 41)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+    """
+    if axis is None:
+        a = asanyarray(a).flatten()
+        axis = 0
+    else:
+        a = asanyarray(a).copy(order="K")
+    a.sort(axis, kind, order)
+    return a
+
+
+def argsort(a, axis=-1, kind='quicksort', order=None):
+    """
+    Returns the indices that would sort an array.
+
+    Perform an indirect sort along the given axis using the algorithm specified
+    by the `kind` keyword. It returns an array of indices of the same shape as
+    `a` that index data along the given axis in sorted order.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to sort.
+    axis : int or None, optional
+        Axis along which to sort.  The default is -1 (the last axis). If None,
+        the flattened array is used.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    index_array : ndarray, int
+        Array of indices that sort `a` along the specified axis.
+        If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`.
+
+    See Also
+    --------
+    sort : Describes sorting algorithms used.
+    lexsort : Indirect stable sort with multiple keys.
+    ndarray.sort : Inplace sort.
+    argpartition : Indirect partial sort.
+
+    Notes
+    -----
+    See `sort` for notes on the different sorting algorithms.
+
+    As of NumPy 1.4.0 `argsort` works with real/complex arrays containing
+    nan values. The enhanced sort order is documented in `sort`.
+
+    Examples
+    --------
+    One dimensional array:
+
+    >>> x = np.array([3, 1, 2])
+    >>> np.argsort(x)
+    array([1, 2, 0])
+
+    Two-dimensional array:
+
+    >>> x = np.array([[0, 3], [2, 2]])
+    >>> x
+    array([[0, 3],
+           [2, 2]])
+
+    >>> np.argsort(x, axis=0)
+    array([[0, 1],
+           [1, 0]])
+
+    >>> np.argsort(x, axis=1)
+    array([[0, 1],
+           [0, 1]])
+
+    Sorting with keys:
+
+    >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
+    >>> x
+    array([(1, 0), (0, 1)],
+          dtype=[('x', '<i4'), ('y', '<i4')])
+
+    >>> np.argsort(x, order=('x','y'))
+    array([1, 0])
+
+    >>> np.argsort(x, order=('y','x'))
+    array([0, 1])
+
+    """
+    try:
+        argsort = a.argsort
+    except AttributeError:
+        return _wrapit(a, 'argsort', axis, kind, order)
+    return argsort(axis, kind, order)
+
+
+def argmax(a, axis=None, out=None):
+    """
+    Returns the indices of the maximum values along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        By default, the index is into the flattened array, otherwise
+        along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+
+    Returns
+    -------
+    index_array : ndarray of ints
+        Array of indices into the array. It has the same shape as `a.shape`
+        with the dimension along `axis` removed.
+
+    See Also
+    --------
+    ndarray.argmax, argmin
+    amax : The maximum value along a given axis.
+    unravel_index : Convert a flat index into an index tuple.
+
+    Notes
+    -----
+    In case of multiple occurrences of the maximum values, the indices
+    corresponding to the first occurrence are returned.
+
+    Examples
+    --------
+    >>> a = np.arange(6).reshape(2,3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argmax(a)
+    5
+    >>> np.argmax(a, axis=0)
+    array([1, 1, 1])
+    >>> np.argmax(a, axis=1)
+    array([2, 2])
+
+    >>> b = np.arange(6)
+    >>> b[1] = 5
+    >>> b
+    array([0, 5, 2, 3, 4, 5])
+    >>> np.argmax(b) # Only the first occurrence is returned.
+    1
+
+    """
+    try:
+        argmax = a.argmax
+    except AttributeError:
+        return _wrapit(a, 'argmax', axis, out)
+    return argmax(axis, out)
+
+
+def argmin(a, axis=None, out=None):
+    """
+    Returns the indices of the minimum values along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        By default, the index is into the flattened array, otherwise
+        along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+
+    Returns
+    -------
+    index_array : ndarray of ints
+        Array of indices into the array. It has the same shape as `a.shape`
+        with the dimension along `axis` removed.
+
+    See Also
+    --------
+    ndarray.argmin, argmax
+    amin : The minimum value along a given axis.
+    unravel_index : Convert a flat index into an index tuple.
+
+    Notes
+    -----
+    In case of multiple occurrences of the minimum values, the indices
+    corresponding to the first occurrence are returned.
+
+    Examples
+    --------
+    >>> a = np.arange(6).reshape(2,3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argmin(a)
+    0
+    >>> np.argmin(a, axis=0)
+    array([0, 0, 0])
+    >>> np.argmin(a, axis=1)
+    array([0, 0])
+
+    >>> b = np.arange(6)
+    >>> b[4] = 0
+    >>> b
+    array([0, 1, 2, 3, 0, 5])
+    >>> np.argmin(b) # Only the first occurrence is returned.
+    0
+
+    """
+    try:
+        argmin = a.argmin
+    except AttributeError:
+        return _wrapit(a, 'argmin', axis, out)
+    return argmin(axis, out)
+
+
+def searchsorted(a, v, side='left', sorter=None):
+    """
+    Find indices where elements should be inserted to maintain order.
+
+    Find the indices into a sorted array `a` such that, if the
+    corresponding elements in `v` were inserted before the indices, the
+    order of `a` would be preserved.
+
+    Parameters
+    ----------
+    a : 1-D array_like
+        Input array. If `sorter` is None, then it must be sorted in
+        ascending order, otherwise `sorter` must be an array of indices
+        that sort it.
+    v : array_like
+        Values to insert into `a`.
+    side : {'left', 'right'}, optional
+        If 'left', the index of the first suitable location found is given.
+        If 'right', return the last such index.  If there is no suitable
+        index, return either 0 or N (where N is the length of `a`).
+    sorter : 1-D array_like, optional
+        Optional array of integer indices that sort array a into ascending
+        order. They are typically the result of argsort.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    indices : array of ints
+        Array of insertion points with the same shape as `v`.
+
+    See Also
+    --------
+    sort : Return a sorted copy of an array.
+    histogram : Produce histogram from 1-D data.
+
+    Notes
+    -----
+    Binary search is used to find the required insertion points.
+
+    As of Numpy 1.4.0 `searchsorted` works with real/complex arrays containing
+    `nan` values. The enhanced sort order is documented in `sort`.
+
+    Examples
+    --------
+    >>> np.searchsorted([1,2,3,4,5], 3)
+    2
+    >>> np.searchsorted([1,2,3,4,5], 3, side='right')
+    3
+    >>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
+    array([0, 5, 1, 2])
+
+    """
+    try:
+        searchsorted = a.searchsorted
+    except AttributeError:
+        return _wrapit(a, 'searchsorted', v, side, sorter)
+    return searchsorted(v, side, sorter)
+
+
+def resize(a, new_shape):
+    """
+    Return a new array with the specified shape.
+
+    If the new array is larger than the original array, then the new
+    array is filled with repeated copies of `a`.  Note that this behavior
+    is different from a.resize(new_shape) which fills with zeros instead
+    of repeated copies of `a`.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be resized.
+
+    new_shape : int or tuple of int
+        Shape of resized array.
+
+    Returns
+    -------
+    reshaped_array : ndarray
+        The new array is formed from the data in the old array, repeated
+        if necessary to fill out the required number of elements.  The
+        data are repeated in the order that they are stored in memory.
+
+    See Also
+    --------
+    ndarray.resize : resize an array in-place.
+
+    Examples
+    --------
+    >>> a=np.array([[0,1],[2,3]])
+    >>> np.resize(a,(2,3))
+    array([[0, 1, 2],
+           [3, 0, 1]])
+    >>> np.resize(a,(1,4))
+    array([[0, 1, 2, 3]])
+    >>> np.resize(a,(2,4))
+    array([[0, 1, 2, 3],
+           [0, 1, 2, 3]])
+
+    """
+    if isinstance(new_shape, (int, nt.integer)):
+        new_shape = (new_shape,)
+    a = ravel(a)
+    Na = len(a)
+    if not Na:
+        return mu.zeros(new_shape, a.dtype)
+    total_size = um.multiply.reduce(new_shape)
+    n_copies = int(total_size / Na)
+    extra = total_size % Na
+
+    if total_size == 0:
+        return a[:0]
+
+    if extra != 0:
+        n_copies = n_copies+1
+        extra = Na-extra
+
+    a = concatenate((a,)*n_copies)
+    if extra > 0:
+        a = a[:-extra]
+
+    return reshape(a, new_shape)
+
+
+def squeeze(a, axis=None):
+    """
+    Remove single-dimensional entries from the shape of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        .. versionadded:: 1.7.0
+
+        Selects a subset of the single-dimensional entries in the
+        shape. If an axis is selected with shape entry greater than
+        one, an error is raised.
+
+    Returns
+    -------
+    squeezed : ndarray
+        The input array, but with all or a subset of the
+        dimensions of length 1 removed. This is always `a` itself
+        or a view into `a`.
+
+    Examples
+    --------
+    >>> x = np.array([[[0], [1], [2]]])
+    >>> x.shape
+    (1, 3, 1)
+    >>> np.squeeze(x).shape
+    (3,)
+    >>> np.squeeze(x, axis=(2,)).shape
+    (1, 3)
+
+    """
+    try:
+        squeeze = a.squeeze
+    except AttributeError:
+        return _wrapit(a, 'squeeze')
+    try:
+        # First try to use the new axis= parameter
+        return squeeze(axis=axis)
+    except TypeError:
+        # For backwards compatibility
+        return squeeze()
+
+
+def diagonal(a, offset=0, axis1=0, axis2=1):
+    """
+    Return specified diagonals.
+
+    If `a` is 2-D, returns the diagonal of `a` with the given offset,
+    i.e., the collection of elements of the form ``a[i, i+offset]``.  If
+    `a` has more than two dimensions, then the axes specified by `axis1`
+    and `axis2` are used to determine the 2-D sub-array whose diagonal is
+    returned.  The shape of the resulting array can be determined by
+    removing `axis1` and `axis2` and appending an index to the right equal
+    to the size of the resulting diagonals.
+
+    In versions of NumPy prior to 1.7, this function always returned a new,
+    independent array containing a copy of the values in the diagonal.
+
+    In NumPy 1.7 and 1.8, it continues to return a copy of the diagonal,
+    but depending on this fact is deprecated. Writing to the resulting
+    array continues to work as it used to, but a FutureWarning is issued.
+
+    Starting in NumPy 1.9 it returns a read-only view on the original array.
+    Attempting to write to the resulting array will produce an error.
+
+    In some future release, it will return a read/write view and writing to
+    the returned array will alter your original array.  The returned array
+    will have the same type as the input array.
+
+    If you don't write to the array returned by this function, then you can
+    just ignore all of the above.
+
+    If you depend on the current behavior, then we suggest copying the
+    returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead
+    of just ``np.diagonal(a)``. This will work with both past and future
+    versions of NumPy.
+
+    Parameters
+    ----------
+    a : array_like
+        Array from which the diagonals are taken.
+    offset : int, optional
+        Offset of the diagonal from the main diagonal.  Can be positive or
+        negative.  Defaults to main diagonal (0).
+    axis1 : int, optional
+        Axis to be used as the first axis of the 2-D sub-arrays from which
+        the diagonals should be taken.  Defaults to first axis (0).
+    axis2 : int, optional
+        Axis to be used as the second axis of the 2-D sub-arrays from
+        which the diagonals should be taken. Defaults to second axis (1).
+
+    Returns
+    -------
+    array_of_diagonals : ndarray
+        If `a` is 2-D and not a matrix, a 1-D array of the same type as `a`
+        containing the diagonal is returned. If `a` is a matrix, a 1-D
+        array containing the diagonal is returned in order to maintain
+        backward compatibility.  If the dimension of `a` is greater than
+        two, then an array of diagonals is returned, "packed" from
+        left-most dimension to right-most (e.g., if `a` is 3-D, then the
+        diagonals are "packed" along rows).
+
+    Raises
+    ------
+    ValueError
+        If the dimension of `a` is less than 2.
+
+    See Also
+    --------
+    diag : MATLAB work-a-like for 1-D and 2-D arrays.
+    diagflat : Create diagonal arrays.
+    trace : Sum along diagonals.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape(2,2)
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> a.diagonal()
+    array([0, 3])
+    >>> a.diagonal(1)
+    array([1])
+
+    A 3-D example:
+
+    >>> a = np.arange(8).reshape(2,2,2); a
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+    >>> a.diagonal(0, # Main diagonals of two arrays created by skipping
+    ...            0, # across the outer(left)-most axis last and
+    ...            1) # the "middle" (row) axis first.
+    array([[0, 6],
+           [1, 7]])
+
+    The sub-arrays whose main diagonals we just obtained; note that each
+    corresponds to fixing the right-most (column) axis, and that the
+    diagonals are "packed" in rows.
+
+    >>> a[:,:,0] # main diagonal is [0 6]
+    array([[0, 2],
+           [4, 6]])
+    >>> a[:,:,1] # main diagonal is [1 7]
+    array([[1, 3],
+           [5, 7]])
+
+    """
+    if isinstance(a, np.matrix):
+        # Make diagonal of matrix 1-D to preserve backward compatibility.
+        return asarray(a).diagonal(offset, axis1, axis2)
+    else:
+        return asanyarray(a).diagonal(offset, axis1, axis2)
+
+
+def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):
+    """
+    Return the sum along diagonals of the array.
+
+    If `a` is 2-D, the sum along its diagonal with the given offset
+    is returned, i.e., the sum of elements ``a[i,i+offset]`` for all i.
+
+    If `a` has more than two dimensions, then the axes specified by axis1 and
+    axis2 are used to determine the 2-D sub-arrays whose traces are returned.
+    The shape of the resulting array is the same as that of `a` with `axis1`
+    and `axis2` removed.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, from which the diagonals are taken.
+    offset : int, optional
+        Offset of the diagonal from the main diagonal. Can be both positive
+        and negative. Defaults to 0.
+    axis1, axis2 : int, optional
+        Axes to be used as the first and second axis of the 2-D sub-arrays
+        from which the diagonals should be taken. Defaults are the first two
+        axes of `a`.
+    dtype : dtype, optional
+        Determines the data-type of the returned array and of the accumulator
+        where the elements are summed. If dtype has the value None and `a` is
+        of integer type of precision less than the default integer
+        precision, then the default integer precision is used. Otherwise,
+        the precision is the same as that of `a`.
+    out : ndarray, optional
+        Array into which the output is placed. Its type is preserved and
+        it must be of the right shape to hold the output.
+
+    Returns
+    -------
+    sum_along_diagonals : ndarray
+        If `a` is 2-D, the sum along the diagonal is returned.  If `a` has
+        larger dimensions, then an array of sums along diagonals is returned.
+
+    See Also
+    --------
+    diag, diagonal, diagflat
+
+    Examples
+    --------
+    >>> np.trace(np.eye(3))
+    3.0
+    >>> a = np.arange(8).reshape((2,2,2))
+    >>> np.trace(a)
+    array([6, 8])
+
+    >>> a = np.arange(24).reshape((2,2,2,3))
+    >>> np.trace(a).shape
+    (2, 3)
+
+    """
+    if isinstance(a, np.matrix):
+        # Get trace of matrix via an array to preserve backward compatibility.
+        return asarray(a).trace(offset, axis1, axis2, dtype, out)
+    else:
+        return asanyarray(a).trace(offset, axis1, axis2, dtype, out)
+
+
+def ravel(a, order='C'):
+    """Return a contiguous flattened array.
+
+    A 1-D array, containing the elements of the input, is returned.  A copy is
+    made only if needed.
+
+    As of NumPy 1.10, the returned array will have the same type as the input
+    array. (for example, a masked array will be returned for a masked array
+    input)
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.  The elements in `a` are read in the order specified by
+        `order`, and packed as a 1-D array.
+    order : {'C','F', 'A', 'K'}, optional
+
+        The elements of `a` are read using this index order. 'C' means
+        to index the elements in row-major, C-style order,
+        with the last axis index changing fastest, back to the first
+        axis index changing slowest.  'F' means to index the elements
+        in column-major, Fortran-style order, with the
+        first index changing fastest, and the last index changing
+        slowest. Note that the 'C' and 'F' options take no account of
+        the memory layout of the underlying array, and only refer to
+        the order of axis indexing.  'A' means to read the elements in
+        Fortran-like index order if `a` is Fortran *contiguous* in
+        memory, C-like order otherwise.  'K' means to read the
+        elements in the order they occur in memory, except for
+        reversing the data when strides are negative.  By default, 'C'
+        index order is used.
+
+    Returns
+    -------
+    y : array_like
+        If `a` is a matrix, y is a 1-D ndarray, otherwise y is an array of
+        the same subtype as `a`. The shape of the returned array is
+        ``(a.size,)``. Matrices are special cased for backward
+        compatibility.
+
+    See Also
+    --------
+    ndarray.flat : 1-D iterator over an array.
+    ndarray.flatten : 1-D array copy of the elements of an array
+                      in row-major order.
+    ndarray.reshape : Change the shape of an array without changing its data.
+
+    Notes
+    -----
+    In row-major, C-style order, in two dimensions, the row index
+    varies the slowest, and the column index the quickest.  This can
+    be generalized to multiple dimensions, where row-major order
+    implies that the index along the first axis varies slowest, and
+    the index along the last quickest.  The opposite holds for
+    column-major, Fortran-style index ordering.
+
+    When a view is desired in as many cases as possible, ``arr.reshape(-1)``
+    may be preferable.
+
+    Examples
+    --------
+    It is equivalent to ``reshape(-1, order=order)``.
+
+    >>> x = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> print(np.ravel(x))
+    [1 2 3 4 5 6]
+
+    >>> print(x.reshape(-1))
+    [1 2 3 4 5 6]
+
+    >>> print(np.ravel(x, order='F'))
+    [1 4 2 5 3 6]
+
+    When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering:
+
+    >>> print(np.ravel(x.T))
+    [1 4 2 5 3 6]
+    >>> print(np.ravel(x.T, order='A'))
+    [1 2 3 4 5 6]
+
+    When ``order`` is 'K', it will preserve orderings that are neither 'C'
+    nor 'F', but won't reverse axes:
+
+    >>> a = np.arange(3)[::-1]; a
+    array([2, 1, 0])
+    >>> a.ravel(order='C')
+    array([2, 1, 0])
+    >>> a.ravel(order='K')
+    array([2, 1, 0])
+
+    >>> a = np.arange(12).reshape(2,3,2).swapaxes(1,2); a
+    array([[[ 0,  2,  4],
+            [ 1,  3,  5]],
+           [[ 6,  8, 10],
+            [ 7,  9, 11]]])
+    >>> a.ravel(order='C')
+    array([ 0,  2,  4,  1,  3,  5,  6,  8, 10,  7,  9, 11])
+    >>> a.ravel(order='K')
+    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
+
+    """
+    if isinstance(a, np.matrix):
+        return asarray(a).ravel(order)
+    else:
+        return asanyarray(a).ravel(order)
+
+
+def nonzero(a):
+    """
+    Return the indices of the elements that are non-zero.
+
+    Returns a tuple of arrays, one for each dimension of `a`,
+    containing the indices of the non-zero elements in that
+    dimension. The values in `a` are always tested and returned in
+    row-major, C-style order. The corresponding non-zero
+    values can be obtained with::
+
+        a[nonzero(a)]
+
+    To group the indices by element, rather than dimension, use::
+
+        transpose(nonzero(a))
+
+    The result of this is always a 2-D array, with a row for
+    each non-zero element.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+
+    Returns
+    -------
+    tuple_of_arrays : tuple
+        Indices of elements that are non-zero.
+
+    See Also
+    --------
+    flatnonzero :
+        Return indices that are non-zero in the flattened version of the input
+        array.
+    ndarray.nonzero :
+        Equivalent ndarray method.
+    count_nonzero :
+        Counts the number of non-zero elements in the input array.
+
+    Examples
+    --------
+    >>> x = np.eye(3)
+    >>> x
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> np.nonzero(x)
+    (array([0, 1, 2]), array([0, 1, 2]))
+
+    >>> x[np.nonzero(x)]
+    array([ 1.,  1.,  1.])
+    >>> np.transpose(np.nonzero(x))
+    array([[0, 0],
+           [1, 1],
+           [2, 2]])
+
+    A common use for ``nonzero`` is to find the indices of an array, where
+    a condition is True.  Given an array `a`, the condition `a` > 3 is a
+    boolean array and since False is interpreted as 0, np.nonzero(a > 3)
+    yields the indices of the `a` where the condition is true.
+
+    >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
+    >>> a > 3
+    array([[False, False, False],
+           [ True,  True,  True],
+           [ True,  True,  True]], dtype=bool)
+    >>> np.nonzero(a > 3)
+    (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+    The ``nonzero`` method of the boolean array can also be called.
+
+    >>> (a > 3).nonzero()
+    (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+    """
+    try:
+        nonzero = a.nonzero
+    except AttributeError:
+        res = _wrapit(a, 'nonzero')
+    else:
+        res = nonzero()
+    return res
+
+
+def shape(a):
+    """
+    Return the shape of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+
+    Returns
+    -------
+    shape : tuple of ints
+        The elements of the shape tuple give the lengths of the
+        corresponding array dimensions.
+
+    See Also
+    --------
+    alen
+    ndarray.shape : Equivalent array method.
+
+    Examples
+    --------
+    >>> np.shape(np.eye(3))
+    (3, 3)
+    >>> np.shape([[1, 2]])
+    (1, 2)
+    >>> np.shape([0])
+    (1,)
+    >>> np.shape(0)
+    ()
+
+    >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+    >>> np.shape(a)
+    (2,)
+    >>> a.shape
+    (2,)
+
+    """
+    try:
+        result = a.shape
+    except AttributeError:
+        result = asarray(a).shape
+    return result
+
+
+def compress(condition, a, axis=None, out=None):
+    """
+    Return selected slices of an array along given axis.
+
+    When working along a given axis, a slice along that axis is returned in
+    `output` for each index where `condition` evaluates to True. When
+    working on a 1-D array, `compress` is equivalent to `extract`.
+
+    Parameters
+    ----------
+    condition : 1-D array of bools
+        Array that selects which entries to return. If len(condition)
+        is less than the size of `a` along the given axis, then output is
+        truncated to the length of the condition array.
+    a : array_like
+        Array from which to extract a part.
+    axis : int, optional
+        Axis along which to take slices. If None (default), work on the
+        flattened array.
+    out : ndarray, optional
+        Output array.  Its type is preserved and it must be of the right
+        shape to hold the output.
+
+    Returns
+    -------
+    compressed_array : ndarray
+        A copy of `a` without the slices along axis for which `condition`
+        is false.
+
+    See Also
+    --------
+    take, choose, diag, diagonal, select
+    ndarray.compress : Equivalent method in ndarray
+    np.extract: Equivalent method when working on 1-D arrays
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4], [5, 6]])
+    >>> a
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    >>> np.compress([0, 1], a, axis=0)
+    array([[3, 4]])
+    >>> np.compress([False, True, True], a, axis=0)
+    array([[3, 4],
+           [5, 6]])
+    >>> np.compress([False, True], a, axis=1)
+    array([[2],
+           [4],
+           [6]])
+
+    Working on the flattened array does not return slices along an axis but
+    selects elements.
+
+    >>> np.compress([False, True], a)
+    array([2])
+
+    """
+    try:
+        compress = a.compress
+    except AttributeError:
+        return _wrapit(a, 'compress', condition, axis, out)
+    return compress(condition, axis, out)
+
+
+def clip(a, a_min, a_max, out=None):
+    """
+    Clip (limit) the values in an array.
+
+    Given an interval, values outside the interval are clipped to
+    the interval edges.  For example, if an interval of ``[0, 1]``
+    is specified, values smaller than 0 become 0, and values larger
+    than 1 become 1.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing elements to clip.
+    a_min : scalar or array_like
+        Minimum value.
+    a_max : scalar or array_like
+        Maximum value.  If `a_min` or `a_max` are array_like, then they will
+        be broadcasted to the shape of `a`.
+    out : ndarray, optional
+        The results will be placed in this array. It may be the input
+        array for in-place clipping.  `out` must be of the right shape
+        to hold the output.  Its type is preserved.
+
+    Returns
+    -------
+    clipped_array : ndarray
+        An array with the elements of `a`, but where values
+        < `a_min` are replaced with `a_min`, and those > `a_max`
+        with `a_max`.
+
+    See Also
+    --------
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Examples
+    --------
+    >>> a = np.arange(10)
+    >>> np.clip(a, 1, 8)
+    array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> np.clip(a, 3, 6, out=a)
+    array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
+    >>> a = np.arange(10)
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8)
+    array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])
+
+    """
+    try:
+        clip = a.clip
+    except AttributeError:
+        return _wrapit(a, 'clip', a_min, a_max, out)
+    return clip(a_min, a_max, out)
+
+
+def sum(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Sum of array elements over a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Elements to sum.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a sum is performed.  The default,
+        axis=None, will sum all of the elements of the input array.  If
+        axis is negative it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If axis is a tuple of ints, a sum is performed on all of the axes
+        specified in the tuple instead of a single axis or all the axes as
+        before.
+    dtype : dtype, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  The dtype of `a` is used by default unless `a`
+        has an integer dtype of less precision than the default platform
+        integer.  In that case, if `a` is signed then the platform integer
+        is used while if `a` is unsigned then an unsigned integer of the
+        same precision as the platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the input array.
+
+    Returns
+    -------
+    sum_along_axis : ndarray
+        An array with the same shape as `a`, with the specified
+        axis removed.   If `a` is a 0-d array, or if `axis` is None, a scalar
+        is returned.  If an output array is specified, a reference to
+        `out` is returned.
+
+    See Also
+    --------
+    ndarray.sum : Equivalent method.
+
+    cumsum : Cumulative sum of array elements.
+
+    trapz : Integration of array values using the composite trapezoidal rule.
+
+    mean, average
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    The sum of an empty array is the neutral element 0:
+
+    >>> np.sum([])
+    0.0
+
+    Examples
+    --------
+    >>> np.sum([0.5, 1.5])
+    2.0
+    >>> np.sum([0.5, 0.7, 0.2, 1.5], dtype=np.int32)
+    1
+    >>> np.sum([[0, 1], [0, 5]])
+    6
+    >>> np.sum([[0, 1], [0, 5]], axis=0)
+    array([0, 6])
+    >>> np.sum([[0, 1], [0, 5]], axis=1)
+    array([1, 5])
+
+    If the accumulator is too small, overflow occurs:
+
+    >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8)
+    -128
+
+    """
+    if isinstance(a, _gentype):
+        res = _sum_(a)
+        if out is not None:
+            out[...] = res
+            return out
+        return res
+    elif type(a) is not mu.ndarray:
+        try:
+            sum = a.sum
+        except AttributeError:
+            return _methods._sum(a, axis=axis, dtype=dtype,
+                                 out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameters here...
+        return sum(axis=axis, dtype=dtype, out=out)
+    else:
+        return _methods._sum(a, axis=axis, dtype=dtype,
+                             out=out, keepdims=keepdims)
+
+
+def product(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Return the product of array elements over a given axis.
+
+    See Also
+    --------
+    prod : equivalent function; see for details.
+
+    """
+    return um.multiply.reduce(a, axis=axis, dtype=dtype,
+                              out=out, keepdims=keepdims)
+
+
+def sometrue(a, axis=None, out=None, keepdims=False):
+    """
+    Check whether some values are true.
+
+    Refer to `any` for full documentation.
+
+    See Also
+    --------
+    any : equivalent function
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.any(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.any(axis=axis, out=out)
+
+
+def alltrue(a, axis=None, out=None, keepdims=False):
+    """
+    Check if all elements of input array are true.
+
+    See Also
+    --------
+    numpy.all : Equivalent function; see for details.
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.all(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.all(axis=axis, out=out)
+
+
+def any(a, axis=None, out=None, keepdims=False):
+    """
+    Test whether any array element along a given axis evaluates to True.
+
+    Returns single boolean unless `axis` is not ``None``
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a logical OR reduction is performed.
+        The default (`axis` = `None`) is to perform a logical OR over all
+        the dimensions of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output and its type is preserved
+        (e.g., if it is of type float, then it will remain so, returning
+        1.0 for True and 0.0 for False, regardless of the type of `a`).
+        See `doc.ufuncs` (Section "Output arguments") for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    any : bool or ndarray
+        A new boolean or `ndarray` is returned unless `out` is specified,
+        in which case a reference to `out` is returned.
+
+    See Also
+    --------
+    ndarray.any : equivalent method
+
+    all : Test whether all elements along a given axis evaluate to True.
+
+    Notes
+    -----
+    Not a Number (NaN), positive infinity and negative infinity evaluate
+    to `True` because these are not equal to zero.
+
+    Examples
+    --------
+    >>> np.any([[True, False], [True, True]])
+    True
+
+    >>> np.any([[True, False], [False, False]], axis=0)
+    array([ True, False], dtype=bool)
+
+    >>> np.any([-1, 0, 5])
+    True
+
+    >>> np.any(np.nan)
+    True
+
+    >>> o=np.array([False])
+    >>> z=np.any([-1, 4, 5], out=o)
+    >>> z, o
+    (array([ True], dtype=bool), array([ True], dtype=bool))
+    >>> # Check now that z is a reference to o
+    >>> z is o
+    True
+    >>> id(z), id(o) # identity of z and o              # doctest: +SKIP
+    (191614240, 191614240)
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.any(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.any(axis=axis, out=out)
+
+
+def all(a, axis=None, out=None, keepdims=False):
+    """
+    Test whether all array elements along a given axis evaluate to True.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a logical AND reduction is performed.
+        The default (`axis` = `None`) is to perform a logical AND over all
+        the dimensions of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternate output array in which to place the result.
+        It must have the same shape as the expected output and its
+        type is preserved (e.g., if ``dtype(out)`` is float, the result
+        will consist of 0.0's and 1.0's).  See `doc.ufuncs` (Section
+        "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    all : ndarray, bool
+        A new boolean or array is returned unless `out` is specified,
+        in which case a reference to `out` is returned.
+
+    See Also
+    --------
+    ndarray.all : equivalent method
+
+    any : Test whether any element along a given axis evaluates to True.
+
+    Notes
+    -----
+    Not a Number (NaN), positive infinity and negative infinity
+    evaluate to `True` because these are not equal to zero.
+
+    Examples
+    --------
+    >>> np.all([[True,False],[True,True]])
+    False
+
+    >>> np.all([[True,False],[True,True]], axis=0)
+    array([ True, False], dtype=bool)
+
+    >>> np.all([-1, 4, 5])
+    True
+
+    >>> np.all([1.0, np.nan])
+    True
+
+    >>> o=np.array([False])
+    >>> z=np.all([-1, 4, 5], out=o)
+    >>> id(z), id(o), z                             # doctest: +SKIP
+    (28293632, 28293632, array([ True], dtype=bool))
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.all(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.all(axis=axis, out=out)
+
+
+def cumsum(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative sum of the elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        Axis along which the cumulative sum is computed. The default
+        (None) is to compute the cumsum over the flattened array.
+    dtype : dtype, optional
+        Type of the returned array and of the accumulator in which the
+        elements are summed.  If `dtype` is not specified, it defaults
+        to the dtype of `a`, unless `a` has an integer dtype with a
+        precision less than that of the default platform integer.  In
+        that case, the default platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type will be cast if necessary. See `doc.ufuncs`
+        (Section "Output arguments") for more details.
+
+    Returns
+    -------
+    cumsum_along_axis : ndarray.
+        A new array holding the result is returned unless `out` is
+        specified, in which case a reference to `out` is returned. The
+        result has the same size as `a`, and the same shape as `a` if
+        `axis` is not None or `a` is a 1-d array.
+
+
+    See Also
+    --------
+    sum : Sum array elements.
+
+    trapz : Integration of array values using the composite trapezoidal rule.
+
+    diff :  Calculate the n-th discrete difference along given axis.
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3], [4,5,6]])
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.cumsum(a)
+    array([ 1,  3,  6, 10, 15, 21])
+    >>> np.cumsum(a, dtype=float)     # specifies type of output value(s)
+    array([  1.,   3.,   6.,  10.,  15.,  21.])
+
+    >>> np.cumsum(a,axis=0)      # sum over rows for each of the 3 columns
+    array([[1, 2, 3],
+           [5, 7, 9]])
+    >>> np.cumsum(a,axis=1)      # sum over columns for each of the 2 rows
+    array([[ 1,  3,  6],
+           [ 4,  9, 15]])
+
+    """
+    try:
+        cumsum = a.cumsum
+    except AttributeError:
+        return _wrapit(a, 'cumsum', axis, dtype, out)
+    return cumsum(axis, dtype, out)
+
+
+def cumproduct(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative product over the given axis.
+
+
+    See Also
+    --------
+    cumprod : equivalent function; see for details.
+
+    """
+    try:
+        cumprod = a.cumprod
+    except AttributeError:
+        return _wrapit(a, 'cumprod', axis, dtype, out)
+    return cumprod(axis, dtype, out)
+
+
+def ptp(a, axis=None, out=None):
+    """
+    Range of values (maximum - minimum) along an axis.
+
+    The name of the function comes from the acronym for 'peak to peak'.
+
+    Parameters
+    ----------
+    a : array_like
+        Input values.
+    axis : int, optional
+        Axis along which to find the peaks.  By default, flatten the
+        array.
+    out : array_like
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type of the output values will be cast if necessary.
+
+    Returns
+    -------
+    ptp : ndarray
+        A new array holding the result, unless `out` was
+        specified, in which case a reference to `out` is returned.
+
+    Examples
+    --------
+    >>> x = np.arange(4).reshape((2,2))
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+
+    >>> np.ptp(x, axis=0)
+    array([2, 2])
+
+    >>> np.ptp(x, axis=1)
+    array([1, 1])
+
+    """
+    try:
+        ptp = a.ptp
+    except AttributeError:
+        return _wrapit(a, 'ptp', axis, out)
+    return ptp(axis, out)
+
+
+def amax(a, axis=None, out=None, keepdims=False):
+    """
+    Return the maximum of an array or maximum along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which to operate.  By default, flattened input is
+        used.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, the maximum is selected over multiple axes,
+        instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternative output array in which to place the result.  Must
+        be of the same shape and buffer length as the expected output.
+        See `doc.ufuncs` (Section "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    amax : ndarray or scalar
+        Maximum of `a`. If `axis` is None, the result is a scalar value.
+        If `axis` is given, the result is an array of dimension
+        ``a.ndim - 1``.
+
+    See Also
+    --------
+    amin :
+        The minimum value of an array along a given axis, propagating any NaNs.
+    nanmax :
+        The maximum value of an array along a given axis, ignoring any NaNs.
+    maximum :
+        Element-wise maximum of two arrays, propagating any NaNs.
+    fmax :
+        Element-wise maximum of two arrays, ignoring any NaNs.
+    argmax :
+        Return the indices of the maximum values.
+
+    nanmin, minimum, fmin
+
+    Notes
+    -----
+    NaN values are propagated, that is if at least one item is NaN, the
+    corresponding max value will be NaN as well. To ignore NaN values
+    (MATLAB behavior), please use nanmax.
+
+    Don't use `amax` for element-wise comparison of 2 arrays; when
+    ``a.shape[0]`` is 2, ``maximum(a[0], a[1])`` is faster than
+    ``amax(a, axis=0)``.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape((2,2))
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> np.amax(a)           # Maximum of the flattened array
+    3
+    >>> np.amax(a, axis=0)   # Maxima along the first axis
+    array([2, 3])
+    >>> np.amax(a, axis=1)   # Maxima along the second axis
+    array([1, 3])
+
+    >>> b = np.arange(5, dtype=np.float)
+    >>> b[2] = np.NaN
+    >>> np.amax(b)
+    nan
+    >>> np.nanmax(b)
+    4.0
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            amax = a.max
+        except AttributeError:
+            return _methods._amax(a, axis=axis,
+                                  out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameter
+        return amax(axis=axis, out=out)
+    else:
+        return _methods._amax(a, axis=axis,
+                              out=out, keepdims=keepdims)
+
+
+def amin(a, axis=None, out=None, keepdims=False):
+    """
+    Return the minimum of an array or minimum along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which to operate.  By default, flattened input is
+        used.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, the minimum is selected over multiple axes,
+        instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternative output array in which to place the result.  Must
+        be of the same shape and buffer length as the expected output.
+        See `doc.ufuncs` (Section "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    amin : ndarray or scalar
+        Minimum of `a`. If `axis` is None, the result is a scalar value.
+        If `axis` is given, the result is an array of dimension
+        ``a.ndim - 1``.
+
+    See Also
+    --------
+    amax :
+        The maximum value of an array along a given axis, propagating any NaNs.
+    nanmin :
+        The minimum value of an array along a given axis, ignoring any NaNs.
+    minimum :
+        Element-wise minimum of two arrays, propagating any NaNs.
+    fmin :
+        Element-wise minimum of two arrays, ignoring any NaNs.
+    argmin :
+        Return the indices of the minimum values.
+
+    nanmax, maximum, fmax
+
+    Notes
+    -----
+    NaN values are propagated, that is if at least one item is NaN, the
+    corresponding min value will be NaN as well. To ignore NaN values
+    (MATLAB behavior), please use nanmin.
+
+    Don't use `amin` for element-wise comparison of 2 arrays; when
+    ``a.shape[0]`` is 2, ``minimum(a[0], a[1])`` is faster than
+    ``amin(a, axis=0)``.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape((2,2))
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> np.amin(a)           # Minimum of the flattened array
+    0
+    >>> np.amin(a, axis=0)   # Minima along the first axis
+    array([0, 1])
+    >>> np.amin(a, axis=1)   # Minima along the second axis
+    array([0, 2])
+
+    >>> b = np.arange(5, dtype=np.float)
+    >>> b[2] = np.NaN
+    >>> np.amin(b)
+    nan
+    >>> np.nanmin(b)
+    0.0
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            amin = a.min
+        except AttributeError:
+            return _methods._amin(a, axis=axis,
+                                  out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameter
+        return amin(axis=axis, out=out)
+    else:
+        return _methods._amin(a, axis=axis,
+                              out=out, keepdims=keepdims)
+
+
+def alen(a):
+    """
+    Return the length of the first dimension of the input array.
+
+    Parameters
+    ----------
+    a : array_like
+       Input array.
+
+    Returns
+    -------
+    alen : int
+       Length of the first dimension of `a`.
+
+    See Also
+    --------
+    shape, size
+
+    Examples
+    --------
+    >>> a = np.zeros((7,4,5))
+    >>> a.shape[0]
+    7
+    >>> np.alen(a)
+    7
+
+    """
+    try:
+        return len(a)
+    except TypeError:
+        return len(array(a, ndmin=1))
+
+
+def prod(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Return the product of array elements over a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a product is performed.  The default,
+        axis=None, will calculate the product of all the elements in the
+        input array. If axis is negative it counts from the last to the
+        first axis.
+
+        .. versionadded:: 1.7.0
+
+        If axis is a tuple of ints, a product is performed on all of the
+        axes specified in the tuple instead of a single axis or all the
+        axes as before.
+    dtype : dtype, optional
+        The type of the returned array, as well as of the accumulator in
+        which the elements are multiplied.  The dtype of `a` is used by
+        default unless `a` has an integer dtype of less precision than the
+        default platform integer.  In that case, if `a` is signed then the
+        platform integer is used while if `a` is unsigned then an unsigned
+        integer of the same precision as the platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the input array.
+
+    Returns
+    -------
+    product_along_axis : ndarray, see `dtype` parameter above.
+        An array shaped as `a` but with the specified axis removed.
+        Returns a reference to `out` if specified.
+
+    See Also
+    --------
+    ndarray.prod : equivalent method
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.  That means that, on a 32-bit platform:
+
+    >>> x = np.array([536870910, 536870910, 536870910, 536870910])
+    >>> np.prod(x) #random
+    16
+
+    The product of an empty array is the neutral element 1:
+
+    >>> np.prod([])
+    1.0
+
+    Examples
+    --------
+    By default, calculate the product of all elements:
+
+    >>> np.prod([1.,2.])
+    2.0
+
+    Even when the input array is two-dimensional:
+
+    >>> np.prod([[1.,2.],[3.,4.]])
+    24.0
+
+    But we can also specify the axis over which to multiply:
+
+    >>> np.prod([[1.,2.],[3.,4.]], axis=1)
+    array([  2.,  12.])
+
+    If the type of `x` is unsigned, then the output type is
+    the unsigned platform integer:
+
+    >>> x = np.array([1, 2, 3], dtype=np.uint8)
+    >>> np.prod(x).dtype == np.uint
+    True
+
+    If `x` is of a signed integer type, then the output type
+    is the default platform integer:
+
+    >>> x = np.array([1, 2, 3], dtype=np.int8)
+    >>> np.prod(x).dtype == np.int
+    True
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            prod = a.prod
+        except AttributeError:
+            return _methods._prod(a, axis=axis, dtype=dtype,
+                                  out=out, keepdims=keepdims)
+        return prod(axis=axis, dtype=dtype, out=out)
+    else:
+        return _methods._prod(a, axis=axis, dtype=dtype,
+                              out=out, keepdims=keepdims)
+
+
+def cumprod(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative product of elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        Axis along which the cumulative product is computed.  By default
+        the input is flattened.
+    dtype : dtype, optional
+        Type of the returned array, as well as of the accumulator in which
+        the elements are multiplied.  If *dtype* is not specified, it
+        defaults to the dtype of `a`, unless `a` has an integer dtype with
+        a precision less than that of the default platform integer.  In
+        that case, the default platform integer is used instead.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type of the resulting values will be cast if necessary.
+
+    Returns
+    -------
+    cumprod : ndarray
+        A new array holding the result is returned unless `out` is
+        specified, in which case a reference to out is returned.
+
+    See Also
+    --------
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    Examples
+    --------
+    >>> a = np.array([1,2,3])
+    >>> np.cumprod(a) # intermediate results 1, 1*2
+    ...               # total product 1*2*3 = 6
+    array([1, 2, 6])
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> np.cumprod(a, dtype=float) # specify type of output
+    array([   1.,    2.,    6.,   24.,  120.,  720.])
+
+    The cumulative product for each column (i.e., over the rows) of `a`:
+
+    >>> np.cumprod(a, axis=0)
+    array([[ 1,  2,  3],
+           [ 4, 10, 18]])
+
+    The cumulative product for each row (i.e. over the columns) of `a`:
+
+    >>> np.cumprod(a,axis=1)
+    array([[  1,   2,   6],
+           [  4,  20, 120]])
+
+    """
+    try:
+        cumprod = a.cumprod
+    except AttributeError:
+        return _wrapit(a, 'cumprod', axis, dtype, out)
+    return cumprod(axis, dtype, out)
+
+
+def ndim(a):
+    """
+    Return the number of dimensions of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.  If it is not already an ndarray, a conversion is
+        attempted.
+
+    Returns
+    -------
+    number_of_dimensions : int
+        The number of dimensions in `a`.  Scalars are zero-dimensional.
+
+    See Also
+    --------
+    ndarray.ndim : equivalent method
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+
+    Examples
+    --------
+    >>> np.ndim([[1,2,3],[4,5,6]])
+    2
+    >>> np.ndim(np.array([[1,2,3],[4,5,6]]))
+    2
+    >>> np.ndim(1)
+    0
+
+    """
+    try:
+        return a.ndim
+    except AttributeError:
+        return asarray(a).ndim
+
+
+def rank(a):
+    """
+    Return the number of dimensions of an array.
+
+    If `a` is not already an array, a conversion is attempted.
+    Scalars are zero dimensional.
+
+    .. note::
+        This function is deprecated in NumPy 1.9 to avoid confusion with
+        `numpy.linalg.matrix_rank`. The ``ndim`` attribute or function
+        should be used instead.
+
+    Parameters
+    ----------
+    a : array_like
+        Array whose number of dimensions is desired. If `a` is not an array,
+        a conversion is attempted.
+
+    Returns
+    -------
+    number_of_dimensions : int
+        The number of dimensions in the array.
+
+    See Also
+    --------
+    ndim : equivalent function
+    ndarray.ndim : equivalent property
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+
+    Notes
+    -----
+    In the old Numeric package, `rank` was the term used for the number of
+    dimensions, but in Numpy `ndim` is used instead.
+
+    Examples
+    --------
+    >>> np.rank([1,2,3])
+    1
+    >>> np.rank(np.array([[1,2,3],[4,5,6]]))
+    2
+    >>> np.rank(1)
+    0
+
+    """
+    # 2014-04-12, 1.9
+    warnings.warn(
+        "`rank` is deprecated; use the `ndim` attribute or function instead. "
+        "To find the rank of a matrix see `numpy.linalg.matrix_rank`.",
+        VisibleDeprecationWarning)
+    try:
+        return a.ndim
+    except AttributeError:
+        return asarray(a).ndim
+
+
+def size(a, axis=None):
+    """
+    Return the number of elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which the elements are counted.  By default, give
+        the total number of elements.
+
+    Returns
+    -------
+    element_count : int
+        Number of elements along the specified axis.
+
+    See Also
+    --------
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+    ndarray.size : number of elements in array
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3],[4,5,6]])
+    >>> np.size(a)
+    6
+    >>> np.size(a,1)
+    3
+    >>> np.size(a,0)
+    2
+
+    """
+    if axis is None:
+        try:
+            return a.size
+        except AttributeError:
+            return asarray(a).size
+    else:
+        try:
+            return a.shape[axis]
+        except AttributeError:
+            return asarray(a).shape[axis]
+
+
+def around(a, decimals=0, out=None):
+    """
+    Evenly round to the given number of decimals.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    decimals : int, optional
+        Number of decimal places to round to (default: 0).  If
+        decimals is negative, it specifies the number of positions to
+        the left of the decimal point.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary. See `doc.ufuncs` (Section
+        "Output arguments") for details.
+
+    Returns
+    -------
+    rounded_array : ndarray
+        An array of the same type as `a`, containing the rounded values.
+        Unless `out` was specified, a new array is created.  A reference to
+        the result is returned.
+
+        The real and imaginary parts of complex numbers are rounded
+        separately.  The result of rounding a float is a float.
+
+    See Also
+    --------
+    ndarray.round : equivalent method
+
+    ceil, fix, floor, rint, trunc
+
+
+    Notes
+    -----
+    For values exactly halfway between rounded decimal values, Numpy
+    rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
+    -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due
+    to the inexact representation of decimal fractions in the IEEE
+    floating point standard [1]_ and errors introduced when scaling
+    by powers of ten.
+
+    References
+    ----------
+    .. [1] "Lecture Notes on the Status of  IEEE 754", William Kahan,
+           http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
+    .. [2] "How Futile are Mindless Assessments of
+           Roundoff in Floating-Point Computation?", William Kahan,
+           http://www.cs.berkeley.edu/~wkahan/Mindless.pdf
+
+    Examples
+    --------
+    >>> np.around([0.37, 1.64])
+    array([ 0.,  2.])
+    >>> np.around([0.37, 1.64], decimals=1)
+    array([ 0.4,  1.6])
+    >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
+    array([ 0.,  2.,  2.,  4.,  4.])
+    >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
+    array([ 1,  2,  3, 11])
+    >>> np.around([1,2,3,11], decimals=-1)
+    array([ 0,  0,  0, 10])
+
+    """
+    try:
+        round = a.round
+    except AttributeError:
+        return _wrapit(a, 'round', decimals, out)
+    return round(decimals, out)
+
+
+def round_(a, decimals=0, out=None):
+    """
+    Round an array to the given number of decimals.
+
+    Refer to `around` for full documentation.
+
+    See Also
+    --------
+    around : equivalent function
+
+    """
+    try:
+        round = a.round
+    except AttributeError:
+        return _wrapit(a, 'round', decimals, out)
+    return round(decimals, out)
+
+
+def mean(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Compute the arithmetic mean along the specified axis.
+
+    Returns the average of the array elements.  The average is taken over
+    the flattened array by default, otherwise over the specified axis.
+    `float64` intermediate and return values are used for integer inputs.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose mean is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the means are computed. The default is to
+        compute the mean of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a mean is performed over multiple axes,
+        instead of a single axis or all the axes as before.
+    dtype : data-type, optional
+        Type to use in computing the mean.  For integer inputs, the default
+        is `float64`; for floating point inputs, it is the same as the
+        input dtype.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.
+        See `doc.ufuncs` for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    m : ndarray, see dtype parameter above
+        If `out=None`, returns a new array containing the mean values,
+        otherwise a reference to the output array is returned.
+
+    See Also
+    --------
+    average : Weighted average
+    std, var, nanmean, nanstd, nanvar
+
+    Notes
+    -----
+    The arithmetic mean is the sum of the elements along the axis divided
+    by the number of elements.
+
+    Note that for floating-point input, the mean is computed using the
+    same precision the input has.  Depending on the input data, this can
+    cause the results to be inaccurate, especially for `float32` (see
+    example below).  Specifying a higher-precision accumulator using the
+    `dtype` keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.mean(a)
+    2.5
+    >>> np.mean(a, axis=0)
+    array([ 2.,  3.])
+    >>> np.mean(a, axis=1)
+    array([ 1.5,  3.5])
+
+    In single precision, `mean` can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.mean(a)
+    0.546875
+
+    Computing the mean in float64 is more accurate:
+
+    >>> np.mean(a, dtype=np.float64)
+    0.55000000074505806
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            mean = a.mean
+            return mean(axis=axis, dtype=dtype, out=out)
+        except AttributeError:
+            pass
+
+    return _methods._mean(a, axis=axis, dtype=dtype,
+                          out=out, keepdims=keepdims)
+
+
+def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the standard deviation along the specified axis.
+
+    Returns the standard deviation, a measure of the spread of a distribution,
+    of the array elements. The standard deviation is computed for the
+    flattened array by default, otherwise over the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Calculate the standard deviation of these values.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the standard deviation is computed. The
+        default is to compute the standard deviation of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a standard deviation is performed over
+        multiple axes, instead of a single axis or all the axes as before.
+    dtype : dtype, optional
+        Type to use in computing the standard deviation. For arrays of
+        integer type the default is float64, for arrays of float types it is
+        the same as the array type.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output but the type (of the calculated
+        values) will be cast if necessary.
+    ddof : int, optional
+        Means Delta Degrees of Freedom.  The divisor used in calculations
+        is ``N - ddof``, where ``N`` represents the number of elements.
+        By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    standard_deviation : ndarray, see dtype parameter above.
+        If `out` is None, return a new array containing the standard deviation,
+        otherwise return a reference to the output array.
+
+    See Also
+    --------
+    var, mean, nanmean, nanstd, nanvar
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The standard deviation is the square root of the average of the squared
+    deviations from the mean, i.e., ``std = sqrt(mean(abs(x - x.mean())**2))``.
+
+    The average squared deviation is normally calculated as
+    ``x.sum() / N``, where ``N = len(x)``.  If, however, `ddof` is specified,
+    the divisor ``N - ddof`` is used instead. In standard statistical
+    practice, ``ddof=1`` provides an unbiased estimator of the variance
+    of the infinite population. ``ddof=0`` provides a maximum likelihood
+    estimate of the variance for normally distributed variables. The
+    standard deviation computed in this function is the square root of
+    the estimated variance, so even with ``ddof=1``, it will not be an
+    unbiased estimate of the standard deviation per se.
+
+    Note that, for complex numbers, `std` takes the absolute
+    value before squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the *std* is computed using the same
+    precision the input has. Depending on the input data, this can cause
+    the results to be inaccurate, especially for float32 (see example below).
+    Specifying a higher-accuracy accumulator using the `dtype` keyword can
+    alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.std(a)
+    1.1180339887498949
+    >>> np.std(a, axis=0)
+    array([ 1.,  1.])
+    >>> np.std(a, axis=1)
+    array([ 0.5,  0.5])
+
+    In single precision, std() can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.std(a)
+    0.45000005
+
+    Computing the standard deviation in float64 is more accurate:
+
+    >>> np.std(a, dtype=np.float64)
+    0.44999999925494177
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            std = a.std
+            return std(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        except AttributeError:
+            pass
+
+    return _methods._std(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                         keepdims=keepdims)
+
+
+def var(a, axis=None, dtype=None, out=None, ddof=0,
+        keepdims=False):
+    """
+    Compute the variance along the specified axis.
+
+    Returns the variance of the array elements, a measure of the spread of a
+    distribution.  The variance is computed for the flattened array by
+    default, otherwise over the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose variance is desired.  If `a` is not an
+        array, a conversion is attempted.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the variance is computed.  The default is to
+        compute the variance of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a variance is performed over multiple axes,
+        instead of a single axis or all the axes as before.
+    dtype : data-type, optional
+        Type to use in computing the variance.  For arrays of integer type
+        the default is `float32`; for arrays of float types it is the same as
+        the array type.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output, but the type is cast if
+        necessary.
+    ddof : int, optional
+        "Delta Degrees of Freedom": the divisor used in the calculation is
+        ``N - ddof``, where ``N`` represents the number of elements. By
+        default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    variance : ndarray, see dtype parameter above
+        If ``out=None``, returns a new array containing the variance;
+        otherwise, a reference to the output array is returned.
+
+    See Also
+    --------
+    std , mean, nanmean, nanstd, nanvar
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The variance is the average of the squared deviations from the mean,
+    i.e.,  ``var = mean(abs(x - x.mean())**2)``.
+
+    The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``.
+    If, however, `ddof` is specified, the divisor ``N - ddof`` is used
+    instead.  In standard statistical practice, ``ddof=1`` provides an
+    unbiased estimator of the variance of a hypothetical infinite population.
+    ``ddof=0`` provides a maximum likelihood estimate of the variance for
+    normally distributed variables.
+
+    Note that for complex numbers, the absolute value is taken before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the variance is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32` (see example
+    below).  Specifying a higher-accuracy accumulator using the ``dtype``
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.var(a)
+    1.25
+    >>> np.var(a, axis=0)
+    array([ 1.,  1.])
+    >>> np.var(a, axis=1)
+    array([ 0.25,  0.25])
+
+    In single precision, var() can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.var(a)
+    0.20250003
+
+    Computing the variance in float64 is more accurate:
+
+    >>> np.var(a, dtype=np.float64)
+    0.20249999932944759
+    >>> ((1-0.55)**2 + (0.1-0.55)**2)/2
+    0.2025
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            var = a.var
+            return var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        except AttributeError:
+            pass
+
+    return _methods._var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                         keepdims=keepdims)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/function_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/function_base.py
new file mode 100644
index 0000000000..21ca1af01a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/function_base.py
@@ -0,0 +1,208 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['logspace', 'linspace']
+
+from . import numeric as _nx
+from .numeric import result_type, NaN, shares_memory, MAY_SHARE_BOUNDS, TooHardError
+
+
+def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
+    """
+    Return evenly spaced numbers over a specified interval.
+
+    Returns `num` evenly spaced samples, calculated over the
+    interval [`start`, `stop`].
+
+    The endpoint of the interval can optionally be excluded.
+
+    Parameters
+    ----------
+    start : scalar
+        The starting value of the sequence.
+    stop : scalar
+        The end value of the sequence, unless `endpoint` is set to False.
+        In that case, the sequence consists of all but the last of ``num + 1``
+        evenly spaced samples, so that `stop` is excluded.  Note that the step
+        size changes when `endpoint` is False.
+    num : int, optional
+        Number of samples to generate. Default is 50. Must be non-negative.
+    endpoint : bool, optional
+        If True, `stop` is the last sample. Otherwise, it is not included.
+        Default is True.
+    retstep : bool, optional
+        If True, return (`samples`, `step`), where `step` is the spacing
+        between samples.
+    dtype : dtype, optional
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    samples : ndarray
+        There are `num` equally spaced samples in the closed interval
+        ``[start, stop]`` or the half-open interval ``[start, stop)``
+        (depending on whether `endpoint` is True or False).
+    step : float
+        Only returned if `retstep` is True
+
+        Size of spacing between samples.
+
+
+    See Also
+    --------
+    arange : Similar to `linspace`, but uses a step size (instead of the
+             number of samples).
+    logspace : Samples uniformly distributed in log space.
+
+    Examples
+    --------
+    >>> np.linspace(2.0, 3.0, num=5)
+        array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])
+    >>> np.linspace(2.0, 3.0, num=5, endpoint=False)
+        array([ 2. ,  2.2,  2.4,  2.6,  2.8])
+    >>> np.linspace(2.0, 3.0, num=5, retstep=True)
+        (array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)
+
+    Graphical illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> N = 8
+    >>> y = np.zeros(N)
+    >>> x1 = np.linspace(0, 10, N, endpoint=True)
+    >>> x2 = np.linspace(0, 10, N, endpoint=False)
+    >>> plt.plot(x1, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(x2, y + 0.5, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.ylim([-0.5, 1])
+    (-0.5, 1)
+    >>> plt.show()
+
+    """
+    num = int(num)
+    if num < 0:
+        raise ValueError("Number of samples, %s, must be non-negative." % num)
+    div = (num - 1) if endpoint else num
+
+    # Convert float/complex array scalars to float, gh-3504
+    start = start * 1.
+    stop = stop * 1.
+
+    dt = result_type(start, stop, float(num))
+    if dtype is None:
+        dtype = dt
+
+    y = _nx.arange(0, num, dtype=dt)
+
+    delta = stop - start
+    if num > 1:
+        step = delta / div
+        if step == 0:
+            # Special handling for denormal numbers, gh-5437
+            y /= div
+            y = y * delta
+        else:
+            # One might be tempted to use faster, in-place multiplication here,
+            # but this prevents step from overriding what class is produced,
+            # and thus prevents, e.g., use of Quantities; see gh-7142.
+            y = y * step
+    else:
+        # 0 and 1 item long sequences have an undefined step
+        step = NaN
+        # Multiply with delta to allow possible override of output class.
+        y = y * delta
+
+    y += start
+
+    if endpoint and num > 1:
+        y[-1] = stop
+
+    if retstep:
+        return y.astype(dtype, copy=False), step
+    else:
+        return y.astype(dtype, copy=False)
+
+
+def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
+    """
+    Return numbers spaced evenly on a log scale.
+
+    In linear space, the sequence starts at ``base ** start``
+    (`base` to the power of `start`) and ends with ``base ** stop``
+    (see `endpoint` below).
+
+    Parameters
+    ----------
+    start : float
+        ``base ** start`` is the starting value of the sequence.
+    stop : float
+        ``base ** stop`` is the final value of the sequence, unless `endpoint`
+        is False.  In that case, ``num + 1`` values are spaced over the
+        interval in log-space, of which all but the last (a sequence of
+        length ``num``) are returned.
+    num : integer, optional
+        Number of samples to generate.  Default is 50.
+    endpoint : boolean, optional
+        If true, `stop` is the last sample. Otherwise, it is not included.
+        Default is True.
+    base : float, optional
+        The base of the log space. The step size between the elements in
+        ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform.
+        Default is 10.0.
+    dtype : dtype
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+    Returns
+    -------
+    samples : ndarray
+        `num` samples, equally spaced on a log scale.
+
+    See Also
+    --------
+    arange : Similar to linspace, with the step size specified instead of the
+             number of samples. Note that, when used with a float endpoint, the
+             endpoint may or may not be included.
+    linspace : Similar to logspace, but with the samples uniformly distributed
+               in linear space, instead of log space.
+
+    Notes
+    -----
+    Logspace is equivalent to the code
+
+    >>> y = np.linspace(start, stop, num=num, endpoint=endpoint)
+    ... # doctest: +SKIP
+    >>> power(base, y).astype(dtype)
+    ... # doctest: +SKIP
+
+    Examples
+    --------
+    >>> np.logspace(2.0, 3.0, num=4)
+        array([  100.        ,   215.443469  ,   464.15888336,  1000.        ])
+    >>> np.logspace(2.0, 3.0, num=4, endpoint=False)
+        array([ 100.        ,  177.827941  ,  316.22776602,  562.34132519])
+    >>> np.logspace(2.0, 3.0, num=4, base=2.0)
+        array([ 4.        ,  5.0396842 ,  6.34960421,  8.        ])
+
+    Graphical illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> N = 10
+    >>> x1 = np.logspace(0.1, 1, N, endpoint=True)
+    >>> x2 = np.logspace(0.1, 1, N, endpoint=False)
+    >>> y = np.zeros(N)
+    >>> plt.plot(x1, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(x2, y + 0.5, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.ylim([-0.5, 1])
+    (-0.5, 1)
+    >>> plt.show()
+
+    """
+    y = linspace(start, stop, num=num, endpoint=endpoint)
+    if dtype is None:
+        return _nx.power(base, y)
+    return _nx.power(base, y).astype(dtype)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
new file mode 100644
index 0000000000..d376ffd292
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
@@ -0,0 +1,253 @@
+from __future__ import division, print_function
+
+import os
+import genapi
+
+from genapi import \
+        TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi
+
+import numpy_api
+
+# use annotated api when running under cpychecker
+h_template = r"""
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+%s
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+%s
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%%x but this version of numpy is 0x%%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%%x but this version of numpy is 0x%%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
+"""
+
+
+c_template = r"""
+/* These pointers will be stored in the C-object for use in other
+    extension modules
+*/
+
+void *PyArray_API[] = {
+%s
+};
+"""
+
+c_api_header = """
+===========
+Numpy C-API
+===========
+"""
+
+def generate_api(output_dir, force=False):
+    basename = 'multiarray_api'
+
+    h_file = os.path.join(output_dir, '__%s.h' % basename)
+    c_file = os.path.join(output_dir, '__%s.c' % basename)
+    d_file = os.path.join(output_dir, '%s.txt' % basename)
+    targets = (h_file, c_file, d_file)
+
+    sources = numpy_api.multiarray_api
+
+    if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):
+        return targets
+    else:
+        do_generate_api(targets, sources)
+
+    return targets
+
+def do_generate_api(targets, sources):
+    header_file = targets[0]
+    c_file = targets[1]
+    doc_file = targets[2]
+
+    global_vars = sources[0]
+    scalar_bool_values = sources[1]
+    types_api = sources[2]
+    multiarray_funcs = sources[3]
+
+    multiarray_api = sources[:]
+
+    module_list = []
+    extension_list = []
+    init_list = []
+
+    # Check multiarray api indexes
+    multiarray_api_index = genapi.merge_api_dicts(multiarray_api)
+    genapi.check_api_dict(multiarray_api_index)
+
+    numpyapi_list = genapi.get_api_functions('NUMPY_API',
+                                              multiarray_funcs)
+    ordered_funcs_api = genapi.order_dict(multiarray_funcs)
+
+    # Create dict name -> *Api instance
+    api_name = 'PyArray_API'
+    multiarray_api_dict = {}
+    for f in numpyapi_list:
+        name = f.name
+        index = multiarray_funcs[name][0]
+        annotations = multiarray_funcs[name][1:]
+        multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,
+                                                  f.return_type,
+                                                  f.args, api_name)
+
+    for name, val in global_vars.items():
+        index, type = val
+        multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)
+
+    for name, val in scalar_bool_values.items():
+        index = val[0]
+        multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)
+
+    for name, val in types_api.items():
+        index = val[0]
+        multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)
+
+    if len(multiarray_api_dict) != len(multiarray_api_index):
+        raise AssertionError("Multiarray API size mismatch %d %d" %
+                        (len(multiarray_api_dict), len(multiarray_api_index)))
+
+    extension_list = []
+    for name, index in genapi.order_dict(multiarray_api_index):
+        api_item = multiarray_api_dict[name]
+        extension_list.append(api_item.define_from_array_api_string())
+        init_list.append(api_item.array_api_define())
+        module_list.append(api_item.internal_define())
+
+    # Write to header
+    fid = open(header_file, 'w')
+    s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
+    fid.write(s)
+    fid.close()
+
+    # Write to c-code
+    fid = open(c_file, 'w')
+    s = c_template % ',\n'.join(init_list)
+    fid.write(s)
+    fid.close()
+
+    # write to documentation
+    fid = open(doc_file, 'w')
+    fid.write(c_api_header)
+    for func in numpyapi_list:
+        fid.write(func.to_ReST())
+        fid.write('\n\n')
+    fid.close()
+
+    return targets
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/getlimits.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/getlimits.py
new file mode 100644
index 0000000000..2ea9c0e11a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/getlimits.py
@@ -0,0 +1,308 @@
+"""Machine limits for Float32 and Float64 and (long double) if available...
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['finfo', 'iinfo']
+
+from .machar import MachAr
+from . import numeric
+from . import numerictypes as ntypes
+from .numeric import array
+
+def _frz(a):
+    """fix rank-0 --> rank-1"""
+    if a.ndim == 0:
+        a.shape = (1,)
+    return a
+
+_convert_to_float = {
+    ntypes.csingle: ntypes.single,
+    ntypes.complex_: ntypes.float_,
+    ntypes.clongfloat: ntypes.longfloat
+    }
+
+class finfo(object):
+    """
+    finfo(dtype)
+
+    Machine limits for floating point types.
+
+    Attributes
+    ----------
+    eps : float
+        The smallest representable positive number such that
+        ``1.0 + eps != 1.0``.  Type of `eps` is an appropriate floating
+        point type.
+    epsneg : floating point number of the appropriate type
+        The smallest representable positive number such that
+        ``1.0 - epsneg != 1.0``.
+    iexp : int
+        The number of bits in the exponent portion of the floating point
+        representation.
+    machar : MachAr
+        The object which calculated these parameters and holds more
+        detailed information.
+    machep : int
+        The exponent that yields `eps`.
+    max : floating point number of the appropriate type
+        The largest representable number.
+    maxexp : int
+        The smallest positive power of the base (2) that causes overflow.
+    min : floating point number of the appropriate type
+        The smallest representable number, typically ``-max``.
+    minexp : int
+        The most negative power of the base (2) consistent with there
+        being no leading 0's in the mantissa.
+    negep : int
+        The exponent that yields `epsneg`.
+    nexp : int
+        The number of bits in the exponent including its sign and bias.
+    nmant : int
+        The number of bits in the mantissa.
+    precision : int
+        The approximate number of decimal digits to which this kind of
+        float is precise.
+    resolution : floating point number of the appropriate type
+        The approximate decimal resolution of this type, i.e.,
+        ``10**-precision``.
+    tiny : float
+        The smallest positive usable number.  Type of `tiny` is an
+        appropriate floating point type.
+
+    Parameters
+    ----------
+    dtype : float, dtype, or instance
+        Kind of floating point data-type about which to get information.
+
+    See Also
+    --------
+    MachAr : The implementation of the tests that produce this information.
+    iinfo : The equivalent for integer data types.
+
+    Notes
+    -----
+    For developers of NumPy: do not instantiate this at the module level.
+    The initial calculation of these parameters is expensive and negatively
+    impacts import times.  These objects are cached, so calling ``finfo()``
+    repeatedly inside your functions is not a problem.
+
+    """
+
+    _finfo_cache = {}
+
+    def __new__(cls, dtype):
+        try:
+            dtype = numeric.dtype(dtype)
+        except TypeError:
+            # In case a float instance was given
+            dtype = numeric.dtype(type(dtype))
+
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        dtypes = [dtype]
+        newdtype = numeric.obj2sctype(dtype)
+        if newdtype is not dtype:
+            dtypes.append(newdtype)
+            dtype = newdtype
+        if not issubclass(dtype, numeric.inexact):
+            raise ValueError("data type %r not inexact" % (dtype))
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        if not issubclass(dtype, numeric.floating):
+            newdtype = _convert_to_float[dtype]
+            if newdtype is not dtype:
+                dtypes.append(newdtype)
+                dtype = newdtype
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        obj = object.__new__(cls)._init(dtype)
+        for dt in dtypes:
+            cls._finfo_cache[dt] = obj
+        return obj
+
+    def _init(self, dtype):
+        self.dtype = numeric.dtype(dtype)
+        if dtype is ntypes.double:
+            itype = ntypes.int64
+            fmt = '%24.16e'
+            precname = 'double'
+        elif dtype is ntypes.single:
+            itype = ntypes.int32
+            fmt = '%15.7e'
+            precname = 'single'
+        elif dtype is ntypes.longdouble:
+            itype = ntypes.longlong
+            fmt = '%s'
+            precname = 'long double'
+        elif dtype is ntypes.half:
+            itype = ntypes.int16
+            fmt = '%12.5e'
+            precname = 'half'
+        else:
+            raise ValueError(repr(dtype))
+
+        machar = MachAr(lambda v:array([v], dtype),
+                        lambda v:_frz(v.astype(itype))[0],
+                        lambda v:array(_frz(v)[0], dtype),
+                        lambda v: fmt % array(_frz(v)[0], dtype),
+                        'numpy %s precision floating point number' % precname)
+
+        for word in ['precision', 'iexp',
+                     'maxexp', 'minexp', 'negep',
+                     'machep']:
+            setattr(self, word, getattr(machar, word))
+        for word in ['tiny', 'resolution', 'epsneg']:
+            setattr(self, word, getattr(machar, word).flat[0])
+        self.max = machar.huge.flat[0]
+        self.min = -self.max
+        self.eps = machar.eps.flat[0]
+        self.nexp = machar.iexp
+        self.nmant = machar.it
+        self.machar = machar
+        self._str_tiny = machar._str_xmin.strip()
+        self._str_max = machar._str_xmax.strip()
+        self._str_epsneg = machar._str_epsneg.strip()
+        self._str_eps = machar._str_eps.strip()
+        self._str_resolution = machar._str_resolution.strip()
+        return self
+
+    def __str__(self):
+        fmt = (
+            'Machine parameters for %(dtype)s\n'
+            '---------------------------------------------------------------\n'
+            'precision=%(precision)3s   resolution= %(_str_resolution)s\n'
+            'machep=%(machep)6s   eps=        %(_str_eps)s\n'
+            'negep =%(negep)6s   epsneg=     %(_str_epsneg)s\n'
+            'minexp=%(minexp)6s   tiny=       %(_str_tiny)s\n'
+            'maxexp=%(maxexp)6s   max=        %(_str_max)s\n'
+            'nexp  =%(nexp)6s   min=        -max\n'
+            '---------------------------------------------------------------\n'
+            )
+        return fmt % self.__dict__
+
+    def __repr__(self):
+        c = self.__class__.__name__
+        d = self.__dict__.copy()
+        d['klass'] = c
+        return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s,"
+                 " max=%(_str_max)s, dtype=%(dtype)s)") % d)
+
+
+class iinfo(object):
+    """
+    iinfo(type)
+
+    Machine limits for integer types.
+
+    Attributes
+    ----------
+    min : int
+        The smallest integer expressible by the type.
+    max : int
+        The largest integer expressible by the type.
+
+    Parameters
+    ----------
+    int_type : integer type, dtype, or instance
+        The kind of integer data type to get information about.
+
+    See Also
+    --------
+    finfo : The equivalent for floating point data types.
+
+    Examples
+    --------
+    With types:
+
+    >>> ii16 = np.iinfo(np.int16)
+    >>> ii16.min
+    -32768
+    >>> ii16.max
+    32767
+    >>> ii32 = np.iinfo(np.int32)
+    >>> ii32.min
+    -2147483648
+    >>> ii32.max
+    2147483647
+
+    With instances:
+
+    >>> ii32 = np.iinfo(np.int32(10))
+    >>> ii32.min
+    -2147483648
+    >>> ii32.max
+    2147483647
+
+    """
+
+    _min_vals = {}
+    _max_vals = {}
+
+    def __init__(self, int_type):
+        try:
+            self.dtype = numeric.dtype(int_type)
+        except TypeError:
+            self.dtype = numeric.dtype(type(int_type))
+        self.kind = self.dtype.kind
+        self.bits = self.dtype.itemsize * 8
+        self.key = "%s%d" % (self.kind, self.bits)
+        if self.kind not in 'iu':
+            raise ValueError("Invalid integer data type.")
+
+    def min(self):
+        """Minimum value of given dtype."""
+        if self.kind == 'u':
+            return 0
+        else:
+            try:
+                val = iinfo._min_vals[self.key]
+            except KeyError:
+                val = int(-(1 << (self.bits-1)))
+                iinfo._min_vals[self.key] = val
+            return val
+
+    min = property(min)
+
+    def max(self):
+        """Maximum value of given dtype."""
+        try:
+            val = iinfo._max_vals[self.key]
+        except KeyError:
+            if self.kind == 'u':
+                val = int((1 << self.bits) - 1)
+            else:
+                val = int((1 << (self.bits-1)) - 1)
+            iinfo._max_vals[self.key] = val
+        return val
+
+    max = property(max)
+
+    def __str__(self):
+        """String representation."""
+        fmt = (
+            'Machine parameters for %(dtype)s\n'
+            '---------------------------------------------------------------\n'
+            'min = %(min)s\n'
+            'max = %(max)s\n'
+            '---------------------------------------------------------------\n'
+            )
+        return fmt % {'dtype': self.dtype, 'min': self.min, 'max': self.max}
+
+    def __repr__(self):
+        return "%s(min=%s, max=%s, dtype=%s)" % (self.__class__.__name__,
+                                    self.min, self.max, self.dtype)
+
+if __name__ == '__main__':
+    f = finfo(ntypes.single)
+    print('single epsilon:', f.eps)
+    print('single tiny:', f.tiny)
+    f = finfo(ntypes.float)
+    print('float epsilon:', f.eps)
+    print('float tiny:', f.tiny)
+    f = finfo(ntypes.longfloat)
+    print('longfloat epsilon:', f.eps)
+    print('longfloat tiny:', f.tiny)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
new file mode 100644
index 0000000000..aefb9de029
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
@@ -0,0 +1,1540 @@
+
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCVersion \
+       (void);
+extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type;
+
+extern NPY_NO_EXPORT int NPY_NUMUSERTYPES;
+
+extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type;
+
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type;
+
+NPY_NO_EXPORT  int PyArray_SetNumericOps \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_GetNumericOps \
+       (void);
+NPY_NO_EXPORT  int PyArray_INCREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_XDECREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  void PyArray_SetStringFunction \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromType \
+       (int);
+NPY_NO_EXPORT  PyObject * PyArray_TypeObjectFromType \
+       (int);
+NPY_NO_EXPORT  char * PyArray_Zero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  char * PyArray_One \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_CastTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CastAnyTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CanCastSafely \
+       (int, int);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTo \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_ObjectType \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromObject \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArrayObject ** PyArray_ConvertToCommonType \
+       (PyObject *, int *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromScalar \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromTypeObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_Size \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Scalar \
+       (void *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_ScalarAsCtype \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_CastScalarToCtype \
+       (PyObject *, void *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_CastScalarDirect \
+       (PyObject *, PyArray_Descr *, void *, int);
+NPY_NO_EXPORT  PyObject * PyArray_ScalarFromObject \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+       (PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromDims \
+       (int, int *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \
+       (int, int *, PyArray_Descr *, char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \
+       (PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromFile \
+       (FILE *, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromString \
+       (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromBuffer \
+       (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \
+       (PyObject *, PyArray_Descr *, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \
+       (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Byteswap \
+       (PyArrayObject *, npy_bool);
+NPY_NO_EXPORT  PyObject * PyArray_Resize \
+       (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_MoveInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyAnyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_ToList \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ToString \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_ToFile \
+       (PyArrayObject *, FILE *, char *, char *);
+NPY_NO_EXPORT  int PyArray_Dump \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Dumps \
+       (PyObject *, int);
+NPY_NO_EXPORT  int PyArray_ValidType \
+       (int);
+NPY_NO_EXPORT  void PyArray_UpdateFlags \
+       (PyArrayObject *, int);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \
+       (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \
+       (PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNew \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewFromType \
+       (int);
+NPY_NO_EXPORT  double PyArray_GetPriority \
+       (PyObject *, double);
+NPY_NO_EXPORT  PyObject * PyArray_IterNew \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterNew \
+       (int, ...);
+NPY_NO_EXPORT  int PyArray_PyIntAsInt \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_PyIntAsIntp \
+       (PyObject *);
+NPY_NO_EXPORT  int PyArray_Broadcast \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  void PyArray_FillObjectArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  int PyArray_FillWithScalar \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CheckStrides \
+       (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewByteorder \
+       (PyArray_Descr *, char);
+NPY_NO_EXPORT  PyObject * PyArray_IterAllButAxis \
+       (PyObject *, int *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromStructInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromArrayAttr \
+       (PyObject *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT  NPY_SCALARKIND PyArray_ScalarKind \
+       (int, PyArrayObject **);
+NPY_NO_EXPORT  int PyArray_CanCoerceScalar \
+       (int, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  PyObject * PyArray_NewFlagsObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastScalar \
+       (PyTypeObject *, PyTypeObject *);
+NPY_NO_EXPORT  int PyArray_CompareUCS4 \
+       (npy_ucs4 *, npy_ucs4 *, size_t);
+NPY_NO_EXPORT  int PyArray_RemoveSmallest \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  int PyArray_ElementStrides \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_Item_INCREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_Item_XDECREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  PyObject * PyArray_FieldNames \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Transpose \
+       (PyArrayObject *, PyArray_Dims *);
+NPY_NO_EXPORT  PyObject * PyArray_TakeFrom \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutTo \
+       (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutMask \
+       (PyArrayObject *, PyObject*, PyObject*);
+NPY_NO_EXPORT  PyObject * PyArray_Repeat \
+       (PyArrayObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Choose \
+       (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  int PyArray_Sort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgSort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_SearchSorted \
+       (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMax \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMin \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Reshape \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Newshape \
+       (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Squeeze \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \
+       (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+NPY_NO_EXPORT  PyObject * PyArray_SwapAxes \
+       (PyArrayObject *, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Max \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Min \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Ptp \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Mean \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Trace \
+       (PyArrayObject *, int, int, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Diagonal \
+       (PyArrayObject *, int, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Clip \
+       (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Conjugate \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Nonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Std \
+       (PyArrayObject *, int, int, PyArrayObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Sum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumSum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Prod \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumProd \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_All \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Any \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Compress \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Flatten \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Ravel \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  npy_intp PyArray_MultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_MultiplyIntList \
+       (int *, int);
+NPY_NO_EXPORT  void * PyArray_GetPtr \
+       (PyArrayObject *, npy_intp*);
+NPY_NO_EXPORT  int PyArray_CompareLists \
+       (npy_intp *, npy_intp *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \
+       (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+NPY_NO_EXPORT  int PyArray_As1D \
+       (PyObject **, char **, int *, int);
+NPY_NO_EXPORT  int PyArray_As2D \
+       (PyObject **, char ***, int *, int *, int);
+NPY_NO_EXPORT  int PyArray_Free \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_Converter \
+       (PyObject *, PyObject **);
+NPY_NO_EXPORT  int PyArray_IntpFromSequence \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Concatenate \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_InnerProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CopyAndTranspose \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  int PyArray_TypestrConvert \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_DescrConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_IntpConverter \
+       (PyObject *, PyArray_Dims *);
+NPY_NO_EXPORT  int PyArray_BufferConverter \
+       (PyObject *, PyArray_Chunk *);
+NPY_NO_EXPORT  int PyArray_AxisConverter \
+       (PyObject *, int *);
+NPY_NO_EXPORT  int PyArray_BoolConverter \
+       (PyObject *, npy_bool *);
+NPY_NO_EXPORT  int PyArray_ByteorderConverter \
+       (PyObject *, char *);
+NPY_NO_EXPORT  int PyArray_OrderConverter \
+       (PyObject *, NPY_ORDER *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Where \
+       (PyObject *, PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Arange \
+       (double, double, double, int);
+NPY_NO_EXPORT  PyObject * PyArray_ArangeObj \
+       (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_SortkindConverter \
+       (PyObject *, NPY_SORTKIND *);
+NPY_NO_EXPORT  PyObject * PyArray_LexSort \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Round \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypenums \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_RegisterDataType \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_RegisterCastFunc \
+       (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+NPY_NO_EXPORT  int PyArray_RegisterCanCast \
+       (PyArray_Descr *, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  void PyArray_InitArrFuncs \
+       (PyArray_ArrFuncs *);
+NPY_NO_EXPORT  PyObject * PyArray_IntTupleFromIntp \
+       (int, npy_intp *);
+NPY_NO_EXPORT  int PyArray_TypeNumFromName \
+       (char *);
+NPY_NO_EXPORT  int PyArray_ClipmodeConverter \
+       (PyObject *, NPY_CLIPMODE *);
+NPY_NO_EXPORT  int PyArray_OutputConverter \
+       (PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  PyObject * PyArray_BroadcastToShape \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  void _PyArray_SigintHandler \
+       (int);
+NPY_NO_EXPORT  void* _PyArray_GetSigintBuf \
+       (void);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_SearchsideConverter \
+       (PyObject *, void *);
+NPY_NO_EXPORT  PyObject * PyArray_CheckAxis \
+       (PyArrayObject *, int *, int);
+NPY_NO_EXPORT  npy_intp PyArray_OverflowMultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_CompareString \
+       (char *, char *, size_t);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterFromObjects \
+       (PyObject **, int, int, ...);
+NPY_NO_EXPORT  int PyArray_GetEndianness \
+       (void);
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCFeatureVersion \
+       (void);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate2 \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject* PyArray_NeighborhoodIterNew \
+       (PyArrayIterObject *, npy_intp *, int, PyArrayObject*);
+extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject NpyIter_Type;
+
+NPY_NO_EXPORT  void PyArray_SetDatetimeParseFunction \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_DatetimeToDatetimeStruct \
+       (npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  void PyArray_TimedeltaToTimedeltaStruct \
+       (npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_DatetimeStructToDatetime \
+       (NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_TimedeltaStructToTimedelta \
+       (NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  NpyIter * NpyIter_New \
+       (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*);
+NPY_NO_EXPORT  NpyIter * NpyIter_MultiNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **);
+NPY_NO_EXPORT  NpyIter * NpyIter_AdvancedNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp);
+NPY_NO_EXPORT  NpyIter * NpyIter_Copy \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Deallocate \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasDelayedBufAlloc \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_EnableExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerStrideArray \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerLoopSizePtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Reset \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_ResetBasePointers \
+       (NpyIter *, char **, char **);
+NPY_NO_EXPORT  int NpyIter_ResetToIterIndexRange \
+       (NpyIter *, npy_intp, npy_intp, char **);
+NPY_NO_EXPORT  int NpyIter_GetNDim \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetNOp \
+       (NpyIter *);
+NPY_NO_EXPORT  NpyIter_IterNextFunc * NpyIter_GetIterNext \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterSize \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetIterIndexRange \
+       (NpyIter *, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIterIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  npy_bool NpyIter_HasMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetShape \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_GotoMultiIndex \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsBuffered \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsGrowInner \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetBufferSize \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetIndexPtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  char ** NpyIter_GetDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArray_Descr ** NpyIter_GetDescrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject ** NpyIter_GetOperandArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject * NpyIter_GetIterView \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  void NpyIter_GetReadFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_GetWriteFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_DebugPrint \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IterationNeedsAPI \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetInnerFixedStrideArray \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveAxis \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetAxisStrideArray \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_bool NpyIter_RequiresBuffering \
+       (NpyIter *);
+NPY_NO_EXPORT  char ** NpyIter_GetInitialDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_CreateCompatibleStrides \
+       (NpyIter *, npy_intp, npy_intp *);
+NPY_NO_EXPORT  int PyArray_CastingConverter \
+       (PyObject *, NPY_CASTING *);
+NPY_NO_EXPORT  npy_intp PyArray_CountNonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_PromoteTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_MinScalarType \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_ResultType \
+       (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastArrayTo \
+       (PyArrayObject *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTypeTo \
+       (PyArray_Descr *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  PyArrayObject * PyArray_EinsteinSum \
+       (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \
+       (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_GetArrayParamsFromObject \
+       (PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *);
+NPY_NO_EXPORT  int PyArray_ConvertClipmodeSequence \
+       (PyObject *, NPY_CLIPMODE *, int);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct2 \
+       (PyObject *, PyObject *, PyArrayObject*);
+NPY_NO_EXPORT  npy_bool NpyIter_IsFirstVisit \
+       (NpyIter *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_CreateSortedStridePerm \
+       (int, npy_intp *, npy_stride_sort_item *);
+NPY_NO_EXPORT  void PyArray_RemoveAxesInPlace \
+       (PyArrayObject *, npy_bool *);
+NPY_NO_EXPORT  void PyArray_DebugPrint \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_FailUnlessWriteable \
+       (PyArrayObject *, const char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  void * PyDataMem_NEW \
+       (size_t);
+NPY_NO_EXPORT  void PyDataMem_FREE \
+       (void *);
+NPY_NO_EXPORT  void * PyDataMem_RENEW \
+       (void *, size_t);
+NPY_NO_EXPORT  PyDataMem_EventHookFunc * PyDataMem_SetEventHook \
+       (PyDataMem_EventHookFunc *, void *, void **);
+extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING;
+
+NPY_NO_EXPORT  void PyArray_MapIterSwapAxes \
+       (PyArrayMapIterObject *, PyArrayObject **, int);
+NPY_NO_EXPORT  PyObject * PyArray_MapIterArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_MapIterNext \
+       (PyArrayMapIterObject *);
+NPY_NO_EXPORT  int PyArray_Partition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgPartition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  int PyArray_SelectkindConverter \
+       (PyObject *, NPY_SELECTKIND *);
+NPY_NO_EXPORT  void * PyDataMem_NEW_ZEROED \
+       (size_t, size_t);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \
+       (PyObject *);
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+#define PyArray_GetNDArrayCVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[40])
+#define PyArray_GetNumericOps \
+        (*(PyObject * (*)(void)) \
+         PyArray_API[41])
+#define PyArray_INCREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[42])
+#define PyArray_XDECREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[43])
+#define PyArray_SetStringFunction \
+        (*(void (*)(PyObject *, int)) \
+         PyArray_API[44])
+#define PyArray_DescrFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+        (*(PyObject * (*)(int)) \
+         PyArray_API[46])
+#define PyArray_Zero \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[47])
+#define PyArray_One \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[48])
+#define PyArray_CastToType \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[49])
+#define PyArray_CastTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[50])
+#define PyArray_CastAnyTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[51])
+#define PyArray_CanCastSafely \
+        (*(int (*)(int, int)) \
+         PyArray_API[52])
+#define PyArray_CanCastTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[53])
+#define PyArray_ObjectType \
+        (*(int (*)(PyObject *, int)) \
+         PyArray_API[54])
+#define PyArray_DescrFromObject \
+        (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+        (*(PyArrayObject ** (*)(PyObject *, int *)) \
+         PyArray_API[56])
+#define PyArray_DescrFromScalar \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[58])
+#define PyArray_Size \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[59])
+#define PyArray_Scalar \
+        (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[60])
+#define PyArray_FromScalar \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+        (*(void (*)(PyObject *, void *)) \
+         PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+        (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+         PyArray_API[63])
+#define PyArray_CastScalarDirect \
+        (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+         PyArray_API[64])
+#define PyArray_ScalarFromObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[65])
+#define PyArray_GetCastFunc \
+        (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+         PyArray_API[66])
+#define PyArray_FromDims \
+        (*(PyObject * (*)(int, int *, int)) \
+         PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+        (*(PyObject * (*)(int, int *, PyArray_Descr *, char *)) \
+         PyArray_API[68])
+#define PyArray_FromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[69])
+#define PyArray_EnsureArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[71])
+#define PyArray_FromFile \
+        (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[72])
+#define PyArray_FromString \
+        (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[73])
+#define PyArray_FromBuffer \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+         PyArray_API[74])
+#define PyArray_FromIter \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+         PyArray_API[75])
+#define PyArray_Return \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[76])
+#define PyArray_GetField \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[77])
+#define PyArray_SetField \
+        (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+         PyArray_API[78])
+#define PyArray_Byteswap \
+        (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+         PyArray_API[79])
+#define PyArray_Resize \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER)) \
+         PyArray_API[80])
+#define PyArray_MoveInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[81])
+#define PyArray_CopyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[82])
+#define PyArray_CopyAnyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[83])
+#define PyArray_CopyObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[84])
+#define PyArray_NewCopy \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[85])
+#define PyArray_ToList \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[86])
+#define PyArray_ToString \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[87])
+#define PyArray_ToFile \
+        (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+         PyArray_API[88])
+#define PyArray_Dump \
+        (*(int (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[89])
+#define PyArray_Dumps \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[90])
+#define PyArray_ValidType \
+        (*(int (*)(int)) \
+         PyArray_API[91])
+#define PyArray_UpdateFlags \
+        (*(void (*)(PyArrayObject *, int)) \
+         PyArray_API[92])
+#define PyArray_New \
+        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
+         PyArray_API[93])
+#define PyArray_NewFromDescr \
+        (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *)) \
+         PyArray_API[94])
+#define PyArray_DescrNew \
+        (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+         PyArray_API[95])
+#define PyArray_DescrNewFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[96])
+#define PyArray_GetPriority \
+        (*(double (*)(PyObject *, double)) \
+         PyArray_API[97])
+#define PyArray_IterNew \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[98])
+#define PyArray_MultiIterNew \
+        (*(PyObject * (*)(int, ...)) \
+         PyArray_API[99])
+#define PyArray_PyIntAsInt \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[101])
+#define PyArray_Broadcast \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[102])
+#define PyArray_FillObjectArray \
+        (*(void (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[103])
+#define PyArray_FillWithScalar \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[104])
+#define PyArray_CheckStrides \
+        (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)) \
+         PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+         PyArray_API[106])
+#define PyArray_IterAllButAxis \
+        (*(PyObject * (*)(PyObject *, int *)) \
+         PyArray_API[107])
+#define PyArray_CheckFromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[108])
+#define PyArray_FromArray \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[109])
+#define PyArray_FromInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[110])
+#define PyArray_FromStructInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[111])
+#define PyArray_FromArrayAttr \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[112])
+#define PyArray_ScalarKind \
+        (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+         PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+        (*(int (*)(int, int, NPY_SCALARKIND)) \
+         PyArray_API[114])
+#define PyArray_NewFlagsObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[115])
+#define PyArray_CanCastScalar \
+        (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+         PyArray_API[116])
+#define PyArray_CompareUCS4 \
+        (*(int (*)(npy_ucs4 *, npy_ucs4 *, size_t)) \
+         PyArray_API[117])
+#define PyArray_RemoveSmallest \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[118])
+#define PyArray_ElementStrides \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[119])
+#define PyArray_Item_INCREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[120])
+#define PyArray_Item_XDECREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[121])
+#define PyArray_FieldNames \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[122])
+#define PyArray_Transpose \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+         PyArray_API[123])
+#define PyArray_TakeFrom \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[124])
+#define PyArray_PutTo \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+         PyArray_API[125])
+#define PyArray_PutMask \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+         PyArray_API[126])
+#define PyArray_Repeat \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+         PyArray_API[127])
+#define PyArray_Choose \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[128])
+#define PyArray_Sort \
+        (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[129])
+#define PyArray_ArgSort \
+        (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[130])
+#define PyArray_SearchSorted \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \
+         PyArray_API[131])
+#define PyArray_ArgMax \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[132])
+#define PyArray_ArgMin \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[133])
+#define PyArray_Reshape \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[134])
+#define PyArray_Newshape \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+         PyArray_API[135])
+#define PyArray_Squeeze \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[136])
+#define PyArray_View \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+         PyArray_API[137])
+#define PyArray_SwapAxes \
+        (*(PyObject * (*)(PyArrayObject *, int, int)) \
+         PyArray_API[138])
+#define PyArray_Max \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[139])
+#define PyArray_Min \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[140])
+#define PyArray_Ptp \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[141])
+#define PyArray_Mean \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[142])
+#define PyArray_Trace \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+         PyArray_API[143])
+#define PyArray_Diagonal \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+         PyArray_API[144])
+#define PyArray_Clip \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+         PyArray_API[145])
+#define PyArray_Conjugate \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[146])
+#define PyArray_Nonzero \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[147])
+#define PyArray_Std \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+         PyArray_API[148])
+#define PyArray_Sum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[149])
+#define PyArray_CumSum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[150])
+#define PyArray_Prod \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[151])
+#define PyArray_CumProd \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[152])
+#define PyArray_All \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[153])
+#define PyArray_Any \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[154])
+#define PyArray_Compress \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+         PyArray_API[155])
+#define PyArray_Flatten \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[156])
+#define PyArray_Ravel \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[157])
+#define PyArray_MultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[158])
+#define PyArray_MultiplyIntList \
+        (*(int (*)(int *, int)) \
+         PyArray_API[159])
+#define PyArray_GetPtr \
+        (*(void * (*)(PyArrayObject *, npy_intp*)) \
+         PyArray_API[160])
+#define PyArray_CompareLists \
+        (*(int (*)(npy_intp *, npy_intp *, int)) \
+         PyArray_API[161])
+#define PyArray_AsCArray \
+        (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+         PyArray_API[162])
+#define PyArray_As1D \
+        (*(int (*)(PyObject **, char **, int *, int)) \
+         PyArray_API[163])
+#define PyArray_As2D \
+        (*(int (*)(PyObject **, char ***, int *, int *, int)) \
+         PyArray_API[164])
+#define PyArray_Free \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[165])
+#define PyArray_Converter \
+        (*(int (*)(PyObject *, PyObject **)) \
+         PyArray_API[166])
+#define PyArray_IntpFromSequence \
+        (*(int (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[167])
+#define PyArray_Concatenate \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[168])
+#define PyArray_InnerProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[169])
+#define PyArray_MatrixProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[171])
+#define PyArray_Correlate \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[172])
+#define PyArray_TypestrConvert \
+        (*(int (*)(int, int)) \
+         PyArray_API[173])
+#define PyArray_DescrConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[174])
+#define PyArray_DescrConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[175])
+#define PyArray_IntpConverter \
+        (*(int (*)(PyObject *, PyArray_Dims *)) \
+         PyArray_API[176])
+#define PyArray_BufferConverter \
+        (*(int (*)(PyObject *, PyArray_Chunk *)) \
+         PyArray_API[177])
+#define PyArray_AxisConverter \
+        (*(int (*)(PyObject *, int *)) \
+         PyArray_API[178])
+#define PyArray_BoolConverter \
+        (*(int (*)(PyObject *, npy_bool *)) \
+         PyArray_API[179])
+#define PyArray_ByteorderConverter \
+        (*(int (*)(PyObject *, char *)) \
+         PyArray_API[180])
+#define PyArray_OrderConverter \
+        (*(int (*)(PyObject *, NPY_ORDER *)) \
+         PyArray_API[181])
+#define PyArray_EquivTypes \
+        (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[182])
+#define PyArray_Zeros \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[183])
+#define PyArray_Empty \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[184])
+#define PyArray_Where \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+         PyArray_API[185])
+#define PyArray_Arange \
+        (*(PyObject * (*)(double, double, double, int)) \
+         PyArray_API[186])
+#define PyArray_ArangeObj \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+         PyArray_API[187])
+#define PyArray_SortkindConverter \
+        (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+         PyArray_API[188])
+#define PyArray_LexSort \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[189])
+#define PyArray_Round \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[190])
+#define PyArray_EquivTypenums \
+        (*(unsigned char (*)(int, int)) \
+         PyArray_API[191])
+#define PyArray_RegisterDataType \
+        (*(int (*)(PyArray_Descr *)) \
+         PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+        (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+         PyArray_API[193])
+#define PyArray_RegisterCanCast \
+        (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+         PyArray_API[194])
+#define PyArray_InitArrFuncs \
+        (*(void (*)(PyArray_ArrFuncs *)) \
+         PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+        (*(PyObject * (*)(int, npy_intp *)) \
+         PyArray_API[196])
+#define PyArray_TypeNumFromName \
+        (*(int (*)(char *)) \
+         PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+         PyArray_API[198])
+#define PyArray_OutputConverter \
+        (*(int (*)(PyObject *, PyArrayObject **)) \
+         PyArray_API[199])
+#define PyArray_BroadcastToShape \
+        (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[200])
+#define _PyArray_SigintHandler \
+        (*(void (*)(int)) \
+         PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+        (*(void* (*)(void)) \
+         PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[204])
+#define PyArray_SearchsideConverter \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[205])
+#define PyArray_CheckAxis \
+        (*(PyObject * (*)(PyArrayObject *, int *, int)) \
+         PyArray_API[206])
+#define PyArray_OverflowMultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[207])
+#define PyArray_CompareString \
+        (*(int (*)(char *, char *, size_t)) \
+         PyArray_API[208])
+#define PyArray_MultiIterFromObjects \
+        (*(PyObject * (*)(PyObject **, int, int, ...)) \
+         PyArray_API[209])
+#define PyArray_GetEndianness \
+        (*(int (*)(void)) \
+         PyArray_API[210])
+#define PyArray_GetNDArrayCFeatureVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[211])
+#define PyArray_Correlate2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[212])
+#define PyArray_NeighborhoodIterNew \
+        (*(PyObject* (*)(PyArrayIterObject *, npy_intp *, int, PyArrayObject*)) \
+         PyArray_API[213])
+#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214])
+#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215])
+#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216])
+#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217])
+#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218])
+#define PyArray_SetDatetimeParseFunction \
+        (*(void (*)(PyObject *)) \
+         PyArray_API[219])
+#define PyArray_DatetimeToDatetimeStruct \
+        (*(void (*)(npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[220])
+#define PyArray_TimedeltaToTimedeltaStruct \
+        (*(void (*)(npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[221])
+#define PyArray_DatetimeStructToDatetime \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[222])
+#define PyArray_TimedeltaStructToTimedelta \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[223])
+#define NpyIter_New \
+        (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \
+         PyArray_API[224])
+#define NpyIter_MultiNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \
+         PyArray_API[225])
+#define NpyIter_AdvancedNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \
+         PyArray_API[226])
+#define NpyIter_Copy \
+        (*(NpyIter * (*)(NpyIter *)) \
+         PyArray_API[227])
+#define NpyIter_Deallocate \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[228])
+#define NpyIter_HasDelayedBufAlloc \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[229])
+#define NpyIter_HasExternalLoop \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[230])
+#define NpyIter_EnableExternalLoop \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[231])
+#define NpyIter_GetInnerStrideArray \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[232])
+#define NpyIter_GetInnerLoopSizePtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[233])
+#define NpyIter_Reset \
+        (*(int (*)(NpyIter *, char **)) \
+         PyArray_API[234])
+#define NpyIter_ResetBasePointers \
+        (*(int (*)(NpyIter *, char **, char **)) \
+         PyArray_API[235])
+#define NpyIter_ResetToIterIndexRange \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \
+         PyArray_API[236])
+#define NpyIter_GetNDim \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[237])
+#define NpyIter_GetNOp \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[238])
+#define NpyIter_GetIterNext \
+        (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[239])
+#define NpyIter_GetIterSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[240])
+#define NpyIter_GetIterIndexRange \
+        (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \
+         PyArray_API[241])
+#define NpyIter_GetIterIndex \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[242])
+#define NpyIter_GotoIterIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[243])
+#define NpyIter_HasMultiIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[244])
+#define NpyIter_GetShape \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[245])
+#define NpyIter_GetGetMultiIndex \
+        (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[246])
+#define NpyIter_GotoMultiIndex \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[247])
+#define NpyIter_RemoveMultiIndex \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[248])
+#define NpyIter_HasIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[249])
+#define NpyIter_IsBuffered \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[250])
+#define NpyIter_IsGrowInner \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[251])
+#define NpyIter_GetBufferSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[252])
+#define NpyIter_GetIndexPtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[253])
+#define NpyIter_GotoIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[254])
+#define NpyIter_GetDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[255])
+#define NpyIter_GetDescrArray \
+        (*(PyArray_Descr ** (*)(NpyIter *)) \
+         PyArray_API[256])
+#define NpyIter_GetOperandArray \
+        (*(PyArrayObject ** (*)(NpyIter *)) \
+         PyArray_API[257])
+#define NpyIter_GetIterView \
+        (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \
+         PyArray_API[258])
+#define NpyIter_GetReadFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[259])
+#define NpyIter_GetWriteFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[260])
+#define NpyIter_DebugPrint \
+        (*(void (*)(NpyIter *)) \
+         PyArray_API[261])
+#define NpyIter_IterationNeedsAPI \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[262])
+#define NpyIter_GetInnerFixedStrideArray \
+        (*(void (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[263])
+#define NpyIter_RemoveAxis \
+        (*(int (*)(NpyIter *, int)) \
+         PyArray_API[264])
+#define NpyIter_GetAxisStrideArray \
+        (*(npy_intp * (*)(NpyIter *, int)) \
+         PyArray_API[265])
+#define NpyIter_RequiresBuffering \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[266])
+#define NpyIter_GetInitialDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[267])
+#define NpyIter_CreateCompatibleStrides \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \
+         PyArray_API[268])
+#define PyArray_CastingConverter \
+        (*(int (*)(PyObject *, NPY_CASTING *)) \
+         PyArray_API[269])
+#define PyArray_CountNonzero \
+        (*(npy_intp (*)(PyArrayObject *)) \
+         PyArray_API[270])
+#define PyArray_PromoteTypes \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[271])
+#define PyArray_MinScalarType \
+        (*(PyArray_Descr * (*)(PyArrayObject *)) \
+         PyArray_API[272])
+#define PyArray_ResultType \
+        (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \
+         PyArray_API[273])
+#define PyArray_CanCastArrayTo \
+        (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[274])
+#define PyArray_CanCastTypeTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[275])
+#define PyArray_EinsteinSum \
+        (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \
+         PyArray_API[276])
+#define PyArray_NewLikeArray \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \
+         PyArray_API[277])
+#define PyArray_GetArrayParamsFromObject \
+        (*(int (*)(PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *)) \
+         PyArray_API[278])
+#define PyArray_ConvertClipmodeSequence \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \
+         PyArray_API[279])
+#define PyArray_MatrixProduct2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \
+         PyArray_API[280])
+#define NpyIter_IsFirstVisit \
+        (*(npy_bool (*)(NpyIter *, int)) \
+         PyArray_API[281])
+#define PyArray_SetBaseObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[282])
+#define PyArray_CreateSortedStridePerm \
+        (*(void (*)(int, npy_intp *, npy_stride_sort_item *)) \
+         PyArray_API[283])
+#define PyArray_RemoveAxesInPlace \
+        (*(void (*)(PyArrayObject *, npy_bool *)) \
+         PyArray_API[284])
+#define PyArray_DebugPrint \
+        (*(void (*)(PyArrayObject *)) \
+         PyArray_API[285])
+#define PyArray_FailUnlessWriteable \
+        (*(int (*)(PyArrayObject *, const char *)) \
+         PyArray_API[286])
+#define PyArray_SetUpdateIfCopyBase \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[287])
+#define PyDataMem_NEW \
+        (*(void * (*)(size_t)) \
+         PyArray_API[288])
+#define PyDataMem_FREE \
+        (*(void (*)(void *)) \
+         PyArray_API[289])
+#define PyDataMem_RENEW \
+        (*(void * (*)(void *, size_t)) \
+         PyArray_API[290])
+#define PyDataMem_SetEventHook \
+        (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \
+         PyArray_API[291])
+#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292])
+#define PyArray_MapIterSwapAxes \
+        (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \
+         PyArray_API[293])
+#define PyArray_MapIterArray \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[294])
+#define PyArray_MapIterNext \
+        (*(void (*)(PyArrayMapIterObject *)) \
+         PyArray_API[295])
+#define PyArray_Partition \
+        (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[296])
+#define PyArray_ArgPartition \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[297])
+#define PyArray_SelectkindConverter \
+        (*(int (*)(PyObject *, NPY_SELECTKIND *)) \
+         PyArray_API[298])
+#define PyDataMem_NEW_ZEROED \
+        (*(void * (*)(size_t, size_t)) \
+         PyArray_API[299])
+#define PyArray_CheckAnyScalarExact \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[300])
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
new file mode 100644
index 0000000000..bad86bda54
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
@@ -0,0 +1,320 @@
+
+#ifdef _UMATHMODULE
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndData \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForType \
+       (PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *);
+NPY_NO_EXPORT  int PyUFunc_GenericFunction \
+       (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  void PyUFunc_f_f_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_g_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F_As_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_G_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_gg_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F_As_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_GG_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_On_Om \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_GetPyValues \
+       (char *, int *, int *, PyObject **);
+NPY_NO_EXPORT  int PyUFunc_checkfperr \
+       (int, PyObject *, int *);
+NPY_NO_EXPORT  void PyUFunc_clearfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_getfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_handlefperr \
+       (int, PyObject *, int, int *);
+NPY_NO_EXPORT  int PyUFunc_ReplaceLoopBySignature \
+       (PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *);
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndDataAndSignature \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *);
+NPY_NO_EXPORT  int PyUFunc_SetUsesArraysAsData \
+       (void **, size_t);
+NPY_NO_EXPORT  void PyUFunc_e_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_DefaultTypeResolver \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_ValidateCasting \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForDescr \
+       (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *);
+
+#else
+
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+#else
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+void **PyUFunc_API;
+#else
+static void **PyUFunc_API=NULL;
+#endif
+#endif
+
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+#define PyUFunc_FromFuncAndData \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \
+         PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+        (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *)) \
+         PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+        (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+         PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[4])
+#define PyUFunc_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[5])
+#define PyUFunc_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[6])
+#define PyUFunc_g_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[8])
+#define PyUFunc_F_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[9])
+#define PyUFunc_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[10])
+#define PyUFunc_G_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[11])
+#define PyUFunc_O_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[13])
+#define PyUFunc_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[14])
+#define PyUFunc_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[15])
+#define PyUFunc_gg_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[17])
+#define PyUFunc_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[18])
+#define PyUFunc_FF_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[19])
+#define PyUFunc_GG_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[20])
+#define PyUFunc_OO_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[23])
+#define PyUFunc_On_Om \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+        (*(int (*)(char *, int *, int *, PyObject **)) \
+         PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+        (*(int (*)(int, PyObject *, int *)) \
+         PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+        (*(void (*)(void)) \
+         PyUFunc_API[27])
+#define PyUFunc_getfperr \
+        (*(int (*)(void)) \
+         PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+        (*(int (*)(int, PyObject *, int, int *)) \
+         PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+        (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)) \
+         PyUFunc_API[30])
+#define PyUFunc_FromFuncAndDataAndSignature \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \
+         PyUFunc_API[31])
+#define PyUFunc_SetUsesArraysAsData \
+        (*(int (*)(void **, size_t)) \
+         PyUFunc_API[32])
+#define PyUFunc_e_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[33])
+#define PyUFunc_e_e_As_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[34])
+#define PyUFunc_e_e_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[35])
+#define PyUFunc_ee_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[36])
+#define PyUFunc_ee_e_As_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[37])
+#define PyUFunc_ee_e_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[38])
+#define PyUFunc_DefaultTypeResolver \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \
+         PyUFunc_API[39])
+#define PyUFunc_ValidateCasting \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \
+         PyUFunc_API[40])
+#define PyUFunc_RegisterLoopForDescr \
+        (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \
+         PyUFunc_API[41])
+
+static NPY_INLINE int
+_import_umath(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyUFunc_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
+      return -1;
+  }
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_UMATH_RETVAL NULL
+#else
+#define NUMPY_IMPORT_UMATH_RETVAL
+#endif
+
+#define import_umath() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return NUMPY_IMPORT_UMATH_RETVAL;\
+        }\
+    } while(0)
+
+#define import_umath1(ret) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_umath2(ret, msg) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError, msg);\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_ufunc() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+        }\
+    } while(0)
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
new file mode 100644
index 0000000000..e8860cbc73
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
@@ -0,0 +1,90 @@
+#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#error You should not include this header directly
+#endif
+/*
+ * Private API (here for inline)
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter);
+
+/*
+ * Update to next item of the iterator
+ *
+ * Note: this simply increment the coordinates vector, last dimension
+ * incremented first , i.e, for dimension 3
+ * ...
+ * -1, -1, -1
+ * -1, -1,  0
+ * -1, -1,  1
+ *  ....
+ * -1,  0, -1
+ * -1,  0,  0
+ *  ....
+ * 0,  -1, -1
+ * 0,  -1,  0
+ *  ....
+ */
+#define _UPDATE_COORD_ITER(c) \
+    wb = iter->coordinates[c] < iter->bounds[c][1]; \
+    if (wb) { \
+        iter->coordinates[c] += 1; \
+        return 0; \
+    } \
+    else { \
+        iter->coordinates[c] = iter->bounds[c][0]; \
+    }
+
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i, wb;
+
+    for (i = iter->nd - 1; i >= 0; --i) {
+        _UPDATE_COORD_ITER(i)
+    }
+
+    return 0;
+}
+
+/*
+ * Version optimized for 2d arrays, manual loop unrolling
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp wb;
+
+    _UPDATE_COORD_ITER(1)
+    _UPDATE_COORD_ITER(0)
+
+    return 0;
+}
+#undef _UPDATE_COORD_ITER
+
+/*
+ * Advance to the next neighbour
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter)
+{
+    _PyArrayNeighborhoodIter_IncrCoord (iter);
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
+
+/*
+ * Reset functions
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i;
+
+    for (i = 0; i < iter->nd; ++i) {
+        iter->coordinates[i] = iter->bounds[i][0];
+    }
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
new file mode 100644
index 0000000000..f12aafb587
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
@@ -0,0 +1,31 @@
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_FLOAT 4
+#define NPY_SIZEOF_COMPLEX_FLOAT 8
+#define NPY_SIZEOF_DOUBLE 8
+#define NPY_SIZEOF_COMPLEX_DOUBLE 16
+#define NPY_SIZEOF_LONGDOUBLE 12
+#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 24
+#define NPY_SIZEOF_PY_INTPTR_T 4
+#define NPY_SIZEOF_OFF_T 4
+#define NPY_SIZEOF_PY_LONG_LONG 8
+#define NPY_SIZEOF_LONGLONG 8
+#define NPY_NO_SIGNAL 1
+#define NPY_NO_SMP 0
+#define NPY_HAVE_DECL_ISNAN
+#define NPY_HAVE_DECL_ISINF
+#define NPY_HAVE_DECL_ISFINITE
+#define NPY_HAVE_DECL_SIGNBIT
+#define NPY_USE_C99_COMPLEX 1
+#define NPY_HAVE_COMPLEX_DOUBLE 1
+#define NPY_HAVE_COMPLEX_FLOAT 1
+#define NPY_HAVE_COMPLEX_LONG_DOUBLE 1
+#define NPY_USE_C99_FORMATS 1
+#define NPY_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#define NPY_ABI_VERSION 0x01000009
+#define NPY_API_VERSION 0x0000000A
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
new file mode 100644
index 0000000000..4f46d6b1ac
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
@@ -0,0 +1,11 @@
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
new file mode 100644
index 0000000000..64450e7132
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
@@ -0,0 +1,175 @@
+#ifndef _NPY_ARRAYSCALARS_H_
+#define _NPY_ARRAYSCALARS_H_
+
+#ifndef _MULTIARRAYMODULE
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+#endif
+
+
+typedef struct {
+        PyObject_HEAD
+        signed char obval;
+} PyByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        short obval;
+} PyShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        int obval;
+} PyIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        long obval;
+} PyLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longlong obval;
+} PyLongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned char obval;
+} PyUByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned short obval;
+} PyUShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned int obval;
+} PyUIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned long obval;
+} PyULongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_ulonglong obval;
+} PyULongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_half obval;
+} PyHalfScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        float obval;
+} PyFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        double obval;
+} PyDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longdouble obval;
+} PyLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cfloat obval;
+} PyCFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cdouble obval;
+} PyCDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        PyObject * obval;
+} PyObjectScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_datetime obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyDatetimeScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_timedelta obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyTimedeltaScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        char obval;
+} PyScalarObject;
+
+#define PyStringScalarObject PyStringObject
+#define PyUnicodeScalarObject PyUnicodeObject
+
+typedef struct {
+        PyObject_VAR_HEAD
+        char *obval;
+        PyArray_Descr *descr;
+        int flags;
+        PyObject *base;
+} PyVoidScalarObject;
+
+/* Macros
+     Py<Cls><bitsize>ScalarObject
+     Py<Cls><bitsize>ArrType_Type
+   are defined in ndarrayobject.h
+*/
+
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+        ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i)                  \
+        return Py_INCREF(PyArrayScalar_FromLong(i)), \
+                PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE              \
+        return Py_INCREF(PyArrayScalar_False),  \
+                PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE               \
+        return Py_INCREF(PyArrayScalar_True),   \
+                PyArrayScalar_True
+
+#define PyArrayScalar_New(cls) \
+        Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls)             \
+        ((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+        PyArrayScalar_VAL(obj, cls) = val
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
new file mode 100644
index 0000000000..ab0d221fb4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
@@ -0,0 +1,70 @@
+#ifndef __NPY_HALFFLOAT_H__
+#define __NPY_HALFFLOAT_H__
+
+#include <Python.h>
+#include <numpy/npy_math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Half-precision routines
+ */
+
+/* Conversions */
+float npy_half_to_float(npy_half h);
+double npy_half_to_double(npy_half h);
+npy_half npy_float_to_half(float f);
+npy_half npy_double_to_half(double d);
+/* Comparisons */
+int npy_half_eq(npy_half h1, npy_half h2);
+int npy_half_ne(npy_half h1, npy_half h2);
+int npy_half_le(npy_half h1, npy_half h2);
+int npy_half_lt(npy_half h1, npy_half h2);
+int npy_half_ge(npy_half h1, npy_half h2);
+int npy_half_gt(npy_half h1, npy_half h2);
+/* faster *_nonan variants for when you know h1 and h2 are not NaN */
+int npy_half_eq_nonan(npy_half h1, npy_half h2);
+int npy_half_lt_nonan(npy_half h1, npy_half h2);
+int npy_half_le_nonan(npy_half h1, npy_half h2);
+/* Miscellaneous functions */
+int npy_half_iszero(npy_half h);
+int npy_half_isnan(npy_half h);
+int npy_half_isinf(npy_half h);
+int npy_half_isfinite(npy_half h);
+int npy_half_signbit(npy_half h);
+npy_half npy_half_copysign(npy_half x, npy_half y);
+npy_half npy_half_spacing(npy_half h);
+npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
+
+/*
+ * Half-precision constants
+ */
+
+#define NPY_HALF_ZERO   (0x0000u)
+#define NPY_HALF_PZERO  (0x0000u)
+#define NPY_HALF_NZERO  (0x8000u)
+#define NPY_HALF_ONE    (0x3c00u)
+#define NPY_HALF_NEGONE (0xbc00u)
+#define NPY_HALF_PINF   (0x7c00u)
+#define NPY_HALF_NINF   (0xfc00u)
+#define NPY_HALF_NAN    (0x7e00u)
+
+#define NPY_MAX_HALF    (0x7bffu)
+
+/*
+ * Bit-level conversions
+ */
+
+npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f);
+npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d);
+npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h);
+npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
new file mode 100644
index 0000000000..3a0683da3c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
@@ -0,0 +1,2449 @@
+
+===========
+Numpy C-API
+===========
+::
+
+  unsigned int
+  PyArray_GetNDArrayCVersion(void )
+
+
+Included at the very first so not auto-grabbed and thus not labeled.
+
+::
+
+  int
+  PyArray_SetNumericOps(PyObject *dict)
+
+Set internal structure with number functions that all arrays will use
+
+::
+
+  PyObject *
+  PyArray_GetNumericOps(void )
+
+Get dictionary showing number functions that all arrays will use
+
+::
+
+  int
+  PyArray_INCREF(PyArrayObject *mp)
+
+For object arrays, increment all internal references.
+
+::
+
+  int
+  PyArray_XDECREF(PyArrayObject *mp)
+
+Decrement all internal references for object arrays.
+(or arrays with object fields)
+
+::
+
+  void
+  PyArray_SetStringFunction(PyObject *op, int repr)
+
+Set the array print function to be a Python function.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromType(int type)
+
+Get the PyArray_Descr structure for a type.
+
+::
+
+  PyObject *
+  PyArray_TypeObjectFromType(int type)
+
+Get a typeobject from a type-number -- can return NULL.
+
+New reference
+
+::
+
+  char *
+  PyArray_Zero(PyArrayObject *arr)
+
+Get pointer to zero of correct type for array.
+
+::
+
+  char *
+  PyArray_One(PyArrayObject *arr)
+
+Get pointer to one of correct type for array
+
+::
+
+  PyObject *
+  PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int
+                     is_f_order)
+
+For backward compatibility
+
+Cast an array using typecode structure.
+steals reference to dtype --- cannot be NULL
+
+This function always makes a copy of arr, even if the dtype
+doesn't change.
+
+::
+
+  int
+  PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.
+
+::
+
+  int
+  PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.  Arrays don't have to be "broadcastable"
+Only requirement is they have the same number of elements.
+
+::
+
+  int
+  PyArray_CanCastSafely(int fromtype, int totype)
+
+Check the type coercion rules.
+
+::
+
+  npy_bool
+  PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
+
+leaves reference count alone --- cannot be NULL
+
+PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
+parameter.
+
+::
+
+  int
+  PyArray_ObjectType(PyObject *op, int minimum_type)
+
+Return the typecode of the array a Python object would be converted to
+
+Returns the type number the result should have, or NPY_NOTYPE on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
+
+new reference -- accepts NULL for mintype
+
+::
+
+  PyArrayObject **
+  PyArray_ConvertToCommonType(PyObject *op, int *retn)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromScalar(PyObject *sc)
+
+Return descr object from array scalar.
+
+New reference
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromTypeObject(PyObject *type)
+
+
+::
+
+  npy_intp
+  PyArray_Size(PyObject *op)
+
+Compute the size of an array (in number of items)
+
+::
+
+  PyObject *
+  PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
+
+Get scalar-equivalent to a region of memory described by a descriptor.
+
+::
+
+  PyObject *
+  PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
+
+Get 0-dim array from scalar
+
+0-dim array from array-scalar object
+always contains a copy of the data
+unless outcode is NULL, it is of void type and the referrer does
+not own it either.
+
+steals reference to outcode
+
+::
+
+  void
+  PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
+
+Convert to c-type
+
+no error checking is performed -- ctypeptr must be same type as scalar
+in case of flexible type, the data is not copied
+into ctypeptr which is expected to be a pointer to pointer
+
+::
+
+  int
+  PyArray_CastScalarToCtype(PyObject *scalar, void
+                            *ctypeptr, PyArray_Descr *outcode)
+
+Cast Scalar to c-type
+
+The output buffer must be large-enough to receive the value
+Even for flexible types which is different from ScalarAsCtype
+where only a reference for flexible types is returned
+
+This may not work right on narrow builds for NumPy unicode scalars.
+
+::
+
+  int
+  PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr
+                           *indescr, void *ctypeptr, int outtype)
+
+Cast Scalar to c-type
+
+::
+
+  PyObject *
+  PyArray_ScalarFromObject(PyObject *object)
+
+Get an Array Scalar From a Python Object
+
+Returns NULL if unsuccessful but error is only set if another error occurred.
+Currently only Numeric-like object supported.
+
+::
+
+  PyArray_VectorUnaryFunc *
+  PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
+
+Get a cast function to cast from the input descriptor to the
+output type_number (must be a registered data-type).
+Returns NULL if un-successful.
+
+::
+
+  PyObject *
+  PyArray_FromDims(int nd, int *d, int type)
+
+Construct an empty array from dimensions and typenum
+
+::
+
+  PyObject *
+  PyArray_FromDimsAndDataAndDescr(int nd, int *d, PyArray_Descr
+                                  *descr, char *data)
+
+Like FromDimsAndData but uses the Descr structure instead of typecode
+as input.
+
+::
+
+  PyObject *
+  PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int
+                  min_depth, int max_depth, int flags, PyObject
+                  *context)
+
+Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
+Steals a reference to newtype --- which can be NULL
+
+::
+
+  PyObject *
+  PyArray_EnsureArray(PyObject *op)
+
+This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY)
+that special cases Arrays and PyArray_Scalars up front
+It *steals a reference* to the object
+It also guarantees that the result is PyArray_Type
+Because it decrefs op if any conversion needs to take place
+so it can be used like PyArray_EnsureArray(some_function(...))
+
+::
+
+  PyObject *
+  PyArray_EnsureAnyArray(PyObject *op)
+
+
+::
+
+  PyObject *
+  PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char
+                   *sep)
+
+
+Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
+array corresponding to the data encoded in that file.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+For memory-mapped files, use the buffer interface. No more data than
+necessary is read by this routine.
+
+::
+
+  PyObject *
+  PyArray_FromString(char *data, npy_intp slen, PyArray_Descr
+                     *dtype, npy_intp num, char *sep)
+
+
+Given a pointer to a string ``data``, a string length ``slen``, and
+a ``PyArray_Descr``, return an array corresponding to the data
+encoded in that string.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+If ``slen`` is < 0, then the end of string is used for text data.
+It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs
+would be the norm).
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+::
+
+  PyObject *
+  PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp
+                     count, npy_intp offset)
+
+
+::
+
+  PyObject *
+  PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count)
+
+
+steals a reference to dtype (which cannot be NULL)
+
+::
+
+  PyObject *
+  PyArray_Return(PyArrayObject *mp)
+
+
+Return either an array or the appropriate Python object if the array
+is 0d and matches a Python type.
+steals reference to mp
+
+::
+
+  PyObject *
+  PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int
+                   offset)
+
+Get a subset of bytes from each element of the array
+steals reference to typed, must not be NULL
+
+::
+
+  int
+  PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int
+                   offset, PyObject *val)
+
+Set a subset of bytes from each element of the array
+steals reference to dtype, must not be NULL
+
+::
+
+  PyObject *
+  PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)
+
+
+::
+
+  PyObject *
+  PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int
+                 refcheck, NPY_ORDER order)
+
+Resize (reallocate data).  Only works if nothing else is referencing this
+array and it is contiguous.  If refcheck is 0, then the reference count is
+not checked and assumed to be 1.  You still must own this data and have no
+weak-references and no base object.
+
+::
+
+  int
+  PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src)
+
+Move the memory of one array into another, allowing for overlapping data.
+
+Returns 0 on success, negative on failure.
+
+::
+
+  int
+  PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array.
+Broadcast to the destination shape if necessary.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  int
+  PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array -- memory must not overlap
+Does not require src and dest to have "broadcastable" shapes
+(only the same number of elements).
+
+TODO: For NumPy 2.0, this could accept an order parameter which
+only allows NPY_CORDER and NPY_FORDER.  Could also rename
+this to CopyAsFlat to make the name more intuitive.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
+
+
+::
+
+  PyObject *
+  PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order)
+
+Copy an array.
+
+::
+
+  PyObject *
+  PyArray_ToList(PyArrayObject *self)
+
+To List
+
+::
+
+  PyObject *
+  PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
+
+
+::
+
+  int
+  PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
+
+To File
+
+::
+
+  int
+  PyArray_Dump(PyObject *self, PyObject *file, int protocol)
+
+
+::
+
+  PyObject *
+  PyArray_Dumps(PyObject *self, int protocol)
+
+
+::
+
+  int
+  PyArray_ValidType(int type)
+
+Is the typenum valid?
+
+::
+
+  void
+  PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
+
+Update Several Flags at once.
+
+::
+
+  PyObject *
+  PyArray_New(PyTypeObject *subtype, int nd, npy_intp *dims, int
+              type_num, npy_intp *strides, void *data, int itemsize, int
+              flags, PyObject *obj)
+
+Generic new array creation routine.
+
+::
+
+  PyObject *
+  PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int
+                       nd, npy_intp *dims, npy_intp *strides, void
+                       *data, int flags, PyObject *obj)
+
+Generic new array creation routine.
+
+steals a reference to descr (even on failure)
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNew(PyArray_Descr *base)
+
+base cannot be NULL
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewFromType(int type_num)
+
+
+::
+
+  double
+  PyArray_GetPriority(PyObject *obj, double default_)
+
+Get Priority from object
+
+::
+
+  PyObject *
+  PyArray_IterNew(PyObject *obj)
+
+Get Iterator.
+
+::
+
+  PyObject *
+  PyArray_MultiIterNew(int n, ... )
+
+Get MultiIterator,
+
+::
+
+  int
+  PyArray_PyIntAsInt(PyObject *o)
+
+
+::
+
+  npy_intp
+  PyArray_PyIntAsIntp(PyObject *o)
+
+
+::
+
+  int
+  PyArray_Broadcast(PyArrayMultiIterObject *mit)
+
+
+::
+
+  void
+  PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
+
+Assumes contiguous
+
+::
+
+  int
+  PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
+
+
+::
+
+  npy_bool
+  PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp
+                       offset, npy_intp *dims, npy_intp *newstrides)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+
+
+returns a copy of the PyArray_Descr structure with the byteorder
+altered:
+no arguments:  The byteorder is swapped (in all subfields as well)
+single argument:  The byteorder is forced to the given state
+(in all subfields as well)
+
+Valid states:  ('big', '>') or ('little' or '<')
+('native', or '=')
+
+If a descr structure with | is encountered it's own
+byte-order is not changed but any fields are:
+
+
+Deep bytorder change of a data-type descriptor
+Leaves reference count of self unchanged --- does not DECREF self ***
+
+::
+
+  PyObject *
+  PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
+
+Get Iterator that iterates over all but one axis (don't use this with
+PyArray_ITER_GOTO1D).  The axis will be over-written if negative
+with the axis having the smallest stride.
+
+::
+
+  PyObject *
+  PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int
+                       min_depth, int max_depth, int requires, PyObject
+                       *context)
+
+steals a reference to descr -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int
+                    flags)
+
+steals reference to newtype --- acc. NULL
+
+::
+
+  PyObject *
+  PyArray_FromInterface(PyObject *origin)
+
+
+::
+
+  PyObject *
+  PyArray_FromStructInterface(PyObject *input)
+
+
+::
+
+  PyObject *
+  PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject
+                        *context)
+
+
+::
+
+  NPY_SCALARKIND
+  PyArray_ScalarKind(int typenum, PyArrayObject **arr)
+
+ScalarKind
+
+Returns the scalar kind of a type number, with an
+optional tweak based on the scalar value itself.
+If no scalar is provided, it returns INTPOS_SCALAR
+for both signed and unsigned integers, otherwise
+it checks the sign of any signed integer to choose
+INTNEG_SCALAR when appropriate.
+
+::
+
+  int
+  PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND
+                          scalar)
+
+
+Determines whether the data type 'thistype', with
+scalar kind 'scalar', can be coerced into 'neededtype'.
+
+::
+
+  PyObject *
+  PyArray_NewFlagsObject(PyObject *obj)
+
+
+Get New ArrayFlagsObject
+
+::
+
+  npy_bool
+  PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
+
+See if array scalars can be cast.
+
+TODO: For NumPy 2.0, add a NPY_CASTING parameter.
+
+::
+
+  int
+  PyArray_CompareUCS4(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
+
+
+::
+
+  int
+  PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
+
+Adjusts previously broadcasted iterators so that the axis with
+the smallest sum of iterator strides is not iterated over.
+Returns dimension which is smallest in the range [0,multi->nd).
+A -1 is returned if multi->nd == 0.
+
+don't use with PyArray_ITER_GOTO1D because factors are not adjusted
+
+::
+
+  int
+  PyArray_ElementStrides(PyObject *obj)
+
+
+::
+
+  void
+  PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  void
+  PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  PyObject *
+  PyArray_FieldNames(PyObject *fields)
+
+Return the tuple of ordered field names from a dictionary.
+
+::
+
+  PyObject *
+  PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
+
+Return Transpose.
+
+::
+
+  PyObject *
+  PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int
+                   axis, PyArrayObject *out, NPY_CLIPMODE clipmode)
+
+Take
+
+::
+
+  PyObject *
+  PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject
+                *indices0, NPY_CLIPMODE clipmode)
+
+Put values into an array
+
+::
+
+  PyObject *
+  PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0)
+
+Put values into an array according to a mask.
+
+::
+
+  PyObject *
+  PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis)
+
+Repeat the array.
+
+::
+
+  PyObject *
+  PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject
+                 *out, NPY_CLIPMODE clipmode)
+
+
+::
+
+  int
+  PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+Sort an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+ArgSort an array
+
+::
+
+  PyObject *
+  PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE
+                       side, PyObject *perm)
+
+
+Search the sorted array op1 for the location of the items in op2. The
+result is an array of indexes, one for each element in op2, such that if
+the item were to be inserted in op1 just before that index the array
+would still be in sorted order.
+
+Parameters
+----------
+op1 : PyArrayObject *
+Array to be searched, must be 1-D.
+op2 : PyObject *
+Array of items whose insertion indexes in op1 are wanted
+side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT}
+If NPY_SEARCHLEFT, return first valid insertion indexes
+If NPY_SEARCHRIGHT, return last valid insertion indexes
+perm : PyObject *
+Permutation array that sorts op1 (optional)
+
+Returns
+-------
+ret : PyObject *
+New reference to npy_intp array containing indexes where items in op2
+could be validly inserted into op1. NULL on error.
+
+Notes
+-----
+Binary search is used to find the indexes.
+
+::
+
+  PyObject *
+  PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMax
+
+::
+
+  PyObject *
+  PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMin
+
+::
+
+  PyObject *
+  PyArray_Reshape(PyArrayObject *self, PyObject *shape)
+
+Reshape
+
+::
+
+  PyObject *
+  PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER
+                   order)
+
+New shape for an array
+
+::
+
+  PyObject *
+  PyArray_Squeeze(PyArrayObject *self)
+
+
+return a new view of the array object with all of its unit-length
+dimensions squeezed out if needed, otherwise
+return the same array.
+
+::
+
+  PyObject *
+  PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject
+               *pytype)
+
+View
+steals a reference to type -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2)
+
+SwapAxes
+
+::
+
+  PyObject *
+  PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Max
+
+::
+
+  PyObject *
+  PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Min
+
+::
+
+  PyObject *
+  PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Ptp
+
+::
+
+  PyObject *
+  PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Mean
+
+::
+
+  PyObject *
+  PyArray_Trace(PyArrayObject *self, int offset, int axis1, int
+                axis2, int rtype, PyArrayObject *out)
+
+Trace
+
+::
+
+  PyObject *
+  PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int
+                   axis2)
+
+Diagonal
+
+In NumPy versions prior to 1.7,  this function always returned a copy of
+the diagonal array. In 1.7, the code has been updated to compute a view
+onto 'self', but it still copies this array before returning, as well as
+setting the internal WARN_ON_WRITE flag. In a future version, it will
+simply return a view onto self.
+
+::
+
+  PyObject *
+  PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject
+               *max, PyArrayObject *out)
+
+Clip
+
+::
+
+  PyObject *
+  PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
+
+Conjugate
+
+::
+
+  PyObject *
+  PyArray_Nonzero(PyArrayObject *self)
+
+Nonzero
+
+TODO: In NumPy 2.0, should make the iteration order a parameter.
+
+::
+
+  PyObject *
+  PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out, int variance)
+
+Set variance to 1 to by-pass square-root calculation and return variance
+Std
+
+::
+
+  PyObject *
+  PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out)
+
+Sum
+
+::
+
+  PyObject *
+  PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+                 *out)
+
+CumSum
+
+::
+
+  PyObject *
+  PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Prod
+
+::
+
+  PyObject *
+  PyArray_CumProd(PyArrayObject *self, int axis, int
+                  rtype, PyArrayObject *out)
+
+CumProd
+
+::
+
+  PyObject *
+  PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)
+
+All
+
+::
+
+  PyObject *
+  PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)
+
+Any
+
+::
+
+  PyObject *
+  PyArray_Compress(PyArrayObject *self, PyObject *condition, int
+                   axis, PyArrayObject *out)
+
+Compress
+
+::
+
+  PyObject *
+  PyArray_Flatten(PyArrayObject *a, NPY_ORDER order)
+
+Flatten
+
+::
+
+  PyObject *
+  PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order)
+
+Ravel
+Returns a contiguous array
+
+::
+
+  npy_intp
+  PyArray_MultiplyList(npy_intp *l1, int n)
+
+Multiply a List
+
+::
+
+  int
+  PyArray_MultiplyIntList(int *l1, int n)
+
+Multiply a List of ints
+
+::
+
+  void *
+  PyArray_GetPtr(PyArrayObject *obj, npy_intp*ind)
+
+Produce a pointer into array
+
+::
+
+  int
+  PyArray_CompareLists(npy_intp *l1, npy_intp *l2, int n)
+
+Compare Lists
+
+::
+
+  int
+  PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int
+                   nd, PyArray_Descr*typedescr)
+
+Simulate a C-array
+steals a reference to typedescr -- can be NULL
+
+::
+
+  int
+  PyArray_As1D(PyObject **op, char **ptr, int *d1, int typecode)
+
+Convert to a 1D C-array
+
+::
+
+  int
+  PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, int
+               typecode)
+
+Convert to a 2D C-array
+
+::
+
+  int
+  PyArray_Free(PyObject *op, void *ptr)
+
+Free pointers created if As2D is called
+
+::
+
+  int
+  PyArray_Converter(PyObject *object, PyObject **address)
+
+
+Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
+
+This conversion function can be used with the "O&" argument for
+PyArg_ParseTuple.  It will immediately return an object of array type
+or will convert to a NPY_ARRAY_CARRAY any other object.
+
+If you use PyArray_Converter, you must DECREF the array when finished
+as you get a new reference to it.
+
+::
+
+  int
+  PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
+
+PyArray_IntpFromSequence
+Returns the number of integers converted or -1 if an error occurred.
+vals must be large enough to hold maxvals
+
+::
+
+  PyObject *
+  PyArray_Concatenate(PyObject *op, int axis)
+
+Concatenate
+
+Concatenate an arbitrary Python sequence into an array.
+op is a python object supporting the sequence interface.
+Its elements will be concatenated together to form a single
+multidimensional array. If axis is NPY_MAXDIMS or bigger, then
+each sequence object will be flattened before concatenation
+
+::
+
+  PyObject *
+  PyArray_InnerProduct(PyObject *op1, PyObject *op2)
+
+Numeric.innerproduct(a,v)
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct(PyObject *op1, PyObject *op2)
+
+Numeric.matrixproduct(a,v)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  PyObject *
+  PyArray_CopyAndTranspose(PyObject *op)
+
+Copy and Transpose
+
+Could deprecate this function, as there isn't a speed benefit over
+calling Transpose and then Copy.
+
+::
+
+  PyObject *
+  PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
+
+Numeric.correlate(a1,a2,mode)
+
+::
+
+  int
+  PyArray_TypestrConvert(int itemsize, int gentype)
+
+Typestr converter
+
+::
+
+  int
+  PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
+This function takes a Python object representing a type and converts it
+to a the correct PyArray_Descr * structure to describe the type.
+
+Many objects can be used to represent a data-type which in NumPy is
+quite a flexible concept.
+
+This is the central code that converts Python objects to
+Type-descriptor objects that are used throughout numpy.
+
+Returns a new reference in *at, but the returned should not be
+modified as it may be one of the canonical immutable objects or
+a reference to the input obj.
+
+::
+
+  int
+  PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NULL
+
+::
+
+  int
+  PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)
+
+Get intp chunk from sequence
+
+This function takes a Python sequence object and allocates and
+fills in an intp array with the converted values.
+
+Remember to free the pointer seq.ptr when done using
+PyDimMem_FREE(seq.ptr)**
+
+::
+
+  int
+  PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
+
+Get buffer chunk from object
+
+this function takes a Python object which exposes the (single-segment)
+buffer interface and returns a pointer to the data segment
+
+You should increment the reference count by one of buf->base
+if you will hang on to a reference
+
+You only get a borrowed reference to the object. Do not free the
+memory...
+
+::
+
+  int
+  PyArray_AxisConverter(PyObject *obj, int *axis)
+
+Get axis from an object (possibly None) -- a converter function,
+
+See also PyArray_ConvertMultiAxis, which also handles a tuple of axes.
+
+::
+
+  int
+  PyArray_BoolConverter(PyObject *object, npy_bool *val)
+
+Convert an object to true / false
+
+::
+
+  int
+  PyArray_ByteorderConverter(PyObject *obj, char *endian)
+
+Convert object to endian
+
+::
+
+  int
+  PyArray_OrderConverter(PyObject *object, NPY_ORDER *val)
+
+Convert an object to FORTRAN / C / ANY / KEEP
+
+::
+
+  unsigned char
+  PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+
+This function returns true if the two typecodes are
+equivalent (same basic kind and same itemsize).
+
+::
+
+  PyObject *
+  PyArray_Zeros(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Zeros
+
+steal a reference
+accepts NULL type
+
+::
+
+  PyObject *
+  PyArray_Empty(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Empty
+
+accepts NULL type
+steals referenct to type
+
+::
+
+  PyObject *
+  PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)
+
+Where
+
+::
+
+  PyObject *
+  PyArray_Arange(double start, double stop, double step, int type_num)
+
+Arange,
+
+::
+
+  PyObject *
+  PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject
+                    *step, PyArray_Descr *dtype)
+
+
+ArangeObj,
+
+this doesn't change the references
+
+::
+
+  int
+  PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
+
+Convert object to sort kind
+
+::
+
+  PyObject *
+  PyArray_LexSort(PyObject *sort_keys, int axis)
+
+LexSort an array providing indices that will sort a collection of arrays
+lexicographically.  The first key is sorted on first, followed by the second key
+-- requires that arg"merge"sort is available for each sort_key
+
+Returns an index array that shows the indexes for the lexicographic sort along
+the given axis.
+
+::
+
+  PyObject *
+  PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out)
+
+Round
+
+::
+
+  unsigned char
+  PyArray_EquivTypenums(int typenum1, int typenum2)
+
+
+::
+
+  int
+  PyArray_RegisterDataType(PyArray_Descr *descr)
+
+Register Data type
+Does not change the reference count of descr
+
+::
+
+  int
+  PyArray_RegisterCastFunc(PyArray_Descr *descr, int
+                           totype, PyArray_VectorUnaryFunc *castfunc)
+
+Register Casting Function
+Replaces any function currently stored.
+
+::
+
+  int
+  PyArray_RegisterCanCast(PyArray_Descr *descr, int
+                          totype, NPY_SCALARKIND scalar)
+
+Register a type number indicating that a descriptor can be cast
+to it safely
+
+::
+
+  void
+  PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
+
+Initialize arrfuncs to NULL
+
+::
+
+  PyObject *
+  PyArray_IntTupleFromIntp(int len, npy_intp *vals)
+
+PyArray_IntTupleFromIntp
+
+::
+
+  int
+  PyArray_TypeNumFromName(char *str)
+
+
+::
+
+  int
+  PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)
+
+Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP
+
+::
+
+  int
+  PyArray_OutputConverter(PyObject *object, PyArrayObject **address)
+
+Useful to pass as converter function for O& processing in
+PyArgs_ParseTuple for output arrays
+
+::
+
+  PyObject *
+  PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd)
+
+Get Iterator broadcast to a particular shape
+
+::
+
+  void
+  _PyArray_SigintHandler(int signum)
+
+
+::
+
+  void*
+  _PyArray_GetSigintBuf(void )
+
+
+::
+
+  int
+  PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to DEFAULT type.
+
+any object with the .fields attribute and/or .itemsize attribute (if the
+.fields attribute does not give the total size -- i.e. a partial record
+naming).  If itemsize is given it must be >= size computed from fields
+
+The .fields attribute must return a convertible dictionary if present.
+Result inherits from NPY_VOID.
+
+::
+
+  int
+  PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to NULL.
+
+::
+
+  int
+  PyArray_SearchsideConverter(PyObject *obj, void *addr)
+
+Convert object to searchsorted side
+
+::
+
+  PyObject *
+  PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
+
+PyArray_CheckAxis
+
+check that axis is valid
+convert 0-d arrays to 1-d arrays
+
+::
+
+  npy_intp
+  PyArray_OverflowMultiplyList(npy_intp *l1, int n)
+
+Multiply a List of Non-negative numbers with over-flow detection.
+
+::
+
+  int
+  PyArray_CompareString(char *s1, char *s2, size_t len)
+
+
+::
+
+  PyObject *
+  PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... )
+
+Get MultiIterator from array of Python objects and any additional
+
+PyObject **mps -- array of PyObjects
+int n - number of PyObjects in the array
+int nadd - number of additional arrays to include in the iterator.
+
+Returns a multi-iterator object.
+
+::
+
+  int
+  PyArray_GetEndianness(void )
+
+
+::
+
+  unsigned int
+  PyArray_GetNDArrayCFeatureVersion(void )
+
+Returns the built-in (at compilation time) C API version
+
+::
+
+  PyObject *
+  PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)
+
+correlate(a1,a2,mode)
+
+This function computes the usual correlation (correlate(a1, a2) !=
+correlate(a2, a1), and conjugate the second argument for complex inputs
+
+::
+
+  PyObject*
+  PyArray_NeighborhoodIterNew(PyArrayIterObject *x, npy_intp
+                              *bounds, int mode, PyArrayObject*fill)
+
+A Neighborhood Iterator object.
+
+::
+
+  void
+  PyArray_SetDatetimeParseFunction(PyObject *op)
+
+This function is scheduled to be removed
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *result)
+
+Fill the datetime struct from the value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_TimedeltaToTimedeltaStruct(npy_timedelta val, NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *result)
+
+Fill the timedelta struct from the timedelta value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *d)
+
+Create a datetime value from a filled datetime struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *d)
+
+Create a timdelta value from a filled timedelta struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  NpyIter *
+  NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER
+              order, NPY_CASTING casting, PyArray_Descr*dtype)
+
+Allocate a new iterator for one array object.
+
+::
+
+  NpyIter *
+  NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32
+                   flags, NPY_ORDER order, NPY_CASTING
+                   casting, npy_uint32 *op_flags, PyArray_Descr
+                   **op_request_dtypes)
+
+Allocate a new iterator for more than one array object, using
+standard NumPy broadcasting rules and the default buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32
+                      flags, NPY_ORDER order, NPY_CASTING
+                      casting, npy_uint32 *op_flags, PyArray_Descr
+                      **op_request_dtypes, int oa_ndim, int
+                      **op_axes, npy_intp *itershape, npy_intp
+                      buffersize)
+
+Allocate a new iterator for multiple array objects, and advanced
+options for controlling the broadcasting, shape, and buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_Copy(NpyIter *iter)
+
+Makes a copy of the iterator
+
+::
+
+  int
+  NpyIter_Deallocate(NpyIter *iter)
+
+Deallocate an iterator
+
+::
+
+  npy_bool
+  NpyIter_HasDelayedBufAlloc(NpyIter *iter)
+
+Whether the buffer allocation is being delayed
+
+::
+
+  npy_bool
+  NpyIter_HasExternalLoop(NpyIter *iter)
+
+Whether the iterator handles the inner loop
+
+::
+
+  int
+  NpyIter_EnableExternalLoop(NpyIter *iter)
+
+Removes the inner loop handling (so HasExternalLoop returns true)
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerStrideArray(NpyIter *iter)
+
+Get the array of strides for the inner loop (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerLoopSizePtr(NpyIter *iter)
+
+Get a pointer to the size of the inner loop  (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_Reset(NpyIter *iter, char **errmsg)
+
+Resets the iterator to its initial state
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char
+                            **errmsg)
+
+Resets the iterator to its initial state, with new base data pointers.
+This function requires great caution.
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp
+                                iend, char **errmsg)
+
+Resets the iterator to a new iterator index range
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GetNDim(NpyIter *iter)
+
+Gets the number of dimensions being iterated
+
+::
+
+  int
+  NpyIter_GetNOp(NpyIter *iter)
+
+Gets the number of operands being iterated
+
+::
+
+  NpyIter_IterNextFunc *
+  NpyIter_GetIterNext(NpyIter *iter, char **errmsg)
+
+Compute the specialized iteration function for an iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  npy_intp
+  NpyIter_GetIterSize(NpyIter *iter)
+
+Gets the number of elements being iterated
+
+::
+
+  void
+  NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp
+                            *iend)
+
+Gets the range of iteration indices being iterated
+
+::
+
+  npy_intp
+  NpyIter_GetIterIndex(NpyIter *iter)
+
+Gets the current iteration index
+
+::
+
+  int
+  NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex)
+
+Sets the iterator position to the specified iterindex,
+which matches the iteration order of the iterator.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  npy_bool
+  NpyIter_HasMultiIndex(NpyIter *iter)
+
+Whether the iterator is tracking a multi-index
+
+::
+
+  int
+  NpyIter_GetShape(NpyIter *iter, npy_intp *outshape)
+
+Gets the broadcast shape if a multi-index is being tracked by the iterator,
+otherwise gets the shape of the iteration as Fortran-order
+(fastest-changing index first).
+
+The reason Fortran-order is returned when a multi-index
+is not enabled is that this is providing a direct view into how
+the iterator traverses the n-dimensional space. The iterator organizes
+its memory from fastest index to slowest index, and when
+a multi-index is enabled, it uses a permutation to recover the original
+order.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  NpyIter_GetMultiIndexFunc *
+  NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg)
+
+Compute a specialized get_multi_index function for the iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp *multi_index)
+
+Sets the iterator to the specified multi-index, which must have the
+correct number of entries for 'ndim'.  It is only valid
+when NPY_ITER_MULTI_INDEX was passed to the constructor.  This operation
+fails if the multi-index is out of bounds.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  int
+  NpyIter_RemoveMultiIndex(NpyIter *iter)
+
+Removes multi-index support from an iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_bool
+  NpyIter_HasIndex(NpyIter *iter)
+
+Whether the iterator is tracking an index
+
+::
+
+  npy_bool
+  NpyIter_IsBuffered(NpyIter *iter)
+
+Whether the iterator is buffered
+
+::
+
+  npy_bool
+  NpyIter_IsGrowInner(NpyIter *iter)
+
+Whether the inner loop can grow if buffering is unneeded
+
+::
+
+  npy_intp
+  NpyIter_GetBufferSize(NpyIter *iter)
+
+Gets the size of the buffer, or 0 if buffering is not enabled
+
+::
+
+  npy_intp *
+  NpyIter_GetIndexPtr(NpyIter *iter)
+
+Get a pointer to the index, if it is being tracked
+
+::
+
+  int
+  NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index)
+
+If the iterator is tracking an index, sets the iterator
+to the specified index.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  char **
+  NpyIter_GetDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  PyArray_Descr **
+  NpyIter_GetDescrArray(NpyIter *iter)
+
+Get the array of data type pointers (1 per object being iterated)
+
+::
+
+  PyArrayObject **
+  NpyIter_GetOperandArray(NpyIter *iter)
+
+Get the array of objects being iterated
+
+::
+
+  PyArrayObject *
+  NpyIter_GetIterView(NpyIter *iter, npy_intp i)
+
+Returns a view to the i-th object with the iterator's internal axes
+
+::
+
+  void
+  NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags)
+
+Gets an array of read flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags)
+
+Gets an array of write flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_DebugPrint(NpyIter *iter)
+
+For debugging
+
+::
+
+  npy_bool
+  NpyIter_IterationNeedsAPI(NpyIter *iter)
+
+Whether the iteration loop, and in particular the iternext()
+function, needs API access.  If this is true, the GIL must
+be retained while iterating.
+
+::
+
+  void
+  NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides)
+
+Get an array of strides which are fixed.  Any strides which may
+change during iteration receive the value NPY_MAX_INTP.  Once
+the iterator is ready to iterate, call this to get the strides
+which will always be fixed in the inner loop, then choose optimized
+inner loop functions which take advantage of those fixed strides.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_RemoveAxis(NpyIter *iter, int axis)
+
+Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX
+was set for iterator creation, and does not work if buffering is
+enabled. This function also resets the iterator to its initial state.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetAxisStrideArray(NpyIter *iter, int axis)
+
+Gets the array of strides for the specified axis.
+If the iterator is tracking a multi-index, gets the strides
+for the axis specified, otherwise gets the strides for
+the iteration axis as Fortran order (fastest-changing axis first).
+
+Returns NULL if an error occurs.
+
+::
+
+  npy_bool
+  NpyIter_RequiresBuffering(NpyIter *iter)
+
+Whether the iteration could be done with no buffering.
+
+::
+
+  char **
+  NpyIter_GetInitialDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated),
+directly into the arrays (never pointing to a buffer), for starting
+unbuffered iteration. This always returns the addresses for the
+iterator position as reset to iterator index 0.
+
+These pointers are different from the pointers accepted by
+NpyIter_ResetBasePointers, because the direction along some
+axes may have been reversed, requiring base offsets.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp
+                                  itemsize, npy_intp *outstrides)
+
+Builds a set of strides which are the same as the strides of an
+output array created using the NPY_ITER_ALLOCATE flag, where NULL
+was passed for op_axes.  This is for data packed contiguously,
+but not necessarily in C or Fortran order. This should be used
+together with NpyIter_GetShape and NpyIter_GetNDim.
+
+A use case for this function is to match the shape and layout of
+the iterator and tack on one or more dimensions.  For example,
+in order to generate a vector per input value for a numerical gradient,
+you pass in ndim*itemsize for itemsize, then add another dimension to
+the end with size ndim and stride itemsize.  To do the Hessian matrix,
+you do the same thing but add two dimensions, or take advantage of
+the symmetry and pack it into 1 dimension with a particular encoding.
+
+This function may only be called if the iterator is tracking a multi-index
+and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from
+being iterated in reverse order.
+
+If an array is created with this method, simply adding 'itemsize'
+for each iteration will traverse the new array matching the
+iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  int
+  PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)
+
+Convert any Python object, *obj*, to an NPY_CASTING enum.
+
+::
+
+  npy_intp
+  PyArray_CountNonzero(PyArrayObject *self)
+
+Counts the number of non-zero elements in the array.
+
+Returns -1 on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+Produces the smallest size and lowest kind type to which both
+input types can be cast.
+
+::
+
+  PyArray_Descr *
+  PyArray_MinScalarType(PyArrayObject *arr)
+
+If arr is a scalar (has 0 dimensions) with a built-in number data type,
+finds the smallest type size/kind which can still represent its data.
+Otherwise, returns the array's data type.
+
+
+::
+
+  PyArray_Descr *
+  PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp
+                     ndtypes, PyArray_Descr **dtypes)
+
+Produces the result type of a bunch of inputs, using the UFunc
+type promotion rules. Use this function when you have a set of
+input arrays, and need to determine an output array dtype.
+
+If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
+of the scalars is greater than the maximum "kind" of the arrays, does
+a regular type promotion.
+
+Otherwise, does a type promotion on the MinScalarType
+of all the inputs.  Data types passed directly are treated as array
+types.
+
+
+::
+
+  npy_bool
+  PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr
+                         *to, NPY_CASTING casting)
+
+Returns 1 if the array object may be cast to the given data type using
+the casting rule, 0 otherwise.  This differs from PyArray_CanCastTo in
+that it handles scalar arrays (0 dimensions) specially, by checking
+their value.
+
+::
+
+  npy_bool
+  PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr
+                        *to, NPY_CASTING casting)
+
+Returns true if data of type 'from' may be cast to data of type
+'to' according to the rule 'casting'.
+
+::
+
+  PyArrayObject *
+  PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject
+                      **op_in, PyArray_Descr *dtype, NPY_ORDER
+                      order, NPY_CASTING casting, PyArrayObject *out)
+
+This function provides summation of array elements according to
+the Einstein summation convention.  For example:
+- trace(a)        -> einsum("ii", a)
+- transpose(a)    -> einsum("ji", a)
+- multiply(a,b)   -> einsum(",", a, b)
+- inner(a,b)      -> einsum("i,i", a, b)
+- outer(a,b)      -> einsum("i,j", a, b)
+- matvec(a,b)     -> einsum("ij,j", a, b)
+- matmat(a,b)     -> einsum("ij,jk", a, b)
+
+subscripts: The string of subscripts for einstein summation.
+nop:        The number of operands
+op_in:      The array of operands
+dtype:      Either NULL, or the data type to force the calculation as.
+order:      The order for the calculation/the output axes.
+casting:    What kind of casts should be permitted.
+out:        Either NULL, or an array into which the output should be placed.
+
+By default, the labels get placed in alphabetical order
+at the end of the output. So, if c = einsum("i,j", a, b)
+then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b)
+then c[i,j] = a[j]*b[i].
+
+Alternatively, you can control the output order or prevent
+an axis from being summed/force an axis to be summed by providing
+indices for the output. This allows us to turn 'trace' into
+'diag', for example.
+- diag(a)         -> einsum("ii->i", a)
+- sum(a, axis=0)  -> einsum("i...->", a)
+
+Subscripts at the beginning and end may be specified by
+putting an ellipsis "..." in the middle.  For example,
+the function einsum("i...i", a) takes the diagonal of
+the first and last dimensions of the operand, and
+einsum("ij...,jk...->ik...") takes the matrix product using
+the first two indices of each operand instead of the last two.
+
+When there is only one operand, no axes being summed, and
+no output parameter, this function returns a view
+into the operand instead of making a copy.
+
+::
+
+  PyObject *
+  PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER
+                       order, PyArray_Descr *dtype, int subok)
+
+Creates a new array with the same shape as the provided one,
+with possible memory layout order and data type changes.
+
+prototype - The array the new one should be like.
+order     - NPY_CORDER - C-contiguous result.
+NPY_FORTRANORDER - Fortran-contiguous result.
+NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise.
+NPY_KEEPORDER - Keeps the axis ordering of prototype.
+dtype     - If not NULL, overrides the data type of the result.
+subok     - If 1, use the prototype's array subtype, otherwise
+always create a base-class array.
+
+NOTE: If dtype is not NULL, steals the dtype reference.
+
+::
+
+  int
+  PyArray_GetArrayParamsFromObject(PyObject *op, PyArray_Descr
+                                   *requested_dtype, npy_bool
+                                   writeable, PyArray_Descr
+                                   **out_dtype, int *out_ndim, npy_intp
+                                   *out_dims, PyArrayObject
+                                   **out_arr, PyObject *context)
+
+Retrieves the array parameters for viewing/converting an arbitrary
+PyObject* to a NumPy array. This allows the "innate type and shape"
+of Python list-of-lists to be discovered without
+actually converting to an array.
+
+In some cases, such as structured arrays and the __array__ interface,
+a data type needs to be used to make sense of the object.  When
+this is needed, provide a Descr for 'requested_dtype', otherwise
+provide NULL. This reference is not stolen. Also, if the requested
+dtype doesn't modify the interpretation of the input, out_dtype will
+still get the "innate" dtype of the object, not the dtype passed
+in 'requested_dtype'.
+
+If writing to the value in 'op' is desired, set the boolean
+'writeable' to 1.  This raises an error when 'op' is a scalar, list
+of lists, or other non-writeable 'op'.
+
+Result: When success (0 return value) is returned, either out_arr
+is filled with a non-NULL PyArrayObject and
+the rest of the parameters are untouched, or out_arr is
+filled with NULL, and the rest of the parameters are
+filled.
+
+Typical usage:
+
+PyArrayObject *arr = NULL;
+PyArray_Descr *dtype = NULL;
+int ndim = 0;
+npy_intp dims[NPY_MAXDIMS];
+
+if (PyArray_GetArrayParamsFromObject(op, NULL, 1, &dtype,
+&ndim, dims, &arr, NULL) < 0) {
+return NULL;
+}
+if (arr == NULL) {
+... validate/change dtype, validate flags, ndim, etc ...
+// Could make custom strides here too
+arr = PyArray_NewFromDescr(&PyArray_Type, dtype, ndim,
+dims, NULL,
+is_f_order ? NPY_ARRAY_F_CONTIGUOUS : 0,
+NULL);
+if (arr == NULL) {
+return NULL;
+}
+if (PyArray_CopyObject(arr, op) < 0) {
+Py_DECREF(arr);
+return NULL;
+}
+}
+else {
+... in this case the other parameters weren't filled, just
+validate and possibly copy arr itself ...
+}
+... use arr ...
+
+::
+
+  int
+  PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE
+                                  *modes, int n)
+
+Convert an object to an array of n NPY_CLIPMODE values.
+This is intended to be used in functions where a different mode
+could be applied to each axis, like in ravel_multi_index.
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct2(PyObject *op1, PyObject
+                         *op2, PyArrayObject*out)
+
+Numeric.matrixproduct2(a,v,out)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  npy_bool
+  NpyIter_IsFirstVisit(NpyIter *iter, int iop)
+
+Checks to see whether this is the first time the elements
+of the specified reduction operand which the iterator points at are
+being seen for the first time. The function returns
+a reasonable answer for reduction operands and when buffering is
+disabled. The answer may be incorrect for buffered non-reduction
+operands.
+
+This function is intended to be used in EXTERNAL_LOOP mode only,
+and will produce some wrong answers when that mode is not enabled.
+
+If this function returns true, the caller should also
+check the inner loop stride of the operand, because if
+that stride is 0, then only the first element of the innermost
+external loop is being visited for the first time.
+
+WARNING: For performance reasons, 'iop' is not bounds-checked,
+it is not confirmed that 'iop' is actually a reduction
+operand, and it is not confirmed that EXTERNAL_LOOP
+mode is enabled. These checks are the responsibility of
+the caller, and should be done outside of any inner loops.
+
+::
+
+  int
+  PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)
+
+Sets the 'base' attribute of the array. This steals a reference
+to 'obj'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void
+  PyArray_CreateSortedStridePerm(int ndim, npy_intp
+                                 *strides, npy_stride_sort_item
+                                 *out_strideperm)
+
+
+This function populates the first ndim elements
+of strideperm with sorted descending by their absolute values.
+For example, the stride array (4, -2, 12) becomes
+[(2, 12), (0, 4), (1, -2)].
+
+::
+
+  void
+  PyArray_RemoveAxesInPlace(PyArrayObject *arr, npy_bool *flags)
+
+
+Removes the axes flagged as True from the array,
+modifying it in place. If an axis flagged for removal
+has a shape entry bigger than one, this effectively selects
+index zero for that axis.
+
+WARNING: If an axis flagged for removal has a shape equal to zero,
+the array will point to invalid memory. The caller must
+validate this!
+If an axis flagged for removal has a shape larger then one,
+the aligned flag (and in the future the contiguous flags),
+may need explicite update.
+(check also NPY_RELAXED_STRIDES_CHECKING)
+
+For example, this can be used to remove the reduction axes
+from a reduction result once its computation is complete.
+
+::
+
+  void
+  PyArray_DebugPrint(PyArrayObject *obj)
+
+Prints the raw data of the ndarray in a form useful for debugging
+low-level C issues.
+
+::
+
+  int
+  PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)
+
+
+This function does nothing if obj is writeable, and raises an exception
+(and returns -1) if obj is not writeable. It may also do other
+house-keeping, such as issuing warnings on arrays which are transitioning
+to become views. Always call this function at some point before writing to
+an array.
+
+'name' is a name for the array, used to give better error
+messages. Something like "assignment destination", "output array", or even
+just "array".
+
+::
+
+  int
+  PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base)
+
+
+Precondition: 'arr' is a copy of 'base' (though possibly with different
+strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the
+->base pointer on 'arr', so that when 'arr' is destructed, it will copy any
+changes back to 'base'.
+
+Steals a reference to 'base'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void *
+  PyDataMem_NEW(size_t size)
+
+Allocates memory for array data.
+
+::
+
+  void
+  PyDataMem_FREE(void *ptr)
+
+Free memory for array data.
+
+::
+
+  void *
+  PyDataMem_RENEW(void *ptr, size_t size)
+
+Reallocate/resize memory for array data.
+
+::
+
+  PyDataMem_EventHookFunc *
+  PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void
+                         *user_data, void **old_data)
+
+Sets the allocation event hook for numpy array data.
+Takes a PyDataMem_EventHookFunc *, which has the signature:
+void hook(void *old, void *new, size_t size, void *user_data).
+Also takes a void *user_data, and void **old_data.
+
+Returns a pointer to the previous hook or NULL.  If old_data is
+non-NULL, the previous user_data pointer will be copied to it.
+
+If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW:
+result = PyDataMem_NEW(size)        -> (*hook)(NULL, result, size, user_data)
+PyDataMem_FREE(ptr)                 -> (*hook)(ptr, NULL, 0, user_data)
+result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data)
+
+When the hook is called, the GIL will be held by the calling
+thread.  The hook should be written to be reentrant, if it performs
+operations that might cause new allocation events (such as the
+creation/descruction numpy objects, or creating/destroying Python
+objects which might cause a gc)
+
+::
+
+  void
+  PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject
+                          **ret, int getmap)
+
+
+::
+
+  PyObject *
+  PyArray_MapIterArray(PyArrayObject *a, PyObject *index)
+
+
+Use advanced indexing to iterate an array. Please note
+that most of this public API is currently not guaranteed
+to stay the same between versions. If you plan on using
+it, please consider adding more utility functions here
+to accommodate new features.
+
+::
+
+  void
+  PyArray_MapIterNext(PyArrayMapIterObject *mit)
+
+This function needs to update the state of the map iterator
+and point mit->dataptr to the memory-location of the next object
+
+Note that this function never handles an extra operand but provides
+compatibility for an old (exposed) API.
+
+::
+
+  int
+  PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int
+                    axis, NPY_SELECTKIND which)
+
+Partition an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int
+                       axis, NPY_SELECTKIND which)
+
+ArgPartition an array
+
+::
+
+  int
+  PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind)
+
+Convert object to select kind
+
+::
+
+  void *
+  PyDataMem_NEW_ZEROED(size_t size, size_t elsize)
+
+Allocates zeroed memory for array data.
+
+::
+
+  int
+  PyArray_CheckAnyScalarExact(PyObject *obj)
+
+return true an object is exactly a numpy scalar
+
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
new file mode 100644
index 0000000000..c97a3a797a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
@@ -0,0 +1,246 @@
+/*
+ * DON'T INCLUDE THIS DIRECTLY.
+ */
+
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#ifdef __cplusplus
+#define CONFUSE_EMACS {
+#define CONFUSE_EMACS2 }
+extern "C" CONFUSE_EMACS
+#undef CONFUSE_EMACS
+#undef CONFUSE_EMACS2
+/* ... otherwise a semi-smart identer (like emacs) tries to indent
+       everything when you're typing */
+#endif
+
+#include <Python.h>
+#include "ndarraytypes.h"
+
+/* Includes the "function" C-API -- these are all stored in a
+   list of pointers --- one for each file
+   The two lists are concatenated into one in multiarray.
+
+   They are available as import_array()
+*/
+
+#include "__multiarray_api.h"
+
+
+/* C-API that requries previous API to be defined */
+
+#define PyArray_DescrCheck(op) (((PyObject*)(op))->ob_type==&PyArrayDescr_Type)
+
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
+
+#define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
+        ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
+         (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
+         (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
+          Py_NotImplemented))
+
+#define PyArray_HasArrayInterface(op, out)                                    \
+        PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
+                               (PyArray_NDIM((PyArrayObject *)op) == 0))
+
+#define PyArray_IsScalar(obj, cls)                                            \
+        (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
+                                PyArray_IsZeroDim(m))
+#if PY_MAJOR_VERSION >= 3
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyFloat_Check(obj) || PyComplex_Check(obj) ||                        \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj)                       \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) ||                 \
+         PyUnicode_Check(obj))
+#else
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyInt_Check(obj) || PyFloat_Check(obj) || PyComplex_Check(obj) ||    \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyInt_Check(obj)                        \
+              || PyLong_Check(obj)                                            \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyString_Check(obj) ||                \
+         PyUnicode_Check(obj))
+#endif
+
+#define PyArray_IsAnyScalar(obj)                                              \
+        (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
+                                     PyArray_CheckScalar(obj))
+
+
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
+                                  Py_INCREF(m), (m) :                         \
+                                  (PyArrayObject *)(PyArray_Copy(m)))
+
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
+                                  PyArray_CompareLists(PyArray_DIMS(a1),      \
+                                                       PyArray_DIMS(a2),      \
+                                                       PyArray_NDIM(a1)))
+
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
+                                                      NULL)
+
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
+                                PyArray_DescrFromType(type), 0, 0, 0, NULL)
+
+#define PyArray_FROM_OTF(m, type, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
+
+#define PyArray_FROMANY(m, type, min, max, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
+
+#define PyArray_ZEROS(m, dims, type, is_f_order) \
+        PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_EMPTY(m, dims, type, is_f_order) \
+        PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
+                                           PyArray_NBYTES(obj))
+
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
+
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT, NULL)
+
+#define PyArray_EquivArrTypes(a1, a2) \
+        PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+
+#define PyArray_EquivByteorders(b1, b2) \
+        (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+
+#define PyArray_SimpleNew(nd, dims, typenum) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
+                    data, 0, NPY_ARRAY_CARRAY, NULL)
+
+#define PyArray_SimpleNewFromDescr(nd, dims, descr) \
+        PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
+                             NULL, NULL, 0, NULL)
+
+#define PyArray_ToScalar(data, arr) \
+        PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+
+
+/* These might be faster without the dereferencing of obj
+   going on inside -- of course an optimizing compiler should
+   inline the constants inside a for loop making it a moot point
+*/
+
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
+                                         (i)*PyArray_STRIDES(obj)[0]))
+
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1]))
+
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2]))
+
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2] + \
+                                            (l)*PyArray_STRIDES(obj)[3]))
+
+static NPY_INLINE void
+PyArray_XDECREF_ERR(PyArrayObject *arr)
+{
+    if (arr != NULL) {
+        if (PyArray_FLAGS(arr) & NPY_ARRAY_UPDATEIFCOPY) {
+            PyArrayObject *base = (PyArrayObject *)PyArray_BASE(arr);
+            PyArray_ENABLEFLAGS(base, NPY_ARRAY_WRITEABLE);
+            PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
+        }
+        Py_DECREF(arr);
+    }
+}
+
+#define PyArray_DESCR_REPLACE(descr) do { \
+                PyArray_Descr *_new_; \
+                _new_ = PyArray_DescrNew(descr); \
+                Py_XDECREF(descr); \
+                descr = _new_; \
+        } while(0)
+
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+
+#define PyArray_FromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_BEHAVED | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                        max_depth, NPY_ARRAY_ENSURECOPY | \
+                                   NPY_ARRAY_DEFAULT | \
+                                   NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_Cast(mp, type_num)                                            \
+        PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+
+#define PyArray_Take(ap, items, axis)                                         \
+        PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+
+#define PyArray_Put(ap, items, values)                                        \
+        PyArray_PutTo(ap, items, values, NPY_RAISE)
+
+/* Compatibility with old Numeric stuff -- don't use in new code */
+
+#define PyArray_FromDimsAndData(nd, d, type, data)                            \
+        PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
+                                        data)
+
+
+/*
+   Check to see if this key in the dictionary is the "title"
+   entry of the tuple (i.e. a duplicate dictionary entry in the fields
+   dict.
+*/
+
+#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \
+                                   (PyTuple_GET_ITEM((value), 2) == (key)))
+
+
+#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
+#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* NPY_NDARRAYOBJECT_H */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
new file mode 100644
index 0000000000..f1fe89f1a1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
@@ -0,0 +1,1793 @@
+#ifndef NDARRAYTYPES_H
+#define NDARRAYTYPES_H
+
+#include "npy_common.h"
+#include "npy_endian.h"
+#include "npy_cpu.h"
+#include "utils.h"
+
+#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN
+
+/* Only use thread if configured in config and python supports it */
+#if defined WITH_THREAD && !NPY_NO_SMP
+        #define NPY_ALLOW_THREADS 1
+#else
+        #define NPY_ALLOW_THREADS 0
+#endif
+
+
+
+/*
+ * There are several places in the code where an array of dimensions
+ * is allocated statically.  This is the size of that static
+ * allocation.
+ *
+ * The array creation itself could have arbitrary dimensions but all
+ * the places where static allocation is used would need to be changed
+ * to dynamic (including inside of several structures)
+ */
+
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+
+/*
+ * Binary compatibility version number.  This number is increased
+ * whenever the C-API is changed such that binary compatibility is
+ * broken, i.e. whenever a recompile of extension modules is needed.
+ */
+#define NPY_VERSION NPY_ABI_VERSION
+
+/*
+ * Minor API version.  This number is increased whenever a change is
+ * made to the C-API -- whether it breaks binary compatibility or not.
+ * Some changes, such as adding a function pointer to the end of the
+ * function table, can be made without breaking binary compatibility.
+ * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION)
+ * would be increased.  Whenever binary compatibility is broken, both
+ * NPY_VERSION and NPY_FEATURE_VERSION should be increased.
+ */
+#define NPY_FEATURE_VERSION NPY_API_VERSION
+
+enum NPY_TYPES {    NPY_BOOL=0,
+                    NPY_BYTE, NPY_UBYTE,
+                    NPY_SHORT, NPY_USHORT,
+                    NPY_INT, NPY_UINT,
+                    NPY_LONG, NPY_ULONG,
+                    NPY_LONGLONG, NPY_ULONGLONG,
+                    NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+                    NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+                    NPY_OBJECT=17,
+                    NPY_STRING, NPY_UNICODE,
+                    NPY_VOID,
+                    /*
+                     * New 1.6 types appended, may be integrated
+                     * into the above in 2.0.
+                     */
+                    NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF,
+
+                    NPY_NTYPES,
+                    NPY_NOTYPE,
+                    NPY_CHAR,      /* special flag */
+                    NPY_USERDEF=256,  /* leave room for characters */
+
+                    /* The number of types not including the new 1.6 types */
+                    NPY_NTYPES_ABI_COMPATIBLE=21
+};
+
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+
+/* How many floating point types are there (excluding half) */
+#define NPY_NUM_FLOATTYPE 3
+
+/*
+ * These characters correspond to the array type and the struct
+ * module
+ */
+
+enum NPY_TYPECHAR {
+        NPY_BOOLLTR = '?',
+        NPY_BYTELTR = 'b',
+        NPY_UBYTELTR = 'B',
+        NPY_SHORTLTR = 'h',
+        NPY_USHORTLTR = 'H',
+        NPY_INTLTR = 'i',
+        NPY_UINTLTR = 'I',
+        NPY_LONGLTR = 'l',
+        NPY_ULONGLTR = 'L',
+        NPY_LONGLONGLTR = 'q',
+        NPY_ULONGLONGLTR = 'Q',
+        NPY_HALFLTR = 'e',
+        NPY_FLOATLTR = 'f',
+        NPY_DOUBLELTR = 'd',
+        NPY_LONGDOUBLELTR = 'g',
+        NPY_CFLOATLTR = 'F',
+        NPY_CDOUBLELTR = 'D',
+        NPY_CLONGDOUBLELTR = 'G',
+        NPY_OBJECTLTR = 'O',
+        NPY_STRINGLTR = 'S',
+        NPY_STRINGLTR2 = 'a',
+        NPY_UNICODELTR = 'U',
+        NPY_VOIDLTR = 'V',
+        NPY_DATETIMELTR = 'M',
+        NPY_TIMEDELTALTR = 'm',
+        NPY_CHARLTR = 'c',
+
+        /*
+         * No Descriptor, just a define -- this let's
+         * Python users specify an array of integers
+         * large enough to hold a pointer on the
+         * platform
+         */
+        NPY_INTPLTR = 'p',
+        NPY_UINTPLTR = 'P',
+
+        /*
+         * These are for dtype 'kinds', not dtype 'typecodes'
+         * as the above are for.
+         */
+        NPY_GENBOOLLTR ='b',
+        NPY_SIGNEDLTR = 'i',
+        NPY_UNSIGNEDLTR = 'u',
+        NPY_FLOATINGLTR = 'f',
+        NPY_COMPLEXLTR = 'c'
+};
+
+typedef enum {
+        NPY_QUICKSORT=0,
+        NPY_HEAPSORT=1,
+        NPY_MERGESORT=2
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_MERGESORT + 1)
+
+
+typedef enum {
+        NPY_INTROSELECT=0
+} NPY_SELECTKIND;
+#define NPY_NSELECTS (NPY_INTROSELECT + 1)
+
+
+typedef enum {
+        NPY_SEARCHLEFT=0,
+        NPY_SEARCHRIGHT=1
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+
+
+typedef enum {
+        NPY_NOSCALAR=-1,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+
+/* For specifying array memory layout or iteration order */
+typedef enum {
+        /* Fortran order if inputs are all Fortran, C otherwise */
+        NPY_ANYORDER=-1,
+        /* C order */
+        NPY_CORDER=0,
+        /* Fortran order */
+        NPY_FORTRANORDER=1,
+        /* An order as close to the inputs as possible */
+        NPY_KEEPORDER=2
+} NPY_ORDER;
+
+/* For specifying allowed casting in operations which support it */
+typedef enum {
+        /* Only allow identical types */
+        NPY_NO_CASTING=0,
+        /* Allow identical and byte swapped types */
+        NPY_EQUIV_CASTING=1,
+        /* Only allow safe casts */
+        NPY_SAFE_CASTING=2,
+        /* Allow safe casts or casts within the same kind */
+        NPY_SAME_KIND_CASTING=3,
+        /* Allow any casts */
+        NPY_UNSAFE_CASTING=4
+} NPY_CASTING;
+
+typedef enum {
+        NPY_CLIP=0,
+        NPY_WRAP=1,
+        NPY_RAISE=2
+} NPY_CLIPMODE;
+
+/* The special not-a-time (NaT) value */
+#define NPY_DATETIME_NAT NPY_MIN_INT64
+
+/*
+ * Upper bound on the length of a DATETIME ISO 8601 string
+ *   YEAR: 21 (64-bit year)
+ *   MONTH: 3
+ *   DAY: 3
+ *   HOURS: 3
+ *   MINUTES: 3
+ *   SECONDS: 3
+ *   ATTOSECONDS: 1 + 3*6
+ *   TIMEZONE: 5
+ *   NULL TERMINATOR: 1
+ */
+#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
+
+typedef enum {
+        NPY_FR_Y = 0,  /* Years */
+        NPY_FR_M = 1,  /* Months */
+        NPY_FR_W = 2,  /* Weeks */
+        /* Gap where 1.6 NPY_FR_B (value 3) was */
+        NPY_FR_D = 4,  /* Days */
+        NPY_FR_h = 5,  /* hours */
+        NPY_FR_m = 6,  /* minutes */
+        NPY_FR_s = 7,  /* seconds */
+        NPY_FR_ms = 8, /* milliseconds */
+        NPY_FR_us = 9, /* microseconds */
+        NPY_FR_ns = 10,/* nanoseconds */
+        NPY_FR_ps = 11,/* picoseconds */
+        NPY_FR_fs = 12,/* femtoseconds */
+        NPY_FR_as = 13,/* attoseconds */
+        NPY_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */
+} NPY_DATETIMEUNIT;
+
+/*
+ * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS
+ *       is technically one more than the actual number of units.
+ */
+#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1)
+#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC
+
+/*
+ * Business day conventions for mapping invalid business
+ * days to valid business days.
+ */
+typedef enum {
+    /* Go forward in time to the following business day. */
+    NPY_BUSDAY_FORWARD,
+    NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD,
+    /* Go backward in time to the preceding business day. */
+    NPY_BUSDAY_BACKWARD,
+    NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD,
+    /*
+     * Go forward in time to the following business day, unless it
+     * crosses a month boundary, in which case go backward
+     */
+    NPY_BUSDAY_MODIFIEDFOLLOWING,
+    /*
+     * Go backward in time to the preceding business day, unless it
+     * crosses a month boundary, in which case go forward.
+     */
+    NPY_BUSDAY_MODIFIEDPRECEDING,
+    /* Produce a NaT for non-business days. */
+    NPY_BUSDAY_NAT,
+    /* Raise an exception for non-business days. */
+    NPY_BUSDAY_RAISE
+} NPY_BUSDAY_ROLL;
+
+/************************************************************
+ * NumPy Auxiliary Data for inner loops, sort functions, etc.
+ ************************************************************/
+
+/*
+ * When creating an auxiliary data struct, this should always appear
+ * as the first member, like this:
+ *
+ * typedef struct {
+ *     NpyAuxData base;
+ *     double constant;
+ * } constant_multiplier_aux_data;
+ */
+typedef struct NpyAuxData_tag NpyAuxData;
+
+/* Function pointers for freeing or cloning auxiliary data */
+typedef void (NpyAuxData_FreeFunc) (NpyAuxData *);
+typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *);
+
+struct NpyAuxData_tag {
+    NpyAuxData_FreeFunc *free;
+    NpyAuxData_CloneFunc *clone;
+    /* To allow for a bit of expansion without breaking the ABI */
+    void *reserved[2];
+};
+
+/* Macros to use for freeing and cloning auxiliary data */
+#define NPY_AUXDATA_FREE(auxdata) \
+    do { \
+        if ((auxdata) != NULL) { \
+            (auxdata)->free(auxdata); \
+        } \
+    } while(0)
+#define NPY_AUXDATA_CLONE(auxdata) \
+    ((auxdata)->clone(auxdata))
+
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+
+  /*
+   * Macros to define how array, and dimension/strides data is
+   * allocated.
+   */
+
+  /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */
+
+#define NPY_USE_PYMEM 1
+
+#if NPY_USE_PYMEM == 1
+#define PyArray_malloc PyMem_Malloc
+#define PyArray_free PyMem_Free
+#define PyArray_realloc PyMem_Realloc
+#else
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+#endif
+
+/* Dimensions and strides */
+#define PyDimMem_NEW(size)                                         \
+    ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+
+#define PyDimMem_RENEW(ptr,size)                                   \
+        ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+
+/* forward declaration */
+struct _PyArray_Descr;
+
+/* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+                                     npy_intp, int, void *);
+
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+
+
+/*
+ * These assume aligned and notswapped data -- a buffer will be used
+ * before or contiguous data will be obtained
+ */
+
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+                               npy_intp, void *);
+
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+                                       void *);
+
+/*
+ * XXX the ignore argument should be removed next time the API version
+ * is bumped. It used to be the separator.
+ */
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+                               char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+                                  struct _PyArray_Descr *);
+
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
+                                    npy_intp *, npy_intp *,
+                                    void *);
+typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
+                                       npy_intp *, npy_intp *,
+                                       void *);
+
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+
+typedef int (PyArray_ScalarKindFunc)(void *);
+
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in,
+                                       void *values, npy_intp nv);
+typedef int  (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray,
+                                       npy_intp nindarray, npy_intp n_outer,
+                                       npy_intp m_middle, npy_intp nelem,
+                                       NPY_CLIPMODE clipmode);
+
+typedef struct {
+        npy_intp *ptr;
+        int len;
+} PyArray_Dims;
+
+typedef struct {
+        /*
+         * Functions to cast to most other standard types
+         * Can have some NULL entries. The types
+         * DATETIME, TIMEDELTA, and HALF go into the castdict
+         * even though they are built-in.
+         */
+        PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
+
+        /* The next four functions *cannot* be NULL */
+
+        /*
+         * Functions to get and set items with standard Python types
+         * -- not array scalars
+         */
+        PyArray_GetItemFunc *getitem;
+        PyArray_SetItemFunc *setitem;
+
+        /*
+         * Copy and/or swap data.  Memory areas may not overlap
+         * Use memmove first if they might
+         */
+        PyArray_CopySwapNFunc *copyswapn;
+        PyArray_CopySwapFunc *copyswap;
+
+        /*
+         * Function to compare items
+         * Can be NULL
+         */
+        PyArray_CompareFunc *compare;
+
+        /*
+         * Function to select largest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmax;
+
+        /*
+         * Function to compute dot product
+         * Can be NULL
+         */
+        PyArray_DotFunc *dotfunc;
+
+        /*
+         * Function to scan an ASCII file and
+         * place a single value plus possible separator
+         * Can be NULL
+         */
+        PyArray_ScanFunc *scanfunc;
+
+        /*
+         * Function to read a single value from a string
+         * and adjust the pointer; Can be NULL
+         */
+        PyArray_FromStrFunc *fromstr;
+
+        /*
+         * Function to determine if data is zero or not
+         * If NULL a default version is
+         * used at Registration time.
+         */
+        PyArray_NonzeroFunc *nonzero;
+
+        /*
+         * Used for arange.
+         * Can be NULL.
+         */
+        PyArray_FillFunc *fill;
+
+        /*
+         * Function to fill arrays with scalar values
+         * Can be NULL
+         */
+        PyArray_FillWithScalarFunc *fillwithscalar;
+
+        /*
+         * Sorting functions
+         * Can be NULL
+         */
+        PyArray_SortFunc *sort[NPY_NSORTS];
+        PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+
+        /*
+         * Dictionary of additional casting functions
+         * PyArray_VectorUnaryFuncs
+         * which can be populated to support casting
+         * to other registered types. Can be NULL
+         */
+        PyObject *castdict;
+
+        /*
+         * Functions useful for generalizing
+         * the casting rules.
+         * Can be NULL;
+         */
+        PyArray_ScalarKindFunc *scalarkind;
+        int **cancastscalarkindto;
+        int *cancastto;
+
+        PyArray_FastClipFunc *fastclip;
+        PyArray_FastPutmaskFunc *fastputmask;
+        PyArray_FastTakeFunc *fasttake;
+
+        /*
+         * Function to select smallest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmin;
+
+} PyArray_ArrFuncs;
+
+/* The item must be reference counted when it is inserted or extracted. */
+#define NPY_ITEM_REFCOUNT   0x01
+/* Same as needing REFCOUNT */
+#define NPY_ITEM_HASOBJECT  0x01
+/* Convert to list for pickling */
+#define NPY_LIST_PICKLE     0x02
+/* The item is a POINTER  */
+#define NPY_ITEM_IS_POINTER 0x04
+/* memory needs to be initialized for this data-type */
+#define NPY_NEEDS_INIT      0x08
+/* operations need Python C-API so don't give-up thread. */
+#define NPY_NEEDS_PYAPI     0x10
+/* Use f.getitem when extracting elements of this data-type */
+#define NPY_USE_GETITEM     0x20
+/* Use f.setitem when setting creating 0-d array from this data-type.*/
+#define NPY_USE_SETITEM     0x40
+/* A sticky flag specifically for structured arrays */
+#define NPY_ALIGNED_STRUCT  0x80
+
+/*
+ *These are inherited for global data-type if any data-types in the
+ * field have them
+ */
+#define NPY_FROM_FIELDS    (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \
+                            NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \
+                                NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+                                NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+
+#define PyDataType_FLAGCHK(dtype, flag) \
+        (((dtype)->flags & (flag)) == (flag))
+
+#define PyDataType_REFCHK(dtype) \
+        PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+
+typedef struct _PyArray_Descr {
+        PyObject_HEAD
+        /*
+         * the type object representing an
+         * instance of this type -- should not
+         * be two type_numbers with the same type
+         * object.
+         */
+        PyTypeObject *typeobj;
+        /* kind for this type */
+        char kind;
+        /* unique-character representing this type */
+        char type;
+        /*
+         * '>' (big), '<' (little), '|'
+         * (not-applicable), or '=' (native).
+         */
+        char byteorder;
+        /* flags describing data type */
+        char flags;
+        /* number representing this type */
+        int type_num;
+        /* element size (itemsize) for this type */
+        int elsize;
+        /* alignment needed for this type */
+        int alignment;
+        /*
+         * Non-NULL if this type is
+         * is an array (C-contiguous)
+         * of some other type
+         */
+        struct _arr_descr *subarray;
+        /*
+         * The fields dictionary for this type
+         * For statically defined descr this
+         * is always Py_None
+         */
+        PyObject *fields;
+        /*
+         * An ordered tuple of field names or NULL
+         * if no fields are defined
+         */
+        PyObject *names;
+        /*
+         * a table of functions specific for each
+         * basic data descriptor
+         */
+        PyArray_ArrFuncs *f;
+        /* Metadata about this dtype */
+        PyObject *metadata;
+        /*
+         * Metadata specific to the C implementation
+         * of the particular dtype. This was added
+         * for NumPy 1.7.0.
+         */
+        NpyAuxData *c_metadata;
+        /* Cached hash value (-1 if not yet computed).
+         * This was added for NumPy 2.0.0.
+         */
+        npy_hash_t hash;
+} PyArray_Descr;
+
+typedef struct _arr_descr {
+        PyArray_Descr *base;
+        PyObject *shape;       /* a tuple */
+} PyArray_ArrayDescr;
+
+/*
+ * The main array object structure.
+ *
+ * It has been recommended to use the inline functions defined below
+ * (PyArray_DATA and friends) to access fields here for a number of
+ * releases. Direct access to the members themselves is deprecated.
+ * To ensure that your code does not use deprecated access,
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
+ */
+/* This struct will be moved to a private header in a future release */
+typedef struct tagPyArrayObject_fields {
+    PyObject_HEAD
+    /* Pointer to the raw data buffer */
+    char *data;
+    /* The number of dimensions, also called 'ndim' */
+    int nd;
+    /* The size in each dimension, also called 'shape' */
+    npy_intp *dimensions;
+    /*
+     * Number of bytes to jump to get to the
+     * next element in each dimension
+     */
+    npy_intp *strides;
+    /*
+     * This object is decref'd upon
+     * deletion of array. Except in the
+     * case of UPDATEIFCOPY which has
+     * special handling.
+     *
+     * For views it points to the original
+     * array, collapsed so no chains of
+     * views occur.
+     *
+     * For creation from buffer object it
+     * points to an object that shold be
+     * decref'd on deletion
+     *
+     * For UPDATEIFCOPY flag this is an
+     * array to-be-updated upon deletion
+     * of this one
+     */
+    PyObject *base;
+    /* Pointer to type structure */
+    PyArray_Descr *descr;
+    /* Flags describing array -- see below */
+    int flags;
+    /* For weak references */
+    PyObject *weakreflist;
+} PyArrayObject_fields;
+
+/*
+ * To hide the implementation details, we only expose
+ * the Python struct HEAD.
+ */
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+/*
+ * Can't put this in npy_deprecated_api.h like the others.
+ * PyArrayObject field access is deprecated as of NumPy 1.7.
+ */
+typedef PyArrayObject_fields PyArrayObject;
+#else
+typedef struct tagPyArrayObject {
+        PyObject_HEAD
+} PyArrayObject;
+#endif
+
+#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
+
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+        PyObject_HEAD
+        PyObject *arr;
+        int flags;
+} PyArrayFlagsObject;
+
+/* Mirrors buffer object to ptr */
+
+typedef struct {
+        PyObject_HEAD
+        PyObject *base;
+        void *ptr;
+        npy_intp len;
+        int flags;
+} PyArray_Chunk;
+
+typedef struct {
+    NPY_DATETIMEUNIT base;
+    int num;
+} PyArray_DatetimeMetaData;
+
+typedef struct {
+    NpyAuxData base;
+    PyArray_DatetimeMetaData meta;
+} PyArray_DatetimeDTypeMetaData;
+
+/*
+ * This structure contains an exploded view of a date-time value.
+ * NaT is represented by year == NPY_DATETIME_NAT.
+ */
+typedef struct {
+        npy_int64 year;
+        npy_int32 month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+
+/* This is not used internally. */
+typedef struct {
+        npy_int64 day;
+        npy_int32 sec, us, ps, as;
+} npy_timedeltastruct;
+
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+
+/*
+ * Means c-style contiguous (last index varies the fastest). The data
+ * elements right after each other.
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_C_CONTIGUOUS    0x0001
+
+/*
+ * Set if array is a contiguous Fortran array: the first index varies
+ * the fastest in memory (strides array is reverse of C-contiguous
+ * array)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_F_CONTIGUOUS    0x0002
+
+/*
+ * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a
+ * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
+ * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
+ * at the same time if they have either zero or one element.
+ * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
+ * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
+ * and the array is contiguous if ndarray.squeeze() is contiguous.
+ * I.e. dimensions for which `ndarray.shape[dimension] == 1` are
+ * ignored.
+ */
+
+/*
+ * If set, the array owns the data: it will be free'd when the array
+ * is deleted.
+ *
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_OWNDATA         0x0004
+
+/*
+ * An array never has the next four set; they're only used as parameter
+ * flags to the the various FromAny functions
+ *
+ * This flag may be requested in constructor functions.
+ */
+
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_ARRAY_FORCECAST       0x0010
+
+/*
+ * Always copy the array. Returned arrays are always CONTIGUOUS,
+ * ALIGNED, and WRITEABLE.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSURECOPY      0x0020
+
+/*
+ * Make sure the returned array is a base-class ndarray
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSUREARRAY     0x0040
+
+/*
+ * Make sure that the strides are in units of the element size Needed
+ * for some operations with record-arrays.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ELEMENTSTRIDES  0x0080
+
+/*
+ * Array data is aligned on the appropiate memory address for the type
+ * stored according to how the compiler would align things (e.g., an
+ * array of integers (4 bytes each) starts on a memory address that's
+ * a multiple of 4)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_ALIGNED         0x0100
+
+/*
+ * Array data has the native endianness
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_NOTSWAPPED      0x0200
+
+/*
+ * Array data is writeable
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_WRITEABLE       0x0400
+
+/*
+ * If this flag is set, then base contains a pointer to an array of
+ * the same size that should be updated with the current contents of
+ * this array when this array is deallocated
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_UPDATEIFCOPY    0x1000
+
+/*
+ * NOTE: there are also internal flags defined in multiarray/arrayobject.h,
+ * which start at bit 31 and work down.
+ */
+
+#define NPY_ARRAY_BEHAVED      (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE)
+#define NPY_ARRAY_BEHAVED_NS   (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE | \
+                                NPY_ARRAY_NOTSWAPPED)
+#define NPY_ARRAY_CARRAY       (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_CARRAY_RO    (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_FARRAY       (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_FARRAY_RO    (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_DEFAULT      (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_IN_ARRAY     (NPY_ARRAY_CARRAY_RO)
+#define NPY_ARRAY_OUT_ARRAY    (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_INOUT_ARRAY  (NPY_ARRAY_CARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+#define NPY_ARRAY_IN_FARRAY    (NPY_ARRAY_FARRAY_RO)
+#define NPY_ARRAY_OUT_FARRAY   (NPY_ARRAY_FARRAY)
+#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+
+#define NPY_ARRAY_UPDATE_ALL   (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+
+/* This flag is for the array interface, not PyArrayObject */
+#define NPY_ARR_HAS_DESCR  0x0800
+
+
+
+
+/*
+ * Size of internal buffers used for alignment Make BUFSIZE a multiple
+ * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned
+ */
+#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000)
+#define NPY_BUFSIZE 8192
+/* buffer stress test size: */
+/*#define NPY_BUFSIZE 17*/
+
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+
+/*
+ * C API: consists of Macros and functions.  The MACROS are defined
+ * here.
+ */
+
+
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED)
+
+#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS)
+
+/* the variable is used in some places, so always define it */
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+#define NPY_END_THREADS   do { if (_save) \
+                { PyEval_RestoreThread(_save); _save = NULL;} } while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+                { _save = PyEval_SaveThread();} } while (0);
+
+#define NPY_BEGIN_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_BEGIN_THREADS;} while (0);
+
+#define NPY_END_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_END_THREADS; } while (0);
+
+#define NPY_ALLOW_C_API_DEF  PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API      do {__save__ = PyGILState_Ensure();} while (0);
+#define NPY_DISABLE_C_API    do {PyGILState_Release(__save__);} while (0);
+#else
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size)
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+#endif
+
+/**********************************
+ * The nditer object, added in 1.6
+ **********************************/
+
+/* The actual structure of the iterator is an internal detail */
+typedef struct NpyIter_InternalOnly NpyIter;
+
+/* Iterator function pointers that may be specialized */
+typedef int (NpyIter_IterNextFunc)(NpyIter *iter);
+typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter,
+                                      npy_intp *outcoords);
+
+/*** Global flags that may be passed to the iterator constructors ***/
+
+/* Track an index representing C order */
+#define NPY_ITER_C_INDEX                    0x00000001
+/* Track an index representing Fortran order */
+#define NPY_ITER_F_INDEX                    0x00000002
+/* Track a multi-index */
+#define NPY_ITER_MULTI_INDEX                0x00000004
+/* User code external to the iterator does the 1-dimensional innermost loop */
+#define NPY_ITER_EXTERNAL_LOOP              0x00000008
+/* Convert all the operands to a common data type */
+#define NPY_ITER_COMMON_DTYPE               0x00000010
+/* Operands may hold references, requiring API access during iteration */
+#define NPY_ITER_REFS_OK                    0x00000020
+/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */
+#define NPY_ITER_ZEROSIZE_OK                0x00000040
+/* Permits reductions (size-0 stride with dimension size > 1) */
+#define NPY_ITER_REDUCE_OK                  0x00000080
+/* Enables sub-range iteration */
+#define NPY_ITER_RANGED                     0x00000100
+/* Enables buffering */
+#define NPY_ITER_BUFFERED                   0x00000200
+/* When buffering is enabled, grows the inner loop if possible */
+#define NPY_ITER_GROWINNER                  0x00000400
+/* Delay allocation of buffers until first Reset* call */
+#define NPY_ITER_DELAY_BUFALLOC             0x00000800
+/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */
+#define NPY_ITER_DONT_NEGATE_STRIDES        0x00001000
+
+/*** Per-operand flags that may be passed to the iterator constructors ***/
+
+/* The operand will be read from and written to */
+#define NPY_ITER_READWRITE                  0x00010000
+/* The operand will only be read from */
+#define NPY_ITER_READONLY                   0x00020000
+/* The operand will only be written to */
+#define NPY_ITER_WRITEONLY                  0x00040000
+/* The operand's data must be in native byte order */
+#define NPY_ITER_NBO                        0x00080000
+/* The operand's data must be aligned */
+#define NPY_ITER_ALIGNED                    0x00100000
+/* The operand's data must be contiguous (within the inner loop) */
+#define NPY_ITER_CONTIG                     0x00200000
+/* The operand may be copied to satisfy requirements */
+#define NPY_ITER_COPY                       0x00400000
+/* The operand may be copied with UPDATEIFCOPY to satisfy requirements */
+#define NPY_ITER_UPDATEIFCOPY               0x00800000
+/* Allocate the operand if it is NULL */
+#define NPY_ITER_ALLOCATE                   0x01000000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE                 0x02000000
+/* This is a virtual array slot, operand is NULL but temporary data is there */
+#define NPY_ITER_VIRTUAL                    0x04000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST               0x08000000
+/* A mask is being used on this array, affects buffer -> array copy */
+#define NPY_ITER_WRITEMASKED                0x10000000
+/* This array is the mask for all WRITEMASKED operands */
+#define NPY_ITER_ARRAYMASK                  0x20000000
+
+#define NPY_ITER_GLOBAL_FLAGS               0x0000ffff
+#define NPY_ITER_PER_OP_FLAGS               0xffff0000
+
+
+/*****************************
+ * Basic iterator object
+ *****************************/
+
+/* FWD declaration */
+typedef struct PyArrayIterObject_tag PyArrayIterObject;
+
+/*
+ * type of the function which translates a set of coordinates to a
+ * pointer to the data
+ */
+typedef char* (*npy_iter_get_dataptr_t)(PyArrayIterObject* iter, npy_intp*);
+
+struct PyArrayIterObject_tag {
+        PyObject_HEAD
+        int               nd_m1;            /* number of dimensions - 1 */
+        npy_intp          index, size;
+        npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+        npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+        npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+        npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+        npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+        PyArrayObject     *ao;
+        char              *dataptr;        /* pointer to current item*/
+        npy_bool          contiguous;
+
+        npy_intp          bounds[NPY_MAXDIMS][2];
+        npy_intp          limits[NPY_MAXDIMS][2];
+        npy_intp          limits_sizes[NPY_MAXDIMS];
+        npy_iter_get_dataptr_t translate;
+} ;
+
+
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) do { \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        memset(_PyAIT(it)->coordinates, 0, \
+               (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \
+} while (0)
+
+#define _PyArray_ITER_NEXT1(it) do { \
+        (it)->dataptr += _PyAIT(it)->strides[0]; \
+        (it)->coordinates[0]++; \
+} while (0)
+
+#define _PyArray_ITER_NEXT2(it) do { \
+        if ((it)->coordinates[1] < (it)->dims_m1[1]) { \
+                (it)->coordinates[1]++; \
+                (it)->dataptr += (it)->strides[1]; \
+        } \
+        else { \
+                (it)->coordinates[1] = 0; \
+                (it)->coordinates[0]++; \
+                (it)->dataptr += (it)->strides[0] - \
+                        (it)->backstrides[1]; \
+        } \
+} while (0)
+
+#define PyArray_ITER_NEXT(it) do { \
+        _PyAIT(it)->index++; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyArray_ITER_NEXT1(_PyAIT(it)); \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else if (_PyAIT(it)->nd_m1 == 1) { \
+                _PyArray_ITER_NEXT2(_PyAIT(it)); \
+        } \
+        else { \
+                int __npy_i; \
+                for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+                        if (_PyAIT(it)->coordinates[__npy_i] < \
+                            _PyAIT(it)->dims_m1[__npy_i]) { \
+                                _PyAIT(it)->coordinates[__npy_i]++; \
+                                _PyAIT(it)->dataptr += \
+                                        _PyAIT(it)->strides[__npy_i]; \
+                                break; \
+                        } \
+                        else { \
+                                _PyAIT(it)->coordinates[__npy_i] = 0; \
+                                _PyAIT(it)->dataptr -= \
+                                        _PyAIT(it)->backstrides[__npy_i]; \
+                        } \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO(it, destination) do { \
+        int __npy_i; \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \
+                if (destination[__npy_i] < 0) { \
+                        destination[__npy_i] += \
+                                _PyAIT(it)->dims_m1[__npy_i]+1; \
+                } \
+                _PyAIT(it)->dataptr += destination[__npy_i] * \
+                        _PyAIT(it)->strides[__npy_i]; \
+                _PyAIT(it)->coordinates[__npy_i] = \
+                        destination[__npy_i]; \
+                _PyAIT(it)->index += destination[__npy_i] * \
+                        ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \
+                          _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO1D(it, ind) do { \
+        int __npy_i; \
+        npy_intp __npy_ind = (npy_intp) (ind); \
+        if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \
+        _PyAIT(it)->index = __npy_ind; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * _PyAIT(it)->strides[0]; \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+                for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
+                     __npy_i++) { \
+                        _PyAIT(it)->dataptr += \
+                                (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+                                * _PyAIT(it)->strides[__npy_i]; \
+                        __npy_ind %= _PyAIT(it)->factors[__npy_i]; \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+
+
+/*
+ * Any object passed to PyArray_Broadcast must be binary compatible
+ * with this structure.
+ */
+
+typedef struct {
+        PyObject_HEAD
+        int                  numiter;                 /* number of iters */
+        npy_intp             size;                    /* broadcasted size */
+        npy_intp             index;                   /* current index */
+        int                  nd;                      /* number of dims */
+        npy_intp             dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject    *iters[NPY_MAXARGS];     /* iterators */
+} PyArrayMultiIterObject;
+
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) do {                                   \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index = 0;                                             \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;  __npy_mi++) {    \
+                PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]);           \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_NEXT(multi) do {                                    \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index++;                                               \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;   __npy_mi++) {   \
+                PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]);            \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_GOTO(multi, dest) do {                            \
+        int __npy_mi;                                                       \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {   \
+                PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest);    \
+        }                                                                   \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;              \
+} while (0)
+
+#define PyArray_MultiIter_GOTO1D(multi, ind) do {                          \
+        int __npy_mi;                                                      \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {  \
+                PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind);  \
+        }                                                                  \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;             \
+} while (0)
+
+#define PyArray_MultiIter_DATA(multi, i)                \
+        ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+
+#define PyArray_MultiIter_NEXTi(multi, i)               \
+        PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+
+#define PyArray_MultiIter_NOTDONE(multi)                \
+        (_PyMIT(multi)->index < _PyMIT(multi)->size)
+
+
+/*
+ * Store the information needed for fancy-indexing over an array. The
+ * fields are slightly unordered to keep consec, dataptr and subspace
+ * where they were originally.
+ */
+typedef struct {
+        PyObject_HEAD
+        /*
+         * Multi-iterator portion --- needs to be present in this
+         * order to work with PyArray_Broadcast
+         */
+
+        int                   numiter;                 /* number of index-array
+                                                          iterators */
+        npy_intp              size;                    /* size of broadcasted
+                                                          result */
+        npy_intp              index;                   /* current index */
+        int                   nd;                      /* number of dims */
+        npy_intp              dimensions[NPY_MAXDIMS]; /* dimensions */
+        NpyIter               *outer;                  /* index objects
+                                                          iterator */
+        void                  *unused[NPY_MAXDIMS - 2];
+        PyArrayObject         *array;
+        /* Flat iterator for the indexed array. For compatibility solely. */
+        PyArrayIterObject     *ait;
+
+        /*
+         * Subspace array. For binary compatibility (was an iterator,
+         * but only the check for NULL should be used).
+         */
+        PyArrayObject         *subspace;
+
+        /*
+         * if subspace iteration, then this is the array of axes in
+         * the underlying array represented by the index objects
+         */
+        int                   iteraxes[NPY_MAXDIMS];
+        npy_intp              fancy_strides[NPY_MAXDIMS];
+
+        /* pointer when all fancy indices are 0 */
+        char                  *baseoffset;
+
+        /*
+         * after binding consec denotes at which axis the fancy axes
+         * are inserted.
+         */
+        int                   consec;
+        char                  *dataptr;
+
+        int                   nd_fancy;
+        npy_intp              fancy_dims[NPY_MAXDIMS];
+
+        /* Whether the iterator (any of the iterators) requires API */
+        int                   needs_api;
+
+        /*
+         * Extra op information.
+         */
+        PyArrayObject         *extra_op;
+        PyArray_Descr         *extra_op_dtype;         /* desired dtype */
+        npy_uint32            *extra_op_flags;         /* Iterator flags */
+
+        NpyIter               *extra_op_iter;
+        NpyIter_IterNextFunc  *extra_op_next;
+        char                  **extra_op_ptrs;
+
+        /*
+         * Information about the iteration state.
+         */
+        NpyIter_IterNextFunc  *outer_next;
+        char                  **outer_ptrs;
+        npy_intp              *outer_strides;
+
+        /*
+         * Information about the subspace iterator.
+         */
+        NpyIter               *subspace_iter;
+        NpyIter_IterNextFunc  *subspace_next;
+        char                  **subspace_ptrs;
+        npy_intp              *subspace_strides;
+
+        /* Count for the external loop (which ever it is) for API iteration */
+        npy_intp              iter_count;
+
+} PyArrayMapIterObject;
+
+enum {
+    NPY_NEIGHBORHOOD_ITER_ZERO_PADDING,
+    NPY_NEIGHBORHOOD_ITER_ONE_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING,
+    NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING
+};
+
+typedef struct {
+    PyObject_HEAD
+
+    /*
+     * PyArrayIterObject part: keep this in this exact order
+     */
+    int               nd_m1;            /* number of dimensions - 1 */
+    npy_intp          index, size;
+    npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+    npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+    npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+    npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+    npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+    PyArrayObject     *ao;
+    char              *dataptr;        /* pointer to current item*/
+    npy_bool          contiguous;
+
+    npy_intp          bounds[NPY_MAXDIMS][2];
+    npy_intp          limits[NPY_MAXDIMS][2];
+    npy_intp          limits_sizes[NPY_MAXDIMS];
+    npy_iter_get_dataptr_t translate;
+
+    /*
+     * New members
+     */
+    npy_intp nd;
+
+    /* Dimensions is the dimension of the array */
+    npy_intp dimensions[NPY_MAXDIMS];
+
+    /*
+     * Neighborhood points coordinates are computed relatively to the
+     * point pointed by _internal_iter
+     */
+    PyArrayIterObject* _internal_iter;
+    /*
+     * To keep a reference to the representation of the constant value
+     * for constant padding
+     */
+    char* constant;
+
+    int mode;
+} PyArrayNeighborhoodIterObject;
+
+/*
+ * Neighborhood iterator API
+ */
+
+/* General: those work for any mode */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter);
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter);
+#if 0
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
+#endif
+
+/*
+ * Include inline implementations - functions defined there are not
+ * considered public API
+ */
+#define _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#include "_neighborhood_iterator_imp.h"
+#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+
+/* The default array type */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+
+/*
+ * All sorts of useful ways to look into a PyArrayObject. It is recommended
+ * to use PyArrayObject * objects instead of always casting from PyObject *,
+ * for improved type checking.
+ *
+ * In many cases here the macro versions of the accessors are deprecated,
+ * but can't be immediately changed to inline functions because the
+ * preexisting macros accept PyObject * and do automatic casts. Inline
+ * functions accepting PyArrayObject * provides for some compile-time
+ * checking of correctness when working with these objects in C.
+ */
+
+#define PyArray_ISONESEGMENT(m) (PyArray_NDIM(m) == 0 || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS))
+
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \
+                             (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)))
+
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
+                               NPY_ARRAY_F_CONTIGUOUS : 0))
+
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
+/*
+ * Changing access macros into functions, to allow for future hiding
+ * of the internal memory layout. This later hiding will allow the 2.x series
+ * to change the internal representation of arrays without affecting
+ * ABI compatibility.
+ */
+
+static NPY_INLINE int
+PyArray_NDIM(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->nd;
+}
+
+static NPY_INLINE void *
+PyArray_DATA(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE char *
+PyArray_BYTES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_DIMS(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_STRIDES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->strides;
+}
+
+static NPY_INLINE npy_intp
+PyArray_DIM(const PyArrayObject *arr, int idim)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions[idim];
+}
+
+static NPY_INLINE npy_intp
+PyArray_STRIDE(const PyArrayObject *arr, int istride)
+{
+    return ((PyArrayObject_fields *)arr)->strides[istride];
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject *
+PyArray_BASE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->base;
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr *
+PyArray_DESCR(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE int
+PyArray_FLAGS(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->flags;
+}
+
+static NPY_INLINE npy_intp
+PyArray_ITEMSIZE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->elsize;
+}
+
+static NPY_INLINE int
+PyArray_TYPE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->type_num;
+}
+
+static NPY_INLINE int
+PyArray_CHKFLAGS(const PyArrayObject *arr, int flags)
+{
+    return (PyArray_FLAGS(arr) & flags) == flags;
+}
+
+static NPY_INLINE PyObject *
+PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->getitem(
+                                        (void *)itemptr, (PyArrayObject *)arr);
+}
+
+static NPY_INLINE int
+PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->setitem(
+                                                        v, itemptr, arr);
+}
+
+#else
+
+/* These macros are deprecated as of NumPy 1.7. */
+#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd)
+#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags)
+#define PyArray_CHKFLAGS(m, FLAGS) \
+        ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS))
+#define PyArray_ITEMSIZE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->type_num)
+#define PyArray_GETITEM(obj,itemptr) \
+        PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+
+#define PyArray_SETITEM(obj,itemptr,v) \
+        PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \
+                                     (char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+#endif
+
+static NPY_INLINE PyArray_Descr *
+PyArray_DTYPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_SHAPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+/*
+ * Enables the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags |= flags;
+}
+
+/*
+ * Clears the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags &= ~flags;
+}
+
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) ||   \
+                                 ((type) == NPY_USHORT) ||     \
+                                 ((type) == NPY_UINT) ||       \
+                                 ((type) == NPY_ULONG) ||      \
+                                 ((type) == NPY_ULONGLONG))
+
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) ||      \
+                               ((type) == NPY_SHORT) ||        \
+                               ((type) == NPY_INT) ||          \
+                               ((type) == NPY_LONG) ||         \
+                               ((type) == NPY_LONGLONG))
+
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) &&     \
+                                ((type) <= NPY_ULONGLONG))
+
+#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \
+                              ((type) <= NPY_LONGDOUBLE)) || \
+                              ((type) == NPY_HALF))
+
+#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \
+                                  ((type) == NPY_HALF))
+
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) ||    \
+                                  ((type) == NPY_UNICODE))
+
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) &&   \
+                                ((type) <= NPY_CLONGDOUBLE))
+
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) ||      \
+                                  ((type) == NPY_DOUBLE) ||    \
+                                  ((type) == NPY_CDOUBLE) ||   \
+                                  ((type) == NPY_BOOL) ||      \
+                                  ((type) == NPY_OBJECT ))
+
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) &&  \
+                                    ((type) <=NPY_VOID))
+
+#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) &&  \
+                                    ((type) <=NPY_TIMEDELTA))
+
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+                                   ((type) < NPY_USERDEF+     \
+                                    NPY_NUMUSERTYPES))
+
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) ||  \
+                                    PyTypeNum_ISUSERDEF(type))
+
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+
+
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(_PyADt(obj))
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL)
+
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+
+    /*
+     * FIXME: This should check for a flag on the data-type that
+     * states whether or not it is variable length.  Because the
+     * ISFLEXIBLE check is hard-coded to the built-in data-types.
+     */
+#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+
+#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj))
+
+
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#else
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#endif
+
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) &&       \
+                                    PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED)
+
+
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+
+/************************************************************
+ * A struct used by PyArray_CreateSortedStridePerm, new in 1.7.
+ ************************************************************/
+
+typedef struct {
+    npy_intp perm, stride;
+} npy_stride_sort_item;
+
+/************************************************************
+ * This is the form of the struct that's returned pointed by the
+ * PyCObject attribute of an array __array_struct__. See
+ * http://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full
+ * documentation.
+ ************************************************************/
+typedef struct {
+    int two;              /*
+                           * contains the integer 2 as a sanity
+                           * check
+                           */
+
+    int nd;               /* number of dimensions */
+
+    char typekind;        /*
+                           * kind in array --- character code of
+                           * typestr
+                           */
+
+    int itemsize;         /* size of each element */
+
+    int flags;            /*
+                           * how should be data interpreted. Valid
+                           * flags are CONTIGUOUS (1), F_CONTIGUOUS (2),
+                           * ALIGNED (0x100), NOTSWAPPED (0x200), and
+                           * WRITEABLE (0x400).  ARR_HAS_DESCR (0x800)
+                           * states that arrdescr field is present in
+                           * structure
+                           */
+
+    npy_intp *shape;       /*
+                            * A length-nd array of shape
+                            * information
+                            */
+
+    npy_intp *strides;    /* A length-nd array of stride information */
+
+    void *data;           /* A pointer to the first element of the array */
+
+    PyObject *descr;      /*
+                           * A list of fields or NULL (ignored if flags
+                           * does not have ARR_HAS_DESCR flag set)
+                           */
+} PyArrayInterface;
+
+/*
+ * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions.
+ * See the documentation for PyDataMem_SetEventHook.
+ */
+typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
+                                       void *user_data);
+
+/*
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+ */
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
+#endif
+#define NPY_DEPRECATED_INCLUDES
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+#include "npy_1_7_deprecated_api.h"
+#endif
+/*
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ *
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ *
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ *     (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+ */
+#undef NPY_DEPRECATED_INCLUDES
+
+#endif /* NPY_ARRAYTYPES_H */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
new file mode 100644
index 0000000000..8306170876
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
@@ -0,0 +1,209 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+
+/*
+ * You can directly include noprefix.h as a backward
+ * compatibility measure
+ */
+#ifndef NPY_NO_PREFIX
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+#endif
+
+#define SIGSETJMP   NPY_SIGSETJMP
+#define SIGLONGJMP  NPY_SIGLONGJMP
+#define SIGJMP_BUF  NPY_SIGJMP_BUF
+
+#define MAX_DIMS NPY_MAXDIMS
+
+#define longlong    npy_longlong
+#define ulonglong   npy_ulonglong
+#define Bool        npy_bool
+#define longdouble  npy_longdouble
+#define byte        npy_byte
+
+#ifndef _BSD_SOURCE
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#endif
+
+#define ubyte       npy_ubyte
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#define cfloat      npy_cfloat
+#define cdouble     npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8        npy_int8
+#define UInt8       npy_uint8
+#define Int16       npy_int16
+#define UInt16      npy_uint16
+#define Int32       npy_int32
+#define UInt32      npy_uint32
+#define Int64       npy_int64
+#define UInt64      npy_uint64
+#define Int128      npy_int128
+#define UInt128     npy_uint128
+#define Int256      npy_int256
+#define UInt256     npy_uint256
+#define Float16     npy_float16
+#define Complex32   npy_complex32
+#define Float32     npy_float32
+#define Complex64   npy_complex64
+#define Float64     npy_float64
+#define Complex128  npy_complex128
+#define Float80     npy_float80
+#define Complex160  npy_complex160
+#define Float96     npy_float96
+#define Complex192  npy_complex192
+#define Float128    npy_float128
+#define Complex256  npy_complex256
+#define intp        npy_intp
+#define uintp       npy_uintp
+#define datetime    npy_datetime
+#define timedelta   npy_timedelta
+
+#define SIZEOF_LONGLONG         NPY_SIZEOF_LONGLONG
+#define SIZEOF_INTP             NPY_SIZEOF_INTP
+#define SIZEOF_UINTP            NPY_SIZEOF_UINTP
+#define SIZEOF_HALF             NPY_SIZEOF_HALF
+#define SIZEOF_LONGDOUBLE       NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_DATETIME         NPY_SIZEOF_DATETIME
+#define SIZEOF_TIMEDELTA        NPY_SIZEOF_TIMEDELTA
+
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX
+
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT   NPY_MAX_INT
+#define MIN_INT   NPY_MIN_INT
+#define MAX_UINT  NPY_MAX_UINT
+#define MAX_LONG  NPY_MAX_LONG
+#define MIN_LONG  NPY_MIN_LONG
+#define MAX_ULONG  NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+#define MIN_DATETIME NPY_MIN_DATETIME
+#define MAX_DATETIME NPY_MAX_DATETIME
+#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA
+#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA
+
+#define BITSOF_BOOL       NPY_BITSOF_BOOL
+#define BITSOF_CHAR       NPY_BITSOF_CHAR
+#define BITSOF_SHORT      NPY_BITSOF_SHORT
+#define BITSOF_INT        NPY_BITSOF_INT
+#define BITSOF_LONG       NPY_BITSOF_LONG
+#define BITSOF_LONGLONG   NPY_BITSOF_LONGLONG
+#define BITSOF_HALF       NPY_BITSOF_HALF
+#define BITSOF_FLOAT      NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE     NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+#define BITSOF_DATETIME   NPY_BITSOF_DATETIME
+#define BITSOF_TIMEDELTA   NPY_BITSOF_TIMEDELTA
+
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS     NPY_BEGIN_THREADS
+#define END_THREADS       NPY_END_THREADS
+#define ALLOW_C_API_DEF   NPY_ALLOW_C_API_DEF
+#define ALLOW_C_API       NPY_ALLOW_C_API
+#define DISABLE_C_API     NPY_DISABLE_C_API
+
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#endif
+
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#endif
+
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+
+#define CONTIGUOUS         NPY_CONTIGUOUS
+#define C_CONTIGUOUS       NPY_C_CONTIGUOUS
+#define FORTRAN            NPY_FORTRAN
+#define F_CONTIGUOUS       NPY_F_CONTIGUOUS
+#define OWNDATA            NPY_OWNDATA
+#define FORCECAST          NPY_FORCECAST
+#define ENSURECOPY         NPY_ENSURECOPY
+#define ENSUREARRAY        NPY_ENSUREARRAY
+#define ELEMENTSTRIDES     NPY_ELEMENTSTRIDES
+#define ALIGNED            NPY_ALIGNED
+#define NOTSWAPPED         NPY_NOTSWAPPED
+#define WRITEABLE          NPY_WRITEABLE
+#define UPDATEIFCOPY       NPY_UPDATEIFCOPY
+#define ARR_HAS_DESCR      NPY_ARR_HAS_DESCR
+#define BEHAVED            NPY_BEHAVED
+#define BEHAVED_NS         NPY_BEHAVED_NS
+#define CARRAY             NPY_CARRAY
+#define CARRAY_RO          NPY_CARRAY_RO
+#define FARRAY             NPY_FARRAY
+#define FARRAY_RO          NPY_FARRAY_RO
+#define DEFAULT            NPY_DEFAULT
+#define IN_ARRAY           NPY_IN_ARRAY
+#define OUT_ARRAY          NPY_OUT_ARRAY
+#define INOUT_ARRAY        NPY_INOUT_ARRAY
+#define IN_FARRAY          NPY_IN_FARRAY
+#define OUT_FARRAY         NPY_OUT_FARRAY
+#define INOUT_FARRAY       NPY_INOUT_FARRAY
+#define UPDATE_ALL         NPY_UPDATE_ALL
+
+#define OWN_DATA          NPY_OWNDATA
+#define BEHAVED_FLAGS     NPY_BEHAVED
+#define BEHAVED_FLAGS_NS  NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO   NPY_CARRAY_RO
+#define CARRAY_FLAGS      NPY_CARRAY
+#define FARRAY_FLAGS      NPY_FARRAY
+#define FARRAY_FLAGS_RO   NPY_FARRAY_RO
+#define DEFAULT_FLAGS     NPY_DEFAULT
+#define UPDATE_ALL_FLAGS  NPY_UPDATE_ALL_FLAGS
+
+#ifndef MIN
+#define MIN PyArray_MIN
+#endif
+#ifndef MAX
+#define MAX PyArray_MAX
+#endif
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
new file mode 100644
index 0000000000..4c318bc478
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
@@ -0,0 +1,130 @@
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+#endif
+
+#if defined(_WIN32)
+#define _WARN___STR2__(x) #x
+#define _WARN___STR1__(x) _WARN___STR2__(x)
+#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: "
+#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
+                         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+#elif defined(__GNUC__)
+#warning "Using deprecated NumPy API, disable it by " \
+         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+#endif
+/* TODO: How to do this warning message for other compilers? */
+
+/*
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
+ *
+ * This is an attempt to remove bad API, the proliferation of macros,
+ * and namespace pollution currently produced by the NumPy headers.
+ */
+
+/* These array flags are deprecated as of NumPy 1.7 */
+#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
+
+/*
+ * The consistent NPY_ARRAY_* names which don't pollute the NPY_*
+ * namespace were added in NumPy 1.7.
+ *
+ * These versions of the carray flags are deprecated, but
+ * probably should only be removed after two releases instead of one.
+ */
+#define NPY_C_CONTIGUOUS   NPY_ARRAY_C_CONTIGUOUS
+#define NPY_F_CONTIGUOUS   NPY_ARRAY_F_CONTIGUOUS
+#define NPY_OWNDATA        NPY_ARRAY_OWNDATA
+#define NPY_FORCECAST      NPY_ARRAY_FORCECAST
+#define NPY_ENSURECOPY     NPY_ARRAY_ENSURECOPY
+#define NPY_ENSUREARRAY    NPY_ARRAY_ENSUREARRAY
+#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES
+#define NPY_ALIGNED        NPY_ARRAY_ALIGNED
+#define NPY_NOTSWAPPED     NPY_ARRAY_NOTSWAPPED
+#define NPY_WRITEABLE      NPY_ARRAY_WRITEABLE
+#define NPY_UPDATEIFCOPY   NPY_ARRAY_UPDATEIFCOPY
+#define NPY_BEHAVED        NPY_ARRAY_BEHAVED
+#define NPY_BEHAVED_NS     NPY_ARRAY_BEHAVED_NS
+#define NPY_CARRAY         NPY_ARRAY_CARRAY
+#define NPY_CARRAY_RO      NPY_ARRAY_CARRAY_RO
+#define NPY_FARRAY         NPY_ARRAY_FARRAY
+#define NPY_FARRAY_RO      NPY_ARRAY_FARRAY_RO
+#define NPY_DEFAULT        NPY_ARRAY_DEFAULT
+#define NPY_IN_ARRAY       NPY_ARRAY_IN_ARRAY
+#define NPY_OUT_ARRAY      NPY_ARRAY_OUT_ARRAY
+#define NPY_INOUT_ARRAY    NPY_ARRAY_INOUT_ARRAY
+#define NPY_IN_FARRAY      NPY_ARRAY_IN_FARRAY
+#define NPY_OUT_FARRAY     NPY_ARRAY_OUT_FARRAY
+#define NPY_INOUT_FARRAY   NPY_ARRAY_INOUT_FARRAY
+#define NPY_UPDATE_ALL     NPY_ARRAY_UPDATE_ALL
+
+/* This way of accessing the default type is deprecated as of NumPy 1.7 */
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+
+/* These DATETIME bits aren't used internally */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer(                   \
+                PyDict_GetItemString(                                         \
+                    descr->metadata, NPY_METADATA_DTSTR), NULL))))
+#else
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(                    \
+                PyDict_GetItemString(descr->metadata, NPY_METADATA_DTSTR)))))
+#endif
+
+/*
+ * Deprecated as of NumPy 1.7, this kind of shortcut doesn't
+ * belong in the public API.
+ */
+#define NPY_AO PyArrayObject
+
+/*
+ * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't
+ * belong in the public API.
+ */
+#define fortran fortran_
+
+/*
+ * Deprecated as of NumPy 1.7, as it is a namespace-polluting
+ * macro.
+ */
+#define FORTRAN_IF PyArray_FORTRAN_IF
+
+/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */
+#define NPY_METADATA_DTSTR "__timeunit__"
+
+/*
+ * Deprecated as of NumPy 1.7.
+ * The reasoning:
+ *  - These are for datetime, but there's no datetime "namespace".
+ *  - They just turn NPY_STR_<x> into "<x>", which is just
+ *    making something simple be indirected.
+ */
+#define NPY_STR_Y "Y"
+#define NPY_STR_M "M"
+#define NPY_STR_W "W"
+#define NPY_STR_D "D"
+#define NPY_STR_h "h"
+#define NPY_STR_m "m"
+#define NPY_STR_s "s"
+#define NPY_STR_ms "ms"
+#define NPY_STR_us "us"
+#define NPY_STR_ns "ns"
+#define NPY_STR_ps "ps"
+#define NPY_STR_fs "fs"
+#define NPY_STR_as "as"
+
+/*
+ * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be
+ * removed in the next major release.
+ */
+#include "old_defines.h"
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
new file mode 100644
index 0000000000..db60a312c3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
@@ -0,0 +1,496 @@
+/*
+ * This is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ *
+ * If you want to use this for your own projects, it's recommended to make a
+ * copy of it. Although the stuff below is unlikely to change, we don't provide
+ * strong backwards compatibility guarantees at the moment.
+ */
+
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+
+#include <Python.h>
+#include <stdio.h>
+
+#if PY_VERSION_HEX >= 0x03000000
+#ifndef NPY_PY3K
+#define NPY_PY3K 1
+#endif
+#endif
+
+#include "numpy/npy_common.h"
+#include "numpy/ndarrayobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * PyInt -> PyLong
+ */
+
+#if defined(NPY_PY3K)
+/* Return True only if the long fits in a C long */
+static NPY_INLINE int PyInt_Check(PyObject *op) {
+    int overflow = 0;
+    if (!PyLong_Check(op)) {
+        return 0;
+    }
+    PyLong_AsLongAndOverflow(op, &overflow);
+    return (overflow == 0);
+}
+
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+
+/* NOTE:
+ *
+ * Since the PyLong type is very different from the fixed-range PyInt,
+ * we don't define PyInt_Type -> PyLong_Type.
+ */
+#endif /* NPY_PY3K */
+
+/*
+ * PyString -> PyBytes
+ */
+
+#if defined(NPY_PY3K)
+
+#define PyString_Type PyBytes_Type
+#define PyString_Check PyBytes_Check
+#define PyStringObject PyBytesObject
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define PyString_FromFormat PyBytes_FromFormat
+#define PyString_Concat PyBytes_Concat
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_Size PyBytes_Size
+
+#define PyUString_Type PyUnicode_Type
+#define PyUString_Check PyUnicode_Check
+#define PyUStringObject PyUnicodeObject
+#define PyUString_FromString PyUnicode_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyUString_FromFormat PyUnicode_FromFormat
+#define PyUString_Concat PyUnicode_Concat2
+#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_Size PyUnicode_Size
+#define PyUString_InternFromString PyUnicode_InternFromString
+#define PyUString_Format PyUnicode_Format
+
+#else
+
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytesObject PyStringObject
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_Size PyString_Size
+
+#define PyUString_Type PyString_Type
+#define PyUString_Check PyString_Check
+#define PyUStringObject PyStringObject
+#define PyUString_FromString PyString_FromString
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#define PyUString_FromFormat PyString_FromFormat
+#define PyUString_Concat PyString_Concat
+#define PyUString_ConcatAndDel PyString_ConcatAndDel
+#define PyUString_GET_SIZE PyString_GET_SIZE
+#define PyUString_Size PyString_Size
+#define PyUString_InternFromString PyString_InternFromString
+#define PyUString_Format PyString_Format
+
+#endif /* NPY_PY3K */
+
+
+static NPY_INLINE void
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    Py_DECREF(right);
+    *left = newobj;
+}
+
+static NPY_INLINE void
+PyUnicode_Concat2(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    *left = newobj;
+}
+
+/*
+ * PyFile_* compatibility
+ */
+#if defined(NPY_PY3K)
+/*
+ * Get a FILE* handle to the file represented by the Python object
+ */
+static NPY_INLINE FILE*
+npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
+{
+    int fd, fd2, unbuf;
+    PyObject *ret, *os, *io, *io_raw;
+    npy_off_t pos;
+    FILE *handle;
+
+    /* Flush first to ensure things end up in the file in the correct order */
+    ret = PyObject_CallMethod(file, "flush", "");
+    if (ret == NULL) {
+        return NULL;
+    }
+    Py_DECREF(ret);
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return NULL;
+    }
+
+    /*
+     * The handle needs to be dup'd because we have to call fclose
+     * at the end
+     */
+    os = PyImport_ImportModule("os");
+    if (os == NULL) {
+        return NULL;
+    }
+    ret = PyObject_CallMethod(os, "dup", "i", fd);
+    Py_DECREF(os);
+    if (ret == NULL) {
+        return NULL;
+    }
+    fd2 = PyNumber_AsSsize_t(ret, NULL);
+    Py_DECREF(ret);
+
+    /* Convert to FILE* handle */
+#ifdef _WIN32
+    handle = _fdopen(fd2, mode);
+#else
+    handle = fdopen(fd2, mode);
+#endif
+    if (handle == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "Getting a FILE* from a Python file object failed");
+    }
+
+    /* Record the original raw file handle position */
+    *orig_pos = npy_ftell(handle);
+    if (*orig_pos == -1) {
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return handle;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+            fclose(handle);
+            return NULL;
+        }
+    }
+
+    /* Seek raw handle to the Python-side position */
+    ret = PyObject_CallMethod(file, "tell", "");
+    if (ret == NULL) {
+        fclose(handle);
+        return NULL;
+    }
+    pos = PyLong_AsLongLong(ret);
+    Py_DECREF(ret);
+    if (PyErr_Occurred()) {
+        fclose(handle);
+        return NULL;
+    }
+    if (npy_fseek(handle, pos, SEEK_SET) == -1) {
+        PyErr_SetString(PyExc_IOError, "seeking file failed");
+        fclose(handle);
+        return NULL;
+    }
+    return handle;
+}
+
+/*
+ * Close the dup-ed file handle, and seek the Python one to the current position
+ */
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
+{
+    int fd, unbuf;
+    PyObject *ret, *io, *io_raw;
+    npy_off_t position;
+
+    position = npy_ftell(handle);
+
+    /* Close the FILE* handle */
+    fclose(handle);
+
+    /*
+     * Restore original file handle position, in order to not confuse
+     * Python-side data structures
+     */
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return -1;
+    }
+
+    if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
+
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            return -1;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            return -1;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return 0;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "seeking file failed");
+            return -1;
+        }
+    }
+
+    if (position == -1) {
+        PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+        return -1;
+    }
+
+    /* Seek Python-side handle to the FILE* handle position */
+    ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+static NPY_INLINE int
+npy_PyFile_Check(PyObject *file)
+{
+    int fd;
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        PyErr_Clear();
+        return 0;
+    }
+    return 1;
+}
+
+#else
+
+static NPY_INLINE FILE *
+npy_PyFile_Dup2(PyObject *file,
+                const char *NPY_UNUSED(mode), npy_off_t *NPY_UNUSED(orig_pos))
+{
+    FILE * fp = PyFile_AsFile(file);
+    if (fp == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "first argument must be an open file");
+        return NULL;
+    }
+    return fp;
+}
+
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *NPY_UNUSED(file), FILE* NPY_UNUSED(handle),
+                     npy_off_t NPY_UNUSED(orig_pos))
+{
+    return 0;
+}
+
+#define npy_PyFile_Check PyFile_Check
+
+#endif
+
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+{
+    PyObject *open;
+    open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+    if (open == NULL) {
+        return NULL;
+    }
+    return PyObject_CallFunction(open, "Os", filename, mode);
+}
+
+static NPY_INLINE int
+npy_PyFile_CloseFile(PyObject *file)
+{
+    PyObject *ret;
+
+    ret = PyObject_CallMethod(file, "close", NULL);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+/*
+ * PyObject_Cmp
+ */
+#if defined(NPY_PY3K)
+static NPY_INLINE int
+PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp)
+{
+    int v;
+    v = PyObject_RichCompareBool(i1, i2, Py_LT);
+    if (v == 1) {
+        *cmp = -1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_GT);
+    if (v == 1) {
+        *cmp = 1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_EQ);
+    if (v == 1) {
+        *cmp = 0;
+        return 1;
+    }
+    else {
+        *cmp = 0;
+        return -1;
+    }
+}
+#endif
+
+/*
+ * PyCObject functions adapted to PyCapsules.
+ *
+ * The main job here is to get rid of the improved error handling
+ * of PyCapsules. It's a shame...
+ */
+#if PY_VERSION_HEX >= 0x03000000
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *))
+{
+    PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor);
+    if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) {
+        PyErr_Clear();
+        Py_DECREF(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCapsule_GetContext(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context,
+        void (*dtor)(void *, void *))
+{
+    return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor);
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCObject_GetDesc(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NPY_3KCOMPAT_H_ */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
new file mode 100644
index 0000000000..baf5549d97
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
@@ -0,0 +1,1069 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+
+/* numpconfig.h is auto-generated */
+#include "numpyconfig.h"
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+
+/* need Python.h for npy_intp, npy_uintp */
+#include <Python.h>
+
+/*
+ * gcc does not unroll even with -O3
+ * use with care, unrolling on modern cpus rarely speeds things up
+ */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS
+#define NPY_GCC_UNROLL_LOOPS \
+    __attribute__((optimize("unroll-loops")))
+#else
+#define NPY_GCC_UNROLL_LOOPS
+#endif
+
+/* highest gcc optimization level, enabled autovectorizer */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3
+#define NPY_GCC_OPT_3 __attribute__((optimize("O3")))
+#else
+#define NPY_GCC_OPT_3
+#endif
+
+/*
+ * mark an argument (starting from 1) that must not be NULL and is not checked
+ * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check
+ */
+#ifdef HAVE_ATTRIBUTE_NONNULL
+#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n)))
+#else
+#define NPY_GCC_NONNULL(n)
+#endif
+
+#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS
+#define NPY_HAVE_SSE_INTRINSICS
+#endif
+
+#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD
+#define NPY_HAVE_SSE2_INTRINSICS
+#endif
+
+/*
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ *
+ * if (NPY_UNLIKELY(failure == 0))
+ *    return NULL;
+ *
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+ */
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#endif
+
+#ifdef HAVE___BUILTIN_PREFETCH
+/* unlike _mm_prefetch also works on non-x86 */
+#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc))
+#else
+#ifdef HAVE__MM_PREFETCH
+/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */
+#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \
+                                             (loc == 1 ? _MM_HINT_T2 : \
+                                              (loc == 2 ? _MM_HINT_T1 : \
+                                               (loc == 3 ? _MM_HINT_T0 : -1))))
+#else
+#define NPY_PREFETCH(x, rw,loc)
+#endif
+#endif
+
+#if defined(_MSC_VER)
+        #define NPY_INLINE __inline
+#elif defined(__GNUC__)
+	#if defined(__STRICT_ANSI__)
+		#define NPY_INLINE __inline__
+	#else
+		#define NPY_INLINE inline
+	#endif
+#else
+        #define NPY_INLINE
+#endif
+
+#ifdef HAVE___THREAD
+    #define NPY_TLS __thread
+#else
+    #ifdef HAVE___DECLSPEC_THREAD_
+        #define NPY_TLS __declspec(thread)
+    #else
+        #define NPY_TLS
+    #endif
+#endif
+
+#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE
+  #define NPY_RETURNS_BORROWED_REF \
+    __attribute__((cpychecker_returns_borrowed_ref))
+#else
+  #define NPY_RETURNS_BORROWED_REF
+#endif
+
+#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE
+  #define NPY_STEALS_REF_TO_ARG(n) \
+   __attribute__((cpychecker_steals_reference_to_arg(n)))
+#else
+ #define NPY_STEALS_REF_TO_ARG(n)
+#endif
+
+/* 64 bit file position support, also on win-amd64. Ticket #1660 */
+#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \
+    defined(__MINGW32__) || defined(__MINGW64__)
+    #include <io.h>
+
+/* mingw based on 3.4.5 has lseek but not ftell/fseek */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+extern int __cdecl _fseeki64(FILE *, long long, int);
+extern long long __cdecl _ftelli64(FILE *);
+#endif
+
+    #define npy_fseek _fseeki64
+    #define npy_ftell _ftelli64
+    #define npy_lseek _lseeki64
+    #define npy_off_t npy_int64
+
+    #if NPY_SIZEOF_INT == 8
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_LONG == 8
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_LONGLONG == 8
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#else
+#ifdef HAVE_FSEEKO
+    #define npy_fseek fseeko
+#else
+    #define npy_fseek fseek
+#endif
+#ifdef HAVE_FTELLO
+    #define npy_ftell ftello
+#else
+    #define npy_ftell ftell
+#endif
+    #include <sys/types.h>
+    #define npy_lseek lseek
+    #define npy_off_t off_t
+
+    #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT
+        #define NPY_OFF_T_PYFMT "h"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#endif
+
+/* enums for detected endianness */
+enum {
+        NPY_CPU_UNKNOWN_ENDIAN,
+        NPY_CPU_LITTLE,
+        NPY_CPU_BIG
+};
+
+/*
+ * This is to typedef npy_intp to the appropriate pointer size for this
+ * platform.  Py_intptr_t, Py_uintptr_t are defined in pyport.h.
+ */
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+
+/*
+ * Define sizes that were not defined in numpyconfig.h.
+ */
+#define NPY_SIZEOF_CHAR 1
+#define NPY_SIZEOF_BYTE 1
+#define NPY_SIZEOF_DATETIME 8
+#define NPY_SIZEOF_TIMEDELTA 8
+#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_HALF 2
+#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT
+#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE
+#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE
+
+#ifdef constchar
+#undef constchar
+#endif
+
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+
+/* NPY_INTP_FMT Note:
+ *      Unlike the other NPY_*_FMT macros which are used with
+ *      PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and
+ *      PyString_Format. These functions use different formatting
+ *      codes which are portably specified according to the Python
+ *      documentation. See ticket #1795.
+ *
+ *      On Windows x64, the LONGLONG formatter should be used, but
+ *      in Python 2.6 the %lld formatter is not supported. In this
+ *      case we work around the problem by using the %zd formatter.
+ */
+#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT
+        #define NPY_INTP NPY_INT
+        #define NPY_UINTP NPY_UINT
+        #define PyIntpArrType_Type PyIntArrType_Type
+        #define PyUIntpArrType_Type PyUIntArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_INT
+        #define NPY_MIN_INTP NPY_MIN_INT
+        #define NPY_MAX_UINTP NPY_MAX_UINT
+        #define NPY_INTP_FMT "d"
+#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG
+        #define NPY_INTP NPY_LONG
+        #define NPY_UINTP NPY_ULONG
+        #define PyIntpArrType_Type PyLongArrType_Type
+        #define PyUIntpArrType_Type PyULongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONG
+        #define NPY_MIN_INTP NPY_MIN_LONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONG
+        #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG)
+        #define NPY_INTP NPY_LONGLONG
+        #define NPY_UINTP NPY_ULONGLONG
+        #define PyIntpArrType_Type PyLongLongArrType_Type
+        #define PyUIntpArrType_Type PyULongLongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONGLONG
+        #define NPY_MIN_INTP NPY_MIN_LONGLONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+    #if (PY_VERSION_HEX >= 0x02070000)
+        #define NPY_INTP_FMT "lld"
+    #else
+        #define NPY_INTP_FMT "zd"
+    #endif
+#endif
+
+/*
+ * We can only use C99 formats for npy_int_p if it is the same as
+ * intp_t, hence the condition on HAVE_UNITPTR_T
+ */
+#if (NPY_USE_C99_FORMATS) == 1 \
+        && (defined HAVE_UINTPTR_T) \
+        && (defined HAVE_INTTYPES_H)
+        #include <inttypes.h>
+        #undef NPY_INTP_FMT
+        #define NPY_INTP_FMT PRIdPTR
+#endif
+
+
+/*
+ * Some platforms don't define bool, long long, or long double.
+ * Handle that here.
+ */
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_HALF_FMT "g"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_FMT         "I64d"
+#    define NPY_ULONGLONG_FMT        "I64u"
+#  else
+#    define NPY_LONGLONG_FMT         "lld"
+#    define NPY_ULONGLONG_FMT        "llu"
+#  endif
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_SUFFIX(x)   (x##i64)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##Ui64)
+#  else
+#    define NPY_LONGLONG_SUFFIX(x)   (x##LL)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##ULL)
+#  endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+#  define NPY_LONGLONG_SUFFIX(x)  (x##L)
+#  define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+        typedef double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "g"
+#else
+        typedef long double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+/* These are for completeness */
+typedef char npy_char;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+typedef float npy_float;
+typedef double npy_double;
+
+/*
+ * Hash value compatibility.
+ * As of Python 3.2 hash values are of type Py_hash_t.
+ * Previous versions use C long.
+ */
+#if PY_VERSION_HEX < 0x03020000
+typedef long npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_LONG
+#else
+typedef Py_hash_t npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP
+#endif
+
+/*
+ * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being
+ * able to do .real/.imag. Will have to convert code first.
+ */
+#if 0
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE)
+typedef complex npy_cdouble;
+#else
+typedef struct { double real, imag; } npy_cdouble;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT)
+typedef complex float npy_cfloat;
+#else
+typedef struct { float real, imag; } npy_cfloat;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE)
+typedef complex long double npy_clongdouble;
+#else
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+#endif
+#endif
+#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE
+#error npy_cdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { double real, imag; } npy_cdouble;
+
+#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT
+#error npy_cfloat definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { float real, imag; } npy_cfloat;
+
+#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE
+#error npy_clongdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { npy_longdouble real, imag; } npy_clongdouble;
+
+/*
+ * numarray-style bit-width typedefs
+ */
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define NPY_MIN_DATETIME NPY_MIN_INT64
+#define NPY_MAX_DATETIME NPY_MAX_INT64
+#define NPY_MIN_TIMEDELTA NPY_MIN_INT64
+#define NPY_MAX_TIMEDELTA NPY_MAX_INT64
+
+        /* Need to find the number of bits for each type and
+           make definitions accordingly.
+
+           C states that sizeof(char) == 1 by definition
+
+           So, just using the sizeof keyword won't help.
+
+           It also looks like Python itself uses sizeof(char) quite a
+           bit, which by definition should be 1 all the time.
+
+           Idea: Make Use of CHAR_BIT which should tell us how many
+           BITS per CHARACTER
+        */
+
+        /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT   INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif
+#define NPY_MIN_INT   INT_MIN
+#define NPY_MAX_UINT  UINT_MAX
+#define NPY_MAX_LONG  LONG_MAX
+#define NPY_MIN_LONG  LONG_MIN
+#define NPY_MAX_ULONG  ULONG_MAX
+
+#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT)
+#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT)
+#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT)
+#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT)
+#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT)
+#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT)
+#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT)
+#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT)
+#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT)
+
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+        typedef long npy_int8;
+        typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+        typedef long npy_int16;
+        typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+        typedef long npy_int32;
+        typedef unsigned long npy_uint32;
+        typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+        typedef long npy_int64;
+        typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#define MyPyLong_FromInt64 PyLong_FromLong
+#define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+        typedef long npy_int128;
+        typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#endif
+
+#if NPY_BITSOF_LONGLONG == 8
+#  ifndef NPY_INT8
+#    define NPY_INT8 NPY_LONGLONG
+#    define NPY_UINT8 NPY_ULONGLONG
+        typedef npy_longlong npy_int8;
+        typedef npy_ulonglong npy_uint8;
+#    define PyInt8ScalarObject PyLongLongScalarObject
+#    define PyInt8ArrType_Type PyLongLongArrType_Type
+#    define PyUInt8ScalarObject PyULongLongScalarObject
+#    define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT8
+#  define NPY_MIN_LONGLONG NPY_MIN_INT8
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+#  ifndef NPY_INT16
+#    define NPY_INT16 NPY_LONGLONG
+#    define NPY_UINT16 NPY_ULONGLONG
+        typedef npy_longlong npy_int16;
+        typedef npy_ulonglong npy_uint16;
+#    define PyInt16ScalarObject PyLongLongScalarObject
+#    define PyInt16ArrType_Type PyLongLongArrType_Type
+#    define PyUInt16ScalarObject PyULongLongScalarObject
+#    define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT16
+#  define NPY_MIN_LONGLONG NPY_MIN_INT16
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+#  ifndef NPY_INT32
+#    define NPY_INT32 NPY_LONGLONG
+#    define NPY_UINT32 NPY_ULONGLONG
+        typedef npy_longlong npy_int32;
+        typedef npy_ulonglong npy_uint32;
+        typedef npy_ulonglong npy_ucs4;
+#    define PyInt32ScalarObject PyLongLongScalarObject
+#    define PyInt32ArrType_Type PyLongLongArrType_Type
+#    define PyUInt32ScalarObject PyULongLongScalarObject
+#    define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT32
+#  define NPY_MIN_LONGLONG NPY_MIN_INT32
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+#  ifndef NPY_INT64
+#    define NPY_INT64 NPY_LONGLONG
+#    define NPY_UINT64 NPY_ULONGLONG
+        typedef npy_longlong npy_int64;
+        typedef npy_ulonglong npy_uint64;
+#    define PyInt64ScalarObject PyLongLongScalarObject
+#    define PyInt64ArrType_Type PyLongLongArrType_Type
+#    define PyUInt64ScalarObject PyULongLongScalarObject
+#    define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLongLong
+#    define MyPyLong_AsInt64 PyLong_AsLongLong
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT64
+#  define NPY_MIN_LONGLONG NPY_MIN_INT64
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+#  ifndef NPY_INT128
+#    define NPY_INT128 NPY_LONGLONG
+#    define NPY_UINT128 NPY_ULONGLONG
+        typedef npy_longlong npy_int128;
+        typedef npy_ulonglong npy_uint128;
+#    define PyInt128ScalarObject PyLongLongScalarObject
+#    define PyInt128ArrType_Type PyLongLongArrType_Type
+#    define PyUInt128ScalarObject PyULongLongScalarObject
+#    define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT128
+#  define NPY_MIN_LONGLONG NPY_MIN_INT128
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+#  define NPY_INT256 NPY_LONGLONG
+#  define NPY_UINT256 NPY_ULONGLONG
+        typedef npy_longlong npy_int256;
+        typedef npy_ulonglong npy_uint256;
+#  define PyInt256ScalarObject PyLongLongScalarObject
+#  define PyInt256ArrType_Type PyLongLongArrType_Type
+#  define PyUInt256ScalarObject PyULongLongScalarObject
+#  define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+#  define NPY_MAX_LONGLONG NPY_MAX_INT256
+#  define NPY_MIN_LONGLONG NPY_MIN_INT256
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#endif
+
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+        typedef int npy_int8;
+        typedef unsigned int npy_uint8;
+#    define PyInt8ScalarObject PyIntScalarObject
+#    define PyInt8ArrType_Type PyIntArrType_Type
+#    define PyUInt8ScalarObject PyUIntScalarObject
+#    define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+        typedef int npy_int16;
+        typedef unsigned int npy_uint16;
+#    define PyInt16ScalarObject PyIntScalarObject
+#    define PyInt16ArrType_Type PyIntArrType_Type
+#    define PyUInt16ScalarObject PyIntUScalarObject
+#    define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+        typedef int npy_int32;
+        typedef unsigned int npy_uint32;
+        typedef unsigned int npy_ucs4;
+#    define PyInt32ScalarObject PyIntScalarObject
+#    define PyInt32ArrType_Type PyIntArrType_Type
+#    define PyUInt32ScalarObject PyUIntScalarObject
+#    define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+        typedef int npy_int64;
+        typedef unsigned int npy_uint64;
+#    define PyInt64ScalarObject PyIntScalarObject
+#    define PyInt64ArrType_Type PyIntArrType_Type
+#    define PyUInt64ScalarObject PyUIntScalarObject
+#    define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+        typedef int npy_int128;
+        typedef unsigned int npy_uint128;
+#    define PyInt128ScalarObject PyIntScalarObject
+#    define PyInt128ArrType_Type PyIntArrType_Type
+#    define PyUInt128ScalarObject PyUIntScalarObject
+#    define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#endif
+#endif
+
+#if NPY_BITSOF_SHORT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+        typedef short npy_int8;
+        typedef unsigned short npy_uint8;
+#    define PyInt8ScalarObject PyShortScalarObject
+#    define PyInt8ArrType_Type PyShortArrType_Type
+#    define PyUInt8ScalarObject PyUShortScalarObject
+#    define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+        typedef short npy_int16;
+        typedef unsigned short npy_uint16;
+#    define PyInt16ScalarObject PyShortScalarObject
+#    define PyInt16ArrType_Type PyShortArrType_Type
+#    define PyUInt16ScalarObject PyUShortScalarObject
+#    define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+        typedef short npy_int32;
+        typedef unsigned short npy_uint32;
+        typedef unsigned short npy_ucs4;
+#    define PyInt32ScalarObject PyShortScalarObject
+#    define PyInt32ArrType_Type PyShortArrType_Type
+#    define PyUInt32ScalarObject PyUShortScalarObject
+#    define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+        typedef short npy_int64;
+        typedef unsigned short npy_uint64;
+#    define PyInt64ScalarObject PyShortScalarObject
+#    define PyInt64ArrType_Type PyShortArrType_Type
+#    define PyUInt64ScalarObject PyUShortScalarObject
+#    define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_SHORT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+        typedef short npy_int128;
+        typedef unsigned short npy_uint128;
+#    define PyInt128ScalarObject PyShortScalarObject
+#    define PyInt128ArrType_Type PyShortArrType_Type
+#    define PyUInt128ScalarObject PyUShortScalarObject
+#    define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_CHAR == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+        typedef signed char npy_int8;
+        typedef unsigned char npy_uint8;
+#    define PyInt8ScalarObject PyByteScalarObject
+#    define PyInt8ArrType_Type PyByteArrType_Type
+#    define PyUInt8ScalarObject PyUByteScalarObject
+#    define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+        typedef signed char npy_int16;
+        typedef unsigned char npy_uint16;
+#    define PyInt16ScalarObject PyByteScalarObject
+#    define PyInt16ArrType_Type PyByteArrType_Type
+#    define PyUInt16ScalarObject PyUByteScalarObject
+#    define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+        typedef signed char npy_int32;
+        typedef unsigned char npy_uint32;
+        typedef unsigned char npy_ucs4;
+#    define PyInt32ScalarObject PyByteScalarObject
+#    define PyInt32ArrType_Type PyByteArrType_Type
+#    define PyUInt32ScalarObject PyUByteScalarObject
+#    define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+        typedef signed char npy_int64;
+        typedef unsigned char npy_uint64;
+#    define PyInt64ScalarObject PyByteScalarObject
+#    define PyInt64ArrType_Type PyByteArrType_Type
+#    define PyUInt64ScalarObject PyUByteScalarObject
+#    define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_CHAR == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+        typedef signed char npy_int128;
+        typedef unsigned char npy_uint128;
+#    define PyInt128ScalarObject PyByteScalarObject
+#    define PyInt128ArrType_Type PyByteArrType_Type
+#    define PyUInt128ScalarObject PyUByteScalarObject
+#    define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+        typedef double npy_float32;
+        typedef npy_cdouble npy_complex64;
+#    define PyFloat32ScalarObject PyDoubleScalarObject
+#    define PyComplex64ScalarObject PyCDoubleScalarObject
+#    define PyFloat32ArrType_Type PyDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+        typedef double npy_float64;
+        typedef npy_cdouble npy_complex128;
+#    define PyFloat64ScalarObject PyDoubleScalarObject
+#    define PyComplex128ScalarObject PyCDoubleScalarObject
+#    define PyFloat64ArrType_Type PyDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+        typedef double npy_float80;
+        typedef npy_cdouble npy_complex160;
+#    define PyFloat80ScalarObject PyDoubleScalarObject
+#    define PyComplex160ScalarObject PyCDoubleScalarObject
+#    define PyFloat80ArrType_Type PyDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+        typedef double npy_float96;
+        typedef npy_cdouble npy_complex192;
+#    define PyFloat96ScalarObject PyDoubleScalarObject
+#    define PyComplex192ScalarObject PyCDoubleScalarObject
+#    define PyFloat96ArrType_Type PyDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+        typedef double npy_float128;
+        typedef npy_cdouble npy_complex256;
+#    define PyFloat128ScalarObject PyDoubleScalarObject
+#    define PyComplex256ScalarObject PyCDoubleScalarObject
+#    define PyFloat128ArrType_Type PyDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_FLOAT == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+        typedef float npy_float32;
+        typedef npy_cfloat npy_complex64;
+#    define PyFloat32ScalarObject PyFloatScalarObject
+#    define PyComplex64ScalarObject PyCFloatScalarObject
+#    define PyFloat32ArrType_Type PyFloatArrType_Type
+#    define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+        typedef float npy_float64;
+        typedef npy_cfloat npy_complex128;
+#    define PyFloat64ScalarObject PyFloatScalarObject
+#    define PyComplex128ScalarObject PyCFloatScalarObject
+#    define PyFloat64ArrType_Type PyFloatArrType_Type
+#    define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+        typedef float npy_float80;
+        typedef npy_cfloat npy_complex160;
+#    define PyFloat80ScalarObject PyFloatScalarObject
+#    define PyComplex160ScalarObject PyCFloatScalarObject
+#    define PyFloat80ArrType_Type PyFloatArrType_Type
+#    define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+        typedef float npy_float96;
+        typedef npy_cfloat npy_complex192;
+#    define PyFloat96ScalarObject PyFloatScalarObject
+#    define PyComplex192ScalarObject PyCFloatScalarObject
+#    define PyFloat96ArrType_Type PyFloatArrType_Type
+#    define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+        typedef float npy_float128;
+        typedef npy_cfloat npy_complex256;
+#    define PyFloat128ScalarObject PyFloatScalarObject
+#    define PyComplex256ScalarObject PyCFloatScalarObject
+#    define PyFloat128ArrType_Type PyFloatArrType_Type
+#    define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+#endif
+#endif
+
+/* half/float16 isn't a floating-point type in C */
+#define NPY_FLOAT16 NPY_HALF
+typedef npy_uint16 npy_half;
+typedef npy_half npy_float16;
+
+#if NPY_BITSOF_LONGDOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float32;
+        typedef npy_clongdouble npy_complex64;
+#    define PyFloat32ScalarObject PyLongDoubleScalarObject
+#    define PyComplex64ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float64;
+        typedef npy_clongdouble npy_complex128;
+#    define PyFloat64ScalarObject PyLongDoubleScalarObject
+#    define PyComplex128ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float80;
+        typedef npy_clongdouble npy_complex160;
+#    define PyFloat80ScalarObject PyLongDoubleScalarObject
+#    define PyComplex160ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float96;
+        typedef npy_clongdouble npy_complex192;
+#    define PyFloat96ScalarObject PyLongDoubleScalarObject
+#    define PyComplex192ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float128;
+        typedef npy_clongdouble npy_complex256;
+#    define PyFloat128ScalarObject PyLongDoubleScalarObject
+#    define PyComplex256ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float256;
+        typedef npy_clongdouble npy_complex512;
+#    define PyFloat256ScalarObject PyLongDoubleScalarObject
+#    define PyComplex512ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+#endif
+
+/* datetime typedefs */
+typedef npy_int64 npy_timedelta;
+typedef npy_int64 npy_datetime;
+#define NPY_DATETIME_FMT NPY_INT64_FMT
+#define NPY_TIMEDELTA_FMT NPY_INT64_FMT
+
+/* End of typedefs for numarray style bit-width names */
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
new file mode 100644
index 0000000000..60abae4e0b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
@@ -0,0 +1,92 @@
+/*
+ * This set (target) cpu specific macros:
+ *      - Possible values:
+ *              NPY_CPU_X86
+ *              NPY_CPU_AMD64
+ *              NPY_CPU_PPC
+ *              NPY_CPU_PPC64
+ *              NPY_CPU_PPC64LE
+ *              NPY_CPU_SPARC
+ *              NPY_CPU_S390
+ *              NPY_CPU_IA64
+ *              NPY_CPU_HPPA
+ *              NPY_CPU_ALPHA
+ *              NPY_CPU_ARMEL
+ *              NPY_CPU_ARMEB
+ *              NPY_CPU_SH_LE
+ *              NPY_CPU_SH_BE
+ */
+#ifndef _NPY_CPUARCH_H_
+#define _NPY_CPUARCH_H_
+
+#include "numpyconfig.h"
+#include <string.h> /* for memcpy */
+
+#if defined( __i386__ ) || defined(i386) || defined(_M_IX86)
+    /*
+     * __i386__ is defined by gcc and Intel compiler on Linux,
+     * _M_IX86 by VS compiler,
+     * i386 by Sun compilers on opensolaris at least
+     */
+    #define NPY_CPU_X86
+#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64)
+    /*
+     * both __x86_64__ and __amd64__ are defined by gcc
+     * __x86_64 defined by sun compiler on opensolaris at least
+     * _M_AMD64 defined by MS compiler
+     */
+    #define NPY_CPU_AMD64
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC)
+    /*
+     * __ppc__ is defined by gcc, I remember having seen __powerpc__ once,
+     * but can't find it ATM
+     * _ARCH_PPC is used by at least gcc on AIX
+     */
+    #define NPY_CPU_PPC
+#elif defined(__ppc64le__)
+    #define NPY_CPU_PPC64LE
+#elif defined(__ppc64__)
+    #define NPY_CPU_PPC64
+#elif defined(__sparc__) || defined(__sparc)
+    /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */
+    #define NPY_CPU_SPARC
+#elif defined(__s390__)
+    #define NPY_CPU_S390
+#elif defined(__ia64)
+    #define NPY_CPU_IA64
+#elif defined(__hppa)
+    #define NPY_CPU_HPPA
+#elif defined(__alpha__)
+    #define NPY_CPU_ALPHA
+#elif defined(__arm__) && defined(__ARMEL__)
+    #define NPY_CPU_ARMEL
+#elif defined(__arm__) && defined(__ARMEB__)
+    #define NPY_CPU_ARMEB
+#elif defined(__sh__) && defined(__LITTLE_ENDIAN__)
+    #define NPY_CPU_SH_LE
+#elif defined(__sh__) && defined(__BIG_ENDIAN__)
+    #define NPY_CPU_SH_BE
+#elif defined(__MIPSEL__)
+    #define NPY_CPU_MIPSEL
+#elif defined(__MIPSEB__)
+    #define NPY_CPU_MIPSEB
+#elif defined(__or1k__)
+    #define NPY_CPU_OR1K
+#elif defined(__aarch64__)
+    #define NPY_CPU_AARCH64
+#elif defined(__mc68000__)
+    #define NPY_CPU_M68K
+#else
+    #error Unknown CPU, please report this to numpy maintainers with \
+    information about your platform (OS, CPU and compiler)
+#endif
+
+#define NPY_COPY_PYOBJECT_PTR(dst, src) memcpy(dst, src, sizeof(PyObject *))
+
+#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
+#else
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
new file mode 100644
index 0000000000..a8ec572458
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
@@ -0,0 +1,61 @@
+#ifndef _NPY_ENDIAN_H_
+#define _NPY_ENDIAN_H_
+
+/*
+ * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in
+ * endian.h
+ */
+
+#ifdef NPY_HAVE_ENDIAN_H
+    /* Use endian.h if available */
+    #include <endian.h>
+
+    #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    BIG_ENDIAN
+    #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    _BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    _BIG_ENDIAN
+    #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    __BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    __BIG_ENDIAN
+    #endif
+#endif
+
+#ifndef NPY_BYTE_ORDER
+    /* Set endianness info using target CPU */
+    #include "npy_cpu.h"
+
+    #define NPY_LITTLE_ENDIAN 1234
+    #define NPY_BIG_ENDIAN 4321
+
+    #if defined(NPY_CPU_X86)            \
+            || defined(NPY_CPU_AMD64)   \
+            || defined(NPY_CPU_IA64)    \
+            || defined(NPY_CPU_ALPHA)   \
+            || defined(NPY_CPU_ARMEL)   \
+            || defined(NPY_CPU_AARCH64) \
+            || defined(NPY_CPU_SH_LE)   \
+            || defined(NPY_CPU_MIPSEL)  \
+            || defined(NPY_CPU_PPC64LE)
+        #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
+    #elif defined(NPY_CPU_PPC)          \
+            || defined(NPY_CPU_SPARC)   \
+            || defined(NPY_CPU_S390)    \
+            || defined(NPY_CPU_HPPA)    \
+            || defined(NPY_CPU_PPC64)   \
+            || defined(NPY_CPU_ARMEB)   \
+            || defined(NPY_CPU_SH_BE)   \
+            || defined(NPY_CPU_MIPSEB)  \
+            || defined(NPY_CPU_OR1K)    \
+            || defined(NPY_CPU_M68K)
+        #define NPY_BYTE_ORDER NPY_BIG_ENDIAN
+    #else
+        #error Unknown CPU: can not set endianness
+    #endif
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
new file mode 100644
index 0000000000..f71fd689eb
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
@@ -0,0 +1,117 @@
+
+/* Signal handling:
+
+This header file defines macros that allow your code to handle
+interrupts received during processing.  Interrupts that
+could reasonably be handled:
+
+SIGINT, SIGABRT, SIGALRM, SIGSEGV
+
+****Warning***************
+
+Do not allow code that creates temporary memory or increases reference
+counts of Python objects to be interrupted unless you handle it
+differently.
+
+**************************
+
+The mechanism for handling interrupts is conceptually simple:
+
+  - replace the signal handler with our own home-grown version
+     and store the old one.
+  - run the code to be interrupted -- if an interrupt occurs
+     the handler should basically just cause a return to the
+     calling function for finish work.
+  - restore the old signal handler
+
+Of course, every code that allows interrupts must account for
+returning via the interrupt and handle clean-up correctly.  But,
+even still, the simple paradigm is complicated by at least three
+factors.
+
+ 1) platform portability (i.e. Microsoft says not to use longjmp
+     to return from signal handling.  They have a __try  and __except
+     extension to C instead but what about mingw?).
+
+ 2) how to handle threads: apparently whether signals are delivered to
+    every thread of the process or the "invoking" thread is platform
+    dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance.  For now, assume the
+    code will not call-back into itself.
+
+Ideas:
+
+ 1) Start by implementing an approach that works on platforms that
+    can use setjmp and longjmp functionality and does nothing
+    on other platforms.
+
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
+
+ 3) Add a default signal_handler function to the C-API but have the rest
+    use macros.
+
+
+Simple Interface:
+
+
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
+[code]
+NPY_SIGINT_OFF
+
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects.  In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
+
+Interrupt handling does not work well with threads.
+
+*/
+
+/* Add signal handling macros
+   Make the global variable and signal handler part of the C-API
+*/
+
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef sigsetjmp
+
+#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF jmp_buf
+
+#else
+
+#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF sigjmp_buf
+
+#endif
+
+#    define NPY_SIGINT_ON {                                             \
+                   PyOS_sighandler_t _npy_sig_save;                     \
+                   _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+                   if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+                                 1) == 0) {                             \
+
+#    define NPY_SIGINT_OFF }                                      \
+        PyOS_setsig(SIGINT, _npy_sig_save);                       \
+        }
+
+#else /* NPY_NO_SIGNAL  */
+
+#define NPY_SIGINT_ON
+#define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
+#endif /* NPY_INTERRUPT_H */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
new file mode 100644
index 0000000000..e76508de04
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
@@ -0,0 +1,529 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#ifdef __SUNPRO_CC
+#include <sunmath.h>
+#endif
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+#include <numpy/npy_common.h>
+
+
+/*
+ * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
+ * for INFINITY)
+ *
+ * XXX: I should test whether INFINITY and NAN are available on the platform
+ */
+NPY_INLINE static float __npy_inff(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nanf(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_pzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL};
+    return __bint.__f;
+}
+
+#define NPY_INFINITYF __npy_inff()
+#define NPY_NANF __npy_nanf()
+#define NPY_PZEROF __npy_pzerof()
+#define NPY_NZEROF __npy_nzerof()
+
+#define NPY_INFINITY ((npy_double)NPY_INFINITYF)
+#define NPY_NAN ((npy_double)NPY_NANF)
+#define NPY_PZERO ((npy_double)NPY_PZEROF)
+#define NPY_NZERO ((npy_double)NPY_NZEROF)
+
+#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF)
+#define NPY_NANL ((npy_longdouble)NPY_NANF)
+#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF)
+#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF)
+
+/*
+ * Useful constants
+ */
+#define NPY_E         2.718281828459045235360287471352662498  /* e */
+#define NPY_LOG2E     1.442695040888963407359924681001892137  /* log_2 e */
+#define NPY_LOG10E    0.434294481903251827651128918916605082  /* log_10 e */
+#define NPY_LOGE2     0.693147180559945309417232121458176568  /* log_e 2 */
+#define NPY_LOGE10    2.302585092994045684017991454684364208  /* log_e 10 */
+#define NPY_PI        3.141592653589793238462643383279502884  /* pi */
+#define NPY_PI_2      1.570796326794896619231321691639751442  /* pi/2 */
+#define NPY_PI_4      0.785398163397448309615660845819875721  /* pi/4 */
+#define NPY_1_PI      0.318309886183790671537767526745028724  /* 1/pi */
+#define NPY_2_PI      0.636619772367581343075535053490057448  /* 2/pi */
+#define NPY_EULER     0.577215664901532860606512090082402431  /* Euler constant */
+#define NPY_SQRT2     1.414213562373095048801688724209698079  /* sqrt(2) */
+#define NPY_SQRT1_2   0.707106781186547524400844362104849039  /* 1/sqrt(2) */
+
+#define NPY_Ef        2.718281828459045235360287471352662498F /* e */
+#define NPY_LOG2Ef    1.442695040888963407359924681001892137F /* log_2 e */
+#define NPY_LOG10Ef   0.434294481903251827651128918916605082F /* log_10 e */
+#define NPY_LOGE2f    0.693147180559945309417232121458176568F /* log_e 2 */
+#define NPY_LOGE10f   2.302585092994045684017991454684364208F /* log_e 10 */
+#define NPY_PIf       3.141592653589793238462643383279502884F /* pi */
+#define NPY_PI_2f     1.570796326794896619231321691639751442F /* pi/2 */
+#define NPY_PI_4f     0.785398163397448309615660845819875721F /* pi/4 */
+#define NPY_1_PIf     0.318309886183790671537767526745028724F /* 1/pi */
+#define NPY_2_PIf     0.636619772367581343075535053490057448F /* 2/pi */
+#define NPY_EULERf    0.577215664901532860606512090082402431F /* Euler constant */
+#define NPY_SQRT2f    1.414213562373095048801688724209698079F /* sqrt(2) */
+#define NPY_SQRT1_2f  0.707106781186547524400844362104849039F /* 1/sqrt(2) */
+
+#define NPY_El        2.718281828459045235360287471352662498L /* e */
+#define NPY_LOG2El    1.442695040888963407359924681001892137L /* log_2 e */
+#define NPY_LOG10El   0.434294481903251827651128918916605082L /* log_10 e */
+#define NPY_LOGE2l    0.693147180559945309417232121458176568L /* log_e 2 */
+#define NPY_LOGE10l   2.302585092994045684017991454684364208L /* log_e 10 */
+#define NPY_PIl       3.141592653589793238462643383279502884L /* pi */
+#define NPY_PI_2l     1.570796326794896619231321691639751442L /* pi/2 */
+#define NPY_PI_4l     0.785398163397448309615660845819875721L /* pi/4 */
+#define NPY_1_PIl     0.318309886183790671537767526745028724L /* 1/pi */
+#define NPY_2_PIl     0.636619772367581343075535053490057448L /* 2/pi */
+#define NPY_EULERl    0.577215664901532860606512090082402431L /* Euler constant */
+#define NPY_SQRT2l    1.414213562373095048801688724209698079L /* sqrt(2) */
+#define NPY_SQRT1_2l  0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+
+/*
+ * C99 double math funcs
+ */
+double npy_sin(double x);
+double npy_cos(double x);
+double npy_tan(double x);
+double npy_sinh(double x);
+double npy_cosh(double x);
+double npy_tanh(double x);
+
+double npy_asin(double x);
+double npy_acos(double x);
+double npy_atan(double x);
+
+double npy_log(double x);
+double npy_log10(double x);
+double npy_exp(double x);
+double npy_sqrt(double x);
+double npy_cbrt(double x);
+
+double npy_fabs(double x);
+double npy_ceil(double x);
+double npy_fmod(double x, double y);
+double npy_floor(double x);
+
+double npy_expm1(double x);
+double npy_log1p(double x);
+double npy_hypot(double x, double y);
+double npy_acosh(double x);
+double npy_asinh(double xx);
+double npy_atanh(double x);
+double npy_rint(double x);
+double npy_trunc(double x);
+double npy_exp2(double x);
+double npy_log2(double x);
+
+double npy_atan2(double x, double y);
+double npy_pow(double x, double y);
+double npy_modf(double x, double* y);
+double npy_frexp(double x, int* y);
+double npy_ldexp(double n, int y);
+
+double npy_copysign(double x, double y);
+double npy_nextafter(double x, double y);
+double npy_spacing(double x);
+
+/*
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+ */
+
+/* use builtins to avoid function calls in tight loops
+ * only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISNAN
+    #define npy_isnan(x) __builtin_isnan(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISNAN
+        #define npy_isnan(x) ((x) != (x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isnan(x) _isnan((x))
+        #else
+            #define npy_isnan(x) isnan(x)
+        #endif
+    #endif
+#endif
+
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISFINITE
+    #define npy_isfinite(x) __builtin_isfinite(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISFINITE
+        #ifdef _MSC_VER
+            #define npy_isfinite(x) _finite((x))
+        #else
+            #define npy_isfinite(x) !npy_isnan((x) + (-x))
+        #endif
+    #else
+        #define npy_isfinite(x) isfinite((x))
+    #endif
+#endif
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISINF
+    #define npy_isinf(x) __builtin_isinf(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISINF
+        #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+        #else
+            #define npy_isinf(x) isinf((x))
+        #endif
+    #endif
+#endif
+
+#ifndef NPY_HAVE_DECL_SIGNBIT
+    int _npy_signbit_f(float x);
+    int _npy_signbit_d(double x);
+    int _npy_signbit_ld(long double x);
+    #define npy_signbit(x) \
+        (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+         : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+         : _npy_signbit_f (x))
+#else
+    #define npy_signbit(x) signbit((x))
+#endif
+
+/*
+ * float C99 math functions
+ */
+
+float npy_sinf(float x);
+float npy_cosf(float x);
+float npy_tanf(float x);
+float npy_sinhf(float x);
+float npy_coshf(float x);
+float npy_tanhf(float x);
+float npy_fabsf(float x);
+float npy_floorf(float x);
+float npy_ceilf(float x);
+float npy_rintf(float x);
+float npy_truncf(float x);
+float npy_sqrtf(float x);
+float npy_cbrtf(float x);
+float npy_log10f(float x);
+float npy_logf(float x);
+float npy_expf(float x);
+float npy_expm1f(float x);
+float npy_asinf(float x);
+float npy_acosf(float x);
+float npy_atanf(float x);
+float npy_asinhf(float x);
+float npy_acoshf(float x);
+float npy_atanhf(float x);
+float npy_log1pf(float x);
+float npy_exp2f(float x);
+float npy_log2f(float x);
+
+float npy_atan2f(float x, float y);
+float npy_hypotf(float x, float y);
+float npy_powf(float x, float y);
+float npy_fmodf(float x, float y);
+
+float npy_modff(float x, float* y);
+float npy_frexpf(float x, int* y);
+float npy_ldexpf(float x, int y);
+
+float npy_copysignf(float x, float y);
+float npy_nextafterf(float x, float y);
+float npy_spacingf(float x);
+
+/*
+ * long double C99 math functions
+ */
+
+npy_longdouble npy_sinl(npy_longdouble x);
+npy_longdouble npy_cosl(npy_longdouble x);
+npy_longdouble npy_tanl(npy_longdouble x);
+npy_longdouble npy_sinhl(npy_longdouble x);
+npy_longdouble npy_coshl(npy_longdouble x);
+npy_longdouble npy_tanhl(npy_longdouble x);
+npy_longdouble npy_fabsl(npy_longdouble x);
+npy_longdouble npy_floorl(npy_longdouble x);
+npy_longdouble npy_ceill(npy_longdouble x);
+npy_longdouble npy_rintl(npy_longdouble x);
+npy_longdouble npy_truncl(npy_longdouble x);
+npy_longdouble npy_sqrtl(npy_longdouble x);
+npy_longdouble npy_cbrtl(npy_longdouble x);
+npy_longdouble npy_log10l(npy_longdouble x);
+npy_longdouble npy_logl(npy_longdouble x);
+npy_longdouble npy_expl(npy_longdouble x);
+npy_longdouble npy_expm1l(npy_longdouble x);
+npy_longdouble npy_asinl(npy_longdouble x);
+npy_longdouble npy_acosl(npy_longdouble x);
+npy_longdouble npy_atanl(npy_longdouble x);
+npy_longdouble npy_asinhl(npy_longdouble x);
+npy_longdouble npy_acoshl(npy_longdouble x);
+npy_longdouble npy_atanhl(npy_longdouble x);
+npy_longdouble npy_log1pl(npy_longdouble x);
+npy_longdouble npy_exp2l(npy_longdouble x);
+npy_longdouble npy_log2l(npy_longdouble x);
+
+npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+
+npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_spacingl(npy_longdouble x);
+
+/*
+ * Non standard functions
+ */
+double npy_deg2rad(double x);
+double npy_rad2deg(double x);
+double npy_logaddexp(double x, double y);
+double npy_logaddexp2(double x, double y);
+double npy_divmod(double x, double y, double *modulus);
+
+float npy_deg2radf(float x);
+float npy_rad2degf(float x);
+float npy_logaddexpf(float x, float y);
+float npy_logaddexp2f(float x, float y);
+float npy_divmodf(float x, float y, float *modulus);
+
+npy_longdouble npy_deg2radl(npy_longdouble x);
+npy_longdouble npy_rad2degl(npy_longdouble x);
+npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+                           npy_longdouble *modulus);
+
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+
+/*
+ * Complex declarations
+ */
+
+/*
+ * C99 specifies that complex numbers have the same representation as
+ * an array of two elements, where the first element is the real part
+ * and the second element is the imaginary part.
+ */
+#define __NPY_CPACK_IMP(x, y, type, ctype)   \
+    union {                                  \
+        ctype z;                             \
+        type a[2];                           \
+    } z1;;                                   \
+                                             \
+    z1.a[0] = (x);                           \
+    z1.a[1] = (y);                           \
+                                             \
+    return z1.z;
+
+static NPY_INLINE npy_cdouble npy_cpack(double x, double y)
+{
+    __NPY_CPACK_IMP(x, y, double, npy_cdouble);
+}
+
+static NPY_INLINE npy_cfloat npy_cpackf(float x, float y)
+{
+    __NPY_CPACK_IMP(x, y, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y)
+{
+    __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CPACK_IMP
+
+/*
+ * Same remark as above, but in the other direction: extract first/second
+ * member of complex number, assuming a C99-compatible representation
+ *
+ * Those are defineds as static inline, and such as a reasonable compiler would
+ * most likely compile this to one or two instructions (on CISC at least)
+ */
+#define __NPY_CEXTRACT_IMP(z, index, type, ctype)   \
+    union {                                         \
+        ctype z;                                    \
+        type a[2];                                  \
+    } __z_repr;                                     \
+    __z_repr.z = z;                                 \
+                                                    \
+    return __z_repr.a[index];
+
+static NPY_INLINE double npy_creal(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble);
+}
+
+static NPY_INLINE double npy_cimag(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble);
+}
+
+static NPY_INLINE float npy_crealf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat);
+}
+
+static NPY_INLINE float npy_cimagf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble);
+}
+
+static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CEXTRACT_IMP
+
+/*
+ * Double precision complex functions
+ */
+double npy_cabs(npy_cdouble z);
+double npy_carg(npy_cdouble z);
+
+npy_cdouble npy_cexp(npy_cdouble z);
+npy_cdouble npy_clog(npy_cdouble z);
+npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y);
+
+npy_cdouble npy_csqrt(npy_cdouble z);
+
+npy_cdouble npy_ccos(npy_cdouble z);
+npy_cdouble npy_csin(npy_cdouble z);
+npy_cdouble npy_ctan(npy_cdouble z);
+
+npy_cdouble npy_ccosh(npy_cdouble z);
+npy_cdouble npy_csinh(npy_cdouble z);
+npy_cdouble npy_ctanh(npy_cdouble z);
+
+npy_cdouble npy_cacos(npy_cdouble z);
+npy_cdouble npy_casin(npy_cdouble z);
+npy_cdouble npy_catan(npy_cdouble z);
+
+npy_cdouble npy_cacosh(npy_cdouble z);
+npy_cdouble npy_casinh(npy_cdouble z);
+npy_cdouble npy_catanh(npy_cdouble z);
+
+/*
+ * Single precision complex functions
+ */
+float npy_cabsf(npy_cfloat z);
+float npy_cargf(npy_cfloat z);
+
+npy_cfloat npy_cexpf(npy_cfloat z);
+npy_cfloat npy_clogf(npy_cfloat z);
+npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y);
+
+npy_cfloat npy_csqrtf(npy_cfloat z);
+
+npy_cfloat npy_ccosf(npy_cfloat z);
+npy_cfloat npy_csinf(npy_cfloat z);
+npy_cfloat npy_ctanf(npy_cfloat z);
+
+npy_cfloat npy_ccoshf(npy_cfloat z);
+npy_cfloat npy_csinhf(npy_cfloat z);
+npy_cfloat npy_ctanhf(npy_cfloat z);
+
+npy_cfloat npy_cacosf(npy_cfloat z);
+npy_cfloat npy_casinf(npy_cfloat z);
+npy_cfloat npy_catanf(npy_cfloat z);
+
+npy_cfloat npy_cacoshf(npy_cfloat z);
+npy_cfloat npy_casinhf(npy_cfloat z);
+npy_cfloat npy_catanhf(npy_cfloat z);
+
+
+/*
+ * Extended precision complex functions
+ */
+npy_longdouble npy_cabsl(npy_clongdouble z);
+npy_longdouble npy_cargl(npy_clongdouble z);
+
+npy_clongdouble npy_cexpl(npy_clongdouble z);
+npy_clongdouble npy_clogl(npy_clongdouble z);
+npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y);
+
+npy_clongdouble npy_csqrtl(npy_clongdouble z);
+
+npy_clongdouble npy_ccosl(npy_clongdouble z);
+npy_clongdouble npy_csinl(npy_clongdouble z);
+npy_clongdouble npy_ctanl(npy_clongdouble z);
+
+npy_clongdouble npy_ccoshl(npy_clongdouble z);
+npy_clongdouble npy_csinhl(npy_clongdouble z);
+npy_clongdouble npy_ctanhl(npy_clongdouble z);
+
+npy_clongdouble npy_cacosl(npy_clongdouble z);
+npy_clongdouble npy_casinl(npy_clongdouble z);
+npy_clongdouble npy_catanl(npy_clongdouble z);
+
+npy_clongdouble npy_cacoshl(npy_clongdouble z);
+npy_clongdouble npy_casinhl(npy_clongdouble z);
+npy_clongdouble npy_catanhl(npy_clongdouble z);
+
+
+/*
+ * Functions that set the floating point error
+ * status word.
+ */
+
+/*
+ * platform-dependent code translates floating point
+ * status to an integer sum of these values
+ */
+#define NPY_FPE_DIVIDEBYZERO  1
+#define NPY_FPE_OVERFLOW      2
+#define NPY_FPE_UNDERFLOW     4
+#define NPY_FPE_INVALID       8
+
+int npy_get_floatstatus(void);
+int npy_clear_floatstatus(void);
+void npy_set_floatstatus_divbyzero(void);
+void npy_set_floatstatus_overflow(void);
+void npy_set_floatstatus_underflow(void);
+void npy_set_floatstatus_invalid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
new file mode 100644
index 0000000000..6183dc2784
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
@@ -0,0 +1,19 @@
+/*
+ * This include file is provided for inclusion in Cython *.pyd files where
+ * one would like to define the NPY_NO_DEPRECATED_API macro. It can be
+ * included by
+ *
+ * cdef extern from "npy_no_deprecated_api.h": pass
+ *
+ */
+#ifndef NPY_NO_DEPRECATED_API
+
+/* put this check here since there may be multiple includes in C extensions. */
+#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \
+    defined(OLD_DEFINES_H)
+#error "npy_no_deprecated_api.h" must be first among numpy includes.
+#else
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
new file mode 100644
index 0000000000..9228c3916e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
@@ -0,0 +1,30 @@
+#ifndef _NPY_OS_H_
+#define _NPY_OS_H_
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+    #define NPY_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
+            defined(__OpenBSD__) || defined(__DragonFly__)
+    #define NPY_OS_BSD
+    #ifdef __FreeBSD__
+        #define NPY_OS_FREEBSD
+    #elif defined(__NetBSD__)
+        #define NPY_OS_NETBSD
+    #elif defined(__OpenBSD__)
+        #define NPY_OS_OPENBSD
+    #elif defined(__DragonFly__)
+        #define NPY_OS_DRAGONFLY
+    #endif
+#elif defined(sun) || defined(__sun)
+    #define NPY_OS_SOLARIS
+#elif defined(__CYGWIN__)
+    #define NPY_OS_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+    #define NPY_OS_WIN32
+#elif defined(__APPLE__)
+    #define NPY_OS_DARWIN
+#else
+    #define NPY_OS_UNKNOWN
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
new file mode 100644
index 0000000000..cbf4a62b9f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
@@ -0,0 +1,37 @@
+#ifndef _NPY_NUMPYCONFIG_H_
+#define _NPY_NUMPYCONFIG_H_
+
+#include "_numpyconfig.h"
+
+/*
+ * On Mac OS X, because there is only one configuration stage for all the archs
+ * in universal builds, any macro which depends on the arch needs to be
+ * harcoded
+ */
+#ifdef __APPLE__
+    #undef NPY_SIZEOF_LONG
+    #undef NPY_SIZEOF_PY_INTPTR_T
+
+    #ifdef __LP64__
+        #define NPY_SIZEOF_LONG         8
+        #define NPY_SIZEOF_PY_INTPTR_T  8
+    #else
+        #define NPY_SIZEOF_LONG         4
+        #define NPY_SIZEOF_PY_INTPTR_T  4
+    #endif
+#endif
+
+/**
+ * To help with the NPY_NO_DEPRECATED_API macro, we include API version
+ * numbers for specific versions of NumPy. To exclude all API that was
+ * deprecated as of 1.7, add the following before #including any NumPy
+ * headers:
+ *   #define NPY_NO_DEPRECATED_API  NPY_1_7_API_VERSION
+ */
+#define NPY_1_7_API_VERSION 0x00000007
+#define NPY_1_8_API_VERSION 0x00000008
+#define NPY_1_9_API_VERSION 0x00000008
+#define NPY_1_10_API_VERSION 0x00000008
+#define NPY_1_11_API_VERSION 0x00000008
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
new file mode 100644
index 0000000000..abf81595ae
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
@@ -0,0 +1,187 @@
+/* This header is deprecated as of NumPy 1.7 */
+#ifndef OLD_DEFINES_H
+#define OLD_DEFINES_H
+
+#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION
+#error The header "old_defines.h" is deprecated as of NumPy 1.7.
+#endif
+
+#define NDARRAY_VERSION NPY_VERSION
+
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+
+#define PyArray_TYPES       NPY_TYPES
+#define PyArray_BOOL        NPY_BOOL
+#define PyArray_BYTE        NPY_BYTE
+#define PyArray_UBYTE       NPY_UBYTE
+#define PyArray_SHORT       NPY_SHORT
+#define PyArray_USHORT      NPY_USHORT
+#define PyArray_INT         NPY_INT
+#define PyArray_UINT        NPY_UINT
+#define PyArray_LONG        NPY_LONG
+#define PyArray_ULONG       NPY_ULONG
+#define PyArray_LONGLONG    NPY_LONGLONG
+#define PyArray_ULONGLONG   NPY_ULONGLONG
+#define PyArray_HALF        NPY_HALF
+#define PyArray_FLOAT       NPY_FLOAT
+#define PyArray_DOUBLE      NPY_DOUBLE
+#define PyArray_LONGDOUBLE  NPY_LONGDOUBLE
+#define PyArray_CFLOAT      NPY_CFLOAT
+#define PyArray_CDOUBLE     NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT      NPY_OBJECT
+#define PyArray_STRING      NPY_STRING
+#define PyArray_UNICODE     NPY_UNICODE
+#define PyArray_VOID        NPY_VOID
+#define PyArray_DATETIME    NPY_DATETIME
+#define PyArray_TIMEDELTA   NPY_TIMEDELTA
+#define PyArray_NTYPES      NPY_NTYPES
+#define PyArray_NOTYPE      NPY_NOTYPE
+#define PyArray_CHAR        NPY_CHAR
+#define PyArray_USERDEF     NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+
+#define PyArray_INTP        NPY_INTP
+#define PyArray_UINTP       NPY_UINTP
+
+#define PyArray_INT8    NPY_INT8
+#define PyArray_UINT8   NPY_UINT8
+#define PyArray_INT16   NPY_INT16
+#define PyArray_UINT16  NPY_UINT16
+#define PyArray_INT32   NPY_INT32
+#define PyArray_UINT32  NPY_UINT32
+
+#ifdef NPY_INT64
+#define PyArray_INT64   NPY_INT64
+#define PyArray_UINT64  NPY_UINT64
+#endif
+
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#endif
+
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16  NPY_FLOAT16
+#define PyArray_COMPLEX32  NPY_COMPLEX32
+#endif
+
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80  NPY_FLOAT80
+#define PyArray_COMPLEX160  NPY_COMPLEX160
+#endif
+
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96  NPY_FLOAT96
+#define PyArray_COMPLEX192  NPY_COMPLEX192
+#endif
+
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128  NPY_FLOAT128
+#define PyArray_COMPLEX256  NPY_COMPLEX256
+#endif
+
+#define PyArray_FLOAT32    NPY_FLOAT32
+#define PyArray_COMPLEX64  NPY_COMPLEX64
+#define PyArray_FLOAT64    NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+
+
+#define PyArray_TYPECHAR        NPY_TYPECHAR
+#define PyArray_BOOLLTR         NPY_BOOLLTR
+#define PyArray_BYTELTR         NPY_BYTELTR
+#define PyArray_UBYTELTR        NPY_UBYTELTR
+#define PyArray_SHORTLTR        NPY_SHORTLTR
+#define PyArray_USHORTLTR       NPY_USHORTLTR
+#define PyArray_INTLTR          NPY_INTLTR
+#define PyArray_UINTLTR         NPY_UINTLTR
+#define PyArray_LONGLTR         NPY_LONGLTR
+#define PyArray_ULONGLTR        NPY_ULONGLTR
+#define PyArray_LONGLONGLTR     NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR    NPY_ULONGLONGLTR
+#define PyArray_HALFLTR         NPY_HALFLTR
+#define PyArray_FLOATLTR        NPY_FLOATLTR
+#define PyArray_DOUBLELTR       NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR   NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR       NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR      NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR  NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR       NPY_OBJECTLTR
+#define PyArray_STRINGLTR       NPY_STRINGLTR
+#define PyArray_STRINGLTR2      NPY_STRINGLTR2
+#define PyArray_UNICODELTR      NPY_UNICODELTR
+#define PyArray_VOIDLTR         NPY_VOIDLTR
+#define PyArray_DATETIMELTR     NPY_DATETIMELTR
+#define PyArray_TIMEDELTALTR    NPY_TIMEDELTALTR
+#define PyArray_CHARLTR         NPY_CHARLTR
+#define PyArray_INTPLTR         NPY_INTPLTR
+#define PyArray_UINTPLTR        NPY_UINTPLTR
+#define PyArray_GENBOOLLTR      NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR       NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR     NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR     NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR      NPY_COMPLEXLTR
+
+#define PyArray_QUICKSORT   NPY_QUICKSORT
+#define PyArray_HEAPSORT    NPY_HEAPSORT
+#define PyArray_MERGESORT   NPY_MERGESORT
+#define PyArray_SORTKIND    NPY_SORTKIND
+#define PyArray_NSORTS      NPY_NSORTS
+
+#define PyArray_NOSCALAR       NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR    NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR  NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR  NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR   NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR  NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND     NPY_SCALARKIND
+#define PyArray_NSCALARKINDS   NPY_NSCALARKINDS
+
+#define PyArray_ANYORDER     NPY_ANYORDER
+#define PyArray_CORDER       NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER        NPY_ORDER
+
+#define PyDescr_ISBOOL      PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED  PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED    PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER   PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT     PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER    PyDataType_ISNUMBER
+#define PyDescr_ISSTRING    PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX   PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON    PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE  PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF   PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED  PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT    PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS   PyDataType_HASFIELDS
+
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+
+#define PyArray_RemoveLargest PyArray_RemoveSmallest
+
+#define PyArray_UCS4 npy_ucs4
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
new file mode 100644
index 0000000000..748f06da31
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
@@ -0,0 +1,23 @@
+#include "arrayobject.h"
+
+#ifndef REFCOUNT
+#  define REFCOUNT NPY_REFCOUNT
+#  define MAX_ELSIZE 16
+#endif
+
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE NPY_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define OWN_DATA NPY_OWNDATA
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
new file mode 100644
index 0000000000..172749633f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
@@ -0,0 +1,321 @@
+
+=================
+Numpy Ufunc C-API
+=================
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void
+                          **data, char *types, int ntypes, int nin, int
+                          nout, int identity, const char *name, const
+                          char *doc, int unused)
+
+
+::
+
+  int
+  PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int
+                              usertype, PyUFuncGenericFunction
+                              function, int *arg_types, void *data)
+
+
+::
+
+  int
+  PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject
+                          *kwds, PyArrayObject **op)
+
+
+This generic function is called with the ufunc object, the arguments to it,
+and an array of (pointers to) PyArrayObjects which are NULL.
+
+'op' is an array of at least NPY_MAXARGS PyArrayObject *.
+
+::
+
+  void
+  PyUFunc_f_f_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_g_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_F_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_G_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_O_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_gg_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_GG_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_O_O_method(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O_method(char **args, npy_intp *dimensions, npy_intp
+                      *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_On_Om(char **args, npy_intp *dimensions, npy_intp *steps, void
+                *func)
+
+
+::
+
+  int
+  PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject
+                      **errobj)
+
+
+On return, if errobj is populated with a non-NULL value, the caller
+owns a new reference to errobj.
+
+::
+
+  int
+  PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first)
+
+
+::
+
+  void
+  PyUFunc_clearfperr()
+
+
+::
+
+  int
+  PyUFunc_getfperr(void )
+
+
+::
+
+  int
+  PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int
+                      *first)
+
+
+::
+
+  int
+  PyUFunc_ReplaceLoopBySignature(PyUFuncObject
+                                 *func, PyUFuncGenericFunction
+                                 newfunc, int
+                                 *signature, PyUFuncGenericFunction
+                                 *oldfunc)
+
+
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void
+                                      **data, char *types, int
+                                      ntypes, int nin, int nout, int
+                                      identity, const char *name, const
+                                      char *doc, int unused, const char
+                                      *signature)
+
+
+::
+
+  int
+  PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+
+
+::
+
+  void
+  PyUFunc_e_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_f_f(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_ff_f(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  int
+  PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING
+                              casting, PyArrayObject
+                              **operands, PyObject
+                              *type_tup, PyArray_Descr **out_dtypes)
+
+
+This function applies the default type resolution rules
+for the provided ufunc.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING
+                          casting, PyArrayObject
+                          **operands, PyArray_Descr **dtypes)
+
+
+Validates that the input operands can be cast to
+the input types, and the output types can be cast to
+the output operands where provided.
+
+Returns 0 on success, -1 (with exception raised) on validation failure.
+
+::
+
+  int
+  PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr
+                               *user_dtype, PyUFuncGenericFunction
+                               function, PyArray_Descr
+                               **arg_dtypes, void *data)
+
+
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
new file mode 100644
index 0000000000..1cca64b75b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
@@ -0,0 +1,357 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+
+#include <numpy/npy_math.h>
+#include <numpy/npy_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The legacy generic inner loop for a standard element-wise or
+ * generalized ufunc.
+ */
+typedef void (*PyUFuncGenericFunction)
+            (char **args,
+             npy_intp *dimensions,
+             npy_intp *strides,
+             void *innerloopdata);
+
+/*
+ * The most generic one-dimensional inner loop for
+ * a masked standard element-wise ufunc. "Masked" here means that it skips
+ * doing calculations on any items for which the maskptr array has a true
+ * value.
+ */
+typedef void (PyUFunc_MaskedStridedInnerLoopFunc)(
+                char **dataptrs, npy_intp *strides,
+                char *maskptr, npy_intp mask_stride,
+                npy_intp count,
+                NpyAuxData *innerloopdata);
+
+/* Forward declaration for the type resolver and loop selector typedefs */
+struct _tagPyUFuncObject;
+
+/*
+ * Given the operands for calling a ufunc, should determine the
+ * calculation input and output data types and return an inner loop function.
+ * This function should validate that the casting rule is being followed,
+ * and fail if it is not.
+ *
+ * For backwards compatibility, the regular type resolution function does not
+ * support auxiliary data with object semantics. The type resolution call
+ * which returns a masked generic function returns a standard NpyAuxData
+ * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros
+ * work.
+ *
+ * ufunc:             The ufunc object.
+ * casting:           The 'casting' parameter provided to the ufunc.
+ * operands:          An array of length (ufunc->nin + ufunc->nout),
+ *                    with the output parameters possibly NULL.
+ * type_tup:          Either NULL, or the type_tup passed to the ufunc.
+ * out_dtypes:        An array which should be populated with new
+ *                    references to (ufunc->nin + ufunc->nout) new
+ *                    dtypes, one for each input and output. These
+ *                    dtypes should all be in native-endian format.
+ *
+ * Should return 0 on success, -1 on failure (with exception set),
+ * or -2 if Py_NotImplemented should be returned.
+ */
+typedef int (PyUFunc_TypeResolutionFunc)(
+                                struct _tagPyUFuncObject *ufunc,
+                                NPY_CASTING casting,
+                                PyArrayObject **operands,
+                                PyObject *type_tup,
+                                PyArray_Descr **out_dtypes);
+
+/*
+ * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc,
+ * and an array of fixed strides (the array will contain NPY_MAX_INTP for
+ * strides which are not necessarily fixed), returns an inner loop
+ * with associated auxiliary data.
+ *
+ * For backwards compatibility, there is a variant of the inner loop
+ * selection which returns an inner loop irrespective of the strides,
+ * and with a void* static auxiliary data instead of an NpyAuxData *
+ * dynamically allocatable auxiliary data.
+ *
+ * ufunc:             The ufunc object.
+ * dtypes:            An array which has been populated with dtypes,
+ *                    in most cases by the type resolution funciton
+ *                    for the same ufunc.
+ * fixed_strides:     For each input/output, either the stride that
+ *                    will be used every time the function is called
+ *                    or NPY_MAX_INTP if the stride might change or
+ *                    is not known ahead of time. The loop selection
+ *                    function may use this stride to pick inner loops
+ *                    which are optimized for contiguous or 0-stride
+ *                    cases.
+ * out_innerloop:     Should be populated with the correct ufunc inner
+ *                    loop for the given type.
+ * out_innerloopdata: Should be populated with the void* data to
+ *                    be passed into the out_innerloop function.
+ * out_needs_api:     If the inner loop needs to use the Python API,
+ *                    should set the to 1, otherwise should leave
+ *                    this untouched.
+ */
+typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyUFuncGenericFunction *out_innerloop,
+                            void **out_innerloopdata,
+                            int *out_needs_api);
+typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyArray_Descr *mask_dtype,
+                            npy_intp *fixed_strides,
+                            npy_intp fixed_mask_stride,
+                            PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
+                            NpyAuxData **out_innerloopdata,
+                            int *out_needs_api);
+
+typedef struct _tagPyUFuncObject {
+        PyObject_HEAD
+        /*
+         * nin: Number of inputs
+         * nout: Number of outputs
+         * nargs: Always nin + nout (Why is it stored?)
+         */
+        int nin, nout, nargs;
+
+        /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */
+        int identity;
+
+        /* Array of one-dimensional core loops */
+        PyUFuncGenericFunction *functions;
+        /* Array of funcdata that gets passed into the functions */
+        void **data;
+        /* The number of elements in 'functions' and 'data' */
+        int ntypes;
+
+        /* Used to be unused field 'check_return' */
+        int reserved1;
+
+        /* The name of the ufunc */
+        const char *name;
+
+        /* Array of type numbers, of size ('nargs' * 'ntypes') */
+        char *types;
+
+        /* Documentation string */
+        const char *doc;
+
+        void *ptr;
+        PyObject *obj;
+        PyObject *userloops;
+
+        /* generalized ufunc parameters */
+
+        /* 0 for scalar ufunc; 1 for generalized ufunc */
+        int core_enabled;
+        /* number of distinct dimension names in signature */
+        int core_num_dim_ix;
+
+        /*
+         * dimension indices of input/output argument k are stored in
+         * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1]
+         */
+
+        /* numbers of core dimensions of each argument */
+        int *core_num_dims;
+        /*
+         * dimension indices in a flatted form; indices
+         * are in the range of [0,core_num_dim_ix)
+         */
+        int *core_dim_ixs;
+        /*
+         * positions of 1st core dimensions of each
+         * argument in core_dim_ixs
+         */
+        int *core_offsets;
+        /* signature string for printing purpose */
+        char *core_signature;
+
+        /*
+         * A function which resolves the types and fills an array
+         * with the dtypes for the inputs and outputs.
+         */
+        PyUFunc_TypeResolutionFunc *type_resolver;
+        /*
+         * A function which returns an inner loop written for
+         * NumPy 1.6 and earlier ufuncs. This is for backwards
+         * compatibility, and may be NULL if inner_loop_selector
+         * is specified.
+         */
+        PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
+        /*
+         * This was blocked off to be the "new" inner loop selector in 1.7,
+         * but this was never implemented. (This is also why the above
+         * selector is called the "legacy" selector.)
+         */
+        void *reserved2;
+        /*
+         * A function which returns a masked inner loop for the ufunc.
+         */
+        PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+
+        /*
+         * List of flags for each operand when ufunc is called by nditer object.
+         * These flags will be used in addition to the default flags for each
+         * operand set by nditer object.
+         */
+        npy_uint32 *op_flags;
+
+        /*
+         * List of global flags used when ufunc is called by nditer object.
+         * These flags will be used in addition to the default global flags
+         * set by nditer object.
+         */
+        npy_uint32 iter_flags;
+} PyUFuncObject;
+
+#include "arrayobject.h"
+
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN   1
+#define UFUNC_ERR_RAISE  2
+#define UFUNC_ERR_CALL   3
+#define UFUNC_ERR_PRINT  4
+#define UFUNC_ERR_LOG    5
+
+        /* Python side integer mask */
+
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW     3
+#define UFUNC_SHIFT_UNDERFLOW    6
+#define UFUNC_SHIFT_INVALID      9
+
+
+#define UFUNC_OBJ_ISOBJECT      1
+#define UFUNC_OBJ_NEEDS_API     2
+
+   /* Default user error mode */
+#define UFUNC_ERR_DEFAULT                               \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) +  \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) +      \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
+
+#if NPY_ALLOW_THREADS
+#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0);
+#define NPY_LOOP_END_THREADS   do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0);
+#else
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+#endif
+
+/*
+ * UFunc has unit of 1, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_One 1
+/*
+ * UFunc has unit of 0, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_Zero 0
+/*
+ * UFunc has no unit, and the order of operations cannot be reordered.
+ * This case does not allow reduction with multiple axes at once.
+ */
+#define PyUFunc_None -1
+/*
+ * UFunc has no unit, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_ReorderableNone -2
+
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+
+
+typedef struct {
+        int nin;
+        int nout;
+        PyObject *callable;
+} PyUFunc_PyFuncData;
+
+/* A linked-list of function information for
+   user-defined 1-d loops.
+ */
+typedef struct _loop1d_info {
+        PyUFuncGenericFunction func;
+        void *data;
+        int *arg_types;
+        struct _loop1d_info *next;
+        int nargs;
+        PyArray_Descr **arg_dtypes;
+} PyUFunc_Loop1d;
+
+
+#include "__ufunc_api.h"
+
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+
+#define UFUNC_CHECK_ERROR(arg) \
+        do {if ((((arg)->obj & UFUNC_OBJ_NEEDS_API) && PyErr_Occurred()) || \
+            ((arg)->errormask && \
+             PyUFunc_checkfperr((arg)->errormask, \
+                                (arg)->errobj, \
+                                &(arg)->first))) \
+                goto fail;} while (0)
+
+
+/* keep in sync with ieee754.c.src */
+#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
+      defined(__NetBSD__) || \
+      defined(__GLIBC__) || defined(__APPLE__) || \
+      defined(__CYGWIN__) || defined(__MINGW32__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version >= 502114)) || \
+      defined(_AIX) || \
+      defined(_MSC_VER) || \
+      defined(__osf__) && defined(__alpha)
+#else
+#define NO_FLOATING_POINT_SUPPORT
+#endif
+
+
+/*
+ * THESE MACROS ARE DEPRECATED.
+ * Use npy_set_floatstatus_* in the npymath library.
+ */
+#define UFUNC_FPE_DIVIDEBYZERO  NPY_FPE_DIVIDEBYZERO
+#define UFUNC_FPE_OVERFLOW      NPY_FPE_OVERFLOW
+#define UFUNC_FPE_UNDERFLOW     NPY_FPE_UNDERFLOW
+#define UFUNC_FPE_INVALID       NPY_FPE_INVALID
+
+#define UFUNC_CHECK_STATUS(ret) \
+    { \
+       ret = npy_clear_floatstatus(); \
+    }
+#define generate_divbyzero_error() npy_set_floatstatus_divbyzero()
+#define generate_overflow_error() npy_set_floatstatus_overflow()
+
+  /* Make sure it gets defined if it isn't already */
+#ifndef UFUNC_NOFPE
+/* Clear the floating point exception default of Borland C++ */
+#if defined(__BORLANDC__)
+#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM);
+#else
+#define UFUNC_NOFPE
+#endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UFUNCOBJECT_H */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
new file mode 100644
index 0000000000..cc968a3544
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
@@ -0,0 +1,19 @@
+#ifndef __NUMPY_UTILS_HEADER__
+#define __NUMPY_UTILS_HEADER__
+
+#ifndef __COMP_NPY_UNUSED
+        #if defined(__GNUC__)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        # elif defined(__ICC)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        #else
+                #define __COMP_NPY_UNUSED
+        #endif
+#endif
+
+/* Use this to tag a variable as not used. It will remove unused variable
+ * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable
+ * to avoid accidental use */
+#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/info.py
new file mode 100644
index 0000000000..241f209b55
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/info.py
@@ -0,0 +1,87 @@
+"""Defines a multi-dimensional array and useful procedures for Numerical computation.
+
+Functions
+
+-   array                      - NumPy Array construction
+-   zeros                      - Return an array of all zeros
+-   empty                      - Return an unitialized array
+-   shape                      - Return shape of sequence or array
+-   rank                       - Return number of dimensions
+-   size                       - Return number of elements in entire array or a
+                                 certain dimension
+-   fromstring                 - Construct array from (byte) string
+-   take                       - Select sub-arrays using sequence of indices
+-   put                        - Set sub-arrays using sequence of 1-D indices
+-   putmask                    - Set portion of arrays using a mask
+-   reshape                    - Return array with new shape
+-   repeat                     - Repeat elements of array
+-   choose                     - Construct new array from indexed array tuple
+-   correlate                  - Correlate two 1-d arrays
+-   searchsorted               - Search for element in 1-d array
+-   sum                        - Total sum over a specified dimension
+-   average                    - Average, possibly weighted, over axis or array.
+-   cumsum                     - Cumulative sum over a specified dimension
+-   product                    - Total product over a specified dimension
+-   cumproduct                 - Cumulative product over a specified dimension
+-   alltrue                    - Logical and over an entire axis
+-   sometrue                   - Logical or over an entire axis
+-   allclose                   - Tests if sequences are essentially equal
+
+More Functions:
+
+-   arange                     - Return regularly spaced array
+-   asarray                    - Guarantee NumPy array
+-   convolve                   - Convolve two 1-d arrays
+-   swapaxes                   - Exchange axes
+-   concatenate                - Join arrays together
+-   transpose                  - Permute axes
+-   sort                       - Sort elements of array
+-   argsort                    - Indices of sorted array
+-   argmax                     - Index of largest value
+-   argmin                     - Index of smallest value
+-   inner                      - Innerproduct of two arrays
+-   dot                        - Dot product (matrix multiplication)
+-   outer                      - Outerproduct of two arrays
+-   resize                     - Return array with arbitrary new shape
+-   indices                    - Tuple of indices
+-   fromfunction               - Construct array from universal function
+-   diagonal                   - Return diagonal array
+-   trace                      - Trace of array
+-   dump                       - Dump array to file object (pickle)
+-   dumps                      - Return pickled string representing data
+-   load                       - Return array stored in file object
+-   loads                      - Return array from pickled string
+-   ravel                      - Return array as 1-D
+-   nonzero                    - Indices of nonzero elements for 1-D array
+-   shape                      - Shape of array
+-   where                      - Construct array from binary result
+-   compress                   - Elements of array where condition is true
+-   clip                       - Clip array between two values
+-   ones                       - Array of all ones
+-   identity                   - 2-D identity array (matrix)
+
+(Universal) Math Functions
+
+       add                    logical_or             exp
+       subtract               logical_xor            log
+       multiply               logical_not            log10
+       divide                 maximum                sin
+       divide_safe            minimum                sinh
+       conjugate              bitwise_and            sqrt
+       power                  bitwise_or             tan
+       absolute               bitwise_xor            tanh
+       negative               invert                 ceil
+       greater                left_shift             fabs
+       greater_equal          right_shift            floor
+       less                   arccos                 arctan2
+       less_equal             arcsin                 fmod
+       equal                  arctan                 hypot
+       not_equal              cos                    around
+       logical_and            cosh                   sign
+       arccosh                arcsinh                arctanh
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['testing']
+global_symbols = ['*']
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
new file mode 100644
index 0000000000..290c51994e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
@@ -0,0 +1,12 @@
+[meta]
+Name = mlib
+Description = Math library used with this version of numpy
+Version = 1.0
+
+[default]
+Libs=
+Cflags=
+
+[msvc]
+Libs=
+Cflags=
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
new file mode 100644
index 0000000000..c8b897f3f0
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
@@ -0,0 +1,20 @@
+[meta]
+Name=npymath
+Description=Portable, core math library implementing C99 standard
+Version=0.1
+
+[variables]
+pkgname=numpy.core
+prefix=${pkgdir}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+[default]
+Libs=-L${libdir} -lnpymath
+Cflags=-I${includedir}
+Requires=mlib
+
+[msvc]
+Libs=/LIBPATH:${libdir} npymath.lib
+Cflags=/INCLUDE:${includedir}
+Requires=mlib
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/machar.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/machar.py
new file mode 100644
index 0000000000..6f2735d325
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/machar.py
@@ -0,0 +1,342 @@
+"""
+Machine arithmetics - determine the parameters of the
+floating-point arithmetic system
+
+Author: Pearu Peterson, September 2003
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['MachAr']
+
+from numpy.core.fromnumeric import any
+from numpy.core.numeric import errstate
+
+# Need to speed this up...especially for longfloat
+
+class MachAr(object):
+    """
+    Diagnosing machine parameters.
+
+    Attributes
+    ----------
+    ibeta : int
+        Radix in which numbers are represented.
+    it : int
+        Number of base-`ibeta` digits in the floating point mantissa M.
+    machep : int
+        Exponent of the smallest (most negative) power of `ibeta` that,
+        added to 1.0, gives something different from 1.0
+    eps : float
+        Floating-point number ``beta**machep`` (floating point precision)
+    negep : int
+        Exponent of the smallest power of `ibeta` that, substracted
+        from 1.0, gives something different from 1.0.
+    epsneg : float
+        Floating-point number ``beta**negep``.
+    iexp : int
+        Number of bits in the exponent (including its sign and bias).
+    minexp : int
+        Smallest (most negative) power of `ibeta` consistent with there
+        being no leading zeros in the mantissa.
+    xmin : float
+        Floating point number ``beta**minexp`` (the smallest [in
+        magnitude] usable floating value).
+    maxexp : int
+        Smallest (positive) power of `ibeta` that causes overflow.
+    xmax : float
+        ``(1-epsneg) * beta**maxexp`` (the largest [in magnitude]
+        usable floating value).
+    irnd : int
+        In ``range(6)``, information on what kind of rounding is done
+        in addition, and on how underflow is handled.
+    ngrd : int
+        Number of 'guard digits' used when truncating the product
+        of two mantissas to fit the representation.
+    epsilon : float
+        Same as `eps`.
+    tiny : float
+        Same as `xmin`.
+    huge : float
+        Same as `xmax`.
+    precision : float
+        ``- int(-log10(eps))``
+    resolution : float
+        ``- 10**(-precision)``
+
+    Parameters
+    ----------
+    float_conv : function, optional
+        Function that converts an integer or integer array to a float
+        or float array. Default is `float`.
+    int_conv : function, optional
+        Function that converts a float or float array to an integer or
+        integer array. Default is `int`.
+    float_to_float : function, optional
+        Function that converts a float array to float. Default is `float`.
+        Note that this does not seem to do anything useful in the current
+        implementation.
+    float_to_str : function, optional
+        Function that converts a single float to a string. Default is
+        ``lambda v:'%24.16e' %v``.
+    title : str, optional
+        Title that is printed in the string representation of `MachAr`.
+
+    See Also
+    --------
+    finfo : Machine limits for floating point types.
+    iinfo : Machine limits for integer types.
+
+    References
+    ----------
+    .. [1] Press, Teukolsky, Vetterling and Flannery,
+           "Numerical Recipes in C++," 2nd ed,
+           Cambridge University Press, 2002, p. 31.
+
+    """
+
+    def __init__(self, float_conv=float,int_conv=int,
+                 float_to_float=float,
+                 float_to_str=lambda v:'%24.16e' % v,
+                 title='Python floating point number'):
+        """
+
+        float_conv - convert integer to float (array)
+        int_conv   - convert float (array) to integer
+        float_to_float - convert float array to float
+        float_to_str - convert array float to str
+        title        - description of used floating point numbers
+
+        """
+        # We ignore all errors here because we are purposely triggering
+        # underflow to detect the properties of the runninng arch.
+        with errstate(under='ignore'):
+            self._do_init(float_conv, int_conv, float_to_float, float_to_str, title)
+
+    def _do_init(self, float_conv, int_conv, float_to_float, float_to_str, title):
+        max_iterN = 10000
+        msg = "Did not converge after %d tries with %s"
+        one = float_conv(1)
+        two = one + one
+        zero = one - one
+
+        # Do we really need to do this?  Aren't they 2 and 2.0?
+        # Determine ibeta and beta
+        a = one
+        for _ in range(max_iterN):
+            a = a + a
+            temp = a + one
+            temp1 = temp - a
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        b = one
+        for _ in range(max_iterN):
+            b = b + b
+            temp = a + b
+            itemp = int_conv(temp-a)
+            if any(itemp != 0):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        ibeta = itemp
+        beta = float_conv(ibeta)
+
+        # Determine it and irnd
+        it = -1
+        b = one
+        for _ in range(max_iterN):
+            it = it + 1
+            b = b * beta
+            temp = b + one
+            temp1 = temp - b
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+
+        betah = beta / two
+        a = one
+        for _ in range(max_iterN):
+            a = a + a
+            temp = a + one
+            temp1 = temp - a
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        temp = a + betah
+        irnd = 0
+        if any(temp-a != zero):
+            irnd = 1
+        tempa = a + beta
+        temp = tempa + betah
+        if irnd == 0 and any(temp-tempa != zero):
+            irnd = 2
+
+        # Determine negep and epsneg
+        negep = it + 3
+        betain = one / beta
+        a = one
+        for i in range(negep):
+            a = a * betain
+        b = a
+        for _ in range(max_iterN):
+            temp = one - a
+            if any(temp-one != zero):
+                break
+            a = a * beta
+            negep = negep - 1
+            # Prevent infinite loop on PPC with gcc 4.0:
+            if negep < 0:
+                raise RuntimeError("could not determine machine tolerance "
+                                   "for 'negep', locals() -> %s" % (locals()))
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        negep = -negep
+        epsneg = a
+
+        # Determine machep and eps
+        machep = - it - 3
+        a = b
+
+        for _ in range(max_iterN):
+            temp = one + a
+            if any(temp-one != zero):
+                break
+            a = a * beta
+            machep = machep + 1
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        eps = a
+
+        # Determine ngrd
+        ngrd = 0
+        temp = one + eps
+        if irnd == 0 and any(temp*one - one != zero):
+            ngrd = 1
+
+        # Determine iexp
+        i = 0
+        k = 1
+        z = betain
+        t = one + eps
+        nxres = 0
+        for _ in range(max_iterN):
+            y = z
+            z = y*y
+            a = z*one  # Check here for underflow
+            temp = z*t
+            if any(a+a == zero) or any(abs(z) >= y):
+                break
+            temp1 = temp * betain
+            if any(temp1*beta == z):
+                break
+            i = i + 1
+            k = k + k
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        if ibeta != 10:
+            iexp = i + 1
+            mx = k + k
+        else:
+            iexp = 2
+            iz = ibeta
+            while k >= iz:
+                iz = iz * ibeta
+                iexp = iexp + 1
+            mx = iz + iz - 1
+
+        # Determine minexp and xmin
+        for _ in range(max_iterN):
+            xmin = y
+            y = y * betain
+            a = y * one
+            temp = y * t
+            if any((a + a) != zero) and any(abs(y) < xmin):
+                k = k + 1
+                temp1 = temp * betain
+                if any(temp1*beta == y) and any(temp != y):
+                    nxres = 3
+                    xmin = y
+                    break
+            else:
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        minexp = -k
+
+        # Determine maxexp, xmax
+        if mx <= k + k - 3 and ibeta != 10:
+            mx = mx + mx
+            iexp = iexp + 1
+        maxexp = mx + minexp
+        irnd = irnd + nxres
+        if irnd >= 2:
+            maxexp = maxexp - 2
+        i = maxexp + minexp
+        if ibeta == 2 and not i:
+            maxexp = maxexp - 1
+        if i > 20:
+            maxexp = maxexp - 1
+        if any(a != y):
+            maxexp = maxexp - 2
+        xmax = one - epsneg
+        if any(xmax*one != xmax):
+            xmax = one - beta*epsneg
+        xmax = xmax / (xmin*beta*beta*beta)
+        i = maxexp + minexp + 3
+        for j in range(i):
+            if ibeta == 2:
+                xmax = xmax + xmax
+            else:
+                xmax = xmax * beta
+
+        self.ibeta = ibeta
+        self.it = it
+        self.negep = negep
+        self.epsneg = float_to_float(epsneg)
+        self._str_epsneg = float_to_str(epsneg)
+        self.machep = machep
+        self.eps = float_to_float(eps)
+        self._str_eps = float_to_str(eps)
+        self.ngrd = ngrd
+        self.iexp = iexp
+        self.minexp = minexp
+        self.xmin = float_to_float(xmin)
+        self._str_xmin = float_to_str(xmin)
+        self.maxexp = maxexp
+        self.xmax = float_to_float(xmax)
+        self._str_xmax = float_to_str(xmax)
+        self.irnd = irnd
+
+        self.title = title
+        # Commonly used parameters
+        self.epsilon = self.eps
+        self.tiny = self.xmin
+        self.huge = self.xmax
+
+        import math
+        self.precision = int(-math.log10(float_to_float(self.eps)))
+        ten = two + two + two + two + two
+        resolution = ten ** (-self.precision)
+        self.resolution = float_to_float(resolution)
+        self._str_resolution = float_to_str(resolution)
+
+    def __str__(self):
+        fmt = (
+           'Machine parameters for %(title)s\n'
+           '---------------------------------------------------------------------\n'
+           'ibeta=%(ibeta)s it=%(it)s iexp=%(iexp)s ngrd=%(ngrd)s irnd=%(irnd)s\n'
+           'machep=%(machep)s     eps=%(_str_eps)s (beta**machep == epsilon)\n'
+           'negep =%(negep)s  epsneg=%(_str_epsneg)s (beta**epsneg)\n'
+           'minexp=%(minexp)s   xmin=%(_str_xmin)s (beta**minexp == tiny)\n'
+           'maxexp=%(maxexp)s    xmax=%(_str_xmax)s ((1-epsneg)*beta**maxexp == huge)\n'
+           '---------------------------------------------------------------------\n'
+           )
+        return fmt % self.__dict__
+
+
+if __name__ == '__main__':
+    print(MachAr())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/memmap.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/memmap.py
new file mode 100644
index 0000000000..70d7b72b47
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/memmap.py
@@ -0,0 +1,311 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from .numeric import uint8, ndarray, dtype
+from numpy.compat import long, basestring
+
+__all__ = ['memmap']
+
+dtypedescr = dtype
+valid_filemodes = ["r", "c", "r+", "w+"]
+writeable_filemodes = ["r+", "w+"]
+
+mode_equivalents = {
+    "readonly":"r",
+    "copyonwrite":"c",
+    "readwrite":"r+",
+    "write":"w+"
+    }
+
+class memmap(ndarray):
+    """Create a memory-map to an array stored in a *binary* file on disk.
+
+    Memory-mapped files are used for accessing small segments of large files
+    on disk, without reading the entire file into memory.  Numpy's
+    memmap's are array-like objects.  This differs from Python's ``mmap``
+    module, which uses file-like objects.
+
+    This subclass of ndarray has some unpleasant interactions with
+    some operations, because it doesn't quite fit properly as a subclass.
+    An alternative to using this subclass is to create the ``mmap``
+    object yourself, then create an ndarray with ndarray.__new__ directly,
+    passing the object created in its 'buffer=' parameter.
+
+    This class may at some point be turned into a factory function
+    which returns a view into an mmap buffer.
+
+    Delete the memmap instance to close.
+
+
+    Parameters
+    ----------
+    filename : str or file-like object
+        The file name or file object to be used as the array data buffer.
+    dtype : data-type, optional
+        The data-type used to interpret the file contents.
+        Default is `uint8`.
+    mode : {'r+', 'r', 'w+', 'c'}, optional
+        The file is opened in this mode:
+
+        +------+-------------------------------------------------------------+
+        | 'r'  | Open existing file for reading only.                        |
+        +------+-------------------------------------------------------------+
+        | 'r+' | Open existing file for reading and writing.                 |
+        +------+-------------------------------------------------------------+
+        | 'w+' | Create or overwrite existing file for reading and writing.  |
+        +------+-------------------------------------------------------------+
+        | 'c'  | Copy-on-write: assignments affect data in memory, but       |
+        |      | changes are not saved to disk.  The file on disk is         |
+        |      | read-only.                                                  |
+        +------+-------------------------------------------------------------+
+
+        Default is 'r+'.
+    offset : int, optional
+        In the file, array data starts at this offset. Since `offset` is
+        measured in bytes, it should normally be a multiple of the byte-size
+        of `dtype`. When ``mode != 'r'``, even positive offsets beyond end of
+        file are valid; The file will be extended to accommodate the
+        additional data. By default, ``memmap`` will start at the beginning of
+        the file, even if ``filename`` is a file pointer ``fp`` and
+        ``fp.tell() != 0``.
+    shape : tuple, optional
+        The desired shape of the array. If ``mode == 'r'`` and the number
+        of remaining bytes after `offset` is not a multiple of the byte-size
+        of `dtype`, you must specify `shape`. By default, the returned array
+        will be 1-D with the number of elements determined by file size
+        and data-type.
+    order : {'C', 'F'}, optional
+        Specify the order of the ndarray memory layout:
+        :term:`row-major`, C-style or :term:`column-major`,
+        Fortran-style.  This only has an effect if the shape is
+        greater than 1-D.  The default order is 'C'.
+
+    Attributes
+    ----------
+    filename : str
+        Path to the mapped file.
+    offset : int
+        Offset position in the file.
+    mode : str
+        File mode.
+
+    Methods
+    -------
+    flush
+        Flush any changes in memory to file on disk.
+        When you delete a memmap object, flush is called first to write
+        changes to disk before removing the object.
+
+
+    Notes
+    -----
+    The memmap object can be used anywhere an ndarray is accepted.
+    Given a memmap ``fp``, ``isinstance(fp, numpy.ndarray)`` returns
+    ``True``.
+
+    Memory-mapped arrays use the Python memory-map object which
+    (prior to Python 2.5) does not allow files to be larger than a
+    certain size depending on the platform. This size is always < 2GB
+    even on 64-bit systems.
+
+    When a memmap causes a file to be created or extended beyond its
+    current size in the filesystem, the contents of the new part are
+    unspecified. On systems with POSIX filesystem semantics, the extended
+    part will be filled with zero bytes.
+
+    Examples
+    --------
+    >>> data = np.arange(12, dtype='float32')
+    >>> data.resize((3,4))
+
+    This example uses a temporary file so that doctest doesn't write
+    files to your directory. You would use a 'normal' filename.
+
+    >>> from tempfile import mkdtemp
+    >>> import os.path as path
+    >>> filename = path.join(mkdtemp(), 'newfile.dat')
+
+    Create a memmap with dtype and shape that matches our data:
+
+    >>> fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4))
+    >>> fp
+    memmap([[ 0.,  0.,  0.,  0.],
+            [ 0.,  0.,  0.,  0.],
+            [ 0.,  0.,  0.,  0.]], dtype=float32)
+
+    Write data to memmap array:
+
+    >>> fp[:] = data[:]
+    >>> fp
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    >>> fp.filename == path.abspath(filename)
+    True
+
+    Deletion flushes memory changes to disk before removing the object:
+
+    >>> del fp
+
+    Load the memmap and verify data was stored:
+
+    >>> newfp = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+    >>> newfp
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    Read-only memmap:
+
+    >>> fpr = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+    >>> fpr.flags.writeable
+    False
+
+    Copy-on-write memmap:
+
+    >>> fpc = np.memmap(filename, dtype='float32', mode='c', shape=(3,4))
+    >>> fpc.flags.writeable
+    True
+
+    It's possible to assign to copy-on-write array, but values are only
+    written into the memory copy of the array, and not written to disk:
+
+    >>> fpc
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+    >>> fpc[0,:] = 0
+    >>> fpc
+    memmap([[  0.,   0.,   0.,   0.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    File on disk is unchanged:
+
+    >>> fpr
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    Offset into a memmap:
+
+    >>> fpo = np.memmap(filename, dtype='float32', mode='r', offset=16)
+    >>> fpo
+    memmap([  4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.], dtype=float32)
+
+    """
+
+    __array_priority__ = -100.0
+
+    def __new__(subtype, filename, dtype=uint8, mode='r+', offset=0,
+                shape=None, order='C'):
+        # Import here to minimize 'import numpy' overhead
+        import mmap
+        import os.path
+        try:
+            mode = mode_equivalents[mode]
+        except KeyError:
+            if mode not in valid_filemodes:
+                raise ValueError("mode must be one of %s" %
+                                 (valid_filemodes + list(mode_equivalents.keys())))
+
+        if hasattr(filename, 'read'):
+            fid = filename
+            own_file = False
+        else:
+            fid = open(filename, (mode == 'c' and 'r' or mode)+'b')
+            own_file = True
+
+        if (mode == 'w+') and shape is None:
+            raise ValueError("shape must be given")
+
+        fid.seek(0, 2)
+        flen = fid.tell()
+        descr = dtypedescr(dtype)
+        _dbytes = descr.itemsize
+
+        if shape is None:
+            bytes = flen - offset
+            if (bytes % _dbytes):
+                fid.close()
+                raise ValueError("Size of available data is not a "
+                        "multiple of the data-type size.")
+            size = bytes // _dbytes
+            shape = (size,)
+        else:
+            if not isinstance(shape, tuple):
+                shape = (shape,)
+            size = 1
+            for k in shape:
+                size *= k
+
+        bytes = long(offset + size*_dbytes)
+
+        if mode == 'w+' or (mode == 'r+' and flen < bytes):
+            fid.seek(bytes - 1, 0)
+            fid.write(np.compat.asbytes('\0'))
+            fid.flush()
+
+        if mode == 'c':
+            acc = mmap.ACCESS_COPY
+        elif mode == 'r':
+            acc = mmap.ACCESS_READ
+        else:
+            acc = mmap.ACCESS_WRITE
+
+        start = offset - offset % mmap.ALLOCATIONGRANULARITY
+        bytes -= start
+        offset -= start
+        mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
+
+        self = ndarray.__new__(subtype, shape, dtype=descr, buffer=mm,
+            offset=offset, order=order)
+        self._mmap = mm
+        self.offset = offset
+        self.mode = mode
+
+        if isinstance(filename, basestring):
+            self.filename = os.path.abspath(filename)
+        # py3 returns int for TemporaryFile().name
+        elif (hasattr(filename, "name") and
+              isinstance(filename.name, basestring)):
+            self.filename = os.path.abspath(filename.name)
+        # same as memmap copies (e.g. memmap + 1)
+        else:
+            self.filename = None
+
+        if own_file:
+            fid.close()
+
+        return self
+
+    def __array_finalize__(self, obj):
+        if hasattr(obj, '_mmap') and np.may_share_memory(self, obj):
+            self._mmap = obj._mmap
+            self.filename = obj.filename
+            self.offset = obj.offset
+            self.mode = obj.mode
+        else:
+            self._mmap = None
+            self.filename = None
+            self.offset = None
+            self.mode = None
+
+    def flush(self):
+        """
+        Write any changes in the array to the file on disk.
+
+        For further information, see `memmap`.
+
+        Parameters
+        ----------
+        None
+
+        See Also
+        --------
+        memmap
+
+        """
+        if self.base is not None and hasattr(self.base, 'flush'):
+            self.base.flush()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..2109023721ed5401b4f88fa21eca984abe0b9ecb
GIT binary patch
literal 1492480
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..c2d966cb3b34efe3604b624680f209d1e0d3f0d9
GIT binary patch
literal 67584
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numeric.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numeric.py
new file mode 100644
index 0000000000..0b728f8043
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numeric.py
@@ -0,0 +1,2996 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import operator
+import warnings
+import collections
+from numpy.core import multiarray
+from . import umath
+from .umath import (invert, sin, UFUNC_BUFSIZE_DEFAULT, ERR_IGNORE,
+                    ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG,
+                    ERR_DEFAULT, PINF, NAN)
+from . import numerictypes
+from .numerictypes import longlong, intc, int_, float_, complex_, bool_
+from ._internal import TooHardError
+
+if sys.version_info[0] >= 3:
+    import pickle
+    basestring = str
+    import builtins
+else:
+    import cPickle as pickle
+    import __builtin__ as builtins
+
+loads = pickle.loads
+
+
+__all__ = [
+    'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
+    'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast',
+    'dtype', 'fromstring', 'fromfile', 'frombuffer', 'int_asbuffer',
+    'where', 'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose',
+    'lexsort', 'set_numeric_ops', 'can_cast', 'promote_types',
+    'min_scalar_type', 'result_type', 'asarray', 'asanyarray',
+    'ascontiguousarray', 'asfortranarray', 'isfortran', 'empty_like',
+    'zeros_like', 'ones_like', 'correlate', 'convolve', 'inner', 'dot',
+    'einsum', 'outer', 'vdot', 'alterdot', 'restoredot', 'roll',
+    'rollaxis', 'moveaxis', 'cross', 'tensordot', 'array2string',
+    'get_printoptions', 'set_printoptions', 'array_repr', 'array_str',
+    'set_string_function', 'little_endian', 'require', 'fromiter',
+    'array_equal', 'array_equiv', 'indices', 'fromfunction', 'isclose', 'load',
+    'loads', 'isscalar', 'binary_repr', 'base_repr', 'ones', 'identity',
+    'allclose', 'compare_chararrays', 'putmask', 'seterr', 'geterr',
+    'setbufsize', 'getbufsize', 'seterrcall', 'geterrcall', 'errstate',
+    'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_',
+    'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS', 'BUFSIZE',
+    'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like', 'matmul',
+    'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT',
+    'TooHardError',
+    ]
+
+if sys.version_info[0] < 3:
+    __all__.extend(['getbuffer', 'newbuffer'])
+
+
+class ComplexWarning(RuntimeWarning):
+    """
+    The warning raised when casting a complex dtype to a real dtype.
+
+    As implemented, casting a complex number to a real discards its imaginary
+    part, but this behavior may not be what the user actually wants.
+
+    """
+    pass
+
+bitwise_not = invert
+
+CLIP = multiarray.CLIP
+WRAP = multiarray.WRAP
+RAISE = multiarray.RAISE
+MAXDIMS = multiarray.MAXDIMS
+ALLOW_THREADS = multiarray.ALLOW_THREADS
+BUFSIZE = multiarray.BUFSIZE
+MAY_SHARE_BOUNDS = multiarray.MAY_SHARE_BOUNDS
+MAY_SHARE_EXACT = multiarray.MAY_SHARE_EXACT
+
+ndarray = multiarray.ndarray
+flatiter = multiarray.flatiter
+nditer = multiarray.nditer
+nested_iters = multiarray.nested_iters
+broadcast = multiarray.broadcast
+dtype = multiarray.dtype
+copyto = multiarray.copyto
+ufunc = type(sin)
+
+
+def zeros_like(a, dtype=None, order='K', subok=True):
+    """
+    Return an array of zeros with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of zeros with the same shape and type as `a`.
+
+    See Also
+    --------
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> x = np.arange(6)
+    >>> x = x.reshape((2, 3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.zeros_like(x)
+    array([[0, 0, 0],
+           [0, 0, 0]])
+
+    >>> y = np.arange(3, dtype=np.float)
+    >>> y
+    array([ 0.,  1.,  2.])
+    >>> np.zeros_like(y)
+    array([ 0.,  0.,  0.])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    # needed instead of a 0 to get same result as zeros for for string dtypes
+    z = zeros(1, dtype=res.dtype)
+    multiarray.copyto(res, z, casting='unsafe')
+    return res
+
+def ones(shape, dtype=None, order='C'):
+    """
+    Return a new array of given shape and type, filled with ones.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `numpy.int8`.  Default is
+        `numpy.float64`.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of ones with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros, ones_like
+
+    Examples
+    --------
+    >>> np.ones(5)
+    array([ 1.,  1.,  1.,  1.,  1.])
+
+    >>> np.ones((5,), dtype=np.int)
+    array([1, 1, 1, 1, 1])
+
+    >>> np.ones((2, 1))
+    array([[ 1.],
+           [ 1.]])
+
+    >>> s = (2,2)
+    >>> np.ones(s)
+    array([[ 1.,  1.],
+           [ 1.,  1.]])
+
+    """
+    a = empty(shape, dtype, order)
+    multiarray.copyto(a, 1, casting='unsafe')
+    return a
+
+def ones_like(a, dtype=None, order='K', subok=True):
+    """
+    Return an array of ones with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of ones with the same shape and type as `a`.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> x = np.arange(6)
+    >>> x = x.reshape((2, 3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.ones_like(x)
+    array([[1, 1, 1],
+           [1, 1, 1]])
+
+    >>> y = np.arange(3, dtype=np.float)
+    >>> y
+    array([ 0.,  1.,  2.])
+    >>> np.ones_like(y)
+    array([ 1.,  1.,  1.])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    multiarray.copyto(res, 1, casting='unsafe')
+    return res
+
+def full(shape, fill_value, dtype=None, order='C'):
+    """
+    Return a new array of given shape and type, filled with `fill_value`.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    fill_value : scalar
+        Fill value.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `np.int8`.  Default
+        is `float`, but will change to `np.array(fill_value).dtype` in a
+        future release.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of `fill_value` with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    full_like : Fill an array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> np.full((2, 2), np.inf)
+    array([[ inf,  inf],
+           [ inf,  inf]])
+    >>> np.full((2, 2), 10, dtype=np.int)
+    array([[10, 10],
+           [10, 10]])
+
+    """
+    a = empty(shape, dtype, order)
+    if dtype is None and array(fill_value).dtype != a.dtype:
+        warnings.warn(
+            "in the future, full({0}, {1!r}) will return an array of {2!r}".
+            format(shape, fill_value, array(fill_value).dtype), FutureWarning)
+    multiarray.copyto(a, fill_value, casting='unsafe')
+    return a
+
+def full_like(a, fill_value, dtype=None, order='K', subok=True):
+    """
+    Return a full array with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    fill_value : scalar
+        Fill value.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of `fill_value` with the same shape and type as `a`.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+    full : Fill a new array.
+
+    Examples
+    --------
+    >>> x = np.arange(6, dtype=np.int)
+    >>> np.full_like(x, 1)
+    array([1, 1, 1, 1, 1, 1])
+    >>> np.full_like(x, 0.1)
+    array([0, 0, 0, 0, 0, 0])
+    >>> np.full_like(x, 0.1, dtype=np.double)
+    array([ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1])
+    >>> np.full_like(x, np.nan, dtype=np.double)
+    array([ nan,  nan,  nan,  nan,  nan,  nan])
+
+    >>> y = np.arange(6, dtype=np.double)
+    >>> np.full_like(y, 0.1)
+    array([ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    multiarray.copyto(res, fill_value, casting='unsafe')
+    return res
+
+
+def extend_all(module):
+    adict = {}
+    for a in __all__:
+        adict[a] = 1
+    try:
+        mall = getattr(module, '__all__')
+    except AttributeError:
+        mall = [k for k in module.__dict__.keys() if not k.startswith('_')]
+    for a in mall:
+        if a not in adict:
+            __all__.append(a)
+
+newaxis = None
+
+
+arange = multiarray.arange
+array = multiarray.array
+zeros = multiarray.zeros
+count_nonzero = multiarray.count_nonzero
+empty = multiarray.empty
+empty_like = multiarray.empty_like
+fromstring = multiarray.fromstring
+fromiter = multiarray.fromiter
+fromfile = multiarray.fromfile
+frombuffer = multiarray.frombuffer
+shares_memory = multiarray.shares_memory
+may_share_memory = multiarray.may_share_memory
+if sys.version_info[0] < 3:
+    newbuffer = multiarray.newbuffer
+    getbuffer = multiarray.getbuffer
+int_asbuffer = multiarray.int_asbuffer
+where = multiarray.where
+concatenate = multiarray.concatenate
+fastCopyAndTranspose = multiarray._fastCopyAndTranspose
+set_numeric_ops = multiarray.set_numeric_ops
+can_cast = multiarray.can_cast
+promote_types = multiarray.promote_types
+min_scalar_type = multiarray.min_scalar_type
+result_type = multiarray.result_type
+lexsort = multiarray.lexsort
+compare_chararrays = multiarray.compare_chararrays
+putmask = multiarray.putmask
+einsum = multiarray.einsum
+dot = multiarray.dot
+inner = multiarray.inner
+vdot = multiarray.vdot
+matmul = multiarray.matmul
+
+
+def asarray(a, dtype=None, order=None):
+    """Convert the input to an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists and ndarrays.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major (C-style) or
+        column-major (Fortran-style) memory representation.
+        Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray
+        Array interpretation of `a`.  No copy is performed if the input
+        is already an ndarray.  If `a` is a subclass of ndarray, a base
+        class ndarray is returned.
+
+    See Also
+    --------
+    asanyarray : Similar function which passes through subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    asarray_chkfinite : Similar function which checks input for NaNs and Infs.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array:
+
+    >>> a = [1, 2]
+    >>> np.asarray(a)
+    array([1, 2])
+
+    Existing arrays are not copied:
+
+    >>> a = np.array([1, 2])
+    >>> np.asarray(a) is a
+    True
+
+    If `dtype` is set, array is copied only if dtype does not match:
+
+    >>> a = np.array([1, 2], dtype=np.float32)
+    >>> np.asarray(a, dtype=np.float32) is a
+    True
+    >>> np.asarray(a, dtype=np.float64) is a
+    False
+
+    Contrary to `asanyarray`, ndarray subclasses are not passed through:
+
+    >>> issubclass(np.matrix, np.ndarray)
+    True
+    >>> a = np.matrix([[1, 2]])
+    >>> np.asarray(a) is a
+    False
+    >>> np.asanyarray(a) is a
+    True
+
+    """
+    return array(a, dtype, copy=False, order=order)
+
+def asanyarray(a, dtype=None, order=None):
+    """Convert the input to an ndarray, but pass ndarray subclasses through.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes scalars, lists, lists of tuples, tuples, tuples of tuples,
+        tuples of lists, and ndarrays.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major (C-style) or column-major
+        (Fortran-style) memory representation.  Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray or an ndarray subclass
+        Array interpretation of `a`.  If `a` is an ndarray or a subclass
+        of ndarray, it is returned as-is and no copy is performed.
+
+    See Also
+    --------
+    asarray : Similar function which always returns ndarrays.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    asarray_chkfinite : Similar function which checks input for NaNs and
+                        Infs.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array:
+
+    >>> a = [1, 2]
+    >>> np.asanyarray(a)
+    array([1, 2])
+
+    Instances of `ndarray` subclasses are passed through as-is:
+
+    >>> a = np.matrix([1, 2])
+    >>> np.asanyarray(a) is a
+    True
+
+    """
+    return array(a, dtype, copy=False, order=order, subok=True)
+
+def ascontiguousarray(a, dtype=None):
+    """
+    Return a contiguous array in memory (C order).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    dtype : str or dtype object, optional
+        Data-type of returned array.
+
+    Returns
+    -------
+    out : ndarray
+        Contiguous array of same shape and content as `a`, with type `dtype`
+        if specified.
+
+    See Also
+    --------
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    require : Return an ndarray that satisfies requirements.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> np.ascontiguousarray(x, dtype=np.float32)
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4.,  5.]], dtype=float32)
+    >>> x.flags['C_CONTIGUOUS']
+    True
+
+    """
+    return array(a, dtype, copy=False, order='C', ndmin=1)
+
+def asfortranarray(a, dtype=None):
+    """
+    Return an array laid out in Fortran order in memory.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    dtype : str or dtype object, optional
+        By default, the data-type is inferred from the input data.
+
+    Returns
+    -------
+    out : ndarray
+        The input `a` in Fortran, or column-major, order.
+
+    See Also
+    --------
+    ascontiguousarray : Convert input to a contiguous (C order) array.
+    asanyarray : Convert input to an ndarray with either row or
+        column-major memory order.
+    require : Return an ndarray that satisfies requirements.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> y = np.asfortranarray(x)
+    >>> x.flags['F_CONTIGUOUS']
+    False
+    >>> y.flags['F_CONTIGUOUS']
+    True
+
+    """
+    return array(a, dtype, copy=False, order='F', ndmin=1)
+
+def require(a, dtype=None, requirements=None):
+    """
+    Return an ndarray of the provided type that satisfies requirements.
+
+    This function is useful to be sure that an array with the correct flags
+    is returned for passing to compiled code (perhaps through ctypes).
+
+    Parameters
+    ----------
+    a : array_like
+       The object to be converted to a type-and-requirement-satisfying array.
+    dtype : data-type
+       The required data-type. If None preserve the current dtype. If your
+       application requires the data to be in native byteorder, include
+       a byteorder specification as a part of the dtype specification.
+    requirements : str or list of str
+       The requirements list can be any of the following
+
+       * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array
+       * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array
+       * 'ALIGNED' ('A')      - ensure a data-type aligned array
+       * 'WRITEABLE' ('W')    - ensure a writable array
+       * 'OWNDATA' ('O')      - ensure an array that owns its own data
+       * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass
+
+    See Also
+    --------
+    asarray : Convert input to an ndarray.
+    asanyarray : Convert to an ndarray, but pass through ndarray subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Notes
+    -----
+    The returned array will be guaranteed to have the listed requirements
+    by making a copy if needed.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> x.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : False
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+
+    >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F'])
+    >>> y.flags
+      C_CONTIGUOUS : False
+      F_CONTIGUOUS : True
+      OWNDATA : True
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+
+    """
+    possible_flags = {'C':'C', 'C_CONTIGUOUS':'C', 'CONTIGUOUS':'C',
+                      'F':'F', 'F_CONTIGUOUS':'F', 'FORTRAN':'F',
+                      'A':'A', 'ALIGNED':'A',
+                      'W':'W', 'WRITEABLE':'W',
+                      'O':'O', 'OWNDATA':'O',
+                      'E':'E', 'ENSUREARRAY':'E'}
+    if not requirements:
+        return asanyarray(a, dtype=dtype)
+    else:
+        requirements = set(possible_flags[x.upper()] for x in requirements)
+
+    if 'E' in requirements:
+        requirements.remove('E')
+        subok = False
+    else:
+        subok = True
+
+    order = 'A'
+    if requirements >= set(['C', 'F']):
+        raise ValueError('Cannot specify both "C" and "F" order')
+    elif 'F' in requirements:
+        order = 'F'
+        requirements.remove('F')
+    elif 'C' in requirements:
+        order = 'C'
+        requirements.remove('C')
+
+    arr = array(a, dtype=dtype, order=order, copy=False, subok=subok)
+
+    for prop in requirements:
+        if not arr.flags[prop]:
+            arr = arr.copy(order)
+            break
+    return arr
+
+def isfortran(a):
+    """
+    Returns True if the array is Fortran contiguous but *not* C contiguous.
+
+    This function is obsolete and, because of changes due to relaxed stride
+    checking, its return value for the same array may differ for versions
+    of Numpy >= 1.10 and previous versions. If you only want to check if an
+    array is Fortran contiguous use ``a.flags.f_contiguous`` instead.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+
+
+    Examples
+    --------
+
+    np.array allows to specify whether the array is written in C-contiguous
+    order (last index varies the fastest), or FORTRAN-contiguous order in
+    memory (first index varies the fastest).
+
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(a)
+    False
+
+    >>> b = np.array([[1, 2, 3], [4, 5, 6]], order='FORTRAN')
+    >>> b
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(b)
+    True
+
+
+    The transpose of a C-ordered array is a FORTRAN-ordered array.
+
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(a)
+    False
+    >>> b = a.T
+    >>> b
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+    >>> np.isfortran(b)
+    True
+
+    C-ordered arrays evaluate as False even if they are also FORTRAN-ordered.
+
+    >>> np.isfortran(np.array([1, 2], order='FORTRAN'))
+    False
+
+    """
+    return a.flags.fnc
+
+def argwhere(a):
+    """
+    Find the indices of array elements that are non-zero, grouped by element.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+
+    Returns
+    -------
+    index_array : ndarray
+        Indices of elements that are non-zero. Indices are grouped by element.
+
+    See Also
+    --------
+    where, nonzero
+
+    Notes
+    -----
+    ``np.argwhere(a)`` is the same as ``np.transpose(np.nonzero(a))``.
+
+    The output of ``argwhere`` is not suitable for indexing arrays.
+    For this purpose use ``where(a)`` instead.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argwhere(x>1)
+    array([[0, 2],
+           [1, 0],
+           [1, 1],
+           [1, 2]])
+
+    """
+    return transpose(nonzero(a))
+
+def flatnonzero(a):
+    """
+    Return indices that are non-zero in the flattened version of a.
+
+    This is equivalent to a.ravel().nonzero()[0].
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+
+    Returns
+    -------
+    res : ndarray
+        Output array, containing the indices of the elements of `a.ravel()`
+        that are non-zero.
+
+    See Also
+    --------
+    nonzero : Return the indices of the non-zero elements of the input array.
+    ravel : Return a 1-D array containing the elements of the input array.
+
+    Examples
+    --------
+    >>> x = np.arange(-2, 3)
+    >>> x
+    array([-2, -1,  0,  1,  2])
+    >>> np.flatnonzero(x)
+    array([0, 1, 3, 4])
+
+    Use the indices of the non-zero elements as an index array to extract
+    these elements:
+
+    >>> x.ravel()[np.flatnonzero(x)]
+    array([-2, -1,  1,  2])
+
+    """
+    return a.ravel().nonzero()[0]
+
+_mode_from_name_dict = {'v': 0,
+                        's': 1,
+                        'f': 2}
+
+def _mode_from_name(mode):
+    if isinstance(mode, basestring):
+        return _mode_from_name_dict[mode.lower()[0]]
+    return mode
+
+def correlate(a, v, mode='valid'):
+    """
+    Cross-correlation of two 1-dimensional sequences.
+
+    This function computes the correlation as generally defined in signal
+    processing texts::
+
+        c_{av}[k] = sum_n a[n+k] * conj(v[n])
+
+    with a and v sequences being zero-padded where necessary and conj being
+    the conjugate.
+
+    Parameters
+    ----------
+    a, v : array_like
+        Input sequences.
+    mode : {'valid', 'same', 'full'}, optional
+        Refer to the `convolve` docstring.  Note that the default
+        is 'valid', unlike `convolve`, which uses 'full'.
+    old_behavior : bool
+        `old_behavior` was removed in NumPy 1.10. If you need the old
+        behavior, use `multiarray.correlate`.
+
+    Returns
+    -------
+    out : ndarray
+        Discrete cross-correlation of `a` and `v`.
+
+    See Also
+    --------
+    convolve : Discrete, linear convolution of two one-dimensional sequences.
+    multiarray.correlate : Old, no conjugate, version of correlate.
+
+    Notes
+    -----
+    The definition of correlation above is not unique and sometimes correlation
+    may be defined differently. Another common definition is::
+
+        c'_{av}[k] = sum_n a[n] conj(v[n+k])
+
+    which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``.
+
+    Examples
+    --------
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5])
+    array([ 3.5])
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5], "same")
+    array([ 2. ,  3.5,  3. ])
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5], "full")
+    array([ 0.5,  2. ,  3.5,  3. ,  0. ])
+
+    Using complex sequences:
+
+    >>> np.correlate([1+1j, 2, 3-1j], [0, 1, 0.5j], 'full')
+    array([ 0.5-0.5j,  1.0+0.j ,  1.5-1.5j,  3.0-1.j ,  0.0+0.j ])
+
+    Note that you get the time reversed, complex conjugated result
+    when the two input sequences change places, i.e.,
+    ``c_{va}[k] = c^{*}_{av}[-k]``:
+
+    >>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full')
+    array([ 0.0+0.j ,  3.0+1.j ,  1.5+1.5j,  1.0+0.j ,  0.5+0.5j])
+
+    """
+    mode = _mode_from_name(mode)
+    return multiarray.correlate2(a, v, mode)
+
+def convolve(a,v,mode='full'):
+    """
+    Returns the discrete, linear convolution of two one-dimensional sequences.
+
+    The convolution operator is often seen in signal processing, where it
+    models the effect of a linear time-invariant system on a signal [1]_.  In
+    probability theory, the sum of two independent random variables is
+    distributed according to the convolution of their individual
+    distributions.
+
+    If `v` is longer than `a`, the arrays are swapped before computation.
+
+    Parameters
+    ----------
+    a : (N,) array_like
+        First one-dimensional input array.
+    v : (M,) array_like
+        Second one-dimensional input array.
+    mode : {'full', 'valid', 'same'}, optional
+        'full':
+          By default, mode is 'full'.  This returns the convolution
+          at each point of overlap, with an output shape of (N+M-1,). At
+          the end-points of the convolution, the signals do not overlap
+          completely, and boundary effects may be seen.
+
+        'same':
+          Mode 'same' returns output of length ``max(M, N)``.  Boundary
+          effects are still visible.
+
+        'valid':
+          Mode 'valid' returns output of length
+          ``max(M, N) - min(M, N) + 1``.  The convolution product is only given
+          for points where the signals overlap completely.  Values outside
+          the signal boundary have no effect.
+
+    Returns
+    -------
+    out : ndarray
+        Discrete, linear convolution of `a` and `v`.
+
+    See Also
+    --------
+    scipy.signal.fftconvolve : Convolve two arrays using the Fast Fourier
+                               Transform.
+    scipy.linalg.toeplitz : Used to construct the convolution operator.
+    polymul : Polynomial multiplication. Same output as convolve, but also
+              accepts poly1d objects as input.
+
+    Notes
+    -----
+    The discrete convolution operation is defined as
+
+    .. math:: (a * v)[n] = \\sum_{m = -\\infty}^{\\infty} a[m] v[n - m]
+
+    It can be shown that a convolution :math:`x(t) * y(t)` in time/space
+    is equivalent to the multiplication :math:`X(f) Y(f)` in the Fourier
+    domain, after appropriate padding (padding is necessary to prevent
+    circular convolution).  Since multiplication is more efficient (faster)
+    than convolution, the function `scipy.signal.fftconvolve` exploits the
+    FFT to calculate the convolution of large data-sets.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Convolution", http://en.wikipedia.org/wiki/Convolution.
+
+    Examples
+    --------
+    Note how the convolution operator flips the second array
+    before "sliding" the two across one another:
+
+    >>> np.convolve([1, 2, 3], [0, 1, 0.5])
+    array([ 0. ,  1. ,  2.5,  4. ,  1.5])
+
+    Only return the middle values of the convolution.
+    Contains boundary effects, where zeros are taken
+    into account:
+
+    >>> np.convolve([1,2,3],[0,1,0.5], 'same')
+    array([ 1. ,  2.5,  4. ])
+
+    The two arrays are of the same length, so there
+    is only one position where they completely overlap:
+
+    >>> np.convolve([1,2,3],[0,1,0.5], 'valid')
+    array([ 2.5])
+
+    """
+    a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1)
+    if (len(v) > len(a)):
+        a, v = v, a
+    if len(a) == 0:
+        raise ValueError('a cannot be empty')
+    if len(v) == 0:
+        raise ValueError('v cannot be empty')
+    mode = _mode_from_name(mode)
+    return multiarray.correlate(a, v[::-1], mode)
+
+def outer(a, b, out=None):
+    """
+    Compute the outer product of two vectors.
+
+    Given two vectors, ``a = [a0, a1, ..., aM]`` and
+    ``b = [b0, b1, ..., bN]``,
+    the outer product [1]_ is::
+
+      [[a0*b0  a0*b1 ... a0*bN ]
+       [a1*b0    .
+       [ ...          .
+       [aM*b0            aM*bN ]]
+
+    Parameters
+    ----------
+    a : (M,) array_like
+        First input vector.  Input is flattened if
+        not already 1-dimensional.
+    b : (N,) array_like
+        Second input vector.  Input is flattened if
+        not already 1-dimensional.
+    out : (M, N) ndarray, optional
+        A location where the result is stored
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    out : (M, N) ndarray
+        ``out[i, j] = a[i] * b[j]``
+
+    See also
+    --------
+    inner, einsum
+
+    References
+    ----------
+    .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd
+             ed., Baltimore, MD, Johns Hopkins University Press, 1996,
+             pg. 8.
+
+    Examples
+    --------
+    Make a (*very* coarse) grid for computing a Mandelbrot set:
+
+    >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5))
+    >>> rl
+    array([[-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.]])
+    >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
+    >>> im
+    array([[ 0.+2.j,  0.+2.j,  0.+2.j,  0.+2.j,  0.+2.j],
+           [ 0.+1.j,  0.+1.j,  0.+1.j,  0.+1.j,  0.+1.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.-1.j,  0.-1.j,  0.-1.j,  0.-1.j,  0.-1.j],
+           [ 0.-2.j,  0.-2.j,  0.-2.j,  0.-2.j,  0.-2.j]])
+    >>> grid = rl + im
+    >>> grid
+    array([[-2.+2.j, -1.+2.j,  0.+2.j,  1.+2.j,  2.+2.j],
+           [-2.+1.j, -1.+1.j,  0.+1.j,  1.+1.j,  2.+1.j],
+           [-2.+0.j, -1.+0.j,  0.+0.j,  1.+0.j,  2.+0.j],
+           [-2.-1.j, -1.-1.j,  0.-1.j,  1.-1.j,  2.-1.j],
+           [-2.-2.j, -1.-2.j,  0.-2.j,  1.-2.j,  2.-2.j]])
+
+    An example using a "vector" of letters:
+
+    >>> x = np.array(['a', 'b', 'c'], dtype=object)
+    >>> np.outer(x, [1, 2, 3])
+    array([[a, aa, aaa],
+           [b, bb, bbb],
+           [c, cc, ccc]], dtype=object)
+
+    """
+    a = asarray(a)
+    b = asarray(b)
+    return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out)
+
+
+def alterdot():
+    """
+    Change `dot`, `vdot`, and `inner` to use accelerated BLAS functions.
+
+    Typically, as a user of Numpy, you do not explicitly call this
+    function. If Numpy is built with an accelerated BLAS, this function is
+    automatically called when Numpy is imported.
+
+    When Numpy is built with an accelerated BLAS like ATLAS, these
+    functions are replaced to make use of the faster implementations.  The
+    faster implementations only affect float32, float64, complex64, and
+    complex128 arrays. Furthermore, the BLAS API only includes
+    matrix-matrix, matrix-vector, and vector-vector products. Products of
+    arrays with larger dimensionalities use the built in functions and are
+    not accelerated.
+
+    .. note:: Deprecated in Numpy 1.10
+              The cblas functions have been integrated into the multarray
+              module and alterdot now longer does anything. It will be
+              removed in Numpy 1.11.0.
+
+    See Also
+    --------
+    restoredot : `restoredot` undoes the effects of `alterdot`.
+
+    """
+    # 2014-08-13, 1.10
+    warnings.warn("alterdot no longer does anything.", DeprecationWarning)
+
+
+def restoredot():
+    """
+    Restore `dot`, `vdot`, and `innerproduct` to the default non-BLAS
+    implementations.
+
+    Typically, the user will only need to call this when troubleshooting
+    and installation problem, reproducing the conditions of a build without
+    an accelerated BLAS, or when being very careful about benchmarking
+    linear algebra operations.
+
+    .. note:: Deprecated in Numpy 1.10
+              The cblas functions have been integrated into the multarray
+              module and restoredot now longer does anything. It will be
+              removed in Numpy 1.11.0.
+
+    See Also
+    --------
+    alterdot : `restoredot` undoes the effects of `alterdot`.
+
+    """
+    # 2014-08-13, 1.10
+    warnings.warn("restoredot no longer does anything.", DeprecationWarning)
+
+
+def tensordot(a, b, axes=2):
+    """
+    Compute tensor dot product along specified axes for arrays >= 1-D.
+
+    Given two tensors (arrays of dimension greater than or equal to one),
+    `a` and `b`, and an array_like object containing two array_like
+    objects, ``(a_axes, b_axes)``, sum the products of `a`'s and `b`'s
+    elements (components) over the axes specified by ``a_axes`` and
+    ``b_axes``. The third argument can be a single non-negative
+    integer_like scalar, ``N``; if it is such, then the last ``N``
+    dimensions of `a` and the first ``N`` dimensions of `b` are summed
+    over.
+
+    Parameters
+    ----------
+    a, b : array_like, len(shape) >= 1
+        Tensors to "dot".
+
+    axes : int or (2,) array_like
+        * integer_like
+          If an int N, sum over the last N axes of `a` and the first N axes
+          of `b` in order. The sizes of the corresponding axes must match.
+        * (2,) array_like
+          Or, a list of axes to be summed over, first sequence applying to `a`,
+          second to `b`. Both elements array_like must be of the same length.
+
+    See Also
+    --------
+    dot, einsum
+
+    Notes
+    -----
+    Three common use cases are:
+        ``axes = 0`` : tensor product $a\otimes b$
+        ``axes = 1`` : tensor dot product $a\cdot b$
+        ``axes = 2`` : (default) tensor double contraction $a:b$
+
+    When `axes` is integer_like, the sequence for evaluation will be: first
+    the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and
+    Nth axis in `b` last.
+
+    When there is more than one axis to sum over - and they are not the last
+    (first) axes of `a` (`b`) - the argument `axes` should consist of
+    two sequences of the same length, with the first axis to sum over given
+    first in both sequences, the second axis second, and so forth.
+
+    Examples
+    --------
+    A "traditional" example:
+
+    >>> a = np.arange(60.).reshape(3,4,5)
+    >>> b = np.arange(24.).reshape(4,3,2)
+    >>> c = np.tensordot(a,b, axes=([1,0],[0,1]))
+    >>> c.shape
+    (5, 2)
+    >>> c
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> # A slower but equivalent way of computing the same...
+    >>> d = np.zeros((5,2))
+    >>> for i in range(5):
+    ...   for j in range(2):
+    ...     for k in range(3):
+    ...       for n in range(4):
+    ...         d[i,j] += a[k,n,i] * b[n,k,j]
+    >>> c == d
+    array([[ True,  True],
+           [ True,  True],
+           [ True,  True],
+           [ True,  True],
+           [ True,  True]], dtype=bool)
+
+    An extended example taking advantage of the overloading of + and \\*:
+
+    >>> a = np.array(range(1, 9))
+    >>> a.shape = (2, 2, 2)
+    >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object)
+    >>> A.shape = (2, 2)
+    >>> a; A
+    array([[[1, 2],
+            [3, 4]],
+           [[5, 6],
+            [7, 8]]])
+    array([[a, b],
+           [c, d]], dtype=object)
+
+    >>> np.tensordot(a, A) # third argument default is 2 for double-contraction
+    array([abbcccdddd, aaaaabbbbbbcccccccdddddddd], dtype=object)
+
+    >>> np.tensordot(a, A, 1)
+    array([[[acc, bdd],
+            [aaacccc, bbbdddd]],
+           [[aaaaacccccc, bbbbbdddddd],
+            [aaaaaaacccccccc, bbbbbbbdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, 0) # tensor product (result too long to incl.)
+    array([[[[[a, b],
+              [c, d]],
+              ...
+
+    >>> np.tensordot(a, A, (0, 1))
+    array([[[abbbbb, cddddd],
+            [aabbbbbb, ccdddddd]],
+           [[aaabbbbbbb, cccddddddd],
+            [aaaabbbbbbbb, ccccdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, (2, 1))
+    array([[[abb, cdd],
+            [aaabbbb, cccdddd]],
+           [[aaaaabbbbbb, cccccdddddd],
+            [aaaaaaabbbbbbbb, cccccccdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, ((0, 1), (0, 1)))
+    array([abbbcccccddddddd, aabbbbccccccdddddddd], dtype=object)
+
+    >>> np.tensordot(a, A, ((2, 1), (1, 0)))
+    array([acccbbdddd, aaaaacccccccbbbbbbdddddddd], dtype=object)
+
+    """
+    try:
+        iter(axes)
+    except:
+        axes_a = list(range(-axes, 0))
+        axes_b = list(range(0, axes))
+    else:
+        axes_a, axes_b = axes
+    try:
+        na = len(axes_a)
+        axes_a = list(axes_a)
+    except TypeError:
+        axes_a = [axes_a]
+        na = 1
+    try:
+        nb = len(axes_b)
+        axes_b = list(axes_b)
+    except TypeError:
+        axes_b = [axes_b]
+        nb = 1
+
+    a, b = asarray(a), asarray(b)
+    as_ = a.shape
+    nda = len(a.shape)
+    bs = b.shape
+    ndb = len(b.shape)
+    equal = True
+    if na != nb:
+        equal = False
+    else:
+        for k in range(na):
+            if as_[axes_a[k]] != bs[axes_b[k]]:
+                equal = False
+                break
+            if axes_a[k] < 0:
+                axes_a[k] += nda
+            if axes_b[k] < 0:
+                axes_b[k] += ndb
+    if not equal:
+        raise ValueError("shape-mismatch for sum")
+
+    # Move the axes to sum over to the end of "a"
+    # and to the front of "b"
+    notin = [k for k in range(nda) if k not in axes_a]
+    newaxes_a = notin + axes_a
+    N2 = 1
+    for axis in axes_a:
+        N2 *= as_[axis]
+    newshape_a = (-1, N2)
+    olda = [as_[axis] for axis in notin]
+
+    notin = [k for k in range(ndb) if k not in axes_b]
+    newaxes_b = axes_b + notin
+    N2 = 1
+    for axis in axes_b:
+        N2 *= bs[axis]
+    newshape_b = (N2, -1)
+    oldb = [bs[axis] for axis in notin]
+
+    at = a.transpose(newaxes_a).reshape(newshape_a)
+    bt = b.transpose(newaxes_b).reshape(newshape_b)
+    res = dot(at, bt)
+    return res.reshape(olda + oldb)
+
+def roll(a, shift, axis=None):
+    """
+    Roll array elements along a given axis.
+
+    Elements that roll beyond the last position are re-introduced at
+    the first.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    shift : int
+        The number of places by which elements are shifted.
+    axis : int, optional
+        The axis along which elements are shifted.  By default, the array
+        is flattened before shifting, after which the original
+        shape is restored.
+
+    Returns
+    -------
+    res : ndarray
+        Output array, with the same shape as `a`.
+
+    See Also
+    --------
+    rollaxis : Roll the specified axis backwards, until it lies in a
+               given position.
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> np.roll(x, 2)
+    array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
+
+    >>> x2 = np.reshape(x, (2,5))
+    >>> x2
+    array([[0, 1, 2, 3, 4],
+           [5, 6, 7, 8, 9]])
+    >>> np.roll(x2, 1)
+    array([[9, 0, 1, 2, 3],
+           [4, 5, 6, 7, 8]])
+    >>> np.roll(x2, 1, axis=0)
+    array([[5, 6, 7, 8, 9],
+           [0, 1, 2, 3, 4]])
+    >>> np.roll(x2, 1, axis=1)
+    array([[4, 0, 1, 2, 3],
+           [9, 5, 6, 7, 8]])
+
+    """
+    a = asanyarray(a)
+    if axis is None:
+        n = a.size
+        reshape = True
+    else:
+        try:
+            n = a.shape[axis]
+        except IndexError:
+            raise ValueError('axis must be >= 0 and < %d' % a.ndim)
+        reshape = False
+    if n == 0:
+        return a
+    shift %= n
+    indexes = concatenate((arange(n - shift, n), arange(n - shift)))
+    res = a.take(indexes, axis)
+    if reshape:
+        res = res.reshape(a.shape)
+    return res
+
+
+def rollaxis(a, axis, start=0):
+    """
+    Roll the specified axis backwards, until it lies in a given position.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    axis : int
+        The axis to roll backwards.  The positions of the other axes do not
+        change relative to one another.
+    start : int, optional
+        The axis is rolled until it lies before this position.  The default,
+        0, results in a "complete" roll.
+
+    Returns
+    -------
+    res : ndarray
+        For Numpy >= 1.10 a view of `a` is always returned. For earlier
+        Numpy versions a view of `a` is returned only if the order of the
+        axes is changed, otherwise the input array is returned.
+
+    See Also
+    --------
+    moveaxis : Move array axes to new positions.
+    roll : Roll the elements of an array by a number of positions along a
+        given axis.
+
+    Examples
+    --------
+    >>> a = np.ones((3,4,5,6))
+    >>> np.rollaxis(a, 3, 1).shape
+    (3, 6, 4, 5)
+    >>> np.rollaxis(a, 2).shape
+    (5, 3, 4, 6)
+    >>> np.rollaxis(a, 1, 4).shape
+    (3, 5, 6, 4)
+
+    """
+    n = a.ndim
+    if axis < 0:
+        axis += n
+    if start < 0:
+        start += n
+    msg = 'rollaxis: %s (%d) must be >=0 and < %d'
+    if not (0 <= axis < n):
+        raise ValueError(msg % ('axis', axis, n))
+    if not (0 <= start < n + 1):
+        raise ValueError(msg % ('start', start, n + 1))
+    if (axis < start):
+        # it's been removed
+        start -= 1
+    if axis == start:
+        return a[...]
+    axes = list(range(0, n))
+    axes.remove(axis)
+    axes.insert(start, axis)
+    return a.transpose(axes)
+
+
+def _validate_axis(axis, ndim, argname):
+    try:
+        axis = [operator.index(axis)]
+    except TypeError:
+        axis = list(axis)
+    axis = [a + ndim if a < 0 else a for a in axis]
+    if not builtins.all(0 <= a < ndim for a in axis):
+        raise ValueError('invalid axis for this array in `%s` argument' %
+                         argname)
+    if len(set(axis)) != len(axis):
+        raise ValueError('repeated axis in `%s` argument' % argname)
+    return axis
+
+
+def moveaxis(a, source, destination):
+    """
+    Move axes of an array to new positions.
+
+    Other axes remain in their original order.
+
+    .. versionadded::1.11.0
+
+    Parameters
+    ----------
+    a : np.ndarray
+        The array whose axes should be reordered.
+    source : int or sequence of int
+        Original positions of the axes to move. These must be unique.
+    destination : int or sequence of int
+        Destination positions for each of the original axes. These must also be
+        unique.
+
+    Returns
+    -------
+    result : np.ndarray
+        Array with moved axes. This array is a view of the input array.
+
+    See Also
+    --------
+    transpose: Permute the dimensions of an array.
+    swapaxes: Interchange two axes of an array.
+
+    Examples
+    --------
+
+    >>> x = np.zeros((3, 4, 5))
+    >>> np.moveaxis(x, 0, -1).shape
+    (4, 5, 3)
+    >>> np.moveaxis(x, -1, 0).shape
+    (5, 3, 4)
+
+    These all achieve the same result:
+
+    >>> np.transpose(x).shape
+    (5, 4, 3)
+    >>> np.swapaxis(x, 0, -1).shape
+    (5, 4, 3)
+    >>> np.moveaxis(x, [0, 1], [-1, -2]).shape
+    (5, 4, 3)
+    >>> np.moveaxis(x, [0, 1, 2], [-1, -2, -3]).shape
+    (5, 4, 3)
+
+    """
+    try:
+        # allow duck-array types if they define transpose
+        transpose = a.transpose
+    except AttributeError:
+        a = asarray(a)
+        transpose = a.transpose
+
+    source = _validate_axis(source, a.ndim, 'source')
+    destination = _validate_axis(destination, a.ndim, 'destination')
+    if len(source) != len(destination):
+        raise ValueError('`source` and `destination` arguments must have '
+                         'the same number of elements')
+
+    order = [n for n in range(a.ndim) if n not in source]
+
+    for dest, src in sorted(zip(destination, source)):
+        order.insert(dest, src)
+
+    result = transpose(order)
+    return result
+
+
+# fix hack in scipy which imports this function
+def _move_axis_to_0(a, axis):
+    return rollaxis(a, axis, 0)
+
+def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
+    """
+    Return the cross product of two (arrays of) vectors.
+
+    The cross product of `a` and `b` in :math:`R^3` is a vector perpendicular
+    to both `a` and `b`.  If `a` and `b` are arrays of vectors, the vectors
+    are defined by the last axis of `a` and `b` by default, and these axes
+    can have dimensions 2 or 3.  Where the dimension of either `a` or `b` is
+    2, the third component of the input vector is assumed to be zero and the
+    cross product calculated accordingly.  In cases where both input vectors
+    have dimension 2, the z-component of the cross product is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Components of the first vector(s).
+    b : array_like
+        Components of the second vector(s).
+    axisa : int, optional
+        Axis of `a` that defines the vector(s).  By default, the last axis.
+    axisb : int, optional
+        Axis of `b` that defines the vector(s).  By default, the last axis.
+    axisc : int, optional
+        Axis of `c` containing the cross product vector(s).  Ignored if
+        both input vectors have dimension 2, as the return is scalar.
+        By default, the last axis.
+    axis : int, optional
+        If defined, the axis of `a`, `b` and `c` that defines the vector(s)
+        and cross product(s).  Overrides `axisa`, `axisb` and `axisc`.
+
+    Returns
+    -------
+    c : ndarray
+        Vector cross product(s).
+
+    Raises
+    ------
+    ValueError
+        When the dimension of the vector(s) in `a` and/or `b` does not
+        equal 2 or 3.
+
+    See Also
+    --------
+    inner : Inner product
+    outer : Outer product.
+    ix_ : Construct index arrays.
+
+    Notes
+    -----
+    .. versionadded:: 1.9.0
+
+    Supports full broadcasting of the inputs.
+
+    Examples
+    --------
+    Vector cross-product.
+
+    >>> x = [1, 2, 3]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([-3,  6, -3])
+
+    One vector with dimension 2.
+
+    >>> x = [1, 2]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([12, -6, -3])
+
+    Equivalently:
+
+    >>> x = [1, 2, 0]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([12, -6, -3])
+
+    Both vectors with dimension 2.
+
+    >>> x = [1,2]
+    >>> y = [4,5]
+    >>> np.cross(x, y)
+    -3
+
+    Multiple vector cross-products. Note that the direction of the cross
+    product vector is defined by the `right-hand rule`.
+
+    >>> x = np.array([[1,2,3], [4,5,6]])
+    >>> y = np.array([[4,5,6], [1,2,3]])
+    >>> np.cross(x, y)
+    array([[-3,  6, -3],
+           [ 3, -6,  3]])
+
+    The orientation of `c` can be changed using the `axisc` keyword.
+
+    >>> np.cross(x, y, axisc=0)
+    array([[-3,  3],
+           [ 6, -6],
+           [-3,  3]])
+
+    Change the vector definition of `x` and `y` using `axisa` and `axisb`.
+
+    >>> x = np.array([[1,2,3], [4,5,6], [7, 8, 9]])
+    >>> y = np.array([[7, 8, 9], [4,5,6], [1,2,3]])
+    >>> np.cross(x, y)
+    array([[ -6,  12,  -6],
+           [  0,   0,   0],
+           [  6, -12,   6]])
+    >>> np.cross(x, y, axisa=0, axisb=0)
+    array([[-24,  48, -24],
+           [-30,  60, -30],
+           [-36,  72, -36]])
+
+    """
+    if axis is not None:
+        axisa, axisb, axisc = (axis,) * 3
+    a = asarray(a)
+    b = asarray(b)
+    # Check axisa and axisb are within bounds
+    axis_msg = "'axis{0}' out of bounds"
+    if axisa < -a.ndim or axisa >= a.ndim:
+        raise ValueError(axis_msg.format('a'))
+    if axisb < -b.ndim or axisb >= b.ndim:
+        raise ValueError(axis_msg.format('b'))
+    # Move working axis to the end of the shape
+    a = rollaxis(a, axisa, a.ndim)
+    b = rollaxis(b, axisb, b.ndim)
+    msg = ("incompatible dimensions for cross product\n"
+           "(dimension must be 2 or 3)")
+    if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3):
+        raise ValueError(msg)
+
+    # Create the output array
+    shape = broadcast(a[..., 0], b[..., 0]).shape
+    if a.shape[-1] == 3 or b.shape[-1] == 3:
+        shape += (3,)
+        # Check axisc is within bounds
+        if axisc < -len(shape) or axisc >= len(shape):
+            raise ValueError(axis_msg.format('c'))
+    dtype = promote_types(a.dtype, b.dtype)
+    cp = empty(shape, dtype)
+
+    # create local aliases for readability
+    a0 = a[..., 0]
+    a1 = a[..., 1]
+    if a.shape[-1] == 3:
+        a2 = a[..., 2]
+    b0 = b[..., 0]
+    b1 = b[..., 1]
+    if b.shape[-1] == 3:
+        b2 = b[..., 2]
+    if cp.ndim != 0 and cp.shape[-1] == 3:
+        cp0 = cp[..., 0]
+        cp1 = cp[..., 1]
+        cp2 = cp[..., 2]
+
+    if a.shape[-1] == 2:
+        if b.shape[-1] == 2:
+            # a0 * b1 - a1 * b0
+            multiply(a0, b1, out=cp)
+            cp -= a1 * b0
+            return cp
+        else:
+            assert b.shape[-1] == 3
+            # cp0 = a1 * b2 - 0  (a2 = 0)
+            # cp1 = 0 - a0 * b2  (a2 = 0)
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a1, b2, out=cp0)
+            multiply(a0, b2, out=cp1)
+            negative(cp1, out=cp1)
+            multiply(a0, b1, out=cp2)
+            cp2 -= a1 * b0
+    else:
+        assert a.shape[-1] == 3
+        if b.shape[-1] == 3:
+            # cp0 = a1 * b2 - a2 * b1
+            # cp1 = a2 * b0 - a0 * b2
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a1, b2, out=cp0)
+            tmp = array(a2 * b1)
+            cp0 -= tmp
+            multiply(a2, b0, out=cp1)
+            multiply(a0, b2, out=tmp)
+            cp1 -= tmp
+            multiply(a0, b1, out=cp2)
+            multiply(a1, b0, out=tmp)
+            cp2 -= tmp
+        else:
+            assert b.shape[-1] == 2
+            # cp0 = 0 - a2 * b1  (b2 = 0)
+            # cp1 = a2 * b0 - 0  (b2 = 0)
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a2, b1, out=cp0)
+            negative(cp0, out=cp0)
+            multiply(a2, b0, out=cp1)
+            multiply(a0, b1, out=cp2)
+            cp2 -= a1 * b0
+
+    # This works because we are moving the last axis
+    return rollaxis(cp, -1, axisc)
+
+#Use numarray's printing function
+from .arrayprint import array2string, get_printoptions, set_printoptions
+
+_typelessdata = [int_, float_, complex_]
+if issubclass(intc, int):
+    _typelessdata.append(intc)
+
+if issubclass(longlong, int):
+    _typelessdata.append(longlong)
+
+def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
+    """
+    Return the string representation of an array.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array.
+    max_line_width : int, optional
+        The maximum number of columns the string should span. Newline
+        characters split the string appropriately after array elements.
+    precision : int, optional
+        Floating point precision. Default is the current printing precision
+        (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent very small numbers as zero, default is False. Very small
+        is defined by `precision`, if the precision is 8 then
+        numbers smaller than 5e-9 are represented as zero.
+
+    Returns
+    -------
+    string : str
+      The string representation of an array.
+
+    See Also
+    --------
+    array_str, array2string, set_printoptions
+
+    Examples
+    --------
+    >>> np.array_repr(np.array([1,2]))
+    'array([1, 2])'
+    >>> np.array_repr(np.ma.array([0.]))
+    'MaskedArray([ 0.])'
+    >>> np.array_repr(np.array([], np.int32))
+    'array([], dtype=int32)'
+
+    >>> x = np.array([1e-6, 4e-7, 2, 3])
+    >>> np.array_repr(x, precision=6, suppress_small=True)
+    'array([ 0.000001,  0.      ,  2.      ,  3.      ])'
+
+    """
+    if arr.size > 0 or arr.shape == (0,):
+        lst = array2string(arr, max_line_width, precision, suppress_small,
+                           ', ', "array(")
+    else:  # show zero-length shape unless it is (0,)
+        lst = "[], shape=%s" % (repr(arr.shape),)
+
+    if arr.__class__ is not ndarray:
+        cName = arr.__class__.__name__
+    else:
+        cName = "array"
+
+    skipdtype = (arr.dtype.type in _typelessdata) and arr.size > 0
+
+    if skipdtype:
+        return "%s(%s)" % (cName, lst)
+    else:
+        typename = arr.dtype.name
+        # Quote typename in the output if it is "complex".
+        if typename and not (typename[0].isalpha() and typename.isalnum()):
+            typename = "'%s'" % typename
+
+        lf = ''
+        if issubclass(arr.dtype.type, flexible):
+            if arr.dtype.names:
+                typename = "%s" % str(arr.dtype)
+            else:
+                typename = "'%s'" % str(arr.dtype)
+            lf = '\n'+' '*len("array(")
+        return cName + "(%s, %sdtype=%s)" % (lst, lf, typename)
+
+def array_str(a, max_line_width=None, precision=None, suppress_small=None):
+    """
+    Return a string representation of the data in an array.
+
+    The data in the array is returned as a single string.  This function is
+    similar to `array_repr`, the difference being that `array_repr` also
+    returns information on the kind of array and its data type.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    max_line_width : int, optional
+        Inserts newlines if text is longer than `max_line_width`.  The
+        default is, indirectly, 75.
+    precision : int, optional
+        Floating point precision.  Default is the current printing precision
+        (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent numbers "very close" to zero as zero; default is False.
+        Very close is defined by precision: if the precision is 8, e.g.,
+        numbers smaller (in absolute value) than 5e-9 are represented as
+        zero.
+
+    See Also
+    --------
+    array2string, array_repr, set_printoptions
+
+    Examples
+    --------
+    >>> np.array_str(np.arange(3))
+    '[0 1 2]'
+
+    """
+    return array2string(a, max_line_width, precision, suppress_small, ' ', "", str)
+
+def set_string_function(f, repr=True):
+    """
+    Set a Python function to be used when pretty printing arrays.
+
+    Parameters
+    ----------
+    f : function or None
+        Function to be used to pretty print arrays. The function should expect
+        a single array argument and return a string of the representation of
+        the array. If None, the function is reset to the default NumPy function
+        to print arrays.
+    repr : bool, optional
+        If True (default), the function for pretty printing (``__repr__``)
+        is set, if False the function that returns the default string
+        representation (``__str__``) is set.
+
+    See Also
+    --------
+    set_printoptions, get_printoptions
+
+    Examples
+    --------
+    >>> def pprint(arr):
+    ...     return 'HA! - What are you going to do now?'
+    ...
+    >>> np.set_string_function(pprint)
+    >>> a = np.arange(10)
+    >>> a
+    HA! - What are you going to do now?
+    >>> print(a)
+    [0 1 2 3 4 5 6 7 8 9]
+
+    We can reset the function to the default:
+
+    >>> np.set_string_function(None)
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    `repr` affects either pretty printing or normal string representation.
+    Note that ``__repr__`` is still affected by setting ``__str__``
+    because the width of each array element in the returned string becomes
+    equal to the length of the result of ``__str__()``.
+
+    >>> x = np.arange(4)
+    >>> np.set_string_function(lambda x:'random', repr=False)
+    >>> x.__str__()
+    'random'
+    >>> x.__repr__()
+    'array([     0,      1,      2,      3])'
+
+    """
+    if f is None:
+        if repr:
+            return multiarray.set_string_function(array_repr, 1)
+        else:
+            return multiarray.set_string_function(array_str, 0)
+    else:
+        return multiarray.set_string_function(f, repr)
+
+set_string_function(array_str, 0)
+set_string_function(array_repr, 1)
+
+little_endian = (sys.byteorder == 'little')
+
+
+def indices(dimensions, dtype=int):
+    """
+    Return an array representing the indices of a grid.
+
+    Compute an array where the subarrays contain index values 0,1,...
+    varying only along the corresponding axis.
+
+    Parameters
+    ----------
+    dimensions : sequence of ints
+        The shape of the grid.
+    dtype : dtype, optional
+        Data type of the result.
+
+    Returns
+    -------
+    grid : ndarray
+        The array of grid indices,
+        ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
+
+    See Also
+    --------
+    mgrid, meshgrid
+
+    Notes
+    -----
+    The output shape is obtained by prepending the number of dimensions
+    in front of the tuple of dimensions, i.e. if `dimensions` is a tuple
+    ``(r0, ..., rN-1)`` of length ``N``, the output shape is
+    ``(N,r0,...,rN-1)``.
+
+    The subarrays ``grid[k]`` contains the N-D array of indices along the
+    ``k-th`` axis. Explicitly::
+
+        grid[k,i0,i1,...,iN-1] = ik
+
+    Examples
+    --------
+    >>> grid = np.indices((2, 3))
+    >>> grid.shape
+    (2, 2, 3)
+    >>> grid[0]        # row indices
+    array([[0, 0, 0],
+           [1, 1, 1]])
+    >>> grid[1]        # column indices
+    array([[0, 1, 2],
+           [0, 1, 2]])
+
+    The indices can be used as an index into an array.
+
+    >>> x = np.arange(20).reshape(5, 4)
+    >>> row, col = np.indices((2, 3))
+    >>> x[row, col]
+    array([[0, 1, 2],
+           [4, 5, 6]])
+
+    Note that it would be more straightforward in the above example to
+    extract the required elements directly with ``x[:2, :3]``.
+
+    """
+    dimensions = tuple(dimensions)
+    N = len(dimensions)
+    if N == 0:
+        return array([], dtype=dtype)
+    res = empty((N,)+dimensions, dtype=dtype)
+    for i, dim in enumerate(dimensions):
+        tmp = arange(dim, dtype=dtype)
+        tmp.shape = (1,)*i + (dim,)+(1,)*(N-i-1)
+        newdim = dimensions[:i] + (1,) + dimensions[i+1:]
+        val = zeros(newdim, dtype)
+        add(tmp, val, res[i])
+    return res
+
+def fromfunction(function, shape, **kwargs):
+    """
+    Construct an array by executing a function over each coordinate.
+
+    The resulting array therefore has a value ``fn(x, y, z)`` at
+    coordinate ``(x, y, z)``.
+
+    Parameters
+    ----------
+    function : callable
+        The function is called with N parameters, where N is the rank of
+        `shape`.  Each parameter represents the coordinates of the array
+        varying along a specific axis.  For example, if `shape`
+        were ``(2, 2)``, then the parameters in turn be (0, 0), (0, 1),
+        (1, 0), (1, 1).
+    shape : (N,) tuple of ints
+        Shape of the output array, which also determines the shape of
+        the coordinate arrays passed to `function`.
+    dtype : data-type, optional
+        Data-type of the coordinate arrays passed to `function`.
+        By default, `dtype` is float.
+
+    Returns
+    -------
+    fromfunction : any
+        The result of the call to `function` is passed back directly.
+        Therefore the shape of `fromfunction` is completely determined by
+        `function`.  If `function` returns a scalar value, the shape of
+        `fromfunction` would match the `shape` parameter.
+
+    See Also
+    --------
+    indices, meshgrid
+
+    Notes
+    -----
+    Keywords other than `dtype` are passed to `function`.
+
+    Examples
+    --------
+    >>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
+    array([[ True, False, False],
+           [False,  True, False],
+           [False, False,  True]], dtype=bool)
+
+    >>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
+    array([[0, 1, 2],
+           [1, 2, 3],
+           [2, 3, 4]])
+
+    """
+    dtype = kwargs.pop('dtype', float)
+    args = indices(shape, dtype=dtype)
+    return function(*args,**kwargs)
+
+def isscalar(num):
+    """
+    Returns True if the type of `num` is a scalar type.
+
+    Parameters
+    ----------
+    num : any
+        Input argument, can be of any type and shape.
+
+    Returns
+    -------
+    val : bool
+        True if `num` is a scalar type, False if it is not.
+
+    Examples
+    --------
+    >>> np.isscalar(3.1)
+    True
+    >>> np.isscalar([3.1])
+    False
+    >>> np.isscalar(False)
+    True
+
+    """
+    if isinstance(num, generic):
+        return True
+    else:
+        return type(num) in ScalarType
+
+_lkup = {
+    '0':'0000',
+    '1':'0001',
+    '2':'0010',
+    '3':'0011',
+    '4':'0100',
+    '5':'0101',
+    '6':'0110',
+    '7':'0111',
+    '8':'1000',
+    '9':'1001',
+    'a':'1010',
+    'b':'1011',
+    'c':'1100',
+    'd':'1101',
+    'e':'1110',
+    'f':'1111',
+    'A':'1010',
+    'B':'1011',
+    'C':'1100',
+    'D':'1101',
+    'E':'1110',
+    'F':'1111',
+    'L':''}
+
+def binary_repr(num, width=None):
+    """
+    Return the binary representation of the input number as a string.
+
+    For negative numbers, if width is not given, a minus sign is added to the
+    front. If width is given, the two's complement of the number is
+    returned, with respect to that width.
+
+    In a two's-complement system negative numbers are represented by the two's
+    complement of the absolute value. This is the most common method of
+    representing signed integers on computers [1]_. A N-bit two's-complement
+    system can represent every integer in the range
+    :math:`-2^{N-1}` to :math:`+2^{N-1}-1`.
+
+    Parameters
+    ----------
+    num : int
+        Only an integer decimal number can be used.
+    width : int, optional
+        The length of the returned string if `num` is positive, the length of
+        the two's complement if `num` is negative.
+
+    Returns
+    -------
+    bin : str
+        Binary representation of `num` or two's complement of `num`.
+
+    See Also
+    --------
+    base_repr: Return a string representation of a number in the given base
+               system.
+
+    Notes
+    -----
+    `binary_repr` is equivalent to using `base_repr` with base 2, but about 25x
+    faster.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Two's complement",
+        http://en.wikipedia.org/wiki/Two's_complement
+
+    Examples
+    --------
+    >>> np.binary_repr(3)
+    '11'
+    >>> np.binary_repr(-3)
+    '-11'
+    >>> np.binary_repr(3, width=4)
+    '0011'
+
+    The two's complement is returned when the input number is negative and
+    width is specified:
+
+    >>> np.binary_repr(-3, width=4)
+    '1101'
+
+    """
+    # ' <-- unbreak Emacs fontification
+    sign = ''
+    if num < 0:
+        if width is None:
+            sign = '-'
+            num = -num
+        else:
+            # replace num with its 2-complement
+            num = 2**width + num
+    elif num == 0:
+        return '0'*(width or 1)
+    ostr = hex(num)
+    bin = ''.join([_lkup[ch] for ch in ostr[2:]])
+    bin = bin.lstrip('0')
+    if width is not None:
+        bin = bin.zfill(width)
+    return sign + bin
+
+def base_repr(number, base=2, padding=0):
+    """
+    Return a string representation of a number in the given base system.
+
+    Parameters
+    ----------
+    number : int
+        The value to convert. Only positive values are handled.
+    base : int, optional
+        Convert `number` to the `base` number system. The valid range is 2-36,
+        the default value is 2.
+    padding : int, optional
+        Number of zeros padded on the left. Default is 0 (no padding).
+
+    Returns
+    -------
+    out : str
+        String representation of `number` in `base` system.
+
+    See Also
+    --------
+    binary_repr : Faster version of `base_repr` for base 2.
+
+    Examples
+    --------
+    >>> np.base_repr(5)
+    '101'
+    >>> np.base_repr(6, 5)
+    '11'
+    >>> np.base_repr(7, base=5, padding=3)
+    '00012'
+
+    >>> np.base_repr(10, base=16)
+    'A'
+    >>> np.base_repr(32, base=16)
+    '20'
+
+    """
+    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+    if base > len(digits):
+        raise ValueError("Bases greater than 36 not handled in base_repr.")
+
+    num = abs(number)
+    res = []
+    while num:
+        res.append(digits[num % base])
+        num //= base
+    if padding:
+        res.append('0' * padding)
+    if number < 0:
+        res.append('-')
+    return ''.join(reversed(res or '0'))
+
+
+def load(file):
+    """
+    Wrapper around cPickle.load which accepts either a file-like object or
+    a filename.
+
+    Note that the NumPy binary format is not based on pickle/cPickle anymore.
+    For details on the preferred way of loading and saving files, see `load`
+    and `save`.
+
+    See Also
+    --------
+    load, save
+
+    """
+    if isinstance(file, type("")):
+        file = open(file, "rb")
+    return pickle.load(file)
+
+# These are all essentially abbreviations
+# These might wind up in a special abbreviations module
+
+def _maketup(descr, val):
+    dt = dtype(descr)
+    # Place val in all scalar tuples:
+    fields = dt.fields
+    if fields is None:
+        return val
+    else:
+        res = [_maketup(fields[name][0], val) for name in dt.names]
+        return tuple(res)
+
+def identity(n, dtype=None):
+    """
+    Return the identity array.
+
+    The identity array is a square array with ones on
+    the main diagonal.
+
+    Parameters
+    ----------
+    n : int
+        Number of rows (and columns) in `n` x `n` output.
+    dtype : data-type, optional
+        Data-type of the output.  Defaults to ``float``.
+
+    Returns
+    -------
+    out : ndarray
+        `n` x `n` array with its main diagonal set to one,
+        and all other elements 0.
+
+    Examples
+    --------
+    >>> np.identity(3)
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """
+    from numpy import eye
+    return eye(n, dtype=dtype)
+
+def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+    """
+    Returns True if two arrays are element-wise equal within a tolerance.
+
+    The tolerance values are positive, typically very small numbers.  The
+    relative difference (`rtol` * abs(`b`)) and the absolute difference
+    `atol` are added together to compare against the absolute difference
+    between `a` and `b`.
+
+    If either array contains one or more NaNs, False is returned.
+    Infs are treated as equal if they are in the same place and of the same
+    sign in both arrays.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    rtol : float
+        The relative tolerance parameter (see Notes).
+    atol : float
+        The absolute tolerance parameter (see Notes).
+    equal_nan : bool
+        Whether to compare NaN's as equal.  If True, NaN's in `a` will be
+        considered equal to NaN's in `b` in the output array.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    allclose : bool
+        Returns True if the two arrays are equal within the given
+        tolerance; False otherwise.
+
+    See Also
+    --------
+    isclose, all, any
+
+    Notes
+    -----
+    If the following equation is element-wise True, then allclose returns
+    True.
+
+     absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    The above equation is not symmetric in `a` and `b`, so that
+    `allclose(a, b)` might be different from `allclose(b, a)` in
+    some rare cases.
+
+    Examples
+    --------
+    >>> np.allclose([1e10,1e-7], [1.00001e10,1e-8])
+    False
+    >>> np.allclose([1e10,1e-8], [1.00001e10,1e-9])
+    True
+    >>> np.allclose([1e10,1e-8], [1.0001e10,1e-9])
+    False
+    >>> np.allclose([1.0, np.nan], [1.0, np.nan])
+    False
+    >>> np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+    True
+
+    """
+    res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
+    return bool(res)
+
+def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+    """
+    Returns a boolean array where two arrays are element-wise equal within a
+    tolerance.
+
+    The tolerance values are positive, typically very small numbers.  The
+    relative difference (`rtol` * abs(`b`)) and the absolute difference
+    `atol` are added together to compare against the absolute difference
+    between `a` and `b`.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    rtol : float
+        The relative tolerance parameter (see Notes).
+    atol : float
+        The absolute tolerance parameter (see Notes).
+    equal_nan : bool
+        Whether to compare NaN's as equal.  If True, NaN's in `a` will be
+        considered equal to NaN's in `b` in the output array.
+
+    Returns
+    -------
+    y : array_like
+        Returns a boolean array of where `a` and `b` are equal within the
+        given tolerance. If both `a` and `b` are scalars, returns a single
+        boolean value.
+
+    See Also
+    --------
+    allclose
+
+    Notes
+    -----
+    .. versionadded:: 1.7.0
+
+    For finite values, isclose uses the following equation to test whether
+    two floating point values are equivalent.
+
+     absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    The above equation is not symmetric in `a` and `b`, so that
+    `isclose(a, b)` might be different from `isclose(b, a)` in
+    some rare cases.
+
+    Examples
+    --------
+    >>> np.isclose([1e10,1e-7], [1.00001e10,1e-8])
+    array([True, False])
+    >>> np.isclose([1e10,1e-8], [1.00001e10,1e-9])
+    array([True, True])
+    >>> np.isclose([1e10,1e-8], [1.0001e10,1e-9])
+    array([False, True])
+    >>> np.isclose([1.0, np.nan], [1.0, np.nan])
+    array([True, False])
+    >>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+    array([True, True])
+    """
+    def within_tol(x, y, atol, rtol):
+        with errstate(invalid='ignore'):
+            result = less_equal(abs(x-y), atol + rtol * abs(y))
+        if isscalar(a) and isscalar(b):
+            result = bool(result)
+        return result
+
+    x = array(a, copy=False, subok=True, ndmin=1)
+    y = array(b, copy=False, subok=True, ndmin=1)
+
+    # Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
+    # This will cause casting of x later. Also, make sure to allow subclasses
+    # (e.g., for numpy.ma).
+    dt = multiarray.result_type(y, 1.)
+    y = array(y, dtype=dt, copy=False, subok=True)
+
+    xfin = isfinite(x)
+    yfin = isfinite(y)
+    if all(xfin) and all(yfin):
+        return within_tol(x, y, atol, rtol)
+    else:
+        finite = xfin & yfin
+        cond = zeros_like(finite, subok=True)
+        # Because we're using boolean indexing, x & y must be the same shape.
+        # Ideally, we'd just do x, y = broadcast_arrays(x, y). It's in
+        # lib.stride_tricks, though, so we can't import it here.
+        x = x * ones_like(cond)
+        y = y * ones_like(cond)
+        # Avoid subtraction with infinite/nan values...
+        cond[finite] = within_tol(x[finite], y[finite], atol, rtol)
+        # Check for equality of infinite values...
+        cond[~finite] = (x[~finite] == y[~finite])
+        if equal_nan:
+            # Make NaN == NaN
+            both_nan = isnan(x) & isnan(y)
+            cond[both_nan] = both_nan[both_nan]
+
+        if isscalar(a) and isscalar(b):
+            return bool(cond)
+        else:
+            return cond
+
+def array_equal(a1, a2):
+    """
+    True if two arrays have the same shape and elements, False otherwise.
+
+    Parameters
+    ----------
+    a1, a2 : array_like
+        Input arrays.
+
+    Returns
+    -------
+    b : bool
+        Returns True if the arrays are equal.
+
+    See Also
+    --------
+    allclose: Returns True if two arrays are element-wise equal within a
+              tolerance.
+    array_equiv: Returns True if input arrays are shape consistent and all
+                 elements equal.
+
+    Examples
+    --------
+    >>> np.array_equal([1, 2], [1, 2])
+    True
+    >>> np.array_equal(np.array([1, 2]), np.array([1, 2]))
+    True
+    >>> np.array_equal([1, 2], [1, 2, 3])
+    False
+    >>> np.array_equal([1, 2], [1, 4])
+    False
+
+    """
+    try:
+        a1, a2 = asarray(a1), asarray(a2)
+    except:
+        return False
+    if a1.shape != a2.shape:
+        return False
+    return bool(asarray(a1 == a2).all())
+
+def array_equiv(a1, a2):
+    """
+    Returns True if input arrays are shape consistent and all elements equal.
+
+    Shape consistent means they are either the same shape, or one input array
+    can be broadcasted to create the same shape as the other one.
+
+    Parameters
+    ----------
+    a1, a2 : array_like
+        Input arrays.
+
+    Returns
+    -------
+    out : bool
+        True if equivalent, False otherwise.
+
+    Examples
+    --------
+    >>> np.array_equiv([1, 2], [1, 2])
+    True
+    >>> np.array_equiv([1, 2], [1, 3])
+    False
+
+    Showing the shape equivalence:
+
+    >>> np.array_equiv([1, 2], [[1, 2], [1, 2]])
+    True
+    >>> np.array_equiv([1, 2], [[1, 2, 1, 2], [1, 2, 1, 2]])
+    False
+
+    >>> np.array_equiv([1, 2], [[1, 2], [1, 3]])
+    False
+
+    """
+    try:
+        a1, a2 = asarray(a1), asarray(a2)
+    except:
+        return False
+    try:
+        multiarray.broadcast(a1, a2)
+    except:
+        return False
+
+    return bool(asarray(a1 == a2).all())
+
+
+_errdict = {"ignore":ERR_IGNORE,
+            "warn":ERR_WARN,
+            "raise":ERR_RAISE,
+            "call":ERR_CALL,
+            "print":ERR_PRINT,
+            "log":ERR_LOG}
+
+_errdict_rev = {}
+for key in _errdict.keys():
+    _errdict_rev[_errdict[key]] = key
+del key
+
+def seterr(all=None, divide=None, over=None, under=None, invalid=None):
+    """
+    Set how floating-point errors are handled.
+
+    Note that operations on integer scalar types (such as `int16`) are
+    handled like floating point, and are affected by these settings.
+
+    Parameters
+    ----------
+    all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Set treatment for all types of floating-point errors at once:
+
+        - ignore: Take no action when the exception occurs.
+        - warn: Print a `RuntimeWarning` (via the Python `warnings` module).
+        - raise: Raise a `FloatingPointError`.
+        - call: Call a function specified using the `seterrcall` function.
+        - print: Print a warning directly to ``stdout``.
+        - log: Record error in a Log object specified by `seterrcall`.
+
+        The default is not to change the current behavior.
+    divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for division by zero.
+    over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for floating-point overflow.
+    under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for floating-point underflow.
+    invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for invalid floating-point operation.
+
+    Returns
+    -------
+    old_settings : dict
+        Dictionary containing the old settings.
+
+    See also
+    --------
+    seterrcall : Set a callback function for the 'call' mode.
+    geterr, geterrcall, errstate
+
+    Notes
+    -----
+    The floating-point exceptions are defined in the IEEE 754 standard [1]:
+
+    - Division by zero: infinite result obtained from finite numbers.
+    - Overflow: result too large to be expressed.
+    - Underflow: result so close to zero that some precision
+      was lost.
+    - Invalid operation: result is not an expressible number, typically
+      indicates that a NaN was produced.
+
+    .. [1] http://en.wikipedia.org/wiki/IEEE_754
+
+    Examples
+    --------
+    >>> old_settings = np.seterr(all='ignore')  #seterr to known value
+    >>> np.seterr(over='raise')
+    {'over': 'ignore', 'divide': 'ignore', 'invalid': 'ignore',
+     'under': 'ignore'}
+    >>> np.seterr(**old_settings)  # reset to default
+    {'over': 'raise', 'divide': 'ignore', 'invalid': 'ignore', 'under': 'ignore'}
+
+    >>> np.int16(32000) * np.int16(3)
+    30464
+    >>> old_settings = np.seterr(all='warn', over='raise')
+    >>> np.int16(32000) * np.int16(3)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    FloatingPointError: overflow encountered in short_scalars
+
+    >>> old_settings = np.seterr(all='print')
+    >>> np.geterr()
+    {'over': 'print', 'divide': 'print', 'invalid': 'print', 'under': 'print'}
+    >>> np.int16(32000) * np.int16(3)
+    Warning: overflow encountered in short_scalars
+    30464
+
+    """
+
+    pyvals = umath.geterrobj()
+    old = geterr()
+
+    if divide is None:
+        divide = all or old['divide']
+    if over is None:
+        over = all or old['over']
+    if under is None:
+        under = all or old['under']
+    if invalid is None:
+        invalid = all or old['invalid']
+
+    maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) +
+                 (_errdict[over] << SHIFT_OVERFLOW) +
+                 (_errdict[under] << SHIFT_UNDERFLOW) +
+                 (_errdict[invalid] << SHIFT_INVALID))
+
+    pyvals[1] = maskvalue
+    umath.seterrobj(pyvals)
+    return old
+
+
+def geterr():
+    """
+    Get the current way of handling floating-point errors.
+
+    Returns
+    -------
+    res : dict
+        A dictionary with keys "divide", "over", "under", and "invalid",
+        whose values are from the strings "ignore", "print", "log", "warn",
+        "raise", and "call". The keys represent possible floating-point
+        exceptions, and the values define how these exceptions are handled.
+
+    See Also
+    --------
+    geterrcall, seterr, seterrcall
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'warn', 'invalid': 'warn',
+    'under': 'ignore'}
+    >>> np.arange(3.) / np.arange(3.)
+    array([ NaN,   1.,   1.])
+
+    >>> oldsettings = np.seterr(all='warn', over='raise')
+    >>> np.geterr()
+    {'over': 'raise', 'divide': 'warn', 'invalid': 'warn', 'under': 'warn'}
+    >>> np.arange(3.) / np.arange(3.)
+    __main__:1: RuntimeWarning: invalid value encountered in divide
+    array([ NaN,   1.,   1.])
+
+    """
+    maskvalue = umath.geterrobj()[1]
+    mask = 7
+    res = {}
+    val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask
+    res['divide'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_OVERFLOW) & mask
+    res['over'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_UNDERFLOW) & mask
+    res['under'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_INVALID) & mask
+    res['invalid'] = _errdict_rev[val]
+    return res
+
+def setbufsize(size):
+    """
+    Set the size of the buffer used in ufuncs.
+
+    Parameters
+    ----------
+    size : int
+        Size of buffer.
+
+    """
+    if size > 10e6:
+        raise ValueError("Buffer size, %s, is too big." % size)
+    if size < 5:
+        raise ValueError("Buffer size, %s, is too small." % size)
+    if size % 16 != 0:
+        raise ValueError("Buffer size, %s, is not a multiple of 16." % size)
+
+    pyvals = umath.geterrobj()
+    old = getbufsize()
+    pyvals[0] = size
+    umath.seterrobj(pyvals)
+    return old
+
+def getbufsize():
+    """
+    Return the size of the buffer used in ufuncs.
+
+    Returns
+    -------
+    getbufsize : int
+        Size of ufunc buffer in bytes.
+
+    """
+    return umath.geterrobj()[0]
+
+def seterrcall(func):
+    """
+    Set the floating-point error callback function or log object.
+
+    There are two ways to capture floating-point error messages.  The first
+    is to set the error-handler to 'call', using `seterr`.  Then, set
+    the function to call using this function.
+
+    The second is to set the error-handler to 'log', using `seterr`.
+    Floating-point errors then trigger a call to the 'write' method of
+    the provided object.
+
+    Parameters
+    ----------
+    func : callable f(err, flag) or object with write method
+        Function to call upon floating-point errors ('call'-mode) or
+        object whose 'write' method is used to log such message ('log'-mode).
+
+        The call function takes two arguments. The first is a string describing the
+        type of error (such as "divide by zero", "overflow", "underflow", or "invalid value"),
+        and the second is the status flag.  The flag is a byte, whose four
+        least-significant bits indicate the type of error, one of "divide", "over",
+        "under", "invalid"::
+
+          [0 0 0 0 divide over under invalid]
+
+        In other words, ``flags = divide + 2*over + 4*under + 8*invalid``.
+
+        If an object is provided, its write method should take one argument,
+        a string.
+
+    Returns
+    -------
+    h : callable, log instance or None
+        The old error handler.
+
+    See Also
+    --------
+    seterr, geterr, geterrcall
+
+    Examples
+    --------
+    Callback upon error:
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+
+    >>> saved_handler = np.seterrcall(err_handler)
+    >>> save_err = np.seterr(all='call')
+
+    >>> np.array([1, 2, 3]) / 0.0
+    Floating point error (divide by zero), with flag 1
+    array([ Inf,  Inf,  Inf])
+
+    >>> np.seterrcall(saved_handler)
+    <function err_handler at 0x...>
+    >>> np.seterr(**save_err)
+    {'over': 'call', 'divide': 'call', 'invalid': 'call', 'under': 'call'}
+
+    Log error message:
+
+    >>> class Log(object):
+    ...     def write(self, msg):
+    ...         print("LOG: %s" % msg)
+    ...
+
+    >>> log = Log()
+    >>> saved_handler = np.seterrcall(log)
+    >>> save_err = np.seterr(all='log')
+
+    >>> np.array([1, 2, 3]) / 0.0
+    LOG: Warning: divide by zero encountered in divide
+    <BLANKLINE>
+    array([ Inf,  Inf,  Inf])
+
+    >>> np.seterrcall(saved_handler)
+    <__main__.Log object at 0x...>
+    >>> np.seterr(**save_err)
+    {'over': 'log', 'divide': 'log', 'invalid': 'log', 'under': 'log'}
+
+    """
+    if func is not None and not isinstance(func, collections.Callable):
+        if not hasattr(func, 'write') or not isinstance(func.write, collections.Callable):
+            raise ValueError("Only callable can be used as callback")
+    pyvals = umath.geterrobj()
+    old = geterrcall()
+    pyvals[2] = func
+    umath.seterrobj(pyvals)
+    return old
+
+def geterrcall():
+    """
+    Return the current callback function used on floating-point errors.
+
+    When the error handling for a floating-point error (one of "divide",
+    "over", "under", or "invalid") is set to 'call' or 'log', the function
+    that is called or the log instance that is written to is returned by
+    `geterrcall`. This function or log instance has been set with
+    `seterrcall`.
+
+    Returns
+    -------
+    errobj : callable, log instance or None
+        The current error handler. If no handler was set through `seterrcall`,
+        ``None`` is returned.
+
+    See Also
+    --------
+    seterrcall, seterr, geterr
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterrcall()  # we did not yet set a handler, returns None
+
+    >>> oldsettings = np.seterr(all='call')
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    >>> oldhandler = np.seterrcall(err_handler)
+    >>> np.array([1, 2, 3]) / 0.0
+    Floating point error (divide by zero), with flag 1
+    array([ Inf,  Inf,  Inf])
+
+    >>> cur_handler = np.geterrcall()
+    >>> cur_handler is err_handler
+    True
+
+    """
+    return umath.geterrobj()[2]
+
+class _unspecified(object):
+    pass
+_Unspecified = _unspecified()
+
+class errstate(object):
+    """
+    errstate(**kwargs)
+
+    Context manager for floating-point error handling.
+
+    Using an instance of `errstate` as a context manager allows statements in
+    that context to execute with a known error handling behavior. Upon entering
+    the context the error handling is set with `seterr` and `seterrcall`, and
+    upon exiting it is reset to what it was before.
+
+    Parameters
+    ----------
+    kwargs : {divide, over, under, invalid}
+        Keyword arguments. The valid keywords are the possible floating-point
+        exceptions. Each keyword should have a string value that defines the
+        treatment for the particular error. Possible values are
+        {'ignore', 'warn', 'raise', 'call', 'print', 'log'}.
+
+    See Also
+    --------
+    seterr, geterr, seterrcall, geterrcall
+
+    Notes
+    -----
+    The ``with`` statement was introduced in Python 2.5, and can only be used
+    there by importing it: ``from __future__ import with_statement``. In
+    earlier Python versions the ``with`` statement is not available.
+
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> from __future__ import with_statement  # use 'with' in Python 2.5
+    >>> olderr = np.seterr(all='ignore')  # Set error handling to known state.
+
+    >>> np.arange(3) / 0.
+    array([ NaN,  Inf,  Inf])
+    >>> with np.errstate(divide='warn'):
+    ...     np.arange(3) / 0.
+    ...
+    __main__:2: RuntimeWarning: divide by zero encountered in divide
+    array([ NaN,  Inf,  Inf])
+
+    >>> np.sqrt(-1)
+    nan
+    >>> with np.errstate(invalid='raise'):
+    ...     np.sqrt(-1)
+    Traceback (most recent call last):
+      File "<stdin>", line 2, in <module>
+    FloatingPointError: invalid value encountered in sqrt
+
+    Outside the context the error handling behavior has not changed:
+
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'warn', 'invalid': 'warn',
+    'under': 'ignore'}
+
+    """
+    # Note that we don't want to run the above doctests because they will fail
+    # without a from __future__ import with_statement
+
+    def __init__(self, **kwargs):
+        self.call = kwargs.pop('call', _Unspecified)
+        self.kwargs = kwargs
+
+    def __enter__(self):
+        self.oldstate = seterr(**self.kwargs)
+        if self.call is not _Unspecified:
+            self.oldcall = seterrcall(self.call)
+
+    def __exit__(self, *exc_info):
+        seterr(**self.oldstate)
+        if self.call is not _Unspecified:
+            seterrcall(self.oldcall)
+
+
+def _setdef():
+    defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
+    umath.seterrobj(defval)
+
+# set the default values
+_setdef()
+
+Inf = inf = infty = Infinity = PINF
+nan = NaN = NAN
+False_ = bool_(False)
+True_ = bool_(True)
+
+from .umath import *
+from .numerictypes import *
+from . import fromnumeric
+from .fromnumeric import *
+extend_all(fromnumeric)
+extend_all(umath)
+extend_all(numerictypes)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.py
new file mode 100644
index 0000000000..1b6551e6c8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.py
@@ -0,0 +1,1036 @@
+"""
+numerictypes: Define the numeric type objects
+
+This module is designed so "from numerictypes import \\*" is safe.
+Exported symbols include:
+
+  Dictionary with all registered number types (including aliases):
+    typeDict
+
+  Type objects (not all will be available, depends on platform):
+      see variable sctypes for which ones you have
+
+    Bit-width names
+
+    int8 int16 int32 int64 int128
+    uint8 uint16 uint32 uint64 uint128
+    float16 float32 float64 float96 float128 float256
+    complex32 complex64 complex128 complex192 complex256 complex512
+    datetime64 timedelta64
+
+    c-based names
+
+    bool_
+
+    object_
+
+    void, str_, unicode_
+
+    byte, ubyte,
+    short, ushort
+    intc, uintc,
+    intp, uintp,
+    int_, uint,
+    longlong, ulonglong,
+
+    single, csingle,
+    float_, complex_,
+    longfloat, clongfloat,
+
+   As part of the type-hierarchy:    xx -- is bit-width
+
+   generic
+     +-> bool_                                  (kind=b)
+     +-> number                                 (kind=i)
+     |     integer
+     |     signedinteger   (intxx)
+     |     byte
+     |     short
+     |     intc
+     |     intp           int0
+     |     int_
+     |     longlong
+     +-> unsignedinteger  (uintxx)              (kind=u)
+     |     ubyte
+     |     ushort
+     |     uintc
+     |     uintp          uint0
+     |     uint_
+     |     ulonglong
+     +-> inexact
+     |   +-> floating           (floatxx)       (kind=f)
+     |   |     half
+     |   |     single
+     |   |     float_  (double)
+     |   |     longfloat
+     |   \\-> complexfloating    (complexxx)     (kind=c)
+     |         csingle  (singlecomplex)
+     |         complex_ (cfloat, cdouble)
+     |         clongfloat (longcomplex)
+     +-> flexible
+     |     character
+     |     void                                 (kind=V)
+     |
+     |     str_     (string_, bytes_)           (kind=S)    [Python 2]
+     |     unicode_                             (kind=U)    [Python 2]
+     |
+     |     bytes_   (string_)                   (kind=S)    [Python 3]
+     |     str_     (unicode_)                  (kind=U)    [Python 3]
+     |
+     \\-> object_ (not used much)                (kind=O)
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types as _types
+import sys
+import numbers
+
+from numpy.compat import bytes, long
+from numpy.core.multiarray import (
+        typeinfo, ndarray, array, empty, dtype, datetime_data,
+        datetime_as_string, busday_offset, busday_count, is_busday,
+        busdaycalendar
+        )
+
+
+# we add more at the bottom
+__all__ = ['sctypeDict', 'sctypeNA', 'typeDict', 'typeNA', 'sctypes',
+           'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
+           'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
+           'issubdtype', 'datetime_data', 'datetime_as_string',
+           'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar',
+           ]
+
+
+# we don't export these for import *, but we do want them accessible
+# as numerictypes.bool, etc.
+if sys.version_info[0] >= 3:
+    from builtins import bool, int, float, complex, object, str
+    unicode = str
+else:
+    from __builtin__ import bool, int, float, complex, object, unicode, str
+
+
+# String-handling utilities to avoid locale-dependence.
+
+# "import string" is costly to import!
+# Construct the translation tables directly
+#   "A" = chr(65), "a" = chr(97)
+_all_chars = [chr(_m) for _m in range(256)]
+_ascii_upper = _all_chars[65:65+26]
+_ascii_lower = _all_chars[97:97+26]
+LOWER_TABLE = "".join(_all_chars[:65] + _ascii_lower + _all_chars[65+26:])
+UPPER_TABLE = "".join(_all_chars[:97] + _ascii_upper + _all_chars[97+26:])
+
+
+def english_lower(s):
+    """ Apply English case rules to convert ASCII strings to all lower case.
+
+    This is an internal utility function to replace calls to str.lower() such
+    that we can avoid changing behavior with changing locales. In particular,
+    Turkish has distinct dotted and dotless variants of the Latin letter "I" in
+    both lowercase and uppercase. Thus, "I".lower() != "i" in a "tr" locale.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    lowered : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_lower
+    >>> english_lower('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+    'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789_'
+    >>> english_lower('')
+    ''
+    """
+    lowered = s.translate(LOWER_TABLE)
+    return lowered
+
+def english_upper(s):
+    """ Apply English case rules to convert ASCII strings to all upper case.
+
+    This is an internal utility function to replace calls to str.upper() such
+    that we can avoid changing behavior with changing locales. In particular,
+    Turkish has distinct dotted and dotless variants of the Latin letter "I" in
+    both lowercase and uppercase. Thus, "i".upper() != "I" in a "tr" locale.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    uppered : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_upper
+    >>> english_upper('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
+    >>> english_upper('')
+    ''
+    """
+    uppered = s.translate(UPPER_TABLE)
+    return uppered
+
+def english_capitalize(s):
+    """ Apply English case rules to convert the first character of an ASCII
+    string to upper case.
+
+    This is an internal utility function to replace calls to str.capitalize()
+    such that we can avoid changing behavior with changing locales.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    capitalized : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_capitalize
+    >>> english_capitalize('int8')
+    'Int8'
+    >>> english_capitalize('Int8')
+    'Int8'
+    >>> english_capitalize('')
+    ''
+    """
+    if s:
+        return english_upper(s[0]) + s[1:]
+    else:
+        return s
+
+
+sctypeDict = {}      # Contains all leaf-node scalar types with aliases
+sctypeNA = {}        # Contails all leaf-node types -> numarray type equivalences
+allTypes = {}      # Collect the types we will add to the module here
+
+def _evalname(name):
+    k = 0
+    for ch in name:
+        if ch in '0123456789':
+            break
+        k += 1
+    try:
+        bits = int(name[k:])
+    except ValueError:
+        bits = 0
+    base = name[:k]
+    return base, bits
+
+def bitname(obj):
+    """Return a bit-width name for a given type object"""
+    name = obj.__name__
+    base = ''
+    char = ''
+    try:
+        if name[-1] == '_':
+            newname = name[:-1]
+        else:
+            newname = name
+        info = typeinfo[english_upper(newname)]
+        assert(info[-1] == obj)  # sanity check
+        bits = info[2]
+
+    except KeyError:     # bit-width name
+        base, bits = _evalname(name)
+        char = base[0]
+
+    if name == 'bool_':
+        char = 'b'
+        base = 'bool'
+    elif name == 'void':
+        char = 'V'
+        base = 'void'
+    elif name == 'object_':
+        char = 'O'
+        base = 'object'
+        bits = 0
+    elif name == 'datetime64':
+        char = 'M'
+    elif name == 'timedelta64':
+        char = 'm'
+
+    if sys.version_info[0] >= 3:
+        if name == 'bytes_':
+            char = 'S'
+            base = 'bytes'
+        elif name == 'str_':
+            char = 'U'
+            base = 'str'
+    else:
+        if name == 'string_':
+            char = 'S'
+            base = 'string'
+        elif name == 'unicode_':
+            char = 'U'
+            base = 'unicode'
+
+    bytes = bits // 8
+
+    if char != '' and bytes != 0:
+        char = "%s%d" % (char, bytes)
+
+    return base, bits, char
+
+
+def _add_types():
+    for a in typeinfo.keys():
+        name = english_lower(a)
+        if isinstance(typeinfo[a], tuple):
+            typeobj = typeinfo[a][-1]
+
+            # define C-name and insert typenum and typechar references also
+            allTypes[name] = typeobj
+            sctypeDict[name] = typeobj
+            sctypeDict[typeinfo[a][0]] = typeobj
+            sctypeDict[typeinfo[a][1]] = typeobj
+
+        else:  # generic class
+            allTypes[name] = typeinfo[a]
+_add_types()
+
+def _add_aliases():
+    for a in typeinfo.keys():
+        name = english_lower(a)
+        if not isinstance(typeinfo[a], tuple):
+            continue
+        typeobj = typeinfo[a][-1]
+        # insert bit-width version for this class (if relevant)
+        base, bit, char = bitname(typeobj)
+        if base[-3:] == 'int' or char[0] in 'ui':
+            continue
+        if base != '':
+            myname = "%s%d" % (base, bit)
+            if ((name != 'longdouble' and name != 'clongdouble') or
+                   myname not in allTypes.keys()):
+                allTypes[myname] = typeobj
+                sctypeDict[myname] = typeobj
+                if base == 'complex':
+                    na_name = '%s%d' % (english_capitalize(base), bit//2)
+                elif base == 'bool':
+                    na_name = english_capitalize(base)
+                    sctypeDict[na_name] = typeobj
+                else:
+                    na_name = "%s%d" % (english_capitalize(base), bit)
+                    sctypeDict[na_name] = typeobj
+                sctypeNA[na_name] = typeobj
+                sctypeDict[na_name] = typeobj
+                sctypeNA[typeobj] = na_name
+                sctypeNA[typeinfo[a][0]] = na_name
+        if char != '':
+            sctypeDict[char] = typeobj
+            sctypeNA[char] = na_name
+_add_aliases()
+
+# Integers are handled so that the int32 and int64 types should agree
+# exactly with NPY_INT32, NPY_INT64. We need to enforce the same checking
+# as is done in arrayobject.h where the order of getting a bit-width match
+# is long, longlong, int, short, char.
+def _add_integer_aliases():
+    _ctypes = ['LONG', 'LONGLONG', 'INT', 'SHORT', 'BYTE']
+    for ctype in _ctypes:
+        val = typeinfo[ctype]
+        bits = val[2]
+        charname = 'i%d' % (bits//8,)
+        ucharname = 'u%d' % (bits//8,)
+        intname = 'int%d' % bits
+        UIntname = 'UInt%d' % bits
+        Intname = 'Int%d' % bits
+        uval = typeinfo['U'+ctype]
+        typeobj = val[-1]
+        utypeobj = uval[-1]
+        if intname not in allTypes.keys():
+            uintname = 'uint%d' % bits
+            allTypes[intname] = typeobj
+            allTypes[uintname] = utypeobj
+            sctypeDict[intname] = typeobj
+            sctypeDict[uintname] = utypeobj
+            sctypeDict[Intname] = typeobj
+            sctypeDict[UIntname] = utypeobj
+            sctypeDict[charname] = typeobj
+            sctypeDict[ucharname] = utypeobj
+            sctypeNA[Intname] = typeobj
+            sctypeNA[UIntname] = utypeobj
+            sctypeNA[charname] = typeobj
+            sctypeNA[ucharname] = utypeobj
+        sctypeNA[typeobj] = Intname
+        sctypeNA[utypeobj] = UIntname
+        sctypeNA[val[0]] = Intname
+        sctypeNA[uval[0]] = UIntname
+_add_integer_aliases()
+
+# We use these later
+void = allTypes['void']
+generic = allTypes['generic']
+
+#
+# Rework the Python names (so that float and complex and int are consistent
+#                            with Python usage)
+#
+def _set_up_aliases():
+    type_pairs = [('complex_', 'cdouble'),
+                  ('int0', 'intp'),
+                  ('uint0', 'uintp'),
+                  ('single', 'float'),
+                  ('csingle', 'cfloat'),
+                  ('singlecomplex', 'cfloat'),
+                  ('float_', 'double'),
+                  ('intc', 'int'),
+                  ('uintc', 'uint'),
+                  ('int_', 'long'),
+                  ('uint', 'ulong'),
+                  ('cfloat', 'cdouble'),
+                  ('longfloat', 'longdouble'),
+                  ('clongfloat', 'clongdouble'),
+                  ('longcomplex', 'clongdouble'),
+                  ('bool_', 'bool'),
+                  ('unicode_', 'unicode'),
+                  ('object_', 'object')]
+    if sys.version_info[0] >= 3:
+        type_pairs.extend([('bytes_', 'string'),
+                           ('str_', 'unicode'),
+                           ('string_', 'string')])
+    else:
+        type_pairs.extend([('str_', 'string'),
+                           ('string_', 'string'),
+                           ('bytes_', 'string')])
+    for alias, t in type_pairs:
+        allTypes[alias] = allTypes[t]
+        sctypeDict[alias] = sctypeDict[t]
+    # Remove aliases overriding python types and modules
+    to_remove = ['ulong', 'object', 'unicode', 'int', 'long', 'float',
+                 'complex', 'bool', 'string', 'datetime', 'timedelta']
+    if sys.version_info[0] >= 3:
+        # Py3K
+        to_remove.append('bytes')
+        to_remove.append('str')
+        to_remove.remove('unicode')
+        to_remove.remove('long')
+    for t in to_remove:
+        try:
+            del allTypes[t]
+            del sctypeDict[t]
+        except KeyError:
+            pass
+_set_up_aliases()
+
+# Now, construct dictionary to lookup character codes from types
+_sctype2char_dict = {}
+def _construct_char_code_lookup():
+    for name in typeinfo.keys():
+        tup = typeinfo[name]
+        if isinstance(tup, tuple):
+            if tup[0] not in ['p', 'P']:
+                _sctype2char_dict[tup[-1]] = tup[0]
+_construct_char_code_lookup()
+
+
+sctypes = {'int': [],
+           'uint':[],
+           'float':[],
+           'complex':[],
+           'others':[bool, object, str, unicode, void]}
+
+def _add_array_type(typename, bits):
+    try:
+        t = allTypes['%s%d' % (typename, bits)]
+    except KeyError:
+        pass
+    else:
+        sctypes[typename].append(t)
+
+def _set_array_types():
+    ibytes = [1, 2, 4, 8, 16, 32, 64]
+    fbytes = [2, 4, 8, 10, 12, 16, 32, 64]
+    for bytes in ibytes:
+        bits = 8*bytes
+        _add_array_type('int', bits)
+        _add_array_type('uint', bits)
+    for bytes in fbytes:
+        bits = 8*bytes
+        _add_array_type('float', bits)
+        _add_array_type('complex', 2*bits)
+    _gi = dtype('p')
+    if _gi.type not in sctypes['int']:
+        indx = 0
+        sz = _gi.itemsize
+        _lst = sctypes['int']
+        while (indx < len(_lst) and sz >= _lst[indx](0).itemsize):
+            indx += 1
+        sctypes['int'].insert(indx, _gi.type)
+        sctypes['uint'].insert(indx, dtype('P').type)
+_set_array_types()
+
+
+genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16',
+                   'int32', 'uint32', 'int64', 'uint64', 'int128',
+                   'uint128', 'float16',
+                   'float32', 'float64', 'float80', 'float96', 'float128',
+                   'float256',
+                   'complex32', 'complex64', 'complex128', 'complex160',
+                   'complex192', 'complex256', 'complex512', 'object']
+
+def maximum_sctype(t):
+    """
+    Return the scalar type of highest precision of the same kind as the input.
+
+    Parameters
+    ----------
+    t : dtype or dtype specifier
+        The input data type. This can be a `dtype` object or an object that
+        is convertible to a `dtype`.
+
+    Returns
+    -------
+    out : dtype
+        The highest precision data type of the same kind (`dtype.kind`) as `t`.
+
+    See Also
+    --------
+    obj2sctype, mintypecode, sctype2char
+    dtype
+
+    Examples
+    --------
+    >>> np.maximum_sctype(np.int)
+    <type 'numpy.int64'>
+    >>> np.maximum_sctype(np.uint8)
+    <type 'numpy.uint64'>
+    >>> np.maximum_sctype(np.complex)
+    <type 'numpy.complex192'>
+
+    >>> np.maximum_sctype(str)
+    <type 'numpy.string_'>
+
+    >>> np.maximum_sctype('i2')
+    <type 'numpy.int64'>
+    >>> np.maximum_sctype('f4')
+    <type 'numpy.float96'>
+
+    """
+    g = obj2sctype(t)
+    if g is None:
+        return t
+    t = g
+    name = t.__name__
+    base, bits = _evalname(name)
+    if bits == 0:
+        return t
+    else:
+        return sctypes[base][-1]
+
+try:
+    buffer_type = _types.BufferType
+except AttributeError:
+    # Py3K
+    buffer_type = memoryview
+
+_python_types = {int: 'int_',
+                 float: 'float_',
+                 complex: 'complex_',
+                 bool: 'bool_',
+                 bytes: 'bytes_',
+                 unicode: 'unicode_',
+                 buffer_type: 'void',
+                 }
+
+if sys.version_info[0] >= 3:
+    def _python_type(t):
+        """returns the type corresponding to a certain Python type"""
+        if not isinstance(t, type):
+            t = type(t)
+        return allTypes[_python_types.get(t, 'object_')]
+else:
+    def _python_type(t):
+        """returns the type corresponding to a certain Python type"""
+        if not isinstance(t, _types.TypeType):
+            t = type(t)
+        return allTypes[_python_types.get(t, 'object_')]
+
+def issctype(rep):
+    """
+    Determines whether the given object represents a scalar data-type.
+
+    Parameters
+    ----------
+    rep : any
+        If `rep` is an instance of a scalar dtype, True is returned. If not,
+        False is returned.
+
+    Returns
+    -------
+    out : bool
+        Boolean result of check whether `rep` is a scalar dtype.
+
+    See Also
+    --------
+    issubsctype, issubdtype, obj2sctype, sctype2char
+
+    Examples
+    --------
+    >>> np.issctype(np.int32)
+    True
+    >>> np.issctype(list)
+    False
+    >>> np.issctype(1.1)
+    False
+
+    Strings are also a scalar type:
+
+    >>> np.issctype(np.dtype('str'))
+    True
+
+    """
+    if not isinstance(rep, (type, dtype)):
+        return False
+    try:
+        res = obj2sctype(rep)
+        if res and res != object_:
+            return True
+        return False
+    except:
+        return False
+
+def obj2sctype(rep, default=None):
+    """
+    Return the scalar dtype or NumPy equivalent of Python type of an object.
+
+    Parameters
+    ----------
+    rep : any
+        The object of which the type is returned.
+    default : any, optional
+        If given, this is returned for objects whose types can not be
+        determined. If not given, None is returned for those objects.
+
+    Returns
+    -------
+    dtype : dtype or Python type
+        The data type of `rep`.
+
+    See Also
+    --------
+    sctype2char, issctype, issubsctype, issubdtype, maximum_sctype
+
+    Examples
+    --------
+    >>> np.obj2sctype(np.int32)
+    <type 'numpy.int32'>
+    >>> np.obj2sctype(np.array([1., 2.]))
+    <type 'numpy.float64'>
+    >>> np.obj2sctype(np.array([1.j]))
+    <type 'numpy.complex128'>
+
+    >>> np.obj2sctype(dict)
+    <type 'numpy.object_'>
+    >>> np.obj2sctype('string')
+    <type 'numpy.string_'>
+
+    >>> np.obj2sctype(1, default=list)
+    <type 'list'>
+
+    """
+    try:
+        if issubclass(rep, generic):
+            return rep
+    except TypeError:
+        pass
+    if isinstance(rep, dtype):
+        return rep.type
+    if isinstance(rep, type):
+        return _python_type(rep)
+    if isinstance(rep, ndarray):
+        return rep.dtype.type
+    try:
+        res = dtype(rep)
+    except:
+        return default
+    return res.type
+
+
+def issubclass_(arg1, arg2):
+    """
+    Determine if a class is a subclass of a second class.
+
+    `issubclass_` is equivalent to the Python built-in ``issubclass``,
+    except that it returns False instead of raising a TypeError if one
+    of the arguments is not a class.
+
+    Parameters
+    ----------
+    arg1 : class
+        Input class. True is returned if `arg1` is a subclass of `arg2`.
+    arg2 : class or tuple of classes.
+        Input class. If a tuple of classes, True is returned if `arg1` is a
+        subclass of any of the tuple elements.
+
+    Returns
+    -------
+    out : bool
+        Whether `arg1` is a subclass of `arg2` or not.
+
+    See Also
+    --------
+    issubsctype, issubdtype, issctype
+
+    Examples
+    --------
+    >>> np.issubclass_(np.int32, np.int)
+    True
+    >>> np.issubclass_(np.int32, np.float)
+    False
+
+    """
+    try:
+        return issubclass(arg1, arg2)
+    except TypeError:
+        return False
+
+def issubsctype(arg1, arg2):
+    """
+    Determine if the first argument is a subclass of the second argument.
+
+    Parameters
+    ----------
+    arg1, arg2 : dtype or dtype specifier
+        Data-types.
+
+    Returns
+    -------
+    out : bool
+        The result.
+
+    See Also
+    --------
+    issctype, issubdtype,obj2sctype
+
+    Examples
+    --------
+    >>> np.issubsctype('S8', str)
+    True
+    >>> np.issubsctype(np.array([1]), np.int)
+    True
+    >>> np.issubsctype(np.array([1]), np.float)
+    False
+
+    """
+    return issubclass(obj2sctype(arg1), obj2sctype(arg2))
+
+def issubdtype(arg1, arg2):
+    """
+    Returns True if first argument is a typecode lower/equal in type hierarchy.
+
+    Parameters
+    ----------
+    arg1, arg2 : dtype_like
+        dtype or string representing a typecode.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    issubsctype, issubclass_
+    numpy.core.numerictypes : Overview of numpy type hierarchy.
+
+    Examples
+    --------
+    >>> np.issubdtype('S1', str)
+    True
+    >>> np.issubdtype(np.float64, np.float32)
+    False
+
+    """
+    if issubclass_(arg2, generic):
+        return issubclass(dtype(arg1).type, arg2)
+    mro = dtype(arg2).type.mro()
+    if len(mro) > 1:
+        val = mro[1]
+    else:
+        val = mro[0]
+    return issubclass(dtype(arg1).type, val)
+
+
+# This dictionary allows look up based on any alias for an array data-type
+class _typedict(dict):
+    """
+    Base object for a dictionary for look-up with any alias for an array dtype.
+
+    Instances of `_typedict` can not be used as dictionaries directly,
+    first they have to be populated.
+
+    """
+
+    def __getitem__(self, obj):
+        return dict.__getitem__(self, obj2sctype(obj))
+
+nbytes = _typedict()
+_alignment = _typedict()
+_maxvals = _typedict()
+_minvals = _typedict()
+def _construct_lookups():
+    for name, val in typeinfo.items():
+        if not isinstance(val, tuple):
+            continue
+        obj = val[-1]
+        nbytes[obj] = val[2] // 8
+        _alignment[obj] = val[3]
+        if (len(val) > 5):
+            _maxvals[obj] = val[4]
+            _minvals[obj] = val[5]
+        else:
+            _maxvals[obj] = None
+            _minvals[obj] = None
+
+_construct_lookups()
+
+def sctype2char(sctype):
+    """
+    Return the string representation of a scalar dtype.
+
+    Parameters
+    ----------
+    sctype : scalar dtype or object
+        If a scalar dtype, the corresponding string character is
+        returned. If an object, `sctype2char` tries to infer its scalar type
+        and then return the corresponding string character.
+
+    Returns
+    -------
+    typechar : str
+        The string character corresponding to the scalar type.
+
+    Raises
+    ------
+    ValueError
+        If `sctype` is an object for which the type can not be inferred.
+
+    See Also
+    --------
+    obj2sctype, issctype, issubsctype, mintypecode
+
+    Examples
+    --------
+    >>> for sctype in [np.int32, np.float, np.complex, np.string_, np.ndarray]:
+    ...     print(np.sctype2char(sctype))
+    l
+    d
+    D
+    S
+    O
+
+    >>> x = np.array([1., 2-1.j])
+    >>> np.sctype2char(x)
+    'D'
+    >>> np.sctype2char(list)
+    'O'
+
+    """
+    sctype = obj2sctype(sctype)
+    if sctype is None:
+        raise ValueError("unrecognized type")
+    return _sctype2char_dict[sctype]
+
+# Create dictionary of casting functions that wrap sequences
+# indexed by type or type character
+
+
+cast = _typedict()
+try:
+    ScalarType = [_types.IntType, _types.FloatType, _types.ComplexType,
+                  _types.LongType, _types.BooleanType,
+                   _types.StringType, _types.UnicodeType, _types.BufferType]
+except AttributeError:
+    # Py3K
+    ScalarType = [int, float, complex, int, bool, bytes, str, memoryview]
+
+ScalarType.extend(_sctype2char_dict.keys())
+ScalarType = tuple(ScalarType)
+for key in _sctype2char_dict.keys():
+    cast[key] = lambda x, k=key: array(x, copy=False).astype(k)
+
+# Create the typestring lookup dictionary
+_typestr = _typedict()
+for key in _sctype2char_dict.keys():
+    if issubclass(key, allTypes['flexible']):
+        _typestr[key] = _sctype2char_dict[key]
+    else:
+        _typestr[key] = empty((1,), key).dtype.str[1:]
+
+# Make sure all typestrings are in sctypeDict
+for key, val in _typestr.items():
+    if val not in sctypeDict:
+        sctypeDict[val] = key
+
+# Add additional strings to the sctypeDict
+
+if sys.version_info[0] >= 3:
+    _toadd = ['int', 'float', 'complex', 'bool', 'object',
+              'str', 'bytes', 'object', ('a', allTypes['bytes_'])]
+else:
+    _toadd = ['int', 'float', 'complex', 'bool', 'object', 'string',
+              ('str', allTypes['string_']),
+              'unicode', 'object', ('a', allTypes['string_'])]
+
+for name in _toadd:
+    if isinstance(name, tuple):
+        sctypeDict[name[0]] = name[1]
+    else:
+        sctypeDict[name] = allTypes['%s_' % name]
+
+del _toadd, name
+
+# Now add the types we've determined to this module
+for key in allTypes:
+    globals()[key] = allTypes[key]
+    __all__.append(key)
+
+del key
+
+typecodes = {'Character':'c',
+             'Integer':'bhilqp',
+             'UnsignedInteger':'BHILQP',
+             'Float':'efdg',
+             'Complex':'FDG',
+             'AllInteger':'bBhHiIlLqQpP',
+             'AllFloat':'efdgFDG',
+             'Datetime': 'Mm',
+             'All':'?bhilqpBHILQPefdgFDGSUVOMm'}
+
+# backwards compatibility --- deprecated name
+typeDict = sctypeDict
+typeNA = sctypeNA
+
+# b -> boolean
+# u -> unsigned integer
+# i -> signed integer
+# f -> floating point
+# c -> complex
+# M -> datetime
+# m -> timedelta
+# S -> string
+# U -> Unicode string
+# V -> record
+# O -> Python object
+_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm']
+
+__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O'
+__len_test_types = len(__test_types)
+
+# Keep incrementing until a common type both can be coerced to
+#  is found.  Otherwise, return None
+def _find_common_coerce(a, b):
+    if a > b:
+        return a
+    try:
+        thisind = __test_types.index(a.char)
+    except ValueError:
+        return None
+    return _can_coerce_all([a, b], start=thisind)
+
+# Find a data-type that all data-types in a list can be coerced to
+def _can_coerce_all(dtypelist, start=0):
+    N = len(dtypelist)
+    if N == 0:
+        return None
+    if N == 1:
+        return dtypelist[0]
+    thisind = start
+    while thisind < __len_test_types:
+        newdtype = dtype(__test_types[thisind])
+        numcoerce = len([x for x in dtypelist if newdtype >= x])
+        if numcoerce == N:
+            return newdtype
+        thisind += 1
+    return None
+
+def _register_types():
+    numbers.Integral.register(integer)
+    numbers.Complex.register(inexact)
+    numbers.Real.register(floating)
+
+_register_types()
+
+def find_common_type(array_types, scalar_types):
+    """
+    Determine common type following standard coercion rules.
+
+    Parameters
+    ----------
+    array_types : sequence
+        A list of dtypes or dtype convertible objects representing arrays.
+    scalar_types : sequence
+        A list of dtypes or dtype convertible objects representing scalars.
+
+    Returns
+    -------
+    datatype : dtype
+        The common data type, which is the maximum of `array_types` ignoring
+        `scalar_types`, unless the maximum of `scalar_types` is of a
+        different kind (`dtype.kind`). If the kind is not understood, then
+        None is returned.
+
+    See Also
+    --------
+    dtype, common_type, can_cast, mintypecode
+
+    Examples
+    --------
+    >>> np.find_common_type([], [np.int64, np.float32, np.complex])
+    dtype('complex128')
+    >>> np.find_common_type([np.int64, np.float32], [])
+    dtype('float64')
+
+    The standard casting rules ensure that a scalar cannot up-cast an
+    array unless the scalar is of a fundamentally different kind of data
+    (i.e. under a different hierarchy in the data type hierarchy) then
+    the array:
+
+    >>> np.find_common_type([np.float32], [np.int64, np.float64])
+    dtype('float32')
+
+    Complex is of a different type, so it up-casts the float in the
+    `array_types` argument:
+
+    >>> np.find_common_type([np.float32], [np.complex])
+    dtype('complex128')
+
+    Type specifier strings are convertible to dtypes and can therefore
+    be used instead of dtypes:
+
+    >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8'])
+    dtype('complex128')
+
+    """
+    array_types = [dtype(x) for x in array_types]
+    scalar_types = [dtype(x) for x in scalar_types]
+
+    maxa = _can_coerce_all(array_types)
+    maxsc = _can_coerce_all(scalar_types)
+
+    if maxa is None:
+        return maxsc
+
+    if maxsc is None:
+        return maxa
+
+    try:
+        index_a = _kind_list.index(maxa.kind)
+        index_sc = _kind_list.index(maxsc.kind)
+    except ValueError:
+        return None
+
+    if index_sc > index_a:
+        return _find_common_coerce(maxsc, maxa)
+    else:
+        return maxa
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..ebd2d4b5f54d264c5a6fb5c3219709e42ce70985
GIT binary patch
literal 17408
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
M07!&k6woFF0KOeJv;Y7A

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/records.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/records.py
new file mode 100644
index 0000000000..9f5dcc8110
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/records.py
@@ -0,0 +1,855 @@
+"""
+Record Arrays
+=============
+Record arrays expose the fields of structured arrays as properties.
+
+Most commonly, ndarrays contain elements of a single type, e.g. floats,
+integers, bools etc.  However, it is possible for elements to be combinations
+of these using structured types, such as::
+
+  >>> a = np.array([(1, 2.0), (1, 2.0)], dtype=[('x', int), ('y', float)])
+  >>> a
+  array([(1, 2.0), (1, 2.0)],
+        dtype=[('x', '<i4'), ('y', '<f8')])
+
+Here, each element consists of two fields: x (and int), and y (a float).
+This is known as a structured array.  The different fields are analogous
+to columns in a spread-sheet.  The different fields can be accessed as
+one would a dictionary::
+
+  >>> a['x']
+  array([1, 1])
+
+  >>> a['y']
+  array([ 2.,  2.])
+
+Record arrays allow us to access fields as properties::
+
+  >>> ar = np.rec.array(a)
+
+  >>> ar.x
+  array([1, 1])
+
+  >>> ar.y
+  array([ 2.,  2.])
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+
+from . import numeric as sb
+from . import numerictypes as nt
+from numpy.compat import isfileobj, bytes, long
+
+# All of the functions allow formats to be a dtype
+__all__ = ['record', 'recarray', 'format_parser']
+
+
+ndarray = sb.ndarray
+
+_byteorderconv = {'b':'>',
+                  'l':'<',
+                  'n':'=',
+                  'B':'>',
+                  'L':'<',
+                  'N':'=',
+                  'S':'s',
+                  's':'s',
+                  '>':'>',
+                  '<':'<',
+                  '=':'=',
+                  '|':'|',
+                  'I':'|',
+                  'i':'|'}
+
+# formats regular expression
+# allows multidimension spec with a tuple syntax in front
+# of the letter code '(2,3)f4' and ' (  2 ,  3  )  f4  '
+# are equally allowed
+
+numfmt = nt.typeDict
+
+def find_duplicate(list):
+    """Find duplication in a list, return a list of duplicated elements"""
+    dup = []
+    for i in range(len(list)):
+        if (list[i] in list[i + 1:]):
+            if (list[i] not in dup):
+                dup.append(list[i])
+    return dup
+
+class format_parser:
+    """
+    Class to convert formats, names, titles description to a dtype.
+
+    After constructing the format_parser object, the dtype attribute is
+    the converted data-type:
+    ``dtype = format_parser(formats, names, titles).dtype``
+
+    Attributes
+    ----------
+    dtype : dtype
+        The converted data-type.
+
+    Parameters
+    ----------
+    formats : str or list of str
+        The format description, either specified as a string with
+        comma-separated format descriptions in the form ``'f8, i4, a5'``, or
+        a list of format description strings  in the form
+        ``['f8', 'i4', 'a5']``.
+    names : str or list/tuple of str
+        The field names, either specified as a comma-separated string in the
+        form ``'col1, col2, col3'``, or as a list or tuple of strings in the
+        form ``['col1', 'col2', 'col3']``.
+        An empty list can be used, in that case default field names
+        ('f0', 'f1', ...) are used.
+    titles : sequence
+        Sequence of title strings. An empty list can be used to leave titles
+        out.
+    aligned : bool, optional
+        If True, align the fields by padding as the C-compiler would.
+        Default is False.
+    byteorder : str, optional
+        If specified, all the fields will be changed to the
+        provided byte-order.  Otherwise, the default byte-order is
+        used. For all available string specifiers, see `dtype.newbyteorder`.
+
+    See Also
+    --------
+    dtype, typename, sctype2char
+
+    Examples
+    --------
+    >>> np.format_parser(['f8', 'i4', 'a5'], ['col1', 'col2', 'col3'],
+    ...                  ['T1', 'T2', 'T3']).dtype
+    dtype([(('T1', 'col1'), '<f8'), (('T2', 'col2'), '<i4'),
+           (('T3', 'col3'), '|S5')])
+
+    `names` and/or `titles` can be empty lists. If `titles` is an empty list,
+    titles will simply not appear. If `names` is empty, default field names
+    will be used.
+
+    >>> np.format_parser(['f8', 'i4', 'a5'], ['col1', 'col2', 'col3'],
+    ...                  []).dtype
+    dtype([('col1', '<f8'), ('col2', '<i4'), ('col3', '|S5')])
+    >>> np.format_parser(['f8', 'i4', 'a5'], [], []).dtype
+    dtype([('f0', '<f8'), ('f1', '<i4'), ('f2', '|S5')])
+
+    """
+
+    def __init__(self, formats, names, titles, aligned=False, byteorder=None):
+        self._parseFormats(formats, aligned)
+        self._setfieldnames(names, titles)
+        self._createdescr(byteorder)
+        self.dtype = self._descr
+
+    def _parseFormats(self, formats, aligned=0):
+        """ Parse the field formats """
+
+        if formats is None:
+            raise ValueError("Need formats argument")
+        if isinstance(formats, list):
+            if len(formats) < 2:
+                formats.append('')
+            formats = ','.join(formats)
+        dtype = sb.dtype(formats, aligned)
+        fields = dtype.fields
+        if fields is None:
+            dtype = sb.dtype([('f1', dtype)], aligned)
+            fields = dtype.fields
+        keys = dtype.names
+        self._f_formats = [fields[key][0] for key in keys]
+        self._offsets = [fields[key][1] for key in keys]
+        self._nfields = len(keys)
+
+    def _setfieldnames(self, names, titles):
+        """convert input field names into a list and assign to the _names
+        attribute """
+
+        if (names):
+            if (type(names) in [list, tuple]):
+                pass
+            elif isinstance(names, str):
+                names = names.split(',')
+            else:
+                raise NameError("illegal input names %s" % repr(names))
+
+            self._names = [n.strip() for n in names[:self._nfields]]
+        else:
+            self._names = []
+
+        # if the names are not specified, they will be assigned as
+        #  "f0, f1, f2,..."
+        # if not enough names are specified, they will be assigned as "f[n],
+        # f[n+1],..." etc. where n is the number of specified names..."
+        self._names += ['f%d' % i for i in range(len(self._names),
+                                                 self._nfields)]
+        # check for redundant names
+        _dup = find_duplicate(self._names)
+        if _dup:
+            raise ValueError("Duplicate field names: %s" % _dup)
+
+        if (titles):
+            self._titles = [n.strip() for n in titles[:self._nfields]]
+        else:
+            self._titles = []
+            titles = []
+
+        if (self._nfields > len(titles)):
+            self._titles += [None] * (self._nfields - len(titles))
+
+    def _createdescr(self, byteorder):
+        descr = sb.dtype({'names':self._names,
+                          'formats':self._f_formats,
+                          'offsets':self._offsets,
+                          'titles':self._titles})
+        if (byteorder is not None):
+            byteorder = _byteorderconv[byteorder[0]]
+            descr = descr.newbyteorder(byteorder)
+
+        self._descr = descr
+
+class record(nt.void):
+    """A data-type scalar that allows field access as attribute lookup.
+    """
+
+    # manually set name and module so that this class's type shows up
+    # as numpy.record when printed
+    __name__ = 'record'
+    __module__ = 'numpy'
+
+    def __repr__(self):
+        return self.__str__()
+
+    def __str__(self):
+        return str(self.item())
+
+    def __getattribute__(self, attr):
+        if attr in ['setfield', 'getfield', 'dtype']:
+            return nt.void.__getattribute__(self, attr)
+        try:
+            return nt.void.__getattribute__(self, attr)
+        except AttributeError:
+            pass
+        fielddict = nt.void.__getattribute__(self, 'dtype').fields
+        res = fielddict.get(attr, None)
+        if res:
+            obj = self.getfield(*res[:2])
+            # if it has fields return a record,
+            # otherwise return the object
+            try:
+                dt = obj.dtype
+            except AttributeError:
+                #happens if field is Object type
+                return obj
+            if dt.fields:
+                return obj.view((self.__class__, obj.dtype.fields))
+            return obj
+        else:
+            raise AttributeError("'record' object has no "
+                    "attribute '%s'" % attr)
+
+    def __setattr__(self, attr, val):
+        if attr in ['setfield', 'getfield', 'dtype']:
+            raise AttributeError("Cannot set '%s' attribute" % attr)
+        fielddict = nt.void.__getattribute__(self, 'dtype').fields
+        res = fielddict.get(attr, None)
+        if res:
+            return self.setfield(val, *res[:2])
+        else:
+            if getattr(self, attr, None):
+                return nt.void.__setattr__(self, attr, val)
+            else:
+                raise AttributeError("'record' object has no "
+                        "attribute '%s'" % attr)
+
+    def __getitem__(self, indx):
+        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))
+        else:
+            # return a single element
+            return obj
+
+    def pprint(self):
+        """Pretty-print all fields."""
+        # pretty-print all fields
+        names = self.dtype.names
+        maxlen = max(len(name) for name in names)
+        rows = []
+        fmt = '%% %ds: %%s' % maxlen
+        for name in names:
+            rows.append(fmt % (name, getattr(self, name)))
+        return "\n".join(rows)
+
+# The recarray is almost identical to a standard array (which supports
+#   named fields already)  The biggest difference is that it can use
+#   attribute-lookup to find the fields and it is constructed using
+#   a record.
+
+# If byteorder is given it forces a particular byteorder on all
+#  the fields (and any subfields)
+
+class recarray(ndarray):
+    """Construct an ndarray that allows field access using attributes.
+
+    Arrays may have a data-types containing fields, analogous
+    to columns in a spread sheet.  An example is ``[(x, int), (y, float)]``,
+    where each entry in the array is a pair of ``(int, float)``.  Normally,
+    these attributes are accessed using dictionary lookups such as ``arr['x']``
+    and ``arr['y']``.  Record arrays allow the fields to be accessed as members
+    of the array, using ``arr.x`` and ``arr.y``.
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of output array.
+    dtype : data-type, optional
+        The desired data-type.  By default, the data-type is determined
+        from `formats`, `names`, `titles`, `aligned` and `byteorder`.
+    formats : list of data-types, optional
+        A list containing the data-types for the different columns, e.g.
+        ``['i4', 'f8', 'i4']``.  `formats` does *not* support the new
+        convention of using types directly, i.e. ``(int, float, int)``.
+        Note that `formats` must be a list, not a tuple.
+        Given that `formats` is somewhat limited, we recommend specifying
+        `dtype` instead.
+    names : tuple of str, optional
+        The name of each column, e.g. ``('x', 'y', 'z')``.
+    buf : buffer, optional
+        By default, a new array is created of the given shape and data-type.
+        If `buf` is specified and is an object exposing the buffer interface,
+        the array will use the memory from the existing buffer.  In this case,
+        the `offset` and `strides` keywords are available.
+
+    Other Parameters
+    ----------------
+    titles : tuple of str, optional
+        Aliases for column names.  For example, if `names` were
+        ``('x', 'y', 'z')`` and `titles` is
+        ``('x_coordinate', 'y_coordinate', 'z_coordinate')``, then
+        ``arr['x']`` is equivalent to both ``arr.x`` and ``arr.x_coordinate``.
+    byteorder : {'<', '>', '='}, optional
+        Byte-order for all fields.
+    aligned : bool, optional
+        Align the fields in memory as the C-compiler would.
+    strides : tuple of ints, optional
+        Buffer (`buf`) is interpreted according to these strides (strides
+        define how many bytes each array element, row, column, etc.
+        occupy in memory).
+    offset : int, optional
+        Start reading buffer (`buf`) from this offset onwards.
+    order : {'C', 'F'}, optional
+        Row-major (C-style) or column-major (Fortran-style) order.
+
+    Returns
+    -------
+    rec : recarray
+        Empty array of the given shape and type.
+
+    See Also
+    --------
+    rec.fromrecords : Construct a record array from data.
+    record : fundamental data-type for `recarray`.
+    format_parser : determine a data-type from formats, names, titles.
+
+    Notes
+    -----
+    This constructor can be compared to ``empty``: it creates a new record
+    array but does not fill it with data.  To create a record array from data,
+    use one of the following methods:
+
+    1. Create a standard ndarray and convert it to a record array,
+       using ``arr.view(np.recarray)``
+    2. Use the `buf` keyword.
+    3. Use `np.rec.fromrecords`.
+
+    Examples
+    --------
+    Create an array with two fields, ``x`` and ``y``:
+
+    >>> x = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
+    >>> x
+    array([(1.0, 2), (3.0, 4)],
+          dtype=[('x', '<f8'), ('y', '<i4')])
+
+    >>> x['x']
+    array([ 1.,  3.])
+
+    View the array as a record array:
+
+    >>> x = x.view(np.recarray)
+
+    >>> x.x
+    array([ 1.,  3.])
+
+    >>> x.y
+    array([2, 4])
+
+    Create a new, empty record array:
+
+    >>> np.recarray((2,),
+    ... dtype=[('x', int), ('y', float), ('z', int)]) #doctest: +SKIP
+    rec.array([(-1073741821, 1.2249118382103472e-301, 24547520),
+           (3471280, 1.2134086255804012e-316, 0)],
+          dtype=[('x', '<i4'), ('y', '<f8'), ('z', '<i4')])
+
+    """
+
+    # manually set name and module so that this class's type shows
+    # up as "numpy.recarray" when printed
+    __name__ = 'recarray'
+    __module__ = 'numpy'
+
+    def __new__(subtype, shape, dtype=None, buf=None, offset=0, strides=None,
+                formats=None, names=None, titles=None,
+                byteorder=None, aligned=False, order='C'):
+
+        if dtype is not None:
+            descr = sb.dtype(dtype)
+        else:
+            descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+        if buf is None:
+            self = ndarray.__new__(subtype, shape, (record, descr), order=order)
+        else:
+            self = ndarray.__new__(subtype, shape, (record, descr),
+                                      buffer=buf, offset=offset,
+                                      strides=strides, order=order)
+        return self
+
+    def __array_finalize__(self, obj):
+        if self.dtype.type is not record:
+            # 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
+
+    def __getattribute__(self, attr):
+        # See if ndarray has this attr, and return it if so. (note that this
+        # means a field with the same name as an ndarray attr cannot be
+        # accessed by attribute).
+        try:
+            return object.__getattribute__(self, attr)
+        except AttributeError:  # attr must be a fieldname
+            pass
+
+        # look for a field with this name
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("recarray has no attribute %s" % attr)
+        obj = self.getfield(*res)
+
+        # At this point obj will always be a recarray, since (see
+        # PyArray_GetField) the type of obj is inherited. Next, if obj.dtype is
+        # non-structured, convert it to an ndarray. Then if obj is structured
+        # 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 issubclass(obj.dtype.type, nt.void):
+                return obj.view(dtype=(self.dtype.type, obj.dtype))
+            return obj
+        else:
+            return obj.view(ndarray)
+
+    # Save the dictionary.
+    # If the attr is a field name and not in the saved dictionary
+    # Undo any "setting" of the attribute and do a setfield
+    # Thus, you can't create attributes on-the-fly that are field names.
+    def __setattr__(self, attr, val):
+
+        # 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:
+            val = sb.dtype((record, val))
+
+        newattr = attr not in self.__dict__
+        try:
+            ret = object.__setattr__(self, attr, val)
+        except:
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            if attr not in fielddict:
+                exctype, value = sys.exc_info()[:2]
+                raise exctype(value)
+        else:
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            if attr not in fielddict:
+                return ret
+            if newattr:
+                # We just added this one or this setattr worked on an
+                # internal attribute.
+                try:
+                    object.__delattr__(self, attr)
+                except:
+                    return ret
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+        return self.setfield(val, *res)
+
+    def __getitem__(self, indx):
+        obj = super(recarray, self).__getitem__(indx)
+
+        # copy behavior of getattr, except that here
+        # we might also be returning a single element
+        if isinstance(obj, ndarray):
+            if obj.dtype.fields:
+                obj = obj.view(type(self))
+                if issubclass(obj.dtype.type, nt.void):
+                    return obj.view(dtype=(self.dtype.type, obj.dtype))
+                return obj
+            else:
+                return obj.view(type=ndarray)
+        else:
+            # return a single element
+            return obj
+
+    def __repr__(self):
+        # get data/shape string. logic taken from numeric.array_repr
+        if self.size > 0 or self.shape == (0,):
+            lst = sb.array2string(self, separator=', ')
+        else:
+            # show zero-length shape unless it is (0,)
+            lst = "[], shape=%s" % (repr(self.shape),)
+
+        if (self.dtype.type is record
+                or (not issubclass(self.dtype.type, nt.void))):
+            # If this is a full record array (has numpy.record dtype),
+            # or if it has a scalar (non-void) dtype with no records,
+            # represent it using the rec.array function. Since rec.array
+            # converts dtype to a numpy.record for us, convert back
+            # to non-record before printing
+            plain_dtype = self.dtype
+            if plain_dtype.type is record:
+                plain_dtype = sb.dtype((nt.void, plain_dtype))
+            lf = '\n'+' '*len("rec.array(")
+            return ('rec.array(%s, %sdtype=%s)' %
+                          (lst, lf, plain_dtype))
+        else:
+            # otherwise represent it using np.array plus a view
+            # This should only happen if the user is playing
+            # strange games with dtypes.
+            lf = '\n'+' '*len("array(")
+            return ('array(%s, %sdtype=%s).view(numpy.recarray)' %
+                          (lst, lf, str(self.dtype)))
+
+    def field(self, attr, val=None):
+        if isinstance(attr, int):
+            names = ndarray.__getattribute__(self, 'dtype').names
+            attr = names[attr]
+
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+
+        res = fielddict[attr][:2]
+
+        if val is None:
+            obj = self.getfield(*res)
+            if obj.dtype.fields:
+                return obj
+            return obj.view(ndarray)
+        else:
+            return self.setfield(val, *res)
+
+
+def fromarrays(arrayList, dtype=None, shape=None, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None):
+    """ create a record array from a (flat) list of arrays
+
+    >>> x1=np.array([1,2,3,4])
+    >>> x2=np.array(['a','dd','xyz','12'])
+    >>> x3=np.array([1.1,2,3,4])
+    >>> r = np.core.records.fromarrays([x1,x2,x3],names='a,b,c')
+    >>> print(r[1])
+    (2, 'dd', 2.0)
+    >>> x1[1]=34
+    >>> r.a
+    array([1, 2, 3, 4])
+    """
+
+    arrayList = [sb.asarray(x) for x in arrayList]
+
+    if shape is None or shape == 0:
+        shape = arrayList[0].shape
+
+    if isinstance(shape, int):
+        shape = (shape,)
+
+    if formats is None and dtype is None:
+        # go through each object in the list to see if it is an ndarray
+        # and determine the formats.
+        formats = []
+        for obj in arrayList:
+            if not isinstance(obj, ndarray):
+                raise ValueError("item in the array list must be an ndarray.")
+            formats.append(obj.dtype.str)
+        formats = ','.join(formats)
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+        _names = descr.names
+    else:
+        parsed = format_parser(formats, names, titles, aligned, byteorder)
+        _names = parsed._names
+        descr = parsed._descr
+
+    # Determine shape from data-type.
+    if len(descr) != len(arrayList):
+        raise ValueError("mismatch between the number of fields "
+                "and the number of arrays")
+
+    d0 = descr[0].shape
+    nn = len(d0)
+    if nn > 0:
+        shape = shape[:-nn]
+
+    for k, obj in enumerate(arrayList):
+        nn = len(descr[k].shape)
+        testshape = obj.shape[:len(obj.shape) - nn]
+        if testshape != shape:
+            raise ValueError("array-shape mismatch in array %d" % k)
+
+    _array = recarray(shape, descr)
+
+    # populate the record array (makes a copy)
+    for i in range(len(arrayList)):
+        _array[_names[i]] = arrayList[i]
+
+    return _array
+
+# shape must be 1-d if you use list of lists...
+def fromrecords(recList, dtype=None, shape=None, formats=None, names=None,
+                titles=None, aligned=False, byteorder=None):
+    """ create a recarray from a list of records in text form
+
+        The data in the same field can be heterogeneous, they will be promoted
+        to the highest data type.  This method is intended for creating
+        smaller record arrays.  If used to create large array without formats
+        defined
+
+        r=fromrecords([(2,3.,'abc')]*100000)
+
+        it can be slow.
+
+        If formats is None, then this will auto-detect formats. Use list of
+        tuples rather than list of lists for faster processing.
+
+    >>> r=np.core.records.fromrecords([(456,'dbe',1.2),(2,'de',1.3)],
+    ... names='col1,col2,col3')
+    >>> print(r[0])
+    (456, 'dbe', 1.2)
+    >>> r.col1
+    array([456,   2])
+    >>> r.col2
+    array(['dbe', 'de'],
+          dtype='|S3')
+    >>> import pickle
+    >>> print(pickle.loads(pickle.dumps(r)))
+    [(456, 'dbe', 1.2) (2, 'de', 1.3)]
+    """
+
+    nfields = len(recList[0])
+    if formats is None and dtype is None:  # slower
+        obj = sb.array(recList, dtype=object)
+        arrlist = [sb.array(obj[..., i].tolist()) for i in range(nfields)]
+        return fromarrays(arrlist, formats=formats, shape=shape, names=names,
+                          titles=titles, aligned=aligned, byteorder=byteorder)
+
+    if dtype is not None:
+        descr = sb.dtype((record, dtype))
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    try:
+        retval = sb.array(recList, dtype=descr)
+    except TypeError:  # list of lists instead of list of tuples
+        if (shape is None or shape == 0):
+            shape = len(recList)
+        if isinstance(shape, (int, long)):
+            shape = (shape,)
+        if len(shape) > 1:
+            raise ValueError("Can only deal with 1-d array.")
+        _array = recarray(shape, descr)
+        for k in range(_array.size):
+            _array[k] = tuple(recList[k])
+        return _array
+    else:
+        if shape is not None and retval.shape != shape:
+            retval.shape = shape
+
+    res = retval.view(recarray)
+
+    return res
+
+
+def fromstring(datastring, dtype=None, shape=None, offset=0, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None):
+    """ create a (read-only) record array from binary data contained in
+    a string"""
+
+    if dtype is None and formats is None:
+        raise ValueError("Must have dtype= or formats=")
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    itemsize = descr.itemsize
+    if (shape is None or shape == 0 or shape == -1):
+        shape = (len(datastring) - offset) / itemsize
+
+    _array = recarray(shape, descr, buf=datastring, offset=offset)
+    return _array
+
+def get_remaining_size(fd):
+    try:
+        fn = fd.fileno()
+    except AttributeError:
+        return os.path.getsize(fd.name) - fd.tell()
+    st = os.fstat(fn)
+    size = st.st_size - fd.tell()
+    return size
+
+def fromfile(fd, dtype=None, shape=None, offset=0, formats=None,
+             names=None, titles=None, aligned=False, byteorder=None):
+    """Create an array from binary file data
+
+    If file is a string then that file is opened, else it is assumed
+    to be a file object.
+
+    >>> from tempfile import TemporaryFile
+    >>> a = np.empty(10,dtype='f8,i4,a5')
+    >>> a[5] = (0.5,10,'abcde')
+    >>>
+    >>> fd=TemporaryFile()
+    >>> a = a.newbyteorder('<')
+    >>> a.tofile(fd)
+    >>>
+    >>> fd.seek(0)
+    >>> r=np.core.records.fromfile(fd, formats='f8,i4,a5', shape=10,
+    ... byteorder='<')
+    >>> print(r[5])
+    (0.5, 10, 'abcde')
+    >>> r.shape
+    (10,)
+    """
+
+    if (shape is None or shape == 0):
+        shape = (-1,)
+    elif isinstance(shape, (int, long)):
+        shape = (shape,)
+
+    name = 0
+    if isinstance(fd, str):
+        name = 1
+        fd = open(fd, 'rb')
+    if (offset > 0):
+        fd.seek(offset, 1)
+    size = get_remaining_size(fd)
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    itemsize = descr.itemsize
+
+    shapeprod = sb.array(shape).prod()
+    shapesize = shapeprod * itemsize
+    if shapesize < 0:
+        shape = list(shape)
+        shape[shape.index(-1)] = size / -shapesize
+        shape = tuple(shape)
+        shapeprod = sb.array(shape).prod()
+
+    nbytes = shapeprod * itemsize
+
+    if nbytes > size:
+        raise ValueError(
+                "Not enough bytes left in file for specified shape and type")
+
+    # create the array
+    _array = recarray(shape, descr)
+    nbytesread = fd.readinto(_array.data)
+    if nbytesread != nbytes:
+        raise IOError("Didn't read as many bytes as expected")
+    if name:
+        fd.close()
+
+    return _array
+
+def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
+          names=None, titles=None, aligned=False, byteorder=None, copy=True):
+    """Construct a record array from a wide-variety of objects.
+    """
+
+    if ((isinstance(obj, (type(None), str)) or isfileobj(obj)) and
+           (formats is None) and (dtype is None)):
+        raise ValueError("Must define formats (or dtype) if object is "
+                         "None, string, or an open file")
+
+    kwds = {}
+    if dtype is not None:
+        dtype = sb.dtype(dtype)
+    elif formats is not None:
+        dtype = format_parser(formats, names, titles,
+                              aligned, byteorder)._descr
+    else:
+        kwds = {'formats': formats,
+                'names': names,
+                'titles': titles,
+                'aligned': aligned,
+                'byteorder': byteorder
+                }
+
+    if obj is None:
+        if shape is None:
+            raise ValueError("Must define a shape if obj is None")
+        return recarray(shape, dtype, buf=obj, offset=offset, strides=strides)
+
+    elif isinstance(obj, bytes):
+        return fromstring(obj, dtype, shape=shape, offset=offset, **kwds)
+
+    elif isinstance(obj, (list, tuple)):
+        if isinstance(obj[0], (tuple, list)):
+            return fromrecords(obj, dtype=dtype, shape=shape, **kwds)
+        else:
+            return fromarrays(obj, dtype=dtype, shape=shape, **kwds)
+
+    elif isinstance(obj, recarray):
+        if dtype is not None and (obj.dtype != dtype):
+            new = obj.view(dtype)
+        else:
+            new = obj
+        if copy:
+            new = new.copy()
+        return new
+
+    elif isfileobj(obj):
+        return fromfile(obj, dtype=dtype, shape=shape, offset=offset)
+
+    elif isinstance(obj, ndarray):
+        if dtype is not None and (obj.dtype != dtype):
+            new = obj.view(dtype)
+        else:
+            new = obj
+        if copy:
+            new = new.copy()
+        return new.view(recarray)
+
+    else:
+        interface = getattr(obj, "__array_interface__", None)
+        if interface is None or not isinstance(interface, dict):
+            raise ValueError("Unknown input type")
+        obj = sb.array(obj)
+        if dtype is not None and (obj.dtype != dtype):
+            obj = obj.view(dtype)
+        return obj.view(recarray)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup.py
new file mode 100644
index 0000000000..3c3d1602e4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup.py
@@ -0,0 +1,964 @@
+from __future__ import division, print_function
+
+import imp
+import os
+import sys
+import pickle
+import copy
+import warnings
+from os.path import join
+from numpy.distutils import log
+from distutils.dep_util import newer
+from distutils.sysconfig import get_config_var
+from numpy._build_utils.apple_accelerate import (uses_accelerate_framework,
+                                                 get_sgemv_fix)
+
+from setup_common import *
+
+# Set to True to enable relaxed strides checking. This (mostly) means
+# that `strides[dim]` is ignored if `shape[dim] == 1` when setting flags.
+NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "0") != "0")
+
+# XXX: ugly, we use a class to avoid calling twice some expensive functions in
+# config.h/numpyconfig.h. I don't see a better way because distutils force
+# config.h generation inside an Extension class, and as such sharing
+# configuration informations between extensions is not easy.
+# Using a pickled-based memoize does not work because config_cmd is an instance
+# method, which cPickle does not like.
+#
+# Use pickle in all cases, as cPickle is gone in python3 and the difference
+# in time is only in build. -- Charles Harris, 2013-03-30
+
+class CallOnceOnly(object):
+    def __init__(self):
+        self._check_types = None
+        self._check_ieee_macros = None
+        self._check_complex = None
+
+    def check_types(self, *a, **kw):
+        if self._check_types is None:
+            out = check_types(*a, **kw)
+            self._check_types = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_types))
+        return out
+
+    def check_ieee_macros(self, *a, **kw):
+        if self._check_ieee_macros is None:
+            out = check_ieee_macros(*a, **kw)
+            self._check_ieee_macros = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_ieee_macros))
+        return out
+
+    def check_complex(self, *a, **kw):
+        if self._check_complex is None:
+            out = check_complex(*a, **kw)
+            self._check_complex = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_complex))
+        return out
+
+PYTHON_HAS_UNICODE_WIDE = True
+
+def pythonlib_dir():
+    """return path where libpython* is."""
+    if sys.platform == 'win32':
+        return os.path.join(sys.prefix, "libs")
+    else:
+        return get_config_var('LIBDIR')
+
+def is_npy_no_signal():
+    """Return True if the NPY_NO_SIGNAL symbol must be defined in configuration
+    header."""
+    return sys.platform == 'win32'
+
+def is_npy_no_smp():
+    """Return True if the NPY_NO_SMP symbol must be defined in public
+    header (when SMP support cannot be reliably enabled)."""
+    # Perhaps a fancier check is in order here.
+    #  so that threads are only enabled if there
+    #  are actually multiple CPUS? -- but
+    #  threaded code can be nice even on a single
+    #  CPU so that long-calculating code doesn't
+    #  block.
+    return 'NPY_NOSMP' in os.environ
+
+def win32_checks(deflist):
+    from numpy.distutils.misc_util import get_build_architecture
+    a = get_build_architecture()
+
+    # Distutils hack on AMD64 on windows
+    print('BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' %
+          (a, os.name, sys.platform))
+    if a == 'AMD64':
+        deflist.append('DISTUTILS_USE_SDK')
+
+    # On win32, force long double format string to be 'g', not
+    # 'Lg', since the MS runtime does not support long double whose
+    # size is > sizeof(double)
+    if a == "Intel" or a == "AMD64":
+        deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
+
+def check_math_capabilities(config, moredefs, mathlibs):
+    def check_func(func_name):
+        return config.check_func(func_name, libraries=mathlibs,
+                                 decl=True, call=True)
+
+    def check_funcs_once(funcs_name):
+        decl = dict([(f, True) for f in funcs_name])
+        st = config.check_funcs_once(funcs_name, libraries=mathlibs,
+                                     decl=decl, call=decl)
+        if st:
+            moredefs.extend([(fname2def(f), 1) for f in funcs_name])
+        return st
+
+    def check_funcs(funcs_name):
+        # Use check_funcs_once first, and if it does not work, test func per
+        # func. Return success only if all the functions are available
+        if not check_funcs_once(funcs_name):
+            # Global check failed, check func per func
+            for f in funcs_name:
+                if check_func(f):
+                    moredefs.append((fname2def(f), 1))
+            return 0
+        else:
+            return 1
+
+    #use_msvc = config.check_decl("_MSC_VER")
+
+    if not check_funcs_once(MANDATORY_FUNCS):
+        raise SystemError("One of the required function to build numpy is not"
+                " available (the list is %s)." % str(MANDATORY_FUNCS))
+
+    # Standard functions which may not be available and for which we have a
+    # replacement implementation. Note that some of these are C99 functions.
+
+    # XXX: hack to circumvent cpp pollution from python: python put its
+    # config.h in the public namespace, so we have a clash for the common
+    # functions we test. We remove every function tested by python's
+    # autoconf, hoping their own test are correct
+    for f in OPTIONAL_STDFUNCS_MAYBE:
+        if config.check_decl(fname2def(f),
+                    headers=["Python.h", "math.h"]):
+            OPTIONAL_STDFUNCS.remove(f)
+
+    check_funcs(OPTIONAL_STDFUNCS)
+
+    for h in OPTIONAL_HEADERS:
+        if config.check_func("", decl=False, call=False, headers=[h]):
+            moredefs.append((fname2def(h).replace(".", "_"), 1))
+
+    for tup in OPTIONAL_INTRINSICS:
+        headers = None
+        if len(tup) == 2:
+            f, args = tup
+        else:
+            f, args, headers = tup[0], tup[1], [tup[2]]
+        if config.check_func(f, decl=False, call=True, call_args=args,
+                             headers=headers):
+            moredefs.append((fname2def(f), 1))
+
+    for dec, fn in OPTIONAL_FUNCTION_ATTRIBUTES:
+        if config.check_gcc_function_attribute(dec, fn):
+            moredefs.append((fname2def(fn), 1))
+
+    for fn in OPTIONAL_VARIABLE_ATTRIBUTES:
+        if config.check_gcc_variable_attribute(fn):
+            m = fn.replace("(", "_").replace(")", "_")
+            moredefs.append((fname2def(m), 1))
+
+    # C99 functions: float and long double versions
+    check_funcs(C99_FUNCS_SINGLE)
+    check_funcs(C99_FUNCS_EXTENDED)
+
+def check_complex(config, mathlibs):
+    priv = []
+    pub = []
+
+    try:
+        if os.uname()[0] == "Interix":
+            warnings.warn("Disabling broken complex support. See #1365")
+            return priv, pub
+    except:
+        # os.uname not available on all platforms. blanket except ugly but safe
+        pass
+
+    # Check for complex support
+    st = config.check_header('complex.h')
+    if st:
+        priv.append(('HAVE_COMPLEX_H', 1))
+        pub.append(('NPY_USE_C99_COMPLEX', 1))
+
+        for t in C99_COMPLEX_TYPES:
+            st = config.check_type(t, headers=["complex.h"])
+            if st:
+                pub.append(('NPY_HAVE_%s' % type2def(t), 1))
+
+        def check_prec(prec):
+            flist = [f + prec for f in C99_COMPLEX_FUNCS]
+            decl = dict([(f, True) for f in flist])
+            if not config.check_funcs_once(flist, call=decl, decl=decl,
+                                           libraries=mathlibs):
+                for f in flist:
+                    if config.check_func(f, call=True, decl=True,
+                                         libraries=mathlibs):
+                        priv.append((fname2def(f), 1))
+            else:
+                priv.extend([(fname2def(f), 1) for f in flist])
+
+        check_prec('')
+        check_prec('f')
+        check_prec('l')
+
+    return priv, pub
+
+def check_ieee_macros(config):
+    priv = []
+    pub = []
+
+    macros = []
+
+    def _add_decl(f):
+        priv.append(fname2def("decl_%s" % f))
+        pub.append('NPY_%s' % fname2def("decl_%s" % f))
+
+    # XXX: hack to circumvent cpp pollution from python: python put its
+    # config.h in the public namespace, so we have a clash for the common
+    # functions we test. We remove every function tested by python's
+    # autoconf, hoping their own test are correct
+    _macros = ["isnan", "isinf", "signbit", "isfinite"]
+    for f in _macros:
+        py_symbol = fname2def("decl_%s" % f)
+        already_declared = config.check_decl(py_symbol,
+                headers=["Python.h", "math.h"])
+        if already_declared:
+            if config.check_macro_true(py_symbol,
+                    headers=["Python.h", "math.h"]):
+                pub.append('NPY_%s' % fname2def("decl_%s" % f))
+        else:
+            macros.append(f)
+    # Normally, isnan and isinf are macro (C99), but some platforms only have
+    # func, or both func and macro version. Check for macro only, and define
+    # replacement ones if not found.
+    # Note: including Python.h is necessary because it modifies some math.h
+    # definitions
+    for f in macros:
+        st = config.check_decl(f, headers=["Python.h", "math.h"])
+        if st:
+            _add_decl(f)
+
+    return priv, pub
+
+def check_types(config_cmd, ext, build_dir):
+    private_defines = []
+    public_defines = []
+
+    # Expected size (in number of bytes) for each type. This is an
+    # optimization: those are only hints, and an exhaustive search for the size
+    # is done if the hints are wrong.
+    expected = {'short': [2], 'int': [4], 'long': [8, 4],
+                'float': [4], 'double': [8], 'long double': [16, 12, 8],
+                'Py_intptr_t': [8, 4], 'PY_LONG_LONG': [8], 'long long': [8],
+                'off_t': [8, 4]}
+
+    # Check we have the python header (-dev* packages on Linux)
+    result = config_cmd.check_header('Python.h')
+    if not result:
+        raise SystemError(
+                "Cannot compile 'Python.h'. Perhaps you need to "
+                "install python-dev|python-devel.")
+    res = config_cmd.check_header("endian.h")
+    if res:
+        private_defines.append(('HAVE_ENDIAN_H', 1))
+        public_defines.append(('NPY_HAVE_ENDIAN_H', 1))
+
+    # Check basic types sizes
+    for type in ('short', 'int', 'long'):
+        res = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), headers=["Python.h"])
+        if res:
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), "SIZEOF_%s" % sym2def(type)))
+        else:
+            res = config_cmd.check_type_size(type, expected=expected[type])
+            if res >= 0:
+                public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+            else:
+                raise SystemError("Checking sizeof (%s) failed !" % type)
+
+    for type in ('float', 'double', 'long double'):
+        already_declared = config_cmd.check_decl("SIZEOF_%s" % sym2def(type),
+                                                 headers=["Python.h"])
+        res = config_cmd.check_type_size(type, expected=expected[type])
+        if res >= 0:
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+            if not already_declared and not type == 'long double':
+                private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % type)
+
+        # Compute size of corresponding complex type: used to check that our
+        # definition is binary compatible with C99 complex type (check done at
+        # build time in npy_common.h)
+        complex_def = "struct {%s __x; %s __y;}" % (type, type)
+        res = config_cmd.check_type_size(complex_def,
+                                         expected=[2 * x for x in expected[type]])
+        if res >= 0:
+            public_defines.append(('NPY_SIZEOF_COMPLEX_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % complex_def)
+
+    for type in ('Py_intptr_t', 'off_t'):
+        res = config_cmd.check_type_size(type, headers=["Python.h"],
+                library_dirs=[pythonlib_dir()],
+                expected=expected[type])
+
+        if res >= 0:
+            private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % type)
+
+    # We check declaration AND type because that's how distutils does it.
+    if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']):
+        res = config_cmd.check_type_size('PY_LONG_LONG',  headers=['Python.h'],
+                library_dirs=[pythonlib_dir()],
+                expected=expected['PY_LONG_LONG'])
+        if res >= 0:
+            private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % 'PY_LONG_LONG')
+
+        res = config_cmd.check_type_size('long long',
+                expected=expected['long long'])
+        if res >= 0:
+            #private_defines.append(('SIZEOF_%s' % sym2def('long long'), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def('long long'), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % 'long long')
+
+    if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']):
+        raise RuntimeError(
+            "Config wo CHAR_BIT is not supported"
+            ", please contact the maintainers")
+
+    return private_defines, public_defines
+
+def check_mathlib(config_cmd):
+    # Testing the C math library
+    mathlibs = []
+    mathlibs_choices = [[], ['m'], ['cpml']]
+    mathlib = os.environ.get('MATHLIB')
+    if mathlib:
+        mathlibs_choices.insert(0, mathlib.split(','))
+    for libs in mathlibs_choices:
+        if config_cmd.check_func("exp", libraries=libs, decl=True, call=True):
+            mathlibs = libs
+            break
+    else:
+        raise EnvironmentError("math library missing; rerun "
+                               "setup.py after setting the "
+                               "MATHLIB env variable")
+    return mathlibs
+
+def visibility_define(config):
+    """Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty
+    string)."""
+    if config.check_compiler_gcc4():
+        return '__attribute__((visibility("hidden")))'
+    else:
+        return ''
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration, dot_join
+    from numpy.distutils.system_info import get_info
+
+    config = Configuration('core', parent_package, top_path)
+    local_dir = config.local_path
+    codegen_dir = join(local_dir, 'code_generators')
+
+    if is_released(config):
+        warnings.simplefilter('error', MismatchCAPIWarning)
+
+    # Check whether we have a mismatch between the set C API VERSION and the
+    # actual C API VERSION
+    check_api_version(C_API_VERSION, codegen_dir)
+
+    generate_umath_py = join(codegen_dir, 'generate_umath.py')
+    n = dot_join(config.name, 'generate_umath')
+    generate_umath = imp.load_module('_'.join(n.split('.')),
+                                     open(generate_umath_py, 'U'), generate_umath_py,
+                                     ('.py', 'U', 1))
+
+    header_dir = 'include/numpy'  # this is relative to config.path_in_package
+
+    cocache = CallOnceOnly()
+
+    def generate_config_h(ext, build_dir):
+        target = join(build_dir, header_dir, 'config.h')
+        d = os.path.dirname(target)
+        if not os.path.exists(d):
+            os.makedirs(d)
+
+        if newer(__file__, target):
+            config_cmd = config.get_config_cmd()
+            log.info('Generating %s', target)
+
+            # Check sizeof
+            moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir)
+
+            # Check math library and C99 math funcs availability
+            mathlibs = check_mathlib(config_cmd)
+            moredefs.append(('MATHLIB', ','.join(mathlibs)))
+
+            check_math_capabilities(config_cmd, moredefs, mathlibs)
+            moredefs.extend(cocache.check_ieee_macros(config_cmd)[0])
+            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0])
+
+            # Signal check
+            if is_npy_no_signal():
+                moredefs.append('__NPY_PRIVATE_NO_SIGNAL')
+
+            # Windows checks
+            if sys.platform == 'win32' or os.name == 'nt':
+                win32_checks(moredefs)
+
+            # C99 restrict keyword
+            moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict()))
+
+            # Inline check
+            inline = config_cmd.check_inline()
+
+            # Check whether we need our own wide character support
+            if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']):
+                PYTHON_HAS_UNICODE_WIDE = True
+            else:
+                PYTHON_HAS_UNICODE_WIDE = False
+
+            if NPY_RELAXED_STRIDES_CHECKING:
+                moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
+
+            # Get long double representation
+            if sys.platform != 'darwin':
+                rep = check_long_double_representation(config_cmd)
+                if rep in ['INTEL_EXTENDED_12_BYTES_LE',
+                           'INTEL_EXTENDED_16_BYTES_LE',
+                           'MOTOROLA_EXTENDED_12_BYTES_BE',
+                           'IEEE_QUAD_LE', 'IEEE_QUAD_BE',
+                           'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE',
+                           'DOUBLE_DOUBLE_BE', 'DOUBLE_DOUBLE_LE']:
+                    moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1))
+                else:
+                    raise ValueError("Unrecognized long double format: %s" % rep)
+
+            # Py3K check
+            if sys.version_info[0] == 3:
+                moredefs.append(('NPY_PY3K', 1))
+
+            # Generate the config.h file from moredefs
+            target_f = open(target, 'w')
+            for d in moredefs:
+                if isinstance(d, str):
+                    target_f.write('#define %s\n' % (d))
+                else:
+                    target_f.write('#define %s %s\n' % (d[0], d[1]))
+
+            # define inline to our keyword, or nothing
+            target_f.write('#ifndef __cplusplus\n')
+            if inline == 'inline':
+                target_f.write('/* #undef inline */\n')
+            else:
+                target_f.write('#define inline %s\n' % inline)
+            target_f.write('#endif\n')
+
+            # add the guard to make sure config.h is never included directly,
+            # but always through npy_config.h
+            target_f.write("""
+#ifndef _NPY_NPY_CONFIG_H_
+#error config.h should never be included directly, include npy_config.h instead
+#endif
+""")
+
+            target_f.close()
+            print('File:', target)
+            target_f = open(target)
+            print(target_f.read())
+            target_f.close()
+            print('EOF')
+        else:
+            mathlibs = []
+            target_f = open(target)
+            for line in target_f:
+                s = '#define MATHLIB'
+                if line.startswith(s):
+                    value = line[len(s):].strip()
+                    if value:
+                        mathlibs.extend(value.split(','))
+            target_f.close()
+
+        # Ugly: this can be called within a library and not an extension,
+        # in which case there is no libraries attributes (and none is
+        # needed).
+        if hasattr(ext, 'libraries'):
+            ext.libraries.extend(mathlibs)
+
+        incl_dir = os.path.dirname(target)
+        if incl_dir not in config.numpy_include_dirs:
+            config.numpy_include_dirs.append(incl_dir)
+
+        return target
+
+    def generate_numpyconfig_h(ext, build_dir):
+        """Depends on config.h: generate_config_h has to be called before !"""
+        # put private include directory in build_dir on search path
+        # allows using code generation in headers headers
+        config.add_include_dirs(join(build_dir, "src", "private"))
+
+        target = join(build_dir, header_dir, '_numpyconfig.h')
+        d = os.path.dirname(target)
+        if not os.path.exists(d):
+            os.makedirs(d)
+        if newer(__file__, target):
+            config_cmd = config.get_config_cmd()
+            log.info('Generating %s', target)
+
+            # Check sizeof
+            ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir)
+
+            if is_npy_no_signal():
+                moredefs.append(('NPY_NO_SIGNAL', 1))
+
+            if is_npy_no_smp():
+                moredefs.append(('NPY_NO_SMP', 1))
+            else:
+                moredefs.append(('NPY_NO_SMP', 0))
+
+            mathlibs = check_mathlib(config_cmd)
+            moredefs.extend(cocache.check_ieee_macros(config_cmd)[1])
+            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1])
+
+            if NPY_RELAXED_STRIDES_CHECKING:
+                moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
+
+            # Check wether we can use inttypes (C99) formats
+            if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']):
+                moredefs.append(('NPY_USE_C99_FORMATS', 1))
+
+            # visibility check
+            hidden_visibility = visibility_define(config_cmd)
+            moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility))
+
+            # Add the C API/ABI versions
+            moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION))
+            moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION))
+
+            # Add moredefs to header
+            target_f = open(target, 'w')
+            for d in moredefs:
+                if isinstance(d, str):
+                    target_f.write('#define %s\n' % (d))
+                else:
+                    target_f.write('#define %s %s\n' % (d[0], d[1]))
+
+            # Define __STDC_FORMAT_MACROS
+            target_f.write("""
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
+""")
+            target_f.close()
+
+            # Dump the numpyconfig.h header to stdout
+            print('File: %s' % target)
+            target_f = open(target)
+            print(target_f.read())
+            target_f.close()
+            print('EOF')
+        config.add_data_files((header_dir, target))
+        return target
+
+    def generate_api_func(module_name):
+        def generate_api(ext, build_dir):
+            script = join(codegen_dir, module_name + '.py')
+            sys.path.insert(0, codegen_dir)
+            try:
+                m = __import__(module_name)
+                log.info('executing %s', script)
+                h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir))
+            finally:
+                del sys.path[0]
+            config.add_data_files((header_dir, h_file),
+                                  (header_dir, doc_file))
+            return (h_file,)
+        return generate_api
+
+    generate_numpy_api = generate_api_func('generate_numpy_api')
+    generate_ufunc_api = generate_api_func('generate_ufunc_api')
+
+    config.add_include_dirs(join(local_dir, "src", "private"))
+    config.add_include_dirs(join(local_dir, "src"))
+    config.add_include_dirs(join(local_dir))
+
+    config.add_data_files('include/numpy/*.h')
+    config.add_include_dirs(join('src', 'npymath'))
+    config.add_include_dirs(join('src', 'multiarray'))
+    config.add_include_dirs(join('src', 'umath'))
+    config.add_include_dirs(join('src', 'npysort'))
+
+    config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")])
+    config.add_define_macros([("_FILE_OFFSET_BITS", "64")])
+    config.add_define_macros([('_LARGEFILE_SOURCE', '1')])
+    config.add_define_macros([('_LARGEFILE64_SOURCE', '1')])
+
+    config.numpy_include_dirs.extend(config.paths('include'))
+
+    deps = [join('src', 'npymath', '_signbit.c'),
+            join('include', 'numpy', '*object.h'),
+            join(codegen_dir, 'genapi.py'),
+            ]
+
+    #######################################################################
+    #                            dummy module                             #
+    #######################################################################
+
+    # npymath needs the config.h and numpyconfig.h files to be generated, but
+    # build_clib cannot handle generate_config_h and generate_numpyconfig_h
+    # (don't ask). Because clib are generated before extensions, we have to
+    # explicitly add an extension which has generate_config_h and
+    # generate_numpyconfig_h as sources *before* adding npymath.
+
+    config.add_extension('_dummy',
+                         sources=[join('src', 'dummymodule.c'),
+                                  generate_config_h,
+                                  generate_numpyconfig_h,
+                                  generate_numpy_api]
+                         )
+
+    #######################################################################
+    #                          npymath library                            #
+    #######################################################################
+
+    subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")])
+
+    def get_mathlib_info(*args):
+        # Another ugly hack: the mathlib info is known once build_src is run,
+        # but we cannot use add_installed_pkg_config here either, so we only
+        # update the substition dictionary during npymath build
+        config_cmd = config.get_config_cmd()
+
+        # Check that the toolchain works, to fail early if it doesn't
+        # (avoid late errors with MATHLIB which are confusing if the
+        # compiler does not work).
+        st = config_cmd.try_link('int main(void) { return 0;}')
+        if not st:
+            raise RuntimeError("Broken toolchain: cannot link a simple C program")
+        mlibs = check_mathlib(config_cmd)
+
+        posix_mlib = ' '.join(['-l%s' % l for l in mlibs])
+        msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs])
+        subst_dict["posix_mathlib"] = posix_mlib
+        subst_dict["msvc_mathlib"] = msvc_mlib
+
+    npymath_sources = [join('src', 'npymath', 'npy_math.c.src'),
+                       join('src', 'npymath', 'ieee754.c.src'),
+                       join('src', 'npymath', 'npy_math_complex.c.src'),
+                       join('src', 'npymath', 'halffloat.c')
+                       ]
+    config.add_installed_library('npymath',
+            sources=npymath_sources + [get_mathlib_info],
+            install_dir='lib')
+    config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config",
+            subst_dict)
+    config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config",
+            subst_dict)
+
+    #######################################################################
+    #                         npysort library                             #
+    #######################################################################
+
+    # This library is created for the build but it is not installed
+    npysort_sources = [join('src', 'npysort', 'quicksort.c.src'),
+                       join('src', 'npysort', 'mergesort.c.src'),
+                       join('src', 'npysort', 'heapsort.c.src'),
+                       join('src', 'private', 'npy_partition.h.src'),
+                       join('src', 'npysort', 'selection.c.src'),
+                       join('src', 'private', 'npy_binsearch.h.src'),
+                       join('src', 'npysort', 'binsearch.c.src'),
+                       ]
+    config.add_library('npysort',
+                       sources=npysort_sources,
+                       include_dirs=[])
+
+    #######################################################################
+    #                        multiarray module                            #
+    #######################################################################
+
+    # Multiarray version: this function is needed to build foo.c from foo.c.src
+    # when foo.c is included in another file and as such not in the src
+    # argument of build_ext command
+    def generate_multiarray_templated_sources(ext, build_dir):
+        from numpy.distutils.misc_util import get_cmd
+
+        subpath = join('src', 'multiarray')
+        sources = [join(local_dir, subpath, 'scalartypes.c.src'),
+                   join(local_dir, subpath, 'arraytypes.c.src'),
+                   join(local_dir, subpath, 'nditer_templ.c.src'),
+                   join(local_dir, subpath, 'lowlevel_strided_loops.c.src'),
+                   join(local_dir, subpath, 'einsum.c.src'),
+                   join(local_dir, 'src', 'private', 'templ_common.h.src')
+                   ]
+
+        # numpy.distutils generate .c from .c.src in weird directories, we have
+        # to add them there as they depend on the build_dir
+        config.add_include_dirs(join(build_dir, subpath))
+        cmd = get_cmd('build_src')
+        cmd.ensure_finalized()
+        cmd.template_sources(sources, ext)
+
+    multiarray_deps = [
+            join('src', 'multiarray', 'arrayobject.h'),
+            join('src', 'multiarray', 'arraytypes.h'),
+            join('src', 'multiarray', 'array_assign.h'),
+            join('src', 'multiarray', 'buffer.h'),
+            join('src', 'multiarray', 'calculation.h'),
+            join('src', 'multiarray', 'cblasfuncs.h'),
+            join('src', 'multiarray', 'common.h'),
+            join('src', 'multiarray', 'convert_datatype.h'),
+            join('src', 'multiarray', 'convert.h'),
+            join('src', 'multiarray', 'conversion_utils.h'),
+            join('src', 'multiarray', 'ctors.h'),
+            join('src', 'multiarray', 'descriptor.h'),
+            join('src', 'multiarray', 'getset.h'),
+            join('src', 'multiarray', 'hashdescr.h'),
+            join('src', 'multiarray', 'iterators.h'),
+            join('src', 'multiarray', 'mapping.h'),
+            join('src', 'multiarray', 'methods.h'),
+            join('src', 'multiarray', 'multiarraymodule.h'),
+            join('src', 'multiarray', 'nditer_impl.h'),
+            join('src', 'multiarray', 'numpymemoryview.h'),
+            join('src', 'multiarray', 'number.h'),
+            join('src', 'multiarray', 'numpyos.h'),
+            join('src', 'multiarray', 'refcount.h'),
+            join('src', 'multiarray', 'scalartypes.h'),
+            join('src', 'multiarray', 'sequence.h'),
+            join('src', 'multiarray', 'shape.h'),
+            join('src', 'multiarray', 'ucsnarrow.h'),
+            join('src', 'multiarray', 'usertypes.h'),
+            join('src', 'multiarray', 'vdot.h'),
+            join('src', 'private', 'npy_config.h'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'private', 'lowlevel_strided_loops.h'),
+            join('src', 'private', 'mem_overlap.h'),
+            join('src', 'private', 'npy_extint128.h'),
+            join('include', 'numpy', 'arrayobject.h'),
+            join('include', 'numpy', '_neighborhood_iterator_imp.h'),
+            join('include', 'numpy', 'npy_endian.h'),
+            join('include', 'numpy', 'arrayscalars.h'),
+            join('include', 'numpy', 'noprefix.h'),
+            join('include', 'numpy', 'npy_interrupt.h'),
+            join('include', 'numpy', 'npy_3kcompat.h'),
+            join('include', 'numpy', 'npy_math.h'),
+            join('include', 'numpy', 'halffloat.h'),
+            join('include', 'numpy', 'npy_common.h'),
+            join('include', 'numpy', 'npy_os.h'),
+            join('include', 'numpy', 'utils.h'),
+            join('include', 'numpy', 'ndarrayobject.h'),
+            join('include', 'numpy', 'npy_cpu.h'),
+            join('include', 'numpy', 'numpyconfig.h'),
+            join('include', 'numpy', 'ndarraytypes.h'),
+            join('include', 'numpy', 'npy_1_7_deprecated_api.h'),
+            join('include', 'numpy', '_numpyconfig.h.in'),
+            # add library sources as distuils does not consider libraries
+            # dependencies
+            ] + npysort_sources + npymath_sources
+
+    multiarray_src = [
+            join('src', 'multiarray', 'alloc.c'),
+            join('src', 'multiarray', 'arrayobject.c'),
+            join('src', 'multiarray', 'arraytypes.c.src'),
+            join('src', 'multiarray', 'array_assign.c'),
+            join('src', 'multiarray', 'array_assign_scalar.c'),
+            join('src', 'multiarray', 'array_assign_array.c'),
+            join('src', 'multiarray', 'buffer.c'),
+            join('src', 'multiarray', 'calculation.c'),
+            join('src', 'multiarray', 'compiled_base.c'),
+            join('src', 'multiarray', 'common.c'),
+            join('src', 'multiarray', 'convert.c'),
+            join('src', 'multiarray', 'convert_datatype.c'),
+            join('src', 'multiarray', 'conversion_utils.c'),
+            join('src', 'multiarray', 'ctors.c'),
+            join('src', 'multiarray', 'datetime.c'),
+            join('src', 'multiarray', 'datetime_strings.c'),
+            join('src', 'multiarray', 'datetime_busday.c'),
+            join('src', 'multiarray', 'datetime_busdaycal.c'),
+            join('src', 'multiarray', 'descriptor.c'),
+            join('src', 'multiarray', 'dtype_transfer.c'),
+            join('src', 'multiarray', 'einsum.c.src'),
+            join('src', 'multiarray', 'flagsobject.c'),
+            join('src', 'multiarray', 'getset.c'),
+            join('src', 'multiarray', 'hashdescr.c'),
+            join('src', 'multiarray', 'item_selection.c'),
+            join('src', 'multiarray', 'iterators.c'),
+            join('src', 'multiarray', 'lowlevel_strided_loops.c.src'),
+            join('src', 'multiarray', 'mapping.c'),
+            join('src', 'multiarray', 'methods.c'),
+            join('src', 'multiarray', 'multiarraymodule.c'),
+            join('src', 'multiarray', 'nditer_templ.c.src'),
+            join('src', 'multiarray', 'nditer_api.c'),
+            join('src', 'multiarray', 'nditer_constr.c'),
+            join('src', 'multiarray', 'nditer_pywrap.c'),
+            join('src', 'multiarray', 'number.c'),
+            join('src', 'multiarray', 'numpymemoryview.c'),
+            join('src', 'multiarray', 'numpyos.c'),
+            join('src', 'multiarray', 'refcount.c'),
+            join('src', 'multiarray', 'sequence.c'),
+            join('src', 'multiarray', 'shape.c'),
+            join('src', 'multiarray', 'scalarapi.c'),
+            join('src', 'multiarray', 'scalartypes.c.src'),
+            join('src', 'multiarray', 'usertypes.c'),
+            join('src', 'multiarray', 'ucsnarrow.c'),
+            join('src', 'multiarray', 'vdot.c'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'private', 'mem_overlap.c'),
+            ]
+
+    blas_info = get_info('blas_opt', 0)
+    if blas_info and ('HAVE_CBLAS', None) in blas_info.get('define_macros', []):
+        extra_info = blas_info
+        # These files are also in MANIFEST.in so that they are always in
+        # the source distribution independently of HAVE_CBLAS.
+        multiarray_src.extend([join('src', 'multiarray', 'cblasfuncs.c'),
+                               join('src', 'multiarray', 'python_xerbla.c'),
+                               ])
+        if uses_accelerate_framework(blas_info):
+            multiarray_src.extend(get_sgemv_fix())
+    else:
+        extra_info = {}
+
+    config.add_extension('multiarray',
+                         sources=multiarray_src +
+                                 [generate_config_h,
+                                  generate_numpyconfig_h,
+                                  generate_numpy_api,
+                                  join(codegen_dir, 'generate_numpy_api.py'),
+                                  join('*.py')],
+                         depends=deps + multiarray_deps,
+                         libraries=['npymath', 'npysort'],
+                         extra_info=extra_info)
+
+    #######################################################################
+    #                           umath module                              #
+    #######################################################################
+
+    # umath version: this function is needed to build foo.c from foo.c.src
+    # when foo.c is included in another file and as such not in the src
+    # argument of build_ext command
+    def generate_umath_templated_sources(ext, build_dir):
+        from numpy.distutils.misc_util import get_cmd
+
+        subpath = join('src', 'umath')
+        sources = [
+            join(local_dir, subpath, 'loops.h.src'),
+            join(local_dir, subpath, 'loops.c.src'),
+            join(local_dir, subpath, 'scalarmath.c.src'),
+            join(local_dir, subpath, 'simd.inc.src')]
+
+        # numpy.distutils generate .c from .c.src in weird directories, we have
+        # to add them there as they depend on the build_dir
+        config.add_include_dirs(join(build_dir, subpath))
+        cmd = get_cmd('build_src')
+        cmd.ensure_finalized()
+        cmd.template_sources(sources, ext)
+
+    def generate_umath_c(ext, build_dir):
+        target = join(build_dir, header_dir, '__umath_generated.c')
+        dir = os.path.dirname(target)
+        if not os.path.exists(dir):
+            os.makedirs(dir)
+        script = generate_umath_py
+        if newer(script, target):
+            f = open(target, 'w')
+            f.write(generate_umath.make_code(generate_umath.defdict,
+                                             generate_umath.__file__))
+            f.close()
+        return []
+
+    umath_src = [
+            join('src', 'umath', 'umathmodule.c'),
+            join('src', 'umath', 'reduction.c'),
+            join('src', 'umath', 'funcs.inc.src'),
+            join('src', 'umath', 'simd.inc.src'),
+            join('src', 'umath', 'loops.h.src'),
+            join('src', 'umath', 'loops.c.src'),
+            join('src', 'umath', 'ufunc_object.c'),
+            join('src', 'umath', 'scalarmath.c.src'),
+            join('src', 'umath', 'ufunc_type_resolution.c')]
+
+    umath_deps = [
+            generate_umath_py,
+            join('include', 'numpy', 'npy_math.h'),
+            join('include', 'numpy', 'halffloat.h'),
+            join('src', 'multiarray', 'common.h'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'umath', 'simd.inc.src'),
+            join(codegen_dir, 'generate_ufunc_api.py'),
+            join('src', 'private', 'ufunc_override.h')] + npymath_sources
+
+    config.add_extension('umath',
+                         sources=umath_src +
+                                 [generate_config_h,
+                                 generate_numpyconfig_h,
+                                 generate_umath_c,
+                                 generate_ufunc_api],
+                         depends=deps + umath_deps,
+                         libraries=['npymath'],
+                         )
+
+    #######################################################################
+    #                        umath_tests module                           #
+    #######################################################################
+
+    config.add_extension('umath_tests',
+                    sources=[join('src', 'umath', 'umath_tests.c.src')])
+
+    #######################################################################
+    #                   custom rational dtype module                      #
+    #######################################################################
+
+    config.add_extension('test_rational',
+                    sources=[join('src', 'umath', 'test_rational.c.src')])
+
+    #######################################################################
+    #                        struct_ufunc_test module                     #
+    #######################################################################
+
+    config.add_extension('struct_ufunc_test',
+                    sources=[join('src', 'umath', 'struct_ufunc_test.c.src')])
+
+    #######################################################################
+    #                     multiarray_tests module                         #
+    #######################################################################
+
+    config.add_extension('multiarray_tests',
+                    sources=[join('src', 'multiarray', 'multiarray_tests.c.src'),
+                             join('src', 'private', 'mem_overlap.c')],
+                    depends=[join('src', 'private', 'mem_overlap.h'),
+                             join('src', 'private', 'npy_extint128.h')])
+
+    #######################################################################
+    #                        operand_flag_tests module                    #
+    #######################################################################
+
+    config.add_extension('operand_flag_tests',
+                    sources=[join('src', 'umath', 'operand_flag_tests.c.src')])
+
+    config.add_data_dir('tests')
+    config.add_data_dir('tests/data')
+
+    config.make_svn_version_py()
+
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup_common.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup_common.py
new file mode 100644
index 0000000000..ba7521e304
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/setup_common.py
@@ -0,0 +1,356 @@
+from __future__ import division, absolute_import, print_function
+
+# Code common to build tools
+import sys
+import warnings
+import copy
+import binascii
+
+from numpy.distutils.misc_util import mingw32
+
+
+#-------------------
+# Versioning support
+#-------------------
+# How to change C_API_VERSION ?
+#   - increase C_API_VERSION value
+#   - record the hash for the new C API with the script cversions.py
+#   and add the hash to cversions.txt
+# The hash values are used to remind developers when the C API number was not
+# updated - generates a MismatchCAPIWarning warning which is turned into an
+# exception for released version.
+
+# Binary compatibility version number. This number is increased whenever the
+# C-API is changed such that binary compatibility is broken, i.e. whenever a
+# recompile of extension modules is needed.
+C_ABI_VERSION = 0x01000009
+
+# Minor API version.  This number is increased whenever a change is made to the
+# C-API -- whether it breaks binary compatibility or not.  Some changes, such
+# as adding a function pointer to the end of the function table, can be made
+# without breaking binary compatibility.  In this case, only the C_API_VERSION
+# (*not* C_ABI_VERSION) would be increased.  Whenever binary compatibility is
+# broken, both C_API_VERSION and C_ABI_VERSION should be increased.
+#
+# 0x00000008 - 1.7.x
+# 0x00000009 - 1.8.x
+# 0x00000009 - 1.9.x
+# 0x0000000a - 1.10.x
+# 0x0000000a - 1.11.x
+C_API_VERSION = 0x0000000a
+
+class MismatchCAPIWarning(Warning):
+    pass
+
+def is_released(config):
+    """Return True if a released version of numpy is detected."""
+    from distutils.version import LooseVersion
+
+    v = config.get_version('../version.py')
+    if v is None:
+        raise ValueError("Could not get version")
+    pv = LooseVersion(vstring=v).version
+    if len(pv) > 3:
+        return False
+    return True
+
+def get_api_versions(apiversion, codegen_dir):
+    """
+    Return current C API checksum and the recorded checksum.
+
+    Return current C API checksum and the recorded checksum for the given
+    version of the C API version.
+
+    """
+    # Compute the hash of the current API as defined in the .txt files in
+    # code_generators
+    sys.path.insert(0, codegen_dir)
+    try:
+        m = __import__('genapi')
+        numpy_api = __import__('numpy_api')
+        curapi_hash = m.fullapi_hash(numpy_api.full_api)
+        apis_hash = m.get_versions_hash()
+    finally:
+        del sys.path[0]
+
+    return curapi_hash, apis_hash[apiversion]
+
+def check_api_version(apiversion, codegen_dir):
+    """Emits a MismacthCAPIWarning if the C API version needs updating."""
+    curapi_hash, api_hash = get_api_versions(apiversion, codegen_dir)
+
+    # If different hash, it means that the api .txt files in
+    # codegen_dir have been updated without the API version being
+    # updated. Any modification in those .txt files should be reflected
+    # in the api and eventually abi versions.
+    # To compute the checksum of the current API, use
+    # code_generators/cversions.py script
+    if not curapi_hash == api_hash:
+        msg = ("API mismatch detected, the C API version "
+               "numbers have to be updated. Current C api version is %d, "
+               "with checksum %s, but recorded checksum for C API version %d in "
+               "codegen_dir/cversions.txt is %s. If functions were added in the "
+               "C API, you have to update C_API_VERSION  in %s."
+               )
+        warnings.warn(msg % (apiversion, curapi_hash, apiversion, api_hash,
+                             __file__),
+                      MismatchCAPIWarning)
+# Mandatory functions: if not found, fail the build
+MANDATORY_FUNCS = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
+        "floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
+        "acos", "atan", "fmod", 'modf', 'frexp', 'ldexp']
+
+# Standard functions which may not be available and for which we have a
+# replacement implementation. Note that some of these are C99 functions.
+OPTIONAL_STDFUNCS = ["expm1", "log1p", "acosh", "asinh", "atanh",
+        "rint", "trunc", "exp2", "log2", "hypot", "atan2", "pow",
+        "copysign", "nextafter", "ftello", "fseeko",
+        "strtoll", "strtoull", "cbrt", "strtold_l", "fallocate"]
+
+
+OPTIONAL_HEADERS = [
+# sse headers only enabled automatically on amd64/x32 builds
+                "xmmintrin.h",  # SSE
+                "emmintrin.h",  # SSE2
+                "features.h",  # for glibc version linux
+]
+
+# optional gcc compiler builtins and their call arguments and optional a
+# required header
+# call arguments are required as the compiler will do strict signature checking
+OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
+                       ("__builtin_isinf", '5.'),
+                       ("__builtin_isfinite", '5.'),
+                       ("__builtin_bswap32", '5u'),
+                       ("__builtin_bswap64", '5u'),
+                       ("__builtin_expect", '5, 0'),
+                       ("__builtin_mul_overflow", '5, 5, (int*)5'),
+                       ("_mm_load_ps", '(float*)0', "xmmintrin.h"),  # SSE
+                       ("_mm_prefetch", '(float*)0, _MM_HINT_NTA',
+                        "xmmintrin.h"),  # SSE
+                       ("_mm_load_pd", '(double*)0', "emmintrin.h"),  # SSE2
+                       ("__builtin_prefetch", "(float*)0, 0, 3"),
+                       ]
+
+# function attributes
+# tested via "int %s %s(void *);" % (attribute, name)
+# function name will be converted to HAVE_<upper-case-name> preprocessor macro
+OPTIONAL_FUNCTION_ATTRIBUTES = [('__attribute__((optimize("unroll-loops")))',
+                                'attribute_optimize_unroll_loops'),
+                                ('__attribute__((optimize("O3")))',
+                                 'attribute_optimize_opt_3'),
+                                ('__attribute__((nonnull (1)))',
+                                 'attribute_nonnull'),
+                                ]
+
+# variable attributes tested via "int %s a" % attribute
+OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"]
+
+# Subset of OPTIONAL_STDFUNCS which may alreay have HAVE_* defined by Python.h
+OPTIONAL_STDFUNCS_MAYBE = [
+    "expm1", "log1p", "acosh", "atanh", "asinh", "hypot", "copysign",
+    "ftello", "fseeko"
+    ]
+
+# C99 functions: float and long double versions
+C99_FUNCS = [
+    "sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor", "ceil",
+    "rint", "trunc", "sqrt", "log10", "log", "log1p", "exp", "expm1",
+    "asin", "acos", "atan", "asinh", "acosh", "atanh", "hypot", "atan2",
+    "pow", "fmod", "modf", 'frexp', 'ldexp', "exp2", "log2", "copysign",
+    "nextafter", "cbrt"
+    ]
+C99_FUNCS_SINGLE = [f + 'f' for f in C99_FUNCS]
+C99_FUNCS_EXTENDED = [f + 'l' for f in C99_FUNCS]
+C99_COMPLEX_TYPES = [
+    'complex double', 'complex float', 'complex long double'
+    ]
+C99_COMPLEX_FUNCS = [
+    "cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
+    "catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
+    "cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
+    ]
+
+def fname2def(name):
+    return "HAVE_%s" % name.upper()
+
+def sym2def(symbol):
+    define = symbol.replace(' ', '')
+    return define.upper()
+
+def type2def(symbol):
+    define = symbol.replace(' ', '_')
+    return define.upper()
+
+# Code to detect long double representation taken from MPFR m4 macro
+def check_long_double_representation(cmd):
+    cmd._check_compiler()
+    body = LONG_DOUBLE_REPRESENTATION_SRC % {'type': 'long double'}
+
+    # Disable whole program optimization (the default on vs2015, with python 3.5+)
+    # which generates intermediary object files and prevents checking the
+    # float representation.
+    if sys.platform == "win32" and not mingw32():
+        try:
+            cmd.compiler.compile_options.remove("/GL")
+        except (AttributeError, ValueError):
+            pass
+
+    # We need to use _compile because we need the object filename
+    src, obj = cmd._compile(body, None, None, 'c')
+    try:
+        ltype = long_double_representation(pyod(obj))
+        return ltype
+    except ValueError:
+        # try linking to support CC="gcc -flto" or icc -ipo
+        # struct needs to be volatile so it isn't optimized away
+        body = body.replace('struct', 'volatile struct')
+        body += "int main(void) { return 0; }\n"
+        src, obj = cmd._compile(body, None, None, 'c')
+        cmd.temp_files.append("_configtest")
+        cmd.compiler.link_executable([obj], "_configtest")
+        ltype = long_double_representation(pyod("_configtest"))
+        return ltype
+    finally:
+        cmd._clean()
+
+LONG_DOUBLE_REPRESENTATION_SRC = r"""
+/* "before" is 16 bytes to ensure there's no padding between it and "x".
+ *    We're not expecting any "long double" bigger than 16 bytes or with
+ *       alignment requirements stricter than 16 bytes.  */
+typedef %(type)s test_type;
+
+struct {
+        char         before[16];
+        test_type    x;
+        char         after[8];
+} foo = {
+        { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+          '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+        -123456789.0,
+        { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
+};
+"""
+
+def pyod(filename):
+    """Python implementation of the od UNIX utility (od -b, more exactly).
+
+    Parameters
+    ----------
+    filename : str
+        name of the file to get the dump from.
+
+    Returns
+    -------
+    out : seq
+        list of lines of od output
+
+    Note
+    ----
+    We only implement enough to get the necessary information for long double
+    representation, this is not intended as a compatible replacement for od.
+    """
+    def _pyod2():
+        out = []
+
+        fid = open(filename, 'rb')
+        try:
+            yo = [int(oct(int(binascii.b2a_hex(o), 16))) for o in fid.read()]
+            for i in range(0, len(yo), 16):
+                line = ['%07d' % int(oct(i))]
+                line.extend(['%03d' % c for c in yo[i:i+16]])
+                out.append(" ".join(line))
+            return out
+        finally:
+            fid.close()
+
+    def _pyod3():
+        out = []
+
+        fid = open(filename, 'rb')
+        try:
+            yo2 = [oct(o)[2:] for o in fid.read()]
+            for i in range(0, len(yo2), 16):
+                line = ['%07d' % int(oct(i)[2:])]
+                line.extend(['%03d' % int(c) for c in yo2[i:i+16]])
+                out.append(" ".join(line))
+            return out
+        finally:
+            fid.close()
+
+    if sys.version_info[0] < 3:
+        return _pyod2()
+    else:
+        return _pyod3()
+
+_BEFORE_SEQ = ['000', '000', '000', '000', '000', '000', '000', '000',
+              '001', '043', '105', '147', '211', '253', '315', '357']
+_AFTER_SEQ = ['376', '334', '272', '230', '166', '124', '062', '020']
+
+_IEEE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000']
+_IEEE_DOUBLE_LE = _IEEE_DOUBLE_BE[::-1]
+_INTEL_EXTENDED_12B = ['000', '000', '000', '000', '240', '242', '171', '353',
+                       '031', '300', '000', '000']
+_INTEL_EXTENDED_16B = ['000', '000', '000', '000', '240', '242', '171', '353',
+                       '031', '300', '000', '000', '000', '000', '000', '000']
+_MOTOROLA_EXTENDED_12B = ['300', '031', '000', '000', '353', '171',
+                          '242', '240', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_BE = ['300', '031', '326', '363', '105', '100', '000', '000',
+                      '000', '000', '000', '000', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_LE = _IEEE_QUAD_PREC_BE[::-1]
+_DOUBLE_DOUBLE_BE = (['301', '235', '157', '064', '124', '000', '000', '000'] +
+                     ['000'] * 8)
+_DOUBLE_DOUBLE_LE = (['000', '000', '000', '124', '064', '157', '235', '301'] +
+                     ['000'] * 8)
+
+def long_double_representation(lines):
+    """Given a binary dump as given by GNU od -b, look for long double
+    representation."""
+
+    # Read contains a list of 32 items, each item is a byte (in octal
+    # representation, as a string). We 'slide' over the output until read is of
+    # the form before_seq + content + after_sequence, where content is the long double
+    # representation:
+    #  - content is 12 bytes: 80 bits Intel representation
+    #  - content is 16 bytes: 80 bits Intel representation (64 bits) or quad precision
+    #  - content is 8 bytes: same as double (not implemented yet)
+    read = [''] * 32
+    saw = None
+    for line in lines:
+        # we skip the first word, as od -b output an index at the beginning of
+        # each line
+        for w in line.split()[1:]:
+            read.pop(0)
+            read.append(w)
+
+            # If the end of read is equal to the after_sequence, read contains
+            # the long double
+            if read[-8:] == _AFTER_SEQ:
+                saw = copy.copy(read)
+                if read[:12] == _BEFORE_SEQ[4:]:
+                    if read[12:-8] == _INTEL_EXTENDED_12B:
+                        return 'INTEL_EXTENDED_12_BYTES_LE'
+                    if read[12:-8] == _MOTOROLA_EXTENDED_12B:
+                        return 'MOTOROLA_EXTENDED_12_BYTES_BE'
+                elif read[:8] == _BEFORE_SEQ[8:]:
+                    if read[8:-8] == _INTEL_EXTENDED_16B:
+                        return 'INTEL_EXTENDED_16_BYTES_LE'
+                    elif read[8:-8] == _IEEE_QUAD_PREC_BE:
+                        return 'IEEE_QUAD_BE'
+                    elif read[8:-8] == _IEEE_QUAD_PREC_LE:
+                        return 'IEEE_QUAD_LE'
+                    elif read[8:-8] == _DOUBLE_DOUBLE_BE:
+                        return 'DOUBLE_DOUBLE_BE'
+                    elif read[8:-8] == _DOUBLE_DOUBLE_LE:
+                        return 'DOUBLE_DOUBLE_LE'
+                elif read[:16] == _BEFORE_SEQ:
+                    if read[16:-8] == _IEEE_DOUBLE_LE:
+                        return 'IEEE_DOUBLE_LE'
+                    elif read[16:-8] == _IEEE_DOUBLE_BE:
+                        return 'IEEE_DOUBLE_BE'
+
+    if saw is not None:
+        raise ValueError("Unrecognized format (%s)" % saw)
+    else:
+        # We never detected the after_sequence
+        raise ValueError("Could not lock sequences (%s)" % saw)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/shape_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/shape_base.py
new file mode 100644
index 0000000000..599b48d82b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/shape_base.py
@@ -0,0 +1,350 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack',
+           'stack']
+
+from . import numeric as _nx
+from .numeric import asanyarray, newaxis
+
+def atleast_1d(*arys):
+    """
+    Convert inputs to arrays with at least one dimension.
+
+    Scalar inputs are converted to 1-dimensional arrays, whilst
+    higher-dimensional inputs are preserved.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more input arrays.
+
+    Returns
+    -------
+    ret : ndarray
+        An array, or sequence of arrays, each with ``a.ndim >= 1``.
+        Copies are made only if necessary.
+
+    See Also
+    --------
+    atleast_2d, atleast_3d
+
+    Examples
+    --------
+    >>> np.atleast_1d(1.0)
+    array([ 1.])
+
+    >>> x = np.arange(9.0).reshape(3,3)
+    >>> np.atleast_1d(x)
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4.,  5.],
+           [ 6.,  7.,  8.]])
+    >>> np.atleast_1d(x) is x
+    True
+
+    >>> np.atleast_1d(1, [3, 4])
+    [array([1]), array([3, 4])]
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1)
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+def atleast_2d(*arys):
+    """
+    View inputs as arrays with at least two dimensions.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more array-like sequences.  Non-array inputs are converted
+        to arrays.  Arrays that already have two or more dimensions are
+        preserved.
+
+    Returns
+    -------
+    res, res2, ... : ndarray
+        An array, or tuple of arrays, each with ``a.ndim >= 2``.
+        Copies are avoided where possible, and views with two or more
+        dimensions are returned.
+
+    See Also
+    --------
+    atleast_1d, atleast_3d
+
+    Examples
+    --------
+    >>> np.atleast_2d(3.0)
+    array([[ 3.]])
+
+    >>> x = np.arange(3.0)
+    >>> np.atleast_2d(x)
+    array([[ 0.,  1.,  2.]])
+    >>> np.atleast_2d(x).base is x
+    True
+
+    >>> np.atleast_2d(1, [1, 2], [[1, 2]])
+    [array([[1]]), array([[1, 2]]), array([[1, 2]])]
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1, 1)
+        elif len(ary.shape) == 1:
+            result = ary[newaxis,:]
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+def atleast_3d(*arys):
+    """
+    View inputs as arrays with at least three dimensions.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more array-like sequences.  Non-array inputs are converted to
+        arrays.  Arrays that already have three or more dimensions are
+        preserved.
+
+    Returns
+    -------
+    res1, res2, ... : ndarray
+        An array, or tuple of arrays, each with ``a.ndim >= 3``.  Copies are
+        avoided where possible, and views with three or more dimensions are
+        returned.  For example, a 1-D array of shape ``(N,)`` becomes a view
+        of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a
+        view of shape ``(M, N, 1)``.
+
+    See Also
+    --------
+    atleast_1d, atleast_2d
+
+    Examples
+    --------
+    >>> np.atleast_3d(3.0)
+    array([[[ 3.]]])
+
+    >>> x = np.arange(3.0)
+    >>> np.atleast_3d(x).shape
+    (1, 3, 1)
+
+    >>> x = np.arange(12.0).reshape(4,3)
+    >>> np.atleast_3d(x).shape
+    (4, 3, 1)
+    >>> np.atleast_3d(x).base is x
+    True
+
+    >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]):
+    ...     print(arr, arr.shape)
+    ...
+    [[[1]
+      [2]]] (1, 2, 1)
+    [[[1]
+      [2]]] (1, 2, 1)
+    [[[1 2]]] (1, 1, 2)
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1, 1, 1)
+        elif len(ary.shape) == 1:
+            result = ary[newaxis,:, newaxis]
+        elif len(ary.shape) == 2:
+            result = ary[:,:, newaxis]
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+
+def vstack(tup):
+    """
+    Stack arrays in sequence vertically (row wise).
+
+    Take a sequence of arrays and stack them vertically to make a single
+    array. Rebuild arrays divided by `vsplit`.
+
+    Parameters
+    ----------
+    tup : sequence of ndarrays
+        Tuple containing arrays to be stacked. The arrays must have the same
+        shape along all but the first axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise).
+    dstack : Stack arrays in sequence depth wise (along third dimension).
+    concatenate : Join a sequence of arrays along an existing axis.
+    vsplit : Split array into a list of multiple sub-arrays vertically.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that
+    are at least 2-dimensional.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3])
+    >>> b = np.array([2, 3, 4])
+    >>> np.vstack((a,b))
+    array([[1, 2, 3],
+           [2, 3, 4]])
+
+    >>> a = np.array([[1], [2], [3]])
+    >>> b = np.array([[2], [3], [4]])
+    >>> np.vstack((a,b))
+    array([[1],
+           [2],
+           [3],
+           [2],
+           [3],
+           [4]])
+
+    """
+    return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
+
+def hstack(tup):
+    """
+    Stack arrays in sequence horizontally (column wise).
+
+    Take a sequence of arrays and stack them horizontally to make
+    a single array. Rebuild arrays divided by `hsplit`.
+
+    Parameters
+    ----------
+    tup : sequence of ndarrays
+        All arrays must have the same shape along all but the second axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    vstack : Stack arrays in sequence vertically (row wise).
+    dstack : Stack arrays in sequence depth wise (along third axis).
+    concatenate : Join a sequence of arrays along an existing axis.
+    hsplit : Split array along second axis.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=1)``
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.hstack((a,b))
+    array([1, 2, 3, 2, 3, 4])
+    >>> a = np.array([[1],[2],[3]])
+    >>> b = np.array([[2],[3],[4]])
+    >>> np.hstack((a,b))
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrs = [atleast_1d(_m) for _m in tup]
+    # As a special case, dimension 0 of 1-dimensional arrays is "horizontal"
+    if arrs[0].ndim == 1:
+        return _nx.concatenate(arrs, 0)
+    else:
+        return _nx.concatenate(arrs, 1)
+
+def stack(arrays, axis=0):
+    """
+    Join a sequence of arrays along a new axis.
+
+    The `axis` parameter specifies the index of the new axis in the dimensions
+    of the result. For example, if ``axis=0`` it will be the first dimension
+    and if ``axis=-1`` it will be the last dimension.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        Each array must have the same shape.
+    axis : int, optional
+        The axis in the result array along which the input arrays are stacked.
+
+    Returns
+    -------
+    stacked : ndarray
+        The stacked array has one more dimension than the input arrays.
+
+    See Also
+    --------
+    concatenate : Join a sequence of arrays along an existing axis.
+    split : Split array into a list of multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> arrays = [np.random.randn(3, 4) for _ in range(10)]
+    >>> np.stack(arrays, axis=0).shape
+    (10, 3, 4)
+
+    >>> np.stack(arrays, axis=1).shape
+    (3, 10, 4)
+
+    >>> np.stack(arrays, axis=2).shape
+    (3, 4, 10)
+
+    >>> a = np.array([1, 2, 3])
+    >>> b = np.array([2, 3, 4])
+    >>> np.stack((a, b))
+    array([[1, 2, 3],
+           [2, 3, 4]])
+
+    >>> np.stack((a, b), axis=-1)
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrays = [asanyarray(arr) for arr in arrays]
+    if not arrays:
+        raise ValueError('need at least one array to stack')
+
+    shapes = set(arr.shape for arr in arrays)
+    if len(shapes) != 1:
+        raise ValueError('all input arrays must have the same shape')
+
+    result_ndim = arrays[0].ndim + 1
+    if not -result_ndim <= axis < result_ndim:
+        msg = 'axis {0} out of bounds [-{1}, {1})'.format(axis, result_ndim)
+        raise IndexError(msg)
+    if axis < 0:
+        axis += result_ndim
+
+    sl = (slice(None),) * axis + (_nx.newaxis,)
+    expanded_arrays = [arr[sl] for arr in arrays]
+    return _nx.concatenate(expanded_arrays, axis=axis)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..bf73ece5b59adbc092edc190eb0b6c55d4faf1d0
GIT binary patch
literal 17920
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
b0|^5eko*D&pT&T~fX6@pB*HKXs2c(RT}s0M

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/test_rational.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/test_rational.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..a8d8eb3667a7695e5331d51860e7ec28dc81bf17
GIT binary patch
literal 86016
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
Z1~jR+0K#W6;4t7Z5CDlVi~`C+002;pD&hbD

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..7397c978297b3f64c7e6540b23f448f280e30bcc
GIT binary patch
literal 716
zcmZo*O3o|IEvVE>&M!*U%Pq|*$xJLNO049HFG@|$&nqq|DorloDrAJH;>t^b$QCkr
zGqi>>Cbb6@GHZA<dV97)6{M6@7Nl|&vV=0FS$H#eGqwj6vTArUhcepu`T2SM|Ns9#
znDAyON$L#oU}9i!2{M+p-EHo`e0p8g@15ojb5<8@_t|OgAgbvyGkT}F!xi0|Hv4y&
zJ0wgjwvyav?jW%`%=gd&bBEn34?|y0H+Ptk9GEzHrMbhFZ|^b;PntWd(b*d(c*@+N
z-hW2Kgwy5@()xE**v^_e99{7+Klq%vgP{b!xWOrNhdqraV);&+JIq{m?%v{4<_<e6
z?Ce&bFn37M-5lO{*xX_HxqFLW9X5A(vo48s`XO_Ny`T2BZa8G_5W8JE-0YCK!;O#Y
z?zkT`cbNY#K;QU)xr4!*vw0c&%^iGon>H%$Gk3VS^{mA7J?0LJV?Ld5TW9Vd`aZyV
z-E?z@4=Wn(s&<<@xL!SEUq8d#!9(`ZREy>24rg3L6EEyHcd*=<<)41e+#y^>rgPdA
zbBC!$c@LDXm^(z2N_#Pa_zi376Rwy$EL|MlD|pr1fkpDIq~#@Zhxbjh=YPFt?jTW}
zRUiD&+~M#^m8-WNn>%=~(d=LO)Z9TP+^kLbsky_7-#70rcw+9LpBl!T^TgaCk)va^
z{S$MCJyDu{?;o2x7?k|a4t{LzuvhwG#hQoa4h$fVoilfEUbEh(d7rsMW^PT=n?2?Z
zdw$$GXL8Wop{M0;(!+b^4w?@qaf!Y(cQ_f}bn4<qa|iDtGs8dc%^lv(|F-wgQ*(#Y
zMZ#6Z7tI|QSzfs9x@hhot$J<B@oVM|Uo%#Rv)?p#@ZHC-Hs+SO1N%Q#dC%MC4mTD!
zb=ci8chCqkj)=Q!?ogWY?D*At<_<sC&iV1>zPW=>_cKkU$L0<?vpXJq`D*S^lB5R!
Dg`qy%

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
new file mode 100644
index 0000000000000000000000000000000000000000..ca48ee85153645a7510e201d574e9b119c089dce
GIT binary patch
literal 8640
zcmWIc^bPQFRZy^1zyd-P^cB)Fb5a#j@>7cylJoP@@{4j6O7a!lJVSyNic1pnQWA?&
zP&7Juh6H#<U^mauOhI2EuQWF)wMZd9O(7|>q*$RKwMZc)u_RHUAhRMh2gN8b$Imgs
zGgtw;c?t$7=7Eh#tVk^eYs5jgMufQfx!^Dl<X^DYKt>g(mMG*VR)V};l9-vNkXlia
znpd2epNC?;v%jyet6zwM0whc{+;UPYGLv#r6+Ckj(^C~fiW2jR3-XIf6oM;@OHy++
z6+l6lSfY@UnwFWDnxc@Ir{GvzQk0*UpIfPrn3sYu4=h}eQCXasT&xgWT2PRanwy$e
zq7a-~l$lzrP-bGHUtnxztOI448|o;OnH%dD7@JzcSZ1br2=kot^GXtvOB6~nQWg9h
zgB=xulQUEEl2aA@)6z1NQ$aBj42{uZkV_OoQj;_C@^kXjD?yG1>r+rbm<J9h7mznH
zOEUBG6jJh&OTi9QHZ(8*8<1a;ky-=^mrQWdNdzg>Lx~yxAWwHsKTv$A2ZsbFd+G*<
z1iLr}>xVcx`M3tFE9fhPBqrs6{F_<?3Va1aOG`^#14~^4a};x695+uNS3gHzS6c=3
zk|ez}P!dyz$tfs+(o144*stJpjU<DE=?6_PSo4P=$UJy@MoJ)=d60aAX(%}HVG56m
zjE2By2#kinXb6mkz-R~zp%4HyCxbox{cIJ~ojm=(trpbwMp9;8Vo{|+38)o=XhY)k
zA-?vrf`x*<f`x8UW{E;lWeNUvF3bYF?PnteeFY=kl+0X6!!|KT0mZd2GmvSpd4{0&
z8nP&aZD_8buTY+uQj!5`OhSB|nTOx4VDpTyo2Ot5F_#oFz}Y_()Evj!UIX<PiZiRg
z?Z4uJ)a1;>97yLQu_!eWyDjec%mcOm^7B$5W~3M8mlh~!6r~oHW)`KUC}gKrmgg6x
zXrh`M;^yh<;}VR$zeR?BLqZ}0T*2|74)XzO`pZd7O3hJ7%P&$$%S_Dyb=C|~U4+UD
zaq|!Ig_vjP0+B*B57adR8JC+_0*Ym@p;n+&Sy_^*;Nl<Z1nNyfG=fO5`@r$5o&@46
zC@7$shv_~es5-0^*nJT5480&KP|d^cJ`-I~j#2RR3vqRK4T9(clVJB5gVLXRGFX7H
z`|!pR*nJT5OdTNx65~F{U}sNH1?P;!qQvBq)FOyR5E<g)85{tK4|gL|Jwr2e_oZYO
z7vv;@yJ(;&0qMbq!RA52&(jc+642a7qIrIyK0aXc;I`@-8Jd`zSQwj`fXai?JXlw^
zEHS4v6_j)olJj#)bMxRDkQre2LBh|`6e2;9`#d~@L;Qmx6`YGw6H8K46x@n36%5U+
zj7+Tz%oU7`biGRRbd3xQARz&<4=*{|f5RI*qmrW`Fd71*AwYBpIEbWyKso~hgKc6`
za!RU$$Qckg%fP^3mzJK9ndKmA3<4$$3=H<!pb=t*Q7{?;qaiRF0;3@?8UmvsFd71*
LAut*OBQ*p7Ng>cF

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_abc.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
new file mode 100644
index 0000000000..2430866fdf
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
@@ -0,0 +1,47 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import TestCase, assert_, run_module_suite
+
+import numbers
+from numpy.core.numerictypes import sctypes
+
+class ABC(TestCase):
+    def test_floats(self):
+        for t in sctypes['float']:
+            assert_(isinstance(t(), numbers.Real), 
+                    "{0} is not instance of Real".format(t.__name__))
+            assert_(issubclass(t, numbers.Real),
+                    "{0} is not subclass of Real".format(t.__name__))
+            assert_(not isinstance(t(), numbers.Rational), 
+                    "{0} is instance of Rational".format(t.__name__))
+            assert_(not issubclass(t, numbers.Rational),
+                    "{0} is subclass of Rational".format(t.__name__))
+
+    def test_complex(self):
+        for t in sctypes['complex']:
+            assert_(isinstance(t(), numbers.Complex), 
+                    "{0} is not instance of Complex".format(t.__name__))
+            assert_(issubclass(t, numbers.Complex),
+                    "{0} is not subclass of Complex".format(t.__name__))
+            assert_(not isinstance(t(), numbers.Real), 
+                    "{0} is instance of Real".format(t.__name__))
+            assert_(not issubclass(t, numbers.Real),
+                    "{0} is subclass of Real".format(t.__name__))
+
+    def test_int(self):
+        for t in sctypes['int']:
+            assert_(isinstance(t(), numbers.Integral), 
+                    "{0} is not instance of Integral".format(t.__name__))
+            assert_(issubclass(t, numbers.Integral),
+                    "{0} is not subclass of Integral".format(t.__name__))
+
+    def test_uint(self):
+        for t in sctypes['uint']:
+            assert_(isinstance(t(), numbers.Integral), 
+                    "{0} is not instance of Integral".format(t.__name__))
+            assert_(issubclass(t, numbers.Integral),
+                    "{0} is not subclass of Integral".format(t.__name__))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_api.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_api.py
new file mode 100644
index 0000000000..876cab4d7b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_api.py
@@ -0,0 +1,515 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import sixu
+from numpy.testing import (
+     run_module_suite, assert_, assert_equal, assert_array_equal,
+     assert_raises
+)
+
+# Switch between new behaviour when NPY_RELAXED_STRIDES_CHECKING is set.
+NPY_RELAXED_STRIDES_CHECKING = np.ones((10, 1), order='C').flags.f_contiguous
+
+
+def test_array_array():
+    tobj = type(object)
+    ones11 = np.ones((1, 1), np.float64)
+    tndarray = type(ones11)
+    # Test is_ndarray
+    assert_equal(np.array(ones11, dtype=np.float64), ones11)
+    old_refcount = sys.getrefcount(tndarray)
+    np.array(ones11)
+    assert_equal(old_refcount, sys.getrefcount(tndarray))
+
+    # test None
+    assert_equal(np.array(None, dtype=np.float64),
+                 np.array(np.nan, dtype=np.float64))
+    old_refcount = sys.getrefcount(tobj)
+    np.array(None, dtype=np.float64)
+    assert_equal(old_refcount, sys.getrefcount(tobj))
+
+    # test scalar
+    assert_equal(np.array(1.0, dtype=np.float64),
+                 np.ones((), dtype=np.float64))
+    old_refcount = sys.getrefcount(np.float64)
+    np.array(np.array(1.0, dtype=np.float64), dtype=np.float64)
+    assert_equal(old_refcount, sys.getrefcount(np.float64))
+
+    # test string
+    S2 = np.dtype((str, 2))
+    S3 = np.dtype((str, 3))
+    S5 = np.dtype((str, 5))
+    assert_equal(np.array("1.0", dtype=np.float64),
+                 np.ones((), dtype=np.float64))
+    assert_equal(np.array("1.0").dtype, S3)
+    assert_equal(np.array("1.0", dtype=str).dtype, S3)
+    assert_equal(np.array("1.0", dtype=S2), np.array("1."))
+    assert_equal(np.array("1", dtype=S5), np.ones((), dtype=S5))
+
+    # test unicode
+    _unicode = globals().get("unicode")
+    if _unicode:
+        U2 = np.dtype((_unicode, 2))
+        U3 = np.dtype((_unicode, 3))
+        U5 = np.dtype((_unicode, 5))
+        assert_equal(np.array(_unicode("1.0"), dtype=np.float64),
+                     np.ones((), dtype=np.float64))
+        assert_equal(np.array(_unicode("1.0")).dtype, U3)
+        assert_equal(np.array(_unicode("1.0"), dtype=_unicode).dtype, U3)
+        assert_equal(np.array(_unicode("1.0"), dtype=U2),
+                     np.array(_unicode("1.")))
+        assert_equal(np.array(_unicode("1"), dtype=U5),
+                     np.ones((), dtype=U5))
+
+    builtins = getattr(__builtins__, '__dict__', __builtins__)
+    assert_(isinstance(builtins, dict))
+
+    # test buffer
+    _buffer = builtins.get("buffer")
+    if _buffer and sys.version_info[:3] >= (2, 7, 5):
+        # This test fails for earlier versions of Python.
+        # Evidently a bug got fixed in 2.7.5.
+        dat = np.array(_buffer('1.0'), dtype=np.float64)
+        assert_equal(dat, [49.0, 46.0, 48.0])
+        assert_(dat.dtype.type is np.float64)
+
+        dat = np.array(_buffer(b'1.0'))
+        assert_equal(dat, [49, 46, 48])
+        assert_(dat.dtype.type is np.uint8)
+
+    # test memoryview, new version of buffer
+    _memoryview = builtins.get("memoryview")
+    if _memoryview:
+        dat = np.array(_memoryview(b'1.0'), dtype=np.float64)
+        assert_equal(dat, [49.0, 46.0, 48.0])
+        assert_(dat.dtype.type is np.float64)
+
+        dat = np.array(_memoryview(b'1.0'))
+        assert_equal(dat, [49, 46, 48])
+        assert_(dat.dtype.type is np.uint8)
+
+    # test array interface
+    a = np.array(100.0, dtype=np.float64)
+    o = type("o", (object,),
+             dict(__array_interface__=a.__array_interface__))
+    assert_equal(np.array(o, dtype=np.float64), a)
+
+    # test array_struct interface
+    a = np.array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
+                 dtype=[('f0', int), ('f1', float), ('f2', str)])
+    o = type("o", (object,),
+             dict(__array_struct__=a.__array_struct__))
+    ## wasn't what I expected... is np.array(o) supposed to equal a ?
+    ## instead we get a array([...], dtype=">V18")
+    assert_equal(str(np.array(o).data), str(a.data))
+
+    # test array
+    o = type("o", (object,),
+             dict(__array__=lambda *x: np.array(100.0, dtype=np.float64)))()
+    assert_equal(np.array(o, dtype=np.float64), np.array(100.0, np.float64))
+
+    # test recursion
+    nested = 1.5
+    for i in range(np.MAXDIMS):
+        nested = [nested]
+
+    # no error
+    np.array(nested)
+
+    # Exceeds recursion limit
+    assert_raises(ValueError, np.array, [nested], dtype=np.float64)
+
+    # Try with lists...
+    assert_equal(np.array([None] * 10, dtype=np.float64),
+                 np.full((10,), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None]] * 10, dtype=np.float64),
+                 np.full((10, 1), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None] * 10], dtype=np.float64),
+                 np.full((1, 10), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None] * 10] * 10, dtype=np.float64),
+                 np.full((10, 10), np.nan, dtype=np.float64))
+
+    assert_equal(np.array([1.0] * 10, dtype=np.float64),
+                 np.ones((10,), dtype=np.float64))
+    assert_equal(np.array([[1.0]] * 10, dtype=np.float64),
+                 np.ones((10, 1), dtype=np.float64))
+    assert_equal(np.array([[1.0] * 10], dtype=np.float64),
+                 np.ones((1, 10), dtype=np.float64))
+    assert_equal(np.array([[1.0] * 10] * 10, dtype=np.float64),
+                 np.ones((10, 10), dtype=np.float64))
+
+    # Try with tuples
+    assert_equal(np.array((None,) * 10, dtype=np.float64),
+                 np.full((10,), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,)] * 10, dtype=np.float64),
+                 np.full((10, 1), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,) * 10], dtype=np.float64),
+                 np.full((1, 10), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,) * 10] * 10, dtype=np.float64),
+                 np.full((10, 10), np.nan, dtype=np.float64))
+
+    assert_equal(np.array((1.0,) * 10, dtype=np.float64),
+                 np.ones((10,), dtype=np.float64))
+    assert_equal(np.array([(1.0,)] * 10, dtype=np.float64),
+                 np.ones((10, 1), dtype=np.float64))
+    assert_equal(np.array([(1.0,) * 10], dtype=np.float64),
+                 np.ones((1, 10), dtype=np.float64))
+    assert_equal(np.array([(1.0,) * 10] * 10, dtype=np.float64),
+                 np.ones((10, 10), dtype=np.float64))
+
+
+def test_fastCopyAndTranspose():
+    # 0D array
+    a = np.array(2)
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+    # 1D array
+    a = np.array([3, 2, 7, 0])
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+    # 2D array
+    a = np.arange(6).reshape(2, 3)
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+def test_array_astype():
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+    # Default behavior: allows unsafe casts, keeps memory layout,
+    #                   always copies.
+    b = a.astype('i4')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('i4'))
+    assert_equal(a.strides, b.strides)
+    b = a.T.astype('i4')
+    assert_equal(a.T, b)
+    assert_equal(b.dtype, np.dtype('i4'))
+    assert_equal(a.T.strides, b.strides)
+    b = a.astype('f4')
+    assert_equal(a, b)
+    assert_(not (a is b))
+
+    # copy=False parameter can sometimes skip a copy
+    b = a.astype('f4', copy=False)
+    assert_(a is b)
+
+    # order parameter allows overriding of the memory layout,
+    # forcing a copy if the layout is wrong
+    b = a.astype('f4', order='F', copy=False)
+    assert_equal(a, b)
+    assert_(not (a is b))
+    assert_(b.flags.f_contiguous)
+
+    b = a.astype('f4', order='C', copy=False)
+    assert_equal(a, b)
+    assert_(a is b)
+    assert_(b.flags.c_contiguous)
+
+    # casting parameter allows catching bad casts
+    b = a.astype('c8', casting='safe')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('c8'))
+
+    assert_raises(TypeError, a.astype, 'i4', casting='safe')
+
+    # subok=False passes through a non-subclassed array
+    b = a.astype('f4', subok=0, copy=False)
+    assert_(a is b)
+
+    a = np.matrix([[0, 1, 2], [3, 4, 5]], dtype='f4')
+
+    # subok=True passes through a matrix
+    b = a.astype('f4', subok=True, copy=False)
+    assert_(a is b)
+
+    # subok=True is default, and creates a subtype on a cast
+    b = a.astype('i4', copy=False)
+    assert_equal(a, b)
+    assert_equal(type(b), np.matrix)
+
+    # subok=False never returns a matrix
+    b = a.astype('f4', subok=False, copy=False)
+    assert_equal(a, b)
+    assert_(not (a is b))
+    assert_(type(b) is not np.matrix)
+
+    # Make sure converting from string object to fixed length string
+    # does not truncate.
+    a = np.array([b'a'*100], dtype='O')
+    b = a.astype('S')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('S100'))
+    a = np.array([sixu('a')*100], dtype='O')
+    b = a.astype('U')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('U100'))
+
+    # Same test as above but for strings shorter than 64 characters
+    a = np.array([b'a'*10], dtype='O')
+    b = a.astype('S')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('S10'))
+    a = np.array([sixu('a')*10], dtype='O')
+    b = a.astype('U')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('U10'))
+
+    a = np.array(123456789012345678901234567890, dtype='O').astype('S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array(123456789012345678901234567890, dtype='O').astype('U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array([123456789012345678901234567890], dtype='O').astype('S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array([123456789012345678901234567890], dtype='O').astype('U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array(123456789012345678901234567890, dtype='S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array(123456789012345678901234567890, dtype='U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array(sixu('a\u0140'), dtype='U')
+    b = np.ndarray(buffer=a, dtype='uint32', shape=2)
+    assert_(b.size == 2)
+
+    a = np.array([1000], dtype='i4')
+    assert_raises(TypeError, a.astype, 'S1', casting='safe')
+
+    a = np.array(1000, dtype='i4')
+    assert_raises(TypeError, a.astype, 'U1', casting='safe')
+
+def test_copyto_fromscalar():
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+
+    # Simple copy
+    np.copyto(a, 1.5)
+    assert_equal(a, 1.5)
+    np.copyto(a.T, 2.5)
+    assert_equal(a, 2.5)
+
+    # Where-masked copy
+    mask = np.array([[0, 1, 0], [0, 0, 1]], dtype='?')
+    np.copyto(a, 3.5, where=mask)
+    assert_equal(a, [[2.5, 3.5, 2.5], [2.5, 2.5, 3.5]])
+    mask = np.array([[0, 1], [1, 1], [1, 0]], dtype='?')
+    np.copyto(a.T, 4.5, where=mask)
+    assert_equal(a, [[2.5, 4.5, 4.5], [4.5, 4.5, 3.5]])
+
+def test_copyto():
+    a = np.arange(6, dtype='i4').reshape(2, 3)
+
+    # Simple copy
+    np.copyto(a, [[3, 1, 5], [6, 2, 1]])
+    assert_equal(a, [[3, 1, 5], [6, 2, 1]])
+
+    # Overlapping copy should work
+    np.copyto(a[:, :2], a[::-1, 1::-1])
+    assert_equal(a, [[2, 6, 5], [1, 3, 1]])
+
+    # Defaults to 'same_kind' casting
+    assert_raises(TypeError, np.copyto, a, 1.5)
+
+    # Force a copy with 'unsafe' casting, truncating 1.5 to 1
+    np.copyto(a, 1.5, casting='unsafe')
+    assert_equal(a, 1)
+
+    # Copying with a mask
+    np.copyto(a, 3, where=[True, False, True])
+    assert_equal(a, [[3, 1, 3], [3, 1, 3]])
+
+    # Casting rule still applies with a mask
+    assert_raises(TypeError, np.copyto, a, 3.5, where=[True, False, True])
+
+    # Lists of integer 0's and 1's is ok too
+    np.copyto(a, 4.0, casting='unsafe', where=[[0, 1, 1], [1, 0, 0]])
+    assert_equal(a, [[3, 4, 4], [4, 1, 3]])
+
+    # Overlapping copy with mask should work
+    np.copyto(a[:, :2], a[::-1, 1::-1], where=[[0, 1], [1, 1]])
+    assert_equal(a, [[3, 4, 4], [4, 3, 3]])
+
+    # 'dst' must be an array
+    assert_raises(TypeError, np.copyto, [1, 2, 3], [2, 3, 4])
+
+def test_copyto_permut():
+    # test explicit overflow case
+    pad = 500
+    l = [True] * pad + [True, True, True, True]
+    r = np.zeros(len(l)-pad)
+    d = np.ones(len(l)-pad)
+    mask = np.array(l)[pad:]
+    np.copyto(r, d, where=mask[::-1])
+
+    # test all permutation of possible masks, 9 should be sufficient for
+    # current 4 byte unrolled code
+    power = 9
+    d = np.ones(power)
+    for i in range(2**power):
+        r = np.zeros(power)
+        l = [(i & x) != 0 for x in range(power)]
+        mask = np.array(l)
+        np.copyto(r, d, where=mask)
+        assert_array_equal(r == 1, l)
+        assert_equal(r.sum(), sum(l))
+
+        r = np.zeros(power)
+        np.copyto(r, d, where=mask[::-1])
+        assert_array_equal(r == 1, l[::-1])
+        assert_equal(r.sum(), sum(l))
+
+        r = np.zeros(power)
+        np.copyto(r[::2], d[::2], where=mask[::2])
+        assert_array_equal(r[::2] == 1, l[::2])
+        assert_equal(r[::2].sum(), sum(l[::2]))
+
+        r = np.zeros(power)
+        np.copyto(r[::2], d[::2], where=mask[::-2])
+        assert_array_equal(r[::2] == 1, l[::-2])
+        assert_equal(r[::2].sum(), sum(l[::-2]))
+
+        for c in [0xFF, 0x7F, 0x02, 0x10]:
+            r = np.zeros(power)
+            mask = np.array(l)
+            imask = np.array(l).view(np.uint8)
+            imask[mask != 0] = c
+            np.copyto(r, d, where=mask)
+            assert_array_equal(r == 1, l)
+            assert_equal(r.sum(), sum(l))
+
+    r = np.zeros(power)
+    np.copyto(r, d, where=True)
+    assert_equal(r.sum(), r.size)
+    r = np.ones(power)
+    d = np.zeros(power)
+    np.copyto(r, d, where=False)
+    assert_equal(r.sum(), r.size)
+
+def test_copy_order():
+    a = np.arange(24).reshape(2, 1, 3, 4)
+    b = a.copy(order='F')
+    c = np.arange(24).reshape(2, 1, 4, 3).swapaxes(2, 3)
+
+    def check_copy_result(x, y, ccontig, fcontig, strides=False):
+        assert_(not (x is y))
+        assert_equal(x, y)
+        assert_equal(res.flags.c_contiguous, ccontig)
+        assert_equal(res.flags.f_contiguous, fcontig)
+        # This check is impossible only because
+        # NPY_RELAXED_STRIDES_CHECKING changes the strides actively
+        if not NPY_RELAXED_STRIDES_CHECKING:
+            if strides:
+                assert_equal(x.strides, y.strides)
+            else:
+                assert_(x.strides != y.strides)
+
+    # Validate the initial state of a, b, and c
+    assert_(a.flags.c_contiguous)
+    assert_(not a.flags.f_contiguous)
+    assert_(not b.flags.c_contiguous)
+    assert_(b.flags.f_contiguous)
+    assert_(not c.flags.c_contiguous)
+    assert_(not c.flags.f_contiguous)
+
+    # Copy with order='C'
+    res = a.copy(order='C')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = b.copy(order='C')
+    check_copy_result(res, b, ccontig=True, fcontig=False, strides=False)
+    res = c.copy(order='C')
+    check_copy_result(res, c, ccontig=True, fcontig=False, strides=False)
+    res = np.copy(a, order='C')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = np.copy(b, order='C')
+    check_copy_result(res, b, ccontig=True, fcontig=False, strides=False)
+    res = np.copy(c, order='C')
+    check_copy_result(res, c, ccontig=True, fcontig=False, strides=False)
+
+    # Copy with order='F'
+    res = a.copy(order='F')
+    check_copy_result(res, a, ccontig=False, fcontig=True, strides=False)
+    res = b.copy(order='F')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = c.copy(order='F')
+    check_copy_result(res, c, ccontig=False, fcontig=True, strides=False)
+    res = np.copy(a, order='F')
+    check_copy_result(res, a, ccontig=False, fcontig=True, strides=False)
+    res = np.copy(b, order='F')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = np.copy(c, order='F')
+    check_copy_result(res, c, ccontig=False, fcontig=True, strides=False)
+
+    # Copy with order='K'
+    res = a.copy(order='K')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = b.copy(order='K')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = c.copy(order='K')
+    check_copy_result(res, c, ccontig=False, fcontig=False, strides=True)
+    res = np.copy(a, order='K')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = np.copy(b, order='K')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = np.copy(c, order='K')
+    check_copy_result(res, c, ccontig=False, fcontig=False, strides=True)
+
+def test_contiguous_flags():
+    a = np.ones((4, 4, 1))[::2,:,:]
+    if NPY_RELAXED_STRIDES_CHECKING:
+        a.strides = a.strides[:2] + (-123,)
+    b = np.ones((2, 2, 1, 2, 2)).swapaxes(3, 4)
+
+    def check_contig(a, ccontig, fcontig):
+        assert_(a.flags.c_contiguous == ccontig)
+        assert_(a.flags.f_contiguous == fcontig)
+
+    # Check if new arrays are correct:
+    check_contig(a, False, False)
+    check_contig(b, False, False)
+    if NPY_RELAXED_STRIDES_CHECKING:
+        check_contig(np.empty((2, 2, 0, 2, 2)), True, True)
+        check_contig(np.array([[[1], [2]]], order='F'), True, True)
+    else:
+        check_contig(np.empty((2, 2, 0, 2, 2)), True, False)
+        check_contig(np.array([[[1], [2]]], order='F'), False, True)
+    check_contig(np.empty((2, 2)), True, False)
+    check_contig(np.empty((2, 2), order='F'), False, True)
+
+    # Check that np.array creates correct contiguous flags:
+    check_contig(np.array(a, copy=False), False, False)
+    check_contig(np.array(a, copy=False, order='C'), True, False)
+    check_contig(np.array(a, ndmin=4, copy=False, order='F'), False, True)
+
+    if NPY_RELAXED_STRIDES_CHECKING:
+        # Check slicing update of flags and :
+        check_contig(a[0], True, True)
+        check_contig(a[None, ::4, ..., None], True, True)
+        check_contig(b[0, 0, ...], False, True)
+        check_contig(b[:,:, 0:0,:,:], True, True)
+    else:
+        # Check slicing update of flags:
+        check_contig(a[0], True, False)
+        # Would be nice if this was C-Contiguous:
+        check_contig(a[None, 0, ..., None], False, False)
+        check_contig(b[0, 0, 0, ...], False, True)
+
+    # Test ravel and squeeze.
+    check_contig(a.ravel(), True, True)
+    check_contig(np.ones((1, 3, 1)).squeeze(), True, True)
+
+def test_broadcast_arrays():
+    # Test user defined dtypes
+    a = np.array([(1, 2, 3)], dtype='u4,u4,u4')
+    b = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4')
+    result = np.broadcast_arrays(a, b)
+    assert_equal(result[0], np.array([(1, 2, 3), (1, 2, 3), (1, 2, 3)], dtype='u4,u4,u4'))
+    assert_equal(result[1], np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4'))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
new file mode 100644
index 0000000000..f89f4b291a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import sixu
+from numpy.testing import (
+     TestCase, run_module_suite, assert_, assert_equal
+)
+
+class TestArrayRepr(object):
+    def test_nan_inf(self):
+        x = np.array([np.nan, np.inf])
+        assert_equal(repr(x), 'array([ nan,  inf])')
+
+class TestComplexArray(TestCase):
+    def test_str(self):
+        rvals = [0, 1, -1, np.inf, -np.inf, np.nan]
+        cvals = [complex(rp, ip) for rp in rvals for ip in rvals]
+        dtypes = [np.complex64, np.cdouble, np.clongdouble]
+        actual = [str(np.array([c], dt)) for c in cvals for dt in dtypes]
+        wanted = [
+            '[ 0.+0.j]',    '[ 0.+0.j]',    '[ 0.0+0.0j]',
+            '[ 0.+1.j]',    '[ 0.+1.j]',    '[ 0.0+1.0j]',
+            '[ 0.-1.j]',    '[ 0.-1.j]',    '[ 0.0-1.0j]',
+            '[ 0.+infj]',   '[ 0.+infj]',   '[ 0.0+infj]',
+            '[ 0.-infj]',   '[ 0.-infj]',   '[ 0.0-infj]',
+            '[ 0.+nanj]',   '[ 0.+nanj]',   '[ 0.0+nanj]',
+            '[ 1.+0.j]',    '[ 1.+0.j]',    '[ 1.0+0.0j]',
+            '[ 1.+1.j]',    '[ 1.+1.j]',    '[ 1.0+1.0j]',
+            '[ 1.-1.j]',    '[ 1.-1.j]',    '[ 1.0-1.0j]',
+            '[ 1.+infj]',   '[ 1.+infj]',   '[ 1.0+infj]',
+            '[ 1.-infj]',   '[ 1.-infj]',   '[ 1.0-infj]',
+            '[ 1.+nanj]',   '[ 1.+nanj]',   '[ 1.0+nanj]',
+            '[-1.+0.j]',    '[-1.+0.j]',    '[-1.0+0.0j]',
+            '[-1.+1.j]',    '[-1.+1.j]',    '[-1.0+1.0j]',
+            '[-1.-1.j]',    '[-1.-1.j]',    '[-1.0-1.0j]',
+            '[-1.+infj]',   '[-1.+infj]',   '[-1.0+infj]',
+            '[-1.-infj]',   '[-1.-infj]',   '[-1.0-infj]',
+            '[-1.+nanj]',   '[-1.+nanj]',   '[-1.0+nanj]',
+            '[ inf+0.j]',   '[ inf+0.j]',   '[ inf+0.0j]',
+            '[ inf+1.j]',   '[ inf+1.j]',   '[ inf+1.0j]',
+            '[ inf-1.j]',   '[ inf-1.j]',   '[ inf-1.0j]',
+            '[ inf+infj]',  '[ inf+infj]',  '[ inf+infj]',
+            '[ inf-infj]',  '[ inf-infj]',  '[ inf-infj]',
+            '[ inf+nanj]',  '[ inf+nanj]',  '[ inf+nanj]',
+            '[-inf+0.j]',   '[-inf+0.j]',   '[-inf+0.0j]',
+            '[-inf+1.j]',   '[-inf+1.j]',   '[-inf+1.0j]',
+            '[-inf-1.j]',   '[-inf-1.j]',   '[-inf-1.0j]',
+            '[-inf+infj]',  '[-inf+infj]',  '[-inf+infj]',
+            '[-inf-infj]',  '[-inf-infj]',  '[-inf-infj]',
+            '[-inf+nanj]',  '[-inf+nanj]',  '[-inf+nanj]',
+            '[ nan+0.j]',   '[ nan+0.j]',   '[ nan+0.0j]',
+            '[ nan+1.j]',   '[ nan+1.j]',   '[ nan+1.0j]',
+            '[ nan-1.j]',   '[ nan-1.j]',   '[ nan-1.0j]',
+            '[ nan+infj]',  '[ nan+infj]',  '[ nan+infj]',
+            '[ nan-infj]',  '[ nan-infj]',  '[ nan-infj]',
+            '[ nan+nanj]',  '[ nan+nanj]',  '[ nan+nanj]']
+
+        for res, val in zip(actual, wanted):
+            assert_(res == val)
+
+class TestArray2String(TestCase):
+    def test_basic(self):
+        """Basic test of array2string."""
+        a = np.arange(3)
+        assert_(np.array2string(a) == '[0 1 2]')
+        assert_(np.array2string(a, max_line_width=4) == '[0 1\n 2]')
+
+    def test_style_keyword(self):
+        """This should only apply to 0-D arrays. See #1218."""
+        stylestr = np.array2string(np.array(1.5),
+                                   style=lambda x: "Value in 0-D array: " + str(x))
+        assert_(stylestr == 'Value in 0-D array: 1.5')
+
+    def test_format_function(self):
+        """Test custom format function for each element in array."""
+        def _format_function(x):
+            if np.abs(x) < 1:
+                return '.'
+            elif np.abs(x) < 2:
+                return 'o'
+            else:
+                return 'O'
+
+        x = np.arange(3)
+        if sys.version_info[0] >= 3:
+            x_hex = "[0x0 0x1 0x2]"
+            x_oct = "[0o0 0o1 0o2]"
+        else:
+            x_hex = "[0x0L 0x1L 0x2L]"
+            x_oct = "[0L 01L 02L]"
+        assert_(np.array2string(x, formatter={'all':_format_function}) ==
+                "[. o O]")
+        assert_(np.array2string(x, formatter={'int_kind':_format_function}) ==
+                "[. o O]")
+        assert_(np.array2string(x, formatter={'all':lambda x: "%.4f" % x}) ==
+                "[0.0000 1.0000 2.0000]")
+        assert_equal(np.array2string(x, formatter={'int':lambda x: hex(x)}),
+                x_hex)
+        assert_equal(np.array2string(x, formatter={'int':lambda x: oct(x)}),
+                x_oct)
+
+        x = np.arange(3.)
+        assert_(np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) ==
+                "[0.00 1.00 2.00]")
+        assert_(np.array2string(x, formatter={'float':lambda x: "%.2f" % x}) ==
+                "[0.00 1.00 2.00]")
+
+        s = np.array(['abc', 'def'])
+        assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) ==
+                '[abcabc defdef]')
+
+
+class TestPrintOptions:
+    """Test getting and setting global print options."""
+
+    def setUp(self):
+        self.oldopts = np.get_printoptions()
+
+    def tearDown(self):
+        np.set_printoptions(**self.oldopts)
+
+    def test_basic(self):
+        x = np.array([1.5, 0, 1.234567890])
+        assert_equal(repr(x), "array([ 1.5       ,  0.        ,  1.23456789])")
+        np.set_printoptions(precision=4)
+        assert_equal(repr(x), "array([ 1.5   ,  0.    ,  1.2346])")
+
+    def test_formatter(self):
+        x = np.arange(3)
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+
+    def test_formatter_reset(self):
+        x = np.arange(3)
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'int':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'all':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        np.set_printoptions(formatter={'int':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'int_kind':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        x = np.arange(3.)
+        np.set_printoptions(formatter={'float':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1.0, 0.0, 1.0])")
+        np.set_printoptions(formatter={'float_kind':None})
+        assert_equal(repr(x), "array([ 0.,  1.,  2.])")
+
+def test_unicode_object_array():
+    import sys
+    if sys.version_info[0] >= 3:
+        expected = "array(['é'], dtype=object)"
+    else:
+        expected = "array([u'\\xe9'], dtype=object)"
+    x = np.array([sixu('\xe9')], dtype=object)
+    assert_equal(repr(x), expected)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
new file mode 100644
index 0000000000..601f09c091
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
@@ -0,0 +1,1909 @@
+from __future__ import division, absolute_import, print_function
+
+import pickle
+import warnings
+
+import numpy
+import numpy as np
+import datetime
+from numpy.compat import asbytes
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_warns, dec
+)
+
+# Use pytz to test out various time zones if available
+try:
+    from pytz import timezone as tz
+    _has_pytz = True
+except ImportError:
+    _has_pytz = False
+
+
+class TestDateTime(TestCase):
+    def test_datetime_dtype_creation(self):
+        for unit in ['Y', 'M', 'W', 'D',
+                     'h', 'm', 's', 'ms', 'us',
+                     'ns', 'ps', 'fs', 'as']:
+            dt1 = np.dtype('M8[750%s]' % unit)
+            assert_(dt1 == np.dtype('datetime64[750%s]' % unit))
+            dt2 = np.dtype('m8[%s]' % unit)
+            assert_(dt2 == np.dtype('timedelta64[%s]' % unit))
+
+        # Generic units shouldn't add [] to the end
+        assert_equal(str(np.dtype("M8")), "datetime64")
+
+        # Should be possible to specify the endianness
+        assert_equal(np.dtype("=M8"), np.dtype("M8"))
+        assert_equal(np.dtype("=M8[s]"), np.dtype("M8[s]"))
+        assert_(np.dtype(">M8") == np.dtype("M8") or
+                np.dtype("<M8") == np.dtype("M8"))
+        assert_(np.dtype(">M8[D]") == np.dtype("M8[D]") or
+                np.dtype("<M8[D]") == np.dtype("M8[D]"))
+        assert_(np.dtype(">M8") != np.dtype("<M8"))
+
+        assert_equal(np.dtype("=m8"), np.dtype("m8"))
+        assert_equal(np.dtype("=m8[s]"), np.dtype("m8[s]"))
+        assert_(np.dtype(">m8") == np.dtype("m8") or
+                np.dtype("<m8") == np.dtype("m8"))
+        assert_(np.dtype(">m8[D]") == np.dtype("m8[D]") or
+                np.dtype("<m8[D]") == np.dtype("m8[D]"))
+        assert_(np.dtype(">m8") != np.dtype("<m8"))
+
+        # Check that the parser rejects bad datetime types
+        assert_raises(TypeError, np.dtype, 'M8[badunit]')
+        assert_raises(TypeError, np.dtype, 'm8[badunit]')
+        assert_raises(TypeError, np.dtype, 'M8[YY]')
+        assert_raises(TypeError, np.dtype, 'm8[YY]')
+        assert_raises(TypeError, np.dtype, 'm4')
+        assert_raises(TypeError, np.dtype, 'M7')
+        assert_raises(TypeError, np.dtype, 'm7')
+        assert_raises(TypeError, np.dtype, 'M16')
+        assert_raises(TypeError, np.dtype, 'm16')
+
+    def test_datetime_casting_rules(self):
+        # Cannot cast safely/same_kind between timedelta and datetime
+        assert_(not np.can_cast('m8', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('M8', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('m8', 'M8', casting='safe'))
+        assert_(not np.can_cast('M8', 'm8', casting='safe'))
+
+        # Can cast safely/same_kind from integer to timedelta
+        assert_(np.can_cast('i8', 'm8', casting='same_kind'))
+        assert_(np.can_cast('i8', 'm8', casting='safe'))
+
+        # Cannot cast safely/same_kind from float to timedelta
+        assert_(not np.can_cast('f4', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('f4', 'm8', casting='safe'))
+
+        # Cannot cast safely/same_kind from integer to datetime
+        assert_(not np.can_cast('i8', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('i8', 'M8', casting='safe'))
+
+        # Cannot cast safely/same_kind from bool to datetime
+        assert_(not np.can_cast('b1', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('b1', 'M8', casting='safe'))
+        # Can cast safely/same_kind from bool to timedelta
+        assert_(np.can_cast('b1', 'm8', casting='same_kind'))
+        assert_(np.can_cast('b1', 'm8', casting='safe'))
+
+        # Can cast datetime safely from months/years to days
+        assert_(np.can_cast('M8[M]', 'M8[D]', casting='safe'))
+        assert_(np.can_cast('M8[Y]', 'M8[D]', casting='safe'))
+        # Cannot cast timedelta safely from months/years to days
+        assert_(not np.can_cast('m8[M]', 'm8[D]', casting='safe'))
+        assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='safe'))
+        # Can cast datetime same_kind from months/years to days
+        assert_(np.can_cast('M8[M]', 'M8[D]', casting='same_kind'))
+        assert_(np.can_cast('M8[Y]', 'M8[D]', casting='same_kind'))
+        # Can't cast timedelta same_kind from months/years to days
+        assert_(not np.can_cast('m8[M]', 'm8[D]', casting='same_kind'))
+        assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='same_kind'))
+        # Can cast datetime same_kind across the date/time boundary
+        assert_(np.can_cast('M8[D]', 'M8[h]', casting='same_kind'))
+        # Can cast timedelta same_kind across the date/time boundary
+        assert_(np.can_cast('m8[D]', 'm8[h]', casting='same_kind'))
+        assert_(np.can_cast('m8[h]', 'm8[D]', casting='same_kind'))
+
+        # Cannot cast safely if the integer multiplier doesn't divide
+        assert_(not np.can_cast('M8[7h]', 'M8[3h]', casting='safe'))
+        assert_(not np.can_cast('M8[3h]', 'M8[6h]', casting='safe'))
+        # But can cast same_kind
+        assert_(np.can_cast('M8[7h]', 'M8[3h]', casting='same_kind'))
+        # Can cast safely if the integer multiplier does divide
+        assert_(np.can_cast('M8[6h]', 'M8[3h]', casting='safe'))
+
+        # We can always cast types with generic units (corresponding to NaT) to
+        # more specific types
+        assert_(np.can_cast('m8', 'm8[h]', casting='same_kind'))
+        assert_(np.can_cast('m8', 'm8[h]', casting='safe'))
+        assert_(np.can_cast('M8', 'M8[h]', casting='same_kind'))
+        assert_(np.can_cast('M8', 'M8[h]', casting='safe'))
+        # but not the other way around
+        assert_(not np.can_cast('m8[h]', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('m8[h]', 'm8', casting='safe'))
+        assert_(not np.can_cast('M8[h]', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('M8[h]', 'M8', casting='safe'))
+
+    def test_compare_generic_nat(self):
+        # regression tests for GH6452
+        assert_equal(np.datetime64('NaT'),
+                     np.datetime64('2000') + np.timedelta64('NaT'))
+        # nb. we may want to make NaT != NaT true in the future; this test
+        # verifies the existing behavior (and that it should not warn)
+        assert_(np.datetime64('NaT') == np.datetime64('NaT', 'us'))
+        assert_(np.datetime64('NaT', 'us') == np.datetime64('NaT'))
+
+    def test_datetime_scalar_construction(self):
+        # Construct with different units
+        assert_equal(np.datetime64('1950-03-12', 'D'),
+                     np.datetime64('1950-03-12'))
+        assert_equal(np.datetime64('1950-03-12T13', 's'),
+                     np.datetime64('1950-03-12T13', 'm'))
+
+        # Default construction means NaT
+        assert_equal(np.datetime64(), np.datetime64('NaT'))
+
+        # Some basic strings and repr
+        assert_equal(str(np.datetime64('NaT')), 'NaT')
+        assert_equal(repr(np.datetime64('NaT')),
+                     "numpy.datetime64('NaT')")
+        assert_equal(str(np.datetime64('2011-02')), '2011-02')
+        assert_equal(repr(np.datetime64('2011-02')),
+                     "numpy.datetime64('2011-02')")
+
+        # None gets constructed as NaT
+        assert_equal(np.datetime64(None), np.datetime64('NaT'))
+
+        # Default construction of NaT is in generic units
+        assert_equal(np.datetime64().dtype, np.dtype('M8'))
+        assert_equal(np.datetime64('NaT').dtype, np.dtype('M8'))
+
+        # Construction from integers requires a specified unit
+        assert_raises(ValueError, np.datetime64, 17)
+
+        # When constructing from a scalar or zero-dimensional array,
+        # it either keeps the units or you can override them.
+        a = np.datetime64('2000-03-18T16', 'h')
+        b = np.array('2000-03-18T16', dtype='M8[h]')
+
+        assert_equal(a.dtype, np.dtype('M8[h]'))
+        assert_equal(b.dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(a), a)
+        assert_equal(np.datetime64(a).dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(b), a)
+        assert_equal(np.datetime64(b).dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(a, 's'), a)
+        assert_equal(np.datetime64(a, 's').dtype, np.dtype('M8[s]'))
+
+        assert_equal(np.datetime64(b, 's'), a)
+        assert_equal(np.datetime64(b, 's').dtype, np.dtype('M8[s]'))
+
+        # Construction from datetime.date
+        assert_equal(np.datetime64('1945-03-25'),
+                     np.datetime64(datetime.date(1945, 3, 25)))
+        assert_equal(np.datetime64('2045-03-25', 'D'),
+                     np.datetime64(datetime.date(2045, 3, 25), 'D'))
+        # Construction from datetime.datetime
+        assert_equal(np.datetime64('1980-01-25T14:36:22.5'),
+                     np.datetime64(datetime.datetime(1980, 1, 25,
+                                                14, 36, 22, 500000)))
+
+        # Construction with time units from a date is okay
+        assert_equal(np.datetime64('1920-03-13', 'h'),
+                     np.datetime64('1920-03-13T00'))
+        assert_equal(np.datetime64('1920-03', 'm'),
+                     np.datetime64('1920-03-01T00:00'))
+        assert_equal(np.datetime64('1920', 's'),
+                     np.datetime64('1920-01-01T00:00:00'))
+        assert_equal(np.datetime64(datetime.date(2045, 3, 25), 'ms'),
+                     np.datetime64('2045-03-25T00:00:00.000'))
+
+        # Construction with date units from a datetime is also okay
+        assert_equal(np.datetime64('1920-03-13T18', 'D'),
+                     np.datetime64('1920-03-13'))
+        assert_equal(np.datetime64('1920-03-13T18:33:12', 'M'),
+                     np.datetime64('1920-03'))
+        assert_equal(np.datetime64('1920-03-13T18:33:12.5', 'Y'),
+                     np.datetime64('1920'))
+
+    def test_datetime_scalar_construction_timezone(self):
+        # verify that supplying an explicit timezone works, but is deprecated
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('2000-01-01T00Z'),
+                         np.datetime64('2000-01-01T00'))
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('2000-01-01T00-08'),
+                         np.datetime64('2000-01-01T08'))
+
+    def test_datetime_array_find_type(self):
+        dt = np.datetime64('1970-01-01', 'M')
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('M8[M]'))
+
+        # at the moment, we don't automatically convert these to datetime64
+
+        dt = datetime.date(1970, 1, 1)
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.datetime(1970, 1, 1, 12, 30, 40)
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        # find "supertype" for non-dates and dates
+
+        b = np.bool_(True)
+        dt = np.datetime64('1970-01-01', 'M')
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.date(1970, 1, 1)
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.datetime(1970, 1, 1, 12, 30, 40)
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+    def test_timedelta_scalar_construction(self):
+        # Construct with different units
+        assert_equal(np.timedelta64(7, 'D'),
+                     np.timedelta64(1, 'W'))
+        assert_equal(np.timedelta64(120, 's'),
+                     np.timedelta64(2, 'm'))
+
+        # Default construction means 0
+        assert_equal(np.timedelta64(), np.timedelta64(0))
+
+        # None gets constructed as NaT
+        assert_equal(np.timedelta64(None), np.timedelta64('NaT'))
+
+        # Some basic strings and repr
+        assert_equal(str(np.timedelta64('NaT')), 'NaT')
+        assert_equal(repr(np.timedelta64('NaT')),
+                     "numpy.timedelta64('NaT')")
+        assert_equal(str(np.timedelta64(3, 's')), '3 seconds')
+        assert_equal(repr(np.timedelta64(-3, 's')),
+                     "numpy.timedelta64(-3,'s')")
+        assert_equal(repr(np.timedelta64(12)),
+                     "numpy.timedelta64(12)")
+
+        # Construction from an integer produces generic units
+        assert_equal(np.timedelta64(12).dtype, np.dtype('m8'))
+
+        # When constructing from a scalar or zero-dimensional array,
+        # it either keeps the units or you can override them.
+        a = np.timedelta64(2, 'h')
+        b = np.array(2, dtype='m8[h]')
+
+        assert_equal(a.dtype, np.dtype('m8[h]'))
+        assert_equal(b.dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(a), a)
+        assert_equal(np.timedelta64(a).dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(b), a)
+        assert_equal(np.timedelta64(b).dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(a, 's'), a)
+        assert_equal(np.timedelta64(a, 's').dtype, np.dtype('m8[s]'))
+
+        assert_equal(np.timedelta64(b, 's'), a)
+        assert_equal(np.timedelta64(b, 's').dtype, np.dtype('m8[s]'))
+
+        # Construction from datetime.timedelta
+        assert_equal(np.timedelta64(5, 'D'),
+                     np.timedelta64(datetime.timedelta(days=5)))
+        assert_equal(np.timedelta64(102347621, 's'),
+                     np.timedelta64(datetime.timedelta(seconds=102347621)))
+        assert_equal(np.timedelta64(-10234760000, 'us'),
+                     np.timedelta64(datetime.timedelta(
+                                            microseconds=-10234760000)))
+        assert_equal(np.timedelta64(10234760000, 'us'),
+                     np.timedelta64(datetime.timedelta(
+                                            microseconds=10234760000)))
+        assert_equal(np.timedelta64(1023476, 'ms'),
+                     np.timedelta64(datetime.timedelta(milliseconds=1023476)))
+        assert_equal(np.timedelta64(10, 'm'),
+                     np.timedelta64(datetime.timedelta(minutes=10)))
+        assert_equal(np.timedelta64(281, 'h'),
+                     np.timedelta64(datetime.timedelta(hours=281)))
+        assert_equal(np.timedelta64(28, 'W'),
+                     np.timedelta64(datetime.timedelta(weeks=28)))
+
+        # Cannot construct across nonlinear time unit boundaries
+        a = np.timedelta64(3, 's')
+        assert_raises(TypeError, np.timedelta64, a, 'M')
+        assert_raises(TypeError, np.timedelta64, a, 'Y')
+        a = np.timedelta64(6, 'M')
+        assert_raises(TypeError, np.timedelta64, a, 'D')
+        assert_raises(TypeError, np.timedelta64, a, 'h')
+        a = np.timedelta64(1, 'Y')
+        assert_raises(TypeError, np.timedelta64, a, 'D')
+        assert_raises(TypeError, np.timedelta64, a, 'm')
+
+    def test_timedelta_scalar_construction_units(self):
+        # String construction detecting units
+        assert_equal(np.datetime64('2010').dtype,
+                     np.dtype('M8[Y]'))
+        assert_equal(np.datetime64('2010-03').dtype,
+                     np.dtype('M8[M]'))
+        assert_equal(np.datetime64('2010-03-12').dtype,
+                     np.dtype('M8[D]'))
+        assert_equal(np.datetime64('2010-03-12T17').dtype,
+                     np.dtype('M8[h]'))
+        assert_equal(np.datetime64('2010-03-12T17:15').dtype,
+                     np.dtype('M8[m]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08').dtype,
+                     np.dtype('M8[s]'))
+
+        assert_equal(np.datetime64('2010-03-12T17:15:08.1').dtype,
+                     np.dtype('M8[ms]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.12').dtype,
+                     np.dtype('M8[ms]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.123').dtype,
+                     np.dtype('M8[ms]'))
+
+        assert_equal(np.datetime64('2010-03-12T17:15:08.1234').dtype,
+                     np.dtype('M8[us]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.12345').dtype,
+                     np.dtype('M8[us]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.123456').dtype,
+                     np.dtype('M8[us]'))
+
+        assert_equal(np.datetime64('1970-01-01T00:00:02.1234567').dtype,
+                     np.dtype('M8[ns]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.12345678').dtype,
+                     np.dtype('M8[ns]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.123456789').dtype,
+                     np.dtype('M8[ns]'))
+
+        assert_equal(np.datetime64('1970-01-01T00:00:02.1234567890').dtype,
+                     np.dtype('M8[ps]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.12345678901').dtype,
+                     np.dtype('M8[ps]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.123456789012').dtype,
+                     np.dtype('M8[ps]'))
+
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.1234567890123').dtype,
+                     np.dtype('M8[fs]'))
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.12345678901234').dtype,
+                     np.dtype('M8[fs]'))
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.123456789012345').dtype,
+                     np.dtype('M8[fs]'))
+
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.1234567890123456').dtype,
+                     np.dtype('M8[as]'))
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.12345678901234567').dtype,
+                     np.dtype('M8[as]'))
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.123456789012345678').dtype,
+                     np.dtype('M8[as]'))
+
+        # Python date object
+        assert_equal(np.datetime64(datetime.date(2010, 4, 16)).dtype,
+                     np.dtype('M8[D]'))
+
+        # Python datetime object
+        assert_equal(np.datetime64(
+                        datetime.datetime(2010, 4, 16, 13, 45, 18)).dtype,
+                     np.dtype('M8[us]'))
+
+        # 'today' special value
+        assert_equal(np.datetime64('today').dtype,
+                     np.dtype('M8[D]'))
+
+        # 'now' special value
+        assert_equal(np.datetime64('now').dtype,
+                     np.dtype('M8[s]'))
+
+    def test_datetime_nat_casting(self):
+        a = np.array('NaT', dtype='M8[D]')
+        b = np.datetime64('NaT', '[D]')
+
+        # Arrays
+        assert_equal(a.astype('M8[s]'), np.array('NaT', dtype='M8[s]'))
+        assert_equal(a.astype('M8[ms]'), np.array('NaT', dtype='M8[ms]'))
+        assert_equal(a.astype('M8[M]'), np.array('NaT', dtype='M8[M]'))
+        assert_equal(a.astype('M8[Y]'), np.array('NaT', dtype='M8[Y]'))
+        assert_equal(a.astype('M8[W]'), np.array('NaT', dtype='M8[W]'))
+
+        # Scalars -> Scalars
+        assert_equal(np.datetime64(b, '[s]'), np.datetime64('NaT', '[s]'))
+        assert_equal(np.datetime64(b, '[ms]'), np.datetime64('NaT', '[ms]'))
+        assert_equal(np.datetime64(b, '[M]'), np.datetime64('NaT', '[M]'))
+        assert_equal(np.datetime64(b, '[Y]'), np.datetime64('NaT', '[Y]'))
+        assert_equal(np.datetime64(b, '[W]'), np.datetime64('NaT', '[W]'))
+
+        # Arrays -> Scalars
+        assert_equal(np.datetime64(a, '[s]'), np.datetime64('NaT', '[s]'))
+        assert_equal(np.datetime64(a, '[ms]'), np.datetime64('NaT', '[ms]'))
+        assert_equal(np.datetime64(a, '[M]'), np.datetime64('NaT', '[M]'))
+        assert_equal(np.datetime64(a, '[Y]'), np.datetime64('NaT', '[Y]'))
+        assert_equal(np.datetime64(a, '[W]'), np.datetime64('NaT', '[W]'))
+
+    def test_days_creation(self):
+        assert_equal(np.array('1599', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3 - 365)
+        assert_equal(np.array('1600', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3)
+        assert_equal(np.array('1601', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3 + 366)
+        assert_equal(np.array('1900', dtype='M8[D]').astype('i8'),
+                (1900-1970)*365 - (1970-1900)//4)
+        assert_equal(np.array('1901', dtype='M8[D]').astype('i8'),
+                (1900-1970)*365 - (1970-1900)//4 + 365)
+        assert_equal(np.array('1967', dtype='M8[D]').astype('i8'), -3*365 - 1)
+        assert_equal(np.array('1968', dtype='M8[D]').astype('i8'), -2*365 - 1)
+        assert_equal(np.array('1969', dtype='M8[D]').astype('i8'), -1*365)
+        assert_equal(np.array('1970', dtype='M8[D]').astype('i8'), 0*365)
+        assert_equal(np.array('1971', dtype='M8[D]').astype('i8'), 1*365)
+        assert_equal(np.array('1972', dtype='M8[D]').astype('i8'), 2*365)
+        assert_equal(np.array('1973', dtype='M8[D]').astype('i8'), 3*365 + 1)
+        assert_equal(np.array('1974', dtype='M8[D]').astype('i8'), 4*365 + 1)
+        assert_equal(np.array('2000', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4)
+        assert_equal(np.array('2001', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 366)
+        assert_equal(np.array('2400', dtype='M8[D]').astype('i8'),
+                 (2400 - 1970)*365 + (2400 - 1972)//4 - 3)
+        assert_equal(np.array('2401', dtype='M8[D]').astype('i8'),
+                 (2400 - 1970)*365 + (2400 - 1972)//4 - 3 + 366)
+
+        assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 28)
+        assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 29)
+        assert_equal(np.array('2000-02-29', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 28)
+        assert_equal(np.array('2000-03-01', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 29)
+        assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 366 + 31 + 28 + 21)
+
+    def test_days_to_pydate(self):
+        assert_equal(np.array('1599', dtype='M8[D]').astype('O'),
+                    datetime.date(1599, 1, 1))
+        assert_equal(np.array('1600', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 1, 1))
+        assert_equal(np.array('1601', dtype='M8[D]').astype('O'),
+                    datetime.date(1601, 1, 1))
+        assert_equal(np.array('1900', dtype='M8[D]').astype('O'),
+                    datetime.date(1900, 1, 1))
+        assert_equal(np.array('1901', dtype='M8[D]').astype('O'),
+                    datetime.date(1901, 1, 1))
+        assert_equal(np.array('2000', dtype='M8[D]').astype('O'),
+                    datetime.date(2000, 1, 1))
+        assert_equal(np.array('2001', dtype='M8[D]').astype('O'),
+                    datetime.date(2001, 1, 1))
+        assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 2, 29))
+        assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 3, 1))
+        assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('O'),
+                    datetime.date(2001, 3, 22))
+
+    def test_dtype_comparison(self):
+        assert_(not (np.dtype('M8[us]') == np.dtype('M8[ms]')))
+        assert_(np.dtype('M8[us]') != np.dtype('M8[ms]'))
+        assert_(np.dtype('M8[2D]') != np.dtype('M8[D]'))
+        assert_(np.dtype('M8[D]') != np.dtype('M8[2D]'))
+
+    def test_pydatetime_creation(self):
+        a = np.array(['1960-03-12', datetime.date(1960, 3, 12)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        a = np.array(['1999-12-31', datetime.date(1999, 12, 31)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        a = np.array(['2000-01-01', datetime.date(2000, 1, 1)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        # Will fail if the date changes during the exact right moment
+        a = np.array(['today', datetime.date.today()], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        # datetime.datetime.now() returns local time, not UTC
+        #a = np.array(['now', datetime.datetime.now()], dtype='M8[s]')
+        #assert_equal(a[0], a[1])
+
+        # we can give a datetime.date time units
+        assert_equal(np.array(datetime.date(1960, 3, 12), dtype='M8[s]'),
+                     np.array(np.datetime64('1960-03-12T00:00:00')))
+
+    def test_datetime_string_conversion(self):
+        a = ['2011-03-16', '1920-01-01', '2013-05-19']
+        str_a = np.array(a, dtype='S')
+        dt_a = np.array(a, dtype='M')
+        str_b = np.empty_like(str_a)
+        dt_b = np.empty_like(dt_a)
+
+        # String to datetime
+        assert_equal(dt_a, str_a.astype('M'))
+        assert_equal(dt_a.dtype, str_a.astype('M').dtype)
+        dt_b[...] = str_a
+        assert_equal(dt_a, dt_b)
+        # Datetime to string
+        assert_equal(str_a, dt_a.astype('S0'))
+        str_b[...] = dt_a
+        assert_equal(str_a, str_b)
+
+        # Convert the 'S' to 'U'
+        str_a = str_a.astype('U')
+        str_b = str_b.astype('U')
+
+        # Unicode to datetime
+        assert_equal(dt_a, str_a.astype('M'))
+        assert_equal(dt_a.dtype, str_a.astype('M').dtype)
+        dt_b[...] = str_a
+        assert_equal(dt_a, dt_b)
+        # Datetime to unicode
+        assert_equal(str_a, dt_a.astype('U'))
+        str_b[...] = dt_a
+        assert_equal(str_a, str_b)
+
+    def test_datetime_array_str(self):
+        a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M')
+        assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']")
+
+        a = np.array(['2011-03-16T13:55', '1920-01-01T03:12'], dtype='M')
+        assert_equal(np.array2string(a, separator=', ',
+                    formatter={'datetime': lambda x:
+                            "'%s'" % np.datetime_as_string(x, timezone='UTC')}),
+                     "['2011-03-16T13:55Z', '1920-01-01T03:12Z']")
+
+        # Check that one NaT doesn't corrupt subsequent entries
+        a = np.array(['2010', 'NaT', '2030']).astype('M')
+        assert_equal(str(a), "['2010' 'NaT' '2030']")
+
+    def test_timedelta_array_str(self):
+        a = np.array([-1, 0, 100], dtype='m')
+        assert_equal(str(a), "[ -1   0 100]")
+        a = np.array(['NaT', 'NaT'], dtype='m')
+        assert_equal(str(a), "['NaT' 'NaT']")
+        # Check right-alignment with NaTs
+        a = np.array([-1, 'NaT', 0], dtype='m')
+        assert_equal(str(a), "[   -1 'NaT'     0]")
+        a = np.array([-1, 'NaT', 1234567], dtype='m')
+        assert_equal(str(a), "[     -1   'NaT' 1234567]")
+
+    def test_pickle(self):
+        # Check that pickle roundtripping works
+        dt = np.dtype('M8[7D]')
+        assert_equal(pickle.loads(pickle.dumps(dt)), dt)
+        dt = np.dtype('M8[W]')
+        assert_equal(pickle.loads(pickle.dumps(dt)), dt)
+
+        # Check that loading pickles from 1.6 works
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'D'\np6\n" + \
+              "I7\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('<M8[7D]'))
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'W'\np6\n" + \
+              "I1\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('<M8[W]'))
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'>'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'us'\np6\n" + \
+              "I1\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('>M8[us]'))
+
+    def test_setstate(self):
+        "Verify that datetime dtype __setstate__ can handle bad arguments"
+        dt = np.dtype('>M8[us]')
+        assert_raises(ValueError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, 1))
+        assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2])
+        assert_raises(TypeError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, ({}, 'xxx')))
+        assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2])
+
+    def test_dtype_promotion(self):
+        # datetime <op> datetime computes the metadata gcd
+        # timedelta <op> timedelta computes the metadata gcd
+        for mM in ['m', 'M']:
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[2Y]'), np.dtype(mM+'8[2Y]')),
+                np.dtype(mM+'8[2Y]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[12Y]'), np.dtype(mM+'8[15Y]')),
+                np.dtype(mM+'8[3Y]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[62M]'), np.dtype(mM+'8[24M]')),
+                np.dtype(mM+'8[2M]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[1W]'), np.dtype(mM+'8[2D]')),
+                np.dtype(mM+'8[1D]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[W]'), np.dtype(mM+'8[13s]')),
+                np.dtype(mM+'8[s]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[13W]'), np.dtype(mM+'8[49s]')),
+                np.dtype(mM+'8[7s]'))
+        # timedelta <op> timedelta raises when there is no reasonable gcd
+        assert_raises(TypeError, np.promote_types,
+                            np.dtype('m8[Y]'), np.dtype('m8[D]'))
+        assert_raises(TypeError, np.promote_types,
+                            np.dtype('m8[M]'), np.dtype('m8[W]'))
+        # timedelta <op> timedelta may overflow with big unit ranges
+        assert_raises(OverflowError, np.promote_types,
+                            np.dtype('m8[W]'), np.dtype('m8[fs]'))
+        assert_raises(OverflowError, np.promote_types,
+                            np.dtype('m8[s]'), np.dtype('m8[as]'))
+
+    def test_cast_overflow(self):
+        # gh-4486
+        def cast():
+            numpy.datetime64("1971-01-01 00:00:00.000000000000000").astype("<M8[D]")
+        assert_raises(OverflowError, cast)
+
+        def cast2():
+            numpy.datetime64("2014").astype("<M8[fs]")
+        assert_raises(OverflowError, cast2)
+
+    def test_pyobject_roundtrip(self):
+        # All datetime types should be able to roundtrip through object
+        a = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0,
+                      -1020040340, -2942398, -1, 0, 1, 234523453, 1199164176],
+                                                        dtype=np.int64)
+        # With date units
+        for unit in ['M8[D]', 'M8[W]', 'M8[M]', 'M8[Y]']:
+            b = a.copy().view(dtype=unit)
+            b[0] = '-0001-01-01'
+            b[1] = '-0001-12-31'
+            b[2] = '0000-01-01'
+            b[3] = '0001-01-01'
+            b[4] = '1969-12-31'
+            b[5] = '1970-01-01'
+            b[6] = '9999-12-31'
+            b[7] = '10000-01-01'
+            b[8] = 'NaT'
+
+            assert_equal(b.astype(object).astype(unit), b,
+                            "Error roundtripping unit %s" % unit)
+        # With time units
+        for unit in ['M8[as]', 'M8[16fs]', 'M8[ps]', 'M8[us]',
+                     'M8[300as]', 'M8[20us]']:
+            b = a.copy().view(dtype=unit)
+            b[0] = '-0001-01-01T00'
+            b[1] = '-0001-12-31T00'
+            b[2] = '0000-01-01T00'
+            b[3] = '0001-01-01T00'
+            b[4] = '1969-12-31T23:59:59.999999'
+            b[5] = '1970-01-01T00'
+            b[6] = '9999-12-31T23:59:59.999999'
+            b[7] = '10000-01-01T00'
+            b[8] = 'NaT'
+
+            assert_equal(b.astype(object).astype(unit), b,
+                            "Error roundtripping unit %s" % unit)
+
+    def test_month_truncation(self):
+        # Make sure that months are truncating correctly
+        assert_equal(np.array('1945-03-01', dtype='M8[M]'),
+                     np.array('1945-03-31', dtype='M8[M]'))
+        assert_equal(np.array('1969-11-01', dtype='M8[M]'),
+             np.array('1969-11-30T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1969-12-01', dtype='M8[M]'),
+             np.array('1969-12-31T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1970-01-01', dtype='M8[M]'),
+             np.array('1970-01-31T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1980-02-01', dtype='M8[M]'),
+             np.array('1980-02-29T23:59:59.99999', dtype='M').astype('M8[M]'))
+
+    def test_different_unit_comparison(self):
+        # Check some years with date units
+        for unit1 in ['Y', 'M', 'D']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['Y', 'M', 'D']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_equal(np.array('1945', dtype=dt1),
+                             np.array('1945', dtype=dt2))
+                assert_equal(np.array('1970', dtype=dt1),
+                             np.array('1970', dtype=dt2))
+                assert_equal(np.array('9999', dtype=dt1),
+                             np.array('9999', dtype=dt2))
+                assert_equal(np.array('10000', dtype=dt1),
+                             np.array('10000-01-01', dtype=dt2))
+                assert_equal(np.datetime64('1945', unit1),
+                             np.datetime64('1945', unit2))
+                assert_equal(np.datetime64('1970', unit1),
+                             np.datetime64('1970', unit2))
+                assert_equal(np.datetime64('9999', unit1),
+                             np.datetime64('9999', unit2))
+                assert_equal(np.datetime64('10000', unit1),
+                             np.datetime64('10000-01-01', unit2))
+        # Check some datetimes with time units
+        for unit1 in ['6h', 'h', 'm', 's', '10ms', 'ms', 'us']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['h', 'm', 's', 'ms', 'us']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_equal(np.array('1945-03-12T18', dtype=dt1),
+                             np.array('1945-03-12T18', dtype=dt2))
+                assert_equal(np.array('1970-03-12T18', dtype=dt1),
+                             np.array('1970-03-12T18', dtype=dt2))
+                assert_equal(np.array('9999-03-12T18', dtype=dt1),
+                             np.array('9999-03-12T18', dtype=dt2))
+                assert_equal(np.array('10000-01-01T00', dtype=dt1),
+                             np.array('10000-01-01T00', dtype=dt2))
+                assert_equal(np.datetime64('1945-03-12T18', unit1),
+                             np.datetime64('1945-03-12T18', unit2))
+                assert_equal(np.datetime64('1970-03-12T18', unit1),
+                             np.datetime64('1970-03-12T18', unit2))
+                assert_equal(np.datetime64('9999-03-12T18', unit1),
+                             np.datetime64('9999-03-12T18', unit2))
+                assert_equal(np.datetime64('10000-01-01T00', unit1),
+                             np.datetime64('10000-01-01T00', unit2))
+        # Check some days with units that won't overflow
+        for unit1 in ['D', '12h', 'h', 'm', 's', '4s', 'ms', 'us']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['D', 'h', 'm', 's', 'ms', 'us']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_(np.equal(np.array('1932-02-17', dtype='M').astype(dt1),
+                     np.array('1932-02-17T00:00:00', dtype='M').astype(dt2),
+                     casting='unsafe'))
+                assert_(np.equal(np.array('10000-04-27', dtype='M').astype(dt1),
+                     np.array('10000-04-27T00:00:00', dtype='M').astype(dt2),
+                     casting='unsafe'))
+
+        # Shouldn't be able to compare datetime and timedelta
+        # TODO: Changing to 'same_kind' or 'safe' casting in the ufuncs by
+        #       default is needed to properly catch this kind of thing...
+        a = np.array('2012-12-21', dtype='M8[D]')
+        b = np.array(3, dtype='m8[D]')
+        #assert_raises(TypeError, np.less, a, b)
+        assert_raises(TypeError, np.less, a, b, casting='same_kind')
+
+    def test_datetime_like(self):
+        a = np.array([3], dtype='m8[4D]')
+        b = np.array(['2012-12-21'], dtype='M8[D]')
+
+        assert_equal(np.ones_like(a).dtype, a.dtype)
+        assert_equal(np.zeros_like(a).dtype, a.dtype)
+        assert_equal(np.empty_like(a).dtype, a.dtype)
+        assert_equal(np.ones_like(b).dtype, b.dtype)
+        assert_equal(np.zeros_like(b).dtype, b.dtype)
+        assert_equal(np.empty_like(b).dtype, b.dtype)
+
+    def test_datetime_unary(self):
+        for tda, tdb, tdzero, tdone, tdmone in \
+                [
+                 # One-dimensional arrays
+                 (np.array([3], dtype='m8[D]'),
+                  np.array([-3], dtype='m8[D]'),
+                  np.array([0], dtype='m8[D]'),
+                  np.array([1], dtype='m8[D]'),
+                  np.array([-1], dtype='m8[D]')),
+                 # NumPy scalars
+                 (np.timedelta64(3, '[D]'),
+                  np.timedelta64(-3, '[D]'),
+                  np.timedelta64(0, '[D]'),
+                  np.timedelta64(1, '[D]'),
+                  np.timedelta64(-1, '[D]'))]:
+            # negative ufunc
+            assert_equal(-tdb, tda)
+            assert_equal((-tdb).dtype, tda.dtype)
+            assert_equal(np.negative(tdb), tda)
+            assert_equal(np.negative(tdb).dtype, tda.dtype)
+
+            # absolute ufunc
+            assert_equal(np.absolute(tdb), tda)
+            assert_equal(np.absolute(tdb).dtype, tda.dtype)
+
+            # sign ufunc
+            assert_equal(np.sign(tda), tdone)
+            assert_equal(np.sign(tdb), tdmone)
+            assert_equal(np.sign(tdzero), tdzero)
+            assert_equal(np.sign(tda).dtype, tda.dtype)
+
+            # The ufuncs always produce native-endian results
+            assert_
+
+    def test_datetime_add(self):
+        for dta, dtb, dtc, dtnat, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array(['2012-12-24'], dtype='M8[D]'),
+                      np.array(['2012-12-21T11'], dtype='M8[h]'),
+                      np.array(['NaT'], dtype='M8[D]'),
+                      np.array([3], dtype='m8[D]'),
+                      np.array([11], dtype='m8[h]'),
+                      np.array([3*24 + 11], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.datetime64('2012-12-24', '[D]'),
+                      np.datetime64('2012-12-21T11', '[h]'),
+                      np.datetime64('NaT', '[D]'),
+                      np.timedelta64(3, '[D]'),
+                      np.timedelta64(11, '[h]'),
+                      np.timedelta64(3*24 + 11, '[h]'))]:
+            # m8 + m8
+            assert_equal(tda + tdb, tdc)
+            assert_equal((tda + tdb).dtype, np.dtype('m8[h]'))
+            # m8 + bool
+            assert_equal(tdb + True, tdb + 1)
+            assert_equal((tdb + True).dtype, np.dtype('m8[h]'))
+            # m8 + int
+            assert_equal(tdb + 3*24, tdc)
+            assert_equal((tdb + 3*24).dtype, np.dtype('m8[h]'))
+            # bool + m8
+            assert_equal(False + tdb, tdb)
+            assert_equal((False + tdb).dtype, np.dtype('m8[h]'))
+            # int + m8
+            assert_equal(3*24 + tdb, tdc)
+            assert_equal((3*24 + tdb).dtype, np.dtype('m8[h]'))
+            # M8 + bool
+            assert_equal(dta + True, dta + 1)
+            assert_equal(dtnat + True, dtnat)
+            assert_equal((dta + True).dtype, np.dtype('M8[D]'))
+            # M8 + int
+            assert_equal(dta + 3, dtb)
+            assert_equal(dtnat + 3, dtnat)
+            assert_equal((dta + 3).dtype, np.dtype('M8[D]'))
+            # bool + M8
+            assert_equal(False + dta, dta)
+            assert_equal(False + dtnat, dtnat)
+            assert_equal((False + dta).dtype, np.dtype('M8[D]'))
+            # int + M8
+            assert_equal(3 + dta, dtb)
+            assert_equal(3 + dtnat, dtnat)
+            assert_equal((3 + dta).dtype, np.dtype('M8[D]'))
+            # M8 + m8
+            assert_equal(dta + tda, dtb)
+            assert_equal(dtnat + tda, dtnat)
+            assert_equal((dta + tda).dtype, np.dtype('M8[D]'))
+            # m8 + M8
+            assert_equal(tda + dta, dtb)
+            assert_equal(tda + dtnat, dtnat)
+            assert_equal((tda + dta).dtype, np.dtype('M8[D]'))
+
+            # In M8 + m8, the result goes to higher precision
+            assert_equal(np.add(dta, tdb, casting='unsafe'), dtc)
+            assert_equal(np.add(dta, tdb, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+            assert_equal(np.add(tdb, dta, casting='unsafe'), dtc)
+            assert_equal(np.add(tdb, dta, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+
+            # M8 + M8
+            assert_raises(TypeError, np.add, dta, dtb)
+
+    def test_datetime_subtract(self):
+        for dta, dtb, dtc, dtd, dte, dtnat, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array(['2012-12-24'], dtype='M8[D]'),
+                      np.array(['1940-12-24'], dtype='M8[D]'),
+                      np.array(['1940-12-24T00'], dtype='M8[h]'),
+                      np.array(['1940-12-23T13'], dtype='M8[h]'),
+                      np.array(['NaT'], dtype='M8[D]'),
+                      np.array([3], dtype='m8[D]'),
+                      np.array([11], dtype='m8[h]'),
+                      np.array([3*24 - 11], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.datetime64('2012-12-24', '[D]'),
+                      np.datetime64('1940-12-24', '[D]'),
+                      np.datetime64('1940-12-24T00', '[h]'),
+                      np.datetime64('1940-12-23T13', '[h]'),
+                      np.datetime64('NaT', '[D]'),
+                      np.timedelta64(3, '[D]'),
+                      np.timedelta64(11, '[h]'),
+                      np.timedelta64(3*24 - 11, '[h]'))]:
+            # m8 - m8
+            assert_equal(tda - tdb, tdc)
+            assert_equal((tda - tdb).dtype, np.dtype('m8[h]'))
+            assert_equal(tdb - tda, -tdc)
+            assert_equal((tdb - tda).dtype, np.dtype('m8[h]'))
+            # m8 - bool
+            assert_equal(tdc - True, tdc - 1)
+            assert_equal((tdc - True).dtype, np.dtype('m8[h]'))
+            # m8 - int
+            assert_equal(tdc - 3*24, -tdb)
+            assert_equal((tdc - 3*24).dtype, np.dtype('m8[h]'))
+            # int - m8
+            assert_equal(False - tdb, -tdb)
+            assert_equal((False - tdb).dtype, np.dtype('m8[h]'))
+            # int - m8
+            assert_equal(3*24 - tdb, tdc)
+            assert_equal((3*24 - tdb).dtype, np.dtype('m8[h]'))
+            # M8 - bool
+            assert_equal(dtb - True, dtb - 1)
+            assert_equal(dtnat - True, dtnat)
+            assert_equal((dtb - True).dtype, np.dtype('M8[D]'))
+            # M8 - int
+            assert_equal(dtb - 3, dta)
+            assert_equal(dtnat - 3, dtnat)
+            assert_equal((dtb - 3).dtype, np.dtype('M8[D]'))
+            # M8 - m8
+            assert_equal(dtb - tda, dta)
+            assert_equal(dtnat - tda, dtnat)
+            assert_equal((dtb - tda).dtype, np.dtype('M8[D]'))
+
+            # In M8 - m8, the result goes to higher precision
+            assert_equal(np.subtract(dtc, tdb, casting='unsafe'), dte)
+            assert_equal(np.subtract(dtc, tdb, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+
+            # M8 - M8 with different goes to higher precision
+            assert_equal(np.subtract(dtc, dtd, casting='unsafe'),
+                         np.timedelta64(0, 'h'))
+            assert_equal(np.subtract(dtc, dtd, casting='unsafe').dtype,
+                         np.dtype('m8[h]'))
+            assert_equal(np.subtract(dtd, dtc, casting='unsafe'),
+                         np.timedelta64(0, 'h'))
+            assert_equal(np.subtract(dtd, dtc, casting='unsafe').dtype,
+                         np.dtype('m8[h]'))
+
+            # m8 - M8
+            assert_raises(TypeError, np.subtract, tda, dta)
+            # bool - M8
+            assert_raises(TypeError, np.subtract, False, dta)
+            # int - M8
+            assert_raises(TypeError, np.subtract, 3, dta)
+
+    def test_datetime_multiply(self):
+        for dta, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array([6], dtype='m8[h]'),
+                      np.array([9], dtype='m8[h]'),
+                      np.array([12], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.timedelta64(6, '[h]'),
+                      np.timedelta64(9, '[h]'),
+                      np.timedelta64(12, '[h]'))]:
+            # m8 * int
+            assert_equal(tda * 2, tdc)
+            assert_equal((tda * 2).dtype, np.dtype('m8[h]'))
+            # int * m8
+            assert_equal(2 * tda, tdc)
+            assert_equal((2 * tda).dtype, np.dtype('m8[h]'))
+            # m8 * float
+            assert_equal(tda * 1.5, tdb)
+            assert_equal((tda * 1.5).dtype, np.dtype('m8[h]'))
+            # float * m8
+            assert_equal(1.5 * tda, tdb)
+            assert_equal((1.5 * tda).dtype, np.dtype('m8[h]'))
+
+            # m8 * m8
+            assert_raises(TypeError, np.multiply, tda, tdb)
+            # m8 * M8
+            assert_raises(TypeError, np.multiply, dta, tda)
+            # M8 * m8
+            assert_raises(TypeError, np.multiply, tda, dta)
+            # M8 * int
+            assert_raises(TypeError, np.multiply, dta, 2)
+            # int * M8
+            assert_raises(TypeError, np.multiply, 2, dta)
+            # M8 * float
+            assert_raises(TypeError, np.multiply, dta, 1.5)
+            # float * M8
+            assert_raises(TypeError, np.multiply, 1.5, dta)
+
+        # NaTs
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', category=RuntimeWarning)
+            nat = np.timedelta64('NaT')
+            def check(a, b, res):
+                assert_equal(a * b, res)
+                assert_equal(b * a, res)
+            for tp in (int, float):
+                check(nat, tp(2), nat)
+                check(nat, tp(0), nat)
+            for f in (float('inf'), float('nan')):
+                check(np.timedelta64(1), f, nat)
+                check(np.timedelta64(0), f, nat)
+                check(nat, f, nat)
+
+    def test_datetime_divide(self):
+        for dta, tda, tdb, tdc, tdd in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array([6], dtype='m8[h]'),
+                      np.array([9], dtype='m8[h]'),
+                      np.array([12], dtype='m8[h]'),
+                      np.array([6], dtype='m8[m]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.timedelta64(6, '[h]'),
+                      np.timedelta64(9, '[h]'),
+                      np.timedelta64(12, '[h]'),
+                      np.timedelta64(6, '[m]'))]:
+            # m8 / int
+            assert_equal(tdc / 2, tda)
+            assert_equal((tdc / 2).dtype, np.dtype('m8[h]'))
+            # m8 / float
+            assert_equal(tda / 0.5, tdc)
+            assert_equal((tda / 0.5).dtype, np.dtype('m8[h]'))
+            # m8 / m8
+            assert_equal(tda / tdb, 6.0 / 9.0)
+            assert_equal(np.divide(tda, tdb), 6.0 / 9.0)
+            assert_equal(np.true_divide(tda, tdb), 6.0 / 9.0)
+            assert_equal(tdb / tda, 9.0 / 6.0)
+            assert_equal((tda / tdb).dtype, np.dtype('f8'))
+            assert_equal(tda / tdd, 60.0)
+            assert_equal(tdd / tda, 1.0 / 60.0)
+
+            # m8 // m8
+            assert_raises(TypeError, np.floor_divide, tda, tdb)
+            # int / m8
+            assert_raises(TypeError, np.divide, 2, tdb)
+            # float / m8
+            assert_raises(TypeError, np.divide, 0.5, tdb)
+            # m8 / M8
+            assert_raises(TypeError, np.divide, dta, tda)
+            # M8 / m8
+            assert_raises(TypeError, np.divide, tda, dta)
+            # M8 / int
+            assert_raises(TypeError, np.divide, dta, 2)
+            # int / M8
+            assert_raises(TypeError, np.divide, 2, dta)
+            # M8 / float
+            assert_raises(TypeError, np.divide, dta, 1.5)
+            # float / M8
+            assert_raises(TypeError, np.divide, 1.5, dta)
+
+        # NaTs
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', category=RuntimeWarning)
+            nat = np.timedelta64('NaT')
+            for tp in (int, float):
+                assert_equal(np.timedelta64(1) / tp(0), nat)
+                assert_equal(np.timedelta64(0) / tp(0), nat)
+                assert_equal(nat / tp(0), nat)
+                assert_equal(nat / tp(2), nat)
+            # Division by inf
+            assert_equal(np.timedelta64(1) / float('inf'), np.timedelta64(0))
+            assert_equal(np.timedelta64(0) / float('inf'), np.timedelta64(0))
+            assert_equal(nat / float('inf'), nat)
+            # Division by nan
+            assert_equal(np.timedelta64(1) / float('nan'), nat)
+            assert_equal(np.timedelta64(0) / float('nan'), nat)
+            assert_equal(nat / float('nan'), nat)
+
+    def test_datetime_compare(self):
+        # Test all the comparison operators
+        a = np.datetime64('2000-03-12T18:00:00.000000')
+        b = np.array(['2000-03-12T18:00:00.000000',
+                      '2000-03-12T17:59:59.999999',
+                      '2000-03-12T18:00:00.000001',
+                      '1970-01-11T12:00:00.909090',
+                      '2016-01-11T12:00:00.909090'],
+                      dtype='datetime64[us]')
+        assert_equal(np.equal(a, b), [1, 0, 0, 0, 0])
+        assert_equal(np.not_equal(a, b), [0, 1, 1, 1, 1])
+        assert_equal(np.less(a, b), [0, 0, 1, 0, 1])
+        assert_equal(np.less_equal(a, b), [1, 0, 1, 0, 1])
+        assert_equal(np.greater(a, b), [0, 1, 0, 1, 0])
+        assert_equal(np.greater_equal(a, b), [1, 1, 0, 1, 0])
+
+    def test_datetime_compare_nat(self):
+        dt_nat = np.datetime64('NaT', 'D')
+        dt_other = np.datetime64('2000-01-01')
+        td_nat = np.timedelta64('NaT', 'h')
+        td_other = np.timedelta64(1, 'h')
+
+        for op in [np.equal, np.less, np.less_equal,
+                   np.greater, np.greater_equal]:
+            if op(dt_nat, dt_nat):
+                assert_warns(FutureWarning, op, dt_nat, dt_nat)
+            if op(dt_nat, dt_other):
+                assert_warns(FutureWarning, op, dt_nat, dt_other)
+            if op(dt_other, dt_nat):
+                assert_warns(FutureWarning, op, dt_other, dt_nat)
+            if op(td_nat, td_nat):
+                assert_warns(FutureWarning, op, td_nat, td_nat)
+            if op(td_nat, td_other):
+                assert_warns(FutureWarning, op, td_nat, td_other)
+            if op(td_other, td_nat):
+                assert_warns(FutureWarning, op, td_other, td_nat)
+
+        assert_warns(FutureWarning, np.not_equal, dt_nat, dt_nat)
+        assert_(np.not_equal(dt_nat, dt_other))
+        assert_(np.not_equal(dt_other, dt_nat))
+        assert_warns(FutureWarning, np.not_equal, td_nat, td_nat)
+        assert_(np.not_equal(td_nat, td_other))
+        assert_(np.not_equal(td_other, td_nat))
+
+    def test_datetime_minmax(self):
+        # The metadata of the result should become the GCD
+        # of the operand metadata
+        a = np.array('1999-03-12T13', dtype='M8[2m]')
+        b = np.array('1999-03-12T12', dtype='M8[s]')
+        assert_equal(np.minimum(a, b), b)
+        assert_equal(np.minimum(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.fmin(a, b), b)
+        assert_equal(np.fmin(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.maximum(a, b), a)
+        assert_equal(np.maximum(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.fmax(a, b), a)
+        assert_equal(np.fmax(a, b).dtype, np.dtype('M8[s]'))
+        # Viewed as integers, the comparison is opposite because
+        # of the units chosen
+        assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8'))
+
+        # Interaction with NaT
+        a = np.array('1999-03-12T13', dtype='M8[2m]')
+        dtnat = np.array('NaT', dtype='M8[h]')
+        assert_equal(np.minimum(a, dtnat), a)
+        assert_equal(np.minimum(dtnat, a), a)
+        assert_equal(np.maximum(a, dtnat), a)
+        assert_equal(np.maximum(dtnat, a), a)
+
+        # Also do timedelta
+        a = np.array(3, dtype='m8[h]')
+        b = np.array(3*3600 - 3, dtype='m8[s]')
+        assert_equal(np.minimum(a, b), b)
+        assert_equal(np.minimum(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.fmin(a, b), b)
+        assert_equal(np.fmin(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.maximum(a, b), a)
+        assert_equal(np.maximum(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.fmax(a, b), a)
+        assert_equal(np.fmax(a, b).dtype, np.dtype('m8[s]'))
+        # Viewed as integers, the comparison is opposite because
+        # of the units chosen
+        assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8'))
+
+        # should raise between datetime and timedelta
+        #
+        # TODO: Allowing unsafe casting by
+        #       default in ufuncs strikes again... :(
+        a = np.array(3, dtype='m8[h]')
+        b = np.array('1999-03-12T12', dtype='M8[s]')
+        #assert_raises(TypeError, np.minimum, a, b)
+        #assert_raises(TypeError, np.maximum, a, b)
+        #assert_raises(TypeError, np.fmin, a, b)
+        #assert_raises(TypeError, np.fmax, a, b)
+        assert_raises(TypeError, np.minimum, a, b, casting='same_kind')
+        assert_raises(TypeError, np.maximum, a, b, casting='same_kind')
+        assert_raises(TypeError, np.fmin, a, b, casting='same_kind')
+        assert_raises(TypeError, np.fmax, a, b, casting='same_kind')
+
+    def test_hours(self):
+        t = np.ones(3, dtype='M8[s]')
+        t[0] = 60*60*24 + 60*60*10
+        assert_(t[0].item().hour == 10)
+
+    def test_divisor_conversion_year(self):
+        assert_(np.dtype('M8[Y/4]') == np.dtype('M8[3M]'))
+        assert_(np.dtype('M8[Y/13]') == np.dtype('M8[4W]'))
+        assert_(np.dtype('M8[3Y/73]') == np.dtype('M8[15D]'))
+
+    def test_divisor_conversion_month(self):
+        assert_(np.dtype('M8[M/2]') == np.dtype('M8[2W]'))
+        assert_(np.dtype('M8[M/15]') == np.dtype('M8[2D]'))
+        assert_(np.dtype('M8[3M/40]') == np.dtype('M8[54h]'))
+
+    def test_divisor_conversion_week(self):
+        assert_(np.dtype('m8[W/7]') == np.dtype('m8[D]'))
+        assert_(np.dtype('m8[3W/14]') == np.dtype('m8[36h]'))
+        assert_(np.dtype('m8[5W/140]') == np.dtype('m8[360m]'))
+
+    def test_divisor_conversion_day(self):
+        assert_(np.dtype('M8[D/12]') == np.dtype('M8[2h]'))
+        assert_(np.dtype('M8[D/120]') == np.dtype('M8[12m]'))
+        assert_(np.dtype('M8[3D/960]') == np.dtype('M8[270s]'))
+
+    def test_divisor_conversion_hour(self):
+        assert_(np.dtype('m8[h/30]') == np.dtype('m8[2m]'))
+        assert_(np.dtype('m8[3h/300]') == np.dtype('m8[36s]'))
+
+    def test_divisor_conversion_minute(self):
+        assert_(np.dtype('m8[m/30]') == np.dtype('m8[2s]'))
+        assert_(np.dtype('m8[3m/300]') == np.dtype('m8[600ms]'))
+
+    def test_divisor_conversion_second(self):
+        assert_(np.dtype('m8[s/100]') == np.dtype('m8[10ms]'))
+        assert_(np.dtype('m8[3s/10000]') == np.dtype('m8[300us]'))
+
+    def test_divisor_conversion_fs(self):
+        assert_(np.dtype('M8[fs/100]') == np.dtype('M8[10as]'))
+        self.assertRaises(ValueError, lambda: np.dtype('M8[3fs/10000]'))
+
+    def test_divisor_conversion_as(self):
+        self.assertRaises(ValueError, lambda: np.dtype('M8[as/10]'))
+
+    def test_string_parser_variants(self):
+        # Allow space instead of 'T' between date and time
+        assert_equal(np.array(['1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                     np.array(['1980-02-29 01:02:03'], np.dtype('M8[s]')))
+        # Allow negative years
+        assert_equal(np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                     np.array(['-1980-02-29 01:02:03'], np.dtype('M8[s]')))
+        # UTC specifier
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                np.array(['-1980-02-29 01:02:03Z'], np.dtype('M8[s]')))
+        # Time zone offset
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-29T02:02:03'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:32:03-0130'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-28T22:32:03'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:02:03+01:30'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-29T02:32:03.506'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:32:03.506-02'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('1977-03-02T12:30-0230'),
+                         np.datetime64('1977-03-02T15:00'))
+
+    def test_string_parser_error_check(self):
+        # Arbitrary bad string
+        assert_raises(ValueError, np.array, ['badvalue'], np.dtype('M8[us]'))
+        # Character after year must be '-'
+        assert_raises(ValueError, np.array, ['1980X'], np.dtype('M8[us]'))
+        # Cannot have trailing '-'
+        assert_raises(ValueError, np.array, ['1980-'], np.dtype('M8[us]'))
+        # Month must be in range [1,12]
+        assert_raises(ValueError, np.array, ['1980-00'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-13'], np.dtype('M8[us]'))
+        # Month must have two digits
+        assert_raises(ValueError, np.array, ['1980-1'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-1-02'], np.dtype('M8[us]'))
+        # 'Mor' is not a valid month
+        assert_raises(ValueError, np.array, ['1980-Mor'], np.dtype('M8[us]'))
+        # Cannot have trailing '-'
+        assert_raises(ValueError, np.array, ['1980-01-'], np.dtype('M8[us]'))
+        # Day must be in range [1,len(month)]
+        assert_raises(ValueError, np.array, ['1980-01-0'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-01-00'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-01-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1979-02-29'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-30'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-03-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-04-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-05-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-06-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-07-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-08-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-09-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-10-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-11-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-12-32'], np.dtype('M8[us]'))
+        # Cannot have trailing characters
+        assert_raises(ValueError, np.array, ['1980-02-03%'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 q'],
+                                                        np.dtype('M8[us]'))
+
+        # Hours must be in range [0, 23]
+        assert_raises(ValueError, np.array, ['1980-02-03 25'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03T25'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 24:01'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03T24:01'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 -1'],
+                                                        np.dtype('M8[us]'))
+        # No trailing ':'
+        assert_raises(ValueError, np.array, ['1980-02-03 01:'],
+                                                        np.dtype('M8[us]'))
+        # Minutes must be in range [0, 59]
+        assert_raises(ValueError, np.array, ['1980-02-03 01:-1'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 01:60'],
+                                                        np.dtype('M8[us]'))
+        # No trailing ':'
+        assert_raises(ValueError, np.array, ['1980-02-03 01:60:'],
+                                                        np.dtype('M8[us]'))
+        # Seconds must be in range [0, 59]
+        assert_raises(ValueError, np.array, ['1980-02-03 01:10:-1'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 01:01:60'],
+                                                        np.dtype('M8[us]'))
+        # Timezone offset must within a reasonable range
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+0661'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+2500'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-0070'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-3000'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-25:00'],
+                                                            np.dtype('M8[us]'))
+
+    def test_creation_overflow(self):
+        date = '1980-03-23 20:00:00'
+        timesteps = np.array([date], dtype='datetime64[s]')[0].astype(np.int64)
+        for unit in ['ms', 'us', 'ns']:
+            timesteps *= 1000
+            x = np.array([date], dtype='datetime64[%s]' % unit)
+
+            assert_equal(timesteps, x[0].astype(np.int64),
+                         err_msg='Datetime conversion error for unit %s' % unit)
+
+        assert_equal(x[0].astype(np.int64), 322689600000000000)
+
+    def test_datetime_as_string(self):
+        # Check all the units with default string conversion
+        date = '1959-10-13'
+        datetime = '1959-10-13T12:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'Y')),
+                     '1959')
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'M')),
+                     '1959-10')
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'D')),
+                     '1959-10-13')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'h')),
+                     '1959-10-13T12')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'm')),
+                     '1959-10-13T12:34')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 's')),
+                     '1959-10-13T12:34:56')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ms')),
+                     '1959-10-13T12:34:56.789')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'us')),
+                     '1959-10-13T12:34:56.789012')
+
+        datetime = '1969-12-31T23:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')),
+                     '1969-12-31T23:34:56.789012345')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')),
+                     '1969-12-31T23:34:56.789012345678')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')),
+                     '1969-12-31T23:34:56.789012345678901')
+
+        datetime = '1969-12-31T23:59:57.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')),
+                     datetime)
+        datetime = '1970-01-01T00:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')),
+                     '1970-01-01T00:34:56.789012345')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')),
+                     '1970-01-01T00:34:56.789012345678')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')),
+                     '1970-01-01T00:34:56.789012345678901')
+
+        datetime = '1970-01-01T00:00:05.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')),
+                     datetime)
+
+        # String conversion with the unit= parameter
+        a = np.datetime64('2032-07-18T12:23:34.123456', 'us')
+        assert_equal(np.datetime_as_string(a, unit='Y', casting='unsafe'),
+                            '2032')
+        assert_equal(np.datetime_as_string(a, unit='M', casting='unsafe'),
+                            '2032-07')
+        assert_equal(np.datetime_as_string(a, unit='W', casting='unsafe'),
+                            '2032-07-18')
+        assert_equal(np.datetime_as_string(a, unit='D', casting='unsafe'),
+                            '2032-07-18')
+        assert_equal(np.datetime_as_string(a, unit='h'), '2032-07-18T12')
+        assert_equal(np.datetime_as_string(a, unit='m'),
+                            '2032-07-18T12:23')
+        assert_equal(np.datetime_as_string(a, unit='s'),
+                            '2032-07-18T12:23:34')
+        assert_equal(np.datetime_as_string(a, unit='ms'),
+                            '2032-07-18T12:23:34.123')
+        assert_equal(np.datetime_as_string(a, unit='us'),
+                            '2032-07-18T12:23:34.123456')
+        assert_equal(np.datetime_as_string(a, unit='ns'),
+                            '2032-07-18T12:23:34.123456000')
+        assert_equal(np.datetime_as_string(a, unit='ps'),
+                            '2032-07-18T12:23:34.123456000000')
+        assert_equal(np.datetime_as_string(a, unit='fs'),
+                            '2032-07-18T12:23:34.123456000000000')
+        assert_equal(np.datetime_as_string(a, unit='as'),
+                            '2032-07-18T12:23:34.123456000000000000')
+
+        # unit='auto' parameter
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34.123456', 'us'), unit='auto'),
+                '2032-07-18T12:23:34.123456')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34.12', 'us'), unit='auto'),
+                '2032-07-18T12:23:34.120')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34', 'us'), unit='auto'),
+                '2032-07-18T12:23:34')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:00', 'us'), unit='auto'),
+                '2032-07-18T12:23')
+        # 'auto' doesn't split up hour and minute
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:00:00', 'us'), unit='auto'),
+                '2032-07-18T12:00')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T00:00:00', 'us'), unit='auto'),
+                '2032-07-18')
+        # 'auto' doesn't split up the date
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-01T00:00:00', 'us'), unit='auto'),
+                '2032-07-01')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-01-01T00:00:00', 'us'), unit='auto'),
+                '2032-01-01')
+
+    @dec.skipif(not _has_pytz, "The pytz module is not available.")
+    def test_datetime_as_string_timezone(self):
+        # timezone='local' vs 'UTC'
+        a = np.datetime64('2010-03-15T06:30', 'm')
+        assert_equal(np.datetime_as_string(a),
+                '2010-03-15T06:30')
+        assert_equal(np.datetime_as_string(a, timezone='naive'),
+                '2010-03-15T06:30')
+        assert_equal(np.datetime_as_string(a, timezone='UTC'),
+                '2010-03-15T06:30Z')
+        assert_(np.datetime_as_string(a, timezone='local') !=
+                '2010-03-15T06:30')
+
+        b = np.datetime64('2010-02-15T06:30', 'm')
+
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Central')),
+                     '2010-03-15T01:30-0500')
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Eastern')),
+                     '2010-03-15T02:30-0400')
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Pacific')),
+                     '2010-03-14T23:30-0700')
+
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Central')),
+                     '2010-02-15T00:30-0600')
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Eastern')),
+                     '2010-02-15T01:30-0500')
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Pacific')),
+                     '2010-02-14T22:30-0800')
+
+        # Dates to strings with a timezone attached is disabled by default
+        assert_raises(TypeError, np.datetime_as_string, a, unit='D',
+                           timezone=tz('US/Pacific'))
+        # Check that we can print out the date in the specified time zone
+        assert_equal(np.datetime_as_string(a, unit='D',
+                           timezone=tz('US/Pacific'), casting='unsafe'),
+                     '2010-03-14')
+        assert_equal(np.datetime_as_string(b, unit='D',
+                           timezone=tz('US/Central'), casting='unsafe'),
+                     '2010-02-15')
+
+    def test_datetime_arange(self):
+        # With two datetimes provided as strings
+        a = np.arange('2010-01-05', '2010-01-10', dtype='M8[D]')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.array(['2010-01-05', '2010-01-06', '2010-01-07',
+                      '2010-01-08', '2010-01-09'], dtype='M8[D]'))
+
+        a = np.arange('1950-02-10', '1950-02-06', -1, dtype='M8[D]')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.array(['1950-02-10', '1950-02-09', '1950-02-08',
+                      '1950-02-07'], dtype='M8[D]'))
+
+        # Unit should be detected as months here
+        a = np.arange('1969-05', '1970-05', 2, dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[M]'))
+        assert_equal(a,
+            np.datetime64('1969-05') + np.arange(12, step=2))
+
+        # datetime, integer|timedelta works as well
+        # produces arange (start, start + stop) in this case
+        a = np.arange('1969', 18, 3, dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[Y]'))
+        assert_equal(a,
+            np.datetime64('1969') + np.arange(18, step=3))
+        a = np.arange('1969-12-19', 22, np.timedelta64(2), dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.datetime64('1969-12-19') + np.arange(22, step=2))
+
+        # Step of 0 is disallowed
+        assert_raises(ValueError, np.arange, np.datetime64('today'),
+                                np.datetime64('today') + 3, 0)
+        # Promotion across nonlinear unit boundaries is disallowed
+        assert_raises(TypeError, np.arange, np.datetime64('2011-03-01', 'D'),
+                                np.timedelta64(5, 'M'))
+        assert_raises(TypeError, np.arange,
+                                np.datetime64('2012-02-03T14', 's'),
+                                np.timedelta64(5, 'Y'))
+
+    def test_datetime_arange_no_dtype(self):
+        d = np.array('2010-01-04', dtype="M8[D]")
+        assert_equal(np.arange(d, d + 1), d)
+        assert_raises(ValueError, np.arange, d)
+
+    def test_timedelta_arange(self):
+        a = np.arange(3, 10, dtype='m8')
+        assert_equal(a.dtype, np.dtype('m8'))
+        assert_equal(a, np.timedelta64(0) + np.arange(3, 10))
+
+        a = np.arange(np.timedelta64(3, 's'), 10, 2, dtype='m8')
+        assert_equal(a.dtype, np.dtype('m8[s]'))
+        assert_equal(a, np.timedelta64(0, 's') + np.arange(3, 10, 2))
+
+        # Step of 0 is disallowed
+        assert_raises(ValueError, np.arange, np.timedelta64(0),
+                                np.timedelta64(5), 0)
+        # Promotion across nonlinear unit boundaries is disallowed
+        assert_raises(TypeError, np.arange, np.timedelta64(0, 'D'),
+                                np.timedelta64(5, 'M'))
+        assert_raises(TypeError, np.arange, np.timedelta64(0, 'Y'),
+                                np.timedelta64(5, 'D'))
+
+    def test_timedelta_arange_no_dtype(self):
+        d = np.array(5, dtype="m8[D]")
+        assert_equal(np.arange(d, d + 1), d)
+        assert_raises(ValueError, np.arange, d)
+
+    def test_datetime_maximum_reduce(self):
+        a = np.array(['2010-01-02', '1999-03-14', '1833-03'], dtype='M8[D]')
+        assert_equal(np.maximum.reduce(a).dtype, np.dtype('M8[D]'))
+        assert_equal(np.maximum.reduce(a),
+                     np.datetime64('2010-01-02'))
+
+        a = np.array([1, 4, 0, 7, 2], dtype='m8[s]')
+        assert_equal(np.maximum.reduce(a).dtype, np.dtype('m8[s]'))
+        assert_equal(np.maximum.reduce(a),
+                     np.timedelta64(7, 's'))
+
+    def test_datetime_busday_offset(self):
+        # First Monday in June
+        assert_equal(
+            np.busday_offset('2011-06', 0, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-06'))
+        # Last Monday in June
+        assert_equal(
+            np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-27'))
+        assert_equal(
+            np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-27'))
+
+        # Default M-F business days, different roll modes
+        assert_equal(np.busday_offset('2010-08', 0, roll='backward'),
+                     np.datetime64('2010-07-30'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='preceding'),
+                     np.datetime64('2010-07-30'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='modifiedpreceding'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='modifiedfollowing'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='forward'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='following'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-10-30', 0, roll='following'),
+                     np.datetime64('2010-11-01'))
+        assert_equal(
+                np.busday_offset('2010-10-30', 0, roll='modifiedfollowing'),
+                np.datetime64('2010-10-29'))
+        assert_equal(
+                np.busday_offset('2010-10-30', 0, roll='modifiedpreceding'),
+                np.datetime64('2010-10-29'))
+        assert_equal(
+                np.busday_offset('2010-10-16', 0, roll='modifiedfollowing'),
+                np.datetime64('2010-10-18'))
+        assert_equal(
+                np.busday_offset('2010-10-16', 0, roll='modifiedpreceding'),
+                np.datetime64('2010-10-15'))
+        # roll='raise' by default
+        assert_raises(ValueError, np.busday_offset, '2011-06-04', 0)
+
+        # Bigger offset values
+        assert_equal(np.busday_offset('2006-02-01', 25),
+                     np.datetime64('2006-03-08'))
+        assert_equal(np.busday_offset('2006-03-08', -25),
+                     np.datetime64('2006-02-01'))
+        assert_equal(np.busday_offset('2007-02-25', 11, weekmask='SatSun'),
+                     np.datetime64('2007-04-07'))
+        assert_equal(np.busday_offset('2007-04-07', -11, weekmask='SatSun'),
+                     np.datetime64('2007-02-25'))
+
+        # NaT values when roll is not raise
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='nat'),
+                     np.datetime64('NaT'))
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='following'),
+                     np.datetime64('NaT'))
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='preceding'),
+                     np.datetime64('NaT'))
+
+
+    def test_datetime_busdaycalendar(self):
+        # Check that it removes NaT, duplicates, and weekends
+        # and sorts the result.
+        bdd = np.busdaycalendar(
+            holidays=['NaT', '2011-01-17', '2011-03-06', 'NaT',
+                       '2011-12-26', '2011-05-30', '2011-01-17'])
+        assert_equal(bdd.holidays,
+            np.array(['2011-01-17', '2011-05-30', '2011-12-26'], dtype='M8'))
+        # Default M-F weekmask
+        assert_equal(bdd.weekmask, np.array([1, 1, 1, 1, 1, 0, 0], dtype='?'))
+
+        # Check string weekmask with varying whitespace.
+        bdd = np.busdaycalendar(weekmask="Sun TueWed  Thu\tFri")
+        assert_equal(bdd.weekmask, np.array([0, 1, 1, 1, 1, 0, 1], dtype='?'))
+
+        # Check length 7 0/1 string
+        bdd = np.busdaycalendar(weekmask="0011001")
+        assert_equal(bdd.weekmask, np.array([0, 0, 1, 1, 0, 0, 1], dtype='?'))
+
+        # Check length 7 string weekmask.
+        bdd = np.busdaycalendar(weekmask="Mon Tue")
+        assert_equal(bdd.weekmask, np.array([1, 1, 0, 0, 0, 0, 0], dtype='?'))
+
+        # All-zeros weekmask should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask=[0, 0, 0, 0, 0, 0, 0])
+        # weekday names must be correct case
+        assert_raises(ValueError, np.busdaycalendar, weekmask="satsun")
+        # All-zeros weekmask should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask="")
+        # Invalid weekday name codes should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Mon Tue We")
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Max")
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Monday Tue")
+
+    def test_datetime_busday_holidays_offset(self):
+        # With exactly one holiday
+        assert_equal(
+            np.busday_offset('2011-11-10', 1, holidays=['2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-04', 5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-10', 5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-18'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1, holidays=['2011-11-11']),
+            np.datetime64('2011-11-10'))
+        assert_equal(
+            np.busday_offset('2011-11-18', -5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-10'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-04'))
+        # With the holiday appearing twice
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', '2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-11-11', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With a NaT holiday
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', 'NaT']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['NaT', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With another holiday after
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-10'))
+        # With another holiday before
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-10-10', '2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-10-10', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With another holiday before and after
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-10-10', '2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-10-10', '2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-10'))
+
+        # A bigger forward jump across more than one week/holiday
+        holidays = ['2011-10-10', '2011-11-11', '2011-11-24',
+                  '2011-12-25', '2011-05-30', '2011-02-21',
+                  '2011-12-26', '2012-01-02']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+        assert_equal(
+            np.busday_offset('2011-10-03', 4, holidays=holidays),
+            np.busday_offset('2011-10-03', 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 5, holidays=holidays),
+            np.busday_offset('2011-10-03', 5 + 1))
+        assert_equal(
+            np.busday_offset('2011-10-03', 27, holidays=holidays),
+            np.busday_offset('2011-10-03', 27 + 1))
+        assert_equal(
+            np.busday_offset('2011-10-03', 28, holidays=holidays),
+            np.busday_offset('2011-10-03', 28 + 2))
+        assert_equal(
+            np.busday_offset('2011-10-03', 35, holidays=holidays),
+            np.busday_offset('2011-10-03', 35 + 2))
+        assert_equal(
+            np.busday_offset('2011-10-03', 36, holidays=holidays),
+            np.busday_offset('2011-10-03', 36 + 3))
+        assert_equal(
+            np.busday_offset('2011-10-03', 56, holidays=holidays),
+            np.busday_offset('2011-10-03', 56 + 3))
+        assert_equal(
+            np.busday_offset('2011-10-03', 57, holidays=holidays),
+            np.busday_offset('2011-10-03', 57 + 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 60, holidays=holidays),
+            np.busday_offset('2011-10-03', 60 + 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 61, holidays=holidays),
+            np.busday_offset('2011-10-03', 61 + 5))
+        assert_equal(
+            np.busday_offset('2011-10-03', 61, busdaycal=bdd),
+            np.busday_offset('2011-10-03', 61 + 5))
+        # A bigger backward jump across more than one week/holiday
+        assert_equal(
+            np.busday_offset('2012-01-03', -1, holidays=holidays),
+            np.busday_offset('2012-01-03', -1 - 1))
+        assert_equal(
+            np.busday_offset('2012-01-03', -4, holidays=holidays),
+            np.busday_offset('2012-01-03', -4 - 1))
+        assert_equal(
+            np.busday_offset('2012-01-03', -5, holidays=holidays),
+            np.busday_offset('2012-01-03', -5 - 2))
+        assert_equal(
+            np.busday_offset('2012-01-03', -25, holidays=holidays),
+            np.busday_offset('2012-01-03', -25 - 2))
+        assert_equal(
+            np.busday_offset('2012-01-03', -26, holidays=holidays),
+            np.busday_offset('2012-01-03', -26 - 3))
+        assert_equal(
+            np.busday_offset('2012-01-03', -33, holidays=holidays),
+            np.busday_offset('2012-01-03', -33 - 3))
+        assert_equal(
+            np.busday_offset('2012-01-03', -34, holidays=holidays),
+            np.busday_offset('2012-01-03', -34 - 4))
+        assert_equal(
+            np.busday_offset('2012-01-03', -56, holidays=holidays),
+            np.busday_offset('2012-01-03', -56 - 4))
+        assert_equal(
+            np.busday_offset('2012-01-03', -57, holidays=holidays),
+            np.busday_offset('2012-01-03', -57 - 5))
+        assert_equal(
+            np.busday_offset('2012-01-03', -57, busdaycal=bdd),
+            np.busday_offset('2012-01-03', -57 - 5))
+
+        # Can't supply both a weekmask/holidays and busdaycal
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', -15,
+                        weekmask='1111100', busdaycal=bdd)
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', -15,
+                        holidays=holidays, busdaycal=bdd)
+
+        # Roll with the holidays
+        assert_equal(
+            np.busday_offset('2011-12-25', 0,
+                roll='forward', holidays=holidays),
+            np.datetime64('2011-12-27'))
+        assert_equal(
+            np.busday_offset('2011-12-26', 0,
+                roll='forward', holidays=holidays),
+            np.datetime64('2011-12-27'))
+        assert_equal(
+            np.busday_offset('2011-12-26', 0,
+                roll='backward', holidays=holidays),
+            np.datetime64('2011-12-23'))
+        assert_equal(
+            np.busday_offset('2012-02-27', 0,
+                roll='modifiedfollowing',
+                holidays=['2012-02-27', '2012-02-26', '2012-02-28',
+                          '2012-03-01', '2012-02-29']),
+            np.datetime64('2012-02-24'))
+        assert_equal(
+            np.busday_offset('2012-03-06', 0,
+                roll='modifiedpreceding',
+                holidays=['2012-03-02', '2012-03-03', '2012-03-01',
+                          '2012-03-05', '2012-03-07', '2012-03-06']),
+            np.datetime64('2012-03-08'))
+
+    def test_datetime_busday_holidays_count(self):
+        holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24',
+                    '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17',
+                    '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30',
+                    '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+
+        # Validate against busday_offset broadcast against
+        # a range of offsets
+        dates = np.busday_offset('2011-01-01', np.arange(366),
+                        roll='forward', busdaycal=bdd)
+        assert_equal(np.busday_count('2011-01-01', dates, busdaycal=bdd),
+                     np.arange(366))
+        # Returns negative value when reversed
+        assert_equal(np.busday_count(dates, '2011-01-01', busdaycal=bdd),
+                     -np.arange(366))
+
+        dates = np.busday_offset('2011-12-31', -np.arange(366),
+                        roll='forward', busdaycal=bdd)
+        assert_equal(np.busday_count(dates, '2011-12-31', busdaycal=bdd),
+                     np.arange(366))
+        # Returns negative value when reversed
+        assert_equal(np.busday_count('2011-12-31', dates, busdaycal=bdd),
+                     -np.arange(366))
+
+        # Can't supply both a weekmask/holidays and busdaycal
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03',
+                        weekmask='1111100', busdaycal=bdd)
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03',
+                        holidays=holidays, busdaycal=bdd)
+
+        # Number of Mondays in March 2011
+        assert_equal(np.busday_count('2011-03', '2011-04', weekmask='Mon'), 4)
+        # Returns negative value when reversed
+        assert_equal(np.busday_count('2011-04', '2011-03', weekmask='Mon'), -4)
+
+    def test_datetime_is_busday(self):
+        holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24',
+                    '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17',
+                    '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30',
+                    '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10',
+                    'NaT']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+
+        # Weekend/weekday tests
+        assert_equal(np.is_busday('2011-01-01'), False)
+        assert_equal(np.is_busday('2011-01-02'), False)
+        assert_equal(np.is_busday('2011-01-03'), True)
+
+        # All the holidays are not business days
+        assert_equal(np.is_busday(holidays, busdaycal=bdd),
+                     np.zeros(len(holidays), dtype='?'))
+
+    def test_datetime_y2038(self):
+        # Test parsing on either side of the Y2038 boundary
+        a = np.datetime64('2038-01-19T03:14:07')
+        assert_equal(a.view(np.int64), 2**31 - 1)
+        a = np.datetime64('2038-01-19T03:14:08')
+        assert_equal(a.view(np.int64), 2**31)
+
+        # Test parsing on either side of the Y2038 boundary with
+        # a manually specified timezone offset
+        with assert_warns(DeprecationWarning):
+            a = np.datetime64('2038-01-19T04:14:07+0100')
+            assert_equal(a.view(np.int64), 2**31 - 1)
+        with assert_warns(DeprecationWarning):
+            a = np.datetime64('2038-01-19T04:14:08+0100')
+            assert_equal(a.view(np.int64), 2**31)
+
+        # Test parsing a date after Y2038
+        a = np.datetime64('2038-01-20T13:21:14')
+        assert_equal(str(a), '2038-01-20T13:21:14')
+
+class TestDateTimeData(TestCase):
+
+    def test_basic(self):
+        a = np.array(['1980-03-23'], dtype=np.datetime64)
+        assert_equal(np.datetime_data(a.dtype), ('D', 1))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
new file mode 100644
index 0000000000..e828b879f3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
@@ -0,0 +1,703 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.core.multiarray import _vec_string
+from numpy.compat import asbytes, asbytes_nested, sixu
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal
+)
+
+kw_unicode_true = {'unicode': True}  # make 2to3 work properly
+kw_unicode_false = {'unicode': False}
+
+class TestBasic(TestCase):
+    def test_from_object_array(self):
+        A = np.array([['abc', 2],
+                      ['long   ', '0123456789']], dtype='O')
+        B = np.char.array(A)
+        assert_equal(B.dtype.itemsize, 10)
+        assert_array_equal(B, asbytes_nested([['abc', '2'],
+                                              ['long', '0123456789']]))
+
+    def test_from_object_array_unicode(self):
+        A = np.array([['abc', sixu('Sigma \u03a3')],
+                      ['long   ', '0123456789']], dtype='O')
+        self.assertRaises(ValueError, np.char.array, (A,))
+        B = np.char.array(A, **kw_unicode_true)
+        assert_equal(B.dtype.itemsize, 10 * np.array('a', 'U').dtype.itemsize)
+        assert_array_equal(B, [['abc', sixu('Sigma \u03a3')],
+                               ['long', '0123456789']])
+
+    def test_from_string_array(self):
+        A = np.array(asbytes_nested([['abc', 'foo'],
+                                     ['long   ', '0123456789']]))
+        assert_equal(A.dtype.type, np.string_)
+        B = np.char.array(A)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+        B[0, 0] = 'changed'
+        assert_(B[0, 0] != A[0, 0])
+        C = np.char.asarray(A)
+        assert_array_equal(C, A)
+        assert_equal(C.dtype, A.dtype)
+        C[0, 0] = 'changed again'
+        assert_(C[0, 0] != B[0, 0])
+        assert_(C[0, 0] == A[0, 0])
+
+    def test_from_unicode_array(self):
+        A = np.array([['abc', sixu('Sigma \u03a3')],
+                      ['long   ', '0123456789']])
+        assert_equal(A.dtype.type, np.unicode_)
+        B = np.char.array(A)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+        B = np.char.array(A, **kw_unicode_true)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+
+        def fail():
+            np.char.array(A, **kw_unicode_false)
+
+        self.assertRaises(UnicodeEncodeError, fail)
+
+    def test_unicode_upconvert(self):
+        A = np.char.array(['abc'])
+        B = np.char.array([sixu('\u03a3')])
+        assert_(issubclass((A + B).dtype.type, np.unicode_))
+
+    def test_from_string(self):
+        A = np.char.array(asbytes('abc'))
+        assert_equal(len(A), 1)
+        assert_equal(len(A[0]), 3)
+        assert_(issubclass(A.dtype.type, np.string_))
+
+    def test_from_unicode(self):
+        A = np.char.array(sixu('\u03a3'))
+        assert_equal(len(A), 1)
+        assert_equal(len(A[0]), 1)
+        assert_equal(A.itemsize, 4)
+        assert_(issubclass(A.dtype.type, np.unicode_))
+
+class TestVecString(TestCase):
+    def test_non_existent_method(self):
+
+        def fail():
+            _vec_string('a', np.string_, 'bogus')
+
+        self.assertRaises(AttributeError, fail)
+
+    def test_non_string_array(self):
+
+        def fail():
+            _vec_string(1, np.string_, 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_args_tuple(self):
+
+        def fail():
+            _vec_string(['a'], np.string_, 'strip', 1)
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_type_descr(self):
+
+        def fail():
+            _vec_string(['a'], 'BOGUS', 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_function_args(self):
+
+        def fail():
+            _vec_string(['a'], np.string_, 'strip', (1,))
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_result_type(self):
+
+        def fail():
+            _vec_string(['a'], np.integer, 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_broadcast_error(self):
+
+        def fail():
+            _vec_string([['abc', 'def']], np.integer, 'find', (['a', 'd', 'j'],))
+
+        self.assertRaises(ValueError, fail)
+
+
+class TestWhitespace(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc ', '123  '],
+                           ['789 ', 'xyz ']]).view(np.chararray)
+        self.B = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+
+    def test1(self):
+        assert_(np.all(self.A == self.B))
+        assert_(np.all(self.A >= self.B))
+        assert_(np.all(self.A <= self.B))
+        assert_(not np.any(self.A > self.B))
+        assert_(not np.any(self.A < self.B))
+        assert_(not np.any(self.A != self.B))
+
+class TestChar(TestCase):
+    def setUp(self):
+        self.A = np.array('abc1', dtype='c').view(np.chararray)
+
+    def test_it(self):
+        assert_equal(self.A.shape, (4,))
+        assert_equal(self.A.upper()[:2].tobytes(), asbytes('AB'))
+
+class TestComparisons(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+        self.B = np.array([['efg', '123  '],
+                           ['051', 'tuv']]).view(np.chararray)
+
+    def test_not_equal(self):
+        assert_array_equal((self.A != self.B), [[True, False], [True, True]])
+
+    def test_equal(self):
+        assert_array_equal((self.A == self.B), [[False, True], [False, False]])
+
+    def test_greater_equal(self):
+        assert_array_equal((self.A >= self.B), [[False, True], [True, True]])
+
+    def test_less_equal(self):
+        assert_array_equal((self.A <= self.B), [[True, True], [False, False]])
+
+    def test_greater(self):
+        assert_array_equal((self.A > self.B), [[False, False], [True, True]])
+
+    def test_less(self):
+        assert_array_equal((self.A < self.B), [[True, False], [False, False]])
+
+class TestComparisonsMixed1(TestComparisons):
+    """Ticket #1276"""
+
+    def setUp(self):
+        TestComparisons.setUp(self)
+        self.B = np.array([['efg', '123  '],
+                           ['051', 'tuv']], np.unicode_).view(np.chararray)
+
+class TestComparisonsMixed2(TestComparisons):
+    """Ticket #1276"""
+
+    def setUp(self):
+        TestComparisons.setUp(self)
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']], np.unicode_).view(np.chararray)
+
+class TestInformation(TestCase):
+    def setUp(self):
+        self.A = np.array([[' abc ', ''],
+                           ['12345', 'MixedCase'],
+                           ['123 \t 345 \0 ', 'UPPER']]).view(np.chararray)
+        self.B = np.array([[sixu(' \u03a3 '), sixu('')],
+                           [sixu('12345'), sixu('MixedCase')],
+                           [sixu('123 \t 345 \0 '), sixu('UPPER')]]).view(np.chararray)
+
+    def test_len(self):
+        assert_(issubclass(np.char.str_len(self.A).dtype.type, np.integer))
+        assert_array_equal(np.char.str_len(self.A), [[5, 0], [5, 9], [12, 5]])
+        assert_array_equal(np.char.str_len(self.B), [[3, 0], [5, 9], [12, 5]])
+
+    def test_count(self):
+        assert_(issubclass(self.A.count('').dtype.type, np.integer))
+        assert_array_equal(self.A.count('a'), [[1, 0], [0, 1], [0, 0]])
+        assert_array_equal(self.A.count('123'), [[0, 0], [1, 0], [1, 0]])
+        # Python doesn't seem to like counting NULL characters
+        # assert_array_equal(self.A.count('\0'), [[0, 0], [0, 0], [1, 0]])
+        assert_array_equal(self.A.count('a', 0, 2), [[1, 0], [0, 0], [0, 0]])
+        assert_array_equal(self.B.count('a'), [[0, 0], [0, 1], [0, 0]])
+        assert_array_equal(self.B.count('123'), [[0, 0], [1, 0], [1, 0]])
+        # assert_array_equal(self.B.count('\0'), [[0, 0], [0, 0], [1, 0]])
+
+    def test_endswith(self):
+        assert_(issubclass(self.A.endswith('').dtype.type, np.bool_))
+        assert_array_equal(self.A.endswith(' '), [[1, 0], [0, 0], [1, 0]])
+        assert_array_equal(self.A.endswith('3', 0, 3), [[0, 0], [1, 0], [1, 0]])
+
+        def fail():
+            self.A.endswith('3', 'fdjk')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_find(self):
+        assert_(issubclass(self.A.find('a').dtype.type, np.integer))
+        assert_array_equal(self.A.find('a'), [[1, -1], [-1, 6], [-1, -1]])
+        assert_array_equal(self.A.find('3'), [[-1, -1], [2, -1], [2, -1]])
+        assert_array_equal(self.A.find('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
+        assert_array_equal(self.A.find(['1', 'P']), [[-1, -1], [0, -1], [0, 1]])
+
+    def test_index(self):
+
+        def fail():
+            self.A.index('a')
+
+        self.assertRaises(ValueError, fail)
+        assert_(np.char.index('abcba', 'b') == 1)
+        assert_(issubclass(np.char.index('abcba', 'b').dtype.type, np.integer))
+
+    def test_isalnum(self):
+        assert_(issubclass(self.A.isalnum().dtype.type, np.bool_))
+        assert_array_equal(self.A.isalnum(), [[False, False], [True, True], [False, True]])
+
+    def test_isalpha(self):
+        assert_(issubclass(self.A.isalpha().dtype.type, np.bool_))
+        assert_array_equal(self.A.isalpha(), [[False, False], [False, True], [False, True]])
+
+    def test_isdigit(self):
+        assert_(issubclass(self.A.isdigit().dtype.type, np.bool_))
+        assert_array_equal(self.A.isdigit(), [[False, False], [True, False], [False, False]])
+
+    def test_islower(self):
+        assert_(issubclass(self.A.islower().dtype.type, np.bool_))
+        assert_array_equal(self.A.islower(), [[True, False], [False, False], [False, False]])
+
+    def test_isspace(self):
+        assert_(issubclass(self.A.isspace().dtype.type, np.bool_))
+        assert_array_equal(self.A.isspace(), [[False, False], [False, False], [False, False]])
+
+    def test_istitle(self):
+        assert_(issubclass(self.A.istitle().dtype.type, np.bool_))
+        assert_array_equal(self.A.istitle(), [[False, False], [False, False], [False, False]])
+
+    def test_isupper(self):
+        assert_(issubclass(self.A.isupper().dtype.type, np.bool_))
+        assert_array_equal(self.A.isupper(), [[False, False], [False, False], [False, True]])
+
+    def test_rfind(self):
+        assert_(issubclass(self.A.rfind('a').dtype.type, np.integer))
+        assert_array_equal(self.A.rfind('a'), [[1, -1], [-1, 6], [-1, -1]])
+        assert_array_equal(self.A.rfind('3'), [[-1, -1], [2, -1], [6, -1]])
+        assert_array_equal(self.A.rfind('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
+        assert_array_equal(self.A.rfind(['1', 'P']), [[-1, -1], [0, -1], [0, 2]])
+
+    def test_rindex(self):
+
+        def fail():
+            self.A.rindex('a')
+
+        self.assertRaises(ValueError, fail)
+        assert_(np.char.rindex('abcba', 'b') == 3)
+        assert_(issubclass(np.char.rindex('abcba', 'b').dtype.type, np.integer))
+
+    def test_startswith(self):
+        assert_(issubclass(self.A.startswith('').dtype.type, np.bool_))
+        assert_array_equal(self.A.startswith(' '), [[1, 0], [0, 0], [0, 0]])
+        assert_array_equal(self.A.startswith('1', 0, 3), [[0, 0], [1, 0], [1, 0]])
+
+        def fail():
+            self.A.startswith('3', 'fdjk')
+
+        self.assertRaises(TypeError, fail)
+
+
+class TestMethods(TestCase):
+    def setUp(self):
+        self.A = np.array([[' abc ', ''],
+                           ['12345', 'MixedCase'],
+                           ['123 \t 345 \0 ', 'UPPER']],
+                          dtype='S').view(np.chararray)
+        self.B = np.array([[sixu(' \u03a3 '), sixu('')],
+                           [sixu('12345'), sixu('MixedCase')],
+                           [sixu('123 \t 345 \0 '), sixu('UPPER')]]).view(np.chararray)
+
+    def test_capitalize(self):
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12345', 'Mixedcase'],
+                              ['123 \t 345 \0 ', 'Upper']])
+        assert_(issubclass(self.A.capitalize().dtype.type, np.string_))
+        assert_array_equal(self.A.capitalize(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), ''],
+               ['12345', 'Mixedcase'],
+               ['123 \t 345 \0 ', 'Upper']]
+        assert_(issubclass(self.B.capitalize().dtype.type, np.unicode_))
+        assert_array_equal(self.B.capitalize(), tgt)
+
+    def test_center(self):
+        assert_(issubclass(self.A.center(10).dtype.type, np.string_))
+        C = self.A.center([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.center(20, asbytes('#'))
+        assert_(np.all(C.startswith(asbytes('#'))))
+        assert_(np.all(C.endswith(asbytes('#'))))
+
+        C = np.char.center(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['   FOO    ', '        FOO         '],
+                              ['      FOO      ', '  FOO   ']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_decode(self):
+        if sys.version_info[0] >= 3:
+            A = np.char.array([asbytes('\\u03a3')])
+            assert_(A.decode('unicode-escape')[0] == '\u03a3')
+        else:
+            A = np.char.array(['736563726574206d657373616765'])
+            assert_(A.decode('hex_codec')[0] == 'secret message')
+
+    def test_encode(self):
+        B = self.B.encode('unicode_escape')
+        assert_(B[0][0] == str(' \\u03a3 ').encode('latin1'))
+
+    def test_expandtabs(self):
+        T = self.A.expandtabs()
+        assert_(T[2, 0] == asbytes('123      345 \0'))
+
+    def test_join(self):
+        if sys.version_info[0] >= 3:
+            # NOTE: list(b'123') == [49, 50, 51]
+            #       so that b','.join(b'123') results to an error on Py3
+            A0 = self.A.decode('ascii')
+        else:
+            A0 = self.A
+
+        A = np.char.join([',', '#'], A0)
+        if sys.version_info[0] >= 3:
+            assert_(issubclass(A.dtype.type, np.unicode_))
+        else:
+            assert_(issubclass(A.dtype.type, np.string_))
+        tgt = np.array([[' ,a,b,c, ', ''],
+                        ['1,2,3,4,5', 'M#i#x#e#d#C#a#s#e'],
+                        ['1,2,3, ,\t, ,3,4,5, ,\x00, ', 'U#P#P#E#R']])
+        assert_array_equal(np.char.join([',', '#'], A0), tgt)
+
+    def test_ljust(self):
+        assert_(issubclass(self.A.ljust(10).dtype.type, np.string_))
+
+        C = self.A.ljust([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.ljust(20, asbytes('#'))
+        assert_array_equal(C.startswith(asbytes('#')), [
+                [False, True], [False, False], [False, False]])
+        assert_(np.all(C.endswith(asbytes('#'))))
+
+        C = np.char.ljust(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['FOO       ', 'FOO                 '],
+                              ['FOO            ', 'FOO     ']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_lower(self):
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12345', 'mixedcase'],
+                              ['123 \t 345 \0 ', 'upper']])
+        assert_(issubclass(self.A.lower().dtype.type, np.string_))
+        assert_array_equal(self.A.lower(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), sixu('')],
+               [sixu('12345'), sixu('mixedcase')],
+               [sixu('123 \t 345 \0 '), sixu('upper')]]
+        assert_(issubclass(self.B.lower().dtype.type, np.unicode_))
+        assert_array_equal(self.B.lower(), tgt)
+
+    def test_lstrip(self):
+        tgt = asbytes_nested([['abc ', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345 \0 ', 'UPPER']])
+        assert_(issubclass(self.A.lstrip().dtype.type, np.string_))
+        assert_array_equal(self.A.lstrip(), tgt)
+
+        tgt = asbytes_nested([[' abc', ''],
+                              ['2345', 'ixedCase'],
+                              ['23 \t 345 \x00', 'UPPER']])
+        assert_array_equal(self.A.lstrip(asbytes_nested(['1', 'M'])), tgt)
+
+        tgt = [[sixu('\u03a3 '), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345 \0 ', 'UPPER']]
+        assert_(issubclass(self.B.lstrip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.lstrip(), tgt)
+
+    def test_partition(self):
+        P = self.A.partition(asbytes_nested(['3', 'M']))
+        tgt = asbytes_nested([[(' abc ', '', ''), ('', '', '')],
+                             [('12', '3', '45'), ('', 'M', 'ixedCase')],
+                             [('12', '3', ' \t 345 \0 '), ('UPPER', '', '')]])
+        assert_(issubclass(P.dtype.type, np.string_))
+        assert_array_equal(P, tgt)
+
+    def test_replace(self):
+        R = self.A.replace(asbytes_nested(['3', 'a']),
+                           asbytes_nested(['##########', '@']))
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12##########45', 'MixedC@se'],
+                              ['12########## \t ##########45 \x00', 'UPPER']])
+        assert_(issubclass(R.dtype.type, np.string_))
+        assert_array_equal(R, tgt)
+
+        if sys.version_info[0] < 3:
+            # NOTE: b'abc'.replace(b'a', 'b') is not allowed on Py3
+            R = self.A.replace(asbytes('a'), sixu('\u03a3'))
+            tgt = [[sixu(' \u03a3bc '), ''],
+                   ['12345', sixu('MixedC\u03a3se')],
+                   ['123 \t 345 \x00', 'UPPER']]
+            assert_(issubclass(R.dtype.type, np.unicode_))
+            assert_array_equal(R, tgt)
+
+    def test_rjust(self):
+        assert_(issubclass(self.A.rjust(10).dtype.type, np.string_))
+
+        C = self.A.rjust([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.rjust(20, asbytes('#'))
+        assert_(np.all(C.startswith(asbytes('#'))))
+        assert_array_equal(C.endswith(asbytes('#')),
+                           [[False, True], [False, False], [False, False]])
+
+        C = np.char.rjust(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['       FOO', '                 FOO'],
+                              ['            FOO', '     FOO']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_rpartition(self):
+        P = self.A.rpartition(asbytes_nested(['3', 'M']))
+        tgt = asbytes_nested([[('', '', ' abc '), ('', '', '')],
+                              [('12', '3', '45'), ('', 'M', 'ixedCase')],
+                              [('123 \t ', '3', '45 \0 '), ('', '', 'UPPER')]])
+        assert_(issubclass(P.dtype.type, np.string_))
+        assert_array_equal(P, tgt)
+
+    def test_rsplit(self):
+        A = self.A.rsplit(asbytes('3'))
+        tgt = asbytes_nested([[[' abc '], ['']],
+                              [['12', '45'], ['MixedCase']],
+                              [['12', ' \t ', '45 \x00 '], ['UPPER']]])
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_equal(A.tolist(), tgt)
+
+    def test_rstrip(self):
+        assert_(issubclass(self.A.rstrip().dtype.type, np.string_))
+
+        tgt = asbytes_nested([[' abc', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345', 'UPPER']])
+        assert_array_equal(self.A.rstrip(), tgt)
+
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['1234', 'MixedCase'],
+                              ['123 \t 345 \x00', 'UPP']
+                              ])
+        assert_array_equal(self.A.rstrip(asbytes_nested(['5', 'ER'])), tgt)
+
+        tgt = [[sixu(' \u03a3'), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345', 'UPPER']]
+        assert_(issubclass(self.B.rstrip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.rstrip(), tgt)
+
+    def test_strip(self):
+        tgt = asbytes_nested([['abc', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345', 'UPPER']])
+        assert_(issubclass(self.A.strip().dtype.type, np.string_))
+        assert_array_equal(self.A.strip(), tgt)
+
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['234', 'ixedCas'],
+                              ['23 \t 345 \x00', 'UPP']])
+        assert_array_equal(self.A.strip(asbytes_nested(['15', 'EReM'])), tgt)
+
+        tgt = [[sixu('\u03a3'), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345', 'UPPER']]
+        assert_(issubclass(self.B.strip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.strip(), tgt)
+
+    def test_split(self):
+        A = self.A.split(asbytes('3'))
+        tgt = asbytes_nested([
+                              [[' abc '], ['']],
+                              [['12', '45'], ['MixedCase']],
+                              [['12', ' \t ', '45 \x00 '], ['UPPER']]])
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_equal(A.tolist(), tgt)
+
+    def test_splitlines(self):
+        A = np.char.array(['abc\nfds\nwer']).splitlines()
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_(A.shape == (1,))
+        assert_(len(A[0]) == 3)
+
+    def test_swapcase(self):
+        tgt = asbytes_nested([[' ABC ', ''],
+                              ['12345', 'mIXEDcASE'],
+                              ['123 \t 345 \0 ', 'upper']])
+        assert_(issubclass(self.A.swapcase().dtype.type, np.string_))
+        assert_array_equal(self.A.swapcase(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), sixu('')],
+               [sixu('12345'), sixu('mIXEDcASE')],
+               [sixu('123 \t 345 \0 '), sixu('upper')]]
+        assert_(issubclass(self.B.swapcase().dtype.type, np.unicode_))
+        assert_array_equal(self.B.swapcase(), tgt)
+
+    def test_title(self):
+        tgt = asbytes_nested([[' Abc ', ''],
+                              ['12345', 'Mixedcase'],
+                              ['123 \t 345 \0 ', 'Upper']])
+        assert_(issubclass(self.A.title().dtype.type, np.string_))
+        assert_array_equal(self.A.title(), tgt)
+
+        tgt = [[sixu(' \u03a3 '), sixu('')],
+               [sixu('12345'), sixu('Mixedcase')],
+               [sixu('123 \t 345 \0 '), sixu('Upper')]]
+        assert_(issubclass(self.B.title().dtype.type, np.unicode_))
+        assert_array_equal(self.B.title(), tgt)
+
+    def test_upper(self):
+        tgt = asbytes_nested([[' ABC ', ''],
+                              ['12345', 'MIXEDCASE'],
+                              ['123 \t 345 \0 ', 'UPPER']])
+        assert_(issubclass(self.A.upper().dtype.type, np.string_))
+        assert_array_equal(self.A.upper(), tgt)
+
+        tgt = [[sixu(' \u03a3 '), sixu('')],
+               [sixu('12345'), sixu('MIXEDCASE')],
+               [sixu('123 \t 345 \0 '), sixu('UPPER')]]
+        assert_(issubclass(self.B.upper().dtype.type, np.unicode_))
+        assert_array_equal(self.B.upper(), tgt)
+
+    def test_isnumeric(self):
+
+        def fail():
+            self.A.isnumeric()
+
+        self.assertRaises(TypeError, fail)
+        assert_(issubclass(self.B.isnumeric().dtype.type, np.bool_))
+        assert_array_equal(self.B.isnumeric(), [
+                [False, False], [True, False], [False, False]])
+
+    def test_isdecimal(self):
+
+        def fail():
+            self.A.isdecimal()
+
+        self.assertRaises(TypeError, fail)
+        assert_(issubclass(self.B.isdecimal().dtype.type, np.bool_))
+        assert_array_equal(self.B.isdecimal(), [
+                [False, False], [True, False], [False, False]])
+
+
+class TestOperations(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+        self.B = np.array([['efg', '456'],
+                           ['051', 'tuv']]).view(np.chararray)
+
+    def test_add(self):
+        AB = np.array([['abcefg', '123456'],
+                       ['789051', 'xyztuv']]).view(np.chararray)
+        assert_array_equal(AB, (self.A + self.B))
+        assert_(len((self.A + self.B)[0][0]) == 6)
+
+    def test_radd(self):
+        QA = np.array([['qabc', 'q123'],
+                       ['q789', 'qxyz']]).view(np.chararray)
+        assert_array_equal(QA, ('q' + self.A))
+
+    def test_mul(self):
+        A = self.A
+        for r in (2, 3, 5, 7, 197):
+            Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
+                           [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray)
+
+            assert_array_equal(Ar, (self.A * r))
+
+        for ob in [object(), 'qrs']:
+            try:
+                A * ob
+            except ValueError:
+                pass
+            else:
+                self.fail("chararray can only be multiplied by integers")
+
+    def test_rmul(self):
+        A = self.A
+        for r in (2, 3, 5, 7, 197):
+            Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
+                           [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray)
+            assert_array_equal(Ar, (r * self.A))
+
+        for ob in [object(), 'qrs']:
+            try:
+                ob * A
+            except ValueError:
+                pass
+            else:
+                self.fail("chararray can only be multiplied by integers")
+
+    def test_mod(self):
+        """Ticket #856"""
+        F = np.array([['%d', '%f'], ['%s', '%r']]).view(np.chararray)
+        C = np.array([[3, 7], [19, 1]])
+        FC = np.array([['3', '7.000000'],
+                       ['19', '1']]).view(np.chararray)
+        assert_array_equal(FC, F % C)
+
+        A = np.array([['%.3f', '%d'], ['%s', '%r']]).view(np.chararray)
+        A1 = np.array([['1.000', '1'], ['1', '1']]).view(np.chararray)
+        assert_array_equal(A1, (A % 1))
+
+        A2 = np.array([['1.000', '2'], ['3', '4']]).view(np.chararray)
+        assert_array_equal(A2, (A % [[1, 2], [3, 4]]))
+
+    def test_rmod(self):
+        assert_(("%s" % self.A) == str(self.A))
+        assert_(("%r" % self.A) == repr(self.A))
+
+        for ob in [42, object()]:
+            try:
+                ob % self.A
+            except TypeError:
+                pass
+            else:
+                self.fail("chararray __rmod__ should fail with "
+                          "non-string objects")
+
+    def test_slice(self):
+        """Regression test for https://github.com/numpy/numpy/issues/5982"""
+
+        arr = np.array([['abc ', 'def '], ['geh ', 'ijk ']],
+                       dtype='S4').view(np.chararray)
+        sl1 = arr[:]
+        assert_array_equal(sl1, arr)
+        assert_(sl1.base is arr)
+        assert_(sl1.base.base is arr.base)
+
+        sl2 = arr[:, :]
+        assert_array_equal(sl2, arr)
+        assert_(sl2.base is arr)
+        assert_(sl2.base.base is arr.base)
+
+        assert_(arr[0, 0] == asbytes('abc'))
+
+
+def test_empty_indexing():
+    """Regression test for ticket 1948."""
+    # Check that indexing a chararray with an empty list/array returns an
+    # empty chararray instead of a chararray with a single empty string in it.
+    s = np.chararray((4,))
+    assert_(s[[]].size == 0)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
new file mode 100644
index 0000000000..562e6966fe
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
@@ -0,0 +1,809 @@
+"""
+Tests related to deprecation warnings. Also a convenient place
+to document how deprecations should eventually be turned into errors.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import datetime
+import sys
+import operator
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_raises, assert_warns, assert_no_warnings,
+    assert_array_equal, assert_, dec)
+
+try:
+    import pytz
+    _has_pytz = True
+except ImportError:
+    _has_pytz = False
+
+
+class _VisibleDeprecationTestCase(object):
+    # Just as warning: warnings uses re.match, so the start of this message
+    # must match.
+    message = ''
+
+    def setUp(self):
+        self.warn_ctx = warnings.catch_warnings(record=True)
+        self.log = self.warn_ctx.__enter__()
+
+        # Do *not* ignore other DeprecationWarnings. Ignoring warnings
+        # can give very confusing results because of
+        # http://bugs.python.org/issue4180 and it is probably simplest to
+        # try to keep the tests cleanly giving only the right warning type.
+        # (While checking them set to "error" those are ignored anyway)
+        # We still have them show up, because otherwise they would be raised
+        warnings.filterwarnings("always", category=np.VisibleDeprecationWarning)
+        warnings.filterwarnings("always", message=self.message,
+                                category=np.VisibleDeprecationWarning)
+
+    def tearDown(self):
+        self.warn_ctx.__exit__()
+
+    def assert_deprecated(self, function, num=1, ignore_others=False,
+                          function_fails=False,
+                          exceptions=(np.VisibleDeprecationWarning,),
+                          args=(), kwargs={}):
+        """Test if VisibleDeprecationWarnings are given and raised.
+
+        This first checks if the function when called gives `num`
+        VisibleDeprecationWarnings, after that it tries to raise these
+        VisibleDeprecationWarnings and compares them with `exceptions`.
+        The exceptions can be different for cases where this code path
+        is simply not anticipated and the exception is replaced.
+
+        Parameters
+        ----------
+        f : callable
+            The function to test
+        num : int
+            Number of VisibleDeprecationWarnings to expect. This should
+            normally be 1.
+        ignore_other : bool
+            Whether warnings of the wrong type should be ignored (note that
+            the message is not checked)
+        function_fails : bool
+            If the function would normally fail, setting this will check for
+            warnings inside a try/except block.
+        exceptions : Exception or tuple of Exceptions
+            Exception to expect when turning the warnings into an error.
+            The default checks for DeprecationWarnings. If exceptions is
+            empty the function is expected to run successfull.
+        args : tuple
+            Arguments for `f`
+        kwargs : dict
+            Keyword arguments for `f`
+        """
+        # reset the log
+        self.log[:] = []
+
+        try:
+            function(*args, **kwargs)
+        except (Exception if function_fails else tuple()):
+            pass
+
+        # just in case, clear the registry
+        num_found = 0
+        for warning in self.log:
+            if warning.category is np.VisibleDeprecationWarning:
+                num_found += 1
+            elif not ignore_others:
+                raise AssertionError(
+                        "expected DeprecationWarning but got: %s" %
+                        (warning.category,))
+        if num is not None and num_found != num:
+            msg = "%i warnings found but %i expected." % (len(self.log), num)
+            lst = [w.category for w in self.log]
+            raise AssertionError("\n".join([msg] + lst))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error", message=self.message,
+                                    category=np.VisibleDeprecationWarning)
+            try:
+                function(*args, **kwargs)
+                if exceptions != tuple():
+                    raise AssertionError(
+                            "No error raised during function call")
+            except exceptions:
+                if exceptions == tuple():
+                    raise AssertionError(
+                            "Error raised during function call")
+
+    def assert_not_deprecated(self, function, args=(), kwargs={}):
+        """Test if VisibleDeprecationWarnings are given and raised.
+
+        This is just a shorthand for:
+
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+        """
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+
+
+class _DeprecationTestCase(object):
+    # Just as warning: warnings uses re.match, so the start of this message
+    # must match.
+    message = ''
+
+    def setUp(self):
+        self.warn_ctx = warnings.catch_warnings(record=True)
+        self.log = self.warn_ctx.__enter__()
+
+        # Do *not* ignore other DeprecationWarnings. Ignoring warnings
+        # can give very confusing results because of
+        # http://bugs.python.org/issue4180 and it is probably simplest to
+        # try to keep the tests cleanly giving only the right warning type.
+        # (While checking them set to "error" those are ignored anyway)
+        # We still have them show up, because otherwise they would be raised
+        warnings.filterwarnings("always", category=DeprecationWarning)
+        warnings.filterwarnings("always", message=self.message,
+                                    category=DeprecationWarning)
+
+    def tearDown(self):
+        self.warn_ctx.__exit__()
+
+    def assert_deprecated(self, function, num=1, ignore_others=False,
+                        function_fails=False,
+                        exceptions=(DeprecationWarning,), args=(), kwargs={}):
+        """Test if DeprecationWarnings are given and raised.
+
+        This first checks if the function when called gives `num`
+        DeprecationWarnings, after that it tries to raise these
+        DeprecationWarnings and compares them with `exceptions`.
+        The exceptions can be different for cases where this code path
+        is simply not anticipated and the exception is replaced.
+
+        Parameters
+        ----------
+        f : callable
+            The function to test
+        num : int
+            Number of DeprecationWarnings to expect. This should normally be 1.
+        ignore_other : bool
+            Whether warnings of the wrong type should be ignored (note that
+            the message is not checked)
+        function_fails : bool
+            If the function would normally fail, setting this will check for
+            warnings inside a try/except block.
+        exceptions : Exception or tuple of Exceptions
+            Exception to expect when turning the warnings into an error.
+            The default checks for DeprecationWarnings. If exceptions is
+            empty the function is expected to run successfull.
+        args : tuple
+            Arguments for `f`
+        kwargs : dict
+            Keyword arguments for `f`
+        """
+        # reset the log
+        self.log[:] = []
+
+        try:
+            function(*args, **kwargs)
+        except (Exception if function_fails else tuple()):
+            pass
+
+        # just in case, clear the registry
+        num_found = 0
+        for warning in self.log:
+            if warning.category is DeprecationWarning:
+                num_found += 1
+            elif not ignore_others:
+                raise AssertionError(
+                        "expected DeprecationWarning but got: %s" %
+                        (warning.category,))
+        if num is not None and num_found != num:
+            msg = "%i warnings found but %i expected." % (len(self.log), num)
+            lst = [w.category for w in self.log]
+            raise AssertionError("\n".join([msg] + lst))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error", message=self.message,
+                                    category=DeprecationWarning)
+            try:
+                function(*args, **kwargs)
+                if exceptions != tuple():
+                    raise AssertionError(
+                            "No error raised during function call")
+            except exceptions:
+                if exceptions == tuple():
+                    raise AssertionError(
+                            "Error raised during function call")
+
+    def assert_not_deprecated(self, function, args=(), kwargs={}):
+        """Test if DeprecationWarnings are given and raised.
+
+        This is just a shorthand for:
+
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+        """
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+
+
+class TestFloatNonIntegerArgumentDeprecation(_VisibleDeprecationTestCase):
+    """
+    These test that ``DeprecationWarning`` is given when you try to use
+    non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]``
+    and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``.
+
+    After deprecation, changes need to be done inside conversion_utils.c
+    in PyArray_PyIntAsIntp and possibly PyArray_IntpConverter.
+    In iterators.c the function slice_GetIndices could be removed in favor
+    of its python equivalent and in mapping.c the function _tuple_of_integers
+    can be simplified (if ``np.array([1]).__index__()`` is also deprecated).
+
+    As for the deprecation time-frame: via Ralf Gommers,
+
+    "Hard to put that as a version number, since we don't know if the
+    version after 1.8 will be 6 months or 2 years after. I'd say 2
+    years is reasonable."
+
+    I interpret this to mean 2 years after the 1.8 release. Possibly
+    giving a PendingDeprecationWarning before that (which is visible
+    by default)
+
+    """
+    message = "using a non-integer number instead of an integer " \
+              "will result in an error in the future"
+
+    def test_indexing(self):
+        a = np.array([[[5]]])
+
+        def assert_deprecated(*args, **kwargs):
+            self.assert_deprecated(*args, exceptions=(IndexError,), **kwargs)
+
+        assert_deprecated(lambda: a[0.0])
+        assert_deprecated(lambda: a[0, 0.0])
+        assert_deprecated(lambda: a[0.0, 0])
+        assert_deprecated(lambda: a[0.0,:])
+        assert_deprecated(lambda: a[:, 0.0])
+        assert_deprecated(lambda: a[:, 0.0,:])
+        assert_deprecated(lambda: a[0.0,:,:])
+        assert_deprecated(lambda: a[0, 0, 0.0])
+        assert_deprecated(lambda: a[0.0, 0, 0])
+        assert_deprecated(lambda: a[0, 0.0, 0])
+        assert_deprecated(lambda: a[-1.4])
+        assert_deprecated(lambda: a[0, -1.4])
+        assert_deprecated(lambda: a[-1.4, 0])
+        assert_deprecated(lambda: a[-1.4,:])
+        assert_deprecated(lambda: a[:, -1.4])
+        assert_deprecated(lambda: a[:, -1.4,:])
+        assert_deprecated(lambda: a[-1.4,:,:])
+        assert_deprecated(lambda: a[0, 0, -1.4])
+        assert_deprecated(lambda: a[-1.4, 0, 0])
+        assert_deprecated(lambda: a[0, -1.4, 0])
+
+        # Test that the slice parameter deprecation warning doesn't mask
+        # the scalar index warning.
+        assert_deprecated(lambda: a[0.0:, 0.0], num=2)
+        assert_deprecated(lambda: a[0.0:, 0.0,:], num=2)
+
+    def test_valid_indexing(self):
+        a = np.array([[[5]]])
+        assert_not_deprecated = self.assert_not_deprecated
+
+        assert_not_deprecated(lambda: a[np.array([0])])
+        assert_not_deprecated(lambda: a[[0, 0]])
+        assert_not_deprecated(lambda: a[:, [0, 0]])
+        assert_not_deprecated(lambda: a[:, 0,:])
+        assert_not_deprecated(lambda: a[:,:,:])
+
+    def test_slicing(self):
+        a = np.array([[5]])
+
+        def assert_deprecated(*args, **kwargs):
+            self.assert_deprecated(*args, exceptions=(IndexError,), **kwargs)
+
+        # start as float.
+        assert_deprecated(lambda: a[0.0:])
+        assert_deprecated(lambda: a[0:, 0.0:2])
+        assert_deprecated(lambda: a[0.0::2, :0])
+        assert_deprecated(lambda: a[0.0:1:2,:])
+        assert_deprecated(lambda: a[:, 0.0:])
+        # stop as float.
+        assert_deprecated(lambda: a[:0.0])
+        assert_deprecated(lambda: a[:0, 1:2.0])
+        assert_deprecated(lambda: a[:0.0:2, :0])
+        assert_deprecated(lambda: a[:0.0,:])
+        assert_deprecated(lambda: a[:, 0:4.0:2])
+        # step as float.
+        assert_deprecated(lambda: a[::1.0])
+        assert_deprecated(lambda: a[0:, :2:2.0])
+        assert_deprecated(lambda: a[1::4.0, :0])
+        assert_deprecated(lambda: a[::5.0,:])
+        assert_deprecated(lambda: a[:, 0:4:2.0])
+        # mixed.
+        assert_deprecated(lambda: a[1.0:2:2.0], num=2)
+        assert_deprecated(lambda: a[1.0::2.0], num=2)
+        assert_deprecated(lambda: a[0:, :2.0:2.0], num=2)
+        assert_deprecated(lambda: a[1.0:1:4.0, :0], num=2)
+        assert_deprecated(lambda: a[1.0:5.0:5.0,:], num=3)
+        assert_deprecated(lambda: a[:, 0.4:4.0:2.0], num=3)
+        # should still get the DeprecationWarning if step = 0.
+        assert_deprecated(lambda: a[::0.0], function_fails=True)
+
+    def test_valid_slicing(self):
+        a = np.array([[[5]]])
+        assert_not_deprecated = self.assert_not_deprecated
+
+        assert_not_deprecated(lambda: a[::])
+        assert_not_deprecated(lambda: a[0:])
+        assert_not_deprecated(lambda: a[:2])
+        assert_not_deprecated(lambda: a[0:2])
+        assert_not_deprecated(lambda: a[::2])
+        assert_not_deprecated(lambda: a[1::2])
+        assert_not_deprecated(lambda: a[:2:2])
+        assert_not_deprecated(lambda: a[1:2:2])
+
+    def test_non_integer_argument_deprecations(self):
+        a = np.array([[5]])
+
+        self.assert_deprecated(np.reshape, args=(a, (1., 1., -1)), num=2)
+        self.assert_deprecated(np.reshape, args=(a, (np.array(1.), -1)))
+        self.assert_deprecated(np.take, args=(a, [0], 1.))
+        self.assert_deprecated(np.take, args=(a, [0], np.float64(1.)))
+
+    def test_non_integer_sequence_multiplication(self):
+        # Numpy scalar sequence multiply should not work with non-integers
+        def mult(a, b):
+            return a * b
+
+        self.assert_deprecated(mult, args=([1], np.float_(3)))
+        self.assert_not_deprecated(mult, args=([1], np.int_(3)))
+
+    def test_reduce_axis_float_index(self):
+        d = np.zeros((3,3,3))
+        self.assert_deprecated(np.min, args=(d, 0.5))
+        self.assert_deprecated(np.min, num=1, args=(d, (0.5, 1)))
+        self.assert_deprecated(np.min, num=1, args=(d, (1, 2.2)))
+        self.assert_deprecated(np.min, num=2, args=(d, (.2, 1.2)))
+
+
+class TestBooleanArgumentDeprecation(_VisibleDeprecationTestCase):
+    """This tests that using a boolean as integer argument/indexing is
+    deprecated.
+
+    This should be kept in sync with TestFloatNonIntegerArgumentDeprecation
+    and like it is handled in PyArray_PyIntAsIntp.
+    """
+    message = "using a boolean instead of an integer " \
+              "will result in an error in the future"
+
+    def test_bool_as_int_argument(self):
+        a = np.array([[[1]]])
+
+        self.assert_deprecated(np.reshape, args=(a, (True, -1)))
+        self.assert_deprecated(np.reshape, args=(a, (np.bool_(True), -1)))
+        # Note that operator.index(np.array(True)) does not work, a boolean
+        # array is thus also deprecated, but not with the same message:
+        assert_raises(TypeError, operator.index, np.array(True))
+        self.assert_deprecated(np.take, args=(a, [0], False))
+        self.assert_deprecated(lambda: a[False:True:True], exceptions=IndexError, num=3)
+        self.assert_deprecated(lambda: a[False, 0], exceptions=IndexError)
+        self.assert_deprecated(lambda: a[False, 0, 0], exceptions=IndexError)
+
+
+class TestArrayToIndexDeprecation(_VisibleDeprecationTestCase):
+    """This tests that creating an an index from an array is deprecated
+    if the array is not 0d.
+
+    This can probably be deprecated somewhat faster then the integer
+    deprecations. The deprecation period started with NumPy 1.8.
+    For deprecation this needs changing of array_index in number.c
+    """
+    message = "converting an array with ndim \> 0 to an index will result " \
+              "in an error in the future"
+
+    def test_array_to_index_deprecation(self):
+        # This drops into the non-integer deprecation, which is ignored here,
+        # so no exception is expected. The raising is effectively tested above.
+        a = np.array([[[1]]])
+
+        self.assert_deprecated(operator.index, args=(np.array([1]),))
+        self.assert_deprecated(np.reshape, args=(a, (a, -1)), exceptions=())
+        self.assert_deprecated(np.take, args=(a, [0], a), exceptions=())
+        # Check slicing. Normal indexing checks arrays specifically.
+        self.assert_deprecated(lambda: a[a:a:a], exceptions=(), num=3)
+
+class TestNonIntegerArrayLike(_VisibleDeprecationTestCase):
+    """Tests that array likes, i.e. lists give a deprecation warning
+    when they cannot be safely cast to an integer.
+    """
+    message = "non integer \(and non boolean\) array-likes will not be " \
+              "accepted as indices in the future"
+
+    def test_basic(self):
+        a = np.arange(10)
+        self.assert_deprecated(a.__getitem__, args=([0.5, 1.5],),
+                               exceptions=IndexError)
+        self.assert_deprecated(a.__getitem__, args=((['1', '2'],),),
+                               exceptions=IndexError)
+
+        self.assert_not_deprecated(a.__getitem__, ([],))
+
+    def test_boolean_futurewarning(self):
+        a = np.arange(10)
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always')
+            assert_warns(FutureWarning, a.__getitem__, [True])
+            # Unfortunatly, the deprecation warning takes precedence:
+            #assert_warns(FutureWarning, a.__getitem__, True)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error')
+            assert_raises(FutureWarning, a.__getitem__, [True])
+            #assert_raises(FutureWarning, a.__getitem__, True)
+
+
+class TestMultipleEllipsisDeprecation(_VisibleDeprecationTestCase):
+    message = "an index can only have a single Ellipsis \(`...`\); replace " \
+              "all but one with slices \(`:`\)."
+
+    def test_basic(self):
+        a = np.arange(10)
+        self.assert_deprecated(a.__getitem__, args=((Ellipsis, Ellipsis),))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', '', np.VisibleDeprecationWarning)
+            # Just check that this works:
+            b = a[...,...]
+            assert_array_equal(a, b)
+            assert_raises(IndexError, a.__getitem__, ((Ellipsis, ) * 3,))
+
+
+class TestBooleanUnaryMinusDeprecation(_DeprecationTestCase):
+    """Test deprecation of unary boolean `-`. While + and * are well
+    defined, unary - is not and even a corrected form seems to have
+    no real uses.
+
+    The deprecation process was started in NumPy 1.9.
+    """
+    message = r"numpy boolean negative, the `-` operator, .*"
+
+    def test_unary_minus_operator_deprecation(self):
+        array = np.array([True])
+        generic = np.bool_(True)
+
+        # Unary minus/negative ufunc:
+        self.assert_deprecated(operator.neg, args=(array,))
+        self.assert_deprecated(operator.neg, args=(generic,))
+
+
+class TestBooleanBinaryMinusDeprecation(_DeprecationTestCase):
+    """Test deprecation of binary boolean `-`. While + and * are well
+    defined, binary  - is not and even a corrected form seems to have
+    no real uses.
+
+    The deprecation process was started in NumPy 1.9.
+    """
+    message = r"numpy boolean subtract, the `-` operator, .*"
+
+    def test_operator_deprecation(self):
+        array = np.array([True])
+        generic = np.bool_(True)
+
+        # Minus operator/subtract ufunc:
+        self.assert_deprecated(operator.sub, args=(array, array))
+        self.assert_deprecated(operator.sub, args=(generic, generic))
+
+
+class TestRankDeprecation(_DeprecationTestCase):
+    """Test that np.rank is deprecated. The function should simply be
+    removed. The VisibleDeprecationWarning may become unnecessary.
+    """
+
+    def test(self):
+        a = np.arange(10)
+        assert_warns(np.VisibleDeprecationWarning, np.rank, a)
+
+
+class TestComparisonDeprecations(_DeprecationTestCase):
+    """This tests the deprecation, for non-element-wise comparison logic.
+    This used to mean that when an error occurred during element-wise comparison
+    (i.e. broadcasting) NotImplemented was returned, but also in the comparison
+    itself, False was given instead of the error.
+
+    Also test FutureWarning for the None comparison.
+    """
+
+    message = "elementwise.* comparison failed; .*"
+
+    def test_normal_types(self):
+        for op in (operator.eq, operator.ne):
+            # Broadcasting errors:
+            self.assert_deprecated(op, args=(np.zeros(3), []))
+            a = np.zeros(3, dtype='i,i')
+            # (warning is issued a couple of times here)
+            self.assert_deprecated(op, args=(a, a[:-1]), num=None)
+
+            # Element comparison error (numpy array can't be compared).
+            a = np.array([1, np.array([1,2,3])], dtype=object)
+            b = np.array([1, np.array([1,2,3])], dtype=object)
+            self.assert_deprecated(op, args=(a, b), num=None)
+
+    def test_string(self):
+        # For two string arrays, strings always raised the broadcasting error:
+        a = np.array(['a', 'b'])
+        b = np.array(['a', 'b', 'c'])
+        assert_raises(ValueError, lambda x, y: x == y, a, b)
+
+        # The empty list is not cast to string, as this is only to document
+        # that fact (it likely should be changed). This means that the
+        # following works (and returns False) due to dtype mismatch:
+        a == []
+
+    def test_none_comparison(self):
+        # Test comparison of None, which should result in element-wise
+        # comparison in the future. [1, 2] == None should be [False, False].
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_warns(FutureWarning, operator.eq, np.arange(3), None)
+            assert_warns(FutureWarning, operator.ne, np.arange(3), None)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', FutureWarning)
+            assert_raises(FutureWarning, operator.eq, np.arange(3), None)
+            assert_raises(FutureWarning, operator.ne, np.arange(3), None)
+
+    def test_scalar_none_comparison(self):
+        # Scalars should still just return False and not give a warnings.
+        # The comparisons are flagged by pep8, ignore that.
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_(not np.float32(1) == None)
+            assert_(not np.str_('test') == None)
+            # This is dubious (see below):
+            assert_(not np.datetime64('NaT') == None)
+
+            assert_(np.float32(1) != None)
+            assert_(np.str_('test') != None)
+            # This is dubious (see below):
+            assert_(np.datetime64('NaT') != None)
+        assert_(len(w) == 0)
+
+        # For documentation purposes, this is why the datetime is dubious.
+        # At the time of deprecation this was no behaviour change, but
+        # it has to be considered when the deprecations are done.
+        assert_(np.equal(np.datetime64('NaT'), None))
+
+    def test_void_dtype_equality_failures(self):
+        class NotArray(object):
+            def __array__(self):
+                raise TypeError
+
+            # Needed so Python 3 does not raise DeprecationWarning twice.
+            def __ne__(self, other):
+                return NotImplemented
+
+        self.assert_deprecated(lambda: np.arange(2) == NotArray())
+        self.assert_deprecated(lambda: np.arange(2) != NotArray())
+
+        struct1 = np.zeros(2, dtype="i4,i4")
+        struct2 = np.zeros(2, dtype="i4,i4,i4")
+
+        assert_warns(FutureWarning, lambda: struct1 == 1)
+        assert_warns(FutureWarning, lambda: struct1 == struct2)
+        assert_warns(FutureWarning, lambda: struct1 != 1)
+        assert_warns(FutureWarning, lambda: struct1 != struct2)
+
+    def test_array_richcompare_legacy_weirdness(self):
+        # It doesn't really work to use assert_deprecated here, b/c part of
+        # the point of assert_deprecated is to check that when warnings are
+        # set to "error" mode then the error is propagated -- which is good!
+        # But here we are testing a bunch of code that is deprecated *because*
+        # it has the habit of swallowing up errors and converting them into
+        # different warnings. So assert_warns will have to be sufficient.
+        assert_warns(FutureWarning, lambda: np.arange(2) == "a")
+        assert_warns(FutureWarning, lambda: np.arange(2) != "a")
+        # No warning for scalar comparisons
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error")
+            assert_(not (np.array(0) == "a"))
+            assert_(np.array(0) != "a")
+            assert_(not (np.int16(0) == "a"))
+            assert_(np.int16(0) != "a")
+
+        for arg1 in [np.asarray(0), np.int16(0)]:
+            struct = np.zeros(2, dtype="i4,i4")
+            for arg2 in [struct, "a"]:
+                for f in [operator.lt, operator.le, operator.gt, operator.ge]:
+                    if sys.version_info[0] >= 3:
+                        # py3
+                        with warnings.catch_warnings() as l:
+                            warnings.filterwarnings("always")
+                            assert_raises(TypeError, f, arg1, arg2)
+                            assert_(not l)
+                    else:
+                        # py2
+                        assert_warns(DeprecationWarning, f, arg1, arg2)
+
+
+class TestIdentityComparisonDeprecations(_DeprecationTestCase):
+    """This tests the equal and not_equal object ufuncs identity check
+    deprecation. This was due to the usage of PyObject_RichCompareBool.
+
+    This tests that for example for `a = np.array([np.nan], dtype=object)`
+    `a == a` it is warned that False and not `np.nan is np.nan` is returned.
+
+    Should be kept in sync with TestComparisonDeprecations and new tests
+    added when the deprecation is over. Requires only removing of @identity@
+    (and blocks) from the ufunc loops.c.src of the OBJECT comparisons.
+    """
+
+    message = "numpy .* will not check object identity in the future."
+
+    def test_identity_equality_mismatch(self):
+        a = np.array([np.nan], dtype=object)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_warns(FutureWarning, np.equal, a, a)
+            assert_warns(FutureWarning, np.not_equal, a, a)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', FutureWarning)
+            assert_raises(FutureWarning, np.equal, a, a)
+            assert_raises(FutureWarning, np.not_equal, a, a)
+            # And the other do not warn:
+            with np.errstate(invalid='ignore'):
+                np.less(a, a)
+                np.greater(a, a)
+                np.less_equal(a, a)
+                np.greater_equal(a, a)
+
+    def test_comparison_error(self):
+        class FunkyType(object):
+            def __eq__(self, other):
+                raise TypeError("I won't compare")
+
+            def __ne__(self, other):
+                raise TypeError("I won't compare")
+
+        a = np.array([FunkyType()])
+        self.assert_deprecated(np.equal, args=(a, a))
+        self.assert_deprecated(np.not_equal, args=(a, a))
+
+    def test_bool_error(self):
+        # The comparison result cannot be interpreted as a bool
+        a = np.array([np.array([1, 2, 3]), None], dtype=object)
+        self.assert_deprecated(np.equal, args=(a, a))
+        self.assert_deprecated(np.not_equal, args=(a, a))
+
+
+class TestAlterdotRestoredotDeprecations(_DeprecationTestCase):
+    """The alterdot/restoredot functions are deprecated.
+
+    These functions no longer do anything in numpy 1.10, so
+    they should not be used.
+
+    """
+
+    def test_alterdot_restoredot_deprecation(self):
+        self.assert_deprecated(np.alterdot)
+        self.assert_deprecated(np.restoredot)
+
+
+class TestBooleanIndexShapeMismatchDeprecation():
+    """Tests deprecation for boolean indexing where the boolean array
+    does not match the input array along the given dimensions.
+    """
+    message = r"boolean index did not match indexed array"
+
+    def test_simple(self):
+        arr = np.ones((5, 4, 3))
+        index = np.array([True])
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+                     arr.__getitem__, index)
+
+        index = np.array([False] * 6)
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, index)
+
+        index = np.zeros((4, 4), dtype=bool)
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, index)
+        #self.assert_deprecated(arr.__getitem__, args=((slice(None), index),))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, (slice(None), index))
+
+
+class TestFullDefaultDtype(object):
+    """np.full defaults to float when dtype is not set.  In the future, it will
+    use the fill value's dtype.
+    """
+
+    def test_full_default_dtype(self):
+        assert_warns(FutureWarning, np.full, 1, 1)
+        assert_warns(FutureWarning, np.full, 1, None)
+        assert_no_warnings(np.full, 1, 1, float)
+
+
+class TestDatetime64Timezone(_DeprecationTestCase):
+    """Parsing of datetime64 with timezones deprecated in 1.11.0, because
+    datetime64 is now timezone naive rather than UTC only.
+
+    It will be quite a while before we can remove this, because, at the very
+    least, a lot of existing code uses the 'Z' modifier to avoid conversion
+    from local time to UTC, even if otherwise it handles time in a timezone
+    naive fashion.
+    """
+    def test_string(self):
+        self.assert_deprecated(np.datetime64, args=('2000-01-01T00+01',))
+        self.assert_deprecated(np.datetime64, args=('2000-01-01T00Z',))
+
+    @dec.skipif(not _has_pytz, "The pytz module is not available.")
+    @dec.knownfailureif(sys.version_info[0:2] < (2, 7))
+    def test_datetime(self):
+        tz = pytz.timezone('US/Eastern')
+        dt = datetime.datetime(2000, 1, 1, 0, 0, tzinfo=tz)
+        self.assert_deprecated(np.datetime64, args=(dt,))
+
+
+class TestNonCContiguousViewDeprecation(_DeprecationTestCase):
+    """View of non-C-contiguous arrays deprecated in 1.11.0.
+
+    The deprecation will not be raised for arrays that are both C and F
+    contiguous, as C contiguous is dominant. There are more such arrays
+    with relaxed stride checking than without so the deprecation is not
+    as visible with relaxed stride checking in force.
+    """
+
+    def test_fortran_contiguous(self):
+        self.assert_deprecated(np.ones((2,2)).T.view, args=(np.complex,))
+        self.assert_deprecated(np.ones((2,2)).T.view, args=(np.int8,))
+
+
+class TestInvalidOrderParameterInputForFlattenArrayDeprecation(_DeprecationTestCase):
+    """Invalid arguments to the ORDER parameter in array.flatten() should not be
+    allowed and should raise an error.  However, in the interests of not breaking
+    code that may inadvertently pass invalid arguments to this parameter, a
+    DeprecationWarning will be issued instead for the time being to give developers
+    time to refactor relevant code.
+    """
+
+    def test_flatten_array_non_string_arg(self):
+        x = np.zeros((3, 5))
+        self.message = ("Non-string object detected for "
+                        "the array ordering. Please pass "
+                        "in 'C', 'F', 'A', or 'K' instead")
+        self.assert_deprecated(x.flatten, args=(np.pi,))
+
+    def test_flatten_array_invalid_string_arg(self):
+        # Tests that a DeprecationWarning is raised
+        # when a string of length greater than one
+        # starting with "C", "F", "A", or "K" (case-
+        # and unicode-insensitive) is passed in for
+        # the ORDER parameter. Otherwise, a TypeError
+        # will be raised!
+
+        x = np.zeros((3, 5))
+        self.message = ("Non length-one string passed "
+                        "in for the array ordering. Please "
+                        "pass in 'C', 'F', 'A', or 'K' instead")
+        self.assert_deprecated(x.flatten, args=("FACK",))
+
+
+class TestTestDeprecated(object):
+    def test_assert_deprecated(self):
+        test_case_instance = _DeprecationTestCase()
+        test_case_instance.setUp()
+        assert_raises(AssertionError,
+                      test_case_instance.assert_deprecated,
+                      lambda: None)
+
+        def foo():
+            warnings.warn("foo", category=DeprecationWarning)
+
+        test_case_instance.assert_deprecated(foo)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
new file mode 100644
index 0000000000..a6cb66b7d5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
@@ -0,0 +1,599 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.core.test_rational import rational
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    dec
+)
+
+def assert_dtype_equal(a, b):
+    assert_equal(a, b)
+    assert_equal(hash(a), hash(b),
+                 "two equivalent types do not hash to the same value !")
+
+def assert_dtype_not_equal(a, b):
+    assert_(a != b)
+    assert_(hash(a) != hash(b),
+            "two different types hash to the same value !")
+
+class TestBuiltin(TestCase):
+    def test_run(self):
+        """Only test hash runs at all."""
+        for t in [np.int, np.float, np.complex, np.int32, np.str, np.object,
+                np.unicode]:
+            dt = np.dtype(t)
+            hash(dt)
+
+    def test_dtype(self):
+        # Make sure equivalent byte order char hash the same (e.g. < and = on
+        # little endian)
+        for t in [np.int, np.float]:
+            dt = np.dtype(t)
+            dt2 = dt.newbyteorder("<")
+            dt3 = dt.newbyteorder(">")
+            if dt == dt2:
+                self.assertTrue(dt.byteorder != dt2.byteorder, "bogus test")
+                assert_dtype_equal(dt, dt2)
+            else:
+                self.assertTrue(dt.byteorder != dt3.byteorder, "bogus test")
+                assert_dtype_equal(dt, dt3)
+
+    def test_equivalent_dtype_hashing(self):
+        # Make sure equivalent dtypes with different type num hash equal
+        uintp = np.dtype(np.uintp)
+        if uintp.itemsize == 4:
+            left = uintp
+            right = np.dtype(np.uint32)
+        else:
+            left = uintp
+            right = np.dtype(np.ulonglong)
+        self.assertTrue(left == right)
+        self.assertTrue(hash(left) == hash(right))
+
+    def test_invalid_types(self):
+        # Make sure invalid type strings raise an error
+
+        assert_raises(TypeError, np.dtype, 'O3')
+        assert_raises(TypeError, np.dtype, 'O5')
+        assert_raises(TypeError, np.dtype, 'O7')
+        assert_raises(TypeError, np.dtype, 'b3')
+        assert_raises(TypeError, np.dtype, 'h4')
+        assert_raises(TypeError, np.dtype, 'I5')
+        assert_raises(TypeError, np.dtype, 'e3')
+        assert_raises(TypeError, np.dtype, 'f5')
+
+        if np.dtype('g').itemsize == 8 or np.dtype('g').itemsize == 16:
+            assert_raises(TypeError, np.dtype, 'g12')
+        elif np.dtype('g').itemsize == 12:
+            assert_raises(TypeError, np.dtype, 'g16')
+
+        if np.dtype('l').itemsize == 8:
+            assert_raises(TypeError, np.dtype, 'l4')
+            assert_raises(TypeError, np.dtype, 'L4')
+        else:
+            assert_raises(TypeError, np.dtype, 'l8')
+            assert_raises(TypeError, np.dtype, 'L8')
+
+        if np.dtype('q').itemsize == 8:
+            assert_raises(TypeError, np.dtype, 'q4')
+            assert_raises(TypeError, np.dtype, 'Q4')
+        else:
+            assert_raises(TypeError, np.dtype, 'q8')
+            assert_raises(TypeError, np.dtype, 'Q8')
+
+    def test_bad_param(self):
+        # Can't give a size that's too small
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i4', 'i1'],
+                         'offsets':[0, 4],
+                         'itemsize':4})
+        # If alignment is enabled, the alignment (4) must divide the itemsize
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i4', 'i1'],
+                         'offsets':[0, 4],
+                         'itemsize':9}, align=True)
+        # If alignment is enabled, the individual fields must be aligned
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i1', 'f4'],
+                         'offsets':[0, 2]}, align=True)
+
+class TestRecord(TestCase):
+    def test_equivalent_record(self):
+        """Test whether equivalent record dtypes hash the same."""
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('yo', np.int)])
+        assert_dtype_equal(a, b)
+
+    def test_different_names(self):
+        # In theory, they may hash the same (collision) ?
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('ye', np.int)])
+        assert_dtype_not_equal(a, b)
+
+    def test_different_titles(self):
+        # In theory, they may hash the same (collision) ?
+        a = np.dtype({'names': ['r', 'b'],
+                      'formats': ['u1', 'u1'],
+                      'titles': ['Red pixel', 'Blue pixel']})
+        b = np.dtype({'names': ['r', 'b'],
+                      'formats': ['u1', 'u1'],
+                      'titles': ['RRed pixel', 'Blue pixel']})
+        assert_dtype_not_equal(a, b)
+
+    def test_mutate(self):
+        # Mutating a dtype should reset the cached hash value
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('yo', np.int)])
+        c = np.dtype([('ye', np.int)])
+        assert_dtype_equal(a, b)
+        assert_dtype_not_equal(a, c)
+        a.names = ['ye']
+        assert_dtype_equal(a, c)
+        assert_dtype_not_equal(a, b)
+        state = b.__reduce__()[2]
+        a.__setstate__(state)
+        assert_dtype_equal(a, b)
+        assert_dtype_not_equal(a, c)
+
+    def test_not_lists(self):
+        """Test if an appropriate exception is raised when passing bad values to
+        the dtype constructor.
+        """
+        self.assertRaises(TypeError, np.dtype,
+            dict(names=set(['A', 'B']), formats=['f8', 'i4']))
+        self.assertRaises(TypeError, np.dtype,
+            dict(names=['A', 'B'], formats=set(['f8', 'i4'])))
+
+    def test_aligned_size(self):
+        # Check that structured dtypes get padded to an aligned size
+        dt = np.dtype('i4, i1', align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype([('f0', 'i4'), ('f1', 'i1')], align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype({'names':['f0', 'f1'],
+                       'formats':['i4', 'u1'],
+                       'offsets':[0, 4]}, align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype({'f0': ('i4', 0), 'f1':('u1', 4)}, align=True)
+        assert_equal(dt.itemsize, 8)
+        # Nesting should preserve that alignment
+        dt1 = np.dtype([('f0', 'i4'),
+                       ('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
+                       ('f2', 'i1')], align=True)
+        assert_equal(dt1.itemsize, 20)
+        dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
+                       'formats':['i4',
+                                  [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
+                                  'i1'],
+                       'offsets':[0, 4, 16]}, align=True)
+        assert_equal(dt2.itemsize, 20)
+        dt3 = np.dtype({'f0': ('i4', 0),
+                       'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
+                       'f2': ('i1', 16)}, align=True)
+        assert_equal(dt3.itemsize, 20)
+        assert_equal(dt1, dt2)
+        assert_equal(dt2, dt3)
+        # Nesting should preserve packing
+        dt1 = np.dtype([('f0', 'i4'),
+                       ('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
+                       ('f2', 'i1')], align=False)
+        assert_equal(dt1.itemsize, 11)
+        dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
+                       'formats':['i4',
+                                  [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
+                                  'i1'],
+                       'offsets':[0, 4, 10]}, align=False)
+        assert_equal(dt2.itemsize, 11)
+        dt3 = np.dtype({'f0': ('i4', 0),
+                       'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
+                       'f2': ('i1', 10)}, align=False)
+        assert_equal(dt3.itemsize, 11)
+        assert_equal(dt1, dt2)
+        assert_equal(dt2, dt3)
+
+    def test_union_struct(self):
+        # Should be able to create union dtypes
+        dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
+                        'offsets':[0, 0, 2]}, align=True)
+        assert_equal(dt.itemsize, 4)
+        a = np.array([3], dtype='<u4').view(dt)
+        a['f1'] = 10
+        a['f2'] = 36
+        assert_equal(a['f0'], 10 + 36*256*256)
+        # Should be able to specify fields out of order
+        dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
+                        'offsets':[4, 0, 2]}, align=True)
+        assert_equal(dt.itemsize, 8)
+        dt2 = np.dtype({'names':['f2', 'f0', 'f1'],
+                        'formats':['<u2', '<u4', '<u2'],
+                        'offsets':[2, 4, 0]}, align=True)
+        vals = [(0, 1, 2), (3, -1, 4)]
+        vals2 = [(2, 0, 1), (4, 3, -1)]
+        a = np.array(vals, dt)
+        b = np.array(vals2, dt2)
+        assert_equal(a.astype(dt2), b)
+        assert_equal(b.astype(dt), a)
+        assert_equal(a.view(dt2), b)
+        assert_equal(b.view(dt), a)
+        # Should not be able to overlap objects with other types
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['O', 'i1'],
+                 'offsets':[0, 2]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['i4', 'O'],
+                 'offsets':[0, 3]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':[[('a', 'O')], 'i1'],
+                 'offsets':[0, 2]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['i4', [('a', 'O')]],
+                 'offsets':[0, 3]})
+        # Out of order should still be ok, however
+        dt = np.dtype({'names':['f0', 'f1'],
+                       'formats':['i1', 'O'],
+                       'offsets':[np.dtype('intp').itemsize, 0]})
+
+    def test_comma_datetime(self):
+        dt = np.dtype('M8[D],datetime64[Y],i8')
+        assert_equal(dt, np.dtype([('f0', 'M8[D]'),
+                                   ('f1', 'datetime64[Y]'),
+                                   ('f2', 'i8')]))
+
+    def test_from_dictproxy(self):
+        # Tests for PR #5920
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'f4']})
+        assert_dtype_equal(dt, np.dtype(dt.fields))
+        dt2 = np.dtype((np.void, dt.fields))
+        assert_equal(dt2.fields, dt.fields)
+
+    def test_bool_commastring(self):
+        d = np.dtype('?,?,?')  # raises?
+        assert_equal(len(d.names), 3)
+        for n in d.names:
+            assert_equal(d.fields[n][0], np.dtype('?'))
+
+
+class TestSubarray(TestCase):
+    def test_single_subarray(self):
+        a = np.dtype((np.int, (2)))
+        b = np.dtype((np.int, (2,)))
+        assert_dtype_equal(a, b)
+
+        assert_equal(type(a.subdtype[1]), tuple)
+        assert_equal(type(b.subdtype[1]), tuple)
+
+    def test_equivalent_record(self):
+        """Test whether equivalent subarray dtypes hash the same."""
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (2, 3)))
+        assert_dtype_equal(a, b)
+
+    def test_nonequivalent_record(self):
+        """Test whether different subarray dtypes hash differently."""
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (3, 2)))
+        assert_dtype_not_equal(a, b)
+
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (2, 2)))
+        assert_dtype_not_equal(a, b)
+
+        a = np.dtype((np.int, (1, 2, 3)))
+        b = np.dtype((np.int, (1, 2)))
+        assert_dtype_not_equal(a, b)
+
+    def test_shape_equal(self):
+        """Test some data types that are equal"""
+        assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', tuple())))
+        assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', 1)))
+        assert_dtype_equal(np.dtype((np.int, 2)), np.dtype((np.int, (2,))))
+        assert_dtype_equal(np.dtype(('<f4', (3, 2))), np.dtype(('<f4', (3, 2))))
+        d = ([('a', 'f4', (1, 2)), ('b', 'f8', (3, 1))], (3, 2))
+        assert_dtype_equal(np.dtype(d), np.dtype(d))
+
+    def test_shape_simple(self):
+        """Test some simple cases that shouldn't be equal"""
+        assert_dtype_not_equal(np.dtype('f8'), np.dtype(('f8', (1,))))
+        assert_dtype_not_equal(np.dtype(('f8', (1,))), np.dtype(('f8', (1, 1))))
+        assert_dtype_not_equal(np.dtype(('f4', (3, 2))), np.dtype(('f4', (2, 3))))
+
+    def test_shape_monster(self):
+        """Test some more complicated cases that shouldn't be equal"""
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', 'f4', (1, 2)), ('b', 'f8', (1, 3))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'i8', (1, 3))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('e', 'f8', (1, 3)), ('d', 'f4', (2, 1))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', [('a', 'i4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', [('a', 'u4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))))
+
+    def test_shape_sequence(self):
+        # Any sequence of integers should work as shape, but the result
+        # should be a tuple (immutable) of base type integers.
+        a = np.array([1, 2, 3], dtype=np.int16)
+        l = [1, 2, 3]
+        # Array gets converted
+        dt = np.dtype([('a', 'f4', a)])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+        # List gets converted
+        dt = np.dtype([('a', 'f4', l)])
+        assert_(isinstance(dt['a'].shape, tuple))
+        #
+
+        class IntLike(object):
+            def __index__(self):
+                return 3
+
+            def __int__(self):
+                # (a PyNumber_Check fails without __int__)
+                return 3
+
+        dt = np.dtype([('a', 'f4', IntLike())])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+        dt = np.dtype([('a', 'f4', (IntLike(),))])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+
+    def test_shape_invalid(self):
+        # Check that the shape is valid.
+        max_int = np.iinfo(np.intc).max
+        max_intp = np.iinfo(np.intp).max
+        # Too large values (the datatype is part of this)
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_int // 4 + 1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_int + 1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', (max_int, 2))])
+        # Takes a different code path (fails earlier:
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_intp + 1)])
+        # Negative values
+        assert_raises(ValueError, np.dtype, [('a', 'f4', -1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', (-1, -1))])
+
+    def test_alignment(self):
+        #Check that subarrays are aligned
+        t1 = np.dtype('1i4', align=True)
+        t2 = np.dtype('2i4', align=True)
+        assert_equal(t1.alignment, t2.alignment)
+
+
+class TestMonsterType(TestCase):
+    """Test deeply nested subtypes."""
+
+    def test1(self):
+        simple1 = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+            'titles': ['Red pixel', 'Blue pixel']})
+        a = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((np.int, (3, 2))))])
+        b = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((np.int, (3, 2))))])
+        assert_dtype_equal(a, b)
+
+        c = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((a, (3, 2))))])
+        d = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((a, (3, 2))))])
+        assert_dtype_equal(c, d)
+
+class TestMetadata(TestCase):
+    def test_no_metadata(self):
+        d = np.dtype(int)
+        self.assertEqual(d.metadata, None)
+
+    def test_metadata_takes_dict(self):
+        d = np.dtype(int, metadata={'datum': 1})
+        self.assertEqual(d.metadata, {'datum': 1})
+
+    def test_metadata_rejects_nondict(self):
+        self.assertRaises(TypeError, np.dtype, int, metadata='datum')
+        self.assertRaises(TypeError, np.dtype, int, metadata=1)
+        self.assertRaises(TypeError, np.dtype, int, metadata=None)
+
+    def test_nested_metadata(self):
+        d = np.dtype([('a', np.dtype(int, metadata={'datum': 1}))])
+        self.assertEqual(d['a'].metadata, {'datum': 1})
+
+    def base_metadata_copied(self):
+        d = np.dtype((np.void, np.dtype('i4,i4', metadata={'datum': 1})))
+        assert_equal(d.metadata, {'datum': 1})
+
+class TestString(TestCase):
+    def test_complex_dtype_str(self):
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))], (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])])
+        assert_equal(str(dt),
+                     "[('top', [('tiles', ('>f4', (64, 64)), (1,)), "
+                     "('rtile', '>f4', (64, 36))], (3,)), "
+                     "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
+                     "('bright', '>f4', (8, 36))])]")
+
+        # If the sticky aligned flag is set to True, it makes the
+        # str() function use a dict representation with an 'aligned' flag
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))],
+                                (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])],
+                       align=True)
+        assert_equal(str(dt),
+                    "{'names':['top','bottom'], "
+                     "'formats':[([('tiles', ('>f4', (64, 64)), (1,)), "
+                                  "('rtile', '>f4', (64, 36))], (3,)),"
+                                 "[('bleft', ('>f4', (8, 64)), (1,)), "
+                                  "('bright', '>f4', (8, 36))]], "
+                     "'offsets':[0,76800], "
+                     "'itemsize':80000, "
+                     "'aligned':True}")
+        assert_equal(np.dtype(eval(str(dt))), dt)
+
+        dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
+                        'offsets': [0, 1, 2],
+                        'titles': ['Red pixel', 'Green pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "[(('Red pixel', 'r'), 'u1'), "
+                    "(('Green pixel', 'g'), 'u1'), "
+                    "(('Blue pixel', 'b'), 'u1')]")
+
+        dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
+                       'formats': ['<u4', 'u1', 'u1', 'u1'],
+                       'offsets': [0, 0, 1, 2],
+                       'titles': ['Color', 'Red pixel',
+                                  'Green pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "{'names':['rgba','r','g','b'],"
+                    " 'formats':['<u4','u1','u1','u1'],"
+                    " 'offsets':[0,0,1,2],"
+                    " 'titles':['Color','Red pixel',"
+                              "'Green pixel','Blue pixel'],"
+                    " 'itemsize':4}")
+
+        dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+                        'offsets': [0, 2],
+                        'titles': ['Red pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "{'names':['r','b'],"
+                    " 'formats':['u1','u1'],"
+                    " 'offsets':[0,2],"
+                    " 'titles':['Red pixel','Blue pixel'],"
+                    " 'itemsize':3}")
+
+        dt = np.dtype([('a', '<m8[D]'), ('b', '<M8[us]')])
+        assert_equal(str(dt),
+                    "[('a', '<m8[D]'), ('b', '<M8[us]')]")
+
+    def test_complex_dtype_repr(self):
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))], (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])])
+        assert_equal(repr(dt),
+                     "dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), "
+                     "('rtile', '>f4', (64, 36))], (3,)), "
+                     "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
+                     "('bright', '>f4', (8, 36))])])")
+
+        dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
+                        'offsets': [0, 1, 2],
+                        'titles': ['Red pixel', 'Green pixel', 'Blue pixel']},
+                        align=True)
+        assert_equal(repr(dt),
+                    "dtype([(('Red pixel', 'r'), 'u1'), "
+                    "(('Green pixel', 'g'), 'u1'), "
+                    "(('Blue pixel', 'b'), 'u1')], align=True)")
+
+        dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
+                       'formats': ['<u4', 'u1', 'u1', 'u1'],
+                       'offsets': [0, 0, 1, 2],
+                       'titles': ['Color', 'Red pixel',
+                                  'Green pixel', 'Blue pixel']}, align=True)
+        assert_equal(repr(dt),
+                    "dtype({'names':['rgba','r','g','b'],"
+                    " 'formats':['<u4','u1','u1','u1'],"
+                    " 'offsets':[0,0,1,2],"
+                    " 'titles':['Color','Red pixel',"
+                              "'Green pixel','Blue pixel'],"
+                    " 'itemsize':4}, align=True)")
+
+        dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+                        'offsets': [0, 2],
+                        'titles': ['Red pixel', 'Blue pixel'],
+                        'itemsize': 4})
+        assert_equal(repr(dt),
+                    "dtype({'names':['r','b'], "
+                    "'formats':['u1','u1'], "
+                    "'offsets':[0,2], "
+                    "'titles':['Red pixel','Blue pixel'], "
+                    "'itemsize':4})")
+
+        dt = np.dtype([('a', '<M8[D]'), ('b', '<m8[us]')])
+        assert_equal(repr(dt),
+                    "dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_dtype_str_with_long_in_shape(self):
+        # Pull request #376, should not error
+        np.dtype('(1L,)i4')
+
+    def test_base_dtype_with_object_type(self):
+        # Issue gh-2798, should not error.
+        np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
+
+    def test_empty_string_to_object(self):
+        # Pull request #4722
+        np.array(["", ""]).astype(object)
+
+class TestDtypeAttributeDeletion(TestCase):
+
+    def test_dtype_non_writable_attributes_deletion(self):
+        dt = np.dtype(np.double)
+        attr = ["subdtype", "descr", "str", "name", "base", "shape",
+                "isbuiltin", "isnative", "isalignedstruct", "fields",
+                "metadata", "hasobject"]
+
+        for s in attr:
+            assert_raises(AttributeError, delattr, dt, s)
+
+    def test_dtype_writable_attributes_deletion(self):
+        dt = np.dtype(np.double)
+        attr = ["names"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, dt, s)
+
+
+class TestDtypeAttributes(TestCase):
+    def test_descr_has_trailing_void(self):
+        # see gh-6359
+        dtype = np.dtype({
+            'names': ['A', 'B'],
+            'formats': ['f4', 'f4'],
+            'offsets': [0, 8],
+            'itemsize': 16})
+        new_dtype = np.dtype(dtype.descr)
+        assert_equal(new_dtype.itemsize, 16)
+
+
+class TestDtypeAttributes(TestCase):
+
+    def test_name_builtin(self):
+        for t in np.typeDict.values():
+            name = t.__name__
+            if name.endswith('_'):
+                name = name[:-1]
+            assert_equal(np.dtype(t).name, name)
+
+    def test_name_dtype_subclass(self):
+        # Ticket #4357
+        class user_def_subcls(np.void):
+            pass
+        assert_equal(np.dtype(user_def_subcls).name, 'user_def_subcls')
+
+
+def test_rational_dtype():
+    # test for bug gh-5719
+    a = np.array([1111], dtype=rational).astype
+    assert_raises(OverflowError, a, 'int8')
+
+    # test that dtype detection finds user-defined types
+    x = rational(1)
+    assert_equal(np.array([x,x]).dtype, np.dtype(rational))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
new file mode 100644
index 0000000000..1f863a7db9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
@@ -0,0 +1,627 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_raises
+    )
+
+class TestEinSum(TestCase):
+    def test_einsum_errors(self):
+        # Need enough arguments
+        assert_raises(ValueError, np.einsum)
+        assert_raises(ValueError, np.einsum, "")
+
+        # subscripts must be a string
+        assert_raises(TypeError, np.einsum, 0, 0)
+
+        # out parameter must be an array
+        assert_raises(TypeError, np.einsum, "", 0, out='test')
+
+        # order parameter must be a valid order
+        assert_raises(TypeError, np.einsum, "", 0, order='W')
+
+        # casting parameter must be a valid casting
+        assert_raises(ValueError, np.einsum, "", 0, casting='blah')
+
+        # dtype parameter must be a valid dtype
+        assert_raises(TypeError, np.einsum, "", 0, dtype='bad_data_type')
+
+        # other keyword arguments are rejected
+        assert_raises(TypeError, np.einsum, "", 0, bad_arg=0)
+
+        # issue 4528 revealed a segfault with this call
+        assert_raises(TypeError, np.einsum, *(None,)*63)
+
+        # number of operands must match count in subscripts string
+        assert_raises(ValueError, np.einsum, "", 0, 0)
+        assert_raises(ValueError, np.einsum, ",", 0, [0], [0])
+        assert_raises(ValueError, np.einsum, ",", [0])
+
+        # can't have more subscripts than dimensions in the operand
+        assert_raises(ValueError, np.einsum, "i", 0)
+        assert_raises(ValueError, np.einsum, "ij", [0, 0])
+        assert_raises(ValueError, np.einsum, "...i", 0)
+        assert_raises(ValueError, np.einsum, "i...j", [0, 0])
+        assert_raises(ValueError, np.einsum, "i...", 0)
+        assert_raises(ValueError, np.einsum, "ij...", [0, 0])
+
+        # invalid ellipsis
+        assert_raises(ValueError, np.einsum, "i..", [0, 0])
+        assert_raises(ValueError, np.einsum, ".i...", [0, 0])
+        assert_raises(ValueError, np.einsum, "j->..j", [0, 0])
+        assert_raises(ValueError, np.einsum, "j->.j...", [0, 0])
+
+        # invalid subscript character
+        assert_raises(ValueError, np.einsum, "i%...", [0, 0])
+        assert_raises(ValueError, np.einsum, "...j$", [0, 0])
+        assert_raises(ValueError, np.einsum, "i->&", [0, 0])
+
+        # output subscripts must appear in input
+        assert_raises(ValueError, np.einsum, "i->ij", [0, 0])
+
+        # output subscripts may only be specified once
+        assert_raises(ValueError, np.einsum, "ij->jij", [[0, 0], [0, 0]])
+
+        # dimensions much match when being collapsed
+        assert_raises(ValueError, np.einsum, "ii", np.arange(6).reshape(2, 3))
+        assert_raises(ValueError, np.einsum, "ii->i", np.arange(6).reshape(2, 3))
+
+        # broadcasting to new dimensions must be enabled explicitly
+        assert_raises(ValueError, np.einsum, "i", np.arange(6).reshape(2, 3))
+        assert_raises(ValueError, np.einsum, "i->i", [[0, 1], [0, 1]],
+                                            out=np.arange(4).reshape(2, 2))
+
+    def test_einsum_views(self):
+        # pass-through
+        a = np.arange(6)
+        a.shape = (2, 3)
+
+        b = np.einsum("...", a)
+        assert_(b.base is a)
+
+        b = np.einsum(a, [Ellipsis])
+        assert_(b.base is a)
+
+        b = np.einsum("ij", a)
+        assert_(b.base is a)
+        assert_equal(b, a)
+
+        b = np.einsum(a, [0, 1])
+        assert_(b.base is a)
+        assert_equal(b, a)
+
+        # output is writeable whenever input is writeable
+        b = np.einsum("...", a)
+        assert_(b.flags['WRITEABLE'])
+        a.flags['WRITEABLE'] = False
+        b = np.einsum("...", a)
+        assert_(not b.flags['WRITEABLE'])
+
+        # transpose
+        a = np.arange(6)
+        a.shape = (2, 3)
+
+        b = np.einsum("ji", a)
+        assert_(b.base is a)
+        assert_equal(b, a.T)
+
+        b = np.einsum(a, [1, 0])
+        assert_(b.base is a)
+        assert_equal(b, a.T)
+
+        # diagonal
+        a = np.arange(9)
+        a.shape = (3, 3)
+
+        b = np.einsum("ii->i", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0], [0])
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i] for i in range(3)])
+
+        # diagonal with various ways of broadcasting an additional dimension
+        a = np.arange(27)
+        a.shape = (3, 3, 3)
+
+        b = np.einsum("...ii->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)] for x in a])
+
+        b = np.einsum(a, [Ellipsis, 0, 0], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)] for x in a])
+
+        b = np.einsum("ii...->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(2, 0, 1)])
+
+        b = np.einsum(a, [0, 0, Ellipsis], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(2, 0, 1)])
+
+        b = np.einsum("...ii->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [Ellipsis, 0, 0], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum("jii->ij", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [1, 0, 0], [0, 1])
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum("ii...->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0, Ellipsis], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)])
+
+        b = np.einsum("i...i->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, Ellipsis, 0], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)])
+
+        b = np.einsum("i...i->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(1, 0, 2)])
+
+        b = np.einsum(a, [0, Ellipsis, 0], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(1, 0, 2)])
+
+        # triple diagonal
+        a = np.arange(27)
+        a.shape = (3, 3, 3)
+
+        b = np.einsum("iii->i", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0, 0], [0])
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i, i] for i in range(3)])
+
+        # swap axes
+        a = np.arange(24)
+        a.shape = (2, 3, 4)
+
+        b = np.einsum("ijk->jik", a)
+        assert_(b.base is a)
+        assert_equal(b, a.swapaxes(0, 1))
+
+        b = np.einsum(a, [0, 1, 2], [1, 0, 2])
+        assert_(b.base is a)
+        assert_equal(b, a.swapaxes(0, 1))
+
+    def check_einsum_sums(self, dtype):
+        # Check various sums.  Does many sizes to exercise unrolled loops.
+
+        # sum(a, axis=-1)
+        for n in range(1, 17):
+            a = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("i->", a), np.sum(a, axis=-1).astype(dtype))
+            assert_equal(np.einsum(a, [0], []),
+                         np.sum(a, axis=-1).astype(dtype))
+
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("...i->...", a),
+                         np.sum(a, axis=-1).astype(dtype))
+            assert_equal(np.einsum(a, [Ellipsis, 0], [Ellipsis]),
+                         np.sum(a, axis=-1).astype(dtype))
+
+        # sum(a, axis=0)
+        for n in range(1, 17):
+            a = np.arange(2*n, dtype=dtype).reshape(2, n)
+            assert_equal(np.einsum("i...->...", a),
+                         np.sum(a, axis=0).astype(dtype))
+            assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis]),
+                         np.sum(a, axis=0).astype(dtype))
+
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("i...->...", a),
+                         np.sum(a, axis=0).astype(dtype))
+            assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis]),
+                         np.sum(a, axis=0).astype(dtype))
+
+        # trace(a)
+        for n in range(1, 17):
+            a = np.arange(n*n, dtype=dtype).reshape(n, n)
+            assert_equal(np.einsum("ii", a), np.trace(a).astype(dtype))
+            assert_equal(np.einsum(a, [0, 0]), np.trace(a).astype(dtype))
+
+        # multiply(a, b)
+        assert_equal(np.einsum("..., ...", 3, 4), 12)  # scalar case
+        for n in range(1, 17):
+            a = np.arange(3*n, dtype=dtype).reshape(3, n)
+            b = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("..., ...", a, b), np.multiply(a, b))
+            assert_equal(np.einsum(a, [Ellipsis], b, [Ellipsis]),
+                         np.multiply(a, b))
+
+        # inner(a,b)
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            b = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("...i, ...i", a, b), np.inner(a, b))
+            assert_equal(np.einsum(a, [Ellipsis, 0], b, [Ellipsis, 0]),
+                         np.inner(a, b))
+
+        for n in range(1, 11):
+            a = np.arange(n*3*2, dtype=dtype).reshape(n, 3, 2)
+            b = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("i..., i...", a, b), np.inner(a.T, b.T).T)
+            assert_equal(np.einsum(a, [0, Ellipsis], b, [0, Ellipsis]),
+                         np.inner(a.T, b.T).T)
+
+        # outer(a,b)
+        for n in range(1, 17):
+            a = np.arange(3, dtype=dtype)+1
+            b = np.arange(n, dtype=dtype)+1
+            assert_equal(np.einsum("i,j", a, b), np.outer(a, b))
+            assert_equal(np.einsum(a, [0], b, [1]), np.outer(a, b))
+
+        # Suppress the complex warnings for the 'as f8' tests
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', np.ComplexWarning)
+
+            # matvec(a,b) / a.dot(b) where a is matrix, b is vector
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n, dtype=dtype)
+                assert_equal(np.einsum("ij, j", a, b), np.dot(a, b))
+                assert_equal(np.einsum(a, [0, 1], b, [1]), np.dot(a, b))
+
+                c = np.arange(4, dtype=dtype)
+                np.einsum("ij,j", a, b, out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1], b, [1], out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n, dtype=dtype)
+                assert_equal(np.einsum("ji,j", a.T, b.T), np.dot(b.T, a.T))
+                assert_equal(np.einsum(a.T, [1, 0], b.T, [1]), np.dot(b.T, a.T))
+
+                c = np.arange(4, dtype=dtype)
+                np.einsum("ji,j", a.T, b.T, out=c, dtype='f8', casting='unsafe')
+                assert_equal(c,
+                        np.dot(b.T.astype('f8'),
+                               a.T.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a.T, [1, 0], b.T, [1], out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                        np.dot(b.T.astype('f8'),
+                               a.T.astype('f8')).astype(dtype))
+
+            # matmat(a,b) / a.dot(b) where a is matrix, b is matrix
+            for n in range(1, 17):
+                if n < 8 or dtype != 'f2':
+                    a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                    b = np.arange(n*6, dtype=dtype).reshape(n, 6)
+                    assert_equal(np.einsum("ij,jk", a, b), np.dot(a, b))
+                    assert_equal(np.einsum(a, [0, 1], b, [1, 2]), np.dot(a, b))
+
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n*6, dtype=dtype).reshape(n, 6)
+                c = np.arange(24, dtype=dtype).reshape(4, 6)
+                np.einsum("ij,jk", a, b, out=c, dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1], b, [1, 2], out=c,
+                                dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+
+            # matrix triple product (note this is not currently an efficient
+            # way to multiply 3 matrices)
+            a = np.arange(12, dtype=dtype).reshape(3, 4)
+            b = np.arange(20, dtype=dtype).reshape(4, 5)
+            c = np.arange(30, dtype=dtype).reshape(5, 6)
+            if dtype != 'f2':
+                assert_equal(np.einsum("ij,jk,kl", a, b, c),
+                                    a.dot(b).dot(c))
+                assert_equal(np.einsum(a, [0, 1], b, [1, 2], c, [2, 3]),
+                                    a.dot(b).dot(c))
+
+            d = np.arange(18, dtype=dtype).reshape(3, 6)
+            np.einsum("ij,jk,kl", a, b, c, out=d,
+                      dtype='f8', casting='unsafe')
+            tgt = a.astype('f8').dot(b.astype('f8'))
+            tgt = tgt.dot(c.astype('f8')).astype(dtype)
+            assert_equal(d, tgt)
+
+            d[...] = 0
+            np.einsum(a, [0, 1], b, [1, 2], c, [2, 3], out=d,
+                      dtype='f8', casting='unsafe')
+            tgt = a.astype('f8').dot(b.astype('f8'))
+            tgt = tgt.dot(c.astype('f8')).astype(dtype)
+            assert_equal(d, tgt)
+
+            # tensordot(a, b)
+            if np.dtype(dtype) != np.dtype('f2'):
+                a = np.arange(60, dtype=dtype).reshape(3, 4, 5)
+                b = np.arange(24, dtype=dtype).reshape(4, 3, 2)
+                assert_equal(np.einsum("ijk, jil -> kl", a, b),
+                                np.tensordot(a, b, axes=([1, 0], [0, 1])))
+                assert_equal(np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3]),
+                                np.tensordot(a, b, axes=([1, 0], [0, 1])))
+
+                c = np.arange(10, dtype=dtype).reshape(5, 2)
+                np.einsum("ijk,jil->kl", a, b, out=c,
+                                        dtype='f8', casting='unsafe')
+                assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'),
+                                        axes=([1, 0], [0, 1])).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3], out=c,
+                                        dtype='f8', casting='unsafe')
+                assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'),
+                                        axes=([1, 0], [0, 1])).astype(dtype))
+
+        # logical_and(logical_and(a!=0, b!=0), c!=0)
+        a = np.array([1,   3,   -2,   0,   12,  13,   0,   1], dtype=dtype)
+        b = np.array([0,   3.5, 0.,   -2,  0,   1,    3,   12], dtype=dtype)
+        c = np.array([True, True, False, True, True, False, True, True])
+        assert_equal(np.einsum("i,i,i->i", a, b, c,
+                                dtype='?', casting='unsafe'),
+                            np.logical_and(np.logical_and(a != 0, b != 0), c != 0))
+        assert_equal(np.einsum(a, [0], b, [0], c, [0], [0],
+                                dtype='?', casting='unsafe'),
+                            np.logical_and(np.logical_and(a != 0, b != 0), c != 0))
+
+        a = np.arange(9, dtype=dtype)
+        assert_equal(np.einsum(",i->", 3, a), 3*np.sum(a))
+        assert_equal(np.einsum(3, [], a, [0], []), 3*np.sum(a))
+        assert_equal(np.einsum("i,->", a, 3), 3*np.sum(a))
+        assert_equal(np.einsum(a, [0], 3, [], []), 3*np.sum(a))
+
+        # Various stride0, contiguous, and SSE aligned variants
+        for n in range(1, 25):
+            a = np.arange(n, dtype=dtype)
+            if np.dtype(dtype).itemsize > 1:
+                assert_equal(np.einsum("...,...", a, a), np.multiply(a, a))
+                assert_equal(np.einsum("i,i", a, a), np.dot(a, a))
+                assert_equal(np.einsum("i,->i", a, 2), 2*a)
+                assert_equal(np.einsum(",i->i", 2, a), 2*a)
+                assert_equal(np.einsum("i,->", a, 2), 2*np.sum(a))
+                assert_equal(np.einsum(",i->", 2, a), 2*np.sum(a))
+
+                assert_equal(np.einsum("...,...", a[1:], a[:-1]),
+                             np.multiply(a[1:], a[:-1]))
+                assert_equal(np.einsum("i,i", a[1:], a[:-1]),
+                             np.dot(a[1:], a[:-1]))
+                assert_equal(np.einsum("i,->i", a[1:], 2), 2*a[1:])
+                assert_equal(np.einsum(",i->i", 2, a[1:]), 2*a[1:])
+                assert_equal(np.einsum("i,->", a[1:], 2), 2*np.sum(a[1:]))
+                assert_equal(np.einsum(",i->", 2, a[1:]), 2*np.sum(a[1:]))
+
+        # An object array, summed as the data type
+        a = np.arange(9, dtype=object)
+
+        b = np.einsum("i->", a, dtype=dtype, casting='unsafe')
+        assert_equal(b, np.sum(a))
+        assert_equal(b.dtype, np.dtype(dtype))
+
+        b = np.einsum(a, [0], [], dtype=dtype, casting='unsafe')
+        assert_equal(b, np.sum(a))
+        assert_equal(b.dtype, np.dtype(dtype))
+
+        # A case which was failing (ticket #1885)
+        p = np.arange(2) + 1
+        q = np.arange(4).reshape(2, 2) + 3
+        r = np.arange(4).reshape(2, 2) + 7
+        assert_equal(np.einsum('z,mz,zm->', p, q, r), 253)
+
+    def test_einsum_sums_int8(self):
+        self.check_einsum_sums('i1')
+
+    def test_einsum_sums_uint8(self):
+        self.check_einsum_sums('u1')
+
+    def test_einsum_sums_int16(self):
+        self.check_einsum_sums('i2')
+
+    def test_einsum_sums_uint16(self):
+        self.check_einsum_sums('u2')
+
+    def test_einsum_sums_int32(self):
+        self.check_einsum_sums('i4')
+
+    def test_einsum_sums_uint32(self):
+        self.check_einsum_sums('u4')
+
+    def test_einsum_sums_int64(self):
+        self.check_einsum_sums('i8')
+
+    def test_einsum_sums_uint64(self):
+        self.check_einsum_sums('u8')
+
+    def test_einsum_sums_float16(self):
+        self.check_einsum_sums('f2')
+
+    def test_einsum_sums_float32(self):
+        self.check_einsum_sums('f4')
+
+    def test_einsum_sums_float64(self):
+        self.check_einsum_sums('f8')
+
+    def test_einsum_sums_longdouble(self):
+        self.check_einsum_sums(np.longdouble)
+
+    def test_einsum_sums_cfloat64(self):
+        self.check_einsum_sums('c8')
+
+    def test_einsum_sums_cfloat128(self):
+        self.check_einsum_sums('c16')
+
+    def test_einsum_sums_clongdouble(self):
+        self.check_einsum_sums(np.clongdouble)
+
+    def test_einsum_misc(self):
+        # This call used to crash because of a bug in
+        # PyArray_AssignZero
+        a = np.ones((1, 2))
+        b = np.ones((2, 2, 1))
+        assert_equal(np.einsum('ij...,j...->i...', a, b), [[[2], [2]]])
+
+        # The iterator had an issue with buffering this reduction
+        a = np.ones((5, 12, 4, 2, 3), np.int64)
+        b = np.ones((5, 12, 11), np.int64)
+        assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b),
+                        np.einsum('ijklm,ijn->', a, b))
+
+        # Issue #2027, was a problem in the contiguous 3-argument
+        # inner loop implementation
+        a = np.arange(1, 3)
+        b = np.arange(1, 5).reshape(2, 2)
+        c = np.arange(1, 9).reshape(4, 2)
+        assert_equal(np.einsum('x,yx,zx->xzy', a, b, c),
+                    [[[1,  3], [3,  9], [5, 15], [7, 21]],
+                    [[8, 16], [16, 32], [24, 48], [32, 64]]])
+
+    def test_einsum_broadcast(self):
+        # Issue #2455 change in handling ellipsis
+        # remove the 'middle broadcast' error
+        # only use the 'RIGHT' iteration in prepare_op_axes
+        # adds auto broadcast on left where it belongs
+        # broadcast on right has to be explicit
+
+        A = np.arange(2*3*4).reshape(2,3,4)
+        B = np.arange(3)
+        ref = np.einsum('ijk,j->ijk',A, B)
+        assert_equal(np.einsum('ij...,j...->ij...',A, B), ref)
+        assert_equal(np.einsum('ij...,...j->ij...',A, B), ref)
+        assert_equal(np.einsum('ij...,j->ij...',A, B), ref)  # used to raise error
+
+        A = np.arange(12).reshape((4,3))
+        B = np.arange(6).reshape((3,2))
+        ref = np.einsum('ik,kj->ij', A, B)
+        assert_equal(np.einsum('ik...,k...->i...', A, B), ref)
+        assert_equal(np.einsum('ik...,...kj->i...j', A, B), ref)
+        assert_equal(np.einsum('...k,kj', A, B), ref)  # used to raise error
+        assert_equal(np.einsum('ik,k...->i...', A, B), ref)  # used to raise error
+
+        dims = [2,3,4,5]
+        a = np.arange(np.prod(dims)).reshape(dims)
+        v = np.arange(dims[2])
+        ref = np.einsum('ijkl,k->ijl', a, v)
+        assert_equal(np.einsum('ijkl,k', a, v), ref)
+        assert_equal(np.einsum('...kl,k', a, v), ref)  # used to raise error
+        assert_equal(np.einsum('...kl,k...', a, v), ref)
+        # no real diff from 1st
+
+        J,K,M = 160,160,120
+        A = np.arange(J*K*M).reshape(1,1,1,J,K,M)
+        B = np.arange(J*K*M*3).reshape(J,K,M,3)
+        ref = np.einsum('...lmn,...lmno->...o', A, B)
+        assert_equal(np.einsum('...lmn,lmno->...o', A, B), ref)  # used to raise error
+
+    def test_einsum_fixedstridebug(self):
+        # Issue #4485 obscure einsum bug
+        # This case revealed a bug in nditer where it reported a stride
+        # as 'fixed' (0) when it was in fact not fixed during processing
+        # (0 or 4). The reason for the bug was that the check for a fixed
+        # stride was using the information from the 2D inner loop reuse
+        # to restrict the iteration dimensions it had to validate to be
+        # the same, but that 2D inner loop reuse logic is only triggered
+        # during the buffer copying step, and hence it was invalid to
+        # rely on those values. The fix is to check all the dimensions
+        # of the stride in question, which in the test case reveals that
+        # the stride is not fixed.
+        #
+        # NOTE: This test is triggered by the fact that the default buffersize,
+        #       used by einsum, is 8192, and 3*2731 = 8193, is larger than that
+        #       and results in a mismatch between the buffering and the
+        #       striding for operand A.
+        A = np.arange(2*3).reshape(2,3).astype(np.float32)
+        B = np.arange(2*3*2731).reshape(2,3,2731).astype(np.int16)
+        es = np.einsum('cl,cpx->lpx', A, B)
+        tp = np.tensordot(A, B, axes=(0, 0))
+        assert_equal(es, tp)
+        # The following is the original test case from the bug report,
+        # made repeatable by changing random arrays to aranges.
+        A = np.arange(3*3).reshape(3,3).astype(np.float64)
+        B = np.arange(3*3*64*64).reshape(3,3,64,64).astype(np.float32)
+        es = np.einsum('cl,cpxy->lpxy', A,B)
+        tp = np.tensordot(A,B, axes=(0,0))
+        assert_equal(es, tp)
+
+    def test_einsum_fixed_collapsingbug(self):
+        # Issue #5147.
+        # The bug only occured when output argument of einssum was used.
+        x = np.random.normal(0, 1, (5, 5, 5, 5))
+        y1 = np.zeros((5, 5))
+        np.einsum('aabb->ab', x, out=y1)
+        idx = np.arange(5)
+        y2 = x[idx[:, None], idx[:, None], idx, idx]
+        assert_equal(y1, y2)
+
+    def test_einsum_all_contig_non_contig_output(self):
+        # Issue gh-5907, tests that the all contiguous special case
+        # actually checks the contiguity of the output
+        x = np.ones((5, 5))
+        out = np.ones(10)[::2]
+        correct_base = np.ones(10)
+        correct_base[::2] = 5
+        # Always worked (inner iteration is done with 0-stride):
+        np.einsum('mi,mi,mi->m', x, x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+        # Example 1:
+        out = np.ones(10)[::2]
+        np.einsum('im,im,im->m', x, x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+        # Example 2, buffering causes x to be contiguous but
+        # special cases do not catch the operation before:
+        out = np.ones((2, 2, 2))[..., 0]
+        correct_base = np.ones((2, 2, 2))
+        correct_base[..., 0] = 2
+        x = np.ones((2, 2), np.float32)
+        np.einsum('ij,jk->ik', x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+
+    def test_small_boolean_arrays(self):
+        # See gh-5946.
+        # Use array of True embedded in False.
+        a = np.zeros((16, 1, 1), dtype=np.bool_)[:2]
+        a[...] = True
+        out = np.zeros((16, 1, 1), dtype=np.bool_)[:2]
+        tgt = np.ones((2,1,1), dtype=np.bool_)
+        res = np.einsum('...ij,...jk->...ik', a, a, out=out)
+        assert_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
new file mode 100644
index 0000000000..7fc749a7ec
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
@@ -0,0 +1,52 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+import numpy as np
+from numpy.testing import TestCase, assert_, run_module_suite, dec
+
+
+class TestErrstate(TestCase):
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_invalid(self):
+        with np.errstate(all='raise', under='ignore'):
+            a = -np.arange(3)
+            # This should work
+            with np.errstate(invalid='ignore'):
+                np.sqrt(a)
+            # While this should fail!
+            try:
+                np.sqrt(a)
+            except FloatingPointError:
+                pass
+            else:
+                self.fail("Did not raise an invalid error")
+
+    def test_divide(self):
+        with np.errstate(all='raise', under='ignore'):
+            a = -np.arange(3)
+            # This should work
+            with np.errstate(divide='ignore'):
+                a // 0
+            # While this should fail!
+            try:
+                a // 0
+            except FloatingPointError:
+                pass
+            else:
+                self.fail("Did not raise divide by zero error")
+
+    def test_errcall(self):
+        def foo(*args):
+            print(args)
+
+        olderrcall = np.geterrcall()
+        with np.errstate(call=foo):
+            assert_(np.geterrcall() is foo, 'call is not foo')
+            with np.errstate(call=None):
+                assert_(np.geterrcall() is None, 'call is not None')
+        assert_(np.geterrcall() is olderrcall, 'call is not olderrcall')
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
new file mode 100644
index 0000000000..2afae2f6b2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
@@ -0,0 +1,225 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import contextlib
+import operator
+
+import numpy as np
+import numpy.core.multiarray_tests as mt
+from numpy.compat import long
+
+from numpy.testing import assert_raises, assert_equal
+
+
+INT64_MAX = np.iinfo(np.int64).max
+INT64_MIN = np.iinfo(np.int64).min
+INT64_MID = 2**32
+
+# int128 is not two's complement, the sign bit is separate
+INT128_MAX = 2**128 - 1
+INT128_MIN = -INT128_MAX
+INT128_MID = 2**64
+
+INT64_VALUES = (
+    [INT64_MIN + j for j in range(20)] +
+    [INT64_MAX - j for j in range(20)] +
+    [INT64_MID + j for j in range(-20, 20)] +
+    [2*INT64_MID + j for j in range(-20, 20)] +
+    [INT64_MID//2 + j for j in range(-20, 20)] +
+    list(range(-70, 70))
+)
+
+INT128_VALUES = (
+    [INT128_MIN + j for j in range(20)] +
+    [INT128_MAX - j for j in range(20)] +
+    [INT128_MID + j for j in range(-20, 20)] +
+    [2*INT128_MID + j for j in range(-20, 20)] +
+    [INT128_MID//2 + j for j in range(-20, 20)] +
+    list(range(-70, 70)) +
+    [False]  # negative zero
+)
+
+INT64_POS_VALUES = [x for x in INT64_VALUES if x > 0]
+
+
+@contextlib.contextmanager
+def exc_iter(*args):
+    """
+    Iterate over Cartesian product of *args, and if an exception is raised,
+    add information of the current iterate.
+    """
+
+    value = [None]
+
+    def iterate():
+        for v in itertools.product(*args):
+            value[0] = v
+            yield v
+
+    try:
+        yield iterate()
+    except:
+        import traceback
+        msg = "At: %r\n%s" % (repr(value[0]),
+                              traceback.format_exc())
+        raise AssertionError(msg)
+
+
+def test_safe_binop():
+    # Test checked arithmetic routines
+
+    ops = [
+        (operator.add, 1),
+        (operator.sub, 2),
+        (operator.mul, 3)
+    ]
+
+    with exc_iter(ops, INT64_VALUES, INT64_VALUES) as it:
+        for xop, a, b in it:
+            pyop, op = xop
+            c = pyop(a, b)
+
+            if not (INT64_MIN <= c <= INT64_MAX):
+                assert_raises(OverflowError, mt.extint_safe_binop, a, b, op)
+            else:
+                d = mt.extint_safe_binop(a, b, op)
+                if c != d:
+                    # assert_equal is slow
+                    assert_equal(d, c)
+
+
+def test_to_128():
+    with exc_iter(INT64_VALUES) as it:
+        for a, in it:
+            b = mt.extint_to_128(a)
+            if a != b:
+                assert_equal(b, a)
+
+
+def test_to_64():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if not (INT64_MIN <= a <= INT64_MAX):
+                assert_raises(OverflowError, mt.extint_to_64, a)
+            else:
+                b = mt.extint_to_64(a)
+                if a != b:
+                    assert_equal(b, a)
+
+
+def test_mul_64_64():
+    with exc_iter(INT64_VALUES, INT64_VALUES) as it:
+        for a, b in it:
+            c = a * b
+            d = mt.extint_mul_64_64(a, b)
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_add_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a + b
+            if not (INT128_MIN <= c <= INT128_MAX):
+                assert_raises(OverflowError, mt.extint_add_128, a, b)
+            else:
+                d = mt.extint_add_128(a, b)
+                if c != d:
+                    assert_equal(d, c)
+
+
+def test_sub_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a - b
+            if not (INT128_MIN <= c <= INT128_MAX):
+                assert_raises(OverflowError, mt.extint_sub_128, a, b)
+            else:
+                d = mt.extint_sub_128(a, b)
+                if c != d:
+                    assert_equal(d, c)
+
+
+def test_neg_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            b = -a
+            c = mt.extint_neg_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_shl_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if a < 0:
+                b = -(((-a) << 1) & (2**128-1))
+            else:
+                b = (a << 1) & (2**128-1)
+            c = mt.extint_shl_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_shr_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if a < 0:
+                b = -((-a) >> 1)
+            else:
+                b = a >> 1
+            c = mt.extint_shr_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_gt_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a > b
+            d = mt.extint_gt_128(a, b)
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_divmod_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            if a >= 0:
+                c, cr = divmod(a, b)
+            else:
+                c, cr = divmod(-a, b)
+                c = -c
+                cr = -cr
+
+            d, dr = mt.extint_divmod_128_64(a, b)
+
+            if c != d or d != dr or b*d + dr != a:
+                assert_equal(d, c)
+                assert_equal(dr, cr)
+                assert_equal(b*d + dr, a)
+
+
+def test_floordiv_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            c = a // b
+            d = mt.extint_floordiv_128_64(a, b)
+
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_ceildiv_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            c = (a + b - 1) // b
+            d = mt.extint_ceildiv_128_64(a, b)
+
+            if c != d:
+                assert_equal(d, c)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
new file mode 100644
index 0000000000..6b5430611a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
@@ -0,0 +1,155 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import (logspace, linspace, dtype, array, finfo, typecodes, arange,
+                   isnan, ndarray)
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal
+)
+
+
+class TestLogspace(TestCase):
+
+    def test_basic(self):
+        y = logspace(0, 6)
+        assert_(len(y) == 50)
+        y = logspace(0, 6, num=100)
+        assert_(y[-1] == 10 ** 6)
+        y = logspace(0, 6, endpoint=0)
+        assert_(y[-1] < 10 ** 6)
+        y = logspace(0, 6, num=7)
+        assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6])
+
+    def test_dtype(self):
+        y = logspace(0, 6, dtype='float32')
+        assert_equal(y.dtype, dtype('float32'))
+        y = logspace(0, 6, dtype='float64')
+        assert_equal(y.dtype, dtype('float64'))
+        y = logspace(0, 6, dtype='int32')
+        assert_equal(y.dtype, dtype('int32'))
+
+
+class TestLinspace(TestCase):
+
+    def test_basic(self):
+        y = linspace(0, 10)
+        assert_(len(y) == 50)
+        y = linspace(2, 10, num=100)
+        assert_(y[-1] == 10)
+        y = linspace(2, 10, endpoint=0)
+        assert_(y[-1] < 10)
+        assert_raises(ValueError, linspace, 0, 10, num=-1)
+
+    def test_corner(self):
+        y = list(linspace(0, 1, 1))
+        assert_(y == [0.0], y)
+        y = list(linspace(0, 1, 2.5))
+        assert_(y == [0.0, 1.0])
+
+    def test_type(self):
+        t1 = linspace(0, 1, 0).dtype
+        t2 = linspace(0, 1, 1).dtype
+        t3 = linspace(0, 1, 2).dtype
+        assert_equal(t1, t2)
+        assert_equal(t2, t3)
+
+    def test_dtype(self):
+        y = linspace(0, 6, dtype='float32')
+        assert_equal(y.dtype, dtype('float32'))
+        y = linspace(0, 6, dtype='float64')
+        assert_equal(y.dtype, dtype('float64'))
+        y = linspace(0, 6, dtype='int32')
+        assert_equal(y.dtype, dtype('int32'))
+
+    def test_array_scalar(self):
+        lim1 = array([-120, 100], dtype="int8")
+        lim2 = array([120, -100], dtype="int8")
+        lim3 = array([1200, 1000], dtype="uint16")
+        t1 = linspace(lim1[0], lim1[1], 5)
+        t2 = linspace(lim2[0], lim2[1], 5)
+        t3 = linspace(lim3[0], lim3[1], 5)
+        t4 = linspace(-120.0, 100.0, 5)
+        t5 = linspace(120.0, -100.0, 5)
+        t6 = linspace(1200.0, 1000.0, 5)
+        assert_equal(t1, t4)
+        assert_equal(t2, t5)
+        assert_equal(t3, t6)
+
+    def test_complex(self):
+        lim1 = linspace(1 + 2j, 3 + 4j, 5)
+        t1 = array([ 1.0+2.j,  1.5+2.5j,  2.0+3.j,  2.5+3.5j,  3.0+4.j])
+        lim2 = linspace(1j, 10, 5)
+        t2 = array([  0.0+1.j,   2.5+0.75j,   5.0+0.5j,   7.5+0.25j,  10.0+0.j])
+        assert_equal(lim1, t1)
+        assert_equal(lim2, t2)
+
+    def test_physical_quantities(self):
+        class PhysicalQuantity(float):
+            def __new__(cls, value):
+                return float.__new__(cls, value)
+
+            def __add__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(x) + float(self))
+            __radd__ = __add__
+
+            def __sub__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(self) - float(x))
+
+            def __rsub__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(x) - float(self))
+
+            def __mul__(self, x):
+                return PhysicalQuantity(float(x) * float(self))
+            __rmul__ = __mul__
+
+            def __div__(self, x):
+                return PhysicalQuantity(float(self) / float(x))
+
+            def __rdiv__(self, x):
+                return PhysicalQuantity(float(x) / float(self))
+
+        a = PhysicalQuantity(0.0)
+        b = PhysicalQuantity(1.0)
+        assert_equal(linspace(a, b), linspace(0.0, 1.0))
+
+    def test_subclass(self):
+        class PhysicalQuantity2(ndarray):
+            __array_priority__ = 10
+
+        a = array(0).view(PhysicalQuantity2)
+        b = array(1).view(PhysicalQuantity2)
+        ls = linspace(a, b)
+        assert type(ls) is PhysicalQuantity2
+        assert_equal(ls, linspace(0.0, 1.0))
+        ls = linspace(a, b, 1)
+        assert type(ls) is PhysicalQuantity2
+        assert_equal(ls, linspace(0.0, 1.0, 1))
+
+    def test_denormal_numbers(self):
+        # Regression test for gh-5437. Will probably fail when compiled
+        # with ICC, which flushes denormals to zero
+        for dt in (dtype(f) for f in typecodes['Float']):
+            stop = finfo(dt).tiny * finfo(dt).resolution
+            assert_(any(linspace(0, stop, 10, endpoint=False, dtype=dt)))
+
+    def test_equivalent_to_arange(self):
+        for j in range(1000):
+            assert_equal(linspace(0, j, j+1, dtype=int),
+                         arange(j+1, dtype=int))
+
+    def test_retstep(self):
+        y = linspace(0, 1, 2, retstep=True)
+        assert_(isinstance(y, tuple) and len(y) == 2)
+        for num in (0, 1):
+            for ept in (False, True):
+                y = linspace(0, 1, num, endpoint=ept, retstep=True)
+                assert_(isinstance(y, tuple) and len(y) == 2 and
+                        len(y[0]) == num and isnan(y[1]),
+                        'num={0}, endpoint={1}'.format(num, ept))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
new file mode 100644
index 0000000000..c36d7c0684
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
@@ -0,0 +1,77 @@
+""" Test functions for limits module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.core import finfo, iinfo
+from numpy import half, single, double, longdouble
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal
+)
+
+##################################################
+
+class TestPythonFloat(TestCase):
+    def test_singleton(self):
+        ftype = finfo(float)
+        ftype2 = finfo(float)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestHalf(TestCase):
+    def test_singleton(self):
+        ftype = finfo(half)
+        ftype2 = finfo(half)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestSingle(TestCase):
+    def test_singleton(self):
+        ftype = finfo(single)
+        ftype2 = finfo(single)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestDouble(TestCase):
+    def test_singleton(self):
+        ftype = finfo(double)
+        ftype2 = finfo(double)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestLongdouble(TestCase):
+    def test_singleton(self,level=2):
+        ftype = finfo(longdouble)
+        ftype2 = finfo(longdouble)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestIinfo(TestCase):
+    def test_basic(self):
+        dts = list(zip(['i1', 'i2', 'i4', 'i8',
+                   'u1', 'u2', 'u4', 'u8'],
+                  [np.int8, np.int16, np.int32, np.int64,
+                   np.uint8, np.uint16, np.uint32, np.uint64]))
+        for dt1, dt2 in dts:
+            assert_equal(iinfo(dt1).min, iinfo(dt2).min)
+            assert_equal(iinfo(dt1).max, iinfo(dt2).max)
+        self.assertRaises(ValueError, iinfo, 'f4')
+
+    def test_unsigned_max(self):
+        types = np.sctypes['uint']
+        for T in types:
+            assert_equal(iinfo(T).max, T(-1))
+
+class TestRepr(TestCase):
+    def test_iinfo_repr(self):
+        expected = "iinfo(min=-32768, max=32767, dtype=int16)"
+        assert_equal(repr(np.iinfo(np.int16)), expected)
+
+    def test_finfo_repr(self):
+        expected = "finfo(resolution=1e-06, min=-3.4028235e+38," + \
+                   " max=3.4028235e+38, dtype=float32)"
+        assert_equal(repr(np.finfo(np.float32)), expected)
+
+
+def test_instances():
+    iinfo(10)
+    finfo(3.0)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_half.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_half.py
new file mode 100644
index 0000000000..56b574ae81
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_half.py
@@ -0,0 +1,436 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+import numpy as np
+from numpy import uint16, float16, float32, float64
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal, \
+    dec
+
+
+def assert_raises_fpe(strmatch, callable, *args, **kwargs):
+    try:
+        callable(*args, **kwargs)
+    except FloatingPointError as exc:
+        assert_(str(exc).find(strmatch) >= 0,
+                "Did not raise floating point %s error" % strmatch)
+    else:
+        assert_(False,
+                "Did not raise floating point %s error" % strmatch)
+
+class TestHalf(TestCase):
+    def setUp(self):
+        # An array of all possible float16 values
+        self.all_f16 = np.arange(0x10000, dtype=uint16)
+        self.all_f16.dtype = float16
+        self.all_f32 = np.array(self.all_f16, dtype=float32)
+        self.all_f64 = np.array(self.all_f16, dtype=float64)
+
+        # An array of all non-NaN float16 values, in sorted order
+        self.nonan_f16 = np.concatenate(
+                                (np.arange(0xfc00, 0x7fff, -1, dtype=uint16),
+                                 np.arange(0x0000, 0x7c01, 1, dtype=uint16)))
+        self.nonan_f16.dtype = float16
+        self.nonan_f32 = np.array(self.nonan_f16, dtype=float32)
+        self.nonan_f64 = np.array(self.nonan_f16, dtype=float64)
+
+        # An array of all finite float16 values, in sorted order
+        self.finite_f16 = self.nonan_f16[1:-1]
+        self.finite_f32 = self.nonan_f32[1:-1]
+        self.finite_f64 = self.nonan_f64[1:-1]
+
+    def test_half_conversions(self):
+        """Checks that all 16-bit values survive conversion
+           to/from 32-bit and 64-bit float"""
+        # Because the underlying routines preserve the NaN bits, every
+        # value is preserved when converting to/from other floats.
+
+        # Convert from float32 back to float16
+        b = np.array(self.all_f32, dtype=float16)
+        assert_equal(self.all_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Convert from float64 back to float16
+        b = np.array(self.all_f64, dtype=float16)
+        assert_equal(self.all_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Convert float16 to longdouble and back
+        # This doesn't necessarily preserve the extra NaN bits,
+        # so exclude NaNs.
+        a_ld = np.array(self.nonan_f16, dtype=np.longdouble)
+        b = np.array(a_ld, dtype=float16)
+        assert_equal(self.nonan_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Check the range for which all integers can be represented
+        i_int = np.arange(-2048, 2049)
+        i_f16 = np.array(i_int, dtype=float16)
+        j = np.array(i_f16, dtype=np.int)
+        assert_equal(i_int, j)
+
+    def test_nans_infs(self):
+        with np.errstate(all='ignore'):
+            # Check some of the ufuncs
+            assert_equal(np.isnan(self.all_f16), np.isnan(self.all_f32))
+            assert_equal(np.isinf(self.all_f16), np.isinf(self.all_f32))
+            assert_equal(np.isfinite(self.all_f16), np.isfinite(self.all_f32))
+            assert_equal(np.signbit(self.all_f16), np.signbit(self.all_f32))
+            assert_equal(np.spacing(float16(65504)), np.inf)
+
+            # Check comparisons of all values with NaN
+            nan = float16(np.nan)
+
+            assert_(not (self.all_f16 == nan).any())
+            assert_(not (nan == self.all_f16).any())
+
+            assert_((self.all_f16 != nan).all())
+            assert_((nan != self.all_f16).all())
+
+            assert_(not (self.all_f16 < nan).any())
+            assert_(not (nan < self.all_f16).any())
+
+            assert_(not (self.all_f16 <= nan).any())
+            assert_(not (nan <= self.all_f16).any())
+
+            assert_(not (self.all_f16 > nan).any())
+            assert_(not (nan > self.all_f16).any())
+
+            assert_(not (self.all_f16 >= nan).any())
+            assert_(not (nan >= self.all_f16).any())
+
+    def test_half_values(self):
+        """Confirms a small number of known half values"""
+        a = np.array([1.0, -1.0,
+                      2.0, -2.0,
+                      0.0999755859375, 0.333251953125,  # 1/10, 1/3
+                      65504, -65504,           # Maximum magnitude
+                      2.0**(-14), -2.0**(-14),  # Minimum normal
+                      2.0**(-24), -2.0**(-24),  # Minimum subnormal
+                      0, -1/1e1000,            # Signed zeros
+                      np.inf, -np.inf])
+        b = np.array([0x3c00, 0xbc00,
+                      0x4000, 0xc000,
+                      0x2e66, 0x3555,
+                      0x7bff, 0xfbff,
+                      0x0400, 0x8400,
+                      0x0001, 0x8001,
+                      0x0000, 0x8000,
+                      0x7c00, 0xfc00], dtype=uint16)
+        b.dtype = float16
+        assert_equal(a, b)
+
+    def test_half_rounding(self):
+        """Checks that rounding when converting to half is correct"""
+        a = np.array([2.0**-25 + 2.0**-35,  # Rounds to minimum subnormal
+                      2.0**-25,       # Underflows to zero (nearest even mode)
+                      2.0**-26,       # Underflows to zero
+                      1.0+2.0**-11 + 2.0**-16,  # rounds to 1.0+2**(-10)
+                      1.0+2.0**-11,   # rounds to 1.0 (nearest even mode)
+                      1.0+2.0**-12,   # rounds to 1.0
+                      65519,          # rounds to 65504
+                      65520],         # rounds to inf
+                      dtype=float64)
+        rounded = [2.0**-24,
+                   0.0,
+                   0.0,
+                   1.0+2.0**(-10),
+                   1.0,
+                   1.0,
+                   65504,
+                   np.inf]
+
+        # Check float64->float16 rounding
+        b = np.array(a, dtype=float16)
+        assert_equal(b, rounded)
+
+        # Check float32->float16 rounding
+        a = np.array(a, dtype=float32)
+        b = np.array(a, dtype=float16)
+        assert_equal(b, rounded)
+
+    def test_half_correctness(self):
+        """Take every finite float16, and check the casting functions with
+           a manual conversion."""
+
+        # Create an array of all finite float16s
+        a_bits = self.finite_f16.view(dtype=uint16)
+
+        # Convert to 64-bit float manually
+        a_sgn = (-1.0)**((a_bits & 0x8000) >> 15)
+        a_exp = np.array((a_bits & 0x7c00) >> 10, dtype=np.int32) - 15
+        a_man = (a_bits & 0x03ff) * 2.0**(-10)
+        # Implicit bit of normalized floats
+        a_man[a_exp != -15] += 1
+        # Denormalized exponent is -14
+        a_exp[a_exp == -15] = -14
+
+        a_manual = a_sgn * a_man * 2.0**a_exp
+
+        a32_fail = np.nonzero(self.finite_f32 != a_manual)[0]
+        if len(a32_fail) != 0:
+            bad_index = a32_fail[0]
+            assert_equal(self.finite_f32, a_manual,
+                 "First non-equal is half value %x -> %g != %g" %
+                            (self.finite_f16[bad_index],
+                             self.finite_f32[bad_index],
+                             a_manual[bad_index]))
+
+        a64_fail = np.nonzero(self.finite_f64 != a_manual)[0]
+        if len(a64_fail) != 0:
+            bad_index = a64_fail[0]
+            assert_equal(self.finite_f64, a_manual,
+                 "First non-equal is half value %x -> %g != %g" %
+                            (self.finite_f16[bad_index],
+                             self.finite_f64[bad_index],
+                             a_manual[bad_index]))
+
+    def test_half_ordering(self):
+        """Make sure comparisons are working right"""
+
+        # All non-NaN float16 values in reverse order
+        a = self.nonan_f16[::-1].copy()
+
+        # 32-bit float copy
+        b = np.array(a, dtype=float32)
+
+        # Should sort the same
+        a.sort()
+        b.sort()
+        assert_equal(a, b)
+
+        # Comparisons should work
+        assert_((a[:-1] <= a[1:]).all())
+        assert_(not (a[:-1] > a[1:]).any())
+        assert_((a[1:] >= a[:-1]).all())
+        assert_(not (a[1:] < a[:-1]).any())
+        # All != except for +/-0
+        assert_equal(np.nonzero(a[:-1] < a[1:])[0].size, a.size-2)
+        assert_equal(np.nonzero(a[1:] > a[:-1])[0].size, a.size-2)
+
+    def test_half_funcs(self):
+        """Test the various ArrFuncs"""
+
+        # fill
+        assert_equal(np.arange(10, dtype=float16),
+                     np.arange(10, dtype=float32))
+
+        # fillwithscalar
+        a = np.zeros((5,), dtype=float16)
+        a.fill(1)
+        assert_equal(a, np.ones((5,), dtype=float16))
+
+        # nonzero and copyswap
+        a = np.array([0, 0, -1, -1/1e20, 0, 2.0**-24, 7.629e-6], dtype=float16)
+        assert_equal(a.nonzero()[0],
+                     [2, 5, 6])
+        a = a.byteswap().newbyteorder()
+        assert_equal(a.nonzero()[0],
+                     [2, 5, 6])
+
+        # dot
+        a = np.arange(0, 10, 0.5, dtype=float16)
+        b = np.ones((20,), dtype=float16)
+        assert_equal(np.dot(a, b),
+                     95)
+
+        # argmax
+        a = np.array([0, -np.inf, -2, 0.5, 12.55, 7.3, 2.1, 12.4], dtype=float16)
+        assert_equal(a.argmax(),
+                     4)
+        a = np.array([0, -np.inf, -2, np.inf, 12.55, np.nan, 2.1, 12.4], dtype=float16)
+        assert_equal(a.argmax(),
+                     5)
+
+        # getitem
+        a = np.arange(10, dtype=float16)
+        for i in range(10):
+            assert_equal(a.item(i), i)
+
+    def test_spacing_nextafter(self):
+        """Test np.spacing and np.nextafter"""
+        # All non-negative finite #'s
+        a = np.arange(0x7c00, dtype=uint16)
+        hinf = np.array((np.inf,), dtype=float16)
+        a_f16 = a.view(dtype=float16)
+
+        assert_equal(np.spacing(a_f16[:-1]), a_f16[1:]-a_f16[:-1])
+
+        assert_equal(np.nextafter(a_f16[:-1], hinf), a_f16[1:])
+        assert_equal(np.nextafter(a_f16[0], -hinf), -a_f16[1])
+        assert_equal(np.nextafter(a_f16[1:], -hinf), a_f16[:-1])
+
+        # switch to negatives
+        a |= 0x8000
+
+        assert_equal(np.spacing(a_f16[0]), np.spacing(a_f16[1]))
+        assert_equal(np.spacing(a_f16[1:]), a_f16[:-1]-a_f16[1:])
+
+        assert_equal(np.nextafter(a_f16[0], hinf), -a_f16[1])
+        assert_equal(np.nextafter(a_f16[1:], hinf), a_f16[:-1])
+        assert_equal(np.nextafter(a_f16[:-1], -hinf), a_f16[1:])
+
+    def test_half_ufuncs(self):
+        """Test the various ufuncs"""
+
+        a = np.array([0, 1, 2, 4, 2], dtype=float16)
+        b = np.array([-2, 5, 1, 4, 3], dtype=float16)
+        c = np.array([0, -1, -np.inf, np.nan, 6], dtype=float16)
+
+        assert_equal(np.add(a, b), [-2, 6, 3, 8, 5])
+        assert_equal(np.subtract(a, b), [2, -4, 1, 0, -1])
+        assert_equal(np.multiply(a, b), [0, 5, 2, 16, 6])
+        assert_equal(np.divide(a, b), [0, 0.199951171875, 2, 1, 0.66650390625])
+
+        assert_equal(np.equal(a, b), [False, False, False, True, False])
+        assert_equal(np.not_equal(a, b), [True, True, True, False, True])
+        assert_equal(np.less(a, b), [False, True, False, False, True])
+        assert_equal(np.less_equal(a, b), [False, True, False, True, True])
+        assert_equal(np.greater(a, b), [True, False, True, False, False])
+        assert_equal(np.greater_equal(a, b), [True, False, True, True, False])
+        assert_equal(np.logical_and(a, b), [False, True, True, True, True])
+        assert_equal(np.logical_or(a, b), [True, True, True, True, True])
+        assert_equal(np.logical_xor(a, b), [True, False, False, False, False])
+        assert_equal(np.logical_not(a), [True, False, False, False, False])
+
+        assert_equal(np.isnan(c), [False, False, False, True, False])
+        assert_equal(np.isinf(c), [False, False, True, False, False])
+        assert_equal(np.isfinite(c), [True, True, False, False, True])
+        assert_equal(np.signbit(b), [True, False, False, False, False])
+
+        assert_equal(np.copysign(b, a), [2, 5, 1, 4, 3])
+
+        assert_equal(np.maximum(a, b), [0, 5, 2, 4, 3])
+        x = np.maximum(b, c)
+        assert_(np.isnan(x[3]))
+        x[3] = 0
+        assert_equal(x, [0, 5, 1, 0, 6])
+        assert_equal(np.minimum(a, b), [-2, 1, 1, 4, 2])
+        x = np.minimum(b, c)
+        assert_(np.isnan(x[3]))
+        x[3] = 0
+        assert_equal(x, [-2, -1, -np.inf, 0, 3])
+        assert_equal(np.fmax(a, b), [0, 5, 2, 4, 3])
+        assert_equal(np.fmax(b, c), [0, 5, 1, 4, 6])
+        assert_equal(np.fmin(a, b), [-2, 1, 1, 4, 2])
+        assert_equal(np.fmin(b, c), [-2, -1, -np.inf, 4, 3])
+
+        assert_equal(np.floor_divide(a, b), [0, 0, 2, 1, 0])
+        assert_equal(np.remainder(a, b), [0, 1, 0, 0, 2])
+        assert_equal(np.square(b), [4, 25, 1, 16, 9])
+        assert_equal(np.reciprocal(b), [-0.5, 0.199951171875, 1, 0.25, 0.333251953125])
+        assert_equal(np.ones_like(b), [1, 1, 1, 1, 1])
+        assert_equal(np.conjugate(b), b)
+        assert_equal(np.absolute(b), [2, 5, 1, 4, 3])
+        assert_equal(np.negative(b), [2, -5, -1, -4, -3])
+        assert_equal(np.sign(b), [-1, 1, 1, 1, 1])
+        assert_equal(np.modf(b), ([0, 0, 0, 0, 0], b))
+        assert_equal(np.frexp(b), ([-0.5, 0.625, 0.5, 0.5, 0.75], [2, 3, 1, 3, 2]))
+        assert_equal(np.ldexp(b, [0, 1, 2, 4, 2]), [-2, 10, 4, 64, 12])
+
+    def test_half_coercion(self):
+        """Test that half gets coerced properly with the other types"""
+        a16 = np.array((1,), dtype=float16)
+        a32 = np.array((1,), dtype=float32)
+        b16 = float16(1)
+        b32 = float32(1)
+
+        assert_equal(np.power(a16, 2).dtype, float16)
+        assert_equal(np.power(a16, 2.0).dtype, float16)
+        assert_equal(np.power(a16, b16).dtype, float16)
+        assert_equal(np.power(a16, b32).dtype, float16)
+        assert_equal(np.power(a16, a16).dtype, float16)
+        assert_equal(np.power(a16, a32).dtype, float32)
+
+        assert_equal(np.power(b16, 2).dtype, float64)
+        assert_equal(np.power(b16, 2.0).dtype, float64)
+        assert_equal(np.power(b16, b16).dtype, float16)
+        assert_equal(np.power(b16, b32).dtype, float32)
+        assert_equal(np.power(b16, a16).dtype, float16)
+        assert_equal(np.power(b16, a32).dtype, float32)
+
+        assert_equal(np.power(a32, a16).dtype, float32)
+        assert_equal(np.power(a32, b16).dtype, float32)
+        assert_equal(np.power(b32, a16).dtype, float16)
+        assert_equal(np.power(b32, b16).dtype, float32)
+
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_half_fpe(self):
+        with np.errstate(all='raise'):
+            sx16 = np.array((1e-4,), dtype=float16)
+            bx16 = np.array((1e4,), dtype=float16)
+            sy16 = float16(1e-4)
+            by16 = float16(1e4)
+
+            # Underflow errors
+            assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sx16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sy16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sx16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sy16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sx16, bx16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sx16, by16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sy16, bx16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sy16, by16)
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14), float16(2**11))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(-2.**-14), float16(2**11))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14+2**-24), float16(2))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(-2.**-14-2**-24), float16(2))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14+2**-23), float16(4))
+
+            # Overflow errors
+            assert_raises_fpe('overflow', lambda a, b:a*b, bx16, bx16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, bx16, by16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, by16, bx16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, by16, by16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sx16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sy16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, by16, sx16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, by16, sy16)
+            assert_raises_fpe('overflow', lambda a, b:a+b,
+                                             float16(65504), float16(17))
+            assert_raises_fpe('overflow', lambda a, b:a-b,
+                                             float16(-65504), float16(17))
+            assert_raises_fpe('overflow', np.nextafter, float16(65504), float16(np.inf))
+            assert_raises_fpe('overflow', np.nextafter, float16(-65504), float16(-np.inf))
+            assert_raises_fpe('overflow', np.spacing, float16(65504))
+
+            # Invalid value errors
+            assert_raises_fpe('invalid', np.divide, float16(np.inf), float16(np.inf))
+            assert_raises_fpe('invalid', np.spacing, float16(np.inf))
+            assert_raises_fpe('invalid', np.spacing, float16(np.nan))
+            assert_raises_fpe('invalid', np.nextafter, float16(np.inf), float16(0))
+            assert_raises_fpe('invalid', np.nextafter, float16(-np.inf), float16(0))
+            assert_raises_fpe('invalid', np.nextafter, float16(0), float16(np.nan))
+
+            # These should not raise
+            float16(65472)+float16(32)
+            float16(2**-13)/float16(2)
+            float16(2**-14)/float16(2**10)
+            np.spacing(float16(-65504))
+            np.nextafter(float16(65504), float16(-np.inf))
+            np.nextafter(float16(-65504), float16(np.inf))
+            float16(2**-14)/float16(2**10)
+            float16(-2**-14)/float16(2**10)
+            float16(2**-14+2**-23)/float16(2)
+            float16(-2**-14-2**-23)/float16(2)
+
+    def test_half_array_interface(self):
+        """Test that half is compatible with __array_interface__"""
+        class Dummy:
+            pass
+
+        a = np.ones((1,), dtype=float16)
+        b = Dummy()
+        b.__array_interface__ = a.__array_interface__
+        c = np.array(b)
+        assert_(c.dtype == float16)
+        assert_equal(a, c)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
new file mode 100644
index 0000000000..e6b6be3610
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
@@ -0,0 +1,126 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_raises
+
+class TestIndexErrors(TestCase):
+    '''Tests to exercise indexerrors not covered by other tests.'''
+
+    def test_arraytypes_fasttake(self):
+        'take from a 0-length dimension'
+        x = np.empty((2, 3, 0, 4))
+        assert_raises(IndexError, x.take, [0], axis=2)
+        assert_raises(IndexError, x.take, [1], axis=2)
+        assert_raises(IndexError, x.take, [0], axis=2, mode='wrap')
+        assert_raises(IndexError, x.take, [0], axis=2, mode='clip')
+
+    def test_take_from_object(self):
+        # Check exception taking from object array
+        d = np.zeros(5, dtype=object)
+        assert_raises(IndexError, d.take, [6])
+
+        # Check exception taking from 0-d array
+        d = np.zeros((5, 0), dtype=object)
+        assert_raises(IndexError, d.take, [1], axis=1)
+        assert_raises(IndexError, d.take, [0], axis=1)
+        assert_raises(IndexError, d.take, [0])
+        assert_raises(IndexError, d.take, [0], mode='wrap')
+        assert_raises(IndexError, d.take, [0], mode='clip')
+
+    def test_multiindex_exceptions(self):
+        a = np.empty(5, dtype=object)
+        assert_raises(IndexError, a.item, 20)
+        a = np.empty((5, 0), dtype=object)
+        assert_raises(IndexError, a.item, (0, 0))
+
+        a = np.empty(5, dtype=object)
+        assert_raises(IndexError, a.itemset, 20, 0)
+        a = np.empty((5, 0), dtype=object)
+        assert_raises(IndexError, a.itemset, (0, 0), 0)
+
+    def test_put_exceptions(self):
+        a = np.zeros((5, 5))
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5), dtype=object)
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5, 0))
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5, 0), dtype=object)
+        assert_raises(IndexError, a.put, 100, 0)
+
+    def test_iterators_exceptions(self):
+        "cases in iterators.c"
+        def assign(obj, ind, val):
+            obj[ind] = val
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a[0, 5, None, 2])
+        assert_raises(IndexError, lambda: a[0, 5, 0, 2])
+        assert_raises(IndexError, lambda: assign(a, (0, 5, None, 2), 1))
+        assert_raises(IndexError, lambda: assign(a, (0, 5, 0, 2),  1))
+
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a[0, 0, None, 2])
+        assert_raises(IndexError, lambda: assign(a, (0, 0, None, 2), 1))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[10])
+        assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[10])
+        assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array(10)])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array(10)])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array([10])])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array([10])])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
+
+    def test_mapping(self):
+        "cases from mapping.c"
+
+        def assign(obj, ind, val):
+            obj[ind] = val
+
+        a = np.zeros((0, 10))
+        assert_raises(IndexError, lambda: a[12])
+
+        a = np.zeros((3, 5))
+        assert_raises(IndexError, lambda: a[(10, 20)])
+        assert_raises(IndexError, lambda: assign(a, (10, 20), 1))
+        a = np.zeros((3, 0))
+        assert_raises(IndexError, lambda: a[(1, 0)])
+        assert_raises(IndexError, lambda: assign(a, (1, 0), 1))
+
+        a = np.zeros((10,))
+        assert_raises(IndexError, lambda: assign(a, 10, 1))
+        a = np.zeros((0,))
+        assert_raises(IndexError, lambda: assign(a, 10, 1))
+
+        a = np.zeros((3, 5))
+        assert_raises(IndexError, lambda: a[(1, [1, 20])])
+        assert_raises(IndexError, lambda: assign(a, (1, [1, 20]), 1))
+        a = np.zeros((3, 0))
+        assert_raises(IndexError, lambda: a[(1, [0, 1])])
+        assert_raises(IndexError, lambda: assign(a, (1, [0, 1]), 1))
+
+    def test_methods(self):
+        "cases from methods.c"
+
+        a = np.zeros((3, 3))
+        assert_raises(IndexError, lambda: a.item(100))
+        assert_raises(IndexError, lambda: a.itemset(100, 1))
+        a = np.zeros((0, 3))
+        assert_raises(IndexError, lambda: a.item(100))
+        assert_raises(IndexError, lambda: a.itemset(100, 1))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
new file mode 100644
index 0000000000..70029f8048
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
@@ -0,0 +1,1044 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+import functools
+
+import numpy as np
+from numpy.core.multiarray_tests import array_indexing
+from itertools import product
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_warns
+)
+
+
+try:
+    cdll = np.ctypeslib.load_library('multiarray', np.core.multiarray.__file__)
+    _HAS_CTYPE = True
+except ImportError:
+    _HAS_CTYPE = False
+
+
+class TestIndexing(TestCase):
+    def test_none_index(self):
+        # `None` index adds newaxis
+        a = np.array([1, 2, 3])
+        assert_equal(a[None], a[np.newaxis])
+        assert_equal(a[None].ndim, a.ndim + 1)
+
+    def test_empty_tuple_index(self):
+        # Empty tuple index creates a view
+        a = np.array([1, 2, 3])
+        assert_equal(a[()], a)
+        assert_(a[()].base is a)
+        a = np.array(0)
+        assert_(isinstance(a[()], np.int_))
+
+        # Regression, it needs to fall through integer and fancy indexing
+        # cases, so need the with statement to ignore the non-integer error.
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', '', DeprecationWarning)
+            a = np.array([1.])
+            assert_(isinstance(a[0.], np.float_))
+
+            a = np.array([np.array(1)], dtype=object)
+            assert_(isinstance(a[0.], np.ndarray))
+
+    def test_same_kind_index_casting(self):
+        # Indexes should be cast with same-kind and not safe, even if
+        # that is somewhat unsafe. So test various different code paths.
+        index = np.arange(5)
+        u_index = index.astype(np.uintp)
+        arr = np.arange(10)
+
+        assert_array_equal(arr[index], arr[u_index])
+        arr[u_index] = np.arange(5)
+        assert_array_equal(arr, np.arange(10))
+
+        arr = np.arange(10).reshape(5, 2)
+        assert_array_equal(arr[index], arr[u_index])
+
+        arr[u_index] = np.arange(5)[:,None]
+        assert_array_equal(arr, np.arange(5)[:,None].repeat(2, axis=1))
+
+        arr = np.arange(25).reshape(5, 5)
+        assert_array_equal(arr[u_index, u_index], arr[index, index])
+
+    def test_empty_fancy_index(self):
+        # Empty list index creates an empty array
+        # with the same dtype (but with weird shape)
+        a = np.array([1, 2, 3])
+        assert_equal(a[[]], [])
+        assert_equal(a[[]].dtype, a.dtype)
+
+        b = np.array([], dtype=np.intp)
+        assert_equal(a[[]], [])
+        assert_equal(a[[]].dtype, a.dtype)
+
+        b = np.array([])
+        assert_raises(IndexError, a.__getitem__, b)
+
+    def test_ellipsis_index(self):
+        # Ellipsis index does not create a view
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+        assert_equal(a[...], a)
+        assert_(a[...].base is a)  # `a[...]` was `a` in numpy <1.9.)
+
+        # Slicing with ellipsis can skip an
+        # arbitrary number of dimensions
+        assert_equal(a[0, ...], a[0])
+        assert_equal(a[0, ...], a[0,:])
+        assert_equal(a[..., 0], a[:, 0])
+
+        # Slicing with ellipsis always results
+        # in an array, not a scalar
+        assert_equal(a[0, ..., 1], np.array(2))
+
+        # Assignment with `(Ellipsis,)` on 0-d arrays
+        b = np.array(1)
+        b[(Ellipsis,)] = 2
+        assert_equal(b, 2)
+
+    def test_single_int_index(self):
+        # Single integer index selects one row
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+
+        assert_equal(a[0], [1, 2, 3])
+        assert_equal(a[-1], [7, 8, 9])
+
+        # Index out of bounds produces IndexError
+        assert_raises(IndexError, a.__getitem__, 1 << 30)
+        # Index overflow produces IndexError
+        assert_raises(IndexError, a.__getitem__, 1 << 64)
+
+    def test_single_bool_index(self):
+        # Single boolean index
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+
+        # Python boolean converts to integer
+        # These are being deprecated (and test in test_deprecations)
+        #assert_equal(a[True], a[1])
+        #assert_equal(a[False], a[0])
+
+        # Same with NumPy boolean scalar
+        # Before DEPRECATE, this is an error (as always, but telling about
+        # future change):
+        assert_raises(IndexError, a.__getitem__, np.array(True))
+        assert_raises(IndexError, a.__getitem__, np.array(False))
+        # After DEPRECATE, this behaviour can be enabled:
+        #assert_equal(a[np.array(True)], a[None])
+        #assert_equal(a[np.array(False), a[None][0:0]])
+
+    def test_boolean_indexing_onedim(self):
+        # Indexing a 2-dimensional array with
+        # boolean array of length one
+        a = np.array([[ 0.,  0.,  0.]])
+        b = np.array([ True], dtype=bool)
+        assert_equal(a[b], a)
+        # boolean assignment
+        a[b] = 1.
+        assert_equal(a, [[1., 1., 1.]])
+
+    def test_boolean_assignment_value_mismatch(self):
+        # A boolean assignment should fail when the shape of the values
+        # cannot be broadcast to the subscription. (see also gh-3458)
+        a = np.arange(4)
+
+        def f(a, v):
+            a[a > -1] = v
+
+        assert_raises(ValueError, f, a, [])
+        assert_raises(ValueError, f, a, [1, 2, 3])
+        assert_raises(ValueError, f, a[:1], [1, 2, 3])
+
+    def test_boolean_indexing_twodim(self):
+        # Indexing a 2-dimensional array with
+        # 2-dimensional boolean array
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+        b = np.array([[ True, False,  True],
+                      [False,  True, False],
+                      [ True, False,  True]])
+        assert_equal(a[b], [1, 3, 5, 7, 9])
+        assert_equal(a[b[1]], [[4, 5, 6]])
+        assert_equal(a[b[0]], a[b[2]])
+
+        # boolean assignment
+        a[b] = 0
+        assert_equal(a, [[0, 2, 0],
+                         [4, 0, 6],
+                         [0, 8, 0]])
+
+    def test_reverse_strides_and_subspace_bufferinit(self):
+        # This tests that the strides are not reversed for simple and
+        # subspace fancy indexing.
+        a = np.ones(5)
+        b = np.zeros(5, dtype=np.intp)[::-1]
+        c = np.arange(5)[::-1]
+
+        a[b] = c
+        # If the strides are not reversed, the 0 in the arange comes last.
+        assert_equal(a[0], 0)
+
+        # This also tests that the subspace buffer is initialized:
+        a = np.ones((5, 2))
+        c = np.arange(10).reshape(5, 2)[::-1]
+        a[b, :] = c
+        assert_equal(a[0], [0, 1])
+
+    def test_reversed_strides_result_allocation(self):
+        # Test a bug when calculating the output strides for a result array
+        # when the subspace size was 1 (and test other cases as well)
+        a = np.arange(10)[:, None]
+        i = np.arange(10)[::-1]
+        assert_array_equal(a[i], a[i.copy('C')])
+
+        a = np.arange(20).reshape(-1, 2)
+
+    def test_uncontiguous_subspace_assignment(self):
+        # During development there was a bug activating a skip logic
+        # based on ndim instead of size.
+        a = np.full((3, 4, 2), -1)
+        b = np.full((3, 4, 2), -1)
+
+        a[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T
+        b[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T.copy()
+
+        assert_equal(a, b)
+
+    def test_too_many_fancy_indices_special_case(self):
+        # Just documents behaviour, this is a small limitation.
+        a = np.ones((1,) * 32)  # 32 is NPY_MAXDIMS
+        assert_raises(IndexError, a.__getitem__, (np.array([0]),) * 32)
+
+    def test_scalar_array_bool(self):
+        # Numpy bools can be used as boolean index (python ones as of yet not)
+        a = np.array(1)
+        assert_equal(a[np.bool_(True)], a[np.array(True)])
+        assert_equal(a[np.bool_(False)], a[np.array(False)])
+
+        # After deprecating bools as integers:
+        #a = np.array([0,1,2])
+        #assert_equal(a[True, :], a[None, :])
+        #assert_equal(a[:, True], a[:, None])
+        #
+        #assert_(not np.may_share_memory(a, a[True, :]))
+
+    def test_everything_returns_views(self):
+        # Before `...` would return a itself.
+        a = np.arange(5)
+
+        assert_(a is not a[()])
+        assert_(a is not a[...])
+        assert_(a is not a[:])
+
+    def test_broaderrors_indexing(self):
+        a = np.zeros((5, 5))
+        assert_raises(IndexError, a.__getitem__, ([0, 1], [0, 1, 2]))
+        assert_raises(IndexError, a.__setitem__, ([0, 1], [0, 1, 2]), 0)
+
+    def test_trivial_fancy_out_of_bounds(self):
+        a = np.zeros(5)
+        ind = np.ones(20, dtype=np.intp)
+        ind[-1] = 10
+        assert_raises(IndexError, a.__getitem__, ind)
+        assert_raises(IndexError, a.__setitem__, ind, 0)
+        ind = np.ones(20, dtype=np.intp)
+        ind[0] = 11
+        assert_raises(IndexError, a.__getitem__, ind)
+        assert_raises(IndexError, a.__setitem__, ind, 0)
+
+    def test_nonbaseclass_values(self):
+        class SubClass(np.ndarray):
+            def __array_finalize__(self, old):
+                # Have array finalize do funny things
+                self.fill(99)
+
+        a = np.zeros((5, 5))
+        s = a.copy().view(type=SubClass)
+        s.fill(1)
+
+        a[[0, 1, 2, 3, 4], :] = s
+        assert_((a == 1).all())
+
+        # Subspace is last, so transposing might want to finalize
+        a[:, [0, 1, 2, 3, 4]] = s
+        assert_((a == 1).all())
+
+        a.fill(0)
+        a[...] = s
+        assert_((a == 1).all())
+
+    def test_subclass_writeable(self):
+        d = np.rec.array([('NGC1001', 11), ('NGC1002', 1.), ('NGC1003', 1.)],
+                         dtype=[('target', 'S20'), ('V_mag', '>f4')])
+        ind = np.array([False,  True,  True], dtype=bool)
+        assert_(d[ind].flags.writeable)
+        ind = np.array([0, 1])
+        assert_(d[ind].flags.writeable)
+        assert_(d[...].flags.writeable)
+        assert_(d[0].flags.writeable)
+
+    def test_memory_order(self):
+        # This is not necessary to preserve. Memory layouts for
+        # more complex indices are not as simple.
+        a = np.arange(10)
+        b = np.arange(10).reshape(5,2).T
+        assert_(a[b].flags.f_contiguous)
+
+        # Takes a different implementation branch:
+        a = a.reshape(-1, 1)
+        assert_(a[b, 0].flags.f_contiguous)
+
+    def test_scalar_return_type(self):
+        # Full scalar indices should return scalars and object
+        # arrays should not call PyArray_Return on their items
+        class Zero(object):
+            # The most basic valid indexing
+            def __index__(self):
+                return 0
+
+        z = Zero()
+
+        class ArrayLike(object):
+            # Simple array, should behave like the array
+            def __array__(self):
+                return np.array(0)
+
+        a = np.zeros(())
+        assert_(isinstance(a[()], np.float_))
+        a = np.zeros(1)
+        assert_(isinstance(a[z], np.float_))
+        a = np.zeros((1, 1))
+        assert_(isinstance(a[z, np.array(0)], np.float_))
+        assert_(isinstance(a[z, ArrayLike()], np.float_))
+
+        # And object arrays do not call it too often:
+        b = np.array(0)
+        a = np.array(0, dtype=object)
+        a[()] = b
+        assert_(isinstance(a[()], np.ndarray))
+        a = np.array([b, None])
+        assert_(isinstance(a[z], np.ndarray))
+        a = np.array([[b, None]])
+        assert_(isinstance(a[z, np.array(0)], np.ndarray))
+        assert_(isinstance(a[z, ArrayLike()], np.ndarray))
+
+    def test_small_regressions(self):
+        # Reference count of intp for index checks
+        a = np.array([0])
+        refcount = sys.getrefcount(np.dtype(np.intp))
+        # item setting always checks indices in separate function:
+        a[np.array([0], dtype=np.intp)] = 1
+        a[np.array([0], dtype=np.uint8)] = 1
+        assert_raises(IndexError, a.__setitem__,
+                      np.array([1], dtype=np.intp), 1)
+        assert_raises(IndexError, a.__setitem__,
+                      np.array([1], dtype=np.uint8), 1)
+
+        assert_equal(sys.getrefcount(np.dtype(np.intp)), refcount)
+
+    def test_unaligned(self):
+        v = (np.zeros(64, dtype=np.int8) + ord('a'))[1:-7]
+        d = v.view(np.dtype("S8"))
+        # unaligned source
+        x = (np.zeros(16, dtype=np.int8) + ord('a'))[1:-7]
+        x = x.view(np.dtype("S8"))
+        x[...] = np.array("b" * 8, dtype="S")
+        b = np.arange(d.size)
+        #trivial
+        assert_equal(d[b], d)
+        d[b] = x
+        # nontrivial
+        # unaligned index array
+        b = np.zeros(d.size + 1).view(np.int8)[1:-(np.intp(0).itemsize - 1)]
+        b = b.view(np.intp)[:d.size]
+        b[...] = np.arange(d.size)
+        assert_equal(d[b.astype(np.int16)], d)
+        d[b.astype(np.int16)] = x
+        # boolean
+        d[b % 2 == 0]
+        d[b % 2 == 0] = x[::2]
+
+    def test_tuple_subclass(self):
+        arr = np.ones((5, 5))
+
+        # A tuple subclass should also be an nd-index
+        class TupleSubclass(tuple):
+            pass
+        index = ([1], [1])
+        index = TupleSubclass(index)
+        assert_(arr[index].shape == (1,))
+        # Unlike the non nd-index:
+        assert_(arr[index,].shape != (1,))
+
+    def test_broken_sequence_not_nd_index(self):
+        # See gh-5063:
+        # If we have an object which claims to be a sequence, but fails
+        # on item getting, this should not be converted to an nd-index (tuple)
+        # If this object happens to be a valid index otherwise, it should work
+        # This object here is very dubious and probably bad though:
+        class SequenceLike(object):
+            def __index__(self):
+                return 0
+
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, item):
+                raise IndexError('Not possible')
+
+        arr = np.arange(10)
+        assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
+
+        # also test that field indexing does not segfault
+        # for a similar reason, by indexing a structured array
+        arr = np.zeros((1,), dtype=[('f1', 'i8'), ('f2', 'i8')])
+        assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
+
+    def test_indexing_array_weird_strides(self):
+        # See also gh-6221
+        # the shapes used here come from the issue and create the correct
+        # size for the iterator buffering size.
+        x = np.ones(10)
+        x2 = np.ones((10, 2))
+        ind = np.arange(10)[:, None, None, None]
+        ind = np.broadcast_to(ind, (10, 55, 4, 4))
+
+        # single advanced index case
+        assert_array_equal(x[ind], x[ind.copy()])
+        # higher dimensional advanced index
+        zind = np.zeros(4, dtype=np.intp)
+        assert_array_equal(x2[ind, zind], x2[ind.copy(), zind])
+
+
+class TestFieldIndexing(TestCase):
+    def test_scalar_return_type(self):
+        # Field access on an array should return an array, even if it
+        # is 0-d.
+        a = np.zeros((), [('a','f8')])
+        assert_(isinstance(a['a'], np.ndarray))
+        assert_(isinstance(a[['a']], np.ndarray))
+
+
+class TestBroadcastedAssignments(TestCase):
+    def assign(self, a, ind, val):
+        a[ind] = val
+        return a
+
+    def test_prepending_ones(self):
+        a = np.zeros((3, 2))
+
+        a[...] = np.ones((1, 3, 2))
+        # Fancy with subspace with and without transpose
+        a[[0, 1, 2], :] = np.ones((1, 3, 2))
+        a[:, [0, 1]] = np.ones((1, 3, 2))
+        # Fancy without subspace (with broadcasting)
+        a[[[0], [1], [2]], [0, 1]] = np.ones((1, 3, 2))
+
+    def test_prepend_not_one(self):
+        assign = self.assign
+        s_ = np.s_
+
+        a = np.zeros(5)
+
+        # Too large and not only ones.
+        assert_raises(ValueError, assign, a, s_[...],  np.ones((2, 1)))
+
+        with warnings.catch_warnings():
+            # Will be a ValueError as well.
+            warnings.simplefilter("error", DeprecationWarning)
+            assert_raises(DeprecationWarning, assign, a, s_[[1, 2, 3],],
+                          np.ones((2, 1)))
+            assert_raises(DeprecationWarning, assign, a, s_[[[1], [2]],],
+                          np.ones((2,2,1)))
+
+    def test_simple_broadcasting_errors(self):
+        assign = self.assign
+        s_ = np.s_
+
+        a = np.zeros((5, 1))
+        assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 2)))
+        assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 0)))
+
+        assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 2)))
+        assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 0)))
+
+        assert_raises(ValueError, assign, a, s_[[0], :], np.zeros((2, 1)))
+
+    def test_index_is_larger(self):
+        # Simple case of fancy index broadcasting of the index.
+        a = np.zeros((5, 5))
+        a[[[0], [1], [2]], [0, 1, 2]] = [2, 3, 4]
+
+        assert_((a[:3, :3] == [2, 3, 4]).all())
+
+    def test_broadcast_subspace(self):
+        a = np.zeros((100, 100))
+        v = np.arange(100)[:,None]
+        b = np.arange(100)[::-1]
+        a[b] = v
+        assert_((a[::-1] == v).all())
+
+
+class TestSubclasses(TestCase):
+    def test_basic(self):
+        class SubClass(np.ndarray):
+            pass
+
+        s = np.arange(5).view(SubClass)
+        assert_(isinstance(s[:3], SubClass))
+        assert_(s[:3].base is s)
+
+        assert_(isinstance(s[[0, 1, 2]], SubClass))
+        assert_(isinstance(s[s > 0], SubClass))
+
+    def test_matrix_fancy(self):
+        # The matrix class messes with the shape. While this is always
+        # weird (getitem is not used, it does not have setitem nor knows
+        # about fancy indexing), this tests gh-3110
+        m = np.matrix([[1, 2], [3, 4]])
+
+        assert_(isinstance(m[[0,1,0], :], np.matrix))
+
+        # gh-3110. Note the transpose currently because matrices do *not*
+        # support dimension fixing for fancy indexing correctly.
+        x = np.asmatrix(np.arange(50).reshape(5,10))
+        assert_equal(x[:2, np.array(-1)], x[:2, -1].T)
+
+    def test_finalize_gets_full_info(self):
+        # Array finalize should be called on the filled array.
+        class SubClass(np.ndarray):
+            def __array_finalize__(self, old):
+                self.finalize_status = np.array(self)
+                self.old = old
+
+        s = np.arange(10).view(SubClass)
+        new_s = s[:3]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+        new_s = s[[0,1,2,3]]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+        new_s = s[s > 0]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+class TestFancingIndexingCast(TestCase):
+    def test_boolean_index_cast_assign(self):
+        # Setup the boolean index and float arrays.
+        shape = (8, 63)
+        bool_index = np.zeros(shape).astype(bool)
+        bool_index[0, 1] = True
+        zero_array = np.zeros(shape)
+
+        # Assigning float is fine.
+        zero_array[bool_index] = np.array([1])
+        assert_equal(zero_array[0, 1], 1)
+
+        # Fancy indexing works, although we get a cast warning.
+        assert_warns(np.ComplexWarning,
+                     zero_array.__setitem__, ([0], [1]), np.array([2 + 1j]))
+        assert_equal(zero_array[0, 1], 2)  # No complex part
+
+        # Cast complex to float, throwing away the imaginary portion.
+        assert_warns(np.ComplexWarning,
+                     zero_array.__setitem__, bool_index, np.array([1j]))
+        assert_equal(zero_array[0, 1], 0)
+
+class TestFancyIndexingEquivalence(TestCase):
+    def test_object_assign(self):
+        # Check that the field and object special case using copyto is active.
+        # The right hand side cannot be converted to an array here.
+        a = np.arange(5, dtype=object)
+        b = a.copy()
+        a[:3] = [1, (1,2), 3]
+        b[[0, 1, 2]] = [1, (1,2), 3]
+        assert_array_equal(a, b)
+
+        # test same for subspace fancy indexing
+        b = np.arange(5, dtype=object)[None, :]
+        b[[0], :3] = [[1, (1,2), 3]]
+        assert_array_equal(a, b[0])
+
+        # Check that swapping of axes works.
+        # There was a bug that made the later assignment throw a ValueError
+        # do to an incorrectly transposed temporary right hand side (gh-5714)
+        b = b.T
+        b[:3, [0]] = [[1], [(1,2)], [3]]
+        assert_array_equal(a, b[:, 0])
+
+        # Another test for the memory order of the subspace
+        arr = np.ones((3, 4, 5), dtype=object)
+        # Equivalent slicing assignment for comparison
+        cmp_arr = arr.copy()
+        cmp_arr[:1, ...] = [[[1], [2], [3], [4]]]
+        arr[[0], ...] = [[[1], [2], [3], [4]]]
+        assert_array_equal(arr, cmp_arr)
+        arr = arr.copy('F')
+        arr[[0], ...] = [[[1], [2], [3], [4]]]
+        assert_array_equal(arr, cmp_arr)
+
+    def test_cast_equivalence(self):
+        # Yes, normal slicing uses unsafe casting.
+        a = np.arange(5)
+        b = a.copy()
+
+        a[:3] = np.array(['2', '-3', '-1'])
+        b[[0, 2, 1]] = np.array(['2', '-1', '-3'])
+        assert_array_equal(a, b)
+
+        # test the same for subspace fancy indexing
+        b = np.arange(5)[None, :]
+        b[[0], :3] = np.array([['2', '-3', '-1']])
+        assert_array_equal(a, b[0])
+
+
+class TestMultiIndexingAutomated(TestCase):
+    """
+     These test use code to mimic the C-Code indexing for selection.
+
+     NOTE: * This still lacks tests for complex item setting.
+           * If you change behavior of indexing, you might want to modify
+             these tests to try more combinations.
+           * Behavior was written to match numpy version 1.8. (though a
+             first version matched 1.7.)
+           * Only tuple indices are supported by the mimicking code.
+             (and tested as of writing this)
+           * Error types should match most of the time as long as there
+             is only one error. For multiple errors, what gets raised
+             will usually not be the same one. They are *not* tested.
+    """
+
+    def setUp(self):
+        self.a = np.arange(np.prod([3, 1, 5, 6])).reshape(3, 1, 5, 6)
+        self.b = np.empty((3, 0, 5, 6))
+        self.complex_indices = ['skip', Ellipsis,
+            0,
+            # Boolean indices, up to 3-d for some special cases of eating up
+            # dimensions, also need to test all False
+            np.array(False),
+            np.array([True, False, False]),
+            np.array([[True, False], [False, True]]),
+            np.array([[[False, False], [False, False]]]),
+            # Some slices:
+            slice(-5, 5, 2),
+            slice(1, 1, 100),
+            slice(4, -1, -2),
+            slice(None, None, -3),
+            # Some Fancy indexes:
+            np.empty((0, 1, 1), dtype=np.intp),  # empty and can be broadcast
+            np.array([0, 1, -2]),
+            np.array([[2], [0], [1]]),
+            np.array([[0, -1], [0, 1]], dtype=np.dtype('intp').newbyteorder()),
+            np.array([2, -1], dtype=np.int8),
+            np.zeros([1]*31, dtype=int),  # trigger too large array.
+            np.array([0., 1.])]  # invalid datatype
+        # Some simpler indices that still cover a bit more
+        self.simple_indices = [Ellipsis, None, -1, [1], np.array([True]), 'skip']
+        # Very simple ones to fill the rest:
+        self.fill_indices = [slice(None, None), 0]
+
+    def _get_multi_index(self, arr, indices):
+        """Mimic multi dimensional indexing.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed.
+        indices : tuple of index objects
+
+        Returns
+        -------
+        out : ndarray
+            An array equivalent to the indexing operation (but always a copy).
+            `arr[indices]` should be identical.
+        no_copy : bool
+            Whether the indexing operation requires a copy. If this is `True`,
+            `np.may_share_memory(arr, arr[indicies])` should be `True` (with
+            some exceptions for scalars and possibly 0-d arrays).
+
+        Notes
+        -----
+        While the function may mostly match the errors of normal indexing this
+        is generally not the case.
+        """
+        in_indices = list(indices)
+        indices = []
+        # if False, this is a fancy or boolean index
+        no_copy = True
+        # number of fancy/scalar indexes that are not consecutive
+        num_fancy = 0
+        # number of dimensions indexed by a "fancy" index
+        fancy_dim = 0
+        # NOTE: This is a funny twist (and probably OK to change).
+        # The boolean array has illegal indexes, but this is
+        # allowed if the broadcast fancy-indices are 0-sized.
+        # This variable is to catch that case.
+        error_unless_broadcast_to_empty = False
+
+        # We need to handle Ellipsis and make arrays from indices, also
+        # check if this is fancy indexing (set no_copy).
+        ndim = 0
+        ellipsis_pos = None  # define here mostly to replace all but first.
+        for i, indx in enumerate(in_indices):
+            if indx is None:
+                continue
+            if isinstance(indx, np.ndarray) and indx.dtype == bool:
+                no_copy = False
+                if indx.ndim == 0:
+                    raise IndexError
+                # boolean indices can have higher dimensions
+                ndim += indx.ndim
+                fancy_dim += indx.ndim
+                continue
+            if indx is Ellipsis:
+                if ellipsis_pos is None:
+                    ellipsis_pos = i
+                    continue  # do not increment ndim counter
+                raise IndexError
+            if isinstance(indx, slice):
+                ndim += 1
+                continue
+            if not isinstance(indx, np.ndarray):
+                # This could be open for changes in numpy.
+                # numpy should maybe raise an error if casting to intp
+                # is not safe. It rejects np.array([1., 2.]) but not
+                # [1., 2.] as index (same for ie. np.take).
+                # (Note the importance of empty lists if changing this here)
+                indx = np.array(indx, dtype=np.intp)
+                in_indices[i] = indx
+            elif indx.dtype.kind != 'b' and indx.dtype.kind != 'i':
+                raise IndexError('arrays used as indices must be of integer (or boolean) type')
+            if indx.ndim != 0:
+                no_copy = False
+            ndim += 1
+            fancy_dim += 1
+
+        if arr.ndim - ndim < 0:
+            # we can't take more dimensions then we have, not even for 0-d arrays.
+            # since a[()] makes sense, but not a[(),]. We will raise an error
+            # later on, unless a broadcasting error occurs first.
+            raise IndexError
+
+        if ndim == 0 and None not in in_indices:
+            # Well we have no indexes or one Ellipsis. This is legal.
+            return arr.copy(), no_copy
+
+        if ellipsis_pos is not None:
+            in_indices[ellipsis_pos:ellipsis_pos+1] = [slice(None, None)] * (arr.ndim - ndim)
+
+        for ax, indx in enumerate(in_indices):
+            if isinstance(indx, slice):
+                # convert to an index array
+                indx = np.arange(*indx.indices(arr.shape[ax]))
+                indices.append(['s', indx])
+                continue
+            elif indx is None:
+                # this is like taking a slice with one element from a new axis:
+                indices.append(['n', np.array([0], dtype=np.intp)])
+                arr = arr.reshape((arr.shape[:ax] + (1,) + arr.shape[ax:]))
+                continue
+            if isinstance(indx, np.ndarray) and indx.dtype == bool:
+                if indx.shape != arr.shape[ax:ax+indx.ndim]:
+                    raise IndexError
+
+                try:
+                    flat_indx = np.ravel_multi_index(np.nonzero(indx),
+                                    arr.shape[ax:ax+indx.ndim], mode='raise')
+                except:
+                    error_unless_broadcast_to_empty = True
+                    # fill with 0s instead, and raise error later
+                    flat_indx = np.array([0]*indx.sum(), dtype=np.intp)
+                # concatenate axis into a single one:
+                if indx.ndim != 0:
+                    arr = arr.reshape((arr.shape[:ax]
+                                  + (np.prod(arr.shape[ax:ax+indx.ndim]),)
+                                  + arr.shape[ax+indx.ndim:]))
+                    indx = flat_indx
+                else:
+                    # This could be changed, a 0-d boolean index can
+                    # make sense (even outside the 0-d indexed array case)
+                    # Note that originally this is could be interpreted as
+                    # integer in the full integer special case.
+                    raise IndexError
+            else:
+                # If the index is a singleton, the bounds check is done
+                # before the broadcasting. This used to be different in <1.9
+                if indx.ndim == 0:
+                    if indx >= arr.shape[ax] or indx < -arr.shape[ax]:
+                        raise IndexError
+            if indx.ndim == 0:
+                # The index is a scalar. This used to be two fold, but if fancy
+                # indexing was active, the check was done later, possibly
+                # after broadcasting it away (1.7. or earlier). Now it is always
+                # done.
+                if indx >= arr.shape[ax] or indx < - arr.shape[ax]:
+                    raise IndexError
+            if len(indices) > 0 and indices[-1][0] == 'f' and ax != ellipsis_pos:
+                # NOTE: There could still have been a 0-sized Ellipsis
+                # between them. Checked that with ellipsis_pos.
+                indices[-1].append(indx)
+            else:
+                # We have a fancy index that is not after an existing one.
+                # NOTE: A 0-d array triggers this as well, while
+                # one may expect it to not trigger it, since a scalar
+                # would not be considered fancy indexing.
+                num_fancy += 1
+                indices.append(['f', indx])
+
+        if num_fancy > 1 and not no_copy:
+            # We have to flush the fancy indexes left
+            new_indices = indices[:]
+            axes = list(range(arr.ndim))
+            fancy_axes = []
+            new_indices.insert(0, ['f'])
+            ni = 0
+            ai = 0
+            for indx in indices:
+                ni += 1
+                if indx[0] == 'f':
+                    new_indices[0].extend(indx[1:])
+                    del new_indices[ni]
+                    ni -= 1
+                    for ax in range(ai, ai + len(indx[1:])):
+                        fancy_axes.append(ax)
+                        axes.remove(ax)
+                ai += len(indx) - 1  # axis we are at
+            indices = new_indices
+            # and now we need to transpose arr:
+            arr = arr.transpose(*(fancy_axes + axes))
+
+        # We only have one 'f' index now and arr is transposed accordingly.
+        # Now handle newaxis by reshaping...
+        ax = 0
+        for indx in indices:
+            if indx[0] == 'f':
+                if len(indx) == 1:
+                    continue
+                # First of all, reshape arr to combine fancy axes into one:
+                orig_shape = arr.shape
+                orig_slice = orig_shape[ax:ax + len(indx[1:])]
+                arr = arr.reshape((arr.shape[:ax]
+                                    + (np.prod(orig_slice).astype(int),)
+                                    + arr.shape[ax + len(indx[1:]):]))
+
+                # Check if broadcasting works
+                res = np.broadcast(*indx[1:])
+                # unfortunately the indices might be out of bounds. So check
+                # that first, and use mode='wrap' then. However only if
+                # there are any indices...
+                if res.size != 0:
+                    if error_unless_broadcast_to_empty:
+                        raise IndexError
+                    for _indx, _size in zip(indx[1:], orig_slice):
+                        if _indx.size == 0:
+                            continue
+                        if np.any(_indx >= _size) or np.any(_indx < -_size):
+                                raise IndexError
+                if len(indx[1:]) == len(orig_slice):
+                    if np.product(orig_slice) == 0:
+                        # Work around for a crash or IndexError with 'wrap'
+                        # in some 0-sized cases.
+                        try:
+                            mi = np.ravel_multi_index(indx[1:], orig_slice, mode='raise')
+                        except:
+                            # This happens with 0-sized orig_slice (sometimes?)
+                            # here it is a ValueError, but indexing gives a:
+                            raise IndexError('invalid index into 0-sized')
+                    else:
+                        mi = np.ravel_multi_index(indx[1:], orig_slice, mode='wrap')
+                else:
+                    # Maybe never happens...
+                    raise ValueError
+                arr = arr.take(mi.ravel(), axis=ax)
+                arr = arr.reshape((arr.shape[:ax]
+                                    + mi.shape
+                                    + arr.shape[ax+1:]))
+                ax += mi.ndim
+                continue
+
+            # If we are here, we have a 1D array for take:
+            arr = arr.take(indx[1], axis=ax)
+            ax += 1
+
+        return arr, no_copy
+
+    def _check_multi_index(self, arr, index):
+        """Check a multi index item getting and simple setting.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed, must be a reshaped arange.
+        index : tuple of indexing objects
+            Index being tested.
+        """
+        # Test item getting
+        try:
+            mimic_get, no_copy = self._get_multi_index(arr, index)
+        except Exception:
+            prev_refcount = sys.getrefcount(arr)
+            assert_raises(Exception, arr.__getitem__, index)
+            assert_raises(Exception, arr.__setitem__, index, 0)
+            assert_equal(prev_refcount, sys.getrefcount(arr))
+            return
+
+        self._compare_index_result(arr, index, mimic_get, no_copy)
+
+    def _check_single_index(self, arr, index):
+        """Check a single index item getting and simple setting.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed, must be an arange.
+        index : indexing object
+            Index being tested. Must be a single index and not a tuple
+            of indexing objects (see also `_check_multi_index`).
+        """
+        try:
+            mimic_get, no_copy = self._get_multi_index(arr, (index,))
+        except Exception:
+            prev_refcount = sys.getrefcount(arr)
+            assert_raises(Exception, arr.__getitem__, index)
+            assert_raises(Exception, arr.__setitem__, index, 0)
+            assert_equal(prev_refcount, sys.getrefcount(arr))
+            return
+
+        self._compare_index_result(arr, index, mimic_get, no_copy)
+
+    def _compare_index_result(self, arr, index, mimic_get, no_copy):
+        """Compare mimicked result to indexing result.
+        """
+        arr = arr.copy()
+        indexed_arr = arr[index]
+        assert_array_equal(indexed_arr, mimic_get)
+        # Check if we got a view, unless its a 0-sized or 0-d array.
+        # (then its not a view, and that does not matter)
+        if indexed_arr.size != 0 and indexed_arr.ndim != 0:
+            assert_(np.may_share_memory(indexed_arr, arr) == no_copy)
+            # Check reference count of the original array
+            if no_copy:
+                # refcount increases by one:
+                assert_equal(sys.getrefcount(arr), 3)
+            else:
+                assert_equal(sys.getrefcount(arr), 2)
+
+        # Test non-broadcast setitem:
+        b = arr.copy()
+        b[index] = mimic_get + 1000
+        if b.size == 0:
+            return  # nothing to compare here...
+        if no_copy and indexed_arr.ndim != 0:
+            # change indexed_arr in-place to manipulate original:
+            indexed_arr += 1000
+            assert_array_equal(arr, b)
+            return
+        # Use the fact that the array is originally an arange:
+        arr.flat[indexed_arr.ravel()] += 1000
+        assert_array_equal(arr, b)
+
+    def test_boolean(self):
+        a = np.array(5)
+        assert_equal(a[np.array(True)], 5)
+        a[np.array(True)] = 1
+        assert_equal(a, 1)
+        # NOTE: This is different from normal broadcasting, as
+        # arr[boolean_array] works like in a multi index. Which means
+        # it is aligned to the left. This is probably correct for
+        # consistency with arr[boolean_array,] also no broadcasting
+        # is done at all
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool),))
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool)[..., 0],))
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool)[None, ...],))
+
+    def test_multidim(self):
+        # Automatically test combinations with complex indexes on 2nd (or 1st)
+        # spot and the simple ones in one other spot.
+        with warnings.catch_warnings():
+            # This is so that np.array(True) is not accepted in a full integer
+            # index, when running the file separately.
+            warnings.filterwarnings('error', '', DeprecationWarning)
+            warnings.filterwarnings('error', '', np.VisibleDeprecationWarning)
+
+            def isskip(idx):
+                return isinstance(idx, str) and idx == "skip"
+
+            for simple_pos in [0, 2, 3]:
+                tocheck = [self.fill_indices, self.complex_indices,
+                           self.fill_indices, self.fill_indices]
+                tocheck[simple_pos] = self.simple_indices
+                for index in product(*tocheck):
+                    index = tuple(i for i in index if not isskip(i))
+                    self._check_multi_index(self.a, index)
+                    self._check_multi_index(self.b, index)
+
+        # Check very simple item getting:
+        self._check_multi_index(self.a, (0, 0, 0, 0))
+        self._check_multi_index(self.b, (0, 0, 0, 0))
+        # Also check (simple cases of) too many indices:
+        assert_raises(IndexError, self.a.__getitem__, (0, 0, 0, 0, 0))
+        assert_raises(IndexError, self.a.__setitem__, (0, 0, 0, 0, 0), 0)
+        assert_raises(IndexError, self.a.__getitem__, (0, 0, [1], 0, 0))
+        assert_raises(IndexError, self.a.__setitem__, (0, 0, [1], 0, 0), 0)
+
+    def test_1d(self):
+        a = np.arange(10)
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', np.VisibleDeprecationWarning)
+            for index in self.complex_indices:
+                self._check_single_index(a, index)
+
+
+class TestCApiAccess(TestCase):
+    def test_getitem(self):
+        subscript = functools.partial(array_indexing, 0)
+
+        # 0-d arrays don't work:
+        assert_raises(IndexError, subscript, np.ones(()), 0)
+        # Out of bound values:
+        assert_raises(IndexError, subscript, np.ones(10), 11)
+        assert_raises(IndexError, subscript, np.ones(10), -11)
+        assert_raises(IndexError, subscript, np.ones((10, 10)), 11)
+        assert_raises(IndexError, subscript, np.ones((10, 10)), -11)
+
+        a = np.arange(10)
+        assert_array_equal(a[4], subscript(a, 4))
+        a = a.reshape(5, 2)
+        assert_array_equal(a[-4], subscript(a, -4))
+
+    def test_setitem(self):
+        assign = functools.partial(array_indexing, 1)
+
+        # Deletion is impossible:
+        assert_raises(ValueError, assign, np.ones(10), 0)
+        # 0-d arrays don't work:
+        assert_raises(IndexError, assign, np.ones(()), 0, 0)
+        # Out of bound values:
+        assert_raises(IndexError, assign, np.ones(10), 11, 0)
+        assert_raises(IndexError, assign, np.ones(10), -11, 0)
+        assert_raises(IndexError, assign, np.ones((10, 10)), 11, 0)
+        assert_raises(IndexError, assign, np.ones((10, 10)), -11, 0)
+
+        a = np.arange(10)
+        assign(a, 4, 10)
+        assert_(a[4] == 10)
+
+        a = a.reshape(5, 2)
+        assign(a, 4, 10)
+        assert_array_equal(a[-1], [10, 10])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
new file mode 100644
index 0000000000..ddce20fe9a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_array_equal
+)
+
+
+class TestTake(TestCase):
+    def test_simple(self):
+        a = [[1, 2], [3, 4]]
+        a_str = [[b'1', b'2'], [b'3', b'4']]
+        modes = ['raise', 'wrap', 'clip']
+        indices = [-1, 4]
+        index_arrays = [np.empty(0, dtype=np.intp),
+                        np.empty(tuple(), dtype=np.intp),
+                        np.empty((1, 1), dtype=np.intp)]
+        real_indices = {'raise': {-1: 1, 4: IndexError},
+                        'wrap': {-1: 1, 4: 0},
+                        'clip': {-1: 0, 4: 1}}
+        # Currently all types but object, use the same function generation.
+        # So it should not be necessary to test all. However test also a non
+        # refcounted struct on top of object.
+        types = np.int, np.object, np.dtype([('', 'i', 2)])
+        for t in types:
+            # ta works, even if the array may be odd if buffer interface is used
+            ta = np.array(a if np.issubdtype(t, np.number) else a_str, dtype=t)
+            tresult = list(ta.T.copy())
+            for index_array in index_arrays:
+                if index_array.size != 0:
+                    tresult[0].shape = (2,) + index_array.shape
+                    tresult[1].shape = (2,) + index_array.shape
+                for mode in modes:
+                    for index in indices:
+                        real_index = real_indices[mode][index]
+                        if real_index is IndexError and index_array.size != 0:
+                            index_array.put(0, index)
+                            assert_raises(IndexError, ta.take, index_array,
+                                          mode=mode, axis=1)
+                        elif index_array.size != 0:
+                            index_array.put(0, index)
+                            res = ta.take(index_array, mode=mode, axis=1)
+                            assert_array_equal(res, tresult[real_index])
+                        else:
+                            res = ta.take(index_array, mode=mode, axis=1)
+                            assert_(res.shape == (2,) + index_array.shape)
+
+    def test_refcounting(self):
+        objects = [object() for i in range(10)]
+        for mode in ('raise', 'clip', 'wrap'):
+            a = np.array(objects)
+            b = np.array([2, 2, 4, 5, 3, 5])
+            a.take(b, out=a[:6])
+            del a
+            assert_(all(sys.getrefcount(o) == 3 for o in objects))
+            # not contiguous, example:
+            a = np.array(objects * 2)[::2]
+            a.take(b, out=a[:6])
+            del a
+            assert_(all(sys.getrefcount(o) == 3 for o in objects))
+
+    def test_unicode_mode(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.take, 5, mode=k)
+
+    def test_empty_partition(self):
+        # In reference to github issue #6530
+        a_original = np.array([0, 2, 4, 6, 8, 10])
+        a = a_original.copy()
+
+        # An empty partition should be a successful no-op
+        a.partition(np.array([], dtype=np.int16))
+
+        assert_array_equal(a, a_original)
+
+    def test_empty_argpartition(self):
+            # In reference to github issue #6530
+            a = np.array([0, 2, 4, 6, 8, 10])
+            a = a.argpartition(np.array([], dtype=np.int16))
+
+            b = np.array([0, 1, 2, 3, 4, 5])
+            assert_array_equal(a, b)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
new file mode 100644
index 0000000000..1c561a48f5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
@@ -0,0 +1,209 @@
+from __future__ import division, absolute_import, print_function
+
+import locale
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, dec, assert_raises,
+    assert_array_equal, TestCase, temppath,
+)
+from numpy.compat import sixu
+from test_print import in_foreign_locale
+
+longdouble_longer_than_double = (np.finfo(np.longdouble).eps
+                                 < np.finfo(np.double).eps)
+
+
+_o = 1 + np.finfo(np.longdouble).eps
+string_to_longdouble_inaccurate = (_o != np.longdouble(repr(_o)))
+del _o
+
+
+def test_scalar_extraction():
+    """Confirm that extracting a value doesn't convert to python float"""
+    o = 1 + np.finfo(np.longdouble).eps
+    a = np.array([o, o, o])
+    assert_equal(a[1], o)
+
+
+# Conversions string -> long double
+
+
+def test_repr_roundtrip():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_equal(np.longdouble(repr(o)), o,
+                 "repr was %s" % repr(o))
+
+
+def test_unicode():
+    np.longdouble(sixu("1.2"))
+
+
+def test_string():
+    np.longdouble("1.2")
+
+
+def test_bytes():
+    np.longdouble(b"1.2")
+
+
+@in_foreign_locale
+def test_fromstring_foreign():
+    f = 1.234
+    a = np.fromstring(repr(f), dtype=float, sep=" ")
+    assert_equal(a[0], f)
+
+
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_repr_roundtrip_bytes():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_equal(np.longdouble(repr(o).encode("ascii")), o)
+
+
+@in_foreign_locale
+def test_repr_roundtrip_foreign():
+    o = 1.5
+    assert_equal(o, np.longdouble(repr(o)))
+
+
+def test_bogus_string():
+    assert_raises(ValueError, np.longdouble, "spam")
+    assert_raises(ValueError, np.longdouble, "1.0 flub")
+
+
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_fromstring():
+    o = 1 + np.finfo(np.longdouble).eps
+    s = (" " + repr(o))*5
+    a = np.array([o]*5)
+    assert_equal(np.fromstring(s, sep=" ", dtype=np.longdouble), a,
+                 err_msg="reading '%s'" % s)
+
+
+@in_foreign_locale
+def test_fromstring_best_effort_float():
+    assert_equal(np.fromstring("1,234", dtype=float, sep=" "),
+                 np.array([1.]))
+
+
+@in_foreign_locale
+def test_fromstring_best_effort():
+    assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "),
+                 np.array([1.]))
+
+
+def test_fromstring_bogus():
+    assert_equal(np.fromstring("1. 2. 3. flop 4.", dtype=float, sep=" "),
+                 np.array([1., 2., 3.]))
+
+
+def test_fromstring_empty():
+    assert_equal(np.fromstring("xxxxx", sep="x"),
+                 np.array([]))
+
+
+def test_fromstring_missing():
+    assert_equal(np.fromstring("1xx3x4x5x6", sep="x"),
+                 np.array([1]))
+
+
+class FileBased(TestCase):
+
+    ldbl = 1 + np.finfo(np.longdouble).eps
+    tgt = np.array([ldbl]*5)
+    out = ''.join([repr(t) + '\n' for t in tgt])
+
+    def test_fromfile_bogus(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write("1. 2. 3. flop 4.\n")
+            res = np.fromfile(path, dtype=float, sep=" ")
+        assert_equal(res, np.array([1., 2., 3.]))
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_fromfile(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.fromfile(path, dtype=np.longdouble, sep="\n")
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_genfromtxt(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.genfromtxt(path, dtype=np.longdouble)
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_loadtxt(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.loadtxt(path, dtype=np.longdouble)
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_tofile_roundtrip(self):
+        with temppath() as path:
+            self.tgt.tofile(path, sep=" ")
+            res = np.fromfile(path, dtype=np.longdouble, sep=" ")
+        assert_equal(res, self.tgt)
+
+
+@in_foreign_locale
+def test_fromstring_foreign():
+    s = "1.234"
+    a = np.fromstring(s, dtype=np.longdouble, sep=" ")
+    assert_equal(a[0], np.longdouble(s))
+
+
+@in_foreign_locale
+def test_fromstring_foreign_sep():
+    a = np.array([1, 2, 3, 4])
+    b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",")
+    assert_array_equal(a, b)
+
+
+@in_foreign_locale
+def test_fromstring_foreign_value():
+    b = np.fromstring("1,234", dtype=np.longdouble, sep=" ")
+    assert_array_equal(b[0], 1)
+
+
+# Conversions long double -> string
+
+
+def test_repr_exact():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_(repr(o) != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "BUG #2376")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_format():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_("{0:.40g}".format(o) != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "BUG #2376")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_percent():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_("%.40g" % o != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "array repr problem")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_array_repr():
+    o = 1 + np.finfo(np.longdouble).eps
+    a = np.array([o])
+    b = np.array([1], dtype=np.longdouble)
+    if not np.all(a != b):
+        raise ValueError("precision loss creating arrays")
+    assert_(repr(a) != repr(b))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_machar.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
new file mode 100644
index 0000000000..d8fc537aa4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
@@ -0,0 +1,29 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.core.machar import MachAr
+import numpy.core.numerictypes as ntypes
+from numpy import errstate, array
+from numpy.testing import TestCase, run_module_suite
+
+class TestMachAr(TestCase):
+    def _run_machar_highprec(self):
+        # Instantiate MachAr instance with high enough precision to cause
+        # underflow
+        try:
+            hiprec = ntypes.float96
+            MachAr(lambda v:array([v], hiprec))
+        except AttributeError:
+            "Skipping test: no ntypes.float96 available on this platform."
+
+    def test_underlow(self):
+        # Regression test for #759:
+        # instanciating MachAr for dtype = np.float96 raises spurious warning.
+        with errstate(all='raise'):
+            try:
+                self._run_machar_highprec()
+            except FloatingPointError as e:
+                self.fail("Caught %s exception, should not have been raised." % e)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
new file mode 100644
index 0000000000..5a1f6ac980
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
@@ -0,0 +1,522 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+
+import numpy as np
+from numpy.testing import run_module_suite, assert_, assert_raises, assert_equal
+
+from numpy.core.multiarray_tests import solve_diophantine, internal_overlap
+from numpy.lib.stride_tricks import as_strided
+from numpy.compat import long
+
+if sys.version_info[0] >= 3:
+    xrange = range
+
+
+ndims = 2
+size = 10
+shape = tuple([size] * ndims)
+
+MAY_SHARE_BOUNDS = 0
+MAY_SHARE_EXACT = -1
+
+
+def _indices_for_nelems(nelems):
+    """Returns slices of length nelems, from start onwards, in direction sign."""
+
+    if nelems == 0:
+        return [size // 2]  # int index
+
+    res = []
+    for step in (1, 2):
+        for sign in (-1, 1):
+            start = size // 2 - nelems * step * sign // 2
+            stop = start + nelems * step * sign
+            res.append(slice(start, stop, step * sign))
+
+    return res
+
+
+def _indices_for_axis():
+    """Returns (src, dst) pairs of indices."""
+
+    res = []
+    for nelems in (0, 2, 3):
+        ind = _indices_for_nelems(nelems)
+
+        # no itertools.product available in Py2.4
+        res.extend([(a, b) for a in ind for b in ind])  # all assignments of size "nelems"
+
+    return res
+
+
+def _indices(ndims):
+    """Returns ((axis0_src, axis0_dst), (axis1_src, axis1_dst), ... ) index pairs."""
+
+    ind = _indices_for_axis()
+
+    # no itertools.product available in Py2.4
+
+    res = [[]]
+    for i in range(ndims):
+        newres = []
+        for elem in ind:
+            for others in res:
+                newres.append([elem] + others)
+        res = newres
+
+    return res
+
+
+def _check_assignment(srcidx, dstidx):
+    """Check assignment arr[dstidx] = arr[srcidx] works."""
+
+    arr = np.arange(np.product(shape)).reshape(shape)
+
+    cpy = arr.copy()
+
+    cpy[dstidx] = arr[srcidx]
+    arr[dstidx] = arr[srcidx]
+
+    assert_(np.all(arr == cpy),
+            'assigning arr[%s] = arr[%s]' % (dstidx, srcidx))
+
+
+def test_overlapping_assignments():
+    """Test automatically generated assignments which overlap in memory."""
+
+    inds = _indices(ndims)
+
+    for ind in inds:
+        srcidx = tuple([a[0] for a in ind])
+        dstidx = tuple([a[1] for a in ind])
+
+        yield _check_assignment, srcidx, dstidx
+
+
+def test_diophantine_fuzz():
+    # Fuzz test the diophantine solver
+    rng = np.random.RandomState(1234)
+
+    max_int = np.iinfo(np.intp).max
+
+    for ndim in range(10):
+        feasible_count = 0
+        infeasible_count = 0
+
+        min_count = 500//(ndim + 1)
+
+        numbers = []
+        while min(feasible_count, infeasible_count) < min_count:
+            # Ensure big and small integer problems
+            A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6
+            U_max = rng.randint(0, 11, dtype=np.intp)**6
+
+            A_max = min(max_int, A_max)
+            U_max = min(max_int-1, U_max)
+
+            A = tuple(int(rng.randint(1, A_max+1, dtype=np.intp))
+                      for j in range(ndim))
+            U = tuple(int(rng.randint(0, U_max+2, dtype=np.intp))
+                      for j in range(ndim))
+
+            b_ub = min(max_int-2, sum(a*ub for a, ub in zip(A, U)))
+            b = rng.randint(-1, b_ub+2, dtype=np.intp)
+
+            if ndim == 0 and feasible_count < min_count:
+                b = 0
+
+            X = solve_diophantine(A, U, b)
+
+            if X is None:
+                # Check the simplified decision problem agrees
+                X_simplified = solve_diophantine(A, U, b, simplify=1)
+                assert_(X_simplified is None, (A, U, b, X_simplified))
+
+                # Check no solution exists (provided the problem is
+                # small enough so that brute force checking doesn't
+                # take too long)
+                try:
+                    ranges = tuple(xrange(0, a*ub+1, a) for a, ub in zip(A, U))
+                except OverflowError:
+                    # xrange on 32-bit Python 2 may overflow
+                    continue
+
+                size = 1
+                for r in ranges:
+                    size *= len(r)
+                if size < 100000:
+                    assert_(not any(sum(w) == b for w in itertools.product(*ranges)))
+                    infeasible_count += 1
+            else:
+                # Check the simplified decision problem agrees
+                X_simplified = solve_diophantine(A, U, b, simplify=1)
+                assert_(X_simplified is not None, (A, U, b, X_simplified))
+
+                # Check validity
+                assert_(sum(a*x for a, x in zip(A, X)) == b)
+                assert_(all(0 <= x <= ub for x, ub in zip(X, U)))
+                feasible_count += 1
+
+
+def test_diophantine_overflow():
+    # Smoke test integer overflow detection
+    max_intp = np.iinfo(np.intp).max
+    max_int64 = np.iinfo(np.int64).max
+
+    if max_int64 <= max_intp:
+        # Check that the algorithm works internally in 128-bit;
+        # solving this problem requires large intermediate numbers
+        A = (max_int64//2, max_int64//2 - 10)
+        U = (max_int64//2, max_int64//2 - 10)
+        b = 2*(max_int64//2) - 10
+
+        assert_equal(solve_diophantine(A, U, b), (1, 1))
+
+
+def check_may_share_memory_exact(a, b):
+    got = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
+
+    assert_equal(np.may_share_memory(a, b),
+                 np.may_share_memory(a, b, max_work=MAY_SHARE_BOUNDS))
+
+    a.fill(0)
+    b.fill(0)
+    a.fill(1)
+    exact = b.any()
+
+    err_msg = ""
+    if got != exact:
+        err_msg = "    " + "\n    ".join([
+            "base_a - base_b = %r" % (a.__array_interface__['data'][0] - b.__array_interface__['data'][0],),
+            "shape_a = %r" % (a.shape,),
+            "shape_b = %r" % (b.shape,),
+            "strides_a = %r" % (a.strides,),
+            "strides_b = %r" % (b.strides,),
+            "size_a = %r" % (a.size,),
+            "size_b = %r" % (b.size,)
+        ])
+
+    assert_equal(got, exact, err_msg=err_msg)
+
+
+def test_may_share_memory_manual():
+    # Manual test cases for may_share_memory
+
+    # Base arrays
+    xs0 = [
+        np.zeros([13, 21, 23, 22], dtype=np.int8),
+        np.zeros([13, 21, 23*2, 22], dtype=np.int8)[:,:,::2,:]
+    ]
+
+    # Generate all negative stride combinations
+    xs = []
+    for x in xs0:
+        for ss in itertools.product(*(([slice(None), slice(None, None, -1)],)*4)):
+            xp = x[ss]
+            xs.append(xp)
+
+    for x in xs:
+        # The default is a simple extent check
+        assert_(np.may_share_memory(x[:,0,:], x[:,1,:]))
+        assert_(np.may_share_memory(x[:,0,:], x[:,1,:], max_work=None))
+
+        # Exact checks
+        check_may_share_memory_exact(x[:,0,:], x[:,1,:])
+        check_may_share_memory_exact(x[:,::7], x[:,3::3])
+
+        try:
+            xp = x.ravel()
+            if xp.flags.owndata:
+                continue
+            xp = xp.view(np.int16)
+        except ValueError:
+            continue
+
+        # 0-size arrays cannot overlap
+        check_may_share_memory_exact(x.ravel()[6:6],
+                                     xp.reshape(13, 21, 23, 11)[:,::7])
+
+        # Test itemsize is dealt with
+        check_may_share_memory_exact(x[:,::7],
+                                     xp.reshape(13, 21, 23, 11))
+        check_may_share_memory_exact(x[:,::7],
+                                     xp.reshape(13, 21, 23, 11)[:,3::3])
+        check_may_share_memory_exact(x.ravel()[6:7],
+                                     xp.reshape(13, 21, 23, 11)[:,::7])
+
+    # Check unit size
+    x = np.zeros([1], dtype=np.int8)
+    check_may_share_memory_exact(x, x)
+    check_may_share_memory_exact(x, x.copy())
+
+
+def check_may_share_memory_easy_fuzz(get_max_work, same_steps, min_count):
+    # Check that overlap problems with common strides are solved with
+    # little work.
+    x = np.zeros([17,34,71,97], dtype=np.int16)
+
+    rng = np.random.RandomState(1234)
+
+    def random_slice(n, step):
+        start = rng.randint(0, n+1, dtype=np.intp)
+        stop = rng.randint(start, n+1, dtype=np.intp)
+        if rng.randint(0, 2, dtype=np.intp) == 0:
+            stop, start = start, stop
+            step *= -1
+        return slice(start, stop, step)
+
+    feasible = 0
+    infeasible = 0
+
+    while min(feasible, infeasible) < min_count:
+        steps = tuple(rng.randint(1, 11, dtype=np.intp)
+                      if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                      for j in range(x.ndim))
+        if same_steps:
+            steps2 = steps
+        else:
+            steps2 = tuple(rng.randint(1, 11, dtype=np.intp)
+                           if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                           for j in range(x.ndim))
+
+        t1 = np.arange(x.ndim)
+        rng.shuffle(t1)
+
+        t2 = np.arange(x.ndim)
+        rng.shuffle(t2)
+
+        s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
+        s2 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps2))
+        a = x[s1].transpose(t1)
+        b = x[s2].transpose(t2)
+
+        bounds_overlap = np.may_share_memory(a, b)
+        may_share_answer = np.may_share_memory(a, b)
+        easy_answer = np.may_share_memory(a, b, max_work=get_max_work(a, b))
+        exact_answer = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
+
+        if easy_answer != exact_answer:
+            # assert_equal is slow...
+            assert_equal(easy_answer, exact_answer, err_msg=repr((s1, s2)))
+
+        if may_share_answer != bounds_overlap:
+            assert_equal(may_share_answer, bounds_overlap,
+                         err_msg=repr((s1, s2)))
+
+        if bounds_overlap:
+            if exact_answer:
+                feasible += 1
+            else:
+                infeasible += 1
+
+
+def test_may_share_memory_easy_fuzz():
+    # Check that overlap problems with common strides are always
+    # solved with little work.
+
+    check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: 1,
+                                     same_steps=True,
+                                     min_count=2000)
+
+
+def test_may_share_memory_harder_fuzz():
+    # Overlap problems with not necessarily common strides take more
+    # work.
+    #
+    # The work bound below can't be reduced much. Harder problems can
+    # also exist but not be detected here, as the set of problems
+    # comes from RNG.
+
+    check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: max(a.size, b.size)//2,
+                                     same_steps=False,
+                                     min_count=2000)
+
+
+def test_shares_memory_api():
+    x = np.zeros([4, 5, 6], dtype=np.int8)
+
+    assert_equal(np.shares_memory(x, x), True)
+    assert_equal(np.shares_memory(x, x.copy()), False)
+
+    a = x[:,::2,::3]
+    b = x[:,::3,::2]
+    assert_equal(np.shares_memory(a, b), True)
+    assert_equal(np.shares_memory(a, b, max_work=None), True)
+    assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=1)
+    assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=long(1))
+
+
+def test_internal_overlap_diophantine():
+    def check(A, U, exists=None):
+        X = solve_diophantine(A, U, 0, require_ub_nontrivial=1)
+
+        if exists is None:
+            exists = (X is not None)
+
+        if X is not None:
+            assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U)))
+            assert_(all(0 <= x <= u for x, u in zip(X, U)))
+            assert_(any(x != u//2 for x, u in zip(X, U)))
+
+        if exists:
+            assert_(X is not None, repr(X))
+        else:
+            assert_(X is None, repr(X))
+
+    # Smoke tests
+    check((3, 2), (2*2, 3*2), exists=True)
+    check((3*2, 2), (15*2, (3-1)*2), exists=False)
+
+
+def test_internal_overlap_slices():
+    # Slicing an array never generates internal overlap
+
+    x = np.zeros([17,34,71,97], dtype=np.int16)
+
+    rng = np.random.RandomState(1234)
+
+    def random_slice(n, step):
+        start = rng.randint(0, n+1, dtype=np.intp)
+        stop = rng.randint(start, n+1, dtype=np.intp)
+        if rng.randint(0, 2, dtype=np.intp) == 0:
+            stop, start = start, stop
+            step *= -1
+        return slice(start, stop, step)
+
+    cases = 0
+    min_count = 5000
+
+    while cases < min_count:
+        steps = tuple(rng.randint(1, 11, dtype=np.intp)
+                      if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                      for j in range(x.ndim))
+        t1 = np.arange(x.ndim)
+        rng.shuffle(t1)
+        s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
+        a = x[s1].transpose(t1)
+
+        assert_(not internal_overlap(a))
+        cases += 1
+
+
+def check_internal_overlap(a, manual_expected=None):
+    got = internal_overlap(a)
+
+    # Brute-force check
+    m = set()
+    ranges = tuple(xrange(n) for n in a.shape)
+    for v in itertools.product(*ranges):
+        offset = sum(s*w for s, w in zip(a.strides, v))
+        if offset in m:
+            expected = True
+            break
+        else:
+            m.add(offset)
+    else:
+        expected = False
+
+    # Compare
+    if got != expected:
+        assert_equal(got, expected, err_msg=repr((a.strides, a.shape)))
+    if manual_expected is not None and expected != manual_expected:
+        assert_equal(expected, manual_expected)
+    return got
+
+
+def test_internal_overlap_manual():
+    # Stride tricks can construct arrays with internal overlap
+
+    # We don't care about memory bounds, the array is not
+    # read/write accessed
+    x = np.arange(1).astype(np.int8)
+
+    # Check low-dimensional special cases
+
+    check_internal_overlap(x, False) # 1-dim
+    check_internal_overlap(x.reshape([]), False) # 0-dim
+
+    a = as_strided(x, strides=(3, 4), shape=(4, 4))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(3, 4), shape=(5, 4))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0,), shape=(0,))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0,), shape=(1,))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0,), shape=(2,))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0, -9993), shape=(87, 22))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0, -9993), shape=(1, 22))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0, -9993), shape=(0, 22))
+    check_internal_overlap(a, False)
+
+
+def test_internal_overlap_fuzz():
+    # Fuzz check; the brute-force check is fairly slow
+
+    x = np.arange(1).astype(np.int8)
+
+    overlap = 0
+    no_overlap = 0
+    min_count = 100
+
+    rng = np.random.RandomState(1234)
+
+    while min(overlap, no_overlap) < min_count:
+        ndim = rng.randint(1, 4, dtype=np.intp)
+
+        strides = tuple(rng.randint(-1000, 1000, dtype=np.intp)
+                        for j in range(ndim))
+        shape = tuple(rng.randint(1, 30, dtype=np.intp)
+                      for j in range(ndim))
+
+        a = as_strided(x, strides=strides, shape=shape)
+        result = check_internal_overlap(a)
+
+        if result:
+            overlap += 1
+        else:
+            no_overlap += 1
+
+
+def test_non_ndarray_inputs():
+    # Regression check for gh-5604
+
+    class MyArray(object):
+        def __init__(self, data):
+            self.data = data
+
+        @property
+        def __array_interface__(self):
+            return self.data.__array_interface__
+
+    class MyArray2(object):
+        def __init__(self, data):
+            self.data = data
+
+        def __array__(self):
+            return self.data
+
+    for cls in [MyArray, MyArray2]:
+        x = np.arange(5)
+
+        assert_(np.may_share_memory(cls(x[::2]), x[1::2]))
+        assert_(not np.shares_memory(cls(x[::2]), x[1::2]))
+
+        assert_(np.shares_memory(cls(x[1::3]), x[::2]))
+        assert_(np.may_share_memory(cls(x[1::3]), x[::2]))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
new file mode 100644
index 0000000000..e41758c510
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
@@ -0,0 +1,130 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import shutil
+from tempfile import NamedTemporaryFile, TemporaryFile, mktemp, mkdtemp
+
+from numpy import memmap
+from numpy import arange, allclose, asarray
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    dec
+)
+
+class TestMemmap(TestCase):
+    def setUp(self):
+        self.tmpfp = NamedTemporaryFile(prefix='mmap')
+        self.tempdir = mkdtemp()
+        self.shape = (3, 4)
+        self.dtype = 'float32'
+        self.data = arange(12, dtype=self.dtype)
+        self.data.resize(self.shape)
+
+    def tearDown(self):
+        self.tmpfp.close()
+        shutil.rmtree(self.tempdir)
+
+    def test_roundtrip(self):
+        # Write data to file
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp[:] = self.data[:]
+        del fp  # Test __del__ machinery, which handles cleanup
+
+        # Read data back from file
+        newfp = memmap(self.tmpfp, dtype=self.dtype, mode='r',
+                       shape=self.shape)
+        assert_(allclose(self.data, newfp))
+        assert_array_equal(self.data, newfp)
+
+    def test_open_with_filename(self):
+        tmpname = mktemp('', 'mmap', dir=self.tempdir)
+        fp = memmap(tmpname, dtype=self.dtype, mode='w+',
+                       shape=self.shape)
+        fp[:] = self.data[:]
+        del fp
+
+    def test_unnamed_file(self):
+        with TemporaryFile() as f:
+            fp = memmap(f, dtype=self.dtype, shape=self.shape)
+            del fp
+
+    def test_attributes(self):
+        offset = 1
+        mode = "w+"
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode=mode,
+                    shape=self.shape, offset=offset)
+        self.assertEqual(offset, fp.offset)
+        self.assertEqual(mode, fp.mode)
+        del fp
+
+    def test_filename(self):
+        tmpname = mktemp('', 'mmap', dir=self.tempdir)
+        fp = memmap(tmpname, dtype=self.dtype, mode='w+',
+                       shape=self.shape)
+        abspath = os.path.abspath(tmpname)
+        fp[:] = self.data[:]
+        self.assertEqual(abspath, fp.filename)
+        b = fp[:1]
+        self.assertEqual(abspath, b.filename)
+        del b
+        del fp
+
+    def test_filename_fileobj(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode="w+",
+                    shape=self.shape)
+        self.assertEqual(fp.filename, self.tmpfp.name)
+
+    @dec.knownfailureif(sys.platform == 'gnu0', "This test is known to fail on hurd")
+    def test_flush(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp[:] = self.data[:]
+        assert_equal(fp[0], self.data[0])
+        fp.flush()
+
+    def test_del(self):
+        # Make sure a view does not delete the underlying mmap
+        fp_base = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp_base[0] = 5
+        fp_view = fp_base[0:1]
+        assert_equal(fp_view[0], 5)
+        del fp_view
+        # Should still be able to access and assign values after
+        # deleting the view
+        assert_equal(fp_base[0], 5)
+        fp_base[0] = 6
+        assert_equal(fp_base[0], 6)
+
+    def test_arithmetic_drops_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        tmp = (fp + 10)
+        if isinstance(tmp, memmap):
+            assert_(tmp._mmap is not fp._mmap)
+
+    def test_indexing_drops_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        tmp = fp[[(1, 2), (2, 3)]]
+        if isinstance(tmp, memmap):
+            assert_(tmp._mmap is not fp._mmap)
+
+    def test_slicing_keeps_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        assert_(fp[:2, :2]._mmap is fp._mmap)
+
+    def test_view(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
+        new1 = fp.view()
+        new2 = new1.view()
+        assert_(new1.base is fp)
+        assert_(new2.base is fp)
+        new_array = asarray(fp)
+        assert_(new_array.base is fp)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
new file mode 100644
index 0000000000..0a68ff6e2e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
@@ -0,0 +1,6386 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+import tempfile
+import sys
+import shutil
+import warnings
+import operator
+import io
+import itertools
+import ctypes
+import os
+if sys.version_info[0] >= 3:
+    import builtins
+else:
+    import __builtin__ as builtins
+from decimal import Decimal
+
+
+import numpy as np
+from numpy.compat import asbytes, getexception, strchar, unicode, sixu
+from test_print import in_foreign_locale
+from numpy.core.multiarray_tests import (
+    test_neighborhood_iterator, test_neighborhood_iterator_oob,
+    test_pydatamem_seteventhook_start, test_pydatamem_seteventhook_end,
+    test_inplace_increment, get_buffer_info, test_as_c_array
+    )
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_equal, assert_almost_equal, assert_array_equal,
+    assert_array_almost_equal, assert_allclose,
+    assert_array_less, runstring, dec, SkipTest
+    )
+
+# Need to test an object that does not fully implement math interface
+from datetime import timedelta
+
+
+if sys.version_info[:2] > (3, 2):
+    # In Python 3.3 the representation of empty shape, strides and sub-offsets
+    # is an empty tuple instead of None.
+    # http://docs.python.org/dev/whatsnew/3.3.html#api-changes
+    EMPTY = ()
+else:
+    EMPTY = None
+
+
+class TestFlags(TestCase):
+    def setUp(self):
+        self.a = np.arange(10)
+
+    def test_writeable(self):
+        mydict = locals()
+        self.a.flags.writeable = False
+        self.assertRaises(ValueError, runstring, 'self.a[0] = 3', mydict)
+        self.assertRaises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict)
+        self.a.flags.writeable = True
+        self.a[0] = 5
+        self.a[0] = 0
+
+    def test_otherflags(self):
+        assert_equal(self.a.flags.carray, True)
+        assert_equal(self.a.flags.farray, False)
+        assert_equal(self.a.flags.behaved, True)
+        assert_equal(self.a.flags.fnc, False)
+        assert_equal(self.a.flags.forc, True)
+        assert_equal(self.a.flags.owndata, True)
+        assert_equal(self.a.flags.writeable, True)
+        assert_equal(self.a.flags.aligned, True)
+        assert_equal(self.a.flags.updateifcopy, False)
+
+    def test_string_align(self):
+        a = np.zeros(4, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+        # not power of two are accessed byte-wise and thus considered aligned
+        a = np.zeros(5, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+
+    def test_void_align(self):
+        a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")]))
+        assert_(a.flags.aligned)
+
+
+class TestHash(TestCase):
+    # see #3793
+    def test_int(self):
+        for st, ut, s in [(np.int8, np.uint8, 8),
+                          (np.int16, np.uint16, 16),
+                          (np.int32, np.uint32, 32),
+                          (np.int64, np.uint64, 64)]:
+            for i in range(1, s):
+                assert_equal(hash(st(-2**i)), hash(-2**i),
+                             err_msg="%r: -2**%d" % (st, i))
+                assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (st, i - 1))
+                assert_equal(hash(st(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (st, i))
+
+                i = max(i - 1, 1)
+                assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (ut, i - 1))
+                assert_equal(hash(ut(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (ut, i))
+
+
+class TestAttributes(TestCase):
+    def setUp(self):
+        self.one = np.arange(10)
+        self.two = np.arange(20).reshape(4, 5)
+        self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6)
+
+    def test_attributes(self):
+        assert_equal(self.one.shape, (10,))
+        assert_equal(self.two.shape, (4, 5))
+        assert_equal(self.three.shape, (2, 5, 6))
+        self.three.shape = (10, 3, 2)
+        assert_equal(self.three.shape, (10, 3, 2))
+        self.three.shape = (2, 5, 6)
+        assert_equal(self.one.strides, (self.one.itemsize,))
+        num = self.two.itemsize
+        assert_equal(self.two.strides, (5*num, num))
+        num = self.three.itemsize
+        assert_equal(self.three.strides, (30*num, 6*num, num))
+        assert_equal(self.one.ndim, 1)
+        assert_equal(self.two.ndim, 2)
+        assert_equal(self.three.ndim, 3)
+        num = self.two.itemsize
+        assert_equal(self.two.size, 20)
+        assert_equal(self.two.nbytes, 20*num)
+        assert_equal(self.two.itemsize, self.two.dtype.itemsize)
+        assert_equal(self.two.base, np.arange(20))
+
+    def test_dtypeattr(self):
+        assert_equal(self.one.dtype, np.dtype(np.int_))
+        assert_equal(self.three.dtype, np.dtype(np.float_))
+        assert_equal(self.one.dtype.char, 'l')
+        assert_equal(self.three.dtype.char, 'd')
+        self.assertTrue(self.three.dtype.str[0] in '<>')
+        assert_equal(self.one.dtype.str[1], 'i')
+        assert_equal(self.three.dtype.str[1], 'f')
+
+    def test_int_subclassing(self):
+        # Regression test for https://github.com/numpy/numpy/pull/3526
+
+        numpy_int = np.int_(0)
+
+        if sys.version_info[0] >= 3:
+            # On Py3k int_ should not inherit from int, because it's not
+            # fixed-width anymore
+            assert_equal(isinstance(numpy_int, int), False)
+        else:
+            # Otherwise, it should inherit from int...
+            assert_equal(isinstance(numpy_int, int), True)
+
+            # ... and fast-path checks on C-API level should also work
+            from numpy.core.multiarray_tests import test_int_subclass
+            assert_equal(test_int_subclass(numpy_int), True)
+
+    def test_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            return np.ndarray(size, buffer=x, dtype=int,
+                              offset=offset*x.itemsize,
+                              strides=strides*x.itemsize)
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(ValueError, make_array, 8, 3, 1)
+        assert_equal(make_array(8, 3, 0), np.array([3]*8))
+        # Check behavior reported in gh-2503:
+        self.assertRaises(ValueError, make_array, (2, 3), 5, np.array([-2, -3]))
+        make_array(0, 0, 10)
+
+    def test_set_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            try:
+                r = np.ndarray([size], dtype=int, buffer=x,
+                               offset=offset*x.itemsize)
+            except:
+                raise RuntimeError(getexception())
+            r.strides = strides = strides*x.itemsize
+            return r
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(RuntimeError, make_array, 8, 3, 1)
+        # Check that the true extent of the array is used.
+        # Test relies on as_strided base not exposing a buffer.
+        x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0))
+
+        def set_strides(arr, strides):
+            arr.strides = strides
+
+        self.assertRaises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize))
+
+        # Test for offset calculations:
+        x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1],
+                                                    shape=(10,), strides=(-1,))
+        self.assertRaises(ValueError, set_strides, x[::-1], -1)
+        a = x[::-1]
+        a.strides = 1
+        a[::2].strides = 2
+
+    def test_fill(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = np.empty((3, 2, 1), t)
+            y = np.empty((3, 2, 1), t)
+            x.fill(1)
+            y[...] = 1
+            assert_equal(x, y)
+
+    def test_fill_max_uint64(self):
+        x = np.empty((3, 2, 1), dtype=np.uint64)
+        y = np.empty((3, 2, 1), dtype=np.uint64)
+        value = 2**64 - 1
+        y[...] = value
+        x.fill(value)
+        assert_array_equal(x, y)
+
+    def test_fill_struct_array(self):
+        # Filling from a scalar
+        x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8')
+        x.fill(x[0])
+        assert_equal(x['f1'][1], x['f1'][0])
+        # Filling from a tuple that can be converted
+        # to a scalar
+        x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')])
+        x.fill((3.5, -2))
+        assert_array_equal(x['a'], [3.5, 3.5])
+        assert_array_equal(x['b'], [-2, -2])
+
+
+class TestArrayConstruction(TestCase):
+    def test_array(self):
+        d = np.ones(6)
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6)))
+
+        d = np.ones(6)
+        tgt = np.ones((2, 6))
+        r = np.array([d, d])
+        assert_equal(r, tgt)
+        tgt[1] = 2
+        r = np.array([d, d + 1])
+        assert_equal(r, tgt)
+
+        d = np.ones(6)
+        r = np.array([[d, d]])
+        assert_equal(r, np.ones((1, 2, 6)))
+
+        d = np.ones(6)
+        r = np.array([[d, d], [d, d]])
+        assert_equal(r, np.ones((2, 2, 6)))
+
+        d = np.ones((6, 6))
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6, 6)))
+
+        d = np.ones((6, ))
+        r = np.array([[d, d + 1], d + 2])
+        assert_equal(len(r), 2)
+        assert_equal(r[0], [d, d + 1])
+        assert_equal(r[1], d + 2)
+
+        tgt = np.ones((2, 3), dtype=np.bool)
+        tgt[0, 2] = False
+        tgt[1, 0:2] = False
+        r = np.array([[True, True, False], [False, False, True]])
+        assert_equal(r, tgt)
+        r = np.array([[True, False], [True, False], [False, True]])
+        assert_equal(r, tgt.T)
+
+    def test_array_empty(self):
+        assert_raises(TypeError, np.array)
+
+    def test_array_copy_false(self):
+        d = np.array([1, 2, 3])
+        e = np.array(d, copy=False)
+        d[1] = 3
+        assert_array_equal(e, [1, 3, 3])
+        e = np.array(d, copy=False, order='F')
+        d[1] = 4
+        assert_array_equal(e, [1, 4, 3])
+        e[2] = 7
+        assert_array_equal(d, [1, 4, 7])
+
+    def test_array_copy_true(self):
+        d = np.array([[1,2,3], [1, 2, 3]])
+        e = np.array(d, copy=True)
+        d[0, 1] = 3
+        e[0, 2] = -7
+        assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
+        e = np.array(d, copy=True, order='F')
+        d[0, 1] = 5
+        e[0, 2] = 7
+        assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 5, 3], [1,2,3]])
+
+    def test_array_cont(self):
+        d = np.ones(10)[::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.ascontiguousarray(d).flags.f_contiguous)
+        assert_(np.asfortranarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+        d = np.ones((10, 10))[::2,::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+
+
+class TestAssignment(TestCase):
+    def test_assignment_broadcasting(self):
+        a = np.arange(6).reshape(2, 3)
+
+        # Broadcasting the input to the output
+        a[...] = np.arange(3)
+        assert_equal(a, [[0, 1, 2], [0, 1, 2]])
+        a[...] = np.arange(2).reshape(2, 1)
+        assert_equal(a, [[0, 0, 0], [1, 1, 1]])
+
+        # For compatibility with <= 1.5, a limited version of broadcasting
+        # the output to the input.
+        #
+        # This behavior is inconsistent with NumPy broadcasting
+        # in general, because it only uses one of the two broadcasting
+        # rules (adding a new "1" dimension to the left of the shape),
+        # applied to the output instead of an input. In NumPy 2.0, this kind
+        # of broadcasting assignment will likely be disallowed.
+        a[...] = np.arange(6)[::-1].reshape(1, 2, 3)
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+        # The other type of broadcasting would require a reduction operation.
+
+        def assign(a, b):
+            a[...] = b
+
+        assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3))
+
+    def test_assignment_errors(self):
+        # Address issue #2276
+        class C:
+            pass
+        a = np.zeros(1)
+
+        def assign(v):
+            a[0] = v
+
+        assert_raises((AttributeError, TypeError), assign, C())
+        assert_raises(ValueError, assign, [1])
+
+
+class TestDtypedescr(TestCase):
+    def test_construction(self):
+        d1 = np.dtype('i4')
+        assert_equal(d1, np.dtype(np.int32))
+        d2 = np.dtype('f8')
+        assert_equal(d2, np.dtype(np.float64))
+
+    def test_byteorders(self):
+        self.assertNotEqual(np.dtype('<i4'), np.dtype('>i4'))
+        self.assertNotEqual(np.dtype([('a', '<i4')]), np.dtype([('a', '>i4')]))
+
+
+class TestZeroRank(TestCase):
+    def setUp(self):
+        self.d = np.array(0), np.array('x', object)
+
+    def test_ellipsis_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(b[...], 'x')
+        self.assertTrue(a[...].base is a)  # `a[...] is a` in numpy <1.9.
+        self.assertTrue(b[...].base is b)  # `b[...] is b` in numpy <1.9.
+
+    def test_empty_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(b[()], 'x')
+        self.assertTrue(type(a[()]) is a.dtype.type)
+        self.assertTrue(type(b[()]) is str)
+
+    def test_invalid_subscript(self):
+        a, b = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[0], b)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], b)
+
+    def test_ellipsis_subscript_assignment(self):
+        a, b = self.d
+        a[...] = 42
+        self.assertEqual(a, 42)
+        b[...] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_empty_subscript_assignment(self):
+        a, b = self.d
+        a[()] = 42
+        self.assertEqual(a, 42)
+        b[()] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_invalid_subscript_assignment(self):
+        a, b = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(IndexError, assign, a, 0, 42)
+        self.assertRaises(IndexError, assign, b, 0, '')
+        self.assertRaises(ValueError, assign, a, (), '')
+
+    def test_newaxis(self):
+        a, b = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a, b = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_constructor(self):
+        x = np.ndarray(())
+        x[()] = 5
+        self.assertEqual(x[()], 5)
+        y = np.ndarray((), buffer=x)
+        y[()] = 6
+        self.assertEqual(x[()], 6)
+
+    def test_output(self):
+        x = np.array(2)
+        self.assertRaises(ValueError, np.add, x, [1], x)
+
+
+class TestScalarIndexing(TestCase):
+    def setUp(self):
+        self.d = np.array([0, 1])[0]
+
+    def test_ellipsis_subscript(self):
+        a = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(a[...].shape, ())
+
+    def test_empty_subscript(self):
+        a = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(a[()].shape, ())
+
+    def test_invalid_subscript(self):
+        a = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+
+    def test_invalid_subscript_assignment(self):
+        a = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(TypeError, assign, a, 0, 42)
+
+    def test_newaxis(self):
+        a = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_overlapping_assignment(self):
+        # With positive strides
+        a = np.arange(4)
+        a[:-1] = a[1:]
+        assert_equal(a, [1, 2, 3, 3])
+
+        a = np.arange(4)
+        a[1:] = a[:-1]
+        assert_equal(a, [0, 0, 1, 2])
+
+        # With positive and negative strides
+        a = np.arange(4)
+        a[:] = a[::-1]
+        assert_equal(a, [3, 2, 1, 0])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1,:] = a[:, ::-1]
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1, ::-1] = a[:, ::-1]
+        assert_equal(a, [[3, 4, 5], [0, 1, 2]])
+
+        # With just one element overlapping
+        a = np.arange(5)
+        a[:3] = a[2:]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[:3]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+        a = np.arange(5)
+        a[2::-1] = a[2:]
+        assert_equal(a, [4, 3, 2, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[2::-1]
+        assert_equal(a, [0, 1, 2, 1, 0])
+
+        a = np.arange(5)
+        a[2::-1] = a[:1:-1]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[:1:-1] = a[2::-1]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+
+class TestCreation(TestCase):
+    def test_from_attribute(self):
+        class x(object):
+            def __array__(self, dtype=None):
+                pass
+
+        self.assertRaises(ValueError, np.array, x())
+
+    def test_from_string(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['Float']
+        nstr = ['123', '123']
+        result = np.array([123, 123], dtype=int)
+        for type in types:
+            msg = 'String conversion for %s' % type
+            assert_equal(np.array(nstr, dtype=type), result, err_msg=msg)
+
+    def test_void(self):
+        arr = np.array([], dtype='V')
+        assert_equal(arr.dtype.kind, 'V')
+
+    def test_zeros(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((13,), dtype=dt)
+            assert_equal(np.count_nonzero(d), 0)
+            # true for ieee floats
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='4i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4, (2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+
+    @dec.slow
+    def test_zeros_big(self):
+        # test big array as they might be allocated different by the system
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((30 * 1024**2,), dtype=dt)
+            assert_(not d.any())
+            # This test can fail on 32-bit systems due to insufficient
+            # contiguous memory. Deallocating the previous array increases the
+            # chance of success.
+            del(d)
+
+    def test_zeros_obj(self):
+        # test initialization from PyLong(0)
+        d = np.zeros((13,), dtype=object)
+        assert_array_equal(d, [0] * 13)
+        assert_equal(np.count_nonzero(d), 0)
+
+    def test_zeros_obj_obj(self):
+        d = np.zeros(10, dtype=[('k', object, 2)])
+        assert_array_equal(d['k'], 0)
+
+    def test_zeros_like_like_zeros(self):
+        # test zeros_like returns the same as zeros
+        for c in np.typecodes['All']:
+            if c == 'V':
+                continue
+            d = np.zeros((3,3), dtype=c)
+            assert_array_equal(np.zeros_like(d), d)
+            assert_equal(np.zeros_like(d).dtype, d.dtype)
+        # explicitly check some special cases
+        d = np.zeros((3,3), dtype='S5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='U5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='f4,f4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+    def test_empty_unicode(self):
+        # don't throw decode errors on garbage memory
+        for i in range(5, 100, 5):
+            d = np.empty(i, dtype='U')
+            str(d)
+
+    def test_sequence_non_homogenous(self):
+        assert_equal(np.array([4, 2**80]).dtype, np.object)
+        assert_equal(np.array([4, 2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80] * 3).dtype, np.object)
+        assert_equal(np.array([[1, 1],[1j, 1j]]).dtype, np.complex)
+        assert_equal(np.array([[1j, 1j],[1, 1]]).dtype, np.complex)
+        assert_equal(np.array([[1, 1, 1],[1, 1j, 1.], [1, 1, 1]]).dtype, np.complex)
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_sequence_long(self):
+        assert_equal(np.array([long(4), long(4)]).dtype, np.long)
+        assert_equal(np.array([long(4), 2**80]).dtype, np.object)
+        assert_equal(np.array([long(4), 2**80, long(4)]).dtype, np.object)
+        assert_equal(np.array([2**80, long(4)]).dtype, np.object)
+
+    def test_non_sequence_sequence(self):
+        """Should not segfault.
+
+        Class Fail breaks the sequence protocol for new style classes, i.e.,
+        those derived from object. Class Map is a mapping type indicated by
+        raising a ValueError. At some point we may raise a warning instead
+        of an error in the Fail case.
+
+        """
+        class Fail(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise ValueError()
+
+        class Map(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise KeyError()
+
+        a = np.array([Map()])
+        assert_(a.shape == (1,))
+        assert_(a.dtype == np.dtype(object))
+        assert_raises(ValueError, np.array, [Fail()])
+
+    def test_no_len_object_type(self):
+        # gh-5100, want object array from iterable object without len()
+        class Point2:
+            def __init__(self):
+                pass
+
+            def __getitem__(self, ind):
+                if ind in [0, 1]:
+                    return ind
+                else:
+                    raise IndexError()
+        d = np.array([Point2(), Point2(), Point2()])
+        assert_equal(d.dtype, np.dtype(object))
+
+    def test_false_len_sequence(self):
+        # gh-7264, segfault for this example
+        class C:
+            def __getitem__(self, i):
+                raise IndexError
+            def __len__(self):
+                return 42
+
+        assert_raises(ValueError, np.array, C()) # segfault?
+
+    def test_failed_len_sequence(self):
+        # gh-7393
+        class A(object):
+            def __init__(self, data):
+                self._data = data
+            def __getitem__(self, item):
+                return type(self)(self._data[item])
+            def __len__(self):
+                return len(self._data)
+
+        # len(d) should give 3, but len(d[0]) will fail
+        d = A([1,2,3])
+        assert_equal(len(np.array(d)), 3)
+
+
+class TestStructured(TestCase):
+    def test_subarray_field_access(self):
+        a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
+        a['a'] = np.arange(60).reshape(3, 5, 2, 2)
+
+        # Since the subarray is always in C-order, a transpose
+        # does not swap the subarray:
+        assert_array_equal(a.T['a'], a['a'].transpose(1, 0, 2, 3))
+
+        # In Fortran order, the subarray gets appended
+        # like in all other cases, not prepended as a special case
+        b = a.copy(order='F')
+        assert_equal(a['a'].shape, b['a'].shape)
+        assert_equal(a.T['a'].shape, a.T.copy()['a'].shape)
+
+    def test_subarray_comparison(self):
+        # Check that comparisons between record arrays with
+        # multi-dimensional field types work properly
+        a = np.rec.fromrecords(
+            [([1, 2, 3], 'a', [[1, 2], [3, 4]]), ([3, 3, 3], 'b', [[0, 0], [0, 0]])],
+            dtype=[('a', ('f4', 3)), ('b', np.object), ('c', ('i4', (2, 2)))])
+        b = a.copy()
+        assert_equal(a == b, [True, True])
+        assert_equal(a != b, [False, False])
+        b[1].b = 'c'
+        assert_equal(a == b, [True, False])
+        assert_equal(a != b, [False, True])
+        for i in range(3):
+            b[0].a = a[0].a
+            b[0].a[i] = 5
+            assert_equal(a == b, [False, False])
+            assert_equal(a != b, [True, True])
+        for i in range(2):
+            for j in range(2):
+                b = a.copy()
+                b[0].c[i, j] = 10
+                assert_equal(a == b, [False, True])
+                assert_equal(a != b, [True, False])
+
+        # Check that broadcasting with a subarray works
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8')])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8')])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8', (1,))])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8', (1,))])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))])
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that broadcasting Fortran-style arrays with a subarray work
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))], order='F')
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that incompatible sub-array shapes don't result to broadcasting
+        x = np.zeros((1,), dtype=[('a', ('f4', (1, 2))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        # Check that structured arrays that are different only in
+        # byte-order work
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i8'), ('b', '<f8')])
+        b = np.array([(5, 43), (10, 1)], dtype=[('a', '<i8'), ('b', '>f8')])
+        assert_equal(a == b, [False, True])
+
+    def test_casting(self):
+        # Check that casting a structured array to change its byte order
+        # works
+        a = np.array([(1,)], dtype=[('a', '<i4')])
+        assert_(np.can_cast(a.dtype, [('a', '>i4')], casting='unsafe'))
+        b = a.astype([('a', '>i4')])
+        assert_equal(b, a.byteswap().newbyteorder())
+        assert_equal(a['a'][0], b['a'][0])
+
+        # Check that equality comparison works on structured arrays if
+        # they are 'equiv'-castable
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', '<f8')])
+        b = np.array([(42, 5), (1, 10)], dtype=[('b', '>f8'), ('a', '<i4')])
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        assert_equal(a == b, [True, True])
+
+        # Check that 'equiv' casting can reorder fields and change byte
+        # order
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        c = a.astype(b.dtype, casting='equiv')
+        assert_equal(a == c, [True, True])
+
+        # Check that 'safe' casting can change byte order and up-cast
+        # fields
+        t = [('a', '<i8'), ('b', '>f8')]
+        assert_(np.can_cast(a.dtype, t, casting='safe'))
+        c = a.astype(t, casting='safe')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that 'same_kind' casting can change byte order and
+        # change field widths within a "kind"
+        t = [('a', '<i4'), ('b', '>f4')]
+        assert_(np.can_cast(a.dtype, t, casting='same_kind'))
+        c = a.astype(t, casting='same_kind')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that casting fails if the casting rule should fail on
+        # any of the fields
+        t = [('a', '>i8'), ('b', '<f4')]
+        assert_(not np.can_cast(a.dtype, t, casting='safe'))
+        assert_raises(TypeError, a.astype, t, casting='safe')
+        t = [('a', '>i2'), ('b', '<f8')]
+        assert_(not np.can_cast(a.dtype, t, casting='equiv'))
+        assert_raises(TypeError, a.astype, t, casting='equiv')
+        t = [('a', '>i8'), ('b', '<i2')]
+        assert_(not np.can_cast(a.dtype, t, casting='same_kind'))
+        assert_raises(TypeError, a.astype, t, casting='same_kind')
+        assert_(not np.can_cast(a.dtype, b.dtype, casting='no'))
+        assert_raises(TypeError, a.astype, b.dtype, casting='no')
+
+        # Check that non-'unsafe' casting can't change the set of field names
+        for casting in ['no', 'safe', 'equiv', 'same_kind']:
+            t = [('a', '>i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+            t = [('a', '>i4'), ('b', '<f8'), ('c', 'i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+
+    def test_objview(self):
+        # https://github.com/numpy/numpy/issues/3286
+        a = np.array([], dtype=[('a', 'f'), ('b', 'f'), ('c', 'O')])
+        a[['a', 'b']]  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3253
+        dat2 = np.zeros(3, [('A', 'i'), ('B', '|O')])
+        dat2[['B', 'A']]  # TypeError?
+
+    def test_setfield(self):
+        # https://github.com/numpy/numpy/issues/3126
+        struct_dt = np.dtype([('elem', 'i4', 5),])
+        dt = np.dtype([('field', 'i4', 10),('struct', struct_dt)])
+        x = np.zeros(1, dt)
+        x[0]['field'] = np.ones(10, dtype='i4')
+        x[0]['struct'] = np.ones(1, dtype=struct_dt)
+        assert_equal(x[0]['field'], np.ones(10, dtype='i4'))
+
+    def test_setfield_object(self):
+        # make sure object field assignment with ndarray value
+        # on void scalar mimics setitem behavior
+        b = np.zeros(1, dtype=[('x', 'O')])
+        # next line should work identically to b['x'][0] = np.arange(3)
+        b[0]['x'] = np.arange(3)
+        assert_equal(b[0]['x'], np.arange(3))
+
+        # check that broadcasting check still works
+        c = np.zeros(1, dtype=[('x', 'O', 5)])
+
+        def testassign():
+            c[0]['x'] = np.arange(3)
+
+        assert_raises(ValueError, testassign)
+
+
+class TestBool(TestCase):
+    def test_test_interning(self):
+        a0 = np.bool_(0)
+        b0 = np.bool_(False)
+        self.assertTrue(a0 is b0)
+        a1 = np.bool_(1)
+        b1 = np.bool_(True)
+        self.assertTrue(a1 is b1)
+        self.assertTrue(np.array([True])[0] is a1)
+        self.assertTrue(np.array(True)[()] is a1)
+
+    def test_sum(self):
+        d = np.ones(101, dtype=np.bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+        d = np.frombuffer(b'\xff\xff' * 100, dtype=bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+    def check_count_nonzero(self, power, length):
+        powers = [2 ** i for i in range(length)]
+        for i in range(2**power):
+            l = [(i & x) != 0 for x in powers]
+            a = np.array(l, dtype=np.bool)
+            c = builtins.sum(l)
+            self.assertEqual(np.count_nonzero(a), c)
+            av = a.view(np.uint8)
+            av *= 3
+            self.assertEqual(np.count_nonzero(a), c)
+            av *= 4
+            self.assertEqual(np.count_nonzero(a), c)
+            av[av != 0] = 0xFF
+            self.assertEqual(np.count_nonzero(a), c)
+
+    def test_count_nonzero(self):
+        # check all 12 bit combinations in a length 17 array
+        # covers most cases of the 16 byte unrolled code
+        self.check_count_nonzero(12, 17)
+
+    @dec.slow
+    def test_count_nonzero_all(self):
+        # check all combinations in a length 17 array
+        # covers all cases of the 16 byte unrolled code
+        self.check_count_nonzero(17, 17)
+
+    def test_count_nonzero_unaligned(self):
+        # prevent mistakes as e.g. gh-4060
+        for o in range(7):
+            a = np.zeros((18,), dtype=np.bool)[o+1:]
+            a[:o] = True
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+            a = np.ones((18,), dtype=np.bool)[o+1:]
+            a[:o] = False
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+
+
+class TestMethods(TestCase):
+    def test_compress(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = arr.compress([0, 1, 0, 1, 0], axis=1)
+        assert_equal(out, tgt)
+
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=1)
+        assert_equal(out, tgt)
+
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1])
+        assert_equal(out, 1)
+
+    def test_choose(self):
+        x = 2*np.ones((3,), dtype=int)
+        y = 3*np.ones((3,), dtype=int)
+        x2 = 2*np.ones((2, 3), dtype=int)
+        y2 = 3*np.ones((2, 3), dtype=int)
+        ind = np.array([0, 0, 1])
+
+        A = ind.choose((x, y))
+        assert_equal(A, [2, 2, 3])
+
+        A = ind.choose((x2, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+        A = ind.choose((x, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_prod(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, a.prod)
+                self.assertRaises(ArithmeticError, a2.prod, axis=1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+    def test_repeat(self):
+        m = np.array([1, 2, 3, 4, 5, 6])
+        m_rect = m.reshape((2, 3))
+
+        A = m.repeat([1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+        A = m.repeat(2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+        A = m_rect.repeat([2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat([1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+        A = m_rect.repeat(2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat(2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+    def test_reshape(self):
+        arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
+
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(arr.reshape(2, 6), tgt)
+
+        tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
+        assert_equal(arr.reshape(3, 4), tgt)
+
+        tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
+        assert_equal(arr.reshape((3, 4), order='F'), tgt)
+
+        tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
+        assert_equal(arr.T.reshape((3, 4), order='C'), tgt)
+
+    def test_round(self):
+        def check_round(arr, expected, *round_args):
+            assert_equal(arr.round(*round_args), expected)
+            # With output array
+            out = np.zeros_like(arr)
+            res = arr.round(*round_args, out=out)
+            assert_equal(out, expected)
+            assert_equal(out, res)
+
+        check_round(np.array([1.2, 1.5]), [1, 2])
+        check_round(np.array(1.5), 2)
+        check_round(np.array([12.2, 15.5]), [10, 20], -1)
+        check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1)
+        # Complex rounding
+        check_round(np.array([4.5 + 1.5j]), [4 + 2j])
+        check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1)
+
+    def test_squeeze(self):
+        a = np.array([[[1], [2], [3]]])
+        assert_equal(a.squeeze(), [1, 2, 3])
+        assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]])
+        assert_raises(ValueError, a.squeeze, axis=(1,))
+        assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]])
+
+    def test_transpose(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(a.transpose(), [[1, 3], [2, 4]])
+        self.assertRaises(ValueError, lambda: a.transpose(0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 1, 2))
+
+    def test_sort(self):
+        # test ordering for floats and complex containing nans. It is only
+        # necessary to check the less-than comparison, so sorts that
+        # only follow the insertion sort path are sufficient. We only
+        # test doubles and complex doubles as the logic is the same.
+
+        # check doubles
+        msg = "Test real sort order with nans"
+        a = np.array([np.nan, 1, 0])
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+        # check complex
+        msg = "Test complex sort order with nans"
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0]
+        a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0]
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+
+        # all c scalar sorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test complex sorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, real part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, imag part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+
+        # test sorting of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                c = arr.copy()
+                c.sort()
+                msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
+                assert_equal(c, arr, msg)
+
+        # test string sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "string sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test unicode sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test object array sorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test record array sorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test datetime64 sorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test timedelta64 sorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific sorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 0], [3, 2]])
+        c = np.array([[2, 3], [0, 1]])
+        d = a.copy()
+        d.sort(axis=0)
+        assert_equal(d, b, "test sort with axis=0")
+        d = a.copy()
+        d.sort(axis=1)
+        assert_equal(d, c, "test sort with axis=1")
+        d = a.copy()
+        d.sort()
+        assert_equal(d, c, "test sort with default axis")
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array sort with axis={0}'.format(axis)
+            assert_equal(np.sort(a, axis=axis), a, msg)
+        msg = 'test empty array sort with axis=None'
+        assert_equal(np.sort(a, axis=None), a.ravel(), msg)
+
+    def test_copy(self):
+        def assert_fortran(arr):
+            assert_(arr.flags.fortran)
+            assert_(arr.flags.f_contiguous)
+            assert_(not arr.flags.c_contiguous)
+
+        def assert_c(arr):
+            assert_(not arr.flags.fortran)
+            assert_(not arr.flags.f_contiguous)
+            assert_(arr.flags.c_contiguous)
+
+        a = np.empty((2, 2), order='F')
+        # Test copying a Fortran array
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_fortran(a.copy('A'))
+
+        # Now test starting with a C array.
+        a = np.empty((2, 2), order='C')
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_c(a.copy('A'))
+
+    def test_sort_order(self):
+        # Test sorting an array with fields
+        x1 = np.array([21, 32, 14])
+        x2 = np.array(['my', 'first', 'name'])
+        x3 = np.array([3.1, 4.5, 6.2])
+        r = np.rec.fromarrays([x1, x2, x3], names='id,word,number')
+
+        r.sort(order=['id'])
+        assert_equal(r.id, np.array([14, 21, 32]))
+        assert_equal(r.word, np.array(['name', 'my', 'first']))
+        assert_equal(r.number, np.array([6.2, 3.1, 4.5]))
+
+        r.sort(order=['word'])
+        assert_equal(r.id, np.array([32, 21, 14]))
+        assert_equal(r.word, np.array(['first', 'my', 'name']))
+        assert_equal(r.number, np.array([4.5, 3.1, 6.2]))
+
+        r.sort(order=['number'])
+        assert_equal(r.id, np.array([21, 32, 14]))
+        assert_equal(r.word, np.array(['my', 'first', 'name']))
+        assert_equal(r.number, np.array([3.1, 4.5, 6.2]))
+
+        if sys.byteorder == 'little':
+            strtype = '>i2'
+        else:
+            strtype = '<i2'
+        mydtype = [('name', strchar + '5'), ('col2', strtype)]
+        r = np.array([('a', 1), ('b', 255), ('c', 3), ('d', 258)],
+                     dtype=mydtype)
+        r.sort(order='col2')
+        assert_equal(r['col2'], [1, 3, 255, 258])
+        assert_equal(r, np.array([('a', 1), ('c', 3), ('b', 255), ('d', 258)],
+                                 dtype=mydtype))
+
+    def test_argsort(self):
+        # all c scalar argsorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), a, msg)
+            assert_equal(b.copy().argsort(kind=kind), b, msg)
+
+        # test complex argsorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+
+        # test argsort of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                msg = 'byte-swapped complex argsort, dtype={0}'.format(dt)
+                assert_equal(arr.argsort(),
+                             np.arange(len(arr), dtype=np.intp), msg)
+
+        # test string argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "string argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test unicode argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test object array argsorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "object argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test structured array argsorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "structured array argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test datetime64 argsorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test timedelta64 argsorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific argsorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 1], [0, 0]])
+        c = np.array([[1, 0], [1, 0]])
+        assert_equal(a.copy().argsort(axis=0), b)
+        assert_equal(a.copy().argsort(axis=1), c)
+        assert_equal(a.copy().argsort(), c)
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argsort with axis={0}'.format(axis)
+            assert_equal(np.argsort(a, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argsort with axis=None'
+        assert_equal(np.argsort(a, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+        # check that stable argsorts are stable
+        r = np.arange(100)
+        # scalars
+        a = np.zeros(100)
+        assert_equal(a.argsort(kind='m'), r)
+        # complex
+        a = np.zeros(100, dtype=np.complex)
+        assert_equal(a.argsort(kind='m'), r)
+        # string
+        a = np.array(['aaaaaaaaa' for i in range(100)])
+        assert_equal(a.argsort(kind='m'), r)
+        # unicode
+        a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode)
+        assert_equal(a.argsort(kind='m'), r)
+
+    def test_sort_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.sort, kind=k)
+        assert_raises(ValueError, d.argsort, kind=k)
+
+    def test_searchsorted(self):
+        # test for floats and complex containing nans. The logic is the
+        # same for all float types so only test double types for now.
+        # The search sorted routines use the compare functions for the
+        # array type, so this checks if that is consistent with the sort
+        # order.
+
+        # check double
+        a = np.array([0, 1, np.nan])
+        msg = "Test real searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(3), msg)
+        msg = "Test real searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 4), msg)
+        # check double complex
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan]
+        a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan]
+        msg = "Test complex searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(9), msg)
+        msg = "Test complex searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 10), msg)
+        msg = "Test searchsorted with little endian, side='l'"
+        a = np.array([0, 128], dtype='<i4')
+        b = a.searchsorted(np.array(128, dtype='<i4'))
+        assert_equal(b, 1, msg)
+        msg = "Test searchsorted with big endian, side='l'"
+        a = np.array([0, 128], dtype='>i4')
+        b = a.searchsorted(np.array(128, dtype='>i4'))
+        assert_equal(b, 1, msg)
+
+        # Check 0 elements
+        a = np.ones(0)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 0])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 0, 0])
+        a = np.ones(1)
+        # Check 1 element
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 1])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 1, 1])
+        # Check all elements equal
+        a = np.ones(2)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 2])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 2, 2])
+
+        # Test searching unaligned array
+        a = np.arange(10)
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        unaligned[:] = a
+        # Test searching unaligned array
+        b = unaligned.searchsorted(a, 'l')
+        assert_equal(b, a)
+        b = unaligned.searchsorted(a, 'r')
+        assert_equal(b, a + 1)
+        # Test searching for unaligned keys
+        b = a.searchsorted(unaligned, 'l')
+        assert_equal(b, a)
+        b = a.searchsorted(unaligned, 'r')
+        assert_equal(b, a + 1)
+
+        # Test smart resetting of binsearch indices
+        a = np.arange(5)
+        b = a.searchsorted([6, 5, 4], 'l')
+        assert_equal(b, [5, 5, 4])
+        b = a.searchsorted([6, 5, 4], 'r')
+        assert_equal(b, [5, 5, 5])
+
+        # Test all type specific binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.arange(2, dtype=dt)
+                out = np.arange(2)
+            else:
+                a = np.arange(0, 5, dtype=dt)
+                out = np.arange(5)
+            b = a.searchsorted(a, 'l')
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r')
+            assert_equal(b, out + 1)
+
+    def test_searchsorted_unicode(self):
+        # Test searchsorted on unicode strings.
+
+        # 1.6.1 contained a string length miscalculation in
+        # arraytypes.c.src:UNICODE_compare() which manifested as
+        # incorrect/inconsistent results from searchsorted.
+        a = np.array(['P:\\20x_dapi_cy3\\20x_dapi_cy3_20100185_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100186_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100187_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100189_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100190_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100191_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100192_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100193_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100194_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100195_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100196_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
+                     dtype=np.unicode)
+        ind = np.arange(len(a))
+        assert_equal([a.searchsorted(v, 'left') for v in a], ind)
+        assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
+        assert_equal([a.searchsorted(a[i], 'left') for i in ind], ind)
+        assert_equal([a.searchsorted(a[i], 'right') for i in ind], ind + 1)
+
+    def test_searchsorted_with_sorter(self):
+        a = np.array([5, 2, 1, 3, 4])
+        s = np.argsort(a)
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=(1, (2, 3)))
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=[1.1])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4, 5, 6])
+
+        # bounds check
+        assert_raises(ValueError, np.searchsorted, a, 4, sorter=[0, 1, 2, 3, 5])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[-1, 0, 1, 2, 3])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[4, 0, -1, 2, 3])
+
+        a = np.random.rand(300)
+        s = a.argsort()
+        b = np.sort(a)
+        k = np.linspace(0, 1, 20)
+        assert_equal(b.searchsorted(k), a.searchsorted(k, sorter=s))
+
+        a = np.array([0, 1, 2, 3, 5]*20)
+        s = a.argsort()
+        k = [0, 1, 2, 3, 5]
+        expected = [0, 20, 40, 60, 80]
+        assert_equal(a.searchsorted(k, side='l', sorter=s), expected)
+        expected = [20, 40, 60, 80, 100]
+        assert_equal(a.searchsorted(k, side='r', sorter=s), expected)
+
+        # Test searching unaligned array
+        keys = np.arange(10)
+        a = keys.copy()
+        np.random.shuffle(s)
+        s = a.argsort()
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        # Test searching unaligned array
+        unaligned[:] = a
+        b = unaligned.searchsorted(keys, 'l', s)
+        assert_equal(b, keys)
+        b = unaligned.searchsorted(keys, 'r', s)
+        assert_equal(b, keys + 1)
+        # Test searching for unaligned keys
+        unaligned[:] = keys
+        b = a.searchsorted(unaligned, 'l', s)
+        assert_equal(b, keys)
+        b = a.searchsorted(unaligned, 'r', s)
+        assert_equal(b, keys + 1)
+
+        # Test all type specific indirect binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.array([1, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([1, 0], dtype=np.int16)
+                out = np.array([1, 0])
+            else:
+                a = np.array([3, 4, 1, 2, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([4, 2, 3, 0, 1], dtype=np.int16)
+                out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+            b = a.searchsorted(a, 'l', s)
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r', s)
+            assert_equal(b, out + 1)
+
+        # Test non-contiguous sorter array
+        a = np.array([3, 4, 1, 2, 0])
+        srt = np.empty((10,), dtype=np.intp)
+        srt[1::2] = -1
+        srt[::2] = [4, 2, 3, 0, 1]
+        s = srt[::2]
+        out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+        b = a.searchsorted(a, 'l', s)
+        assert_equal(b, out)
+        b = a.searchsorted(a, 'r', s)
+        assert_equal(b, out + 1)
+
+    def test_searchsorted_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        s = np.arange(5).view(A)
+        assert_(not isinstance(a.searchsorted(b, 'l'), A))
+        assert_(not isinstance(a.searchsorted(b, 'r'), A))
+        assert_(not isinstance(a.searchsorted(b, 'l', s), A))
+        assert_(not isinstance(a.searchsorted(b, 'r', s), A))
+
+    def test_argpartition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.argpartition, 10)
+        assert_raises(ValueError, d.argpartition, -11)
+        # Test also for generic type argpartition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.argpartition, 10)
+        assert_raises(ValueError, d_obj.argpartition, -11)
+
+    def test_partition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.partition, 10)
+        assert_raises(ValueError, d.partition, -11)
+        # Test also for generic type partition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.partition, 10)
+        assert_raises(ValueError, d_obj.partition, -11)
+
+    def test_partition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array partition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis), a, msg)
+        msg = 'test empty array partition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None), a.ravel(), msg)
+
+    def test_argpartition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argpartition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argpartition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+    def test_partition(self):
+        d = np.arange(10)
+        assert_raises(TypeError, np.partition, d, 2, kind=1)
+        assert_raises(ValueError, np.partition, d, 2, kind="nonsense")
+        assert_raises(ValueError, np.argpartition, d, 2, kind="nonsense")
+        assert_raises(ValueError, d.partition, 2, axis=0, kind="nonsense")
+        assert_raises(ValueError, d.argpartition, 2, axis=0, kind="nonsense")
+        for k in ("introselect",):
+            d = np.array([])
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(np.argpartition(d, 0, kind=k), d)
+            d = np.ones(1)
+            assert_array_equal(np.partition(d, 0, kind=k)[0], d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # kth not modified
+            kth = np.array([30, 15, 5])
+            okth = kth.copy()
+            np.partition(np.arange(40), kth)
+            assert_array_equal(kth, okth)
+
+            for r in ([2, 1], [1, 2], [1, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            for r in ([3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1],
+                      [1, 1, 1], [1, 2, 2], [2, 2, 1], [1, 2, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(np.partition(d, 2, kind=k)[2], tgt[2])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                assert_array_equal(d[np.argpartition(d, 2, kind=k)],
+                                   np.partition(d, 2, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            d = np.ones(50)
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # sorted
+            d = np.arange(49)
+            self.assertEqual(np.partition(d, 5, kind=k)[5], 5)
+            self.assertEqual(np.partition(d, 15, kind=k)[15], 15)
+            assert_array_equal(d[np.argpartition(d, 5, kind=k)],
+                               np.partition(d, 5, kind=k))
+            assert_array_equal(d[np.argpartition(d, 15, kind=k)],
+                               np.partition(d, 15, kind=k))
+
+            # rsorted
+            d = np.arange(47)[::-1]
+            self.assertEqual(np.partition(d, 6, kind=k)[6], 6)
+            self.assertEqual(np.partition(d, 16, kind=k)[16], 16)
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+
+            assert_array_equal(np.partition(d, -6, kind=k),
+                               np.partition(d, 41, kind=k))
+            assert_array_equal(np.partition(d, -16, kind=k),
+                               np.partition(d, 31, kind=k))
+            assert_array_equal(d[np.argpartition(d, -6, kind=k)],
+                               np.partition(d, 41, kind=k))
+
+            # median of 3 killer, O(n^2) on pure median 3 pivot quickselect
+            # exercises the median of median of 5 code used to keep O(n)
+            d = np.arange(1000000)
+            x = np.roll(d, d.size // 2)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+            d = np.arange(1000001)
+            x = np.roll(d, d.size // 2 + 1)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+
+            # max
+            d = np.ones(10)
+            d[1] = 4
+            assert_equal(np.partition(d, (2, -1))[-1], 4)
+            assert_equal(np.partition(d, (2, -1))[2], 1)
+            assert_equal(d[np.argpartition(d, (2, -1))][-1], 4)
+            assert_equal(d[np.argpartition(d, (2, -1))][2], 1)
+            d[1] = np.nan
+            assert_(np.isnan(d[np.argpartition(d, (2, -1))][-1]))
+            assert_(np.isnan(np.partition(d, (2, -1))[-1]))
+
+            # equal elements
+            d = np.arange(47) % 7
+            tgt = np.sort(np.arange(47) % 7)
+            np.random.shuffle(d)
+            for i in range(d.size):
+                self.assertEqual(np.partition(d, i, kind=k)[i], tgt[i])
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+            for i in range(d.size):
+                d[i:].partition(0, kind=k)
+            assert_array_equal(d, tgt)
+
+            d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                          7, 7, 7, 7, 7, 9])
+            kth = [0, 3, 19, 20]
+            assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
+            assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
+
+            d = np.array([2, 1])
+            d.partition(0, kind=k)
+            assert_raises(ValueError, d.partition, 2)
+            assert_raises(ValueError, d.partition, 3, axis=1)
+            assert_raises(ValueError, np.partition, d, 2)
+            assert_raises(ValueError, np.partition, d, 2, axis=1)
+            assert_raises(ValueError, d.argpartition, 2)
+            assert_raises(ValueError, d.argpartition, 3, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 2)
+            assert_raises(ValueError, np.argpartition, d, 2, axis=1)
+            d = np.arange(10).reshape((2, 5))
+            d.partition(1, axis=0, kind=k)
+            d.partition(4, axis=1, kind=k)
+            np.partition(d, 1, axis=0, kind=k)
+            np.partition(d, 4, axis=1, kind=k)
+            np.partition(d, 1, axis=None, kind=k)
+            np.partition(d, 9, axis=None, kind=k)
+            d.argpartition(1, axis=0, kind=k)
+            d.argpartition(4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=0, kind=k)
+            np.argpartition(d, 4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=None, kind=k)
+            np.argpartition(d, 9, axis=None, kind=k)
+            assert_raises(ValueError, d.partition, 2, axis=0)
+            assert_raises(ValueError, d.partition, 11, axis=1)
+            assert_raises(TypeError, d.partition, 2, axis=None)
+            assert_raises(ValueError, np.partition, d, 9, axis=1)
+            assert_raises(ValueError, np.partition, d, 11, axis=None)
+            assert_raises(ValueError, d.argpartition, 2, axis=0)
+            assert_raises(ValueError, d.argpartition, 11, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 9, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 11, axis=None)
+
+            td = [(dt, s) for dt in [np.int32, np.float32, np.complex64]
+                  for s in (9, 16)]
+            for dt, s in td:
+                aae = assert_array_equal
+                at = self.assertTrue
+
+                d = np.arange(s, dtype=dt)
+                np.random.shuffle(d)
+                d1 = np.tile(np.arange(s, dtype=dt), (4, 1))
+                map(np.random.shuffle, d1)
+                d0 = np.transpose(d1)
+                for i in range(d.size):
+                    p = np.partition(d, i, kind=k)
+                    self.assertEqual(p[i], i)
+                    # all before are smaller
+                    assert_array_less(p[:i], p[i])
+                    # all after are larger
+                    assert_array_less(p[i], p[i + 1:])
+                    aae(p, d[np.argpartition(d, i, kind=k)])
+
+                    p = np.partition(d1, i, axis=1, kind=k)
+                    aae(p[:, i], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:, :i].T <= p[:, i]).all(),
+                       msg="%d: %r <= %r" % (i, p[:, i], p[:, :i].T))
+                    at((p[:, i + 1:].T > p[:, i]).all(),
+                       msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T))
+                    aae(p, d1[np.arange(d1.shape[0])[:, None],
+                        np.argpartition(d1, i, axis=1, kind=k)])
+
+                    p = np.partition(d0, i, axis=0, kind=k)
+                    aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:i, :] <= p[i, :]).all(),
+                       msg="%d: %r <= %r" % (i, p[i, :], p[:i, :]))
+                    at((p[i + 1:, :] > p[i, :]).all(),
+                       msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:]))
+                    aae(p, d0[np.argpartition(d0, i, axis=0, kind=k),
+                        np.arange(d0.shape[1])[None, :]])
+
+                    # check inplace
+                    dc = d.copy()
+                    dc.partition(i, kind=k)
+                    assert_equal(dc, np.partition(d, i, kind=k))
+                    dc = d0.copy()
+                    dc.partition(i, axis=0, kind=k)
+                    assert_equal(dc, np.partition(d0, i, axis=0, kind=k))
+                    dc = d1.copy()
+                    dc.partition(i, axis=1, kind=k)
+                    assert_equal(dc, np.partition(d1, i, axis=1, kind=k))
+
+    def assert_partitioned(self, d, kth):
+        prev = 0
+        for k in np.sort(kth):
+            assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k)
+            assert_((d[k:] >= d[k]).all(),
+                    msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k]))
+            prev = k + 1
+
+    def test_partition_iterative(self):
+            d = np.arange(17)
+            kth = (0, 1, 2, 429, 231)
+            assert_raises(ValueError, d.partition, kth)
+            assert_raises(ValueError, d.argpartition, kth)
+            d = np.arange(10).reshape((2, 5))
+            assert_raises(ValueError, d.partition, kth, axis=0)
+            assert_raises(ValueError, d.partition, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=None)
+
+            d = np.array([3, 4, 2, 1])
+            p = np.partition(d, (0, 3))
+            self.assert_partitioned(p, (0, 3))
+            self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3))
+
+            assert_array_equal(p, np.partition(d, (-3, -1)))
+            assert_array_equal(p, d[np.argpartition(d, (-3, -1))])
+
+            d = np.arange(17)
+            np.random.shuffle(d)
+            d.partition(range(d.size))
+            assert_array_equal(np.arange(17), d)
+            np.random.shuffle(d)
+            assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))])
+
+            # test unsorted kth
+            d = np.arange(17)
+            np.random.shuffle(d)
+            keys = np.array([1, 3, 8, -2])
+            np.random.shuffle(d)
+            p = np.partition(d, keys)
+            self.assert_partitioned(p, keys)
+            p = d[np.argpartition(d, keys)]
+            self.assert_partitioned(p, keys)
+            np.random.shuffle(keys)
+            assert_array_equal(np.partition(d, keys), p)
+            assert_array_equal(d[np.argpartition(d, keys)], p)
+
+            # equal kth
+            d = np.arange(20)[::-1]
+            self.assert_partitioned(np.partition(d, [5]*4), [5])
+            self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]),
+                                    [5]*4 + [6, 13])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])],
+                                    [5]*4 + [6, 13])
+
+            d = np.arange(12)
+            np.random.shuffle(d)
+            d1 = np.tile(np.arange(12), (4, 1))
+            map(np.random.shuffle, d1)
+            d0 = np.transpose(d1)
+
+            kth = (1, 6, 7, -1)
+            p = np.partition(d1, kth, axis=1)
+            pa = d1[np.arange(d1.shape[0])[:, None],
+                    d1.argpartition(kth, axis=1)]
+            assert_array_equal(p, pa)
+            for i in range(d1.shape[0]):
+                self.assert_partitioned(p[i,:], kth)
+            p = np.partition(d0, kth, axis=0)
+            pa = d0[np.argpartition(d0, kth, axis=0),
+                    np.arange(d0.shape[1])[None,:]]
+            assert_array_equal(p, pa)
+            for i in range(d0.shape[1]):
+                self.assert_partitioned(p[:, i], kth)
+
+    def test_partition_cdtype(self):
+        d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+                   ('Lancelot', 1.9, 38)],
+                  dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+        tgt = np.sort(d, order=['age', 'height'])
+        assert_array_equal(np.partition(d, range(d.size),
+                                        order=['age', 'height']),
+                           tgt)
+        assert_array_equal(d[np.argpartition(d, range(d.size),
+                                             order=['age', 'height'])],
+                           tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k, order=['age', 'height'])[k],
+                        tgt[k])
+            assert_equal(d[np.argpartition(d, k, order=['age', 'height'])][k],
+                         tgt[k])
+
+        d = np.array(['Galahad', 'Arthur', 'zebra', 'Lancelot'])
+        tgt = np.sort(d)
+        assert_array_equal(np.partition(d, range(d.size)), tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k)[k], tgt[k])
+            assert_equal(d[np.argpartition(d, k)][k], tgt[k])
+
+    def test_partition_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.partition, 2, kind=k)
+        assert_raises(ValueError, d.argpartition, 2, kind=k)
+
+    def test_partition_fuzz(self):
+        # a few rounds of random data testing
+        for j in range(10, 30):
+            for i in range(1, j - 2):
+                d = np.arange(j)
+                np.random.shuffle(d)
+                d = d % np.random.randint(2, 30)
+                idx = np.random.randint(d.size)
+                kth = [0, idx, i, i + 1]
+                tgt = np.sort(d)[kth]
+                assert_array_equal(np.partition(d, kth)[kth], tgt,
+                                   err_msg="data: %r\n kth: %r" % (d, kth))
+
+    def test_argpartition_gh5524(self):
+        #  A test for functionality of argpartition on lists.
+        d = [6,7,3,2,9,0]
+        p = np.argpartition(d,1)
+        self.assert_partitioned(np.array(d)[p],[1])
+
+    def test_flatten(self):
+        x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
+        x1 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], np.int32)
+        y0 = np.array([1, 2, 3, 4, 5, 6], np.int32)
+        y0f = np.array([1, 4, 2, 5, 3, 6], np.int32)
+        y1 = np.array([1, 2, 3, 4, 5, 6, 7, 8], np.int32)
+        y1f = np.array([1, 5, 3, 7, 2, 6, 4, 8], np.int32)
+        assert_equal(x0.flatten(), y0)
+        assert_equal(x0.flatten('F'), y0f)
+        assert_equal(x0.flatten('F'), x0.T.flatten())
+        assert_equal(x1.flatten(), y1)
+        assert_equal(x1.flatten('F'), y1f)
+        assert_equal(x1.flatten('F'), x1.T.flatten())
+
+    def test_dot(self):
+        a = np.array([[1, 0], [0, 1]])
+        b = np.array([[0, 1], [1, 0]])
+        c = np.array([[9, 1], [1, -9]])
+        d = np.arange(24).reshape(4, 6)
+        ddt = np.array(
+            [[  55,  145,  235,  325],
+             [ 145,  451,  757, 1063],
+             [ 235,  757, 1279, 1801],
+             [ 325, 1063, 1801, 2539]]
+        )
+        dtd = np.array(
+            [[504, 540, 576, 612, 648, 684],
+             [540, 580, 620, 660, 700, 740],
+             [576, 620, 664, 708, 752, 796],
+             [612, 660, 708, 756, 804, 852],
+             [648, 700, 752, 804, 856, 908],
+             [684, 740, 796, 852, 908, 964]]
+        )
+
+
+        # gemm vs syrk optimizations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            assert_equal(np.dot(eaf, eaf), eaf)
+            assert_equal(np.dot(eaf.T, eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T.copy()), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf.T.copy()), eaf)
+
+        # syrk validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            ebf = b.astype(et)
+            assert_equal(np.dot(ebf, ebf), eaf)
+            assert_equal(np.dot(ebf.T, ebf), eaf)
+            assert_equal(np.dot(ebf, ebf.T), eaf)
+            assert_equal(np.dot(ebf.T, ebf.T), eaf)
+
+        # syrk - different shape, stride, and view validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            assert_equal(
+                np.dot(edf[::-1, :], edf.T),
+                np.dot(edf[::-1, :].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:, ::-1], edf.T),
+                np.dot(edf[:, ::-1].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[::-1, :].T),
+                np.dot(edf, edf[::-1, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[:, ::-1].T),
+                np.dot(edf, edf[:, ::-1].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:edf.shape[0] // 2, :], edf[::2, :].T),
+                np.dot(edf[:edf.shape[0] // 2, :].copy(), edf[::2, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[::2, :], edf[:edf.shape[0] // 2, :].T),
+                np.dot(edf[::2, :].copy(), edf[:edf.shape[0] // 2, :].T.copy())
+            )
+
+        # syrk - different shape
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            eddtf = ddt.astype(et)
+            edtdf = dtd.astype(et)
+            assert_equal(np.dot(edf, edf.T), eddtf)
+            assert_equal(np.dot(edf.T, edf), edtdf)
+
+        # function versus methods
+        assert_equal(np.dot(a, b), a.dot(b))
+        assert_equal(np.dot(np.dot(a, b), c), a.dot(b).dot(c))
+
+        # test passing in an output array
+        c = np.zeros_like(a)
+        a.dot(b, c)
+        assert_equal(c, np.dot(a, b))
+
+        # test keyword args
+        c = np.zeros_like(a)
+        a.dot(b=b, out=c)
+        assert_equal(c, np.dot(a, b))
+
+    def test_dot_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        b = B()
+        c = np.array([[1]])
+
+        assert_equal(np.dot(a, b), "A")
+        assert_equal(c.dot(a), "A")
+        assert_raises(TypeError, np.dot, b, c)
+        assert_raises(TypeError, c.dot, b)
+
+    def test_dot_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.dot, c, A)
+        assert_raises(TypeError, np.dot, A, c)
+
+    def test_diagonal(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.diagonal(), [0, 5, 10])
+        assert_equal(a.diagonal(0), [0, 5, 10])
+        assert_equal(a.diagonal(1), [1, 6, 11])
+        assert_equal(a.diagonal(-1), [4, 9])
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.diagonal(), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(0), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(1), [[2], [3]])
+        assert_equal(b.diagonal(-1), [[4], [5]])
+        assert_raises(ValueError, b.diagonal, axis1=0, axis2=0)
+        assert_equal(b.diagonal(0, 1, 2), [[0, 3], [4, 7]])
+        assert_equal(b.diagonal(0, 0, 1), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(offset=1, axis1=0, axis2=2), [[1], [3]])
+        # Order of axis argument doesn't matter:
+        assert_equal(b.diagonal(0, 2, 1), [[0, 3], [4, 7]])
+
+    def test_diagonal_view_notwriteable(self):
+        # this test is only for 1.9, the diagonal view will be
+        # writeable in 1.10.
+        a = np.eye(3).diagonal()
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diagonal(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diag(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+    def test_diagonal_memleak(self):
+        # Regression test for a bug that crept in at one point
+        a = np.zeros((100, 100))
+        assert_(sys.getrefcount(a) < 50)
+        for i in range(100):
+            a.diagonal()
+        assert_(sys.getrefcount(a) < 50)
+
+    def test_trace(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.trace(), 15)
+        assert_equal(a.trace(0), 15)
+        assert_equal(a.trace(1), 18)
+        assert_equal(a.trace(-1), 13)
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.trace(), [6, 8])
+        assert_equal(b.trace(0), [6, 8])
+        assert_equal(b.trace(1), [2, 3])
+        assert_equal(b.trace(-1), [4, 5])
+        assert_equal(b.trace(0, 0, 1), [6, 8])
+        assert_equal(b.trace(0, 0, 2), [5, 9])
+        assert_equal(b.trace(0, 1, 2), [3, 11])
+        assert_equal(b.trace(offset=1, axis1=0, axis2=2), [1, 3])
+
+    def test_trace_subclass(self):
+        # The class would need to overwrite trace to ensure single-element
+        # output also has the right subclass.
+        class MyArray(np.ndarray):
+            pass
+
+        b = np.arange(8).reshape((2, 2, 2)).view(MyArray)
+        t = b.trace()
+        assert isinstance(t, MyArray)
+
+    def test_put(self):
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+        for dt in icodes + fcodes + 'O':
+            tgt = np.array([0, 1, 0, 3, 0, 5], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt.reshape(2, 3))
+
+        for dt in '?':
+            tgt = np.array([False, True, False, True, False, True], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt.reshape(2, 3))
+
+        # check must be writeable
+        a = np.zeros(6)
+        a.flags.writeable = False
+        assert_raises(ValueError, a.put, [1, 3, 5], [1, 3, 5])
+
+        # when calling np.put, make sure a
+        # TypeError is raised if the object
+        # isn't an ndarray
+        bad_array = [1, 2, 3]
+        assert_raises(TypeError, np.put, bad_array, [0, 2], 5)
+
+    def test_ravel(self):
+        a = np.array([[0, 1], [2, 3]])
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_(not a.ravel().flags.owndata)
+        assert_equal(a.ravel('F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='C'), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='A'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_equal(a.ravel(order='K'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+
+        a = np.array([[0, 1], [2, 3]], order='F')
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='A'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='K'), [0, 2, 1, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+        assert_equal(a.ravel(order='A'), a.reshape(-1, order='A'))
+
+        a = np.array([[0, 1], [2, 3]])[::-1, :]
+        assert_equal(a.ravel(), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='C'), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='F'), [2, 0, 3, 1])
+        assert_equal(a.ravel(order='A'), [2, 3, 0, 1])
+        # 'K' doesn't reverse the axes of negative strides
+        assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
+        assert_(a.ravel(order='K').flags.owndata)
+
+        # Test simple 1-d copy behaviour:
+        a = np.arange(10)[::2]
+        assert_(a.ravel('K').flags.owndata)
+        assert_(a.ravel('C').flags.owndata)
+        assert_(a.ravel('F').flags.owndata)
+
+        # Not contiguous and 1-sized axis with non matching stride
+        a = np.arange(2**3 * 2)[::2]
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('K'), np.arange(0, 15, 2))
+
+        # contiguous and 1-sized axis with non matching stride works:
+        a = np.arange(2**3)
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(np.may_share_memory(a.ravel(order='K'), a))
+        assert_equal(a.ravel(order='K'), np.arange(2**3))
+
+        # Test negative strides (not very interesting since non-contiguous):
+        a = np.arange(4)[::-1].reshape(2, 2)
+        assert_(a.ravel(order='C').flags.owndata)
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('C'), [3, 2, 1, 0])
+        assert_equal(a.ravel('K'), [3, 2, 1, 0])
+
+        # 1-element tidy strides test (NPY_RELAXED_STRIDES_CHECKING):
+        a = np.array([[1]])
+        a.strides = (123, 432)
+        # If the stride is not 8, NPY_RELAXED_STRIDES_CHECKING is messing
+        # them up on purpose:
+        if np.ones(1).strides == (8,):
+            assert_(np.may_share_memory(a.ravel('K'), a))
+            assert_equal(a.ravel('K').strides, (a.dtype.itemsize,))
+
+        for order in ('C', 'F', 'A', 'K'):
+            # 0-d corner case:
+            a = np.array(0)
+            assert_equal(a.ravel(order), [0])
+            assert_(np.may_share_memory(a.ravel(order), a))
+
+        # Test that certain non-inplace ravels work right (mostly) for 'K':
+        b = np.arange(2**4 * 2)[::2].reshape(2, 2, 2, 2)
+        a = b[..., ::2]
+        assert_equal(a.ravel('K'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('C'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('A'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('F'), [0, 16, 8, 24, 4, 20, 12, 28])
+
+        a = b[::2, ...]
+        assert_equal(a.ravel('K'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('C'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('A'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('F'), [0, 8, 4, 12, 2, 10, 6, 14])
+
+    def test_ravel_subclass(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = np.arange(10).view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+        a = np.arange(10)[::2].view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+    def test_swapaxes(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        idx = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        b = a.copy()
+        # check exceptions
+        assert_raises(ValueError, a.swapaxes, -5, 0)
+        assert_raises(ValueError, a.swapaxes, 4, 0)
+        assert_raises(ValueError, a.swapaxes, 0, -5)
+        assert_raises(ValueError, a.swapaxes, 0, 4)
+
+        for i in range(-4, 4):
+            for j in range(-4, 4):
+                for k, src in enumerate((a, b)):
+                    c = src.swapaxes(i, j)
+                    # check shape
+                    shape = list(src.shape)
+                    shape[i] = src.shape[j]
+                    shape[j] = src.shape[i]
+                    assert_equal(c.shape, shape, str((i, j, k)))
+                    # check array contents
+                    i0, i1, i2, i3 = [dim-1 for dim in c.shape]
+                    j0, j1, j2, j3 = [dim-1 for dim in src.shape]
+                    assert_equal(src[idx[j0], idx[j1], idx[j2], idx[j3]],
+                                 c[idx[i0], idx[i1], idx[i2], idx[i3]],
+                                 str((i, j, k)))
+                    # check a view is always returned, gh-5260
+                    assert_(not c.flags['OWNDATA'], str((i, j, k)))
+                    # check on non-contiguous input array
+                    if k == 1:
+                        b = c
+
+    def test_conjugate(self):
+        a = np.array([1-1j, 1+1j, 23+23.0j])
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1, 2, 3])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1.0, 2.0, 3.0])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 1, 2.0], object)
+        ac = a.conj()
+        assert_equal(ac, [k.conjugate() for k in a])
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1, 2.0, 'f'], object)
+        assert_raises(AttributeError, lambda: a.conj())
+        assert_raises(AttributeError, lambda: a.conjugate())
+
+class TestBinop(object):
+    def test_inplace(self):
+        # test refcount 1 inplace conversion
+        assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
+                                  [0.5, 1.0])
+
+        d = np.array([0.5, 0.5])[::2]
+        assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
+                                  [0.25, 0.5])
+
+        a = np.array([0.5])
+        b = np.array([0.5])
+        c = a + b
+        c = a - b
+        c = a * b
+        c = a / b
+        assert_equal(a, b)
+        assert_almost_equal(c, 1.)
+
+        c = a + b * 2. / b * a - a / b
+        assert_equal(a, b)
+        assert_equal(c, 0.5)
+
+        # true divide
+        a = np.array([5])
+        b = np.array([3])
+        c = (a * a) / b
+
+        assert_almost_equal(c, 25 / 3)
+        assert_equal(a, 5)
+        assert_equal(b, 3)
+
+    def test_extension_incref_elide(self):
+        # test extension (e.g. cython) calling PyNumber_* slots without
+        # increasing the reference counts
+        #
+        # def incref_elide(a):
+        #    d = input.copy() # refcount 1
+        #    return d, d + d # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide
+        d = np.ones(5)
+        orig, res = incref_elide(d)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(orig, d)
+        assert_array_equal(res, d + d)
+
+    def test_extension_incref_elide_stack(self):
+        # scanning if the refcount == 1 object is on the python stack to check
+        # that we are called directly from python is flawed as object may still
+        # be above the stack pointer and we have no access to the top of it
+        #
+        # def incref_elide_l(d):
+        #    return l[4] + l[4] # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide_l
+        # padding with 1 makes sure the object on the stack is not overwriten
+        l = [1, 1, 1, 1, np.ones(5)]
+        res = incref_elide_l(l)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(l[4], np.ones(5))
+        assert_array_equal(res, l[4] + l[4])
+
+    def test_ufunc_override_rop_precedence(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that __rmul__ and other right-hand operations have
+        # precedence over __numpy_ufunc__
+
+        ops = {
+            '__add__':      ('__radd__', np.add, True),
+            '__sub__':      ('__rsub__', np.subtract, True),
+            '__mul__':      ('__rmul__', np.multiply, True),
+            '__truediv__':  ('__rtruediv__', np.true_divide, True),
+            '__floordiv__': ('__rfloordiv__', np.floor_divide, True),
+            '__mod__':      ('__rmod__', np.remainder, True),
+            '__divmod__':   ('__rdivmod__', None, False),
+            '__pow__':      ('__rpow__', np.power, True),
+            '__lshift__':   ('__rlshift__', np.left_shift, True),
+            '__rshift__':   ('__rrshift__', np.right_shift, True),
+            '__and__':      ('__rand__', np.bitwise_and, True),
+            '__xor__':      ('__rxor__', np.bitwise_xor, True),
+            '__or__':       ('__ror__', np.bitwise_or, True),
+            '__ge__':       ('__le__', np.less_equal, False),
+            '__gt__':       ('__lt__', np.less, False),
+            '__le__':       ('__ge__', np.greater_equal, False),
+            '__lt__':       ('__gt__', np.greater, False),
+            '__eq__':       ('__eq__', np.equal, False),
+            '__ne__':       ('__ne__', np.not_equal, False),
+        }
+
+        class OtherNdarraySubclass(np.ndarray):
+            pass
+
+        class OtherNdarraySubclassWithOverride(np.ndarray):
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+        def check(op_name, ndsubclass):
+            rop_name, np_op, has_iop = ops[op_name]
+
+            if has_iop:
+                iop_name = '__i' + op_name[2:]
+                iop = getattr(operator, iop_name)
+
+            if op_name == "__divmod__":
+                op = divmod
+            else:
+                op = getattr(operator, op_name)
+
+            # Dummy class
+            def __init__(self, *a, **kw):
+                pass
+
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+            def __op__(self, *other):
+                return "op"
+
+            def __rop__(self, *other):
+                return "rop"
+
+            if ndsubclass:
+                bases = (np.ndarray,)
+            else:
+                bases = (object,)
+
+            dct = {'__init__': __init__,
+                   '__numpy_ufunc__': __numpy_ufunc__,
+                   op_name: __op__}
+            if op_name != rop_name:
+                dct[rop_name] = __rop__
+
+            cls = type("Rop" + rop_name, bases, dct)
+
+            # Check behavior against both bare ndarray objects and a
+            # ndarray subclasses with and without their own override
+            obj = cls((1,), buffer=np.ones(1,))
+
+            arr_objs = [np.array([1]),
+                        np.array([2]).view(OtherNdarraySubclass),
+                        np.array([3]).view(OtherNdarraySubclassWithOverride),
+                        ]
+
+            for arr in arr_objs:
+                err_msg = "%r %r" % (op_name, arr,)
+
+                # Check that ndarray op gives up if it sees a non-subclass
+                if not isinstance(obj, arr.__class__):
+                    assert_equal(getattr(arr, op_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+
+                # Check that the Python binops have priority
+                assert_equal(op(obj, arr), "op", err_msg=err_msg)
+                if op_name == rop_name:
+                    assert_equal(op(arr, obj), "op", err_msg=err_msg)
+                else:
+                    assert_equal(op(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that Python binops have priority also for in-place ops
+                if has_iop:
+                    assert_equal(getattr(arr, iop_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+                    if op_name != "__pow__":
+                        # inplace pow requires the other object to be
+                        # integer-like?
+                        assert_equal(iop(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that ufunc call __numpy_ufunc__ normally
+                if np_op is not None:
+                    assert_raises(AssertionError, np_op, arr, obj,
+                                  err_msg=err_msg)
+                    assert_raises(AssertionError, np_op, obj, arr,
+                                  err_msg=err_msg)
+
+        # Check all binary operations
+        for op_name in sorted(ops.keys()):
+            yield check, op_name, True
+            yield check, op_name, False
+
+    def test_ufunc_override_rop_simple(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check parts of the binary op overriding behavior in an
+        # explicit test case that is easier to understand.
+        class SomeClass(object):
+            def __numpy_ufunc__(self, *a, **kw):
+                return "ufunc"
+
+            def __mul__(self, other):
+                return 123
+
+            def __rmul__(self, other):
+                return 321
+
+            def __rsub__(self, other):
+                return "no subs for me"
+
+            def __gt__(self, other):
+                return "yep"
+
+            def __lt__(self, other):
+                return "nope"
+
+        class SomeClass2(SomeClass, np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if ufunc is np.multiply or ufunc is np.bitwise_and:
+                    return "ufunc"
+                else:
+                    inputs = list(inputs)
+                    if i < len(inputs):
+                        inputs[i] = np.asarray(self)
+                    func = getattr(ufunc, method)
+                    if ('out' in kw) and (kw['out'] is not None):
+                        kw['out'] = np.asarray(kw['out'])
+                    r = func(*inputs, **kw)
+                    x = self.__class__(r.shape, dtype=r.dtype)
+                    x[...] = r
+                    return x
+
+        class SomeClass3(SomeClass2):
+            def __rsub__(self, other):
+                return "sub for me"
+
+        arr = np.array([0])
+        obj = SomeClass()
+        obj2 = SomeClass2((1,), dtype=np.int_)
+        obj2[0] = 9
+        obj3 = SomeClass3((1,), dtype=np.int_)
+        obj3[0] = 4
+
+        # obj is first, so should get to define outcome.
+        assert_equal(obj * arr, 123)
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        assert_equal(arr * obj, 321)
+        # obj is second, but has __numpy_ufunc__ and defines __rsub__.
+        assert_equal(arr - obj, "no subs for me")
+        # obj is second, but has __numpy_ufunc__ and defines __lt__.
+        assert_equal(arr > obj, "nope")
+        # obj is second, but has __numpy_ufunc__ and defines __gt__.
+        assert_equal(arr < obj, "yep")
+        # Called as a ufunc, obj.__numpy_ufunc__ is used.
+        assert_equal(np.multiply(arr, obj), "ufunc")
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        arr *= obj
+        assert_equal(arr, 321)
+
+        # obj2 is an ndarray subclass, so CPython takes care of the same rules.
+        assert_equal(obj2 * arr, 123)
+        assert_equal(arr * obj2, 321)
+        assert_equal(arr - obj2, "no subs for me")
+        assert_equal(arr > obj2, "nope")
+        assert_equal(arr < obj2, "yep")
+        # Called as a ufunc, obj2.__numpy_ufunc__ is called.
+        assert_equal(np.multiply(arr, obj2), "ufunc")
+        # Also when the method is not overridden.
+        assert_equal(arr & obj2, "ufunc")
+        arr *= obj2
+        assert_equal(arr, 321)
+
+        obj2 += 33
+        assert_equal(obj2[0], 42)
+        assert_equal(obj2.sum(), 42)
+        assert_(isinstance(obj2, SomeClass2))
+
+        # Obj3 is subclass that defines __rsub__.  CPython calls it.
+        assert_equal(arr - obj3, "sub for me")
+        assert_equal(obj2 - obj3, "sub for me")
+        # obj3 is a subclass that defines __rmul__.  CPython calls it.
+        assert_equal(arr * obj3, 321)
+        # But not here, since obj3.__rmul__ is obj2.__rmul__.
+        assert_equal(obj2 * obj3, 123)
+        # And of course, here obj3.__mul__ should be called.
+        assert_equal(obj3 * obj2, 123)
+        # obj3 defines __numpy_ufunc__ but obj3.__radd__ is obj2.__radd__.
+        # (and both are just ndarray.__radd__); see #4815.
+        res = obj2 + obj3
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass2))
+        # Since obj3 is a subclass, it should have precedence, like CPython
+        # would give, even though obj2 has __numpy_ufunc__ and __radd__.
+        # See gh-4815 and gh-5747.
+        res = obj3 + obj2
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass3))
+
+    def test_ufunc_override_normalize_signature(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # gh-5674
+        class SomeClass(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return kw
+
+        a = SomeClass()
+        kw = np.add(a, [1])
+        assert_('sig' not in kw and 'signature' not in kw)
+        kw = np.add(a, [1], sig='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+        kw = np.add(a, [1], signature='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+
+    def test_numpy_ufunc_index(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that index is set appropriately, also if only an output
+        # is passed on (latter is another regression tests for github bug 4753)
+        class CheckIndex(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return i
+
+        a = CheckIndex()
+        dummy = np.arange(2.)
+        # 1 input, 1 output
+        assert_equal(np.sin(a), 0)
+        assert_equal(np.sin(dummy, a), 1)
+        assert_equal(np.sin(dummy, out=a), 1)
+        assert_equal(np.sin(dummy, out=(a,)), 1)
+        assert_equal(np.sin(a, a), 0)
+        assert_equal(np.sin(a, out=a), 0)
+        assert_equal(np.sin(a, out=(a,)), 0)
+        # 1 input, 2 outputs
+        assert_equal(np.modf(dummy, a), 1)
+        assert_equal(np.modf(dummy, None, a), 2)
+        assert_equal(np.modf(dummy, dummy, a), 2)
+        assert_equal(np.modf(dummy, out=a), 1)
+        assert_equal(np.modf(dummy, out=(a,)), 1)
+        assert_equal(np.modf(dummy, out=(a, None)), 1)
+        assert_equal(np.modf(dummy, out=(a, dummy)), 1)
+        assert_equal(np.modf(dummy, out=(None, a)), 2)
+        assert_equal(np.modf(dummy, out=(dummy, a)), 2)
+        assert_equal(np.modf(a, out=(dummy, a)), 0)
+        # 2 inputs, 1 output
+        assert_equal(np.add(a, dummy), 0)
+        assert_equal(np.add(dummy, a), 1)
+        assert_equal(np.add(dummy, dummy, a), 2)
+        assert_equal(np.add(dummy, a, a), 1)
+        assert_equal(np.add(dummy, dummy, out=a), 2)
+        assert_equal(np.add(dummy, dummy, out=(a,)), 2)
+        assert_equal(np.add(a, dummy, out=a), 0)
+
+    def test_out_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # regression test for github bug 4753
+        class OutClass(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if 'out' in kw:
+                    tmp_kw = kw.copy()
+                    tmp_kw.pop('out')
+                    func = getattr(ufunc, method)
+                    kw['out'][...] = func(*inputs, **tmp_kw)
+
+        A = np.array([0]).view(OutClass)
+        B = np.array([5])
+        C = np.array([6])
+        np.multiply(C, B, A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+        A[0] = 0
+        np.multiply(C, B, out=A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+
+
+class TestCAPI(TestCase):
+    def test_IsPythonScalar(self):
+        from numpy.core.multiarray_tests import IsPythonScalar
+        assert_(IsPythonScalar(b'foobar'))
+        assert_(IsPythonScalar(1))
+        assert_(IsPythonScalar(2**80))
+        assert_(IsPythonScalar(2.))
+        assert_(IsPythonScalar("a"))
+
+
+class TestSubscripting(TestCase):
+    def test_test_zero_rank(self):
+        x = np.array([1, 2, 3])
+        self.assertTrue(isinstance(x[0], np.int_))
+        if sys.version_info[0] < 3:
+            self.assertTrue(isinstance(x[0], int))
+        self.assertTrue(type(x[0, ...]) is np.ndarray)
+
+
+class TestPickling(TestCase):
+    def test_roundtrip(self):
+        import pickle
+        carray = np.array([[2, 9], [7, 0], [3, 8]])
+        DATA = [
+            carray,
+            np.transpose(carray),
+            np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int),
+                                               ('c', float)])
+        ]
+
+        for a in DATA:
+            assert_equal(a, pickle.loads(a.dumps()), err_msg="%r" % a)
+
+    def _loads(self, obj):
+        if sys.version_info[0] >= 3:
+            return np.loads(obj, encoding='latin1')
+        else:
+            return np.loads(obj)
+
+    # version 0 pickles, using protocol=2 to pickle
+    # version 0 doesn't have a version field
+    def test_version0_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    # version 1 pickles, using protocol=2 to pickle
+    def test_version1_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(K\x01U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_subarray_int_shape(self):
+        s = "cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'V6'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'a'\np12\ng3\ntp13\n(dp14\ng12\n(g7\n(S'V4'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'|'\np18\n(g7\n(S'i1'\np19\nI0\nI1\ntp20\nRp21\n(I3\nS'|'\np22\nNNNI-1\nI-1\nI0\ntp23\nb(I2\nI2\ntp24\ntp25\nNNI4\nI1\nI0\ntp26\nbI0\ntp27\nsg3\n(g7\n(S'V2'\np28\nI0\nI1\ntp29\nRp30\n(I3\nS'|'\np31\n(g21\nI2\ntp32\nNNI2\nI1\nI0\ntp33\nbI4\ntp34\nsI6\nI1\nI0\ntp35\nbI00\nS'\\x01\\x01\\x01\\x01\\x01\\x02'\np36\ntp37\nb."
+        a = np.array([(1, (1, 2))], dtype=[('a', 'i1', (2, 2)), ('b', 'i1', 2)])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+
+class TestFancyIndexing(TestCase):
+    def test_list(self):
+        x = np.ones((1, 1))
+        x[:, [0]] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+
+        x = np.ones((1, 1, 1))
+        x[:, :, [0]] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_tuple(self):
+        x = np.ones((1, 1))
+        x[:, (0,)] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+        x = np.ones((1, 1, 1))
+        x[:, :, (0,)] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        assert_array_equal(x[m], np.array([2]))
+
+    def test_mask2(self):
+        x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        assert_array_equal(x[m], np.array([[5, 6, 7, 8]]))
+        assert_array_equal(x[m2], np.array([2, 5]))
+        assert_array_equal(x[m3], np.array([2]))
+
+    def test_assign_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        x[m] = 5
+        assert_array_equal(x, np.array([1, 5, 3, 4]))
+
+    def test_assign_mask2(self):
+        xorig = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        x = xorig.copy()
+        x[m] = 10
+        assert_array_equal(x, np.array([[1, 2, 3, 4], [10, 10, 10, 10]]))
+        x = xorig.copy()
+        x[m2] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [10, 6, 7, 8]]))
+        x = xorig.copy()
+        x[m3] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [5, 6, 7, 8]]))
+
+
+class TestStringCompare(TestCase):
+    def test_string(self):
+        g1 = np.array(["This", "is", "example"])
+        g2 = np.array(["This", "was", "example"])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
+
+    def test_mixed(self):
+        g1 = np.array(["spam", "spa", "spammer", "and eggs"])
+        g2 = "spam"
+        assert_array_equal(g1 == g2, [x == g2 for x in g1])
+        assert_array_equal(g1 != g2, [x != g2 for x in g1])
+        assert_array_equal(g1 < g2, [x < g2 for x in g1])
+        assert_array_equal(g1 > g2, [x > g2 for x in g1])
+        assert_array_equal(g1 <= g2, [x <= g2 for x in g1])
+        assert_array_equal(g1 >= g2, [x >= g2 for x in g1])
+
+    def test_unicode(self):
+        g1 = np.array([sixu("This"), sixu("is"), sixu("example")])
+        g2 = np.array([sixu("This"), sixu("was"), sixu("example")])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2,  [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2,  [g1[i] > g2[i] for i in [0, 1, 2]])
+
+
+class TestArgmax(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 5),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2015-11-20T12:20:59'),
+          np.datetime64('1932-09-23T10:10:13'),
+          np.datetime64('2014-10-10T03:50:30')], 3),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 4),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 0),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 3),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 0),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 1),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 2),
+
+        ([False, False, False, False, True], 4),
+        ([False, False, False, True, False], 3),
+        ([True, False, False, False, False], 0),
+        ([True, False, True, False, False], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amax = a.max(i)
+            aargmax = a.argmax(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmax(arr)], np.max(arr), err_msg="%r" % arr)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmax(-1, out=out)
+        assert_equal(out, a.argmax(-1))
+
+    def test_argmax_unicode(self):
+        d = np.zeros(6031, dtype='<U9')
+        d[5942] = "as"
+        assert_equal(d.argmax(), 5942)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmax and numpy.argmax support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.zeros(2, dtype=int)
+        assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.zeros(3, dtype=int)
+        assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmax_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmax(), 0)
+        a[3] = 10
+        assert_equal(a.argmax(), 3)
+        a[1] = 30
+        assert_equal(a.argmax(), 1)
+
+
+class TestArgmin(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 2),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 1),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 0),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2014-11-20T12:20:59'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 4),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 1),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 2),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 0),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 1),
+
+        ([True, True, True, True, False], 4),
+        ([True, True, True, False, True], 3),
+        ([False, True, True, True, True], 0),
+        ([False, True, False, True, True], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amin = a.min(i)
+            aargmin = a.argmin(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmin(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmin(arr)], np.min(arr), err_msg="%r" % arr)
+
+    def test_minimum_signed_integers(self):
+
+        a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
+        assert_equal(np.argmin(a), 1)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmin(-1, out=out)
+        assert_equal(out, a.argmin(-1))
+
+    def test_argmin_unicode(self):
+        d = np.ones(6031, dtype='<U9')
+        d[6001] = "0"
+        assert_equal(d.argmin(), 6001)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmin and numpy.argmin support out/axis args
+        a = np.random.normal(size=(2, 3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.ones(2, dtype=int)
+        assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.ones(3, dtype=int)
+        assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmin_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmin(), 0)
+        a[3] = 30
+        assert_equal(a.argmin(), 3)
+        a[1] = 10
+        assert_equal(a.argmin(), 1)
+
+
+class TestMinMax(TestCase):
+
+    def test_scalar(self):
+        assert_raises(ValueError, np.amax, 1, 1)
+        assert_raises(ValueError, np.amin, 1, 1)
+
+        assert_equal(np.amax(1, axis=0), 1)
+        assert_equal(np.amin(1, axis=0), 1)
+        assert_equal(np.amax(1, axis=None), 1)
+        assert_equal(np.amin(1, axis=None), 1)
+
+    def test_axis(self):
+        assert_raises(ValueError, np.amax, [1, 2, 3], 1000)
+        assert_equal(np.amax([[1, 2, 3]], axis=1), 3)
+
+    def test_datetime(self):
+        # NaTs are ignored
+        for dtype in ('m8[s]', 'm8[Y]'):
+            a = np.arange(10).astype(dtype)
+            a[3] = 'NaT'
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[9])
+            a[0] = 'NaT'
+            assert_equal(np.amin(a), a[1])
+            assert_equal(np.amax(a), a[9])
+            a.fill('NaT')
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[0])
+
+
+class TestNewaxis(TestCase):
+    def test_basic(self):
+        sk = np.array([0, -0.1, 0.1])
+        res = 250*sk[:, np.newaxis]
+        assert_almost_equal(res.ravel(), 250*sk)
+
+
+class TestClip(TestCase):
+    def _check_range(self, x, cmin, cmax):
+        assert_(np.all(x >= cmin))
+        assert_(np.all(x <= cmax))
+
+    def _clip_type(self, type_group, array_max,
+                   clip_min, clip_max, inplace=False,
+                   expected_min=None, expected_max=None):
+        if expected_min is None:
+            expected_min = clip_min
+        if expected_max is None:
+            expected_max = clip_max
+
+        for T in np.sctypes[type_group]:
+            if sys.byteorder == 'little':
+                byte_orders = ['=', '>']
+            else:
+                byte_orders = ['<', '=']
+
+            for byteorder in byte_orders:
+                dtype = np.dtype(T).newbyteorder(byteorder)
+
+                x = (np.random.random(1000) * array_max).astype(dtype)
+                if inplace:
+                    x.clip(clip_min, clip_max, x)
+                else:
+                    x = x.clip(clip_min, clip_max)
+                    byteorder = '='
+
+                if x.dtype.byteorder == '|':
+                    byteorder = '|'
+                assert_equal(x.dtype.byteorder, byteorder)
+                self._check_range(x, expected_min, expected_max)
+        return x
+
+    def test_basic(self):
+        for inplace in [False, True]:
+            self._clip_type(
+                'float', 1024, -12.8, 100.2, inplace=inplace)
+            self._clip_type(
+                'float', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'int', 1024, -120, 100.5, inplace=inplace)
+            self._clip_type(
+                'int', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'uint', 1024, 0, 0, inplace=inplace)
+            self._clip_type(
+                'uint', 1024, -120, 100, inplace=inplace, expected_min=0)
+
+    def test_record_array(self):
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                       dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
+        y = rec['x'].clip(-0.3, 0.5)
+        self._check_range(y, -0.3, 0.5)
+
+    def test_max_or_min(self):
+        val = np.array([0, 1, 2, 3, 4, 5, 6, 7])
+        x = val.clip(3)
+        assert_(np.all(x >= 3))
+        x = val.clip(min=3)
+        assert_(np.all(x >= 3))
+        x = val.clip(max=4)
+        assert_(np.all(x <= 4))
+
+
+class TestCompress(TestCase):
+    def test_axis(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = np.compress([0, 1, 0, 1, 0], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_truncate(self):
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_flatten(self):
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr)
+        assert_equal(out, 1)
+
+
+class TestPutmask(object):
+    def tst_basic(self, x, T, mask, val):
+        np.putmask(x, mask, val)
+        assert_(np.all(x[mask] == T(val)))
+        assert_(x.dtype == T)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(1000)*100
+        mask = x < 40
+
+        for val in [-100, 0, 15]:
+            for types in np.sctypes.values():
+                for T in types:
+                    if T not in unchecked_types:
+                        yield self.tst_basic, x.copy().astype(T), T, mask, val
+
+    def test_mask_size(self):
+        assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5)
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        np.putmask(x, [True, False, True], -1)
+        assert_array_equal(x, [-1, 2, -1])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        np.putmask(rec['x'], [True, False], 10)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [2, 4])
+        assert_array_equal(rec['z'], [3, 3])
+        np.putmask(rec['y'], [True, False], 11)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [11, 4])
+        assert_array_equal(rec['z'], [3, 3])
+
+
+class TestTake(object):
+    def tst_basic(self, x):
+        ind = list(range(x.shape[0]))
+        assert_array_equal(x.take(ind, axis=0), x)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        for types in np.sctypes.values():
+            for T in types:
+                if T not in unchecked_types:
+                    yield self.tst_basic, x.copy().astype(T)
+
+    def test_raise(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_raises(IndexError, x.take, [0, 1, 2], axis=0)
+        assert_raises(IndexError, x.take, [-3], axis=0)
+        assert_array_equal(x.take([-1], axis=0)[0], x[1])
+
+    def test_clip(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='clip')[0], x[0])
+        assert_array_equal(x.take([2], axis=0, mode='clip')[0], x[1])
+
+    def test_wrap(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='wrap')[0], x[1])
+        assert_array_equal(x.take([2], axis=0, mode='wrap')[0], x[0])
+        assert_array_equal(x.take([3], axis=0, mode='wrap')[0], x[1])
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        assert_array_equal(x.take([0, 2, 1]), [1, 3, 2])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        rec1 = rec.take([1])
+        assert_(rec1['x'] == 5.0 and rec1['y'] == 4.0)
+
+
+class TestLexsort(TestCase):
+    def test_basic(self):
+        a = [1, 2, 1, 3, 1, 5]
+        b = [0, 4, 5, 6, 2, 3]
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([0, 4, 2, 1, 3, 5])
+        assert_array_equal(idx, expected_idx)
+
+        x = np.vstack((b, a))
+        idx = np.lexsort(x)
+        assert_array_equal(idx, expected_idx)
+
+        assert_array_equal(x[1][idx], np.sort(x[1]))
+
+    def test_datetime(self):
+        a = np.array([0,0,0], dtype='datetime64[D]')
+        b = np.array([2,1,0], dtype='datetime64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+        a = np.array([0,0,0], dtype='timedelta64[D]')
+        b = np.array([2,1,0], dtype='timedelta64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+    def test_object(self):  # gh-6312
+        a = np.random.choice(10, 1000)
+        b = np.random.choice(['abc', 'xy', 'wz', 'efghi', 'qwst', 'x'], 1000)
+
+        for u in a, b:
+            left = np.lexsort((u.astype('O'),))
+            right = np.argsort(u, kind='mergesort')
+            assert_array_equal(left, right)
+
+        for u, v in (a, b), (b, a):
+            idx = np.lexsort((u, v))
+            assert_array_equal(idx, np.lexsort((u.astype('O'), v)))
+            assert_array_equal(idx, np.lexsort((u, v.astype('O'))))
+            u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
+            assert_array_equal(idx, np.lexsort((u, v)))
+
+
+class TestIO(object):
+    """Test tofile, fromfile, tobytes, and fromstring"""
+
+    def setUp(self):
+        shape = (2, 4, 3)
+        rand = np.random.random
+        self.x = rand(shape) + rand(shape).astype(np.complex)*1j
+        self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
+        self.dtype = self.x.dtype
+        self.tempdir = tempfile.mkdtemp()
+        self.filename = tempfile.mktemp(dir=self.tempdir)
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def test_nofile(self):
+        # this should probably be supported as a file
+        # but for now test for proper errors
+        b = io.BytesIO()
+        assert_raises(IOError, np.fromfile, b, np.uint8, 80)
+        d = np.ones(7);
+        assert_raises(IOError, lambda x: x.tofile(b), d)
+
+    def test_bool_fromstring(self):
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        y = np.fromstring('1 0 -2.3 0.0', sep=' ', dtype=np.bool_)
+        assert_array_equal(v, y)
+
+    def test_uint64_fromstring(self):
+        d = np.fromstring("9923372036854775807 104783749223640",
+                          dtype=np.uint64, sep=' ')
+        e = np.array([9923372036854775807, 104783749223640], dtype=np.uint64)
+        assert_array_equal(d, e)
+
+    def test_int64_fromstring(self):
+        d = np.fromstring("-25041670086757 104783749223640",
+                          dtype=np.int64, sep=' ')
+        e = np.array([-25041670086757, 104783749223640], dtype=np.int64)
+        assert_array_equal(d, e)
+
+    def test_empty_files_binary(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename)
+        assert_(y.size == 0, "Array not empty")
+
+    def test_empty_files_text(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename, sep=" ")
+        assert_(y.size == 0, "Array not empty")
+
+    def test_roundtrip_file(self):
+        f = open(self.filename, 'wb')
+        self.x.tofile(f)
+        f.close()
+        # NB. doesn't work with flush+seek, due to use of C stdio
+        f = open(self.filename, 'rb')
+        y = np.fromfile(f, dtype=self.dtype)
+        f.close()
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_filename(self):
+        self.x.tofile(self.filename)
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_binary_str(self):
+        s = self.x.tobytes()
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+        s = self.x.tobytes('F')
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flatten('F'))
+
+    def test_roundtrip_str(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(str, x))
+        y = np.fromstring(s, sep="@")
+        # NB. str imbues less precision
+        nan_mask = ~np.isfinite(x)
+        assert_array_equal(x[nan_mask], y[nan_mask])
+        assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
+
+    def test_roundtrip_repr(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(repr, x))
+        y = np.fromstring(s, sep="@")
+        assert_array_equal(x, y)
+
+    def test_unbuffered_fromfile(self):
+        # gh-6246
+        self.x.tofile(self.filename)
+
+        def fail(*args, **kwargs):
+            raise io.IOError('Can not tell or seek')
+
+        f = io.open(self.filename, 'rb', buffering=0)
+        f.seek = fail
+        f.tell = fail
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_largish_file(self):
+        # check the fallocate path on files > 16MB
+        d = np.zeros(4 * 1024 ** 2)
+        d.tofile(self.filename)
+        assert_equal(os.path.getsize(self.filename), d.nbytes)
+        assert_array_equal(d, np.fromfile(self.filename));
+        # check offset
+        with open(self.filename, "r+b") as f:
+            f.seek(d.nbytes)
+            d.tofile(f)
+            assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+
+    def test_file_position_after_fromfile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.close()
+
+            for mode in ['rb', 'r+b']:
+                err_msg = "%d %s" % (size, mode)
+
+                f = open(self.filename, mode)
+                f.read(2)
+                np.fromfile(f, dtype=np.float64, count=1)
+                pos = f.tell()
+                f.close()
+                assert_equal(pos, 10, err_msg=err_msg)
+
+    def test_file_position_after_tofile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            err_msg = "%d" % (size,)
+
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.seek(10)
+            f.write(b'12')
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
+
+            f = open(self.filename, 'r+b')
+            f.read(2)
+            f.seek(0, 1)  # seek between read&write required by ANSI C
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10, err_msg=err_msg)
+
+    def _check_from(self, s, value, **kw):
+        y = np.fromstring(asbytes(s), **kw)
+        assert_array_equal(y, value)
+
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, **kw)
+        assert_array_equal(y, value)
+
+    def test_nan(self):
+        self._check_from(
+            "nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
+            [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
+            sep=' ')
+
+    def test_inf(self):
+        self._check_from(
+            "inf +inf -inf infinity -Infinity iNfInItY -inF",
+            [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
+            sep=' ')
+
+    def test_numbers(self):
+        self._check_from("1.234 -1.234 .3 .3e55 -123133.1231e+133",
+                         [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+
+    def test_binary(self):
+        self._check_from('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+                         np.array([1, 2, 3, 4]),
+                         dtype='<f4')
+
+    @dec.slow  # takes > 1 minute on mechanical hard drive
+    def test_big_binary(self):
+        """Test workarounds for 32-bit limited fwrite, fseek, and ftell
+        calls in windows. These normally would hang doing something like this.
+        See http://projects.scipy.org/numpy/ticket/1660"""
+        if sys.platform != 'win32' or "MSYSTEM" in os.environ:
+            return
+        try:
+            # before workarounds, only up to 2**32-1 worked
+            fourgbplus = 2**32 + 2**16
+            testbytes = np.arange(8, dtype=np.int8)
+            n = len(testbytes)
+            flike = tempfile.NamedTemporaryFile()
+            f = flike.file
+            np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
+            flike.seek(0)
+            a = np.fromfile(f, dtype=np.int8)
+            flike.close()
+            assert_(len(a) == fourgbplus)
+            # check only start and end for speed:
+            assert_((a[:n] == testbytes).all())
+            assert_((a[-n:] == testbytes).all())
+        except (MemoryError, ValueError):
+            pass
+
+    def test_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], sep=',')
+
+    def test_counted_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3.], count=3, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+
+    def test_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3, 4], dtype=int, sep=' ')
+
+    def test_counted_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3], count=3, dtype=int,
+                         sep=' ')
+
+    def test_ascii(self):
+        self._check_from('1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
+
+    def test_malformed(self):
+        self._check_from('1.234 1,234', [1.234, 1.], sep=' ')
+
+    def test_long_sep(self):
+        self._check_from('1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
+
+    def test_dtype(self):
+        v = np.array([1, 2, 3, 4], dtype=np.int_)
+        self._check_from('1,2,3,4', v, sep=',', dtype=np.int_)
+
+    def test_dtype_bool(self):
+        # can't use _check_from because fromstring can't handle True/False
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        s = '1,0,-2.3,0'
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
+        assert_(y.dtype == '?')
+        assert_array_equal(y, v)
+
+    def test_tofile_sep(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        #assert_equal(s, '1.51,2.0,3.51,4.0')
+        y = np.array([float(p) for p in s.split(',')])
+        assert_array_equal(x,y)
+
+    def test_tofile_format(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',', format='%.2f')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.00,3.51,4.00')
+
+    def test_locale(self):
+        in_foreign_locale(self.test_numbers)()
+        in_foreign_locale(self.test_nan)()
+        in_foreign_locale(self.test_inf)()
+        in_foreign_locale(self.test_counted_string)()
+        in_foreign_locale(self.test_ascii)()
+        in_foreign_locale(self.test_malformed)()
+        in_foreign_locale(self.test_tofile_sep)()
+        in_foreign_locale(self.test_tofile_format)()
+
+
+class TestFromBuffer(object):
+    def tst_basic(self, buffer, expected, kwargs):
+        assert_array_equal(np.frombuffer(buffer,**kwargs), expected)
+
+    def test_ip_basic(self):
+        for byteorder in ['<', '>']:
+            for dtype in [float, int, np.complex]:
+                dt = np.dtype(dtype).newbyteorder(byteorder)
+                x = (np.random.random((4, 7))*5).astype(dt)
+                buf = x.tobytes()
+                yield self.tst_basic, buf, x.flat, {'dtype':dt}
+
+    def test_empty(self):
+        yield self.tst_basic, asbytes(''), np.array([]), {}
+
+
+class TestFlat(TestCase):
+    def setUp(self):
+        a0 = np.arange(20.0)
+        a = a0.reshape(4, 5)
+        a0.shape = (4, 5)
+        a.flags.writeable = False
+        self.a = a
+        self.b = a[::2, ::2]
+        self.a0 = a0
+        self.b0 = a0[::2, ::2]
+
+    def test_contiguous(self):
+        testpassed = False
+        try:
+            self.a.flat[12] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.a.flat[12] == 12.0)
+
+    def test_discontiguous(self):
+        testpassed = False
+        try:
+            self.b.flat[4] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.b.flat[4] == 12.0)
+
+    def test___array__(self):
+        c = self.a.flat.__array__()
+        d = self.b.flat.__array__()
+        e = self.a0.flat.__array__()
+        f = self.b0.flat.__array__()
+
+        assert_(c.flags.writeable is False)
+        assert_(d.flags.writeable is False)
+        assert_(e.flags.writeable is True)
+        assert_(f.flags.writeable is True)
+
+        assert_(c.flags.updateifcopy is False)
+        assert_(d.flags.updateifcopy is False)
+        assert_(e.flags.updateifcopy is False)
+        assert_(f.flags.updateifcopy is True)
+        assert_(f.base is self.b0)
+
+
+class TestResize(TestCase):
+    def test_basic(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        x.resize((5, 5))
+        assert_array_equal(x.flat[:9],
+                np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat)
+        assert_array_equal(x[9:].flat, 0)
+
+    def test_check_reference(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        y = x
+        self.assertRaises(ValueError, x.resize, (5, 1))
+        del y  # avoid pyflakes unused variable warning.
+
+    def test_int_shape(self):
+        x = np.eye(3)
+        x.resize(3)
+        assert_array_equal(x, np.eye(3)[0,:])
+
+    def test_none_shape(self):
+        x = np.eye(3)
+        x.resize(None)
+        assert_array_equal(x, np.eye(3))
+        x.resize()
+        assert_array_equal(x, np.eye(3))
+
+    def test_invalid_arguements(self):
+        self.assertRaises(TypeError, np.eye(3).resize, 'hi')
+        self.assertRaises(ValueError, np.eye(3).resize, -1)
+        self.assertRaises(TypeError, np.eye(3).resize, order=1)
+        self.assertRaises(TypeError, np.eye(3).resize, refcheck='hi')
+
+    def test_freeform_shape(self):
+        x = np.eye(3)
+        x.resize(3, 2, 1)
+        assert_(x.shape == (3, 2, 1))
+
+    def test_zeros_appended(self):
+        x = np.eye(3)
+        x.resize(2, 3, 3)
+        assert_array_equal(x[0], np.eye(3))
+        assert_array_equal(x[1], np.zeros((3, 3)))
+
+    def test_obj_obj(self):
+        # check memory is initialized on resize, gh-4857
+        a = np.ones(10, dtype=[('k', object, 2)])
+        a.resize(15,)
+        assert_equal(a.shape, (15,))
+        assert_array_equal(a['k'][-5:], 0)
+        assert_array_equal(a['k'][:-5], 1)
+
+
+class TestRecord(TestCase):
+    def test_field_rename(self):
+        dt = np.dtype([('f', float), ('i', int)])
+        dt.names = ['p', 'q']
+        assert_equal(dt.names, ['p', 'q'])
+
+    def test_multiple_field_name_occurrence(self):
+        def test_assign():
+            dtype = np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")])
+
+        # Error raised when multiple fields have the same name
+        assert_raises(ValueError, test_assign)
+
+    if sys.version_info[0] >= 3:
+        def test_bytes_fields(self):
+            # Bytes are not allowed in field names and not recognized in titles
+            # on Py3
+            assert_raises(TypeError, np.dtype, [(asbytes('a'), int)])
+            assert_raises(TypeError, np.dtype, [(('b', asbytes('a')), int)])
+
+            dt = np.dtype([((asbytes('a'), 'b'), int)])
+            assert_raises(ValueError, dt.__getitem__, asbytes('a'))
+
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            assert_raises(IndexError, x.__getitem__, asbytes('a'))
+
+            y = x[0]
+            assert_raises(IndexError, y.__getitem__, asbytes('a'))
+
+        def test_multiple_field_name_unicode(self):
+            def test_assign_unicode():
+                dt = np.dtype([("\u20B9", "f8"),
+                               ("B", "f8"),
+                               ("\u20B9", "f8")])
+
+            # Error raised when multiple fields have the same name(unicode included)
+            assert_raises(ValueError, test_assign_unicode)
+
+    else:
+        def test_unicode_field_titles(self):
+            # Unicode field titles are added to field dict on Py2
+            title = unicode('b')
+            dt = np.dtype([((title, 'a'), int)])
+            dt[title]
+            dt['a']
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            x[title]
+            x['a']
+            y = x[0]
+            y[title]
+            y['a']
+
+        def test_unicode_field_names(self):
+            # Unicode field names are not allowed on Py2
+            title = unicode('b')
+            assert_raises(TypeError, np.dtype, [(title, int)])
+            assert_raises(TypeError, np.dtype, [(('a', title), int)])
+
+    def test_field_names(self):
+        # Test unicode and 8-bit / byte strings can be used
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        is_py3 = sys.version_info[0] >= 3
+        if is_py3:
+            funcs = (str,)
+            # byte string indexing fails gracefully
+            assert_raises(IndexError, a.__setitem__, asbytes('f1'), 1)
+            assert_raises(IndexError, a.__getitem__, asbytes('f1'))
+            assert_raises(IndexError, a['f1'].__setitem__, asbytes('sf1'), 1)
+            assert_raises(IndexError, a['f1'].__getitem__, asbytes('sf1'))
+        else:
+            funcs = (str, unicode)
+        for func in funcs:
+            b = a.copy()
+            fn1 = func('f1')
+            b[fn1] = 1
+            assert_equal(b[fn1], 1)
+            fnn = func('not at all')
+            assert_raises(ValueError, b.__setitem__, fnn, 1)
+            assert_raises(ValueError, b.__getitem__, fnn)
+            b[0][fn1] = 2
+            assert_equal(b[fn1], 2)
+            # Subfield
+            assert_raises(ValueError, b[0].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[0].__getitem__, fnn)
+            # Subfield
+            fn3 = func('f3')
+            sfn1 = func('sf1')
+            b[fn3][sfn1] = 1
+            assert_equal(b[fn3][sfn1], 1)
+            assert_raises(ValueError, b[fn3].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[fn3].__getitem__, fnn)
+            # multiple subfields
+            fn2 = func('f2')
+            b[fn2] = 3
+            assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2))
+            assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,)))
+            # view of subfield view/copy
+            assert_equal(b[['f1', 'f2']][0].view(('i4', 2)).tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].view(('i4', 2)).tolist(), (3, 2))
+            view_dtype = [('f1', 'i4'), ('f3', [('', 'i4')])]
+            assert_equal(b[['f1', 'f3']][0].view(view_dtype).tolist(), (2, (1,)))
+        # non-ascii unicode field indexing is well behaved
+        if not is_py3:
+            raise SkipTest('non ascii unicode field indexing skipped; '
+                           'raises segfault on python 2.x')
+        else:
+            assert_raises(ValueError, a.__setitem__, sixu('\u03e0'), 1)
+            assert_raises(ValueError, a.__getitem__, sixu('\u03e0'))
+
+    def test_field_names_deprecation(self):
+
+        def collect_warnings(f, *args, **kwargs):
+            with warnings.catch_warnings(record=True) as log:
+                warnings.simplefilter("always")
+                f(*args, **kwargs)
+            return [w.category for w in log]
+
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        a['f1'][0] = 1
+        a['f2'][0] = 2
+        a['f3'][0] = (3,)
+        b = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        b['f1'][0] = 1
+        b['f2'][0] = 2
+        b['f3'][0] = (3,)
+
+        # All the different functions raise a warning, but not an error, and
+        # 'a' is not modified:
+        assert_equal(collect_warnings(a[['f1', 'f2']].__setitem__, 0, (10, 20)),
+                     [FutureWarning])
+        assert_equal(a, b)
+        # Views also warn
+        subset = a[['f1', 'f2']]
+        subset_view = subset.view()
+        assert_equal(collect_warnings(subset_view['f1'].__setitem__, 0, 10),
+                     [FutureWarning])
+        # But the write goes through:
+        assert_equal(subset['f1'][0], 10)
+        # Only one warning per multiple field indexing, though (even if there
+        # are multiple views involved):
+        assert_equal(collect_warnings(subset['f1'].__setitem__, 0, 10), [])
+
+    def test_record_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        a.flags.writeable = False
+        b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')])
+        b.flags.writeable = False
+        c = np.array([(1, 2), (3, 4)], dtype='i1,i2')
+        c.flags.writeable = False
+        self.assertTrue(hash(a[0]) == hash(a[1]))
+        self.assertTrue(hash(a[0]) == hash(b[0]))
+        self.assertTrue(hash(a[0]) != hash(b[1]))
+        self.assertTrue(hash(c[0]) == hash(a[0]) and c[0] == a[0])
+
+    def test_record_no_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        self.assertRaises(TypeError, hash, a[0])
+
+    def test_empty_structure_creation(self):
+        # make sure these do not raise errors (gh-5631)
+        np.array([()], dtype={'names': [], 'formats': [],
+                           'offsets': [], 'itemsize': 12})
+        np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [],
+                                           'offsets': [], 'itemsize': 12})
+
+class TestView(TestCase):
+    def test_basic(self):
+        x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)],
+                     dtype=[('r', np.int8), ('g', np.int8),
+                            ('b', np.int8), ('a', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i4')
+        # ... and again without the keyword.
+        z = x.view('<i4')
+        assert_array_equal(y, z)
+        assert_array_equal(y, [67305985, 134678021])
+
+
+def _mean(a, **args):
+    return a.mean(**args)
+
+
+def _var(a, **args):
+    return a.var(**args)
+
+
+def _std(a, **args):
+    return a.std(**args)
+
+
+class TestStats(TestCase):
+
+    funcs = [_mean, _var, _std]
+
+    def setUp(self):
+        np.random.seed(range(3))
+        self.rmat = np.random.random((4, 5))
+        self.cmat = self.rmat + 1j * self.rmat
+        self.omat = np.array([Decimal(repr(r)) for r in self.rmat.flat])
+        self.omat = self.omat.reshape(4, 5)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            for axis in [0, 1]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == mat.ndim)
+                assert_(res.shape[axis] == 1)
+            for axis in [None]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.shape == (1, 1))
+
+    def test_out(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            out = np.zeros(3)
+            tgt = f(mat, axis=1)
+            res = f(mat, axis=1, out=out)
+            assert_almost_equal(res, out)
+            assert_almost_equal(res, tgt)
+        out = np.empty(2)
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+        out = np.empty((2, 2))
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+
+    def test_dtype_from_input(self):
+
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+
+        # object type
+        for f in self.funcs:
+            mat = np.array([[Decimal(1)]*3]*3)
+            tgt = mat.dtype.type
+            res = f(mat, axis=1).dtype.type
+            assert_(res is tgt)
+            # scalar case
+            res = type(f(mat, axis=None))
+            assert_(res is Decimal)
+
+        # integer types
+        for f in self.funcs:
+            for c in icodes:
+                mat = np.eye(3, dtype=c)
+                tgt = np.float64
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # mean for float types
+        for f in [_mean]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                tgt = mat.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # var, std for float types
+        for f in [_var, _std]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                # deal with complex types
+                tgt = mat.real.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+
+        # stats for integer types
+        # FIXME:
+        # this needs definition as there are lots places along the line
+        # where type casting may take place.
+
+        # for f in self.funcs:
+        #    for c in np.typecodes['AllInteger']:
+        #        tgt = np.dtype(c).type
+        #        res = f(mat, axis=1, dtype=c).dtype.type
+        #        assert_(res is tgt)
+        #        # scalar case
+        #        res = f(mat, axis=None, dtype=c).dtype.type
+        #        assert_(res is tgt)
+
+        # stats for float types
+        for f in self.funcs:
+            for c in np.typecodes['AllFloat']:
+                tgt = np.dtype(c).type
+                res = f(mat, axis=1, dtype=c).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None, dtype=c).dtype.type
+                assert_(res is tgt)
+
+    def test_ddof(self):
+        for f in [_var]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * dim
+                res = f(self.rmat, axis=1, ddof=ddof) * (dim - ddof)
+        for f in [_std]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * np.sqrt(dim)
+                res = f(self.rmat, axis=1, ddof=ddof) * np.sqrt(dim - ddof)
+                assert_almost_equal(res, tgt)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        dim = self.rmat.shape[1]
+        for f in [_var, _std]:
+            for ddof in range(dim, dim + 2):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    res = f(self.rmat, axis=1, ddof=ddof)
+                    assert_(not (res < 0).any())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        A = np.zeros((0, 3))
+        for f in self.funcs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(A, axis=axis)).all())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(A, axis=axis), np.zeros([]))
+
+    def test_mean_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * mat.shape[axis]
+                assert_almost_equal(res, tgt)
+            for axis in [None]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * np.prod(mat.shape)
+                assert_almost_equal(res, tgt)
+
+    def test_var_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                msqr = _mean(mat * mat.conj(), axis=axis)
+                mean = _mean(mat, axis=axis)
+                tgt = msqr - mean * mean.conjugate()
+                res = _var(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_std_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                tgt = np.sqrt(_var(mat, axis=axis))
+                res = _std(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_subclass(self):
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, "info", '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        res = dat.mean(1)
+        assert_(res.info == dat.info)
+        res = dat.std(1)
+        assert_(res.info == dat.info)
+        res = dat.var(1)
+        assert_(res.info == dat.info)
+
+class TestVdot(TestCase):
+    def test_basic(self):
+        dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
+        dt_complex = np.typecodes['Complex']
+
+        # test real
+        a = np.eye(3)
+        for dt in dt_numeric + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test complex
+        a = np.eye(3) * 1j
+        for dt in dt_complex + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test boolean
+        b = np.eye(3, dtype=np.bool)
+        res = np.vdot(b, b)
+        assert_(np.isscalar(res))
+        assert_equal(np.vdot(b, b), True)
+
+    def test_vdot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.vdot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.vdot(a, b), res)
+        assert_equal(np.vdot(b, a), res)
+        assert_equal(np.vdot(b, b), res)
+
+    def test_vdot_uncontiguous(self):
+        for size in [2, 1000]:
+            # Different sizes match different branches in vdot.
+            a = np.zeros((size, 2, 2))
+            b = np.zeros((size, 2, 2))
+            a[:, 0, 0] = np.arange(size)
+            b[:, 0, 0] = np.arange(size) + 1
+            # Make a and b uncontiguous:
+            a = a[..., 0]
+            b = b[..., 0]
+
+            assert_equal(np.vdot(a, b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy()),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy(), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy('F'), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy('F')),
+                         np.vdot(a.flatten(), b.flatten()))
+
+
+class TestDot(TestCase):
+    def setUp(self):
+        np.random.seed(128)
+        self.A = np.random.rand(4, 2)
+        self.b1 = np.random.rand(2, 1)
+        self.b2 = np.random.rand(2)
+        self.b3 = np.random.rand(1, 2)
+        self.b4 = np.random.rand(4)
+        self.N = 7
+
+    def test_dotmatmat(self):
+        A = self.A
+        res = np.dot(A.transpose(), A)
+        tgt = np.array([[1.45046013, 0.86323640],
+                        [0.86323640, 0.84934569]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec(self):
+        A, b1 = self.A, self.b1
+        res = np.dot(A, b1)
+        tgt = np.array([[0.32114320], [0.04889721],
+                        [0.15696029], [0.33612621]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec2(self):
+        A, b2 = self.A, self.b2
+        res = np.dot(A, b2)
+        tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(b4, A)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat2(self):
+        b3, A = self.b3, self.A
+        res = np.dot(b3, A.transpose())
+        tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat3(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(A.transpose(), b4)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecouter(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b1, b3)
+        tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecinner(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b3, b1)
+        tgt = np.array([[ 0.23129668]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect1(self):
+        b1 = np.ones((3, 1))
+        b2 = [5.3]
+        res = np.dot(b1, b2)
+        tgt = np.array([5.3, 5.3, 5.3])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect2(self):
+        b1 = np.ones((3, 1)).transpose()
+        b2 = [6.2]
+        res = np.dot(b2, b1)
+        tgt = np.array([6.2, 6.2, 6.2])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar(self):
+        np.random.seed(100)
+        b1 = np.random.rand(1, 1)
+        b2 = np.random.rand(1, 4)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar2(self):
+        np.random.seed(100)
+        b1 = np.random.rand(4, 1)
+        b2 = np.random.rand(1, 1)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_all(self):
+        dims = [(), (1,), (1, 1)]
+        dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)]
+        for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)):
+            b1 = np.zeros(dim1)
+            b2 = np.zeros(dim2)
+            res = np.dot(b1, b2)
+            tgt = np.zeros(dim)
+            assert_(res.shape == tgt.shape)
+            assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_vecobject(self):
+        class Vec(object):
+            def __init__(self, sequence=None):
+                if sequence is None:
+                    sequence = []
+                self.array = np.array(sequence)
+
+            def __add__(self, other):
+                out = Vec()
+                out.array = self.array + other.array
+                return out
+
+            def __sub__(self, other):
+                out = Vec()
+                out.array = self.array - other.array
+                return out
+
+            def __mul__(self, other):  # with scalar
+                out = Vec(self.array.copy())
+                out.array *= other
+                return out
+
+            def __rmul__(self, other):
+                return self*other
+
+        U_non_cont = np.transpose([[1., 1.], [1., 2.]])
+        U_cont = np.ascontiguousarray(U_non_cont)
+        x = np.array([Vec([1., 0.]), Vec([0., 1.])])
+        zeros = np.array([Vec([0., 0.]), Vec([0., 0.])])
+        zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x)
+        assert_equal(zeros[0].array, zeros_test[0].array)
+        assert_equal(zeros[1].array, zeros_test[1].array)
+
+    def test_dot_2args(self):
+        from numpy.core.multiarray import dot
+
+        a = np.array([[1, 2], [3, 4]], dtype=float)
+        b = np.array([[1, 0], [1, 1]], dtype=float)
+        c = np.array([[3, 2], [7, 4]], dtype=float)
+
+        d = dot(a, b)
+        assert_allclose(c, d)
+
+    def test_dot_3args(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 32))
+        for i in range(12):
+            dot(f, v, r)
+        assert_equal(sys.getrefcount(r), 2)
+        r2 = dot(f, v, out=None)
+        assert_array_equal(r2, r)
+        assert_(r is dot(f, v, out=r))
+
+        v = v[:, 0].copy()  # v.shape == (16,)
+        r = r[:, 0].copy()  # r.shape == (1024,)
+        r2 = dot(f, v)
+        assert_(r is dot(f, v, r))
+        assert_array_equal(r2, r)
+
+    def test_dot_3args_errors(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 31))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32, 1024))
+        assert_raises(ValueError, dot, f, v, r)
+        assert_raises(ValueError, dot, f, v, r.T)
+
+        r = np.empty((1024, 64))
+        assert_raises(ValueError, dot, f, v, r[:, ::2])
+        assert_raises(ValueError, dot, f, v, r[:, :32])
+
+        r = np.empty((1024, 32), dtype=np.float32)
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024, 32), dtype=int)
+        assert_raises(ValueError, dot, f, v, r)
+
+    def test_dot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.dot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.dot(a, b), res)
+        assert_equal(np.dot(b, a), res)
+        assert_equal(np.dot(b, b), res)
+
+    def test_dot_scalar_and_matrix_of_objects(self):
+        # Ticket #2469
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.dot(arr, 3), desired)
+        assert_equal(np.dot(3, arr), desired)
+
+    def test_accelerate_framework_sgemv_fix(self):
+
+        def aligned_array(shape, align, dtype, order='C'):
+            d = dtype(0)
+            N = np.prod(shape)
+            tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
+            address = tmp.__array_interface__["data"][0]
+            for offset in range(align):
+                if (address + offset) % align == 0:
+                    break
+            tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
+            return tmp.reshape(shape, order=order)
+
+        def as_aligned(arr, align, dtype, order='C'):
+            aligned = aligned_array(arr.shape, align, dtype, order)
+            aligned[:] = arr[:]
+            return aligned
+
+        def assert_dot_close(A, X, desired):
+            assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
+
+        m = aligned_array(100, 15, np.float32)
+        s = aligned_array((100, 100), 15, np.float32)
+        np.dot(s, m)  # this will always segfault if the bug is present
+
+        testdata = itertools.product((15,32), (10000,), (200,89), ('C','F'))
+        for align, m, n, a_order in testdata:
+            # Calculation in double precision
+            A_d = np.random.rand(m, n)
+            X_d = np.random.rand(n)
+            desired = np.dot(A_d, X_d)
+            # Calculation with aligned single precision
+            A_f = as_aligned(A_d, align, np.float32, order=a_order)
+            X_f = as_aligned(X_d, align, np.float32)
+            assert_dot_close(A_f, X_f, desired)
+            # Strided A rows
+            A_d_2 = A_d[::2]
+            desired = np.dot(A_d_2, X_d)
+            A_f_2 = A_f[::2]
+            assert_dot_close(A_f_2, X_f, desired)
+            # Strided A columns, strided X vector
+            A_d_22 = A_d_2[:, ::2]
+            X_d_2 = X_d[::2]
+            desired = np.dot(A_d_22, X_d_2)
+            A_f_22 = A_f_2[:, ::2]
+            X_f_2 = X_f[::2]
+            assert_dot_close(A_f_22, X_f_2, desired)
+            # Check the strides are as expected
+            if a_order == 'F':
+                assert_equal(A_f_22.strides, (8, 8 * m))
+            else:
+                assert_equal(A_f_22.strides, (8 * n, 8))
+            assert_equal(X_f_2.strides, (8,))
+            # Strides in A rows + cols only
+            X_f_2c = as_aligned(X_f_2, align, np.float32)
+            assert_dot_close(A_f_22, X_f_2c, desired)
+            # Strides just in A cols
+            A_d_12 = A_d[:, ::2]
+            desired = np.dot(A_d_12, X_d_2)
+            A_f_12 = A_f[:, ::2]
+            assert_dot_close(A_f_12, X_f_2c, desired)
+            # Strides in A cols and X
+            assert_dot_close(A_f_12, X_f_2, desired)
+
+
+class MatmulCommon():
+    """Common tests for '@' operator and numpy.matmul.
+
+    Do not derive from TestCase to avoid nose running it.
+
+    """
+    # Should work with these types. Will want to add
+    # "O" at some point
+    types = "?bhilqBHILQefdgFDG"
+
+    def test_exceptions(self):
+        dims = [
+            ((1,), (2,)),            # mismatched vector vector
+            ((2, 1,), (2,)),         # mismatched matrix vector
+            ((2,), (1, 2)),          # mismatched vector matrix
+            ((1, 2), (3, 1)),        # mismatched matrix matrix
+            ((1,), ()),              # vector scalar
+            ((), (1)),               # scalar vector
+            ((1, 1), ()),            # matrix scalar
+            ((), (1, 1)),            # scalar matrix
+            ((2, 2, 1), (3, 1, 2)),  # cannot broadcast
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            assert_raises(ValueError, self.matmul, a, b)
+
+    def test_shapes(self):
+        dims = [
+            ((1, 1), (2, 1, 1)),     # broadcast first argument
+            ((2, 1, 1), (1, 1)),     # broadcast second argument
+            ((2, 1, 1), (2, 1, 1)),  # matrix stack sizes match
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            res = self.matmul(a, b)
+            assert_(res.shape == (2, 1, 1))
+
+        # vector vector returns scalars.
+        for dt in self.types:
+            a = np.ones((2,), dtype=dt)
+            b = np.ones((2,), dtype=dt)
+            c = self.matmul(a, b)
+            assert_(np.array(c).shape == ())
+
+    def test_result_types(self):
+        mat = np.ones((1,1))
+        vec = np.ones((1,))
+        for dt in self.types:
+            m = mat.astype(dt)
+            v = vec.astype(dt)
+            for arg in [(m, v), (v, m), (m, m)]:
+                res = self.matmul(*arg)
+                assert_(res.dtype == dt)
+
+            # vector vector returns scalars
+            res = self.matmul(v, v)
+            assert_(type(res) is np.dtype(dt).type)
+
+    def test_vector_vector_values(self):
+        vec = np.array([1, 2])
+        tgt = 5
+        for dt in self.types[1:]:
+            v1 = vec.astype(dt)
+            res = self.matmul(v1, v1)
+            assert_equal(res, tgt)
+
+        # boolean type
+        vec = np.array([True, True], dtype='?')
+        res = self.matmul(vec, vec)
+        assert_equal(res, True)
+
+    def test_vector_matrix_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([7, 10])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(v, m1)
+            assert_equal(res, tgt1)
+            res = self.matmul(v, m2)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_vector_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([5, 11])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(m1, v)
+            assert_equal(res, tgt1)
+            res = self.matmul(m2, v)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_matrix_values(self):
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.array([[1, 0], [1, 1]])
+        mat12 = np.stack([mat1, mat2], axis=0)
+        mat21 = np.stack([mat2, mat1], axis=0)
+        tgt11 = np.array([[7, 10], [15, 22]])
+        tgt12 = np.array([[3, 2], [7, 4]])
+        tgt21 = np.array([[1, 2], [4, 6]])
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+        for dt in self.types[1:]:
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            m12 = mat12.astype(dt)
+            m21 = mat21.astype(dt)
+
+            # matrix @ matrix
+            res = self.matmul(m1, m2)
+            assert_equal(res, tgt12)
+            res = self.matmul(m2, m1)
+            assert_equal(res, tgt21)
+
+            # stacked @ matrix
+            res = self.matmul(m12, m1)
+            assert_equal(res, tgt11_21)
+
+            # matrix @ stacked
+            res = self.matmul(m1, m12)
+            assert_equal(res, tgt11_12)
+
+            # stacked @ stacked
+            res = self.matmul(m12, m21)
+            assert_equal(res, tgt12_21)
+
+        # boolean type
+        m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_)
+        m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_)
+        m12 = np.stack([m1, m2], axis=0)
+        m21 = np.stack([m2, m1], axis=0)
+        tgt11 = m1
+        tgt12 = m1
+        tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_)
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+
+        # matrix @ matrix
+        res = self.matmul(m1, m2)
+        assert_equal(res, tgt12)
+        res = self.matmul(m2, m1)
+        assert_equal(res, tgt21)
+
+        # stacked @ matrix
+        res = self.matmul(m12, m1)
+        assert_equal(res, tgt11_21)
+
+        # matrix @ stacked
+        res = self.matmul(m1, m12)
+        assert_equal(res, tgt11_12)
+
+        # stacked @ stacked
+        res = self.matmul(m12, m21)
+        assert_equal(res, tgt12_21)
+
+    def test_numpy_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A([1, 2])
+        b = B([1, 2])
+        c = np.ones(2)
+        assert_equal(self.matmul(a, b), "A")
+        assert_equal(self.matmul(b, a), "A")
+        assert_raises(TypeError, self.matmul, b, c)
+
+
+class TestMatmul(MatmulCommon, TestCase):
+    matmul = np.matmul
+
+    def test_out_arg(self):
+        a = np.ones((2, 2), dtype=np.float)
+        b = np.ones((2, 2), dtype=np.float)
+        tgt = np.full((2,2), 2, dtype=np.float)
+
+        # test as positional argument
+        msg = "out positional argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test as keyword argument
+        msg = "out keyword argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out=out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out with not allowed type cast (safe casting)
+        # einsum and cblas raise different error types, so
+        # use Exception.
+        msg = "out argument with illegal cast"
+        out = np.zeros((2, 2), dtype=np.int32)
+        assert_raises(Exception, self.matmul, a, b, out=out)
+
+        # skip following tests for now, cblas does not allow non-contiguous
+        # outputs and consistency with dot would require same type,
+        # dimensions, subtype, and c_contiguous.
+
+        # test out with allowed type cast
+        # msg = "out argument with allowed cast"
+        # out = np.zeros((2, 2), dtype=np.complex128)
+        # self.matmul(a, b, out=out)
+        # assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out non-contiguous
+        # msg = "out argument with non-contiguous layout"
+        # c = np.zeros((2, 2, 2), dtype=np.float)
+        # self.matmul(a, b, out=c[..., 0])
+        # assert_array_equal(c, tgt, err_msg=msg)
+
+
+if sys.version_info[:2] >= (3, 5):
+    class TestMatmulOperator(MatmulCommon, TestCase):
+        import operator
+        matmul = operator.matmul
+
+        def test_array_priority_override(self):
+
+            class A(object):
+                __array_priority__ = 1000
+
+                def __matmul__(self, other):
+                    return "A"
+
+                def __rmatmul__(self, other):
+                    return "A"
+
+            a = A()
+            b = np.ones(2)
+            assert_equal(self.matmul(a, b), "A")
+            assert_equal(self.matmul(b, a), "A")
+
+    def test_matmul_inplace():
+        # It would be nice to support in-place matmul eventually, but for now
+        # we don't have a working implementation, so better just to error out
+        # and nudge people to writing "a = a @ b".
+        a = np.eye(3)
+        b = np.eye(3)
+        assert_raises(TypeError, a.__imatmul__, b)
+        import operator
+        assert_raises(TypeError, operator.imatmul, a, b)
+        # we avoid writing the token `exec` so as not to crash python 2's
+        # parser
+        exec_ = getattr(builtins, "exec")
+        assert_raises(TypeError, exec_, "a @= b", globals(), locals())
+
+
+class TestInner(TestCase):
+
+    def test_inner_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.inner, c, A)
+        assert_raises(TypeError, np.inner, A, c)
+
+    def test_inner_scalar_and_vector(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            vec = np.array([1, 2], dtype=dt)
+            desired = np.array([3, 6], dtype=dt)
+            assert_equal(np.inner(vec, sca), desired)
+            assert_equal(np.inner(sca, vec), desired)
+
+    def test_inner_scalar_and_matrix(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            arr = np.matrix([[1, 2], [3, 4]], dtype=dt)
+            desired = np.matrix([[3, 6], [9, 12]], dtype=dt)
+            assert_equal(np.inner(arr, sca), desired)
+            assert_equal(np.inner(sca, arr), desired)
+
+    def test_inner_scalar_and_matrix_of_objects(self):
+        # Ticket #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.inner(arr, 3), desired)
+        assert_equal(np.inner(3, arr), desired)
+
+    def test_vecself(self):
+        # Ticket 844.
+        # Inner product of a vector with itself segfaults or give
+        # meaningless result
+        a = np.zeros(shape=(1, 80), dtype=np.float64)
+        p = np.inner(a, a)
+        assert_almost_equal(p, 0, decimal=14)
+
+    def test_inner_product_with_various_contiguities(self):
+        # github issue 6532
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            # check an inner product involving a matrix transpose
+            A = np.array([[1, 2], [3, 4]], dtype=dt)
+            B = np.array([[1, 3], [2, 4]], dtype=dt)
+            C = np.array([1, 1], dtype=dt)
+            desired = np.array([4, 6], dtype=dt)
+            assert_equal(np.inner(A.T, C), desired)
+            assert_equal(np.inner(C, A.T), desired)
+            assert_equal(np.inner(B, C), desired)
+            assert_equal(np.inner(C, B), desired)
+            # check a matrix product
+            desired = np.array([[7, 10], [15, 22]], dtype=dt)
+            assert_equal(np.inner(A, B), desired)
+            # check the syrk vs. gemm paths
+            desired = np.array([[5, 11], [11, 25]], dtype=dt)
+            assert_equal(np.inner(A, A), desired)
+            assert_equal(np.inner(A, A.copy()), desired)
+            # check an inner product involving an aliased and reversed view
+            a = np.arange(5).astype(dt)
+            b = a[::-1]
+            desired = np.array(10, dtype=dt).item()
+            assert_equal(np.inner(b, a), desired)
+
+    def test_3d_tensor(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            a = np.arange(24).reshape(2,3,4).astype(dt)
+            b = np.arange(24, 48).reshape(2,3,4).astype(dt)
+            desired = np.array(
+                [[[[ 158,  182,  206],
+                   [ 230,  254,  278]],
+
+                  [[ 566,  654,  742],
+                   [ 830,  918, 1006]],
+
+                  [[ 974, 1126, 1278],
+                   [1430, 1582, 1734]]],
+
+                 [[[1382, 1598, 1814],
+                   [2030, 2246, 2462]],
+
+                  [[1790, 2070, 2350],
+                   [2630, 2910, 3190]],
+
+                  [[2198, 2542, 2886],
+                   [3230, 3574, 3918]]]],
+                dtype=dt
+            )
+            assert_equal(np.inner(a, b), desired)
+            assert_equal(np.inner(b, a).transpose(2,3,0,1), desired)
+
+
+class TestSummarization(TestCase):
+    def test_1d(self):
+        A = np.arange(1001)
+        strA = '[   0    1    2 ...,  998  999 1000]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([   0,    1,    2, ...,  998,  999, 1000])'
+        assert_(repr(A) == reprA)
+
+    def test_2d(self):
+        A = np.arange(1002).reshape(2, 501)
+        strA = '[[   0    1    2 ...,  498  499  500]\n' \
+               ' [ 501  502  503 ...,  999 1000 1001]]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([[   0,    1,    2, ...,  498,  499,  500],\n' \
+                '       [ 501,  502,  503, ...,  999, 1000, 1001]])'
+        assert_(repr(A) == reprA)
+
+
+class TestAlen(TestCase):
+    def test_basic(self):
+        m = np.array([1, 2, 3])
+        self.assertEqual(np.alen(m), 3)
+
+        m = np.array([[1, 2, 3], [4, 5, 7]])
+        self.assertEqual(np.alen(m), 2)
+
+        m = [1, 2, 3]
+        self.assertEqual(np.alen(m), 3)
+
+        m = [[1, 2, 3], [4, 5, 7]]
+        self.assertEqual(np.alen(m), 2)
+
+    def test_singleton(self):
+        self.assertEqual(np.alen(5), 1)
+
+
+class TestChoose(TestCase):
+    def setUp(self):
+        self.x = 2*np.ones((3,), dtype=int)
+        self.y = 3*np.ones((3,), dtype=int)
+        self.x2 = 2*np.ones((2, 3), dtype=int)
+        self.y2 = 3*np.ones((2, 3), dtype=int)
+        self.ind = [0, 0, 1]
+
+    def test_basic(self):
+        A = np.choose(self.ind, (self.x, self.y))
+        assert_equal(A, [2, 2, 3])
+
+    def test_broadcast1(self):
+        A = np.choose(self.ind, (self.x2, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_broadcast2(self):
+        A = np.choose(self.ind, (self.x, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+
+class TestRepeat(TestCase):
+    def setUp(self):
+        self.m = np.array([1, 2, 3, 4, 5, 6])
+        self.m_rect = self.m.reshape((2, 3))
+
+    def test_basic(self):
+        A = np.repeat(self.m, [1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+    def test_broadcast1(self):
+        A = np.repeat(self.m, 2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+    def test_axis_spec(self):
+        A = np.repeat(self.m_rect, [2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, [1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+    def test_broadcast2(self):
+        A = np.repeat(self.m_rect, 2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, 2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+
+# TODO: test for multidimensional
+NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4}
+
+
+class TestNeighborhoodIter(TestCase):
+    # Simple, 2d tests
+    def _test_simple2d(self, dt):
+        # Test zero and one padding for simple data type
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt),
+             np.array([[0, 0, 0], [0, 1, 0]], dtype=dt),
+             np.array([[0, 0, 1], [0, 2, 3]], dtype=dt),
+             np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt),
+             np.array([[1, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[1, 0, 1], [1, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt),
+             np.array([[4, 4, 4], [0, 1, 4]], dtype=dt),
+             np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
+             np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], 4,
+                NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple2d(self):
+        self._test_simple2d(np.float)
+
+    def test_simple2d_object(self):
+        self._test_simple2d(Decimal)
+
+    def _test_mirror2d(self, dt):
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
+             np.array([[0, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[0, 0, 1], [2, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    def test_mirror2d(self):
+        self._test_mirror2d(np.float)
+
+    def test_mirror2d_object(self):
+        self._test_mirror2d(Decimal)
+
+    # Simple, 1d tests
+    def _test_simple(self, dt):
+        # Test padding with constant values
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[4], NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple_float(self):
+        self._test_simple(np.float)
+
+    def test_simple_object(self):
+        self._test_simple(Decimal)
+
+    # Test mirror modes
+    def _test_mirror(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[1], NEIGH_MODE['mirror'])
+        self.assertTrue([i.dtype == dt for i in l])
+        assert_array_equal(l, r)
+
+    def test_mirror(self):
+        self._test_mirror(np.float)
+
+    def test_mirror_object(self):
+        self._test_mirror(Decimal)
+
+    # Circular mode
+    def _test_circular(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    def test_circular(self):
+        self._test_circular(np.float)
+
+    def test_circular_object(self):
+        self._test_circular(Decimal)
+
+# Test stacking neighborhood iterators
+class TestStackedNeighborhoodIter(TestCase):
+    # Simple, 1d test: stacking 2 constant-padded neigh iterators
+    def test_simple_const(self):
+        dt = np.float64
+        # Test zero and one padding for simple data type
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([1], dtype=dt),
+             np.array([2], dtype=dt),
+             np.array([3], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-2, 4], NEIGH_MODE['zero'],
+                [0, 0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([1, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-1, 1], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+    # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # mirror padding
+    def test_simple_mirror(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 1], dtype=dt),
+             np.array([1, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 3], dtype=dt),
+             np.array([3, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['mirror'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # circular padding
+    def test_simple_circular(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 3, 1], dtype=dt),
+             np.array([3, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 1], dtype=dt),
+             np.array([3, 1, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['circular'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator
+    # being strictly within the array
+    def test_simple_strict_within(self):
+        dt = np.float64
+        # Stacking zero on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+class TestWarnings(object):
+
+    def test_complex_warning(self):
+        x = np.array([1, 2])
+        y = np.array([1-2j, 1+2j])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", np.ComplexWarning)
+            assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y)
+            assert_equal(x, [1, 2])
+
+
+class TestMinScalarType(object):
+
+    def test_usigned_shortshort(self):
+        dt = np.min_scalar_type(2**8-1)
+        wanted = np.dtype('uint8')
+        assert_equal(wanted, dt)
+
+    def test_usigned_short(self):
+        dt = np.min_scalar_type(2**16-1)
+        wanted = np.dtype('uint16')
+        assert_equal(wanted, dt)
+
+    def test_usigned_int(self):
+        dt = np.min_scalar_type(2**32-1)
+        wanted = np.dtype('uint32')
+        assert_equal(wanted, dt)
+
+    def test_usigned_longlong(self):
+        dt = np.min_scalar_type(2**63-1)
+        wanted = np.dtype('uint64')
+        assert_equal(wanted, dt)
+
+    def test_object(self):
+        dt = np.min_scalar_type(2**64)
+        wanted = np.dtype('O')
+        assert_equal(wanted, dt)
+
+
+if sys.version_info[:2] == (2, 6):
+    from numpy.core.multiarray import memorysimpleview as memoryview
+
+from numpy.core._internal import _dtype_from_pep3118
+
+
+class TestPEP3118Dtype(object):
+    def _check(self, spec, wanted):
+        dt = np.dtype(wanted)
+        if isinstance(wanted, list) and isinstance(wanted[-1], tuple):
+            if wanted[-1][0] == '':
+                names = list(dt.names)
+                names[-1] = ''
+                dt.names = tuple(names)
+        assert_equal(_dtype_from_pep3118(spec), dt,
+                     err_msg="spec %r != dtype %r" % (spec, wanted))
+
+    def test_native_padding(self):
+        align = np.dtype('i').alignment
+        for j in range(8):
+            if j == 0:
+                s = 'bi'
+            else:
+                s = 'b%dxi' % j
+            self._check('@'+s, {'f0': ('i1', 0),
+                                'f1': ('i', align*(1 + j//align))})
+            self._check('='+s, {'f0': ('i1', 0),
+                                'f1': ('i', 1+j)})
+
+    def test_native_padding_2(self):
+        # Native padding should work also for structs and sub-arrays
+        self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
+        self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
+
+    def test_trailing_padding(self):
+        # Trailing padding should be included, *and*, the item size
+        # should match the alignment if in aligned mode
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('ix', [('f0', 'i'), ('', VV(1))])
+        self._check('ixx', [('f0', 'i'), ('', VV(2))])
+        self._check('ixxx', [('f0', 'i'), ('', VV(3))])
+        self._check('ixxxx', [('f0', 'i'), ('', VV(4))])
+        self._check('i7x', [('f0', 'i'), ('', VV(7))])
+
+        self._check('^ix', [('f0', 'i'), ('', 'V1')])
+        self._check('^ixx', [('f0', 'i'), ('', 'V2')])
+        self._check('^ixxx', [('f0', 'i'), ('', 'V3')])
+        self._check('^ixxxx', [('f0', 'i'), ('', 'V4')])
+        self._check('^i7x', [('f0', 'i'), ('', 'V7')])
+
+    def test_native_padding_3(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'),
+                    ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
+
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
+
+    def test_padding_with_array_inside_struct(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)),
+                    ('d', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
+
+    def test_byteorder_inside_struct(self):
+        # The byte order after @T{=i} should be '=', not '@'.
+        # Check this by noting the absence of native alignment.
+        self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0),
+                                 'f1': ('i', 5)})
+
+    def test_intra_padding(self):
+        # Natively aligned sub-arrays may require some internal padding
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('(3)T{ix}', ({'f0': ('i', 0), '': (VV(1), 4)}, (3,)))
+
+
+class TestNewBufferProtocol(object):
+    def _check_roundtrip(self, obj):
+        obj = np.asarray(obj)
+        x = memoryview(obj)
+        y = np.asarray(x)
+        y2 = np.array(x)
+        assert_(not y.flags.owndata)
+        assert_(y2.flags.owndata)
+
+        assert_equal(y.dtype, obj.dtype)
+        assert_equal(y.shape, obj.shape)
+        assert_array_equal(obj, y)
+
+        assert_equal(y2.dtype, obj.dtype)
+        assert_equal(y2.shape, obj.shape)
+        assert_array_equal(obj, y2)
+
+    def test_roundtrip(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i4')
+        self._check_roundtrip(x)
+
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        self._check_roundtrip(x)
+
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        self._check_roundtrip(x)
+
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('xxx'), True, 1.0)],
+                dtype=dt)
+        self._check_roundtrip(x)
+
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))])
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i4')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i4')
+        self._check_roundtrip(x)
+
+        # check long long can be represented as non-native
+        x = np.array([1, 2, 3], dtype='>q')
+        self._check_roundtrip(x)
+
+        # Native-only data types can be passed through the buffer interface
+        # only in native byte order
+        if sys.byteorder == 'little':
+            x = np.array([1, 2, 3], dtype='>g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+            x = np.array([1, 2, 3], dtype='<g')
+            self._check_roundtrip(x)
+        else:
+            x = np.array([1, 2, 3], dtype='>g')
+            self._check_roundtrip(x)
+            x = np.array([1, 2, 3], dtype='<g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+
+    def test_roundtrip_half(self):
+        half_list = [
+            1.0,
+            -2.0,
+            6.5504 * 10**4,  # (max half precision)
+            2**-14,  # ~= 6.10352 * 10**-5 (minimum positive normal)
+            2**-24,  # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
+            0.0,
+            -0.0,
+            float('+inf'),
+            float('-inf'),
+            0.333251953125,  # ~= 1/3
+        ]
+
+        x = np.array(half_list, dtype='>e')
+        self._check_roundtrip(x)
+        x = np.array(half_list, dtype='<e')
+        self._check_roundtrip(x)
+
+    def test_roundtrip_single_types(self):
+        for typ in np.typeDict.values():
+            dtype = np.dtype(typ)
+
+            if dtype.char in 'Mm':
+                # datetimes cannot be used in buffers
+                continue
+            if dtype.char == 'V':
+                # skip void
+                continue
+
+            x = np.zeros(4, dtype=dtype)
+            self._check_roundtrip(x)
+
+            if dtype.char not in 'qQgG':
+                dt = dtype.newbyteorder('<')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+                dt = dtype.newbyteorder('>')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+    def test_roundtrip_scalar(self):
+        # Issue #4015.
+        self._check_roundtrip(0)
+
+    def test_export_simple_1d(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i')
+        y = memoryview(x)
+        assert_equal(y.format, 'i')
+        assert_equal(y.shape, (5,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.strides, (4,))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_simple_nd(self):
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        y = memoryview(x)
+        assert_equal(y.format, 'd')
+        assert_equal(y.shape, (2, 2))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (16, 8))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 8)
+
+    def test_export_discontiguous(self):
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        y = memoryview(x)
+        assert_equal(y.format, 'f')
+        assert_equal(y.shape, (3, 3))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (36, 4))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_record(self):
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('   '), True, 1.0)],
+                dtype=dt)
+        y = memoryview(x)
+        assert_equal(y.shape, (1,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.suboffsets, EMPTY)
+
+        sz = sum([np.dtype(b).itemsize for a, b in dt])
+        if np.dtype('l').itemsize == 4:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        else:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides
+        if not (np.ones(1).strides[0] == np.iinfo(np.intp).max):
+            assert_equal(y.strides, (sz,))
+        assert_equal(y.itemsize, sz)
+
+    def test_export_subarray(self):
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))])
+        y = memoryview(x)
+        assert_equal(y.format, 'T{(2,2)i:a:}')
+        assert_equal(y.shape, EMPTY)
+        assert_equal(y.ndim, 0)
+        assert_equal(y.strides, EMPTY)
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 16)
+
+    def test_export_endian(self):
+        x = np.array([1, 2, 3], dtype='>i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, '>i')
+        else:
+            assert_equal(y.format, 'i')
+
+        x = np.array([1, 2, 3], dtype='<i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, 'i')
+        else:
+            assert_equal(y.format, '<i')
+
+    def test_export_flags(self):
+        # Check SIMPLE flag, see also gh-3613 (exception should be BufferError)
+        assert_raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
+
+    def test_padding(self):
+        for j in range(8):
+            x = np.array([(1,), (2,)], dtype={'f0': (int, j)})
+            self._check_roundtrip(x)
+
+    def test_reference_leak(self):
+        count_1 = sys.getrefcount(np.core._internal)
+        a = np.zeros(4)
+        b = memoryview(a)
+        c = np.asarray(b)
+        count_2 = sys.getrefcount(np.core._internal)
+        assert_equal(count_1, count_2)
+        del c  # avoid pyflakes unused variable warning.
+
+    def test_padded_struct_array(self):
+        dt1 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        x1 = np.arange(dt1.itemsize, dtype=np.int8).view(dt1)
+        self._check_roundtrip(x1)
+
+        dt2 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')],
+                align=True)
+        x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
+        self._check_roundtrip(x2)
+
+        dt3 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
+        self._check_roundtrip(x3)
+
+    def test_relaxed_strides(self):
+        # Test that relaxed strides are converted to non-relaxed
+        c = np.ones((1, 10, 10), dtype='i8')
+
+        # Check for NPY_RELAXED_STRIDES_CHECKING:
+        if np.ones((10, 1), order="C").flags.f_contiguous:
+            c.strides = (-1, 80, 8)
+
+        assert_(memoryview(c).strides == (800, 80, 8))
+
+        # Writing C-contiguous data to a BytesIO buffer should work
+        fd = io.BytesIO()
+        fd.write(c.data)
+
+        fortran = c.T
+        assert_(memoryview(fortran).strides == (8, 80, 800))
+
+        arr = np.ones((1, 10))
+        if arr.flags.f_contiguous:
+            shape, strides = get_buffer_info(arr, ['F_CONTIGUOUS'])
+            assert_(strides[0] == 8)
+            arr = np.ones((10, 1), order='F')
+            shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
+            assert_(strides[-1] == 8)
+
+
+class TestArrayAttributeDeletion(object):
+
+    def test_multiarray_writable_attributes_deletion(self):
+        """ticket #2046, should not seqfault, raise AttributeError"""
+        a = np.ones(2)
+        attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_not_writable_attributes_deletion(self):
+        a = np.ones(2)
+        attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
+                "ctypes", "T", "__array_interface__", "__array_struct__",
+                "__array_priority__", "__array_finalize__"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ['updateifcopy', 'aligned', 'writeable']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_not_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
+                "owndata", "fnc", "forc", "behaved", "carray", "farray",
+                "num"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+
+def test_array_interface():
+    # Test scalar coercion within the array interface
+    class Foo(object):
+        def __init__(self, value):
+            self.value = value
+            self.iface = {'typestr': '=f8'}
+
+        def __float__(self):
+            return float(self.value)
+
+        @property
+        def __array_interface__(self):
+            return self.iface
+
+    f = Foo(0.5)
+    assert_equal(np.array(f), 0.5)
+    assert_equal(np.array([f]), [0.5])
+    assert_equal(np.array([f, f]), [0.5, 0.5])
+    assert_equal(np.array(f).dtype, np.dtype('=f8'))
+    # Test various shape definitions
+    f.iface['shape'] = ()
+    assert_equal(np.array(f), 0.5)
+    f.iface['shape'] = None
+    assert_raises(TypeError, np.array, f)
+    f.iface['shape'] = (1, 1)
+    assert_equal(np.array(f), [[0.5]])
+    f.iface['shape'] = (2,)
+    assert_raises(ValueError, np.array, f)
+
+    # test scalar with no shape
+    class ArrayLike(object):
+        array = np.array(1)
+        __array_interface__ = array.__array_interface__
+    assert_equal(np.array(ArrayLike()), 1)
+
+
+def test_array_interface_itemsize():
+    # See gh-6361
+    my_dtype = np.dtype({'names': ['A', 'B'], 'formats': ['f4', 'f4'],
+                         'offsets': [0, 8], 'itemsize': 16})
+    a = np.ones(10, dtype=my_dtype)
+    descr_t = np.dtype(a.__array_interface__['descr'])
+    typestr_t = np.dtype(a.__array_interface__['typestr'])
+    assert_equal(descr_t.itemsize, typestr_t.itemsize)
+
+
+def test_flat_element_deletion():
+    it = np.ones(3).flat
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+
+def test_scalar_element_deletion():
+    a = np.zeros(2, dtype=[('x', 'int'), ('y', 'int')])
+    assert_raises(ValueError, a[0].__delitem__, 'x')
+
+
+class TestMemEventHook(TestCase):
+    def test_mem_seteventhook(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+        test_pydatamem_seteventhook_start()
+        # force an allocation and free of a numpy array
+        # needs to be larger then limit of small memory cacher in ctors.c
+        a = np.zeros(1000)
+        del a
+        test_pydatamem_seteventhook_end()
+
+class TestMapIter(TestCase):
+    def test_mapiter(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+
+        a = np.arange(12).reshape((3, 4)).astype(float)
+        index = ([1, 1, 2, 0],
+                 [0, 0, 2, 3])
+        vals = [50, 50, 30, 16]
+
+        test_inplace_increment(a, index, vals)
+        assert_equal(a, [[0.00, 1., 2.0, 19.],
+                         [104., 5., 6.0, 7.0],
+                         [8.00, 9., 40., 11.]])
+
+        b = np.arange(6).astype(float)
+        index = (np.array([1, 2, 0]),)
+        vals = [50, 4, 100.1]
+        test_inplace_increment(b, index, vals)
+        assert_equal(b, [100.1,  51.,   6.,   3.,   4.,   5.])
+
+
+class TestAsCArray(TestCase):
+    def test_1darray(self):
+        array = np.arange(24, dtype=np.double)
+        from_c = test_as_c_array(array, 3)
+        assert_equal(array[3], from_c)
+
+    def test_2darray(self):
+        array = np.arange(24, dtype=np.double).reshape(3, 8)
+        from_c = test_as_c_array(array, 2, 4)
+        assert_equal(array[2, 4], from_c)
+
+    def test_3darray(self):
+        array = np.arange(24, dtype=np.double).reshape(2, 3, 4)
+        from_c = test_as_c_array(array, 1, 2, 3)
+        assert_equal(array[1, 2, 3], from_c)
+
+
+class TestConversion(TestCase):
+    def test_array_scalar_relational_operation(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+
+            # Unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+class TestWhere(TestCase):
+    def test_basic(self):
+        dts = [np.bool, np.int16, np.int32, np.int64, np.double, np.complex128,
+               np.longdouble, np.clongdouble]
+        for dt in dts:
+            c = np.ones(53, dtype=np.bool)
+            assert_equal(np.where( c, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(~c, dt(0), dt(1)), dt(1))
+            assert_equal(np.where(True, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(False, dt(0), dt(1)), dt(1))
+            d = np.ones_like(c).astype(dt)
+            e = np.zeros_like(d)
+            r = d.astype(dt)
+            c[7] = False
+            r[7] = e[7]
+            assert_equal(np.where(c, e, e), e)
+            assert_equal(np.where(c, d, e), r)
+            assert_equal(np.where(c, d, e[0]), r)
+            assert_equal(np.where(c, d[0], e), r)
+            assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2])
+            assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2])
+            assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3])
+            assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3])
+            assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2])
+            assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3])
+            assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3])
+
+    def test_exotic(self):
+        # object
+        assert_array_equal(np.where(True, None, None), np.array(None))
+        # zero sized
+        m = np.array([], dtype=bool).reshape(0, 3)
+        b = np.array([], dtype=np.float64).reshape(0, 3)
+        assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3))
+
+        # object cast
+        d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313,
+                      0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013,
+                      1.267, 0.229, -1.39, 0.487])
+        nan = float('NaN')
+        e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan,
+                     'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'],
+                     dtype=object)
+        m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+                      0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool)
+
+        r = e[:]
+        r[np.where(m)] = d[np.where(m)]
+        assert_array_equal(np.where(m, d, e), r)
+
+        r = e[:]
+        r[np.where(~m)] = d[np.where(~m)]
+        assert_array_equal(np.where(m, e, d), r)
+
+        assert_array_equal(np.where(m, e, e), e)
+
+        # minimal dtype result with NaN scalar (e.g required by pandas)
+        d = np.array([1., 2.], dtype=np.float32)
+        e = float('NaN')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('-Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        # also check upcast
+        e = float(1e150)
+        assert_equal(np.where(True, d, e).dtype, np.float64)
+
+    def test_ndim(self):
+        c = [True, False]
+        a = np.zeros((2, 25))
+        b = np.ones((2, 25))
+        r = np.where(np.array(c)[:,np.newaxis], a, b)
+        assert_array_equal(r[0], a[0])
+        assert_array_equal(r[1], b[0])
+
+        a = a.T
+        b = b.T
+        r = np.where(c, a, b)
+        assert_array_equal(r[:,0], a[:,0])
+        assert_array_equal(r[:,1], b[:,0])
+
+    def test_dtype_mix(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        a = np.uint32(1)
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                      dtype=np.float64)
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype(np.float32)
+        b = b.astype(np.int64)
+        assert_equal(np.where(c, a, b), r)
+
+        # non bool mask
+        c = c.astype(np.int)
+        c[c != 0] = 34242324
+        assert_equal(np.where(c, a, b), r)
+        # invert
+        tmpmask = c != 0
+        c[c == 0] = 41247212
+        c[tmpmask] = 0
+        assert_equal(np.where(c, b, a), r)
+
+    def test_foreign(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        a = np.ones(1, dtype='>i4')
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        b = b.astype('>f8')
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype('<i4')
+        assert_equal(np.where(c, a, b), r)
+
+        c = c.astype('>i4')
+        assert_equal(np.where(c, a, b), r)
+
+    def test_error(self):
+        c = [True, True]
+        a = np.ones((4, 5))
+        b = np.ones((5, 5))
+        assert_raises(ValueError, np.where, c, a, a)
+        assert_raises(ValueError, np.where, c[0], a, b)
+
+    def test_string(self):
+        # gh-4778 check strings are properly filled with nulls
+        a = np.array("abc")
+        b = np.array("x" * 753)
+        assert_equal(np.where(True, a, b), "abc")
+        assert_equal(np.where(False, b, a), "abc")
+
+        # check native datatype sized strings
+        a = np.array("abcd")
+        b = np.array("x" * 8)
+        assert_equal(np.where(True, a, b), "abcd")
+        assert_equal(np.where(False, b, a), "abcd")
+
+
+class TestSizeOf(TestCase):
+
+    def test_empty_array(self):
+        x = np.array([])
+        assert_(sys.getsizeof(x) > 0)
+
+    def check_array(self, dtype):
+        elem_size = dtype(0).itemsize
+
+        for length in [10, 50, 100, 500]:
+            x = np.arange(length, dtype=dtype)
+            assert_(sys.getsizeof(x) > length * elem_size)
+
+    def test_array_int32(self):
+        self.check_array(np.int32)
+
+    def test_array_int64(self):
+        self.check_array(np.int64)
+
+    def test_array_float32(self):
+        self.check_array(np.float32)
+
+    def test_array_float64(self):
+        self.check_array(np.float64)
+
+    def test_view(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d[...]) < sys.getsizeof(d))
+
+    def test_reshape(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy()))
+
+    def test_resize(self):
+        d = np.ones(100)
+        old = sys.getsizeof(d)
+        d.resize(50)
+        assert_(old > sys.getsizeof(d))
+        d.resize(150)
+        assert_(old < sys.getsizeof(d))
+
+    def test_error(self):
+        d = np.ones(100)
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestHashing(TestCase):
+
+    def test_arrays_not_hashable(self):
+        x = np.ones(3)
+        assert_raises(TypeError, hash, x)
+
+    def test_collections_hashable(self):
+        x = np.array([])
+        self.assertFalse(isinstance(x, collections.Hashable))
+
+
+class TestArrayPriority(TestCase):
+    # This will go away when __array_priority__ is settled, meanwhile
+    # it serves to check unintended changes.
+    op = operator
+    binary_ops = [
+        op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod,
+        op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt,
+        op.ge, op.lt, op.le, op.ne, op.eq
+        ]
+
+    if sys.version_info[0] < 3:
+        binary_ops.append(op.div)
+
+    class Foo(np.ndarray):
+        __array_priority__ = 100.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Bar(np.ndarray):
+        __array_priority__ = 101.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Other(object):
+        __array_priority__ = 1000.
+
+        def _all(self, other):
+            return self.__class__()
+
+        __add__ = __radd__ = _all
+        __sub__ = __rsub__ = _all
+        __mul__ = __rmul__ = _all
+        __pow__ = __rpow__ = _all
+        __div__ = __rdiv__ = _all
+        __mod__ = __rmod__ = _all
+        __truediv__ = __rtruediv__ = _all
+        __floordiv__ = __rfloordiv__ = _all
+        __and__ = __rand__ = _all
+        __xor__ = __rxor__ = _all
+        __or__ = __ror__ = _all
+        __lshift__ = __rlshift__ = _all
+        __rshift__ = __rrshift__ = _all
+        __eq__ = _all
+        __ne__ = _all
+        __gt__ = _all
+        __ge__ = _all
+        __lt__ = _all
+        __le__ = _all
+
+    def test_ndarray_subclass(self):
+        a = np.array([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_ndarray_other(self):
+        a = np.array([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+    def test_subclass_subclass(self):
+        a = self.Foo([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_subclass_other(self):
+        a = self.Foo([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+
+class TestBytestringArrayNonzero(TestCase):
+
+    def test_empty_bstring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.str))
+
+    def test_whitespace_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_bstring_array_is_truthy(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+class TestUnicodeArrayNonzero(TestCase):
+
+    def test_empty_ustring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.unicode))
+
+    def test_whitespace_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_ustring_array_is_truthy(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
new file mode 100644
index 0000000000..c73a0f3a66
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
@@ -0,0 +1,6386 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+import tempfile
+import sys
+import shutil
+import warnings
+import operator
+import io
+import itertools
+import ctypes
+import os
+if sys.version_info[0] >= 3:
+    import builtins
+else:
+    import __builtin__ as builtins
+from decimal import Decimal
+
+
+import numpy as np
+from numpy.compat import asbytes, getexception, strchar, unicode, sixu
+from test_print import in_foreign_locale
+from numpy.core.multiarray_tests import (
+    test_neighborhood_iterator, test_neighborhood_iterator_oob,
+    test_pydatamem_seteventhook_start, test_pydatamem_seteventhook_end,
+    test_inplace_increment, get_buffer_info, test_as_c_array
+    )
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_equal, assert_almost_equal, assert_array_equal,
+    assert_array_almost_equal, assert_allclose,
+    assert_array_less, runstring, dec, SkipTest
+    )
+
+# Need to test an object that does not fully implement math interface
+from datetime import timedelta
+
+
+if sys.version_info[:2] > (3, 2):
+    # In Python 3.3 the representation of empty shape, strides and sub-offsets
+    # is an empty tuple instead of None.
+    # http://docs.python.org/dev/whatsnew/3.3.html#api-changes
+    EMPTY = ()
+else:
+    EMPTY = None
+
+
+class TestFlags(TestCase):
+    def setUp(self):
+        self.a = np.arange(10)
+
+    def test_writeable(self):
+        mydict = locals()
+        self.a.flags.writeable = False
+        self.assertRaises(ValueError, runstring, 'self.a[0] = 3', mydict)
+        self.assertRaises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict)
+        self.a.flags.writeable = True
+        self.a[0] = 5
+        self.a[0] = 0
+
+    def test_otherflags(self):
+        assert_equal(self.a.flags.carray, True)
+        assert_equal(self.a.flags.farray, False)
+        assert_equal(self.a.flags.behaved, True)
+        assert_equal(self.a.flags.fnc, False)
+        assert_equal(self.a.flags.forc, True)
+        assert_equal(self.a.flags.owndata, True)
+        assert_equal(self.a.flags.writeable, True)
+        assert_equal(self.a.flags.aligned, True)
+        assert_equal(self.a.flags.updateifcopy, False)
+
+    def test_string_align(self):
+        a = np.zeros(4, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+        # not power of two are accessed byte-wise and thus considered aligned
+        a = np.zeros(5, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+
+    def test_void_align(self):
+        a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")]))
+        assert_(a.flags.aligned)
+
+
+class TestHash(TestCase):
+    # see #3793
+    def test_int(self):
+        for st, ut, s in [(np.int8, np.uint8, 8),
+                          (np.int16, np.uint16, 16),
+                          (np.int32, np.uint32, 32),
+                          (np.int64, np.uint64, 64)]:
+            for i in range(1, s):
+                assert_equal(hash(st(-2**i)), hash(-2**i),
+                             err_msg="%r: -2**%d" % (st, i))
+                assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (st, i - 1))
+                assert_equal(hash(st(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (st, i))
+
+                i = max(i - 1, 1)
+                assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (ut, i - 1))
+                assert_equal(hash(ut(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (ut, i))
+
+
+class TestAttributes(TestCase):
+    def setUp(self):
+        self.one = np.arange(10)
+        self.two = np.arange(20).reshape(4, 5)
+        self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6)
+
+    def test_attributes(self):
+        assert_equal(self.one.shape, (10,))
+        assert_equal(self.two.shape, (4, 5))
+        assert_equal(self.three.shape, (2, 5, 6))
+        self.three.shape = (10, 3, 2)
+        assert_equal(self.three.shape, (10, 3, 2))
+        self.three.shape = (2, 5, 6)
+        assert_equal(self.one.strides, (self.one.itemsize,))
+        num = self.two.itemsize
+        assert_equal(self.two.strides, (5*num, num))
+        num = self.three.itemsize
+        assert_equal(self.three.strides, (30*num, 6*num, num))
+        assert_equal(self.one.ndim, 1)
+        assert_equal(self.two.ndim, 2)
+        assert_equal(self.three.ndim, 3)
+        num = self.two.itemsize
+        assert_equal(self.two.size, 20)
+        assert_equal(self.two.nbytes, 20*num)
+        assert_equal(self.two.itemsize, self.two.dtype.itemsize)
+        assert_equal(self.two.base, np.arange(20))
+
+    def test_dtypeattr(self):
+        assert_equal(self.one.dtype, np.dtype(np.int_))
+        assert_equal(self.three.dtype, np.dtype(np.float_))
+        assert_equal(self.one.dtype.char, 'l')
+        assert_equal(self.three.dtype.char, 'd')
+        self.assertTrue(self.three.dtype.str[0] in '<>')
+        assert_equal(self.one.dtype.str[1], 'i')
+        assert_equal(self.three.dtype.str[1], 'f')
+
+    def test_int_subclassing(self):
+        # Regression test for https://github.com/numpy/numpy/pull/3526
+
+        numpy_int = np.int_(0)
+
+        if sys.version_info[0] >= 3:
+            # On Py3k int_ should not inherit from int, because it's not
+            # fixed-width anymore
+            assert_equal(isinstance(numpy_int, int), False)
+        else:
+            # Otherwise, it should inherit from int...
+            assert_equal(isinstance(numpy_int, int), True)
+
+            # ... and fast-path checks on C-API level should also work
+            from numpy.core.multiarray_tests import test_int_subclass
+            assert_equal(test_int_subclass(numpy_int), True)
+
+    def test_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            return np.ndarray(size, buffer=x, dtype=int,
+                              offset=offset*x.itemsize,
+                              strides=strides*x.itemsize)
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(ValueError, make_array, 8, 3, 1)
+        assert_equal(make_array(8, 3, 0), np.array([3]*8))
+        # Check behavior reported in gh-2503:
+        self.assertRaises(ValueError, make_array, (2, 3), 5, np.array([-2, -3]))
+        make_array(0, 0, 10)
+
+    def test_set_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            try:
+                r = np.ndarray([size], dtype=int, buffer=x,
+                               offset=offset*x.itemsize)
+            except:
+                raise RuntimeError(getexception())
+            r.strides = strides = strides*x.itemsize
+            return r
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(RuntimeError, make_array, 8, 3, 1)
+        # Check that the true extent of the array is used.
+        # Test relies on as_strided base not exposing a buffer.
+        x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0))
+
+        def set_strides(arr, strides):
+            arr.strides = strides
+
+        self.assertRaises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize))
+
+        # Test for offset calculations:
+        x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1],
+                                                    shape=(10,), strides=(-1,))
+        self.assertRaises(ValueError, set_strides, x[::-1], -1)
+        a = x[::-1]
+        a.strides = 1
+        a[::2].strides = 2
+
+    def test_fill(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = np.empty((3, 2, 1), t)
+            y = np.empty((3, 2, 1), t)
+            x.fill(1)
+            y[...] = 1
+            assert_equal(x, y)
+
+    def test_fill_max_uint64(self):
+        x = np.empty((3, 2, 1), dtype=np.uint64)
+        y = np.empty((3, 2, 1), dtype=np.uint64)
+        value = 2**64 - 1
+        y[...] = value
+        x.fill(value)
+        assert_array_equal(x, y)
+
+    def test_fill_struct_array(self):
+        # Filling from a scalar
+        x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8')
+        x.fill(x[0])
+        assert_equal(x['f1'][1], x['f1'][0])
+        # Filling from a tuple that can be converted
+        # to a scalar
+        x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')])
+        x.fill((3.5, -2))
+        assert_array_equal(x['a'], [3.5, 3.5])
+        assert_array_equal(x['b'], [-2, -2])
+
+
+class TestArrayConstruction(TestCase):
+    def test_array(self):
+        d = np.ones(6)
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6)))
+
+        d = np.ones(6)
+        tgt = np.ones((2, 6))
+        r = np.array([d, d])
+        assert_equal(r, tgt)
+        tgt[1] = 2
+        r = np.array([d, d + 1])
+        assert_equal(r, tgt)
+
+        d = np.ones(6)
+        r = np.array([[d, d]])
+        assert_equal(r, np.ones((1, 2, 6)))
+
+        d = np.ones(6)
+        r = np.array([[d, d], [d, d]])
+        assert_equal(r, np.ones((2, 2, 6)))
+
+        d = np.ones((6, 6))
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6, 6)))
+
+        d = np.ones((6, ))
+        r = np.array([[d, d + 1], d + 2])
+        assert_equal(len(r), 2)
+        assert_equal(r[0], [d, d + 1])
+        assert_equal(r[1], d + 2)
+
+        tgt = np.ones((2, 3), dtype=np.bool)
+        tgt[0, 2] = False
+        tgt[1, 0:2] = False
+        r = np.array([[True, True, False], [False, False, True]])
+        assert_equal(r, tgt)
+        r = np.array([[True, False], [True, False], [False, True]])
+        assert_equal(r, tgt.T)
+
+    def test_array_empty(self):
+        assert_raises(TypeError, np.array)
+
+    def test_array_copy_false(self):
+        d = np.array([1, 2, 3])
+        e = np.array(d, copy=False)
+        d[1] = 3
+        assert_array_equal(e, [1, 3, 3])
+        e = np.array(d, copy=False, order='F')
+        d[1] = 4
+        assert_array_equal(e, [1, 4, 3])
+        e[2] = 7
+        assert_array_equal(d, [1, 4, 7])
+
+    def test_array_copy_true(self):
+        d = np.array([[1,2,3], [1, 2, 3]])
+        e = np.array(d, copy=True)
+        d[0, 1] = 3
+        e[0, 2] = -7
+        assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
+        e = np.array(d, copy=True, order='F')
+        d[0, 1] = 5
+        e[0, 2] = 7
+        assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 5, 3], [1,2,3]])
+
+    def test_array_cont(self):
+        d = np.ones(10)[::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.ascontiguousarray(d).flags.f_contiguous)
+        assert_(np.asfortranarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+        d = np.ones((10, 10))[::2,::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+
+
+class TestAssignment(TestCase):
+    def test_assignment_broadcasting(self):
+        a = np.arange(6).reshape(2, 3)
+
+        # Broadcasting the input to the output
+        a[...] = np.arange(3)
+        assert_equal(a, [[0, 1, 2], [0, 1, 2]])
+        a[...] = np.arange(2).reshape(2, 1)
+        assert_equal(a, [[0, 0, 0], [1, 1, 1]])
+
+        # For compatibility with <= 1.5, a limited version of broadcasting
+        # the output to the input.
+        #
+        # This behavior is inconsistent with NumPy broadcasting
+        # in general, because it only uses one of the two broadcasting
+        # rules (adding a new "1" dimension to the left of the shape),
+        # applied to the output instead of an input. In NumPy 2.0, this kind
+        # of broadcasting assignment will likely be disallowed.
+        a[...] = np.arange(6)[::-1].reshape(1, 2, 3)
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+        # The other type of broadcasting would require a reduction operation.
+
+        def assign(a, b):
+            a[...] = b
+
+        assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3))
+
+    def test_assignment_errors(self):
+        # Address issue #2276
+        class C:
+            pass
+        a = np.zeros(1)
+
+        def assign(v):
+            a[0] = v
+
+        assert_raises((AttributeError, TypeError), assign, C())
+        assert_raises(ValueError, assign, [1])
+
+
+class TestDtypedescr(TestCase):
+    def test_construction(self):
+        d1 = np.dtype('i4')
+        assert_equal(d1, np.dtype(np.int32))
+        d2 = np.dtype('f8')
+        assert_equal(d2, np.dtype(np.float64))
+
+    def test_byteorders(self):
+        self.assertNotEqual(np.dtype('<i4'), np.dtype('>i4'))
+        self.assertNotEqual(np.dtype([('a', '<i4')]), np.dtype([('a', '>i4')]))
+
+
+class TestZeroRank(TestCase):
+    def setUp(self):
+        self.d = np.array(0), np.array('x', object)
+
+    def test_ellipsis_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(b[...], 'x')
+        self.assertTrue(a[...].base is a)  # `a[...] is a` in numpy <1.9.
+        self.assertTrue(b[...].base is b)  # `b[...] is b` in numpy <1.9.
+
+    def test_empty_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(b[()], 'x')
+        self.assertTrue(type(a[()]) is a.dtype.type)
+        self.assertTrue(type(b[()]) is str)
+
+    def test_invalid_subscript(self):
+        a, b = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[0], b)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], b)
+
+    def test_ellipsis_subscript_assignment(self):
+        a, b = self.d
+        a[...] = 42
+        self.assertEqual(a, 42)
+        b[...] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_empty_subscript_assignment(self):
+        a, b = self.d
+        a[()] = 42
+        self.assertEqual(a, 42)
+        b[()] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_invalid_subscript_assignment(self):
+        a, b = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(IndexError, assign, a, 0, 42)
+        self.assertRaises(IndexError, assign, b, 0, '')
+        self.assertRaises(ValueError, assign, a, (), '')
+
+    def test_newaxis(self):
+        a, b = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a, b = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_constructor(self):
+        x = np.ndarray(())
+        x[()] = 5
+        self.assertEqual(x[()], 5)
+        y = np.ndarray((), buffer=x)
+        y[()] = 6
+        self.assertEqual(x[()], 6)
+
+    def test_output(self):
+        x = np.array(2)
+        self.assertRaises(ValueError, np.add, x, [1], x)
+
+
+class TestScalarIndexing(TestCase):
+    def setUp(self):
+        self.d = np.array([0, 1])[0]
+
+    def test_ellipsis_subscript(self):
+        a = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(a[...].shape, ())
+
+    def test_empty_subscript(self):
+        a = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(a[()].shape, ())
+
+    def test_invalid_subscript(self):
+        a = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+
+    def test_invalid_subscript_assignment(self):
+        a = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(TypeError, assign, a, 0, 42)
+
+    def test_newaxis(self):
+        a = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_overlapping_assignment(self):
+        # With positive strides
+        a = np.arange(4)
+        a[:-1] = a[1:]
+        assert_equal(a, [1, 2, 3, 3])
+
+        a = np.arange(4)
+        a[1:] = a[:-1]
+        assert_equal(a, [0, 0, 1, 2])
+
+        # With positive and negative strides
+        a = np.arange(4)
+        a[:] = a[::-1]
+        assert_equal(a, [3, 2, 1, 0])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1,:] = a[:, ::-1]
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1, ::-1] = a[:, ::-1]
+        assert_equal(a, [[3, 4, 5], [0, 1, 2]])
+
+        # With just one element overlapping
+        a = np.arange(5)
+        a[:3] = a[2:]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[:3]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+        a = np.arange(5)
+        a[2::-1] = a[2:]
+        assert_equal(a, [4, 3, 2, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[2::-1]
+        assert_equal(a, [0, 1, 2, 1, 0])
+
+        a = np.arange(5)
+        a[2::-1] = a[:1:-1]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[:1:-1] = a[2::-1]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+
+class TestCreation(TestCase):
+    def test_from_attribute(self):
+        class x(object):
+            def __array__(self, dtype=None):
+                pass
+
+        self.assertRaises(ValueError, np.array, x())
+
+    def test_from_string(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['Float']
+        nstr = ['123', '123']
+        result = np.array([123, 123], dtype=int)
+        for type in types:
+            msg = 'String conversion for %s' % type
+            assert_equal(np.array(nstr, dtype=type), result, err_msg=msg)
+
+    def test_void(self):
+        arr = np.array([], dtype='V')
+        assert_equal(arr.dtype.kind, 'V')
+
+    def test_zeros(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((13,), dtype=dt)
+            assert_equal(np.count_nonzero(d), 0)
+            # true for ieee floats
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='4i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4, (2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+
+    @dec.slow
+    def test_zeros_big(self):
+        # test big array as they might be allocated different by the system
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((30 * 1024**2,), dtype=dt)
+            assert_(not d.any())
+            # This test can fail on 32-bit systems due to insufficient
+            # contiguous memory. Deallocating the previous array increases the
+            # chance of success.
+            del(d)
+
+    def test_zeros_obj(self):
+        # test initialization from PyLong(0)
+        d = np.zeros((13,), dtype=object)
+        assert_array_equal(d, [0] * 13)
+        assert_equal(np.count_nonzero(d), 0)
+
+    def test_zeros_obj_obj(self):
+        d = np.zeros(10, dtype=[('k', object, 2)])
+        assert_array_equal(d['k'], 0)
+
+    def test_zeros_like_like_zeros(self):
+        # test zeros_like returns the same as zeros
+        for c in np.typecodes['All']:
+            if c == 'V':
+                continue
+            d = np.zeros((3,3), dtype=c)
+            assert_array_equal(np.zeros_like(d), d)
+            assert_equal(np.zeros_like(d).dtype, d.dtype)
+        # explicitly check some special cases
+        d = np.zeros((3,3), dtype='S5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='U5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='f4,f4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+    def test_empty_unicode(self):
+        # don't throw decode errors on garbage memory
+        for i in range(5, 100, 5):
+            d = np.empty(i, dtype='U')
+            str(d)
+
+    def test_sequence_non_homogenous(self):
+        assert_equal(np.array([4, 2**80]).dtype, np.object)
+        assert_equal(np.array([4, 2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80] * 3).dtype, np.object)
+        assert_equal(np.array([[1, 1],[1j, 1j]]).dtype, np.complex)
+        assert_equal(np.array([[1j, 1j],[1, 1]]).dtype, np.complex)
+        assert_equal(np.array([[1, 1, 1],[1, 1j, 1.], [1, 1, 1]]).dtype, np.complex)
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_sequence_long(self):
+        assert_equal(np.array([long(4), long(4)]).dtype, np.long)
+        assert_equal(np.array([long(4), 2**80]).dtype, np.object)
+        assert_equal(np.array([long(4), 2**80, long(4)]).dtype, np.object)
+        assert_equal(np.array([2**80, long(4)]).dtype, np.object)
+
+    def test_non_sequence_sequence(self):
+        """Should not segfault.
+
+        Class Fail breaks the sequence protocol for new style classes, i.e.,
+        those derived from object. Class Map is a mapping type indicated by
+        raising a ValueError. At some point we may raise a warning instead
+        of an error in the Fail case.
+
+        """
+        class Fail(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise ValueError()
+
+        class Map(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise KeyError()
+
+        a = np.array([Map()])
+        assert_(a.shape == (1,))
+        assert_(a.dtype == np.dtype(object))
+        assert_raises(ValueError, np.array, [Fail()])
+
+    def test_no_len_object_type(self):
+        # gh-5100, want object array from iterable object without len()
+        class Point2:
+            def __init__(self):
+                pass
+
+            def __getitem__(self, ind):
+                if ind in [0, 1]:
+                    return ind
+                else:
+                    raise IndexError()
+        d = np.array([Point2(), Point2(), Point2()])
+        assert_equal(d.dtype, np.dtype(object))
+
+    def test_false_len_sequence(self):
+        # gh-7264, segfault for this example
+        class C:
+            def __getitem__(self, i):
+                raise IndexError
+            def __len__(self):
+                return 42
+
+        assert_raises(ValueError, np.array, C()) # segfault?
+
+    def test_failed_len_sequence(self):
+        # gh-7393
+        class A(object):
+            def __init__(self, data):
+                self._data = data
+            def __getitem__(self, item):
+                return type(self)(self._data[item])
+            def __len__(self):
+                return len(self._data)
+
+        # len(d) should give 3, but len(d[0]) will fail
+        d = A([1,2,3])
+        assert_equal(len(np.array(d)), 3)
+
+
+class TestStructured(TestCase):
+    def test_subarray_field_access(self):
+        a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
+        a['a'] = np.arange(60).reshape(3, 5, 2, 2)
+
+        # Since the subarray is always in C-order, a transpose
+        # does not swap the subarray:
+        assert_array_equal(a.T['a'], a['a'].transpose(1, 0, 2, 3))
+
+        # In Fortran order, the subarray gets appended
+        # like in all other cases, not prepended as a special case
+        b = a.copy(order='F')
+        assert_equal(a['a'].shape, b['a'].shape)
+        assert_equal(a.T['a'].shape, a.T.copy()['a'].shape)
+
+    def test_subarray_comparison(self):
+        # Check that comparisons between record arrays with
+        # multi-dimensional field types work properly
+        a = np.rec.fromrecords(
+            [([1, 2, 3], 'a', [[1, 2], [3, 4]]), ([3, 3, 3], 'b', [[0, 0], [0, 0]])],
+            dtype=[('a', ('f4', 3)), ('b', np.object), ('c', ('i4', (2, 2)))])
+        b = a.copy()
+        assert_equal(a == b, [True, True])
+        assert_equal(a != b, [False, False])
+        b[1].b = 'c'
+        assert_equal(a == b, [True, False])
+        assert_equal(a != b, [False, True])
+        for i in range(3):
+            b[0].a = a[0].a
+            b[0].a[i] = 5
+            assert_equal(a == b, [False, False])
+            assert_equal(a != b, [True, True])
+        for i in range(2):
+            for j in range(2):
+                b = a.copy()
+                b[0].c[i, j] = 10
+                assert_equal(a == b, [False, True])
+                assert_equal(a != b, [True, False])
+
+        # Check that broadcasting with a subarray works
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8')])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8')])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8', (1,))])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8', (1,))])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))])
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that broadcasting Fortran-style arrays with a subarray work
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))], order='F')
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that incompatible sub-array shapes don't result to broadcasting
+        x = np.zeros((1,), dtype=[('a', ('f4', (1, 2))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        # Check that structured arrays that are different only in
+        # byte-order work
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i8'), ('b', '<f8')])
+        b = np.array([(5, 43), (10, 1)], dtype=[('a', '<i8'), ('b', '>f8')])
+        assert_equal(a == b, [False, True])
+
+    def test_casting(self):
+        # Check that casting a structured array to change its byte order
+        # works
+        a = np.array([(1,)], dtype=[('a', '<i4')])
+        assert_(np.can_cast(a.dtype, [('a', '>i4')], casting='unsafe'))
+        b = a.astype([('a', '>i4')])
+        assert_equal(b, a.byteswap().newbyteorder())
+        assert_equal(a['a'][0], b['a'][0])
+
+        # Check that equality comparison works on structured arrays if
+        # they are 'equiv'-castable
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', '<f8')])
+        b = np.array([(42, 5), (1, 10)], dtype=[('b', '>f8'), ('a', '<i4')])
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        assert_equal(a == b, [True, True])
+
+        # Check that 'equiv' casting can reorder fields and change byte
+        # order
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        c = a.astype(b.dtype, casting='equiv')
+        assert_equal(a == c, [True, True])
+
+        # Check that 'safe' casting can change byte order and up-cast
+        # fields
+        t = [('a', '<i8'), ('b', '>f8')]
+        assert_(np.can_cast(a.dtype, t, casting='safe'))
+        c = a.astype(t, casting='safe')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that 'same_kind' casting can change byte order and
+        # change field widths within a "kind"
+        t = [('a', '<i4'), ('b', '>f4')]
+        assert_(np.can_cast(a.dtype, t, casting='same_kind'))
+        c = a.astype(t, casting='same_kind')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that casting fails if the casting rule should fail on
+        # any of the fields
+        t = [('a', '>i8'), ('b', '<f4')]
+        assert_(not np.can_cast(a.dtype, t, casting='safe'))
+        assert_raises(TypeError, a.astype, t, casting='safe')
+        t = [('a', '>i2'), ('b', '<f8')]
+        assert_(not np.can_cast(a.dtype, t, casting='equiv'))
+        assert_raises(TypeError, a.astype, t, casting='equiv')
+        t = [('a', '>i8'), ('b', '<i2')]
+        assert_(not np.can_cast(a.dtype, t, casting='same_kind'))
+        assert_raises(TypeError, a.astype, t, casting='same_kind')
+        assert_(not np.can_cast(a.dtype, b.dtype, casting='no'))
+        assert_raises(TypeError, a.astype, b.dtype, casting='no')
+
+        # Check that non-'unsafe' casting can't change the set of field names
+        for casting in ['no', 'safe', 'equiv', 'same_kind']:
+            t = [('a', '>i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+            t = [('a', '>i4'), ('b', '<f8'), ('c', 'i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+
+    def test_objview(self):
+        # https://github.com/numpy/numpy/issues/3286
+        a = np.array([], dtype=[('a', 'f'), ('b', 'f'), ('c', 'O')])
+        a[['a', 'b']]  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3253
+        dat2 = np.zeros(3, [('A', 'i'), ('B', '|O')])
+        dat2[['B', 'A']]  # TypeError?
+
+    def test_setfield(self):
+        # https://github.com/numpy/numpy/issues/3126
+        struct_dt = np.dtype([('elem', 'i4', 5),])
+        dt = np.dtype([('field', 'i4', 10),('struct', struct_dt)])
+        x = np.zeros(1, dt)
+        x[0]['field'] = np.ones(10, dtype='i4')
+        x[0]['struct'] = np.ones(1, dtype=struct_dt)
+        assert_equal(x[0]['field'], np.ones(10, dtype='i4'))
+
+    def test_setfield_object(self):
+        # make sure object field assignment with ndarray value
+        # on void scalar mimics setitem behavior
+        b = np.zeros(1, dtype=[('x', 'O')])
+        # next line should work identically to b['x'][0] = np.arange(3)
+        b[0]['x'] = np.arange(3)
+        assert_equal(b[0]['x'], np.arange(3))
+
+        # check that broadcasting check still works
+        c = np.zeros(1, dtype=[('x', 'O', 5)])
+
+        def testassign():
+            c[0]['x'] = np.arange(3)
+
+        assert_raises(ValueError, testassign)
+
+
+class TestBool(TestCase):
+    def test_test_interning(self):
+        a0 = np.bool_(0)
+        b0 = np.bool_(False)
+        self.assertTrue(a0 is b0)
+        a1 = np.bool_(1)
+        b1 = np.bool_(True)
+        self.assertTrue(a1 is b1)
+        self.assertTrue(np.array([True])[0] is a1)
+        self.assertTrue(np.array(True)[()] is a1)
+
+    def test_sum(self):
+        d = np.ones(101, dtype=np.bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+        d = np.frombuffer(b'\xff\xff' * 100, dtype=bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+    def check_count_nonzero(self, power, length):
+        powers = [2 ** i for i in range(length)]
+        for i in range(2**power):
+            l = [(i & x) != 0 for x in powers]
+            a = np.array(l, dtype=np.bool)
+            c = builtins.sum(l)
+            self.assertEqual(np.count_nonzero(a), c)
+            av = a.view(np.uint8)
+            av *= 3
+            self.assertEqual(np.count_nonzero(a), c)
+            av *= 4
+            self.assertEqual(np.count_nonzero(a), c)
+            av[av != 0] = 0xFF
+            self.assertEqual(np.count_nonzero(a), c)
+
+    def test_count_nonzero(self):
+        # check all 12 bit combinations in a length 17 array
+        # covers most cases of the 16 byte unrolled code
+        self.check_count_nonzero(12, 17)
+
+    @dec.slow
+    def test_count_nonzero_all(self):
+        # check all combinations in a length 17 array
+        # covers all cases of the 16 byte unrolled code
+        self.check_count_nonzero(17, 17)
+
+    def test_count_nonzero_unaligned(self):
+        # prevent mistakes as e.g. gh-4060
+        for o in range(7):
+            a = np.zeros((18,), dtype=np.bool)[o+1:]
+            a[:o] = True
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+            a = np.ones((18,), dtype=np.bool)[o+1:]
+            a[:o] = False
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+
+
+class TestMethods(TestCase):
+    def test_compress(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = arr.compress([0, 1, 0, 1, 0], axis=1)
+        assert_equal(out, tgt)
+
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=1)
+        assert_equal(out, tgt)
+
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1])
+        assert_equal(out, 1)
+
+    def test_choose(self):
+        x = 2*np.ones((3,), dtype=int)
+        y = 3*np.ones((3,), dtype=int)
+        x2 = 2*np.ones((2, 3), dtype=int)
+        y2 = 3*np.ones((2, 3), dtype=int)
+        ind = np.array([0, 0, 1])
+
+        A = ind.choose((x, y))
+        assert_equal(A, [2, 2, 3])
+
+        A = ind.choose((x2, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+        A = ind.choose((x, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_prod(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, a.prod)
+                self.assertRaises(ArithmeticError, a2.prod, axis=1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+    def test_repeat(self):
+        m = np.array([1, 2, 3, 4, 5, 6])
+        m_rect = m.reshape((2, 3))
+
+        A = m.repeat([1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+        A = m.repeat(2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+        A = m_rect.repeat([2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat([1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+        A = m_rect.repeat(2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat(2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+    def test_reshape(self):
+        arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
+
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(arr.reshape(2, 6), tgt)
+
+        tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
+        assert_equal(arr.reshape(3, 4), tgt)
+
+        tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
+        assert_equal(arr.reshape((3, 4), order='F'), tgt)
+
+        tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
+        assert_equal(arr.T.reshape((3, 4), order='C'), tgt)
+
+    def test_round(self):
+        def check_round(arr, expected, *round_args):
+            assert_equal(arr.round(*round_args), expected)
+            # With output array
+            out = np.zeros_like(arr)
+            res = arr.round(*round_args, out=out)
+            assert_equal(out, expected)
+            assert_equal(out, res)
+
+        check_round(np.array([1.2, 1.5]), [1, 2])
+        check_round(np.array(1.5), 2)
+        check_round(np.array([12.2, 15.5]), [10, 20], -1)
+        check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1)
+        # Complex rounding
+        check_round(np.array([4.5 + 1.5j]), [4 + 2j])
+        check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1)
+
+    def test_squeeze(self):
+        a = np.array([[[1], [2], [3]]])
+        assert_equal(a.squeeze(), [1, 2, 3])
+        assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]])
+        assert_raises(ValueError, a.squeeze, axis=(1,))
+        assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]])
+
+    def test_transpose(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(a.transpose(), [[1, 3], [2, 4]])
+        self.assertRaises(ValueError, lambda: a.transpose(0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 1, 2))
+
+    def test_sort(self):
+        # test ordering for floats and complex containing nans. It is only
+        # necessary to check the less-than comparison, so sorts that
+        # only follow the insertion sort path are sufficient. We only
+        # test doubles and complex doubles as the logic is the same.
+
+        # check doubles
+        msg = "Test real sort order with nans"
+        a = np.array([np.nan, 1, 0])
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+        # check complex
+        msg = "Test complex sort order with nans"
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0]
+        a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0]
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+
+        # all c scalar sorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test complex sorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, real part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, imag part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+
+        # test sorting of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                c = arr.copy()
+                c.sort()
+                msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
+                assert_equal(c, arr, msg)
+
+        # test string sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "string sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test unicode sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test object array sorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test record array sorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test datetime64 sorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test timedelta64 sorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific sorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 0], [3, 2]])
+        c = np.array([[2, 3], [0, 1]])
+        d = a.copy()
+        d.sort(axis=0)
+        assert_equal(d, b, "test sort with axis=0")
+        d = a.copy()
+        d.sort(axis=1)
+        assert_equal(d, c, "test sort with axis=1")
+        d = a.copy()
+        d.sort()
+        assert_equal(d, c, "test sort with default axis")
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array sort with axis={0}'.format(axis)
+            assert_equal(np.sort(a, axis=axis), a, msg)
+        msg = 'test empty array sort with axis=None'
+        assert_equal(np.sort(a, axis=None), a.ravel(), msg)
+
+    def test_copy(self):
+        def assert_fortran(arr):
+            assert_(arr.flags.fortran)
+            assert_(arr.flags.f_contiguous)
+            assert_(not arr.flags.c_contiguous)
+
+        def assert_c(arr):
+            assert_(not arr.flags.fortran)
+            assert_(not arr.flags.f_contiguous)
+            assert_(arr.flags.c_contiguous)
+
+        a = np.empty((2, 2), order='F')
+        # Test copying a Fortran array
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_fortran(a.copy('A'))
+
+        # Now test starting with a C array.
+        a = np.empty((2, 2), order='C')
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_c(a.copy('A'))
+
+    def test_sort_order(self):
+        # Test sorting an array with fields
+        x1 = np.array([21, 32, 14])
+        x2 = np.array(['my', 'first', 'name'])
+        x3 = np.array([3.1, 4.5, 6.2])
+        r = np.rec.fromarrays([x1, x2, x3], names='id,word,number')
+
+        r.sort(order=['id'])
+        assert_equal(r.id, np.array([14, 21, 32]))
+        assert_equal(r.word, np.array(['name', 'my', 'first']))
+        assert_equal(r.number, np.array([6.2, 3.1, 4.5]))
+
+        r.sort(order=['word'])
+        assert_equal(r.id, np.array([32, 21, 14]))
+        assert_equal(r.word, np.array(['first', 'my', 'name']))
+        assert_equal(r.number, np.array([4.5, 3.1, 6.2]))
+
+        r.sort(order=['number'])
+        assert_equal(r.id, np.array([21, 32, 14]))
+        assert_equal(r.word, np.array(['my', 'first', 'name']))
+        assert_equal(r.number, np.array([3.1, 4.5, 6.2]))
+
+        if sys.byteorder == 'little':
+            strtype = '>i2'
+        else:
+            strtype = '<i2'
+        mydtype = [('name', strchar + '5'), ('col2', strtype)]
+        r = np.array([('a', 1), ('b', 255), ('c', 3), ('d', 258)],
+                     dtype=mydtype)
+        r.sort(order='col2')
+        assert_equal(r['col2'], [1, 3, 255, 258])
+        assert_equal(r, np.array([('a', 1), ('c', 3), ('b', 255), ('d', 258)],
+                                 dtype=mydtype))
+
+    def test_argsort(self):
+        # all c scalar argsorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), a, msg)
+            assert_equal(b.copy().argsort(kind=kind), b, msg)
+
+        # test complex argsorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+
+        # test argsort of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                msg = 'byte-swapped complex argsort, dtype={0}'.format(dt)
+                assert_equal(arr.argsort(),
+                             np.arange(len(arr), dtype=np.intp), msg)
+
+        # test string argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "string argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test unicode argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test object array argsorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "object argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test structured array argsorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "structured array argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test datetime64 argsorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test timedelta64 argsorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific argsorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 1], [0, 0]])
+        c = np.array([[1, 0], [1, 0]])
+        assert_equal(a.copy().argsort(axis=0), b)
+        assert_equal(a.copy().argsort(axis=1), c)
+        assert_equal(a.copy().argsort(), c)
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argsort with axis={0}'.format(axis)
+            assert_equal(np.argsort(a, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argsort with axis=None'
+        assert_equal(np.argsort(a, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+        # check that stable argsorts are stable
+        r = np.arange(100)
+        # scalars
+        a = np.zeros(100)
+        assert_equal(a.argsort(kind='m'), r)
+        # complex
+        a = np.zeros(100, dtype=np.complex)
+        assert_equal(a.argsort(kind='m'), r)
+        # string
+        a = np.array(['aaaaaaaaa' for i in range(100)])
+        assert_equal(a.argsort(kind='m'), r)
+        # unicode
+        a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode)
+        assert_equal(a.argsort(kind='m'), r)
+
+    def test_sort_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.sort, kind=k)
+        assert_raises(ValueError, d.argsort, kind=k)
+
+    def test_searchsorted(self):
+        # test for floats and complex containing nans. The logic is the
+        # same for all float types so only test double types for now.
+        # The search sorted routines use the compare functions for the
+        # array type, so this checks if that is consistent with the sort
+        # order.
+
+        # check double
+        a = np.array([0, 1, np.nan])
+        msg = "Test real searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(3), msg)
+        msg = "Test real searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 4), msg)
+        # check double complex
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan]
+        a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan]
+        msg = "Test complex searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(9), msg)
+        msg = "Test complex searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 10), msg)
+        msg = "Test searchsorted with little endian, side='l'"
+        a = np.array([0, 128], dtype='<i4')
+        b = a.searchsorted(np.array(128, dtype='<i4'))
+        assert_equal(b, 1, msg)
+        msg = "Test searchsorted with big endian, side='l'"
+        a = np.array([0, 128], dtype='>i4')
+        b = a.searchsorted(np.array(128, dtype='>i4'))
+        assert_equal(b, 1, msg)
+
+        # Check 0 elements
+        a = np.ones(0)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 0])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 0, 0])
+        a = np.ones(1)
+        # Check 1 element
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 1])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 1, 1])
+        # Check all elements equal
+        a = np.ones(2)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 2])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 2, 2])
+
+        # Test searching unaligned array
+        a = np.arange(10)
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        unaligned[:] = a
+        # Test searching unaligned array
+        b = unaligned.searchsorted(a, 'l')
+        assert_equal(b, a)
+        b = unaligned.searchsorted(a, 'r')
+        assert_equal(b, a + 1)
+        # Test searching for unaligned keys
+        b = a.searchsorted(unaligned, 'l')
+        assert_equal(b, a)
+        b = a.searchsorted(unaligned, 'r')
+        assert_equal(b, a + 1)
+
+        # Test smart resetting of binsearch indices
+        a = np.arange(5)
+        b = a.searchsorted([6, 5, 4], 'l')
+        assert_equal(b, [5, 5, 4])
+        b = a.searchsorted([6, 5, 4], 'r')
+        assert_equal(b, [5, 5, 5])
+
+        # Test all type specific binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.arange(2, dtype=dt)
+                out = np.arange(2)
+            else:
+                a = np.arange(0, 5, dtype=dt)
+                out = np.arange(5)
+            b = a.searchsorted(a, 'l')
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r')
+            assert_equal(b, out + 1)
+
+    def test_searchsorted_unicode(self):
+        # Test searchsorted on unicode strings.
+
+        # 1.6.1 contained a string length miscalculation in
+        # arraytypes.c.src:UNICODE_compare() which manifested as
+        # incorrect/inconsistent results from searchsorted.
+        a = np.array(['P:\\20x_dapi_cy3\\20x_dapi_cy3_20100185_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100186_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100187_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100189_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100190_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100191_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100192_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100193_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100194_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100195_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100196_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
+                     dtype=np.unicode)
+        ind = np.arange(len(a))
+        assert_equal([a.searchsorted(v, 'left') for v in a], ind)
+        assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
+        assert_equal([a.searchsorted(a[i], 'left') for i in ind], ind)
+        assert_equal([a.searchsorted(a[i], 'right') for i in ind], ind + 1)
+
+    def test_searchsorted_with_sorter(self):
+        a = np.array([5, 2, 1, 3, 4])
+        s = np.argsort(a)
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=(1, (2, 3)))
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=[1.1])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4, 5, 6])
+
+        # bounds check
+        assert_raises(ValueError, np.searchsorted, a, 4, sorter=[0, 1, 2, 3, 5])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[-1, 0, 1, 2, 3])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[4, 0, -1, 2, 3])
+
+        a = np.random.rand(300)
+        s = a.argsort()
+        b = np.sort(a)
+        k = np.linspace(0, 1, 20)
+        assert_equal(b.searchsorted(k), a.searchsorted(k, sorter=s))
+
+        a = np.array([0, 1, 2, 3, 5]*20)
+        s = a.argsort()
+        k = [0, 1, 2, 3, 5]
+        expected = [0, 20, 40, 60, 80]
+        assert_equal(a.searchsorted(k, side='l', sorter=s), expected)
+        expected = [20, 40, 60, 80, 100]
+        assert_equal(a.searchsorted(k, side='r', sorter=s), expected)
+
+        # Test searching unaligned array
+        keys = np.arange(10)
+        a = keys.copy()
+        np.random.shuffle(s)
+        s = a.argsort()
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        # Test searching unaligned array
+        unaligned[:] = a
+        b = unaligned.searchsorted(keys, 'l', s)
+        assert_equal(b, keys)
+        b = unaligned.searchsorted(keys, 'r', s)
+        assert_equal(b, keys + 1)
+        # Test searching for unaligned keys
+        unaligned[:] = keys
+        b = a.searchsorted(unaligned, 'l', s)
+        assert_equal(b, keys)
+        b = a.searchsorted(unaligned, 'r', s)
+        assert_equal(b, keys + 1)
+
+        # Test all type specific indirect binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.array([1, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([1, 0], dtype=np.int16)
+                out = np.array([1, 0])
+            else:
+                a = np.array([3, 4, 1, 2, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([4, 2, 3, 0, 1], dtype=np.int16)
+                out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+            b = a.searchsorted(a, 'l', s)
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r', s)
+            assert_equal(b, out + 1)
+
+        # Test non-contiguous sorter array
+        a = np.array([3, 4, 1, 2, 0])
+        srt = np.empty((10,), dtype=np.intp)
+        srt[1::2] = -1
+        srt[::2] = [4, 2, 3, 0, 1]
+        s = srt[::2]
+        out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+        b = a.searchsorted(a, 'l', s)
+        assert_equal(b, out)
+        b = a.searchsorted(a, 'r', s)
+        assert_equal(b, out + 1)
+
+    def test_searchsorted_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        s = np.arange(5).view(A)
+        assert_(not isinstance(a.searchsorted(b, 'l'), A))
+        assert_(not isinstance(a.searchsorted(b, 'r'), A))
+        assert_(not isinstance(a.searchsorted(b, 'l', s), A))
+        assert_(not isinstance(a.searchsorted(b, 'r', s), A))
+
+    def test_argpartition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.argpartition, 10)
+        assert_raises(ValueError, d.argpartition, -11)
+        # Test also for generic type argpartition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.argpartition, 10)
+        assert_raises(ValueError, d_obj.argpartition, -11)
+
+    def test_partition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.partition, 10)
+        assert_raises(ValueError, d.partition, -11)
+        # Test also for generic type partition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.partition, 10)
+        assert_raises(ValueError, d_obj.partition, -11)
+
+    def test_partition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array partition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis), a, msg)
+        msg = 'test empty array partition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None), a.ravel(), msg)
+
+    def test_argpartition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argpartition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argpartition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+    def test_partition(self):
+        d = np.arange(10)
+        assert_raises(TypeError, np.partition, d, 2, kind=1)
+        assert_raises(ValueError, np.partition, d, 2, kind="nonsense")
+        assert_raises(ValueError, np.argpartition, d, 2, kind="nonsense")
+        assert_raises(ValueError, d.partition, 2, axis=0, kind="nonsense")
+        assert_raises(ValueError, d.argpartition, 2, axis=0, kind="nonsense")
+        for k in ("introselect",):
+            d = np.array([])
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(np.argpartition(d, 0, kind=k), d)
+            d = np.ones(1)
+            assert_array_equal(np.partition(d, 0, kind=k)[0], d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # kth not modified
+            kth = np.array([30, 15, 5])
+            okth = kth.copy()
+            np.partition(np.arange(40), kth)
+            assert_array_equal(kth, okth)
+
+            for r in ([2, 1], [1, 2], [1, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            for r in ([3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1],
+                      [1, 1, 1], [1, 2, 2], [2, 2, 1], [1, 2, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(np.partition(d, 2, kind=k)[2], tgt[2])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                assert_array_equal(d[np.argpartition(d, 2, kind=k)],
+                                   np.partition(d, 2, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            d = np.ones(50)
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # sorted
+            d = np.arange(49)
+            self.assertEqual(np.partition(d, 5, kind=k)[5], 5)
+            self.assertEqual(np.partition(d, 15, kind=k)[15], 15)
+            assert_array_equal(d[np.argpartition(d, 5, kind=k)],
+                               np.partition(d, 5, kind=k))
+            assert_array_equal(d[np.argpartition(d, 15, kind=k)],
+                               np.partition(d, 15, kind=k))
+
+            # rsorted
+            d = np.arange(47)[::-1]
+            self.assertEqual(np.partition(d, 6, kind=k)[6], 6)
+            self.assertEqual(np.partition(d, 16, kind=k)[16], 16)
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+
+            assert_array_equal(np.partition(d, -6, kind=k),
+                               np.partition(d, 41, kind=k))
+            assert_array_equal(np.partition(d, -16, kind=k),
+                               np.partition(d, 31, kind=k))
+            assert_array_equal(d[np.argpartition(d, -6, kind=k)],
+                               np.partition(d, 41, kind=k))
+
+            # median of 3 killer, O(n^2) on pure median 3 pivot quickselect
+            # exercises the median of median of 5 code used to keep O(n)
+            d = np.arange(1000000)
+            x = np.roll(d, d.size // 2)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+            d = np.arange(1000001)
+            x = np.roll(d, d.size // 2 + 1)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+
+            # max
+            d = np.ones(10)
+            d[1] = 4
+            assert_equal(np.partition(d, (2, -1))[-1], 4)
+            assert_equal(np.partition(d, (2, -1))[2], 1)
+            assert_equal(d[np.argpartition(d, (2, -1))][-1], 4)
+            assert_equal(d[np.argpartition(d, (2, -1))][2], 1)
+            d[1] = np.nan
+            assert_(np.isnan(d[np.argpartition(d, (2, -1))][-1]))
+            assert_(np.isnan(np.partition(d, (2, -1))[-1]))
+
+            # equal elements
+            d = np.arange(47) % 7
+            tgt = np.sort(np.arange(47) % 7)
+            np.random.shuffle(d)
+            for i in range(d.size):
+                self.assertEqual(np.partition(d, i, kind=k)[i], tgt[i])
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+            for i in range(d.size):
+                d[i:].partition(0, kind=k)
+            assert_array_equal(d, tgt)
+
+            d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                          7, 7, 7, 7, 7, 9])
+            kth = [0, 3, 19, 20]
+            assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
+            assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
+
+            d = np.array([2, 1])
+            d.partition(0, kind=k)
+            assert_raises(ValueError, d.partition, 2)
+            assert_raises(ValueError, d.partition, 3, axis=1)
+            assert_raises(ValueError, np.partition, d, 2)
+            assert_raises(ValueError, np.partition, d, 2, axis=1)
+            assert_raises(ValueError, d.argpartition, 2)
+            assert_raises(ValueError, d.argpartition, 3, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 2)
+            assert_raises(ValueError, np.argpartition, d, 2, axis=1)
+            d = np.arange(10).reshape((2, 5))
+            d.partition(1, axis=0, kind=k)
+            d.partition(4, axis=1, kind=k)
+            np.partition(d, 1, axis=0, kind=k)
+            np.partition(d, 4, axis=1, kind=k)
+            np.partition(d, 1, axis=None, kind=k)
+            np.partition(d, 9, axis=None, kind=k)
+            d.argpartition(1, axis=0, kind=k)
+            d.argpartition(4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=0, kind=k)
+            np.argpartition(d, 4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=None, kind=k)
+            np.argpartition(d, 9, axis=None, kind=k)
+            assert_raises(ValueError, d.partition, 2, axis=0)
+            assert_raises(ValueError, d.partition, 11, axis=1)
+            assert_raises(TypeError, d.partition, 2, axis=None)
+            assert_raises(ValueError, np.partition, d, 9, axis=1)
+            assert_raises(ValueError, np.partition, d, 11, axis=None)
+            assert_raises(ValueError, d.argpartition, 2, axis=0)
+            assert_raises(ValueError, d.argpartition, 11, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 9, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 11, axis=None)
+
+            td = [(dt, s) for dt in [np.int32, np.float32, np.complex64]
+                  for s in (9, 16)]
+            for dt, s in td:
+                aae = assert_array_equal
+                at = self.assertTrue
+
+                d = np.arange(s, dtype=dt)
+                np.random.shuffle(d)
+                d1 = np.tile(np.arange(s, dtype=dt), (4, 1))
+                map(np.random.shuffle, d1)
+                d0 = np.transpose(d1)
+                for i in range(d.size):
+                    p = np.partition(d, i, kind=k)
+                    self.assertEqual(p[i], i)
+                    # all before are smaller
+                    assert_array_less(p[:i], p[i])
+                    # all after are larger
+                    assert_array_less(p[i], p[i + 1:])
+                    aae(p, d[np.argpartition(d, i, kind=k)])
+
+                    p = np.partition(d1, i, axis=1, kind=k)
+                    aae(p[:, i], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:, :i].T <= p[:, i]).all(),
+                       msg="%d: %r <= %r" % (i, p[:, i], p[:, :i].T))
+                    at((p[:, i + 1:].T > p[:, i]).all(),
+                       msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T))
+                    aae(p, d1[np.arange(d1.shape[0])[:, None],
+                        np.argpartition(d1, i, axis=1, kind=k)])
+
+                    p = np.partition(d0, i, axis=0, kind=k)
+                    aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:i, :] <= p[i, :]).all(),
+                       msg="%d: %r <= %r" % (i, p[i, :], p[:i, :]))
+                    at((p[i + 1:, :] > p[i, :]).all(),
+                       msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:]))
+                    aae(p, d0[np.argpartition(d0, i, axis=0, kind=k),
+                        np.arange(d0.shape[1])[None, :]])
+
+                    # check inplace
+                    dc = d.copy()
+                    dc.partition(i, kind=k)
+                    assert_equal(dc, np.partition(d, i, kind=k))
+                    dc = d0.copy()
+                    dc.partition(i, axis=0, kind=k)
+                    assert_equal(dc, np.partition(d0, i, axis=0, kind=k))
+                    dc = d1.copy()
+                    dc.partition(i, axis=1, kind=k)
+                    assert_equal(dc, np.partition(d1, i, axis=1, kind=k))
+
+    def assert_partitioned(self, d, kth):
+        prev = 0
+        for k in np.sort(kth):
+            assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k)
+            assert_((d[k:] >= d[k]).all(),
+                    msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k]))
+            prev = k + 1
+
+    def test_partition_iterative(self):
+            d = np.arange(17)
+            kth = (0, 1, 2, 429, 231)
+            assert_raises(ValueError, d.partition, kth)
+            assert_raises(ValueError, d.argpartition, kth)
+            d = np.arange(10).reshape((2, 5))
+            assert_raises(ValueError, d.partition, kth, axis=0)
+            assert_raises(ValueError, d.partition, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=None)
+
+            d = np.array([3, 4, 2, 1])
+            p = np.partition(d, (0, 3))
+            self.assert_partitioned(p, (0, 3))
+            self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3))
+
+            assert_array_equal(p, np.partition(d, (-3, -1)))
+            assert_array_equal(p, d[np.argpartition(d, (-3, -1))])
+
+            d = np.arange(17)
+            np.random.shuffle(d)
+            d.partition(range(d.size))
+            assert_array_equal(np.arange(17), d)
+            np.random.shuffle(d)
+            assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))])
+
+            # test unsorted kth
+            d = np.arange(17)
+            np.random.shuffle(d)
+            keys = np.array([1, 3, 8, -2])
+            np.random.shuffle(d)
+            p = np.partition(d, keys)
+            self.assert_partitioned(p, keys)
+            p = d[np.argpartition(d, keys)]
+            self.assert_partitioned(p, keys)
+            np.random.shuffle(keys)
+            assert_array_equal(np.partition(d, keys), p)
+            assert_array_equal(d[np.argpartition(d, keys)], p)
+
+            # equal kth
+            d = np.arange(20)[::-1]
+            self.assert_partitioned(np.partition(d, [5]*4), [5])
+            self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]),
+                                    [5]*4 + [6, 13])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])],
+                                    [5]*4 + [6, 13])
+
+            d = np.arange(12)
+            np.random.shuffle(d)
+            d1 = np.tile(np.arange(12), (4, 1))
+            map(np.random.shuffle, d1)
+            d0 = np.transpose(d1)
+
+            kth = (1, 6, 7, -1)
+            p = np.partition(d1, kth, axis=1)
+            pa = d1[np.arange(d1.shape[0])[:, None],
+                    d1.argpartition(kth, axis=1)]
+            assert_array_equal(p, pa)
+            for i in range(d1.shape[0]):
+                self.assert_partitioned(p[i,:], kth)
+            p = np.partition(d0, kth, axis=0)
+            pa = d0[np.argpartition(d0, kth, axis=0),
+                    np.arange(d0.shape[1])[None,:]]
+            assert_array_equal(p, pa)
+            for i in range(d0.shape[1]):
+                self.assert_partitioned(p[:, i], kth)
+
+    def test_partition_cdtype(self):
+        d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+                   ('Lancelot', 1.9, 38)],
+                  dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+        tgt = np.sort(d, order=['age', 'height'])
+        assert_array_equal(np.partition(d, range(d.size),
+                                        order=['age', 'height']),
+                           tgt)
+        assert_array_equal(d[np.argpartition(d, range(d.size),
+                                             order=['age', 'height'])],
+                           tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k, order=['age', 'height'])[k],
+                        tgt[k])
+            assert_equal(d[np.argpartition(d, k, order=['age', 'height'])][k],
+                         tgt[k])
+
+        d = np.array(['Galahad', 'Arthur', 'zebra', 'Lancelot'])
+        tgt = np.sort(d)
+        assert_array_equal(np.partition(d, range(d.size)), tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k)[k], tgt[k])
+            assert_equal(d[np.argpartition(d, k)][k], tgt[k])
+
+    def test_partition_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.partition, 2, kind=k)
+        assert_raises(ValueError, d.argpartition, 2, kind=k)
+
+    def test_partition_fuzz(self):
+        # a few rounds of random data testing
+        for j in range(10, 30):
+            for i in range(1, j - 2):
+                d = np.arange(j)
+                np.random.shuffle(d)
+                d = d % np.random.randint(2, 30)
+                idx = np.random.randint(d.size)
+                kth = [0, idx, i, i + 1]
+                tgt = np.sort(d)[kth]
+                assert_array_equal(np.partition(d, kth)[kth], tgt,
+                                   err_msg="data: %r\n kth: %r" % (d, kth))
+
+    def test_argpartition_gh5524(self):
+        #  A test for functionality of argpartition on lists.
+        d = [6,7,3,2,9,0]
+        p = np.argpartition(d,1)
+        self.assert_partitioned(np.array(d)[p],[1])
+
+    def test_flatten(self):
+        x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
+        x1 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], np.int32)
+        y0 = np.array([1, 2, 3, 4, 5, 6], np.int32)
+        y0f = np.array([1, 4, 2, 5, 3, 6], np.int32)
+        y1 = np.array([1, 2, 3, 4, 5, 6, 7, 8], np.int32)
+        y1f = np.array([1, 5, 3, 7, 2, 6, 4, 8], np.int32)
+        assert_equal(x0.flatten(), y0)
+        assert_equal(x0.flatten('F'), y0f)
+        assert_equal(x0.flatten('F'), x0.T.flatten())
+        assert_equal(x1.flatten(), y1)
+        assert_equal(x1.flatten('F'), y1f)
+        assert_equal(x1.flatten('F'), x1.T.flatten())
+
+    def test_dot(self):
+        a = np.array([[1, 0], [0, 1]])
+        b = np.array([[0, 1], [1, 0]])
+        c = np.array([[9, 1], [1, -9]])
+        d = np.arange(24).reshape(4, 6)
+        ddt = np.array(
+            [[  55,  145,  235,  325],
+             [ 145,  451,  757, 1063],
+             [ 235,  757, 1279, 1801],
+             [ 325, 1063, 1801, 2539]]
+        )
+        dtd = np.array(
+            [[504, 540, 576, 612, 648, 684],
+             [540, 580, 620, 660, 700, 740],
+             [576, 620, 664, 708, 752, 796],
+             [612, 660, 708, 756, 804, 852],
+             [648, 700, 752, 804, 856, 908],
+             [684, 740, 796, 852, 908, 964]]
+        )
+
+
+        # gemm vs syrk optimizations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            assert_equal(np.dot(eaf, eaf), eaf)
+            assert_equal(np.dot(eaf.T, eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T.copy()), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf.T.copy()), eaf)
+
+        # syrk validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            ebf = b.astype(et)
+            assert_equal(np.dot(ebf, ebf), eaf)
+            assert_equal(np.dot(ebf.T, ebf), eaf)
+            assert_equal(np.dot(ebf, ebf.T), eaf)
+            assert_equal(np.dot(ebf.T, ebf.T), eaf)
+
+        # syrk - different shape, stride, and view validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            assert_equal(
+                np.dot(edf[::-1, :], edf.T),
+                np.dot(edf[::-1, :].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:, ::-1], edf.T),
+                np.dot(edf[:, ::-1].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[::-1, :].T),
+                np.dot(edf, edf[::-1, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[:, ::-1].T),
+                np.dot(edf, edf[:, ::-1].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:edf.shape[0] // 2, :], edf[::2, :].T),
+                np.dot(edf[:edf.shape[0] // 2, :].copy(), edf[::2, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[::2, :], edf[:edf.shape[0] // 2, :].T),
+                np.dot(edf[::2, :].copy(), edf[:edf.shape[0] // 2, :].T.copy())
+            )
+
+        # syrk - different shape
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            eddtf = ddt.astype(et)
+            edtdf = dtd.astype(et)
+            assert_equal(np.dot(edf, edf.T), eddtf)
+            assert_equal(np.dot(edf.T, edf), edtdf)
+
+        # function versus methods
+        assert_equal(np.dot(a, b), a.dot(b))
+        assert_equal(np.dot(np.dot(a, b), c), a.dot(b).dot(c))
+
+        # test passing in an output array
+        c = np.zeros_like(a)
+        a.dot(b, c)
+        assert_equal(c, np.dot(a, b))
+
+        # test keyword args
+        c = np.zeros_like(a)
+        a.dot(b=b, out=c)
+        assert_equal(c, np.dot(a, b))
+
+    def test_dot_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        b = B()
+        c = np.array([[1]])
+
+        assert_equal(np.dot(a, b), "A")
+        assert_equal(c.dot(a), "A")
+        assert_raises(TypeError, np.dot, b, c)
+        assert_raises(TypeError, c.dot, b)
+
+    def test_dot_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.dot, c, A)
+        assert_raises(TypeError, np.dot, A, c)
+
+    def test_diagonal(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.diagonal(), [0, 5, 10])
+        assert_equal(a.diagonal(0), [0, 5, 10])
+        assert_equal(a.diagonal(1), [1, 6, 11])
+        assert_equal(a.diagonal(-1), [4, 9])
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.diagonal(), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(0), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(1), [[2], [3]])
+        assert_equal(b.diagonal(-1), [[4], [5]])
+        assert_raises(ValueError, b.diagonal, axis1=0, axis2=0)
+        assert_equal(b.diagonal(0, 1, 2), [[0, 3], [4, 7]])
+        assert_equal(b.diagonal(0, 0, 1), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(offset=1, axis1=0, axis2=2), [[1], [3]])
+        # Order of axis argument doesn't matter:
+        assert_equal(b.diagonal(0, 2, 1), [[0, 3], [4, 7]])
+
+    def test_diagonal_view_notwriteable(self):
+        # this test is only for 1.9, the diagonal view will be
+        # writeable in 1.10.
+        a = np.eye(3).diagonal()
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diagonal(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diag(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+    def test_diagonal_memleak(self):
+        # Regression test for a bug that crept in at one point
+        a = np.zeros((100, 100))
+        assert_(sys.getrefcount(a) < 50)
+        for i in range(100):
+            a.diagonal()
+        assert_(sys.getrefcount(a) < 50)
+
+    def test_trace(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.trace(), 15)
+        assert_equal(a.trace(0), 15)
+        assert_equal(a.trace(1), 18)
+        assert_equal(a.trace(-1), 13)
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.trace(), [6, 8])
+        assert_equal(b.trace(0), [6, 8])
+        assert_equal(b.trace(1), [2, 3])
+        assert_equal(b.trace(-1), [4, 5])
+        assert_equal(b.trace(0, 0, 1), [6, 8])
+        assert_equal(b.trace(0, 0, 2), [5, 9])
+        assert_equal(b.trace(0, 1, 2), [3, 11])
+        assert_equal(b.trace(offset=1, axis1=0, axis2=2), [1, 3])
+
+    def test_trace_subclass(self):
+        # The class would need to overwrite trace to ensure single-element
+        # output also has the right subclass.
+        class MyArray(np.ndarray):
+            pass
+
+        b = np.arange(8).reshape((2, 2, 2)).view(MyArray)
+        t = b.trace()
+        assert isinstance(t, MyArray)
+
+    def test_put(self):
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+        for dt in icodes + fcodes + 'O':
+            tgt = np.array([0, 1, 0, 3, 0, 5], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt.reshape(2, 3))
+
+        for dt in '?':
+            tgt = np.array([False, True, False, True, False, True], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt.reshape(2, 3))
+
+        # check must be writeable
+        a = np.zeros(6)
+        a.flags.writeable = False
+        assert_raises(ValueError, a.put, [1, 3, 5], [1, 3, 5])
+
+        # when calling np.put, make sure a
+        # TypeError is raised if the object
+        # isn't an ndarray
+        bad_array = [1, 2, 3]
+        assert_raises(TypeError, np.put, bad_array, [0, 2], 5)
+
+    def test_ravel(self):
+        a = np.array([[0, 1], [2, 3]])
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_(not a.ravel().flags.owndata)
+        assert_equal(a.ravel('F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='C'), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='A'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_equal(a.ravel(order='K'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+
+        a = np.array([[0, 1], [2, 3]], order='F')
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='A'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='K'), [0, 2, 1, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+        assert_equal(a.ravel(order='A'), a.reshape(-1, order='A'))
+
+        a = np.array([[0, 1], [2, 3]])[::-1, :]
+        assert_equal(a.ravel(), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='C'), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='F'), [2, 0, 3, 1])
+        assert_equal(a.ravel(order='A'), [2, 3, 0, 1])
+        # 'K' doesn't reverse the axes of negative strides
+        assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
+        assert_(a.ravel(order='K').flags.owndata)
+
+        # Test simple 1-d copy behaviour:
+        a = np.arange(10)[::2]
+        assert_(a.ravel('K').flags.owndata)
+        assert_(a.ravel('C').flags.owndata)
+        assert_(a.ravel('F').flags.owndata)
+
+        # Not contiguous and 1-sized axis with non matching stride
+        a = np.arange(2**3 * 2)[::2]
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('K'), np.arange(0, 15, 2))
+
+        # contiguous and 1-sized axis with non matching stride works:
+        a = np.arange(2**3)
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(np.may_share_memory(a.ravel(order='K'), a))
+        assert_equal(a.ravel(order='K'), np.arange(2**3))
+
+        # Test negative strides (not very interesting since non-contiguous):
+        a = np.arange(4)[::-1].reshape(2, 2)
+        assert_(a.ravel(order='C').flags.owndata)
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('C'), [3, 2, 1, 0])
+        assert_equal(a.ravel('K'), [3, 2, 1, 0])
+
+        # 1-element tidy strides test (NPY_RELAXED_STRIDES_CHECKING):
+        a = np.array([[1]])
+        a.strides = (123, 432)
+        # If the stride is not 8, NPY_RELAXED_STRIDES_CHECKING is messing
+        # them up on purpose:
+        if np.ones(1).strides == (8,):
+            assert_(np.may_share_memory(a.ravel('K'), a))
+            assert_equal(a.ravel('K').strides, (a.dtype.itemsize,))
+
+        for order in ('C', 'F', 'A', 'K'):
+            # 0-d corner case:
+            a = np.array(0)
+            assert_equal(a.ravel(order), [0])
+            assert_(np.may_share_memory(a.ravel(order), a))
+
+        # Test that certain non-inplace ravels work right (mostly) for 'K':
+        b = np.arange(2**4 * 2)[::2].reshape(2, 2, 2, 2)
+        a = b[..., ::2]
+        assert_equal(a.ravel('K'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('C'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('A'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('F'), [0, 16, 8, 24, 4, 20, 12, 28])
+
+        a = b[::2, ...]
+        assert_equal(a.ravel('K'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('C'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('A'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('F'), [0, 8, 4, 12, 2, 10, 6, 14])
+
+    def test_ravel_subclass(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = np.arange(10).view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+        a = np.arange(10)[::2].view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+    def test_swapaxes(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        idx = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        b = a.copy()
+        # check exceptions
+        assert_raises(ValueError, a.swapaxes, -5, 0)
+        assert_raises(ValueError, a.swapaxes, 4, 0)
+        assert_raises(ValueError, a.swapaxes, 0, -5)
+        assert_raises(ValueError, a.swapaxes, 0, 4)
+
+        for i in range(-4, 4):
+            for j in range(-4, 4):
+                for k, src in enumerate((a, b)):
+                    c = src.swapaxes(i, j)
+                    # check shape
+                    shape = list(src.shape)
+                    shape[i] = src.shape[j]
+                    shape[j] = src.shape[i]
+                    assert_equal(c.shape, shape, str((i, j, k)))
+                    # check array contents
+                    i0, i1, i2, i3 = [dim-1 for dim in c.shape]
+                    j0, j1, j2, j3 = [dim-1 for dim in src.shape]
+                    assert_equal(src[idx[j0], idx[j1], idx[j2], idx[j3]],
+                                 c[idx[i0], idx[i1], idx[i2], idx[i3]],
+                                 str((i, j, k)))
+                    # check a view is always returned, gh-5260
+                    assert_(not c.flags['OWNDATA'], str((i, j, k)))
+                    # check on non-contiguous input array
+                    if k == 1:
+                        b = c
+
+    def test_conjugate(self):
+        a = np.array([1-1j, 1+1j, 23+23.0j])
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1, 2, 3])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1.0, 2.0, 3.0])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 1, 2.0], object)
+        ac = a.conj()
+        assert_equal(ac, [k.conjugate() for k in a])
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1, 2.0, 'f'], object)
+        assert_raises(AttributeError, lambda: a.conj())
+        assert_raises(AttributeError, lambda: a.conjugate())
+
+class TestBinop(object):
+    def test_inplace(self):
+        # test refcount 1 inplace conversion
+        assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
+                                  [0.5, 1.0])
+
+        d = np.array([0.5, 0.5])[::2]
+        assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
+                                  [0.25, 0.5])
+
+        a = np.array([0.5])
+        b = np.array([0.5])
+        c = a + b
+        c = a - b
+        c = a * b
+        c = a / b
+        assert_equal(a, b)
+        assert_almost_equal(c, 1.)
+
+        c = a + b * 2. / b * a - a / b
+        assert_equal(a, b)
+        assert_equal(c, 0.5)
+
+        # true divide
+        a = np.array([5])
+        b = np.array([3])
+        c = (a * a) / b
+
+        assert_almost_equal(c, 25 / 3)
+        assert_equal(a, 5)
+        assert_equal(b, 3)
+
+    def test_extension_incref_elide(self):
+        # test extension (e.g. cython) calling PyNumber_* slots without
+        # increasing the reference counts
+        #
+        # def incref_elide(a):
+        #    d = input.copy() # refcount 1
+        #    return d, d + d # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide
+        d = np.ones(5)
+        orig, res = incref_elide(d)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(orig, d)
+        assert_array_equal(res, d + d)
+
+    def test_extension_incref_elide_stack(self):
+        # scanning if the refcount == 1 object is on the python stack to check
+        # that we are called directly from python is flawed as object may still
+        # be above the stack pointer and we have no access to the top of it
+        #
+        # def incref_elide_l(d):
+        #    return l[4] + l[4] # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide_l
+        # padding with 1 makes sure the object on the stack is not overwriten
+        l = [1, 1, 1, 1, np.ones(5)]
+        res = incref_elide_l(l)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(l[4], np.ones(5))
+        assert_array_equal(res, l[4] + l[4])
+
+    def test_ufunc_override_rop_precedence(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that __rmul__ and other right-hand operations have
+        # precedence over __numpy_ufunc__
+
+        ops = {
+            '__add__':      ('__radd__', np.add, True),
+            '__sub__':      ('__rsub__', np.subtract, True),
+            '__mul__':      ('__rmul__', np.multiply, True),
+            '__truediv__':  ('__rtruediv__', np.true_divide, True),
+            '__floordiv__': ('__rfloordiv__', np.floor_divide, True),
+            '__mod__':      ('__rmod__', np.remainder, True),
+            '__divmod__':   ('__rdivmod__', None, False),
+            '__pow__':      ('__rpow__', np.power, True),
+            '__lshift__':   ('__rlshift__', np.left_shift, True),
+            '__rshift__':   ('__rrshift__', np.right_shift, True),
+            '__and__':      ('__rand__', np.bitwise_and, True),
+            '__xor__':      ('__rxor__', np.bitwise_xor, True),
+            '__or__':       ('__ror__', np.bitwise_or, True),
+            '__ge__':       ('__le__', np.less_equal, False),
+            '__gt__':       ('__lt__', np.less, False),
+            '__le__':       ('__ge__', np.greater_equal, False),
+            '__lt__':       ('__gt__', np.greater, False),
+            '__eq__':       ('__eq__', np.equal, False),
+            '__ne__':       ('__ne__', np.not_equal, False),
+        }
+
+        class OtherNdarraySubclass(np.ndarray):
+            pass
+
+        class OtherNdarraySubclassWithOverride(np.ndarray):
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+        def check(op_name, ndsubclass):
+            rop_name, np_op, has_iop = ops[op_name]
+
+            if has_iop:
+                iop_name = '__i' + op_name[2:]
+                iop = getattr(operator, iop_name)
+
+            if op_name == "__divmod__":
+                op = divmod
+            else:
+                op = getattr(operator, op_name)
+
+            # Dummy class
+            def __init__(self, *a, **kw):
+                pass
+
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+            def __op__(self, *other):
+                return "op"
+
+            def __rop__(self, *other):
+                return "rop"
+
+            if ndsubclass:
+                bases = (np.ndarray,)
+            else:
+                bases = (object,)
+
+            dct = {'__init__': __init__,
+                   '__numpy_ufunc__': __numpy_ufunc__,
+                   op_name: __op__}
+            if op_name != rop_name:
+                dct[rop_name] = __rop__
+
+            cls = type("Rop" + rop_name, bases, dct)
+
+            # Check behavior against both bare ndarray objects and a
+            # ndarray subclasses with and without their own override
+            obj = cls((1,), buffer=np.ones(1,))
+
+            arr_objs = [np.array([1]),
+                        np.array([2]).view(OtherNdarraySubclass),
+                        np.array([3]).view(OtherNdarraySubclassWithOverride),
+                        ]
+
+            for arr in arr_objs:
+                err_msg = "%r %r" % (op_name, arr,)
+
+                # Check that ndarray op gives up if it sees a non-subclass
+                if not isinstance(obj, arr.__class__):
+                    assert_equal(getattr(arr, op_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+
+                # Check that the Python binops have priority
+                assert_equal(op(obj, arr), "op", err_msg=err_msg)
+                if op_name == rop_name:
+                    assert_equal(op(arr, obj), "op", err_msg=err_msg)
+                else:
+                    assert_equal(op(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that Python binops have priority also for in-place ops
+                if has_iop:
+                    assert_equal(getattr(arr, iop_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+                    if op_name != "__pow__":
+                        # inplace pow requires the other object to be
+                        # integer-like?
+                        assert_equal(iop(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that ufunc call __numpy_ufunc__ normally
+                if np_op is not None:
+                    assert_raises(AssertionError, np_op, arr, obj,
+                                  err_msg=err_msg)
+                    assert_raises(AssertionError, np_op, obj, arr,
+                                  err_msg=err_msg)
+
+        # Check all binary operations
+        for op_name in sorted(ops.keys()):
+            yield check, op_name, True
+            yield check, op_name, False
+
+    def test_ufunc_override_rop_simple(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check parts of the binary op overriding behavior in an
+        # explicit test case that is easier to understand.
+        class SomeClass(object):
+            def __numpy_ufunc__(self, *a, **kw):
+                return "ufunc"
+
+            def __mul__(self, other):
+                return 123
+
+            def __rmul__(self, other):
+                return 321
+
+            def __rsub__(self, other):
+                return "no subs for me"
+
+            def __gt__(self, other):
+                return "yep"
+
+            def __lt__(self, other):
+                return "nope"
+
+        class SomeClass2(SomeClass, np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if ufunc is np.multiply or ufunc is np.bitwise_and:
+                    return "ufunc"
+                else:
+                    inputs = list(inputs)
+                    if i < len(inputs):
+                        inputs[i] = np.asarray(self)
+                    func = getattr(ufunc, method)
+                    if ('out' in kw) and (kw['out'] is not None):
+                        kw['out'] = np.asarray(kw['out'])
+                    r = func(*inputs, **kw)
+                    x = self.__class__(r.shape, dtype=r.dtype)
+                    x[...] = r
+                    return x
+
+        class SomeClass3(SomeClass2):
+            def __rsub__(self, other):
+                return "sub for me"
+
+        arr = np.array([0])
+        obj = SomeClass()
+        obj2 = SomeClass2((1,), dtype=np.int_)
+        obj2[0] = 9
+        obj3 = SomeClass3((1,), dtype=np.int_)
+        obj3[0] = 4
+
+        # obj is first, so should get to define outcome.
+        assert_equal(obj * arr, 123)
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        assert_equal(arr * obj, 321)
+        # obj is second, but has __numpy_ufunc__ and defines __rsub__.
+        assert_equal(arr - obj, "no subs for me")
+        # obj is second, but has __numpy_ufunc__ and defines __lt__.
+        assert_equal(arr > obj, "nope")
+        # obj is second, but has __numpy_ufunc__ and defines __gt__.
+        assert_equal(arr < obj, "yep")
+        # Called as a ufunc, obj.__numpy_ufunc__ is used.
+        assert_equal(np.multiply(arr, obj), "ufunc")
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        arr *= obj
+        assert_equal(arr, 321)
+
+        # obj2 is an ndarray subclass, so CPython takes care of the same rules.
+        assert_equal(obj2 * arr, 123)
+        assert_equal(arr * obj2, 321)
+        assert_equal(arr - obj2, "no subs for me")
+        assert_equal(arr > obj2, "nope")
+        assert_equal(arr < obj2, "yep")
+        # Called as a ufunc, obj2.__numpy_ufunc__ is called.
+        assert_equal(np.multiply(arr, obj2), "ufunc")
+        # Also when the method is not overridden.
+        assert_equal(arr & obj2, "ufunc")
+        arr *= obj2
+        assert_equal(arr, 321)
+
+        obj2 += 33
+        assert_equal(obj2[0], 42)
+        assert_equal(obj2.sum(), 42)
+        assert_(isinstance(obj2, SomeClass2))
+
+        # Obj3 is subclass that defines __rsub__.  CPython calls it.
+        assert_equal(arr - obj3, "sub for me")
+        assert_equal(obj2 - obj3, "sub for me")
+        # obj3 is a subclass that defines __rmul__.  CPython calls it.
+        assert_equal(arr * obj3, 321)
+        # But not here, since obj3.__rmul__ is obj2.__rmul__.
+        assert_equal(obj2 * obj3, 123)
+        # And of course, here obj3.__mul__ should be called.
+        assert_equal(obj3 * obj2, 123)
+        # obj3 defines __numpy_ufunc__ but obj3.__radd__ is obj2.__radd__.
+        # (and both are just ndarray.__radd__); see #4815.
+        res = obj2 + obj3
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass2))
+        # Since obj3 is a subclass, it should have precedence, like CPython
+        # would give, even though obj2 has __numpy_ufunc__ and __radd__.
+        # See gh-4815 and gh-5747.
+        res = obj3 + obj2
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass3))
+
+    def test_ufunc_override_normalize_signature(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # gh-5674
+        class SomeClass(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return kw
+
+        a = SomeClass()
+        kw = np.add(a, [1])
+        assert_('sig' not in kw and 'signature' not in kw)
+        kw = np.add(a, [1], sig='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+        kw = np.add(a, [1], signature='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+
+    def test_numpy_ufunc_index(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that index is set appropriately, also if only an output
+        # is passed on (latter is another regression tests for github bug 4753)
+        class CheckIndex(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return i
+
+        a = CheckIndex()
+        dummy = np.arange(2.)
+        # 1 input, 1 output
+        assert_equal(np.sin(a), 0)
+        assert_equal(np.sin(dummy, a), 1)
+        assert_equal(np.sin(dummy, out=a), 1)
+        assert_equal(np.sin(dummy, out=(a,)), 1)
+        assert_equal(np.sin(a, a), 0)
+        assert_equal(np.sin(a, out=a), 0)
+        assert_equal(np.sin(a, out=(a,)), 0)
+        # 1 input, 2 outputs
+        assert_equal(np.modf(dummy, a), 1)
+        assert_equal(np.modf(dummy, None, a), 2)
+        assert_equal(np.modf(dummy, dummy, a), 2)
+        assert_equal(np.modf(dummy, out=a), 1)
+        assert_equal(np.modf(dummy, out=(a,)), 1)
+        assert_equal(np.modf(dummy, out=(a, None)), 1)
+        assert_equal(np.modf(dummy, out=(a, dummy)), 1)
+        assert_equal(np.modf(dummy, out=(None, a)), 2)
+        assert_equal(np.modf(dummy, out=(dummy, a)), 2)
+        assert_equal(np.modf(a, out=(dummy, a)), 0)
+        # 2 inputs, 1 output
+        assert_equal(np.add(a, dummy), 0)
+        assert_equal(np.add(dummy, a), 1)
+        assert_equal(np.add(dummy, dummy, a), 2)
+        assert_equal(np.add(dummy, a, a), 1)
+        assert_equal(np.add(dummy, dummy, out=a), 2)
+        assert_equal(np.add(dummy, dummy, out=(a,)), 2)
+        assert_equal(np.add(a, dummy, out=a), 0)
+
+    def test_out_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # regression test for github bug 4753
+        class OutClass(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if 'out' in kw:
+                    tmp_kw = kw.copy()
+                    tmp_kw.pop('out')
+                    func = getattr(ufunc, method)
+                    kw['out'][...] = func(*inputs, **tmp_kw)
+
+        A = np.array([0]).view(OutClass)
+        B = np.array([5])
+        C = np.array([6])
+        np.multiply(C, B, A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+        A[0] = 0
+        np.multiply(C, B, out=A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+
+
+class TestCAPI(TestCase):
+    def test_IsPythonScalar(self):
+        from numpy.core.multiarray_tests import IsPythonScalar
+        assert_(IsPythonScalar(b'foobar'))
+        assert_(IsPythonScalar(1))
+        assert_(IsPythonScalar(2**80))
+        assert_(IsPythonScalar(2.))
+        assert_(IsPythonScalar("a"))
+
+
+class TestSubscripting(TestCase):
+    def test_test_zero_rank(self):
+        x = np.array([1, 2, 3])
+        self.assertTrue(isinstance(x[0], np.int_))
+        if sys.version_info[0] < 3:
+            self.assertTrue(isinstance(x[0], int))
+        self.assertTrue(type(x[0, ...]) is np.ndarray)
+
+
+class TestPickling(TestCase):
+    def test_roundtrip(self):
+        import pickle
+        carray = np.array([[2, 9], [7, 0], [3, 8]])
+        DATA = [
+            carray,
+            np.transpose(carray),
+            np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int),
+                                               ('c', float)])
+        ]
+
+        for a in DATA:
+            assert_equal(a, pickle.loads(a.dumps()), err_msg="%r" % a)
+
+    def _loads(self, obj):
+        if sys.version_info[0] >= 3:
+            return np.loads(obj, encoding='latin1')
+        else:
+            return np.loads(obj)
+
+    # version 0 pickles, using protocol=2 to pickle
+    # version 0 doesn't have a version field
+    def test_version0_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    # version 1 pickles, using protocol=2 to pickle
+    def test_version1_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(K\x01U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_subarray_int_shape(self):
+        s = "cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'V6'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'a'\np12\ng3\ntp13\n(dp14\ng12\n(g7\n(S'V4'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'|'\np18\n(g7\n(S'i1'\np19\nI0\nI1\ntp20\nRp21\n(I3\nS'|'\np22\nNNNI-1\nI-1\nI0\ntp23\nb(I2\nI2\ntp24\ntp25\nNNI4\nI1\nI0\ntp26\nbI0\ntp27\nsg3\n(g7\n(S'V2'\np28\nI0\nI1\ntp29\nRp30\n(I3\nS'|'\np31\n(g21\nI2\ntp32\nNNI2\nI1\nI0\ntp33\nbI4\ntp34\nsI6\nI1\nI0\ntp35\nbI00\nS'\\x01\\x01\\x01\\x01\\x01\\x02'\np36\ntp37\nb."
+        a = np.array([(1, (1, 2))], dtype=[('a', 'i1', (2, 2)), ('b', 'i1', 2)])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+
+class TestFancyIndexing(TestCase):
+    def test_list(self):
+        x = np.ones((1, 1))
+        x[:, [0]] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+
+        x = np.ones((1, 1, 1))
+        x[:, :, [0]] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_tuple(self):
+        x = np.ones((1, 1))
+        x[:, (0,)] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+        x = np.ones((1, 1, 1))
+        x[:, :, (0,)] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        assert_array_equal(x[m], np.array([2]))
+
+    def test_mask2(self):
+        x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        assert_array_equal(x[m], np.array([[5, 6, 7, 8]]))
+        assert_array_equal(x[m2], np.array([2, 5]))
+        assert_array_equal(x[m3], np.array([2]))
+
+    def test_assign_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        x[m] = 5
+        assert_array_equal(x, np.array([1, 5, 3, 4]))
+
+    def test_assign_mask2(self):
+        xorig = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        x = xorig.copy()
+        x[m] = 10
+        assert_array_equal(x, np.array([[1, 2, 3, 4], [10, 10, 10, 10]]))
+        x = xorig.copy()
+        x[m2] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [10, 6, 7, 8]]))
+        x = xorig.copy()
+        x[m3] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [5, 6, 7, 8]]))
+
+
+class TestStringCompare(TestCase):
+    def test_string(self):
+        g1 = np.array(["This", "is", "example"])
+        g2 = np.array(["This", "was", "example"])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
+
+    def test_mixed(self):
+        g1 = np.array(["spam", "spa", "spammer", "and eggs"])
+        g2 = "spam"
+        assert_array_equal(g1 == g2, [x == g2 for x in g1])
+        assert_array_equal(g1 != g2, [x != g2 for x in g1])
+        assert_array_equal(g1 < g2, [x < g2 for x in g1])
+        assert_array_equal(g1 > g2, [x > g2 for x in g1])
+        assert_array_equal(g1 <= g2, [x <= g2 for x in g1])
+        assert_array_equal(g1 >= g2, [x >= g2 for x in g1])
+
+    def test_unicode(self):
+        g1 = np.array([sixu("This"), sixu("is"), sixu("example")])
+        g2 = np.array([sixu("This"), sixu("was"), sixu("example")])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2,  [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2,  [g1[i] > g2[i] for i in [0, 1, 2]])
+
+
+class TestArgmax(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 5),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2015-11-20T12:20:59'),
+          np.datetime64('1932-09-23T10:10:13'),
+          np.datetime64('2014-10-10T03:50:30')], 3),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 4),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 0),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 3),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 0),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 1),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 2),
+
+        ([False, False, False, False, True], 4),
+        ([False, False, False, True, False], 3),
+        ([True, False, False, False, False], 0),
+        ([True, False, True, False, False], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amax = a.max(i)
+            aargmax = a.argmax(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmax(arr)], np.max(arr), err_msg="%r" % arr)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmax(-1, out=out)
+        assert_equal(out, a.argmax(-1))
+
+    def test_argmax_unicode(self):
+        d = np.zeros(6031, dtype='<U9')
+        d[5942] = "as"
+        assert_equal(d.argmax(), 5942)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmax and numpy.argmax support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.zeros(2, dtype=int)
+        assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.zeros(3, dtype=int)
+        assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmax_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmax(), 0)
+        a[3] = 10
+        assert_equal(a.argmax(), 3)
+        a[1] = 30
+        assert_equal(a.argmax(), 1)
+
+
+class TestArgmin(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 2),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 1),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 0),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2014-11-20T12:20:59'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 4),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 1),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 2),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 0),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 1),
+
+        ([True, True, True, True, False], 4),
+        ([True, True, True, False, True], 3),
+        ([False, True, True, True, True], 0),
+        ([False, True, False, True, True], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amin = a.min(i)
+            aargmin = a.argmin(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmin(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmin(arr)], np.min(arr), err_msg="%r" % arr)
+
+    def test_minimum_signed_integers(self):
+
+        a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
+        assert_equal(np.argmin(a), 1)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmin(-1, out=out)
+        assert_equal(out, a.argmin(-1))
+
+    def test_argmin_unicode(self):
+        d = np.ones(6031, dtype='<U9')
+        d[6001] = "0"
+        assert_equal(d.argmin(), 6001)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmin and numpy.argmin support out/axis args
+        a = np.random.normal(size=(2, 3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.ones(2, dtype=int)
+        assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.ones(3, dtype=int)
+        assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmin_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmin(), 0)
+        a[3] = 30
+        assert_equal(a.argmin(), 3)
+        a[1] = 10
+        assert_equal(a.argmin(), 1)
+
+
+class TestMinMax(TestCase):
+
+    def test_scalar(self):
+        assert_raises(ValueError, np.amax, 1, 1)
+        assert_raises(ValueError, np.amin, 1, 1)
+
+        assert_equal(np.amax(1, axis=0), 1)
+        assert_equal(np.amin(1, axis=0), 1)
+        assert_equal(np.amax(1, axis=None), 1)
+        assert_equal(np.amin(1, axis=None), 1)
+
+    def test_axis(self):
+        assert_raises(ValueError, np.amax, [1, 2, 3], 1000)
+        assert_equal(np.amax([[1, 2, 3]], axis=1), 3)
+
+    def test_datetime(self):
+        # NaTs are ignored
+        for dtype in ('m8[s]', 'm8[Y]'):
+            a = np.arange(10).astype(dtype)
+            a[3] = 'NaT'
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[9])
+            a[0] = 'NaT'
+            assert_equal(np.amin(a), a[1])
+            assert_equal(np.amax(a), a[9])
+            a.fill('NaT')
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[0])
+
+
+class TestNewaxis(TestCase):
+    def test_basic(self):
+        sk = np.array([0, -0.1, 0.1])
+        res = 250*sk[:, np.newaxis]
+        assert_almost_equal(res.ravel(), 250*sk)
+
+
+class TestClip(TestCase):
+    def _check_range(self, x, cmin, cmax):
+        assert_(np.all(x >= cmin))
+        assert_(np.all(x <= cmax))
+
+    def _clip_type(self, type_group, array_max,
+                   clip_min, clip_max, inplace=False,
+                   expected_min=None, expected_max=None):
+        if expected_min is None:
+            expected_min = clip_min
+        if expected_max is None:
+            expected_max = clip_max
+
+        for T in np.sctypes[type_group]:
+            if sys.byteorder == 'little':
+                byte_orders = ['=', '>']
+            else:
+                byte_orders = ['<', '=']
+
+            for byteorder in byte_orders:
+                dtype = np.dtype(T).newbyteorder(byteorder)
+
+                x = (np.random.random(1000) * array_max).astype(dtype)
+                if inplace:
+                    x.clip(clip_min, clip_max, x)
+                else:
+                    x = x.clip(clip_min, clip_max)
+                    byteorder = '='
+
+                if x.dtype.byteorder == '|':
+                    byteorder = '|'
+                assert_equal(x.dtype.byteorder, byteorder)
+                self._check_range(x, expected_min, expected_max)
+        return x
+
+    def test_basic(self):
+        for inplace in [False, True]:
+            self._clip_type(
+                'float', 1024, -12.8, 100.2, inplace=inplace)
+            self._clip_type(
+                'float', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'int', 1024, -120, 100.5, inplace=inplace)
+            self._clip_type(
+                'int', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'uint', 1024, 0, 0, inplace=inplace)
+            self._clip_type(
+                'uint', 1024, -120, 100, inplace=inplace, expected_min=0)
+
+    def test_record_array(self):
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                       dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
+        y = rec['x'].clip(-0.3, 0.5)
+        self._check_range(y, -0.3, 0.5)
+
+    def test_max_or_min(self):
+        val = np.array([0, 1, 2, 3, 4, 5, 6, 7])
+        x = val.clip(3)
+        assert_(np.all(x >= 3))
+        x = val.clip(min=3)
+        assert_(np.all(x >= 3))
+        x = val.clip(max=4)
+        assert_(np.all(x <= 4))
+
+
+class TestCompress(TestCase):
+    def test_axis(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = np.compress([0, 1, 0, 1, 0], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_truncate(self):
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_flatten(self):
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr)
+        assert_equal(out, 1)
+
+
+class TestPutmask(object):
+    def tst_basic(self, x, T, mask, val):
+        np.putmask(x, mask, val)
+        assert_(np.all(x[mask] == T(val)))
+        assert_(x.dtype == T)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(1000)*100
+        mask = x < 40
+
+        for val in [-100, 0, 15]:
+            for types in np.sctypes.values():
+                for T in types:
+                    if T not in unchecked_types:
+                        yield self.tst_basic, x.copy().astype(T), T, mask, val
+
+    def test_mask_size(self):
+        assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5)
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        np.putmask(x, [True, False, True], -1)
+        assert_array_equal(x, [-1, 2, -1])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        np.putmask(rec['x'], [True, False], 10)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [2, 4])
+        assert_array_equal(rec['z'], [3, 3])
+        np.putmask(rec['y'], [True, False], 11)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [11, 4])
+        assert_array_equal(rec['z'], [3, 3])
+
+
+class TestTake(object):
+    def tst_basic(self, x):
+        ind = list(range(x.shape[0]))
+        assert_array_equal(x.take(ind, axis=0), x)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        for types in np.sctypes.values():
+            for T in types:
+                if T not in unchecked_types:
+                    yield self.tst_basic, x.copy().astype(T)
+
+    def test_raise(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_raises(IndexError, x.take, [0, 1, 2], axis=0)
+        assert_raises(IndexError, x.take, [-3], axis=0)
+        assert_array_equal(x.take([-1], axis=0)[0], x[1])
+
+    def test_clip(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='clip')[0], x[0])
+        assert_array_equal(x.take([2], axis=0, mode='clip')[0], x[1])
+
+    def test_wrap(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='wrap')[0], x[1])
+        assert_array_equal(x.take([2], axis=0, mode='wrap')[0], x[0])
+        assert_array_equal(x.take([3], axis=0, mode='wrap')[0], x[1])
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        assert_array_equal(x.take([0, 2, 1]), [1, 3, 2])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        rec1 = rec.take([1])
+        assert_(rec1['x'] == 5.0 and rec1['y'] == 4.0)
+
+
+class TestLexsort(TestCase):
+    def test_basic(self):
+        a = [1, 2, 1, 3, 1, 5]
+        b = [0, 4, 5, 6, 2, 3]
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([0, 4, 2, 1, 3, 5])
+        assert_array_equal(idx, expected_idx)
+
+        x = np.vstack((b, a))
+        idx = np.lexsort(x)
+        assert_array_equal(idx, expected_idx)
+
+        assert_array_equal(x[1][idx], np.sort(x[1]))
+
+    def test_datetime(self):
+        a = np.array([0,0,0], dtype='datetime64[D]')
+        b = np.array([2,1,0], dtype='datetime64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+        a = np.array([0,0,0], dtype='timedelta64[D]')
+        b = np.array([2,1,0], dtype='timedelta64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+    def test_object(self):  # gh-6312
+        a = np.random.choice(10, 1000)
+        b = np.random.choice(['abc', 'xy', 'wz', 'efghi', 'qwst', 'x'], 1000)
+
+        for u in a, b:
+            left = np.lexsort((u.astype('O'),))
+            right = np.argsort(u, kind='mergesort')
+            assert_array_equal(left, right)
+
+        for u, v in (a, b), (b, a):
+            idx = np.lexsort((u, v))
+            assert_array_equal(idx, np.lexsort((u.astype('O'), v)))
+            assert_array_equal(idx, np.lexsort((u, v.astype('O'))))
+            u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
+            assert_array_equal(idx, np.lexsort((u, v)))
+
+
+class TestIO(object):
+    """Test tofile, fromfile, tobytes, and fromstring"""
+
+    def setUp(self):
+        shape = (2, 4, 3)
+        rand = np.random.random
+        self.x = rand(shape) + rand(shape).astype(np.complex)*1j
+        self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
+        self.dtype = self.x.dtype
+        self.tempdir = tempfile.mkdtemp()
+        self.filename = tempfile.mktemp(dir=self.tempdir)
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def test_nofile(self):
+        # this should probably be supported as a file
+        # but for now test for proper errors
+        b = io.BytesIO()
+        assert_raises(IOError, np.fromfile, b, np.uint8, 80)
+        d = np.ones(7);
+        assert_raises(IOError, lambda x: x.tofile(b), d)
+
+    def test_bool_fromstring(self):
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        y = np.fromstring('1 0 -2.3 0.0', sep=' ', dtype=np.bool_)
+        assert_array_equal(v, y)
+
+    def test_uint64_fromstring(self):
+        d = np.fromstring("9923372036854775807 104783749223640",
+                          dtype=np.uint64, sep=' ')
+        e = np.array([9923372036854775807, 104783749223640], dtype=np.uint64)
+        assert_array_equal(d, e)
+
+    def test_int64_fromstring(self):
+        d = np.fromstring("-25041670086757 104783749223640",
+                          dtype=np.int64, sep=' ')
+        e = np.array([-25041670086757, 104783749223640], dtype=np.int64)
+        assert_array_equal(d, e)
+
+    def test_empty_files_binary(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename)
+        assert_(y.size == 0, "Array not empty")
+
+    def test_empty_files_text(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename, sep=" ")
+        assert_(y.size == 0, "Array not empty")
+
+    def test_roundtrip_file(self):
+        f = open(self.filename, 'wb')
+        self.x.tofile(f)
+        f.close()
+        # NB. doesn't work with flush+seek, due to use of C stdio
+        f = open(self.filename, 'rb')
+        y = np.fromfile(f, dtype=self.dtype)
+        f.close()
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_filename(self):
+        self.x.tofile(self.filename)
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_binary_str(self):
+        s = self.x.tobytes()
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+        s = self.x.tobytes('F')
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flatten('F'))
+
+    def test_roundtrip_str(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(str, x))
+        y = np.fromstring(s, sep="@")
+        # NB. str imbues less precision
+        nan_mask = ~np.isfinite(x)
+        assert_array_equal(x[nan_mask], y[nan_mask])
+        assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
+
+    def test_roundtrip_repr(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(repr, x))
+        y = np.fromstring(s, sep="@")
+        assert_array_equal(x, y)
+
+    def test_unbuffered_fromfile(self):
+        # gh-6246
+        self.x.tofile(self.filename)
+
+        def fail(*args, **kwargs):
+            raise io.IOError('Can not tell or seek')
+
+        f = io.open(self.filename, 'rb', buffering=0)
+        f.seek = fail
+        f.tell = fail
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_largish_file(self):
+        # check the fallocate path on files > 16MB
+        d = np.zeros(4 * 1024 ** 2)
+        d.tofile(self.filename)
+        assert_equal(os.path.getsize(self.filename), d.nbytes)
+        assert_array_equal(d, np.fromfile(self.filename));
+        # check offset
+        with open(self.filename, "r+b") as f:
+            f.seek(d.nbytes)
+            d.tofile(f)
+            assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+
+    def test_file_position_after_fromfile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.close()
+
+            for mode in ['rb', 'r+b']:
+                err_msg = "%d %s" % (size, mode)
+
+                f = open(self.filename, mode)
+                f.read(2)
+                np.fromfile(f, dtype=np.float64, count=1)
+                pos = f.tell()
+                f.close()
+                assert_equal(pos, 10, err_msg=err_msg)
+
+    def test_file_position_after_tofile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            err_msg = "%d" % (size,)
+
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.seek(10)
+            f.write(b'12')
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
+
+            f = open(self.filename, 'r+b')
+            f.read(2)
+            f.seek(0, 1)  # seek between read&write required by ANSI C
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10, err_msg=err_msg)
+
+    def _check_from(self, s, value, **kw):
+        y = np.fromstring(asbytes(s), **kw)
+        assert_array_equal(y, value)
+
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, **kw)
+        assert_array_equal(y, value)
+
+    def test_nan(self):
+        self._check_from(
+            "nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
+            [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
+            sep=' ')
+
+    def test_inf(self):
+        self._check_from(
+            "inf +inf -inf infinity -Infinity iNfInItY -inF",
+            [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
+            sep=' ')
+
+    def test_numbers(self):
+        self._check_from("1.234 -1.234 .3 .3e55 -123133.1231e+133",
+                         [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+
+    def test_binary(self):
+        self._check_from('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+                         np.array([1, 2, 3, 4]),
+                         dtype='<f4')
+
+    @dec.slow  # takes > 1 minute on mechanical hard drive
+    def test_big_binary(self):
+        """Test workarounds for 32-bit limited fwrite, fseek, and ftell
+        calls in windows. These normally would hang doing something like this.
+        See http://projects.scipy.org/numpy/ticket/1660"""
+        if sys.platform != 'win32':
+            return
+        try:
+            # before workarounds, only up to 2**32-1 worked
+            fourgbplus = 2**32 + 2**16
+            testbytes = np.arange(8, dtype=np.int8)
+            n = len(testbytes)
+            flike = tempfile.NamedTemporaryFile()
+            f = flike.file
+            np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
+            flike.seek(0)
+            a = np.fromfile(f, dtype=np.int8)
+            flike.close()
+            assert_(len(a) == fourgbplus)
+            # check only start and end for speed:
+            assert_((a[:n] == testbytes).all())
+            assert_((a[-n:] == testbytes).all())
+        except (MemoryError, ValueError):
+            pass
+
+    def test_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], sep=',')
+
+    def test_counted_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3.], count=3, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+
+    def test_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3, 4], dtype=int, sep=' ')
+
+    def test_counted_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3], count=3, dtype=int,
+                         sep=' ')
+
+    def test_ascii(self):
+        self._check_from('1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
+
+    def test_malformed(self):
+        self._check_from('1.234 1,234', [1.234, 1.], sep=' ')
+
+    def test_long_sep(self):
+        self._check_from('1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
+
+    def test_dtype(self):
+        v = np.array([1, 2, 3, 4], dtype=np.int_)
+        self._check_from('1,2,3,4', v, sep=',', dtype=np.int_)
+
+    def test_dtype_bool(self):
+        # can't use _check_from because fromstring can't handle True/False
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        s = '1,0,-2.3,0'
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
+        assert_(y.dtype == '?')
+        assert_array_equal(y, v)
+
+    def test_tofile_sep(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        #assert_equal(s, '1.51,2.0,3.51,4.0')
+        y = np.array([float(p) for p in s.split(',')])
+        assert_array_equal(x,y)
+
+    def test_tofile_format(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',', format='%.2f')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.00,3.51,4.00')
+
+    def test_locale(self):
+        in_foreign_locale(self.test_numbers)()
+        in_foreign_locale(self.test_nan)()
+        in_foreign_locale(self.test_inf)()
+        in_foreign_locale(self.test_counted_string)()
+        in_foreign_locale(self.test_ascii)()
+        in_foreign_locale(self.test_malformed)()
+        in_foreign_locale(self.test_tofile_sep)()
+        in_foreign_locale(self.test_tofile_format)()
+
+
+class TestFromBuffer(object):
+    def tst_basic(self, buffer, expected, kwargs):
+        assert_array_equal(np.frombuffer(buffer,**kwargs), expected)
+
+    def test_ip_basic(self):
+        for byteorder in ['<', '>']:
+            for dtype in [float, int, np.complex]:
+                dt = np.dtype(dtype).newbyteorder(byteorder)
+                x = (np.random.random((4, 7))*5).astype(dt)
+                buf = x.tobytes()
+                yield self.tst_basic, buf, x.flat, {'dtype':dt}
+
+    def test_empty(self):
+        yield self.tst_basic, asbytes(''), np.array([]), {}
+
+
+class TestFlat(TestCase):
+    def setUp(self):
+        a0 = np.arange(20.0)
+        a = a0.reshape(4, 5)
+        a0.shape = (4, 5)
+        a.flags.writeable = False
+        self.a = a
+        self.b = a[::2, ::2]
+        self.a0 = a0
+        self.b0 = a0[::2, ::2]
+
+    def test_contiguous(self):
+        testpassed = False
+        try:
+            self.a.flat[12] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.a.flat[12] == 12.0)
+
+    def test_discontiguous(self):
+        testpassed = False
+        try:
+            self.b.flat[4] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.b.flat[4] == 12.0)
+
+    def test___array__(self):
+        c = self.a.flat.__array__()
+        d = self.b.flat.__array__()
+        e = self.a0.flat.__array__()
+        f = self.b0.flat.__array__()
+
+        assert_(c.flags.writeable is False)
+        assert_(d.flags.writeable is False)
+        assert_(e.flags.writeable is True)
+        assert_(f.flags.writeable is True)
+
+        assert_(c.flags.updateifcopy is False)
+        assert_(d.flags.updateifcopy is False)
+        assert_(e.flags.updateifcopy is False)
+        assert_(f.flags.updateifcopy is True)
+        assert_(f.base is self.b0)
+
+
+class TestResize(TestCase):
+    def test_basic(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        x.resize((5, 5))
+        assert_array_equal(x.flat[:9],
+                np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat)
+        assert_array_equal(x[9:].flat, 0)
+
+    def test_check_reference(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        y = x
+        self.assertRaises(ValueError, x.resize, (5, 1))
+        del y  # avoid pyflakes unused variable warning.
+
+    def test_int_shape(self):
+        x = np.eye(3)
+        x.resize(3)
+        assert_array_equal(x, np.eye(3)[0,:])
+
+    def test_none_shape(self):
+        x = np.eye(3)
+        x.resize(None)
+        assert_array_equal(x, np.eye(3))
+        x.resize()
+        assert_array_equal(x, np.eye(3))
+
+    def test_invalid_arguements(self):
+        self.assertRaises(TypeError, np.eye(3).resize, 'hi')
+        self.assertRaises(ValueError, np.eye(3).resize, -1)
+        self.assertRaises(TypeError, np.eye(3).resize, order=1)
+        self.assertRaises(TypeError, np.eye(3).resize, refcheck='hi')
+
+    def test_freeform_shape(self):
+        x = np.eye(3)
+        x.resize(3, 2, 1)
+        assert_(x.shape == (3, 2, 1))
+
+    def test_zeros_appended(self):
+        x = np.eye(3)
+        x.resize(2, 3, 3)
+        assert_array_equal(x[0], np.eye(3))
+        assert_array_equal(x[1], np.zeros((3, 3)))
+
+    def test_obj_obj(self):
+        # check memory is initialized on resize, gh-4857
+        a = np.ones(10, dtype=[('k', object, 2)])
+        a.resize(15,)
+        assert_equal(a.shape, (15,))
+        assert_array_equal(a['k'][-5:], 0)
+        assert_array_equal(a['k'][:-5], 1)
+
+
+class TestRecord(TestCase):
+    def test_field_rename(self):
+        dt = np.dtype([('f', float), ('i', int)])
+        dt.names = ['p', 'q']
+        assert_equal(dt.names, ['p', 'q'])
+
+    def test_multiple_field_name_occurrence(self):
+        def test_assign():
+            dtype = np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")])
+
+        # Error raised when multiple fields have the same name
+        assert_raises(ValueError, test_assign)
+
+    if sys.version_info[0] >= 3:
+        def test_bytes_fields(self):
+            # Bytes are not allowed in field names and not recognized in titles
+            # on Py3
+            assert_raises(TypeError, np.dtype, [(asbytes('a'), int)])
+            assert_raises(TypeError, np.dtype, [(('b', asbytes('a')), int)])
+
+            dt = np.dtype([((asbytes('a'), 'b'), int)])
+            assert_raises(ValueError, dt.__getitem__, asbytes('a'))
+
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            assert_raises(IndexError, x.__getitem__, asbytes('a'))
+
+            y = x[0]
+            assert_raises(IndexError, y.__getitem__, asbytes('a'))
+
+        def test_multiple_field_name_unicode(self):
+            def test_assign_unicode():
+                dt = np.dtype([("\u20B9", "f8"),
+                               ("B", "f8"),
+                               ("\u20B9", "f8")])
+
+            # Error raised when multiple fields have the same name(unicode included)
+            assert_raises(ValueError, test_assign_unicode)
+
+    else:
+        def test_unicode_field_titles(self):
+            # Unicode field titles are added to field dict on Py2
+            title = unicode('b')
+            dt = np.dtype([((title, 'a'), int)])
+            dt[title]
+            dt['a']
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            x[title]
+            x['a']
+            y = x[0]
+            y[title]
+            y['a']
+
+        def test_unicode_field_names(self):
+            # Unicode field names are not allowed on Py2
+            title = unicode('b')
+            assert_raises(TypeError, np.dtype, [(title, int)])
+            assert_raises(TypeError, np.dtype, [(('a', title), int)])
+
+    def test_field_names(self):
+        # Test unicode and 8-bit / byte strings can be used
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        is_py3 = sys.version_info[0] >= 3
+        if is_py3:
+            funcs = (str,)
+            # byte string indexing fails gracefully
+            assert_raises(IndexError, a.__setitem__, asbytes('f1'), 1)
+            assert_raises(IndexError, a.__getitem__, asbytes('f1'))
+            assert_raises(IndexError, a['f1'].__setitem__, asbytes('sf1'), 1)
+            assert_raises(IndexError, a['f1'].__getitem__, asbytes('sf1'))
+        else:
+            funcs = (str, unicode)
+        for func in funcs:
+            b = a.copy()
+            fn1 = func('f1')
+            b[fn1] = 1
+            assert_equal(b[fn1], 1)
+            fnn = func('not at all')
+            assert_raises(ValueError, b.__setitem__, fnn, 1)
+            assert_raises(ValueError, b.__getitem__, fnn)
+            b[0][fn1] = 2
+            assert_equal(b[fn1], 2)
+            # Subfield
+            assert_raises(ValueError, b[0].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[0].__getitem__, fnn)
+            # Subfield
+            fn3 = func('f3')
+            sfn1 = func('sf1')
+            b[fn3][sfn1] = 1
+            assert_equal(b[fn3][sfn1], 1)
+            assert_raises(ValueError, b[fn3].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[fn3].__getitem__, fnn)
+            # multiple subfields
+            fn2 = func('f2')
+            b[fn2] = 3
+            assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2))
+            assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,)))
+            # view of subfield view/copy
+            assert_equal(b[['f1', 'f2']][0].view(('i4', 2)).tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].view(('i4', 2)).tolist(), (3, 2))
+            view_dtype = [('f1', 'i4'), ('f3', [('', 'i4')])]
+            assert_equal(b[['f1', 'f3']][0].view(view_dtype).tolist(), (2, (1,)))
+        # non-ascii unicode field indexing is well behaved
+        if not is_py3:
+            raise SkipTest('non ascii unicode field indexing skipped; '
+                           'raises segfault on python 2.x')
+        else:
+            assert_raises(ValueError, a.__setitem__, sixu('\u03e0'), 1)
+            assert_raises(ValueError, a.__getitem__, sixu('\u03e0'))
+
+    def test_field_names_deprecation(self):
+
+        def collect_warnings(f, *args, **kwargs):
+            with warnings.catch_warnings(record=True) as log:
+                warnings.simplefilter("always")
+                f(*args, **kwargs)
+            return [w.category for w in log]
+
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        a['f1'][0] = 1
+        a['f2'][0] = 2
+        a['f3'][0] = (3,)
+        b = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        b['f1'][0] = 1
+        b['f2'][0] = 2
+        b['f3'][0] = (3,)
+
+        # All the different functions raise a warning, but not an error, and
+        # 'a' is not modified:
+        assert_equal(collect_warnings(a[['f1', 'f2']].__setitem__, 0, (10, 20)),
+                     [FutureWarning])
+        assert_equal(a, b)
+        # Views also warn
+        subset = a[['f1', 'f2']]
+        subset_view = subset.view()
+        assert_equal(collect_warnings(subset_view['f1'].__setitem__, 0, 10),
+                     [FutureWarning])
+        # But the write goes through:
+        assert_equal(subset['f1'][0], 10)
+        # Only one warning per multiple field indexing, though (even if there
+        # are multiple views involved):
+        assert_equal(collect_warnings(subset['f1'].__setitem__, 0, 10), [])
+
+    def test_record_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        a.flags.writeable = False
+        b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')])
+        b.flags.writeable = False
+        c = np.array([(1, 2), (3, 4)], dtype='i1,i2')
+        c.flags.writeable = False
+        self.assertTrue(hash(a[0]) == hash(a[1]))
+        self.assertTrue(hash(a[0]) == hash(b[0]))
+        self.assertTrue(hash(a[0]) != hash(b[1]))
+        self.assertTrue(hash(c[0]) == hash(a[0]) and c[0] == a[0])
+
+    def test_record_no_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        self.assertRaises(TypeError, hash, a[0])
+
+    def test_empty_structure_creation(self):
+        # make sure these do not raise errors (gh-5631)
+        np.array([()], dtype={'names': [], 'formats': [],
+                           'offsets': [], 'itemsize': 12})
+        np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [],
+                                           'offsets': [], 'itemsize': 12})
+
+class TestView(TestCase):
+    def test_basic(self):
+        x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)],
+                     dtype=[('r', np.int8), ('g', np.int8),
+                            ('b', np.int8), ('a', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i4')
+        # ... and again without the keyword.
+        z = x.view('<i4')
+        assert_array_equal(y, z)
+        assert_array_equal(y, [67305985, 134678021])
+
+
+def _mean(a, **args):
+    return a.mean(**args)
+
+
+def _var(a, **args):
+    return a.var(**args)
+
+
+def _std(a, **args):
+    return a.std(**args)
+
+
+class TestStats(TestCase):
+
+    funcs = [_mean, _var, _std]
+
+    def setUp(self):
+        np.random.seed(range(3))
+        self.rmat = np.random.random((4, 5))
+        self.cmat = self.rmat + 1j * self.rmat
+        self.omat = np.array([Decimal(repr(r)) for r in self.rmat.flat])
+        self.omat = self.omat.reshape(4, 5)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            for axis in [0, 1]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == mat.ndim)
+                assert_(res.shape[axis] == 1)
+            for axis in [None]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.shape == (1, 1))
+
+    def test_out(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            out = np.zeros(3)
+            tgt = f(mat, axis=1)
+            res = f(mat, axis=1, out=out)
+            assert_almost_equal(res, out)
+            assert_almost_equal(res, tgt)
+        out = np.empty(2)
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+        out = np.empty((2, 2))
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+
+    def test_dtype_from_input(self):
+
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+
+        # object type
+        for f in self.funcs:
+            mat = np.array([[Decimal(1)]*3]*3)
+            tgt = mat.dtype.type
+            res = f(mat, axis=1).dtype.type
+            assert_(res is tgt)
+            # scalar case
+            res = type(f(mat, axis=None))
+            assert_(res is Decimal)
+
+        # integer types
+        for f in self.funcs:
+            for c in icodes:
+                mat = np.eye(3, dtype=c)
+                tgt = np.float64
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # mean for float types
+        for f in [_mean]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                tgt = mat.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # var, std for float types
+        for f in [_var, _std]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                # deal with complex types
+                tgt = mat.real.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+
+        # stats for integer types
+        # FIXME:
+        # this needs definition as there are lots places along the line
+        # where type casting may take place.
+
+        # for f in self.funcs:
+        #    for c in np.typecodes['AllInteger']:
+        #        tgt = np.dtype(c).type
+        #        res = f(mat, axis=1, dtype=c).dtype.type
+        #        assert_(res is tgt)
+        #        # scalar case
+        #        res = f(mat, axis=None, dtype=c).dtype.type
+        #        assert_(res is tgt)
+
+        # stats for float types
+        for f in self.funcs:
+            for c in np.typecodes['AllFloat']:
+                tgt = np.dtype(c).type
+                res = f(mat, axis=1, dtype=c).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None, dtype=c).dtype.type
+                assert_(res is tgt)
+
+    def test_ddof(self):
+        for f in [_var]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * dim
+                res = f(self.rmat, axis=1, ddof=ddof) * (dim - ddof)
+        for f in [_std]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * np.sqrt(dim)
+                res = f(self.rmat, axis=1, ddof=ddof) * np.sqrt(dim - ddof)
+                assert_almost_equal(res, tgt)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        dim = self.rmat.shape[1]
+        for f in [_var, _std]:
+            for ddof in range(dim, dim + 2):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    res = f(self.rmat, axis=1, ddof=ddof)
+                    assert_(not (res < 0).any())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        A = np.zeros((0, 3))
+        for f in self.funcs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(A, axis=axis)).all())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(A, axis=axis), np.zeros([]))
+
+    def test_mean_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * mat.shape[axis]
+                assert_almost_equal(res, tgt)
+            for axis in [None]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * np.prod(mat.shape)
+                assert_almost_equal(res, tgt)
+
+    def test_var_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                msqr = _mean(mat * mat.conj(), axis=axis)
+                mean = _mean(mat, axis=axis)
+                tgt = msqr - mean * mean.conjugate()
+                res = _var(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_std_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                tgt = np.sqrt(_var(mat, axis=axis))
+                res = _std(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_subclass(self):
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, "info", '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        res = dat.mean(1)
+        assert_(res.info == dat.info)
+        res = dat.std(1)
+        assert_(res.info == dat.info)
+        res = dat.var(1)
+        assert_(res.info == dat.info)
+
+class TestVdot(TestCase):
+    def test_basic(self):
+        dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
+        dt_complex = np.typecodes['Complex']
+
+        # test real
+        a = np.eye(3)
+        for dt in dt_numeric + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test complex
+        a = np.eye(3) * 1j
+        for dt in dt_complex + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test boolean
+        b = np.eye(3, dtype=np.bool)
+        res = np.vdot(b, b)
+        assert_(np.isscalar(res))
+        assert_equal(np.vdot(b, b), True)
+
+    def test_vdot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.vdot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.vdot(a, b), res)
+        assert_equal(np.vdot(b, a), res)
+        assert_equal(np.vdot(b, b), res)
+
+    def test_vdot_uncontiguous(self):
+        for size in [2, 1000]:
+            # Different sizes match different branches in vdot.
+            a = np.zeros((size, 2, 2))
+            b = np.zeros((size, 2, 2))
+            a[:, 0, 0] = np.arange(size)
+            b[:, 0, 0] = np.arange(size) + 1
+            # Make a and b uncontiguous:
+            a = a[..., 0]
+            b = b[..., 0]
+
+            assert_equal(np.vdot(a, b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy()),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy(), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy('F'), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy('F')),
+                         np.vdot(a.flatten(), b.flatten()))
+
+
+class TestDot(TestCase):
+    def setUp(self):
+        np.random.seed(128)
+        self.A = np.random.rand(4, 2)
+        self.b1 = np.random.rand(2, 1)
+        self.b2 = np.random.rand(2)
+        self.b3 = np.random.rand(1, 2)
+        self.b4 = np.random.rand(4)
+        self.N = 7
+
+    def test_dotmatmat(self):
+        A = self.A
+        res = np.dot(A.transpose(), A)
+        tgt = np.array([[1.45046013, 0.86323640],
+                        [0.86323640, 0.84934569]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec(self):
+        A, b1 = self.A, self.b1
+        res = np.dot(A, b1)
+        tgt = np.array([[0.32114320], [0.04889721],
+                        [0.15696029], [0.33612621]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec2(self):
+        A, b2 = self.A, self.b2
+        res = np.dot(A, b2)
+        tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(b4, A)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat2(self):
+        b3, A = self.b3, self.A
+        res = np.dot(b3, A.transpose())
+        tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat3(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(A.transpose(), b4)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecouter(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b1, b3)
+        tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecinner(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b3, b1)
+        tgt = np.array([[ 0.23129668]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect1(self):
+        b1 = np.ones((3, 1))
+        b2 = [5.3]
+        res = np.dot(b1, b2)
+        tgt = np.array([5.3, 5.3, 5.3])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect2(self):
+        b1 = np.ones((3, 1)).transpose()
+        b2 = [6.2]
+        res = np.dot(b2, b1)
+        tgt = np.array([6.2, 6.2, 6.2])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar(self):
+        np.random.seed(100)
+        b1 = np.random.rand(1, 1)
+        b2 = np.random.rand(1, 4)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar2(self):
+        np.random.seed(100)
+        b1 = np.random.rand(4, 1)
+        b2 = np.random.rand(1, 1)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_all(self):
+        dims = [(), (1,), (1, 1)]
+        dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)]
+        for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)):
+            b1 = np.zeros(dim1)
+            b2 = np.zeros(dim2)
+            res = np.dot(b1, b2)
+            tgt = np.zeros(dim)
+            assert_(res.shape == tgt.shape)
+            assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_vecobject(self):
+        class Vec(object):
+            def __init__(self, sequence=None):
+                if sequence is None:
+                    sequence = []
+                self.array = np.array(sequence)
+
+            def __add__(self, other):
+                out = Vec()
+                out.array = self.array + other.array
+                return out
+
+            def __sub__(self, other):
+                out = Vec()
+                out.array = self.array - other.array
+                return out
+
+            def __mul__(self, other):  # with scalar
+                out = Vec(self.array.copy())
+                out.array *= other
+                return out
+
+            def __rmul__(self, other):
+                return self*other
+
+        U_non_cont = np.transpose([[1., 1.], [1., 2.]])
+        U_cont = np.ascontiguousarray(U_non_cont)
+        x = np.array([Vec([1., 0.]), Vec([0., 1.])])
+        zeros = np.array([Vec([0., 0.]), Vec([0., 0.])])
+        zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x)
+        assert_equal(zeros[0].array, zeros_test[0].array)
+        assert_equal(zeros[1].array, zeros_test[1].array)
+
+    def test_dot_2args(self):
+        from numpy.core.multiarray import dot
+
+        a = np.array([[1, 2], [3, 4]], dtype=float)
+        b = np.array([[1, 0], [1, 1]], dtype=float)
+        c = np.array([[3, 2], [7, 4]], dtype=float)
+
+        d = dot(a, b)
+        assert_allclose(c, d)
+
+    def test_dot_3args(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 32))
+        for i in range(12):
+            dot(f, v, r)
+        assert_equal(sys.getrefcount(r), 2)
+        r2 = dot(f, v, out=None)
+        assert_array_equal(r2, r)
+        assert_(r is dot(f, v, out=r))
+
+        v = v[:, 0].copy()  # v.shape == (16,)
+        r = r[:, 0].copy()  # r.shape == (1024,)
+        r2 = dot(f, v)
+        assert_(r is dot(f, v, r))
+        assert_array_equal(r2, r)
+
+    def test_dot_3args_errors(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 31))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32, 1024))
+        assert_raises(ValueError, dot, f, v, r)
+        assert_raises(ValueError, dot, f, v, r.T)
+
+        r = np.empty((1024, 64))
+        assert_raises(ValueError, dot, f, v, r[:, ::2])
+        assert_raises(ValueError, dot, f, v, r[:, :32])
+
+        r = np.empty((1024, 32), dtype=np.float32)
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024, 32), dtype=int)
+        assert_raises(ValueError, dot, f, v, r)
+
+    def test_dot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.dot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.dot(a, b), res)
+        assert_equal(np.dot(b, a), res)
+        assert_equal(np.dot(b, b), res)
+
+    def test_dot_scalar_and_matrix_of_objects(self):
+        # Ticket #2469
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.dot(arr, 3), desired)
+        assert_equal(np.dot(3, arr), desired)
+
+    def test_accelerate_framework_sgemv_fix(self):
+
+        def aligned_array(shape, align, dtype, order='C'):
+            d = dtype(0)
+            N = np.prod(shape)
+            tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
+            address = tmp.__array_interface__["data"][0]
+            for offset in range(align):
+                if (address + offset) % align == 0:
+                    break
+            tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
+            return tmp.reshape(shape, order=order)
+
+        def as_aligned(arr, align, dtype, order='C'):
+            aligned = aligned_array(arr.shape, align, dtype, order)
+            aligned[:] = arr[:]
+            return aligned
+
+        def assert_dot_close(A, X, desired):
+            assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
+
+        m = aligned_array(100, 15, np.float32)
+        s = aligned_array((100, 100), 15, np.float32)
+        np.dot(s, m)  # this will always segfault if the bug is present
+
+        testdata = itertools.product((15,32), (10000,), (200,89), ('C','F'))
+        for align, m, n, a_order in testdata:
+            # Calculation in double precision
+            A_d = np.random.rand(m, n)
+            X_d = np.random.rand(n)
+            desired = np.dot(A_d, X_d)
+            # Calculation with aligned single precision
+            A_f = as_aligned(A_d, align, np.float32, order=a_order)
+            X_f = as_aligned(X_d, align, np.float32)
+            assert_dot_close(A_f, X_f, desired)
+            # Strided A rows
+            A_d_2 = A_d[::2]
+            desired = np.dot(A_d_2, X_d)
+            A_f_2 = A_f[::2]
+            assert_dot_close(A_f_2, X_f, desired)
+            # Strided A columns, strided X vector
+            A_d_22 = A_d_2[:, ::2]
+            X_d_2 = X_d[::2]
+            desired = np.dot(A_d_22, X_d_2)
+            A_f_22 = A_f_2[:, ::2]
+            X_f_2 = X_f[::2]
+            assert_dot_close(A_f_22, X_f_2, desired)
+            # Check the strides are as expected
+            if a_order == 'F':
+                assert_equal(A_f_22.strides, (8, 8 * m))
+            else:
+                assert_equal(A_f_22.strides, (8 * n, 8))
+            assert_equal(X_f_2.strides, (8,))
+            # Strides in A rows + cols only
+            X_f_2c = as_aligned(X_f_2, align, np.float32)
+            assert_dot_close(A_f_22, X_f_2c, desired)
+            # Strides just in A cols
+            A_d_12 = A_d[:, ::2]
+            desired = np.dot(A_d_12, X_d_2)
+            A_f_12 = A_f[:, ::2]
+            assert_dot_close(A_f_12, X_f_2c, desired)
+            # Strides in A cols and X
+            assert_dot_close(A_f_12, X_f_2, desired)
+
+
+class MatmulCommon():
+    """Common tests for '@' operator and numpy.matmul.
+
+    Do not derive from TestCase to avoid nose running it.
+
+    """
+    # Should work with these types. Will want to add
+    # "O" at some point
+    types = "?bhilqBHILQefdgFDG"
+
+    def test_exceptions(self):
+        dims = [
+            ((1,), (2,)),            # mismatched vector vector
+            ((2, 1,), (2,)),         # mismatched matrix vector
+            ((2,), (1, 2)),          # mismatched vector matrix
+            ((1, 2), (3, 1)),        # mismatched matrix matrix
+            ((1,), ()),              # vector scalar
+            ((), (1)),               # scalar vector
+            ((1, 1), ()),            # matrix scalar
+            ((), (1, 1)),            # scalar matrix
+            ((2, 2, 1), (3, 1, 2)),  # cannot broadcast
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            assert_raises(ValueError, self.matmul, a, b)
+
+    def test_shapes(self):
+        dims = [
+            ((1, 1), (2, 1, 1)),     # broadcast first argument
+            ((2, 1, 1), (1, 1)),     # broadcast second argument
+            ((2, 1, 1), (2, 1, 1)),  # matrix stack sizes match
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            res = self.matmul(a, b)
+            assert_(res.shape == (2, 1, 1))
+
+        # vector vector returns scalars.
+        for dt in self.types:
+            a = np.ones((2,), dtype=dt)
+            b = np.ones((2,), dtype=dt)
+            c = self.matmul(a, b)
+            assert_(np.array(c).shape == ())
+
+    def test_result_types(self):
+        mat = np.ones((1,1))
+        vec = np.ones((1,))
+        for dt in self.types:
+            m = mat.astype(dt)
+            v = vec.astype(dt)
+            for arg in [(m, v), (v, m), (m, m)]:
+                res = self.matmul(*arg)
+                assert_(res.dtype == dt)
+
+            # vector vector returns scalars
+            res = self.matmul(v, v)
+            assert_(type(res) is np.dtype(dt).type)
+
+    def test_vector_vector_values(self):
+        vec = np.array([1, 2])
+        tgt = 5
+        for dt in self.types[1:]:
+            v1 = vec.astype(dt)
+            res = self.matmul(v1, v1)
+            assert_equal(res, tgt)
+
+        # boolean type
+        vec = np.array([True, True], dtype='?')
+        res = self.matmul(vec, vec)
+        assert_equal(res, True)
+
+    def test_vector_matrix_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([7, 10])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(v, m1)
+            assert_equal(res, tgt1)
+            res = self.matmul(v, m2)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_vector_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([5, 11])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(m1, v)
+            assert_equal(res, tgt1)
+            res = self.matmul(m2, v)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_matrix_values(self):
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.array([[1, 0], [1, 1]])
+        mat12 = np.stack([mat1, mat2], axis=0)
+        mat21 = np.stack([mat2, mat1], axis=0)
+        tgt11 = np.array([[7, 10], [15, 22]])
+        tgt12 = np.array([[3, 2], [7, 4]])
+        tgt21 = np.array([[1, 2], [4, 6]])
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+        for dt in self.types[1:]:
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            m12 = mat12.astype(dt)
+            m21 = mat21.astype(dt)
+
+            # matrix @ matrix
+            res = self.matmul(m1, m2)
+            assert_equal(res, tgt12)
+            res = self.matmul(m2, m1)
+            assert_equal(res, tgt21)
+
+            # stacked @ matrix
+            res = self.matmul(m12, m1)
+            assert_equal(res, tgt11_21)
+
+            # matrix @ stacked
+            res = self.matmul(m1, m12)
+            assert_equal(res, tgt11_12)
+
+            # stacked @ stacked
+            res = self.matmul(m12, m21)
+            assert_equal(res, tgt12_21)
+
+        # boolean type
+        m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_)
+        m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_)
+        m12 = np.stack([m1, m2], axis=0)
+        m21 = np.stack([m2, m1], axis=0)
+        tgt11 = m1
+        tgt12 = m1
+        tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_)
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+
+        # matrix @ matrix
+        res = self.matmul(m1, m2)
+        assert_equal(res, tgt12)
+        res = self.matmul(m2, m1)
+        assert_equal(res, tgt21)
+
+        # stacked @ matrix
+        res = self.matmul(m12, m1)
+        assert_equal(res, tgt11_21)
+
+        # matrix @ stacked
+        res = self.matmul(m1, m12)
+        assert_equal(res, tgt11_12)
+
+        # stacked @ stacked
+        res = self.matmul(m12, m21)
+        assert_equal(res, tgt12_21)
+
+    def test_numpy_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A([1, 2])
+        b = B([1, 2])
+        c = np.ones(2)
+        assert_equal(self.matmul(a, b), "A")
+        assert_equal(self.matmul(b, a), "A")
+        assert_raises(TypeError, self.matmul, b, c)
+
+
+class TestMatmul(MatmulCommon, TestCase):
+    matmul = np.matmul
+
+    def test_out_arg(self):
+        a = np.ones((2, 2), dtype=np.float)
+        b = np.ones((2, 2), dtype=np.float)
+        tgt = np.full((2,2), 2, dtype=np.float)
+
+        # test as positional argument
+        msg = "out positional argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test as keyword argument
+        msg = "out keyword argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out=out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out with not allowed type cast (safe casting)
+        # einsum and cblas raise different error types, so
+        # use Exception.
+        msg = "out argument with illegal cast"
+        out = np.zeros((2, 2), dtype=np.int32)
+        assert_raises(Exception, self.matmul, a, b, out=out)
+
+        # skip following tests for now, cblas does not allow non-contiguous
+        # outputs and consistency with dot would require same type,
+        # dimensions, subtype, and c_contiguous.
+
+        # test out with allowed type cast
+        # msg = "out argument with allowed cast"
+        # out = np.zeros((2, 2), dtype=np.complex128)
+        # self.matmul(a, b, out=out)
+        # assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out non-contiguous
+        # msg = "out argument with non-contiguous layout"
+        # c = np.zeros((2, 2, 2), dtype=np.float)
+        # self.matmul(a, b, out=c[..., 0])
+        # assert_array_equal(c, tgt, err_msg=msg)
+
+
+if sys.version_info[:2] >= (3, 5):
+    class TestMatmulOperator(MatmulCommon, TestCase):
+        import operator
+        matmul = operator.matmul
+
+        def test_array_priority_override(self):
+
+            class A(object):
+                __array_priority__ = 1000
+
+                def __matmul__(self, other):
+                    return "A"
+
+                def __rmatmul__(self, other):
+                    return "A"
+
+            a = A()
+            b = np.ones(2)
+            assert_equal(self.matmul(a, b), "A")
+            assert_equal(self.matmul(b, a), "A")
+
+    def test_matmul_inplace():
+        # It would be nice to support in-place matmul eventually, but for now
+        # we don't have a working implementation, so better just to error out
+        # and nudge people to writing "a = a @ b".
+        a = np.eye(3)
+        b = np.eye(3)
+        assert_raises(TypeError, a.__imatmul__, b)
+        import operator
+        assert_raises(TypeError, operator.imatmul, a, b)
+        # we avoid writing the token `exec` so as not to crash python 2's
+        # parser
+        exec_ = getattr(builtins, "exec")
+        assert_raises(TypeError, exec_, "a @= b", globals(), locals())
+
+
+class TestInner(TestCase):
+
+    def test_inner_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.inner, c, A)
+        assert_raises(TypeError, np.inner, A, c)
+
+    def test_inner_scalar_and_vector(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            vec = np.array([1, 2], dtype=dt)
+            desired = np.array([3, 6], dtype=dt)
+            assert_equal(np.inner(vec, sca), desired)
+            assert_equal(np.inner(sca, vec), desired)
+
+    def test_inner_scalar_and_matrix(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            arr = np.matrix([[1, 2], [3, 4]], dtype=dt)
+            desired = np.matrix([[3, 6], [9, 12]], dtype=dt)
+            assert_equal(np.inner(arr, sca), desired)
+            assert_equal(np.inner(sca, arr), desired)
+
+    def test_inner_scalar_and_matrix_of_objects(self):
+        # Ticket #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.inner(arr, 3), desired)
+        assert_equal(np.inner(3, arr), desired)
+
+    def test_vecself(self):
+        # Ticket 844.
+        # Inner product of a vector with itself segfaults or give
+        # meaningless result
+        a = np.zeros(shape=(1, 80), dtype=np.float64)
+        p = np.inner(a, a)
+        assert_almost_equal(p, 0, decimal=14)
+
+    def test_inner_product_with_various_contiguities(self):
+        # github issue 6532
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            # check an inner product involving a matrix transpose
+            A = np.array([[1, 2], [3, 4]], dtype=dt)
+            B = np.array([[1, 3], [2, 4]], dtype=dt)
+            C = np.array([1, 1], dtype=dt)
+            desired = np.array([4, 6], dtype=dt)
+            assert_equal(np.inner(A.T, C), desired)
+            assert_equal(np.inner(C, A.T), desired)
+            assert_equal(np.inner(B, C), desired)
+            assert_equal(np.inner(C, B), desired)
+            # check a matrix product
+            desired = np.array([[7, 10], [15, 22]], dtype=dt)
+            assert_equal(np.inner(A, B), desired)
+            # check the syrk vs. gemm paths
+            desired = np.array([[5, 11], [11, 25]], dtype=dt)
+            assert_equal(np.inner(A, A), desired)
+            assert_equal(np.inner(A, A.copy()), desired)
+            # check an inner product involving an aliased and reversed view
+            a = np.arange(5).astype(dt)
+            b = a[::-1]
+            desired = np.array(10, dtype=dt).item()
+            assert_equal(np.inner(b, a), desired)
+
+    def test_3d_tensor(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            a = np.arange(24).reshape(2,3,4).astype(dt)
+            b = np.arange(24, 48).reshape(2,3,4).astype(dt)
+            desired = np.array(
+                [[[[ 158,  182,  206],
+                   [ 230,  254,  278]],
+
+                  [[ 566,  654,  742],
+                   [ 830,  918, 1006]],
+
+                  [[ 974, 1126, 1278],
+                   [1430, 1582, 1734]]],
+
+                 [[[1382, 1598, 1814],
+                   [2030, 2246, 2462]],
+
+                  [[1790, 2070, 2350],
+                   [2630, 2910, 3190]],
+
+                  [[2198, 2542, 2886],
+                   [3230, 3574, 3918]]]],
+                dtype=dt
+            )
+            assert_equal(np.inner(a, b), desired)
+            assert_equal(np.inner(b, a).transpose(2,3,0,1), desired)
+
+
+class TestSummarization(TestCase):
+    def test_1d(self):
+        A = np.arange(1001)
+        strA = '[   0    1    2 ...,  998  999 1000]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([   0,    1,    2, ...,  998,  999, 1000])'
+        assert_(repr(A) == reprA)
+
+    def test_2d(self):
+        A = np.arange(1002).reshape(2, 501)
+        strA = '[[   0    1    2 ...,  498  499  500]\n' \
+               ' [ 501  502  503 ...,  999 1000 1001]]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([[   0,    1,    2, ...,  498,  499,  500],\n' \
+                '       [ 501,  502,  503, ...,  999, 1000, 1001]])'
+        assert_(repr(A) == reprA)
+
+
+class TestAlen(TestCase):
+    def test_basic(self):
+        m = np.array([1, 2, 3])
+        self.assertEqual(np.alen(m), 3)
+
+        m = np.array([[1, 2, 3], [4, 5, 7]])
+        self.assertEqual(np.alen(m), 2)
+
+        m = [1, 2, 3]
+        self.assertEqual(np.alen(m), 3)
+
+        m = [[1, 2, 3], [4, 5, 7]]
+        self.assertEqual(np.alen(m), 2)
+
+    def test_singleton(self):
+        self.assertEqual(np.alen(5), 1)
+
+
+class TestChoose(TestCase):
+    def setUp(self):
+        self.x = 2*np.ones((3,), dtype=int)
+        self.y = 3*np.ones((3,), dtype=int)
+        self.x2 = 2*np.ones((2, 3), dtype=int)
+        self.y2 = 3*np.ones((2, 3), dtype=int)
+        self.ind = [0, 0, 1]
+
+    def test_basic(self):
+        A = np.choose(self.ind, (self.x, self.y))
+        assert_equal(A, [2, 2, 3])
+
+    def test_broadcast1(self):
+        A = np.choose(self.ind, (self.x2, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_broadcast2(self):
+        A = np.choose(self.ind, (self.x, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+
+class TestRepeat(TestCase):
+    def setUp(self):
+        self.m = np.array([1, 2, 3, 4, 5, 6])
+        self.m_rect = self.m.reshape((2, 3))
+
+    def test_basic(self):
+        A = np.repeat(self.m, [1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+    def test_broadcast1(self):
+        A = np.repeat(self.m, 2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+    def test_axis_spec(self):
+        A = np.repeat(self.m_rect, [2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, [1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+    def test_broadcast2(self):
+        A = np.repeat(self.m_rect, 2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, 2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+
+# TODO: test for multidimensional
+NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4}
+
+
+class TestNeighborhoodIter(TestCase):
+    # Simple, 2d tests
+    def _test_simple2d(self, dt):
+        # Test zero and one padding for simple data type
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt),
+             np.array([[0, 0, 0], [0, 1, 0]], dtype=dt),
+             np.array([[0, 0, 1], [0, 2, 3]], dtype=dt),
+             np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt),
+             np.array([[1, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[1, 0, 1], [1, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt),
+             np.array([[4, 4, 4], [0, 1, 4]], dtype=dt),
+             np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
+             np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], 4,
+                NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple2d(self):
+        self._test_simple2d(np.float)
+
+    def test_simple2d_object(self):
+        self._test_simple2d(Decimal)
+
+    def _test_mirror2d(self, dt):
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
+             np.array([[0, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[0, 0, 1], [2, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    def test_mirror2d(self):
+        self._test_mirror2d(np.float)
+
+    def test_mirror2d_object(self):
+        self._test_mirror2d(Decimal)
+
+    # Simple, 1d tests
+    def _test_simple(self, dt):
+        # Test padding with constant values
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[4], NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple_float(self):
+        self._test_simple(np.float)
+
+    def test_simple_object(self):
+        self._test_simple(Decimal)
+
+    # Test mirror modes
+    def _test_mirror(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[1], NEIGH_MODE['mirror'])
+        self.assertTrue([i.dtype == dt for i in l])
+        assert_array_equal(l, r)
+
+    def test_mirror(self):
+        self._test_mirror(np.float)
+
+    def test_mirror_object(self):
+        self._test_mirror(Decimal)
+
+    # Circular mode
+    def _test_circular(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    def test_circular(self):
+        self._test_circular(np.float)
+
+    def test_circular_object(self):
+        self._test_circular(Decimal)
+
+# Test stacking neighborhood iterators
+class TestStackedNeighborhoodIter(TestCase):
+    # Simple, 1d test: stacking 2 constant-padded neigh iterators
+    def test_simple_const(self):
+        dt = np.float64
+        # Test zero and one padding for simple data type
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([1], dtype=dt),
+             np.array([2], dtype=dt),
+             np.array([3], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-2, 4], NEIGH_MODE['zero'],
+                [0, 0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([1, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-1, 1], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+    # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # mirror padding
+    def test_simple_mirror(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 1], dtype=dt),
+             np.array([1, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 3], dtype=dt),
+             np.array([3, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['mirror'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # circular padding
+    def test_simple_circular(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 3, 1], dtype=dt),
+             np.array([3, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 1], dtype=dt),
+             np.array([3, 1, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['circular'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator
+    # being strictly within the array
+    def test_simple_strict_within(self):
+        dt = np.float64
+        # Stacking zero on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+class TestWarnings(object):
+
+    def test_complex_warning(self):
+        x = np.array([1, 2])
+        y = np.array([1-2j, 1+2j])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", np.ComplexWarning)
+            assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y)
+            assert_equal(x, [1, 2])
+
+
+class TestMinScalarType(object):
+
+    def test_usigned_shortshort(self):
+        dt = np.min_scalar_type(2**8-1)
+        wanted = np.dtype('uint8')
+        assert_equal(wanted, dt)
+
+    def test_usigned_short(self):
+        dt = np.min_scalar_type(2**16-1)
+        wanted = np.dtype('uint16')
+        assert_equal(wanted, dt)
+
+    def test_usigned_int(self):
+        dt = np.min_scalar_type(2**32-1)
+        wanted = np.dtype('uint32')
+        assert_equal(wanted, dt)
+
+    def test_usigned_longlong(self):
+        dt = np.min_scalar_type(2**63-1)
+        wanted = np.dtype('uint64')
+        assert_equal(wanted, dt)
+
+    def test_object(self):
+        dt = np.min_scalar_type(2**64)
+        wanted = np.dtype('O')
+        assert_equal(wanted, dt)
+
+
+if sys.version_info[:2] == (2, 6):
+    from numpy.core.multiarray import memorysimpleview as memoryview
+
+from numpy.core._internal import _dtype_from_pep3118
+
+
+class TestPEP3118Dtype(object):
+    def _check(self, spec, wanted):
+        dt = np.dtype(wanted)
+        if isinstance(wanted, list) and isinstance(wanted[-1], tuple):
+            if wanted[-1][0] == '':
+                names = list(dt.names)
+                names[-1] = ''
+                dt.names = tuple(names)
+        assert_equal(_dtype_from_pep3118(spec), dt,
+                     err_msg="spec %r != dtype %r" % (spec, wanted))
+
+    def test_native_padding(self):
+        align = np.dtype('i').alignment
+        for j in range(8):
+            if j == 0:
+                s = 'bi'
+            else:
+                s = 'b%dxi' % j
+            self._check('@'+s, {'f0': ('i1', 0),
+                                'f1': ('i', align*(1 + j//align))})
+            self._check('='+s, {'f0': ('i1', 0),
+                                'f1': ('i', 1+j)})
+
+    def test_native_padding_2(self):
+        # Native padding should work also for structs and sub-arrays
+        self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
+        self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
+
+    def test_trailing_padding(self):
+        # Trailing padding should be included, *and*, the item size
+        # should match the alignment if in aligned mode
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('ix', [('f0', 'i'), ('', VV(1))])
+        self._check('ixx', [('f0', 'i'), ('', VV(2))])
+        self._check('ixxx', [('f0', 'i'), ('', VV(3))])
+        self._check('ixxxx', [('f0', 'i'), ('', VV(4))])
+        self._check('i7x', [('f0', 'i'), ('', VV(7))])
+
+        self._check('^ix', [('f0', 'i'), ('', 'V1')])
+        self._check('^ixx', [('f0', 'i'), ('', 'V2')])
+        self._check('^ixxx', [('f0', 'i'), ('', 'V3')])
+        self._check('^ixxxx', [('f0', 'i'), ('', 'V4')])
+        self._check('^i7x', [('f0', 'i'), ('', 'V7')])
+
+    def test_native_padding_3(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'),
+                    ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
+
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
+
+    def test_padding_with_array_inside_struct(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)),
+                    ('d', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
+
+    def test_byteorder_inside_struct(self):
+        # The byte order after @T{=i} should be '=', not '@'.
+        # Check this by noting the absence of native alignment.
+        self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0),
+                                 'f1': ('i', 5)})
+
+    def test_intra_padding(self):
+        # Natively aligned sub-arrays may require some internal padding
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('(3)T{ix}', ({'f0': ('i', 0), '': (VV(1), 4)}, (3,)))
+
+
+class TestNewBufferProtocol(object):
+    def _check_roundtrip(self, obj):
+        obj = np.asarray(obj)
+        x = memoryview(obj)
+        y = np.asarray(x)
+        y2 = np.array(x)
+        assert_(not y.flags.owndata)
+        assert_(y2.flags.owndata)
+
+        assert_equal(y.dtype, obj.dtype)
+        assert_equal(y.shape, obj.shape)
+        assert_array_equal(obj, y)
+
+        assert_equal(y2.dtype, obj.dtype)
+        assert_equal(y2.shape, obj.shape)
+        assert_array_equal(obj, y2)
+
+    def test_roundtrip(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i4')
+        self._check_roundtrip(x)
+
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        self._check_roundtrip(x)
+
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        self._check_roundtrip(x)
+
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('xxx'), True, 1.0)],
+                dtype=dt)
+        self._check_roundtrip(x)
+
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))])
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i4')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i4')
+        self._check_roundtrip(x)
+
+        # check long long can be represented as non-native
+        x = np.array([1, 2, 3], dtype='>q')
+        self._check_roundtrip(x)
+
+        # Native-only data types can be passed through the buffer interface
+        # only in native byte order
+        if sys.byteorder == 'little':
+            x = np.array([1, 2, 3], dtype='>g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+            x = np.array([1, 2, 3], dtype='<g')
+            self._check_roundtrip(x)
+        else:
+            x = np.array([1, 2, 3], dtype='>g')
+            self._check_roundtrip(x)
+            x = np.array([1, 2, 3], dtype='<g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+
+    def test_roundtrip_half(self):
+        half_list = [
+            1.0,
+            -2.0,
+            6.5504 * 10**4,  # (max half precision)
+            2**-14,  # ~= 6.10352 * 10**-5 (minimum positive normal)
+            2**-24,  # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
+            0.0,
+            -0.0,
+            float('+inf'),
+            float('-inf'),
+            0.333251953125,  # ~= 1/3
+        ]
+
+        x = np.array(half_list, dtype='>e')
+        self._check_roundtrip(x)
+        x = np.array(half_list, dtype='<e')
+        self._check_roundtrip(x)
+
+    def test_roundtrip_single_types(self):
+        for typ in np.typeDict.values():
+            dtype = np.dtype(typ)
+
+            if dtype.char in 'Mm':
+                # datetimes cannot be used in buffers
+                continue
+            if dtype.char == 'V':
+                # skip void
+                continue
+
+            x = np.zeros(4, dtype=dtype)
+            self._check_roundtrip(x)
+
+            if dtype.char not in 'qQgG':
+                dt = dtype.newbyteorder('<')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+                dt = dtype.newbyteorder('>')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+    def test_roundtrip_scalar(self):
+        # Issue #4015.
+        self._check_roundtrip(0)
+
+    def test_export_simple_1d(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i')
+        y = memoryview(x)
+        assert_equal(y.format, 'i')
+        assert_equal(y.shape, (5,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.strides, (4,))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_simple_nd(self):
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        y = memoryview(x)
+        assert_equal(y.format, 'd')
+        assert_equal(y.shape, (2, 2))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (16, 8))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 8)
+
+    def test_export_discontiguous(self):
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        y = memoryview(x)
+        assert_equal(y.format, 'f')
+        assert_equal(y.shape, (3, 3))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (36, 4))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_record(self):
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('   '), True, 1.0)],
+                dtype=dt)
+        y = memoryview(x)
+        assert_equal(y.shape, (1,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.suboffsets, EMPTY)
+
+        sz = sum([np.dtype(b).itemsize for a, b in dt])
+        if np.dtype('l').itemsize == 4:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        else:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides
+        if not (np.ones(1).strides[0] == np.iinfo(np.intp).max):
+            assert_equal(y.strides, (sz,))
+        assert_equal(y.itemsize, sz)
+
+    def test_export_subarray(self):
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))])
+        y = memoryview(x)
+        assert_equal(y.format, 'T{(2,2)i:a:}')
+        assert_equal(y.shape, EMPTY)
+        assert_equal(y.ndim, 0)
+        assert_equal(y.strides, EMPTY)
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 16)
+
+    def test_export_endian(self):
+        x = np.array([1, 2, 3], dtype='>i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, '>i')
+        else:
+            assert_equal(y.format, 'i')
+
+        x = np.array([1, 2, 3], dtype='<i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, 'i')
+        else:
+            assert_equal(y.format, '<i')
+
+    def test_export_flags(self):
+        # Check SIMPLE flag, see also gh-3613 (exception should be BufferError)
+        assert_raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
+
+    def test_padding(self):
+        for j in range(8):
+            x = np.array([(1,), (2,)], dtype={'f0': (int, j)})
+            self._check_roundtrip(x)
+
+    def test_reference_leak(self):
+        count_1 = sys.getrefcount(np.core._internal)
+        a = np.zeros(4)
+        b = memoryview(a)
+        c = np.asarray(b)
+        count_2 = sys.getrefcount(np.core._internal)
+        assert_equal(count_1, count_2)
+        del c  # avoid pyflakes unused variable warning.
+
+    def test_padded_struct_array(self):
+        dt1 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        x1 = np.arange(dt1.itemsize, dtype=np.int8).view(dt1)
+        self._check_roundtrip(x1)
+
+        dt2 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')],
+                align=True)
+        x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
+        self._check_roundtrip(x2)
+
+        dt3 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
+        self._check_roundtrip(x3)
+
+    def test_relaxed_strides(self):
+        # Test that relaxed strides are converted to non-relaxed
+        c = np.ones((1, 10, 10), dtype='i8')
+
+        # Check for NPY_RELAXED_STRIDES_CHECKING:
+        if np.ones((10, 1), order="C").flags.f_contiguous:
+            c.strides = (-1, 80, 8)
+
+        assert_(memoryview(c).strides == (800, 80, 8))
+
+        # Writing C-contiguous data to a BytesIO buffer should work
+        fd = io.BytesIO()
+        fd.write(c.data)
+
+        fortran = c.T
+        assert_(memoryview(fortran).strides == (8, 80, 800))
+
+        arr = np.ones((1, 10))
+        if arr.flags.f_contiguous:
+            shape, strides = get_buffer_info(arr, ['F_CONTIGUOUS'])
+            assert_(strides[0] == 8)
+            arr = np.ones((10, 1), order='F')
+            shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
+            assert_(strides[-1] == 8)
+
+
+class TestArrayAttributeDeletion(object):
+
+    def test_multiarray_writable_attributes_deletion(self):
+        """ticket #2046, should not seqfault, raise AttributeError"""
+        a = np.ones(2)
+        attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_not_writable_attributes_deletion(self):
+        a = np.ones(2)
+        attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
+                "ctypes", "T", "__array_interface__", "__array_struct__",
+                "__array_priority__", "__array_finalize__"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ['updateifcopy', 'aligned', 'writeable']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_not_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
+                "owndata", "fnc", "forc", "behaved", "carray", "farray",
+                "num"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+
+def test_array_interface():
+    # Test scalar coercion within the array interface
+    class Foo(object):
+        def __init__(self, value):
+            self.value = value
+            self.iface = {'typestr': '=f8'}
+
+        def __float__(self):
+            return float(self.value)
+
+        @property
+        def __array_interface__(self):
+            return self.iface
+
+    f = Foo(0.5)
+    assert_equal(np.array(f), 0.5)
+    assert_equal(np.array([f]), [0.5])
+    assert_equal(np.array([f, f]), [0.5, 0.5])
+    assert_equal(np.array(f).dtype, np.dtype('=f8'))
+    # Test various shape definitions
+    f.iface['shape'] = ()
+    assert_equal(np.array(f), 0.5)
+    f.iface['shape'] = None
+    assert_raises(TypeError, np.array, f)
+    f.iface['shape'] = (1, 1)
+    assert_equal(np.array(f), [[0.5]])
+    f.iface['shape'] = (2,)
+    assert_raises(ValueError, np.array, f)
+
+    # test scalar with no shape
+    class ArrayLike(object):
+        array = np.array(1)
+        __array_interface__ = array.__array_interface__
+    assert_equal(np.array(ArrayLike()), 1)
+
+
+def test_array_interface_itemsize():
+    # See gh-6361
+    my_dtype = np.dtype({'names': ['A', 'B'], 'formats': ['f4', 'f4'],
+                         'offsets': [0, 8], 'itemsize': 16})
+    a = np.ones(10, dtype=my_dtype)
+    descr_t = np.dtype(a.__array_interface__['descr'])
+    typestr_t = np.dtype(a.__array_interface__['typestr'])
+    assert_equal(descr_t.itemsize, typestr_t.itemsize)
+
+
+def test_flat_element_deletion():
+    it = np.ones(3).flat
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+
+def test_scalar_element_deletion():
+    a = np.zeros(2, dtype=[('x', 'int'), ('y', 'int')])
+    assert_raises(ValueError, a[0].__delitem__, 'x')
+
+
+class TestMemEventHook(TestCase):
+    def test_mem_seteventhook(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+        test_pydatamem_seteventhook_start()
+        # force an allocation and free of a numpy array
+        # needs to be larger then limit of small memory cacher in ctors.c
+        a = np.zeros(1000)
+        del a
+        test_pydatamem_seteventhook_end()
+
+class TestMapIter(TestCase):
+    def test_mapiter(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+
+        a = np.arange(12).reshape((3, 4)).astype(float)
+        index = ([1, 1, 2, 0],
+                 [0, 0, 2, 3])
+        vals = [50, 50, 30, 16]
+
+        test_inplace_increment(a, index, vals)
+        assert_equal(a, [[0.00, 1., 2.0, 19.],
+                         [104., 5., 6.0, 7.0],
+                         [8.00, 9., 40., 11.]])
+
+        b = np.arange(6).astype(float)
+        index = (np.array([1, 2, 0]),)
+        vals = [50, 4, 100.1]
+        test_inplace_increment(b, index, vals)
+        assert_equal(b, [100.1,  51.,   6.,   3.,   4.,   5.])
+
+
+class TestAsCArray(TestCase):
+    def test_1darray(self):
+        array = np.arange(24, dtype=np.double)
+        from_c = test_as_c_array(array, 3)
+        assert_equal(array[3], from_c)
+
+    def test_2darray(self):
+        array = np.arange(24, dtype=np.double).reshape(3, 8)
+        from_c = test_as_c_array(array, 2, 4)
+        assert_equal(array[2, 4], from_c)
+
+    def test_3darray(self):
+        array = np.arange(24, dtype=np.double).reshape(2, 3, 4)
+        from_c = test_as_c_array(array, 1, 2, 3)
+        assert_equal(array[1, 2, 3], from_c)
+
+
+class TestConversion(TestCase):
+    def test_array_scalar_relational_operation(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+
+            # Unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+class TestWhere(TestCase):
+    def test_basic(self):
+        dts = [np.bool, np.int16, np.int32, np.int64, np.double, np.complex128,
+               np.longdouble, np.clongdouble]
+        for dt in dts:
+            c = np.ones(53, dtype=np.bool)
+            assert_equal(np.where( c, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(~c, dt(0), dt(1)), dt(1))
+            assert_equal(np.where(True, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(False, dt(0), dt(1)), dt(1))
+            d = np.ones_like(c).astype(dt)
+            e = np.zeros_like(d)
+            r = d.astype(dt)
+            c[7] = False
+            r[7] = e[7]
+            assert_equal(np.where(c, e, e), e)
+            assert_equal(np.where(c, d, e), r)
+            assert_equal(np.where(c, d, e[0]), r)
+            assert_equal(np.where(c, d[0], e), r)
+            assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2])
+            assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2])
+            assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3])
+            assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3])
+            assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2])
+            assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3])
+            assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3])
+
+    def test_exotic(self):
+        # object
+        assert_array_equal(np.where(True, None, None), np.array(None))
+        # zero sized
+        m = np.array([], dtype=bool).reshape(0, 3)
+        b = np.array([], dtype=np.float64).reshape(0, 3)
+        assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3))
+
+        # object cast
+        d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313,
+                      0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013,
+                      1.267, 0.229, -1.39, 0.487])
+        nan = float('NaN')
+        e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan,
+                     'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'],
+                     dtype=object)
+        m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+                      0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool)
+
+        r = e[:]
+        r[np.where(m)] = d[np.where(m)]
+        assert_array_equal(np.where(m, d, e), r)
+
+        r = e[:]
+        r[np.where(~m)] = d[np.where(~m)]
+        assert_array_equal(np.where(m, e, d), r)
+
+        assert_array_equal(np.where(m, e, e), e)
+
+        # minimal dtype result with NaN scalar (e.g required by pandas)
+        d = np.array([1., 2.], dtype=np.float32)
+        e = float('NaN')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('-Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        # also check upcast
+        e = float(1e150)
+        assert_equal(np.where(True, d, e).dtype, np.float64)
+
+    def test_ndim(self):
+        c = [True, False]
+        a = np.zeros((2, 25))
+        b = np.ones((2, 25))
+        r = np.where(np.array(c)[:,np.newaxis], a, b)
+        assert_array_equal(r[0], a[0])
+        assert_array_equal(r[1], b[0])
+
+        a = a.T
+        b = b.T
+        r = np.where(c, a, b)
+        assert_array_equal(r[:,0], a[:,0])
+        assert_array_equal(r[:,1], b[:,0])
+
+    def test_dtype_mix(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        a = np.uint32(1)
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                      dtype=np.float64)
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype(np.float32)
+        b = b.astype(np.int64)
+        assert_equal(np.where(c, a, b), r)
+
+        # non bool mask
+        c = c.astype(np.int)
+        c[c != 0] = 34242324
+        assert_equal(np.where(c, a, b), r)
+        # invert
+        tmpmask = c != 0
+        c[c == 0] = 41247212
+        c[tmpmask] = 0
+        assert_equal(np.where(c, b, a), r)
+
+    def test_foreign(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        a = np.ones(1, dtype='>i4')
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        b = b.astype('>f8')
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype('<i4')
+        assert_equal(np.where(c, a, b), r)
+
+        c = c.astype('>i4')
+        assert_equal(np.where(c, a, b), r)
+
+    def test_error(self):
+        c = [True, True]
+        a = np.ones((4, 5))
+        b = np.ones((5, 5))
+        assert_raises(ValueError, np.where, c, a, a)
+        assert_raises(ValueError, np.where, c[0], a, b)
+
+    def test_string(self):
+        # gh-4778 check strings are properly filled with nulls
+        a = np.array("abc")
+        b = np.array("x" * 753)
+        assert_equal(np.where(True, a, b), "abc")
+        assert_equal(np.where(False, b, a), "abc")
+
+        # check native datatype sized strings
+        a = np.array("abcd")
+        b = np.array("x" * 8)
+        assert_equal(np.where(True, a, b), "abcd")
+        assert_equal(np.where(False, b, a), "abcd")
+
+
+class TestSizeOf(TestCase):
+
+    def test_empty_array(self):
+        x = np.array([])
+        assert_(sys.getsizeof(x) > 0)
+
+    def check_array(self, dtype):
+        elem_size = dtype(0).itemsize
+
+        for length in [10, 50, 100, 500]:
+            x = np.arange(length, dtype=dtype)
+            assert_(sys.getsizeof(x) > length * elem_size)
+
+    def test_array_int32(self):
+        self.check_array(np.int32)
+
+    def test_array_int64(self):
+        self.check_array(np.int64)
+
+    def test_array_float32(self):
+        self.check_array(np.float32)
+
+    def test_array_float64(self):
+        self.check_array(np.float64)
+
+    def test_view(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d[...]) < sys.getsizeof(d))
+
+    def test_reshape(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy()))
+
+    def test_resize(self):
+        d = np.ones(100)
+        old = sys.getsizeof(d)
+        d.resize(50)
+        assert_(old > sys.getsizeof(d))
+        d.resize(150)
+        assert_(old < sys.getsizeof(d))
+
+    def test_error(self):
+        d = np.ones(100)
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestHashing(TestCase):
+
+    def test_arrays_not_hashable(self):
+        x = np.ones(3)
+        assert_raises(TypeError, hash, x)
+
+    def test_collections_hashable(self):
+        x = np.array([])
+        self.assertFalse(isinstance(x, collections.Hashable))
+
+
+class TestArrayPriority(TestCase):
+    # This will go away when __array_priority__ is settled, meanwhile
+    # it serves to check unintended changes.
+    op = operator
+    binary_ops = [
+        op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod,
+        op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt,
+        op.ge, op.lt, op.le, op.ne, op.eq
+        ]
+
+    if sys.version_info[0] < 3:
+        binary_ops.append(op.div)
+
+    class Foo(np.ndarray):
+        __array_priority__ = 100.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Bar(np.ndarray):
+        __array_priority__ = 101.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Other(object):
+        __array_priority__ = 1000.
+
+        def _all(self, other):
+            return self.__class__()
+
+        __add__ = __radd__ = _all
+        __sub__ = __rsub__ = _all
+        __mul__ = __rmul__ = _all
+        __pow__ = __rpow__ = _all
+        __div__ = __rdiv__ = _all
+        __mod__ = __rmod__ = _all
+        __truediv__ = __rtruediv__ = _all
+        __floordiv__ = __rfloordiv__ = _all
+        __and__ = __rand__ = _all
+        __xor__ = __rxor__ = _all
+        __or__ = __ror__ = _all
+        __lshift__ = __rlshift__ = _all
+        __rshift__ = __rrshift__ = _all
+        __eq__ = _all
+        __ne__ = _all
+        __gt__ = _all
+        __ge__ = _all
+        __lt__ = _all
+        __le__ = _all
+
+    def test_ndarray_subclass(self):
+        a = np.array([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_ndarray_other(self):
+        a = np.array([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+    def test_subclass_subclass(self):
+        a = self.Foo([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_subclass_other(self):
+        a = self.Foo([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+
+class TestBytestringArrayNonzero(TestCase):
+
+    def test_empty_bstring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.str))
+
+    def test_whitespace_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_bstring_array_is_truthy(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+class TestUnicodeArrayNonzero(TestCase):
+
+    def test_empty_ustring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.unicode))
+
+    def test_whitespace_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_ustring_array_is_truthy(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
new file mode 100644
index 0000000000..ed01979912
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
@@ -0,0 +1,2638 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+
+import numpy as np
+from numpy import array, arange, nditer, all
+from numpy.compat import asbytes, sixu
+from numpy.core.multiarray_tests import test_nditer_too_large
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_raises, dec
+    )
+
+
+def iter_multi_index(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.multi_index)
+        i.iternext()
+    return ret
+
+def iter_indices(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.index)
+        i.iternext()
+    return ret
+
+def iter_iterindices(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.iterindex)
+        i.iternext()
+    return ret
+
+def test_iter_refcount():
+    # Make sure the iterator doesn't leak
+
+    # Basic
+    a = arange(6)
+    dt = np.dtype('f4').newbyteorder()
+    rc_a = sys.getrefcount(a)
+    rc_dt = sys.getrefcount(dt)
+    it = nditer(a, [],
+                [['readwrite', 'updateifcopy']],
+                casting='unsafe',
+                op_dtypes=[dt])
+    assert_(not it.iterationneedsapi)
+    assert_(sys.getrefcount(a) > rc_a)
+    assert_(sys.getrefcount(dt) > rc_dt)
+    it = None
+    assert_equal(sys.getrefcount(a), rc_a)
+    assert_equal(sys.getrefcount(dt), rc_dt)
+
+    # With a copy
+    a = arange(6, dtype='f4')
+    dt = np.dtype('f4')
+    rc_a = sys.getrefcount(a)
+    rc_dt = sys.getrefcount(dt)
+    it = nditer(a, [],
+                [['readwrite']],
+                op_dtypes=[dt])
+    rc2_a = sys.getrefcount(a)
+    rc2_dt = sys.getrefcount(dt)
+    it2 = it.copy()
+    assert_(sys.getrefcount(a) > rc2_a)
+    assert_(sys.getrefcount(dt) > rc2_dt)
+    it = None
+    assert_equal(sys.getrefcount(a), rc2_a)
+    assert_equal(sys.getrefcount(dt), rc2_dt)
+    it2 = None
+    assert_equal(sys.getrefcount(a), rc_a)
+    assert_equal(sys.getrefcount(dt), rc_dt)
+
+    del it2  # avoid pyflakes unused variable warning
+
+def test_iter_best_order():
+    # The iterator should always find the iteration order
+    # with increasing memory addresses
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, [], [['readonly']])
+            assert_equal([x for x in i], a)
+            # Fortran-order
+            i = nditer(aview.T, [], [['readonly']])
+            assert_equal([x for x in i], a)
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), [], [['readonly']])
+                assert_equal([x for x in i], a)
+
+def test_iter_c_order():
+    # Test forcing C order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='C')
+            assert_equal([x for x in i], aview.ravel(order='C'))
+            # Fortran-order
+            i = nditer(aview.T, order='C')
+            assert_equal([x for x in i], aview.T.ravel(order='C'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='C')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='C'))
+
+def test_iter_f_order():
+    # Test forcing F order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='F')
+            assert_equal([x for x in i], aview.ravel(order='F'))
+            # Fortran-order
+            i = nditer(aview.T, order='F')
+            assert_equal([x for x in i], aview.T.ravel(order='F'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='F')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='F'))
+
+def test_iter_c_or_f_order():
+    # Test forcing any contiguous (C or F) order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='A')
+            assert_equal([x for x in i], aview.ravel(order='A'))
+            # Fortran-order
+            i = nditer(aview.T, order='A')
+            assert_equal([x for x in i], aview.T.ravel(order='A'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='A')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='A'))
+
+def test_iter_best_order_multi_index_1d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0,), (1,), (2,), (3,)])
+    # 1D reversed order
+    i = nditer(a[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(3,), (2,), (1,), (0,)])
+
+def test_iter_best_order_multi_index_2d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 0), (1, 1), (1, 2), (0, 0), (0, 1), (0, 2)])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 2), (0, 1), (0, 0), (1, 2), (1, 1), (1, 0)])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 2), (1, 1), (1, 0), (0, 2), (0, 1), (0, 0)])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 0), (0, 0), (1, 1), (0, 1), (1, 2), (0, 2)])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                                   ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 2), (1, 2), (0, 1), (1, 1), (0, 0), (1, 0)])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                                   ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 2), (0, 2), (1, 1), (0, 1), (1, 0), (0, 0)])
+
+def test_iter_best_order_multi_index_3d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1),
+                             (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1)])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0),
+                             (0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1)])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1),
+                             (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1)])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 2, 0), (0, 2, 1), (0, 1, 0), (0, 1, 1), (0, 0, 0), (0, 0, 1),
+                             (1, 2, 0), (1, 2, 1), (1, 1, 0), (1, 1, 1), (1, 0, 0), (1, 0, 1)])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 1), (0, 0, 0), (0, 1, 1), (0, 1, 0), (0, 2, 1), (0, 2, 0),
+                             (1, 0, 1), (1, 0, 0), (1, 1, 1), (1, 1, 0), (1, 2, 1), (1, 2, 0)])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0), (1, 2, 0), (0, 2, 0),
+                             (1, 0, 1), (0, 0, 1), (1, 1, 1), (0, 1, 1), (1, 2, 1), (0, 2, 1)])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 2, 0), (1, 2, 0), (0, 1, 0), (1, 1, 0), (0, 0, 0), (1, 0, 0),
+                             (0, 2, 1), (1, 2, 1), (0, 1, 1), (1, 1, 1), (0, 0, 1), (1, 0, 1)])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1),
+                             (0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0)])
+
+def test_iter_best_order_c_index_1d():
+    # The C index should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3])
+    # 1D reversed order
+    i = nditer(a[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 2, 1, 0])
+
+def test_iter_best_order_c_index_2d():
+    # The C index should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'),
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 3, 1, 4, 2, 5])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 4, 5, 0, 1, 2])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [2, 1, 0, 5, 4, 3])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 0, 4, 1, 5, 2])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [2, 5, 1, 4, 0, 3])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 2, 4, 1, 3, 0])
+
+def test_iter_best_order_c_index_3d():
+    # The C index should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
+
+def test_iter_best_order_f_index_1d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3])
+    # 1D reversed order
+    i = nditer(a[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 2, 1, 0])
+
+def test_iter_best_order_f_index_2d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 2, 4, 1, 3, 5])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'),
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [1, 3, 5, 0, 2, 4])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [4, 2, 0, 5, 3, 1])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 3, 1, 4, 2, 0])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [1, 0, 3, 2, 5, 4])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [4, 5, 2, 3, 0, 1])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
+
+def test_iter_best_order_f_index_3d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
+
+def test_iter_no_inner_full_coalesce():
+    # Check no_inner iterators which coalesce into a single inner loop
+
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        size = np.prod(shape)
+        a = arange(size)
+        # Test each combination of forward and backwards indexing
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, ['external_loop'], [['readonly']])
+            assert_equal(i.ndim, 1)
+            assert_equal(i[0].shape, (size,))
+            # Fortran-order
+            i = nditer(aview.T, ['external_loop'], [['readonly']])
+            assert_equal(i.ndim, 1)
+            assert_equal(i[0].shape, (size,))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1),
+                                    ['external_loop'], [['readonly']])
+                assert_equal(i.ndim, 1)
+                assert_equal(i[0].shape, (size,))
+
+def test_iter_no_inner_dim_coalescing():
+    # Check no_inner iterators whose dimensions may not coalesce completely
+
+    # Skipping the last element in a dimension prevents coalescing
+    # with the next-bigger dimension
+    a = arange(24).reshape(2, 3, 4)[:,:, :-1]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 2)
+    assert_equal(i[0].shape, (3,))
+    a = arange(24).reshape(2, 3, 4)[:, :-1,:]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 2)
+    assert_equal(i[0].shape, (8,))
+    a = arange(24).reshape(2, 3, 4)[:-1,:,:]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    assert_equal(i[0].shape, (12,))
+
+    # Even with lots of 1-sized dimensions, should still coalesce
+    a = arange(24).reshape(1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1)
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    assert_equal(i[0].shape, (24,))
+
+def test_iter_dim_coalescing():
+    # Check that the correct number of dimensions are coalesced
+
+    # Tracking a multi-index disables coalescing
+    a = arange(24).reshape(2, 3, 4)
+    i = nditer(a, ['multi_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+
+    # A tracked index can allow coalescing if it's compatible with the array
+    a3d = arange(24).reshape(2, 3, 4)
+    i = nditer(a3d, ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.swapaxes(0, 1), ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, ['f_index'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T.swapaxes(0, 1), ['f_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+
+    # When C or F order is forced, coalescing may still occur
+    a3d = arange(24).reshape(2, 3, 4)
+    i = nditer(a3d, order='C')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T, order='C')
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d, order='F')
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, order='F')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d, order='A')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T, order='A')
+    assert_equal(i.ndim, 1)
+
+def test_iter_broadcasting():
+    # Standard NumPy broadcasting rules
+
+    # 1D with scalar
+    i = nditer([arange(6), np.int32(2)], ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (6,))
+
+    # 2D with scalar
+    i = nditer([arange(6).reshape(2, 3), np.int32(2)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    # 2D with 1D
+    i = nditer([arange(6).reshape(2, 3), arange(3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    i = nditer([arange(2).reshape(2, 1), arange(3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    # 2D with 2D
+    i = nditer([arange(2).reshape(2, 1), arange(3).reshape(1, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+
+    # 3D with scalar
+    i = nditer([np.int32(2), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 1D
+    i = nditer([arange(3), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(3), arange(8).reshape(4, 2, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 2D
+    i = nditer([arange(6).reshape(2, 3), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(2).reshape(2, 1), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(3).reshape(1, 3), arange(8).reshape(4, 2, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 3D
+    i = nditer([arange(2).reshape(1, 2, 1), arange(3).reshape(1, 1, 3),
+                        arange(4).reshape(4, 1, 1)],
+                        ['multi_index'], [['readonly']]*3)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(6).reshape(1, 2, 3), arange(4).reshape(4, 1, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(24).reshape(4, 2, 3), arange(12).reshape(4, 1, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+
+def test_iter_itershape():
+    # Check that allocated outputs work with a specified shape
+    a = np.arange(6, dtype='i2').reshape(2, 3)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (2, 3, 4))
+    assert_equal(i.operands[1].strides, (24, 8, 2))
+
+    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (3, 2, 4))
+    assert_equal(i.operands[1].strides, (8, 24, 2))
+
+    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            order='F',
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (3, 2, 4))
+    assert_equal(i.operands[1].strides, (2, 6, 12))
+
+    # If we specify 1 in the itershape, it shouldn't allow broadcasting
+    # of that dimension to a bigger value
+    assert_raises(ValueError, nditer, [a, None], [],
+                            [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, 1, 4))
+    # Test bug that for no op_axes but itershape, they are NULLed correctly
+    i = np.nditer([np.ones(2), None, None], itershape=(2,))
+
+def test_iter_broadcasting_errors():
+    # Check that errors are thrown for bad broadcasting shapes
+
+    # 1D with 1D
+    assert_raises(ValueError, nditer, [arange(2), arange(3)],
+                    [], [['readonly']]*2)
+    # 2D with 1D
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(2)],
+                    [], [['readonly']]*2)
+    # 2D with 2D
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(9).reshape(3, 3)],
+                    [], [['readonly']]*2)
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(4).reshape(2, 2)],
+                    [], [['readonly']]*2)
+    # 3D with 3D
+    assert_raises(ValueError, nditer,
+                    [arange(36).reshape(3, 3, 4), arange(24).reshape(2, 3, 4)],
+                    [], [['readonly']]*2)
+    assert_raises(ValueError, nditer,
+                    [arange(8).reshape(2, 4, 1), arange(24).reshape(2, 3, 4)],
+                    [], [['readonly']]*2)
+
+    # Verify that the error message mentions the right shapes
+    try:
+        nditer([arange(2).reshape(1, 2, 1),
+                arange(3).reshape(1, 3),
+                arange(6).reshape(2, 3)],
+               [],
+               [['readonly'], ['readonly'], ['writeonly', 'no_broadcast']])
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain the shape of the 3rd operand
+        assert_(msg.find('(2,3)') >= 0,
+                'Message "%s" doesn\'t contain operand shape (2,3)' % msg)
+        # The message should contain the broadcast shape
+        assert_(msg.find('(1,2,3)') >= 0,
+                'Message "%s" doesn\'t contain broadcast shape (1,2,3)' % msg)
+
+    try:
+        nditer([arange(6).reshape(2, 3), arange(2)],
+               [],
+               [['readonly'], ['readonly']],
+               op_axes=[[0, 1], [0, np.newaxis]],
+               itershape=(4, 3))
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain "shape->remappedshape" for each operand
+        assert_(msg.find('(2,3)->(2,3)') >= 0,
+            'Message "%s" doesn\'t contain operand shape (2,3)->(2,3)' % msg)
+        assert_(msg.find('(2,)->(2,newaxis)') >= 0,
+                ('Message "%s" doesn\'t contain remapped operand shape' +
+                '(2,)->(2,newaxis)') % msg)
+        # The message should contain the itershape parameter
+        assert_(msg.find('(4,3)') >= 0,
+                'Message "%s" doesn\'t contain itershape parameter (4,3)' % msg)
+
+    try:
+        nditer([np.zeros((2, 1, 1)), np.zeros((2,))],
+               [],
+               [['writeonly', 'no_broadcast'], ['readonly']])
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain the shape of the bad operand
+        assert_(msg.find('(2,1,1)') >= 0,
+            'Message "%s" doesn\'t contain operand shape (2,1,1)' % msg)
+        # The message should contain the broadcast shape
+        assert_(msg.find('(2,1,2)') >= 0,
+                'Message "%s" doesn\'t contain the broadcast shape (2,1,2)' % msg)
+
+def test_iter_flags_errors():
+    # Check that bad combinations of flags produce errors
+
+    a = arange(6)
+
+    # Not enough operands
+    assert_raises(ValueError, nditer, [], [], [])
+    # Too many operands
+    assert_raises(ValueError, nditer, [a]*100, [], [['readonly']]*100)
+    # Bad global flag
+    assert_raises(ValueError, nditer, [a], ['bad flag'], [['readonly']])
+    # Bad op flag
+    assert_raises(ValueError, nditer, [a], [], [['readonly', 'bad flag']])
+    # Bad order parameter
+    assert_raises(ValueError, nditer, [a], [], [['readonly']], order='G')
+    # Bad casting parameter
+    assert_raises(ValueError, nditer, [a], [], [['readonly']], casting='noon')
+    # op_flags must match ops
+    assert_raises(ValueError, nditer, [a]*3, [], [['readonly']]*2)
+    # Cannot track both a C and an F index
+    assert_raises(ValueError, nditer, a,
+                ['c_index', 'f_index'], [['readonly']])
+    # Inner iteration and multi-indices/indices are incompatible
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'multi_index'], [['readonly']])
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'c_index'], [['readonly']])
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'f_index'], [['readonly']])
+    # Must specify exactly one of readwrite/readonly/writeonly per operand
+    assert_raises(ValueError, nditer, a, [], [[]])
+    assert_raises(ValueError, nditer, a, [], [['readonly', 'writeonly']])
+    assert_raises(ValueError, nditer, a, [], [['readonly', 'readwrite']])
+    assert_raises(ValueError, nditer, a, [], [['writeonly', 'readwrite']])
+    assert_raises(ValueError, nditer, a,
+                [], [['readonly', 'writeonly', 'readwrite']])
+    # Python scalars are always readonly
+    assert_raises(TypeError, nditer, 1.5, [], [['writeonly']])
+    assert_raises(TypeError, nditer, 1.5, [], [['readwrite']])
+    # Array scalars are always readonly
+    assert_raises(TypeError, nditer, np.int32(1), [], [['writeonly']])
+    assert_raises(TypeError, nditer, np.int32(1), [], [['readwrite']])
+    # Check readonly array
+    a.flags.writeable = False
+    assert_raises(ValueError, nditer, a, [], [['writeonly']])
+    assert_raises(ValueError, nditer, a, [], [['readwrite']])
+    a.flags.writeable = True
+    # Multi-indices available only with the multi_index flag
+    i = nditer(arange(6), [], [['readonly']])
+    assert_raises(ValueError, lambda i:i.multi_index, i)
+    # Index available only with an index flag
+    assert_raises(ValueError, lambda i:i.index, i)
+    # GotoCoords and GotoIndex incompatible with buffering or no_inner
+
+    def assign_multi_index(i):
+        i.multi_index = (0,)
+
+    def assign_index(i):
+        i.index = 0
+
+    def assign_iterindex(i):
+        i.iterindex = 0
+
+    def assign_iterrange(i):
+        i.iterrange = (0, 1)
+    i = nditer(arange(6), ['external_loop'])
+    assert_raises(ValueError, assign_multi_index, i)
+    assert_raises(ValueError, assign_index, i)
+    assert_raises(ValueError, assign_iterindex, i)
+    assert_raises(ValueError, assign_iterrange, i)
+    i = nditer(arange(6), ['buffered'])
+    assert_raises(ValueError, assign_multi_index, i)
+    assert_raises(ValueError, assign_index, i)
+    assert_raises(ValueError, assign_iterrange, i)
+    # Can't iterate if size is zero
+    assert_raises(ValueError, nditer, np.array([]))
+
+def test_iter_slice():
+    a, b, c = np.arange(3), np.arange(3), np.arange(3.)
+    i = nditer([a, b, c], [], ['readwrite'])
+    i[0:2] = (3, 3)
+    assert_equal(a, [3, 1, 2])
+    assert_equal(b, [3, 1, 2])
+    assert_equal(c, [0, 1, 2])
+    i[1] = 12
+    assert_equal(i[0:2], [3, 12])
+
+def test_iter_nbo_align_contig():
+    # Check that byte order, alignment, and contig changes work
+
+    # Byte order change by requesting a specific dtype
+    a = np.arange(6, dtype='f4')
+    au = a.byteswap().newbyteorder()
+    assert_(a.dtype.byteorder != au.dtype.byteorder)
+    i = nditer(au, [], [['readwrite', 'updateifcopy']],
+                        casting='equiv',
+                        op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 2
+    i = None
+    assert_equal(au, [2]*6)
+
+    # Byte order change by requesting NBO
+    a = np.arange(6, dtype='f4')
+    au = a.byteswap().newbyteorder()
+    assert_(a.dtype.byteorder != au.dtype.byteorder)
+    i = nditer(au, [], [['readwrite', 'updateifcopy', 'nbo']], casting='equiv')
+    assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 2
+    i = None
+    assert_equal(au, [2]*6)
+
+    # Unaligned input
+    a = np.zeros((6*4+1,), dtype='i1')[1:]
+    a.dtype = 'f4'
+    a[:] = np.arange(6, dtype='f4')
+    assert_(not a.flags.aligned)
+    # Without 'aligned', shouldn't copy
+    i = nditer(a, [], [['readonly']])
+    assert_(not i.operands[0].flags.aligned)
+    assert_equal(i.operands[0], a)
+    # With 'aligned', should make a copy
+    i = nditer(a, [], [['readwrite', 'updateifcopy', 'aligned']])
+    assert_(i.operands[0].flags.aligned)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 3
+    i = None
+    assert_equal(a, [3]*6)
+
+    # Discontiguous input
+    a = arange(12)
+    # If it is contiguous, shouldn't copy
+    i = nditer(a[:6], [], [['readonly']])
+    assert_(i.operands[0].flags.contiguous)
+    assert_equal(i.operands[0], a[:6])
+    # If it isn't contiguous, should buffer
+    i = nditer(a[::2], ['buffered', 'external_loop'],
+                        [['readonly', 'contig']],
+                        buffersize=10)
+    assert_(i[0].flags.contiguous)
+    assert_equal(i[0], a[::2])
+
+def test_iter_array_cast():
+    # Check that arrays are cast as requested
+
+    # No cast 'f4' -> 'f4'
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+    i = nditer(a, [], [['readwrite']], op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+
+    # Byte-order cast '<f4' -> '>f4'
+    a = np.arange(6, dtype='<f4').reshape(2, 3)
+    i = nditer(a, [], [['readwrite', 'updateifcopy']],
+            casting='equiv',
+            op_dtypes=[np.dtype('>f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('>f4'))
+
+    # Safe case 'f4' -> 'f8'
+    a = np.arange(24, dtype='f4').reshape(2, 3, 4).swapaxes(1, 2)
+    i = nditer(a, [], [['readonly', 'copy']],
+            casting='safe',
+            op_dtypes=[np.dtype('f8')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f8'))
+    # The memory layout of the temporary should match a (a is (48,4,16))
+    # except negative strides get flipped to positive strides.
+    assert_equal(i.operands[0].strides, (96, 8, 32))
+    a = a[::-1,:, ::-1]
+    i = nditer(a, [], [['readonly', 'copy']],
+            casting='safe',
+            op_dtypes=[np.dtype('f8')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f8'))
+    assert_equal(i.operands[0].strides, (96, 8, 32))
+
+    # Same-kind cast 'f8' -> 'f4' -> 'f8'
+    a = np.arange(24, dtype='f8').reshape(2, 3, 4).T
+    i = nditer(a, [],
+            [['readwrite', 'updateifcopy']],
+            casting='same_kind',
+            op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+    assert_equal(i.operands[0].strides, (4, 16, 48))
+    # Check that UPDATEIFCOPY is activated
+    i.operands[0][2, 1, 1] = -12.5
+    assert_(a[2, 1, 1] != -12.5)
+    i = None
+    assert_equal(a[2, 1, 1], -12.5)
+
+    a = np.arange(6, dtype='i4')[::-2]
+    i = nditer(a, [],
+            [['writeonly', 'updateifcopy']],
+            casting='unsafe',
+            op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+    # Even though the stride was negative in 'a', it
+    # becomes positive in the temporary
+    assert_equal(i.operands[0].strides, (4,))
+    i.operands[0][:] = [1, 2, 3]
+    i = None
+    assert_equal(a, [1, 2, 3])
+
+def test_iter_array_cast_errors():
+    # Check that invalid casts are caught
+
+    # Need to enable copying for casts to occur
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly']], op_dtypes=[np.dtype('f8')])
+    # Also need to allow casting for casts to occur
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']], casting='no',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']], casting='equiv',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='no',
+                op_dtypes=[np.dtype('f4')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='equiv',
+                op_dtypes=[np.dtype('f4')])
+    # '<f4' -> '>f4' should not work with casting='no'
+    assert_raises(TypeError, nditer, arange(2, dtype='<f4'), [],
+                [['readonly', 'copy']], casting='no',
+                op_dtypes=[np.dtype('>f4')])
+    # 'f4' -> 'f8' is a safe cast, but 'f8' -> 'f4' isn't
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readwrite', 'updateifcopy']],
+                casting='safe',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['readwrite', 'updateifcopy']],
+                casting='safe',
+                op_dtypes=[np.dtype('f4')])
+    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('i4')])
+    assert_raises(TypeError, nditer, arange(2, dtype='i4'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('f4')])
+
+def test_iter_scalar_cast():
+    # Check that scalars are cast as requested
+
+    # No cast 'f4' -> 'f4'
+    i = nditer(np.float32(2.5), [], [['readonly']],
+                    op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.value.dtype, np.dtype('f4'))
+    assert_equal(i.value, 2.5)
+    # Safe cast 'f4' -> 'f8'
+    i = nditer(np.float32(2.5), [],
+                    [['readonly', 'copy']],
+                    casting='safe',
+                    op_dtypes=[np.dtype('f8')])
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.value.dtype, np.dtype('f8'))
+    assert_equal(i.value, 2.5)
+    # Same-kind cast 'f8' -> 'f4'
+    i = nditer(np.float64(2.5), [],
+                    [['readonly', 'copy']],
+                    casting='same_kind',
+                    op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.value.dtype, np.dtype('f4'))
+    assert_equal(i.value, 2.5)
+    # Unsafe cast 'f8' -> 'i4'
+    i = nditer(np.float64(3.0), [],
+                    [['readonly', 'copy']],
+                    casting='unsafe',
+                    op_dtypes=[np.dtype('i4')])
+    assert_equal(i.dtypes[0], np.dtype('i4'))
+    assert_equal(i.value.dtype, np.dtype('i4'))
+    assert_equal(i.value, 3)
+    # Readonly scalars may be cast even without setting COPY or BUFFERED
+    i = nditer(3, [], [['readonly']], op_dtypes=[np.dtype('f8')])
+    assert_equal(i[0].dtype, np.dtype('f8'))
+    assert_equal(i[0], 3.)
+
+def test_iter_scalar_cast_errors():
+    # Check that invalid casts are caught
+
+    # Need to allow copying/buffering for write casts of scalars to occur
+    assert_raises(TypeError, nditer, np.float32(2), [],
+                [['readwrite']], op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, 2.5, [],
+                [['readwrite']], op_dtypes=[np.dtype('f4')])
+    # 'f8' -> 'f4' isn't a safe cast if the value would overflow
+    assert_raises(TypeError, nditer, np.float64(1e60), [],
+                [['readonly']],
+                casting='safe',
+                op_dtypes=[np.dtype('f4')])
+    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
+    assert_raises(TypeError, nditer, np.float32(2), [],
+                [['readonly']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('i4')])
+
+def test_iter_object_arrays_basic():
+    # Check that object arrays work
+
+    obj = {'a':3,'b':'d'}
+    a = np.array([[1, 2, 3], None, obj, None], dtype='O')
+    rc = sys.getrefcount(obj)
+
+    # Need to allow references for object arrays
+    assert_raises(TypeError, nditer, a)
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a, ['refs_ok'], ['readonly'])
+    vals = [x_[()] for x_ in i]
+    assert_equal(np.array(vals, dtype='O'), a)
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
+                        ['readonly'], order='C')
+    assert_(i.iterationneedsapi)
+    vals = [x_[()] for x_ in i]
+    assert_equal(np.array(vals, dtype='O'), a.reshape(2, 2).ravel(order='F'))
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
+                        ['readwrite'], order='C')
+    for x in i:
+        x[...] = None
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc-1)
+    assert_equal(a, np.array([None]*4, dtype='O'))
+
+def test_iter_object_arrays_conversions():
+    # Conversions to/from objects
+    a = np.arange(6, dtype='O')
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='i4')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    a = np.arange(6, dtype='i4')
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='O')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    # Non-contiguous object array
+    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'O')])
+    a = a['a']
+    a[:] = np.arange(6)
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='i4')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    #Non-contiguous value array
+    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'i4')])
+    a = a['a']
+    a[:] = np.arange(6) + 98172488
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='O')
+    ob = i[0][()]
+    rc = sys.getrefcount(ob)
+    for x in i:
+        x[...] += 1
+    assert_equal(sys.getrefcount(ob), rc-1)
+    assert_equal(a, np.arange(6)+98172489)
+
+def test_iter_common_dtype():
+    # Check that the iterator finds a common data type correctly
+
+    i = nditer([array([3], dtype='f4'), array([0], dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.dtypes[1], np.dtype('f8'))
+    i = nditer([array([3], dtype='i4'), array([0], dtype='f4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.dtypes[1], np.dtype('f8'))
+    i = nditer([array([3], dtype='f4'), array(0, dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='same_kind')
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.dtypes[1], np.dtype('f4'))
+    i = nditer([array([3], dtype='u4'), array(0, dtype='i4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('u4'))
+    assert_equal(i.dtypes[1], np.dtype('u4'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('i8'))
+    assert_equal(i.dtypes[1], np.dtype('i8'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'),
+                 array([2j], dtype='c8'), array([9], dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*4,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('c16'))
+    assert_equal(i.dtypes[1], np.dtype('c16'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+    assert_equal(i.dtypes[3], np.dtype('c16'))
+    assert_equal(i.value, (3, -12, 2j, 9))
+
+    # When allocating outputs, other outputs aren't factored in
+    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')], [],
+                    [['readonly', 'copy'],
+                     ['writeonly', 'allocate'],
+                     ['writeonly']],
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('i4'))
+    assert_equal(i.dtypes[1], np.dtype('i4'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+    # But, if common data types are requested, they are
+    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')],
+                    ['common_dtype'],
+                    [['readonly', 'copy'],
+                     ['writeonly', 'allocate'],
+                     ['writeonly']],
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('c16'))
+    assert_equal(i.dtypes[1], np.dtype('c16'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+
+def test_iter_op_axes():
+    # Check that custom axes work
+
+    # Reverse the axes
+    a = arange(6).reshape(2, 3)
+    i = nditer([a, a.T], [], [['readonly']]*2, op_axes=[[0, 1], [1, 0]])
+    assert_(all([x == y for (x, y) in i]))
+    a = arange(24).reshape(2, 3, 4)
+    i = nditer([a.T, a], [], [['readonly']]*2, op_axes=[[2, 1, 0], None])
+    assert_(all([x == y for (x, y) in i]))
+
+    # Broadcast 1D to any dimension
+    a = arange(1, 31).reshape(2, 3, 5)
+    b = arange(1, 3)
+    i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [0, -1, -1]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(2, 1, 1)).ravel())
+    b = arange(1, 4)
+    i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [-1, 0, -1]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 3, 1)).ravel())
+    b = arange(1, 6)
+    i = nditer([a, b], [], [['readonly']]*2,
+                            op_axes=[None, [np.newaxis, np.newaxis, 0]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 1, 5)).ravel())
+
+    # Inner product-style broadcasting
+    a = arange(24).reshape(2, 3, 4)
+    b = arange(40).reshape(5, 2, 4)
+    i = nditer([a, b], ['multi_index'], [['readonly']]*2,
+                            op_axes=[[0, 1, -1, -1], [-1, -1, 0, 1]])
+    assert_equal(i.shape, (2, 3, 5, 2))
+
+    # Matrix product-style broadcasting
+    a = arange(12).reshape(3, 4)
+    b = arange(20).reshape(4, 5)
+    i = nditer([a, b], ['multi_index'], [['readonly']]*2,
+                            op_axes=[[0, -1], [-1, 1]])
+    assert_equal(i.shape, (3, 5))
+
+def test_iter_op_axes_errors():
+    # Check that custom axes throws errors for bad inputs
+
+    # Wrong number of items in op_axes
+    a = arange(6).reshape(2, 3)
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0], [1], [0]])
+    # Out of bounds items in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[2, 1], [0, 1]])
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [2, -1]])
+    # Duplicate items in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 0], [0, 1]])
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [1, 1]])
+
+    # Different sized arrays in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [0, 1, 0]])
+
+    # Non-broadcastable dimensions in the result
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [1, 0]])
+
+def test_iter_copy():
+    # Check that copying the iterator works correctly
+    a = arange(24).reshape(2, 3, 4)
+
+    # Simple iterator
+    i = nditer(a)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterindex = 3
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    # Buffered iterator
+    i = nditer(a, ['buffered', 'ranged'], order='F', buffersize=3)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterindex = 3
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterrange = (3, 9)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterrange = (2, 18)
+    next(i)
+    next(i)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    # Casting iterator
+    i = nditer(a, ['buffered'], order='F', casting='unsafe',
+                op_dtypes='f8', buffersize=5)
+    j = i.copy()
+    i = None
+    assert_equal([x[()] for x in j], a.ravel(order='F'))
+
+    a = arange(24, dtype='<i4').reshape(2, 3, 4)
+    i = nditer(a, ['buffered'], order='F', casting='unsafe',
+                op_dtypes='>f8', buffersize=5)
+    j = i.copy()
+    i = None
+    assert_equal([x[()] for x in j], a.ravel(order='F'))
+
+def test_iter_allocate_output_simple():
+    # Check that the iterator will properly allocate outputs
+
+    # Simple case
+    a = arange(6)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+
+def test_iter_allocate_output_buffered_readwrite():
+    # Allocated output with buffering + delay_bufalloc
+
+    a = arange(6)
+    i = nditer([a, None], ['buffered', 'delay_bufalloc'],
+                        [['readonly'], ['allocate', 'readwrite']])
+    i.operands[1][:] = 1
+    i.reset()
+    for x in i:
+        x[1][...] += x[0][...]
+    assert_equal(i.operands[1], a+1)
+
+def test_iter_allocate_output_itorder():
+    # The allocated output should match the iteration order
+
+    # C-order input, best iteration order
+    a = arange(6, dtype='i4').reshape(2, 3)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, a.strides)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+    # F-order input, best iteration order
+    a = arange(24, dtype='i4').reshape(2, 3, 4).T
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, a.strides)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+    # Non-contiguous input, C iteration order
+    a = arange(24, dtype='i4').reshape(2, 3, 4).swapaxes(0, 1)
+    i = nditer([a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        order='C',
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, (32, 16, 4))
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+
+def test_iter_allocate_output_opaxes():
+    # Specifing op_axes should work
+
+    a = arange(24, dtype='i4').reshape(2, 3, 4)
+    i = nditer([None, a], [], [['writeonly', 'allocate'], ['readonly']],
+                        op_dtypes=[np.dtype('u4'), None],
+                        op_axes=[[1, 2, 0], None])
+    assert_equal(i.operands[0].shape, (4, 2, 3))
+    assert_equal(i.operands[0].strides, (4, 48, 16))
+    assert_equal(i.operands[0].dtype, np.dtype('u4'))
+
+def test_iter_allocate_output_types_promotion():
+    # Check type promotion of automatic outputs
+
+    i = nditer([array([3], dtype='f4'), array([0], dtype='f8'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f8'))
+    i = nditer([array([3], dtype='i4'), array([0], dtype='f4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f8'))
+    i = nditer([array([3], dtype='f4'), array(0, dtype='f8'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f4'))
+    i = nditer([array([3], dtype='u4'), array(0, dtype='i4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('u4'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('i8'))
+
+def test_iter_allocate_output_types_byte_order():
+    # Verify the rules for byte order changes
+
+    # When there's just one input, the output type exactly matches
+    a = array([3], dtype='u4').newbyteorder()
+    i = nditer([a, None], [],
+                    [['readonly'], ['writeonly', 'allocate']])
+    assert_equal(i.dtypes[0], i.dtypes[1])
+    # With two or more inputs, the output type is in native byte order
+    i = nditer([a, a, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    assert_(i.dtypes[0] != i.dtypes[2])
+    assert_equal(i.dtypes[0].newbyteorder('='), i.dtypes[2])
+
+def test_iter_allocate_output_types_scalar():
+    # If the inputs are all scalars, the output should be a scalar
+
+    i = nditer([None, 1, 2.3, np.float32(12), np.complex128(3)], [],
+                [['writeonly', 'allocate']] + [['readonly']]*4)
+    assert_equal(i.operands[0].dtype, np.dtype('complex128'))
+    assert_equal(i.operands[0].ndim, 0)
+
+def test_iter_allocate_output_subtype():
+    # Make sure that the subtype with priority wins
+
+    # matrix vs ndarray
+    a = np.matrix([[1, 2], [3, 4]])
+    b = np.arange(4).reshape(2, 2).T
+    i = nditer([a, b, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    assert_equal(type(a), type(i.operands[2]))
+    assert_(type(b) != type(i.operands[2]))
+    assert_equal(i.operands[2].shape, (2, 2))
+
+    # matrix always wants things to be 2D
+    b = np.arange(4).reshape(1, 2, 2)
+    assert_raises(RuntimeError, nditer, [a, b, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    # but if subtypes are disabled, the result can still work
+    i = nditer([a, b, None], [],
+            [['readonly'], ['readonly'], ['writeonly', 'allocate', 'no_subtype']])
+    assert_equal(type(b), type(i.operands[2]))
+    assert_(type(a) != type(i.operands[2]))
+    assert_equal(i.operands[2].shape, (1, 2, 2))
+
+def test_iter_allocate_output_errors():
+    # Check that the iterator will throw errors for bad output allocations
+
+    # Need an input if no output data type is specified
+    a = arange(6)
+    assert_raises(TypeError, nditer, [a, None], [],
+                        [['writeonly'], ['writeonly', 'allocate']])
+    # Allocated output should be flagged for writing
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['allocate', 'readonly']])
+    # Allocated output can't have buffering without delayed bufalloc
+    assert_raises(ValueError, nditer, [a, None], ['buffered'],
+                                            ['allocate', 'readwrite'])
+    # Must specify at least one input
+    assert_raises(ValueError, nditer, [None, None], [],
+                        [['writeonly', 'allocate'],
+                         ['writeonly', 'allocate']],
+                        op_dtypes=[np.dtype('f4'), np.dtype('f4')])
+    # If using op_axes, must specify all the axes
+    a = arange(24, dtype='i4').reshape(2, 3, 4)
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, np.newaxis, 1]])
+    # If using op_axes, the axes must be within bounds
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, 3, 1]])
+    # If using op_axes, there can't be duplicates
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, 2, 1, 0]])
+
+def test_iter_remove_axis():
+    a = arange(24).reshape(2, 3, 4)
+
+    i = nditer(a, ['multi_index'])
+    i.remove_axis(1)
+    assert_equal([x for x in i], a[:, 0,:].ravel())
+
+    a = a[::-1,:,:]
+    i = nditer(a, ['multi_index'])
+    i.remove_axis(0)
+    assert_equal([x for x in i], a[0,:,:].ravel())
+
+def test_iter_remove_multi_index_inner_loop():
+    # Check that removing multi-index support works
+
+    a = arange(24).reshape(2, 3, 4)
+
+    i = nditer(a, ['multi_index'])
+    assert_equal(i.ndim, 3)
+    assert_equal(i.shape, (2, 3, 4))
+    assert_equal(i.itviews[0].shape, (2, 3, 4))
+
+    # Removing the multi-index tracking causes all dimensions to coalesce
+    before = [x for x in i]
+    i.remove_multi_index()
+    after = [x for x in i]
+
+    assert_equal(before, after)
+    assert_equal(i.ndim, 1)
+    assert_raises(ValueError, lambda i:i.shape, i)
+    assert_equal(i.itviews[0].shape, (24,))
+
+    # Removing the inner loop means there's just one iteration
+    i.reset()
+    assert_equal(i.itersize, 24)
+    assert_equal(i[0].shape, tuple())
+    i.enable_external_loop()
+    assert_equal(i.itersize, 24)
+    assert_equal(i[0].shape, (24,))
+    assert_equal(i.value, arange(24))
+
+def test_iter_iterindex():
+    # Make sure iterindex works
+
+    buffersize = 5
+    a = arange(24).reshape(4, 3, 2)
+    for flags in ([], ['buffered']):
+        i = nditer(a, flags, buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 2
+        assert_equal(iter_iterindices(i), list(range(2, 24)))
+
+        i = nditer(a, flags, order='F', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 5
+        assert_equal(iter_iterindices(i), list(range(5, 24)))
+
+        i = nditer(a[::-1], flags, order='F', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 9
+        assert_equal(iter_iterindices(i), list(range(9, 24)))
+
+        i = nditer(a[::-1, ::-1], flags, order='C', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 13
+        assert_equal(iter_iterindices(i), list(range(13, 24)))
+
+        i = nditer(a[::1, ::-1], flags, buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 23
+        assert_equal(iter_iterindices(i), list(range(23, 24)))
+        i.reset()
+        i.iterindex = 2
+        assert_equal(iter_iterindices(i), list(range(2, 24)))
+
+def test_iter_iterrange():
+    # Make sure getting and resetting the iterrange works
+
+    buffersize = 5
+    a = arange(24, dtype='i4').reshape(4, 3, 2)
+    a_fort = a.ravel(order='F')
+
+    i = nditer(a, ['ranged'], ['readonly'], order='F',
+                buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal([x[()] for x in i], a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal([x[()] for x in i], a_fort[r[0]:r[1]])
+
+    i = nditer(a, ['ranged', 'buffered'], ['readonly'], order='F',
+                op_dtypes='f8', buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal([x[()] for x in i], a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal([x[()] for x in i], a_fort[r[0]:r[1]])
+
+    def get_array(i):
+        val = np.array([], dtype='f8')
+        for x in i:
+            val = np.concatenate((val, x))
+        return val
+
+    i = nditer(a, ['ranged', 'buffered', 'external_loop'],
+                ['readonly'], order='F',
+                op_dtypes='f8', buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal(get_array(i), a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal(get_array(i), a_fort[r[0]:r[1]])
+
+def test_iter_buffering():
+    # Test buffering with several buffer sizes and types
+    arrays = []
+    # F-order swapped array
+    arrays.append(np.arange(24,
+                    dtype='c16').reshape(2, 3, 4).T.newbyteorder().byteswap())
+    # Contiguous 1-dimensional array
+    arrays.append(np.arange(10, dtype='f4'))
+    # Unaligned array
+    a = np.zeros((4*16+1,), dtype='i1')[1:]
+    a.dtype = 'i4'
+    a[:] = np.arange(16, dtype='i4')
+    arrays.append(a)
+    # 4-D F-order array
+    arrays.append(np.arange(120, dtype='i4').reshape(5, 3, 2, 4).T)
+    for a in arrays:
+        for buffersize in (1, 2, 3, 5, 8, 11, 16, 1024):
+            vals = []
+            i = nditer(a, ['buffered', 'external_loop'],
+                           [['readonly', 'nbo', 'aligned']],
+                           order='C',
+                           casting='equiv',
+                           buffersize=buffersize)
+            while not i.finished:
+                assert_(i[0].size <= buffersize)
+                vals.append(i[0].copy())
+                i.iternext()
+            assert_equal(np.concatenate(vals), a.ravel(order='C'))
+
+def test_iter_write_buffering():
+    # Test that buffering of writes is working
+
+    # F-order swapped array
+    a = np.arange(24).reshape(2, 3, 4).T.newbyteorder().byteswap()
+    i = nditer(a, ['buffered'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='equiv',
+                   order='C',
+                   buffersize=16)
+    x = 0
+    while not i.finished:
+        i[0] = x
+        x += 1
+        i.iternext()
+    assert_equal(a.ravel(order='C'), np.arange(24))
+
+def test_iter_buffering_delayed_alloc():
+    # Test that delaying buffer allocation works
+
+    a = np.arange(6)
+    b = np.arange(1, dtype='f4')
+    i = nditer([a, b], ['buffered', 'delay_bufalloc', 'multi_index', 'reduce_ok'],
+                    ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes='f4')
+    assert_(i.has_delayed_bufalloc)
+    assert_raises(ValueError, lambda i:i.multi_index, i)
+    assert_raises(ValueError, lambda i:i[0], i)
+    assert_raises(ValueError, lambda i:i[0:2], i)
+
+    def assign_iter(i):
+        i[0] = 0
+    assert_raises(ValueError, assign_iter, i)
+
+    i.reset()
+    assert_(not i.has_delayed_bufalloc)
+    assert_equal(i.multi_index, (0,))
+    assert_equal(i[0], 0)
+    i[1] = 1
+    assert_equal(i[0:2], [0, 1])
+    assert_equal([[x[0][()], x[1][()]] for x in i], list(zip(range(6), [1]*6)))
+
+def test_iter_buffered_cast_simple():
+    # Test that buffering can handle a simple cast
+
+    a = np.arange(10, dtype='f4')
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f8')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+
+    assert_equal(a, 2*np.arange(10, dtype='f4'))
+
+def test_iter_buffered_cast_byteswapped():
+    # Test that buffering can handle a cast which requires swap->cast->swap
+
+    a = np.arange(10, dtype='f4').newbyteorder().byteswap()
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f8').newbyteorder()],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+
+    assert_equal(a, 2*np.arange(10, dtype='f4'))
+
+    try:
+        warnings.simplefilter("ignore", np.ComplexWarning)
+
+        a = np.arange(10, dtype='f8').newbyteorder().byteswap()
+        i = nditer(a, ['buffered', 'external_loop'],
+                       [['readwrite', 'nbo', 'aligned']],
+                       casting='unsafe',
+                       op_dtypes=[np.dtype('c8').newbyteorder()],
+                       buffersize=3)
+        for v in i:
+            v[...] *= 2
+
+        assert_equal(a, 2*np.arange(10, dtype='f8'))
+    finally:
+        warnings.simplefilter("default", np.ComplexWarning)
+
+def test_iter_buffered_cast_byteswapped_complex():
+    # Test that buffering can handle a cast which requires swap->cast->copy
+
+    a = np.arange(10, dtype='c8').newbyteorder().byteswap()
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype='c8') + 4j)
+
+    a = np.arange(10, dtype='c8')
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16').newbyteorder()],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype='c8') + 4j)
+
+    a = np.arange(10, dtype=np.clongdouble).newbyteorder().byteswap()
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype=np.clongdouble) + 4j)
+
+    a = np.arange(10, dtype=np.longdouble).newbyteorder().byteswap()
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f4')],
+                   buffersize=7)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype=np.longdouble))
+
+def test_iter_buffered_cast_structured_type():
+    # Tests buffering of structured types
+
+    # simple -> struct type (duplicates the value)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.arange(3, dtype='f4') + 0.5
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt)
+    vals = [np.array(x) for x in i]
+    assert_equal(vals[0]['a'], 0.5)
+    assert_equal(vals[0]['b'], 0)
+    assert_equal(vals[0]['c'], [[(0.5)]*3]*2)
+    assert_equal(vals[0]['d'], 0.5)
+    assert_equal(vals[1]['a'], 1.5)
+    assert_equal(vals[1]['b'], 1)
+    assert_equal(vals[1]['c'], [[(1.5)]*3]*2)
+    assert_equal(vals[1]['d'], 1.5)
+    assert_equal(vals[0].dtype, np.dtype(sdt))
+
+    # object -> struct type
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.zeros((3,), dtype='O')
+    a[0] = (0.5, 0.5, [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5]], 0.5)
+    a[1] = (1.5, 1.5, [[1.5, 1.5, 1.5], [1.5, 1.5, 1.5]], 1.5)
+    a[2] = (2.5, 2.5, [[2.5, 2.5, 2.5], [2.5, 2.5, 2.5]], 2.5)
+    rc = sys.getrefcount(a[0])
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt)
+    vals = [x.copy() for x in i]
+    assert_equal(vals[0]['a'], 0.5)
+    assert_equal(vals[0]['b'], 0)
+    assert_equal(vals[0]['c'], [[(0.5)]*3]*2)
+    assert_equal(vals[0]['d'], 0.5)
+    assert_equal(vals[1]['a'], 1.5)
+    assert_equal(vals[1]['b'], 1)
+    assert_equal(vals[1]['c'], [[(1.5)]*3]*2)
+    assert_equal(vals[1]['d'], 1.5)
+    assert_equal(vals[0].dtype, np.dtype(sdt))
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(a[0]), rc)
+
+    # struct type -> simple (takes the first value)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    a = np.array([(5.5, 7, 'test'), (8, 10, 11)], dtype=sdt)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes='i4')
+    assert_equal([x_[()] for x_ in i], [5, 8])
+
+    # struct type -> struct type (field-wise copy)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    sdt2 = [('d', 'u2'), ('a', 'O'), ('b', 'f8')]
+    a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    assert_equal([np.array(x_) for x_ in i],
+                 [np.array((3, 1, 2), dtype=sdt2),
+                  np.array((6, 4, 5), dtype=sdt2)])
+
+    # struct type -> struct type (field gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, None), (8, 5, None)], dtype=sdt1))
+
+    # struct type -> struct type (structured field gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'i4')])]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, (0, 9)), (4, 5, (20, 21))], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, (0, 0)), (8, 5, (0, 0))], dtype=sdt1))
+
+    # struct type -> struct type (structured field w/ ref gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'O')])]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, (0, 9)), (4, 5, (20, 21))], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, (0, None)), (8, 5, (0, None))], dtype=sdt1))
+
+    # struct type -> struct type back (structured field w/ ref gets discarded)
+    sdt1 = [('b', 'O'), ('a', 'f8')]
+    sdt2 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'O')])]
+    a = np.array([(1, 2), (4, 5)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        assert_equal(x['d'], np.array((0, None), dtype=[('a', 'i2'), ('b', 'O')]))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1, (0, None)), dtype=sdt2),
+                     np.array((5, 4, (0, None)), dtype=sdt2)])
+    assert_equal(a, np.array([(1, 4), (4, 7)], dtype=sdt1))
+
+def test_iter_buffered_cast_subarray():
+    # Tests buffering of subarrays
+
+    # one element -> many (copies it to all)
+    sdt1 = [('a', 'f4')]
+    sdt2 = [('a', 'f8', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    for x, count in zip(i, list(range(6))):
+        assert_(np.all(x['a'] == count))
+
+    # one element -> many -> back (copies it to all)
+    sdt1 = [('a', 'O', (1, 1))]
+    sdt2 = [('a', 'O', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_(np.all(x['a'] == count))
+        x['a'][0] += 2
+        count += 1
+    assert_equal(a['a'], np.arange(6).reshape(6, 1, 1)+2)
+
+    # many -> one element -> back (copies just element 0)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'O', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        x['a'] += 2
+        count += 1
+    assert_equal(a['a'], np.arange(6).reshape(6, 1, 1, 1)*np.ones((1, 3, 2, 2))+2)
+
+    # many -> one element -> back (copies just element 0)
+    sdt1 = [('a', 'f8', (3, 2, 2))]
+    sdt2 = [('a', 'O', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        count += 1
+
+    # many -> one element (copies just element 0)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'f4', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        count += 1
+
+    # many -> matching shape (straightforward copy)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'f4', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*3*2*2).reshape(6, 3, 2, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], a[count]['a'])
+        count += 1
+
+    # vector -> smaller vector (truncates)
+    sdt1 = [('a', 'f8', (6,))]
+    sdt2 = [('a', 'f4', (2,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*6).reshape(6, 6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], a[count]['a'][:2])
+        count += 1
+
+    # vector -> bigger vector (pads with zeros)
+    sdt1 = [('a', 'f8', (2,))]
+    sdt2 = [('a', 'f4', (6,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2], a[count]['a'])
+        assert_equal(x['a'][2:], [0, 0, 0, 0])
+        count += 1
+
+    # vector -> matrix (broadcasts)
+    sdt1 = [('a', 'f8', (2,))]
+    sdt2 = [('a', 'f4', (2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][0], a[count]['a'])
+        assert_equal(x['a'][1], a[count]['a'])
+        count += 1
+
+    # vector -> matrix (broadcasts and zero-pads)
+    sdt1 = [('a', 'f8', (2, 1))]
+    sdt2 = [('a', 'f4', (3, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2, 1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2, 0], a[count]['a'][:, 0])
+        assert_equal(x['a'][:2, 1], a[count]['a'][:, 0])
+        assert_equal(x['a'][2,:], [0, 0])
+        count += 1
+
+    # matrix -> matrix (truncates and zero-pads)
+    sdt1 = [('a', 'f8', (2, 3))]
+    sdt2 = [('a', 'f4', (3, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2*3).reshape(6, 2, 3)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2, 0], a[count]['a'][:, 0])
+        assert_equal(x['a'][:2, 1], a[count]['a'][:, 1])
+        assert_equal(x['a'][2,:], [0, 0])
+        count += 1
+
+def test_iter_buffering_badwriteback():
+    # Writing back from a buffer cannot combine elements
+
+    # a needs write buffering, but had a broadcast dimension
+    a = np.arange(6).reshape(2, 3, 1)
+    b = np.arange(12).reshape(2, 3, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+
+    # But if a is readonly, it's fine
+    nditer([a, b], ['buffered', 'external_loop'],
+           [['readonly'], ['writeonly']],
+           order='C')
+
+    # If a has just one element, it's fine too (constant 0 stride, a reduction)
+    a = np.arange(1).reshape(1, 1, 1)
+    nditer([a, b], ['buffered', 'external_loop', 'reduce_ok'],
+           [['readwrite'], ['writeonly']],
+           order='C')
+
+    # check that it fails on other dimensions too
+    a = np.arange(6).reshape(1, 3, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+    a = np.arange(4).reshape(2, 1, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+
+def test_iter_buffering_string():
+    # Safe casting disallows shrinking strings
+    a = np.array(['abc', 'a', 'abcd'], dtype=np.bytes_)
+    assert_equal(a.dtype, np.dtype('S4'))
+    assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'],
+                  op_dtypes='S2')
+    i = nditer(a, ['buffered'], ['readonly'], op_dtypes='S6')
+    assert_equal(i[0], asbytes('abc'))
+    assert_equal(i[0].dtype, np.dtype('S6'))
+
+    a = np.array(['abc', 'a', 'abcd'], dtype=np.unicode)
+    assert_equal(a.dtype, np.dtype('U4'))
+    assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'],
+                    op_dtypes='U2')
+    i = nditer(a, ['buffered'], ['readonly'], op_dtypes='U6')
+    assert_equal(i[0], sixu('abc'))
+    assert_equal(i[0].dtype, np.dtype('U6'))
+
+def test_iter_buffering_growinner():
+    # Test that the inner loop grows when no buffering is needed
+    a = np.arange(30)
+    i = nditer(a, ['buffered', 'growinner', 'external_loop'],
+                           buffersize=5)
+    # Should end up with just one inner loop here
+    assert_equal(i[0].size, a.size)
+
+
+@dec.slow
+def test_iter_buffered_reduce_reuse():
+    # large enough array for all views, including negative strides.
+    a = np.arange(2*3**5)[3**5:3**5+1]
+    flags = ['buffered', 'delay_bufalloc', 'multi_index', 'reduce_ok', 'refs_ok']
+    op_flags = [('readonly',), ('readwrite', 'allocate')]
+    op_axes_list = [[(0, 1, 2), (0, 1, -1)], [(0, 1, 2), (0, -1, -1)]]
+    # wrong dtype to force buffering
+    op_dtypes = [np.float, a.dtype]
+
+    def get_params():
+        for xs in range(-3**2, 3**2 + 1):
+            for ys in range(xs, 3**2 + 1):
+                for op_axes in op_axes_list:
+                    # last stride is reduced and because of that not
+                    # important for this test, as it is the inner stride.
+                    strides = (xs * a.itemsize, ys * a.itemsize, a.itemsize)
+                    arr = np.lib.stride_tricks.as_strided(a, (3, 3, 3), strides)
+
+                    for skip in [0, 1]:
+                        yield arr, op_axes, skip
+
+    for arr, op_axes, skip in get_params():
+        nditer2 = np.nditer([arr.copy(), None],
+                            op_axes=op_axes, flags=flags, op_flags=op_flags,
+                            op_dtypes=op_dtypes)
+        nditer2.operands[-1][...] = 0
+        nditer2.reset()
+        nditer2.iterindex = skip
+
+        for (a2_in, b2_in) in nditer2:
+            b2_in += a2_in.astype(np.int_)
+
+        comp_res = nditer2.operands[-1]
+
+        for bufsize in range(0, 3**3):
+            nditer1 = np.nditer([arr, None],
+                                op_axes=op_axes, flags=flags, op_flags=op_flags,
+                                buffersize=bufsize, op_dtypes=op_dtypes)
+            nditer1.operands[-1][...] = 0
+            nditer1.reset()
+            nditer1.iterindex = skip
+
+            for (a1_in, b1_in) in nditer1:
+                b1_in += a1_in.astype(np.int_)
+
+            res = nditer1.operands[-1]
+            assert_array_equal(res, comp_res)
+
+
+def test_iter_no_broadcast():
+    # Test that the no_broadcast flag works
+    a = np.arange(24).reshape(2, 3, 4)
+    b = np.arange(6).reshape(2, 3, 1)
+    c = np.arange(12).reshape(3, 4)
+
+    nditer([a, b, c], [],
+           [['readonly', 'no_broadcast'],
+            ['readonly'], ['readonly']])
+    assert_raises(ValueError, nditer, [a, b, c], [],
+                  [['readonly'], ['readonly', 'no_broadcast'], ['readonly']])
+    assert_raises(ValueError, nditer, [a, b, c], [],
+                  [['readonly'], ['readonly'], ['readonly', 'no_broadcast']])
+
+def test_iter_nested_iters_basic():
+    # Test nested iteration basic usage
+    a = arange(12).reshape(2, 3, 2)
+
+    i, j = np.nested_iters(a, [[0], [1, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+def test_iter_nested_iters_reorder():
+    # Test nested iteration basic usage
+    a = arange(12).reshape(2, 3, 2)
+
+    # In 'K' order (default), it gets reordered
+    i, j = np.nested_iters(a, [[0], [2, 1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[2, 0], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+    # In 'C' order, it doesn't
+    i, j = np.nested_iters(a, [[0], [2, 1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4, 1, 3, 5], [6, 8, 10, 7, 9, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0], [2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [6, 7], [2, 3], [8, 9], [4, 5], [10, 11]])
+
+    i, j = np.nested_iters(a, [[2, 0], [1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [6, 8, 10], [1, 3, 5], [7, 9, 11]])
+
+def test_iter_nested_iters_flip_axes():
+    # Test nested iteration with negative axes
+    a = arange(12).reshape(2, 3, 2)[::-1, ::-1, ::-1]
+
+    # In 'K' order (default), the axes all get flipped
+    i, j = np.nested_iters(a, [[0], [1, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+    # In 'C' order, flipping axes is disabled
+    i, j = np.nested_iters(a, [[0], [1, 2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 10, 9, 8, 7, 6], [5, 4, 3, 2, 1, 0]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 10], [9, 8], [7, 6], [5, 4], [3, 2], [1, 0]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 9, 7], [10, 8, 6], [5, 3, 1], [4, 2, 0]])
+
+def test_iter_nested_iters_broadcast():
+    # Test nested iteration with broadcasting
+    a = arange(2).reshape(2, 1)
+    b = arange(3).reshape(1, 3)
+
+    i, j = np.nested_iters([a, b], [[0], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]])
+
+    i, j = np.nested_iters([a, b], [[1], [0]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[[0, 0], [1, 0]], [[0, 1], [1, 1]], [[0, 2], [1, 2]]])
+
+def test_iter_nested_iters_dtype_copy():
+    # Test nested iteration with a copy to change dtype
+
+    # copy
+    a = arange(6, dtype='i4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        op_flags=['readonly', 'copy'],
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2], [3, 4, 5]])
+    vals = None
+
+    # updateifcopy
+    a = arange(6, dtype='f4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        op_flags=['readwrite', 'updateifcopy'],
+                        casting='same_kind',
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    for x in i:
+        for y in j:
+            y[...] += 1
+    assert_equal(a, [[0, 1, 2], [3, 4, 5]])
+    i, j, x, y = (None,)*4  # force the updateifcopy
+    assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+def test_iter_nested_iters_dtype_buffered():
+    # Test nested iteration with buffering to change dtype
+
+    a = arange(6, dtype='f4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        flags=['buffered'],
+                        op_flags=['readwrite'],
+                        casting='same_kind',
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    for x in i:
+        for y in j:
+            y[...] += 1
+    assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+def test_iter_reduction_error():
+
+    a = np.arange(6)
+    assert_raises(ValueError, nditer, [a, None], [],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0], [-1]])
+
+    a = np.arange(6).reshape(2, 3)
+    assert_raises(ValueError, nditer, [a, None], ['external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0, 1], [-1, -1]])
+
+def test_iter_reduction():
+    # Test doing reductions with the iterator
+
+    a = np.arange(6)
+    i = nditer([a, None], ['reduce_ok'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0], [-1]])
+    # Need to initialize the output operand to the addition unit
+    i.operands[1][...] = 0
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(i.operands[1].ndim, 0)
+    assert_equal(i.operands[1], np.sum(a))
+
+    a = np.arange(6).reshape(2, 3)
+    i = nditer([a, None], ['reduce_ok', 'external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0, 1], [-1, -1]])
+    # Need to initialize the output operand to the addition unit
+    i.operands[1][...] = 0
+    # Reduction shape/strides for the output
+    assert_equal(i[1].shape, (6,))
+    assert_equal(i[1].strides, (0,))
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(i.operands[1].ndim, 0)
+    assert_equal(i.operands[1], np.sum(a))
+
+    # This is a tricky reduction case for the buffering double loop
+    # to handle
+    a = np.ones((2, 3, 5))
+    it1 = nditer([a, None], ['reduce_ok', 'external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[None, [0, -1, 1]])
+    it2 = nditer([a, None], ['reduce_ok', 'external_loop',
+                            'buffered', 'delay_bufalloc'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[None, [0, -1, 1]], buffersize=10)
+    it1.operands[1].fill(0)
+    it2.operands[1].fill(0)
+    it2.reset()
+    for x in it1:
+        x[1][...] += x[0]
+    for x in it2:
+        x[1][...] += x[0]
+    assert_equal(it1.operands[1], it2.operands[1])
+    assert_equal(it2.operands[1].sum(), a.size)
+
+def test_iter_buffering_reduction():
+    # Test doing buffered reductions with the iterator
+
+    a = np.arange(6)
+    b = np.array(0., dtype='f8').byteswap().newbyteorder()
+    i = nditer([a, b], ['reduce_ok', 'buffered'],
+                    [['readonly'], ['readwrite', 'nbo']],
+                    op_axes=[[0], [-1]])
+    assert_equal(i[1].dtype, np.dtype('f8'))
+    assert_(i[1].dtype != b.dtype)
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(b, np.sum(a))
+
+    a = np.arange(6).reshape(2, 3)
+    b = np.array([0, 0], dtype='f8').byteswap().newbyteorder()
+    i = nditer([a, b], ['reduce_ok', 'external_loop', 'buffered'],
+                    [['readonly'], ['readwrite', 'nbo']],
+                    op_axes=[[0, 1], [0, -1]])
+    # Reduction shape/strides for the output
+    assert_equal(i[1].shape, (3,))
+    assert_equal(i[1].strides, (0,))
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    assert_equal(b, np.sum(a, axis=1))
+
+    # Iterator inner double loop was wrong on this one
+    p = np.arange(2) + 1
+    it = np.nditer([p, None],
+            ['delay_bufalloc', 'reduce_ok', 'buffered', 'external_loop'],
+            [['readonly'], ['readwrite', 'allocate']],
+            op_axes=[[-1, 0], [-1, -1]],
+            itershape=(2, 2))
+    it.operands[1].fill(0)
+    it.reset()
+    assert_equal(it[0], [1, 2, 1, 2])
+
+def test_iter_buffering_reduction_reuse_reduce_loops():
+    # There was a bug triggering reuse of the reduce loop inappropriately,
+    # which caused processing to happen in unnecessarily small chunks
+    # and overran the buffer.
+
+    a = np.zeros((2, 7))
+    b = np.zeros((1, 7))
+    it = np.nditer([a, b], flags=['reduce_ok', 'external_loop', 'buffered'],
+                    op_flags=[['readonly'], ['readwrite']],
+                    buffersize=5)
+
+    bufsizes = []
+    for x, y in it:
+        bufsizes.append(x.shape[0])
+    assert_equal(bufsizes, [5, 2, 5, 2])
+    assert_equal(sum(bufsizes), a.size)
+
+def test_iter_writemasked_badinput():
+    a = np.zeros((2, 3))
+    b = np.zeros((3,))
+    m = np.array([[True, True, False], [False, True, False]])
+    m2 = np.array([True, True, False])
+    m3 = np.array([0, 1, 1], dtype='u1')
+    mbad1 = np.array([0, 1, 1], dtype='i1')
+    mbad2 = np.array([0, 1, 1], dtype='f4')
+
+    # Need an 'arraymask' if any operand is 'writemasked'
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readwrite', 'writemasked'], ['readonly']])
+
+    # A 'writemasked' operand must not be readonly
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readonly', 'writemasked'], ['readonly', 'arraymask']])
+
+    # 'writemasked' and 'arraymask' may not be used together
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readonly'], ['readwrite', 'arraymask', 'writemasked']])
+
+    # 'arraymask' may only be specified once
+    assert_raises(ValueError, nditer, [a, m, m2], [],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask'],
+                     ['readonly', 'arraymask']])
+
+    # An 'arraymask' with nothing 'writemasked' also doesn't make sense
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readwrite'], ['readonly', 'arraymask']])
+
+    # A writemasked reduction requires a similarly smaller mask
+    assert_raises(ValueError, nditer, [a, b, m], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']])
+    # But this should work with a smaller/equal mask to the reduction operand
+    np.nditer([a, b, m2], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']])
+    # The arraymask itself cannot be a reduction
+    assert_raises(ValueError, nditer, [a, b, m2], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readwrite', 'arraymask']])
+
+    # A uint8 mask is ok too
+    np.nditer([a, m3], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+    # An int8 mask isn't ok
+    assert_raises(TypeError, np.nditer, [a, mbad1], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+    # A float32 mask isn't ok
+    assert_raises(TypeError, np.nditer, [a, mbad2], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+
+def test_iter_writemasked():
+    a = np.zeros((3,), dtype='f8')
+    msk = np.array([True, True, False])
+
+    # When buffering is unused, 'writemasked' effectively does nothing.
+    # It's up to the user of the iterator to obey the requested semantics.
+    it = np.nditer([a, msk], [],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']])
+    for x, m in it:
+        x[...] = 1
+    # Because we violated the semantics, all the values became 1
+    assert_equal(a, [1, 1, 1])
+
+    # Even if buffering is enabled, we still may be accessing the array
+    # directly.
+    it = np.nditer([a, msk], ['buffered'],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']])
+    for x, m in it:
+        x[...] = 2.5
+    # Because we violated the semantics, all the values became 2.5
+    assert_equal(a, [2.5, 2.5, 2.5])
+
+    # If buffering will definitely happening, for instance because of
+    # a cast, only the items selected by the mask will be copied back from
+    # the buffer.
+    it = np.nditer([a, msk], ['buffered'],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']],
+                op_dtypes=['i8', None],
+                casting='unsafe')
+    for x, m in it:
+        x[...] = 3
+    # Even though we violated the semantics, only the selected values
+    # were copied back
+    assert_equal(a, [3, 3, 2.5])
+
+def test_iter_non_writable_attribute_deletion():
+    it = np.nditer(np.ones(2))
+    attr = ["value", "shape", "operands", "itviews", "has_delayed_bufalloc",
+            "iterationneedsapi", "has_multi_index", "has_index", "dtypes",
+            "ndim", "nop", "itersize", "finished"]
+
+    for s in attr:
+        assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_writable_attribute_deletion():
+    it = np.nditer(np.ones(2))
+    attr = [ "multi_index", "index", "iterrange", "iterindex"]
+    for s in attr:
+        assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_element_deletion():
+    it = np.nditer(np.ones(3))
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+def test_iter_allocated_array_dtypes():
+    # If the dtype of an allocated output has a shape, the shape gets
+    # tacked onto the end of the result.
+    it = np.nditer(([1, 3, 20], None), op_dtypes=[None, ('i4', (2,))])
+    for a, b in it:
+        b[0] = a - 1
+        b[1] = a + 1
+    assert_equal(it.operands[1], [[0, 2], [2, 4], [19, 21]])
+
+    # Make sure this works for scalars too
+    it = np.nditer((10, 2, None), op_dtypes=[None, None, ('i4', (2, 2))])
+    for a, b, c in it:
+        c[0, 0] = a - b
+        c[0, 1] = a + b
+        c[1, 0] = a * b
+        c[1, 1] = a / b
+    assert_equal(it.operands[2], [[8, 12], [20, 5]])
+
+
+def test_0d_iter():
+    # Basic test for iteration of 0-d arrays:
+    i = nditer([2, 3], ['multi_index'], [['readonly']]*2)
+    assert_equal(i.ndim, 0)
+    assert_equal(next(i), (2, 3))
+    assert_equal(i.multi_index, ())
+    assert_equal(i.iterindex, 0)
+    assert_raises(StopIteration, next, i)
+    # test reset:
+    i.reset()
+    assert_equal(next(i), (2, 3))
+    assert_raises(StopIteration, next, i)
+
+    # test forcing to 0-d
+    i = nditer(np.arange(5), ['multi_index'], [['readonly']], op_axes=[()])
+    assert_equal(i.ndim, 0)
+    assert_equal(len(i), 1)
+    # note that itershape=(), still behaves like None due to the conversions
+
+    # Test a more complex buffered casting case (same as another test above)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.array(0.5, dtype='f4')
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe', op_dtypes=sdt)
+    vals = next(i)
+    assert_equal(vals['a'], 0.5)
+    assert_equal(vals['b'], 0)
+    assert_equal(vals['c'], [[(0.5)]*3]*2)
+    assert_equal(vals['d'], 0.5)
+
+
+def test_0d_nested_iter():
+    a = np.arange(12).reshape(2, 3, 2)
+    i, j = np.nested_iters(a, [[], [1, 0, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0, 2], []])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]])
+
+    i, j, k = np.nested_iters(a, [[2, 0], [], [1]])
+    vals = []
+    for x in i:
+        for y in j:
+            vals.append([z for z in k])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+
+def test_iter_too_large():
+    # The total size of the iterator must not exceed the maximum intp due
+    # to broadcasting. Dividing by 1024 will keep it small enough to
+    # give a legal array.
+    size = np.iinfo(np.intp).max // 1024
+    arr = np.lib.stride_tricks.as_strided(np.zeros(1), (size,), (0,))
+    assert_raises(ValueError, nditer, (arr, arr[:, None]))
+    # test the same for multiindex. That may get more interesting when
+    # removing 0 dimensional axis is allowed (since an iterator can grow then)
+    assert_raises(ValueError, nditer,
+                  (arr, arr[:, None]), flags=['multi_index'])
+
+
+def test_iter_too_large_with_multiindex():
+    # When a multi index is being tracked, the error is delayed this
+    # checks the delayed error messages and getting below that by
+    # removing an axis.
+    base_size = 2**10
+    num = 1
+    while base_size**num < np.iinfo(np.intp).max:
+        num += 1
+
+    shape_template = [1, 1] * num
+    arrays = []
+    for i in range(num):
+        shape = shape_template[:]
+        shape[i * 2] = 2**10
+        arrays.append(np.empty(shape))
+    arrays = tuple(arrays)
+
+    # arrays are now too large to be broadcast. The different modes test
+    # different nditer functionality with or without GIL.
+    for mode in range(6):
+        assert_raises(ValueError, test_nditer_too_large, arrays, -1, mode)
+    # but if we do nothing with the nditer, it can be constructed:
+    test_nditer_too_large(arrays, -1, 7)
+
+    # When an axis is removed, things should work again (half the time):
+    for i in range(num):
+        for mode in range(6):
+            # an axis with size 1024 is removed:
+            test_nditer_too_large(arrays, i*2, mode)
+            # an axis with size 1 is removed:
+            assert_raises(ValueError, test_nditer_too_large,
+                          arrays, i*2 + 1, mode)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
new file mode 100644
index 0000000000..5dbeec3b4e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
@@ -0,0 +1,2438 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+import itertools
+import platform
+from decimal import Decimal
+
+import numpy as np
+from numpy.core import umath
+from numpy.random import rand, randint, randn
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_raises_regex, assert_array_equal, assert_almost_equal,
+    assert_array_almost_equal, dec
+)
+
+
+class TestResize(TestCase):
+    def test_copies(self):
+        A = np.array([[1, 2], [3, 4]])
+        Ar1 = np.array([[1, 2, 3, 4], [1, 2, 3, 4]])
+        assert_equal(np.resize(A, (2, 4)), Ar1)
+
+        Ar2 = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
+        assert_equal(np.resize(A, (4, 2)), Ar2)
+
+        Ar3 = np.array([[1, 2, 3], [4, 1, 2], [3, 4, 1], [2, 3, 4]])
+        assert_equal(np.resize(A, (4, 3)), Ar3)
+
+    def test_zeroresize(self):
+        A = np.array([[1, 2], [3, 4]])
+        Ar = np.resize(A, (0,))
+        assert_array_equal(Ar, np.array([]))
+        assert_equal(A.dtype, Ar.dtype)
+
+    def test_reshape_from_zero(self):
+        # See also gh-6740
+        A = np.zeros(0, dtype=[('a', np.float32, 1)])
+        Ar = np.resize(A, (2, 1))
+        assert_array_equal(Ar, np.zeros((2, 1), Ar.dtype))
+        assert_equal(A.dtype, Ar.dtype)
+
+
+class TestNonarrayArgs(TestCase):
+    # check that non-array arguments to functions wrap them in arrays
+    def test_choose(self):
+        choices = [[0, 1, 2],
+                   [3, 4, 5],
+                   [5, 6, 7]]
+        tgt = [5, 1, 5]
+        a = [2, 0, 1]
+
+        out = np.choose(a, choices)
+        assert_equal(out, tgt)
+
+    def test_clip(self):
+        arr = [-1, 5, 2, 3, 10, -4, -9]
+        out = np.clip(arr, 2, 7)
+        tgt = [2, 5, 2, 3, 7, 2, 2]
+        assert_equal(out, tgt)
+
+    def test_compress(self):
+        arr = [[0, 1, 2, 3, 4],
+               [5, 6, 7, 8, 9]]
+        tgt = [[5, 6, 7, 8, 9]]
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+    def test_cumproduct(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.all(np.cumproduct(A) == np.array([1, 2, 6, 24, 120, 720])))
+
+    def test_diagonal(self):
+        a = [[0, 1, 2, 3],
+             [4, 5, 6, 7],
+             [8, 9, 10, 11]]
+        out = np.diagonal(a)
+        tgt = [0, 5, 10]
+
+        assert_equal(out, tgt)
+
+    def test_mean(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.mean(A) == 3.5)
+        assert_(np.all(np.mean(A, 0) == np.array([2.5, 3.5, 4.5])))
+        assert_(np.all(np.mean(A, 1) == np.array([2., 5.])))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.mean([])))
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_ptp(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.ptp(a, axis=0), 15.0)
+
+    def test_prod(self):
+        arr = [[1, 2, 3, 4],
+               [5, 6, 7, 9],
+               [10, 3, 4, 5]]
+        tgt = [24, 1890, 600]
+
+        assert_equal(np.prod(arr, axis=-1), tgt)
+
+    def test_ravel(self):
+        a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
+        tgt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+        assert_equal(np.ravel(a), tgt)
+
+    def test_repeat(self):
+        a = [1, 2, 3]
+        tgt = [1, 1, 2, 2, 3, 3]
+
+        out = np.repeat(a, 2)
+        assert_equal(out, tgt)
+
+    def test_reshape(self):
+        arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(np.reshape(arr, (2, 6)), tgt)
+
+    def test_round(self):
+        arr = [1.56, 72.54, 6.35, 3.25]
+        tgt = [1.6, 72.5, 6.4, 3.2]
+        assert_equal(np.around(arr, decimals=1), tgt)
+
+    def test_searchsorted(self):
+        arr = [-8, -5, -1, 3, 6, 10]
+        out = np.searchsorted(arr, 0)
+        assert_equal(out, 3)
+
+    def test_size(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.size(A) == 6)
+        assert_(np.size(A, 0) == 2)
+        assert_(np.size(A, 1) == 3)
+
+    def test_squeeze(self):
+        A = [[[1, 1, 1], [2, 2, 2], [3, 3, 3]]]
+        assert_(np.squeeze(A).shape == (3, 3))
+
+    def test_std(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_almost_equal(np.std(A), 1.707825127659933)
+        assert_almost_equal(np.std(A, 0), np.array([1.5, 1.5, 1.5]))
+        assert_almost_equal(np.std(A, 1), np.array([0.81649658, 0.81649658]))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.std([])))
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_swapaxes(self):
+        tgt = [[[0, 4], [2, 6]], [[1, 5], [3, 7]]]
+        a = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
+        out = np.swapaxes(a, 0, 2)
+        assert_equal(out, tgt)
+
+    def test_sum(self):
+        m = [[1, 2, 3],
+             [4, 5, 6],
+             [7, 8, 9]]
+        tgt = [[6], [15], [24]]
+        out = np.sum(m, axis=1, keepdims=True)
+
+        assert_equal(tgt, out)
+
+    def test_take(self):
+        tgt = [2, 3, 5]
+        indices = [1, 2, 4]
+        a = [1, 2, 3, 4, 5]
+
+        out = np.take(a, indices)
+        assert_equal(out, tgt)
+
+    def test_trace(self):
+        c = [[1, 2], [3, 4], [5, 6]]
+        assert_equal(np.trace(c), 5)
+
+    def test_transpose(self):
+        arr = [[1, 2], [3, 4], [5, 6]]
+        tgt = [[1, 3, 5], [2, 4, 6]]
+        assert_equal(np.transpose(arr, (1, 0)), tgt)
+
+    def test_var(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_almost_equal(np.var(A), 2.9166666666666665)
+        assert_almost_equal(np.var(A, 0), np.array([2.25, 2.25, 2.25]))
+        assert_almost_equal(np.var(A, 1), np.array([0.66666667, 0.66666667]))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.var([])))
+            assert_(w[0].category is RuntimeWarning)
+
+
+class TestBoolScalar(TestCase):
+    def test_logical(self):
+        f = np.False_
+        t = np.True_
+        s = "xyz"
+        self.assertTrue((t and s) is s)
+        self.assertTrue((f and s) is f)
+
+    def test_bitwise_or(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t | t) is t)
+        self.assertTrue((f | t) is t)
+        self.assertTrue((t | f) is t)
+        self.assertTrue((f | f) is f)
+
+    def test_bitwise_and(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t & t) is t)
+        self.assertTrue((f & t) is f)
+        self.assertTrue((t & f) is f)
+        self.assertTrue((f & f) is f)
+
+    def test_bitwise_xor(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t ^ t) is f)
+        self.assertTrue((f ^ t) is t)
+        self.assertTrue((t ^ f) is t)
+        self.assertTrue((f ^ f) is f)
+
+
+class TestBoolArray(TestCase):
+    def setUp(self):
+        # offset for simd tests
+        self.t = np.array([True] * 41, dtype=np.bool)[1::]
+        self.f = np.array([False] * 41, dtype=np.bool)[1::]
+        self.o = np.array([False] * 42, dtype=np.bool)[2::]
+        self.nm = self.f.copy()
+        self.im = self.t.copy()
+        self.nm[3] = True
+        self.nm[-2] = True
+        self.im[3] = False
+        self.im[-2] = False
+
+    def test_all_any(self):
+        self.assertTrue(self.t.all())
+        self.assertTrue(self.t.any())
+        self.assertFalse(self.f.all())
+        self.assertFalse(self.f.any())
+        self.assertTrue(self.nm.any())
+        self.assertTrue(self.im.any())
+        self.assertFalse(self.nm.all())
+        self.assertFalse(self.im.all())
+        # check bad element in all positions
+        for i in range(256 - 7):
+            d = np.array([False] * 256, dtype=np.bool)[7::]
+            d[i] = True
+            self.assertTrue(np.any(d))
+            e = np.array([True] * 256, dtype=np.bool)[7::]
+            e[i] = False
+            self.assertFalse(np.all(e))
+            assert_array_equal(e, ~d)
+        # big array test for blocked libc loops
+        for i in list(range(9, 6000, 507)) + [7764, 90021, -10]:
+            d = np.array([False] * 100043, dtype=np.bool)
+            d[i] = True
+            self.assertTrue(np.any(d), msg="%r" % i)
+            e = np.array([True] * 100043, dtype=np.bool)
+            e[i] = False
+            self.assertFalse(np.all(e), msg="%r" % i)
+
+    def test_logical_not_abs(self):
+        assert_array_equal(~self.t, self.f)
+        assert_array_equal(np.abs(~self.t), self.f)
+        assert_array_equal(np.abs(~self.f), self.t)
+        assert_array_equal(np.abs(self.f), self.f)
+        assert_array_equal(~np.abs(self.f), self.t)
+        assert_array_equal(~np.abs(self.t), self.f)
+        assert_array_equal(np.abs(~self.nm), self.im)
+        np.logical_not(self.t, out=self.o)
+        assert_array_equal(self.o, self.f)
+        np.abs(self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+
+    def test_logical_and_or_xor(self):
+        assert_array_equal(self.t | self.t, self.t)
+        assert_array_equal(self.f | self.f, self.f)
+        assert_array_equal(self.t | self.f, self.t)
+        assert_array_equal(self.f | self.t, self.t)
+        np.logical_or(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+        assert_array_equal(self.t & self.t, self.t)
+        assert_array_equal(self.f & self.f, self.f)
+        assert_array_equal(self.t & self.f, self.f)
+        assert_array_equal(self.f & self.t, self.f)
+        np.logical_and(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+        assert_array_equal(self.t ^ self.t, self.f)
+        assert_array_equal(self.f ^ self.f, self.f)
+        assert_array_equal(self.t ^ self.f, self.t)
+        assert_array_equal(self.f ^ self.t, self.t)
+        np.logical_xor(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.f)
+
+        assert_array_equal(self.nm & self.t, self.nm)
+        assert_array_equal(self.im & self.f, False)
+        assert_array_equal(self.nm & True, self.nm)
+        assert_array_equal(self.im & False, self.f)
+        assert_array_equal(self.nm | self.t, self.t)
+        assert_array_equal(self.im | self.f, self.im)
+        assert_array_equal(self.nm | True, self.t)
+        assert_array_equal(self.im | False, self.im)
+        assert_array_equal(self.nm ^ self.t, self.im)
+        assert_array_equal(self.im ^ self.f, self.im)
+        assert_array_equal(self.nm ^ True, self.im)
+        assert_array_equal(self.im ^ False, self.im)
+
+
+class TestBoolCmp(TestCase):
+    def setUp(self):
+        self.f = np.ones(256, dtype=np.float32)
+        self.ef = np.ones(self.f.size, dtype=np.bool)
+        self.d = np.ones(128, dtype=np.float64)
+        self.ed = np.ones(self.d.size, dtype=np.bool)
+        # generate values for all permutation of 256bit simd vectors
+        s = 0
+        for i in range(32):
+            self.f[s:s+8] = [i & 2**x for x in range(8)]
+            self.ef[s:s+8] = [(i & 2**x) != 0 for x in range(8)]
+            s += 8
+        s = 0
+        for i in range(16):
+            self.d[s:s+4] = [i & 2**x for x in range(4)]
+            self.ed[s:s+4] = [(i & 2**x) != 0 for x in range(4)]
+            s += 4
+
+        self.nf = self.f.copy()
+        self.nd = self.d.copy()
+        self.nf[self.ef] = np.nan
+        self.nd[self.ed] = np.nan
+
+    def test_float(self):
+        # offset for alignment test
+        for i in range(4):
+            assert_array_equal(self.f[i:] > 0, self.ef[i:])
+            assert_array_equal(self.f[i:] - 1 >= 0, self.ef[i:])
+            assert_array_equal(self.f[i:] == 0, ~self.ef[i:])
+            assert_array_equal(-self.f[i:] < 0, self.ef[i:])
+            assert_array_equal(-self.f[i:] + 1 <= 0, self.ef[i:])
+            r = self.f[i:] != 0
+            assert_array_equal(r, self.ef[i:])
+            r2 = self.f[i:] != np.zeros_like(self.f[i:])
+            r3 = 0 != self.f[i:]
+            assert_array_equal(r, r2)
+            assert_array_equal(r, r3)
+            # check bool == 0x1
+            assert_array_equal(r.view(np.int8), r.astype(np.int8))
+            assert_array_equal(r2.view(np.int8), r2.astype(np.int8))
+            assert_array_equal(r3.view(np.int8), r3.astype(np.int8))
+
+            # isnan on amd64 takes the same code path
+            assert_array_equal(np.isnan(self.nf[i:]), self.ef[i:])
+
+    def test_double(self):
+        # offset for alignment test
+        for i in range(2):
+            assert_array_equal(self.d[i:] > 0, self.ed[i:])
+            assert_array_equal(self.d[i:] - 1 >= 0, self.ed[i:])
+            assert_array_equal(self.d[i:] == 0, ~self.ed[i:])
+            assert_array_equal(-self.d[i:] < 0, self.ed[i:])
+            assert_array_equal(-self.d[i:] + 1 <= 0, self.ed[i:])
+            r = self.d[i:] != 0
+            assert_array_equal(r, self.ed[i:])
+            r2 = self.d[i:] != np.zeros_like(self.d[i:])
+            r3 = 0 != self.d[i:]
+            assert_array_equal(r, r2)
+            assert_array_equal(r, r3)
+            # check bool == 0x1
+            assert_array_equal(r.view(np.int8), r.astype(np.int8))
+            assert_array_equal(r2.view(np.int8), r2.astype(np.int8))
+            assert_array_equal(r3.view(np.int8), r3.astype(np.int8))
+
+            # isnan on amd64 takes the same code path
+            assert_array_equal(np.isnan(self.nd[i:]), self.ed[i:])
+
+
+class TestSeterr(TestCase):
+    def test_default(self):
+        err = np.geterr()
+        self.assertEqual(err, dict(
+            divide='warn',
+            invalid='warn',
+            over='warn',
+            under='ignore',
+        ))
+
+    def test_set(self):
+        with np.errstate():
+            err = np.seterr()
+            old = np.seterr(divide='print')
+            self.assertTrue(err == old)
+            new = np.seterr()
+            self.assertTrue(new['divide'] == 'print')
+            np.seterr(over='raise')
+            self.assertTrue(np.geterr()['over'] == 'raise')
+            self.assertTrue(new['divide'] == 'print')
+            np.seterr(**old)
+            self.assertTrue(np.geterr() == old)
+
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_divide_err(self):
+        with np.errstate(divide='raise'):
+            try:
+                np.array([1.]) / np.array([0.])
+            except FloatingPointError:
+                pass
+            else:
+                self.fail()
+            np.seterr(divide='ignore')
+            np.array([1.]) / np.array([0.])
+
+    def test_errobj(self):
+        olderrobj = np.geterrobj()
+        self.called = 0
+        try:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter("always")
+                with np.errstate(divide='warn'):
+                    np.seterrobj([20000, 1, None])
+                    np.array([1.]) / np.array([0.])
+                    self.assertEqual(len(w), 1)
+
+            def log_err(*args):
+                self.called += 1
+                extobj_err = args
+                assert_(len(extobj_err) == 2)
+                assert_("divide" in extobj_err[0])
+
+            with np.errstate(divide='ignore'):
+                np.seterrobj([20000, 3, log_err])
+                np.array([1.]) / np.array([0.])
+            self.assertEqual(self.called, 1)
+
+            np.seterrobj(olderrobj)
+            with np.errstate(divide='ignore'):
+                np.divide(1., 0., extobj=[20000, 3, log_err])
+            self.assertEqual(self.called, 2)
+        finally:
+            np.seterrobj(olderrobj)
+            del self.called
+
+    def test_errobj_noerrmask(self):
+        # errmask = 0 has a special code path for the default
+        olderrobj = np.geterrobj()
+        try:
+            # set errobj to something non default
+            np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT,
+                         umath.ERR_DEFAULT + 1, None])
+            # call a ufunc
+            np.isnan(np.array([6]))
+            # same with the default, lots of times to get rid of possible
+            # pre-existing stack in the code
+            for i in range(10000):
+                np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, umath.ERR_DEFAULT,
+                             None])
+            np.isnan(np.array([6]))
+        finally:
+            np.seterrobj(olderrobj)
+
+
+class TestFloatExceptions(TestCase):
+    def assert_raises_fpe(self, fpeerr, flop, x, y):
+        ftype = type(x)
+        try:
+            flop(x, y)
+            assert_(False,
+                    "Type %s did not raise fpe error '%s'." % (ftype, fpeerr))
+        except FloatingPointError as exc:
+            assert_(str(exc).find(fpeerr) >= 0,
+                    "Type %s raised wrong fpe error '%s'." % (ftype, exc))
+
+    def assert_op_raises_fpe(self, fpeerr, flop, sc1, sc2):
+        # Check that fpe exception is raised.
+        #
+        # Given a floating operation `flop` and two scalar values, check that
+        # the operation raises the floating point exception specified by
+        # `fpeerr`. Tests all variants with 0-d array scalars as well.
+
+        self.assert_raises_fpe(fpeerr, flop, sc1, sc2)
+        self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2)
+        self.assert_raises_fpe(fpeerr, flop, sc1, sc2[()])
+        self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2[()])
+
+    @dec.knownfailureif(True, "See ticket #2350")
+    def test_floating_exceptions(self):
+        # Test basic arithmetic function errors
+        with np.errstate(all='raise'):
+            # Test for all real and complex float types
+            for typecode in np.typecodes['AllFloat']:
+                ftype = np.obj2sctype(typecode)
+                if np.dtype(ftype).kind == 'f':
+                    # Get some extreme values for the type
+                    fi = np.finfo(ftype)
+                    ft_tiny = fi.tiny
+                    ft_max = fi.max
+                    ft_eps = fi.eps
+                    underflow = 'underflow'
+                    divbyzero = 'divide by zero'
+                else:
+                    # 'c', complex, corresponding real dtype
+                    rtype = type(ftype(0).real)
+                    fi = np.finfo(rtype)
+                    ft_tiny = ftype(fi.tiny)
+                    ft_max = ftype(fi.max)
+                    ft_eps = ftype(fi.eps)
+                    # The complex types raise different exceptions
+                    underflow = ''
+                    divbyzero = ''
+                overflow = 'overflow'
+                invalid = 'invalid'
+
+                self.assert_raises_fpe(underflow,
+                                       lambda a, b: a/b, ft_tiny, ft_max)
+                self.assert_raises_fpe(underflow,
+                                       lambda a, b: a*b, ft_tiny, ft_tiny)
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a*b, ft_max, ftype(2))
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a/b, ft_max, ftype(0.5))
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a+b, ft_max, ft_max*ft_eps)
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a-b, -ft_max, ft_max*ft_eps)
+                self.assert_raises_fpe(overflow,
+                                       np.power, ftype(2), ftype(2**fi.nexp))
+                self.assert_raises_fpe(divbyzero,
+                                       lambda a, b: a/b, ftype(1), ftype(0))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a/b, ftype(np.inf), ftype(np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a/b, ftype(0), ftype(0))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a-b, ftype(np.inf), ftype(np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a+b, ftype(np.inf), ftype(-np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a*b, ftype(0), ftype(np.inf))
+
+    def test_warnings(self):
+        # test warning code path
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter("always")
+            with np.errstate(all="warn"):
+                np.divide(1, 0.)
+                self.assertEqual(len(w), 1)
+                self.assertTrue("divide by zero" in str(w[0].message))
+                np.array(1e300) * np.array(1e300)
+                self.assertEqual(len(w), 2)
+                self.assertTrue("overflow" in str(w[-1].message))
+                np.array(np.inf) - np.array(np.inf)
+                self.assertEqual(len(w), 3)
+                self.assertTrue("invalid value" in str(w[-1].message))
+                np.array(1e-300) * np.array(1e-300)
+                self.assertEqual(len(w), 4)
+                self.assertTrue("underflow" in str(w[-1].message))
+
+
+class TestTypes(TestCase):
+    def check_promotion_cases(self, promote_func):
+        # tests that the scalars get coerced correctly.
+        b = np.bool_(0)
+        i8, i16, i32, i64 = np.int8(0), np.int16(0), np.int32(0), np.int64(0)
+        u8, u16, u32, u64 = np.uint8(0), np.uint16(0), np.uint32(0), np.uint64(0)
+        f32, f64, fld = np.float32(0), np.float64(0), np.longdouble(0)
+        c64, c128, cld = np.complex64(0), np.complex128(0), np.clongdouble(0)
+
+        # coercion within the same kind
+        assert_equal(promote_func(i8, i16), np.dtype(np.int16))
+        assert_equal(promote_func(i32, i8), np.dtype(np.int32))
+        assert_equal(promote_func(i16, i64), np.dtype(np.int64))
+        assert_equal(promote_func(u8, u32), np.dtype(np.uint32))
+        assert_equal(promote_func(f32, f64), np.dtype(np.float64))
+        assert_equal(promote_func(fld, f32), np.dtype(np.longdouble))
+        assert_equal(promote_func(f64, fld), np.dtype(np.longdouble))
+        assert_equal(promote_func(c128, c64), np.dtype(np.complex128))
+        assert_equal(promote_func(cld, c128), np.dtype(np.clongdouble))
+        assert_equal(promote_func(c64, fld), np.dtype(np.clongdouble))
+
+        # coercion between kinds
+        assert_equal(promote_func(b, i32), np.dtype(np.int32))
+        assert_equal(promote_func(b, u8), np.dtype(np.uint8))
+        assert_equal(promote_func(i8, u8), np.dtype(np.int16))
+        assert_equal(promote_func(u8, i32), np.dtype(np.int32))
+        assert_equal(promote_func(i64, u32), np.dtype(np.int64))
+        assert_equal(promote_func(u64, i32), np.dtype(np.float64))
+        assert_equal(promote_func(i32, f32), np.dtype(np.float64))
+        assert_equal(promote_func(i64, f32), np.dtype(np.float64))
+        assert_equal(promote_func(f32, i16), np.dtype(np.float32))
+        assert_equal(promote_func(f32, u32), np.dtype(np.float64))
+        assert_equal(promote_func(f32, c64), np.dtype(np.complex64))
+        assert_equal(promote_func(c128, f32), np.dtype(np.complex128))
+        assert_equal(promote_func(cld, f64), np.dtype(np.clongdouble))
+
+        # coercion between scalars and 1-D arrays
+        assert_equal(promote_func(np.array([b]), i8), np.dtype(np.int8))
+        assert_equal(promote_func(np.array([b]), u8), np.dtype(np.uint8))
+        assert_equal(promote_func(np.array([b]), i32), np.dtype(np.int32))
+        assert_equal(promote_func(np.array([b]), u32), np.dtype(np.uint32))
+        assert_equal(promote_func(np.array([i8]), i64), np.dtype(np.int8))
+        assert_equal(promote_func(u64, np.array([i32])), np.dtype(np.int32))
+        assert_equal(promote_func(i64, np.array([u32])), np.dtype(np.uint32))
+        assert_equal(promote_func(np.int32(-1), np.array([u64])),
+                     np.dtype(np.float64))
+        assert_equal(promote_func(f64, np.array([f32])), np.dtype(np.float32))
+        assert_equal(promote_func(fld, np.array([f32])), np.dtype(np.float32))
+        assert_equal(promote_func(np.array([f64]), fld), np.dtype(np.float64))
+        assert_equal(promote_func(fld, np.array([c64])),
+                     np.dtype(np.complex64))
+        assert_equal(promote_func(c64, np.array([f64])),
+                     np.dtype(np.complex128))
+        assert_equal(promote_func(np.complex64(3j), np.array([f64])),
+                     np.dtype(np.complex128))
+
+        # coercion between scalars and 1-D arrays, where
+        # the scalar has greater kind than the array
+        assert_equal(promote_func(np.array([b]), f64), np.dtype(np.float64))
+        assert_equal(promote_func(np.array([b]), i64), np.dtype(np.int64))
+        assert_equal(promote_func(np.array([b]), u64), np.dtype(np.uint64))
+        assert_equal(promote_func(np.array([i8]), f64), np.dtype(np.float64))
+        assert_equal(promote_func(np.array([u16]), f64), np.dtype(np.float64))
+
+        # uint and int are treated as the same "kind" for
+        # the purposes of array-scalar promotion.
+        assert_equal(promote_func(np.array([u16]), i32), np.dtype(np.uint16))
+
+        # float and complex are treated as the same "kind" for
+        # the purposes of array-scalar promotion, so that you can do
+        # (0j + float32array) to get a complex64 array instead of
+        # a complex128 array.
+        assert_equal(promote_func(np.array([f32]), c128),
+                     np.dtype(np.complex64))
+
+    def test_coercion(self):
+        def res_type(a, b):
+            return np.add(a, b).dtype
+
+        self.check_promotion_cases(res_type)
+
+        # Use-case: float/complex scalar * bool/int8 array
+        #           shouldn't narrow the float/complex type
+        for a in [np.array([True, False]), np.array([-3, 12], dtype=np.int8)]:
+            b = 1.234 * a
+            assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype)
+            b = np.longdouble(1.234) * a
+            assert_equal(b.dtype, np.dtype(np.longdouble),
+                         "array type %s" % a.dtype)
+            b = np.float64(1.234) * a
+            assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype)
+            b = np.float32(1.234) * a
+            assert_equal(b.dtype, np.dtype('f4'), "array type %s" % a.dtype)
+            b = np.float16(1.234) * a
+            assert_equal(b.dtype, np.dtype('f2'), "array type %s" % a.dtype)
+
+            b = 1.234j * a
+            assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype)
+            b = np.clongdouble(1.234j) * a
+            assert_equal(b.dtype, np.dtype(np.clongdouble),
+                         "array type %s" % a.dtype)
+            b = np.complex128(1.234j) * a
+            assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype)
+            b = np.complex64(1.234j) * a
+            assert_equal(b.dtype, np.dtype('c8'), "array type %s" % a.dtype)
+
+        # The following use-case is problematic, and to resolve its
+        # tricky side-effects requires more changes.
+        #
+        # Use-case: (1-t)*a, where 't' is a boolean array and 'a' is
+        #            a float32, shouldn't promote to float64
+        #
+        # a = np.array([1.0, 1.5], dtype=np.float32)
+        # t = np.array([True, False])
+        # b = t*a
+        # assert_equal(b, [1.0, 0.0])
+        # assert_equal(b.dtype, np.dtype('f4'))
+        # b = (1-t)*a
+        # assert_equal(b, [0.0, 1.5])
+        # assert_equal(b.dtype, np.dtype('f4'))
+        #
+        # Probably ~t (bitwise negation) is more proper to use here,
+        # but this is arguably less intuitive to understand at a glance, and
+        # would fail if 't' is actually an integer array instead of boolean:
+        #
+        # b = (~t)*a
+        # assert_equal(b, [0.0, 1.5])
+        # assert_equal(b.dtype, np.dtype('f4'))
+
+    def test_result_type(self):
+        self.check_promotion_cases(np.result_type)
+        assert_(np.result_type(None) == np.dtype(None))
+
+    def test_promote_types_endian(self):
+        # promote_types should always return native-endian types
+        assert_equal(np.promote_types('<i8', '<i8'), np.dtype('i8'))
+        assert_equal(np.promote_types('>i8', '>i8'), np.dtype('i8'))
+
+        assert_equal(np.promote_types('>i8', '>U16'), np.dtype('U21'))
+        assert_equal(np.promote_types('<i8', '<U16'), np.dtype('U21'))
+        assert_equal(np.promote_types('>U16', '>i8'), np.dtype('U21'))
+        assert_equal(np.promote_types('<U16', '<i8'), np.dtype('U21'))
+
+        assert_equal(np.promote_types('<S5', '<U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('>S5', '>U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('<U8', '<S5'), np.dtype('U8'))
+        assert_equal(np.promote_types('>U8', '>S5'), np.dtype('U8'))
+        assert_equal(np.promote_types('<U5', '<U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('>U8', '>U5'), np.dtype('U8'))
+
+        assert_equal(np.promote_types('<M8', '<M8'), np.dtype('M8'))
+        assert_equal(np.promote_types('>M8', '>M8'), np.dtype('M8'))
+        assert_equal(np.promote_types('<m8', '<m8'), np.dtype('m8'))
+        assert_equal(np.promote_types('>m8', '>m8'), np.dtype('m8'))
+
+    def test_promote_types_strings(self):
+        assert_equal(np.promote_types('bool', 'S'), np.dtype('S5'))
+        assert_equal(np.promote_types('b', 'S'), np.dtype('S4'))
+        assert_equal(np.promote_types('u1', 'S'), np.dtype('S3'))
+        assert_equal(np.promote_types('u2', 'S'), np.dtype('S5'))
+        assert_equal(np.promote_types('u4', 'S'), np.dtype('S10'))
+        assert_equal(np.promote_types('u8', 'S'), np.dtype('S20'))
+        assert_equal(np.promote_types('i1', 'S'), np.dtype('S4'))
+        assert_equal(np.promote_types('i2', 'S'), np.dtype('S6'))
+        assert_equal(np.promote_types('i4', 'S'), np.dtype('S11'))
+        assert_equal(np.promote_types('i8', 'S'), np.dtype('S21'))
+        assert_equal(np.promote_types('bool', 'U'), np.dtype('U5'))
+        assert_equal(np.promote_types('b', 'U'), np.dtype('U4'))
+        assert_equal(np.promote_types('u1', 'U'), np.dtype('U3'))
+        assert_equal(np.promote_types('u2', 'U'), np.dtype('U5'))
+        assert_equal(np.promote_types('u4', 'U'), np.dtype('U10'))
+        assert_equal(np.promote_types('u8', 'U'), np.dtype('U20'))
+        assert_equal(np.promote_types('i1', 'U'), np.dtype('U4'))
+        assert_equal(np.promote_types('i2', 'U'), np.dtype('U6'))
+        assert_equal(np.promote_types('i4', 'U'), np.dtype('U11'))
+        assert_equal(np.promote_types('i8', 'U'), np.dtype('U21'))
+        assert_equal(np.promote_types('bool', 'S1'), np.dtype('S5'))
+        assert_equal(np.promote_types('bool', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('b', 'S1'), np.dtype('S4'))
+        assert_equal(np.promote_types('b', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u1', 'S1'), np.dtype('S3'))
+        assert_equal(np.promote_types('u1', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u2', 'S1'), np.dtype('S5'))
+        assert_equal(np.promote_types('u2', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u4', 'S1'), np.dtype('S10'))
+        assert_equal(np.promote_types('u4', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u8', 'S1'), np.dtype('S20'))
+        assert_equal(np.promote_types('u8', 'S30'), np.dtype('S30'))
+
+    def test_can_cast(self):
+        assert_(np.can_cast(np.int32, np.int64))
+        assert_(np.can_cast(np.float64, np.complex))
+        assert_(not np.can_cast(np.complex, np.float))
+
+        assert_(np.can_cast('i8', 'f8'))
+        assert_(not np.can_cast('i8', 'f4'))
+        assert_(np.can_cast('i4', 'S11'))
+
+        assert_(np.can_cast('i8', 'i8', 'no'))
+        assert_(not np.can_cast('<i8', '>i8', 'no'))
+
+        assert_(np.can_cast('<i8', '>i8', 'equiv'))
+        assert_(not np.can_cast('<i4', '>i8', 'equiv'))
+
+        assert_(np.can_cast('<i4', '>i8', 'safe'))
+        assert_(not np.can_cast('<i8', '>i4', 'safe'))
+
+        assert_(np.can_cast('<i8', '>i4', 'same_kind'))
+        assert_(not np.can_cast('<i8', '>u4', 'same_kind'))
+
+        assert_(np.can_cast('<i8', '>u4', 'unsafe'))
+
+        assert_(np.can_cast('bool', 'S5'))
+        assert_(not np.can_cast('bool', 'S4'))
+
+        assert_(np.can_cast('b', 'S4'))
+        assert_(not np.can_cast('b', 'S3'))
+
+        assert_(np.can_cast('u1', 'S3'))
+        assert_(not np.can_cast('u1', 'S2'))
+        assert_(np.can_cast('u2', 'S5'))
+        assert_(not np.can_cast('u2', 'S4'))
+        assert_(np.can_cast('u4', 'S10'))
+        assert_(not np.can_cast('u4', 'S9'))
+        assert_(np.can_cast('u8', 'S20'))
+        assert_(not np.can_cast('u8', 'S19'))
+
+        assert_(np.can_cast('i1', 'S4'))
+        assert_(not np.can_cast('i1', 'S3'))
+        assert_(np.can_cast('i2', 'S6'))
+        assert_(not np.can_cast('i2', 'S5'))
+        assert_(np.can_cast('i4', 'S11'))
+        assert_(not np.can_cast('i4', 'S10'))
+        assert_(np.can_cast('i8', 'S21'))
+        assert_(not np.can_cast('i8', 'S20'))
+
+        assert_(np.can_cast('bool', 'S5'))
+        assert_(not np.can_cast('bool', 'S4'))
+
+        assert_(np.can_cast('b', 'U4'))
+        assert_(not np.can_cast('b', 'U3'))
+
+        assert_(np.can_cast('u1', 'U3'))
+        assert_(not np.can_cast('u1', 'U2'))
+        assert_(np.can_cast('u2', 'U5'))
+        assert_(not np.can_cast('u2', 'U4'))
+        assert_(np.can_cast('u4', 'U10'))
+        assert_(not np.can_cast('u4', 'U9'))
+        assert_(np.can_cast('u8', 'U20'))
+        assert_(not np.can_cast('u8', 'U19'))
+
+        assert_(np.can_cast('i1', 'U4'))
+        assert_(not np.can_cast('i1', 'U3'))
+        assert_(np.can_cast('i2', 'U6'))
+        assert_(not np.can_cast('i2', 'U5'))
+        assert_(np.can_cast('i4', 'U11'))
+        assert_(not np.can_cast('i4', 'U10'))
+        assert_(np.can_cast('i8', 'U21'))
+        assert_(not np.can_cast('i8', 'U20'))
+
+        assert_raises(TypeError, np.can_cast, 'i4', None)
+        assert_raises(TypeError, np.can_cast, None, 'i4')
+
+
+# Custom exception class to test exception propagation in fromiter
+class NIterError(Exception):
+    pass
+
+
+class TestFromiter(TestCase):
+    def makegen(self):
+        for x in range(24):
+            yield x**2
+
+    def test_types(self):
+        ai32 = np.fromiter(self.makegen(), np.int32)
+        ai64 = np.fromiter(self.makegen(), np.int64)
+        af = np.fromiter(self.makegen(), float)
+        self.assertTrue(ai32.dtype == np.dtype(np.int32))
+        self.assertTrue(ai64.dtype == np.dtype(np.int64))
+        self.assertTrue(af.dtype == np.dtype(float))
+
+    def test_lengths(self):
+        expected = np.array(list(self.makegen()))
+        a = np.fromiter(self.makegen(), int)
+        a20 = np.fromiter(self.makegen(), int, 20)
+        self.assertTrue(len(a) == len(expected))
+        self.assertTrue(len(a20) == 20)
+        self.assertRaises(ValueError, np.fromiter,
+                          self.makegen(), int, len(expected) + 10)
+
+    def test_values(self):
+        expected = np.array(list(self.makegen()))
+        a = np.fromiter(self.makegen(), int)
+        a20 = np.fromiter(self.makegen(), int, 20)
+        self.assertTrue(np.alltrue(a == expected, axis=0))
+        self.assertTrue(np.alltrue(a20 == expected[:20], axis=0))
+
+    def load_data(self, n, eindex):
+        # Utility method for the issue 2592 tests.
+        # Raise an exception at the desired index in the iterator.
+        for e in range(n):
+            if e == eindex:
+                raise NIterError('error at index %s' % eindex)
+            yield e
+
+    def test_2592(self):
+        # Test iteration exceptions are correctly raised.
+        count, eindex = 10, 5
+        self.assertRaises(NIterError, np.fromiter,
+                          self.load_data(count, eindex), dtype=int, count=count)
+
+    def test_2592_edge(self):
+        # Test iter. exceptions, edge case (exception at end of iterator).
+        count = 10
+        eindex = count-1
+        self.assertRaises(NIterError, np.fromiter,
+                          self.load_data(count, eindex), dtype=int, count=count)
+
+
+class TestNonzero(TestCase):
+    def test_nonzero_trivial(self):
+        assert_equal(np.count_nonzero(np.array([])), 0)
+        assert_equal(np.count_nonzero(np.array([], dtype='?')), 0)
+        assert_equal(np.nonzero(np.array([])), ([],))
+
+        assert_equal(np.count_nonzero(np.array(0)), 0)
+        assert_equal(np.count_nonzero(np.array(0, dtype='?')), 0)
+        assert_equal(np.nonzero(np.array(0)), ([],))
+        assert_equal(np.count_nonzero(np.array(1)), 1)
+        assert_equal(np.count_nonzero(np.array(1, dtype='?')), 1)
+        assert_equal(np.nonzero(np.array(1)), ([0],))
+
+    def test_nonzero_onedim(self):
+        x = np.array([1, 0, 2, -1, 0, 0, 8])
+        assert_equal(np.count_nonzero(x), 4)
+        assert_equal(np.count_nonzero(x), 4)
+        assert_equal(np.nonzero(x), ([0, 2, 3, 6],))
+
+        x = np.array([(1, 2), (0, 0), (1, 1), (-1, 3), (0, 7)],
+                     dtype=[('a', 'i4'), ('b', 'i2')])
+        assert_equal(np.count_nonzero(x['a']), 3)
+        assert_equal(np.count_nonzero(x['b']), 4)
+        assert_equal(np.nonzero(x['a']), ([0, 2, 3],))
+        assert_equal(np.nonzero(x['b']), ([0, 2, 3, 4],))
+
+    def test_nonzero_twodim(self):
+        x = np.array([[0, 1, 0], [2, 0, 3]])
+        assert_equal(np.count_nonzero(x), 3)
+        assert_equal(np.nonzero(x), ([0, 1, 1], [1, 0, 2]))
+
+        x = np.eye(3)
+        assert_equal(np.count_nonzero(x), 3)
+        assert_equal(np.nonzero(x), ([0, 1, 2], [0, 1, 2]))
+
+        x = np.array([[(0, 1), (0, 0), (1, 11)],
+                   [(1, 1), (1, 0), (0, 0)],
+                   [(0, 0), (1, 5), (0, 1)]], dtype=[('a', 'f4'), ('b', 'u1')])
+        assert_equal(np.count_nonzero(x['a']), 4)
+        assert_equal(np.count_nonzero(x['b']), 5)
+        assert_equal(np.nonzero(x['a']), ([0, 1, 1, 2], [2, 0, 1, 1]))
+        assert_equal(np.nonzero(x['b']), ([0, 0, 1, 2, 2], [0, 2, 0, 1, 2]))
+
+        assert_(not x['a'].T.flags.aligned)
+        assert_equal(np.count_nonzero(x['a'].T), 4)
+        assert_equal(np.count_nonzero(x['b'].T), 5)
+        assert_equal(np.nonzero(x['a'].T), ([0, 1, 1, 2], [1, 1, 2, 0]))
+        assert_equal(np.nonzero(x['b'].T), ([0, 0, 1, 2, 2], [0, 1, 2, 0, 2]))
+
+    def test_sparse(self):
+        # test special sparse condition boolean code path
+        for i in range(20):
+            c = np.zeros(200, dtype=np.bool)
+            c[i::20] = True
+            assert_equal(np.nonzero(c)[0], np.arange(i, 200 + i, 20))
+
+            c = np.zeros(400, dtype=np.bool)
+            c[10 + i:20 + i] = True
+            c[20 + i*2] = True
+            assert_equal(np.nonzero(c)[0],
+                         np.concatenate((np.arange(10 + i, 20 + i), [20 + i*2])))
+
+    def test_return_type(self):
+        class C(np.ndarray):
+            pass
+
+        for view in (C, np.ndarray):
+            for nd in range(1, 4):
+                shape = tuple(range(2, 2+nd))
+                x = np.arange(np.prod(shape)).reshape(shape).view(view)
+                for nzx in (np.nonzero(x), x.nonzero()):
+                    for nzx_i in nzx:
+                        assert_(type(nzx_i) is np.ndarray)
+                        assert_(nzx_i.flags.writeable)
+
+    # Tests that the array method
+    # call works
+    def test_array_method(self):
+        m = np.array([[1, 0, 0], [4, 0, 6]])
+        tgt = [[0, 1, 1], [0, 0, 2]]
+
+        assert_equal(m.nonzero(), tgt)
+
+
+class TestIndex(TestCase):
+    def test_boolean(self):
+        a = rand(3, 5, 8)
+        V = rand(5, 8)
+        g1 = randint(0, 5, size=15)
+        g2 = randint(0, 8, size=15)
+        V[g1, g2] = -V[g1, g2]
+        assert_((np.array([a[0][V > 0], a[1][V > 0], a[2][V > 0]]) == a[:, V > 0]).all())
+
+    def test_boolean_edgecase(self):
+        a = np.array([], dtype='int32')
+        b = np.array([], dtype='bool')
+        c = a[b]
+        assert_equal(c, [])
+        assert_equal(c.dtype, np.dtype('int32'))
+
+
+class TestBinaryRepr(TestCase):
+    def test_zero(self):
+        assert_equal(np.binary_repr(0), '0')
+
+    def test_large(self):
+        assert_equal(np.binary_repr(10736848), '101000111101010011010000')
+
+    def test_negative(self):
+        assert_equal(np.binary_repr(-1), '-1')
+        assert_equal(np.binary_repr(-1, width=8), '11111111')
+
+
+class TestBaseRepr(TestCase):
+    def test_base3(self):
+        assert_equal(np.base_repr(3**5, 3), '100000')
+
+    def test_positive(self):
+        assert_equal(np.base_repr(12, 10), '12')
+        assert_equal(np.base_repr(12, 10, 4), '000012')
+        assert_equal(np.base_repr(12, 4), '30')
+        assert_equal(np.base_repr(3731624803700888, 36), '10QR0ROFCEW')
+
+    def test_negative(self):
+        assert_equal(np.base_repr(-12, 10), '-12')
+        assert_equal(np.base_repr(-12, 10, 4), '-000012')
+        assert_equal(np.base_repr(-12, 4), '-30')
+
+
+class TestArrayComparisons(TestCase):
+    def test_array_equal(self):
+        res = np.array_equal(np.array([1, 2]), np.array([1, 2]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([1, 2, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([3, 4]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([1, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array(['a'], dtype='S1'), np.array(['a'], dtype='S1'))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([('a', 1)], dtype='S1,u4'),
+                             np.array([('a', 1)], dtype='S1,u4'))
+        assert_(res)
+        assert_(type(res) is bool)
+
+    def test_array_equiv(self):
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 2]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 2, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([3, 4]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+
+        res = np.array_equiv(np.array([1, 1]), np.array([1]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 1]), np.array([[1], [1]]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([2]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([[1], [2]]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
+        assert_(not res)
+        assert_(type(res) is bool)
+
+
+def assert_array_strict_equal(x, y):
+    assert_array_equal(x, y)
+    # Check flags, 32 bit arches typically don't provide 16 byte alignment
+    if ((x.dtype.alignment <= 8 or
+            np.intp().dtype.itemsize != 4) and
+            sys.platform != 'win32'):
+        assert_(x.flags == y.flags)
+    else:
+        assert_(x.flags.owndata == y.flags.owndata)
+        assert_(x.flags.writeable == y.flags.writeable)
+        assert_(x.flags.c_contiguous == y.flags.c_contiguous)
+        assert_(x.flags.f_contiguous == y.flags.f_contiguous)
+        assert_(x.flags.updateifcopy == y.flags.updateifcopy)
+    # check endianness
+    assert_(x.dtype.isnative == y.dtype.isnative)
+
+
+class TestClip(TestCase):
+    def setUp(self):
+        self.nr = 5
+        self.nc = 3
+
+    def fastclip(self, a, m, M, out=None):
+        if out is None:
+            return a.clip(m, M)
+        else:
+            return a.clip(m, M, out)
+
+    def clip(self, a, m, M, out=None):
+        # use slow-clip
+        selector = np.less(a, m) + 2*np.greater(a, M)
+        return selector.choose((a, m, M), out=out)
+
+    # Handy functions
+    def _generate_data(self, n, m):
+        return randn(n, m)
+
+    def _generate_data_complex(self, n, m):
+        return randn(n, m) + 1.j * rand(n, m)
+
+    def _generate_flt_data(self, n, m):
+        return (randn(n, m)).astype(np.float32)
+
+    def _neg_byteorder(self, a):
+        a = np.asarray(a)
+        if sys.byteorder == 'little':
+            a = a.astype(a.dtype.newbyteorder('>'))
+        else:
+            a = a.astype(a.dtype.newbyteorder('<'))
+        return a
+
+    def _generate_non_native_data(self, n, m):
+        data = randn(n, m)
+        data = self._neg_byteorder(data)
+        assert_(not data.dtype.isnative)
+        return data
+
+    def _generate_int_data(self, n, m):
+        return (10 * rand(n, m)).astype(np.int64)
+
+    def _generate_int32_data(self, n, m):
+        return (10 * rand(n, m)).astype(np.int32)
+
+    # Now the real test cases
+    def test_simple_double(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = 0.1
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int(self):
+        # Test native int input with scalar min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        a = a.astype(int)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_array_double(self):
+        # Test native double input with array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = np.zeros(a.shape)
+        M = m + 0.5
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_nonnative(self):
+        # Test non native double input with scalar min/max.
+        # Test native double input with non native double scalar min/max.
+        a = self._generate_non_native_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_equal(ac, act)
+
+        # Test native double input with non native double scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = self._neg_byteorder(0.6)
+        assert_(not M.dtype.isnative)
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_equal(ac, act)
+
+    def test_simple_complex(self):
+        # Test native complex input with native double scalar min/max.
+        # Test native input with complex double scalar min/max.
+        a = 3 * self._generate_data_complex(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+        # Test native input with complex double scalar min/max.
+        a = 3 * self._generate_data(self.nr, self.nc)
+        m = -0.5 + 1.j
+        M = 1. + 2.j
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_complex(self):
+        # Address Issue gh-5354 for clipping complex arrays
+        # Test native complex input without explicit min/max
+        # ie, either min=None or max=None
+        a = np.ones(10, dtype=np.complex)
+        m = a.min()
+        M = a.max()
+        am = self.fastclip(a, m, None)
+        aM = self.fastclip(a, None, M)
+        assert_array_strict_equal(am, a)
+        assert_array_strict_equal(aM, a)
+
+    def test_clip_non_contig(self):
+        # Test clip for non contiguous native input and native scalar min/max.
+        a = self._generate_data(self.nr * 2, self.nc * 3)
+        a = a[::2, ::3]
+        assert_(not a.flags['F_CONTIGUOUS'])
+        assert_(not a.flags['C_CONTIGUOUS'])
+        ac = self.fastclip(a, -1.6, 1.7)
+        act = self.clip(a, -1.6, 1.7)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_out(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = np.zeros(a.shape)
+        act = np.zeros(a.shape)
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int32_inout(self):
+        # Test native int32 input with double min/max and int32 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float64(0)
+        M = np.float64(2)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int64_out(self):
+        # Test native int32 input with int32 scalar min/max and int64 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.int32(-1)
+        M = np.int32(1)
+        ac = np.zeros(a.shape, dtype=np.int64)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int64_inout(self):
+        # Test native int32 input with double array min/max and int32 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.zeros(a.shape, np.float64)
+        M = np.float64(1)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int32_out(self):
+        # Test native double input with scalar min/max and int out.
+        a = self._generate_data(self.nr, self.nc)
+        m = -1.0
+        M = 2.0
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_inplace_01(self):
+        # Test native double input with array min/max in-place.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = np.zeros(a.shape)
+        M = 1.0
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_simple_inplace_02(self):
+        # Test native double input with scalar min/max in-place.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_noncontig_inplace(self):
+        # Test non contiguous double input with double scalar min/max in-place.
+        a = self._generate_data(self.nr * 2, self.nc * 3)
+        a = a[::2, ::3]
+        assert_(not a.flags['F_CONTIGUOUS'])
+        assert_(not a.flags['C_CONTIGUOUS'])
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_equal(a, ac)
+
+    def test_type_cast_01(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_02(self):
+        # Test native int32 input with int32 scalar min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        a = a.astype(np.int32)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_03(self):
+        # Test native int32 input with float64 scalar min/max.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, np.float64(m), np.float64(M))
+        act = self.clip(a, np.float64(m), np.float64(M))
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_04(self):
+        # Test native int32 input with float32 scalar min/max.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float32(-2)
+        M = np.float32(4)
+        act = self.fastclip(a, m, M)
+        ac = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_05(self):
+        # Test native int32 with double arrays min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        ac = self.fastclip(a, m * np.zeros(a.shape), M)
+        act = self.clip(a, m * np.zeros(a.shape), M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_06(self):
+        # Test native with NON native scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = 0.5
+        m_s = self._neg_byteorder(m)
+        M = 1.
+        act = self.clip(a, m_s, M)
+        ac = self.fastclip(a, m_s, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_07(self):
+        # Test NON native with native array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5 * np.ones(a.shape)
+        M = 1.
+        a_s = self._neg_byteorder(a)
+        assert_(not a_s.dtype.isnative)
+        act = a_s.clip(m, M)
+        ac = self.fastclip(a_s, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_08(self):
+        # Test NON native with native scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        a_s = self._neg_byteorder(a)
+        assert_(not a_s.dtype.isnative)
+        ac = self.fastclip(a_s, m, M)
+        act = a_s.clip(m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_09(self):
+        # Test native with NON native array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5 * np.ones(a.shape)
+        M = 1.
+        m_s = self._neg_byteorder(m)
+        assert_(not m_s.dtype.isnative)
+        ac = self.fastclip(a, m_s, M)
+        act = self.clip(a, m_s, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_10(self):
+        # Test native int32 with float min/max and float out for output argument.
+        a = self._generate_int_data(self.nr, self.nc)
+        b = np.zeros(a.shape, dtype=np.float32)
+        m = np.float32(-0.5)
+        M = np.float32(1)
+        act = self.clip(a, m, M, out=b)
+        ac = self.fastclip(a, m, M, out=b)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_11(self):
+        # Test non native with native scalar, min/max, out non native
+        a = self._generate_non_native_data(self.nr, self.nc)
+        b = a.copy()
+        b = b.astype(b.dtype.newbyteorder('>'))
+        bt = b.copy()
+        m = -0.5
+        M = 1.
+        self.fastclip(a, m, M, out=b)
+        self.clip(a, m, M, out=bt)
+        assert_array_strict_equal(b, bt)
+
+    def test_type_cast_12(self):
+        # Test native int32 input and min/max and float out
+        a = self._generate_int_data(self.nr, self.nc)
+        b = np.zeros(a.shape, dtype=np.float32)
+        m = np.int32(0)
+        M = np.int32(1)
+        act = self.clip(a, m, M, out=b)
+        ac = self.fastclip(a, m, M, out=b)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple(self):
+        # Test native double input with scalar min/max
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = np.zeros(a.shape)
+        act = np.zeros(a.shape)
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple2(self):
+        # Test native int32 input with double min/max and int32 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float64(0)
+        M = np.float64(2)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple_int32(self):
+        # Test native int32 input with int32 scalar min/max and int64 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.int32(-1)
+        M = np.int32(1)
+        ac = np.zeros(a.shape, dtype=np.int64)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_array_int32(self):
+        # Test native int32 input with double array min/max and int32 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.zeros(a.shape, np.float64)
+        M = np.float64(1)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_array_outint32(self):
+        # Test native double input with scalar min/max and int out
+        a = self._generate_data(self.nr, self.nc)
+        m = -1.0
+        M = 2.0
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_inplace_array(self):
+        # Test native double input with array min/max
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = np.zeros(a.shape)
+        M = 1.0
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_clip_inplace_simple(self):
+        # Test native double input with scalar min/max
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_clip_func_takes_out(self):
+        # Ensure that the clip() function takes an out=argument.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        a2 = np.clip(a, m, M, out=a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a2, ac)
+        self.assertTrue(a2 is a)
+
+    def test_clip_nan(self):
+        d = np.arange(7.)
+        assert_equal(d.clip(min=np.nan), d)
+        assert_equal(d.clip(max=np.nan), d)
+        assert_equal(d.clip(min=np.nan, max=np.nan), d)
+        assert_equal(d.clip(min=-2, max=np.nan), d)
+        assert_equal(d.clip(min=np.nan, max=10), d)
+
+
+class TestAllclose(object):
+    rtol = 1e-5
+    atol = 1e-8
+
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def tst_allclose(self, x, y):
+        assert_(np.allclose(x, y), "%s and %s not close" % (x, y))
+
+    def tst_not_allclose(self, x, y):
+        assert_(not np.allclose(x, y), "%s and %s shouldn't be close" % (x, y))
+
+    def test_ip_allclose(self):
+        # Parametric test factory.
+        arr = np.array([100, 1000])
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        atol = self.atol
+        rtol = self.rtol
+
+        data = [([1, 0], [1, 0]),
+                ([atol], [0]),
+                ([1], [1+rtol+atol]),
+                (arr, arr + arr*rtol),
+                (arr, arr + arr*rtol + atol*2),
+                (aran, aran + aran*rtol),
+                (np.inf, np.inf),
+                (np.inf, [np.inf])]
+
+        for (x, y) in data:
+            yield (self.tst_allclose, x, y)
+
+    def test_ip_not_allclose(self):
+        # Parametric test factory.
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        atol = self.atol
+        rtol = self.rtol
+
+        data = [([np.inf, 0], [1, np.inf]),
+                ([np.inf, 0], [1, 0]),
+                ([np.inf, np.inf], [1, np.inf]),
+                ([np.inf, np.inf], [1, 0]),
+                ([-np.inf, 0], [np.inf, 0]),
+                ([np.nan, 0], [np.nan, 0]),
+                ([atol*2], [0]),
+                ([1], [1+rtol+atol*2]),
+                (aran, aran + aran*atol + atol*2),
+                (np.array([np.inf, 1]), np.array([0, np.inf]))]
+
+        for (x, y) in data:
+            yield (self.tst_not_allclose, x, y)
+
+    def test_no_parameter_modification(self):
+        x = np.array([np.inf, 1])
+        y = np.array([0, np.inf])
+        np.allclose(x, y)
+        assert_array_equal(x, np.array([np.inf, 1]))
+        assert_array_equal(y, np.array([0, np.inf]))
+
+    def test_min_int(self):
+        # Could make problems because of abs(min_int) == min_int
+        min_int = np.iinfo(np.int_).min
+        a = np.array([min_int], dtype=np.int_)
+        assert_(np.allclose(a, a))
+
+    def test_equalnan(self):
+        x = np.array([1.0, np.nan])
+        assert_(np.allclose(x, x, equal_nan=True))
+
+    def test_return_class_is_ndarray(self):
+        # Issue gh-6475
+        # Check that allclose does not preserve subtypes
+        class Foo(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+        a = Foo([1])
+        assert_(type(np.allclose(a, a)) is bool)
+
+
+class TestIsclose(object):
+    rtol = 1e-5
+    atol = 1e-8
+
+    def setup(self):
+        atol = self.atol
+        rtol = self.rtol
+        arr = np.array([100, 1000])
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        self.all_close_tests = [
+                ([1, 0], [1, 0]),
+                ([atol], [0]),
+                ([1], [1 + rtol + atol]),
+                (arr, arr + arr*rtol),
+                (arr, arr + arr*rtol + atol),
+                (aran, aran + aran*rtol),
+                (np.inf, np.inf),
+                (np.inf, [np.inf]),
+                ([np.inf, -np.inf], [np.inf, -np.inf]),
+                ]
+        self.none_close_tests = [
+                ([np.inf, 0], [1, np.inf]),
+                ([np.inf, -np.inf], [1, 0]),
+                ([np.inf, np.inf], [1, -np.inf]),
+                ([np.inf, np.inf], [1, 0]),
+                ([np.nan, 0], [np.nan, -np.inf]),
+                ([atol*2], [0]),
+                ([1], [1 + rtol + atol*2]),
+                (aran, aran + rtol*1.1*aran + atol*1.1),
+                (np.array([np.inf, 1]), np.array([0, np.inf])),
+                ]
+        self.some_close_tests = [
+                ([np.inf, 0], [np.inf, atol*2]),
+                ([atol, 1, 1e6*(1 + 2*rtol) + atol], [0, np.nan, 1e6]),
+                (np.arange(3), [0, 1, 2.1]),
+                (np.nan, [np.nan, np.nan, np.nan]),
+                ([0], [atol, np.inf, -np.inf, np.nan]),
+                (0, [atol, np.inf, -np.inf, np.nan]),
+                ]
+        self.some_close_results = [
+                [True, False],
+                [True, False, False],
+                [True, True, False],
+                [False, False, False],
+                [True, False, False, False],
+                [True, False, False, False],
+                ]
+
+    def test_ip_isclose(self):
+        self.setup()
+        tests = self.some_close_tests
+        results = self.some_close_results
+        for (x, y), result in zip(tests, results):
+            yield (assert_array_equal, np.isclose(x, y), result)
+
+    def tst_all_isclose(self, x, y):
+        assert_(np.all(np.isclose(x, y)), "%s and %s not close" % (x, y))
+
+    def tst_none_isclose(self, x, y):
+        msg = "%s and %s shouldn't be close"
+        assert_(not np.any(np.isclose(x, y)), msg % (x, y))
+
+    def tst_isclose_allclose(self, x, y):
+        msg = "isclose.all() and allclose aren't same for %s and %s"
+        msg2 = "isclose and allclose aren't same for %s and %s"
+        if np.isscalar(x) and np.isscalar(y):
+            assert_(np.isclose(x, y) == np.allclose(x, y), msg=msg2 % (x, y))
+        else:
+            assert_array_equal(np.isclose(x, y).all(), np.allclose(x, y), msg % (x, y))
+
+    def test_ip_all_isclose(self):
+        self.setup()
+        for (x, y) in self.all_close_tests:
+            yield (self.tst_all_isclose, x, y)
+
+    def test_ip_none_isclose(self):
+        self.setup()
+        for (x, y) in self.none_close_tests:
+            yield (self.tst_none_isclose, x, y)
+
+    def test_ip_isclose_allclose(self):
+        self.setup()
+        tests = (self.all_close_tests + self.none_close_tests +
+                 self.some_close_tests)
+        for (x, y) in tests:
+            yield (self.tst_isclose_allclose, x, y)
+
+    def test_equal_nan(self):
+        assert_array_equal(np.isclose(np.nan, np.nan, equal_nan=True), [True])
+        arr = np.array([1.0, np.nan])
+        assert_array_equal(np.isclose(arr, arr, equal_nan=True), [True, True])
+
+    def test_masked_arrays(self):
+        # Make sure to test the output type when arguments are interchanged.
+
+        x = np.ma.masked_where([True, True, False], np.arange(3))
+        assert_(type(x) is type(np.isclose(2, x)))
+        assert_(type(x) is type(np.isclose(x, 2)))
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.inf, np.nan])
+        assert_(type(x) is type(np.isclose(np.inf, x)))
+        assert_(type(x) is type(np.isclose(x, np.inf)))
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan])
+        y = np.isclose(np.nan, x, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+        y = np.isclose(x, np.nan, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan])
+        y = np.isclose(x, x, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+
+    def test_scalar_return(self):
+        assert_(np.isscalar(np.isclose(1, 1)))
+
+    def test_no_parameter_modification(self):
+        x = np.array([np.inf, 1])
+        y = np.array([0, np.inf])
+        np.isclose(x, y)
+        assert_array_equal(x, np.array([np.inf, 1]))
+        assert_array_equal(y, np.array([0, np.inf]))
+
+    def test_non_finite_scalar(self):
+        # GH7014, when two scalars are compared the output should also be a
+        # scalar
+        assert_(np.isclose(np.inf, -np.inf) is False)
+        assert_(np.isclose(0, np.inf) is False)
+        assert_(type(np.isclose(0, np.inf)) is bool)
+
+
+class TestStdVar(TestCase):
+    def setUp(self):
+        self.A = np.array([1, -1, 1, -1])
+        self.real_var = 1
+
+    def test_basic(self):
+        assert_almost_equal(np.var(self.A), self.real_var)
+        assert_almost_equal(np.std(self.A)**2, self.real_var)
+
+    def test_scalars(self):
+        assert_equal(np.var(1), 0)
+        assert_equal(np.std(1), 0)
+
+    def test_ddof1(self):
+        assert_almost_equal(np.var(self.A, ddof=1),
+                            self.real_var*len(self.A)/float(len(self.A)-1))
+        assert_almost_equal(np.std(self.A, ddof=1)**2,
+                            self.real_var*len(self.A)/float(len(self.A)-1))
+
+    def test_ddof2(self):
+        assert_almost_equal(np.var(self.A, ddof=2),
+                            self.real_var*len(self.A)/float(len(self.A)-2))
+        assert_almost_equal(np.std(self.A, ddof=2)**2,
+                            self.real_var*len(self.A)/float(len(self.A)-2))
+
+    def test_out_scalar(self):
+        d = np.arange(10)
+        out = np.array(0.)
+        r = np.std(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+        r = np.var(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+        r = np.mean(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+
+
+class TestStdVarComplex(TestCase):
+    def test_basic(self):
+        A = np.array([1, 1.j, -1, -1.j])
+        real_var = 1
+        assert_almost_equal(np.var(A), real_var)
+        assert_almost_equal(np.std(A)**2, real_var)
+
+    def test_scalars(self):
+        assert_equal(np.var(1j), 0)
+        assert_equal(np.std(1j), 0)
+
+
+class TestCreationFuncs(TestCase):
+    # Test ones, zeros, empty and filled
+
+    def setUp(self):
+        self.dtypes = ('b', 'i', 'u', 'f', 'c', 'S', 'a', 'U', 'V')
+        self.orders = {'C': 'c_contiguous', 'F': 'f_contiguous'}
+        self.ndims = 10
+
+    def check_function(self, func, fill_value=None):
+        par = (
+            (0, 1, 2),
+            range(self.ndims),
+            self.orders,
+            self.dtypes,
+            2**np.arange(9)
+        )
+        fill_kwarg = {}
+        if fill_value is not None:
+            fill_kwarg = {'fill_value': fill_value}
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', DeprecationWarning)
+            for size, ndims, order, type, bytes in itertools.product(*par):
+                shape = ndims * [size]
+                try:
+                    dtype = np.dtype('{0}{1}'.format(type, bytes))
+                except TypeError:  # dtype combination does not exist
+                    continue
+                else:
+                    # do not fill void type
+                    if fill_value is not None and type in 'V':
+                        continue
+
+                    arr = func(shape, order=order, dtype=dtype,
+                               **fill_kwarg)
+
+                    assert_(arr.dtype == dtype)
+                    assert_(getattr(arr.flags, self.orders[order]))
+
+                    if fill_value is not None:
+                        if dtype.str.startswith('|S'):
+                            val = str(fill_value)
+                        else:
+                            val = fill_value
+                        assert_equal(arr, dtype.type(val))
+
+    def test_zeros(self):
+        self.check_function(np.zeros)
+
+    def test_ones(self):
+        self.check_function(np.zeros)
+
+    def test_empty(self):
+        self.check_function(np.empty)
+
+    def test_filled(self):
+        self.check_function(np.full, 0)
+        self.check_function(np.full, 1)
+
+    def test_for_reference_leak(self):
+        # Make sure we have an object for reference
+        dim = 1
+        beg = sys.getrefcount(dim)
+        np.zeros([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.ones([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.empty([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.full([dim]*10, 0)
+        assert_(sys.getrefcount(dim) == beg)
+
+
+class TestLikeFuncs(TestCase):
+    '''Test ones_like, zeros_like, empty_like and full_like'''
+
+    def setUp(self):
+        self.data = [
+                # Array scalars
+                (np.array(3.), None),
+                (np.array(3), 'f8'),
+                # 1D arrays
+                (np.arange(6, dtype='f4'), None),
+                (np.arange(6), 'c16'),
+                # 2D C-layout arrays
+                (np.arange(6).reshape(2, 3), None),
+                (np.arange(6).reshape(3, 2), 'i1'),
+                # 2D F-layout arrays
+                (np.arange(6).reshape((2, 3), order='F'), None),
+                (np.arange(6).reshape((3, 2), order='F'), 'i1'),
+                # 3D C-layout arrays
+                (np.arange(24).reshape(2, 3, 4), None),
+                (np.arange(24).reshape(4, 3, 2), 'f4'),
+                # 3D F-layout arrays
+                (np.arange(24).reshape((2, 3, 4), order='F'), None),
+                (np.arange(24).reshape((4, 3, 2), order='F'), 'f4'),
+                # 3D non-C/F-layout arrays
+                (np.arange(24).reshape(2, 3, 4).swapaxes(0, 1), None),
+                (np.arange(24).reshape(4, 3, 2).swapaxes(0, 1), '?'),
+                     ]
+
+    def compare_array_value(self, dz, value, fill_value):
+        if value is not None:
+            if fill_value:
+                try:
+                    z = dz.dtype.type(value)
+                except OverflowError:
+                    pass
+                else:
+                    assert_(np.all(dz == z))
+            else:
+                assert_(np.all(dz == value))
+
+    def check_like_function(self, like_function, value, fill_value=False):
+        if fill_value:
+            fill_kwarg = {'fill_value': value}
+        else:
+            fill_kwarg = {}
+        for d, dtype in self.data:
+            # default (K) order, dtype
+            dz = like_function(d, dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_equal(np.array(dz.strides)*d.dtype.itemsize,
+                         np.array(d.strides)*dz.dtype.itemsize)
+            assert_equal(d.flags.c_contiguous, dz.flags.c_contiguous)
+            assert_equal(d.flags.f_contiguous, dz.flags.f_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # C order, default dtype
+            dz = like_function(d, order='C', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_(dz.flags.c_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # F order, default dtype
+            dz = like_function(d, order='F', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_(dz.flags.f_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # A order
+            dz = like_function(d, order='A', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            if d.flags.f_contiguous:
+                assert_(dz.flags.f_contiguous)
+            else:
+                assert_(dz.flags.c_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+        # Test the 'subok' parameter
+        a = np.matrix([[1, 2], [3, 4]])
+
+        b = like_function(a, **fill_kwarg)
+        assert_(type(b) is np.matrix)
+
+        b = like_function(a, subok=False, **fill_kwarg)
+        assert_(type(b) is not np.matrix)
+
+    def test_ones_like(self):
+        self.check_like_function(np.ones_like, 1)
+
+    def test_zeros_like(self):
+        self.check_like_function(np.zeros_like, 0)
+
+    def test_empty_like(self):
+        self.check_like_function(np.empty_like, None)
+
+    def test_filled_like(self):
+        self.check_like_function(np.full_like, 0, True)
+        self.check_like_function(np.full_like, 1, True)
+        self.check_like_function(np.full_like, 1000, True)
+        self.check_like_function(np.full_like, 123.456, True)
+        self.check_like_function(np.full_like, np.inf, True)
+
+
+class TestCorrelate(TestCase):
+    def _setup(self, dt):
+        self.x = np.array([1, 2, 3, 4, 5], dtype=dt)
+        self.xs = np.arange(1, 20)[::3]
+        self.y = np.array([-1, -2, -3], dtype=dt)
+        self.z1 = np.array([ -3.,  -8., -14., -20., -26., -14.,  -5.], dtype=dt)
+        self.z1_4 = np.array([-2., -5., -8., -11., -14., -5.], dtype=dt)
+        self.z1r = np.array([-15., -22., -22., -16., -10.,  -4.,  -1.], dtype=dt)
+        self.z2 = np.array([-5., -14., -26., -20., -14., -8.,  -3.], dtype=dt)
+        self.z2r = np.array([-1., -4., -10., -16., -22., -22., -15.], dtype=dt)
+        self.zs = np.array([-3., -14., -30., -48., -66., -84.,
+                           -102., -54., -19.], dtype=dt)
+
+    def test_float(self):
+        self._setup(np.float)
+        z = np.correlate(self.x, self.y, 'full')
+        assert_array_almost_equal(z, self.z1)
+        z = np.correlate(self.x, self.y[:-1], 'full')
+        assert_array_almost_equal(z, self.z1_4)
+        z = np.correlate(self.y, self.x, 'full')
+        assert_array_almost_equal(z, self.z2)
+        z = np.correlate(self.x[::-1], self.y, 'full')
+        assert_array_almost_equal(z, self.z1r)
+        z = np.correlate(self.y, self.x[::-1], 'full')
+        assert_array_almost_equal(z, self.z2r)
+        z = np.correlate(self.xs, self.y, 'full')
+        assert_array_almost_equal(z, self.zs)
+
+    def test_object(self):
+        self._setup(Decimal)
+        z = np.correlate(self.x, self.y, 'full')
+        assert_array_almost_equal(z, self.z1)
+        z = np.correlate(self.y, self.x, 'full')
+        assert_array_almost_equal(z, self.z2)
+
+    def test_no_overwrite(self):
+        d = np.ones(100)
+        k = np.ones(3)
+        np.correlate(d, k)
+        assert_array_equal(d, np.ones(100))
+        assert_array_equal(k, np.ones(3))
+
+    def test_complex(self):
+        x = np.array([1, 2, 3, 4+1j], dtype=np.complex)
+        y = np.array([-1, -2j, 3+1j], dtype=np.complex)
+        r_z = np.array([3-1j, 6, 8+1j, 11+5j, -5+8j, -4-1j], dtype=np.complex)
+        r_z = r_z[::-1].conjugate()
+        z = np.correlate(y, x, mode='full')
+        assert_array_almost_equal(z, r_z)
+
+
+class TestConvolve(TestCase):
+    def test_object(self):
+        d = [1.] * 100
+        k = [1.] * 3
+        assert_array_almost_equal(np.convolve(d, k)[2:-2], np.full(98, 3))
+
+    def test_no_overwrite(self):
+        d = np.ones(100)
+        k = np.ones(3)
+        np.convolve(d, k)
+        assert_array_equal(d, np.ones(100))
+        assert_array_equal(k, np.ones(3))
+
+
+class TestArgwhere(object):
+    def test_2D(self):
+        x = np.arange(6).reshape((2, 3))
+        assert_array_equal(np.argwhere(x > 1),
+                           [[0, 2],
+                            [1, 0],
+                            [1, 1],
+                            [1, 2]])
+
+    def test_list(self):
+        assert_equal(np.argwhere([4, 0, 2, 1, 3]), [[0], [2], [3], [4]])
+
+
+class TestStringFunction(object):
+
+    def test_set_string_function(self):
+        a = np.array([1])
+        np.set_string_function(lambda x: "FOO", repr=True)
+        assert_equal(repr(a), "FOO")
+        np.set_string_function(None, repr=True)
+        assert_equal(repr(a), "array([1])")
+
+        np.set_string_function(lambda x: "FOO", repr=False)
+        assert_equal(str(a), "FOO")
+        np.set_string_function(None, repr=False)
+        assert_equal(str(a), "[1]")
+
+
+class TestRoll(TestCase):
+    def test_roll1d(self):
+        x = np.arange(10)
+        xr = np.roll(x, 2)
+        assert_equal(xr, np.array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7]))
+
+    def test_roll2d(self):
+        x2 = np.reshape(np.arange(10), (2, 5))
+        x2r = np.roll(x2, 1)
+        assert_equal(x2r, np.array([[9, 0, 1, 2, 3], [4, 5, 6, 7, 8]]))
+
+        x2r = np.roll(x2, 1, axis=0)
+        assert_equal(x2r, np.array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]]))
+
+        x2r = np.roll(x2, 1, axis=1)
+        assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]]))
+
+    def test_roll_empty(self):
+        x = np.array([])
+        assert_equal(np.roll(x, 1), np.array([]))
+
+
+class TestRollaxis(TestCase):
+
+    # expected shape indexed by (axis, start) for array of
+    # shape (1, 2, 3, 4)
+    tgtshape = {(0, 0): (1, 2, 3, 4), (0, 1): (1, 2, 3, 4),
+                (0, 2): (2, 1, 3, 4), (0, 3): (2, 3, 1, 4),
+                (0, 4): (2, 3, 4, 1),
+                (1, 0): (2, 1, 3, 4), (1, 1): (1, 2, 3, 4),
+                (1, 2): (1, 2, 3, 4), (1, 3): (1, 3, 2, 4),
+                (1, 4): (1, 3, 4, 2),
+                (2, 0): (3, 1, 2, 4), (2, 1): (1, 3, 2, 4),
+                (2, 2): (1, 2, 3, 4), (2, 3): (1, 2, 3, 4),
+                (2, 4): (1, 2, 4, 3),
+                (3, 0): (4, 1, 2, 3), (3, 1): (1, 4, 2, 3),
+                (3, 2): (1, 2, 4, 3), (3, 3): (1, 2, 3, 4),
+                (3, 4): (1, 2, 3, 4)}
+
+    def test_exceptions(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4)
+        assert_raises(ValueError, np.rollaxis, a, -5, 0)
+        assert_raises(ValueError, np.rollaxis, a, 0, -5)
+        assert_raises(ValueError, np.rollaxis, a, 4, 0)
+        assert_raises(ValueError, np.rollaxis, a, 0, 5)
+
+    def test_results(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        aind = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        for (i, j) in self.tgtshape:
+            # positive axis, positive start
+            res = np.rollaxis(a, axis=i, start=j)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(i, j)], str((i,j)))
+            assert_(not res.flags['OWNDATA'])
+
+            # negative axis, positive start
+            ip = i + 1
+            res = np.rollaxis(a, axis=-ip, start=j)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(4 - ip, j)])
+            assert_(not res.flags['OWNDATA'])
+
+            # positive axis, negative start
+            jp = j + 1 if j < 4 else j
+            res = np.rollaxis(a, axis=i, start=-jp)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(i, 4 - jp)])
+            assert_(not res.flags['OWNDATA'])
+
+            # negative axis, negative start
+            ip = i + 1
+            jp = j + 1 if j < 4 else j
+            res = np.rollaxis(a, axis=-ip, start=-jp)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(4 - ip, 4 - jp)])
+            assert_(not res.flags['OWNDATA'])
+
+
+class TestMoveaxis(TestCase):
+    def test_move_to_end(self):
+        x = np.random.randn(5, 6, 7)
+        for source, expected in [(0, (6, 7, 5)),
+                                 (1, (5, 7, 6)),
+                                 (2, (5, 6, 7)),
+                                 (-1, (5, 6, 7))]:
+            actual = np.moveaxis(x, source, -1).shape
+            assert_(actual, expected)
+
+    def test_move_new_position(self):
+        x = np.random.randn(1, 2, 3, 4)
+        for source, destination, expected in [
+                (0, 1, (2, 1, 3, 4)),
+                (1, 2, (1, 3, 2, 4)),
+                (1, -1, (1, 3, 4, 2)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, expected)
+
+    def test_preserve_order(self):
+        x = np.zeros((1, 2, 3, 4))
+        for source, destination in [
+                (0, 0),
+                (3, -1),
+                (-1, 3),
+                ([0, -1], [0, -1]),
+                ([2, 0], [2, 0]),
+                (range(4), range(4)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, (1, 2, 3, 4))
+
+    def test_move_multiples(self):
+        x = np.zeros((0, 1, 2, 3))
+        for source, destination, expected in [
+                ([0, 1], [2, 3], (2, 3, 0, 1)),
+                ([2, 3], [0, 1], (2, 3, 0, 1)),
+                ([0, 1, 2], [2, 3, 0], (2, 3, 0, 1)),
+                ([3, 0], [1, 0], (0, 3, 1, 2)),
+                ([0, 3], [0, 1], (0, 3, 1, 2)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, expected)
+
+    def test_errors(self):
+        x = np.random.randn(1, 2, 3)
+        assert_raises_regex(ValueError, 'invalid axis .* `source`',
+                            np.moveaxis, x, 3, 0)
+        assert_raises_regex(ValueError, 'invalid axis .* `source`',
+                            np.moveaxis, x, -4, 0)
+        assert_raises_regex(ValueError, 'invalid axis .* `destination`',
+                            np.moveaxis, x, 0, 5)
+        assert_raises_regex(ValueError, 'repeated axis in `source`',
+                            np.moveaxis, x, [0, 0], [0, 1])
+        assert_raises_regex(ValueError, 'repeated axis in `destination`',
+                            np.moveaxis, x, [0, 1], [1, 1])
+        assert_raises_regex(ValueError, 'must have the same number',
+                            np.moveaxis, x, 0, [0, 1])
+        assert_raises_regex(ValueError, 'must have the same number',
+                            np.moveaxis, x, [0, 1], [0])
+
+    def test_array_likes(self):
+        x = np.ma.zeros((1, 2, 3))
+        result = np.moveaxis(x, 0, 0)
+        assert_(x.shape, result.shape)
+        assert_(isinstance(result, np.ma.MaskedArray))
+
+        x = [1, 2, 3]
+        result = np.moveaxis(x, 0, 0)
+        assert_(x, list(result))
+        assert_(isinstance(result, np.ndarray))
+
+
+class TestCross(TestCase):
+    def test_2x2(self):
+        u = [1, 2]
+        v = [3, 4]
+        z = -2
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_2x3(self):
+        u = [1, 2]
+        v = [3, 4, 5]
+        z = np.array([10, -5, -2])
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_3x3(self):
+        u = [1, 2, 3]
+        v = [4, 5, 6]
+        z = np.array([-3, 6, -3])
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_broadcasting(self):
+        # Ticket #2624 (Trac #2032)
+        u = np.tile([1, 2], (11, 1))
+        v = np.tile([3, 4], (11, 1))
+        z = -2
+        assert_equal(np.cross(u, v), z)
+        assert_equal(np.cross(v, u), -z)
+        assert_equal(np.cross(u, u), 0)
+
+        u = np.tile([1, 2], (11, 1)).T
+        v = np.tile([3, 4, 5], (11, 1))
+        z = np.tile([10, -5, -2], (11, 1))
+        assert_equal(np.cross(u, v, axisa=0), z)
+        assert_equal(np.cross(v, u.T), -z)
+        assert_equal(np.cross(v, v), 0)
+
+        u = np.tile([1, 2, 3], (11, 1)).T
+        v = np.tile([3, 4], (11, 1)).T
+        z = np.tile([-12, 9, -2], (11, 1))
+        assert_equal(np.cross(u, v, axisa=0, axisb=0), z)
+        assert_equal(np.cross(v.T, u.T), -z)
+        assert_equal(np.cross(u.T, u.T), 0)
+
+        u = np.tile([1, 2, 3], (5, 1))
+        v = np.tile([4, 5, 6], (5, 1)).T
+        z = np.tile([-3, 6, -3], (5, 1))
+        assert_equal(np.cross(u, v, axisb=0), z)
+        assert_equal(np.cross(v.T, u), -z)
+        assert_equal(np.cross(u, u), 0)
+
+    def test_broadcasting_shapes(self):
+        u = np.ones((2, 1, 3))
+        v = np.ones((5, 3))
+        assert_equal(np.cross(u, v).shape, (2, 5, 3))
+        u = np.ones((10, 3, 5))
+        v = np.ones((2, 5))
+        assert_equal(np.cross(u, v, axisa=1, axisb=0).shape, (10, 5, 3))
+        assert_raises(ValueError, np.cross, u, v, axisa=1, axisb=2)
+        assert_raises(ValueError, np.cross, u, v, axisa=3, axisb=0)
+        u = np.ones((10, 3, 5, 7))
+        v = np.ones((5, 7, 2))
+        assert_equal(np.cross(u, v, axisa=1, axisc=2).shape, (10, 5, 3, 7))
+        assert_raises(ValueError, np.cross, u, v, axisa=-5, axisb=2)
+        assert_raises(ValueError, np.cross, u, v, axisa=1, axisb=-4)
+        # gh-5885
+        u = np.ones((3, 4, 2))
+        for axisc in range(-2, 2):
+            assert_equal(np.cross(u, u, axisc=axisc).shape, (3, 4))
+
+
+def test_outer_out_param():
+    arr1 = np.ones((5,))
+    arr2 = np.ones((2,))
+    arr3 = np.linspace(-2, 2, 5)
+    out1 = np.ndarray(shape=(5,5))
+    out2 = np.ndarray(shape=(2, 5))
+    res1 = np.outer(arr1, arr3, out1)
+    assert_equal(res1, out1)
+    assert_equal(np.outer(arr2, arr3, out2), out2)
+
+
+class TestRequire(object):
+    flag_names = ['C', 'C_CONTIGUOUS', 'CONTIGUOUS',
+                  'F', 'F_CONTIGUOUS', 'FORTRAN',
+                  'A', 'ALIGNED',
+                  'W', 'WRITEABLE',
+                  'O', 'OWNDATA']
+
+    def generate_all_false(self, dtype):
+        arr = np.zeros((2, 2), [('junk', 'i1'), ('a', dtype)])
+        arr.setflags(write=False)
+        a = arr['a']
+        assert_(not a.flags['C'])
+        assert_(not a.flags['F'])
+        assert_(not a.flags['O'])
+        assert_(not a.flags['W'])
+        assert_(not a.flags['A'])
+        return a
+
+    def set_and_check_flag(self, flag, dtype, arr):
+        if dtype is None:
+            dtype = arr.dtype
+        b = np.require(arr, dtype, [flag])
+        assert_(b.flags[flag])
+        assert_(b.dtype == dtype)
+
+        # a further call to np.require ought to return the same array
+        # unless OWNDATA is specified.
+        c = np.require(b, None, [flag])
+        if flag[0] != 'O':
+            assert_(c is b)
+        else:
+            assert_(c.flags[flag])
+
+    def test_require_each(self):
+
+        id = ['f8', 'i4']
+        fd = [None, 'f8', 'c16']
+        for idtype, fdtype, flag in itertools.product(id, fd, self.flag_names):
+            a = self.generate_all_false(idtype)
+            yield self.set_and_check_flag, flag, fdtype,  a
+
+    def test_unknown_requirement(self):
+        a = self.generate_all_false('f8')
+        assert_raises(KeyError, np.require, a, None, 'Q')
+
+    def test_non_array_input(self):
+        a = np.require([1, 2, 3, 4], 'i4', ['C', 'A', 'O'])
+        assert_(a.flags['O'])
+        assert_(a.flags['C'])
+        assert_(a.flags['A'])
+        assert_(a.dtype == 'i4')
+        assert_equal(a, [1, 2, 3, 4])
+
+    def test_C_and_F_simul(self):
+        a = self.generate_all_false('f8')
+        assert_raises(ValueError, np.require, a, None, ['C', 'F'])
+
+    def test_ensure_array(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = ArraySubclass((2, 2))
+        b = np.require(a, None, ['E'])
+        assert_(type(b) is np.ndarray)
+
+    def test_preserve_subtype(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        for flag in self.flag_names:
+            a = ArraySubclass((2, 2))
+            yield self.set_and_check_flag, flag, None, a
+
+
+class TestBroadcast(TestCase):
+    def test_broadcast_in_args(self):
+        # gh-5881
+        arrs = [np.empty((6, 7)), np.empty((5, 6, 1)), np.empty((7,)),
+                np.empty((5, 1, 7))]
+        mits = [np.broadcast(*arrs),
+                np.broadcast(np.broadcast(*arrs[:2]), np.broadcast(*arrs[2:])),
+                np.broadcast(arrs[0], np.broadcast(*arrs[1:-1]), arrs[-1])]
+        for mit in mits:
+            assert_equal(mit.shape, (5, 6, 7))
+            assert_equal(mit.nd, 3)
+            assert_equal(mit.numiter, 4)
+            for a, ia in zip(arrs, mit.iters):
+                assert_(a is ia.base)
+
+    def test_broadcast_single_arg(self):
+        # gh-6899
+        arrs = [np.empty((5, 6, 7))]
+        mit = np.broadcast(*arrs)
+        assert_equal(mit.shape, (5, 6, 7))
+        assert_equal(mit.nd, 3)
+        assert_equal(mit.numiter, 1)
+        assert_(arrs[0] is mit.iters[0].base)
+
+    def test_number_of_arguments(self):
+        arr = np.empty((5,))
+        for j in range(35):
+            arrs = [arr] * j
+            if j < 1 or j > 32:
+                assert_raises(ValueError, np.broadcast, *arrs)
+            else:
+                mit = np.broadcast(*arrs)
+                assert_equal(mit.numiter, j)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
new file mode 100644
index 0000000000..a7bbe01922
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
@@ -0,0 +1,382 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import asbytes, asunicode
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal
+)
+
+# This is the structure of the table used for plain objects:
+#
+# +-+-+-+
+# |x|y|z|
+# +-+-+-+
+
+# Structure of a plain array description:
+Pdescr = [
+    ('x', 'i4', (2,)),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+# A plain list of tuples with values for testing:
+PbufferT = [
+    # x     y                  z
+    ([3, 2], [[6., 4.], [6., 4.]], 8),
+    ([4, 3], [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+# This is the structure of the table used for nested objects (DON'T PANIC!):
+#
+# +-+---------------------------------+-----+----------+-+-+
+# |x|Info                             |color|info      |y|z|
+# | +-----+--+----------------+----+--+     +----+-----+ | |
+# | |value|y2|Info2           |name|z2|     |Name|Value| | |
+# | |     |  +----+-----+--+--+    |  |     |    |     | | |
+# | |     |  |name|value|y3|z3|    |  |     |    |     | | |
+# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+
+#
+
+# The corresponding nested array description:
+Ndescr = [
+    ('x', 'i4', (2,)),
+    ('Info', [
+        ('value', 'c16'),
+        ('y2', 'f8'),
+        ('Info2', [
+            ('name', 'S2'),
+            ('value', 'c16', (2,)),
+            ('y3', 'f8', (2,)),
+            ('z3', 'u4', (2,))]),
+        ('name', 'S2'),
+        ('z2', 'b1')]),
+    ('color', 'S2'),
+    ('info', [
+        ('Name', 'U8'),
+        ('Value', 'c16')]),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+NbufferT = [
+    # x     Info                                                color info        y                  z
+    #       value y2 Info2                            name z2         Name Value
+    #                name   value    y3       z3
+    ([3, 2], (6j, 6., (asbytes('nn'), [6j, 4j], [6., 4.], [1, 2]), asbytes('NN'), True), asbytes('cc'), (asunicode('NN'), 6j), [[6., 4.], [6., 4.]], 8),
+    ([4, 3], (7j, 7., (asbytes('oo'), [7j, 5j], [7., 5.], [2, 1]), asbytes('OO'), False), asbytes('dd'), (asunicode('OO'), 7j), [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+byteorder = {'little':'<', 'big':'>'}[sys.byteorder]
+
+def normalize_descr(descr):
+    "Normalize a description adding the platform byteorder."
+
+    out = []
+    for item in descr:
+        dtype = item[1]
+        if isinstance(dtype, str):
+            if dtype[0] not in ['|', '<', '>']:
+                onebyte = dtype[1:] == "1"
+                if onebyte or dtype[0] in ['S', 'V', 'b']:
+                    dtype = "|" + dtype
+                else:
+                    dtype = byteorder + dtype
+            if len(item) > 2 and np.prod(item[2]) > 1:
+                nitem = (item[0], dtype, item[2])
+            else:
+                nitem = (item[0], dtype)
+            out.append(nitem)
+        elif isinstance(item[1], list):
+            l = []
+            for j in normalize_descr(item[1]):
+                l.append(j)
+            out.append((item[0], l))
+        else:
+            raise ValueError("Expected a str or list and got %s" %
+                             (type(item)))
+    return out
+
+
+############################################################
+#    Creation tests
+############################################################
+
+class create_zeros(object):
+    """Check the creation of heterogeneous arrays zero-valued"""
+
+    def test_zeros0D(self):
+        """Check creation of 0-dimensional objects"""
+        h = np.zeros((), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype.fields['x'][0].name[:4] == 'void')
+        self.assertTrue(h.dtype.fields['x'][0].char == 'V')
+        self.assertTrue(h.dtype.fields['x'][0].type == np.void)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((), dtype='u1'))
+
+    def test_zerosSD(self):
+        """Check creation of single-dimensional objects"""
+        h = np.zeros((2,), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype['y'].name[:4] == 'void')
+        self.assertTrue(h.dtype['y'].char == 'V')
+        self.assertTrue(h.dtype['y'].type == np.void)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((2,), dtype='u1'))
+
+    def test_zerosMD(self):
+        """Check creation of multi-dimensional objects"""
+        h = np.zeros((2, 3), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype['z'].name == 'uint8')
+        self.assertTrue(h.dtype['z'].char == 'B')
+        self.assertTrue(h.dtype['z'].type == np.uint8)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((2, 3), dtype='u1'))
+
+
+class test_create_zeros_plain(create_zeros, TestCase):
+    """Check the creation of heterogeneous arrays zero-valued (plain)"""
+    _descr = Pdescr
+
+class test_create_zeros_nested(create_zeros, TestCase):
+    """Check the creation of heterogeneous arrays zero-valued (nested)"""
+    _descr = Ndescr
+
+
+class create_values(object):
+    """Check the creation of heterogeneous arrays with values"""
+
+    def test_tuple(self):
+        """Check creation from tuples"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (2,))
+        else:
+            self.assertTrue(h.shape == ())
+
+    def test_list_of_tuple(self):
+        """Check creation from list of tuples"""
+        h = np.array([self._buffer], dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (1, 2))
+        else:
+            self.assertTrue(h.shape == (1,))
+
+    def test_list_of_list_of_tuple(self):
+        """Check creation from list of list of tuples"""
+        h = np.array([[self._buffer]], dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (1, 1, 2))
+        else:
+            self.assertTrue(h.shape == (1, 1))
+
+
+class test_create_values_plain_single(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (plain, single row)"""
+    _descr = Pdescr
+    multiple_rows = 0
+    _buffer = PbufferT[0]
+
+class test_create_values_plain_multiple(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (plain, multiple rows)"""
+    _descr = Pdescr
+    multiple_rows = 1
+    _buffer = PbufferT
+
+class test_create_values_nested_single(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (nested, single row)"""
+    _descr = Ndescr
+    multiple_rows = 0
+    _buffer = NbufferT[0]
+
+class test_create_values_nested_multiple(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (nested, multiple rows)"""
+    _descr = Ndescr
+    multiple_rows = 1
+    _buffer = NbufferT
+
+
+############################################################
+#    Reading tests
+############################################################
+
+class read_values_plain(object):
+    """Check the reading of values in heterogeneous arrays (plain)"""
+
+    def test_access_fields(self):
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            self.assertTrue(h.shape == ())
+            assert_equal(h['x'], np.array(self._buffer[0], dtype='i4'))
+            assert_equal(h['y'], np.array(self._buffer[1], dtype='f8'))
+            assert_equal(h['z'], np.array(self._buffer[2], dtype='u1'))
+        else:
+            self.assertTrue(len(h) == 2)
+            assert_equal(h['x'], np.array([self._buffer[0][0],
+                                             self._buffer[1][0]], dtype='i4'))
+            assert_equal(h['y'], np.array([self._buffer[0][1],
+                                             self._buffer[1][1]], dtype='f8'))
+            assert_equal(h['z'], np.array([self._buffer[0][2],
+                                             self._buffer[1][2]], dtype='u1'))
+
+
+class test_read_values_plain_single(read_values_plain, TestCase):
+    """Check the creation of heterogeneous arrays (plain, single row)"""
+    _descr = Pdescr
+    multiple_rows = 0
+    _buffer = PbufferT[0]
+
+class test_read_values_plain_multiple(read_values_plain, TestCase):
+    """Check the values of heterogeneous arrays (plain, multiple rows)"""
+    _descr = Pdescr
+    multiple_rows = 1
+    _buffer = PbufferT
+
+class read_values_nested(object):
+    """Check the reading of values in heterogeneous arrays (nested)"""
+
+    def test_access_top_fields(self):
+        """Check reading the top fields of a nested array"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            self.assertTrue(h.shape == ())
+            assert_equal(h['x'], np.array(self._buffer[0], dtype='i4'))
+            assert_equal(h['y'], np.array(self._buffer[4], dtype='f8'))
+            assert_equal(h['z'], np.array(self._buffer[5], dtype='u1'))
+        else:
+            self.assertTrue(len(h) == 2)
+            assert_equal(h['x'], np.array([self._buffer[0][0],
+                                           self._buffer[1][0]], dtype='i4'))
+            assert_equal(h['y'], np.array([self._buffer[0][4],
+                                           self._buffer[1][4]], dtype='f8'))
+            assert_equal(h['z'], np.array([self._buffer[0][5],
+                                           self._buffer[1][5]], dtype='u1'))
+
+    def test_nested1_acessors(self):
+        """Check reading the nested fields of a nested array (1st level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            assert_equal(h['Info']['value'],
+                         np.array(self._buffer[1][0], dtype='c16'))
+            assert_equal(h['Info']['y2'],
+                         np.array(self._buffer[1][1], dtype='f8'))
+            assert_equal(h['info']['Name'],
+                         np.array(self._buffer[3][0], dtype='U2'))
+            assert_equal(h['info']['Value'],
+                         np.array(self._buffer[3][1], dtype='c16'))
+        else:
+            assert_equal(h['Info']['value'],
+                         np.array([self._buffer[0][1][0],
+                                self._buffer[1][1][0]],
+                                dtype='c16'))
+            assert_equal(h['Info']['y2'],
+                         np.array([self._buffer[0][1][1],
+                                self._buffer[1][1][1]],
+                                dtype='f8'))
+            assert_equal(h['info']['Name'],
+                         np.array([self._buffer[0][3][0],
+                                self._buffer[1][3][0]],
+                               dtype='U2'))
+            assert_equal(h['info']['Value'],
+                         np.array([self._buffer[0][3][1],
+                                self._buffer[1][3][1]],
+                               dtype='c16'))
+
+    def test_nested2_acessors(self):
+        """Check reading the nested fields of a nested array (2nd level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            assert_equal(h['Info']['Info2']['value'],
+                         np.array(self._buffer[1][2][1], dtype='c16'))
+            assert_equal(h['Info']['Info2']['z3'],
+                         np.array(self._buffer[1][2][3], dtype='u4'))
+        else:
+            assert_equal(h['Info']['Info2']['value'],
+                         np.array([self._buffer[0][1][2][1],
+                                self._buffer[1][1][2][1]],
+                               dtype='c16'))
+            assert_equal(h['Info']['Info2']['z3'],
+                         np.array([self._buffer[0][1][2][3],
+                                self._buffer[1][1][2][3]],
+                               dtype='u4'))
+
+    def test_nested1_descriptor(self):
+        """Check access nested descriptors of a nested array (1st level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(h.dtype['Info']['value'].name == 'complex128')
+        self.assertTrue(h.dtype['Info']['y2'].name == 'float64')
+        if sys.version_info[0] >= 3:
+            self.assertTrue(h.dtype['info']['Name'].name == 'str256')
+        else:
+            self.assertTrue(h.dtype['info']['Name'].name == 'unicode256')
+        self.assertTrue(h.dtype['info']['Value'].name == 'complex128')
+
+    def test_nested2_descriptor(self):
+        """Check access nested descriptors of a nested array (2nd level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(h.dtype['Info']['Info2']['value'].name == 'void256')
+        self.assertTrue(h.dtype['Info']['Info2']['z3'].name == 'void64')
+
+
+class test_read_values_nested_single(read_values_nested, TestCase):
+    """Check the values of heterogeneous arrays (nested, single row)"""
+    _descr = Ndescr
+    multiple_rows = False
+    _buffer = NbufferT[0]
+
+class test_read_values_nested_multiple(read_values_nested, TestCase):
+    """Check the values of heterogeneous arrays (nested, multiple rows)"""
+    _descr = Ndescr
+    multiple_rows = True
+    _buffer = NbufferT
+
+class TestEmptyField(TestCase):
+    def test_assign(self):
+        a = np.arange(10, dtype=np.float32)
+        a.dtype = [("int",   "<0i4"), ("float", "<2f4")]
+        assert_(a['int'].shape == (5, 0))
+        assert_(a['float'].shape == (5, 2))
+
+class TestCommonType(TestCase):
+    def test_scalar_loses1(self):
+        res = np.find_common_type(['f4', 'f4', 'i2'], ['f8'])
+        assert_(res == 'f4')
+
+    def test_scalar_loses2(self):
+        res = np.find_common_type(['f4', 'f4'], ['i8'])
+        assert_(res == 'f4')
+
+    def test_scalar_wins(self):
+        res = np.find_common_type(['f4', 'f4', 'i2'], ['c8'])
+        assert_(res == 'c8')
+
+    def test_scalar_wins2(self):
+        res = np.find_common_type(['u4', 'i4', 'i4'], ['f4'])
+        assert_(res == 'f8')
+
+    def test_scalar_wins3(self):  # doesn't go up to 'f16' on purpose
+        res = np.find_common_type(['u8', 'i8', 'i8'], ['f8'])
+        assert_(res == 'f8')
+
+class TestMultipleFields(TestCase):
+    def setUp(self):
+        self.ary = np.array([(1, 2, 3, 4), (5, 6, 7, 8)], dtype='i4,f4,i2,c8')
+
+    def _bad_call(self):
+        return self.ary['f0', 'f1']
+
+    def test_no_tuple(self):
+        self.assertRaises(IndexError, self._bad_call)
+
+    def test_return(self):
+        res = self.ary[['f0', 'f2']].tolist()
+        assert_(res == [(1, 3), (5, 7)])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_print.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_print.py
new file mode 100644
index 0000000000..6234b641ea
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_print.py
@@ -0,0 +1,248 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import locale
+import nose
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, SkipTest
+)
+
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+_REF = {np.inf: 'inf', -np.inf: '-inf', np.nan: 'nan'}
+
+
+def check_float_type(tp):
+    for x in [0, 1, -1, 1e20]:
+        assert_equal(str(tp(x)), str(float(x)),
+                     err_msg='Failed str formatting for type %s' % tp)
+
+    if tp(1e10).itemsize > 4:
+        assert_equal(str(tp(1e10)), str(float('1e10')),
+                     err_msg='Failed str formatting for type %s' % tp)
+    else:
+        ref = '1e+10'
+        assert_equal(str(tp(1e10)), ref,
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_float_types():
+    """ Check formatting.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_float_type, t
+
+def check_nan_inf_float(tp):
+    for x in [np.inf, -np.inf, np.nan]:
+        assert_equal(str(tp(x)), _REF[x],
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_nan_inf_float():
+    """ Check formatting of nan & inf.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_nan_inf_float, t
+
+def check_complex_type(tp):
+    for x in [0, 1, -1, 1e20]:
+        assert_equal(str(tp(x)), str(complex(x)),
+                     err_msg='Failed str formatting for type %s' % tp)
+        assert_equal(str(tp(x*1j)), str(complex(x*1j)),
+                     err_msg='Failed str formatting for type %s' % tp)
+        assert_equal(str(tp(x + x*1j)), str(complex(x + x*1j)),
+                     err_msg='Failed str formatting for type %s' % tp)
+
+    if tp(1e10).itemsize > 8:
+        assert_equal(str(tp(1e10)), str(complex(1e10)),
+                     err_msg='Failed str formatting for type %s' % tp)
+    else:
+        ref = '(1e+10+0j)'
+        assert_equal(str(tp(1e10)), ref,
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_complex_types():
+    """Check formatting of complex types.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.complex64, np.cdouble, np.clongdouble]:
+        yield check_complex_type, t
+
+def test_complex_inf_nan():
+    """Check inf/nan formatting of complex types."""
+    TESTS = {
+        complex(np.inf, 0): "(inf+0j)",
+        complex(0, np.inf): "inf*j",
+        complex(-np.inf, 0): "(-inf+0j)",
+        complex(0, -np.inf): "-inf*j",
+        complex(np.inf, 1): "(inf+1j)",
+        complex(1, np.inf): "(1+inf*j)",
+        complex(-np.inf, 1): "(-inf+1j)",
+        complex(1, -np.inf): "(1-inf*j)",
+        complex(np.nan, 0): "(nan+0j)",
+        complex(0, np.nan): "nan*j",
+        complex(-np.nan, 0): "(nan+0j)",
+        complex(0, -np.nan): "nan*j",
+        complex(np.nan, 1): "(nan+1j)",
+        complex(1, np.nan): "(1+nan*j)",
+        complex(-np.nan, 1): "(nan+1j)",
+        complex(1, -np.nan): "(1+nan*j)",
+    }
+    for tp in [np.complex64, np.cdouble, np.clongdouble]:
+        for c, s in TESTS.items():
+            yield _check_complex_inf_nan, c, s, tp
+
+def _check_complex_inf_nan(c, s, dtype):
+    assert_equal(str(dtype(c)), s)
+
+# print tests
+def _test_redirected_print(x, tp, ref=None):
+    file = StringIO()
+    file_tp = StringIO()
+    stdout = sys.stdout
+    try:
+        sys.stdout = file_tp
+        print(tp(x))
+        sys.stdout = file
+        if ref:
+            print(ref)
+        else:
+            print(x)
+    finally:
+        sys.stdout = stdout
+
+    assert_equal(file.getvalue(), file_tp.getvalue(),
+                 err_msg='print failed for type%s' % tp)
+
+def check_float_type_print(tp):
+    for x in [0, 1, -1, 1e20]:
+        _test_redirected_print(float(x), tp)
+
+    for x in [np.inf, -np.inf, np.nan]:
+        _test_redirected_print(float(x), tp, _REF[x])
+
+    if tp(1e10).itemsize > 4:
+        _test_redirected_print(float(1e10), tp)
+    else:
+        ref = '1e+10'
+        _test_redirected_print(float(1e10), tp, ref)
+
+def check_complex_type_print(tp):
+    # We do not create complex with inf/nan directly because the feature is
+    # missing in python < 2.6
+    for x in [0, 1, -1, 1e20]:
+        _test_redirected_print(complex(x), tp)
+
+    if tp(1e10).itemsize > 8:
+        _test_redirected_print(complex(1e10), tp)
+    else:
+        ref = '(1e+10+0j)'
+        _test_redirected_print(complex(1e10), tp, ref)
+
+    _test_redirected_print(complex(np.inf, 1), tp, '(inf+1j)')
+    _test_redirected_print(complex(-np.inf, 1), tp, '(-inf+1j)')
+    _test_redirected_print(complex(-np.nan, 1), tp, '(nan+1j)')
+
+def test_float_type_print():
+    """Check formatting when using print """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_float_type_print, t
+
+def test_complex_type_print():
+    """Check formatting when using print """
+    for t in [np.complex64, np.cdouble, np.clongdouble]:
+        yield check_complex_type_print, t
+
+def test_scalar_format():
+    """Test the str.format method with NumPy scalar types"""
+    tests = [('{0}', True, np.bool_),
+            ('{0}', False, np.bool_),
+            ('{0:d}', 130, np.uint8),
+            ('{0:d}', 50000, np.uint16),
+            ('{0:d}', 3000000000, np.uint32),
+            ('{0:d}', 15000000000000000000, np.uint64),
+            ('{0:d}', -120, np.int8),
+            ('{0:d}', -30000, np.int16),
+            ('{0:d}', -2000000000, np.int32),
+            ('{0:d}', -7000000000000000000, np.int64),
+            ('{0:g}', 1.5, np.float16),
+            ('{0:g}', 1.5, np.float32),
+            ('{0:g}', 1.5, np.float64),
+            ('{0:g}', 1.5, np.longdouble)]
+    # Python 2.6 doesn't implement complex.__format__
+    if sys.version_info[:2] > (2, 6):
+        tests += [('{0:g}', 1.5+0.5j, np.complex64),
+                ('{0:g}', 1.5+0.5j, np.complex128),
+                ('{0:g}', 1.5+0.5j, np.clongdouble)]
+
+    for (fmat, val, valtype) in tests:
+        try:
+            assert_equal(fmat.format(val), fmat.format(valtype(val)),
+                    "failed with val %s, type %s" % (val, valtype))
+        except ValueError as e:
+            assert_(False,
+               "format raised exception (fmt='%s', val=%s, type=%s, exc='%s')" %
+                            (fmat, repr(val), repr(valtype), str(e)))
+
+
+# Locale tests: scalar types formatting should be independent of the locale
+def in_foreign_locale(func):
+    """
+    Swap LC_NUMERIC locale to one in which the decimal point is ',' and not '.'
+    If not possible, raise SkipTest
+
+    """
+    if sys.platform == 'win32':
+        locales = ['FRENCH']
+    else:
+        locales = ['fr_FR', 'fr_FR.UTF-8', 'fi_FI', 'fi_FI.UTF-8']
+
+    def wrapper(*args, **kwargs):
+        curloc = locale.getlocale(locale.LC_NUMERIC)
+        try:
+            for loc in locales:
+                try:
+                    locale.setlocale(locale.LC_NUMERIC, loc)
+                    break
+                except locale.Error:
+                    pass
+            else:
+                raise SkipTest("Skipping locale test, because "
+                                "French locale not found")
+            return func(*args, **kwargs)
+        finally:
+            locale.setlocale(locale.LC_NUMERIC, locale=curloc)
+    return nose.tools.make_decorator(func)(wrapper)
+
+@in_foreign_locale
+def test_locale_single():
+    assert_equal(str(np.float32(1.2)), str(float(1.2)))
+
+@in_foreign_locale
+def test_locale_double():
+    assert_equal(str(np.double(1.2)), str(float(1.2)))
+
+@in_foreign_locale
+def test_locale_longdouble():
+    assert_equal(str(np.longdouble(1.2)), str(float(1.2)))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_records.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_records.py
new file mode 100644
index 0000000000..9fbdf51d60
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_records.py
@@ -0,0 +1,337 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import collections
+import pickle
+from os import path
+
+import numpy as np
+from numpy.compat import asbytes
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_raises
+    )
+
+
+class TestFromrecords(TestCase):
+    def test_fromrecords(self):
+        r = np.rec.fromrecords([[456, 'dbe', 1.2], [2, 'de', 1.3]],
+                            names='col1,col2,col3')
+        assert_equal(r[0].item(), (456, 'dbe', 1.2))
+        assert_equal(r['col1'].dtype.kind, 'i')
+        if sys.version_info[0] >= 3:
+            assert_equal(r['col2'].dtype.kind, 'U')
+            assert_equal(r['col2'].dtype.itemsize, 12)
+        else:
+            assert_equal(r['col2'].dtype.kind, 'S')
+            assert_equal(r['col2'].dtype.itemsize, 3)
+        assert_equal(r['col3'].dtype.kind, 'f')
+
+    def test_method_array(self):
+        r = np.rec.array(asbytes('abcdefg') * 100, formats='i2,a3,i4', shape=3, byteorder='big')
+        assert_equal(r[1].item(), (25444, asbytes('efg'), 1633837924))
+
+    def test_method_array2(self):
+        r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'),
+                     (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1')
+        assert_equal(r[1].item(), (2, 22.0, asbytes('b')))
+
+    def test_recarray_slices(self):
+        r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'),
+                     (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1')
+        assert_equal(r[1::2][1].item(), (4, 44.0, asbytes('d')))
+
+    def test_recarray_fromarrays(self):
+        x1 = np.array([1, 2, 3, 4])
+        x2 = np.array(['a', 'dd', 'xyz', '12'])
+        x3 = np.array([1.1, 2, 3, 4])
+        r = np.rec.fromarrays([x1, x2, x3], names='a,b,c')
+        assert_equal(r[1].item(), (2, 'dd', 2.0))
+        x1[1] = 34
+        assert_equal(r.a, np.array([1, 2, 3, 4]))
+
+    def test_recarray_fromfile(self):
+        data_dir = path.join(path.dirname(__file__), 'data')
+        filename = path.join(data_dir, 'recarray_from_file.fits')
+        fd = open(filename, 'rb')
+        fd.seek(2880 * 2)
+        r1 = np.rec.fromfile(fd, formats='f8,i4,a5', shape=3, byteorder='big')
+        fd.seek(2880 * 2)
+        r2 = np.rec.array(fd, formats='f8,i4,a5', shape=3, byteorder='big')
+        fd.close()
+        assert_equal(r1, r2)
+
+    def test_recarray_from_obj(self):
+        count = 10
+        a = np.zeros(count, dtype='O')
+        b = np.zeros(count, dtype='f8')
+        c = np.zeros(count, dtype='f8')
+        for i in range(len(a)):
+            a[i] = list(range(1, 10))
+
+        mine = np.rec.fromarrays([a, b, c], names='date,data1,data2')
+        for i in range(len(a)):
+            assert_((mine.date[i] == list(range(1, 10))))
+            assert_((mine.data1[i] == 0.0))
+            assert_((mine.data2[i] == 0.0))
+
+    def test_recarray_from_repr(self):
+        a = np.array([(1,'ABC'), (2, "DEF")],
+                     dtype=[('foo', int), ('bar', 'S4')])
+        recordarr = np.rec.array(a)
+        recarr = a.view(np.recarray)
+        recordview = a.view(np.dtype((np.record, a.dtype)))
+
+        recordarr_r = eval("numpy." + repr(recordarr), {'numpy': np})
+        recarr_r = eval("numpy." + repr(recarr), {'numpy': np})
+        recordview_r = eval("numpy." + repr(recordview), {'numpy': np})
+
+        assert_equal(type(recordarr_r), np.recarray)
+        assert_equal(recordarr_r.dtype.type, np.record)
+        assert_equal(recordarr, recordarr_r)
+
+        assert_equal(type(recarr_r), np.recarray)
+        assert_equal(recarr_r.dtype.type, np.record)
+        assert_equal(recarr, recarr_r)
+
+        assert_equal(type(recordview_r), np.ndarray)
+        assert_equal(recordview.dtype.type, np.record)
+        assert_equal(recordview, recordview_r)
+
+    def test_recarray_views(self):
+        a = np.array([(1,'ABC'), (2, "DEF")],
+                     dtype=[('foo', int), ('bar', 'S4')])
+        b = np.array([1,2,3,4,5], dtype=np.int64)
+
+        #check that np.rec.array gives right dtypes
+        assert_equal(np.rec.array(a).dtype.type, np.record)
+        assert_equal(type(np.rec.array(a)), np.recarray)
+        assert_equal(np.rec.array(b).dtype.type, np.int64)
+        assert_equal(type(np.rec.array(b)), np.recarray)
+
+        #check that viewing as recarray does the same
+        assert_equal(a.view(np.recarray).dtype.type, np.record)
+        assert_equal(type(a.view(np.recarray)), np.recarray)
+        assert_equal(b.view(np.recarray).dtype.type, np.int64)
+        assert_equal(type(b.view(np.recarray)), np.recarray)
+
+        #check that view to non-structured dtype preserves type=np.recarray
+        r = np.rec.array(np.ones(4, dtype="f4,i4"))
+        rv = r.view('f8').view('f4,i4')
+        assert_equal(type(rv), np.recarray)
+        assert_equal(rv.dtype.type, np.record)
+
+        #check that getitem also preserves np.recarray and np.record
+        r = np.rec.array(np.ones(4, dtype=[('a', 'i4'), ('b', 'i4'),
+                                           ('c', 'i4,i4')]))
+        assert_equal(r['c'].dtype.type, np.record)
+        assert_equal(type(r['c']), np.recarray)
+        assert_equal(r[['a', 'b']].dtype.type, np.record)
+        assert_equal(type(r[['a', 'b']]), np.recarray)
+
+        #and that it preserves subclasses (gh-6949)
+        class C(np.recarray):
+            pass
+
+        c = r.view(C)
+        assert_equal(type(c['c']), C)
+
+        # check that accessing nested structures keep record type, but
+        # not for subarrays, non-void structures, non-structured voids
+        test_dtype = [('a', 'f4,f4'), ('b', 'V8'), ('c', ('f4',2)),
+                      ('d', ('i8', 'i4,i4'))]
+        r = np.rec.array([((1,1), b'11111111', [1,1], 1),
+                          ((1,1), b'11111111', [1,1], 1)], dtype=test_dtype)
+        assert_equal(r.a.dtype.type, np.record)
+        assert_equal(r.b.dtype.type, np.void)
+        assert_equal(r.c.dtype.type, np.float32)
+        assert_equal(r.d.dtype.type, np.int64)
+        # check the same, but for views
+        r = np.rec.array(np.ones(4, dtype='i4,i4'))
+        assert_equal(r.view('f4,f4').dtype.type, np.record)
+        assert_equal(r.view(('i4',2)).dtype.type, np.int32)
+        assert_equal(r.view('V8').dtype.type, np.void)
+        assert_equal(r.view(('i8', 'i4,i4')).dtype.type, np.int64)
+
+        #check that we can undo the view
+        arrs = [np.ones(4, dtype='f4,i4'), np.ones(4, dtype='f8')]
+        for arr in arrs:
+            rec = np.rec.array(arr)
+            # recommended way to view as an ndarray:
+            arr2 = rec.view(rec.dtype.fields or rec.dtype, np.ndarray)
+            assert_equal(arr2.dtype.type, arr.dtype.type)
+            assert_equal(type(arr2), type(arr))
+
+    def test_recarray_repr(self):
+        # make sure non-structured dtypes also show up as rec.array
+        a = np.array(np.ones(4, dtype='f8'))
+        assert_(repr(np.rec.array(a)).startswith('rec.array'))
+
+        # check that the 'np.record' part of the dtype isn't shown
+        a = np.rec.array(np.ones(3, dtype='i4,i4'))
+        assert_equal(repr(a).find('numpy.record'), -1)
+        a = np.rec.array(np.ones(3, dtype='i4'))
+        assert_(repr(a).find('dtype=int32') != -1)
+
+    def test_recarray_from_names(self):
+        ra = np.rec.array([
+            (1, 'abc', 3.7000002861022949, 0),
+            (2, 'xy', 6.6999998092651367, 1),
+            (0, ' ', 0.40000000596046448, 0)],
+                       names='c1, c2, c3, c4')
+        pa = np.rec.fromrecords([
+            (1, 'abc', 3.7000002861022949, 0),
+            (2, 'xy', 6.6999998092651367, 1),
+            (0, ' ', 0.40000000596046448, 0)],
+                       names='c1, c2, c3, c4')
+        assert_(ra.dtype == pa.dtype)
+        assert_(ra.shape == pa.shape)
+        for k in range(len(ra)):
+            assert_(ra[k].item() == pa[k].item())
+
+    def test_recarray_conflict_fields(self):
+        ra = np.rec.array([(1, 'abc', 2.3), (2, 'xyz', 4.2),
+                        (3, 'wrs', 1.3)],
+                       names='field, shape, mean')
+        ra.mean = [1.1, 2.2, 3.3]
+        assert_array_almost_equal(ra['mean'], [1.1, 2.2, 3.3])
+        assert_(type(ra.mean) is type(ra.var))
+        ra.shape = (1, 3)
+        assert_(ra.shape == (1, 3))
+        ra.shape = ['A', 'B', 'C']
+        assert_array_equal(ra['shape'], [['A', 'B', 'C']])
+        ra.field = 5
+        assert_array_equal(ra['field'], [[5, 5, 5]])
+        assert_(isinstance(ra.field, collections.Callable))
+
+    def test_fromrecords_with_explicit_dtype(self):
+        a = np.rec.fromrecords([(1, 'a'), (2, 'bbb')],
+                                dtype=[('a', int), ('b', np.object)])
+        assert_equal(a.a, [1, 2])
+        assert_equal(a[0].a, 1)
+        assert_equal(a.b, ['a', 'bbb'])
+        assert_equal(a[-1].b, 'bbb')
+        #
+        ndtype = np.dtype([('a', int), ('b', np.object)])
+        a = np.rec.fromrecords([(1, 'a'), (2, 'bbb')], dtype=ndtype)
+        assert_equal(a.a, [1, 2])
+        assert_equal(a[0].a, 1)
+        assert_equal(a.b, ['a', 'bbb'])
+        assert_equal(a[-1].b, 'bbb')
+
+    def test_recarray_stringtypes(self):
+        # Issue #3993
+        a = np.array([('abc ', 1), ('abc', 2)],
+                     dtype=[('foo', 'S4'), ('bar', int)])
+        a = a.view(np.recarray)
+        assert_equal(a.foo[0] == a.foo[1], False)
+
+    def test_recarray_returntypes(self):
+        qux_fields = {'C': (np.dtype('S5'), 0), 'D': (np.dtype('S5'), 6)}
+        a = np.rec.array([('abc ', (1,1), 1, ('abcde', 'fgehi')),
+                          ('abc', (2,3), 1, ('abcde', 'jklmn'))],
+                         dtype=[('foo', 'S4'),
+                                ('bar', [('A', int), ('B', int)]),
+                                ('baz', int), ('qux', qux_fields)])
+        assert_equal(type(a.foo), np.ndarray)
+        assert_equal(type(a['foo']), np.ndarray)
+        assert_equal(type(a.bar), np.recarray)
+        assert_equal(type(a['bar']), np.recarray)
+        assert_equal(a.bar.dtype.type, np.record)
+        assert_equal(type(a['qux']), np.recarray)
+        assert_equal(a.qux.dtype.type, np.record)
+        assert_equal(dict(a.qux.dtype.fields), qux_fields)
+        assert_equal(type(a.baz), np.ndarray)
+        assert_equal(type(a['baz']), np.ndarray)
+        assert_equal(type(a[0].bar), np.record)
+        assert_equal(type(a[0]['bar']), np.record)
+        assert_equal(a[0].bar.A, 1)
+        assert_equal(a[0].bar['A'], 1)
+        assert_equal(a[0]['bar'].A, 1)
+        assert_equal(a[0]['bar']['A'], 1)
+        assert_equal(a[0].qux.D, asbytes('fgehi'))
+        assert_equal(a[0].qux['D'], asbytes('fgehi'))
+        assert_equal(a[0]['qux'].D, asbytes('fgehi'))
+        assert_equal(a[0]['qux']['D'], asbytes('fgehi'))
+
+
+class TestRecord(TestCase):
+    def setUp(self):
+        self.data = np.rec.fromrecords([(1, 2, 3), (4, 5, 6)],
+                            dtype=[("col1", "<i4"),
+                                   ("col2", "<i4"),
+                                   ("col3", "<i4")])
+
+    def test_assignment1(self):
+        a = self.data
+        assert_equal(a.col1[0], 1)
+        a[0].col1 = 0
+        assert_equal(a.col1[0], 0)
+
+    def test_assignment2(self):
+        a = self.data
+        assert_equal(a.col1[0], 1)
+        a.col1[0] = 0
+        assert_equal(a.col1[0], 0)
+
+    def test_invalid_assignment(self):
+        a = self.data
+
+        def assign_invalid_column(x):
+            x[0].col5 = 1
+
+        self.assertRaises(AttributeError, assign_invalid_column, a)
+
+    def test_out_of_order_fields(self):
+        """Ticket #1431."""
+        x = self.data[['col1', 'col2']]
+        y = self.data[['col2', 'col1']]
+        assert_equal(x[0][0], y[0][1])
+
+    def test_pickle_1(self):
+        # Issue #1529
+        a = np.array([(1, [])], dtype=[('a', np.int32), ('b', np.int32, 0)])
+        assert_equal(a, pickle.loads(pickle.dumps(a)))
+        assert_equal(a[0], pickle.loads(pickle.dumps(a[0])))
+
+    def test_pickle_2(self):
+        a = self.data
+        assert_equal(a, pickle.loads(pickle.dumps(a)))
+        assert_equal(a[0], pickle.loads(pickle.dumps(a[0])))
+
+    def test_objview_record(self):
+        # https://github.com/numpy/numpy/issues/2599
+        dt = np.dtype([('foo', 'i8'), ('bar', 'O')])
+        r = np.zeros((1,3), dtype=dt).view(np.recarray)
+        r.foo = np.array([1, 2, 3])  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3256
+        ra = np.recarray((2,), dtype=[('x', object), ('y', float), ('z', int)])
+        ra[['x','y']]  # TypeError?
+
+    def test_record_scalar_setitem(self):
+        # https://github.com/numpy/numpy/issues/3561
+        rec = np.recarray(1, dtype=[('x', float, 5)])
+        rec[0].x = 1
+        assert_equal(rec[0].x, np.ones(5))
+
+    def test_missing_field(self):
+        # https://github.com/numpy/numpy/issues/4806
+        arr = np.zeros((3,), dtype=[('x', int), ('y', int)])
+        assert_raises(ValueError, lambda: arr[['nofield']])
+
+def test_find_duplicate():
+    l1 = [1, 2, 3, 4, 5, 6]
+    assert_(np.rec.find_duplicate(l1) == [])
+
+    l2 = [1, 2, 1, 4, 5, 6]
+    assert_(np.rec.find_duplicate(l2) == [1])
+
+    l3 = [1, 2, 1, 4, 1, 6, 2, 3]
+    assert_(np.rec.find_duplicate(l3) == [1, 2])
+
+    l3 = [2, 2, 1, 4, 1, 6, 2, 3]
+    assert_(np.rec.find_duplicate(l3) == [2, 1])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
new file mode 100644
index 0000000000..a61e64d8de
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
@@ -0,0 +1,2187 @@
+from __future__ import division, absolute_import, print_function
+
+import copy
+import pickle
+import sys
+import platform
+import gc
+import warnings
+import tempfile
+from os import path
+from io import BytesIO
+from itertools import chain
+
+import numpy as np
+from numpy.testing import (
+        run_module_suite, TestCase, assert_, assert_equal,
+        assert_almost_equal, assert_array_equal, assert_array_almost_equal,
+        assert_raises, assert_warns, dec
+        )
+from numpy.testing.utils import _assert_valid_refcount
+from numpy.compat import asbytes, asunicode, asbytes_nested, long, sixu
+
+rlevel = 1
+
+class TestRegression(TestCase):
+    def test_invalid_round(self,level=rlevel):
+        # Ticket #3
+        v = 4.7599999999999998
+        assert_array_equal(np.array([v]), np.array(v))
+
+    def test_mem_empty(self,level=rlevel):
+        # Ticket #7
+        np.empty((1,), dtype=[('x', np.int64)])
+
+    def test_pickle_transposed(self,level=rlevel):
+        # Ticket #16
+        a = np.transpose(np.array([[2, 9], [7, 0], [3, 8]]))
+        f = BytesIO()
+        pickle.dump(a, f)
+        f.seek(0)
+        b = pickle.load(f)
+        f.close()
+        assert_array_equal(a, b)
+
+    def test_typeNA(self,level=rlevel):
+        # Ticket #31
+        assert_equal(np.typeNA[np.int64], 'Int64')
+        assert_equal(np.typeNA[np.uint64], 'UInt64')
+
+    def test_dtype_names(self,level=rlevel):
+        # Ticket #35
+        # Should succeed
+        np.dtype([(('name', 'label'), np.int32, 3)])
+
+    def test_reduce(self,level=rlevel):
+        # Ticket #40
+        assert_almost_equal(np.add.reduce([1., .5], dtype=None), 1.5)
+
+    def test_zeros_order(self,level=rlevel):
+        # Ticket #43
+        np.zeros([3], int, 'C')
+        np.zeros([3], order='C')
+        np.zeros([3], int, order='C')
+
+    def test_asarray_with_order(self,level=rlevel):
+        # Check that nothing is done when order='F' and array C/F-contiguous
+        a = np.ones(2)
+        assert_(a is np.asarray(a, order='F'))
+
+    def test_ravel_with_order(self,level=rlevel):
+        # Check that ravel works when order='F' and array C/F-contiguous
+        a = np.ones(2)
+        assert_(not a.ravel('F').flags.owndata)
+
+    def test_sort_bigendian(self,level=rlevel):
+        # Ticket #47
+        a = np.linspace(0, 10, 11)
+        c = a.astype(np.dtype('<f8'))
+        c.sort()
+        assert_array_almost_equal(c, a)
+
+    def test_negative_nd_indexing(self,level=rlevel):
+        # Ticket #49
+        c = np.arange(125).reshape((5, 5, 5))
+        origidx = np.array([-1, 0, 1])
+        idx = np.array(origidx)
+        c[idx]
+        assert_array_equal(idx, origidx)
+
+    def test_char_dump(self,level=rlevel):
+        # Ticket #50
+        f = BytesIO()
+        ca = np.char.array(np.arange(1000, 1010), itemsize=4)
+        ca.dump(f)
+        f.seek(0)
+        ca = np.load(f)
+        f.close()
+
+    def test_noncontiguous_fill(self,level=rlevel):
+        # Ticket #58.
+        a = np.zeros((5, 3))
+        b = a[:, :2,]
+
+        def rs():
+            b.shape = (10,)
+
+        self.assertRaises(AttributeError, rs)
+
+    def test_bool(self,level=rlevel):
+        # Ticket #60
+        np.bool_(1)  # Should succeed
+
+    def test_indexing1(self,level=rlevel):
+        # Ticket #64
+        descr = [('x', [('y', [('z', 'c16', (2,)),]),]),]
+        buffer = ((([6j, 4j],),),)
+        h = np.array(buffer, dtype=descr)
+        h['x']['y']['z']
+
+    def test_indexing2(self,level=rlevel):
+        # Ticket #65
+        descr = [('x', 'i4', (2,))]
+        buffer = ([3, 2],)
+        h = np.array(buffer, dtype=descr)
+        h['x']
+
+    def test_round(self,level=rlevel):
+        # Ticket #67
+        x = np.array([1+2j])
+        assert_almost_equal(x**(-1), [1/(1+2j)])
+
+    def test_scalar_compare(self,level=rlevel):
+        # Trac Ticket #72
+        # https://github.com/numpy/numpy/issues/565
+        a = np.array(['test', 'auto'])
+        assert_array_equal(a == 'auto', np.array([False, True]))
+        self.assertTrue(a[1] == 'auto')
+        self.assertTrue(a[0] != 'auto')
+        b = np.linspace(0, 10, 11)
+        # This should return true for now, but will eventually raise an error:
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            self.assertTrue(b != 'auto')
+        self.assertTrue(b[0] != 'auto')
+
+    def test_unicode_swapping(self,level=rlevel):
+        # Ticket #79
+        ulen = 1
+        ucs_value = sixu('\U0010FFFF')
+        ua = np.array([[[ucs_value*ulen]*2]*3]*4, dtype='U%s' % ulen)
+        ua.newbyteorder()  # Should succeed.
+
+    def test_object_array_fill(self,level=rlevel):
+        # Ticket #86
+        x = np.zeros(1, 'O')
+        x.fill([])
+
+    def test_mem_dtype_align(self,level=rlevel):
+        # Ticket #93
+        self.assertRaises(TypeError, np.dtype,
+                              {'names':['a'],'formats':['foo']}, align=1)
+
+    @dec.knownfailureif((sys.version_info[0] >= 3) or
+                        (sys.platform == "win32" and
+                         platform.architecture()[0] == "64bit"),
+                        "numpy.intp('0xff', 16) not supported on Py3, "
+                        "as it does not inherit from Python int")
+    def test_intp(self,level=rlevel):
+        # Ticket #99
+        i_width = np.int_(0).nbytes*2 - 1
+        np.intp('0x' + 'f'*i_width, 16)
+        self.assertRaises(OverflowError, np.intp, '0x' + 'f'*(i_width+1), 16)
+        self.assertRaises(ValueError, np.intp, '0x1', 32)
+        assert_equal(255, np.intp('0xFF', 16))
+        assert_equal(1024, np.intp(1024))
+
+    def test_endian_bool_indexing(self,level=rlevel):
+        # Ticket #105
+        a = np.arange(10., dtype='>f8')
+        b = np.arange(10., dtype='<f8')
+        xa = np.where((a > 2) & (a < 6))
+        xb = np.where((b > 2) & (b < 6))
+        ya = ((a > 2) & (a < 6))
+        yb = ((b > 2) & (b < 6))
+        assert_array_almost_equal(xa, ya.nonzero())
+        assert_array_almost_equal(xb, yb.nonzero())
+        assert_(np.all(a[ya] > 0.5))
+        assert_(np.all(b[yb] > 0.5))
+
+    def test_endian_where(self,level=rlevel):
+        # GitHub issue #369
+        net = np.zeros(3, dtype='>f4')
+        net[1] = 0.00458849
+        net[2] = 0.605202
+        max_net = net.max()
+        test = np.where(net <= 0., max_net, net)
+        correct = np.array([ 0.60520202,  0.00458849,  0.60520202])
+        assert_array_almost_equal(test, correct)
+
+    def test_endian_recarray(self,level=rlevel):
+        # Ticket #2185
+        dt = np.dtype([
+               ('head', '>u4'),
+               ('data', '>u4', 2),
+            ])
+        buf = np.recarray(1, dtype=dt)
+        buf[0]['head'] = 1
+        buf[0]['data'][:] = [1, 1]
+
+        h = buf[0]['head']
+        d = buf[0]['data'][0]
+        buf[0]['head'] = h
+        buf[0]['data'][0] = d
+        assert_(buf[0]['head'] == 1)
+
+    def test_mem_dot(self,level=rlevel):
+        # Ticket #106
+        x = np.random.randn(0, 1)
+        y = np.random.randn(10, 1)
+        # Dummy array to detect bad memory access:
+        _z = np.ones(10)
+        _dummy = np.empty((0, 10))
+        z = np.lib.stride_tricks.as_strided(_z, _dummy.shape, _dummy.strides)
+        np.dot(x, np.transpose(y), out=z)
+        assert_equal(_z, np.ones(10))
+        # Do the same for the built-in dot:
+        np.core.multiarray.dot(x, np.transpose(y), out=z)
+        assert_equal(_z, np.ones(10))
+
+    def test_arange_endian(self,level=rlevel):
+        # Ticket #111
+        ref = np.arange(10)
+        x = np.arange(10, dtype='<f8')
+        assert_array_equal(ref, x)
+        x = np.arange(10, dtype='>f8')
+        assert_array_equal(ref, x)
+
+    def test_argmax(self,level=rlevel):
+        # Ticket #119
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            a.argmax(i)  # Should succeed
+
+    def test_mem_divmod(self,level=rlevel):
+        # Ticket #126
+        for i in range(10):
+            divmod(np.array([i])[0], 10)
+
+    def test_hstack_invalid_dims(self,level=rlevel):
+        # Ticket #128
+        x = np.arange(9).reshape((3, 3))
+        y = np.array([0, 0, 0])
+        self.assertRaises(ValueError, np.hstack, (x, y))
+
+    def test_squeeze_type(self,level=rlevel):
+        # Ticket #133
+        a = np.array([3])
+        b = np.array(3)
+        assert_(type(a.squeeze()) is np.ndarray)
+        assert_(type(b.squeeze()) is np.ndarray)
+
+    def test_add_identity(self,level=rlevel):
+        # Ticket #143
+        assert_equal(0, np.add.identity)
+
+    def test_numpy_float_python_long_addition(self):
+        # Check that numpy float and python longs can be added correctly.
+        a = np.float_(23.) + 2**135
+        assert_equal(a, 23. + 2**135)
+
+    def test_binary_repr_0(self,level=rlevel):
+        # Ticket #151
+        assert_equal('0', np.binary_repr(0))
+
+    def test_rec_iterate(self,level=rlevel):
+        # Ticket #160
+        descr = np.dtype([('i', int), ('f', float), ('s', '|S3')])
+        x = np.rec.array([(1, 1.1, '1.0'),
+                         (2, 2.2, '2.0')], dtype=descr)
+        x[0].tolist()
+        [i for i in x[0]]
+
+    def test_unicode_string_comparison(self,level=rlevel):
+        # Ticket #190
+        a = np.array('hello', np.unicode_)
+        b = np.array('world')
+        a == b
+
+    def test_tobytes_FORTRANORDER_discontiguous(self,level=rlevel):
+        # Fix in r2836
+        # Create non-contiguous Fortran ordered array
+        x = np.array(np.random.rand(3, 3), order='F')[:, :2]
+        assert_array_almost_equal(x.ravel(), np.fromstring(x.tobytes()))
+
+    def test_flat_assignment(self,level=rlevel):
+        # Correct behaviour of ticket #194
+        x = np.empty((3, 1))
+        x.flat = np.arange(3)
+        assert_array_almost_equal(x, [[0], [1], [2]])
+        x.flat = np.arange(3, dtype=float)
+        assert_array_almost_equal(x, [[0], [1], [2]])
+
+    def test_broadcast_flat_assignment(self,level=rlevel):
+        # Ticket #194
+        x = np.empty((3, 1))
+
+        def bfa():
+            x[:] = np.arange(3)
+
+        def bfb():
+            x[:] = np.arange(3, dtype=float)
+
+        self.assertRaises(ValueError, bfa)
+        self.assertRaises(ValueError, bfb)
+
+    def test_nonarray_assignment(self):
+        # See also Issue gh-2870, test for non-array assignment
+        # and equivalent unsafe casted array assignment
+        a = np.arange(10)
+        b = np.ones(10, dtype=bool)
+        r = np.arange(10)
+
+        def assign(a, b, c):
+            a[b] = c
+
+        assert_raises(ValueError, assign, a, b, np.nan)
+        a[b] = np.array(np.nan)  # but not this.
+        assert_raises(ValueError, assign, a, r, np.nan)
+        a[r] = np.array(np.nan)
+
+    def test_unpickle_dtype_with_object(self,level=rlevel):
+        # Implemented in r2840
+        dt = np.dtype([('x', int), ('y', np.object_), ('z', 'O')])
+        f = BytesIO()
+        pickle.dump(dt, f)
+        f.seek(0)
+        dt_ = pickle.load(f)
+        f.close()
+        assert_equal(dt, dt_)
+
+    def test_mem_array_creation_invalid_specification(self,level=rlevel):
+        # Ticket #196
+        dt = np.dtype([('x', int), ('y', np.object_)])
+        # Wrong way
+        self.assertRaises(ValueError, np.array, [1, 'object'], dt)
+        # Correct way
+        np.array([(1, 'object')], dt)
+
+    def test_recarray_single_element(self,level=rlevel):
+        # Ticket #202
+        a = np.array([1, 2, 3], dtype=np.int32)
+        b = a.copy()
+        r = np.rec.array(a, shape=1, formats=['3i4'], names=['d'])
+        assert_array_equal(a, b)
+        assert_equal(a, r[0][0])
+
+    def test_zero_sized_array_indexing(self,level=rlevel):
+        # Ticket #205
+        tmp = np.array([])
+
+        def index_tmp():
+            tmp[np.array(10)]
+
+        self.assertRaises(IndexError, index_tmp)
+
+    def test_chararray_rstrip(self,level=rlevel):
+        # Ticket #222
+        x = np.chararray((1,), 5)
+        x[0] = asbytes('a   ')
+        x = x.rstrip()
+        assert_equal(x[0], asbytes('a'))
+
+    def test_object_array_shape(self,level=rlevel):
+        # Ticket #239
+        assert_equal(np.array([[1, 2], 3, 4], dtype=object).shape, (3,))
+        assert_equal(np.array([[1, 2], [3, 4]], dtype=object).shape, (2, 2))
+        assert_equal(np.array([(1, 2), (3, 4)], dtype=object).shape, (2, 2))
+        assert_equal(np.array([], dtype=object).shape, (0,))
+        assert_equal(np.array([[], [], []], dtype=object).shape, (3, 0))
+        assert_equal(np.array([[3, 4], [5, 6], None], dtype=object).shape, (3,))
+
+    def test_mem_around(self,level=rlevel):
+        # Ticket #243
+        x = np.zeros((1,))
+        y = [0]
+        decimal = 6
+        np.around(abs(x-y), decimal) <= 10.0**(-decimal)
+
+    def test_character_array_strip(self,level=rlevel):
+        # Ticket #246
+        x = np.char.array(("x", "x ", "x  "))
+        for c in x:
+            assert_equal(c, "x")
+
+    def test_lexsort(self,level=rlevel):
+        # Lexsort memory error
+        v = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+        assert_equal(np.lexsort(v), 0)
+
+    def test_lexsort_invalid_sequence(self):
+        # Issue gh-4123
+        class BuggySequence(object):
+            def __len__(self):
+                return 4
+
+            def __getitem__(self, key):
+                raise KeyError
+
+        assert_raises(KeyError, np.lexsort, BuggySequence())
+
+    def test_pickle_py2_bytes_encoding(self):
+        # Check that arrays and scalars pickled on Py2 are
+        # unpickleable on Py3 using encoding='bytes'
+
+        test_data = [
+            # (original, py2_pickle)
+            (np.unicode_('\u6f2c'),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+                     "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\n"
+                     "I0\ntp6\nbS',o\\x00\\x00'\np7\ntp8\nRp9\n.")),
+
+            (np.array([9e123], dtype=np.float64),
+             asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\n"
+                     "p1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\n"
+                     "p7\n(S'f8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'<'\np11\nNNNI-1\nI-1\n"
+                     "I0\ntp12\nbI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np13\ntp14\nb.")),
+
+            (np.array([(9e123,)], dtype=[('name', float)]),
+             asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n"
+                     "(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n"
+                     "(S'V8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'name'\np12\ntp13\n"
+                     "(dp14\ng12\n(g7\n(S'f8'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'<'\np18\nNNNI-1\n"
+                     "I-1\nI0\ntp19\nbI0\ntp20\nsI8\nI1\nI0\ntp21\n"
+                     "bI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np22\ntp23\nb.")),
+        ]
+
+        if sys.version_info[:2] >= (3, 4):
+            # encoding='bytes' was added in Py3.4
+            for original, data in test_data:
+                result = pickle.loads(data, encoding='bytes')
+                assert_equal(result, original)
+
+                if isinstance(result, np.ndarray) and result.dtype.names:
+                    for name in result.dtype.names:
+                        assert_(isinstance(name, str))
+
+    def test_pickle_dtype(self,level=rlevel):
+        # Ticket #251
+        pickle.dumps(np.float)
+
+    def test_swap_real(self, level=rlevel):
+        # Ticket #265
+        assert_equal(np.arange(4, dtype='>c8').imag.max(), 0.0)
+        assert_equal(np.arange(4, dtype='<c8').imag.max(), 0.0)
+        assert_equal(np.arange(4, dtype='>c8').real.max(), 3.0)
+        assert_equal(np.arange(4, dtype='<c8').real.max(), 3.0)
+
+    def test_object_array_from_list(self, level=rlevel):
+        # Ticket #270
+        np.array([1, 'A', None])  # Should succeed
+
+    def test_multiple_assign(self, level=rlevel):
+        # Ticket #273
+        a = np.zeros((3, 1), int)
+        a[[1, 2]] = 1
+
+    def test_empty_array_type(self, level=rlevel):
+        assert_equal(np.array([]).dtype, np.zeros(0).dtype)
+
+    def test_void_copyswap(self, level=rlevel):
+        dt = np.dtype([('one', '<i4'), ('two', '<i4')])
+        x = np.array((1, 2), dtype=dt)
+        x = x.byteswap()
+        assert_(x['one'] > 1 and x['two'] > 2)
+
+    def test_method_args(self, level=rlevel):
+        # Make sure methods and functions have same default axis
+        # keyword and arguments
+        funcs1 = ['argmax', 'argmin', 'sum', ('product', 'prod'),
+                 ('sometrue', 'any'),
+                 ('alltrue', 'all'), 'cumsum', ('cumproduct', 'cumprod'),
+                 'ptp', 'cumprod', 'prod', 'std', 'var', 'mean',
+                 'round', 'min', 'max', 'argsort', 'sort']
+        funcs2 = ['compress', 'take', 'repeat']
+
+        for func in funcs1:
+            arr = np.random.rand(8, 7)
+            arr2 = arr.copy()
+            if isinstance(func, tuple):
+                func_meth = func[1]
+                func = func[0]
+            else:
+                func_meth = func
+            res1 = getattr(arr, func_meth)()
+            res2 = getattr(np, func)(arr2)
+            if res1 is None:
+                res1 = arr
+
+            if res1.dtype.kind in 'uib':
+                assert_((res1 == res2).all(), func)
+            else:
+                assert_(abs(res1-res2).max() < 1e-8, func)
+
+        for func in funcs2:
+            arr1 = np.random.rand(8, 7)
+            arr2 = np.random.rand(8, 7)
+            res1 = None
+            if func == 'compress':
+                arr1 = arr1.ravel()
+                res1 = getattr(arr2, func)(arr1)
+            else:
+                arr2 = (15*arr2).astype(int).ravel()
+            if res1 is None:
+                res1 = getattr(arr1, func)(arr2)
+            res2 = getattr(np, func)(arr1, arr2)
+            assert_(abs(res1-res2).max() < 1e-8, func)
+
+    def test_mem_lexsort_strings(self, level=rlevel):
+        # Ticket #298
+        lst = ['abc', 'cde', 'fgh']
+        np.lexsort((lst,))
+
+    def test_fancy_index(self, level=rlevel):
+        # Ticket #302
+        x = np.array([1, 2])[np.array([0])]
+        assert_equal(x.shape, (1,))
+
+    def test_recarray_copy(self, level=rlevel):
+        # Ticket #312
+        dt = [('x', np.int16), ('y', np.float64)]
+        ra = np.array([(1, 2.3)], dtype=dt)
+        rb = np.rec.array(ra, dtype=dt)
+        rb['x'] = 2.
+        assert_(ra['x'] != rb['x'])
+
+    def test_rec_fromarray(self, level=rlevel):
+        # Ticket #322
+        x1 = np.array([[1, 2], [3, 4], [5, 6]])
+        x2 = np.array(['a', 'dd', 'xyz'])
+        x3 = np.array([1.1, 2, 3])
+        np.rec.fromarrays([x1, x2, x3], formats="(2,)i4,a3,f8")
+
+    def test_object_array_assign(self, level=rlevel):
+        x = np.empty((2, 2), object)
+        x.flat[2] = (1, 2, 3)
+        assert_equal(x.flat[2], (1, 2, 3))
+
+    def test_ndmin_float64(self, level=rlevel):
+        # Ticket #324
+        x = np.array([1, 2, 3], dtype=np.float64)
+        assert_equal(np.array(x, dtype=np.float32, ndmin=2).ndim, 2)
+        assert_equal(np.array(x, dtype=np.float64, ndmin=2).ndim, 2)
+
+    def test_ndmin_order(self, level=rlevel):
+        # Issue #465 and related checks
+        assert_(np.array([1, 2], order='C', ndmin=3).flags.c_contiguous)
+        assert_(np.array([1, 2], order='F', ndmin=3).flags.f_contiguous)
+        assert_(np.array(np.ones((2, 2), order='F'), ndmin=3).flags.f_contiguous)
+        assert_(np.array(np.ones((2, 2), order='C'), ndmin=3).flags.c_contiguous)
+
+    def test_mem_axis_minimization(self, level=rlevel):
+        # Ticket #327
+        data = np.arange(5)
+        data = np.add.outer(data, data)
+
+    def test_mem_float_imag(self, level=rlevel):
+        # Ticket #330
+        np.float64(1.0).imag
+
+    def test_dtype_tuple(self, level=rlevel):
+        # Ticket #334
+        assert_(np.dtype('i4') == np.dtype(('i4', ())))
+
+    def test_dtype_posttuple(self, level=rlevel):
+        # Ticket #335
+        np.dtype([('col1', '()i4')])
+
+    def test_numeric_carray_compare(self, level=rlevel):
+        # Ticket #341
+        assert_equal(np.array(['X'], 'c'), asbytes('X'))
+
+    def test_string_array_size(self, level=rlevel):
+        # Ticket #342
+        self.assertRaises(ValueError,
+                              np.array, [['X'], ['X', 'X', 'X']], '|S1')
+
+    def test_dtype_repr(self, level=rlevel):
+        # Ticket #344
+        dt1 = np.dtype(('uint32', 2))
+        dt2 = np.dtype(('uint32', (2,)))
+        assert_equal(dt1.__repr__(), dt2.__repr__())
+
+    def test_reshape_order(self, level=rlevel):
+        # Make sure reshape order works.
+        a = np.arange(6).reshape(2, 3, order='F')
+        assert_equal(a, [[0, 2, 4], [1, 3, 5]])
+        a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
+        b = a[:, 1]
+        assert_equal(b.reshape(2, 2, order='F'), [[2, 6], [4, 8]])
+
+    def test_reshape_zero_strides(self, level=rlevel):
+        # Issue #380, test reshaping of zero strided arrays
+        a = np.ones(1)
+        a = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(0,))
+        assert_(a.reshape(5, 1).strides[0] == 0)
+
+    def test_reshape_zero_size(self, level=rlevel):
+        # GitHub Issue #2700, setting shape failed for 0-sized arrays
+        a = np.ones((0, 2))
+        a.shape = (-1, 2)
+
+    # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides.
+    # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous.
+    @dec.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max)
+    def test_reshape_trailing_ones_strides(self):
+        # GitHub issue gh-2949, bad strides for trailing ones of new shape
+        a = np.zeros(12, dtype=np.int32)[::2]  # not contiguous
+        strides_c = (16, 8, 8, 8)
+        strides_f = (8, 24, 48, 48)
+        assert_equal(a.reshape(3, 2, 1, 1).strides, strides_c)
+        assert_equal(a.reshape(3, 2, 1, 1, order='F').strides, strides_f)
+        assert_equal(np.array(0, dtype=np.int32).reshape(1, 1).strides, (4, 4))
+
+    def test_repeat_discont(self, level=rlevel):
+        # Ticket #352
+        a = np.arange(12).reshape(4, 3)[:, 2]
+        assert_equal(a.repeat(3), [2, 2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11])
+
+    def test_array_index(self, level=rlevel):
+        # Make sure optimization is not called in this case.
+        a = np.array([1, 2, 3])
+        a2 = np.array([[1, 2, 3]])
+        assert_equal(a[np.where(a == 3)], a2[np.where(a2 == 3)])
+
+    def test_object_argmax(self, level=rlevel):
+        a = np.array([1, 2, 3], dtype=object)
+        assert_(a.argmax() == 2)
+
+    def test_recarray_fields(self, level=rlevel):
+        # Ticket #372
+        dt0 = np.dtype([('f0', 'i4'), ('f1', 'i4')])
+        dt1 = np.dtype([('f0', 'i8'), ('f1', 'i8')])
+        for a in [np.array([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.array([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.array([(1, 2), (3, 4)]),
+                  np.rec.fromarrays([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.fromarrays([(1, 2), (3, 4)])]:
+            assert_(a.dtype in [dt0, dt1])
+
+    def test_random_shuffle(self, level=rlevel):
+        # Ticket #374
+        a = np.arange(5).reshape((5, 1))
+        b = a.copy()
+        np.random.shuffle(b)
+        assert_equal(np.sort(b, axis=0), a)
+
+    def test_refcount_vdot(self, level=rlevel):
+        # Changeset #3443
+        _assert_valid_refcount(np.vdot)
+
+    def test_startswith(self, level=rlevel):
+        ca = np.char.array(['Hi', 'There'])
+        assert_equal(ca.startswith('H'), [True, False])
+
+    def test_noncommutative_reduce_accumulate(self, level=rlevel):
+        # Ticket #413
+        tosubtract = np.arange(5)
+        todivide = np.array([2.0, 0.5, 0.25])
+        assert_equal(np.subtract.reduce(tosubtract), -10)
+        assert_equal(np.divide.reduce(todivide), 16.0)
+        assert_array_equal(np.subtract.accumulate(tosubtract),
+            np.array([0, -1, -3, -6, -10]))
+        assert_array_equal(np.divide.accumulate(todivide),
+            np.array([2., 4., 16.]))
+
+    def test_convolve_empty(self, level=rlevel):
+        # Convolve should raise an error for empty input array.
+        self.assertRaises(ValueError, np.convolve, [], [1])
+        self.assertRaises(ValueError, np.convolve, [1], [])
+
+    def test_multidim_byteswap(self, level=rlevel):
+        # Ticket #449
+        r = np.array([(1, (0, 1, 2))], dtype="i2,3i2")
+        assert_array_equal(r.byteswap(),
+                           np.array([(256, (0, 256, 512))], r.dtype))
+
+    def test_string_NULL(self, level=rlevel):
+        # Changeset 3557
+        assert_equal(np.array("a\x00\x0b\x0c\x00").item(),
+                     'a\x00\x0b\x0c')
+
+    def test_junk_in_string_fields_of_recarray(self, level=rlevel):
+        # Ticket #483
+        r = np.array([[asbytes('abc')]], dtype=[('var1', '|S20')])
+        assert_(asbytes(r['var1'][0][0]) == asbytes('abc'))
+
+    def test_take_output(self, level=rlevel):
+        # Ensure that 'take' honours output parameter.
+        x = np.arange(12).reshape((3, 4))
+        a = np.take(x, [0, 2], axis=1)
+        b = np.zeros_like(a)
+        np.take(x, [0, 2], axis=1, out=b)
+        assert_array_equal(a, b)
+
+    def test_take_object_fail(self):
+        # Issue gh-3001
+        d = 123.
+        a = np.array([d, 1], dtype=object)
+        ref_d = sys.getrefcount(d)
+        try:
+            a.take([0, 100])
+        except IndexError:
+            pass
+        assert_(ref_d == sys.getrefcount(d))
+
+    def test_array_str_64bit(self, level=rlevel):
+        # Ticket #501
+        s = np.array([1, np.nan], dtype=np.float64)
+        with np.errstate(all='raise'):
+            np.array_str(s)  # Should succeed
+
+    def test_frompyfunc_endian(self, level=rlevel):
+        # Ticket #503
+        from math import radians
+        uradians = np.frompyfunc(radians, 1, 1)
+        big_endian = np.array([83.4, 83.5], dtype='>f8')
+        little_endian = np.array([83.4, 83.5], dtype='<f8')
+        assert_almost_equal(uradians(big_endian).astype(float),
+                            uradians(little_endian).astype(float))
+
+    def test_mem_string_arr(self, level=rlevel):
+        # Ticket #514
+        s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        t = []
+        np.hstack((t, s))
+
+    def test_arr_transpose(self, level=rlevel):
+        # Ticket #516
+        x = np.random.rand(*(2,)*16)
+        x.transpose(list(range(16)))  # Should succeed
+
+    def test_string_mergesort(self, level=rlevel):
+        # Ticket #540
+        x = np.array(['a']*32)
+        assert_array_equal(x.argsort(kind='m'), np.arange(32))
+
+    def test_argmax_byteorder(self, level=rlevel):
+        # Ticket #546
+        a = np.arange(3, dtype='>f')
+        assert_(a[a.argmax()] == a.max())
+
+    def test_rand_seed(self, level=rlevel):
+        # Ticket #555
+        for l in np.arange(4):
+            np.random.seed(l)
+
+    def test_mem_deallocation_leak(self, level=rlevel):
+        # Ticket #562
+        a = np.zeros(5, dtype=float)
+        b = np.array(a, dtype=float)
+        del a, b
+
+    def test_mem_on_invalid_dtype(self):
+        "Ticket #583"
+        self.assertRaises(ValueError, np.fromiter, [['12', ''], ['13', '']], str)
+
+    def test_dot_negative_stride(self, level=rlevel):
+        # Ticket #588
+        x = np.array([[1, 5, 25, 125., 625]])
+        y = np.array([[20.], [160.], [640.], [1280.], [1024.]])
+        z = y[::-1].copy()
+        y2 = y[::-1]
+        assert_equal(np.dot(x, z), np.dot(x, y2))
+
+    def test_object_casting(self, level=rlevel):
+        # This used to trigger the object-type version of
+        # the bitwise_or operation, because float64 -> object
+        # casting succeeds
+        def rs():
+            x = np.ones([484, 286])
+            y = np.zeros([484, 286])
+            x |= y
+
+        self.assertRaises(TypeError, rs)
+
+    def test_unicode_scalar(self, level=rlevel):
+        # Ticket #600
+        x = np.array(["DROND", "DROND1"], dtype="U6")
+        el = x[1]
+        new = pickle.loads(pickle.dumps(el))
+        assert_equal(new, el)
+
+    def test_arange_non_native_dtype(self, level=rlevel):
+        # Ticket #616
+        for T in ('>f4', '<f4'):
+            dt = np.dtype(T)
+            assert_equal(np.arange(0, dtype=dt).dtype, dt)
+            assert_equal(np.arange(0.5, dtype=dt).dtype, dt)
+            assert_equal(np.arange(5, dtype=dt).dtype, dt)
+
+    def test_bool_flat_indexing_invalid_nr_elements(self, level=rlevel):
+        s = np.ones(10, dtype=float)
+        x = np.array((15,), dtype=float)
+
+        def ia(x, s, v):
+            x[(s > 0)] = v
+
+        # After removing deprecation, the following are ValueErrors.
+        # This might seem odd as compared to the value error below. This
+        # is due to the fact that the new code always uses "nonzero" logic
+        # and the boolean special case is not taken.
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', DeprecationWarning)
+            warnings.simplefilter('ignore', np.VisibleDeprecationWarning)
+            self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float))
+            self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float))
+        # Old special case (different code path):
+        self.assertRaises(ValueError, ia, x.flat, s, np.zeros(9, dtype=float))
+        self.assertRaises(ValueError, ia, x.flat, s, np.zeros(11, dtype=float))
+
+    def test_mem_scalar_indexing(self, level=rlevel):
+        # Ticket #603
+        x = np.array([0], dtype=float)
+        index = np.array(0, dtype=np.int32)
+        x[index]
+
+    def test_binary_repr_0_width(self, level=rlevel):
+        assert_equal(np.binary_repr(0, width=3), '000')
+
+    def test_fromstring(self, level=rlevel):
+        assert_equal(np.fromstring("12:09:09", dtype=int, sep=":"),
+                     [12, 9, 9])
+
+    def test_searchsorted_variable_length(self, level=rlevel):
+        x = np.array(['a', 'aa', 'b'])
+        y = np.array(['d', 'e'])
+        assert_equal(x.searchsorted(y), [3, 3])
+
+    def test_string_argsort_with_zeros(self, level=rlevel):
+        # Check argsort for strings containing zeros.
+        x = np.fromstring("\x00\x02\x00\x01", dtype="|S2")
+        assert_array_equal(x.argsort(kind='m'), np.array([1, 0]))
+        assert_array_equal(x.argsort(kind='q'), np.array([1, 0]))
+
+    def test_string_sort_with_zeros(self, level=rlevel):
+        # Check sort for strings containing zeros.
+        x = np.fromstring("\x00\x02\x00\x01", dtype="|S2")
+        y = np.fromstring("\x00\x01\x00\x02", dtype="|S2")
+        assert_array_equal(np.sort(x, kind="q"), y)
+
+    def test_copy_detection_zero_dim(self, level=rlevel):
+        # Ticket #658
+        np.indices((0, 3, 4)).T.reshape(-1, 3)
+
+    def test_flat_byteorder(self, level=rlevel):
+        # Ticket #657
+        x = np.arange(10)
+        assert_array_equal(x.astype('>i4'), x.astype('<i4').flat[:])
+        assert_array_equal(x.astype('>i4').flat[:], x.astype('<i4'))
+
+    def test_uint64_from_negative(self, level=rlevel):
+        assert_equal(np.uint64(-2), np.uint64(18446744073709551614))
+
+    def test_sign_bit(self, level=rlevel):
+        x = np.array([0, -0.0, 0])
+        assert_equal(str(np.abs(x)), '[ 0.  0.  0.]')
+
+    def test_flat_index_byteswap(self, level=rlevel):
+        for dt in (np.dtype('<i4'), np.dtype('>i4')):
+            x = np.array([-1, 0, 1], dtype=dt)
+            assert_equal(x.flat[0].dtype, x[0].dtype)
+
+    def test_copy_detection_corner_case(self, level=rlevel):
+        # Ticket #658
+        np.indices((0, 3, 4)).T.reshape(-1, 3)
+
+    # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides.
+    # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous,
+    # 0-sized reshape itself is tested elsewhere.
+    @dec.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max)
+    def test_copy_detection_corner_case2(self, level=rlevel):
+        # Ticket #771: strides are not set correctly when reshaping 0-sized
+        # arrays
+        b = np.indices((0, 3, 4)).T.reshape(-1, 3)
+        assert_equal(b.strides, (3 * b.itemsize, b.itemsize))
+
+    def test_object_array_refcounting(self, level=rlevel):
+        # Ticket #633
+        if not hasattr(sys, 'getrefcount'):
+            return
+
+        # NB. this is probably CPython-specific
+
+        cnt = sys.getrefcount
+
+        a = object()
+        b = object()
+        c = object()
+
+        cnt0_a = cnt(a)
+        cnt0_b = cnt(b)
+        cnt0_c = cnt(c)
+
+        # -- 0d -> 1-d broadcast slice assignment
+
+        arr = np.zeros(5, dtype=np.object_)
+
+        arr[:] = a
+        assert_equal(cnt(a), cnt0_a + 5)
+
+        arr[:] = b
+        assert_equal(cnt(a), cnt0_a)
+        assert_equal(cnt(b), cnt0_b + 5)
+
+        arr[:2] = c
+        assert_equal(cnt(b), cnt0_b + 3)
+        assert_equal(cnt(c), cnt0_c + 2)
+
+        del arr
+
+        # -- 1-d -> 2-d broadcast slice assignment
+
+        arr = np.zeros((5, 2), dtype=np.object_)
+        arr0 = np.zeros(2, dtype=np.object_)
+
+        arr0[0] = a
+        assert_(cnt(a) == cnt0_a + 1)
+        arr0[1] = b
+        assert_(cnt(b) == cnt0_b + 1)
+
+        arr[:,:] = arr0
+        assert_(cnt(a) == cnt0_a + 6)
+        assert_(cnt(b) == cnt0_b + 6)
+
+        arr[:, 0] = None
+        assert_(cnt(a) == cnt0_a + 1)
+
+        del arr, arr0
+
+        # -- 2-d copying + flattening
+
+        arr = np.zeros((5, 2), dtype=np.object_)
+
+        arr[:, 0] = a
+        arr[:, 1] = b
+        assert_(cnt(a) == cnt0_a + 5)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        arr2 = arr.copy()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 10)
+
+        arr2 = arr[:, 0].copy()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        arr2 = arr.flatten()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 10)
+
+        del arr, arr2
+
+        # -- concatenate, repeat, take, choose
+
+        arr1 = np.zeros((5, 1), dtype=np.object_)
+        arr2 = np.zeros((5, 1), dtype=np.object_)
+
+        arr1[...] = a
+        arr2[...] = b
+        assert_(cnt(a) == cnt0_a + 5)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        tmp = np.concatenate((arr1, arr2))
+        assert_(cnt(a) == cnt0_a + 5 + 5)
+        assert_(cnt(b) == cnt0_b + 5 + 5)
+
+        tmp = arr1.repeat(3, axis=0)
+        assert_(cnt(a) == cnt0_a + 5 + 3*5)
+
+        tmp = arr1.take([1, 2, 3], axis=0)
+        assert_(cnt(a) == cnt0_a + 5 + 3)
+
+        x = np.array([[0], [1], [0], [1], [1]], int)
+        tmp = x.choose(arr1, arr2)
+        assert_(cnt(a) == cnt0_a + 5 + 2)
+        assert_(cnt(b) == cnt0_b + 5 + 3)
+
+        del tmp  # Avoid pyflakes unused variable warning
+
+    def test_mem_custom_float_to_array(self, level=rlevel):
+        # Ticket 702
+        class MyFloat(object):
+            def __float__(self):
+                return 1.0
+
+        tmp = np.atleast_1d([MyFloat()])
+        tmp.astype(float)  # Should succeed
+
+    def test_object_array_refcount_self_assign(self, level=rlevel):
+        # Ticket #711
+        class VictimObject(object):
+            deleted = False
+
+            def __del__(self):
+                self.deleted = True
+
+        d = VictimObject()
+        arr = np.zeros(5, dtype=np.object_)
+        arr[:] = d
+        del d
+        arr[:] = arr  # refcount of 'd' might hit zero here
+        assert_(not arr[0].deleted)
+        arr[:] = arr  # trying to induce a segfault by doing it again...
+        assert_(not arr[0].deleted)
+
+    def test_mem_fromiter_invalid_dtype_string(self, level=rlevel):
+        x = [1, 2, 3]
+        self.assertRaises(ValueError,
+                              np.fromiter, [xi for xi in x], dtype='S')
+
+    def test_reduce_big_object_array(self, level=rlevel):
+        # Ticket #713
+        oldsize = np.setbufsize(10*16)
+        a = np.array([None]*161, object)
+        assert_(not np.any(a))
+        np.setbufsize(oldsize)
+
+    def test_mem_0d_array_index(self, level=rlevel):
+        # Ticket #714
+        np.zeros(10)[np.array(0)]
+
+    def test_floats_from_string(self, level=rlevel):
+        # Ticket #640, floats from string
+        fsingle = np.single('1.234')
+        fdouble = np.double('1.234')
+        flongdouble = np.longdouble('1.234')
+        assert_almost_equal(fsingle, 1.234)
+        assert_almost_equal(fdouble, 1.234)
+        assert_almost_equal(flongdouble, 1.234)
+
+    def test_nonnative_endian_fill(self, level=rlevel):
+        # Non-native endian arrays were incorrectly filled with scalars
+        # before r5034.
+        if sys.byteorder == 'little':
+            dtype = np.dtype('>i4')
+        else:
+            dtype = np.dtype('<i4')
+        x = np.empty([1], dtype=dtype)
+        x.fill(1)
+        assert_equal(x, np.array([1], dtype=dtype))
+
+    def test_dot_alignment_sse2(self, level=rlevel):
+        # Test for ticket #551, changeset r5140
+        x = np.zeros((30, 40))
+        y = pickle.loads(pickle.dumps(x))
+        # y is now typically not aligned on a 8-byte boundary
+        z = np.ones((1, y.shape[0]))
+        # This shouldn't cause a segmentation fault:
+        np.dot(z, y)
+
+    def test_astype_copy(self, level=rlevel):
+        # Ticket #788, changeset r5155
+        # The test data file was generated by scipy.io.savemat.
+        # The dtype is float64, but the isbuiltin attribute is 0.
+        data_dir = path.join(path.dirname(__file__), 'data')
+        filename = path.join(data_dir, "astype_copy.pkl")
+        if sys.version_info[0] >= 3:
+            f = open(filename, 'rb')
+            xp = pickle.load(f, encoding='latin1')
+            f.close()
+        else:
+            f = open(filename)
+            xp = pickle.load(f)
+            f.close()
+        xpd = xp.astype(np.float64)
+        assert_((xp.__array_interface__['data'][0] !=
+                xpd.__array_interface__['data'][0]))
+
+    def test_compress_small_type(self, level=rlevel):
+        # Ticket #789, changeset 5217.
+        # compress with out argument segfaulted if cannot cast safely
+        import numpy as np
+        a = np.array([[1, 2], [3, 4]])
+        b = np.zeros((2, 1), dtype=np.single)
+        try:
+            a.compress([True, False], axis=1, out=b)
+            raise AssertionError("compress with an out which cannot be "
+                                 "safely casted should not return "
+                                 "successfully")
+        except TypeError:
+            pass
+
+    def test_attributes(self, level=rlevel):
+        # Ticket #791
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, 'info', '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        assert_(dat.info == 'jubba')
+        dat.resize((4, 2))
+        assert_(dat.info == 'jubba')
+        dat.sort()
+        assert_(dat.info == 'jubba')
+        dat.fill(2)
+        assert_(dat.info == 'jubba')
+        dat.put([2, 3, 4], [6, 3, 4])
+        assert_(dat.info == 'jubba')
+        dat.setfield(4, np.int32, 0)
+        assert_(dat.info == 'jubba')
+        dat.setflags()
+        assert_(dat.info == 'jubba')
+        assert_(dat.all(1).info == 'jubba')
+        assert_(dat.any(1).info == 'jubba')
+        assert_(dat.argmax(1).info == 'jubba')
+        assert_(dat.argmin(1).info == 'jubba')
+        assert_(dat.argsort(1).info == 'jubba')
+        assert_(dat.astype(TestArray).info == 'jubba')
+        assert_(dat.byteswap().info == 'jubba')
+        assert_(dat.clip(2, 7).info == 'jubba')
+        assert_(dat.compress([0, 1, 1]).info == 'jubba')
+        assert_(dat.conj().info == 'jubba')
+        assert_(dat.conjugate().info == 'jubba')
+        assert_(dat.copy().info == 'jubba')
+        dat2 = TestArray([2, 3, 1, 0], 'jubba')
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        assert_(dat2.choose(choices).info == 'jubba')
+        assert_(dat.cumprod(1).info == 'jubba')
+        assert_(dat.cumsum(1).info == 'jubba')
+        assert_(dat.diagonal().info == 'jubba')
+        assert_(dat.flatten().info == 'jubba')
+        assert_(dat.getfield(np.int32, 0).info == 'jubba')
+        assert_(dat.imag.info == 'jubba')
+        assert_(dat.max(1).info == 'jubba')
+        assert_(dat.mean(1).info == 'jubba')
+        assert_(dat.min(1).info == 'jubba')
+        assert_(dat.newbyteorder().info == 'jubba')
+        assert_(dat.prod(1).info == 'jubba')
+        assert_(dat.ptp(1).info == 'jubba')
+        assert_(dat.ravel().info == 'jubba')
+        assert_(dat.real.info == 'jubba')
+        assert_(dat.repeat(2).info == 'jubba')
+        assert_(dat.reshape((2, 4)).info == 'jubba')
+        assert_(dat.round().info == 'jubba')
+        assert_(dat.squeeze().info == 'jubba')
+        assert_(dat.std(1).info == 'jubba')
+        assert_(dat.sum(1).info == 'jubba')
+        assert_(dat.swapaxes(0, 1).info == 'jubba')
+        assert_(dat.take([2, 3, 5]).info == 'jubba')
+        assert_(dat.transpose().info == 'jubba')
+        assert_(dat.T.info == 'jubba')
+        assert_(dat.var(1).info == 'jubba')
+        assert_(dat.view(TestArray).info == 'jubba')
+        # These methods do not preserve subclasses
+        assert_(type(dat.nonzero()[0]) is np.ndarray)
+        assert_(type(dat.nonzero()[1]) is np.ndarray)
+
+    def test_recarray_tolist(self, level=rlevel):
+        # Ticket #793, changeset r5215
+        # Comparisons fail for NaN, so we can't use random memory
+        # for the test.
+        buf = np.zeros(40, dtype=np.int8)
+        a = np.recarray(2, formats="i4,f8,f8", names="id,x,y", buf=buf)
+        b = a.tolist()
+        assert_( a[0].tolist() == b[0])
+        assert_( a[1].tolist() == b[1])
+
+    def test_nonscalar_item_method(self):
+        # Make sure that .item() fails graciously when it should
+        a = np.arange(5)
+        assert_raises(ValueError, a.item)
+
+    def test_char_array_creation(self, level=rlevel):
+        a = np.array('123', dtype='c')
+        b = np.array(asbytes_nested(['1', '2', '3']))
+        assert_equal(a, b)
+
+    def test_unaligned_unicode_access(self, level=rlevel):
+        # Ticket #825
+        for i in range(1, 9):
+            msg = 'unicode offset: %d chars' % i
+            t = np.dtype([('a', 'S%d' % i), ('b', 'U2')])
+            x = np.array([(asbytes('a'), sixu('b'))], dtype=t)
+            if sys.version_info[0] >= 3:
+                assert_equal(str(x), "[(b'a', 'b')]", err_msg=msg)
+            else:
+                assert_equal(str(x), "[('a', u'b')]", err_msg=msg)
+
+    def test_sign_for_complex_nan(self, level=rlevel):
+        # Ticket 794.
+        with np.errstate(invalid='ignore'):
+            C = np.array([-np.inf, -2+1j, 0, 2-1j, np.inf, np.nan])
+            have = np.sign(C)
+            want = np.array([-1+0j, -1+0j, 0+0j, 1+0j, 1+0j, np.nan])
+            assert_equal(have, want)
+
+    def test_for_equal_names(self, level=rlevel):
+        # Ticket #674
+        dt = np.dtype([('foo', float), ('bar', float)])
+        a = np.zeros(10, dt)
+        b = list(a.dtype.names)
+        b[0] = "notfoo"
+        a.dtype.names = b
+        assert_(a.dtype.names[0] == "notfoo")
+        assert_(a.dtype.names[1] == "bar")
+
+    def test_for_object_scalar_creation(self, level=rlevel):
+        # Ticket #816
+        a = np.object_()
+        b = np.object_(3)
+        b2 = np.object_(3.0)
+        c = np.object_([4, 5])
+        d = np.object_([None, {}, []])
+        assert_(a is None)
+        assert_(type(b) is int)
+        assert_(type(b2) is float)
+        assert_(type(c) is np.ndarray)
+        assert_(c.dtype == object)
+        assert_(d.dtype == object)
+
+    def test_array_resize_method_system_error(self):
+        # Ticket #840 - order should be an invalid keyword.
+        x = np.array([[0, 1], [2, 3]])
+        self.assertRaises(TypeError, x.resize, (2, 2), order='C')
+
+    def test_for_zero_length_in_choose(self, level=rlevel):
+        "Ticket #882"
+        a = np.array(1)
+        self.assertRaises(ValueError, lambda x: x.choose([]), a)
+
+    def test_array_ndmin_overflow(self):
+        "Ticket #947."
+        self.assertRaises(ValueError, lambda: np.array([1], ndmin=33))
+
+    def test_errobj_reference_leak(self, level=rlevel):
+        # Ticket #955
+        with np.errstate(all="ignore"):
+            z = int(0)
+            p = np.int32(-1)
+
+            gc.collect()
+            n_before = len(gc.get_objects())
+            z**p  # this shouldn't leak a reference to errobj
+            gc.collect()
+            n_after = len(gc.get_objects())
+            assert_(n_before >= n_after, (n_before, n_after))
+
+    def test_void_scalar_with_titles(self, level=rlevel):
+        # No ticket
+        data = [('john', 4), ('mary', 5)]
+        dtype1 = [(('source:yy', 'name'), 'O'), (('source:xx', 'id'), int)]
+        arr = np.array(data, dtype=dtype1)
+        assert_(arr[0][0] == 'john')
+        assert_(arr[0][1] == 4)
+
+    def test_void_scalar_constructor(self):
+        #Issue #1550
+
+        #Create test string data, construct void scalar from data and assert
+        #that void scalar contains original data.
+        test_string = np.array("test")
+        test_string_void_scalar = np.core.multiarray.scalar(
+            np.dtype(("V", test_string.dtype.itemsize)), test_string.tobytes())
+
+        assert_(test_string_void_scalar.view(test_string.dtype) == test_string)
+
+        #Create record scalar, construct from data and assert that
+        #reconstructed scalar is correct.
+        test_record = np.ones((), "i,i")
+        test_record_void_scalar = np.core.multiarray.scalar(
+            test_record.dtype, test_record.tobytes())
+
+        assert_(test_record_void_scalar == test_record)
+
+        #Test pickle and unpickle of void and record scalars
+        assert_(pickle.loads(pickle.dumps(test_string)) == test_string)
+        assert_(pickle.loads(pickle.dumps(test_record)) == test_record)
+
+    def test_blasdot_uninitialized_memory(self):
+        # Ticket #950
+        for m in [0, 1, 2]:
+            for n in [0, 1, 2]:
+                for k in range(3):
+                    # Try to ensure that x->data contains non-zero floats
+                    x = np.array([123456789e199], dtype=np.float64)
+                    x.resize((m, 0))
+                    y = np.array([123456789e199], dtype=np.float64)
+                    y.resize((0, n))
+
+                    # `dot` should just return zero (m,n) matrix
+                    z = np.dot(x, y)
+                    assert_(np.all(z == 0))
+                    assert_(z.shape == (m, n))
+
+    def test_zeros(self):
+        # Regression test for #1061.
+        # Set a size which cannot fit into a 64 bits signed integer
+        sz = 2 ** 64
+        good = 'Maximum allowed dimension exceeded'
+        try:
+            np.empty(sz)
+        except ValueError as e:
+            if not str(e) == good:
+                self.fail("Got msg '%s', expected '%s'" % (e, good))
+        except Exception as e:
+            self.fail("Got exception of type %s instead of ValueError" % type(e))
+
+    def test_huge_arange(self):
+        # Regression test for #1062.
+        # Set a size which cannot fit into a 64 bits signed integer
+        sz = 2 ** 64
+        good = 'Maximum allowed size exceeded'
+        try:
+            np.arange(sz)
+            self.assertTrue(np.size == sz)
+        except ValueError as e:
+            if not str(e) == good:
+                self.fail("Got msg '%s', expected '%s'" % (e, good))
+        except Exception as e:
+            self.fail("Got exception of type %s instead of ValueError" % type(e))
+
+    def test_fromiter_bytes(self):
+        # Ticket #1058
+        a = np.fromiter(list(range(10)), dtype='b')
+        b = np.fromiter(list(range(10)), dtype='B')
+        assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+        assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+
+    def test_array_from_sequence_scalar_array(self):
+        # Ticket #1078: segfaults when creating an array with a sequence of
+        # 0d arrays.
+        a = np.array((np.ones(2), np.array(2)))
+        assert_equal(a.shape, (2,))
+        assert_equal(a.dtype, np.dtype(object))
+        assert_equal(a[0], np.ones(2))
+        assert_equal(a[1], np.array(2))
+
+        a = np.array(((1,), np.array(1)))
+        assert_equal(a.shape, (2,))
+        assert_equal(a.dtype, np.dtype(object))
+        assert_equal(a[0], (1,))
+        assert_equal(a[1], np.array(1))
+
+    def test_array_from_sequence_scalar_array2(self):
+        # Ticket #1081: weird array with strange input...
+        t = np.array([np.array([]), np.array(0, object)])
+        assert_equal(t.shape, (2,))
+        assert_equal(t.dtype, np.dtype(object))
+
+    def test_array_too_big(self):
+        # Ticket #1080.
+        assert_raises(ValueError, np.zeros, [975]*7, np.int8)
+        assert_raises(ValueError, np.zeros, [26244]*5, np.int8)
+
+    def test_dtype_keyerrors_(self):
+        # Ticket #1106.
+        dt = np.dtype([('f1', np.uint)])
+        assert_raises(KeyError, dt.__getitem__, "f2")
+        assert_raises(IndexError, dt.__getitem__, 1)
+        assert_raises(ValueError, dt.__getitem__, 0.0)
+
+    def test_lexsort_buffer_length(self):
+        # Ticket #1217, don't segfault.
+        a = np.ones(100, dtype=np.int8)
+        b = np.ones(100, dtype=np.int32)
+        i = np.lexsort((a[::-1], b))
+        assert_equal(i, np.arange(100, dtype=np.int))
+
+    def test_object_array_to_fixed_string(self):
+        # Ticket #1235.
+        a = np.array(['abcdefgh', 'ijklmnop'], dtype=np.object_)
+        b = np.array(a, dtype=(np.str_, 8))
+        assert_equal(a, b)
+        c = np.array(a, dtype=(np.str_, 5))
+        assert_equal(c, np.array(['abcde', 'ijklm']))
+        d = np.array(a, dtype=(np.str_, 12))
+        assert_equal(a, d)
+        e = np.empty((2, ), dtype=(np.str_, 8))
+        e[:] = a[:]
+        assert_equal(a, e)
+
+    def test_unicode_to_string_cast(self):
+        # Ticket #1240.
+        a = np.array([[sixu('abc'), sixu('\u03a3')],
+                      [sixu('asdf'), sixu('erw')]],
+                     dtype='U')
+        self.assertRaises(UnicodeEncodeError, np.array, a, 'S4')
+
+    def test_mixed_string_unicode_array_creation(self):
+        a = np.array(['1234', sixu('123')])
+        assert_(a.itemsize == 16)
+        a = np.array([sixu('123'), '1234'])
+        assert_(a.itemsize == 16)
+        a = np.array(['1234', sixu('123'), '12345'])
+        assert_(a.itemsize == 20)
+        a = np.array([sixu('123'), '1234', sixu('12345')])
+        assert_(a.itemsize == 20)
+        a = np.array([sixu('123'), '1234', sixu('1234')])
+        assert_(a.itemsize == 16)
+
+    def test_misaligned_objects_segfault(self):
+        # Ticket #1198 and #1267
+        a1 = np.zeros((10,), dtype='O,c')
+        a2 = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 'S10')
+        a1['f0'] = a2
+        repr(a1)
+        np.argmax(a1['f0'])
+        a1['f0'][1] = "FOO"
+        a1['f0'] = "FOO"
+        np.array(a1['f0'], dtype='S')
+        np.nonzero(a1['f0'])
+        a1.sort()
+        copy.deepcopy(a1)
+
+    def test_misaligned_scalars_segfault(self):
+        # Ticket #1267
+        s1 = np.array(('a', 'Foo'), dtype='c,O')
+        s2 = np.array(('b', 'Bar'), dtype='c,O')
+        s1['f1'] = s2['f1']
+        s1['f1'] = 'Baz'
+
+    def test_misaligned_dot_product_objects(self):
+        # Ticket #1267
+        # This didn't require a fix, but it's worth testing anyway, because
+        # it may fail if .dot stops enforcing the arrays to be BEHAVED
+        a = np.array([[(1, 'a'), (0, 'a')], [(0, 'a'), (1, 'a')]], dtype='O,c')
+        b = np.array([[(4, 'a'), (1, 'a')], [(2, 'a'), (2, 'a')]], dtype='O,c')
+        np.dot(a['f0'], b['f0'])
+
+    def test_byteswap_complex_scalar(self):
+        # Ticket #1259 and gh-441
+        for dtype in [np.dtype('<'+t) for t in np.typecodes['Complex']]:
+            z = np.array([2.2-1.1j], dtype)
+            x = z[0]  # always native-endian
+            y = x.byteswap()
+            if x.dtype.byteorder == z.dtype.byteorder:
+                # little-endian machine
+                assert_equal(x, np.fromstring(y.tobytes(), dtype=dtype.newbyteorder()))
+            else:
+                # big-endian machine
+                assert_equal(x, np.fromstring(y.tobytes(), dtype=dtype))
+            # double check real and imaginary parts:
+            assert_equal(x.real, y.real.byteswap())
+            assert_equal(x.imag, y.imag.byteswap())
+
+    def test_structured_arrays_with_objects1(self):
+        # Ticket #1299
+        stra = 'aaaa'
+        strb = 'bbbb'
+        x = np.array([[(0, stra), (1, strb)]], 'i8,O')
+        x[x.nonzero()] = x.ravel()[:1]
+        assert_(x[0, 1] == x[0, 0])
+
+    def test_structured_arrays_with_objects2(self):
+        # Ticket #1299 second test
+        stra = 'aaaa'
+        strb = 'bbbb'
+        numb = sys.getrefcount(strb)
+        numa = sys.getrefcount(stra)
+        x = np.array([[(0, stra), (1, strb)]], 'i8,O')
+        x[x.nonzero()] = x.ravel()[:1]
+        assert_(sys.getrefcount(strb) == numb)
+        assert_(sys.getrefcount(stra) == numa + 2)
+
+    def test_duplicate_title_and_name(self):
+        # Ticket #1254
+        dtspec = [(('a', 'a'), 'i'), ('b', 'i')]
+        self.assertRaises(ValueError, np.dtype, dtspec)
+
+    def test_signed_integer_division_overflow(self):
+        # Ticket #1317.
+        def test_type(t):
+            min = np.array([np.iinfo(t).min])
+            min //= -1
+
+        with np.errstate(divide="ignore"):
+            for t in (np.int8, np.int16, np.int32, np.int64, np.int, np.long):
+                test_type(t)
+
+    def test_buffer_hashlib(self):
+        try:
+            from hashlib import md5
+        except ImportError:
+            from md5 import new as md5
+
+        x = np.array([1, 2, 3], dtype=np.dtype('<i4'))
+        assert_equal(md5(x).hexdigest(), '2a1dd1e1e59d0a384c26951e316cd7e6')
+
+    def test_0d_string_scalar(self):
+        # Bug #1436; the following should succeed
+        np.asarray('x', '>c')
+
+    def test_log1p_compiler_shenanigans(self):
+        # Check if log1p is behaving on 32 bit intel systems.
+        assert_(np.isfinite(np.log1p(np.exp2(-53))))
+
+    def test_fromiter_comparison(self, level=rlevel):
+        a = np.fromiter(list(range(10)), dtype='b')
+        b = np.fromiter(list(range(10)), dtype='B')
+        assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+        assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+
+    def test_fromstring_crash(self):
+        # Ticket #1345: the following should not cause a crash
+        np.fromstring(asbytes('aa, aa, 1.0'), sep=',')
+
+    def test_ticket_1539(self):
+        dtypes = [x for x in np.typeDict.values()
+                  if (issubclass(x, np.number)
+                      and not issubclass(x, np.timedelta64))]
+        a = np.array([], dtypes[0])
+        failures = []
+        # ignore complex warnings
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', np.ComplexWarning)
+            for x in dtypes:
+                b = a.astype(x)
+                for y in dtypes:
+                    c = a.astype(y)
+                    try:
+                        np.dot(b, c)
+                    except TypeError:
+                        failures.append((x, y))
+        if failures:
+            raise AssertionError("Failures: %r" % failures)
+
+    def test_ticket_1538(self):
+        x = np.finfo(np.float32)
+        for name in 'eps epsneg max min resolution tiny'.split():
+            assert_equal(type(getattr(x, name)), np.float32,
+                         err_msg=name)
+
+    def test_ticket_1434(self):
+        # Check that the out= argument in var and std has an effect
+        data = np.array(((1, 2, 3), (4, 5, 6), (7, 8, 9)))
+        out = np.zeros((3,))
+
+        ret = data.var(axis=1, out=out)
+        assert_(ret is out)
+        assert_array_equal(ret, data.var(axis=1))
+
+        ret = data.std(axis=1, out=out)
+        assert_(ret is out)
+        assert_array_equal(ret, data.std(axis=1))
+
+    def test_complex_nan_maximum(self):
+        cnan = complex(0, np.nan)
+        assert_equal(np.maximum(1, cnan), cnan)
+
+    def test_subclass_int_tuple_assignment(self):
+        # ticket #1563
+        class Subclass(np.ndarray):
+            def __new__(cls, i):
+                return np.ones((i,)).view(cls)
+
+        x = Subclass(5)
+        x[(0,)] = 2  # shouldn't raise an exception
+        assert_equal(x[0], 2)
+
+    def test_ufunc_no_unnecessary_views(self):
+        # ticket #1548
+        class Subclass(np.ndarray):
+            pass
+        x = np.array([1, 2, 3]).view(Subclass)
+        y = np.add(x, x, x)
+        assert_equal(id(x), id(y))
+
+    def test_take_refcount(self):
+        # ticket #939
+        a = np.arange(16, dtype=np.float)
+        a.shape = (4, 4)
+        lut = np.ones((5 + 3, 4), np.float)
+        rgba = np.empty(shape=a.shape + (4,), dtype=lut.dtype)
+        c1 = sys.getrefcount(rgba)
+        try:
+            lut.take(a, axis=0, mode='clip', out=rgba)
+        except TypeError:
+            pass
+        c2 = sys.getrefcount(rgba)
+        assert_equal(c1, c2)
+
+    def test_fromfile_tofile_seeks(self):
+        # On Python 3, tofile/fromfile used to get (#1610) the Python
+        # file handle out of sync
+        f0 = tempfile.NamedTemporaryFile()
+        f = f0.file
+        f.write(np.arange(255, dtype='u1').tobytes())
+
+        f.seek(20)
+        ret = np.fromfile(f, count=4, dtype='u1')
+        assert_equal(ret, np.array([20, 21, 22, 23], dtype='u1'))
+        assert_equal(f.tell(), 24)
+
+        f.seek(40)
+        np.array([1, 2, 3], dtype='u1').tofile(f)
+        assert_equal(f.tell(), 43)
+
+        f.seek(40)
+        data = f.read(3)
+        assert_equal(data, asbytes("\x01\x02\x03"))
+
+        f.seek(80)
+        f.read(4)
+        data = np.fromfile(f, dtype='u1', count=4)
+        assert_equal(data, np.array([84, 85, 86, 87], dtype='u1'))
+
+        f.close()
+
+    def test_complex_scalar_warning(self):
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = tp(1+2j)
+            assert_warns(np.ComplexWarning, float, x)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                assert_equal(float(x), float(x.real))
+
+    def test_complex_scalar_complex_cast(self):
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = tp(1+2j)
+            assert_equal(complex(x), 1+2j)
+
+    def test_complex_boolean_cast(self):
+        # Ticket #2218
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = np.array([0, 0+0.5j, 0.5+0j], dtype=tp)
+            assert_equal(x.astype(bool), np.array([0, 1, 1], dtype=bool))
+            assert_(np.any(x))
+            assert_(np.all(x[1:]))
+
+    def test_uint_int_conversion(self):
+        x = 2**64 - 1
+        assert_equal(int(np.uint64(x)), x)
+
+    def test_duplicate_field_names_assign(self):
+        ra = np.fromiter(((i*3, i*2) for i in range(10)), dtype='i8,f8')
+        ra.dtype.names = ('f1', 'f2')
+        repr(ra)  # should not cause a segmentation fault
+        assert_raises(ValueError, setattr, ra.dtype, 'names', ('f1', 'f1'))
+
+    def test_eq_string_and_object_array(self):
+        # From e-mail thread "__eq__ with str and object" (Keith Goodman)
+        a1 = np.array(['a', 'b'], dtype=object)
+        a2 = np.array(['a', 'c'])
+        assert_array_equal(a1 == a2, [True, False])
+        assert_array_equal(a2 == a1, [True, False])
+
+    def test_nonzero_byteswap(self):
+        a = np.array([0x80000000, 0x00000080, 0], dtype=np.uint32)
+        a.dtype = np.float32
+        assert_equal(a.nonzero()[0], [1])
+        a = a.byteswap().newbyteorder()
+        assert_equal(a.nonzero()[0], [1])  # [0] if nonzero() ignores swap
+
+    def test_find_common_type_boolean(self):
+        # Ticket #1695
+        assert_(np.find_common_type([], ['?', '?']) == '?')
+
+    def test_empty_mul(self):
+        a = np.array([1.])
+        a[1:1] *= 2
+        assert_equal(a, [1.])
+
+    def test_array_side_effect(self):
+        # The second use of itemsize was throwing an exception because in
+        # ctors.c, discover_itemsize was calling PyObject_Length without
+        # checking the return code.  This failed to get the length of the
+        # number 2, and the exception hung around until something checked
+        # PyErr_Occurred() and returned an error.
+        assert_equal(np.dtype('S10').itemsize, 10)
+        np.array([['abc', 2], ['long   ', '0123456789']], dtype=np.string_)
+        assert_equal(np.dtype('S10').itemsize, 10)
+
+    def test_any_float(self):
+        # all and any for floats
+        a = np.array([0.1, 0.9])
+        assert_(np.any(a))
+        assert_(np.all(a))
+
+    def test_large_float_sum(self):
+        a = np.arange(10000, dtype='f')
+        assert_equal(a.sum(dtype='d'), a.astype('d').sum())
+
+    def test_ufunc_casting_out(self):
+        a = np.array(1.0, dtype=np.float32)
+        b = np.array(1.0, dtype=np.float64)
+        c = np.array(1.0, dtype=np.float32)
+        np.add(a, b, out=c)
+        assert_equal(c, 2.0)
+
+    def test_array_scalar_contiguous(self):
+        # Array scalars are both C and Fortran contiguous
+        assert_(np.array(1.0).flags.c_contiguous)
+        assert_(np.array(1.0).flags.f_contiguous)
+        assert_(np.array(np.float32(1.0)).flags.c_contiguous)
+        assert_(np.array(np.float32(1.0)).flags.f_contiguous)
+
+    def test_squeeze_contiguous(self):
+        # Similar to GitHub issue #387
+        a = np.zeros((1, 2)).squeeze()
+        b = np.zeros((2, 2, 2), order='F')[:,:, ::2].squeeze()
+        assert_(a.flags.c_contiguous)
+        assert_(a.flags.f_contiguous)
+        assert_(b.flags.f_contiguous)
+
+    def test_reduce_contiguous(self):
+        # GitHub issue #387
+        a = np.add.reduce(np.zeros((2, 1, 2)), (0, 1))
+        b = np.add.reduce(np.zeros((2, 1, 2)), 1)
+        assert_(a.flags.c_contiguous)
+        assert_(a.flags.f_contiguous)
+        assert_(b.flags.c_contiguous)
+
+    def test_object_array_self_reference(self):
+        # Object arrays with references to themselves can cause problems
+        a = np.array(0, dtype=object)
+        a[()] = a
+        assert_raises(TypeError, int, a)
+        assert_raises(TypeError, long, a)
+        assert_raises(TypeError, float, a)
+        assert_raises(TypeError, oct, a)
+        assert_raises(TypeError, hex, a)
+
+        # Test the same for a circular reference.
+        b = np.array(a, dtype=object)
+        a[()] = b
+        assert_raises(TypeError, int, a)
+        # Numpy has no tp_traverse currently, so circular references
+        # cannot be detected. So resolve it:
+        a[()] = 0
+
+        # This was causing a to become like the above
+        a = np.array(0, dtype=object)
+        a[...] += 1
+        assert_equal(a, 1)
+
+    def test_object_array_self_copy(self):
+        # An object array being copied into itself DECREF'ed before INCREF'ing
+        # causing segmentation faults (gh-3787)
+        a = np.array(object(), dtype=object)
+        np.copyto(a, a)
+        assert_equal(sys.getrefcount(a[()]), 2)
+        a[()].__class__  # will segfault if object was deleted
+
+    def test_zerosize_accumulate(self):
+        "Ticket #1733"
+        x = np.array([[42, 0]], dtype=np.uint32)
+        assert_equal(np.add.accumulate(x[:-1, 0]), [])
+
+    def test_objectarray_setfield(self):
+        # Setfield should not overwrite Object fields with non-Object data
+        x = np.array([1, 2, 3], dtype=object)
+        assert_raises(TypeError, x.setfield, 4, np.int32, 0)
+
+    def test_setting_rank0_string(self):
+        "Ticket #1736"
+        s1 = asbytes("hello1")
+        s2 = asbytes("hello2")
+        a = np.zeros((), dtype="S10")
+        a[()] = s1
+        assert_equal(a, np.array(s1))
+        a[()] = np.array(s2)
+        assert_equal(a, np.array(s2))
+
+        a = np.zeros((), dtype='f4')
+        a[()] = 3
+        assert_equal(a, np.array(3))
+        a[()] = np.array(4)
+        assert_equal(a, np.array(4))
+
+    def test_string_astype(self):
+        "Ticket #1748"
+        s1 = asbytes('black')
+        s2 = asbytes('white')
+        s3 = asbytes('other')
+        a = np.array([[s1], [s2], [s3]])
+        assert_equal(a.dtype, np.dtype('S5'))
+        b = a.astype(np.dtype('S0'))
+        assert_equal(b.dtype, np.dtype('S5'))
+
+    def test_ticket_1756(self):
+        # Ticket #1756
+        s = asbytes('0123456789abcdef')
+        a = np.array([s]*5)
+        for i in range(1, 17):
+            a1 = np.array(a, "|S%d" % i)
+            a2 = np.array([s[:i]]*5)
+            assert_equal(a1, a2)
+
+    def test_fields_strides(self):
+        "Ticket #1760"
+        r = np.fromstring('abcdefghijklmnop'*4*3, dtype='i4,(2,3)u2')
+        assert_equal(r[0:3:2]['f1'], r['f1'][0:3:2])
+        assert_equal(r[0:3:2]['f1'][0], r[0:3:2][0]['f1'])
+        assert_equal(r[0:3:2]['f1'][0][()], r[0:3:2][0]['f1'][()])
+        assert_equal(r[0:3:2]['f1'][0].strides, r[0:3:2][0]['f1'].strides)
+
+    def test_alignment_update(self):
+        # Check that alignment flag is updated on stride setting
+        a = np.arange(10)
+        assert_(a.flags.aligned)
+        a.strides = 3
+        assert_(not a.flags.aligned)
+
+    def test_ticket_1770(self):
+        "Should not segfault on python 3k"
+        import numpy as np
+        try:
+            a = np.zeros((1,), dtype=[('f1', 'f')])
+            a['f1'] = 1
+            a['f2'] = 1
+        except ValueError:
+            pass
+        except:
+            raise AssertionError
+
+    def test_ticket_1608(self):
+        "x.flat shouldn't modify data"
+        x = np.array([[1, 2], [3, 4]]).T
+        np.array(x.flat)
+        assert_equal(x, [[1, 3], [2, 4]])
+
+    def test_pickle_string_overwrite(self):
+        import re
+
+        data = np.array([1], dtype='b')
+        blob = pickle.dumps(data, protocol=1)
+        data = pickle.loads(blob)
+
+        # Check that loads does not clobber interned strings
+        s = re.sub("a(.)", "\x01\\1", "a_")
+        assert_equal(s[0], "\x01")
+        data[0] = 0xbb
+        s = re.sub("a(.)", "\x01\\1", "a_")
+        assert_equal(s[0], "\x01")
+
+    def test_pickle_bytes_overwrite(self):
+        if sys.version_info[0] >= 3:
+            data = np.array([1], dtype='b')
+            data = pickle.loads(pickle.dumps(data))
+            data[0] = 0xdd
+            bytestring = "\x01  ".encode('ascii')
+            assert_equal(bytestring[0:1], '\x01'.encode('ascii'))
+
+    def test_pickle_py2_array_latin1_hack(self):
+        # Check that unpickling hacks in Py3 that support
+        # encoding='latin1' work correctly.
+
+        # Python2 output for pickle.dumps(numpy.array([129], dtype='b'))
+        data = asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\n"
+                       "tp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'i1'\np8\n"
+                       "I0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x81'\n"
+                       "p13\ntp14\nb.")
+        if sys.version_info[0] >= 3:
+            # This should work:
+            result = pickle.loads(data, encoding='latin1')
+            assert_array_equal(result, np.array([129], dtype='b'))
+            # Should not segfault:
+            assert_raises(Exception, pickle.loads, data, encoding='koi8-r')
+
+    def test_pickle_py2_scalar_latin1_hack(self):
+        # Check that scalar unpickling hack in Py3 that supports
+        # encoding='latin1' work correctly.
+
+        # Python2 output for pickle.dumps(...)
+        datas = [
+            # (original, python2_pickle, koi8r_validity)
+            (np.unicode_('\u6bd2'),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+                     "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\nI0\n"
+                     "tp6\nbS'\\xd2k\\x00\\x00'\np7\ntp8\nRp9\n."),
+             'invalid'),
+
+            (np.float64(9e123),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'f8'\n"
+                     "p2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI-1\nI-1\nI0\ntp6\n"
+                     "bS'O\\x81\\xb7Z\\xaa:\\xabY'\np7\ntp8\nRp9\n."),
+             'invalid'),
+
+            (np.bytes_(asbytes('\x9c')),  # different 8-bit code point in KOI8-R vs latin1
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'S1'\np2\n"
+                     "I0\nI1\ntp3\nRp4\n(I3\nS'|'\np5\nNNNI1\nI1\nI0\ntp6\nbS'\\x9c'\np7\n"
+                     "tp8\nRp9\n."),
+             'different'),
+        ]
+        if sys.version_info[0] >= 3:
+            for original, data, koi8r_validity in datas:
+                result = pickle.loads(data, encoding='latin1')
+                assert_equal(result, original)
+
+                # Decoding under non-latin1 encoding (e.g.) KOI8-R can
+                # produce bad results, but should not segfault.
+                if koi8r_validity == 'different':
+                    # Unicode code points happen to lie within latin1,
+                    # but are different in koi8-r, resulting to silent
+                    # bogus results
+                    result = pickle.loads(data, encoding='koi8-r')
+                    assert_(result != original)
+                elif koi8r_validity == 'invalid':
+                    # Unicode code points outside latin1, so results
+                    # to an encoding exception
+                    assert_raises(ValueError, pickle.loads, data, encoding='koi8-r')
+                else:
+                    raise ValueError(koi8r_validity)
+
+    def test_structured_type_to_object(self):
+        a_rec = np.array([(0, 1), (3, 2)], dtype='i4,i8')
+        a_obj = np.empty((2,), dtype=object)
+        a_obj[0] = (0, 1)
+        a_obj[1] = (3, 2)
+        # astype records -> object
+        assert_equal(a_rec.astype(object), a_obj)
+        # '=' records -> object
+        b = np.empty_like(a_obj)
+        b[...] = a_rec
+        assert_equal(b, a_obj)
+        # '=' object -> records
+        b = np.empty_like(a_rec)
+        b[...] = a_obj
+        assert_equal(b, a_rec)
+
+    def test_assign_obj_listoflists(self):
+        # Ticket # 1870
+        # The inner list should get assigned to the object elements
+        a = np.zeros(4, dtype=object)
+        b = a.copy()
+        a[0] = [1]
+        a[1] = [2]
+        a[2] = [3]
+        a[3] = [4]
+        b[...] = [[1], [2], [3], [4]]
+        assert_equal(a, b)
+        # The first dimension should get broadcast
+        a = np.zeros((2, 2), dtype=object)
+        a[...] = [[1, 2]]
+        assert_equal(a, [[1, 2], [1, 2]])
+
+    def test_memoryleak(self):
+        # Ticket #1917 - ensure that array data doesn't leak
+        for i in range(1000):
+            # 100MB times 1000 would give 100GB of memory usage if it leaks
+            a = np.empty((100000000,), dtype='i1')
+            del a
+
+    def test_ufunc_reduce_memoryleak(self):
+        a = np.arange(6)
+        acnt = sys.getrefcount(a)
+        np.add.reduce(a)
+        assert_equal(sys.getrefcount(a), acnt)
+
+    def test_search_sorted_invalid_arguments(self):
+        # Ticket #2021, should not segfault.
+        x = np.arange(0, 4, dtype='datetime64[D]')
+        assert_raises(TypeError, x.searchsorted, 1)
+
+    def test_string_truncation(self):
+        # Ticket #1990 - Data can be truncated in creation of an array from a
+        # mixed sequence of numeric values and strings
+        for val in [True, 1234, 123.4, complex(1, 234)]:
+            for tostr in [asunicode, asbytes]:
+                b = np.array([val, tostr('xx')])
+                assert_equal(tostr(b[0]), tostr(val))
+                b = np.array([tostr('xx'), val])
+                assert_equal(tostr(b[1]), tostr(val))
+
+                # test also with longer strings
+                b = np.array([val, tostr('xxxxxxxxxx')])
+                assert_equal(tostr(b[0]), tostr(val))
+                b = np.array([tostr('xxxxxxxxxx'), val])
+                assert_equal(tostr(b[1]), tostr(val))
+
+    def test_string_truncation_ucs2(self):
+        # Ticket #2081. Python compiled with two byte unicode
+        # can lead to truncation if itemsize is not properly
+        # adjusted for Numpy's four byte unicode.
+        if sys.version_info[0] >= 3:
+            a = np.array(['abcd'])
+        else:
+            a = np.array([sixu('abcd')])
+        assert_equal(a.dtype.itemsize, 16)
+
+    def test_unique_stable(self):
+        # Ticket #2063 must always choose stable sort for argsort to
+        # get consistent results
+        v = np.array(([0]*5 + [1]*6 + [2]*6)*4)
+        res = np.unique(v, return_index=True)
+        tgt = (np.array([0, 1, 2]), np.array([ 0,  5, 11]))
+        assert_equal(res, tgt)
+
+    def test_unicode_alloc_dealloc_match(self):
+        # Ticket #1578, the mismatch only showed up when running
+        # python-debug for python versions >= 2.7, and then as
+        # a core dump and error message.
+        a = np.array(['abc'], dtype=np.unicode)[0]
+        del a
+
+    def test_refcount_error_in_clip(self):
+        # Ticket #1588
+        a = np.zeros((2,), dtype='>i2').clip(min=0)
+        x = a + a
+        # This used to segfault:
+        y = str(x)
+        # Check the final string:
+        assert_(y == "[0 0]")
+
+    def test_searchsorted_wrong_dtype(self):
+        # Ticket #2189, it used to segfault, so we check that it raises the
+        # proper exception.
+        a = np.array([('a', 1)], dtype='S1, int')
+        assert_raises(TypeError, np.searchsorted, a, 1.2)
+        # Ticket #2066, similar problem:
+        dtype = np.format_parser(['i4', 'i4'], [], [])
+        a = np.recarray((2, ), dtype)
+        assert_raises(TypeError, np.searchsorted, a, 1)
+
+    def test_complex64_alignment(self):
+        # Issue gh-2668 (trac 2076), segfault on sparc due to misalignment
+        dtt = np.complex64
+        arr = np.arange(10, dtype=dtt)
+        # 2D array
+        arr2 = np.reshape(arr, (2, 5))
+        # Fortran write followed by (C or F) read caused bus error
+        data_str = arr2.tobytes('F')
+        data_back = np.ndarray(arr2.shape,
+                              arr2.dtype,
+                              buffer=data_str,
+                              order='F')
+        assert_array_equal(arr2, data_back)
+
+    def test_structured_count_nonzero(self):
+        arr = np.array([0, 1]).astype('i4, (2)i4')[:1]
+        count = np.count_nonzero(arr)
+        assert_equal(count, 0)
+
+    def test_copymodule_preserves_f_contiguity(self):
+        a = np.empty((2, 2), order='F')
+        b = copy.copy(a)
+        c = copy.deepcopy(a)
+        assert_(b.flags.fortran)
+        assert_(b.flags.f_contiguous)
+        assert_(c.flags.fortran)
+        assert_(c.flags.f_contiguous)
+
+    def test_fortran_order_buffer(self):
+        import numpy as np
+        a = np.array([['Hello', 'Foob']], dtype='U5', order='F')
+        arr = np.ndarray(shape=[1, 2, 5], dtype='U1', buffer=a)
+        arr2 = np.array([[[sixu('H'), sixu('e'), sixu('l'), sixu('l'), sixu('o')],
+                          [sixu('F'), sixu('o'), sixu('o'), sixu('b'), sixu('')]]])
+        assert_array_equal(arr, arr2)
+
+    def test_assign_from_sequence_error(self):
+        # Ticket #4024.
+        arr = np.array([1, 2, 3])
+        assert_raises(ValueError, arr.__setitem__, slice(None), [9, 9])
+        arr.__setitem__(slice(None), [9])
+        assert_equal(arr, [9, 9, 9])
+
+    def test_format_on_flex_array_element(self):
+        # Ticket #4369.
+        dt = np.dtype([('date', '<M8[D]'), ('val', '<f8')])
+        arr = np.array([('2000-01-01', 1)], dt)
+        formatted = '{0}'.format(arr[0])
+        assert_equal(formatted, str(arr[0]))
+
+    def test_deepcopy_on_0d_array(self):
+        # Ticket #3311.
+        arr = np.array(3)
+        arr_cp = copy.deepcopy(arr)
+
+        assert_equal(arr, arr_cp)
+        assert_equal(arr.shape, arr_cp.shape)
+        assert_equal(int(arr), int(arr_cp))
+        self.assertTrue(arr is not arr_cp)
+        self.assertTrue(isinstance(arr_cp, type(arr)))
+
+    def test_bool_subscript_crash(self):
+        # gh-4494
+        c = np.rec.array([(1, 2, 3), (4, 5, 6)])
+        masked = c[np.array([True, False])]
+        base = masked.base
+        del masked, c
+        base.dtype
+
+    def test_richcompare_crash(self):
+        # gh-4613
+        import operator as op
+
+        # dummy class where __array__ throws exception
+        class Foo(object):
+            __array_priority__ = 1002
+
+            def __array__(self,*args,**kwargs):
+                raise Exception()
+
+        rhs = Foo()
+        lhs = np.array(1)
+        for f in [op.lt, op.le, op.gt, op.ge]:
+            if sys.version_info[0] >= 3:
+                assert_raises(TypeError, f, lhs, rhs)
+            else:
+                f(lhs, rhs)
+        assert_(not op.eq(lhs, rhs))
+        assert_(op.ne(lhs, rhs))
+
+    def test_richcompare_scalar_and_subclass(self):
+        # gh-4709
+        class Foo(np.ndarray):
+            def __eq__(self, other):
+                return "OK"
+
+        x = np.array([1,2,3]).view(Foo)
+        assert_equal(10 == x, "OK")
+        assert_equal(np.int32(10) == x, "OK")
+        assert_equal(np.array([10]) == x, "OK")
+
+    def test_pickle_empty_string(self):
+        # gh-3926
+
+        import pickle
+        test_string = np.string_('')
+        assert_equal(pickle.loads(pickle.dumps(test_string)), test_string)
+
+    def test_frompyfunc_many_args(self):
+        # gh-5672
+
+        def passer(*args):
+            pass
+
+        assert_raises(ValueError, np.frompyfunc, passer, 32, 1)
+
+    def test_repeat_broadcasting(self):
+        # gh-5743
+        a = np.arange(60).reshape(3, 4, 5)
+        for axis in chain(range(-a.ndim, a.ndim), [None]):
+            assert_equal(a.repeat(2, axis=axis), a.repeat([2], axis=axis))
+
+    def test_frompyfunc_nout_0(self):
+        # gh-2014
+
+        def f(x):
+            x[0], x[-1] = x[-1], x[0]
+
+        uf = np.frompyfunc(f, 1, 0)
+        a = np.array([[1, 2, 3], [4, 5], [6, 7, 8, 9]])
+        assert_equal(uf(a), ())
+        assert_array_equal(a, [[3, 2, 1], [5, 4], [9, 7, 8, 6]])
+
+    def test_leak_in_structured_dtype_comparison(self):
+        # gh-6250
+        recordtype = np.dtype([('a', np.float64),
+                               ('b', np.int32),
+                               ('d', (np.str, 5))])
+
+        # Simple case
+        a = np.zeros(2, dtype=recordtype)
+        for i in range(100):
+            a == a
+        assert_(sys.getrefcount(a) < 10)
+
+        # The case in the bug report.
+        before = sys.getrefcount(a)
+        u, v = a[0], a[1]
+        u == v
+        del u, v
+        gc.collect()
+        after = sys.getrefcount(a)
+        assert_equal(before, after)
+
+    def test_empty_percentile(self):
+        # gh-6530 / gh-6553
+        assert_array_equal(np.percentile(np.arange(10), []), np.array([]))
+
+    def test_void_compare_segfault(self):
+        # gh-6922. The following should not segfault
+        a = np.ones(3, dtype=[('object', 'O'), ('int', '<i2')])
+        a.sort()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
new file mode 100644
index 0000000000..e8cf7fde00
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+""" Test printing of scalar types.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+class A(object):
+    pass
+class B(A, np.float64):
+    pass
+
+class C(B):
+    pass
+class D(C, B):
+    pass
+
+class B0(np.float64, A):
+    pass
+class C0(B0):
+    pass
+
+class TestInherit(TestCase):
+    def test_init(self):
+        x = B(1.0)
+        assert_(str(x) == '1.0')
+        y = C(2.0)
+        assert_(str(y) == '2.0')
+        z = D(3.0)
+        assert_(str(z) == '3.0')
+
+    def test_init2(self):
+        x = B0(1.0)
+        assert_(str(x) == '1.0')
+        y = C0(2.0)
+        assert_(str(y) == '2.0')
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
new file mode 100644
index 0000000000..12b1a0fe33
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
@@ -0,0 +1,473 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import warnings
+import operator
+
+import numpy as np
+from numpy.testing.utils import _gen_alignment_data
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_almost_equal, assert_allclose
+)
+
+types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
+         np.int_, np.uint, np.longlong, np.ulonglong,
+         np.single, np.double, np.longdouble, np.csingle,
+         np.cdouble, np.clongdouble]
+
+floating_types = np.floating.__subclasses__()
+
+
+# This compares scalarmath against ufuncs.
+
+class TestTypes(TestCase):
+    def test_types(self, level=1):
+        for atype in types:
+            a = atype(1)
+            assert_(a == 1, "error with %r: got %r" % (atype, a))
+
+    def test_type_add(self, level=1):
+        # list of types
+        for k, atype in enumerate(types):
+            a_scalar = atype(3)
+            a_array = np.array([3], dtype=atype)
+            for l, btype in enumerate(types):
+                b_scalar = btype(1)
+                b_array = np.array([1], dtype=btype)
+                c_scalar = a_scalar + b_scalar
+                c_array = a_array + b_array
+                # It was comparing the type numbers, but the new ufunc
+                # function-finding mechanism finds the lowest function
+                # to which both inputs can be cast - which produces 'l'
+                # when you do 'q' + 'b'.  The old function finding mechanism
+                # skipped ahead based on the first argument, but that
+                # does not produce properly symmetric results...
+                assert_equal(c_scalar.dtype, c_array.dtype,
+                           "error with types (%d/'%c' + %d/'%c')" %
+                            (k, np.dtype(atype).char, l, np.dtype(btype).char))
+
+    def test_type_create(self, level=1):
+        for k, atype in enumerate(types):
+            a = np.array([1, 2, 3], atype)
+            b = atype([1, 2, 3])
+            assert_equal(a, b)
+
+    def test_leak(self):
+        # test leak of scalar objects
+        # a leak would show up in valgrind as still-reachable of ~2.6MB
+        for i in range(200000):
+            np.add(1, 1)
+
+
+class TestBaseMath(TestCase):
+    def test_blocked(self):
+        # test alignments offsets for simd instructions
+        # alignments for vz + 2 * (vs - 1) + 1
+        for dt, sz in [(np.float32, 11), (np.float64, 7)]:
+            for out, inp1, inp2, msg in _gen_alignment_data(dtype=dt,
+                                                            type='binary',
+                                                            max_size=sz):
+                exp1 = np.ones_like(inp1)
+                inp1[...] = np.ones_like(inp1)
+                inp2[...] = np.zeros_like(inp2)
+                assert_almost_equal(np.add(inp1, inp2), exp1, err_msg=msg)
+                assert_almost_equal(np.add(inp1, 1), exp1 + 1, err_msg=msg)
+                assert_almost_equal(np.add(1, inp2), exp1, err_msg=msg)
+
+                np.add(inp1, inp2, out=out)
+                assert_almost_equal(out, exp1, err_msg=msg)
+
+                inp2[...] += np.arange(inp2.size, dtype=dt) + 1
+                assert_almost_equal(np.square(inp2),
+                                    np.multiply(inp2, inp2),  err_msg=msg)
+                assert_almost_equal(np.reciprocal(inp2),
+                                    np.divide(1, inp2),  err_msg=msg)
+
+                inp1[...] = np.ones_like(inp1)
+                inp2[...] = np.zeros_like(inp2)
+                np.add(inp1, 1, out=out)
+                assert_almost_equal(out, exp1 + 1, err_msg=msg)
+                np.add(1, inp2, out=out)
+                assert_almost_equal(out, exp1, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_almost_equal(d + d, d * 2)
+        np.add(d, d, out=o)
+        np.add(np.ones_like(d), d, out=o)
+        np.add(d, np.ones_like(d), out=o)
+        np.add(np.ones_like(d), d)
+        np.add(d, np.ones_like(d))
+
+
+class TestPower(TestCase):
+    def test_small_types(self):
+        for t in [np.int8, np.int16, np.float16]:
+            a = t(3)
+            b = a ** 4
+            assert_(b == 81, "error with %r: got %r" % (t, b))
+
+    def test_large_types(self):
+        for t in [np.int32, np.int64, np.float32, np.float64, np.longdouble]:
+            a = t(51)
+            b = a ** 4
+            msg = "error with %r: got %r" % (t, b)
+            if np.issubdtype(t, np.integer):
+                assert_(b == 6765201, msg)
+            else:
+                assert_almost_equal(b, 6765201, err_msg=msg)
+
+    def test_mixed_types(self):
+        typelist = [np.int8, np.int16, np.float16,
+                    np.float32, np.float64, np.int8,
+                    np.int16, np.int32, np.int64]
+        for t1 in typelist:
+            for t2 in typelist:
+                a = t1(3)
+                b = t2(2)
+                result = a**b
+                msg = ("error with %r and %r:"
+                       "got %r, expected %r") % (t1, t2, result, 9)
+                if np.issubdtype(np.dtype(result), np.integer):
+                    assert_(result == 9, msg)
+                else:
+                    assert_almost_equal(result, 9, err_msg=msg)
+
+
+class TestModulus(TestCase):
+
+    floordiv = operator.floordiv
+    mod = operator.mod
+
+    def test_modulus_basic(self):
+        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                if sg1 == -1 and dt1 in np.typecodes['UnsignedInteger']:
+                    continue
+                if sg2 == -1 and dt2 in np.typecodes['UnsignedInteger']:
+                    continue
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*71, dtype=dt1)[()]
+                b = np.array(sg2*19, dtype=dt2)[()]
+                div = self.floordiv(a, b)
+                rem = self.mod(a, b)
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_modulus_exact(self):
+        # test that float results are exact for small integers. This also
+        # holds for the same integers scaled by powers of two.
+        nlst = list(range(-127, 0))
+        plst = list(range(1, 128))
+        dividend = nlst + [0] + plst
+        divisor = nlst + plst
+        arg = list(itertools.product(dividend, divisor))
+        tgt = list(divmod(*t) for t in arg)
+
+        a, b = np.array(arg, dtype=int).T
+        # convert exact integer results from Python to float so that
+        # signed zero can be used, it is checked.
+        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
+        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
+        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
+
+        for dt in np.typecodes['Float']:
+            msg = 'dtype: %s' % (dt,)
+            fa = a.astype(dt)
+            fb = b.astype(dt)
+            # use list comprehension so a_ and b_ are scalars
+            div = [self.floordiv(a_, b_) for  a_, b_ in zip(fa, fb)]
+            rem = [self.mod(a_, b_) for a_, b_ in zip(fa, fb)]
+            assert_equal(div, tgtdiv, err_msg=msg)
+            assert_equal(rem, tgtrem, err_msg=msg)
+
+    def test_float_modulus_roundoff(self):
+        # gh-6127
+        dt = np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*78*6e-8, dtype=dt1)[()]
+                b = np.array(sg2*6e-8, dtype=dt2)[()]
+                div = self.floordiv(a, b)
+                rem = self.mod(a, b)
+                # Equal assertion should hold when fmod is used
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_modulus_corner_cases(self):
+        # Check remainder magnitude.
+        for dt in np.typecodes['Float']:
+            b = np.array(1.0, dtype=dt)
+            a = np.nextafter(np.array(0.0, dtype=dt), -b)
+            rem = self.mod(a, b)
+            assert_(rem <= b, 'dt: %s' % dt)
+            rem = self.mod(-a, -b)
+            assert_(rem >= -b, 'dt: %s' % dt)
+
+        # Check nans, inf
+        with warnings.catch_warnings():
+            warnings.simplefilter('always')
+            warnings.simplefilter('ignore', RuntimeWarning)
+            for dt in np.typecodes['Float']:
+                fone = np.array(1.0, dtype=dt)
+                fzer = np.array(0.0, dtype=dt)
+                finf = np.array(np.inf, dtype=dt)
+                fnan = np.array(np.nan, dtype=dt)
+                rem = self.mod(fone, fzer)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+                # MSVC 2008 returns NaN here, so disable the check.
+                #rem = self.mod(fone, finf)
+                #assert_(rem == fone, 'dt: %s' % dt)
+                rem = self.mod(fone, fnan)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+                rem = self.mod(finf, fone)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+
+
+class TestComplexDivision(TestCase):
+    def test_zero_division(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                a = t(0.0)
+                b = t(1.0)
+                assert_(np.isinf(b/a))
+                b = t(complex(np.inf, np.inf))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.inf, np.nan))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.nan, np.inf))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.nan, np.nan))
+                assert_(np.isnan(b/a))
+                b = t(0.)
+                assert_(np.isnan(b/a))
+
+    def test_signed_zeros(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                # tupled (numerator, denominator, expected)
+                # for testing as expected == numerator/denominator
+                data = (
+                    (( 0.0,-1.0), ( 0.0, 1.0), (-1.0,-0.0)),
+                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    (( 0.0,-1.0), (-0.0,-1.0), ( 1.0, 0.0)),
+                    (( 0.0,-1.0), (-0.0, 1.0), (-1.0, 0.0)),
+                    (( 0.0, 1.0), ( 0.0,-1.0), (-1.0, 0.0)),
+                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    ((-0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    ((-0.0, 1.0), ( 0.0,-1.0), (-1.0,-0.0))
+                )
+                for cases in data:
+                    n = cases[0]
+                    d = cases[1]
+                    ex = cases[2]
+                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
+                    # check real and imag parts separately to avoid comparison
+                    # in array context, which does not account for signed zeros
+                    assert_equal(result.real, ex[0])
+                    assert_equal(result.imag, ex[1])
+
+    def test_branches(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                # tupled (numerator, denominator, expected)
+                # for testing as expected == numerator/denominator
+                data = list()
+
+                # trigger branch: real(fabs(denom)) > imag(fabs(denom))
+                # followed by else condition as neither are == 0
+                data.append((( 2.0, 1.0), ( 2.0, 1.0), (1.0, 0.0)))
+
+                # trigger branch: real(fabs(denom)) > imag(fabs(denom))
+                # followed by if condition as both are == 0
+                # is performed in test_zero_division(), so this is skipped
+
+                # trigger else if branch: real(fabs(denom)) < imag(fabs(denom))
+                data.append((( 1.0, 2.0), ( 1.0, 2.0), (1.0, 0.0)))
+
+                for cases in data:
+                    n = cases[0]
+                    d = cases[1]
+                    ex = cases[2]
+                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
+                    # check real and imag parts separately to avoid comparison
+                    # in array context, which does not account for signed zeros
+                    assert_equal(result.real, ex[0])
+                    assert_equal(result.imag, ex[1])
+
+
+class TestConversion(TestCase):
+    def test_int_from_long(self):
+        l = [1e6, 1e12, 1e18, -1e6, -1e12, -1e18]
+        li = [10**6, 10**12, 10**18, -10**6, -10**12, -10**18]
+        for T in [None, np.float64, np.int64]:
+            a = np.array(l, dtype=T)
+            assert_equal([int(_m) for _m in a], li)
+
+        a = np.array(l[:3], dtype=np.uint64)
+        assert_equal([int(_m) for _m in a], li[:3])
+
+    def test_iinfo_long_values(self):
+        for code in 'bBhH':
+            res = np.array(np.iinfo(code).max + 1, dtype=code)
+            tgt = np.iinfo(code).min
+            assert_(res == tgt)
+
+        for code in np.typecodes['AllInteger']:
+            res = np.array(np.iinfo(code).max, dtype=code)
+            tgt = np.iinfo(code).max
+            assert_(res == tgt)
+
+        for code in np.typecodes['AllInteger']:
+            res = np.typeDict[code](np.iinfo(code).max)
+            tgt = np.iinfo(code).max
+            assert_(res == tgt)
+
+    def test_int_raise_behaviour(self):
+        def overflow_error_func(dtype):
+            np.typeDict[dtype](np.iinfo(dtype).max + 1)
+
+        for code in 'lLqQ':
+            assert_raises(OverflowError, overflow_error_func, code)
+
+    def test_longdouble_int(self):
+        # gh-627
+        x = np.longdouble(np.inf)
+        assert_raises(OverflowError, x.__int__)
+        x = np.clongdouble(np.inf)
+        assert_raises(OverflowError, x.__int__)
+
+    def test_numpy_scalar_relational_operators(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1)[()] > np.array(0, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(0, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+        #Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            #unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1)[()] != np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+        #Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1)[()] == np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+#class TestRepr(TestCase):
+#    def test_repr(self):
+#        for t in types:
+#            val = t(1197346475.0137341)
+#            val_repr = repr(val)
+#            val2 = eval(val_repr)
+#            assert_equal( val, val2 )
+
+
+class TestRepr(object):
+    def _test_type_repr(self, t):
+        finfo = np.finfo(t)
+        last_fraction_bit_idx = finfo.nexp + finfo.nmant
+        last_exponent_bit_idx = finfo.nexp
+        storage_bytes = np.dtype(t).itemsize*8
+        # could add some more types to the list below
+        for which in ['small denorm', 'small norm']:
+            # Values from http://en.wikipedia.org/wiki/IEEE_754
+            constr = np.array([0x00]*storage_bytes, dtype=np.uint8)
+            if which == 'small denorm':
+                byte = last_fraction_bit_idx // 8
+                bytebit = 7-(last_fraction_bit_idx % 8)
+                constr[byte] = 1 << bytebit
+            elif which == 'small norm':
+                byte = last_exponent_bit_idx // 8
+                bytebit = 7-(last_exponent_bit_idx % 8)
+                constr[byte] = 1 << bytebit
+            else:
+                raise ValueError('hmm')
+            val = constr.view(t)[0]
+            val_repr = repr(val)
+            val2 = t(eval(val_repr))
+            if not (val2 == 0 and val < 1e-100):
+                assert_equal(val, val2)
+
+    def test_float_repr(self):
+        # long double test cannot work, because eval goes through a python
+        # float
+        for t in [np.float32, np.float64]:
+            yield self._test_type_repr, t
+
+
+class TestSizeOf(TestCase):
+
+    def test_equal_nbytes(self):
+        for type in types:
+            x = type(0)
+            assert_(sys.getsizeof(x) > x.nbytes)
+
+    def test_error(self):
+        d = np.float32()
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestAbs(TestCase):
+
+    def _test_abs_func(self, absfunc):
+        for tp in floating_types:
+            x = tp(-1.5)
+            assert_equal(absfunc(x), 1.5)
+            x = tp(0.0)
+            res = absfunc(x)
+            # assert_equal() checks zero signedness
+            assert_equal(res, 0.0)
+            x = tp(-0.0)
+            res = absfunc(x)
+            assert_equal(res, 0.0)
+
+    def test_builtin_abs(self):
+        self._test_abs_func(abs)
+
+    def test_numpy_abs(self):
+        self._test_abs_func(np.abs)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
new file mode 100644
index 0000000000..8d0f27182b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+""" Test printing of scalar types.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, assert_, run_module_suite
+
+
+class TestRealScalars(TestCase):
+    def test_str(self):
+        svals = [0.0, -0.0, 1, -1, np.inf, -np.inf, np.nan]
+        styps = [np.float16, np.float32, np.float64, np.longdouble]
+        actual = [str(f(c)) for c in svals for f in styps]
+        wanted = [
+             '0.0',  '0.0',  '0.0',  '0.0',
+             '-0.0', '-0.0', '-0.0', '-0.0',
+             '1.0',  '1.0',  '1.0',  '1.0',
+             '-1.0', '-1.0', '-1.0', '-1.0',
+             'inf',  'inf',  'inf',  'inf',
+             '-inf', '-inf', '-inf', '-inf',
+             'nan',  'nan',  'nan',  'nan']
+
+        for res, val in zip(actual, wanted):
+            assert_(res == val)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
new file mode 100644
index 0000000000..0d163c1dc9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
@@ -0,0 +1,319 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.compat import long
+from numpy.core import (array, arange, atleast_1d, atleast_2d, atleast_3d,
+                        vstack, hstack, newaxis, concatenate, stack)
+from numpy.testing import (TestCase, assert_, assert_raises, assert_array_equal,
+                           assert_equal, run_module_suite, assert_raises_regex)
+
+class TestAtleast1d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [array([1]), array([2])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [array([1, 2]), array([2, 3])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_r1array(self):
+        """ Test to make sure equivalent Travis O's r1array function
+        """
+        assert_(atleast_1d(3).shape == (1,))
+        assert_(atleast_1d(3j).shape == (1,))
+        assert_(atleast_1d(long(3)).shape == (1,))
+        assert_(atleast_1d(3.0).shape == (1,))
+        assert_(atleast_1d([[2, 3], [4, 5]]).shape == (2, 2))
+
+
+class TestAtleast2d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [array([[1]]), array([[2]])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [array([[1, 2]]), array([[2, 3]])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_r2array(self):
+        """ Test to make sure equivalent Travis O's r2array function
+        """
+        assert_(atleast_2d(3).shape == (1, 1))
+        assert_(atleast_2d([3j, 1]).shape == (1, 2))
+        assert_(atleast_2d([[[3, 1], [4, 5]], [[3, 5], [1, 2]]]).shape == (2, 2, 2))
+
+
+class TestAtleast3d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [array([[[1]]]), array([[[2]]])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [array([[[1], [2]]]), array([[[2], [3]]])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [a[:,:, newaxis], b[:,:, newaxis]]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+
+class TestHstack(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = hstack([a, b])
+        desired = array([1, 2])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1])
+        b = array([2])
+        res = hstack([a, b])
+        desired = array([1, 2])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1], [2]])
+        b = array([[1], [2]])
+        res = hstack([a, b])
+        desired = array([[1, 1], [2, 2]])
+        assert_array_equal(res, desired)
+
+
+class TestVstack(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = vstack([a, b])
+        desired = array([[1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1])
+        b = array([2])
+        res = vstack([a, b])
+        desired = array([[1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1], [2]])
+        b = array([[1], [2]])
+        res = vstack([a, b])
+        desired = array([[1], [2], [1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array2(self):
+        a = array([1, 2])
+        b = array([1, 2])
+        res = vstack([a, b])
+        desired = array([[1, 2], [1, 2]])
+        assert_array_equal(res, desired)
+
+
+class TestConcatenate(TestCase):
+    def test_exceptions(self):
+        # test axis must be in bounds
+        for ndim in [1, 2, 3]:
+            a = np.ones((1,)*ndim)
+            np.concatenate((a, a), axis=0)  # OK
+            assert_raises(IndexError, np.concatenate, (a, a), axis=ndim)
+            assert_raises(IndexError, np.concatenate, (a, a), axis=-(ndim + 1))
+
+        # Scalars cannot be concatenated
+        assert_raises(ValueError, concatenate, (0,))
+        assert_raises(ValueError, concatenate, (np.array(0),))
+
+        # test shapes must match except for concatenation axis
+        a = np.ones((1, 2, 3))
+        b = np.ones((2, 2, 3))
+        axis = list(range(3))
+        for i in range(3):
+            np.concatenate((a, b), axis=axis[0])  # OK
+            assert_raises(ValueError, np.concatenate, (a, b), axis=axis[1])
+            assert_raises(ValueError, np.concatenate, (a, b), axis=axis[2])
+            a = np.rollaxis(a, -1)
+            b = np.rollaxis(b, -1)
+            axis.append(axis.pop(0))
+
+        # No arrays to concatenate raises ValueError
+        assert_raises(ValueError, concatenate, ())
+
+    def test_concatenate_axis_None(self):
+        a = np.arange(4, dtype=np.float64).reshape((2, 2))
+        b = list(range(3))
+        c = ['x']
+        r = np.concatenate((a, a), axis=None)
+        assert_equal(r.dtype, a.dtype)
+        assert_equal(r.ndim, 1)
+        r = np.concatenate((a, b), axis=None)
+        assert_equal(r.size, a.size + len(b))
+        assert_equal(r.dtype, a.dtype)
+        r = np.concatenate((a, b, c), axis=None)
+        d = array(['0.0', '1.0', '2.0', '3.0',
+                   '0', '1', '2', 'x'])
+        assert_array_equal(r, d)
+
+    def test_large_concatenate_axis_None(self):
+        # When no axis is given, concatenate uses flattened versions.
+        # This also had a bug with many arrays (see gh-5979).
+        x = np.arange(1, 100)
+        r = np.concatenate(x, None)
+        assert_array_equal(x, r)
+
+        # This should probably be deprecated:
+        r = np.concatenate(x, 100)  # axis is >= MAXDIMS
+        assert_array_equal(x, r)
+
+    def test_concatenate(self):
+        # Test concatenate function
+        # One sequence returns unmodified (but as array)
+        r4 = list(range(4))
+        assert_array_equal(concatenate((r4,)), r4)
+        # Any sequence
+        assert_array_equal(concatenate((tuple(r4),)), r4)
+        assert_array_equal(concatenate((array(r4),)), r4)
+        # 1D default concatenation
+        r3 = list(range(3))
+        assert_array_equal(concatenate((r4, r3)), r4 + r3)
+        # Mixed sequence types
+        assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3)
+        assert_array_equal(concatenate((array(r4), r3)), r4 + r3)
+        # Explicit axis specification
+        assert_array_equal(concatenate((r4, r3), 0), r4 + r3)
+        # Including negative
+        assert_array_equal(concatenate((r4, r3), -1), r4 + r3)
+        # 2D
+        a23 = array([[10, 11, 12], [13, 14, 15]])
+        a13 = array([[0, 1, 2]])
+        res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]])
+        assert_array_equal(concatenate((a23, a13)), res)
+        assert_array_equal(concatenate((a23, a13), 0), res)
+        assert_array_equal(concatenate((a23.T, a13.T), 1), res.T)
+        assert_array_equal(concatenate((a23.T, a13.T), -1), res.T)
+        # Arrays much match shape
+        assert_raises(ValueError, concatenate, (a23.T, a13.T), 0)
+        # 3D
+        res = arange(2 * 3 * 7).reshape((2, 3, 7))
+        a0 = res[..., :4]
+        a1 = res[..., 4:6]
+        a2 = res[..., 6:]
+        assert_array_equal(concatenate((a0, a1, a2), 2), res)
+        assert_array_equal(concatenate((a0, a1, a2), -1), res)
+        assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T)
+
+
+def test_stack():
+    # 0d input
+    for input_ in [(1, 2, 3),
+                   [np.int32(1), np.int32(2), np.int32(3)],
+                   [np.array(1), np.array(2), np.array(3)]]:
+        assert_array_equal(stack(input_), [1, 2, 3])
+    # 1d input examples
+    a = np.array([1, 2, 3])
+    b = np.array([4, 5, 6])
+    r1 = array([[1, 2, 3], [4, 5, 6]])
+    assert_array_equal(np.stack((a, b)), r1)
+    assert_array_equal(np.stack((a, b), axis=1), r1.T)
+    # all input types
+    assert_array_equal(np.stack(list([a, b])), r1)
+    assert_array_equal(np.stack(array([a, b])), r1)
+    # all shapes for 1d input
+    arrays = [np.random.randn(3) for _ in range(10)]
+    axes = [0, 1, -1, -2]
+    expected_shapes = [(10, 3), (3, 10), (3, 10), (10, 3)]
+    for axis, expected_shape in zip(axes, expected_shapes):
+        assert_equal(np.stack(arrays, axis).shape, expected_shape)
+    assert_raises_regex(IndexError, 'out of bounds', stack, arrays, axis=2)
+    assert_raises_regex(IndexError, 'out of bounds', stack, arrays, axis=-3)
+    # all shapes for 2d input
+    arrays = [np.random.randn(3, 4) for _ in range(10)]
+    axes = [0, 1, 2, -1, -2, -3]
+    expected_shapes = [(10, 3, 4), (3, 10, 4), (3, 4, 10),
+                        (3, 4, 10), (3, 10, 4), (10, 3, 4)]
+    for axis, expected_shape in zip(axes, expected_shapes):
+        assert_equal(np.stack(arrays, axis).shape, expected_shape)
+    # empty arrays
+    assert_(stack([[], [], []]).shape == (3, 0))
+    assert_(stack([[], [], []], axis=1).shape == (0, 3))
+    # edge cases
+    assert_raises_regex(ValueError, 'need at least one array', stack, [])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [1, np.arange(3)])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(3), 1])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(3), 1], axis=1)
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.zeros((3, 3)), np.zeros(3)], axis=1)
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(2), np.arange(3)])
+    # np.matrix
+    m = np.matrix([[1, 2], [3, 4]])
+    assert_raises_regex(ValueError, 'shape too large to be a matrix',
+                        stack, [m, m])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
new file mode 100644
index 0000000000..ab8cecff0f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
@@ -0,0 +1,1243 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.core.umath_tests as umt
+import numpy.core.operand_flag_tests as opflag_tests
+from numpy.compat import asbytes
+from numpy.core.test_rational import rational, test_add, test_add_rationals
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_almost_equal, assert_array_almost_equal,
+    assert_no_warnings
+)
+
+
+class TestUfuncKwargs(TestCase):
+    def test_kwarg_exact(self):
+        assert_raises(TypeError, np.add, 1, 2, castingx='safe')
+        assert_raises(TypeError, np.add, 1, 2, dtypex=np.int)
+        assert_raises(TypeError, np.add, 1, 2, extobjx=[4096])
+        assert_raises(TypeError, np.add, 1, 2, outx=None)
+        assert_raises(TypeError, np.add, 1, 2, sigx='ii->i')
+        assert_raises(TypeError, np.add, 1, 2, signaturex='ii->i')
+        assert_raises(TypeError, np.add, 1, 2, subokx=False)
+        assert_raises(TypeError, np.add, 1, 2, wherex=[True])
+
+    def test_sig_signature(self):
+        assert_raises(ValueError, np.add, 1, 2, sig='ii->i',
+                      signature='ii->i')
+
+    def test_sig_dtype(self):
+        assert_raises(RuntimeError, np.add, 1, 2, sig='ii->i',
+                      dtype=np.int)
+        assert_raises(RuntimeError, np.add, 1, 2, signature='ii->i',
+                      dtype=np.int)
+
+
+class TestUfunc(TestCase):
+    def test_pickle(self):
+        import pickle
+        assert_(pickle.loads(pickle.dumps(np.sin)) is np.sin)
+
+        # Check that ufunc not defined in the top level numpy namespace such as
+        # numpy.core.test_rational.test_add can also be pickled
+        assert_(pickle.loads(pickle.dumps(test_add)) is test_add)
+
+    def test_pickle_withstring(self):
+        import pickle
+        astring = asbytes("cnumpy.core\n_ufunc_reconstruct\np0\n"
+                "(S'numpy.core.umath'\np1\nS'cos'\np2\ntp3\nRp4\n.")
+        assert_(pickle.loads(astring) is np.cos)
+
+    def test_reduceat_shifting_sum(self):
+        L = 6
+        x = np.arange(L)
+        idx = np.array(list(zip(np.arange(L - 2), np.arange(L - 2) + 2))).ravel()
+        assert_array_equal(np.add.reduceat(x, idx)[::2], [1, 3, 5, 7])
+
+    def test_generic_loops(self):
+        """Test generic loops.
+
+        The loops to be tested are:
+
+            PyUFunc_ff_f_As_dd_d
+            PyUFunc_ff_f
+            PyUFunc_dd_d
+            PyUFunc_gg_g
+            PyUFunc_FF_F_As_DD_D
+            PyUFunc_DD_D
+            PyUFunc_FF_F
+            PyUFunc_GG_G
+            PyUFunc_OO_O
+            PyUFunc_OO_O_method
+            PyUFunc_f_f_As_d_d
+            PyUFunc_d_d
+            PyUFunc_f_f
+            PyUFunc_g_g
+            PyUFunc_F_F_As_D_D
+            PyUFunc_F_F
+            PyUFunc_D_D
+            PyUFunc_G_G
+            PyUFunc_O_O
+            PyUFunc_O_O_method
+            PyUFunc_On_Om
+
+        Where:
+
+            f -- float
+            d -- double
+            g -- long double
+            F -- complex float
+            D -- complex double
+            G -- complex long double
+            O -- python object
+
+        It is difficult to assure that each of these loops is entered from the
+        Python level as the special cased loops are a moving target and the
+        corresponding types are architecture dependent. We probably need to
+        define C level testing ufuncs to get at them. For the time being, I've
+        just looked at the signatures registered in the build directory to find
+        relevant functions.
+
+        Fixme, currently untested:
+
+            PyUFunc_ff_f_As_dd_d
+            PyUFunc_FF_F_As_DD_D
+            PyUFunc_f_f_As_d_d
+            PyUFunc_F_F_As_D_D
+            PyUFunc_On_Om
+
+        """
+        fone = np.exp
+        ftwo = lambda x, y: x**y
+        fone_val = 1
+        ftwo_val = 1
+        # check unary PyUFunc_f_f.
+        msg = "PyUFunc_f_f"
+        x = np.zeros(10, dtype=np.single)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_d_d.
+        msg = "PyUFunc_d_d"
+        x = np.zeros(10, dtype=np.double)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_g_g.
+        msg = "PyUFunc_g_g"
+        x = np.zeros(10, dtype=np.longdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_F_F.
+        msg = "PyUFunc_F_F"
+        x = np.zeros(10, dtype=np.csingle)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_D_D.
+        msg = "PyUFunc_D_D"
+        x = np.zeros(10, dtype=np.cdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_G_G.
+        msg = "PyUFunc_G_G"
+        x = np.zeros(10, dtype=np.clongdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+
+        # check binary PyUFunc_ff_f.
+        msg = "PyUFunc_ff_f"
+        x = np.ones(10, dtype=np.single)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_dd_d.
+        msg = "PyUFunc_dd_d"
+        x = np.ones(10, dtype=np.double)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_gg_g.
+        msg = "PyUFunc_gg_g"
+        x = np.ones(10, dtype=np.longdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_FF_F.
+        msg = "PyUFunc_FF_F"
+        x = np.ones(10, dtype=np.csingle)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_DD_D.
+        msg = "PyUFunc_DD_D"
+        x = np.ones(10, dtype=np.cdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_GG_G.
+        msg = "PyUFunc_GG_G"
+        x = np.ones(10, dtype=np.clongdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+
+        # class to use in testing object method loops
+        class foo(object):
+            def conjugate(self):
+                return np.bool_(1)
+
+            def logical_xor(self, obj):
+                return np.bool_(1)
+
+        # check unary PyUFunc_O_O
+        msg = "PyUFunc_O_O"
+        x = np.ones(10, dtype=np.object)[0::2]
+        assert_(np.all(np.abs(x) == 1), msg)
+        # check unary PyUFunc_O_O_method
+        msg = "PyUFunc_O_O_method"
+        x = np.zeros(10, dtype=np.object)[0::2]
+        for i in range(len(x)):
+            x[i] = foo()
+        assert_(np.all(np.conjugate(x) == True), msg)
+
+        # check binary PyUFunc_OO_O
+        msg = "PyUFunc_OO_O"
+        x = np.ones(10, dtype=np.object)[0::2]
+        assert_(np.all(np.add(x, x) == 2), msg)
+        # check binary PyUFunc_OO_O_method
+        msg = "PyUFunc_OO_O_method"
+        x = np.zeros(10, dtype=np.object)[0::2]
+        for i in range(len(x)):
+            x[i] = foo()
+        assert_(np.all(np.logical_xor(x, x)), msg)
+
+        # check PyUFunc_On_Om
+        # fixme -- I don't know how to do this yet
+
+    def test_all_ufunc(self):
+        """Try to check presence and results of all ufuncs.
+
+        The list of ufuncs comes from generate_umath.py and is as follows:
+
+        =====  ====  =============  ===============  ========================
+        done   args   function        types                notes
+        =====  ====  =============  ===============  ========================
+        n      1     conjugate      nums + O
+        n      1     absolute       nums + O         complex -> real
+        n      1     negative       nums + O
+        n      1     sign           nums + O         -> int
+        n      1     invert         bool + ints + O  flts raise an error
+        n      1     degrees        real + M         cmplx raise an error
+        n      1     radians        real + M         cmplx raise an error
+        n      1     arccos         flts + M
+        n      1     arccosh        flts + M
+        n      1     arcsin         flts + M
+        n      1     arcsinh        flts + M
+        n      1     arctan         flts + M
+        n      1     arctanh        flts + M
+        n      1     cos            flts + M
+        n      1     sin            flts + M
+        n      1     tan            flts + M
+        n      1     cosh           flts + M
+        n      1     sinh           flts + M
+        n      1     tanh           flts + M
+        n      1     exp            flts + M
+        n      1     expm1          flts + M
+        n      1     log            flts + M
+        n      1     log10          flts + M
+        n      1     log1p          flts + M
+        n      1     sqrt           flts + M         real x < 0 raises error
+        n      1     ceil           real + M
+        n      1     trunc          real + M
+        n      1     floor          real + M
+        n      1     fabs           real + M
+        n      1     rint           flts + M
+        n      1     isnan          flts             -> bool
+        n      1     isinf          flts             -> bool
+        n      1     isfinite       flts             -> bool
+        n      1     signbit        real             -> bool
+        n      1     modf           real             -> (frac, int)
+        n      1     logical_not    bool + nums + M  -> bool
+        n      2     left_shift     ints + O         flts raise an error
+        n      2     right_shift    ints + O         flts raise an error
+        n      2     add            bool + nums + O  boolean + is ||
+        n      2     subtract       bool + nums + O  boolean - is ^
+        n      2     multiply       bool + nums + O  boolean * is &
+        n      2     divide         nums + O
+        n      2     floor_divide   nums + O
+        n      2     true_divide    nums + O         bBhH -> f, iIlLqQ -> d
+        n      2     fmod           nums + M
+        n      2     power          nums + O
+        n      2     greater        bool + nums + O  -> bool
+        n      2     greater_equal  bool + nums + O  -> bool
+        n      2     less           bool + nums + O  -> bool
+        n      2     less_equal     bool + nums + O  -> bool
+        n      2     equal          bool + nums + O  -> bool
+        n      2     not_equal      bool + nums + O  -> bool
+        n      2     logical_and    bool + nums + M  -> bool
+        n      2     logical_or     bool + nums + M  -> bool
+        n      2     logical_xor    bool + nums + M  -> bool
+        n      2     maximum        bool + nums + O
+        n      2     minimum        bool + nums + O
+        n      2     bitwise_and    bool + ints + O  flts raise an error
+        n      2     bitwise_or     bool + ints + O  flts raise an error
+        n      2     bitwise_xor    bool + ints + O  flts raise an error
+        n      2     arctan2        real + M
+        n      2     remainder      ints + real + O
+        n      2     hypot          real + M
+        =====  ====  =============  ===============  ========================
+
+        Types other than those listed will be accepted, but they are cast to
+        the smallest compatible type for which the function is defined. The
+        casting rules are:
+
+        bool -> int8 -> float32
+        ints -> double
+
+        """
+        pass
+
+    def test_signature(self):
+        # the arguments to test_signature are: nin, nout, core_signature
+        # pass
+        assert_equal(umt.test_signature(2, 1, "(i),(i)->()"), 1)
+
+        # pass. empty core signature; treat as plain ufunc (with trivial core)
+        assert_equal(umt.test_signature(2, 1, "(),()->()"), 0)
+
+        # in the following calls, a ValueError should be raised because
+        # of error in core signature
+        # FIXME These should be using assert_raises
+
+        # error: extra parenthesis
+        msg = "core_sig: extra parenthesis"
+        try:
+            ret = umt.test_signature(2, 1, "((i)),(i)->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: parenthesis matching
+        msg = "core_sig: parenthesis matching"
+        try:
+            ret = umt.test_signature(2, 1, "(i),)i(->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: incomplete signature. letters outside of parenthesis are ignored
+        msg = "core_sig: incomplete signature"
+        try:
+            ret = umt.test_signature(2, 1, "(i),->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: incomplete signature. 2 output arguments are specified
+        msg = "core_sig: incomplete signature"
+        try:
+            ret = umt.test_signature(2, 2, "(i),(i)->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # more complicated names for variables
+        assert_equal(umt.test_signature(2, 1, "(i1,i2),(J_1)->(_kAB)"), 1)
+
+    def test_get_signature(self):
+        assert_equal(umt.inner1d.signature, "(i),(i)->()")
+
+    def test_forced_sig(self):
+        a = 0.5*np.arange(3, dtype='f8')
+        assert_equal(np.add(a, 0.5), [0.5, 1, 1.5])
+        assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig='ii->i', casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig=('i4', 'i4', 'i4'),
+                                            casting='unsafe'), [0, 0, 1])
+
+        b = np.zeros((3,), dtype='f8')
+        np.add(a, 0.5, out=b)
+        assert_equal(b, [0.5, 1, 1.5])
+        b[:] = 0
+        np.add(a, 0.5, sig='i', out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig='ii->i', out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig=('i4', 'i4', 'i4'), out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+
+    def test_true_divide(self):
+        # True_divide has a non uniform signature, see #3484.
+        # This also tests type_tuple_type_resolver.
+        a = np.full(5, 12.5)
+        b = np.full(5, 10.0)
+        tgt = np.full(5, 1.25)
+        assert_almost_equal(np.true_divide(a, b, dtype=np.float64), tgt)
+        assert_almost_equal(np.true_divide(a, b, dtype=np.float32), tgt)
+        assert_raises(TypeError, np.true_divide, a, b, dtype=np.int)
+
+    def test_sum_stability(self):
+        a = np.ones(500, dtype=np.float32)
+        assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 4)
+
+        a = np.ones(500, dtype=np.float64)
+        assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 13)
+
+    def test_sum(self):
+        for dt in (np.int, np.float16, np.float32, np.float64, np.longdouble):
+            for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
+                      128, 1024, 1235):
+                tgt = dt(v * (v + 1) / 2)
+                d = np.arange(1, v + 1, dtype=dt)
+                assert_almost_equal(np.sum(d), tgt)
+                assert_almost_equal(np.sum(d[::-1]), tgt)
+
+            d = np.ones(500, dtype=dt)
+            assert_almost_equal(np.sum(d[::2]), 250.)
+            assert_almost_equal(np.sum(d[1::2]), 250.)
+            assert_almost_equal(np.sum(d[::3]), 167.)
+            assert_almost_equal(np.sum(d[1::3]), 167.)
+            assert_almost_equal(np.sum(d[::-2]), 250.)
+            assert_almost_equal(np.sum(d[-1::-2]), 250.)
+            assert_almost_equal(np.sum(d[::-3]), 167.)
+            assert_almost_equal(np.sum(d[-1::-3]), 167.)
+            # sum with first reduction entry != 0
+            d = np.ones((1,), dtype=dt)
+            d += d
+            assert_almost_equal(d, 2.)
+
+    def test_sum_complex(self):
+        for dt in (np.complex64, np.complex128, np.clongdouble):
+            for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
+                      128, 1024, 1235):
+                tgt = dt(v * (v + 1) / 2) - dt((v * (v + 1) / 2) * 1j)
+                d = np.empty(v, dtype=dt)
+                d.real = np.arange(1, v + 1)
+                d.imag = -np.arange(1, v + 1)
+                assert_almost_equal(np.sum(d), tgt)
+                assert_almost_equal(np.sum(d[::-1]), tgt)
+
+            d = np.ones(500, dtype=dt) + 1j
+            assert_almost_equal(np.sum(d[::2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[1::2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[::3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[1::3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[::-2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[-1::-2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[::-3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[-1::-3]), 167. + 167j)
+            # sum with first reduction entry != 0
+            d = np.ones((1,), dtype=dt) + 1j
+            d += d
+            assert_almost_equal(d, 2. + 2j)
+
+    def test_inner1d(self):
+        a = np.arange(6).reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1))
+        a = np.arange(6)
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a))
+
+    def test_broadcast(self):
+        msg = "broadcast"
+        a = np.arange(4).reshape((2, 1, 2))
+        b = np.arange(4).reshape((1, 2, 2))
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        msg = "extend & broadcast loop dimensions"
+        b = np.arange(4).reshape((2, 2))
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        # Broadcast in core dimensions should fail
+        a = np.arange(8).reshape((4, 2))
+        b = np.arange(4).reshape((4, 1))
+        assert_raises(ValueError, umt.inner1d, a, b)
+        # Extend core dimensions should fail
+        a = np.arange(8).reshape((4, 2))
+        b = np.array(7)
+        assert_raises(ValueError, umt.inner1d, a, b)
+        # Broadcast should fail
+        a = np.arange(2).reshape((2, 1, 1))
+        b = np.arange(3).reshape((3, 1, 1))
+        assert_raises(ValueError, umt.inner1d, a, b)
+
+    def test_type_cast(self):
+        msg = "type cast"
+        a = np.arange(6, dtype='short').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+        msg = "type cast on one argument"
+        a = np.arange(6).reshape((2, 3))
+        b = a + 0.1
+        assert_array_almost_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1),
+                                  err_msg=msg)
+
+    def test_endian(self):
+        msg = "big endian"
+        a = np.arange(6, dtype='>i4').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+        msg = "little endian"
+        a = np.arange(6, dtype='<i4').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+
+        # Output should always be native-endian
+        Ba = np.arange(1, dtype='>f8')
+        La = np.arange(1, dtype='<f8')
+        assert_equal((Ba+Ba).dtype, np.dtype('f8'))
+        assert_equal((Ba+La).dtype, np.dtype('f8'))
+        assert_equal((La+Ba).dtype, np.dtype('f8'))
+        assert_equal((La+La).dtype, np.dtype('f8'))
+
+        assert_equal(np.absolute(La).dtype, np.dtype('f8'))
+        assert_equal(np.absolute(Ba).dtype, np.dtype('f8'))
+        assert_equal(np.negative(La).dtype, np.dtype('f8'))
+        assert_equal(np.negative(Ba).dtype, np.dtype('f8'))
+
+    def test_incontiguous_array(self):
+        msg = "incontiguous memory layout of array"
+        x = np.arange(64).reshape((2, 2, 2, 2, 2, 2))
+        a = x[:, 0,:, 0,:, 0]
+        b = x[:, 1,:, 1,:, 1]
+        a[0, 0, 0] = -1
+        msg2 = "make sure it references to the original array"
+        assert_equal(x[0, 0, 0, 0, 0, 0], -1, err_msg=msg2)
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        x = np.arange(24).reshape(2, 3, 4)
+        a = x.T
+        b = x.T
+        a[0, 0, 0] = -1
+        assert_equal(x[0, 0, 0], -1, err_msg=msg2)
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+
+    def test_output_argument(self):
+        msg = "output argument"
+        a = np.arange(12).reshape((2, 3, 2))
+        b = np.arange(4).reshape((2, 1, 2)) + 1
+        c = np.zeros((2, 3), dtype='int')
+        umt.inner1d(a, b, c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+
+        msg = "output argument with type cast"
+        c = np.zeros((2, 3), dtype='int16')
+        umt.inner1d(a, b, c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+
+        msg = "output argument with incontiguous layout"
+        c = np.zeros((2, 3, 4), dtype='int16')
+        umt.inner1d(a, b, c[..., 0])
+        assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c[..., 0])
+        assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
+
+    def test_innerwt(self):
+        a = np.arange(6).reshape((2, 3))
+        b = np.arange(10, 16).reshape((2, 3))
+        w = np.arange(20, 26).reshape((2, 3))
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+        a = np.arange(100, 124).reshape((2, 3, 4))
+        b = np.arange(200, 224).reshape((2, 3, 4))
+        w = np.arange(300, 324).reshape((2, 3, 4))
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+
+    def test_innerwt_empty(self):
+        """Test generalized ufunc with zero-sized operands"""
+        a = np.array([], dtype='f8')
+        b = np.array([], dtype='f8')
+        w = np.array([], dtype='f8')
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+
+    def test_matrix_multiply(self):
+        self.compare_matrix_multiply_results(np.long)
+        self.compare_matrix_multiply_results(np.double)
+
+    def compare_matrix_multiply_results(self, tp):
+        d1 = np.array(np.random.rand(2, 3, 4), dtype=tp)
+        d2 = np.array(np.random.rand(2, 3, 4), dtype=tp)
+        msg = "matrix multiply on type %s" % d1.dtype.name
+
+        def permute_n(n):
+            if n == 1:
+                return ([0],)
+            ret = ()
+            base = permute_n(n-1)
+            for perm in base:
+                for i in range(n):
+                    new = perm + [n-1]
+                    new[n-1] = new[i]
+                    new[i] = n-1
+                    ret += (new,)
+            return ret
+
+        def slice_n(n):
+            if n == 0:
+                return ((),)
+            ret = ()
+            base = slice_n(n-1)
+            for sl in base:
+                ret += (sl+(slice(None),),)
+                ret += (sl+(slice(0, 1),),)
+            return ret
+
+        def broadcastable(s1, s2):
+            return s1 == s2 or s1 == 1 or s2 == 1
+
+        permute_3 = permute_n(3)
+        slice_3 = slice_n(3) + ((slice(None, None, -1),)*3,)
+
+        ref = True
+        for p1 in permute_3:
+            for p2 in permute_3:
+                for s1 in slice_3:
+                    for s2 in slice_3:
+                        a1 = d1.transpose(p1)[s1]
+                        a2 = d2.transpose(p2)[s2]
+                        ref = ref and a1.base is not None
+                        ref = ref and a2.base is not None
+                        if (a1.shape[-1] == a2.shape[-2] and
+                                broadcastable(a1.shape[0], a2.shape[0])):
+                            assert_array_almost_equal(
+                                umt.matrix_multiply(a1, a2),
+                                np.sum(a2[..., np.newaxis].swapaxes(-3, -1) *
+                                       a1[..., np.newaxis,:], axis=-1),
+                                err_msg=msg + ' %s %s' % (str(a1.shape),
+                                                          str(a2.shape)))
+
+        assert_equal(ref, True, err_msg="reference check")
+
+    def test_euclidean_pdist(self):
+        a = np.arange(12, dtype=np.float).reshape(4, 3)
+        out = np.empty((a.shape[0] * (a.shape[0] - 1) // 2,), dtype=a.dtype)
+        umt.euclidean_pdist(a, out)
+        b = np.sqrt(np.sum((a[:, None] - a)**2, axis=-1))
+        b = b[~np.tri(a.shape[0], dtype=bool)]
+        assert_almost_equal(out, b)
+        # An output array is required to determine p with signature (n,d)->(p)
+        assert_raises(ValueError, umt.euclidean_pdist, a)
+
+    def test_object_logical(self):
+        a = np.array([3, None, True, False, "test", ""], dtype=object)
+        assert_equal(np.logical_or(a, None),
+                        np.array([x or None for x in a], dtype=object))
+        assert_equal(np.logical_or(a, True),
+                        np.array([x or True for x in a], dtype=object))
+        assert_equal(np.logical_or(a, 12),
+                        np.array([x or 12 for x in a], dtype=object))
+        assert_equal(np.logical_or(a, "blah"),
+                        np.array([x or "blah" for x in a], dtype=object))
+
+        assert_equal(np.logical_and(a, None),
+                        np.array([x and None for x in a], dtype=object))
+        assert_equal(np.logical_and(a, True),
+                        np.array([x and True for x in a], dtype=object))
+        assert_equal(np.logical_and(a, 12),
+                        np.array([x and 12 for x in a], dtype=object))
+        assert_equal(np.logical_and(a, "blah"),
+                        np.array([x and "blah" for x in a], dtype=object))
+
+        assert_equal(np.logical_not(a),
+                        np.array([not x for x in a], dtype=object))
+
+        assert_equal(np.logical_or.reduce(a), 3)
+        assert_equal(np.logical_and.reduce(a), None)
+
+    def test_object_array_reduction(self):
+        # Reductions on object arrays
+        a = np.array(['a', 'b', 'c'], dtype=object)
+        assert_equal(np.sum(a), 'abc')
+        assert_equal(np.max(a), 'c')
+        assert_equal(np.min(a), 'a')
+        a = np.array([True, False, True], dtype=object)
+        assert_equal(np.sum(a), 2)
+        assert_equal(np.prod(a), 0)
+        assert_equal(np.any(a), True)
+        assert_equal(np.all(a), False)
+        assert_equal(np.max(a), True)
+        assert_equal(np.min(a), False)
+        assert_equal(np.array([[1]], dtype=object).sum(), 1)
+        assert_equal(np.array([[[1, 2]]], dtype=object).sum((0, 1)), [1, 2])
+
+    def test_object_array_accumulate_inplace(self):
+        # Checks that in-place accumulates work, see also gh-7402
+        arr = np.ones(4, dtype=object)
+        arr[:] = [[1] for i in range(4)]
+        # Twice reproduced also for tuples:
+        np.add.accumulate(arr, out=arr)
+        np.add.accumulate(arr, out=arr)
+        assert_array_equal(arr, np.array([[1]*i for i in [1, 3, 6, 10]]))
+
+        # And the same if the axis argument is used
+        arr = np.ones((2, 4), dtype=object)
+        arr[0, :] = [[2] for i in range(4)]
+        np.add.accumulate(arr, out=arr, axis=-1)
+        np.add.accumulate(arr, out=arr, axis=-1)
+        assert_array_equal(arr[0, :], np.array([[2]*i for i in [1, 3, 6, 10]]))
+
+    def test_object_scalar_multiply(self):
+        # Tickets #2469 and #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.multiply(arr, 3), desired)
+        assert_equal(np.multiply(3, arr), desired)
+
+    def test_zerosize_reduction(self):
+        # Test with default dtype and object dtype
+        for a in [[], np.array([], dtype=object)]:
+            assert_equal(np.sum(a), 0)
+            assert_equal(np.prod(a), 1)
+            assert_equal(np.any(a), False)
+            assert_equal(np.all(a), True)
+            assert_raises(ValueError, np.max, a)
+            assert_raises(ValueError, np.min, a)
+
+    def test_axis_out_of_bounds(self):
+        a = np.array([False, False])
+        assert_raises(ValueError, a.all, axis=1)
+        a = np.array([False, False])
+        assert_raises(ValueError, a.all, axis=-2)
+
+        a = np.array([False, False])
+        assert_raises(ValueError, a.any, axis=1)
+        a = np.array([False, False])
+        assert_raises(ValueError, a.any, axis=-2)
+
+    def test_scalar_reduction(self):
+        # The functions 'sum', 'prod', etc allow specifying axis=0
+        # even for scalars
+        assert_equal(np.sum(3, axis=0), 3)
+        assert_equal(np.prod(3.5, axis=0), 3.5)
+        assert_equal(np.any(True, axis=0), True)
+        assert_equal(np.all(False, axis=0), False)
+        assert_equal(np.max(3, axis=0), 3)
+        assert_equal(np.min(2.5, axis=0), 2.5)
+
+        # Check scalar behaviour for ufuncs without an identity
+        assert_equal(np.power.reduce(3), 3)
+
+        # Make sure that scalars are coming out from this operation
+        assert_(type(np.prod(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.sum(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.max(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.min(np.float32(2.5), axis=0)) is np.float32)
+
+        # check if scalars/0-d arrays get cast
+        assert_(type(np.any(0, axis=0)) is np.bool_)
+
+        # assert that 0-d arrays get wrapped
+        class MyArray(np.ndarray):
+            pass
+        a = np.array(1).view(MyArray)
+        assert_(type(np.any(a)) is MyArray)
+
+    def test_casting_out_param(self):
+        # Test that it's possible to do casts on output
+        a = np.ones((200, 100), np.int64)
+        b = np.ones((200, 100), np.int64)
+        c = np.ones((200, 100), np.float64)
+        np.add(a, b, out=c)
+        assert_equal(c, 2)
+
+        a = np.zeros(65536)
+        b = np.zeros(65536, dtype=np.float32)
+        np.subtract(a, 0, out=b)
+        assert_equal(b, 0)
+
+    def test_where_param(self):
+        # Test that the where= ufunc parameter works with regular arrays
+        a = np.arange(7)
+        b = np.ones(7)
+        c = np.zeros(7)
+        np.add(a, b, out=c, where=(a % 2 == 1))
+        assert_equal(c, [0, 2, 0, 4, 0, 6, 0])
+
+        a = np.arange(4).reshape(2, 2) + 2
+        np.power(a, [2, 3], out=a, where=[[0, 1], [1, 0]])
+        assert_equal(a, [[2, 27], [16, 5]])
+        # Broadcasting the where= parameter
+        np.subtract(a, 2, out=a, where=[True, False])
+        assert_equal(a, [[0, 27], [14, 5]])
+
+    def test_where_param_buffer_output(self):
+        # This test is temporarily skipped because it requires
+        # adding masking features to the nditer to work properly
+
+        # With casting on output
+        a = np.ones(10, np.int64)
+        b = np.ones(10, np.int64)
+        c = 1.5 * np.ones(10, np.float64)
+        np.add(a, b, out=c, where=[1, 0, 0, 1, 0, 0, 1, 1, 1, 0])
+        assert_equal(c, [2, 1.5, 1.5, 2, 1.5, 1.5, 2, 2, 2, 1.5])
+
+    def check_identityless_reduction(self, a):
+        # np.minimum.reduce is a identityless reduction
+
+        # Verify that it sees the zero at various positions
+        a[...] = 1
+        a[1, 0, 0] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [1, 0])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[1, 1, 1, 1], [0, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[1, 1, 1], [0, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+        a[...] = 1
+        a[0, 1, 0] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [1, 0, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[1, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[0, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[1, 0, 1], [1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+        a[...] = 1
+        a[0, 0, 1] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [1, 0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[1, 0, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[0, 1, 1], [1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+    def test_identityless_reduction_corder(self):
+        a = np.empty((2, 3, 4), order='C')
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_forder(self):
+        a = np.empty((2, 3, 4), order='F')
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_otherorder(self):
+        a = np.empty((2, 4, 3), order='C').swapaxes(1, 2)
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_noncontig(self):
+        a = np.empty((3, 5, 4), order='C').swapaxes(1, 2)
+        a = a[1:, 1:, 1:]
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_noncontig_unaligned(self):
+        a = np.empty((3*4*5*8 + 1,), dtype='i1')
+        a = a[1:].view(dtype='f8')
+        a.shape = (3, 4, 5)
+        a = a[1:, 1:, 1:]
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_nonreorderable(self):
+        a = np.array([[8.0, 2.0, 2.0], [1.0, 0.5, 0.25]])
+
+        res = np.divide.reduce(a, axis=0)
+        assert_equal(res, [8.0, 4.0, 8.0])
+
+        res = np.divide.reduce(a, axis=1)
+        assert_equal(res, [2.0, 8.0])
+
+        res = np.divide.reduce(a, axis=())
+        assert_equal(res, a)
+
+        assert_raises(ValueError, np.divide.reduce, a, axis=(0, 1))
+
+    def test_reduce_zero_axis(self):
+        # If we have a n x m array and do a reduction with axis=1, then we are
+        # doing n reductions, and each reduction takes an m-element array. For
+        # a reduction operation without an identity, then:
+        #   n > 0, m > 0: fine
+        #   n = 0, m > 0: fine, doing 0 reductions of m-element arrays
+        #   n > 0, m = 0: can't reduce a 0-element array, ValueError
+        #   n = 0, m = 0: can't reduce a 0-element array, ValueError (for
+        #     consistency with the above case)
+        # This test doesn't actually look at return values, it just checks to
+        # make sure that error we get an error in exactly those cases where we
+        # expect one, and assumes the calculations themselves are done
+        # correctly.
+
+        def ok(f, *args, **kwargs):
+            f(*args, **kwargs)
+
+        def err(f, *args, **kwargs):
+            assert_raises(ValueError, f, *args, **kwargs)
+
+        def t(expect, func, n, m):
+            expect(func, np.zeros((n, m)), axis=1)
+            expect(func, np.zeros((m, n)), axis=0)
+            expect(func, np.zeros((n // 2, n // 2, m)), axis=2)
+            expect(func, np.zeros((n // 2, m, n // 2)), axis=1)
+            expect(func, np.zeros((n, m // 2, m // 2)), axis=(1, 2))
+            expect(func, np.zeros((m // 2, n, m // 2)), axis=(0, 2))
+            expect(func, np.zeros((m // 3, m // 3, m // 3,
+                                  n // 2, n // 2)),
+                                 axis=(0, 1, 2))
+            # Check what happens if the inner (resp. outer) dimensions are a
+            # mix of zero and non-zero:
+            expect(func, np.zeros((10, m, n)), axis=(0, 1))
+            expect(func, np.zeros((10, n, m)), axis=(0, 2))
+            expect(func, np.zeros((m, 10, n)), axis=0)
+            expect(func, np.zeros((10, m, n)), axis=1)
+            expect(func, np.zeros((10, n, m)), axis=2)
+
+        # np.maximum is just an arbitrary ufunc with no reduction identity
+        assert_equal(np.maximum.identity, None)
+        t(ok, np.maximum.reduce, 30, 30)
+        t(ok, np.maximum.reduce, 0, 30)
+        t(err, np.maximum.reduce, 30, 0)
+        t(err, np.maximum.reduce, 0, 0)
+        err(np.maximum.reduce, [])
+        np.maximum.reduce(np.zeros((0, 0)), axis=())
+
+        # all of the combinations are fine for a reduction that has an
+        # identity
+        t(ok, np.add.reduce, 30, 30)
+        t(ok, np.add.reduce, 0, 30)
+        t(ok, np.add.reduce, 30, 0)
+        t(ok, np.add.reduce, 0, 0)
+        np.add.reduce([])
+        np.add.reduce(np.zeros((0, 0)), axis=())
+
+        # OTOH, accumulate always makes sense for any combination of n and m,
+        # because it maps an m-element array to an m-element array. These
+        # tests are simpler because accumulate doesn't accept multiple axes.
+        for uf in (np.maximum, np.add):
+            uf.accumulate(np.zeros((30, 0)), axis=0)
+            uf.accumulate(np.zeros((0, 30)), axis=0)
+            uf.accumulate(np.zeros((30, 30)), axis=0)
+            uf.accumulate(np.zeros((0, 0)), axis=0)
+
+    def test_safe_casting(self):
+        # In old versions of numpy, in-place operations used the 'unsafe'
+        # casting rules. In versions >= 1.10, 'same_kind' is the
+        # default and an exception is raised instead of a warning.
+        # when 'same_kind' is not satisfied.
+        a = np.array([1, 2, 3], dtype=int)
+        # Non-in-place addition is fine
+        assert_array_equal(assert_no_warnings(np.add, a, 1.1),
+                           [2.1, 3.1, 4.1])
+        assert_raises(TypeError, np.add, a, 1.1, out=a)
+
+        def add_inplace(a, b):
+            a += b
+
+        assert_raises(TypeError, add_inplace, a, 1.1)
+        # Make sure that explicitly overriding the exception is allowed:
+        assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe")
+        assert_array_equal(a, [2, 3, 4])
+
+    def test_ufunc_custom_out(self):
+        # Test ufunc with built in input types and custom output type
+
+        a = np.array([0, 1, 2], dtype='i8')
+        b = np.array([0, 1, 2], dtype='i8')
+        c = np.empty(3, dtype=rational)
+
+        # Output must be specified so numpy knows what
+        # ufunc signature to look for
+        result = test_add(a, b, c)
+        assert_equal(result, np.array([0, 2, 4], dtype=rational))
+
+        # no output type should raise TypeError
+        assert_raises(TypeError, test_add, a, b)
+
+    def test_operand_flags(self):
+        a = np.arange(16, dtype='l').reshape(4, 4)
+        b = np.arange(9, dtype='l').reshape(3, 3)
+        opflag_tests.inplace_add(a[:-1, :-1], b)
+        assert_equal(a, np.array([[0, 2, 4, 3], [7, 9, 11, 7],
+            [14, 16, 18, 11], [12, 13, 14, 15]], dtype='l'))
+
+        a = np.array(0)
+        opflag_tests.inplace_add(a, 3)
+        assert_equal(a, 3)
+        opflag_tests.inplace_add(a, [3, 4])
+        assert_equal(a, 10)
+
+    def test_struct_ufunc(self):
+        import numpy.core.struct_ufunc_test as struct_ufunc
+
+        a = np.array([(1, 2, 3)], dtype='u8,u8,u8')
+        b = np.array([(1, 2, 3)], dtype='u8,u8,u8')
+
+        result = struct_ufunc.add_triplet(a, b)
+        assert_equal(result, np.array([(2, 4, 6)], dtype='u8,u8,u8'))
+
+    def test_custom_ufunc(self):
+        a = np.array([rational(1, 2), rational(1, 3), rational(1, 4)],
+            dtype=rational)
+        b = np.array([rational(1, 2), rational(1, 3), rational(1, 4)],
+            dtype=rational)
+
+        result = test_add_rationals(a, b)
+        expected = np.array([rational(1), rational(2, 3), rational(1, 2)],
+            dtype=rational)
+        assert_equal(result, expected)
+
+    def test_custom_array_like(self):
+
+        class MyThing(object):
+            __array_priority__ = 1000
+
+            rmul_count = 0
+            getitem_count = 0
+
+            def __init__(self, shape):
+                self.shape = shape
+
+            def __len__(self):
+                return self.shape[0]
+
+            def __getitem__(self, i):
+                MyThing.getitem_count += 1
+                if not isinstance(i, tuple):
+                    i = (i,)
+                if len(i) > len(self.shape):
+                    raise IndexError("boo")
+
+                return MyThing(self.shape[len(i):])
+
+            def __rmul__(self, other):
+                MyThing.rmul_count += 1
+                return self
+
+        np.float64(5)*MyThing((3, 3))
+        assert_(MyThing.rmul_count == 1, MyThing.rmul_count)
+        assert_(MyThing.getitem_count <= 2, MyThing.getitem_count)
+
+    def test_inplace_fancy_indexing(self):
+
+        a = np.arange(10)
+        np.add.at(a, [2, 5, 2], 1)
+        assert_equal(a, [0, 1, 4, 3, 4, 6, 6, 7, 8, 9])
+
+        a = np.arange(10)
+        b = np.array([100, 100, 100])
+        np.add.at(a, [2, 5, 2], b)
+        assert_equal(a, [0, 1, 202, 3, 4, 105, 6, 7, 8, 9])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
+        np.add.at(a, (slice(None), [1, 2, 1]), b)
+        assert_equal(a, [[0, 201, 102], [3, 404, 205], [6, 607, 308]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), slice(None), [1, 2, 1]), b)
+        assert_equal(a,
+            [[[0, 401, 202],
+              [3, 404, 205],
+              [6, 407, 208]],
+
+             [[9, 410, 211],
+              [12, 413, 214],
+              [15, 416, 217]],
+
+             [[18, 419, 220],
+              [21, 422, 223],
+              [24, 425, 226]]])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
+        np.add.at(a, ([1, 2, 1], slice(None)), b)
+        assert_equal(a, [[0, 1, 2], [403, 404, 405], [206, 207, 208]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), [1, 2, 1], slice(None)), b)
+        assert_equal(a,
+            [[[0,  1,  2],
+              [203, 404, 605],
+              [106, 207, 308]],
+
+             [[9,  10, 11],
+              [212, 413, 614],
+              [115, 216, 317]],
+
+             [[18, 19, 20],
+              [221, 422, 623],
+              [124, 225, 326]]])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (0, [1, 2, 1]), b)
+        assert_equal(a, [[0, 401, 202], [3, 4, 5], [6, 7, 8]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, ([1, 2, 1], 0, slice(None)), b)
+        assert_equal(a,
+            [[[0,  1,  2],
+              [3,  4,  5],
+              [6,  7,  8]],
+
+             [[209, 410, 611],
+              [12,  13, 14],
+              [15,  16, 17]],
+
+             [[118, 219, 320],
+              [21,  22, 23],
+              [24,  25, 26]]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), slice(None), slice(None)), b)
+        assert_equal(a,
+            [[[100, 201, 302],
+              [103, 204, 305],
+              [106, 207, 308]],
+
+             [[109, 210, 311],
+              [112, 213, 314],
+              [115, 216, 317]],
+
+             [[118, 219, 320],
+              [121, 222, 323],
+              [124, 225, 326]]])
+
+        a = np.arange(10)
+        np.negative.at(a, [2, 5, 2])
+        assert_equal(a, [0, 1, 2, 3, 4, -5, 6, 7, 8, 9])
+
+        # Test 0-dim array
+        a = np.array(0)
+        np.add.at(a, (), 1)
+        assert_equal(a, 1)
+
+        assert_raises(IndexError, np.add.at, a, 0, 1)
+        assert_raises(IndexError, np.add.at, a, [], 1)
+
+        # Test mixed dtypes
+        a = np.arange(10)
+        np.power.at(a, [1, 2, 3, 2], 3.5)
+        assert_equal(a, np.array([0, 1, 4414, 46, 4, 5, 6, 7, 8, 9]))
+
+        # Test boolean indexing and boolean ufuncs
+        a = np.arange(10)
+        index = a % 2 == 0
+        np.equal.at(a, index, [0, 2, 4, 6, 8])
+        assert_equal(a, [1, 1, 1, 3, 1, 5, 1, 7, 1, 9])
+
+        # Test unary operator
+        a = np.arange(10, dtype='u4')
+        np.invert.at(a, [2, 5, 2])
+        assert_equal(a, [0, 1, 2, 3, 4, 5 ^ 0xffffffff, 6, 7, 8, 9])
+
+        # Test empty subspace
+        orig = np.arange(4)
+        a = orig[:, None][:, 0:0]
+        np.add.at(a, [0, 1], 3)
+        assert_array_equal(orig, np.arange(4))
+
+        # Test with swapped byte order
+        index = np.array([1, 2, 1], np.dtype('i').newbyteorder())
+        values = np.array([1, 2, 3, 4], np.dtype('f').newbyteorder())
+        np.add.at(values, index, 3)
+        assert_array_equal(values, [1, 8, 6, 4])
+
+        # Test exception thrown
+        values = np.array(['a', 1], dtype=np.object)
+        self.assertRaises(TypeError, np.add.at, values, [0, 1], 1)
+        assert_array_equal(values, np.array(['a', 1], dtype=np.object))
+
+        # Test multiple output ufuncs raise error, gh-5665
+        assert_raises(ValueError, np.modf.at, np.arange(10), [1])
+
+    def test_reduce_arguments(self):
+        f = np.add.reduce
+        d = np.ones((5,2), dtype=int)
+        o = np.ones((2,), dtype=d.dtype)
+        r = o * 5
+        assert_equal(f(d), r)
+        # a, axis=0, dtype=None, out=None, keepdims=False
+        assert_equal(f(d, axis=0), r)
+        assert_equal(f(d, 0), r)
+        assert_equal(f(d, 0, dtype=None), r)
+        assert_equal(f(d, 0, dtype='i'), r)
+        assert_equal(f(d, 0, 'i'), r)
+        assert_equal(f(d, 0, None), r)
+        assert_equal(f(d, 0, None, out=None), r)
+        assert_equal(f(d, 0, None, out=o), r)
+        assert_equal(f(d, 0, None, o), r)
+        assert_equal(f(d, 0, None, None), r)
+        assert_equal(f(d, 0, None, None, keepdims=False), r)
+        assert_equal(f(d, 0, None, None, True), r.reshape((1,) + r.shape))
+        # multiple keywords
+        assert_equal(f(d, axis=0, dtype=None, out=None, keepdims=False), r)
+        assert_equal(f(d, 0, dtype=None, out=None, keepdims=False), r)
+        assert_equal(f(d, 0, None, out=None, keepdims=False), r)
+
+        # too little
+        assert_raises(TypeError, f)
+        # too much
+        assert_raises(TypeError, f, d, 0, None, None, False, 1)
+        # invalid axis
+        assert_raises(TypeError, f, d, "invalid")
+        assert_raises(TypeError, f, d, axis="invalid")
+        assert_raises(TypeError, f, d, axis="invalid", dtype=None,
+                      keepdims=True)
+        # invalid dtype
+        assert_raises(TypeError, f, d, 0, "invalid")
+        assert_raises(TypeError, f, d, dtype="invalid")
+        assert_raises(TypeError, f, d, dtype="invalid", out=None)
+        # invalid out
+        assert_raises(TypeError, f, d, 0, None, "invalid")
+        assert_raises(TypeError, f, d, out="invalid")
+        assert_raises(TypeError, f, d, out="invalid", dtype=None)
+        # keepdims boolean, no invalid value
+        # assert_raises(TypeError, f, d, 0, None, None, "invalid")
+        # assert_raises(TypeError, f, d, keepdims="invalid", axis=0, dtype=None)
+        # invalid mix
+        assert_raises(TypeError, f, d, 0, keepdims="invalid", dtype="invalid",
+                     out=None)
+
+        # invalid keyord
+        assert_raises(TypeError, f, d, axis=0, dtype=None, invalid=0)
+        assert_raises(TypeError, f, d, invalid=0)
+        assert_raises(TypeError, f, d, 0, keepdims=True, invalid="invalid",
+                      out=None)
+        assert_raises(TypeError, f, d, axis=0, dtype=None, keepdims=True,
+                      out=None, invalid=0)
+        assert_raises(TypeError, f, d, axis=0, dtype=None,
+                      out=None, invalid=0)
+
+    def test_structured_equal(self):
+        # https://github.com/numpy/numpy/issues/4855
+
+        class MyA(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kwargs):
+                return getattr(ufunc, method)(*(input.view(np.ndarray)
+                                              for input in inputs), **kwargs)
+        a = np.arange(12.).reshape(4,3)
+        ra = a.view(dtype=('f8,f8,f8')).squeeze()
+        mra = ra.view(MyA)
+
+        target = np.array([ True, False, False, False], dtype=bool)
+        assert_equal(np.all(target == (mra == ra[0])), True)
+
+    def test_NotImplemented_not_returned(self):
+        # See gh-5964 and gh-2091. Some of these functions are not operator
+        # related and were fixed for other reasons in the past.
+        binary_funcs = [
+            np.power, np.add, np.subtract, np.multiply, np.divide,
+            np.true_divide, np.floor_divide, np.bitwise_and, np.bitwise_or,
+            np.bitwise_xor, np.left_shift, np.right_shift, np.fmax,
+            np.fmin, np.fmod, np.hypot, np.logaddexp, np.logaddexp2,
+            np.logical_and, np.logical_or, np.logical_xor, np.maximum,
+            np.minimum, np.mod
+            ]
+
+        # These functions still return NotImplemented. Will be fixed in
+        # future.
+        # bad = [np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal]
+
+        a = np.array('1')
+        b = 1
+        for f in binary_funcs:
+            assert_raises(TypeError, f, a, b)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
new file mode 100644
index 0000000000..da52e0dde3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
@@ -0,0 +1,2062 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import platform
+import warnings
+import itertools
+
+from numpy.testing.utils import _gen_alignment_data
+import numpy.core.umath as ncu
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_almost_equal, assert_array_almost_equal,
+    dec, assert_allclose, assert_no_warnings
+)
+
+
+def on_powerpc():
+    """ True if we are running on a Power PC platform."""
+    return platform.processor() == 'powerpc' or \
+           platform.machine().startswith('ppc')
+
+
+class _FilterInvalids(object):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+
+class TestConstants(TestCase):
+    def test_pi(self):
+        assert_allclose(ncu.pi, 3.141592653589793, 1e-15)
+
+    def test_e(self):
+        assert_allclose(ncu.e, 2.718281828459045, 1e-15)
+
+    def test_euler_gamma(self):
+        assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15)
+
+
+class TestOut(TestCase):
+    def test_out_subok(self):
+        for subok in (True, False):
+            a = np.array(0.5)
+            o = np.empty(())
+
+            r = np.add(a, 2, o, subok=subok)
+            assert_(r is o)
+            r = np.add(a, 2, out=o, subok=subok)
+            assert_(r is o)
+            r = np.add(a, 2, out=(o,), subok=subok)
+            assert_(r is o)
+
+            d = np.array(5.7)
+            o1 = np.empty(())
+            o2 = np.empty((), dtype=np.int32)
+
+            r1, r2 = np.frexp(d, o1, None, subok=subok)
+            assert_(r1 is o1)
+            r1, r2 = np.frexp(d, None, o2, subok=subok)
+            assert_(r2 is o2)
+            r1, r2 = np.frexp(d, o1, o2, subok=subok)
+            assert_(r1 is o1)
+            assert_(r2 is o2)
+
+            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
+            assert_(r1 is o1)
+            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
+            assert_(r2 is o2)
+            r1, r2 = np.frexp(d, out=(o1, o2), subok=subok)
+            assert_(r1 is o1)
+            assert_(r2 is o2)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings('always', '', DeprecationWarning)
+                r1, r2 = np.frexp(d, out=o1, subok=subok)
+                assert_(r1 is o1)
+                assert_(w[0].category is DeprecationWarning)
+
+            assert_raises(ValueError, np.add, a, 2, o, o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, o, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, None, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(), subok=subok)
+            assert_raises(TypeError, np.add, a, 2, [], subok=subok)
+            assert_raises(TypeError, np.add, a, 2, out=[], subok=subok)
+            assert_raises(TypeError, np.add, a, 2, out=([],), subok=subok)
+            o.flags.writeable = False
+            assert_raises(ValueError, np.add, a, 2, o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(o,), subok=subok)
+
+    def test_out_wrap_subok(self):
+        class ArrayWrap(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls, arr):
+                return np.asarray(arr).view(cls).copy()
+
+            def __array_wrap__(self, arr, context):
+                return arr.view(type(self))
+
+        for subok in (True, False):
+            a = ArrayWrap([0.5])
+
+            r = np.add(a, 2, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, None, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, out=None, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, out=(None,), subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            d = ArrayWrap([5.7])
+            o1 = np.empty((1,))
+            o2 = np.empty((1,), dtype=np.int32)
+
+            r1, r2 = np.frexp(d, o1, subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, o1, None, subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, None, o2, subok=subok)
+            if subok:
+                assert_(isinstance(r1, ArrayWrap))
+            else:
+                assert_(type(r1) == np.ndarray)
+
+            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
+            if subok:
+                assert_(isinstance(r1, ArrayWrap))
+            else:
+                assert_(type(r1) == np.ndarray)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings('always', '', DeprecationWarning)
+                r1, r2 = np.frexp(d, out=o1, subok=subok)
+                if subok:
+                    assert_(isinstance(r2, ArrayWrap))
+                else:
+                    assert_(type(r2) == np.ndarray)
+                assert_(w[0].category is DeprecationWarning)
+
+
+class TestDivision(TestCase):
+    def test_division_int(self):
+        # int division should follow Python
+        x = np.array([5, 10, 90, 100, -5, -10, -90, -100, -120])
+        if 5 / 10 == 0.5:
+            assert_equal(x / 100, [0.05, 0.1, 0.9, 1,
+                                   -0.05, -0.1, -0.9, -1, -1.2])
+        else:
+            assert_equal(x / 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
+        assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
+        assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80])
+
+    def test_division_complex(self):
+        # check that implementation is correct
+        msg = "Complex division implementation check"
+        x = np.array([1. + 1.*1j, 1. + .5*1j, 1. + 2.*1j], dtype=np.complex128)
+        assert_almost_equal(x**2/x, x, err_msg=msg)
+        # check overflow, underflow
+        msg = "Complex division overflow/underflow check"
+        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
+        y = x**2/x
+        assert_almost_equal(y/x, [1, 1], err_msg=msg)
+
+    def test_zero_division_complex(self):
+        with np.errstate(invalid="ignore", divide="ignore"):
+            x = np.array([0.0], dtype=np.complex128)
+            y = 1.0/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.inf, np.nan)/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.nan, np.inf)/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.inf, np.inf)/x
+            assert_(np.isinf(y)[0])
+            y = 0.0/x
+            assert_(np.isnan(y)[0])
+
+    def test_floor_division_complex(self):
+        # check that implementation is correct
+        msg = "Complex floor division implementation check"
+        x = np.array([.9 + 1j, -.1 + 1j, .9 + .5*1j, .9 + 2.*1j], dtype=np.complex128)
+        y = np.array([0., -1., 0., 0.], dtype=np.complex128)
+        assert_equal(np.floor_divide(x**2, x), y, err_msg=msg)
+        # check overflow, underflow
+        msg = "Complex floor division overflow/underflow check"
+        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
+        y = np.floor_divide(x**2, x)
+        assert_equal(y, [1.e+110, 0], err_msg=msg)
+
+
+class TestRemainder(TestCase):
+
+    def test_remainder_basic(self):
+        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                if sg1 == -1 and dt1 in np.typecodes['UnsignedInteger']:
+                    continue
+                if sg2 == -1 and dt2 in np.typecodes['UnsignedInteger']:
+                    continue
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*71, dtype=dt1)
+                b = np.array(sg2*19, dtype=dt2)
+                div = np.floor_divide(a, b)
+                rem = np.remainder(a, b)
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_remainder_exact(self):
+        # test that float results are exact for small integers. This also
+        # holds for the same integers scaled by powers of two.
+        nlst = list(range(-127, 0))
+        plst = list(range(1, 128))
+        dividend = nlst + [0] + plst
+        divisor = nlst + plst
+        arg = list(itertools.product(dividend, divisor))
+        tgt = list(divmod(*t) for t in arg)
+
+        a, b = np.array(arg, dtype=int).T
+        # convert exact integer results from Python to float so that
+        # signed zero can be used, it is checked.
+        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
+        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
+        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
+
+        for dt in np.typecodes['Float']:
+            msg = 'dtype: %s' % (dt,)
+            fa = a.astype(dt)
+            fb = b.astype(dt)
+            div = np.floor_divide(fa, fb)
+            rem = np.remainder(fa, fb)
+            assert_equal(div, tgtdiv, err_msg=msg)
+            assert_equal(rem, tgtrem, err_msg=msg)
+
+    def test_float_remainder_roundoff(self):
+        # gh-6127
+        dt = np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*78*6e-8, dtype=dt1)
+                b = np.array(sg2*6e-8, dtype=dt2)
+                div = np.floor_divide(a, b)
+                rem = np.remainder(a, b)
+                # Equal assertion should hold when fmod is used
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_remainder_corner_cases(self):
+        # Check remainder magnitude.
+        for dt in np.typecodes['Float']:
+            b = np.array(1.0, dtype=dt)
+            a = np.nextafter(np.array(0.0, dtype=dt), -b)
+            rem = np.remainder(a, b)
+            assert_(rem <= b, 'dt: %s' % dt)
+            rem = np.remainder(-a, -b)
+            assert_(rem >= -b, 'dt: %s' % dt)
+
+        # Check nans, inf
+        with warnings.catch_warnings():
+            warnings.simplefilter('always')
+            warnings.simplefilter('ignore', RuntimeWarning)
+            for dt in np.typecodes['Float']:
+                fone = np.array(1.0, dtype=dt)
+                fzer = np.array(0.0, dtype=dt)
+                finf = np.array(np.inf, dtype=dt)
+                fnan = np.array(np.nan, dtype=dt)
+                rem = np.remainder(fone, fzer)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+                # MSVC 2008 returns NaN here, so disable the check.
+                #rem = np.remainder(fone, finf)
+                #assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem))
+                rem = np.remainder(fone, fnan)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+                rem = np.remainder(finf, fone)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+
+
+class TestCbrt(TestCase):
+    def test_cbrt_scalar(self):
+        assert_almost_equal((np.cbrt(np.float32(-2.5)**3)), -2.5)
+
+    def test_cbrt(self):
+        x = np.array([1., 2., -3., np.inf, -np.inf])
+        assert_almost_equal(np.cbrt(x**3), x)
+
+        assert_(np.isnan(np.cbrt(np.nan)))
+        assert_equal(np.cbrt(np.inf), np.inf)
+        assert_equal(np.cbrt(-np.inf), -np.inf)
+
+
+class TestPower(TestCase):
+    def test_power_float(self):
+        x = np.array([1., 2., 3.])
+        assert_equal(x**0, [1., 1., 1.])
+        assert_equal(x**1, x)
+        assert_equal(x**2, [1., 4., 9.])
+        y = x.copy()
+        y **= 2
+        assert_equal(y, [1., 4., 9.])
+        assert_almost_equal(x**(-1), [1., 0.5, 1./3])
+        assert_almost_equal(x**(0.5), [1., ncu.sqrt(2), ncu.sqrt(3)])
+
+        for out, inp, msg in _gen_alignment_data(dtype=np.float32,
+                                                 type='unary',
+                                                 max_size=11):
+            exp = [ncu.sqrt(i) for i in inp]
+            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
+            np.sqrt(inp, out=out)
+            assert_equal(out, exp, err_msg=msg)
+
+        for out, inp, msg in _gen_alignment_data(dtype=np.float64,
+                                                 type='unary',
+                                                 max_size=7):
+            exp = [ncu.sqrt(i) for i in inp]
+            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
+            np.sqrt(inp, out=out)
+            assert_equal(out, exp, err_msg=msg)
+
+    def test_power_complex(self):
+        x = np.array([1+2j, 2+3j, 3+4j])
+        assert_equal(x**0, [1., 1., 1.])
+        assert_equal(x**1, x)
+        assert_almost_equal(x**2, [-3+4j, -5+12j, -7+24j])
+        assert_almost_equal(x**3, [(1+2j)**3, (2+3j)**3, (3+4j)**3])
+        assert_almost_equal(x**4, [(1+2j)**4, (2+3j)**4, (3+4j)**4])
+        assert_almost_equal(x**(-1), [1/(1+2j), 1/(2+3j), 1/(3+4j)])
+        assert_almost_equal(x**(-2), [1/(1+2j)**2, 1/(2+3j)**2, 1/(3+4j)**2])
+        assert_almost_equal(x**(-3), [(-11+2j)/125, (-46-9j)/2197,
+                                      (-117-44j)/15625])
+        assert_almost_equal(x**(0.5), [ncu.sqrt(1+2j), ncu.sqrt(2+3j),
+                                       ncu.sqrt(3+4j)])
+        norm = 1./((x**14)[0])
+        assert_almost_equal(x**14 * norm,
+                [i * norm for i in [-76443+16124j, 23161315+58317492j,
+                                    5583548873 + 2465133864j]])
+
+        # Ticket #836
+        def assert_complex_equal(x, y):
+            assert_array_equal(x.real, y.real)
+            assert_array_equal(x.imag, y.imag)
+
+        for z in [complex(0, np.inf), complex(1, np.inf)]:
+            z = np.array([z], dtype=np.complex_)
+            with np.errstate(invalid="ignore"):
+                assert_complex_equal(z**1, z)
+                assert_complex_equal(z**2, z*z)
+                assert_complex_equal(z**3, z*z*z)
+
+    def test_power_zero(self):
+        # ticket #1271
+        zero = np.array([0j])
+        one = np.array([1+0j])
+        cnan = np.array([complex(np.nan, np.nan)])
+        # FIXME cinf not tested.
+        #cinf = np.array([complex(np.inf, 0)])
+
+        def assert_complex_equal(x, y):
+            x, y = np.asarray(x), np.asarray(y)
+            assert_array_equal(x.real, y.real)
+            assert_array_equal(x.imag, y.imag)
+
+        # positive powers
+        for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
+            assert_complex_equal(np.power(zero, p), zero)
+
+        # zero power
+        assert_complex_equal(np.power(zero, 0), one)
+        with np.errstate(invalid="ignore"):
+            assert_complex_equal(np.power(zero, 0+1j), cnan)
+
+            # negative power
+            for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
+                assert_complex_equal(np.power(zero, -p), cnan)
+            assert_complex_equal(np.power(zero, -1+0.2j), cnan)
+
+    def test_fast_power(self):
+        x = np.array([1, 2, 3], np.int16)
+        assert_((x**2.00001).dtype is (x**2.0).dtype)
+
+        # Check that the fast path ignores 1-element not 0-d arrays
+        res = x ** np.array([[[2]]])
+        assert_equal(res.shape, (1, 1, 3))
+
+
+class TestLog2(TestCase):
+    def test_log2_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)
+            assert_almost_equal(np.log2(xf), yf)
+
+    def test_log2_ints(self):
+        # a good log2 implementation should provide this,
+        # might fail on OS with bad libm
+        for i in range(1, 65):
+            v = np.log2(2.**i)
+            assert_equal(v, float(i), err_msg='at exponent %d' % i)
+
+    def test_log2_special(self):
+        assert_equal(np.log2(1.), 0.)
+        assert_equal(np.log2(np.inf), np.inf)
+        assert_(np.isnan(np.log2(np.nan)))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.log2(-1.)))
+            assert_(np.isnan(np.log2(-np.inf)))
+            assert_equal(np.log2(0.), -np.inf)
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+            assert_(w[2].category is RuntimeWarning)
+
+
+class TestExp2(TestCase):
+    def test_exp2_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)
+            assert_almost_equal(np.exp2(yf), xf)
+
+
+class TestLogAddExp2(_FilterInvalids):
+    # Need test for intermediate precisions
+    def test_logaddexp2_values(self):
+        x = [1, 2, 3, 4, 5]
+        y = [5, 4, 3, 2, 1]
+        z = [6, 6, 6, 6, 6]
+        for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]):
+            xf = np.log2(np.array(x, dtype=dt))
+            yf = np.log2(np.array(y, dtype=dt))
+            zf = np.log2(np.array(z, dtype=dt))
+            assert_almost_equal(np.logaddexp2(xf, yf), zf, decimal=dec_)
+
+    def test_logaddexp2_range(self):
+        x = [1000000, -1000000, 1000200, -1000200]
+        y = [1000200, -1000200, 1000000, -1000000]
+        z = [1000200, -1000000, 1000200, -1000000]
+        for dt in ['f', 'd', 'g']:
+            logxf = np.array(x, dtype=dt)
+            logyf = np.array(y, dtype=dt)
+            logzf = np.array(z, dtype=dt)
+            assert_almost_equal(np.logaddexp2(logxf, logyf), logzf)
+
+    def test_inf(self):
+        inf = np.inf
+        x = [inf, -inf,  inf, -inf, inf, 1,  -inf,  1]
+        y = [inf,  inf, -inf, -inf, 1,   inf, 1,   -inf]
+        z = [inf,  inf,  inf, -inf, inf, inf, 1,    1]
+        with np.errstate(invalid='raise'):
+            for dt in ['f', 'd', 'g']:
+                logxf = np.array(x, dtype=dt)
+                logyf = np.array(y, dtype=dt)
+                logzf = np.array(z, dtype=dt)
+                assert_equal(np.logaddexp2(logxf, logyf), logzf)
+
+    def test_nan(self):
+        assert_(np.isnan(np.logaddexp2(np.nan, np.inf)))
+        assert_(np.isnan(np.logaddexp2(np.inf, np.nan)))
+        assert_(np.isnan(np.logaddexp2(np.nan, 0)))
+        assert_(np.isnan(np.logaddexp2(0, np.nan)))
+        assert_(np.isnan(np.logaddexp2(np.nan, np.nan)))
+
+
+class TestLog(TestCase):
+    def test_log_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            log2_ = 0.69314718055994530943
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)*log2_
+            assert_almost_equal(np.log(xf), yf)
+
+
+class TestExp(TestCase):
+    def test_exp_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            log2_ = 0.69314718055994530943
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)*log2_
+            assert_almost_equal(np.exp(yf), xf)
+
+
+class TestLogAddExp(_FilterInvalids):
+    def test_logaddexp_values(self):
+        x = [1, 2, 3, 4, 5]
+        y = [5, 4, 3, 2, 1]
+        z = [6, 6, 6, 6, 6]
+        for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]):
+            xf = np.log(np.array(x, dtype=dt))
+            yf = np.log(np.array(y, dtype=dt))
+            zf = np.log(np.array(z, dtype=dt))
+            assert_almost_equal(np.logaddexp(xf, yf), zf, decimal=dec_)
+
+    def test_logaddexp_range(self):
+        x = [1000000, -1000000, 1000200, -1000200]
+        y = [1000200, -1000200, 1000000, -1000000]
+        z = [1000200, -1000000, 1000200, -1000000]
+        for dt in ['f', 'd', 'g']:
+            logxf = np.array(x, dtype=dt)
+            logyf = np.array(y, dtype=dt)
+            logzf = np.array(z, dtype=dt)
+            assert_almost_equal(np.logaddexp(logxf, logyf), logzf)
+
+    def test_inf(self):
+        inf = np.inf
+        x = [inf, -inf,  inf, -inf, inf, 1,  -inf,  1]
+        y = [inf,  inf, -inf, -inf, 1,   inf, 1,   -inf]
+        z = [inf,  inf,  inf, -inf, inf, inf, 1,    1]
+        with np.errstate(invalid='raise'):
+            for dt in ['f', 'd', 'g']:
+                logxf = np.array(x, dtype=dt)
+                logyf = np.array(y, dtype=dt)
+                logzf = np.array(z, dtype=dt)
+                assert_equal(np.logaddexp(logxf, logyf), logzf)
+
+    def test_nan(self):
+        assert_(np.isnan(np.logaddexp(np.nan, np.inf)))
+        assert_(np.isnan(np.logaddexp(np.inf, np.nan)))
+        assert_(np.isnan(np.logaddexp(np.nan, 0)))
+        assert_(np.isnan(np.logaddexp(0, np.nan)))
+        assert_(np.isnan(np.logaddexp(np.nan, np.nan)))
+
+
+class TestLog1p(TestCase):
+    def test_log1p(self):
+        assert_almost_equal(ncu.log1p(0.2), ncu.log(1.2))
+        assert_almost_equal(ncu.log1p(1e-6), ncu.log(1+1e-6))
+
+    def test_special(self):
+        with np.errstate(invalid="ignore", divide="ignore"):
+            assert_equal(ncu.log1p(np.nan), np.nan)
+            assert_equal(ncu.log1p(np.inf), np.inf)
+            assert_equal(ncu.log1p(-1.), -np.inf)
+            assert_equal(ncu.log1p(-2.), np.nan)
+            assert_equal(ncu.log1p(-np.inf), np.nan)
+
+
+class TestExpm1(TestCase):
+    def test_expm1(self):
+        assert_almost_equal(ncu.expm1(0.2), ncu.exp(0.2)-1)
+        assert_almost_equal(ncu.expm1(1e-6), ncu.exp(1e-6)-1)
+
+    def test_special(self):
+        assert_equal(ncu.expm1(np.inf), np.inf)
+        assert_equal(ncu.expm1(0.), 0.)
+        assert_equal(ncu.expm1(-0.), -0.)
+        assert_equal(ncu.expm1(np.inf), np.inf)
+        assert_equal(ncu.expm1(-np.inf), -1.)
+
+
+class TestHypot(TestCase, object):
+    def test_simple(self):
+        assert_almost_equal(ncu.hypot(1, 1), ncu.sqrt(2))
+        assert_almost_equal(ncu.hypot(0, 0), 0)
+
+
+def assert_hypot_isnan(x, y):
+    with np.errstate(invalid='ignore'):
+        assert_(np.isnan(ncu.hypot(x, y)),
+                "hypot(%s, %s) is %s, not nan" % (x, y, ncu.hypot(x, y)))
+
+
+def assert_hypot_isinf(x, y):
+    with np.errstate(invalid='ignore'):
+        assert_(np.isinf(ncu.hypot(x, y)),
+                "hypot(%s, %s) is %s, not inf" % (x, y, ncu.hypot(x, y)))
+
+
+class TestHypotSpecialValues(TestCase):
+    def test_nan_outputs(self):
+        assert_hypot_isnan(np.nan, np.nan)
+        assert_hypot_isnan(np.nan, 1)
+
+    def test_nan_outputs2(self):
+        assert_hypot_isinf(np.nan, np.inf)
+        assert_hypot_isinf(np.inf, np.nan)
+        assert_hypot_isinf(np.inf, 0)
+        assert_hypot_isinf(0, np.inf)
+        assert_hypot_isinf(np.inf, np.inf)
+        assert_hypot_isinf(np.inf, 23.0)
+
+    def test_no_fpe(self):
+        assert_no_warnings(ncu.hypot, np.inf, 0)
+
+
+def assert_arctan2_isnan(x, y):
+    assert_(np.isnan(ncu.arctan2(x, y)), "arctan(%s, %s) is %s, not nan" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_ispinf(x, y):
+    assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) > 0), "arctan(%s, %s) is %s, not +inf" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_isninf(x, y):
+    assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) < 0), "arctan(%s, %s) is %s, not -inf" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_ispzero(x, y):
+    assert_((ncu.arctan2(x, y) == 0 and not np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not +0" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_isnzero(x, y):
+    assert_((ncu.arctan2(x, y) == 0 and np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not -0" % (x, y, ncu.arctan2(x, y)))
+
+
+class TestArctan2SpecialValues(TestCase):
+    def test_one_one(self):
+        # atan2(1, 1) returns pi/4.
+        assert_almost_equal(ncu.arctan2(1, 1), 0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(-1, 1), -0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(1, -1), 0.75 * np.pi)
+
+    def test_zero_nzero(self):
+        # atan2(+-0, -0) returns +-pi.
+        assert_almost_equal(ncu.arctan2(np.PZERO, np.NZERO), np.pi)
+        assert_almost_equal(ncu.arctan2(np.NZERO, np.NZERO), -np.pi)
+
+    def test_zero_pzero(self):
+        # atan2(+-0, +0) returns +-0.
+        assert_arctan2_ispzero(np.PZERO, np.PZERO)
+        assert_arctan2_isnzero(np.NZERO, np.PZERO)
+
+    def test_zero_negative(self):
+        # atan2(+-0, x) returns +-pi for x < 0.
+        assert_almost_equal(ncu.arctan2(np.PZERO, -1), np.pi)
+        assert_almost_equal(ncu.arctan2(np.NZERO, -1), -np.pi)
+
+    def test_zero_positive(self):
+        # atan2(+-0, x) returns +-0 for x > 0.
+        assert_arctan2_ispzero(np.PZERO, 1)
+        assert_arctan2_isnzero(np.NZERO, 1)
+
+    def test_positive_zero(self):
+        # atan2(y, +-0) returns +pi/2 for y > 0.
+        assert_almost_equal(ncu.arctan2(1, np.PZERO), 0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(1, np.NZERO), 0.5 * np.pi)
+
+    def test_negative_zero(self):
+        # atan2(y, +-0) returns -pi/2 for y < 0.
+        assert_almost_equal(ncu.arctan2(-1, np.PZERO), -0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(-1, np.NZERO), -0.5 * np.pi)
+
+    def test_any_ninf(self):
+        # atan2(+-y, -infinity) returns +-pi for finite y > 0.
+        assert_almost_equal(ncu.arctan2(1, np.NINF),  np.pi)
+        assert_almost_equal(ncu.arctan2(-1, np.NINF), -np.pi)
+
+    def test_any_pinf(self):
+        # atan2(+-y, +infinity) returns +-0 for finite y > 0.
+        assert_arctan2_ispzero(1, np.inf)
+        assert_arctan2_isnzero(-1, np.inf)
+
+    def test_inf_any(self):
+        # atan2(+-infinity, x) returns +-pi/2 for finite x.
+        assert_almost_equal(ncu.arctan2( np.inf, 1),  0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, 1), -0.5 * np.pi)
+
+    def test_inf_ninf(self):
+        # atan2(+-infinity, -infinity) returns +-3*pi/4.
+        assert_almost_equal(ncu.arctan2( np.inf, -np.inf),  0.75 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, -np.inf), -0.75 * np.pi)
+
+    def test_inf_pinf(self):
+        # atan2(+-infinity, +infinity) returns +-pi/4.
+        assert_almost_equal(ncu.arctan2( np.inf, np.inf),  0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, np.inf), -0.25 * np.pi)
+
+    def test_nan_any(self):
+        # atan2(nan, x) returns nan for any x, including inf
+        assert_arctan2_isnan(np.nan, np.inf)
+        assert_arctan2_isnan(np.inf, np.nan)
+        assert_arctan2_isnan(np.nan, np.nan)
+
+
+class TestLdexp(TestCase):
+    def _check_ldexp(self, tp):
+        assert_almost_equal(ncu.ldexp(np.array(2., np.float32),
+                                      np.array(3, tp)), 16.)
+        assert_almost_equal(ncu.ldexp(np.array(2., np.float64),
+                                      np.array(3, tp)), 16.)
+        assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble),
+                                      np.array(3, tp)), 16.)
+
+    def test_ldexp(self):
+        # The default Python int type should work
+        assert_almost_equal(ncu.ldexp(2., 3),  16.)
+        # The following int types should all be accepted
+        self._check_ldexp(np.int8)
+        self._check_ldexp(np.int16)
+        self._check_ldexp(np.int32)
+        self._check_ldexp('i')
+        self._check_ldexp('l')
+
+    def test_ldexp_overflow(self):
+        # silence warning emitted on overflow
+        with np.errstate(over="ignore"):
+            imax = np.iinfo(np.dtype('l')).max
+            imin = np.iinfo(np.dtype('l')).min
+            assert_equal(ncu.ldexp(2., imax), np.inf)
+            assert_equal(ncu.ldexp(2., imin), 0)
+
+
+class TestMaximum(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.maximum.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), np.nan)
+            assert_equal(func(tmp2), np.nan)
+
+    def test_reduce_complex(self):
+        assert_equal(np.maximum.reduce([1, 2j]), 1)
+        assert_equal(np.maximum.reduce([1+3j, 2j]), 1+3j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([nan, nan, nan])
+        assert_equal(np.maximum(arg1, arg2), out)
+
+    def test_object_nans(self):
+        # Multiple checks to give this a chance to
+        # fail if cmp is used instead of rich compare.
+        # Failure cannot be guaranteed.
+        for i in range(1):
+            x = np.array(float('nan'), np.object)
+            y = 1.0
+            z = np.array(float('nan'), np.object)
+            assert_(np.maximum(x, y) == 1.0)
+            assert_(np.maximum(z, y) == 1.0)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([nan, nan, nan], dtype=np.complex)
+            assert_equal(np.maximum(arg1, arg2), out)
+
+    def test_object_array(self):
+        arg1 = np.arange(5, dtype=np.object)
+        arg2 = arg1 + 1
+        assert_equal(np.maximum(arg1, arg2), arg2)
+
+
+class TestMinimum(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.minimum.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), np.nan)
+            assert_equal(func(tmp2), np.nan)
+
+    def test_reduce_complex(self):
+        assert_equal(np.minimum.reduce([1, 2j]), 2j)
+        assert_equal(np.minimum.reduce([1+3j, 2j]), 2j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([nan, nan, nan])
+        assert_equal(np.minimum(arg1, arg2), out)
+
+    def test_object_nans(self):
+        # Multiple checks to give this a chance to
+        # fail if cmp is used instead of rich compare.
+        # Failure cannot be guaranteed.
+        for i in range(1):
+            x = np.array(float('nan'), np.object)
+            y = 1.0
+            z = np.array(float('nan'), np.object)
+            assert_(np.minimum(x, y) == 1.0)
+            assert_(np.minimum(z, y) == 1.0)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([nan, nan, nan], dtype=np.complex)
+            assert_equal(np.minimum(arg1, arg2), out)
+
+    def test_object_array(self):
+        arg1 = np.arange(5, dtype=np.object)
+        arg2 = arg1 + 1
+        assert_equal(np.minimum(arg1, arg2), arg1)
+
+
+class TestFmax(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.fmax.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), 9)
+            assert_equal(func(tmp2), 9)
+
+    def test_reduce_complex(self):
+        assert_equal(np.fmax.reduce([1, 2j]), 1)
+        assert_equal(np.fmax.reduce([1+3j, 2j]), 1+3j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([0,   0,   nan])
+        assert_equal(np.fmax(arg1, arg2), out)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([0,    0, nan], dtype=np.complex)
+            assert_equal(np.fmax(arg1, arg2), out)
+
+
+class TestFmin(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.fmin.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), 1)
+            assert_equal(func(tmp2), 1)
+
+    def test_reduce_complex(self):
+        assert_equal(np.fmin.reduce([1, 2j]), 2j)
+        assert_equal(np.fmin.reduce([1+3j, 2j]), 2j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([0,   0,   nan])
+        assert_equal(np.fmin(arg1, arg2), out)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([0,    0, nan], dtype=np.complex)
+            assert_equal(np.fmin(arg1, arg2), out)
+
+
+class TestBool(TestCase):
+    def test_truth_table_logical(self):
+        # 2, 3 and 4 serves as true values
+        input1 = [0, 0, 3, 2]
+        input2 = [0, 4, 0, 2]
+
+        typecodes = (np.typecodes['AllFloat']
+                     + np.typecodes['AllInteger']
+                     + '?')     # boolean
+        for dtype in map(np.dtype, typecodes):
+            arg1 = np.asarray(input1, dtype=dtype)
+            arg2 = np.asarray(input2, dtype=dtype)
+
+            # OR
+            out = [False, True, True, True]
+            for func in (np.logical_or, np.maximum):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+            # AND
+            out = [False, False, False, True]
+            for func in (np.logical_and, np.minimum):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+            # XOR
+            out = [False, True, True, False]
+            for func in (np.logical_xor, np.not_equal):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+
+    def test_truth_table_bitwise(self):
+        arg1 = [False, False, True, True]
+        arg2 = [False, True, False, True]
+
+        out = [False, True, True, True]
+        assert_equal(np.bitwise_or(arg1, arg2), out)
+
+        out = [False, False, False, True]
+        assert_equal(np.bitwise_and(arg1, arg2), out)
+
+        out = [False, True, True, False]
+        assert_equal(np.bitwise_xor(arg1, arg2), out)
+
+
+class TestInt(TestCase):
+    def test_logical_not(self):
+        x = np.ones(10, dtype=np.int16)
+        o = np.ones(10 * 2, dtype=np.bool)
+        tgt = o.copy()
+        tgt[::2] = False
+        os = o[::2]
+        assert_array_equal(np.logical_not(x, out=os), False)
+        assert_array_equal(o, tgt)
+
+
+class TestFloatingPoint(TestCase):
+    def test_floating_point(self):
+        assert_equal(ncu.FLOATING_POINT_SUPPORT, 1)
+
+
+class TestDegrees(TestCase):
+    def test_degrees(self):
+        assert_almost_equal(ncu.degrees(np.pi), 180.0)
+        assert_almost_equal(ncu.degrees(-0.5*np.pi), -90.0)
+
+
+class TestRadians(TestCase):
+    def test_radians(self):
+        assert_almost_equal(ncu.radians(180.0), np.pi)
+        assert_almost_equal(ncu.radians(-90.0), -0.5*np.pi)
+
+
+class TestSign(TestCase):
+    def test_sign(self):
+        a = np.array([np.inf, -np.inf, np.nan, 0.0, 3.0, -3.0])
+        out = np.zeros(a.shape)
+        tgt = np.array([1., -1., np.nan, 0.0, 1.0, -1.0])
+
+        with np.errstate(invalid='ignore'):
+            res = ncu.sign(a)
+            assert_equal(res, tgt)
+            res = ncu.sign(a, out)
+            assert_equal(res, tgt)
+            assert_equal(out, tgt)
+
+    def test_sign_dtype_object(self):
+        # In reference to github issue #6229
+
+        foo = np.array([-.1, 0, .1])
+        a = np.sign(foo.astype(np.object))
+        b = np.sign(foo)
+
+        assert_array_equal(a, b)
+
+    def test_sign_dtype_nan_object(self):
+        # In reference to github issue #6229
+        def test_nan():
+            foo = np.array([np.nan])
+            a = np.sign(foo.astype(np.object))
+
+        assert_raises(TypeError, test_nan)
+
+class TestMinMax(TestCase):
+    def test_minmax_blocked(self):
+        # simd tests on max/min, test all alignments, slow but important
+        # for 2 * vz + 2 * (vs - 1) + 1 (unrolled once)
+        for dt, sz in [(np.float32, 15), (np.float64, 7)]:
+            for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary',
+                                                     max_size=sz):
+                for i in range(inp.size):
+                    inp[:] = np.arange(inp.size, dtype=dt)
+                    inp[i] = np.nan
+                    emsg = lambda: '%r\n%s' % (inp, msg)
+                    assert_(np.isnan(inp.max()), msg=emsg)
+                    assert_(np.isnan(inp.min()), msg=emsg)
+
+                    inp[i] = 1e10
+                    assert_equal(inp.max(), 1e10, err_msg=msg)
+                    inp[i] = -1e10
+                    assert_equal(inp.min(), -1e10, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_equal(d.max(), d[0])
+        assert_equal(d.min(), d[0])
+
+
+class TestAbsoluteNegative(TestCase):
+    def test_abs_neg_blocked(self):
+        # simd tests on abs, test all alignments for vz + 2 * (vs - 1) + 1
+        for dt, sz in [(np.float32, 11), (np.float64, 5)]:
+            for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary',
+                                                     max_size=sz):
+                tgt = [ncu.absolute(i) for i in inp]
+                np.absolute(inp, out=out)
+                assert_equal(out, tgt, err_msg=msg)
+                self.assertTrue((out >= 0).all())
+
+                tgt = [-1*(i) for i in inp]
+                np.negative(inp, out=out)
+                assert_equal(out, tgt, err_msg=msg)
+
+                # will throw invalid flag depending on compiler optimizations
+                with np.errstate(invalid='ignore'):
+                    for v in [np.nan, -np.inf, np.inf]:
+                        for i in range(inp.size):
+                            d = np.arange(inp.size, dtype=dt)
+                            inp[:] = -d
+                            inp[i] = v
+                            d[i] = -v if v == -np.inf else v
+                            assert_array_equal(np.abs(inp), d, err_msg=msg)
+                            np.abs(inp, out=out)
+                            assert_array_equal(out, d, err_msg=msg)
+
+                            assert_array_equal(-inp, -1*inp, err_msg=msg)
+                            np.negative(inp, out=out)
+                            assert_array_equal(out, -1*inp, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_equal(np.abs(d), d)
+        assert_equal(np.negative(d), -d)
+        np.negative(d, out=d)
+        np.negative(np.ones_like(d), out=d)
+        np.abs(d, out=d)
+        np.abs(np.ones_like(d), out=d)
+
+
+class TestSpecialMethods(TestCase):
+    def test_wrap(self):
+
+        class with_wrap(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                r = with_wrap()
+                r.arr = arr
+                r.context = context
+                return r
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x.arr, np.zeros(1))
+        func, args, i = x.context
+        self.assertTrue(func is ncu.minimum)
+        self.assertEqual(len(args), 2)
+        assert_equal(args[0], a)
+        assert_equal(args[1], a)
+        self.assertEqual(i, 0)
+
+    def test_wrap_with_iterable(self):
+        # test fix for bug #1026:
+
+        class with_wrap(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls):
+                return np.asarray(1).view(cls).copy()
+
+            def __array_wrap__(self, arr, context):
+                return arr.view(type(self))
+
+        a = with_wrap()
+        x = ncu.multiply(a, (1, 2, 3))
+        self.assertTrue(isinstance(x, with_wrap))
+        assert_array_equal(x, np.array((1, 2, 3)))
+
+    def test_priority_with_scalar(self):
+        # test fix for bug #826:
+
+        class A(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls):
+                return np.asarray(1.0, 'float64').view(cls).copy()
+
+        a = A()
+        x = np.float64(1)*a
+        self.assertTrue(isinstance(x, A))
+        assert_array_equal(x, np.array(1))
+
+    def test_old_wrap(self):
+
+        class with_wrap(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr):
+                r = with_wrap()
+                r.arr = arr
+                return r
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x.arr, np.zeros(1))
+
+    def test_priority(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                r = type(self)()
+                r.arr = arr
+                r.context = context
+                return r
+
+        class B(A):
+            __array_priority__ = 20.
+
+        class C(A):
+            __array_priority__ = 40.
+
+        x = np.zeros(1)
+        a = A()
+        b = B()
+        c = C()
+        f = ncu.minimum
+        self.assertTrue(type(f(x, x)) is np.ndarray)
+        self.assertTrue(type(f(x, a)) is A)
+        self.assertTrue(type(f(x, b)) is B)
+        self.assertTrue(type(f(x, c)) is C)
+        self.assertTrue(type(f(a, x)) is A)
+        self.assertTrue(type(f(b, x)) is B)
+        self.assertTrue(type(f(c, x)) is C)
+
+        self.assertTrue(type(f(a, a)) is A)
+        self.assertTrue(type(f(a, b)) is B)
+        self.assertTrue(type(f(b, a)) is B)
+        self.assertTrue(type(f(b, b)) is B)
+        self.assertTrue(type(f(b, c)) is C)
+        self.assertTrue(type(f(c, b)) is C)
+        self.assertTrue(type(f(c, c)) is C)
+
+        self.assertTrue(type(ncu.exp(a) is A))
+        self.assertTrue(type(ncu.exp(b) is B))
+        self.assertTrue(type(ncu.exp(c) is C))
+
+    def test_failing_wrap(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                raise RuntimeError
+
+        a = A()
+        self.assertRaises(RuntimeError, ncu.maximum, a, a)
+
+    def test_default_prepare(self):
+
+        class with_wrap(object):
+            __array_priority__ = 10
+
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                return arr
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x, np.zeros(1))
+        assert_equal(type(x), np.ndarray)
+
+    def test_prepare(self):
+
+        class with_prepare(np.ndarray):
+            __array_priority__ = 10
+
+            def __array_prepare__(self, arr, context):
+                # make sure we can return a new
+                return np.array(arr).view(type=with_prepare)
+
+        a = np.array(1).view(type=with_prepare)
+        x = np.add(a, a)
+        assert_equal(x, np.array(2))
+        assert_equal(type(x), with_prepare)
+
+    def test_failing_prepare(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_prepare__(self, arr, context=None):
+                raise RuntimeError
+
+        a = A()
+        self.assertRaises(RuntimeError, ncu.maximum, a, a)
+
+    def test_array_with_context(self):
+
+        class A(object):
+            def __array__(self, dtype=None, context=None):
+                func, args, i = context
+                self.func = func
+                self.args = args
+                self.i = i
+                return np.zeros(1)
+
+        class B(object):
+            def __array__(self, dtype=None):
+                return np.zeros(1, dtype)
+
+        class C(object):
+            def __array__(self):
+                return np.zeros(1)
+
+        a = A()
+        ncu.maximum(np.zeros(1), a)
+        self.assertTrue(a.func is ncu.maximum)
+        assert_equal(a.args[0], 0)
+        self.assertTrue(a.args[1] is a)
+        self.assertTrue(a.i == 1)
+        assert_equal(ncu.maximum(a, B()), 0)
+        assert_equal(ncu.maximum(a, C()), 0)
+
+    def test_ufunc_override_disabled(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        # This test should be removed when __numpy_ufunc__ is re-enabled.
+
+        class MyArray(object):
+            def __numpy_ufunc__(self, *args, **kwargs):
+                self._numpy_ufunc_called = True
+
+        my_array = MyArray()
+        real_array = np.ones(10)
+        assert_raises(TypeError, lambda: real_array + my_array)
+        assert_raises(TypeError, np.add, real_array, my_array)
+        assert not hasattr(my_array, "_numpy_ufunc_called")
+
+
+    def test_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return self, func, method, pos, inputs, kwargs
+
+        a = A()
+        b = np.matrix([1])
+        res0 = np.multiply(a, b)
+        res1 = np.dot(a, b)
+
+        # self
+        assert_equal(res0[0], a)
+        assert_equal(res1[0], a)
+        assert_equal(res0[1], np.multiply)
+        assert_equal(res1[1], np.dot)
+        assert_equal(res0[2], '__call__')
+        assert_equal(res1[2], '__call__')
+        assert_equal(res0[3], 0)
+        assert_equal(res1[3], 0)
+        assert_equal(res0[4], (a, b))
+        assert_equal(res1[4], (a, b))
+        assert_equal(res0[5], {})
+        assert_equal(res1[5], {})
+
+    def test_ufunc_override_mro(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Some multi arg functions for testing.
+        def tres_mul(a, b, c):
+            return a * b * c
+
+        def quatro_mul(a, b, c, d):
+            return a * b * c * d
+
+        # Make these into ufuncs.
+        three_mul_ufunc = np.frompyfunc(tres_mul, 3, 1)
+        four_mul_ufunc = np.frompyfunc(quatro_mul, 4, 1)
+
+        class A(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "A"
+
+        class ASub(A):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "ASub"
+
+        class B(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "B"
+
+        class C(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        class CSub(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        a_sub = ASub()
+        b = B()
+        c = C()
+        c_sub = CSub()
+
+        # Standard
+        res = np.multiply(a, a_sub)
+        assert_equal(res, "ASub")
+        res = np.multiply(a_sub, b)
+        assert_equal(res, "ASub")
+
+        # With 1 NotImplemented
+        res = np.multiply(c, a)
+        assert_equal(res, "A")
+
+        # Both NotImplemented.
+        assert_raises(TypeError, np.multiply, c, c_sub)
+        assert_raises(TypeError, np.multiply, c_sub, c)
+        assert_raises(TypeError, np.multiply, 2, c)
+
+        # Ternary testing.
+        assert_equal(three_mul_ufunc(a, 1, 2), "A")
+        assert_equal(three_mul_ufunc(1, a, 2), "A")
+        assert_equal(three_mul_ufunc(1, 2, a), "A")
+
+        assert_equal(three_mul_ufunc(a, a, 6), "A")
+        assert_equal(three_mul_ufunc(a, 2, a), "A")
+        assert_equal(three_mul_ufunc(a, 2, b), "A")
+        assert_equal(three_mul_ufunc(a, 2, a_sub), "ASub")
+        assert_equal(three_mul_ufunc(a, a_sub, 3), "ASub")
+        assert_equal(three_mul_ufunc(c, a_sub, 3), "ASub")
+        assert_equal(three_mul_ufunc(1, a_sub, c), "ASub")
+
+        assert_equal(three_mul_ufunc(a, b, c), "A")
+        assert_equal(three_mul_ufunc(a, b, c_sub), "A")
+        assert_equal(three_mul_ufunc(1, 2, b), "B")
+
+        assert_raises(TypeError, three_mul_ufunc, 1, 2, c)
+        assert_raises(TypeError, three_mul_ufunc, c_sub, 2, c)
+        assert_raises(TypeError, three_mul_ufunc, c_sub, 2, 3)
+
+        # Quaternary testing.
+        assert_equal(four_mul_ufunc(a, 1, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, a, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, 1, a, 3), "A")
+        assert_equal(four_mul_ufunc(1, 1, 2, a), "A")
+
+        assert_equal(four_mul_ufunc(a, b, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, a, 2, b), "A")
+        assert_equal(four_mul_ufunc(b, 1, a, 3), "B")
+        assert_equal(four_mul_ufunc(a_sub, 1, 2, a), "ASub")
+        assert_equal(four_mul_ufunc(a, 1, 2, a_sub), "ASub")
+
+        assert_raises(TypeError, four_mul_ufunc, 1, 2, 3, c)
+        assert_raises(TypeError, four_mul_ufunc, 1, 2, c_sub, c)
+        assert_raises(TypeError, four_mul_ufunc, 1, c, c_sub, c)
+
+    def test_ufunc_override_methods(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return self, ufunc, method, pos, inputs, kwargs
+
+        # __call__
+        a = A()
+        res = np.multiply.__call__(1, a, foo='bar', answer=42)
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], '__call__')
+        assert_equal(res[3], 1)
+        assert_equal(res[4], (1, a))
+        assert_equal(res[5], {'foo': 'bar', 'answer': 42})
+
+        # reduce, positional args
+        res = np.multiply.reduce(a, 'axis0', 'dtype0', 'out0', 'keep0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduce')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'keepdims': 'keep0',
+                               'axis': 'axis0'})
+
+        # reduce, kwargs
+        res = np.multiply.reduce(a, axis='axis0', dtype='dtype0', out='out0',
+                                 keepdims='keep0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduce')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'keepdims': 'keep0',
+                               'axis': 'axis0'})
+
+        # accumulate, pos args
+        res = np.multiply.accumulate(a, 'axis0', 'dtype0', 'out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'accumulate')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # accumulate, kwargs
+        res = np.multiply.accumulate(a, axis='axis0', dtype='dtype0',
+                                     out='out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'accumulate')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # reduceat, pos args
+        res = np.multiply.reduceat(a, [4, 2], 'axis0', 'dtype0', 'out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduceat')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2]))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # reduceat, kwargs
+        res = np.multiply.reduceat(a, [4, 2], axis='axis0', dtype='dtype0',
+                                   out='out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduceat')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2]))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # outer
+        res = np.multiply.outer(a, 42)
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'outer')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, 42))
+        assert_equal(res[5], {})
+
+        # at
+        res = np.multiply.at(a, [4, 2], 'b0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'at')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2], 'b0'))
+
+    def test_ufunc_override_out(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return kwargs
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return kwargs
+
+        a = A()
+        b = B()
+        res0 = np.multiply(a, b, 'out_arg')
+        res1 = np.multiply(a, b, out='out_arg')
+        res2 = np.multiply(2, b, 'out_arg')
+        res3 = np.multiply(3, b, out='out_arg')
+        res4 = np.multiply(a, 4, 'out_arg')
+        res5 = np.multiply(a, 5, out='out_arg')
+
+        assert_equal(res0['out'], 'out_arg')
+        assert_equal(res1['out'], 'out_arg')
+        assert_equal(res2['out'], 'out_arg')
+        assert_equal(res3['out'], 'out_arg')
+        assert_equal(res4['out'], 'out_arg')
+        assert_equal(res5['out'], 'out_arg')
+
+        # ufuncs with multiple output modf and frexp.
+        res6 = np.modf(a, 'out0', 'out1')
+        res7 = np.frexp(a, 'out0', 'out1')
+        assert_equal(res6['out'][0], 'out0')
+        assert_equal(res6['out'][1], 'out1')
+        assert_equal(res7['out'][0], 'out0')
+        assert_equal(res7['out'][1], 'out1')
+
+    def test_ufunc_override_exception(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, *a, **kwargs):
+                raise ValueError("oops")
+
+        a = A()
+        for func in [np.divide, np.dot]:
+            assert_raises(ValueError, func, a, a)
+
+class TestChoose(TestCase):
+    def test_mixed(self):
+        c = np.array([True, True])
+        a = np.array([True, True])
+        assert_equal(np.choose(c, (a, 1)), np.array([1, 1]))
+
+
+def is_longdouble_finfo_bogus():
+    info = np.finfo(np.longcomplex)
+    return not np.isfinite(np.log10(info.tiny/info.eps))
+
+
+class TestComplexFunctions(object):
+    funcs = [np.arcsin,  np.arccos,  np.arctan, np.arcsinh, np.arccosh,
+             np.arctanh, np.sin,     np.cos,    np.tan,     np.exp,
+             np.exp2,    np.log,     np.sqrt,   np.log10,   np.log2,
+             np.log1p]
+
+    def test_it(self):
+        for f in self.funcs:
+            if f is np.arccosh:
+                x = 1.5
+            else:
+                x = .5
+            fr = f(x)
+            fz = f(np.complex(x))
+            assert_almost_equal(fz.real, fr, err_msg='real part %s' % f)
+            assert_almost_equal(fz.imag, 0., err_msg='imag part %s' % f)
+
+    def test_precisions_consistent(self):
+        z = 1 + 1j
+        for f in self.funcs:
+            fcf = f(np.csingle(z))
+            fcd = f(np.cdouble(z))
+            fcl = f(np.clongdouble(z))
+            assert_almost_equal(fcf, fcd, decimal=6, err_msg='fch-fcd %s' % f)
+            assert_almost_equal(fcl, fcd, decimal=15, err_msg='fch-fcl %s' % f)
+
+    def test_branch_cuts(self):
+        # check branch cuts and continuity on them
+        yield _check_branch_cut, np.log,   -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log2,  -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.sqrt,  -0.5, 1j, 1, -1, True
+
+        yield _check_branch_cut, np.arcsin, [ -2, 2],   [1j, 1j], 1, -1, True
+        yield _check_branch_cut, np.arccos, [ -2, 2],   [1j, 1j], 1, -1, True
+        yield _check_branch_cut, np.arctan, [0-2j, 2j],  [1,  1], -1, 1, True
+
+        yield _check_branch_cut, np.arcsinh, [0-2j,  2j], [1,   1], -1, 1, True
+        yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j,  1j], 1, -1, True
+        yield _check_branch_cut, np.arctanh, [ -2,   2], [1j, 1j], 1, -1, True
+
+        # check against bogus branch cuts: assert continuity between quadrants
+        yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1,  1], 1, 1
+        yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1,  1], 1, 1
+        yield _check_branch_cut, np.arctan, [ -2,  2], [1j, 1j], 1, 1
+
+        yield _check_branch_cut, np.arcsinh, [ -2,  2, 0], [1j, 1j, 1], 1, 1
+        yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1,  1,  1j], 1, 1
+        yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1,  1,  1j], 1, 1
+
+    def test_branch_cuts_complex64(self):
+        # check branch cuts and continuity on them
+        yield _check_branch_cut, np.log,   -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log2,  -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.sqrt,  -0.5, 1j, 1, -1, True, np.complex64
+
+        yield _check_branch_cut, np.arcsin, [ -2, 2],   [1j, 1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arccos, [ -2, 2],   [1j, 1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arctan, [0-2j, 2j],  [1,  1], -1, 1, True, np.complex64
+
+        yield _check_branch_cut, np.arcsinh, [0-2j,  2j], [1,   1], -1, 1, True, np.complex64
+        yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j,  1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arctanh, [ -2,   2], [1j, 1j], 1, -1, True, np.complex64
+
+        # check against bogus branch cuts: assert continuity between quadrants
+        yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1,  1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1,  1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arctan, [ -2,  2], [1j, 1j], 1, 1, False, np.complex64
+
+        yield _check_branch_cut, np.arcsinh, [ -2,  2, 0], [1j, 1j, 1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1,  1,  1j], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1,  1,  1j], 1, 1, False, np.complex64
+
+    def test_against_cmath(self):
+        import cmath
+
+        points = [-1-1j, -1+1j, +1-1j, +1+1j]
+        name_map = {'arcsin': 'asin', 'arccos': 'acos', 'arctan': 'atan',
+                    'arcsinh': 'asinh', 'arccosh': 'acosh', 'arctanh': 'atanh'}
+        atol = 4*np.finfo(np.complex).eps
+        for func in self.funcs:
+            fname = func.__name__.split('.')[-1]
+            cname = name_map.get(fname, fname)
+            try:
+                cfunc = getattr(cmath, cname)
+            except AttributeError:
+                continue
+            for p in points:
+                a = complex(func(np.complex_(p)))
+                b = cfunc(p)
+                assert_(abs(a - b) < atol, "%s %s: %s; cmath: %s" % (fname, p, a, b))
+
+    def check_loss_of_precision(self, dtype):
+        """Check loss of precision in complex arc* functions"""
+
+        # Check against known-good functions
+
+        info = np.finfo(dtype)
+        real_dtype = dtype(0.).real.dtype
+        eps = info.eps
+
+        def check(x, rtol):
+            x = x.astype(real_dtype)
+
+            z = x.astype(dtype)
+            d = np.absolute(np.arcsinh(x)/np.arcsinh(z).real - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arcsinh'))
+
+            z = (1j*x).astype(dtype)
+            d = np.absolute(np.arcsinh(x)/np.arcsin(z).imag - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arcsin'))
+
+            z = x.astype(dtype)
+            d = np.absolute(np.arctanh(x)/np.arctanh(z).real - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arctanh'))
+
+            z = (1j*x).astype(dtype)
+            d = np.absolute(np.arctanh(x)/np.arctan(z).imag - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arctan'))
+
+        # The switchover was chosen as 1e-3; hence there can be up to
+        # ~eps/1e-3 of relative cancellation error before it
+
+        x_series = np.logspace(-20, -3.001, 200)
+        x_basic = np.logspace(-2.999, 0, 10, endpoint=False)
+
+        if dtype is np.longcomplex:
+            # It's not guaranteed that the system-provided arc functions
+            # are accurate down to a few epsilons. (Eg. on Linux 64-bit)
+            # So, give more leeway for long complex tests here:
+            check(x_series, 50*eps)
+        else:
+            check(x_series, 2.1*eps)
+        check(x_basic, 2*eps/1e-3)
+
+        # Check a few points
+
+        z = np.array([1e-5*(1+1j)], dtype=dtype)
+        p = 9.999999999333333333e-6 + 1.000000000066666666e-5j
+        d = np.absolute(1-np.arctanh(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 1.0000000000333333333e-5 + 9.999999999666666667e-6j
+        d = np.absolute(1-np.arcsinh(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 9.999999999333333333e-6j + 1.000000000066666666e-5
+        d = np.absolute(1-np.arctan(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 1.0000000000333333333e-5j + 9.999999999666666667e-6
+        d = np.absolute(1-np.arcsin(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        # Check continuity across switchover points
+
+        def check(func, z0, d=1):
+            z0 = np.asarray(z0, dtype=dtype)
+            zp = z0 + abs(z0) * d * eps * 2
+            zm = z0 - abs(z0) * d * eps * 2
+            assert_(np.all(zp != zm), (zp, zm))
+
+            # NB: the cancellation error at the switchover is at least eps
+            good = (abs(func(zp) - func(zm)) < 2*eps)
+            assert_(np.all(good), (func, z0[~good]))
+
+        for func in (np.arcsinh, np.arcsinh, np.arcsin, np.arctanh, np.arctan):
+            pts = [rp+1j*ip for rp in (-1e-3, 0, 1e-3) for ip in(-1e-3, 0, 1e-3)
+                   if rp != 0 or ip != 0]
+            check(func, pts, 1)
+            check(func, pts, 1j)
+            check(func, pts, 1+1j)
+
+    def test_loss_of_precision(self):
+        for dtype in [np.complex64, np.complex_]:
+            yield self.check_loss_of_precision, dtype
+
+    @dec.knownfailureif(is_longdouble_finfo_bogus(), "Bogus long double finfo")
+    def test_loss_of_precision_longcomplex(self):
+        self.check_loss_of_precision(np.longcomplex)
+
+
+class TestAttributes(TestCase):
+    def test_attributes(self):
+        add = ncu.add
+        assert_equal(add.__name__, 'add')
+        assert_(add.__doc__.startswith('add(x1, x2[, out])\n\n'))
+        self.assertTrue(add.ntypes >= 18)  # don't fail if types added
+        self.assertTrue('ii->i' in add.types)
+        assert_equal(add.nin, 2)
+        assert_equal(add.nout, 1)
+        assert_equal(add.identity, 0)
+
+
+class TestSubclass(TestCase):
+
+    def test_subclass_op(self):
+
+        class simple(np.ndarray):
+            def __new__(subtype, shape):
+                self = np.ndarray.__new__(subtype, shape, dtype=object)
+                self.fill(0)
+                return self
+
+        a = simple((3, 4))
+        assert_equal(a+a, a)
+
+def _check_branch_cut(f, x0, dx, re_sign=1, im_sign=-1, sig_zero_ok=False,
+                      dtype=np.complex):
+    """
+    Check for a branch cut in a function.
+
+    Assert that `x0` lies on a branch cut of function `f` and `f` is
+    continuous from the direction `dx`.
+
+    Parameters
+    ----------
+    f : func
+        Function to check
+    x0 : array-like
+        Point on branch cut
+    dx : array-like
+        Direction to check continuity in
+    re_sign, im_sign : {1, -1}
+        Change of sign of the real or imaginary part expected
+    sig_zero_ok : bool
+        Whether to check if the branch cut respects signed zero (if applicable)
+    dtype : dtype
+        Dtype to check (should be complex)
+
+    """
+    x0 = np.atleast_1d(x0).astype(dtype)
+    dx = np.atleast_1d(dx).astype(dtype)
+
+    if np.dtype(dtype).char == 'F':
+        scale = np.finfo(dtype).eps * 1e2
+        atol = np.float32(1e-2)
+    else:
+        scale = np.finfo(dtype).eps * 1e3
+        atol = 1e-4
+
+    y0 = f(x0)
+    yp = f(x0 + dx*scale*np.absolute(x0)/np.absolute(dx))
+    ym = f(x0 - dx*scale*np.absolute(x0)/np.absolute(dx))
+
+    assert_(np.all(np.absolute(y0.real - yp.real) < atol), (y0, yp))
+    assert_(np.all(np.absolute(y0.imag - yp.imag) < atol), (y0, yp))
+    assert_(np.all(np.absolute(y0.real - ym.real*re_sign) < atol), (y0, ym))
+    assert_(np.all(np.absolute(y0.imag - ym.imag*im_sign) < atol), (y0, ym))
+
+    if sig_zero_ok:
+        # check that signed zeros also work as a displacement
+        jr = (x0.real == 0) & (dx.real != 0)
+        ji = (x0.imag == 0) & (dx.imag != 0)
+        if np.any(jr):
+            x = x0[jr]
+            x.real = np.NZERO
+            ym = f(x)
+            assert_(np.all(np.absolute(y0[jr].real - ym.real*re_sign) < atol), (y0[jr], ym))
+            assert_(np.all(np.absolute(y0[jr].imag - ym.imag*im_sign) < atol), (y0[jr], ym))
+
+        if np.any(ji):
+            x = x0[ji]
+            x.imag = np.NZERO
+            ym = f(x)
+            assert_(np.all(np.absolute(y0[ji].real - ym.real*re_sign) < atol), (y0[ji], ym))
+            assert_(np.all(np.absolute(y0[ji].imag - ym.imag*im_sign) < atol), (y0[ji], ym))
+
+def test_copysign():
+    assert_(np.copysign(1, -1) == -1)
+    with np.errstate(divide="ignore"):
+        assert_(1 / np.copysign(0, -1) < 0)
+        assert_(1 / np.copysign(0, 1) > 0)
+    assert_(np.signbit(np.copysign(np.nan, -1)))
+    assert_(not np.signbit(np.copysign(np.nan, 1)))
+
+def _test_nextafter(t):
+    one = t(1)
+    two = t(2)
+    zero = t(0)
+    eps = np.finfo(t).eps
+    assert_(np.nextafter(one, two) - one == eps)
+    assert_(np.nextafter(one, zero) - one < 0)
+    assert_(np.isnan(np.nextafter(np.nan, one)))
+    assert_(np.isnan(np.nextafter(one, np.nan)))
+    assert_(np.nextafter(one, one) == one)
+
+def test_nextafter():
+    return _test_nextafter(np.float64)
+
+def test_nextafterf():
+    return _test_nextafter(np.float32)
+
+@dec.knownfailureif(sys.platform == 'win32' or on_powerpc(),
+            "Long double support buggy on win32 and PPC, ticket 1664.")
+def test_nextafterl():
+    return _test_nextafter(np.longdouble)
+
+def _test_spacing(t):
+    one = t(1)
+    eps = np.finfo(t).eps
+    nan = t(np.nan)
+    inf = t(np.inf)
+    with np.errstate(invalid='ignore'):
+        assert_(np.spacing(one) == eps)
+        assert_(np.isnan(np.spacing(nan)))
+        assert_(np.isnan(np.spacing(inf)))
+        assert_(np.isnan(np.spacing(-inf)))
+        assert_(np.spacing(t(1e30)) != 0)
+
+def test_spacing():
+    return _test_spacing(np.float64)
+
+def test_spacingf():
+    return _test_spacing(np.float32)
+
+@dec.knownfailureif(sys.platform == 'win32' or on_powerpc(),
+            "Long double support buggy on win32 and PPC, ticket 1664.")
+def test_spacingl():
+    return _test_spacing(np.longdouble)
+
+def test_spacing_gfortran():
+    # Reference from this fortran file, built with gfortran 4.3.3 on linux
+    # 32bits:
+    #       PROGRAM test_spacing
+    #        INTEGER, PARAMETER :: SGL = SELECTED_REAL_KIND(p=6, r=37)
+    #        INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(p=13, r=200)
+    #
+    #        WRITE(*,*) spacing(0.00001_DBL)
+    #        WRITE(*,*) spacing(1.0_DBL)
+    #        WRITE(*,*) spacing(1000._DBL)
+    #        WRITE(*,*) spacing(10500._DBL)
+    #
+    #        WRITE(*,*) spacing(0.00001_SGL)
+    #        WRITE(*,*) spacing(1.0_SGL)
+    #        WRITE(*,*) spacing(1000._SGL)
+    #        WRITE(*,*) spacing(10500._SGL)
+    #       END PROGRAM
+    ref = {np.float64: [1.69406589450860068E-021,
+                        2.22044604925031308E-016,
+                        1.13686837721616030E-013,
+                        1.81898940354585648E-012],
+           np.float32: [9.09494702E-13,
+                        1.19209290E-07,
+                        6.10351563E-05,
+                        9.76562500E-04]}
+
+    for dt, dec_ in zip([np.float32, np.float64], (10, 20)):
+        x = np.array([1e-5, 1, 1000, 10500], dtype=dt)
+        assert_array_almost_equal(np.spacing(x), ref[dt], decimal=dec_)
+
+def test_nextafter_vs_spacing():
+    # XXX: spacing does not handle long double yet
+    for t in [np.float32, np.float64]:
+        for _f in [1, 1e-5, 1000]:
+            f = t(_f)
+            f1 = t(_f + 1)
+            assert_(np.nextafter(f, f1) - f == np.spacing(f))
+
+def test_pos_nan():
+    """Check np.nan is a positive nan."""
+    assert_(np.signbit(np.nan) == 0)
+
+def test_reduceat():
+    """Test bug in reduceat when structured arrays are not copied."""
+    db = np.dtype([('name', 'S11'), ('time', np.int64), ('value', np.float32)])
+    a = np.empty([100], dtype=db)
+    a['name'] = 'Simple'
+    a['time'] = 10
+    a['value'] = 100
+    indx = [0, 7, 15, 25]
+
+    h2 = []
+    val1 = indx[0]
+    for val2 in indx[1:]:
+        h2.append(np.add.reduce(a['value'][val1:val2]))
+        val1 = val2
+    h2.append(np.add.reduce(a['value'][val1:]))
+    h2 = np.array(h2)
+
+    # test buffered -- this should work
+    h1 = np.add.reduceat(a['value'], indx)
+    assert_array_almost_equal(h1, h2)
+
+    # This is when the error occurs.
+    # test no buffer
+    np.setbufsize(32)
+    h1 = np.add.reduceat(a['value'], indx)
+    np.setbufsize(np.UFUNC_BUFSIZE_DEFAULT)
+    assert_array_almost_equal(h1, h2)
+
+def test_reduceat_empty():
+    """Reduceat should work with empty arrays"""
+    indices = np.array([], 'i4')
+    x = np.array([], 'f8')
+    result = np.add.reduceat(x, indices)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (0,))
+    # Another case with a slightly different zero-sized shape
+    x = np.ones((5, 2))
+    result = np.add.reduceat(x, [], axis=0)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (0, 2))
+    result = np.add.reduceat(x, [], axis=1)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (5, 0))
+
+def test_complex_nan_comparisons():
+    nans = [complex(np.nan, 0), complex(0, np.nan), complex(np.nan, np.nan)]
+    fins = [complex(1, 0), complex(-1, 0), complex(0, 1), complex(0, -1),
+            complex(1, 1), complex(-1, -1), complex(0, 0)]
+
+    with np.errstate(invalid='ignore'):
+        for x in nans + fins:
+            x = np.array([x])
+            for y in nans + fins:
+                y = np.array([y])
+
+                if np.isfinite(x) and np.isfinite(y):
+                    continue
+
+                assert_equal(x < y, False, err_msg="%r < %r" % (x, y))
+                assert_equal(x > y, False, err_msg="%r > %r" % (x, y))
+                assert_equal(x <= y, False, err_msg="%r <= %r" % (x, y))
+                assert_equal(x >= y, False, err_msg="%r >= %r" % (x, y))
+                assert_equal(x == y, False, err_msg="%r == %r" % (x, y))
+
+
+def test_rint_big_int():
+    # np.rint bug for large integer values on Windows 32-bit and MKL
+    # https://github.com/numpy/numpy/issues/6685
+    val = 4607998452777363968
+    # This is exactly representable in floating point
+    assert_equal(val, int(float(val)))
+    # Rint should not change the value
+    assert_equal(val, np.rint(val))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
new file mode 100644
index 0000000000..536ad398a7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
@@ -0,0 +1,538 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import platform
+
+import numpy as np
+import numpy.core.umath as ncu
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_almost_equal, dec
+)
+
+# TODO: branch cuts (use Pauli code)
+# TODO: conj 'symmetry'
+# TODO: FPU exceptions
+
+# At least on Windows the results of many complex functions are not conforming
+# to the C99 standard. See ticket 1574.
+# Ditto for Solaris (ticket 1642) and OS X on PowerPC.
+with np.errstate(all='ignore'):
+    functions_seem_flaky = ((np.exp(complex(np.inf, 0)).imag != 0)
+                            or (np.log(complex(np.NZERO, 0)).imag != np.pi))
+# TODO: replace with a check on whether platform-provided C99 funcs are used
+skip_complex_tests = (not sys.platform.startswith('linux') or functions_seem_flaky)
+
+def platform_skip(func):
+    return dec.skipif(skip_complex_tests,
+        "Numpy is using complex functions (e.g. sqrt) provided by your"
+        "platform's C library. However, they do not seem to behave according"
+        "to C99 -- so C99 tests are skipped.")(func)
+
+
+class TestCexp(object):
+    def test_simple(self):
+        check = check_complex_value
+        f = np.exp
+
+        yield check, f, 1, 0, np.exp(1), 0, False
+        yield check, f, 0, 1, np.cos(1), np.sin(1), False
+
+        ref = np.exp(1) * np.complex(np.cos(1), np.sin(1))
+        yield check, f, 1, 1, ref.real, ref.imag, False
+
+    @platform_skip
+    def test_special_values(self):
+        # C99: Section G 6.3.1
+
+        check = check_complex_value
+        f = np.exp
+
+        # cexp(+-0 + 0i) is 1 + 0i
+        yield check, f, np.PZERO, 0, 1, 0, False
+        yield check, f, np.NZERO, 0, 1, 0, False
+
+        # cexp(x + infi) is nan + nani for finite x and raises 'invalid' FPU
+        # exception
+        yield check, f,  1, np.inf, np.nan, np.nan
+        yield check, f, -1, np.inf, np.nan, np.nan
+        yield check, f,  0, np.inf, np.nan, np.nan
+
+        # cexp(inf + 0i) is inf + 0i
+        yield check, f,  np.inf, 0, np.inf, 0
+
+        # cexp(-inf + yi) is +0 * (cos(y) + i sin(y)) for finite y
+        yield check, f,  -np.inf, 1, np.PZERO, np.PZERO
+        yield check, f,  -np.inf, 0.75 * np.pi, np.NZERO, np.PZERO
+
+        # cexp(inf + yi) is +inf * (cos(y) + i sin(y)) for finite y
+        yield check, f,  np.inf, 1, np.inf, np.inf
+        yield check, f,  np.inf, 0.75 * np.pi, -np.inf, np.inf
+
+        # cexp(-inf + inf i) is +-0 +- 0i (signs unspecified)
+        def _check_ninf_inf(dummy):
+            msgform = "cexp(-inf, inf) is (%f, %f), expected (+-0, +-0)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(-np.inf, np.inf)))
+                if z.real != 0 or z.imag != 0:
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_inf, None
+
+        # cexp(inf + inf i) is +-inf + NaNi and raised invalid FPU ex.
+        def _check_inf_inf(dummy):
+            msgform = "cexp(inf, inf) is (%f, %f), expected (+-inf, nan)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(np.inf, np.inf)))
+                if not np.isinf(z.real) or not np.isnan(z.imag):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_inf_inf, None
+
+        # cexp(-inf + nan i) is +-0 +- 0i
+        def _check_ninf_nan(dummy):
+            msgform = "cexp(-inf, nan) is (%f, %f), expected (+-0, +-0)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(-np.inf, np.nan)))
+                if z.real != 0 or z.imag != 0:
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_nan, None
+
+        # cexp(inf + nan i) is +-inf + nan
+        def _check_inf_nan(dummy):
+            msgform = "cexp(-inf, nan) is (%f, %f), expected (+-inf, nan)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(np.inf, np.nan)))
+                if not np.isinf(z.real) or not np.isnan(z.imag):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_inf_nan, None
+
+        # cexp(nan + yi) is nan + nani for y != 0 (optional: raises invalid FPU
+        # ex)
+        yield check, f, np.nan, 1, np.nan, np.nan
+        yield check, f, np.nan, -1, np.nan, np.nan
+
+        yield check, f, np.nan,  np.inf, np.nan, np.nan
+        yield check, f, np.nan, -np.inf, np.nan, np.nan
+
+        # cexp(nan + nani) is nan + nani
+        yield check, f, np.nan, np.nan, np.nan, np.nan
+
+    @dec.knownfailureif(True, "cexp(nan + 0I) is wrong on most implementations")
+    def test_special_values2(self):
+        # XXX: most implementations get it wrong here (including glibc <= 2.10)
+        # cexp(nan + 0i) is nan + 0i
+        check = check_complex_value
+        f = np.exp
+
+        yield check, f, np.nan, 0, np.nan, 0
+
+class TestClog(TestCase):
+    def test_simple(self):
+        x = np.array([1+0j, 1+2j])
+        y_r = np.log(np.abs(x)) + 1j * np.angle(x)
+        y = np.log(x)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    @platform_skip
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_special_values(self):
+        xl = []
+        yl = []
+
+        # From C99 std (Sec 6.3.2)
+        # XXX: check exceptions raised
+        # --- raise for invalid fails.
+
+        # clog(-0 + i0) returns -inf + i pi and raises the 'divide-by-zero'
+        # floating-point exception.
+        with np.errstate(divide='raise'):
+            x = np.array([np.NZERO], dtype=np.complex)
+            y = np.complex(-np.inf, np.pi)
+            self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(divide='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+0 + i0) returns -inf + i0 and raises the 'divide-by-zero'
+        # floating-point exception.
+        with np.errstate(divide='raise'):
+            x = np.array([0], dtype=np.complex)
+            y = np.complex(-np.inf, 0)
+            self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(divide='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(x + i inf returns +inf + i pi /2, for finite x.
+        x = np.array([complex(1, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.5 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        x = np.array([complex(-1, np.inf)], dtype=np.complex)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(x + iNaN) returns NaN + iNaN and optionally raises the
+        # 'invalid' floating- point exception, for finite x.
+        with np.errstate(invalid='raise'):
+            x = np.array([complex(1., np.nan)], dtype=np.complex)
+            y = np.complex(np.nan, np.nan)
+            #self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(invalid='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        with np.errstate(invalid='raise'):
+            x = np.array([np.inf + 1j * np.nan], dtype=np.complex)
+            #self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(invalid='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(- inf + iy) returns +inf + ipi , for finite positive-signed y.
+        x = np.array([-np.inf + 1j], dtype=np.complex)
+        y = np.complex(np.inf, np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+ inf + iy) returns +inf + i0, for finite positive-signed y.
+        x = np.array([np.inf + 1j], dtype=np.complex)
+        y = np.complex(np.inf, 0)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(- inf + i inf) returns +inf + i3pi /4.
+        x = np.array([complex(-np.inf, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.75 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+ inf + i inf) returns +inf + ipi /4.
+        x = np.array([complex(np.inf, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.25 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+/- inf + iNaN) returns +inf + iNaN.
+        x = np.array([complex(np.inf, np.nan)], dtype=np.complex)
+        y = np.complex(np.inf, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        x = np.array([complex(-np.inf, np.nan)], dtype=np.complex)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + iy) returns NaN + iNaN and optionally raises the
+        # 'invalid' floating-point exception, for finite y.
+        x = np.array([complex(np.nan, 1)], dtype=np.complex)
+        y = np.complex(np.nan, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + i inf) returns +inf + iNaN.
+        x = np.array([complex(np.nan, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + iNaN) returns NaN + iNaN.
+        x = np.array([complex(np.nan, np.nan)], dtype=np.complex)
+        y = np.complex(np.nan, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(conj(z)) = conj(clog(z)).
+        xa = np.array(xl, dtype=np.complex)
+        ya = np.array(yl, dtype=np.complex)
+        with np.errstate(divide='ignore'):
+            for i in range(len(xa)):
+                assert_almost_equal(np.log(xa[i].conj()), ya[i].conj())
+
+class TestCsqrt(object):
+
+    def test_simple(self):
+        # sqrt(1)
+        yield check_complex_value, np.sqrt, 1, 0, 1, 0
+
+        # sqrt(1i)
+        yield check_complex_value, np.sqrt, 0, 1, 0.5*np.sqrt(2), 0.5*np.sqrt(2), False
+
+        # sqrt(-1)
+        yield check_complex_value, np.sqrt, -1, 0, 0, 1
+
+    def test_simple_conjugate(self):
+        ref = np.conj(np.sqrt(np.complex(1, 1)))
+
+        def f(z):
+            return np.sqrt(np.conj(z))
+        yield check_complex_value, f, 1, 1, ref.real, ref.imag, False
+
+    #def test_branch_cut(self):
+    #    _check_branch_cut(f, -1, 0, 1, -1)
+
+    @platform_skip
+    def test_special_values(self):
+        # C99: Sec G 6.4.2
+
+        check = check_complex_value
+        f = np.sqrt
+
+        # csqrt(+-0 + 0i) is 0 + 0i
+        yield check, f, np.PZERO, 0, 0, 0
+        yield check, f, np.NZERO, 0, 0, 0
+
+        # csqrt(x + infi) is inf + infi for any x (including NaN)
+        yield check, f,  1, np.inf, np.inf, np.inf
+        yield check, f, -1, np.inf, np.inf, np.inf
+
+        yield check, f, np.PZERO, np.inf, np.inf, np.inf
+        yield check, f, np.NZERO, np.inf, np.inf, np.inf
+        yield check, f,   np.inf, np.inf, np.inf, np.inf
+        yield check, f,  -np.inf, np.inf, np.inf, np.inf
+        yield check, f,  -np.nan, np.inf, np.inf, np.inf
+
+        # csqrt(x + nani) is nan + nani for any finite x
+        yield check, f,  1, np.nan, np.nan, np.nan
+        yield check, f, -1, np.nan, np.nan, np.nan
+        yield check, f,  0, np.nan, np.nan, np.nan
+
+        # csqrt(-inf + yi) is +0 + infi for any finite y > 0
+        yield check, f, -np.inf, 1, np.PZERO, np.inf
+
+        # csqrt(inf + yi) is +inf + 0i for any finite y > 0
+        yield check, f, np.inf, 1, np.inf, np.PZERO
+
+        # csqrt(-inf + nani) is nan +- infi (both +i infi are valid)
+        def _check_ninf_nan(dummy):
+            msgform = "csqrt(-inf, nan) is (%f, %f), expected (nan, +-inf)"
+            z = np.sqrt(np.array(np.complex(-np.inf, np.nan)))
+            #Fixme: ugly workaround for isinf bug.
+            with np.errstate(invalid='ignore'):
+                if not (np.isnan(z.real) and np.isinf(z.imag)):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_nan, None
+
+        # csqrt(+inf + nani) is inf + nani
+        yield check, f, np.inf, np.nan, np.inf, np.nan
+
+        # csqrt(nan + yi) is nan + nani for any finite y (infinite handled in x
+        # + nani)
+        yield check, f, np.nan,       0, np.nan, np.nan
+        yield check, f, np.nan,       1, np.nan, np.nan
+        yield check, f, np.nan,  np.nan, np.nan, np.nan
+
+        # XXX: check for conj(csqrt(z)) == csqrt(conj(z)) (need to fix branch
+        # cuts first)
+
+class TestCpow(TestCase):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def test_simple(self):
+        x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan])
+        y_r = x ** 2
+        y = np.power(x, 2)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    def test_scalar(self):
+        x = np.array([1, 1j,         2,  2.5+.37j, np.inf, np.nan])
+        y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j,      2,      3])
+        lx = list(range(len(x)))
+        # Compute the values for complex type in python
+        p_r = [complex(x[i]) ** complex(y[i]) for i in lx]
+        # Substitute a result allowed by C99 standard
+        p_r[4] = complex(np.inf, np.nan)
+        # Do the same with numpy complex scalars
+        n_r = [x[i] ** y[i] for i in lx]
+        for i in lx:
+            assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i)
+
+    def test_array(self):
+        x = np.array([1, 1j,         2,  2.5+.37j, np.inf, np.nan])
+        y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j,      2,      3])
+        lx = list(range(len(x)))
+        # Compute the values for complex type in python
+        p_r = [complex(x[i]) ** complex(y[i]) for i in lx]
+        # Substitute a result allowed by C99 standard
+        p_r[4] = complex(np.inf, np.nan)
+        # Do the same with numpy arrays
+        n_r = x ** y
+        for i in lx:
+            assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i)
+
+class TestCabs(object):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def test_simple(self):
+        x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan])
+        y_r = np.array([np.sqrt(2.), 2, np.sqrt(5), np.inf, np.nan])
+        y = np.abs(x)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    def test_fabs(self):
+        # Test that np.abs(x +- 0j) == np.abs(x) (as mandated by C99 for cabs)
+        x = np.array([1+0j], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(1, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(np.inf, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(np.nan, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+    def test_cabs_inf_nan(self):
+        x, y = [], []
+
+        # cabs(+-nan + nani) returns nan
+        x.append(np.nan)
+        y.append(np.nan)
+        yield check_real_value, np.abs,  np.nan, np.nan, np.nan
+
+        x.append(np.nan)
+        y.append(-np.nan)
+        yield check_real_value, np.abs, -np.nan, np.nan, np.nan
+
+        # According to C99 standard, if exactly one of the real/part is inf and
+        # the other nan, then cabs should return inf
+        x.append(np.inf)
+        y.append(np.nan)
+        yield check_real_value, np.abs,  np.inf, np.nan, np.inf
+
+        x.append(-np.inf)
+        y.append(np.nan)
+        yield check_real_value, np.abs, -np.inf, np.nan, np.inf
+
+        # cabs(conj(z)) == conj(cabs(z)) (= cabs(z))
+        def f(a):
+            return np.abs(np.conj(a))
+
+        def g(a, b):
+            return np.abs(np.complex(a, b))
+
+        xa = np.array(x, dtype=np.complex)
+        for i in range(len(xa)):
+            ref = g(x[i], y[i])
+            yield check_real_value, f, x[i], y[i], ref
+
+class TestCarg(object):
+    def test_simple(self):
+        check_real_value(ncu._arg, 1, 0, 0, False)
+        check_real_value(ncu._arg, 0, 1, 0.5*np.pi, False)
+
+        check_real_value(ncu._arg, 1, 1, 0.25*np.pi, False)
+        check_real_value(ncu._arg, np.PZERO, np.PZERO, np.PZERO)
+
+    @dec.knownfailureif(True,
+        "Complex arithmetic with signed zero is buggy on most implementation")
+    def test_zero(self):
+        # carg(-0 +- 0i) returns +- pi
+        yield check_real_value, ncu._arg, np.NZERO, np.PZERO,  np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, np.NZERO, -np.pi, False
+
+        # carg(+0 +- 0i) returns +- 0
+        yield check_real_value, ncu._arg, np.PZERO, np.PZERO, np.PZERO
+        yield check_real_value, ncu._arg, np.PZERO, np.NZERO, np.NZERO
+
+        # carg(x +- 0i) returns +- 0 for x > 0
+        yield check_real_value, ncu._arg, 1, np.PZERO, np.PZERO, False
+        yield check_real_value, ncu._arg, 1, np.NZERO, np.NZERO, False
+
+        # carg(x +- 0i) returns +- pi for x < 0
+        yield check_real_value, ncu._arg, -1, np.PZERO,  np.pi, False
+        yield check_real_value, ncu._arg, -1, np.NZERO, -np.pi, False
+
+        # carg(+- 0 + yi) returns pi/2 for y > 0
+        yield check_real_value, ncu._arg, np.PZERO, 1, 0.5 * np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, 1, 0.5 * np.pi, False
+
+        # carg(+- 0 + yi) returns -pi/2 for y < 0
+        yield check_real_value, ncu._arg, np.PZERO, -1, 0.5 * np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, -1, -0.5 * np.pi, False
+
+    #def test_branch_cuts(self):
+    #    _check_branch_cut(ncu._arg, -1, 1j, -1, 1)
+
+    def test_special_values(self):
+        # carg(-np.inf +- yi) returns +-pi for finite y > 0
+        yield check_real_value, ncu._arg, -np.inf,  1,  np.pi, False
+        yield check_real_value, ncu._arg, -np.inf, -1, -np.pi, False
+
+        # carg(np.inf +- yi) returns +-0 for finite y > 0
+        yield check_real_value, ncu._arg, np.inf,  1, np.PZERO, False
+        yield check_real_value, ncu._arg, np.inf, -1, np.NZERO, False
+
+        # carg(x +- np.infi) returns +-pi/2 for finite x
+        yield check_real_value, ncu._arg, 1,  np.inf,  0.5 * np.pi, False
+        yield check_real_value, ncu._arg, 1, -np.inf, -0.5 * np.pi, False
+
+        # carg(-np.inf +- np.infi) returns +-3pi/4
+        yield check_real_value, ncu._arg, -np.inf,  np.inf,  0.75 * np.pi, False
+        yield check_real_value, ncu._arg, -np.inf, -np.inf, -0.75 * np.pi, False
+
+        # carg(np.inf +- np.infi) returns +-pi/4
+        yield check_real_value, ncu._arg, np.inf,  np.inf,  0.25 * np.pi, False
+        yield check_real_value, ncu._arg, np.inf, -np.inf, -0.25 * np.pi, False
+
+        # carg(x + yi) returns np.nan if x or y is nan
+        yield check_real_value, ncu._arg, np.nan,      0, np.nan, False
+        yield check_real_value, ncu._arg,      0, np.nan, np.nan, False
+
+        yield check_real_value, ncu._arg, np.nan, np.inf, np.nan, False
+        yield check_real_value, ncu._arg, np.inf, np.nan, np.nan, False
+
+def check_real_value(f, x1, y1, x, exact=True):
+    z1 = np.array([complex(x1, y1)])
+    if exact:
+        assert_equal(f(z1), x)
+    else:
+        assert_almost_equal(f(z1), x)
+
+def check_complex_value(f, x1, y1, x2, y2, exact=True):
+    z1 = np.array([complex(x1, y1)])
+    z2 = np.complex(x2, y2)
+    with np.errstate(invalid='ignore'):
+        if exact:
+            assert_equal(f(z1), z2)
+        else:
+            assert_almost_equal(f(z1), z2)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
new file mode 100644
index 0000000000..7a421a5fbc
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
@@ -0,0 +1,360 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import asbytes, unicode, sixu
+from numpy.testing import TestCase, run_module_suite, assert_equal
+
+# Guess the UCS length for this python interpreter
+if sys.version_info[:2] >= (3, 3):
+    # Python 3.3 uses a flexible string representation
+    ucs4 = False
+
+    def buffer_length(arr):
+        if isinstance(arr, unicode):
+            arr = str(arr)
+            return (sys.getsizeof(arr+"a") - sys.getsizeof(arr)) * len(arr)
+        v = memoryview(arr)
+        if v.shape is None:
+            return len(v) * v.itemsize
+        else:
+            return np.prod(v.shape) * v.itemsize
+elif sys.version_info[0] >= 3:
+    import array as _array
+
+    ucs4 = (_array.array('u').itemsize == 4)
+
+    def buffer_length(arr):
+        if isinstance(arr, unicode):
+            return _array.array('u').itemsize * len(arr)
+        v = memoryview(arr)
+        if v.shape is None:
+            return len(v) * v.itemsize
+        else:
+            return np.prod(v.shape) * v.itemsize
+else:
+    if len(buffer(sixu('u'))) == 4:
+        ucs4 = True
+    else:
+        ucs4 = False
+
+    def buffer_length(arr):
+        if isinstance(arr, np.ndarray):
+            return len(arr.data)
+        return len(buffer(arr))
+
+# In both cases below we need to make sure that the byte swapped value (as
+# UCS4) is still a valid unicode:
+# Value that can be represented in UCS2 interpreters
+ucs2_value = sixu('\u0900')
+# Value that cannot be represented in UCS2 interpreters (but can in UCS4)
+ucs4_value = sixu('\U00100900')
+
+
+############################################################
+#    Creation tests
+############################################################
+
+class create_zeros(object):
+    """Check the creation of zero-valued arrays"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == sixu(''))
+        # Encode to ascii and double check
+        self.assertTrue(ua_scalar.encode('ascii') == asbytes(''))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 0)
+        else:
+            self.assertTrue(buffer_length(ua_scalar) == 0)
+
+    def test_zeros0D(self):
+        # Check creation of 0-dimensional objects
+        ua = np.zeros((), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_zerosSD(self):
+        # Check creation of single-dimensional objects
+        ua = np.zeros((2,), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_zerosMD(self):
+        # Check creation of multi-dimensional objects
+        ua = np.zeros((2, 3, 4), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_create_zeros_1(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 1)"""
+    ulen = 1
+
+
+class test_create_zeros_2(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 2)"""
+    ulen = 2
+
+
+class test_create_zeros_1009(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 1009)"""
+    ulen = 1009
+
+
+class create_values(object):
+    """Check the creation of unicode arrays with values"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == self.ucs_value*self.ulen)
+        # Encode to UTF-8 and double check
+        self.assertTrue(ua_scalar.encode('utf-8') ==
+                        (self.ucs_value*self.ulen).encode('utf-8'))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 4*self.ulen)
+        else:
+            if self.ucs_value == ucs4_value:
+                # In UCS2, the \U0010FFFF will be represented using a
+                # surrogate *pair*
+                self.assertTrue(buffer_length(ua_scalar) == 2*2*self.ulen)
+            else:
+                # In UCS2, the \uFFFF will be represented using a
+                # regular 2-byte word
+                self.assertTrue(buffer_length(ua_scalar) == 2*self.ulen)
+
+    def test_values0D(self):
+        # Check creation of 0-dimensional objects with values
+        ua = np.array(self.ucs_value*self.ulen, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_valuesSD(self):
+        # Check creation of single-dimensional objects with values
+        ua = np.array([self.ucs_value*self.ulen]*2, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_valuesMD(self):
+        # Check creation of multi-dimensional objects with values
+        ua = np.array([[[self.ucs_value*self.ulen]*2]*3]*4, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_create_values_1_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_create_values_1_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_create_values_2_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_create_values_2_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_create_values_1009_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_create_values_1009_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+############################################################
+#    Assignment tests
+############################################################
+
+class assign_values(object):
+    """Check the assignment of unicode arrays with values"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == self.ucs_value*self.ulen)
+        # Encode to UTF-8 and double check
+        self.assertTrue(ua_scalar.encode('utf-8') ==
+                        (self.ucs_value*self.ulen).encode('utf-8'))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 4*self.ulen)
+        else:
+            if self.ucs_value == ucs4_value:
+                # In UCS2, the \U0010FFFF will be represented using a
+                # surrogate *pair*
+                self.assertTrue(buffer_length(ua_scalar) == 2*2*self.ulen)
+            else:
+                # In UCS2, the \uFFFF will be represented using a
+                # regular 2-byte word
+                self.assertTrue(buffer_length(ua_scalar) == 2*self.ulen)
+
+    def test_values0D(self):
+        # Check assignment of 0-dimensional objects with values
+        ua = np.zeros((), dtype='U%s' % self.ulen)
+        ua[()] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_valuesSD(self):
+        # Check assignment of single-dimensional objects with values
+        ua = np.zeros((2,), dtype='U%s' % self.ulen)
+        ua[0] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        ua[1] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_valuesMD(self):
+        # Check assignment of multi-dimensional objects with values
+        ua = np.zeros((2, 3, 4), dtype='U%s' % self.ulen)
+        ua[0, 0, 0] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        ua[-1, -1, -1] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_assign_values_1_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_assign_values_1_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_assign_values_2_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_assign_values_2_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_assign_values_1009_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_assign_values_1009_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+############################################################
+#    Byteorder tests
+############################################################
+
+class byteorder_values:
+    """Check the byteorder of unicode arrays in round-trip conversions"""
+
+    def test_values0D(self):
+        # Check byteorder of 0-dimensional objects
+        ua = np.array(self.ucs_value*self.ulen, dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        # This changes the interpretation of the data region (but not the
+        #  actual data), therefore the returned scalars are not
+        #  the same (they are byte-swapped versions of each other).
+        self.assertTrue(ua[()] != ua2[()])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+    def test_valuesSD(self):
+        # Check byteorder of single-dimensional objects
+        ua = np.array([self.ucs_value*self.ulen]*2, dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        self.assertTrue(ua[0] != ua2[0])
+        self.assertTrue(ua[-1] != ua2[-1])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+    def test_valuesMD(self):
+        # Check byteorder of multi-dimensional objects
+        ua = np.array([[[self.ucs_value*self.ulen]*2]*3]*4,
+                   dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        self.assertTrue(ua[0, 0, 0] != ua2[0, 0, 0])
+        self.assertTrue(ua[-1, -1, -1] != ua2[-1, -1, -1])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+
+class test_byteorder_1_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_byteorder_1_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_byteorder_2_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_byteorder_2_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_byteorder_1009_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_byteorder_1009_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..87147d9946377e753080e69e0e09e70949758b2c
GIT binary patch
literal 611328
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
J6pYvq000S|JTw3R

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath_tests.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..575fcbabf7362e27305e56fa44e3112dc9a4be9f
GIT binary patch
literal 24064
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
X$bi&tfbdxiI1G3U1VADTLlFP~@_HoV

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ctypeslib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ctypeslib.py
new file mode 100644
index 0000000000..fa1dcad6f1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ctypeslib.py
@@ -0,0 +1,453 @@
+"""
+============================
+``ctypes`` Utility Functions
+============================
+
+See Also
+---------
+load_library : Load a C library.
+ndpointer : Array restype/argtype with verification.
+as_ctypes : Create a ctypes array from an ndarray.
+as_array : Create an ndarray from a ctypes array.
+
+References
+----------
+.. [1] "SciPy Cookbook: ctypes", http://www.scipy.org/Cookbook/Ctypes
+
+Examples
+--------
+Load the C library:
+
+>>> _lib = np.ctypeslib.load_library('libmystuff', '.')     #doctest: +SKIP
+
+Our result type, an ndarray that must be of type double, be 1-dimensional
+and is C-contiguous in memory:
+
+>>> array_1d_double = np.ctypeslib.ndpointer(
+...                          dtype=np.double,
+...                          ndim=1, flags='CONTIGUOUS')    #doctest: +SKIP
+
+Our C-function typically takes an array and updates its values
+in-place.  For example::
+
+    void foo_func(double* x, int length)
+    {
+        int i;
+        for (i = 0; i < length; i++) {
+            x[i] = i*i;
+        }
+    }
+
+We wrap it using:
+
+>>> _lib.foo_func.restype = None                      #doctest: +SKIP
+>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP
+
+Then, we're ready to call ``foo_func``:
+
+>>> out = np.empty(15, dtype=np.double)
+>>> _lib.foo_func(out, len(out))                #doctest: +SKIP
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['load_library', 'ndpointer', 'test', 'ctypes_load_library',
+           'c_intp', 'as_ctypes', 'as_array']
+
+import sys, os
+from numpy import integer, ndarray, dtype as _dtype, deprecate, array
+from numpy.core.multiarray import _flagdict, flagsobj
+
+try:
+    import ctypes
+except ImportError:
+    ctypes = None
+
+if ctypes is None:
+    def _dummy(*args, **kwds):
+        """
+        Dummy object that raises an ImportError if ctypes is not available.
+
+        Raises
+        ------
+        ImportError
+            If ctypes is not available.
+
+        """
+        raise ImportError("ctypes is not available.")
+    ctypes_load_library = _dummy
+    load_library = _dummy
+    as_ctypes = _dummy
+    as_array = _dummy
+    from numpy import intp as c_intp
+    _ndptr_base = object
+else:
+    import numpy.core._internal as nic
+    c_intp = nic._getintp_ctype()
+    del nic
+    _ndptr_base = ctypes.c_void_p
+
+    # Adapted from Albert Strasheim
+    def load_library(libname, loader_path):
+        """
+        It is possible to load a library using 
+        >>> lib = ctypes.cdll[<full_path_name>]
+
+        But there are cross-platform considerations, such as library file extensions,
+        plus the fact Windows will just load the first library it finds with that name.  
+        Numpy supplies the load_library function as a convenience.
+
+        Parameters
+        ----------
+        libname : str
+            Name of the library, which can have 'lib' as a prefix,
+            but without an extension.
+        loader_path : str
+            Where the library can be found.
+
+        Returns
+        -------
+        ctypes.cdll[libpath] : library object
+           A ctypes library object 
+
+        Raises
+        ------
+        OSError
+            If there is no library with the expected extension, or the 
+            library is defective and cannot be loaded.
+        """
+        if ctypes.__version__ < '1.0.1':
+            import warnings
+            warnings.warn("All features of ctypes interface may not work " \
+                          "with ctypes < 1.0.1")
+
+        ext = os.path.splitext(libname)[1]
+        if not ext:
+            # Try to load library with platform-specific name, otherwise
+            # default to libname.[so|pyd].  Sometimes, these files are built
+            # erroneously on non-linux platforms.
+            from numpy.distutils.misc_util import get_shared_lib_extension
+            so_ext = get_shared_lib_extension()
+            libname_ext = [libname + so_ext]
+            # mac, windows and linux >= py3.2 shared library and loadable
+            # module have different extensions so try both
+            so_ext2 = get_shared_lib_extension(is_python_ext=True)
+            if not so_ext2 == so_ext:
+                libname_ext.insert(0, libname + so_ext2)
+        else:
+            libname_ext = [libname]
+
+        loader_path = os.path.abspath(loader_path)
+        if not os.path.isdir(loader_path):
+            libdir = os.path.dirname(loader_path)
+        else:
+            libdir = loader_path
+
+        for ln in libname_ext:
+            libpath = os.path.join(libdir, ln)
+            if os.path.exists(libpath):
+                try:
+                    return ctypes.cdll[libpath]
+                except OSError:
+                    ## defective lib file
+                    raise
+        ## if no successful return in the libname_ext loop:
+        raise OSError("no file with expected extension")
+
+    ctypes_load_library = deprecate(load_library, 'ctypes_load_library',
+                                    'load_library')
+
+def _num_fromflags(flaglist):
+    num = 0
+    for val in flaglist:
+        num += _flagdict[val]
+    return num
+
+_flagnames = ['C_CONTIGUOUS', 'F_CONTIGUOUS', 'ALIGNED', 'WRITEABLE',
+              'OWNDATA', 'UPDATEIFCOPY']
+def _flags_fromnum(num):
+    res = []
+    for key in _flagnames:
+        value = _flagdict[key]
+        if (num & value):
+            res.append(key)
+    return res
+
+
+class _ndptr(_ndptr_base):
+
+    def _check_retval_(self):
+        """This method is called when this class is used as the .restype
+        asttribute for a shared-library function.   It constructs a numpy
+        array from a void pointer."""
+        return array(self)
+
+    @property
+    def __array_interface__(self):
+        return {'descr': self._dtype_.descr,
+                '__ref': self,
+                'strides': None,
+                'shape': self._shape_,
+                'version': 3,
+                'typestr': self._dtype_.descr[0][1],
+                'data': (self.value, False),
+                }
+
+    @classmethod
+    def from_param(cls, obj):
+        if not isinstance(obj, ndarray):
+            raise TypeError("argument must be an ndarray")
+        if cls._dtype_ is not None \
+               and obj.dtype != cls._dtype_:
+            raise TypeError("array must have data type %s" % cls._dtype_)
+        if cls._ndim_ is not None \
+               and obj.ndim != cls._ndim_:
+            raise TypeError("array must have %d dimension(s)" % cls._ndim_)
+        if cls._shape_ is not None \
+               and obj.shape != cls._shape_:
+            raise TypeError("array must have shape %s" % str(cls._shape_))
+        if cls._flags_ is not None \
+               and ((obj.flags.num & cls._flags_) != cls._flags_):
+            raise TypeError("array must have flags %s" %
+                    _flags_fromnum(cls._flags_))
+        return obj.ctypes
+
+
+# Factory for an array-checking class with from_param defined for
+#  use with ctypes argtypes mechanism
+_pointer_type_cache = {}
+def ndpointer(dtype=None, ndim=None, shape=None, flags=None):
+    """
+    Array-checking restype/argtypes.
+
+    An ndpointer instance is used to describe an ndarray in restypes
+    and argtypes specifications.  This approach is more flexible than
+    using, for example, ``POINTER(c_double)``, since several restrictions
+    can be specified, which are verified upon calling the ctypes function.
+    These include data type, number of dimensions, shape and flags.  If a
+    given array does not satisfy the specified restrictions,
+    a ``TypeError`` is raised.
+
+    Parameters
+    ----------
+    dtype : data-type, optional
+        Array data-type.
+    ndim : int, optional
+        Number of array dimensions.
+    shape : tuple of ints, optional
+        Array shape.
+    flags : str or tuple of str
+        Array flags; may be one or more of:
+
+          - C_CONTIGUOUS / C / CONTIGUOUS
+          - F_CONTIGUOUS / F / FORTRAN
+          - OWNDATA / O
+          - WRITEABLE / W
+          - ALIGNED / A
+          - UPDATEIFCOPY / U
+
+    Returns
+    -------
+    klass : ndpointer type object
+        A type object, which is an ``_ndtpr`` instance containing
+        dtype, ndim, shape and flags information.
+
+    Raises
+    ------
+    TypeError
+        If a given array does not satisfy the specified restrictions.
+
+    Examples
+    --------
+    >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,
+    ...                                                  ndim=1,
+    ...                                                  flags='C_CONTIGUOUS')]
+    ... #doctest: +SKIP
+    >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64))
+    ... #doctest: +SKIP
+
+    """
+
+    if dtype is not None:
+        dtype = _dtype(dtype)
+    num = None
+    if flags is not None:
+        if isinstance(flags, str):
+            flags = flags.split(',')
+        elif isinstance(flags, (int, integer)):
+            num = flags
+            flags = _flags_fromnum(num)
+        elif isinstance(flags, flagsobj):
+            num = flags.num
+            flags = _flags_fromnum(num)
+        if num is None:
+            try:
+                flags = [x.strip().upper() for x in flags]
+            except:
+                raise TypeError("invalid flags specification")
+            num = _num_fromflags(flags)
+    try:
+        return _pointer_type_cache[(dtype, ndim, shape, num)]
+    except KeyError:
+        pass
+    if dtype is None:
+        name = 'any'
+    elif dtype.names:
+        name = str(id(dtype))
+    else:
+        name = dtype.str
+    if ndim is not None:
+        name += "_%dd" % ndim
+    if shape is not None:
+        try:
+            strshape = [str(x) for x in shape]
+        except TypeError:
+            strshape = [str(shape)]
+            shape = (shape,)
+        shape = tuple(shape)
+        name += "_"+"x".join(strshape)
+    if flags is not None:
+        name += "_"+"_".join(flags)
+    else:
+        flags = []
+    klass = type("ndpointer_%s"%name, (_ndptr,),
+                 {"_dtype_": dtype,
+                  "_shape_" : shape,
+                  "_ndim_" : ndim,
+                  "_flags_" : num})
+    _pointer_type_cache[dtype] = klass
+    return klass
+
+if ctypes is not None:
+    ct = ctypes
+    ################################################################
+    # simple types
+
+    # maps the numpy typecodes like '<f8' to simple ctypes types like
+    # c_double. Filled in by prep_simple.
+    _typecodes = {}
+
+    def prep_simple(simple_type, dtype):
+        """Given a ctypes simple type, construct and attach an
+        __array_interface__ property to it if it does not yet have one.
+        """
+        try: simple_type.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        typestr = _dtype(dtype).str
+        _typecodes[typestr] = simple_type
+
+        def __array_interface__(self):
+            return {'descr': [('', typestr)],
+                    '__ref': self,
+                    'strides': None,
+                    'shape': (),
+                    'version': 3,
+                    'typestr': typestr,
+                    'data': (ct.addressof(self), False),
+                    }
+
+        simple_type.__array_interface__ = property(__array_interface__)
+
+    simple_types = [
+        ((ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong), "i"),
+        ((ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong), "u"),
+        ((ct.c_float, ct.c_double), "f"),
+    ]
+
+    # Prep that numerical ctypes types:
+    for types, code in simple_types:
+        for tp in types:
+            prep_simple(tp, "%c%d" % (code, ct.sizeof(tp)))
+
+    ################################################################
+    # array types
+
+    _ARRAY_TYPE = type(ct.c_int * 1)
+
+    def prep_array(array_type):
+        """Given a ctypes array type, construct and attach an
+        __array_interface__ property to it if it does not yet have one.
+        """
+        try: array_type.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        shape = []
+        ob = array_type
+        while type(ob) is _ARRAY_TYPE:
+            shape.append(ob._length_)
+            ob = ob._type_
+        shape = tuple(shape)
+        ai = ob().__array_interface__
+        descr = ai['descr']
+        typestr = ai['typestr']
+
+        def __array_interface__(self):
+            return {'descr': descr,
+                    '__ref': self,
+                    'strides': None,
+                    'shape': shape,
+                    'version': 3,
+                    'typestr': typestr,
+                    'data': (ct.addressof(self), False),
+                    }
+
+        array_type.__array_interface__ = property(__array_interface__)
+
+    def prep_pointer(pointer_obj, shape):
+        """Given a ctypes pointer object, construct and
+        attach an __array_interface__ property to it if it does not
+        yet have one.
+        """
+        try: pointer_obj.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        contents = pointer_obj.contents
+        dtype = _dtype(type(contents))
+
+        inter = {'version': 3,
+                 'typestr': dtype.str,
+                 'data': (ct.addressof(contents), False),
+                 'shape': shape}
+
+        pointer_obj.__array_interface__ = inter
+
+    ################################################################
+    # public functions
+
+    def as_array(obj, shape=None):
+        """Create a numpy array from a ctypes array or a ctypes POINTER.
+        The numpy array shares the memory with the ctypes object.
+
+        The size parameter must be given if converting from a ctypes POINTER.
+        The size parameter is ignored if converting from a ctypes array
+        """
+        tp = type(obj)
+        try: tp.__array_interface__
+        except AttributeError:
+            if hasattr(obj, 'contents'):
+                prep_pointer(obj, shape)
+            else:
+                prep_array(tp)
+        return array(obj, copy=False)
+
+    def as_ctypes(obj):
+        """Create and return a ctypes object from a numpy array.  Actually
+        anything that exposes the __array_interface__ is accepted."""
+        ai = obj.__array_interface__
+        if ai["strides"]:
+            raise TypeError("strided arrays not supported")
+        if ai["version"] != 3:
+            raise TypeError("only __array_interface__ version 3 supported")
+        addr, readonly = ai["data"]
+        if readonly:
+            raise TypeError("readonly arrays unsupported")
+        tp = _typecodes[ai["typestr"]]
+        for dim in ai["shape"][::-1]:
+            tp = tp * dim
+        result = tp.from_address(addr)
+        result.__keep = ai
+        return result
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.py
new file mode 100644
index 0000000000..8d0a522235
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.py
@@ -0,0 +1,26 @@
+# This file is generated by C:/repo/mingw-w64-python-numpy/src/numpy-py2-i686/setup.py
+# It contains system_info results at the time of building this package.
+__all__ = ["get_info","show"]
+
+lapack_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+openblas_lapack_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_mkl_info={}
+openblas_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw32/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    
\ No newline at end of file
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.py
new file mode 100644
index 0000000000..602a3d1170
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from .__version__ import version as __version__
+# Must import local ccompiler ASAP in order to get
+# customized CCompiler.spawn effective.
+from . import ccompiler
+from . import unixccompiler
+
+from .info import __doc__
+from .npy_pkg_config import *
+
+# If numpy is installed, add distutils.test()
+try:
+    from . import __config__
+    # Normally numpy is installed if the above import works, but an interrupted
+    # in-place build could also have left a __config__.py.  In that case the
+    # next import may still fail, so keep it inside the try block.
+    from numpy.testing.nosetester import _numpy_tester
+    test = _numpy_tester().test
+except ImportError:
+    pass
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.py
new file mode 100644
index 0000000000..969decbba2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.py
@@ -0,0 +1,6 @@
+from __future__ import division, absolute_import, print_function
+
+major = 0
+minor = 4
+micro = 0
+version = '%(major)d.%(minor)d.%(micro)d' % (locals())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
new file mode 100644
index 0000000000..2f2d63b599
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
@@ -0,0 +1,689 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import types
+from copy import copy
+from distutils import ccompiler
+from distutils.ccompiler import *
+from distutils.errors import DistutilsExecError, DistutilsModuleError, \
+                             DistutilsPlatformError
+from distutils.sysconfig import customize_compiler
+from distutils.version import LooseVersion
+
+from numpy.distutils import log
+from numpy.distutils.compat import get_exception
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, \
+                                      quote_args, get_num_build_jobs
+
+
+def replace_method(klass, method_name, func):
+    if sys.version_info[0] < 3:
+        m = types.MethodType(func, None, klass)
+    else:
+        # Py3k does not have unbound method anymore, MethodType does not work
+        m = lambda self, *args, **kw: func(self, *args, **kw)
+    setattr(klass, method_name, m)
+
+# Using customized CCompiler.spawn.
+def CCompiler_spawn(self, cmd, display=None):
+    """
+    Execute a command in a sub-process.
+
+    Parameters
+    ----------
+    cmd : str
+        The command to execute.
+    display : str or sequence of str, optional
+        The text to add to the log file kept by `numpy.distutils`.
+        If not given, `display` is equal to `cmd`.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    DistutilsExecError
+        If the command failed, i.e. the exit status was not 0.
+
+    """
+    if display is None:
+        display = cmd
+        if is_sequence(display):
+            display = ' '.join(list(display))
+    log.info(display)
+    s, o = exec_command(cmd)
+    if s:
+        if is_sequence(cmd):
+            cmd = ' '.join(list(cmd))
+        try:
+            print(o)
+        except UnicodeError:
+            # When installing through pip, `o` can contain non-ascii chars
+            pass
+        if re.search('Too many open files', o):
+            msg = '\nTry rerunning setup command until build succeeds.'
+        else:
+            msg = ''
+        raise DistutilsExecError('Command "%s" failed with exit status %d%s' % (cmd, s, msg))
+
+replace_method(CCompiler, 'spawn', CCompiler_spawn)
+
+def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
+    """
+    Return the name of the object files for the given source files.
+
+    Parameters
+    ----------
+    source_filenames : list of str
+        The list of paths to source files. Paths can be either relative or
+        absolute, this is handled transparently.
+    strip_dir : bool, optional
+        Whether to strip the directory from the returned paths. If True,
+        the file name prepended by `output_dir` is returned. Default is False.
+    output_dir : str, optional
+        If given, this path is prepended to the returned paths to the
+        object files.
+
+    Returns
+    -------
+    obj_names : list of str
+        The list of paths to the object files corresponding to the source
+        files in `source_filenames`.
+
+    """
+    if output_dir is None:
+        output_dir = ''
+    obj_names = []
+    for src_name in source_filenames:
+        base, ext = os.path.splitext(os.path.normpath(src_name))
+        base = os.path.splitdrive(base)[1] # Chop off the drive
+        base = base[os.path.isabs(base):]  # If abs, chop off leading /
+        if base.startswith('..'):
+            # Resolve starting relative path components, middle ones
+            # (if any) have been handled by os.path.normpath above.
+            i = base.rfind('..')+2
+            d = base[:i]
+            d = os.path.basename(os.path.abspath(d))
+            base = d + base[i:]
+        if ext not in self.src_extensions:
+            raise UnknownFileError("unknown file type '%s' (from '%s')" % (ext, src_name))
+        if strip_dir:
+            base = os.path.basename(base)
+        obj_name = os.path.join(output_dir, base + self.obj_extension)
+        obj_names.append(obj_name)
+    return obj_names
+
+replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames)
+
+def CCompiler_compile(self, sources, output_dir=None, macros=None,
+                      include_dirs=None, debug=0, extra_preargs=None,
+                      extra_postargs=None, depends=None):
+    """
+    Compile one or more source files.
+
+    Please refer to the Python distutils API reference for more details.
+
+    Parameters
+    ----------
+    sources : list of str
+        A list of filenames
+    output_dir : str, optional
+        Path to the output directory.
+    macros : list of tuples
+        A list of macro definitions.
+    include_dirs : list of str, optional
+        The directories to add to the default include file search path for
+        this compilation only.
+    debug : bool, optional
+        Whether or not to output debug symbols in or alongside the object
+        file(s).
+    extra_preargs, extra_postargs : ?
+        Extra pre- and post-arguments.
+    depends : list of str, optional
+        A list of file names that all targets depend on.
+
+    Returns
+    -------
+    objects : list of str
+        A list of object file names, one per source file `sources`.
+
+    Raises
+    ------
+    CompileError
+        If compilation fails.
+
+    """
+    # This method is effective only with Python >=2.3 distutils.
+    # Any changes here should be applied also to fcompiler.compile
+    # method to support pre Python 2.3 distutils.
+    if not sources:
+        return []
+    # FIXME:RELATIVE_IMPORT
+    if sys.version_info[0] < 3:
+        from .fcompiler import FCompiler, is_f_file, has_f90_header
+    else:
+        from numpy.distutils.fcompiler import (FCompiler, is_f_file,
+                                               has_f90_header)
+    if isinstance(self, FCompiler):
+        display = []
+        for fc in ['f77', 'f90', 'fix']:
+            fcomp = getattr(self, 'compiler_'+fc)
+            if fcomp is None:
+                continue
+            display.append("Fortran %s compiler: %s" % (fc, ' '.join(fcomp)))
+        display = '\n'.join(display)
+    else:
+        ccomp = self.compiler_so
+        display = "C compiler: %s\n" % (' '.join(ccomp),)
+    log.info(display)
+    macros, objects, extra_postargs, pp_opts, build = \
+            self._setup_compile(output_dir, macros, include_dirs, sources,
+                                depends, extra_postargs)
+    cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
+    display = "compile options: '%s'" % (' '.join(cc_args))
+    if extra_postargs:
+        display += "\nextra options: '%s'" % (' '.join(extra_postargs))
+    log.info(display)
+
+    def single_compile(args):
+        obj, (src, ext) = args
+        self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
+
+    if isinstance(self, FCompiler):
+        objects_to_build = list(build.keys())
+        f77_objects, other_objects = [], []
+        for obj in objects:
+            if obj in objects_to_build:
+                src, ext = build[obj]
+                if self.compiler_type=='absoft':
+                    obj = cyg2win32(obj)
+                    src = cyg2win32(src)
+                if is_f_file(src) and not has_f90_header(src):
+                    f77_objects.append((obj, (src, ext)))
+                else:
+                    other_objects.append((obj, (src, ext)))
+
+        # f77 objects can be built in parallel
+        build_items = f77_objects
+        # build f90 modules serial, module files are generated during
+        # compilation and may be used by files later in the list so the
+        # ordering is important
+        for o in other_objects:
+            single_compile(o)
+    else:
+        build_items = build.items()
+
+    jobs = get_num_build_jobs()
+    if len(build) > 1 and jobs > 1:
+        # build parallel
+        import multiprocessing.pool
+        pool = multiprocessing.pool.ThreadPool(jobs)
+        pool.map(single_compile, build_items)
+        pool.close()
+    else:
+        # build serial
+        for o in build_items:
+            single_compile(o)
+
+    # Return *all* object filenames, not just the ones we just built.
+    return objects
+
+replace_method(CCompiler, 'compile', CCompiler_compile)
+
+def CCompiler_customize_cmd(self, cmd, ignore=()):
+    """
+    Customize compiler using distutils command.
+
+    Parameters
+    ----------
+    cmd : class instance
+        An instance inheriting from `distutils.cmd.Command`.
+    ignore : sequence of str, optional
+        List of `CCompiler` commands (without ``'set_'``) that should not be
+        altered. Strings that are checked for are:
+        ``('include_dirs', 'define', 'undef', 'libraries', 'library_dirs',
+        'rpath', 'link_objects')``.
+
+    Returns
+    -------
+    None
+
+    """
+    log.info('customize %s using %s' % (self.__class__.__name__,
+                                        cmd.__class__.__name__))
+    def allow(attr):
+        return getattr(cmd, attr, None) is not None and attr not in ignore
+
+    if allow('include_dirs'):
+        self.set_include_dirs(cmd.include_dirs)
+    if allow('define'):
+        for (name, value) in cmd.define:
+            self.define_macro(name, value)
+    if allow('undef'):
+        for macro in cmd.undef:
+            self.undefine_macro(macro)
+    if allow('libraries'):
+        self.set_libraries(self.libraries + cmd.libraries)
+    if allow('library_dirs'):
+        self.set_library_dirs(self.library_dirs + cmd.library_dirs)
+    if allow('rpath'):
+        self.set_runtime_library_dirs(cmd.rpath)
+    if allow('link_objects'):
+        self.set_link_objects(cmd.link_objects)
+
+replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd)
+
+def _compiler_to_string(compiler):
+    props = []
+    mx = 0
+    keys = list(compiler.executables.keys())
+    for key in ['version', 'libraries', 'library_dirs',
+                'object_switch', 'compile_switch',
+                'include_dirs', 'define', 'undef', 'rpath', 'link_objects']:
+        if key not in keys:
+            keys.append(key)
+    for key in keys:
+        if hasattr(compiler, key):
+            v = getattr(compiler, key)
+            mx = max(mx, len(key))
+            props.append((key, repr(v)))
+    lines = []
+    format = '%-' + repr(mx+1) + 's = %s'
+    for prop in props:
+        lines.append(format % prop)
+    return '\n'.join(lines)
+
+def CCompiler_show_customization(self):
+    """
+    Print the compiler customizations to stdout.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    None
+
+    Notes
+    -----
+    Printing is only done if the distutils log threshold is < 2.
+
+    """
+    if 0:
+        for attrname in ['include_dirs', 'define', 'undef',
+                         'libraries', 'library_dirs',
+                         'rpath', 'link_objects']:
+            attr = getattr(self, attrname, None)
+            if not attr:
+                continue
+            log.info("compiler '%s' is set to %s" % (attrname, attr))
+    try:
+        self.get_version()
+    except:
+        pass
+    if log._global_log.threshold<2:
+        print('*'*80)
+        print(self.__class__)
+        print(_compiler_to_string(self))
+        print('*'*80)
+
+replace_method(CCompiler, 'show_customization', CCompiler_show_customization)
+
+def CCompiler_customize(self, dist, need_cxx=0):
+    """
+    Do any platform-specific customization of a compiler instance.
+
+    This method calls `distutils.sysconfig.customize_compiler` for
+    platform-specific customization, as well as optionally remove a flag
+    to suppress spurious warnings in case C++ code is being compiled.
+
+    Parameters
+    ----------
+    dist : object
+        This parameter is not used for anything.
+    need_cxx : bool, optional
+        Whether or not C++ has to be compiled. If so (True), the
+        ``"-Wstrict-prototypes"`` option is removed to prevent spurious
+        warnings. Default is False.
+
+    Returns
+    -------
+    None
+
+    Notes
+    -----
+    All the default options used by distutils can be extracted with::
+
+      from distutils import sysconfig
+      sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS',
+                                'CCSHARED', 'LDSHARED', 'SO')
+
+    """
+    # See FCompiler.customize for suggested usage.
+    log.info('customize %s' % (self.__class__.__name__))
+    customize_compiler(self)
+    if need_cxx:
+        # In general, distutils uses -Wstrict-prototypes, but this option is
+        # not valid for C++ code, only for C.  Remove it if it's there to
+        # avoid a spurious warning on every compilation.
+        try:
+            self.compiler_so.remove('-Wstrict-prototypes')
+        except (AttributeError, ValueError):
+            pass
+
+        if hasattr(self, 'compiler') and 'cc' in self.compiler[0]:
+            if not self.compiler_cxx:
+                if self.compiler[0].startswith('gcc'):
+                    a, b = 'gcc', 'g++'
+                else:
+                    a, b = 'cc', 'c++'
+                self.compiler_cxx = [self.compiler[0].replace(a, b)]\
+                                    + self.compiler[1:]
+        else:
+            if hasattr(self, 'compiler'):
+                log.warn("#### %s #######" % (self.compiler,))
+            if not hasattr(self, 'compiler_cxx'):
+                log.warn('Missing compiler_cxx fix for ' + self.__class__.__name__)
+    return
+
+replace_method(CCompiler, 'customize', CCompiler_customize)
+
+def simple_version_match(pat=r'[-.\d]+', ignore='', start=''):
+    """
+    Simple matching of version numbers, for use in CCompiler and FCompiler.
+
+    Parameters
+    ----------
+    pat : str, optional
+        A regular expression matching version numbers.
+        Default is ``r'[-.\\d]+'``.
+    ignore : str, optional
+        A regular expression matching patterns to skip.
+        Default is ``''``, in which case nothing is skipped.
+    start : str, optional
+        A regular expression matching the start of where to start looking
+        for version numbers.
+        Default is ``''``, in which case searching is started at the
+        beginning of the version string given to `matcher`.
+
+    Returns
+    -------
+    matcher : callable
+        A function that is appropriate to use as the ``.version_match``
+        attribute of a `CCompiler` class. `matcher` takes a single parameter,
+        a version string.
+
+    """
+    def matcher(self, version_string):
+        # version string may appear in the second line, so getting rid
+        # of new lines:
+        version_string = version_string.replace('\n', ' ')
+        pos = 0
+        if start:
+            m = re.match(start, version_string)
+            if not m:
+                return None
+            pos = m.end()
+        while True:
+            m = re.search(pat, version_string[pos:])
+            if not m:
+                return None
+            if ignore and re.match(ignore, m.group(0)):
+                pos = m.end()
+                continue
+            break
+        return m.group(0)
+    return matcher
+
+def CCompiler_get_version(self, force=False, ok_status=[0]):
+    """
+    Return compiler version, or None if compiler is not available.
+
+    Parameters
+    ----------
+    force : bool, optional
+        If True, force a new determination of the version, even if the
+        compiler already has a version attribute. Default is False.
+    ok_status : list of int, optional
+        The list of status values returned by the version look-up process
+        for which a version string is returned. If the status value is not
+        in `ok_status`, None is returned. Default is ``[0]``.
+
+    Returns
+    -------
+    version : str or None
+        Version string, in the format of `distutils.version.LooseVersion`.
+
+    """
+    if not force and hasattr(self, 'version'):
+        return self.version
+    self.find_executables()
+    try:
+        version_cmd = self.version_cmd
+    except AttributeError:
+        return None
+    if not version_cmd or not version_cmd[0]:
+        return None
+    try:
+        matcher = self.version_match
+    except AttributeError:
+        try:
+            pat = self.version_pattern
+        except AttributeError:
+            return None
+        def matcher(version_string):
+            m = re.match(pat, version_string)
+            if not m:
+                return None
+            version = m.group('version')
+            return version
+
+    status, output = exec_command(version_cmd, use_tee=0)
+
+    version = None
+    if status in ok_status:
+        version = matcher(output)
+        if version:
+            version = LooseVersion(version)
+    self.version = version
+    return version
+
+replace_method(CCompiler, 'get_version', CCompiler_get_version)
+
+def CCompiler_cxx_compiler(self):
+    """
+    Return the C++ compiler.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    cxx : class instance
+        The C++ compiler, as a `CCompiler` instance.
+
+    """
+    if self.compiler_type in ('msvc', 'intelw', 'intelemw'):
+        return self
+
+    cxx = copy(self)
+    cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:]
+    if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]:
+        # AIX needs the ld_so_aix script included with Python
+        cxx.linker_so = [cxx.linker_so[0], cxx.compiler_cxx[0]] \
+                        + cxx.linker_so[2:]
+    else:
+        cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:]
+    return cxx
+
+replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler)
+
+compiler_class['intel'] = ('intelccompiler', 'IntelCCompiler',
+                           "Intel C Compiler for 32-bit applications")
+compiler_class['intele'] = ('intelccompiler', 'IntelItaniumCCompiler',
+                            "Intel C Itanium Compiler for Itanium-based applications")
+compiler_class['intelem'] = ('intelccompiler', 'IntelEM64TCCompiler',
+                             "Intel C Compiler for 64-bit applications")
+compiler_class['intelw'] = ('intelccompiler', 'IntelCCompilerW',
+                            "Intel C Compiler for 32-bit applications on Windows")
+compiler_class['intelemw'] = ('intelccompiler', 'IntelEM64TCCompilerW',
+                              "Intel C Compiler for 64-bit applications on Windows")
+compiler_class['pathcc'] = ('pathccompiler', 'PathScaleCCompiler',
+                            "PathScale Compiler for SiCortex-based applications")
+ccompiler._default_compilers += (('linux.*', 'intel'),
+                                 ('linux.*', 'intele'),
+                                 ('linux.*', 'intelem'),
+                                 ('linux.*', 'pathcc'),
+                                 ('nt', 'intelw'),
+                                 ('nt', 'intelemw'))
+
+if sys.platform == 'win32':
+    compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',
+                                 "Mingw32 port of GNU C Compiler for Win32"\
+                                 "(for MSC built Python)")
+    if mingw32():
+        # On windows platforms, we want to default to mingw32 (gcc)
+        # because msvc can't build blitz stuff.
+        log.info('Setting mingw32 as default compiler for nt.')
+        ccompiler._default_compilers = (('nt', 'mingw32'),) \
+                                       + ccompiler._default_compilers
+
+
+_distutils_new_compiler = new_compiler
+def new_compiler (plat=None,
+                  compiler=None,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+    # Try first C compilers from numpy.distutils.
+    if plat is None:
+        plat = os.name
+    try:
+        if compiler is None:
+            compiler = get_default_compiler(plat)
+        (module_name, class_name, long_description) = compiler_class[compiler]
+    except KeyError:
+        msg = "don't know how to compile C/C++ code on platform '%s'" % plat
+        if compiler is not None:
+            msg = msg + " with '%s' compiler" % compiler
+        raise DistutilsPlatformError(msg)
+    module_name = "numpy.distutils." + module_name
+    try:
+        __import__ (module_name)
+    except ImportError:
+        msg = str(get_exception())
+        log.info('%s in numpy.distutils; trying from distutils',
+                 str(msg))
+        module_name = module_name[6:]
+        try:
+            __import__(module_name)
+        except ImportError:
+            msg = str(get_exception())
+            raise DistutilsModuleError("can't compile C/C++ code: unable to load module '%s'" % \
+                  module_name)
+    try:
+        module = sys.modules[module_name]
+        klass = vars(module)[class_name]
+    except KeyError:
+        raise DistutilsModuleError(("can't compile C/C++ code: unable to find class '%s' " +
+               "in module '%s'") % (class_name, module_name))
+    compiler = klass(None, dry_run, force)
+    log.debug('new_compiler returns %s' % (klass))
+    return compiler
+
+ccompiler.new_compiler = new_compiler
+
+_distutils_gen_lib_options = gen_lib_options
+def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
+    library_dirs = quote_args(library_dirs)
+    runtime_library_dirs = quote_args(runtime_library_dirs)
+    r = _distutils_gen_lib_options(compiler, library_dirs,
+                                   runtime_library_dirs, libraries)
+    lib_opts = []
+    for i in r:
+        if is_sequence(i):
+            lib_opts.extend(list(i))
+        else:
+            lib_opts.append(i)
+    return lib_opts
+ccompiler.gen_lib_options = gen_lib_options
+
+# Also fix up the various compiler modules, which do
+# from distutils.ccompiler import gen_lib_options
+# Don't bother with mwerks, as we don't support Classic Mac.
+for _cc in ['msvc9', 'msvc', 'bcpp', 'cygwinc', 'emxc', 'unixc']:
+    _m = sys.modules.get('distutils.' + _cc + 'compiler')
+    if _m is not None:
+        setattr(_m, 'gen_lib_options', gen_lib_options)
+
+_distutils_gen_preprocess_options = gen_preprocess_options
+def gen_preprocess_options (macros, include_dirs):
+    include_dirs = quote_args(include_dirs)
+    return _distutils_gen_preprocess_options(macros, include_dirs)
+ccompiler.gen_preprocess_options = gen_preprocess_options
+
+##Fix distutils.util.split_quoted:
+# NOTE:  I removed this fix in revision 4481 (see ticket #619), but it appears
+# that removing this fix causes f2py problems on Windows XP (see ticket #723).
+# Specifically, on WinXP when gfortran is installed in a directory path, which
+# contains spaces, then f2py is unable to find it.
+import string
+_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
+_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
+_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
+_has_white_re = re.compile(r'\s')
+def split_quoted(s):
+    s = s.strip()
+    words = []
+    pos = 0
+
+    while s:
+        m = _wordchars_re.match(s, pos)
+        end = m.end()
+        if end == len(s):
+            words.append(s[:end])
+            break
+
+        if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
+            words.append(s[:end])       # we definitely have a word delimiter
+            s = s[end:].lstrip()
+            pos = 0
+
+        elif s[end] == '\\':            # preserve whatever is being escaped;
+                                        # will become part of the current word
+            s = s[:end] + s[end+1:]
+            pos = end+1
+
+        else:
+            if s[end] == "'":           # slurp singly-quoted string
+                m = _squote_re.match(s, end)
+            elif s[end] == '"':         # slurp doubly-quoted string
+                m = _dquote_re.match(s, end)
+            else:
+                raise RuntimeError("this can't happen (bad char '%c')" % s[end])
+
+            if m is None:
+                raise ValueError("bad string (mismatched %s quotes?)" % s[end])
+
+            (beg, end) = m.span()
+            if _has_white_re.search(s[beg+1:end-1]):
+                s = s[:beg] + s[beg+1:end-1] + s[end:]
+                pos = m.end() - 2
+            else:
+                # Keeping quotes when a quoted word does not contain
+                # white-space. XXX: send a patch to distutils
+                pos = m.end()
+
+        if pos >= len(s):
+            words.append(s)
+            break
+
+    return words
+ccompiler.split_quoted = split_quoted
+##Fix distutils.util.split_quoted:
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
new file mode 100644
index 0000000000..76a2600723
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
@@ -0,0 +1,43 @@
+"""distutils.command
+
+Package containing implementation of all the standard Distutils
+commands.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+def test_na_writable_attributes_deletion():
+    a = np.NA(2)
+    attr =  ['payload', 'dtype']
+    for s in attr:
+        assert_raises(AttributeError, delattr, a, s)
+
+
+__revision__ = "$Id: __init__.py,v 1.3 2005/05/16 11:08:49 pearu Exp $"
+
+distutils_all = [  #'build_py',
+                   'clean',
+                   'install_clib',
+                   'install_scripts',
+                   'bdist',
+                   'bdist_dumb',
+                   'bdist_wininst',
+                ]
+
+__import__('distutils.command', globals(), locals(), distutils_all)
+
+__all__ = ['build',
+           'config_compiler',
+           'config',
+           'build_src',
+           'build_py',
+           'build_ext',
+           'build_clib',
+           'build_scripts',
+           'install',
+           'install_data',
+           'install_headers',
+           'install_lib',
+           'bdist_rpm',
+           'sdist',
+          ] + distutils_all
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
new file mode 100644
index 0000000000..d5e78963c1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
@@ -0,0 +1,96 @@
+"""This module implements additional tests ala autoconf which can be useful.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+
+# We put them here since they could be easily reused outside numpy.distutils
+
+def check_inline(cmd):
+    """Return the inline identifier (may be empty)."""
+    cmd._check_compiler()
+    body = """
+#ifndef __cplusplus
+static %(inline)s int static_func (void)
+{
+    return 0;
+}
+%(inline)s int nostatic_func (void)
+{
+    return 0;
+}
+#endif"""
+
+    for kw in ['inline', '__inline__', '__inline']:
+        st = cmd.try_compile(body % {'inline': kw}, None, None)
+        if st:
+            return kw
+
+    return ''
+
+def check_restrict(cmd):
+    """Return the restrict identifier (may be empty)."""
+    cmd._check_compiler()
+    body = """
+static int static_func (char * %(restrict)s a)
+{
+    return 0;
+}
+"""
+
+    for kw in ['restrict', '__restrict__', '__restrict']:
+        st = cmd.try_compile(body % {'restrict': kw}, None, None)
+        if st:
+            return kw
+
+    return ''
+
+def check_compiler_gcc4(cmd):
+    """Return True if the C compiler is GCC 4.x."""
+    cmd._check_compiler()
+    body = """
+int
+main()
+{
+#if (! defined __GNUC__) || (__GNUC__ < 4)
+#error gcc >= 4 required
+#endif
+    return 0;
+}
+"""
+    return cmd.try_compile(body, None, None)
+
+
+def check_gcc_function_attribute(cmd, attribute, name):
+    """Return True if the given function attribute is supported."""
+    cmd._check_compiler()
+    body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s %s(void*);
+
+int
+main()
+{
+    return 0;
+}
+""" % (attribute, name)
+    return cmd.try_compile(body, None, None) != 0
+
+def check_gcc_variable_attribute(cmd, attribute):
+    """Return True if the given variable attribute is supported."""
+    cmd._check_compiler()
+    body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s foo;
+
+int
+main()
+{
+    return 0;
+}
+""" % (attribute, )
+    return cmd.try_compile(body, None, None) != 0
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
new file mode 100644
index 0000000000..3e52a503b1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
@@ -0,0 +1,24 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+if 'setuptools' in sys.modules:
+    from setuptools.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+else:
+    from distutils.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+
+class bdist_rpm(old_bdist_rpm):
+
+    def _make_spec_file(self):
+        spec_file = old_bdist_rpm._make_spec_file(self)
+
+        # Replace hardcoded setup.py script name
+        # with the real setup script name.
+        setup_py = os.path.basename(sys.argv[0])
+        if setup_py == 'setup.py':
+            return spec_file
+        new_spec_file = []
+        for line in spec_file:
+            line = line.replace('setup.py', setup_py)
+            new_spec_file.append(line)
+        return new_spec_file
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.py
new file mode 100644
index 0000000000..3d7101582a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.py
@@ -0,0 +1,47 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from distutils.command.build import build as old_build
+from distutils.util import get_platform
+from numpy.distutils.command.config_compiler import show_fortran_compilers
+
+class build(old_build):
+
+    sub_commands = [('config_cc',     lambda *args: True),
+                    ('config_fc',     lambda *args: True),
+                    ('build_src',     old_build.has_ext_modules),
+                    ] + old_build.sub_commands
+
+    user_options = old_build.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    help_options = old_build.help_options + [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    def initialize_options(self):
+        old_build.initialize_options(self)
+        self.fcompiler = None
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+        build_scripts = self.build_scripts
+        old_build.finalize_options(self)
+        plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+        if build_scripts is None:
+            self.build_scripts = os.path.join(self.build_base,
+                                              'scripts' + plat_specifier)
+
+    def run(self):
+        old_build.run(self)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
new file mode 100644
index 0000000000..1c868cf6c7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
@@ -0,0 +1,295 @@
+""" Modified version of build_clib that handles fortran source files.
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+from glob import glob
+import shutil
+from distutils.command.build_clib import build_clib as old_build_clib
+from distutils.errors import DistutilsSetupError, DistutilsError, \
+     DistutilsFileError
+
+from numpy.distutils import log
+from distutils.dep_util import newer_group
+from numpy.distutils.misc_util import filter_sources, has_f_sources,\
+     has_cxx_sources, all_strings, get_lib_source_files, is_sequence, \
+     get_numpy_include_dirs
+
+# Fix Python distutils bug sf #1718574:
+_l = old_build_clib.user_options
+for _i in range(len(_l)):
+    if _l[_i][0] in ['build-clib', 'build-temp']:
+        _l[_i] = (_l[_i][0]+'=',)+_l[_i][1:]
+#
+
+class build_clib(old_build_clib):
+
+    description = "build C/C++/F libraries used by Python extensions"
+
+    user_options = old_build_clib.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('inplace', 'i', 'Build in-place'),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    boolean_options = old_build_clib.boolean_options + ['inplace']
+
+    def initialize_options(self):
+        old_build_clib.initialize_options(self)
+        self.fcompiler = None
+        self.inplace = 0
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+        old_build_clib.finalize_options(self)
+        self.set_undefined_options('build', ('parallel', 'parallel'))
+
+    def have_f_sources(self):
+        for (lib_name, build_info) in self.libraries:
+            if has_f_sources(build_info.get('sources', [])):
+                return True
+        return False
+
+    def have_cxx_sources(self):
+        for (lib_name, build_info) in self.libraries:
+            if has_cxx_sources(build_info.get('sources', [])):
+                return True
+        return False
+
+    def run(self):
+        if not self.libraries:
+            return
+
+        # Make sure that library sources are complete.
+        languages = []
+
+        # Make sure that extension sources are complete.
+        self.run_command('build_src')
+
+        for (lib_name, build_info) in self.libraries:
+            l = build_info.get('language', None)
+            if l and l not in languages: languages.append(l)
+
+        from distutils.ccompiler import new_compiler
+        self.compiler = new_compiler(compiler=self.compiler,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        self.compiler.customize(self.distribution,
+                                need_cxx=self.have_cxx_sources())
+
+        libraries = self.libraries
+        self.libraries = None
+        self.compiler.customize_cmd(self)
+        self.libraries = libraries
+
+        self.compiler.show_customization()
+
+        if self.have_f_sources():
+            from numpy.distutils.fcompiler import new_fcompiler
+            self._f_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90='f90' in languages,
+                                               c_compiler=self.compiler)
+            if self._f_compiler is not None:
+                self._f_compiler.customize(self.distribution)
+
+                libraries = self.libraries
+                self.libraries = None
+                self._f_compiler.customize_cmd(self)
+                self.libraries = libraries
+
+                self._f_compiler.show_customization()
+        else:
+            self._f_compiler = None
+
+        self.build_libraries(self.libraries)
+
+        if self.inplace:
+            for l in  self.distribution.installed_libraries:
+                libname = self.compiler.library_filename(l.name)
+                source = os.path.join(self.build_clib, libname)
+                target =  os.path.join(l.target_dir, libname)
+                self.mkpath(l.target_dir)
+                shutil.copy(source, target)
+
+    def get_source_files(self):
+        self.check_library_list(self.libraries)
+        filenames = []
+        for lib in self.libraries:
+            filenames.extend(get_lib_source_files(lib))
+        return filenames
+
+    def build_libraries(self, libraries):
+        for (lib_name, build_info) in libraries:
+            self.build_a_library(build_info, lib_name, libraries)
+
+    def build_a_library(self, build_info, lib_name, libraries):
+        # default compilers
+        compiler = self.compiler
+        fcompiler = self._f_compiler
+
+        sources = build_info.get('sources')
+        if sources is None or not is_sequence(sources):
+            raise DistutilsSetupError(("in 'libraries' option (library '%s'), " +
+                   "'sources' must be present and must be " +
+                   "a list of source filenames") % lib_name)
+        sources = list(sources)
+
+        c_sources, cxx_sources, f_sources, fmodule_sources \
+                   = filter_sources(sources)
+        requiref90 = not not fmodule_sources or \
+                     build_info.get('language', 'c')=='f90'
+
+        # save source type information so that build_ext can use it.
+        source_languages = []
+        if c_sources: source_languages.append('c')
+        if cxx_sources: source_languages.append('c++')
+        if requiref90: source_languages.append('f90')
+        elif f_sources: source_languages.append('f77')
+        build_info['source_languages'] = source_languages
+
+        lib_file = compiler.library_filename(lib_name,
+                                             output_dir=self.build_clib)
+        depends = sources + build_info.get('depends', [])
+        if not (self.force or newer_group(depends, lib_file, 'newer')):
+            log.debug("skipping '%s' library (up-to-date)", lib_name)
+            return
+        else:
+            log.info("building '%s' library", lib_name)
+
+        config_fc = build_info.get('config_fc', {})
+        if fcompiler is not None and config_fc:
+            log.info('using additional config_fc from setup script '\
+                     'for fortran compiler: %s' \
+                     % (config_fc,))
+            from numpy.distutils.fcompiler import new_fcompiler
+            fcompiler = new_fcompiler(compiler=fcompiler.compiler_type,
+                                      verbose=self.verbose,
+                                      dry_run=self.dry_run,
+                                      force=self.force,
+                                      requiref90=requiref90,
+                                      c_compiler=self.compiler)
+            if fcompiler is not None:
+                dist = self.distribution
+                base_config_fc = dist.get_option_dict('config_fc').copy()
+                base_config_fc.update(config_fc)
+                fcompiler.customize(base_config_fc)
+
+        # check availability of Fortran compilers
+        if (f_sources or fmodule_sources) and fcompiler is None:
+            raise DistutilsError("library %s has Fortran sources"\
+                  " but no Fortran compiler found" % (lib_name))
+
+        if fcompiler is not None:
+            fcompiler.extra_f77_compile_args = build_info.get('extra_f77_compile_args') or []
+            fcompiler.extra_f90_compile_args = build_info.get('extra_f90_compile_args') or []
+
+        macros = build_info.get('macros')
+        include_dirs = build_info.get('include_dirs')
+        if include_dirs is None:
+            include_dirs = []
+        extra_postargs = build_info.get('extra_compiler_args') or []
+
+        include_dirs.extend(get_numpy_include_dirs())
+        # where compiled F90 module files are:
+        module_dirs = build_info.get('module_dirs') or []
+        module_build_dir = os.path.dirname(lib_file)
+        if requiref90: self.mkpath(module_build_dir)
+
+        if compiler.compiler_type=='msvc':
+            # this hack works around the msvc compiler attributes
+            # problem, msvc uses its own convention :(
+            c_sources += cxx_sources
+            cxx_sources = []
+
+        objects = []
+        if c_sources:
+            log.info("compiling C sources")
+            objects = compiler.compile(c_sources,
+                                       output_dir=self.build_temp,
+                                       macros=macros,
+                                       include_dirs=include_dirs,
+                                       debug=self.debug,
+                                       extra_postargs=extra_postargs)
+
+        if cxx_sources:
+            log.info("compiling C++ sources")
+            cxx_compiler = compiler.cxx_compiler()
+            cxx_objects = cxx_compiler.compile(cxx_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+            objects.extend(cxx_objects)
+
+        if f_sources or fmodule_sources:
+            extra_postargs = []
+            f_objects = []
+
+            if requiref90:
+                if fcompiler.module_dir_switch is None:
+                    existing_modules = glob('*.mod')
+                extra_postargs += fcompiler.module_options(\
+                    module_dirs, module_build_dir)
+
+            if fmodule_sources:
+                log.info("compiling Fortran 90 module sources")
+                f_objects += fcompiler.compile(fmodule_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+
+            if requiref90 and self._f_compiler.module_dir_switch is None:
+                # move new compiled F90 module files to module_build_dir
+                for f in glob('*.mod'):
+                    if f in existing_modules:
+                        continue
+                    t = os.path.join(module_build_dir, f)
+                    if os.path.abspath(f)==os.path.abspath(t):
+                        continue
+                    if os.path.isfile(t):
+                        os.remove(t)
+                    try:
+                        self.move_file(f, module_build_dir)
+                    except DistutilsFileError:
+                        log.warn('failed to move %r to %r' \
+                                 % (f, module_build_dir))
+
+            if f_sources:
+                log.info("compiling Fortran sources")
+                f_objects += fcompiler.compile(f_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+        else:
+            f_objects = []
+
+        objects.extend(f_objects)
+
+        # assume that default linker is suitable for
+        # linking Fortran object files
+        compiler.create_static_lib(objects, lib_name,
+                                   output_dir=self.build_clib,
+                                   debug=self.debug)
+
+        # fix library dependencies
+        clib_libraries = build_info.get('libraries', [])
+        for lname, binfo in libraries:
+            if lname in clib_libraries:
+                clib_libraries.extend(binfo.get('libraries', []))
+        if clib_libraries:
+            build_info['libraries'] = clib_libraries
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
new file mode 100644
index 0000000000..0fa52a2818
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
@@ -0,0 +1,522 @@
+""" Modified version of build_ext that handles fortran source files.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from glob import glob
+
+from distutils.dep_util import newer_group
+from distutils.command.build_ext import build_ext as old_build_ext
+from distutils.errors import DistutilsFileError, DistutilsSetupError,\
+     DistutilsError
+from distutils.file_util import copy_file
+
+from numpy.distutils import log
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.system_info import combine_paths
+from numpy.distutils.misc_util import filter_sources, has_f_sources, \
+     has_cxx_sources, get_ext_source_files, \
+     get_numpy_include_dirs, is_sequence, get_build_architecture, \
+     msvc_version
+from numpy.distutils.command.config_compiler import show_fortran_compilers
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+class build_ext (old_build_ext):
+
+    description = "build C/C++/F extensions (compile/link to build directory)"
+
+    user_options = old_build_ext.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    help_options = old_build_ext.help_options + [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    def initialize_options(self):
+        old_build_ext.initialize_options(self)
+        self.fcompiler = None
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+
+        # Ensure that self.include_dirs and self.distribution.include_dirs
+        # refer to the same list object. finalize_options will modify
+        # self.include_dirs, but self.distribution.include_dirs is used
+        # during the actual build.
+        # self.include_dirs is None unless paths are specified with
+        # --include-dirs.
+        # The include paths will be passed to the compiler in the order:
+        # numpy paths, --include-dirs paths, Python include path.
+        if isinstance(self.include_dirs, str):
+            self.include_dirs = self.include_dirs.split(os.pathsep)
+        incl_dirs = self.include_dirs or []
+        if self.distribution.include_dirs is None:
+            self.distribution.include_dirs = []
+        self.include_dirs = self.distribution.include_dirs
+        self.include_dirs.extend(incl_dirs)
+
+        old_build_ext.finalize_options(self)
+        self.set_undefined_options('build', ('parallel', 'parallel'))
+
+    def run(self):
+        if not self.extensions:
+            return
+
+        # Make sure that extension sources are complete.
+        self.run_command('build_src')
+
+        if self.distribution.has_c_libraries():
+            if self.inplace:
+                if self.distribution.have_run.get('build_clib'):
+                    log.warn('build_clib already run, it is too late to ' \
+                            'ensure in-place build of build_clib')
+                    build_clib = self.distribution.get_command_obj('build_clib')
+                else:
+                    build_clib = self.distribution.get_command_obj('build_clib')
+                    build_clib.inplace = 1
+                    build_clib.ensure_finalized()
+                    build_clib.run()
+                    self.distribution.have_run['build_clib'] = 1
+
+            else:
+                self.run_command('build_clib')
+                build_clib = self.get_finalized_command('build_clib')
+            self.library_dirs.append(build_clib.build_clib)
+        else:
+            build_clib = None
+
+        # Not including C libraries to the list of
+        # extension libraries automatically to prevent
+        # bogus linking commands. Extensions must
+        # explicitly specify the C libraries that they use.
+
+        from distutils.ccompiler import new_compiler
+        from numpy.distutils.fcompiler import new_fcompiler
+
+        compiler_type = self.compiler
+        # Initialize C compiler:
+        self.compiler = new_compiler(compiler=compiler_type,
+                                     verbose=self.verbose,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        self.compiler.customize(self.distribution)
+        self.compiler.customize_cmd(self)
+        self.compiler.show_customization()
+
+        # Create mapping of libraries built by build_clib:
+        clibs = {}
+        if build_clib is not None:
+            for libname, build_info in build_clib.libraries or []:
+                if libname in clibs and clibs[libname] != build_info:
+                    log.warn('library %r defined more than once,'\
+                             ' overwriting build_info\n%s... \nwith\n%s...' \
+                             % (libname, repr(clibs[libname])[:300], repr(build_info)[:300]))
+                clibs[libname] = build_info
+        # .. and distribution libraries:
+        for libname, build_info in self.distribution.libraries or []:
+            if libname in clibs:
+                # build_clib libraries have a precedence before distribution ones
+                continue
+            clibs[libname] = build_info
+
+        # Determine if C++/Fortran 77/Fortran 90 compilers are needed.
+        # Update extension libraries, library_dirs, and macros.
+        all_languages = set()
+        for ext in self.extensions:
+            ext_languages = set()
+            c_libs = []
+            c_lib_dirs = []
+            macros = []
+            for libname in ext.libraries:
+                if libname in clibs:
+                    binfo = clibs[libname]
+                    c_libs += binfo.get('libraries', [])
+                    c_lib_dirs += binfo.get('library_dirs', [])
+                    for m in binfo.get('macros', []):
+                        if m not in macros:
+                            macros.append(m)
+
+                for l in clibs.get(libname, {}).get('source_languages', []):
+                    ext_languages.add(l)
+            if c_libs:
+                new_c_libs = ext.libraries + c_libs
+                log.info('updating extension %r libraries from %r to %r'
+                         % (ext.name, ext.libraries, new_c_libs))
+                ext.libraries = new_c_libs
+                ext.library_dirs = ext.library_dirs + c_lib_dirs
+            if macros:
+                log.info('extending extension %r defined_macros with %r'
+                         % (ext.name, macros))
+                ext.define_macros = ext.define_macros + macros
+
+            # determine extension languages
+            if has_f_sources(ext.sources):
+                ext_languages.add('f77')
+            if has_cxx_sources(ext.sources):
+                ext_languages.add('c++')
+            l = ext.language or self.compiler.detect_language(ext.sources)
+            if l:
+                ext_languages.add(l)
+            # reset language attribute for choosing proper linker
+            if 'c++' in ext_languages:
+                ext_language = 'c++'
+            elif 'f90' in ext_languages:
+                ext_language = 'f90'
+            elif 'f77' in ext_languages:
+                ext_language = 'f77'
+            else:
+                ext_language = 'c' # default
+            if l and l != ext_language and ext.language:
+                log.warn('resetting extension %r language from %r to %r.' %
+                         (ext.name, l, ext_language))
+            ext.language = ext_language
+            # global language
+            all_languages.update(ext_languages)
+
+        need_f90_compiler = 'f90' in all_languages
+        need_f77_compiler = 'f77' in all_languages
+        need_cxx_compiler = 'c++' in all_languages
+
+        # Initialize C++ compiler:
+        if need_cxx_compiler:
+            self._cxx_compiler = new_compiler(compiler=compiler_type,
+                                             verbose=self.verbose,
+                                             dry_run=self.dry_run,
+                                             force=self.force)
+            compiler = self._cxx_compiler
+            compiler.customize(self.distribution, need_cxx=need_cxx_compiler)
+            compiler.customize_cmd(self)
+            compiler.show_customization()
+            self._cxx_compiler = compiler.cxx_compiler()
+        else:
+            self._cxx_compiler = None
+
+        # Initialize Fortran 77 compiler:
+        if need_f77_compiler:
+            ctype = self.fcompiler
+            self._f77_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90=False,
+                                               c_compiler=self.compiler)
+            fcompiler = self._f77_compiler
+            if fcompiler:
+                ctype = fcompiler.compiler_type
+                fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
+                fcompiler.customize_cmd(self)
+                fcompiler.show_customization()
+            else:
+                self.warn('f77_compiler=%s is not available.' %
+                          (ctype))
+                self._f77_compiler = None
+        else:
+            self._f77_compiler = None
+
+        # Initialize Fortran 90 compiler:
+        if need_f90_compiler:
+            ctype = self.fcompiler
+            self._f90_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90=True,
+                                               c_compiler = self.compiler)
+            fcompiler = self._f90_compiler
+            if fcompiler:
+                ctype = fcompiler.compiler_type
+                fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
+                fcompiler.customize_cmd(self)
+                fcompiler.show_customization()
+            else:
+                self.warn('f90_compiler=%s is not available.' %
+                          (ctype))
+                self._f90_compiler = None
+        else:
+            self._f90_compiler = None
+
+        # Build extensions
+        self.build_extensions()
+
+
+    def swig_sources(self, sources):
+        # Do nothing. Swig sources have beed handled in build_src command.
+        return sources
+
+    def build_extension(self, ext):
+        sources = ext.sources
+        if sources is None or not is_sequence(sources):
+            raise DistutilsSetupError(
+                ("in 'ext_modules' option (extension '%s'), " +
+                 "'sources' must be present and must be " +
+                 "a list of source filenames") % ext.name)
+        sources = list(sources)
+
+        if not sources:
+            return
+
+        fullname = self.get_ext_fullname(ext.name)
+        if self.inplace:
+            modpath = fullname.split('.')
+            package = '.'.join(modpath[0:-1])
+            base = modpath[-1]
+            build_py = self.get_finalized_command('build_py')
+            package_dir = build_py.get_package_dir(package)
+            ext_filename = os.path.join(package_dir,
+                                        self.get_ext_filename(base))
+        else:
+            ext_filename = os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname))
+        depends = sources + ext.depends
+
+        if not (self.force or newer_group(depends, ext_filename, 'newer')):
+            log.debug("skipping '%s' extension (up-to-date)", ext.name)
+            return
+        else:
+            log.info("building '%s' extension", ext.name)
+
+        extra_args = ext.extra_compile_args or []
+        macros = ext.define_macros[:]
+        for undef in ext.undef_macros:
+            macros.append((undef,))
+
+        c_sources, cxx_sources, f_sources, fmodule_sources = \
+                   filter_sources(ext.sources)
+
+
+
+        if self.compiler.compiler_type=='msvc':
+            if cxx_sources:
+                # Needed to compile kiva.agg._agg extension.
+                extra_args.append('/Zm1000')
+            # this hack works around the msvc compiler attributes
+            # problem, msvc uses its own convention :(
+            c_sources += cxx_sources
+            cxx_sources = []
+
+        # Set Fortran/C++ compilers for compilation and linking.
+        if ext.language=='f90':
+            fcompiler = self._f90_compiler
+        elif ext.language=='f77':
+            fcompiler = self._f77_compiler
+        else: # in case ext.language is c++, for instance
+            fcompiler = self._f90_compiler or self._f77_compiler
+        if fcompiler is not None:
+            fcompiler.extra_f77_compile_args = (ext.extra_f77_compile_args or []) if hasattr(ext, 'extra_f77_compile_args') else []
+            fcompiler.extra_f90_compile_args = (ext.extra_f90_compile_args or []) if hasattr(ext, 'extra_f90_compile_args') else []
+        cxx_compiler = self._cxx_compiler
+
+        # check for the availability of required compilers
+        if cxx_sources and cxx_compiler is None:
+            raise DistutilsError("extension %r has C++ sources" \
+                  "but no C++ compiler found" % (ext.name))
+        if (f_sources or fmodule_sources) and fcompiler is None:
+            raise DistutilsError("extension %r has Fortran sources " \
+                  "but no Fortran compiler found" % (ext.name))
+        if ext.language in ['f77', 'f90'] and fcompiler is None:
+            self.warn("extension %r has Fortran libraries " \
+                  "but no Fortran linker found, using default linker" % (ext.name))
+        if ext.language=='c++' and cxx_compiler is None:
+            self.warn("extension %r has C++ libraries " \
+                  "but no C++ linker found, using default linker" % (ext.name))
+
+        kws = {'depends':ext.depends}
+        output_dir = self.build_temp
+
+        include_dirs = ext.include_dirs + get_numpy_include_dirs()
+
+        c_objects = []
+        if c_sources:
+            log.info("compiling C sources")
+            c_objects = self.compiler.compile(c_sources,
+                                              output_dir=output_dir,
+                                              macros=macros,
+                                              include_dirs=include_dirs,
+                                              debug=self.debug,
+                                              extra_postargs=extra_args,
+                                              **kws)
+
+        if cxx_sources:
+            log.info("compiling C++ sources")
+            c_objects += cxx_compiler.compile(cxx_sources,
+                                              output_dir=output_dir,
+                                              macros=macros,
+                                              include_dirs=include_dirs,
+                                              debug=self.debug,
+                                              extra_postargs=extra_args,
+                                              **kws)
+
+        extra_postargs = []
+        f_objects = []
+        if fmodule_sources:
+            log.info("compiling Fortran 90 module sources")
+            module_dirs = ext.module_dirs[:]
+            module_build_dir = os.path.join(
+                self.build_temp, os.path.dirname(
+                    self.get_ext_filename(fullname)))
+
+            self.mkpath(module_build_dir)
+            if fcompiler.module_dir_switch is None:
+                existing_modules = glob('*.mod')
+            extra_postargs += fcompiler.module_options(
+                module_dirs, module_build_dir)
+            f_objects += fcompiler.compile(fmodule_sources,
+                                           output_dir=self.build_temp,
+                                           macros=macros,
+                                           include_dirs=include_dirs,
+                                           debug=self.debug,
+                                           extra_postargs=extra_postargs,
+                                           depends=ext.depends)
+
+            if fcompiler.module_dir_switch is None:
+                for f in glob('*.mod'):
+                    if f in existing_modules:
+                        continue
+                    t = os.path.join(module_build_dir, f)
+                    if os.path.abspath(f)==os.path.abspath(t):
+                        continue
+                    if os.path.isfile(t):
+                        os.remove(t)
+                    try:
+                        self.move_file(f, module_build_dir)
+                    except DistutilsFileError:
+                        log.warn('failed to move %r to %r' %
+                                 (f, module_build_dir))
+        if f_sources:
+            log.info("compiling Fortran sources")
+            f_objects += fcompiler.compile(f_sources,
+                                           output_dir=self.build_temp,
+                                           macros=macros,
+                                           include_dirs=include_dirs,
+                                           debug=self.debug,
+                                           extra_postargs=extra_postargs,
+                                           depends=ext.depends)
+
+        objects = c_objects + f_objects
+
+        if ext.extra_objects:
+            objects.extend(ext.extra_objects)
+        extra_args = ext.extra_link_args or []
+        libraries = self.get_libraries(ext)[:]
+        library_dirs = ext.library_dirs[:]
+
+        linker = self.compiler.link_shared_object
+        # Always use system linker when using MSVC compiler.
+        if self.compiler.compiler_type in ('msvc', 'intelw', 'intelemw'):
+            # expand libraries with fcompiler libraries as we are
+            # not using fcompiler linker
+            self._libs_with_msvc_and_fortran(fcompiler, libraries, library_dirs)
+
+        elif ext.language in ['f77', 'f90'] and fcompiler is not None:
+            linker = fcompiler.link_shared_object
+        if ext.language=='c++' and cxx_compiler is not None:
+            linker = cxx_compiler.link_shared_object
+
+        linker(objects, ext_filename,
+               libraries=libraries,
+               library_dirs=library_dirs,
+               runtime_library_dirs=ext.runtime_library_dirs,
+               extra_postargs=extra_args,
+               export_symbols=self.get_export_symbols(ext),
+               debug=self.debug,
+               build_temp=self.build_temp,
+               target_lang=ext.language)
+
+    def _add_dummy_mingwex_sym(self, c_sources):
+        build_src = self.get_finalized_command("build_src").build_src
+        build_clib = self.get_finalized_command("build_clib").build_clib
+        objects = self.compiler.compile([os.path.join(build_src,
+                "gfortran_vs2003_hack.c")],
+                output_dir=self.build_temp)
+        self.compiler.create_static_lib(objects, "_gfortran_workaround", output_dir=build_clib, debug=self.debug)
+
+    def _libs_with_msvc_and_fortran(self, fcompiler, c_libraries,
+                                    c_library_dirs):
+        if fcompiler is None: return
+
+        for libname in c_libraries:
+            if libname.startswith('msvc'): continue
+            fileexists = False
+            for libdir in c_library_dirs or []:
+                libfile = os.path.join(libdir, '%s.lib' % (libname))
+                if os.path.isfile(libfile):
+                    fileexists = True
+                    break
+            if fileexists: continue
+            # make g77-compiled static libs available to MSVC
+            fileexists = False
+            for libdir in c_library_dirs:
+                libfile = os.path.join(libdir, 'lib%s.a' % (libname))
+                if os.path.isfile(libfile):
+                    # copy libname.a file to name.lib so that MSVC linker
+                    # can find it
+                    libfile2 = os.path.join(self.build_temp, libname + '.lib')
+                    copy_file(libfile, libfile2)
+                    if self.build_temp not in c_library_dirs:
+                        c_library_dirs.append(self.build_temp)
+                    fileexists = True
+                    break
+            if fileexists: continue
+            log.warn('could not find library %r in directories %s'
+                     % (libname, c_library_dirs))
+
+        # Always use system linker when using MSVC compiler.
+        f_lib_dirs = []
+        for dir in fcompiler.library_dirs:
+            # correct path when compiling in Cygwin but with normal Win
+            # Python
+            if dir.startswith('/usr/lib'):
+                s, o = exec_command(['cygpath', '-w', dir], use_tee=False)
+                if not s:
+                    dir = o
+            f_lib_dirs.append(dir)
+        c_library_dirs.extend(f_lib_dirs)
+
+        # make g77-compiled static libs available to MSVC
+        for lib in fcompiler.libraries:
+            if not lib.startswith('msvc'):
+                c_libraries.append(lib)
+                p = combine_paths(f_lib_dirs, 'lib' + lib + '.a')
+                if p:
+                    dst_name = os.path.join(self.build_temp, lib + '.lib')
+                    if not os.path.isfile(dst_name):
+                        copy_file(p[0], dst_name)
+                    if self.build_temp not in c_library_dirs:
+                        c_library_dirs.append(self.build_temp)
+
+    def get_source_files (self):
+        self.check_extensions_list(self.extensions)
+        filenames = []
+        for ext in self.extensions:
+            filenames.extend(get_ext_source_files(ext))
+        return filenames
+
+    def get_outputs (self):
+        self.check_extensions_list(self.extensions)
+
+        outputs = []
+        for ext in self.extensions:
+            if not ext.sources:
+                continue
+            fullname = self.get_ext_fullname(ext.name)
+            outputs.append(os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname)))
+        return outputs
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
new file mode 100644
index 0000000000..54dcde4350
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
@@ -0,0 +1,33 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.command.build_py import build_py as old_build_py
+from numpy.distutils.misc_util import is_string
+
+class build_py(old_build_py):
+
+    def run(self):
+        build_src = self.get_finalized_command('build_src')
+        if build_src.py_modules_dict and self.packages is None:
+            self.packages = list(build_src.py_modules_dict.keys ())
+        old_build_py.run(self)
+
+    def find_package_modules(self, package, package_dir):
+        modules = old_build_py.find_package_modules(self, package, package_dir)
+
+        # Find build_src generated *.py files.
+        build_src = self.get_finalized_command('build_src')
+        modules += build_src.py_modules_dict.get(package, [])
+
+        return modules
+
+    def find_modules(self):
+        old_py_modules = self.py_modules[:]
+        new_py_modules = [_m for _m in self.py_modules if is_string(_m)]
+        self.py_modules[:] = new_py_modules
+        modules = old_build_py.find_modules(self)
+        self.py_modules[:] = old_py_modules
+
+        return modules
+
+    # XXX: Fix find_source_files for item in py_modules such that item is 3-tuple
+    # and item[2] is source file.
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
new file mode 100644
index 0000000000..c8b25fc719
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
@@ -0,0 +1,51 @@
+""" Modified version of build_scripts that handles building scripts from functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from distutils.command.build_scripts import build_scripts as old_build_scripts
+from numpy.distutils import log
+from numpy.distutils.misc_util import is_string
+
+class build_scripts(old_build_scripts):
+
+    def generate_scripts(self, scripts):
+        new_scripts = []
+        func_scripts = []
+        for script in scripts:
+            if is_string(script):
+                new_scripts.append(script)
+            else:
+                func_scripts.append(script)
+        if not func_scripts:
+            return new_scripts
+
+        build_dir = self.build_dir
+        self.mkpath(build_dir)
+        for func in func_scripts:
+            script = func(build_dir)
+            if not script:
+                continue
+            if is_string(script):
+                log.info("  adding '%s' to scripts" % (script,))
+                new_scripts.append(script)
+            else:
+                [log.info("  adding '%s' to scripts" % (s,)) for s in script]
+                new_scripts.extend(list(script))
+        return new_scripts
+
+    def run (self):
+        if not self.scripts:
+            return
+
+        self.scripts = self.generate_scripts(self.scripts)
+        # Now make sure that the distribution object has this list of scripts.
+        # setuptools' develop command requires that this be a list of filenames,
+        # not functions.
+        self.distribution.scripts = self.scripts
+
+        return old_build_scripts.run(self)
+
+    def get_source_files(self):
+        from numpy.distutils.misc_util import get_script_files
+        return get_script_files(self.scripts)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
new file mode 100644
index 0000000000..2efcdea60c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
@@ -0,0 +1,775 @@
+""" Build swig and f2py sources.
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import shlex
+import copy
+
+from distutils.command import build_ext
+from distutils.dep_util import newer_group, newer
+from distutils.util import get_platform
+from distutils.errors import DistutilsError, DistutilsSetupError
+
+
+# this import can't be done here, as it uses numpy stuff only available
+# after it's installed
+#import numpy.f2py
+from numpy.distutils import log
+from numpy.distutils.misc_util import fortran_ext_match, \
+     appendpath, is_string, is_sequence, get_cmd
+from numpy.distutils.from_template import process_file as process_f_file
+from numpy.distutils.conv_template import process_file as process_c_file
+
+def subst_vars(target, source, d):
+    """Substitute any occurence of @foo@ by d['foo'] from source file into
+    target."""
+    var = re.compile('@([a-zA-Z_]+)@')
+    fs = open(source, 'r')
+    try:
+        ft = open(target, 'w')
+        try:
+            for l in fs:
+                m = var.search(l)
+                if m:
+                    ft.write(l.replace('@%s@' % m.group(1), d[m.group(1)]))
+                else:
+                    ft.write(l)
+        finally:
+            ft.close()
+    finally:
+        fs.close()
+
+class build_src(build_ext.build_ext):
+
+    description = "build sources from SWIG, F2PY files or a function"
+
+    user_options = [
+        ('build-src=', 'd', "directory to \"build\" sources to"),
+        ('f2py-opts=', None, "list of f2py command line options"),
+        ('swig=', None, "path to the SWIG executable"),
+        ('swig-opts=', None, "list of SWIG command line options"),
+        ('swig-cpp', None, "make SWIG create C++ files (default is autodetected from sources)"),
+        ('f2pyflags=', None, "additional flags to f2py (use --f2py-opts= instead)"), # obsolete
+        ('swigflags=', None, "additional flags to swig (use --swig-opts= instead)"), # obsolete
+        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+        ('inplace', 'i',
+         "ignore build-lib and put compiled extensions into the source " +
+         "directory alongside your pure Python modules"),
+        ]
+
+    boolean_options = ['force', 'inplace']
+
+    help_options = []
+
+    def initialize_options(self):
+        self.extensions = None
+        self.package = None
+        self.py_modules = None
+        self.py_modules_dict = None
+        self.build_src = None
+        self.build_lib = None
+        self.build_base = None
+        self.force = None
+        self.inplace = None
+        self.package_dir = None
+        self.f2pyflags = None # obsolete
+        self.f2py_opts = None
+        self.swigflags = None # obsolete
+        self.swig_opts = None
+        self.swig_cpp = None
+        self.swig = None
+
+    def finalize_options(self):
+        self.set_undefined_options('build',
+                                   ('build_base', 'build_base'),
+                                   ('build_lib', 'build_lib'),
+                                   ('force', 'force'))
+        if self.package is None:
+            self.package = self.distribution.ext_package
+        self.extensions = self.distribution.ext_modules
+        self.libraries = self.distribution.libraries or []
+        self.py_modules = self.distribution.py_modules or []
+        self.data_files = self.distribution.data_files or []
+
+        if self.build_src is None:
+            plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+            self.build_src = os.path.join(self.build_base, 'src'+plat_specifier)
+
+        # py_modules_dict is used in build_py.find_package_modules
+        self.py_modules_dict = {}
+
+        if self.f2pyflags:
+            if self.f2py_opts:
+                log.warn('ignoring --f2pyflags as --f2py-opts already used')
+            else:
+                self.f2py_opts = self.f2pyflags
+            self.f2pyflags = None
+        if self.f2py_opts is None:
+            self.f2py_opts = []
+        else:
+            self.f2py_opts = shlex.split(self.f2py_opts)
+
+        if self.swigflags:
+            if self.swig_opts:
+                log.warn('ignoring --swigflags as --swig-opts already used')
+            else:
+                self.swig_opts = self.swigflags
+            self.swigflags = None
+
+        if self.swig_opts is None:
+            self.swig_opts = []
+        else:
+            self.swig_opts = shlex.split(self.swig_opts)
+
+        # use options from build_ext command
+        build_ext = self.get_finalized_command('build_ext')
+        if self.inplace is None:
+            self.inplace = build_ext.inplace
+        if self.swig_cpp is None:
+            self.swig_cpp = build_ext.swig_cpp
+        for c in ['swig', 'swig_opt']:
+            o = '--'+c.replace('_', '-')
+            v = getattr(build_ext, c, None)
+            if v:
+                if getattr(self, c):
+                    log.warn('both build_src and build_ext define %s option' % (o))
+                else:
+                    log.info('using "%s=%s" option from build_ext command' % (o, v))
+                    setattr(self, c, v)
+
+    def run(self):
+        log.info("build_src")
+        if not (self.extensions or self.libraries):
+            return
+        self.build_sources()
+
+    def build_sources(self):
+
+        if self.inplace:
+            self.get_package_dir = \
+                     self.get_finalized_command('build_py').get_package_dir
+
+        self.build_py_modules_sources()
+
+        for libname_info in self.libraries:
+            self.build_library_sources(*libname_info)
+
+        if self.extensions:
+            self.check_extensions_list(self.extensions)
+
+            for ext in self.extensions:
+                self.build_extension_sources(ext)
+
+        self.build_data_files_sources()
+        self.build_npy_pkg_config()
+
+    def build_data_files_sources(self):
+        if not self.data_files:
+            return
+        log.info('building data_files sources')
+        from numpy.distutils.misc_util import get_data_files
+        new_data_files = []
+        for data in self.data_files:
+            if isinstance(data, str):
+                new_data_files.append(data)
+            elif isinstance(data, tuple):
+                d, files = data
+                if self.inplace:
+                    build_dir = self.get_package_dir('.'.join(d.split(os.sep)))
+                else:
+                    build_dir = os.path.join(self.build_src, d)
+                funcs = [f for f in files if hasattr(f, '__call__')]
+                files = [f for f in files if not hasattr(f, '__call__')]
+                for f in funcs:
+                    if f.__code__.co_argcount==1:
+                        s = f(build_dir)
+                    else:
+                        s = f()
+                    if s is not None:
+                        if isinstance(s, list):
+                            files.extend(s)
+                        elif isinstance(s, str):
+                            files.append(s)
+                        else:
+                            raise TypeError(repr(s))
+                filenames = get_data_files((d, files))
+                new_data_files.append((d, filenames))
+            else:
+                raise TypeError(repr(data))
+        self.data_files[:] = new_data_files
+
+
+    def _build_npy_pkg_config(self, info, gd):
+        import shutil
+        template, install_dir, subst_dict = info
+        template_dir = os.path.dirname(template)
+        for k, v in gd.items():
+            subst_dict[k] = v
+
+        if self.inplace == 1:
+            generated_dir = os.path.join(template_dir, install_dir)
+        else:
+            generated_dir = os.path.join(self.build_src, template_dir,
+                    install_dir)
+        generated = os.path.basename(os.path.splitext(template)[0])
+        generated_path = os.path.join(generated_dir, generated)
+        if not os.path.exists(generated_dir):
+            os.makedirs(generated_dir)
+
+        subst_vars(generated_path, template, subst_dict)
+
+        # Where to install relatively to install prefix
+        full_install_dir = os.path.join(template_dir, install_dir)
+        return full_install_dir, generated_path
+
+    def build_npy_pkg_config(self):
+        log.info('build_src: building npy-pkg config files')
+
+        # XXX: another ugly workaround to circumvent distutils brain damage. We
+        # need the install prefix here, but finalizing the options of the
+        # install command when only building sources cause error. Instead, we
+        # copy the install command instance, and finalize the copy so that it
+        # does not disrupt how distutils want to do things when with the
+        # original install command instance.
+        install_cmd = copy.copy(get_cmd('install'))
+        if not install_cmd.finalized == 1:
+            install_cmd.finalize_options()
+        build_npkg = False
+        gd = {}
+        if self.inplace == 1:
+            top_prefix = '.'
+            build_npkg = True
+        elif hasattr(install_cmd, 'install_libbase'):
+            top_prefix = install_cmd.install_libbase
+            build_npkg = True
+
+        if build_npkg:
+            for pkg, infos in self.distribution.installed_pkg_config.items():
+                pkg_path = self.distribution.package_dir[pkg]
+                prefix = os.path.join(os.path.abspath(top_prefix), pkg_path)
+                d = {'prefix': prefix}
+                for info in infos:
+                    install_dir, generated = self._build_npy_pkg_config(info, d)
+                    self.distribution.data_files.append((install_dir,
+                        [generated]))
+
+    def build_py_modules_sources(self):
+        if not self.py_modules:
+            return
+        log.info('building py_modules sources')
+        new_py_modules = []
+        for source in self.py_modules:
+            if is_sequence(source) and len(source)==3:
+                package, module_base, source = source
+                if self.inplace:
+                    build_dir = self.get_package_dir(package)
+                else:
+                    build_dir = os.path.join(self.build_src,
+                                             os.path.join(*package.split('.')))
+                if hasattr(source, '__call__'):
+                    target = os.path.join(build_dir, module_base + '.py')
+                    source = source(target)
+                if source is None:
+                    continue
+                modules = [(package, module_base, source)]
+                if package not in self.py_modules_dict:
+                    self.py_modules_dict[package] = []
+                self.py_modules_dict[package] += modules
+            else:
+                new_py_modules.append(source)
+        self.py_modules[:] = new_py_modules
+
+    def build_library_sources(self, lib_name, build_info):
+        sources = list(build_info.get('sources', []))
+
+        if not sources:
+            return
+
+        log.info('building library "%s" sources' % (lib_name))
+
+        sources = self.generate_sources(sources, (lib_name, build_info))
+
+        sources = self.template_sources(sources, (lib_name, build_info))
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     self.package, h_files)
+
+        #for f in h_files:
+        #    self.distribution.headers.append((lib_name,f))
+
+        build_info['sources'] = sources
+        return
+
+    def build_extension_sources(self, ext):
+
+        sources = list(ext.sources)
+
+        log.info('building extension "%s" sources' % (ext.name))
+
+        fullname = self.get_ext_fullname(ext.name)
+
+        modpath = fullname.split('.')
+        package = '.'.join(modpath[0:-1])
+
+        if self.inplace:
+            self.ext_target_dir = self.get_package_dir(package)
+
+        sources = self.generate_sources(sources, ext)
+        sources = self.template_sources(sources, ext)
+        sources = self.swig_sources(sources, ext)
+        sources = self.f2py_sources(sources, ext)
+        sources = self.pyrex_sources(sources, ext)
+
+        sources, py_files = self.filter_py_files(sources)
+
+        if package not in self.py_modules_dict:
+            self.py_modules_dict[package] = []
+        modules = []
+        for f in py_files:
+            module = os.path.splitext(os.path.basename(f))[0]
+            modules.append((package, module, f))
+        self.py_modules_dict[package] += modules
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     package, h_files)
+        #for f in h_files:
+        #    self.distribution.headers.append((package,f))
+
+        ext.sources = sources
+
+    def generate_sources(self, sources, extension):
+        new_sources = []
+        func_sources = []
+        for source in sources:
+            if is_string(source):
+                new_sources.append(source)
+            else:
+                func_sources.append(source)
+        if not func_sources:
+            return new_sources
+        if self.inplace and not is_sequence(extension):
+            build_dir = self.ext_target_dir
+        else:
+            if is_sequence(extension):
+                name = extension[0]
+            #    if 'include_dirs' not in extension[1]:
+            #        extension[1]['include_dirs'] = []
+            #    incl_dirs = extension[1]['include_dirs']
+            else:
+                name = extension.name
+            #    incl_dirs = extension.include_dirs
+            #if self.build_src not in incl_dirs:
+            #    incl_dirs.append(self.build_src)
+            build_dir = os.path.join(*([self.build_src]\
+                                       +name.split('.')[:-1]))
+        self.mkpath(build_dir)
+        for func in func_sources:
+            source = func(extension, build_dir)
+            if not source:
+                continue
+            if is_sequence(source):
+                [log.info("  adding '%s' to sources." % (s,)) for s in source]
+                new_sources.extend(source)
+            else:
+                log.info("  adding '%s' to sources." % (source,))
+                new_sources.append(source)
+
+        return new_sources
+
+    def filter_py_files(self, sources):
+        return self.filter_files(sources, ['.py'])
+
+    def filter_h_files(self, sources):
+        return self.filter_files(sources, ['.h', '.hpp', '.inc'])
+
+    def filter_files(self, sources, exts = []):
+        new_sources = []
+        files = []
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext in exts:
+                files.append(source)
+            else:
+                new_sources.append(source)
+        return new_sources, files
+
+    def template_sources(self, sources, extension):
+        new_sources = []
+        if is_sequence(extension):
+            depends = extension[1].get('depends')
+            include_dirs = extension[1].get('include_dirs')
+        else:
+            depends = extension.depends
+            include_dirs = extension.include_dirs
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.src':  # Template file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                self.mkpath(target_dir)
+                target_file = os.path.join(target_dir, os.path.basename(base))
+                if (self.force or newer_group([source] + depends, target_file)):
+                    if _f_pyf_ext_match(base):
+                        log.info("from_template:> %s" % (target_file))
+                        outstr = process_f_file(source)
+                    else:
+                        log.info("conv_template:> %s" % (target_file))
+                        outstr = process_c_file(source)
+                    fid = open(target_file, 'w')
+                    fid.write(outstr)
+                    fid.close()
+                if _header_ext_match(target_file):
+                    d = os.path.dirname(target_file)
+                    if d not in include_dirs:
+                        log.info("  adding '%s' to include_dirs." % (d))
+                        include_dirs.append(d)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def pyrex_sources(self, sources, extension):
+        """Pyrex not supported; this remains for Cython support (see below)"""
+        new_sources = []
+        ext_name = extension.name.split('.')[-1]
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyx':
+                target_file = self.generate_a_pyrex_source(base, ext_name,
+                                                           source,
+                                                           extension)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def generate_a_pyrex_source(self, base, ext_name, source, extension):
+        """Pyrex is not supported, but some projects monkeypatch this method.
+
+        That allows compiling Cython code, see gh-6955.
+        This method will remain here for compatibility reasons.
+        """
+        return []
+
+    def f2py_sources(self, sources, extension):
+        new_sources = []
+        f2py_sources = []
+        f_sources = []
+        f2py_targets = {}
+        target_dirs = []
+        ext_name = extension.name.split('.')[-1]
+        skip_f2py = 0
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyf': # F2PY interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                if os.path.isfile(source):
+                    name = get_f2py_modulename(source)
+                    if name != ext_name:
+                        raise DistutilsSetupError('mismatch of extension names: %s '
+                                                  'provides %r but expected %r' % (
+                            source, name, ext_name))
+                    target_file = os.path.join(target_dir, name+'module.c')
+                else:
+                    log.debug('  source %s does not exist: skipping f2py\'ing.' \
+                              % (source))
+                    name = ext_name
+                    skip_f2py = 1
+                    target_file = os.path.join(target_dir, name+'module.c')
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %smodule.c was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = os.path.join(target_dir, name+'module.c')
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.info('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                f2py_sources.append(source)
+                f2py_targets[source] = target_file
+                new_sources.append(target_file)
+            elif fortran_ext_match(ext):
+                f_sources.append(source)
+            else:
+                new_sources.append(source)
+
+        if not (f2py_sources or f_sources):
+            return new_sources
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        f2py_options = extension.f2py_options + self.f2py_opts
+
+        if self.distribution.libraries:
+            for name, build_info in self.distribution.libraries:
+                if name in extension.libraries:
+                    f2py_options.extend(build_info.get('f2py_options', []))
+
+        log.info("f2py options: %s" % (f2py_options))
+
+        if f2py_sources:
+            if len(f2py_sources) != 1:
+                raise DistutilsSetupError(
+                    'only one .pyf file is allowed per extension module but got'\
+                    ' more: %r' % (f2py_sources,))
+            source = f2py_sources[0]
+            target_file = f2py_targets[source]
+            target_dir = os.path.dirname(target_file) or '.'
+            depends = [source] + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py: %s" % (source))
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options
+                                    + ['--build-dir', target_dir, source])
+            else:
+                log.debug("  skipping '%s' f2py interface (up-to-date)" % (source))
+        else:
+            #XXX TODO: --inplace support for sdist command
+            if is_sequence(extension):
+                name = extension[0]
+            else: name = extension.name
+            target_dir = os.path.join(*([self.build_src]\
+                                        +name.split('.')[:-1]))
+            target_file = os.path.join(target_dir, ext_name + 'module.c')
+            new_sources.append(target_file)
+            depends = f_sources + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py:> %s" % (target_file))
+                self.mkpath(target_dir)
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options + ['--lower',
+                                                '--build-dir', target_dir]+\
+                                ['-m', ext_name]+f_sources)
+            else:
+                log.debug("  skipping f2py fortran files for '%s' (up-to-date)"\
+                          % (target_file))
+
+        if not os.path.isfile(target_file):
+            raise DistutilsError("f2py target file %r not generated" % (target_file,))
+
+        target_c = os.path.join(self.build_src, 'fortranobject.c')
+        target_h = os.path.join(self.build_src, 'fortranobject.h')
+        log.info("  adding '%s' to sources." % (target_c))
+        new_sources.append(target_c)
+        if self.build_src not in extension.include_dirs:
+            log.info("  adding '%s' to include_dirs." \
+                     % (self.build_src))
+            extension.include_dirs.append(self.build_src)
+
+        if not skip_f2py:
+            import numpy.f2py
+            d = os.path.dirname(numpy.f2py.__file__)
+            source_c = os.path.join(d, 'src', 'fortranobject.c')
+            source_h = os.path.join(d, 'src', 'fortranobject.h')
+            if newer(source_c, target_c) or newer(source_h, target_h):
+                self.mkpath(os.path.dirname(target_c))
+                self.copy_file(source_c, target_c)
+                self.copy_file(source_h, target_h)
+        else:
+            if not os.path.isfile(target_c):
+                raise DistutilsSetupError("f2py target_c file %r not found" % (target_c,))
+            if not os.path.isfile(target_h):
+                raise DistutilsSetupError("f2py target_h file %r not found" % (target_h,))
+
+        for name_ext in ['-f2pywrappers.f', '-f2pywrappers2.f90']:
+            filename = os.path.join(target_dir, ext_name + name_ext)
+            if os.path.isfile(filename):
+                log.info("  adding '%s' to sources." % (filename))
+                f_sources.append(filename)
+
+        return new_sources + f_sources
+
+    def swig_sources(self, sources, extension):
+        # Assuming SWIG 1.3.14 or later. See compatibility note in
+        #   http://www.swig.org/Doc1.3/Python.html#Python_nn6
+
+        new_sources = []
+        swig_sources = []
+        swig_targets = {}
+        target_dirs = []
+        py_files = []     # swig generated .py files
+        target_ext = '.c'
+        if '-c++' in extension.swig_opts:
+            typ = 'c++'
+            is_cpp = True
+            extension.swig_opts.remove('-c++')
+        elif self.swig_cpp:
+            typ = 'c++'
+            is_cpp = True
+        else:
+            typ = None
+            is_cpp = False
+        skip_swig = 0
+        ext_name = extension.name.split('.')[-1]
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.i': # SWIG interface file
+                # the code below assumes that the sources list
+                # contains not more than one .i SWIG interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                    py_target_dir = self.ext_target_dir
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                    py_target_dir = target_dir
+                if os.path.isfile(source):
+                    name = get_swig_modulename(source)
+                    if name != ext_name[1:]:
+                        raise DistutilsSetupError(
+                            'mismatch of extension names: %s provides %r'
+                            ' but expected %r' % (source, name, ext_name[1:]))
+                    if typ is None:
+                        typ = get_swig_target(source)
+                        is_cpp = typ=='c++'
+                    else:
+                        typ2 = get_swig_target(source)
+                        if typ2 is None:
+                            log.warn('source %r does not define swig target, assuming %s swig target' \
+                                     % (source, typ))
+                        elif typ!=typ2:
+                            log.warn('expected %r but source %r defines %r swig target' \
+                                     % (typ, source, typ2))
+                            if typ2=='c++':
+                                log.warn('resetting swig target to c++ (some targets may have .c extension)')
+                                is_cpp = True
+                            else:
+                                log.warn('assuming that %r has c++ swig target' % (source))
+                    if is_cpp:
+                        target_ext = '.cpp'
+                    target_file = os.path.join(target_dir, '%s_wrap%s' \
+                                               % (name, target_ext))
+                else:
+                    log.warn('  source %s does not exist: skipping swig\'ing.' \
+                             % (source))
+                    name = ext_name[1:]
+                    skip_swig = 1
+                    target_file = _find_swig_target(target_dir, name)
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %s_wrap.{c,cpp} was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = _find_swig_target(target_dir, name)
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.warn('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                new_sources.append(target_file)
+                py_files.append(os.path.join(py_target_dir, name+'.py'))
+                swig_sources.append(source)
+                swig_targets[source] = new_sources[-1]
+            else:
+                new_sources.append(source)
+
+        if not swig_sources:
+            return new_sources
+
+        if skip_swig:
+            return new_sources + py_files
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        swig = self.swig or self.find_swig()
+        swig_cmd = [swig, "-python"] + extension.swig_opts
+        if is_cpp:
+            swig_cmd.append('-c++')
+        for d in extension.include_dirs:
+            swig_cmd.append('-I'+d)
+        for source in swig_sources:
+            target = swig_targets[source]
+            depends = [source] + extension.depends
+            if self.force or newer_group(depends, target, 'newer'):
+                log.info("%s: %s" % (os.path.basename(swig) \
+                                     + (is_cpp and '++' or ''), source))
+                self.spawn(swig_cmd + self.swig_opts \
+                           + ["-o", target, '-outdir', py_target_dir, source])
+            else:
+                log.debug("  skipping '%s' swig interface (up-to-date)" \
+                         % (source))
+
+        return new_sources + py_files
+
+_f_pyf_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+_header_ext_match = re.compile(r'.*[.](inc|h|hpp)\Z', re.I).match
+
+#### SWIG related auxiliary functions ####
+_swig_module_name_match = re.compile(r'\s*%module\s*(.*\(\s*package\s*=\s*"(?P<package>[\w_]+)".*\)|)\s*(?P<name>[\w_]+)',
+                                     re.I).match
+_has_c_header = re.compile(r'-[*]-\s*c\s*-[*]-', re.I).search
+_has_cpp_header = re.compile(r'-[*]-\s*c[+][+]\s*-[*]-', re.I).search
+
+def get_swig_target(source):
+    f = open(source, 'r')
+    result = None
+    line = f.readline()
+    if _has_cpp_header(line):
+        result = 'c++'
+    if _has_c_header(line):
+        result = 'c'
+    f.close()
+    return result
+
+def get_swig_modulename(source):
+    f = open(source, 'r')
+    name = None
+    for line in f:
+        m = _swig_module_name_match(line)
+        if m:
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+def _find_swig_target(target_dir, name):
+    for ext in ['.cpp', '.c']:
+        target = os.path.join(target_dir, '%s_wrap%s' % (name, ext))
+        if os.path.isfile(target):
+            break
+    return target
+
+#### F2PY related auxiliary functions ####
+
+_f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]+)',
+                                re.I).match
+_f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]*?'\
+                                     '__user__[\w_]*)', re.I).match
+
+def get_f2py_modulename(source):
+    name = None
+    f = open(source)
+    for line in f:
+        m = _f2py_module_name_match(line)
+        if m:
+            if _f2py_user_module_name_match(line): # skip *__user__* names
+                continue
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+##########################################
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.py
new file mode 100644
index 0000000000..4f20fc0de1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.py
@@ -0,0 +1,437 @@
+# Added Fortran compiler support to config. Currently useful only for
+# try_compile call. try_run works but is untested for most of Fortran
+# compilers (they must define linker_exe first).
+# Pearu Peterson
+from __future__ import division, absolute_import, print_function
+
+import os, signal
+import warnings
+import sys
+
+from distutils.command.config import config as old_config
+from distutils.command.config import LANG_EXT
+from distutils import log
+from distutils.file_util import copy_file
+from distutils.ccompiler import CompileError, LinkError
+import distutils
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.mingw32ccompiler import generate_manifest
+from numpy.distutils.command.autodist import (check_gcc_function_attribute,
+                                              check_gcc_variable_attribute,
+                                              check_inline,
+                                              check_restrict,
+                                              check_compiler_gcc4)
+from numpy.distutils.compat import get_exception
+
+LANG_EXT['f77'] = '.f'
+LANG_EXT['f90'] = '.f90'
+
+class config(old_config):
+    old_config.user_options += [
+        ('fcompiler=', None, "specify the Fortran compiler type"),
+        ]
+
+    def initialize_options(self):
+        self.fcompiler = None
+        old_config.initialize_options(self)
+
+    def _check_compiler (self):
+        old_config._check_compiler(self)
+        from numpy.distutils.fcompiler import FCompiler, new_fcompiler
+
+        if sys.platform == 'win32' and (self.compiler.compiler_type in
+                                        ('msvc', 'intelw', 'intelemw')):
+            # XXX: hack to circumvent a python 2.6 bug with msvc9compiler:
+            # initialize call query_vcvarsall, which throws an IOError, and
+            # causes an error along the way without much information. We try to
+            # catch it here, hoping it is early enough, and print an helpful
+            # message instead of Error: None.
+            if not self.compiler.initialized:
+                try:
+                    self.compiler.initialize()
+                except IOError:
+                    e = get_exception()
+                    msg = """\
+Could not initialize compiler instance: do you have Visual Studio
+installed?  If you are trying to build with MinGW, please use "python setup.py
+build -c mingw32" instead.  If you have Visual Studio installed, check it is
+correctly installed, and the right version (VS 2008 for python 2.6, 2.7 and 3.2,
+VS 2010 for >= 3.3).
+
+Original exception was: %s, and the Compiler class was %s
+============================================================================""" \
+                        % (e, self.compiler.__class__.__name__)
+                    print ("""\
+============================================================================""")
+                    raise distutils.errors.DistutilsPlatformError(msg)
+
+            # After MSVC is initialized, add an explicit /MANIFEST to linker
+            # flags.  See issues gh-4245 and gh-4101 for details.  Also
+            # relevant are issues 4431 and 16296 on the Python bug tracker.
+            from distutils import msvc9compiler
+            if msvc9compiler.get_build_version() >= 10:
+                for ldflags in [self.compiler.ldflags_shared,
+                                self.compiler.ldflags_shared_debug]:
+                    if '/MANIFEST' not in ldflags:
+                        ldflags.append('/MANIFEST')
+
+        if not isinstance(self.fcompiler, FCompiler):
+            self.fcompiler = new_fcompiler(compiler=self.fcompiler,
+                                           dry_run=self.dry_run, force=1,
+                                           c_compiler=self.compiler)
+            if self.fcompiler is not None:
+                self.fcompiler.customize(self.distribution)
+                if self.fcompiler.get_version():
+                    self.fcompiler.customize_cmd(self)
+                    self.fcompiler.show_customization()
+
+    def _wrap_method(self, mth, lang, args):
+        from distutils.ccompiler import CompileError
+        from distutils.errors import DistutilsExecError
+        save_compiler = self.compiler
+        if lang in ['f77', 'f90']:
+            self.compiler = self.fcompiler
+        try:
+            ret = mth(*((self,)+args))
+        except (DistutilsExecError, CompileError):
+            msg = str(get_exception())
+            self.compiler = save_compiler
+            raise CompileError
+        self.compiler = save_compiler
+        return ret
+
+    def _compile (self, body, headers, include_dirs, lang):
+        return self._wrap_method(old_config._compile, lang,
+                                 (body, headers, include_dirs, lang))
+
+    def _link (self, body,
+               headers, include_dirs,
+               libraries, library_dirs, lang):
+        if self.compiler.compiler_type=='msvc':
+            libraries = (libraries or [])[:]
+            library_dirs = (library_dirs or [])[:]
+            if lang in ['f77', 'f90']:
+                lang = 'c' # always use system linker when using MSVC compiler
+                if self.fcompiler:
+                    for d in self.fcompiler.library_dirs or []:
+                        # correct path when compiling in Cygwin but with
+                        # normal Win Python
+                        if d.startswith('/usr/lib'):
+                            s, o = exec_command(['cygpath', '-w', d],
+                                               use_tee=False)
+                            if not s: d = o
+                        library_dirs.append(d)
+                    for libname in self.fcompiler.libraries or []:
+                        if libname not in libraries:
+                            libraries.append(libname)
+            for libname in libraries:
+                if libname.startswith('msvc'): continue
+                fileexists = False
+                for libdir in library_dirs or []:
+                    libfile = os.path.join(libdir, '%s.lib' % (libname))
+                    if os.path.isfile(libfile):
+                        fileexists = True
+                        break
+                if fileexists: continue
+                # make g77-compiled static libs available to MSVC
+                fileexists = False
+                for libdir in library_dirs:
+                    libfile = os.path.join(libdir, 'lib%s.a' % (libname))
+                    if os.path.isfile(libfile):
+                        # copy libname.a file to name.lib so that MSVC linker
+                        # can find it
+                        libfile2 = os.path.join(libdir, '%s.lib' % (libname))
+                        copy_file(libfile, libfile2)
+                        self.temp_files.append(libfile2)
+                        fileexists = True
+                        break
+                if fileexists: continue
+                log.warn('could not find library %r in directories %s' \
+                         % (libname, library_dirs))
+        elif self.compiler.compiler_type == 'mingw32':
+            generate_manifest(self)
+        return self._wrap_method(old_config._link, lang,
+                                 (body, headers, include_dirs,
+                                  libraries, library_dirs, lang))
+
+    def check_header(self, header, include_dirs=None, library_dirs=None, lang='c'):
+        self._check_compiler()
+        return self.try_compile(
+                "/* we need a dummy line to make distutils happy */",
+                [header], include_dirs)
+
+    def check_decl(self, symbol,
+                   headers=None, include_dirs=None):
+        self._check_compiler()
+        body = """
+int main(void)
+{
+#ifndef %s
+    (void) %s;
+#endif
+    ;
+    return 0;
+}""" % (symbol, symbol)
+
+        return self.try_compile(body, headers, include_dirs)
+
+    def check_macro_true(self, symbol,
+                         headers=None, include_dirs=None):
+        self._check_compiler()
+        body = """
+int main(void)
+{
+#if %s
+#else
+#error false or undefined macro
+#endif
+    ;
+    return 0;
+}""" % (symbol,)
+
+        return self.try_compile(body, headers, include_dirs)
+
+    def check_type(self, type_name, headers=None, include_dirs=None,
+            library_dirs=None):
+        """Check type availability. Return True if the type can be compiled,
+        False otherwise"""
+        self._check_compiler()
+
+        # First check the type can be compiled
+        body = r"""
+int main(void) {
+  if ((%(name)s *) 0)
+    return 0;
+  if (sizeof (%(name)s))
+    return 0;
+}
+""" % {'name': type_name}
+
+        st = False
+        try:
+            try:
+                self._compile(body % {'type': type_name},
+                        headers, include_dirs, 'c')
+                st = True
+            except distutils.errors.CompileError:
+                st = False
+        finally:
+            self._clean()
+
+        return st
+
+    def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None, expected=None):
+        """Check size of a given type."""
+        self._check_compiler()
+
+        # First check the type can be compiled
+        body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+        self._compile(body % {'type': type_name},
+                headers, include_dirs, 'c')
+        self._clean()
+
+        if expected:
+            body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) == %(size)s)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+            for size in expected:
+                try:
+                    self._compile(body % {'type': type_name, 'size': size},
+                            headers, include_dirs, 'c')
+                    self._clean()
+                    return size
+                except CompileError:
+                    pass
+
+        # this fails to *compile* if size > sizeof(type)
+        body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+
+        # The principle is simple: we first find low and high bounds of size
+        # for the type, where low/high are looked up on a log scale. Then, we
+        # do a binary search to find the exact size between low and high
+        low = 0
+        mid = 0
+        while True:
+            try:
+                self._compile(body % {'type': type_name, 'size': mid},
+                        headers, include_dirs, 'c')
+                self._clean()
+                break
+            except CompileError:
+                #log.info("failure to test for bound %d" % mid)
+                low = mid + 1
+                mid = 2 * mid + 1
+
+        high = mid
+        # Binary search:
+        while low != high:
+            mid = (high - low) // 2 + low
+            try:
+                self._compile(body % {'type': type_name, 'size': mid},
+                        headers, include_dirs, 'c')
+                self._clean()
+                high = mid
+            except CompileError:
+                low = mid + 1
+        return low
+
+    def check_func(self, func,
+                   headers=None, include_dirs=None,
+                   libraries=None, library_dirs=None,
+                   decl=False, call=False, call_args=None):
+        # clean up distutils's config a bit: add void to main(), and
+        # return a value.
+        self._check_compiler()
+        body = []
+        if decl:
+            if type(decl) == str:
+                body.append(decl)
+            else:
+                body.append("int %s (void);" % func)
+        # Handle MSVC intrinsics: force MS compiler to make a function call.
+        # Useful to test for some functions when built with optimization on, to
+        # avoid build error because the intrinsic and our 'fake' test
+        # declaration do not match.
+        body.append("#ifdef _MSC_VER")
+        body.append("#pragma function(%s)" % func)
+        body.append("#endif")
+        body.append("int main (void) {")
+        if call:
+            if call_args is None:
+                call_args = ''
+            body.append("  %s(%s);" % (func, call_args))
+        else:
+            body.append("  %s;" % func)
+        body.append("  return 0;")
+        body.append("}")
+        body = '\n'.join(body) + "\n"
+
+        return self.try_link(body, headers, include_dirs,
+                             libraries, library_dirs)
+
+    def check_funcs_once(self, funcs,
+                   headers=None, include_dirs=None,
+                   libraries=None, library_dirs=None,
+                   decl=False, call=False, call_args=None):
+        """Check a list of functions at once.
+
+        This is useful to speed up things, since all the functions in the funcs
+        list will be put in one compilation unit.
+
+        Arguments
+        ---------
+        funcs : seq
+            list of functions to test
+        include_dirs : seq
+            list of header paths
+        libraries : seq
+            list of libraries to link the code snippet to
+        libraru_dirs : seq
+            list of library paths
+        decl : dict
+            for every (key, value), the declaration in the value will be
+            used for function in key. If a function is not in the
+            dictionay, no declaration will be used.
+        call : dict
+            for every item (f, value), if the value is True, a call will be
+            done to the function f.
+        """
+        self._check_compiler()
+        body = []
+        if decl:
+            for f, v in decl.items():
+                if v:
+                    body.append("int %s (void);" % f)
+
+        # Handle MS intrinsics. See check_func for more info.
+        body.append("#ifdef _MSC_VER")
+        for func in funcs:
+            body.append("#pragma function(%s)" % func)
+        body.append("#endif")
+
+        body.append("int main (void) {")
+        if call:
+            for f in funcs:
+                if f in call and call[f]:
+                    if not (call_args and f in call_args and call_args[f]):
+                        args = ''
+                    else:
+                        args = call_args[f]
+                    body.append("  %s(%s);" % (f, args))
+                else:
+                    body.append("  %s;" % f)
+        else:
+            for f in funcs:
+                body.append("  %s;" % f)
+        body.append("  return 0;")
+        body.append("}")
+        body = '\n'.join(body) + "\n"
+
+        return self.try_link(body, headers, include_dirs,
+                             libraries, library_dirs)
+
+    def check_inline(self):
+        """Return the inline keyword recognized by the compiler, empty string
+        otherwise."""
+        return check_inline(self)
+
+    def check_restrict(self):
+        """Return the restrict keyword recognized by the compiler, empty string
+        otherwise."""
+        return check_restrict(self)
+
+    def check_compiler_gcc4(self):
+        """Return True if the C compiler is gcc >= 4."""
+        return check_compiler_gcc4(self)
+
+    def check_gcc_function_attribute(self, attribute, name):
+        return check_gcc_function_attribute(self, attribute, name)
+
+    def check_gcc_variable_attribute(self, attribute):
+        return check_gcc_variable_attribute(self, attribute)
+
+
+class GrabStdout(object):
+
+    def __init__(self):
+        self.sys_stdout = sys.stdout
+        self.data = ''
+        sys.stdout = self
+
+    def write (self, data):
+        self.sys_stdout.write(data)
+        self.data += data
+
+    def flush (self):
+        self.sys_stdout.flush()
+
+    def restore(self):
+        sys.stdout = self.sys_stdout
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
new file mode 100644
index 0000000000..5e638feccc
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
@@ -0,0 +1,125 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.core import Command
+from numpy.distutils import log
+
+#XXX: Linker flags
+
+def show_fortran_compilers(_cache=[]):
+    # Using cache to prevent infinite recursion
+    if _cache: return
+    _cache.append(1)
+    from numpy.distutils.fcompiler import show_fcompilers
+    import distutils.core
+    dist = distutils.core._setup_distribution
+    show_fcompilers(dist)
+
+class config_fc(Command):
+    """ Distutils command to hold user specified options
+    to Fortran compilers.
+
+    config_fc command is used by the FCompiler.customize() method.
+    """
+
+    description = "specify Fortran 77/Fortran 90 compiler information"
+
+    user_options = [
+        ('fcompiler=', None, "specify Fortran compiler type"),
+        ('f77exec=', None, "specify F77 compiler command"),
+        ('f90exec=', None, "specify F90 compiler command"),
+        ('f77flags=', None, "specify F77 compiler flags"),
+        ('f90flags=', None, "specify F90 compiler flags"),
+        ('opt=', None, "specify optimization flags"),
+        ('arch=', None, "specify architecture specific optimization flags"),
+        ('debug', 'g', "compile with debugging information"),
+        ('noopt', None, "compile without optimization"),
+        ('noarch', None, "compile without arch-dependent optimization"),
+        ]
+
+    help_options = [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    boolean_options = ['debug', 'noopt', 'noarch']
+
+    def initialize_options(self):
+        self.fcompiler = None
+        self.f77exec = None
+        self.f90exec = None
+        self.f77flags = None
+        self.f90flags = None
+        self.opt = None
+        self.arch = None
+        self.debug = None
+        self.noopt = None
+        self.noarch = None
+
+    def finalize_options(self):
+        log.info('unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options')
+        build_clib = self.get_finalized_command('build_clib')
+        build_ext = self.get_finalized_command('build_ext')
+        config = self.get_finalized_command('config')
+        build = self.get_finalized_command('build')
+        cmd_list = [self, config, build_clib, build_ext, build]
+        for a in ['fcompiler']:
+            l = []
+            for c in cmd_list:
+                v = getattr(c, a)
+                if v is not None:
+                    if not isinstance(v, str): v = v.compiler_type
+                    if v not in l: l.append(v)
+            if not l: v1 = None
+            else: v1 = l[0]
+            if len(l)>1:
+                log.warn('  commands have different --%s options: %s'\
+                         ', using first in list as default' % (a, l))
+            if v1:
+                for c in cmd_list:
+                    if getattr(c, a) is None: setattr(c, a, v1)
+
+    def run(self):
+        # Do nothing.
+        return
+
+class config_cc(Command):
+    """ Distutils command to hold user specified options
+    to C/C++ compilers.
+    """
+
+    description = "specify C/C++ compiler information"
+
+    user_options = [
+        ('compiler=', None, "specify C/C++ compiler type"),
+        ]
+
+    def initialize_options(self):
+        self.compiler = None
+
+    def finalize_options(self):
+        log.info('unifing config_cc, config, build_clib, build_ext, build commands --compiler options')
+        build_clib = self.get_finalized_command('build_clib')
+        build_ext = self.get_finalized_command('build_ext')
+        config = self.get_finalized_command('config')
+        build = self.get_finalized_command('build')
+        cmd_list = [self, config, build_clib, build_ext, build]
+        for a in ['compiler']:
+            l = []
+            for c in cmd_list:
+                v = getattr(c, a)
+                if v is not None:
+                    if not isinstance(v, str): v = v.compiler_type
+                    if v not in l: l.append(v)
+            if not l: v1 = None
+            else: v1 = l[0]
+            if len(l)>1:
+                log.warn('  commands have different --%s options: %s'\
+                         ', using first in list as default' % (a, l))
+            if v1:
+                for c in cmd_list:
+                    if getattr(c, a) is None: setattr(c, a, v1)
+        return
+
+    def run(self):
+        # Do nothing.
+        return
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.py
new file mode 100644
index 0000000000..1410ab2a00
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.py
@@ -0,0 +1,17 @@
+""" Override the develop command from setuptools so we can ensure that our
+generated files (from build_src or build_scripts) are properly converted to real
+files with filenames.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from setuptools.command.develop import develop as old_develop
+
+class develop(old_develop):
+    __doc__ = old_develop.__doc__
+    def install_for_development(self):
+        # Build sources in-place, too.
+        self.reinitialize_command('build_src', inplace=1)
+        # Make sure scripts are built.
+        self.run_command('build_scripts')
+        old_develop.install_for_development(self)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
new file mode 100644
index 0000000000..972a27df38
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
@@ -0,0 +1,19 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from setuptools.command.egg_info import egg_info as _egg_info
+
+class egg_info(_egg_info):
+    def run(self):
+        if 'sdist' in sys.argv:
+            import warnings
+            warnings.warn("`build_src` is being run, this may lead to missing "
+                          "files in your sdist!  See numpy issue gh-7127 for "
+                          "details", UserWarning)
+
+        # We need to ensure that build_src has been executed in order to give
+        # setuptools' egg_info command real filenames instead of functions which
+        # generate files.
+        self.run_command("build_src")
+        _egg_info.run(self)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.py
new file mode 100644
index 0000000000..a1dd47755c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.py
@@ -0,0 +1,82 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+if 'setuptools' in sys.modules:
+    import setuptools.command.install as old_install_mod
+    have_setuptools = True
+else:
+    import distutils.command.install as old_install_mod
+    have_setuptools = False
+from distutils.file_util import write_file
+
+old_install = old_install_mod.install
+
+class install(old_install):
+
+    # Always run install_clib - the command is cheap, so no need to bypass it;
+    # but it's not run by setuptools -- so it's run again in install_data
+    sub_commands = old_install.sub_commands + [
+        ('install_clib', lambda x: True)
+    ]
+
+    def finalize_options (self):
+        old_install.finalize_options(self)
+        self.install_lib = self.install_libbase
+
+    def setuptools_run(self):
+        """ The setuptools version of the .run() method.
+
+        We must pull in the entire code so we can override the level used in the
+        _getframe() call since we wrap this call by one more level.
+        """
+        from distutils.command.install import install as distutils_install
+
+        # Explicit request for old-style install?  Just do it
+        if self.old_and_unmanageable or self.single_version_externally_managed:
+            return distutils_install.run(self)
+
+        # Attempt to detect whether we were called from setup() or by another
+        # command.  If we were called by setup(), our caller will be the
+        # 'run_command' method in 'distutils.dist', and *its* caller will be
+        # the 'run_commands' method.  If we were called any other way, our
+        # immediate caller *might* be 'run_command', but it won't have been
+        # called by 'run_commands'.  This is slightly kludgy, but seems to
+        # work.
+        #
+        caller = sys._getframe(3)
+        caller_module = caller.f_globals.get('__name__', '')
+        caller_name = caller.f_code.co_name
+
+        if caller_module != 'distutils.dist' or caller_name!='run_commands':
+            # We weren't called from the command line or setup(), so we
+            # should run in backward-compatibility mode to support bdist_*
+            # commands.
+            distutils_install.run(self)
+        else:
+            self.do_egg_install()
+
+    def run(self):
+        if not have_setuptools:
+            r = old_install.run(self)
+        else:
+            r = self.setuptools_run()
+        if self.record:
+            # bdist_rpm fails when INSTALLED_FILES contains
+            # paths with spaces. Such paths must be enclosed
+            # with double-quotes.
+            f = open(self.record, 'r')
+            lines = []
+            need_rewrite = False
+            for l in f:
+                l = l.rstrip()
+                if ' ' in l:
+                    need_rewrite = True
+                    l = '"%s"' % (l)
+                lines.append(l)
+            f.close()
+            if need_rewrite:
+                self.execute(write_file,
+                             (self.record, lines),
+                             "re-writing list of installed files to '%s'" %
+                             self.record)
+        return r
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
new file mode 100644
index 0000000000..662aa00bda
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
@@ -0,0 +1,39 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.core import Command
+from distutils.ccompiler import new_compiler
+from numpy.distutils.misc_util import get_cmd
+
+class install_clib(Command):
+    description = "Command to install installable C libraries"
+
+    user_options = []
+
+    def initialize_options(self):
+        self.install_dir = None
+        self.outfiles = []
+
+    def finalize_options(self):
+        self.set_undefined_options('install', ('install_lib', 'install_dir'))
+
+    def run (self):
+        build_clib_cmd = get_cmd("build_clib")
+        build_dir = build_clib_cmd.build_clib
+
+        # We need the compiler to get the library name -> filename association
+        if not build_clib_cmd.compiler:
+            compiler = new_compiler(compiler=None)
+            compiler.customize(self.distribution)
+        else:
+            compiler = build_clib_cmd.compiler
+
+        for l in self.distribution.installed_libraries:
+            target_dir = os.path.join(self.install_dir, l.target_dir)
+            name = compiler.library_filename(l.name)
+            source = os.path.join(build_dir, name)
+            self.mkpath(target_dir)
+            self.outfiles.append(self.copy_file(source, target_dir)[0])
+
+    def get_outputs(self):
+        return self.outfiles
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
new file mode 100644
index 0000000000..996cf7e401
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
@@ -0,0 +1,26 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+have_setuptools = ('setuptools' in sys.modules)
+
+from distutils.command.install_data import install_data as old_install_data
+
+#data installer with improved intelligence over distutils
+#data files are copied into the project directory instead
+#of willy-nilly
+class install_data (old_install_data):
+
+    def run(self):
+        old_install_data.run(self)
+
+        if have_setuptools:
+            # Run install_clib again, since setuptools does not run sub-commands
+            # of install automatically
+            self.run_command('install_clib')
+
+    def finalize_options (self):
+        self.set_undefined_options('install',
+                                   ('install_lib', 'install_dir'),
+                                   ('root', 'root'),
+                                   ('force', 'force'),
+                                  )
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
new file mode 100644
index 0000000000..f3f58aa287
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
@@ -0,0 +1,27 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.command.install_headers import install_headers as old_install_headers
+
+class install_headers (old_install_headers):
+
+    def run (self):
+        headers = self.distribution.headers
+        if not headers:
+            return
+
+        prefix = os.path.dirname(self.install_dir)
+        for header in headers:
+            if isinstance(header, tuple):
+                # Kind of a hack, but I don't know where else to change this...
+                if header[0] == 'numpy.core':
+                    header = ('numpy', header[1])
+                    if os.path.splitext(header[1])[1] == '.inc':
+                        continue
+                d = os.path.join(*([prefix]+header[0].split('.')))
+                header = header[1]
+            else:
+                d = self.install_dir
+            self.mkpath(d)
+            (out, _) = self.copy_file(header, d)
+            self.outfiles.append(out)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
new file mode 100644
index 0000000000..bfaab1c8ff
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
@@ -0,0 +1,29 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+if 'setuptools' in sys.modules:
+    from setuptools.command.sdist import sdist as old_sdist
+else:
+    from distutils.command.sdist import sdist as old_sdist
+
+from numpy.distutils.misc_util import get_data_files
+
+class sdist(old_sdist):
+
+    def add_defaults (self):
+        old_sdist.add_defaults(self)
+
+        dist = self.distribution
+
+        if dist.has_data_files():
+            for data in dist.data_files:
+                self.filelist.extend(get_data_files(data))
+
+        if dist.has_headers():
+            headers = []
+            for h in dist.headers:
+                if isinstance(h, str): headers.append(h)
+                else: headers.append(h[1])
+            self.filelist.extend(headers)
+
+        return
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/compat.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/compat.py
new file mode 100644
index 0000000000..9a81cd392f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/compat.py
@@ -0,0 +1,10 @@
+"""Small modules to cope with python 2 vs 3 incompatibilities inside
+numpy.distutils
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+def get_exception():
+    return sys.exc_info()[1]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.py
new file mode 100644
index 0000000000..43adb16360
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.py
@@ -0,0 +1,337 @@
+#!/usr/bin/python2
+"""
+takes templated file .xxx.src and produces .xxx file  where .xxx is
+.i or .c or .h, using the following template rules
+
+/**begin repeat  -- on a line by itself marks the start of a repeated code
+                    segment
+/**end repeat**/ -- on a line by itself marks it's end
+
+After the /**begin repeat and before the */, all the named templates are placed
+these should all have the same number of replacements
+
+Repeat blocks can be nested, with each nested block labeled with its depth,
+i.e.
+/**begin repeat1
+ *....
+ */
+/**end repeat1**/
+
+When using nested loops, you can optionally exlude particular
+combinations of the variables using (inside the comment portion of the inner loop):
+
+ :exclude: var1=value1, var2=value2, ...
+
+This will exlude the pattern where var1 is value1 and var2 is value2 when
+the result is being generated.
+
+
+In the main body each replace will use one entry from the list of named replacements
+
+ Note that all #..# forms in a block must have the same number of
+   comma-separated entries.
+
+Example:
+
+    An input file containing
+
+        /**begin repeat
+         * #a = 1,2,3#
+         * #b = 1,2,3#
+         */
+
+        /**begin repeat1
+         * #c = ted, jim#
+         */
+        @a@, @b@, @c@
+        /**end repeat1**/
+
+        /**end repeat**/
+
+    produces
+
+        line 1 "template.c.src"
+
+        /*
+         *********************************************************************
+         **       This file was autogenerated from a template  DO NOT EDIT!!**
+         **       Changes should be made to the original source (.src) file **
+         *********************************************************************
+         */
+
+        #line 9
+        1, 1, ted
+
+        #line 9
+        1, 1, jim
+
+        #line 9
+        2, 2, ted
+
+        #line 9
+        2, 2, jim
+
+        #line 9
+        3, 3, ted
+
+        #line 9
+        3, 3, jim
+
+"""
+from __future__ import division, absolute_import, print_function
+
+
+__all__ = ['process_str', 'process_file']
+
+import os
+import sys
+import re
+
+from numpy.distutils.compat import get_exception
+
+# names for replacement that are already global.
+global_names = {}
+
+# header placed at the front of head processed file
+header =\
+"""
+/*
+ *****************************************************************************
+ **       This file was autogenerated from a template  DO NOT EDIT!!!!      **
+ **       Changes should be made to the original source (.src) file         **
+ *****************************************************************************
+ */
+
+"""
+# Parse string for repeat loops
+def parse_structure(astr, level):
+    """
+    The returned line number is from the beginning of the string, starting
+    at zero. Returns an empty list if no loops found.
+
+    """
+    if level == 0 :
+        loopbeg = "/**begin repeat"
+        loopend = "/**end repeat**/"
+    else :
+        loopbeg = "/**begin repeat%d" % level
+        loopend = "/**end repeat%d**/" % level
+
+    ind = 0
+    line = 0
+    spanlist = []
+    while True:
+        start = astr.find(loopbeg, ind)
+        if start == -1:
+            break
+        start2 = astr.find("*/", start)
+        start2 = astr.find("\n", start2)
+        fini1 = astr.find(loopend, start2)
+        fini2 = astr.find("\n", fini1)
+        line += astr.count("\n", ind, start2+1)
+        spanlist.append((start, start2+1, fini1, fini2+1, line))
+        line += astr.count("\n", start2+1, fini2)
+        ind = fini2
+    spanlist.sort()
+    return spanlist
+
+
+def paren_repl(obj):
+    torep = obj.group(1)
+    numrep = obj.group(2)
+    return ','.join([torep]*int(numrep))
+
+parenrep = re.compile(r"[(]([^)]*)[)]\*(\d+)")
+plainrep = re.compile(r"([^*]+)\*(\d+)")
+def parse_values(astr):
+    # replaces all occurrences of '(a,b,c)*4' in astr
+    # with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate
+    # empty values, i.e., ()*4 yields ',,,'. The result is
+    # split at ',' and a list of values returned.
+    astr = parenrep.sub(paren_repl, astr)
+    # replaces occurences of xxx*3 with xxx, xxx, xxx
+    astr = ','.join([plainrep.sub(paren_repl, x.strip())
+                     for x in astr.split(',')])
+    return astr.split(',')
+
+
+stripast = re.compile(r"\n\s*\*?")
+named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#")
+exclude_vars_re = re.compile(r"(\w*)=(\w*)")
+exclude_re = re.compile(":exclude:")
+def parse_loop_header(loophead) :
+    """Find all named replacements in the header
+
+    Returns a list of dictionaries, one for each loop iteration,
+    where each key is a name to be substituted and the corresponding
+    value is the replacement string.
+
+    Also return a list of exclusions.  The exclusions are dictionaries
+     of key value pairs. There can be more than one exclusion.
+     [{'var1':'value1', 'var2', 'value2'[,...]}, ...]
+
+    """
+    # Strip out '\n' and leading '*', if any, in continuation lines.
+    # This should not effect code previous to this change as
+    # continuation lines were not allowed.
+    loophead = stripast.sub("", loophead)
+    # parse out the names and lists of values
+    names = []
+    reps = named_re.findall(loophead)
+    nsub = None
+    for rep in reps:
+        name = rep[0]
+        vals = parse_values(rep[1])
+        size = len(vals)
+        if nsub is None :
+            nsub = size
+        elif nsub != size :
+            msg = "Mismatch in number of values:\n%s = %s" % (name, vals)
+            raise ValueError(msg)
+        names.append((name, vals))
+
+
+    # Find any exclude variables
+    excludes = []
+
+    for obj in exclude_re.finditer(loophead):
+        span = obj.span()
+        # find next newline
+        endline = loophead.find('\n', span[1])
+        substr = loophead[span[1]:endline]
+        ex_names = exclude_vars_re.findall(substr)
+        excludes.append(dict(ex_names))
+
+    # generate list of dictionaries, one for each template iteration
+    dlist = []
+    if nsub is None :
+        raise ValueError("No substitution variables found")
+    for i in range(nsub) :
+        tmp = {}
+        for name, vals in names :
+            tmp[name] = vals[i]
+        dlist.append(tmp)
+    return dlist
+
+replace_re = re.compile(r"@([\w]+)@")
+def parse_string(astr, env, level, line) :
+    lineno = "#line %d\n" % line
+
+    # local function for string replacement, uses env
+    def replace(match):
+        name = match.group(1)
+        try :
+            val = env[name]
+        except KeyError:
+            msg = 'line %d: no definition of key "%s"'%(line, name)
+            raise ValueError(msg)
+        return val
+
+    code = [lineno]
+    struct = parse_structure(astr, level)
+    if struct :
+        # recurse over inner loops
+        oldend = 0
+        newlevel = level + 1
+        for sub in struct:
+            pref = astr[oldend:sub[0]]
+            head = astr[sub[0]:sub[1]]
+            text = astr[sub[1]:sub[2]]
+            oldend = sub[3]
+            newline = line + sub[4]
+            code.append(replace_re.sub(replace, pref))
+            try :
+                envlist = parse_loop_header(head)
+            except ValueError:
+                e = get_exception()
+                msg = "line %d: %s" % (newline, e)
+                raise ValueError(msg)
+            for newenv in envlist :
+                newenv.update(env)
+                newcode = parse_string(text, newenv, newlevel, newline)
+                code.extend(newcode)
+        suff = astr[oldend:]
+        code.append(replace_re.sub(replace, suff))
+    else :
+        # replace keys
+        code.append(replace_re.sub(replace, astr))
+    code.append('\n')
+    return ''.join(code)
+
+def process_str(astr):
+    code = [header]
+    code.extend(parse_string(astr, global_names, 0, 1))
+    return ''.join(code)
+
+
+include_src_re = re.compile(r"(\n|\A)#include\s*['\"]"
+                            r"(?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
+
+def resolve_includes(source):
+    d = os.path.dirname(source)
+    fid = open(source)
+    lines = []
+    for line in fid:
+        m = include_src_re.match(line)
+        if m:
+            fn = m.group('name')
+            if not os.path.isabs(fn):
+                fn = os.path.join(d, fn)
+            if os.path.isfile(fn):
+                print('Including file', fn)
+                lines.extend(resolve_includes(fn))
+            else:
+                lines.append(line)
+        else:
+            lines.append(line)
+    fid.close()
+    return lines
+
+def process_file(source):
+    lines = resolve_includes(source)
+    sourcefile = os.path.normcase(source).replace("\\", "\\\\")
+    try:
+        code = process_str(''.join(lines))
+    except ValueError:
+        e = get_exception()
+        raise ValueError('In "%s" loop at %s' % (sourcefile, e))
+    return '#line 1 "%s"\n%s' % (sourcefile, code)
+
+
+def unique_key(adict):
+    # this obtains a unique key given a dictionary
+    # currently it works by appending together n of the letters of the
+    #   current keys and increasing n until a unique key is found
+    # -- not particularly quick
+    allkeys = list(adict.keys())
+    done = False
+    n = 1
+    while not done:
+        newkey = "".join([x[:n] for x in allkeys])
+        if newkey in allkeys:
+            n += 1
+        else:
+            done = True
+    return newkey
+
+
+if __name__ == "__main__":
+
+    try:
+        file = sys.argv[1]
+    except IndexError:
+        fid = sys.stdin
+        outfile = sys.stdout
+    else:
+        fid = open(file, 'r')
+        (base, ext) = os.path.splitext(file)
+        newname = base
+        outfile = open(newname, 'w')
+
+    allstr = fid.read()
+    try:
+        writestr = process_str(allstr)
+    except ValueError:
+        e = get_exception()
+        raise ValueError("In %s loop at %s" % (file, e))
+    outfile.write(writestr)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/core.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/core.py
new file mode 100644
index 0000000000..3f0fd464a0
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/core.py
@@ -0,0 +1,210 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from distutils.core import *
+
+if 'setuptools' in sys.modules:
+    have_setuptools = True
+    from setuptools import setup as old_setup
+    # easy_install imports math, it may be picked up from cwd
+    from setuptools.command import easy_install
+    try:
+        # very old versions of setuptools don't have this
+        from setuptools.command import bdist_egg
+    except ImportError:
+        have_setuptools = False
+else:
+    from distutils.core import setup as old_setup
+    have_setuptools = False
+
+import warnings
+import distutils.core
+import distutils.dist
+
+from numpy.distutils.extension import Extension
+from numpy.distutils.numpy_distribution import NumpyDistribution
+from numpy.distutils.command import config, config_compiler, \
+     build, build_py, build_ext, build_clib, build_src, build_scripts, \
+     sdist, install_data, install_headers, install, bdist_rpm, \
+     install_clib
+from numpy.distutils.misc_util import get_data_files, is_sequence, is_string
+
+numpy_cmdclass = {'build':            build.build,
+                  'build_src':        build_src.build_src,
+                  'build_scripts':    build_scripts.build_scripts,
+                  'config_cc':        config_compiler.config_cc,
+                  'config_fc':        config_compiler.config_fc,
+                  'config':           config.config,
+                  'build_ext':        build_ext.build_ext,
+                  'build_py':         build_py.build_py,
+                  'build_clib':       build_clib.build_clib,
+                  'sdist':            sdist.sdist,
+                  'install_data':     install_data.install_data,
+                  'install_headers':  install_headers.install_headers,
+                  'install_clib':     install_clib.install_clib,
+                  'install':          install.install,
+                  'bdist_rpm':        bdist_rpm.bdist_rpm,
+                  }
+if have_setuptools:
+    # Use our own versions of develop and egg_info to ensure that build_src is
+    # handled appropriately.
+    from numpy.distutils.command import develop, egg_info
+    numpy_cmdclass['bdist_egg'] = bdist_egg.bdist_egg
+    numpy_cmdclass['develop'] = develop.develop
+    numpy_cmdclass['easy_install'] = easy_install.easy_install
+    numpy_cmdclass['egg_info'] = egg_info.egg_info
+
+def _dict_append(d, **kws):
+    for k, v in kws.items():
+        if k not in d:
+            d[k] = v
+            continue
+        dv = d[k]
+        if isinstance(dv, tuple):
+            d[k] = dv + tuple(v)
+        elif isinstance(dv, list):
+            d[k] = dv + list(v)
+        elif isinstance(dv, dict):
+            _dict_append(dv, **v)
+        elif is_string(dv):
+            d[k] = dv + v
+        else:
+            raise TypeError(repr(type(dv)))
+
+def _command_line_ok(_cache=[]):
+    """ Return True if command line does not contain any
+    help or display requests.
+    """
+    if _cache:
+        return _cache[0]
+    ok = True
+    display_opts = ['--'+n for n in Distribution.display_option_names]
+    for o in Distribution.display_options:
+        if o[1]:
+            display_opts.append('-'+o[1])
+    for arg in sys.argv:
+        if arg.startswith('--help') or arg=='-h' or arg in display_opts:
+            ok = False
+            break
+    _cache.append(ok)
+    return ok
+
+def get_distribution(always=False):
+    dist = distutils.core._setup_distribution
+    # XXX Hack to get numpy installable with easy_install.
+    # The problem is easy_install runs it's own setup(), which
+    # sets up distutils.core._setup_distribution. However,
+    # when our setup() runs, that gets overwritten and lost.
+    # We can't use isinstance, as the DistributionWithoutHelpCommands
+    # class is local to a function in setuptools.command.easy_install
+    if dist is not None and \
+            'DistributionWithoutHelpCommands' in repr(dist):
+        dist = None
+    if always and dist is None:
+        dist = NumpyDistribution()
+    return dist
+
+def setup(**attr):
+
+    cmdclass = numpy_cmdclass.copy()
+
+    new_attr = attr.copy()
+    if 'cmdclass' in new_attr:
+        cmdclass.update(new_attr['cmdclass'])
+    new_attr['cmdclass'] = cmdclass
+
+    if 'configuration' in new_attr:
+        # To avoid calling configuration if there are any errors
+        # or help request in command in the line.
+        configuration = new_attr.pop('configuration')
+
+        old_dist = distutils.core._setup_distribution
+        old_stop = distutils.core._setup_stop_after
+        distutils.core._setup_distribution = None
+        distutils.core._setup_stop_after = "commandline"
+        try:
+            dist = setup(**new_attr)
+        finally:
+            distutils.core._setup_distribution = old_dist
+            distutils.core._setup_stop_after = old_stop
+        if dist.help or not _command_line_ok():
+            # probably displayed help, skip running any commands
+            return dist
+
+        # create setup dictionary and append to new_attr
+        config = configuration()
+        if hasattr(config, 'todict'):
+            config = config.todict()
+        _dict_append(new_attr, **config)
+
+    # Move extension source libraries to libraries
+    libraries = []
+    for ext in new_attr.get('ext_modules', []):
+        new_libraries = []
+        for item in ext.libraries:
+            if is_sequence(item):
+                lib_name, build_info = item
+                _check_append_ext_library(libraries, lib_name, build_info)
+                new_libraries.append(lib_name)
+            elif is_string(item):
+                new_libraries.append(item)
+            else:
+                raise TypeError("invalid description of extension module "
+                                "library %r" % (item,))
+        ext.libraries = new_libraries
+    if libraries:
+        if 'libraries' not in new_attr:
+            new_attr['libraries'] = []
+        for item in libraries:
+            _check_append_library(new_attr['libraries'], item)
+
+    # sources in ext_modules or libraries may contain header files
+    if ('ext_modules' in new_attr or 'libraries' in new_attr) \
+       and 'headers' not in new_attr:
+        new_attr['headers'] = []
+
+    # Use our custom NumpyDistribution class instead of distutils' one
+    new_attr['distclass'] = NumpyDistribution
+
+    return old_setup(**new_attr)
+
+def _check_append_library(libraries, item):
+    for libitem in libraries:
+        if is_sequence(libitem):
+            if is_sequence(item):
+                if item[0]==libitem[0]:
+                    if item[1] is libitem[1]:
+                        return
+                    warnings.warn("[0] libraries list contains %r with"
+                                  " different build_info" % (item[0],))
+                    break
+            else:
+                if item==libitem[0]:
+                    warnings.warn("[1] libraries list contains %r with"
+                                  " no build_info" % (item[0],))
+                    break
+        else:
+            if is_sequence(item):
+                if item[0]==libitem:
+                    warnings.warn("[2] libraries list contains %r with"
+                                  " no build_info" % (item[0],))
+                    break
+            else:
+                if item==libitem:
+                    return
+    libraries.append(item)
+
+def _check_append_ext_library(libraries, lib_name, build_info):
+    for item in libraries:
+        if is_sequence(item):
+            if item[0]==lib_name:
+                if item[1] is build_info:
+                    return
+                warnings.warn("[3] libraries list contains %r with"
+                              " different build_info" % (lib_name,))
+                break
+        elif item==lib_name:
+            warnings.warn("[4] libraries list contains %r with"
+                          " no build_info" % (lib_name,))
+            break
+    libraries.append((lib_name, build_info))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
new file mode 100644
index 0000000000..40f9d77c98
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
@@ -0,0 +1,693 @@
+#!/usr/bin/env python2
+"""
+cpuinfo
+
+Copyright 2002 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) license.  See LICENSE.txt that came with
+this distribution for specifics.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['cpu']
+
+import sys, re, types
+import os
+
+if sys.version_info[0] >= 3:
+    from subprocess import getstatusoutput
+else:
+    from commands import getstatusoutput
+
+import warnings
+import platform
+
+from numpy.distutils.compat import get_exception
+
+def getoutput(cmd, successful_status=(0,), stacklevel=1):
+    try:
+        status, output = getstatusoutput(cmd)
+    except EnvironmentError:
+        e = get_exception()
+        warnings.warn(str(e), UserWarning, stacklevel=stacklevel)
+        return False, output
+    if os.WIFEXITED(status) and os.WEXITSTATUS(status) in successful_status:
+        return True, output
+    return False, output
+
+def command_info(successful_status=(0,), stacklevel=1, **kw):
+    info = {}
+    for key in kw:
+        ok, output = getoutput(kw[key], successful_status=successful_status,
+                               stacklevel=stacklevel+1)
+        if ok:
+            info[key] = output.strip()
+    return info
+
+def command_by_line(cmd, successful_status=(0,), stacklevel=1):
+    ok, output = getoutput(cmd, successful_status=successful_status,
+                           stacklevel=stacklevel+1)
+    if not ok:
+        return
+    for line in output.splitlines():
+        yield line.strip()
+
+def key_value_from_command(cmd, sep, successful_status=(0,),
+                           stacklevel=1):
+    d = {}
+    for line in command_by_line(cmd, successful_status=successful_status,
+                                stacklevel=stacklevel+1):
+        l = [s.strip() for s in line.split(sep, 1)]
+        if len(l) == 2:
+            d[l[0]] = l[1]
+    return d
+
+class CPUInfoBase(object):
+    """Holds CPU information and provides methods for requiring
+    the availability of various CPU features.
+    """
+
+    def _try_call(self, func):
+        try:
+            return func()
+        except:
+            pass
+
+    def __getattr__(self, name):
+        if not name.startswith('_'):
+            if hasattr(self, '_'+name):
+                attr = getattr(self, '_'+name)
+                if isinstance(attr, types.MethodType):
+                    return lambda func=self._try_call,attr=attr : func(attr)
+            else:
+                return lambda : None
+        raise AttributeError(name)
+
+    def _getNCPUs(self):
+        return 1
+
+    def __get_nbits(self):
+        abits = platform.architecture()[0]
+        nbits = re.compile('(\d+)bit').search(abits).group(1)
+        return nbits
+
+    def _is_32bit(self):
+        return self.__get_nbits() == '32'
+
+    def _is_64bit(self):
+        return self.__get_nbits() == '64'
+
+class LinuxCPUInfo(CPUInfoBase):
+
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = [ {} ]
+        ok, output = getoutput('uname -m')
+        if ok:
+            info[0]['uname_m'] = output.strip()
+        try:
+            fo = open('/proc/cpuinfo')
+        except EnvironmentError:
+            e = get_exception()
+            warnings.warn(str(e), UserWarning)
+        else:
+            for line in fo:
+                name_value = [s.strip() for s in line.split(':', 1)]
+                if len(name_value) != 2:
+                    continue
+                name, value = name_value
+                if not info or name in info[-1]: # next processor
+                    info.append({})
+                info[-1][name] = value
+            fo.close()
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    # Athlon
+
+    def _is_AMD(self):
+        return self.info[0]['vendor_id']=='AuthenticAMD'
+
+    def _is_AthlonK6_2(self):
+        return self._is_AMD() and self.info[0]['model'] == '2'
+
+    def _is_AthlonK6_3(self):
+        return self._is_AMD() and self.info[0]['model'] == '3'
+
+    def _is_AthlonK6(self):
+        return re.match(r'.*?AMD-K6', self.info[0]['model name']) is not None
+
+    def _is_AthlonK7(self):
+        return re.match(r'.*?AMD-K7', self.info[0]['model name']) is not None
+
+    def _is_AthlonMP(self):
+        return re.match(r'.*?Athlon\(tm\) MP\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_AMD64(self):
+        return self.is_AMD() and self.info[0]['family'] == '15'
+
+    def _is_Athlon64(self):
+        return re.match(r'.*?Athlon\(tm\) 64\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_AthlonHX(self):
+        return re.match(r'.*?Athlon HX\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Opteron(self):
+        return re.match(r'.*?Opteron\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Hammer(self):
+        return re.match(r'.*?Hammer\b',
+                        self.info[0]['model name']) is not None
+
+    # Alpha
+
+    def _is_Alpha(self):
+        return self.info[0]['cpu']=='Alpha'
+
+    def _is_EV4(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV4'
+
+    def _is_EV5(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV5'
+
+    def _is_EV56(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV56'
+
+    def _is_PCA56(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'PCA56'
+
+    # Intel
+
+    #XXX
+    _is_i386 = _not_impl
+
+    def _is_Intel(self):
+        return self.info[0]['vendor_id']=='GenuineIntel'
+
+    def _is_i486(self):
+        return self.info[0]['cpu']=='i486'
+
+    def _is_i586(self):
+        return self.is_Intel() and self.info[0]['cpu family'] == '5'
+
+    def _is_i686(self):
+        return self.is_Intel() and self.info[0]['cpu family'] == '6'
+
+    def _is_Celeron(self):
+        return re.match(r'.*?Celeron',
+                        self.info[0]['model name']) is not None
+
+    def _is_Pentium(self):
+        return re.match(r'.*?Pentium',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumII(self):
+        return re.match(r'.*?Pentium.*?II\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumPro(self):
+        return re.match(r'.*?PentiumPro\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumMMX(self):
+        return re.match(r'.*?Pentium.*?MMX\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumIII(self):
+        return re.match(r'.*?Pentium.*?III\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumIV(self):
+        return re.match(r'.*?Pentium.*?(IV|4)\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumM(self):
+        return re.match(r'.*?Pentium.*?M\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Prescott(self):
+        return self.is_PentiumIV() and self.has_sse3()
+
+    def _is_Nocona(self):
+        return self.is_Intel() \
+               and (self.info[0]['cpu family'] == '6' \
+                    or self.info[0]['cpu family'] == '15' ) \
+               and (self.has_sse3() and not self.has_ssse3())\
+               and re.match(r'.*?\blm\b', self.info[0]['flags']) is not None
+
+    def _is_Core2(self):
+        return self.is_64bit() and self.is_Intel() and \
+               re.match(r'.*?Core\(TM\)2\b', \
+                        self.info[0]['model name']) is not None
+
+    def _is_Itanium(self):
+        return re.match(r'.*?Itanium\b',
+                        self.info[0]['family']) is not None
+
+    def _is_XEON(self):
+        return re.match(r'.*?XEON\b',
+                        self.info[0]['model name'], re.IGNORECASE) is not None
+
+    _is_Xeon = _is_XEON
+
+    # Varia
+
+    def _is_singleCPU(self):
+        return len(self.info) == 1
+
+    def _getNCPUs(self):
+        return len(self.info)
+
+    def _has_fdiv_bug(self):
+        return self.info[0]['fdiv_bug']=='yes'
+
+    def _has_f00f_bug(self):
+        return self.info[0]['f00f_bug']=='yes'
+
+    def _has_mmx(self):
+        return re.match(r'.*?\bmmx\b', self.info[0]['flags']) is not None
+
+    def _has_sse(self):
+        return re.match(r'.*?\bsse\b', self.info[0]['flags']) is not None
+
+    def _has_sse2(self):
+        return re.match(r'.*?\bsse2\b', self.info[0]['flags']) is not None
+
+    def _has_sse3(self):
+        return re.match(r'.*?\bpni\b', self.info[0]['flags']) is not None
+
+    def _has_ssse3(self):
+        return re.match(r'.*?\bssse3\b', self.info[0]['flags']) is not None
+
+    def _has_3dnow(self):
+        return re.match(r'.*?\b3dnow\b', self.info[0]['flags']) is not None
+
+    def _has_3dnowext(self):
+        return re.match(r'.*?\b3dnowext\b', self.info[0]['flags']) is not None
+
+class IRIXCPUInfo(CPUInfoBase):
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = key_value_from_command('sysconf', sep=' ',
+                                      successful_status=(0, 1))
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _is_singleCPU(self):
+        return self.info.get('NUM_PROCESSORS') == '1'
+
+    def _getNCPUs(self):
+        return int(self.info.get('NUM_PROCESSORS', 1))
+
+    def __cputype(self, n):
+        return self.info.get('PROCESSORS').split()[0].lower() == 'r%s' % (n)
+    def _is_r2000(self): return self.__cputype(2000)
+    def _is_r3000(self): return self.__cputype(3000)
+    def _is_r3900(self): return self.__cputype(3900)
+    def _is_r4000(self): return self.__cputype(4000)
+    def _is_r4100(self): return self.__cputype(4100)
+    def _is_r4300(self): return self.__cputype(4300)
+    def _is_r4400(self): return self.__cputype(4400)
+    def _is_r4600(self): return self.__cputype(4600)
+    def _is_r4650(self): return self.__cputype(4650)
+    def _is_r5000(self): return self.__cputype(5000)
+    def _is_r6000(self): return self.__cputype(6000)
+    def _is_r8000(self): return self.__cputype(8000)
+    def _is_r10000(self): return self.__cputype(10000)
+    def _is_r12000(self): return self.__cputype(12000)
+    def _is_rorion(self): return self.__cputype('orion')
+
+    def get_ip(self):
+        try: return self.info.get('MACHINE')
+        except: pass
+    def __machine(self, n):
+        return self.info.get('MACHINE').lower() == 'ip%s' % (n)
+    def _is_IP19(self): return self.__machine(19)
+    def _is_IP20(self): return self.__machine(20)
+    def _is_IP21(self): return self.__machine(21)
+    def _is_IP22(self): return self.__machine(22)
+    def _is_IP22_4k(self): return self.__machine(22) and self._is_r4000()
+    def _is_IP22_5k(self): return self.__machine(22)  and self._is_r5000()
+    def _is_IP24(self): return self.__machine(24)
+    def _is_IP25(self): return self.__machine(25)
+    def _is_IP26(self): return self.__machine(26)
+    def _is_IP27(self): return self.__machine(27)
+    def _is_IP28(self): return self.__machine(28)
+    def _is_IP30(self): return self.__machine(30)
+    def _is_IP32(self): return self.__machine(32)
+    def _is_IP32_5k(self): return self.__machine(32) and self._is_r5000()
+    def _is_IP32_10k(self): return self.__machine(32) and self._is_r10000()
+
+
+class DarwinCPUInfo(CPUInfoBase):
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = command_info(arch='arch',
+                            machine='machine')
+        info['sysctl_hw'] = key_value_from_command('sysctl hw', sep='=')
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _getNCPUs(self):
+        return int(self.info['sysctl_hw'].get('hw.ncpu', 1))
+
+    def _is_Power_Macintosh(self):
+        return self.info['sysctl_hw']['hw.machine']=='Power Macintosh'
+
+    def _is_i386(self):
+        return self.info['arch']=='i386'
+    def _is_ppc(self):
+        return self.info['arch']=='ppc'
+
+    def __machine(self, n):
+        return self.info['machine'] == 'ppc%s'%n
+    def _is_ppc601(self): return self.__machine(601)
+    def _is_ppc602(self): return self.__machine(602)
+    def _is_ppc603(self): return self.__machine(603)
+    def _is_ppc603e(self): return self.__machine('603e')
+    def _is_ppc604(self): return self.__machine(604)
+    def _is_ppc604e(self): return self.__machine('604e')
+    def _is_ppc620(self): return self.__machine(620)
+    def _is_ppc630(self): return self.__machine(630)
+    def _is_ppc740(self): return self.__machine(740)
+    def _is_ppc7400(self): return self.__machine(7400)
+    def _is_ppc7450(self): return self.__machine(7450)
+    def _is_ppc750(self): return self.__machine(750)
+    def _is_ppc403(self): return self.__machine(403)
+    def _is_ppc505(self): return self.__machine(505)
+    def _is_ppc801(self): return self.__machine(801)
+    def _is_ppc821(self): return self.__machine(821)
+    def _is_ppc823(self): return self.__machine(823)
+    def _is_ppc860(self): return self.__machine(860)
+
+
+class SunOSCPUInfo(CPUInfoBase):
+
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = command_info(arch='arch',
+                            mach='mach',
+                            uname_i='uname_i',
+                            isainfo_b='isainfo -b',
+                            isainfo_n='isainfo -n',
+                            )
+        info['uname_X'] = key_value_from_command('uname -X', sep='=')
+        for line in command_by_line('psrinfo -v 0'):
+            m = re.match(r'\s*The (?P<p>[\w\d]+) processor operates at', line)
+            if m:
+                info['processor'] = m.group('p')
+                break
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _is_i386(self):
+        return self.info['isainfo_n']=='i386'
+    def _is_sparc(self):
+        return self.info['isainfo_n']=='sparc'
+    def _is_sparcv9(self):
+        return self.info['isainfo_n']=='sparcv9'
+
+    def _getNCPUs(self):
+        return int(self.info['uname_X'].get('NumCPU', 1))
+
+    def _is_sun4(self):
+        return self.info['arch']=='sun4'
+
+    def _is_SUNW(self):
+        return re.match(r'SUNW', self.info['uname_i']) is not None
+    def _is_sparcstation5(self):
+        return re.match(r'.*SPARCstation-5', self.info['uname_i']) is not None
+    def _is_ultra1(self):
+        return re.match(r'.*Ultra-1', self.info['uname_i']) is not None
+    def _is_ultra250(self):
+        return re.match(r'.*Ultra-250', self.info['uname_i']) is not None
+    def _is_ultra2(self):
+        return re.match(r'.*Ultra-2', self.info['uname_i']) is not None
+    def _is_ultra30(self):
+        return re.match(r'.*Ultra-30', self.info['uname_i']) is not None
+    def _is_ultra4(self):
+        return re.match(r'.*Ultra-4', self.info['uname_i']) is not None
+    def _is_ultra5_10(self):
+        return re.match(r'.*Ultra-5_10', self.info['uname_i']) is not None
+    def _is_ultra5(self):
+        return re.match(r'.*Ultra-5', self.info['uname_i']) is not None
+    def _is_ultra60(self):
+        return re.match(r'.*Ultra-60', self.info['uname_i']) is not None
+    def _is_ultra80(self):
+        return re.match(r'.*Ultra-80', self.info['uname_i']) is not None
+    def _is_ultraenterprice(self):
+        return re.match(r'.*Ultra-Enterprise', self.info['uname_i']) is not None
+    def _is_ultraenterprice10k(self):
+        return re.match(r'.*Ultra-Enterprise-10000', self.info['uname_i']) is not None
+    def _is_sunfire(self):
+        return re.match(r'.*Sun-Fire', self.info['uname_i']) is not None
+    def _is_ultra(self):
+        return re.match(r'.*Ultra', self.info['uname_i']) is not None
+
+    def _is_cpusparcv7(self):
+        return self.info['processor']=='sparcv7'
+    def _is_cpusparcv8(self):
+        return self.info['processor']=='sparcv8'
+    def _is_cpusparcv9(self):
+        return self.info['processor']=='sparcv9'
+
+class Win32CPUInfo(CPUInfoBase):
+
+    info = None
+    pkey = r"HARDWARE\DESCRIPTION\System\CentralProcessor"
+    # XXX: what does the value of
+    #   HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
+    # mean?
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = []
+        try:
+            #XXX: Bad style to use so long `try:...except:...`. Fix it!
+            if sys.version_info[0] >= 3:
+                import winreg
+            else:
+                import _winreg as winreg
+
+            prgx = re.compile(r"family\s+(?P<FML>\d+)\s+model\s+(?P<MDL>\d+)"\
+                              "\s+stepping\s+(?P<STP>\d+)", re.IGNORECASE)
+            chnd=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, self.pkey)
+            pnum=0
+            while True:
+                try:
+                    proc=winreg.EnumKey(chnd, pnum)
+                except winreg.error:
+                    break
+                else:
+                    pnum+=1
+                    info.append({"Processor":proc})
+                    phnd=winreg.OpenKey(chnd, proc)
+                    pidx=0
+                    while True:
+                        try:
+                            name, value, vtpe=winreg.EnumValue(phnd, pidx)
+                        except winreg.error:
+                            break
+                        else:
+                            pidx=pidx+1
+                            info[-1][name]=value
+                            if name=="Identifier":
+                                srch=prgx.search(value)
+                                if srch:
+                                    info[-1]["Family"]=int(srch.group("FML"))
+                                    info[-1]["Model"]=int(srch.group("MDL"))
+                                    info[-1]["Stepping"]=int(srch.group("STP"))
+        except:
+            print(sys.exc_info()[1], '(ignoring)')
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    # Athlon
+
+    def _is_AMD(self):
+        return self.info[0]['VendorIdentifier']=='AuthenticAMD'
+
+    def _is_Am486(self):
+        return self.is_AMD() and self.info[0]['Family']==4
+
+    def _is_Am5x86(self):
+        return self.is_AMD() and self.info[0]['Family']==4
+
+    def _is_AMDK5(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model'] in [0, 1, 2, 3]
+
+    def _is_AMDK6(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model'] in [6, 7]
+
+    def _is_AMDK6_2(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==8
+
+    def _is_AMDK6_3(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==9
+
+    def _is_AMDK7(self):
+        return self.is_AMD() and self.info[0]['Family'] == 6
+
+    # To reliably distinguish between the different types of AMD64 chips
+    # (Athlon64, Operton, Athlon64 X2, Semperon, Turion 64, etc.) would
+    # require looking at the 'brand' from cpuid
+
+    def _is_AMD64(self):
+        return self.is_AMD() and self.info[0]['Family'] == 15
+
+    # Intel
+
+    def _is_Intel(self):
+        return self.info[0]['VendorIdentifier']=='GenuineIntel'
+
+    def _is_i386(self):
+        return self.info[0]['Family']==3
+
+    def _is_i486(self):
+        return self.info[0]['Family']==4
+
+    def _is_i586(self):
+        return self.is_Intel() and self.info[0]['Family']==5
+
+    def _is_i686(self):
+        return self.is_Intel() and self.info[0]['Family']==6
+
+    def _is_Pentium(self):
+        return self.is_Intel() and self.info[0]['Family']==5
+
+    def _is_PentiumMMX(self):
+        return self.is_Intel() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==4
+
+    def _is_PentiumPro(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model']==1
+
+    def _is_PentiumII(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model'] in [3, 5, 6]
+
+    def _is_PentiumIII(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model'] in [7, 8, 9, 10, 11]
+
+    def _is_PentiumIV(self):
+        return self.is_Intel() and self.info[0]['Family']==15
+
+    def _is_PentiumM(self):
+        return self.is_Intel() and self.info[0]['Family'] == 6 \
+               and self.info[0]['Model'] in [9, 13, 14]
+
+    def _is_Core2(self):
+        return self.is_Intel() and self.info[0]['Family'] == 6 \
+               and self.info[0]['Model'] in [15, 16, 17]
+
+    # Varia
+
+    def _is_singleCPU(self):
+        return len(self.info) == 1
+
+    def _getNCPUs(self):
+        return len(self.info)
+
+    def _has_mmx(self):
+        if self.is_Intel():
+            return (self.info[0]['Family']==5 and self.info[0]['Model']==4) \
+                   or (self.info[0]['Family'] in [6, 15])
+        elif self.is_AMD():
+            return self.info[0]['Family'] in [5, 6, 15]
+        else:
+            return False
+
+    def _has_sse(self):
+        if self.is_Intel():
+            return (self.info[0]['Family']==6 and \
+                    self.info[0]['Model'] in [7, 8, 9, 10, 11]) \
+                    or self.info[0]['Family']==15
+        elif self.is_AMD():
+            return (self.info[0]['Family']==6 and \
+                    self.info[0]['Model'] in [6, 7, 8, 10]) \
+                    or self.info[0]['Family']==15
+        else:
+            return False
+
+    def _has_sse2(self):
+        if self.is_Intel():
+            return self.is_Pentium4() or self.is_PentiumM() \
+                   or self.is_Core2()
+        elif self.is_AMD():
+            return self.is_AMD64()
+        else:
+            return False
+
+    def _has_3dnow(self):
+        return self.is_AMD() and self.info[0]['Family'] in [5, 6, 15]
+
+    def _has_3dnowext(self):
+        return self.is_AMD() and self.info[0]['Family'] in [6, 15]
+
+if sys.platform.startswith('linux'): # variations: linux2,linux-i386 (any others?)
+    cpuinfo = LinuxCPUInfo
+elif sys.platform.startswith('irix'):
+    cpuinfo = IRIXCPUInfo
+elif sys.platform == 'darwin':
+    cpuinfo = DarwinCPUInfo
+elif sys.platform.startswith('sunos'):
+    cpuinfo = SunOSCPUInfo
+elif sys.platform.startswith('win32'):
+    cpuinfo = Win32CPUInfo
+elif sys.platform.startswith('cygwin'):
+    cpuinfo = LinuxCPUInfo
+#XXX: other OS's. Eg. use _winreg on Win32. Or os.uname on unices.
+else:
+    cpuinfo = CPUInfoBase
+
+cpu = cpuinfo()
+
+#if __name__ == "__main__":
+#
+#    cpu.is_blaa()
+#    cpu.is_Intel()
+#    cpu.is_Alpha()
+#
+#    print 'CPU information:',
+#    for name in dir(cpuinfo):
+#        if name[0]=='_' and name[1]!='_':
+#            r = getattr(cpu,name[1:])()
+#            if r:
+#                if r!=1:
+#                    print '%s=%s' %(name[1:],r),
+#                else:
+#                    print name[1:],
+#    print
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/environment.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/environment.py
new file mode 100644
index 0000000000..3798e16f5d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/environment.py
@@ -0,0 +1,72 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.dist import Distribution
+
+__metaclass__ = type
+
+class EnvironmentConfig(object):
+    def __init__(self, distutils_section='ALL', **kw):
+        self._distutils_section = distutils_section
+        self._conf_keys = kw
+        self._conf = None
+        self._hook_handler = None
+
+    def dump_variable(self, name):
+        conf_desc = self._conf_keys[name]
+        hook, envvar, confvar, convert = conf_desc
+        if not convert:
+            convert = lambda x : x
+        print('%s.%s:' % (self._distutils_section, name))
+        v = self._hook_handler(name, hook)
+        print('  hook   : %s' % (convert(v),))
+        if envvar:
+            v = os.environ.get(envvar, None)
+            print('  environ: %s' % (convert(v),))
+        if confvar and self._conf:
+            v = self._conf.get(confvar, (None, None))[1]
+            print('  config : %s' % (convert(v),))
+
+    def dump_variables(self):
+        for name in self._conf_keys:
+            self.dump_variable(name)
+
+    def __getattr__(self, name):
+        try:
+            conf_desc = self._conf_keys[name]
+        except KeyError:
+            raise AttributeError(name)
+        return self._get_var(name, conf_desc)
+
+    def get(self, name, default=None):
+        try:
+            conf_desc = self._conf_keys[name]
+        except KeyError:
+            return default
+        var = self._get_var(name, conf_desc)
+        if var is None:
+            var = default
+        return var
+
+    def _get_var(self, name, conf_desc):
+        hook, envvar, confvar, convert = conf_desc
+        var = self._hook_handler(name, hook)
+        if envvar is not None:
+            var = os.environ.get(envvar, var)
+        if confvar is not None and self._conf:
+            var = self._conf.get(confvar, (None, var))[1]
+        if convert is not None:
+            var = convert(var)
+        return var
+
+    def clone(self, hook_handler):
+        ec = self.__class__(distutils_section=self._distutils_section,
+                            **self._conf_keys)
+        ec._hook_handler = hook_handler
+        return ec
+
+    def use_distribution(self, dist):
+        if isinstance(dist, Distribution):
+            self._conf = dist.get_option_dict(self._distutils_section)
+        else:
+            self._conf = dist
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.py
new file mode 100644
index 0000000000..c127dc355b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.py
@@ -0,0 +1,651 @@
+#!/usr/bin/env python2
+"""
+exec_command
+
+Implements exec_command function that is (almost) equivalent to
+commands.getstatusoutput function but on NT, DOS systems the
+returned status is actually correct (though, the returned status
+values may be different by a factor). In addition, exec_command
+takes keyword arguments for (re-)defining environment variables.
+
+Provides functions:
+
+  exec_command  --- execute command in a specified directory and
+                    in the modified environment.
+  find_executable --- locate a command using info from environment
+                    variable PATH. Equivalent to posix `which`
+                    command.
+
+Author: Pearu Peterson <pearu@cens.ioc.ee>
+Created: 11 January 2003
+
+Requires: Python 2.x
+
+Succesfully tested on:
+
+========  ============  =================================================
+os.name   sys.platform  comments
+========  ============  =================================================
+posix     linux2        Debian (sid) Linux, Python 2.1.3+, 2.2.3+, 2.3.3
+                        PyCrust 0.9.3, Idle 1.0.2
+posix     linux2        Red Hat 9 Linux, Python 2.1.3, 2.2.2, 2.3.2
+posix     sunos5        SunOS 5.9, Python 2.2, 2.3.2
+posix     darwin        Darwin 7.2.0, Python 2.3
+nt        win32         Windows Me
+                        Python 2.3(EE), Idle 1.0, PyCrust 0.7.2
+                        Python 2.1.1 Idle 0.8
+nt        win32         Windows 98, Python 2.1.1. Idle 0.8
+nt        win32         Cygwin 98-4.10, Python 2.1.1(MSC) - echo tests
+                        fail i.e. redefining environment variables may
+                        not work. FIXED: don't use cygwin echo!
+                        Comment: also `cmd /c echo` will not work
+                        but redefining environment variables do work.
+posix     cygwin        Cygwin 98-4.10, Python 2.3.3(cygming special)
+nt        win32         Windows XP, Python 2.3.3
+========  ============  =================================================
+
+Known bugs:
+
+* Tests, that send messages to stderr, fail when executed from MSYS prompt
+  because the messages are lost at some point.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['exec_command', 'find_executable']
+
+import os
+import sys
+import shlex
+
+from numpy.distutils.misc_util import is_sequence, make_temp_file
+from numpy.distutils import log
+from numpy.distutils.compat import get_exception
+
+from numpy.compat import open_latin1
+
+def temp_file_name():
+    fo, name = make_temp_file()
+    fo.close()
+    return name
+
+def get_pythonexe():
+    pythonexe = sys.executable
+    if os.name in ['nt', 'dos']:
+        fdir, fn = os.path.split(pythonexe)
+        fn = fn.upper().replace('PYTHONW', 'PYTHON')
+        pythonexe = os.path.join(fdir, fn)
+        assert os.path.isfile(pythonexe), '%r is not a file' % (pythonexe,)
+    return pythonexe
+
+def find_executable(exe, path=None, _cache={}):
+    """Return full path of a executable or None.
+
+    Symbolic links are not followed.
+    """
+    key = exe, path
+    try:
+        return _cache[key]
+    except KeyError:
+        pass
+    log.debug('find_executable(%r)' % exe)
+    orig_exe = exe
+
+    if path is None:
+        path = os.environ.get('PATH', os.defpath)
+    if os.name=='posix':
+        realpath = os.path.realpath
+    else:
+        realpath = lambda a:a
+
+    if exe.startswith('"'):
+        exe = exe[1:-1]
+
+    suffixes = ['']
+    if os.name in ['nt', 'dos', 'os2']:
+        fn, ext = os.path.splitext(exe)
+        extra_suffixes = ['.exe', '.com', '.bat']
+        if ext.lower() not in extra_suffixes:
+            suffixes = extra_suffixes
+
+    if os.path.isabs(exe):
+        paths = ['']
+    else:
+        paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ]
+
+    for path in paths:
+        fn = os.path.join(path, exe)
+        for s in suffixes:
+            f_ext = fn+s
+            if not os.path.islink(f_ext):
+                f_ext = realpath(f_ext)
+            if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK):
+                log.info('Found executable %s' % f_ext)
+                _cache[key] = f_ext
+                return f_ext
+
+    log.warn('Could not locate executable %s' % orig_exe)
+    return None
+
+############################################################
+
+def _preserve_environment( names ):
+    log.debug('_preserve_environment(%r)' % (names))
+    env = {}
+    for name in names:
+        env[name] = os.environ.get(name)
+    return env
+
+def _update_environment( **env ):
+    log.debug('_update_environment(...)')
+    for name, value in env.items():
+        os.environ[name] = value or ''
+
+def _supports_fileno(stream):
+    """
+    Returns True if 'stream' supports the file descriptor and allows fileno().
+    """
+    if hasattr(stream, 'fileno'):
+        try:
+            r = stream.fileno()
+            return True
+        except IOError:
+            return False
+    else:
+        return False
+
+def exec_command(command, execute_in='', use_shell=None, use_tee=None,
+                 _with_python = 1, **env ):
+    """
+    Return (status,output) of executed command.
+
+    Parameters
+    ----------
+    command : str
+        A concatenated string of executable and arguments.
+    execute_in : str
+        Before running command ``cd execute_in`` and after ``cd -``.
+    use_shell : {bool, None}, optional
+        If True, execute ``sh -c command``. Default None (True)
+    use_tee : {bool, None}, optional
+        If True use tee. Default None (True)
+
+
+    Returns
+    -------
+    res : str
+        Both stdout and stderr messages.
+
+    Notes
+    -----
+    On NT, DOS systems the returned status is correct for external commands.
+    Wild cards will not work for non-posix systems or when use_shell=0.
+
+    """
+    log.debug('exec_command(%r,%s)' % (command,\
+         ','.join(['%s=%r'%kv for kv in env.items()])))
+
+    if use_tee is None:
+        use_tee = os.name=='posix'
+    if use_shell is None:
+        use_shell = os.name=='posix'
+    execute_in = os.path.abspath(execute_in)
+    oldcwd = os.path.abspath(os.getcwd())
+
+    if __name__[-12:] == 'exec_command':
+        exec_dir = os.path.dirname(os.path.abspath(__file__))
+    elif os.path.isfile('exec_command.py'):
+        exec_dir = os.path.abspath('.')
+    else:
+        exec_dir = os.path.abspath(sys.argv[0])
+        if os.path.isfile(exec_dir):
+            exec_dir = os.path.dirname(exec_dir)
+
+    if oldcwd!=execute_in:
+        os.chdir(execute_in)
+        log.debug('New cwd: %s' % execute_in)
+    else:
+        log.debug('Retaining cwd: %s' % oldcwd)
+
+    oldenv = _preserve_environment( list(env.keys()) )
+    _update_environment( **env )
+
+    try:
+        # _exec_command is robust but slow, it relies on
+        # usable sys.std*.fileno() descriptors. If they
+        # are bad (like in win32 Idle, PyCrust environments)
+        # then _exec_command_python (even slower)
+        # will be used as a last resort.
+        #
+        # _exec_command_posix uses os.system and is faster
+        # but not on all platforms os.system will return
+        # a correct status.
+        if (_with_python and _supports_fileno(sys.stdout) and
+                            sys.stdout.fileno() == -1):
+            st = _exec_command_python(command,
+                                      exec_command_dir = exec_dir,
+                                      **env)
+        elif os.name=='posix':
+            st = _exec_command_posix(command,
+                                     use_shell=use_shell,
+                                     use_tee=use_tee,
+                                     **env)
+        else:
+            st = _exec_command(command, use_shell=use_shell,
+                               use_tee=use_tee,**env)
+    finally:
+        if oldcwd!=execute_in:
+            os.chdir(oldcwd)
+            log.debug('Restored cwd to %s' % oldcwd)
+        _update_environment(**oldenv)
+
+    return st
+
+def _exec_command_posix( command,
+                         use_shell = None,
+                         use_tee = None,
+                         **env ):
+    log.debug('_exec_command_posix(...)')
+
+    if is_sequence(command):
+        command_str = ' '.join(list(command))
+    else:
+        command_str = command
+
+    tmpfile = temp_file_name()
+    stsfile = None
+    if use_tee:
+        stsfile = temp_file_name()
+        filter = ''
+        if use_tee == 2:
+            filter = r'| tr -cd "\n" | tr "\n" "."; echo'
+        command_posix = '( %s ; echo $? > %s ) 2>&1 | tee %s %s'\
+                      % (command_str, stsfile, tmpfile, filter)
+    else:
+        stsfile = temp_file_name()
+        command_posix = '( %s ; echo $? > %s ) > %s 2>&1'\
+                        % (command_str, stsfile, tmpfile)
+        #command_posix = '( %s ) > %s 2>&1' % (command_str,tmpfile)
+
+    log.debug('Running os.system(%r)' % (command_posix))
+    status = os.system(command_posix)
+
+    if use_tee:
+        if status:
+            # if command_tee fails then fall back to robust exec_command
+            log.warn('_exec_command_posix failed (status=%s)' % status)
+            return _exec_command(command, use_shell=use_shell, **env)
+
+    if stsfile is not None:
+        f = open_latin1(stsfile, 'r')
+        status_text = f.read()
+        status = int(status_text)
+        f.close()
+        os.remove(stsfile)
+
+    f = open_latin1(tmpfile, 'r')
+    text = f.read()
+    f.close()
+    os.remove(tmpfile)
+
+    if text[-1:]=='\n':
+        text = text[:-1]
+
+    return status, text
+
+
+def _exec_command_python(command,
+                         exec_command_dir='', **env):
+    log.debug('_exec_command_python(...)')
+
+    python_exe = get_pythonexe()
+    cmdfile = temp_file_name()
+    stsfile = temp_file_name()
+    outfile = temp_file_name()
+
+    f = open(cmdfile, 'w')
+    f.write('import os\n')
+    f.write('import sys\n')
+    f.write('sys.path.insert(0,%r)\n' % (exec_command_dir))
+    f.write('from exec_command import exec_command\n')
+    f.write('del sys.path[0]\n')
+    f.write('cmd = %r\n' % command)
+    f.write('os.environ = %r\n' % (os.environ))
+    f.write('s,o = exec_command(cmd, _with_python=0, **%r)\n' % (env))
+    f.write('f=open(%r,"w")\nf.write(str(s))\nf.close()\n' % (stsfile))
+    f.write('f=open(%r,"w")\nf.write(o)\nf.close()\n' % (outfile))
+    f.close()
+
+    cmd = '%s %s' % (python_exe, cmdfile)
+    status = os.system(cmd)
+    if status:
+        raise RuntimeError("%r failed" % (cmd,))
+    os.remove(cmdfile)
+
+    f = open_latin1(stsfile, 'r')
+    status = int(f.read())
+    f.close()
+    os.remove(stsfile)
+
+    f = open_latin1(outfile, 'r')
+    text = f.read()
+    f.close()
+    os.remove(outfile)
+
+    return status, text
+
+def quote_arg(arg):
+    if arg[0]!='"' and ' ' in arg:
+        return '"%s"' % arg
+    return arg
+
+def _exec_command( command, use_shell=None, use_tee = None, **env ):
+    log.debug('_exec_command(...)')
+
+    if use_shell is None:
+        use_shell = os.name=='posix'
+    if use_tee is None:
+        use_tee = os.name=='posix'
+    using_command = 0
+    if use_shell:
+        # We use shell (unless use_shell==0) so that wildcards can be
+        # used.
+        sh = os.environ.get('SHELL', '/bin/sh')
+        if is_sequence(command):
+            argv = [sh, '-c', ' '.join(list(command))]
+        else:
+            argv = [sh, '-c', command]
+    else:
+        # On NT, DOS we avoid using command.com as it's exit status is
+        # not related to the exit status of a command.
+        if is_sequence(command):
+            argv = command[:]
+        else:
+            argv = shlex.split(command)
+
+    if hasattr(os, 'spawnvpe'):
+        spawn_command = os.spawnvpe
+    else:
+        spawn_command = os.spawnve
+        argv[0] = find_executable(argv[0]) or argv[0]
+        if not os.path.isfile(argv[0]):
+            log.warn('Executable %s does not exist' % (argv[0]))
+            if os.name in ['nt', 'dos']:
+                # argv[0] might be internal command
+                argv = [os.environ['COMSPEC'], '/C'] + argv
+                using_command = 1
+
+    _so_has_fileno = _supports_fileno(sys.stdout)
+    _se_has_fileno = _supports_fileno(sys.stderr)
+    so_flush = sys.stdout.flush
+    se_flush = sys.stderr.flush
+    if _so_has_fileno:
+        so_fileno = sys.stdout.fileno()
+        so_dup = os.dup(so_fileno)
+    if _se_has_fileno:
+        se_fileno = sys.stderr.fileno()
+        se_dup = os.dup(se_fileno)
+
+    outfile = temp_file_name()
+    fout = open(outfile, 'w')
+    if using_command:
+        errfile = temp_file_name()
+        ferr = open(errfile, 'w')
+
+    log.debug('Running %s(%s,%r,%r,os.environ)' \
+              % (spawn_command.__name__, os.P_WAIT, argv[0], argv))
+
+    if sys.version_info[0] >= 3 and os.name == 'nt':
+        # Pre-encode os.environ, discarding un-encodable entries,
+        # to avoid it failing during encoding as part of spawn. Failure
+        # is possible if the environment contains entries that are not
+        # encoded using the system codepage as windows expects.
+        #
+        # This is not necessary on unix, where os.environ is encoded
+        # using the surrogateescape error handler and decoded using
+        # it as part of spawn.
+        encoded_environ = {}
+        for k, v in os.environ.items():
+            try:
+                encoded_environ[k.encode(sys.getfilesystemencoding())] = v.encode(
+                    sys.getfilesystemencoding())
+            except UnicodeEncodeError:
+                log.debug("ignoring un-encodable env entry %s", k)
+    else:
+        encoded_environ = os.environ
+
+    argv0 = argv[0]
+    if not using_command:
+        argv[0] = quote_arg(argv0)
+
+    so_flush()
+    se_flush()
+    if _so_has_fileno:
+        os.dup2(fout.fileno(), so_fileno)
+
+    if _se_has_fileno:
+        if using_command:
+            #XXX: disabled for now as it does not work from cmd under win32.
+            #     Tests fail on msys
+            os.dup2(ferr.fileno(), se_fileno)
+        else:
+            os.dup2(fout.fileno(), se_fileno)
+    try:
+        status = spawn_command(os.P_WAIT, argv0, argv, encoded_environ)
+    except Exception:
+        errmess = str(get_exception())
+        status = 999
+        sys.stderr.write('%s: %s'%(errmess, argv[0]))
+
+    so_flush()
+    se_flush()
+    if _so_has_fileno:
+        os.dup2(so_dup, so_fileno)
+        os.close(so_dup)
+    if _se_has_fileno:
+        os.dup2(se_dup, se_fileno)
+        os.close(se_dup)
+
+    fout.close()
+    fout = open_latin1(outfile, 'r')
+    text = fout.read()
+    fout.close()
+    os.remove(outfile)
+
+    if using_command:
+        ferr.close()
+        ferr = open_latin1(errfile, 'r')
+        errmess = ferr.read()
+        ferr.close()
+        os.remove(errfile)
+        if errmess and not status:
+            # Not sure how to handle the case where errmess
+            # contains only warning messages and that should
+            # not be treated as errors.
+            #status = 998
+            if text:
+                text = text + '\n'
+            #text = '%sCOMMAND %r FAILED: %s' %(text,command,errmess)
+            text = text + errmess
+            print (errmess)
+    if text[-1:]=='\n':
+        text = text[:-1]
+    if status is None:
+        status = 0
+
+    if use_tee:
+        print (text)
+
+    return status, text
+
+
+def test_nt(**kws):
+    pythonexe = get_pythonexe()
+    echo = find_executable('echo')
+    using_cygwin_echo = echo != 'echo'
+    if using_cygwin_echo:
+        log.warn('Using cygwin echo in win32 environment is not supported')
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'AAA\',\'\')"')
+        assert s==0 and o=='', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'AAA\')"',
+                         AAA='Tere')
+        assert s==0 and o=='Tere', (s, o)
+
+        os.environ['BBB'] = 'Hi'
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
+        assert s==0 and o=='Hi', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"',
+                         BBB='Hey')
+        assert s==0 and o=='Hey', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
+        assert s==0 and o=='Hi', (s, o)
+    elif 0:
+        s, o=exec_command('echo Hello')
+        assert s==0 and o=='Hello', (s, o)
+
+        s, o=exec_command('echo a%AAA%')
+        assert s==0 and o=='a', (s, o)
+
+        s, o=exec_command('echo a%AAA%', AAA='Tere')
+        assert s==0 and o=='aTere', (s, o)
+
+        os.environ['BBB'] = 'Hi'
+        s, o=exec_command('echo a%BBB%')
+        assert s==0 and o=='aHi', (s, o)
+
+        s, o=exec_command('echo a%BBB%', BBB='Hey')
+        assert s==0 and o=='aHey', (s, o)
+        s, o=exec_command('echo a%BBB%')
+        assert s==0 and o=='aHi', (s, o)
+
+        s, o=exec_command('this_is_not_a_command')
+        assert s and o!='', (s, o)
+
+        s, o=exec_command('type not_existing_file')
+        assert s and o!='', (s, o)
+
+    s, o=exec_command('echo path=%path%')
+    assert s==0 and o!='', (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.stderr.write(sys.platform)"' \
+                     % pythonexe)
+    assert s==0 and o=='win32', (s, o)
+
+    s, o=exec_command('%s -c "raise \'Ignore me.\'"' % pythonexe)
+    assert s==1 and o, (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"'\
+                     % pythonexe)
+    assert s==0 and o=='012', (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.exit(15)"' % pythonexe)
+    assert s==15 and o=='', (s, o)
+
+    s, o=exec_command('%s -c "print \'Heipa\'"' % pythonexe)
+    assert s==0 and o=='Heipa', (s, o)
+
+    print ('ok')
+
+def test_posix(**kws):
+    s, o=exec_command("echo Hello",**kws)
+    assert s==0 and o=='Hello', (s, o)
+
+    s, o=exec_command('echo $AAA',**kws)
+    assert s==0 and o=='', (s, o)
+
+    s, o=exec_command('echo "$AAA"',AAA='Tere',**kws)
+    assert s==0 and o=='Tere', (s, o)
+
+
+    s, o=exec_command('echo "$AAA"',**kws)
+    assert s==0 and o=='', (s, o)
+
+    os.environ['BBB'] = 'Hi'
+    s, o=exec_command('echo "$BBB"',**kws)
+    assert s==0 and o=='Hi', (s, o)
+
+    s, o=exec_command('echo "$BBB"',BBB='Hey',**kws)
+    assert s==0 and o=='Hey', (s, o)
+
+    s, o=exec_command('echo "$BBB"',**kws)
+    assert s==0 and o=='Hi', (s, o)
+
+
+    s, o=exec_command('this_is_not_a_command',**kws)
+    assert s!=0 and o!='', (s, o)
+
+    s, o=exec_command('echo path=$PATH',**kws)
+    assert s==0 and o!='', (s, o)
+
+    s, o=exec_command('python -c "import sys,os;sys.stderr.write(os.name)"',**kws)
+    assert s==0 and o=='posix', (s, o)
+
+    s, o=exec_command('python -c "raise \'Ignore me.\'"',**kws)
+    assert s==1 and o, (s, o)
+
+    s, o=exec_command('python -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"',**kws)
+    assert s==0 and o=='012', (s, o)
+
+    s, o=exec_command('python -c "import sys;sys.exit(15)"',**kws)
+    assert s==15 and o=='', (s, o)
+
+    s, o=exec_command('python -c "print \'Heipa\'"',**kws)
+    assert s==0 and o=='Heipa', (s, o)
+
+    print ('ok')
+
+def test_execute_in(**kws):
+    pythonexe = get_pythonexe()
+    tmpfile = temp_file_name()
+    fn = os.path.basename(tmpfile)
+    tmpdir = os.path.dirname(tmpfile)
+    f = open(tmpfile, 'w')
+    f.write('Hello')
+    f.close()
+
+    s, o = exec_command('%s -c "print \'Ignore the following IOError:\','\
+                       'open(%r,\'r\')"' % (pythonexe, fn),**kws)
+    assert s and o!='', (s, o)
+    s, o = exec_command('%s -c "print open(%r,\'r\').read()"' % (pythonexe, fn),
+                       execute_in = tmpdir,**kws)
+    assert s==0 and o=='Hello', (s, o)
+    os.remove(tmpfile)
+    print ('ok')
+
+def test_svn(**kws):
+    s, o = exec_command(['svn', 'status'],**kws)
+    assert s, (s, o)
+    print ('svn ok')
+
+def test_cl(**kws):
+    if os.name=='nt':
+        s, o = exec_command(['cl', '/V'],**kws)
+        assert s, (s, o)
+        print ('cl ok')
+
+if os.name=='posix':
+    test = test_posix
+elif os.name in ['nt', 'dos']:
+    test = test_nt
+else:
+    raise NotImplementedError('exec_command tests for ', os.name)
+
+############################################################
+
+if __name__ == "__main__":
+
+    test(use_tee=0)
+    test(use_tee=1)
+    test_execute_in(use_tee=0)
+    test_execute_in(use_tee=1)
+    test_svn(use_tee=1)
+    test_cl(use_tee=1)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/extension.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/extension.py
new file mode 100644
index 0000000000..344c66da02
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/extension.py
@@ -0,0 +1,90 @@
+"""distutils.extension
+
+Provides the Extension class, used to describe C/C++ extension
+modules in setup scripts.
+
+Overridden to support f2py.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+from distutils.extension import Extension as old_Extension
+
+if sys.version_info[0] >= 3:
+    basestring = str
+
+
+cxx_ext_re = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
+fortran_pyf_ext_re = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+
+class Extension(old_Extension):
+    def __init__ (self, name, sources,
+                  include_dirs=None,
+                  define_macros=None,
+                  undef_macros=None,
+                  library_dirs=None,
+                  libraries=None,
+                  runtime_library_dirs=None,
+                  extra_objects=None,
+                  extra_compile_args=None,
+                  extra_link_args=None,
+                  export_symbols=None,
+                  swig_opts=None,
+                  depends=None,
+                  language=None,
+                  f2py_options=None,
+                  module_dirs=None,
+                  extra_f77_compile_args=None,
+                  extra_f90_compile_args=None,
+                 ):
+        old_Extension.__init__(self, name, [],
+                               include_dirs,
+                               define_macros,
+                               undef_macros,
+                               library_dirs,
+                               libraries,
+                               runtime_library_dirs,
+                               extra_objects,
+                               extra_compile_args,
+                               extra_link_args,
+                               export_symbols)
+        # Avoid assert statements checking that sources contains strings:
+        self.sources = sources
+
+        # Python 2.4 distutils new features
+        self.swig_opts = swig_opts or []
+        # swig_opts is assumed to be a list. Here we handle the case where it
+        # is specified as a string instead.
+        if isinstance(self.swig_opts, basestring):
+            import warnings
+            msg = "swig_opts is specified as a string instead of a list"
+            warnings.warn(msg, SyntaxWarning)
+            self.swig_opts = self.swig_opts.split()
+
+        # Python 2.3 distutils new features
+        self.depends = depends or []
+        self.language = language
+
+        # numpy_distutils features
+        self.f2py_options = f2py_options or []
+        self.module_dirs = module_dirs or []
+        self.extra_f77_compile_args = extra_f77_compile_args or []
+        self.extra_f90_compile_args = extra_f90_compile_args or []
+
+        return
+
+    def has_cxx_sources(self):
+        for source in self.sources:
+            if cxx_ext_re(str(source)):
+                return True
+        return False
+
+    def has_f2py_sources(self):
+        for source in self.sources:
+            if fortran_pyf_ext_re(source):
+                return True
+        return False
+
+# class Extension
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
new file mode 100644
index 0000000000..0b1b1ee6d9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
@@ -0,0 +1,989 @@
+"""numpy.distutils.fcompiler
+
+Contains FCompiler, an abstract base class that defines the interface
+for the numpy.distutils Fortran compiler abstraction model.
+
+Terminology:
+
+To be consistent, where the term 'executable' is used, it means the single
+file, like 'gcc', that is executed, and should be a string. In contrast,
+'command' means the entire command line, like ['gcc', '-c', 'file.c'], and
+should be a list.
+
+But note that FCompiler.executables is actually a dictionary of commands.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['FCompiler', 'new_fcompiler', 'show_fcompilers',
+           'dummy_fortran_file']
+
+import os
+import sys
+import re
+import types
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from numpy.compat import open_latin1
+
+from distutils.sysconfig import get_python_lib
+from distutils.fancy_getopt import FancyGetopt
+from distutils.errors import DistutilsModuleError, \
+     DistutilsExecError, CompileError, LinkError, DistutilsPlatformError
+from distutils.util import split_quoted, strtobool
+
+from numpy.distutils.ccompiler import CCompiler, gen_lib_options
+from numpy.distutils import log
+from numpy.distutils.misc_util import is_string, all_strings, is_sequence, \
+    make_temp_file, get_shared_lib_extension
+from numpy.distutils.environment import EnvironmentConfig
+from numpy.distutils.exec_command import find_executable
+from numpy.distutils.compat import get_exception
+
+__metaclass__ = type
+
+class CompilerNotFound(Exception):
+    pass
+
+def flaglist(s):
+    if is_string(s):
+        return split_quoted(s)
+    else:
+        return s
+
+def str2bool(s):
+    if is_string(s):
+        return strtobool(s)
+    return bool(s)
+
+def is_sequence_of_strings(seq):
+    return is_sequence(seq) and all_strings(seq)
+
+class FCompiler(CCompiler):
+    """Abstract base class to define the interface that must be implemented
+    by real Fortran compiler classes.
+
+    Methods that subclasses may redefine:
+
+        update_executables(), find_executables(), get_version()
+        get_flags(), get_flags_opt(), get_flags_arch(), get_flags_debug()
+        get_flags_f77(), get_flags_opt_f77(), get_flags_arch_f77(),
+        get_flags_debug_f77(), get_flags_f90(), get_flags_opt_f90(),
+        get_flags_arch_f90(), get_flags_debug_f90(),
+        get_flags_fix(), get_flags_linker_so()
+
+    DON'T call these methods (except get_version) after
+    constructing a compiler instance or inside any other method.
+    All methods, except update_executables() and find_executables(),
+    may call the get_version() method.
+
+    After constructing a compiler instance, always call customize(dist=None)
+    method that finalizes compiler construction and makes the following
+    attributes available:
+      compiler_f77
+      compiler_f90
+      compiler_fix
+      linker_so
+      archiver
+      ranlib
+      libraries
+      library_dirs
+    """
+
+    # These are the environment variables and distutils keys used.
+    # Each configuration descripition is
+    # (<hook name>, <environment variable>, <key in distutils.cfg>, <convert>)
+    # The hook names are handled by the self._environment_hook method.
+    #  - names starting with 'self.' call methods in this class
+    #  - names starting with 'exe.' return the key in the executables dict
+    #  - names like 'flags.YYY' return self.get_flag_YYY()
+    # convert is either None or a function to convert a string to the
+    # appropiate type used.
+
+    distutils_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        noopt = (None, None, 'noopt', str2bool),
+        noarch = (None, None, 'noarch', str2bool),
+        debug = (None, None, 'debug', str2bool),
+        verbose = (None, None, 'verbose', str2bool),
+    )
+
+    command_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec', None),
+        compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec', None),
+        compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec', None),
+        version_cmd = ('exe.version_cmd', None, None, None),
+        linker_so = ('exe.linker_so', 'LDSHARED', 'ldshared', None),
+        linker_exe = ('exe.linker_exe', 'LD', 'ld', None),
+        archiver = (None, 'AR', 'ar', None),
+        ranlib = (None, 'RANLIB', 'ranlib', None),
+    )
+
+    flag_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        f77 = ('flags.f77', 'F77FLAGS', 'f77flags', flaglist),
+        f90 = ('flags.f90', 'F90FLAGS', 'f90flags', flaglist),
+        free = ('flags.free', 'FREEFLAGS', 'freeflags', flaglist),
+        fix = ('flags.fix', None, None, flaglist),
+        opt = ('flags.opt', 'FOPT', 'opt', flaglist),
+        opt_f77 = ('flags.opt_f77', None, None, flaglist),
+        opt_f90 = ('flags.opt_f90', None, None, flaglist),
+        arch = ('flags.arch', 'FARCH', 'arch', flaglist),
+        arch_f77 = ('flags.arch_f77', None, None, flaglist),
+        arch_f90 = ('flags.arch_f90', None, None, flaglist),
+        debug = ('flags.debug', 'FDEBUG', 'fdebug', flaglist),
+        debug_f77 = ('flags.debug_f77', None, None, flaglist),
+        debug_f90 = ('flags.debug_f90', None, None, flaglist),
+        flags = ('self.get_flags', 'FFLAGS', 'fflags', flaglist),
+        linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags', flaglist),
+        linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags', flaglist),
+        ar = ('flags.ar', 'ARFLAGS', 'arflags', flaglist),
+    )
+
+    language_map = {'.f': 'f77',
+                    '.for': 'f77',
+                    '.F': 'f77',    # XXX: needs preprocessor
+                    '.ftn': 'f77',
+                    '.f77': 'f77',
+                    '.f90': 'f90',
+                    '.F90': 'f90',  # XXX: needs preprocessor
+                    '.f95': 'f90',
+                    }
+    language_order = ['f90', 'f77']
+
+
+    # These will be set by the subclass
+
+    compiler_type = None
+    compiler_aliases = ()
+    version_pattern = None
+
+    possible_executables = []
+    executables = {
+        'version_cmd': ["f77", "-v"],
+        'compiler_f77': ["f77"],
+        'compiler_f90': ["f90"],
+        'compiler_fix': ["f90", "-fixed"],
+        'linker_so': ["f90", "-shared"],
+        'linker_exe': ["f90"],
+        'archiver': ["ar", "-cr"],
+        'ranlib': None,
+        }
+
+    # If compiler does not support compiling Fortran 90 then it can
+    # suggest using another compiler. For example, gnu would suggest
+    # gnu95 compiler type when there are F90 sources.
+    suggested_f90_compiler = None
+
+    compile_switch = "-c"
+    object_switch = "-o "   # Ending space matters! It will be stripped
+                            # but if it is missing then object_switch
+                            # will be prefixed to object file name by
+                            # string concatenation.
+    library_switch = "-o "  # Ditto!
+
+    # Switch to specify where module files are created and searched
+    # for USE statement.  Normally it is a string and also here ending
+    # space matters. See above.
+    module_dir_switch = None
+
+    # Switch to specify where module files are searched for USE statement.
+    module_include_switch = '-I'
+
+    pic_flags = []           # Flags to create position-independent code
+
+    src_extensions = ['.for', '.ftn', '.f77', '.f', '.f90', '.f95', '.F', '.F90', '.FOR']
+    obj_extension = ".o"
+
+    shared_lib_extension = get_shared_lib_extension()
+    static_lib_extension = ".a"  # or .lib
+    static_lib_format = "lib%s%s" # or %s%s
+    shared_lib_format = "%s%s"
+    exe_extension = ""
+
+    _exe_cache = {}
+
+    _executable_keys = ['version_cmd', 'compiler_f77', 'compiler_f90',
+                        'compiler_fix', 'linker_so', 'linker_exe', 'archiver',
+                        'ranlib']
+
+    # This will be set by new_fcompiler when called in
+    # command/{build_ext.py, build_clib.py, config.py} files.
+    c_compiler = None
+
+    # extra_{f77,f90}_compile_args are set by build_ext.build_extension method
+    extra_f77_compile_args = []
+    extra_f90_compile_args = []
+
+    def __init__(self, *args, **kw):
+        CCompiler.__init__(self, *args, **kw)
+        self.distutils_vars = self.distutils_vars.clone(self._environment_hook)
+        self.command_vars = self.command_vars.clone(self._environment_hook)
+        self.flag_vars = self.flag_vars.clone(self._environment_hook)
+        self.executables = self.executables.copy()
+        for e in self._executable_keys:
+            if e not in self.executables:
+                self.executables[e] = None
+
+        # Some methods depend on .customize() being called first, so
+        # this keeps track of whether that's happened yet.
+        self._is_customised = False
+
+    def __copy__(self):
+        obj = self.__new__(self.__class__)
+        obj.__dict__.update(self.__dict__)
+        obj.distutils_vars = obj.distutils_vars.clone(obj._environment_hook)
+        obj.command_vars = obj.command_vars.clone(obj._environment_hook)
+        obj.flag_vars = obj.flag_vars.clone(obj._environment_hook)
+        obj.executables = obj.executables.copy()
+        return obj
+
+    def copy(self):
+        return self.__copy__()
+
+    # Use properties for the attributes used by CCompiler. Setting them
+    # as attributes from the self.executables dictionary is error-prone,
+    # so we get them from there each time.
+    def _command_property(key):
+        def fget(self):
+            assert self._is_customised
+            return self.executables[key]
+        return property(fget=fget)
+    version_cmd = _command_property('version_cmd')
+    compiler_f77 = _command_property('compiler_f77')
+    compiler_f90 = _command_property('compiler_f90')
+    compiler_fix = _command_property('compiler_fix')
+    linker_so = _command_property('linker_so')
+    linker_exe = _command_property('linker_exe')
+    archiver = _command_property('archiver')
+    ranlib = _command_property('ranlib')
+
+    # Make our terminology consistent.
+    def set_executable(self, key, value):
+        self.set_command(key, value)
+
+    def set_commands(self, **kw):
+        for k, v in kw.items():
+            self.set_command(k, v)
+
+    def set_command(self, key, value):
+        if not key in self._executable_keys:
+            raise ValueError(
+                "unknown executable '%s' for class %s" %
+                (key, self.__class__.__name__))
+        if is_string(value):
+            value = split_quoted(value)
+        assert value is None or is_sequence_of_strings(value[1:]), (key, value)
+        self.executables[key] = value
+
+    ######################################################################
+    ## Methods that subclasses may redefine. But don't call these methods!
+    ## They are private to FCompiler class and may return unexpected
+    ## results if used elsewhere. So, you have been warned..
+
+    def find_executables(self):
+        """Go through the self.executables dictionary, and attempt to
+        find and assign appropiate executables.
+
+        Executable names are looked for in the environment (environment
+        variables, the distutils.cfg, and command line), the 0th-element of
+        the command list, and the self.possible_executables list.
+
+        Also, if the 0th element is "<F77>" or "<F90>", the Fortran 77
+        or the Fortran 90 compiler executable is used, unless overridden
+        by an environment setting.
+
+        Subclasses should call this if overriden.
+        """
+        assert self._is_customised
+        exe_cache = self._exe_cache
+        def cached_find_executable(exe):
+            if exe in exe_cache:
+                return exe_cache[exe]
+            fc_exe = find_executable(exe)
+            exe_cache[exe] = exe_cache[fc_exe] = fc_exe
+            return fc_exe
+        def verify_command_form(name, value):
+            if value is not None and not is_sequence_of_strings(value):
+                raise ValueError(
+                    "%s value %r is invalid in class %s" %
+                    (name, value, self.__class__.__name__))
+        def set_exe(exe_key, f77=None, f90=None):
+            cmd = self.executables.get(exe_key, None)
+            if not cmd:
+                return None
+            # Note that we get cmd[0] here if the environment doesn't
+            # have anything set
+            exe_from_environ = getattr(self.command_vars, exe_key)
+            if not exe_from_environ:
+                possibles = [f90, f77] + self.possible_executables
+            else:
+                possibles = [exe_from_environ] + self.possible_executables
+
+            seen = set()
+            unique_possibles = []
+            for e in possibles:
+                if e == '<F77>':
+                    e = f77
+                elif e == '<F90>':
+                    e = f90
+                if not e or e in seen:
+                    continue
+                seen.add(e)
+                unique_possibles.append(e)
+
+            for exe in unique_possibles:
+                fc_exe = cached_find_executable(exe)
+                if fc_exe:
+                    cmd[0] = fc_exe
+                    return fc_exe
+            self.set_command(exe_key, None)
+            return None
+
+        ctype = self.compiler_type
+        f90 = set_exe('compiler_f90')
+        if not f90:
+            f77 = set_exe('compiler_f77')
+            if f77:
+                log.warn('%s: no Fortran 90 compiler found' % ctype)
+            else:
+                raise CompilerNotFound('%s: f90 nor f77' % ctype)
+        else:
+            f77 = set_exe('compiler_f77', f90=f90)
+            if not f77:
+                log.warn('%s: no Fortran 77 compiler found' % ctype)
+            set_exe('compiler_fix', f90=f90)
+
+        set_exe('linker_so', f77=f77, f90=f90)
+        set_exe('linker_exe', f77=f77, f90=f90)
+        set_exe('version_cmd', f77=f77, f90=f90)
+        set_exe('archiver')
+        set_exe('ranlib')
+
+    def update_executables(elf):
+        """Called at the beginning of customisation. Subclasses should
+        override this if they need to set up the executables dictionary.
+
+        Note that self.find_executables() is run afterwards, so the
+        self.executables dictionary values can contain <F77> or <F90> as
+        the command, which will be replaced by the found F77 or F90
+        compiler.
+        """
+        pass
+
+    def get_flags(self):
+        """List of flags common to all compiler types."""
+        return [] + self.pic_flags
+
+    def _get_command_flags(self, key):
+        cmd = self.executables.get(key, None)
+        if cmd is None:
+            return []
+        return cmd[1:]
+
+    def get_flags_f77(self):
+        """List of Fortran 77 specific flags."""
+        return self._get_command_flags('compiler_f77')
+    def get_flags_f90(self):
+        """List of Fortran 90 specific flags."""
+        return self._get_command_flags('compiler_f90')
+    def get_flags_free(self):
+        """List of Fortran 90 free format specific flags."""
+        return []
+    def get_flags_fix(self):
+        """List of Fortran 90 fixed format specific flags."""
+        return self._get_command_flags('compiler_fix')
+    def get_flags_linker_so(self):
+        """List of linker flags to build a shared library."""
+        return self._get_command_flags('linker_so')
+    def get_flags_linker_exe(self):
+        """List of linker flags to build an executable."""
+        return self._get_command_flags('linker_exe')
+    def get_flags_ar(self):
+        """List of archiver flags. """
+        return self._get_command_flags('archiver')
+    def get_flags_opt(self):
+        """List of architecture independent compiler flags."""
+        return []
+    def get_flags_arch(self):
+        """List of architecture dependent compiler flags."""
+        return []
+    def get_flags_debug(self):
+        """List of compiler flags to compile with debugging information."""
+        return []
+
+    get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt
+    get_flags_arch_f77 = get_flags_arch_f90 = get_flags_arch
+    get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug
+
+    def get_libraries(self):
+        """List of compiler libraries."""
+        return self.libraries[:]
+    def get_library_dirs(self):
+        """List of compiler library directories."""
+        return self.library_dirs[:]
+
+    def get_version(self, force=False, ok_status=[0]):
+        assert self._is_customised
+        version = CCompiler.get_version(self, force=force, ok_status=ok_status)
+        if version is None:
+            raise CompilerNotFound()
+        return version
+
+    ############################################################
+
+    ## Public methods:
+
+    def customize(self, dist = None):
+        """Customize Fortran compiler.
+
+        This method gets Fortran compiler specific information from
+        (i) class definition, (ii) environment, (iii) distutils config
+        files, and (iv) command line (later overrides earlier).
+
+        This method should be always called after constructing a
+        compiler instance. But not in __init__ because Distribution
+        instance is needed for (iii) and (iv).
+        """
+        log.info('customize %s' % (self.__class__.__name__))
+
+        self._is_customised = True
+
+        self.distutils_vars.use_distribution(dist)
+        self.command_vars.use_distribution(dist)
+        self.flag_vars.use_distribution(dist)
+
+        self.update_executables()
+
+        # find_executables takes care of setting the compiler commands,
+        # version_cmd, linker_so, linker_exe, ar, and ranlib
+        self.find_executables()
+
+        noopt = self.distutils_vars.get('noopt', False)
+        noarch = self.distutils_vars.get('noarch', noopt)
+        debug = self.distutils_vars.get('debug', False)
+
+        f77 = self.command_vars.compiler_f77
+        f90 = self.command_vars.compiler_f90
+
+        f77flags = []
+        f90flags = []
+        freeflags = []
+        fixflags = []
+
+        if f77:
+            f77flags = self.flag_vars.f77
+        if f90:
+            f90flags = self.flag_vars.f90
+            freeflags = self.flag_vars.free
+        # XXX Assuming that free format is default for f90 compiler.
+        fix = self.command_vars.compiler_fix
+        if fix:
+            fixflags = self.flag_vars.fix + f90flags
+
+        oflags, aflags, dflags = [], [], []
+        # examine get_flags_<tag>_<compiler> for extra flags
+        # only add them if the method is different from get_flags_<tag>
+        def get_flags(tag, flags):
+            # note that self.flag_vars.<tag> calls self.get_flags_<tag>()
+            flags.extend(getattr(self.flag_vars, tag))
+            this_get = getattr(self, 'get_flags_' + tag)
+            for name, c, flagvar in [('f77', f77, f77flags),
+                                     ('f90', f90, f90flags),
+                                     ('f90', fix, fixflags)]:
+                t = '%s_%s' % (tag, name)
+                if c and this_get is not getattr(self, 'get_flags_' + t):
+                    flagvar.extend(getattr(self.flag_vars, t))
+        if not noopt:
+            get_flags('opt', oflags)
+            if not noarch:
+                get_flags('arch', aflags)
+        if debug:
+            get_flags('debug', dflags)
+
+        fflags = self.flag_vars.flags + dflags + oflags + aflags
+
+        if f77:
+            self.set_commands(compiler_f77=[f77]+f77flags+fflags)
+        if f90:
+            self.set_commands(compiler_f90=[f90]+freeflags+f90flags+fflags)
+        if fix:
+            self.set_commands(compiler_fix=[fix]+fixflags+fflags)
+
+
+        #XXX: Do we need LDSHARED->SOSHARED, LDFLAGS->SOFLAGS
+        linker_so = self.linker_so
+        if linker_so:
+            linker_so_flags = self.flag_vars.linker_so
+            if sys.platform.startswith('aix'):
+                python_lib = get_python_lib(standard_lib=1)
+                ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
+                python_exp = os.path.join(python_lib, 'config', 'python.exp')
+                linker_so = [ld_so_aix] + linker_so + ['-bI:'+python_exp]
+            self.set_commands(linker_so=linker_so+linker_so_flags)
+
+        linker_exe = self.linker_exe
+        if linker_exe:
+            linker_exe_flags = self.flag_vars.linker_exe
+            self.set_commands(linker_exe=linker_exe+linker_exe_flags)
+
+        ar = self.command_vars.archiver
+        if ar:
+            arflags = self.flag_vars.ar
+            self.set_commands(archiver=[ar]+arflags)
+
+        self.set_library_dirs(self.get_library_dirs())
+        self.set_libraries(self.get_libraries())
+
+    def dump_properties(self):
+        """Print out the attributes of a compiler instance."""
+        props = []
+        for key in list(self.executables.keys()) + \
+                ['version', 'libraries', 'library_dirs',
+                 'object_switch', 'compile_switch']:
+            if hasattr(self, key):
+                v = getattr(self, key)
+                props.append((key, None, '= '+repr(v)))
+        props.sort()
+
+        pretty_printer = FancyGetopt(props)
+        for l in pretty_printer.generate_help("%s instance properties:" \
+                                              % (self.__class__.__name__)):
+            if l[:4]=='  --':
+                l = '  ' + l[4:]
+            print(l)
+
+    ###################
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        """Compile 'src' to product 'obj'."""
+        src_flags = {}
+        if is_f_file(src) and not has_f90_header(src):
+            flavor = ':f77'
+            compiler = self.compiler_f77
+            src_flags = get_f77flags(src)
+            extra_compile_args = self.extra_f77_compile_args or []
+        elif is_free_format(src):
+            flavor = ':f90'
+            compiler = self.compiler_f90
+            if compiler is None:
+                raise DistutilsExecError('f90 not supported by %s needed for %s'\
+                      % (self.__class__.__name__, src))
+            extra_compile_args = self.extra_f90_compile_args or []
+        else:
+            flavor = ':fix'
+            compiler = self.compiler_fix
+            if compiler is None:
+                raise DistutilsExecError('f90 (fixed) not supported by %s needed for %s'\
+                      % (self.__class__.__name__, src))
+            extra_compile_args = self.extra_f90_compile_args or []
+        if self.object_switch[-1]==' ':
+            o_args = [self.object_switch.strip(), obj]
+        else:
+            o_args = [self.object_switch.strip()+obj]
+
+        assert self.compile_switch.strip()
+        s_args = [self.compile_switch, src]
+
+        if extra_compile_args:
+            log.info('extra %s options: %r' \
+                     % (flavor[1:], ' '.join(extra_compile_args)))
+
+        extra_flags = src_flags.get(self.compiler_type, [])
+        if extra_flags:
+            log.info('using compile options from source: %r' \
+                     % ' '.join(extra_flags))
+
+        command = compiler + cc_args + extra_flags + s_args + o_args \
+                  + extra_postargs + extra_compile_args
+
+        display = '%s: %s' % (os.path.basename(compiler[0]) + flavor,
+                              src)
+        try:
+            self.spawn(command, display=display)
+        except DistutilsExecError:
+            msg = str(get_exception())
+            raise CompileError(msg)
+
+    def module_options(self, module_dirs, module_build_dir):
+        options = []
+        if self.module_dir_switch is not None:
+            if self.module_dir_switch[-1]==' ':
+                options.extend([self.module_dir_switch.strip(), module_build_dir])
+            else:
+                options.append(self.module_dir_switch.strip()+module_build_dir)
+        else:
+            print('XXX: module_build_dir=%r option ignored' % (module_build_dir))
+            print('XXX: Fix module_dir_switch for ', self.__class__.__name__)
+        if self.module_include_switch is not None:
+            for d in [module_build_dir]+module_dirs:
+                options.append('%s%s' % (self.module_include_switch, d))
+        else:
+            print('XXX: module_dirs=%r option ignored' % (module_dirs))
+            print('XXX: Fix module_include_switch for ', self.__class__.__name__)
+        return options
+
+    def library_option(self, lib):
+        return "-l" + lib
+    def library_dir_option(self, dir):
+        return "-L" + dir
+
+    def link(self, target_desc, objects,
+             output_filename, output_dir=None, libraries=None,
+             library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=0, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        libraries, library_dirs, runtime_library_dirs = \
+            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
+
+        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
+                                   libraries)
+        if is_string(output_dir):
+            output_filename = os.path.join(output_dir, output_filename)
+        elif output_dir is not None:
+            raise TypeError("'output_dir' must be a string or None")
+
+        if self._need_link(objects, output_filename):
+            if self.library_switch[-1]==' ':
+                o_args = [self.library_switch.strip(), output_filename]
+            else:
+                o_args = [self.library_switch.strip()+output_filename]
+
+            if is_string(self.objects):
+                ld_args = objects + [self.objects]
+            else:
+                ld_args = objects + self.objects
+            ld_args = ld_args + lib_opts + o_args
+            if debug:
+                ld_args[:0] = ['-g']
+            if extra_preargs:
+                ld_args[:0] = extra_preargs
+            if extra_postargs:
+                ld_args.extend(extra_postargs)
+            self.mkpath(os.path.dirname(output_filename))
+            if target_desc == CCompiler.EXECUTABLE:
+                linker = self.linker_exe[:]
+            else:
+                linker = self.linker_so[:]
+            command = linker + ld_args
+            try:
+                self.spawn(command)
+            except DistutilsExecError:
+                msg = str(get_exception())
+                raise LinkError(msg)
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    def _environment_hook(self, name, hook_name):
+        if hook_name is None:
+            return None
+        if is_string(hook_name):
+            if hook_name.startswith('self.'):
+                hook_name = hook_name[5:]
+                hook = getattr(self, hook_name)
+                return hook()
+            elif hook_name.startswith('exe.'):
+                hook_name = hook_name[4:]
+                var = self.executables[hook_name]
+                if var:
+                    return var[0]
+                else:
+                    return None
+            elif hook_name.startswith('flags.'):
+                hook_name = hook_name[6:]
+                hook = getattr(self, 'get_flags_' + hook_name)
+                return hook()
+        else:
+            return hook_name()
+
+    ## class FCompiler
+
+_default_compilers = (
+    # sys.platform mappings
+    ('win32', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95',
+               'intelvem', 'intelem')),
+    ('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')),
+    ('linux.*', ('gnu95', 'intel', 'lahey', 'pg', 'absoft', 'nag', 'vast', 'compaq',
+                'intele', 'intelem', 'gnu', 'g95', 'pathf95')),
+    ('darwin.*', ('gnu95', 'nag', 'absoft', 'ibm', 'intel', 'gnu', 'g95', 'pg')),
+    ('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')),
+    ('irix.*', ('mips', 'gnu', 'gnu95',)),
+    ('aix.*', ('ibm', 'gnu', 'gnu95',)),
+    # os.name mappings
+    ('posix', ('gnu', 'gnu95',)),
+    ('nt', ('gnu', 'gnu95',)),
+    ('mac', ('gnu95', 'gnu', 'pg')),
+    )
+
+fcompiler_class = None
+fcompiler_aliases = None
+
+def load_all_fcompiler_classes():
+    """Cache all the FCompiler classes found in modules in the
+    numpy.distutils.fcompiler package.
+    """
+    from glob import glob
+    global fcompiler_class, fcompiler_aliases
+    if fcompiler_class is not None:
+        return
+    pys = os.path.join(os.path.dirname(__file__), '*.py')
+    fcompiler_class = {}
+    fcompiler_aliases = {}
+    for fname in glob(pys):
+        module_name, ext = os.path.splitext(os.path.basename(fname))
+        module_name = 'numpy.distutils.fcompiler.' + module_name
+        __import__ (module_name)
+        module = sys.modules[module_name]
+        if hasattr(module, 'compilers'):
+            for cname in module.compilers:
+                klass = getattr(module, cname)
+                desc = (klass.compiler_type, klass, klass.description)
+                fcompiler_class[klass.compiler_type] = desc
+                for alias in klass.compiler_aliases:
+                    if alias in fcompiler_aliases:
+                        raise ValueError("alias %r defined for both %s and %s"
+                                         % (alias, klass.__name__,
+                                            fcompiler_aliases[alias][1].__name__))
+                    fcompiler_aliases[alias] = desc
+
+def _find_existing_fcompiler(compiler_types,
+                             osname=None, platform=None,
+                             requiref90=False,
+                             c_compiler=None):
+    from numpy.distutils.core import get_distribution
+    dist = get_distribution(always=True)
+    for compiler_type in compiler_types:
+        v = None
+        try:
+            c = new_fcompiler(plat=platform, compiler=compiler_type,
+                              c_compiler=c_compiler)
+            c.customize(dist)
+            v = c.get_version()
+            if requiref90 and c.compiler_f90 is None:
+                v = None
+                new_compiler = c.suggested_f90_compiler
+                if new_compiler:
+                    log.warn('Trying %r compiler as suggested by %r '
+                             'compiler for f90 support.' % (compiler_type,
+                                                            new_compiler))
+                    c = new_fcompiler(plat=platform, compiler=new_compiler,
+                                      c_compiler=c_compiler)
+                    c.customize(dist)
+                    v = c.get_version()
+                    if v is not None:
+                        compiler_type = new_compiler
+            if requiref90 and c.compiler_f90 is None:
+                raise ValueError('%s does not support compiling f90 codes, '
+                                 'skipping.' % (c.__class__.__name__))
+        except DistutilsModuleError:
+            log.debug("_find_existing_fcompiler: compiler_type='%s' raised DistutilsModuleError", compiler_type)
+        except CompilerNotFound:
+            log.debug("_find_existing_fcompiler: compiler_type='%s' not found", compiler_type)
+        if v is not None:
+            return compiler_type
+    return None
+
+def available_fcompilers_for_platform(osname=None, platform=None):
+    if osname is None:
+        osname = os.name
+    if platform is None:
+        platform = sys.platform
+    matching_compiler_types = []
+    for pattern, compiler_type in _default_compilers:
+        if re.match(pattern, platform) or re.match(pattern, osname):
+            for ct in compiler_type:
+                if ct not in matching_compiler_types:
+                    matching_compiler_types.append(ct)
+    if not matching_compiler_types:
+        matching_compiler_types.append('gnu')
+    return matching_compiler_types
+
+def get_default_fcompiler(osname=None, platform=None, requiref90=False,
+                          c_compiler=None):
+    """Determine the default Fortran compiler to use for the given
+    platform."""
+    matching_compiler_types = available_fcompilers_for_platform(osname,
+                                                                platform)
+    compiler_type =  _find_existing_fcompiler(matching_compiler_types,
+                                              osname=osname,
+                                              platform=platform,
+                                              requiref90=requiref90,
+                                              c_compiler=c_compiler)
+    return compiler_type
+
+# Flag to avoid rechecking for Fortran compiler every time
+failed_fcompilers = set()
+
+def new_fcompiler(plat=None,
+                  compiler=None,
+                  verbose=0,
+                  dry_run=0,
+                  force=0,
+                  requiref90=False,
+                  c_compiler = None):
+    """Generate an instance of some FCompiler subclass for the supplied
+    platform/compiler combination.
+    """
+    global failed_fcompilers
+    fcompiler_key = (plat, compiler)
+    if fcompiler_key in failed_fcompilers:
+        return None
+
+    load_all_fcompiler_classes()
+    if plat is None:
+        plat = os.name
+    if compiler is None:
+        compiler = get_default_fcompiler(plat, requiref90=requiref90,
+                                         c_compiler=c_compiler)
+    if compiler in fcompiler_class:
+        module_name, klass, long_description = fcompiler_class[compiler]
+    elif compiler in fcompiler_aliases:
+        module_name, klass, long_description = fcompiler_aliases[compiler]
+    else:
+        msg = "don't know how to compile Fortran code on platform '%s'" % plat
+        if compiler is not None:
+            msg = msg + " with '%s' compiler." % compiler
+            msg = msg + " Supported compilers are: %s)" \
+                  % (','.join(fcompiler_class.keys()))
+        log.warn(msg)
+        failed_fcompilers.add(fcompiler_key)
+        return None
+
+    compiler = klass(verbose=verbose, dry_run=dry_run, force=force)
+    compiler.c_compiler = c_compiler
+    return compiler
+
+def show_fcompilers(dist=None):
+    """Print list of available compilers (used by the "--help-fcompiler"
+    option to "config_fc").
+    """
+    if dist is None:
+        from distutils.dist import Distribution
+        from numpy.distutils.command.config_compiler import config_fc
+        dist = Distribution()
+        dist.script_name = os.path.basename(sys.argv[0])
+        dist.script_args = ['config_fc'] + sys.argv[1:]
+        try:
+            dist.script_args.remove('--help-fcompiler')
+        except ValueError:
+            pass
+        dist.cmdclass['config_fc'] = config_fc
+        dist.parse_config_files()
+        dist.parse_command_line()
+    compilers = []
+    compilers_na = []
+    compilers_ni = []
+    if not fcompiler_class:
+        load_all_fcompiler_classes()
+    platform_compilers = available_fcompilers_for_platform()
+    for compiler in platform_compilers:
+        v = None
+        log.set_verbosity(-2)
+        try:
+            c = new_fcompiler(compiler=compiler, verbose=dist.verbose)
+            c.customize(dist)
+            v = c.get_version()
+        except (DistutilsModuleError, CompilerNotFound):
+            e = get_exception()
+            log.debug("show_fcompilers: %s not found" % (compiler,))
+            log.debug(repr(e))
+
+        if v is None:
+            compilers_na.append(("fcompiler="+compiler, None,
+                              fcompiler_class[compiler][2]))
+        else:
+            c.dump_properties()
+            compilers.append(("fcompiler="+compiler, None,
+                              fcompiler_class[compiler][2] + ' (%s)' % v))
+
+    compilers_ni = list(set(fcompiler_class.keys()) - set(platform_compilers))
+    compilers_ni = [("fcompiler="+fc, None, fcompiler_class[fc][2])
+                    for fc in compilers_ni]
+
+    compilers.sort()
+    compilers_na.sort()
+    compilers_ni.sort()
+    pretty_printer = FancyGetopt(compilers)
+    pretty_printer.print_help("Fortran compilers found:")
+    pretty_printer = FancyGetopt(compilers_na)
+    pretty_printer.print_help("Compilers available for this "
+                              "platform, but not found:")
+    if compilers_ni:
+        pretty_printer = FancyGetopt(compilers_ni)
+        pretty_printer.print_help("Compilers not available on this platform:")
+    print("For compiler details, run 'config_fc --verbose' setup command.")
+
+
+def dummy_fortran_file():
+    fo, name = make_temp_file(suffix='.f')
+    fo.write("      subroutine dummy()\n      end\n")
+    fo.close()
+    return name[:-2]
+
+
+is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
+_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
+_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]', re.I).match
+
+def is_free_format(file):
+    """Check if file is in free format Fortran."""
+    # f90 allows both fixed and free format, assuming fixed unless
+    # signs of free format are detected.
+    result = 0
+    f = open_latin1(file, 'r')
+    line = f.readline()
+    n = 10000 # the number of non-comment lines to scan for hints
+    if _has_f_header(line):
+        n = 0
+    elif _has_f90_header(line):
+        n = 0
+        result = 1
+    while n>0 and line:
+        line = line.rstrip()
+        if line and line[0]!='!':
+            n -= 1
+            if (line[0]!='\t' and _free_f90_start(line[:5])) or line[-1:]=='&':
+                result = 1
+                break
+        line = f.readline()
+    f.close()
+    return result
+
+def has_f90_header(src):
+    f = open_latin1(src, 'r')
+    line = f.readline()
+    f.close()
+    return _has_f90_header(line) or _has_fix_header(line)
+
+_f77flags_re = re.compile(r'(c|)f77flags\s*\(\s*(?P<fcname>\w+)\s*\)\s*=\s*(?P<fflags>.*)', re.I)
+def get_f77flags(src):
+    """
+    Search the first 20 lines of fortran 77 code for line pattern
+      `CF77FLAGS(<fcompiler type>)=<f77 flags>`
+    Return a dictionary {<fcompiler type>:<f77 flags>}.
+    """
+    flags = {}
+    f = open_latin1(src, 'r')
+    i = 0
+    for line in f:
+        i += 1
+        if i>20: break
+        m = _f77flags_re.match(line)
+        if not m: continue
+        fcname = m.group('fcname').strip()
+        fflags = m.group('fflags').strip()
+        flags[fcname] = split_quoted(fflags)
+    f.close()
+    return flags
+
+# TODO: implement get_f90flags and use it in _compile similarly to get_f77flags
+
+if __name__ == '__main__':
+    show_fcompilers()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
new file mode 100644
index 0000000000..bde0529bea
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
@@ -0,0 +1,160 @@
+
+# http://www.absoft.com/literature/osxuserguide.pdf
+# http://www.absoft.com/documentation.html
+
+# Notes:
+# - when using -g77 then use -DUNDERSCORE_G77 to compile f2py
+#   generated extension modules (works for f2py v2.45.241_1936 and up)
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.cpuinfo import cpu
+from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
+from numpy.distutils.misc_util import cyg2win32
+
+compilers = ['AbsoftFCompiler']
+
+class AbsoftFCompiler(FCompiler):
+
+    compiler_type = 'absoft'
+    description = 'Absoft Corp Fortran Compiler'
+    #version_pattern = r'FORTRAN 77 Compiler (?P<version>[^\s*,]*).*?Absoft Corp'
+    version_pattern = r'(f90:.*?(Absoft Pro FORTRAN Version|FORTRAN 77 Compiler|Absoft Fortran Compiler Version|Copyright Absoft Corporation.*?Version))'+\
+                       r' (?P<version>[^\s*,]*)(.*?Absoft Corp|)'
+
+    # on windows: f90 -V -c dummy.f
+    # f90: Copyright Absoft Corporation 1994-1998 mV2; Cray Research, Inc. 1994-1996 CF90 (2.x.x.x  f36t87) Version 2.3 Wed Apr 19, 2006  13:05:16
+
+    # samt5735(8)$ f90 -V -c dummy.f
+    # f90: Copyright Absoft Corporation 1994-2002; Absoft Pro FORTRAN Version 8.0
+    # Note that fink installs g77 as f77, so need to use f90 for detection.
+
+    executables = {
+        'version_cmd'  : None,          # set by update_executables
+        'compiler_f77' : ["f77"],
+        'compiler_fix' : ["f90"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    if os.name=='nt':
+        library_switch = '/out:'      #No space after /out:!
+
+    module_dir_switch = None
+    module_include_switch = '-p'
+
+    def update_executables(self):
+        f = cyg2win32(dummy_fortran_file())
+        self.executables['version_cmd'] = ['<F90>', '-V', '-c',
+                                           f+'.f', '-o', f+'.o']
+
+    def get_flags_linker_so(self):
+        if os.name=='nt':
+            opt = ['/dll']
+        # The "-K shared" switches are being left in for pre-9.0 versions
+        # of Absoft though I don't think versions earlier than 9 can
+        # actually be used to build shared libraries.  In fact, version
+        # 8 of Absoft doesn't recognize "-K shared" and will fail.
+        elif self.get_version() >= '9.0':
+            opt = ['-shared']
+        else:
+            opt = ["-K", "shared"]
+        return opt
+
+    def library_dir_option(self, dir):
+        if os.name=='nt':
+            return ['-link', '/PATH:"%s"' % (dir)]
+        return "-L" + dir
+
+    def library_option(self, lib):
+        if os.name=='nt':
+            return '%s.lib' % (lib)
+        return "-l" + lib
+
+    def get_library_dirs(self):
+        opt = FCompiler.get_library_dirs(self)
+        d = os.environ.get('ABSOFT')
+        if d:
+            if self.get_version() >= '10.0':
+                # use shared libraries, the static libraries were not compiled -fPIC
+                prefix = 'sh'
+            else:
+                prefix = ''
+            if cpu.is_64bit():
+                suffix = '64'
+            else:
+                suffix = ''
+            opt.append(os.path.join(d, '%slib%s' % (prefix, suffix)))
+        return opt
+
+    def get_libraries(self):
+        opt = FCompiler.get_libraries(self)
+        if self.get_version() >= '11.0':
+            opt.extend(['af90math', 'afio', 'af77math', 'amisc'])
+        elif self.get_version() >= '10.0':
+            opt.extend(['af90math', 'afio', 'af77math', 'U77'])
+        elif self.get_version() >= '8.0':
+            opt.extend(['f90math', 'fio', 'f77math', 'U77'])
+        else:
+            opt.extend(['fio', 'f90math', 'fmath', 'U77'])
+        if os.name =='nt':
+            opt.append('COMDLG32')
+        return opt
+
+    def get_flags(self):
+        opt = FCompiler.get_flags(self)
+        if os.name != 'nt':
+            opt.extend(['-s'])
+            if self.get_version():
+                if self.get_version()>='8.2':
+                    opt.append('-fpic')
+        return opt
+
+    def get_flags_f77(self):
+        opt = FCompiler.get_flags_f77(self)
+        opt.extend(['-N22', '-N90', '-N110'])
+        v = self.get_version()
+        if os.name == 'nt':
+            if v and v>='8.0':
+                opt.extend(['-f', '-N15'])
+        else:
+            opt.append('-f')
+            if v:
+                if v<='4.6':
+                    opt.append('-B108')
+                else:
+                    # Though -N15 is undocumented, it works with
+                    # Absoft 8.0 on Linux
+                    opt.append('-N15')
+        return opt
+
+    def get_flags_f90(self):
+        opt = FCompiler.get_flags_f90(self)
+        opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX",
+                    "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"])
+        if self.get_version():
+            if self.get_version()>'4.6':
+                opt.extend(["-YDEALLOC=ALL"])
+        return opt
+
+    def get_flags_fix(self):
+        opt = FCompiler.get_flags_fix(self)
+        opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX",
+                    "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"])
+        opt.extend(["-f", "fixed"])
+        return opt
+
+    def get_flags_opt(self):
+        opt = ['-O']
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='absoft')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
new file mode 100644
index 0000000000..e25f244534
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
@@ -0,0 +1,128 @@
+
+#http://www.compaq.com/fortran/docs/
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.compat import get_exception
+from distutils.errors import DistutilsPlatformError
+
+compilers = ['CompaqFCompiler']
+if (os.name != 'posix' or sys.platform[:6] == 'cygwin') and not 'GCC' in sys.version:
+    # Otherwise we'd get a false positive on posix systems with
+    # case-insensitive filesystems (like darwin), because we'll pick
+    # up /bin/df
+    compilers.append('CompaqVisualFCompiler')
+
+class CompaqFCompiler(FCompiler):
+
+    compiler_type = 'compaq'
+    description = 'Compaq Fortran Compiler'
+    version_pattern = r'Compaq Fortran (?P<version>[^\s]*).*'
+
+    if sys.platform[:5]=='linux':
+        fc_exe = 'fort'
+    else:
+        fc_exe = 'f90'
+
+    executables = {
+        'version_cmd'  : ['<F90>', "-version"],
+        'compiler_f77' : [fc_exe, "-f77rtl", "-fixed"],
+        'compiler_fix' : [fc_exe, "-fixed"],
+        'compiler_f90' : [fc_exe],
+        'linker_so'    : ['<F90>'],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    module_dir_switch = '-module ' # not tested
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        return ['-assume no2underscore', '-nomixed_str_len_arg']
+    def get_flags_debug(self):
+        return ['-g', '-check bounds']
+    def get_flags_opt(self):
+        return ['-O4', '-align dcommons', '-assume bigarrays',
+                '-assume nozsize', '-math_library fast']
+    def get_flags_arch(self):
+        return ['-arch host', '-tune host']
+    def get_flags_linker_so(self):
+        if sys.platform[:5]=='linux':
+            return ['-shared']
+        return ['-shared', '-Wl,-expect_unresolved,*']
+
+class CompaqVisualFCompiler(FCompiler):
+
+    compiler_type = 'compaqv'
+    description = 'DIGITAL or Compaq Visual Fortran Compiler'
+    version_pattern = r'(DIGITAL|Compaq) Visual Fortran Optimizing Compiler'\
+                      ' Version (?P<version>[^\s]*).*'
+
+    compile_switch = '/compile_only'
+    object_switch = '/object:'
+    library_switch = '/OUT:'      #No space after /OUT:!
+
+    static_lib_extension = ".lib"
+    static_lib_format = "%s%s"
+    module_dir_switch = '/module:'
+    module_include_switch = '/I'
+
+    ar_exe = 'lib.exe'
+    fc_exe = 'DF'
+
+    if sys.platform=='win32':
+        from numpy.distutils.msvccompiler import MSVCCompiler
+
+        try:
+            m = MSVCCompiler()
+            m.initialize()
+            ar_exe = m.lib
+        except DistutilsPlatformError:
+            pass
+        except AttributeError:
+            msg = get_exception()
+            if '_MSVCCompiler__root' in str(msg):
+                print('Ignoring "%s" (I think it is msvccompiler.py bug)' % (msg))
+            else:
+                raise
+        except IOError:
+            e = get_exception()
+            if not "vcvarsall.bat" in str(e):
+                print("Unexpected IOError in", __file__)
+                raise e
+        except ValueError:
+            e = get_exception()
+            if not "path']" in str(e):
+                print("Unexpected ValueError in", __file__)
+                raise e
+
+    executables = {
+        'version_cmd'  : ['<F90>', "/what"],
+        'compiler_f77' : [fc_exe, "/f77rtl", "/fixed"],
+        'compiler_fix' : [fc_exe, "/fixed"],
+        'compiler_f90' : [fc_exe],
+        'linker_so'    : ['<F90>'],
+        'archiver'     : [ar_exe, "/OUT:"],
+        'ranlib'       : None
+        }
+
+    def get_flags(self):
+        return ['/nologo', '/MD', '/WX', '/iface=(cref,nomixed_str_len_arg)',
+                '/names:lowercase', '/assume:underscore']
+    def get_flags_opt(self):
+        return ['/Ox', '/fast', '/optimize:5', '/unroll:0', '/math_library:fast']
+    def get_flags_arch(self):
+        return ['/threads']
+    def get_flags_debug(self):
+        return ['/debug']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='compaq')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
new file mode 100644
index 0000000000..26f73b530e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
@@ -0,0 +1,45 @@
+# http://g95.sourceforge.net/
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['G95FCompiler']
+
+class G95FCompiler(FCompiler):
+    compiler_type = 'g95'
+    description = 'G95 Fortran Compiler'
+
+#    version_pattern = r'G95 \((GCC (?P<gccversion>[\d.]+)|.*?) \(g95!\) (?P<version>.*)\).*'
+    # $ g95 --version
+    # G95 (GCC 4.0.3 (g95!) May 22 2006)
+
+    version_pattern = r'G95 \((GCC (?P<gccversion>[\d.]+)|.*?) \(g95 (?P<version>.*)!\) (?P<date>.*)\).*'
+    # $ g95 --version
+    # G95 (GCC 4.0.3 (g95 0.90!) Aug 22 2006)
+
+    executables = {
+        'version_cmd'  : ["<F90>", "--version"],
+        'compiler_f77' : ["g95", "-ffixed-form"],
+        'compiler_fix' : ["g95", "-ffixed-form"],
+        'compiler_f90' : ["g95"],
+        'linker_so'    : ["<F90>", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    pic_flags = ['-fpic']
+    module_dir_switch = '-fmod='
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        return ['-fno-second-underscore']
+    def get_flags_opt(self):
+        return ['-O']
+    def get_flags_debug(self):
+        return ['-g']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    compiler = G95FCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
new file mode 100644
index 0000000000..dcca73c9ce
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
@@ -0,0 +1,391 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+import os
+import sys
+import warnings
+import platform
+import tempfile
+from subprocess import Popen, PIPE, STDOUT
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.misc_util import msvc_runtime_library
+from numpy.distutils.compat import get_exception
+
+compilers = ['GnuFCompiler', 'Gnu95FCompiler']
+
+TARGET_R = re.compile("Target: ([a-zA-Z0-9_\-]*)")
+
+# XXX: handle cross compilation
+def is_win64():
+    return sys.platform == "win32" and platform.architecture()[0] == "64bit"
+
+if is_win64():
+    #_EXTRAFLAGS = ["-fno-leading-underscore"]
+    _EXTRAFLAGS = []
+else:
+    _EXTRAFLAGS = []
+
+class GnuFCompiler(FCompiler):
+    compiler_type = 'gnu'
+    compiler_aliases = ('g77',)
+    description = 'GNU Fortran 77 compiler'
+
+    def gnu_version_match(self, version_string):
+        """Handle the different versions of GNU fortran compilers"""
+        # Strip warning(s) that may be emitted by gfortran
+        while version_string.startswith('gfortran: warning'):
+            version_string = version_string[version_string.find('\n')+1:]
+
+        # Gfortran versions from after 2010 will output a simple string
+        # (usually "x.y", "x.y.z" or "x.y.z-q") for ``-dumpversion``; older
+        # gfortrans may still return long version strings (``-dumpversion`` was
+        # an alias for ``--version``)
+        if len(version_string) <= 20:
+            # Try to find a valid version string
+            m = re.search(r'([0-9.]+)', version_string)
+            if m:
+                # g77 provides a longer version string that starts with GNU
+                # Fortran
+                if version_string.startswith('GNU Fortran'):
+                    return ('g77', m.group(1))
+
+                # gfortran only outputs a version string such as #.#.#, so check
+                # if the match is at the start of the string
+                elif m.start() == 0:
+                    return ('gfortran', m.group(1))
+        else:
+            # Output probably from --version, try harder:
+            m = re.search(r'GNU Fortran\s+95.*?([0-9-.]+)', version_string)
+            if m:
+                return ('gfortran', m.group(1))
+            m = re.search(r'GNU Fortran.*?\-?(\d*(?:\.\d+)+)', version_string)
+            if m:
+                v = m.group(1)
+                if v.startswith('0') or v.startswith('2') or v.startswith('3'):
+                    # the '0' is for early g77's
+                    return ('g77', v)
+                else:
+                    # at some point in the 4.x series, the ' 95' was dropped
+                    # from the version string
+                    return ('gfortran', v)
+
+        # If still nothing, raise an error to make the problem easy to find.
+        err = 'A valid Fortran version was not found in this string:\n'
+        raise ValueError(err + version_string)
+
+    def version_match(self, version_string):
+        v = self.gnu_version_match(version_string)
+        if not v or v[0] != 'g77':
+            return None
+        return v[1]
+
+    possible_executables = ['g77', 'f77']
+    executables = {
+        'version_cmd'  : [None, "-dumpversion"],
+        'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"],
+        'compiler_f90' : None,  # Use --fcompiler=gnu95 for f90 codes
+        'compiler_fix' : None,
+        'linker_so'    : [None, "-g", "-Wall"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"],
+        'linker_exe'   : [None, "-g", "-Wall"]
+        }
+    module_dir_switch = None
+    module_include_switch = None
+
+    # Cygwin: f771: warning: -fPIC ignored for target (all code is
+    # position independent)
+    if os.name != 'nt' and sys.platform != 'cygwin':
+        pic_flags = ['-fPIC']
+
+    # use -mno-cygwin for g77 when Python is not Cygwin-Python
+    if sys.platform == 'win32' and not 'GCC' in sys.version:
+        for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']:
+            executables[key].append('-mno-cygwin')
+
+    g2c = 'g2c'
+    suggested_f90_compiler = 'gnu95'
+
+    def get_flags_linker_so(self):
+        opt = self.linker_so[1:]
+        if sys.platform == 'darwin':
+            target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
+            # If MACOSX_DEPLOYMENT_TARGET is set, we simply trust the value
+            # and leave it alone.  But, distutils will complain if the
+            # environment's value is different from the one in the Python
+            # Makefile used to build Python.  We let disutils handle this
+            # error checking.
+            if not target:
+                # If MACOSX_DEPLOYMENT_TARGET is not set in the environment,
+                # we try to get it first from the Python Makefile and then we
+                # fall back to setting it to 10.3 to maximize the set of
+                # versions we can work with.  This is a reasonable default
+                # even when using the official Python dist and those derived
+                # from it.
+                import distutils.sysconfig as sc
+                g = {}
+                filename = sc.get_makefile_filename()
+                sc.parse_makefile(filename, g)
+                target = g.get('MACOSX_DEPLOYMENT_TARGET', '10.3')
+                os.environ['MACOSX_DEPLOYMENT_TARGET'] = target
+                if target == '10.3':
+                    s = 'Env. variable MACOSX_DEPLOYMENT_TARGET set to 10.3'
+                    warnings.warn(s)
+
+            opt.extend(['-undefined', 'dynamic_lookup', '-bundle'])
+        else:
+            opt.append("-shared")
+        if sys.platform.startswith('sunos'):
+            # SunOS often has dynamically loaded symbols defined in the
+            # static library libg2c.a  The linker doesn't like this.  To
+            # ignore the problem, use the -mimpure-text flag.  It isn't
+            # the safest thing, but seems to work. 'man gcc' says:
+            # ".. Instead of using -mimpure-text, you should compile all
+            #  source code with -fpic or -fPIC."
+            opt.append('-mimpure-text')
+        return opt
+
+    def get_libgcc_dir(self):
+        status, output = exec_command(self.compiler_f77 +
+                                      ['-print-libgcc-file-name'],
+                                      use_tee=0)
+        if not status:
+            return os.path.dirname(output)
+        return None
+
+    def get_library_dirs(self):
+        opt = []
+        if sys.platform[:5] != 'linux':
+            d = self.get_libgcc_dir()
+            if d:
+                # if windows and not cygwin, libg2c lies in a different folder
+                if sys.platform == 'win32' and not d.startswith('/usr/lib'):
+                    d = os.path.normpath(d)
+                    path = os.path.join(d, "lib%s.a" % self.g2c)
+                    if not os.path.exists(path):
+                        root = os.path.join(d, *((os.pardir,)*4))
+                        d2 = os.path.abspath(os.path.join(root, 'lib'))
+                        path = os.path.join(d2, "lib%s.a" % self.g2c)
+                        if os.path.exists(path):
+                            opt.append(d2)
+                opt.append(d)
+        return opt
+
+    def get_libraries(self):
+        opt = []
+        d = self.get_libgcc_dir()
+        if d is not None:
+            g2c = self.g2c + '-pic'
+            f = self.static_lib_format % (g2c, self.static_lib_extension)
+            if not os.path.isfile(os.path.join(d, f)):
+                g2c = self.g2c
+        else:
+            g2c = self.g2c
+
+        if g2c is not None:
+            opt.append(g2c)
+        c_compiler = self.c_compiler
+        if sys.platform == 'win32' and c_compiler and \
+               c_compiler.compiler_type == 'msvc':
+            # the following code is not needed (read: breaks) when using MinGW
+            # in case want to link F77 compiled code with MSVC
+            opt.append('gcc')
+            runtime_lib = msvc_runtime_library()
+            if runtime_lib:
+                opt.append(runtime_lib)
+        if sys.platform == 'darwin':
+            opt.append('cc_dynamic')
+        return opt
+
+    def get_flags_debug(self):
+        return ['-g']
+
+    def get_flags_opt(self):
+        v = self.get_version()
+        if v and v <= '3.3.3':
+            # With this compiler version building Fortran BLAS/LAPACK
+            # with -O3 caused failures in lib.lapack heevr,syevr tests.
+            opt = ['-O2']
+        else:
+            opt = ['-O3']
+        opt.append('-funroll-loops')
+        return opt
+
+    def _c_arch_flags(self):
+        """ Return detected arch flags from CFLAGS """
+        from distutils import sysconfig
+        try:
+            cflags = sysconfig.get_config_vars()['CFLAGS']
+        except KeyError:
+            return []
+        arch_re = re.compile(r"-arch\s+(\w+)")
+        arch_flags = []
+        for arch in arch_re.findall(cflags):
+            arch_flags += ['-arch', arch]
+        return arch_flags
+
+    def get_flags_arch(self):
+        return []
+
+    def runtime_library_dir_option(self, dir):
+        return '-Wl,-rpath="%s"' % dir
+
+class Gnu95FCompiler(GnuFCompiler):
+    compiler_type = 'gnu95'
+    compiler_aliases = ('gfortran',)
+    description = 'GNU Fortran 95 compiler'
+
+    def version_match(self, version_string):
+        v = self.gnu_version_match(version_string)
+        if not v or v[0] != 'gfortran':
+            return None
+        v = v[1]
+        if v >= '4.':
+            # gcc-4 series releases do not support -mno-cygwin option
+            pass
+        else:
+            # use -mno-cygwin flag for gfortran when Python is not
+            # Cygwin-Python
+            if sys.platform == 'win32':
+                for key in ['version_cmd', 'compiler_f77', 'compiler_f90',
+                            'compiler_fix', 'linker_so', 'linker_exe']:
+                    self.executables[key].append('-mno-cygwin')
+        return v
+
+    possible_executables = ['gfortran', 'f95']
+    executables = {
+        'version_cmd'  : ["<F90>", "-dumpversion"],
+        'compiler_f77' : [None, "-Wall", "-g", "-ffixed-form",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'compiler_f90' : [None, "-Wall", "-g",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'compiler_fix' : [None, "-Wall",  "-g","-ffixed-form",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'linker_so'    : ["<F90>", "-Wall", "-g"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"],
+        'linker_exe'   : [None, "-Wall"]
+        }
+
+    module_dir_switch = '-J'
+    module_include_switch = '-I'
+
+    g2c = 'gfortran'
+
+    def _universal_flags(self, cmd):
+        """Return a list of -arch flags for every supported architecture."""
+        if not sys.platform == 'darwin':
+            return []
+        arch_flags = []
+        # get arches the C compiler gets.
+        c_archs = self._c_arch_flags()
+        if "i386" in c_archs:
+            c_archs[c_archs.index("i386")] = "i686"
+        # check the arches the Fortran compiler supports, and compare with
+        # arch flags from C compiler
+        for arch in ["ppc", "i686", "x86_64", "ppc64"]:
+            if _can_target(cmd, arch) and arch in c_archs:
+                arch_flags.extend(["-arch", arch])
+        return arch_flags
+
+    def get_flags(self):
+        flags = GnuFCompiler.get_flags(self)
+        arch_flags = self._universal_flags(self.compiler_f90)
+        if arch_flags:
+            flags[:0] = arch_flags
+        return flags
+
+    def get_flags_linker_so(self):
+        flags = GnuFCompiler.get_flags_linker_so(self)
+        arch_flags = self._universal_flags(self.linker_so)
+        if arch_flags:
+            flags[:0] = arch_flags
+        return flags
+
+    def get_library_dirs(self):
+        opt = GnuFCompiler.get_library_dirs(self)
+        if sys.platform == 'win32':
+            c_compiler = self.c_compiler
+            if c_compiler and c_compiler.compiler_type == "msvc":
+                target = self.get_target()
+                if target:
+                    d = os.path.normpath(self.get_libgcc_dir())
+                    root = os.path.join(d, *((os.pardir,)*4))
+                    path = os.path.join(root, "lib")
+                    mingwdir = os.path.normpath(path)
+                    if os.path.exists(os.path.join(mingwdir, "libmingwex.a")):
+                        opt.append(mingwdir)
+        return opt
+
+    def get_libraries(self):
+        opt = GnuFCompiler.get_libraries(self)
+        if sys.platform == 'darwin':
+            opt.remove('cc_dynamic')
+        if sys.platform == 'win32':
+            c_compiler = self.c_compiler
+            if c_compiler and c_compiler.compiler_type == "msvc":
+                if "gcc" in opt:
+                    i = opt.index("gcc")
+                    opt.insert(i+1, "mingwex")
+                    opt.insert(i+1, "mingw32")
+            # XXX: fix this mess, does not work for mingw
+            if is_win64():
+                c_compiler = self.c_compiler
+                if c_compiler and c_compiler.compiler_type == "msvc":
+                    return []
+                else:
+                    pass
+        return opt
+
+    def get_target(self):
+        status, output = exec_command(self.compiler_f77 +
+                                      ['-v'],
+                                      use_tee=0)
+        if not status:
+            m = TARGET_R.search(output)
+            if m:
+                return m.group(1)
+        return ""
+
+    def get_flags_opt(self):
+        if is_win64():
+            return ['-O0']
+        else:
+            return GnuFCompiler.get_flags_opt(self)
+
+def _can_target(cmd, arch):
+    """Return true if the architecture supports the -arch flag"""
+    newcmd = cmd[:]
+    fid, filename = tempfile.mkstemp(suffix=".f")
+    try:
+        d = os.path.dirname(filename)
+        output = os.path.splitext(filename)[0] + ".o"
+        try:
+            newcmd.extend(["-arch", arch, "-c", filename])
+            p = Popen(newcmd, stderr=STDOUT, stdout=PIPE, cwd=d)
+            p.communicate()
+            return p.returncode == 0
+        finally:
+            if os.path.exists(output):
+                os.remove(output)
+    finally:
+        os.remove(filename)
+    return False
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+
+    compiler = GnuFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
+
+    try:
+        compiler = Gnu95FCompiler()
+        compiler.customize()
+        print(compiler.get_version())
+    except Exception:
+        msg = get_exception()
+        print(msg)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
new file mode 100644
index 0000000000..9004961e1d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
@@ -0,0 +1,45 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['HPUXFCompiler']
+
+class HPUXFCompiler(FCompiler):
+
+    compiler_type = 'hpux'
+    description = 'HP Fortran 90 Compiler'
+    version_pattern =  r'HP F90 (?P<version>[^\s*,]*)'
+
+    executables = {
+        'version_cmd'  : ["f90", "+version"],
+        'compiler_f77' : ["f90"],
+        'compiler_fix' : ["f90"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["ld", "-b"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = None #XXX: fix me
+    module_include_switch = None #XXX: fix me
+    pic_flags = ['+Z']
+    def get_flags(self):
+        return self.pic_flags + ['+ppu', '+DD64']
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_libraries(self):
+        return ['m']
+    def get_library_dirs(self):
+        opt = ['/usr/lib/hpux64']
+        return opt
+    def get_version(self, force=0, ok_status=[256, 0, 1]):
+        # XXX status==256 may indicate 'unrecognized option' or
+        #     'no input file'. So, version_cmd needs more work.
+        return FCompiler.get_version(self, force, ok_status)
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(10)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='hpux')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
new file mode 100644
index 0000000000..cc65df9721
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
@@ -0,0 +1,96 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.exec_command import exec_command, find_executable
+from numpy.distutils.misc_util import make_temp_file
+from distutils import log
+
+compilers = ['IBMFCompiler']
+
+class IBMFCompiler(FCompiler):
+    compiler_type = 'ibm'
+    description = 'IBM XL Fortran Compiler'
+    version_pattern =  r'(xlf\(1\)\s*|)IBM XL Fortran ((Advanced Edition |)Version |Enterprise Edition V|for AIX, V)(?P<version>[^\s*]*)'
+    #IBM XL Fortran Enterprise Edition V10.1 for AIX \nVersion: 10.01.0000.0004
+
+    executables = {
+        'version_cmd'  : ["<F77>", "-qversion"],
+        'compiler_f77' : ["xlf"],
+        'compiler_fix' : ["xlf90", "-qfixed"],
+        'compiler_f90' : ["xlf90"],
+        'linker_so'    : ["xlf95"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_version(self,*args,**kwds):
+        version = FCompiler.get_version(self,*args,**kwds)
+
+        if version is None and sys.platform.startswith('aix'):
+            # use lslpp to find out xlf version
+            lslpp = find_executable('lslpp')
+            xlf = find_executable('xlf')
+            if os.path.exists(xlf) and os.path.exists(lslpp):
+                s, o = exec_command(lslpp + ' -Lc xlfcmp')
+                m = re.search('xlfcmp:(?P<version>\d+([.]\d+)+)', o)
+                if m: version = m.group('version')
+
+        xlf_dir = '/etc/opt/ibmcmp/xlf'
+        if version is None and os.path.isdir(xlf_dir):
+            # linux:
+            # If the output of xlf does not contain version info
+            # (that's the case with xlf 8.1, for instance) then
+            # let's try another method:
+            l = sorted(os.listdir(xlf_dir))
+            l.reverse()
+            l = [d for d in l if os.path.isfile(os.path.join(xlf_dir, d, 'xlf.cfg'))]
+            if l:
+                from distutils.version import LooseVersion
+                self.version = version = LooseVersion(l[0])
+        return version
+
+    def get_flags(self):
+        return ['-qextname']
+
+    def get_flags_debug(self):
+        return ['-g']
+
+    def get_flags_linker_so(self):
+        opt = []
+        if sys.platform=='darwin':
+            opt.append('-Wl,-bundle,-flat_namespace,-undefined,suppress')
+        else:
+            opt.append('-bshared')
+        version = self.get_version(ok_status=[0, 40])
+        if version is not None:
+            if sys.platform.startswith('aix'):
+                xlf_cfg = '/etc/xlf.cfg'
+            else:
+                xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version
+            fo, new_cfg = make_temp_file(suffix='_xlf.cfg')
+            log.info('Creating '+new_cfg)
+            fi = open(xlf_cfg, 'r')
+            crt1_match = re.compile(r'\s*crt\s*[=]\s*(?P<path>.*)/crt1.o').match
+            for line in fi:
+                m = crt1_match(line)
+                if m:
+                    fo.write('crt = %s/bundle1.o\n' % (m.group('path')))
+                else:
+                    fo.write(line)
+            fi.close()
+            fo.close()
+            opt.append('-F'+new_cfg)
+        return opt
+
+    def get_flags_opt(self):
+        return ['-O3']
+
+if __name__ == '__main__':
+    log.set_verbosity(2)
+    compiler = IBMFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
new file mode 100644
index 0000000000..c4f15a073a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
@@ -0,0 +1,217 @@
+# http://developer.intel.com/software/products/compilers/flin/
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from numpy.distutils.ccompiler import simple_version_match
+from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
+
+compilers = ['IntelFCompiler', 'IntelVisualFCompiler',
+             'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler',
+             'IntelEM64VisualFCompiler', 'IntelEM64TFCompiler']
+
+
+def intel_version_match(type):
+    # Match against the important stuff in the version string
+    return simple_version_match(start=r'Intel.*?Fortran.*?(?:%s).*?Version' % (type,))
+
+
+class BaseIntelFCompiler(FCompiler):
+    def update_executables(self):
+        f = dummy_fortran_file()
+        self.executables['version_cmd'] = ['<F77>', '-FI', '-V', '-c',
+                                           f + '.f', '-o', f + '.o']
+
+    def runtime_library_dir_option(self, dir):
+        return '-Wl,-rpath="%s"' % dir
+
+
+class IntelFCompiler(BaseIntelFCompiler):
+
+    compiler_type = 'intel'
+    compiler_aliases = ('ifort',)
+    description = 'Intel Fortran Compiler for 32-bit apps'
+    version_match = intel_version_match('32-bit|IA-32')
+
+    possible_executables = ['ifort', 'ifc']
+
+    executables = {
+        'version_cmd'  : None,          # set by update_executables
+        'compiler_f77' : [None, "-72", "-w90", "-w95"],
+        'compiler_f90' : [None],
+        'compiler_fix' : [None, "-FI"],
+        'linker_so'    : ["<F90>", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    pic_flags = ['-fPIC']
+    module_dir_switch = '-module '  # Don't remove ending space!
+    module_include_switch = '-I'
+
+    def get_flags_free(self):
+        return ['-FR']
+
+    def get_flags(self):
+        return ['-fPIC']
+
+    def get_flags_opt(self):  # Scipy test failures with -O2
+        return ['-xhost -openmp -fp-model strict -O1']
+
+    def get_flags_arch(self):
+        return []
+
+    def get_flags_linker_so(self):
+        opt = FCompiler.get_flags_linker_so(self)
+        v = self.get_version()
+        if v and v >= '8.0':
+            opt.append('-nofor_main')
+        if sys.platform == 'darwin':
+            # Here, it's -dynamiclib
+            try:
+                idx = opt.index('-shared')
+                opt.remove('-shared')
+            except ValueError:
+                idx = 0
+            opt[idx:idx] = ['-dynamiclib', '-Wl,-undefined,dynamic_lookup']
+        return opt
+
+
+class IntelItaniumFCompiler(IntelFCompiler):
+    compiler_type = 'intele'
+    compiler_aliases = ()
+    description = 'Intel Fortran Compiler for Itanium apps'
+
+    version_match = intel_version_match('Itanium|IA-64')
+
+    possible_executables = ['ifort', 'efort', 'efc']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI", "-w90", "-w95"],
+        'compiler_fix' : [None, "-FI"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+
+class IntelEM64TFCompiler(IntelFCompiler):
+    compiler_type = 'intelem'
+    compiler_aliases = ()
+    description = 'Intel Fortran Compiler for 64-bit apps'
+
+    version_match = intel_version_match('EM64T-based|Intel\\(R\\) 64|64|IA-64|64-bit')
+
+    possible_executables = ['ifort', 'efort', 'efc']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI"],
+        'compiler_fix' : [None, "-FI"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_flags(self):
+        return ['-fPIC']
+
+    def get_flags_opt(self):  # Scipy test failures with -O2
+        return ['-openmp -fp-model strict -O1']
+
+    def get_flags_arch(self):
+        return ['-xSSE4.2']
+
+# Is there no difference in the version string between the above compilers
+# and the Visual compilers?
+
+
+class IntelVisualFCompiler(BaseIntelFCompiler):
+    compiler_type = 'intelv'
+    description = 'Intel Visual Fortran Compiler for 32-bit apps'
+    version_match = intel_version_match('32-bit|IA-32')
+
+    def update_executables(self):
+        f = dummy_fortran_file()
+        self.executables['version_cmd'] = ['<F77>', '/FI', '/c',
+                                           f + '.f', '/o', f + '.o']
+
+    ar_exe = 'lib.exe'
+    possible_executables = ['ifort', 'ifl']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None],
+        'compiler_fix' : [None],
+        'compiler_f90' : [None],
+        'linker_so'    : [None],
+        'archiver'     : [ar_exe, "/verbose", "/OUT:"],
+        'ranlib'       : None
+        }
+
+    compile_switch = '/c '
+    object_switch = '/Fo'     # No space after /Fo!
+    library_switch = '/OUT:'  # No space after /OUT:!
+    module_dir_switch = '/module:'  # No space after /module:
+    module_include_switch = '/I'
+
+    def get_flags(self):
+        opt = ['/nologo', '/MD', '/nbs', '/names:lowercase', '/assume:underscore']
+        return opt
+
+    def get_flags_free(self):
+        return []
+
+    def get_flags_debug(self):
+        return ['/4Yb', '/d2']
+
+    def get_flags_opt(self):
+        return ['/O1']  # Scipy test failures with /O2
+
+    def get_flags_arch(self):
+        return ["/arch:IA32", "/QaxSSE3"]
+
+    def runtime_library_dir_option(self, dir):
+        raise NotImplementedError
+
+
+class IntelItaniumVisualFCompiler(IntelVisualFCompiler):
+    compiler_type = 'intelev'
+    description = 'Intel Visual Fortran Compiler for Itanium apps'
+
+    version_match = intel_version_match('Itanium')
+
+    possible_executables = ['efl']  # XXX this is a wild guess
+    ar_exe = IntelVisualFCompiler.ar_exe
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI", "-w90", "-w95"],
+        'compiler_fix' : [None, "-FI", "-4L72", "-w"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : [ar_exe, "/verbose", "/OUT:"],
+        'ranlib'       : None
+        }
+
+
+class IntelEM64VisualFCompiler(IntelVisualFCompiler):
+    compiler_type = 'intelvem'
+    description = 'Intel Visual Fortran Compiler for 64-bit apps'
+
+    version_match = simple_version_match(start='Intel\(R\).*?64,')
+
+    def get_flags_arch(self):
+        return ['/QaxSSE4.2']
+
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='intel')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
new file mode 100644
index 0000000000..7a33b4b63c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
@@ -0,0 +1,49 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['LaheyFCompiler']
+
+class LaheyFCompiler(FCompiler):
+
+    compiler_type = 'lahey'
+    description = 'Lahey/Fujitsu Fortran 95 Compiler'
+    version_pattern =  r'Lahey/Fujitsu Fortran 95 Compiler Release (?P<version>[^\s*]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "--version"],
+        'compiler_f77' : ["lf95", "--fix"],
+        'compiler_fix' : ["lf95", "--fix"],
+        'compiler_f90' : ["lf95"],
+        'linker_so'    : ["lf95", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    module_dir_switch = None  #XXX Fix me
+    module_include_switch = None #XXX Fix me
+
+    def get_flags_opt(self):
+        return ['-O']
+    def get_flags_debug(self):
+        return ['-g', '--chk', '--chkglobal']
+    def get_library_dirs(self):
+        opt = []
+        d = os.environ.get('LAHEY')
+        if d:
+            opt.append(os.path.join(d, 'lib'))
+        return opt
+    def get_libraries(self):
+        opt = []
+        opt.extend(['fj9f6', 'fj9i6', 'fj9ipp', 'fj9e6'])
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='lahey')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
new file mode 100644
index 0000000000..6a8d230992
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
@@ -0,0 +1,58 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.cpuinfo import cpu
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['MIPSFCompiler']
+
+class MIPSFCompiler(FCompiler):
+
+    compiler_type = 'mips'
+    description = 'MIPSpro Fortran Compiler'
+    version_pattern =  r'MIPSpro Compilers: Version (?P<version>[^\s*,]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-version"],
+        'compiler_f77' : ["f77", "-f77"],
+        'compiler_fix' : ["f90", "-fixedform"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["f90", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : None
+        }
+    module_dir_switch = None #XXX: fix me
+    module_include_switch = None #XXX: fix me
+    pic_flags = ['-KPIC']
+
+    def get_flags(self):
+        return self.pic_flags + ['-n32']
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_flags_arch(self):
+        opt = []
+        for a in '19 20 21 22_4k 22_5k 24 25 26 27 28 30 32_5k 32_10k'.split():
+            if getattr(cpu, 'is_IP%s'%a)():
+                opt.append('-TARG:platform=IP%s' % a)
+                break
+        return opt
+    def get_flags_arch_f77(self):
+        r = None
+        if cpu.is_r10000(): r = 10000
+        elif cpu.is_r12000(): r = 12000
+        elif cpu.is_r8000(): r = 8000
+        elif cpu.is_r5000(): r = 5000
+        elif cpu.is_r4000(): r = 4000
+        if r is not None:
+            return ['r%s' % (r)]
+        return []
+    def get_flags_arch_f90(self):
+        r = self.get_flags_arch_f77()
+        if r:
+            r[0] = '-' + r[0]
+        return r
+
+if __name__ == '__main__':
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='mips')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
new file mode 100644
index 0000000000..ae1b96faf3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
@@ -0,0 +1,45 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['NAGFCompiler']
+
+class NAGFCompiler(FCompiler):
+
+    compiler_type = 'nag'
+    description = 'NAGWare Fortran 95 Compiler'
+    version_pattern =  r'NAGWare Fortran 95 compiler Release (?P<version>[^\s]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-V"],
+        'compiler_f77' : ["f95", "-fixed"],
+        'compiler_fix' : ["f95", "-fixed"],
+        'compiler_f90' : ["f95"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_flags_linker_so(self):
+        if sys.platform=='darwin':
+            return ['-unsharedf95', '-Wl,-bundle,-flat_namespace,-undefined,suppress']
+        return ["-Wl,-shared"]
+    def get_flags_opt(self):
+        return ['-O4']
+    def get_flags_arch(self):
+        version = self.get_version()
+        if version and version < '5.1':
+            return ['-target=native']
+        else:
+            return ['']
+    def get_flags_debug(self):
+        return ['-g', '-gline', '-g90', '-nan', '-C']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='nag')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
new file mode 100644
index 0000000000..6f602d734d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
@@ -0,0 +1,31 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['NoneFCompiler']
+
+class NoneFCompiler(FCompiler):
+
+    compiler_type = 'none'
+    description = 'Fake Fortran compiler'
+
+    executables = {'compiler_f77': None,
+                   'compiler_f90': None,
+                   'compiler_fix': None,
+                   'linker_so': None,
+                   'linker_exe': None,
+                   'archiver': None,
+                   'ranlib': None,
+                   'version_cmd': None,
+                   }
+
+    def find_executables(self):
+        pass
+
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    compiler = NoneFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
new file mode 100644
index 0000000000..1902bbc242
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
@@ -0,0 +1,38 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['PathScaleFCompiler']
+
+class PathScaleFCompiler(FCompiler):
+
+    compiler_type = 'pathf95'
+    description = 'PathScale Fortran Compiler'
+    version_pattern =  r'PathScale\(TM\) Compiler Suite: Version (?P<version>[\d.]+)'
+
+    executables = {
+        'version_cmd'  : ["pathf95", "-version"],
+        'compiler_f77' : ["pathf95", "-fixedform"],
+        'compiler_fix' : ["pathf95", "-fixedform"],
+        'compiler_f90' : ["pathf95"],
+        'linker_so'    : ["pathf95", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+    }
+    pic_flags = ['-fPIC']
+    module_dir_switch = '-module ' # Don't remove ending space!
+    module_include_switch = '-I'
+
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_flags_debug(self):
+        return ['-g']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    #compiler = PathScaleFCompiler()
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='pathf95')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
new file mode 100644
index 0000000000..ee357c6d08
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
@@ -0,0 +1,63 @@
+# http://www.pgroup.com
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+from sys import platform
+
+compilers = ['PGroupFCompiler']
+
+class PGroupFCompiler(FCompiler):
+
+    compiler_type = 'pg'
+    description = 'Portland Group Fortran Compiler'
+    version_pattern =  r'\s*pg(f77|f90|hpf|fortran) (?P<version>[\d.-]+).*'
+
+    if platform == 'darwin':
+        executables = {
+        'version_cmd'  : ["<F77>", "-V"],
+        'compiler_f77' : ["pgfortran", "-dynamiclib"],
+        'compiler_fix' : ["pgfortran", "-Mfixed", "-dynamiclib"],
+        'compiler_f90' : ["pgfortran", "-dynamiclib"],
+        'linker_so'    : ["libtool"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+        pic_flags = ['']
+    else:
+        executables = {
+        'version_cmd'  : ["<F77>", "-V"],
+        'compiler_f77' : ["pgfortran"],
+        'compiler_fix' : ["pgfortran", "-Mfixed"],
+        'compiler_f90' : ["pgfortran"],
+        'linker_so'    : ["pgfortran", "-shared", "-fpic"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+        pic_flags = ['-fpic']
+
+
+    module_dir_switch = '-module '
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        opt = ['-Minform=inform', '-Mnosecond_underscore']
+        return self.pic_flags + opt
+    def get_flags_opt(self):
+        return ['-fast']
+    def get_flags_debug(self):
+        return ['-g']
+
+    if platform == 'darwin':
+        def get_flags_linker_so(self):
+            return ["-dynamic", '-undefined', 'dynamic_lookup']
+
+    def runtime_library_dir_option(self, dir):
+        return '-R"%s"' % dir
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='pg')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
new file mode 100644
index 0000000000..76ce1cabc6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
@@ -0,0 +1,55 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.ccompiler import simple_version_match
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['SunFCompiler']
+
+class SunFCompiler(FCompiler):
+
+    compiler_type = 'sun'
+    description = 'Sun or Forte Fortran 95 Compiler'
+    # ex:
+    # f90: Sun WorkShop 6 update 2 Fortran 95 6.2 Patch 111690-10 2003/08/28
+    version_match = simple_version_match(
+                      start=r'f9[05]: (Sun|Forte|WorkShop).*Fortran 95')
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-V"],
+        'compiler_f77' : ["f90"],
+        'compiler_fix' : ["f90", "-fixed"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>", "-Bdynamic", "-G"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = '-moddir='
+    module_include_switch = '-M'
+    pic_flags = ['-xcode=pic32']
+
+    def get_flags_f77(self):
+        ret = ["-ftrap=%none"]
+        if (self.get_version() or '') >= '7':
+            ret.append("-f77")
+        else:
+            ret.append("-fixed")
+        return ret
+    def get_opt(self):
+        return ['-fast', '-dalign']
+    def get_arch(self):
+        return ['-xtarget=generic']
+    def get_libraries(self):
+        opt = []
+        opt.extend(['fsu', 'sunmath', 'mvec'])
+        return opt
+
+    def runtime_library_dir_option(self, dir):
+        return '-R"%s"' % dir
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='sun')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
new file mode 100644
index 0000000000..05bbc10bad
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
@@ -0,0 +1,56 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.fcompiler.gnu import GnuFCompiler
+
+compilers = ['VastFCompiler']
+
+class VastFCompiler(GnuFCompiler):
+    compiler_type = 'vast'
+    compiler_aliases = ()
+    description = 'Pacific-Sierra Research Fortran 90 Compiler'
+    version_pattern = r'\s*Pacific-Sierra Research vf90 '\
+                      '(Personal|Professional)\s+(?P<version>[^\s]*)'
+
+    # VAST f90 does not support -o with -c. So, object files are created
+    # to the current directory and then moved to build directory
+    object_switch = ' && function _mvfile { mv -v `basename $1` $1 ; } && _mvfile '
+
+    executables = {
+        'version_cmd'  : ["vf90", "-v"],
+        'compiler_f77' : ["g77"],
+        'compiler_fix' : ["f90", "-Wv,-ya"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = None  #XXX Fix me
+    module_include_switch = None #XXX Fix me
+
+    def find_executables(self):
+        pass
+
+    def get_version_cmd(self):
+        f90 = self.compiler_f90[0]
+        d, b = os.path.split(f90)
+        vf90 = os.path.join(d, 'v'+b)
+        return vf90
+
+    def get_flags_arch(self):
+        vast_version = self.get_version()
+        gnu = GnuFCompiler()
+        gnu.customize(None)
+        self.version = gnu.get_version()
+        opt = GnuFCompiler.get_flags_arch(self)
+        self.version = vast_version
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='vast')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.py
new file mode 100644
index 0000000000..b7013ddf46
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.py
@@ -0,0 +1,256 @@
+#!/usr/bin/python2
+"""
+
+process_file(filename)
+
+  takes templated file .xxx.src and produces .xxx file where .xxx
+  is .pyf .f90 or .f using the following template rules:
+
+  '<..>' denotes a template.
+
+  All function and subroutine blocks in a source file with names that
+  contain '<..>' will be replicated according to the rules in '<..>'.
+
+  The number of comma-separeted words in '<..>' will determine the number of
+  replicates.
+
+  '<..>' may have two different forms, named and short. For example,
+
+  named:
+   <p=d,s,z,c> where anywhere inside a block '<p>' will be replaced with
+   'd', 's', 'z', and 'c' for each replicate of the block.
+
+   <_c>  is already defined: <_c=s,d,c,z>
+   <_t>  is already defined: <_t=real,double precision,complex,double complex>
+
+  short:
+   <s,d,c,z>, a short form of the named, useful when no <p> appears inside
+   a block.
+
+  In general, '<..>' contains a comma separated list of arbitrary
+  expressions. If these expression must contain a comma|leftarrow|rightarrow,
+  then prepend the comma|leftarrow|rightarrow with a backslash.
+
+  If an expression matches '\\<index>' then it will be replaced
+  by <index>-th expression.
+
+  Note that all '<..>' forms in a block must have the same number of
+  comma-separated entries.
+
+ Predefined named template rules:
+  <prefix=s,d,c,z>
+  <ftype=real,double precision,complex,double complex>
+  <ftypereal=real,double precision,\\0,\\1>
+  <ctype=float,double,complex_float,complex_double>
+  <ctypereal=float,double,\\0,\\1>
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['process_str', 'process_file']
+
+import os
+import sys
+import re
+
+routine_start_re = re.compile(r'(\n|\A)((     (\$|\*))|)\s*(subroutine|function)\b', re.I)
+routine_end_re = re.compile(r'\n\s*end\s*(subroutine|function)\b.*(\n|\Z)', re.I)
+function_start_re = re.compile(r'\n     (\$|\*)\s*function\b', re.I)
+
+def parse_structure(astr):
+    """ Return a list of tuples for each function or subroutine each
+    tuple is the start and end of a subroutine or function to be
+    expanded.
+    """
+
+    spanlist = []
+    ind = 0
+    while True:
+        m = routine_start_re.search(astr, ind)
+        if m is None:
+            break
+        start = m.start()
+        if function_start_re.match(astr, start, m.end()):
+            while True:
+                i = astr.rfind('\n', ind, start)
+                if i==-1:
+                    break
+                start = i
+                if astr[i:i+7]!='\n     $':
+                    break
+        start += 1
+        m = routine_end_re.search(astr, m.end())
+        ind = end = m and m.end()-1 or len(astr)
+        spanlist.append((start, end))
+    return spanlist
+
+template_re = re.compile(r"<\s*(\w[\w\d]*)\s*>")
+named_re = re.compile(r"<\s*(\w[\w\d]*)\s*=\s*(.*?)\s*>")
+list_re = re.compile(r"<\s*((.*?))\s*>")
+
+def find_repl_patterns(astr):
+    reps = named_re.findall(astr)
+    names = {}
+    for rep in reps:
+        name = rep[0].strip() or unique_key(names)
+        repl = rep[1].replace('\,', '@comma@')
+        thelist = conv(repl)
+        names[name] = thelist
+    return names
+
+item_re = re.compile(r"\A\\(?P<index>\d+)\Z")
+def conv(astr):
+    b = astr.split(',')
+    l = [x.strip() for x in b]
+    for i in range(len(l)):
+        m = item_re.match(l[i])
+        if m:
+            j = int(m.group('index'))
+            l[i] = l[j]
+    return ','.join(l)
+
+def unique_key(adict):
+    """ Obtain a unique key given a dictionary."""
+    allkeys = list(adict.keys())
+    done = False
+    n = 1
+    while not done:
+        newkey = '__l%s' % (n)
+        if newkey in allkeys:
+            n += 1
+        else:
+            done = True
+    return newkey
+
+
+template_name_re = re.compile(r'\A\s*(\w[\w\d]*)\s*\Z')
+def expand_sub(substr, names):
+    substr = substr.replace('\>', '@rightarrow@')
+    substr = substr.replace('\<', '@leftarrow@')
+    lnames = find_repl_patterns(substr)
+    substr = named_re.sub(r"<\1>", substr)  # get rid of definition templates
+
+    def listrepl(mobj):
+        thelist = conv(mobj.group(1).replace('\,', '@comma@'))
+        if template_name_re.match(thelist):
+            return "<%s>" % (thelist)
+        name = None
+        for key in lnames.keys():    # see if list is already in dictionary
+            if lnames[key] == thelist:
+                name = key
+        if name is None:      # this list is not in the dictionary yet
+            name = unique_key(lnames)
+            lnames[name] = thelist
+        return "<%s>" % name
+
+    substr = list_re.sub(listrepl, substr) # convert all lists to named templates
+                                           # newnames are constructed as needed
+
+    numsubs = None
+    base_rule = None
+    rules = {}
+    for r in template_re.findall(substr):
+        if r not in rules:
+            thelist = lnames.get(r, names.get(r, None))
+            if thelist is None:
+                raise ValueError('No replicates found for <%s>' % (r))
+            if r not in names and not thelist.startswith('_'):
+                names[r] = thelist
+            rule = [i.replace('@comma@', ',') for i in thelist.split(',')]
+            num = len(rule)
+
+            if numsubs is None:
+                numsubs = num
+                rules[r] = rule
+                base_rule = r
+            elif num == numsubs:
+                rules[r] = rule
+            else:
+                print("Mismatch in number of replacements (base <%s=%s>)"
+                      " for <%s=%s>. Ignoring." %
+                      (base_rule, ','.join(rules[base_rule]), r, thelist))
+    if not rules:
+        return substr
+
+    def namerepl(mobj):
+        name = mobj.group(1)
+        return rules.get(name, (k+1)*[name])[k]
+
+    newstr = ''
+    for k in range(numsubs):
+        newstr += template_re.sub(namerepl, substr) + '\n\n'
+
+    newstr = newstr.replace('@rightarrow@', '>')
+    newstr = newstr.replace('@leftarrow@', '<')
+    return newstr
+
+def process_str(allstr):
+    newstr = allstr
+    writestr = '' #_head # using _head will break free-format files
+
+    struct = parse_structure(newstr)
+
+    oldend = 0
+    names = {}
+    names.update(_special_names)
+    for sub in struct:
+        writestr += newstr[oldend:sub[0]]
+        names.update(find_repl_patterns(newstr[oldend:sub[0]]))
+        writestr += expand_sub(newstr[sub[0]:sub[1]], names)
+        oldend =  sub[1]
+    writestr += newstr[oldend:]
+
+    return writestr
+
+include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
+
+def resolve_includes(source):
+    d = os.path.dirname(source)
+    fid = open(source)
+    lines = []
+    for line in fid:
+        m = include_src_re.match(line)
+        if m:
+            fn = m.group('name')
+            if not os.path.isabs(fn):
+                fn = os.path.join(d, fn)
+            if os.path.isfile(fn):
+                print('Including file', fn)
+                lines.extend(resolve_includes(fn))
+            else:
+                lines.append(line)
+        else:
+            lines.append(line)
+    fid.close()
+    return lines
+
+def process_file(source):
+    lines = resolve_includes(source)
+    return process_str(''.join(lines))
+
+_special_names = find_repl_patterns('''
+<_c=s,d,c,z>
+<_t=real,double precision,complex,double complex>
+<prefix=s,d,c,z>
+<ftype=real,double precision,complex,double complex>
+<ctype=float,double,complex_float,complex_double>
+<ftypereal=real,double precision,\\0,\\1>
+<ctypereal=float,double,\\0,\\1>
+''')
+
+if __name__ == "__main__":
+
+    try:
+        file = sys.argv[1]
+    except IndexError:
+        fid = sys.stdin
+        outfile = sys.stdout
+    else:
+        fid = open(file, 'r')
+        (base, ext) = os.path.splitext(file)
+        newname = base
+        outfile = open(newname, 'w')
+
+    allstr = fid.read()
+    writestr = process_str(allstr)
+    outfile.write(writestr)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/info.py
new file mode 100644
index 0000000000..2f5310665c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/info.py
@@ -0,0 +1,6 @@
+"""
+Enhanced distutils with Fortran compilers support and more.
+"""
+from __future__ import division, absolute_import, print_function
+
+postpone_import = True
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
new file mode 100644
index 0000000000..20c6d2ba41
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
@@ -0,0 +1,105 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+from distutils.unixccompiler import UnixCCompiler
+from numpy.distutils.exec_command import find_executable
+from numpy.distutils.ccompiler import simple_version_match
+if platform.system() == 'Windows':
+    from numpy.distutils.msvc9compiler import MSVCCompiler
+
+
+class IntelCCompiler(UnixCCompiler):
+    """A modified Intel compiler compatible with a GCC-built Python."""
+    compiler_type = 'intel'
+    cc_exe = 'icc'
+    cc_args = 'fPIC'
+
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__(self, verbose, dry_run, force)
+        self.cc_exe = ('icc -fPIC -fp-model strict -O3 '
+                       '-fomit-frame-pointer -openmp')
+        compiler = self.cc_exe
+        if platform.system() == 'Darwin':
+            shared_flag = '-Wl,-undefined,dynamic_lookup'
+        else:
+            shared_flag = '-shared'
+        self.set_executables(compiler=compiler,
+                             compiler_so=compiler,
+                             compiler_cxx=compiler,
+                             archiver='xiar' + ' cru',
+                             linker_exe=compiler + ' -shared-intel',
+                             linker_so=compiler + ' ' + shared_flag +
+                             ' -shared-intel')
+
+
+class IntelItaniumCCompiler(IntelCCompiler):
+    compiler_type = 'intele'
+
+    # On Itanium, the Intel Compiler used to be called ecc, let's search for
+    # it (now it's also icc, so ecc is last in the search).
+    for cc_exe in map(find_executable, ['icc', 'ecc']):
+        if cc_exe:
+            break
+
+
+class IntelEM64TCCompiler(UnixCCompiler):
+    """
+    A modified Intel x86_64 compiler compatible with a 64bit GCC-built Python.
+    """
+    compiler_type = 'intelem'
+    cc_exe = 'icc -m64'
+    cc_args = '-fPIC'
+
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__(self, verbose, dry_run, force)
+        self.cc_exe = ('icc -m64 -fPIC -fp-model strict -O3 '
+                       '-fomit-frame-pointer -openmp -xSSE4.2')
+        compiler = self.cc_exe
+        if platform.system() == 'Darwin':
+            shared_flag = '-Wl,-undefined,dynamic_lookup'
+        else:
+            shared_flag = '-shared'
+        self.set_executables(compiler=compiler,
+                             compiler_so=compiler,
+                             compiler_cxx=compiler,
+                             archiver='xiar' + ' cru',
+                             linker_exe=compiler + ' -shared-intel',
+                             linker_so=compiler + ' ' + shared_flag +
+                             ' -shared-intel')
+
+
+if platform.system() == 'Windows':
+    class IntelCCompilerW(MSVCCompiler):
+        """
+        A modified Intel compiler compatible with an MSVC-built Python.
+        """
+        compiler_type = 'intelw'
+        compiler_cxx = 'icl'
+
+        def __init__(self, verbose=0, dry_run=0, force=0):
+            MSVCCompiler.__init__(self, verbose, dry_run, force)
+            version_match = simple_version_match(start='Intel\(R\).*?32,')
+            self.__version = version_match
+
+        def initialize(self, plat_name=None):
+            MSVCCompiler.initialize(self, plat_name)
+            self.cc = self.find_exe('icl.exe')
+            self.lib = self.find_exe('xilib')
+            self.linker = self.find_exe('xilink')
+            self.compile_options = ['/nologo', '/O3', '/MD', '/W3',
+                                    '/Qstd=c99', '/QaxSSE4.2']
+            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3',
+                                          '/Qstd=c99', '/Z7', '/D_DEBUG']
+
+    class IntelEM64TCCompilerW(IntelCCompilerW):
+        """
+        A modified Intel x86_64 compiler compatible with
+        a 64bit MSVC-built Python.
+        """
+        compiler_type = 'intelemw'
+
+        def __init__(self, verbose=0, dry_run=0, force=0):
+            MSVCCompiler.__init__(self, verbose, dry_run, force)
+            version_match = simple_version_match(start='Intel\(R\).*?64,')
+            self.__version = version_match
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.py
new file mode 100644
index 0000000000..0a53645664
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.py
@@ -0,0 +1,116 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+import sys
+import os
+import subprocess
+
+__doc__ = """This module generates a DEF file from the symbols in
+an MSVC-compiled DLL import library.  It correctly discriminates between
+data and functions.  The data is collected from the output of the program
+nm(1).
+
+Usage:
+    python lib2def.py [libname.lib] [output.def]
+or
+    python lib2def.py [libname.lib] > output.def
+
+libname.lib defaults to python<py_ver>.lib and output.def defaults to stdout
+
+Author: Robert Kern <kernr@mail.ncifcrf.gov>
+Last Update: April 30, 1999
+"""
+
+__version__ = '0.1a'
+
+py_ver = "%d%d" % tuple(sys.version_info[:2])
+
+DEFAULT_NM = 'nm -Cs'
+
+DEF_HEADER = """LIBRARY         python%s.dll
+;CODE           PRELOAD MOVEABLE DISCARDABLE
+;DATA           PRELOAD SINGLE
+
+EXPORTS
+""" % py_ver
+# the header of the DEF file
+
+FUNC_RE = re.compile(r"^(.*) in python%s\.dll" % py_ver, re.MULTILINE)
+DATA_RE = re.compile(r"^_imp__(.*) in python%s\.dll" % py_ver, re.MULTILINE)
+
+def parse_cmd():
+    """Parses the command-line arguments.
+
+libfile, deffile = parse_cmd()"""
+    if len(sys.argv) == 3:
+        if sys.argv[1][-4:] == '.lib' and sys.argv[2][-4:] == '.def':
+            libfile, deffile = sys.argv[1:]
+        elif sys.argv[1][-4:] == '.def' and sys.argv[2][-4:] == '.lib':
+            deffile, libfile = sys.argv[1:]
+        else:
+            print("I'm assuming that your first argument is the library")
+            print("and the second is the DEF file.")
+    elif len(sys.argv) == 2:
+        if sys.argv[1][-4:] == '.def':
+            deffile = sys.argv[1]
+            libfile = 'python%s.lib' % py_ver
+        elif sys.argv[1][-4:] == '.lib':
+            deffile = None
+            libfile = sys.argv[1]
+    else:
+        libfile = 'python%s.lib' % py_ver
+        deffile = None
+    return libfile, deffile
+
+def getnm(nm_cmd = ['nm', '-Cs', 'python%s.lib' % py_ver]):
+    """Returns the output of nm_cmd via a pipe.
+
+nm_output = getnam(nm_cmd = 'nm -Cs py_lib')"""
+    f = subprocess.Popen(nm_cmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
+    nm_output = f.stdout.read()
+    f.stdout.close()
+    return nm_output
+
+def parse_nm(nm_output):
+    """Returns a tuple of lists: dlist for the list of data
+symbols and flist for the list of function symbols.
+
+dlist, flist = parse_nm(nm_output)"""
+    data = DATA_RE.findall(nm_output)
+    func = FUNC_RE.findall(nm_output)
+
+    flist = []
+    for sym in data:
+        if sym in func and (sym[:2] == 'Py' or sym[:3] == '_Py' or sym[:4] == 'init'):
+            flist.append(sym)
+
+    dlist = []
+    for sym in data:
+        if sym not in flist and (sym[:2] == 'Py' or sym[:3] == '_Py'):
+            dlist.append(sym)
+
+    dlist.sort()
+    flist.sort()
+    return dlist, flist
+
+def output_def(dlist, flist, header, file = sys.stdout):
+    """Outputs the final DEF file to a file defaulting to stdout.
+
+output_def(dlist, flist, header, file = sys.stdout)"""
+    for data_sym in dlist:
+        header = header + '\t%s DATA\n' % data_sym
+    header = header + '\n' # blank line
+    for func_sym in flist:
+        header = header + '\t%s\n' % func_sym
+    file.write(header)
+
+if __name__ == '__main__':
+    libfile, deffile = parse_cmd()
+    if deffile is None:
+        deffile = sys.stdout
+    else:
+        deffile = open(deffile, 'w')
+    nm_cmd = [str(DEFAULT_NM), str(libfile)]
+    nm_output = getnm(nm_cmd)
+    dlist, flist = parse_nm(nm_output)
+    output_def(dlist, flist, DEF_HEADER, deffile)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.py
new file mode 100644
index 0000000000..5ecb104ffd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.py
@@ -0,0 +1,76 @@
+""" Functions for converting from DOS to UNIX line endings
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys, re, os
+
+def dos2unix(file):
+    "Replace CRLF with LF in argument files.  Print names of changed files."
+    if os.path.isdir(file):
+        print(file, "Directory!")
+        return
+
+    data = open(file, "rb").read()
+    if '\0' in data:
+        print(file, "Binary!")
+        return
+
+    newdata = re.sub("\r\n", "\n", data)
+    if newdata != data:
+        print('dos2unix:', file)
+        f = open(file, "wb")
+        f.write(newdata)
+        f.close()
+        return file
+    else:
+        print(file, 'ok')
+
+def dos2unix_one_dir(modified_files, dir_name, file_names):
+    for file in file_names:
+        full_path = os.path.join(dir_name, file)
+        file = dos2unix(full_path)
+        if file is not None:
+            modified_files.append(file)
+
+def dos2unix_dir(dir_name):
+    modified_files = []
+    os.path.walk(dir_name, dos2unix_one_dir, modified_files)
+    return modified_files
+#----------------------------------
+
+def unix2dos(file):
+    "Replace LF with CRLF in argument files.  Print names of changed files."
+    if os.path.isdir(file):
+        print(file, "Directory!")
+        return
+
+    data = open(file, "rb").read()
+    if '\0' in data:
+        print(file, "Binary!")
+        return
+    newdata = re.sub("\r\n", "\n", data)
+    newdata = re.sub("\n", "\r\n", newdata)
+    if newdata != data:
+        print('unix2dos:', file)
+        f = open(file, "wb")
+        f.write(newdata)
+        f.close()
+        return file
+    else:
+        print(file, 'ok')
+
+def unix2dos_one_dir(modified_files, dir_name, file_names):
+    for file in file_names:
+        full_path = os.path.join(dir_name, file)
+        unix2dos(full_path)
+        if file is not None:
+            modified_files.append(file)
+
+def unix2dos_dir(dir_name):
+    modified_files = []
+    os.path.walk(dir_name, unix2dos_one_dir, modified_files)
+    return modified_files
+
+if __name__ == "__main__":
+    dos2unix_dir(sys.argv[1])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/log.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/log.py
new file mode 100644
index 0000000000..37f9fe5dd0
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/log.py
@@ -0,0 +1,93 @@
+# Colored log, requires Python 2.3 or up.
+from __future__ import division, absolute_import, print_function
+
+import sys
+from distutils.log import *
+from distutils.log import Log as old_Log
+from distutils.log import _global_log
+
+if sys.version_info[0] < 3:
+    from .misc_util import (red_text, default_text, cyan_text, green_text,
+            is_sequence, is_string)
+else:
+    from numpy.distutils.misc_util import (red_text, default_text, cyan_text,
+            green_text, is_sequence, is_string)
+
+
+def _fix_args(args,flag=1):
+    if is_string(args):
+        return args.replace('%', '%%')
+    if flag and is_sequence(args):
+        return tuple([_fix_args(a, flag=0) for a in args])
+    return args
+
+
+class Log(old_Log):
+    def _log(self, level, msg, args):
+        if level >= self.threshold:
+            if args:
+                msg = msg % _fix_args(args)
+            if 0:
+                if msg.startswith('copying ') and msg.find(' -> ') != -1:
+                    return
+                if msg.startswith('byte-compiling '):
+                    return
+            print(_global_color_map[level](msg))
+            sys.stdout.flush()
+
+    def good(self, msg, *args):
+        """
+        If we log WARN messages, log this message as a 'nice' anti-warn
+        message.
+
+        """
+        if WARN >= self.threshold:
+            if args:
+                print(green_text(msg % _fix_args(args)))
+            else:
+                print(green_text(msg))
+            sys.stdout.flush()
+
+
+_global_log.__class__ = Log
+
+good = _global_log.good
+
+def set_threshold(level, force=False):
+    prev_level = _global_log.threshold
+    if prev_level > DEBUG or force:
+        # If we're running at DEBUG, don't change the threshold, as there's
+        # likely a good reason why we're running at this level.
+        _global_log.threshold = level
+        if level <= DEBUG:
+            info('set_threshold: setting threshold to DEBUG level,'
+                    ' it can be changed only with force argument')
+    else:
+        info('set_threshold: not changing threshold from DEBUG level'
+                ' %s to %s' % (prev_level, level))
+    return prev_level
+
+
+def set_verbosity(v, force=False):
+    prev_level = _global_log.threshold
+    if v < 0:
+        set_threshold(ERROR, force)
+    elif v == 0:
+        set_threshold(WARN, force)
+    elif v == 1:
+        set_threshold(INFO, force)
+    elif v >= 2:
+        set_threshold(DEBUG, force)
+    return {FATAL:-2,ERROR:-1,WARN:0,INFO:1,DEBUG:2}.get(prev_level, 1)
+
+
+_global_color_map = {
+    DEBUG:cyan_text,
+    INFO:default_text,
+    WARN:red_text,
+    ERROR:red_text,
+    FATAL:red_text
+}
+
+# don't use INFO,.. flags in set_verbosity, these flags are for set_threshold.
+set_verbosity(0, force=True)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
new file mode 100644
index 0000000000..15ed7e6863
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
@@ -0,0 +1,6 @@
+int _get_output_format(void)
+{
+	return 0;
+}
+
+int _imp____lc_codepage = 0;
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
new file mode 100644
index 0000000000..c05cbf492e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
@@ -0,0 +1,584 @@
+"""
+Support code for building Python extensions on Windows.
+
+    # NT stuff
+    # 1. Make sure libpython<version>.a exists for gcc.  If not, build it.
+    # 2. Force windows to use gcc (we're struggling with MSVC and g77 support)
+    # 3. Force windows to use g77
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import subprocess
+import re
+
+# Overwrite certain distutils.ccompiler functions:
+import numpy.distutils.ccompiler
+
+if sys.version_info[0] < 3:
+    from . import log
+else:
+    from numpy.distutils import log
+# NT stuff
+# 1. Make sure libpython<version>.a exists for gcc.  If not, build it.
+# 2. Force windows to use gcc (we're struggling with MSVC and g77 support)
+#    --> this is done in numpy/distutils/ccompiler.py
+# 3. Force windows to use g77
+
+import distutils.cygwinccompiler
+from distutils.version import StrictVersion
+from numpy.distutils.ccompiler import gen_preprocess_options, gen_lib_options
+from distutils.unixccompiler import UnixCCompiler
+from distutils.msvccompiler import get_build_version as get_build_msvc_version
+from distutils.errors import (DistutilsExecError, CompileError,
+                              UnknownFileError)
+from numpy.distutils.misc_util import (msvc_runtime_library,
+                                       get_build_architecture)
+
+# Useful to generate table of symbols from a dll
+_START = re.compile(r'\[Ordinal/Name Pointer\] Table')
+_TABLE = re.compile(r'^\s+\[([\s*[0-9]*)\] ([a-zA-Z0-9_]*)')
+
+# the same as cygwin plus some additional parameters
+class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
+    """ A modified MingW32 compiler compatible with an MSVC built Python.
+
+    """
+
+    compiler_type = 'mingw32'
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        distutils.cygwinccompiler.CygwinCCompiler.__init__ (self, verbose,
+                                                            dry_run, force)
+
+        # we need to support 3.2 which doesn't match the standard
+        # get_versions methods regex
+        if self.gcc_version is None:
+            import re
+            p = subprocess.Popen(['gcc', '-dumpversion'], shell=True,
+                                 stdout=subprocess.PIPE)
+            out_string = p.stdout.read()
+            p.stdout.close()
+            result = re.search('(\d+\.\d+)', out_string)
+            if result:
+                self.gcc_version = StrictVersion(result.group(1))
+
+        # A real mingw32 doesn't need to specify a different entry point,
+        # but cygwin 2.91.57 in no-cygwin-mode needs it.
+        if self.gcc_version <= "2.91.57":
+            entry_point = '--entry _DllMain@12'
+        else:
+            entry_point = ''
+
+        if self.linker_dll == 'dllwrap':
+            # Commented out '--driver-name g++' part that fixes weird
+            #   g++.exe: g++: No such file or directory
+            # error (mingw 1.0 in Enthon24 tree, gcc-3.4.5).
+            # If the --driver-name part is required for some environment
+            # then make the inclusion of this part specific to that
+            # environment.
+            self.linker = 'dllwrap' #  --driver-name g++'
+        elif self.linker_dll == 'gcc':
+            self.linker = 'g++'
+
+        if not 'GCC' in sys.version:
+
+            # **changes: eric jones 4/11/01
+            # 1. Check for import library on Windows.  Build if it doesn't exist.
+
+            build_import_library()
+
+            # Check for custom msvc runtime library on Windows. Build if it doesn't exist.
+            msvcr_success = build_msvcr_library()
+            msvcr_dbg_success = build_msvcr_library(debug=True)
+            if msvcr_success or msvcr_dbg_success:
+                # add preprocessor statement for using customized msvcr lib
+                self.define_macro('NPY_MINGW_USE_CUSTOM_MSVCR')
+
+            # Define the MSVC version as hint for MinGW
+            msvcr_version = '0x%03i0' % int(msvc_runtime_library().lstrip('msvcr'))
+            self.define_macro('__MSVCRT_VERSION__', msvcr_version)
+
+        # MS_WIN64 should be defined when building for amd64 on windows,
+        # but python headers define it only for MS compilers, which has all
+        # kind of bad consequences, like using Py_ModuleInit4 instead of
+        # Py_ModuleInit4_64, etc... So we add it here
+        if get_build_architecture() == 'AMD64':
+            if self.gcc_version < "4.0":
+                self.set_executables(
+                    compiler='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall',
+                    compiler_so='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0'
+                                ' -Wall -Wstrict-prototypes',
+                    linker_exe='gcc -g -mno-cygwin',
+                    linker_so='gcc -g -mno-cygwin -shared')
+            else:
+                # gcc-4 series releases do not support -mno-cygwin option
+                self.set_executables(
+                    compiler='gcc -march=x86-64 -mtune=generic -DMS_WIN64'
+                             ' -O2 -msse2 -Wall',
+                    compiler_so='gcc -march=x86-64 -mtune=generic -DMS_WIN64'
+                                ' -O2 -msse2 -Wall -Wstrict-prototypes',
+                    linker_exe='gcc',
+                    linker_so='gcc -shared -Wl,-gc-sections -Wl,-s')
+        else:
+            if self.gcc_version <= "3.0.0":
+                self.set_executables(
+                    compiler='gcc -mno-cygwin -O2 -w',
+                    compiler_so='gcc -mno-cygwin -mdll -O2 -w'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ -mno-cygwin',
+                    linker_so='%s -mno-cygwin -mdll -static %s' %
+                              (self.linker, entry_point))
+            elif self.gcc_version < "4.0":
+                self.set_executables(
+                    compiler='gcc -mno-cygwin -O2 -Wall',
+                    compiler_so='gcc -mno-cygwin -O2 -Wall'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ -mno-cygwin',
+                    linker_so='g++ -mno-cygwin -shared')
+            else:
+                # gcc-4 series releases do not support -mno-cygwin option
+                self.set_executables(
+                    compiler='gcc -O2 -march=core2 -mtune=generic'
+                             ' -mfpmath=sse -msse2'
+                             ' -mincoming-stack-boundary=2 -Wall',
+                    compiler_so='gcc -O2 -march=core2 -mtune=generic'
+                                ' -mfpmath=sse -msse2'
+                                ' -mincoming-stack-boundary=2 -Wall'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ ',
+                    linker_so='g++ -shared -Wl,-gc-sections -Wl,-s')
+        # added for python2.3 support
+        # we can't pass it through set_executables because pre 2.2 would fail
+        self.compiler_cxx = ['g++']
+
+        # Maybe we should also append -mthreads, but then the finished dlls
+        # need another dll (mingwm10.dll see Mingw32 docs) (-mthreads: Support
+        # thread-safe exception handling on `Mingw32')
+
+        # no additional libraries needed
+        #self.dll_libraries=[]
+        return
+
+    # __init__ ()
+
+    def link(self,
+             target_desc,
+             objects,
+             output_filename,
+             output_dir,
+             libraries,
+             library_dirs,
+             runtime_library_dirs,
+             export_symbols = None,
+             debug=0,
+             extra_preargs=None,
+             extra_postargs=None,
+             build_temp=None,
+             target_lang=None):
+        # Include the appropiate MSVC runtime library if Python was built
+        # with MSVC >= 7.0 (MinGW standard is msvcrt)
+        runtime_library = msvc_runtime_library()
+        if runtime_library:
+            if not libraries:
+                libraries = []
+            libraries.append(runtime_library)
+        args = (self,
+                target_desc,
+                objects,
+                output_filename,
+                output_dir,
+                libraries,
+                library_dirs,
+                runtime_library_dirs,
+                None, #export_symbols, we do this in our def-file
+                debug,
+                extra_preargs,
+                extra_postargs,
+                build_temp,
+                target_lang)
+        if self.gcc_version < "3.0.0":
+            func = distutils.cygwinccompiler.CygwinCCompiler.link
+        else:
+            func = UnixCCompiler.link
+        func(*args[:func.__code__.co_argcount])
+        return
+
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+
+            # added these lines to strip off windows drive letters
+            # without it, .o files are placed next to .c files
+            # instead of the build directory
+            drv, base = os.path.splitdrive(base)
+            if drv:
+                base = base[1:]
+
+            if ext not in (self.src_extensions + ['.rc', '.res']):
+                raise UnknownFileError(
+                      "unknown file type '%s' (from '%s')" % \
+                      (ext, src_name))
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext == '.res' or ext == '.rc':
+                # these need to be compiled to object files
+                obj_names.append (os.path.join (output_dir,
+                                                base + ext + self.obj_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                                base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+
+def find_python_dll():
+    maj, min, micro = [int(i) for i in sys.version_info[:3]]
+    dllname = 'python%d%d.dll' % (maj, min)
+    print("Looking for %s" % dllname)
+
+    # We can't do much here:
+    # - find it in python main dir
+    # - in system32,
+    # - ortherwise (Sxs), I don't know how to get it.
+    lib_dirs = [sys.prefix, os.path.join(sys.prefix, 'lib')]
+    try:
+        lib_dirs.append(os.path.join(os.environ['SYSTEMROOT'], 'system32'))
+    except KeyError:
+        pass
+
+    for d in lib_dirs:
+        dll = os.path.join(d, dllname)
+        if os.path.exists(dll):
+            return dll
+
+    raise ValueError("%s not found in %s" % (dllname, lib_dirs))
+
+def dump_table(dll):
+    st = subprocess.Popen(["objdump.exe", "-p", dll], stdout=subprocess.PIPE)
+    return st.stdout.readlines()
+
+def generate_def(dll, dfile):
+    """Given a dll file location,  get all its exported symbols and dump them
+    into the given def file.
+
+    The .def file will be overwritten"""
+    dump = dump_table(dll)
+    for i in range(len(dump)):
+        if _START.match(dump[i].decode()):
+            break
+    else:
+        raise ValueError("Symbol table not found")
+
+    syms = []
+    for j in range(i+1, len(dump)):
+        m = _TABLE.match(dump[j].decode())
+        if m:
+            syms.append((int(m.group(1).strip()), m.group(2)))
+        else:
+            break
+
+    if len(syms) == 0:
+        log.warn('No symbols found in %s' % dll)
+
+    d = open(dfile, 'w')
+    d.write('LIBRARY        %s\n' % os.path.basename(dll))
+    d.write(';CODE          PRELOAD MOVEABLE DISCARDABLE\n')
+    d.write(';DATA          PRELOAD SINGLE\n')
+    d.write('\nEXPORTS\n')
+    for s in syms:
+        #d.write('@%d    %s\n' % (s[0], s[1]))
+        d.write('%s\n' % s[1])
+    d.close()
+
+def find_dll(dll_name):
+
+    arch = {'AMD64' : 'amd64',
+            'Intel' : 'x86'}[get_build_architecture()]
+
+    def _find_dll_in_winsxs(dll_name):
+        # Walk through the WinSxS directory to find the dll.
+        winsxs_path = os.path.join(os.environ['WINDIR'], 'winsxs')
+        if not os.path.exists(winsxs_path):
+            return None
+        for root, dirs, files in os.walk(winsxs_path):
+            if dll_name in files and arch in root:
+                return os.path.join(root, dll_name)
+        return None
+
+    def _find_dll_in_path(dll_name):
+        # First, look in the Python directory, then scan PATH for
+        # the given dll name.
+        for path in [sys.prefix] + os.environ['PATH'].split(';'):
+            filepath = os.path.join(path, dll_name)
+            if os.path.exists(filepath):
+                return os.path.abspath(filepath)
+
+    return _find_dll_in_winsxs(dll_name) or _find_dll_in_path(dll_name)
+
+def build_msvcr_library(debug=False):
+    if os.name != 'nt':
+        return False
+
+    msvcr_name = msvc_runtime_library()
+
+    # Skip using a custom library for versions < MSVC 8.0
+    if int(msvcr_name.lstrip('msvcr')) < 80:
+        log.debug('Skip building msvcr library:'
+                  ' custom functionality not present')
+        return False
+
+    if debug:
+        msvcr_name += 'd'
+
+    # Skip if custom library already exists
+    out_name = "lib%s.a" % msvcr_name
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if os.path.isfile(out_file):
+        log.debug('Skip building msvcr library: "%s" exists' %
+                  (out_file,))
+        return True
+
+    # Find the msvcr dll
+    msvcr_dll_name = msvcr_name + '.dll'
+    dll_file = find_dll(msvcr_dll_name)
+    if not dll_file:
+        log.warn('Cannot build msvcr library: "%s" not found' %
+                 msvcr_dll_name)
+        return False
+
+    def_name = "lib%s.def" % msvcr_name
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+
+    log.info('Building msvcr library: "%s" (from %s)' \
+             % (out_file, dll_file))
+
+    # Generate a symbol definition file from the msvcr dll
+    generate_def(dll_file, def_file)
+
+    # Create a custom mingw library for the given symbol definitions
+    cmd = ['dlltool', '-d', def_file, '-l', out_file]
+    retcode = subprocess.call(cmd)
+
+    # Clean up symbol definitions
+    os.remove(def_file)
+
+    return (not retcode)
+
+def build_import_library():
+    if os.name != 'nt':
+        return
+
+    arch = get_build_architecture()
+    if arch == 'AMD64':
+        return _build_import_library_amd64()
+    elif arch == 'Intel':
+        return _build_import_library_x86()
+    else:
+        raise ValueError("Unhandled arch %s" % arch)
+
+def _build_import_library_amd64():
+    dll_file = find_python_dll()
+
+    out_name = "libpython%d%d.a" % tuple(sys.version_info[:2])
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if os.path.isfile(out_file):
+        log.debug('Skip building import library: "%s" exists' %
+                  (out_file))
+        return
+
+    def_name = "python%d%d.def" % tuple(sys.version_info[:2])
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+
+    log.info('Building import library (arch=AMD64): "%s" (from %s)' %
+             (out_file, dll_file))
+
+    generate_def(dll_file, def_file)
+
+    cmd = ['dlltool', '-d', def_file, '-l', out_file]
+    subprocess.Popen(cmd)
+
+def _build_import_library_x86():
+    """ Build the import libraries for Mingw32-gcc on Windows
+    """
+    lib_name = "python%d%d.lib" % tuple(sys.version_info[:2])
+    lib_file = os.path.join(sys.prefix, 'libs', lib_name)
+    out_name = "libpython%d%d.a" % tuple(sys.version_info[:2])
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if not os.path.isfile(lib_file):
+        log.warn('Cannot build import library: "%s" not found' % (lib_file))
+        return
+    if os.path.isfile(out_file):
+        log.debug('Skip building import library: "%s" exists' % (out_file))
+        return
+    log.info('Building import library (ARCH=x86): "%s"' % (out_file))
+
+    from numpy.distutils import lib2def
+
+    def_name = "python%d%d.def" % tuple(sys.version_info[:2])
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+    nm_cmd = '%s %s' % (lib2def.DEFAULT_NM, lib_file)
+    nm_output = lib2def.getnm(nm_cmd)
+    dlist, flist = lib2def.parse_nm(nm_output)
+    lib2def.output_def(dlist, flist, lib2def.DEF_HEADER, open(def_file, 'w'))
+
+    dll_name = "python%d%d.dll" % tuple(sys.version_info[:2])
+    args = (dll_name, def_file, out_file)
+    cmd = 'dlltool --dllname %s --def %s --output-lib %s' % args
+    status = os.system(cmd)
+    # for now, fail silently
+    if status:
+        log.warn('Failed to build import library for gcc. Linking will fail.')
+    return
+
+#=====================================
+# Dealing with Visual Studio MANIFESTS
+#=====================================
+
+# Functions to deal with visual studio manifests. Manifest are a mechanism to
+# enforce strong DLL versioning on windows, and has nothing to do with
+# distutils MANIFEST. manifests are XML files with version info, and used by
+# the OS loader; they are necessary when linking against a DLL not in the
+# system path; in particular, official python 2.6 binary is built against the
+# MS runtime 9 (the one from VS 2008), which is not available on most windows
+# systems; python 2.6 installer does install it in the Win SxS (Side by side)
+# directory, but this requires the manifest for this to work. This is a big
+# mess, thanks MS for a wonderful system.
+
+# XXX: ideally, we should use exactly the same version as used by python. I
+# submitted a patch to get this version, but it was only included for python
+# 2.6.1 and above. So for versions below, we use a "best guess".
+_MSVCRVER_TO_FULLVER = {}
+if sys.platform == 'win32':
+    try:
+        import msvcrt
+        # I took one version in my SxS directory: no idea if it is the good
+        # one, and we can't retrieve it from python
+        _MSVCRVER_TO_FULLVER['80'] = "8.0.50727.42"
+        _MSVCRVER_TO_FULLVER['90'] = "9.0.21022.8"
+        # Value from msvcrt.CRT_ASSEMBLY_VERSION under Python 3.3.0
+        # on Windows XP:
+        _MSVCRVER_TO_FULLVER['100'] = "10.0.30319.460"
+        if hasattr(msvcrt, "CRT_ASSEMBLY_VERSION"):
+            major, minor, rest = msvcrt.CRT_ASSEMBLY_VERSION.split(".", 2)
+            _MSVCRVER_TO_FULLVER[major + minor] = msvcrt.CRT_ASSEMBLY_VERSION
+            del major, minor, rest
+    except ImportError:
+        # If we are here, means python was not built with MSVC. Not sure what
+        # to do in that case: manifest building will fail, but it should not be
+        # used in that case anyway
+        log.warn('Cannot import msvcrt: using manifest will not be possible')
+
+def msvc_manifest_xml(maj, min):
+    """Given a major and minor version of the MSVCR, returns the
+    corresponding XML file."""
+    try:
+        fullver = _MSVCRVER_TO_FULLVER[str(maj * 10 + min)]
+    except KeyError:
+        raise ValueError("Version %d,%d of MSVCRT not supported yet" %
+                         (maj, min))
+    # Don't be fooled, it looks like an XML, but it is not. In particular, it
+    # should not have any space before starting, and its size should be
+    # divisible by 4, most likely for alignement constraints when the xml is
+    # embedded in the binary...
+    # This template was copied directly from the python 2.6 binary (using
+    # strings.exe from mingw on python.exe).
+    template = """\
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC%(maj)d%(min)d.CRT" version="%(fullver)s" processorArchitecture="*" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
+    </dependentAssembly>
+  </dependency>
+</assembly>"""
+
+    return template % {'fullver': fullver, 'maj': maj, 'min': min}
+
+def manifest_rc(name, type='dll'):
+    """Return the rc file used to generate the res file which will be embedded
+    as manifest for given manifest file name, of given type ('dll' or
+    'exe').
+
+    Parameters
+    ----------
+    name : str
+            name of the manifest file to embed
+    type : str {'dll', 'exe'}
+            type of the binary which will embed the manifest
+
+    """
+    if type == 'dll':
+        rctype = 2
+    elif type == 'exe':
+        rctype = 1
+    else:
+        raise ValueError("Type %s not supported" % type)
+
+    return """\
+#include "winuser.h"
+%d RT_MANIFEST %s""" % (rctype, name)
+
+def check_embedded_msvcr_match_linked(msver):
+    """msver is the ms runtime version used for the MANIFEST."""
+    # check msvcr major version are the same for linking and
+    # embedding
+    msvcv = msvc_runtime_library()
+    if msvcv:
+        assert msvcv.startswith("msvcr"), msvcv
+        # Dealing with something like "mscvr90" or "mscvr100", the last
+        # last digit is the minor release, want int("9") or int("10"):
+        maj = int(msvcv[5:-1])
+        if not maj == int(msver):
+            raise ValueError(
+                  "Discrepancy between linked msvcr " \
+                  "(%d) and the one about to be embedded " \
+                  "(%d)" % (int(msver), maj))
+
+def configtest_name(config):
+    base = os.path.basename(config._gen_temp_sourcefile("yo", [], "c"))
+    return os.path.splitext(base)[0]
+
+def manifest_name(config):
+    # Get configest name (including suffix)
+    root = configtest_name(config)
+    exext = config.compiler.exe_extension
+    return root + exext + ".manifest"
+
+def rc_name(config):
+    # Get configtest name (including suffix)
+    root = configtest_name(config)
+    return root + ".rc"
+
+def generate_manifest(config):
+    msver = get_build_msvc_version()
+    if msver is not None:
+        if msver >= 8:
+            check_embedded_msvcr_match_linked(msver)
+            ma = int(msver)
+            mi = int((msver - ma) * 10)
+            # Write the manifest file
+            manxml = msvc_manifest_xml(ma, mi)
+            man = open(manifest_name(config), "w")
+            config.temp_files.append(manifest_name(config))
+            man.write(manxml)
+            man.close()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.py
new file mode 100644
index 0000000000..960e20c366
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.py
@@ -0,0 +1,2312 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import imp
+import copy
+import glob
+import atexit
+import tempfile
+import subprocess
+import shutil
+
+import distutils
+from distutils.errors import DistutilsError
+try:
+    from threading import local as tlocal
+except ImportError:
+    from dummy_threading import local as tlocal
+
+# stores temporary directory of each thread to only create one per thread
+_tdata = tlocal()
+
+# store all created temporary directories so they can be deleted on exit
+_tmpdirs = []
+def clean_up_temporary_directory():
+    for d in _tmpdirs:
+        try:
+            shutil.rmtree(d)
+        except OSError:
+            pass
+
+atexit.register(clean_up_temporary_directory)
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from numpy.distutils.compat import get_exception
+from numpy.compat import basestring
+
+__all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict',
+           'dict_append', 'appendpath', 'generate_config_py',
+           'get_cmd', 'allpath', 'get_mathlibs',
+           'terminal_has_colors', 'red_text', 'green_text', 'yellow_text',
+           'blue_text', 'cyan_text', 'cyg2win32', 'mingw32', 'all_strings',
+           'has_f_sources', 'has_cxx_sources', 'filter_sources',
+           'get_dependencies', 'is_local_src_dir', 'get_ext_source_files',
+           'get_script_files', 'get_lib_source_files', 'get_data_files',
+           'dot_join', 'get_frame', 'minrelpath', 'njoin',
+           'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language',
+           'quote_args', 'get_build_architecture', 'get_info', 'get_pkg_info',
+           'get_num_build_jobs']
+
+class InstallableLib(object):
+    """
+    Container to hold information on an installable library.
+
+    Parameters
+    ----------
+    name : str
+        Name of the installed library.
+    build_info : dict
+        Dictionary holding build information.
+    target_dir : str
+        Absolute path specifying where to install the library.
+
+    See Also
+    --------
+    Configuration.add_installed_library
+
+    Notes
+    -----
+    The three parameters are stored as attributes with the same names.
+
+    """
+    def __init__(self, name, build_info, target_dir):
+        self.name = name
+        self.build_info = build_info
+        self.target_dir = target_dir
+
+
+def get_num_build_jobs():
+    """
+    Get number of parallel build jobs set by the --parallel command line
+    argument of setup.py
+    If the command did not receive a setting the environment variable
+    NPY_NUM_BUILD_JOBS checked and if that is unset it returns 1.
+
+    Returns
+    -------
+    out : int
+        number of parallel jobs that can be run
+
+    """
+    from numpy.distutils.core import get_distribution
+    envjobs = int(os.environ.get("NPY_NUM_BUILD_JOBS", 1))
+    dist = get_distribution()
+    # may be None during configuration
+    if dist is None:
+        return envjobs
+
+    # any of these three may have the job set, take the largest
+    cmdattr = (getattr(dist.get_command_obj('build'), 'parallel', None),
+               getattr(dist.get_command_obj('build_ext'), 'parallel', None),
+               getattr(dist.get_command_obj('build_clib'), 'parallel', None))
+    if all(x is None for x in cmdattr):
+        return envjobs
+    else:
+        return max(x for x in cmdattr if x is not None)
+
+def quote_args(args):
+    # don't used _nt_quote_args as it does not check if
+    # args items already have quotes or not.
+    args = list(args)
+    for i in range(len(args)):
+        a = args[i]
+        if ' ' in a and a[0] not in '"\'':
+            args[i] = '"%s"' % (a)
+    return args
+
+def allpath(name):
+    "Convert a /-separated pathname to one using the OS's path separator."
+    splitted = name.split('/')
+    return os.path.join(*splitted)
+
+def rel_path(path, parent_path):
+    """Return path relative to parent_path.
+    """
+    pd = os.path.abspath(parent_path)
+    apath = os.path.abspath(path)
+    if len(apath)<len(pd):
+        return path
+    if apath==pd:
+        return ''
+    if pd == apath[:len(pd)]:
+        assert apath[len(pd)] in [os.sep], repr((path, apath[len(pd)]))
+        path = apath[len(pd)+1:]
+    return path
+
+def get_path_from_frame(frame, parent_path=None):
+    """Return path of the module given a frame object from the call stack.
+
+    Returned path is relative to parent_path when given,
+    otherwise it is absolute path.
+    """
+
+    # First, try to find if the file name is in the frame.
+    try:
+        caller_file = eval('__file__', frame.f_globals, frame.f_locals)
+        d = os.path.dirname(os.path.abspath(caller_file))
+    except NameError:
+        # __file__ is not defined, so let's try __name__. We try this second
+        # because setuptools spoofs __name__ to be '__main__' even though
+        # sys.modules['__main__'] might be something else, like easy_install(1).
+        caller_name = eval('__name__', frame.f_globals, frame.f_locals)
+        __import__(caller_name)
+        mod = sys.modules[caller_name]
+        if hasattr(mod, '__file__'):
+            d = os.path.dirname(os.path.abspath(mod.__file__))
+        else:
+            # we're probably running setup.py as execfile("setup.py")
+            # (likely we're building an egg)
+            d = os.path.abspath('.')
+            # hmm, should we use sys.argv[0] like in __builtin__ case?
+
+    if parent_path is not None:
+        d = rel_path(d, parent_path)
+
+    return d or '.'
+
+def njoin(*path):
+    """Join two or more pathname components +
+    - convert a /-separated pathname to one using the OS's path separator.
+    - resolve `..` and `.` from path.
+
+    Either passing n arguments as in njoin('a','b'), or a sequence
+    of n names as in njoin(['a','b']) is handled, or a mixture of such arguments.
+    """
+    paths = []
+    for p in path:
+        if is_sequence(p):
+            # njoin(['a', 'b'], 'c')
+            paths.append(njoin(*p))
+        else:
+            assert is_string(p)
+            paths.append(p)
+    path = paths
+    if not path:
+        # njoin()
+        joined = ''
+    else:
+        # njoin('a', 'b')
+        joined = os.path.join(*path)
+    if os.path.sep != '/':
+        joined = joined.replace('/', os.path.sep)
+    return minrelpath(joined)
+
+def get_mathlibs(path=None):
+    """Return the MATHLIB line from numpyconfig.h
+    """
+    if path is not None:
+        config_file = os.path.join(path, '_numpyconfig.h')
+    else:
+        # Look for the file in each of the numpy include directories.
+        dirs = get_numpy_include_dirs()
+        for path in dirs:
+            fn = os.path.join(path, '_numpyconfig.h')
+            if os.path.exists(fn):
+                config_file = fn
+                break
+        else:
+            raise DistutilsError('_numpyconfig.h not found in numpy include '
+                'dirs %r' % (dirs,))
+
+    fid = open(config_file)
+    mathlibs = []
+    s = '#define MATHLIB'
+    for line in fid:
+        if line.startswith(s):
+            value = line[len(s):].strip()
+            if value:
+                mathlibs.extend(value.split(','))
+    fid.close()
+    return mathlibs
+
+def minrelpath(path):
+    """Resolve `..` and '.' from path.
+    """
+    if not is_string(path):
+        return path
+    if '.' not in path:
+        return path
+    l = path.split(os.sep)
+    while l:
+        try:
+            i = l.index('.', 1)
+        except ValueError:
+            break
+        del l[i]
+    j = 1
+    while l:
+        try:
+            i = l.index('..', j)
+        except ValueError:
+            break
+        if l[i-1]=='..':
+            j += 1
+        else:
+            del l[i], l[i-1]
+            j = 1
+    if not l:
+        return ''
+    return os.sep.join(l)
+
+def _fix_paths(paths, local_path, include_non_existing):
+    assert is_sequence(paths), repr(type(paths))
+    new_paths = []
+    assert not is_string(paths), repr(paths)
+    for n in paths:
+        if is_string(n):
+            if '*' in n or '?' in n:
+                p = glob.glob(n)
+                p2 = glob.glob(njoin(local_path, n))
+                if p2:
+                    new_paths.extend(p2)
+                elif p:
+                    new_paths.extend(p)
+                else:
+                    if include_non_existing:
+                        new_paths.append(n)
+                    print('could not resolve pattern in %r: %r' %
+                            (local_path, n))
+            else:
+                n2 = njoin(local_path, n)
+                if os.path.exists(n2):
+                    new_paths.append(n2)
+                else:
+                    if os.path.exists(n):
+                        new_paths.append(n)
+                    elif include_non_existing:
+                        new_paths.append(n)
+                    if not os.path.exists(n):
+                        print('non-existing path in %r: %r' %
+                                (local_path, n))
+
+        elif is_sequence(n):
+            new_paths.extend(_fix_paths(n, local_path, include_non_existing))
+        else:
+            new_paths.append(n)
+    return [minrelpath(p) for p in new_paths]
+
+def gpaths(paths, local_path='', include_non_existing=True):
+    """Apply glob to paths and prepend local_path if needed.
+    """
+    if is_string(paths):
+        paths = (paths,)
+    return _fix_paths(paths, local_path, include_non_existing)
+
+def make_temp_file(suffix='', prefix='', text=True):
+    if not hasattr(_tdata, 'tempdir'):
+        _tdata.tempdir = tempfile.mkdtemp()
+        _tmpdirs.append(_tdata.tempdir)
+    fid, name = tempfile.mkstemp(suffix=suffix,
+                                 prefix=prefix,
+                                 dir=_tdata.tempdir,
+                                 text=text)
+    fo = os.fdopen(fid, 'w')
+    return fo, name
+
+# Hooks for colored terminal output.
+# See also http://www.livinglogic.de/Python/ansistyle
+def terminal_has_colors():
+    if sys.platform=='cygwin' and 'USE_COLOR' not in os.environ:
+        # Avoid importing curses that causes illegal operation
+        # with a message:
+        #  PYTHON2 caused an invalid page fault in
+        #  module CYGNURSES7.DLL as 015f:18bbfc28
+        # Details: Python 2.3.3 [GCC 3.3.1 (cygming special)]
+        #          ssh to Win32 machine from debian
+        #          curses.version is 2.2
+        #          CYGWIN_98-4.10, release 1.5.7(0.109/3/2))
+        return 0
+    if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
+        try:
+            import curses
+            curses.setupterm()
+            if (curses.tigetnum("colors") >= 0
+                and curses.tigetnum("pairs") >= 0
+                and ((curses.tigetstr("setf") is not None
+                      and curses.tigetstr("setb") is not None)
+                     or (curses.tigetstr("setaf") is not None
+                         and curses.tigetstr("setab") is not None)
+                     or curses.tigetstr("scp") is not None)):
+                return 1
+        except Exception:
+            pass
+    return 0
+
+if terminal_has_colors():
+    _colour_codes = dict(black=0, red=1, green=2, yellow=3,
+                         blue=4, magenta=5, cyan=6, white=7, default=9)
+    def colour_text(s, fg=None, bg=None, bold=False):
+        seq = []
+        if bold:
+            seq.append('1')
+        if fg:
+            fgcode = 30 + _colour_codes.get(fg.lower(), 0)
+            seq.append(str(fgcode))
+        if bg:
+            bgcode = 40 + _colour_codes.get(fg.lower(), 7)
+            seq.append(str(bgcode))
+        if seq:
+            return '\x1b[%sm%s\x1b[0m' % (';'.join(seq), s)
+        else:
+            return s
+else:
+    def colour_text(s, fg=None, bg=None):
+        return s
+
+def default_text(s):
+    return colour_text(s, 'default')
+def red_text(s):
+    return colour_text(s, 'red')
+def green_text(s):
+    return colour_text(s, 'green')
+def yellow_text(s):
+    return colour_text(s, 'yellow')
+def cyan_text(s):
+    return colour_text(s, 'cyan')
+def blue_text(s):
+    return colour_text(s, 'blue')
+
+#########################
+
+def cyg2win32(path):
+    if sys.platform=='cygwin' and path.startswith('/cygdrive'):
+        path = path[10] + ':' + os.path.normcase(path[11:])
+    return path
+
+def mingw32():
+    """Return true when using mingw32 environment.
+    """
+    if sys.platform=='win32':
+        if os.environ.get('OSTYPE', '')=='msys':
+            return True
+        if os.environ.get('MSYSTEM', '')=='MINGW32':
+            return True
+        if os.environ.get('MSYSTEM', '')=='MINGW64':
+            return True
+        if 'GCC' in sys.version:
+            return True
+    return False
+
+def msvc_runtime_library():
+    "Return name of MSVC runtime library if Python was built with MSVC >= 7"
+    msc_pos = sys.version.find('MSC v.')
+    if msc_pos != -1:
+        msc_ver = sys.version[msc_pos+6:msc_pos+10]
+        lib = {'1300': 'msvcr70',    # MSVC 7.0
+               '1310': 'msvcr71',    # MSVC 7.1
+               '1400': 'msvcr80',    # MSVC 8
+               '1500': 'msvcr90',    # MSVC 9 (VS 2008)
+               '1600': 'msvcr100',   # MSVC 10 (aka 2010)
+              }.get(msc_ver, None)
+    else:
+        lib = None
+    return lib
+
+
+#########################
+
+#XXX need support for .C that is also C++
+cxx_ext_match = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
+fortran_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f)\Z', re.I).match
+f90_ext_match = re.compile(r'.*[.](f90|f95)\Z', re.I).match
+f90_module_name_match = re.compile(r'\s*module\s*(?P<name>[\w_]+)', re.I).match
+def _get_f90_modules(source):
+    """Return a list of Fortran f90 module names that
+    given source file defines.
+    """
+    if not f90_ext_match(source):
+        return []
+    modules = []
+    f = open(source, 'r')
+    for line in f:
+        m = f90_module_name_match(line)
+        if m:
+            name = m.group('name')
+            modules.append(name)
+            # break  # XXX can we assume that there is one module per file?
+    f.close()
+    return modules
+
+def is_string(s):
+    return isinstance(s, basestring)
+
+def all_strings(lst):
+    """Return True if all items in lst are string objects. """
+    for item in lst:
+        if not is_string(item):
+            return False
+    return True
+
+def is_sequence(seq):
+    if is_string(seq):
+        return False
+    try:
+        len(seq)
+    except:
+        return False
+    return True
+
+def is_glob_pattern(s):
+    return is_string(s) and ('*' in s or '?' is s)
+
+def as_list(seq):
+    if is_sequence(seq):
+        return list(seq)
+    else:
+        return [seq]
+
+def get_language(sources):
+    # not used in numpy/scipy packages, use build_ext.detect_language instead
+    """Determine language value (c,f77,f90) from sources """
+    language = None
+    for source in sources:
+        if isinstance(source, str):
+            if f90_ext_match(source):
+                language = 'f90'
+                break
+            elif fortran_ext_match(source):
+                language = 'f77'
+    return language
+
+def has_f_sources(sources):
+    """Return True if sources contains Fortran files """
+    for source in sources:
+        if fortran_ext_match(source):
+            return True
+    return False
+
+def has_cxx_sources(sources):
+    """Return True if sources contains C++ files """
+    for source in sources:
+        if cxx_ext_match(source):
+            return True
+    return False
+
+def filter_sources(sources):
+    """Return four lists of filenames containing
+    C, C++, Fortran, and Fortran 90 module sources,
+    respectively.
+    """
+    c_sources = []
+    cxx_sources = []
+    f_sources = []
+    fmodule_sources = []
+    for source in sources:
+        if fortran_ext_match(source):
+            modules = _get_f90_modules(source)
+            if modules:
+                fmodule_sources.append(source)
+            else:
+                f_sources.append(source)
+        elif cxx_ext_match(source):
+            cxx_sources.append(source)
+        else:
+            c_sources.append(source)
+    return c_sources, cxx_sources, f_sources, fmodule_sources
+
+
+def _get_headers(directory_list):
+    # get *.h files from list of directories
+    headers = []
+    for d in directory_list:
+        head = glob.glob(os.path.join(d, "*.h")) #XXX: *.hpp files??
+        headers.extend(head)
+    return headers
+
+def _get_directories(list_of_sources):
+    # get unique directories from list of sources.
+    direcs = []
+    for f in list_of_sources:
+        d = os.path.split(f)
+        if d[0] != '' and not d[0] in direcs:
+            direcs.append(d[0])
+    return direcs
+
+def get_dependencies(sources):
+    #XXX scan sources for include statements
+    return _get_headers(_get_directories(sources))
+
+def is_local_src_dir(directory):
+    """Return true if directory is local directory.
+    """
+    if not is_string(directory):
+        return False
+    abs_dir = os.path.abspath(directory)
+    c = os.path.commonprefix([os.getcwd(), abs_dir])
+    new_dir = abs_dir[len(c):].split(os.sep)
+    if new_dir and not new_dir[0]:
+        new_dir = new_dir[1:]
+    if new_dir and new_dir[0]=='build':
+        return False
+    new_dir = os.sep.join(new_dir)
+    return os.path.isdir(new_dir)
+
+def general_source_files(top_path):
+    pruned_directories = {'CVS':1, '.svn':1, 'build':1}
+    prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$')
+    for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
+        pruned = [ d for d in dirnames if d not in pruned_directories ]
+        dirnames[:] = pruned
+        for f in filenames:
+            if not prune_file_pat.search(f):
+                yield os.path.join(dirpath, f)
+
+def general_source_directories_files(top_path):
+    """Return a directory name relative to top_path and
+    files contained.
+    """
+    pruned_directories = ['CVS', '.svn', 'build']
+    prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$')
+    for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
+        pruned = [ d for d in dirnames if d not in pruned_directories ]
+        dirnames[:] = pruned
+        for d in dirnames:
+            dpath = os.path.join(dirpath, d)
+            rpath = rel_path(dpath, top_path)
+            files = []
+            for f in os.listdir(dpath):
+                fn = os.path.join(dpath, f)
+                if os.path.isfile(fn) and not prune_file_pat.search(fn):
+                    files.append(fn)
+            yield rpath, files
+    dpath = top_path
+    rpath = rel_path(dpath, top_path)
+    filenames = [os.path.join(dpath, f) for f in os.listdir(dpath) \
+                 if not prune_file_pat.search(f)]
+    files = [f for f in filenames if os.path.isfile(f)]
+    yield rpath, files
+
+
+def get_ext_source_files(ext):
+    # Get sources and any include files in the same directory.
+    filenames = []
+    sources = [_m for _m in ext.sources if is_string(_m)]
+    filenames.extend(sources)
+    filenames.extend(get_dependencies(sources))
+    for d in ext.depends:
+        if is_local_src_dir(d):
+            filenames.extend(list(general_source_files(d)))
+        elif os.path.isfile(d):
+            filenames.append(d)
+    return filenames
+
+def get_script_files(scripts):
+    scripts = [_m for _m in scripts if is_string(_m)]
+    return scripts
+
+def get_lib_source_files(lib):
+    filenames = []
+    sources = lib[1].get('sources', [])
+    sources = [_m for _m in sources if is_string(_m)]
+    filenames.extend(sources)
+    filenames.extend(get_dependencies(sources))
+    depends = lib[1].get('depends', [])
+    for d in depends:
+        if is_local_src_dir(d):
+            filenames.extend(list(general_source_files(d)))
+        elif os.path.isfile(d):
+            filenames.append(d)
+    return filenames
+
+def get_shared_lib_extension(is_python_ext=False):
+    """Return the correct file extension for shared libraries.
+
+    Parameters
+    ----------
+    is_python_ext : bool, optional
+        Whether the shared library is a Python extension.  Default is False.
+
+    Returns
+    -------
+    so_ext : str
+        The shared library extension.
+
+    Notes
+    -----
+    For Python shared libs, `so_ext` will typically be '.so' on Linux and OS X,
+    and '.pyd' on Windows.  For Python >= 3.2 `so_ext` has a tag prepended on
+    POSIX systems according to PEP 3149.  For Python 3.2 this is implemented on
+    Linux, but not on OS X.
+
+    """
+    confvars = distutils.sysconfig.get_config_vars()
+    # SO is deprecated in 3.3.1, use EXT_SUFFIX instead
+    so_ext = confvars.get('EXT_SUFFIX', None)
+    if so_ext is None:
+        so_ext = confvars.get('SO', '')
+
+    if not is_python_ext:
+        # hardcode known values, config vars (including SHLIB_SUFFIX) are
+        # unreliable (see #3182)
+        # darwin, windows and debug linux are wrong in 3.3.1 and older
+        if (sys.platform.startswith('linux') or
+            sys.platform.startswith('gnukfreebsd')):
+            so_ext = '.so'
+        elif sys.platform.startswith('darwin'):
+            so_ext = '.dylib'
+        elif sys.platform.startswith('win'):
+            so_ext = '.dll'
+        else:
+            # fall back to config vars for unknown platforms
+            # fix long extension for Python >=3.2, see PEP 3149.
+            if 'SOABI' in confvars:
+                # Does nothing unless SOABI config var exists
+                so_ext = so_ext.replace('.' + confvars.get('SOABI'), '', 1)
+
+    return so_ext
+
+def get_data_files(data):
+    if is_string(data):
+        return [data]
+    sources = data[1]
+    filenames = []
+    for s in sources:
+        if hasattr(s, '__call__'):
+            continue
+        if is_local_src_dir(s):
+            filenames.extend(list(general_source_files(s)))
+        elif is_string(s):
+            if os.path.isfile(s):
+                filenames.append(s)
+            else:
+                print('Not existing data file:', s)
+        else:
+            raise TypeError(repr(s))
+    return filenames
+
+def dot_join(*args):
+    return '.'.join([a for a in args if a])
+
+def get_frame(level=0):
+    """Return frame object from call stack with given level.
+    """
+    try:
+        return sys._getframe(level+1)
+    except AttributeError:
+        frame = sys.exc_info()[2].tb_frame
+        for _ in range(level+1):
+            frame = frame.f_back
+        return frame
+
+
+######################
+
+class Configuration(object):
+
+    _list_keys = ['packages', 'ext_modules', 'data_files', 'include_dirs',
+                  'libraries', 'headers', 'scripts', 'py_modules',
+                  'installed_libraries', 'define_macros']
+    _dict_keys = ['package_dir', 'installed_pkg_config']
+    _extra_keys = ['name', 'version']
+
+    numpy_include_dirs = []
+
+    def __init__(self,
+                 package_name=None,
+                 parent_name=None,
+                 top_path=None,
+                 package_path=None,
+                 caller_level=1,
+                 setup_name='setup.py',
+                 **attrs):
+        """Construct configuration instance of a package.
+
+        package_name -- name of the package
+                        Ex.: 'distutils'
+        parent_name  -- name of the parent package
+                        Ex.: 'numpy'
+        top_path     -- directory of the toplevel package
+                        Ex.: the directory where the numpy package source sits
+        package_path -- directory of package. Will be computed by magic from the
+                        directory of the caller module if not specified
+                        Ex.: the directory where numpy.distutils is
+        caller_level -- frame level to caller namespace, internal parameter.
+        """
+        self.name = dot_join(parent_name, package_name)
+        self.version = None
+
+        caller_frame = get_frame(caller_level)
+        self.local_path = get_path_from_frame(caller_frame, top_path)
+        # local_path -- directory of a file (usually setup.py) that
+        #               defines a configuration() function.
+        # local_path -- directory of a file (usually setup.py) that
+        #               defines a configuration() function.
+        if top_path is None:
+            top_path = self.local_path
+            self.local_path = ''
+        if package_path is None:
+            package_path = self.local_path
+        elif os.path.isdir(njoin(self.local_path, package_path)):
+            package_path = njoin(self.local_path, package_path)
+        if not os.path.isdir(package_path or '.'):
+            raise ValueError("%r is not a directory" % (package_path,))
+        self.top_path = top_path
+        self.package_path = package_path
+        # this is the relative path in the installed package
+        self.path_in_package = os.path.join(*self.name.split('.'))
+
+        self.list_keys = self._list_keys[:]
+        self.dict_keys = self._dict_keys[:]
+
+        for n in self.list_keys:
+            v = copy.copy(attrs.get(n, []))
+            setattr(self, n, as_list(v))
+
+        for n in self.dict_keys:
+            v = copy.copy(attrs.get(n, {}))
+            setattr(self, n, v)
+
+        known_keys = self.list_keys + self.dict_keys
+        self.extra_keys = self._extra_keys[:]
+        for n in attrs.keys():
+            if n in known_keys:
+                continue
+            a = attrs[n]
+            setattr(self, n, a)
+            if isinstance(a, list):
+                self.list_keys.append(n)
+            elif isinstance(a, dict):
+                self.dict_keys.append(n)
+            else:
+                self.extra_keys.append(n)
+
+        if os.path.exists(njoin(package_path, '__init__.py')):
+            self.packages.append(self.name)
+            self.package_dir[self.name] = package_path
+
+        self.options = dict(
+            ignore_setup_xxx_py = False,
+            assume_default_configuration = False,
+            delegate_options_to_subpackages = False,
+            quiet = False,
+            )
+
+        caller_instance = None
+        for i in range(1, 3):
+            try:
+                f = get_frame(i)
+            except ValueError:
+                break
+            try:
+                caller_instance = eval('self', f.f_globals, f.f_locals)
+                break
+            except NameError:
+                pass
+        if isinstance(caller_instance, self.__class__):
+            if caller_instance.options['delegate_options_to_subpackages']:
+                self.set_options(**caller_instance.options)
+
+        self.setup_name = setup_name
+
+    def todict(self):
+        """
+        Return a dictionary compatible with the keyword arguments of distutils
+        setup function.
+
+        Examples
+        --------
+        >>> setup(**config.todict())                           #doctest: +SKIP
+        """
+
+        self._optimize_data_files()
+        d = {}
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        for n in known_keys:
+            a = getattr(self, n)
+            if a:
+                d[n] = a
+        return d
+
+    def info(self, message):
+        if not self.options['quiet']:
+            print(message)
+
+    def warn(self, message):
+        sys.stderr.write('Warning: %s' % (message,))
+
+    def set_options(self, **options):
+        """
+        Configure Configuration instance.
+
+        The following options are available:
+         - ignore_setup_xxx_py
+         - assume_default_configuration
+         - delegate_options_to_subpackages
+         - quiet
+
+        """
+        for key, value in options.items():
+            if key in self.options:
+                self.options[key] = value
+            else:
+                raise ValueError('Unknown option: '+key)
+
+    def get_distribution(self):
+        """Return the distutils distribution object for self."""
+        from numpy.distutils.core import get_distribution
+        return get_distribution()
+
+    def _wildcard_get_subpackage(self, subpackage_name,
+                                 parent_name,
+                                 caller_level = 1):
+        l = subpackage_name.split('.')
+        subpackage_path = njoin([self.local_path]+l)
+        dirs = [_m for _m in glob.glob(subpackage_path) if os.path.isdir(_m)]
+        config_list = []
+        for d in dirs:
+            if not os.path.isfile(njoin(d, '__init__.py')):
+                continue
+            if 'build' in d.split(os.sep):
+                continue
+            n = '.'.join(d.split(os.sep)[-len(l):])
+            c = self.get_subpackage(n,
+                                    parent_name = parent_name,
+                                    caller_level = caller_level+1)
+            config_list.extend(c)
+        return config_list
+
+    def _get_configuration_from_setup_py(self, setup_py,
+                                         subpackage_name,
+                                         subpackage_path,
+                                         parent_name,
+                                         caller_level = 1):
+        # In case setup_py imports local modules:
+        sys.path.insert(0, os.path.dirname(setup_py))
+        try:
+            fo_setup_py = open(setup_py, 'U')
+            setup_name = os.path.splitext(os.path.basename(setup_py))[0]
+            n = dot_join(self.name, subpackage_name, setup_name)
+            setup_module = imp.load_module('_'.join(n.split('.')),
+                                           fo_setup_py,
+                                           setup_py,
+                                           ('.py', 'U', 1))
+            fo_setup_py.close()
+            if not hasattr(setup_module, 'configuration'):
+                if not self.options['assume_default_configuration']:
+                    self.warn('Assuming default configuration '\
+                              '(%s does not define configuration())'\
+                              % (setup_module))
+                config = Configuration(subpackage_name, parent_name,
+                                       self.top_path, subpackage_path,
+                                       caller_level = caller_level + 1)
+            else:
+                pn = dot_join(*([parent_name] + subpackage_name.split('.')[:-1]))
+                args = (pn,)
+                def fix_args_py2(args):
+                    if setup_module.configuration.__code__.co_argcount > 1:
+                        args = args + (self.top_path,)
+                    return args
+                def fix_args_py3(args):
+                    if setup_module.configuration.__code__.co_argcount > 1:
+                        args = args + (self.top_path,)
+                    return args
+                if sys.version_info[0] < 3:
+                    args = fix_args_py2(args)
+                else:
+                    args = fix_args_py3(args)
+                config = setup_module.configuration(*args)
+            if config.name!=dot_join(parent_name, subpackage_name):
+                self.warn('Subpackage %r configuration returned as %r' % \
+                          (dot_join(parent_name, subpackage_name), config.name))
+        finally:
+            del sys.path[0]
+        return config
+
+    def get_subpackage(self,subpackage_name,
+                       subpackage_path=None,
+                       parent_name=None,
+                       caller_level = 1):
+        """Return list of subpackage configurations.
+
+        Parameters
+        ----------
+        subpackage_name : str or None
+            Name of the subpackage to get the configuration. '*' in
+            subpackage_name is handled as a wildcard.
+        subpackage_path : str
+            If None, then the path is assumed to be the local path plus the
+            subpackage_name. If a setup.py file is not found in the
+            subpackage_path, then a default configuration is used.
+        parent_name : str
+            Parent name.
+        """
+        if subpackage_name is None:
+            if subpackage_path is None:
+                raise ValueError(
+                    "either subpackage_name or subpackage_path must be specified")
+            subpackage_name = os.path.basename(subpackage_path)
+
+        # handle wildcards
+        l = subpackage_name.split('.')
+        if subpackage_path is None and '*' in subpackage_name:
+            return self._wildcard_get_subpackage(subpackage_name,
+                                                 parent_name,
+                                                 caller_level = caller_level+1)
+        assert '*' not in subpackage_name, repr((subpackage_name, subpackage_path, parent_name))
+        if subpackage_path is None:
+            subpackage_path = njoin([self.local_path] + l)
+        else:
+            subpackage_path = njoin([subpackage_path] + l[:-1])
+            subpackage_path = self.paths([subpackage_path])[0]
+        setup_py = njoin(subpackage_path, self.setup_name)
+        if not self.options['ignore_setup_xxx_py']:
+            if not os.path.isfile(setup_py):
+                setup_py = njoin(subpackage_path,
+                                 'setup_%s.py' % (subpackage_name))
+        if not os.path.isfile(setup_py):
+            if not self.options['assume_default_configuration']:
+                self.warn('Assuming default configuration '\
+                          '(%s/{setup_%s,setup}.py was not found)' \
+                          % (os.path.dirname(setup_py), subpackage_name))
+            config = Configuration(subpackage_name, parent_name,
+                                   self.top_path, subpackage_path,
+                                   caller_level = caller_level+1)
+        else:
+            config = self._get_configuration_from_setup_py(
+                setup_py,
+                subpackage_name,
+                subpackage_path,
+                parent_name,
+                caller_level = caller_level + 1)
+        if config:
+            return [config]
+        else:
+            return []
+
+    def add_subpackage(self,subpackage_name,
+                       subpackage_path=None,
+                       standalone = False):
+        """Add a sub-package to the current Configuration instance.
+
+        This is useful in a setup.py script for adding sub-packages to a
+        package.
+
+        Parameters
+        ----------
+        subpackage_name : str
+            name of the subpackage
+        subpackage_path : str
+            if given, the subpackage path such as the subpackage is in
+            subpackage_path / subpackage_name. If None,the subpackage is
+            assumed to be located in the local path / subpackage_name.
+        standalone : bool
+        """
+
+        if standalone:
+            parent_name = None
+        else:
+            parent_name = self.name
+        config_list = self.get_subpackage(subpackage_name, subpackage_path,
+                                          parent_name = parent_name,
+                                          caller_level = 2)
+        if not config_list:
+            self.warn('No configuration returned, assuming unavailable.')
+        for config in config_list:
+            d = config
+            if isinstance(config, Configuration):
+                d = config.todict()
+            assert isinstance(d, dict), repr(type(d))
+
+            self.info('Appending %s configuration to %s' \
+                      % (d.get('name'), self.name))
+            self.dict_append(**d)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add a subpackage '+ subpackage_name)
+
+    def add_data_dir(self, data_path):
+        """Recursively add files under data_path to data_files list.
+
+        Recursively add files under data_path to the list of data_files to be
+        installed (and distributed). The data_path can be either a relative
+        path-name, or an absolute path-name, or a 2-tuple where the first
+        argument shows where in the install directory the data directory
+        should be installed to.
+
+        Parameters
+        ----------
+        data_path : seq or str
+            Argument can be either
+
+                * 2-sequence (<datadir suffix>, <path to data directory>)
+                * path to data directory where python datadir suffix defaults
+                  to package dir.
+
+        Notes
+        -----
+        Rules for installation paths:
+          foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar
+          (gun, foo/bar) -> parent/gun
+          foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b
+          (gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun
+          (gun/*, foo/*) -> parent/gun/a, parent/gun/b
+          /foo/bar -> (bar, /foo/bar) -> parent/bar
+          (gun, /foo/bar) -> parent/gun
+          (fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar
+
+        Examples
+        --------
+        For example suppose the source directory contains fun/foo.dat and
+        fun/bar/car.dat::
+
+            >>> self.add_data_dir('fun')                       #doctest: +SKIP
+            >>> self.add_data_dir(('sun', 'fun'))              #doctest: +SKIP
+            >>> self.add_data_dir(('gun', '/full/path/to/fun'))#doctest: +SKIP
+
+        Will install data-files to the locations::
+
+            <package install directory>/
+              fun/
+                foo.dat
+                bar/
+                  car.dat
+              sun/
+                foo.dat
+                bar/
+                  car.dat
+              gun/
+                foo.dat
+                car.dat
+        """
+        if is_sequence(data_path):
+            d, data_path = data_path
+        else:
+            d = None
+        if is_sequence(data_path):
+            [self.add_data_dir((d, p)) for p in data_path]
+            return
+        if not is_string(data_path):
+            raise TypeError("not a string: %r" % (data_path,))
+        if d is None:
+            if os.path.isabs(data_path):
+                return self.add_data_dir((os.path.basename(data_path), data_path))
+            return self.add_data_dir((data_path, data_path))
+        paths = self.paths(data_path, include_non_existing=False)
+        if is_glob_pattern(data_path):
+            if is_glob_pattern(d):
+                pattern_list = allpath(d).split(os.sep)
+                pattern_list.reverse()
+                # /a/*//b/ -> /a/*/b
+                rl = list(range(len(pattern_list)-1)); rl.reverse()
+                for i in rl:
+                    if not pattern_list[i]:
+                        del pattern_list[i]
+                #
+                for path in paths:
+                    if not os.path.isdir(path):
+                        print('Not a directory, skipping', path)
+                        continue
+                    rpath = rel_path(path, self.local_path)
+                    path_list = rpath.split(os.sep)
+                    path_list.reverse()
+                    target_list = []
+                    i = 0
+                    for s in pattern_list:
+                        if is_glob_pattern(s):
+                            if i>=len(path_list):
+                                raise ValueError('cannot fill pattern %r with %r' \
+                                      % (d, path))
+                            target_list.append(path_list[i])
+                        else:
+                            assert s==path_list[i], repr((s, path_list[i], data_path, d, path, rpath))
+                            target_list.append(s)
+                        i += 1
+                    if path_list[i:]:
+                        self.warn('mismatch of pattern_list=%s and path_list=%s'\
+                                  % (pattern_list, path_list))
+                    target_list.reverse()
+                    self.add_data_dir((os.sep.join(target_list), path))
+            else:
+                for path in paths:
+                    self.add_data_dir((d, path))
+            return
+        assert not is_glob_pattern(d), repr(d)
+
+        dist = self.get_distribution()
+        if dist is not None and dist.data_files is not None:
+            data_files = dist.data_files
+        else:
+            data_files = self.data_files
+
+        for path in paths:
+            for d1, f in list(general_source_directories_files(path)):
+                target_path = os.path.join(self.path_in_package, d, d1)
+                data_files.append((target_path, f))
+
+    def _optimize_data_files(self):
+        data_dict = {}
+        for p, files in self.data_files:
+            if p not in data_dict:
+                data_dict[p] = set()
+            for f in files:
+                data_dict[p].add(f)
+        self.data_files[:] = [(p, list(files)) for p, files in data_dict.items()]
+
+    def add_data_files(self,*files):
+        """Add data files to configuration data_files.
+
+        Parameters
+        ----------
+        files : sequence
+            Argument(s) can be either
+
+                * 2-sequence (<datadir prefix>,<path to data file(s)>)
+                * paths to data files where python datadir prefix defaults
+                  to package dir.
+
+        Notes
+        -----
+        The form of each element of the files sequence is very flexible
+        allowing many combinations of where to get the files from the package
+        and where they should ultimately be installed on the system. The most
+        basic usage is for an element of the files argument sequence to be a
+        simple filename. This will cause that file from the local path to be
+        installed to the installation path of the self.name package (package
+        path). The file argument can also be a relative path in which case the
+        entire relative path will be installed into the package directory.
+        Finally, the file can be an absolute path name in which case the file
+        will be found at the absolute path name but installed to the package
+        path.
+
+        This basic behavior can be augmented by passing a 2-tuple in as the
+        file argument. The first element of the tuple should specify the
+        relative path (under the package install directory) where the
+        remaining sequence of files should be installed to (it has nothing to
+        do with the file-names in the source distribution). The second element
+        of the tuple is the sequence of files that should be installed. The
+        files in this sequence can be filenames, relative paths, or absolute
+        paths. For absolute paths the file will be installed in the top-level
+        package installation directory (regardless of the first argument).
+        Filenames and relative path names will be installed in the package
+        install directory under the path name given as the first element of
+        the tuple.
+
+        Rules for installation paths:
+
+          #. file.txt -> (., file.txt)-> parent/file.txt
+          #. foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt
+          #. /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt
+          #. *.txt -> parent/a.txt, parent/b.txt
+          #. foo/*.txt -> parent/foo/a.txt, parent/foo/b.txt
+          #. */*.txt -> (*, */*.txt) -> parent/c/a.txt, parent/d/b.txt
+          #. (sun, file.txt) -> parent/sun/file.txt
+          #. (sun, bar/file.txt) -> parent/sun/file.txt
+          #. (sun, /foo/bar/file.txt) -> parent/sun/file.txt
+          #. (sun, *.txt) -> parent/sun/a.txt, parent/sun/b.txt
+          #. (sun, bar/*.txt) -> parent/sun/a.txt, parent/sun/b.txt
+          #. (sun/*, */*.txt) -> parent/sun/c/a.txt, parent/d/b.txt
+
+        An additional feature is that the path to a data-file can actually be
+        a function that takes no arguments and returns the actual path(s) to
+        the data-files. This is useful when the data files are generated while
+        building the package.
+
+        Examples
+        --------
+        Add files to the list of data_files to be included with the package.
+
+            >>> self.add_data_files('foo.dat',
+            ...     ('fun', ['gun.dat', 'nun/pun.dat', '/tmp/sun.dat']),
+            ...     'bar/cat.dat',
+            ...     '/full/path/to/can.dat')                   #doctest: +SKIP
+
+        will install these data files to::
+
+            <package install directory>/
+             foo.dat
+             fun/
+               gun.dat
+               nun/
+                 pun.dat
+             sun.dat
+             bar/
+               car.dat
+             can.dat
+
+        where <package install directory> is the package (or sub-package)
+        directory such as '/usr/lib/python2.4/site-packages/mypackage' ('C:
+        \\Python2.4 \\Lib \\site-packages \\mypackage') or
+        '/usr/lib/python2.4/site- packages/mypackage/mysubpackage' ('C:
+        \\Python2.4 \\Lib \\site-packages \\mypackage \\mysubpackage').
+        """
+
+        if len(files)>1:
+            for f in files:
+                self.add_data_files(f)
+            return
+        assert len(files)==1
+        if is_sequence(files[0]):
+            d, files = files[0]
+        else:
+            d = None
+        if is_string(files):
+            filepat = files
+        elif is_sequence(files):
+            if len(files)==1:
+                filepat = files[0]
+            else:
+                for f in files:
+                    self.add_data_files((d, f))
+                return
+        else:
+            raise TypeError(repr(type(files)))
+
+        if d is None:
+            if hasattr(filepat, '__call__'):
+                d = ''
+            elif os.path.isabs(filepat):
+                d = ''
+            else:
+                d = os.path.dirname(filepat)
+            self.add_data_files((d, files))
+            return
+
+        paths = self.paths(filepat, include_non_existing=False)
+        if is_glob_pattern(filepat):
+            if is_glob_pattern(d):
+                pattern_list = d.split(os.sep)
+                pattern_list.reverse()
+                for path in paths:
+                    path_list = path.split(os.sep)
+                    path_list.reverse()
+                    path_list.pop() # filename
+                    target_list = []
+                    i = 0
+                    for s in pattern_list:
+                        if is_glob_pattern(s):
+                            target_list.append(path_list[i])
+                            i += 1
+                        else:
+                            target_list.append(s)
+                    target_list.reverse()
+                    self.add_data_files((os.sep.join(target_list), path))
+            else:
+                self.add_data_files((d, paths))
+            return
+        assert not is_glob_pattern(d), repr((d, filepat))
+
+        dist = self.get_distribution()
+        if dist is not None and dist.data_files is not None:
+            data_files = dist.data_files
+        else:
+            data_files = self.data_files
+
+        data_files.append((os.path.join(self.path_in_package, d), paths))
+
+    ### XXX Implement add_py_modules
+
+    def add_define_macros(self, macros):
+        """Add define macros to configuration
+
+        Add the given sequence of macro name and value duples to the beginning
+        of the define_macros list This list will be visible to all extension
+        modules of the current package.
+        """
+        dist = self.get_distribution()
+        if dist is not None:
+            if not hasattr(dist, 'define_macros'):
+                dist.define_macros = []
+            dist.define_macros.extend(macros)
+        else:
+            self.define_macros.extend(macros)
+
+
+    def add_include_dirs(self,*paths):
+        """Add paths to configuration include directories.
+
+        Add the given sequence of paths to the beginning of the include_dirs
+        list. This list will be visible to all extension modules of the
+        current package.
+        """
+        include_dirs = self.paths(paths)
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.include_dirs is None:
+                dist.include_dirs = []
+            dist.include_dirs.extend(include_dirs)
+        else:
+            self.include_dirs.extend(include_dirs)
+
+    def add_headers(self,*files):
+        """Add installable headers to configuration.
+
+        Add the given sequence of files to the beginning of the headers list.
+        By default, headers will be installed under <python-
+        include>/<self.name.replace('.','/')>/ directory. If an item of files
+        is a tuple, then its first argument specifies the actual installation
+        location relative to the <python-include> path.
+
+        Parameters
+        ----------
+        files : str or seq
+            Argument(s) can be either:
+
+                * 2-sequence (<includedir suffix>,<path to header file(s)>)
+                * path(s) to header file(s) where python includedir suffix will
+                  default to package name.
+        """
+        headers = []
+        for path in files:
+            if is_string(path):
+                [headers.append((self.name, p)) for p in self.paths(path)]
+            else:
+                if not isinstance(path, (tuple, list)) or len(path) != 2:
+                    raise TypeError(repr(path))
+                [headers.append((path[0], p)) for p in self.paths(path[1])]
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.headers is None:
+                dist.headers = []
+            dist.headers.extend(headers)
+        else:
+            self.headers.extend(headers)
+
+    def paths(self,*paths,**kws):
+        """Apply glob to paths and prepend local_path if needed.
+
+        Applies glob.glob(...) to each path in the sequence (if needed) and
+        pre-pends the local_path if needed. Because this is called on all
+        source lists, this allows wildcard characters to be specified in lists
+        of sources for extension modules and libraries and scripts and allows
+        path-names be relative to the source directory.
+
+        """
+        include_non_existing = kws.get('include_non_existing', True)
+        return gpaths(paths,
+                      local_path = self.local_path,
+                      include_non_existing=include_non_existing)
+
+    def _fix_paths_dict(self, kw):
+        for k in kw.keys():
+            v = kw[k]
+            if k in ['sources', 'depends', 'include_dirs', 'library_dirs',
+                     'module_dirs', 'extra_objects']:
+                new_v = self.paths(v)
+                kw[k] = new_v
+
+    def add_extension(self,name,sources,**kw):
+        """Add extension to configuration.
+
+        Create and add an Extension instance to the ext_modules list. This
+        method also takes the following optional keyword arguments that are
+        passed on to the Extension constructor.
+
+        Parameters
+        ----------
+        name : str
+            name of the extension
+        sources : seq
+            list of the sources. The list of sources may contain functions
+            (called source generators) which must take an extension instance
+            and a build directory as inputs and return a source file or list of
+            source files or None. If None is returned then no sources are
+            generated. If the Extension instance has no sources after
+            processing all source generators, then no extension module is
+            built.
+        include_dirs :
+        define_macros :
+        undef_macros :
+        library_dirs :
+        libraries :
+        runtime_library_dirs :
+        extra_objects :
+        extra_compile_args :
+        extra_link_args :
+        extra_f77_compile_args :
+        extra_f90_compile_args :
+        export_symbols :
+        swig_opts :
+        depends :
+            The depends list contains paths to files or directories that the
+            sources of the extension module depend on. If any path in the
+            depends list is newer than the extension module, then the module
+            will be rebuilt.
+        language :
+        f2py_options :
+        module_dirs :
+        extra_info : dict or list
+            dict or list of dict of keywords to be appended to keywords.
+
+        Notes
+        -----
+        The self.paths(...) method is applied to all lists that may contain
+        paths.
+        """
+        ext_args = copy.copy(kw)
+        ext_args['name'] = dot_join(self.name, name)
+        ext_args['sources'] = sources
+
+        if 'extra_info' in ext_args:
+            extra_info = ext_args['extra_info']
+            del ext_args['extra_info']
+            if isinstance(extra_info, dict):
+                extra_info = [extra_info]
+            for info in extra_info:
+                assert isinstance(info, dict), repr(info)
+                dict_append(ext_args,**info)
+
+        self._fix_paths_dict(ext_args)
+
+        # Resolve out-of-tree dependencies
+        libraries = ext_args.get('libraries', [])
+        libnames = []
+        ext_args['libraries'] = []
+        for libname in libraries:
+            if isinstance(libname, tuple):
+                self._fix_paths_dict(libname[1])
+
+            # Handle library names of the form libname@relative/path/to/library
+            if '@' in libname:
+                lname, lpath = libname.split('@', 1)
+                lpath = os.path.abspath(njoin(self.local_path, lpath))
+                if os.path.isdir(lpath):
+                    c = self.get_subpackage(None, lpath,
+                                            caller_level = 2)
+                    if isinstance(c, Configuration):
+                        c = c.todict()
+                    for l in [l[0] for l in c.get('libraries', [])]:
+                        llname = l.split('__OF__', 1)[0]
+                        if llname == lname:
+                            c.pop('name', None)
+                            dict_append(ext_args,**c)
+                            break
+                    continue
+            libnames.append(libname)
+
+        ext_args['libraries'] = libnames + ext_args['libraries']
+        ext_args['define_macros'] = \
+            self.define_macros + ext_args.get('define_macros', [])
+
+        from numpy.distutils.core import Extension
+        ext = Extension(**ext_args)
+        self.ext_modules.append(ext)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add an extension '+name)
+        return ext
+
+    def add_library(self,name,sources,**build_info):
+        """
+        Add library to configuration.
+
+        Parameters
+        ----------
+        name : str
+            Name of the extension.
+        sources : sequence
+            List of the sources. The list of sources may contain functions
+            (called source generators) which must take an extension instance
+            and a build directory as inputs and return a source file or list of
+            source files or None. If None is returned then no sources are
+            generated. If the Extension instance has no sources after
+            processing all source generators, then no extension module is
+            built.
+        build_info : dict, optional
+            The following keys are allowed:
+
+                * depends
+                * macros
+                * include_dirs
+                * extra_compiler_args
+                * extra_f77_compiler_args
+                * extra_f90_compiler_args
+                * f2py_options
+                * language
+
+        """
+        self._add_library(name, sources, None, build_info)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add a library '+ name)
+
+    def _add_library(self, name, sources, install_dir, build_info):
+        """Common implementation for add_library and add_installed_library. Do
+        not use directly"""
+        build_info = copy.copy(build_info)
+        name = name #+ '__OF__' + self.name
+        build_info['sources'] = sources
+
+        # Sometimes, depends is not set up to an empty list by default, and if
+        # depends is not given to add_library, distutils barfs (#1134)
+        if not 'depends' in build_info:
+            build_info['depends'] = []
+
+        self._fix_paths_dict(build_info)
+
+        # Add to libraries list so that it is build with build_clib
+        self.libraries.append((name, build_info))
+
+    def add_installed_library(self, name, sources, install_dir, build_info=None):
+        """
+        Similar to add_library, but the specified library is installed.
+
+        Most C libraries used with `distutils` are only used to build python
+        extensions, but libraries built through this method will be installed
+        so that they can be reused by third-party packages.
+
+        Parameters
+        ----------
+        name : str
+            Name of the installed library.
+        sources : sequence
+            List of the library's source files. See `add_library` for details.
+        install_dir : str
+            Path to install the library, relative to the current sub-package.
+        build_info : dict, optional
+            The following keys are allowed:
+
+                * depends
+                * macros
+                * include_dirs
+                * extra_compiler_args
+                * extra_f77_compiler_args
+                * extra_f90_compiler_args
+                * f2py_options
+                * language
+
+        Returns
+        -------
+        None
+
+        See Also
+        --------
+        add_library, add_npy_pkg_config, get_info
+
+        Notes
+        -----
+        The best way to encode the options required to link against the specified
+        C libraries is to use a "libname.ini" file, and use `get_info` to
+        retrieve the required options (see `add_npy_pkg_config` for more
+        information).
+
+        """
+        if not build_info:
+            build_info = {}
+
+        install_dir = os.path.join(self.package_path, install_dir)
+        self._add_library(name, sources, install_dir, build_info)
+        self.installed_libraries.append(InstallableLib(name, build_info, install_dir))
+
+    def add_npy_pkg_config(self, template, install_dir, subst_dict=None):
+        """
+        Generate and install a npy-pkg config file from a template.
+
+        The config file generated from `template` is installed in the
+        given install directory, using `subst_dict` for variable substitution.
+
+        Parameters
+        ----------
+        template : str
+            The path of the template, relatively to the current package path.
+        install_dir : str
+            Where to install the npy-pkg config file, relatively to the current
+            package path.
+        subst_dict : dict, optional
+            If given, any string of the form ``@key@`` will be replaced by
+            ``subst_dict[key]`` in the template file when installed. The install
+            prefix is always available through the variable ``@prefix@``, since the
+            install prefix is not easy to get reliably from setup.py.
+
+        See also
+        --------
+        add_installed_library, get_info
+
+        Notes
+        -----
+        This works for both standard installs and in-place builds, i.e. the
+        ``@prefix@`` refer to the source directory for in-place builds.
+
+        Examples
+        --------
+        ::
+
+            config.add_npy_pkg_config('foo.ini.in', 'lib', {'foo': bar})
+
+        Assuming the foo.ini.in file has the following content::
+
+            [meta]
+            Name=@foo@
+            Version=1.0
+            Description=dummy description
+
+            [default]
+            Cflags=-I@prefix@/include
+            Libs=
+
+        The generated file will have the following content::
+
+            [meta]
+            Name=bar
+            Version=1.0
+            Description=dummy description
+
+            [default]
+            Cflags=-Iprefix_dir/include
+            Libs=
+
+        and will be installed as foo.ini in the 'lib' subpath.
+
+        """
+        if subst_dict is None:
+            subst_dict = {}
+        basename = os.path.splitext(template)[0]
+        template = os.path.join(self.package_path, template)
+
+        if self.name in self.installed_pkg_config:
+            self.installed_pkg_config[self.name].append((template, install_dir,
+                subst_dict))
+        else:
+            self.installed_pkg_config[self.name] = [(template, install_dir,
+                subst_dict)]
+
+
+    def add_scripts(self,*files):
+        """Add scripts to configuration.
+
+        Add the sequence of files to the beginning of the scripts list.
+        Scripts will be installed under the <prefix>/bin/ directory.
+
+        """
+        scripts = self.paths(files)
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.scripts is None:
+                dist.scripts = []
+            dist.scripts.extend(scripts)
+        else:
+            self.scripts.extend(scripts)
+
+    def dict_append(self,**dict):
+        for key in self.list_keys:
+            a = getattr(self, key)
+            a.extend(dict.get(key, []))
+        for key in self.dict_keys:
+            a = getattr(self, key)
+            a.update(dict.get(key, {}))
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        for key in dict.keys():
+            if key not in known_keys:
+                a = getattr(self, key, None)
+                if a and a==dict[key]: continue
+                self.warn('Inheriting attribute %r=%r from %r' \
+                          % (key, dict[key], dict.get('name', '?')))
+                setattr(self, key, dict[key])
+                self.extra_keys.append(key)
+            elif key in self.extra_keys:
+                self.info('Ignoring attempt to set %r (from %r to %r)' \
+                          % (key, getattr(self, key), dict[key]))
+            elif key in known_keys:
+                # key is already processed above
+                pass
+            else:
+                raise ValueError("Don't know about key=%r" % (key))
+
+    def __str__(self):
+        from pprint import pformat
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        s = '<'+5*'-' + '\n'
+        s += 'Configuration of '+self.name+':\n'
+        known_keys.sort()
+        for k in known_keys:
+            a = getattr(self, k, None)
+            if a:
+                s += '%s = %s\n' % (k, pformat(a))
+        s += 5*'-' + '>'
+        return s
+
+    def get_config_cmd(self):
+        """
+        Returns the numpy.distutils config command instance.
+        """
+        cmd = get_cmd('config')
+        cmd.ensure_finalized()
+        cmd.dump_source = 0
+        cmd.noisy = 0
+        old_path = os.environ.get('PATH')
+        if old_path:
+            path = os.pathsep.join(['.', old_path])
+            os.environ['PATH'] = path
+        return cmd
+
+    def get_build_temp_dir(self):
+        """
+        Return a path to a temporary directory where temporary files should be
+        placed.
+        """
+        cmd = get_cmd('build')
+        cmd.ensure_finalized()
+        return cmd.build_temp
+
+    def have_f77c(self):
+        """Check for availability of Fortran 77 compiler.
+
+        Use it inside source generating function to ensure that
+        setup distribution instance has been initialized.
+
+        Notes
+        -----
+        True if a Fortran 77 compiler is available (because a simple Fortran 77
+        code was able to be compiled successfully).
+        """
+        simple_fortran_subroutine = '''
+        subroutine simple
+        end
+        '''
+        config_cmd = self.get_config_cmd()
+        flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f77')
+        return flag
+
+    def have_f90c(self):
+        """Check for availability of Fortran 90 compiler.
+
+        Use it inside source generating function to ensure that
+        setup distribution instance has been initialized.
+
+        Notes
+        -----
+        True if a Fortran 90 compiler is available (because a simple Fortran
+        90 code was able to be compiled successfully)
+        """
+        simple_fortran_subroutine = '''
+        subroutine simple
+        end
+        '''
+        config_cmd = self.get_config_cmd()
+        flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f90')
+        return flag
+
+    def append_to(self, extlib):
+        """Append libraries, include_dirs to extension or library item.
+        """
+        if is_sequence(extlib):
+            lib_name, build_info = extlib
+            dict_append(build_info,
+                        libraries=self.libraries,
+                        include_dirs=self.include_dirs)
+        else:
+            from numpy.distutils.core import Extension
+            assert isinstance(extlib, Extension), repr(extlib)
+            extlib.libraries.extend(self.libraries)
+            extlib.include_dirs.extend(self.include_dirs)
+
+    def _get_svn_revision(self, path):
+        """Return path's SVN revision number.
+        """
+        revision = None
+        m = None
+        cwd =  os.getcwd()
+        try:
+            os.chdir(path or '.')
+            p = subprocess.Popen(['svnversion'], shell=True,
+                    stdout=subprocess.PIPE, stderr=None,
+                    close_fds=True)
+            sout = p.stdout
+            m = re.match(r'(?P<revision>\d+)', sout.read())
+        except:
+            pass
+        os.chdir(cwd)
+        if m:
+            revision = int(m.group('revision'))
+            return revision
+        if sys.platform=='win32' and os.environ.get('SVN_ASP_DOT_NET_HACK', None):
+            entries = njoin(path, '_svn', 'entries')
+        else:
+            entries = njoin(path, '.svn', 'entries')
+        if os.path.isfile(entries):
+            f = open(entries)
+            fstr = f.read()
+            f.close()
+            if fstr[:5] == '<?xml':  # pre 1.4
+                m = re.search(r'revision="(?P<revision>\d+)"', fstr)
+                if m:
+                    revision = int(m.group('revision'))
+            else:  # non-xml entries file --- check to be sure that
+                m = re.search(r'dir[\n\r]+(?P<revision>\d+)', fstr)
+                if m:
+                    revision = int(m.group('revision'))
+        return revision
+
+    def _get_hg_revision(self, path):
+        """Return path's Mercurial revision number.
+        """
+        revision = None
+        m = None
+        cwd =  os.getcwd()
+        try:
+            os.chdir(path or '.')
+            p = subprocess.Popen(['hg identify --num'], shell=True,
+                    stdout=subprocess.PIPE, stderr=None,
+                    close_fds=True)
+            sout = p.stdout
+            m = re.match(r'(?P<revision>\d+)', sout.read())
+        except:
+            pass
+        os.chdir(cwd)
+        if m:
+            revision = int(m.group('revision'))
+            return revision
+        branch_fn = njoin(path, '.hg', 'branch')
+        branch_cache_fn = njoin(path, '.hg', 'branch.cache')
+
+        if os.path.isfile(branch_fn):
+            branch0 = None
+            f = open(branch_fn)
+            revision0 = f.read().strip()
+            f.close()
+
+            branch_map = {}
+            for line in file(branch_cache_fn, 'r'):
+                branch1, revision1  = line.split()[:2]
+                if revision1==revision0:
+                    branch0 = branch1
+                try:
+                    revision1 = int(revision1)
+                except ValueError:
+                    continue
+                branch_map[branch1] = revision1
+
+            revision = branch_map.get(branch0)
+        return revision
+
+
+    def get_version(self, version_file=None, version_variable=None):
+        """Try to get version string of a package.
+
+        Return a version string of the current package or None if the version
+        information could not be detected.
+
+        Notes
+        -----
+        This method scans files named
+        __version__.py, <packagename>_version.py, version.py, and
+        __svn_version__.py for string variables version, __version\__, and
+        <packagename>_version, until a version number is found.
+        """
+        version = getattr(self, 'version', None)
+        if version is not None:
+            return version
+
+        # Get version from version file.
+        if version_file is None:
+            files = ['__version__.py',
+                     self.name.split('.')[-1]+'_version.py',
+                     'version.py',
+                     '__svn_version__.py',
+                     '__hg_version__.py']
+        else:
+            files = [version_file]
+        if version_variable is None:
+            version_vars = ['version',
+                            '__version__',
+                            self.name.split('.')[-1]+'_version']
+        else:
+            version_vars = [version_variable]
+        for f in files:
+            fn = njoin(self.local_path, f)
+            if os.path.isfile(fn):
+                info = (open(fn), fn, ('.py', 'U', 1))
+                name = os.path.splitext(os.path.basename(fn))[0]
+                n = dot_join(self.name, name)
+                try:
+                    version_module = imp.load_module('_'.join(n.split('.')),*info)
+                except ImportError:
+                    msg = get_exception()
+                    self.warn(str(msg))
+                    version_module = None
+                if version_module is None:
+                    continue
+
+                for a in version_vars:
+                    version = getattr(version_module, a, None)
+                    if version is not None:
+                        break
+                if version is not None:
+                    break
+
+        if version is not None:
+            self.version = version
+            return version
+
+        # Get version as SVN or Mercurial revision number
+        revision = self._get_svn_revision(self.local_path)
+        if revision is None:
+            revision = self._get_hg_revision(self.local_path)
+
+        if revision is not None:
+            version = str(revision)
+            self.version = version
+
+        return version
+
+    def make_svn_version_py(self, delete=True):
+        """Appends a data function to the data_files list that will generate
+        __svn_version__.py file to the current package directory.
+
+        Generate package __svn_version__.py file from SVN revision number,
+        it will be removed after python exits but will be available
+        when sdist, etc commands are executed.
+
+        Notes
+        -----
+        If __svn_version__.py existed before, nothing is done.
+
+        This is
+        intended for working with source directories that are in an SVN
+        repository.
+        """
+        target = njoin(self.local_path, '__svn_version__.py')
+        revision = self._get_svn_revision(self.local_path)
+        if os.path.isfile(target) or revision is None:
+            return
+        else:
+            def generate_svn_version_py():
+                if not os.path.isfile(target):
+                    version = str(revision)
+                    self.info('Creating %s (version=%r)' % (target, version))
+                    f = open(target, 'w')
+                    f.write('version = %r\n' % (version))
+                    f.close()
+
+                import atexit
+                def rm_file(f=target,p=self.info):
+                    if delete:
+                        try: os.remove(f); p('removed '+f)
+                        except OSError: pass
+                        try: os.remove(f+'c'); p('removed '+f+'c')
+                        except OSError: pass
+
+                atexit.register(rm_file)
+
+                return target
+
+            self.add_data_files(('', generate_svn_version_py()))
+
+    def make_hg_version_py(self, delete=True):
+        """Appends a data function to the data_files list that will generate
+        __hg_version__.py file to the current package directory.
+
+        Generate package __hg_version__.py file from Mercurial revision,
+        it will be removed after python exits but will be available
+        when sdist, etc commands are executed.
+
+        Notes
+        -----
+        If __hg_version__.py existed before, nothing is done.
+
+        This is intended for working with source directories that are
+        in an Mercurial repository.
+        """
+        target = njoin(self.local_path, '__hg_version__.py')
+        revision = self._get_hg_revision(self.local_path)
+        if os.path.isfile(target) or revision is None:
+            return
+        else:
+            def generate_hg_version_py():
+                if not os.path.isfile(target):
+                    version = str(revision)
+                    self.info('Creating %s (version=%r)' % (target, version))
+                    f = open(target, 'w')
+                    f.write('version = %r\n' % (version))
+                    f.close()
+
+                import atexit
+                def rm_file(f=target,p=self.info):
+                    if delete:
+                        try: os.remove(f); p('removed '+f)
+                        except OSError: pass
+                        try: os.remove(f+'c'); p('removed '+f+'c')
+                        except OSError: pass
+
+                atexit.register(rm_file)
+
+                return target
+
+            self.add_data_files(('', generate_hg_version_py()))
+
+    def make_config_py(self,name='__config__'):
+        """Generate package __config__.py file containing system_info
+        information used during building the package.
+
+        This file is installed to the
+        package installation directory.
+
+        """
+        self.py_modules.append((self.name, name, generate_config_py))
+
+
+    def get_info(self,*names):
+        """Get resources information.
+
+        Return information (from system_info.get_info) for all of the names in
+        the argument list in a single dictionary.
+        """
+        from .system_info import get_info, dict_append
+        info_dict = {}
+        for a in names:
+            dict_append(info_dict,**get_info(a))
+        return info_dict
+
+
+def get_cmd(cmdname, _cache={}):
+    if cmdname not in _cache:
+        import distutils.core
+        dist = distutils.core._setup_distribution
+        if dist is None:
+            from distutils.errors import DistutilsInternalError
+            raise DistutilsInternalError(
+                  'setup distribution instance not initialized')
+        cmd = dist.get_command_obj(cmdname)
+        _cache[cmdname] = cmd
+    return _cache[cmdname]
+
+def get_numpy_include_dirs():
+    # numpy_include_dirs are set by numpy/core/setup.py, otherwise []
+    include_dirs = Configuration.numpy_include_dirs[:]
+    if not include_dirs:
+        import numpy
+        include_dirs = [ numpy.get_include() ]
+    # else running numpy/core/setup.py
+    return include_dirs
+
+def get_npy_pkg_dir():
+    """Return the path where to find the npy-pkg-config directory."""
+    # XXX: import here for bootstrapping reasons
+    import numpy
+    d = os.path.join(os.path.dirname(numpy.__file__),
+            'core', 'lib', 'npy-pkg-config')
+    return d
+
+def get_pkg_info(pkgname, dirs=None):
+    """
+    Return library info for the given package.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of additional directories where to look
+        for npy-pkg-config files. Those directories are searched prior to the
+        NumPy directory.
+
+    Returns
+    -------
+    pkginfo : class instance
+        The `LibraryInfo` instance containing the build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    Configuration.add_npy_pkg_config, Configuration.add_installed_library,
+    get_info
+
+    """
+    from numpy.distutils.npy_pkg_config import read_config
+
+    if dirs:
+        dirs.append(get_npy_pkg_dir())
+    else:
+        dirs = [get_npy_pkg_dir()]
+    return read_config(pkgname, dirs)
+
+def get_info(pkgname, dirs=None):
+    """
+    Return an info dict for a given C library.
+
+    The info dict contains the necessary options to use the C library.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of additional directories where to look
+        for npy-pkg-config files. Those directories are searched prior to the
+        NumPy directory.
+
+    Returns
+    -------
+    info : dict
+        The dictionary with build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    Configuration.add_npy_pkg_config, Configuration.add_installed_library,
+    get_pkg_info
+
+    Examples
+    --------
+    To get the necessary information for the npymath library from NumPy:
+
+    >>> npymath_info = np.distutils.misc_util.get_info('npymath')
+    >>> npymath_info                                    #doctest: +SKIP
+    {'define_macros': [], 'libraries': ['npymath'], 'library_dirs':
+    ['.../numpy/core/lib'], 'include_dirs': ['.../numpy/core/include']}
+
+    This info dict can then be used as input to a `Configuration` instance::
+
+      config.add_extension('foo', sources=['foo.c'], extra_info=npymath_info)
+
+    """
+    from numpy.distutils.npy_pkg_config import parse_flags
+    pkg_info = get_pkg_info(pkgname, dirs)
+
+    # Translate LibraryInfo instance into a build_info dict
+    info = parse_flags(pkg_info.cflags())
+    for k, v in parse_flags(pkg_info.libs()).items():
+        info[k].extend(v)
+
+    # add_extension extra_info argument is ANAL
+    info['define_macros'] = info['macros']
+    del info['macros']
+    del info['ignored']
+
+    return info
+
+def is_bootstrapping():
+    if sys.version_info[0] >= 3:
+        import builtins
+    else:
+        import __builtin__ as builtins
+
+    try:
+        builtins.__NUMPY_SETUP__
+        return True
+    except AttributeError:
+        return False
+        __NUMPY_SETUP__ = False
+
+
+#########################
+
+def default_config_dict(name = None, parent_name = None, local_path=None):
+    """Return a configuration dictionary for usage in
+    configuration() function defined in file setup_<name>.py.
+    """
+    import warnings
+    warnings.warn('Use Configuration(%r,%r,top_path=%r) instead of '\
+                  'deprecated default_config_dict(%r,%r,%r)'
+                  % (name, parent_name, local_path,
+                     name, parent_name, local_path,
+                     ))
+    c = Configuration(name, parent_name, local_path)
+    return c.todict()
+
+
+def dict_append(d, **kws):
+    for k, v in kws.items():
+        if k in d:
+            ov = d[k]
+            if isinstance(ov, str):
+                d[k] = v
+            else:
+                d[k].extend(v)
+        else:
+            d[k] = v
+
+def appendpath(prefix, path):
+    if os.path.sep != '/':
+        prefix = prefix.replace('/', os.path.sep)
+        path = path.replace('/', os.path.sep)
+    drive = ''
+    if os.path.isabs(path):
+        drive = os.path.splitdrive(prefix)[0]
+        absprefix = os.path.splitdrive(os.path.abspath(prefix))[1]
+        pathdrive, path = os.path.splitdrive(path)
+        d = os.path.commonprefix([absprefix, path])
+        if os.path.join(absprefix[:len(d)], absprefix[len(d):]) != absprefix \
+           or os.path.join(path[:len(d)], path[len(d):]) != path:
+            # Handle invalid paths
+            d = os.path.dirname(d)
+        subpath = path[len(d):]
+        if os.path.isabs(subpath):
+            subpath = subpath[1:]
+    else:
+        subpath = path
+    return os.path.normpath(njoin(drive + prefix, subpath))
+
+def generate_config_py(target):
+    """Generate config.py file containing system_info information
+    used during building the package.
+
+    Usage:
+        config['py_modules'].append((packagename, '__config__',generate_config_py))
+    """
+    from numpy.distutils.system_info import system_info
+    from distutils.dir_util import mkpath
+    mkpath(os.path.dirname(target))
+    f = open(target, 'w')
+    f.write('# This file is generated by %s\n' % (os.path.abspath(sys.argv[0])))
+    f.write('# It contains system_info results at the time of building this package.\n')
+    f.write('__all__ = ["get_info","show"]\n\n')
+    for k, i in system_info.saved_results.items():
+        f.write('%s=%r\n' % (k, i))
+    f.write(r'''
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    ''')
+
+    f.close()
+    return target
+
+def msvc_version(compiler):
+    """Return version major and minor of compiler instance if it is
+    MSVC, raise an exception otherwise."""
+    if not compiler.compiler_type == "msvc":
+        raise ValueError("Compiler instance is not msvc (%s)"\
+                         % compiler.compiler_type)
+    return compiler._MSVCCompiler__version
+
+if sys.version[:3] >= '2.5':
+    def get_build_architecture():
+        from distutils.msvccompiler import get_build_architecture
+        return get_build_architecture()
+else:
+    #copied from python 2.5.1 distutils/msvccompiler.py
+    def get_build_architecture():
+        """Return the processor architecture.
+
+        Possible results are "Intel", "Itanium", or "AMD64".
+        """
+        prefix = " bit ("
+        i = sys.version.find(prefix)
+        if i == -1:
+            return "Intel"
+        j = sys.version.find(")", i)
+        return sys.version[i+len(prefix):j]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
new file mode 100644
index 0000000000..c53f45531c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
@@ -0,0 +1,25 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import distutils.msvc9compiler
+from distutils.msvc9compiler import *
+
+
+class MSVCCompiler(distutils.msvc9compiler.MSVCCompiler):
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        distutils.msvc9compiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
+
+    def initialize(self, plat_name=None):
+        environ_lib = os.getenv('lib')
+        environ_include = os.getenv('include')
+        distutils.msvc9compiler.MSVCCompiler.initialize(self, plat_name)
+        if environ_lib is not None:
+            os.environ['lib'] = environ_lib + os.environ['lib']
+        if environ_include is not None:
+            os.environ['include'] = environ_include + os.environ['include']
+
+    def manifest_setup_ldargs(self, output_filename, build_temp, ld_args):
+        ld_args.append('/MANIFEST')
+        distutils.msvc9compiler.MSVCCompiler.manifest_setup_ldargs(self,
+                                                                   output_filename,
+                                                                   build_temp, ld_args)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
new file mode 100644
index 0000000000..9e0eb8e100
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
@@ -0,0 +1,26 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import distutils.msvccompiler
+from distutils.msvccompiler import *
+
+from .system_info import platform_bits
+
+
+class MSVCCompiler(distutils.msvccompiler.MSVCCompiler):
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        distutils.msvccompiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
+
+    def initialize(self, plat_name=None):
+        environ_lib = os.getenv('lib')
+        environ_include = os.getenv('include')
+        distutils.msvccompiler.MSVCCompiler.initialize(self)
+        if environ_lib is not None:
+            os.environ['lib'] = environ_lib + os.environ['lib']
+        if environ_include is not None:
+            os.environ['include'] = environ_include + os.environ['include']
+        if platform_bits == 32:
+            # msvc9 building for 32 bits requires SSE2 to work around a
+            # compiler bug.
+            self.compile_options += ['/arch:SSE2']
+            self.compile_options_debug += ['/arch:SSE2']
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
new file mode 100644
index 0000000000..fe64709ca2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
@@ -0,0 +1,450 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+import os
+
+if sys.version_info[0] < 3:
+    from ConfigParser import SafeConfigParser, NoOptionError
+else:
+    from configparser import ConfigParser, SafeConfigParser, NoOptionError
+
+__all__ = ['FormatError', 'PkgNotFound', 'LibraryInfo', 'VariableSet',
+        'read_config', 'parse_flags']
+
+_VAR = re.compile('\$\{([a-zA-Z0-9_-]+)\}')
+
+class FormatError(IOError):
+    """
+    Exception thrown when there is a problem parsing a configuration file.
+
+    """
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return self.msg
+
+class PkgNotFound(IOError):
+    """Exception raised when a package can not be located."""
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return self.msg
+
+def parse_flags(line):
+    """
+    Parse a line from a config file containing compile flags.
+
+    Parameters
+    ----------
+    line : str
+        A single line containing one or more compile flags.
+
+    Returns
+    -------
+    d : dict
+        Dictionary of parsed flags, split into relevant categories.
+        These categories are the keys of `d`:
+
+        * 'include_dirs'
+        * 'library_dirs'
+        * 'libraries'
+        * 'macros'
+        * 'ignored'
+
+    """
+    d = {'include_dirs': [], 'library_dirs': [], 'libraries': [],
+         'macros': [], 'ignored': []}
+
+    flags = (' ' + line).split(' -')
+    for flag in flags:
+        flag = '-' + flag
+        if len(flag) > 0:
+            if flag.startswith('-I'):
+                d['include_dirs'].append(flag[2:].strip())
+            elif flag.startswith('-L'):
+                d['library_dirs'].append(flag[2:].strip())
+            elif flag.startswith('-l'):
+                d['libraries'].append(flag[2:].strip())
+            elif flag.startswith('-D'):
+                d['macros'].append(flag[2:].strip())
+            else:
+                d['ignored'].append(flag)
+
+    return d
+
+def _escape_backslash(val):
+    return val.replace('\\', '\\\\')
+
+class LibraryInfo(object):
+    """
+    Object containing build information about a library.
+
+    Parameters
+    ----------
+    name : str
+        The library name.
+    description : str
+        Description of the library.
+    version : str
+        Version string.
+    sections : dict
+        The sections of the configuration file for the library. The keys are
+        the section headers, the values the text under each header.
+    vars : class instance
+        A `VariableSet` instance, which contains ``(name, value)`` pairs for
+        variables defined in the configuration file for the library.
+    requires : sequence, optional
+        The required libraries for the library to be installed.
+
+    Notes
+    -----
+    All input parameters (except "sections" which is a method) are available as
+    attributes of the same name.
+
+    """
+    def __init__(self, name, description, version, sections, vars, requires=None):
+        self.name = name
+        self.description = description
+        if requires:
+            self.requires = requires
+        else:
+            self.requires = []
+        self.version = version
+        self._sections = sections
+        self.vars = vars
+
+    def sections(self):
+        """
+        Return the section headers of the config file.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        keys : list of str
+            The list of section headers.
+
+        """
+        return list(self._sections.keys())
+
+    def cflags(self, section="default"):
+        val = self.vars.interpolate(self._sections[section]['cflags'])
+        return _escape_backslash(val)
+
+    def libs(self, section="default"):
+        val = self.vars.interpolate(self._sections[section]['libs'])
+        return _escape_backslash(val)
+
+    def __str__(self):
+        m = ['Name: %s' % self.name, 'Description: %s' % self.description]
+        if self.requires:
+            m.append('Requires:')
+        else:
+            m.append('Requires: %s' % ",".join(self.requires))
+        m.append('Version: %s' % self.version)
+
+        return "\n".join(m)
+
+class VariableSet(object):
+    """
+    Container object for the variables defined in a config file.
+
+    `VariableSet` can be used as a plain dictionary, with the variable names
+    as keys.
+
+    Parameters
+    ----------
+    d : dict
+        Dict of items in the "variables" section of the configuration file.
+
+    """
+    def __init__(self, d):
+        self._raw_data = dict([(k, v) for k, v in d.items()])
+
+        self._re = {}
+        self._re_sub = {}
+
+        self._init_parse()
+
+    def _init_parse(self):
+        for k, v in self._raw_data.items():
+            self._init_parse_var(k, v)
+
+    def _init_parse_var(self, name, value):
+        self._re[name] = re.compile(r'\$\{%s\}' % name)
+        self._re_sub[name] = value
+
+    def interpolate(self, value):
+        # Brute force: we keep interpolating until there is no '${var}' anymore
+        # or until interpolated string is equal to input string
+        def _interpolate(value):
+            for k in self._re.keys():
+                value = self._re[k].sub(self._re_sub[k], value)
+            return value
+        while _VAR.search(value):
+            nvalue = _interpolate(value)
+            if nvalue == value:
+                break
+            value = nvalue
+
+        return value
+
+    def variables(self):
+        """
+        Return the list of variable names.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        names : list of str
+            The names of all variables in the `VariableSet` instance.
+
+        """
+        return list(self._raw_data.keys())
+
+    # Emulate a dict to set/get variables values
+    def __getitem__(self, name):
+        return self._raw_data[name]
+
+    def __setitem__(self, name, value):
+        self._raw_data[name] = value
+        self._init_parse_var(name, value)
+
+def parse_meta(config):
+    if not config.has_section('meta'):
+        raise FormatError("No meta section found !")
+
+    d = {}
+    for name, value in config.items('meta'):
+        d[name] = value
+
+    for k in ['name', 'description', 'version']:
+        if not k in d:
+            raise FormatError("Option %s (section [meta]) is mandatory, "
+                "but not found" % k)
+
+    if not 'requires' in d:
+        d['requires'] = []
+
+    return d
+
+def parse_variables(config):
+    if not config.has_section('variables'):
+        raise FormatError("No variables section found !")
+
+    d = {}
+
+    for name, value in config.items("variables"):
+        d[name] = value
+
+    return VariableSet(d)
+
+def parse_sections(config):
+    return meta_d, r
+
+def pkg_to_filename(pkg_name):
+    return "%s.ini" % pkg_name
+
+def parse_config(filename, dirs=None):
+    if dirs:
+        filenames = [os.path.join(d, filename) for d in dirs]
+    else:
+        filenames = [filename]
+
+    if sys.version[:3] > '3.1':
+        # SafeConfigParser is deprecated in py-3.2 and renamed to ConfigParser
+        config = ConfigParser()
+    else:
+        config = SafeConfigParser()
+
+    n = config.read(filenames)
+    if not len(n) >= 1:
+        raise PkgNotFound("Could not find file(s) %s" % str(filenames))
+
+    # Parse meta and variables sections
+    meta = parse_meta(config)
+
+    vars = {}
+    if config.has_section('variables'):
+        for name, value in config.items("variables"):
+            vars[name] = _escape_backslash(value)
+
+    # Parse "normal" sections
+    secs = [s for s in config.sections() if not s in ['meta', 'variables']]
+    sections = {}
+
+    requires = {}
+    for s in secs:
+        d = {}
+        if config.has_option(s, "requires"):
+            requires[s] = config.get(s, 'requires')
+
+        for name, value in config.items(s):
+            d[name] = value
+        sections[s] = d
+
+    return meta, vars, sections, requires
+
+def _read_config_imp(filenames, dirs=None):
+    def _read_config(f):
+        meta, vars, sections, reqs = parse_config(f, dirs)
+        # recursively add sections and variables of required libraries
+        for rname, rvalue in reqs.items():
+            nmeta, nvars, nsections, nreqs = _read_config(pkg_to_filename(rvalue))
+
+            # Update var dict for variables not in 'top' config file
+            for k, v in nvars.items():
+                if not k in vars:
+                    vars[k] = v
+
+            # Update sec dict
+            for oname, ovalue in nsections[rname].items():
+                if ovalue:
+                    sections[rname][oname] += ' %s' % ovalue
+
+        return meta, vars, sections, reqs
+
+    meta, vars, sections, reqs = _read_config(filenames)
+
+    # FIXME: document this. If pkgname is defined in the variables section, and
+    # there is no pkgdir variable defined, pkgdir is automatically defined to
+    # the path of pkgname. This requires the package to be imported to work
+    if not 'pkgdir' in vars and "pkgname" in vars:
+        pkgname = vars["pkgname"]
+        if not pkgname in sys.modules:
+            raise ValueError("You should import %s to get information on %s" %
+                             (pkgname, meta["name"]))
+
+        mod = sys.modules[pkgname]
+        vars["pkgdir"] = _escape_backslash(os.path.dirname(mod.__file__))
+
+    return LibraryInfo(name=meta["name"], description=meta["description"],
+            version=meta["version"], sections=sections, vars=VariableSet(vars))
+
+# Trivial cache to cache LibraryInfo instances creation. To be really
+# efficient, the cache should be handled in read_config, since a same file can
+# be parsed many time outside LibraryInfo creation, but I doubt this will be a
+# problem in practice
+_CACHE = {}
+def read_config(pkgname, dirs=None):
+    """
+    Return library info for a package from its configuration file.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of directories - usually including
+        the NumPy base directory - where to look for npy-pkg-config files.
+
+    Returns
+    -------
+    pkginfo : class instance
+        The `LibraryInfo` instance containing the build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    misc_util.get_info, misc_util.get_pkg_info
+
+    Examples
+    --------
+    >>> npymath_info = np.distutils.npy_pkg_config.read_config('npymath')
+    >>> type(npymath_info)
+    <class 'numpy.distutils.npy_pkg_config.LibraryInfo'>
+    >>> print(npymath_info)
+    Name: npymath
+    Description: Portable, core math library implementing C99 standard
+    Requires:
+    Version: 0.1  #random
+
+    """
+    try:
+        return _CACHE[pkgname]
+    except KeyError:
+        v = _read_config_imp(pkg_to_filename(pkgname), dirs)
+        _CACHE[pkgname] = v
+        return v
+
+# TODO:
+#   - implements version comparison (modversion + atleast)
+
+# pkg-config simple emulator - useful for debugging, and maybe later to query
+# the system
+if __name__ == '__main__':
+    import sys
+    from optparse import OptionParser
+    import glob
+
+    parser = OptionParser()
+    parser.add_option("--cflags", dest="cflags", action="store_true",
+                      help="output all preprocessor and compiler flags")
+    parser.add_option("--libs", dest="libs", action="store_true",
+                      help="output all linker flags")
+    parser.add_option("--use-section", dest="section",
+                      help="use this section instead of default for options")
+    parser.add_option("--version", dest="version", action="store_true",
+                      help="output version")
+    parser.add_option("--atleast-version", dest="min_version",
+                      help="Minimal version")
+    parser.add_option("--list-all", dest="list_all", action="store_true",
+                      help="Minimal version")
+    parser.add_option("--define-variable", dest="define_variable",
+                      help="Replace variable with the given value")
+
+    (options, args) = parser.parse_args(sys.argv)
+
+    if len(args) < 2:
+        raise ValueError("Expect package name on the command line:")
+
+    if options.list_all:
+        files = glob.glob("*.ini")
+        for f in files:
+            info = read_config(f)
+            print("%s\t%s - %s" % (info.name, info.name, info.description))
+
+    pkg_name = args[1]
+    import os
+    d = os.environ.get('NPY_PKG_CONFIG_PATH')
+    if d:
+        info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.', d])
+    else:
+        info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.'])
+
+    if options.section:
+        section = options.section
+    else:
+        section = "default"
+
+    if options.define_variable:
+        m = re.search('([\S]+)=([\S]+)', options.define_variable)
+        if not m:
+            raise ValueError("--define-variable option should be of " \
+                             "the form --define-variable=foo=bar")
+        else:
+            name = m.group(1)
+            value = m.group(2)
+        info.vars[name] = value
+
+    if options.cflags:
+        print(info.cflags(section))
+    if options.libs:
+        print(info.libs(section))
+    if options.version:
+        print(info.version)
+    if options.min_version:
+        print(info.version >= options.min_version)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
new file mode 100644
index 0000000000..6ae19d16b1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
@@ -0,0 +1,19 @@
+# XXX: Handle setuptools ?
+from __future__ import division, absolute_import, print_function
+
+from distutils.core import Distribution
+
+# This class is used because we add new files (sconscripts, and so on) with the
+# scons command
+class NumpyDistribution(Distribution):
+    def __init__(self, attrs = None):
+        # A list of (sconscripts, pre_hook, post_hook, src, parent_names)
+        self.scons_data = []
+        # A list of installable libraries
+        self.installed_libraries = []
+        # A dict of pkg_config files to generate/install
+        self.installed_pkg_config = {}
+        Distribution.__init__(self, attrs)
+
+    def has_scons_scripts(self):
+        return bool(self.scons_data)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
new file mode 100644
index 0000000000..fc9872db34
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.unixccompiler import UnixCCompiler
+
+class PathScaleCCompiler(UnixCCompiler):
+
+    """
+    PathScale compiler compatible with an gcc built Python.
+    """
+
+    compiler_type = 'pathcc'
+    cc_exe = 'pathcc'
+    cxx_exe = 'pathCC'
+
+    def __init__ (self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__ (self, verbose, dry_run, force)
+        cc_compiler = self.cc_exe
+        cxx_compiler = self.cxx_exe
+        self.set_executables(compiler=cc_compiler,
+                             compiler_so=cc_compiler,
+                             compiler_cxx=cxx_compiler,
+                             linker_exe=cc_compiler,
+                             linker_so=cc_compiler + ' -shared')
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/setup.py
new file mode 100644
index 0000000000..2f12d42d91
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/setup.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('distutils', parent_package, top_path)
+    config.add_subpackage('command')
+    config.add_subpackage('fcompiler')
+    config.add_data_dir('tests')
+    config.add_data_files('site.cfg')
+    config.add_data_files('mingw/gfortran_vs2003_hack.c')
+    config.make_config_py()
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core      import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.py
new file mode 100644
index 0000000000..cd24185d26
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.py
@@ -0,0 +1,2405 @@
+#!/usr/bin/env python2
+"""
+This file defines a set of system_info classes for getting
+information about various resources (libraries, library directories,
+include directories, etc.) in the system. Currently, the following
+classes are available:
+
+  atlas_info
+  atlas_threads_info
+  atlas_blas_info
+  atlas_blas_threads_info
+  lapack_atlas_info
+  lapack_atlas_threads_info
+  atlas_3_10_info
+  atlas_3_10_threads_info
+  atlas_3_10_blas_info,
+  atlas_3_10_blas_threads_info,
+  lapack_atlas_3_10_info
+  lapack_atlas_3_10_threads_info
+  blas_info
+  lapack_info
+  openblas_info
+  blas_opt_info       # usage recommended
+  lapack_opt_info     # usage recommended
+  fftw_info,dfftw_info,sfftw_info
+  fftw_threads_info,dfftw_threads_info,sfftw_threads_info
+  djbfft_info
+  x11_info
+  lapack_src_info
+  blas_src_info
+  numpy_info
+  numarray_info
+  numpy_info
+  boost_python_info
+  agg2_info
+  wx_info
+  gdk_pixbuf_xlib_2_info
+  gdk_pixbuf_2_info
+  gdk_x11_2_info
+  gtkp_x11_2_info
+  gtkp_2_info
+  xft_info
+  freetype2_info
+  umfpack_info
+
+Usage:
+    info_dict = get_info(<name>)
+  where <name> is a string 'atlas','x11','fftw','lapack','blas',
+  'lapack_src', 'blas_src', etc. For a complete list of allowed names,
+  see the definition of get_info() function below.
+
+  Returned info_dict is a dictionary which is compatible with
+  distutils.setup keyword arguments. If info_dict == {}, then the
+  asked resource is not available (system_info could not find it).
+
+  Several *_info classes specify an environment variable to specify
+  the locations of software. When setting the corresponding environment
+  variable to 'None' then the software will be ignored, even when it
+  is available in system.
+
+Global parameters:
+  system_info.search_static_first - search static libraries (.a)
+             in precedence to shared ones (.so, .sl) if enabled.
+  system_info.verbosity - output the results to stdout if enabled.
+
+The file 'site.cfg' is looked for in
+
+1) Directory of main setup.py file being run.
+2) Home directory of user running the setup.py file as ~/.numpy-site.cfg
+3) System wide directory (location of this file...)
+
+The first one found is used to get system configuration options The
+format is that used by ConfigParser (i.e., Windows .INI style). The
+section ALL has options that are the default for each section. The
+available sections are fftw, atlas, and x11. Appropiate defaults are
+used if nothing is specified.
+
+The order of finding the locations of resources is the following:
+ 1. environment variable
+ 2. section in site.cfg
+ 3. ALL section in site.cfg
+Only the first complete match is returned.
+
+Example:
+----------
+[ALL]
+library_dirs = /usr/lib:/usr/local/lib:/opt/lib
+include_dirs = /usr/include:/usr/local/include:/opt/include
+src_dirs = /usr/local/src:/opt/src
+# search static libraries (.a) in preference to shared ones (.so)
+search_static_first = 0
+
+[fftw]
+fftw_libs = rfftw, fftw
+fftw_opt_libs = rfftw_threaded, fftw_threaded
+# if the above aren't found, look for {s,d}fftw_libs and {s,d}fftw_opt_libs
+
+[atlas]
+library_dirs = /usr/lib/3dnow:/usr/lib/3dnow/atlas
+# for overriding the names of the atlas libraries
+atlas_libs = lapack, f77blas, cblas, atlas
+
+[x11]
+library_dirs = /usr/X11R6/lib
+include_dirs = /usr/X11R6/include
+----------
+
+Authors:
+  Pearu Peterson <pearu@cens.ioc.ee>, February 2002
+  David M. Cooke <cookedm@physics.mcmaster.ca>, April 2002
+
+Copyright 2002 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) license.  See LICENSE.txt that came with
+this distribution for specifics.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import re
+import copy
+import warnings
+from glob import glob
+from functools import reduce
+if sys.version_info[0] < 3:
+    from ConfigParser import NoOptionError, ConfigParser
+else:
+    from configparser import NoOptionError, ConfigParser
+
+from distutils.errors import DistutilsError
+from distutils.dist import Distribution
+import distutils.sysconfig
+from distutils import log
+from distutils.util import get_platform
+
+from numpy.distutils.exec_command import \
+    find_executable, exec_command, get_pythonexe
+from numpy.distutils.misc_util import is_sequence, is_string, \
+                                      get_shared_lib_extension
+from numpy.distutils.command.config import config as cmd_config
+from numpy.distutils.compat import get_exception
+import distutils.ccompiler
+import tempfile
+import shutil
+
+
+# Determine number of bits
+import platform
+_bits = {'32bit': 32, '64bit': 64}
+platform_bits = _bits[platform.architecture()[0]]
+
+
+def libpaths(paths, bits):
+    """Return a list of library paths valid on 32 or 64 bit systems.
+
+    Inputs:
+      paths : sequence
+        A sequence of strings (typically paths)
+      bits : int
+        An integer, the only valid values are 32 or 64.  A ValueError exception
+      is raised otherwise.
+
+    Examples:
+
+    Consider a list of directories
+    >>> paths = ['/usr/X11R6/lib','/usr/X11/lib','/usr/lib']
+
+    For a 32-bit platform, this is already valid:
+    >>> np.distutils.system_info.libpaths(paths,32)
+    ['/usr/X11R6/lib', '/usr/X11/lib', '/usr/lib']
+
+    On 64 bits, we prepend the '64' postfix
+    >>> np.distutils.system_info.libpaths(paths,64)
+    ['/usr/X11R6/lib64', '/usr/X11R6/lib', '/usr/X11/lib64', '/usr/X11/lib',
+    '/usr/lib64', '/usr/lib']
+    """
+    if bits not in (32, 64):
+        raise ValueError("Invalid bit size in libpaths: 32 or 64 only")
+
+    # Handle 32bit case
+    if bits == 32:
+        return paths
+
+    # Handle 64bit case
+    out = []
+    for p in paths:
+        out.extend([p + '64', p])
+
+    return out
+
+
+if sys.platform == 'win32':
+    default_lib_dirs = ['C:\\',
+                        os.path.join(distutils.sysconfig.EXEC_PREFIX,
+                                     'libs')]
+    default_runtime_dirs = []
+    default_include_dirs = []
+    default_src_dirs = ['.']
+    default_x11_lib_dirs = []
+    default_x11_include_dirs = []
+else:
+    default_lib_dirs = libpaths(['/usr/local/lib', '/opt/lib', '/usr/lib',
+                                 '/opt/local/lib', '/sw/lib'], platform_bits)
+    default_runtime_dirs = []
+    default_include_dirs = ['/usr/local/include',
+                            '/opt/include', '/usr/include',
+                            # path of umfpack under macports
+                            '/opt/local/include/ufsparse',
+                            '/opt/local/include', '/sw/include',
+                            '/usr/include/suitesparse']
+    default_src_dirs = ['.', '/usr/local/src', '/opt/src', '/sw/src']
+
+    default_x11_lib_dirs = libpaths(['/usr/X11R6/lib', '/usr/X11/lib',
+                                     '/usr/lib'], platform_bits)
+    default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include',
+                                '/usr/include']
+
+    if os.path.exists('/usr/lib/X11'):
+        globbed_x11_dir = glob('/usr/lib/*/libX11.so')
+        if globbed_x11_dir:
+            x11_so_dir = os.path.split(globbed_x11_dir[0])[0]
+            default_x11_lib_dirs.extend([x11_so_dir, '/usr/lib/X11'])
+            default_x11_include_dirs.extend(['/usr/lib/X11/include',
+                                             '/usr/include/X11'])
+
+    import subprocess as sp
+    tmp = None
+    try:
+        # Explicitly open/close file to avoid ResourceWarning when
+        # tests are run in debug mode Python 3.
+        tmp = open(os.devnull, 'w')
+        p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE,
+                stderr=tmp)
+    except (OSError, DistutilsError):
+        # OSError if gcc is not installed, or SandboxViolation (DistutilsError
+        # subclass) if an old setuptools bug is triggered (see gh-3160).
+        pass
+    else:
+        triplet = str(p.communicate()[0].decode().strip())
+        if p.returncode == 0:
+            # gcc supports the "-print-multiarch" option
+            default_x11_lib_dirs += [os.path.join("/usr/lib/", triplet)]
+            default_lib_dirs += [os.path.join("/usr/lib/", triplet)]
+    finally:
+        if tmp is not None:
+            tmp.close()
+
+if os.path.join(sys.prefix, 'lib') not in default_lib_dirs:
+    default_lib_dirs.insert(0, os.path.join(sys.prefix, 'lib'))
+    default_include_dirs.append(os.path.join(sys.prefix, 'include'))
+    default_src_dirs.append(os.path.join(sys.prefix, 'src'))
+
+default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)]
+default_runtime_dirs = [_m for _m in default_runtime_dirs if os.path.isdir(_m)]
+default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)]
+default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)]
+
+so_ext = get_shared_lib_extension()
+
+
+def get_standard_file(fname):
+    """Returns a list of files named 'fname' from
+    1) System-wide directory (directory-location of this module)
+    2) Users HOME directory (os.environ['HOME'])
+    3) Local directory
+    """
+    # System-wide file
+    filenames = []
+    try:
+        f = __file__
+    except NameError:
+        f = sys.argv[0]
+    else:
+        sysfile = os.path.join(os.path.split(os.path.abspath(f))[0],
+                               fname)
+        if os.path.isfile(sysfile):
+            filenames.append(sysfile)
+
+    # Home directory
+    # And look for the user config file
+    try:
+        f = os.path.expanduser('~')
+    except KeyError:
+        pass
+    else:
+        user_file = os.path.join(f, fname)
+        if os.path.isfile(user_file):
+            filenames.append(user_file)
+
+    # Local file
+    if os.path.isfile(fname):
+        filenames.append(os.path.abspath(fname))
+
+    return filenames
+
+
+def get_info(name, notfound_action=0):
+    """
+    notfound_action:
+      0 - do nothing
+      1 - display warning message
+      2 - raise error
+    """
+    cl = {'atlas': atlas_info,  # use lapack_opt or blas_opt instead
+          'atlas_threads': atlas_threads_info,                # ditto
+          'atlas_blas': atlas_blas_info,
+          'atlas_blas_threads': atlas_blas_threads_info,
+          'lapack_atlas': lapack_atlas_info,  # use lapack_opt instead
+          'lapack_atlas_threads': lapack_atlas_threads_info,  # ditto
+          'atlas_3_10': atlas_3_10_info,  # use lapack_opt or blas_opt instead
+          'atlas_3_10_threads': atlas_3_10_threads_info,                # ditto
+          'atlas_3_10_blas': atlas_3_10_blas_info,
+          'atlas_3_10_blas_threads': atlas_3_10_blas_threads_info,
+          'lapack_atlas_3_10': lapack_atlas_3_10_info,  # use lapack_opt instead
+          'lapack_atlas_3_10_threads': lapack_atlas_3_10_threads_info,  # ditto
+          'mkl': mkl_info,
+          # openblas which may or may not have embedded lapack
+          'openblas': openblas_info,          # use blas_opt instead
+          # openblas with embedded lapack
+          'openblas_lapack': openblas_lapack_info, # use blas_opt instead
+          'lapack_mkl': lapack_mkl_info,      # use lapack_opt instead
+          'blas_mkl': blas_mkl_info,          # use blas_opt instead
+          'x11': x11_info,
+          'fft_opt': fft_opt_info,
+          'fftw': fftw_info,
+          'fftw2': fftw2_info,
+          'fftw3': fftw3_info,
+          'dfftw': dfftw_info,
+          'sfftw': sfftw_info,
+          'fftw_threads': fftw_threads_info,
+          'dfftw_threads': dfftw_threads_info,
+          'sfftw_threads': sfftw_threads_info,
+          'djbfft': djbfft_info,
+          'blas': blas_info,                  # use blas_opt instead
+          'lapack': lapack_info,              # use lapack_opt instead
+          'lapack_src': lapack_src_info,
+          'blas_src': blas_src_info,
+          'numpy': numpy_info,
+          'f2py': f2py_info,
+          'Numeric': Numeric_info,
+          'numeric': Numeric_info,
+          'numarray': numarray_info,
+          'numerix': numerix_info,
+          'lapack_opt': lapack_opt_info,
+          'blas_opt': blas_opt_info,
+          'boost_python': boost_python_info,
+          'agg2': agg2_info,
+          'wx': wx_info,
+          'gdk_pixbuf_xlib_2': gdk_pixbuf_xlib_2_info,
+          'gdk-pixbuf-xlib-2.0': gdk_pixbuf_xlib_2_info,
+          'gdk_pixbuf_2': gdk_pixbuf_2_info,
+          'gdk-pixbuf-2.0': gdk_pixbuf_2_info,
+          'gdk': gdk_info,
+          'gdk_2': gdk_2_info,
+          'gdk-2.0': gdk_2_info,
+          'gdk_x11_2': gdk_x11_2_info,
+          'gdk-x11-2.0': gdk_x11_2_info,
+          'gtkp_x11_2': gtkp_x11_2_info,
+          'gtk+-x11-2.0': gtkp_x11_2_info,
+          'gtkp_2': gtkp_2_info,
+          'gtk+-2.0': gtkp_2_info,
+          'xft': xft_info,
+          'freetype2': freetype2_info,
+          'umfpack': umfpack_info,
+          'amd': amd_info,
+          }.get(name.lower(), system_info)
+    return cl().get_info(notfound_action)
+
+
+class NotFoundError(DistutilsError):
+    """Some third-party program or library is not found."""
+
+
+class AtlasNotFoundError(NotFoundError):
+    """
+    Atlas (http://math-atlas.sourceforge.net/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [atlas]) or by setting
+    the ATLAS environment variable."""
+
+
+class LapackNotFoundError(NotFoundError):
+    """
+    Lapack (http://www.netlib.org/lapack/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [lapack]) or by setting
+    the LAPACK environment variable."""
+
+
+class LapackSrcNotFoundError(LapackNotFoundError):
+    """
+    Lapack (http://www.netlib.org/lapack/) sources not found.
+    Directories to search for the sources can be specified in the
+    numpy/distutils/site.cfg file (section [lapack_src]) or by setting
+    the LAPACK_SRC environment variable."""
+
+
+class BlasNotFoundError(NotFoundError):
+    """
+    Blas (http://www.netlib.org/blas/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [blas]) or by setting
+    the BLAS environment variable."""
+
+
+class BlasSrcNotFoundError(BlasNotFoundError):
+    """
+    Blas (http://www.netlib.org/blas/) sources not found.
+    Directories to search for the sources can be specified in the
+    numpy/distutils/site.cfg file (section [blas_src]) or by setting
+    the BLAS_SRC environment variable."""
+
+
+class FFTWNotFoundError(NotFoundError):
+    """
+    FFTW (http://www.fftw.org/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [fftw]) or by setting
+    the FFTW environment variable."""
+
+
+class DJBFFTNotFoundError(NotFoundError):
+    """
+    DJBFFT (http://cr.yp.to/djbfft.html) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [djbfft]) or by setting
+    the DJBFFT environment variable."""
+
+
+class NumericNotFoundError(NotFoundError):
+    """
+    Numeric (http://www.numpy.org/) module not found.
+    Get it from above location, install it, and retry setup.py."""
+
+
+class X11NotFoundError(NotFoundError):
+    """X11 libraries not found."""
+
+
+class UmfpackNotFoundError(NotFoundError):
+    """
+    UMFPACK sparse solver (http://www.cise.ufl.edu/research/sparse/umfpack/)
+    not found. Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [umfpack]) or by setting
+    the UMFPACK environment variable."""
+
+
+class system_info(object):
+
+    """ get_info() is the only public method. Don't use others.
+    """
+    section = 'ALL'
+    dir_env_var = None
+    search_static_first = 0  # XXX: disabled by default, may disappear in
+                            # future unless it is proved to be useful.
+    verbosity = 1
+    saved_results = {}
+
+    notfounderror = NotFoundError
+
+    def __init__(self,
+                  default_lib_dirs=default_lib_dirs,
+                  default_include_dirs=default_include_dirs,
+                  verbosity=1,
+                  ):
+        self.__class__.info = {}
+        self.local_prefixes = []
+        defaults = {'library_dirs': os.pathsep.join(default_lib_dirs),
+                    'include_dirs': os.pathsep.join(default_include_dirs),
+                    'runtime_library_dirs': os.pathsep.join(default_runtime_dirs),
+                    'rpath': '',
+                    'src_dirs': os.pathsep.join(default_src_dirs),
+                    'search_static_first': str(self.search_static_first),
+                    'extra_compile_args': '', 'extra_link_args': ''}
+        self.cp = ConfigParser(defaults)
+        self.files = []
+        self.files.extend(get_standard_file('.numpy-site.cfg'))
+        self.files.extend(get_standard_file('site.cfg'))
+        self.parse_config_files()
+        if self.section is not None:
+            self.search_static_first = self.cp.getboolean(
+                self.section, 'search_static_first')
+        assert isinstance(self.search_static_first, int)
+
+    def parse_config_files(self):
+        self.cp.read(self.files)
+        if not self.cp.has_section(self.section):
+            if self.section is not None:
+                self.cp.add_section(self.section)
+
+    def calc_libraries_info(self):
+        libs = self.get_libraries()
+        dirs = self.get_lib_dirs()
+        # The extensions use runtime_library_dirs
+        r_dirs = self.get_runtime_lib_dirs() 
+        # Intrinsic distutils use rpath, we simply append both entries
+        # as though they were one entry
+        r_dirs.extend(self.get_runtime_lib_dirs(key='rpath'))
+        info = {}
+        for lib in libs:
+            i = self.check_libs(dirs, [lib])
+            if i is not None:
+                dict_append(info, **i)
+            else:
+                log.info('Library %s was not found. Ignoring' % (lib))
+            i = self.check_libs(r_dirs, [lib])
+            if i is not None:
+                # Swap library keywords found to runtime_library_dirs
+                # the libraries are insisting on the user having defined
+                # them using the library_dirs, and not necessarily by
+                # runtime_library_dirs
+                del i['libraries']
+                i['runtime_library_dirs'] = i.pop('library_dirs')
+                dict_append(info, **i)
+            else:
+                log.info('Runtime library %s was not found. Ignoring' % (lib))
+        return info
+
+    def set_info(self, **info):
+        if info:
+            lib_info = self.calc_libraries_info()
+            dict_append(info, **lib_info)
+            # Update extra information
+            extra_info = self.calc_extra_info()
+            dict_append(info, **extra_info)
+        self.saved_results[self.__class__.__name__] = info
+
+    def has_info(self):
+        return self.__class__.__name__ in self.saved_results
+
+    def calc_extra_info(self):
+        """ Updates the information in the current information with
+        respect to these flags:
+          extra_compile_args
+          extra_link_args
+        """
+        info = {}
+        for key in ['extra_compile_args', 'extra_link_args']:
+            # Get values
+            opt = self.cp.get(self.section, key)
+            if opt:
+                tmp = {key : [opt]}
+                dict_append(info, **tmp)
+        return info
+
+    def get_info(self, notfound_action=0):
+        """ Return a dictonary with items that are compatible
+            with numpy.distutils.setup keyword arguments.
+        """
+        flag = 0
+        if not self.has_info():
+            flag = 1
+            log.info(self.__class__.__name__ + ':')
+            if hasattr(self, 'calc_info'):
+                self.calc_info()
+            if notfound_action:
+                if not self.has_info():
+                    if notfound_action == 1:
+                        warnings.warn(self.notfounderror.__doc__)
+                    elif notfound_action == 2:
+                        raise self.notfounderror(self.notfounderror.__doc__)
+                    else:
+                        raise ValueError(repr(notfound_action))
+
+            if not self.has_info():
+                log.info('  NOT AVAILABLE')
+                self.set_info()
+            else:
+                log.info('  FOUND:')
+
+        res = self.saved_results.get(self.__class__.__name__)
+        if self.verbosity > 0 and flag:
+            for k, v in res.items():
+                v = str(v)
+                if k in ['sources', 'libraries'] and len(v) > 270:
+                    v = v[:120] + '...\n...\n...' + v[-120:]
+                log.info('    %s = %s', k, v)
+            log.info('')
+
+        return copy.deepcopy(res)
+
+    def get_paths(self, section, key):
+        dirs = self.cp.get(section, key).split(os.pathsep)
+        env_var = self.dir_env_var
+        if env_var:
+            if is_sequence(env_var):
+                e0 = env_var[-1]
+                for e in env_var:
+                    if e in os.environ:
+                        e0 = e
+                        break
+                if not env_var[0] == e0:
+                    log.info('Setting %s=%s' % (env_var[0], e0))
+                env_var = e0
+        if env_var and env_var in os.environ:
+            d = os.environ[env_var]
+            if d == 'None':
+                log.info('Disabled %s: %s',
+                         self.__class__.__name__, '(%s is None)'
+                         % (env_var,))
+                return []
+            if os.path.isfile(d):
+                dirs = [os.path.dirname(d)] + dirs
+                l = getattr(self, '_lib_names', [])
+                if len(l) == 1:
+                    b = os.path.basename(d)
+                    b = os.path.splitext(b)[0]
+                    if b[:3] == 'lib':
+                        log.info('Replacing _lib_names[0]==%r with %r' \
+                              % (self._lib_names[0], b[3:]))
+                        self._lib_names[0] = b[3:]
+            else:
+                ds = d.split(os.pathsep)
+                ds2 = []
+                for d in ds:
+                    if os.path.isdir(d):
+                        ds2.append(d)
+                        for dd in ['include', 'lib']:
+                            d1 = os.path.join(d, dd)
+                            if os.path.isdir(d1):
+                                ds2.append(d1)
+                dirs = ds2 + dirs
+        default_dirs = self.cp.get(self.section, key).split(os.pathsep)
+        dirs.extend(default_dirs)
+        ret = []
+        for d in dirs:
+            if len(d) > 0 and not os.path.isdir(d):
+                warnings.warn('Specified path %s is invalid.' % d)
+                continue
+
+            if d not in ret:
+                ret.append(d)
+
+        log.debug('( %s = %s )', key, ':'.join(ret))
+        return ret
+
+    def get_lib_dirs(self, key='library_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_runtime_lib_dirs(self, key='runtime_library_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_include_dirs(self, key='include_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_src_dirs(self, key='src_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_libs(self, key, default):
+        try:
+            libs = self.cp.get(self.section, key)
+        except NoOptionError:
+            if not default:
+                return []
+            if is_string(default):
+                return [default]
+            return default
+        return [b for b in [a.strip() for a in libs.split(',')] if b]
+
+    def get_libraries(self, key='libraries'):
+        if hasattr(self, '_lib_names'):
+            return self.get_libs(key, default=self._lib_names)
+        else:
+            return self.get_libs(key, '')
+
+    def library_extensions(self):
+        static_exts = ['.a']
+        if sys.platform == 'win32':
+            static_exts.append('.lib')  # .lib is used by MSVC
+        if self.search_static_first:
+            exts = static_exts + [so_ext]
+        else:
+            exts = [so_ext] + static_exts
+        if sys.platform == 'cygwin':
+            exts.append('.dll.a')
+        if sys.platform == 'darwin':
+            exts.append('.dylib')
+        return exts
+
+    def check_libs(self, lib_dirs, libs, opt_libs=[]):
+        """If static or shared libraries are available then return
+        their info dictionary.
+
+        Checks for all libraries as shared libraries first, then
+        static (or vice versa if self.search_static_first is True).
+        """
+        exts = self.library_extensions()
+        info = None
+        for ext in exts:
+            info = self._check_libs(lib_dirs, libs, opt_libs, [ext])
+            if info is not None:
+                break
+        if not info:
+            log.info('  libraries %s not found in %s', ','.join(libs),
+                     lib_dirs)
+        return info
+
+    def check_libs2(self, lib_dirs, libs, opt_libs=[]):
+        """If static or shared libraries are available then return
+        their info dictionary.
+
+        Checks each library for shared or static.
+        """
+        exts = self.library_extensions()
+        info = self._check_libs(lib_dirs, libs, opt_libs, exts)
+        if not info:
+            log.info('  libraries %s not found in %s', ','.join(libs),
+                     lib_dirs)
+        return info
+
+    def _lib_list(self, lib_dir, libs, exts):
+        assert is_string(lib_dir)
+        liblist = []
+        # under windows first try without 'lib' prefix
+        if sys.platform == 'win32':
+            lib_prefixes = ['', 'lib']
+        else:
+            lib_prefixes = ['lib']
+        # for each library name, see if we can find a file for it.
+        for l in libs:
+            for ext in exts:
+                for prefix in lib_prefixes:
+                    p = self.combine_paths(lib_dir, prefix + l + ext)
+                    if p:
+                        break
+                if p:
+                    assert len(p) == 1
+                    # ??? splitext on p[0] would do this for cygwin
+                    # doesn't seem correct
+                    if ext == '.dll.a':
+                        l += '.dll'
+                    liblist.append(l)
+                    break
+        return liblist
+
+    def _check_libs(self, lib_dirs, libs, opt_libs, exts):
+        """Find mandatory and optional libs in expected paths.
+
+        Missing optional libraries are silently forgotten.
+        """
+        # First, try to find the mandatory libraries
+        if is_sequence(lib_dirs):
+            found_libs, found_dirs = [], []
+            for dir_ in lib_dirs:
+                found_libs1 = self._lib_list(dir_, libs, exts)
+                # It's possible that we'll find the same library in multiple
+                # directories. It's also possible that we'll find some
+                # libraries on in directory, and some in another. So the
+                # obvious thing would be to use a set instead of a list, but I
+                # don't know if preserving order matters (does it?).
+                for found_lib in found_libs1:
+                    if found_lib not in found_libs:
+                        found_libs.append(found_lib)
+                        if dir_ not in found_dirs:
+                            found_dirs.append(dir_)
+        else:
+            found_libs = self._lib_list(lib_dirs, libs, exts)
+            found_dirs = [lib_dirs]
+        if len(found_libs) > 0 and len(found_libs) == len(libs):
+            info = {'libraries': found_libs, 'library_dirs': found_dirs}
+            # Now, check for optional libraries
+            if is_sequence(lib_dirs):
+                for dir_ in lib_dirs:
+                    opt_found_libs = self._lib_list(dir_, opt_libs, exts)
+                    if opt_found_libs:
+                        if dir_ not in found_dirs:
+                            found_dirs.extend(dir_)
+                        found_libs.extend(opt_found_libs)
+            else:
+                opt_found_libs = self._lib_list(lib_dirs, opt_libs, exts)
+                if opt_found_libs:
+                    found_libs.extend(opt_found_libs)
+            return info
+        else:
+            return None
+
+    def combine_paths(self, *args):
+        """Return a list of existing paths composed by all combinations
+        of items from the arguments.
+        """
+        return combine_paths(*args, **{'verbosity': self.verbosity})
+
+
+class fft_opt_info(system_info):
+
+    def calc_info(self):
+        info = {}
+        fftw_info = get_info('fftw3') or get_info('fftw2') or get_info('dfftw')
+        djbfft_info = get_info('djbfft')
+        if fftw_info:
+            dict_append(info, **fftw_info)
+            if djbfft_info:
+                dict_append(info, **djbfft_info)
+            self.set_info(**info)
+            return
+
+
+class fftw_info(system_info):
+    #variables to override
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw3',
+                    'libs':['fftw3'],
+                    'includes':['fftw3.h'],
+                    'macros':[('SCIPY_FFTW3_H', None)]},
+                  {'name':'fftw2',
+                    'libs':['rfftw', 'fftw'],
+                    'includes':['fftw.h', 'rfftw.h'],
+                    'macros':[('SCIPY_FFTW_H', None)]}]
+
+    def calc_ver_info(self, ver_param):
+        """Returns True on successful version detection, else False"""
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        incl_dir = None
+        libs = self.get_libs(self.section + '_libs', ver_param['libs'])
+        info = self.check_libs(lib_dirs, libs)
+        if info is not None:
+            flag = 0
+            for d in incl_dirs:
+                if len(self.combine_paths(d, ver_param['includes'])) \
+                   == len(ver_param['includes']):
+                    dict_append(info, include_dirs=[d])
+                    flag = 1
+                    incl_dirs = [d]
+                    break
+            if flag:
+                dict_append(info, define_macros=ver_param['macros'])
+            else:
+                info = None
+        if info is not None:
+            self.set_info(**info)
+            return True
+        else:
+            log.info('  %s not found' % (ver_param['name']))
+            return False
+
+    def calc_info(self):
+        for i in self.ver_info:
+            if self.calc_ver_info(i):
+                break
+
+
+class fftw2_info(fftw_info):
+    #variables to override
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw2',
+                    'libs':['rfftw', 'fftw'],
+                    'includes':['fftw.h', 'rfftw.h'],
+                    'macros':[('SCIPY_FFTW_H', None)]}
+                  ]
+
+
+class fftw3_info(fftw_info):
+    #variables to override
+    section = 'fftw3'
+    dir_env_var = 'FFTW3'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw3',
+                    'libs':['fftw3'],
+                    'includes':['fftw3.h'],
+                    'macros':[('SCIPY_FFTW3_H', None)]},
+                  ]
+
+
+class dfftw_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'dfftw',
+                    'libs':['drfftw', 'dfftw'],
+                    'includes':['dfftw.h', 'drfftw.h'],
+                    'macros':[('SCIPY_DFFTW_H', None)]}]
+
+
+class sfftw_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'sfftw',
+                    'libs':['srfftw', 'sfftw'],
+                    'includes':['sfftw.h', 'srfftw.h'],
+                    'macros':[('SCIPY_SFFTW_H', None)]}]
+
+
+class fftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'fftw threads',
+                    'libs':['rfftw_threads', 'fftw_threads'],
+                    'includes':['fftw_threads.h', 'rfftw_threads.h'],
+                    'macros':[('SCIPY_FFTW_THREADS_H', None)]}]
+
+
+class dfftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'dfftw threads',
+                    'libs':['drfftw_threads', 'dfftw_threads'],
+                    'includes':['dfftw_threads.h', 'drfftw_threads.h'],
+                    'macros':[('SCIPY_DFFTW_THREADS_H', None)]}]
+
+
+class sfftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'sfftw threads',
+                    'libs':['srfftw_threads', 'sfftw_threads'],
+                    'includes':['sfftw_threads.h', 'srfftw_threads.h'],
+                    'macros':[('SCIPY_SFFTW_THREADS_H', None)]}]
+
+
+class djbfft_info(system_info):
+    section = 'djbfft'
+    dir_env_var = 'DJBFFT'
+    notfounderror = DJBFFTNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend(self.combine_paths(d, ['djbfft']) + [d])
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        info = None
+        for d in lib_dirs:
+            p = self.combine_paths(d, ['djbfft.a'])
+            if p:
+                info = {'extra_objects': p}
+                break
+            p = self.combine_paths(d, ['libdjbfft.a', 'libdjbfft' + so_ext])
+            if p:
+                info = {'libraries': ['djbfft'], 'library_dirs': [d]}
+                break
+        if info is None:
+            return
+        for d in incl_dirs:
+            if len(self.combine_paths(d, ['fftc8.h', 'fftfreq.h'])) == 2:
+                dict_append(info, include_dirs=[d],
+                            define_macros=[('SCIPY_DJBFFT_H', None)])
+                self.set_info(**info)
+                return
+        return
+
+
+class mkl_info(system_info):
+    section = 'mkl'
+    dir_env_var = 'MKL'
+    _lib_mkl = ['mkl', 'vml', 'guide']
+
+    def get_mkl_rootdir(self):
+        mklroot = os.environ.get('MKLROOT', None)
+        if mklroot is not None:
+            return mklroot
+        paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep)
+        ld_so_conf = '/etc/ld.so.conf'
+        if os.path.isfile(ld_so_conf):
+            for d in open(ld_so_conf, 'r'):
+                d = d.strip()
+                if d:
+                    paths.append(d)
+        intel_mkl_dirs = []
+        for path in paths:
+            path_atoms = path.split(os.sep)
+            for m in path_atoms:
+                if m.startswith('mkl'):
+                    d = os.sep.join(path_atoms[:path_atoms.index(m) + 2])
+                    intel_mkl_dirs.append(d)
+                    break
+        for d in paths:
+            dirs = glob(os.path.join(d, 'mkl', '*'))
+            dirs += glob(os.path.join(d, 'mkl*'))
+            for d in dirs:
+                if os.path.isdir(os.path.join(d, 'lib')):
+                    return d
+        return None
+
+    def __init__(self):
+        mklroot = self.get_mkl_rootdir()
+        if mklroot is None:
+            system_info.__init__(self)
+        else:
+            from .cpuinfo import cpu
+            l = 'mkl'  # use shared library
+            if cpu.is_Itanium():
+                plt = '64'
+            elif cpu.is_Xeon():
+                plt = 'intel64'
+            else:
+                plt = '32'
+            if l not in self._lib_mkl:
+                self._lib_mkl.insert(0, l)
+            system_info.__init__(
+                self,
+                default_lib_dirs=[os.path.join(mklroot, 'lib', plt)],
+                default_include_dirs=[os.path.join(mklroot, 'include')])
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        mkl_libs = self.get_libs('mkl_libs', self._lib_mkl)
+        info = self.check_libs2(lib_dirs, mkl_libs)
+        if info is None:
+            return
+        dict_append(info,
+                    define_macros=[('SCIPY_MKL_H', None),
+                                   ('HAVE_CBLAS', None)],
+                    include_dirs=incl_dirs)
+        if sys.platform == 'win32':
+            pass  # win32 has no pthread library
+        else:
+            dict_append(info, libraries=['pthread'])
+        self.set_info(**info)
+
+
+class lapack_mkl_info(mkl_info):
+
+    def calc_info(self):
+        mkl = get_info('mkl')
+        if not mkl:
+            return
+        if sys.platform == 'win32':
+            lapack_libs = self.get_libs('lapack_libs', ['mkl_lapack'])
+        else:
+            lapack_libs = self.get_libs('lapack_libs',
+                                        ['mkl_lapack32', 'mkl_lapack64'])
+
+        info = {'libraries': lapack_libs}
+        dict_append(info, **mkl)
+        self.set_info(**info)
+
+
+class blas_mkl_info(mkl_info):
+    pass
+
+
+class atlas_info(system_info):
+    section = 'atlas'
+    dir_env_var = 'ATLAS'
+    _lib_names = ['f77blas', 'cblas']
+    if sys.platform[:7] == 'freebsd':
+        _lib_atlas = ['atlas_r']
+        _lib_lapack = ['alapack_r']
+    else:
+        _lib_atlas = ['atlas']
+        _lib_lapack = ['lapack']
+
+    notfounderror = AtlasNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend(self.combine_paths(d, ['atlas*', 'ATLAS*',
+                                         'sse', '3dnow', 'sse2']) + [d])
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names + self._lib_atlas)
+        lapack_libs = self.get_libs('lapack_libs', self._lib_lapack)
+        atlas = None
+        lapack = None
+        atlas_1 = None
+        for d in lib_dirs:
+            atlas = self.check_libs2(d, atlas_libs, [])
+            lapack_atlas = self.check_libs2(d, ['lapack_atlas'], [])
+            if atlas is not None:
+                lib_dirs2 = [d] + self.combine_paths(d, ['atlas*', 'ATLAS*'])
+                lapack = self.check_libs2(lib_dirs2, lapack_libs, [])
+                if lapack is not None:
+                    break
+            if atlas:
+                atlas_1 = atlas
+        log.info(self.__class__)
+        if atlas is None:
+            atlas = atlas_1
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        if lapack is not None:
+            dict_append(info, **lapack)
+            dict_append(info, **atlas)
+        elif 'lapack_atlas' in atlas['libraries']:
+            dict_append(info, **atlas)
+            dict_append(info,
+                        define_macros=[('ATLAS_WITH_LAPACK_ATLAS', None)])
+            self.set_info(**info)
+            return
+        else:
+            dict_append(info, **atlas)
+            dict_append(info, define_macros=[('ATLAS_WITHOUT_LAPACK', None)])
+            message = """
+*********************************************************************
+    Could not find lapack library within the ATLAS installation.
+*********************************************************************
+"""
+            warnings.warn(message)
+            self.set_info(**info)
+            return
+
+        # Check if lapack library is complete, only warn if it is not.
+        lapack_dir = lapack['library_dirs'][0]
+        lapack_name = lapack['libraries'][0]
+        lapack_lib = None
+        lib_prefixes = ['lib']
+        if sys.platform == 'win32':
+            lib_prefixes.append('')
+        for e in self.library_extensions():
+            for prefix in lib_prefixes:
+                fn = os.path.join(lapack_dir, prefix + lapack_name + e)
+                if os.path.exists(fn):
+                    lapack_lib = fn
+                    break
+            if lapack_lib:
+                break
+        if lapack_lib is not None:
+            sz = os.stat(lapack_lib)[6]
+            if sz <= 4000 * 1024:
+                message = """
+*********************************************************************
+    Lapack library (from ATLAS) is probably incomplete:
+      size of %s is %sk (expected >4000k)
+
+    Follow the instructions in the KNOWN PROBLEMS section of the file
+    numpy/INSTALL.txt.
+*********************************************************************
+""" % (lapack_lib, sz / 1024)
+                warnings.warn(message)
+            else:
+                info['language'] = 'f77'
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(info, **atlas_extra_info)
+
+        self.set_info(**info)
+
+
+class atlas_blas_info(atlas_info):
+    _lib_names = ['f77blas', 'cblas']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names + self._lib_atlas)
+        atlas = self.check_libs2(lib_dirs, atlas_libs, [])
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(atlas, **atlas_extra_info)
+
+        dict_append(info, **atlas)
+
+        self.set_info(**info)
+        return
+
+
+class atlas_threads_info(atlas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['ptf77blas', 'ptcblas']
+
+
+class atlas_blas_threads_info(atlas_blas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['ptf77blas', 'ptcblas']
+
+
+class lapack_atlas_info(atlas_info):
+    _lib_names = ['lapack_atlas'] + atlas_info._lib_names
+
+
+class lapack_atlas_threads_info(atlas_threads_info):
+    _lib_names = ['lapack_atlas'] + atlas_threads_info._lib_names
+
+
+class atlas_3_10_info(atlas_info):
+    _lib_names = ['satlas']
+    _lib_atlas = _lib_names
+    _lib_lapack = _lib_names
+
+
+class atlas_3_10_blas_info(atlas_3_10_info):
+    _lib_names = ['satlas']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names)
+        atlas = self.check_libs2(lib_dirs, atlas_libs, [])
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(atlas, **atlas_extra_info)
+
+        dict_append(info, **atlas)
+
+        self.set_info(**info)
+        return
+
+
+class atlas_3_10_threads_info(atlas_3_10_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['tatlas']
+    _lib_atlas = _lib_names
+    _lib_lapack = _lib_names
+
+
+class atlas_3_10_blas_threads_info(atlas_3_10_blas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['tatlas']
+
+
+class lapack_atlas_3_10_info(atlas_3_10_info):
+    pass
+
+
+class lapack_atlas_3_10_threads_info(atlas_3_10_threads_info):
+    pass
+
+
+class lapack_info(system_info):
+    section = 'lapack'
+    dir_env_var = 'LAPACK'
+    _lib_names = ['lapack']
+    notfounderror = LapackNotFoundError
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        lapack_libs = self.get_libs('lapack_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, lapack_libs, [])
+        if info is None:
+            return
+        info['language'] = 'f77'
+        self.set_info(**info)
+
+
+class lapack_src_info(system_info):
+    section = 'lapack_src'
+    dir_env_var = 'LAPACK_SRC'
+    notfounderror = LapackSrcNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['LAPACK*/SRC', 'SRC']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'dgesv.f')):
+                src_dir = d
+                break
+        if not src_dir:
+            #XXX: Get sources from netlib. May be ask first.
+            return
+        # The following is extracted from LAPACK-3.0/SRC/Makefile.
+        # Added missing names from lapack-lite-3.1.1/SRC/Makefile
+        # while keeping removed names for Lapack-3.0 compatibility.
+        allaux = '''
+        ilaenv ieeeck lsame lsamen xerbla
+        iparmq
+        '''  # *.f
+        laux = '''
+        bdsdc bdsqr disna labad lacpy ladiv lae2 laebz laed0 laed1
+        laed2 laed3 laed4 laed5 laed6 laed7 laed8 laed9 laeda laev2
+        lagtf lagts lamch lamrg lanst lapy2 lapy3 larnv larrb larre
+        larrf lartg laruv las2 lascl lasd0 lasd1 lasd2 lasd3 lasd4
+        lasd5 lasd6 lasd7 lasd8 lasd9 lasda lasdq lasdt laset lasq1
+        lasq2 lasq3 lasq4 lasq5 lasq6 lasr lasrt lassq lasv2 pttrf
+        stebz stedc steqr sterf
+
+        larra larrc larrd larr larrk larrj larrr laneg laisnan isnan
+        lazq3 lazq4
+        '''  # [s|d]*.f
+        lasrc = '''
+        gbbrd gbcon gbequ gbrfs gbsv gbsvx gbtf2 gbtrf gbtrs gebak
+        gebal gebd2 gebrd gecon geequ gees geesx geev geevx gegs gegv
+        gehd2 gehrd gelq2 gelqf gels gelsd gelss gelsx gelsy geql2
+        geqlf geqp3 geqpf geqr2 geqrf gerfs gerq2 gerqf gesc2 gesdd
+        gesv gesvd gesvx getc2 getf2 getrf getri getrs ggbak ggbal
+        gges ggesx ggev ggevx ggglm gghrd gglse ggqrf ggrqf ggsvd
+        ggsvp gtcon gtrfs gtsv gtsvx gttrf gttrs gtts2 hgeqz hsein
+        hseqr labrd lacon laein lags2 lagtm lahqr lahrd laic1 lals0
+        lalsa lalsd langb lange langt lanhs lansb lansp lansy lantb
+        lantp lantr lapll lapmt laqgb laqge laqp2 laqps laqsb laqsp
+        laqsy lar1v lar2v larf larfb larfg larft larfx largv larrv
+        lartv larz larzb larzt laswp lasyf latbs latdf latps latrd
+        latrs latrz latzm lauu2 lauum pbcon pbequ pbrfs pbstf pbsv
+        pbsvx pbtf2 pbtrf pbtrs pocon poequ porfs posv posvx potf2
+        potrf potri potrs ppcon ppequ pprfs ppsv ppsvx pptrf pptri
+        pptrs ptcon pteqr ptrfs ptsv ptsvx pttrs ptts2 spcon sprfs
+        spsv spsvx sptrf sptri sptrs stegr stein sycon syrfs sysv
+        sysvx sytf2 sytrf sytri sytrs tbcon tbrfs tbtrs tgevc tgex2
+        tgexc tgsen tgsja tgsna tgsy2 tgsyl tpcon tprfs tptri tptrs
+        trcon trevc trexc trrfs trsen trsna trsyl trti2 trtri trtrs
+        tzrqf tzrzf
+
+        lacn2 lahr2 stemr laqr0 laqr1 laqr2 laqr3 laqr4 laqr5
+        '''  # [s|c|d|z]*.f
+        sd_lasrc = '''
+        laexc lag2 lagv2 laln2 lanv2 laqtr lasy2 opgtr opmtr org2l
+        org2r orgbr orghr orgl2 orglq orgql orgqr orgr2 orgrq orgtr
+        orm2l orm2r ormbr ormhr orml2 ormlq ormql ormqr ormr2 ormr3
+        ormrq ormrz ormtr rscl sbev sbevd sbevx sbgst sbgv sbgvd sbgvx
+        sbtrd spev spevd spevx spgst spgv spgvd spgvx sptrd stev stevd
+        stevr stevx syev syevd syevr syevx sygs2 sygst sygv sygvd
+        sygvx sytd2 sytrd
+        '''  # [s|d]*.f
+        cz_lasrc = '''
+        bdsqr hbev hbevd hbevx hbgst hbgv hbgvd hbgvx hbtrd hecon heev
+        heevd heevr heevx hegs2 hegst hegv hegvd hegvx herfs hesv
+        hesvx hetd2 hetf2 hetrd hetrf hetri hetrs hpcon hpev hpevd
+        hpevx hpgst hpgv hpgvd hpgvx hprfs hpsv hpsvx hptrd hptrf
+        hptri hptrs lacgv lacp2 lacpy lacrm lacrt ladiv laed0 laed7
+        laed8 laesy laev2 lahef lanhb lanhe lanhp lanht laqhb laqhe
+        laqhp larcm larnv lartg lascl laset lasr lassq pttrf rot spmv
+        spr stedc steqr symv syr ung2l ung2r ungbr unghr ungl2 unglq
+        ungql ungqr ungr2 ungrq ungtr unm2l unm2r unmbr unmhr unml2
+        unmlq unmql unmqr unmr2 unmr3 unmrq unmrz unmtr upgtr upmtr
+        '''  # [c|z]*.f
+        #######
+        sclaux = laux + ' econd '                  # s*.f
+        dzlaux = laux + ' secnd '                  # d*.f
+        slasrc = lasrc + sd_lasrc                  # s*.f
+        dlasrc = lasrc + sd_lasrc                  # d*.f
+        clasrc = lasrc + cz_lasrc + ' srot srscl '  # c*.f
+        zlasrc = lasrc + cz_lasrc + ' drot drscl '  # z*.f
+        oclasrc = ' icmax1 scsum1 '                # *.f
+        ozlasrc = ' izmax1 dzsum1 '                # *.f
+        sources = ['s%s.f' % f for f in (sclaux + slasrc).split()] \
+                  + ['d%s.f' % f for f in (dzlaux + dlasrc).split()] \
+                  + ['c%s.f' % f for f in (clasrc).split()] \
+                  + ['z%s.f' % f for f in (zlasrc).split()] \
+                  + ['%s.f' % f for f in (allaux + oclasrc + ozlasrc).split()]
+        sources = [os.path.join(src_dir, f) for f in sources]
+        # Lapack 3.1:
+        src_dir2 = os.path.join(src_dir, '..', 'INSTALL')
+        sources += [os.path.join(src_dir2, p + 'lamch.f') for p in 'sdcz']
+        # Lapack 3.2.1:
+        sources += [os.path.join(src_dir, p + 'larfp.f') for p in 'sdcz']
+        sources += [os.path.join(src_dir, 'ila' + p + 'lr.f') for p in 'sdcz']
+        sources += [os.path.join(src_dir, 'ila' + p + 'lc.f') for p in 'sdcz']
+        # Should we check here actual existence of source files?
+        # Yes, the file listing is different between 3.0 and 3.1
+        # versions.
+        sources = [f for f in sources if os.path.isfile(f)]
+        info = {'sources': sources, 'language': 'f77'}
+        self.set_info(**info)
+
+atlas_version_c_text = r'''
+/* This file is generated from numpy/distutils/system_info.py */
+void ATL_buildinfo(void);
+int main(void) {
+  ATL_buildinfo();
+  return 0;
+}
+'''
+
+_cached_atlas_version = {}
+
+
+def get_atlas_version(**config):
+    libraries = config.get('libraries', [])
+    library_dirs = config.get('library_dirs', [])
+    key = (tuple(libraries), tuple(library_dirs))
+    if key in _cached_atlas_version:
+        return _cached_atlas_version[key]
+    c = cmd_config(Distribution())
+    atlas_version = None
+    info = {}
+    try:
+        s, o = c.get_output(atlas_version_c_text,
+                            libraries=libraries, library_dirs=library_dirs,
+                            use_tee=(system_info.verbosity > 0))
+        if s and re.search(r'undefined reference to `_gfortran', o, re.M):
+            s, o = c.get_output(atlas_version_c_text,
+                                libraries=libraries + ['gfortran'],
+                                library_dirs=library_dirs,
+                                use_tee=(system_info.verbosity > 0))
+            if not s:
+                warnings.warn("""
+*****************************************************
+Linkage with ATLAS requires gfortran. Use
+
+  python setup.py config_fc --fcompiler=gnu95 ...
+
+when building extension libraries that use ATLAS.
+Make sure that -lgfortran is used for C++ extensions.
+*****************************************************
+""")
+                dict_append(info, language='f90',
+                            define_macros=[('ATLAS_REQUIRES_GFORTRAN', None)])
+    except Exception:  # failed to get version from file -- maybe on Windows
+        # look at directory name
+        for o in library_dirs:
+            m = re.search(r'ATLAS_(?P<version>\d+[.]\d+[.]\d+)_', o)
+            if m:
+                atlas_version = m.group('version')
+            if atlas_version is not None:
+                break
+
+        # final choice --- look at ATLAS_VERSION environment
+        #   variable
+        if atlas_version is None:
+            atlas_version = os.environ.get('ATLAS_VERSION', None)
+        if atlas_version:
+            dict_append(info, define_macros=[(
+                'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
+            ])
+        else:
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', -1)])
+        return atlas_version or '?.?.?', info
+
+    if not s:
+        m = re.search(r'ATLAS version (?P<version>\d+[.]\d+[.]\d+)', o)
+        if m:
+            atlas_version = m.group('version')
+    if atlas_version is None:
+        if re.search(r'undefined symbol: ATL_buildinfo', o, re.M):
+            atlas_version = '3.2.1_pre3.3.6'
+        else:
+            log.info('Status: %d', s)
+            log.info('Output: %s', o)
+
+    if atlas_version == '3.2.1_pre3.3.6':
+        dict_append(info, define_macros=[('NO_ATLAS_INFO', -2)])
+    else:
+        dict_append(info, define_macros=[(
+            'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
+        ])
+    result = _cached_atlas_version[key] = atlas_version, info
+    return result
+
+
+class lapack_opt_info(system_info):
+
+    notfounderror = LapackNotFoundError
+
+    def calc_info(self):
+
+        openblas_info = get_info('openblas_lapack')
+        if openblas_info:
+            self.set_info(**openblas_info)
+            return
+
+        lapack_mkl_info = get_info('lapack_mkl')
+        if lapack_mkl_info:
+            self.set_info(**lapack_mkl_info)
+            return
+
+        atlas_info = get_info('atlas_3_10_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_3_10')
+        if not atlas_info:
+            atlas_info = get_info('atlas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas')
+
+        if sys.platform == 'darwin' and not atlas_info:
+            # Use the system lapack from Accelerate or vecLib under OSX
+            args = []
+            link_args = []
+            if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
+               'x86_64' in get_platform() or \
+               'i386' in platform.platform():
+                intel = 1
+            else:
+                intel = 0
+            if os.path.exists('/System/Library/Frameworks'
+                              '/Accelerate.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
+            elif os.path.exists('/System/Library/Frameworks'
+                                '/vecLib.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
+            if args:
+                self.set_info(extra_compile_args=args,
+                              extra_link_args=link_args,
+                              define_macros=[('NO_ATLAS_INFO', 3),
+                                             ('HAVE_CBLAS', None)])
+                return
+
+        need_lapack = 0
+        need_blas = 0
+        info = {}
+        if atlas_info:
+            l = atlas_info.get('define_macros', [])
+            if ('ATLAS_WITH_LAPACK_ATLAS', None) in l \
+                   or ('ATLAS_WITHOUT_LAPACK', None) in l:
+                need_lapack = 1
+            info = atlas_info
+
+        else:
+            warnings.warn(AtlasNotFoundError.__doc__)
+            need_blas = 1
+            need_lapack = 1
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
+
+        if need_lapack:
+            lapack_info = get_info('lapack')
+            #lapack_info = {} ## uncomment for testing
+            if lapack_info:
+                dict_append(info, **lapack_info)
+            else:
+                warnings.warn(LapackNotFoundError.__doc__)
+                lapack_src_info = get_info('lapack_src')
+                if not lapack_src_info:
+                    warnings.warn(LapackSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('flapack_src', lapack_src_info)])
+
+        if need_blas:
+            blas_info = get_info('blas')
+            if blas_info:
+                dict_append(info, **blas_info)
+            else:
+                warnings.warn(BlasNotFoundError.__doc__)
+                blas_src_info = get_info('blas_src')
+                if not blas_src_info:
+                    warnings.warn(BlasSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('fblas_src', blas_src_info)])
+
+        self.set_info(**info)
+        return
+
+
+class blas_opt_info(system_info):
+
+    notfounderror = BlasNotFoundError
+
+    def calc_info(self):
+
+        blas_mkl_info = get_info('blas_mkl')
+        if blas_mkl_info:
+            self.set_info(**blas_mkl_info)
+            return
+
+        openblas_info = get_info('openblas')
+        if openblas_info:
+            self.set_info(**openblas_info)
+            return
+
+        atlas_info = get_info('atlas_3_10_blas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_3_10_blas')
+        if not atlas_info:
+            atlas_info = get_info('atlas_blas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_blas')
+
+        if sys.platform == 'darwin' and not atlas_info:
+            # Use the system BLAS from Accelerate or vecLib under OSX
+            args = []
+            link_args = []
+            if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
+               'x86_64' in get_platform() or \
+               'i386' in platform.platform():
+                intel = 1
+            else:
+                intel = 0
+            if os.path.exists('/System/Library/Frameworks'
+                              '/Accelerate.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                args.extend([
+                    '-I/System/Library/Frameworks/vecLib.framework/Headers'])
+                link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
+            elif os.path.exists('/System/Library/Frameworks'
+                                '/vecLib.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                args.extend([
+                    '-I/System/Library/Frameworks/vecLib.framework/Headers'])
+                link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
+            if args:
+                self.set_info(extra_compile_args=args,
+                              extra_link_args=link_args,
+                              define_macros=[('NO_ATLAS_INFO', 3),
+                                             ('HAVE_CBLAS', None)])
+                return
+
+        need_blas = 0
+        info = {}
+        if atlas_info:
+            info = atlas_info
+        else:
+            warnings.warn(AtlasNotFoundError.__doc__)
+            need_blas = 1
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
+
+        if need_blas:
+            blas_info = get_info('blas')
+            if blas_info:
+                dict_append(info, **blas_info)
+            else:
+                warnings.warn(BlasNotFoundError.__doc__)
+                blas_src_info = get_info('blas_src')
+                if not blas_src_info:
+                    warnings.warn(BlasSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('fblas_src', blas_src_info)])
+
+        self.set_info(**info)
+        return
+
+
+class blas_info(system_info):
+    section = 'blas'
+    dir_env_var = 'BLAS'
+    _lib_names = ['blas']
+    notfounderror = BlasNotFoundError
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        blas_libs = self.get_libs('blas_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, blas_libs, [])
+        if info is None:
+            return
+        if platform.system() == 'Windows':
+            # The check for windows is needed because has_cblas uses the
+            # same compiler that was used to compile Python and msvc is
+            # often not installed when mingw is being used. This rough
+            # treatment is not desirable, but windows is tricky.
+            info['language'] = 'f77'  # XXX: is it generally true?
+        else:
+            lib = self.has_cblas(info)
+            if lib is not None:
+                info['language'] = 'c'
+                info['libraries'] = [lib]
+                info['define_macros'] = [('HAVE_CBLAS', None)]
+        self.set_info(**info)
+
+    def has_cblas(self, info):
+        # primitive cblas check by looking for the header and trying to link
+        # cblas or blas
+        res = False
+        c = distutils.ccompiler.new_compiler()
+        tmpdir = tempfile.mkdtemp()
+        s = """#include <cblas.h>
+        int main(int argc, const char *argv[])
+        {
+            double a[4] = {1,2,3,4};
+            double b[4] = {5,6,7,8};
+            return cblas_ddot(4, a, 1, b, 1) > 10;
+        }"""
+        src = os.path.join(tmpdir, 'source.c')
+        try:
+            with open(src, 'wt') as f:
+                f.write(s)
+
+            try:
+                # check we can compile (find headers)
+                obj = c.compile([src], output_dir=tmpdir,
+                                include_dirs=self.get_include_dirs())
+
+                # check we can link (find library)
+                # some systems have separate cblas and blas libs. First
+                # check for cblas lib, and if not present check for blas lib.
+                try:
+                    c.link_executable(obj, os.path.join(tmpdir, "a.out"),
+                                      libraries=["cblas"],
+                                      library_dirs=info['library_dirs'],
+                                      extra_postargs=info.get('extra_link_args', []))
+                    res = "cblas"
+                except distutils.ccompiler.LinkError:
+                    c.link_executable(obj, os.path.join(tmpdir, "a.out"),
+                                      libraries=["blas"],
+                                      library_dirs=info['library_dirs'],
+                                      extra_postargs=info.get('extra_link_args', []))
+                    res = "blas"
+            except distutils.ccompiler.CompileError:
+                res = None
+        finally:
+            shutil.rmtree(tmpdir)
+        return res
+
+
+class openblas_info(blas_info):
+    section = 'openblas'
+    dir_env_var = 'OPENBLAS'
+    _lib_names = ['openblas']
+    notfounderror = BlasNotFoundError
+
+    def check_embedded_lapack(self, info):
+        return True
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        openblas_libs = self.get_libs('libraries', self._lib_names)
+        if openblas_libs == self._lib_names: # backward compat with 1.8.0
+            openblas_libs = self.get_libs('openblas_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, openblas_libs, [])
+        if info is None:
+            return
+
+        # Add extra info for OpenBLAS
+        extra_info = self.calc_extra_info()
+        dict_append(info, **extra_info)
+
+        if not self.check_embedded_lapack(info):
+            return
+
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+        self.set_info(**info)
+
+
+class openblas_lapack_info(openblas_info):
+    section = 'openblas'
+    dir_env_var = 'OPENBLAS'
+    _lib_names = ['openblas']
+    notfounderror = BlasNotFoundError
+
+    def check_embedded_lapack(self, info):
+        res = False
+        c = distutils.ccompiler.new_compiler()
+        tmpdir = tempfile.mkdtemp()
+        s = """void zungqr();
+        int main(int argc, const char *argv[])
+        {
+            zungqr_();
+            return 0;
+        }"""
+        src = os.path.join(tmpdir, 'source.c')
+        out = os.path.join(tmpdir, 'a.out')
+        # Add the additional "extra" arguments
+        try:
+            extra_args = info['extra_link_args']
+        except:
+            extra_args = []
+        try:
+            with open(src, 'wt') as f:
+                f.write(s)
+            obj = c.compile([src], output_dir=tmpdir)
+            try:
+                c.link_executable(obj, out, libraries=info['libraries'],
+                                  library_dirs=info['library_dirs'],
+                                  extra_postargs=extra_args)
+                res = True
+            except distutils.ccompiler.LinkError:
+                res = False
+        finally:
+            shutil.rmtree(tmpdir)
+        return res
+
+
+class blas_src_info(system_info):
+    section = 'blas_src'
+    dir_env_var = 'BLAS_SRC'
+    notfounderror = BlasSrcNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['blas']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'daxpy.f')):
+                src_dir = d
+                break
+        if not src_dir:
+            #XXX: Get sources from netlib. May be ask first.
+            return
+        blas1 = '''
+        caxpy csscal dnrm2 dzasum saxpy srotg zdotc ccopy cswap drot
+        dznrm2 scasum srotm zdotu cdotc dasum drotg icamax scnrm2
+        srotmg zdrot cdotu daxpy drotm idamax scopy sscal zdscal crotg
+        dcabs1 drotmg isamax sdot sswap zrotg cscal dcopy dscal izamax
+        snrm2 zaxpy zscal csrot ddot dswap sasum srot zcopy zswap
+        scabs1
+        '''
+        blas2 = '''
+        cgbmv chpmv ctrsv dsymv dtrsv sspr2 strmv zhemv ztpmv cgemv
+        chpr dgbmv dsyr lsame ssymv strsv zher ztpsv cgerc chpr2 dgemv
+        dsyr2 sgbmv ssyr xerbla zher2 ztrmv cgeru ctbmv dger dtbmv
+        sgemv ssyr2 zgbmv zhpmv ztrsv chbmv ctbsv dsbmv dtbsv sger
+        stbmv zgemv zhpr chemv ctpmv dspmv dtpmv ssbmv stbsv zgerc
+        zhpr2 cher ctpsv dspr dtpsv sspmv stpmv zgeru ztbmv cher2
+        ctrmv dspr2 dtrmv sspr stpsv zhbmv ztbsv
+        '''
+        blas3 = '''
+        cgemm csymm ctrsm dsyrk sgemm strmm zhemm zsyr2k chemm csyr2k
+        dgemm dtrmm ssymm strsm zher2k zsyrk cher2k csyrk dsymm dtrsm
+        ssyr2k zherk ztrmm cherk ctrmm dsyr2k ssyrk zgemm zsymm ztrsm
+        '''
+        sources = [os.path.join(src_dir, f + '.f') \
+                   for f in (blas1 + blas2 + blas3).split()]
+        #XXX: should we check here actual existence of source files?
+        sources = [f for f in sources if os.path.isfile(f)]
+        info = {'sources': sources, 'language': 'f77'}
+        self.set_info(**info)
+
+
+class x11_info(system_info):
+    section = 'x11'
+    notfounderror = X11NotFoundError
+
+    def __init__(self):
+        system_info.__init__(self,
+                             default_lib_dirs=default_x11_lib_dirs,
+                             default_include_dirs=default_x11_include_dirs)
+
+    def calc_info(self):
+        if sys.platform  in ['win32']:
+            return
+        lib_dirs = self.get_lib_dirs()
+        include_dirs = self.get_include_dirs()
+        x11_libs = self.get_libs('x11_libs', ['X11'])
+        info = self.check_libs(lib_dirs, x11_libs, [])
+        if info is None:
+            return
+        inc_dir = None
+        for d in include_dirs:
+            if self.combine_paths(d, 'X11/X.h'):
+                inc_dir = d
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir])
+        self.set_info(**info)
+
+
+class _numpy_info(system_info):
+    section = 'Numeric'
+    modulename = 'Numeric'
+    notfounderror = NumericNotFoundError
+
+    def __init__(self):
+        include_dirs = []
+        try:
+            module = __import__(self.modulename)
+            prefix = []
+            for name in module.__file__.split(os.sep):
+                if name == 'lib':
+                    break
+                prefix.append(name)
+
+            # Ask numpy for its own include path before attempting
+            # anything else
+            try:
+                include_dirs.append(getattr(module, 'get_include')())
+            except AttributeError:
+                pass
+
+            include_dirs.append(distutils.sysconfig.get_python_inc(
+                                        prefix=os.sep.join(prefix)))
+        except ImportError:
+            pass
+        py_incl_dir = distutils.sysconfig.get_python_inc()
+        include_dirs.append(py_incl_dir)
+        py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
+        if py_pincl_dir not in include_dirs:
+            include_dirs.append(py_pincl_dir)
+        for d in default_include_dirs:
+            d = os.path.join(d, os.path.basename(py_incl_dir))
+            if d not in include_dirs:
+                include_dirs.append(d)
+        system_info.__init__(self,
+                             default_lib_dirs=[],
+                             default_include_dirs=include_dirs)
+
+    def calc_info(self):
+        try:
+            module = __import__(self.modulename)
+        except ImportError:
+            return
+        info = {}
+        macros = []
+        for v in ['__version__', 'version']:
+            vrs = getattr(module, v, None)
+            if vrs is None:
+                continue
+            macros = [(self.modulename.upper() + '_VERSION',
+                      '"\\"%s\\""' % (vrs)),
+                      (self.modulename.upper(), None)]
+            break
+        dict_append(info, define_macros=macros)
+        include_dirs = self.get_include_dirs()
+        inc_dir = None
+        for d in include_dirs:
+            if self.combine_paths(d,
+                                  os.path.join(self.modulename,
+                                               'arrayobject.h')):
+                inc_dir = d
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir])
+        if info:
+            self.set_info(**info)
+        return
+
+
+class numarray_info(_numpy_info):
+    section = 'numarray'
+    modulename = 'numarray'
+
+
+class Numeric_info(_numpy_info):
+    section = 'Numeric'
+    modulename = 'Numeric'
+
+
+class numpy_info(_numpy_info):
+    section = 'numpy'
+    modulename = 'numpy'
+
+
+class numerix_info(system_info):
+    section = 'numerix'
+
+    def calc_info(self):
+        which = None, None
+        if os.getenv("NUMERIX"):
+            which = os.getenv("NUMERIX"), "environment var"
+        # If all the above fail, default to numpy.
+        if which[0] is None:
+            which = "numpy", "defaulted"
+            try:
+                import numpy
+                which = "numpy", "defaulted"
+            except ImportError:
+                msg1 = str(get_exception())
+                try:
+                    import Numeric
+                    which = "numeric", "defaulted"
+                except ImportError:
+                    msg2 = str(get_exception())
+                    try:
+                        import numarray
+                        which = "numarray", "defaulted"
+                    except ImportError:
+                        msg3 = str(get_exception())
+                        log.info(msg1)
+                        log.info(msg2)
+                        log.info(msg3)
+        which = which[0].strip().lower(), which[1]
+        if which[0] not in ["numeric", "numarray", "numpy"]:
+            raise ValueError("numerix selector must be either 'Numeric' "
+                             "or 'numarray' or 'numpy' but the value obtained"
+                             " from the %s was '%s'." % (which[1], which[0]))
+        os.environ['NUMERIX'] = which[0]
+        self.set_info(**get_info(which[0]))
+
+
+class f2py_info(system_info):
+    def calc_info(self):
+        try:
+            import numpy.f2py as f2py
+        except ImportError:
+            return
+        f2py_dir = os.path.join(os.path.dirname(f2py.__file__), 'src')
+        self.set_info(sources=[os.path.join(f2py_dir, 'fortranobject.c')],
+                      include_dirs=[f2py_dir])
+        return
+
+
+class boost_python_info(system_info):
+    section = 'boost_python'
+    dir_env_var = 'BOOST'
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['boost*']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'libs', 'python', 'src',
+                                           'module.cpp')):
+                src_dir = d
+                break
+        if not src_dir:
+            return
+        py_incl_dirs = [distutils.sysconfig.get_python_inc()]
+        py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
+        if py_pincl_dir not in py_incl_dirs:
+            py_incl_dirs.append(py_pincl_dir)
+        srcs_dir = os.path.join(src_dir, 'libs', 'python', 'src')
+        bpl_srcs = glob(os.path.join(srcs_dir, '*.cpp'))
+        bpl_srcs += glob(os.path.join(srcs_dir, '*', '*.cpp'))
+        info = {'libraries': [('boost_python_src',
+                               {'include_dirs': [src_dir] + py_incl_dirs,
+                                'sources':bpl_srcs}
+                              )],
+                'include_dirs': [src_dir],
+                }
+        if info:
+            self.set_info(**info)
+        return
+
+
+class agg2_info(system_info):
+    section = 'agg2'
+    dir_env_var = 'AGG2'
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['agg2*']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'src', 'agg_affine_matrix.cpp')):
+                src_dir = d
+                break
+        if not src_dir:
+            return
+        if sys.platform == 'win32':
+            agg2_srcs = glob(os.path.join(src_dir, 'src', 'platform',
+                                          'win32', 'agg_win32_bmp.cpp'))
+        else:
+            agg2_srcs = glob(os.path.join(src_dir, 'src', '*.cpp'))
+            agg2_srcs += [os.path.join(src_dir, 'src', 'platform',
+                                       'X11',
+                                       'agg_platform_support.cpp')]
+
+        info = {'libraries':
+                [('agg2_src',
+                  {'sources': agg2_srcs,
+                   'include_dirs': [os.path.join(src_dir, 'include')],
+                  }
+                 )],
+                'include_dirs': [os.path.join(src_dir, 'include')],
+                }
+        if info:
+            self.set_info(**info)
+        return
+
+
+class _pkg_config_info(system_info):
+    section = None
+    config_env_var = 'PKG_CONFIG'
+    default_config_exe = 'pkg-config'
+    append_config_exe = ''
+    version_macro_name = None
+    release_macro_name = None
+    version_flag = '--modversion'
+    cflags_flag = '--cflags'
+
+    def get_config_exe(self):
+        if self.config_env_var in os.environ:
+            return os.environ[self.config_env_var]
+        return self.default_config_exe
+
+    def get_config_output(self, config_exe, option):
+        cmd = config_exe + ' ' + self.append_config_exe + ' ' + option
+        s, o = exec_command(cmd, use_tee=0)
+        if not s:
+            return o
+
+    def calc_info(self):
+        config_exe = find_executable(self.get_config_exe())
+        if not config_exe:
+            log.warn('File not found: %s. Cannot determine %s info.' \
+                  % (config_exe, self.section))
+            return
+        info = {}
+        macros = []
+        libraries = []
+        library_dirs = []
+        include_dirs = []
+        extra_link_args = []
+        extra_compile_args = []
+        version = self.get_config_output(config_exe, self.version_flag)
+        if version:
+            macros.append((self.__class__.__name__.split('.')[-1].upper(),
+                           '"\\"%s\\""' % (version)))
+            if self.version_macro_name:
+                macros.append((self.version_macro_name + '_%s'
+                               % (version.replace('.', '_')), None))
+        if self.release_macro_name:
+            release = self.get_config_output(config_exe, '--release')
+            if release:
+                macros.append((self.release_macro_name + '_%s'
+                               % (release.replace('.', '_')), None))
+        opts = self.get_config_output(config_exe, '--libs')
+        if opts:
+            for opt in opts.split():
+                if opt[:2] == '-l':
+                    libraries.append(opt[2:])
+                elif opt[:2] == '-L':
+                    library_dirs.append(opt[2:])
+                else:
+                    extra_link_args.append(opt)
+        opts = self.get_config_output(config_exe, self.cflags_flag)
+        if opts:
+            for opt in opts.split():
+                if opt[:2] == '-I':
+                    include_dirs.append(opt[2:])
+                elif opt[:2] == '-D':
+                    if '=' in opt:
+                        n, v = opt[2:].split('=')
+                        macros.append((n, v))
+                    else:
+                        macros.append((opt[2:], None))
+                else:
+                    extra_compile_args.append(opt)
+        if macros:
+            dict_append(info, define_macros=macros)
+        if libraries:
+            dict_append(info, libraries=libraries)
+        if library_dirs:
+            dict_append(info, library_dirs=library_dirs)
+        if include_dirs:
+            dict_append(info, include_dirs=include_dirs)
+        if extra_link_args:
+            dict_append(info, extra_link_args=extra_link_args)
+        if extra_compile_args:
+            dict_append(info, extra_compile_args=extra_compile_args)
+        if info:
+            self.set_info(**info)
+        return
+
+
+class wx_info(_pkg_config_info):
+    section = 'wx'
+    config_env_var = 'WX_CONFIG'
+    default_config_exe = 'wx-config'
+    append_config_exe = ''
+    version_macro_name = 'WX_VERSION'
+    release_macro_name = 'WX_RELEASE'
+    version_flag = '--version'
+    cflags_flag = '--cxxflags'
+
+
+class gdk_pixbuf_xlib_2_info(_pkg_config_info):
+    section = 'gdk_pixbuf_xlib_2'
+    append_config_exe = 'gdk-pixbuf-xlib-2.0'
+    version_macro_name = 'GDK_PIXBUF_XLIB_VERSION'
+
+
+class gdk_pixbuf_2_info(_pkg_config_info):
+    section = 'gdk_pixbuf_2'
+    append_config_exe = 'gdk-pixbuf-2.0'
+    version_macro_name = 'GDK_PIXBUF_VERSION'
+
+
+class gdk_x11_2_info(_pkg_config_info):
+    section = 'gdk_x11_2'
+    append_config_exe = 'gdk-x11-2.0'
+    version_macro_name = 'GDK_X11_VERSION'
+
+
+class gdk_2_info(_pkg_config_info):
+    section = 'gdk_2'
+    append_config_exe = 'gdk-2.0'
+    version_macro_name = 'GDK_VERSION'
+
+
+class gdk_info(_pkg_config_info):
+    section = 'gdk'
+    append_config_exe = 'gdk'
+    version_macro_name = 'GDK_VERSION'
+
+
+class gtkp_x11_2_info(_pkg_config_info):
+    section = 'gtkp_x11_2'
+    append_config_exe = 'gtk+-x11-2.0'
+    version_macro_name = 'GTK_X11_VERSION'
+
+
+class gtkp_2_info(_pkg_config_info):
+    section = 'gtkp_2'
+    append_config_exe = 'gtk+-2.0'
+    version_macro_name = 'GTK_VERSION'
+
+
+class xft_info(_pkg_config_info):
+    section = 'xft'
+    append_config_exe = 'xft'
+    version_macro_name = 'XFT_VERSION'
+
+
+class freetype2_info(_pkg_config_info):
+    section = 'freetype2'
+    append_config_exe = 'freetype2'
+    version_macro_name = 'FREETYPE2_VERSION'
+
+
+class amd_info(system_info):
+    section = 'amd'
+    dir_env_var = 'AMD'
+    _lib_names = ['amd']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        amd_libs = self.get_libs('amd_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, amd_libs, [])
+        if info is None:
+            return
+
+        include_dirs = self.get_include_dirs()
+
+        inc_dir = None
+        for d in include_dirs:
+            p = self.combine_paths(d, 'amd.h')
+            if p:
+                inc_dir = os.path.dirname(p[0])
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir],
+                        define_macros=[('SCIPY_AMD_H', None)],
+                        swig_opts=['-I' + inc_dir])
+
+        self.set_info(**info)
+        return
+
+
+class umfpack_info(system_info):
+    section = 'umfpack'
+    dir_env_var = 'UMFPACK'
+    notfounderror = UmfpackNotFoundError
+    _lib_names = ['umfpack']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        umfpack_libs = self.get_libs('umfpack_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, umfpack_libs, [])
+        if info is None:
+            return
+
+        include_dirs = self.get_include_dirs()
+
+        inc_dir = None
+        for d in include_dirs:
+            p = self.combine_paths(d, ['', 'umfpack'], 'umfpack.h')
+            if p:
+                inc_dir = os.path.dirname(p[0])
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir],
+                        define_macros=[('SCIPY_UMFPACK_H', None)],
+                        swig_opts=['-I' + inc_dir])
+
+        amd = get_info('amd')
+        dict_append(info, **get_info('amd'))
+
+        self.set_info(**info)
+        return
+
+
+def combine_paths(*args, **kws):
+    """ Return a list of existing paths composed by all combinations of
+        items from arguments.
+    """
+    r = []
+    for a in args:
+        if not a:
+            continue
+        if is_string(a):
+            a = [a]
+        r.append(a)
+    args = r
+    if not args:
+        return []
+    if len(args) == 1:
+        result = reduce(lambda a, b: a + b, map(glob, args[0]), [])
+    elif len(args) == 2:
+        result = []
+        for a0 in args[0]:
+            for a1 in args[1]:
+                result.extend(glob(os.path.join(a0, a1)))
+    else:
+        result = combine_paths(*(combine_paths(args[0], args[1]) + args[2:]))
+    verbosity = kws.get('verbosity', 1)
+    log.debug('(paths: %s)', ','.join(result))
+    return result
+
+language_map = {'c': 0, 'c++': 1, 'f77': 2, 'f90': 3}
+inv_language_map = {0: 'c', 1: 'c++', 2: 'f77', 3: 'f90'}
+
+
+def dict_append(d, **kws):
+    languages = []
+    for k, v in kws.items():
+        if k == 'language':
+            languages.append(v)
+            continue
+        if k in d:
+            if k in ['library_dirs', 'include_dirs', 
+                     'extra_compile_args', 'extra_link_args',
+                     'runtime_library_dirs', 'define_macros']:
+                [d[k].append(vv) for vv in v if vv not in d[k]]
+            else:
+                d[k].extend(v)
+        else:
+            d[k] = v
+    if languages:
+        l = inv_language_map[max([language_map.get(l, 0) for l in languages])]
+        d['language'] = l
+    return
+
+
+def parseCmdLine(argv=(None,)):
+    import optparse
+    parser = optparse.OptionParser("usage: %prog [-v] [info objs]")
+    parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
+                      default=False,
+                      help='be verbose and print more messages')
+
+    opts, args = parser.parse_args(args=argv[1:])
+    return opts, args
+
+
+def show_all(argv=None):
+    import inspect
+    if argv is None:
+        argv = sys.argv
+    opts, args = parseCmdLine(argv)
+    if opts.verbose:
+        log.set_threshold(log.DEBUG)
+    else:
+        log.set_threshold(log.INFO)
+    show_only = []
+    for n in args:
+        if n[-5:] != '_info':
+            n = n + '_info'
+        show_only.append(n)
+    show_all = not show_only
+    _gdict_ = globals().copy()
+    for name, c in _gdict_.items():
+        if not inspect.isclass(c):
+            continue
+        if not issubclass(c, system_info) or c is system_info:
+            continue
+        if not show_all:
+            if name not in show_only:
+                continue
+            del show_only[show_only.index(name)]
+        conf = c()
+        conf.verbosity = 2
+        r = conf.get_info()
+    if show_only:
+        log.info('Info classes not defined: %s', ','.join(show_only))
+
+if __name__ == "__main__":
+    show_all()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
new file mode 100644
index 0000000000..0931f749b3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
@@ -0,0 +1,92 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from tempfile import TemporaryFile
+
+from numpy.distutils import exec_command
+
+# In python 3 stdout, stderr are text (unicode compliant) devices, so to
+# emulate them import StringIO from the io module.
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+class redirect_stdout(object):
+    """Context manager to redirect stdout for exec_command test."""
+    def __init__(self, stdout=None):
+        self._stdout = stdout or sys.stdout
+
+    def __enter__(self):
+        self.old_stdout = sys.stdout
+        sys.stdout = self._stdout
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._stdout.flush()
+        sys.stdout = self.old_stdout
+        # note: closing sys.stdout won't close it.
+        self._stdout.close()
+
+class redirect_stderr(object):
+    """Context manager to redirect stderr for exec_command test."""
+    def __init__(self, stderr=None):
+        self._stderr = stderr or sys.stderr
+
+    def __enter__(self):
+        self.old_stderr = sys.stderr
+        sys.stderr = self._stderr
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._stderr.flush()
+        sys.stderr = self.old_stderr
+        # note: closing sys.stderr won't close it.
+        self._stderr.close()
+
+class emulate_nonposix(object):
+    """Context manager to emulate os.name != 'posix' """
+    def __init__(self, osname='non-posix'):
+        self._new_name = osname
+
+    def __enter__(self):
+        self._old_name = os.name
+        os.name = self._new_name
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        os.name = self._old_name
+
+
+def test_exec_command_stdout():
+    # Regression test for gh-2999 and gh-2915.
+    # There are several packages (nose, scipy.weave.inline, Sage inline
+    # Fortran) that replace stdout, in which case it doesn't have a fileno
+    # method.  This is tested here, with a do-nothing command that fails if the
+    # presence of fileno() is assumed in exec_command.
+
+    # The code has a special case for posix systems, so if we are on posix test
+    # both that the special case works and that the generic code works.
+
+    # Test posix version:
+    with redirect_stdout(StringIO()):
+        with redirect_stderr(TemporaryFile()):
+            exec_command.exec_command("cd '.'")
+
+    if os.name == 'posix':
+        # Test general (non-posix) version:
+        with emulate_nonposix():
+            with redirect_stdout(StringIO()):
+                with redirect_stderr(TemporaryFile()):
+                    exec_command.exec_command("cd '.'")
+
+def test_exec_command_stderr():
+    # Test posix version:
+    with redirect_stdout(TemporaryFile(mode='w+')):
+        with redirect_stderr(StringIO()):
+            exec_command.exec_command("cd '.'")
+
+    if os.name == 'posix':
+        # Test general (non-posix) version:
+        with emulate_nonposix():
+            with redirect_stdout(TemporaryFile()):
+                with redirect_stderr(StringIO()):
+                    exec_command.exec_command("cd '.'")
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
new file mode 100644
index 0000000000..7ca99db22a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
@@ -0,0 +1,60 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import TestCase, assert_, run_module_suite
+
+import numpy.distutils.fcompiler
+
+g77_version_strings = [
+    ('GNU Fortran 0.5.25 20010319 (prerelease)', '0.5.25'),
+    ('GNU Fortran (GCC 3.2) 3.2 20020814 (release)', '3.2'),
+    ('GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian)', '3.3.3'),
+    ('GNU Fortran (GCC) 3.3.3 (Debian 20040401)', '3.3.3'),
+    ('GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2'
+       ' 20030222 (Red Hat Linux 3.2.2-5)', '3.2.2'),
+]
+
+gfortran_version_strings = [
+    ('GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3))',
+     '4.0.3'),
+    ('GNU Fortran 95 (GCC) 4.1.0', '4.1.0'),
+    ('GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental)', '4.2.0'),
+    ('GNU Fortran (GCC) 4.3.0 20070316 (experimental)', '4.3.0'),
+    ('GNU Fortran (rubenvb-4.8.0) 4.8.0', '4.8.0'),
+    ('4.8.0', '4.8.0'),
+    ('4.0.3-7', '4.0.3'),
+    ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n4.9.1",
+     '4.9.1'),
+    ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n"
+     "gfortran: warning: yet another warning\n4.9.1",
+     '4.9.1')
+]
+
+class TestG77Versions(TestCase):
+    def test_g77_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
+        for vs, version in g77_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version, (vs, v))
+
+    def test_not_g77(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
+        for vs, _ in gfortran_version_strings:
+            v = fc.version_match(vs)
+            assert_(v is None, (vs, v))
+
+class TestGFortranVersions(TestCase):
+    def test_gfortran_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
+        for vs, version in gfortran_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version, (vs, v))
+
+    def test_not_gfortran(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
+        for vs, _ in g77_version_strings:
+            v = fc.version_match(vs)
+            assert_(v is None, (vs, v))
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
new file mode 100644
index 0000000000..8e371b92b7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
@@ -0,0 +1,36 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.distutils.fcompiler
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+intel_32bit_version_strings = [
+    ("Intel(R) Fortran Intel(R) 32-bit Compiler Professional for applications"
+     "running on Intel(R) 32, Version 11.1", '11.1'),
+]
+
+intel_64bit_version_strings = [
+    ("Intel(R) Fortran IA-64 Compiler Professional for applications"
+     "running on IA-64, Version 11.0", '11.0'),
+    ("Intel(R) Fortran Intel(R) 64 Compiler Professional for applications"
+     "running on Intel(R) 64, Version 11.1", '11.1')
+]
+
+class TestIntelFCompilerVersions(TestCase):
+    def test_32bit_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intel')
+        for vs, version in intel_32bit_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version)
+
+
+class TestIntelEM64TFCompilerVersions(TestCase):
+    def test_64bit_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intelem')
+        for vs, version in intel_64bit_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version)
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
new file mode 100644
index 0000000000..df845f71b3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python2
+from __future__ import division, absolute_import, print_function
+
+from os.path import join, sep, dirname
+
+from numpy.distutils.misc_util import (
+    appendpath, minrelpath, gpaths, get_shared_lib_extension
+)
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal
+)
+
+ajoin = lambda *paths: join(*((sep,)+paths))
+
+class TestAppendpath(TestCase):
+
+    def test_1(self):
+        assert_equal(appendpath('prefix', 'name'), join('prefix', 'name'))
+        assert_equal(appendpath('/prefix', 'name'), ajoin('prefix', 'name'))
+        assert_equal(appendpath('/prefix', '/name'), ajoin('prefix', 'name'))
+        assert_equal(appendpath('prefix', '/name'), join('prefix', 'name'))
+
+    def test_2(self):
+        assert_equal(appendpath('prefix/sub', 'name'),
+                     join('prefix', 'sub', 'name'))
+        assert_equal(appendpath('prefix/sub', 'sup/name'),
+                     join('prefix', 'sub', 'sup', 'name'))
+        assert_equal(appendpath('/prefix/sub', '/prefix/name'),
+                     ajoin('prefix', 'sub', 'name'))
+
+    def test_3(self):
+        assert_equal(appendpath('/prefix/sub', '/prefix/sup/name'),
+                     ajoin('prefix', 'sub', 'sup', 'name'))
+        assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sup/sup2/name'),
+                     ajoin('prefix', 'sub', 'sub2', 'sup', 'sup2', 'name'))
+        assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sub/sup/name'),
+                     ajoin('prefix', 'sub', 'sub2', 'sup', 'name'))
+
+class TestMinrelpath(TestCase):
+
+    def test_1(self):
+        n = lambda path: path.replace('/', sep)
+        assert_equal(minrelpath(n('aa/bb')), n('aa/bb'))
+        assert_equal(minrelpath('..'), '..')
+        assert_equal(minrelpath(n('aa/..')), '')
+        assert_equal(minrelpath(n('aa/../bb')), 'bb')
+        assert_equal(minrelpath(n('aa/bb/..')), 'aa')
+        assert_equal(minrelpath(n('aa/bb/../..')), '')
+        assert_equal(minrelpath(n('aa/bb/../cc/../dd')), n('aa/dd'))
+        assert_equal(minrelpath(n('.././..')), n('../..'))
+        assert_equal(minrelpath(n('aa/bb/.././../dd')), n('dd'))
+
+class TestGpaths(TestCase):
+
+    def test_gpaths(self):
+        local_path = minrelpath(join(dirname(__file__), '..'))
+        ls = gpaths('command/*.py', local_path)
+        assert_(join(local_path, 'command', 'build_src.py') in ls, repr(ls))
+        f = gpaths('system_info.py', local_path)
+        assert_(join(local_path, 'system_info.py') == f[0], repr(f))
+
+class TestSharedExtension(TestCase):
+
+    def test_get_shared_lib_extension(self):
+        import sys
+        ext = get_shared_lib_extension(is_python_ext=False)
+        if sys.platform.startswith('linux'):
+            assert_equal(ext, '.so')
+        elif sys.platform.startswith('gnukfreebsd'):
+            assert_equal(ext, '.so')
+        elif sys.platform.startswith('darwin'):
+            assert_equal(ext, '.dylib')
+        elif sys.platform.startswith('win'):
+            assert_equal(ext, '.dll')
+        # just check for no crash
+        assert_(get_shared_lib_extension(is_python_ext=True))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
new file mode 100644
index 0000000000..bdef47167b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.npy_pkg_config import read_config, parse_flags
+from numpy.testing import TestCase, run_module_suite, temppath
+
+simple = """\
+[meta]
+Name = foo
+Description = foo lib
+Version = 0.1
+
+[default]
+cflags = -I/usr/include
+libs = -L/usr/lib
+"""
+simple_d = {'cflags': '-I/usr/include', 'libflags': '-L/usr/lib',
+        'version': '0.1', 'name': 'foo'}
+
+simple_variable = """\
+[meta]
+Name = foo
+Description = foo lib
+Version = 0.1
+
+[variables]
+prefix = /foo/bar
+libdir = ${prefix}/lib
+includedir = ${prefix}/include
+
+[default]
+cflags = -I${includedir}
+libs = -L${libdir}
+"""
+simple_variable_d = {'cflags': '-I/foo/bar/include', 'libflags': '-L/foo/bar/lib',
+        'version': '0.1', 'name': 'foo'}
+
+class TestLibraryInfo(TestCase):
+    def test_simple(self):
+        with temppath('foo.ini') as path:
+            with open(path,  'w') as f:
+                f.write(simple)
+            pkg = os.path.splitext(path)[0]
+            out = read_config(pkg)
+
+        self.assertTrue(out.cflags() == simple_d['cflags'])
+        self.assertTrue(out.libs() == simple_d['libflags'])
+        self.assertTrue(out.name == simple_d['name'])
+        self.assertTrue(out.version == simple_d['version'])
+
+    def test_simple_variable(self):
+        with temppath('foo.ini') as path:
+            with open(path,  'w') as f:
+                f.write(simple_variable)
+            pkg = os.path.splitext(path)[0]
+            out = read_config(pkg)
+
+        self.assertTrue(out.cflags() == simple_variable_d['cflags'])
+        self.assertTrue(out.libs() == simple_variable_d['libflags'])
+        self.assertTrue(out.name == simple_variable_d['name'])
+        self.assertTrue(out.version == simple_variable_d['version'])
+        out.vars['prefix'] = '/Users/david'
+        self.assertTrue(out.cflags() == '-I/Users/david/include')
+
+class TestParseFlags(TestCase):
+    def test_simple_cflags(self):
+        d = parse_flags("-I/usr/include")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+
+        d = parse_flags("-I/usr/include -DFOO")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+        self.assertTrue(d['macros'] == ['FOO'])
+
+        d = parse_flags("-I /usr/include -DFOO")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+        self.assertTrue(d['macros'] == ['FOO'])
+
+    def test_simple_lflags(self):
+        d = parse_flags("-L/usr/lib -lfoo -L/usr/lib -lbar")
+        self.assertTrue(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
+        self.assertTrue(d['libraries'] == ['foo', 'bar'])
+
+        d = parse_flags("-L /usr/lib -lfoo -L/usr/lib -lbar")
+        self.assertTrue(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
+        self.assertTrue(d['libraries'] == ['foo', 'bar'])
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
new file mode 100644
index 0000000000..58ad05a593
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
@@ -0,0 +1,208 @@
+from __future__ import division, print_function
+
+import os
+import shutil
+from tempfile import mkstemp, mkdtemp
+
+from numpy.distutils import ccompiler
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal
+from numpy.testing.decorators import skipif
+from numpy.distutils.system_info import system_info, ConfigParser
+from numpy.distutils.system_info import default_lib_dirs, default_include_dirs
+
+
+def get_class(name, notfound_action=1):
+    """
+    notfound_action:
+      0 - do nothing
+      1 - display warning message
+      2 - raise error
+    """
+    cl = {'temp1': TestTemp1,
+          'temp2': TestTemp2
+          }.get(name.lower(), test_system_info)
+    return cl()
+
+simple_site = """
+[ALL]
+library_dirs = {dir1:s}{pathsep:s}{dir2:s}
+libraries = {lib1:s},{lib2:s}
+extra_compile_args = -I/fake/directory
+runtime_library_dirs = {dir1:s}
+
+[temp1]
+library_dirs = {dir1:s}
+libraries = {lib1:s}
+runtime_library_dirs = {dir1:s}
+
+[temp2]
+library_dirs = {dir2:s}
+libraries = {lib2:s}
+extra_link_args = -Wl,-rpath={lib2:s}
+rpath = {dir2:s}
+"""
+site_cfg = simple_site
+
+fakelib_c_text = """
+/* This file is generated from numpy/distutils/testing/test_system_info.py */
+#include<stdio.h>
+void foo(void) {
+   printf("Hello foo");
+}
+void bar(void) {
+   printf("Hello bar");
+}
+"""
+
+
+class test_system_info(system_info):
+
+    def __init__(self,
+                 default_lib_dirs=default_lib_dirs,
+                 default_include_dirs=default_include_dirs,
+                 verbosity=1,
+                 ):
+        self.__class__.info = {}
+        self.local_prefixes = []
+        defaults = {'library_dirs': '',
+                    'include_dirs': '',
+                    'runtime_library_dirs': '',
+                    'rpath': '',
+                    'src_dirs': '',
+                    'search_static_first': "0",
+                    'extra_compile_args': '',
+                    'extra_link_args': ''}
+        self.cp = ConfigParser(defaults)
+        # We have to parse the config files afterwards
+        # to have a consistent temporary filepath
+
+    def _check_libs(self, lib_dirs, libs, opt_libs, exts):
+        """Override _check_libs to return with all dirs """
+        info = {'libraries': libs, 'library_dirs': lib_dirs}
+        return info
+
+
+class TestTemp1(test_system_info):
+    section = 'temp1'
+
+
+class TestTemp2(test_system_info):
+    section = 'temp2'
+
+
+class TestSystemInfoReading(TestCase):
+
+    def setUp(self):
+        """ Create the libraries """
+        # Create 2 sources and 2 libraries
+        self._dir1 = mkdtemp()
+        self._src1 = os.path.join(self._dir1, 'foo.c')
+        self._lib1 = os.path.join(self._dir1, 'libfoo.so')
+        self._dir2 = mkdtemp()
+        self._src2 = os.path.join(self._dir2, 'bar.c')
+        self._lib2 = os.path.join(self._dir2, 'libbar.so')
+        # Update local site.cfg
+        global simple_site, site_cfg
+        site_cfg = simple_site.format(**{
+            'dir1': self._dir1,
+            'lib1': self._lib1,
+            'dir2': self._dir2,
+            'lib2': self._lib2,
+            'pathsep': os.pathsep
+        })
+        # Write site.cfg
+        fd, self._sitecfg = mkstemp()
+        os.close(fd)
+        with open(self._sitecfg, 'w') as fd:
+            fd.write(site_cfg)
+        # Write the sources
+        with open(self._src1, 'w') as fd:
+            fd.write(fakelib_c_text)
+        with open(self._src2, 'w') as fd:
+            fd.write(fakelib_c_text)
+        # We create all class-instances
+
+        def site_and_parse(c, site_cfg):
+            c.files = [site_cfg]
+            c.parse_config_files()
+            return c
+        self.c_default = site_and_parse(get_class('default'), self._sitecfg)
+        self.c_temp1 = site_and_parse(get_class('temp1'), self._sitecfg)
+        self.c_temp2 = site_and_parse(get_class('temp2'), self._sitecfg)
+
+    def tearDown(self):
+        # Do each removal separately
+        try:
+            shutil.rmtree(self._dir1)
+        except:
+            pass
+        try:
+            shutil.rmtree(self._dir2)
+        except:
+            pass
+        try:
+            os.remove(self._sitecfg)
+        except:
+            pass
+
+    def test_all(self):
+        # Read in all information in the ALL block
+        tsi = self.c_default
+        assert_equal(tsi.get_lib_dirs(), [self._dir1, self._dir2])
+        assert_equal(tsi.get_libraries(), [self._lib1, self._lib2])
+        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
+        extra = tsi.calc_extra_info()
+        assert_equal(extra['extra_compile_args'], ['-I/fake/directory'])
+
+    def test_temp1(self):
+        # Read in all information in the temp1 block
+        tsi = self.c_temp1
+        assert_equal(tsi.get_lib_dirs(), [self._dir1])
+        assert_equal(tsi.get_libraries(), [self._lib1])
+        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
+
+    def test_temp2(self):
+        # Read in all information in the temp2 block
+        tsi = self.c_temp2
+        assert_equal(tsi.get_lib_dirs(), [self._dir2])
+        assert_equal(tsi.get_libraries(), [self._lib2])
+        # Now from rpath and not runtime_library_dirs
+        assert_equal(tsi.get_runtime_lib_dirs(key='rpath'), [self._dir2])
+        extra = tsi.calc_extra_info()
+        assert_equal(extra['extra_link_args'], ['-Wl,-rpath=' + self._lib2])
+
+    def test_compile1(self):
+        # Compile source and link the first source
+        c = ccompiler.new_compiler()
+        try:
+            # Change directory to not screw up directories
+            previousDir = os.getcwd()
+            os.chdir(self._dir1)
+            c.compile([os.path.basename(self._src1)], output_dir=self._dir1)
+            # Ensure that the object exists
+            assert_(os.path.isfile(self._src1.replace('.c', '.o')) or
+                    os.path.isfile(self._src1.replace('.c', '.obj')))
+            os.chdir(previousDir)
+        except OSError:
+            pass
+
+    @skipif('msvc' in repr(ccompiler.new_compiler()))
+    def test_compile2(self):
+        # Compile source and link the second source
+        tsi = self.c_temp2
+        c = ccompiler.new_compiler()
+        extra_link_args = tsi.calc_extra_info()['extra_link_args']
+        try:
+            # Change directory to not screw up directories
+            previousDir = os.getcwd()
+            os.chdir(self._dir2)
+            c.compile([os.path.basename(self._src2)], output_dir=self._dir2,
+                      extra_postargs=extra_link_args)
+            # Ensure that the object exists
+            assert_(os.path.isfile(self._src2.replace('.c', '.o')))
+            os.chdir(previousDir)
+        except OSError:
+            pass
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
new file mode 100644
index 0000000000..a92ccd3e7d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
@@ -0,0 +1,125 @@
+"""
+unixccompiler - can handle very long argument lists for ar.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from distutils.errors import DistutilsExecError, CompileError
+from distutils.unixccompiler import *
+from numpy.distutils.ccompiler import replace_method
+from numpy.distutils.compat import get_exception
+
+if sys.version_info[0] < 3:
+    from . import log
+else:
+    from numpy.distutils import log
+
+# Note that UnixCCompiler._compile appeared in Python 2.3
+def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+    """Compile a single source files with a Unix-style compiler."""
+    # HP ad-hoc fix, see ticket 1383
+    ccomp = self.compiler_so
+    if ccomp[0] == 'aCC':
+        # remove flags that will trigger ANSI-C mode for aCC
+        if '-Ae' in ccomp:
+            ccomp.remove('-Ae')
+        if '-Aa' in ccomp:
+            ccomp.remove('-Aa')
+        # add flags for (almost) sane C++ handling
+        ccomp += ['-AA']
+        self.compiler_so = ccomp
+    # ensure OPT environment variable is read
+    if 'OPT' in os.environ:
+        from distutils.sysconfig import get_config_vars
+        opt = " ".join(os.environ['OPT'].split())
+        gcv_opt = " ".join(get_config_vars('OPT')[0].split())
+        ccomp_s = " ".join(self.compiler_so)
+        if opt not in ccomp_s:
+            ccomp_s = ccomp_s.replace(gcv_opt, opt)
+            self.compiler_so = ccomp_s.split()
+        llink_s = " ".join(self.linker_so)
+        if opt not in llink_s:
+            self.linker_so = llink_s.split() + opt.split()
+
+    display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
+    try:
+        self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+                   extra_postargs, display = display)
+    except DistutilsExecError:
+        msg = str(get_exception())
+        raise CompileError(msg)
+
+replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile)
+
+
+def UnixCCompiler_create_static_lib(self, objects, output_libname,
+                                    output_dir=None, debug=0, target_lang=None):
+    """
+    Build a static library in a separate sub-process.
+
+    Parameters
+    ----------
+    objects : list or tuple of str
+        List of paths to object files used to build the static library.
+    output_libname : str
+        The library name as an absolute or relative (if `output_dir` is used)
+        path.
+    output_dir : str, optional
+        The path to the output directory. Default is None, in which case
+        the ``output_dir`` attribute of the UnixCCompiler instance.
+    debug : bool, optional
+        This parameter is not used.
+    target_lang : str, optional
+        This parameter is not used.
+
+    Returns
+    -------
+    None
+
+    """
+    objects, output_dir = self._fix_object_args(objects, output_dir)
+
+    output_filename = \
+                    self.library_filename(output_libname, output_dir=output_dir)
+
+    if self._need_link(objects, output_filename):
+        try:
+            # previous .a may be screwed up; best to remove it first
+            # and recreate.
+            # Also, ar on OS X doesn't handle updating universal archives
+            os.unlink(output_filename)
+        except (IOError, OSError):
+            pass
+        self.mkpath(os.path.dirname(output_filename))
+        tmp_objects = objects + self.objects
+        while tmp_objects:
+            objects = tmp_objects[:50]
+            tmp_objects = tmp_objects[50:]
+            display = '%s: adding %d object files to %s' % (
+                           os.path.basename(self.archiver[0]),
+                           len(objects), output_filename)
+            self.spawn(self.archiver + [output_filename] + objects,
+                       display = display)
+
+        # Not many Unices required ranlib anymore -- SunOS 4.x is, I
+        # think the only major Unix that does.  Maybe we need some
+        # platform intelligence here to skip ranlib if it's not
+        # needed -- or maybe Python's configure script took care of
+        # it for us, hence the check for leading colon.
+        if self.ranlib:
+            display = '%s:@ %s' % (os.path.basename(self.ranlib[0]),
+                                   output_filename)
+            try:
+                self.spawn(self.ranlib + [output_filename],
+                           display = display)
+            except DistutilsExecError:
+                msg = str(get_exception())
+                raise LibError(msg)
+    else:
+        log.debug("skipping %s (up-to-date)", output_filename)
+    return
+
+replace_method(UnixCCompiler, 'create_static_lib',
+               UnixCCompiler_create_static_lib)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/__init__.py
new file mode 100644
index 0000000000..b6f1fa71c5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/__init__.py
@@ -0,0 +1,28 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+ref_dir = os.path.join(os.path.dirname(__file__))
+
+__all__ = sorted(f[:-3] for f in os.listdir(ref_dir) if f.endswith('.py') and
+           not f.startswith('__'))
+
+for f in __all__:
+    __import__(__name__ + '.' + f)
+
+del f, ref_dir
+
+__doc__ = """\
+Topical documentation
+=====================
+
+The following topics are available:
+%s
+
+You can view them by
+
+>>> help(np.doc.TOPIC)                                      #doctest: +SKIP
+
+""" % '\n- '.join([''] + __all__)
+
+__all__.extend(['__doc__'])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/basics.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/basics.py
new file mode 100644
index 0000000000..745bff15a6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/basics.py
@@ -0,0 +1,185 @@
+"""
+============
+Array basics
+============
+
+Array types and conversions between types
+=========================================
+
+Numpy supports a much greater variety of numerical types than Python does.
+This section shows which are available, and how to modify an array's data-type.
+
+==========  ==========================================================
+Data type   Description
+==========  ==========================================================
+bool_       Boolean (True or False) stored as a byte
+int_        Default integer type (same as C ``long``; normally either
+            ``int64`` or ``int32``)
+intc        Identical to C ``int`` (normally ``int32`` or ``int64``)
+intp        Integer used for indexing (same as C ``ssize_t``; normally
+            either ``int32`` or ``int64``)
+int8        Byte (-128 to 127)
+int16       Integer (-32768 to 32767)
+int32       Integer (-2147483648 to 2147483647)
+int64       Integer (-9223372036854775808 to 9223372036854775807)
+uint8       Unsigned integer (0 to 255)
+uint16      Unsigned integer (0 to 65535)
+uint32      Unsigned integer (0 to 4294967295)
+uint64      Unsigned integer (0 to 18446744073709551615)
+float_      Shorthand for ``float64``.
+float16     Half precision float: sign bit, 5 bits exponent,
+            10 bits mantissa
+float32     Single precision float: sign bit, 8 bits exponent,
+            23 bits mantissa
+float64     Double precision float: sign bit, 11 bits exponent,
+            52 bits mantissa
+complex_    Shorthand for ``complex128``.
+complex64   Complex number, represented by two 32-bit floats (real
+            and imaginary components)
+complex128  Complex number, represented by two 64-bit floats (real
+            and imaginary components)
+==========  ==========================================================
+
+Additionally to ``intc`` the platform dependent C integer types ``short``,
+``long``, ``longlong`` and their unsigned versions are defined.
+
+Numpy numerical types are instances of ``dtype`` (data-type) objects, each
+having unique characteristics.  Once you have imported NumPy using
+
+  ::
+
+    >>> import numpy as np
+
+the dtypes are available as ``np.bool_``, ``np.float32``, etc.
+
+Advanced types, not listed in the table above, are explored in
+section :ref:`structured_arrays`.
+
+There are 5 basic numerical types representing booleans (bool), integers (int),
+unsigned integers (uint) floating point (float) and complex. Those with numbers
+in their name indicate the bitsize of the type (i.e. how many bits are needed
+to represent a single value in memory).  Some types, such as ``int`` and
+``intp``, have differing bitsizes, dependent on the platforms (e.g. 32-bit
+vs. 64-bit machines).  This should be taken into account when interfacing
+with low-level code (such as C or Fortran) where the raw memory is addressed.
+
+Data-types can be used as functions to convert python numbers to array scalars
+(see the array scalar section for an explanation), python sequences of numbers
+to arrays of that type, or as arguments to the dtype keyword that many numpy
+functions or methods accept. Some examples::
+
+    >>> import numpy as np
+    >>> x = np.float32(1.0)
+    >>> x
+    1.0
+    >>> y = np.int_([1,2,4])
+    >>> y
+    array([1, 2, 4])
+    >>> z = np.arange(3, dtype=np.uint8)
+    >>> z
+    array([0, 1, 2], dtype=uint8)
+
+Array types can also be referred to by character codes, mostly to retain
+backward compatibility with older packages such as Numeric.  Some
+documentation may still refer to these, for example::
+
+  >>> np.array([1, 2, 3], dtype='f')
+  array([ 1.,  2.,  3.], dtype=float32)
+
+We recommend using dtype objects instead.
+
+To convert the type of an array, use the .astype() method (preferred) or
+the type itself as a function. For example: ::
+
+    >>> z.astype(float)                 #doctest: +NORMALIZE_WHITESPACE
+    array([  0.,  1.,  2.])
+    >>> np.int8(z)
+    array([0, 1, 2], dtype=int8)
+
+Note that, above, we use the *Python* float object as a dtype.  NumPy knows
+that ``int`` refers to ``np.int_``, ``bool`` means ``np.bool_``,
+that ``float`` is ``np.float_`` and ``complex`` is ``np.complex_``.
+The other data-types do not have Python equivalents.
+
+To determine the type of an array, look at the dtype attribute::
+
+    >>> z.dtype
+    dtype('uint8')
+
+dtype objects also contain information about the type, such as its bit-width
+and its byte-order.  The data type can also be used indirectly to query
+properties of the type, such as whether it is an integer::
+
+    >>> d = np.dtype(int)
+    >>> d
+    dtype('int32')
+
+    >>> np.issubdtype(d, int)
+    True
+
+    >>> np.issubdtype(d, float)
+    False
+
+
+Array Scalars
+=============
+
+Numpy generally returns elements of arrays as array scalars (a scalar
+with an associated dtype).  Array scalars differ from Python scalars, but
+for the most part they can be used interchangeably (the primary
+exception is for versions of Python older than v2.x, where integer array
+scalars cannot act as indices for lists and tuples).  There are some
+exceptions, such as when code requires very specific attributes of a scalar
+or when it checks specifically whether a value is a Python scalar. Generally,
+problems are easily fixed by explicitly converting array scalars
+to Python scalars, using the corresponding Python type function
+(e.g., ``int``, ``float``, ``complex``, ``str``, ``unicode``).
+
+The primary advantage of using array scalars is that
+they preserve the array type (Python may not have a matching scalar type
+available, e.g. ``int16``).  Therefore, the use of array scalars ensures
+identical behaviour between arrays and scalars, irrespective of whether the
+value is inside an array or not.  NumPy scalars also have many of the same
+methods arrays do.
+
+Extended Precision
+==================
+
+Python's floating-point numbers are usually 64-bit floating-point numbers,
+nearly equivalent to ``np.float64``. In some unusual situations it may be
+useful to use floating-point numbers with more precision. Whether this
+is possible in numpy depends on the hardware and on the development
+environment: specifically, x86 machines provide hardware floating-point
+with 80-bit precision, and while most C compilers provide this as their
+``long double`` type, MSVC (standard for Windows builds) makes
+``long double`` identical to ``double`` (64 bits). Numpy makes the
+compiler's ``long double`` available as ``np.longdouble`` (and
+``np.clongdouble`` for the complex numbers). You can find out what your
+numpy provides with``np.finfo(np.longdouble)``.
+
+Numpy does not provide a dtype with more precision than C
+``long double``s; in particular, the 128-bit IEEE quad precision
+data type (FORTRAN's ``REAL*16``) is not available.
+
+For efficient memory alignment, ``np.longdouble`` is usually stored
+padded with zero bits, either to 96 or 128 bits. Which is more efficient
+depends on hardware and development environment; typically on 32-bit
+systems they are padded to 96 bits, while on 64-bit systems they are
+typically padded to 128 bits. ``np.longdouble`` is padded to the system
+default; ``np.float96`` and ``np.float128`` are provided for users who
+want specific padding. In spite of the names, ``np.float96`` and
+``np.float128`` provide only as much precision as ``np.longdouble``,
+that is, 80 bits on most x86 machines and 64 bits in standard
+Windows builds.
+
+Be warned that even if ``np.longdouble`` offers more precision than
+python ``float``, it is easy to lose that extra precision, since
+python often forces values to pass through ``float``. For example,
+the ``%`` formatting operator requires its arguments to be converted
+to standard python types, and it is therefore impossible to preserve
+extended precision even if many decimal places are requested. It can
+be useful to test your code with the value
+``1 + np.finfo(np.longdouble).eps``.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.py
new file mode 100644
index 0000000000..717914cda2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.py
@@ -0,0 +1,178 @@
+"""
+========================
+Broadcasting over arrays
+========================
+
+The term broadcasting describes how numpy treats arrays with different
+shapes during arithmetic operations. Subject to certain constraints,
+the smaller array is "broadcast" across the larger array so that they
+have compatible shapes. Broadcasting provides a means of vectorizing
+array operations so that looping occurs in C instead of Python. It does
+this without making needless copies of data and usually leads to
+efficient algorithm implementations. There are, however, cases where
+broadcasting is a bad idea because it leads to inefficient use of memory
+that slows computation.
+
+NumPy operations are usually done on pairs of arrays on an
+element-by-element basis.  In the simplest case, the two arrays must
+have exactly the same shape, as in the following example:
+
+  >>> a = np.array([1.0, 2.0, 3.0])
+  >>> b = np.array([2.0, 2.0, 2.0])
+  >>> a * b
+  array([ 2.,  4.,  6.])
+
+NumPy's broadcasting rule relaxes this constraint when the arrays'
+shapes meet certain constraints. The simplest broadcasting example occurs
+when an array and a scalar value are combined in an operation:
+
+>>> a = np.array([1.0, 2.0, 3.0])
+>>> b = 2.0
+>>> a * b
+array([ 2.,  4.,  6.])
+
+The result is equivalent to the previous example where ``b`` was an array.
+We can think of the scalar ``b`` being *stretched* during the arithmetic
+operation into an array with the same shape as ``a``. The new elements in
+``b`` are simply copies of the original scalar. The stretching analogy is
+only conceptual.  NumPy is smart enough to use the original scalar value
+without actually making copies, so that broadcasting operations are as
+memory and computationally efficient as possible.
+
+The code in the second example is more efficient than that in the first
+because broadcasting moves less memory around during the multiplication
+(``b`` is a scalar rather than an array).
+
+General Broadcasting Rules
+==========================
+When operating on two arrays, NumPy compares their shapes element-wise.
+It starts with the trailing dimensions, and works its way forward.  Two
+dimensions are compatible when
+
+1) they are equal, or
+2) one of them is 1
+
+If these conditions are not met, a
+``ValueError: frames are not aligned`` exception is thrown, indicating that
+the arrays have incompatible shapes. The size of the resulting array
+is the maximum size along each dimension of the input arrays.
+
+Arrays do not need to have the same *number* of dimensions.  For example,
+if you have a ``256x256x3`` array of RGB values, and you want to scale
+each color in the image by a different value, you can multiply the image
+by a one-dimensional array with 3 values. Lining up the sizes of the
+trailing axes of these arrays according to the broadcast rules, shows that
+they are compatible::
+
+  Image  (3d array): 256 x 256 x 3
+  Scale  (1d array):             3
+  Result (3d array): 256 x 256 x 3
+
+When either of the dimensions compared is one, the other is
+used.  In other words, dimensions with size 1 are stretched or "copied"
+to match the other.
+
+In the following example, both the ``A`` and ``B`` arrays have axes with
+length one that are expanded to a larger size during the broadcast
+operation::
+
+  A      (4d array):  8 x 1 x 6 x 1
+  B      (3d array):      7 x 1 x 5
+  Result (4d array):  8 x 7 x 6 x 5
+
+Here are some more examples::
+
+  A      (2d array):  5 x 4
+  B      (1d array):      1
+  Result (2d array):  5 x 4
+
+  A      (2d array):  5 x 4
+  B      (1d array):      4
+  Result (2d array):  5 x 4
+
+  A      (3d array):  15 x 3 x 5
+  B      (3d array):  15 x 1 x 5
+  Result (3d array):  15 x 3 x 5
+
+  A      (3d array):  15 x 3 x 5
+  B      (2d array):       3 x 5
+  Result (3d array):  15 x 3 x 5
+
+  A      (3d array):  15 x 3 x 5
+  B      (2d array):       3 x 1
+  Result (3d array):  15 x 3 x 5
+
+Here are examples of shapes that do not broadcast::
+
+  A      (1d array):  3
+  B      (1d array):  4 # trailing dimensions do not match
+
+  A      (2d array):      2 x 1
+  B      (3d array):  8 x 4 x 3 # second from last dimensions mismatched
+
+An example of broadcasting in practice::
+
+ >>> x = np.arange(4)
+ >>> xx = x.reshape(4,1)
+ >>> y = np.ones(5)
+ >>> z = np.ones((3,4))
+
+ >>> x.shape
+ (4,)
+
+ >>> y.shape
+ (5,)
+
+ >>> x + y
+ <type 'exceptions.ValueError'>: shape mismatch: objects cannot be broadcast to a single shape
+
+ >>> xx.shape
+ (4, 1)
+
+ >>> y.shape
+ (5,)
+
+ >>> (xx + y).shape
+ (4, 5)
+
+ >>> xx + y
+ array([[ 1.,  1.,  1.,  1.,  1.],
+        [ 2.,  2.,  2.,  2.,  2.],
+        [ 3.,  3.,  3.,  3.,  3.],
+        [ 4.,  4.,  4.,  4.,  4.]])
+
+ >>> x.shape
+ (4,)
+
+ >>> z.shape
+ (3, 4)
+
+ >>> (x + z).shape
+ (3, 4)
+
+ >>> x + z
+ array([[ 1.,  2.,  3.,  4.],
+        [ 1.,  2.,  3.,  4.],
+        [ 1.,  2.,  3.,  4.]])
+
+Broadcasting provides a convenient way of taking the outer product (or
+any other outer operation) of two arrays. The following example shows an
+outer addition operation of two 1-d arrays::
+
+  >>> a = np.array([0.0, 10.0, 20.0, 30.0])
+  >>> b = np.array([1.0, 2.0, 3.0])
+  >>> a[:, np.newaxis] + b
+  array([[  1.,   2.,   3.],
+         [ 11.,  12.,  13.],
+         [ 21.,  22.,  23.],
+         [ 31.,  32.,  33.]])
+
+Here the ``newaxis`` index operator inserts a new axis into ``a``,
+making it a two-dimensional ``4x1`` array.  Combining the ``4x1`` array
+with ``b``, which has shape ``(3,)``, yields a ``4x3`` array.
+
+See `this article <http://wiki.scipy.org/EricsBroadcastingDoc>`_
+for illustrations of broadcasting concepts.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.py
new file mode 100644
index 0000000000..59c0498789
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.py
@@ -0,0 +1,156 @@
+"""
+
+=============================
+ Byteswapping and byte order
+=============================
+
+Introduction to byte ordering and ndarrays
+==========================================
+
+The ``ndarray`` is an object that provide a python array interface to data
+in memory.
+
+It often happens that the memory that you want to view with an array is
+not of the same byte ordering as the computer on which you are running
+Python.
+
+For example, I might be working on a computer with a little-endian CPU -
+such as an Intel Pentium, but I have loaded some data from a file
+written by a computer that is big-endian.  Let's say I have loaded 4
+bytes from a file written by a Sun (big-endian) computer.  I know that
+these 4 bytes represent two 16-bit integers.  On a big-endian machine, a
+two-byte integer is stored with the Most Significant Byte (MSB) first,
+and then the Least Significant Byte (LSB). Thus the bytes are, in memory order:
+
+#. MSB integer 1
+#. LSB integer 1
+#. MSB integer 2
+#. LSB integer 2
+
+Let's say the two integers were in fact 1 and 770.  Because 770 = 256 *
+3 + 2, the 4 bytes in memory would contain respectively: 0, 1, 3, 2.
+The bytes I have loaded from the file would have these contents:
+
+>>> big_end_str = chr(0) + chr(1) + chr(3) + chr(2)
+>>> big_end_str
+'\\x00\\x01\\x03\\x02'
+
+We might want to use an ``ndarray`` to access these integers.  In that
+case, we can create an array around this memory, and tell numpy that
+there are two integers, and that they are 16 bit and big-endian:
+
+>>> import numpy as np
+>>> big_end_arr = np.ndarray(shape=(2,),dtype='>i2', buffer=big_end_str)
+>>> big_end_arr[0]
+1
+>>> big_end_arr[1]
+770
+
+Note the array ``dtype`` above of ``>i2``.  The ``>`` means 'big-endian'
+(``<`` is little-endian) and ``i2`` means 'signed 2-byte integer'.  For
+example, if our data represented a single unsigned 4-byte little-endian
+integer, the dtype string would be ``<u4``.
+
+In fact, why don't we try that?
+
+>>> little_end_u4 = np.ndarray(shape=(1,),dtype='<u4', buffer=big_end_str)
+>>> little_end_u4[0] == 1 * 256**1 + 3 * 256**2 + 2 * 256**3
+True
+
+Returning to our ``big_end_arr`` - in this case our underlying data is
+big-endian (data endianness) and we've set the dtype to match (the dtype
+is also big-endian).  However, sometimes you need to flip these around.
+
+.. warning::
+
+    Scalars currently do not include byte order information, so extracting
+    a scalar from an array will return an integer in native byte order.
+    Hence:
+
+    >>> big_end_arr[0].dtype.byteorder == little_end_u4[0].dtype.byteorder
+    True
+
+Changing byte ordering
+======================
+
+As you can imagine from the introduction, there are two ways you can
+affect the relationship between the byte ordering of the array and the
+underlying memory it is looking at:
+
+* Change the byte-ordering information in the array dtype so that it
+  interprets the undelying data as being in a different byte order.
+  This is the role of ``arr.newbyteorder()``
+* Change the byte-ordering of the underlying data, leaving the dtype
+  interpretation as it was.  This is what ``arr.byteswap()`` does.
+
+The common situations in which you need to change byte ordering are:
+
+#. Your data and dtype endianess don't match, and you want to change
+   the dtype so that it matches the data.
+#. Your data and dtype endianess don't match, and you want to swap the
+   data so that they match the dtype
+#. Your data and dtype endianess match, but you want the data swapped
+   and the dtype to reflect this
+
+Data and dtype endianness don't match, change dtype to match data
+-----------------------------------------------------------------
+
+We make something where they don't match:
+
+>>> wrong_end_dtype_arr = np.ndarray(shape=(2,),dtype='<i2', buffer=big_end_str)
+>>> wrong_end_dtype_arr[0]
+256
+
+The obvious fix for this situation is to change the dtype so it gives
+the correct endianness:
+
+>>> fixed_end_dtype_arr = wrong_end_dtype_arr.newbyteorder()
+>>> fixed_end_dtype_arr[0]
+1
+
+Note the the array has not changed in memory:
+
+>>> fixed_end_dtype_arr.tobytes() == big_end_str
+True
+
+Data and type endianness don't match, change data to match dtype
+----------------------------------------------------------------
+
+You might want to do this if you need the data in memory to be a certain
+ordering.  For example you might be writing the memory out to a file
+that needs a certain byte ordering.
+
+>>> fixed_end_mem_arr = wrong_end_dtype_arr.byteswap()
+>>> fixed_end_mem_arr[0]
+1
+
+Now the array *has* changed in memory:
+
+>>> fixed_end_mem_arr.tobytes() == big_end_str
+False
+
+Data and dtype endianness match, swap data and dtype
+----------------------------------------------------
+
+You may have a correctly specified array dtype, but you need the array
+to have the opposite byte order in memory, and you want the dtype to
+match so the array values make sense.  In this case you just do both of
+the previous operations:
+
+>>> swapped_end_arr = big_end_arr.byteswap().newbyteorder()
+>>> swapped_end_arr[0]
+1
+>>> swapped_end_arr.tobytes() == big_end_str
+False
+
+An easier way of casting the data to a specific dtype and byte ordering
+can be achieved with the ndarray astype method:
+
+>>> swapped_end_arr = big_end_arr.astype('<i2')
+>>> swapped_end_arr[0]
+1
+>>> swapped_end_arr.tobytes() == big_end_str
+False
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/constants.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/constants.py
new file mode 100644
index 0000000000..36f94d3070
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/constants.py
@@ -0,0 +1,393 @@
+"""
+=========
+Constants
+=========
+
+Numpy includes several constants:
+
+%(constant_list)s
+"""
+#
+# Note: the docstring is autogenerated.
+#
+from __future__ import division, absolute_import, print_function
+
+import textwrap, re
+
+# Maintain same format as in numpy.add_newdocs
+constants = []
+def add_newdoc(module, name, doc):
+    constants.append((name, doc))
+
+add_newdoc('numpy', 'Inf',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'Infinity',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'NAN',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    `NaN` and `NAN` are equivalent definitions of `nan`. Please use
+    `nan` instead of `NAN`.
+
+    See Also
+    --------
+    nan
+
+    """)
+
+add_newdoc('numpy', 'NINF',
+    """
+    IEEE 754 floating point representation of negative infinity.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of negative infinity.
+
+    See Also
+    --------
+    isinf : Shows which elements are positive or negative infinity
+
+    isposinf : Shows which elements are positive infinity
+
+    isneginf : Shows which elements are negative infinity
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Also that positive infinity is not equivalent to negative infinity. But
+    infinity is equivalent to positive infinity.
+
+    Examples
+    --------
+    >>> np.NINF
+    -inf
+    >>> np.log(0)
+    -inf
+
+    """)
+
+add_newdoc('numpy', 'NZERO',
+    """
+    IEEE 754 floating point representation of negative zero.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of negative zero.
+
+    See Also
+    --------
+    PZERO : Defines positive zero.
+
+    isinf : Shows which elements are positive or negative infinity.
+
+    isposinf : Shows which elements are positive infinity.
+
+    isneginf : Shows which elements are negative infinity.
+
+    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.
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). Negative zero is considered to be a finite number.
+
+    Examples
+    --------
+    >>> np.NZERO
+    -0.0
+    >>> np.PZERO
+    0.0
+
+    >>> np.isfinite([np.NZERO])
+    array([ True], dtype=bool)
+    >>> np.isnan([np.NZERO])
+    array([False], dtype=bool)
+    >>> np.isinf([np.NZERO])
+    array([False], dtype=bool)
+
+    """)
+
+add_newdoc('numpy', 'NaN',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    `NaN` and `NAN` are equivalent definitions of `nan`. Please use
+    `nan` instead of `NaN`.
+
+    See Also
+    --------
+    nan
+
+    """)
+
+add_newdoc('numpy', 'PINF',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'PZERO',
+    """
+    IEEE 754 floating point representation of positive zero.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of positive zero.
+
+    See Also
+    --------
+    NZERO : Defines negative zero.
+
+    isinf : Shows which elements are positive or negative infinity.
+
+    isposinf : Shows which elements are positive infinity.
+
+    isneginf : Shows which elements are negative infinity.
+
+    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.
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). Positive zero is considered to be a finite number.
+
+    Examples
+    --------
+    >>> np.PZERO
+    0.0
+    >>> np.NZERO
+    -0.0
+
+    >>> np.isfinite([np.PZERO])
+    array([ True], dtype=bool)
+    >>> np.isnan([np.PZERO])
+    array([False], dtype=bool)
+    >>> np.isinf([np.PZERO])
+    array([False], dtype=bool)
+
+    """)
+
+add_newdoc('numpy', 'e',
+    """
+    Euler's constant, base of natural logarithms, Napier's constant.
+
+    ``e = 2.71828182845904523536028747135266249775724709369995...``
+
+    See Also
+    --------
+    exp : Exponential function
+    log : Natural logarithm
+
+    References
+    ----------
+    .. [1] http://en.wikipedia.org/wiki/Napier_constant
+
+    """)
+
+add_newdoc('numpy', 'inf',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of positive infinity.
+
+    See Also
+    --------
+    isinf : Shows which elements are positive or negative infinity
+
+    isposinf : Shows which elements are positive infinity
+
+    isneginf : Shows which elements are negative infinity
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Also that positive infinity is not equivalent to negative infinity. But
+    infinity is equivalent to positive infinity.
+
+    `Inf`, `Infinity`, `PINF` and `infty` are aliases for `inf`.
+
+    Examples
+    --------
+    >>> np.inf
+    inf
+    >>> np.array([1]) / 0.
+    array([ Inf])
+
+    """)
+
+add_newdoc('numpy', 'infty',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'nan',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    Returns
+    -------
+    y : A floating point representation of Not a Number.
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+
+    `NaN` and `NAN` are aliases of `nan`.
+
+    Examples
+    --------
+    >>> np.nan
+    nan
+    >>> np.log(-1)
+    nan
+    >>> np.log([-1, 1, 2])
+    array([        NaN,  0.        ,  0.69314718])
+
+    """)
+
+add_newdoc('numpy', 'newaxis',
+    """
+    A convenient alias for None, useful for indexing arrays.
+
+    See Also
+    --------
+    `numpy.doc.indexing`
+
+    Examples
+    --------
+    >>> newaxis is None
+    True
+    >>> x = np.arange(3)
+    >>> x
+    array([0, 1, 2])
+    >>> x[:, newaxis]
+    array([[0],
+    [1],
+    [2]])
+    >>> x[:, newaxis, newaxis]
+    array([[[0]],
+    [[1]],
+    [[2]]])
+    >>> x[:, newaxis] * x
+    array([[0, 0, 0],
+    [0, 1, 2],
+    [0, 2, 4]])
+
+    Outer product, same as ``outer(x, y)``:
+
+    >>> y = np.arange(3, 6)
+    >>> x[:, newaxis] * y
+    array([[ 0,  0,  0],
+    [ 3,  4,  5],
+    [ 6,  8, 10]])
+
+    ``x[newaxis, :]`` is equivalent to ``x[newaxis]`` and ``x[None]``:
+
+    >>> x[newaxis, :].shape
+    (1, 3)
+    >>> x[newaxis].shape
+    (1, 3)
+    >>> x[None].shape
+    (1, 3)
+    >>> x[:, newaxis].shape
+    (3, 1)
+
+    """)
+
+if __doc__:
+    constants_str = []
+    constants.sort()
+    for name, doc in constants:
+        s = textwrap.dedent(doc).replace("\n", "\n    ")
+
+        # Replace sections by rubrics
+        lines = s.split("\n")
+        new_lines = []
+        for line in lines:
+            m = re.match(r'^(\s+)[-=]+\s*$', line)
+            if m and new_lines:
+                prev = textwrap.dedent(new_lines.pop())
+                new_lines.append('%s.. rubric:: %s' % (m.group(1), prev))
+                new_lines.append('')
+            else:
+                new_lines.append(line)
+        s = "\n".join(new_lines)
+
+        # Done.
+        constants_str.append(""".. const:: %s\n    %s""" % (name, s))
+    constants_str = "\n".join(constants_str)
+
+    __doc__ = __doc__ % dict(constant_list=constants_str)
+    del constants_str, name, doc
+    del line, lines, new_lines, m, s, prev
+
+del constants, add_newdoc
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/creation.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/creation.py
new file mode 100644
index 0000000000..b10d45d481
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/creation.py
@@ -0,0 +1,144 @@
+"""
+==============
+Array Creation
+==============
+
+Introduction
+============
+
+There are 5 general mechanisms for creating arrays:
+
+1) Conversion from other Python structures (e.g., lists, tuples)
+2) Intrinsic numpy array array creation objects (e.g., arange, ones, zeros,
+   etc.)
+3) Reading arrays from disk, either from standard or custom formats
+4) Creating arrays from raw bytes through the use of strings or buffers
+5) Use of special library functions (e.g., random)
+
+This section will not cover means of replicating, joining, or otherwise
+expanding or mutating existing arrays. Nor will it cover creating object
+arrays or structured arrays. Both of those are covered in their own sections.
+
+Converting Python array_like Objects to Numpy Arrays
+====================================================
+
+In general, numerical data arranged in an array-like structure in Python can
+be converted to arrays through the use of the array() function. The most
+obvious examples are lists and tuples. See the documentation for array() for
+details for its use. Some objects may support the array-protocol and allow
+conversion to arrays this way. A simple way to find out if the object can be
+converted to a numpy array using array() is simply to try it interactively and
+see if it works! (The Python Way).
+
+Examples: ::
+
+ >>> x = np.array([2,3,1,0])
+ >>> x = np.array([2, 3, 1, 0])
+ >>> x = np.array([[1,2.0],[0,0],(1+1j,3.)]) # note mix of tuple and lists,
+     and types
+ >>> x = np.array([[ 1.+0.j, 2.+0.j], [ 0.+0.j, 0.+0.j], [ 1.+1.j, 3.+0.j]])
+
+Intrinsic Numpy Array Creation
+==============================
+
+Numpy has built-in functions for creating arrays from scratch:
+
+zeros(shape) will create an array filled with 0 values with the specified
+shape. The default dtype is float64.
+
+``>>> np.zeros((2, 3))
+array([[ 0., 0., 0.], [ 0., 0., 0.]])``
+
+ones(shape) will create an array filled with 1 values. It is identical to
+zeros in all other respects.
+
+arange() will create arrays with regularly incrementing values. Check the
+docstring for complete information on the various ways it can be used. A few
+examples will be given here: ::
+
+ >>> np.arange(10)
+ array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+ >>> np.arange(2, 10, dtype=np.float)
+ array([ 2., 3., 4., 5., 6., 7., 8., 9.])
+ >>> np.arange(2, 3, 0.1)
+ array([ 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9])
+
+Note that there are some subtleties regarding the last usage that the user
+should be aware of that are described in the arange docstring.
+
+linspace() will create arrays with a specified number of elements, and
+spaced equally between the specified beginning and end values. For
+example: ::
+
+ >>> np.linspace(1., 4., 6)
+ array([ 1. ,  1.6,  2.2,  2.8,  3.4,  4. ])
+
+The advantage of this creation function is that one can guarantee the
+number of elements and the starting and end point, which arange()
+generally will not do for arbitrary start, stop, and step values.
+
+indices() will create a set of arrays (stacked as a one-higher dimensioned
+array), one per dimension with each representing variation in that dimension.
+An example illustrates much better than a verbal description: ::
+
+ >>> np.indices((3,3))
+ array([[[0, 0, 0], [1, 1, 1], [2, 2, 2]], [[0, 1, 2], [0, 1, 2], [0, 1, 2]]])
+
+This is particularly useful for evaluating functions of multiple dimensions on
+a regular grid.
+
+Reading Arrays From Disk
+========================
+
+This is presumably the most common case of large array creation. The details,
+of course, depend greatly on the format of data on disk and so this section
+can only give general pointers on how to handle various formats.
+
+Standard Binary Formats
+-----------------------
+
+Various fields have standard formats for array data. The following lists the
+ones with known python libraries to read them and return numpy arrays (there
+may be others for which it is possible to read and convert to numpy arrays so
+check the last section as well)
+::
+
+ HDF5: PyTables
+ FITS: PyFITS
+
+Examples of formats that cannot be read directly but for which it is not hard to
+convert are those formats supported by libraries like PIL (able to read and
+write many image formats such as jpg, png, etc).
+
+Common ASCII Formats
+------------------------
+
+Comma Separated Value files (CSV) are widely used (and an export and import
+option for programs like Excel). There are a number of ways of reading these
+files in Python. There are CSV functions in Python and functions in pylab
+(part of matplotlib).
+
+More generic ascii files can be read using the io package in scipy.
+
+Custom Binary Formats
+---------------------
+
+There are a variety of approaches one can use. If the file has a relatively
+simple format then one can write a simple I/O library and use the numpy
+fromfile() function and .tofile() method to read and write numpy arrays
+directly (mind your byteorder though!) If a good C or C++ library exists that
+read the data, one can wrap that library with a variety of techniques though
+that certainly is much more work and requires significantly more advanced
+knowledge to interface with C or C++.
+
+Use of Special Libraries
+------------------------
+
+There are libraries that can be used to generate arrays for special purposes
+and it isn't possible to enumerate all of them. The most common uses are use
+of the many array generation functions in random that can generate arrays of
+random values, and some utility functions to generate special matrices (e.g.
+diagonal).
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/glossary.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/glossary.py
new file mode 100644
index 0000000000..4a32384913
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/glossary.py
@@ -0,0 +1,423 @@
+"""
+========
+Glossary
+========
+
+.. glossary::
+
+   along an axis
+       Axes are defined for arrays with more than one dimension.  A
+       2-dimensional array has two corresponding axes: the first running
+       vertically downwards across rows (axis 0), and the second running
+       horizontally across columns (axis 1).
+
+       Many operation can take place along one of these axes.  For example,
+       we can sum each row of an array, in which case we operate along
+       columns, or axis 1::
+
+         >>> x = np.arange(12).reshape((3,4))
+
+         >>> x
+         array([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+
+         >>> x.sum(axis=1)
+         array([ 6, 22, 38])
+
+   array
+       A homogeneous container of numerical elements.  Each element in the
+       array occupies a fixed amount of memory (hence homogeneous), and
+       can be a numerical element of a single type (such as float, int
+       or complex) or a combination (such as ``(float, int, float)``).  Each
+       array has an associated data-type (or ``dtype``), which describes
+       the numerical type of its elements::
+
+         >>> x = np.array([1, 2, 3], float)
+
+         >>> x
+         array([ 1.,  2.,  3.])
+
+         >>> x.dtype # floating point number, 64 bits of memory per element
+         dtype('float64')
+
+
+         # More complicated data type: each array element is a combination of
+         # and integer and a floating point number
+         >>> np.array([(1, 2.0), (3, 4.0)], dtype=[('x', int), ('y', float)])
+         array([(1, 2.0), (3, 4.0)],
+               dtype=[('x', '<i4'), ('y', '<f8')])
+
+       Fast element-wise operations, called `ufuncs`_, operate on arrays.
+
+   array_like
+       Any sequence that can be interpreted as an ndarray.  This includes
+       nested lists, tuples, scalars and existing arrays.
+
+   attribute
+       A property of an object that can be accessed using ``obj.attribute``,
+       e.g., ``shape`` is an attribute of an array::
+
+         >>> x = np.array([1, 2, 3])
+         >>> x.shape
+         (3,)
+
+   BLAS
+       `Basic Linear Algebra Subprograms <http://en.wikipedia.org/wiki/BLAS>`_
+
+   broadcast
+       NumPy can do operations on arrays whose shapes are mismatched::
+
+         >>> x = np.array([1, 2])
+         >>> y = np.array([[3], [4]])
+
+         >>> x
+         array([1, 2])
+
+         >>> y
+         array([[3],
+                [4]])
+
+         >>> x + y
+         array([[4, 5],
+                [5, 6]])
+
+       See `doc.broadcasting`_ for more information.
+
+   C order
+       See `row-major`
+
+   column-major
+       A way to represent items in a N-dimensional array in the 1-dimensional
+       computer memory. In column-major order, the leftmost index "varies the
+       fastest": for example the array::
+
+            [[1, 2, 3],
+             [4, 5, 6]]
+
+       is represented in the column-major order as::
+
+           [1, 4, 2, 5, 3, 6]
+
+       Column-major order is also known as the Fortran order, as the Fortran
+       programming language uses it.
+
+   decorator
+       An operator that transforms a function.  For example, a ``log``
+       decorator may be defined to print debugging information upon
+       function execution::
+
+         >>> def log(f):
+         ...     def new_logging_func(*args, **kwargs):
+         ...         print("Logging call with parameters:", args, kwargs)
+         ...         return f(*args, **kwargs)
+         ...
+         ...     return new_logging_func
+
+       Now, when we define a function, we can "decorate" it using ``log``::
+
+         >>> @log
+         ... def add(a, b):
+         ...     return a + b
+
+       Calling ``add`` then yields:
+
+       >>> add(1, 2)
+       Logging call with parameters: (1, 2) {}
+       3
+
+   dictionary
+       Resembling a language dictionary, which provides a mapping between
+       words and descriptions thereof, a Python dictionary is a mapping
+       between two objects::
+
+         >>> x = {1: 'one', 'two': [1, 2]}
+
+       Here, `x` is a dictionary mapping keys to values, in this case
+       the integer 1 to the string "one", and the string "two" to
+       the list ``[1, 2]``.  The values may be accessed using their
+       corresponding keys::
+
+         >>> x[1]
+         'one'
+
+         >>> x['two']
+         [1, 2]
+
+       Note that dictionaries are not stored in any specific order.  Also,
+       most mutable (see *immutable* below) objects, such as lists, may not
+       be used as keys.
+
+       For more information on dictionaries, read the
+       `Python tutorial <http://docs.python.org/tut>`_.
+
+   Fortran order
+       See `column-major`
+
+   flattened
+       Collapsed to a one-dimensional array. See `ndarray.flatten`_ for details.
+
+   immutable
+       An object that cannot be modified after execution is called
+       immutable.  Two common examples are strings and tuples.
+
+   instance
+       A class definition gives the blueprint for constructing an object::
+
+         >>> class House(object):
+         ...     wall_colour = 'white'
+
+       Yet, we have to *build* a house before it exists::
+
+         >>> h = House() # build a house
+
+       Now, ``h`` is called a ``House`` instance.  An instance is therefore
+       a specific realisation of a class.
+
+   iterable
+       A sequence that allows "walking" (iterating) over items, typically
+       using a loop such as::
+
+         >>> x = [1, 2, 3]
+         >>> [item**2 for item in x]
+         [1, 4, 9]
+
+       It is often used in combintion with ``enumerate``::
+         >>> keys = ['a','b','c']
+         >>> for n, k in enumerate(keys):
+         ...     print("Key %d: %s" % (n, k))
+         ...
+         Key 0: a
+         Key 1: b
+         Key 2: c
+
+   list
+       A Python container that can hold any number of objects or items.
+       The items do not have to be of the same type, and can even be
+       lists themselves::
+
+         >>> x = [2, 2.0, "two", [2, 2.0]]
+
+       The list `x` contains 4 items, each which can be accessed individually::
+
+         >>> x[2] # the string 'two'
+         'two'
+
+         >>> x[3] # a list, containing an integer 2 and a float 2.0
+         [2, 2.0]
+
+       It is also possible to select more than one item at a time,
+       using *slicing*::
+
+         >>> x[0:2] # or, equivalently, x[:2]
+         [2, 2.0]
+
+       In code, arrays are often conveniently expressed as nested lists::
+
+
+         >>> np.array([[1, 2], [3, 4]])
+         array([[1, 2],
+                [3, 4]])
+
+       For more information, read the section on lists in the `Python
+       tutorial <http://docs.python.org/tut>`_.  For a mapping
+       type (key-value), see *dictionary*.
+
+   mask
+       A boolean array, used to select only certain elements for an operation::
+
+         >>> x = np.arange(5)
+         >>> x
+         array([0, 1, 2, 3, 4])
+
+         >>> mask = (x > 2)
+         >>> mask
+         array([False, False, False, True,  True], dtype=bool)
+
+         >>> x[mask] = -1
+         >>> x
+         array([ 0,  1,  2,  -1, -1])
+
+   masked array
+       Array that suppressed values indicated by a mask::
+
+         >>> x = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True])
+         >>> x
+         masked_array(data = [-- 2.0 --],
+                      mask = [ True False  True],
+                fill_value = 1e+20)
+         <BLANKLINE>
+
+         >>> x + [1, 2, 3]
+         masked_array(data = [-- 4.0 --],
+                      mask = [ True False  True],
+                fill_value = 1e+20)
+         <BLANKLINE>
+
+
+       Masked arrays are often used when operating on arrays containing
+       missing or invalid entries.
+
+   matrix
+       A 2-dimensional ndarray that preserves its two-dimensional nature
+       throughout operations.  It has certain special operations, such as ``*``
+       (matrix multiplication) and ``**`` (matrix power), defined::
+
+         >>> x = np.mat([[1, 2], [3, 4]])
+         >>> x
+         matrix([[1, 2],
+                 [3, 4]])
+
+         >>> x**2
+         matrix([[ 7, 10],
+               [15, 22]])
+
+   method
+       A function associated with an object.  For example, each ndarray has a
+       method called ``repeat``::
+
+         >>> x = np.array([1, 2, 3])
+         >>> x.repeat(2)
+         array([1, 1, 2, 2, 3, 3])
+
+   ndarray
+       See *array*.
+
+   record array
+       An `ndarray`_ with `structured data type`_ which has been subclassed as
+       np.recarray and whose dtype is of type np.record, making the
+       fields of its data type to be accessible by attribute.
+
+   reference
+       If ``a`` is a reference to ``b``, then ``(a is b) == True``.  Therefore,
+       ``a`` and ``b`` are different names for the same Python object.
+
+   row-major
+       A way to represent items in a N-dimensional array in the 1-dimensional
+       computer memory. In row-major order, the rightmost index "varies
+       the fastest": for example the array::
+
+            [[1, 2, 3],
+             [4, 5, 6]]
+
+       is represented in the row-major order as::
+
+           [1, 2, 3, 4, 5, 6]
+
+       Row-major order is also known as the C order, as the C programming
+       language uses it. New Numpy arrays are by default in row-major order.
+
+   self
+       Often seen in method signatures, ``self`` refers to the instance
+       of the associated class.  For example:
+
+         >>> class Paintbrush(object):
+         ...     color = 'blue'
+         ...
+         ...     def paint(self):
+         ...         print("Painting the city %s!" % self.color)
+         ...
+         >>> p = Paintbrush()
+         >>> p.color = 'red'
+         >>> p.paint() # self refers to 'p'
+         Painting the city red!
+
+   slice
+       Used to select only certain elements from a sequence::
+
+         >>> x = range(5)
+         >>> x
+         [0, 1, 2, 3, 4]
+
+         >>> x[1:3] # slice from 1 to 3 (excluding 3 itself)
+         [1, 2]
+
+         >>> x[1:5:2] # slice from 1 to 5, but skipping every second element
+         [1, 3]
+
+         >>> x[::-1] # slice a sequence in reverse
+         [4, 3, 2, 1, 0]
+
+       Arrays may have more than one dimension, each which can be sliced
+       individually::
+
+         >>> x = np.array([[1, 2], [3, 4]])
+         >>> x
+         array([[1, 2],
+                [3, 4]])
+
+         >>> x[:, 1]
+         array([2, 4])
+   
+   structured data type
+       A data type composed of other datatypes
+   
+   tuple
+       A sequence that may contain a variable number of types of any
+       kind.  A tuple is immutable, i.e., once constructed it cannot be
+       changed.  Similar to a list, it can be indexed and sliced::
+
+         >>> x = (1, 'one', [1, 2])
+         >>> x
+         (1, 'one', [1, 2])
+
+         >>> x[0]
+         1
+
+         >>> x[:2]
+         (1, 'one')
+
+       A useful concept is "tuple unpacking", which allows variables to
+       be assigned to the contents of a tuple::
+
+         >>> x, y = (1, 2)
+         >>> x, y = 1, 2
+
+       This is often used when a function returns multiple values:
+
+         >>> def return_many():
+         ...     return 1, 'alpha', None
+
+         >>> a, b, c = return_many()
+         >>> a, b, c
+         (1, 'alpha', None)
+
+         >>> a
+         1
+         >>> b
+         'alpha'
+
+   ufunc
+       Universal function.  A fast element-wise array operation.  Examples include
+       ``add``, ``sin`` and ``logical_or``.
+
+   view
+       An array that does not own its data, but refers to another array's
+       data instead.  For example, we may create a view that only shows
+       every second element of another array::
+
+         >>> x = np.arange(5)
+         >>> x
+         array([0, 1, 2, 3, 4])
+
+         >>> y = x[::2]
+         >>> y
+         array([0, 2, 4])
+
+         >>> x[0] = 3 # changing x changes y as well, since y is a view on x
+         >>> y
+         array([3, 2, 4])
+
+   wrapper
+       Python is a high-level (highly abstracted, or English-like) language.
+       This abstraction comes at a price in execution speed, and sometimes
+       it becomes necessary to use lower level languages to do fast
+       computations.  A wrapper is code that provides a bridge between
+       high and the low level languages, allowing, e.g., Python to execute
+       code written in C or Fortran.
+
+       Examples include ctypes, SWIG and Cython (which wraps C and C++)
+       and f2py (which wraps Fortran).
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/indexing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/indexing.py
new file mode 100644
index 0000000000..9e9f0a10cd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/indexing.py
@@ -0,0 +1,439 @@
+"""==============
+Array indexing
+==============
+
+Array indexing refers to any use of the square brackets ([]) to index
+array values. There are many options to indexing, which give numpy
+indexing great power, but with power comes some complexity and the
+potential for confusion. This section is just an overview of the
+various options and issues related to indexing. Aside from single
+element indexing, the details on most of these options are to be
+found in related sections.
+
+Assignment vs referencing
+=========================
+
+Most of the following examples show the use of indexing when
+referencing data in an array. The examples work just as well
+when assigning to an array. See the section at the end for
+specific examples and explanations on how assignments work.
+
+Single element indexing
+=======================
+
+Single element indexing for a 1-D array is what one expects. It work
+exactly like that for other standard Python sequences. It is 0-based,
+and accepts negative indices for indexing from the end of the array. ::
+
+    >>> x = np.arange(10)
+    >>> x[2]
+    2
+    >>> x[-2]
+    8
+
+Unlike lists and tuples, numpy arrays support multidimensional indexing
+for multidimensional arrays. That means that it is not necessary to
+separate each dimension's index into its own set of square brackets. ::
+
+    >>> x.shape = (2,5) # now x is 2-dimensional
+    >>> x[1,3]
+    8
+    >>> x[1,-1]
+    9
+
+Note that if one indexes a multidimensional array with fewer indices
+than dimensions, one gets a subdimensional array. For example: ::
+
+    >>> x[0]
+    array([0, 1, 2, 3, 4])
+
+That is, each index specified selects the array corresponding to the
+rest of the dimensions selected. In the above example, choosing 0
+means that the remaining dimension of length 5 is being left unspecified,
+and that what is returned is an array of that dimensionality and size.
+It must be noted that the returned array is not a copy of the original,
+but points to the same values in memory as does the original array.
+In  this case, the 1-D array at the first position (0) is returned.
+So using a single index on the returned array, results in a single
+element being returned. That is: ::
+
+    >>> x[0][2]
+    2
+
+So note that ``x[0,2] = x[0][2]`` though the second case is more
+inefficient as a new temporary array is created after the first index
+that is subsequently indexed by 2.
+
+Note to those used to IDL or Fortran memory order as it relates to
+indexing.  Numpy uses C-order indexing. That means that the last
+index usually represents the most rapidly changing memory location,
+unlike Fortran or IDL, where the first index represents the most
+rapidly changing location in memory. This difference represents a
+great potential for confusion.
+
+Other indexing options
+======================
+
+It is possible to slice and stride arrays to extract arrays of the
+same number of dimensions, but of different sizes than the original.
+The slicing and striding works exactly the same way it does for lists
+and tuples except that they can be applied to multiple dimensions as
+well. A few examples illustrates best: ::
+
+ >>> x = np.arange(10)
+ >>> x[2:5]
+ array([2, 3, 4])
+ >>> x[:-7]
+ array([0, 1, 2])
+ >>> x[1:7:2]
+ array([1, 3, 5])
+ >>> y = np.arange(35).reshape(5,7)
+ >>> y[1:5:2,::3]
+ array([[ 7, 10, 13],
+        [21, 24, 27]])
+
+Note that slices of arrays do not copy the internal array data but
+also produce new views of the original data.
+
+It is possible to index arrays with other arrays for the purposes of
+selecting lists of values out of arrays into new arrays. There are
+two different ways of accomplishing this. One uses one or more arrays
+of index values. The other involves giving a boolean array of the proper
+shape to indicate the values to be selected. Index arrays are a very
+powerful tool that allow one to avoid looping over individual elements in
+arrays and thus greatly improve performance.
+
+It is possible to use special features to effectively increase the
+number of dimensions in an array through indexing so the resulting
+array aquires the shape needed for use in an expression or with a
+specific function.
+
+Index arrays
+============
+
+Numpy arrays may be indexed with other arrays (or any other sequence-
+like object that can be converted to an array, such as lists, with the
+exception of tuples; see the end of this document for why this is). The
+use of index arrays ranges from simple, straightforward cases to
+complex, hard-to-understand cases. For all cases of index arrays, what
+is returned is a copy of the original data, not a view as one gets for
+slices.
+
+Index arrays must be of integer type. Each value in the array indicates
+which value in the array to use in place of the index. To illustrate: ::
+
+ >>> x = np.arange(10,1,-1)
+ >>> x
+ array([10,  9,  8,  7,  6,  5,  4,  3,  2])
+ >>> x[np.array([3, 3, 1, 8])]
+ array([7, 7, 9, 2])
+
+
+The index array consisting of the values 3, 3, 1 and 8 correspondingly
+create an array of length 4 (same as the index array) where each index
+is replaced by the value the index array has in the array being indexed.
+
+Negative values are permitted and work as they do with single indices
+or slices: ::
+
+ >>> x[np.array([3,3,-3,8])]
+ array([7, 7, 4, 2])
+
+It is an error to have index values out of bounds: ::
+
+ >>> x[np.array([3, 3, 20, 8])]
+ <type 'exceptions.IndexError'>: index 20 out of bounds 0<=index<9
+
+Generally speaking, what is returned when index arrays are used is
+an array with the same shape as the index array, but with the type
+and values of the array being indexed. As an example, we can use a
+multidimensional index array instead: ::
+
+ >>> x[np.array([[1,1],[2,3]])]
+ array([[9, 9],
+        [8, 7]])
+
+Indexing Multi-dimensional arrays
+=================================
+
+Things become more complex when multidimensional arrays are indexed,
+particularly with multidimensional index arrays. These tend to be
+more unusal uses, but theyare permitted, and they are useful for some
+problems. We'll  start with thesimplest multidimensional case (using
+the array y from the previous examples): ::
+
+ >>> y[np.array([0,2,4]), np.array([0,1,2])]
+ array([ 0, 15, 30])
+
+In this case, if the index arrays have a matching shape, and there is
+an index array for each dimension of the array being indexed, the
+resultant array has the same shape as the index arrays, and the values
+correspond to the index set for each position in the index arrays. In
+this example, the first index value is 0 for both index arrays, and
+thus the first value of the resultant array is y[0,0]. The next value
+is y[2,1], and the last is y[4,2].
+
+If the index arrays do not have the same shape, there is an attempt to
+broadcast them to the same shape.  If they cannot be broadcast to the
+same shape, an exception is raised: ::
+
+ >>> y[np.array([0,2,4]), np.array([0,1])]
+ <type 'exceptions.ValueError'>: shape mismatch: objects cannot be
+ broadcast to a single shape
+
+The broadcasting mechanism permits index arrays to be combined with
+scalars for other indices. The effect is that the scalar value is used
+for all the corresponding values of the index arrays: ::
+
+ >>> y[np.array([0,2,4]), 1]
+ array([ 1, 15, 29])
+
+Jumping to the next level of complexity, it is possible to only
+partially index an array with index arrays. It takes a bit of thought
+to understand what happens in such cases. For example if we just use
+one index array with y: ::
+
+ >>> y[np.array([0,2,4])]
+ array([[ 0,  1,  2,  3,  4,  5,  6],
+        [14, 15, 16, 17, 18, 19, 20],
+        [28, 29, 30, 31, 32, 33, 34]])
+
+What results is the construction of a new array where each value of
+the index array selects one row from the array being indexed and the
+resultant array has the resulting shape (size of row, number index
+elements).
+
+An example of where this may be useful is for a color lookup table
+where we want to map the values of an image into RGB triples for
+display. The lookup table could have a shape (nlookup, 3). Indexing
+such an array with an image with shape (ny, nx) with dtype=np.uint8
+(or any integer type so long as values are with the bounds of the
+lookup table) will result in an array of shape (ny, nx, 3) where a
+triple of RGB values is associated with each pixel location.
+
+In general, the shape of the resulant array will be the concatenation
+of the shape of the index array (or the shape that all the index arrays
+were broadcast to) with the shape of any unused dimensions (those not
+indexed) in the array being indexed.
+
+Boolean or "mask" index arrays
+==============================
+
+Boolean arrays used as indices are treated in a different manner
+entirely than index arrays. Boolean arrays must be of the same shape
+as the initial dimensions of the array being indexed. In the
+most straightforward case, the boolean array has the same shape: ::
+
+ >>> b = y>20
+ >>> y[b]
+ array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])
+
+Unlike in the case of integer index arrays, in the boolean case, the
+result is a 1-D array containing all the elements in the indexed array
+corresponding to all the true elements in the boolean array. The
+elements in the indexed array are always iterated and returned in
+:term:`row-major` (C-style) order. The result is also identical to
+``y[np.nonzero(b)]``. As with index arrays, what is returned is a copy
+of the data, not a view as one gets with slices.
+
+The result will be multidimensional if y has more dimensions than b.
+For example: ::
+
+ >>> b[:,5] # use a 1-D boolean whose first dim agrees with the first dim of y
+ array([False, False, False,  True,  True], dtype=bool)
+ >>> y[b[:,5]]
+ array([[21, 22, 23, 24, 25, 26, 27],
+        [28, 29, 30, 31, 32, 33, 34]])
+
+Here the 4th and 5th rows are selected from the indexed array and
+combined to make a 2-D array.
+
+In general, when the boolean array has fewer dimensions than the array
+being indexed, this is equivalent to y[b, ...], which means
+y is indexed by b followed by as many : as are needed to fill
+out the rank of y.
+Thus the shape of the result is one dimension containing the number
+of True elements of the boolean array, followed by the remaining
+dimensions of the array being indexed.
+
+For example, using a 2-D boolean array of shape (2,3)
+with four True elements to select rows from a 3-D array of shape
+(2,3,5) results in a 2-D result of shape (4,5): ::
+
+ >>> x = np.arange(30).reshape(2,3,5)
+ >>> x
+ array([[[ 0,  1,  2,  3,  4],
+         [ 5,  6,  7,  8,  9],
+         [10, 11, 12, 13, 14]],
+        [[15, 16, 17, 18, 19],
+         [20, 21, 22, 23, 24],
+         [25, 26, 27, 28, 29]]])
+ >>> b = np.array([[True, True, False], [False, True, True]])
+ >>> x[b]
+ array([[ 0,  1,  2,  3,  4],
+        [ 5,  6,  7,  8,  9],
+        [20, 21, 22, 23, 24],
+        [25, 26, 27, 28, 29]])
+
+For further details, consult the numpy reference documentation on array indexing.
+
+Combining index arrays with slices
+==================================
+
+Index arrays may be combined with slices. For example: ::
+
+ >>> y[np.array([0,2,4]),1:3]
+ array([[ 1,  2],
+        [15, 16],
+        [29, 30]])
+
+In effect, the slice is converted to an index array
+np.array([[1,2]]) (shape (1,2)) that is broadcast with the index array
+to produce a resultant array of shape (3,2).
+
+Likewise, slicing can be combined with broadcasted boolean indices: ::
+
+ >>> y[b[:,5],1:3]
+ array([[22, 23],
+        [29, 30]])
+
+Structural indexing tools
+=========================
+
+To facilitate easy matching of array shapes with expressions and in
+assignments, the np.newaxis object can be used within array indices
+to add new dimensions with a size of 1. For example: ::
+
+ >>> y.shape
+ (5, 7)
+ >>> y[:,np.newaxis,:].shape
+ (5, 1, 7)
+
+Note that there are no new elements in the array, just that the
+dimensionality is increased. This can be handy to combine two
+arrays in a way that otherwise would require explicitly reshaping
+operations. For example: ::
+
+ >>> x = np.arange(5)
+ >>> x[:,np.newaxis] + x[np.newaxis,:]
+ array([[0, 1, 2, 3, 4],
+        [1, 2, 3, 4, 5],
+        [2, 3, 4, 5, 6],
+        [3, 4, 5, 6, 7],
+        [4, 5, 6, 7, 8]])
+
+The ellipsis syntax maybe used to indicate selecting in full any
+remaining unspecified dimensions. For example: ::
+
+ >>> z = np.arange(81).reshape(3,3,3,3)
+ >>> z[1,...,2]
+ array([[29, 32, 35],
+        [38, 41, 44],
+        [47, 50, 53]])
+
+This is equivalent to: ::
+
+ >>> z[1,:,:,2]
+ array([[29, 32, 35],
+        [38, 41, 44],
+        [47, 50, 53]])
+
+Assigning values to indexed arrays
+==================================
+
+As mentioned, one can select a subset of an array to assign to using
+a single index, slices, and index and mask arrays. The value being
+assigned to the indexed array must be shape consistent (the same shape
+or broadcastable to the shape the index produces). For example, it is
+permitted to assign a constant to a slice: ::
+
+ >>> x = np.arange(10)
+ >>> x[2:7] = 1
+
+or an array of the right size: ::
+
+ >>> x[2:7] = np.arange(5)
+
+Note that assignments may result in changes if assigning
+higher types to lower types (like floats to ints) or even
+exceptions (assigning complex to floats or ints): ::
+
+ >>> x[1] = 1.2
+ >>> x[1]
+ 1
+ >>> x[1] = 1.2j
+ <type 'exceptions.TypeError'>: can't convert complex to long; use
+ long(abs(z))
+
+
+Unlike some of the references (such as array and mask indices)
+assignments are always made to the original data in the array
+(indeed, nothing else would make sense!). Note though, that some
+actions may not work as one may naively expect. This particular
+example is often surprising to people: ::
+
+ >>> x = np.arange(0, 50, 10)
+ >>> x
+ array([ 0, 10, 20, 30, 40])
+ >>> x[np.array([1, 1, 3, 1])] += 1
+ >>> x
+ array([ 0, 11, 20, 31, 40])
+
+Where people expect that the 1st location will be incremented by 3.
+In fact, it will only be incremented by 1. The reason is because
+a new array is extracted from the original (as a temporary) containing
+the values at 1, 1, 3, 1, then the value 1 is added to the temporary,
+and then the temporary is assigned back to the original array. Thus
+the value of the array at x[1]+1 is assigned to x[1] three times,
+rather than being incremented 3 times.
+
+Dealing with variable numbers of indices within programs
+========================================================
+
+The index syntax is very powerful but limiting when dealing with
+a variable number of indices. For example, if you want to write
+a function that can handle arguments with various numbers of
+dimensions without having to write special case code for each
+number of possible dimensions, how can that be done? If one
+supplies to the index a tuple, the tuple will be interpreted
+as a list of indices. For example (using the previous definition
+for the array z): ::
+
+ >>> indices = (1,1,1,1)
+ >>> z[indices]
+ 40
+
+So one can use code to construct tuples of any number of indices
+and then use these within an index.
+
+Slices can be specified within programs by using the slice() function
+in Python. For example: ::
+
+ >>> indices = (1,1,1,slice(0,2)) # same as [1,1,1,0:2]
+ >>> z[indices]
+ array([39, 40])
+
+Likewise, ellipsis can be specified by code by using the Ellipsis
+object: ::
+
+ >>> indices = (1, Ellipsis, 1) # same as [1,...,1]
+ >>> z[indices]
+ array([[28, 31, 34],
+        [37, 40, 43],
+        [46, 49, 52]])
+
+For this reason it is possible to use the output from the np.where()
+function directly as an index since it always returns a tuple of index
+arrays.
+
+Because the special treatment of tuples, they are not automatically
+converted to an array as a list would be. As an example: ::
+
+ >>> z[[1,1,1,1]] # produces a large array
+ array([[[[27, 28, 29],
+          [30, 31, 32], ...
+ >>> z[(1,1,1,1)] # returns a single value
+ 40
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/internals.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/internals.py
new file mode 100644
index 0000000000..6bd6b1ae94
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/internals.py
@@ -0,0 +1,163 @@
+"""
+===============
+Array Internals
+===============
+
+Internal organization of numpy arrays
+=====================================
+
+It helps to understand a bit about how numpy arrays are handled under the covers to help understand numpy better. This section will not go into great detail. Those wishing to understand the full details are referred to Travis Oliphant's book "Guide to Numpy".
+
+Numpy arrays consist of two major components, the raw array data (from now on,
+referred to as the data buffer), and the information about the raw array data.
+The data buffer is typically what people think of as arrays in C or Fortran,
+a contiguous (and fixed) block of memory containing fixed sized data items.
+Numpy also contains a significant set of data that describes how to interpret
+the data in the data buffer. This extra information contains (among other things):
+
+ 1) The basic data element's size in bytes
+ 2) The start of the data within the data buffer (an offset relative to the
+    beginning of the data buffer).
+ 3) The number of dimensions and the size of each dimension
+ 4) The separation between elements for each dimension (the 'stride'). This
+    does not have to be a multiple of the element size
+ 5) The byte order of the data (which may not be the native byte order)
+ 6) Whether the buffer is read-only
+ 7) Information (via the dtype object) about the interpretation of the basic
+    data element. The basic data element may be as simple as a int or a float,
+    or it may be a compound object (e.g., struct-like), a fixed character field,
+    or Python object pointers.
+ 8) Whether the array is to interpreted as C-order or Fortran-order.
+
+This arrangement allow for very flexible use of arrays. One thing that it allows
+is simple changes of the metadata to change the interpretation of the array buffer.
+Changing the byteorder of the array is a simple change involving no rearrangement
+of the data. The shape of the array can be changed very easily without changing
+anything in the data buffer or any data copying at all
+
+Among other things that are made possible is one can create a new array metadata
+object that uses the same data buffer
+to create a new view of that data buffer that has a different interpretation
+of the buffer (e.g., different shape, offset, byte order, strides, etc) but
+shares the same data bytes. Many operations in numpy do just this such as
+slices. Other operations, such as transpose, don't move data elements
+around in the array, but rather change the information about the shape and strides so that the indexing of the array changes, but the data in the doesn't move.
+
+Typically these new versions of the array metadata but the same data buffer are
+new 'views' into the data buffer. There is a different ndarray object, but it
+uses the same data buffer. This is why it is necessary to force copies through
+use of the .copy() method if one really wants to make a new and independent
+copy of the data buffer.
+
+New views into arrays mean the the object reference counts for the data buffer
+increase. Simply doing away with the original array object will not remove the
+data buffer if other views of it still exist.
+
+Multidimensional Array Indexing Order Issues
+============================================
+
+What is the right way to index
+multi-dimensional arrays? Before you jump to conclusions about the one and
+true way to index multi-dimensional arrays, it pays to understand why this is
+a confusing issue. This section will try to explain in detail how numpy
+indexing works and why we adopt the convention we do for images, and when it
+may be appropriate to adopt other conventions.
+
+The first thing to understand is
+that there are two conflicting conventions for indexing 2-dimensional arrays.
+Matrix notation uses the first index to indicate which row is being selected and
+the second index to indicate which column is selected. This is opposite the
+geometrically oriented-convention for images where people generally think the
+first index represents x position (i.e., column) and the second represents y
+position (i.e., row). This alone is the source of much confusion;
+matrix-oriented users and image-oriented users expect two different things with
+regard to indexing.
+
+The second issue to understand is how indices correspond
+to the order the array is stored in memory. In Fortran the first index is the
+most rapidly varying index when moving through the elements of a two
+dimensional array as it is stored in memory. If you adopt the matrix
+convention for indexing, then this means the matrix is stored one column at a
+time (since the first index moves to the next row as it changes). Thus Fortran
+is considered a Column-major language. C has just the opposite convention. In
+C, the last index changes most rapidly as one moves through the array as
+stored in memory. Thus C is a Row-major language. The matrix is stored by
+rows. Note that in both cases it presumes that the matrix convention for
+indexing is being used, i.e., for both Fortran and C, the first index is the
+row. Note this convention implies that the indexing convention is invariant
+and that the data order changes to keep that so.
+
+But that's not the only way
+to look at it. Suppose one has large two-dimensional arrays (images or
+matrices) stored in data files. Suppose the data are stored by rows rather than
+by columns. If we are to preserve our index convention (whether matrix or
+image) that means that depending on the language we use, we may be forced to
+reorder the data if it is read into memory to preserve our indexing
+convention. For example if we read row-ordered data into memory without
+reordering, it will match the matrix indexing convention for C, but not for
+Fortran. Conversely, it will match the image indexing convention for Fortran,
+but not for C. For C, if one is using data stored in row order, and one wants
+to preserve the image index convention, the data must be reordered when
+reading into memory.
+
+In the end, which you do for Fortran or C depends on
+which is more important, not reordering data or preserving the indexing
+convention. For large images, reordering data is potentially expensive, and
+often the indexing convention is inverted to avoid that.
+
+The situation with
+numpy makes this issue yet more complicated. The internal machinery of numpy
+arrays is flexible enough to accept any ordering of indices. One can simply
+reorder indices by manipulating the internal stride information for arrays
+without reordering the data at all. Numpy will know how to map the new index
+order to the data without moving the data.
+
+So if this is true, why not choose
+the index order that matches what you most expect? In particular, why not define
+row-ordered images to use the image convention? (This is sometimes referred
+to as the Fortran convention vs the C convention, thus the 'C' and 'FORTRAN'
+order options for array ordering in numpy.) The drawback of doing this is
+potential performance penalties. It's common to access the data sequentially,
+either implicitly in array operations or explicitly by looping over rows of an
+image. When that is done, then the data will be accessed in non-optimal order.
+As the first index is incremented, what is actually happening is that elements
+spaced far apart in memory are being sequentially accessed, with usually poor
+memory access speeds. For example, for a two dimensional image 'im' defined so
+that im[0, 10] represents the value at x=0, y=10. To be consistent with usual
+Python behavior then im[0] would represent a column at x=0. Yet that data
+would be spread over the whole array since the data are stored in row order.
+Despite the flexibility of numpy's indexing, it can't really paper over the fact
+basic operations are rendered inefficient because of data order or that getting
+contiguous subarrays is still awkward (e.g., im[:,0] for the first row, vs
+im[0]), thus one can't use an idiom such as for row in im; for col in im does
+work, but doesn't yield contiguous column data.
+
+As it turns out, numpy is
+smart enough when dealing with ufuncs to determine which index is the most
+rapidly varying one in memory and uses that for the innermost loop. Thus for
+ufuncs there is no large intrinsic advantage to either approach in most cases.
+On the other hand, use of .flat with an FORTRAN ordered array will lead to
+non-optimal memory access as adjacent elements in the flattened array (iterator,
+actually) are not contiguous in memory.
+
+Indeed, the fact is that Python
+indexing on lists and other sequences naturally leads to an outside-to inside
+ordering (the first index gets the largest grouping, the next the next largest,
+and the last gets the smallest element). Since image data are normally stored
+by rows, this corresponds to position within rows being the last item indexed.
+
+If you do want to use Fortran ordering realize that
+there are two approaches to consider: 1) accept that the first index is just not
+the most rapidly changing in memory and have all your I/O routines reorder
+your data when going from memory to disk or visa versa, or use numpy's
+mechanism for mapping the first index to the most rapidly varying data. We
+recommend the former if possible. The disadvantage of the latter is that many
+of numpy's functions will yield arrays without Fortran ordering unless you are
+careful to use the 'order' keyword. Doing this would be highly inconvenient.
+
+Otherwise we recommend simply learning to reverse the usual order of indices
+when accessing elements of an array. Granted, it goes against the grain, but
+it is more in line with Python semantics and the natural order of the data.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/misc.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/misc.py
new file mode 100644
index 0000000000..37ebca5724
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/misc.py
@@ -0,0 +1,226 @@
+"""
+=============
+Miscellaneous
+=============
+
+IEEE 754 Floating Point Special Values
+--------------------------------------
+
+Special values defined in numpy: nan, inf,
+
+NaNs can be used as a poor-man's mask (if you don't care what the
+original value was)
+
+Note: cannot use equality to test NaNs. E.g.: ::
+
+ >>> myarr = np.array([1., 0., np.nan, 3.])
+ >>> np.where(myarr == np.nan)
+ >>> np.nan == np.nan  # is always False! Use special numpy functions instead.
+ False
+ >>> myarr[myarr == np.nan] = 0. # doesn't work
+ >>> myarr
+ array([  1.,   0.,  NaN,   3.])
+ >>> myarr[np.isnan(myarr)] = 0. # use this instead find
+ >>> myarr
+ array([ 1.,  0.,  0.,  3.])
+
+Other related special value functions: ::
+
+ isinf():    True if value is inf
+ isfinite(): True if not nan or inf
+ nan_to_num(): Map nan to 0, inf to max float, -inf to min float
+
+The following corresponds to the usual functions except that nans are excluded
+from the results: ::
+
+ nansum()
+ nanmax()
+ nanmin()
+ nanargmax()
+ nanargmin()
+
+ >>> x = np.arange(10.)
+ >>> x[3] = np.nan
+ >>> x.sum()
+ nan
+ >>> np.nansum(x)
+ 42.0
+
+How numpy handles numerical exceptions
+--------------------------------------
+
+The default is to ``'warn'`` for ``invalid``, ``divide``, and ``overflow``
+and ``'ignore'`` for ``underflow``.  But this can be changed, and it can be
+set individually for different kinds of exceptions. The different behaviors
+are:
+
+ - 'ignore' : Take no action when the exception occurs.
+ - 'warn'   : Print a `RuntimeWarning` (via the Python `warnings` module).
+ - 'raise'  : Raise a `FloatingPointError`.
+ - 'call'   : Call a function specified using the `seterrcall` function.
+ - 'print'  : Print a warning directly to ``stdout``.
+ - 'log'    : Record error in a Log object specified by `seterrcall`.
+
+These behaviors can be set for all kinds of errors or specific ones:
+
+ - all       : apply to all numeric exceptions
+ - invalid   : when NaNs are generated
+ - divide    : divide by zero (for integers as well!)
+ - overflow  : floating point overflows
+ - underflow : floating point underflows
+
+Note that integer divide-by-zero is handled by the same machinery.
+These behaviors are set on a per-thread basis.
+
+Examples
+--------
+
+::
+
+ >>> oldsettings = np.seterr(all='warn')
+ >>> np.zeros(5,dtype=np.float32)/0.
+ invalid value encountered in divide
+ >>> j = np.seterr(under='ignore')
+ >>> np.array([1.e-100])**10
+ >>> j = np.seterr(invalid='raise')
+ >>> np.sqrt(np.array([-1.]))
+ FloatingPointError: invalid value encountered in sqrt
+ >>> def errorhandler(errstr, errflag):
+ ...      print("saw stupid error!")
+ >>> np.seterrcall(errorhandler)
+ <function err_handler at 0x...>
+ >>> j = np.seterr(all='call')
+ >>> np.zeros(5, dtype=np.int32)/0
+ FloatingPointError: invalid value encountered in divide
+ saw stupid error!
+ >>> j = np.seterr(**oldsettings) # restore previous
+ ...                              # error-handling settings
+
+Interfacing to C
+----------------
+Only a survey of the choices. Little detail on how each works.
+
+1) Bare metal, wrap your own C-code manually.
+
+ - Plusses:
+
+   - Efficient
+   - No dependencies on other tools
+
+ - Minuses:
+
+   - Lots of learning overhead:
+
+     - need to learn basics of Python C API
+     - need to learn basics of numpy C API
+     - need to learn how to handle reference counting and love it.
+
+   - Reference counting often difficult to get right.
+
+     - getting it wrong leads to memory leaks, and worse, segfaults
+
+   - API will change for Python 3.0!
+
+2) Cython
+
+ - Plusses:
+
+   - avoid learning C API's
+   - no dealing with reference counting
+   - can code in pseudo python and generate C code
+   - can also interface to existing C code
+   - should shield you from changes to Python C api
+   - has become the de-facto standard within the scientific Python community
+   - fast indexing support for arrays
+
+ - Minuses:
+
+   - Can write code in non-standard form which may become obsolete
+   - Not as flexible as manual wrapping
+
+3) ctypes
+
+ - Plusses:
+
+   - part of Python standard library
+   - good for interfacing to existing sharable libraries, particularly
+     Windows DLLs
+   - avoids API/reference counting issues
+   - good numpy support: arrays have all these in their ctypes
+     attribute: ::
+
+       a.ctypes.data              a.ctypes.get_strides
+       a.ctypes.data_as           a.ctypes.shape
+       a.ctypes.get_as_parameter  a.ctypes.shape_as
+       a.ctypes.get_data          a.ctypes.strides
+       a.ctypes.get_shape         a.ctypes.strides_as
+
+ - Minuses:
+
+   - can't use for writing code to be turned into C extensions, only a wrapper
+     tool.
+
+4) SWIG (automatic wrapper generator)
+
+ - Plusses:
+
+   - around a long time
+   - multiple scripting language support
+   - C++ support
+   - Good for wrapping large (many functions) existing C libraries
+
+ - Minuses:
+
+   - generates lots of code between Python and the C code
+   - can cause performance problems that are nearly impossible to optimize
+     out
+   - interface files can be hard to write
+   - doesn't necessarily avoid reference counting issues or needing to know
+     API's
+
+5) scipy.weave
+
+ - Plusses:
+
+   - can turn many numpy expressions into C code
+   - dynamic compiling and loading of generated C code
+   - can embed pure C code in Python module and have weave extract, generate
+     interfaces and compile, etc.
+
+ - Minuses:
+
+   - Future very uncertain: it's the only part of Scipy not ported to Python 3
+     and is effectively deprecated in favor of Cython.
+
+6) Psyco
+
+ - Plusses:
+
+   - Turns pure python into efficient machine code through jit-like
+     optimizations
+   - very fast when it optimizes well
+
+ - Minuses:
+
+   - Only on intel (windows?)
+   - Doesn't do much for numpy?
+
+Interfacing to Fortran:
+-----------------------
+The clear choice to wrap Fortran code is
+`f2py <http://docs.scipy.org/doc/numpy-dev/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
+longer.
+
+Interfacing to C++:
+-------------------
+ 1) Cython
+ 2) CXX
+ 3) Boost.python
+ 4) SWIG
+ 5) SIP (used mainly in PyQT)
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
new file mode 100644
index 0000000000..1135c1395c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
@@ -0,0 +1,290 @@
+"""
+=================
+Structured Arrays
+=================
+
+Introduction
+============
+
+Numpy provides powerful capabilities to create arrays of structured datatype.
+These arrays permit one to manipulate the data by named fields. A simple 
+example will show what is meant.: ::
+
+ >>> x = np.array([(1,2.,'Hello'), (2,3.,"World")],
+ ...              dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
+ >>> x
+ array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
+      dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+
+Here we have created a one-dimensional array of length 2. Each element of
+this array is a structure that contains three items, a 32-bit integer, a 32-bit
+float, and a string of length 10 or less. If we index this array at the second
+position we get the second structure: ::
+
+ >>> x[1]
+ (2,3.,"World")
+
+Conveniently, one can access any field of the array by indexing using the
+string that names that field. ::
+
+ >>> y = x['bar']
+ >>> y
+ array([ 2.,  3.], dtype=float32)
+ >>> y[:] = 2*y
+ >>> y
+ array([ 4.,  6.], dtype=float32)
+ >>> x
+ array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
+       dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+
+In these examples, y is a simple float array consisting of the 2nd field
+in the structured type. But, rather than being a copy of the data in the structured
+array, it is a view, i.e., it shares exactly the same memory locations.
+Thus, when we updated this array by doubling its values, the structured
+array shows the corresponding values as doubled as well. Likewise, if one
+changes the structured array, the field view also changes: ::
+
+ >>> x[1] = (-1,-1.,"Master")
+ >>> x
+ array([(1, 4.0, 'Hello'), (-1, -1.0, 'Master')],
+       dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+ >>> y
+ array([ 4., -1.], dtype=float32)
+
+Defining Structured Arrays
+==========================
+
+One defines a structured array through the dtype object.  There are
+**several** alternative ways to define the fields of a record.  Some of
+these variants provide backward compatibility with Numeric, numarray, or
+another module, and should not be used except for such purposes. These
+will be so noted. One specifies record structure in
+one of four alternative ways, using an argument (as supplied to a dtype
+function keyword or a dtype object constructor itself).  This
+argument must be one of the following: 1) string, 2) tuple, 3) list, or
+4) dictionary.  Each of these is briefly described below.
+
+1) String argument.
+In this case, the constructor expects a comma-separated list of type
+specifiers, optionally with extra shape information. The fields are 
+given the default names 'f0', 'f1', 'f2' and so on.
+The type specifiers can take 4 different forms: ::
+
+  a) b1, i1, i2, i4, i8, u1, u2, u4, u8, f2, f4, f8, c8, c16, a<n>
+     (representing bytes, ints, unsigned ints, floats, complex and
+      fixed length strings of specified byte lengths)
+  b) int8,...,uint8,...,float16, float32, float64, complex64, complex128
+     (this time with bit sizes)
+  c) older Numeric/numarray type specifications (e.g. Float32).
+     Don't use these in new code!
+  d) Single character type specifiers (e.g H for unsigned short ints).
+     Avoid using these unless you must. Details can be found in the
+     Numpy book
+
+These different styles can be mixed within the same string (but why would you
+want to do that?). Furthermore, each type specifier can be prefixed
+with a repetition number, or a shape. In these cases an array
+element is created, i.e., an array within a record. That array
+is still referred to as a single field. An example: ::
+
+ >>> x = np.zeros(3, dtype='3int8, float32, (2,3)float64')
+ >>> x
+ array([([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
+        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
+        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])],
+       dtype=[('f0', '|i1', 3), ('f1', '>f4'), ('f2', '>f8', (2, 3))])
+
+By using strings to define the record structure, it precludes being
+able to name the fields in the original definition. The names can
+be changed as shown later, however.
+
+2) Tuple argument: The only relevant tuple case that applies to record
+structures is when a structure is mapped to an existing data type. This
+is done by pairing in a tuple, the existing data type with a matching
+dtype definition (using any of the variants being described here). As
+an example (using a definition using a list, so see 3) for further
+details): ::
+
+ >>> x = np.zeros(3, dtype=('i4',[('r','u1'), ('g','u1'), ('b','u1'), ('a','u1')]))
+ >>> x
+ array([0, 0, 0])
+ >>> x['r']
+ array([0, 0, 0], dtype=uint8)
+
+In this case, an array is produced that looks and acts like a simple int32 array,
+but also has definitions for fields that use only one byte of the int32 (a bit
+like Fortran equivalencing).
+
+3) List argument: In this case the record structure is defined with a list of
+tuples. Each tuple has 2 or 3 elements specifying: 1) The name of the field
+('' is permitted), 2) the type of the field, and 3) the shape (optional).
+For example::
+
+ >>> x = np.zeros(3, dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
+ >>> x
+ array([(0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
+        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
+        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]])],
+       dtype=[('x', '>f4'), ('y', '>f4'), ('value', '>f4', (2, 2))])
+
+4) Dictionary argument: two different forms are permitted. The first consists
+of a dictionary with two required keys ('names' and 'formats'), each having an
+equal sized list of values. The format list contains any type/shape specifier
+allowed in other contexts. The names must be strings. There are two optional
+keys: 'offsets' and 'titles'. Each must be a correspondingly matching list to
+the required two where offsets contain integer offsets for each field, and
+titles are objects containing metadata for each field (these do not have
+to be strings), where the value of None is permitted. As an example: ::
+
+ >>> x = np.zeros(3, dtype={'names':['col1', 'col2'], 'formats':['i4','f4']})
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+       dtype=[('col1', '>i4'), ('col2', '>f4')])
+
+The other dictionary form permitted is a dictionary of name keys with tuple
+values specifying type, offset, and an optional title. ::
+
+ >>> x = np.zeros(3, dtype={'col1':('i1',0,'title 1'), 'col2':('f4',1,'title 2')})
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+       dtype=[(('title 1', 'col1'), '|i1'), (('title 2', 'col2'), '>f4')])
+
+Accessing and modifying field names
+===================================
+
+The field names are an attribute of the dtype object defining the structure.
+For the last example: ::
+
+ >>> x.dtype.names
+ ('col1', 'col2')
+ >>> x.dtype.names = ('x', 'y')
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+      dtype=[(('title 1', 'x'), '|i1'), (('title 2', 'y'), '>f4')])
+ >>> x.dtype.names = ('x', 'y', 'z') # wrong number of names
+ <type 'exceptions.ValueError'>: must replace all names at once with a sequence of length 2
+
+Accessing field titles
+====================================
+
+The field titles provide a standard place to put associated info for fields.
+They do not have to be strings. ::
+
+ >>> x.dtype.fields['x'][2]
+ 'title 1'
+
+Accessing multiple fields at once
+====================================
+
+You can access multiple fields at once using a list of field names: ::
+
+ >>> x = np.array([(1.5,2.5,(1.0,2.0)),(3.,4.,(4.,5.)),(1.,3.,(2.,6.))],
+         dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
+
+Notice that `x` is created with a list of tuples. ::
+
+ >>> x[['x','y']]
+ array([(1.5, 2.5), (3.0, 4.0), (1.0, 3.0)],
+      dtype=[('x', '<f4'), ('y', '<f4')])
+ >>> x[['x','value']]
+ array([(1.5, [[1.0, 2.0], [1.0, 2.0]]), (3.0, [[4.0, 5.0], [4.0, 5.0]]),
+       (1.0, [[2.0, 6.0], [2.0, 6.0]])],
+      dtype=[('x', '<f4'), ('value', '<f4', (2, 2))])
+
+The fields are returned in the order they are asked for.::
+
+ >>> x[['y','x']]
+ array([(2.5, 1.5), (4.0, 3.0), (3.0, 1.0)],
+      dtype=[('y', '<f4'), ('x', '<f4')])
+
+Filling structured arrays
+=========================
+
+Structured arrays can be filled by field or row by row. ::
+
+ >>> arr = np.zeros((5,), dtype=[('var1','f8'),('var2','f8')])
+ >>> arr['var1'] = np.arange(5)
+
+If you fill it in row by row, it takes a take a tuple
+(but not a list or array!)::
+
+ >>> arr[0] = (10,20)
+ >>> arr
+ array([(10.0, 20.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0)],
+      dtype=[('var1', '<f8'), ('var2', '<f8')])
+
+Record Arrays
+=============
+
+For convenience, numpy provides "record arrays" which allow one to access
+fields of structured arrays by attribute rather than by index. Record arrays
+are structured arrays wrapped using a subclass of ndarray,
+:class:`numpy.recarray`, which allows field access by attribute on the array
+object, and record arrays also use a special datatype, :class:`numpy.record`,
+which allows field access by attribute on the individual elements of the array. 
+
+The simplest way to create a record array is with :func:`numpy.rec.array`: ::
+
+ >>> recordarr = np.rec.array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...                    dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr.bar
+ array([ 2.,  3.], dtype=float32)
+ >>> recordarr[1:2]
+ rec.array([(2, 3.0, 'World')], 
+       dtype=[('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')])
+ >>> recordarr[1:2].foo
+ array([2], dtype=int32)
+ >>> recordarr.foo[1:2]
+ array([2], dtype=int32)
+ >>> recordarr[1].baz
+ 'World'
+
+numpy.rec.array can convert a wide variety of arguments into record arrays,
+including normal structured arrays: ::
+
+ >>> arr = array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...             dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr = np.rec.array(arr)
+
+The numpy.rec module provides a number of other convenience functions for
+creating record arrays, see :ref:`record array creation routines
+<routines.array-creation.rec>`.
+
+A record array representation of a structured array can be obtained using the
+appropriate :ref:`view`: ::
+
+ >>> arr = np.array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...                dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')])
+ >>> recordarr = arr.view(dtype=dtype((np.record, arr.dtype)), 
+ ...                      type=np.recarray)
+
+For convenience, viewing an ndarray as type `np.recarray` will automatically
+convert to `np.record` datatype, so the dtype can be left out of the view: ::
+
+ >>> recordarr = arr.view(np.recarray)
+ >>> recordarr.dtype
+ dtype((numpy.record, [('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')]))
+
+To get back to a plain ndarray both the dtype and type must be reset. The
+following view does so, taking into account the unusual case that the
+recordarr was not a structured type: ::
+
+ >>> arr2 = recordarr.view(recordarr.dtype.fields or recordarr.dtype, np.ndarray)
+
+Record array fields accessed by index or by attribute are returned as a record
+array if the field has a structured type but as a plain ndarray otherwise. ::
+
+ >>> recordarr = np.rec.array([('Hello', (1,2)),("World", (3,4))], 
+ ...                 dtype=[('foo', 'S6'),('bar', [('A', int), ('B', int)])])
+ >>> type(recordarr.foo)
+ <type 'numpy.ndarray'>
+ >>> type(recordarr.bar)
+ <class 'numpy.core.records.recarray'>
+
+Note that if a field has the same name as an ndarray attribute, the ndarray
+attribute takes precedence. Such fields will be inaccessible by attribute but
+may still be accessed by index.
+
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.py
new file mode 100644
index 0000000000..85327feab3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.py
@@ -0,0 +1,560 @@
+"""
+=============================
+Subclassing ndarray in python
+=============================
+
+Credits
+-------
+
+This page is based with thanks on the wiki page on subclassing by Pierre
+Gerard-Marchant - http://www.scipy.org/Subclasses.
+
+Introduction
+------------
+
+Subclassing ndarray is relatively simple, but it has some complications
+compared to other Python objects.  On this page we explain the machinery
+that allows you to subclass ndarray, and the implications for
+implementing a subclass.
+
+ndarrays and object creation
+============================
+
+Subclassing ndarray is complicated by the fact that new instances of
+ndarray classes can come about in three different ways.  These are:
+
+#. Explicit constructor call - as in ``MySubClass(params)``.  This is
+   the usual route to Python instance creation.
+#. View casting - casting an existing ndarray as a given subclass
+#. New from template - creating a new instance from a template
+   instance. Examples include returning slices from a subclassed array,
+   creating return types from ufuncs, and copying arrays.  See
+   :ref:`new-from-template` for more details
+
+The last two are characteristics of ndarrays - in order to support
+things like array slicing.  The complications of subclassing ndarray are
+due to the mechanisms numpy has to support these latter two routes of
+instance creation.
+
+.. _view-casting:
+
+View casting
+------------
+
+*View casting* is the standard ndarray mechanism by which you take an
+ndarray of any subclass, and return a view of the array as another
+(specified) subclass:
+
+>>> import numpy as np
+>>> # create a completely useless ndarray subclass
+>>> class C(np.ndarray): pass
+>>> # create a standard ndarray
+>>> arr = np.zeros((3,))
+>>> # take a view of it, as our useless subclass
+>>> c_arr = arr.view(C)
+>>> type(c_arr)
+<class 'C'>
+
+.. _new-from-template:
+
+Creating new from template
+--------------------------
+
+New instances of an ndarray subclass can also come about by a very
+similar mechanism to :ref:`view-casting`, when numpy finds it needs to
+create a new instance from a template instance.  The most obvious place
+this has to happen is when you are taking slices of subclassed arrays.
+For example:
+
+>>> v = c_arr[1:]
+>>> type(v) # the view is of type 'C'
+<class 'C'>
+>>> v is c_arr # but it's a new instance
+False
+
+The slice is a *view* onto the original ``c_arr`` data.  So, when we
+take a view from the ndarray, we return a new ndarray, of the same
+class, that points to the data in the original.
+
+There are other points in the use of ndarrays where we need such views,
+such as copying arrays (``c_arr.copy()``), creating ufunc output arrays
+(see also :ref:`array-wrap`), and reducing methods (like
+``c_arr.mean()``.
+
+Relationship of view casting and new-from-template
+--------------------------------------------------
+
+These paths both use the same machinery.  We make the distinction here,
+because they result in different input to your methods.  Specifically,
+:ref:`view-casting` means you have created a new instance of your array
+type from any potential subclass of ndarray.  :ref:`new-from-template`
+means you have created a new instance of your class from a pre-existing
+instance, allowing you - for example - to copy across attributes that
+are particular to your subclass.
+
+Implications for subclassing
+----------------------------
+
+If we subclass ndarray, we need to deal not only with explicit
+construction of our array type, but also :ref:`view-casting` or
+:ref:`new-from-template`.  Numpy has the machinery to do this, and this
+machinery that makes subclassing slightly non-standard.
+
+There are two aspects to the machinery that ndarray uses to support
+views and new-from-template in subclasses.
+
+The first is the use of the ``ndarray.__new__`` method for the main work
+of object initialization, rather then the more usual ``__init__``
+method.  The second is the use of the ``__array_finalize__`` method to
+allow subclasses to clean up after the creation of views and new
+instances from templates.
+
+A brief Python primer on ``__new__`` and ``__init__``
+=====================================================
+
+``__new__`` is a standard Python method, and, if present, is called
+before ``__init__`` when we create a class instance. See the `python
+__new__ documentation
+<http://docs.python.org/reference/datamodel.html#object.__new__>`_ for more detail.
+
+For example, consider the following Python code:
+
+.. testcode::
+
+  class C(object):
+      def __new__(cls, *args):
+          print('Cls in __new__:', cls)
+          print('Args in __new__:', args)
+          return object.__new__(cls, *args)
+
+      def __init__(self, *args):
+          print('type(self) in __init__:', type(self))
+          print('Args in __init__:', args)
+
+meaning that we get:
+
+>>> c = C('hello')
+Cls in __new__: <class 'C'>
+Args in __new__: ('hello',)
+type(self) in __init__: <class 'C'>
+Args in __init__: ('hello',)
+
+When we call ``C('hello')``, the ``__new__`` method gets its own class
+as first argument, and the passed argument, which is the string
+``'hello'``.  After python calls ``__new__``, it usually (see below)
+calls our ``__init__`` method, with the output of ``__new__`` as the
+first argument (now a class instance), and the passed arguments
+following.
+
+As you can see, the object can be initialized in the ``__new__``
+method or the ``__init__`` method, or both, and in fact ndarray does
+not have an ``__init__`` method, because all the initialization is
+done in the ``__new__`` method.
+
+Why use ``__new__`` rather than just the usual ``__init__``?  Because
+in some cases, as for ndarray, we want to be able to return an object
+of some other class.  Consider the following:
+
+.. testcode::
+
+  class D(C):
+      def __new__(cls, *args):
+          print('D cls is:', cls)
+          print('D args in __new__:', args)
+          return C.__new__(C, *args)
+
+      def __init__(self, *args):
+          # we never get here
+          print('In D __init__')
+
+meaning that:
+
+>>> obj = D('hello')
+D cls is: <class 'D'>
+D args in __new__: ('hello',)
+Cls in __new__: <class 'C'>
+Args in __new__: ('hello',)
+>>> type(obj)
+<class 'C'>
+
+The definition of ``C`` is the same as before, but for ``D``, the
+``__new__`` method returns an instance of class ``C`` rather than
+``D``.  Note that the ``__init__`` method of ``D`` does not get
+called.  In general, when the ``__new__`` method returns an object of
+class other than the class in which it is defined, the ``__init__``
+method of that class is not called.
+
+This is how subclasses of the ndarray class are able to return views
+that preserve the class type.  When taking a view, the standard
+ndarray machinery creates the new ndarray object with something
+like::
+
+  obj = ndarray.__new__(subtype, shape, ...
+
+where ``subdtype`` is the subclass.  Thus the returned view is of the
+same class as the subclass, rather than being of class ``ndarray``.
+
+That solves the problem of returning views of the same type, but now
+we have a new problem.  The machinery of ndarray can set the class
+this way, in its standard methods for taking views, but the ndarray
+``__new__`` method knows nothing of what we have done in our own
+``__new__`` method in order to set attributes, and so on.  (Aside -
+why not call ``obj = subdtype.__new__(...`` then?  Because we may not
+have a ``__new__`` method with the same call signature).
+
+The role of ``__array_finalize__``
+==================================
+
+``__array_finalize__`` is the mechanism that numpy provides to allow
+subclasses to handle the various ways that new instances get created.
+
+Remember that subclass instances can come about in these three ways:
+
+#. explicit constructor call (``obj = MySubClass(params)``).  This will
+   call the usual sequence of ``MySubClass.__new__`` then (if it exists)
+   ``MySubClass.__init__``.
+#. :ref:`view-casting`
+#. :ref:`new-from-template`
+
+Our ``MySubClass.__new__`` method only gets called in the case of the
+explicit constructor call, so we can't rely on ``MySubClass.__new__`` or
+``MySubClass.__init__`` to deal with the view casting and
+new-from-template.  It turns out that ``MySubClass.__array_finalize__``
+*does* get called for all three methods of object creation, so this is
+where our object creation housekeeping usually goes.
+
+* For the explicit constructor call, our subclass will need to create a
+  new ndarray instance of its own class.  In practice this means that
+  we, the authors of the code, will need to make a call to
+  ``ndarray.__new__(MySubClass,...)``, or do view casting of an existing
+  array (see below)
+* For view casting and new-from-template, the equivalent of
+  ``ndarray.__new__(MySubClass,...`` is called, at the C level.
+
+The arguments that ``__array_finalize__`` recieves differ for the three
+methods of instance creation above.
+
+The following code allows us to look at the call sequences and arguments:
+
+.. testcode::
+
+   import numpy as np
+
+   class C(np.ndarray):
+       def __new__(cls, *args, **kwargs):
+           print('In __new__ with class %s' % cls)
+           return np.ndarray.__new__(cls, *args, **kwargs)
+
+       def __init__(self, *args, **kwargs):
+           # in practice you probably will not need or want an __init__
+           # method for your subclass
+           print('In __init__ with class %s' % self.__class__)
+
+       def __array_finalize__(self, obj):
+           print('In array_finalize:')
+           print('   self type is %s' % type(self))
+           print('   obj type is %s' % type(obj))
+
+
+Now:
+
+>>> # Explicit constructor
+>>> c = C((10,))
+In __new__ with class <class 'C'>
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <type 'NoneType'>
+In __init__ with class <class 'C'>
+>>> # View casting
+>>> a = np.arange(10)
+>>> cast_a = a.view(C)
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <type 'numpy.ndarray'>
+>>> # Slicing (example of new-from-template)
+>>> cv = c[:1]
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <class 'C'>
+
+The signature of ``__array_finalize__`` is::
+
+    def __array_finalize__(self, obj):
+
+``ndarray.__new__`` passes ``__array_finalize__`` the new object, of our
+own class (``self``) as well as the object from which the view has been
+taken (``obj``).  As you can see from the output above, the ``self`` is
+always a newly created instance of our subclass, and the type of ``obj``
+differs for the three instance creation methods:
+
+* When called from the explicit constructor, ``obj`` is ``None``
+* When called from view casting, ``obj`` can be an instance of any
+  subclass of ndarray, including our own.
+* When called in new-from-template, ``obj`` is another instance of our
+  own subclass, that we might use to update the new ``self`` instance.
+
+Because ``__array_finalize__`` is the only method that always sees new
+instances being created, it is the sensible place to fill in instance
+defaults for new object attributes, among other tasks.
+
+This may be clearer with an example.
+
+Simple example - adding an extra attribute to ndarray
+-----------------------------------------------------
+
+.. testcode::
+
+  import numpy as np
+
+  class InfoArray(np.ndarray):
+
+      def __new__(subtype, shape, dtype=float, buffer=None, offset=0,
+            strides=None, order=None, info=None):
+          # Create the ndarray instance of our type, given the usual
+          # ndarray input arguments.  This will call the standard
+          # ndarray constructor, but return an object of our type.
+          # It also triggers a call to InfoArray.__array_finalize__
+          obj = np.ndarray.__new__(subtype, shape, dtype, buffer, offset, strides,
+                           order)
+          # set the new 'info' attribute to the value passed
+          obj.info = info
+          # Finally, we must return the newly created object:
+          return obj
+
+      def __array_finalize__(self, obj):
+          # ``self`` is a new object resulting from
+          # ndarray.__new__(InfoArray, ...), therefore it only has
+          # attributes that the ndarray.__new__ constructor gave it -
+          # i.e. those of a standard ndarray.
+          #
+          # We could have got to the ndarray.__new__ call in 3 ways:
+          # From an explicit constructor - e.g. InfoArray():
+          #    obj is None
+          #    (we're in the middle of the InfoArray.__new__
+          #    constructor, and self.info will be set when we return to
+          #    InfoArray.__new__)
+          if obj is None: return
+          # From view casting - e.g arr.view(InfoArray):
+          #    obj is arr
+          #    (type(obj) can be InfoArray)
+          # From new-from-template - e.g infoarr[:3]
+          #    type(obj) is InfoArray
+          #
+          # Note that it is here, rather than in the __new__ method,
+          # that we set the default value for 'info', because this
+          # method sees all creation of default objects - with the
+          # InfoArray.__new__ constructor, but also with
+          # arr.view(InfoArray).
+          self.info = getattr(obj, 'info', None)
+          # We do not need to return anything
+
+
+Using the object looks like this:
+
+  >>> obj = InfoArray(shape=(3,)) # explicit constructor
+  >>> type(obj)
+  <class 'InfoArray'>
+  >>> obj.info is None
+  True
+  >>> obj = InfoArray(shape=(3,), info='information')
+  >>> obj.info
+  'information'
+  >>> v = obj[1:] # new-from-template - here - slicing
+  >>> type(v)
+  <class 'InfoArray'>
+  >>> v.info
+  'information'
+  >>> arr = np.arange(10)
+  >>> cast_arr = arr.view(InfoArray) # view casting
+  >>> type(cast_arr)
+  <class 'InfoArray'>
+  >>> cast_arr.info is None
+  True
+
+This class isn't very useful, because it has the same constructor as the
+bare ndarray object, including passing in buffers and shapes and so on.
+We would probably prefer the constructor to be able to take an already
+formed ndarray from the usual numpy calls to ``np.array`` and return an
+object.
+
+Slightly more realistic example - attribute added to existing array
+-------------------------------------------------------------------
+
+Here is a class that takes a standard ndarray that already exists, casts
+as our type, and adds an extra attribute.
+
+.. testcode::
+
+  import numpy as np
+
+  class RealisticInfoArray(np.ndarray):
+
+      def __new__(cls, input_array, info=None):
+          # Input array is an already formed ndarray instance
+          # We first cast to be our class type
+          obj = np.asarray(input_array).view(cls)
+          # add the new attribute to the created instance
+          obj.info = info
+          # Finally, we must return the newly created object:
+          return obj
+
+      def __array_finalize__(self, obj):
+          # see InfoArray.__array_finalize__ for comments
+          if obj is None: return
+          self.info = getattr(obj, 'info', None)
+
+
+So:
+
+  >>> arr = np.arange(5)
+  >>> obj = RealisticInfoArray(arr, info='information')
+  >>> type(obj)
+  <class 'RealisticInfoArray'>
+  >>> obj.info
+  'information'
+  >>> v = obj[1:]
+  >>> type(v)
+  <class 'RealisticInfoArray'>
+  >>> v.info
+  'information'
+
+.. _array-wrap:
+
+``__array_wrap__`` for ufuncs
+-------------------------------------------------------
+
+``__array_wrap__`` gets called at the end of numpy ufuncs and other numpy
+functions, to allow a subclass to set the type of the return value
+and update attributes and metadata. Let's show how this works with an example.
+First we make the same subclass as above, but with a different name and
+some print statements:
+
+.. testcode::
+
+  import numpy as np
+
+  class MySubClass(np.ndarray):
+
+      def __new__(cls, input_array, info=None):
+          obj = np.asarray(input_array).view(cls)
+          obj.info = info
+          return obj
+
+      def __array_finalize__(self, obj):
+          print('In __array_finalize__:')
+          print('   self is %s' % repr(self))
+          print('   obj is %s' % repr(obj))
+          if obj is None: return
+          self.info = getattr(obj, 'info', None)
+
+      def __array_wrap__(self, out_arr, context=None):
+          print('In __array_wrap__:')
+          print('   self is %s' % repr(self))
+          print('   arr is %s' % repr(out_arr))
+          # then just call the parent
+          return np.ndarray.__array_wrap__(self, out_arr, context)
+
+We run a ufunc on an instance of our new array:
+
+>>> obj = MySubClass(np.arange(5), info='spam')
+In __array_finalize__:
+   self is MySubClass([0, 1, 2, 3, 4])
+   obj is array([0, 1, 2, 3, 4])
+>>> arr2 = np.arange(5)+1
+>>> ret = np.add(arr2, obj)
+In __array_wrap__:
+   self is MySubClass([0, 1, 2, 3, 4])
+   arr is array([1, 3, 5, 7, 9])
+In __array_finalize__:
+   self is MySubClass([1, 3, 5, 7, 9])
+   obj is MySubClass([0, 1, 2, 3, 4])
+>>> ret
+MySubClass([1, 3, 5, 7, 9])
+>>> ret.info
+'spam'
+
+Note that the ufunc (``np.add``) has called the ``__array_wrap__`` method of the
+input with the highest ``__array_priority__`` value, in this case
+``MySubClass.__array_wrap__``, with arguments ``self`` as ``obj``, and
+``out_arr`` as the (ndarray) result of the addition.  In turn, the
+default ``__array_wrap__`` (``ndarray.__array_wrap__``) has cast the
+result to class ``MySubClass``, and called ``__array_finalize__`` -
+hence the copying of the ``info`` attribute.  This has all happened at the C level.
+
+But, we could do anything we wanted:
+
+.. testcode::
+
+  class SillySubClass(np.ndarray):
+
+      def __array_wrap__(self, arr, context=None):
+          return 'I lost your data'
+
+>>> arr1 = np.arange(5)
+>>> obj = arr1.view(SillySubClass)
+>>> arr2 = np.arange(5)
+>>> ret = np.multiply(obj, arr2)
+>>> ret
+'I lost your data'
+
+So, by defining a specific ``__array_wrap__`` method for our subclass,
+we can tweak the output from ufuncs. The ``__array_wrap__`` method
+requires ``self``, then an argument - which is the result of the ufunc -
+and an optional parameter *context*. This parameter is returned by some
+ufuncs as a 3-element tuple: (name of the ufunc, argument of the ufunc,
+domain of the ufunc). ``__array_wrap__`` should return an instance of
+its containing class.  See the masked array subclass for an
+implementation.
+
+In addition to ``__array_wrap__``, which is called on the way out of the
+ufunc, there is also an ``__array_prepare__`` method which is called on
+the way into the ufunc, after the output arrays are created but before any
+computation has been performed. The default implementation does nothing
+but pass through the array. ``__array_prepare__`` should not attempt to
+access the array data or resize the array, it is intended for setting the
+output array type, updating attributes and metadata, and performing any
+checks based on the input that may be desired before computation begins.
+Like ``__array_wrap__``, ``__array_prepare__`` must return an ndarray or
+subclass thereof or raise an error.
+
+Extra gotchas - custom ``__del__`` methods and ndarray.base
+-----------------------------------------------------------
+
+One of the problems that ndarray solves is keeping track of memory
+ownership of ndarrays and their views.  Consider the case where we have
+created an ndarray, ``arr`` and have taken a slice with ``v = arr[1:]``.
+The two objects are looking at the same memory.  Numpy keeps track of
+where the data came from for a particular array or view, with the
+``base`` attribute:
+
+>>> # A normal ndarray, that owns its own data
+>>> arr = np.zeros((4,))
+>>> # In this case, base is None
+>>> arr.base is None
+True
+>>> # We take a view
+>>> v1 = arr[1:]
+>>> # base now points to the array that it derived from
+>>> v1.base is arr
+True
+>>> # Take a view of a view
+>>> v2 = v1[1:]
+>>> # base points to the view it derived from
+>>> v2.base is v1
+True
+
+In general, if the array owns its own memory, as for ``arr`` in this
+case, then ``arr.base`` will be None - there are some exceptions to this
+- see the numpy book for more details.
+
+The ``base`` attribute is useful in being able to tell whether we have
+a view or the original array.  This in turn can be useful if we need
+to know whether or not to do some specific cleanup when the subclassed
+array is deleted.  For example, we may only want to do the cleanup if
+the original array is deleted, but not the views.  For an example of
+how this can work, have a look at the ``memmap`` class in
+``numpy.core``.
+
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.py
new file mode 100644
index 0000000000..0132202adc
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.py
@@ -0,0 +1,138 @@
+"""
+===================
+Universal Functions
+===================
+
+Ufuncs are, generally speaking, mathematical functions or operations that are
+applied element-by-element to the contents of an array. That is, the result
+in each output array element only depends on the value in the corresponding
+input array (or arrays) and on no other array elements. Numpy comes with a
+large suite of ufuncs, and scipy extends that suite substantially. The simplest
+example is the addition operator: ::
+
+ >>> np.array([0,2,3,4]) + np.array([1,1,-1,2])
+ array([1, 3, 2, 6])
+
+The unfunc module lists all the available ufuncs in numpy. Documentation on
+the specific ufuncs may be found in those modules. This documentation is
+intended to address the more general aspects of unfuncs common to most of
+them. All of the ufuncs that make use of Python operators (e.g., +, -, etc.)
+have equivalent functions defined (e.g. add() for +)
+
+Type coercion
+=============
+
+What happens when a binary operator (e.g., +,-,\\*,/, etc) deals with arrays of
+two different types? What is the type of the result? Typically, the result is
+the higher of the two types. For example: ::
+
+ float32 + float64 -> float64
+ int8 + int32 -> int32
+ int16 + float32 -> float32
+ float32 + complex64 -> complex64
+
+There are some less obvious cases generally involving mixes of types
+(e.g. uints, ints and floats) where equal bit sizes for each are not
+capable of saving all the information in a different type of equivalent
+bit size. Some examples are int32 vs float32 or uint32 vs int32.
+Generally, the result is the higher type of larger size than both
+(if available). So: ::
+
+ int32 + float32 -> float64
+ uint32 + int32 -> int64
+
+Finally, the type coercion behavior when expressions involve Python
+scalars is different than that seen for arrays. Since Python has a
+limited number of types, combining a Python int with a dtype=np.int8
+array does not coerce to the higher type but instead, the type of the
+array prevails. So the rules for Python scalars combined with arrays is
+that the result will be that of the array equivalent the Python scalar
+if the Python scalar is of a higher 'kind' than the array (e.g., float
+vs. int), otherwise the resultant type will be that of the array.
+For example: ::
+
+  Python int + int8 -> int8
+  Python float + int8 -> float64
+
+ufunc methods
+=============
+
+Binary ufuncs support 4 methods.
+
+**.reduce(arr)** applies the binary operator to elements of the array in
+  sequence. For example: ::
+
+ >>> np.add.reduce(np.arange(10))  # adds all elements of array
+ 45
+
+For multidimensional arrays, the first dimension is reduced by default: ::
+
+ >>> np.add.reduce(np.arange(10).reshape(2,5))
+     array([ 5,  7,  9, 11, 13])
+
+The axis keyword can be used to specify different axes to reduce: ::
+
+ >>> np.add.reduce(np.arange(10).reshape(2,5),axis=1)
+ array([10, 35])
+
+**.accumulate(arr)** applies the binary operator and generates an an
+equivalently shaped array that includes the accumulated amount for each
+element of the array. A couple examples: ::
+
+ >>> np.add.accumulate(np.arange(10))
+ array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45])
+ >>> np.multiply.accumulate(np.arange(1,9))
+ array([    1,     2,     6,    24,   120,   720,  5040, 40320])
+
+The behavior for multidimensional arrays is the same as for .reduce(),
+as is the use of the axis keyword).
+
+**.reduceat(arr,indices)** allows one to apply reduce to selected parts
+  of an array. It is a difficult method to understand. See the documentation
+  at:
+
+**.outer(arr1,arr2)** generates an outer operation on the two arrays arr1 and
+  arr2. It will work on multidimensional arrays (the shape of the result is
+  the concatenation of the two input shapes.: ::
+
+ >>> np.multiply.outer(np.arange(3),np.arange(4))
+ array([[0, 0, 0, 0],
+        [0, 1, 2, 3],
+        [0, 2, 4, 6]])
+
+Output arguments
+================
+
+All ufuncs accept an optional output array. The array must be of the expected
+output shape. Beware that if the type of the output array is of a different
+(and lower) type than the output result, the results may be silently truncated
+or otherwise corrupted in the downcast to the lower type. This usage is useful
+when one wants to avoid creating large temporary arrays and instead allows one
+to reuse the same array memory repeatedly (at the expense of not being able to
+use more convenient operator notation in expressions). Note that when the
+output argument is used, the ufunc still returns a reference to the result.
+
+ >>> x = np.arange(2)
+ >>> np.add(np.arange(2),np.arange(2.),x)
+ array([0, 2])
+ >>> x
+ array([0, 2])
+
+and & or as ufuncs
+==================
+
+Invariably people try to use the python 'and' and 'or' as logical operators
+(and quite understandably). But these operators do not behave as normal
+operators since Python treats these quite differently. They cannot be
+overloaded with array equivalents. Thus using 'and' or 'or' with an array
+results in an error. There are two alternatives:
+
+ 1) use the ufunc functions logical_and() and logical_or().
+ 2) use the bitwise operators & and \\|. The drawback of these is that if
+    the arguments to these operators are not boolean arrays, the result is
+    likely incorrect. On the other hand, most usages of logical_and and
+    logical_or are with boolean arrays. As long as one is careful, this is
+    a convenient way to apply these operators.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/dual.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/dual.py
new file mode 100644
index 0000000000..1517d84213
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/dual.py
@@ -0,0 +1,71 @@
+"""
+Aliases for functions which may be accelerated by Scipy.
+
+Scipy_ can be built to use accelerated or otherwise improved libraries
+for FFTs, linear algebra, and special functions. This module allows
+developers to transparently support these accelerated functions when
+scipy is available but still support users who have only installed
+Numpy.
+
+.. _Scipy : http://www.scipy.org
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# This module should be used for functions both in numpy and scipy if
+#  you want to use the numpy version if available but the scipy version
+#  otherwise.
+#  Usage  --- from numpy.dual import fft, inv
+
+__all__ = ['fft', 'ifft', 'fftn', 'ifftn', 'fft2', 'ifft2',
+           'norm', 'inv', 'svd', 'solve', 'det', 'eig', 'eigvals',
+           'eigh', 'eigvalsh', 'lstsq', 'pinv', 'cholesky', 'i0']
+
+import numpy.linalg as linpkg
+import numpy.fft as fftpkg
+from numpy.lib import i0
+import sys
+
+
+fft = fftpkg.fft
+ifft = fftpkg.ifft
+fftn = fftpkg.fftn
+ifftn = fftpkg.ifftn
+fft2 = fftpkg.fft2
+ifft2 = fftpkg.ifft2
+
+norm = linpkg.norm
+inv = linpkg.inv
+svd = linpkg.svd
+solve = linpkg.solve
+det = linpkg.det
+eig = linpkg.eig
+eigvals = linpkg.eigvals
+eigh = linpkg.eigh
+eigvalsh = linpkg.eigvalsh
+lstsq = linpkg.lstsq
+pinv = linpkg.pinv
+cholesky = linpkg.cholesky
+
+_restore_dict = {}
+
+def register_func(name, func):
+    if name not in __all__:
+        raise ValueError("%s not a dual function." % name)
+    f = sys._getframe(0).f_globals
+    _restore_dict[name] = f[name]
+    f[name] = func
+
+def restore_func(name):
+    if name not in __all__:
+        raise ValueError("%s not a dual function." % name)
+    try:
+        val = _restore_dict[name]
+    except KeyError:
+        return
+    else:
+        sys._getframe(0).f_globals[name] = val
+
+def restore_all():
+    for name in _restore_dict.keys():
+        restore_func(name)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.py
new file mode 100644
index 0000000000..4d1bc13766
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python2
+"""Fortran to Python Interface Generator.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['run_main', 'compile', 'f2py_testing']
+
+import sys
+
+from . import f2py2e
+from . import f2py_testing
+from . import diagnose
+
+run_main = f2py2e.run_main
+main = f2py2e.main
+
+
+def compile(source,
+            modulename='untitled',
+            extra_args='',
+            verbose=True,
+            source_fn=None,
+            extension='.f'
+            ):
+    ''' Build extension module from processing source with f2py.
+
+    Parameters
+    ----------
+    source : str
+        Fortran source of module / subroutine to compile
+    modulename : str, optional
+        the name of compiled python module
+    extra_args: str, optional
+        additional parameters passed to f2py
+    verbose: bool, optional
+        print f2py output to screen
+    extension: {'.f', '.f90'}, optional
+        filename extension influences the fortran compiler behavior
+
+        .. versionadded:: 1.11.0
+
+    '''
+    from numpy.distutils.exec_command import exec_command
+    import tempfile
+    if source_fn is None:
+        f = tempfile.NamedTemporaryFile(suffix=extension)
+    else:
+        f = open(source_fn, 'w')
+
+    try:
+        f.write(source)
+        f.flush()
+
+        args = ' -c -m {} {} {}'.format(modulename, f.name, extra_args)
+        c = '{} -c "import numpy.f2py as f2py2e;f2py2e.main()" {}'
+        c = c.format(sys.executable, args)
+        status, output = exec_command(c)
+        if verbose:
+            print(output)
+    finally:
+        f.close()
+    return status
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.py
new file mode 100644
index 0000000000..cb8f261c1b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.py
@@ -0,0 +1,27 @@
+# See http://cens.ioc.ee/projects/f2py2e/
+from __future__ import division, print_function
+
+import os
+import sys
+for mode in ["g3-numpy", "2e-numeric", "2e-numarray", "2e-numpy"]:
+    try:
+        i = sys.argv.index("--" + mode)
+        del sys.argv[i]
+        break
+    except ValueError:
+        pass
+os.environ["NO_SCIPY_IMPORT"] = "f2py"
+if mode == "g3-numpy":
+    sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
+    sys.exit(1)
+elif mode == "2e-numeric":
+    from f2py2e import main
+elif mode == "2e-numarray":
+    sys.argv.append("-DNUMARRAY")
+    from f2py2e import main
+elif mode == "2e-numpy":
+    from numpy.f2py import main
+else:
+    sys.stderr.write("Unknown mode: " + repr(mode) + "\\n")
+    sys.exit(1)
+main()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.py
new file mode 100644
index 0000000000..49a2199bf3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.py
@@ -0,0 +1,10 @@
+from __future__ import division, absolute_import, print_function
+
+major = 2
+
+try:
+    from __svn_version__ import version
+    version_info = (major, version)
+    version = '%s_%s' % version_info
+except (ImportError, ValueError):
+    version = str(major)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
new file mode 100644
index 0000000000..77a942e9ac
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
@@ -0,0 +1,854 @@
+#!/usr/bin/env python2
+"""
+
+Auxiliary functions for f2py2e.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) LICENSE.
+
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/07/24 19:01:55 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import pprint
+import sys
+import types
+from functools import reduce
+
+from . import __version__
+from . import cfuncs
+
+__all__ = [
+    'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle',
+    'getargs2', 'getcallprotoargument', 'getcallstatement',
+    'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode',
+    'getusercode1', 'hasbody', 'hascallstatement', 'hascommon',
+    'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote',
+    'isallocatable', 'isarray', 'isarrayofstrings', 'iscomplex',
+    'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn',
+    'isdouble', 'isdummyroutine', 'isexternal', 'isfunction',
+    'isfunction_wrap', 'isint1array', 'isinteger', 'isintent_aux',
+    'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict',
+    'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace',
+    'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical',
+    'islogicalfunction', 'islong_complex', 'islong_double',
+    'islong_doublefunction', 'islong_long', 'islong_longfunction',
+    'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isrequired',
+    'isroutine', 'isscalar', 'issigned_long_longarray', 'isstring',
+    'isstringarray', 'isstringfunction', 'issubroutine',
+    'issubroutine_wrap', 'isthreadsafe', 'isunsigned', 'isunsigned_char',
+    'isunsigned_chararray', 'isunsigned_long_long',
+    'isunsigned_long_longarray', 'isunsigned_short',
+    'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess',
+    'replace', 'show', 'stripcomma', 'throw_error',
+]
+
+
+f2py_version = __version__.version
+
+
+errmess = sys.stderr.write
+show = pprint.pprint
+
+options = {}
+debugoptions = []
+wrapfuncs = 1
+
+
+def outmess(t):
+    if options.get('verbose', 1):
+        sys.stdout.write(t)
+
+
+def debugcapi(var):
+    return 'capi' in debugoptions
+
+
+def _isstring(var):
+    return 'typespec' in var and var['typespec'] == 'character' and \
+           not isexternal(var)
+
+
+def isstring(var):
+    return _isstring(var) and not isarray(var)
+
+
+def ischaracter(var):
+    return isstring(var) and 'charselector' not in var
+
+
+def isstringarray(var):
+    return isarray(var) and _isstring(var)
+
+
+def isarrayofstrings(var):
+    # leaving out '*' for now so that `character*(*) a(m)` and `character
+    # a(m,*)` are treated differently. Luckily `character**` is illegal.
+    return isstringarray(var) and var['dimension'][-1] == '(*)'
+
+
+def isarray(var):
+    return 'dimension' in var and not isexternal(var)
+
+
+def isscalar(var):
+    return not (isarray(var) or isstring(var) or isexternal(var))
+
+
+def iscomplex(var):
+    return isscalar(var) and \
+           var.get('typespec') in ['complex', 'double complex']
+
+
+def islogical(var):
+    return isscalar(var) and var.get('typespec') == 'logical'
+
+
+def isinteger(var):
+    return isscalar(var) and var.get('typespec') == 'integer'
+
+
+def isreal(var):
+    return isscalar(var) and var.get('typespec') == 'real'
+
+
+def get_kind(var):
+    try:
+        return var['kindselector']['*']
+    except KeyError:
+        try:
+            return var['kindselector']['kind']
+        except KeyError:
+            pass
+
+
+def islong_long(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') not in ['integer', 'logical']:
+        return 0
+    return get_kind(var) == '8'
+
+
+def isunsigned_char(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-1'
+
+
+def isunsigned_short(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-2'
+
+
+def isunsigned(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-4'
+
+
+def isunsigned_long_long(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-8'
+
+
+def isdouble(var):
+    if not isscalar(var):
+        return 0
+    if not var.get('typespec') == 'real':
+        return 0
+    return get_kind(var) == '8'
+
+
+def islong_double(var):
+    if not isscalar(var):
+        return 0
+    if not var.get('typespec') == 'real':
+        return 0
+    return get_kind(var) == '16'
+
+
+def islong_complex(var):
+    if not iscomplex(var):
+        return 0
+    return get_kind(var) == '32'
+
+
+def iscomplexarray(var):
+    return isarray(var) and \
+           var.get('typespec') in ['complex', 'double complex']
+
+
+def isint1array(var):
+    return isarray(var) and var.get('typespec') == 'integer' \
+        and get_kind(var) == '1'
+
+
+def isunsigned_chararray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-1'
+
+
+def isunsigned_shortarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-2'
+
+
+def isunsignedarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-4'
+
+
+def isunsigned_long_longarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-8'
+
+
+def issigned_chararray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '1'
+
+
+def issigned_shortarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '2'
+
+
+def issigned_array(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '4'
+
+
+def issigned_long_longarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '8'
+
+
+def isallocatable(var):
+    return 'attrspec' in var and 'allocatable' in var['attrspec']
+
+
+def ismutable(var):
+    return not ('dimension' not in var or isstring(var))
+
+
+def ismoduleroutine(rout):
+    return 'modulename' in rout
+
+
+def ismodule(rout):
+    return 'block' in rout and 'module' == rout['block']
+
+
+def isfunction(rout):
+    return 'block' in rout and 'function' == rout['block']
+
+def isfunction_wrap(rout):
+    if isintent_c(rout):
+        return 0
+    return wrapfuncs and isfunction(rout) and (not isexternal(rout))
+
+
+def issubroutine(rout):
+    return 'block' in rout and 'subroutine' == rout['block']
+
+
+def issubroutine_wrap(rout):
+    if isintent_c(rout):
+        return 0
+    return issubroutine(rout) and hasassumedshape(rout)
+
+
+def hasassumedshape(rout):
+    if rout.get('hasassumedshape'):
+        return True
+    for a in rout['args']:
+        for d in rout['vars'].get(a, {}).get('dimension', []):
+            if d == ':':
+                rout['hasassumedshape'] = True
+                return True
+    return False
+
+
+def isroutine(rout):
+    return isfunction(rout) or issubroutine(rout)
+
+
+def islogicalfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islogical(rout['vars'][a])
+    return 0
+
+
+def islong_longfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islong_long(rout['vars'][a])
+    return 0
+
+
+def islong_doublefunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islong_double(rout['vars'][a])
+    return 0
+
+
+def iscomplexfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return iscomplex(rout['vars'][a])
+    return 0
+
+
+def iscomplexfunction_warn(rout):
+    if iscomplexfunction(rout):
+        outmess("""\
+    **************************************************************
+        Warning: code with a function returning complex value
+        may not work correctly with your Fortran compiler.
+        Run the following test before using it in your applications:
+        $(f2py install dir)/test-site/{b/runme_scalar,e/runme}
+        When using GNU gcc/g77 compilers, codes should work correctly.
+    **************************************************************\n""")
+        return 1
+    return 0
+
+
+def isstringfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return isstring(rout['vars'][a])
+    return 0
+
+
+def hasexternals(rout):
+    return 'externals' in rout and rout['externals']
+
+
+def isthreadsafe(rout):
+    return 'f2pyenhancements' in rout and \
+           'threadsafe' in rout['f2pyenhancements']
+
+
+def hasvariables(rout):
+    return 'vars' in rout and rout['vars']
+
+
+def isoptional(var):
+    return ('attrspec' in var and 'optional' in var['attrspec'] and
+            'required' not in var['attrspec']) and isintent_nothide(var)
+
+
+def isexternal(var):
+    return 'attrspec' in var and 'external' in var['attrspec']
+
+
+def isrequired(var):
+    return not isoptional(var) and isintent_nothide(var)
+
+
+def isintent_in(var):
+    if 'intent' not in var:
+        return 1
+    if 'hide' in var['intent']:
+        return 0
+    if 'inplace' in var['intent']:
+        return 0
+    if 'in' in var['intent']:
+        return 1
+    if 'out' in var['intent']:
+        return 0
+    if 'inout' in var['intent']:
+        return 0
+    if 'outin' in var['intent']:
+        return 0
+    return 1
+
+
+def isintent_inout(var):
+    return ('intent' in var and ('inout' in var['intent'] or
+            'outin' in var['intent']) and 'in' not in var['intent'] and
+            'hide' not in var['intent'] and 'inplace' not in var['intent'])
+
+
+def isintent_out(var):
+    return 'out' in var.get('intent', [])
+
+
+def isintent_hide(var):
+    return ('intent' in var and ('hide' in var['intent'] or
+            ('out' in var['intent'] and 'in' not in var['intent'] and
+                (not l_or(isintent_inout, isintent_inplace)(var)))))
+
+def isintent_nothide(var):
+    return not isintent_hide(var)
+
+
+def isintent_c(var):
+    return 'c' in var.get('intent', [])
+
+
+def isintent_cache(var):
+    return 'cache' in var.get('intent', [])
+
+
+def isintent_copy(var):
+    return 'copy' in var.get('intent', [])
+
+
+def isintent_overwrite(var):
+    return 'overwrite' in var.get('intent', [])
+
+
+def isintent_callback(var):
+    return 'callback' in var.get('intent', [])
+
+
+def isintent_inplace(var):
+    return 'inplace' in var.get('intent', [])
+
+
+def isintent_aux(var):
+    return 'aux' in var.get('intent', [])
+
+
+def isintent_aligned4(var):
+    return 'aligned4' in var.get('intent', [])
+
+
+def isintent_aligned8(var):
+    return 'aligned8' in var.get('intent', [])
+
+
+def isintent_aligned16(var):
+    return 'aligned16' in var.get('intent', [])
+
+isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT',
+                 isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE',
+                 isintent_cache: 'INTENT_CACHE',
+                 isintent_c: 'INTENT_C', isoptional: 'OPTIONAL',
+                 isintent_inplace: 'INTENT_INPLACE',
+                 isintent_aligned4: 'INTENT_ALIGNED4',
+                 isintent_aligned8: 'INTENT_ALIGNED8',
+                 isintent_aligned16: 'INTENT_ALIGNED16',
+                 }
+
+
+def isprivate(var):
+    return 'attrspec' in var and 'private' in var['attrspec']
+
+
+def hasinitvalue(var):
+    return '=' in var
+
+
+def hasinitvalueasstring(var):
+    if not hasinitvalue(var):
+        return 0
+    return var['='][0] in ['"', "'"]
+
+
+def hasnote(var):
+    return 'note' in var
+
+
+def hasresultnote(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return hasnote(rout['vars'][a])
+    return 0
+
+
+def hascommon(rout):
+    return 'common' in rout
+
+
+def containscommon(rout):
+    if hascommon(rout):
+        return 1
+    if hasbody(rout):
+        for b in rout['body']:
+            if containscommon(b):
+                return 1
+    return 0
+
+
+def containsmodule(block):
+    if ismodule(block):
+        return 1
+    if not hasbody(block):
+        return 0
+    for b in block['body']:
+        if containsmodule(b):
+            return 1
+    return 0
+
+
+def hasbody(rout):
+    return 'body' in rout
+
+
+def hascallstatement(rout):
+    return getcallstatement(rout) is not None
+
+
+def istrue(var):
+    return 1
+
+
+def isfalse(var):
+    return 0
+
+
+class F2PYError(Exception):
+    pass
+
+
+class throw_error:
+
+    def __init__(self, mess):
+        self.mess = mess
+
+    def __call__(self, var):
+        mess = '\n\n  var = %s\n  Message: %s\n' % (var, self.mess)
+        raise F2PYError(mess)
+
+
+def l_and(*f):
+    l, l2 = 'lambda v', []
+    for i in range(len(f)):
+        l = '%s,f%d=f[%d]' % (l, i, i)
+        l2.append('f%d(v)' % (i))
+    return eval('%s:%s' % (l, ' and '.join(l2)))
+
+
+def l_or(*f):
+    l, l2 = 'lambda v', []
+    for i in range(len(f)):
+        l = '%s,f%d=f[%d]' % (l, i, i)
+        l2.append('f%d(v)' % (i))
+    return eval('%s:%s' % (l, ' or '.join(l2)))
+
+
+def l_not(f):
+    return eval('lambda v,f=f:not f(v)')
+
+
+def isdummyroutine(rout):
+    try:
+        return rout['f2pyenhancements']['fortranname'] == ''
+    except KeyError:
+        return 0
+
+
+def getfortranname(rout):
+    try:
+        name = rout['f2pyenhancements']['fortranname']
+        if name == '':
+            raise KeyError
+        if not name:
+            errmess('Failed to use fortranname from %s\n' %
+                    (rout['f2pyenhancements']))
+            raise KeyError
+    except KeyError:
+        name = rout['name']
+    return name
+
+
+def getmultilineblock(rout, blockname, comment=1, counter=0):
+    try:
+        r = rout['f2pyenhancements'].get(blockname)
+    except KeyError:
+        return
+    if not r:
+        return
+    if counter > 0 and isinstance(r, str):
+        return
+    if isinstance(r, list):
+        if counter >= len(r):
+            return
+        r = r[counter]
+    if r[:3] == "'''":
+        if comment:
+            r = '\t/* start ' + blockname + \
+                ' multiline (' + repr(counter) + ') */\n' + r[3:]
+        else:
+            r = r[3:]
+        if r[-3:] == "'''":
+            if comment:
+                r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/'
+            else:
+                r = r[:-3]
+        else:
+            errmess("%s multiline block should end with `'''`: %s\n"
+                    % (blockname, repr(r)))
+    return r
+
+
+def getcallstatement(rout):
+    return getmultilineblock(rout, 'callstatement')
+
+
+def getcallprotoargument(rout, cb_map={}):
+    r = getmultilineblock(rout, 'callprotoargument', comment=0)
+    if r:
+        return r
+    if hascallstatement(rout):
+        outmess(
+            'warning: callstatement is defined without callprotoargument\n')
+        return
+    from .capi_maps import getctype
+    arg_types, arg_types2 = [], []
+    if l_and(isstringfunction, l_not(isfunction_wrap))(rout):
+        arg_types.extend(['char*', 'size_t'])
+    for n in rout['args']:
+        var = rout['vars'][n]
+        if isintent_callback(var):
+            continue
+        if n in cb_map:
+            ctype = cb_map[n] + '_typedef'
+        else:
+            ctype = getctype(var)
+            if l_and(isintent_c, l_or(isscalar, iscomplex))(var):
+                pass
+            elif isstring(var):
+                pass
+            else:
+                ctype = ctype + '*'
+            if isstring(var) or isarrayofstrings(var):
+                arg_types2.append('size_t')
+        arg_types.append(ctype)
+
+    proto_args = ','.join(arg_types + arg_types2)
+    if not proto_args:
+        proto_args = 'void'
+    return proto_args
+
+
+def getusercode(rout):
+    return getmultilineblock(rout, 'usercode')
+
+
+def getusercode1(rout):
+    return getmultilineblock(rout, 'usercode', counter=1)
+
+
+def getpymethoddef(rout):
+    return getmultilineblock(rout, 'pymethoddef')
+
+
+def getargs(rout):
+    sortargs, args = [], []
+    if 'args' in rout:
+        args = rout['args']
+        if 'sortvars' in rout:
+            for a in rout['sortvars']:
+                if a in args:
+                    sortargs.append(a)
+            for a in args:
+                if a not in sortargs:
+                    sortargs.append(a)
+        else:
+            sortargs = rout['args']
+    return args, sortargs
+
+
+def getargs2(rout):
+    sortargs, args = [], rout.get('args', [])
+    auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])
+               and a not in args]
+    args = auxvars + args
+    if 'sortvars' in rout:
+        for a in rout['sortvars']:
+            if a in args:
+                sortargs.append(a)
+        for a in args:
+            if a not in sortargs:
+                sortargs.append(a)
+    else:
+        sortargs = auxvars + rout['args']
+    return args, sortargs
+
+
+def getrestdoc(rout):
+    if 'f2pymultilines' not in rout:
+        return None
+    k = None
+    if rout['block'] == 'python module':
+        k = rout['block'], rout['name']
+    return rout['f2pymultilines'].get(k, None)
+
+
+def gentitle(name):
+    l = (80 - len(name) - 6) // 2
+    return '/*%s %s %s*/' % (l * '*', name, l * '*')
+
+
+def flatlist(l):
+    if isinstance(l, list):
+        return reduce(lambda x, y, f=flatlist: x + f(y), l, [])
+    return [l]
+
+
+def stripcomma(s):
+    if s and s[-1] == ',':
+        return s[:-1]
+    return s
+
+
+def replace(str, d, defaultsep=''):
+    if isinstance(d, list):
+        return [replace(str, _m, defaultsep) for _m in d]
+    if isinstance(str, list):
+        return [replace(_m, d, defaultsep) for _m in str]
+    for k in 2 * list(d.keys()):
+        if k == 'separatorsfor':
+            continue
+        if 'separatorsfor' in d and k in d['separatorsfor']:
+            sep = d['separatorsfor'][k]
+        else:
+            sep = defaultsep
+        if isinstance(d[k], list):
+            str = str.replace('#%s#' % (k), sep.join(flatlist(d[k])))
+        else:
+            str = str.replace('#%s#' % (k), d[k])
+    return str
+
+
+def dictappend(rd, ar):
+    if isinstance(ar, list):
+        for a in ar:
+            rd = dictappend(rd, a)
+        return rd
+    for k in ar.keys():
+        if k[0] == '_':
+            continue
+        if k in rd:
+            if isinstance(rd[k], str):
+                rd[k] = [rd[k]]
+            if isinstance(rd[k], list):
+                if isinstance(ar[k], list):
+                    rd[k] = rd[k] + ar[k]
+                else:
+                    rd[k].append(ar[k])
+            elif isinstance(rd[k], dict):
+                if isinstance(ar[k], dict):
+                    if k == 'separatorsfor':
+                        for k1 in ar[k].keys():
+                            if k1 not in rd[k]:
+                                rd[k][k1] = ar[k][k1]
+                    else:
+                        rd[k] = dictappend(rd[k], ar[k])
+        else:
+            rd[k] = ar[k]
+    return rd
+
+
+def applyrules(rules, d, var={}):
+    ret = {}
+    if isinstance(rules, list):
+        for r in rules:
+            rr = applyrules(r, d, var)
+            ret = dictappend(ret, rr)
+            if '_break' in rr:
+                break
+        return ret
+    if '_check' in rules and (not rules['_check'](var)):
+        return ret
+    if 'need' in rules:
+        res = applyrules({'needs': rules['need']}, d, var)
+        if 'needs' in res:
+            cfuncs.append_needs(res['needs'])
+
+    for k in rules.keys():
+        if k == 'separatorsfor':
+            ret[k] = rules[k]
+            continue
+        if isinstance(rules[k], str):
+            ret[k] = replace(rules[k], d)
+        elif isinstance(rules[k], list):
+            ret[k] = []
+            for i in rules[k]:
+                ar = applyrules({k: i}, d, var)
+                if k in ar:
+                    ret[k].append(ar[k])
+        elif k[0] == '_':
+            continue
+        elif isinstance(rules[k], dict):
+            ret[k] = []
+            for k1 in rules[k].keys():
+                if isinstance(k1, types.FunctionType) and k1(var):
+                    if isinstance(rules[k][k1], list):
+                        for i in rules[k][k1]:
+                            if isinstance(i, dict):
+                                res = applyrules({'supertext': i}, d, var)
+                                if 'supertext' in res:
+                                    i = res['supertext']
+                                else:
+                                    i = ''
+                            ret[k].append(replace(i, d))
+                    else:
+                        i = rules[k][k1]
+                        if isinstance(i, dict):
+                            res = applyrules({'supertext': i}, d)
+                            if 'supertext' in res:
+                                i = res['supertext']
+                            else:
+                                i = ''
+                        ret[k].append(replace(i, d))
+        else:
+            errmess('applyrules: ignoring rule %s.\n' % repr(rules[k]))
+        if isinstance(ret[k], list):
+            if len(ret[k]) == 1:
+                ret[k] = ret[k][0]
+            if ret[k] == []:
+                del ret[k]
+    return ret
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
new file mode 100644
index 0000000000..28154dc805
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
@@ -0,0 +1,843 @@
+#!/usr/bin/env python2
+"""
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 10:57:33 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.60 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+import copy
+import re
+import os
+import sys
+from .crackfortran import markoutercomma
+from . import cb_rules
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+__all__ = [
+    'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
+    'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
+    'cb_sign2map', 'cb_routsign2map', 'common_sign2map'
+]
+
+
+# Numarray and Numeric users should set this False
+using_newcore = True
+
+depargs = []
+lcb_map = {}
+lcb2_map = {}
+# forced casting: mainly caused by the fact that Python or Numeric
+#                 C/APIs do not support the corresponding C types.
+c2py_map = {'double': 'float',
+            'float': 'float',                          # forced casting
+            'long_double': 'float',                    # forced casting
+            'char': 'int',                             # forced casting
+            'signed_char': 'int',                      # forced casting
+            'unsigned_char': 'int',                    # forced casting
+            'short': 'int',                            # forced casting
+            'unsigned_short': 'int',                   # forced casting
+            'int': 'int',                              # (forced casting)
+            'long': 'int',
+            'long_long': 'long',
+            'unsigned': 'int',                         # forced casting
+            'complex_float': 'complex',                # forced casting
+            'complex_double': 'complex',
+            'complex_long_double': 'complex',          # forced casting
+            'string': 'string',
+            }
+c2capi_map = {'double': 'NPY_DOUBLE',
+              'float': 'NPY_FLOAT',
+              'long_double': 'NPY_DOUBLE',           # forced casting
+              'char': 'NPY_CHAR',
+              'unsigned_char': 'NPY_UBYTE',
+              'signed_char': 'NPY_BYTE',
+              'short': 'NPY_SHORT',
+              'unsigned_short': 'NPY_USHORT',
+              'int': 'NPY_INT',
+              'unsigned': 'NPY_UINT',
+              'long': 'NPY_LONG',
+              'long_long': 'NPY_LONG',                # forced casting
+              'complex_float': 'NPY_CFLOAT',
+              'complex_double': 'NPY_CDOUBLE',
+              'complex_long_double': 'NPY_CDOUBLE',   # forced casting
+              'string': 'NPY_CHAR'}
+
+# These new maps aren't used anyhere yet, but should be by default
+#  unless building numeric or numarray extensions.
+if using_newcore:
+    c2capi_map = {'double': 'NPY_DOUBLE',
+                  'float': 'NPY_FLOAT',
+                  'long_double': 'NPY_LONGDOUBLE',
+                  'char': 'NPY_BYTE',
+                  'unsigned_char': 'NPY_UBYTE',
+                  'signed_char': 'NPY_BYTE',
+                  'short': 'NPY_SHORT',
+                  'unsigned_short': 'NPY_USHORT',
+                  'int': 'NPY_INT',
+                  'unsigned': 'NPY_UINT',
+                  'long': 'NPY_LONG',
+                  'unsigned_long': 'NPY_ULONG',
+                  'long_long': 'NPY_LONGLONG',
+                  'unsigned_long_long': 'NPY_ULONGLONG',
+                  'complex_float': 'NPY_CFLOAT',
+                  'complex_double': 'NPY_CDOUBLE',
+                  'complex_long_double': 'NPY_CDOUBLE',
+                  # f2py 2e is not ready for NPY_STRING (must set itemisize
+                  # etc)
+                  'string': 'NPY_CHAR',
+                  #'string':'NPY_STRING'
+
+                  }
+c2pycode_map = {'double': 'd',
+                'float': 'f',
+                'long_double': 'd',                       # forced casting
+                'char': '1',
+                'signed_char': '1',
+                'unsigned_char': 'b',
+                'short': 's',
+                'unsigned_short': 'w',
+                'int': 'i',
+                'unsigned': 'u',
+                'long': 'l',
+                'long_long': 'L',
+                'complex_float': 'F',
+                'complex_double': 'D',
+                'complex_long_double': 'D',               # forced casting
+                'string': 'c'
+                }
+if using_newcore:
+    c2pycode_map = {'double': 'd',
+                    'float': 'f',
+                    'long_double': 'g',
+                    'char': 'b',
+                    'unsigned_char': 'B',
+                    'signed_char': 'b',
+                    'short': 'h',
+                    'unsigned_short': 'H',
+                    'int': 'i',
+                    'unsigned': 'I',
+                    'long': 'l',
+                    'unsigned_long': 'L',
+                    'long_long': 'q',
+                    'unsigned_long_long': 'Q',
+                    'complex_float': 'F',
+                    'complex_double': 'D',
+                    'complex_long_double': 'G',
+                    'string': 'S'}
+c2buildvalue_map = {'double': 'd',
+                    'float': 'f',
+                    'char': 'b',
+                    'signed_char': 'b',
+                    'short': 'h',
+                    'int': 'i',
+                    'long': 'l',
+                    'long_long': 'L',
+                    'complex_float': 'N',
+                    'complex_double': 'N',
+                    'complex_long_double': 'N',
+                    'string': 'z'}
+
+if sys.version_info[0] >= 3:
+    # Bytes, not Unicode strings
+    c2buildvalue_map['string'] = 'y'
+
+if using_newcore:
+    # c2buildvalue_map=???
+    pass
+
+f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
+                       '12': 'long_double', '16': 'long_double'},
+              'integer': {'': 'int', '1': 'signed_char', '2': 'short',
+                          '4': 'int', '8': 'long_long',
+                          '-1': 'unsigned_char', '-2': 'unsigned_short',
+                          '-4': 'unsigned', '-8': 'unsigned_long_long'},
+              'complex': {'': 'complex_float', '8': 'complex_float',
+                          '16': 'complex_double', '24': 'complex_long_double',
+                          '32': 'complex_long_double'},
+              'complexkind': {'': 'complex_float', '4': 'complex_float',
+                              '8': 'complex_double', '12': 'complex_long_double',
+                              '16': 'complex_long_double'},
+              'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int',
+                          '8': 'long_long'},
+              'double complex': {'': 'complex_double'},
+              'double precision': {'': 'double'},
+              'byte': {'': 'char'},
+              'character': {'': 'string'}
+              }
+
+if os.path.isfile('.f2py_f2cmap'):
+    # User defined additions to f2cmap_all.
+    # .f2py_f2cmap must contain a dictionary of dictionaries, only.  For
+    # example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
+    # interpreted as C 'float'.  This feature is useful for F90/95 users if
+    # they use PARAMETERSs in type specifications.
+    try:
+        outmess('Reading .f2py_f2cmap ...\n')
+        f = open('.f2py_f2cmap', 'r')
+        d = eval(f.read(), {}, {})
+        f.close()
+        for k, d1 in list(d.items()):
+            for k1 in list(d1.keys()):
+                d1[k1.lower()] = d1[k1]
+            d[k.lower()] = d[k]
+        for k in list(d.keys()):
+            if k not in f2cmap_all:
+                f2cmap_all[k] = {}
+            for k1 in list(d[k].keys()):
+                if d[k][k1] in c2py_map:
+                    if k1 in f2cmap_all[k]:
+                        outmess(
+                            "\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n" % (k, k1, f2cmap_all[k][k1], d[k][k1]))
+                    f2cmap_all[k][k1] = d[k][k1]
+                    outmess('\tMapping "%s(kind=%s)" to "%s"\n' %
+                            (k, k1, d[k][k1]))
+                else:
+                    errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n" % (
+                        k, k1, d[k][k1], d[k][k1], list(c2py_map.keys())))
+        outmess('Succesfully applied user defined changes from .f2py_f2cmap\n')
+    except Exception as msg:
+        errmess(
+            'Failed to apply user defined changes from .f2py_f2cmap: %s. Skipping.\n' % (msg))
+
+cformat_map = {'double': '%g',
+               'float': '%g',
+               'long_double': '%Lg',
+               'char': '%d',
+               'signed_char': '%d',
+               'unsigned_char': '%hhu',
+               'short': '%hd',
+               'unsigned_short': '%hu',
+               'int': '%d',
+               'unsigned': '%u',
+               'long': '%ld',
+               'unsigned_long': '%lu',
+               'long_long': '%ld',
+               'complex_float': '(%g,%g)',
+               'complex_double': '(%g,%g)',
+               'complex_long_double': '(%Lg,%Lg)',
+               'string': '%s',
+               }
+
+# Auxiliary functions
+
+
+def getctype(var):
+    """
+    Determines C type
+    """
+    ctype = 'void'
+    if isfunction(var):
+        if 'result' in var:
+            a = var['result']
+        else:
+            a = var['name']
+        if a in var['vars']:
+            return getctype(var['vars'][a])
+        else:
+            errmess('getctype: function %s has no return value?!\n' % a)
+    elif issubroutine(var):
+        return ctype
+    elif 'typespec' in var and var['typespec'].lower() in f2cmap_all:
+        typespec = var['typespec'].lower()
+        f2cmap = f2cmap_all[typespec]
+        ctype = f2cmap['']  # default type
+        if 'kindselector' in var:
+            if '*' in var['kindselector']:
+                try:
+                    ctype = f2cmap[var['kindselector']['*']]
+                except KeyError:
+                    errmess('getctype: "%s %s %s" not supported.\n' %
+                            (var['typespec'], '*', var['kindselector']['*']))
+            elif 'kind' in var['kindselector']:
+                if typespec + 'kind' in f2cmap_all:
+                    f2cmap = f2cmap_all[typespec + 'kind']
+                try:
+                    ctype = f2cmap[var['kindselector']['kind']]
+                except KeyError:
+                    if typespec in f2cmap_all:
+                        f2cmap = f2cmap_all[typespec]
+                    try:
+                        ctype = f2cmap[str(var['kindselector']['kind'])]
+                    except KeyError:
+                        errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="<C typespec>")) in %s/.f2py_f2cmap file).\n'
+                                % (typespec, var['kindselector']['kind'], ctype,
+                                   typespec, var['kindselector']['kind'], os.getcwd()))
+
+    else:
+        if not isexternal(var):
+            errmess(
+                'getctype: No C-type found in "%s", assuming void.\n' % var)
+    return ctype
+
+
+def getstrlength(var):
+    if isstringfunction(var):
+        if 'result' in var:
+            a = var['result']
+        else:
+            a = var['name']
+        if a in var['vars']:
+            return getstrlength(var['vars'][a])
+        else:
+            errmess('getstrlength: function %s has no return value?!\n' % a)
+    if not isstring(var):
+        errmess(
+            'getstrlength: expected a signature of a string but got: %s\n' % (repr(var)))
+    len = '1'
+    if 'charselector' in var:
+        a = var['charselector']
+        if '*' in a:
+            len = a['*']
+        elif 'len' in a:
+            len = a['len']
+    if re.match(r'\(\s*([*]|[:])\s*\)', len) or re.match(r'([*]|[:])', len):
+        if isintent_hide(var):
+            errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
+                repr(var)))
+        len = '-1'
+    return len
+
+
+def getarrdims(a, var, verbose=0):
+    global depargs
+    ret = {}
+    if isstring(var) and not isarray(var):
+        ret['dims'] = getstrlength(var)
+        ret['size'] = ret['dims']
+        ret['rank'] = '1'
+    elif isscalar(var):
+        ret['size'] = '1'
+        ret['rank'] = '0'
+        ret['dims'] = ''
+    elif isarray(var):
+        dim = copy.copy(var['dimension'])
+        ret['size'] = '*'.join(dim)
+        try:
+            ret['size'] = repr(eval(ret['size']))
+        except:
+            pass
+        ret['dims'] = ','.join(dim)
+        ret['rank'] = repr(len(dim))
+        ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1]
+        for i in range(len(dim)):  # solve dim for dependecies
+            v = []
+            if dim[i] in depargs:
+                v = [dim[i]]
+            else:
+                for va in depargs:
+                    if re.match(r'.*?\b%s\b.*' % va, dim[i]):
+                        v.append(va)
+            for va in v:
+                if depargs.index(va) > depargs.index(a):
+                    dim[i] = '*'
+                    break
+        ret['setdims'], i = '', -1
+        for d in dim:
+            i = i + 1
+            if d not in ['*', ':', '(*)', '(:)']:
+                ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['setdims'], i, d)
+        if ret['setdims']:
+            ret['setdims'] = ret['setdims'][:-1]
+        ret['cbsetdims'], i = '', -1
+        for d in var['dimension']:
+            i = i + 1
+            if d not in ['*', ':', '(*)', '(:)']:
+                ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['cbsetdims'], i, d)
+            elif isintent_in(var):
+                outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n'
+                        % (d))
+                ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['cbsetdims'], i, 0)
+            elif verbose:
+                errmess(
+                    'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d)))
+        if ret['cbsetdims']:
+            ret['cbsetdims'] = ret['cbsetdims'][:-1]
+#         if not isintent_c(var):
+#             var['dimension'].reverse()
+    return ret
+
+
+def getpydocsign(a, var):
+    global lcb_map
+    if isfunction(var):
+        if 'result' in var:
+            af = var['result']
+        else:
+            af = var['name']
+        if af in var['vars']:
+            return getpydocsign(af, var['vars'][af])
+        else:
+            errmess('getctype: function %s has no return value?!\n' % af)
+        return '', ''
+    sig, sigout = a, a
+    opt = ''
+    if isintent_in(var):
+        opt = 'input'
+    elif isintent_inout(var):
+        opt = 'in/output'
+    out_a = a
+    if isintent_out(var):
+        for k in var['intent']:
+            if k[:4] == 'out=':
+                out_a = k[4:]
+                break
+    init = ''
+    ctype = getctype(var)
+
+    if hasinitvalue(var):
+        init, showinit = getinit(a, var)
+        init = ', optional\\n    Default: %s' % showinit
+    if isscalar(var):
+        if isintent_inout(var):
+            sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype],
+                                                         c2pycode_map[ctype], init)
+        else:
+            sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
+        sigout = '%s : %s' % (out_a, c2py_map[ctype])
+    elif isstring(var):
+        if isintent_inout(var):
+            sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % (
+                a, opt, getstrlength(var), init)
+        else:
+            sig = '%s : %s string(len=%s)%s' % (
+                a, opt, getstrlength(var), init)
+        sigout = '%s : string(len=%s)' % (out_a, getstrlength(var))
+    elif isarray(var):
+        dim = var['dimension']
+        rank = repr(len(dim))
+        sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank,
+                                                                    c2pycode_map[
+                                                                        ctype],
+                                                                    ','.join(dim), init)
+        if a == out_a:
+            sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\
+                % (a, rank, c2pycode_map[ctype], ','.join(dim))
+        else:
+            sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\
+                % (out_a, rank, c2pycode_map[ctype], ','.join(dim), a)
+    elif isexternal(var):
+        ua = ''
+        if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]:
+            ua = lcb2_map[lcb_map[a]]['argname']
+            if not ua == a:
+                ua = ' => %s' % ua
+            else:
+                ua = ''
+        sig = '%s : call-back function%s' % (a, ua)
+        sigout = sig
+    else:
+        errmess(
+            'getpydocsign: Could not resolve docsignature for "%s".\\n' % a)
+    return sig, sigout
+
+
+def getarrdocsign(a, var):
+    ctype = getctype(var)
+    if isstring(var) and (not isarray(var)):
+        sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a,
+                                                           getstrlength(var))
+    elif isscalar(var):
+        sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype],
+                                                c2pycode_map[ctype],)
+    elif isarray(var):
+        dim = var['dimension']
+        rank = repr(len(dim))
+        sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank,
+                                                               c2pycode_map[
+                                                                   ctype],
+                                                               ','.join(dim))
+    return sig
+
+
+def getinit(a, var):
+    if isstring(var):
+        init, showinit = '""', "''"
+    else:
+        init, showinit = '', ''
+    if hasinitvalue(var):
+        init = var['=']
+        showinit = init
+        if iscomplex(var) or iscomplexarray(var):
+            ret = {}
+
+            try:
+                v = var["="]
+                if ',' in v:
+                    ret['init.r'], ret['init.i'] = markoutercomma(
+                        v[1:-1]).split('@,@')
+                else:
+                    v = eval(v, {}, {})
+                    ret['init.r'], ret['init.i'] = str(v.real), str(v.imag)
+            except:
+                raise ValueError(
+                    'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a))
+            if isarray(var):
+                init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % (
+                    ret['init.r'], ret['init.i'])
+        elif isstring(var):
+            if not init:
+                init, showinit = '""', "''"
+            if init[0] == "'":
+                init = '"%s"' % (init[1:-1].replace('"', '\\"'))
+            if init[0] == '"':
+                showinit = "'%s'" % (init[1:-1])
+    return init, showinit
+
+
+def sign2map(a, var):
+    """
+    varname,ctype,atype
+    init,init.r,init.i,pytype
+    vardebuginfo,vardebugshowvalue,varshowvalue
+    varrfromat
+    intent
+    """
+    global lcb_map, cb_map
+    out_a = a
+    if isintent_out(var):
+        for k in var['intent']:
+            if k[:4] == 'out=':
+                out_a = k[4:]
+                break
+    ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)}
+    intent_flags = []
+    for f, s in isintent_dict.items():
+        if f(var):
+            intent_flags.append('F2PY_%s' % s)
+    if intent_flags:
+        # XXX: Evaluate intent_flags here.
+        ret['intent'] = '|'.join(intent_flags)
+    else:
+        ret['intent'] = 'F2PY_INTENT_IN'
+    if isarray(var):
+        ret['varrformat'] = 'N'
+    elif ret['ctype'] in c2buildvalue_map:
+        ret['varrformat'] = c2buildvalue_map[ret['ctype']]
+    else:
+        ret['varrformat'] = 'O'
+    ret['init'], ret['showinit'] = getinit(a, var)
+    if hasinitvalue(var) and iscomplex(var) and not isarray(var):
+        ret['init.r'], ret['init.i'] = markoutercomma(
+            ret['init'][1:-1]).split('@,@')
+    if isexternal(var):
+        ret['cbnamekey'] = a
+        if a in lcb_map:
+            ret['cbname'] = lcb_map[a]
+            ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs']
+            ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs']
+            ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr']
+            ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr']
+        else:
+            ret['cbname'] = a
+            errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % (
+                a, list(lcb_map.keys())))
+    if isstring(var):
+        ret['length'] = getstrlength(var)
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+        dim = copy.copy(var['dimension'])
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    # Debug info
+    if debugcapi(var):
+        il = [isintent_in, 'input', isintent_out, 'output',
+              isintent_inout, 'inoutput', isrequired, 'required',
+              isoptional, 'optional', isintent_hide, 'hidden',
+              iscomplex, 'complex scalar',
+              l_and(isscalar, l_not(iscomplex)), 'scalar',
+              isstring, 'string', isarray, 'array',
+              iscomplexarray, 'complex array', isstringarray, 'string array',
+              iscomplexfunction, 'complex function',
+              l_and(isfunction, l_not(iscomplexfunction)), 'function',
+              isexternal, 'callback',
+              isintent_callback, 'callback',
+              isintent_aux, 'auxiliary',
+              ]
+        rl = []
+        for i in range(0, len(il), 2):
+            if il[i](var):
+                rl.append(il[i + 1])
+        if isstring(var):
+            rl.append('slen(%s)=%s' % (a, ret['length']))
+        if isarray(var):
+            ddim = ','.join(
+                map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim))
+            rl.append('dims(%s)' % ddim)
+        if isexternal(var):
+            ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % (
+                a, ret['cbname'], ','.join(rl))
+        else:
+            ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % (
+                ret['ctype'], a, ret['showinit'], ','.join(rl))
+        if isscalar(var):
+            if ret['ctype'] in cformat_map:
+                ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % (
+                    a, cformat_map[ret['ctype']])
+        if isstring(var):
+            ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
+                a, a)
+        if isexternal(var):
+            ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a)
+    if ret['ctype'] in cformat_map:
+        ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']])
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isstring(var):
+        ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a)
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+    return ret
+
+
+def routsign2map(rout):
+    """
+    name,NAME,begintitle,endtitle
+    rname,ctype,rformat
+    routdebugshowvalue
+    """
+    global lcb_map
+    name = rout['name']
+    fname = getfortranname(rout)
+    ret = {'name': name,
+           'texname': name.replace('_', '\\_'),
+           'name_lower': name.lower(),
+           'NAME': name.upper(),
+           'begintitle': gentitle(name),
+           'endtitle': gentitle('end of %s' % name),
+           'fortranname': fname,
+           'FORTRANNAME': fname.upper(),
+           'callstatement': getcallstatement(rout) or '',
+           'usercode': getusercode(rout) or '',
+           'usercode1': getusercode1(rout) or '',
+           }
+    if '_' in fname:
+        ret['F_FUNC'] = 'F_FUNC_US'
+    else:
+        ret['F_FUNC'] = 'F_FUNC'
+    if '_' in name:
+        ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US'
+    else:
+        ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC'
+    lcb_map = {}
+    if 'use' in rout:
+        for u in rout['use'].keys():
+            if u in cb_rules.cb_map:
+                for un in cb_rules.cb_map[u]:
+                    ln = un[0]
+                    if 'map' in rout['use'][u]:
+                        for k in rout['use'][u]['map'].keys():
+                            if rout['use'][u]['map'][k] == un[0]:
+                                ln = k
+                                break
+                    lcb_map[ln] = un[1]
+    elif 'externals' in rout and rout['externals']:
+        errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % (
+            ret['name'], repr(rout['externals'])))
+    ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or ''
+    if isfunction(rout):
+        if 'result' in rout:
+            a = rout['result']
+        else:
+            a = rout['name']
+        ret['rname'] = a
+        ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
+        ret['ctype'] = getctype(rout['vars'][a])
+        if hasresultnote(rout):
+            ret['resultnote'] = rout['vars'][a]['note']
+            rout['vars'][a]['note'] = ['See elsewhere.']
+        if ret['ctype'] in c2buildvalue_map:
+            ret['rformat'] = c2buildvalue_map[ret['ctype']]
+        else:
+            ret['rformat'] = 'O'
+            errmess('routsign2map: no c2buildvalue key for type %s\n' %
+                    (repr(ret['ctype'])))
+        if debugcapi(rout):
+            if ret['ctype'] in cformat_map:
+                ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % (
+                    a, cformat_map[ret['ctype']])
+            if isstringfunction(rout):
+                ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
+                    a, a)
+        if isstringfunction(rout):
+            ret['rlength'] = getstrlength(rout['vars'][a])
+            if ret['rlength'] == '-1':
+                errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % (
+                    repr(rout['name'])))
+                ret['rlength'] = '10'
+    if hasnote(rout):
+        ret['note'] = rout['note']
+        rout['note'] = ['See elsewhere.']
+    return ret
+
+
+def modsign2map(m):
+    """
+    modulename
+    """
+    if ismodule(m):
+        ret = {'f90modulename': m['name'],
+               'F90MODULENAME': m['name'].upper(),
+               'texf90modulename': m['name'].replace('_', '\\_')}
+    else:
+        ret = {'modulename': m['name'],
+               'MODULENAME': m['name'].upper(),
+               'texmodulename': m['name'].replace('_', '\\_')}
+    ret['restdoc'] = getrestdoc(m) or []
+    if hasnote(m):
+        ret['note'] = m['note']
+    ret['usercode'] = getusercode(m) or ''
+    ret['usercode1'] = getusercode1(m) or ''
+    if m['body']:
+        ret['interface_usercode'] = getusercode(m['body'][0]) or ''
+    else:
+        ret['interface_usercode'] = ''
+    ret['pymethoddef'] = getpymethoddef(m) or ''
+    if 'coutput' in m:
+        ret['coutput'] = m['coutput']
+    if 'f2py_wrapper_output' in m:
+        ret['f2py_wrapper_output'] = m['f2py_wrapper_output']
+    return ret
+
+
+def cb_sign2map(a, var, index=None):
+    ret = {'varname': a}
+    if index is None or 1:  # disable 7712 patch
+        ret['varname_i'] = ret['varname']
+    else:
+        ret['varname_i'] = ret['varname'] + '_' + str(index)
+    ret['ctype'] = getctype(var)
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+        var['note'] = ['See elsewhere.']
+    return ret
+
+
+def cb_routsign2map(rout, um):
+    """
+    name,begintitle,endtitle,argname
+    ctype,rctype,maxnofargs,nofoptargs,returncptr
+    """
+    ret = {'name': 'cb_%s_in_%s' % (rout['name'], um),
+           'returncptr': ''}
+    if isintent_callback(rout):
+        if '_' in rout['name']:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        ret['callbackname'] = '%s(%s,%s)' \
+                              % (F_FUNC,
+                                 rout['name'].lower(),
+                                 rout['name'].upper(),
+                                 )
+        ret['static'] = 'extern'
+    else:
+        ret['callbackname'] = ret['name']
+        ret['static'] = 'static'
+    ret['argname'] = rout['name']
+    ret['begintitle'] = gentitle(ret['name'])
+    ret['endtitle'] = gentitle('end of %s' % ret['name'])
+    ret['ctype'] = getctype(rout)
+    ret['rctype'] = 'void'
+    if ret['ctype'] == 'string':
+        ret['rctype'] = 'void'
+    else:
+        ret['rctype'] = ret['ctype']
+    if ret['rctype'] != 'void':
+        if iscomplexfunction(rout):
+            ret['returncptr'] = """
+#ifdef F2PY_CB_RETURNCOMPLEX
+return_value=
+#endif
+"""
+        else:
+            ret['returncptr'] = 'return_value='
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isstringfunction(rout):
+        ret['strlength'] = getstrlength(rout)
+    if isfunction(rout):
+        if 'result' in rout:
+            a = rout['result']
+        else:
+            a = rout['name']
+        if hasnote(rout['vars'][a]):
+            ret['note'] = rout['vars'][a]['note']
+            rout['vars'][a]['note'] = ['See elsewhere.']
+        ret['rname'] = a
+        ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
+        if iscomplexfunction(rout):
+            ret['rctype'] = """
+#ifdef F2PY_CB_RETURNCOMPLEX
+#ctype#
+#else
+void
+#endif
+"""
+    else:
+        if hasnote(rout):
+            ret['note'] = rout['note']
+            rout['note'] = ['See elsewhere.']
+    nofargs = 0
+    nofoptargs = 0
+    if 'args' in rout and 'vars' in rout:
+        for a in rout['args']:
+            var = rout['vars'][a]
+            if l_or(isintent_in, isintent_inout)(var):
+                nofargs = nofargs + 1
+                if isoptional(var):
+                    nofoptargs = nofoptargs + 1
+    ret['maxnofargs'] = repr(nofargs)
+    ret['nofoptargs'] = repr(nofoptargs)
+    if hasnote(rout) and isfunction(rout) and 'result' in rout:
+        ret['routnote'] = rout['note']
+        rout['note'] = ['See elsewhere.']
+    return ret
+
+
+def common_sign2map(a, var):  # obsolute
+    ret = {'varname': a, 'ctype': getctype(var)}
+    if isstringarray(var):
+        ret['ctype'] = 'char'
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+    elif isstring(var):
+        ret['size'] = getstrlength(var)
+        ret['rank'] = '1'
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+        var['note'] = ['See elsewhere.']
+    # for strings this returns 0-rank but actually is 1-rank
+    ret['arrdocstr'] = getarrdocsign(a, var)
+    return ret
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
new file mode 100644
index 0000000000..e2b9c1efd9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
@@ -0,0 +1,554 @@
+#!/usr/bin/env python2
+"""
+
+Build call-back mechanism for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/07/20 11:27:58 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import __version__
+from .auxfuncs import (
+    applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray,
+    iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c,
+    isintent_hide, isintent_in, isintent_inout, isintent_nothide,
+    isintent_out, isoptional, isrequired, isscalar, isstring,
+    isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace,
+    stripcomma, throw_error
+)
+from . import cfuncs
+
+f2py_version = __version__.version
+
+
+################## Rules for callback function ##############
+
+cb_routine_rules = {
+    'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
+    'body': """
+#begintitle#
+PyObject *#name#_capi = NULL;/*was Py_None*/
+PyTupleObject *#name#_args_capi = NULL;
+int #name#_nofargs = 0;
+jmp_buf #name#_jmpbuf;
+/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
+#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
+\tPyTupleObject *capi_arglist = #name#_args_capi;
+\tPyObject *capi_return = NULL;
+\tPyObject *capi_tmp = NULL;
+\tint capi_j,capi_i = 0;
+\tint capi_longjmp_ok = 1;
+#decl#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_start_clock();
+#endif
+\tCFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
+\tCFUNCSMESSPY(\"cb:#name#_capi=\",#name#_capi);
+\tif (#name#_capi==NULL) {
+\t\tcapi_longjmp_ok = 0;
+\t\t#name#_capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
+\t}
+\tif (#name#_capi==NULL) {
+\t\tPyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
+\t\tgoto capi_fail;
+\t}
+\tif (F2PyCapsule_Check(#name#_capi)) {
+\t#name#_typedef #name#_cptr;
+\t#name#_cptr = F2PyCapsule_AsVoidPtr(#name#_capi);
+\t#returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
+\t#return#
+\t}
+\tif (capi_arglist==NULL) {
+\t\tcapi_longjmp_ok = 0;
+\t\tcapi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
+\t\tif (capi_tmp) {
+\t\t\tcapi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
+\t\t\tif (capi_arglist==NULL) {
+\t\t\t\tPyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
+\t\t\t\tgoto capi_fail;
+\t\t\t}
+\t\t} else {
+\t\t\tPyErr_Clear();
+\t\t\tcapi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
+\t\t}
+\t}
+\tif (capi_arglist == NULL) {
+\t\tPyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
+\t\tgoto capi_fail;
+\t}
+#setdims#
+#pyobjfrom#
+\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
+\tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_start_call_clock();
+#endif
+\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist);
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_stop_call_clock();
+#endif
+\tCFUNCSMESSPY(\"cb:capi_return=\",capi_return);
+\tif (capi_return == NULL) {
+\t\tfprintf(stderr,\"capi_return is NULL\\n\");
+\t\tgoto capi_fail;
+\t}
+\tif (capi_return == Py_None) {
+\t\tPy_DECREF(capi_return);
+\t\tcapi_return = Py_BuildValue(\"()\");
+\t}
+\telse if (!PyTuple_Check(capi_return)) {
+\t\tcapi_return = Py_BuildValue(\"(N)\",capi_return);
+\t}
+\tcapi_j = PyTuple_Size(capi_return);
+\tcapi_i = 0;
+#frompyobj#
+\tCFUNCSMESS(\"cb:#name#:successful\\n\");
+\tPy_DECREF(capi_return);
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_stop_clock();
+#endif
+\tgoto capi_return_pt;
+capi_fail:
+\tfprintf(stderr,\"Call-back #name# failed.\\n\");
+\tPy_XDECREF(capi_return);
+\tif (capi_longjmp_ok)
+\t\tlongjmp(#name#_jmpbuf,-1);
+capi_return_pt:
+\t;
+#return#
+}
+#endtitle#
+""",
+    'need': ['setjmp.h', 'CFUNCSMESS'],
+    'maxnofargs': '#maxnofargs#',
+    'nofoptargs': '#nofoptargs#',
+    'docstr': """\
+\tdef #argname#(#docsignature#): return #docreturn#\\n\\
+#docstrsigns#""",
+    'latexdocstr': """
+{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
+#routnote#
+
+#latexdocstrsigns#""",
+    'docstrshort': 'def #argname#(#docsignature#): return #docreturn#'
+}
+cb_rout_rules = [
+    {  # Init
+        'separatorsfor': {'decl': '\n',
+                          'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
+                          'args_td': ',', 'optargs_td': '',
+                          'args_nm': ',', 'optargs_nm': '',
+                          'frompyobj': '\n', 'setdims': '\n',
+                          'docstrsigns': '\\n"\n"',
+                          'latexdocstrsigns': '\n',
+                          'latexdocstrreq': '\n', 'latexdocstropt': '\n',
+                          'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
+                          },
+        'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
+        'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
+        'args_td': [], 'optargs_td': '', 'strarglens_td': '',
+        'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
+        'noargs': '',
+        'setdims': '/*setdims*/',
+        'docstrsigns': '', 'latexdocstrsigns': '',
+        'docstrreq': '\tRequired arguments:',
+        'docstropt': '\tOptional arguments:',
+        'docstrout': '\tReturn objects:',
+        'docstrcbs': '\tCall-back functions:',
+        'docreturn': '', 'docsign': '', 'docsignopt': '',
+        'latexdocstrreq': '\\noindent Required arguments:',
+        'latexdocstropt': '\\noindent Optional arguments:',
+        'latexdocstrout': '\\noindent Return objects:',
+        'latexdocstrcbs': '\\noindent Call-back functions:',
+        'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
+    }, {  # Function
+        'decl': '\t#ctype# return_value;',
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
+                      '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");',
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#.\\n",return_value);'}
+                      ],
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
+        'return': '\treturn return_value;',
+        '_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
+    },
+    {  # String function
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
+        'args': '#ctype# return_value,int return_value_len',
+        'args_nm': 'return_value,&return_value_len',
+        'args_td': '#ctype# ,int',
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->\\"");'},
+                      """\tif (capi_j>capi_i)
+\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""",
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
+                      ],
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
+                 'string.h', 'GETSTRFROMPYTUPLE'],
+        'return': 'return;',
+        '_check': isstringfunction
+    },
+    {  # Complex function
+        'optargs': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+#ctype# *return_value
+#endif
+""",
+        'optargs_nm': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+return_value
+#endif
+""",
+        'optargs_td': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+#ctype# *
+#endif
+""",
+        'decl': """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\t#ctype# return_value;
+#endif
+""",
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
+                      """\
+\tif (capi_j>capi_i)
+#ifdef F2PY_CB_RETURNCOMPLEX
+\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
+#else
+\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
+#endif
+""",
+                      {debugcapi: """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\tfprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
+#else
+\tfprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
+#endif
+
+"""}
+                      ],
+        'return': """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\treturn return_value;
+#else
+\treturn;
+#endif
+""",
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
+                 'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
+        '_check': iscomplexfunction
+    },
+    {'docstrout': '\t\t#pydocsignout#',
+     'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                        {hasnote: '--- #note#'}],
+     'docreturn': '#rname#,',
+     '_check': isfunction},
+    {'_check': issubroutine, 'return': 'return;'}
+]
+
+cb_arg_rules = [
+    {  # Doc
+        'docstropt': {l_and(isoptional, isintent_nothide): '\t\t#pydocsign#'},
+        'docstrreq': {l_and(isrequired, isintent_nothide): '\t\t#pydocsign#'},
+        'docstrout': {isintent_out: '\t\t#pydocsignout#'},
+        'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                                          {l_and(hasnote, isintent_hide): '--- #note#',
+                                           l_and(hasnote, isintent_nothide): '--- See above.'}]},
+        'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'},
+        'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'},
+        'depend': ''
+    },
+    {
+        'args': {
+            l_and(isscalar, isintent_c): '#ctype# #varname_i#',
+            l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi',
+            isarray: '#ctype# *#varname_i#',
+            isstring: '#ctype# #varname_i#'
+        },
+        'args_nm': {
+            l_and(isscalar, isintent_c): '#varname_i#',
+            l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi',
+            isarray: '#varname_i#',
+            isstring: '#varname_i#'
+        },
+        'args_td': {
+            l_and(isscalar, isintent_c): '#ctype#',
+            l_and(isscalar, l_not(isintent_c)): '#ctype# *',
+            isarray: '#ctype# *',
+            isstring: '#ctype#'
+        },
+        # untested with multiple args
+        'strarglens': {isstring: ',int #varname_i#_cb_len'},
+        'strarglens_td': {isstring: ',int'},  # untested with multiple args
+        # untested with multiple args
+        'strarglens_nm': {isstring: ',#varname_i#_cb_len'},
+    },
+    {  # Scalars
+        'decl': {l_not(isintent_c): '\t#ctype# #varname_i#=(*#varname_i#_cb_capi);'},
+        'error': {l_and(isintent_c, isintent_out,
+                        throw_error('intent(c,out) is forbidden for callback scalar arguments')):
+                  ''},
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
+                      {isintent_out:
+                       '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
+                      {l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
+                      {l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
+                      {l_and(debugcapi, l_and(iscomplex, isintent_c)):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
+                      {l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
+                      ],
+        'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
+                 {debugcapi: 'CFUNCSMESS'}],
+        '_check': isscalar
+    }, {
+        'pyobjfrom': [{isintent_in: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname_i#)))
+\t\t\tgoto capi_fail;"""},
+                      {isintent_inout: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
+\t\t\tgoto capi_fail;"""}],
+        'need': [{isintent_in: 'pyobj_from_#ctype#1'},
+                 {isintent_inout: 'pyarr_from_p_#ctype#1'},
+                 {iscomplex: '#ctype#'}],
+        '_check': l_and(isscalar, isintent_nothide),
+        '_optional': ''
+    }, {  # String
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->\\"");'},
+                      """\tif (capi_j>capi_i)
+\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
+                      ],
+        'need': ['#ctype#', 'GETSTRFROMPYTUPLE',
+                 {debugcapi: 'CFUNCSMESS'}, 'string.h'],
+        '_check': l_and(isstring, isintent_out)
+    }, {
+        'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'},
+                      {isintent_in: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
+\t\t\tgoto capi_fail;"""},
+                      {isintent_inout: """\
+\tif (#name#_nofargs>capi_i) {
+\t\tint #varname_i#_cb_dims[] = {#varname_i#_cb_len};
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
+\t\t\tgoto capi_fail;
+\t}"""}],
+        'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
+                 {isintent_inout: 'pyarr_from_p_#ctype#1'}],
+        '_check': l_and(isstring, isintent_nothide),
+        '_optional': ''
+    },
+    # Array ...
+    {
+        'decl': '\tnpy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
+        'setdims': '\t#cbsetdims#;',
+        '_check': isarray,
+        '_depend': ''
+    },
+    {
+        'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'},
+                      {isintent_c: """\
+\tif (#name#_nofargs>capi_i) {
+\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_CARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
+""",
+                       l_not(isintent_c): """\
+\tif (#name#_nofargs>capi_i) {
+\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_FARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
+""",
+                       },
+                      """
+\t\tif (tmp_arr==NULL)
+\t\t\tgoto capi_fail;
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,(PyObject *)tmp_arr))
+\t\t\tgoto capi_fail;
+}"""],
+        '_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
+        '_optional': '',
+    }, {
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
+                      """\tif (capi_j>capi_i) {
+\t\tPyArrayObject *rv_cb_arr = NULL;
+\t\tif ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
+\t\trv_cb_arr =  array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
+                      {isintent_c: '|F2PY_INTENT_C'},
+                      """,capi_tmp);
+\t\tif (rv_cb_arr == NULL) {
+\t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\");
+\t\t\tgoto capi_fail;
+\t\t}
+\t\tMEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr));
+\t\tif (capi_tmp != (PyObject *)rv_cb_arr) {
+\t\t\tPy_DECREF(rv_cb_arr);
+\t\t}
+\t}""",
+                      {debugcapi: '\tfprintf(stderr,"<-.\\n");'},
+                      ],
+        'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}],
+        '_check': l_and(isarray, isintent_out)
+    }, {
+        'docreturn': '#varname#,',
+        '_check': isintent_out
+    }
+]
+
+################## Build call-back module #############
+cb_map = {}
+
+
+def buildcallbacks(m):
+    global cb_map
+    cb_map[m['name']] = []
+    for bi in m['body']:
+        if bi['block'] == 'interface':
+            for b in bi['body']:
+                if b:
+                    buildcallback(b, m['name'])
+                else:
+                    errmess('warning: empty body for %s\n' % (m['name']))
+
+
+def buildcallback(rout, um):
+    global cb_map
+    from . import capi_maps
+
+    outmess('\tConstructing call-back function "cb_%s_in_%s"\n' %
+            (rout['name'], um))
+    args, depargs = getargs(rout)
+    capi_maps.depargs = depargs
+    var = rout['vars']
+    vrd = capi_maps.cb_routsign2map(rout, um)
+    rd = dictappend({}, vrd)
+    cb_map[um].append([rout['name'], rd['name']])
+    for r in cb_rout_rules:
+        if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
+            ar = applyrules(r, vrd, rout)
+            rd = dictappend(rd, ar)
+    savevrd = {}
+    for i, a in enumerate(args):
+        vrd = capi_maps.cb_sign2map(a, var[a], index=i)
+        savevrd[a] = vrd
+        for r in cb_arg_rules:
+            if '_depend' in r:
+                continue
+            if '_optional' in r and isoptional(var[a]):
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in args:
+        vrd = savevrd[a]
+        for r in cb_arg_rules:
+            if '_depend' in r:
+                continue
+            if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in depargs:
+        vrd = savevrd[a]
+        for r in cb_arg_rules:
+            if '_depend' not in r:
+                continue
+            if '_optional' in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    if 'args' in rd and 'optargs' in rd:
+        if isinstance(rd['optargs'], list):
+            rd['optargs'] = rd['optargs'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+            rd['optargs_nm'] = rd['optargs_nm'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+            rd['optargs_td'] = rd['optargs_td'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+    if isinstance(rd['docreturn'], list):
+        rd['docreturn'] = stripcomma(
+            replace('#docreturn#', {'docreturn': rd['docreturn']}))
+    optargs = stripcomma(replace('#docsignopt#',
+                                 {'docsignopt': rd['docsignopt']}
+                                 ))
+    if optargs == '':
+        rd['docsignature'] = stripcomma(
+            replace('#docsign#', {'docsign': rd['docsign']}))
+    else:
+        rd['docsignature'] = replace('#docsign#[#docsignopt#]',
+                                     {'docsign': rd['docsign'],
+                                      'docsignopt': optargs,
+                                      })
+    rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_')
+    rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ')
+    rd['docstrsigns'] = []
+    rd['latexdocstrsigns'] = []
+    for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
+        if k in rd and isinstance(rd[k], list):
+            rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
+        k = 'latex' + k
+        if k in rd and isinstance(rd[k], list):
+            rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
+                ['\\begin{description}'] + rd[k][1:] +\
+                ['\\end{description}']
+    if 'args' not in rd:
+        rd['args'] = ''
+        rd['args_td'] = ''
+        rd['args_nm'] = ''
+    if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
+        rd['noargs'] = 'void'
+
+    ar = applyrules(cb_routine_rules, rd)
+    cfuncs.callbacks[rd['name']] = ar['body']
+    if isinstance(ar['need'], str):
+        ar['need'] = [ar['need']]
+
+    if 'need' in rd:
+        for t in cfuncs.typedefs.keys():
+            if t in rd['need']:
+                ar['need'].append(t)
+
+    cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs']
+    ar['need'].append(rd['name'] + '_typedef')
+    cfuncs.needs[rd['name']] = ar['need']
+
+    capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'],
+                                      'nofoptargs': ar['nofoptargs'],
+                                      'docstr': ar['docstr'],
+                                      'latexdocstr': ar['latexdocstr'],
+                                      'argname': rd['argname']
+                                      }
+    outmess('\t  %s\n' % (ar['docstrshort']))
+    return
+################## Build call-back function #############
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
new file mode 100644
index 0000000000..1d426bad37
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
@@ -0,0 +1,1261 @@
+#!/usr/bin/env python2
+"""
+
+C declarations, CPP macros, and C functions for f2py2e.
+Only required declarations/macros/functions will be used.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 11:42:34 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import copy
+
+from . import __version__
+
+f2py_version = __version__.version
+errmess = sys.stderr.write
+
+##################### Definitions ##################
+
+outneeds = {'includes0': [], 'includes': [], 'typedefs': [], 'typedefs_generated': [],
+            'userincludes': [],
+            'cppmacros': [], 'cfuncs': [], 'callbacks': [], 'f90modhooks': [],
+            'commonhooks': []}
+needs = {}
+includes0 = {'includes0': '/*need_includes0*/'}
+includes = {'includes': '/*need_includes*/'}
+userincludes = {'userincludes': '/*need_userincludes*/'}
+typedefs = {'typedefs': '/*need_typedefs*/'}
+typedefs_generated = {'typedefs_generated': '/*need_typedefs_generated*/'}
+cppmacros = {'cppmacros': '/*need_cppmacros*/'}
+cfuncs = {'cfuncs': '/*need_cfuncs*/'}
+callbacks = {'callbacks': '/*need_callbacks*/'}
+f90modhooks = {'f90modhooks': '/*need_f90modhooks*/',
+               'initf90modhooksstatic': '/*initf90modhooksstatic*/',
+               'initf90modhooksdynamic': '/*initf90modhooksdynamic*/',
+               }
+commonhooks = {'commonhooks': '/*need_commonhooks*/',
+               'initcommonhooks': '/*need_initcommonhooks*/',
+               }
+
+############ Includes ###################
+
+includes0['math.h'] = '#include <math.h>'
+includes0['string.h'] = '#include <string.h>'
+includes0['setjmp.h'] = '#include <setjmp.h>'
+
+includes['Python.h'] = '#include "Python.h"'
+needs['arrayobject.h'] = ['Python.h']
+includes['arrayobject.h'] = '''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
+#include "arrayobject.h"'''
+
+includes['arrayobject.h'] = '#include "fortranobject.h"'
+includes['stdarg.h'] = '#include <stdarg.h>'
+
+############# Type definitions ###############
+
+typedefs['unsigned_char'] = 'typedef unsigned char unsigned_char;'
+typedefs['unsigned_short'] = 'typedef unsigned short unsigned_short;'
+typedefs['unsigned_long'] = 'typedef unsigned long unsigned_long;'
+typedefs['signed_char'] = 'typedef signed char signed_char;'
+typedefs['long_long'] = """\
+#ifdef _WIN32
+typedef __int64 long_long;
+#else
+typedef long long long_long;
+typedef unsigned long long unsigned_long_long;
+#endif
+"""
+typedefs['unsigned_long_long'] = """\
+#ifdef _WIN32
+typedef __uint64 long_long;
+#else
+typedef unsigned long long unsigned_long_long;
+#endif
+"""
+typedefs['long_double'] = """\
+#ifndef _LONG_DOUBLE
+typedef long double long_double;
+#endif
+"""
+typedefs[
+    'complex_long_double'] = 'typedef struct {long double r,i;} complex_long_double;'
+typedefs['complex_float'] = 'typedef struct {float r,i;} complex_float;'
+typedefs['complex_double'] = 'typedef struct {double r,i;} complex_double;'
+typedefs['string'] = """typedef char * string;"""
+
+
+############### CPP macros ####################
+cppmacros['CFUNCSMESS'] = """\
+#ifdef DEBUGCFUNCS
+#define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess);
+#define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\
+\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
+\tfprintf(stderr,\"\\n\");
+#else
+#define CFUNCSMESS(mess)
+#define CFUNCSMESSPY(mess,obj)
+#endif
+"""
+cppmacros['F_FUNC'] = """\
+#if defined(PREPEND_FORTRAN)
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) _##F
+#else
+#define F_FUNC(f,F) _##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) _##F##_
+#else
+#define F_FUNC(f,F) _##f##_
+#endif
+#endif
+#else
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) F
+#else
+#define F_FUNC(f,F) f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) F##_
+#else
+#define F_FUNC(f,F) f##_
+#endif
+#endif
+#endif
+#if defined(UNDERSCORE_G77)
+#define F_FUNC_US(f,F) F_FUNC(f##_,F##_)
+#else
+#define F_FUNC_US(f,F) F_FUNC(f,F)
+#endif
+"""
+cppmacros['F_WRAPPEDFUNC'] = """\
+#if defined(PREPEND_FORTRAN)
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F
+#else
+#define F_WRAPPEDFUNC(f,F) _f2pywrap##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_
+#else
+#define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_
+#endif
+#endif
+#else
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F
+#else
+#define F_WRAPPEDFUNC(f,F) f2pywrap##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_
+#else
+#define F_WRAPPEDFUNC(f,F) f2pywrap##f##_
+#endif
+#endif
+#endif
+#if defined(UNDERSCORE_G77)
+#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_)
+#else
+#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F)
+#endif
+"""
+cppmacros['F_MODFUNC'] = """\
+#if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f
+#else
+#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _
+#endif
+#endif
+
+#if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f)  __ ## m ## _MOD_ ## f
+#else
+#define F_MODFUNCNAME(m,f)  __ ## m ## _MOD_ ## f ## _
+#endif
+#endif
+
+#if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f)  f ## .in. ## m
+#else
+#define F_MODFUNCNAME(m,f)  f ## .in. ## m ## _
+#endif
+#endif
+/*
+#if defined(UPPERCASE_FORTRAN)
+#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F)
+#else
+#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f)
+#endif
+*/
+
+#define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f))
+"""
+cppmacros['SWAPUNSAFE'] = """\
+#define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\
+ (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\
+ (size_t)(a) = ((size_t)(a) ^ (size_t)(b))
+"""
+cppmacros['SWAP'] = """\
+#define SWAP(a,b,t) {\\
+\tt *c;\\
+\tc = a;\\
+\ta = b;\\
+\tb = c;}
+"""
+# cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) &
+# NPY_ARRAY_C_CONTIGUOUS)'
+cppmacros['PRINTPYOBJERR'] = """\
+#define PRINTPYOBJERR(obj)\\
+\tfprintf(stderr,\"#modulename#.error is related to \");\\
+\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
+\tfprintf(stderr,\"\\n\");
+"""
+cppmacros['MINMAX'] = """\
+#ifndef max
+#define max(a,b) ((a > b) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b) ((a < b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a > b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a < b) ? (a) : (b))
+#endif
+"""
+needs['len..'] = ['f2py_size']
+cppmacros['len..'] = """\
+#define rank(var) var ## _Rank
+#define shape(var,dim) var ## _Dims[dim]
+#define old_rank(var) (PyArray_NDIM((PyArrayObject *)(capi_ ## var ## _tmp)))
+#define old_shape(var,dim) PyArray_DIM(((PyArrayObject *)(capi_ ## var ## _tmp)),dim)
+#define fshape(var,dim) shape(var,rank(var)-dim-1)
+#define len(var) shape(var,0)
+#define flen(var) fshape(var,0)
+#define old_size(var) PyArray_SIZE((PyArrayObject *)(capi_ ## var ## _tmp))
+/* #define index(i) capi_i ## i */
+#define slen(var) capi_ ## var ## _len
+#define size(var, ...) f2py_size((PyArrayObject *)(capi_ ## var ## _tmp), ## __VA_ARGS__, -1)
+"""
+needs['f2py_size'] = ['stdarg.h']
+cfuncs['f2py_size'] = """\
+static int f2py_size(PyArrayObject* var, ...)
+{
+  npy_int sz = 0;
+  npy_int dim;
+  npy_int rank;
+  va_list argp;
+  va_start(argp, var);
+  dim = va_arg(argp, npy_int);
+  if (dim==-1)
+    {
+      sz = PyArray_SIZE(var);
+    }
+  else
+    {
+      rank = PyArray_NDIM(var);
+      if (dim>=1 && dim<=rank)
+        sz = PyArray_DIM(var, dim-1);
+      else
+        fprintf(stderr, \"f2py_size: 2nd argument value=%d fails to satisfy 1<=value<=%d. Result will be 0.\\n\", dim, rank);
+    }
+  va_end(argp);
+  return sz;
+}
+"""
+
+cppmacros[
+    'pyobj_from_char1'] = '#define pyobj_from_char1(v) (PyInt_FromLong(v))'
+cppmacros[
+    'pyobj_from_short1'] = '#define pyobj_from_short1(v) (PyInt_FromLong(v))'
+needs['pyobj_from_int1'] = ['signed_char']
+cppmacros['pyobj_from_int1'] = '#define pyobj_from_int1(v) (PyInt_FromLong(v))'
+cppmacros[
+    'pyobj_from_long1'] = '#define pyobj_from_long1(v) (PyLong_FromLong(v))'
+needs['pyobj_from_long_long1'] = ['long_long']
+cppmacros['pyobj_from_long_long1'] = """\
+#ifdef HAVE_LONG_LONG
+#define pyobj_from_long_long1(v) (PyLong_FromLongLong(v))
+#else
+#warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long.
+#define pyobj_from_long_long1(v) (PyLong_FromLong(v))
+#endif
+"""
+needs['pyobj_from_long_double1'] = ['long_double']
+cppmacros[
+    'pyobj_from_long_double1'] = '#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))'
+cppmacros[
+    'pyobj_from_double1'] = '#define pyobj_from_double1(v) (PyFloat_FromDouble(v))'
+cppmacros[
+    'pyobj_from_float1'] = '#define pyobj_from_float1(v) (PyFloat_FromDouble(v))'
+needs['pyobj_from_complex_long_double1'] = ['complex_long_double']
+cppmacros[
+    'pyobj_from_complex_long_double1'] = '#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_complex_double1'] = ['complex_double']
+cppmacros[
+    'pyobj_from_complex_double1'] = '#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_complex_float1'] = ['complex_float']
+cppmacros[
+    'pyobj_from_complex_float1'] = '#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_string1'] = ['string']
+cppmacros[
+    'pyobj_from_string1'] = '#define pyobj_from_string1(v) (PyString_FromString((char *)v))'
+needs['pyobj_from_string1size'] = ['string']
+cppmacros[
+    'pyobj_from_string1size'] = '#define pyobj_from_string1size(v,len) (PyUString_FromStringAndSize((char *)v, len))'
+needs['TRYPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
+cppmacros['TRYPYARRAYTEMPLATE'] = """\
+/* New SciPy */
+#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break;
+#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;
+#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr)); break;
+
+#define TRYPYARRAYTEMPLATE(ctype,typecode) \\
+        PyArrayObject *arr = NULL;\\
+        if (!obj) return -2;\\
+        if (!PyArray_Check(obj)) return -1;\\
+        if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
+        if (PyArray_DESCR(arr)->type==typecode)  {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\
+        switch (PyArray_TYPE(arr)) {\\
+                case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_INT: *(int *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\
+                case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_SHORT: *(short *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr), arr); break;\\
+        default: return -2;\\
+        };\\
+        return 1
+"""
+
+needs['TRYCOMPLEXPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
+cppmacros['TRYCOMPLEXPYARRAYTEMPLATE'] = """\
+#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break;
+#define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\
+        PyArrayObject *arr = NULL;\\
+        if (!obj) return -2;\\
+        if (!PyArray_Check(obj)) return -1;\\
+        if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
+        if (PyArray_DESCR(arr)->type==typecode) {\\
+            *(ctype *)(PyArray_DATA(arr))=(*v).r;\\
+            *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\
+            return 1;\\
+        }\\
+        switch (PyArray_TYPE(arr)) {\\
+                case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r;*(double *)(PyArray_DATA(arr)+sizeof(double))=(*v).i;break;\\
+                case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=(*v).r;*(float *)(PyArray_DATA(arr)+sizeof(float))=(*v).i;break;\\
+                case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONG: *(long *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_INT: *(int *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_SHORT: *(short *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\
+                case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;*(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;break;\\
+                case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break;\\
+                default: return -2;\\
+        };\\
+        return -1;
+"""
+# cppmacros['NUMFROMARROBJ']="""\
+# define NUMFROMARROBJ(typenum,ctype) \\
+# \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
+# \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
+# \tif (arr) {\\
+# \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\
+# \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
+# \t\t\tgoto capi_fail;\\
+# \t\t} else {\\
+# \t\t\t(PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\
+# \t\t}\\
+# \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
+# \t\treturn 1;\\
+# \t}
+# """
+# XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ
+# cppmacros['CNUMFROMARROBJ']="""\
+# define CNUMFROMARROBJ(typenum,ctype) \\
+# \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
+# \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
+# \tif (arr) {\\
+# \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\
+# \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
+# \t\t\tgoto capi_fail;\\
+# \t\t} else {\\
+# \t\t\t(PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\
+# \t\t}\\
+# \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
+# \t\treturn 1;\\
+# \t}
+# """
+
+
+needs['GETSTRFROMPYTUPLE'] = ['STRINGCOPYN', 'PRINTPYOBJERR']
+cppmacros['GETSTRFROMPYTUPLE'] = """\
+#define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\
+\t\tPyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\
+\t\tif (rv_cb_str == NULL)\\
+\t\t\tgoto capi_fail;\\
+\t\tif (PyString_Check(rv_cb_str)) {\\
+\t\t\tstr[len-1]='\\0';\\
+\t\t\tSTRINGCOPYN((str),PyString_AS_STRING((PyStringObject*)rv_cb_str),(len));\\
+\t\t} else {\\
+\t\t\tPRINTPYOBJERR(rv_cb_str);\\
+\t\t\tPyErr_SetString(#modulename#_error,\"string object expected\");\\
+\t\t\tgoto capi_fail;\\
+\t\t}\\
+\t}
+"""
+cppmacros['GETSCALARFROMPYTUPLE'] = """\
+#define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\
+\t\tif ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\
+\t\tif (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\
+\t\t\tgoto capi_fail;\\
+\t}
+"""
+
+cppmacros['FAILNULL'] = """\\
+#define FAILNULL(p) do {                                            \\
+    if ((p) == NULL) {                                              \\
+        PyErr_SetString(PyExc_MemoryError, "NULL pointer found");   \\
+        goto capi_fail;                                             \\
+    }                                                               \\
+} while (0)
+"""
+needs['MEMCOPY'] = ['string.h', 'FAILNULL']
+cppmacros['MEMCOPY'] = """\
+#define MEMCOPY(to,from,n)\\
+    do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0)
+"""
+cppmacros['STRINGMALLOC'] = """\
+#define STRINGMALLOC(str,len)\\
+\tif ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\
+\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
+\t\tgoto capi_fail;\\
+\t} else {\\
+\t\t(str)[len] = '\\0';\\
+\t}
+"""
+cppmacros['STRINGFREE'] = """\
+#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0)
+"""
+needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
+cppmacros['STRINGCOPYN'] = """\
+#define STRINGCOPYN(to,from,buf_size)                           \\
+    do {                                                        \\
+        int _m = (buf_size);                                    \\
+        char *_to = (to);                                       \\
+        char *_from = (from);                                   \\
+        FAILNULL(_to); FAILNULL(_from);                         \\
+        (void)strncpy(_to, _from, sizeof(char)*_m);             \\
+        _to[_m-1] = '\\0';                                      \\
+        /* Padding with spaces instead of nulls */              \\
+        for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) {      \\
+            _to[_m] = ' ';                                      \\
+        }                                                       \\
+    } while (0)
+"""
+needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
+cppmacros['STRINGCOPY'] = """\
+#define STRINGCOPY(to,from)\\
+    do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0)
+"""
+cppmacros['CHECKGENERIC'] = """\
+#define CHECKGENERIC(check,tcheck,name) \\
+\tif (!(check)) {\\
+\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKARRAY'] = """\
+#define CHECKARRAY(check,tcheck,name) \\
+\tif (!(check)) {\\
+\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKSTRING'] = """\
+#define CHECKSTRING(check,tcheck,name,show,var)\\
+\tif (!(check)) {\\
+\t\tchar errstring[256];\\
+\t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\
+\t\tPyErr_SetString(#modulename#_error, errstring);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKSCALAR'] = """\
+#define CHECKSCALAR(check,tcheck,name,show,var)\\
+\tif (!(check)) {\\
+\t\tchar errstring[256];\\
+\t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\
+\t\tPyErr_SetString(#modulename#_error,errstring);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+# cppmacros['CHECKDIMS']="""\
+# define CHECKDIMS(dims,rank) \\
+# \tfor (int i=0;i<(rank);i++)\\
+# \t\tif (dims[i]<0) {\\
+# \t\t\tfprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\
+# \t\t\tgoto capi_fail;\\
+# \t\t}
+# """
+cppmacros[
+    'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))'
+cppmacros['OLDPYNUM'] = """\
+#ifdef OLDPYNUM
+#error You need to intall Numeric Python version 13 or higher. Get it from http:/sourceforge.net/project/?group_id=1369
+#endif
+"""
+################# C functions ###############
+
+cfuncs['calcarrindex'] = """\
+static int calcarrindex(int *i,PyArrayObject *arr) {
+\tint k,ii = i[0];
+\tfor (k=1; k < PyArray_NDIM(arr); k++)
+\t\tii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */
+\treturn ii;
+}"""
+cfuncs['calcarrindextr'] = """\
+static int calcarrindextr(int *i,PyArrayObject *arr) {
+\tint k,ii = i[PyArray_NDIM(arr)-1];
+\tfor (k=1; k < PyArray_NDIM(arr); k++)
+\t\tii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */
+\treturn ii;
+}"""
+cfuncs['forcomb'] = """\
+static struct { int nd;npy_intp *d;int *i,*i_tr,tr; } forcombcache;
+static int initforcomb(npy_intp *dims,int nd,int tr) {
+  int k;
+  if (dims==NULL) return 0;
+  if (nd<0) return 0;
+  forcombcache.nd = nd;
+  forcombcache.d = dims;
+  forcombcache.tr = tr;
+  if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
+  if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
+  for (k=1;k<nd;k++) {
+    forcombcache.i[k] = forcombcache.i_tr[nd-k-1] = 0;
+  }
+  forcombcache.i[0] = forcombcache.i_tr[nd-1] = -1;
+  return 1;
+}
+static int *nextforcomb(void) {
+  int j,*i,*i_tr,k;
+  int nd=forcombcache.nd;
+  if ((i=forcombcache.i) == NULL) return NULL;
+  if ((i_tr=forcombcache.i_tr) == NULL) return NULL;
+  if (forcombcache.d == NULL) return NULL;
+  i[0]++;
+  if (i[0]==forcombcache.d[0]) {
+    j=1;
+    while ((j<nd) && (i[j]==forcombcache.d[j]-1)) j++;
+    if (j==nd) {
+      free(i);
+      free(i_tr);
+      return NULL;
+    }
+    for (k=0;k<j;k++) i[k] = i_tr[nd-k-1] = 0;
+    i[j]++;
+    i_tr[nd-j-1]++;
+  } else
+    i_tr[nd-1]++;
+  if (forcombcache.tr) return i_tr;
+  return i;
+}"""
+needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
+cfuncs['try_pyarr_from_string'] = """\
+static int try_pyarr_from_string(PyObject *obj,const string str) {
+\tPyArrayObject *arr = NULL;
+\tif (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL)))
+\t\t{ STRINGCOPYN(PyArray_DATA(arr),str,PyArray_NBYTES(arr)); }
+\treturn 1;
+capi_fail:
+\tPRINTPYOBJERR(obj);
+\tPyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\");
+\treturn 0;
+}
+"""
+needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
+cfuncs['string_from_pyobj'] = """\
+static int string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess) {
+\tPyArrayObject *arr = NULL;
+\tPyObject *tmp = NULL;
+#ifdef DEBUGCFUNCS
+fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj);
+#endif
+\tif (obj == Py_None) {
+\t\tif (*len == -1)
+\t\t\t*len = strlen(inistr); /* Will this cause problems? */
+\t\tSTRINGMALLOC(*str,*len);
+\t\tSTRINGCOPYN(*str,inistr,*len+1);
+\t\treturn 1;
+\t}
+\tif (PyArray_Check(obj)) {
+\t\tif ((arr = (PyArrayObject *)obj) == NULL)
+\t\t\tgoto capi_fail;
+\t\tif (!ISCONTIGUOUS(arr)) {
+\t\t\tPyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\");
+\t\t\tgoto capi_fail;
+\t\t}
+\t\tif (*len == -1)
+\t\t\t*len = (PyArray_ITEMSIZE(arr))*PyArray_SIZE(arr);
+\t\tSTRINGMALLOC(*str,*len);
+\t\tSTRINGCOPYN(*str,PyArray_DATA(arr),*len+1);
+\t\treturn 1;
+\t}
+\tif (PyString_Check(obj)) {
+\t\ttmp = obj;
+\t\tPy_INCREF(tmp);
+\t}
+#if PY_VERSION_HEX >= 0x03000000
+\telse if (PyUnicode_Check(obj)) {
+\t\ttmp = PyUnicode_AsASCIIString(obj);
+\t}
+\telse {
+\t\tPyObject *tmp2;
+\t\ttmp2 = PyObject_Str(obj);
+\t\tif (tmp2) {
+\t\t\ttmp = PyUnicode_AsASCIIString(tmp2);
+\t\t\tPy_DECREF(tmp2);
+\t\t}
+\t\telse {
+\t\t\ttmp = NULL;
+\t\t}
+\t}
+#else
+\telse {
+\t\ttmp = PyObject_Str(obj);
+\t}
+#endif
+\tif (tmp == NULL) goto capi_fail;
+\tif (*len == -1)
+\t\t*len = PyString_GET_SIZE(tmp);
+\tSTRINGMALLOC(*str,*len);
+\tSTRINGCOPYN(*str,PyString_AS_STRING(tmp),*len+1);
+\tPy_DECREF(tmp);
+\treturn 1;
+capi_fail:
+\tPy_XDECREF(tmp);
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['char_from_pyobj'] = ['int_from_pyobj']
+cfuncs['char_from_pyobj'] = """\
+static int char_from_pyobj(char* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (char)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['signed_char_from_pyobj'] = ['int_from_pyobj', 'signed_char']
+cfuncs['signed_char_from_pyobj'] = """\
+static int signed_char_from_pyobj(signed_char* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (signed_char)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['short_from_pyobj'] = ['int_from_pyobj']
+cfuncs['short_from_pyobj'] = """\
+static int short_from_pyobj(short* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (short)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+cfuncs['int_from_pyobj'] = """\
+static int int_from_pyobj(int* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyInt_Check(obj)) {
+\t\t*v = (int)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Int(obj);
+\tif (tmp) {
+\t\t*v = PyInt_AS_LONG(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (int_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+cfuncs['long_from_pyobj'] = """\
+static int long_from_pyobj(long* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyInt_Check(obj)) {
+\t\t*v = PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Int(obj);
+\tif (tmp) {
+\t\t*v = PyInt_AS_LONG(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['long_long_from_pyobj'] = ['long_long']
+cfuncs['long_long_from_pyobj'] = """\
+static int long_long_from_pyobj(long_long* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyLong_Check(obj)) {
+\t\t*v = PyLong_AsLongLong(obj);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PyInt_Check(obj)) {
+\t\t*v = (long_long)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Long(obj);
+\tif (tmp) {
+\t\t*v = PyLong_AsLongLong(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (long_long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['long_double_from_pyobj'] = ['double_from_pyobj', 'long_double']
+cfuncs['long_double_from_pyobj'] = """\
+static int long_double_from_pyobj(long_double* v,PyObject *obj,const char *errmess) {
+\tdouble d=0;
+\tif (PyArray_CheckScalar(obj)){
+\t\tif PyArray_IsScalar(obj, LongDouble) {
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t\treturn 1;
+\t\t}
+\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_LONGDOUBLE) {
+\t\t\t(*v) = *((npy_longdouble *)PyArray_DATA(obj));
+\t\t\treturn 1;
+\t\t}
+\t}
+\tif (double_from_pyobj(&d,obj,errmess)) {
+\t\t*v = (long_double)d;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+cfuncs['double_from_pyobj'] = """\
+static int double_from_pyobj(double* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyFloat_Check(obj)) {
+#ifdef __sgi
+\t\t*v = PyFloat_AsDouble(obj);
+#else
+\t\t*v = PyFloat_AS_DOUBLE(obj);
+#endif
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Float(obj);
+\tif (tmp) {
+#ifdef __sgi
+\t\t*v = PyFloat_AsDouble(tmp);
+#else
+\t\t*v = PyFloat_AS_DOUBLE(tmp);
+#endif
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['float_from_pyobj'] = ['double_from_pyobj']
+cfuncs['float_from_pyobj'] = """\
+static int float_from_pyobj(float* v,PyObject *obj,const char *errmess) {
+\tdouble d=0.0;
+\tif (double_from_pyobj(&d,obj,errmess)) {
+\t\t*v = (float)d;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['complex_long_double_from_pyobj'] = ['complex_long_double', 'long_double',
+                                           'complex_double_from_pyobj']
+cfuncs['complex_long_double_from_pyobj'] = """\
+static int complex_long_double_from_pyobj(complex_long_double* v,PyObject *obj,const char *errmess) {
+\tcomplex_double cd={0.0,0.0};
+\tif (PyArray_CheckScalar(obj)){
+\t\tif PyArray_IsScalar(obj, CLongDouble) {
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t\treturn 1;
+\t\t}
+\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_CLONGDOUBLE) {
+\t\t\t(*v).r = ((npy_clongdouble *)PyArray_DATA(obj))->real;
+\t\t\t(*v).i = ((npy_clongdouble *)PyArray_DATA(obj))->imag;
+\t\t\treturn 1;
+\t\t}
+\t}
+\tif (complex_double_from_pyobj(&cd,obj,errmess)) {
+\t\t(*v).r = (long_double)cd.r;
+\t\t(*v).i = (long_double)cd.i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['complex_double_from_pyobj'] = ['complex_double']
+cfuncs['complex_double_from_pyobj'] = """\
+static int complex_double_from_pyobj(complex_double* v,PyObject *obj,const char *errmess) {
+\tPy_complex c;
+\tif (PyComplex_Check(obj)) {
+\t\tc=PyComplex_AsCComplex(obj);
+\t\t(*v).r=c.real, (*v).i=c.imag;
+\t\treturn 1;
+\t}
+\tif (PyArray_IsScalar(obj, ComplexFloating)) {
+\t\tif (PyArray_IsScalar(obj, CFloat)) {
+\t\t\tnpy_cfloat new;
+\t\t\tPyArray_ScalarAsCtype(obj, &new);
+\t\t\t(*v).r = (double)new.real;
+\t\t\t(*v).i = (double)new.imag;
+\t\t}
+\t\telse if (PyArray_IsScalar(obj, CLongDouble)) {
+\t\t\tnpy_clongdouble new;
+\t\t\tPyArray_ScalarAsCtype(obj, &new);
+\t\t\t(*v).r = (double)new.real;
+\t\t\t(*v).i = (double)new.imag;
+\t\t}
+\t\telse { /* if (PyArray_IsScalar(obj, CDouble)) */
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t}
+\t\treturn 1;
+\t}
+\tif (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */
+\t\tPyObject *arr;
+\t\tif (PyArray_Check(obj)) {
+\t\t\tarr = PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE);
+\t\t}
+\t\telse {
+\t\t\tarr = PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE));
+\t\t}
+\t\tif (arr==NULL) return 0;
+\t\t(*v).r = ((npy_cdouble *)PyArray_DATA(arr))->real;
+\t\t(*v).i = ((npy_cdouble *)PyArray_DATA(arr))->imag;
+\t\treturn 1;
+\t}
+\t/* Python does not provide PyNumber_Complex function :-( */
+\t(*v).i=0.0;
+\tif (PyFloat_Check(obj)) {
+#ifdef __sgi
+\t\t(*v).r = PyFloat_AsDouble(obj);
+#else
+\t\t(*v).r = PyFloat_AS_DOUBLE(obj);
+#endif
+\t\treturn 1;
+\t}
+\tif (PyInt_Check(obj)) {
+\t\t(*v).r = (double)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\tif (PyLong_Check(obj)) {
+\t\t(*v).r = PyLong_AsDouble(obj);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PySequence_Check(obj) && !(PyString_Check(obj) || PyUnicode_Check(obj))) {
+\t\tPyObject *tmp = PySequence_GetItem(obj,0);
+\t\tif (tmp) {
+\t\t\tif (complex_double_from_pyobj(v,tmp,errmess)) {
+\t\t\t\tPy_DECREF(tmp);
+\t\t\t\treturn 1;
+\t\t\t}
+\t\t\tPy_DECREF(tmp);
+\t\t}
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL)
+\t\t\terr = PyExc_TypeError;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['complex_float_from_pyobj'] = [
+    'complex_float', 'complex_double_from_pyobj']
+cfuncs['complex_float_from_pyobj'] = """\
+static int complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess) {
+\tcomplex_double cd={0.0,0.0};
+\tif (complex_double_from_pyobj(&cd,obj,errmess)) {
+\t\t(*v).r = (float)cd.r;
+\t\t(*v).i = (float)cd.i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['try_pyarr_from_char'] = ['pyobj_from_char1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_char'] = 'static int try_pyarr_from_char(PyObject* obj,char* v) {\n\tTRYPYARRAYTEMPLATE(char,\'c\');\n}\n'
+needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'unsigned_char']
+cfuncs[
+    'try_pyarr_from_unsigned_char'] = 'static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n\tTRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n'
+needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'signed_char']
+cfuncs[
+    'try_pyarr_from_signed_char'] = 'static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n\tTRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n'
+needs['try_pyarr_from_short'] = ['pyobj_from_short1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_short'] = 'static int try_pyarr_from_short(PyObject* obj,short* v) {\n\tTRYPYARRAYTEMPLATE(short,\'s\');\n}\n'
+needs['try_pyarr_from_int'] = ['pyobj_from_int1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_int'] = 'static int try_pyarr_from_int(PyObject* obj,int* v) {\n\tTRYPYARRAYTEMPLATE(int,\'i\');\n}\n'
+needs['try_pyarr_from_long'] = ['pyobj_from_long1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_long'] = 'static int try_pyarr_from_long(PyObject* obj,long* v) {\n\tTRYPYARRAYTEMPLATE(long,\'l\');\n}\n'
+needs['try_pyarr_from_long_long'] = [
+    'pyobj_from_long_long1', 'TRYPYARRAYTEMPLATE', 'long_long']
+cfuncs[
+    'try_pyarr_from_long_long'] = 'static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n\tTRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n'
+needs['try_pyarr_from_float'] = ['pyobj_from_float1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_float'] = 'static int try_pyarr_from_float(PyObject* obj,float* v) {\n\tTRYPYARRAYTEMPLATE(float,\'f\');\n}\n'
+needs['try_pyarr_from_double'] = ['pyobj_from_double1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_double'] = 'static int try_pyarr_from_double(PyObject* obj,double* v) {\n\tTRYPYARRAYTEMPLATE(double,\'d\');\n}\n'
+needs['try_pyarr_from_complex_float'] = [
+    'pyobj_from_complex_float1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_float']
+cfuncs[
+    'try_pyarr_from_complex_float'] = 'static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n'
+needs['try_pyarr_from_complex_double'] = [
+    'pyobj_from_complex_double1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_double']
+cfuncs[
+    'try_pyarr_from_complex_double'] = 'static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n'
+
+needs['create_cb_arglist'] = ['CFUNCSMESS', 'PRINTPYOBJERR', 'MINMAX']
+cfuncs['create_cb_arglist'] = """\
+static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofargs,const int nofoptargs,int *nofargs,PyTupleObject **args,const char *errmess) {
+\tPyObject *tmp = NULL;
+\tPyObject *tmp_fun = NULL;
+\tint tot,opt,ext,siz,i,di=0;
+\tCFUNCSMESS(\"create_cb_arglist\\n\");
+\ttot=opt=ext=siz=0;
+\t/* Get the total number of arguments */
+\tif (PyFunction_Check(fun))
+\t\ttmp_fun = fun;
+\telse {
+\t\tdi = 1;
+\t\tif (PyObject_HasAttrString(fun,\"im_func\")) {
+\t\t\ttmp_fun = PyObject_GetAttrString(fun,\"im_func\");
+\t\t}
+\t\telse if (PyObject_HasAttrString(fun,\"__call__\")) {
+\t\t\ttmp = PyObject_GetAttrString(fun,\"__call__\");
+\t\t\tif (PyObject_HasAttrString(tmp,\"im_func\"))
+\t\t\t\ttmp_fun = PyObject_GetAttrString(tmp,\"im_func\");
+\t\t\telse {
+\t\t\t\ttmp_fun = fun; /* built-in function */
+\t\t\t\ttot = maxnofargs;
+\t\t\t\tif (xa != NULL)
+\t\t\t\t\ttot += PyTuple_Size((PyObject *)xa);
+\t\t\t}
+\t\t\tPy_XDECREF(tmp);
+\t\t}
+\t\telse if (PyFortran_Check(fun) || PyFortran_Check1(fun)) {
+\t\t\ttot = maxnofargs;
+\t\t\tif (xa != NULL)
+\t\t\t\ttot += PyTuple_Size((PyObject *)xa);
+\t\t\ttmp_fun = fun;
+\t\t}
+\t\telse if (F2PyCapsule_Check(fun)) {
+\t\t\ttot = maxnofargs;
+\t\t\tif (xa != NULL)
+\t\t\t\text = PyTuple_Size((PyObject *)xa);
+\t\t\tif(ext>0) {
+\t\t\t\tfprintf(stderr,\"extra arguments tuple cannot be used with CObject call-back\\n\");
+\t\t\t\tgoto capi_fail;
+\t\t\t}
+\t\t\ttmp_fun = fun;
+\t\t}
+\t}
+if (tmp_fun==NULL) {
+fprintf(stderr,\"Call-back argument must be function|instance|instance.__call__|f2py-function but got %s.\\n\",(fun==NULL?\"NULL\":Py_TYPE(fun)->tp_name));
+goto capi_fail;
+}
+#if PY_VERSION_HEX >= 0x03000000
+\tif (PyObject_HasAttrString(tmp_fun,\"__code__\")) {
+\t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\"))
+#else
+\tif (PyObject_HasAttrString(tmp_fun,\"func_code\")) {
+\t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\"))
+#endif
+\t\t\ttot = PyInt_AsLong(PyObject_GetAttrString(tmp,\"co_argcount\")) - di;
+\t\tPy_XDECREF(tmp);
+\t}
+\t/* Get the number of optional arguments */
+#if PY_VERSION_HEX >= 0x03000000
+\tif (PyObject_HasAttrString(tmp_fun,\"__defaults__\")) {
+\t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"__defaults__\")))
+#else
+\tif (PyObject_HasAttrString(tmp_fun,\"func_defaults\")) {
+\t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"func_defaults\")))
+#endif
+\t\t\topt = PyTuple_Size(tmp);
+\t\tPy_XDECREF(tmp);
+\t}
+\t/* Get the number of extra arguments */
+\tif (xa != NULL)
+\t\text = PyTuple_Size((PyObject *)xa);
+\t/* Calculate the size of call-backs argument list */
+\tsiz = MIN(maxnofargs+ext,tot);
+\t*nofargs = MAX(0,siz-ext);
+#ifdef DEBUGCFUNCS
+\tfprintf(stderr,\"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),tot,opt,ext,siz,nofargs=%d(-%d),%d,%d,%d,%d,%d\\n\",maxnofargs,nofoptargs,tot,opt,ext,siz,*nofargs);
+#endif
+\tif (siz<tot-opt) {
+\t\tfprintf(stderr,\"create_cb_arglist: Failed to build argument list (siz) with enough arguments (tot-opt) required by user-supplied function (siz,tot,opt=%d,%d,%d).\\n\",siz,tot,opt);
+\t\tgoto capi_fail;
+\t}
+\t/* Initialize argument list */
+\t*args = (PyTupleObject *)PyTuple_New(siz);
+\tfor (i=0;i<*nofargs;i++) {
+\t\tPy_INCREF(Py_None);
+\t\tPyTuple_SET_ITEM((PyObject *)(*args),i,Py_None);
+\t}
+\tif (xa != NULL)
+\t\tfor (i=(*nofargs);i<siz;i++) {
+\t\t\ttmp = PyTuple_GetItem((PyObject *)xa,i-(*nofargs));
+\t\t\tPy_INCREF(tmp);
+\t\t\tPyTuple_SET_ITEM(*args,i,tmp);
+\t\t}
+\tCFUNCSMESS(\"create_cb_arglist-end\\n\");
+\treturn 1;
+capi_fail:
+\tif ((PyErr_Occurred())==NULL)
+\t\tPyErr_SetString(#modulename#_error,errmess);
+\treturn 0;
+}
+"""
+
+
+def buildcfuncs():
+    from .capi_maps import c2capi_map
+    for k in c2capi_map.keys():
+        m = 'pyarr_from_p_%s1' % k
+        cppmacros[
+            m] = '#define %s(v) (PyArray_SimpleNewFromData(0,NULL,%s,(char *)v))' % (m, c2capi_map[k])
+    k = 'string'
+    m = 'pyarr_from_p_%s1' % k
+    cppmacros[
+        m] = '#define %s(v,dims) (PyArray_SimpleNewFromData(1,dims,NPY_CHAR,(char *)v))' % (m)
+
+
+############ Auxiliary functions for sorting needs ###################
+
+def append_needs(need, flag=1):
+    global outneeds, needs
+    if isinstance(need, list):
+        for n in need:
+            append_needs(n, flag)
+    elif isinstance(need, str):
+        if not need:
+            return
+        if need in includes0:
+            n = 'includes0'
+        elif need in includes:
+            n = 'includes'
+        elif need in typedefs:
+            n = 'typedefs'
+        elif need in typedefs_generated:
+            n = 'typedefs_generated'
+        elif need in cppmacros:
+            n = 'cppmacros'
+        elif need in cfuncs:
+            n = 'cfuncs'
+        elif need in callbacks:
+            n = 'callbacks'
+        elif need in f90modhooks:
+            n = 'f90modhooks'
+        elif need in commonhooks:
+            n = 'commonhooks'
+        else:
+            errmess('append_needs: unknown need %s\n' % (repr(need)))
+            return
+        if need in outneeds[n]:
+            return
+        if flag:
+            tmp = {}
+            if need in needs:
+                for nn in needs[need]:
+                    t = append_needs(nn, 0)
+                    if isinstance(t, dict):
+                        for nnn in t.keys():
+                            if nnn in tmp:
+                                tmp[nnn] = tmp[nnn] + t[nnn]
+                            else:
+                                tmp[nnn] = t[nnn]
+            for nn in tmp.keys():
+                for nnn in tmp[nn]:
+                    if nnn not in outneeds[nn]:
+                        outneeds[nn] = [nnn] + outneeds[nn]
+            outneeds[n].append(need)
+        else:
+            tmp = {}
+            if need in needs:
+                for nn in needs[need]:
+                    t = append_needs(nn, flag)
+                    if isinstance(t, dict):
+                        for nnn in t.keys():
+                            if nnn in tmp:
+                                tmp[nnn] = t[nnn] + tmp[nnn]
+                            else:
+                                tmp[nnn] = t[nnn]
+            if n not in tmp:
+                tmp[n] = []
+            tmp[n].append(need)
+            return tmp
+    else:
+        errmess('append_needs: expected list or string but got :%s\n' %
+                (repr(need)))
+
+
+def get_needs():
+    global outneeds, needs
+    res = {}
+    for n in outneeds.keys():
+        out = []
+        saveout = copy.copy(outneeds[n])
+        while len(outneeds[n]) > 0:
+            if outneeds[n][0] not in needs:
+                out.append(outneeds[n][0])
+                del outneeds[n][0]
+            else:
+                flag = 0
+                for k in outneeds[n][1:]:
+                    if k in needs[outneeds[n][0]]:
+                        flag = 1
+                        break
+                if flag:
+                    outneeds[n] = outneeds[n][1:] + [outneeds[n][0]]
+                else:
+                    out.append(outneeds[n][0])
+                    del outneeds[n][0]
+            if saveout and (0 not in map(lambda x, y: x == y, saveout, outneeds[n])) \
+                    and outneeds[n] != []:
+                print(n, saveout)
+                errmess(
+                    'get_needs: no progress in sorting needs, probably circular dependence, skipping.\n')
+                out = out + saveout
+                break
+            saveout = copy.copy(outneeds[n])
+        if out == []:
+            out = [n]
+        res[n] = out
+    return res
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.py
new file mode 100644
index 0000000000..1210064bc2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python2
+"""
+
+Build common block mechanism for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 10:57:33 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.19 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+from .auxfuncs import (
+    hasbody, hascommon, hasnote, isintent_hide, outmess
+)
+from . import capi_maps
+from . import func2subr
+from .crackfortran import rmbadname
+
+
+def findcommonblocks(block, top=1):
+    ret = []
+    if hascommon(block):
+        for n in block['common'].keys():
+            vars = {}
+            for v in block['common'][n]:
+                vars[v] = block['vars'][v]
+            ret.append((n, block['common'][n], vars))
+    elif hasbody(block):
+        for b in block['body']:
+            ret = ret + findcommonblocks(b, 0)
+    if top:
+        tret = []
+        names = []
+        for t in ret:
+            if t[0] not in names:
+                names.append(t[0])
+                tret.append(t)
+        return tret
+    return ret
+
+
+def buildhooks(m):
+    ret = {'commonhooks': [], 'initcommonhooks': [],
+           'docs': ['"COMMON blocks:\\n"']}
+    fwrap = ['']
+
+    def fadd(line, s=fwrap):
+        s[0] = '%s\n      %s' % (s[0], line)
+    chooks = ['']
+
+    def cadd(line, s=chooks):
+        s[0] = '%s\n%s' % (s[0], line)
+    ihooks = ['']
+
+    def iadd(line, s=ihooks):
+        s[0] = '%s\n%s' % (s[0], line)
+    doc = ['']
+
+    def dadd(line, s=doc):
+        s[0] = '%s\n%s' % (s[0], line)
+    for (name, vnames, vars) in findcommonblocks(m):
+        lower_name = name.lower()
+        hnames, inames = [], []
+        for n in vnames:
+            if isintent_hide(vars[n]):
+                hnames.append(n)
+            else:
+                inames.append(n)
+        if hnames:
+            outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t  %s\n\t\t  Hidden: %s\n' % (
+                name, ','.join(inames), ','.join(hnames)))
+        else:
+            outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t  %s\n' % (
+                name, ','.join(inames)))
+        fadd('subroutine f2pyinit%s(setupfunc)' % name)
+        fadd('external setupfunc')
+        for n in vnames:
+            fadd(func2subr.var2fixfortran(vars, n))
+        if name == '_BLNK_':
+            fadd('common %s' % (','.join(vnames)))
+        else:
+            fadd('common /%s/ %s' % (name, ','.join(vnames)))
+        fadd('call setupfunc(%s)' % (','.join(inames)))
+        fadd('end\n')
+        cadd('static FortranDataDef f2py_%s_def[] = {' % (name))
+        idims = []
+        for n in inames:
+            ct = capi_maps.getctype(vars[n])
+            at = capi_maps.c2capi_map[ct]
+            dm = capi_maps.getarrdims(n, vars[n])
+            if dm['dims']:
+                idims.append('(%s)' % (dm['dims']))
+            else:
+                idims.append('')
+            dms = dm['dims'].strip()
+            if not dms:
+                dms = '-1'
+            cadd('\t{\"%s\",%s,{{%s}},%s},' % (n, dm['rank'], dms, at))
+        cadd('\t{NULL}\n};')
+        inames1 = rmbadname(inames)
+        inames1_tps = ','.join(['char *' + s for s in inames1])
+        cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
+        cadd('\tint i_f2py=0;')
+        for n in inames1:
+            cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
+        cadd('}')
+        if '_' in lower_name:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
+             % (F_FUNC, lower_name, name.upper(),
+                ','.join(['char*'] * len(inames1))))
+        cadd('static void f2py_init_%s(void) {' % name)
+        cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
+             % (F_FUNC, lower_name, name.upper(), name))
+        cadd('}\n')
+        iadd('\tF2PyDict_SetItemString(d, \"%s\", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
+            name, name, name))
+        tname = name.replace('_', '\\_')
+        dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
+        dadd('\\begin{description}')
+        for n in inames:
+            dadd('\\item[]{{}\\verb@%s@{}}' %
+                 (capi_maps.getarrdocsign(n, vars[n])))
+            if hasnote(vars[n]):
+                note = vars[n]['note']
+                if isinstance(note, list):
+                    note = '\n'.join(note)
+                dadd('--- %s' % (note))
+        dadd('\\end{description}')
+        ret['docs'].append(
+            '"\t/%s/ %s\\n"' % (name, ','.join(map(lambda v, d: v + d, inames, idims))))
+    ret['commonhooks'] = chooks
+    ret['initcommonhooks'] = ihooks
+    ret['latexdoc'] = doc[0]
+    if len(ret['docs']) <= 1:
+        ret['docs'] = ''
+    return ret, fwrap[0]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
new file mode 100644
index 0000000000..5fd1d08c7f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
@@ -0,0 +1,3311 @@
+#!/usr/bin/env python2
+"""
+crackfortran --- read fortran (77,90) code and extract declaration information.
+
+Copyright 1999-2004 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/09/27 07:13:49 $
+Pearu Peterson
+
+
+Usage of crackfortran:
+======================
+Command line keys: -quiet,-verbose,-fix,-f77,-f90,-show,-h <pyffilename>
+                   -m <module name for f77 routines>,--ignore-contains
+Functions: crackfortran, crack2fortran
+The following Fortran statements/constructions are supported
+(or will be if needed):
+   block data,byte,call,character,common,complex,contains,data,
+   dimension,double complex,double precision,end,external,function,
+   implicit,integer,intent,interface,intrinsic,
+   logical,module,optional,parameter,private,public,
+   program,real,(sequence?),subroutine,type,use,virtual,
+   include,pythonmodule
+Note: 'virtual' is mapped to 'dimension'.
+Note: 'implicit integer (z) static (z)' is 'implicit static (z)' (this is minor bug).
+Note: code after 'contains' will be ignored until its scope ends.
+Note: 'common' statement is extended: dimensions are moved to variable definitions
+Note: f2py directive: <commentchar>f2py<line> is read as <line>
+Note: pythonmodule is introduced to represent Python module
+
+Usage:
+  `postlist=crackfortran(files,funcs)`
+  `postlist` contains declaration information read from the list of files `files`.
+  `crack2fortran(postlist)` returns a fortran code to be saved to pyf-file
+
+  `postlist` has the following structure:
+ *** it is a list of dictionaries containing `blocks':
+     B = {'block','body','vars','parent_block'[,'name','prefix','args','result',
+          'implicit','externals','interfaced','common','sortvars',
+          'commonvars','note']}
+     B['block'] = 'interface' | 'function' | 'subroutine' | 'module' |
+                  'program' | 'block data' | 'type' | 'pythonmodule'
+     B['body'] --- list containing `subblocks' with the same structure as `blocks'
+     B['parent_block'] --- dictionary of a parent block:
+                             C['body'][<index>]['parent_block'] is C
+     B['vars'] --- dictionary of variable definitions
+     B['sortvars'] --- dictionary of variable definitions sorted by dependence (independent first)
+     B['name'] --- name of the block (not if B['block']=='interface')
+     B['prefix'] --- prefix string (only if B['block']=='function')
+     B['args'] --- list of argument names if B['block']== 'function' | 'subroutine'
+     B['result'] --- name of the return value (only if B['block']=='function')
+     B['implicit'] --- dictionary {'a':<variable definition>,'b':...} | None
+     B['externals'] --- list of variables being external
+     B['interfaced'] --- list of variables being external and defined
+     B['common'] --- dictionary of common blocks (list of objects)
+     B['commonvars'] --- list of variables used in common blocks (dimensions are moved to variable definitions)
+     B['from'] --- string showing the 'parents' of the current block
+     B['use'] --- dictionary of modules used in current block:
+         {<modulename>:{['only':<0|1>],['map':{<local_name1>:<use_name1>,...}]}}
+     B['note'] --- list of LaTeX comments on the block
+     B['f2pyenhancements'] --- optional dictionary
+          {'threadsafe':'','fortranname':<name>,
+           'callstatement':<C-expr>|<multi-line block>,
+           'callprotoargument':<C-expr-list>,
+           'usercode':<multi-line block>|<list of multi-line blocks>,
+           'pymethoddef:<multi-line block>'
+           }
+     B['entry'] --- dictionary {entryname:argslist,..}
+     B['varnames'] --- list of variable names given in the order of reading the
+                       Fortran code, useful for derived types.
+     B['saved_interface'] --- a string of scanned routine signature, defines explicit interface
+ *** Variable definition is a dictionary
+     D = B['vars'][<variable name>] =
+     {'typespec'[,'attrspec','kindselector','charselector','=','typename']}
+     D['typespec'] = 'byte' | 'character' | 'complex' | 'double complex' |
+                     'double precision' | 'integer' | 'logical' | 'real' | 'type'
+     D['attrspec'] --- list of attributes (e.g. 'dimension(<arrayspec>)',
+                       'external','intent(in|out|inout|hide|c|callback|cache|aligned4|aligned8|aligned16)',
+                       'optional','required', etc)
+     K = D['kindselector'] = {['*','kind']} (only if D['typespec'] =
+                         'complex' | 'integer' | 'logical' | 'real' )
+     C = D['charselector'] = {['*','len','kind']}
+                             (only if D['typespec']=='character')
+     D['='] --- initialization expression string
+     D['typename'] --- name of the type if D['typespec']=='type'
+     D['dimension'] --- list of dimension bounds
+     D['intent'] --- list of intent specifications
+     D['depend'] --- list of variable names on which current variable depends on
+     D['check'] --- list of C-expressions; if C-expr returns zero, exception is raised
+     D['note'] --- list of LaTeX comments on the variable
+ *** Meaning of kind/char selectors (few examples):
+     D['typespec>']*K['*']
+     D['typespec'](kind=K['kind'])
+     character*C['*']
+     character(len=C['len'],kind=C['kind'])
+     (see also fortran type declaration statement formats below)
+
+Fortran 90 type declaration statement format (F77 is subset of F90)
+====================================================================
+(Main source: IBM XL Fortran 5.1 Language Reference Manual)
+type declaration = <typespec> [[<attrspec>]::] <entitydecl>
+<typespec> = byte                          |
+             character[<charselector>]     |
+             complex[<kindselector>]       |
+             double complex                |
+             double precision              |
+             integer[<kindselector>]       |
+             logical[<kindselector>]       |
+             real[<kindselector>]          |
+             type(<typename>)
+<charselector> = * <charlen>               |
+             ([len=]<len>[,[kind=]<kind>]) |
+             (kind=<kind>[,len=<len>])
+<kindselector> = * <intlen>                |
+             ([kind=]<kind>)
+<attrspec> = comma separated list of attributes.
+             Only the following attributes are used in
+             building up the interface:
+                external
+                (parameter --- affects '=' key)
+                optional
+                intent
+             Other attributes are ignored.
+<intentspec> = in | out | inout
+<arrayspec> = comma separated list of dimension bounds.
+<entitydecl> = <name> [[*<charlen>][(<arrayspec>)] | [(<arrayspec>)]*<charlen>]
+                      [/<init_expr>/ | =<init_expr>] [,<entitydecl>]
+
+In addition, the following attributes are used: check,depend,note
+
+TODO:
+    * Apply 'parameter' attribute (e.g. 'integer parameter :: i=2' 'real x(i)'
+                                   -> 'real x(2)')
+    The above may be solved by creating appropriate preprocessor program, for example.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import string
+import fileinput
+import re
+import os
+import copy
+import platform
+
+from . import __version__
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+
+f2py_version = __version__.version
+
+# Global flags:
+strictf77 = 1          # Ignore `!' comments unless line[0]=='!'
+sourcecodeform = 'fix'  # 'fix','free'
+quiet = 0              # Be verbose if 0 (Obsolete: not used any more)
+verbose = 1            # Be quiet if 0, extra verbose if > 1.
+tabchar = 4 * ' '
+pyffilename = ''
+f77modulename = ''
+skipemptyends = 0      # for old F77 programs without 'program' statement
+ignorecontains = 1
+dolowercase = 1
+debug = []
+
+# Global variables
+beginpattern = ''
+currentfilename = ''
+expectbegin = 1
+f90modulevars = {}
+filepositiontext = ''
+gotnextfile = 1
+groupcache = None
+groupcounter = 0
+grouplist = {groupcounter: []}
+groupname = ''
+include_paths = []
+neededmodule = -1
+onlyfuncs = []
+previous_context = None
+skipblocksuntil = -1
+skipfuncs = []
+skipfunctions = []
+usermodules = []
+
+
+def reset_global_f2py_vars():
+    global groupcounter, grouplist, neededmodule, expectbegin
+    global skipblocksuntil, usermodules, f90modulevars, gotnextfile
+    global filepositiontext, currentfilename, skipfunctions, skipfuncs
+    global onlyfuncs, include_paths, previous_context
+    global strictf77, sourcecodeform, quiet, verbose, tabchar, pyffilename
+    global f77modulename, skipemptyends, ignorecontains, dolowercase, debug
+
+    # flags
+    strictf77 = 1
+    sourcecodeform = 'fix'
+    quiet = 0
+    verbose = 1
+    tabchar = 4 * ' '
+    pyffilename = ''
+    f77modulename = ''
+    skipemptyends = 0
+    ignorecontains = 1
+    dolowercase = 1
+    debug = []
+    # variables
+    groupcounter = 0
+    grouplist = {groupcounter: []}
+    neededmodule = -1
+    expectbegin = 1
+    skipblocksuntil = -1
+    usermodules = []
+    f90modulevars = {}
+    gotnextfile = 1
+    filepositiontext = ''
+    currentfilename = ''
+    skipfunctions = []
+    skipfuncs = []
+    onlyfuncs = []
+    include_paths = []
+    previous_context = None
+
+
+def outmess(line, flag=1):
+    global filepositiontext
+
+    if not verbose:
+        return
+    if not quiet:
+        if flag:
+            sys.stdout.write(filepositiontext)
+        sys.stdout.write(line)
+
+re._MAXCACHE = 50
+defaultimplicitrules = {}
+for c in "abcdefghopqrstuvwxyz$_":
+    defaultimplicitrules[c] = {'typespec': 'real'}
+for c in "ijklmn":
+    defaultimplicitrules[c] = {'typespec': 'integer'}
+del c
+badnames = {}
+invbadnames = {}
+for n in ['int', 'double', 'float', 'char', 'short', 'long', 'void', 'case', 'while',
+          'return', 'signed', 'unsigned', 'if', 'for', 'typedef', 'sizeof', 'union',
+          'struct', 'static', 'register', 'new', 'break', 'do', 'goto', 'switch',
+          'continue', 'else', 'inline', 'extern', 'delete', 'const', 'auto',
+          'len', 'rank', 'shape', 'index', 'slen', 'size', '_i',
+          'max', 'min',
+          'flen', 'fshape',
+          'string', 'complex_double', 'float_double', 'stdin', 'stderr', 'stdout',
+          'type', 'default']:
+    badnames[n] = n + '_bn'
+    invbadnames[n + '_bn'] = n
+
+
+def rmbadname1(name):
+    if name in badnames:
+        errmess('rmbadname1: Replacing "%s" with "%s".\n' %
+                (name, badnames[name]))
+        return badnames[name]
+    return name
+
+
+def rmbadname(names):
+    return [rmbadname1(_m) for _m in names]
+
+
+def undo_rmbadname1(name):
+    if name in invbadnames:
+        errmess('undo_rmbadname1: Replacing "%s" with "%s".\n'
+                % (name, invbadnames[name]))
+        return invbadnames[name]
+    return name
+
+
+def undo_rmbadname(names):
+    return [undo_rmbadname1(_m) for _m in names]
+
+
+def getextension(name):
+    i = name.rfind('.')
+    if i == -1:
+        return ''
+    if '\\' in name[i:]:
+        return ''
+    if '/' in name[i:]:
+        return ''
+    return name[i + 1:]
+
+is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
+_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
+_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+_free_f90_start = re.compile(r'[^c*]\s*[^\s\d\t]', re.I).match
+
+
+def is_free_format(file):
+    """Check if file is in free format Fortran."""
+    # f90 allows both fixed and free format, assuming fixed unless
+    # signs of free format are detected.
+    result = 0
+    f = open(file, 'r')
+    line = f.readline()
+    n = 15  # the number of non-comment lines to scan for hints
+    if _has_f_header(line):
+        n = 0
+    elif _has_f90_header(line):
+        n = 0
+        result = 1
+    while n > 0 and line:
+        if line[0] != '!' and line.strip():
+            n -= 1
+            if (line[0] != '\t' and _free_f90_start(line[:5])) or line[-2:-1] == '&':
+                result = 1
+                break
+        line = f.readline()
+    f.close()
+    return result
+
+
+# Read fortran (77,90) code
+def readfortrancode(ffile, dowithline=show, istop=1):
+    """
+    Read fortran codes from files and
+     1) Get rid of comments, line continuations, and empty lines; lower cases.
+     2) Call dowithline(line) on every line.
+     3) Recursively call itself when statement \"include '<filename>'\" is met.
+    """
+    global gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77
+    global beginpattern, quiet, verbose, dolowercase, include_paths
+
+    if not istop:
+        saveglobals = gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\
+            beginpattern, quiet, verbose, dolowercase
+    if ffile == []:
+        return
+    localdolowercase = dolowercase
+    cont = 0
+    finalline = ''
+    ll = ''
+    commentline = re.compile(
+        r'(?P<line>([^"]*["][^"]*["][^"!]*|[^\']*\'[^\']*\'[^\'!]*|[^!\'"]*))!{1}(?P<rest>.*)')
+    includeline = re.compile(
+        r'\s*include\s*(\'|")(?P<name>[^\'"]*)(\'|")', re.I)
+    cont1 = re.compile(r'(?P<line>.*)&\s*\Z')
+    cont2 = re.compile(r'(\s*&|)(?P<line>.*)')
+    mline_mark = re.compile(r".*?'''")
+    if istop:
+        dowithline('', -1)
+    ll, l1 = '', ''
+    spacedigits = [' '] + [str(_m) for _m in range(10)]
+    filepositiontext = ''
+    fin = fileinput.FileInput(ffile)
+    while True:
+        l = fin.readline()
+        if not l:
+            break
+        if fin.isfirstline():
+            filepositiontext = ''
+            currentfilename = fin.filename()
+            gotnextfile = 1
+            l1 = l
+            strictf77 = 0
+            sourcecodeform = 'fix'
+            ext = os.path.splitext(currentfilename)[1]
+            if is_f_file(currentfilename) and \
+                    not (_has_f90_header(l) or _has_fix_header(l)):
+                strictf77 = 1
+            elif is_free_format(currentfilename) and not _has_fix_header(l):
+                sourcecodeform = 'free'
+            if strictf77:
+                beginpattern = beginpattern77
+            else:
+                beginpattern = beginpattern90
+            outmess('\tReading file %s (format:%s%s)\n'
+                    % (repr(currentfilename), sourcecodeform,
+                       strictf77 and ',strict' or ''))
+
+        l = l.expandtabs().replace('\xa0', ' ')
+        # Get rid of newline characters
+        while not l == '':
+            if l[-1] not in "\n\r\f":
+                break
+            l = l[:-1]
+        if not strictf77:
+            r = commentline.match(l)
+            if r:
+                l = r.group('line') + ' '  # Strip comments starting with `!'
+                rl = r.group('rest')
+                if rl[:4].lower() == 'f2py':  # f2py directive
+                    l = l + 4 * ' '
+                    r = commentline.match(rl[4:])
+                    if r:
+                        l = l + r.group('line')
+                    else:
+                        l = l + rl[4:]
+        if l.strip() == '':  # Skip empty line
+            cont = 0
+            continue
+        if sourcecodeform == 'fix':
+            if l[0] in ['*', 'c', '!', 'C', '#']:
+                if l[1:5].lower() == 'f2py':  # f2py directive
+                    l = '     ' + l[5:]
+                else:  # Skip comment line
+                    cont = 0
+                    continue
+            elif strictf77:
+                if len(l) > 72:
+                    l = l[:72]
+            if not (l[0] in spacedigits):
+                raise Exception('readfortrancode: Found non-(space,digit) char '
+                                'in the first column.\n\tAre you sure that '
+                                'this code is in fix form?\n\tline=%s' % repr(l))
+
+            if (not cont or strictf77) and (len(l) > 5 and not l[5] == ' '):
+                # Continuation of a previous line
+                ll = ll + l[6:]
+                finalline = ''
+                origfinalline = ''
+            else:
+                if not strictf77:
+                    # F90 continuation
+                    r = cont1.match(l)
+                    if r:
+                        l = r.group('line')  # Continuation follows ..
+                    if cont:
+                        ll = ll + cont2.match(l).group('line')
+                        finalline = ''
+                        origfinalline = ''
+                    else:
+                        # clean up line beginning from possible digits.
+                        l = '     ' + l[5:]
+                        if localdolowercase:
+                            finalline = ll.lower()
+                        else:
+                            finalline = ll
+                        origfinalline = ll
+                        ll = l
+                    cont = (r is not None)
+                else:
+                    # clean up line beginning from possible digits.
+                    l = '     ' + l[5:]
+                    if localdolowercase:
+                        finalline = ll.lower()
+                    else:
+                        finalline = ll
+                    origfinalline = ll
+                    ll = l
+
+        elif sourcecodeform == 'free':
+            if not cont and ext == '.pyf' and mline_mark.match(l):
+                l = l + '\n'
+                while True:
+                    lc = fin.readline()
+                    if not lc:
+                        errmess(
+                            'Unexpected end of file when reading multiline\n')
+                        break
+                    l = l + lc
+                    if mline_mark.match(lc):
+                        break
+                l = l.rstrip()
+            r = cont1.match(l)
+            if r:
+                l = r.group('line')  # Continuation follows ..
+            if cont:
+                ll = ll + cont2.match(l).group('line')
+                finalline = ''
+                origfinalline = ''
+            else:
+                if localdolowercase:
+                    finalline = ll.lower()
+                else:
+                    finalline = ll
+                origfinalline = ll
+                ll = l
+            cont = (r is not None)
+        else:
+            raise ValueError(
+                "Flag sourcecodeform must be either 'fix' or 'free': %s" % repr(sourcecodeform))
+        filepositiontext = 'Line #%d in %s:"%s"\n\t' % (
+            fin.filelineno() - 1, currentfilename, l1)
+        m = includeline.match(origfinalline)
+        if m:
+            fn = m.group('name')
+            if os.path.isfile(fn):
+                readfortrancode(fn, dowithline=dowithline, istop=0)
+            else:
+                include_dirs = [
+                    os.path.dirname(currentfilename)] + include_paths
+                foundfile = 0
+                for inc_dir in include_dirs:
+                    fn1 = os.path.join(inc_dir, fn)
+                    if os.path.isfile(fn1):
+                        foundfile = 1
+                        readfortrancode(fn1, dowithline=dowithline, istop=0)
+                        break
+                if not foundfile:
+                    outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % (
+                        repr(fn), os.pathsep.join(include_dirs)))
+        else:
+            dowithline(finalline)
+        l1 = ll
+    if localdolowercase:
+        finalline = ll.lower()
+    else:
+        finalline = ll
+    origfinalline = ll
+    filepositiontext = 'Line #%d in %s:"%s"\n\t' % (
+        fin.filelineno() - 1, currentfilename, l1)
+    m = includeline.match(origfinalline)
+    if m:
+        fn = m.group('name')
+        if os.path.isfile(fn):
+            readfortrancode(fn, dowithline=dowithline, istop=0)
+        else:
+            include_dirs = [os.path.dirname(currentfilename)] + include_paths
+            foundfile = 0
+            for inc_dir in include_dirs:
+                fn1 = os.path.join(inc_dir, fn)
+                if os.path.isfile(fn1):
+                    foundfile = 1
+                    readfortrancode(fn1, dowithline=dowithline, istop=0)
+                    break
+            if not foundfile:
+                outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % (
+                    repr(fn), os.pathsep.join(include_dirs)))
+    else:
+        dowithline(finalline)
+    filepositiontext = ''
+    fin.close()
+    if istop:
+        dowithline('', 1)
+    else:
+        gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\
+            beginpattern, quiet, verbose, dolowercase = saveglobals
+
+# Crack line
+beforethisafter = r'\s*(?P<before>%s(?=\s*(\b(%s)\b)))' + \
+    r'\s*(?P<this>(\b(%s)\b))' + \
+    r'\s*(?P<after>%s)\s*\Z'
+##
+fortrantypes = 'character|logical|integer|real|complex|double\s*(precision\s*(complex|)|complex)|type(?=\s*\([\w\s,=(*)]*\))|byte'
+typespattern = re.compile(
+    beforethisafter % ('', fortrantypes, fortrantypes, '.*'), re.I), 'type'
+typespattern4implicit = re.compile(beforethisafter % (
+    '', fortrantypes + '|static|automatic|undefined', fortrantypes + '|static|automatic|undefined', '.*'), re.I)
+#
+functionpattern = re.compile(beforethisafter % (
+    '([a-z]+[\w\s(=*+-/)]*?|)', 'function', 'function', '.*'), re.I), 'begin'
+subroutinepattern = re.compile(beforethisafter % (
+    '[a-z\s]*?', 'subroutine', 'subroutine', '.*'), re.I), 'begin'
+# modulepattern=re.compile(beforethisafter%('[a-z\s]*?','module','module','.*'),re.I),'begin'
+#
+groupbegins77 = r'program|block\s*data'
+beginpattern77 = re.compile(
+    beforethisafter % ('', groupbegins77, groupbegins77, '.*'), re.I), 'begin'
+groupbegins90 = groupbegins77 + \
+    r'|module(?!\s*procedure)|python\s*module|interface|type(?!\s*\()'
+beginpattern90 = re.compile(
+    beforethisafter % ('', groupbegins90, groupbegins90, '.*'), re.I), 'begin'
+groupends = r'end|endprogram|endblockdata|endmodule|endpythonmodule|endinterface'
+endpattern = re.compile(
+    beforethisafter % ('', groupends, groupends, '[\w\s]*'), re.I), 'end'
+# endifs='end\s*(if|do|where|select|while|forall)'
+endifs = '(end\s*(if|do|where|select|while|forall))|(module\s*procedure)'
+endifpattern = re.compile(
+    beforethisafter % ('[\w]*?', endifs, endifs, '[\w\s]*'), re.I), 'endif'
+#
+implicitpattern = re.compile(
+    beforethisafter % ('', 'implicit', 'implicit', '.*'), re.I), 'implicit'
+dimensionpattern = re.compile(beforethisafter % (
+    '', 'dimension|virtual', 'dimension|virtual', '.*'), re.I), 'dimension'
+externalpattern = re.compile(
+    beforethisafter % ('', 'external', 'external', '.*'), re.I), 'external'
+optionalpattern = re.compile(
+    beforethisafter % ('', 'optional', 'optional', '.*'), re.I), 'optional'
+requiredpattern = re.compile(
+    beforethisafter % ('', 'required', 'required', '.*'), re.I), 'required'
+publicpattern = re.compile(
+    beforethisafter % ('', 'public', 'public', '.*'), re.I), 'public'
+privatepattern = re.compile(
+    beforethisafter % ('', 'private', 'private', '.*'), re.I), 'private'
+intrisicpattern = re.compile(
+    beforethisafter % ('', 'intrisic', 'intrisic', '.*'), re.I), 'intrisic'
+intentpattern = re.compile(beforethisafter % (
+    '', 'intent|depend|note|check', 'intent|depend|note|check', '\s*\(.*?\).*'), re.I), 'intent'
+parameterpattern = re.compile(
+    beforethisafter % ('', 'parameter', 'parameter', '\s*\(.*'), re.I), 'parameter'
+datapattern = re.compile(
+    beforethisafter % ('', 'data', 'data', '.*'), re.I), 'data'
+callpattern = re.compile(
+    beforethisafter % ('', 'call', 'call', '.*'), re.I), 'call'
+entrypattern = re.compile(
+    beforethisafter % ('', 'entry', 'entry', '.*'), re.I), 'entry'
+callfunpattern = re.compile(
+    beforethisafter % ('', 'callfun', 'callfun', '.*'), re.I), 'callfun'
+commonpattern = re.compile(
+    beforethisafter % ('', 'common', 'common', '.*'), re.I), 'common'
+usepattern = re.compile(
+    beforethisafter % ('', 'use', 'use', '.*'), re.I), 'use'
+containspattern = re.compile(
+    beforethisafter % ('', 'contains', 'contains', ''), re.I), 'contains'
+formatpattern = re.compile(
+    beforethisafter % ('', 'format', 'format', '.*'), re.I), 'format'
+# Non-fortran and f2py-specific statements
+f2pyenhancementspattern = re.compile(beforethisafter % ('', 'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef',
+                                                        'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef', '.*'), re.I | re.S), 'f2pyenhancements'
+multilinepattern = re.compile(
+    r"\s*(?P<before>''')(?P<this>.*?)(?P<after>''')\s*\Z", re.S), 'multiline'
+##
+
+
+def _simplifyargs(argsline):
+    a = []
+    for n in markoutercomma(argsline).split('@,@'):
+        for r in '(),':
+            n = n.replace(r, '_')
+        a.append(n)
+    return ','.join(a)
+
+crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+[\w]*\b)\s*[=].*', re.I)
+
+
+def crackline(line, reset=0):
+    """
+    reset=-1  --- initialize
+    reset=0   --- crack the line
+    reset=1   --- final check if mismatch of blocks occured
+
+    Cracked data is saved in grouplist[0].
+    """
+    global beginpattern, groupcounter, groupname, groupcache, grouplist
+    global filepositiontext, currentfilename, neededmodule, expectbegin
+    global skipblocksuntil, skipemptyends, previous_context, gotnextfile
+
+    if ';' in line and not (f2pyenhancementspattern[0].match(line) or
+                            multilinepattern[0].match(line)):
+        for l in line.split(';'):
+            # XXX: non-zero reset values need testing
+            assert reset == 0, repr(reset)
+            crackline(l, reset)
+        return
+    if reset < 0:
+        groupcounter = 0
+        groupname = {groupcounter: ''}
+        groupcache = {groupcounter: {}}
+        grouplist = {groupcounter: []}
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['block'] = ''
+        groupcache[groupcounter]['name'] = ''
+        neededmodule = -1
+        skipblocksuntil = -1
+        return
+    if reset > 0:
+        fl = 0
+        if f77modulename and neededmodule == groupcounter:
+            fl = 2
+        while groupcounter > fl:
+            outmess('crackline: groupcounter=%s groupname=%s\n' %
+                    (repr(groupcounter), repr(groupname)))
+            outmess(
+                'crackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement.\n')
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1
+        if f77modulename and neededmodule == groupcounter:
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end interface
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end module
+            neededmodule = -1
+        return
+    if line == '':
+        return
+    flag = 0
+    for pat in [dimensionpattern, externalpattern, intentpattern, optionalpattern,
+                requiredpattern,
+                parameterpattern, datapattern, publicpattern, privatepattern,
+                intrisicpattern,
+                endifpattern, endpattern,
+                formatpattern,
+                beginpattern, functionpattern, subroutinepattern,
+                implicitpattern, typespattern, commonpattern,
+                callpattern, usepattern, containspattern,
+                entrypattern,
+                f2pyenhancementspattern,
+                multilinepattern
+                ]:
+        m = pat[0].match(line)
+        if m:
+            break
+        flag = flag + 1
+    if not m:
+        re_1 = crackline_re_1
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        if 'externals' in groupcache[groupcounter]:
+            for name in groupcache[groupcounter]['externals']:
+                if name in invbadnames:
+                    name = invbadnames[name]
+                if 'interfaced' in groupcache[groupcounter] and name in groupcache[groupcounter]['interfaced']:
+                    continue
+                m1 = re.match(
+                    r'(?P<before>[^"]*)\b%s\b\s*@\(@(?P<args>[^@]*)@\)@.*\Z' % name, markouterparen(line), re.I)
+                if m1:
+                    m2 = re_1.match(m1.group('before'))
+                    a = _simplifyargs(m1.group('args'))
+                    if m2:
+                        line = 'callfun %s(%s) result (%s)' % (
+                            name, a, m2.group('result'))
+                    else:
+                        line = 'callfun %s(%s)' % (name, a)
+                    m = callfunpattern[0].match(line)
+                    if not m:
+                        outmess(
+                            'crackline: could not resolve function call for line=%s.\n' % repr(line))
+                        return
+                    analyzeline(m, 'callfun', line)
+                    return
+        if verbose > 1 or (verbose == 1 and currentfilename.lower().endswith('.pyf')):
+            previous_context = None
+            outmess('crackline:%d: No pattern for line\n' % (groupcounter))
+        return
+    elif pat[1] == 'end':
+        if 0 <= skipblocksuntil < groupcounter:
+            groupcounter = groupcounter - 1
+            if skipblocksuntil <= groupcounter:
+                return
+        if groupcounter <= 0:
+            raise Exception('crackline: groupcounter(=%s) is nonpositive. '
+                            'Check the blocks.'
+                            % (groupcounter))
+        m1 = beginpattern[0].match((line))
+        if (m1) and (not m1.group('this') == groupname[groupcounter]):
+            raise Exception('crackline: End group %s does not match with '
+                            'previous Begin group %s\n\t%s' %
+                            (repr(m1.group('this')), repr(groupname[groupcounter]),
+                             filepositiontext)
+                            )
+        if skipblocksuntil == groupcounter:
+            skipblocksuntil = -1
+        grouplist[groupcounter - 1].append(groupcache[groupcounter])
+        grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+        del grouplist[groupcounter]
+        groupcounter = groupcounter - 1
+        if not skipemptyends:
+            expectbegin = 1
+    elif pat[1] == 'begin':
+        if 0 <= skipblocksuntil <= groupcounter:
+            groupcounter = groupcounter + 1
+            return
+        gotnextfile = 0
+        analyzeline(m, pat[1], line)
+        expectbegin = 0
+    elif pat[1] == 'endif':
+        pass
+    elif pat[1] == 'contains':
+        if ignorecontains:
+            return
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        skipblocksuntil = groupcounter
+    else:
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        analyzeline(m, pat[1], line)
+
+
+def markouterparen(line):
+    l = ''
+    f = 0
+    for c in line:
+        if c == '(':
+            f = f + 1
+            if f == 1:
+                l = l + '@(@'
+                continue
+        elif c == ')':
+            f = f - 1
+            if f == 0:
+                l = l + '@)@'
+                continue
+        l = l + c
+    return l
+
+
+def markoutercomma(line, comma=','):
+    l = ''
+    f = 0
+    cc = ''
+    for c in line:
+        if (not cc or cc == ')') and c == '(':
+            f = f + 1
+            cc = ')'
+        elif not cc and c == '\'' and (not l or l[-1] != '\\'):
+            f = f + 1
+            cc = '\''
+        elif c == cc:
+            f = f - 1
+            if f == 0:
+                cc = ''
+        elif c == comma and f == 0:
+            l = l + '@' + comma + '@'
+            continue
+        l = l + c
+    assert not f, repr((f, line, l, cc))
+    return l
+
+
+def unmarkouterparen(line):
+    r = line.replace('@(@', '(').replace('@)@', ')')
+    return r
+
+
+def appenddecl(decl, decl2, force=1):
+    if not decl:
+        decl = {}
+    if not decl2:
+        return decl
+    if decl is decl2:
+        return decl
+    for k in list(decl2.keys()):
+        if k == 'typespec':
+            if force or k not in decl:
+                decl[k] = decl2[k]
+        elif k == 'attrspec':
+            for l in decl2[k]:
+                decl = setattrspec(decl, l, force)
+        elif k == 'kindselector':
+            decl = setkindselector(decl, decl2[k], force)
+        elif k == 'charselector':
+            decl = setcharselector(decl, decl2[k], force)
+        elif k in ['=', 'typename']:
+            if force or k not in decl:
+                decl[k] = decl2[k]
+        elif k == 'note':
+            pass
+        elif k in ['intent', 'check', 'dimension', 'optional', 'required']:
+            errmess('appenddecl: "%s" not implemented.\n' % k)
+        else:
+            raise Exception('appenddecl: Unknown variable definition key:' +
+                            str(k))
+    return decl
+
+selectpattern = re.compile(
+    r'\s*(?P<this>(@\(@.*?@\)@|[*][\d*]+|[*]\s*@\(@.*?@\)@|))(?P<after>.*)\Z', re.I)
+nameargspattern = re.compile(
+    r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P<bind>.*)\s*@\)@))*\s*\Z', re.I)
+callnameargspattern = re.compile(
+    r'\s*(?P<name>\b[\w$]+\b)\s*@\(@\s*(?P<args>.*)\s*@\)@\s*\Z', re.I)
+real16pattern = re.compile(
+    r'([-+]?(?:\d+(?:\.\d*)?|\d*\.\d+))[dD]((?:[-+]?\d+)?)')
+real8pattern = re.compile(
+    r'([-+]?((?:\d+(?:\.\d*)?|\d*\.\d+))[eE]((?:[-+]?\d+)?)|(\d+\.\d*))')
+
+_intentcallbackpattern = re.compile(r'intent\s*\(.*?\bcallback\b', re.I)
+
+
+def _is_intent_callback(vdecl):
+    for a in vdecl.get('attrspec', []):
+        if _intentcallbackpattern.match(a):
+            return 1
+    return 0
+
+
+def _resolvenameargspattern(line):
+    line = markouterparen(line)
+    m1 = nameargspattern.match(line)
+    if m1:
+        return m1.group('name'), m1.group('args'), m1.group('result'), m1.group('bind')
+    m1 = callnameargspattern.match(line)
+    if m1:
+        return m1.group('name'), m1.group('args'), None, None
+    return None, [], None, None
+
+
+def analyzeline(m, case, line):
+    global groupcounter, groupname, groupcache, grouplist, filepositiontext
+    global currentfilename, f77modulename, neededinterface, neededmodule
+    global expectbegin, gotnextfile, previous_context
+
+    block = m.group('this')
+    if case != 'multiline':
+        previous_context = None
+    if expectbegin and case not in ['begin', 'call', 'callfun', 'type'] \
+       and not skipemptyends and groupcounter < 1:
+        newname = os.path.basename(currentfilename).split('.')[0]
+        outmess(
+            'analyzeline: no group yet. Creating program group with name "%s".\n' % newname)
+        gotnextfile = 0
+        groupcounter = groupcounter + 1
+        groupname[groupcounter] = 'program'
+        groupcache[groupcounter] = {}
+        grouplist[groupcounter] = []
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['block'] = 'program'
+        groupcache[groupcounter]['name'] = newname
+        groupcache[groupcounter]['from'] = 'fromsky'
+        expectbegin = 0
+    if case in ['begin', 'call', 'callfun']:
+        # Crack line => block,name,args,result
+        block = block.lower()
+        if re.match(r'block\s*data', block, re.I):
+            block = 'block data'
+        if re.match(r'python\s*module', block, re.I):
+            block = 'python module'
+        name, args, result, bind = _resolvenameargspattern(m.group('after'))
+        if name is None:
+            if block == 'block data':
+                name = '_BLOCK_DATA_'
+            else:
+                name = ''
+            if block not in ['interface', 'block data']:
+                outmess('analyzeline: No name/args pattern found for line.\n')
+
+        previous_context = (block, name, groupcounter)
+        if args:
+            args = rmbadname([x.strip()
+                              for x in markoutercomma(args).split('@,@')])
+        else:
+            args = []
+        if '' in args:
+            while '' in args:
+                args.remove('')
+            outmess(
+                'analyzeline: argument list is malformed (missing argument).\n')
+
+        # end of crack line => block,name,args,result
+        needmodule = 0
+        needinterface = 0
+
+        if case in ['call', 'callfun']:
+            needinterface = 1
+            if 'args' not in groupcache[groupcounter]:
+                return
+            if name not in groupcache[groupcounter]['args']:
+                return
+            for it in grouplist[groupcounter]:
+                if it['name'] == name:
+                    return
+            if name in groupcache[groupcounter]['interfaced']:
+                return
+            block = {'call': 'subroutine', 'callfun': 'function'}[case]
+        if f77modulename and neededmodule == -1 and groupcounter <= 1:
+            neededmodule = groupcounter + 2
+            needmodule = 1
+            if block != 'interface':
+                needinterface = 1
+        # Create new block(s)
+        groupcounter = groupcounter + 1
+        groupcache[groupcounter] = {}
+        grouplist[groupcounter] = []
+        if needmodule:
+            if verbose > 1:
+                outmess('analyzeline: Creating module block %s\n' %
+                        repr(f77modulename), 0)
+            groupname[groupcounter] = 'module'
+            groupcache[groupcounter]['block'] = 'python module'
+            groupcache[groupcounter]['name'] = f77modulename
+            groupcache[groupcounter]['from'] = ''
+            groupcache[groupcounter]['body'] = []
+            groupcache[groupcounter]['externals'] = []
+            groupcache[groupcounter]['interfaced'] = []
+            groupcache[groupcounter]['vars'] = {}
+            groupcounter = groupcounter + 1
+            groupcache[groupcounter] = {}
+            grouplist[groupcounter] = []
+        if needinterface:
+            if verbose > 1:
+                outmess('analyzeline: Creating additional interface block (groupcounter=%s).\n' % (
+                    groupcounter), 0)
+            groupname[groupcounter] = 'interface'
+            groupcache[groupcounter]['block'] = 'interface'
+            groupcache[groupcounter]['name'] = 'unknown_interface'
+            groupcache[groupcounter]['from'] = '%s:%s' % (
+                groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name'])
+            groupcache[groupcounter]['body'] = []
+            groupcache[groupcounter]['externals'] = []
+            groupcache[groupcounter]['interfaced'] = []
+            groupcache[groupcounter]['vars'] = {}
+            groupcounter = groupcounter + 1
+            groupcache[groupcounter] = {}
+            grouplist[groupcounter] = []
+        groupname[groupcounter] = block
+        groupcache[groupcounter]['block'] = block
+        if not name:
+            name = 'unknown_' + block
+        groupcache[groupcounter]['prefix'] = m.group('before')
+        groupcache[groupcounter]['name'] = rmbadname1(name)
+        groupcache[groupcounter]['result'] = result
+        if groupcounter == 1:
+            groupcache[groupcounter]['from'] = currentfilename
+        else:
+            if f77modulename and groupcounter == 3:
+                groupcache[groupcounter]['from'] = '%s:%s' % (
+                    groupcache[groupcounter - 1]['from'], currentfilename)
+            else:
+                groupcache[groupcounter]['from'] = '%s:%s' % (
+                    groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name'])
+        for k in list(groupcache[groupcounter].keys()):
+            if not groupcache[groupcounter][k]:
+                del groupcache[groupcounter][k]
+
+        groupcache[groupcounter]['args'] = args
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['externals'] = []
+        groupcache[groupcounter]['interfaced'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['entry'] = {}
+        # end of creation
+        if block == 'type':
+            groupcache[groupcounter]['varnames'] = []
+
+        if case in ['call', 'callfun']:  # set parents variables
+            if name not in groupcache[groupcounter - 2]['externals']:
+                groupcache[groupcounter - 2]['externals'].append(name)
+            groupcache[groupcounter]['vars'] = copy.deepcopy(
+                groupcache[groupcounter - 2]['vars'])
+            try:
+                del groupcache[groupcounter]['vars'][name][
+                    groupcache[groupcounter]['vars'][name]['attrspec'].index('external')]
+            except:
+                pass
+        if block in ['function', 'subroutine']:  # set global attributes
+            try:
+                groupcache[groupcounter]['vars'][name] = appenddecl(
+                    groupcache[groupcounter]['vars'][name], groupcache[groupcounter - 2]['vars'][''])
+            except:
+                pass
+            if case == 'callfun':  # return type
+                if result and result in groupcache[groupcounter]['vars']:
+                    if not name == result:
+                        groupcache[groupcounter]['vars'][name] = appenddecl(
+                            groupcache[groupcounter]['vars'][name], groupcache[groupcounter]['vars'][result])
+            # if groupcounter>1: # name is interfaced
+            try:
+                groupcache[groupcounter - 2]['interfaced'].append(name)
+            except:
+                pass
+        if block == 'function':
+            t = typespattern[0].match(m.group('before') + ' ' + name)
+            if t:
+                typespec, selector, attr, edecl = cracktypespec0(
+                    t.group('this'), t.group('after'))
+                updatevars(typespec, selector, attr, edecl)
+
+        if case in ['call', 'callfun']:
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end routine
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end interface
+
+    elif case == 'entry':
+        name, args, result, bind = _resolvenameargspattern(m.group('after'))
+        if name is not None:
+            if args:
+                args = rmbadname([x.strip()
+                                  for x in markoutercomma(args).split('@,@')])
+            else:
+                args = []
+            assert result is None, repr(result)
+            groupcache[groupcounter]['entry'][name] = args
+            previous_context = ('entry', name, groupcounter)
+    elif case == 'type':
+        typespec, selector, attr, edecl = cracktypespec0(
+            block, m.group('after'))
+        last_name = updatevars(typespec, selector, attr, edecl)
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case in ['dimension', 'intent', 'optional', 'required', 'external', 'public', 'private', 'intrisic']:
+        edecl = groupcache[groupcounter]['vars']
+        ll = m.group('after').strip()
+        i = ll.find('::')
+        if i < 0 and case == 'intent':
+            i = markouterparen(ll).find('@)@') - 2
+            ll = ll[:i + 1] + '::' + ll[i + 1:]
+            i = ll.find('::')
+            if ll[i:] == '::' and 'args' in groupcache[groupcounter]:
+                outmess('All arguments will have attribute %s%s\n' %
+                        (m.group('this'), ll[:i]))
+                ll = ll + ','.join(groupcache[groupcounter]['args'])
+        if i < 0:
+            i = 0
+            pl = ''
+        else:
+            pl = ll[:i].strip()
+            ll = ll[i + 2:]
+        ch = markoutercomma(pl).split('@,@')
+        if len(ch) > 1:
+            pl = ch[0]
+            outmess('analyzeline: cannot handle multiple attributes without type specification. Ignoring %r.\n' % (
+                ','.join(ch[1:])))
+        last_name = None
+
+        for e in [x.strip() for x in markoutercomma(ll).split('@,@')]:
+            m1 = namepattern.match(e)
+            if not m1:
+                if case in ['public', 'private']:
+                    k = ''
+                else:
+                    print(m.groupdict())
+                    outmess('analyzeline: no name pattern found in %s statement for %s. Skipping.\n' % (
+                        case, repr(e)))
+                    continue
+            else:
+                k = rmbadname1(m1.group('name'))
+            if k not in edecl:
+                edecl[k] = {}
+            if case == 'dimension':
+                ap = case + m1.group('after')
+            if case == 'intent':
+                ap = m.group('this') + pl
+                if _intentcallbackpattern.match(ap):
+                    if k not in groupcache[groupcounter]['args']:
+                        if groupcounter > 1:
+                            if '__user__' not in groupcache[groupcounter - 2]['name']:
+                                outmess(
+                                    'analyzeline: missing __user__ module (could be nothing)\n')
+                            # fixes ticket 1693
+                            if k != groupcache[groupcounter]['name']:
+                                outmess('analyzeline: appending intent(callback) %s'
+                                        ' to %s arguments\n' % (k, groupcache[groupcounter]['name']))
+                                groupcache[groupcounter]['args'].append(k)
+                        else:
+                            errmess(
+                                'analyzeline: intent(callback) %s is ignored' % (k))
+                    else:
+                        errmess('analyzeline: intent(callback) %s is already'
+                                ' in argument list' % (k))
+            if case in ['optional', 'required', 'public', 'external', 'private', 'intrisic']:
+                ap = case
+            if 'attrspec' in edecl[k]:
+                edecl[k]['attrspec'].append(ap)
+            else:
+                edecl[k]['attrspec'] = [ap]
+            if case == 'external':
+                if groupcache[groupcounter]['block'] == 'program':
+                    outmess('analyzeline: ignoring program arguments\n')
+                    continue
+                if k not in groupcache[groupcounter]['args']:
+                    continue
+                if 'externals' not in groupcache[groupcounter]:
+                    groupcache[groupcounter]['externals'] = []
+                groupcache[groupcounter]['externals'].append(k)
+            last_name = k
+        groupcache[groupcounter]['vars'] = edecl
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'parameter':
+        edecl = groupcache[groupcounter]['vars']
+        ll = m.group('after').strip()[1:-1]
+        last_name = None
+        for e in markoutercomma(ll).split('@,@'):
+            try:
+                k, initexpr = [x.strip() for x in e.split('=')]
+            except:
+                outmess(
+                    'analyzeline: could not extract name,expr in parameter statement "%s" of "%s"\n' % (e, ll))
+                continue
+            params = get_parameters(edecl)
+            k = rmbadname1(k)
+            if k not in edecl:
+                edecl[k] = {}
+            if '=' in edecl[k] and (not edecl[k]['='] == initexpr):
+                outmess('analyzeline: Overwriting the value of parameter "%s" ("%s") with "%s".\n' % (
+                    k, edecl[k]['='], initexpr))
+            t = determineexprtype(initexpr, params)
+            if t:
+                if t.get('typespec') == 'real':
+                    tt = list(initexpr)
+                    for m in real16pattern.finditer(initexpr):
+                        tt[m.start():m.end()] = list(
+                            initexpr[m.start():m.end()].lower().replace('d', 'e'))
+                    initexpr = ''.join(tt)
+                elif t.get('typespec') == 'complex':
+                    initexpr = initexpr[1:].lower().replace('d', 'e').\
+                        replace(',', '+1j*(')
+            try:
+                v = eval(initexpr, {}, params)
+            except (SyntaxError, NameError, TypeError) as msg:
+                errmess('analyzeline: Failed to evaluate %r. Ignoring: %s\n'
+                        % (initexpr, msg))
+                continue
+            edecl[k]['='] = repr(v)
+            if 'attrspec' in edecl[k]:
+                edecl[k]['attrspec'].append('parameter')
+            else:
+                edecl[k]['attrspec'] = ['parameter']
+            last_name = k
+        groupcache[groupcounter]['vars'] = edecl
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'implicit':
+        if m.group('after').strip().lower() == 'none':
+            groupcache[groupcounter]['implicit'] = None
+        elif m.group('after'):
+            if 'implicit' in groupcache[groupcounter]:
+                impl = groupcache[groupcounter]['implicit']
+            else:
+                impl = {}
+            if impl is None:
+                outmess(
+                    'analyzeline: Overwriting earlier "implicit none" statement.\n')
+                impl = {}
+            for e in markoutercomma(m.group('after')).split('@,@'):
+                decl = {}
+                m1 = re.match(
+                    r'\s*(?P<this>.*?)\s*(\(\s*(?P<after>[a-z-, ]+)\s*\)\s*|)\Z', e, re.I)
+                if not m1:
+                    outmess(
+                        'analyzeline: could not extract info of implicit statement part "%s"\n' % (e))
+                    continue
+                m2 = typespattern4implicit.match(m1.group('this'))
+                if not m2:
+                    outmess(
+                        'analyzeline: could not extract types pattern of implicit statement part "%s"\n' % (e))
+                    continue
+                typespec, selector, attr, edecl = cracktypespec0(
+                    m2.group('this'), m2.group('after'))
+                kindselect, charselect, typename = cracktypespec(
+                    typespec, selector)
+                decl['typespec'] = typespec
+                decl['kindselector'] = kindselect
+                decl['charselector'] = charselect
+                decl['typename'] = typename
+                for k in list(decl.keys()):
+                    if not decl[k]:
+                        del decl[k]
+                for r in markoutercomma(m1.group('after')).split('@,@'):
+                    if '-' in r:
+                        try:
+                            begc, endc = [x.strip() for x in r.split('-')]
+                        except:
+                            outmess(
+                                'analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement\n' % r)
+                            continue
+                    else:
+                        begc = endc = r.strip()
+                    if not len(begc) == len(endc) == 1:
+                        outmess(
+                            'analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement (2)\n' % r)
+                        continue
+                    for o in range(ord(begc), ord(endc) + 1):
+                        impl[chr(o)] = decl
+            groupcache[groupcounter]['implicit'] = impl
+    elif case == 'data':
+        ll = []
+        dl = ''
+        il = ''
+        f = 0
+        fc = 1
+        inp = 0
+        for c in m.group('after'):
+            if not inp:
+                if c == "'":
+                    fc = not fc
+                if c == '/' and fc:
+                    f = f + 1
+                    continue
+            if c == '(':
+                inp = inp + 1
+            elif c == ')':
+                inp = inp - 1
+            if f == 0:
+                dl = dl + c
+            elif f == 1:
+                il = il + c
+            elif f == 2:
+                dl = dl.strip()
+                if dl.startswith(','):
+                    dl = dl[1:].strip()
+                ll.append([dl, il])
+                dl = c
+                il = ''
+                f = 0
+        if f == 2:
+            dl = dl.strip()
+            if dl.startswith(','):
+                dl = dl[1:].strip()
+            ll.append([dl, il])
+        vars = {}
+        if 'vars' in groupcache[groupcounter]:
+            vars = groupcache[groupcounter]['vars']
+        last_name = None
+        for l in ll:
+            l = [x.strip() for x in l]
+            if l[0][0] == ',':
+                l[0] = l[0][1:]
+            if l[0][0] == '(':
+                outmess(
+                    'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % l[0])
+                continue
+            i = 0
+            j = 0
+            llen = len(l[1])
+            for v in rmbadname([x.strip() for x in markoutercomma(l[0]).split('@,@')]):
+                if v[0] == '(':
+                    outmess(
+                        'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % v)
+                    # XXX: subsequent init expressions may get wrong values.
+                    # Ignoring since data statements are irrelevant for
+                    # wrapping.
+                    continue
+                fc = 0
+                while (i < llen) and (fc or not l[1][i] == ','):
+                    if l[1][i] == "'":
+                        fc = not fc
+                    i = i + 1
+                i = i + 1
+                if v not in vars:
+                    vars[v] = {}
+                if '=' in vars[v] and not vars[v]['='] == l[1][j:i - 1]:
+                    outmess('analyzeline: changing init expression of "%s" ("%s") to "%s"\n' % (
+                        v, vars[v]['='], l[1][j:i - 1]))
+                vars[v]['='] = l[1][j:i - 1]
+                j = i
+                last_name = v
+        groupcache[groupcounter]['vars'] = vars
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'common':
+        line = m.group('after').strip()
+        if not line[0] == '/':
+            line = '//' + line
+        cl = []
+        f = 0
+        bn = ''
+        ol = ''
+        for c in line:
+            if c == '/':
+                f = f + 1
+                continue
+            if f >= 3:
+                bn = bn.strip()
+                if not bn:
+                    bn = '_BLNK_'
+                cl.append([bn, ol])
+                f = f - 2
+                bn = ''
+                ol = ''
+            if f % 2:
+                bn = bn + c
+            else:
+                ol = ol + c
+        bn = bn.strip()
+        if not bn:
+            bn = '_BLNK_'
+        cl.append([bn, ol])
+        commonkey = {}
+        if 'common' in groupcache[groupcounter]:
+            commonkey = groupcache[groupcounter]['common']
+        for c in cl:
+            if c[0] not in commonkey:
+                commonkey[c[0]] = []
+            for i in [x.strip() for x in markoutercomma(c[1]).split('@,@')]:
+                if i:
+                    commonkey[c[0]].append(i)
+        groupcache[groupcounter]['common'] = commonkey
+        previous_context = ('common', bn, groupcounter)
+    elif case == 'use':
+        m1 = re.match(
+            r'\A\s*(?P<name>\b[\w]+\b)\s*((,(\s*\bonly\b\s*:|(?P<notonly>))\s*(?P<list>.*))|)\s*\Z', m.group('after'), re.I)
+        if m1:
+            mm = m1.groupdict()
+            if 'use' not in groupcache[groupcounter]:
+                groupcache[groupcounter]['use'] = {}
+            name = m1.group('name')
+            groupcache[groupcounter]['use'][name] = {}
+            isonly = 0
+            if 'list' in mm and mm['list'] is not None:
+                if 'notonly' in mm and mm['notonly'] is None:
+                    isonly = 1
+                groupcache[groupcounter]['use'][name]['only'] = isonly
+                ll = [x.strip() for x in mm['list'].split(',')]
+                rl = {}
+                for l in ll:
+                    if '=' in l:
+                        m2 = re.match(
+                            r'\A\s*(?P<local>\b[\w]+\b)\s*=\s*>\s*(?P<use>\b[\w]+\b)\s*\Z', l, re.I)
+                        if m2:
+                            rl[m2.group('local').strip()] = m2.group(
+                                'use').strip()
+                        else:
+                            outmess(
+                                'analyzeline: Not local=>use pattern found in %s\n' % repr(l))
+                    else:
+                        rl[l] = l
+                    groupcache[groupcounter]['use'][name]['map'] = rl
+            else:
+                pass
+        else:
+            print(m.groupdict())
+            outmess('analyzeline: Could not crack the use statement.\n')
+    elif case in ['f2pyenhancements']:
+        if 'f2pyenhancements' not in groupcache[groupcounter]:
+            groupcache[groupcounter]['f2pyenhancements'] = {}
+        d = groupcache[groupcounter]['f2pyenhancements']
+        if m.group('this') == 'usercode' and 'usercode' in d:
+            if isinstance(d['usercode'], str):
+                d['usercode'] = [d['usercode']]
+            d['usercode'].append(m.group('after'))
+        else:
+            d[m.group('this')] = m.group('after')
+    elif case == 'multiline':
+        if previous_context is None:
+            if verbose:
+                outmess('analyzeline: No context for multiline block.\n')
+            return
+        gc = groupcounter
+        appendmultiline(groupcache[gc],
+                        previous_context[:2],
+                        m.group('this'))
+    else:
+        if verbose > 1:
+            print(m.groupdict())
+            outmess('analyzeline: No code implemented for line.\n')
+
+
+def appendmultiline(group, context_name, ml):
+    if 'f2pymultilines' not in group:
+        group['f2pymultilines'] = {}
+    d = group['f2pymultilines']
+    if context_name not in d:
+        d[context_name] = []
+    d[context_name].append(ml)
+    return
+
+
+def cracktypespec0(typespec, ll):
+    selector = None
+    attr = None
+    if re.match(r'double\s*complex', typespec, re.I):
+        typespec = 'double complex'
+    elif re.match(r'double\s*precision', typespec, re.I):
+        typespec = 'double precision'
+    else:
+        typespec = typespec.strip().lower()
+    m1 = selectpattern.match(markouterparen(ll))
+    if not m1:
+        outmess(
+            'cracktypespec0: no kind/char_selector pattern found for line.\n')
+        return
+    d = m1.groupdict()
+    for k in list(d.keys()):
+        d[k] = unmarkouterparen(d[k])
+    if typespec in ['complex', 'integer', 'logical', 'real', 'character', 'type']:
+        selector = d['this']
+        ll = d['after']
+    i = ll.find('::')
+    if i >= 0:
+        attr = ll[:i].strip()
+        ll = ll[i + 2:]
+    return typespec, selector, attr, ll
+#####
+namepattern = re.compile(r'\s*(?P<name>\b[\w]+\b)\s*(?P<after>.*)\s*\Z', re.I)
+kindselector = re.compile(
+    r'\s*(\(\s*(kind\s*=)?\s*(?P<kind>.*)\s*\)|[*]\s*(?P<kind2>.*?))\s*\Z', re.I)
+charselector = re.compile(
+    r'\s*(\((?P<lenkind>.*)\)|[*]\s*(?P<charlen>.*))\s*\Z', re.I)
+lenkindpattern = re.compile(
+    r'\s*(kind\s*=\s*(?P<kind>.*?)\s*(@,@\s*len\s*=\s*(?P<len>.*)|)|(len\s*=\s*|)(?P<len2>.*?)\s*(@,@\s*(kind\s*=\s*|)(?P<kind2>.*)|))\s*\Z', re.I)
+lenarraypattern = re.compile(
+    r'\s*(@\(@\s*(?!/)\s*(?P<array>.*?)\s*@\)@\s*[*]\s*(?P<len>.*?)|([*]\s*(?P<len2>.*?)|)\s*(@\(@\s*(?!/)\s*(?P<array2>.*?)\s*@\)@|))\s*(=\s*(?P<init>.*?)|(@\(@|)/\s*(?P<init2>.*?)\s*/(@\)@|)|)\s*\Z', re.I)
+
+
+def removespaces(expr):
+    expr = expr.strip()
+    if len(expr) <= 1:
+        return expr
+    expr2 = expr[0]
+    for i in range(1, len(expr) - 1):
+        if (expr[i] == ' ' and
+            ((expr[i + 1] in "()[]{}=+-/* ") or
+                (expr[i - 1] in "()[]{}=+-/* "))):
+            continue
+        expr2 = expr2 + expr[i]
+    expr2 = expr2 + expr[-1]
+    return expr2
+
+
+def markinnerspaces(line):
+    l = ''
+    f = 0
+    cc = '\''
+    cb = ''
+    for c in line:
+        if cb == '\\' and c in ['\\', '\'', '"']:
+            l = l + c
+            cb = c
+            continue
+        if f == 0 and c in ['\'', '"']:
+            cc = c
+        if c == cc:
+            f = f + 1
+        elif c == cc:
+            f = f - 1
+        elif c == ' ' and f == 1:
+            l = l + '@_@'
+            continue
+        l = l + c
+        cb = c
+    return l
+
+
+def updatevars(typespec, selector, attrspec, entitydecl):
+    global groupcache, groupcounter
+
+    last_name = None
+    kindselect, charselect, typename = cracktypespec(typespec, selector)
+    if attrspec:
+        attrspec = [x.strip() for x in markoutercomma(attrspec).split('@,@')]
+        l = []
+        c = re.compile(r'(?P<start>[a-zA-Z]+)')
+        for a in attrspec:
+            if not a:
+                continue
+            m = c.match(a)
+            if m:
+                s = m.group('start').lower()
+                a = s + a[len(s):]
+            l.append(a)
+        attrspec = l
+    el = [x.strip() for x in markoutercomma(entitydecl).split('@,@')]
+    el1 = []
+    for e in el:
+        for e1 in [x.strip() for x in markoutercomma(removespaces(markinnerspaces(e)), comma=' ').split('@ @')]:
+            if e1:
+                el1.append(e1.replace('@_@', ' '))
+    for e in el1:
+        m = namepattern.match(e)
+        if not m:
+            outmess(
+                'updatevars: no name pattern found for entity=%s. Skipping.\n' % (repr(e)))
+            continue
+        ename = rmbadname1(m.group('name'))
+        edecl = {}
+        if ename in groupcache[groupcounter]['vars']:
+            edecl = groupcache[groupcounter]['vars'][ename].copy()
+            not_has_typespec = 'typespec' not in edecl
+            if not_has_typespec:
+                edecl['typespec'] = typespec
+            elif typespec and (not typespec == edecl['typespec']):
+                outmess('updatevars: attempt to change the type of "%s" ("%s") to "%s". Ignoring.\n' % (
+                    ename, edecl['typespec'], typespec))
+            if 'kindselector' not in edecl:
+                edecl['kindselector'] = copy.copy(kindselect)
+            elif kindselect:
+                for k in list(kindselect.keys()):
+                    if k in edecl['kindselector'] and (not kindselect[k] == edecl['kindselector'][k]):
+                        outmess('updatevars: attempt to change the kindselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            k, ename, edecl['kindselector'][k], kindselect[k]))
+                    else:
+                        edecl['kindselector'][k] = copy.copy(kindselect[k])
+            if 'charselector' not in edecl and charselect:
+                if not_has_typespec:
+                    edecl['charselector'] = charselect
+                else:
+                    errmess('updatevars:%s: attempt to change empty charselector to %r. Ignoring.\n'
+                            % (ename, charselect))
+            elif charselect:
+                for k in list(charselect.keys()):
+                    if k in edecl['charselector'] and (not charselect[k] == edecl['charselector'][k]):
+                        outmess('updatevars: attempt to change the charselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            k, ename, edecl['charselector'][k], charselect[k]))
+                    else:
+                        edecl['charselector'][k] = copy.copy(charselect[k])
+            if 'typename' not in edecl:
+                edecl['typename'] = typename
+            elif typename and (not edecl['typename'] == typename):
+                outmess('updatevars: attempt to change the typename of "%s" ("%s") to "%s". Ignoring.\n' % (
+                    ename, edecl['typename'], typename))
+            if 'attrspec' not in edecl:
+                edecl['attrspec'] = copy.copy(attrspec)
+            elif attrspec:
+                for a in attrspec:
+                    if a not in edecl['attrspec']:
+                        edecl['attrspec'].append(a)
+        else:
+            edecl['typespec'] = copy.copy(typespec)
+            edecl['kindselector'] = copy.copy(kindselect)
+            edecl['charselector'] = copy.copy(charselect)
+            edecl['typename'] = typename
+            edecl['attrspec'] = copy.copy(attrspec)
+        if m.group('after'):
+            m1 = lenarraypattern.match(markouterparen(m.group('after')))
+            if m1:
+                d1 = m1.groupdict()
+                for lk in ['len', 'array', 'init']:
+                    if d1[lk + '2'] is not None:
+                        d1[lk] = d1[lk + '2']
+                        del d1[lk + '2']
+                for k in list(d1.keys()):
+                    if d1[k] is not None:
+                        d1[k] = unmarkouterparen(d1[k])
+                    else:
+                        del d1[k]
+                if 'len' in d1 and 'array' in d1:
+                    if d1['len'] == '':
+                        d1['len'] = d1['array']
+                        del d1['array']
+                    else:
+                        d1['array'] = d1['array'] + ',' + d1['len']
+                        del d1['len']
+                        errmess('updatevars: "%s %s" is mapped to "%s %s(%s)"\n' % (
+                            typespec, e, typespec, ename, d1['array']))
+                if 'array' in d1:
+                    dm = 'dimension(%s)' % d1['array']
+                    if 'attrspec' not in edecl or (not edecl['attrspec']):
+                        edecl['attrspec'] = [dm]
+                    else:
+                        edecl['attrspec'].append(dm)
+                        for dm1 in edecl['attrspec']:
+                            if dm1[:9] == 'dimension' and dm1 != dm:
+                                del edecl['attrspec'][-1]
+                                errmess('updatevars:%s: attempt to change %r to %r. Ignoring.\n'
+                                        % (ename, dm1, dm))
+                                break
+
+                if 'len' in d1:
+                    if typespec in ['complex', 'integer', 'logical', 'real']:
+                        if ('kindselector' not in edecl) or (not edecl['kindselector']):
+                            edecl['kindselector'] = {}
+                        edecl['kindselector']['*'] = d1['len']
+                    elif typespec == 'character':
+                        if ('charselector' not in edecl) or (not edecl['charselector']):
+                            edecl['charselector'] = {}
+                        if 'len' in edecl['charselector']:
+                            del edecl['charselector']['len']
+                        edecl['charselector']['*'] = d1['len']
+                if 'init' in d1:
+                    if '=' in edecl and (not edecl['='] == d1['init']):
+                        outmess('updatevars: attempt to change the init expression of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            ename, edecl['='], d1['init']))
+                    else:
+                        edecl['='] = d1['init']
+            else:
+                outmess('updatevars: could not crack entity declaration "%s". Ignoring.\n' % (
+                    ename + m.group('after')))
+        for k in list(edecl.keys()):
+            if not edecl[k]:
+                del edecl[k]
+        groupcache[groupcounter]['vars'][ename] = edecl
+        if 'varnames' in groupcache[groupcounter]:
+            groupcache[groupcounter]['varnames'].append(ename)
+        last_name = ename
+    return last_name
+
+
+def cracktypespec(typespec, selector):
+    kindselect = None
+    charselect = None
+    typename = None
+    if selector:
+        if typespec in ['complex', 'integer', 'logical', 'real']:
+            kindselect = kindselector.match(selector)
+            if not kindselect:
+                outmess(
+                    'cracktypespec: no kindselector pattern found for %s\n' % (repr(selector)))
+                return
+            kindselect = kindselect.groupdict()
+            kindselect['*'] = kindselect['kind2']
+            del kindselect['kind2']
+            for k in list(kindselect.keys()):
+                if not kindselect[k]:
+                    del kindselect[k]
+            for k, i in list(kindselect.items()):
+                kindselect[k] = rmbadname1(i)
+        elif typespec == 'character':
+            charselect = charselector.match(selector)
+            if not charselect:
+                outmess(
+                    'cracktypespec: no charselector pattern found for %s\n' % (repr(selector)))
+                return
+            charselect = charselect.groupdict()
+            charselect['*'] = charselect['charlen']
+            del charselect['charlen']
+            if charselect['lenkind']:
+                lenkind = lenkindpattern.match(
+                    markoutercomma(charselect['lenkind']))
+                lenkind = lenkind.groupdict()
+                for lk in ['len', 'kind']:
+                    if lenkind[lk + '2']:
+                        lenkind[lk] = lenkind[lk + '2']
+                    charselect[lk] = lenkind[lk]
+                    del lenkind[lk + '2']
+            del charselect['lenkind']
+            for k in list(charselect.keys()):
+                if not charselect[k]:
+                    del charselect[k]
+            for k, i in list(charselect.items()):
+                charselect[k] = rmbadname1(i)
+        elif typespec == 'type':
+            typename = re.match(r'\s*\(\s*(?P<name>\w+)\s*\)', selector, re.I)
+            if typename:
+                typename = typename.group('name')
+            else:
+                outmess('cracktypespec: no typename found in %s\n' %
+                        (repr(typespec + selector)))
+        else:
+            outmess('cracktypespec: no selector used for %s\n' %
+                    (repr(selector)))
+    return kindselect, charselect, typename
+######
+
+
+def setattrspec(decl, attr, force=0):
+    if not decl:
+        decl = {}
+    if not attr:
+        return decl
+    if 'attrspec' not in decl:
+        decl['attrspec'] = [attr]
+        return decl
+    if force:
+        decl['attrspec'].append(attr)
+    if attr in decl['attrspec']:
+        return decl
+    if attr == 'static' and 'automatic' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'automatic' and 'static' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'public' and 'private' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'private' and 'public' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    else:
+        decl['attrspec'].append(attr)
+    return decl
+
+
+def setkindselector(decl, sel, force=0):
+    if not decl:
+        decl = {}
+    if not sel:
+        return decl
+    if 'kindselector' not in decl:
+        decl['kindselector'] = sel
+        return decl
+    for k in list(sel.keys()):
+        if force or k not in decl['kindselector']:
+            decl['kindselector'][k] = sel[k]
+    return decl
+
+
+def setcharselector(decl, sel, force=0):
+    if not decl:
+        decl = {}
+    if not sel:
+        return decl
+    if 'charselector' not in decl:
+        decl['charselector'] = sel
+        return decl
+    for k in list(sel.keys()):
+        if force or k not in decl['charselector']:
+            decl['charselector'][k] = sel[k]
+    return decl
+
+
+def getblockname(block, unknown='unknown'):
+    if 'name' in block:
+        return block['name']
+    return unknown
+
+# post processing
+
+
+def setmesstext(block):
+    global filepositiontext
+
+    try:
+        filepositiontext = 'In: %s:%s\n' % (block['from'], block['name'])
+    except:
+        pass
+
+
+def get_usedict(block):
+    usedict = {}
+    if 'parent_block' in block:
+        usedict = get_usedict(block['parent_block'])
+    if 'use' in block:
+        usedict.update(block['use'])
+    return usedict
+
+
+def get_useparameters(block, param_map=None):
+    global f90modulevars
+
+    if param_map is None:
+        param_map = {}
+    usedict = get_usedict(block)
+    if not usedict:
+        return param_map
+    for usename, mapping in list(usedict.items()):
+        usename = usename.lower()
+        if usename not in f90modulevars:
+            outmess('get_useparameters: no module %s info used by %s\n' %
+                    (usename, block.get('name')))
+            continue
+        mvars = f90modulevars[usename]
+        params = get_parameters(mvars)
+        if not params:
+            continue
+        # XXX: apply mapping
+        if mapping:
+            errmess('get_useparameters: mapping for %s not impl.' % (mapping))
+        for k, v in list(params.items()):
+            if k in param_map:
+                outmess('get_useparameters: overriding parameter %s with'
+                        ' value from module %s' % (repr(k), repr(usename)))
+            param_map[k] = v
+
+    return param_map
+
+
+def postcrack2(block, tab='', param_map=None):
+    global f90modulevars
+
+    if not f90modulevars:
+        return block
+    if isinstance(block, list):
+        ret = []
+        for g in block:
+            g = postcrack2(g, tab=tab + '\t', param_map=param_map)
+            ret.append(g)
+        return ret
+    setmesstext(block)
+    outmess('%sBlock: %s\n' % (tab, block['name']), 0)
+
+    if param_map is None:
+        param_map = get_useparameters(block)
+
+    if param_map is not None and 'vars' in block:
+        vars = block['vars']
+        for n in list(vars.keys()):
+            var = vars[n]
+            if 'kindselector' in var:
+                kind = var['kindselector']
+                if 'kind' in kind:
+                    val = kind['kind']
+                    if val in param_map:
+                        kind['kind'] = param_map[val]
+    new_body = []
+    for b in block['body']:
+        b = postcrack2(b, tab=tab + '\t', param_map=param_map)
+        new_body.append(b)
+    block['body'] = new_body
+
+    return block
+
+
+def postcrack(block, args=None, tab=''):
+    """
+    TODO:
+          function return values
+          determine expression types if in argument list
+    """
+    global usermodules, onlyfunctions
+
+    if isinstance(block, list):
+        gret = []
+        uret = []
+        for g in block:
+            setmesstext(g)
+            g = postcrack(g, tab=tab + '\t')
+            # sort user routines to appear first
+            if 'name' in g and '__user__' in g['name']:
+                uret.append(g)
+            else:
+                gret.append(g)
+        return uret + gret
+    setmesstext(block)
+    if not isinstance(block, dict) and 'block' not in block:
+        raise Exception('postcrack: Expected block dictionary instead of ' +
+                        str(block))
+    if 'name' in block and not block['name'] == 'unknown_interface':
+        outmess('%sBlock: %s\n' % (tab, block['name']), 0)
+    block = analyzeargs(block)
+    block = analyzecommon(block)
+    block['vars'] = analyzevars(block)
+    block['sortvars'] = sortvarnames(block['vars'])
+    if 'args' in block and block['args']:
+        args = block['args']
+    block['body'] = analyzebody(block, args, tab=tab)
+
+    userisdefined = []
+    if 'use' in block:
+        useblock = block['use']
+        for k in list(useblock.keys()):
+            if '__user__' in k:
+                userisdefined.append(k)
+    else:
+        useblock = {}
+    name = ''
+    if 'name' in block:
+        name = block['name']
+    # and not userisdefined: # Build a __user__ module
+    if 'externals' in block and block['externals']:
+        interfaced = []
+        if 'interfaced' in block:
+            interfaced = block['interfaced']
+        mvars = copy.copy(block['vars'])
+        if name:
+            mname = name + '__user__routines'
+        else:
+            mname = 'unknown__user__routines'
+        if mname in userisdefined:
+            i = 1
+            while '%s_%i' % (mname, i) in userisdefined:
+                i = i + 1
+            mname = '%s_%i' % (mname, i)
+        interface = {'block': 'interface', 'body': [],
+                     'vars': {}, 'name': name + '_user_interface'}
+        for e in block['externals']:
+            if e in interfaced:
+                edef = []
+                j = -1
+                for b in block['body']:
+                    j = j + 1
+                    if b['block'] == 'interface':
+                        i = -1
+                        for bb in b['body']:
+                            i = i + 1
+                            if 'name' in bb and bb['name'] == e:
+                                edef = copy.copy(bb)
+                                del b['body'][i]
+                                break
+                        if edef:
+                            if not b['body']:
+                                del block['body'][j]
+                            del interfaced[interfaced.index(e)]
+                            break
+                interface['body'].append(edef)
+            else:
+                if e in mvars and not isexternal(mvars[e]):
+                    interface['vars'][e] = mvars[e]
+        if interface['vars'] or interface['body']:
+            block['interfaced'] = interfaced
+            mblock = {'block': 'python module', 'body': [
+                interface], 'vars': {}, 'name': mname, 'interfaced': block['externals']}
+            useblock[mname] = {}
+            usermodules.append(mblock)
+    if useblock:
+        block['use'] = useblock
+    return block
+
+
+def sortvarnames(vars):
+    indep = []
+    dep = []
+    for v in list(vars.keys()):
+        if 'depend' in vars[v] and vars[v]['depend']:
+            dep.append(v)
+        else:
+            indep.append(v)
+    n = len(dep)
+    i = 0
+    while dep:  # XXX: How to catch dependence cycles correctly?
+        v = dep[0]
+        fl = 0
+        for w in dep[1:]:
+            if w in vars[v]['depend']:
+                fl = 1
+                break
+        if fl:
+            dep = dep[1:] + [v]
+            i = i + 1
+            if i > n:
+                errmess('sortvarnames: failed to compute dependencies because'
+                        ' of cyclic dependencies between '
+                        + ', '.join(dep) + '\n')
+                indep = indep + dep
+                break
+        else:
+            indep.append(v)
+            dep = dep[1:]
+            n = len(dep)
+            i = 0
+    return indep
+
+
+def analyzecommon(block):
+    if not hascommon(block):
+        return block
+    commonvars = []
+    for k in list(block['common'].keys()):
+        comvars = []
+        for e in block['common'][k]:
+            m = re.match(
+                r'\A\s*\b(?P<name>.*?)\b\s*(\((?P<dims>.*?)\)|)\s*\Z', e, re.I)
+            if m:
+                dims = []
+                if m.group('dims'):
+                    dims = [x.strip()
+                            for x in markoutercomma(m.group('dims')).split('@,@')]
+                n = m.group('name').strip()
+                if n in block['vars']:
+                    if 'attrspec' in block['vars'][n]:
+                        block['vars'][n]['attrspec'].append(
+                            'dimension(%s)' % (','.join(dims)))
+                    else:
+                        block['vars'][n]['attrspec'] = [
+                            'dimension(%s)' % (','.join(dims))]
+                else:
+                    if dims:
+                        block['vars'][n] = {
+                            'attrspec': ['dimension(%s)' % (','.join(dims))]}
+                    else:
+                        block['vars'][n] = {}
+                if n not in commonvars:
+                    commonvars.append(n)
+            else:
+                n = e
+                errmess(
+                    'analyzecommon: failed to extract "<name>[(<dims>)]" from "%s" in common /%s/.\n' % (e, k))
+            comvars.append(n)
+        block['common'][k] = comvars
+    if 'commonvars' not in block:
+        block['commonvars'] = commonvars
+    else:
+        block['commonvars'] = block['commonvars'] + commonvars
+    return block
+
+
+def analyzebody(block, args, tab=''):
+    global usermodules, skipfuncs, onlyfuncs, f90modulevars
+
+    setmesstext(block)
+    body = []
+    for b in block['body']:
+        b['parent_block'] = block
+        if b['block'] in ['function', 'subroutine']:
+            if args is not None and b['name'] not in args:
+                continue
+            else:
+                as_ = b['args']
+            if b['name'] in skipfuncs:
+                continue
+            if onlyfuncs and b['name'] not in onlyfuncs:
+                continue
+            b['saved_interface'] = crack2fortrangen(
+                b, '\n' + ' ' * 6, as_interface=True)
+
+        else:
+            as_ = args
+        b = postcrack(b, as_, tab=tab + '\t')
+        if b['block'] == 'interface' and not b['body']:
+            if 'f2pyenhancements' not in b:
+                continue
+        if b['block'].replace(' ', '') == 'pythonmodule':
+            usermodules.append(b)
+        else:
+            if b['block'] == 'module':
+                f90modulevars[b['name']] = b['vars']
+            body.append(b)
+    return body
+
+
+def buildimplicitrules(block):
+    setmesstext(block)
+    implicitrules = defaultimplicitrules
+    attrrules = {}
+    if 'implicit' in block:
+        if block['implicit'] is None:
+            implicitrules = None
+            if verbose > 1:
+                outmess(
+                    'buildimplicitrules: no implicit rules for routine %s.\n' % repr(block['name']))
+        else:
+            for k in list(block['implicit'].keys()):
+                if block['implicit'][k].get('typespec') not in ['static', 'automatic']:
+                    implicitrules[k] = block['implicit'][k]
+                else:
+                    attrrules[k] = block['implicit'][k]['typespec']
+    return implicitrules, attrrules
+
+
+def myeval(e, g=None, l=None):
+    r = eval(e, g, l)
+    if type(r) in [type(0), type(0.0)]:
+        return r
+    raise ValueError('r=%r' % (r))
+
+getlincoef_re_1 = re.compile(r'\A\b\w+\b\Z', re.I)
+
+
+def getlincoef(e, xset):  # e = a*x+b ; x in xset
+    try:
+        c = int(myeval(e, {}, {}))
+        return 0, c, None
+    except:
+        pass
+    if getlincoef_re_1.match(e):
+        return 1, 0, e
+    len_e = len(e)
+    for x in xset:
+        if len(x) > len_e:
+            continue
+        if re.search(r'\w\s*\([^)]*\b' + x + r'\b', e):
+            # skip function calls having x as an argument, e.g max(1, x)
+            continue
+        re_1 = re.compile(r'(?P<before>.*?)\b' + x + r'\b(?P<after>.*)', re.I)
+        m = re_1.match(e)
+        if m:
+            try:
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 0, m1.group('after'))
+                    m1 = re_1.match(ee)
+                b = myeval(ee, {}, {})
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 1, m1.group('after'))
+                    m1 = re_1.match(ee)
+                a = myeval(ee, {}, {}) - b
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 0.5, m1.group('after'))
+                    m1 = re_1.match(ee)
+                c = myeval(ee, {}, {})
+                # computing another point to be sure that expression is linear
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 1.5, m1.group('after'))
+                    m1 = re_1.match(ee)
+                c2 = myeval(ee, {}, {})
+                if (a * 0.5 + b == c and a * 1.5 + b == c2):
+                    return a, b, x
+            except:
+                pass
+            break
+    return None, None, None
+
+_varname_match = re.compile(r'\A[a-z]\w*\Z').match
+
+
+def getarrlen(dl, args, star='*'):
+    edl = []
+    try:
+        edl.append(myeval(dl[0], {}, {}))
+    except:
+        edl.append(dl[0])
+    try:
+        edl.append(myeval(dl[1], {}, {}))
+    except:
+        edl.append(dl[1])
+    if isinstance(edl[0], int):
+        p1 = 1 - edl[0]
+        if p1 == 0:
+            d = str(dl[1])
+        elif p1 < 0:
+            d = '%s-%s' % (dl[1], -p1)
+        else:
+            d = '%s+%s' % (dl[1], p1)
+    elif isinstance(edl[1], int):
+        p1 = 1 + edl[1]
+        if p1 == 0:
+            d = '-(%s)' % (dl[0])
+        else:
+            d = '%s-(%s)' % (p1, dl[0])
+    else:
+        d = '%s-(%s)+1' % (dl[1], dl[0])
+    try:
+        return repr(myeval(d, {}, {})), None, None
+    except:
+        pass
+    d1, d2 = getlincoef(dl[0], args), getlincoef(dl[1], args)
+    if None not in [d1[0], d2[0]]:
+        if (d1[0], d2[0]) == (0, 0):
+            return repr(d2[1] - d1[1] + 1), None, None
+        b = d2[1] - d1[1] + 1
+        d1 = (d1[0], 0, d1[2])
+        d2 = (d2[0], b, d2[2])
+        if d1[0] == 0 and d2[2] in args:
+            if b < 0:
+                return '%s * %s - %s' % (d2[0], d2[2], -b), d2[2], '+%s)/(%s)' % (-b, d2[0])
+            elif b:
+                return '%s * %s + %s' % (d2[0], d2[2], b), d2[2], '-%s)/(%s)' % (b, d2[0])
+            else:
+                return '%s * %s' % (d2[0], d2[2]), d2[2], ')/(%s)' % (d2[0])
+        if d2[0] == 0 and d1[2] in args:
+
+            if b < 0:
+                return '%s * %s - %s' % (-d1[0], d1[2], -b), d1[2], '+%s)/(%s)' % (-b, -d1[0])
+            elif b:
+                return '%s * %s + %s' % (-d1[0], d1[2], b), d1[2], '-%s)/(%s)' % (b, -d1[0])
+            else:
+                return '%s * %s' % (-d1[0], d1[2]), d1[2], ')/(%s)' % (-d1[0])
+        if d1[2] == d2[2] and d1[2] in args:
+            a = d2[0] - d1[0]
+            if not a:
+                return repr(b), None, None
+            if b < 0:
+                return '%s * %s - %s' % (a, d1[2], -b), d2[2], '+%s)/(%s)' % (-b, a)
+            elif b:
+                return '%s * %s + %s' % (a, d1[2], b), d2[2], '-%s)/(%s)' % (b, a)
+            else:
+                return '%s * %s' % (a, d1[2]), d2[2], ')/(%s)' % (a)
+        if d1[0] == d2[0] == 1:
+            c = str(d1[2])
+            if c not in args:
+                if _varname_match(c):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c))
+                c = '(%s)' % c
+            if b == 0:
+                d = '%s-%s' % (d2[2], c)
+            elif b < 0:
+                d = '%s-%s-%s' % (d2[2], c, -b)
+            else:
+                d = '%s-%s+%s' % (d2[2], c, b)
+        elif d1[0] == 0:
+            c2 = str(d2[2])
+            if c2 not in args:
+                if _varname_match(c2):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c2))
+                c2 = '(%s)' % c2
+            if d2[0] == 1:
+                pass
+            elif d2[0] == -1:
+                c2 = '-%s' % c2
+            else:
+                c2 = '%s*%s' % (d2[0], c2)
+
+            if b == 0:
+                d = c2
+            elif b < 0:
+                d = '%s-%s' % (c2, -b)
+            else:
+                d = '%s+%s' % (c2, b)
+        elif d2[0] == 0:
+            c1 = str(d1[2])
+            if c1 not in args:
+                if _varname_match(c1):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c1))
+                c1 = '(%s)' % c1
+            if d1[0] == 1:
+                c1 = '-%s' % c1
+            elif d1[0] == -1:
+                c1 = '+%s' % c1
+            elif d1[0] < 0:
+                c1 = '+%s*%s' % (-d1[0], c1)
+            else:
+                c1 = '-%s*%s' % (d1[0], c1)
+
+            if b == 0:
+                d = c1
+            elif b < 0:
+                d = '%s-%s' % (c1, -b)
+            else:
+                d = '%s+%s' % (c1, b)
+        else:
+            c1 = str(d1[2])
+            if c1 not in args:
+                if _varname_match(c1):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c1))
+                c1 = '(%s)' % c1
+            if d1[0] == 1:
+                c1 = '-%s' % c1
+            elif d1[0] == -1:
+                c1 = '+%s' % c1
+            elif d1[0] < 0:
+                c1 = '+%s*%s' % (-d1[0], c1)
+            else:
+                c1 = '-%s*%s' % (d1[0], c1)
+
+            c2 = str(d2[2])
+            if c2 not in args:
+                if _varname_match(c2):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c2))
+                c2 = '(%s)' % c2
+            if d2[0] == 1:
+                pass
+            elif d2[0] == -1:
+                c2 = '-%s' % c2
+            else:
+                c2 = '%s*%s' % (d2[0], c2)
+
+            if b == 0:
+                d = '%s%s' % (c2, c1)
+            elif b < 0:
+                d = '%s%s-%s' % (c2, c1, -b)
+            else:
+                d = '%s%s+%s' % (c2, c1, b)
+    return d, None, None
+
+word_pattern = re.compile(r'\b[a-z][\w$]*\b', re.I)
+
+
+def _get_depend_dict(name, vars, deps):
+    if name in vars:
+        words = vars[name].get('depend', [])
+
+        if '=' in vars[name] and not isstring(vars[name]):
+            for word in word_pattern.findall(vars[name]['=']):
+                if word not in words and word in vars:
+                    words.append(word)
+        for word in words[:]:
+            for w in deps.get(word, []) \
+                    or _get_depend_dict(word, vars, deps):
+                if w not in words:
+                    words.append(w)
+    else:
+        outmess('_get_depend_dict: no dependence info for %s\n' % (repr(name)))
+        words = []
+    deps[name] = words
+    return words
+
+
+def _calc_depend_dict(vars):
+    names = list(vars.keys())
+    depend_dict = {}
+    for n in names:
+        _get_depend_dict(n, vars, depend_dict)
+    return depend_dict
+
+
+def get_sorted_names(vars):
+    """
+    """
+    depend_dict = _calc_depend_dict(vars)
+    names = []
+    for name in list(depend_dict.keys()):
+        if not depend_dict[name]:
+            names.append(name)
+            del depend_dict[name]
+    while depend_dict:
+        for name, lst in list(depend_dict.items()):
+            new_lst = [n for n in lst if n in depend_dict]
+            if not new_lst:
+                names.append(name)
+                del depend_dict[name]
+            else:
+                depend_dict[name] = new_lst
+    return [name for name in names if name in vars]
+
+
+def _kind_func(string):
+    # XXX: return something sensible.
+    if string[0] in "'\"":
+        string = string[1:-1]
+    if real16pattern.match(string):
+        return 8
+    elif real8pattern.match(string):
+        return 4
+    return 'kind(' + string + ')'
+
+
+def _selected_int_kind_func(r):
+    # XXX: This should be processor dependent
+    m = 10 ** r
+    if m <= 2 ** 8:
+        return 1
+    if m <= 2 ** 16:
+        return 2
+    if m <= 2 ** 32:
+        return 4
+    if m <= 2 ** 63:
+        return 8
+    if m <= 2 ** 128:
+        return 16
+    return -1
+
+
+def _selected_real_kind_func(p, r=0, radix=0):
+    # XXX: This should be processor dependent
+    # This is only good for 0 <= p <= 20
+    if p < 7:
+        return 4
+    if p < 16:
+        return 8
+    if platform.machine().lower().startswith('power'):
+        if p <= 20:
+            return 16
+    else:
+        if p < 19:
+            return 10
+        elif p <= 20:
+            return 16
+    return -1
+
+
+def get_parameters(vars, global_params={}):
+    params = copy.copy(global_params)
+    g_params = copy.copy(global_params)
+    for name, func in [('kind', _kind_func),
+                       ('selected_int_kind', _selected_int_kind_func),
+                       ('selected_real_kind', _selected_real_kind_func), ]:
+        if name not in g_params:
+            g_params[name] = func
+    param_names = []
+    for n in get_sorted_names(vars):
+        if 'attrspec' in vars[n] and 'parameter' in vars[n]['attrspec']:
+            param_names.append(n)
+    kind_re = re.compile(r'\bkind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    selected_int_kind_re = re.compile(
+        r'\bselected_int_kind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    selected_kind_re = re.compile(
+        r'\bselected_(int|real)_kind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    for n in param_names:
+        if '=' in vars[n]:
+            v = vars[n]['=']
+            if islogical(vars[n]):
+                v = v.lower()
+                for repl in [
+                    ('.false.', 'False'),
+                    ('.true.', 'True'),
+                    # TODO: test .eq., .neq., etc replacements.
+                ]:
+                    v = v.replace(*repl)
+            v = kind_re.sub(r'kind("\1")', v)
+            v = selected_int_kind_re.sub(r'selected_int_kind(\1)', v)
+            if isinteger(vars[n]) and not selected_kind_re.match(v):
+                v = v.split('_')[0]
+            if isdouble(vars[n]):
+                tt = list(v)
+                for m in real16pattern.finditer(v):
+                    tt[m.start():m.end()] = list(
+                        v[m.start():m.end()].lower().replace('d', 'e'))
+                v = ''.join(tt)
+            if iscomplex(vars[n]):
+                if v[0] == '(' and v[-1] == ')':
+                    # FIXME, unused l looks like potential bug
+                    l = markoutercomma(v[1:-1]).split('@,@')
+            try:
+                params[n] = eval(v, g_params, params)
+            except Exception as msg:
+                params[n] = v
+                outmess('get_parameters: got "%s" on %s\n' % (msg, repr(v)))
+            if isstring(vars[n]) and isinstance(params[n], int):
+                params[n] = chr(params[n])
+            nl = n.lower()
+            if nl != n:
+                params[nl] = params[n]
+        else:
+            print(vars[n])
+            outmess(
+                'get_parameters:parameter %s does not have value?!\n' % (repr(n)))
+    return params
+
+
+def _eval_length(length, params):
+    if length in ['(:)', '(*)', '*']:
+        return '(*)'
+    return _eval_scalar(length, params)
+
+_is_kind_number = re.compile(r'\d+_').match
+
+
+def _eval_scalar(value, params):
+    if _is_kind_number(value):
+        value = value.split('_')[0]
+    try:
+        value = str(eval(value, {}, params))
+    except (NameError, SyntaxError):
+        return value
+    except Exception as msg:
+        errmess('"%s" in evaluating %r '
+                '(available names: %s)\n'
+                % (msg, value, list(params.keys())))
+    return value
+
+
+def analyzevars(block):
+    global f90modulevars
+
+    setmesstext(block)
+    implicitrules, attrrules = buildimplicitrules(block)
+    vars = copy.copy(block['vars'])
+    if block['block'] == 'function' and block['name'] not in vars:
+        vars[block['name']] = {}
+    if '' in block['vars']:
+        del vars['']
+        if 'attrspec' in block['vars']['']:
+            gen = block['vars']['']['attrspec']
+            for n in list(vars.keys()):
+                for k in ['public', 'private']:
+                    if k in gen:
+                        vars[n] = setattrspec(vars[n], k)
+    svars = []
+    args = block['args']
+    for a in args:
+        try:
+            vars[a]
+            svars.append(a)
+        except KeyError:
+            pass
+    for n in list(vars.keys()):
+        if n not in args:
+            svars.append(n)
+
+    params = get_parameters(vars, get_useparameters(block))
+
+    dep_matches = {}
+    name_match = re.compile(r'\w[\w\d_$]*').match
+    for v in list(vars.keys()):
+        m = name_match(v)
+        if m:
+            n = v[m.start():m.end()]
+            try:
+                dep_matches[n]
+            except KeyError:
+                dep_matches[n] = re.compile(r'.*\b%s\b' % (v), re.I).match
+    for n in svars:
+        if n[0] in list(attrrules.keys()):
+            vars[n] = setattrspec(vars[n], attrrules[n[0]])
+        if 'typespec' not in vars[n]:
+            if not('attrspec' in vars[n] and 'external' in vars[n]['attrspec']):
+                if implicitrules:
+                    ln0 = n[0].lower()
+                    for k in list(implicitrules[ln0].keys()):
+                        if k == 'typespec' and implicitrules[ln0][k] == 'undefined':
+                            continue
+                        if k not in vars[n]:
+                            vars[n][k] = implicitrules[ln0][k]
+                        elif k == 'attrspec':
+                            for l in implicitrules[ln0][k]:
+                                vars[n] = setattrspec(vars[n], l)
+                elif n in block['args']:
+                    outmess('analyzevars: typespec of variable %s is not defined in routine %s.\n' % (
+                        repr(n), block['name']))
+
+        if 'charselector' in vars[n]:
+            if 'len' in vars[n]['charselector']:
+                l = vars[n]['charselector']['len']
+                try:
+                    l = str(eval(l, {}, params))
+                except:
+                    pass
+                vars[n]['charselector']['len'] = l
+
+        if 'kindselector' in vars[n]:
+            if 'kind' in vars[n]['kindselector']:
+                l = vars[n]['kindselector']['kind']
+                try:
+                    l = str(eval(l, {}, params))
+                except:
+                    pass
+                vars[n]['kindselector']['kind'] = l
+
+        savelindims = {}
+        if 'attrspec' in vars[n]:
+            attr = vars[n]['attrspec']
+            attr.reverse()
+            vars[n]['attrspec'] = []
+            dim, intent, depend, check, note = None, None, None, None, None
+            for a in attr:
+                if a[:9] == 'dimension':
+                    dim = (a[9:].strip())[1:-1]
+                elif a[:6] == 'intent':
+                    intent = (a[6:].strip())[1:-1]
+                elif a[:6] == 'depend':
+                    depend = (a[6:].strip())[1:-1]
+                elif a[:5] == 'check':
+                    check = (a[5:].strip())[1:-1]
+                elif a[:4] == 'note':
+                    note = (a[4:].strip())[1:-1]
+                else:
+                    vars[n] = setattrspec(vars[n], a)
+                if intent:
+                    if 'intent' not in vars[n]:
+                        vars[n]['intent'] = []
+                    for c in [x.strip() for x in markoutercomma(intent).split('@,@')]:
+                        # Remove spaces so that 'in out' becomes 'inout'
+                        tmp = c.replace(' ', '')
+                        if tmp not in vars[n]['intent']:
+                            vars[n]['intent'].append(tmp)
+                    intent = None
+                if note:
+                    note = note.replace('\\n\\n', '\n\n')
+                    note = note.replace('\\n ', '\n')
+                    if 'note' not in vars[n]:
+                        vars[n]['note'] = [note]
+                    else:
+                        vars[n]['note'].append(note)
+                    note = None
+                if depend is not None:
+                    if 'depend' not in vars[n]:
+                        vars[n]['depend'] = []
+                    for c in rmbadname([x.strip() for x in markoutercomma(depend).split('@,@')]):
+                        if c not in vars[n]['depend']:
+                            vars[n]['depend'].append(c)
+                    depend = None
+                if check is not None:
+                    if 'check' not in vars[n]:
+                        vars[n]['check'] = []
+                    for c in [x.strip() for x in markoutercomma(check).split('@,@')]:
+                        if c not in vars[n]['check']:
+                            vars[n]['check'].append(c)
+                    check = None
+            if dim and 'dimension' not in vars[n]:
+                vars[n]['dimension'] = []
+                for d in rmbadname([x.strip() for x in markoutercomma(dim).split('@,@')]):
+                    star = '*'
+                    if d == ':':
+                        star = ':'
+                    if d in params:
+                        d = str(params[d])
+                    for p in list(params.keys()):
+                        re_1 = re.compile(r'(?P<before>.*?)\b' + p + r'\b(?P<after>.*)', re.I)
+                        m = re_1.match(d)
+                        while m:
+                            d = m.group('before') + \
+                                str(params[p]) + m.group('after')
+                            m = re_1.match(d)
+                    if d == star:
+                        dl = [star]
+                    else:
+                        dl = markoutercomma(d, ':').split('@:@')
+                    if len(dl) == 2 and '*' in dl:  # e.g. dimension(5:*)
+                        dl = ['*']
+                        d = '*'
+                    if len(dl) == 1 and not dl[0] == star:
+                        dl = ['1', dl[0]]
+                    if len(dl) == 2:
+                        d, v, di = getarrlen(dl, list(block['vars'].keys()))
+                        if d[:4] == '1 * ':
+                            d = d[4:]
+                        if di and di[-4:] == '/(1)':
+                            di = di[:-4]
+                        if v:
+                            savelindims[d] = v, di
+                    vars[n]['dimension'].append(d)
+        if 'dimension' in vars[n]:
+            if isintent_c(vars[n]):
+                shape_macro = 'shape'
+            else:
+                shape_macro = 'shape'  # 'fshape'
+            if isstringarray(vars[n]):
+                if 'charselector' in vars[n]:
+                    d = vars[n]['charselector']
+                    if '*' in d:
+                        d = d['*']
+                        errmess('analyzevars: character array "character*%s %s(%s)" is considered as "character %s(%s)"; "intent(c)" is forced.\n'
+                                % (d, n,
+                                   ','.join(vars[n]['dimension']),
+                                   n, ','.join(vars[n]['dimension'] + [d])))
+                        vars[n]['dimension'].append(d)
+                        del vars[n]['charselector']
+                        if 'intent' not in vars[n]:
+                            vars[n]['intent'] = []
+                        if 'c' not in vars[n]['intent']:
+                            vars[n]['intent'].append('c')
+                    else:
+                        errmess(
+                            "analyzevars: charselector=%r unhandled." % (d))
+        if 'check' not in vars[n] and 'args' in block and n in block['args']:
+            flag = 'depend' not in vars[n]
+            if flag:
+                vars[n]['depend'] = []
+            vars[n]['check'] = []
+            if 'dimension' in vars[n]:
+                #/----< no check
+                i = -1
+                ni = len(vars[n]['dimension'])
+                for d in vars[n]['dimension']:
+                    ddeps = []  # dependecies of 'd'
+                    ad = ''
+                    pd = ''
+                    if d not in vars:
+                        if d in savelindims:
+                            pd, ad = '(', savelindims[d][1]
+                            d = savelindims[d][0]
+                        else:
+                            for r in block['args']:
+                                if r not in vars:
+                                    continue
+                                if re.match(r'.*?\b' + r + r'\b', d, re.I):
+                                    ddeps.append(r)
+                    if d in vars:
+                        if 'attrspec' in vars[d]:
+                            for aa in vars[d]['attrspec']:
+                                if aa[:6] == 'depend':
+                                    ddeps += aa[6:].strip()[1:-1].split(',')
+                        if 'depend' in vars[d]:
+                            ddeps = ddeps + vars[d]['depend']
+                    i = i + 1
+                    if d in vars and ('depend' not in vars[d]) \
+                       and ('=' not in vars[d]) and (d not in vars[n]['depend']) \
+                       and l_or(isintent_in, isintent_inout, isintent_inplace)(vars[n]):
+                        vars[d]['depend'] = [n]
+                        if ni > 1:
+                            vars[d]['='] = '%s%s(%s,%s)%s' % (
+                                pd, shape_macro, n, i, ad)
+                        else:
+                            vars[d]['='] = '%slen(%s)%s' % (pd, n, ad)
+                        #  /---< no check
+                        if 1 and 'check' not in vars[d]:
+                            if ni > 1:
+                                vars[d]['check'] = ['%s%s(%s,%i)%s==%s'
+                                                    % (pd, shape_macro, n, i, ad, d)]
+                            else:
+                                vars[d]['check'] = [
+                                    '%slen(%s)%s>=%s' % (pd, n, ad, d)]
+                        if 'attrspec' not in vars[d]:
+                            vars[d]['attrspec'] = ['optional']
+                        if ('optional' not in vars[d]['attrspec']) and\
+                           ('required' not in vars[d]['attrspec']):
+                            vars[d]['attrspec'].append('optional')
+                    elif d not in ['*', ':']:
+                        #/----< no check
+                        if flag:
+                            if d in vars:
+                                if n not in ddeps:
+                                    vars[n]['depend'].append(d)
+                            else:
+                                vars[n]['depend'] = vars[n]['depend'] + ddeps
+            elif isstring(vars[n]):
+                length = '1'
+                if 'charselector' in vars[n]:
+                    if '*' in vars[n]['charselector']:
+                        length = _eval_length(vars[n]['charselector']['*'],
+                                              params)
+                        vars[n]['charselector']['*'] = length
+                    elif 'len' in vars[n]['charselector']:
+                        length = _eval_length(vars[n]['charselector']['len'],
+                                              params)
+                        del vars[n]['charselector']['len']
+                        vars[n]['charselector']['*'] = length
+
+            if not vars[n]['check']:
+                del vars[n]['check']
+            if flag and not vars[n]['depend']:
+                del vars[n]['depend']
+        if '=' in vars[n]:
+            if 'attrspec' not in vars[n]:
+                vars[n]['attrspec'] = []
+            if ('optional' not in vars[n]['attrspec']) and \
+               ('required' not in vars[n]['attrspec']):
+                vars[n]['attrspec'].append('optional')
+            if 'depend' not in vars[n]:
+                vars[n]['depend'] = []
+                for v, m in list(dep_matches.items()):
+                    if m(vars[n]['=']):
+                        vars[n]['depend'].append(v)
+                if not vars[n]['depend']:
+                    del vars[n]['depend']
+            if isscalar(vars[n]):
+                vars[n]['='] = _eval_scalar(vars[n]['='], params)
+
+    for n in list(vars.keys()):
+        if n == block['name']:  # n is block name
+            if 'note' in vars[n]:
+                block['note'] = vars[n]['note']
+            if block['block'] == 'function':
+                if 'result' in block and block['result'] in vars:
+                    vars[n] = appenddecl(vars[n], vars[block['result']])
+                if 'prefix' in block:
+                    pr = block['prefix']
+                    ispure = 0
+                    isrec = 1
+                    pr1 = pr.replace('pure', '')
+                    ispure = (not pr == pr1)
+                    pr = pr1.replace('recursive', '')
+                    isrec = (not pr == pr1)
+                    m = typespattern[0].match(pr)
+                    if m:
+                        typespec, selector, attr, edecl = cracktypespec0(
+                            m.group('this'), m.group('after'))
+                        kindselect, charselect, typename = cracktypespec(
+                            typespec, selector)
+                        vars[n]['typespec'] = typespec
+                        if kindselect:
+                            if 'kind' in kindselect:
+                                try:
+                                    kindselect['kind'] = eval(
+                                        kindselect['kind'], {}, params)
+                                except:
+                                    pass
+                            vars[n]['kindselector'] = kindselect
+                        if charselect:
+                            vars[n]['charselector'] = charselect
+                        if typename:
+                            vars[n]['typename'] = typename
+                        if ispure:
+                            vars[n] = setattrspec(vars[n], 'pure')
+                        if isrec:
+                            vars[n] = setattrspec(vars[n], 'recursive')
+                    else:
+                        outmess(
+                            'analyzevars: prefix (%s) were not used\n' % repr(block['prefix']))
+    if not block['block'] in ['module', 'pythonmodule', 'python module', 'block data']:
+        if 'commonvars' in block:
+            neededvars = copy.copy(block['args'] + block['commonvars'])
+        else:
+            neededvars = copy.copy(block['args'])
+        for n in list(vars.keys()):
+            if l_or(isintent_callback, isintent_aux)(vars[n]):
+                neededvars.append(n)
+        if 'entry' in block:
+            neededvars.extend(list(block['entry'].keys()))
+            for k in list(block['entry'].keys()):
+                for n in block['entry'][k]:
+                    if n not in neededvars:
+                        neededvars.append(n)
+        if block['block'] == 'function':
+            if 'result' in block:
+                neededvars.append(block['result'])
+            else:
+                neededvars.append(block['name'])
+        if block['block'] in ['subroutine', 'function']:
+            name = block['name']
+            if name in vars and 'intent' in vars[name]:
+                block['intent'] = vars[name]['intent']
+        if block['block'] == 'type':
+            neededvars.extend(list(vars.keys()))
+        for n in list(vars.keys()):
+            if n not in neededvars:
+                del vars[n]
+    return vars
+
+analyzeargs_re_1 = re.compile(r'\A[a-z]+[\w$]*\Z', re.I)
+
+
+def expr2name(a, block, args=[]):
+    orig_a = a
+    a_is_expr = not analyzeargs_re_1.match(a)
+    if a_is_expr:  # `a` is an expression
+        implicitrules, attrrules = buildimplicitrules(block)
+        at = determineexprtype(a, block['vars'], implicitrules)
+        na = 'e_'
+        for c in a:
+            c = c.lower()
+            if c not in string.ascii_lowercase + string.digits:
+                c = '_'
+            na = na + c
+        if na[-1] == '_':
+            na = na + 'e'
+        else:
+            na = na + '_e'
+        a = na
+        while a in block['vars'] or a in block['args']:
+            a = a + 'r'
+    if a in args:
+        k = 1
+        while a + str(k) in args:
+            k = k + 1
+        a = a + str(k)
+    if a_is_expr:
+        block['vars'][a] = at
+    else:
+        if a not in block['vars']:
+            if orig_a in block['vars']:
+                block['vars'][a] = block['vars'][orig_a]
+            else:
+                block['vars'][a] = {}
+        if 'externals' in block and orig_a in block['externals'] + block['interfaced']:
+            block['vars'][a] = setattrspec(block['vars'][a], 'external')
+    return a
+
+
+def analyzeargs(block):
+    setmesstext(block)
+    implicitrules, attrrules = buildimplicitrules(block)
+    if 'args' not in block:
+        block['args'] = []
+    args = []
+    for a in block['args']:
+        a = expr2name(a, block, args)
+        args.append(a)
+    block['args'] = args
+    if 'entry' in block:
+        for k, args1 in list(block['entry'].items()):
+            for a in args1:
+                if a not in block['vars']:
+                    block['vars'][a] = {}
+
+    for b in block['body']:
+        if b['name'] in args:
+            if 'externals' not in block:
+                block['externals'] = []
+            if b['name'] not in block['externals']:
+                block['externals'].append(b['name'])
+    if 'result' in block and block['result'] not in block['vars']:
+        block['vars'][block['result']] = {}
+    return block
+
+determineexprtype_re_1 = re.compile(r'\A\(.+?[,].+?\)\Z', re.I)
+determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(P<name>[\w]+)|)\Z', re.I)
+determineexprtype_re_3 = re.compile(
+    r'\A[+-]?[\d.]+[\d+-de.]*(_(P<name>[\w]+)|)\Z', re.I)
+determineexprtype_re_4 = re.compile(r'\A\(.*\)\Z', re.I)
+determineexprtype_re_5 = re.compile(r'\A(?P<name>\w+)\s*\(.*?\)\s*\Z', re.I)
+
+
+def _ensure_exprdict(r):
+    if isinstance(r, int):
+        return {'typespec': 'integer'}
+    if isinstance(r, float):
+        return {'typespec': 'real'}
+    if isinstance(r, complex):
+        return {'typespec': 'complex'}
+    if isinstance(r, dict):
+        return r
+    raise AssertionError(repr(r))
+
+
+def determineexprtype(expr, vars, rules={}):
+    if expr in vars:
+        return _ensure_exprdict(vars[expr])
+    expr = expr.strip()
+    if determineexprtype_re_1.match(expr):
+        return {'typespec': 'complex'}
+    m = determineexprtype_re_2.match(expr)
+    if m:
+        if 'name' in m.groupdict() and m.group('name'):
+            outmess(
+                'determineexprtype: selected kind types not supported (%s)\n' % repr(expr))
+        return {'typespec': 'integer'}
+    m = determineexprtype_re_3.match(expr)
+    if m:
+        if 'name' in m.groupdict() and m.group('name'):
+            outmess(
+                'determineexprtype: selected kind types not supported (%s)\n' % repr(expr))
+        return {'typespec': 'real'}
+    for op in ['+', '-', '*', '/']:
+        for e in [x.strip() for x in markoutercomma(expr, comma=op).split('@' + op + '@')]:
+            if e in vars:
+                return _ensure_exprdict(vars[e])
+    t = {}
+    if determineexprtype_re_4.match(expr):  # in parenthesis
+        t = determineexprtype(expr[1:-1], vars, rules)
+    else:
+        m = determineexprtype_re_5.match(expr)
+        if m:
+            rn = m.group('name')
+            t = determineexprtype(m.group('name'), vars, rules)
+            if t and 'attrspec' in t:
+                del t['attrspec']
+            if not t:
+                if rn[0] in rules:
+                    return _ensure_exprdict(rules[rn[0]])
+    if expr[0] in '\'"':
+        return {'typespec': 'character', 'charselector': {'*': '*'}}
+    if not t:
+        outmess(
+            'determineexprtype: could not determine expressions (%s) type.\n' % (repr(expr)))
+    return t
+
+######
+
+
+def crack2fortrangen(block, tab='\n', as_interface=False):
+    global skipfuncs, onlyfuncs
+
+    setmesstext(block)
+    ret = ''
+    if isinstance(block, list):
+        for g in block:
+            if g and g['block'] in ['function', 'subroutine']:
+                if g['name'] in skipfuncs:
+                    continue
+                if onlyfuncs and g['name'] not in onlyfuncs:
+                    continue
+            ret = ret + crack2fortrangen(g, tab, as_interface=as_interface)
+        return ret
+    prefix = ''
+    name = ''
+    args = ''
+    blocktype = block['block']
+    if blocktype == 'program':
+        return ''
+    argsl = []
+    if 'name' in block:
+        name = block['name']
+    if 'args' in block:
+        vars = block['vars']
+        for a in block['args']:
+            a = expr2name(a, block, argsl)
+            if not isintent_callback(vars[a]):
+                argsl.append(a)
+        if block['block'] == 'function' or argsl:
+            args = '(%s)' % ','.join(argsl)
+    f2pyenhancements = ''
+    if 'f2pyenhancements' in block:
+        for k in list(block['f2pyenhancements'].keys()):
+            f2pyenhancements = '%s%s%s %s' % (
+                f2pyenhancements, tab + tabchar, k, block['f2pyenhancements'][k])
+    intent_lst = block.get('intent', [])[:]
+    if blocktype == 'function' and 'callback' in intent_lst:
+        intent_lst.remove('callback')
+    if intent_lst:
+        f2pyenhancements = '%s%sintent(%s) %s' %\
+                           (f2pyenhancements, tab + tabchar,
+                            ','.join(intent_lst), name)
+    use = ''
+    if 'use' in block:
+        use = use2fortran(block['use'], tab + tabchar)
+    common = ''
+    if 'common' in block:
+        common = common2fortran(block['common'], tab + tabchar)
+    if name == 'unknown_interface':
+        name = ''
+    result = ''
+    if 'result' in block:
+        result = ' result (%s)' % block['result']
+        if block['result'] not in argsl:
+            argsl.append(block['result'])
+    body = crack2fortrangen(block['body'], tab + tabchar)
+    vars = vars2fortran(
+        block, block['vars'], argsl, tab + tabchar, as_interface=as_interface)
+    mess = ''
+    if 'from' in block and not as_interface:
+        mess = '! in %s' % block['from']
+    if 'entry' in block:
+        entry_stmts = ''
+        for k, i in list(block['entry'].items()):
+            entry_stmts = '%s%sentry %s(%s)' \
+                          % (entry_stmts, tab + tabchar, k, ','.join(i))
+        body = body + entry_stmts
+    if blocktype == 'block data' and name == '_BLOCK_DATA_':
+        name = ''
+    ret = '%s%s%s %s%s%s %s%s%s%s%s%s%send %s %s' % (
+        tab, prefix, blocktype, name, args, result, mess, f2pyenhancements, use, vars, common, body, tab, blocktype, name)
+    return ret
+
+
+def common2fortran(common, tab=''):
+    ret = ''
+    for k in list(common.keys()):
+        if k == '_BLNK_':
+            ret = '%s%scommon %s' % (ret, tab, ','.join(common[k]))
+        else:
+            ret = '%s%scommon /%s/ %s' % (ret, tab, k, ','.join(common[k]))
+    return ret
+
+
+def use2fortran(use, tab=''):
+    ret = ''
+    for m in list(use.keys()):
+        ret = '%s%suse %s,' % (ret, tab, m)
+        if use[m] == {}:
+            if ret and ret[-1] == ',':
+                ret = ret[:-1]
+            continue
+        if 'only' in use[m] and use[m]['only']:
+            ret = '%s only:' % (ret)
+        if 'map' in use[m] and use[m]['map']:
+            c = ' '
+            for k in list(use[m]['map'].keys()):
+                if k == use[m]['map'][k]:
+                    ret = '%s%s%s' % (ret, c, k)
+                    c = ','
+                else:
+                    ret = '%s%s%s=>%s' % (ret, c, k, use[m]['map'][k])
+                    c = ','
+        if ret and ret[-1] == ',':
+            ret = ret[:-1]
+    return ret
+
+
+def true_intent_list(var):
+    lst = var['intent']
+    ret = []
+    for intent in lst:
+        try:
+            c = eval('isintent_%s(var)' % intent)
+        except NameError:
+            c = 0
+        if c:
+            ret.append(intent)
+    return ret
+
+
+def vars2fortran(block, vars, args, tab='', as_interface=False):
+    """
+    TODO:
+    public sub
+    ...
+    """
+    setmesstext(block)
+    ret = ''
+    nout = []
+    for a in args:
+        if a in block['vars']:
+            nout.append(a)
+    if 'commonvars' in block:
+        for a in block['commonvars']:
+            if a in vars:
+                if a not in nout:
+                    nout.append(a)
+            else:
+                errmess(
+                    'vars2fortran: Confused?!: "%s" is not defined in vars.\n' % a)
+    if 'varnames' in block:
+        nout.extend(block['varnames'])
+    if not as_interface:
+        for a in list(vars.keys()):
+            if a not in nout:
+                nout.append(a)
+    for a in nout:
+        if 'depend' in vars[a]:
+            for d in vars[a]['depend']:
+                if d in vars and 'depend' in vars[d] and a in vars[d]['depend']:
+                    errmess(
+                        'vars2fortran: Warning: cross-dependence between variables "%s" and "%s"\n' % (a, d))
+        if 'externals' in block and a in block['externals']:
+            if isintent_callback(vars[a]):
+                ret = '%s%sintent(callback) %s' % (ret, tab, a)
+            ret = '%s%sexternal %s' % (ret, tab, a)
+            if isoptional(vars[a]):
+                ret = '%s%soptional %s' % (ret, tab, a)
+            if a in vars and 'typespec' not in vars[a]:
+                continue
+            cont = 1
+            for b in block['body']:
+                if a == b['name'] and b['block'] == 'function':
+                    cont = 0
+                    break
+            if cont:
+                continue
+        if a not in vars:
+            show(vars)
+            outmess('vars2fortran: No definition for argument "%s".\n' % a)
+            continue
+        if a == block['name'] and not block['block'] == 'function':
+            continue
+        if 'typespec' not in vars[a]:
+            if 'attrspec' in vars[a] and 'external' in vars[a]['attrspec']:
+                if a in args:
+                    ret = '%s%sexternal %s' % (ret, tab, a)
+                continue
+            show(vars[a])
+            outmess('vars2fortran: No typespec for argument "%s".\n' % a)
+            continue
+        vardef = vars[a]['typespec']
+        if vardef == 'type' and 'typename' in vars[a]:
+            vardef = '%s(%s)' % (vardef, vars[a]['typename'])
+        selector = {}
+        if 'kindselector' in vars[a]:
+            selector = vars[a]['kindselector']
+        elif 'charselector' in vars[a]:
+            selector = vars[a]['charselector']
+        if '*' in selector:
+            if selector['*'] in ['*', ':']:
+                vardef = '%s*(%s)' % (vardef, selector['*'])
+            else:
+                vardef = '%s*%s' % (vardef, selector['*'])
+        else:
+            if 'len' in selector:
+                vardef = '%s(len=%s' % (vardef, selector['len'])
+                if 'kind' in selector:
+                    vardef = '%s,kind=%s)' % (vardef, selector['kind'])
+                else:
+                    vardef = '%s)' % (vardef)
+            elif 'kind' in selector:
+                vardef = '%s(kind=%s)' % (vardef, selector['kind'])
+        c = ' '
+        if 'attrspec' in vars[a]:
+            attr = []
+            for l in vars[a]['attrspec']:
+                if l not in ['external']:
+                    attr.append(l)
+            if attr:
+                vardef = '%s, %s' % (vardef, ','.join(attr))
+                c = ','
+        if 'dimension' in vars[a]:
+            vardef = '%s%sdimension(%s)' % (
+                vardef, c, ','.join(vars[a]['dimension']))
+            c = ','
+        if 'intent' in vars[a]:
+            lst = true_intent_list(vars[a])
+            if lst:
+                vardef = '%s%sintent(%s)' % (vardef, c, ','.join(lst))
+            c = ','
+        if 'check' in vars[a]:
+            vardef = '%s%scheck(%s)' % (vardef, c, ','.join(vars[a]['check']))
+            c = ','
+        if 'depend' in vars[a]:
+            vardef = '%s%sdepend(%s)' % (
+                vardef, c, ','.join(vars[a]['depend']))
+            c = ','
+        if '=' in vars[a]:
+            v = vars[a]['=']
+            if vars[a]['typespec'] in ['complex', 'double complex']:
+                try:
+                    v = eval(v)
+                    v = '(%s,%s)' % (v.real, v.imag)
+                except:
+                    pass
+            vardef = '%s :: %s=%s' % (vardef, a, v)
+        else:
+            vardef = '%s :: %s' % (vardef, a)
+        ret = '%s%s%s' % (ret, tab, vardef)
+    return ret
+######
+
+
+def crackfortran(files):
+    global usermodules
+
+    outmess('Reading fortran codes...\n', 0)
+    readfortrancode(files, crackline)
+    outmess('Post-processing...\n', 0)
+    usermodules = []
+    postlist = postcrack(grouplist[0])
+    outmess('Post-processing (stage 2)...\n', 0)
+    postlist = postcrack2(postlist)
+    return usermodules + postlist
+
+
+def crack2fortran(block):
+    global f2py_version
+
+    pyf = crack2fortrangen(block) + '\n'
+    header = """!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+"""
+    footer = """
+! This file was auto-generated with f2py (version:%s).
+! See http://cens.ioc.ee/projects/f2py2e/
+""" % (f2py_version)
+    return header + pyf + footer
+
+if __name__ == "__main__":
+    files = []
+    funcs = []
+    f = 1
+    f2 = 0
+    f3 = 0
+    showblocklist = 0
+    for l in sys.argv[1:]:
+        if l == '':
+            pass
+        elif l[0] == ':':
+            f = 0
+        elif l == '-quiet':
+            quiet = 1
+            verbose = 0
+        elif l == '-verbose':
+            verbose = 2
+            quiet = 0
+        elif l == '-fix':
+            if strictf77:
+                outmess(
+                    'Use option -f90 before -fix if Fortran 90 code is in fix form.\n', 0)
+            skipemptyends = 1
+            sourcecodeform = 'fix'
+        elif l == '-skipemptyends':
+            skipemptyends = 1
+        elif l == '--ignore-contains':
+            ignorecontains = 1
+        elif l == '-f77':
+            strictf77 = 1
+            sourcecodeform = 'fix'
+        elif l == '-f90':
+            strictf77 = 0
+            sourcecodeform = 'free'
+            skipemptyends = 1
+        elif l == '-h':
+            f2 = 1
+        elif l == '-show':
+            showblocklist = 1
+        elif l == '-m':
+            f3 = 1
+        elif l[0] == '-':
+            errmess('Unknown option %s\n' % repr(l))
+        elif f2:
+            f2 = 0
+            pyffilename = l
+        elif f3:
+            f3 = 0
+            f77modulename = l
+        elif f:
+            try:
+                open(l).close()
+                files.append(l)
+            except IOError as detail:
+                errmess('IOError: %s\n' % str(detail))
+        else:
+            funcs.append(l)
+    if not strictf77 and f77modulename and not skipemptyends:
+        outmess("""\
+  Warning: You have specifyied module name for non Fortran 77 code
+  that should not need one (expect if you are scanning F90 code
+  for non module blocks but then you should use flag -skipemptyends
+  and also be sure that the files do not contain programs without program statement).
+""", 0)
+
+    postlist = crackfortran(files, funcs)
+    if pyffilename:
+        outmess('Writing fortran code to file %s\n' % repr(pyffilename), 0)
+        pyf = crack2fortran(postlist)
+        f = open(pyffilename, 'w')
+        f.write(pyf)
+        f.close()
+    if showblocklist:
+        show(postlist)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.py
new file mode 100644
index 0000000000..e25573056b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python2
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import tempfile
+
+
+def run_command(cmd):
+    print('Running %r:' % (cmd))
+    os.system(cmd)
+    print('------')
+
+
+def run():
+    _path = os.getcwd()
+    os.chdir(tempfile.gettempdir())
+    print('------')
+    print('os.name=%r' % (os.name))
+    print('------')
+    print('sys.platform=%r' % (sys.platform))
+    print('------')
+    print('sys.version:')
+    print(sys.version)
+    print('------')
+    print('sys.prefix:')
+    print(sys.prefix)
+    print('------')
+    print('sys.path=%r' % (':'.join(sys.path)))
+    print('------')
+
+    try:
+        import numpy
+        has_newnumpy = 1
+    except ImportError:
+        print('Failed to import new numpy:', sys.exc_info()[1])
+        has_newnumpy = 0
+
+    try:
+        from numpy.f2py import f2py2e
+        has_f2py2e = 1
+    except ImportError:
+        print('Failed to import f2py2e:', sys.exc_info()[1])
+        has_f2py2e = 0
+
+    try:
+        import numpy.distutils
+        has_numpy_distutils = 2
+    except ImportError:
+        try:
+            import numpy_distutils
+            has_numpy_distutils = 1
+        except ImportError:
+            print('Failed to import numpy_distutils:', sys.exc_info()[1])
+            has_numpy_distutils = 0
+
+    if has_newnumpy:
+        try:
+            print('Found new numpy version %r in %s' %
+                  (numpy.__version__, numpy.__file__))
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+
+    if has_f2py2e:
+        try:
+            print('Found f2py2e version %r in %s' %
+                  (f2py2e.__version__.version, f2py2e.__file__))
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+
+    if has_numpy_distutils:
+        try:
+            if has_numpy_distutils == 2:
+                print('Found numpy.distutils version %r in %r' % (
+                    numpy.distutils.__version__,
+                    numpy.distutils.__file__))
+            else:
+                print('Found numpy_distutils version %r in %r' % (
+                    numpy_distutils.numpy_distutils_version.numpy_distutils_version,
+                    numpy_distutils.__file__))
+            print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+        try:
+            if has_numpy_distutils == 1:
+                print(
+                    'Importing numpy_distutils.command.build_flib ...', end=' ')
+                import numpy_distutils.command.build_flib as build_flib
+                print('ok')
+                print('------')
+                try:
+                    print(
+                        'Checking availability of supported Fortran compilers:')
+                    for compiler_class in build_flib.all_compilers:
+                        compiler_class(verbose=1).is_available()
+                        print('------')
+                except Exception as msg:
+                    print('error:', msg)
+                    print('------')
+        except Exception as msg:
+            print(
+                'error:', msg, '(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)')
+            print('------')
+        try:
+            if has_numpy_distutils == 2:
+                print('Importing numpy.distutils.fcompiler ...', end=' ')
+                import numpy.distutils.fcompiler as fcompiler
+            else:
+                print('Importing numpy_distutils.fcompiler ...', end=' ')
+                import numpy_distutils.fcompiler as fcompiler
+            print('ok')
+            print('------')
+            try:
+                print('Checking availability of supported Fortran compilers:')
+                fcompiler.show_fcompilers()
+                print('------')
+            except Exception as msg:
+                print('error:', msg)
+                print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+        try:
+            if has_numpy_distutils == 2:
+                print('Importing numpy.distutils.cpuinfo ...', end=' ')
+                from numpy.distutils.cpuinfo import cpuinfo
+                print('ok')
+                print('------')
+            else:
+                try:
+                    print(
+                        'Importing numpy_distutils.command.cpuinfo ...', end=' ')
+                    from numpy_distutils.command.cpuinfo import cpuinfo
+                    print('ok')
+                    print('------')
+                except Exception as msg:
+                    print('error:', msg, '(ignore it)')
+                    print('Importing numpy_distutils.cpuinfo ...', end=' ')
+                    from numpy_distutils.cpuinfo import cpuinfo
+                    print('ok')
+                    print('------')
+            cpu = cpuinfo()
+            print('CPU information:', end=' ')
+            for name in dir(cpuinfo):
+                if name[0] == '_' and name[1] != '_' and getattr(cpu, name[1:])():
+                    print(name[1:], end=' ')
+            print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+    os.chdir(_path)
+if __name__ == "__main__":
+    run()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
new file mode 100644
index 0000000000..8008e6bdb7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
@@ -0,0 +1,656 @@
+#!/usr/bin/env python2
+"""
+
+f2py2e - Fortran to Python C/API generator. 2nd Edition.
+         See __usage__ below.
+
+Copyright 1999--2011 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 08:31:19 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import pprint
+import re
+
+from . import crackfortran
+from . import rules
+from . import cb_rules
+from . import auxfuncs
+from . import cfuncs
+from . import f90mod_rules
+from . import __version__
+
+f2py_version = __version__.version
+errmess = sys.stderr.write
+# outmess=sys.stdout.write
+show = pprint.pprint
+outmess = auxfuncs.outmess
+
+try:
+    from numpy import __version__ as numpy_version
+except ImportError:
+    numpy_version = 'N/A'
+
+__usage__ = """\
+Usage:
+
+1) To construct extension module sources:
+
+      f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
+                                        <fortran functions> ] \\
+                                       [: <fortran files> ...]
+
+2) To compile fortran files and build extension modules:
+
+      f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
+
+3) To generate signature files:
+
+      f2py -h <filename.pyf> ...< same options as in (1) >
+
+Description: This program generates a Python C/API file (<modulename>module.c)
+             that contains wrappers for given fortran functions so that they
+             can be called from Python. With the -c option the corresponding
+             extension modules are built.
+
+Options:
+
+  --2d-numpy       Use numpy.f2py tool with NumPy support. [DEFAULT]
+  --2d-numeric     Use f2py2e tool with Numeric support.
+  --2d-numarray    Use f2py2e tool with Numarray support.
+  --g3-numpy       Use 3rd generation f2py from the separate f2py package.
+                   [NOT AVAILABLE YET]
+
+  -h <filename>    Write signatures of the fortran routines to file <filename>
+                   and exit. You can then edit <filename> and use it instead
+                   of <fortran files>. If <filename>==stdout then the
+                   signatures are printed to stdout.
+  <fortran functions>  Names of fortran routines for which Python C/API
+                   functions will be generated. Default is all that are found
+                   in <fortran files>.
+  <fortran files>  Paths to fortran/signature files that will be scanned for
+                   <fortran functions> in order to determine their signatures.
+  skip:            Ignore fortran functions that follow until `:'.
+  only:            Use only fortran functions that follow until `:'.
+  :                Get back to <fortran files> mode.
+
+  -m <modulename>  Name of the module; f2py generates a Python/C API
+                   file <modulename>module.c or extension module <modulename>.
+                   Default is 'untitled'.
+
+  --[no-]lower     Do [not] lower the cases in <fortran files>. By default,
+                   --lower is assumed with -h key, and --no-lower without -h key.
+
+  --build-dir <dirname>  All f2py generated files are created in <dirname>.
+                   Default is tempfile.mkdtemp().
+
+  --overwrite-signature  Overwrite existing signature file.
+
+  --[no-]latex-doc Create (or not) <modulename>module.tex.
+                   Default is --no-latex-doc.
+  --short-latex    Create 'incomplete' LaTeX document (without commands
+                   \\documentclass, \\tableofcontents, and \\begin{document},
+                   \\end{document}).
+
+  --[no-]rest-doc Create (or not) <modulename>module.rst.
+                   Default is --no-rest-doc.
+
+  --debug-capi     Create C/API code that reports the state of the wrappers
+                   during runtime. Useful for debugging.
+
+  --[no-]wrap-functions    Create Fortran subroutine wrappers to Fortran 77
+                   functions. --wrap-functions is default because it ensures
+                   maximum portability/compiler independence.
+
+  --include-paths <path1>:<path2>:...   Search include files from the given
+                   directories.
+
+  --help-link [..] List system resources found by system_info.py. See also
+                   --link-<resource> switch below. [..] is optional list
+                   of resources names. E.g. try 'f2py --help-link lapack_opt'.
+
+  --quiet          Run quietly.
+  --verbose        Run with extra verbosity.
+  -v               Print f2py version ID and exit.
+
+
+numpy.distutils options (only effective with -c):
+
+  --fcompiler=         Specify Fortran compiler type by vendor
+  --compiler=          Specify C compiler type (as defined by distutils)
+
+  --help-fcompiler     List available Fortran compilers and exit
+  --f77exec=           Specify the path to F77 compiler
+  --f90exec=           Specify the path to F90 compiler
+  --f77flags=          Specify F77 compiler flags
+  --f90flags=          Specify F90 compiler flags
+  --opt=               Specify optimization flags
+  --arch=              Specify architecture specific optimization flags
+  --noopt              Compile without optimization
+  --noarch             Compile without arch-dependent optimization
+  --debug              Compile with debugging information
+
+Extra options (only effective with -c):
+
+  --link-<resource>    Link extension module with <resource> as defined
+                       by numpy.distutils/system_info.py. E.g. to link
+                       with optimized LAPACK libraries (vecLib on MacOSX,
+                       ATLAS elsewhere), use --link-lapack_opt.
+                       See also --help-link switch.
+
+  -L/path/to/lib/ -l<libname>
+  -D<define> -U<name>
+  -I/path/to/include/
+  <filename>.o <filename>.so <filename>.a
+
+  Using the following macros may be required with non-gcc Fortran
+  compilers:
+    -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
+    -DUNDERSCORE_G77
+
+  When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
+  interface is printed out at exit (platforms: Linux).
+
+  When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
+  sent to stderr whenever F2PY interface makes a copy of an
+  array. Integer <int> sets the threshold for array sizes when
+  a message should be shown.
+
+Version:     %s
+numpy Version: %s
+Requires:    Python 2.3 or higher.
+License:     NumPy license (see LICENSE.txt in the NumPy source code)
+Copyright 1999 - 2011 Pearu Peterson all rights reserved.
+http://cens.ioc.ee/projects/f2py2e/""" % (f2py_version, numpy_version)
+
+
+def scaninputline(inputline):
+    files, skipfuncs, onlyfuncs, debug = [], [], [], []
+    f, f2, f3, f5, f6, f7, f8, f9 = 1, 0, 0, 0, 0, 0, 0, 0
+    verbose = 1
+    dolc = -1
+    dolatexdoc = 0
+    dorestdoc = 0
+    wrapfuncs = 1
+    buildpath = '.'
+    include_paths = []
+    signsfile, modulename = None, None
+    options = {'buildpath': buildpath,
+               'coutput': None,
+               'f2py_wrapper_output': None}
+    for l in inputline:
+        if l == '':
+            pass
+        elif l == 'only:':
+            f = 0
+        elif l == 'skip:':
+            f = -1
+        elif l == ':':
+            f = 1
+        elif l[:8] == '--debug-':
+            debug.append(l[8:])
+        elif l == '--lower':
+            dolc = 1
+        elif l == '--build-dir':
+            f6 = 1
+        elif l == '--no-lower':
+            dolc = 0
+        elif l == '--quiet':
+            verbose = 0
+        elif l == '--verbose':
+            verbose += 1
+        elif l == '--latex-doc':
+            dolatexdoc = 1
+        elif l == '--no-latex-doc':
+            dolatexdoc = 0
+        elif l == '--rest-doc':
+            dorestdoc = 1
+        elif l == '--no-rest-doc':
+            dorestdoc = 0
+        elif l == '--wrap-functions':
+            wrapfuncs = 1
+        elif l == '--no-wrap-functions':
+            wrapfuncs = 0
+        elif l == '--short-latex':
+            options['shortlatex'] = 1
+        elif l == '--coutput':
+            f8 = 1
+        elif l == '--f2py-wrapper-output':
+            f9 = 1
+        elif l == '--overwrite-signature':
+            options['h-overwrite'] = 1
+        elif l == '-h':
+            f2 = 1
+        elif l == '-m':
+            f3 = 1
+        elif l[:2] == '-v':
+            print(f2py_version)
+            sys.exit()
+        elif l == '--show-compilers':
+            f5 = 1
+        elif l[:8] == '-include':
+            cfuncs.outneeds['userincludes'].append(l[9:-1])
+            cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:]
+        elif l[:15] in '--include_paths':
+            outmess(
+                'f2py option --include_paths is deprecated, use --include-paths instead.\n')
+            f7 = 1
+        elif l[:15] in '--include-paths':
+            f7 = 1
+        elif l[0] == '-':
+            errmess('Unknown option %s\n' % repr(l))
+            sys.exit()
+        elif f2:
+            f2 = 0
+            signsfile = l
+        elif f3:
+            f3 = 0
+            modulename = l
+        elif f6:
+            f6 = 0
+            buildpath = l
+        elif f7:
+            f7 = 0
+            include_paths.extend(l.split(os.pathsep))
+        elif f8:
+            f8 = 0
+            options["coutput"] = l
+        elif f9:
+            f9 = 0
+            options["f2py_wrapper_output"] = l
+        elif f == 1:
+            try:
+                open(l).close()
+                files.append(l)
+            except IOError as detail:
+                errmess('IOError: %s. Skipping file "%s".\n' %
+                        (str(detail), l))
+        elif f == -1:
+            skipfuncs.append(l)
+        elif f == 0:
+            onlyfuncs.append(l)
+    if not f5 and not files and not modulename:
+        print(__usage__)
+        sys.exit()
+    if not os.path.isdir(buildpath):
+        if not verbose:
+            outmess('Creating build directory %s' % (buildpath))
+        os.mkdir(buildpath)
+    if signsfile:
+        signsfile = os.path.join(buildpath, signsfile)
+    if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options:
+        errmess(
+            'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
+        sys.exit()
+
+    options['debug'] = debug
+    options['verbose'] = verbose
+    if dolc == -1 and not signsfile:
+        options['do-lower'] = 0
+    else:
+        options['do-lower'] = dolc
+    if modulename:
+        options['module'] = modulename
+    if signsfile:
+        options['signsfile'] = signsfile
+    if onlyfuncs:
+        options['onlyfuncs'] = onlyfuncs
+    if skipfuncs:
+        options['skipfuncs'] = skipfuncs
+    options['dolatexdoc'] = dolatexdoc
+    options['dorestdoc'] = dorestdoc
+    options['wrapfuncs'] = wrapfuncs
+    options['buildpath'] = buildpath
+    options['include_paths'] = include_paths
+    return files, options
+
+
+def callcrackfortran(files, options):
+    rules.options = options
+    crackfortran.debug = options['debug']
+    crackfortran.verbose = options['verbose']
+    if 'module' in options:
+        crackfortran.f77modulename = options['module']
+    if 'skipfuncs' in options:
+        crackfortran.skipfuncs = options['skipfuncs']
+    if 'onlyfuncs' in options:
+        crackfortran.onlyfuncs = options['onlyfuncs']
+    crackfortran.include_paths[:] = options['include_paths']
+    crackfortran.dolowercase = options['do-lower']
+    postlist = crackfortran.crackfortran(files)
+    if 'signsfile' in options:
+        outmess('Saving signatures to file "%s"\n' % (options['signsfile']))
+        pyf = crackfortran.crack2fortran(postlist)
+        if options['signsfile'][-6:] == 'stdout':
+            sys.stdout.write(pyf)
+        else:
+            f = open(options['signsfile'], 'w')
+            f.write(pyf)
+            f.close()
+    if options["coutput"] is None:
+        for mod in postlist:
+            mod["coutput"] = "%smodule.c" % mod["name"]
+    else:
+        for mod in postlist:
+            mod["coutput"] = options["coutput"]
+    if options["f2py_wrapper_output"] is None:
+        for mod in postlist:
+            mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"]
+    else:
+        for mod in postlist:
+            mod["f2py_wrapper_output"] = options["f2py_wrapper_output"]
+    return postlist
+
+
+def buildmodules(lst):
+    cfuncs.buildcfuncs()
+    outmess('Building modules...\n')
+    modules, mnames, isusedby = [], [], {}
+    for i in range(len(lst)):
+        if '__user__' in lst[i]['name']:
+            cb_rules.buildcallbacks(lst[i])
+        else:
+            if 'use' in lst[i]:
+                for u in lst[i]['use'].keys():
+                    if u not in isusedby:
+                        isusedby[u] = []
+                    isusedby[u].append(lst[i]['name'])
+            modules.append(lst[i])
+            mnames.append(lst[i]['name'])
+    ret = {}
+    for i in range(len(mnames)):
+        if mnames[i] in isusedby:
+            outmess('\tSkipping module "%s" which is used by %s.\n' % (
+                mnames[i], ','.join(['"%s"' % s for s in isusedby[mnames[i]]])))
+        else:
+            um = []
+            if 'use' in modules[i]:
+                for u in modules[i]['use'].keys():
+                    if u in isusedby and u in mnames:
+                        um.append(modules[mnames.index(u)])
+                    else:
+                        outmess(
+                            '\tModule "%s" uses nonexisting "%s" which will be ignored.\n' % (mnames[i], u))
+            ret[mnames[i]] = {}
+            dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um))
+    return ret
+
+
+def dict_append(d_out, d_in):
+    for (k, v) in d_in.items():
+        if k not in d_out:
+            d_out[k] = []
+        if isinstance(v, list):
+            d_out[k] = d_out[k] + v
+        else:
+            d_out[k].append(v)
+
+
+def run_main(comline_list):
+    """Run f2py as if string.join(comline_list,' ') is used as a command line.
+    In case of using -h flag, return None.
+    """
+    crackfortran.reset_global_f2py_vars()
+    f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__))
+    fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h')
+    fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
+    files, options = scaninputline(comline_list)
+    auxfuncs.options = options
+    postlist = callcrackfortran(files, options)
+    isusedby = {}
+    for i in range(len(postlist)):
+        if 'use' in postlist[i]:
+            for u in postlist[i]['use'].keys():
+                if u not in isusedby:
+                    isusedby[u] = []
+                isusedby[u].append(postlist[i]['name'])
+    for i in range(len(postlist)):
+        if postlist[i]['block'] == 'python module' and '__user__' in postlist[i]['name']:
+            if postlist[i]['name'] in isusedby:
+                # if not quiet:
+                outmess('Skipping Makefile build for module "%s" which is used by %s\n' % (
+                    postlist[i]['name'], ','.join(['"%s"' % s for s in isusedby[postlist[i]['name']]])))
+    if 'signsfile' in options:
+        if options['verbose'] > 1:
+            outmess(
+                'Stopping. Edit the signature file and then run f2py on the signature file: ')
+            outmess('%s %s\n' %
+                    (os.path.basename(sys.argv[0]), options['signsfile']))
+        return
+    for i in range(len(postlist)):
+        if postlist[i]['block'] != 'python module':
+            if 'python module' not in options:
+                errmess(
+                    'Tip: If your original code is Fortran source then you must use -m option.\n')
+            raise TypeError('All blocks must be python module blocks but got %s' % (
+                repr(postlist[i]['block'])))
+    auxfuncs.debugoptions = options['debug']
+    f90mod_rules.options = options
+    auxfuncs.wrapfuncs = options['wrapfuncs']
+
+    ret = buildmodules(postlist)
+
+    for mn in ret.keys():
+        dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc})
+    return ret
+
+
+def filter_files(prefix, suffix, files, remove_prefix=None):
+    """
+    Filter files by prefix and suffix.
+    """
+    filtered, rest = [], []
+    match = re.compile(prefix + r'.*' + suffix + r'\Z').match
+    if remove_prefix:
+        ind = len(prefix)
+    else:
+        ind = 0
+    for file in [x.strip() for x in files]:
+        if match(file):
+            filtered.append(file[ind:])
+        else:
+            rest.append(file)
+    return filtered, rest
+
+
+def get_prefix(module):
+    p = os.path.dirname(os.path.dirname(module.__file__))
+    return p
+
+
+def run_compile():
+    """
+    Do it all in one call!
+    """
+    import tempfile
+
+    i = sys.argv.index('-c')
+    del sys.argv[i]
+
+    remove_build_dir = 0
+    try:
+        i = sys.argv.index('--build-dir')
+    except ValueError:
+        i = None
+    if i is not None:
+        build_dir = sys.argv[i + 1]
+        del sys.argv[i + 1]
+        del sys.argv[i]
+    else:
+        remove_build_dir = 1
+        build_dir = tempfile.mkdtemp()
+
+    _reg1 = re.compile(r'[-][-]link[-]')
+    sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
+    if sysinfo_flags:
+        sysinfo_flags = [f[7:] for f in sysinfo_flags]
+
+    _reg2 = re.compile(
+        r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include')
+    f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
+    f2py_flags2 = []
+    fl = 0
+    for a in sys.argv[1:]:
+        if a in ['only:', 'skip:']:
+            fl = 1
+        elif a == ':':
+            fl = 0
+        if fl or a == ':':
+            f2py_flags2.append(a)
+    if f2py_flags2 and f2py_flags2[-1] != ':':
+        f2py_flags2.append(':')
+    f2py_flags.extend(f2py_flags2)
+
+    sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
+    _reg3 = re.compile(
+        r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)')
+    flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
+    _reg4 = re.compile(
+        r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))')
+    fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in fc_flags]
+
+    if 1:
+        del_list = []
+        for s in flib_flags:
+            v = '--fcompiler='
+            if s[:len(v)] == v:
+                from numpy.distutils import fcompiler
+                fcompiler.load_all_fcompiler_classes()
+                allowed_keys = list(fcompiler.fcompiler_class.keys())
+                nv = ov = s[len(v):].lower()
+                if ov not in allowed_keys:
+                    vmap = {}  # XXX
+                    try:
+                        nv = vmap[ov]
+                    except KeyError:
+                        if ov not in vmap.values():
+                            print('Unknown vendor: "%s"' % (s[len(v):]))
+                    nv = ov
+                i = flib_flags.index(s)
+                flib_flags[i] = '--fcompiler=' + nv
+                continue
+        for s in del_list:
+            i = flib_flags.index(s)
+            del flib_flags[i]
+        assert len(flib_flags) <= 2, repr(flib_flags)
+
+    _reg5 = re.compile(r'[-][-](verbose)')
+    setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
+
+    if '--quiet' in f2py_flags:
+        setup_flags.append('--quiet')
+
+    modulename = 'untitled'
+    sources = sys.argv[1:]
+
+    for optname in ['--include_paths', '--include-paths']:
+        if optname in sys.argv:
+            i = sys.argv.index(optname)
+            f2py_flags.extend(sys.argv[i:i + 2])
+            del sys.argv[i + 1], sys.argv[i]
+            sources = sys.argv[1:]
+
+    if '-m' in sys.argv:
+        i = sys.argv.index('-m')
+        modulename = sys.argv[i + 1]
+        del sys.argv[i + 1], sys.argv[i]
+        sources = sys.argv[1:]
+    else:
+        from numpy.distutils.command.build_src import get_f2py_modulename
+        pyf_files, sources = filter_files('', '[.]pyf([.]src|)', sources)
+        sources = pyf_files + sources
+        for f in pyf_files:
+            modulename = get_f2py_modulename(f)
+            if modulename:
+                break
+
+    extra_objects, sources = filter_files('', '[.](o|a|so)', sources)
+    include_dirs, sources = filter_files('-I', '', sources, remove_prefix=1)
+    library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1)
+    libraries, sources = filter_files('-l', '', sources, remove_prefix=1)
+    undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1)
+    define_macros, sources = filter_files('-D', '', sources, remove_prefix=1)
+    for i in range(len(define_macros)):
+        name_value = define_macros[i].split('=', 1)
+        if len(name_value) == 1:
+            name_value.append(None)
+        if len(name_value) == 2:
+            define_macros[i] = tuple(name_value)
+        else:
+            print('Invalid use of -D:', name_value)
+
+    from numpy.distutils.system_info import get_info
+
+    num_info = {}
+    if num_info:
+        include_dirs.extend(num_info.get('include_dirs', []))
+
+    from numpy.distutils.core import setup, Extension
+    ext_args = {'name': modulename, 'sources': sources,
+                'include_dirs': include_dirs,
+                'library_dirs': library_dirs,
+                'libraries': libraries,
+                'define_macros': define_macros,
+                'undef_macros': undef_macros,
+                'extra_objects': extra_objects,
+                'f2py_options': f2py_flags,
+                }
+
+    if sysinfo_flags:
+        from numpy.distutils.misc_util import dict_append
+        for n in sysinfo_flags:
+            i = get_info(n)
+            if not i:
+                outmess('No %s resources found in system'
+                        ' (try `f2py --help-link`)\n' % (repr(n)))
+            dict_append(ext_args, **i)
+
+    ext = Extension(**ext_args)
+    sys.argv = [sys.argv[0]] + setup_flags
+    sys.argv.extend(['build',
+                     '--build-temp', build_dir,
+                     '--build-base', build_dir,
+                     '--build-platlib', '.'])
+    if fc_flags:
+        sys.argv.extend(['config_fc'] + fc_flags)
+    if flib_flags:
+        sys.argv.extend(['build_ext'] + flib_flags)
+
+    setup(ext_modules=[ext])
+
+    if remove_build_dir and os.path.exists(build_dir):
+        import shutil
+        outmess('Removing build directory %s\n' % (build_dir))
+        shutil.rmtree(build_dir)
+
+
+def main():
+    if '--help-link' in sys.argv[1:]:
+        sys.argv.remove('--help-link')
+        from numpy.distutils.system_info import show_all
+        show_all()
+        return
+    if '-c' in sys.argv[1:]:
+        run_compile()
+    else:
+        run_main(sys.argv[1:])
+
+# if __name__ == "__main__":
+#    main()
+
+
+# EOF
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
new file mode 100644
index 0000000000..c7041fe25e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
@@ -0,0 +1,48 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+
+from numpy.testing.utils import jiffies, memusage
+
+
+def cmdline():
+    m = re.compile(r'\A\d+\Z')
+    args = []
+    repeat = 1
+    for a in sys.argv[1:]:
+        if m.match(a):
+            repeat = eval(a)
+        else:
+            args.append(a)
+    f2py_opts = ' '.join(args)
+    return repeat, f2py_opts
+
+
+def run(runtest, test_functions, repeat=1):
+    l = [(t, repr(t.__doc__.split('\n')[1].strip())) for t in test_functions]
+    start_memusage = memusage()
+    diff_memusage = None
+    start_jiffies = jiffies()
+    i = 0
+    while i < repeat:
+        i += 1
+        for t, fname in l:
+            runtest(t)
+            if start_memusage is None:
+                continue
+            if diff_memusage is None:
+                diff_memusage = memusage() - start_memusage
+            else:
+                diff_memusage2 = memusage() - start_memusage
+                if diff_memusage2 != diff_memusage:
+                    print('memory usage change at step %i:' % i,
+                          diff_memusage2 - diff_memusage,
+                          fname)
+                    diff_memusage = diff_memusage2
+    current_memusage = memusage()
+    print('run', repeat * len(test_functions), 'tests',
+          'in %.2f seconds' % ((jiffies() - start_jiffies) / 100.0))
+    if start_memusage:
+        print('initial virtual memory size:', start_memusage, 'bytes')
+        print('current virtual memory size:', current_memusage, 'bytes')
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
new file mode 100644
index 0000000000..94a83e97d8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
@@ -0,0 +1,272 @@
+#!/usr/bin/env python2
+"""
+
+Build F90 module support for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/02/03 19:30:23 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.27 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+import numpy as np
+
+from . import capi_maps
+from . import func2subr
+from .crackfortran import undo_rmbadname, undo_rmbadname1
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+options = {}
+
+
+def findf90modules(m):
+    if ismodule(m):
+        return [m]
+    if not hasbody(m):
+        return []
+    ret = []
+    for b in m['body']:
+        if ismodule(b):
+            ret.append(b)
+        else:
+            ret = ret + findf90modules(b)
+    return ret
+
+fgetdims1 = """\
+      external f2pysetdata
+      logical ns
+      integer r,i
+      integer(%d) s(*)
+      ns = .FALSE.
+      if (allocated(d)) then
+         do i=1,r
+            if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
+               ns = .TRUE.
+            end if
+         end do
+         if (ns) then
+            deallocate(d)
+         end if
+      end if
+      if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize
+
+fgetdims2 = """\
+      end if
+      if (allocated(d)) then
+         do i=1,r
+            s(i) = size(d,i)
+         end do
+      end if
+      flag = 1
+      call f2pysetdata(d,allocated(d))"""
+
+fgetdims2_sa = """\
+      end if
+      if (allocated(d)) then
+         do i=1,r
+            s(i) = size(d,i)
+         end do
+         !s(r) must be equal to len(d(1))
+      end if
+      flag = 2
+      call f2pysetdata(d,allocated(d))"""
+
+
+def buildhooks(pymod):
+    global fgetdims1, fgetdims2
+    from . import rules
+    ret = {'f90modhooks': [], 'initf90modhooks': [], 'body': [],
+           'need': ['F_FUNC', 'arrayobject.h'],
+           'separatorsfor': {'includes0': '\n', 'includes': '\n'},
+           'docs': ['"Fortran 90/95 modules:\\n"'],
+           'latexdoc': []}
+    fhooks = ['']
+
+    def fadd(line, s=fhooks):
+        s[0] = '%s\n      %s' % (s[0], line)
+    doc = ['']
+
+    def dadd(line, s=doc):
+        s[0] = '%s\n%s' % (s[0], line)
+    for m in findf90modules(pymod):
+        sargs, fargs, efargs, modobjs, notvars, onlyvars = [], [], [], [], [
+            m['name']], []
+        sargsp = []
+        ifargs = []
+        mfargs = []
+        if hasbody(m):
+            for b in m['body']:
+                notvars.append(b['name'])
+        for n in m['vars'].keys():
+            var = m['vars'][n]
+            if (n not in notvars) and (not l_or(isintent_hide, isprivate)(var)):
+                onlyvars.append(n)
+                mfargs.append(n)
+        outmess('\t\tConstructing F90 module support for "%s"...\n' %
+                (m['name']))
+        if onlyvars:
+            outmess('\t\t  Variables: %s\n' % (' '.join(onlyvars)))
+        chooks = ['']
+
+        def cadd(line, s=chooks):
+            s[0] = '%s\n%s' % (s[0], line)
+        ihooks = ['']
+
+        def iadd(line, s=ihooks):
+            s[0] = '%s\n%s' % (s[0], line)
+
+        vrd = capi_maps.modsign2map(m)
+        cadd('static FortranDataDef f2py_%s_def[] = {' % (m['name']))
+        dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n' % (m['name']))
+        if hasnote(m):
+            note = m['note']
+            if isinstance(note, list):
+                note = '\n'.join(note)
+            dadd(note)
+        if onlyvars:
+            dadd('\\begin{description}')
+        for n in onlyvars:
+            var = m['vars'][n]
+            modobjs.append(n)
+            ct = capi_maps.getctype(var)
+            at = capi_maps.c2capi_map[ct]
+            dm = capi_maps.getarrdims(n, var)
+            dms = dm['dims'].replace('*', '-1').strip()
+            dms = dms.replace(':', '-1').strip()
+            if not dms:
+                dms = '-1'
+            use_fgetdims2 = fgetdims2
+            if isstringarray(var):
+                if 'charselector' in var and 'len' in var['charselector']:
+                    cadd('\t{"%s",%s,{{%s,%s}},%s},'
+                         % (undo_rmbadname1(n), dm['rank'], dms, var['charselector']['len'], at))
+                    use_fgetdims2 = fgetdims2_sa
+                else:
+                    cadd('\t{"%s",%s,{{%s}},%s},' %
+                         (undo_rmbadname1(n), dm['rank'], dms, at))
+            else:
+                cadd('\t{"%s",%s,{{%s}},%s},' %
+                     (undo_rmbadname1(n), dm['rank'], dms, at))
+            dadd('\\item[]{{}\\verb@%s@{}}' %
+                 (capi_maps.getarrdocsign(n, var)))
+            if hasnote(var):
+                note = var['note']
+                if isinstance(note, list):
+                    note = '\n'.join(note)
+                dadd('--- %s' % (note))
+            if isallocatable(var):
+                fargs.append('f2py_%s_getdims_%s' % (m['name'], n))
+                efargs.append(fargs[-1])
+                sargs.append(
+                    'void (*%s)(int*,int*,void(*)(char*,int*),int*)' % (n))
+                sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)')
+                iadd('\tf2py_%s_def[i_f2py++].func = %s;' % (m['name'], n))
+                fadd('subroutine %s(r,s,f2pysetdata,flag)' % (fargs[-1]))
+                fadd('use %s, only: d => %s\n' %
+                     (m['name'], undo_rmbadname1(n)))
+                fadd('integer flag\n')
+                fhooks[0] = fhooks[0] + fgetdims1
+                dms = eval('range(1,%s+1)' % (dm['rank']))
+                fadd(' allocate(d(%s))\n' %
+                     (','.join(['s(%s)' % i for i in dms])))
+                fhooks[0] = fhooks[0] + use_fgetdims2
+                fadd('end subroutine %s' % (fargs[-1]))
+            else:
+                fargs.append(n)
+                sargs.append('char *%s' % (n))
+                sargsp.append('char*')
+                iadd('\tf2py_%s_def[i_f2py++].data = %s;' % (m['name'], n))
+        if onlyvars:
+            dadd('\\end{description}')
+        if hasbody(m):
+            for b in m['body']:
+                if not isroutine(b):
+                    print('Skipping', b['block'], b['name'])
+                    continue
+                modobjs.append('%s()' % (b['name']))
+                b['modulename'] = m['name']
+                api, wrap = rules.buildapi(b)
+                if isfunction(b):
+                    fhooks[0] = fhooks[0] + wrap
+                    fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
+                    ifargs.append(func2subr.createfuncwrapper(b, signature=1))
+                else:
+                    if wrap:
+                        fhooks[0] = fhooks[0] + wrap
+                        fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
+                        ifargs.append(
+                            func2subr.createsubrwrapper(b, signature=1))
+                    else:
+                        fargs.append(b['name'])
+                        mfargs.append(fargs[-1])
+                api['externroutines'] = []
+                ar = applyrules(api, vrd)
+                ar['docs'] = []
+                ar['docshort'] = []
+                ret = dictappend(ret, ar)
+                cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},' %
+                     (b['name'], m['name'], b['name'], m['name'], b['name']))
+                sargs.append('char *%s' % (b['name']))
+                sargsp.append('char *')
+                iadd('\tf2py_%s_def[i_f2py++].data = %s;' %
+                     (m['name'], b['name']))
+        cadd('\t{NULL}\n};\n')
+        iadd('}')
+        ihooks[0] = 'static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s' % (
+            m['name'], ','.join(sargs), ihooks[0])
+        if '_' in m['name']:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'
+             % (F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp)))
+        iadd('static void f2py_init_%s(void) {' % (m['name']))
+        iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
+             % (F_FUNC, m['name'], m['name'].upper(), m['name']))
+        iadd('}\n')
+        ret['f90modhooks'] = ret['f90modhooks'] + chooks + ihooks
+        ret['initf90modhooks'] = ['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
+            m['name'], m['name'], m['name'])] + ret['initf90modhooks']
+        fadd('')
+        fadd('subroutine f2pyinit%s(f2pysetupfunc)' % (m['name']))
+        if mfargs:
+            for a in undo_rmbadname(mfargs):
+                fadd('use %s, only : %s' % (m['name'], a))
+        if ifargs:
+            fadd(' '.join(['interface'] + ifargs))
+            fadd('end interface')
+        fadd('external f2pysetupfunc')
+        if efargs:
+            for a in undo_rmbadname(efargs):
+                fadd('external %s' % (a))
+        fadd('call f2pysetupfunc(%s)' % (','.join(undo_rmbadname(fargs))))
+        fadd('end subroutine f2pyinit%s\n' % (m['name']))
+
+        dadd('\n'.join(ret['latexdoc']).replace(
+            r'\subsection{', r'\subsubsection{'))
+
+        ret['latexdoc'] = []
+        ret['docs'].append('"\t%s --- %s"' % (m['name'],
+                                              ','.join(undo_rmbadname(modobjs))))
+
+    ret['routine_defs'] = ''
+    ret['doc'] = []
+    ret['docshort'] = []
+    ret['latexdoc'] = doc[0]
+    if len(ret['docs']) <= 1:
+        ret['docs'] = ''
+    return ret, fhooks[0]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.py
new file mode 100644
index 0000000000..bb690bb419
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.py
@@ -0,0 +1,299 @@
+#!/usr/bin/env python2
+"""
+
+Rules for building C/API module with f2py2e.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2004/11/26 11:13:06 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.16 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+import copy
+
+from .auxfuncs import (
+    getfortranname, isexternal, isfunction, isfunction_wrap, isintent_in,
+    isintent_out, islogicalfunction, ismoduleroutine, isscalar,
+    issubroutine, issubroutine_wrap, outmess, show
+)
+
+
+def var2fixfortran(vars, a, fa=None, f90mode=None):
+    if fa is None:
+        fa = a
+    if a not in vars:
+        show(vars)
+        outmess('var2fixfortran: No definition for argument "%s".\n' % a)
+        return ''
+    if 'typespec' not in vars[a]:
+        show(vars[a])
+        outmess('var2fixfortran: No typespec for argument "%s".\n' % a)
+        return ''
+    vardef = vars[a]['typespec']
+    if vardef == 'type' and 'typename' in vars[a]:
+        vardef = '%s(%s)' % (vardef, vars[a]['typename'])
+    selector = {}
+    lk = ''
+    if 'kindselector' in vars[a]:
+        selector = vars[a]['kindselector']
+        lk = 'kind'
+    elif 'charselector' in vars[a]:
+        selector = vars[a]['charselector']
+        lk = 'len'
+    if '*' in selector:
+        if f90mode:
+            if selector['*'] in ['*', ':', '(*)']:
+                vardef = '%s(len=*)' % (vardef)
+            else:
+                vardef = '%s(%s=%s)' % (vardef, lk, selector['*'])
+        else:
+            if selector['*'] in ['*', ':']:
+                vardef = '%s*(%s)' % (vardef, selector['*'])
+            else:
+                vardef = '%s*%s' % (vardef, selector['*'])
+    else:
+        if 'len' in selector:
+            vardef = '%s(len=%s' % (vardef, selector['len'])
+            if 'kind' in selector:
+                vardef = '%s,kind=%s)' % (vardef, selector['kind'])
+            else:
+                vardef = '%s)' % (vardef)
+        elif 'kind' in selector:
+            vardef = '%s(kind=%s)' % (vardef, selector['kind'])
+
+    vardef = '%s %s' % (vardef, fa)
+    if 'dimension' in vars[a]:
+        vardef = '%s(%s)' % (vardef, ','.join(vars[a]['dimension']))
+    return vardef
+
+
+def createfuncwrapper(rout, signature=0):
+    assert isfunction(rout)
+
+    extra_args = []
+    vars = rout['vars']
+    for a in rout['args']:
+        v = rout['vars'][a]
+        for i, d in enumerate(v.get('dimension', [])):
+            if d == ':':
+                dn = 'f2py_%s_d%s' % (a, i)
+                dv = dict(typespec='integer', intent=['hide'])
+                dv['='] = 'shape(%s, %s)' % (a, i)
+                extra_args.append(dn)
+                vars[dn] = dv
+                v['dimension'][i] = dn
+    rout['args'].extend(extra_args)
+    need_interface = bool(extra_args)
+
+    ret = ['']
+
+    def add(line, ret=ret):
+        ret[0] = '%s\n      %s' % (ret[0], line)
+    name = rout['name']
+    fortranname = getfortranname(rout)
+    f90mode = ismoduleroutine(rout)
+    newname = '%sf2pywrap' % (name)
+
+    if newname not in vars:
+        vars[newname] = vars[name]
+        args = [newname] + rout['args'][1:]
+    else:
+        args = [newname] + rout['args']
+
+    l = var2fixfortran(vars, name, newname, f90mode)
+    if l[:13] == 'character*(*)':
+        if f90mode:
+            l = 'character(len=10)' + l[13:]
+        else:
+            l = 'character*10' + l[13:]
+        charselect = vars[name]['charselector']
+        if charselect.get('*', '') == '(*)':
+            charselect['*'] = '10'
+    sargs = ', '.join(args)
+    if f90mode:
+        add('subroutine f2pywrap_%s_%s (%s)' %
+            (rout['modulename'], name, sargs))
+        if not signature:
+            add('use %s, only : %s' % (rout['modulename'], fortranname))
+    else:
+        add('subroutine f2pywrap%s (%s)' % (name, sargs))
+        if not need_interface:
+            add('external %s' % (fortranname))
+            l = l + ', ' + fortranname
+    if need_interface:
+        for line in rout['saved_interface'].split('\n'):
+            if line.lstrip().startswith('use '):
+                add(line)
+
+    args = args[1:]
+    dumped_args = []
+    for a in args:
+        if isexternal(vars[a]):
+            add('external %s' % (a))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isscalar(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isintent_in(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        add(var2fixfortran(vars, a, f90mode=f90mode))
+
+    add(l)
+
+    if need_interface:
+        if f90mode:
+            # f90 module already defines needed interface
+            pass
+        else:
+            add('interface')
+            add(rout['saved_interface'].lstrip())
+            add('end interface')
+
+    sargs = ', '.join([a for a in args if a not in extra_args])
+
+    if not signature:
+        if islogicalfunction(rout):
+            add('%s = .not.(.not.%s(%s))' % (newname, fortranname, sargs))
+        else:
+            add('%s = %s(%s)' % (newname, fortranname, sargs))
+    if f90mode:
+        add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
+    else:
+        add('end')
+    return ret[0]
+
+
+def createsubrwrapper(rout, signature=0):
+    assert issubroutine(rout)
+
+    extra_args = []
+    vars = rout['vars']
+    for a in rout['args']:
+        v = rout['vars'][a]
+        for i, d in enumerate(v.get('dimension', [])):
+            if d == ':':
+                dn = 'f2py_%s_d%s' % (a, i)
+                dv = dict(typespec='integer', intent=['hide'])
+                dv['='] = 'shape(%s, %s)' % (a, i)
+                extra_args.append(dn)
+                vars[dn] = dv
+                v['dimension'][i] = dn
+    rout['args'].extend(extra_args)
+    need_interface = bool(extra_args)
+
+    ret = ['']
+
+    def add(line, ret=ret):
+        ret[0] = '%s\n      %s' % (ret[0], line)
+    name = rout['name']
+    fortranname = getfortranname(rout)
+    f90mode = ismoduleroutine(rout)
+
+    args = rout['args']
+
+    sargs = ', '.join(args)
+    if f90mode:
+        add('subroutine f2pywrap_%s_%s (%s)' %
+            (rout['modulename'], name, sargs))
+        if not signature:
+            add('use %s, only : %s' % (rout['modulename'], fortranname))
+    else:
+        add('subroutine f2pywrap%s (%s)' % (name, sargs))
+        if not need_interface:
+            add('external %s' % (fortranname))
+
+    if need_interface:
+        for line in rout['saved_interface'].split('\n'):
+            if line.lstrip().startswith('use '):
+                add(line)
+
+    dumped_args = []
+    for a in args:
+        if isexternal(vars[a]):
+            add('external %s' % (a))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isscalar(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        add(var2fixfortran(vars, a, f90mode=f90mode))
+
+    if need_interface:
+        if f90mode:
+            # f90 module already defines needed interface
+            pass
+        else:
+            add('interface')
+            add(rout['saved_interface'].lstrip())
+            add('end interface')
+
+    sargs = ', '.join([a for a in args if a not in extra_args])
+
+    if not signature:
+        add('call %s(%s)' % (fortranname, sargs))
+    if f90mode:
+        add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
+    else:
+        add('end')
+    return ret[0]
+
+
+def assubr(rout):
+    if isfunction_wrap(rout):
+        fortranname = getfortranname(rout)
+        name = rout['name']
+        outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n' % (
+            name, fortranname))
+        rout = copy.copy(rout)
+        fname = name
+        rname = fname
+        if 'result' in rout:
+            rname = rout['result']
+            rout['vars'][fname] = rout['vars'][rname]
+        fvar = rout['vars'][fname]
+        if not isintent_out(fvar):
+            if 'intent' not in fvar:
+                fvar['intent'] = []
+            fvar['intent'].append('out')
+            flag = 1
+            for i in fvar['intent']:
+                if i.startswith('out='):
+                    flag = 0
+                    break
+            if flag:
+                fvar['intent'].append('out=%s' % (rname))
+        rout['args'][:] = [fname] + rout['args']
+        return rout, createfuncwrapper(rout)
+    if issubroutine_wrap(rout):
+        fortranname = getfortranname(rout)
+        name = rout['name']
+        outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n' % (
+            name, fortranname))
+        rout = copy.copy(rout)
+        return rout, createsubrwrapper(rout)
+    return rout, ''
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/info.py
new file mode 100644
index 0000000000..c895c5de28
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/info.py
@@ -0,0 +1,6 @@
+"""Fortran to Python Interface Generator.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+postpone_import = True
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/rules.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/rules.py
new file mode 100644
index 0000000000..09b2a597a3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/rules.py
@@ -0,0 +1,1475 @@
+#!/usr/bin/env python2
+"""
+
+Rules for building C/API module with f2py2e.
+
+Here is a skeleton of a new wrapper function (13Dec2001):
+
+wrapper_function(args)
+  declarations
+  get_python_arguments, say, `a' and `b'
+
+  get_a_from_python
+  if (successful) {
+
+    get_b_from_python
+    if (successful) {
+
+      callfortran
+      if (succesful) {
+
+        put_a_to_python
+        if (succesful) {
+
+          put_b_to_python
+          if (succesful) {
+
+            buildvalue = ...
+
+          }
+
+        }
+
+      }
+
+    }
+    cleanup_b
+
+  }
+  cleanup_a
+
+  return buildvalue
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/08/30 08:58:42 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.129 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+import os
+import time
+import copy
+
+from .auxfuncs import (
+    applyrules, debugcapi, dictappend, errmess, gentitle, getargs2,
+    hascallstatement, hasexternals, hasinitvalue, hasnote, hasresultnote,
+    isarray, isarrayofstrings, iscomplex, iscomplexarray,
+    iscomplexfunction, iscomplexfunction_warn, isdummyroutine, isexternal,
+    isfunction, isfunction_wrap, isint1array, isintent_aux, isintent_c,
+    isintent_callback, isintent_copy, isintent_hide, isintent_inout,
+    isintent_nothide, isintent_out, isintent_overwrite, islogical,
+    islong_complex, islong_double, islong_doublefunction, islong_long,
+    islong_longfunction, ismoduleroutine, isoptional, isrequired, isscalar,
+    issigned_long_longarray, isstring, isstringarray, isstringfunction,
+    issubroutine, issubroutine_wrap, isthreadsafe, isunsigned,
+    isunsigned_char, isunsigned_chararray, isunsigned_long_long,
+    isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray,
+    l_and, l_not, l_or, outmess, replace, stripcomma,
+)
+
+from . import capi_maps
+from . import cfuncs
+from . import common_rules
+from . import use_rules
+from . import f90mod_rules
+from . import func2subr
+
+options = {}
+sepdict = {}
+#for k in ['need_cfuncs']: sepdict[k]=','
+for k in ['decl',
+          'frompyobj',
+          'cleanupfrompyobj',
+          'topyarr', 'method',
+          'pyobjfrom', 'closepyobjfrom',
+          'freemem',
+          'userincludes',
+          'includes0', 'includes', 'typedefs', 'typedefs_generated',
+          'cppmacros', 'cfuncs', 'callbacks',
+          'latexdoc',
+          'restdoc',
+          'routine_defs', 'externroutines',
+          'initf2pywraphooks',
+          'commonhooks', 'initcommonhooks',
+          'f90modhooks', 'initf90modhooks']:
+    sepdict[k] = '\n'
+
+#################### Rules for C/API module #################
+
+module_rules = {
+    'modulebody': """\
+/* File: #modulename#module.c
+ * This file is auto-generated with f2py (version:#f2py_version#).
+ * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
+ * written by Pearu Peterson <pearu@cens.ioc.ee>.
+ * See http://cens.ioc.ee/projects/f2py2e/
+ * Generation date: """ + time.asctime(time.localtime(time.time())) + """
+ * $R""" + """evision:$
+ * $D""" + """ate:$
+ * Do not edit this file directly unless you know what you are doing!!!
+ */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+""" + gentitle("See f2py2e/cfuncs.py: includes") + """
+#includes#
+#includes0#
+
+""" + gentitle("See f2py2e/rules.py: mod_rules['modulebody']") + """
+static PyObject *#modulename#_error;
+static PyObject *#modulename#_module;
+
+""" + gentitle("See f2py2e/cfuncs.py: typedefs") + """
+#typedefs#
+
+""" + gentitle("See f2py2e/cfuncs.py: typedefs_generated") + """
+#typedefs_generated#
+
+""" + gentitle("See f2py2e/cfuncs.py: cppmacros") + """
+#cppmacros#
+
+""" + gentitle("See f2py2e/cfuncs.py: cfuncs") + """
+#cfuncs#
+
+""" + gentitle("See f2py2e/cfuncs.py: userincludes") + """
+#userincludes#
+
+""" + gentitle("See f2py2e/capi_rules.py: usercode") + """
+#usercode#
+
+/* See f2py2e/rules.py */
+#externroutines#
+
+""" + gentitle("See f2py2e/capi_rules.py: usercode1") + """
+#usercode1#
+
+""" + gentitle("See f2py2e/cb_rules.py: buildcallback") + """
+#callbacks#
+
+""" + gentitle("See f2py2e/rules.py: buildapi") + """
+#body#
+
+""" + gentitle("See f2py2e/f90mod_rules.py: buildhooks") + """
+#f90modhooks#
+
+""" + gentitle("See f2py2e/rules.py: module_rules['modulebody']") + """
+
+""" + gentitle("See f2py2e/common_rules.py: buildhooks") + """
+#commonhooks#
+
+""" + gentitle("See f2py2e/rules.py") + """
+
+static FortranDataDef f2py_routine_defs[] = {
+#routine_defs#
+\t{NULL}
+};
+
+static PyMethodDef f2py_module_methods[] = {
+#pymethoddef#
+\t{NULL,NULL}
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+static struct PyModuleDef moduledef = {
+\tPyModuleDef_HEAD_INIT,
+\t"#modulename#",
+\tNULL,
+\t-1,
+\tf2py_module_methods,
+\tNULL,
+\tNULL,
+\tNULL,
+\tNULL
+};
+#endif
+
+#if PY_VERSION_HEX >= 0x03000000
+#define RETVAL m
+PyMODINIT_FUNC PyInit_#modulename#(void) {
+#else
+#define RETVAL
+PyMODINIT_FUNC init#modulename#(void) {
+#endif
+\tint i;
+\tPyObject *m,*d, *s;
+#if PY_VERSION_HEX >= 0x03000000
+\tm = #modulename#_module = PyModule_Create(&moduledef);
+#else
+\tm = #modulename#_module = Py_InitModule(\"#modulename#\", f2py_module_methods);
+#endif
+\tPy_TYPE(&PyFortran_Type) = &PyType_Type;
+\timport_array();
+\tif (PyErr_Occurred())
+\t\t{PyErr_SetString(PyExc_ImportError, \"can't initialize module #modulename# (failed to import numpy)\"); return RETVAL;}
+\td = PyModule_GetDict(m);
+\ts = PyString_FromString(\"$R""" + """evision: $\");
+\tPyDict_SetItemString(d, \"__version__\", s);
+#if PY_VERSION_HEX >= 0x03000000
+\ts = PyUnicode_FromString(
+#else
+\ts = PyString_FromString(
+#endif
+\t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\");
+\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]));
+#initf2pywraphooks#
+#initf90modhooks#
+#initcommonhooks#
+#interface_usercode#
+
+#ifdef F2PY_REPORT_ATEXIT
+\tif (! PyErr_Occurred())
+\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\");
+#endif
+
+\treturn RETVAL;
+}
+#ifdef __cplusplus
+}
+#endif
+""",
+    'separatorsfor': {'latexdoc': '\n\n',
+                      'restdoc': '\n\n'},
+    'latexdoc': ['\\section{Module \\texttt{#texmodulename#}}\n',
+                 '#modnote#\n',
+                 '#latexdoc#'],
+    'restdoc': ['Module #modulename#\n' + '=' * 80,
+                '\n#restdoc#']
+}
+
+defmod_rules = [
+    {'body': '/*eof body*/',
+     'method': '/*eof method*/',
+     'externroutines': '/*eof externroutines*/',
+     'routine_defs': '/*eof routine_defs*/',
+     'initf90modhooks': '/*eof initf90modhooks*/',
+     'initf2pywraphooks': '/*eof initf2pywraphooks*/',
+     'initcommonhooks': '/*eof initcommonhooks*/',
+     'latexdoc': '',
+     'restdoc': '',
+     'modnote': {hasnote: '#note#', l_not(hasnote): ''},
+     }
+]
+
+routine_rules = {
+    'separatorsfor': sepdict,
+    'body': """
+#begintitle#
+static char doc_#apiname#[] = \"\\\n#docreturn##name#(#docsignatureshort#)\\n\\nWrapper for ``#name#``.\\\n\\n#docstrsigns#\";
+/* #declfortranroutine# */
+static PyObject *#apiname#(const PyObject *capi_self,
+                           PyObject *capi_args,
+                           PyObject *capi_keywds,
+                           #functype# (*f2py_func)(#callprotoargument#)) {
+\tPyObject * volatile capi_buildvalue = NULL;
+\tvolatile int f2py_success = 1;
+#decl#
+\tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL};
+#usercode#
+#routdebugenter#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_start_clock();
+#endif
+\tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\
+\t\t\"#argformat##keyformat##xaformat#:#pyname#\",\\
+\t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL;
+#frompyobj#
+/*end of frompyobj*/
+#ifdef F2PY_REPORT_ATEXIT
+f2py_start_call_clock();
+#endif
+#callfortranroutine#
+if (PyErr_Occurred())
+  f2py_success = 0;
+#ifdef F2PY_REPORT_ATEXIT
+f2py_stop_call_clock();
+#endif
+/*end of callfortranroutine*/
+\t\tif (f2py_success) {
+#pyobjfrom#
+/*end of pyobjfrom*/
+\t\tCFUNCSMESS(\"Building return value.\\n\");
+\t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#);
+/*closepyobjfrom*/
+#closepyobjfrom#
+\t\t} /*if (f2py_success) after callfortranroutine*/
+/*cleanupfrompyobj*/
+#cleanupfrompyobj#
+\tif (capi_buildvalue == NULL) {
+#routdebugfailure#
+\t} else {
+#routdebugleave#
+\t}
+\tCFUNCSMESS(\"Freeing memory.\\n\");
+#freemem#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_stop_clock();
+#endif
+\treturn capi_buildvalue;
+}
+#endtitle#
+""",
+    'routine_defs': '#routine_def#',
+    'initf2pywraphooks': '#initf2pywraphook#',
+    'externroutines': '#declfortranroutine#',
+    'doc': '#docreturn##name#(#docsignature#)',
+    'docshort': '#docreturn##name#(#docsignatureshort#)',
+    'docs': '"\t#docreturn##name#(#docsignature#)\\n"\n',
+    'need': ['arrayobject.h', 'CFUNCSMESS', 'MINMAX'],
+    'cppmacros': {debugcapi: '#define DEBUGCFUNCS'},
+    'latexdoc': ['\\subsection{Wrapper function \\texttt{#texname#}}\n',
+                 """
+\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)}
+#routnote#
+
+#latexdocstrsigns#
+"""],
+    'restdoc': ['Wrapped function ``#name#``\n' + '-' * 80,
+
+                ]
+}
+
+################## Rules for C/API function ##############
+
+rout_rules = [
+    {  # Init
+        'separatorsfor': {'callfortranroutine': '\n', 'routdebugenter': '\n', 'decl': '\n',
+                          'routdebugleave': '\n', 'routdebugfailure': '\n',
+                          'setjmpbuf': ' || ',
+                          'docstrreq': '\n', 'docstropt': '\n', 'docstrout': '\n',
+                          'docstrcbs': '\n', 'docstrsigns': '\\n"\n"',
+                          'latexdocstrsigns': '\n',
+                          'latexdocstrreq': '\n', 'latexdocstropt': '\n',
+                          'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
+                          },
+        'kwlist': '', 'kwlistopt': '', 'callfortran': '', 'callfortranappend': '',
+        'docsign': '', 'docsignopt': '', 'decl': '/*decl*/',
+        'freemem': '/*freemem*/',
+        'docsignshort': '', 'docsignoptshort': '',
+        'docstrsigns': '', 'latexdocstrsigns': '',
+        'docstrreq': '\\nParameters\\n----------',
+        'docstropt': '\\nOther Parameters\\n----------------',
+        'docstrout': '\\nReturns\\n-------',
+        'docstrcbs': '\\nNotes\\n-----\\nCall-back functions::\\n',
+        'latexdocstrreq': '\\noindent Required arguments:',
+        'latexdocstropt': '\\noindent Optional arguments:',
+        'latexdocstrout': '\\noindent Return objects:',
+        'latexdocstrcbs': '\\noindent Call-back functions:',
+        'args_capi': '', 'keys_capi': '', 'functype': '',
+        'frompyobj': '/*frompyobj*/',
+        # this list will be reversed
+        'cleanupfrompyobj': ['/*end of cleanupfrompyobj*/'],
+        'pyobjfrom': '/*pyobjfrom*/',
+        # this list will be reversed
+        'closepyobjfrom': ['/*end of closepyobjfrom*/'],
+        'topyarr': '/*topyarr*/', 'routdebugleave': '/*routdebugleave*/',
+        'routdebugenter': '/*routdebugenter*/',
+        'routdebugfailure': '/*routdebugfailure*/',
+        'callfortranroutine': '/*callfortranroutine*/',
+        'argformat': '', 'keyformat': '', 'need_cfuncs': '',
+        'docreturn': '', 'return': '', 'returnformat': '', 'rformat': '',
+        'kwlistxa': '', 'keys_xa': '', 'xaformat': '', 'docsignxa': '', 'docsignxashort': '',
+        'initf2pywraphook': '',
+        'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
+    }, {
+        'apiname': 'f2py_rout_#modulename#_#name#',
+        'pyname': '#modulename#.#name#',
+        'decl': '',
+        '_check': l_not(ismoduleroutine)
+    }, {
+        'apiname': 'f2py_rout_#modulename#_#f90modulename#_#name#',
+        'pyname': '#modulename#.#f90modulename#.#name#',
+        'decl': '',
+        '_check': ismoduleroutine
+    }, {  # Subroutine
+        'functype': 'void',
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);',
+                               ismoduleroutine: '',
+                               isdummyroutine: ''
+                               },
+        'routine_def': {l_not(l_or(ismoduleroutine, isintent_c, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isdummyroutine): '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'need': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'F_FUNC'},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\t\tif (#setjmpbuf#) {
+\t\t\tf2py_success = 0;
+\t\t} else {"""},
+            {isthreadsafe: '\t\t\tPy_BEGIN_ALLOW_THREADS'},
+            {hascallstatement: '''\t\t\t\t#callstatement#;
+\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t\t\t\t(*f2py_func)(#callfortran#);'},
+            {isthreadsafe: '\t\t\tPy_END_ALLOW_THREADS'},
+            {hasexternals: """\t\t}"""}
+        ],
+        '_check': l_and(issubroutine, l_not(issubroutine_wrap)),
+    }, {  # Wrapped function
+        'functype': 'void',
+        'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
+                               isdummyroutine: '',
+                               },
+
+        'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
+    {
+      extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void);
+      PyObject* o = PyDict_GetItemString(d,"#name#");
+      PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+#if PY_VERSION_HEX >= 0x03000000
+      PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+#else
+      PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+#endif
+    }
+    '''},
+        'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t(*f2py_func)(#callfortran#);'},
+            {hascallstatement:
+                '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'}
+        ],
+        '_check': isfunction_wrap,
+    }, {  # Wrapped subroutine
+        'functype': 'void',
+        'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
+                               isdummyroutine: '',
+                               },
+
+        'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
+    {
+      extern void #F_FUNC#(#name_lower#,#NAME#)(void);
+      PyObject* o = PyDict_GetItemString(d,"#name#");
+      PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+#if PY_VERSION_HEX >= 0x03000000
+      PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+#else
+      PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+#endif
+    }
+    '''},
+        'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t(*f2py_func)(#callfortran#);'},
+            {hascallstatement:
+                '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'}
+        ],
+        '_check': issubroutine_wrap,
+    }, {  # Function
+        'functype': '#ctype#',
+        'docreturn': {l_not(isintent_hide): '#rname#,'},
+        'docstrout': '#pydocsignout#',
+        'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                           {hasresultnote: '--- #resultnote#'}],
+        'callfortranroutine': [{l_and(debugcapi, isstringfunction): """\
+#ifdef USESCOMPAQFORTRAN
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\");
+#else
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
+#endif
+"""},
+                               {l_and(debugcapi, l_not(isstringfunction)): """\
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
+"""}
+                               ],
+        '_check': l_and(isfunction, l_not(isfunction_wrap))
+    }, {  # Scalar function
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern #ctype# #fortranname#(#callprotoargument#);',
+                               isdummyroutine: ''
+                               },
+        'routine_def': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'decl': [{iscomplexfunction_warn: '\t#ctype# #name#_return_value={0,0};',
+                  l_not(iscomplexfunction): '\t#ctype# #name#_return_value=0;'},
+                 {iscomplexfunction:
+                  '\tPyObject *#name#_return_value_capi = Py_None;'}
+                 ],
+        'callfortranroutine': [
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {hascallstatement: '''\t#callstatement#;
+/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/
+'''},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t#name#_return_value = (*f2py_func)(#callfortran#);'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'},
+            {l_and(debugcapi, iscomplexfunction)
+                   : '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'},
+            {l_and(debugcapi, l_not(iscomplexfunction)): '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}],
+        'pyobjfrom': {iscomplexfunction: '\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'},
+        'need': [{l_not(isdummyroutine): 'F_FUNC'},
+                 {iscomplexfunction: 'pyobj_from_#ctype#1'},
+                 {islong_longfunction: 'long_long'},
+                 {islong_doublefunction: 'long_double'}],
+        'returnformat': {l_not(isintent_hide): '#rformat#'},
+        'return': {iscomplexfunction: ',#name#_return_value_capi',
+                   l_not(l_or(iscomplexfunction, isintent_hide)): ',#name#_return_value'},
+        '_check': l_and(isfunction, l_not(isstringfunction), l_not(isfunction_wrap))
+    }, {  # String function # in use for --no-wrap
+        'declfortranroutine': 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+        'routine_def': {l_not(l_or(ismoduleroutine, isintent_c)):
+                        '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c):
+                        '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},'
+                        },
+        'decl': ['\t#ctype# #name#_return_value = NULL;',
+                 '\tint #name#_return_value_len = 0;'],
+        'callfortran':'#name#_return_value,#name#_return_value_len,',
+        'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
+                              '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
+                              '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
+                              '\t\tf2py_success = 0;',
+                              '\t} else {',
+                              "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';",
+                              '\t}',
+                              '\tif (f2py_success) {',
+                              {hasexternals: """\
+\t\tif (#setjmpbuf#) {
+\t\t\tf2py_success = 0;
+\t\t} else {"""},
+                              {isthreadsafe: '\t\tPy_BEGIN_ALLOW_THREADS'},
+                              """\
+#ifdef USESCOMPAQFORTRAN
+\t\t(*f2py_func)(#callcompaqfortran#);
+#else
+\t\t(*f2py_func)(#callfortran#);
+#endif
+""",
+                              {isthreadsafe: '\t\tPy_END_ALLOW_THREADS'},
+                              {hasexternals: '\t\t}'},
+                              {debugcapi:
+                                  '\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'},
+                              '\t} /* if (f2py_success) after (string)malloc */',
+                              ],
+        'returnformat': '#rformat#',
+        'return': ',#name#_return_value',
+        'freemem': '\tSTRINGFREE(#name#_return_value);',
+        'need': ['F_FUNC', '#ctype#', 'STRINGFREE'],
+        '_check':l_and(isstringfunction, l_not(isfunction_wrap))  # ???obsolete
+    },
+    {  # Debugging
+        'routdebugenter': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");',
+        'routdebugleave': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");',
+        'routdebugfailure': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");',
+        '_check': debugcapi
+    }
+]
+
+################ Rules for arguments ##################
+
+typedef_need_dict = {islong_long: 'long_long',
+                     islong_double: 'long_double',
+                     islong_complex: 'complex_long_double',
+                     isunsigned_char: 'unsigned_char',
+                     isunsigned_short: 'unsigned_short',
+                     isunsigned: 'unsigned',
+                     isunsigned_long_long: 'unsigned_long_long',
+                     isunsigned_chararray: 'unsigned_char',
+                     isunsigned_shortarray: 'unsigned_short',
+                     isunsigned_long_longarray: 'unsigned_long_long',
+                     issigned_long_longarray: 'long_long',
+                     }
+
+aux_rules = [
+    {
+        'separatorsfor': sepdict
+    },
+    {  # Common
+        'frompyobj': ['\t/* Processing auxiliary variable #varname# */',
+                      {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
+        'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
+        'need': typedef_need_dict,
+    },
+    # Scalars (not complex)
+    {  # Common
+        'decl': '\t#ctype# #varname# = 0;',
+        'need': {hasinitvalue: 'math.h'},
+        'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+    },
+    {
+        'return': ',#varname#',
+        'docstrout': '#pydocsignout#',
+        'docreturn': '#outvarname#,',
+        'returnformat': '#varrformat#',
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_out),
+    },
+    # Complex scalars
+    {  # Common
+        'decl': '\t#ctype# #varname#;',
+        'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
+        '_check': iscomplex
+    },
+    # String
+    {  # Common
+        'decl': ['\t#ctype# #varname# = NULL;',
+                 '\tint slen(#varname#);',
+                 ],
+        'need':['len..'],
+        '_check':isstring
+    },
+    # Array
+    {  # Common
+        'decl': ['\t#ctype# *#varname# = NULL;',
+                 '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
+                 '\tconst int #varname#_Rank = #rank#;',
+                 ],
+        'need':['len..', {hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
+        '_check': isarray
+    },
+    # Scalararray
+    {  # Common
+        '_check': l_and(isarray, l_not(iscomplexarray))
+    }, {  # Not hidden
+        '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
+    },
+    # Integer*1 array
+    {'need': '#ctype#',
+     '_check': isint1array,
+     '_depend': ''
+     },
+    # Integer*-1 array
+    {'need': '#ctype#',
+     '_check': isunsigned_chararray,
+     '_depend': ''
+     },
+    # Integer*-2 array
+    {'need': '#ctype#',
+     '_check': isunsigned_shortarray,
+     '_depend': ''
+     },
+    # Integer*-8 array
+    {'need': '#ctype#',
+     '_check': isunsigned_long_longarray,
+     '_depend': ''
+     },
+    # Complexarray
+    {'need': '#ctype#',
+     '_check': iscomplexarray,
+     '_depend': ''
+     },
+    # Stringarray
+    {
+        'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
+        'need': 'string',
+        '_check': isstringarray
+    }
+]
+
+arg_rules = [
+    {
+        'separatorsfor': sepdict
+    },
+    {  # Common
+        'frompyobj': ['\t/* Processing variable #varname# */',
+                      {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
+        'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
+        '_depend': '',
+        'need': typedef_need_dict,
+    },
+    # Doc signatures
+    {
+        'docstropt': {l_and(isoptional, isintent_nothide): '#pydocsign#'},
+        'docstrreq': {l_and(isrequired, isintent_nothide): '#pydocsign#'},
+        'docstrout': {isintent_out: '#pydocsignout#'},
+        'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                                          {l_and(hasnote, isintent_hide): '--- #note#',
+                                           l_and(hasnote, isintent_nothide): '--- See above.'}]},
+        'depend': ''
+    },
+    # Required/Optional arguments
+    {
+        'kwlist': '"#varname#",',
+        'docsign': '#varname#,',
+        '_check': l_and(isintent_nothide, l_not(isoptional))
+    },
+    {
+        'kwlistopt': '"#varname#",',
+        'docsignopt': '#varname#=#showinit#,',
+        'docsignoptshort': '#varname#,',
+        '_check': l_and(isintent_nothide, isoptional)
+    },
+    # Docstring/BuildValue
+    {
+        'docreturn': '#outvarname#,',
+        'returnformat': '#varrformat#',
+        '_check': isintent_out
+    },
+    # Externals (call-back functions)
+    {  # Common
+        'docsignxa': {isintent_nothide: '#varname#_extra_args=(),'},
+        'docsignxashort': {isintent_nothide: '#varname#_extra_args,'},
+        'docstropt': {isintent_nothide: '#varname#_extra_args : input tuple, optional\\n    Default: ()'},
+        'docstrcbs': '#cbdocstr#',
+        'latexdocstrcbs': '\\item[] #cblatexdocstr#',
+        'latexdocstropt': {isintent_nothide: '\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'},
+        'decl': ['\tPyObject *#varname#_capi = Py_None;',
+                 '\tPyTupleObject *#varname#_xa_capi = NULL;',
+                 '\tPyTupleObject *#varname#_args_capi = NULL;',
+                 '\tint #varname#_nofargs_capi = 0;',
+                 {l_not(isintent_callback):
+                  '\t#cbname#_typedef #varname#_cptr;'}
+                 ],
+        'kwlistxa': {isintent_nothide: '"#varname#_extra_args",'},
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'xaformat': {isintent_nothide: 'O!'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'keys_xa': ',&PyTuple_Type,&#varname#_xa_capi',
+        'setjmpbuf': '(setjmp(#cbname#_jmpbuf))',
+        'callfortran': {l_not(isintent_callback): '#varname#_cptr,'},
+        'need': ['#cbname#', 'setjmp.h'],
+        '_check':isexternal
+    },
+    {
+        'frompyobj': [{l_not(isintent_callback): """\
+if(F2PyCapsule_Check(#varname#_capi)) {
+  #varname#_cptr = F2PyCapsule_AsVoidPtr(#varname#_capi);
+} else {
+  #varname#_cptr = #cbname#;
+}
+"""}, {isintent_callback: """\
+if (#varname#_capi==Py_None) {
+  #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\");
+  if (#varname#_capi) {
+    if (#varname#_xa_capi==NULL) {
+      if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) {
+        PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\");
+        if (capi_tmp)
+          #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
+        else
+          #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\");
+        if (#varname#_xa_capi==NULL) {
+          PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\");
+          return NULL;
+        }
+      }
+    }
+  }
+  if (#varname#_capi==NULL) {
+    PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\");
+    return NULL;
+  }
+}
+"""},
+            """\
+\t#varname#_nofargs_capi = #cbname#_nofargs;
+\tif (create_cb_arglist(#varname#_capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#cbname#_nofargs,&#varname#_args_capi,\"failed in processing argument list for call-back #varname#.\")) {
+\t\tjmp_buf #varname#_jmpbuf;""",
+            {debugcapi: ["""\
+\t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs);
+\t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""",
+                         {l_not(isintent_callback): """\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]},
+            """\
+\t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\");
+\t\tSWAP(#varname#_capi,#cbname#_capi,PyObject);
+\t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject);
+\t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""",
+        ],
+        'cleanupfrompyobj':
+        """\
+\t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\");
+\t\t#cbname#_capi = #varname#_capi;
+\t\tPy_DECREF(#cbname#_args_capi);
+\t\t#cbname#_args_capi = #varname#_args_capi;
+\t\t#cbname#_nofargs = #varname#_nofargs_capi;
+\t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf));
+\t}""",
+        'need': ['SWAP', 'create_cb_arglist'],
+        '_check':isexternal,
+        '_depend':''
+    },
+    # Scalars (not complex)
+    {  # Common
+        'decl': '\t#ctype# #varname# = 0;',
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
+        'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
+        'return': {isintent_out: ',#varname#'},
+        '_check': l_and(isscalar, l_not(iscomplex))
+    }, {
+        'need': {hasinitvalue: 'math.h'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'pyobjfrom': {isintent_inout: """\
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
+\tif (f2py_success) {"""},
+        'closepyobjfrom': {isintent_inout: "\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide)
+    }, {
+        'frompyobj': [
+            # hasinitvalue...
+            #   if pyobj is None:
+            #     varname = init
+            #   else
+            #     from_pyobj(varname)
+            #
+            # isoptional and noinitvalue...
+            #   if pyobj is not None:
+            #     from_pyobj(varname)
+            #   else:
+            #     varname is uninitialized
+            #
+            # ...
+            #   from_pyobj(varname)
+            #
+            {hasinitvalue: '\tif (#varname#_capi == Py_None) #varname# = #init#; else',
+             '_depend': ''},
+            {l_and(isoptional, l_not(hasinitvalue)): '\tif (#varname#_capi != Py_None)',
+             '_depend': ''},
+            {l_not(islogical): '''\
+\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");
+\tif (f2py_success) {'''},
+            {islogical: '''\
+\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi);
+\t\tf2py_success = 1;
+\tif (f2py_success) {'''},
+        ],
+        'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname#*/',
+        'need': {l_not(islogical): '#ctype#_from_pyobj'},
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide),
+        '_depend': ''
+    }, {  # Hidden
+        'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
+        'need': typedef_need_dict,
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_hide),
+        '_depend': ''
+    }, {  # Common
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+        '_depend': ''
+    },
+    # Complex scalars
+    {  # Common
+        'decl': '\t#ctype# #varname#;',
+        'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
+        'return': {isintent_out: ',#varname#_capi'},
+        '_check': iscomplex
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        'pyobjfrom': {isintent_inout: """\
+\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
+\t\tif (f2py_success) {"""},
+        'closepyobjfrom': {isintent_inout: "\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
+        '_check': l_and(iscomplex, isintent_nothide)
+    }, {
+        'frompyobj': [{hasinitvalue: '\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'},
+                      {l_and(isoptional, l_not(hasinitvalue))
+                             : '\tif (#varname#_capi != Py_None)'},
+                      '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");'
+                      '\n\tif (f2py_success) {'],
+        'cleanupfrompyobj': '\t}  /*if (f2py_success) of #varname# frompyobj*/',
+        'need': ['#ctype#_from_pyobj'],
+        '_check': l_and(iscomplex, isintent_nothide),
+        '_depend': ''
+    }, {  # Hidden
+        'decl': {isintent_out: '\tPyObject *#varname#_capi = Py_None;'},
+        '_check': l_and(iscomplex, isintent_hide)
+    }, {
+        'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
+        '_check': l_and(iscomplex, isintent_hide),
+        '_depend': ''
+    }, {  # Common
+        'pyobjfrom': {isintent_out: '\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'},
+        'need': ['pyobj_from_#ctype#1'],
+        '_check': iscomplex
+    }, {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
+        '_check': iscomplex,
+        '_depend': ''
+    },
+    # String
+    {  # Common
+        'decl': ['\t#ctype# #varname# = NULL;',
+                 '\tint slen(#varname#);',
+                 '\tPyObject *#varname#_capi = Py_None;'],
+        'callfortran':'#varname#,',
+        'callfortranappend':'slen(#varname#),',
+        'pyobjfrom':{debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+        'return': {isintent_out: ',#varname#'},
+        'need': ['len..'],  # 'STRINGFREE'],
+        '_check':isstring
+    }, {  # Common
+        'frompyobj': """\
+\tslen(#varname#) = #length#;
+\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\");
+\tif (f2py_success) {""",
+        'cleanupfrompyobj': """\
+\t\tSTRINGFREE(#varname#);
+\t}  /*if (f2py_success) of #varname#*/""",
+        'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE'],
+        '_check':isstring,
+        '_depend':''
+    }, {  # Not hidden
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'pyobjfrom': {isintent_inout: '''\
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
+\tif (f2py_success) {'''},
+        'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        '_check': l_and(isstring, isintent_nothide)
+    }, {  # Hidden
+        '_check': l_and(isstring, isintent_hide)
+    }, {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+        '_check': isstring,
+        '_depend': ''
+    },
+    # Array
+    {  # Common
+        'decl': ['\t#ctype# *#varname# = NULL;',
+                 '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
+                 '\tconst int #varname#_Rank = #rank#;',
+                 '\tPyArrayObject *capi_#varname#_tmp = NULL;',
+                 '\tint capi_#varname#_intent = 0;',
+                 ],
+        'callfortran':'#varname#,',
+        'return':{isintent_out: ',capi_#varname#_tmp'},
+        'need': 'len..',
+        '_check': isarray
+    }, {  # intent(overwrite) array
+        'decl': '\tint capi_overwrite_#varname# = 1;',
+        'kwlistxa': '"overwrite_#varname#",',
+        'xaformat': 'i',
+        'keys_xa': ',&capi_overwrite_#varname#',
+        'docsignxa': 'overwrite_#varname#=1,',
+        'docsignxashort': 'overwrite_#varname#,',
+        'docstropt': 'overwrite_#varname# : input int, optional\\n    Default: 1',
+        '_check': l_and(isarray, isintent_overwrite),
+    }, {
+        'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
+        '_check': l_and(isarray, isintent_overwrite),
+        '_depend': '',
+    },
+    {  # intent(copy) array
+        'decl': '\tint capi_overwrite_#varname# = 0;',
+        'kwlistxa': '"overwrite_#varname#",',
+        'xaformat': 'i',
+        'keys_xa': ',&capi_overwrite_#varname#',
+        'docsignxa': 'overwrite_#varname#=0,',
+        'docsignxashort': 'overwrite_#varname#,',
+        'docstropt': 'overwrite_#varname# : input int, optional\\n    Default: 0',
+        '_check': l_and(isarray, isintent_copy),
+    }, {
+        'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
+        '_check': l_and(isarray, isintent_copy),
+        '_depend': '',
+    }, {
+        'need': [{hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
+        '_check': isarray,
+        '_depend': ''
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        '_check': l_and(isarray, isintent_nothide)
+    }, {
+        'frompyobj': ['\t#setdims#;',
+                      '\tcapi_#varname#_intent |= #intent#;',
+                      {isintent_hide:
+                       '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'},
+                      {isintent_nothide:
+                       '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'},
+                      """\
+\tif (capi_#varname#_tmp == NULL) {
+\t\tif (!PyErr_Occurred())
+\t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" );
+\t} else {
+\t\t#varname# = (#ctype# *)(PyArray_DATA(capi_#varname#_tmp));
+""",
+                      {hasinitvalue: [
+                          {isintent_nothide:
+                              '\tif (#varname#_capi == Py_None) {'},
+                          {isintent_hide: '\t{'},
+                          {iscomplexarray: '\t\t#ctype# capi_c;'},
+                          """\
+\t\tint *_i,capi_i=0;
+\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\");
+\t\tif (initforcomb(PyArray_DIMS(capi_#varname#_tmp),PyArray_NDIM(capi_#varname#_tmp),1)) {
+\t\t\twhile ((_i = nextforcomb()))
+\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */
+\t\t} else {
+\t\t\tif (!PyErr_Occurred())
+\t\t\t\tPyErr_SetString(#modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\");
+\t\t\tf2py_success = 0;
+\t\t}
+\t}
+\tif (f2py_success) {"""]},
+                      ],
+        'cleanupfrompyobj': [  # note that this list will be reversed
+            '\t}  /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/',
+            {l_not(l_or(isintent_out, isintent_hide)): """\
+\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) {
+\t\tPy_XDECREF(capi_#varname#_tmp); }"""},
+            {l_and(isintent_hide, l_not(isintent_out))
+                   : """\t\tPy_XDECREF(capi_#varname#_tmp);"""},
+            {hasinitvalue: '\t}  /*if (f2py_success) of #varname# init*/'},
+        ],
+        '_check': isarray,
+        '_depend': ''
+    },
+    # Scalararray
+    {  # Common
+        '_check': l_and(isarray, l_not(iscomplexarray))
+    }, {  # Not hidden
+        '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
+    },
+    # Integer*1 array
+    {'need': '#ctype#',
+     '_check': isint1array,
+     '_depend': ''
+     },
+    # Integer*-1 array
+    {'need': '#ctype#',
+     '_check': isunsigned_chararray,
+     '_depend': ''
+     },
+    # Integer*-2 array
+    {'need': '#ctype#',
+     '_check': isunsigned_shortarray,
+     '_depend': ''
+     },
+    # Integer*-8 array
+    {'need': '#ctype#',
+     '_check': isunsigned_long_longarray,
+     '_depend': ''
+     },
+    # Complexarray
+    {'need': '#ctype#',
+     '_check': iscomplexarray,
+     '_depend': ''
+     },
+    # Stringarray
+    {
+        'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
+        'need': 'string',
+        '_check': isstringarray
+    }
+]
+
+################# Rules for checking ###############
+
+check_rules = [
+    {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'},
+        'need': 'len..'
+    }, {
+        'frompyobj': '\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
+        'cleanupfrompyobj': '\t} /*CHECKSCALAR(#check#)*/',
+        'need': 'CHECKSCALAR',
+        '_check': l_and(isscalar, l_not(iscomplex)),
+        '_break': ''
+    }, {
+        'frompyobj': '\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
+        'cleanupfrompyobj': '\t} /*CHECKSTRING(#check#)*/',
+        'need': 'CHECKSTRING',
+        '_check': isstring,
+        '_break': ''
+    }, {
+        'need': 'CHECKARRAY',
+        'frompyobj': '\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {',
+        'cleanupfrompyobj': '\t} /*CHECKARRAY(#check#)*/',
+        '_check': isarray,
+        '_break': ''
+    }, {
+        'need': 'CHECKGENERIC',
+        'frompyobj': '\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {',
+        'cleanupfrompyobj': '\t} /*CHECKGENERIC(#check#)*/',
+    }
+]
+
+########## Applying the rules. No need to modify what follows #############
+
+#################### Build C/API module #######################
+
+
+def buildmodule(m, um):
+    """
+    Return
+    """
+    global f2py_version, options
+    outmess('\tBuilding module "%s"...\n' % (m['name']))
+    ret = {}
+    mod_rules = defmod_rules[:]
+    vrd = capi_maps.modsign2map(m)
+    rd = dictappend({'f2py_version': f2py_version}, vrd)
+    funcwrappers = []
+    funcwrappers2 = []  # F90 codes
+    for n in m['interfaced']:
+        nb = None
+        for bi in m['body']:
+            if not bi['block'] == 'interface':
+                errmess('buildmodule: Expected interface block. Skipping.\n')
+                continue
+            for b in bi['body']:
+                if b['name'] == n:
+                    nb = b
+                    break
+
+        if not nb:
+            errmess(
+                'buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n' % (n))
+            continue
+        nb_list = [nb]
+        if 'entry' in nb:
+            for k, a in nb['entry'].items():
+                nb1 = copy.deepcopy(nb)
+                del nb1['entry']
+                nb1['name'] = k
+                nb1['args'] = a
+                nb_list.append(nb1)
+        for nb in nb_list:
+            api, wrap = buildapi(nb)
+            if wrap:
+                if ismoduleroutine(nb):
+                    funcwrappers2.append(wrap)
+                else:
+                    funcwrappers.append(wrap)
+            ar = applyrules(api, vrd)
+            rd = dictappend(rd, ar)
+
+    # Construct COMMON block support
+    cr, wrap = common_rules.buildhooks(m)
+    if wrap:
+        funcwrappers.append(wrap)
+    ar = applyrules(cr, vrd)
+    rd = dictappend(rd, ar)
+
+    # Construct F90 module support
+    mr, wrap = f90mod_rules.buildhooks(m)
+    if wrap:
+        funcwrappers2.append(wrap)
+    ar = applyrules(mr, vrd)
+    rd = dictappend(rd, ar)
+
+    for u in um:
+        ar = use_rules.buildusevars(u, m['use'][u['name']])
+        rd = dictappend(rd, ar)
+
+    needs = cfuncs.get_needs()
+    code = {}
+    for n in needs.keys():
+        code[n] = []
+        for k in needs[n]:
+            c = ''
+            if k in cfuncs.includes0:
+                c = cfuncs.includes0[k]
+            elif k in cfuncs.includes:
+                c = cfuncs.includes[k]
+            elif k in cfuncs.userincludes:
+                c = cfuncs.userincludes[k]
+            elif k in cfuncs.typedefs:
+                c = cfuncs.typedefs[k]
+            elif k in cfuncs.typedefs_generated:
+                c = cfuncs.typedefs_generated[k]
+            elif k in cfuncs.cppmacros:
+                c = cfuncs.cppmacros[k]
+            elif k in cfuncs.cfuncs:
+                c = cfuncs.cfuncs[k]
+            elif k in cfuncs.callbacks:
+                c = cfuncs.callbacks[k]
+            elif k in cfuncs.f90modhooks:
+                c = cfuncs.f90modhooks[k]
+            elif k in cfuncs.commonhooks:
+                c = cfuncs.commonhooks[k]
+            else:
+                errmess('buildmodule: unknown need %s.\n' % (repr(k)))
+                continue
+            code[n].append(c)
+    mod_rules.append(code)
+    for r in mod_rules:
+        if ('_check' in r and r['_check'](m)) or ('_check' not in r):
+            ar = applyrules(r, vrd, m)
+            rd = dictappend(rd, ar)
+    ar = applyrules(module_rules, rd)
+
+    fn = os.path.join(options['buildpath'], vrd['coutput'])
+    ret['csrc'] = fn
+    f = open(fn, 'w')
+    f.write(ar['modulebody'].replace('\t', 2 * ' '))
+    f.close()
+    outmess('\tWrote C/API module "%s" to file "%s"\n' % (m['name'], fn))
+
+    if options['dorestdoc']:
+        fn = os.path.join(
+            options['buildpath'], vrd['modulename'] + 'module.rest')
+        f = open(fn, 'w')
+        f.write('.. -*- rest -*-\n')
+        f.write('\n'.join(ar['restdoc']))
+        f.close()
+        outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n' %
+                (options['buildpath'], vrd['modulename']))
+    if options['dolatexdoc']:
+        fn = os.path.join(
+            options['buildpath'], vrd['modulename'] + 'module.tex')
+        ret['ltx'] = fn
+        f = open(fn, 'w')
+        f.write(
+            '%% This file is auto-generated with f2py (version:%s)\n' % (f2py_version))
+        if 'shortlatex' not in options:
+            f.write(
+                '\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n')
+        f.write('\n'.join(ar['latexdoc']))
+        if 'shortlatex' not in options:
+            f.write('\\end{document}')
+        f.close()
+        outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n' %
+                (options['buildpath'], vrd['modulename']))
+    if funcwrappers:
+        wn = os.path.join(options['buildpath'], vrd['f2py_wrapper_output'])
+        ret['fsrc'] = wn
+        f = open(wn, 'w')
+        f.write('C     -*- fortran -*-\n')
+        f.write(
+            'C     This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
+        f.write(
+            'C     It contains Fortran 77 wrappers to fortran functions.\n')
+        lines = []
+        for l in ('\n\n'.join(funcwrappers) + '\n').split('\n'):
+            if l and l[0] == ' ':
+                while len(l) >= 66:
+                    lines.append(l[:66] + '\n     &')
+                    l = l[66:]
+                lines.append(l + '\n')
+            else:
+                lines.append(l + '\n')
+        lines = ''.join(lines).replace('\n     &\n', '\n')
+        f.write(lines)
+        f.close()
+        outmess('\tFortran 77 wrappers are saved to "%s"\n' % (wn))
+    if funcwrappers2:
+        wn = os.path.join(
+            options['buildpath'], '%s-f2pywrappers2.f90' % (vrd['modulename']))
+        ret['fsrc'] = wn
+        f = open(wn, 'w')
+        f.write('!     -*- f90 -*-\n')
+        f.write(
+            '!     This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
+        f.write(
+            '!     It contains Fortran 90 wrappers to fortran functions.\n')
+        lines = []
+        for l in ('\n\n'.join(funcwrappers2) + '\n').split('\n'):
+            if len(l) > 72 and l[0] == ' ':
+                lines.append(l[:72] + '&\n     &')
+                l = l[72:]
+                while len(l) > 66:
+                    lines.append(l[:66] + '&\n     &')
+                    l = l[66:]
+                lines.append(l + '\n')
+            else:
+                lines.append(l + '\n')
+        lines = ''.join(lines).replace('\n     &\n', '\n')
+        f.write(lines)
+        f.close()
+        outmess('\tFortran 90 wrappers are saved to "%s"\n' % (wn))
+    return ret
+
+################## Build C/API function #############
+
+stnd = {1: 'st', 2: 'nd', 3: 'rd', 4: 'th', 5: 'th',
+        6: 'th', 7: 'th', 8: 'th', 9: 'th', 0: 'th'}
+
+
+def buildapi(rout):
+    rout, wrap = func2subr.assubr(rout)
+    args, depargs = getargs2(rout)
+    capi_maps.depargs = depargs
+    var = rout['vars']
+
+    if ismoduleroutine(rout):
+        outmess('\t\t\tConstructing wrapper function "%s.%s"...\n' %
+                (rout['modulename'], rout['name']))
+    else:
+        outmess('\t\tConstructing wrapper function "%s"...\n' % (rout['name']))
+    # Routine
+    vrd = capi_maps.routsign2map(rout)
+    rd = dictappend({}, vrd)
+    for r in rout_rules:
+        if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
+            ar = applyrules(r, vrd, rout)
+            rd = dictappend(rd, ar)
+
+    # Args
+    nth, nthk = 0, 0
+    savevrd = {}
+    for a in args:
+        vrd = capi_maps.sign2map(a, var[a])
+        if isintent_aux(var[a]):
+            _rules = aux_rules
+        else:
+            _rules = arg_rules
+            if not isintent_hide(var[a]):
+                if not isoptional(var[a]):
+                    nth = nth + 1
+                    vrd['nth'] = repr(nth) + stnd[nth % 10] + ' argument'
+                else:
+                    nthk = nthk + 1
+                    vrd['nth'] = repr(nthk) + stnd[nthk % 10] + ' keyword'
+            else:
+                vrd['nth'] = 'hidden'
+        savevrd[a] = vrd
+        for r in _rules:
+            if '_depend' in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in depargs:
+        if isintent_aux(var[a]):
+            _rules = aux_rules
+        else:
+            _rules = arg_rules
+        vrd = savevrd[a]
+        for r in _rules:
+            if '_depend' not in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+        if 'check' in var[a]:
+            for c in var[a]['check']:
+                vrd['check'] = c
+                ar = applyrules(check_rules, vrd, var[a])
+                rd = dictappend(rd, ar)
+    if isinstance(rd['cleanupfrompyobj'], list):
+        rd['cleanupfrompyobj'].reverse()
+    if isinstance(rd['closepyobjfrom'], list):
+        rd['closepyobjfrom'].reverse()
+    rd['docsignature'] = stripcomma(replace('#docsign##docsignopt##docsignxa#',
+                                            {'docsign': rd['docsign'],
+                                             'docsignopt': rd['docsignopt'],
+                                             'docsignxa': rd['docsignxa']}))
+    optargs = stripcomma(replace('#docsignopt##docsignxa#',
+                                 {'docsignxa': rd['docsignxashort'],
+                                  'docsignopt': rd['docsignoptshort']}
+                                 ))
+    if optargs == '':
+        rd['docsignatureshort'] = stripcomma(
+            replace('#docsign#', {'docsign': rd['docsign']}))
+    else:
+        rd['docsignatureshort'] = replace('#docsign#[#docsignopt#]',
+                                          {'docsign': rd['docsign'],
+                                           'docsignopt': optargs,
+                                           })
+    rd['latexdocsignatureshort'] = rd['docsignatureshort'].replace('_', '\\_')
+    rd['latexdocsignatureshort'] = rd[
+        'latexdocsignatureshort'].replace(',', ', ')
+    cfs = stripcomma(replace('#callfortran##callfortranappend#', {
+                     'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
+    if len(rd['callfortranappend']) > 1:
+        rd['callcompaqfortran'] = stripcomma(replace('#callfortran# 0,#callfortranappend#', {
+                                             'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
+    else:
+        rd['callcompaqfortran'] = cfs
+    rd['callfortran'] = cfs
+    if isinstance(rd['docreturn'], list):
+        rd['docreturn'] = stripcomma(
+            replace('#docreturn#', {'docreturn': rd['docreturn']})) + ' = '
+    rd['docstrsigns'] = []
+    rd['latexdocstrsigns'] = []
+    for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
+        if k in rd and isinstance(rd[k], list):
+            rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
+        k = 'latex' + k
+        if k in rd and isinstance(rd[k], list):
+            rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
+                ['\\begin{description}'] + rd[k][1:] +\
+                ['\\end{description}']
+
+    # Workaround for Python 2.6, 2.6.1 bug: http://bugs.python.org/issue4720
+    if rd['keyformat'] or rd['xaformat']:
+        argformat = rd['argformat']
+        if isinstance(argformat, list):
+            argformat.append('|')
+        else:
+            assert isinstance(argformat, str), repr(
+                (argformat, type(argformat)))
+            rd['argformat'] += '|'
+
+    ar = applyrules(routine_rules, rd)
+    if ismoduleroutine(rout):
+        outmess('\t\t\t  %s\n' % (ar['docshort']))
+    else:
+        outmess('\t\t  %s\n' % (ar['docshort']))
+    return ar, wrap
+
+
+#################### EOF rules.py #######################
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/setup.py
new file mode 100644
index 0000000000..fb68ed5a8a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/setup.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python2
+"""
+setup.py for installing F2PY
+
+Usage:
+   python setup.py install
+
+Copyright 2001-2005 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Revision: 1.32 $
+$Date: 2005/01/30 17:22:14 $
+Pearu Peterson
+
+"""
+from __future__ import division, print_function
+
+__version__ = "$Id: setup.py,v 1.32 2005/01/30 17:22:14 pearu Exp $"
+
+import os
+import sys
+from distutils.dep_util import newer
+from numpy.distutils import log
+from numpy.distutils.core import setup
+from numpy.distutils.misc_util import Configuration
+
+from __version__ import version
+
+
+def _get_f2py_shebang():
+    """ Return shebang line for f2py script
+
+    If we are building a binary distribution format, then the shebang line
+    should be ``#!python`` rather than ``#!`` followed by the contents of
+    ``sys.executable``.
+    """
+    if set(('bdist_wheel', 'bdist_egg', 'bdist_wininst',
+            'bdist_rpm')).intersection(sys.argv):
+        return '#!python'
+    return '#!' + sys.executable
+
+
+def configuration(parent_package='', top_path=None):
+    config = Configuration('f2py', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    config.add_data_files('src/fortranobject.c',
+                          'src/fortranobject.h',
+                          )
+
+    config.make_svn_version_py()
+
+    def generate_f2py_py(build_dir):
+        f2py_exe = 'f2py' + os.path.basename(sys.executable)[6:]
+        if f2py_exe[-4:] == '.exe':
+            f2py_exe = f2py_exe[:-4] + '.py'
+        if 'bdist_wininst' in sys.argv and f2py_exe[-3:] != '.py':
+            f2py_exe = f2py_exe + '.py'
+        target = os.path.join(build_dir, f2py_exe)
+        if newer(__file__, target):
+            log.info('Creating %s', target)
+            f = open(target, 'w')
+            f.write(_get_f2py_shebang() + '\n')
+            mainloc = os.path.join(os.path.dirname(__file__), "__main__.py")
+            with open(mainloc) as mf:
+                f.write(mf.read())
+            f.close()
+        return target
+
+    config.add_scripts(generate_f2py_py)
+
+    log.info('F2PY Version %s', config.get_version())
+
+    return config
+
+if __name__ == "__main__":
+
+    config = configuration(top_path='')
+    print('F2PY Version', version)
+    config = config.todict()
+
+    config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\
+                             "/F2PY-2-latest.tar.gz"
+    config['classifiers'] = [
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'Intended Audience :: Science/Research',
+        'License :: OSI Approved :: NumPy License',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Programming Language :: C',
+        'Programming Language :: Fortran',
+        'Programming Language :: Python',
+        'Topic :: Scientific/Engineering',
+        'Topic :: Software Development :: Code Generators',
+    ]
+    setup(version=version,
+          description="F2PY - Fortran to Python Interface Generaton",
+          author="Pearu Peterson",
+          author_email="pearu@cens.ioc.ee",
+          maintainer="Pearu Peterson",
+          maintainer_email="pearu@cens.ioc.ee",
+          license="BSD",
+          platforms="Unix, Windows (mingw|cygwin), Mac OSX",
+          long_description="""\
+The Fortran to Python Interface Generator, or F2PY for short, is a
+command line tool (f2py) for generating Python C/API modules for
+wrapping Fortran 77/90/95 subroutines, accessing common blocks from
+Python, and calling Python functions from Fortran (call-backs).
+Interfacing subroutines/data from Fortran 90/95 modules is supported.""",
+          url="http://cens.ioc.ee/projects/f2py2e/",
+          keywords=['Fortran', 'f2py'],
+          **config)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
new file mode 100644
index 0000000000..9024dd5b34
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
@@ -0,0 +1,1037 @@
+#define FORTRANOBJECT_C
+#include "fortranobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+  This file implements: FortranObject, array_from_pyobj, copy_ND_array
+
+  Author: Pearu Peterson <pearu@cens.ioc.ee>
+  $Revision: 1.52 $
+  $Date: 2005/07/11 07:44:20 $
+*/
+
+int
+F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj)
+{
+    if (obj==NULL) {
+        fprintf(stderr, "Error loading %s\n", name);
+        if (PyErr_Occurred()) {
+            PyErr_Print();
+            PyErr_Clear();
+        }
+        return -1;
+    }
+    return PyDict_SetItemString(dict, name, obj);
+}
+
+/************************* FortranObject *******************************/
+
+typedef PyObject *(*fortranfunc)(PyObject *,PyObject *,PyObject *,void *);
+
+PyObject *
+PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) {
+    int i;
+    PyFortranObject *fp = NULL;
+    PyObject *v = NULL;
+    if (init!=NULL)                           /* Initialize F90 module objects */
+        (*(init))();
+    if ((fp = PyObject_New(PyFortranObject, &PyFortran_Type))==NULL) return NULL;
+    if ((fp->dict = PyDict_New())==NULL) return NULL;
+    fp->len = 0;
+    while (defs[fp->len].name != NULL) fp->len++;
+    if (fp->len == 0) goto fail;
+    fp->defs = defs;
+    for (i=0;i<fp->len;i++)
+        if (fp->defs[i].rank == -1) {                      /* Is Fortran routine */
+            v = PyFortranObject_NewAsAttr(&(fp->defs[i]));
+            if (v==NULL) return NULL;
+            PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+        } else
+            if ((fp->defs[i].data)!=NULL) { /* Is Fortran variable or array (not allocatable) */
+                if (fp->defs[i].type == NPY_STRING) {
+                    int n = fp->defs[i].rank-1;
+                    v = PyArray_New(&PyArray_Type, n, fp->defs[i].dims.d,
+                                    NPY_STRING, NULL, fp->defs[i].data, fp->defs[i].dims.d[n],
+                                    NPY_ARRAY_FARRAY, NULL);
+                }
+                else {
+                    v = PyArray_New(&PyArray_Type, fp->defs[i].rank, fp->defs[i].dims.d,
+                                    fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY,
+                                    NULL);
+                }
+                if (v==NULL) return NULL;
+                PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+            }
+    Py_XDECREF(v);
+    return (PyObject *)fp;
+ fail:
+    Py_XDECREF(v);
+    return NULL;
+}
+
+PyObject *
+PyFortranObject_NewAsAttr(FortranDataDef* defs) { /* used for calling F90 module routines */
+    PyFortranObject *fp = NULL;
+    fp = PyObject_New(PyFortranObject, &PyFortran_Type);
+    if (fp == NULL) return NULL;
+    if ((fp->dict = PyDict_New())==NULL) return NULL;
+    fp->len = 1;
+    fp->defs = defs;
+    return (PyObject *)fp;
+}
+
+/* Fortran methods */
+
+static void
+fortran_dealloc(PyFortranObject *fp) {
+    Py_XDECREF(fp->dict);
+    PyMem_Del(fp);
+}
+
+
+#if PY_VERSION_HEX >= 0x03000000
+#else
+static PyMethodDef fortran_methods[] = {
+    {NULL,          NULL}           /* sentinel */
+};
+#endif
+
+
+/* Returns number of bytes consumed from buf, or -1 on error. */
+static Py_ssize_t
+format_def(char *buf, Py_ssize_t size, FortranDataDef def)
+{
+    char *p = buf;
+    int i, n;
+
+    n = PyOS_snprintf(p, size, "array(%" NPY_INTP_FMT, def.dims.d[0]);
+    if (n < 0 || n >= size) {
+        return -1;
+    }
+    p += n;
+    size -= n;
+
+    for (i = 1; i < def.rank; i++) {
+        n = PyOS_snprintf(p, size, ",%" NPY_INTP_FMT, def.dims.d[i]);
+        if (n < 0 || n >= size) {
+            return -1;
+        }
+        p += n;
+        size -= n;
+    }
+
+    if (size <= 0) {
+        return -1;
+    }
+
+    p[size] = ')';
+    p++;
+    size--;
+
+    if (def.data == NULL) {
+        static const char notalloc[] = ", not allocated";
+        if (size < sizeof(notalloc)) {
+            return -1;
+        }
+        memcpy(p, notalloc, sizeof(notalloc));
+    }
+
+    return p - buf;
+}
+
+static PyObject *
+fortran_doc(FortranDataDef def)
+{
+    char *buf, *p;
+    PyObject *s = NULL;
+    Py_ssize_t n, origsize, size = 100;
+
+    if (def.doc != NULL) {
+        size += strlen(def.doc);
+    }
+    origsize = size;
+    buf = p = (char *)PyMem_Malloc(size);
+    if (buf == NULL) {
+        return PyErr_NoMemory();
+    }
+
+    if (def.rank == -1) {
+        if (def.doc) {
+            n = strlen(def.doc);
+            if (n > size) {
+                goto fail;
+            }
+            memcpy(p, def.doc, n);
+            p += n;
+            size -= n;
+        }
+        else {
+            n = PyOS_snprintf(p, size, "%s - no docs available", def.name);
+            if (n < 0 || n >= size) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+    }
+    else {
+        PyArray_Descr *d = PyArray_DescrFromType(def.type);
+        n = PyOS_snprintf(p, size, "'%c'-", d->type);
+        Py_DECREF(d);
+        if (n < 0 || n >= size) {
+            goto fail;
+        }
+        p += n;
+        size -= n;
+
+        if (def.data == NULL) {
+            n = format_def(p, size, def) == -1;
+            if (n < 0) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+        else if (def.rank > 0) {
+            n = format_def(p, size, def);
+            if (n < 0) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+        else {
+            n = strlen("scalar");
+            if (size < n) {
+                goto fail;
+            }
+            memcpy(p, "scalar", n);
+            p += n;
+            size -= n;
+        }
+    }
+    if (size <= 1) {
+        goto fail;
+    }
+    *p++ = '\n';
+    size--;
+
+    /* p now points one beyond the last character of the string in buf */
+#if PY_VERSION_HEX >= 0x03000000
+    s = PyUnicode_FromStringAndSize(buf, p - buf);
+#else
+    s = PyString_FromStringAndSize(buf, p - buf);
+#endif
+
+    PyMem_Free(buf);
+    return s;
+
+ fail:
+    fprintf(stderr, "fortranobject.c: fortran_doc: len(p)=%zd>%zd=size:"
+                    " too long docstring required, increase size\n",
+            p - buf, origsize);
+    PyMem_Free(buf);
+    return NULL;
+}
+
+static FortranDataDef *save_def; /* save pointer of an allocatable array */
+static void set_data(char *d,npy_intp *f) {  /* callback from Fortran */
+    if (*f)                               /* In fortran f=allocated(d) */
+        save_def->data = d;
+    else
+        save_def->data = NULL;
+    /* printf("set_data: d=%p,f=%d\n",d,*f); */
+}
+
+static PyObject *
+fortran_getattr(PyFortranObject *fp, char *name) {
+    int i,j,k,flag;
+    if (fp->dict != NULL) {
+        PyObject *v = PyDict_GetItemString(fp->dict, name);
+        if (v != NULL) {
+            Py_INCREF(v);
+            return v;
+        }
+    }
+    for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++);
+    if (j==0)
+        if (fp->defs[i].rank!=-1) {                   /* F90 allocatable array */
+            if (fp->defs[i].func==NULL) return NULL;
+            for(k=0;k<fp->defs[i].rank;++k)
+                fp->defs[i].dims.d[k]=-1;
+            save_def = &fp->defs[i];
+            (*(fp->defs[i].func))(&fp->defs[i].rank,fp->defs[i].dims.d,set_data,&flag);
+            if (flag==2)
+                k = fp->defs[i].rank + 1;
+            else
+                k = fp->defs[i].rank;
+            if (fp->defs[i].data !=NULL) {              /* array is allocated */
+                PyObject *v = PyArray_New(&PyArray_Type, k, fp->defs[i].dims.d,
+                                          fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY,
+                                          NULL);
+                if (v==NULL) return NULL;
+                /* Py_INCREF(v); */
+                return v;
+            } else {                                    /* array is not allocated */
+                Py_RETURN_NONE;
+            }
+        }
+    if (strcmp(name,"__dict__")==0) {
+        Py_INCREF(fp->dict);
+        return fp->dict;
+    }
+    if (strcmp(name,"__doc__")==0) {
+#if PY_VERSION_HEX >= 0x03000000
+        PyObject *s = PyUnicode_FromString(""), *s2, *s3;
+        for (i=0;i<fp->len;i++) {
+            s2 = fortran_doc(fp->defs[i]);
+            s3 = PyUnicode_Concat(s, s2);
+            Py_DECREF(s2);
+            Py_DECREF(s);
+            s = s3;
+        }
+#else
+        PyObject *s = PyString_FromString("");
+        for (i=0;i<fp->len;i++)
+            PyString_ConcatAndDel(&s,fortran_doc(fp->defs[i]));
+#endif
+        if (PyDict_SetItemString(fp->dict, name, s))
+            return NULL;
+        return s;
+    }
+    if ((strcmp(name,"_cpointer")==0) && (fp->len==1)) {
+        PyObject *cobj = F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data),NULL);
+        if (PyDict_SetItemString(fp->dict, name, cobj))
+            return NULL;
+        return cobj;
+    }
+#if PY_VERSION_HEX >= 0x03000000
+    if (1) {
+        PyObject *str, *ret;
+        str = PyUnicode_FromString(name);
+        ret = PyObject_GenericGetAttr((PyObject *)fp, str);
+        Py_DECREF(str);
+        return ret;
+    }
+#else
+    return Py_FindMethod(fortran_methods, (PyObject *)fp, name);
+#endif
+}
+
+static int
+fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) {
+    int i,j,flag;
+    PyArrayObject *arr = NULL;
+    for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++);
+    if (j==0) {
+        if (fp->defs[i].rank==-1) {
+            PyErr_SetString(PyExc_AttributeError,"over-writing fortran routine");
+            return -1;
+        }
+        if (fp->defs[i].func!=NULL) { /* is allocatable array */
+            npy_intp dims[F2PY_MAX_DIMS];
+            int k;
+            save_def = &fp->defs[i];
+            if (v!=Py_None) {     /* set new value (reallocate if needed --
+                                     see f2py generated code for more
+                                     details ) */
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1;
+                if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL)
+                    return -1;
+                (*(fp->defs[i].func))(&fp->defs[i].rank,PyArray_DIMS(arr),set_data,&flag);
+            } else {             /* deallocate */
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=0;
+                (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag);
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1;
+            }
+            memcpy(fp->defs[i].dims.d,dims,fp->defs[i].rank*sizeof(npy_intp));
+        } else {                     /* not allocatable array */
+            if ((arr = array_from_pyobj(fp->defs[i].type,fp->defs[i].dims.d,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL)
+                return -1;
+        }
+        if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */
+            npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,PyArray_NDIM(arr));
+            if (s==-1)
+                s = PyArray_MultiplyList(PyArray_DIMS(arr),PyArray_NDIM(arr));
+            if (s<0 ||
+                (memcpy(fp->defs[i].data,PyArray_DATA(arr),s*PyArray_ITEMSIZE(arr)))==NULL) {
+                if ((PyObject*)arr!=v) {
+                    Py_DECREF(arr);
+                }
+                return -1;
+            }
+            if ((PyObject*)arr!=v) {
+                Py_DECREF(arr);
+            }
+        } else return (fp->defs[i].func==NULL?-1:0);
+        return 0; /* succesful */
+    }
+    if (fp->dict == NULL) {
+        fp->dict = PyDict_New();
+        if (fp->dict == NULL)
+            return -1;
+    }
+    if (v == NULL) {
+        int rv = PyDict_DelItemString(fp->dict, name);
+        if (rv < 0)
+            PyErr_SetString(PyExc_AttributeError,"delete non-existing fortran attribute");
+        return rv;
+    }
+    else
+        return PyDict_SetItemString(fp->dict, name, v);
+}
+
+static PyObject*
+fortran_call(PyFortranObject *fp, PyObject *arg, PyObject *kw) {
+    int i = 0;
+    /*  printf("fortran call
+        name=%s,func=%p,data=%p,%p\n",fp->defs[i].name,
+        fp->defs[i].func,fp->defs[i].data,&fp->defs[i].data); */
+    if (fp->defs[i].rank==-1) {/* is Fortran routine */
+        if (fp->defs[i].func==NULL) {
+            PyErr_Format(PyExc_RuntimeError, "no function to call");
+            return NULL;
+        }
+        else if (fp->defs[i].data==NULL)
+            /* dummy routine */
+            return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,NULL);
+        else
+            return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,
+                                                        (void *)fp->defs[i].data);
+    }
+    PyErr_Format(PyExc_TypeError, "this fortran object is not callable");
+    return NULL;
+}
+
+static PyObject *
+fortran_repr(PyFortranObject *fp)
+{
+    PyObject *name = NULL, *repr = NULL;
+    name = PyObject_GetAttrString((PyObject *)fp, "__name__");
+    PyErr_Clear();
+#if PY_VERSION_HEX >= 0x03000000
+    if (name != NULL && PyUnicode_Check(name)) {
+        repr = PyUnicode_FromFormat("<fortran %U>", name);
+    }
+    else {
+        repr = PyUnicode_FromString("<fortran object>");
+    }
+#else
+    if (name != NULL && PyString_Check(name)) {
+        repr = PyString_FromFormat("<fortran %s>", PyString_AsString(name));
+    }
+    else {
+        repr = PyString_FromString("<fortran object>");
+    }
+#endif
+    Py_XDECREF(name);
+    return repr;
+}
+
+
+PyTypeObject PyFortran_Type = {
+#if PY_VERSION_HEX >= 0x03000000
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
+    PyObject_HEAD_INIT(0)
+    0,                    /*ob_size*/
+#endif
+    "fortran",                    /*tp_name*/
+    sizeof(PyFortranObject),      /*tp_basicsize*/
+    0,                    /*tp_itemsize*/
+    /* methods */
+    (destructor)fortran_dealloc, /*tp_dealloc*/
+    0,                    /*tp_print*/
+    (getattrfunc)fortran_getattr, /*tp_getattr*/
+    (setattrfunc)fortran_setattr, /*tp_setattr*/
+    0,                    /*tp_compare/tp_reserved*/
+    (reprfunc)fortran_repr, /*tp_repr*/
+    0,                    /*tp_as_number*/
+    0,                    /*tp_as_sequence*/
+    0,                    /*tp_as_mapping*/
+    0,                    /*tp_hash*/
+    (ternaryfunc)fortran_call,                    /*tp_call*/
+};
+
+/************************* f2py_report_atexit *******************************/
+
+#ifdef F2PY_REPORT_ATEXIT
+static int passed_time = 0;
+static int passed_counter = 0;
+static int passed_call_time = 0;
+static struct timeb start_time;
+static struct timeb stop_time;
+static struct timeb start_call_time;
+static struct timeb stop_call_time;
+static int cb_passed_time = 0;
+static int cb_passed_counter = 0;
+static int cb_passed_call_time = 0;
+static struct timeb cb_start_time;
+static struct timeb cb_stop_time;
+static struct timeb cb_start_call_time;
+static struct timeb cb_stop_call_time;
+
+extern void f2py_start_clock(void) { ftime(&start_time); }
+extern
+void f2py_start_call_clock(void) {
+    f2py_stop_clock();
+    ftime(&start_call_time);
+}
+extern
+void f2py_stop_clock(void) {
+    ftime(&stop_time);
+    passed_time += 1000*(stop_time.time - start_time.time);
+    passed_time += stop_time.millitm - start_time.millitm;
+}
+extern
+void f2py_stop_call_clock(void) {
+    ftime(&stop_call_time);
+    passed_call_time += 1000*(stop_call_time.time - start_call_time.time);
+    passed_call_time += stop_call_time.millitm - start_call_time.millitm;
+    passed_counter += 1;
+    f2py_start_clock();
+}
+
+extern void f2py_cb_start_clock(void) { ftime(&cb_start_time); }
+extern
+void f2py_cb_start_call_clock(void) {
+    f2py_cb_stop_clock();
+    ftime(&cb_start_call_time);
+}
+extern
+void f2py_cb_stop_clock(void) {
+    ftime(&cb_stop_time);
+    cb_passed_time += 1000*(cb_stop_time.time - cb_start_time.time);
+    cb_passed_time += cb_stop_time.millitm - cb_start_time.millitm;
+}
+extern
+void f2py_cb_stop_call_clock(void) {
+    ftime(&cb_stop_call_time);
+    cb_passed_call_time += 1000*(cb_stop_call_time.time - cb_start_call_time.time);
+    cb_passed_call_time += cb_stop_call_time.millitm - cb_start_call_time.millitm;
+    cb_passed_counter += 1;
+    f2py_cb_start_clock();
+}
+
+static int f2py_report_on_exit_been_here = 0;
+extern
+void f2py_report_on_exit(int exit_flag,void *name) {
+    if (f2py_report_on_exit_been_here) {
+        fprintf(stderr,"             %s\n",(char*)name);
+        return;
+    }
+    f2py_report_on_exit_been_here = 1;
+    fprintf(stderr,"                      /-----------------------\\\n");
+    fprintf(stderr,"                     < F2PY performance report >\n");
+    fprintf(stderr,"                      \\-----------------------/\n");
+    fprintf(stderr,"Overall time spent in ...\n");
+    fprintf(stderr,"(a) wrapped (Fortran/C) functions           : %8d msec\n",
+            passed_call_time);
+    fprintf(stderr,"(b) f2py interface,           %6d calls  : %8d msec\n",
+            passed_counter,passed_time);
+    fprintf(stderr,"(c) call-back (Python) functions            : %8d msec\n",
+            cb_passed_call_time);
+    fprintf(stderr,"(d) f2py call-back interface, %6d calls  : %8d msec\n",
+            cb_passed_counter,cb_passed_time);
+
+    fprintf(stderr,"(e) wrapped (Fortran/C) functions (acctual) : %8d msec\n\n",
+            passed_call_time-cb_passed_call_time-cb_passed_time);
+    fprintf(stderr,"Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.\n");
+    fprintf(stderr,"Exit status: %d\n",exit_flag);
+    fprintf(stderr,"Modules    : %s\n",(char*)name);
+}
+#endif
+
+/********************** report on array copy ****************************/
+
+#ifdef F2PY_REPORT_ON_ARRAY_COPY
+static void f2py_report_on_array_copy(PyArrayObject* arr) {
+    const npy_intp arr_size = PyArray_Size((PyObject *)arr);
+    if (arr_size>F2PY_REPORT_ON_ARRAY_COPY) {
+        fprintf(stderr,"copied an array: size=%ld, elsize=%"NPY_INTP_FMT"\n",
+                arr_size, (npy_intp)PyArray_ITEMSIZE(arr));
+    }
+}
+static void f2py_report_on_array_copy_fromany(void) {
+    fprintf(stderr,"created an array from object\n");
+}
+
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR f2py_report_on_array_copy((PyArrayObject *)arr)
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY f2py_report_on_array_copy_fromany()
+#else
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY
+#endif
+
+
+/************************* array_from_obj *******************************/
+
+/*
+ * File: array_from_pyobj.c
+ *
+ * Description:
+ * ------------
+ * Provides array_from_pyobj function that returns a contigious array
+ * object with the given dimensions and required storage order, either
+ * in row-major (C) or column-major (Fortran) order. The function
+ * array_from_pyobj is very flexible about its Python object argument
+ * that can be any number, list, tuple, or array.
+ *
+ * array_from_pyobj is used in f2py generated Python extension
+ * modules.
+ *
+ * Author: Pearu Peterson <pearu@cens.ioc.ee>
+ * Created: 13-16 January 2002
+ * $Id: fortranobject.c,v 1.52 2005/07/11 07:44:20 pearu Exp $
+ */
+
+static int
+count_nonpos(const int rank,
+             const npy_intp *dims) {
+    int i=0,r=0;
+    while (i<rank) {
+        if (dims[i] <= 0) ++r;
+        ++i;
+    }
+    return r;
+}
+
+static int check_and_fix_dimensions(const PyArrayObject* arr,
+                                    const int rank,
+                                    npy_intp *dims);
+
+#ifdef DEBUG_COPY_ND_ARRAY
+void dump_dims(int rank, npy_intp* dims) {
+    int i;
+    printf("[");
+    for(i=0;i<rank;++i) {
+        printf("%3" NPY_INTP_FMT, dims[i]);
+    }
+    printf("]\n");
+}
+void dump_attrs(const PyArrayObject* obj) {
+    const PyArrayObject_fields *arr = (const PyArrayObject_fields*) obj;
+    int rank = PyArray_NDIM(arr);
+    npy_intp size = PyArray_Size((PyObject *)arr);
+    printf("\trank = %d, flags = %d, size = %" NPY_INTP_FMT  "\n",
+           rank,arr->flags,size);
+    printf("\tstrides = ");
+    dump_dims(rank,arr->strides);
+    printf("\tdimensions = ");
+    dump_dims(rank,arr->dimensions);
+}
+#endif
+
+#define SWAPTYPE(a,b,t) {t c; c = (a); (a) = (b); (b) = c; }
+
+static int swap_arrays(PyArrayObject* obj1, PyArrayObject* obj2) {
+    PyArrayObject_fields *arr1 = (PyArrayObject_fields*) obj1,
+                         *arr2 = (PyArrayObject_fields*) obj2;
+    SWAPTYPE(arr1->data,arr2->data,char*);
+    SWAPTYPE(arr1->nd,arr2->nd,int);
+    SWAPTYPE(arr1->dimensions,arr2->dimensions,npy_intp*);
+    SWAPTYPE(arr1->strides,arr2->strides,npy_intp*);
+    SWAPTYPE(arr1->base,arr2->base,PyObject*);
+    SWAPTYPE(arr1->descr,arr2->descr,PyArray_Descr*);
+    SWAPTYPE(arr1->flags,arr2->flags,int);
+    /* SWAPTYPE(arr1->weakreflist,arr2->weakreflist,PyObject*); */
+    return 0;
+}
+
+#define ARRAY_ISCOMPATIBLE(arr,type_num)                                \
+    (  (PyArray_ISINTEGER(arr) && PyTypeNum_ISINTEGER(type_num))        \
+       ||(PyArray_ISFLOAT(arr) && PyTypeNum_ISFLOAT(type_num))          \
+       ||(PyArray_ISCOMPLEX(arr) && PyTypeNum_ISCOMPLEX(type_num))      \
+       ||(PyArray_ISBOOL(arr) && PyTypeNum_ISBOOL(type_num))            \
+       )
+
+extern
+PyArrayObject* array_from_pyobj(const int type_num,
+                                npy_intp *dims,
+                                const int rank,
+                                const int intent,
+                                PyObject *obj) {
+    /* Note about reference counting
+       -----------------------------
+       If the caller returns the array to Python, it must be done with
+       Py_BuildValue("N",arr).
+       Otherwise, if obj!=arr then the caller must call Py_DECREF(arr).
+
+       Note on intent(cache,out,..)
+       ---------------------
+       Don't expect correct data when returning intent(cache) array.
+
+    */
+    char mess[200];
+    PyArrayObject *arr = NULL;
+    PyArray_Descr *descr;
+    char typechar;
+    int elsize;
+
+    if ((intent & F2PY_INTENT_HIDE)
+        || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None))
+        || ((intent & F2PY_OPTIONAL) && (obj==Py_None))
+        ) {
+        /* intent(cache), optional, intent(hide) */
+        if (count_nonpos(rank,dims)) {
+            int i;
+            strcpy(mess, "failed to create intent(cache|hide)|optional array"
+                   "-- must have defined dimensions but got (");
+            for(i=0;i<rank;++i)
+                sprintf(mess+strlen(mess),"%" NPY_INTP_FMT ",",dims[i]);
+            strcat(mess, ")");
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+        arr = (PyArrayObject *)
+            PyArray_New(&PyArray_Type, rank, dims, type_num,
+                        NULL,NULL,0,
+                        !(intent&F2PY_INTENT_C),
+                        NULL);
+        if (arr==NULL) return NULL;
+        if (!(intent & F2PY_INTENT_CACHE))
+            PyArray_FILLWBYTE(arr, 0);
+        return arr;
+    }
+
+    descr = PyArray_DescrFromType(type_num);
+    elsize = descr->elsize;
+    typechar = descr->type;
+    Py_DECREF(descr);
+    if (PyArray_Check(obj)) {
+        arr = (PyArrayObject *)obj;
+
+        if (intent & F2PY_INTENT_CACHE) {
+            /* intent(cache) */
+            if (PyArray_ISONESEGMENT(arr)
+                && PyArray_ITEMSIZE(arr)>=elsize) {
+                if (check_and_fix_dimensions(arr,rank,dims)) {
+                    return NULL; /*XXX: set exception */
+                }
+                if (intent & F2PY_INTENT_OUT)
+                    Py_INCREF(arr);
+                return arr;
+            }
+            strcpy(mess, "failed to initialize intent(cache) array");
+            if (!PyArray_ISONESEGMENT(arr))
+                strcat(mess, " -- input must be in one segment");
+            if (PyArray_ITEMSIZE(arr)<elsize)
+                sprintf(mess+strlen(mess),
+                        " -- expected at least elsize=%d but got %" NPY_INTP_FMT,
+                        elsize,
+                        (npy_intp)PyArray_ITEMSIZE(arr)
+                        );
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+
+        /* here we have always intent(in) or intent(inout) or intent(inplace) */
+
+        if (check_and_fix_dimensions(arr,rank,dims)) {
+            return NULL; /*XXX: set exception */
+        }
+	/*
+	printf("intent alignement=%d\n", F2PY_GET_ALIGNMENT(intent));
+	printf("alignement check=%d\n", F2PY_CHECK_ALIGNMENT(arr, intent));
+	int i;
+	for (i=1;i<=16;i++)
+	  printf("i=%d isaligned=%d\n", i, ARRAY_ISALIGNED(arr, i));
+	*/
+        if ((! (intent & F2PY_INTENT_COPY))
+            && PyArray_ITEMSIZE(arr)==elsize
+            && ARRAY_ISCOMPATIBLE(arr,type_num)
+	    && F2PY_CHECK_ALIGNMENT(arr, intent)
+            ) {
+            if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) {
+                if ((intent & F2PY_INTENT_OUT)) {
+                    Py_INCREF(arr);
+                }
+                /* Returning input array */
+                return arr;
+            }
+        }
+
+        if (intent & F2PY_INTENT_INOUT) {
+            strcpy(mess, "failed to initialize intent(inout) array");
+            if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr))
+                strcat(mess, " -- input not contiguous");
+            if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr))
+                strcat(mess, " -- input not fortran contiguous");
+            if (PyArray_ITEMSIZE(arr)!=elsize)
+                sprintf(mess+strlen(mess),
+                        " -- expected elsize=%d but got %" NPY_INTP_FMT,
+                        elsize,
+                        (npy_intp)PyArray_ITEMSIZE(arr)
+                        );
+            if (!(ARRAY_ISCOMPATIBLE(arr,type_num)))
+                sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'",
+                        PyArray_DESCR(arr)->type,typechar);
+	    if (!(F2PY_CHECK_ALIGNMENT(arr, intent)))
+	      sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent));
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+
+        /* here we have always intent(in) or intent(inplace) */
+
+        {
+            PyArrayObject *retarr = (PyArrayObject *) \
+                PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num,
+                            NULL,NULL,0,
+                            !(intent&F2PY_INTENT_C),
+                            NULL);
+            if (retarr==NULL)
+                return NULL;
+            F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
+            if (PyArray_CopyInto(retarr, arr)) {
+                Py_DECREF(retarr);
+                return NULL;
+            }
+            if (intent & F2PY_INTENT_INPLACE) {
+                if (swap_arrays(arr,retarr))
+                    return NULL; /* XXX: set exception */
+                Py_XDECREF(retarr);
+                if (intent & F2PY_INTENT_OUT)
+                    Py_INCREF(arr);
+            } else {
+                arr = retarr;
+            }
+        }
+        return arr;
+    }
+
+    if ((intent & F2PY_INTENT_INOUT) ||
+            (intent & F2PY_INTENT_INPLACE) ||
+            (intent & F2PY_INTENT_CACHE)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "failed to initialize intent(inout|inplace|cache) "
+                        "array, input not an array");
+        return NULL;
+    }
+
+    {
+        F2PY_REPORT_ON_ARRAY_COPY_FROMANY;
+        arr = (PyArrayObject *) \
+            PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0,
+                            ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \
+                            | NPY_ARRAY_FORCECAST, NULL);
+        if (arr==NULL)
+            return NULL;
+        if (check_and_fix_dimensions(arr,rank,dims))
+            return NULL; /*XXX: set exception */
+        return arr;
+    }
+
+}
+
+/*****************************************/
+/* Helper functions for array_from_pyobj */
+/*****************************************/
+
+static
+int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *dims) {
+    /*
+      This function fills in blanks (that are -1\'s) in dims list using
+      the dimensions from arr. It also checks that non-blank dims will
+      match with the corresponding values in arr dimensions.
+    */
+    const npy_intp arr_size = (PyArray_NDIM(arr))?PyArray_Size((PyObject *)arr):1;
+#ifdef DEBUG_COPY_ND_ARRAY
+    dump_attrs(arr);
+    printf("check_and_fix_dimensions:init: dims=");
+    dump_dims(rank,dims);
+#endif
+    if (rank > PyArray_NDIM(arr)) { /* [1,2] -> [[1],[2]]; 1 -> [[1]]  */
+        npy_intp new_size = 1;
+        int free_axe = -1;
+        int i;
+        npy_intp d;
+        /* Fill dims where -1 or 0; check dimensions; calc new_size; */
+        for(i=0;i<PyArray_NDIM(arr);++i) {
+            d = PyArray_DIM(arr,i);
+            if (dims[i] >= 0) {
+                if (d>1 && dims[i]!=d) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT "\n",
+                            i,dims[i], d);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else {
+                dims[i] = d ? d : 1;
+            }
+            new_size *= dims[i];
+        }
+        for(i=PyArray_NDIM(arr);i<rank;++i)
+            if (dims[i]>1) {
+                fprintf(stderr,"%d-th dimension must be %" NPY_INTP_FMT
+                        " but got 0 (not defined).\n",
+                        i,dims[i]);
+                return 1;
+            } else if (free_axe<0)
+                free_axe = i;
+            else
+                dims[i] = 1;
+        if (free_axe>=0) {
+            dims[free_axe] = arr_size/new_size;
+            new_size *= dims[free_axe];
+        }
+        if (new_size != arr_size) {
+            fprintf(stderr,"unexpected array size: new_size=%" NPY_INTP_FMT
+                    ", got array with arr_size=%" NPY_INTP_FMT " (maybe too many free"
+                    " indices)\n", new_size,arr_size);
+            return 1;
+        }
+    } else if (rank==PyArray_NDIM(arr)) {
+        npy_intp new_size = 1;
+        int i;
+        npy_intp d;
+        for (i=0; i<rank; ++i) {
+	    d = PyArray_DIM(arr,i);
+            if (dims[i]>=0) {
+                if (d > 1 && d!=dims[i]) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT "\n",
+                            i,dims[i],d);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else dims[i] = d;
+            new_size *= dims[i];
+        }
+        if (new_size != arr_size) {
+            fprintf(stderr,"unexpected array size: new_size=%" NPY_INTP_FMT
+                    ", got array with arr_size=%" NPY_INTP_FMT "\n", new_size,arr_size);
+            return 1;
+        }
+    } else { /* [[1,2]] -> [[1],[2]] */
+        int i,j;
+        npy_intp d;
+        int effrank;
+        npy_intp size;
+        for (i=0,effrank=0;i<PyArray_NDIM(arr);++i)
+            if (PyArray_DIM(arr,i)>1) ++effrank;
+        if (dims[rank-1]>=0)
+            if (effrank>rank) {
+                fprintf(stderr,"too many axes: %d (effrank=%d), expected rank=%d\n",
+                        PyArray_NDIM(arr),effrank,rank);
+                return 1;
+            }
+
+        for (i=0,j=0;i<rank;++i) {
+            while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j;
+            if (j>=PyArray_NDIM(arr)) d = 1;
+            else d = PyArray_DIM(arr,j++);
+            if (dims[i]>=0) {
+                if (d>1 && d!=dims[i]) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT " (real index=%d)\n",
+                            i,dims[i],d,j-1);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else
+                dims[i] = d;
+        }
+
+        for (i=rank;i<PyArray_NDIM(arr);++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */
+            while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j;
+            if (j>=PyArray_NDIM(arr)) d = 1;
+            else d = PyArray_DIM(arr,j++);
+            dims[rank-1] *= d;
+        }
+        for (i=0,size=1;i<rank;++i) size *= dims[i];
+        if (size != arr_size) {
+            fprintf(stderr,"unexpected array size: size=%" NPY_INTP_FMT ", arr_size=%" NPY_INTP_FMT
+                    ", rank=%d, effrank=%d, arr.nd=%d, dims=[",
+                    size,arr_size,rank,effrank,PyArray_NDIM(arr));
+            for (i=0;i<rank;++i) fprintf(stderr," %" NPY_INTP_FMT,dims[i]);
+            fprintf(stderr," ], arr.dims=[");
+            for (i=0;i<PyArray_NDIM(arr);++i) fprintf(stderr," %" NPY_INTP_FMT,PyArray_DIM(arr,i));
+            fprintf(stderr," ]\n");
+            return 1;
+        }
+    }
+#ifdef DEBUG_COPY_ND_ARRAY
+    printf("check_and_fix_dimensions:end: dims=");
+    dump_dims(rank,dims);
+#endif
+    return 0;
+}
+
+/* End of file: array_from_pyobj.c */
+
+/************************* copy_ND_array *******************************/
+
+extern
+int copy_ND_array(const PyArrayObject *arr, PyArrayObject *out)
+{
+    F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
+    return PyArray_CopyInto(out, (PyArrayObject *)arr);
+}
+
+/*********************************************/
+/* Compatibility functions for Python >= 3.0 */
+/*********************************************/
+
+#if PY_VERSION_HEX >= 0x03000000
+
+PyObject *
+F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+void *
+F2PyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+int
+F2PyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+PyObject *
+F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+void *
+F2PyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+int
+F2PyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+/************************* EOF fortranobject.c *******************************/
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
new file mode 100644
index 0000000000..c9b54e2594
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
@@ -0,0 +1,162 @@
+#ifndef Py_FORTRANOBJECT_H
+#define Py_FORTRANOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Python.h"
+
+#ifdef FORTRANOBJECT_C
+#define NO_IMPORT_ARRAY
+#endif
+#define PY_ARRAY_UNIQUE_SYMBOL _npy_f2py_ARRAY_API
+#include "numpy/arrayobject.h"
+
+/*
+ * Python 3 support macros
+ */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyString_Check PyBytes_Check
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_FromString PyBytes_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+
+#define PyInt_Check PyLong_Check
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsLong PyLong_AsLong
+
+#define PyNumber_Int PyNumber_Long
+
+#else
+
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#endif
+
+
+#ifdef F2PY_REPORT_ATEXIT
+#include <sys/timeb.h>
+  extern void f2py_start_clock(void);
+  extern void f2py_stop_clock(void);
+  extern void f2py_start_call_clock(void);
+  extern void f2py_stop_call_clock(void);
+  extern void f2py_cb_start_clock(void);
+  extern void f2py_cb_stop_clock(void);
+  extern void f2py_cb_start_call_clock(void);
+  extern void f2py_cb_stop_call_clock(void);
+  extern void f2py_report_on_exit(int,void*);
+#endif
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/* Fortran object interface */
+
+/*
+123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+
+PyFortranObject represents various Fortran objects:
+Fortran (module) routines, COMMON blocks, module data.
+
+Author: Pearu Peterson <pearu@cens.ioc.ee>
+*/
+
+#define F2PY_MAX_DIMS 40
+
+typedef void (*f2py_set_data_func)(char*,npy_intp*);
+typedef void (*f2py_void_func)(void);
+typedef void (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*);
+
+  /*typedef void* (*f2py_c_func)(void*,...);*/
+
+typedef void *(*f2pycfunc)(void);
+
+typedef struct {
+  char *name;                /* attribute (array||routine) name */
+  int rank;                  /* array rank, 0 for scalar, max is F2PY_MAX_DIMS,
+				|| rank=-1 for Fortran routine */
+  struct {npy_intp d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */
+  int type;                  /* PyArray_<type> || not used */
+  char *data;                /* pointer to array || Fortran routine */
+  f2py_init_func func;            /* initialization function for
+				allocatable arrays:
+				func(&rank,dims,set_ptr_func,name,len(name))
+				|| C/API wrapper for Fortran routine */
+  char *doc;                 /* documentation string; only recommended
+				for routines. */
+} FortranDataDef;
+
+typedef struct {
+  PyObject_HEAD
+  int len;                   /* Number of attributes */
+  FortranDataDef *defs;      /* An array of FortranDataDef's */
+  PyObject       *dict;      /* Fortran object attribute dictionary */
+} PyFortranObject;
+
+#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type)
+#define PyFortran_Check1(op) (0==strcmp(Py_TYPE(op)->tp_name,"fortran"))
+
+  extern PyTypeObject PyFortran_Type;
+  extern int F2PyDict_SetItemString(PyObject* dict, char *name, PyObject *obj);
+  extern PyObject * PyFortranObject_New(FortranDataDef* defs, f2py_void_func init);
+  extern PyObject * PyFortranObject_NewAsAttr(FortranDataDef* defs);
+
+#if PY_VERSION_HEX >= 0x03000000
+
+PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
+void * F2PyCapsule_AsVoidPtr(PyObject *obj);
+int F2PyCapsule_Check(PyObject *ptr);
+
+#else
+
+PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *));
+void * F2PyCapsule_AsVoidPtr(PyObject *ptr);
+int F2PyCapsule_Check(PyObject *ptr);
+
+#endif
+
+#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS)
+#define F2PY_INTENT_IN 1
+#define F2PY_INTENT_INOUT 2
+#define F2PY_INTENT_OUT 4
+#define F2PY_INTENT_HIDE 8
+#define F2PY_INTENT_CACHE 16
+#define F2PY_INTENT_COPY 32
+#define F2PY_INTENT_C 64
+#define F2PY_OPTIONAL 128
+#define F2PY_INTENT_INPLACE 256
+#define F2PY_INTENT_ALIGNED4 512
+#define F2PY_INTENT_ALIGNED8 1024
+#define F2PY_INTENT_ALIGNED16 2048
+
+#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0)
+#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4)
+#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8)
+#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16)
+
+#define F2PY_GET_ALIGNMENT(intent) \
+	(F2PY_ALIGN4(intent) ? 4 : \
+	 (F2PY_ALIGN8(intent) ? 8 : \
+	  (F2PY_ALIGN16(intent) ? 16 : 1) ))
+#define F2PY_CHECK_ALIGNMENT(arr, intent) ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent))
+
+  extern PyArrayObject* array_from_pyobj(const int type_num,
+					 npy_intp *dims,
+					 const int rank,
+					 const int intent,
+					 PyObject *obj);
+  extern int copy_ND_array(const PyArrayObject *in, PyArrayObject *out);
+
+#ifdef DEBUG_COPY_ND_ARRAY
+  extern void dump_attrs(const PyArrayObject* arr);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FORTRANOBJECT_H */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
new file mode 100644
index 0000000000..2da6a2c5de
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
@@ -0,0 +1,223 @@
+/* File: wrapmodule.c
+ * This file is auto-generated with f2py (version:2_1330).
+ * Hand edited by Pearu.
+ * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
+ * written by Pearu Peterson <pearu@cens.ioc.ee>.
+ * See http://cens.ioc.ee/projects/f2py2e/
+ * Generation date: Fri Oct 21 22:41:12 2005
+ * $Revision:$
+ * $Date:$
+ * Do not edit this file directly unless you know what you are doing!!!
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************** See f2py2e/cfuncs.py: includes ***********************/
+#include "Python.h"
+#include "fortranobject.h"
+#include <math.h>
+
+static PyObject *wrap_error;
+static PyObject *wrap_module;
+
+/************************************ call ************************************/
+static char doc_f2py_rout_wrap_call[] = "\
+Function signature:\n\
+  arr = call(type_num,dims,intent,obj)\n\
+Required arguments:\n"
+"  type_num : input int\n"
+"  dims : input int-sequence\n"
+"  intent : input int\n"
+"  obj : input python object\n"
+"Return objects:\n"
+"  arr : array";
+static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
+				     PyObject *capi_args) {
+  PyObject * volatile capi_buildvalue = NULL;
+  int type_num = 0;
+  npy_intp *dims = NULL;
+  PyObject *dims_capi = Py_None;
+  int rank = 0;
+  int intent = 0;
+  PyArrayObject *capi_arr_tmp = NULL;
+  PyObject *arr_capi = Py_None;
+  int i;
+
+  if (!PyArg_ParseTuple(capi_args,"iOiO|:wrap.call",\
+			&type_num,&dims_capi,&intent,&arr_capi))
+    return NULL;
+  rank = PySequence_Length(dims_capi);
+  dims = malloc(rank*sizeof(npy_intp));
+  for (i=0;i<rank;++i)
+    dims[i] = (npy_intp)PyInt_AsLong(PySequence_GetItem(dims_capi,i));
+
+  capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi);
+  if (capi_arr_tmp == NULL) {
+    free(dims);
+    return NULL;
+  }
+  capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
+  free(dims);
+  return capi_buildvalue;
+}
+
+static char doc_f2py_rout_wrap_attrs[] = "\
+Function signature:\n\
+  arr = array_attrs(arr)\n\
+Required arguments:\n"
+"  arr : input array object\n"
+"Return objects:\n"
+"  data : data address in hex\n"
+"  nd : int\n"
+"  dimensions : tuple\n"
+"  strides : tuple\n"
+"  base : python object\n"
+"  (kind,type,type_num,elsize,alignment) : 4-tuple\n"
+"  flags : int\n"
+"  itemsize : int\n"
+;
+static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
+				      PyObject *capi_args) {
+  PyObject *arr_capi = Py_None;
+  PyArrayObject *arr = NULL;
+  PyObject *dimensions = NULL;
+  PyObject *strides = NULL;
+  char s[100];
+  int i;
+  memset(s,0,100*sizeof(char));
+  if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
+			&PyArray_Type,&arr_capi))
+    return NULL;
+  arr = (PyArrayObject *)arr_capi;
+  sprintf(s,"%p",PyArray_DATA(arr));
+  dimensions = PyTuple_New(PyArray_NDIM(arr));
+  strides = PyTuple_New(PyArray_NDIM(arr));
+  for (i=0;i<PyArray_NDIM(arr);++i) {
+    PyTuple_SetItem(dimensions,i,PyInt_FromLong(PyArray_DIM(arr,i)));
+    PyTuple_SetItem(strides,i,PyInt_FromLong(PyArray_STRIDE(arr,i)));
+  }
+  return Py_BuildValue("siOOO(cciii)ii",s,PyArray_NDIM(arr),
+		       dimensions,strides,
+		       (PyArray_BASE(arr)==NULL?Py_None:PyArray_BASE(arr)),
+		       PyArray_DESCR(arr)->kind,
+		       PyArray_DESCR(arr)->type,
+		       PyArray_TYPE(arr),
+		       PyArray_ITEMSIZE(arr),
+		       PyArray_DESCR(arr)->alignment,
+		       PyArray_FLAGS(arr),
+		       PyArray_ITEMSIZE(arr));
+}
+
+static PyMethodDef f2py_module_methods[] = {
+
+  {"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call},
+  {"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs},
+  {NULL,NULL}
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "test_array_from_pyobj_ext",
+    NULL,
+    -1,
+    f2py_module_methods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+#endif
+
+#if PY_VERSION_HEX >= 0x03000000
+#define RETVAL m
+PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
+#else
+#define RETVAL
+PyMODINIT_FUNC inittest_array_from_pyobj_ext(void) {
+#endif
+  PyObject *m,*d, *s;
+#if PY_VERSION_HEX >= 0x03000000
+  m = wrap_module = PyModule_Create(&moduledef);
+#else
+  m = wrap_module = Py_InitModule("test_array_from_pyobj_ext", f2py_module_methods);
+#endif
+  Py_TYPE(&PyFortran_Type) = &PyType_Type;
+  import_array();
+  if (PyErr_Occurred())
+    Py_FatalError("can't initialize module wrap (failed to import numpy)");
+  d = PyModule_GetDict(m);
+  s = PyString_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n"
+"  arr = call(type_num,dims,intent,obj)\n"
+".");
+  PyDict_SetItemString(d, "__doc__", s);
+  wrap_error = PyErr_NewException ("wrap.error", NULL, NULL);
+  Py_DECREF(s);
+  PyDict_SetItemString(d, "F2PY_INTENT_IN", PyInt_FromLong(F2PY_INTENT_IN));
+  PyDict_SetItemString(d, "F2PY_INTENT_INOUT", PyInt_FromLong(F2PY_INTENT_INOUT));
+  PyDict_SetItemString(d, "F2PY_INTENT_OUT", PyInt_FromLong(F2PY_INTENT_OUT));
+  PyDict_SetItemString(d, "F2PY_INTENT_HIDE", PyInt_FromLong(F2PY_INTENT_HIDE));
+  PyDict_SetItemString(d, "F2PY_INTENT_CACHE", PyInt_FromLong(F2PY_INTENT_CACHE));
+  PyDict_SetItemString(d, "F2PY_INTENT_COPY", PyInt_FromLong(F2PY_INTENT_COPY));
+  PyDict_SetItemString(d, "F2PY_INTENT_C", PyInt_FromLong(F2PY_INTENT_C));
+  PyDict_SetItemString(d, "F2PY_OPTIONAL", PyInt_FromLong(F2PY_OPTIONAL));
+  PyDict_SetItemString(d, "F2PY_INTENT_INPLACE", PyInt_FromLong(F2PY_INTENT_INPLACE));
+  PyDict_SetItemString(d, "NPY_BOOL", PyInt_FromLong(NPY_BOOL));
+  PyDict_SetItemString(d, "NPY_BYTE", PyInt_FromLong(NPY_BYTE));
+  PyDict_SetItemString(d, "NPY_UBYTE", PyInt_FromLong(NPY_UBYTE));
+  PyDict_SetItemString(d, "NPY_SHORT", PyInt_FromLong(NPY_SHORT));
+  PyDict_SetItemString(d, "NPY_USHORT", PyInt_FromLong(NPY_USHORT));
+  PyDict_SetItemString(d, "NPY_INT", PyInt_FromLong(NPY_INT));
+  PyDict_SetItemString(d, "NPY_UINT", PyInt_FromLong(NPY_UINT));
+  PyDict_SetItemString(d, "NPY_INTP", PyInt_FromLong(NPY_INTP));
+  PyDict_SetItemString(d, "NPY_UINTP", PyInt_FromLong(NPY_UINTP));
+  PyDict_SetItemString(d, "NPY_LONG", PyInt_FromLong(NPY_LONG));
+  PyDict_SetItemString(d, "NPY_ULONG", PyInt_FromLong(NPY_ULONG));
+  PyDict_SetItemString(d, "NPY_LONGLONG", PyInt_FromLong(NPY_LONGLONG));
+  PyDict_SetItemString(d, "NPY_ULONGLONG", PyInt_FromLong(NPY_ULONGLONG));
+  PyDict_SetItemString(d, "NPY_FLOAT", PyInt_FromLong(NPY_FLOAT));
+  PyDict_SetItemString(d, "NPY_DOUBLE", PyInt_FromLong(NPY_DOUBLE));
+  PyDict_SetItemString(d, "NPY_LONGDOUBLE", PyInt_FromLong(NPY_LONGDOUBLE));
+  PyDict_SetItemString(d, "NPY_CFLOAT", PyInt_FromLong(NPY_CFLOAT));
+  PyDict_SetItemString(d, "NPY_CDOUBLE", PyInt_FromLong(NPY_CDOUBLE));
+  PyDict_SetItemString(d, "NPY_CLONGDOUBLE", PyInt_FromLong(NPY_CLONGDOUBLE));
+  PyDict_SetItemString(d, "NPY_OBJECT", PyInt_FromLong(NPY_OBJECT));
+  PyDict_SetItemString(d, "NPY_STRING", PyInt_FromLong(NPY_STRING));
+  PyDict_SetItemString(d, "NPY_UNICODE", PyInt_FromLong(NPY_UNICODE));
+  PyDict_SetItemString(d, "NPY_VOID", PyInt_FromLong(NPY_VOID));
+  PyDict_SetItemString(d, "NPY_NTYPES", PyInt_FromLong(NPY_NTYPES));
+  PyDict_SetItemString(d, "NPY_NOTYPE", PyInt_FromLong(NPY_NOTYPE));
+  PyDict_SetItemString(d, "NPY_USERDEF", PyInt_FromLong(NPY_USERDEF));
+
+  PyDict_SetItemString(d, "CONTIGUOUS", PyInt_FromLong(NPY_ARRAY_C_CONTIGUOUS));
+  PyDict_SetItemString(d, "FORTRAN", PyInt_FromLong(NPY_ARRAY_F_CONTIGUOUS));
+  PyDict_SetItemString(d, "OWNDATA", PyInt_FromLong(NPY_ARRAY_OWNDATA));
+  PyDict_SetItemString(d, "FORCECAST", PyInt_FromLong(NPY_ARRAY_FORCECAST));
+  PyDict_SetItemString(d, "ENSURECOPY", PyInt_FromLong(NPY_ARRAY_ENSURECOPY));
+  PyDict_SetItemString(d, "ENSUREARRAY", PyInt_FromLong(NPY_ARRAY_ENSUREARRAY));
+  PyDict_SetItemString(d, "ALIGNED", PyInt_FromLong(NPY_ARRAY_ALIGNED));
+  PyDict_SetItemString(d, "WRITEABLE", PyInt_FromLong(NPY_ARRAY_WRITEABLE));
+  PyDict_SetItemString(d, "UPDATEIFCOPY", PyInt_FromLong(NPY_ARRAY_UPDATEIFCOPY));
+
+  PyDict_SetItemString(d, "BEHAVED", PyInt_FromLong(NPY_ARRAY_BEHAVED));
+  PyDict_SetItemString(d, "BEHAVED_NS", PyInt_FromLong(NPY_ARRAY_BEHAVED_NS));
+  PyDict_SetItemString(d, "CARRAY", PyInt_FromLong(NPY_ARRAY_CARRAY));
+  PyDict_SetItemString(d, "FARRAY", PyInt_FromLong(NPY_ARRAY_FARRAY));
+  PyDict_SetItemString(d, "CARRAY_RO", PyInt_FromLong(NPY_ARRAY_CARRAY_RO));
+  PyDict_SetItemString(d, "FARRAY_RO", PyInt_FromLong(NPY_ARRAY_FARRAY_RO));
+  PyDict_SetItemString(d, "DEFAULT", PyInt_FromLong(NPY_ARRAY_DEFAULT));
+  PyDict_SetItemString(d, "UPDATE_ALL", PyInt_FromLong(NPY_ARRAY_UPDATE_ALL));
+
+  if (PyErr_Occurred())
+    Py_FatalError("can't initialize module wrap");
+
+#ifdef F2PY_REPORT_ATEXIT
+  on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
+#endif
+
+  return RETVAL;
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
new file mode 100644
index 0000000000..2665f89b52
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
@@ -0,0 +1 @@
+dict(real=dict(rk="double"))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
new file mode 100644
index 0000000000..b301710f5d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
@@ -0,0 +1,34 @@
+
+subroutine sum(x, res)
+  implicit none
+  real, intent(in) :: x(:)
+  real, intent(out) :: res
+
+  integer :: i
+
+  !print *, "sum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end subroutine sum
+
+function fsum(x) result (res)
+  implicit none
+  real, intent(in) :: x(:)
+  real :: res
+
+  integer :: i
+
+  !print *, "fsum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end function fsum
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
new file mode 100644
index 0000000000..cbe6317ed8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
@@ -0,0 +1,41 @@
+
+module mod
+
+contains
+
+subroutine sum(x, res)
+  implicit none
+  real, intent(in) :: x(:)
+  real, intent(out) :: res
+
+  integer :: i
+
+  !print *, "sum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end subroutine sum
+
+function fsum(x) result (res)
+  implicit none
+  real, intent(in) :: x(:)
+  real :: res
+
+  integer :: i
+
+  !print *, "fsum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end function fsum
+
+
+end module mod
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
new file mode 100644
index 0000000000..337465ac54
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
@@ -0,0 +1,19 @@
+subroutine sum_with_use(x, res)
+  use precision
+
+  implicit none
+
+  real(kind=rk), intent(in) :: x(:)
+  real(kind=rk), intent(out) :: res
+
+  integer :: i
+
+  !print *, "size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+ end subroutine
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
new file mode 100644
index 0000000000..ed6c70cbbe
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
@@ -0,0 +1,4 @@
+module precision
+  integer, parameter :: rk = selected_real_kind(8)
+  integer, parameter :: ik = selected_real_kind(4)
+end module
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
new file mode 100644
index 0000000000..d3d15cfb20
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
@@ -0,0 +1,20 @@
+
+
+subroutine selectedrealkind(p, r, res)
+  implicit none
+  
+  integer, intent(in) :: p, r
+  !f2py integer :: r=0
+  integer, intent(out) :: res
+  res = selected_real_kind(p, r)
+
+end subroutine
+
+subroutine selectedintkind(p, res)
+  implicit none
+
+  integer, intent(in) :: p
+  integer, intent(out) :: res
+  res = selected_int_kind(p)
+
+end subroutine
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
new file mode 100644
index 0000000000..c34742578f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
@@ -0,0 +1,5 @@
+      subroutine bar11(a)
+cf2py intent(out) a
+      integer a
+      a = 11
+      end
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
new file mode 100644
index 0000000000..7543a6acb7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
@@ -0,0 +1,8 @@
+      module foo_fixed
+      contains
+        subroutine bar12(a)
+!f2py intent(out) a
+          integer a
+          a = 12
+        end subroutine bar12
+      end module foo_fixed
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
new file mode 100644
index 0000000000..c1b641f13e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
@@ -0,0 +1,8 @@
+module foo_free
+contains
+  subroutine bar13(a)
+    !f2py intent(out) a
+    integer a
+    a = 13
+  end subroutine bar13
+end module foo_free
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
new file mode 100644
index 0000000000..80cdad90ce
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
@@ -0,0 +1,9 @@
+! Check that intent(in out) translates as intent(inout).
+! The separation seems to be a common usage.
+      subroutine foo(x)
+          implicit none
+          real(4), intent(in out) :: x
+          dimension x(3)
+          x(1) = x(1) + x(2) + x(3)
+          return
+      end
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90 b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
new file mode 100644
index 0000000000..5b66f8c430
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
@@ -0,0 +1,44 @@
+
+subroutine foo(a, n, m, b)
+  implicit none
+
+  real, intent(in) :: a(n, m)
+  integer, intent(in) :: n, m
+  real, intent(out) :: b(size(a, 1))
+
+  integer :: i
+
+  do i = 1, size(b)
+    b(i) = sum(a(i,:))
+  enddo
+end subroutine
+
+subroutine trans(x,y)
+  implicit none
+  real, intent(in), dimension(:,:) :: x
+  real, intent(out), dimension( size(x,2), size(x,1) ) :: y
+  integer :: N, M, i, j
+  N = size(x,1)
+  M = size(x,2)
+  DO i=1,N
+     do j=1,M
+        y(j,i) = x(i,j)
+     END DO
+  END DO
+end subroutine trans
+
+subroutine flatten(x,y)
+  implicit none
+  real, intent(in), dimension(:,:) :: x
+  real, intent(out), dimension( size(x) ) :: y
+  integer :: N, M, i, j, k
+  N = size(x,1)
+  M = size(x,2)
+  k = 1
+  DO i=1,N
+     do j=1,M
+        y(k) = x(i,j)
+        k = k + 1
+     END DO
+  END DO
+end subroutine flatten
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
new file mode 100644
index 0000000000..48bb7c0f4d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
@@ -0,0 +1,591 @@
+from __future__ import division, absolute_import, print_function
+
+import unittest
+import os
+import sys
+import copy
+
+from numpy import (
+    array, alltrue, ndarray, zeros, dtype, intp, clongdouble
+)
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, SkipTest
+)
+from numpy.core.multiarray import typeinfo
+import util
+
+wrap = None
+
+
+def setup():
+    """
+    Build the required testing extension module
+
+    """
+    global wrap
+
+    # Check compiler availability first
+    if not util.has_c_compiler():
+        raise SkipTest("No C compiler available")
+
+    if wrap is None:
+        config_code = """
+        config.add_extension('test_array_from_pyobj_ext',
+                             sources=['wrapmodule.c', 'fortranobject.c'],
+                             define_macros=[])
+        """
+        d = os.path.dirname(__file__)
+        src = [os.path.join(d, 'src', 'array_from_pyobj', 'wrapmodule.c'),
+               os.path.join(d, '..', 'src', 'fortranobject.c'),
+               os.path.join(d, '..', 'src', 'fortranobject.h')]
+        wrap = util.build_module_distutils(src, config_code,
+                                           'test_array_from_pyobj_ext')
+
+
+def flags_info(arr):
+    flags = wrap.array_attrs(arr)[6]
+    return flags2names(flags)
+
+
+def flags2names(flags):
+    info = []
+    for flagname in ['CONTIGUOUS', 'FORTRAN', 'OWNDATA', 'ENSURECOPY',
+                     'ENSUREARRAY', 'ALIGNED', 'NOTSWAPPED', 'WRITEABLE',
+                     'UPDATEIFCOPY', 'BEHAVED', 'BEHAVED_RO',
+                     'CARRAY', 'FARRAY'
+                     ]:
+        if abs(flags) & getattr(wrap, flagname, 0):
+            info.append(flagname)
+    return info
+
+
+class Intent(object):
+
+    def __init__(self, intent_list=[]):
+        self.intent_list = intent_list[:]
+        flags = 0
+        for i in intent_list:
+            if i == 'optional':
+                flags |= wrap.F2PY_OPTIONAL
+            else:
+                flags |= getattr(wrap, 'F2PY_INTENT_' + i.upper())
+        self.flags = flags
+
+    def __getattr__(self, name):
+        name = name.lower()
+        if name == 'in_':
+            name = 'in'
+        return self.__class__(self.intent_list + [name])
+
+    def __str__(self):
+        return 'intent(%s)' % (','.join(self.intent_list))
+
+    def __repr__(self):
+        return 'Intent(%r)' % (self.intent_list)
+
+    def is_intent(self, *names):
+        for name in names:
+            if name not in self.intent_list:
+                return False
+        return True
+
+    def is_intent_exact(self, *names):
+        return len(self.intent_list) == len(names) and self.is_intent(*names)
+
+intent = Intent()
+
+_type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT',
+               'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG',
+               'FLOAT', 'DOUBLE', 'CFLOAT']
+
+_cast_dict = {'BOOL': ['BOOL']}
+_cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE']
+_cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE']
+_cast_dict['BYTE'] = ['BYTE']
+_cast_dict['UBYTE'] = ['UBYTE']
+_cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT']
+_cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT']
+_cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT']
+_cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT']
+
+_cast_dict['LONG'] = _cast_dict['INT'] + ['LONG']
+_cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG']
+
+_cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG']
+_cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG']
+
+_cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT']
+_cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE']
+
+_cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT']
+
+# 32 bit system malloc typically does not provide the alignment required by
+# 16 byte long double types this means the inout intent cannot be satisfied
+# and several tests fail as the alignment flag can be randomly true or fals
+# when numpy gains an aligned allocator the tests could be enabled again
+if ((intp().dtype.itemsize != 4 or clongdouble().dtype.alignment <= 8) and
+        sys.platform != 'win32'):
+    _type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE'])
+    _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \
+        ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE']
+    _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + \
+        ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE']
+    _cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT', 'CDOUBLE']
+
+
+class Type(object):
+    _type_cache = {}
+
+    def __new__(cls, name):
+        if isinstance(name, dtype):
+            dtype0 = name
+            name = None
+            for n, i in typeinfo.items():
+                if isinstance(i, tuple) and dtype0.type is i[-1]:
+                    name = n
+                    break
+        obj = cls._type_cache.get(name.upper(), None)
+        if obj is not None:
+            return obj
+        obj = object.__new__(cls)
+        obj._init(name)
+        cls._type_cache[name.upper()] = obj
+        return obj
+
+    def _init(self, name):
+        self.NAME = name.upper()
+        self.type_num = getattr(wrap, 'NPY_' + self.NAME)
+        assert_equal(self.type_num, typeinfo[self.NAME][1])
+        self.dtype = typeinfo[self.NAME][-1]
+        self.elsize = typeinfo[self.NAME][2] / 8
+        self.dtypechar = typeinfo[self.NAME][0]
+
+    def cast_types(self):
+        return [self.__class__(_m) for _m in _cast_dict[self.NAME]]
+
+    def all_types(self):
+        return [self.__class__(_m) for _m in _type_names]
+
+    def smaller_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if typeinfo[name][3] < bits:
+                types.append(Type(name))
+        return types
+
+    def equal_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if name == self.NAME:
+                continue
+            if typeinfo[name][3] == bits:
+                types.append(Type(name))
+        return types
+
+    def larger_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if typeinfo[name][3] > bits:
+                types.append(Type(name))
+        return types
+
+
+class Array(object):
+
+    def __init__(self, typ, dims, intent, obj):
+        self.type = typ
+        self.dims = dims
+        self.intent = intent
+        self.obj_copy = copy.deepcopy(obj)
+        self.obj = obj
+
+        # arr.dtypechar may be different from typ.dtypechar
+        self.arr = wrap.call(typ.type_num, dims, intent.flags, obj)
+
+        assert_(isinstance(self.arr, ndarray), repr(type(self.arr)))
+
+        self.arr_attr = wrap.array_attrs(self.arr)
+
+        if len(dims) > 1:
+            if self.intent.is_intent('c'):
+                assert_(intent.flags & wrap.F2PY_INTENT_C)
+                assert_(not self.arr.flags['FORTRAN'],
+                        repr((self.arr.flags, getattr(obj, 'flags', None))))
+                assert_(self.arr.flags['CONTIGUOUS'])
+                assert_(not self.arr_attr[6] & wrap.FORTRAN)
+            else:
+                assert_(not intent.flags & wrap.F2PY_INTENT_C)
+                assert_(self.arr.flags['FORTRAN'])
+                assert_(not self.arr.flags['CONTIGUOUS'])
+                assert_(self.arr_attr[6] & wrap.FORTRAN)
+
+        if obj is None:
+            self.pyarr = None
+            self.pyarr_attr = None
+            return
+
+        if intent.is_intent('cache'):
+            assert_(isinstance(obj, ndarray), repr(type(obj)))
+            self.pyarr = array(obj).reshape(*dims).copy()
+        else:
+            self.pyarr = array(array(obj, dtype=typ.dtypechar).reshape(*dims),
+                               order=self.intent.is_intent('c') and 'C' or 'F')
+            assert_(self.pyarr.dtype == typ,
+                    repr((self.pyarr.dtype, typ)))
+        assert_(self.pyarr.flags['OWNDATA'], (obj, intent))
+        self.pyarr_attr = wrap.array_attrs(self.pyarr)
+
+        if len(dims) > 1:
+            if self.intent.is_intent('c'):
+                assert_(not self.pyarr.flags['FORTRAN'])
+                assert_(self.pyarr.flags['CONTIGUOUS'])
+                assert_(not self.pyarr_attr[6] & wrap.FORTRAN)
+            else:
+                assert_(self.pyarr.flags['FORTRAN'])
+                assert_(not self.pyarr.flags['CONTIGUOUS'])
+                assert_(self.pyarr_attr[6] & wrap.FORTRAN)
+
+        assert_(self.arr_attr[1] == self.pyarr_attr[1])  # nd
+        assert_(self.arr_attr[2] == self.pyarr_attr[2])  # dimensions
+        if self.arr_attr[1] <= 1:
+            assert_(self.arr_attr[3] == self.pyarr_attr[3],
+                    repr((self.arr_attr[3], self.pyarr_attr[3],
+                          self.arr.tobytes(), self.pyarr.tobytes())))  # strides
+        assert_(self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:],
+                repr((self.arr_attr[5], self.pyarr_attr[5])))  # descr
+        assert_(self.arr_attr[6] == self.pyarr_attr[6],
+                repr((self.arr_attr[6], self.pyarr_attr[6],
+                      flags2names(0 * self.arr_attr[6] - self.pyarr_attr[6]),
+                      flags2names(self.arr_attr[6]), intent)))  # flags
+
+        if intent.is_intent('cache'):
+            assert_(self.arr_attr[5][3] >= self.type.elsize,
+                    repr((self.arr_attr[5][3], self.type.elsize)))
+        else:
+            assert_(self.arr_attr[5][3] == self.type.elsize,
+                    repr((self.arr_attr[5][3], self.type.elsize)))
+        assert_(self.arr_equal(self.pyarr, self.arr))
+
+        if isinstance(self.obj, ndarray):
+            if typ.elsize == Type(obj.dtype).elsize:
+                if not intent.is_intent('copy') and self.arr_attr[1] <= 1:
+                    assert_(self.has_shared_memory())
+
+    def arr_equal(self, arr1, arr2):
+        if arr1.shape != arr2.shape:
+            return False
+        s = arr1 == arr2
+        return alltrue(s.flatten())
+
+    def __str__(self):
+        return str(self.arr)
+
+    def has_shared_memory(self):
+        """Check that created array shares data with input array.
+        """
+        if self.obj is self.arr:
+            return True
+        if not isinstance(self.obj, ndarray):
+            return False
+        obj_attr = wrap.array_attrs(self.obj)
+        return obj_attr[0] == self.arr_attr[0]
+
+
+class test_intent(unittest.TestCase):
+
+    def test_in_out(self):
+        assert_equal(str(intent.in_.out), 'intent(in,out)')
+        assert_(intent.in_.c.is_intent('c'))
+        assert_(not intent.in_.c.is_intent_exact('c'))
+        assert_(intent.in_.c.is_intent_exact('c', 'in'))
+        assert_(intent.in_.c.is_intent_exact('in', 'c'))
+        assert_(not intent.in_.is_intent('c'))
+
+
+class _test_shared_memory:
+    num2seq = [1, 2]
+    num23seq = [[1, 2, 3], [4, 5, 6]]
+
+    def test_in_from_2seq(self):
+        a = self.array([2], intent.in_, self.num2seq)
+        assert_(not a.has_shared_memory())
+
+    def test_in_from_2casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num2seq, dtype=t.dtype)
+            a = self.array([len(self.num2seq)], intent.in_, obj)
+            if t.elsize == self.type.elsize:
+                assert_(
+                    a.has_shared_memory(), repr((self.type.dtype, t.dtype)))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_inout_2seq(self):
+        obj = array(self.num2seq, dtype=self.type.dtype)
+        a = self.array([len(self.num2seq)], intent.inout, obj)
+        assert_(a.has_shared_memory())
+
+        try:
+            a = self.array([2], intent.in_.inout, self.num2seq)
+        except TypeError as msg:
+            if not str(msg).startswith('failed to initialize intent'
+                                       '(inout|inplace|cache) array'):
+                raise
+        else:
+            raise SystemError('intent(inout) should have failed on sequence')
+
+    def test_f_inout_23seq(self):
+        obj = array(self.num23seq, dtype=self.type.dtype, order='F')
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        a = self.array(shape, intent.in_.inout, obj)
+        assert_(a.has_shared_memory())
+
+        obj = array(self.num23seq, dtype=self.type.dtype, order='C')
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        try:
+            a = self.array(shape, intent.in_.inout, obj)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to initialize intent'
+                                       '(inout) array'):
+                raise
+        else:
+            raise SystemError(
+                'intent(inout) should have failed on improper array')
+
+    def test_c_inout_23seq(self):
+        obj = array(self.num23seq, dtype=self.type.dtype)
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        a = self.array(shape, intent.in_.c.inout, obj)
+        assert_(a.has_shared_memory())
+
+    def test_in_copy_from_2casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num2seq, dtype=t.dtype)
+            a = self.array([len(self.num2seq)], intent.in_.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_in_from_23seq(self):
+        a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                       intent.in_, self.num23seq)
+        assert_(not a.has_shared_memory())
+
+    def test_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_f_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype, order='F')
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_, obj)
+            if t.elsize == self.type.elsize:
+                assert_(a.has_shared_memory(), repr(t.dtype))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.c, obj)
+            if t.elsize == self.type.elsize:
+                assert_(a.has_shared_memory(), repr(t.dtype))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_f_copy_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype, order='F')
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_copy_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.c.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_in_cache_from_2casttype(self):
+        for t in self.type.all_types():
+            if t.elsize != self.type.elsize:
+                continue
+            obj = array(self.num2seq, dtype=t.dtype)
+            shape = (len(self.num2seq),)
+            a = self.array(shape, intent.in_.c.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            a = self.array(shape, intent.in_.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            obj = array(self.num2seq, dtype=t.dtype, order='F')
+            a = self.array(shape, intent.in_.c.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            a = self.array(shape, intent.in_.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            try:
+                a = self.array(shape, intent.in_.cache, obj[::-1])
+            except ValueError as msg:
+                if not str(msg).startswith('failed to initialize'
+                                           ' intent(cache) array'):
+                    raise
+            else:
+                raise SystemError(
+                    'intent(cache) should have failed on multisegmented array')
+
+    def test_in_cache_from_2casttype_failure(self):
+        for t in self.type.all_types():
+            if t.elsize >= self.type.elsize:
+                continue
+            obj = array(self.num2seq, dtype=t.dtype)
+            shape = (len(self.num2seq),)
+            try:
+                self.array(shape, intent.in_.cache, obj)  # Should succeed
+            except ValueError as msg:
+                if not str(msg).startswith('failed to initialize'
+                                           ' intent(cache) array'):
+                    raise
+            else:
+                raise SystemError(
+                    'intent(cache) should have failed on smaller array')
+
+    def test_cache_hidden(self):
+        shape = (2,)
+        a = self.array(shape, intent.cache.hide, None)
+        assert_(a.arr.shape == shape)
+
+        shape = (2, 3)
+        a = self.array(shape, intent.cache.hide, None)
+        assert_(a.arr.shape == shape)
+
+        shape = (-1, 3)
+        try:
+            a = self.array(shape, intent.cache.hide, None)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to create intent'
+                                       '(cache|hide)|optional array'):
+                raise
+        else:
+            raise SystemError(
+                'intent(cache) should have failed on undefined dimensions')
+
+    def test_hidden(self):
+        shape = (2,)
+        a = self.array(shape, intent.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+
+        shape = (2, 3)
+        a = self.array(shape, intent.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
+
+        shape = (2, 3)
+        a = self.array(shape, intent.c.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
+
+        shape = (-1, 3)
+        try:
+            a = self.array(shape, intent.hide, None)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to create intent'
+                                       '(cache|hide)|optional array'):
+                raise
+        else:
+            raise SystemError('intent(hide) should have failed'
+                              ' on undefined dimensions')
+
+    def test_optional_none(self):
+        shape = (2,)
+        a = self.array(shape, intent.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+
+        shape = (2, 3)
+        a = self.array(shape, intent.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
+
+        shape = (2, 3)
+        a = self.array(shape, intent.c.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
+
+    def test_optional_from_2seq(self):
+        obj = self.num2seq
+        shape = (len(obj),)
+        a = self.array(shape, intent.optional, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+    def test_optional_from_23seq(self):
+        obj = self.num23seq
+        shape = (len(obj), len(obj[0]))
+        a = self.array(shape, intent.optional, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+        a = self.array(shape, intent.optional.c, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+    def test_inplace(self):
+        obj = array(self.num23seq, dtype=self.type.dtype)
+        assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
+        shape = obj.shape
+        a = self.array(shape, intent.inplace, obj)
+        assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
+        a.arr[1][2] = 54
+        assert_(obj[1][2] == a.arr[1][2] ==
+                array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+        assert_(a.arr is obj)
+        assert_(obj.flags['FORTRAN'])  # obj attributes are changed inplace!
+        assert_(not obj.flags['CONTIGUOUS'])
+
+    def test_inplace_from_casttype(self):
+        for t in self.type.cast_types():
+            if t is self.type:
+                continue
+            obj = array(self.num23seq, dtype=t.dtype)
+            assert_(obj.dtype.type == t.dtype)
+            assert_(obj.dtype.type is not self.type.dtype)
+            assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
+            shape = obj.shape
+            a = self.array(shape, intent.inplace, obj)
+            assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
+            a.arr[1][2] = 54
+            assert_(obj[1][2] == a.arr[1][2] ==
+                    array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+            assert_(a.arr is obj)
+            assert_(obj.flags['FORTRAN'])  # obj attributes changed inplace!
+            assert_(not obj.flags['CONTIGUOUS'])
+            assert_(obj.dtype.type is self.type.dtype)  # obj changed inplace!
+
+
+for t in _type_names:
+    exec('''\
+class test_%s_gen(unittest.TestCase,
+              _test_shared_memory
+              ):
+    def setUp(self):
+        self.type = Type(%r)
+    array = lambda self,dims,intent,obj: Array(Type(%r),dims,intent,obj)
+''' % (t, t, t))
+
+if __name__ == "__main__":
+    setup()
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
new file mode 100644
index 0000000000..725e7f0c1b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
@@ -0,0 +1,35 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestAssumedShapeSumExample(util.F2PyTest):
+    sources = [_path('src', 'assumed_shape', 'foo_free.f90'),
+               _path('src', 'assumed_shape', 'foo_use.f90'),
+               _path('src', 'assumed_shape', 'precision.f90'),
+               _path('src', 'assumed_shape', 'foo_mod.f90'),
+               ]
+
+    @dec.slow
+    def test_all(self):
+        r = self.module.fsum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.sum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.sum_with_use([1, 2])
+        assert_(r == 3, repr(r))
+
+        r = self.module.mod.sum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.mod.fsum([1, 2])
+        assert_(r == 3, repr(r))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
new file mode 100644
index 0000000000..6824a20424
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
@@ -0,0 +1,136 @@
+from __future__ import division, absolute_import, print_function
+
+import math
+import textwrap
+
+from numpy import array
+from numpy.testing import run_module_suite, assert_, assert_equal, dec
+import util
+
+
+class TestF77Callback(util.F2PyTest):
+    code = """
+       subroutine t(fun,a)
+       integer a
+cf2py  intent(out) a
+       external fun
+       call fun(a)
+       end
+
+       subroutine func(a)
+cf2py  intent(in,out) a
+       integer a
+       a = a + 11
+       end
+
+       subroutine func0(a)
+cf2py  intent(out) a
+       integer a
+       a = 11
+       end
+
+       subroutine t2(a)
+cf2py  intent(callback) fun
+       integer a
+cf2py  intent(out) a
+       external fun
+       call fun(a)
+       end
+
+       subroutine string_callback(callback, a)
+       external callback
+       double precision callback
+       double precision a
+       character*1 r
+cf2py  intent(out) a
+       r = 'r'
+       a = callback(r)
+       end
+
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t,t2".split(","):
+            self.check_function(name)
+
+    @dec.slow
+    def test_docstring(self):
+        expected = """
+        a = t(fun,[fun_extra_args])
+
+        Wrapper for ``t``.
+
+        Parameters
+        ----------
+        fun : call-back function
+
+        Other Parameters
+        ----------------
+        fun_extra_args : input tuple, optional
+            Default: ()
+
+        Returns
+        -------
+        a : int
+
+        Notes
+        -----
+        Call-back functions::
+
+          def fun(): return a
+          Return objects:
+            a : int
+        """
+        assert_equal(self.module.t.__doc__, textwrap.dedent(expected).lstrip())
+
+    def check_function(self, name):
+        t = getattr(self.module, name)
+        r = t(lambda: 4)
+        assert_(r == 4, repr(r))
+        r = t(lambda a: 5, fun_extra_args=(6,))
+        assert_(r == 5, repr(r))
+        r = t(lambda a: a, fun_extra_args=(6,))
+        assert_(r == 6, repr(r))
+        r = t(lambda a: 5 + a, fun_extra_args=(7,))
+        assert_(r == 12, repr(r))
+        r = t(lambda a: math.degrees(a), fun_extra_args=(math.pi,))
+        assert_(r == 180, repr(r))
+        r = t(math.degrees, fun_extra_args=(math.pi,))
+        assert_(r == 180, repr(r))
+
+        r = t(self.module.func, fun_extra_args=(6,))
+        assert_(r == 17, repr(r))
+        r = t(self.module.func0)
+        assert_(r == 11, repr(r))
+        r = t(self.module.func0._cpointer)
+        assert_(r == 11, repr(r))
+
+        class A(object):
+
+            def __call__(self):
+                return 7
+
+            def mth(self):
+                return 9
+        a = A()
+        r = t(a)
+        assert_(r == 7, repr(r))
+        r = t(a.mth)
+        assert_(r == 9, repr(r))
+
+    def test_string_callback(self):
+
+        def callback(code):
+            if code == 'r':
+                return 0
+            else:
+                return 1
+
+        f = getattr(self.module, 'string_callback')
+        r = f(callback)
+        assert_(r == 0, repr(r))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
new file mode 100644
index 0000000000..2552234a15
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
@@ -0,0 +1,36 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_, dec
+from numpy.f2py.crackfortran import (
+    _selected_int_kind_func as selected_int_kind,
+    _selected_real_kind_func as selected_real_kind
+)
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestKind(util.F2PyTest):
+    sources = [_path('src', 'kind', 'foo.f90')]
+
+    @dec.slow
+    def test_all(self):
+        selectedrealkind = self.module.selectedrealkind
+        selectedintkind = self.module.selectedintkind
+
+        for i in range(40):
+            assert_(selectedintkind(i) in [selected_int_kind(i), -1],
+                    'selectedintkind(%s): expected %r but got %r' %
+                    (i, selected_int_kind(i), selectedintkind(i)))
+
+        for i in range(20):
+            assert_(selectedrealkind(i) in [selected_real_kind(i), -1],
+                    'selectedrealkind(%s): expected %r but got %r' %
+                    (i, selected_real_kind(i), selectedrealkind(i)))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
new file mode 100644
index 0000000000..9055083bfc
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
@@ -0,0 +1,40 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import textwrap
+
+from numpy.testing import run_module_suite, assert_, assert_equal, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestMixed(util.F2PyTest):
+    sources = [_path('src', 'mixed', 'foo.f'),
+               _path('src', 'mixed', 'foo_fixed.f90'),
+               _path('src', 'mixed', 'foo_free.f90')]
+
+    @dec.slow
+    def test_all(self):
+        assert_(self.module.bar11() == 11)
+        assert_(self.module.foo_fixed.bar12() == 12)
+        assert_(self.module.foo_free.bar13() == 13)
+
+    @dec.slow
+    def test_docstring(self):
+        expected = """
+        a = bar11()
+
+        Wrapper for ``bar11``.
+
+        Returns
+        -------
+        a : int
+        """
+        assert_equal(self.module.bar11.__doc__,
+                     textwrap.dedent(expected).lstrip())
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
new file mode 100644
index 0000000000..b30af0c4ca
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
@@ -0,0 +1,34 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import math
+
+import numpy as np
+from numpy.testing import dec, assert_raises, assert_equal
+
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestIntentInOut(util.F2PyTest):
+    # Check that intent(in out) translates as intent(inout)
+    sources = [_path('src', 'regression', 'inout.f90')]
+
+    @dec.slow
+    def test_inout(self):
+        # non-contiguous should raise error
+        x = np.arange(6, dtype=np.float32)[::2]
+        assert_raises(ValueError, self.module.foo, x)
+
+        # check values with contiguous array
+        x = np.arange(3, dtype=np.float32)
+        self.module.foo(x)
+        assert_equal(x, [3, 1, 2])
+
+
+if __name__ == "__main__":
+    import nose
+    nose.runmodule()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
new file mode 100644
index 0000000000..e3e2b0d7e4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
@@ -0,0 +1,148 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import asbytes
+from numpy.testing import run_module_suite, assert_, dec
+import util
+
+
+class TestReturnCharacter(util.F2PyTest):
+
+    def check_function(self, t):
+        tname = t.__doc__.split()[0]
+        if tname in ['t0', 't1', 's0', 's1']:
+            assert_(t(23) == asbytes('2'))
+            r = t('ab')
+            assert_(r == asbytes('a'), repr(r))
+            r = t(array('ab'))
+            assert_(r == asbytes('a'), repr(r))
+            r = t(array(77, 'u1'))
+            assert_(r == asbytes('M'), repr(r))
+            #assert_(_raises(ValueError, t, array([77,87])))
+            #assert_(_raises(ValueError, t, array(77)))
+        elif tname in ['ts', 'ss']:
+            assert_(t(23) == asbytes('23        '), repr(t(23)))
+            assert_(t('123456789abcdef') == asbytes('123456789a'))
+        elif tname in ['t5', 's5']:
+            assert_(t(23) == asbytes('23   '), repr(t(23)))
+            assert_(t('ab') == asbytes('ab   '), repr(t('ab')))
+            assert_(t('123456789abcdef') == asbytes('12345'))
+        else:
+            raise NotImplementedError
+
+
+class TestF77ReturnCharacter(TestReturnCharacter):
+    code = """
+       function t0(value)
+         character value
+         character t0
+         t0 = value
+       end
+       function t1(value)
+         character*1 value
+         character*1 t1
+         t1 = value
+       end
+       function t5(value)
+         character*5 value
+         character*5 t5
+         t5 = value
+       end
+       function ts(value)
+         character*(*) value
+         character*(*) ts
+         ts = value
+       end
+
+       subroutine s0(t0,value)
+         character value
+         character t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         character*1 value
+         character*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s5(t5,value)
+         character*5 value
+         character*5 t5
+cf2py    intent(out) t5
+         t5 = value
+       end
+       subroutine ss(ts,value)
+         character*(*) value
+         character*10 ts
+cf2py    intent(out) ts
+         ts = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t5,s0,s1,s5,ss".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnCharacter(TestReturnCharacter):
+    suffix = ".f90"
+    code = """
+module f90_return_char
+  contains
+       function t0(value)
+         character :: value
+         character :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         character(len=1) :: value
+         character(len=1) :: t1
+         t1 = value
+       end function t1
+       function t5(value)
+         character(len=5) :: value
+         character(len=5) :: t5
+         t5 = value
+       end function t5
+       function ts(value)
+         character(len=*) :: value
+         character(len=10) :: ts
+         ts = value
+       end function ts
+
+       subroutine s0(t0,value)
+         character :: value
+         character :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         character(len=1) :: value
+         character(len=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s5(t5,value)
+         character(len=5) :: value
+         character(len=5) :: t5
+!f2py    intent(out) t5
+         t5 = value
+       end subroutine s5
+       subroutine ss(ts,value)
+         character(len=*) :: value
+         character(len=10) :: ts
+!f2py    intent(out) ts
+         ts = value
+       end subroutine ss
+end module f90_return_char
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t5,ts,s0,s1,s5,ss".split(","):
+            self.check_function(getattr(self.module.f90_return_char, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
new file mode 100644
index 0000000000..88ef83e940
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
@@ -0,0 +1,170 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnComplex(util.F2PyTest):
+
+    def check_function(self, t):
+        tname = t.__doc__.split()[0]
+        if tname in ['t0', 't8', 's0', 's8']:
+            err = 1e-5
+        else:
+            err = 0.0
+        assert_(abs(t(234j) - 234.0j) <= err)
+        assert_(abs(t(234.6) - 234.6) <= err)
+        assert_(abs(t(long(234)) - 234.0) <= err)
+        assert_(abs(t(234.6 + 3j) - (234.6 + 3j)) <= err)
+        #assert_( abs(t('234')-234.)<=err)
+        #assert_( abs(t('234.6')-234.6)<=err)
+        assert_(abs(t(-234) + 234.) <= err)
+        assert_(abs(t([234]) - 234.) <= err)
+        assert_(abs(t((234,)) - 234.) <= err)
+        assert_(abs(t(array(234)) - 234.) <= err)
+        assert_(abs(t(array(23 + 4j, 'F')) - (23 + 4j)) <= err)
+        assert_(abs(t(array([234])) - 234.) <= err)
+        assert_(abs(t(array([[234]])) - 234.) <= err)
+        assert_(abs(t(array([234], 'b')) + 22.) <= err)
+        assert_(abs(t(array([234], 'h')) - 234.) <= err)
+        assert_(abs(t(array([234], 'i')) - 234.) <= err)
+        assert_(abs(t(array([234], 'l')) - 234.) <= err)
+        assert_(abs(t(array([234], 'q')) - 234.) <= err)
+        assert_(abs(t(array([234], 'f')) - 234.) <= err)
+        assert_(abs(t(array([234], 'd')) - 234.) <= err)
+        assert_(abs(t(array([234 + 3j], 'F')) - (234 + 3j)) <= err)
+        assert_(abs(t(array([234], 'D')) - 234.) <= err)
+
+        #assert_raises(TypeError, t, array([234], 'a1'))
+        assert_raises(TypeError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(TypeError, t, t)
+        assert_raises(TypeError, t, {})
+
+        try:
+            r = t(10 ** 400)
+            assert_(repr(r) in ['(inf+0j)', '(Infinity+0j)'], repr(r))
+        except OverflowError:
+            pass
+
+
+class TestF77ReturnComplex(TestReturnComplex):
+    code = """
+       function t0(value)
+         complex value
+         complex t0
+         t0 = value
+       end
+       function t8(value)
+         complex*8 value
+         complex*8 t8
+         t8 = value
+       end
+       function t16(value)
+         complex*16 value
+         complex*16 t16
+         t16 = value
+       end
+       function td(value)
+         double complex value
+         double complex td
+         td = value
+       end
+
+       subroutine s0(t0,value)
+         complex value
+         complex t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s8(t8,value)
+         complex*8 value
+         complex*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+       subroutine s16(t16,value)
+         complex*16 value
+         complex*16 t16
+cf2py    intent(out) t16
+         t16 = value
+       end
+       subroutine sd(td,value)
+         double complex value
+         double complex td
+cf2py    intent(out) td
+         td = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnComplex(TestReturnComplex):
+    suffix = ".f90"
+    code = """
+module f90_return_complex
+  contains
+       function t0(value)
+         complex :: value
+         complex :: t0
+         t0 = value
+       end function t0
+       function t8(value)
+         complex(kind=4) :: value
+         complex(kind=4) :: t8
+         t8 = value
+       end function t8
+       function t16(value)
+         complex(kind=8) :: value
+         complex(kind=8) :: t16
+         t16 = value
+       end function t16
+       function td(value)
+         double complex :: value
+         double complex :: td
+         td = value
+       end function td
+
+       subroutine s0(t0,value)
+         complex :: value
+         complex :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s8(t8,value)
+         complex(kind=4) :: value
+         complex(kind=4) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+       subroutine s16(t16,value)
+         complex(kind=8) :: value
+         complex(kind=8) :: t16
+!f2py    intent(out) t16
+         t16 = value
+       end subroutine s16
+       subroutine sd(td,value)
+         double complex :: value
+         double complex :: td
+!f2py    intent(out) td
+         td = value
+       end subroutine sd
+end module f90_return_complex
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
+            self.check_function(getattr(self.module.f90_return_complex, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
new file mode 100644
index 0000000000..00033d6988
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
@@ -0,0 +1,180 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnInteger(util.F2PyTest):
+
+    def check_function(self, t):
+        assert_(t(123) == 123, repr(t(123)))
+        assert_(t(123.6) == 123)
+        assert_(t(long(123)) == 123)
+        assert_(t('123') == 123)
+        assert_(t(-123) == -123)
+        assert_(t([123]) == 123)
+        assert_(t((123,)) == 123)
+        assert_(t(array(123)) == 123)
+        assert_(t(array([123])) == 123)
+        assert_(t(array([[123]])) == 123)
+        assert_(t(array([123], 'b')) == 123)
+        assert_(t(array([123], 'h')) == 123)
+        assert_(t(array([123], 'i')) == 123)
+        assert_(t(array([123], 'l')) == 123)
+        assert_(t(array([123], 'B')) == 123)
+        assert_(t(array([123], 'f')) == 123)
+        assert_(t(array([123], 'd')) == 123)
+
+        #assert_raises(ValueError, t, array([123],'S3'))
+        assert_raises(ValueError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(Exception, t, t)
+        assert_raises(Exception, t, {})
+
+        if t.__doc__.split()[0] in ['t8', 's8']:
+            assert_raises(OverflowError, t, 100000000000000000000000)
+            assert_raises(OverflowError, t, 10000000011111111111111.23)
+
+
+class TestF77ReturnInteger(TestReturnInteger):
+    code = """
+       function t0(value)
+         integer value
+         integer t0
+         t0 = value
+       end
+       function t1(value)
+         integer*1 value
+         integer*1 t1
+         t1 = value
+       end
+       function t2(value)
+         integer*2 value
+         integer*2 t2
+         t2 = value
+       end
+       function t4(value)
+         integer*4 value
+         integer*4 t4
+         t4 = value
+       end
+       function t8(value)
+         integer*8 value
+         integer*8 t8
+         t8 = value
+       end
+
+       subroutine s0(t0,value)
+         integer value
+         integer t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         integer*1 value
+         integer*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s2(t2,value)
+         integer*2 value
+         integer*2 t2
+cf2py    intent(out) t2
+         t2 = value
+       end
+       subroutine s4(t4,value)
+         integer*4 value
+         integer*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+       subroutine s8(t8,value)
+         integer*8 value
+         integer*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnInteger(TestReturnInteger):
+    suffix = ".f90"
+    code = """
+module f90_return_integer
+  contains
+       function t0(value)
+         integer :: value
+         integer :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         integer(kind=1) :: value
+         integer(kind=1) :: t1
+         t1 = value
+       end function t1
+       function t2(value)
+         integer(kind=2) :: value
+         integer(kind=2) :: t2
+         t2 = value
+       end function t2
+       function t4(value)
+         integer(kind=4) :: value
+         integer(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         integer(kind=8) :: value
+         integer(kind=8) :: t8
+         t8 = value
+       end function t8
+
+       subroutine s0(t0,value)
+         integer :: value
+         integer :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         integer(kind=1) :: value
+         integer(kind=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s2(t2,value)
+         integer(kind=2) :: value
+         integer(kind=2) :: t2
+!f2py    intent(out) t2
+         t2 = value
+       end subroutine s2
+       subroutine s4(t4,value)
+         integer(kind=4) :: value
+         integer(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         integer(kind=8) :: value
+         integer(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+end module f90_return_integer
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module.f90_return_integer, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
new file mode 100644
index 0000000000..f88a25d7ae
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
@@ -0,0 +1,189 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnLogical(util.F2PyTest):
+
+    def check_function(self, t):
+        assert_(t(True) == 1, repr(t(True)))
+        assert_(t(False) == 0, repr(t(False)))
+        assert_(t(0) == 0)
+        assert_(t(None) == 0)
+        assert_(t(0.0) == 0)
+        assert_(t(0j) == 0)
+        assert_(t(1j) == 1)
+        assert_(t(234) == 1)
+        assert_(t(234.6) == 1)
+        assert_(t(long(234)) == 1)
+        assert_(t(234.6 + 3j) == 1)
+        assert_(t('234') == 1)
+        assert_(t('aaa') == 1)
+        assert_(t('') == 0)
+        assert_(t([]) == 0)
+        assert_(t(()) == 0)
+        assert_(t({}) == 0)
+        assert_(t(t) == 1)
+        assert_(t(-234) == 1)
+        assert_(t(10 ** 100) == 1)
+        assert_(t([234]) == 1)
+        assert_(t((234,)) == 1)
+        assert_(t(array(234)) == 1)
+        assert_(t(array([234])) == 1)
+        assert_(t(array([[234]])) == 1)
+        assert_(t(array([234], 'b')) == 1)
+        assert_(t(array([234], 'h')) == 1)
+        assert_(t(array([234], 'i')) == 1)
+        assert_(t(array([234], 'l')) == 1)
+        assert_(t(array([234], 'f')) == 1)
+        assert_(t(array([234], 'd')) == 1)
+        assert_(t(array([234 + 3j], 'F')) == 1)
+        assert_(t(array([234], 'D')) == 1)
+        assert_(t(array(0)) == 0)
+        assert_(t(array([0])) == 0)
+        assert_(t(array([[0]])) == 0)
+        assert_(t(array([0j])) == 0)
+        assert_(t(array([1])) == 1)
+        assert_raises(ValueError, t, array([0, 0]))
+
+
+class TestF77ReturnLogical(TestReturnLogical):
+    code = """
+       function t0(value)
+         logical value
+         logical t0
+         t0 = value
+       end
+       function t1(value)
+         logical*1 value
+         logical*1 t1
+         t1 = value
+       end
+       function t2(value)
+         logical*2 value
+         logical*2 t2
+         t2 = value
+       end
+       function t4(value)
+         logical*4 value
+         logical*4 t4
+         t4 = value
+       end
+c       function t8(value)
+c         logical*8 value
+c         logical*8 t8
+c         t8 = value
+c       end
+
+       subroutine s0(t0,value)
+         logical value
+         logical t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         logical*1 value
+         logical*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s2(t2,value)
+         logical*2 value
+         logical*2 t2
+cf2py    intent(out) t2
+         t2 = value
+       end
+       subroutine s4(t4,value)
+         logical*4 value
+         logical*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+c       subroutine s8(t8,value)
+c         logical*8 value
+c         logical*8 t8
+cf2py    intent(out) t8
+c         t8 = value
+c       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,s0,s1,s2,s4".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnLogical(TestReturnLogical):
+    suffix = ".f90"
+    code = """
+module f90_return_logical
+  contains
+       function t0(value)
+         logical :: value
+         logical :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         logical(kind=1) :: value
+         logical(kind=1) :: t1
+         t1 = value
+       end function t1
+       function t2(value)
+         logical(kind=2) :: value
+         logical(kind=2) :: t2
+         t2 = value
+       end function t2
+       function t4(value)
+         logical(kind=4) :: value
+         logical(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         logical(kind=8) :: value
+         logical(kind=8) :: t8
+         t8 = value
+       end function t8
+
+       subroutine s0(t0,value)
+         logical :: value
+         logical :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         logical(kind=1) :: value
+         logical(kind=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s2(t2,value)
+         logical(kind=2) :: value
+         logical(kind=2) :: t2
+!f2py    intent(out) t2
+         t2 = value
+       end subroutine s2
+       subroutine s4(t4,value)
+         logical(kind=4) :: value
+         logical(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         logical(kind=8) :: value
+         logical(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+end module f90_return_logical
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module.f90_return_logical, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
new file mode 100644
index 0000000000..57aa9badff
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
@@ -0,0 +1,206 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnReal(util.F2PyTest):
+
+    def check_function(self, t):
+        if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
+            err = 1e-5
+        else:
+            err = 0.0
+        assert_(abs(t(234) - 234.0) <= err)
+        assert_(abs(t(234.6) - 234.6) <= err)
+        assert_(abs(t(long(234)) - 234.0) <= err)
+        assert_(abs(t('234') - 234) <= err)
+        assert_(abs(t('234.6') - 234.6) <= err)
+        assert_(abs(t(-234) + 234) <= err)
+        assert_(abs(t([234]) - 234) <= err)
+        assert_(abs(t((234,)) - 234.) <= err)
+        assert_(abs(t(array(234)) - 234.) <= err)
+        assert_(abs(t(array([234])) - 234.) <= err)
+        assert_(abs(t(array([[234]])) - 234.) <= err)
+        assert_(abs(t(array([234], 'b')) + 22) <= err)
+        assert_(abs(t(array([234], 'h')) - 234.) <= err)
+        assert_(abs(t(array([234], 'i')) - 234.) <= err)
+        assert_(abs(t(array([234], 'l')) - 234.) <= err)
+        assert_(abs(t(array([234], 'B')) - 234.) <= err)
+        assert_(abs(t(array([234], 'f')) - 234.) <= err)
+        assert_(abs(t(array([234], 'd')) - 234.) <= err)
+        if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
+            assert_(t(1e200) == t(1e300))  # inf
+
+        #assert_raises(ValueError, t, array([234], 'S1'))
+        assert_raises(ValueError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(Exception, t, t)
+        assert_raises(Exception, t, {})
+
+        try:
+            r = t(10 ** 400)
+            assert_(repr(r) in ['inf', 'Infinity'], repr(r))
+        except OverflowError:
+            pass
+
+
+class TestCReturnReal(TestReturnReal):
+    suffix = ".pyf"
+    module_name = "c_ext_return_real"
+    code = """
+python module c_ext_return_real
+usercode \'\'\'
+float t4(float value) { return value; }
+void s4(float *t4, float value) { *t4 = value; }
+double t8(double value) { return value; }
+void s8(double *t8, double value) { *t8 = value; }
+\'\'\'
+interface
+  function t4(value)
+    real*4 intent(c) :: t4,value
+  end
+  function t8(value)
+    real*8 intent(c) :: t8,value
+  end
+  subroutine s4(t4,value)
+    intent(c) s4
+    real*4 intent(out) :: t4
+    real*4 intent(c) :: value
+  end
+  subroutine s8(t8,value)
+    intent(c) s8
+    real*8 intent(out) :: t8
+    real*8 intent(c) :: value
+  end
+end interface
+end python module c_ext_return_real
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t4,t8,s4,s8".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF77ReturnReal(TestReturnReal):
+    code = """
+       function t0(value)
+         real value
+         real t0
+         t0 = value
+       end
+       function t4(value)
+         real*4 value
+         real*4 t4
+         t4 = value
+       end
+       function t8(value)
+         real*8 value
+         real*8 t8
+         t8 = value
+       end
+       function td(value)
+         double precision value
+         double precision td
+         td = value
+       end
+
+       subroutine s0(t0,value)
+         real value
+         real t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s4(t4,value)
+         real*4 value
+         real*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+       subroutine s8(t8,value)
+         real*8 value
+         real*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+       subroutine sd(td,value)
+         double precision value
+         double precision td
+cf2py    intent(out) td
+         td = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnReal(TestReturnReal):
+    suffix = ".f90"
+    code = """
+module f90_return_real
+  contains
+       function t0(value)
+         real :: value
+         real :: t0
+         t0 = value
+       end function t0
+       function t4(value)
+         real(kind=4) :: value
+         real(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         real(kind=8) :: value
+         real(kind=8) :: t8
+         t8 = value
+       end function t8
+       function td(value)
+         double precision :: value
+         double precision :: td
+         td = value
+       end function td
+
+       subroutine s0(t0,value)
+         real :: value
+         real :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s4(t4,value)
+         real(kind=4) :: value
+         real(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         real(kind=8) :: value
+         real(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+       subroutine sd(td,value)
+         double precision :: value
+         double precision :: td
+!f2py    intent(out) td
+         td = value
+       end subroutine sd
+end module f90_return_real
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
+            self.check_function(getattr(self.module.f90_return_real, name))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
new file mode 100644
index 0000000000..aeb70486a6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
@@ -0,0 +1,44 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_equal, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestSizeSumExample(util.F2PyTest):
+    sources = [_path('src', 'size', 'foo.f90')]
+
+    @dec.slow
+    def test_all(self):
+        r = self.module.foo([[1, 2]])
+        assert_equal(r, [3], repr(r))
+
+        r = self.module.foo([[1, 2], [3, 4]])
+        assert_equal(r, [3, 7], repr(r))
+
+        r = self.module.foo([[1, 2], [3, 4], [5, 6]])
+        assert_equal(r, [3, 7, 11], repr(r))
+
+    @dec.slow
+    def test_transpose(self):
+        r = self.module.trans([[1, 2]])
+        assert_equal(r, [[1], [2]], repr(r))
+
+        r = self.module.trans([[1, 2, 3], [4, 5, 6]])
+        assert_equal(r, [[1, 4], [2, 5], [3, 6]], repr(r))
+
+    @dec.slow
+    def test_flatten(self):
+        r = self.module.flatten([[1, 2]])
+        assert_equal(r, [1, 2], repr(r))
+
+        r = self.module.flatten([[1, 2, 3], [4, 5, 6]])
+        assert_equal(r, [1, 2, 3, 4, 5, 6], repr(r))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/util.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/util.py
new file mode 100644
index 0000000000..0c9e91568a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/tests/util.py
@@ -0,0 +1,358 @@
+"""
+Utility functions for
+
+- building and importing modules on test time, using a temporary location
+- detecting if compilers are present
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import subprocess
+import tempfile
+import shutil
+import atexit
+import textwrap
+import re
+import random
+
+from numpy.compat import asbytes, asstr
+import numpy.f2py
+from numpy.testing import SkipTest, temppath
+
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import new as md5
+
+#
+# Maintaining a temporary module directory
+#
+
+_module_dir = None
+
+
+def _cleanup():
+    global _module_dir
+    if _module_dir is not None:
+        try:
+            sys.path.remove(_module_dir)
+        except ValueError:
+            pass
+        try:
+            shutil.rmtree(_module_dir)
+        except (IOError, OSError):
+            pass
+        _module_dir = None
+
+
+def get_module_dir():
+    global _module_dir
+    if _module_dir is None:
+        _module_dir = tempfile.mkdtemp()
+        atexit.register(_cleanup)
+        if _module_dir not in sys.path:
+            sys.path.insert(0, _module_dir)
+    return _module_dir
+
+
+def get_temp_module_name():
+    # Assume single-threaded, and the module dir usable only by this thread
+    d = get_module_dir()
+    for j in range(5403, 9999999):
+        name = "_test_ext_module_%d" % j
+        fn = os.path.join(d, name)
+        if name not in sys.modules and not os.path.isfile(fn + '.py'):
+            return name
+    raise RuntimeError("Failed to create a temporary module name")
+
+
+def _memoize(func):
+    memo = {}
+
+    def wrapper(*a, **kw):
+        key = repr((a, kw))
+        if key not in memo:
+            try:
+                memo[key] = func(*a, **kw)
+            except Exception as e:
+                memo[key] = e
+                raise
+        ret = memo[key]
+        if isinstance(ret, Exception):
+            raise ret
+        return ret
+    wrapper.__name__ = func.__name__
+    return wrapper
+
+#
+# Building modules
+#
+
+
+@_memoize
+def build_module(source_files, options=[], skip=[], only=[], module_name=None):
+    """
+    Compile and import a f2py module, built from the given files.
+
+    """
+
+    code = ("import sys; sys.path = %s; import numpy.f2py as f2py2e; "
+            "f2py2e.main()" % repr(sys.path))
+
+    d = get_module_dir()
+
+    # Copy files
+    dst_sources = []
+    for fn in source_files:
+        if not os.path.isfile(fn):
+            raise RuntimeError("%s is not a file" % fn)
+        dst = os.path.join(d, os.path.basename(fn))
+        shutil.copyfile(fn, dst)
+        dst_sources.append(dst)
+
+        fn = os.path.join(os.path.dirname(fn), '.f2py_f2cmap')
+        if os.path.isfile(fn):
+            dst = os.path.join(d, os.path.basename(fn))
+            if not os.path.isfile(dst):
+                shutil.copyfile(fn, dst)
+
+    # Prepare options
+    if module_name is None:
+        module_name = get_temp_module_name()
+    f2py_opts = ['-c', '-m', module_name] + options + dst_sources
+    if skip:
+        f2py_opts += ['skip:'] + skip
+    if only:
+        f2py_opts += ['only:'] + only
+
+    # Build
+    cwd = os.getcwd()
+    try:
+        os.chdir(d)
+        cmd = [sys.executable, '-c', code] + f2py_opts
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+        if p.returncode != 0:
+            raise RuntimeError("Running f2py failed: %s\n%s"
+                               % (cmd[4:], asstr(out)))
+    finally:
+        os.chdir(cwd)
+
+        # Partial cleanup
+        for fn in dst_sources:
+            os.unlink(fn)
+
+    # Import
+    __import__(module_name)
+    return sys.modules[module_name]
+
+
+@_memoize
+def build_code(source_code, options=[], skip=[], only=[], suffix=None,
+               module_name=None):
+    """
+    Compile and import Fortran code using f2py.
+
+    """
+    if suffix is None:
+        suffix = '.f'
+    with temppath(suffix=suffix) as path:
+        with open(path, 'w') as f:
+            f.write(source_code)
+        return build_module([path], options=options, skip=skip, only=only,
+                            module_name=module_name)
+
+#
+# Check if compilers are available at all...
+#
+
+_compiler_status = None
+
+
+def _get_compiler_status():
+    global _compiler_status
+    if _compiler_status is not None:
+        return _compiler_status
+
+    _compiler_status = (False, False, False)
+
+    # XXX: this is really ugly. But I don't know how to invoke Distutils
+    #      in a safer way...
+    code = """
+import os
+import sys
+sys.path = %(syspath)s
+
+def configuration(parent_name='',top_path=None):
+    global config
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('', parent_name, top_path)
+    return config
+
+from numpy.distutils.core import setup
+setup(configuration=configuration)
+
+config_cmd = config.get_config_cmd()
+have_c = config_cmd.try_compile('void foo() {}')
+print('COMPILERS:%%d,%%d,%%d' %% (have_c,
+                                  config.have_f77c(),
+                                  config.have_f90c()))
+sys.exit(99)
+"""
+    code = code % dict(syspath=repr(sys.path))
+
+    with temppath(suffix='.py') as script:
+        with open(script, 'w') as f:
+            f.write(code)
+
+        cmd = [sys.executable, script, 'config']
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+
+    m = re.search(asbytes(r'COMPILERS:(\d+),(\d+),(\d+)'), out)
+    if m:
+        _compiler_status = (bool(int(m.group(1))), bool(int(m.group(2))),
+                            bool(int(m.group(3))))
+    # Finished
+    return _compiler_status
+
+
+def has_c_compiler():
+    return _get_compiler_status()[0]
+
+
+def has_f77_compiler():
+    return _get_compiler_status()[1]
+
+
+def has_f90_compiler():
+    return _get_compiler_status()[2]
+
+#
+# Building with distutils
+#
+
+
+@_memoize
+def build_module_distutils(source_files, config_code, module_name, **kw):
+    """
+    Build a module via distutils and import it.
+
+    """
+    from numpy.distutils.misc_util import Configuration
+    from numpy.distutils.core import setup
+
+    d = get_module_dir()
+
+    # Copy files
+    dst_sources = []
+    for fn in source_files:
+        if not os.path.isfile(fn):
+            raise RuntimeError("%s is not a file" % fn)
+        dst = os.path.join(d, os.path.basename(fn))
+        shutil.copyfile(fn, dst)
+        dst_sources.append(dst)
+
+    # Build script
+    config_code = textwrap.dedent(config_code).replace("\n", "\n    ")
+
+    code = """\
+import os
+import sys
+sys.path = %(syspath)s
+
+def configuration(parent_name='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('', parent_name, top_path)
+    %(config_code)s
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
+""" % dict(config_code=config_code, syspath=repr(sys.path))
+
+    script = os.path.join(d, get_temp_module_name() + '.py')
+    dst_sources.append(script)
+    f = open(script, 'wb')
+    f.write(asbytes(code))
+    f.close()
+
+    # Build
+    cwd = os.getcwd()
+    try:
+        os.chdir(d)
+        cmd = [sys.executable, script, 'build_ext', '-i']
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+        if p.returncode != 0:
+            raise RuntimeError("Running distutils build failed: %s\n%s"
+                               % (cmd[4:], asstr(out)))
+    finally:
+        os.chdir(cwd)
+
+        # Partial cleanup
+        for fn in dst_sources:
+            os.unlink(fn)
+
+    # Import
+    __import__(module_name)
+    return sys.modules[module_name]
+
+#
+# Unittest convenience
+#
+
+
+class F2PyTest(object):
+    code = None
+    sources = None
+    options = []
+    skip = []
+    only = []
+    suffix = '.f'
+    module = None
+    module_name = None
+
+    def setUp(self):
+        if self.module is not None:
+            return
+
+        # Check compiler availability first
+        if not has_c_compiler():
+            raise SkipTest("No C compiler available")
+
+        codes = []
+        if self.sources:
+            codes.extend(self.sources)
+        if self.code is not None:
+            codes.append(self.suffix)
+
+        needs_f77 = False
+        needs_f90 = False
+        for fn in codes:
+            if fn.endswith('.f'):
+                needs_f77 = True
+            elif fn.endswith('.f90'):
+                needs_f90 = True
+        if needs_f77 and not has_f77_compiler():
+            raise SkipTest("No Fortran 77 compiler available")
+        if needs_f90 and not has_f90_compiler():
+            raise SkipTest("No Fortran 90 compiler available")
+
+        # Build the module
+        if self.code is not None:
+            self.module = build_code(self.code, options=self.options,
+                                     skip=self.skip, only=self.only,
+                                     suffix=self.suffix,
+                                     module_name=self.module_name)
+
+        if self.sources is not None:
+            self.module = build_module(self.sources, options=self.options,
+                                       skip=self.skip, only=self.only,
+                                       module_name=self.module_name)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.py
new file mode 100644
index 0000000000..6acba44e2e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python2
+"""
+
+Build 'use others module data' mechanism for f2py2e.
+
+Unfinished.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2000/09/10 12:35:43 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.3 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+
+from .auxfuncs import (
+    applyrules, dictappend, gentitle, hasnote, outmess
+)
+
+
+usemodule_rules = {
+    'body': """
+#begintitle#
+static char doc_#apiname#[] = \"\\\nVariable wrapper signature:\\n\\
+\t #name# = get_#name#()\\n\\
+Arguments:\\n\\
+#docstr#\";
+extern F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#);
+static PyObject *#apiname#(PyObject *capi_self, PyObject *capi_args) {
+/*#decl#*/
+\tif (!PyArg_ParseTuple(capi_args, \"\")) goto capi_fail;
+printf(\"c: %d\\n\",F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#));
+\treturn Py_BuildValue(\"\");
+capi_fail:
+\treturn NULL;
+}
+""",
+    'method': '\t{\"get_#name#\",#apiname#,METH_VARARGS|METH_KEYWORDS,doc_#apiname#},',
+    'need': ['F_MODFUNC']
+}
+
+################
+
+
+def buildusevars(m, r):
+    ret = {}
+    outmess(
+        '\t\tBuilding use variable hooks for module "%s" (feature only for F90/F95)...\n' % (m['name']))
+    varsmap = {}
+    revmap = {}
+    if 'map' in r:
+        for k in r['map'].keys():
+            if r['map'][k] in revmap:
+                outmess('\t\t\tVariable "%s<=%s" is already mapped by "%s". Skipping.\n' % (
+                    r['map'][k], k, revmap[r['map'][k]]))
+            else:
+                revmap[r['map'][k]] = k
+    if 'only' in r and r['only']:
+        for v in r['map'].keys():
+            if r['map'][v] in m['vars']:
+
+                if revmap[r['map'][v]] == v:
+                    varsmap[v] = r['map'][v]
+                else:
+                    outmess('\t\t\tIgnoring map "%s=>%s". See above.\n' %
+                            (v, r['map'][v]))
+            else:
+                outmess(
+                    '\t\t\tNo definition for variable "%s=>%s". Skipping.\n' % (v, r['map'][v]))
+    else:
+        for v in m['vars'].keys():
+            if v in revmap:
+                varsmap[v] = revmap[v]
+            else:
+                varsmap[v] = v
+    for v in varsmap.keys():
+        ret = dictappend(ret, buildusevar(v, varsmap[v], m['vars'], m['name']))
+    return ret
+
+
+def buildusevar(name, realname, vars, usemodulename):
+    outmess('\t\t\tConstructing wrapper function for variable "%s=>%s"...\n' % (
+        name, realname))
+    ret = {}
+    vrd = {'name': name,
+           'realname': realname,
+           'REALNAME': realname.upper(),
+           'usemodulename': usemodulename,
+           'USEMODULENAME': usemodulename.upper(),
+           'texname': name.replace('_', '\\_'),
+           'begintitle': gentitle('%s=>%s' % (name, realname)),
+           'endtitle': gentitle('end of %s=>%s' % (name, realname)),
+           'apiname': '#modulename#_use_%s_from_%s' % (realname, usemodulename)
+           }
+    nummap = {0: 'Ro', 1: 'Ri', 2: 'Rii', 3: 'Riii', 4: 'Riv',
+              5: 'Rv', 6: 'Rvi', 7: 'Rvii', 8: 'Rviii', 9: 'Rix'}
+    vrd['texnamename'] = name
+    for i in nummap.keys():
+        vrd['texnamename'] = vrd['texnamename'].replace(repr(i), nummap[i])
+    if hasnote(vars[realname]):
+        vrd['note'] = vars[realname]['note']
+    rd = dictappend({}, vrd)
+
+    print(name, realname, vars[realname])
+    ret = applyrules(usemodule_rules, rd)
+    return ret
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/__init__.py
new file mode 100644
index 0000000000..a1f9e90e0a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/__init__.py
@@ -0,0 +1,11 @@
+from __future__ import division, absolute_import, print_function
+
+# To get sub-modules
+from .info import __doc__
+
+from .fftpack import *
+from .helper import *
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.py
new file mode 100644
index 0000000000..275be0d77a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.py
@@ -0,0 +1,1247 @@
+"""
+Discrete Fourier Transforms
+
+Routines in this module:
+
+fft(a, n=None, axis=-1)
+ifft(a, n=None, axis=-1)
+rfft(a, n=None, axis=-1)
+irfft(a, n=None, axis=-1)
+hfft(a, n=None, axis=-1)
+ihfft(a, n=None, axis=-1)
+fftn(a, s=None, axes=None)
+ifftn(a, s=None, axes=None)
+rfftn(a, s=None, axes=None)
+irfftn(a, s=None, axes=None)
+fft2(a, s=None, axes=(-2,-1))
+ifft2(a, s=None, axes=(-2, -1))
+rfft2(a, s=None, axes=(-2,-1))
+irfft2(a, s=None, axes=(-2, -1))
+
+i = inverse transform
+r = transform of purely real data
+h = Hermite transform
+n = n-dimensional transform
+2 = 2-dimensional transform
+(Note: 2D routines are just nD routines with different default
+behavior.)
+
+The underlying code for these functions is an f2c-translated and modified
+version of the FFTPACK routines.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['fft', 'ifft', 'rfft', 'irfft', 'hfft', 'ihfft', 'rfftn',
+           'irfftn', 'rfft2', 'irfft2', 'fft2', 'ifft2', 'fftn', 'ifftn']
+
+from numpy.core import (array, asarray, zeros, swapaxes, shape, conjugate,
+                        take, sqrt)
+from . import fftpack_lite as fftpack
+
+_fft_cache = {}
+_real_fft_cache = {}
+
+
+def _raw_fft(a, n=None, axis=-1, init_function=fftpack.cffti,
+             work_function=fftpack.cfftf, fft_cache=_fft_cache):
+    a = asarray(a)
+
+    if n is None:
+        n = a.shape[axis]
+
+    if n < 1:
+        raise ValueError("Invalid number of FFT data points (%d) specified."
+                         % n)
+
+    try:
+        # Thread-safety note: We rely on list.pop() here to atomically
+        # retrieve-and-remove a wsave from the cache.  This ensures that no
+        # other thread can get the same wsave while we're using it.
+        wsave = fft_cache.setdefault(n, []).pop()
+    except (IndexError):
+        wsave = init_function(n)
+
+    if a.shape[axis] != n:
+        s = list(a.shape)
+        if s[axis] > n:
+            index = [slice(None)]*len(s)
+            index[axis] = slice(0, n)
+            a = a[index]
+        else:
+            index = [slice(None)]*len(s)
+            index[axis] = slice(0, s[axis])
+            s[axis] = n
+            z = zeros(s, a.dtype.char)
+            z[index] = a
+            a = z
+
+    if axis != -1:
+        a = swapaxes(a, axis, -1)
+    r = work_function(a, wsave)
+    if axis != -1:
+        r = swapaxes(r, axis, -1)
+
+    # As soon as we put wsave back into the cache, another thread could pick it
+    # up and start using it, so we must not do this until after we're
+    # completely done using it ourselves.
+    fft_cache[n].append(wsave)
+
+    return r
+
+
+def _unitary(norm):
+    if norm not in (None, "ortho"):
+        raise ValueError("Invalid norm value %s, should be None or \"ortho\"."
+                         % norm)
+    return norm is not None
+
+
+def fft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional discrete Fourier Transform.
+
+    This function computes the one-dimensional *n*-point discrete Fourier
+    Transform (DFT) with the efficient Fast Fourier Transform (FFT)
+    algorithm [CT].
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    n : int, optional
+        Length of the transformed axis of the output.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros.  If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the FFT.  If not given, the last axis is
+        used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+
+    Raises
+    ------
+    IndexError
+        if `axes` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : for definition of the DFT and conventions used.
+    ifft : The inverse of `fft`.
+    fft2 : The two-dimensional FFT.
+    fftn : The *n*-dimensional FFT.
+    rfftn : The *n*-dimensional FFT of real input.
+    fftfreq : Frequency bins for given FFT parameters.
+
+    Notes
+    -----
+    FFT (Fast Fourier Transform) refers to a way the discrete Fourier
+    Transform (DFT) can be calculated efficiently, by using symmetries in the
+    calculated terms.  The symmetry is highest when `n` is a power of 2, and
+    the transform is therefore most efficient for these sizes.
+
+    The DFT is defined, with the conventions used in this implementation, in
+    the documentation for the `numpy.fft` module.
+
+    References
+    ----------
+    .. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the
+            machine calculation of complex Fourier series," *Math. Comput.*
+            19: 297-301.
+
+    Examples
+    --------
+    >>> np.fft.fft(np.exp(2j * np.pi * np.arange(8) / 8))
+    array([ -3.44505240e-16 +1.14383329e-17j,
+             8.00000000e+00 -5.71092652e-15j,
+             2.33482938e-16 +1.22460635e-16j,
+             1.64863782e-15 +1.77635684e-15j,
+             9.95839695e-17 +2.33482938e-16j,
+             0.00000000e+00 +1.66837030e-15j,
+             1.14383329e-17 +1.22460635e-16j,
+             -1.64863782e-15 +1.77635684e-15j])
+
+    >>> import matplotlib.pyplot as plt
+    >>> t = np.arange(256)
+    >>> sp = np.fft.fft(np.sin(t))
+    >>> freq = np.fft.fftfreq(t.shape[-1])
+    >>> plt.plot(freq, sp.real, freq, sp.imag)
+    [<matplotlib.lines.Line2D object at 0x...>, <matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.show()
+
+    In this example, real input has an FFT which is Hermitian, i.e., symmetric
+    in the real part and anti-symmetric in the imaginary part, as described in
+    the `numpy.fft` documentation.
+
+    """
+
+    a = asarray(a).astype(complex, copy=False)
+    if n is None:
+        n = a.shape[axis]
+    output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftf, _fft_cache)
+    if _unitary(norm):
+        output *= 1 / sqrt(n)
+    return output
+
+
+def ifft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the one-dimensional *n*-point
+    discrete Fourier transform computed by `fft`.  In other words,
+    ``ifft(fft(a)) == a`` to within numerical accuracy.
+    For a general description of the algorithm and definitions,
+    see `numpy.fft`.
+
+    The input should be ordered in the same way as is returned by `fft`,
+    i.e.,
+
+    * ``a[0]`` should contain the zero frequency term,
+    * ``a[1:n//2]`` should contain the positive-frequency terms,
+    * ``a[n//2 + 1:]`` should contain the negative-frequency terms, in
+      increasing order starting from the most negative frequency.
+
+    For an even number of input points, ``A[n//2]`` represents the sum of
+    the values at the positive and negative Nyquist frequencies, as the two
+    are aliased together. See `numpy.fft` for details.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    n : int, optional
+        Length of the transformed axis of the output.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros.  If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+        See notes about padding issues.
+    axis : int, optional
+        Axis over which to compute the inverse DFT.  If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+
+    Raises
+    ------
+    IndexError
+        If `axes` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : An introduction, with definitions and general explanations.
+    fft : The one-dimensional (forward) FFT, of which `ifft` is the inverse
+    ifft2 : The two-dimensional inverse FFT.
+    ifftn : The n-dimensional inverse FFT.
+
+    Notes
+    -----
+    If the input parameter `n` is larger than the size of the input, the input
+    is padded by appending zeros at the end.  Even though this is the common
+    approach, it might lead to surprising results.  If a different padding is
+    desired, it must be performed before calling `ifft`.
+
+    Examples
+    --------
+    >>> np.fft.ifft([0, 4, 0, 0])
+    array([ 1.+0.j,  0.+1.j, -1.+0.j,  0.-1.j])
+
+    Create and plot a band-limited signal with random phases:
+
+    >>> import matplotlib.pyplot as plt
+    >>> t = np.arange(400)
+    >>> n = np.zeros((400,), dtype=complex)
+    >>> n[40:60] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20,)))
+    >>> s = np.fft.ifft(n)
+    >>> plt.plot(t, s.real, 'b-', t, s.imag, 'r--')
+    ...
+    >>> plt.legend(('real', 'imaginary'))
+    ...
+    >>> plt.show()
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = a.shape[axis]
+    unitary = _unitary(norm)
+    output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftb, _fft_cache)
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def rfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional discrete Fourier Transform for real input.
+
+    This function computes the one-dimensional *n*-point discrete Fourier
+    Transform (DFT) of a real-valued array by means of an efficient algorithm
+    called the Fast Fourier Transform (FFT).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+    n : int, optional
+        Number of points along transformation axis in the input to use.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros. If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the FFT. If not given, the last axis is
+        used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        If `n` is even, the length of the transformed axis is ``(n/2)+1``.
+        If `n` is odd, the length is ``(n+1)/2``.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : For definition of the DFT and conventions used.
+    irfft : The inverse of `rfft`.
+    fft : The one-dimensional FFT of general (complex) input.
+    fftn : The *n*-dimensional FFT.
+    rfftn : The *n*-dimensional FFT of real input.
+
+    Notes
+    -----
+    When the DFT is computed for purely real input, the output is
+    Hermitian-symmetric, i.e. the negative frequency terms are just the complex
+    conjugates of the corresponding positive-frequency terms, and the
+    negative-frequency terms are therefore redundant.  This function does not
+    compute the negative frequency terms, and the length of the transformed
+    axis of the output is therefore ``n//2 + 1``.
+
+    When ``A = rfft(a)`` and fs is the sampling frequency, ``A[0]`` contains
+    the zero-frequency term 0*fs, which is real due to Hermitian symmetry.
+
+    If `n` is even, ``A[-1]`` contains the term representing both positive
+    and negative Nyquist frequency (+fs/2 and -fs/2), and must also be purely
+    real. If `n` is odd, there is no term at fs/2; ``A[-1]`` contains
+    the largest positive frequency (fs/2*(n-1)/n), and is complex in the
+    general case.
+
+    If the input `a` contains an imaginary part, it is silently discarded.
+
+    Examples
+    --------
+    >>> np.fft.fft([0, 1, 0, 0])
+    array([ 1.+0.j,  0.-1.j, -1.+0.j,  0.+1.j])
+    >>> np.fft.rfft([0, 1, 0, 0])
+    array([ 1.+0.j,  0.-1.j, -1.+0.j])
+
+    Notice how the final element of the `fft` output is the complex conjugate
+    of the second element, for real input. For `rfft`, this symmetry is
+    exploited to compute only the non-negative frequency terms.
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftf,
+                      _real_fft_cache)
+    if _unitary(norm):
+        output *= 1 / sqrt(a.shape[axis])
+    return output
+
+
+def irfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the inverse of the n-point DFT for real input.
+
+    This function computes the inverse of the one-dimensional *n*-point
+    discrete Fourier Transform of real input computed by `rfft`.
+    In other words, ``irfft(rfft(a), len(a)) == a`` to within numerical
+    accuracy. (See Notes below for why ``len(a)`` is necessary here.)
+
+    The input is expected to be in the form returned by `rfft`, i.e. the
+    real zero-frequency term followed by the complex positive frequency terms
+    in order of increasing frequency.  Since the discrete Fourier Transform of
+    real input is Hermitian-symmetric, the negative frequency terms are taken
+    to be the complex conjugates of the corresponding positive frequency terms.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    n : int, optional
+        Length of the transformed axis of the output.
+        For `n` output points, ``n//2+1`` input points are necessary.  If the
+        input is longer than this, it is cropped.  If it is shorter than this,
+        it is padded with zeros.  If `n` is not given, it is determined from
+        the length of the input along the axis specified by `axis`.
+    axis : int, optional
+        Axis over which to compute the inverse FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        The length of the transformed axis is `n`, or, if `n` is not given,
+        ``2*(m-1)`` where ``m`` is the length of the transformed axis of the
+        input. To get an odd number of output points, `n` must be specified.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : For definition of the DFT and conventions used.
+    rfft : The one-dimensional FFT of real input, of which `irfft` is inverse.
+    fft : The one-dimensional FFT.
+    irfft2 : The inverse of the two-dimensional FFT of real input.
+    irfftn : The inverse of the *n*-dimensional FFT of real input.
+
+    Notes
+    -----
+    Returns the real valued `n`-point inverse discrete Fourier transform
+    of `a`, where `a` contains the non-negative frequency terms of a
+    Hermitian-symmetric sequence. `n` is the length of the result, not the
+    input.
+
+    If you specify an `n` such that `a` must be zero-padded or truncated, the
+    extra/removed values will be added/removed at high frequencies. One can
+    thus resample a series to `m` points via Fourier interpolation by:
+    ``a_resamp = irfft(rfft(a), m)``.
+
+    Examples
+    --------
+    >>> np.fft.ifft([1, -1j, -1, 1j])
+    array([ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j])
+    >>> np.fft.irfft([1, -1j, -1])
+    array([ 0.,  1.,  0.,  0.])
+
+    Notice how the last term in the input to the ordinary `ifft` is the
+    complex conjugate of the second term, and the output has zero imaginary
+    part everywhere.  When calling `irfft`, the negative frequencies are not
+    specified, and the output array is purely real.
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = (a.shape[axis] - 1) * 2
+    unitary = _unitary(norm)
+    output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftb,
+                      _real_fft_cache)
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def hfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the FFT of a signal which has Hermitian symmetry (real spectrum).
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    n : int, optional
+        Length of the transformed axis of the output.
+        For `n` output points, ``n//2+1`` input points are necessary.  If the
+        input is longer than this, it is cropped.  If it is shorter than this,
+        it is padded with zeros.  If `n` is not given, it is determined from
+        the length of the input along the axis specified by `axis`.
+    axis : int, optional
+        Axis over which to compute the FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        The length of the transformed axis is `n`, or, if `n` is not given,
+        ``2*(m-1)`` where ``m`` is the length of the transformed axis of the
+        input. To get an odd number of output points, `n` must be specified.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See also
+    --------
+    rfft : Compute the one-dimensional FFT for real input.
+    ihfft : The inverse of `hfft`.
+
+    Notes
+    -----
+    `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
+    opposite case: here the signal has Hermitian symmetry in the time domain
+    and is real in the frequency domain. So here it's `hfft` for which
+    you must supply the length of the result if it is to be odd:
+    ``ihfft(hfft(a), len(a)) == a``, within numerical accuracy.
+
+    Examples
+    --------
+    >>> signal = np.array([1, 2, 3, 4, 3, 2])
+    >>> np.fft.fft(signal)
+    array([ 15.+0.j,  -4.+0.j,   0.+0.j,  -1.-0.j,   0.+0.j,  -4.+0.j])
+    >>> np.fft.hfft(signal[:4]) # Input first half of signal
+    array([ 15.,  -4.,   0.,  -1.,   0.,  -4.])
+    >>> np.fft.hfft(signal, 6)  # Input entire signal and truncate
+    array([ 15.,  -4.,   0.,  -1.,   0.,  -4.])
+
+
+    >>> signal = np.array([[1, 1.j], [-1.j, 2]])
+    >>> np.conj(signal.T) - signal   # check Hermitian symmetry
+    array([[ 0.-0.j,  0.+0.j],
+           [ 0.+0.j,  0.-0.j]])
+    >>> freq_spectrum = np.fft.hfft(signal)
+    >>> freq_spectrum
+    array([[ 1.,  1.],
+           [ 2., -2.]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = (a.shape[axis] - 1) * 2
+    unitary = _unitary(norm)
+    return irfft(conjugate(a), n, axis) * (sqrt(n) if unitary else n)
+
+
+def ihfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the inverse FFT of a signal which has Hermitian symmetry.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    n : int, optional
+        Length of the inverse FFT.
+        Number of points along transformation axis in the input to use.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros. If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the inverse FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        If `n` is even, the length of the transformed axis is ``(n/2)+1``.
+        If `n` is odd, the length is ``(n+1)/2``.
+
+    See also
+    --------
+    hfft, irfft
+
+    Notes
+    -----
+    `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
+    opposite case: here the signal has Hermitian symmetry in the time domain
+    and is real in the frequency domain. So here it's `hfft` for which
+    you must supply the length of the result if it is to be odd:
+    ``ihfft(hfft(a), len(a)) == a``, within numerical accuracy.
+
+    Examples
+    --------
+    >>> spectrum = np.array([ 15, -4, 0, -1, 0, -4])
+    >>> np.fft.ifft(spectrum)
+    array([ 1.+0.j,  2.-0.j,  3.+0.j,  4.+0.j,  3.+0.j,  2.-0.j])
+    >>> np.fft.ihfft(spectrum)
+    array([ 1.-0.j,  2.-0.j,  3.-0.j,  4.-0.j])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    if n is None:
+        n = a.shape[axis]
+    unitary = _unitary(norm)
+    output = conjugate(rfft(a, n, axis))
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def _cook_nd_args(a, s=None, axes=None, invreal=0):
+    if s is None:
+        shapeless = 1
+        if axes is None:
+            s = list(a.shape)
+        else:
+            s = take(a.shape, axes)
+    else:
+        shapeless = 0
+    s = list(s)
+    if axes is None:
+        axes = list(range(-len(s), 0))
+    if len(s) != len(axes):
+        raise ValueError("Shape and axes have different lengths.")
+    if invreal and shapeless:
+        s[-1] = (a.shape[axes[-1]] - 1) * 2
+    return s, axes
+
+
+def _raw_fftnd(a, s=None, axes=None, function=fft, norm=None):
+    a = asarray(a)
+    s, axes = _cook_nd_args(a, s, axes)
+    itl = list(range(len(axes)))
+    itl.reverse()
+    for ii in itl:
+        a = function(a, n=s[ii], axis=axes[ii], norm=norm)
+    return a
+
+
+def fftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional discrete Fourier Transform.
+
+    This function computes the *N*-dimensional discrete Fourier Transform over
+    any number of axes in an *M*-dimensional array by means of the Fast Fourier
+    Transform (FFT).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (`s[0]` refers to axis 0, `s[1]` to axis 1, etc.).
+        This corresponds to `n` for `fft(x, n)`.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the transform over that axis is
+        performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` and `a`,
+        as explained in the parameters section above.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+        and conventions used.
+    ifftn : The inverse of `fftn`, the inverse *n*-dimensional FFT.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    rfftn : The *n*-dimensional FFT of real input.
+    fft2 : The two-dimensional FFT.
+    fftshift : Shifts zero-frequency terms to centre of array
+
+    Notes
+    -----
+    The output, analogously to `fft`, contains the term for zero frequency in
+    the low-order corner of all axes, the positive frequency terms in the
+    first half of all axes, the term for the Nyquist frequency in the middle
+    of all axes and the negative frequency terms in the second half of all
+    axes, in order of decreasingly negative frequency.
+
+    See `numpy.fft` for details, definitions and conventions used.
+
+    Examples
+    --------
+    >>> a = np.mgrid[:3, :3, :3][0]
+    >>> np.fft.fftn(a, axes=(1, 2))
+    array([[[  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]],
+           [[  9.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]],
+           [[ 18.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]]])
+    >>> np.fft.fftn(a, (2, 2), axes=(0, 1))
+    array([[[ 2.+0.j,  2.+0.j,  2.+0.j],
+            [ 0.+0.j,  0.+0.j,  0.+0.j]],
+           [[-2.+0.j, -2.+0.j, -2.+0.j],
+            [ 0.+0.j,  0.+0.j,  0.+0.j]]])
+
+    >>> import matplotlib.pyplot as plt
+    >>> [X, Y] = np.meshgrid(2 * np.pi * np.arange(200) / 12,
+    ...                      2 * np.pi * np.arange(200) / 34)
+    >>> S = np.sin(X) + np.cos(Y) + np.random.uniform(0, 1, X.shape)
+    >>> FS = np.fft.fftn(S)
+    >>> plt.imshow(np.log(np.abs(np.fft.fftshift(FS))**2))
+    <matplotlib.image.AxesImage object at 0x...>
+    >>> plt.show()
+
+    """
+
+    return _raw_fftnd(a, s, axes, fft, norm)
+
+
+def ifftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the N-dimensional discrete
+    Fourier Transform over any number of axes in an M-dimensional array by
+    means of the Fast Fourier Transform (FFT).  In other words,
+    ``ifftn(fftn(a)) == a`` to within numerical accuracy.
+    For a description of the definitions and conventions used, see `numpy.fft`.
+
+    The input, analogously to `ifft`, should be ordered in the same way as is
+    returned by `fftn`, i.e. it should have the term for zero frequency
+    in all axes in the low-order corner, the positive frequency terms in the
+    first half of all axes, the term for the Nyquist frequency in the middle
+    of all axes and the negative frequency terms in the second half of all
+    axes, in order of decreasingly negative frequency.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
+        This corresponds to ``n`` for ``ifft(x, n)``.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.  See notes for issue on `ifft` zero padding.
+    axes : sequence of ints, optional
+        Axes over which to compute the IFFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the inverse transform over that
+        axis is performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` or `a`,
+        as explained in the parameters section above.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    fftn : The forward *n*-dimensional FFT, of which `ifftn` is the inverse.
+    ifft : The one-dimensional inverse FFT.
+    ifft2 : The two-dimensional inverse FFT.
+    ifftshift : Undoes `fftshift`, shifts zero-frequency terms to beginning
+        of array.
+
+    Notes
+    -----
+    See `numpy.fft` for definitions and conventions used.
+
+    Zero-padding, analogously with `ifft`, is performed by appending zeros to
+    the input along the specified dimension.  Although this is the common
+    approach, it might lead to surprising results.  If another form of zero
+    padding is desired, it must be performed before `ifftn` is called.
+
+    Examples
+    --------
+    >>> a = np.eye(4)
+    >>> np.fft.ifftn(np.fft.fftn(a, axes=(0,)), axes=(1,))
+    array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j]])
+
+
+    Create and plot an image with band-limited frequency content:
+
+    >>> import matplotlib.pyplot as plt
+    >>> n = np.zeros((200,200), dtype=complex)
+    >>> n[60:80, 20:40] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20, 20)))
+    >>> im = np.fft.ifftn(n).real
+    >>> plt.imshow(im)
+    <matplotlib.image.AxesImage object at 0x...>
+    >>> plt.show()
+
+    """
+
+    return _raw_fftnd(a, s, axes, ifft, norm)
+
+
+def fft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional discrete Fourier Transform
+
+    This function computes the *n*-dimensional discrete Fourier Transform
+    over any axes in an *M*-dimensional array by means of the
+    Fast Fourier Transform (FFT).  By default, the transform is computed over
+    the last two axes of the input array, i.e., a 2-dimensional FFT.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (`s[0]` refers to axis 0, `s[1]` to axis 1, etc.).
+        This corresponds to `n` for `fft(x, n)`.
+        Along each axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last two
+        axes are used.  A repeated index in `axes` means the transform over
+        that axis is performed multiple times.  A one-element sequence means
+        that a one-dimensional FFT is performed.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or the last two axes if `axes` is not given.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length, or `axes` not given and
+        ``len(s) != 2``.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    ifft2 : The inverse two-dimensional FFT.
+    fft : The one-dimensional FFT.
+    fftn : The *n*-dimensional FFT.
+    fftshift : Shifts zero-frequency terms to the center of the array.
+        For two-dimensional input, swaps first and third quadrants, and second
+        and fourth quadrants.
+
+    Notes
+    -----
+    `fft2` is just `fftn` with a different default for `axes`.
+
+    The output, analogously to `fft`, contains the term for zero frequency in
+    the low-order corner of the transformed axes, the positive frequency terms
+    in the first half of these axes, the term for the Nyquist frequency in the
+    middle of the axes and the negative frequency terms in the second half of
+    the axes, in order of decreasingly negative frequency.
+
+    See `fftn` for details and a plotting example, and `numpy.fft` for
+    definitions and conventions used.
+
+
+    Examples
+    --------
+    >>> a = np.mgrid[:5, :5][0]
+    >>> np.fft.fft2(a)
+    array([[ 50.0 +0.j        ,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5+17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5 +4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5 -4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
+                0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5-17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ]])
+
+    """
+
+    return _raw_fftnd(a, s, axes, fft, norm)
+
+
+def ifft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the 2-dimensional discrete Fourier
+    Transform over any number of axes in an M-dimensional array by means of
+    the Fast Fourier Transform (FFT).  In other words, ``ifft2(fft2(a)) == a``
+    to within numerical accuracy.  By default, the inverse transform is
+    computed over the last two axes of the input array.
+
+    The input, analogously to `ifft`, should be ordered in the same way as is
+    returned by `fft2`, i.e. it should have the term for zero frequency
+    in the low-order corner of the two axes, the positive frequency terms in
+    the first half of these axes, the term for the Nyquist frequency in the
+    middle of the axes and the negative frequency terms in the second half of
+    both axes, in order of decreasingly negative frequency.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each axis) of the output (``s[0]`` refers to axis 0,
+        ``s[1]`` to axis 1, etc.).  This corresponds to `n` for ``ifft(x, n)``.
+        Along each axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.  See notes for issue on `ifft` zero padding.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last two
+        axes are used.  A repeated index in `axes` means the transform over
+        that axis is performed multiple times.  A one-element sequence means
+        that a one-dimensional FFT is performed.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or the last two axes if `axes` is not given.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length, or `axes` not given and
+        ``len(s) != 2``.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    fft2 : The forward 2-dimensional FFT, of which `ifft2` is the inverse.
+    ifftn : The inverse of the *n*-dimensional FFT.
+    fft : The one-dimensional FFT.
+    ifft : The one-dimensional inverse FFT.
+
+    Notes
+    -----
+    `ifft2` is just `ifftn` with a different default for `axes`.
+
+    See `ifftn` for details and a plotting example, and `numpy.fft` for
+    definition and conventions used.
+
+    Zero-padding, analogously with `ifft`, is performed by appending zeros to
+    the input along the specified dimension.  Although this is the common
+    approach, it might lead to surprising results.  If another form of zero
+    padding is desired, it must be performed before `ifft2` is called.
+
+    Examples
+    --------
+    >>> a = 4 * np.eye(4)
+    >>> np.fft.ifft2(a)
+    array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j],
+           [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
+           [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j]])
+
+    """
+
+    return _raw_fftnd(a, s, axes, ifft, norm)
+
+
+def rfftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional discrete Fourier Transform for real input.
+
+    This function computes the N-dimensional discrete Fourier Transform over
+    any number of axes in an M-dimensional real array by means of the Fast
+    Fourier Transform (FFT).  By default, all axes are transformed, with the
+    real transform performed over the last axis, while the remaining
+    transforms are complex.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, taken to be real.
+    s : sequence of ints, optional
+        Shape (length along each transformed axis) to use from the input.
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
+        The final element of `s` corresponds to `n` for ``rfft(x, n)``, while
+        for the remaining axes, it corresponds to `n` for ``fft(x, n)``.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` and `a`,
+        as explained in the parameters section above.
+        The length of the last axis transformed will be ``s[-1]//2+1``,
+        while the remaining transformed axes will have lengths according to
+        `s`, or unchanged from the input.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    irfftn : The inverse of `rfftn`, i.e. the inverse of the n-dimensional FFT
+         of real input.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    rfft : The one-dimensional FFT of real input.
+    fftn : The n-dimensional FFT.
+    rfft2 : The two-dimensional FFT of real input.
+
+    Notes
+    -----
+    The transform for real input is performed over the last transformation
+    axis, as by `rfft`, then the transform over the remaining axes is
+    performed as by `fftn`.  The order of the output is as for `rfft` for the
+    final transformation axis, and as for `fftn` for the remaining
+    transformation axes.
+
+    See `fft` for details, definitions and conventions used.
+
+    Examples
+    --------
+    >>> a = np.ones((2, 2, 2))
+    >>> np.fft.rfftn(a)
+    array([[[ 8.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]],
+           [[ 0.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]]])
+
+    >>> np.fft.rfftn(a, axes=(2, 0))
+    array([[[ 4.+0.j,  0.+0.j],
+            [ 4.+0.j,  0.+0.j]],
+           [[ 0.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    s, axes = _cook_nd_args(a, s, axes)
+    a = rfft(a, s[-1], axes[-1], norm)
+    for ii in range(len(axes)-1):
+        a = fft(a, s[ii], axes[ii], norm)
+    return a
+
+
+def rfft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional FFT of a real array.
+
+    Parameters
+    ----------
+    a : array
+        Input array, taken to be real.
+    s : sequence of ints, optional
+        Shape of the FFT.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The result of the real 2-D FFT.
+
+    See Also
+    --------
+    rfftn : Compute the N-dimensional discrete Fourier Transform for real
+            input.
+
+    Notes
+    -----
+    This is really just `rfftn` with different default behavior.
+    For more details see `rfftn`.
+
+    """
+
+    return rfftn(a, s, axes, norm)
+
+
+def irfftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the inverse of the N-dimensional FFT of real input.
+
+    This function computes the inverse of the N-dimensional discrete
+    Fourier Transform for real input over any number of axes in an
+    M-dimensional array by means of the Fast Fourier Transform (FFT).  In
+    other words, ``irfftn(rfftn(a), a.shape) == a`` to within numerical
+    accuracy. (The ``a.shape`` is necessary like ``len(a)`` is for `irfft`,
+    and for the same reason.)
+
+    The input should be ordered in the same way as is returned by `rfftn`,
+    i.e. as for `irfft` for the final transformation axis, and as for `ifftn`
+    along all the other axes.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the
+        number of input points used along this axis, except for the last axis,
+        where ``s[-1]//2+1`` points of the input are used.
+        Along any axis, if the shape indicated by `s` is smaller than that of
+        the input, the input is cropped.  If it is larger, the input is padded
+        with zeros. If `s` is not given, the shape of the input along the
+        axes specified by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the inverse FFT. If not given, the last
+        `len(s)` axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the inverse transform over that
+        axis is performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` or `a`,
+        as explained in the parameters section above.
+        The length of each transformed axis is as given by the corresponding
+        element of `s`, or the length of the input in every axis except for the
+        last one if `s` is not given.  In the final transformed axis the length
+        of the output when `s` is not given is ``2*(m-1)`` where ``m`` is the
+        length of the final transformed axis of the input.  To get an odd
+        number of output points in the final axis, `s` must be specified.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    rfftn : The forward n-dimensional FFT of real input,
+            of which `ifftn` is the inverse.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    irfft : The inverse of the one-dimensional FFT of real input.
+    irfft2 : The inverse of the two-dimensional FFT of real input.
+
+    Notes
+    -----
+    See `fft` for definitions and conventions used.
+
+    See `rfft` for definitions and conventions used for real input.
+
+    Examples
+    --------
+    >>> a = np.zeros((3, 2, 2))
+    >>> a[0, 0, 0] = 3 * 2 * 2
+    >>> np.fft.irfftn(a)
+    array([[[ 1.,  1.],
+            [ 1.,  1.]],
+           [[ 1.,  1.],
+            [ 1.,  1.]],
+           [[ 1.,  1.],
+            [ 1.,  1.]]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    s, axes = _cook_nd_args(a, s, axes, invreal=1)
+    for ii in range(len(axes)-1):
+        a = ifft(a, s[ii], axes[ii], norm)
+    a = irfft(a, s[-1], axes[-1], norm)
+    return a
+
+
+def irfft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional inverse FFT of a real array.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array
+    s : sequence of ints, optional
+        Shape of the inverse FFT.
+    axes : sequence of ints, optional
+        The axes over which to compute the inverse fft.
+        Default is the last two axes.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The result of the inverse real 2-D FFT.
+
+    See Also
+    --------
+    irfftn : Compute the inverse of the N-dimensional FFT of real input.
+
+    Notes
+    -----
+    This is really `irfftn` with different defaults.
+    For more details see `irfftn`.
+
+    """
+
+    return irfftn(a, s, axes, norm)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..ac9e02952ea4c12833ce5936798d193eb92dc708
GIT binary patch
literal 44032
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
LF%STYFyH|I{w+8m

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/helper.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/helper.py
new file mode 100644
index 0000000000..160120e585
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/helper.py
@@ -0,0 +1,224 @@
+"""
+Discrete Fourier Transforms - helper.py
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.compat import integer_types
+from numpy.core import (
+        asarray, concatenate, arange, take, integer, empty
+        )
+
+# Created by Pearu Peterson, September 2002
+
+__all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq']
+
+integer_types = integer_types + (integer,)
+
+
+def fftshift(x, axes=None):
+    """
+    Shift the zero-frequency component to the center of the spectrum.
+
+    This function swaps half-spaces for all axes listed (defaults to all).
+    Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+    axes : int or shape tuple, optional
+        Axes over which to shift.  Default is None, which shifts all axes.
+
+    Returns
+    -------
+    y : ndarray
+        The shifted array.
+
+    See Also
+    --------
+    ifftshift : The inverse of `fftshift`.
+
+    Examples
+    --------
+    >>> freqs = np.fft.fftfreq(10, 0.1)
+    >>> freqs
+    array([ 0.,  1.,  2.,  3.,  4., -5., -4., -3., -2., -1.])
+    >>> np.fft.fftshift(freqs)
+    array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
+
+    Shift the zero-frequency component only along the second axis:
+
+    >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
+    >>> freqs
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+    >>> np.fft.fftshift(freqs, axes=(1,))
+    array([[ 2.,  0.,  1.],
+           [-4.,  3.,  4.],
+           [-1., -3., -2.]])
+
+    """
+    tmp = asarray(x)
+    ndim = len(tmp.shape)
+    if axes is None:
+        axes = list(range(ndim))
+    elif isinstance(axes, integer_types):
+        axes = (axes,)
+    y = tmp
+    for k in axes:
+        n = tmp.shape[k]
+        p2 = (n+1)//2
+        mylist = concatenate((arange(p2, n), arange(p2)))
+        y = take(y, mylist, k)
+    return y
+
+
+def ifftshift(x, axes=None):
+    """
+    The inverse of `fftshift`. Although identical for even-length `x`, the
+    functions differ by one sample for odd-length `x`.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+    axes : int or shape tuple, optional
+        Axes over which to calculate.  Defaults to None, which shifts all axes.
+
+    Returns
+    -------
+    y : ndarray
+        The shifted array.
+
+    See Also
+    --------
+    fftshift : Shift zero-frequency component to the center of the spectrum.
+
+    Examples
+    --------
+    >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
+    >>> freqs
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+    >>> np.fft.ifftshift(np.fft.fftshift(freqs))
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+
+    """
+    tmp = asarray(x)
+    ndim = len(tmp.shape)
+    if axes is None:
+        axes = list(range(ndim))
+    elif isinstance(axes, integer_types):
+        axes = (axes,)
+    y = tmp
+    for k in axes:
+        n = tmp.shape[k]
+        p2 = n-(n+1)//2
+        mylist = concatenate((arange(p2, n), arange(p2)))
+        y = take(y, mylist, k)
+    return y
+
+
+def fftfreq(n, d=1.0):
+    """
+    Return the Discrete Fourier Transform sample frequencies.
+
+    The returned float array `f` contains the frequency bin centers in cycles
+    per unit of the sample spacing (with zero at the start).  For instance, if
+    the sample spacing is in seconds, then the frequency unit is cycles/second.
+
+    Given a window length `n` and a sample spacing `d`::
+
+      f = [0, 1, ...,   n/2-1,     -n/2, ..., -1] / (d*n)   if n is even
+      f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n)   if n is odd
+
+    Parameters
+    ----------
+    n : int
+        Window length.
+    d : scalar, optional
+        Sample spacing (inverse of the sampling rate). Defaults to 1.
+
+    Returns
+    -------
+    f : ndarray
+        Array of length `n` containing the sample frequencies.
+
+    Examples
+    --------
+    >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
+    >>> fourier = np.fft.fft(signal)
+    >>> n = signal.size
+    >>> timestep = 0.1
+    >>> freq = np.fft.fftfreq(n, d=timestep)
+    >>> freq
+    array([ 0.  ,  1.25,  2.5 ,  3.75, -5.  , -3.75, -2.5 , -1.25])
+
+    """
+    if not isinstance(n, integer_types):
+        raise ValueError("n should be an integer")
+    val = 1.0 / (n * d)
+    results = empty(n, int)
+    N = (n-1)//2 + 1
+    p1 = arange(0, N, dtype=int)
+    results[:N] = p1
+    p2 = arange(-(n//2), 0, dtype=int)
+    results[N:] = p2
+    return results * val
+    #return hstack((arange(0,(n-1)/2 + 1), arange(-(n/2),0))) / (n*d)
+
+
+def rfftfreq(n, d=1.0):
+    """
+    Return the Discrete Fourier Transform sample frequencies
+    (for usage with rfft, irfft).
+
+    The returned float array `f` contains the frequency bin centers in cycles
+    per unit of the sample spacing (with zero at the start).  For instance, if
+    the sample spacing is in seconds, then the frequency unit is cycles/second.
+
+    Given a window length `n` and a sample spacing `d`::
+
+      f = [0, 1, ...,     n/2-1,     n/2] / (d*n)   if n is even
+      f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n)   if n is odd
+
+    Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`)
+    the Nyquist frequency component is considered to be positive.
+
+    Parameters
+    ----------
+    n : int
+        Window length.
+    d : scalar, optional
+        Sample spacing (inverse of the sampling rate). Defaults to 1.
+
+    Returns
+    -------
+    f : ndarray
+        Array of length ``n//2 + 1`` containing the sample frequencies.
+
+    Examples
+    --------
+    >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
+    >>> fourier = np.fft.rfft(signal)
+    >>> n = signal.size
+    >>> sample_rate = 100
+    >>> freq = np.fft.fftfreq(n, d=1./sample_rate)
+    >>> freq
+    array([  0.,  10.,  20.,  30.,  40., -50., -40., -30., -20., -10.])
+    >>> freq = np.fft.rfftfreq(n, d=1./sample_rate)
+    >>> freq
+    array([  0.,  10.,  20.,  30.,  40.,  50.])
+
+    """
+    if not isinstance(n, integer_types):
+        raise ValueError("n should be an integer")
+    val = 1.0/(n*d)
+    N = n//2 + 1
+    results = arange(0, N, dtype=int)
+    return results * val
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/info.py
new file mode 100644
index 0000000000..cb6526b447
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/info.py
@@ -0,0 +1,187 @@
+"""
+Discrete Fourier Transform (:mod:`numpy.fft`)
+=============================================
+
+.. currentmodule:: numpy.fft
+
+Standard FFTs
+-------------
+
+.. autosummary::
+   :toctree: generated/
+
+   fft       Discrete Fourier transform.
+   ifft      Inverse discrete Fourier transform.
+   fft2      Discrete Fourier transform in two dimensions.
+   ifft2     Inverse discrete Fourier transform in two dimensions.
+   fftn      Discrete Fourier transform in N-dimensions.
+   ifftn     Inverse discrete Fourier transform in N dimensions.
+
+Real FFTs
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   rfft      Real discrete Fourier transform.
+   irfft     Inverse real discrete Fourier transform.
+   rfft2     Real discrete Fourier transform in two dimensions.
+   irfft2    Inverse real discrete Fourier transform in two dimensions.
+   rfftn     Real discrete Fourier transform in N dimensions.
+   irfftn    Inverse real discrete Fourier transform in N dimensions.
+
+Hermitian FFTs
+--------------
+
+.. autosummary::
+   :toctree: generated/
+
+   hfft      Hermitian discrete Fourier transform.
+   ihfft     Inverse Hermitian discrete Fourier transform.
+
+Helper routines
+---------------
+
+.. autosummary::
+   :toctree: generated/
+
+   fftfreq   Discrete Fourier Transform sample frequencies.
+   rfftfreq  DFT sample frequencies (for usage with rfft, irfft).
+   fftshift  Shift zero-frequency component to center of spectrum.
+   ifftshift Inverse of fftshift.
+
+
+Background information
+----------------------
+
+Fourier analysis is fundamentally a method for expressing a function as a
+sum of periodic components, and for recovering the function from those
+components.  When both the function and its Fourier transform are
+replaced with discretized counterparts, it is called the discrete Fourier
+transform (DFT).  The DFT has become a mainstay of numerical computing in
+part because of a very fast algorithm for computing it, called the Fast
+Fourier Transform (FFT), which was known to Gauss (1805) and was brought
+to light in its current form by Cooley and Tukey [CT]_.  Press et al. [NR]_
+provide an accessible introduction to Fourier analysis and its
+applications.
+
+Because the discrete Fourier transform separates its input into
+components that contribute at discrete frequencies, it has a great number
+of applications in digital signal processing, e.g., for filtering, and in
+this context the discretized input to the transform is customarily
+referred to as a *signal*, which exists in the *time domain*.  The output
+is called a *spectrum* or *transform* and exists in the *frequency
+domain*.
+
+Implementation details
+----------------------
+
+There are many ways to define the DFT, varying in the sign of the
+exponent, normalization, etc.  In this implementation, the DFT is defined
+as
+
+.. math::
+   A_k =  \\sum_{m=0}^{n-1} a_m \\exp\\left\\{-2\\pi i{mk \\over n}\\right\\}
+   \\qquad k = 0,\\ldots,n-1.
+
+The DFT is in general defined for complex inputs and outputs, and a
+single-frequency component at linear frequency :math:`f` is
+represented by a complex exponential
+:math:`a_m = \\exp\\{2\\pi i\\,f m\\Delta t\\}`, where :math:`\\Delta t`
+is the sampling interval.
+
+The values in the result follow so-called "standard" order: If ``A =
+fft(a, n)``, then ``A[0]`` contains the zero-frequency term (the sum of
+the signal), which is always purely real for real inputs. Then ``A[1:n/2]``
+contains the positive-frequency terms, and ``A[n/2+1:]`` contains the
+negative-frequency terms, in order of decreasingly negative frequency.
+For an even number of input points, ``A[n/2]`` represents both positive and
+negative Nyquist frequency, and is also purely real for real input.  For
+an odd number of input points, ``A[(n-1)/2]`` contains the largest positive
+frequency, while ``A[(n+1)/2]`` contains the largest negative frequency.
+The routine ``np.fft.fftfreq(n)`` returns an array giving the frequencies
+of corresponding elements in the output.  The routine
+``np.fft.fftshift(A)`` shifts transforms and their frequencies to put the
+zero-frequency components in the middle, and ``np.fft.ifftshift(A)`` undoes
+that shift.
+
+When the input `a` is a time-domain signal and ``A = fft(a)``, ``np.abs(A)``
+is its amplitude spectrum and ``np.abs(A)**2`` is its power spectrum.
+The phase spectrum is obtained by ``np.angle(A)``.
+
+The inverse DFT is defined as
+
+.. math::
+   a_m = \\frac{1}{n}\\sum_{k=0}^{n-1}A_k\\exp\\left\\{2\\pi i{mk\\over n}\\right\\}
+   \\qquad m = 0,\\ldots,n-1.
+
+It differs from the forward transform by the sign of the exponential
+argument and the default normalization by :math:`1/n`.
+
+Normalization
+-------------
+The default normalization has the direct transforms unscaled and the inverse
+transforms are scaled by :math:`1/n`. It is possible to obtain unitary
+transforms by setting the keyword argument ``norm`` to ``"ortho"`` (default is
+`None`) so that both direct and inverse transforms will be scaled by
+:math:`1/\\sqrt{n}`.
+
+Real and Hermitian transforms
+-----------------------------
+
+When the input is purely real, its transform is Hermitian, i.e., the
+component at frequency :math:`f_k` is the complex conjugate of the
+component at frequency :math:`-f_k`, which means that for real
+inputs there is no information in the negative frequency components that
+is not already available from the positive frequency components.
+The family of `rfft` functions is
+designed to operate on real inputs, and exploits this symmetry by
+computing only the positive frequency components, up to and including the
+Nyquist frequency.  Thus, ``n`` input points produce ``n/2+1`` complex
+output points.  The inverses of this family assumes the same symmetry of
+its input, and for an output of ``n`` points uses ``n/2+1`` input points.
+
+Correspondingly, when the spectrum is purely real, the signal is
+Hermitian.  The `hfft` family of functions exploits this symmetry by
+using ``n/2+1`` complex points in the input (time) domain for ``n`` real
+points in the frequency domain.
+
+In higher dimensions, FFTs are used, e.g., for image analysis and
+filtering.  The computational efficiency of the FFT means that it can
+also be a faster way to compute large convolutions, using the property
+that a convolution in the time domain is equivalent to a point-by-point
+multiplication in the frequency domain.
+
+Higher dimensions
+-----------------
+
+In two dimensions, the DFT is defined as
+
+.. math::
+   A_{kl} =  \\sum_{m=0}^{M-1} \\sum_{n=0}^{N-1}
+   a_{mn}\\exp\\left\\{-2\\pi i \\left({mk\\over M}+{nl\\over N}\\right)\\right\\}
+   \\qquad k = 0, \\ldots, M-1;\\quad l = 0, \\ldots, N-1,
+
+which extends in the obvious way to higher dimensions, and the inverses
+in higher dimensions also extend in the same way.
+
+References
+----------
+
+.. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the
+        machine calculation of complex Fourier series," *Math. Comput.*
+        19: 297-301.
+
+.. [NR] Press, W., Teukolsky, S., Vetterline, W.T., and Flannery, B.P.,
+        2007, *Numerical Recipes: The Art of Scientific Computing*, ch.
+        12-13.  Cambridge Univ. Press, Cambridge, UK.
+
+Examples
+--------
+
+For examples, see the various functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/setup.py
new file mode 100644
index 0000000000..cd99a82d7b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/setup.py
@@ -0,0 +1,19 @@
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('fft', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    # Configure fftpack_lite
+    config.add_extension('fftpack_lite',
+                         sources=['fftpack_litemodule.c', 'fftpack.c']
+                         )
+
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
new file mode 100644
index 0000000000..2e6294252e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
@@ -0,0 +1,166 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.random import random
+from numpy.testing import TestCase, run_module_suite, assert_array_almost_equal
+from numpy.testing import assert_array_equal
+import threading
+import sys
+if sys.version_info[0] >= 3:
+    import queue
+else:
+    import Queue as queue
+
+
+def fft1(x):
+    L = len(x)
+    phase = -2j*np.pi*(np.arange(L)/float(L))
+    phase = np.arange(L).reshape(-1, 1) * phase
+    return np.sum(x*np.exp(phase), axis=1)
+
+
+class TestFFTShift(TestCase):
+
+    def test_fft_n(self):
+        self.assertRaises(ValueError, np.fft.fft, [1, 2, 3], 0)
+
+
+class TestFFT1D(TestCase):
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    def test_fftn(self):
+        x = random((30, 20, 10)) + 1j*random((30, 20, 10))
+        assert_array_almost_equal(
+            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"))
+
+    def test_ifftn(self):
+        x = random((30, 20, 10)) + 1j*random((30, 20, 10))
+        assert_array_almost_equal(
+            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"))
+
+    def test_rfft(self):
+        x = random(30)
+        assert_array_almost_equal(np.fft.fft(x)[:16], np.fft.rfft(x))
+        assert_array_almost_equal(np.fft.rfft(x) / np.sqrt(30),
+                                  np.fft.rfft(x, norm="ortho"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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(
+            x_herm, np.fft.ihfft(np.fft.hfft(x_herm, norm="ortho"),
+                                 norm="ortho"))
+
+
+class TestFFTThreadSafe(TestCase):
+    threads = 16
+    input_shape = (800, 200)
+
+    def _test_mtsame(self, func, *args):
+        def worker(args, q):
+            q.put(func(*args))
+
+        q = queue.Queue()
+        expected = func(*args)
+
+        # Spin off a bunch of threads to call the same function simultaneously
+        t = [threading.Thread(target=worker, args=(args, q))
+             for i in range(self.threads)]
+        [x.start() for x in t]
+
+        [x.join() for x in t]
+        # Make sure all threads returned the correct value
+        for i in range(self.threads):
+            assert_array_equal(q.get(timeout=5), expected,
+                'Function returned wrong value in multithreaded context')
+
+    def test_fft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.fft, a)
+
+    def test_ifft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.ifft, a)
+
+    def test_rfft(self):
+        a = np.ones(self.input_shape)
+        self._test_mtsame(np.fft.rfft, a)
+
+    def test_irfft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.irfft, a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
new file mode 100644
index 0000000000..1811571347
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python2
+"""Test functions for fftpack.helper module
+
+Copied from fftpack.helper by Pearu Peterson, October 2005
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_array_almost_equal
+from numpy import fft
+from numpy import pi
+
+
+class TestFFTShift(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4, -4, -3, -2, -1]
+        y = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
+        assert_array_almost_equal(fft.fftshift(x), y)
+        assert_array_almost_equal(fft.ifftshift(y), x)
+        x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1]
+        y = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
+        assert_array_almost_equal(fft.fftshift(x), y)
+        assert_array_almost_equal(fft.ifftshift(y), x)
+
+    def test_inverse(self):
+        for n in [1, 4, 9, 100, 211]:
+            x = np.random.random((n,))
+            assert_array_almost_equal(fft.ifftshift(fft.fftshift(x)), x)
+
+    def test_axes_keyword(self):
+        freqs = [[0, 1, 2], [3, 4, -4], [-3, -2, -1]]
+        shifted = [[-1, -3, -2], [2, 0, 1], [-4, 3, 4]]
+        assert_array_almost_equal(fft.fftshift(freqs, axes=(0, 1)), shifted)
+        assert_array_almost_equal(fft.fftshift(freqs, axes=0),
+                fft.fftshift(freqs, axes=(0,)))
+        assert_array_almost_equal(fft.ifftshift(shifted, axes=(0, 1)), freqs)
+        assert_array_almost_equal(fft.ifftshift(shifted, axes=0),
+                fft.ifftshift(shifted, axes=(0,)))
+
+
+class TestFFTFreq(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4, -4, -3, -2, -1]
+        assert_array_almost_equal(9*fft.fftfreq(9), x)
+        assert_array_almost_equal(9*pi*fft.fftfreq(9, pi), x)
+        x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1]
+        assert_array_almost_equal(10*fft.fftfreq(10), x)
+        assert_array_almost_equal(10*pi*fft.fftfreq(10, pi), x)
+
+
+class TestRFFTFreq(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4]
+        assert_array_almost_equal(9*fft.rfftfreq(9), x)
+        assert_array_almost_equal(9*pi*fft.rfftfreq(9, pi), x)
+        x = [0, 1, 2, 3, 4, 5]
+        assert_array_almost_equal(10*fft.rfftfreq(10), x)
+        assert_array_almost_equal(10*pi*fft.rfftfreq(10, pi), x)
+
+
+class TestIRFFTN(TestCase):
+
+    def test_not_last_axis_success(self):
+        ar, ai = np.random.random((2, 16, 8, 32))
+        a = ar + 1j*ai
+
+        axes = (-2,)
+
+        # Should not raise error
+        fft.irfftn(a, axes=axes)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/__init__.py
new file mode 100644
index 0000000000..1d65db55e1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/__init__.py
@@ -0,0 +1,46 @@
+from __future__ import division, absolute_import, print_function
+
+import math
+
+from .info import __doc__
+from numpy.version import version as __version__
+
+from .type_check import *
+from .index_tricks import *
+from .function_base import *
+from .nanfunctions import *
+from .shape_base import *
+from .stride_tricks import *
+from .twodim_base import *
+from .ufunclike import *
+
+from . import scimath as emath
+from .polynomial import *
+#import convertcode
+from .utils import *
+from .arraysetops import *
+from .npyio import *
+from .financial import *
+from .arrayterator import Arrayterator
+from .arraypad import *
+from ._version import *
+
+__all__ = ['emath', 'math']
+__all__ += type_check.__all__
+__all__ += index_tricks.__all__
+__all__ += function_base.__all__
+__all__ += shape_base.__all__
+__all__ += stride_tricks.__all__
+__all__ += twodim_base.__all__
+__all__ += ufunclike.__all__
+__all__ += arraypad.__all__
+__all__ += polynomial.__all__
+__all__ += utils.__all__
+__all__ += arraysetops.__all__
+__all__ += npyio.__all__
+__all__ += financial.__all__
+__all__ += nanfunctions.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.py
new file mode 100644
index 0000000000..338c8b3311
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.py
@@ -0,0 +1,666 @@
+"""A file interface for handling local and remote data files.
+
+The goal of datasource is to abstract some of the file system operations
+when dealing with data files so the researcher doesn't have to know all the
+low-level details.  Through datasource, a researcher can obtain and use a
+file with one function call, regardless of location of the file.
+
+DataSource is meant to augment standard python libraries, not replace them.
+It should work seemlessly with standard file IO operations and the os
+module.
+
+DataSource files can originate locally or remotely:
+
+- local files : '/home/guido/src/local/data.txt'
+- URLs (http, ftp, ...) : 'http://www.scipy.org/not/real/data.txt'
+
+DataSource files can also be compressed or uncompressed.  Currently only
+gzip and bz2 are supported.
+
+Example::
+
+    >>> # Create a DataSource, use os.curdir (default) for local storage.
+    >>> ds = datasource.DataSource()
+    >>>
+    >>> # Open a remote file.
+    >>> # DataSource downloads the file, stores it locally in:
+    >>> #     './www.google.com/index.html'
+    >>> # opens the file and returns a file object.
+    >>> fp = ds.open('http://www.google.com/index.html')
+    >>>
+    >>> # Use the file as you normally would
+    >>> fp.read()
+    >>> fp.close()
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import shutil
+
+_open = open
+
+
+# Using a class instead of a module-level dictionary
+# to reduce the inital 'import numpy' overhead by
+# deferring the import of bz2 and gzip until needed
+
+# TODO: .zip support, .tar support?
+class _FileOpeners(object):
+    """
+    Container for different methods to open (un-)compressed files.
+
+    `_FileOpeners` contains a dictionary that holds one method for each
+    supported file format. Attribute lookup is implemented in such a way
+    that an instance of `_FileOpeners` itself can be indexed with the keys
+    of that dictionary. Currently uncompressed files as well as files
+    compressed with ``gzip`` or ``bz2`` compression are supported.
+
+    Notes
+    -----
+    `_file_openers`, an instance of `_FileOpeners`, is made available for
+    use in the `_datasource` module.
+
+    Examples
+    --------
+    >>> np.lib._datasource._file_openers.keys()
+    [None, '.bz2', '.gz']
+    >>> np.lib._datasource._file_openers['.gz'] is gzip.open
+    True
+
+    """
+
+    def __init__(self):
+        self._loaded = False
+        self._file_openers = {None: open}
+
+    def _load(self):
+        if self._loaded:
+            return
+        try:
+            import bz2
+            self._file_openers[".bz2"] = bz2.BZ2File
+        except ImportError:
+            pass
+        try:
+            import gzip
+            self._file_openers[".gz"] = gzip.open
+        except ImportError:
+            pass
+        self._loaded = True
+
+    def keys(self):
+        """
+        Return the keys of currently supported file openers.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        keys : list
+            The keys are None for uncompressed files and the file extension
+            strings (i.e. ``'.gz'``, ``'.bz2'``) for supported compression
+            methods.
+
+        """
+        self._load()
+        return list(self._file_openers.keys())
+
+    def __getitem__(self, key):
+        self._load()
+        return self._file_openers[key]
+
+_file_openers = _FileOpeners()
+
+def open(path, mode='r', destpath=os.curdir):
+    """
+    Open `path` with `mode` and return the file object.
+
+    If ``path`` is an URL, it will be downloaded, stored in the
+    `DataSource` `destpath` directory and opened from there.
+
+    Parameters
+    ----------
+    path : str
+        Local file path or URL to open.
+    mode : str, optional
+        Mode to open `path`. Mode 'r' for reading, 'w' for writing, 'a' to
+        append. Available modes depend on the type of object specified by
+        path.  Default is 'r'.
+    destpath : str, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Returns
+    -------
+    out : file object
+        The opened file.
+
+    Notes
+    -----
+    This is a convenience function that instantiates a `DataSource` and
+    returns the file object from ``DataSource.open(path)``.
+
+    """
+
+    ds = DataSource(destpath)
+    return ds.open(path, mode)
+
+
+class DataSource (object):
+    """
+    DataSource(destpath='.')
+
+    A generic data source file (file, http, ftp, ...).
+
+    DataSources can be local files or remote files/URLs.  The files may
+    also be compressed or uncompressed. DataSource hides some of the
+    low-level details of downloading the file, allowing you to simply pass
+    in a valid file path (or URL) and obtain a file object.
+
+    Parameters
+    ----------
+    destpath : str or None, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Notes
+    -----
+    URLs require a scheme string (``http://``) to be used, without it they
+    will fail::
+
+        >>> repos = DataSource()
+        >>> repos.exists('www.google.com/index.html')
+        False
+        >>> repos.exists('http://www.google.com/index.html')
+        True
+
+    Temporary directories are deleted when the DataSource is deleted.
+
+    Examples
+    --------
+    ::
+
+        >>> ds = DataSource('/home/guido')
+        >>> urlname = 'http://www.google.com/index.html'
+        >>> gfile = ds.open('http://www.google.com/index.html')  # remote file
+        >>> ds.abspath(urlname)
+        '/home/guido/www.google.com/site/index.html'
+
+        >>> ds = DataSource(None)  # use with temporary file
+        >>> ds.open('/home/guido/foobar.txt')
+        <open file '/home/guido.foobar.txt', mode 'r' at 0x91d4430>
+        >>> ds.abspath('/home/guido/foobar.txt')
+        '/tmp/tmpy4pgsP/home/guido/foobar.txt'
+
+    """
+
+    def __init__(self, destpath=os.curdir):
+        """Create a DataSource with a local path at destpath."""
+        if destpath:
+            self._destpath = os.path.abspath(destpath)
+            self._istmpdest = False
+        else:
+            import tempfile  # deferring import to improve startup time
+            self._destpath = tempfile.mkdtemp()
+            self._istmpdest = True
+
+    def __del__(self):
+        # Remove temp directories
+        if self._istmpdest:
+            shutil.rmtree(self._destpath)
+
+    def _iszip(self, filename):
+        """Test if the filename is a zip file by looking at the file extension.
+
+        """
+        fname, ext = os.path.splitext(filename)
+        return ext in _file_openers.keys()
+
+    def _iswritemode(self, mode):
+        """Test if the given mode will open a file for writing."""
+
+        # Currently only used to test the bz2 files.
+        _writemodes = ("w", "+")
+        for c in mode:
+            if c in _writemodes:
+                return True
+        return False
+
+    def _splitzipext(self, filename):
+        """Split zip extension from filename and return filename.
+
+        *Returns*:
+            base, zip_ext : {tuple}
+
+        """
+
+        if self._iszip(filename):
+            return os.path.splitext(filename)
+        else:
+            return filename, None
+
+    def _possible_names(self, filename):
+        """Return a tuple containing compressed filename variations."""
+        names = [filename]
+        if not self._iszip(filename):
+            for zipext in _file_openers.keys():
+                if zipext:
+                    names.append(filename+zipext)
+        return names
+
+    def _isurl(self, path):
+        """Test if path is a net location.  Tests the scheme and netloc."""
+
+        # We do this here to reduce the 'import numpy' initial import time.
+        if sys.version_info[0] >= 3:
+            from urllib.parse import urlparse
+        else:
+            from urlparse import urlparse
+
+        # BUG : URLs require a scheme string ('http://') to be used.
+        #       www.google.com will fail.
+        #       Should we prepend the scheme for those that don't have it and
+        #       test that also?  Similar to the way we append .gz and test for
+        #       for compressed versions of files.
+
+        scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
+        return bool(scheme and netloc)
+
+    def _cache(self, path):
+        """Cache the file specified by path.
+
+        Creates a copy of the file in the datasource cache.
+
+        """
+        # We import these here because importing urllib2 is slow and
+        # a significant fraction of numpy's total import time.
+        if sys.version_info[0] >= 3:
+            from urllib.request import urlopen
+            from urllib.error import URLError
+        else:
+            from urllib2 import urlopen
+            from urllib2 import URLError
+
+        upath = self.abspath(path)
+
+        # ensure directory exists
+        if not os.path.exists(os.path.dirname(upath)):
+            os.makedirs(os.path.dirname(upath))
+
+        # TODO: Doesn't handle compressed files!
+        if self._isurl(path):
+            try:
+                openedurl = urlopen(path)
+                f = _open(upath, 'wb')
+                try:
+                    shutil.copyfileobj(openedurl, f)
+                finally:
+                    f.close()
+                    openedurl.close()
+            except URLError:
+                raise URLError("URL not found: %s" % path)
+        else:
+            shutil.copyfile(path, upath)
+        return upath
+
+    def _findfile(self, path):
+        """Searches for ``path`` and returns full path if found.
+
+        If path is an URL, _findfile will cache a local copy and return the
+        path to the cached file.  If path is a local file, _findfile will
+        return a path to that local file.
+
+        The search will include possible compressed versions of the file
+        and return the first occurence found.
+
+        """
+
+        # Build list of possible local file paths
+        if not self._isurl(path):
+            # Valid local paths
+            filelist = self._possible_names(path)
+            # Paths in self._destpath
+            filelist += self._possible_names(self.abspath(path))
+        else:
+            # Cached URLs in self._destpath
+            filelist = self._possible_names(self.abspath(path))
+            # Remote URLs
+            filelist = filelist + self._possible_names(path)
+
+        for name in filelist:
+            if self.exists(name):
+                if self._isurl(name):
+                    name = self._cache(name)
+                return name
+        return None
+
+    def abspath(self, path):
+        """
+        Return absolute path of file in the DataSource directory.
+
+        If `path` is an URL, then `abspath` will return either the location
+        the file exists locally or the location it would exist when opened
+        using the `open` method.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL.
+
+        Returns
+        -------
+        out : str
+            Complete path, including the `DataSource` destination directory.
+
+        Notes
+        -----
+        The functionality is based on `os.path.abspath`.
+
+        """
+        # We do this here to reduce the 'import numpy' initial import time.
+        if sys.version_info[0] >= 3:
+            from urllib.parse import urlparse
+        else:
+            from urlparse import urlparse
+
+        # TODO:  This should be more robust.  Handles case where path includes
+        #        the destpath, but not other sub-paths. Failing case:
+        #        path = /home/guido/datafile.txt
+        #        destpath = /home/alex/
+        #        upath = self.abspath(path)
+        #        upath == '/home/alex/home/guido/datafile.txt'
+
+        # handle case where path includes self._destpath
+        splitpath = path.split(self._destpath, 2)
+        if len(splitpath) > 1:
+            path = splitpath[1]
+        scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
+        netloc = self._sanitize_relative_path(netloc)
+        upath = self._sanitize_relative_path(upath)
+        return os.path.join(self._destpath, netloc, upath)
+
+    def _sanitize_relative_path(self, path):
+        """Return a sanitised relative path for which
+        os.path.abspath(os.path.join(base, path)).startswith(base)
+        """
+        last = None
+        path = os.path.normpath(path)
+        while path != last:
+            last = path
+            # Note: os.path.join treats '/' as os.sep on Windows
+            path = path.lstrip(os.sep).lstrip('/')
+            path = path.lstrip(os.pardir).lstrip('..')
+            drive, path = os.path.splitdrive(path)  # for Windows
+        return path
+
+    def exists(self, path):
+        """
+        Test if path exists.
+
+        Test if `path` exists as (and in this order):
+
+        - a local file.
+        - a remote URL that has been downloaded and stored locally in the
+          `DataSource` directory.
+        - a remote URL that has not been downloaded, but is valid and
+          accessible.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL.
+
+        Returns
+        -------
+        out : bool
+            True if `path` exists.
+
+        Notes
+        -----
+        When `path` is an URL, `exists` will return True if it's either
+        stored locally in the `DataSource` directory, or is a valid remote
+        URL.  `DataSource` does not discriminate between the two, the file
+        is accessible if it exists in either location.
+
+        """
+        # We import this here because importing urllib2 is slow and
+        # a significant fraction of numpy's total import time.
+        if sys.version_info[0] >= 3:
+            from urllib.request import urlopen
+            from urllib.error import URLError
+        else:
+            from urllib2 import urlopen
+            from urllib2 import URLError
+
+        # Test local path
+        if os.path.exists(path):
+            return True
+
+        # Test cached url
+        upath = self.abspath(path)
+        if os.path.exists(upath):
+            return True
+
+        # Test remote url
+        if self._isurl(path):
+            try:
+                netfile = urlopen(path)
+                netfile.close()
+                del(netfile)
+                return True
+            except URLError:
+                return False
+        return False
+
+    def open(self, path, mode='r'):
+        """
+        Open and return file-like object.
+
+        If `path` is an URL, it will be downloaded, stored in the
+        `DataSource` directory and opened from there.
+
+        Parameters
+        ----------
+        path : str
+            Local file path or URL to open.
+        mode : {'r', 'w', 'a'}, optional
+            Mode to open `path`.  Mode 'r' for reading, 'w' for writing,
+            'a' to append. Available modes depend on the type of object
+            specified by `path`. Default is 'r'.
+
+        Returns
+        -------
+        out : file object
+            File object.
+
+        """
+
+        # TODO: There is no support for opening a file for writing which
+        #       doesn't exist yet (creating a file).  Should there be?
+
+        # TODO: Add a ``subdir`` parameter for specifying the subdirectory
+        #       used to store URLs in self._destpath.
+
+        if self._isurl(path) and self._iswritemode(mode):
+            raise ValueError("URLs are not writeable")
+
+        # NOTE: _findfile will fail on a new file opened for writing.
+        found = self._findfile(path)
+        if found:
+            _fname, ext = self._splitzipext(found)
+            if ext == 'bz2':
+                mode.replace("+", "")
+            return _file_openers[ext](found, mode=mode)
+        else:
+            raise IOError("%s not found." % path)
+
+
+class Repository (DataSource):
+    """
+    Repository(baseurl, destpath='.')
+
+    A data repository where multiple DataSource's share a base
+    URL/directory.
+
+    `Repository` extends `DataSource` by prepending a base URL (or
+    directory) to all the files it handles. Use `Repository` when you will
+    be working with multiple files from one base URL.  Initialize
+    `Repository` with the base URL, then refer to each file by its filename
+    only.
+
+    Parameters
+    ----------
+    baseurl : str
+        Path to the local directory or remote location that contains the
+        data files.
+    destpath : str or None, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Examples
+    --------
+    To analyze all files in the repository, do something like this
+    (note: this is not self-contained code)::
+
+        >>> repos = np.lib._datasource.Repository('/home/user/data/dir/')
+        >>> for filename in filelist:
+        ...     fp = repos.open(filename)
+        ...     fp.analyze()
+        ...     fp.close()
+
+    Similarly you could use a URL for a repository::
+
+        >>> repos = np.lib._datasource.Repository('http://www.xyz.edu/data')
+
+    """
+
+    def __init__(self, baseurl, destpath=os.curdir):
+        """Create a Repository with a shared url or directory of baseurl."""
+        DataSource.__init__(self, destpath=destpath)
+        self._baseurl = baseurl
+
+    def __del__(self):
+        DataSource.__del__(self)
+
+    def _fullpath(self, path):
+        """Return complete path for path.  Prepends baseurl if necessary."""
+        splitpath = path.split(self._baseurl, 2)
+        if len(splitpath) == 1:
+            result = os.path.join(self._baseurl, path)
+        else:
+            result = path    # path contains baseurl already
+        return result
+
+    def _findfile(self, path):
+        """Extend DataSource method to prepend baseurl to ``path``."""
+        return DataSource._findfile(self, self._fullpath(path))
+
+    def abspath(self, path):
+        """
+        Return absolute path of file in the Repository directory.
+
+        If `path` is an URL, then `abspath` will return either the location
+        the file exists locally or the location it would exist when opened
+        using the `open` method.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL. This may, but does not
+            have to, include the `baseurl` with which the `Repository` was
+            initialized.
+
+        Returns
+        -------
+        out : str
+            Complete path, including the `DataSource` destination directory.
+
+        """
+        return DataSource.abspath(self, self._fullpath(path))
+
+    def exists(self, path):
+        """
+        Test if path exists prepending Repository base URL to path.
+
+        Test if `path` exists as (and in this order):
+
+        - a local file.
+        - a remote URL that has been downloaded and stored locally in the
+          `DataSource` directory.
+        - a remote URL that has not been downloaded, but is valid and
+          accessible.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL. This may, but does not
+            have to, include the `baseurl` with which the `Repository` was
+            initialized.
+
+        Returns
+        -------
+        out : bool
+            True if `path` exists.
+
+        Notes
+        -----
+        When `path` is an URL, `exists` will return True if it's either
+        stored locally in the `DataSource` directory, or is a valid remote
+        URL.  `DataSource` does not discriminate between the two, the file
+        is accessible if it exists in either location.
+
+        """
+        return DataSource.exists(self, self._fullpath(path))
+
+    def open(self, path, mode='r'):
+        """
+        Open and return file-like object prepending Repository base URL.
+
+        If `path` is an URL, it will be downloaded, stored in the
+        DataSource directory and opened from there.
+
+        Parameters
+        ----------
+        path : str
+            Local file path or URL to open. This may, but does not have to,
+            include the `baseurl` with which the `Repository` was
+            initialized.
+        mode : {'r', 'w', 'a'}, optional
+            Mode to open `path`.  Mode 'r' for reading, 'w' for writing,
+            'a' to append. Available modes depend on the type of object
+            specified by `path`. Default is 'r'.
+
+        Returns
+        -------
+        out : file object
+            File object.
+
+        """
+        return DataSource.open(self, self._fullpath(path), mode)
+
+    def listdir(self):
+        """
+        List files in the source Repository.
+
+        Returns
+        -------
+        files : list of str
+            List of file names (not containing a directory part).
+
+        Notes
+        -----
+        Does not currently work for remote repositories.
+
+        """
+        if self._isurl(self._baseurl):
+            raise NotImplementedError(
+                  "Directory listing of URLs, not supported yet.")
+        else:
+            return os.listdir(self._baseurl)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.py
new file mode 100644
index 0000000000..dfdc38b72e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.py
@@ -0,0 +1,930 @@
+"""A collection of functions designed to help I/O with ascii files.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__docformat__ = "restructuredtext en"
+
+import sys
+import numpy as np
+import numpy.core.numeric as nx
+from numpy.compat import asbytes, bytes, asbytes_nested, basestring
+
+if sys.version_info[0] >= 3:
+    from builtins import bool, int, float, complex, object, str
+    unicode = str
+else:
+    from __builtin__ import bool, int, float, complex, object, unicode, str
+
+
+if sys.version_info[0] >= 3:
+    def _bytes_to_complex(s):
+        return complex(s.decode('ascii'))
+
+    def _bytes_to_name(s):
+        return s.decode('ascii')
+else:
+    _bytes_to_complex = complex
+    _bytes_to_name = str
+
+
+def _is_string_like(obj):
+    """
+    Check whether obj behaves like a string.
+    """
+    try:
+        obj + ''
+    except (TypeError, ValueError):
+        return False
+    return True
+
+
+def _is_bytes_like(obj):
+    """
+    Check whether obj behaves like a bytes object.
+    """
+    try:
+        obj + asbytes('')
+    except (TypeError, ValueError):
+        return False
+    return True
+
+
+def _to_filehandle(fname, flag='r', return_opened=False):
+    """
+    Returns the filehandle corresponding to a string or a file.
+    If the string ends in '.gz', the file is automatically unzipped.
+
+    Parameters
+    ----------
+    fname : string, filehandle
+        Name of the file whose filehandle must be returned.
+    flag : string, optional
+        Flag indicating the status of the file ('r' for read, 'w' for write).
+    return_opened : boolean, optional
+        Whether to return the opening status of the file.
+    """
+    if _is_string_like(fname):
+        if fname.endswith('.gz'):
+            import gzip
+            fhd = gzip.open(fname, flag)
+        elif fname.endswith('.bz2'):
+            import bz2
+            fhd = bz2.BZ2File(fname)
+        else:
+            fhd = file(fname, flag)
+        opened = True
+    elif hasattr(fname, 'seek'):
+        fhd = fname
+        opened = False
+    else:
+        raise ValueError('fname must be a string or file handle')
+    if return_opened:
+        return fhd, opened
+    return fhd
+
+
+def has_nested_fields(ndtype):
+    """
+    Returns whether one or several fields of a dtype are nested.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        Data-type of a structured array.
+
+    Raises
+    ------
+    AttributeError
+        If `ndtype` does not have a `names` attribute.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float)])
+    >>> np.lib._iotools.has_nested_fields(dt)
+    False
+
+    """
+    for name in ndtype.names or ():
+        if ndtype[name].names:
+            return True
+    return False
+
+
+def flatten_dtype(ndtype, flatten_base=False):
+    """
+    Unpack a structured data-type by collapsing nested fields and/or fields
+    with a shape.
+
+    Note that the field names are lost.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        The datatype to collapse
+    flatten_base : {False, True}, optional
+        Whether to transform a field with a shape into several fields or not.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+    ...                ('block', int, (2, 3))])
+    >>> np.lib._iotools.flatten_dtype(dt)
+    [dtype('|S4'), dtype('float64'), dtype('float64'), dtype('int32')]
+    >>> np.lib._iotools.flatten_dtype(dt, flatten_base=True)
+    [dtype('|S4'), dtype('float64'), dtype('float64'), dtype('int32'),
+     dtype('int32'), dtype('int32'), dtype('int32'), dtype('int32'),
+     dtype('int32')]
+
+    """
+    names = ndtype.names
+    if names is None:
+        if flatten_base:
+            return [ndtype.base] * int(np.prod(ndtype.shape))
+        return [ndtype.base]
+    else:
+        types = []
+        for field in names:
+            info = ndtype.fields[field]
+            flat_dt = flatten_dtype(info[0], flatten_base)
+            types.extend(flat_dt)
+        return types
+
+
+class LineSplitter(object):
+    """
+    Object to split a string at a given delimiter or at given places.
+
+    Parameters
+    ----------
+    delimiter : str, int, or sequence of ints, optional
+        If a string, character used to delimit consecutive fields.
+        If an integer or a sequence of integers, width(s) of each field.
+    comments : str, optional
+        Character used to mark the beginning of a comment. Default is '#'.
+    autostrip : bool, optional
+        Whether to strip each individual field. Default is True.
+
+    """
+
+    def autostrip(self, method):
+        """
+        Wrapper to strip each member of the output of `method`.
+
+        Parameters
+        ----------
+        method : function
+            Function that takes a single argument and returns a sequence of
+            strings.
+
+        Returns
+        -------
+        wrapped : function
+            The result of wrapping `method`. `wrapped` takes a single input
+            argument and returns a list of strings that are stripped of
+            white-space.
+
+        """
+        return lambda input: [_.strip() for _ in method(input)]
+    #
+
+    def __init__(self, delimiter=None, comments=asbytes('#'), autostrip=True):
+        self.comments = comments
+        # Delimiter is a character
+        if isinstance(delimiter, unicode):
+            delimiter = delimiter.encode('ascii')
+        if (delimiter is None) or _is_bytes_like(delimiter):
+            delimiter = delimiter or None
+            _handyman = self._delimited_splitter
+        # Delimiter is a list of field widths
+        elif hasattr(delimiter, '__iter__'):
+            _handyman = self._variablewidth_splitter
+            idx = np.cumsum([0] + list(delimiter))
+            delimiter = [slice(i, j) for (i, j) in zip(idx[:-1], idx[1:])]
+        # Delimiter is a single integer
+        elif int(delimiter):
+            (_handyman, delimiter) = (
+                    self._fixedwidth_splitter, int(delimiter))
+        else:
+            (_handyman, delimiter) = (self._delimited_splitter, None)
+        self.delimiter = delimiter
+        if autostrip:
+            self._handyman = self.autostrip(_handyman)
+        else:
+            self._handyman = _handyman
+    #
+
+    def _delimited_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        line = line.strip(asbytes(" \r\n"))
+        if not line:
+            return []
+        return line.split(self.delimiter)
+    #
+
+    def _fixedwidth_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        line = line.strip(asbytes("\r\n"))
+        if not line:
+            return []
+        fixed = self.delimiter
+        slices = [slice(i, i + fixed) for i in range(0, len(line), fixed)]
+        return [line[s] for s in slices]
+    #
+
+    def _variablewidth_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        if not line:
+            return []
+        slices = self.delimiter
+        return [line[s] for s in slices]
+    #
+
+    def __call__(self, line):
+        return self._handyman(line)
+
+
+class NameValidator(object):
+    """
+    Object to validate a list of strings to use as field names.
+
+    The strings are stripped of any non alphanumeric character, and spaces
+    are replaced by '_'. During instantiation, the user can define a list
+    of names to exclude, as well as a list of invalid characters. Names in
+    the exclusion list are appended a '_' character.
+
+    Once an instance has been created, it can be called with a list of
+    names, and a list of valid names will be created.  The `__call__`
+    method accepts an optional keyword "default" that sets the default name
+    in case of ambiguity. By default this is 'f', so that names will
+    default to `f0`, `f1`, etc.
+
+    Parameters
+    ----------
+    excludelist : sequence, optional
+        A list of names to exclude. This list is appended to the default
+        list ['return', 'file', 'print']. Excluded names are appended an
+        underscore: for example, `file` becomes `file_` if supplied.
+    deletechars : str, optional
+        A string combining invalid characters that must be deleted from the
+        names.
+    case_sensitive : {True, False, 'upper', 'lower'}, optional
+        * If True, field names are case-sensitive.
+        * If False or 'upper', field names are converted to upper case.
+        * If 'lower', field names are converted to lower case.
+
+        The default value is True.
+    replace_space : '_', optional
+        Character(s) used in replacement of white spaces.
+
+    Notes
+    -----
+    Calling an instance of `NameValidator` is the same as calling its
+    method `validate`.
+
+    Examples
+    --------
+    >>> validator = np.lib._iotools.NameValidator()
+    >>> validator(['file', 'field2', 'with space', 'CaSe'])
+    ['file_', 'field2', 'with_space', 'CaSe']
+
+    >>> validator = np.lib._iotools.NameValidator(excludelist=['excl'],
+                                                  deletechars='q',
+                                                  case_sensitive='False')
+    >>> validator(['excl', 'field2', 'no_q', 'with space', 'CaSe'])
+    ['excl_', 'field2', 'no_', 'with_space', 'case']
+
+    """
+    #
+    defaultexcludelist = ['return', 'file', 'print']
+    defaultdeletechars = set("""~!@#$%^&*()-=+~\|]}[{';: /?.>,<""")
+    #
+
+    def __init__(self, excludelist=None, deletechars=None,
+                 case_sensitive=None, replace_space='_'):
+        # Process the exclusion list ..
+        if excludelist is None:
+            excludelist = []
+        excludelist.extend(self.defaultexcludelist)
+        self.excludelist = excludelist
+        # Process the list of characters to delete
+        if deletechars is None:
+            delete = self.defaultdeletechars
+        else:
+            delete = set(deletechars)
+        delete.add('"')
+        self.deletechars = delete
+        # Process the case option .....
+        if (case_sensitive is None) or (case_sensitive is True):
+            self.case_converter = lambda x: x
+        elif (case_sensitive is False) or case_sensitive.startswith('u'):
+            self.case_converter = lambda x: x.upper()
+        elif case_sensitive.startswith('l'):
+            self.case_converter = lambda x: x.lower()
+        else:
+            msg = 'unrecognized case_sensitive value %s.' % case_sensitive
+            raise ValueError(msg)
+        #
+        self.replace_space = replace_space
+
+    def validate(self, names, defaultfmt="f%i", nbfields=None):
+        """
+        Validate a list of strings as field names for a structured array.
+
+        Parameters
+        ----------
+        names : sequence of str
+            Strings to be validated.
+        defaultfmt : str, optional
+            Default format string, used if validating a given string
+            reduces its length to zero.
+        nbfields : integer, optional
+            Final number of validated names, used to expand or shrink the
+            initial list of names.
+
+        Returns
+        -------
+        validatednames : list of str
+            The list of validated field names.
+
+        Notes
+        -----
+        A `NameValidator` instance can be called directly, which is the
+        same as calling `validate`. For examples, see `NameValidator`.
+
+        """
+        # Initial checks ..............
+        if (names is None):
+            if (nbfields is None):
+                return None
+            names = []
+        if isinstance(names, basestring):
+            names = [names, ]
+        if nbfields is not None:
+            nbnames = len(names)
+            if (nbnames < nbfields):
+                names = list(names) + [''] * (nbfields - nbnames)
+            elif (nbnames > nbfields):
+                names = names[:nbfields]
+        # Set some shortcuts ...........
+        deletechars = self.deletechars
+        excludelist = self.excludelist
+        case_converter = self.case_converter
+        replace_space = self.replace_space
+        # Initializes some variables ...
+        validatednames = []
+        seen = dict()
+        nbempty = 0
+        #
+        for item in names:
+            item = case_converter(item).strip()
+            if replace_space:
+                item = item.replace(' ', replace_space)
+            item = ''.join([c for c in item if c not in deletechars])
+            if item == '':
+                item = defaultfmt % nbempty
+                while item in names:
+                    nbempty += 1
+                    item = defaultfmt % nbempty
+                nbempty += 1
+            elif item in excludelist:
+                item += '_'
+            cnt = seen.get(item, 0)
+            if cnt > 0:
+                validatednames.append(item + '_%d' % cnt)
+            else:
+                validatednames.append(item)
+            seen[item] = cnt + 1
+        return tuple(validatednames)
+    #
+
+    def __call__(self, names, defaultfmt="f%i", nbfields=None):
+        return self.validate(names, defaultfmt=defaultfmt, nbfields=nbfields)
+
+
+def str2bool(value):
+    """
+    Tries to transform a string supposed to represent a boolean to a boolean.
+
+    Parameters
+    ----------
+    value : str
+        The string that is transformed to a boolean.
+
+    Returns
+    -------
+    boolval : bool
+        The boolean representation of `value`.
+
+    Raises
+    ------
+    ValueError
+        If the string is not 'True' or 'False' (case independent)
+
+    Examples
+    --------
+    >>> np.lib._iotools.str2bool('TRUE')
+    True
+    >>> np.lib._iotools.str2bool('false')
+    False
+
+    """
+    value = value.upper()
+    if value == asbytes('TRUE'):
+        return True
+    elif value == asbytes('FALSE'):
+        return False
+    else:
+        raise ValueError("Invalid boolean")
+
+
+class ConverterError(Exception):
+    """
+    Exception raised when an error occurs in a converter for string values.
+
+    """
+    pass
+
+
+class ConverterLockError(ConverterError):
+    """
+    Exception raised when an attempt is made to upgrade a locked converter.
+
+    """
+    pass
+
+
+class ConversionWarning(UserWarning):
+    """
+    Warning issued when a string converter has a problem.
+
+    Notes
+    -----
+    In `genfromtxt` a `ConversionWarning` is issued if raising exceptions
+    is explicitly suppressed with the "invalid_raise" keyword.
+
+    """
+    pass
+
+
+class StringConverter(object):
+    """
+    Factory class for function transforming a string into another object
+    (int, float).
+
+    After initialization, an instance can be called to transform a string
+    into another object. If the string is recognized as representing a
+    missing value, a default value is returned.
+
+    Attributes
+    ----------
+    func : function
+        Function used for the conversion.
+    default : any
+        Default value to return when the input corresponds to a missing
+        value.
+    type : type
+        Type of the output.
+    _status : int
+        Integer representing the order of the conversion.
+    _mapper : sequence of tuples
+        Sequence of tuples (dtype, function, default value) to evaluate in
+        order.
+    _locked : bool
+        Holds `locked` parameter.
+
+    Parameters
+    ----------
+    dtype_or_func : {None, dtype, function}, optional
+        If a `dtype`, specifies the input data type, used to define a basic
+        function and a default value for missing data. For example, when
+        `dtype` is float, the `func` attribute is set to `float` and the
+        default value to `np.nan`.  If a function, this function is used to
+        convert a string to another object. In this case, it is recommended
+        to give an associated default value as input.
+    default : any, optional
+        Value to return by default, that is, when the string to be
+        converted is flagged as missing. If not given, `StringConverter`
+        tries to supply a reasonable default value.
+    missing_values : sequence of str, optional
+        Sequence of strings indicating a missing value.
+    locked : bool, optional
+        Whether the StringConverter should be locked to prevent automatic
+        upgrade or not. Default is False.
+
+    """
+    #
+    _mapper = [(nx.bool_, str2bool, False),
+               (nx.integer, int, -1)]
+
+    # On 32-bit systems, we need to make sure that we explicitly include
+    # nx.int64 since ns.integer is nx.int32.
+    if nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize:
+        _mapper.append((nx.int64, int, -1))
+
+    _mapper.extend([(nx.floating, float, nx.nan),
+                    (complex, _bytes_to_complex, nx.nan + 0j),
+                    (nx.longdouble, nx.longdouble, nx.nan),
+                    (nx.string_, bytes, asbytes('???'))])
+
+    (_defaulttype, _defaultfunc, _defaultfill) = zip(*_mapper)
+
+    @classmethod
+    def _getdtype(cls, val):
+        """Returns the dtype of the input variable."""
+        return np.array(val).dtype
+    #
+
+    @classmethod
+    def _getsubdtype(cls, val):
+        """Returns the type of the dtype of the input variable."""
+        return np.array(val).dtype.type
+    #
+    # This is a bit annoying. We want to return the "general" type in most
+    # cases (ie. "string" rather than "S10"), but we want to return the
+    # specific type for datetime64 (ie. "datetime64[us]" rather than
+    # "datetime64").
+
+    @classmethod
+    def _dtypeortype(cls, dtype):
+        """Returns dtype for datetime64 and type of dtype otherwise."""
+        if dtype.type == np.datetime64:
+            return dtype
+        return dtype.type
+    #
+
+    @classmethod
+    def upgrade_mapper(cls, func, default=None):
+        """
+    Upgrade the mapper of a StringConverter by adding a new function and
+    its corresponding default.
+
+    The input function (or sequence of functions) and its associated
+    default value (if any) is inserted in penultimate position of the
+    mapper.  The corresponding type is estimated from the dtype of the
+    default value.
+
+    Parameters
+    ----------
+    func : var
+        Function, or sequence of functions
+
+    Examples
+    --------
+    >>> import dateutil.parser
+    >>> import datetime
+    >>> dateparser = datetustil.parser.parse
+    >>> defaultdate = datetime.date(2000, 1, 1)
+    >>> StringConverter.upgrade_mapper(dateparser, default=defaultdate)
+        """
+        # Func is a single functions
+        if hasattr(func, '__call__'):
+            cls._mapper.insert(-1, (cls._getsubdtype(default), func, default))
+            return
+        elif hasattr(func, '__iter__'):
+            if isinstance(func[0], (tuple, list)):
+                for _ in func:
+                    cls._mapper.insert(-1, _)
+                return
+            if default is None:
+                default = [None] * len(func)
+            else:
+                default = list(default)
+                default.append([None] * (len(func) - len(default)))
+            for (fct, dft) in zip(func, default):
+                cls._mapper.insert(-1, (cls._getsubdtype(dft), fct, dft))
+    #
+
+    def __init__(self, dtype_or_func=None, default=None, missing_values=None,
+                 locked=False):
+        # Convert unicode (for Py3)
+        if isinstance(missing_values, unicode):
+            missing_values = asbytes(missing_values)
+        elif isinstance(missing_values, (list, tuple)):
+            missing_values = asbytes_nested(missing_values)
+        # Defines a lock for upgrade
+        self._locked = bool(locked)
+        # No input dtype: minimal initialization
+        if dtype_or_func is None:
+            self.func = str2bool
+            self._status = 0
+            self.default = default or False
+            dtype = np.dtype('bool')
+        else:
+            # Is the input a np.dtype ?
+            try:
+                self.func = None
+                dtype = np.dtype(dtype_or_func)
+            except TypeError:
+                # dtype_or_func must be a function, then
+                if not hasattr(dtype_or_func, '__call__'):
+                    errmsg = ("The input argument `dtype` is neither a"
+                              " function nor a dtype (got '%s' instead)")
+                    raise TypeError(errmsg % type(dtype_or_func))
+                # Set the function
+                self.func = dtype_or_func
+                # If we don't have a default, try to guess it or set it to
+                # None
+                if default is None:
+                    try:
+                        default = self.func(asbytes('0'))
+                    except ValueError:
+                        default = None
+                dtype = self._getdtype(default)
+            # Set the status according to the dtype
+            _status = -1
+            for (i, (deftype, func, default_def)) in enumerate(self._mapper):
+                if np.issubdtype(dtype.type, deftype):
+                    _status = i
+                    if default is None:
+                        self.default = default_def
+                    else:
+                        self.default = default
+                    break
+            # if a converter for the specific dtype is available use that
+            last_func = func
+            for (i, (deftype, func, default_def)) in enumerate(self._mapper):
+                if dtype.type == deftype:
+                    _status = i
+                    last_func = func
+                    if default is None:
+                        self.default = default_def
+                    else:
+                        self.default = default
+                    break
+            func = last_func
+            if _status == -1:
+                # We never found a match in the _mapper...
+                _status = 0
+                self.default = default
+            self._status = _status
+            # If the input was a dtype, set the function to the last we saw
+            if self.func is None:
+                self.func = func
+            # If the status is 1 (int), change the function to
+            # something more robust.
+            if self.func == self._mapper[1][1]:
+                if issubclass(dtype.type, np.uint64):
+                    self.func = np.uint64
+                elif issubclass(dtype.type, np.int64):
+                    self.func = np.int64
+                else:
+                    self.func = lambda x: int(float(x))
+        # Store the list of strings corresponding to missing values.
+        if missing_values is None:
+            self.missing_values = set([asbytes('')])
+        else:
+            if isinstance(missing_values, bytes):
+                missing_values = missing_values.split(asbytes(","))
+            self.missing_values = set(list(missing_values) + [asbytes('')])
+        #
+        self._callingfunction = self._strict_call
+        self.type = self._dtypeortype(dtype)
+        self._checked = False
+        self._initial_default = default
+    #
+
+    def _loose_call(self, value):
+        try:
+            return self.func(value)
+        except ValueError:
+            return self.default
+    #
+
+    def _strict_call(self, value):
+        try:
+
+            # We check if we can convert the value using the current function
+            new_value = self.func(value)
+
+            # In addition to having to check whether func can convert the
+            # value, we also have to make sure that we don't get overflow
+            # errors for integers.
+            if self.func is int:
+                try:
+                    np.array(value, dtype=self.type)
+                except OverflowError:
+                    raise ValueError
+
+            # We're still here so we can now return the new value
+            return new_value
+
+        except ValueError:
+            if value.strip() in self.missing_values:
+                if not self._status:
+                    self._checked = False
+                return self.default
+            raise ValueError("Cannot convert string '%s'" % value)
+    #
+
+    def __call__(self, value):
+        return self._callingfunction(value)
+    #
+
+    def upgrade(self, value):
+        """
+        Find the best converter for a given string, and return the result.
+
+        The supplied string `value` is converted by testing different
+        converters in order. First the `func` method of the
+        `StringConverter` instance is tried, if this fails other available
+        converters are tried.  The order in which these other converters
+        are tried is determined by the `_status` attribute of the instance.
+
+        Parameters
+        ----------
+        value : str
+            The string to convert.
+
+        Returns
+        -------
+        out : any
+            The result of converting `value` with the appropriate converter.
+
+        """
+        self._checked = True
+        try:
+            return self._strict_call(value)
+        except ValueError:
+            # Raise an exception if we locked the converter...
+            if self._locked:
+                errmsg = "Converter is locked and cannot be upgraded"
+                raise ConverterLockError(errmsg)
+            _statusmax = len(self._mapper)
+            # Complains if we try to upgrade by the maximum
+            _status = self._status
+            if _status == _statusmax:
+                errmsg = "Could not find a valid conversion function"
+                raise ConverterError(errmsg)
+            elif _status < _statusmax - 1:
+                _status += 1
+            (self.type, self.func, default) = self._mapper[_status]
+            self._status = _status
+            if self._initial_default is not None:
+                self.default = self._initial_default
+            else:
+                self.default = default
+            return self.upgrade(value)
+
+    def iterupgrade(self, value):
+        self._checked = True
+        if not hasattr(value, '__iter__'):
+            value = (value,)
+        _strict_call = self._strict_call
+        try:
+            for _m in value:
+                _strict_call(_m)
+        except ValueError:
+            # Raise an exception if we locked the converter...
+            if self._locked:
+                errmsg = "Converter is locked and cannot be upgraded"
+                raise ConverterLockError(errmsg)
+            _statusmax = len(self._mapper)
+            # Complains if we try to upgrade by the maximum
+            _status = self._status
+            if _status == _statusmax:
+                raise ConverterError(
+                    "Could not find a valid conversion function"
+                    )
+            elif _status < _statusmax - 1:
+                _status += 1
+            (self.type, self.func, default) = self._mapper[_status]
+            if self._initial_default is not None:
+                self.default = self._initial_default
+            else:
+                self.default = default
+            self._status = _status
+            self.iterupgrade(value)
+
+    def update(self, func, default=None, testing_value=None,
+               missing_values=asbytes(''), locked=False):
+        """
+        Set StringConverter attributes directly.
+
+        Parameters
+        ----------
+        func : function
+            Conversion function.
+        default : any, optional
+            Value to return by default, that is, when the string to be
+            converted is flagged as missing. If not given,
+            `StringConverter` tries to supply a reasonable default value.
+        testing_value : str, optional
+            A string representing a standard input value of the converter.
+            This string is used to help defining a reasonable default
+            value.
+        missing_values : sequence of str, optional
+            Sequence of strings indicating a missing value.
+        locked : bool, optional
+            Whether the StringConverter should be locked to prevent
+            automatic upgrade or not. Default is False.
+
+        Notes
+        -----
+        `update` takes the same parameters as the constructor of
+        `StringConverter`, except that `func` does not accept a `dtype`
+        whereas `dtype_or_func` in the constructor does.
+
+        """
+        self.func = func
+        self._locked = locked
+        # Don't reset the default to None if we can avoid it
+        if default is not None:
+            self.default = default
+            self.type = self._dtypeortype(self._getdtype(default))
+        else:
+            try:
+                tester = func(testing_value or asbytes('1'))
+            except (TypeError, ValueError):
+                tester = None
+            self.type = self._dtypeortype(self._getdtype(tester))
+        # Add the missing values to the existing set
+        if missing_values is not None:
+            if _is_bytes_like(missing_values):
+                self.missing_values.add(missing_values)
+            elif hasattr(missing_values, '__iter__'):
+                for val in missing_values:
+                    self.missing_values.add(val)
+        else:
+            self.missing_values = []
+
+
+def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs):
+    """
+    Convenience function to create a `np.dtype` object.
+
+    The function processes the input `dtype` and matches it with the given
+    names.
+
+    Parameters
+    ----------
+    ndtype : var
+        Definition of the dtype. Can be any string or dictionary recognized
+        by the `np.dtype` function, or a sequence of types.
+    names : str or sequence, optional
+        Sequence of strings to use as field names for a structured dtype.
+        For convenience, `names` can be a string of a comma-separated list
+        of names.
+    defaultfmt : str, optional
+        Format string used to define missing names, such as ``"f%i"``
+        (default) or ``"fields_%02i"``.
+    validationargs : optional
+        A series of optional arguments used to initialize a
+        `NameValidator`.
+
+    Examples
+    --------
+    >>> np.lib._iotools.easy_dtype(float)
+    dtype('float64')
+    >>> np.lib._iotools.easy_dtype("i4, f8")
+    dtype([('f0', '<i4'), ('f1', '<f8')])
+    >>> np.lib._iotools.easy_dtype("i4, f8", defaultfmt="field_%03i")
+    dtype([('field_000', '<i4'), ('field_001', '<f8')])
+
+    >>> np.lib._iotools.easy_dtype((int, float, float), names="a,b,c")
+    dtype([('a', '<i8'), ('b', '<f8'), ('c', '<f8')])
+    >>> np.lib._iotools.easy_dtype(float, names="a,b,c")
+    dtype([('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
+
+    """
+    try:
+        ndtype = np.dtype(ndtype)
+    except TypeError:
+        validate = NameValidator(**validationargs)
+        nbfields = len(ndtype)
+        if names is None:
+            names = [''] * len(ndtype)
+        elif isinstance(names, basestring):
+            names = names.split(",")
+        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:
+                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,
+                                        defaultfmt=defaultfmt)
+        # No implicit names
+        elif (nbtypes > 0):
+            validate = NameValidator(**validationargs)
+            # Default initial names : should we change the format ?
+            if ((ndtype.names == tuple("f%i" % i for i in range(nbtypes))) and
+                    (defaultfmt != "f%i")):
+                ndtype.names = validate([''] * nbtypes, defaultfmt=defaultfmt)
+            # Explicit initial names : just validate
+            else:
+                ndtype.names = validate(ndtype.names, defaultfmt=defaultfmt)
+    return ndtype
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_version.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_version.py
new file mode 100644
index 0000000000..54b9c1dc78
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/_version.py
@@ -0,0 +1,156 @@
+"""Utility to compare (Numpy) version strings.
+
+The NumpyVersion class allows properly comparing numpy version strings.
+The LooseVersion and StrictVersion classes that distutils provides don't
+work; they don't recognize anything like alpha/beta/rc/dev versions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import re
+
+from numpy.compat import basestring
+
+
+__all__ = ['NumpyVersion']
+
+
+class NumpyVersion():
+    """Parse and compare numpy version strings.
+
+    Numpy has the following versioning scheme (numbers given are examples; they
+    can be > 9) in principle):
+
+    - Released version: '1.8.0', '1.8.1', etc.
+    - Alpha: '1.8.0a1', '1.8.0a2', etc.
+    - Beta: '1.8.0b1', '1.8.0b2', etc.
+    - Release candidates: '1.8.0rc1', '1.8.0rc2', etc.
+    - Development versions: '1.8.0.dev-f1234afa' (git commit hash appended)
+    - Development versions after a1: '1.8.0a1.dev-f1234afa',
+                                     '1.8.0b2.dev-f1234afa',
+                                     '1.8.1rc1.dev-f1234afa', etc.
+    - Development versions (no git hash available): '1.8.0.dev-Unknown'
+
+    Comparing needs to be done against a valid version string or other
+    `NumpyVersion` instance. Note that all development versions of the same
+    (pre-)release compare equal.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    vstring : str
+        Numpy version string (``np.__version__``).
+
+    Examples
+    --------
+    >>> from numpy.lib import NumpyVersion
+    >>> if NumpyVersion(np.__version__) < '1.7.0'):
+    ...     print('skip')
+    skip
+
+    >>> NumpyVersion('1.7')  # raises ValueError, add ".0"
+
+    """
+
+    def __init__(self, vstring):
+        self.vstring = vstring
+        ver_main = re.match(r'\d[.]\d+[.]\d+', vstring)
+        if not ver_main:
+            raise ValueError("Not a valid numpy version string")
+
+        self.version = ver_main.group()
+        self.major, self.minor, self.bugfix = [int(x) for x in
+            self.version.split('.')]
+        if len(vstring) == ver_main.end():
+            self.pre_release = 'final'
+        else:
+            alpha = re.match(r'a\d', vstring[ver_main.end():])
+            beta = re.match(r'b\d', vstring[ver_main.end():])
+            rc = re.match(r'rc\d', vstring[ver_main.end():])
+            pre_rel = [m for m in [alpha, beta, rc] if m is not None]
+            if pre_rel:
+                self.pre_release = pre_rel[0].group()
+            else:
+                self.pre_release = ''
+
+        self.is_devversion = bool(re.search(r'.dev', vstring))
+
+    def _compare_version(self, other):
+        """Compare major.minor.bugfix"""
+        if self.major == other.major:
+            if self.minor == other.minor:
+                if self.bugfix == other.bugfix:
+                    vercmp = 0
+                elif self.bugfix > other.bugfix:
+                    vercmp = 1
+                else:
+                    vercmp = -1
+            elif self.minor > other.minor:
+                vercmp = 1
+            else:
+                vercmp = -1
+        elif self.major > other.major:
+            vercmp = 1
+        else:
+            vercmp = -1
+
+        return vercmp
+
+    def _compare_pre_release(self, other):
+        """Compare alpha/beta/rc/final."""
+        if self.pre_release == other.pre_release:
+            vercmp = 0
+        elif self.pre_release == 'final':
+            vercmp = 1
+        elif other.pre_release == 'final':
+            vercmp = -1
+        elif self.pre_release > other.pre_release:
+            vercmp = 1
+        else:
+            vercmp = -1
+
+        return vercmp
+
+    def _compare(self, other):
+        if not isinstance(other, (basestring, NumpyVersion)):
+            raise ValueError("Invalid object to compare with NumpyVersion.")
+
+        if isinstance(other, basestring):
+            other = NumpyVersion(other)
+
+        vercmp = self._compare_version(other)
+        if vercmp == 0:
+            # Same x.y.z version, check for alpha/beta/rc
+            vercmp = self._compare_pre_release(other)
+            if vercmp == 0:
+                # Same version and same pre-release, check if dev version
+                if self.is_devversion is other.is_devversion:
+                    vercmp = 0
+                elif self.is_devversion:
+                    vercmp = -1
+                else:
+                    vercmp = 1
+
+        return vercmp
+
+    def __lt__(self, other):
+        return self._compare(other) < 0
+
+    def __le__(self, other):
+        return self._compare(other) <= 0
+
+    def __eq__(self, other):
+        return self._compare(other) == 0
+
+    def __ne__(self, other):
+        return self._compare(other) != 0
+
+    def __gt__(self, other):
+        return self._compare(other) > 0
+
+    def __ge__(self, other):
+        return self._compare(other) >= 0
+
+    def __repr(self):
+        return "NumpyVersion(%s)" % self.vstring
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.py
new file mode 100644
index 0000000000..c30ef6bf58
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.py
@@ -0,0 +1,1494 @@
+"""
+The arraypad module contains a group of functions to pad values onto the edges
+of an n-dimensional array.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+
+__all__ = ['pad']
+
+
+###############################################################################
+# Private utility functions.
+
+
+def _arange_ndarray(arr, shape, axis, reverse=False):
+    """
+    Create an ndarray of `shape` with increments along specified `axis`
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    shape : tuple of ints
+        Shape of desired array. Should be equivalent to `arr.shape` except
+        `shape[axis]` which may have any positive value.
+    axis : int
+        Axis to increment along.
+    reverse : bool
+        If False, increment in a positive fashion from 1 to `shape[axis]`,
+        inclusive. If True, the bounds are the same but the order reversed.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array sized to pad `arr` along `axis`, with linear range from
+        1 to `shape[axis]` along specified `axis`.
+
+    Notes
+    -----
+    The range is deliberately 1-indexed for this specific use case. Think of
+    this algorithm as broadcasting `np.arange` to a single `axis` of an
+    arbitrarily shaped ndarray.
+
+    """
+    initshape = tuple(1 if i != axis else shape[axis]
+                      for (i, x) in enumerate(arr.shape))
+    if not reverse:
+        padarr = np.arange(1, shape[axis] + 1)
+    else:
+        padarr = np.arange(shape[axis], 0, -1)
+    padarr = padarr.reshape(initshape)
+    for i, dim in enumerate(shape):
+        if padarr.shape[i] != dim:
+            padarr = padarr.repeat(dim, axis=i)
+    return padarr
+
+
+def _round_ifneeded(arr, dtype):
+    """
+    Rounds arr inplace if destination dtype is integer.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array.
+    dtype : dtype
+        The dtype of the destination array.
+
+    """
+    if np.issubdtype(dtype, np.integer):
+        arr.round(out=arr)
+
+
+def _prepend_const(arr, pad_amt, val, axis=-1):
+    """
+    Prepend constant `val` along `axis` of `arr`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    val : scalar
+        Constant value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` constant `val` prepended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+    if val == 0:
+        return np.concatenate((np.zeros(padshape, dtype=arr.dtype), arr),
+                              axis=axis)
+    else:
+        return np.concatenate(((np.zeros(padshape) + val).astype(arr.dtype),
+                               arr), axis=axis)
+
+
+def _append_const(arr, pad_amt, val, axis=-1):
+    """
+    Append constant `val` along `axis` of `arr`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    val : scalar
+        Constant value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` constant `val` appended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+    if val == 0:
+        return np.concatenate((arr, np.zeros(padshape, dtype=arr.dtype)),
+                              axis=axis)
+    else:
+        return np.concatenate(
+            (arr, (np.zeros(padshape) + val).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_edge(arr, pad_amt, axis=-1):
+    """
+    Prepend `pad_amt` to `arr` along `axis` by extending edge values.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, extended by `pad_amt` edge values appended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    edge_slice = tuple(slice(None) if i != axis else 0
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    edge_arr = arr[edge_slice].reshape(pad_singleton)
+    return np.concatenate((edge_arr.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_edge(arr, pad_amt, axis=-1):
+    """
+    Append `pad_amt` to `arr` along `axis` by extending edge values.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, extended by `pad_amt` edge values prepended along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    edge_slice = tuple(slice(None) if i != axis else arr.shape[axis] - 1
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    edge_arr = arr[edge_slice].reshape(pad_singleton)
+    return np.concatenate((arr, edge_arr.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _prepend_ramp(arr, pad_amt, end, axis=-1):
+    """
+    Prepend linear ramp along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    end : scalar
+        Constal value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region ramps linearly from the edge value to `end`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Generate shape for final concatenated array
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+
+    # Generate an n-dimensional array incrementing along `axis`
+    ramp_arr = _arange_ndarray(arr, padshape, axis,
+                               reverse=True).astype(np.float64)
+
+    # Appropriate slicing to extract n-dimensional edge along `axis`
+    edge_slice = tuple(slice(None) if i != axis else 0
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract edge, reshape to original rank, and extend along `axis`
+    edge_pad = arr[edge_slice].reshape(pad_singleton).repeat(pad_amt, axis)
+
+    # Linear ramp
+    slope = (end - edge_pad) / float(pad_amt)
+    ramp_arr = ramp_arr * slope
+    ramp_arr += edge_pad
+    _round_ifneeded(ramp_arr, arr.dtype)
+
+    # Ramp values will most likely be float, cast them to the same type as arr
+    return np.concatenate((ramp_arr.astype(arr.dtype), arr), axis=axis)
+
+
+def _append_ramp(arr, pad_amt, end, axis=-1):
+    """
+    Append linear ramp along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    end : scalar
+        Constal value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region ramps linearly from the edge value to `end`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Generate shape for final concatenated array
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+
+    # Generate an n-dimensional array incrementing along `axis`
+    ramp_arr = _arange_ndarray(arr, padshape, axis,
+                               reverse=False).astype(np.float64)
+
+    # Slice a chunk from the edge to calculate stats on
+    edge_slice = tuple(slice(None) if i != axis else -1
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract edge, reshape to original rank, and extend along `axis`
+    edge_pad = arr[edge_slice].reshape(pad_singleton).repeat(pad_amt, axis)
+
+    # Linear ramp
+    slope = (end - edge_pad) / float(pad_amt)
+    ramp_arr = ramp_arr * slope
+    ramp_arr += edge_pad
+    _round_ifneeded(ramp_arr, arr.dtype)
+
+    # Ramp values will most likely be float, cast them to the same type as arr
+    return np.concatenate((arr, ramp_arr.astype(arr.dtype)), axis=axis)
+
+
+def _prepend_max(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` maximum values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate maximum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        prepended region is the maximum of the first `num` values along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    max_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate max, reshape to add singleton dimension back
+    max_chunk = arr[max_slice].max(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `max_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((max_chunk.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_max(arr, pad_amt, num, axis=-1):
+    """
+    Pad one `axis` of `arr` with the maximum of the last `num` elements.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate maximum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the maximum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        max_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        max_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate max, reshape to add singleton dimension back
+    max_chunk = arr[max_slice].max(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `max_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((arr, max_chunk.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _prepend_mean(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` mean values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate mean.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the mean of the first `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    mean_slice = tuple(slice(None) if i != axis else slice(num)
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate mean, reshape to add singleton dimension back
+    mean_chunk = arr[mean_slice].mean(axis).reshape(pad_singleton)
+    _round_ifneeded(mean_chunk, arr.dtype)
+
+    # Concatenate `arr` with `mean_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((mean_chunk.repeat(pad_amt, axis).astype(arr.dtype),
+                           arr), axis=axis)
+
+
+def _append_mean(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` mean values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate mean.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the maximum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        mean_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        mean_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate mean, reshape to add singleton dimension back
+    mean_chunk = arr[mean_slice].mean(axis=axis).reshape(pad_singleton)
+    _round_ifneeded(mean_chunk, arr.dtype)
+
+    # Concatenate `arr` with `mean_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (arr, mean_chunk.repeat(pad_amt, axis).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_med(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate median.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the median of the first `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    med_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate median, reshape to add singleton dimension back
+    med_chunk = np.median(arr[med_slice], axis=axis).reshape(pad_singleton)
+    _round_ifneeded(med_chunk, arr.dtype)
+
+    # Concatenate `arr` with `med_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (med_chunk.repeat(pad_amt, axis).astype(arr.dtype), arr), axis=axis)
+
+
+def _append_med(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate median.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the median of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        med_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        med_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate median, reshape to add singleton dimension back
+    med_chunk = np.median(arr[med_slice], axis=axis).reshape(pad_singleton)
+    _round_ifneeded(med_chunk, arr.dtype)
+
+    # Concatenate `arr` with `med_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (arr, med_chunk.repeat(pad_amt, axis).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_min(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` minimum values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate minimum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the minimum of the first `num` values along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    min_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate min, reshape to add singleton dimension back
+    min_chunk = arr[min_slice].min(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `min_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((min_chunk.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_min(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate minimum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the minimum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        min_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        min_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate min, reshape to add singleton dimension back
+    min_chunk = arr[min_slice].min(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `min_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((arr, min_chunk.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _pad_ref(arr, pad_amt, method, axis=-1):
+    """
+    Pad `axis` of `arr` by reflection.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    method : str
+        Controls method of reflection; options are 'even' or 'odd'.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded with reflected
+        values from the original array.
+
+    Notes
+    -----
+    This algorithm does not pad with repetition, i.e. the edges are not
+    repeated in the reflection. For that behavior, use `mode='symmetric'`.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    ref_slice = tuple(slice(None) if i != axis else slice(pad_amt[0], 0, -1)
+                      for (i, x) in enumerate(arr.shape))
+
+    ref_chunk1 = arr[ref_slice]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        ref_chunk1 = ref_chunk1.reshape(pad_singleton)
+
+    # Memory/computationally more expensive, only do this if `method='odd'`
+    if 'odd' in method and pad_amt[0] > 0:
+        edge_slice1 = tuple(slice(None) if i != axis else 0
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice1].reshape(pad_singleton)
+        ref_chunk1 = 2 * edge_chunk - ref_chunk1
+        del edge_chunk
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    start = arr.shape[axis] - pad_amt[1] - 1
+    end = arr.shape[axis] - 1
+    ref_slice = tuple(slice(None) if i != axis else slice(start, end)
+                      for (i, x) in enumerate(arr.shape))
+    rev_idx = tuple(slice(None) if i != axis else slice(None, None, -1)
+                    for (i, x) in enumerate(arr.shape))
+    ref_chunk2 = arr[ref_slice][rev_idx]
+
+    if pad_amt[1] == 1:
+        ref_chunk2 = ref_chunk2.reshape(pad_singleton)
+
+    if 'odd' in method:
+        edge_slice2 = tuple(slice(None) if i != axis else -1
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice2].reshape(pad_singleton)
+        ref_chunk2 = 2 * edge_chunk - ref_chunk2
+        del edge_chunk
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((ref_chunk1, arr, ref_chunk2), axis=axis)
+
+
+def _pad_sym(arr, pad_amt, method, axis=-1):
+    """
+    Pad `axis` of `arr` by symmetry.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    method : str
+        Controls method of symmetry; options are 'even' or 'odd'.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded with symmetric
+        values from the original array.
+
+    Notes
+    -----
+    This algorithm DOES pad with repetition, i.e. the edges are repeated.
+    For padding without repeated edges, use `mode='reflect'`.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    sym_slice = tuple(slice(None) if i != axis else slice(0, pad_amt[0])
+                      for (i, x) in enumerate(arr.shape))
+    rev_idx = tuple(slice(None) if i != axis else slice(None, None, -1)
+                    for (i, x) in enumerate(arr.shape))
+    sym_chunk1 = arr[sym_slice][rev_idx]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        sym_chunk1 = sym_chunk1.reshape(pad_singleton)
+
+    # Memory/computationally more expensive, only do this if `method='odd'`
+    if 'odd' in method and pad_amt[0] > 0:
+        edge_slice1 = tuple(slice(None) if i != axis else 0
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice1].reshape(pad_singleton)
+        sym_chunk1 = 2 * edge_chunk - sym_chunk1
+        del edge_chunk
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    start = arr.shape[axis] - pad_amt[1]
+    end = arr.shape[axis]
+    sym_slice = tuple(slice(None) if i != axis else slice(start, end)
+                      for (i, x) in enumerate(arr.shape))
+    sym_chunk2 = arr[sym_slice][rev_idx]
+
+    if pad_amt[1] == 1:
+        sym_chunk2 = sym_chunk2.reshape(pad_singleton)
+
+    if 'odd' in method:
+        edge_slice2 = tuple(slice(None) if i != axis else -1
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice2].reshape(pad_singleton)
+        sym_chunk2 = 2 * edge_chunk - sym_chunk2
+        del edge_chunk
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((sym_chunk1, arr, sym_chunk2), axis=axis)
+
+
+def _pad_wrap(arr, pad_amt, axis=-1):
+    """
+    Pad `axis` of `arr` via wrapping.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded wrapped values
+        from the opposite end of `axis`.
+
+    Notes
+    -----
+    This method of padding is also known as 'tile' or 'tiling'.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    start = arr.shape[axis] - pad_amt[0]
+    end = arr.shape[axis]
+    wrap_slice = tuple(slice(None) if i != axis else slice(start, end)
+                       for (i, x) in enumerate(arr.shape))
+    wrap_chunk1 = arr[wrap_slice]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        wrap_chunk1 = wrap_chunk1.reshape(pad_singleton)
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    wrap_slice = tuple(slice(None) if i != axis else slice(0, pad_amt[1])
+                       for (i, x) in enumerate(arr.shape))
+    wrap_chunk2 = arr[wrap_slice]
+
+    if pad_amt[1] == 1:
+        wrap_chunk2 = wrap_chunk2.reshape(pad_singleton)
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((wrap_chunk1, arr, wrap_chunk2), axis=axis)
+
+
+def _normalize_shape(ndarray, shape, cast_to_int=True):
+    """
+    Private function which does some checks and normalizes the possibly
+    much simpler representations of 'pad_width', 'stat_length',
+    'constant_values', 'end_values'.
+
+    Parameters
+    ----------
+    narray : ndarray
+        Input ndarray
+    shape : {sequence, array_like, float, int}, optional
+        The width of padding (pad_width), the number of elements on the
+        edge of the narray used for statistics (stat_length), the constant
+        value(s) to use when filling padded regions (constant_values), or the
+        endpoint target(s) for linear ramps (end_values).
+        ((before_1, after_1), ... (before_N, after_N)) unique number of
+        elements for each axis where `N` is rank of `narray`.
+        ((before, after),) yields same before and after constants for each
+        axis.
+        (constant,) or val is a shortcut for before = after = constant for
+        all axes.
+    cast_to_int : bool, optional
+        Controls if values in ``shape`` will be rounded and cast to int
+        before being returned.
+
+    Returns
+    -------
+    normalized_shape : tuple of tuples
+        val                               => ((val, val), (val, val), ...)
+        [[val1, val2], [val3, val4], ...] => ((val1, val2), (val3, val4), ...)
+        ((val1, val2), (val3, val4), ...) => no change
+        [[val1, val2], ]                  => ((val1, val2), (val1, val2), ...)
+        ((val1, val2), )                  => ((val1, val2), (val1, val2), ...)
+        [[val ,     ], ]                  => ((val, val), (val, val), ...)
+        ((val ,     ), )                  => ((val, val), (val, val), ...)
+
+    """
+    ndims = ndarray.ndim
+
+    # Shortcut shape=None
+    if shape is None:
+        return ((None, None), ) * ndims
+
+    # Convert any input `info` to a NumPy array
+    arr = np.asarray(shape)
+
+    # Switch based on what input looks like
+    if arr.ndim <= 1:
+        if arr.shape == () or arr.shape == (1,):
+            # Single scalar input
+            #   Create new array of ones, multiply by the scalar
+            arr = np.ones((ndims, 2), dtype=ndarray.dtype) * arr
+        elif arr.shape == (2,):
+            # Apply padding (before, after) each axis
+            #   Create new axis 0, repeat along it for every axis
+            arr = arr[np.newaxis, :].repeat(ndims, axis=0)
+        else:
+            fmt = "Unable to create correctly shaped tuple from %s"
+            raise ValueError(fmt % (shape,))
+
+    elif arr.ndim == 2:
+        if arr.shape[1] == 1 and arr.shape[0] == ndims:
+            # Padded before and after by the same amount
+            arr = arr.repeat(2, axis=1)
+        elif arr.shape[0] == ndims:
+            # Input correctly formatted, pass it on as `arr`
+            arr = shape
+        else:
+            fmt = "Unable to create correctly shaped tuple from %s"
+            raise ValueError(fmt % (shape,))
+
+    else:
+        fmt = "Unable to create correctly shaped tuple from %s"
+        raise ValueError(fmt % (shape,))
+
+    # Cast if necessary
+    if cast_to_int is True:
+        arr = np.round(arr).astype(int)
+
+    # Convert list of lists to tuple of tuples
+    return tuple(tuple(axis) for axis in arr.tolist())
+
+
+def _validate_lengths(narray, number_elements):
+    """
+    Private function which does some checks and reformats pad_width and
+    stat_length using _normalize_shape.
+
+    Parameters
+    ----------
+    narray : ndarray
+        Input ndarray
+    number_elements : {sequence, int}, optional
+        The width of padding (pad_width) or the number of elements on the edge
+        of the narray used for statistics (stat_length).
+        ((before_1, after_1), ... (before_N, after_N)) unique number of
+        elements for each axis.
+        ((before, after),) yields same before and after constants for each
+        axis.
+        (constant,) or int is a shortcut for before = after = constant for all
+        axes.
+
+    Returns
+    -------
+    _validate_lengths : tuple of tuples
+        int                               => ((int, int), (int, int), ...)
+        [[int1, int2], [int3, int4], ...] => ((int1, int2), (int3, int4), ...)
+        ((int1, int2), (int3, int4), ...) => no change
+        [[int1, int2], ]                  => ((int1, int2), (int1, int2), ...)
+        ((int1, int2), )                  => ((int1, int2), (int1, int2), ...)
+        [[int ,     ], ]                  => ((int, int), (int, int), ...)
+        ((int ,     ), )                  => ((int, int), (int, int), ...)
+
+    """
+    normshp = _normalize_shape(narray, number_elements)
+    for i in normshp:
+        chk = [1 if x is None else x for x in i]
+        chk = [1 if x >= 0 else -1 for x in chk]
+        if (chk[0] < 0) or (chk[1] < 0):
+            fmt = "%s cannot contain negative values."
+            raise ValueError(fmt % (number_elements,))
+    return normshp
+
+
+###############################################################################
+# Public functions
+
+
+def pad(array, pad_width, mode, **kwargs):
+    """
+    Pads an array.
+
+    Parameters
+    ----------
+    array : array_like of rank N
+        Input array
+    pad_width : {sequence, array_like, int}
+        Number of values padded to the edges of each axis.
+        ((before_1, after_1), ... (before_N, after_N)) unique pad widths
+        for each axis.
+        ((before, after),) yields same before and after pad for each axis.
+        (pad,) or int is a shortcut for before = after = pad width for all
+        axes.
+    mode : str or function
+        One of the following string values or a user supplied function.
+
+        'constant'
+            Pads with a constant value.
+        'edge'
+            Pads with the edge values of array.
+        'linear_ramp'
+            Pads with the linear ramp between end_value and the
+            array edge value.
+        'maximum'
+            Pads with the maximum value of all or part of the
+            vector along each axis.
+        'mean'
+            Pads with the mean value of all or part of the
+            vector along each axis.
+        'median'
+            Pads with the median value of all or part of the
+            vector along each axis.
+        'minimum'
+            Pads with the minimum value of all or part of the
+            vector along each axis.
+        'reflect'
+            Pads with the reflection of the vector mirrored on
+            the first and last values of the vector along each
+            axis.
+        'symmetric'
+            Pads with the reflection of the vector mirrored
+            along the edge of the array.
+        'wrap'
+            Pads with the wrap of the vector along the axis.
+            The first values are used to pad the end and the
+            end values are used to pad the beginning.
+        <function>
+            Padding function, see Notes.
+    stat_length : sequence or int, optional
+        Used in 'maximum', 'mean', 'median', and 'minimum'.  Number of
+        values at edge of each axis used to calculate the statistic value.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique statistic
+        lengths for each axis.
+
+        ((before, after),) yields same before and after statistic lengths
+        for each axis.
+
+        (stat_length,) or int is a shortcut for before = after = statistic
+        length for all axes.
+
+        Default is ``None``, to use the entire axis.
+    constant_values : sequence or int, optional
+        Used in 'constant'.  The values to set the padded values for each
+        axis.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique pad constants
+        for each axis.
+
+        ((before, after),) yields same before and after constants for each
+        axis.
+
+        (constant,) or int is a shortcut for before = after = constant for
+        all axes.
+
+        Default is 0.
+    end_values : sequence or int, optional
+        Used in 'linear_ramp'.  The values used for the ending value of the
+        linear_ramp and that will form the edge of the padded array.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique end values
+        for each axis.
+
+        ((before, after),) yields same before and after end values for each
+        axis.
+
+        (constant,) or int is a shortcut for before = after = end value for
+        all axes.
+
+        Default is 0.
+    reflect_type : {'even', 'odd'}, optional
+        Used in 'reflect', and 'symmetric'.  The 'even' style is the
+        default with an unaltered reflection around the edge value.  For
+        the 'odd' style, the extented part of the array is created by
+        subtracting the reflected values from two times the edge value.
+
+    Returns
+    -------
+    pad : ndarray
+        Padded array of rank equal to `array` with shape increased
+        according to `pad_width`.
+
+    Notes
+    -----
+    .. versionadded:: 1.7.0
+
+    For an array with rank greater than 1, some of the padding of later
+    axes is calculated from padding of previous axes.  This is easiest to
+    think about with a rank 2 array where the corners of the padded array
+    are calculated by using padded values from the first axis.
+
+    The padding function, if used, should return a rank 1 array equal in
+    length to the vector argument with padded values replaced. It has the
+    following signature::
+
+        padding_func(vector, iaxis_pad_width, iaxis, **kwargs)
+
+    where
+
+        vector : ndarray
+            A rank 1 array already padded with zeros.  Padded values are
+            vector[:pad_tuple[0]] and vector[-pad_tuple[1]:].
+        iaxis_pad_width : tuple
+            A 2-tuple of ints, iaxis_pad_width[0] represents the number of
+            values padded at the beginning of vector where
+            iaxis_pad_width[1] represents the number of values padded at
+            the end of vector.
+        iaxis : int
+            The axis currently being calculated.
+        kwargs : misc
+            Any keyword arguments the function requires.
+
+    Examples
+    --------
+    >>> a = [1, 2, 3, 4, 5]
+    >>> np.lib.pad(a, (2,3), 'constant', constant_values=(4, 6))
+    array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])
+
+    >>> np.lib.pad(a, (2, 3), 'edge')
+    array([1, 1, 1, 2, 3, 4, 5, 5, 5, 5])
+
+    >>> np.lib.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
+    array([ 5,  3,  1,  2,  3,  4,  5,  2, -1, -4])
+
+    >>> np.lib.pad(a, (2,), 'maximum')
+    array([5, 5, 1, 2, 3, 4, 5, 5, 5])
+
+    >>> np.lib.pad(a, (2,), 'mean')
+    array([3, 3, 1, 2, 3, 4, 5, 3, 3])
+
+    >>> np.lib.pad(a, (2,), 'median')
+    array([3, 3, 1, 2, 3, 4, 5, 3, 3])
+
+    >>> a = [[1, 2], [3, 4]]
+    >>> np.lib.pad(a, ((3, 2), (2, 3)), 'minimum')
+    array([[1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [3, 3, 3, 4, 3, 3, 3],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1]])
+
+    >>> a = [1, 2, 3, 4, 5]
+    >>> np.lib.pad(a, (2, 3), 'reflect')
+    array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])
+
+    >>> np.lib.pad(a, (2, 3), 'reflect', reflect_type='odd')
+    array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8])
+
+    >>> np.lib.pad(a, (2, 3), 'symmetric')
+    array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])
+
+    >>> np.lib.pad(a, (2, 3), 'symmetric', reflect_type='odd')
+    array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
+
+    >>> np.lib.pad(a, (2, 3), 'wrap')
+    array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])
+
+    >>> def padwithtens(vector, pad_width, iaxis, kwargs):
+    ...     vector[:pad_width[0]] = 10
+    ...     vector[-pad_width[1]:] = 10
+    ...     return vector
+
+    >>> a = np.arange(6)
+    >>> a = a.reshape((2, 3))
+
+    >>> np.lib.pad(a, 2, padwithtens)
+    array([[10, 10, 10, 10, 10, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10],
+           [10, 10,  0,  1,  2, 10, 10],
+           [10, 10,  3,  4,  5, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10]])
+    """
+    if not np.asarray(pad_width).dtype.kind == 'i':
+        raise TypeError('`pad_width` must be of integral type.')
+
+    narray = np.array(array)
+    pad_width = _validate_lengths(narray, pad_width)
+
+    allowedkwargs = {
+        'constant': ['constant_values'],
+        'edge': [],
+        'linear_ramp': ['end_values'],
+        'maximum': ['stat_length'],
+        'mean': ['stat_length'],
+        'median': ['stat_length'],
+        'minimum': ['stat_length'],
+        'reflect': ['reflect_type'],
+        'symmetric': ['reflect_type'],
+        'wrap': [],
+        }
+
+    kwdefaults = {
+        'stat_length': None,
+        'constant_values': 0,
+        'end_values': 0,
+        'reflect_type': 'even',
+        }
+
+    if isinstance(mode, np.compat.basestring):
+        # Make sure have allowed kwargs appropriate for mode
+        for key in kwargs:
+            if key not in allowedkwargs[mode]:
+                raise ValueError('%s keyword not in allowed keywords %s' %
+                                 (key, allowedkwargs[mode]))
+
+        # Set kwarg defaults
+        for kw in allowedkwargs[mode]:
+            kwargs.setdefault(kw, kwdefaults[kw])
+
+        # Need to only normalize particular keywords.
+        for i in kwargs:
+            if i == 'stat_length':
+                kwargs[i] = _validate_lengths(narray, kwargs[i])
+            if i in ['end_values', 'constant_values']:
+                kwargs[i] = _normalize_shape(narray, kwargs[i],
+                                             cast_to_int=False)
+    else:
+        # Drop back to old, slower np.apply_along_axis mode for user-supplied
+        # vector function
+        function = mode
+
+        # Create a new padded array
+        rank = list(range(len(narray.shape)))
+        total_dim_increase = [np.sum(pad_width[i]) for i in rank]
+        offset_slices = [slice(pad_width[i][0],
+                               pad_width[i][0] + narray.shape[i])
+                         for i in rank]
+        new_shape = np.array(narray.shape) + total_dim_increase
+        newmat = np.zeros(new_shape, narray.dtype)
+
+        # Insert the original array into the padded array
+        newmat[offset_slices] = narray
+
+        # This is the core of pad ...
+        for iaxis in rank:
+            np.apply_along_axis(function,
+                                iaxis,
+                                newmat,
+                                pad_width[iaxis],
+                                iaxis,
+                                kwargs)
+        return newmat
+
+    # If we get here, use new padding method
+    newmat = narray.copy()
+
+    # API preserved, but completely new algorithm which pads by building the
+    # entire block to pad before/after `arr` with in one step, for each axis.
+    if mode == 'constant':
+        for axis, ((pad_before, pad_after), (before_val, after_val)) \
+                in enumerate(zip(pad_width, kwargs['constant_values'])):
+            newmat = _prepend_const(newmat, pad_before, before_val, axis)
+            newmat = _append_const(newmat, pad_after, after_val, axis)
+
+    elif mode == 'edge':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            newmat = _prepend_edge(newmat, pad_before, axis)
+            newmat = _append_edge(newmat, pad_after, axis)
+
+    elif mode == 'linear_ramp':
+        for axis, ((pad_before, pad_after), (before_val, after_val)) \
+                in enumerate(zip(pad_width, kwargs['end_values'])):
+            newmat = _prepend_ramp(newmat, pad_before, before_val, axis)
+            newmat = _append_ramp(newmat, pad_after, after_val, axis)
+
+    elif mode == 'maximum':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_max(newmat, pad_before, chunk_before, axis)
+            newmat = _append_max(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'mean':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_mean(newmat, pad_before, chunk_before, axis)
+            newmat = _append_mean(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'median':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_med(newmat, pad_before, chunk_before, axis)
+            newmat = _append_med(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'minimum':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_min(newmat, pad_before, chunk_before, axis)
+            newmat = _append_min(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'reflect':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            if ((pad_before > 0) or
+                    (pad_after > 0)) and newmat.shape[axis] == 1:
+                # Extending singleton dimension for 'reflect' is legacy
+                # behavior; it really should raise an error.
+                newmat = _prepend_edge(newmat, pad_before, axis)
+                newmat = _append_edge(newmat, pad_after, axis)
+                continue
+
+            method = kwargs['reflect_type']
+            safe_pad = newmat.shape[axis] - 1
+            while ((pad_before > safe_pad) or (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_ref(newmat, (pad_iter_b,
+                                           pad_iter_a), method, axis)
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_ref(newmat, (pad_before, pad_after), method, axis)
+
+    elif mode == 'symmetric':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            method = kwargs['reflect_type']
+            safe_pad = newmat.shape[axis]
+            while ((pad_before > safe_pad) or
+                   (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_sym(newmat, (pad_iter_b,
+                                           pad_iter_a), method, axis)
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_sym(newmat, (pad_before, pad_after), method, axis)
+
+    elif mode == 'wrap':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            safe_pad = newmat.shape[axis]
+            while ((pad_before > safe_pad) or
+                   (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_wrap(newmat, (pad_iter_b, pad_iter_a), axis)
+
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_wrap(newmat, (pad_before, pad_after), axis)
+
+    return newmat
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.py
new file mode 100644
index 0000000000..17dfa7567e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.py
@@ -0,0 +1,480 @@
+"""
+Set operations for 1D numeric arrays based on sorting.
+
+:Contains:
+  ediff1d,
+  unique,
+  intersect1d,
+  setxor1d,
+  in1d,
+  union1d,
+  setdiff1d
+
+:Notes:
+
+For floating point arrays, inaccurate results may appear due to usual round-off
+and floating point comparison issues.
+
+Speed could be gained in some operations by an implementation of
+sort(), that can provide directly the permutation vectors, avoiding
+thus calls to argsort().
+
+To do: Optionally return indices analogously to unique for all functions.
+
+:Author: Robert Cimrman
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+
+__all__ = [
+    'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique',
+    'in1d'
+    ]
+
+
+def ediff1d(ary, to_end=None, to_begin=None):
+    """
+    The differences between consecutive elements of an array.
+
+    Parameters
+    ----------
+    ary : array_like
+        If necessary, will be flattened before the differences are taken.
+    to_end : array_like, optional
+        Number(s) to append at the end of the returned differences.
+    to_begin : array_like, optional
+        Number(s) to prepend at the beginning of the returned differences.
+
+    Returns
+    -------
+    ediff1d : ndarray
+        The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``.
+
+    See Also
+    --------
+    diff, gradient
+
+    Notes
+    -----
+    When applied to masked arrays, this function drops the mask information
+    if the `to_begin` and/or `to_end` parameters are used.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 0])
+    >>> np.ediff1d(x)
+    array([ 1,  2,  3, -7])
+
+    >>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99]))
+    array([-99,   1,   2,   3,  -7,  88,  99])
+
+    The returned array is always 1D.
+
+    >>> y = [[1, 2, 4], [1, 6, 24]]
+    >>> np.ediff1d(y)
+    array([ 1,  2, -3,  5, 18])
+
+    """
+    ary = np.asanyarray(ary).flat
+    ed = ary[1:] - ary[:-1]
+    arrays = [ed]
+    if to_begin is not None:
+        arrays.insert(0, to_begin)
+    if to_end is not None:
+        arrays.append(to_end)
+
+    if len(arrays) != 1:
+        # We'll save ourselves a copy of a potentially large array in
+        # the common case where neither to_begin or to_end was given.
+        ed = np.hstack(arrays)
+
+    return ed
+
+def unique(ar, return_index=False, return_inverse=False, return_counts=False):
+    """
+    Find the unique elements of an array.
+
+    Returns the sorted unique elements of an array. There are three optional
+    outputs in addition to the unique elements: the indices of the input array
+    that give the unique values, the indices of the unique array that
+    reconstruct the input array, and the number of times each unique value
+    comes up in the input array.
+
+    Parameters
+    ----------
+    ar : array_like
+        Input array. This will be flattened if it is not already 1-D.
+    return_index : bool, optional
+        If True, also return the indices of `ar` that result in the unique
+        array.
+    return_inverse : bool, optional
+        If True, also return the indices of the unique array that can be used
+        to reconstruct `ar`.
+    return_counts : bool, optional
+        If True, also return the number of times each unique value comes up
+        in `ar`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    unique : ndarray
+        The sorted unique values.
+    unique_indices : ndarray, optional
+        The indices of the first occurrences of the unique values in the
+        (flattened) original array. Only provided if `return_index` is True.
+    unique_inverse : ndarray, optional
+        The indices to reconstruct the (flattened) original array from the
+        unique array. Only provided if `return_inverse` is True.
+    unique_counts : ndarray, optional
+        The number of times each of the unique values comes up in the
+        original array. Only provided if `return_counts` is True.
+
+        .. versionadded:: 1.9.0
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.unique([1, 1, 2, 2, 3, 3])
+    array([1, 2, 3])
+    >>> a = np.array([[1, 1], [2, 3]])
+    >>> np.unique(a)
+    array([1, 2, 3])
+
+    Return the indices of the original array that give the unique values:
+
+    >>> a = np.array(['a', 'b', 'b', 'c', 'a'])
+    >>> u, indices = np.unique(a, return_index=True)
+    >>> u
+    array(['a', 'b', 'c'],
+           dtype='|S1')
+    >>> indices
+    array([0, 1, 3])
+    >>> a[indices]
+    array(['a', 'b', 'c'],
+           dtype='|S1')
+
+    Reconstruct the input array from the unique values:
+
+    >>> a = np.array([1, 2, 6, 4, 2, 3, 2])
+    >>> u, indices = np.unique(a, return_inverse=True)
+    >>> u
+    array([1, 2, 3, 4, 6])
+    >>> indices
+    array([0, 1, 4, 3, 1, 2, 1])
+    >>> u[indices]
+    array([1, 2, 6, 4, 2, 3, 2])
+
+    """
+    ar = np.asanyarray(ar).flatten()
+
+    optional_indices = return_index or return_inverse
+    optional_returns = optional_indices or return_counts
+
+    if ar.size == 0:
+        if not optional_returns:
+            ret = ar
+        else:
+            ret = (ar,)
+            if return_index:
+                ret += (np.empty(0, np.bool),)
+            if return_inverse:
+                ret += (np.empty(0, np.bool),)
+            if return_counts:
+                ret += (np.empty(0, np.intp),)
+        return ret
+
+    if optional_indices:
+        perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')
+        aux = ar[perm]
+    else:
+        ar.sort()
+        aux = ar
+    flag = np.concatenate(([True], aux[1:] != aux[:-1]))
+
+    if not optional_returns:
+        ret = aux[flag]
+    else:
+        ret = (aux[flag],)
+        if return_index:
+            ret += (perm[flag],)
+        if return_inverse:
+            iflag = np.cumsum(flag) - 1
+            inv_idx = np.empty(ar.shape, dtype=np.intp)
+            inv_idx[perm] = iflag
+            ret += (inv_idx,)
+        if return_counts:
+            idx = np.concatenate(np.nonzero(flag) + ([ar.size],))
+            ret += (np.diff(idx),)
+    return ret
+
+def intersect1d(ar1, ar2, assume_unique=False):
+    """
+    Find the intersection of two arrays.
+
+    Return the sorted, unique values that are in both of the input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    intersect1d : ndarray
+        Sorted 1D array of common and unique elements.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])
+    array([1, 3])
+
+    To intersect more than two arrays, use functools.reduce:
+
+    >>> from functools import reduce
+    >>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
+    array([3])
+    """
+    if not assume_unique:
+        # Might be faster than unique( intersect1d( ar1, ar2 ) )?
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    aux = np.concatenate((ar1, ar2))
+    aux.sort()
+    return aux[:-1][aux[1:] == aux[:-1]]
+
+def setxor1d(ar1, ar2, assume_unique=False):
+    """
+    Find the set exclusive-or of two arrays.
+
+    Return the sorted, unique values that are in only one (not both) of the
+    input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    setxor1d : ndarray
+        Sorted 1D array of unique values that are in only one of the input
+        arrays.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3, 2, 4])
+    >>> b = np.array([2, 3, 5, 7, 5])
+    >>> np.setxor1d(a,b)
+    array([1, 4, 5, 7])
+
+    """
+    if not assume_unique:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+
+    aux = np.concatenate((ar1, ar2))
+    if aux.size == 0:
+        return aux
+
+    aux.sort()
+#    flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
+    flag = np.concatenate(([True], aux[1:] != aux[:-1], [True]))
+#    flag2 = ediff1d( flag ) == 0
+    flag2 = flag[1:] == flag[:-1]
+    return aux[flag2]
+
+def in1d(ar1, ar2, assume_unique=False, invert=False):
+    """
+    Test whether each element of a 1-D array is also present in a second array.
+
+    Returns a boolean array the same length as `ar1` that is True
+    where an element of `ar1` is in `ar2` and False otherwise.
+
+    Parameters
+    ----------
+    ar1 : (M,) array_like
+        Input array.
+    ar2 : array_like
+        The values against which to test each value of `ar1`.
+    assume_unique : bool, optional
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+    invert : bool, optional
+        If True, the values in the returned array are inverted (that is,
+        False where an element of `ar1` is in `ar2` and True otherwise).
+        Default is False. ``np.in1d(a, b, invert=True)`` is equivalent
+        to (but is faster than) ``np.invert(in1d(a, b))``.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    in1d : (M,) ndarray, bool
+        The values `ar1[in1d]` are in `ar2`.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Notes
+    -----
+    `in1d` can be considered as an element-wise function version of the
+    python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly
+    equivalent to ``np.array([item in b for item in a])``.
+    However, this idea fails if `ar2` is a set, or similar (non-sequence)
+    container:  As ``ar2`` is converted to an array, in those cases
+    ``asarray(ar2)`` is an object array rather than the expected array of
+    contained values.
+
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    >>> test = np.array([0, 1, 2, 5, 0])
+    >>> states = [0, 2]
+    >>> mask = np.in1d(test, states)
+    >>> mask
+    array([ True, False,  True, False,  True], dtype=bool)
+    >>> test[mask]
+    array([0, 2, 0])
+    >>> mask = np.in1d(test, states, invert=True)
+    >>> mask
+    array([False,  True, False,  True, False], dtype=bool)
+    >>> test[mask]
+    array([1, 5])
+    """
+    # Ravel both arrays, behavior for the first array could be different
+    ar1 = np.asarray(ar1).ravel()
+    ar2 = np.asarray(ar2).ravel()
+
+    # This code is significantly faster when the condition is satisfied.
+    if len(ar2) < 10 * len(ar1) ** 0.145:
+        if invert:
+            mask = np.ones(len(ar1), dtype=np.bool)
+            for a in ar2:
+                mask &= (ar1 != a)
+        else:
+            mask = np.zeros(len(ar1), dtype=np.bool)
+            for a in ar2:
+                mask |= (ar1 == a)
+        return mask
+
+    # Otherwise use sorting
+    if not assume_unique:
+        ar1, rev_idx = np.unique(ar1, return_inverse=True)
+        ar2 = np.unique(ar2)
+
+    ar = np.concatenate((ar1, ar2))
+    # We need this to be a stable sort, so always use 'mergesort'
+    # here. The values from the first array should always come before
+    # the values from the second array.
+    order = ar.argsort(kind='mergesort')
+    sar = ar[order]
+    if invert:
+        bool_ar = (sar[1:] != sar[:-1])
+    else:
+        bool_ar = (sar[1:] == sar[:-1])
+    flag = np.concatenate((bool_ar, [invert]))
+    ret = np.empty(ar.shape, dtype=bool)
+    ret[order] = flag
+
+    if assume_unique:
+        return ret[:len(ar1)]
+    else:
+        return ret[rev_idx]
+
+def union1d(ar1, ar2):
+    """
+    Find the union of two arrays.
+
+    Return the unique, sorted array of values that are in either of the two
+    input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays. They are flattened if they are not already 1D.
+
+    Returns
+    -------
+    union1d : ndarray
+        Unique, sorted union of the input arrays.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.union1d([-1, 0, 1], [-2, 0, 2])
+    array([-2, -1,  0,  1,  2])
+
+    To find the union of more than two arrays, use functools.reduce:
+
+    >>> from functools import reduce
+    >>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
+    array([1, 2, 3, 4, 6])
+    """
+    return unique(np.concatenate((ar1, ar2)))
+
+def setdiff1d(ar1, ar2, assume_unique=False):
+    """
+    Find the set difference of two arrays.
+
+    Return the sorted, unique values in `ar1` that are not in `ar2`.
+
+    Parameters
+    ----------
+    ar1 : array_like
+        Input array.
+    ar2 : array_like
+        Input comparison array.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    setdiff1d : ndarray
+        Sorted 1D array of values in `ar1` that are not in `ar2`.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3, 2, 4, 1])
+    >>> b = np.array([3, 4, 5, 6])
+    >>> np.setdiff1d(a, b)
+    array([1, 2])
+
+    """
+    if assume_unique:
+        ar1 = np.asarray(ar1).ravel()
+    else:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.py
new file mode 100644
index 0000000000..fb52ada86c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.py
@@ -0,0 +1,225 @@
+"""
+A buffered iterator for big arrays.
+
+This module solves the problem of iterating over a big file-based array
+without having to read it into memory. The `Arrayterator` class wraps
+an array object, and when iterated it will return sub-arrays with at most
+a user-specified number of elements.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from operator import mul
+from functools import reduce
+
+from numpy.compat import long
+
+__all__ = ['Arrayterator']
+
+
+class Arrayterator(object):
+    """
+    Buffered iterator for big arrays.
+
+    `Arrayterator` creates a buffered iterator for reading big arrays in small
+    contiguous blocks. The class is useful for objects stored in the
+    file system. It allows iteration over the object *without* reading
+    everything in memory; instead, small blocks are read and iterated over.
+
+    `Arrayterator` can be used with any object that supports multidimensional
+    slices. This includes NumPy arrays, but also variables from
+    Scientific.IO.NetCDF or pynetcdf for example.
+
+    Parameters
+    ----------
+    var : array_like
+        The object to iterate over.
+    buf_size : int, optional
+        The buffer size. If `buf_size` is supplied, the maximum amount of
+        data that will be read into memory is `buf_size` elements.
+        Default is None, which will read as many element as possible
+        into memory.
+
+    Attributes
+    ----------
+    var
+    buf_size
+    start
+    stop
+    step
+    shape
+    flat
+
+    See Also
+    --------
+    ndenumerate : Multidimensional array iterator.
+    flatiter : Flat array iterator.
+    memmap : Create a memory-map to an array stored in a binary file on disk.
+
+    Notes
+    -----
+    The algorithm works by first finding a "running dimension", along which
+    the blocks will be extracted. Given an array of dimensions
+    ``(d1, d2, ..., dn)``, e.g. if `buf_size` is smaller than ``d1``, the
+    first dimension will be used. If, on the other hand,
+    ``d1 < buf_size < d1*d2`` the second dimension will be used, and so on.
+    Blocks are extracted along this dimension, and when the last block is
+    returned the process continues from the next dimension, until all
+    elements have been read.
+
+    Examples
+    --------
+    >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+    >>> a_itor = np.lib.Arrayterator(a, 2)
+    >>> a_itor.shape
+    (3, 4, 5, 6)
+
+    Now we can iterate over ``a_itor``, and it will return arrays of size
+    two. Since `buf_size` was smaller than any dimension, the first
+    dimension will be iterated over first:
+
+    >>> for subarr in a_itor:
+    ...     if not subarr.all():
+    ...         print(subarr, subarr.shape)
+    ...
+    [[[[0 1]]]] (1, 1, 1, 2)
+
+    """
+
+    def __init__(self, var, buf_size=None):
+        self.var = var
+        self.buf_size = buf_size
+
+        self.start = [0 for dim in var.shape]
+        self.stop = [dim for dim in var.shape]
+        self.step = [1 for dim in var.shape]
+
+    def __getattr__(self, attr):
+        return getattr(self.var, attr)
+
+    def __getitem__(self, index):
+        """
+        Return a new arrayterator.
+
+        """
+        # Fix index, handling ellipsis and incomplete slices.
+        if not isinstance(index, tuple):
+            index = (index,)
+        fixed = []
+        length, dims = len(index), len(self.shape)
+        for slice_ in index:
+            if slice_ is Ellipsis:
+                fixed.extend([slice(None)] * (dims-length+1))
+                length = len(fixed)
+            elif isinstance(slice_, (int, long)):
+                fixed.append(slice(slice_, slice_+1, 1))
+            else:
+                fixed.append(slice_)
+        index = tuple(fixed)
+        if len(index) < dims:
+            index += (slice(None),) * (dims-len(index))
+
+        # Return a new arrayterator object.
+        out = self.__class__(self.var, self.buf_size)
+        for i, (start, stop, step, slice_) in enumerate(
+                zip(self.start, self.stop, self.step, index)):
+            out.start[i] = start + (slice_.start or 0)
+            out.step[i] = step * (slice_.step or 1)
+            out.stop[i] = start + (slice_.stop or stop-start)
+            out.stop[i] = min(stop, out.stop[i])
+        return out
+
+    def __array__(self):
+        """
+        Return corresponding data.
+
+        """
+        slice_ = tuple(slice(*t) for t in zip(
+                self.start, self.stop, self.step))
+        return self.var[slice_]
+
+    @property
+    def flat(self):
+        """
+        A 1-D flat iterator for Arrayterator objects.
+
+        This iterator returns elements of the array to be iterated over in
+        `Arrayterator` one by one. It is similar to `flatiter`.
+
+        See Also
+        --------
+        Arrayterator
+        flatiter
+
+        Examples
+        --------
+        >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+        >>> a_itor = np.lib.Arrayterator(a, 2)
+
+        >>> for subarr in a_itor.flat:
+        ...     if not subarr:
+        ...         print(subarr, type(subarr))
+        ...
+        0 <type 'numpy.int32'>
+
+        """
+        for block in self:
+            for value in block.flat:
+                yield value
+
+    @property
+    def shape(self):
+        """
+        The shape of the array to be iterated over.
+
+        For an example, see `Arrayterator`.
+
+        """
+        return tuple(((stop-start-1)//step+1) for start, stop, step in
+                zip(self.start, self.stop, self.step))
+
+    def __iter__(self):
+        # Skip arrays with degenerate dimensions
+        if [dim for dim in self.shape if dim <= 0]:
+            return
+
+        start = self.start[:]
+        stop = self.stop[:]
+        step = self.step[:]
+        ndims = len(self.var.shape)
+
+        while True:
+            count = self.buf_size or reduce(mul, self.shape)
+
+            # iterate over each dimension, looking for the
+            # running dimension (ie, the dimension along which
+            # the blocks will be built from)
+            rundim = 0
+            for i in range(ndims-1, -1, -1):
+                # if count is zero we ran out of elements to read
+                # along higher dimensions, so we read only a single position
+                if count == 0:
+                    stop[i] = start[i]+1
+                elif count <= self.shape[i]:
+                    # limit along this dimension
+                    stop[i] = start[i] + count*step[i]
+                    rundim = i
+                else:
+                    # read everything along this dimension
+                    stop[i] = self.stop[i]
+                stop[i] = min(self.stop[i], stop[i])
+                count = count//self.shape[i]
+
+            # yield a block
+            slice_ = tuple(slice(*t) for t in zip(start, stop, step))
+            yield self.var[slice_]
+
+            # Update start position, taking care of overflow to
+            # other dimensions
+            start[rundim] = stop[rundim]  # start where we stopped
+            for i in range(ndims-1, 0, -1):
+                if start[i] >= self.stop[i]:
+                    start[i] = self.start[i]
+                    start[i-1] += self.step[i-1]
+            if start[0] >= self.stop[0]:
+                return
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/financial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/financial.py
new file mode 100644
index 0000000000..c42424da17
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/financial.py
@@ -0,0 +1,737 @@
+"""Some simple financial calculations
+
+patterned after spreadsheet computations.
+
+There is some complexity in each function
+so that the functions behave like ufuncs with
+broadcasting and being able to be called with scalars
+or arrays (or other sequences).
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate',
+           'irr', 'npv', 'mirr']
+
+_when_to_num = {'end':0, 'begin':1,
+                'e':0, 'b':1,
+                0:0, 1:1,
+                'beginning':1,
+                'start':1,
+                'finish':0}
+
+def _convert_when(when):
+    #Test to see if when has already been converted to ndarray
+    #This will happen if one function calls another, for example ppmt
+    if isinstance(when, np.ndarray):
+        return when
+    try:
+        return _when_to_num[when]
+    except (KeyError, TypeError):
+        return [_when_to_num[x] for x in when]
+
+
+def fv(rate, nper, pmt, pv, when='end'):
+    """
+    Compute the future value.
+
+    Given:
+     * a present value, `pv`
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * a (fixed) payment, `pmt`, paid either
+     * at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the value at the end of the `nper` periods
+
+    Parameters
+    ----------
+    rate : scalar or array_like of shape(M, )
+        Rate of interest as decimal (not per cent) per period
+    nper : scalar or array_like of shape(M, )
+        Number of compounding periods
+    pmt : scalar or array_like of shape(M, )
+        Payment
+    pv : scalar or array_like of shape(M, )
+        Present value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0)).
+        Defaults to {'end', 0}.
+
+    Returns
+    -------
+    out : ndarray
+        Future values.  If all input is scalar, returns a scalar float.  If
+        any input is array_like, returns future values for each input element.
+        If multiple inputs are array_like, they all must have the same shape.
+
+    Notes
+    -----
+    The future value is computed by solving the equation::
+
+     fv +
+     pv*(1+rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
+
+    or, when ``rate == 0``::
+
+     fv + pv + pmt * nper == 0
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+       OpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the future value after 10 years of saving $100 now, with
+    an additional monthly savings of $100.  Assume the interest rate is
+    5% (annually) compounded monthly?
+
+    >>> np.fv(0.05/12, 10*12, -100, -100)
+    15692.928894335748
+
+    By convention, the negative sign represents cash flow out (i.e. money not
+    available today).  Thus, saving $100 a month at 5% annual interest leads
+    to $15,692.93 available to spend in 10 years.
+
+    If any input is array_like, returns an array of equal shape.  Let's
+    compare different interest rates from the example above.
+
+    >>> a = np.array((0.05, 0.06, 0.07))/12
+    >>> np.fv(a, 10*12, -100, -100)
+    array([ 15692.92889434,  16569.87435405,  17509.44688102])
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pmt, pv, when) = map(np.asarray, [rate, nper, pmt, pv, when])
+    temp = (1+rate)**nper
+    miter = np.broadcast(rate, nper, pmt, pv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate == zer, nper + zer,
+                    (1 + rate*when)*(temp - 1)/rate + zer)
+    return -(pv*temp + pmt*fact)
+
+def pmt(rate, nper, pv, fv=0, when='end'):
+    """
+    Compute the payment against loan principal plus interest.
+
+    Given:
+     * a present value, `pv` (e.g., an amount borrowed)
+     * a future value, `fv` (e.g., 0)
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * and (optional) specification of whether payment is made
+       at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the (fixed) periodic payment.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    nper : array_like
+        Number of compounding periods
+    pv : array_like
+        Present value
+    fv : array_like,  optional
+        Future value (default = 0)
+    when : {{'begin', 1}, {'end', 0}}, {string, int}
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Returns
+    -------
+    out : ndarray
+        Payment against loan plus interest.  If all input is scalar, returns a
+        scalar float.  If any input is array_like, returns payment for each
+        input element. If multiple inputs are array_like, they all must have
+        the same shape.
+
+    Notes
+    -----
+    The payment is computed by solving the equation::
+
+     fv +
+     pv*(1 + rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
+
+    or, when ``rate == 0``::
+
+      fv + pv + pmt * nper == 0
+
+    for ``pmt``.
+
+    Note that computing a monthly mortgage payment is only
+    one use for this function.  For example, pmt returns the
+    periodic deposit one must make to achieve a specified
+    future balance given an initial deposit, a fixed,
+    periodically compounded interest rate, and the total
+    number of periods.
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php
+       ?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the monthly payment needed to pay off a $200,000 loan in 15
+    years at an annual interest rate of 7.5%?
+
+    >>> np.pmt(0.075/12, 12*15, 200000)
+    -1854.0247200054619
+
+    In order to pay-off (i.e., have a future-value of 0) the $200,000 obtained
+    today, a monthly payment of $1,854.02 would be required.  Note that this
+    example illustrates usage of `fv` having a default value of 0.
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pv, fv, when) = map(np.asarray, [rate, nper, pv, fv, when])
+    temp = (1 + rate)**nper
+    mask = (rate == 0.0)
+    np.copyto(rate, 1.0, where=mask)
+    z = np.zeros(np.broadcast(rate, nper, pv, fv, when).shape)
+    fact = np.where(mask != z, nper + z, (1 + rate*when)*(temp - 1)/rate + z)
+    return -(fv + pv*temp) / fact
+
+def nper(rate, pmt, pv, fv=0, when='end'):
+    """
+    Compute the number of periodic payments.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    pmt : array_like
+        Payment
+    pv : array_like
+        Present value
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Notes
+    -----
+    The number of periods ``nper`` is computed by solving the equation::
+
+     fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate*((1+rate)**nper-1) = 0
+
+    but if ``rate = 0`` then::
+
+     fv + pv + pmt*nper = 0
+
+    Examples
+    --------
+    If you only had $150/month to pay towards the loan, how long would it take
+    to pay-off a loan of $8,000 at 7% annual interest?
+
+    >>> print(round(np.nper(0.07/12, -150, 8000), 5))
+    64.07335
+
+    So, over 64 months would be required to pay off the loan.
+
+    The same analysis could be done with several different interest rates
+    and/or payments and/or total amounts to produce an entire table.
+
+    >>> np.nper(*(np.ogrid[0.07/12: 0.08/12: 0.01/12,
+    ...                    -150   : -99     : 50    ,
+    ...                    8000   : 9001    : 1000]))
+    array([[[  64.07334877,   74.06368256],
+            [ 108.07548412,  127.99022654]],
+           [[  66.12443902,   76.87897353],
+            [ 114.70165583,  137.90124779]]])
+
+    """
+    when = _convert_when(when)
+    (rate, pmt, pv, fv, when) = map(np.asarray, [rate, pmt, pv, fv, when])
+
+    use_zero_rate = False
+    with np.errstate(divide="raise"):
+        try:
+            z = pmt*(1.0+rate*when)/rate
+        except FloatingPointError:
+            use_zero_rate = True
+
+    if use_zero_rate:
+        return (-fv + pv) / (pmt + 0.0)
+    else:
+        A = -(fv + pv)/(pmt+0.0)
+        B = np.log((-fv+z) / (pv+z))/np.log(1.0+rate)
+        miter = np.broadcast(rate, pmt, pv, fv, when)
+        zer = np.zeros(miter.shape)
+        return np.where(rate == zer, A + zer, B + zer) + 0.0
+
+def ipmt(rate, per, nper, pv, fv=0.0, when='end'):
+    """
+    Compute the interest portion of a payment.
+
+    Parameters
+    ----------
+    rate : scalar or array_like of shape(M, )
+        Rate of interest as decimal (not per cent) per period
+    per : scalar or array_like of shape(M, )
+        Interest paid against the loan changes during the life or the loan.
+        The `per` is the payment period to calculate the interest amount.
+    nper : scalar or array_like of shape(M, )
+        Number of compounding periods
+    pv : scalar or array_like of shape(M, )
+        Present value
+    fv : scalar or array_like of shape(M, ), optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0)).
+        Defaults to {'end', 0}.
+
+    Returns
+    -------
+    out : ndarray
+        Interest portion of payment.  If all input is scalar, returns a scalar
+        float.  If any input is array_like, returns interest payment for each
+        input element. If multiple inputs are array_like, they all must have
+        the same shape.
+
+    See Also
+    --------
+    ppmt, pmt, pv
+
+    Notes
+    -----
+    The total payment is made up of payment against principal plus interest.
+
+    ``pmt = ppmt + ipmt``
+
+    Examples
+    --------
+    What is the amortization schedule for a 1 year loan of $2500 at
+    8.24% interest per year compounded monthly?
+
+    >>> principal = 2500.00
+
+    The 'per' variable represents the periods of the loan.  Remember that
+    financial equations start the period count at 1!
+
+    >>> per = np.arange(1*12) + 1
+    >>> ipmt = np.ipmt(0.0824/12, per, 1*12, principal)
+    >>> ppmt = np.ppmt(0.0824/12, per, 1*12, principal)
+
+    Each element of the sum of the 'ipmt' and 'ppmt' arrays should equal
+    'pmt'.
+
+    >>> pmt = np.pmt(0.0824/12, 1*12, principal)
+    >>> np.allclose(ipmt + ppmt, pmt)
+    True
+
+    >>> fmt = '{0:2d} {1:8.2f} {2:8.2f} {3:8.2f}'
+    >>> for payment in per:
+    ...     index = payment - 1
+    ...     principal = principal + ppmt[index]
+    ...     print(fmt.format(payment, ppmt[index], ipmt[index], principal))
+     1  -200.58   -17.17  2299.42
+     2  -201.96   -15.79  2097.46
+     3  -203.35   -14.40  1894.11
+     4  -204.74   -13.01  1689.37
+     5  -206.15   -11.60  1483.22
+     6  -207.56   -10.18  1275.66
+     7  -208.99    -8.76  1066.67
+     8  -210.42    -7.32   856.25
+     9  -211.87    -5.88   644.38
+    10  -213.32    -4.42   431.05
+    11  -214.79    -2.96   216.26
+    12  -216.26    -1.49    -0.00
+
+    >>> interestpd = np.sum(ipmt)
+    >>> np.round(interestpd, 2)
+    -112.98
+
+    """
+    when = _convert_when(when)
+    rate, per, nper, pv, fv, when = np.broadcast_arrays(rate, per, nper,
+                                                        pv, fv, when)
+    total_pmt = pmt(rate, nper, pv, fv, when)
+    ipmt = _rbl(rate, per, total_pmt, pv, when)*rate
+    try:
+        ipmt = np.where(when == 1, ipmt/(1 + rate), ipmt)
+        ipmt = np.where(np.logical_and(when == 1, per == 1), 0.0, ipmt)
+    except IndexError:
+        pass
+    return ipmt
+
+def _rbl(rate, per, pmt, pv, when):
+    """
+    This function is here to simply have a different name for the 'fv'
+    function to not interfere with the 'fv' keyword argument within the 'ipmt'
+    function.  It is the 'remaining balance on loan' which might be useful as
+    it's own function, but is easily calculated with the 'fv' function.
+    """
+    return fv(rate, (per - 1), pmt, pv, when)
+
+def ppmt(rate, per, nper, pv, fv=0.0, when='end'):
+    """
+    Compute the payment against loan principal.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    per : array_like, int
+        Amount paid against the loan changes.  The `per` is the period of
+        interest.
+    nper : array_like
+        Number of compounding periods
+    pv : array_like
+        Present value
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}
+        When payments are due ('begin' (1) or 'end' (0))
+
+    See Also
+    --------
+    pmt, pv, ipmt
+
+    """
+    total = pmt(rate, nper, pv, fv, when)
+    return total - ipmt(rate, per, nper, pv, fv, when)
+
+def pv(rate, nper, pmt, fv=0.0, when='end'):
+    """
+    Compute the present value.
+
+    Given:
+     * a future value, `fv`
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * a (fixed) payment, `pmt`, paid either
+     * at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the value now
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    nper : array_like
+        Number of compounding periods
+    pmt : array_like
+        Payment
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Returns
+    -------
+    out : ndarray, float
+        Present value of a series of payments or investments.
+
+    Notes
+    -----
+    The present value is computed by solving the equation::
+
+     fv +
+     pv*(1 + rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) = 0
+
+    or, when ``rate = 0``::
+
+     fv + pv + pmt * nper = 0
+
+    for `pv`, which is then returned.
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+       OpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the present value (e.g., the initial investment)
+    of an investment that needs to total $15692.93
+    after 10 years of saving $100 every month?  Assume the
+    interest rate is 5% (annually) compounded monthly.
+
+    >>> np.pv(0.05/12, 10*12, -100, 15692.93)
+    -100.00067131625819
+
+    By convention, the negative sign represents cash flow out
+    (i.e., money not available today).  Thus, to end up with
+    $15,692.93 in 10 years saving $100 a month at 5% annual
+    interest, one's initial deposit should also be $100.
+
+    If any input is array_like, ``pv`` returns an array of equal shape.
+    Let's compare different interest rates in the example above:
+
+    >>> a = np.array((0.05, 0.04, 0.03))/12
+    >>> np.pv(a, 10*12, -100, 15692.93)
+    array([ -100.00067132,  -649.26771385, -1273.78633713])
+
+    So, to end up with the same $15692.93 under the same $100 per month
+    "savings plan," for annual interest rates of 4% and 3%, one would
+    need initial investments of $649.27 and $1273.79, respectively.
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pmt, fv, when) = map(np.asarray, [rate, nper, pmt, fv, when])
+    temp = (1+rate)**nper
+    miter = np.broadcast(rate, nper, pmt, fv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate == zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer)
+    return -(fv + pmt*fact)/temp
+
+# Computed with Sage
+#  (y + (r + 1)^n*x + p*((r + 1)^n - 1)*(r*w + 1)/r)/(n*(r + 1)^(n - 1)*x -
+#  p*((r + 1)^n - 1)*(r*w + 1)/r^2 + n*p*(r + 1)^(n - 1)*(r*w + 1)/r +
+#  p*((r + 1)^n - 1)*w/r)
+
+def _g_div_gp(r, n, p, x, y, w):
+    t1 = (r+1)**n
+    t2 = (r+1)**(n-1)
+    return ((y + t1*x + p*(t1 - 1)*(r*w + 1)/r) /
+                (n*t2*x - p*(t1 - 1)*(r*w + 1)/(r**2) + n*p*t2*(r*w + 1)/r +
+                 p*(t1 - 1)*w/r))
+
+# Use Newton's iteration until the change is less than 1e-6
+#  for all values or a maximum of 100 iterations is reached.
+#  Newton's rule is
+#  r_{n+1} = r_{n} - g(r_n)/g'(r_n)
+#     where
+#  g(r) is the formula
+#  g'(r) is the derivative with respect to r.
+def rate(nper, pmt, pv, fv, when='end', guess=0.10, tol=1e-6, maxiter=100):
+    """
+    Compute the rate of interest per period.
+
+    Parameters
+    ----------
+    nper : array_like
+        Number of compounding periods
+    pmt : array_like
+        Payment
+    pv : array_like
+        Present value
+    fv : array_like
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+    guess : float, optional
+        Starting guess for solving the rate of interest
+    tol : float, optional
+        Required tolerance for the solution
+    maxiter : int, optional
+        Maximum iterations in finding the solution
+
+    Notes
+    -----
+    The rate of interest is computed by iteratively solving the
+    (non-linear) equation::
+
+     fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate * ((1+rate)**nper - 1) = 0
+
+    for ``rate``.
+
+    References
+    ----------
+    Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May). Open Document
+    Format for Office Applications (OpenDocument)v1.2, Part 2: Recalculated
+    Formula (OpenFormula) Format - Annotated Version, Pre-Draft 12.
+    Organization for the Advancement of Structured Information Standards
+    (OASIS). Billerica, MA, USA. [ODT Document]. Available:
+    http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+    OpenDocument-formula-20090508.odt
+
+    """
+    when = _convert_when(when)
+    (nper, pmt, pv, fv, when) = map(np.asarray, [nper, pmt, pv, fv, when])
+    rn = guess
+    iter = 0
+    close = False
+    while (iter < maxiter) and not close:
+        rnp1 = rn - _g_div_gp(rn, nper, pmt, pv, fv, when)
+        diff = abs(rnp1-rn)
+        close = np.all(diff < tol)
+        iter += 1
+        rn = rnp1
+    if not close:
+        # Return nan's in array of the same shape as rn
+        return np.nan + rn
+    else:
+        return rn
+
+def irr(values):
+    """
+    Return the Internal Rate of Return (IRR).
+
+    This is the "average" periodically compounded rate of return
+    that gives a net present value of 0.0; for a more complete explanation,
+    see Notes below.
+
+    Parameters
+    ----------
+    values : array_like, shape(N,)
+        Input cash flows per time period.  By convention, net "deposits"
+        are negative and net "withdrawals" are positive.  Thus, for
+        example, at least the first element of `values`, which represents
+        the initial investment, will typically be negative.
+
+    Returns
+    -------
+    out : float
+        Internal Rate of Return for periodic input values.
+
+    Notes
+    -----
+    The IRR is perhaps best understood through an example (illustrated
+    using np.irr in the Examples section below).  Suppose one invests 100
+    units and then makes the following withdrawals at regular (fixed)
+    intervals: 39, 59, 55, 20.  Assuming the ending value is 0, one's 100
+    unit investment yields 173 units; however, due to the combination of
+    compounding and the periodic withdrawals, the "average" rate of return
+    is neither simply 0.73/4 nor (1.73)^0.25-1.  Rather, it is the solution
+    (for :math:`r`) of the equation:
+
+    .. math:: -100 + \\frac{39}{1+r} + \\frac{59}{(1+r)^2}
+     + \\frac{55}{(1+r)^3} + \\frac{20}{(1+r)^4} = 0
+
+    In general, for `values` :math:`= [v_0, v_1, ... v_M]`,
+    irr is the solution of the equation: [G]_
+
+    .. math:: \\sum_{t=0}^M{\\frac{v_t}{(1+irr)^{t}}} = 0
+
+    References
+    ----------
+    .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+       Addison-Wesley, 2003, pg. 348.
+
+    Examples
+    --------
+    >>> round(irr([-100, 39, 59, 55, 20]), 5)
+    0.28095
+    >>> round(irr([-100, 0, 0, 74]), 5)
+    -0.0955
+    >>> round(irr([-100, 100, 0, -7]), 5)
+    -0.0833
+    >>> round(irr([-100, 100, 0, 7]), 5)
+    0.06206
+    >>> round(irr([-5, 10.5, 1, -8, 1]), 5)
+    0.0886
+
+    (Compare with the Example given for numpy.lib.financial.npv)
+
+    """
+    res = np.roots(values[::-1])
+    mask = (res.imag == 0) & (res.real > 0)
+    if res.size == 0:
+        return np.nan
+    res = res[mask].real
+    # NPV(rate) = 0 can have more than one solution so we return
+    # only the solution closest to zero.
+    rate = 1.0/res - 1
+    rate = rate.item(np.argmin(np.abs(rate)))
+    return rate
+
+def npv(rate, values):
+    """
+    Returns the NPV (Net Present Value) of a cash flow series.
+
+    Parameters
+    ----------
+    rate : scalar
+        The discount rate.
+    values : array_like, shape(M, )
+        The values of the time series of cash flows.  The (fixed) time
+        interval between cash flow "events" must be the same as that for
+        which `rate` is given (i.e., if `rate` is per year, then precisely
+        a year is understood to elapse between each cash flow event).  By
+        convention, investments or "deposits" are negative, income or
+        "withdrawals" are positive; `values` must begin with the initial
+        investment, thus `values[0]` will typically be negative.
+
+    Returns
+    -------
+    out : float
+        The NPV of the input cash flow series `values` at the discount
+        `rate`.
+
+    Notes
+    -----
+    Returns the result of: [G]_
+
+    .. math :: \\sum_{t=0}^{M-1}{\\frac{values_t}{(1+rate)^{t}}}
+
+    References
+    ----------
+    .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+       Addison-Wesley, 2003, pg. 346.
+
+    Examples
+    --------
+    >>> np.npv(0.281,[-100, 39, 59, 55, 20])
+    -0.0084785916384548798
+
+    (Compare with the Example given for numpy.lib.financial.irr)
+
+    """
+    values = np.asarray(values)
+    return (values / (1+rate)**np.arange(0, len(values))).sum(axis=0)
+
+def mirr(values, finance_rate, reinvest_rate):
+    """
+    Modified internal rate of return.
+
+    Parameters
+    ----------
+    values : array_like
+        Cash flows (must contain at least one positive and one negative
+        value) or nan is returned.  The first value is considered a sunk
+        cost at time zero.
+    finance_rate : scalar
+        Interest rate paid on the cash flows
+    reinvest_rate : scalar
+        Interest rate received on the cash flows upon reinvestment
+
+    Returns
+    -------
+    out : float
+        Modified internal rate of return
+
+    """
+    values = np.asarray(values, dtype=np.double)
+    n = values.size
+    pos = values > 0
+    neg = values < 0
+    if not (pos.any() and neg.any()):
+        return np.nan
+    numer = np.abs(npv(reinvest_rate, values*pos))
+    denom = np.abs(npv(finance_rate, values*neg))
+    return (numer/denom)**(1.0/(n - 1))*(1 + reinvest_rate) - 1
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/format.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/format.py
new file mode 100644
index 0000000000..a0f2c54975
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/format.py
@@ -0,0 +1,813 @@
+"""
+Define a simple format for saving numpy arrays to disk with the full
+information about them.
+
+The ``.npy`` format is the standard binary file format in NumPy for
+persisting a *single* arbitrary NumPy array on disk. The format stores all
+of the shape and dtype information necessary to reconstruct the array
+correctly even on another machine with a different architecture.
+The format is designed to be as simple as possible while achieving
+its limited goals.
+
+The ``.npz`` format is the standard format for persisting *multiple* NumPy
+arrays on disk. A ``.npz`` file is a zip file containing multiple ``.npy``
+files, one for each array.
+
+Capabilities
+------------
+
+- Can represent all NumPy arrays including nested record arrays and
+  object arrays.
+
+- Represents the data in its native binary form.
+
+- Supports Fortran-contiguous arrays directly.
+
+- Stores all of the necessary information to reconstruct the array
+  including shape and dtype on a machine of a different
+  architecture.  Both little-endian and big-endian arrays are
+  supported, and a file with little-endian numbers will yield
+  a little-endian array on any machine reading the file. The
+  types are described in terms of their actual sizes. For example,
+  if a machine with a 64-bit C "long int" writes out an array with
+  "long ints", a reading machine with 32-bit C "long ints" will yield
+  an array with 64-bit integers.
+
+- Is straightforward to reverse engineer. Datasets often live longer than
+  the programs that created them. A competent developer should be
+  able to create a solution in their preferred programming language to
+  read most ``.npy`` files that he has been given without much
+  documentation.
+
+- Allows memory-mapping of the data. See `open_memmep`.
+
+- Can be read from a filelike stream object instead of an actual file.
+
+- Stores object arrays, i.e. arrays containing elements that are arbitrary
+  Python objects. Files with object arrays are not to be mmapable, but
+  can be read and written to disk.
+
+Limitations
+-----------
+
+- Arbitrary subclasses of numpy.ndarray are not completely preserved.
+  Subclasses will be accepted for writing, but only the array data will
+  be written out. A regular numpy.ndarray object will be created
+  upon reading the file.
+
+.. warning::
+
+  Due to limitations in the interpretation of structured dtypes, dtypes
+  with fields with empty names will have the names replaced by 'f0', 'f1',
+  etc. Such arrays will not round-trip through the format entirely
+  accurately. The data is intact; only the field names will differ. We are
+  working on a fix for this. This fix will not require a change in the
+  file format. The arrays with such structures can still be saved and
+  restored, and the correct dtype may be restored by using the
+  ``loadedarray.view(correct_dtype)`` method.
+
+File extensions
+---------------
+
+We recommend using the ``.npy`` and ``.npz`` extensions for files saved
+in this format. This is by no means a requirement; applications may wish
+to use these file formats but use an extension specific to the
+application. In the absence of an obvious alternative, however,
+we suggest using ``.npy`` and ``.npz``.
+
+Version numbering
+-----------------
+
+The version numbering of these formats is independent of NumPy version
+numbering. If the format is upgraded, the code in `numpy.io` will still
+be able to read and write Version 1.0 files.
+
+Format Version 1.0
+------------------
+
+The first 6 bytes are a magic string: exactly ``\\x93NUMPY``.
+
+The next 1 byte is an unsigned byte: the major version number of the file
+format, e.g. ``\\x01``.
+
+The next 1 byte is an unsigned byte: the minor version number of the file
+format, e.g. ``\\x00``. Note: the version of the file format is not tied
+to the version of the numpy package.
+
+The next 2 bytes form a little-endian unsigned short int: the length of
+the header data HEADER_LEN.
+
+The next HEADER_LEN bytes form the header data describing the array's
+format. It is an ASCII string which contains a Python literal expression
+of a dictionary. It is terminated by a newline (``\\n``) and padded with
+spaces (``\\x20``) to make the total length of
+``magic string + 4 + HEADER_LEN`` be evenly divisible by 16 for alignment
+purposes.
+
+The dictionary contains three keys:
+
+    "descr" : dtype.descr
+      An object that can be passed as an argument to the `numpy.dtype`
+      constructor to create the array's dtype.
+    "fortran_order" : bool
+      Whether the array data is Fortran-contiguous or not. Since
+      Fortran-contiguous arrays are a common form of non-C-contiguity,
+      we allow them to be written directly to disk for efficiency.
+    "shape" : tuple of int
+      The shape of the array.
+
+For repeatability and readability, the dictionary keys are sorted in
+alphabetic order. This is for convenience only. A writer SHOULD implement
+this if possible. A reader MUST NOT depend on this.
+
+Following the header comes the array data. If the dtype contains Python
+objects (i.e. ``dtype.hasobject is True``), then the data is a Python
+pickle of the array. Otherwise the data is the contiguous (either C-
+or Fortran-, depending on ``fortran_order``) bytes of the array.
+Consumers can figure out the number of bytes by multiplying the number
+of elements given by the shape (noting that ``shape=()`` means there is
+1 element) by ``dtype.itemsize``.
+
+Format Version 2.0
+------------------
+
+The version 1.0 format only allowed the array header to have a total size of
+65535 bytes.  This can be exceeded by structured arrays with a large number of
+columns.  The version 2.0 format extends the header size to 4 GiB.
+`numpy.save` will automatically save in 2.0 format if the data requires it,
+else it will always use the more compatible 1.0 format.
+
+The description of the fourth element of the header therefore has become:
+"The next 4 bytes form a little-endian unsigned int: the length of the header
+data HEADER_LEN."
+
+Notes
+-----
+The ``.npy`` format, including reasons for creating it and a comparison of
+alternatives, is described fully in the "npy-format" NEP.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy
+import sys
+import io
+import warnings
+from numpy.lib.utils import safe_eval
+from numpy.compat import asbytes, asstr, isfileobj, long, basestring
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+
+MAGIC_PREFIX = asbytes('\x93NUMPY')
+MAGIC_LEN = len(MAGIC_PREFIX) + 2
+BUFFER_SIZE = 2**18  # size of buffer for reading npz files in bytes
+
+# difference between version 1.0 and 2.0 is a 4 byte (I) header length
+# instead of 2 bytes (H) allowing storage of large structured arrays
+
+def _check_version(version):
+    if version not in [(1, 0), (2, 0), None]:
+        msg = "we only support format version (1,0) and (2, 0), not %s"
+        raise ValueError(msg % (version,))
+
+def magic(major, minor):
+    """ Return the magic string for the given file format version.
+
+    Parameters
+    ----------
+    major : int in [0, 255]
+    minor : int in [0, 255]
+
+    Returns
+    -------
+    magic : str
+
+    Raises
+    ------
+    ValueError if the version cannot be formatted.
+    """
+    if major < 0 or major > 255:
+        raise ValueError("major version must be 0 <= major < 256")
+    if minor < 0 or minor > 255:
+        raise ValueError("minor version must be 0 <= minor < 256")
+    if sys.version_info[0] < 3:
+        return MAGIC_PREFIX + chr(major) + chr(minor)
+    else:
+        return MAGIC_PREFIX + bytes([major, minor])
+
+def read_magic(fp):
+    """ Read the magic string to get the version of the file format.
+
+    Parameters
+    ----------
+    fp : filelike object
+
+    Returns
+    -------
+    major : int
+    minor : int
+    """
+    magic_str = _read_bytes(fp, MAGIC_LEN, "magic string")
+    if magic_str[:-2] != MAGIC_PREFIX:
+        msg = "the magic string is not correct; expected %r, got %r"
+        raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2]))
+    if sys.version_info[0] < 3:
+        major, minor = map(ord, magic_str[-2:])
+    else:
+        major, minor = magic_str[-2:]
+    return major, minor
+
+def dtype_to_descr(dtype):
+    """
+    Get a serializable descriptor from the dtype.
+
+    The .descr attribute of a dtype object cannot be round-tripped through
+    the dtype() constructor. Simple types, like dtype('float32'), have
+    a descr which looks like a record array with one field with '' as
+    a name. The dtype() constructor interprets this as a request to give
+    a default name.  Instead, we construct descriptor that can be passed to
+    dtype().
+
+    Parameters
+    ----------
+    dtype : dtype
+        The dtype of the array that will be written to disk.
+
+    Returns
+    -------
+    descr : object
+        An object that can be passed to `numpy.dtype()` in order to
+        replicate the input dtype.
+
+    """
+    if dtype.names is not None:
+        # This is a record array. The .descr is fine.  XXX: parts of the
+        # record array with an empty name, like padding bytes, still get
+        # fiddled with. This needs to be fixed in the C implementation of
+        # dtype().
+        return dtype.descr
+    else:
+        return dtype.str
+
+def header_data_from_array_1_0(array):
+    """ Get the dictionary of header metadata from a numpy.ndarray.
+
+    Parameters
+    ----------
+    array : numpy.ndarray
+
+    Returns
+    -------
+    d : dict
+        This has the appropriate entries for writing its string representation
+        to the header of the file.
+    """
+    d = {'shape': array.shape}
+    if array.flags.c_contiguous:
+        d['fortran_order'] = False
+    elif array.flags.f_contiguous:
+        d['fortran_order'] = True
+    else:
+        # Totally non-contiguous data. We will have to make it C-contiguous
+        # before writing. Note that we need to test for C_CONTIGUOUS first
+        # because a 1-D array is both C_CONTIGUOUS and F_CONTIGUOUS.
+        d['fortran_order'] = False
+
+    d['descr'] = dtype_to_descr(array.dtype)
+    return d
+
+def _write_array_header(fp, d, version=None):
+    """ Write the header for an array and returns the version used
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string representation
+        to the header of the file.
+    version: tuple or None
+        None means use oldest that works
+        explicit version will raise a ValueError if the format does not
+        allow saving this data.  Default: None
+    Returns
+    -------
+    version : tuple of int
+        the file version which needs to be used to store the data
+    """
+    import struct
+    header = ["{"]
+    for key, value in sorted(d.items()):
+        # Need to use repr here, since we eval these when reading
+        header.append("'%s': %s, " % (key, repr(value)))
+    header.append("}")
+    header = "".join(header)
+    # Pad the header with spaces and a final newline such that the magic
+    # string, the header-length short and the header are aligned on a
+    # 16-byte boundary.  Hopefully, some system, possibly memory-mapping,
+    # can take advantage of our premature optimization.
+    current_header_len = MAGIC_LEN + 2 + len(header) + 1  # 1 for the newline
+    topad = 16 - (current_header_len % 16)
+    header = header + ' '*topad + '\n'
+    header = asbytes(_filter_header(header))
+
+    hlen = len(header)
+    if hlen < 256*256 and version in (None, (1, 0)):
+        version = (1, 0)
+        header_prefix = magic(1, 0) + struct.pack('<H', hlen)
+    elif hlen < 2**32 and version in (None, (2, 0)):
+        version = (2, 0)
+        header_prefix = magic(2, 0) + struct.pack('<I', hlen)
+    else:
+        msg = "Header length %s too big for version=%s"
+        msg %= (hlen, version)
+        raise ValueError(msg)
+
+    fp.write(header_prefix)
+    fp.write(header)
+    return version
+
+def write_array_header_1_0(fp, d):
+    """ Write the header for an array using the 1.0 format.
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string
+        representation to the header of the file.
+    """
+    _write_array_header(fp, d, (1, 0))
+
+
+def write_array_header_2_0(fp, d):
+    """ Write the header for an array using the 2.0 format.
+        The 2.0 format allows storing very large structured arrays.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string
+        representation to the header of the file.
+    """
+    _write_array_header(fp, d, (2, 0))
+
+def read_array_header_1_0(fp):
+    """
+    Read an array header from a filelike object using the 1.0 file format
+    version.
+
+    This will leave the file object located just after the header.
+
+    Parameters
+    ----------
+    fp : filelike object
+        A file object or something with a `.read()` method like a file.
+
+    Returns
+    -------
+    shape : tuple of int
+        The shape of the array.
+    fortran_order : bool
+        The array data will be written out directly if it is either
+        C-contiguous or Fortran-contiguous. Otherwise, it will be made
+        contiguous before writing it out.
+    dtype : dtype
+        The dtype of the file's data.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid.
+
+    """
+    return _read_array_header(fp, version=(1, 0))
+
+def read_array_header_2_0(fp):
+    """
+    Read an array header from a filelike object using the 2.0 file format
+    version.
+
+    This will leave the file object located just after the header.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    fp : filelike object
+        A file object or something with a `.read()` method like a file.
+
+    Returns
+    -------
+    shape : tuple of int
+        The shape of the array.
+    fortran_order : bool
+        The array data will be written out directly if it is either
+        C-contiguous or Fortran-contiguous. Otherwise, it will be made
+        contiguous before writing it out.
+    dtype : dtype
+        The dtype of the file's data.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid.
+
+    """
+    return _read_array_header(fp, version=(2, 0))
+
+
+def _filter_header(s):
+    """Clean up 'L' in npz header ints.
+
+    Cleans up the 'L' in strings representing integers. Needed to allow npz
+    headers produced in Python2 to be read in Python3.
+
+    Parameters
+    ----------
+    s : byte string
+        Npy file header.
+
+    Returns
+    -------
+    header : str
+        Cleaned up header.
+
+    """
+    import tokenize
+    if sys.version_info[0] >= 3:
+        from io import StringIO
+    else:
+        from StringIO import StringIO
+
+    tokens = []
+    last_token_was_number = False
+    for token in tokenize.generate_tokens(StringIO(asstr(s)).read):
+        token_type = token[0]
+        token_string = token[1]
+        if (last_token_was_number and
+                token_type == tokenize.NAME and
+                token_string == "L"):
+            continue
+        else:
+            tokens.append(token)
+        last_token_was_number = (token_type == tokenize.NUMBER)
+    return tokenize.untokenize(tokens)
+
+
+def _read_array_header(fp, version):
+    """
+    see read_array_header_1_0
+    """
+    # Read an unsigned, little-endian short int which has the length of the
+    # header.
+    import struct
+    if version == (1, 0):
+        hlength_str = _read_bytes(fp, 2, "array header length")
+        header_length = struct.unpack('<H', hlength_str)[0]
+        header = _read_bytes(fp, header_length, "array header")
+    elif version == (2, 0):
+        hlength_str = _read_bytes(fp, 4, "array header length")
+        header_length = struct.unpack('<I', hlength_str)[0]
+        header = _read_bytes(fp, header_length, "array header")
+    else:
+        raise ValueError("Invalid version %r" % version)
+
+    # The header is a pretty-printed string representation of a literal
+    # Python dictionary with trailing newlines padded to a 16-byte
+    # boundary. The keys are strings.
+    #   "shape" : tuple of int
+    #   "fortran_order" : bool
+    #   "descr" : dtype.descr
+    header = _filter_header(header)
+    try:
+        d = safe_eval(header)
+    except SyntaxError as e:
+        msg = "Cannot parse header: %r\nException: %r"
+        raise ValueError(msg % (header, e))
+    if not isinstance(d, dict):
+        msg = "Header is not a dictionary: %r"
+        raise ValueError(msg % d)
+    keys = sorted(d.keys())
+    if keys != ['descr', 'fortran_order', 'shape']:
+        msg = "Header does not contain the correct keys: %r"
+        raise ValueError(msg % (keys,))
+
+    # Sanity-check the values.
+    if (not isinstance(d['shape'], tuple) or
+            not numpy.all([isinstance(x, (int, long)) for x in d['shape']])):
+        msg = "shape is not valid: %r"
+        raise ValueError(msg % (d['shape'],))
+    if not isinstance(d['fortran_order'], bool):
+        msg = "fortran_order is not a valid bool: %r"
+        raise ValueError(msg % (d['fortran_order'],))
+    try:
+        dtype = numpy.dtype(d['descr'])
+    except TypeError as e:
+        msg = "descr is not a valid dtype descriptor: %r"
+        raise ValueError(msg % (d['descr'],))
+
+    return d['shape'], d['fortran_order'], dtype
+
+def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None):
+    """
+    Write an array to an NPY file, including a header.
+
+    If the array is neither C-contiguous nor Fortran-contiguous AND the
+    file_like object is not a real file object, this function will have to
+    copy data in memory.
+
+    Parameters
+    ----------
+    fp : file_like object
+        An open, writable file object, or similar object with a
+        ``.write()`` method.
+    array : ndarray
+        The array to write to disk.
+    version : (int, int) or None, optional
+        The version number of the format. None means use the oldest
+        supported version that is able to store the data.  Default: None
+    allow_pickle : bool, optional
+        Whether to allow writing pickled data. Default: True
+    pickle_kwargs : dict, optional
+        Additional keyword arguments to pass to pickle.dump, excluding
+        'protocol'. These are only useful when pickling objects in object
+        arrays on Python 3 to Python 2 compatible format.
+
+    Raises
+    ------
+    ValueError
+        If the array cannot be persisted. This includes the case of
+        allow_pickle=False and array being an object array.
+    Various other errors
+        If the array contains Python objects as part of its dtype, the
+        process of pickling them may raise various errors if the objects
+        are not picklable.
+
+    """
+    _check_version(version)
+    used_ver = _write_array_header(fp, header_data_from_array_1_0(array),
+                                   version)
+    # this warning can be removed when 1.9 has aged enough
+    if version != (2, 0) and used_ver == (2, 0):
+        warnings.warn("Stored array in format 2.0. It can only be"
+                      "read by NumPy >= 1.9", UserWarning)
+
+    # Set buffer size to 16 MiB to hide the Python loop overhead.
+    buffersize = max(16 * 1024 ** 2 // array.itemsize, 1)
+
+    if array.dtype.hasobject:
+        # We contain Python objects so we cannot write out the data
+        # directly.  Instead, we will pickle it out with version 2 of the
+        # pickle protocol.
+        if not allow_pickle:
+            raise ValueError("Object arrays cannot be saved when "
+                             "allow_pickle=False")
+        if pickle_kwargs is None:
+            pickle_kwargs = {}
+        pickle.dump(array, fp, protocol=2, **pickle_kwargs)
+    elif array.flags.f_contiguous and not array.flags.c_contiguous:
+        if isfileobj(fp):
+            array.T.tofile(fp)
+        else:
+            for chunk in numpy.nditer(
+                    array, flags=['external_loop', 'buffered', 'zerosize_ok'],
+                    buffersize=buffersize, order='F'):
+                fp.write(chunk.tobytes('C'))
+    else:
+        if isfileobj(fp):
+            array.tofile(fp)
+        else:
+            for chunk in numpy.nditer(
+                    array, flags=['external_loop', 'buffered', 'zerosize_ok'],
+                    buffersize=buffersize, order='C'):
+                fp.write(chunk.tobytes('C'))
+
+
+def read_array(fp, allow_pickle=True, pickle_kwargs=None):
+    """
+    Read an array from an NPY file.
+
+    Parameters
+    ----------
+    fp : file_like object
+        If this is not a real file object, then this may take extra memory
+        and time.
+    allow_pickle : bool, optional
+        Whether to allow reading pickled data. Default: True
+    pickle_kwargs : dict
+        Additional keyword arguments to pass to pickle.load. These are only
+        useful when loading object arrays saved on Python 2 when using
+        Python 3.
+
+    Returns
+    -------
+    array : ndarray
+        The array from the data on disk.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid, or allow_pickle=False and the file contains
+        an object array.
+
+    """
+    version = read_magic(fp)
+    _check_version(version)
+    shape, fortran_order, dtype = _read_array_header(fp, version)
+    if len(shape) == 0:
+        count = 1
+    else:
+        count = numpy.multiply.reduce(shape)
+
+    # Now read the actual data.
+    if dtype.hasobject:
+        # The array contained Python objects. We need to unpickle the data.
+        if not allow_pickle:
+            raise ValueError("Object arrays cannot be loaded when "
+                             "allow_pickle=False")
+        if pickle_kwargs is None:
+            pickle_kwargs = {}
+        try:
+            array = pickle.load(fp, **pickle_kwargs)
+        except UnicodeError as err:
+            if sys.version_info[0] >= 3:
+                # Friendlier error message
+                raise UnicodeError("Unpickling a python object failed: %r\n"
+                                   "You may need to pass the encoding= option "
+                                   "to numpy.load" % (err,))
+            raise
+    else:
+        if isfileobj(fp):
+            # We can use the fast fromfile() function.
+            array = numpy.fromfile(fp, dtype=dtype, count=count)
+        else:
+            # This is not a real file. We have to read it the
+            # memory-intensive way.
+            # crc32 module fails on reads greater than 2 ** 32 bytes,
+            # breaking large reads from gzip streams. Chunk reads to
+            # BUFFER_SIZE bytes to avoid issue and reduce memory overhead
+            # of the read. In non-chunked case count < max_read_count, so
+            # only one read is performed.
+
+            max_read_count = BUFFER_SIZE // min(BUFFER_SIZE, dtype.itemsize)
+
+            array = numpy.empty(count, dtype=dtype)
+            for i in range(0, count, max_read_count):
+                read_count = min(max_read_count, count - i)
+                read_size = int(read_count * dtype.itemsize)
+                data = _read_bytes(fp, read_size, "array data")
+                array[i:i+read_count] = numpy.frombuffer(data, dtype=dtype,
+                                                         count=read_count)
+
+        if fortran_order:
+            array.shape = shape[::-1]
+            array = array.transpose()
+        else:
+            array.shape = shape
+
+    return array
+
+
+def open_memmap(filename, mode='r+', dtype=None, shape=None,
+                fortran_order=False, version=None):
+    """
+    Open a .npy file as a memory-mapped array.
+
+    This may be used to read an existing file or create a new one.
+
+    Parameters
+    ----------
+    filename : str
+        The name of the file on disk.  This may *not* be a file-like
+        object.
+    mode : str, optional
+        The mode in which to open the file; the default is 'r+'.  In
+        addition to the standard file modes, 'c' is also accepted to mean
+        "copy on write."  See `memmap` for the available mode strings.
+    dtype : data-type, optional
+        The data type of the array if we are creating a new file in "write"
+        mode, if not, `dtype` is ignored.  The default value is None, which
+        results in a data-type of `float64`.
+    shape : tuple of int
+        The shape of the array if we are creating a new file in "write"
+        mode, in which case this parameter is required.  Otherwise, this
+        parameter is ignored and is thus optional.
+    fortran_order : bool, optional
+        Whether the array should be Fortran-contiguous (True) or
+        C-contiguous (False, the default) if we are creating a new file in
+        "write" mode.
+    version : tuple of int (major, minor) or None
+        If the mode is a "write" mode, then this is the version of the file
+        format used to create the file.  None means use the oldest
+        supported version that is able to store the data.  Default: None
+
+    Returns
+    -------
+    marray : memmap
+        The memory-mapped array.
+
+    Raises
+    ------
+    ValueError
+        If the data or the mode is invalid.
+    IOError
+        If the file is not found or cannot be opened correctly.
+
+    See Also
+    --------
+    memmap
+
+    """
+    if not isinstance(filename, basestring):
+        raise ValueError("Filename must be a string.  Memmap cannot use"
+                         " existing file handles.")
+
+    if 'w' in mode:
+        # We are creating the file, not reading it.
+        # Check if we ought to create the file.
+        _check_version(version)
+        # Ensure that the given dtype is an authentic dtype object rather
+        # than just something that can be interpreted as a dtype object.
+        dtype = numpy.dtype(dtype)
+        if dtype.hasobject:
+            msg = "Array can't be memory-mapped: Python objects in dtype."
+            raise ValueError(msg)
+        d = dict(
+            descr=dtype_to_descr(dtype),
+            fortran_order=fortran_order,
+            shape=shape,
+        )
+        # If we got here, then it should be safe to create the file.
+        fp = open(filename, mode+'b')
+        try:
+            used_ver = _write_array_header(fp, d, version)
+            # this warning can be removed when 1.9 has aged enough
+            if version != (2, 0) and used_ver == (2, 0):
+                warnings.warn("Stored array in format 2.0. It can only be"
+                              "read by NumPy >= 1.9", UserWarning)
+            offset = fp.tell()
+        finally:
+            fp.close()
+    else:
+        # Read the header of the file first.
+        fp = open(filename, 'rb')
+        try:
+            version = read_magic(fp)
+            _check_version(version)
+
+            shape, fortran_order, dtype = _read_array_header(fp, version)
+            if dtype.hasobject:
+                msg = "Array can't be memory-mapped: Python objects in dtype."
+                raise ValueError(msg)
+            offset = fp.tell()
+        finally:
+            fp.close()
+
+    if fortran_order:
+        order = 'F'
+    else:
+        order = 'C'
+
+    # We need to change a write-only mode to a read-write mode since we've
+    # already written data to the file.
+    if mode == 'w+':
+        mode = 'r+'
+
+    marray = numpy.memmap(filename, dtype=dtype, shape=shape, order=order,
+        mode=mode, offset=offset)
+
+    return marray
+
+
+def _read_bytes(fp, size, error_template="ran out of data"):
+    """
+    Read from file-like object until size bytes are read.
+    Raises ValueError if not EOF is encountered before size bytes are read.
+    Non-blocking objects only supported if they derive from io objects.
+
+    Required as e.g. ZipExtFile in python 2.6 can return less data than
+    requested.
+    """
+    data = bytes()
+    while True:
+        # io files (default in python3) return None or raise on
+        # would-block, python2 file will truncate, probably nothing can be
+        # done about that.  note that regular files can't be non-blocking
+        try:
+            r = fp.read(size - len(data))
+            data += r
+            if len(r) == 0 or len(data) == size:
+                break
+        except io.BlockingIOError:
+            pass
+    if len(data) != size:
+        msg = "EOF: reading %s, expected %d bytes got %d"
+        raise ValueError(msg % (error_template, size, len(data)))
+    else:
+        return data
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/function_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/function_base.py
new file mode 100644
index 0000000000..44e0d5ce6b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/function_base.py
@@ -0,0 +1,4576 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+import collections
+import operator
+
+import numpy as np
+import numpy.core.numeric as _nx
+from numpy.core import linspace, atleast_1d, atleast_2d
+from numpy.core.numeric import (
+    ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
+    empty_like, ndarray, around, floor, ceil, take, dot, where, intp,
+    integer, isscalar
+    )
+from numpy.core.umath import (
+    pi, multiply, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin,
+    mod, exp, log10
+    )
+from numpy.core.fromnumeric import (
+    ravel, nonzero, sort, partition, mean, any, sum
+    )
+from numpy.core.numerictypes import typecodes, number
+from numpy.lib.twodim_base import diag
+from .utils import deprecate
+from numpy.core.multiarray import _insert, add_docstring
+from numpy.core.multiarray import digitize, bincount, interp as compiled_interp
+from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
+from numpy.compat import long
+from numpy.compat.py3k import basestring
+
+# Force range to be a generator, for np.delete's usage.
+if sys.version_info[0] < 3:
+    range = xrange
+
+
+__all__ = [
+    'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
+    'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp',
+    'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
+    'histogram', 'histogramdd', 'bincount', 'digitize', 'cov', 'corrcoef',
+    'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
+    'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring',
+    'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc'
+    ]
+
+
+def iterable(y):
+    """
+    Check whether or not an object can be iterated over.
+
+    Parameters
+    ----------
+    y : object
+      Input object.
+
+    Returns
+    -------
+    b : {0, 1}
+      Return 1 if the object has an iterator method or is a sequence,
+      and 0 otherwise.
+
+
+    Examples
+    --------
+    >>> np.iterable([1, 2, 3])
+    1
+    >>> np.iterable(2)
+    0
+
+    """
+    try:
+        iter(y)
+    except:
+        return 0
+    return 1
+
+
+def _hist_bin_sqrt(x):
+    """
+    Square root histogram bin estimator.
+
+    Bin width is inversely proportional to the data size. Used by many
+    programs for its simplicity.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / np.sqrt(x.size)
+
+
+def _hist_bin_sturges(x):
+    """
+    Sturges histogram bin estimator.
+
+    A very simplistic estimator based on the assumption of normality of
+    the data. This estimator has poor performance for non-normal data,
+    which becomes especially obvious for large data sets. The estimate
+    depends only on size of the data.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / (np.log2(x.size) + 1.0)
+
+
+def _hist_bin_rice(x):
+    """
+    Rice histogram bin estimator.
+
+    Another simple estimator with no normality assumption. It has better
+    performance for large data than Sturges, but tends to overestimate
+    the number of bins. The number of bins is proportional to the cube
+    root of data size (asymptotically optimal). The estimate depends
+    only on size of the data.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / (2.0 * x.size ** (1.0 / 3))
+
+
+def _hist_bin_scott(x):
+    """
+    Scott histogram bin estimator.
+
+    The binwidth is proportional to the standard deviation of the data
+    and inversely proportional to the cube root of data size
+    (asymptotically optimal).
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return (24.0 * np.pi**0.5 / x.size)**(1.0 / 3.0) * np.std(x)
+
+
+def _hist_bin_doane(x):
+    """
+    Doane's histogram bin estimator.
+
+    Improved version of Sturges' formula which works better for
+    non-normal data. See
+    http://stats.stackexchange.com/questions/55134/doanes-formula-for-histogram-binning
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    if x.size > 2:
+        sg1 = np.sqrt(6.0 * (x.size - 2) / ((x.size + 1.0) * (x.size + 3)))
+        sigma = np.std(x)
+        if sigma > 0.0:
+            # These three operations add up to
+            # g1 = np.mean(((x - np.mean(x)) / sigma)**3)
+            # but use only one temp array instead of three
+            temp = x - np.mean(x)
+            np.true_divide(temp, sigma, temp)
+            np.power(temp, 3, temp)
+            g1 = np.mean(temp)
+            return x.ptp() / (1.0 + np.log2(x.size) +
+                                    np.log2(1.0 + np.absolute(g1) / sg1))
+    return 0.0
+
+
+def _hist_bin_fd(x):
+    """
+    The Freedman-Diaconis histogram bin estimator.
+
+    The Freedman-Diaconis rule uses interquartile range (IQR) to
+    estimate binwidth. It is considered a variation of the Scott rule
+    with more robustness as the IQR is less affected by outliers than
+    the standard deviation. However, the IQR depends on fewer points
+    than the standard deviation, so it is less accurate, especially for
+    long tailed distributions.
+
+    If the IQR is 0, this function returns 1 for the number of bins.
+    Binwidth is inversely proportional to the cube root of data size
+    (asymptotically optimal).
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    iqr = np.subtract(*np.percentile(x, [75, 25]))
+    return 2.0 * iqr * x.size ** (-1.0 / 3.0)
+
+
+def _hist_bin_auto(x):
+    """
+    Histogram bin estimator that uses the minimum width of the
+    Freedman-Diaconis and Sturges estimators.
+
+    The FD estimator is usually the most robust method, but its width
+    estimate tends to be too large for small `x`. The Sturges estimator
+    is quite good for small (<1000) datasets and is the default in the R
+    language. This method gives good off the shelf behaviour.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+
+    See Also
+    --------
+    _hist_bin_fd, _hist_bin_sturges
+    """
+    # There is no need to check for zero here. If ptp is, so is IQR and
+    # vice versa. Either both are zero or neither one is.
+    return min(_hist_bin_fd(x), _hist_bin_sturges(x))
+
+
+# Private dict initialized at module load time
+_hist_bin_selectors = {'auto': _hist_bin_auto,
+                       'doane': _hist_bin_doane,
+                       'fd': _hist_bin_fd,
+                       'rice': _hist_bin_rice,
+                       'scott': _hist_bin_scott,
+                       'sqrt': _hist_bin_sqrt,
+                       'sturges': _hist_bin_sturges}
+
+
+def histogram(a, bins=10, range=None, normed=False, weights=None,
+              density=None):
+    r"""
+    Compute the histogram of a set of data.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data. The histogram is computed over the flattened array.
+    bins : int or sequence of scalars or str, optional
+        If `bins` is an int, it defines the number of equal-width
+        bins in the given range (10, by default). If `bins` is a
+        sequence, it defines the bin edges, including the rightmost
+        edge, allowing for non-uniform bin widths.
+
+        .. versionadded:: 1.11.0
+
+        If `bins` is a string from the list below, `histogram` will use
+        the method chosen to calculate the optimal bin width and
+        consequently the number of bins (see `Notes` for more detail on
+        the estimators) from the data that falls within the requested
+        range. While the bin width will be optimal for the actual data
+        in the range, the number of bins will be computed to fill the
+        entire range, including the empty portions. For visualisation,
+        using the 'auto' option is suggested. Weighted data is not
+        supported for automated bin size selection.
+
+        'auto'
+            Maximum of the 'sturges' and 'fd' estimators. Provides good
+            all round performance
+
+        'fd' (Freedman Diaconis Estimator)
+            Robust (resilient to outliers) estimator that takes into
+            account data variability and data size .
+
+        'doane'
+            An improved version of Sturges' estimator that works better
+            with non-normal datasets.
+
+        'scott'
+            Less robust estimator that that takes into account data
+            variability and data size.
+
+        'rice'
+            Estimator does not take variability into account, only data
+            size. Commonly overestimates number of bins required.
+
+        'sturges'
+            R's default method, only accounts for data size. Only
+            optimal for gaussian data and underestimates number of bins
+            for large non-gaussian datasets.
+
+        'sqrt'
+            Square root (of data size) estimator, used by Excel and
+            other programs for its speed and simplicity.
+
+    range : (float, float), optional
+        The lower and upper range of the bins.  If not provided, range
+        is simply ``(a.min(), a.max())``.  Values outside the range are
+        ignored. The first element of the range must be less than or
+        equal to the second. `range` affects the automatic bin
+        computation as well. While bin width is computed to be optimal
+        based on the actual data within `range`, the bin count will fill
+        the entire range including portions containing no data.
+    normed : bool, optional
+        This keyword is deprecated in Numpy 1.6 due to confusing/buggy
+        behavior. It will be removed in Numpy 2.0. Use the ``density``
+        keyword instead. If ``False``, the result will contain the
+        number of samples in each bin. If ``True``, the result is the
+        value of the probability *density* function at the bin,
+        normalized such that the *integral* over the range is 1. Note
+        that this latter behavior is known to be buggy with unequal bin
+        widths; use ``density`` instead.
+    weights : array_like, optional
+        An array of weights, of the same shape as `a`.  Each value in
+        `a` only contributes its associated weight towards the bin count
+        (instead of 1). If `density` is True, the weights are
+        normalized, so that the integral of the density over the range
+        remains 1.
+    density : bool, optional
+        If ``False``, the result will contain the number of samples in
+        each bin. If ``True``, the result is the value of the
+        probability *density* function at the bin, normalized such that
+        the *integral* over the range is 1. Note that the sum of the
+        histogram values will not be equal to 1 unless bins of unity
+        width are chosen; it is not a probability *mass* function.
+
+        Overrides the ``normed`` keyword if given.
+
+    Returns
+    -------
+    hist : array
+        The values of the histogram. See `density` and `weights` for a
+        description of the possible semantics.
+    bin_edges : array of dtype float
+        Return the bin edges ``(length(hist)+1)``.
+
+
+    See Also
+    --------
+    histogramdd, bincount, searchsorted, digitize
+
+    Notes
+    -----
+    All but the last (righthand-most) bin is half-open.  In other words,
+    if `bins` is::
+
+      [1, 2, 3, 4]
+
+    then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
+    the second ``[2, 3)``.  The last bin, however, is ``[3, 4]``, which
+    *includes* 4.
+
+    .. versionadded:: 1.11.0
+
+    The methods to estimate the optimal number of bins are well founded
+    in literature, and are inspired by the choices R provides for
+    histogram visualisation. Note that having the number of bins
+    proportional to :math:`n^{1/3}` is asymptotically optimal, which is
+    why it appears in most estimators. These are simply plug-in methods
+    that give good starting points for number of bins. In the equations
+    below, :math:`h` is the binwidth and :math:`n_h` is the number of
+    bins. All estimators that compute bin counts are recast to bin width
+    using the `ptp` of the data. The final bin count is obtained from
+    ``np.round(np.ceil(range / h))`.
+
+    'Auto' (maximum of the 'Sturges' and 'FD' estimators)
+        A compromise to get a good value. For small datasets the Sturges
+        value will usually be chosen, while larger datasets will usually
+        default to FD.  Avoids the overly conservative behaviour of FD
+        and Sturges for small and large datasets respectively.
+        Switchover point is usually :math:`a.size \approx 1000`.
+
+    'FD' (Freedman Diaconis Estimator)
+        .. math:: h = 2 \frac{IQR}{n^{1/3}}
+
+        The binwidth is proportional to the interquartile range (IQR)
+        and inversely proportional to cube root of a.size. Can be too
+        conservative for small datasets, but is quite good for large
+        datasets. The IQR is very robust to outliers.
+
+    'Scott'
+        .. math:: h = \sigma \sqrt[3]{\frac{24 * \sqrt{\pi}}{n}}
+
+        The binwidth is proportional to the standard deviation of the
+        data and inversely proportional to cube root of ``x.size``. Can
+        be too conservative for small datasets, but is quite good for
+        large datasets. The standard deviation is not very robust to
+        outliers. Values are very similar to the Freedman-Diaconis
+        estimator in the absence of outliers.
+
+    'Rice'
+        .. math:: n_h = 2n^{1/3}
+
+        The number of bins is only proportional to cube root of
+        ``a.size``. It tends to overestimate the number of bins and it
+        does not take into account data variability.
+
+    'Sturges'
+        .. math:: n_h = \log _{2}n+1
+
+        The number of bins is the base 2 log of ``a.size``.  This
+        estimator assumes normality of data and is too conservative for
+        larger, non-normal datasets. This is the default method in R's
+        ``hist`` method.
+
+    'Doane'
+        .. math:: n_h = 1 + \log_{2}(n) +
+                        \log_{2}(1 + \frac{|g_1|}{\sigma_{g_1})}
+
+            g_1 = mean[(\frac{x - \mu}{\sigma})^3]
+
+            \sigma_{g_1} = \sqrt{\frac{6(n - 2)}{(n + 1)(n + 3)}}
+
+        An improved version of Sturges' formula that produces better
+        estimates for non-normal datasets. This estimator attempts to
+        account for the skew of the data.
+
+    'Sqrt'
+        .. math:: n_h = \sqrt n
+        The simplest and fastest estimator. Only takes into account the
+        data size.
+
+    Examples
+    --------
+    >>> np.histogram([1, 2, 1], bins=[0, 1, 2, 3])
+    (array([0, 2, 1]), array([0, 1, 2, 3]))
+    >>> np.histogram(np.arange(4), bins=np.arange(5), density=True)
+    (array([ 0.25,  0.25,  0.25,  0.25]), array([0, 1, 2, 3, 4]))
+    >>> np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3])
+    (array([1, 4, 1]), array([0, 1, 2, 3]))
+
+    >>> a = np.arange(5)
+    >>> hist, bin_edges = np.histogram(a, density=True)
+    >>> hist
+    array([ 0.5,  0. ,  0.5,  0. ,  0. ,  0.5,  0. ,  0.5,  0. ,  0.5])
+    >>> hist.sum()
+    2.4999999999999996
+    >>> np.sum(hist*np.diff(bin_edges))
+    1.0
+
+    .. versionadded:: 1.11.0
+
+    Automated Bin Selection Methods example, using 2 peak random data
+    with 2000 points:
+
+    >>> import matplotlib.pyplot as plt
+    >>> rng = np.random.RandomState(10)  # deterministic random data
+    >>> a = np.hstack((rng.normal(size=1000),
+    ...                rng.normal(loc=5, scale=2, size=1000)))
+    >>> plt.hist(a, bins='auto')  # plt.hist passes it's arguments to np.histogram
+    >>> plt.title("Histogram with 'auto' bins")
+    >>> plt.show()
+
+    """
+    a = asarray(a)
+    if weights is not None:
+        weights = asarray(weights)
+        if np.any(weights.shape != a.shape):
+            raise ValueError(
+                'weights should have the same shape as a.')
+        weights = weights.ravel()
+    a = a.ravel()
+
+    # Do not modify the original value of range so we can check for `None`
+    if range is None:
+        if a.size == 0:
+            # handle empty arrays. Can't determine range, so use 0-1.
+            mn, mx = 0.0, 1.0
+        else:
+            mn, mx = a.min() + 0.0, a.max() + 0.0
+    else:
+        mn, mx = [mi + 0.0 for mi in range]
+    if mn > mx:
+        raise ValueError(
+            'max must be larger than min in range parameter.')
+    if not np.all(np.isfinite([mn, mx])):
+        raise ValueError(
+            'range parameter must be finite.')
+    if mn == mx:
+        mn -= 0.5
+        mx += 0.5
+
+    if isinstance(bins, basestring):
+        # if `bins` is a string for an automatic method,
+        # this will replace it with the number of bins calculated
+        if bins not in _hist_bin_selectors:
+            raise ValueError("{0} not a valid estimator for bins".format(bins))
+        if weights is not None:
+            raise TypeError("Automated estimation of the number of "
+                            "bins is not supported for weighted data")
+        # Make a reference to `a`
+        b = a
+        # Update the reference if the range needs truncation
+        if range is not None:
+            keep = (a >= mn)
+            keep &= (a <= mx)
+            if not np.logical_and.reduce(keep):
+                b = a[keep]
+
+        if b.size == 0:
+            bins = 1
+        else:
+            # Do not call selectors on empty arrays
+            width = _hist_bin_selectors[bins](b)
+            if width:
+                bins = int(np.ceil((mx - mn) / width))
+            else:
+                # Width can be zero for some estimators, e.g. FD when
+                # the IQR of the data is zero.
+                bins = 1
+
+    # Histogram is an integer or a float array depending on the weights.
+    if weights is None:
+        ntype = np.dtype(np.intp)
+    else:
+        ntype = weights.dtype
+
+    # We set a block size, as this allows us to iterate over chunks when
+    # computing histograms, to minimize memory usage.
+    BLOCK = 65536
+
+    if not iterable(bins):
+        if np.isscalar(bins) and bins < 1:
+            raise ValueError(
+                '`bins` should be a positive integer.')
+        # At this point, if the weights are not integer, floating point, or
+        # complex, we have to use the slow algorithm.
+        if weights is not None and not (np.can_cast(weights.dtype, np.double) or
+                                        np.can_cast(weights.dtype, np.complex)):
+            bins = linspace(mn, mx, bins + 1, endpoint=True)
+
+    if not iterable(bins):
+        # We now convert values of a to bin indices, under the assumption of
+        # equal bin widths (which is valid here).
+
+        # Initialize empty histogram
+        n = np.zeros(bins, ntype)
+        # Pre-compute histogram scaling factor
+        norm = bins / (mx - mn)
+
+        # We iterate over blocks here for two reasons: the first is that for
+        # large arrays, it is actually faster (for example for a 10^8 array it
+        # is 2x as fast) and it results in a memory footprint 3x lower in the
+        # limit of large arrays.
+        for i in arange(0, len(a), BLOCK):
+            tmp_a = a[i:i+BLOCK]
+            if weights is None:
+                tmp_w = None
+            else:
+                tmp_w = weights[i:i + BLOCK]
+
+            # Only include values in the right range
+            keep = (tmp_a >= mn)
+            keep &= (tmp_a <= mx)
+            if not np.logical_and.reduce(keep):
+                tmp_a = tmp_a[keep]
+                if tmp_w is not None:
+                    tmp_w = tmp_w[keep]
+            tmp_a = tmp_a.astype(float)
+            tmp_a -= mn
+            tmp_a *= norm
+
+            # Compute the bin indices, and for values that lie exactly on mx we
+            # need to subtract one
+            indices = tmp_a.astype(np.intp)
+            indices[indices == bins] -= 1
+
+            # We now compute the histogram using bincount
+            if ntype.kind == 'c':
+                n.real += np.bincount(indices, weights=tmp_w.real, minlength=bins)
+                n.imag += np.bincount(indices, weights=tmp_w.imag, minlength=bins)
+            else:
+                n += np.bincount(indices, weights=tmp_w, minlength=bins).astype(ntype)
+
+        # We now compute the bin edges since these are returned
+        bins = linspace(mn, mx, bins + 1, endpoint=True)
+    else:
+        bins = asarray(bins)
+        if (np.diff(bins) < 0).any():
+            raise ValueError(
+                'bins must increase monotonically.')
+
+        # Initialize empty histogram
+        n = np.zeros(bins.shape, ntype)
+
+        if weights is None:
+            for i in arange(0, len(a), BLOCK):
+                sa = sort(a[i:i+BLOCK])
+                n += np.r_[sa.searchsorted(bins[:-1], 'left'),
+                           sa.searchsorted(bins[-1], 'right')]
+        else:
+            zero = array(0, dtype=ntype)
+            for i in arange(0, len(a), BLOCK):
+                tmp_a = a[i:i+BLOCK]
+                tmp_w = weights[i:i+BLOCK]
+                sorting_index = np.argsort(tmp_a)
+                sa = tmp_a[sorting_index]
+                sw = tmp_w[sorting_index]
+                cw = np.concatenate(([zero, ], sw.cumsum()))
+                bin_index = np.r_[sa.searchsorted(bins[:-1], 'left'),
+                                  sa.searchsorted(bins[-1], 'right')]
+                n += cw[bin_index]
+
+
+        n = np.diff(n)
+
+    if density is not None:
+        if density:
+            db = array(np.diff(bins), float)
+            return n/db/n.sum(), bins
+        else:
+            return n, bins
+    else:
+        # deprecated, buggy behavior. Remove for Numpy 2.0
+        if normed:
+            db = array(np.diff(bins), float)
+            return n/(n*db).sum(), bins
+        else:
+            return n, bins
+
+
+def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
+    """
+    Compute the multidimensional histogram of some data.
+
+    Parameters
+    ----------
+    sample : array_like
+        The data to be histogrammed. It must be an (N,D) array or data
+        that can be converted to such. The rows of the resulting array
+        are the coordinates of points in a D dimensional polytope.
+    bins : sequence or int, optional
+        The bin specification:
+
+        * A sequence of arrays describing the bin edges along each dimension.
+        * The number of bins for each dimension (nx, ny, ... =bins)
+        * The number of bins for all dimensions (nx=ny=...=bins).
+
+    range : sequence, optional
+        A sequence of lower and upper bin edges to be used if the edges are
+        not given explicitly in `bins`. Defaults to the minimum and maximum
+        values along each dimension.
+    normed : bool, optional
+        If False, returns the number of samples in each bin. If True,
+        returns the bin density ``bin_count / sample_count / bin_volume``.
+    weights : (N,) array_like, optional
+        An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
+        Weights are normalized to 1 if normed is True. If normed is False,
+        the values of the returned histogram are equal to the sum of the
+        weights belonging to the samples falling into each bin.
+
+    Returns
+    -------
+    H : ndarray
+        The multidimensional histogram of sample x. See normed and weights
+        for the different possible semantics.
+    edges : list
+        A list of D arrays describing the bin edges for each dimension.
+
+    See Also
+    --------
+    histogram: 1-D histogram
+    histogram2d: 2-D histogram
+
+    Examples
+    --------
+    >>> r = np.random.randn(100,3)
+    >>> H, edges = np.histogramdd(r, bins = (5, 8, 4))
+    >>> H.shape, edges[0].size, edges[1].size, edges[2].size
+    ((5, 8, 4), 6, 9, 5)
+
+    """
+
+    try:
+        # Sample is an ND-array.
+        N, D = sample.shape
+    except (AttributeError, ValueError):
+        # Sample is a sequence of 1D arrays.
+        sample = atleast_2d(sample).T
+        N, D = sample.shape
+
+    nbin = empty(D, int)
+    edges = D*[None]
+    dedges = D*[None]
+    if weights is not None:
+        weights = asarray(weights)
+
+    try:
+        M = len(bins)
+        if M != D:
+            raise ValueError(
+                'The dimension of bins must be equal to the dimension of the '
+                ' sample x.')
+    except TypeError:
+        # bins is an integer
+        bins = D*[bins]
+
+    # Select range for each dimension
+    # Used only if number of bins is given.
+    if range is None:
+        # Handle empty input. Range can't be determined in that case, use 0-1.
+        if N == 0:
+            smin = zeros(D)
+            smax = ones(D)
+        else:
+            smin = atleast_1d(array(sample.min(0), float))
+            smax = atleast_1d(array(sample.max(0), float))
+    else:
+        if not np.all(np.isfinite(range)):
+            raise ValueError(
+                'range parameter must be finite.')
+        smin = zeros(D)
+        smax = zeros(D)
+        for i in arange(D):
+            smin[i], smax[i] = range[i]
+
+    # Make sure the bins have a finite width.
+    for i in arange(len(smin)):
+        if smin[i] == smax[i]:
+            smin[i] = smin[i] - .5
+            smax[i] = smax[i] + .5
+
+    # avoid rounding issues for comparisons when dealing with inexact types
+    if np.issubdtype(sample.dtype, np.inexact):
+        edge_dt = sample.dtype
+    else:
+        edge_dt = float
+    # Create edge arrays
+    for i in arange(D):
+        if isscalar(bins[i]):
+            if bins[i] < 1:
+                raise ValueError(
+                    "Element at index %s in `bins` should be a positive "
+                    "integer." % i)
+            nbin[i] = bins[i] + 2  # +2 for outlier bins
+            edges[i] = linspace(smin[i], smax[i], nbin[i]-1, dtype=edge_dt)
+        else:
+            edges[i] = asarray(bins[i], edge_dt)
+            nbin[i] = len(edges[i]) + 1  # +1 for outlier bins
+        dedges[i] = diff(edges[i])
+        if np.any(np.asarray(dedges[i]) <= 0):
+            raise ValueError(
+                "Found bin edge of size <= 0. Did you specify `bins` with"
+                "non-monotonic sequence?")
+
+    nbin = asarray(nbin)
+
+    # Handle empty input.
+    if N == 0:
+        return np.zeros(nbin-2), edges
+
+    # Compute the bin number each sample falls into.
+    Ncount = {}
+    for i in arange(D):
+        Ncount[i] = digitize(sample[:, i], edges[i])
+
+    # Using digitize, values that fall on an edge are put in the right bin.
+    # For the rightmost bin, we want values equal to the right edge to be
+    # counted in the last bin, and not as an outlier.
+    for i in arange(D):
+        # Rounding precision
+        mindiff = dedges[i].min()
+        if not np.isinf(mindiff):
+            decimal = int(-log10(mindiff)) + 6
+            # Find which points are on the rightmost edge.
+            not_smaller_than_edge = (sample[:, i] >= edges[i][-1])
+            on_edge = (around(sample[:, i], decimal) ==
+                       around(edges[i][-1], decimal))
+            # Shift these points one bin to the left.
+            Ncount[i][where(on_edge & not_smaller_than_edge)[0]] -= 1
+
+    # Flattened histogram matrix (1D)
+    # Reshape is used so that overlarge arrays
+    # will raise an error.
+    hist = zeros(nbin, float).reshape(-1)
+
+    # Compute the sample indices in the flattened histogram matrix.
+    ni = nbin.argsort()
+    xy = zeros(N, int)
+    for i in arange(0, D-1):
+        xy += Ncount[ni[i]] * nbin[ni[i+1:]].prod()
+    xy += Ncount[ni[-1]]
+
+    # Compute the number of repetitions in xy and assign it to the
+    # flattened histmat.
+    if len(xy) == 0:
+        return zeros(nbin-2, int), edges
+
+    flatcount = bincount(xy, weights)
+    a = arange(len(flatcount))
+    hist[a] = flatcount
+
+    # Shape into a proper matrix
+    hist = hist.reshape(sort(nbin))
+    for i in arange(nbin.size):
+        j = ni.argsort()[i]
+        hist = hist.swapaxes(i, j)
+        ni[i], ni[j] = ni[j], ni[i]
+
+    # Remove outliers (indices 0 and -1 for each dimension).
+    core = D*[slice(1, -1)]
+    hist = hist[core]
+
+    # Normalize if normed is True
+    if normed:
+        s = hist.sum()
+        for i in arange(D):
+            shape = ones(D, int)
+            shape[i] = nbin[i] - 2
+            hist = hist / dedges[i].reshape(shape)
+        hist /= s
+
+    if (hist.shape != nbin - 2).any():
+        raise RuntimeError(
+            "Internal Shape Error")
+    return hist, edges
+
+
+def average(a, axis=None, weights=None, returned=False):
+    """
+    Compute the weighted average along the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing data to be averaged. If `a` is not an array, a
+        conversion is attempted.
+    axis : int, optional
+        Axis along which to average `a`. If `None`, averaging is done over
+        the flattened array.
+    weights : array_like, optional
+        An array of weights associated with the values in `a`. Each value in
+        `a` contributes to the average according to its associated weight.
+        The weights array can either be 1-D (in which case its length must be
+        the size of `a` along the given axis) or of the same shape as `a`.
+        If `weights=None`, then all data in `a` are assumed to have a
+        weight equal to one.
+    returned : bool, optional
+        Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
+        is returned, otherwise only the average is returned.
+        If `weights=None`, `sum_of_weights` is equivalent to the number of
+        elements over which the average is taken.
+
+
+    Returns
+    -------
+    average, [sum_of_weights] : array_type or double
+        Return the average along the specified axis. When returned is `True`,
+        return a tuple with the average as the first element and the sum
+        of the weights as the second element. The return type is `Float`
+        if `a` is of integer type, otherwise it is of the same type as `a`.
+        `sum_of_weights` is of the same type as `average`.
+
+    Raises
+    ------
+    ZeroDivisionError
+        When all weights along axis are zero. See `numpy.ma.average` for a
+        version robust to this type of error.
+    TypeError
+        When the length of 1D `weights` is not the same as the shape of `a`
+        along axis.
+
+    See Also
+    --------
+    mean
+
+    ma.average : average for masked arrays -- useful if your data contains
+                 "missing" values
+
+    Examples
+    --------
+    >>> data = range(1,5)
+    >>> data
+    [1, 2, 3, 4]
+    >>> np.average(data)
+    2.5
+    >>> np.average(range(1,11), weights=range(10,0,-1))
+    4.0
+
+    >>> data = np.arange(6).reshape((3,2))
+    >>> data
+    array([[0, 1],
+           [2, 3],
+           [4, 5]])
+    >>> np.average(data, axis=1, weights=[1./4, 3./4])
+    array([ 0.75,  2.75,  4.75])
+    >>> np.average(data, weights=[1./4, 3./4])
+    Traceback (most recent call last):
+    ...
+    TypeError: Axis must be specified when shapes of a and weights differ.
+
+    """
+    if not isinstance(a, np.matrix):
+        a = np.asarray(a)
+
+    if weights is None:
+        avg = a.mean(axis)
+        scl = avg.dtype.type(a.size/avg.size)
+    else:
+        a = a + 0.0
+        wgt = np.asarray(weights)
+        # Sanity checks
+        if a.shape != wgt.shape:
+            if axis is None:
+                raise TypeError(
+                    "Axis must be specified when shapes of a and weights "
+                    "differ.")
+            if wgt.ndim != 1:
+                raise TypeError(
+                    "1D weights expected when shapes of a and weights differ.")
+            if wgt.shape[0] != a.shape[axis]:
+                raise ValueError(
+                    "Length of weights not compatible with specified axis.")
+
+            # setup wgt to broadcast along axis
+            wgt = np.array(wgt, copy=0, ndmin=a.ndim).swapaxes(-1, axis)
+
+        scl = wgt.sum(axis=axis, dtype=np.result_type(a.dtype, wgt.dtype))
+        if (scl == 0.0).any():
+            raise ZeroDivisionError(
+                "Weights sum to zero, can't be normalized")
+
+        avg = np.multiply(a, wgt).sum(axis)/scl
+
+    if returned:
+        scl = np.multiply(avg, 0) + scl
+        return avg, scl
+    else:
+        return avg
+
+
+def asarray_chkfinite(a, dtype=None, order=None):
+    """Convert the input to an array, checking for NaNs or Infs.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists and ndarrays.  Success requires no NaNs or Infs.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+         Whether to use row-major (C-style) or
+         column-major (Fortran-style) memory representation.
+         Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray
+        Array interpretation of `a`.  No copy is performed if the input
+        is already an ndarray.  If `a` is a subclass of ndarray, a base
+        class ndarray is returned.
+
+    Raises
+    ------
+    ValueError
+        Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).
+
+    See Also
+    --------
+    asarray : Create and array.
+    asanyarray : Similar function which passes through subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array.  If all elements are finite
+    ``asarray_chkfinite`` is identical to ``asarray``.
+
+    >>> a = [1, 2]
+    >>> np.asarray_chkfinite(a, dtype=float)
+    array([1., 2.])
+
+    Raises ValueError if array_like contains Nans or Infs.
+
+    >>> a = [1, 2, np.inf]
+    >>> try:
+    ...     np.asarray_chkfinite(a)
+    ... except ValueError:
+    ...     print('ValueError')
+    ...
+    ValueError
+
+    """
+    a = asarray(a, dtype=dtype, order=order)
+    if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
+        raise ValueError(
+            "array must not contain infs or NaNs")
+    return a
+
+
+def piecewise(x, condlist, funclist, *args, **kw):
+    """
+    Evaluate a piecewise-defined function.
+
+    Given a set of conditions and corresponding functions, evaluate each
+    function on the input data wherever its condition is true.
+
+    Parameters
+    ----------
+    x : ndarray
+        The input domain.
+    condlist : list of bool arrays
+        Each boolean array corresponds to a function in `funclist`.  Wherever
+        `condlist[i]` is True, `funclist[i](x)` is used as the output value.
+
+        Each boolean array in `condlist` selects a piece of `x`,
+        and should therefore be of the same shape as `x`.
+
+        The length of `condlist` must correspond to that of `funclist`.
+        If one extra function is given, i.e. if
+        ``len(funclist) - len(condlist) == 1``, then that extra function
+        is the default value, used wherever all conditions are false.
+    funclist : list of callables, f(x,*args,**kw), or scalars
+        Each function is evaluated over `x` wherever its corresponding
+        condition is True.  It should take an array as input and give an array
+        or a scalar value as output.  If, instead of a callable,
+        a scalar is provided then a constant function (``lambda x: scalar``) is
+        assumed.
+    args : tuple, optional
+        Any further arguments given to `piecewise` are passed to the functions
+        upon execution, i.e., if called ``piecewise(..., ..., 1, 'a')``, then
+        each function is called as ``f(x, 1, 'a')``.
+    kw : dict, optional
+        Keyword arguments used in calling `piecewise` are passed to the
+        functions upon execution, i.e., if called
+        ``piecewise(..., ..., lambda=1)``, then each function is called as
+        ``f(x, lambda=1)``.
+
+    Returns
+    -------
+    out : ndarray
+        The output is the same shape and type as x and is found by
+        calling the functions in `funclist` on the appropriate portions of `x`,
+        as defined by the boolean arrays in `condlist`.  Portions not covered
+        by any condition have a default value of 0.
+
+
+    See Also
+    --------
+    choose, select, where
+
+    Notes
+    -----
+    This is similar to choose or select, except that functions are
+    evaluated on elements of `x` that satisfy the corresponding condition from
+    `condlist`.
+
+    The result is::
+
+            |--
+            |funclist[0](x[condlist[0]])
+      out = |funclist[1](x[condlist[1]])
+            |...
+            |funclist[n2](x[condlist[n2]])
+            |--
+
+    Examples
+    --------
+    Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``.
+
+    >>> x = np.linspace(-2.5, 2.5, 6)
+    >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1])
+    array([-1., -1., -1.,  1.,  1.,  1.])
+
+    Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for
+    ``x >= 0``.
+
+    >>> np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x])
+    array([ 2.5,  1.5,  0.5,  0.5,  1.5,  2.5])
+
+    """
+    x = asanyarray(x)
+    n2 = len(funclist)
+    if (isscalar(condlist) or not (isinstance(condlist[0], list) or
+                                   isinstance(condlist[0], ndarray))):
+        condlist = [condlist]
+    condlist = array(condlist, dtype=bool)
+    n = len(condlist)
+    # This is a hack to work around problems with NumPy's
+    #  handling of 0-d arrays and boolean indexing with
+    #  numpy.bool_ scalars
+    zerod = False
+    if x.ndim == 0:
+        x = x[None]
+        zerod = True
+        if condlist.shape[-1] != 1:
+            condlist = condlist.T
+    if n == n2 - 1:  # compute the "otherwise" condition.
+        totlist = np.logical_or.reduce(condlist, axis=0)
+        # Only able to stack vertically if the array is 1d or less
+        if x.ndim <= 1:
+            condlist = np.vstack([condlist, ~totlist])
+        else:
+            condlist = [asarray(c, dtype=bool) for c in condlist]
+            totlist = condlist[0]
+            for k in range(1, n):
+                totlist |= condlist[k]
+            condlist.append(~totlist)
+        n += 1
+
+    y = zeros(x.shape, x.dtype)
+    for k in range(n):
+        item = funclist[k]
+        if not isinstance(item, collections.Callable):
+            y[condlist[k]] = item
+        else:
+            vals = x[condlist[k]]
+            if vals.size > 0:
+                y[condlist[k]] = item(vals, *args, **kw)
+    if zerod:
+        y = y.squeeze()
+    return y
+
+
+def select(condlist, choicelist, default=0):
+    """
+    Return an array drawn from elements in choicelist, depending on conditions.
+
+    Parameters
+    ----------
+    condlist : list of bool ndarrays
+        The list of conditions which determine from which array in `choicelist`
+        the output elements are taken. When multiple conditions are satisfied,
+        the first one encountered in `condlist` is used.
+    choicelist : list of ndarrays
+        The list of arrays from which the output elements are taken. It has
+        to be of the same length as `condlist`.
+    default : scalar, optional
+        The element inserted in `output` when all conditions evaluate to False.
+
+    Returns
+    -------
+    output : ndarray
+        The output at position m is the m-th element of the array in
+        `choicelist` where the m-th element of the corresponding array in
+        `condlist` is True.
+
+    See Also
+    --------
+    where : Return elements from one of two arrays depending on condition.
+    take, choose, compress, diag, diagonal
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> condlist = [x<3, x>5]
+    >>> choicelist = [x, x**2]
+    >>> np.select(condlist, choicelist)
+    array([ 0,  1,  2,  0,  0,  0, 36, 49, 64, 81])
+
+    """
+    # Check the size of condlist and choicelist are the same, or abort.
+    if len(condlist) != len(choicelist):
+        raise ValueError(
+            'list of cases must be same length as list of conditions')
+
+    # Now that the dtype is known, handle the deprecated select([], []) case
+    if len(condlist) == 0:
+        # 2014-02-24, 1.9
+        warnings.warn("select with an empty condition list is not possible"
+                      "and will be deprecated",
+                      DeprecationWarning)
+        return np.asarray(default)[()]
+
+    choicelist = [np.asarray(choice) for choice in choicelist]
+    choicelist.append(np.asarray(default))
+
+    # need to get the result type before broadcasting for correct scalar
+    # behaviour
+    dtype = np.result_type(*choicelist)
+
+    # Convert conditions to arrays and broadcast conditions and choices
+    # as the shape is needed for the result. Doing it separately optimizes
+    # for example when all choices are scalars.
+    condlist = np.broadcast_arrays(*condlist)
+    choicelist = np.broadcast_arrays(*choicelist)
+
+    # If cond array is not an ndarray in boolean format or scalar bool, abort.
+    deprecated_ints = False
+    for i in range(len(condlist)):
+        cond = condlist[i]
+        if cond.dtype.type is not np.bool_:
+            if np.issubdtype(cond.dtype, np.integer):
+                # A previous implementation accepted int ndarrays accidentally.
+                # Supported here deliberately, but deprecated.
+                condlist[i] = condlist[i].astype(bool)
+                deprecated_ints = True
+            else:
+                raise ValueError(
+                    'invalid entry in choicelist: should be boolean ndarray')
+
+    if deprecated_ints:
+        # 2014-02-24, 1.9
+        msg = "select condlists containing integer ndarrays is deprecated " \
+            "and will be removed in the future. Use `.astype(bool)` to " \
+            "convert to bools."
+        warnings.warn(msg, DeprecationWarning)
+
+    if choicelist[0].ndim == 0:
+        # This may be common, so avoid the call.
+        result_shape = condlist[0].shape
+    else:
+        result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape
+
+    result = np.full(result_shape, choicelist[-1], dtype)
+
+    # Use np.copyto to burn each choicelist array onto result, using the
+    # corresponding condlist as a boolean mask. This is done in reverse
+    # order since the first choice should take precedence.
+    choicelist = choicelist[-2::-1]
+    condlist = condlist[::-1]
+    for choice, cond in zip(choicelist, condlist):
+        np.copyto(result, choice, where=cond)
+
+    return result
+
+
+def copy(a, order='K'):
+    """
+    Return an array copy of the given object.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the copy. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible. (Note that this function and :meth:ndarray.copy are very
+        similar, but have different default values for their order=
+        arguments.)
+
+    Returns
+    -------
+    arr : ndarray
+        Array interpretation of `a`.
+
+    Notes
+    -----
+    This is equivalent to
+
+    >>> np.array(a, copy=True)                              #doctest: +SKIP
+
+    Examples
+    --------
+    Create an array x, with a reference y and a copy z:
+
+    >>> x = np.array([1, 2, 3])
+    >>> y = x
+    >>> z = np.copy(x)
+
+    Note that, when we modify x, y changes, but not z:
+
+    >>> x[0] = 10
+    >>> x[0] == y[0]
+    True
+    >>> x[0] == z[0]
+    False
+
+    """
+    return array(a, order=order, copy=True)
+
+# Basic operations
+
+
+def gradient(f, *varargs, **kwargs):
+    """
+    Return the gradient of an N-dimensional array.
+
+    The gradient is computed using second order accurate central differences
+    in the interior and either first differences or second order accurate
+    one-sides (forward or backwards) differences at the boundaries. The
+    returned gradient hence has the same shape as the input array.
+
+    Parameters
+    ----------
+    f : array_like
+        An N-dimensional array containing samples of a scalar function.
+    varargs : scalar or list of scalar, optional
+        N scalars specifying the sample distances for each dimension,
+        i.e. `dx`, `dy`, `dz`, ... Default distance: 1.
+        single scalar specifies sample distance for all dimensions.
+        if `axis` is given, the number of varargs must equal the number of axes.
+    edge_order : {1, 2}, optional
+        Gradient is calculated using N\ :sup:`th` order accurate differences
+        at the boundaries. Default: 1.
+
+        .. versionadded:: 1.9.1
+
+    axis : None or int or tuple of ints, optional
+        Gradient is calculated only along the given axis or axes
+        The default (axis = None) is to calculate the gradient for all the axes of the input array.
+        axis may be negative, in which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.11.0
+
+    Returns
+    -------
+    gradient : list of ndarray
+        Each element of `list` has the same shape as `f` giving the derivative
+        of `f` with respect to each dimension.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 11, 16], dtype=np.float)
+    >>> np.gradient(x)
+    array([ 1. ,  1.5,  2.5,  3.5,  4.5,  5. ])
+    >>> np.gradient(x, 2)
+    array([ 0.5 ,  0.75,  1.25,  1.75,  2.25,  2.5 ])
+
+    For two dimensional arrays, the return will be two arrays ordered by
+    axis. In this example the first array stands for the gradient in
+    rows and the second one in columns direction:
+
+    >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float))
+    [array([[ 2.,  2., -1.],
+            [ 2.,  2., -1.]]), array([[ 1. ,  2.5,  4. ],
+            [ 1. ,  1. ,  1. ]])]
+
+    >>> x = np.array([0, 1, 2, 3, 4])
+    >>> dx = np.gradient(x)
+    >>> y = x**2
+    >>> np.gradient(y, dx, edge_order=2)
+    array([-0.,  2.,  4.,  6.,  8.])
+
+    The axis keyword can be used to specify a subset of axes of which the gradient is calculated
+    >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float), axis=0)
+    array([[ 2.,  2., -1.],
+           [ 2.,  2., -1.]])
+    """
+    f = np.asanyarray(f)
+    N = len(f.shape)  # number of dimensions
+
+    axes = kwargs.pop('axis', None)
+    if axes is None:
+        axes = tuple(range(N))
+    # check axes to have correct type and no duplicate entries
+    if isinstance(axes, int):
+        axes = (axes,)
+    if not isinstance(axes, tuple):
+        raise TypeError("A tuple of integers or a single integer is required")
+
+    # normalize axis values:
+    axes = tuple(x + N if x < 0 else x for x in axes)
+    if max(axes) >= N or min(axes) < 0:
+        raise ValueError("'axis' entry is out of bounds")
+
+    if len(set(axes)) != len(axes):
+        raise ValueError("duplicate value in 'axis'")
+
+    n = len(varargs)
+    if n == 0:
+        dx = [1.0]*N
+    elif n == 1:
+        dx = [varargs[0]]*N
+    elif n == len(axes):
+        dx = list(varargs)
+    else:
+        raise SyntaxError(
+            "invalid number of arguments")
+
+    edge_order = kwargs.pop('edge_order', 1)
+    if kwargs:
+        raise TypeError('"{}" are not valid keyword arguments.'.format(
+                                                  '", "'.join(kwargs.keys())))
+    if edge_order > 2:
+        raise ValueError("'edge_order' greater than 2 not supported")
+
+    # use central differences on interior and one-sided differences on the
+    # endpoints. This preserves second order-accuracy over the full domain.
+
+    outvals = []
+
+    # create slice objects --- initially all are [:, :, ..., :]
+    slice1 = [slice(None)]*N
+    slice2 = [slice(None)]*N
+    slice3 = [slice(None)]*N
+    slice4 = [slice(None)]*N
+
+    otype = f.dtype.char
+    if otype not in ['f', 'd', 'F', 'D', 'm', 'M']:
+        otype = 'd'
+
+    # Difference of datetime64 elements results in timedelta64
+    if otype == 'M':
+        # Need to use the full dtype name because it contains unit information
+        otype = f.dtype.name.replace('datetime', 'timedelta')
+    elif otype == 'm':
+        # Needs to keep the specific units, can't be a general unit
+        otype = f.dtype
+
+    # Convert datetime64 data into ints. Make dummy variable `y`
+    # that is a view of ints if the data is datetime64, otherwise
+    # just set y equal to the array `f`.
+    if f.dtype.char in ["M", "m"]:
+        y = f.view('int64')
+    else:
+        y = f
+
+    for i, axis in enumerate(axes):
+
+        if y.shape[axis] < 2:
+            raise ValueError(
+                "Shape of array too small to calculate a numerical gradient, "
+                "at least two elements are required.")
+
+        # Numerical differentiation: 1st order edges, 2nd order interior
+        if y.shape[axis] == 2 or edge_order == 1:
+            # Use first order differences for time data
+            out = np.empty_like(y, dtype=otype)
+
+            slice1[axis] = slice(1, -1)
+            slice2[axis] = slice(2, None)
+            slice3[axis] = slice(None, -2)
+            # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
+            out[slice1] = (y[slice2] - y[slice3])/2.0
+
+            slice1[axis] = 0
+            slice2[axis] = 1
+            slice3[axis] = 0
+            # 1D equivalent -- out[0] = (y[1] - y[0])
+            out[slice1] = (y[slice2] - y[slice3])
+
+            slice1[axis] = -1
+            slice2[axis] = -1
+            slice3[axis] = -2
+            # 1D equivalent -- out[-1] = (y[-1] - y[-2])
+            out[slice1] = (y[slice2] - y[slice3])
+
+        # Numerical differentiation: 2st order edges, 2nd order interior
+        else:
+            # Use second order differences where possible
+            out = np.empty_like(y, dtype=otype)
+
+            slice1[axis] = slice(1, -1)
+            slice2[axis] = slice(2, None)
+            slice3[axis] = slice(None, -2)
+            # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
+            out[slice1] = (y[slice2] - y[slice3])/2.0
+
+            slice1[axis] = 0
+            slice2[axis] = 0
+            slice3[axis] = 1
+            slice4[axis] = 2
+            # 1D equivalent -- out[0] = -(3*y[0] - 4*y[1] + y[2]) / 2.0
+            out[slice1] = -(3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
+
+            slice1[axis] = -1
+            slice2[axis] = -1
+            slice3[axis] = -2
+            slice4[axis] = -3
+            # 1D equivalent -- out[-1] = (3*y[-1] - 4*y[-2] + y[-3])
+            out[slice1] = (3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
+
+        # divide by step size
+        out /= dx[i]
+        outvals.append(out)
+
+        # reset the slice object in this dimension to ":"
+        slice1[axis] = slice(None)
+        slice2[axis] = slice(None)
+        slice3[axis] = slice(None)
+        slice4[axis] = slice(None)
+
+    if len(axes) == 1:
+        return outvals[0]
+    else:
+        return outvals
+
+
+def diff(a, n=1, axis=-1):
+    """
+    Calculate the n-th discrete difference along given axis.
+
+    The first difference is given by ``out[n] = a[n+1] - a[n]`` along
+    the given axis, higher differences are calculated by using `diff`
+    recursively.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+    n : int, optional
+        The number of times values are differenced.
+    axis : int, optional
+        The axis along which the difference is taken, default is the last axis.
+
+    Returns
+    -------
+    diff : ndarray
+        The n-th differences. The shape of the output is the same as `a`
+        except along `axis` where the dimension is smaller by `n`.
+.
+
+    See Also
+    --------
+    gradient, ediff1d, cumsum
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 0])
+    >>> np.diff(x)
+    array([ 1,  2,  3, -7])
+    >>> np.diff(x, n=2)
+    array([  1,   1, -10])
+
+    >>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]])
+    >>> np.diff(x)
+    array([[2, 3, 4],
+           [5, 1, 2]])
+    >>> np.diff(x, axis=0)
+    array([[-1,  2,  0, -2]])
+
+    """
+    if n == 0:
+        return a
+    if n < 0:
+        raise ValueError(
+            "order must be non-negative but got " + repr(n))
+    a = asanyarray(a)
+    nd = len(a.shape)
+    slice1 = [slice(None)]*nd
+    slice2 = [slice(None)]*nd
+    slice1[axis] = slice(1, None)
+    slice2[axis] = slice(None, -1)
+    slice1 = tuple(slice1)
+    slice2 = tuple(slice2)
+    if n > 1:
+        return diff(a[slice1]-a[slice2], n-1, axis=axis)
+    else:
+        return a[slice1]-a[slice2]
+
+
+def interp(x, xp, fp, left=None, right=None, period=None):
+    """
+    One-dimensional linear interpolation.
+
+    Returns the one-dimensional piecewise linear interpolant to a function
+    with given values at discrete data-points.
+
+    Parameters
+    ----------
+    x : array_like
+        The x-coordinates of the interpolated values.
+
+    xp : 1-D sequence of floats
+        The x-coordinates of the data points, must be increasing if argument
+        `period` is not specified. Otherwise, `xp` is internally sorted after
+        normalizing the periodic boundaries with ``xp = xp % period``.
+
+    fp : 1-D sequence of floats
+        The y-coordinates of the data points, same length as `xp`.
+
+    left : float, optional
+        Value to return for `x < xp[0]`, default is `fp[0]`.
+
+    right : float, optional
+        Value to return for `x > xp[-1]`, default is `fp[-1]`.
+
+    period : None or float, optional
+        A period for the x-coordinates. This parameter allows the proper
+        interpolation of angular x-coordinates. Parameters `left` and `right`
+        are ignored if `period` is specified.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    y : float or ndarray
+        The interpolated values, same shape as `x`.
+
+    Raises
+    ------
+    ValueError
+        If `xp` and `fp` have different length
+        If `xp` or `fp` are not 1-D sequences
+        If `period == 0`
+
+    Notes
+    -----
+    Does not check that the x-coordinate sequence `xp` is increasing.
+    If `xp` is not increasing, the results are nonsense.
+    A simple check for increasing is::
+
+        np.all(np.diff(xp) > 0)
+
+    Examples
+    --------
+    >>> xp = [1, 2, 3]
+    >>> fp = [3, 2, 0]
+    >>> np.interp(2.5, xp, fp)
+    1.0
+    >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
+    array([ 3. ,  3. ,  2.5 ,  0.56,  0. ])
+    >>> UNDEF = -99.0
+    >>> np.interp(3.14, xp, fp, right=UNDEF)
+    -99.0
+
+    Plot an interpolant to the sine function:
+
+    >>> x = np.linspace(0, 2*np.pi, 10)
+    >>> y = np.sin(x)
+    >>> xvals = np.linspace(0, 2*np.pi, 50)
+    >>> yinterp = np.interp(xvals, x, y)
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot(x, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(xvals, yinterp, '-x')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.show()
+
+    Interpolation with periodic x-coordinates:
+
+    >>> x = [-180, -170, -185, 185, -10, -5, 0, 365]
+    >>> xp = [190, -190, 350, -350]
+    >>> fp = [5, 10, 3, 4]
+    >>> np.interp(x, xp, fp, period=360)
+    array([7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75])
+
+    """
+    if period is None:
+        if isinstance(x, (float, int, number)):
+            return compiled_interp([x], xp, fp, left, right).item()
+        elif isinstance(x, np.ndarray) and x.ndim == 0:
+            return compiled_interp([x], xp, fp, left, right).item()
+        else:
+            return compiled_interp(x, xp, fp, left, right)
+    else:
+        if period == 0:
+            raise ValueError("period must be a non-zero value")
+        period = abs(period)
+        left = None
+        right = None
+        return_array = True
+        if isinstance(x, (float, int, number)):
+            return_array = False
+            x = [x]
+        x = np.asarray(x, dtype=np.float64)
+        xp = np.asarray(xp, dtype=np.float64)
+        fp = np.asarray(fp, dtype=np.float64)
+        if xp.ndim != 1 or fp.ndim != 1:
+            raise ValueError("Data points must be 1-D sequences")
+        if xp.shape[0] != fp.shape[0]:
+            raise ValueError("fp and xp are not of the same length")
+        # normalizing periodic boundaries
+        x = x % period
+        xp = xp % period
+        asort_xp = np.argsort(xp)
+        xp = xp[asort_xp]
+        fp = fp[asort_xp]
+        xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
+        fp = np.concatenate((fp[-1:], fp, fp[0:1]))
+        if return_array:
+            return compiled_interp(x, xp, fp, left, right)
+        else:
+            return compiled_interp(x, xp, fp, left, right).item()
+
+
+def angle(z, deg=0):
+    """
+    Return the angle of the complex argument.
+
+    Parameters
+    ----------
+    z : array_like
+        A complex number or sequence of complex numbers.
+    deg : bool, optional
+        Return angle in degrees if True, radians if False (default).
+
+    Returns
+    -------
+    angle : ndarray or scalar
+        The counterclockwise angle from the positive real axis on
+        the complex plane, with dtype as numpy.float64.
+
+    See Also
+    --------
+    arctan2
+    absolute
+
+
+
+    Examples
+    --------
+    >>> np.angle([1.0, 1.0j, 1+1j])               # in radians
+    array([ 0.        ,  1.57079633,  0.78539816])
+    >>> np.angle(1+1j, deg=True)                  # in degrees
+    45.0
+
+    """
+    if deg:
+        fact = 180/pi
+    else:
+        fact = 1.0
+    z = asarray(z)
+    if (issubclass(z.dtype.type, _nx.complexfloating)):
+        zimag = z.imag
+        zreal = z.real
+    else:
+        zimag = 0
+        zreal = z
+    return arctan2(zimag, zreal) * fact
+
+
+def unwrap(p, discont=pi, axis=-1):
+    """
+    Unwrap by changing deltas between values to 2*pi complement.
+
+    Unwrap radian phase `p` by changing absolute jumps greater than
+    `discont` to their 2*pi complement along the given axis.
+
+    Parameters
+    ----------
+    p : array_like
+        Input array.
+    discont : float, optional
+        Maximum discontinuity between values, default is ``pi``.
+    axis : int, optional
+        Axis along which unwrap will operate, default is the last axis.
+
+    Returns
+    -------
+    out : ndarray
+        Output array.
+
+    See Also
+    --------
+    rad2deg, deg2rad
+
+    Notes
+    -----
+    If the discontinuity in `p` is smaller than ``pi``, but larger than
+    `discont`, no unwrapping is done because taking the 2*pi complement
+    would only make the discontinuity larger.
+
+    Examples
+    --------
+    >>> phase = np.linspace(0, np.pi, num=5)
+    >>> phase[3:] += np.pi
+    >>> phase
+    array([ 0.        ,  0.78539816,  1.57079633,  5.49778714,  6.28318531])
+    >>> np.unwrap(phase)
+    array([ 0.        ,  0.78539816,  1.57079633, -0.78539816,  0.        ])
+
+    """
+    p = asarray(p)
+    nd = len(p.shape)
+    dd = diff(p, axis=axis)
+    slice1 = [slice(None, None)]*nd     # full slices
+    slice1[axis] = slice(1, None)
+    ddmod = mod(dd + pi, 2*pi) - pi
+    _nx.copyto(ddmod, pi, where=(ddmod == -pi) & (dd > 0))
+    ph_correct = ddmod - dd
+    _nx.copyto(ph_correct, 0, where=abs(dd) < discont)
+    up = array(p, copy=True, dtype='d')
+    up[slice1] = p[slice1] + ph_correct.cumsum(axis)
+    return up
+
+
+def sort_complex(a):
+    """
+    Sort a complex array using the real part first, then the imaginary part.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+
+    Returns
+    -------
+    out : complex ndarray
+        Always returns a sorted complex array.
+
+    Examples
+    --------
+    >>> np.sort_complex([5, 3, 6, 2, 1])
+    array([ 1.+0.j,  2.+0.j,  3.+0.j,  5.+0.j,  6.+0.j])
+
+    >>> np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
+    array([ 1.+2.j,  2.-1.j,  3.-3.j,  3.-2.j,  3.+5.j])
+
+    """
+    b = array(a, copy=True)
+    b.sort()
+    if not issubclass(b.dtype.type, _nx.complexfloating):
+        if b.dtype.char in 'bhBH':
+            return b.astype('F')
+        elif b.dtype.char == 'g':
+            return b.astype('G')
+        else:
+            return b.astype('D')
+    else:
+        return b
+
+
+def trim_zeros(filt, trim='fb'):
+    """
+    Trim the leading and/or trailing zeros from a 1-D array or sequence.
+
+    Parameters
+    ----------
+    filt : 1-D array or sequence
+        Input array.
+    trim : str, optional
+        A string with 'f' representing trim from front and 'b' to trim from
+        back. Default is 'fb', trim zeros from both front and back of the
+        array.
+
+    Returns
+    -------
+    trimmed : 1-D array or sequence
+        The result of trimming the input. The input data type is preserved.
+
+    Examples
+    --------
+    >>> a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))
+    >>> np.trim_zeros(a)
+    array([1, 2, 3, 0, 2, 1])
+
+    >>> np.trim_zeros(a, 'b')
+    array([0, 0, 0, 1, 2, 3, 0, 2, 1])
+
+    The input data type is preserved, list/tuple in means list/tuple out.
+
+    >>> np.trim_zeros([0, 1, 2, 0])
+    [1, 2]
+
+    """
+    first = 0
+    trim = trim.upper()
+    if 'F' in trim:
+        for i in filt:
+            if i != 0.:
+                break
+            else:
+                first = first + 1
+    last = len(filt)
+    if 'B' in trim:
+        for i in filt[::-1]:
+            if i != 0.:
+                break
+            else:
+                last = last - 1
+    return filt[first:last]
+
+
+@deprecate
+def unique(x):
+    """
+    This function is deprecated.  Use numpy.lib.arraysetops.unique()
+    instead.
+    """
+    try:
+        tmp = x.flatten()
+        if tmp.size == 0:
+            return tmp
+        tmp.sort()
+        idx = concatenate(([True], tmp[1:] != tmp[:-1]))
+        return tmp[idx]
+    except AttributeError:
+        items = sorted(set(x))
+        return asarray(items)
+
+
+def extract(condition, arr):
+    """
+    Return the elements of an array that satisfy some condition.
+
+    This is equivalent to ``np.compress(ravel(condition), ravel(arr))``.  If
+    `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``.
+
+    Note that `place` does the exact opposite of `extract`.
+
+    Parameters
+    ----------
+    condition : array_like
+        An array whose nonzero or True entries indicate the elements of `arr`
+        to extract.
+    arr : array_like
+        Input array of the same size as `condition`.
+
+    Returns
+    -------
+    extract : ndarray
+        Rank 1 array of values from `arr` where `condition` is True.
+
+    See Also
+    --------
+    take, put, copyto, compress, place
+
+    Examples
+    --------
+    >>> arr = np.arange(12).reshape((3, 4))
+    >>> arr
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11]])
+    >>> condition = np.mod(arr, 3)==0
+    >>> condition
+    array([[ True, False, False,  True],
+           [False, False,  True, False],
+           [False,  True, False, False]], dtype=bool)
+    >>> np.extract(condition, arr)
+    array([0, 3, 6, 9])
+
+
+    If `condition` is boolean:
+
+    >>> arr[condition]
+    array([0, 3, 6, 9])
+
+    """
+    return _nx.take(ravel(arr), nonzero(ravel(condition))[0])
+
+
+def place(arr, mask, vals):
+    """
+    Change elements of an array based on conditional and input values.
+
+    Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that
+    `place` uses the first N elements of `vals`, where N is the number of
+    True values in `mask`, while `copyto` uses the elements where `mask`
+    is True.
+
+    Note that `extract` does the exact opposite of `place`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Array to put data into.
+    mask : array_like
+        Boolean mask array. Must have the same size as `a`.
+    vals : 1-D sequence
+        Values to put into `a`. Only the first N elements are used, where
+        N is the number of True values in `mask`. If `vals` is smaller
+        than N it will be repeated.
+
+    See Also
+    --------
+    copyto, put, take, extract
+
+    Examples
+    --------
+    >>> arr = np.arange(6).reshape(2, 3)
+    >>> np.place(arr, arr>2, [44, 55])
+    >>> arr
+    array([[ 0,  1,  2],
+           [44, 55, 44]])
+
+    """
+    if not isinstance(arr, np.ndarray):
+        raise TypeError("argument 1 must be numpy.ndarray, "
+                        "not {name}".format(name=type(arr).__name__))
+
+    return _insert(arr, mask, vals)
+
+
+def disp(mesg, device=None, linefeed=True):
+    """
+    Display a message on a device.
+
+    Parameters
+    ----------
+    mesg : str
+        Message to display.
+    device : object
+        Device to write message. If None, defaults to ``sys.stdout`` which is
+        very similar to ``print``. `device` needs to have ``write()`` and
+        ``flush()`` methods.
+    linefeed : bool, optional
+        Option whether to print a line feed or not. Defaults to True.
+
+    Raises
+    ------
+    AttributeError
+        If `device` does not have a ``write()`` or ``flush()`` method.
+
+    Examples
+    --------
+    Besides ``sys.stdout``, a file-like object can also be used as it has
+    both required methods:
+
+    >>> from StringIO import StringIO
+    >>> buf = StringIO()
+    >>> np.disp('"Display" in a file', device=buf)
+    >>> buf.getvalue()
+    '"Display" in a file\\n'
+
+    """
+    if device is None:
+        device = sys.stdout
+    if linefeed:
+        device.write('%s\n' % mesg)
+    else:
+        device.write('%s' % mesg)
+    device.flush()
+    return
+
+
+class vectorize(object):
+    """
+    vectorize(pyfunc, otypes='', doc=None, excluded=None, cache=False)
+
+    Generalized function class.
+
+    Define a vectorized function which takes a nested sequence
+    of objects or numpy arrays as inputs and returns a
+    numpy array as output. The vectorized function evaluates `pyfunc` over
+    successive tuples of the input arrays like the python map function,
+    except it uses the broadcasting rules of numpy.
+
+    The data type of the output of `vectorized` is determined by calling
+    the function with the first element of the input.  This can be avoided
+    by specifying the `otypes` argument.
+
+    Parameters
+    ----------
+    pyfunc : callable
+        A python function or method.
+    otypes : str or list of dtypes, optional
+        The output data type. It must be specified as either a string of
+        typecode characters or a list of data type specifiers. There should
+        be one data type specifier for each output.
+    doc : str, optional
+        The docstring for the function. If `None`, the docstring will be the
+        ``pyfunc.__doc__``.
+    excluded : set, optional
+        Set of strings or integers representing the positional or keyword
+        arguments for which the function will not be vectorized.  These will be
+        passed directly to `pyfunc` unmodified.
+
+        .. versionadded:: 1.7.0
+
+    cache : bool, optional
+       If `True`, then cache the first function call that determines the number
+       of outputs if `otypes` is not provided.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    vectorized : callable
+        Vectorized function.
+
+    Examples
+    --------
+    >>> def myfunc(a, b):
+    ...     "Return a-b if a>b, otherwise return a+b"
+    ...     if a > b:
+    ...         return a - b
+    ...     else:
+    ...         return a + b
+
+    >>> vfunc = np.vectorize(myfunc)
+    >>> vfunc([1, 2, 3, 4], 2)
+    array([3, 4, 1, 2])
+
+    The docstring is taken from the input function to `vectorize` unless it
+    is specified
+
+    >>> vfunc.__doc__
+    'Return a-b if a>b, otherwise return a+b'
+    >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')
+    >>> vfunc.__doc__
+    'Vectorized `myfunc`'
+
+    The output type is determined by evaluating the first element of the input,
+    unless it is specified
+
+    >>> out = vfunc([1, 2, 3, 4], 2)
+    >>> type(out[0])
+    <type 'numpy.int32'>
+    >>> vfunc = np.vectorize(myfunc, otypes=[np.float])
+    >>> out = vfunc([1, 2, 3, 4], 2)
+    >>> type(out[0])
+    <type 'numpy.float64'>
+
+    The `excluded` argument can be used to prevent vectorizing over certain
+    arguments.  This can be useful for array-like arguments of a fixed length
+    such as the coefficients for a polynomial as in `polyval`:
+
+    >>> def mypolyval(p, x):
+    ...     _p = list(p)
+    ...     res = _p.pop(0)
+    ...     while _p:
+    ...         res = res*x + _p.pop(0)
+    ...     return res
+    >>> vpolyval = np.vectorize(mypolyval, excluded=['p'])
+    >>> vpolyval(p=[1, 2, 3], x=[0, 1])
+    array([3, 6])
+
+    Positional arguments may also be excluded by specifying their position:
+
+    >>> vpolyval.excluded.add(0)
+    >>> vpolyval([1, 2, 3], x=[0, 1])
+    array([3, 6])
+
+    Notes
+    -----
+    The `vectorize` function is provided primarily for convenience, not for
+    performance. The implementation is essentially a for loop.
+
+    If `otypes` is not specified, then a call to the function with the
+    first argument will be used to determine the number of outputs.  The
+    results of this call will be cached if `cache` is `True` to prevent
+    calling the function twice.  However, to implement the cache, the
+    original function must be wrapped which will slow down subsequent
+    calls, so only do this if your function is expensive.
+
+    The new keyword argument interface and `excluded` argument support
+    further degrades performance.
+
+    """
+
+    def __init__(self, pyfunc, otypes='', doc=None, excluded=None,
+                 cache=False):
+        self.pyfunc = pyfunc
+        self.cache = cache
+        self._ufunc = None    # Caching to improve default performance
+
+        if doc is None:
+            self.__doc__ = pyfunc.__doc__
+        else:
+            self.__doc__ = doc
+
+        if isinstance(otypes, str):
+            self.otypes = otypes
+            for char in self.otypes:
+                if char not in typecodes['All']:
+                    raise ValueError(
+                        "Invalid otype specified: %s" % (char,))
+        elif iterable(otypes):
+            self.otypes = ''.join([_nx.dtype(x).char for x in otypes])
+        else:
+            raise ValueError(
+                "Invalid otype specification")
+
+        # Excluded variable support
+        if excluded is None:
+            excluded = set()
+        self.excluded = set(excluded)
+
+    def __call__(self, *args, **kwargs):
+        """
+        Return arrays with the results of `pyfunc` broadcast (vectorized) over
+        `args` and `kwargs` not in `excluded`.
+        """
+        excluded = self.excluded
+        if not kwargs and not excluded:
+            func = self.pyfunc
+            vargs = args
+        else:
+            # The wrapper accepts only positional arguments: we use `names` and
+            # `inds` to mutate `the_args` and `kwargs` to pass to the original
+            # function.
+            nargs = len(args)
+
+            names = [_n for _n in kwargs if _n not in excluded]
+            inds = [_i for _i in range(nargs) if _i not in excluded]
+            the_args = list(args)
+
+            def func(*vargs):
+                for _n, _i in enumerate(inds):
+                    the_args[_i] = vargs[_n]
+                kwargs.update(zip(names, vargs[len(inds):]))
+                return self.pyfunc(*the_args, **kwargs)
+
+            vargs = [args[_i] for _i in inds]
+            vargs.extend([kwargs[_n] for _n in names])
+
+        return self._vectorize_call(func=func, args=vargs)
+
+    def _get_ufunc_and_otypes(self, func, args):
+        """Return (ufunc, otypes)."""
+        # frompyfunc will fail if args is empty
+        if not args:
+            raise ValueError('args can not be empty')
+
+        if self.otypes:
+            otypes = self.otypes
+            nout = len(otypes)
+
+            # Note logic here: We only *use* self._ufunc if func is self.pyfunc
+            # even though we set self._ufunc regardless.
+            if func is self.pyfunc and self._ufunc is not None:
+                ufunc = self._ufunc
+            else:
+                ufunc = self._ufunc = frompyfunc(func, len(args), nout)
+        else:
+            # Get number of outputs and output types by calling the function on
+            # the first entries of args.  We also cache the result to prevent
+            # the subsequent call when the ufunc is evaluated.
+            # Assumes that ufunc first evaluates the 0th elements in the input
+            # arrays (the input values are not checked to ensure this)
+            inputs = [asarray(_a).flat[0] for _a in args]
+            outputs = func(*inputs)
+
+            # Performance note: profiling indicates that -- for simple
+            # functions at least -- this wrapping can almost double the
+            # execution time.
+            # Hence we make it optional.
+            if self.cache:
+                _cache = [outputs]
+
+                def _func(*vargs):
+                    if _cache:
+                        return _cache.pop()
+                    else:
+                        return func(*vargs)
+            else:
+                _func = func
+
+            if isinstance(outputs, tuple):
+                nout = len(outputs)
+            else:
+                nout = 1
+                outputs = (outputs,)
+
+            otypes = ''.join([asarray(outputs[_k]).dtype.char
+                              for _k in range(nout)])
+
+            # Performance note: profiling indicates that creating the ufunc is
+            # not a significant cost compared with wrapping so it seems not
+            # worth trying to cache this.
+            ufunc = frompyfunc(_func, len(args), nout)
+
+        return ufunc, otypes
+
+    def _vectorize_call(self, func, args):
+        """Vectorized call to `func` over positional `args`."""
+        if not args:
+            _res = func()
+        else:
+            ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
+
+            # Convert args to object arrays first
+            inputs = [array(_a, copy=False, subok=True, dtype=object)
+                      for _a in args]
+
+            outputs = ufunc(*inputs)
+
+            if ufunc.nout == 1:
+                _res = array(outputs,
+                             copy=False, subok=True, dtype=otypes[0])
+            else:
+                _res = tuple([array(_x, copy=False, subok=True, dtype=_t)
+                              for _x, _t in zip(outputs, otypes)])
+        return _res
+
+
+def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None,
+        aweights=None):
+    """
+    Estimate a covariance matrix, given data and weights.
+
+    Covariance indicates the level to which two variables vary together.
+    If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`,
+    then the covariance matrix element :math:`C_{ij}` is the covariance of
+    :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance
+    of :math:`x_i`.
+
+    See the notes for an outline of the algorithm.
+
+    Parameters
+    ----------
+    m : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `m` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same form
+        as that of `m`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : bool, optional
+        Default normalization (False) is by ``(N - 1)``, where ``N`` is the
+        number of observations given (unbiased estimate). If `bias` is True, then
+        normalization is by ``N``. These values can be overridden by using the
+        keyword ``ddof`` in numpy versions >= 1.5.
+    ddof : int, optional
+        If not ``None`` the default value implied by `bias` is overridden.
+        Note that ``ddof=1`` will return the unbiased estimate, even if both
+        `fweights` and `aweights` are specified, and ``ddof=0`` will return
+        the simple average. See the notes for the details. The default value
+        is ``None``.
+
+        .. versionadded:: 1.5
+    fweights : array_like, int, optional
+        1-D array of integer freguency weights; the number of times each
+        observation vector should be repeated.
+
+        .. versionadded:: 1.10
+    aweights : array_like, optional
+        1-D array of observation vector weights. These relative weights are
+        typically large for observations considered "important" and smaller for
+        observations considered less "important". If ``ddof=0`` the array of
+        weights can be used to assign probabilities to observation vectors.
+
+        .. versionadded:: 1.10
+
+    Returns
+    -------
+    out : ndarray
+        The covariance matrix of the variables.
+
+    See Also
+    --------
+    corrcoef : Normalized covariance matrix
+
+    Notes
+    -----
+    Assume that the observations are in the columns of the observation
+    array `m` and let ``f = fweights`` and ``a = aweights`` for brevity. The
+    steps to compute the weighted covariance are as follows::
+
+        >>> w = f * a
+        >>> v1 = np.sum(w)
+        >>> v2 = np.sum(w * a)
+        >>> m -= np.sum(m * w, axis=1, keepdims=True) / v1
+        >>> cov = np.dot(m * w, m.T) * v1 / (v1**2 - ddof * v2)
+
+    Note that when ``a == 1``, the normalization factor
+    ``v1 / (v1**2 - ddof * v2)`` goes over to ``1 / (np.sum(f) - ddof)``
+    as it should.
+
+    Examples
+    --------
+    Consider two variables, :math:`x_0` and :math:`x_1`, which
+    correlate perfectly, but in opposite directions:
+
+    >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T
+    >>> x
+    array([[0, 1, 2],
+           [2, 1, 0]])
+
+    Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance
+    matrix shows this clearly:
+
+    >>> np.cov(x)
+    array([[ 1., -1.],
+           [-1.,  1.]])
+
+    Note that element :math:`C_{0,1}`, which shows the correlation between
+    :math:`x_0` and :math:`x_1`, is negative.
+
+    Further, note how `x` and `y` are combined:
+
+    >>> x = [-2.1, -1,  4.3]
+    >>> y = [3,  1.1,  0.12]
+    >>> X = np.vstack((x,y))
+    >>> print(np.cov(X))
+    [[ 11.71        -4.286     ]
+     [ -4.286        2.14413333]]
+    >>> print(np.cov(x, y))
+    [[ 11.71        -4.286     ]
+     [ -4.286        2.14413333]]
+    >>> print(np.cov(x))
+    11.71
+
+    """
+    # Check inputs
+    if ddof is not None and ddof != int(ddof):
+        raise ValueError(
+            "ddof must be integer")
+
+    # Handles complex arrays too
+    m = np.asarray(m)
+    if y is None:
+        dtype = np.result_type(m, np.float64)
+    else:
+        y = np.asarray(y)
+        dtype = np.result_type(m, y, np.float64)
+    X = array(m, ndmin=2, dtype=dtype)
+    if rowvar == 0 and X.shape[0] != 1:
+        X = X.T
+    if X.shape[0] == 0:
+        return np.array([]).reshape(0, 0)
+    if y is not None:
+        y = array(y, copy=False, ndmin=2, dtype=dtype)
+        if rowvar == 0 and y.shape[0] != 1:
+            y = y.T
+        X = np.vstack((X, y))
+
+    if ddof is None:
+        if bias == 0:
+            ddof = 1
+        else:
+            ddof = 0
+
+    # Get the product of frequencies and weights
+    w = None
+    if fweights is not None:
+        fweights = np.asarray(fweights, dtype=np.float)
+        if not np.all(fweights == np.around(fweights)):
+            raise TypeError(
+                "fweights must be integer")
+        if fweights.ndim > 1:
+            raise RuntimeError(
+                "cannot handle multidimensional fweights")
+        if fweights.shape[0] != X.shape[1]:
+            raise RuntimeError(
+                "incompatible numbers of samples and fweights")
+        if any(fweights < 0):
+            raise ValueError(
+                "fweights cannot be negative")
+        w = fweights
+    if aweights is not None:
+        aweights = np.asarray(aweights, dtype=np.float)
+        if aweights.ndim > 1:
+            raise RuntimeError(
+                "cannot handle multidimensional aweights")
+        if aweights.shape[0] != X.shape[1]:
+            raise RuntimeError(
+                "incompatible numbers of samples and aweights")
+        if any(aweights < 0):
+            raise ValueError(
+                "aweights cannot be negative")
+        if w is None:
+            w = aweights
+        else:
+            w *= aweights
+
+    avg, w_sum = average(X, axis=1, weights=w, returned=True)
+    w_sum = w_sum[0]
+
+    # Determine the normalization
+    if w is None:
+        fact = X.shape[1] - ddof
+    elif ddof == 0:
+        fact = w_sum
+    elif aweights is None:
+        fact = w_sum - ddof
+    else:
+        fact = w_sum - ddof*sum(w*aweights)/w_sum
+
+    if fact <= 0:
+        warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
+        fact = 0.0
+
+    X -= avg[:, None]
+    if w is None:
+        X_T = X.T
+    else:
+        X_T = (X*w).T
+    c = dot(X, X_T.conj())
+    c *= 1. / np.float64(fact)
+    return c.squeeze()
+
+
+def corrcoef(x, y=None, rowvar=1, bias=np._NoValue, ddof=np._NoValue):
+    """
+    Return Pearson product-moment correlation coefficients.
+
+    Please refer to the documentation for `cov` for more detail.  The
+    relationship between the correlation coefficient matrix, `R`, and the
+    covariance matrix, `C`, is
+
+    .. math:: R_{ij} = \\frac{ C_{ij} } { \\sqrt{ C_{ii} * C_{jj} } }
+
+    The values of `R` are between -1 and 1, inclusive.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        shape as `x`.
+    rowvar : int, optional
+        If `rowvar` is non-zero (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+    ddof : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+
+    Returns
+    -------
+    R : ndarray
+        The correlation coefficient matrix of the variables.
+
+    See Also
+    --------
+    cov : Covariance matrix
+
+    Notes
+    -----
+    Due to floating point rounding the resulting array may not be Hermitian,
+    the diagonal elements may not be 1, and the elements may not satisfy the
+    inequality abs(a) <= 1. The real and imaginary parts are clipped to the
+    interval [-1,  1] in an attempt to improve on that situation but is not
+    much help in the complex case.
+
+    This function accepts but discards arguments `bias` and `ddof`.  This is
+    for backwards compatibility with previous versions of this function.  These
+    arguments had no effect on the return values of the function and can be
+    safely ignored in this and previous versions of numpy.
+    """
+    if bias is not np._NoValue or ddof is not np._NoValue:
+        # 2015-03-15, 1.10
+        warnings.warn('bias and ddof have no effect and are deprecated',
+                      DeprecationWarning)
+    c = cov(x, y, rowvar)
+    try:
+        d = diag(c)
+    except ValueError:
+        # scalar covariance
+        # nan if incorrect value (nan, inf, 0), 1 otherwise
+        return c / c
+    stddev = sqrt(d.real)
+    c /= stddev[:, None]
+    c /= stddev[None, :]
+
+    # Clip real and imaginary parts to [-1, 1].  This does not guarantee
+    # abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without
+    # excessive work.
+    np.clip(c.real, -1, 1, out=c.real)
+    if np.iscomplexobj(c):
+        np.clip(c.imag, -1, 1, out=c.imag)
+
+    return c
+
+
+def blackman(M):
+    """
+    Return the Blackman window.
+
+    The Blackman window is a taper formed by using the first three
+    terms of a summation of cosines. It was designed to have close to the
+    minimal leakage possible.  It is close to optimal, only slightly worse
+    than a Kaiser window.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an empty
+        array is returned.
+
+    Returns
+    -------
+    out : ndarray
+        The window, with the maximum value normalized to one (the value one
+        appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, hamming, hanning, kaiser
+
+    Notes
+    -----
+    The Blackman window is defined as
+
+    .. math::  w(n) = 0.42 - 0.5 \\cos(2\\pi n/M) + 0.08 \\cos(4\\pi n/M)
+
+    Most references to the Blackman window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function. It is known as a
+    "near optimal" tapering function, almost as good (by some measures)
+    as the kaiser window.
+
+    References
+    ----------
+    Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra,
+    Dover Publications, New York.
+
+    Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing.
+    Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471.
+
+    Examples
+    --------
+    >>> np.blackman(12)
+    array([ -1.38777878e-17,   3.26064346e-02,   1.59903635e-01,
+             4.14397981e-01,   7.36045180e-01,   9.67046769e-01,
+             9.67046769e-01,   7.36045180e-01,   4.14397981e-01,
+             1.59903635e-01,   3.26064346e-02,  -1.38777878e-17])
+
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.blackman(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Blackman window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Blackman window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.42 - 0.5*cos(2.0*pi*n/(M-1)) + 0.08*cos(4.0*pi*n/(M-1))
+
+
+def bartlett(M):
+    """
+    Return the Bartlett window.
+
+    The Bartlett window is very similar to a triangular window, except
+    that the end points are at zero.  It is often used in signal
+    processing for tapering a signal, without generating too much
+    ripple in the frequency domain.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : array
+        The triangular window, with the maximum value normalized to one
+        (the value one appears only if the number of samples is odd), with
+        the first and last samples equal to zero.
+
+    See Also
+    --------
+    blackman, hamming, hanning, kaiser
+
+    Notes
+    -----
+    The Bartlett window is defined as
+
+    .. math:: w(n) = \\frac{2}{M-1} \\left(
+              \\frac{M-1}{2} - \\left|n - \\frac{M-1}{2}\\right|
+              \\right)
+
+    Most references to the Bartlett window come from the signal
+    processing literature, where it is used as one of many windowing
+    functions for smoothing values.  Note that convolution with this
+    window produces linear interpolation.  It is also known as an
+    apodization (which means"removing the foot", i.e. smoothing
+    discontinuities at the beginning and end of the sampled signal) or
+    tapering function. The fourier transform of the Bartlett is the product
+    of two sinc functions.
+    Note the excellent discussion in Kanasewich.
+
+    References
+    ----------
+    .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
+           Biometrika 37, 1-16, 1950.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
+           The University of Alberta Press, 1975, pp. 109-110.
+    .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal
+           Processing", Prentice-Hall, 1999, pp. 468-471.
+    .. [4] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [5] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 429.
+
+
+    Examples
+    --------
+    >>> np.bartlett(12)
+    array([ 0.        ,  0.18181818,  0.36363636,  0.54545455,  0.72727273,
+            0.90909091,  0.90909091,  0.72727273,  0.54545455,  0.36363636,
+            0.18181818,  0.        ])
+
+    Plot the window and its frequency response (requires SciPy and matplotlib):
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.bartlett(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Bartlett window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Bartlett window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return where(less_equal(n, (M-1)/2.0), 2.0*n/(M-1), 2.0 - 2.0*n/(M-1))
+
+
+def hanning(M):
+    """
+    Return the Hanning window.
+
+    The Hanning window is a taper formed by using a weighted cosine.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : ndarray, shape(M,)
+        The window, with the maximum value normalized to one (the value
+        one appears only if `M` is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hamming, kaiser
+
+    Notes
+    -----
+    The Hanning window is defined as
+
+    .. math::  w(n) = 0.5 - 0.5cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
+               \\qquad 0 \\leq n \\leq M-1
+
+    The Hanning was named for Julius von Hann, an Austrian meteorologist.
+    It is also known as the Cosine Bell. Some authors prefer that it be
+    called a Hann window, to help avoid confusion with the very similar
+    Hamming window.
+
+    Most references to the Hanning window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
+           spectra, Dover Publications, New York.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
+           The University of Alberta Press, 1975, pp. 106-108.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [4] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 425.
+
+    Examples
+    --------
+    >>> np.hanning(12)
+    array([ 0.        ,  0.07937323,  0.29229249,  0.57115742,  0.82743037,
+            0.97974649,  0.97974649,  0.82743037,  0.57115742,  0.29229249,
+            0.07937323,  0.        ])
+
+    Plot the window and its frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.hanning(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Hann window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of the Hann window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.5 - 0.5*cos(2.0*pi*n/(M-1))
+
+
+def hamming(M):
+    """
+    Return the Hamming window.
+
+    The Hamming window is a taper formed by using a weighted cosine.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : ndarray
+        The window, with the maximum value normalized to one (the value
+        one appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hanning, kaiser
+
+    Notes
+    -----
+    The Hamming window is defined as
+
+    .. math::  w(n) = 0.54 - 0.46cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
+               \\qquad 0 \\leq n \\leq M-1
+
+    The Hamming was named for R. W. Hamming, an associate of J. W. Tukey
+    and is described in Blackman and Tukey. It was recommended for
+    smoothing the truncated autocovariance function in the time domain.
+    Most references to the Hamming window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
+           spectra, Dover Publications, New York.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
+           University of Alberta Press, 1975, pp. 109-110.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [4] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 425.
+
+    Examples
+    --------
+    >>> np.hamming(12)
+    array([ 0.08      ,  0.15302337,  0.34890909,  0.60546483,  0.84123594,
+            0.98136677,  0.98136677,  0.84123594,  0.60546483,  0.34890909,
+            0.15302337,  0.08      ])
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.hamming(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Hamming window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Hamming window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.54 - 0.46*cos(2.0*pi*n/(M-1))
+
+## Code from cephes for i0
+
+_i0A = [
+    -4.41534164647933937950E-18,
+    3.33079451882223809783E-17,
+    -2.43127984654795469359E-16,
+    1.71539128555513303061E-15,
+    -1.16853328779934516808E-14,
+    7.67618549860493561688E-14,
+    -4.85644678311192946090E-13,
+    2.95505266312963983461E-12,
+    -1.72682629144155570723E-11,
+    9.67580903537323691224E-11,
+    -5.18979560163526290666E-10,
+    2.65982372468238665035E-9,
+    -1.30002500998624804212E-8,
+    6.04699502254191894932E-8,
+    -2.67079385394061173391E-7,
+    1.11738753912010371815E-6,
+    -4.41673835845875056359E-6,
+    1.64484480707288970893E-5,
+    -5.75419501008210370398E-5,
+    1.88502885095841655729E-4,
+    -5.76375574538582365885E-4,
+    1.63947561694133579842E-3,
+    -4.32430999505057594430E-3,
+    1.05464603945949983183E-2,
+    -2.37374148058994688156E-2,
+    4.93052842396707084878E-2,
+    -9.49010970480476444210E-2,
+    1.71620901522208775349E-1,
+    -3.04682672343198398683E-1,
+    6.76795274409476084995E-1
+    ]
+
+_i0B = [
+    -7.23318048787475395456E-18,
+    -4.83050448594418207126E-18,
+    4.46562142029675999901E-17,
+    3.46122286769746109310E-17,
+    -2.82762398051658348494E-16,
+    -3.42548561967721913462E-16,
+    1.77256013305652638360E-15,
+    3.81168066935262242075E-15,
+    -9.55484669882830764870E-15,
+    -4.15056934728722208663E-14,
+    1.54008621752140982691E-14,
+    3.85277838274214270114E-13,
+    7.18012445138366623367E-13,
+    -1.79417853150680611778E-12,
+    -1.32158118404477131188E-11,
+    -3.14991652796324136454E-11,
+    1.18891471078464383424E-11,
+    4.94060238822496958910E-10,
+    3.39623202570838634515E-9,
+    2.26666899049817806459E-8,
+    2.04891858946906374183E-7,
+    2.89137052083475648297E-6,
+    6.88975834691682398426E-5,
+    3.36911647825569408990E-3,
+    8.04490411014108831608E-1
+    ]
+
+
+def _chbevl(x, vals):
+    b0 = vals[0]
+    b1 = 0.0
+
+    for i in range(1, len(vals)):
+        b2 = b1
+        b1 = b0
+        b0 = x*b1 - b2 + vals[i]
+
+    return 0.5*(b0 - b2)
+
+
+def _i0_1(x):
+    return exp(x) * _chbevl(x/2.0-2, _i0A)
+
+
+def _i0_2(x):
+    return exp(x) * _chbevl(32.0/x - 2.0, _i0B) / sqrt(x)
+
+
+def i0(x):
+    """
+    Modified Bessel function of the first kind, order 0.
+
+    Usually denoted :math:`I_0`.  This function does broadcast, but will *not*
+    "up-cast" int dtype arguments unless accompanied by at least one float or
+    complex dtype argument (see Raises below).
+
+    Parameters
+    ----------
+    x : array_like, dtype float or complex
+        Argument of the Bessel function.
+
+    Returns
+    -------
+    out : ndarray, shape = x.shape, dtype = x.dtype
+        The modified Bessel function evaluated at each of the elements of `x`.
+
+    Raises
+    ------
+    TypeError: array cannot be safely cast to required type
+        If argument consists exclusively of int dtypes.
+
+    See Also
+    --------
+    scipy.special.iv, scipy.special.ive
+
+    Notes
+    -----
+    We use the algorithm published by Clenshaw [1]_ and referenced by
+    Abramowitz and Stegun [2]_, for which the function domain is
+    partitioned into the two intervals [0,8] and (8,inf), and Chebyshev
+    polynomial expansions are employed in each interval. Relative error on
+    the domain [0,30] using IEEE arithmetic is documented [3]_ as having a
+    peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000).
+
+    References
+    ----------
+    .. [1] C. W. Clenshaw, "Chebyshev series for mathematical functions", in
+           *National Physical Laboratory Mathematical Tables*, vol. 5, London:
+           Her Majesty's Stationery Office, 1962.
+    .. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical
+           Functions*, 10th printing, New York: Dover, 1964, pp. 379.
+           http://www.math.sfu.ca/~cbm/aands/page_379.htm
+    .. [3] http://kobesearch.cpan.org/htdocs/Math-Cephes/Math/Cephes.html
+
+    Examples
+    --------
+    >>> np.i0([0.])
+    array(1.0)
+    >>> np.i0([0., 1. + 2j])
+    array([ 1.00000000+0.j        ,  0.18785373+0.64616944j])
+
+    """
+    x = atleast_1d(x).copy()
+    y = empty_like(x)
+    ind = (x < 0)
+    x[ind] = -x[ind]
+    ind = (x <= 8.0)
+    y[ind] = _i0_1(x[ind])
+    ind2 = ~ind
+    y[ind2] = _i0_2(x[ind2])
+    return y.squeeze()
+
+## End of cephes code for i0
+
+
+def kaiser(M, beta):
+    """
+    Return the Kaiser window.
+
+    The Kaiser window is a taper formed by using a Bessel function.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+    beta : float
+        Shape parameter for window.
+
+    Returns
+    -------
+    out : array
+        The window, with the maximum value normalized to one (the value
+        one appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hamming, hanning
+
+    Notes
+    -----
+    The Kaiser window is defined as
+
+    .. math::  w(n) = I_0\\left( \\beta \\sqrt{1-\\frac{4n^2}{(M-1)^2}}
+               \\right)/I_0(\\beta)
+
+    with
+
+    .. math:: \\quad -\\frac{M-1}{2} \\leq n \\leq \\frac{M-1}{2},
+
+    where :math:`I_0` is the modified zeroth-order Bessel function.
+
+    The Kaiser was named for Jim Kaiser, who discovered a simple
+    approximation to the DPSS window based on Bessel functions.  The Kaiser
+    window is a very good approximation to the Digital Prolate Spheroidal
+    Sequence, or Slepian window, which is the transform which maximizes the
+    energy in the main lobe of the window relative to total energy.
+
+    The Kaiser can approximate many other windows by varying the beta
+    parameter.
+
+    ====  =======================
+    beta  Window shape
+    ====  =======================
+    0     Rectangular
+    5     Similar to a Hamming
+    6     Similar to a Hanning
+    8.6   Similar to a Blackman
+    ====  =======================
+
+    A beta value of 14 is probably a good starting point. Note that as beta
+    gets large, the window narrows, and so the number of samples needs to be
+    large enough to sample the increasingly narrow spike, otherwise NaNs will
+    get returned.
+
+    Most references to the Kaiser window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by
+           digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285.
+           John Wiley and Sons, New York, (1966).
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
+           University of Alberta Press, 1975, pp. 177-178.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+
+    Examples
+    --------
+    >>> np.kaiser(12, 14)
+    array([  7.72686684e-06,   3.46009194e-03,   4.65200189e-02,
+             2.29737120e-01,   5.99885316e-01,   9.45674898e-01,
+             9.45674898e-01,   5.99885316e-01,   2.29737120e-01,
+             4.65200189e-02,   3.46009194e-03,   7.72686684e-06])
+
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.kaiser(51, 14)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Kaiser window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Kaiser window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    from numpy.dual import i0
+    if M == 1:
+        return np.array([1.])
+    n = arange(0, M)
+    alpha = (M-1)/2.0
+    return i0(beta * sqrt(1-((n-alpha)/alpha)**2.0))/i0(float(beta))
+
+
+def sinc(x):
+    """
+    Return the sinc function.
+
+    The sinc function is :math:`\\sin(\\pi x)/(\\pi x)`.
+
+    Parameters
+    ----------
+    x : ndarray
+        Array (possibly multi-dimensional) of values for which to to
+        calculate ``sinc(x)``.
+
+    Returns
+    -------
+    out : ndarray
+        ``sinc(x)``, which has the same shape as the input.
+
+    Notes
+    -----
+    ``sinc(0)`` is the limit value 1.
+
+    The name sinc is short for "sine cardinal" or "sinus cardinalis".
+
+    The sinc function is used in various signal processing applications,
+    including in anti-aliasing, in the construction of a Lanczos resampling
+    filter, and in interpolation.
+
+    For bandlimited interpolation of discrete-time signals, the ideal
+    interpolation kernel is proportional to the sinc function.
+
+    References
+    ----------
+    .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
+           Resource. http://mathworld.wolfram.com/SincFunction.html
+    .. [2] Wikipedia, "Sinc function",
+           http://en.wikipedia.org/wiki/Sinc_function
+
+    Examples
+    --------
+    >>> x = np.linspace(-4, 4, 41)
+    >>> np.sinc(x)
+    array([ -3.89804309e-17,  -4.92362781e-02,  -8.40918587e-02,
+            -8.90384387e-02,  -5.84680802e-02,   3.89804309e-17,
+             6.68206631e-02,   1.16434881e-01,   1.26137788e-01,
+             8.50444803e-02,  -3.89804309e-17,  -1.03943254e-01,
+            -1.89206682e-01,  -2.16236208e-01,  -1.55914881e-01,
+             3.89804309e-17,   2.33872321e-01,   5.04551152e-01,
+             7.56826729e-01,   9.35489284e-01,   1.00000000e+00,
+             9.35489284e-01,   7.56826729e-01,   5.04551152e-01,
+             2.33872321e-01,   3.89804309e-17,  -1.55914881e-01,
+            -2.16236208e-01,  -1.89206682e-01,  -1.03943254e-01,
+            -3.89804309e-17,   8.50444803e-02,   1.26137788e-01,
+             1.16434881e-01,   6.68206631e-02,   3.89804309e-17,
+            -5.84680802e-02,  -8.90384387e-02,  -8.40918587e-02,
+            -4.92362781e-02,  -3.89804309e-17])
+
+    >>> plt.plot(x, np.sinc(x))
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Sinc Function")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("X")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    It works in 2-D as well:
+
+    >>> x = np.linspace(-4, 4, 401)
+    >>> xx = np.outer(x, x)
+    >>> plt.imshow(np.sinc(xx))
+    <matplotlib.image.AxesImage object at 0x...>
+
+    """
+    x = np.asanyarray(x)
+    y = pi * where(x == 0, 1.0e-20, x)
+    return sin(y)/y
+
+
+def msort(a):
+    """
+    Return a copy of an array sorted along the first axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+
+    Returns
+    -------
+    sorted_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    sort
+
+    Notes
+    -----
+    ``np.msort(a)`` is equivalent to  ``np.sort(a, axis=0)``.
+
+    """
+    b = array(a, subok=True, copy=True)
+    b.sort(0)
+    return b
+
+
+def _ureduce(a, func, **kwargs):
+    """
+    Internal Function.
+    Call `func` with `a` as first argument swapping the axes to use extended
+    axis on functions that don't support it natively.
+
+    Returns result and a.shape with axis dims set to 1.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    func : callable
+        Reduction function Kapable of receiving an axis argument.
+        It is is called with `a` as first argument followed by `kwargs`.
+     kwargs : keyword arguments
+        additional keyword arguments to pass to `func`.
+
+    Returns
+    -------
+    result : tuple
+        Result of func(a, **kwargs) and a.shape with axis dims set to 1
+        which can be used to reshape the result to the same shape a ufunc with
+        keepdims=True would produce.
+
+    """
+    a = np.asanyarray(a)
+    axis = kwargs.get('axis', None)
+    if axis is not None:
+        keepdim = list(a.shape)
+        nd = a.ndim
+        try:
+            axis = operator.index(axis)
+            if axis >= nd or axis < -nd:
+                raise IndexError("axis %d out of bounds (%d)" % (axis, a.ndim))
+            keepdim[axis] = 1
+        except TypeError:
+            sax = set()
+            for x in axis:
+                if x >= nd or x < -nd:
+                    raise IndexError("axis %d out of bounds (%d)" % (x, nd))
+                if x in sax:
+                    raise ValueError("duplicate value in axis")
+                sax.add(x % nd)
+                keepdim[x] = 1
+            keep = sax.symmetric_difference(frozenset(range(nd)))
+            nkeep = len(keep)
+            # swap axis that should not be reduced to front
+            for i, s in enumerate(sorted(keep)):
+                a = a.swapaxes(i, s)
+            # merge reduced axis
+            a = a.reshape(a.shape[:nkeep] + (-1,))
+            kwargs['axis'] = -1
+    else:
+        keepdim = [1] * a.ndim
+
+    r = func(a, **kwargs)
+    return r, keepdim
+
+
+def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
+    """
+    Compute the median along the specified axis.
+
+    Returns the median of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the medians are computed. The default
+        is to compute the median along a flattened version of the array.
+        A sequence of axes is supported since version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+       If True, then allow use of memory of input array `a` for
+       calculations. The input array will be modified by the call to
+       `median`. This will save memory when you do not need to preserve
+       the contents of the input array. Treat the input as undefined,
+       but it will probably be fully or partially sorted. Default is
+       False. If `overwrite_input` is ``True`` and `a` is not already an
+       `ndarray`, an error will be raised.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result. If the input contains integers
+        or floats smaller than ``float64``, then the output data-type is
+        ``np.float64``.  Otherwise, the data-type of the output is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, percentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the median of ``V`` is the
+    middle value of a sorted copy of ``V``, ``V_sorted`` - i
+    e., ``V_sorted[(N-1)/2]``, when ``N`` is odd, and the average of the
+    two middle values of ``V_sorted`` when ``N`` is even.
+
+    Examples
+    --------
+    >>> a = np.array([[10, 7, 4], [3, 2, 1]])
+    >>> a
+    array([[10,  7,  4],
+           [ 3,  2,  1]])
+    >>> np.median(a)
+    3.5
+    >>> np.median(a, axis=0)
+    array([ 6.5,  4.5,  2.5])
+    >>> np.median(a, axis=1)
+    array([ 7.,  2.])
+    >>> m = np.median(a, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.median(a, axis=0, out=m)
+    array([ 6.5,  4.5,  2.5])
+    >>> m
+    array([ 6.5,  4.5,  2.5])
+    >>> b = a.copy()
+    >>> np.median(b, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a==b)
+    >>> b = a.copy()
+    >>> np.median(b, axis=None, overwrite_input=True)
+    3.5
+    >>> assert not np.all(a==b)
+
+    """
+    r, k = _ureduce(a, func=_median, axis=axis, out=out,
+                    overwrite_input=overwrite_input)
+    if keepdims:
+        return r.reshape(k)
+    else:
+        return r
+
+def _median(a, axis=None, out=None, overwrite_input=False):
+    # can't be reasonably be implemented in terms of percentile as we have to
+    # call mean to not break astropy
+    a = np.asanyarray(a)
+
+    # Set the partition indexes
+    if axis is None:
+        sz = a.size
+    else:
+        sz = a.shape[axis]
+    if sz % 2 == 0:
+        szh = sz // 2
+        kth = [szh - 1, szh]
+    else:
+        kth = [(sz - 1) // 2]
+    # Check if the array contains any nan's
+    if np.issubdtype(a.dtype, np.inexact):
+        kth.append(-1)
+
+    if overwrite_input:
+        if axis is None:
+            part = a.ravel()
+            part.partition(kth)
+        else:
+            a.partition(kth, axis=axis)
+            part = a
+    else:
+        part = partition(a, kth, axis=axis)
+
+    if part.shape == ():
+        # make 0-D arrays work
+        return part.item()
+    if axis is None:
+        axis = 0
+
+    indexer = [slice(None)] * part.ndim
+    index = part.shape[axis] // 2
+    if part.shape[axis] % 2 == 1:
+        # index with slice to allow mean (below) to work
+        indexer[axis] = slice(index, index+1)
+    else:
+        indexer[axis] = slice(index-1, index+1)
+
+    # Check if the array contains any nan's
+    if np.issubdtype(a.dtype, np.inexact) and sz > 0:
+        # warn and return nans like mean would
+        rout = mean(part[indexer], axis=axis, out=out)
+        part = np.rollaxis(part, axis, part.ndim)
+        n = np.isnan(part[..., -1])
+        if rout.ndim == 0:
+            if n == True:
+                warnings.warn("Invalid value encountered in median",
+                              RuntimeWarning)
+                if out is not None:
+                    out[...] = a.dtype.type(np.nan)
+                    rout = out
+                else:
+                    rout = a.dtype.type(np.nan)
+        elif np.count_nonzero(n.ravel()) > 0:
+            warnings.warn("Invalid value encountered in median for" +
+                          " %d results" % np.count_nonzero(n.ravel()),
+                          RuntimeWarning)
+            rout[n] = np.nan
+        return rout
+    else:
+        # if there are no nans
+        # Use mean in odd and even case to coerce data type
+        # and check, use out array.
+        return mean(part[indexer], axis=axis, out=out)
+
+
+def percentile(a, q, axis=None, out=None,
+               overwrite_input=False, interpolation='linear', keepdims=False):
+    """
+    Compute the qth percentile of the data along the specified axis.
+
+    Returns the qth percentile(s) of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    q : float in range of [0,100] (or sequence of floats)
+        Percentile to compute, which must be between 0 and 100 inclusive.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the percentiles are computed. The
+        default is to compute the percentile(s) along a flattened
+        version of the array. A sequence of axes is supported since
+        version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array `a` 
+        calculations. The input array will be modified by the call to
+        `percentile`. This will save memory when you do not need to
+        preserve the contents of the input array. In this case you
+        should not make any assumptions about the contents of the input
+        `a` after this function completes -- treat it as undefined.
+        Default is False. If `a` is not already an array, this parameter
+        will have no effect as `a` will be converted to an array
+        internally regardless of the value of this parameter.
+    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``.
+
+        .. versionadded:: 1.9.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original array `a`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    percentile : scalar or ndarray
+        If `q` is a single percentile and `axis=None`, then the result
+        is a scalar. If multiple percentiles are given, first axis of
+        the result corresponds to the percentiles. The other axes are
+        the axes that remain after the reduction of `a`. If the input 
+        contains integers or floats smaller than ``float64``, the output
+        data-type is ``float64``. Otherwise, the output data-type is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, median, nanpercentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the ``q``-th percentile of
+    ``V`` is the value ``q/100`` of the way from the mimumum to the
+    maximum in in a sorted copy of ``V``. The values and distances of
+    the two nearest neighbors as well as the `interpolation` parameter
+    will determine the percentile if the normalized ranking does not
+    match the location of ``q`` exactly. This function is the same as
+    the median if ``q=50``, the same as the minimum if ``q=0`` and the
+    same as the maximum if ``q=100``.
+
+    Examples
+    --------
+    >>> a = np.array([[10, 7, 4], [3, 2, 1]])
+    >>> a
+    array([[10,  7,  4],
+           [ 3,  2,  1]])
+    >>> np.percentile(a, 50)
+    3.5
+    >>> np.percentile(a, 50, axis=0)
+    array([[ 6.5,  4.5,  2.5]])
+    >>> np.percentile(a, 50, axis=1)
+    array([ 7.,  2.])
+    >>> np.percentile(a, 50, axis=1, keepdims=True)
+    array([[ 7.],
+           [ 2.]])
+
+    >>> m = np.percentile(a, 50, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.percentile(a, 50, axis=0, out=out)
+    array([[ 6.5,  4.5,  2.5]])
+    >>> m
+    array([[ 6.5,  4.5,  2.5]])
+
+    >>> b = a.copy()
+    >>> np.percentile(b, 50, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a == b)
+
+    """
+    q = array(q, dtype=np.float64, copy=True)
+    r, k = _ureduce(a, func=_percentile, q=q, axis=axis, out=out,
+                    overwrite_input=overwrite_input,
+                    interpolation=interpolation)
+    if keepdims:
+        if q.ndim == 0:
+            return r.reshape(k)
+        else:
+            return r.reshape([len(q)] + k)
+    else:
+        return r
+
+
+def _percentile(a, q, axis=None, out=None,
+                overwrite_input=False, interpolation='linear', keepdims=False):
+    a = asarray(a)
+    if q.ndim == 0:
+        # Do not allow 0-d arrays because following code fails for scalar
+        zerod = True
+        q = q[None]
+    else:
+        zerod = False
+
+    # avoid expensive reductions, relevant for arrays with < O(1000) elements
+    if q.size < 10:
+        for i in range(q.size):
+            if q[i] < 0. or q[i] > 100.:
+                raise ValueError("Percentiles must be in the range [0,100]")
+            q[i] /= 100.
+    else:
+        # faster than any()
+        if np.count_nonzero(q < 0.) or np.count_nonzero(q > 100.):
+            raise ValueError("Percentiles must be in the range [0,100]")
+        q /= 100.
+
+    # prepare a for partioning
+    if overwrite_input:
+        if axis is None:
+            ap = a.ravel()
+        else:
+            ap = a
+    else:
+        if axis is None:
+            ap = a.flatten()
+        else:
+            ap = a.copy()
+
+    if axis is None:
+        axis = 0
+
+    Nx = ap.shape[axis]
+    indices = q * (Nx - 1)
+
+    # round fractional indices according to interpolation method
+    if interpolation == 'lower':
+        indices = floor(indices).astype(intp)
+    elif interpolation == 'higher':
+        indices = ceil(indices).astype(intp)
+    elif interpolation == 'midpoint':
+        indices = 0.5 * (floor(indices) + ceil(indices))
+    elif interpolation == 'nearest':
+        indices = around(indices).astype(intp)
+    elif interpolation == 'linear':
+        pass  # keep index as fraction and interpolate
+    else:
+        raise ValueError(
+            "interpolation can only be 'linear', 'lower' 'higher', "
+            "'midpoint', or 'nearest'")
+
+    n = np.array(False, dtype=bool) # check for nan's flag
+    if indices.dtype == intp:  # take the points along axis
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices = concatenate((indices, [-1]))
+
+        ap.partition(indices, axis=axis)
+        # ensure axis with qth is first
+        ap = np.rollaxis(ap, axis, 0)
+        axis = 0
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices = indices[:-1]
+            n = np.isnan(ap[-1:, ...])
+
+        if zerod:
+            indices = indices[0]
+        r = take(ap, indices, axis=axis, out=out)
+
+
+    else:  # weight the points above and below the indices
+        indices_below = floor(indices).astype(intp)
+        indices_above = indices_below + 1
+        indices_above[indices_above > Nx - 1] = Nx - 1
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices_above = concatenate((indices_above, [-1]))
+
+        weights_above = indices - indices_below
+        weights_below = 1.0 - weights_above
+
+        weights_shape = [1, ] * ap.ndim
+        weights_shape[axis] = len(indices)
+        weights_below.shape = weights_shape
+        weights_above.shape = weights_shape
+
+        ap.partition(concatenate((indices_below, indices_above)), axis=axis)
+
+        # ensure axis with qth is first
+        ap = np.rollaxis(ap, axis, 0)
+        weights_below = np.rollaxis(weights_below, axis, 0)
+        weights_above = np.rollaxis(weights_above, axis, 0)
+        axis = 0
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices_above = indices_above[:-1]
+            n = np.isnan(ap[-1:, ...])
+
+        x1 = take(ap, indices_below, axis=axis) * weights_below
+        x2 = take(ap, indices_above, axis=axis) * weights_above
+
+        # ensure axis with qth is first
+        x1 = np.rollaxis(x1, axis, 0)
+        x2 = np.rollaxis(x2, axis, 0)
+
+        if zerod:
+            x1 = x1.squeeze(0)
+            x2 = x2.squeeze(0)
+
+        if out is not None:
+            r = add(x1, x2, out=out)
+        else:
+            r = add(x1, x2)
+
+    if np.any(n):
+        warnings.warn("Invalid value encountered in percentile",
+                              RuntimeWarning)
+        if zerod:
+            if ap.ndim == 1:
+                if out is not None:
+                    out[...] = a.dtype.type(np.nan)
+                    r = out
+                else:
+                    r = a.dtype.type(np.nan)
+            else:
+                r[..., n.squeeze(0)] = a.dtype.type(np.nan)
+        else:
+            if r.ndim == 1:
+                r[:] = a.dtype.type(np.nan)
+            else:
+                r[..., n.repeat(q.size, 0)] = a.dtype.type(np.nan)
+
+    return r
+
+
+def trapz(y, x=None, dx=1.0, axis=-1):
+    """
+    Integrate along the given axis using the composite trapezoidal rule.
+
+    Integrate `y` (`x`) along given axis.
+
+    Parameters
+    ----------
+    y : array_like
+        Input array to integrate.
+    x : array_like, optional
+        The sample points corresponding to the `y` values. If `x` is None,
+        the sample points are assumed to be evenly spaced `dx` apart. The
+        default is None.
+    dx : scalar, optional
+        The spacing between sample points when `x` is None. The default is 1.
+    axis : int, optional
+        The axis along which to integrate.
+
+    Returns
+    -------
+    trapz : float
+        Definite integral as approximated by trapezoidal rule.
+
+    See Also
+    --------
+    sum, cumsum
+
+    Notes
+    -----
+    Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
+    will be taken from `y` array, by default x-axis distances between
+    points will be 1.0, alternatively they can be provided with `x` array
+    or with `dx` scalar.  Return value will be equal to combined area under
+    the red lines.
+
+
+    References
+    ----------
+    .. [1] Wikipedia page: http://en.wikipedia.org/wiki/Trapezoidal_rule
+
+    .. [2] Illustration image:
+           http://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
+
+    Examples
+    --------
+    >>> np.trapz([1,2,3])
+    4.0
+    >>> np.trapz([1,2,3], x=[4,6,8])
+    8.0
+    >>> np.trapz([1,2,3], dx=2)
+    8.0
+    >>> a = np.arange(6).reshape(2, 3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.trapz(a, axis=0)
+    array([ 1.5,  2.5,  3.5])
+    >>> np.trapz(a, axis=1)
+    array([ 2.,  8.])
+
+    """
+    y = asanyarray(y)
+    if x is None:
+        d = dx
+    else:
+        x = asanyarray(x)
+        if x.ndim == 1:
+            d = diff(x)
+            # reshape to correct shape
+            shape = [1]*y.ndim
+            shape[axis] = d.shape[0]
+            d = d.reshape(shape)
+        else:
+            d = diff(x, axis=axis)
+    nd = len(y.shape)
+    slice1 = [slice(None)]*nd
+    slice2 = [slice(None)]*nd
+    slice1[axis] = slice(1, None)
+    slice2[axis] = slice(None, -1)
+    try:
+        ret = (d * (y[slice1] + y[slice2]) / 2.0).sum(axis)
+    except ValueError:
+        # Operations didn't work, cast to ndarray
+        d = np.asarray(d)
+        y = np.asarray(y)
+        ret = add.reduce(d * (y[slice1]+y[slice2])/2.0, axis)
+    return ret
+
+
+#always succeed
+def add_newdoc(place, obj, doc):
+    """
+    Adds documentation to obj which is in module place.
+
+    If doc is a string add it to obj as a docstring
+
+    If doc is a tuple, then the first element is interpreted as
+       an attribute of obj and the second as the docstring
+          (method, docstring)
+
+    If doc is a list, then each element of the list should be a
+       sequence of length two --> [(method1, docstring1),
+       (method2, docstring2), ...]
+
+    This routine never raises an error.
+
+    This routine cannot modify read-only docstrings, as appear
+    in new-style classes or built-in functions. Because this
+    routine never raises an error the caller must check manually
+    that the docstrings were changed.
+    """
+    try:
+        new = getattr(__import__(place, globals(), {}, [obj]), obj)
+        if isinstance(doc, str):
+            add_docstring(new, doc.strip())
+        elif isinstance(doc, tuple):
+            add_docstring(getattr(new, doc[0]), doc[1].strip())
+        elif isinstance(doc, list):
+            for val in doc:
+                add_docstring(getattr(new, val[0]), val[1].strip())
+    except:
+        pass
+
+
+# Based on scitools meshgrid
+def meshgrid(*xi, **kwargs):
+    """
+    Return coordinate matrices from coordinate vectors.
+
+    Make N-D coordinate arrays for vectorized evaluations of
+    N-D scalar/vector fields over N-D grids, given
+    one-dimensional coordinate arrays x1, x2,..., xn.
+
+    .. versionchanged:: 1.9
+       1-D and 0-D cases are allowed.
+
+    Parameters
+    ----------
+    x1, x2,..., xn : array_like
+        1-D arrays representing the coordinates of a grid.
+    indexing : {'xy', 'ij'}, optional
+        Cartesian ('xy', default) or matrix ('ij') indexing of output.
+        See Notes for more details.
+
+        .. versionadded:: 1.7.0
+    sparse : bool, optional
+        If True a sparse grid is returned in order to conserve memory.
+        Default is False.
+
+        .. versionadded:: 1.7.0
+    copy : bool, optional
+        If False, a view into the original arrays are returned in order to
+        conserve memory.  Default is True.  Please note that
+        ``sparse=False, copy=False`` will likely return non-contiguous
+        arrays.  Furthermore, more than one element of a broadcast array
+        may refer to a single memory location.  If you need to write to the
+        arrays, make copies first.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    X1, X2,..., XN : ndarray
+        For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` ,
+        return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij'
+        or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy'
+        with the elements of `xi` repeated to fill the matrix along
+        the first dimension for `x1`, the second for `x2` and so on.
+
+    Notes
+    -----
+    This function supports both indexing conventions through the indexing
+    keyword argument.  Giving the string 'ij' returns a meshgrid with
+    matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
+    In the 2-D case with inputs of length M and N, the outputs are of shape
+    (N, M) for 'xy' indexing and (M, N) for 'ij' indexing.  In the 3-D case
+    with inputs of length M, N and P, outputs are of shape (N, M, P) for
+    'xy' indexing and (M, N, P) for 'ij' indexing.  The difference is
+    illustrated by the following code snippet::
+
+        xv, yv = meshgrid(x, y, sparse=False, indexing='ij')
+        for i in range(nx):
+            for j in range(ny):
+                # treat xv[i,j], yv[i,j]
+
+        xv, yv = meshgrid(x, y, sparse=False, indexing='xy')
+        for i in range(nx):
+            for j in range(ny):
+                # treat xv[j,i], yv[j,i]
+
+    In the 1-D and 0-D case, the indexing and sparse keywords have no effect.
+
+    See Also
+    --------
+    index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
+                     using indexing notation.
+    index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
+                     using indexing notation.
+
+    Examples
+    --------
+    >>> nx, ny = (3, 2)
+    >>> x = np.linspace(0, 1, nx)
+    >>> y = np.linspace(0, 1, ny)
+    >>> xv, yv = meshgrid(x, y)
+    >>> xv
+    array([[ 0. ,  0.5,  1. ],
+           [ 0. ,  0.5,  1. ]])
+    >>> yv
+    array([[ 0.,  0.,  0.],
+           [ 1.,  1.,  1.]])
+    >>> xv, yv = meshgrid(x, y, sparse=True)  # make sparse output arrays
+    >>> xv
+    array([[ 0. ,  0.5,  1. ]])
+    >>> yv
+    array([[ 0.],
+           [ 1.]])
+
+    `meshgrid` is very useful to evaluate functions on a grid.
+
+    >>> x = np.arange(-5, 5, 0.1)
+    >>> y = np.arange(-5, 5, 0.1)
+    >>> xx, yy = meshgrid(x, y, sparse=True)
+    >>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
+    >>> h = plt.contourf(x,y,z)
+
+    """
+    ndim = len(xi)
+
+    copy_ = kwargs.pop('copy', True)
+    sparse = kwargs.pop('sparse', False)
+    indexing = kwargs.pop('indexing', 'xy')
+
+    if kwargs:
+        raise TypeError("meshgrid() got an unexpected keyword argument '%s'"
+                        % (list(kwargs)[0],))
+
+    if indexing not in ['xy', 'ij']:
+        raise ValueError(
+            "Valid values for `indexing` are 'xy' and 'ij'.")
+
+    s0 = (1,) * ndim
+    output = [np.asanyarray(x).reshape(s0[:i] + (-1,) + s0[i + 1::])
+              for i, x in enumerate(xi)]
+
+    shape = [x.size for x in output]
+
+    if indexing == 'xy' and ndim > 1:
+        # switch first and second axis
+        output[0].shape = (1, -1) + (1,)*(ndim - 2)
+        output[1].shape = (-1, 1) + (1,)*(ndim - 2)
+        shape[0], shape[1] = shape[1], shape[0]
+
+    if sparse:
+        if copy_:
+            return [x.copy() for x in output]
+        else:
+            return output
+    else:
+        # Return the full N-D matrix (not only the 1-D vector)
+        if copy_:
+            mult_fact = np.ones(shape, dtype=int)
+            return [x * mult_fact for x in output]
+        else:
+            return np.broadcast_arrays(*output)
+
+
+def delete(arr, obj, axis=None):
+    """
+    Return a new array with sub-arrays along an axis deleted. For a one
+    dimensional array, this returns those entries not returned by
+    `arr[obj]`.
+
+    Parameters
+    ----------
+    arr : array_like
+      Input array.
+    obj : slice, int or array of ints
+      Indicate which sub-arrays to remove.
+    axis : int, optional
+      The axis along which to delete the subarray defined by `obj`.
+      If `axis` is None, `obj` is applied to the flattened array.
+
+    Returns
+    -------
+    out : ndarray
+        A copy of `arr` with the elements specified by `obj` removed. Note
+        that `delete` does not occur in-place. If `axis` is None, `out` is
+        a flattened array.
+
+    See Also
+    --------
+    insert : Insert elements into an array.
+    append : Append elements at the end of an array.
+
+    Notes
+    -----
+    Often it is preferable to use a boolean mask. For example:
+
+    >>> mask = np.ones(len(arr), dtype=bool)
+    >>> mask[[0,2,4]] = False
+    >>> result = arr[mask,...]
+
+    Is equivalent to `np.delete(arr, [0,2,4], axis=0)`, but allows further
+    use of `mask`.
+
+    Examples
+    --------
+    >>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
+    >>> arr
+    array([[ 1,  2,  3,  4],
+           [ 5,  6,  7,  8],
+           [ 9, 10, 11, 12]])
+    >>> np.delete(arr, 1, 0)
+    array([[ 1,  2,  3,  4],
+           [ 9, 10, 11, 12]])
+
+    >>> np.delete(arr, np.s_[::2], 1)
+    array([[ 2,  4],
+           [ 6,  8],
+           [10, 12]])
+    >>> np.delete(arr, [1,3,5], None)
+    array([ 1,  3,  5,  7,  8,  9, 10, 11, 12])
+
+    """
+    wrap = None
+    if type(arr) is not ndarray:
+        try:
+            wrap = arr.__array_wrap__
+        except AttributeError:
+            pass
+
+    arr = asarray(arr)
+    ndim = arr.ndim
+    arrorder = 'F' if arr.flags.fnc else 'C'
+    if axis is None:
+        if ndim != 1:
+            arr = arr.ravel()
+        ndim = arr.ndim
+        axis = ndim - 1
+    if ndim == 0:
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "in the future the special handling of scalars will be removed "
+            "from delete and raise an error", DeprecationWarning)
+        if wrap:
+            return wrap(arr)
+        else:
+            return arr.copy()
+
+    slobj = [slice(None)]*ndim
+    N = arr.shape[axis]
+    newshape = list(arr.shape)
+
+    if isinstance(obj, slice):
+        start, stop, step = obj.indices(N)
+        xr = range(start, stop, step)
+        numtodel = len(xr)
+
+        if numtodel <= 0:
+            if wrap:
+                return wrap(arr.copy())
+            else:
+                return arr.copy()
+
+        # Invert if step is negative:
+        if step < 0:
+            step = -step
+            start = xr[-1]
+            stop = xr[0] + 1
+
+        newshape[axis] -= numtodel
+        new = empty(newshape, arr.dtype, arrorder)
+        # copy initial chunk
+        if start == 0:
+            pass
+        else:
+            slobj[axis] = slice(None, start)
+            new[slobj] = arr[slobj]
+        # copy end chunck
+        if stop == N:
+            pass
+        else:
+            slobj[axis] = slice(stop-numtodel, None)
+            slobj2 = [slice(None)]*ndim
+            slobj2[axis] = slice(stop, None)
+            new[slobj] = arr[slobj2]
+        # copy middle pieces
+        if step == 1:
+            pass
+        else:  # use array indexing.
+            keep = ones(stop-start, dtype=bool)
+            keep[:stop-start:step] = False
+            slobj[axis] = slice(start, stop-numtodel)
+            slobj2 = [slice(None)]*ndim
+            slobj2[axis] = slice(start, stop)
+            arr = arr[slobj2]
+            slobj2[axis] = keep
+            new[slobj] = arr[slobj2]
+        if wrap:
+            return wrap(new)
+        else:
+            return new
+
+    _obj = obj
+    obj = np.asarray(obj)
+    # After removing the special handling of booleans and out of
+    # bounds values, the conversion to the array can be removed.
+    if obj.dtype == bool:
+        warnings.warn(
+            "in the future insert will treat boolean arrays and array-likes "
+            "as boolean index instead of casting it to integer", FutureWarning)
+        obj = obj.astype(intp)
+    if isinstance(_obj, (int, long, integer)):
+        # optimization for a single value
+        obj = obj.item()
+        if (obj < -N or obj >= N):
+            raise IndexError(
+                "index %i is out of bounds for axis %i with "
+                "size %i" % (obj, axis, N))
+        if (obj < 0):
+            obj += N
+        newshape[axis] -= 1
+        new = empty(newshape, arr.dtype, arrorder)
+        slobj[axis] = slice(None, obj)
+        new[slobj] = arr[slobj]
+        slobj[axis] = slice(obj, None)
+        slobj2 = [slice(None)]*ndim
+        slobj2[axis] = slice(obj+1, None)
+        new[slobj] = arr[slobj2]
+    else:
+        if obj.size == 0 and not isinstance(_obj, np.ndarray):
+            obj = obj.astype(intp)
+        if not np.can_cast(obj, intp, 'same_kind'):
+            # obj.size = 1 special case always failed and would just
+            # give superfluous warnings.
+            # 2013-09-24, 1.9
+            warnings.warn(
+                "using a non-integer array as obj in delete will result in an "
+                "error in the future", DeprecationWarning)
+            obj = obj.astype(intp)
+        keep = ones(N, dtype=bool)
+
+        # Test if there are out of bound indices, this is deprecated
+        inside_bounds = (obj < N) & (obj >= -N)
+        if not inside_bounds.all():
+            # 2013-09-24, 1.9
+            warnings.warn(
+                "in the future out of bounds indices will raise an error "
+                "instead of being ignored by `numpy.delete`.",
+                DeprecationWarning)
+            obj = obj[inside_bounds]
+        positive_indices = obj >= 0
+        if not positive_indices.all():
+            warnings.warn(
+                "in the future negative indices will not be ignored by "
+                "`numpy.delete`.", FutureWarning)
+            obj = obj[positive_indices]
+
+        keep[obj, ] = False
+        slobj[axis] = keep
+        new = arr[slobj]
+
+    if wrap:
+        return wrap(new)
+    else:
+        return new
+
+
+def insert(arr, obj, values, axis=None):
+    """
+    Insert values along the given axis before the given indices.
+
+    Parameters
+    ----------
+    arr : array_like
+        Input array.
+    obj : int, slice or sequence of ints
+        Object that defines the index or indices before which `values` is
+        inserted.
+
+        .. versionadded:: 1.8.0
+
+        Support for multiple insertions when `obj` is a single scalar or a
+        sequence with one element (similar to calling insert multiple
+        times).
+    values : array_like
+        Values to insert into `arr`. If the type of `values` is different
+        from that of `arr`, `values` is converted to the type of `arr`.
+        `values` should be shaped so that ``arr[...,obj,...] = values``
+        is legal.
+    axis : int, optional
+        Axis along which to insert `values`.  If `axis` is None then `arr`
+        is flattened first.
+
+    Returns
+    -------
+    out : ndarray
+        A copy of `arr` with `values` inserted.  Note that `insert`
+        does not occur in-place: a new array is returned. If
+        `axis` is None, `out` is a flattened array.
+
+    See Also
+    --------
+    append : Append elements at the end of an array.
+    concatenate : Join a sequence of arrays along an existing axis.
+    delete : Delete elements from an array.
+
+    Notes
+    -----
+    Note that for higher dimensional inserts `obj=0` behaves very different
+    from `obj=[0]` just like `arr[:,0,:] = values` is different from
+    `arr[:,[0],:] = values`.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 1], [2, 2], [3, 3]])
+    >>> a
+    array([[1, 1],
+           [2, 2],
+           [3, 3]])
+    >>> np.insert(a, 1, 5)
+    array([1, 5, 1, 2, 2, 3, 3])
+    >>> np.insert(a, 1, 5, axis=1)
+    array([[1, 5, 1],
+           [2, 5, 2],
+           [3, 5, 3]])
+
+    Difference between sequence and scalars:
+
+    >>> np.insert(a, [1], [[1],[2],[3]], axis=1)
+    array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])
+    >>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1),
+    ...                np.insert(a, [1], [[1],[2],[3]], axis=1))
+    True
+
+    >>> b = a.flatten()
+    >>> b
+    array([1, 1, 2, 2, 3, 3])
+    >>> np.insert(b, [2, 2], [5, 6])
+    array([1, 1, 5, 6, 2, 2, 3, 3])
+
+    >>> np.insert(b, slice(2, 4), [5, 6])
+    array([1, 1, 5, 2, 6, 2, 3, 3])
+
+    >>> np.insert(b, [2, 2], [7.13, False]) # type casting
+    array([1, 1, 7, 0, 2, 2, 3, 3])
+
+    >>> x = np.arange(8).reshape(2, 4)
+    >>> idx = (1, 3)
+    >>> np.insert(x, idx, 999, axis=1)
+    array([[  0, 999,   1,   2, 999,   3],
+           [  4, 999,   5,   6, 999,   7]])
+
+    """
+    wrap = None
+    if type(arr) is not ndarray:
+        try:
+            wrap = arr.__array_wrap__
+        except AttributeError:
+            pass
+
+    arr = asarray(arr)
+    ndim = arr.ndim
+    arrorder = 'F' if arr.flags.fnc else 'C'
+    if axis is None:
+        if ndim != 1:
+            arr = arr.ravel()
+        ndim = arr.ndim
+        axis = ndim - 1
+    else:
+        if ndim > 0 and (axis < -ndim or axis >= ndim):
+            raise IndexError(
+                "axis %i is out of bounds for an array of "
+                "dimension %i" % (axis, ndim))
+        if (axis < 0):
+            axis += ndim
+    if (ndim == 0):
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "in the future the special handling of scalars will be removed "
+            "from insert and raise an error", DeprecationWarning)
+        arr = arr.copy()
+        arr[...] = values
+        if wrap:
+            return wrap(arr)
+        else:
+            return arr
+    slobj = [slice(None)]*ndim
+    N = arr.shape[axis]
+    newshape = list(arr.shape)
+
+    if isinstance(obj, slice):
+        # turn it into a range object
+        indices = arange(*obj.indices(N), **{'dtype': intp})
+    else:
+        # need to copy obj, because indices will be changed in-place
+        indices = np.array(obj)
+        if indices.dtype == bool:
+            # See also delete
+            warnings.warn(
+                "in the future insert will treat boolean arrays and "
+                "array-likes as a boolean index instead of casting it to "
+                "integer", FutureWarning)
+            indices = indices.astype(intp)
+            # Code after warning period:
+            #if obj.ndim != 1:
+            #    raise ValueError('boolean array argument obj to insert '
+            #                     'must be one dimensional')
+            #indices = np.flatnonzero(obj)
+        elif indices.ndim > 1:
+            raise ValueError(
+                "index array argument obj to insert must be one dimensional "
+                "or scalar")
+    if indices.size == 1:
+        index = indices.item()
+        if index < -N or index > N:
+            raise IndexError(
+                "index %i is out of bounds for axis %i with "
+                "size %i" % (obj, axis, N))
+        if (index < 0):
+            index += N
+
+        # There are some object array corner cases here, but we cannot avoid
+        # that:
+        values = array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype)
+        if indices.ndim == 0:
+            # broadcasting is very different here, since a[:,0,:] = ... behaves
+            # very different from a[:,[0],:] = ...! This changes values so that
+            # it works likes the second case. (here a[:,0:1,:])
+            values = np.rollaxis(values, 0, (axis % values.ndim) + 1)
+        numnew = values.shape[axis]
+        newshape[axis] += numnew
+        new = empty(newshape, arr.dtype, arrorder)
+        slobj[axis] = slice(None, index)
+        new[slobj] = arr[slobj]
+        slobj[axis] = slice(index, index+numnew)
+        new[slobj] = values
+        slobj[axis] = slice(index+numnew, None)
+        slobj2 = [slice(None)] * ndim
+        slobj2[axis] = slice(index, None)
+        new[slobj] = arr[slobj2]
+        if wrap:
+            return wrap(new)
+        return new
+    elif indices.size == 0 and not isinstance(obj, np.ndarray):
+        # Can safely cast the empty list to intp
+        indices = indices.astype(intp)
+
+    if not np.can_cast(indices, intp, 'same_kind'):
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "using a non-integer array as obj in insert will result in an "
+            "error in the future", DeprecationWarning)
+        indices = indices.astype(intp)
+
+    indices[indices < 0] += N
+
+    numnew = len(indices)
+    order = indices.argsort(kind='mergesort')   # stable sort
+    indices[order] += np.arange(numnew)
+
+    newshape[axis] += numnew
+    old_mask = ones(newshape[axis], dtype=bool)
+    old_mask[indices] = False
+
+    new = empty(newshape, arr.dtype, arrorder)
+    slobj2 = [slice(None)]*ndim
+    slobj[axis] = indices
+    slobj2[axis] = old_mask
+    new[slobj] = values
+    new[slobj2] = arr
+
+    if wrap:
+        return wrap(new)
+    return new
+
+
+def append(arr, values, axis=None):
+    """
+    Append values to the end of an array.
+
+    Parameters
+    ----------
+    arr : array_like
+        Values are appended to a copy of this array.
+    values : array_like
+        These values are appended to a copy of `arr`.  It must be of the
+        correct shape (the same shape as `arr`, excluding `axis`).  If
+        `axis` is not specified, `values` can be any shape and will be
+        flattened before use.
+    axis : int, optional
+        The axis along which `values` are appended.  If `axis` is not
+        given, both `arr` and `values` are flattened before use.
+
+    Returns
+    -------
+    append : ndarray
+        A copy of `arr` with `values` appended to `axis`.  Note that
+        `append` does not occur in-place: a new array is allocated and
+        filled.  If `axis` is None, `out` is a flattened array.
+
+    See Also
+    --------
+    insert : Insert elements into an array.
+    delete : Delete elements from an array.
+
+    Examples
+    --------
+    >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
+    array([1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    When `axis` is specified, `values` must have the correct shape.
+
+    >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
+    array([[1, 2, 3],
+           [4, 5, 6],
+           [7, 8, 9]])
+    >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
+    Traceback (most recent call last):
+    ...
+    ValueError: arrays must have same number of dimensions
+
+    """
+    arr = asanyarray(arr)
+    if axis is None:
+        if arr.ndim != 1:
+            arr = arr.ravel()
+        values = ravel(values)
+        axis = arr.ndim-1
+    return concatenate((arr, values), axis=axis)
+
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.py
new file mode 100644
index 0000000000..a0875a25fd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.py
@@ -0,0 +1,874 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import math
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import (
+    asarray, ScalarType, array, alltrue, cumprod, arange
+    )
+from numpy.core.numerictypes import find_common_type, issubdtype
+
+from . import function_base
+import numpy.matrixlib as matrix
+from .function_base import diff
+from numpy.core.multiarray import ravel_multi_index, unravel_index
+from numpy.lib.stride_tricks import as_strided
+
+makemat = matrix.matrix
+
+
+__all__ = [
+    'ravel_multi_index', 'unravel_index', 'mgrid', 'ogrid', 'r_', 'c_',
+    's_', 'index_exp', 'ix_', 'ndenumerate', 'ndindex', 'fill_diagonal',
+    'diag_indices', 'diag_indices_from'
+    ]
+
+
+def ix_(*args):
+    """
+    Construct an open mesh from multiple sequences.
+
+    This function takes N 1-D sequences and returns N outputs with N
+    dimensions each, such that the shape is 1 in all but one dimension
+    and the dimension with the non-unit shape value cycles through all
+    N dimensions.
+
+    Using `ix_` one can quickly construct index arrays that will index
+    the cross product. ``a[np.ix_([1,3],[2,5])]`` returns the array
+    ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``.
+
+    Parameters
+    ----------
+    args : 1-D sequences
+
+    Returns
+    -------
+    out : tuple of ndarrays
+        N arrays with N dimensions each, with N the number of input
+        sequences. Together these arrays form an open mesh.
+
+    See Also
+    --------
+    ogrid, mgrid, meshgrid
+
+    Examples
+    --------
+    >>> a = np.arange(10).reshape(2, 5)
+    >>> a
+    array([[0, 1, 2, 3, 4],
+           [5, 6, 7, 8, 9]])
+    >>> ixgrid = np.ix_([0,1], [2,4])
+    >>> ixgrid
+    (array([[0],
+           [1]]), array([[2, 4]]))
+    >>> ixgrid[0].shape, ixgrid[1].shape
+    ((2, 1), (1, 2))
+    >>> a[ixgrid]
+    array([[2, 4],
+           [7, 9]])
+
+    """
+    out = []
+    nd = len(args)
+    for k, new in enumerate(args):
+        new = asarray(new)
+        if new.ndim != 1:
+            raise ValueError("Cross index must be 1 dimensional")
+        if new.size == 0:
+            # Explicitly type empty arrays to avoid float default
+            new = new.astype(_nx.intp)
+        if issubdtype(new.dtype, _nx.bool_):
+            new, = new.nonzero()
+        new = new.reshape((1,)*k + (new.size,) + (1,)*(nd-k-1))
+        out.append(new)
+    return tuple(out)
+
+class nd_grid(object):
+    """
+    Construct a multi-dimensional "meshgrid".
+
+    ``grid = nd_grid()`` creates an instance which will return a mesh-grid
+    when indexed.  The dimension and number of the output arrays are equal
+    to the number of indexing dimensions.  If the step length is not a
+    complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then the
+    integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    If instantiated with an argument of ``sparse=True``, the mesh-grid is
+    open (or not fleshed out) so that only one-dimension of each returned
+    argument is greater than 1.
+
+    Parameters
+    ----------
+    sparse : bool, optional
+        Whether the grid is sparse or not. Default is False.
+
+    Notes
+    -----
+    Two instances of `nd_grid` are made available in the NumPy namespace,
+    `mgrid` and `ogrid`::
+
+        mgrid = nd_grid(sparse=False)
+        ogrid = nd_grid(sparse=True)
+
+    Users should use these pre-defined instances instead of using `nd_grid`
+    directly.
+
+    Examples
+    --------
+    >>> mgrid = np.lib.index_tricks.nd_grid()
+    >>> mgrid[0:5,0:5]
+    array([[[0, 0, 0, 0, 0],
+            [1, 1, 1, 1, 1],
+            [2, 2, 2, 2, 2],
+            [3, 3, 3, 3, 3],
+            [4, 4, 4, 4, 4]],
+           [[0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4]]])
+    >>> mgrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+
+    >>> ogrid = np.lib.index_tricks.nd_grid(sparse=True)
+    >>> ogrid[0:5,0:5]
+    [array([[0],
+            [1],
+            [2],
+            [3],
+            [4]]), array([[0, 1, 2, 3, 4]])]
+
+    """
+
+    def __init__(self, sparse=False):
+        self.sparse = sparse
+
+    def __getitem__(self, key):
+        try:
+            size = []
+            typ = int
+            for k in range(len(key)):
+                step = key[k].step
+                start = key[k].start
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size.append(int(abs(step)))
+                    typ = float
+                else:
+                    size.append(
+                        int(math.ceil((key[k].stop - start)/(step*1.0))))
+                if (isinstance(step, float) or
+                        isinstance(start, float) or
+                        isinstance(key[k].stop, float)):
+                    typ = float
+            if self.sparse:
+                nn = [_nx.arange(_x, dtype=_t)
+                        for _x, _t in zip(size, (typ,)*len(size))]
+            else:
+                nn = _nx.indices(size, typ)
+            for k in range(len(size)):
+                step = key[k].step
+                start = key[k].start
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    step = int(abs(step))
+                    if step != 1:
+                        step = (key[k].stop - start)/float(step-1)
+                nn[k] = (nn[k]*step+start)
+            if self.sparse:
+                slobj = [_nx.newaxis]*len(size)
+                for k in range(len(size)):
+                    slobj[k] = slice(None, None)
+                    nn[k] = nn[k][slobj]
+                    slobj[k] = _nx.newaxis
+            return nn
+        except (IndexError, TypeError):
+            step = key.step
+            stop = key.stop
+            start = key.start
+            if start is None:
+                start = 0
+            if isinstance(step, complex):
+                step = abs(step)
+                length = int(step)
+                if step != 1:
+                    step = (key.stop-start)/float(step-1)
+                stop = key.stop + step
+                return _nx.arange(0, length, 1, float)*step + start
+            else:
+                return _nx.arange(start, stop, step)
+
+    def __getslice__(self, i, j):
+        return _nx.arange(i, j)
+
+    def __len__(self):
+        return 0
+
+mgrid = nd_grid(sparse=False)
+ogrid = nd_grid(sparse=True)
+mgrid.__doc__ = None  # set in numpy.add_newdocs
+ogrid.__doc__ = None  # set in numpy.add_newdocs
+
+class AxisConcatenator(object):
+    """
+    Translates slice objects to concatenation along an axis.
+
+    For detailed documentation on usage, see `r_`.
+
+    """
+
+    def _retval(self, res):
+        if self.matrix:
+            oldndim = res.ndim
+            res = makemat(res)
+            if oldndim == 1 and self.col:
+                res = res.T
+        self.axis = self._axis
+        self.matrix = self._matrix
+        self.col = 0
+        return res
+
+    def __init__(self, axis=0, matrix=False, ndmin=1, trans1d=-1):
+        self._axis = axis
+        self._matrix = matrix
+        self.axis = axis
+        self.matrix = matrix
+        self.col = 0
+        self.trans1d = trans1d
+        self.ndmin = ndmin
+
+    def __getitem__(self, key):
+        trans1d = self.trans1d
+        ndmin = self.ndmin
+        if isinstance(key, str):
+            frame = sys._getframe().f_back
+            mymat = matrix.bmat(key, frame.f_globals, frame.f_locals)
+            return mymat
+        if not isinstance(key, tuple):
+            key = (key,)
+        objs = []
+        scalars = []
+        arraytypes = []
+        scalartypes = []
+        for k in range(len(key)):
+            scalar = False
+            if isinstance(key[k], slice):
+                step = key[k].step
+                start = key[k].start
+                stop = key[k].stop
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size = int(abs(step))
+                    newobj = function_base.linspace(start, stop, num=size)
+                else:
+                    newobj = _nx.arange(start, stop, step)
+                if ndmin > 1:
+                    newobj = array(newobj, copy=False, ndmin=ndmin)
+                    if trans1d != -1:
+                        newobj = newobj.swapaxes(-1, trans1d)
+            elif isinstance(key[k], str):
+                if k != 0:
+                    raise ValueError("special directives must be the "
+                            "first entry.")
+                key0 = key[0]
+                if key0 in 'rc':
+                    self.matrix = True
+                    self.col = (key0 == 'c')
+                    continue
+                if ',' in key0:
+                    vec = key0.split(',')
+                    try:
+                        self.axis, ndmin = \
+                                   [int(x) for x in vec[:2]]
+                        if len(vec) == 3:
+                            trans1d = int(vec[2])
+                        continue
+                    except:
+                        raise ValueError("unknown special directive")
+                try:
+                    self.axis = int(key[k])
+                    continue
+                except (ValueError, TypeError):
+                    raise ValueError("unknown special directive")
+            elif type(key[k]) in ScalarType:
+                newobj = array(key[k], ndmin=ndmin)
+                scalars.append(k)
+                scalar = True
+                scalartypes.append(newobj.dtype)
+            else:
+                newobj = key[k]
+                if ndmin > 1:
+                    tempobj = array(newobj, copy=False, subok=True)
+                    newobj = array(newobj, copy=False, subok=True,
+                                   ndmin=ndmin)
+                    if trans1d != -1 and tempobj.ndim < ndmin:
+                        k2 = ndmin-tempobj.ndim
+                        if (trans1d < 0):
+                            trans1d += k2 + 1
+                        defaxes = list(range(ndmin))
+                        k1 = trans1d
+                        axes = defaxes[:k1] + defaxes[k2:] + \
+                               defaxes[k1:k2]
+                        newobj = newobj.transpose(axes)
+                    del tempobj
+            objs.append(newobj)
+            if not scalar and isinstance(newobj, _nx.ndarray):
+                arraytypes.append(newobj.dtype)
+
+        #  Esure that scalars won't up-cast unless warranted
+        final_dtype = find_common_type(arraytypes, scalartypes)
+        if final_dtype is not None:
+            for k in scalars:
+                objs[k] = objs[k].astype(final_dtype)
+
+        res = _nx.concatenate(tuple(objs), axis=self.axis)
+        return self._retval(res)
+
+    def __getslice__(self, i, j):
+        res = _nx.arange(i, j)
+        return self._retval(res)
+
+    def __len__(self):
+        return 0
+
+# separate classes are used here instead of just making r_ = concatentor(0),
+# etc. because otherwise we couldn't get the doc string to come out right
+# in help(r_)
+
+class RClass(AxisConcatenator):
+    """
+    Translates slice objects to concatenation along the first axis.
+
+    This is a simple way to build up arrays quickly. There are two use cases.
+
+    1. If the index expression contains comma separated arrays, then stack
+       them along their first axis.
+    2. If the index expression contains slice notation or scalars then create
+       a 1-D array with a range indicated by the slice notation.
+
+    If slice notation is used, the syntax ``start:stop:step`` is equivalent
+    to ``np.arange(start, stop, step)`` inside of the brackets. However, if
+    ``step`` is an imaginary number (i.e. 100j) then its integer portion is
+    interpreted as a number-of-points desired and the start and stop are
+    inclusive. In other words ``start:stop:stepj`` is interpreted as
+    ``np.linspace(start, stop, step, endpoint=1)`` inside of the brackets.
+    After expansion of slice notation, all comma separated sequences are
+    concatenated together.
+
+    Optional character strings placed as the first element of the index
+    expression can be used to change the output. The strings 'r' or 'c' result
+    in matrix output. If the result is 1-D and 'r' is specified a 1 x N (row)
+    matrix is produced. If the result is 1-D and 'c' is specified, then a N x 1
+    (column) matrix is produced. If the result is 2-D then both provide the
+    same matrix result.
+
+    A string integer specifies which axis to stack multiple comma separated
+    arrays along. A string of two comma-separated integers allows indication
+    of the minimum number of dimensions to force each entry into as the
+    second integer (the axis to concatenate along is still the first integer).
+
+    A string with three comma-separated integers allows specification of the
+    axis to concatenate along, the minimum number of dimensions to force the
+    entries to, and which axis should contain the start of the arrays which
+    are less than the specified number of dimensions. In other words the third
+    integer allows you to specify where the 1's should be placed in the shape
+    of the arrays that have their shapes upgraded. By default, they are placed
+    in the front of the shape tuple. The third argument allows you to specify
+    where the start of the array should be instead. Thus, a third argument of
+    '0' would place the 1's at the end of the array shape. Negative integers
+    specify where in the new shape tuple the last dimension of upgraded arrays
+    should be placed, so the default is '-1'.
+
+    Parameters
+    ----------
+    Not a function, so takes no parameters
+
+
+    Returns
+    -------
+    A concatenated ndarray or matrix.
+
+    See Also
+    --------
+    concatenate : Join a sequence of arrays along an existing axis.
+    c_ : Translates slice objects to concatenation along the second axis.
+
+    Examples
+    --------
+    >>> np.r_[np.array([1,2,3]), 0, 0, np.array([4,5,6])]
+    array([1, 2, 3, 0, 0, 4, 5, 6])
+    >>> np.r_[-1:1:6j, [0]*3, 5, 6]
+    array([-1. , -0.6, -0.2,  0.2,  0.6,  1. ,  0. ,  0. ,  0. ,  5. ,  6. ])
+
+    String integers specify the axis to concatenate along or the minimum
+    number of dimensions to force entries into.
+
+    >>> a = np.array([[0, 1, 2], [3, 4, 5]])
+    >>> np.r_['-1', a, a] # concatenate along last axis
+    array([[0, 1, 2, 0, 1, 2],
+           [3, 4, 5, 3, 4, 5]])
+    >>> np.r_['0,2', [1,2,3], [4,5,6]] # concatenate along first axis, dim>=2
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    >>> np.r_['0,2,0', [1,2,3], [4,5,6]]
+    array([[1],
+           [2],
+           [3],
+           [4],
+           [5],
+           [6]])
+    >>> np.r_['1,2,0', [1,2,3], [4,5,6]]
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+
+    Using 'r' or 'c' as a first string argument creates a matrix.
+
+    >>> np.r_['r',[1,2,3], [4,5,6]]
+    matrix([[1, 2, 3, 4, 5, 6]])
+
+    """
+
+    def __init__(self):
+        AxisConcatenator.__init__(self, 0)
+
+r_ = RClass()
+
+class CClass(AxisConcatenator):
+    """
+    Translates slice objects to concatenation along the second axis.
+
+    This is short-hand for ``np.r_['-1,2,0', index expression]``, which is
+    useful because of its common occurrence. In particular, arrays will be
+    stacked along their last axis after being upgraded to at least 2-D with
+    1's post-pended to the shape (column vectors made out of 1-D arrays).
+
+    For detailed documentation, see `r_`.
+
+    Examples
+    --------
+    >>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]
+    array([[1, 2, 3, 0, 0, 4, 5, 6]])
+
+    """
+
+    def __init__(self):
+        AxisConcatenator.__init__(self, -1, ndmin=2, trans1d=0)
+
+c_ = CClass()
+
+class ndenumerate(object):
+    """
+    Multidimensional index iterator.
+
+    Return an iterator yielding pairs of array coordinates and values.
+
+    Parameters
+    ----------
+    arr : ndarray
+      Input array.
+
+    See Also
+    --------
+    ndindex, flatiter
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> for index, x in np.ndenumerate(a):
+    ...     print(index, x)
+    (0, 0) 1
+    (0, 1) 2
+    (1, 0) 3
+    (1, 1) 4
+
+    """
+
+    def __init__(self, arr):
+        self.iter = asarray(arr).flat
+
+    def __next__(self):
+        """
+        Standard iterator method, returns the index tuple and array value.
+
+        Returns
+        -------
+        coords : tuple of ints
+            The indices of the current iteration.
+        val : scalar
+            The array element of the current iteration.
+
+        """
+        return self.iter.coords, next(self.iter)
+
+    def __iter__(self):
+        return self
+
+    next = __next__
+
+
+class ndindex(object):
+    """
+    An N-dimensional iterator object to index arrays.
+
+    Given the shape of an array, an `ndindex` instance iterates over
+    the N-dimensional index of the array. At each iteration a tuple
+    of indices is returned, the last dimension is iterated over first.
+
+    Parameters
+    ----------
+    `*args` : ints
+      The size of each dimension of the array.
+
+    See Also
+    --------
+    ndenumerate, flatiter
+
+    Examples
+    --------
+    >>> for index in np.ndindex(3, 2, 1):
+    ...     print(index)
+    (0, 0, 0)
+    (0, 1, 0)
+    (1, 0, 0)
+    (1, 1, 0)
+    (2, 0, 0)
+    (2, 1, 0)
+
+    """
+
+    def __init__(self, *shape):
+        if len(shape) == 1 and isinstance(shape[0], tuple):
+            shape = shape[0]
+        x = as_strided(_nx.zeros(1), shape=shape,
+                       strides=_nx.zeros_like(shape))
+        self._it = _nx.nditer(x, flags=['multi_index', 'zerosize_ok'],
+                              order='C')
+
+    def __iter__(self):
+        return self
+
+    def ndincr(self):
+        """
+        Increment the multi-dimensional index by one.
+
+        This method is for backward compatibility only: do not use.
+        """
+        next(self)
+
+    def __next__(self):
+        """
+        Standard iterator method, updates the index and returns the index
+        tuple.
+
+        Returns
+        -------
+        val : tuple of ints
+            Returns a tuple containing the indices of the current
+            iteration.
+
+        """
+        next(self._it)
+        return self._it.multi_index
+
+    next = __next__
+
+
+# You can do all this with slice() plus a few special objects,
+# but there's a lot to remember. This version is simpler because
+# it uses the standard array indexing syntax.
+#
+# Written by Konrad Hinsen <hinsen@cnrs-orleans.fr>
+# last revision: 1999-7-23
+#
+# Cosmetic changes by T. Oliphant 2001
+#
+#
+
+class IndexExpression(object):
+    """
+    A nicer way to build up index tuples for arrays.
+
+    .. note::
+       Use one of the two predefined instances `index_exp` or `s_`
+       rather than directly using `IndexExpression`.
+
+    For any index combination, including slicing and axis insertion,
+    ``a[indices]`` is the same as ``a[np.index_exp[indices]]`` for any
+    array `a`. However, ``np.index_exp[indices]`` can be used anywhere
+    in Python code and returns a tuple of slice objects that can be
+    used in the construction of complex index expressions.
+
+    Parameters
+    ----------
+    maketuple : bool
+        If True, always returns a tuple.
+
+    See Also
+    --------
+    index_exp : Predefined instance that always returns a tuple:
+       `index_exp = IndexExpression(maketuple=True)`.
+    s_ : Predefined instance without tuple conversion:
+       `s_ = IndexExpression(maketuple=False)`.
+
+    Notes
+    -----
+    You can do all this with `slice()` plus a few special objects,
+    but there's a lot to remember and this version is simpler because
+    it uses the standard array indexing syntax.
+
+    Examples
+    --------
+    >>> np.s_[2::2]
+    slice(2, None, 2)
+    >>> np.index_exp[2::2]
+    (slice(2, None, 2),)
+
+    >>> np.array([0, 1, 2, 3, 4])[np.s_[2::2]]
+    array([2, 4])
+
+    """
+
+    def __init__(self, maketuple):
+        self.maketuple = maketuple
+
+    def __getitem__(self, item):
+        if self.maketuple and not isinstance(item, tuple):
+            return (item,)
+        else:
+            return item
+
+index_exp = IndexExpression(maketuple=True)
+s_ = IndexExpression(maketuple=False)
+
+# End contribution from Konrad.
+
+
+# The following functions complement those in twodim_base, but are
+# applicable to N-dimensions.
+
+def fill_diagonal(a, val, wrap=False):
+    """Fill the main diagonal of the given array of any dimensionality.
+
+    For an array `a` with ``a.ndim > 2``, the diagonal is the list of
+    locations with indices ``a[i, i, ..., i]`` all identical. This function
+    modifies the input array in-place, it does not return a value.
+
+    Parameters
+    ----------
+    a : array, at least 2-D.
+      Array whose diagonal is to be filled, it gets modified in-place.
+
+    val : scalar
+      Value to be written on the diagonal, its type must be compatible with
+      that of the array a.
+
+    wrap : bool
+      For tall matrices in NumPy version up to 1.6.2, the
+      diagonal "wrapped" after N columns. You can have this behavior
+      with this option. This affects only tall matrices.
+
+    See also
+    --------
+    diag_indices, diag_indices_from
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    This functionality can be obtained via `diag_indices`, but internally
+    this version uses a much faster implementation that never constructs the
+    indices and uses simple slicing.
+
+    Examples
+    --------
+    >>> a = np.zeros((3, 3), int)
+    >>> np.fill_diagonal(a, 5)
+    >>> a
+    array([[5, 0, 0],
+           [0, 5, 0],
+           [0, 0, 5]])
+
+    The same function can operate on a 4-D array:
+
+    >>> a = np.zeros((3, 3, 3, 3), int)
+    >>> np.fill_diagonal(a, 4)
+
+    We only show a few blocks for clarity:
+
+    >>> a[0, 0]
+    array([[4, 0, 0],
+           [0, 0, 0],
+           [0, 0, 0]])
+    >>> a[1, 1]
+    array([[0, 0, 0],
+           [0, 4, 0],
+           [0, 0, 0]])
+    >>> a[2, 2]
+    array([[0, 0, 0],
+           [0, 0, 0],
+           [0, 0, 4]])
+
+    The wrap option affects only tall matrices:
+
+    >>> # tall matrices no wrap
+    >>> a = np.zeros((5, 3),int)
+    >>> fill_diagonal(a, 4)
+    >>> a
+    array([[4, 0, 0],
+           [0, 4, 0],
+           [0, 0, 4],
+           [0, 0, 0],
+           [0, 0, 0]])
+
+    >>> # tall matrices wrap
+    >>> a = np.zeros((5, 3),int)
+    >>> fill_diagonal(a, 4, wrap=True)
+    >>> a
+    array([[4, 0, 0],
+           [0, 4, 0],
+           [0, 0, 4],
+           [0, 0, 0],
+           [4, 0, 0]])
+
+    >>> # wide matrices
+    >>> a = np.zeros((3, 5),int)
+    >>> fill_diagonal(a, 4, wrap=True)
+    >>> a
+    array([[4, 0, 0, 0, 0],
+           [0, 4, 0, 0, 0],
+           [0, 0, 4, 0, 0]])
+
+    """
+    if a.ndim < 2:
+        raise ValueError("array must be at least 2-d")
+    end = None
+    if a.ndim == 2:
+        # Explicit, fast formula for the common case.  For 2-d arrays, we
+        # accept rectangular ones.
+        step = a.shape[1] + 1
+        #This is needed to don't have tall matrix have the diagonal wrap.
+        if not wrap:
+            end = a.shape[1] * a.shape[1]
+    else:
+        # For more than d=2, the strided formula is only valid for arrays with
+        # all dimensions equal, so we check first.
+        if not alltrue(diff(a.shape) == 0):
+            raise ValueError("All dimensions of input must be of equal length")
+        step = 1 + (cumprod(a.shape[:-1])).sum()
+
+    # Write the value out into the diagonal.
+    a.flat[:end:step] = val
+
+
+def diag_indices(n, ndim=2):
+    """
+    Return the indices to access the main diagonal of an array.
+
+    This returns a tuple of indices that can be used to access the main
+    diagonal of an array `a` with ``a.ndim >= 2`` dimensions and shape
+    (n, n, ..., n). For ``a.ndim = 2`` this is the usual diagonal, for
+    ``a.ndim > 2`` this is the set of indices to access ``a[i, i, ..., i]``
+    for ``i = [0..n-1]``.
+
+    Parameters
+    ----------
+    n : int
+      The size, along each dimension, of the arrays for which the returned
+      indices can be used.
+
+    ndim : int, optional
+      The number of dimensions.
+
+    See also
+    --------
+    diag_indices_from
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Create a set of indices to access the diagonal of a (4, 4) array:
+
+    >>> di = np.diag_indices(4)
+    >>> di
+    (array([0, 1, 2, 3]), array([0, 1, 2, 3]))
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+    >>> a[di] = 100
+    >>> a
+    array([[100,   1,   2,   3],
+           [  4, 100,   6,   7],
+           [  8,   9, 100,  11],
+           [ 12,  13,  14, 100]])
+
+    Now, we create indices to manipulate a 3-D array:
+
+    >>> d3 = np.diag_indices(2, 3)
+    >>> d3
+    (array([0, 1]), array([0, 1]), array([0, 1]))
+
+    And use it to set the diagonal of an array of zeros to 1:
+
+    >>> a = np.zeros((2, 2, 2), dtype=np.int)
+    >>> a[d3] = 1
+    >>> a
+    array([[[1, 0],
+            [0, 0]],
+           [[0, 0],
+            [0, 1]]])
+
+    """
+    idx = arange(n)
+    return (idx,) * ndim
+
+
+def diag_indices_from(arr):
+    """
+    Return the indices to access the main diagonal of an n-dimensional array.
+
+    See `diag_indices` for full details.
+
+    Parameters
+    ----------
+    arr : array, at least 2-D
+
+    See Also
+    --------
+    diag_indices
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+
+    if not arr.ndim >= 2:
+        raise ValueError("input array must be at least 2-d")
+    # For more than d=2, the strided formula is only valid for arrays with
+    # all dimensions equal, so we check first.
+    if not alltrue(diff(arr.shape) == 0):
+        raise ValueError("All dimensions of input must be of equal length")
+
+    return diag_indices(arr.shape[0], arr.ndim)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/info.py
new file mode 100644
index 0000000000..ca1e723975
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/info.py
@@ -0,0 +1,158 @@
+"""
+Basic functions used by several sub-packages and
+useful to have in the main name-space.
+
+Type Handling
+-------------
+================ ===================
+iscomplexobj     Test for complex object, scalar result
+isrealobj        Test for real object, scalar result
+iscomplex        Test for complex elements, array result
+isreal           Test for real elements, array result
+imag             Imaginary part
+real             Real part
+real_if_close    Turns complex number with tiny imaginary part to real
+isneginf         Tests for negative infinity, array result
+isposinf         Tests for positive infinity, array result
+isnan            Tests for nans, array result
+isinf            Tests for infinity, array result
+isfinite         Tests for finite numbers, array result
+isscalar         True if argument is a scalar
+nan_to_num       Replaces NaN's with 0 and infinities with large numbers
+cast             Dictionary of functions to force cast to each type
+common_type      Determine the minimum common type code for a group
+                 of arrays
+mintypecode      Return minimal allowed common typecode.
+================ ===================
+
+Index Tricks
+------------
+================ ===================
+mgrid            Method which allows easy construction of N-d
+                 'mesh-grids'
+``r_``           Append and construct arrays: turns slice objects into
+                 ranges and concatenates them, for 2d arrays appends rows.
+index_exp        Konrad Hinsen's index_expression class instance which
+                 can be useful for building complicated slicing syntax.
+================ ===================
+
+Useful Functions
+----------------
+================ ===================
+select           Extension of where to multiple conditions and choices
+extract          Extract 1d array from flattened array according to mask
+insert           Insert 1d array of values into Nd array according to mask
+linspace         Evenly spaced samples in linear space
+logspace         Evenly spaced samples in logarithmic space
+fix              Round x to nearest integer towards zero
+mod              Modulo mod(x,y) = x % y except keeps sign of y
+amax             Array maximum along axis
+amin             Array minimum along axis
+ptp              Array max-min along axis
+cumsum           Cumulative sum along axis
+prod             Product of elements along axis
+cumprod          Cumluative product along axis
+diff             Discrete differences along axis
+angle            Returns angle of complex argument
+unwrap           Unwrap phase along given axis (1-d algorithm)
+sort_complex     Sort a complex-array (based on real, then imaginary)
+trim_zeros       Trim the leading and trailing zeros from 1D array.
+vectorize        A class that wraps a Python function taking scalar
+                 arguments into a generalized function which can handle
+                 arrays of arguments using the broadcast rules of
+                 numerix Python.
+================ ===================
+
+Shape Manipulation
+------------------
+================ ===================
+squeeze          Return a with length-one dimensions removed.
+atleast_1d       Force arrays to be > 1D
+atleast_2d       Force arrays to be > 2D
+atleast_3d       Force arrays to be > 3D
+vstack           Stack arrays vertically (row on row)
+hstack           Stack arrays horizontally (column on column)
+column_stack     Stack 1D arrays as columns into 2D array
+dstack           Stack arrays depthwise (along third dimension)
+stack            Stack arrays along a new axis
+split            Divide array into a list of sub-arrays
+hsplit           Split into columns
+vsplit           Split into rows
+dsplit           Split along third dimension
+================ ===================
+
+Matrix (2D Array) Manipulations
+-------------------------------
+================ ===================
+fliplr           2D array with columns flipped
+flipud           2D array with rows flipped
+rot90            Rotate a 2D array a multiple of 90 degrees
+eye              Return a 2D array with ones down a given diagonal
+diag             Construct a 2D array from a vector, or return a given
+                 diagonal from a 2D array.
+mat              Construct a Matrix
+bmat             Build a Matrix from blocks
+================ ===================
+
+Polynomials
+-----------
+================ ===================
+poly1d           A one-dimensional polynomial class
+poly             Return polynomial coefficients from roots
+roots            Find roots of polynomial given coefficients
+polyint          Integrate polynomial
+polyder          Differentiate polynomial
+polyadd          Add polynomials
+polysub          Substract polynomials
+polymul          Multiply polynomials
+polydiv          Divide polynomials
+polyval          Evaluate polynomial at given argument
+================ ===================
+
+Iterators
+---------
+================ ===================
+Arrayterator     A buffered iterator for big arrays.
+================ ===================
+
+Import Tricks
+-------------
+================ ===================
+ppimport         Postpone module import until trying to use it
+ppimport_attr    Postpone module import until trying to use its attribute
+ppresolve        Import postponed module and return it.
+================ ===================
+
+Machine Arithmetics
+-------------------
+================ ===================
+machar_single    Single precision floating point arithmetic parameters
+machar_double    Double precision floating point arithmetic parameters
+================ ===================
+
+Threading Tricks
+----------------
+================ ===================
+ParallelExec     Execute commands in parallel thread.
+================ ===================
+
+1D Array Set Operations
+-----------------------
+Set operations for 1D numeric arrays based on sort() function.
+
+================ ===================
+ediff1d          Array difference (auxiliary function).
+unique           Unique elements of an array.
+intersect1d      Intersection of 1D arrays with unique elements.
+setxor1d         Set exclusive-or of 1D arrays with unique elements.
+in1d             Test whether elements in a 1D array are also present in
+                 another array.
+union1d          Union of 1D arrays with unique elements.
+setdiff1d        Set difference of 1D arrays with unique elements.
+================ ===================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core', 'testing']
+global_symbols = ['*']
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
new file mode 100644
index 0000000000..8fe7afd46f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
@@ -0,0 +1,1248 @@
+"""
+Functions that ignore NaN.
+
+Functions
+---------
+
+- `nanmin` -- minimum non-NaN value
+- `nanmax` -- maximum non-NaN value
+- `nanargmin` -- index of minimum non-NaN value
+- `nanargmax` -- index of maximum non-NaN value
+- `nansum` -- sum of non-NaN values
+- `nanprod` -- product of non-NaN values
+- `nanmean` -- mean of non-NaN values
+- `nanvar` -- variance of non-NaN values
+- `nanstd` -- standard deviation of non-NaN values
+- `nanmedian` -- median of non-NaN values
+- `nanpercentile` -- qth percentile of non-NaN values
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+from numpy.lib.function_base import _ureduce as _ureduce
+
+__all__ = [
+    'nansum', 'nanmax', 'nanmin', 'nanargmax', 'nanargmin', 'nanmean',
+    'nanmedian', 'nanpercentile', 'nanvar', 'nanstd', 'nanprod',
+    ]
+
+
+def _replace_nan(a, val):
+    """
+    If `a` is of inexact type, make a copy of `a`, replace NaNs with
+    the `val` value, and return the copy together with a boolean mask
+    marking the locations where NaNs were present. If `a` is not of
+    inexact type, do nothing and return `a` together with a mask of None.
+
+    Note that scalars will end up as array scalars, which is important
+    for using the result as the value of the out argument in some
+    operations.
+
+    Parameters
+    ----------
+    a : array-like
+        Input array.
+    val : float
+        NaN values are set to val before doing the operation.
+
+    Returns
+    -------
+    y : ndarray
+        If `a` is of inexact type, return a copy of `a` with the NaNs
+        replaced by the fill value, otherwise return `a`.
+    mask: {bool, None}
+        If `a` is of inexact type, return a boolean mask marking locations of
+        NaNs, otherwise return None.
+
+    """
+    is_new = not isinstance(a, np.ndarray)
+    if is_new:
+        a = np.array(a)
+    if not issubclass(a.dtype.type, np.inexact):
+        return a, None
+    if not is_new:
+        # need copy
+        a = np.array(a, subok=True)
+
+    mask = np.isnan(a)
+    np.copyto(a, val, where=mask)
+    return a, mask
+
+
+def _copyto(a, val, mask):
+    """
+    Replace values in `a` with NaN where `mask` is True.  This differs from
+    copyto in that it will deal with the case where `a` is a numpy scalar.
+
+    Parameters
+    ----------
+    a : ndarray or numpy scalar
+        Array or numpy scalar some of whose values are to be replaced
+        by val.
+    val : numpy scalar
+        Value used a replacement.
+    mask : ndarray, scalar
+        Boolean array. Where True the corresponding element of `a` is
+        replaced by `val`. Broadcasts.
+
+    Returns
+    -------
+    res : ndarray, scalar
+        Array with elements replaced or scalar `val`.
+
+    """
+    if isinstance(a, np.ndarray):
+        np.copyto(a, val, where=mask, casting='unsafe')
+    else:
+        a = a.dtype.type(val)
+    return a
+
+
+def _divide_by_count(a, b, out=None):
+    """
+    Compute a/b ignoring invalid results. If `a` is an array the division
+    is done in place. If `a` is a scalar, then its type is preserved in the
+    output. If out is None, then then a is used instead so that the
+    division is in place. Note that this is only called with `a` an inexact
+    type.
+
+    Parameters
+    ----------
+    a : {ndarray, numpy scalar}
+        Numerator. Expected to be of inexact type but not checked.
+    b : {ndarray, numpy scalar}
+        Denominator.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.
+
+    Returns
+    -------
+    ret : {ndarray, numpy scalar}
+        The return value is a/b. If `a` was an ndarray the division is done
+        in place. If `a` is a numpy scalar, the division preserves its type.
+
+    """
+    with np.errstate(invalid='ignore'):
+        if isinstance(a, np.ndarray):
+            if out is None:
+                return np.divide(a, b, out=a, casting='unsafe')
+            else:
+                return np.divide(a, b, out=out, casting='unsafe')
+        else:
+            if out is None:
+                return a.dtype.type(a / b)
+            else:
+                # This is questionable, but currently a numpy scalar can
+                # be output to a zero dimensional array.
+                return np.divide(a, b, out=out, casting='unsafe')
+
+
+def nanmin(a, axis=None, out=None, keepdims=False):
+    """
+    Return minimum of an array or minimum along an axis, ignoring any NaNs.
+    When all-NaN slices are encountered a ``RuntimeWarning`` is raised and
+    Nan is returned for that slice.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose minimum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the minimum is computed. The default is to compute
+        the minimum of the flattened array.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `a`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    nanmin : ndarray
+        An array with the same shape as `a`, with the specified axis
+        removed.  If `a` is a 0-d array, or if axis is None, an ndarray
+        scalar is returned.  The same dtype as `a` is returned.
+
+    See Also
+    --------
+    nanmax :
+        The maximum value of an array along a given axis, ignoring any NaNs.
+    amin :
+        The minimum value of an array along a given axis, propagating any NaNs.
+    fmin :
+        Element-wise minimum of two arrays, ignoring any NaNs.
+    minimum :
+        Element-wise minimum of two arrays, propagating any NaNs.
+    isnan :
+        Shows which elements are Not a Number (NaN).
+    isfinite:
+        Shows which elements are neither NaN nor infinity.
+
+    amax, fmax, maximum
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Positive infinity is treated as a very large number and negative
+    infinity is treated as a very small (i.e. negative) number.
+
+    If the input has a integer type the function is equivalent to np.min.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanmin(a)
+    1.0
+    >>> np.nanmin(a, axis=0)
+    array([ 1.,  2.])
+    >>> np.nanmin(a, axis=1)
+    array([ 1.,  3.])
+
+    When positive infinity and negative infinity are present:
+
+    >>> np.nanmin([1, 2, np.nan, np.inf])
+    1.0
+    >>> np.nanmin([1, 2, np.nan, np.NINF])
+    -inf
+
+    """
+    if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
+        # Fast, but not safe for subclasses of ndarray
+        res = np.fmin.reduce(a, axis=axis, out=out, keepdims=keepdims)
+        if np.isnan(res).any():
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    else:
+        # Slow, but safe for subclasses of ndarray
+        a, mask = _replace_nan(a, +np.inf)
+        res = np.amin(a, axis=axis, out=out, keepdims=keepdims)
+        if mask is None:
+            return res
+
+        # Check for all-NaN axis
+        mask = np.all(mask, axis=axis, keepdims=keepdims)
+        if np.any(mask):
+            res = _copyto(res, np.nan, mask)
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    return res
+
+
+def nanmax(a, axis=None, out=None, keepdims=False):
+    """
+    Return the maximum of an array or maximum along an axis, ignoring any
+    NaNs.  When all-NaN slices are encountered a ``RuntimeWarning`` is
+    raised and NaN is returned for that slice.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose maximum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the maximum is computed. The default is to compute
+        the maximum of the flattened array.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `a`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    nanmax : ndarray
+        An array with the same shape as `a`, with the specified axis removed.
+        If `a` is a 0-d array, or if axis is None, an ndarray scalar is
+        returned.  The same dtype as `a` is returned.
+
+    See Also
+    --------
+    nanmin :
+        The minimum value of an array along a given axis, ignoring any NaNs.
+    amax :
+        The maximum value of an array along a given axis, propagating any NaNs.
+    fmax :
+        Element-wise maximum of two arrays, ignoring any NaNs.
+    maximum :
+        Element-wise maximum of two arrays, propagating any NaNs.
+    isnan :
+        Shows which elements are Not a Number (NaN).
+    isfinite:
+        Shows which elements are neither NaN nor infinity.
+
+    amin, fmin, minimum
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Positive infinity is treated as a very large number and negative
+    infinity is treated as a very small (i.e. negative) number.
+
+    If the input has a integer type the function is equivalent to np.max.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanmax(a)
+    3.0
+    >>> np.nanmax(a, axis=0)
+    array([ 3.,  2.])
+    >>> np.nanmax(a, axis=1)
+    array([ 2.,  3.])
+
+    When positive infinity and negative infinity are present:
+
+    >>> np.nanmax([1, 2, np.nan, np.NINF])
+    2.0
+    >>> np.nanmax([1, 2, np.nan, np.inf])
+    inf
+
+    """
+    if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
+        # Fast, but not safe for subclasses of ndarray
+        res = np.fmax.reduce(a, axis=axis, out=out, keepdims=keepdims)
+        if np.isnan(res).any():
+            warnings.warn("All-NaN slice encountered", RuntimeWarning)
+    else:
+        # Slow, but safe for subclasses of ndarray
+        a, mask = _replace_nan(a, -np.inf)
+        res = np.amax(a, axis=axis, out=out, keepdims=keepdims)
+        if mask is None:
+            return res
+
+        # Check for all-NaN axis
+        mask = np.all(mask, axis=axis, keepdims=keepdims)
+        if np.any(mask):
+            res = _copyto(res, np.nan, mask)
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    return res
+
+
+def nanargmin(a, axis=None):
+    """
+    Return the indices of the minimum values in the specified axis ignoring
+    NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the results
+    cannot be trusted if a slice contains only NaNs and Infs.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which to operate.  By default flattened input is used.
+
+    Returns
+    -------
+    index_array : ndarray
+        An array of indices or a single index value.
+
+    See Also
+    --------
+    argmin, nanargmax
+
+    Examples
+    --------
+    >>> a = np.array([[np.nan, 4], [2, 3]])
+    >>> np.argmin(a)
+    0
+    >>> np.nanargmin(a)
+    2
+    >>> np.nanargmin(a, axis=0)
+    array([1, 1])
+    >>> np.nanargmin(a, axis=1)
+    array([1, 0])
+
+    """
+    a, mask = _replace_nan(a, np.inf)
+    res = np.argmin(a, axis=axis)
+    if mask is not None:
+        mask = np.all(mask, axis=axis)
+        if np.any(mask):
+            raise ValueError("All-NaN slice encountered")
+    return res
+
+
+def nanargmax(a, axis=None):
+    """
+    Return the indices of the maximum values in the specified axis ignoring
+    NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the
+    results cannot be trusted if a slice contains only NaNs and -Infs.
+
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which to operate.  By default flattened input is used.
+
+    Returns
+    -------
+    index_array : ndarray
+        An array of indices or a single index value.
+
+    See Also
+    --------
+    argmax, nanargmin
+
+    Examples
+    --------
+    >>> a = np.array([[np.nan, 4], [2, 3]])
+    >>> np.argmax(a)
+    0
+    >>> np.nanargmax(a)
+    1
+    >>> np.nanargmax(a, axis=0)
+    array([1, 0])
+    >>> np.nanargmax(a, axis=1)
+    array([1, 1])
+
+    """
+    a, mask = _replace_nan(a, -np.inf)
+    res = np.argmax(a, axis=axis)
+    if mask is not None:
+        mask = np.all(mask, axis=axis)
+        if np.any(mask):
+            raise ValueError("All-NaN slice encountered")
+    return res
+
+
+def nansum(a, axis=None, dtype=None, out=None, keepdims=0):
+    """
+    Return the sum of array elements over a given axis treating Not a
+    Numbers (NaNs) as zero.
+
+    In Numpy versions <= 1.8 Nan is returned for slices that are all-NaN or
+    empty. In later versions zero is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose sum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the sum is computed. The default is to compute the
+        sum of the flattened array.
+    dtype : data-type, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  By default, the dtype of `a` is used.  An
+        exception is when `a` has an integer type with less precision than
+        the platform (u)intp. In that case, the default will be either
+        (u)int32 or (u)int64 depending on whether the platform is 32 or 64
+        bits. For inexact inputs, dtype must be inexact.
+
+        .. versionadded:: 1.8.0
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``. If provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details. The casting of NaN to integer can yield
+        unexpected results.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If True, the axes which are reduced are left in the result as
+        dimensions with size one. With this option, the result will
+        broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    y : ndarray or numpy scalar
+
+    See Also
+    --------
+    numpy.sum : Sum across array propagating NaNs.
+    isnan : Show which elements are NaN.
+    isfinite: Show which elements are not NaN or +/-inf.
+
+    Notes
+    -----
+    If both positive and negative infinity are present, the sum will be Not
+    A Number (NaN).
+
+    Numpy integer arithmetic is modular. If the size of a sum exceeds the
+    size of an integer accumulator, its value will wrap around and the
+    result will be incorrect. Specifying ``dtype=double`` can alleviate
+    that problem.
+
+    Examples
+    --------
+    >>> np.nansum(1)
+    1
+    >>> np.nansum([1])
+    1
+    >>> np.nansum([1, np.nan])
+    1.0
+    >>> a = np.array([[1, 1], [1, np.nan]])
+    >>> np.nansum(a)
+    3.0
+    >>> np.nansum(a, axis=0)
+    array([ 2.,  1.])
+    >>> np.nansum([1, np.nan, np.inf])
+    inf
+    >>> np.nansum([1, np.nan, np.NINF])
+    -inf
+    >>> np.nansum([1, np.nan, np.inf, -np.inf]) # both +/- infinity present
+    nan
+
+    """
+    a, mask = _replace_nan(a, 0)
+    return np.sum(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+
+def nanprod(a, axis=None, dtype=None, out=None, keepdims=0):
+    """
+    Return the product of array elements over a given axis treating Not a
+    Numbers (NaNs) as zero.
+
+    One is returned for slices that are all-NaN or empty.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose sum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the product is computed. The default is to compute
+        the product of the flattened array.
+    dtype : data-type, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  By default, the dtype of `a` is used.  An
+        exception is when `a` has an integer type with less precision than
+        the platform (u)intp. In that case, the default will be either
+        (u)int32 or (u)int64 depending on whether the platform is 32 or 64
+        bits. For inexact inputs, dtype must be inexact.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``. If provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details. The casting of NaN to integer can yield
+        unexpected results.
+    keepdims : bool, optional
+        If True, the axes which are reduced are left in the result as
+        dimensions with size one. With this option, the result will
+        broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    y : ndarray or numpy scalar
+
+    See Also
+    --------
+    numpy.prod : Product across array propagating NaNs.
+    isnan : Show which elements are NaN.
+
+    Notes
+    -----
+    Numpy integer arithmetic is modular. If the size of a product exceeds
+    the size of an integer accumulator, its value will wrap around and the
+    result will be incorrect. Specifying ``dtype=double`` can alleviate
+    that problem.
+
+    Examples
+    --------
+    >>> np.nanprod(1)
+    1
+    >>> np.nanprod([1])
+    1
+    >>> np.nanprod([1, np.nan])
+    1.0
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanprod(a)
+    6.0
+    >>> np.nanprod(a, axis=0)
+    array([ 3.,  2.])
+
+    """
+    a, mask = _replace_nan(a, 1)
+    return np.prod(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+
+def nanmean(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Compute the arithmetic mean along the specified axis, ignoring NaNs.
+
+    Returns the average of the array elements.  The average is taken over
+    the flattened array by default, otherwise over the specified axis.
+    `float64` intermediate and return values are used for integer inputs.
+
+    For all-NaN slices, NaN is returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose mean is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the means are computed. The default is to compute
+        the mean of the flattened array.
+    dtype : data-type, optional
+        Type to use in computing the mean.  For integer inputs, the default
+        is `float64`; for inexact inputs, it is the same as the input
+        dtype.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    m : ndarray, see dtype parameter above
+        If `out=None`, returns a new array containing the mean values,
+        otherwise a reference to the output array is returned. Nan is
+        returned for slices that contain only NaNs.
+
+    See Also
+    --------
+    average : Weighted average
+    mean : Arithmetic mean taken while not ignoring NaNs
+    var, nanvar
+
+    Notes
+    -----
+    The arithmetic mean is the sum of the non-NaN elements along the axis
+    divided by the number of non-NaN elements.
+
+    Note that for floating-point input, the mean is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32`.  Specifying a
+    higher-precision accumulator using the `dtype` keyword can alleviate
+    this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.nanmean(a)
+    2.6666666666666665
+    >>> np.nanmean(a, axis=0)
+    array([ 2.,  4.])
+    >>> np.nanmean(a, axis=1)
+    array([ 1.,  3.5])
+
+    """
+    arr, mask = _replace_nan(a, 0)
+    if mask is None:
+        return np.mean(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+    if dtype is not None:
+        dtype = np.dtype(dtype)
+    if dtype is not None and not issubclass(dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then dtype must be inexact")
+    if out is not None and not issubclass(out.dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then out must be inexact")
+
+    # The warning context speeds things up.
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+        cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims)
+        tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+        avg = _divide_by_count(tot, cnt, out=out)
+
+    isbad = (cnt == 0)
+    if isbad.any():
+        warnings.warn("Mean of empty slice", RuntimeWarning)
+        # NaN is the only possible bad value, so no further
+        # action is needed to handle bad results.
+    return avg
+
+
+def _nanmedian1d(arr1d, overwrite_input=False):
+    """
+    Private function for rank 1 arrays. Compute the median ignoring NaNs.
+    See nanmedian for parameter usage
+    """
+    c = np.isnan(arr1d)
+    s = np.where(c)[0]
+    if s.size == arr1d.size:
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+        return np.nan
+    elif s.size == 0:
+        return np.median(arr1d, overwrite_input=overwrite_input)
+    else:
+        if overwrite_input:
+            x = arr1d
+        else:
+            x = arr1d.copy()
+        # select non-nans at end of array
+        enonan = arr1d[-s.size:][~c[-s.size:]]
+        # fill nans in beginning of array with non-nans of end
+        x[s[:enonan.size]] = enonan
+        # slice nans away
+        return np.median(x[:-s.size], overwrite_input=True)
+
+
+def _nanmedian(a, axis=None, out=None, overwrite_input=False):
+    """
+    Private function that doesn't support extended axis or keepdims.
+    These methods are extended to this function using _ureduce
+    See nanmedian for parameter usage
+
+    """
+    if axis is None or a.ndim == 1:
+        part = a.ravel()
+        if out is None:
+            return _nanmedian1d(part, overwrite_input)
+        else:
+            out[...] = _nanmedian1d(part, overwrite_input)
+            return out
+    else:
+        # for small medians use sort + indexing which is still faster than
+        # apply_along_axis
+        if a.shape[axis] < 400:
+            return _nanmedian_small(a, axis, out, overwrite_input)
+        result = np.apply_along_axis(_nanmedian1d, axis, a, overwrite_input)
+        if out is not None:
+            out[...] = result
+        return result
+
+def _nanmedian_small(a, axis=None, out=None, overwrite_input=False):
+    """
+    sort + indexing median, faster for small medians along multiple
+    dimensions due to the high overhead of apply_along_axis
+
+    see nanmedian for parameter usage
+    """
+    a = np.ma.masked_array(a, np.isnan(a))
+    m = np.ma.median(a, axis=axis, overwrite_input=overwrite_input)
+    for i in range(np.count_nonzero(m.mask.ravel())):
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+    if out is not None:
+        out[...] = m.filled(np.nan)
+        return out
+    return m.filled(np.nan)
+
+def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=False):
+    """
+    Compute the median along the specified axis, while ignoring NaNs.
+
+    Returns the median of the array elements.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the medians are computed. The default
+        is to compute the median along a flattened version of the array.
+        A sequence of axes is supported since version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+       If True, then allow use of memory of input array `a` for
+       calculations. The input array will be modified by the call to
+       `median`. This will save memory when you do not need to preserve
+       the contents of the input array. Treat the input as undefined,
+       but it will probably be fully or partially sorted. Default is
+       False. If `overwrite_input` is ``True`` and `a` is not already an
+       `ndarray`, an error will be raised.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result. If the input contains integers
+        or floats smaller than ``float64``, then the output data-type is
+        ``np.float64``.  Otherwise, the data-type of the output is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, median, percentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the median of ``V`` is the
+    middle value of a sorted copy of ``V``, ``V_sorted`` - i.e.,
+    ``V_sorted[(N-1)/2]``, when ``N`` is odd and the average of the two
+    middle values of ``V_sorted`` when ``N`` is even.
+
+    Examples
+    --------
+    >>> a = np.array([[10.0, 7, 4], [3, 2, 1]])
+    >>> a[0, 1] = np.nan
+    >>> a
+    array([[ 10.,  nan,   4.],
+       [  3.,   2.,   1.]])
+    >>> np.median(a)
+    nan
+    >>> np.nanmedian(a)
+    3.0
+    >>> np.nanmedian(a, axis=0)
+    array([ 6.5,  2.,  2.5])
+    >>> np.median(a, axis=1)
+    array([ 7.,  2.])
+    >>> b = a.copy()
+    >>> np.nanmedian(b, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a==b)
+    >>> b = a.copy()
+    >>> np.nanmedian(b, axis=None, overwrite_input=True)
+    3.0
+    >>> assert not np.all(a==b)
+
+    """
+    a = np.asanyarray(a)
+    # apply_along_axis in _nanmedian doesn't handle empty arrays well,
+    # so deal them upfront
+    if a.size == 0:
+        return np.nanmean(a, axis, out=out, keepdims=keepdims)
+
+    r, k = _ureduce(a, func=_nanmedian, axis=axis, out=out,
+                    overwrite_input=overwrite_input)
+    if keepdims:
+        return r.reshape(k)
+    else:
+        return r
+
+
+def nanpercentile(a, q, axis=None, out=None, overwrite_input=False,
+                  interpolation='linear', keepdims=False):
+    """
+    Compute the qth percentile of the data along the specified axis,
+    while ignoring nan values.
+
+    Returns the qth percentile(s) of the array elements.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    q : float in range of [0,100] (or sequence of floats)
+        Percentile to compute, which must be between 0 and 100
+        inclusive.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the percentiles are computed. The
+        default is to compute the percentile(s) along a flattened
+        version of the array. A sequence of axes is supported since
+        version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array `a` for
+        calculations. The input array will be modified by the call to
+        `percentile`. This will save memory when you do not need to
+        preserve the contents of the input array. In this case you
+        should not make any assumptions about the contents of the input
+        `a` after this function completes -- treat it as undefined.
+        Default is False. If `a` is not already an array, this parameter
+        will have no effect as `a` will be converted to an array
+        internally regardless of the value of this parameter.
+    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``.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original array `a`.
+
+    Returns
+    -------
+    percentile : scalar or ndarray
+        If `q` is a single percentile and `axis=None`, then the result
+        is a scalar. If multiple percentiles are given, first axis of
+        the result corresponds to the percentiles. The other axes are
+        the axes that remain after the reduction of `a`. If the input 
+        contains integers or floats smaller than ``float64``, the output
+        data-type is ``float64``. Otherwise, the output data-type is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    nanmean, nanmedian, percentile, median, mean
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the ``q``-th percentile of
+    ``V`` is the value ``q/100`` of the way from the mimumum to the
+    maximum in in a sorted copy of ``V``. The values and distances of
+    the two nearest neighbors as well as the `interpolation` parameter
+    will determine the percentile if the normalized ranking does not
+    match the location of ``q`` exactly. This function is the same as
+    the median if ``q=50``, the same as the minimum if ``q=0`` and the
+    same as the maximum if ``q=100``.
+
+    Examples
+    --------
+    >>> a = np.array([[10., 7., 4.], [3., 2., 1.]])
+    >>> a[0][1] = np.nan
+    >>> a
+    array([[ 10.,  nan,   4.],
+       [  3.,   2.,   1.]])
+    >>> np.percentile(a, 50)
+    nan
+    >>> np.nanpercentile(a, 50)
+    3.5
+    >>> np.nanpercentile(a, 50, axis=0)
+    array([ 6.5,  2.,   2.5])
+    >>> np.nanpercentile(a, 50, axis=1, keepdims=True)
+    array([[ 7.],
+           [ 2.]])
+    >>> m = np.nanpercentile(a, 50, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.nanpercentile(a, 50, axis=0, out=out)
+    array([ 6.5,  2.,   2.5])
+    >>> m
+    array([ 6.5,  2. ,  2.5])
+
+    >>> b = a.copy()
+    >>> np.nanpercentile(b, 50, axis=1, overwrite_input=True)
+    array([  7.,  2.])
+    >>> assert not np.all(a==b)
+
+    """
+
+    a = np.asanyarray(a)
+    q = np.asanyarray(q)
+    # apply_along_axis in _nanpercentile doesn't handle empty arrays well,
+    # so deal them upfront
+    if a.size == 0:
+        return np.nanmean(a, axis, out=out, keepdims=keepdims)
+
+    r, k = _ureduce(a, func=_nanpercentile, q=q, axis=axis, out=out,
+                    overwrite_input=overwrite_input,
+                    interpolation=interpolation)
+    if keepdims:
+        if q.ndim == 0:
+            return r.reshape(k)
+        else:
+            return r.reshape([len(q)] + k)
+    else:
+        return r
+
+
+def _nanpercentile(a, q, axis=None, out=None, overwrite_input=False,
+                   interpolation='linear', keepdims=False):
+    """
+    Private function that doesn't support extended axis or keepdims.
+    These methods are extended to this function using _ureduce
+    See nanpercentile for parameter usage
+
+    """
+    if axis is None:
+        part = a.ravel()
+        result = _nanpercentile1d(part, q, overwrite_input, interpolation)
+    else:
+        result = np.apply_along_axis(_nanpercentile1d, axis, a, q,
+                                     overwrite_input, interpolation)
+        # apply_along_axis fills in collapsed axis with results.
+        # Move that axis to the beginning to match percentile's
+        # convention.
+        if q.ndim != 0:
+            result = np.rollaxis(result, axis)   
+
+    if out is not None:
+        out[...] = result
+    return result
+
+
+def _nanpercentile1d(arr1d, q, overwrite_input=False, interpolation='linear'):
+    """
+    Private function for rank 1 arrays. Compute percentile ignoring
+    NaNs.
+
+    See nanpercentile for parameter usage
+    """
+    c = np.isnan(arr1d)
+    s = np.where(c)[0]
+    if s.size == arr1d.size:
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+        if q.ndim == 0:
+            return np.nan
+        else:
+            return np.nan * np.ones((len(q),))
+    elif s.size == 0:
+        return np.percentile(arr1d, q, overwrite_input=overwrite_input,
+                             interpolation=interpolation)
+    else:
+        if overwrite_input:
+            x = arr1d
+        else:
+            x = arr1d.copy()
+        # select non-nans at end of array
+        enonan = arr1d[-s.size:][~c[-s.size:]]
+        # fill nans in beginning of array with non-nans of end
+        x[s[:enonan.size]] = enonan
+        # slice nans away
+        return np.percentile(x[:-s.size], q, overwrite_input=True,
+                             interpolation=interpolation)
+
+
+def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the variance along the specified axis, while ignoring NaNs.
+
+    Returns the variance of the array elements, a measure of the spread of
+    a distribution.  The variance is computed for the flattened array by
+    default, otherwise over the specified axis.
+
+    For all-NaN slices or slices with zero degrees of freedom, NaN is
+    returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose variance is desired.  If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the variance is computed.  The default is to compute
+        the variance of the flattened array.
+    dtype : data-type, optional
+        Type to use in computing the variance.  For arrays of integer type
+        the default is `float32`; for arrays of float types it is the same as
+        the array type.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output, but the type is cast if
+        necessary.
+    ddof : int, optional
+        "Delta Degrees of Freedom": the divisor used in the calculation is
+        ``N - ddof``, where ``N`` represents the number of non-NaN
+        elements. By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    variance : ndarray, see dtype parameter above
+        If `out` is None, return a new array containing the variance,
+        otherwise return a reference to the output array. If ddof is >= the
+        number of non-NaN elements in a slice or the slice contains only
+        NaNs, then the result for that slice is NaN.
+
+    See Also
+    --------
+    std : Standard deviation
+    mean : Average
+    var : Variance while not ignoring NaNs
+    nanstd, nanmean
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The variance is the average of the squared deviations from the mean,
+    i.e.,  ``var = mean(abs(x - x.mean())**2)``.
+
+    The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``.
+    If, however, `ddof` is specified, the divisor ``N - ddof`` is used
+    instead.  In standard statistical practice, ``ddof=1`` provides an
+    unbiased estimator of the variance of a hypothetical infinite
+    population.  ``ddof=0`` provides a maximum likelihood estimate of the
+    variance for normally distributed variables.
+
+    Note that for complex numbers, the absolute value is taken before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the variance is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32` (see example
+    below).  Specifying a higher-accuracy accumulator using the ``dtype``
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.var(a)
+    1.5555555555555554
+    >>> np.nanvar(a, axis=0)
+    array([ 1.,  0.])
+    >>> np.nanvar(a, axis=1)
+    array([ 0.,  0.25])
+
+    """
+    arr, mask = _replace_nan(a, 0)
+    if mask is None:
+        return np.var(arr, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                      keepdims=keepdims)
+
+    if dtype is not None:
+        dtype = np.dtype(dtype)
+    if dtype is not None and not issubclass(dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then dtype must be inexact")
+    if out is not None and not issubclass(out.dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then out must be inexact")
+
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+
+        # Compute mean
+        cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=True)
+        avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=True)
+        avg = _divide_by_count(avg, cnt)
+
+        # Compute squared deviation from mean.
+        np.subtract(arr, avg, out=arr, casting='unsafe')
+        arr = _copyto(arr, 0, mask)
+        if issubclass(arr.dtype.type, np.complexfloating):
+            sqr = np.multiply(arr, arr.conj(), out=arr).real
+        else:
+            sqr = np.multiply(arr, arr, out=arr)
+
+        # Compute variance.
+        var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+        if var.ndim < cnt.ndim:
+            # Subclasses of ndarray may ignore keepdims, so check here.
+            cnt = cnt.squeeze(axis)
+        dof = cnt - ddof
+        var = _divide_by_count(var, dof)
+
+    isbad = (dof <= 0)
+    if np.any(isbad):
+        warnings.warn("Degrees of freedom <= 0 for slice.", RuntimeWarning)
+        # NaN, inf, or negative numbers are all possible bad
+        # values, so explicitly replace them with NaN.
+        var = _copyto(var, np.nan, isbad)
+    return var
+
+
+def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the standard deviation along the specified axis, while
+    ignoring NaNs.
+
+    Returns the standard deviation, a measure of the spread of a
+    distribution, of the non-NaN array elements. The standard deviation is
+    computed for the flattened array by default, otherwise over the
+    specified axis.
+
+    For all-NaN slices or slices with zero degrees of freedom, NaN is
+    returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Calculate the standard deviation of the non-NaN values.
+    axis : int, optional
+        Axis along which the standard deviation is computed. The default is
+        to compute the standard deviation of the flattened array.
+    dtype : dtype, optional
+        Type to use in computing the standard deviation. For arrays of
+        integer type the default is float64, for arrays of float types it
+        is the same as the array type.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output but the type (of the
+        calculated values) will be cast if necessary.
+    ddof : int, optional
+        Means Delta Degrees of Freedom.  The divisor used in calculations
+        is ``N - ddof``, where ``N`` represents the number of non-NaN
+        elements.  By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    standard_deviation : ndarray, see dtype parameter above.
+        If `out` is None, return a new array containing the standard
+        deviation, otherwise return a reference to the output array. If
+        ddof is >= the number of non-NaN elements in a slice or the slice
+        contains only NaNs, then the result for that slice is NaN.
+
+    See Also
+    --------
+    var, mean, std
+    nanvar, nanmean
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The standard deviation is the square root of the average of the squared
+    deviations from the mean: ``std = sqrt(mean(abs(x - x.mean())**2))``.
+
+    The average squared deviation is normally calculated as
+    ``x.sum() / N``, where ``N = len(x)``.  If, however, `ddof` is
+    specified, the divisor ``N - ddof`` is used instead. In standard
+    statistical practice, ``ddof=1`` provides an unbiased estimator of the
+    variance of the infinite population. ``ddof=0`` provides a maximum
+    likelihood estimate of the variance for normally distributed variables.
+    The standard deviation computed in this function is the square root of
+    the estimated variance, so even with ``ddof=1``, it will not be an
+    unbiased estimate of the standard deviation per se.
+
+    Note that, for complex numbers, `std` takes the absolute value before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the *std* is computed using the same
+    precision the input has. Depending on the input data, this can cause
+    the results to be inaccurate, especially for float32 (see example
+    below).  Specifying a higher-accuracy accumulator using the `dtype`
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.nanstd(a)
+    1.247219128924647
+    >>> np.nanstd(a, axis=0)
+    array([ 1.,  0.])
+    >>> np.nanstd(a, axis=1)
+    array([ 0.,  0.5])
+
+    """
+    var = nanvar(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                 keepdims=keepdims)
+    if isinstance(var, np.ndarray):
+        std = np.sqrt(var, out=var)
+    else:
+        std = var.dtype.type(np.sqrt(var))
+    return std
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/npyio.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/npyio.py
new file mode 100644
index 0000000000..640f4fa32d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/npyio.py
@@ -0,0 +1,1995 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import re
+import itertools
+import warnings
+import weakref
+from operator import itemgetter
+
+import numpy as np
+from . import format
+from ._datasource import DataSource
+from numpy.core.multiarray import packbits, unpackbits
+from ._iotools import (
+    LineSplitter, NameValidator, StringConverter, ConverterError,
+    ConverterLockError, ConversionWarning, _is_string_like, has_nested_fields,
+    flatten_dtype, easy_dtype, _bytes_to_name
+    )
+
+from numpy.compat import (
+    asbytes, asstr, asbytes_nested, bytes, basestring, unicode
+    )
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+    from future_builtins import map
+
+loads = pickle.loads
+
+__all__ = [
+    'savetxt', 'loadtxt', 'genfromtxt', 'ndfromtxt', 'mafromtxt',
+    'recfromtxt', 'recfromcsv', 'load', 'loads', 'save', 'savez',
+    'savez_compressed', 'packbits', 'unpackbits', 'fromregex', 'DataSource'
+    ]
+
+
+class BagObj(object):
+    """
+    BagObj(obj)
+
+    Convert attribute look-ups to getitems on the object passed in.
+
+    Parameters
+    ----------
+    obj : class instance
+        Object on which attribute look-up is performed.
+
+    Examples
+    --------
+    >>> from numpy.lib.npyio import BagObj as BO
+    >>> class BagDemo(object):
+    ...     def __getitem__(self, key): # An instance of BagObj(BagDemo)
+    ...                                 # will call this method when any
+    ...                                 # attribute look-up is required
+    ...         result = "Doesn't matter what you want, "
+    ...         return result + "you're gonna get this"
+    ...
+    >>> demo_obj = BagDemo()
+    >>> bagobj = BO(demo_obj)
+    >>> bagobj.hello_there
+    "Doesn't matter what you want, you're gonna get this"
+    >>> bagobj.I_can_be_anything
+    "Doesn't matter what you want, you're gonna get this"
+
+    """
+
+    def __init__(self, obj):
+        # Use weakref to make NpzFile objects collectable by refcount
+        self._obj = weakref.proxy(obj)
+
+    def __getattribute__(self, key):
+        try:
+            return object.__getattribute__(self, '_obj')[key]
+        except KeyError:
+            raise AttributeError(key)
+
+    def __dir__(self):
+        """
+        Enables dir(bagobj) to list the files in an NpzFile.
+
+        This also enables tab-completion in an interpreter or IPython.
+        """
+        return object.__getattribute__(self, '_obj').keys()
+
+
+def zipfile_factory(*args, **kwargs):
+    import zipfile
+    kwargs['allowZip64'] = True
+    return zipfile.ZipFile(*args, **kwargs)
+
+
+class NpzFile(object):
+    """
+    NpzFile(fid)
+
+    A dictionary-like object with lazy-loading of files in the zipped
+    archive provided on construction.
+
+    `NpzFile` is used to load files in the NumPy ``.npz`` data archive
+    format. It assumes that files in the archive have a ``.npy`` extension,
+    other files are ignored.
+
+    The arrays and file strings are lazily loaded on either
+    getitem access using ``obj['key']`` or attribute lookup using
+    ``obj.f.key``. A list of all files (without ``.npy`` extensions) can
+    be obtained with ``obj.files`` and the ZipFile object itself using
+    ``obj.zip``.
+
+    Attributes
+    ----------
+    files : list of str
+        List of all files in the archive with a ``.npy`` extension.
+    zip : ZipFile instance
+        The ZipFile object initialized with the zipped archive.
+    f : BagObj instance
+        An object on which attribute can be performed as an alternative
+        to getitem access on the `NpzFile` instance itself.
+    allow_pickle : bool, optional
+        Allow loading pickled data. Default: True
+    pickle_kwargs : dict, optional
+        Additional keyword arguments to pass on to pickle.load.
+        These are only useful when loading object arrays saved on
+        Python 2 when using Python 3.
+
+    Parameters
+    ----------
+    fid : file or str
+        The zipped archive to open. This is either a file-like object
+        or a string containing the path to the archive.
+    own_fid : bool, optional
+        Whether NpzFile should close the file handle.
+        Requires that `fid` is a file-like object.
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+    >>> x = np.arange(10)
+    >>> y = np.sin(x)
+    >>> np.savez(outfile, x=x, y=y)
+    >>> outfile.seek(0)
+
+    >>> npz = np.load(outfile)
+    >>> isinstance(npz, np.lib.io.NpzFile)
+    True
+    >>> npz.files
+    ['y', 'x']
+    >>> npz['x']  # getitem access
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> npz.f.x  # attribute lookup
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+
+    def __init__(self, fid, own_fid=False, allow_pickle=True,
+                 pickle_kwargs=None):
+        # Import is postponed to here since zipfile depends on gzip, an
+        # optional component of the so-called standard library.
+        _zip = zipfile_factory(fid)
+        self._files = _zip.namelist()
+        self.files = []
+        self.allow_pickle = allow_pickle
+        self.pickle_kwargs = pickle_kwargs
+        for x in self._files:
+            if x.endswith('.npy'):
+                self.files.append(x[:-4])
+            else:
+                self.files.append(x)
+        self.zip = _zip
+        self.f = BagObj(self)
+        if own_fid:
+            self.fid = fid
+        else:
+            self.fid = None
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.close()
+
+    def close(self):
+        """
+        Close the file.
+
+        """
+        if self.zip is not None:
+            self.zip.close()
+            self.zip = None
+        if self.fid is not None:
+            self.fid.close()
+            self.fid = None
+        self.f = None  # break reference cycle
+
+    def __del__(self):
+        self.close()
+
+    def __getitem__(self, key):
+        # FIXME: This seems like it will copy strings around
+        #   more than is strictly necessary.  The zipfile
+        #   will read the string and then
+        #   the format.read_array will copy the string
+        #   to another place in memory.
+        #   It would be better if the zipfile could read
+        #   (or at least uncompress) the data
+        #   directly into the array memory.
+        member = 0
+        if key in self._files:
+            member = 1
+        elif key in self.files:
+            member = 1
+            key += '.npy'
+        if member:
+            bytes = self.zip.open(key)
+            magic = bytes.read(len(format.MAGIC_PREFIX))
+            bytes.close()
+            if magic == format.MAGIC_PREFIX:
+                bytes = self.zip.open(key)
+                return format.read_array(bytes,
+                                         allow_pickle=self.allow_pickle,
+                                         pickle_kwargs=self.pickle_kwargs)
+            else:
+                return self.zip.read(key)
+        else:
+            raise KeyError("%s is not a file in the archive" % key)
+
+    def __iter__(self):
+        return iter(self.files)
+
+    def items(self):
+        """
+        Return a list of tuples, with each tuple (filename, array in file).
+
+        """
+        return [(f, self[f]) for f in self.files]
+
+    def iteritems(self):
+        """Generator that returns tuples (filename, array in file)."""
+        for f in self.files:
+            yield (f, self[f])
+
+    def keys(self):
+        """Return files in the archive with a ``.npy`` extension."""
+        return self.files
+
+    def iterkeys(self):
+        """Return an iterator over the files in the archive."""
+        return self.__iter__()
+
+    def __contains__(self, key):
+        return self.files.__contains__(key)
+
+
+def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
+         encoding='ASCII'):
+    """
+    Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.
+
+    Parameters
+    ----------
+    file : file-like object or string
+        The file to read. File-like objects must support the
+        ``seek()`` and ``read()`` methods. Pickled files require that the
+        file-like object support the ``readline()`` method as well.
+    mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional
+        If not None, then memory-map the file, using the given mode (see
+        `numpy.memmap` for a detailed description of the modes).  A
+        memory-mapped array is kept on disk. However, it can be accessed
+        and sliced like any ndarray.  Memory mapping is especially useful
+        for accessing small fragments of large files without reading the
+        entire file into memory.
+    allow_pickle : bool, optional
+        Allow loading pickled object arrays stored in npy files. Reasons for
+        disallowing pickles include security, as loading pickled data can
+        execute arbitrary code. If pickles are disallowed, loading object
+        arrays will fail.
+        Default: True
+    fix_imports : bool, optional
+        Only useful when loading Python 2 generated pickled files on Python 3,
+        which includes npy/npz files containing object arrays. If `fix_imports`
+        is True, pickle will try to map the old Python 2 names to the new names
+        used in Python 3.
+    encoding : str, optional
+        What encoding to use when reading Python 2 strings. Only useful when
+        loading Python 2 generated pickled files on Python 3, which includes
+        npy/npz files containing object arrays. Values other than 'latin1',
+        'ASCII', and 'bytes' are not allowed, as they can corrupt numerical
+        data. Default: 'ASCII'
+
+    Returns
+    -------
+    result : array, tuple, dict, etc.
+        Data stored in the file. For ``.npz`` files, the returned instance
+        of NpzFile class must be closed to avoid leaking file descriptors.
+
+    Raises
+    ------
+    IOError
+        If the input file does not exist or cannot be read.
+    ValueError
+        The file contains an object array, but allow_pickle=False given.
+
+    See Also
+    --------
+    save, savez, savez_compressed, loadtxt
+    memmap : Create a memory-map to an array stored in a file on disk.
+
+    Notes
+    -----
+    - If the file contains pickle data, then whatever object is stored
+      in the pickle is returned.
+    - If the file is a ``.npy`` file, then a single array is returned.
+    - If the file is a ``.npz`` file, then a dictionary-like object is
+      returned, containing ``{filename: array}`` key-value pairs, one for
+      each file in the archive.
+    - If the file is a ``.npz`` file, the returned value supports the
+      context manager protocol in a similar fashion to the open function::
+
+        with load('foo.npz') as data:
+            a = data['a']
+
+      The underlying file descriptor is closed when exiting the 'with'
+      block.
+
+    Examples
+    --------
+    Store data to disk, and load it again:
+
+    >>> np.save('/tmp/123', np.array([[1, 2, 3], [4, 5, 6]]))
+    >>> np.load('/tmp/123.npy')
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    Store compressed data to disk, and load it again:
+
+    >>> a=np.array([[1, 2, 3], [4, 5, 6]])
+    >>> b=np.array([1, 2])
+    >>> np.savez('/tmp/123.npz', a=a, b=b)
+    >>> data = np.load('/tmp/123.npz')
+    >>> data['a']
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> data['b']
+    array([1, 2])
+    >>> data.close()
+
+    Mem-map the stored array, and then access the second row
+    directly from disk:
+
+    >>> X = np.load('/tmp/123.npy', mmap_mode='r')
+    >>> X[1, :]
+    memmap([4, 5, 6])
+
+    """
+    import gzip
+
+    own_fid = False
+    if isinstance(file, basestring):
+        fid = open(file, "rb")
+        own_fid = True
+    else:
+        fid = file
+
+    if encoding not in ('ASCII', 'latin1', 'bytes'):
+        # The 'encoding' value for pickle also affects what encoding
+        # the serialized binary data of Numpy arrays is loaded
+        # in. Pickle does not pass on the encoding information to
+        # Numpy. The unpickling code in numpy.core.multiarray is
+        # written to assume that unicode data appearing where binary
+        # should be is in 'latin1'. 'bytes' is also safe, as is 'ASCII'.
+        #
+        # Other encoding values can corrupt binary data, and we
+        # purposefully disallow them. For the same reason, the errors=
+        # argument is not exposed, as values other than 'strict'
+        # result can similarly silently corrupt numerical data.
+        raise ValueError("encoding must be 'ASCII', 'latin1', or 'bytes'")
+
+    if sys.version_info[0] >= 3:
+        pickle_kwargs = dict(encoding=encoding, fix_imports=fix_imports)
+    else:
+        # Nothing to do on Python 2
+        pickle_kwargs = {}
+
+    try:
+        # Code to distinguish from NumPy binary files and pickles.
+        _ZIP_PREFIX = asbytes('PK\x03\x04')
+        N = len(format.MAGIC_PREFIX)
+        magic = fid.read(N)
+        fid.seek(-N, 1)  # back-up
+        if magic.startswith(_ZIP_PREFIX):
+            # zip-file (assume .npz)
+            # Transfer file ownership to NpzFile
+            tmp = own_fid
+            own_fid = False
+            return NpzFile(fid, own_fid=tmp, allow_pickle=allow_pickle,
+                           pickle_kwargs=pickle_kwargs)
+        elif magic == format.MAGIC_PREFIX:
+            # .npy file
+            if mmap_mode:
+                return format.open_memmap(file, mode=mmap_mode)
+            else:
+                return format.read_array(fid, allow_pickle=allow_pickle,
+                                         pickle_kwargs=pickle_kwargs)
+        else:
+            # Try a pickle
+            if not allow_pickle:
+                raise ValueError("allow_pickle=False, but file does not contain "
+                                 "non-pickled data")
+            try:
+                return pickle.load(fid, **pickle_kwargs)
+            except:
+                raise IOError(
+                    "Failed to interpret file %s as a pickle" % repr(file))
+    finally:
+        if own_fid:
+            fid.close()
+
+
+def save(file, arr, allow_pickle=True, fix_imports=True):
+    """
+    Save an array to a binary file in NumPy ``.npy`` format.
+
+    Parameters
+    ----------
+    file : file or str
+        File or filename to which the data is saved.  If file is a file-object,
+        then the filename is unchanged.  If file is a string, a ``.npy``
+        extension will be appended to the file name if it does not already
+        have one.
+    allow_pickle : bool, optional
+        Allow saving object arrays using Python pickles. Reasons for disallowing
+        pickles include security (loading pickled data can execute arbitrary
+        code) and portability (pickled objects may not be loadable on different
+        Python installations, for example if the stored objects require libraries
+        that are not available, and not all pickled data is compatible between
+        Python 2 and Python 3).
+        Default: True
+    fix_imports : bool, optional
+        Only useful in forcing objects in object arrays on Python 3 to be
+        pickled in a Python 2 compatible way. If `fix_imports` is True, pickle
+        will try to map the new Python 3 names to the old module names used in
+        Python 2, so that the pickle data stream is readable with Python 2.
+    arr : array_like
+        Array data to be saved.
+
+    See Also
+    --------
+    savez : Save several arrays into a ``.npz`` archive
+    savetxt, load
+
+    Notes
+    -----
+    For a description of the ``.npy`` format, see the module docstring
+    of `numpy.lib.format` or the Numpy Enhancement Proposal
+    http://docs.scipy.org/doc/numpy/neps/npy-format.html
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+
+    >>> x = np.arange(10)
+    >>> np.save(outfile, x)
+
+    >>> outfile.seek(0) # Only needed here to simulate closing & reopening file
+    >>> np.load(outfile)
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+    own_fid = False
+    if isinstance(file, basestring):
+        if not file.endswith('.npy'):
+            file = file + '.npy'
+        fid = open(file, "wb")
+        own_fid = True
+    else:
+        fid = file
+
+    if sys.version_info[0] >= 3:
+        pickle_kwargs = dict(fix_imports=fix_imports)
+    else:
+        # Nothing to do on Python 2
+        pickle_kwargs = None
+
+    try:
+        arr = np.asanyarray(arr)
+        format.write_array(fid, arr, allow_pickle=allow_pickle,
+                           pickle_kwargs=pickle_kwargs)
+    finally:
+        if own_fid:
+            fid.close()
+
+
+def savez(file, *args, **kwds):
+    """
+    Save several arrays into a single file in uncompressed ``.npz`` format.
+
+    If arguments are passed in with no keywords, the corresponding variable
+    names, in the ``.npz`` file, are 'arr_0', 'arr_1', etc. If keyword
+    arguments are given, the corresponding variable names, in the ``.npz``
+    file will match the keyword names.
+
+    Parameters
+    ----------
+    file : str or file
+        Either the file name (string) or an open file (file-like object)
+        where the data will be saved. If file is a string, the ``.npz``
+        extension will be appended to the file name if it is not already there.
+    args : Arguments, optional
+        Arrays to save to the file. Since it is not possible for Python to
+        know the names of the arrays outside `savez`, the arrays will be saved
+        with names "arr_0", "arr_1", and so on. These arguments can be any
+        expression.
+    kwds : Keyword arguments, optional
+        Arrays to save to the file. Arrays will be saved in the file with the
+        keyword names.
+
+    Returns
+    -------
+    None
+
+    See Also
+    --------
+    save : Save a single array to a binary file in NumPy format.
+    savetxt : Save an array to a file as plain text.
+    savez_compressed : Save several arrays into a compressed ``.npz`` archive
+
+    Notes
+    -----
+    The ``.npz`` file format is a zipped archive of files named after the
+    variables they contain.  The archive is not compressed and each file
+    in the archive contains one variable in ``.npy`` format. For a
+    description of the ``.npy`` format, see `numpy.lib.format` or the
+    Numpy Enhancement Proposal
+    http://docs.scipy.org/doc/numpy/neps/npy-format.html
+
+    When opening the saved ``.npz`` file with `load` a `NpzFile` object is
+    returned. This is a dictionary-like object which can be queried for
+    its list of arrays (with the ``.files`` attribute), and for the arrays
+    themselves.
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+    >>> x = np.arange(10)
+    >>> y = np.sin(x)
+
+    Using `savez` with \\*args, the arrays are saved with default names.
+
+    >>> np.savez(outfile, x, y)
+    >>> outfile.seek(0) # Only needed here to simulate closing & reopening file
+    >>> npzfile = np.load(outfile)
+    >>> npzfile.files
+    ['arr_1', 'arr_0']
+    >>> npzfile['arr_0']
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    Using `savez` with \\**kwds, the arrays are saved with the keyword names.
+
+    >>> outfile = TemporaryFile()
+    >>> np.savez(outfile, x=x, y=y)
+    >>> outfile.seek(0)
+    >>> npzfile = np.load(outfile)
+    >>> npzfile.files
+    ['y', 'x']
+    >>> npzfile['x']
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+    _savez(file, args, kwds, False)
+
+
+def savez_compressed(file, *args, **kwds):
+    """
+    Save several arrays into a single file in compressed ``.npz`` format.
+
+    If keyword arguments are given, then filenames are taken from the keywords.
+    If arguments are passed in with no keywords, then stored file names are
+    arr_0, arr_1, etc.
+
+    Parameters
+    ----------
+    file : str
+        File name of ``.npz`` file.
+    args : Arguments
+        Function arguments.
+    kwds : Keyword arguments
+        Keywords.
+
+    See Also
+    --------
+    numpy.savez : Save several arrays into an uncompressed ``.npz`` file format
+    numpy.load : Load the files created by savez_compressed.
+
+    """
+    _savez(file, args, kwds, True)
+
+
+def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None):
+    # Import is postponed to here since zipfile depends on gzip, an optional
+    # component of the so-called standard library.
+    import zipfile
+    # Import deferred for startup time improvement
+    import tempfile
+
+    if isinstance(file, basestring):
+        if not file.endswith('.npz'):
+            file = file + '.npz'
+
+    namedict = kwds
+    for i, val in enumerate(args):
+        key = 'arr_%d' % i
+        if key in namedict.keys():
+            raise ValueError(
+                "Cannot use un-named variables and keyword %s" % key)
+        namedict[key] = val
+
+    if compress:
+        compression = zipfile.ZIP_DEFLATED
+    else:
+        compression = zipfile.ZIP_STORED
+
+    zipf = zipfile_factory(file, mode="w", compression=compression)
+
+    # Stage arrays in a temporary file on disk, before writing to zip.
+    fd, tmpfile = tempfile.mkstemp(suffix='-numpy.npy')
+    os.close(fd)
+    try:
+        for key, val in namedict.items():
+            fname = key + '.npy'
+            fid = open(tmpfile, 'wb')
+            try:
+                format.write_array(fid, np.asanyarray(val),
+                                   allow_pickle=allow_pickle,
+                                   pickle_kwargs=pickle_kwargs)
+                fid.close()
+                fid = None
+                zipf.write(tmpfile, arcname=fname)
+            finally:
+                if fid:
+                    fid.close()
+    finally:
+        os.remove(tmpfile)
+
+    zipf.close()
+
+
+def _getconv(dtype):
+    """ Find the correct dtype converter. Adapted from matplotlib """
+
+    def floatconv(x):
+        x.lower()
+        if b'0x' in x:
+            return float.fromhex(asstr(x))
+        return float(x)
+
+    typ = dtype.type
+    if issubclass(typ, np.bool_):
+        return lambda x: bool(int(x))
+    if issubclass(typ, np.uint64):
+        return np.uint64
+    if issubclass(typ, np.int64):
+        return np.int64
+    if issubclass(typ, np.integer):
+        return lambda x: int(float(x))
+    elif issubclass(typ, np.longdouble):
+        return np.longdouble
+    elif issubclass(typ, np.floating):
+        return floatconv
+    elif issubclass(typ, np.complex):
+        return lambda x: complex(asstr(x))
+    elif issubclass(typ, np.bytes_):
+        return bytes
+    else:
+        return str
+
+
+def loadtxt(fname, dtype=float, comments='#', delimiter=None,
+            converters=None, skiprows=0, usecols=None, unpack=False,
+            ndmin=0):
+    """
+    Load data from a text file.
+
+    Each row in the text file must have the same number of values.
+
+    Parameters
+    ----------
+    fname : file or str
+        File, filename, or generator to read.  If the filename extension is
+        ``.gz`` or ``.bz2``, the file is first decompressed. Note that
+        generators should return byte strings for Python 3k.
+    dtype : data-type, optional
+        Data-type of the resulting array; default: float.  If this is a
+        structured data-type, the resulting array will be 1-dimensional, and
+        each row will be interpreted as an element of the array.  In this
+        case, the number of columns used must match the number of fields in
+        the data-type.
+    comments : str or sequence, optional
+        The characters or list of characters used to indicate the start of a
+        comment;
+        default: '#'.
+    delimiter : str, optional
+        The string used to separate values.  By default, this is any
+        whitespace.
+    converters : dict, optional
+        A dictionary mapping column number to a function that will convert
+        that column to a float.  E.g., if column 0 is a date string:
+        ``converters = {0: datestr2num}``.  Converters can also be used to
+        provide a default value for missing data (but see also `genfromtxt`):
+        ``converters = {3: lambda s: float(s.strip() or 0)}``.  Default: None.
+    skiprows : int, optional
+        Skip the first `skiprows` lines; default: 0.
+    usecols : sequence, optional
+        Which columns to read, with 0 being the first.  For example,
+        ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
+        The default, None, results in all columns being read.
+    unpack : bool, optional
+        If True, the returned array is transposed, so that arguments may be
+        unpacked using ``x, y, z = loadtxt(...)``.  When used with a structured
+        data-type, arrays are returned for each field.  Default is False.
+    ndmin : int, optional
+        The returned array will have at least `ndmin` dimensions.
+        Otherwise mono-dimensional axes will be squeezed.
+        Legal values: 0 (default), 1 or 2.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    out : ndarray
+        Data read from the text file.
+
+    See Also
+    --------
+    load, fromstring, fromregex
+    genfromtxt : Load data with missing values handled as specified.
+    scipy.io.loadmat : reads MATLAB data files
+
+    Notes
+    -----
+    This function aims to be a fast reader for simply formatted files.  The
+    `genfromtxt` function provides more sophisticated handling of, e.g.,
+    lines with missing values.
+
+    .. versionadded:: 1.10.0
+
+    The strings produced by the Python float.hex method can be used as
+    input for floats.
+
+    Examples
+    --------
+    >>> from io import StringIO   # StringIO behaves like a file object
+    >>> c = StringIO("0 1\\n2 3")
+    >>> np.loadtxt(c)
+    array([[ 0.,  1.],
+           [ 2.,  3.]])
+
+    >>> d = StringIO("M 21 72\\nF 35 58")
+    >>> np.loadtxt(d, dtype={'names': ('gender', 'age', 'weight'),
+    ...                      'formats': ('S1', 'i4', 'f4')})
+    array([('M', 21, 72.0), ('F', 35, 58.0)],
+          dtype=[('gender', '|S1'), ('age', '<i4'), ('weight', '<f4')])
+
+    >>> c = StringIO("1,0,2\\n3,0,4")
+    >>> x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True)
+    >>> x
+    array([ 1.,  3.])
+    >>> y
+    array([ 2.,  4.])
+
+    """
+    # Type conversions for Py3 convenience
+    if comments is not None:
+        if isinstance(comments, (basestring, bytes)):
+            comments = [asbytes(comments)]
+        else:
+            comments = [asbytes(comment) for comment in comments]
+
+        # Compile regex for comments beforehand
+        comments = (re.escape(comment) for comment in comments)
+        regex_comments = re.compile(asbytes('|').join(comments))
+    user_converters = converters
+    if delimiter is not None:
+        delimiter = asbytes(delimiter)
+    if usecols is not None:
+        usecols = list(usecols)
+
+    fown = False
+    try:
+        if _is_string_like(fname):
+            fown = True
+            if fname.endswith('.gz'):
+                import gzip
+                fh = iter(gzip.GzipFile(fname))
+            elif fname.endswith('.bz2'):
+                import bz2
+                fh = iter(bz2.BZ2File(fname))
+            elif sys.version_info[0] == 2:
+                fh = iter(open(fname, 'U'))
+            else:
+                fh = iter(open(fname))
+        else:
+            fh = iter(fname)
+    except TypeError:
+        raise ValueError('fname must be a string, file handle, or generator')
+    X = []
+
+    def flatten_dtype(dt):
+        """Unpack a structured data-type, and produce re-packing info."""
+        if dt.names is None:
+            # If the dtype is flattened, return.
+            # If the dtype has a shape, the dtype occurs
+            # in the list more than once.
+            shape = dt.shape
+            if len(shape) == 0:
+                return ([dt.base], None)
+            else:
+                packing = [(shape[-1], list)]
+                if len(shape) > 1:
+                    for dim in dt.shape[-2::-1]:
+                        packing = [(dim*packing[0][0], packing*dim)]
+                return ([dt.base] * int(np.prod(dt.shape)), packing)
+        else:
+            types = []
+            packing = []
+            for field in dt.names:
+                tp, bytes = dt.fields[field]
+                flat_dt, flat_packing = flatten_dtype(tp)
+                types.extend(flat_dt)
+                # Avoid extra nesting for subarrays
+                if len(tp.shape) > 0:
+                    packing.extend(flat_packing)
+                else:
+                    packing.append((len(flat_dt), flat_packing))
+            return (types, packing)
+
+    def pack_items(items, packing):
+        """Pack items into nested lists based on re-packing info."""
+        if packing is None:
+            return items[0]
+        elif packing is tuple:
+            return tuple(items)
+        elif packing is list:
+            return list(items)
+        else:
+            start = 0
+            ret = []
+            for length, subpacking in packing:
+                ret.append(pack_items(items[start:start+length], subpacking))
+                start += length
+            return tuple(ret)
+
+    def split_line(line):
+        """Chop off comments, strip, and split at delimiter.
+
+        Note that although the file is opened as text, this function
+        returns bytes.
+
+        """
+        line = asbytes(line)
+        if comments is not None:
+            line = regex_comments.split(asbytes(line), maxsplit=1)[0]
+        line = line.strip(asbytes('\r\n'))
+        if line:
+            return line.split(delimiter)
+        else:
+            return []
+
+    try:
+        # Make sure we're dealing with a proper dtype
+        dtype = np.dtype(dtype)
+        defconv = _getconv(dtype)
+
+        # Skip the first `skiprows` lines
+        for i in range(skiprows):
+            next(fh)
+
+        # Read until we find a line with some values, and use
+        # it to estimate the number of columns, N.
+        first_vals = None
+        try:
+            while not first_vals:
+                first_line = next(fh)
+                first_vals = split_line(first_line)
+        except StopIteration:
+            # End of lines reached
+            first_line = ''
+            first_vals = []
+            warnings.warn('loadtxt: Empty input file: "%s"' % fname)
+        N = len(usecols or first_vals)
+
+        dtype_types, packing = flatten_dtype(dtype)
+        if len(dtype_types) > 1:
+            # We're dealing with a structured array, each field of
+            # the dtype matches a column
+            converters = [_getconv(dt) for dt in dtype_types]
+        else:
+            # All fields have the same dtype
+            converters = [defconv for i in range(N)]
+            if N > 1:
+                packing = [(N, tuple)]
+
+        # By preference, use the converters specified by the user
+        for i, conv in (user_converters or {}).items():
+            if usecols:
+                try:
+                    i = usecols.index(i)
+                except ValueError:
+                    # Unused converter specified
+                    continue
+            converters[i] = conv
+
+        # Parse each line, including the first
+        for i, line in enumerate(itertools.chain([first_line], fh)):
+            vals = split_line(line)
+            if len(vals) == 0:
+                continue
+            if usecols:
+                vals = [vals[i] for i in usecols]
+            if len(vals) != N:
+                line_num = i + skiprows + 1
+                raise ValueError("Wrong number of columns at line %d"
+                                 % line_num)
+
+            # Convert each value according to its column and store
+            items = [conv(val) for (conv, val) in zip(converters, vals)]
+            # Then pack it according to the dtype's nesting
+            items = pack_items(items, packing)
+            X.append(items)
+    finally:
+        if fown:
+            fh.close()
+
+    X = np.array(X, dtype)
+    # Multicolumn data are returned with shape (1, N, M), i.e.
+    # (1, 1, M) for a single row - remove the singleton dimension there
+    if X.ndim == 3 and X.shape[:2] == (1, 1):
+        X.shape = (1, -1)
+
+    # Verify that the array has at least dimensions `ndmin`.
+    # Check correctness of the values of `ndmin`
+    if ndmin not in [0, 1, 2]:
+        raise ValueError('Illegal value of ndmin keyword: %s' % ndmin)
+    # Tweak the size and shape of the arrays - remove extraneous dimensions
+    if X.ndim > ndmin:
+        X = np.squeeze(X)
+    # and ensure we have the minimum number of dimensions asked for
+    # - has to be in this order for the odd case ndmin=1, X.squeeze().ndim=0
+    if X.ndim < ndmin:
+        if ndmin == 1:
+            X = np.atleast_1d(X)
+        elif ndmin == 2:
+            X = np.atleast_2d(X).T
+
+    if unpack:
+        if len(dtype_types) > 1:
+            # For structured arrays, return an array for each field.
+            return [X[field] for field in dtype.names]
+        else:
+            return X.T
+    else:
+        return X
+
+
+def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='',
+            footer='', comments='# '):
+    """
+    Save an array to a text file.
+
+    Parameters
+    ----------
+    fname : filename or file handle
+        If the filename ends in ``.gz``, the file is automatically saved in
+        compressed gzip format.  `loadtxt` understands gzipped files
+        transparently.
+    X : array_like
+        Data to be saved to a text file.
+    fmt : str or sequence of strs, optional
+        A single format (%10.5f), a sequence of formats, or a
+        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 %+.4j %.4e %+.4j %.4e %+.4j'` 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
+    delimiter : str, optional
+        String or character separating columns.
+    newline : str, optional
+        String or character separating lines.
+
+        .. versionadded:: 1.5.0
+    header : str, optional
+        String that will be written at the beginning of the file.
+
+        .. versionadded:: 1.7.0
+    footer : str, optional
+        String that will be written at the end of the file.
+
+        .. versionadded:: 1.7.0
+    comments : str, optional
+        String that will be prepended to the ``header`` and ``footer`` strings,
+        to mark them as comments. Default: '# ',  as expected by e.g.
+        ``numpy.loadtxt``.
+
+        .. versionadded:: 1.7.0
+
+
+    See Also
+    --------
+    save : Save an array to a binary file in NumPy ``.npy`` format
+    savez : Save several arrays into an uncompressed ``.npz`` archive
+    savez_compressed : Save several arrays into a compressed ``.npz`` archive
+
+    Notes
+    -----
+    Further explanation of the `fmt` parameter
+    (``%[flag]width[.precision]specifier``):
+
+    flags:
+        ``-`` : left justify
+
+        ``+`` : Forces to precede result with + or -.
+
+        ``0`` : Left pad the number with zeros instead of space (see width).
+
+    width:
+        Minimum number of characters to be printed. The value is not truncated
+        if it has more characters.
+
+    precision:
+        - For integer specifiers (eg. ``d,i,o,x``), the minimum number of
+          digits.
+        - For ``e, E`` and ``f`` specifiers, the number of digits to print
+          after the decimal point.
+        - For ``g`` and ``G``, the maximum number of significant digits.
+        - For ``s``, the maximum number of characters.
+
+    specifiers:
+        ``c`` : character
+
+        ``d`` or ``i`` : signed decimal integer
+
+        ``e`` or ``E`` : scientific notation with ``e`` or ``E``.
+
+        ``f`` : decimal floating point
+
+        ``g,G`` : use the shorter of ``e,E`` or ``f``
+
+        ``o`` : signed octal
+
+        ``s`` : string of characters
+
+        ``u`` : unsigned decimal integer
+
+        ``x,X`` : unsigned hexadecimal integer
+
+    This explanation of ``fmt`` is not complete, for an exhaustive
+    specification see [1]_.
+
+    References
+    ----------
+    .. [1] `Format Specification Mini-Language
+           <http://docs.python.org/library/string.html#
+           format-specification-mini-language>`_, Python Documentation.
+
+    Examples
+    --------
+    >>> x = y = z = np.arange(0.0,5.0,1.0)
+    >>> np.savetxt('test.out', x, delimiter=',')   # X is an array
+    >>> np.savetxt('test.out', (x,y,z))   # x,y,z equal sized 1D arrays
+    >>> np.savetxt('test.out', x, fmt='%1.4e')   # use exponential notation
+
+    """
+
+    # Py3 conversions first
+    if isinstance(fmt, bytes):
+        fmt = asstr(fmt)
+    delimiter = asstr(delimiter)
+
+    own_fh = False
+    if _is_string_like(fname):
+        own_fh = True
+        if fname.endswith('.gz'):
+            import gzip
+            fh = gzip.open(fname, 'wb')
+        else:
+            if sys.version_info[0] >= 3:
+                fh = open(fname, 'wb')
+            else:
+                fh = open(fname, 'w')
+    elif hasattr(fname, 'write'):
+        fh = fname
+    else:
+        raise ValueError('fname must be a string or file handle')
+
+    try:
+        X = np.asarray(X)
+
+        # Handle 1-dimensional arrays
+        if X.ndim == 1:
+            # Common case -- 1d array of numbers
+            if X.dtype.names is None:
+                X = np.atleast_2d(X).T
+                ncol = 1
+
+            # Complex dtype -- each field indicates a separate column
+            else:
+                ncol = len(X.dtype.descr)
+        else:
+            ncol = X.shape[1]
+
+        iscomplex_X = np.iscomplexobj(X)
+        # `fmt` can be a string with multiple insertion points or a
+        # list of formats.  E.g. '%10.5f\t%10d' or ('%10.5f', '$10d')
+        if type(fmt) in (list, tuple):
+            if len(fmt) != ncol:
+                raise AttributeError('fmt has wrong shape.  %s' % str(fmt))
+            format = asstr(delimiter).join(map(asstr, fmt))
+        elif isinstance(fmt, str):
+            n_fmt_chars = fmt.count('%')
+            error = ValueError('fmt has wrong number of %% formats:  %s' % fmt)
+            if n_fmt_chars == 1:
+                if iscomplex_X:
+                    fmt = [' (%s+%sj)' % (fmt, fmt), ] * ncol
+                else:
+                    fmt = [fmt, ] * ncol
+                format = delimiter.join(fmt)
+            elif iscomplex_X and n_fmt_chars != (2 * ncol):
+                raise error
+            elif ((not iscomplex_X) and n_fmt_chars != ncol):
+                raise error
+            else:
+                format = fmt
+        else:
+            raise ValueError('invalid fmt: %r' % (fmt,))
+
+        if len(header) > 0:
+            header = header.replace('\n', '\n' + comments)
+            fh.write(asbytes(comments + header + newline))
+        if iscomplex_X:
+            for row in X:
+                row2 = []
+                for number in row:
+                    row2.append(number.real)
+                    row2.append(number.imag)
+                fh.write(asbytes(format % tuple(row2) + newline))
+        else:
+            for row in X:
+                try:
+                    fh.write(asbytes(format % tuple(row) + newline))
+                except TypeError:
+                    raise TypeError("Mismatch between array dtype ('%s') and "
+                                    "format specifier ('%s')"
+                                    % (str(X.dtype), format))
+        if len(footer) > 0:
+            footer = footer.replace('\n', '\n' + comments)
+            fh.write(asbytes(comments + footer + newline))
+    finally:
+        if own_fh:
+            fh.close()
+
+
+def fromregex(file, regexp, dtype):
+    """
+    Construct an array from a text file, using regular expression parsing.
+
+    The returned array is always a structured array, and is constructed from
+    all matches of the regular expression in the file. Groups in the regular
+    expression are converted to fields of the structured array.
+
+    Parameters
+    ----------
+    file : str or file
+        File name or file object to read.
+    regexp : str or regexp
+        Regular expression used to parse the file.
+        Groups in the regular expression correspond to fields in the dtype.
+    dtype : dtype or list of dtypes
+        Dtype for the structured array.
+
+    Returns
+    -------
+    output : ndarray
+        The output array, containing the part of the content of `file` that
+        was matched by `regexp`. `output` is always a structured array.
+
+    Raises
+    ------
+    TypeError
+        When `dtype` is not a valid dtype for a structured array.
+
+    See Also
+    --------
+    fromstring, loadtxt
+
+    Notes
+    -----
+    Dtypes for structured arrays can be specified in several forms, but all
+    forms specify at least the data type and field name. For details see
+    `doc.structured_arrays`.
+
+    Examples
+    --------
+    >>> f = open('test.dat', 'w')
+    >>> f.write("1312 foo\\n1534  bar\\n444   qux")
+    >>> f.close()
+
+    >>> regexp = r"(\\d+)\\s+(...)"  # match [digits, whitespace, anything]
+    >>> output = np.fromregex('test.dat', regexp,
+    ...                       [('num', np.int64), ('key', 'S3')])
+    >>> output
+    array([(1312L, 'foo'), (1534L, 'bar'), (444L, 'qux')],
+          dtype=[('num', '<i8'), ('key', '|S3')])
+    >>> output['num']
+    array([1312, 1534,  444], dtype=int64)
+
+    """
+    own_fh = False
+    if not hasattr(file, "read"):
+        file = open(file, 'rb')
+        own_fh = True
+
+    try:
+        if not hasattr(regexp, 'match'):
+            regexp = re.compile(asbytes(regexp))
+        if not isinstance(dtype, np.dtype):
+            dtype = np.dtype(dtype)
+
+        seq = regexp.findall(file.read())
+        if seq and not isinstance(seq[0], tuple):
+            # Only one group is in the regexp.
+            # Create the new array as a single data-type and then
+            #   re-interpret as a single-field structured array.
+            newdtype = np.dtype(dtype[dtype.names[0]])
+            output = np.array(seq, dtype=newdtype)
+            output.dtype = dtype
+        else:
+            output = np.array(seq, dtype=dtype)
+
+        return output
+    finally:
+        if own_fh:
+            file.close()
+
+
+#####--------------------------------------------------------------------------
+#---- --- ASCII functions ---
+#####--------------------------------------------------------------------------
+
+
+def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
+               skip_header=0, skip_footer=0, converters=None,
+               missing_values=None, filling_values=None, usecols=None,
+               names=None, excludelist=None, deletechars=None,
+               replace_space='_', autostrip=False, case_sensitive=True,
+               defaultfmt="f%i", unpack=None, usemask=False, loose=True,
+               invalid_raise=True, max_rows=None):
+    """
+    Load data from a text file, with missing values handled as specified.
+
+    Each line past the first `skip_header` lines is split at the `delimiter`
+    character, and characters following the `comments` character are discarded.
+
+    Parameters
+    ----------
+    fname : file, str, list of str, generator
+        File, filename, list, or generator to read.  If the filename
+        extension is `.gz` or `.bz2`, the file is first decompressed. Mote
+        that generators must return byte strings in Python 3k.  The strings
+        in a list or produced by a generator are treated as lines.
+    dtype : dtype, optional
+        Data type of the resulting array.
+        If None, the dtypes will be determined by the contents of each
+        column, individually.
+    comments : str, optional
+        The character used to indicate the start of a comment.
+        All the characters occurring on a line after a comment are discarded
+    delimiter : str, int, or sequence, optional
+        The string used to separate values.  By default, any consecutive
+        whitespaces act as delimiter.  An integer or sequence of integers
+        can also be provided as width(s) of each field.
+    skiprows : int, optional
+        `skiprows` was removed in numpy 1.10. Please use `skip_header` instead.
+    skip_header : int, optional
+        The number of lines to skip at the beginning of the file.
+    skip_footer : int, optional
+        The number of lines to skip at the end of the file.
+    converters : variable, optional
+        The set of functions that convert the data of a column to a value.
+        The converters can also be used to provide a default value
+        for missing data: ``converters = {3: lambda s: float(s or 0)}``.
+    missing : variable, optional
+        `missing` was removed in numpy 1.10. Please use `missing_values`
+        instead.
+    missing_values : variable, optional
+        The set of strings corresponding to missing data.
+    filling_values : variable, optional
+        The set of values to be used as default when the data are missing.
+    usecols : sequence, optional
+        Which columns to read, with 0 being the first.  For example,
+        ``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns.
+    names : {None, True, str, sequence}, optional
+        If `names` is True, the field names are read from the first valid line
+        after the first `skip_header` lines.
+        If `names` is a sequence or a single-string of comma-separated names,
+        the names will be used to define the field names in a structured dtype.
+        If `names` is None, the names of the dtype fields will be used, if any.
+    excludelist : sequence, optional
+        A list of names to exclude. This list is appended to the default list
+        ['return','file','print']. Excluded names are appended an underscore:
+        for example, `file` would become `file_`.
+    deletechars : str, optional
+        A string combining invalid characters that must be deleted from the
+        names.
+    defaultfmt : str, optional
+        A format used to define default field names, such as "f%i" or "f_%02i".
+    autostrip : bool, optional
+        Whether to automatically strip white spaces from the variables.
+    replace_space : char, optional
+        Character(s) used in replacement of white spaces in the variables
+        names. By default, use a '_'.
+    case_sensitive : {True, False, 'upper', 'lower'}, optional
+        If True, field names are case sensitive.
+        If False or 'upper', field names are converted to upper case.
+        If 'lower', field names are converted to lower case.
+    unpack : bool, optional
+        If True, the returned array is transposed, so that arguments may be
+        unpacked using ``x, y, z = loadtxt(...)``
+    usemask : bool, optional
+        If True, return a masked array.
+        If False, return a regular array.
+    loose : bool, optional
+        If True, do not raise errors for invalid values.
+    invalid_raise : bool, optional
+        If True, an exception is raised if an inconsistency is detected in the
+        number of columns.
+        If False, a warning is emitted and the offending lines are skipped.
+    max_rows : int,  optional
+        The maximum number of rows to read. Must not be used with skip_footer
+        at the same time.  If given, the value must be at least 1. Default is
+        to read the entire file.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    out : ndarray
+        Data read from the text file. If `usemask` is True, this is a
+        masked array.
+
+    See Also
+    --------
+    numpy.loadtxt : equivalent function when no data is missing.
+
+    Notes
+    -----
+    * When spaces are used as delimiters, or when no delimiter has been given
+      as input, there should not be any missing data between two fields.
+    * When the variables are named (either by a flexible dtype or with `names`,
+      there must not be any header in the file (else a ValueError
+      exception is raised).
+    * Individual values are not stripped of spaces by default.
+      When using a custom converter, make sure the function does remove spaces.
+
+    References
+    ----------
+    .. [1] Numpy User Guide, section `I/O with Numpy
+           <http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html>`_.
+
+    Examples
+    ---------
+    >>> from io import StringIO
+    >>> import numpy as np
+
+    Comma delimited file with mixed dtype
+
+    >>> s = StringIO("1,1.3,abcde")
+    >>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
+    ... ('mystring','S5')], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    Using dtype = None
+
+    >>> s.seek(0) # needed for StringIO example only
+    >>> data = np.genfromtxt(s, dtype=None,
+    ... names = ['myint','myfloat','mystring'], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    Specifying dtype and names
+
+    >>> s.seek(0)
+    >>> data = np.genfromtxt(s, dtype="i8,f8,S5",
+    ... names=['myint','myfloat','mystring'], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    An example with fixed-width columns
+
+    >>> s = StringIO("11.3abcde")
+    >>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'],
+    ...     delimiter=[1,3,5])
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('intvar', '<i8'), ('fltvar', '<f8'), ('strvar', '|S5')])
+
+    """
+    if max_rows is not None:
+        if skip_footer:
+            raise ValueError(
+                    "The keywords 'skip_footer' and 'max_rows' can not be "
+                    "specified at the same time.")
+        if max_rows < 1:
+            raise ValueError("'max_rows' must be at least 1.")
+
+    # Py3 data conversions to bytes, for convenience
+    if comments is not None:
+        comments = asbytes(comments)
+    if isinstance(delimiter, unicode):
+        delimiter = asbytes(delimiter)
+    if isinstance(missing_values, (unicode, list, tuple)):
+        missing_values = asbytes_nested(missing_values)
+
+    #
+    if usemask:
+        from numpy.ma import MaskedArray, make_mask_descr
+    # Check the input dictionary of converters
+    user_converters = converters or {}
+    if not isinstance(user_converters, dict):
+        raise TypeError(
+            "The input argument 'converter' should be a valid dictionary "
+            "(got '%s' instead)" % type(user_converters))
+
+    # Initialize the filehandle, the LineSplitter and the NameValidator
+    own_fhd = False
+    try:
+        if isinstance(fname, basestring):
+            if sys.version_info[0] == 2:
+                fhd = iter(np.lib._datasource.open(fname, 'rbU'))
+            else:
+                fhd = iter(np.lib._datasource.open(fname, 'rb'))
+            own_fhd = True
+        else:
+            fhd = iter(fname)
+    except TypeError:
+        raise TypeError(
+            "fname must be a string, filehandle, list of strings, "
+            "or generator. Got %s instead." % type(fname))
+
+    split_line = LineSplitter(delimiter=delimiter, comments=comments,
+                              autostrip=autostrip)._handyman
+    validate_names = NameValidator(excludelist=excludelist,
+                                   deletechars=deletechars,
+                                   case_sensitive=case_sensitive,
+                                   replace_space=replace_space)
+
+    # Skip the first `skip_header` rows
+    for i in range(skip_header):
+        next(fhd)
+
+    # Keep on until we find the first valid values
+    first_values = None
+    try:
+        while not first_values:
+            first_line = next(fhd)
+            if names is True:
+                if comments in first_line:
+                    first_line = (
+                        asbytes('').join(first_line.split(comments)[1:]))
+            first_values = split_line(first_line)
+    except StopIteration:
+        # return an empty array if the datafile is empty
+        first_line = asbytes('')
+        first_values = []
+        warnings.warn('genfromtxt: Empty input file: "%s"' % fname)
+
+    # Should we take the first values as names ?
+    if names is True:
+        fval = first_values[0].strip()
+        if fval in comments:
+            del first_values[0]
+
+    # Check the columns to use: make sure `usecols` is a list
+    if usecols is not None:
+        try:
+            usecols = [_.strip() for _ in usecols.split(",")]
+        except AttributeError:
+            try:
+                usecols = list(usecols)
+            except TypeError:
+                usecols = [usecols, ]
+    nbcols = len(usecols or first_values)
+
+    # Check the names and overwrite the dtype.names if needed
+    if names is True:
+        names = validate_names([_bytes_to_name(_.strip())
+                                for _ in first_values])
+        first_line = asbytes('')
+    elif _is_string_like(names):
+        names = validate_names([_.strip() for _ in names.split(',')])
+    elif names:
+        names = validate_names(names)
+    # Get the dtype
+    if dtype is not None:
+        dtype = easy_dtype(dtype, defaultfmt=defaultfmt, names=names,
+                           excludelist=excludelist,
+                           deletechars=deletechars,
+                           case_sensitive=case_sensitive,
+                           replace_space=replace_space)
+    # Make sure the names is a list (for 2.5)
+    if names is not None:
+        names = list(names)
+
+    if usecols:
+        for (i, current) in enumerate(usecols):
+            # if usecols is a list of names, convert to a list of indices
+            if _is_string_like(current):
+                usecols[i] = names.index(current)
+            elif current < 0:
+                usecols[i] = current + len(first_values)
+        # If the dtype is not None, make sure we update it
+        if (dtype is not None) and (len(dtype) > nbcols):
+            descr = dtype.descr
+            dtype = np.dtype([descr[_] for _ in usecols])
+            names = list(dtype.names)
+        # If `names` is not None, update the names
+        elif (names is not None) and (len(names) > nbcols):
+            names = [names[_] for _ in usecols]
+    elif (names is not None) and (dtype is not None):
+        names = list(dtype.names)
+
+    # Process the missing values ...............................
+    # Rename missing_values for convenience
+    user_missing_values = missing_values or ()
+
+    # Define the list of missing_values (one column: one list)
+    missing_values = [list([asbytes('')]) for _ in range(nbcols)]
+
+    # We have a dictionary: process it field by field
+    if isinstance(user_missing_values, dict):
+        # Loop on the items
+        for (key, val) in user_missing_values.items():
+            # Is the key a string ?
+            if _is_string_like(key):
+                try:
+                    # Transform it into an integer
+                    key = names.index(key)
+                except ValueError:
+                    # We couldn't find it: the name must have been dropped
+                    continue
+            # Redefine the key as needed if it's a column number
+            if usecols:
+                try:
+                    key = usecols.index(key)
+                except ValueError:
+                    pass
+            # Transform the value as a list of string
+            if isinstance(val, (list, tuple)):
+                val = [str(_) for _ in val]
+            else:
+                val = [str(val), ]
+            # Add the value(s) to the current list of missing
+            if key is None:
+                # None acts as default
+                for miss in missing_values:
+                    miss.extend(val)
+            else:
+                missing_values[key].extend(val)
+    # We have a sequence : each item matches a column
+    elif isinstance(user_missing_values, (list, tuple)):
+        for (value, entry) in zip(user_missing_values, missing_values):
+            value = str(value)
+            if value not in entry:
+                entry.append(value)
+    # We have a string : apply it to all entries
+    elif isinstance(user_missing_values, bytes):
+        user_value = user_missing_values.split(asbytes(","))
+        for entry in missing_values:
+            entry.extend(user_value)
+    # We have something else: apply it to all entries
+    else:
+        for entry in missing_values:
+            entry.extend([str(user_missing_values)])
+
+    # Process the filling_values ...............................
+    # Rename the input for convenience
+    user_filling_values = filling_values
+    if user_filling_values is None:
+        user_filling_values = []
+    # Define the default
+    filling_values = [None] * nbcols
+    # We have a dictionary : update each entry individually
+    if isinstance(user_filling_values, dict):
+        for (key, val) in user_filling_values.items():
+            if _is_string_like(key):
+                try:
+                    # Transform it into an integer
+                    key = names.index(key)
+                except ValueError:
+                    # We couldn't find it: the name must have been dropped,
+                    continue
+            # Redefine the key if it's a column number and usecols is defined
+            if usecols:
+                try:
+                    key = usecols.index(key)
+                except ValueError:
+                    pass
+            # Add the value to the list
+            filling_values[key] = val
+    # We have a sequence : update on a one-to-one basis
+    elif isinstance(user_filling_values, (list, tuple)):
+        n = len(user_filling_values)
+        if (n <= nbcols):
+            filling_values[:n] = user_filling_values
+        else:
+            filling_values = user_filling_values[:nbcols]
+    # We have something else : use it for all entries
+    else:
+        filling_values = [user_filling_values] * nbcols
+
+    # Initialize the converters ................................
+    if dtype is None:
+        # Note: we can't use a [...]*nbcols, as we would have 3 times the same
+        # ... converter, instead of 3 different converters.
+        converters = [StringConverter(None, missing_values=miss, default=fill)
+                      for (miss, fill) in zip(missing_values, filling_values)]
+    else:
+        dtype_flat = flatten_dtype(dtype, flatten_base=True)
+        # Initialize the converters
+        if len(dtype_flat) > 1:
+            # Flexible type : get a converter from each dtype
+            zipit = zip(dtype_flat, missing_values, filling_values)
+            converters = [StringConverter(dt, locked=True,
+                                          missing_values=miss, default=fill)
+                          for (dt, miss, fill) in zipit]
+        else:
+            # Set to a default converter (but w/ different missing values)
+            zipit = zip(missing_values, filling_values)
+            converters = [StringConverter(dtype, locked=True,
+                                          missing_values=miss, default=fill)
+                          for (miss, fill) in zipit]
+    # Update the converters to use the user-defined ones
+    uc_update = []
+    for (j, conv) in user_converters.items():
+        # If the converter is specified by column names, use the index instead
+        if _is_string_like(j):
+            try:
+                j = names.index(j)
+                i = j
+            except ValueError:
+                continue
+        elif usecols:
+            try:
+                i = usecols.index(j)
+            except ValueError:
+                # Unused converter specified
+                continue
+        else:
+            i = j
+        # Find the value to test - first_line is not filtered by usecols:
+        if len(first_line):
+            testing_value = first_values[j]
+        else:
+            testing_value = None
+        converters[i].update(conv, locked=True,
+                             testing_value=testing_value,
+                             default=filling_values[i],
+                             missing_values=missing_values[i],)
+        uc_update.append((i, conv))
+    # Make sure we have the corrected keys in user_converters...
+    user_converters.update(uc_update)
+
+    # Fixme: possible error as following variable never used.
+    #miss_chars = [_.missing_values for _ in converters]
+
+    # Initialize the output lists ...
+    # ... rows
+    rows = []
+    append_to_rows = rows.append
+    # ... masks
+    if usemask:
+        masks = []
+        append_to_masks = masks.append
+    # ... invalid
+    invalid = []
+    append_to_invalid = invalid.append
+
+    # Parse each line
+    for (i, line) in enumerate(itertools.chain([first_line, ], fhd)):
+        values = split_line(line)
+        nbvalues = len(values)
+        # Skip an empty line
+        if nbvalues == 0:
+            continue
+        if usecols:
+            # Select only the columns we need
+            try:
+                values = [values[_] for _ in usecols]
+            except IndexError:
+                append_to_invalid((i + skip_header + 1, nbvalues))
+                continue
+        elif nbvalues != nbcols:
+            append_to_invalid((i + skip_header + 1, nbvalues))
+            continue
+        # Store the values
+        append_to_rows(tuple(values))
+        if usemask:
+            append_to_masks(tuple([v.strip() in m
+                                   for (v, m) in zip(values,
+                                                     missing_values)]))
+        if len(rows) == max_rows:
+            break
+
+    if own_fhd:
+        fhd.close()
+
+    # Upgrade the converters (if needed)
+    if dtype is None:
+        for (i, converter) in enumerate(converters):
+            current_column = [itemgetter(i)(_m) for _m in rows]
+            try:
+                converter.iterupgrade(current_column)
+            except ConverterLockError:
+                errmsg = "Converter #%i is locked and cannot be upgraded: " % i
+                current_column = map(itemgetter(i), rows)
+                for (j, value) in enumerate(current_column):
+                    try:
+                        converter.upgrade(value)
+                    except (ConverterError, ValueError):
+                        errmsg += "(occurred line #%i for value '%s')"
+                        errmsg %= (j + 1 + skip_header, value)
+                        raise ConverterError(errmsg)
+
+    # Check that we don't have invalid values
+    nbinvalid = len(invalid)
+    if nbinvalid > 0:
+        nbrows = len(rows) + nbinvalid - skip_footer
+        # Construct the error message
+        template = "    Line #%%i (got %%i columns instead of %i)" % nbcols
+        if skip_footer > 0:
+            nbinvalid_skipped = len([_ for _ in invalid
+                                     if _[0] > nbrows + skip_header])
+            invalid = invalid[:nbinvalid - nbinvalid_skipped]
+            skip_footer -= nbinvalid_skipped
+#
+#            nbrows -= skip_footer
+#            errmsg = [template % (i, nb)
+#                      for (i, nb) in invalid if i < nbrows]
+#        else:
+        errmsg = [template % (i, nb)
+                  for (i, nb) in invalid]
+        if len(errmsg):
+            errmsg.insert(0, "Some errors were detected !")
+            errmsg = "\n".join(errmsg)
+            # Raise an exception ?
+            if invalid_raise:
+                raise ValueError(errmsg)
+            # Issue a warning ?
+            else:
+                warnings.warn(errmsg, ConversionWarning)
+
+    # Strip the last skip_footer data
+    if skip_footer > 0:
+        rows = rows[:-skip_footer]
+        if usemask:
+            masks = masks[:-skip_footer]
+
+    # Convert each value according to the converter:
+    # We want to modify the list in place to avoid creating a new one...
+    if loose:
+        rows = list(
+            zip(*[[conv._loose_call(_r) for _r in map(itemgetter(i), rows)]
+                  for (i, conv) in enumerate(converters)]))
+    else:
+        rows = list(
+            zip(*[[conv._strict_call(_r) for _r in map(itemgetter(i), rows)]
+                  for (i, conv) in enumerate(converters)]))
+
+    # Reset the dtype
+    data = rows
+    if dtype is None:
+        # Get the dtypes from the types of the converters
+        column_types = [conv.type for conv in converters]
+        # Find the columns with strings...
+        strcolidx = [i for (i, v) in enumerate(column_types)
+                     if v in (type('S'), np.string_)]
+        # ... and take the largest number of chars.
+        for i in strcolidx:
+            column_types[i] = "|S%i" % max(len(row[i]) for row in data)
+        #
+        if names is None:
+            # If the dtype is uniform, don't define names, else use ''
+            base = set([c.type for c in converters if c._checked])
+            if len(base) == 1:
+                (ddtype, mdtype) = (list(base)[0], np.bool)
+            else:
+                ddtype = [(defaultfmt % i, dt)
+                          for (i, dt) in enumerate(column_types)]
+                if usemask:
+                    mdtype = [(defaultfmt % i, np.bool)
+                              for (i, dt) in enumerate(column_types)]
+        else:
+            ddtype = list(zip(names, column_types))
+            mdtype = list(zip(names, [np.bool] * len(column_types)))
+        output = np.array(data, dtype=ddtype)
+        if usemask:
+            outputmask = np.array(masks, dtype=mdtype)
+    else:
+        # Overwrite the initial dtype names if needed
+        if names and dtype.names:
+            dtype.names = names
+        # Case 1. We have a structured type
+        if len(dtype_flat) > 1:
+            # Nested dtype, eg [('a', int), ('b', [('b0', int), ('b1', 'f4')])]
+            # First, create the array using a flattened dtype:
+            # [('a', int), ('b1', int), ('b2', float)]
+            # Then, view the array using the specified dtype.
+            if 'O' in (_.char for _ in dtype_flat):
+                if has_nested_fields(dtype):
+                    raise NotImplementedError(
+                        "Nested fields involving objects are not supported...")
+                else:
+                    output = np.array(data, dtype=dtype)
+            else:
+                rows = np.array(data, dtype=[('', _) for _ in dtype_flat])
+                output = rows.view(dtype)
+            # Now, process the rowmasks the same way
+            if usemask:
+                rowmasks = np.array(
+                    masks, dtype=np.dtype([('', np.bool) for t in dtype_flat]))
+                # Construct the new dtype
+                mdtype = make_mask_descr(dtype)
+                outputmask = rowmasks.view(mdtype)
+        # Case #2. We have a basic dtype
+        else:
+            # We used some user-defined converters
+            if user_converters:
+                ishomogeneous = True
+                descr = []
+                for i, ttype in enumerate([conv.type for conv in converters]):
+                    # Keep the dtype of the current converter
+                    if i in user_converters:
+                        ishomogeneous &= (ttype == dtype.type)
+                        if ttype == np.string_:
+                            ttype = "|S%i" % max(len(row[i]) for row in data)
+                        descr.append(('', ttype))
+                    else:
+                        descr.append(('', dtype))
+                # So we changed the dtype ?
+                if not ishomogeneous:
+                    # We have more than one field
+                    if len(descr) > 1:
+                        dtype = np.dtype(descr)
+                    # We have only one field: drop the name if not needed.
+                    else:
+                        dtype = np.dtype(ttype)
+            #
+            output = np.array(data, dtype)
+            if usemask:
+                if dtype.names:
+                    mdtype = [(_, np.bool) for _ in dtype.names]
+                else:
+                    mdtype = np.bool
+                outputmask = np.array(masks, dtype=mdtype)
+    # Try to take care of the missing data we missed
+    names = output.dtype.names
+    if usemask and names:
+        for (name, conv) in zip(names or (), converters):
+            missing_values = [conv(_) for _ in conv.missing_values
+                              if _ != asbytes('')]
+            for mval in missing_values:
+                outputmask[name] |= (output[name] == mval)
+    # Construct the final array
+    if usemask:
+        output = output.view(MaskedArray)
+        output._mask = outputmask
+    if unpack:
+        return output.squeeze().T
+    return output.squeeze()
+
+
+def ndfromtxt(fname, **kwargs):
+    """
+    Load ASCII data stored in a file and return it as a single array.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function.
+
+    """
+    kwargs['usemask'] = False
+    return genfromtxt(fname, **kwargs)
+
+
+def mafromtxt(fname, **kwargs):
+    """
+    Load ASCII data stored in a text file and return a masked array.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function to load ASCII data.
+
+    """
+    kwargs['usemask'] = True
+    return genfromtxt(fname, **kwargs)
+
+
+def recfromtxt(fname, **kwargs):
+    """
+    Load ASCII data from a file and return it in a record array.
+
+    If ``usemask=False`` a standard `recarray` is returned,
+    if ``usemask=True`` a MaskedRecords array is returned.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function
+
+    Notes
+    -----
+    By default, `dtype` is None, which means that the data-type of the output
+    array will be determined from the data.
+
+    """
+    kwargs.setdefault("dtype", None)
+    usemask = kwargs.get('usemask', False)
+    output = genfromtxt(fname, **kwargs)
+    if usemask:
+        from numpy.ma.mrecords import MaskedRecords
+        output = output.view(MaskedRecords)
+    else:
+        output = output.view(np.recarray)
+    return output
+
+
+def recfromcsv(fname, **kwargs):
+    """
+    Load ASCII data stored in a comma-separated file.
+
+    The returned array is a record array (if ``usemask=False``, see
+    `recarray`) or a masked record array (if ``usemask=True``,
+    see `ma.mrecords.MaskedRecords`).
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function to load ASCII data.
+
+    Notes
+    -----
+    By default, `dtype` is None, which means that the data-type of the output
+    array will be determined from the data.
+
+    """
+    # Set default kwargs for genfromtxt as relevant to csv import.
+    kwargs.setdefault("case_sensitive", "lower")
+    kwargs.setdefault("names", True)
+    kwargs.setdefault("delimiter", ",")
+    kwargs.setdefault("dtype", None)
+    output = genfromtxt(fname, **kwargs)
+
+    usemask = kwargs.get("usemask", False)
+    if usemask:
+        from numpy.ma.mrecords import MaskedRecords
+        output = output.view(MaskedRecords)
+    else:
+        output = output.view(np.recarray)
+    return output
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.py
new file mode 100644
index 0000000000..189e59154d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.py
@@ -0,0 +1,1278 @@
+"""
+Functions to operate on polynomials.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['poly', 'roots', 'polyint', 'polyder', 'polyadd',
+           'polysub', 'polymul', 'polydiv', 'polyval', 'poly1d',
+           'polyfit', 'RankWarning']
+
+import re
+import warnings
+import numpy.core.numeric as NX
+
+from numpy.core import (isscalar, abs, finfo, atleast_1d, hstack, dot, array,
+                        ones)
+from numpy.lib.twodim_base import diag, vander
+from numpy.lib.function_base import trim_zeros, sort_complex
+from numpy.lib.type_check import iscomplex, real, imag, mintypecode
+from numpy.linalg import eigvals, lstsq, inv
+
+class RankWarning(UserWarning):
+    """
+    Issued by `polyfit` when the Vandermonde matrix is rank deficient.
+
+    For more information, a way to suppress the warning, and an example of
+    `RankWarning` being issued, see `polyfit`.
+
+    """
+    pass
+
+def poly(seq_of_zeros):
+    """
+    Find the coefficients of a polynomial with the given sequence of roots.
+
+    Returns the coefficients of the polynomial whose leading coefficient
+    is one for the given sequence of zeros (multiple roots must be included
+    in the sequence as many times as their multiplicity; see Examples).
+    A square matrix (or array, which will be treated as a matrix) can also
+    be given, in which case the coefficients of the characteristic polynomial
+    of the matrix are returned.
+
+    Parameters
+    ----------
+    seq_of_zeros : array_like, shape (N,) or (N, N)
+        A sequence of polynomial roots, or a square array or matrix object.
+
+    Returns
+    -------
+    c : ndarray
+        1D array of polynomial coefficients from highest to lowest degree:
+
+        ``c[0] * x**(N) + c[1] * x**(N-1) + ... + c[N-1] * x + c[N]``
+        where c[0] always equals 1.
+
+    Raises
+    ------
+    ValueError
+        If input is the wrong shape (the input must be a 1-D or square
+        2-D array).
+
+    See Also
+    --------
+    polyval : Compute polynomial values.
+    roots : Return the roots of a polynomial.
+    polyfit : Least squares polynomial fit.
+    poly1d : A one-dimensional polynomial class.
+
+    Notes
+    -----
+    Specifying the roots of a polynomial still leaves one degree of
+    freedom, typically represented by an undetermined leading
+    coefficient. [1]_ In the case of this function, that coefficient -
+    the first one in the returned array - is always taken as one. (If
+    for some reason you have one other point, the only automatic way
+    presently to leverage that information is to use ``polyfit``.)
+
+    The characteristic polynomial, :math:`p_a(t)`, of an `n`-by-`n`
+    matrix **A** is given by
+
+        :math:`p_a(t) = \\mathrm{det}(t\\, \\mathbf{I} - \\mathbf{A})`,
+
+    where **I** is the `n`-by-`n` identity matrix. [2]_
+
+    References
+    ----------
+    .. [1] M. Sullivan and M. Sullivan, III, "Algebra and Trignometry,
+       Enhanced With Graphing Utilities," Prentice-Hall, pg. 318, 1996.
+
+    .. [2] G. Strang, "Linear Algebra and Its Applications, 2nd Edition,"
+       Academic Press, pg. 182, 1980.
+
+    Examples
+    --------
+    Given a sequence of a polynomial's zeros:
+
+    >>> np.poly((0, 0, 0)) # Multiple root example
+    array([1, 0, 0, 0])
+
+    The line above represents z**3 + 0*z**2 + 0*z + 0.
+
+    >>> np.poly((-1./2, 0, 1./2))
+    array([ 1.  ,  0.  , -0.25,  0.  ])
+
+    The line above represents z**3 - z/4
+
+    >>> np.poly((np.random.random(1.)[0], 0, np.random.random(1.)[0]))
+    array([ 1.        , -0.77086955,  0.08618131,  0.        ]) #random
+
+    Given a square array object:
+
+    >>> P = np.array([[0, 1./3], [-1./2, 0]])
+    >>> np.poly(P)
+    array([ 1.        ,  0.        ,  0.16666667])
+
+    Or a square matrix object:
+
+    >>> np.poly(np.matrix(P))
+    array([ 1.        ,  0.        ,  0.16666667])
+
+    Note how in all cases the leading coefficient is always 1.
+
+    """
+    seq_of_zeros = atleast_1d(seq_of_zeros)
+    sh = seq_of_zeros.shape
+
+    if len(sh) == 2 and sh[0] == sh[1] and sh[0] != 0:
+        seq_of_zeros = eigvals(seq_of_zeros)
+    elif len(sh) == 1:
+        dt = seq_of_zeros.dtype
+        # Let object arrays slip through, e.g. for arbitrary precision
+        if dt != object:
+            seq_of_zeros = seq_of_zeros.astype(mintypecode(dt.char))
+    else:
+        raise ValueError("input must be 1d or non-empty square 2d array.")
+
+    if len(seq_of_zeros) == 0:
+        return 1.0
+    dt = seq_of_zeros.dtype
+    a = ones((1,), dtype=dt)
+    for k in range(len(seq_of_zeros)):
+        a = NX.convolve(a, array([1, -seq_of_zeros[k]], dtype=dt),
+                        mode='full')
+
+    if issubclass(a.dtype.type, NX.complexfloating):
+        # if complex roots are all complex conjugates, the roots are real.
+        roots = NX.asarray(seq_of_zeros, complex)
+        pos_roots = sort_complex(NX.compress(roots.imag > 0, roots))
+        neg_roots = NX.conjugate(sort_complex(
+                                        NX.compress(roots.imag < 0, roots)))
+        if (len(pos_roots) == len(neg_roots) and
+                NX.alltrue(neg_roots == pos_roots)):
+            a = a.real.copy()
+
+    return a
+
+def roots(p):
+    """
+    Return the roots of a polynomial with coefficients given in p.
+
+    The values in the rank-1 array `p` are coefficients of a polynomial.
+    If the length of `p` is n+1 then the polynomial is described by::
+
+      p[0] * x**n + p[1] * x**(n-1) + ... + p[n-1]*x + p[n]
+
+    Parameters
+    ----------
+    p : array_like
+        Rank-1 array of polynomial coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        An array containing the complex roots of the polynomial.
+
+    Raises
+    ------
+    ValueError
+        When `p` cannot be converted to a rank-1 array.
+
+    See also
+    --------
+    poly : Find the coefficients of a polynomial with a given sequence
+           of roots.
+    polyval : Compute polynomial values.
+    polyfit : Least squares polynomial fit.
+    poly1d : A one-dimensional polynomial class.
+
+    Notes
+    -----
+    The algorithm relies on computing the eigenvalues of the
+    companion matrix [1]_.
+
+    References
+    ----------
+    .. [1] R. A. Horn & C. R. Johnson, *Matrix Analysis*.  Cambridge, UK:
+        Cambridge University Press, 1999, pp. 146-7.
+
+    Examples
+    --------
+    >>> coeff = [3.2, 2, 1]
+    >>> np.roots(coeff)
+    array([-0.3125+0.46351241j, -0.3125-0.46351241j])
+
+    """
+    # If input is scalar, this makes it an array
+    p = atleast_1d(p)
+    if len(p.shape) != 1:
+        raise ValueError("Input must be a rank-1 array.")
+
+    # find non-zero array entries
+    non_zero = NX.nonzero(NX.ravel(p))[0]
+
+    # Return an empty array if polynomial is all zeros
+    if len(non_zero) == 0:
+        return NX.array([])
+
+    # find the number of trailing zeros -- this is the number of roots at 0.
+    trailing_zeros = len(p) - non_zero[-1] - 1
+
+    # strip leading and trailing zeros
+    p = p[int(non_zero[0]):int(non_zero[-1])+1]
+
+    # casting: if incoming array isn't floating point, make it floating point.
+    if not issubclass(p.dtype.type, (NX.floating, NX.complexfloating)):
+        p = p.astype(float)
+
+    N = len(p)
+    if N > 1:
+        # build companion matrix and find its eigenvalues (the roots)
+        A = diag(NX.ones((N-2,), p.dtype), -1)
+        A[0,:] = -p[1:] / p[0]
+        roots = eigvals(A)
+    else:
+        roots = NX.array([])
+
+    # tack any zeros onto the back of the array
+    roots = hstack((roots, NX.zeros(trailing_zeros, roots.dtype)))
+    return roots
+
+def polyint(p, m=1, k=None):
+    """
+    Return an antiderivative (indefinite integral) of a polynomial.
+
+    The returned order `m` antiderivative `P` of polynomial `p` satisfies
+    :math:`\\frac{d^m}{dx^m}P(x) = p(x)` and is defined up to `m - 1`
+    integration constants `k`. The constants determine the low-order
+    polynomial part
+
+    .. math:: \\frac{k_{m-1}}{0!} x^0 + \\ldots + \\frac{k_0}{(m-1)!}x^{m-1}
+
+    of `P` so that :math:`P^{(j)}(0) = k_{m-j-1}`.
+
+    Parameters
+    ----------
+    p : array_like or poly1d
+        Polynomial to differentiate.
+        A sequence is interpreted as polynomial coefficients, see `poly1d`.
+    m : int, optional
+        Order of the antiderivative. (Default: 1)
+    k : list of `m` scalars or scalar, optional
+        Integration constants. They are given in the order of integration:
+        those corresponding to highest-order terms come first.
+
+        If ``None`` (default), all constants are assumed to be zero.
+        If `m = 1`, a single scalar can be given instead of a list.
+
+    See Also
+    --------
+    polyder : derivative of a polynomial
+    poly1d.integ : equivalent method
+
+    Examples
+    --------
+    The defining property of the antiderivative:
+
+    >>> p = np.poly1d([1,1,1])
+    >>> P = np.polyint(p)
+    >>> P
+    poly1d([ 0.33333333,  0.5       ,  1.        ,  0.        ])
+    >>> np.polyder(P) == p
+    True
+
+    The integration constants default to zero, but can be specified:
+
+    >>> P = np.polyint(p, 3)
+    >>> P(0)
+    0.0
+    >>> np.polyder(P)(0)
+    0.0
+    >>> np.polyder(P, 2)(0)
+    0.0
+    >>> P = np.polyint(p, 3, k=[6,5,3])
+    >>> P
+    poly1d([ 0.01666667,  0.04166667,  0.16666667,  3. ,  5. ,  3. ])
+
+    Note that 3 = 6 / 2!, and that the constants are given in the order of
+    integrations. Constant of the highest-order polynomial term comes first:
+
+    >>> np.polyder(P, 2)(0)
+    6.0
+    >>> np.polyder(P, 1)(0)
+    5.0
+    >>> P(0)
+    3.0
+
+    """
+    m = int(m)
+    if m < 0:
+        raise ValueError("Order of integral must be positive (see polyder)")
+    if k is None:
+        k = NX.zeros(m, float)
+    k = atleast_1d(k)
+    if len(k) == 1 and m > 1:
+        k = k[0]*NX.ones(m, float)
+    if len(k) < m:
+        raise ValueError(
+              "k must be a scalar or a rank-1 array of length 1 or >m.")
+
+    truepoly = isinstance(p, poly1d)
+    p = NX.asarray(p)
+    if m == 0:
+        if truepoly:
+            return poly1d(p)
+        return p
+    else:
+        # Note: this must work also with object and integer arrays
+        y = NX.concatenate((p.__truediv__(NX.arange(len(p), 0, -1)), [k[0]]))
+        val = polyint(y, m - 1, k=k[1:])
+        if truepoly:
+            return poly1d(val)
+        return val
+
+def polyder(p, m=1):
+    """
+    Return the derivative of the specified order of a polynomial.
+
+    Parameters
+    ----------
+    p : poly1d or sequence
+        Polynomial to differentiate.
+        A sequence is interpreted as polynomial coefficients, see `poly1d`.
+    m : int, optional
+        Order of differentiation (default: 1)
+
+    Returns
+    -------
+    der : poly1d
+        A new polynomial representing the derivative.
+
+    See Also
+    --------
+    polyint : Anti-derivative of a polynomial.
+    poly1d : Class for one-dimensional polynomials.
+
+    Examples
+    --------
+    The derivative of the polynomial :math:`x^3 + x^2 + x^1 + 1` is:
+
+    >>> p = np.poly1d([1,1,1,1])
+    >>> p2 = np.polyder(p)
+    >>> p2
+    poly1d([3, 2, 1])
+
+    which evaluates to:
+
+    >>> p2(2.)
+    17.0
+
+    We can verify this, approximating the derivative with
+    ``(f(x + h) - f(x))/h``:
+
+    >>> (p(2. + 0.001) - p(2.)) / 0.001
+    17.007000999997857
+
+    The fourth-order derivative of a 3rd-order polynomial is zero:
+
+    >>> np.polyder(p, 2)
+    poly1d([6, 2])
+    >>> np.polyder(p, 3)
+    poly1d([6])
+    >>> np.polyder(p, 4)
+    poly1d([ 0.])
+
+    """
+    m = int(m)
+    if m < 0:
+        raise ValueError("Order of derivative must be positive (see polyint)")
+
+    truepoly = isinstance(p, poly1d)
+    p = NX.asarray(p)
+    n = len(p) - 1
+    y = p[:-1] * NX.arange(n, 0, -1)
+    if m == 0:
+        val = p
+    else:
+        val = polyder(y, m - 1)
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
+    """
+    Least squares polynomial fit.
+
+    Fit a polynomial ``p(x) = p[0] * x**deg + ... + p[deg]`` of degree `deg`
+    to points `(x, y)`. Returns a vector of coefficients `p` that minimises
+    the squared error.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int
+        Degree of the fitting polynomial
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (M,), optional
+        Weights to apply to the y-coordinates of the sample points. For
+        gaussian uncertainties, use 1/sigma (not 1/sigma**2).
+    cov : bool, optional
+        Return the estimate and the covariance matrix of the estimate
+        If full is True, then cov is not returned.
+
+    Returns
+    -------
+    p : ndarray, shape (M,) or (M, K)
+        Polynomial coefficients, highest power first.  If `y` was 2-D, the
+        coefficients for `k`-th data set are in ``p[:,k]``.
+
+    residuals, rank, singular_values, rcond :
+        Present only if `full` = True.  Residuals of the least-squares fit,
+        the effective rank of the scaled Vandermonde coefficient matrix,
+        its singular values, and the specified value of `rcond`. For more
+        details, see `linalg.lstsq`.
+
+    V : ndarray, shape (M,M) or (M,M,K)
+        Present only if `full` = False and `cov`=True.  The covariance
+        matrix of the polynomial coefficient estimates.  The diagonal of
+        this matrix are the variance estimates for each coefficient.  If y
+        is a 2-D array, then the covariance matrix for the `k`-th data set
+        are in ``V[:,:,k]``
+
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.
+
+        The warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', np.RankWarning)
+
+    See Also
+    --------
+    polyval : Compute polynomial values.
+    linalg.lstsq : Computes a least-squares fit.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution minimizes the squared error
+
+    .. math ::
+        E = \\sum_{j=0}^k |p(x_j) - y_j|^2
+
+    in the equations::
+
+        x[0]**n * p[0] + ... + x[0] * p[n-1] + p[n] = y[0]
+        x[1]**n * p[0] + ... + x[1] * p[n-1] + p[n] = y[1]
+        ...
+        x[k]**n * p[0] + ... + x[k] * p[n-1] + p[n] = y[k]
+
+    The coefficient matrix of the coefficients `p` is a Vandermonde matrix.
+
+    `polyfit` issues a `RankWarning` when the least-squares fit is badly
+    conditioned. This implies that the best fit is not well-defined due
+    to numerical error. The results may be improved by lowering the polynomial
+    degree or by replacing `x` by `x` - `x`.mean(). The `rcond` parameter
+    can also be set to a value smaller than its default, but the resulting
+    fit may be spurious: including contributions from the small singular
+    values can add numerical noise to the result.
+
+    Note that fitting polynomial coefficients is inherently badly conditioned
+    when the degree of the polynomial is large or the interval of sample points
+    is badly centered. The quality of the fit should always be checked in these
+    cases. When polynomial fits are not satisfactory, splines may be a good
+    alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+    .. [2] Wikipedia, "Polynomial interpolation",
+           http://en.wikipedia.org/wiki/Polynomial_interpolation
+
+    Examples
+    --------
+    >>> x = np.array([0.0, 1.0, 2.0, 3.0,  4.0,  5.0])
+    >>> y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0])
+    >>> z = np.polyfit(x, y, 3)
+    >>> z
+    array([ 0.08703704, -0.81349206,  1.69312169, -0.03968254])
+
+    It is convenient to use `poly1d` objects for dealing with polynomials:
+
+    >>> p = np.poly1d(z)
+    >>> p(0.5)
+    0.6143849206349179
+    >>> p(3.5)
+    -0.34732142857143039
+    >>> p(10)
+    22.579365079365115
+
+    High-order polynomials may oscillate wildly:
+
+    >>> p30 = np.poly1d(np.polyfit(x, y, 30))
+    /... RankWarning: Polyfit may be poorly conditioned...
+    >>> p30(4)
+    -0.80000000000000204
+    >>> p30(5)
+    -0.99999999999999445
+    >>> p30(4.5)
+    -0.10547061179440398
+
+    Illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> xp = np.linspace(-2, 6, 100)
+    >>> _ = plt.plot(x, y, '.', xp, p(xp), '-', xp, p30(xp), '--')
+    >>> plt.ylim(-2,2)
+    (-2, 2)
+    >>> plt.show()
+
+    """
+    order = int(deg) + 1
+    x = NX.asarray(x) + 0.0
+    y = NX.asarray(y) + 0.0
+
+    # check arguments.
+    if deg < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if x.shape[0] != y.shape[0]:
+        raise TypeError("expected x and y to have same length")
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*finfo(x.dtype).eps
+
+    # set up least squares equation for powers of x
+    lhs = vander(x, order)
+    rhs = y
+
+    # apply weighting
+    if w is not None:
+        w = NX.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected a 1-d array for weights")
+        if w.shape[0] != y.shape[0]:
+            raise TypeError("expected w and y to have the same length")
+        lhs *= w[:, NX.newaxis]
+        if rhs.ndim == 2:
+            rhs *= w[:, NX.newaxis]
+        else:
+            rhs *= w
+
+    # scale lhs to improve condition number and solve
+    scale = NX.sqrt((lhs*lhs).sum(axis=0))
+    lhs /= scale
+    c, resids, rank, s = lstsq(lhs, rhs, rcond)
+    c = (c.T/scale).T  # broadcast scale coefficients
+
+    # warn on rank reduction, which indicates an ill conditioned matrix
+    if rank != order and not full:
+        msg = "Polyfit may be poorly conditioned"
+        warnings.warn(msg, RankWarning)
+
+    if full:
+        return c, resids, rank, s, rcond
+    elif cov:
+        Vbase = inv(dot(lhs.T, lhs))
+        Vbase /= NX.outer(scale, scale)
+        # Some literature ignores the extra -2.0 factor in the denominator, but
+        #  it is included here because the covariance of Multivariate Student-T
+        #  (which is implied by a Bayesian uncertainty analysis) includes it.
+        #  Plus, it gives a slightly more conservative estimate of uncertainty.
+        fac = resids / (len(x) - order - 2.0)
+        if y.ndim == 1:
+            return c, Vbase * fac
+        else:
+            return c, Vbase[:,:, NX.newaxis] * fac
+    else:
+        return c
+
+
+def polyval(p, x):
+    """
+    Evaluate a polynomial at specific values.
+
+    If `p` is of length N, this function returns the value:
+
+        ``p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]``
+
+    If `x` is a sequence, then `p(x)` is returned for each element of `x`.
+    If `x` is another polynomial then the composite polynomial `p(x(t))`
+    is returned.
+
+    Parameters
+    ----------
+    p : array_like or poly1d object
+       1D array of polynomial coefficients (including coefficients equal
+       to zero) from highest degree to the constant term, or an
+       instance of poly1d.
+    x : array_like or poly1d object
+       A number, an array of numbers, or an instance of poly1d, at
+       which to evaluate `p`.
+
+    Returns
+    -------
+    values : ndarray or poly1d
+       If `x` is a poly1d instance, the result is the composition of the two
+       polynomials, i.e., `x` is "substituted" in `p` and the simplified
+       result is returned. In addition, the type of `x` - array_like or
+       poly1d - governs the type of the output: `x` array_like => `values`
+       array_like, `x` a poly1d object => `values` is also.
+
+    See Also
+    --------
+    poly1d: A polynomial class.
+
+    Notes
+    -----
+    Horner's scheme [1]_ is used to evaluate the polynomial. Even so,
+    for polynomials of high degree the values may be inaccurate due to
+    rounding errors. Use carefully.
+
+    References
+    ----------
+    .. [1] I. N. Bronshtein, K. A. Semendyayev, and K. A. Hirsch (Eng.
+       trans. Ed.), *Handbook of Mathematics*, New York, Van Nostrand
+       Reinhold Co., 1985, pg. 720.
+
+    Examples
+    --------
+    >>> np.polyval([3,0,1], 5)  # 3 * 5**2 + 0 * 5**1 + 1
+    76
+    >>> np.polyval([3,0,1], np.poly1d(5))
+    poly1d([ 76.])
+    >>> np.polyval(np.poly1d([3,0,1]), 5)
+    76
+    >>> np.polyval(np.poly1d([3,0,1]), np.poly1d(5))
+    poly1d([ 76.])
+
+    """
+    p = NX.asarray(p)
+    if isinstance(x, poly1d):
+        y = 0
+    else:
+        x = NX.asarray(x)
+        y = NX.zeros_like(x)
+    for i in range(len(p)):
+        y = y * x + p[i]
+    return y
+
+def polyadd(a1, a2):
+    """
+    Find the sum of two polynomials.
+
+    Returns the polynomial resulting from the sum of two input polynomials.
+    Each input must be either a poly1d object or a 1D sequence of polynomial
+    coefficients, from highest to lowest degree.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d object
+        Input polynomials.
+
+    Returns
+    -------
+    out : ndarray or poly1d object
+        The sum of the inputs. If either input is a poly1d object, then the
+        output is also a poly1d object. Otherwise, it is a 1D array of
+        polynomial coefficients from highest to lowest degree.
+
+    See Also
+    --------
+    poly1d : A one-dimensional polynomial class.
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval
+
+    Examples
+    --------
+    >>> np.polyadd([1, 2], [9, 5, 4])
+    array([9, 6, 6])
+
+    Using poly1d objects:
+
+    >>> p1 = np.poly1d([1, 2])
+    >>> p2 = np.poly1d([9, 5, 4])
+    >>> print(p1)
+    1 x + 2
+    >>> print(p2)
+       2
+    9 x + 5 x + 4
+    >>> print(np.polyadd(p1, p2))
+       2
+    9 x + 6 x + 6
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1 = atleast_1d(a1)
+    a2 = atleast_1d(a2)
+    diff = len(a2) - len(a1)
+    if diff == 0:
+        val = a1 + a2
+    elif diff > 0:
+        zr = NX.zeros(diff, a1.dtype)
+        val = NX.concatenate((zr, a1)) + a2
+    else:
+        zr = NX.zeros(abs(diff), a2.dtype)
+        val = a1 + NX.concatenate((zr, a2))
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polysub(a1, a2):
+    """
+    Difference (subtraction) of two polynomials.
+
+    Given two polynomials `a1` and `a2`, returns ``a1 - a2``.
+    `a1` and `a2` can be either array_like sequences of the polynomials'
+    coefficients (including coefficients equal to zero), or `poly1d` objects.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d
+        Minuend and subtrahend polynomials, respectively.
+
+    Returns
+    -------
+    out : ndarray or poly1d
+        Array or `poly1d` object of the difference polynomial's coefficients.
+
+    See Also
+    --------
+    polyval, polydiv, polymul, polyadd
+
+    Examples
+    --------
+    .. math:: (2 x^2 + 10 x - 2) - (3 x^2 + 10 x -4) = (-x^2 + 2)
+
+    >>> np.polysub([2, 10, -2], [3, 10, -4])
+    array([-1,  0,  2])
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1 = atleast_1d(a1)
+    a2 = atleast_1d(a2)
+    diff = len(a2) - len(a1)
+    if diff == 0:
+        val = a1 - a2
+    elif diff > 0:
+        zr = NX.zeros(diff, a1.dtype)
+        val = NX.concatenate((zr, a1)) - a2
+    else:
+        zr = NX.zeros(abs(diff), a2.dtype)
+        val = a1 - NX.concatenate((zr, a2))
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+
+def polymul(a1, a2):
+    """
+    Find the product of two polynomials.
+
+    Finds the polynomial resulting from the multiplication of the two input
+    polynomials. Each input must be either a poly1d object or a 1D sequence
+    of polynomial coefficients, from highest to lowest degree.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d object
+        Input polynomials.
+
+    Returns
+    -------
+    out : ndarray or poly1d object
+        The polynomial resulting from the multiplication of the inputs. If
+        either inputs is a poly1d object, then the output is also a poly1d
+        object. Otherwise, it is a 1D array of polynomial coefficients from
+        highest to lowest degree.
+
+    See Also
+    --------
+    poly1d : A one-dimensional polynomial class.
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polysub,
+    polyval
+    convolve : Array convolution. Same output as polymul, but has parameter
+               for overlap mode.
+
+    Examples
+    --------
+    >>> np.polymul([1, 2, 3], [9, 5, 1])
+    array([ 9, 23, 38, 17,  3])
+
+    Using poly1d objects:
+
+    >>> p1 = np.poly1d([1, 2, 3])
+    >>> p2 = np.poly1d([9, 5, 1])
+    >>> print(p1)
+       2
+    1 x + 2 x + 3
+    >>> print(p2)
+       2
+    9 x + 5 x + 1
+    >>> print(np.polymul(p1, p2))
+       4      3      2
+    9 x + 23 x + 38 x + 17 x + 3
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1, a2 = poly1d(a1), poly1d(a2)
+    val = NX.convolve(a1, a2)
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polydiv(u, v):
+    """
+    Returns the quotient and remainder of polynomial division.
+
+    The input arrays are the coefficients (including any coefficients
+    equal to zero) of the "numerator" (dividend) and "denominator"
+    (divisor) polynomials, respectively.
+
+    Parameters
+    ----------
+    u : array_like or poly1d
+        Dividend polynomial's coefficients.
+
+    v : array_like or poly1d
+        Divisor polynomial's coefficients.
+
+    Returns
+    -------
+    q : ndarray
+        Coefficients, including those equal to zero, of the quotient.
+    r : ndarray
+        Coefficients, including those equal to zero, of the remainder.
+
+    See Also
+    --------
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polymul, polysub,
+    polyval
+
+    Notes
+    -----
+    Both `u` and `v` must be 0-d or 1-d (ndim = 0 or 1), but `u.ndim` need
+    not equal `v.ndim`. In other words, all four possible combinations -
+    ``u.ndim = v.ndim = 0``, ``u.ndim = v.ndim = 1``,
+    ``u.ndim = 1, v.ndim = 0``, and ``u.ndim = 0, v.ndim = 1`` - work.
+
+    Examples
+    --------
+    .. math:: \\frac{3x^2 + 5x + 2}{2x + 1} = 1.5x + 1.75, remainder 0.25
+
+    >>> x = np.array([3.0, 5.0, 2.0])
+    >>> y = np.array([2.0, 1.0])
+    >>> np.polydiv(x, y)
+    (array([ 1.5 ,  1.75]), array([ 0.25]))
+
+    """
+    truepoly = (isinstance(u, poly1d) or isinstance(u, poly1d))
+    u = atleast_1d(u) + 0.0
+    v = atleast_1d(v) + 0.0
+    # w has the common type
+    w = u[0] + v[0]
+    m = len(u) - 1
+    n = len(v) - 1
+    scale = 1. / v[0]
+    q = NX.zeros((max(m - n + 1, 1),), w.dtype)
+    r = u.copy()
+    for k in range(0, m-n+1):
+        d = scale * r[k]
+        q[k] = d
+        r[k:k+n+1] -= d*v
+    while NX.allclose(r[0], 0, rtol=1e-14) and (r.shape[-1] > 1):
+        r = r[1:]
+    if truepoly:
+        return poly1d(q), poly1d(r)
+    return q, r
+
+_poly_mat = re.compile(r"[*][*]([0-9]*)")
+def _raise_power(astr, wrap=70):
+    n = 0
+    line1 = ''
+    line2 = ''
+    output = ' '
+    while True:
+        mat = _poly_mat.search(astr, n)
+        if mat is None:
+            break
+        span = mat.span()
+        power = mat.groups()[0]
+        partstr = astr[n:span[0]]
+        n = span[1]
+        toadd2 = partstr + ' '*(len(power)-1)
+        toadd1 = ' '*(len(partstr)-1) + power
+        if ((len(line2) + len(toadd2) > wrap) or
+                (len(line1) + len(toadd1) > wrap)):
+            output += line1 + "\n" + line2 + "\n "
+            line1 = toadd1
+            line2 = toadd2
+        else:
+            line2 += partstr + ' '*(len(power)-1)
+            line1 += ' '*(len(partstr)-1) + power
+    output += line1 + "\n" + line2
+    return output + astr[n:]
+
+
+class poly1d(object):
+    """
+    A one-dimensional polynomial class.
+
+    A convenience class, used to encapsulate "natural" operations on
+    polynomials so that said operations may take on their customary
+    form in code (see Examples).
+
+    Parameters
+    ----------
+    c_or_r : array_like
+        The polynomial's coefficients, in decreasing powers, or if
+        the value of the second parameter is True, the polynomial's
+        roots (values where the polynomial evaluates to 0).  For example,
+        ``poly1d([1, 2, 3])`` returns an object that represents
+        :math:`x^2 + 2x + 3`, whereas ``poly1d([1, 2, 3], True)`` returns
+        one that represents :math:`(x-1)(x-2)(x-3) = x^3 - 6x^2 + 11x -6`.
+    r : bool, optional
+        If True, `c_or_r` specifies the polynomial's roots; the default
+        is False.
+    variable : str, optional
+        Changes the variable used when printing `p` from `x` to `variable`
+        (see Examples).
+
+    Examples
+    --------
+    Construct the polynomial :math:`x^2 + 2x + 3`:
+
+    >>> p = np.poly1d([1, 2, 3])
+    >>> print(np.poly1d(p))
+       2
+    1 x + 2 x + 3
+
+    Evaluate the polynomial at :math:`x = 0.5`:
+
+    >>> p(0.5)
+    4.25
+
+    Find the roots:
+
+    >>> p.r
+    array([-1.+1.41421356j, -1.-1.41421356j])
+    >>> p(p.r)
+    array([ -4.44089210e-16+0.j,  -4.44089210e-16+0.j])
+
+    These numbers in the previous line represent (0, 0) to machine precision
+
+    Show the coefficients:
+
+    >>> p.c
+    array([1, 2, 3])
+
+    Display the order (the leading zero-coefficients are removed):
+
+    >>> p.order
+    2
+
+    Show the coefficient of the k-th power in the polynomial
+    (which is equivalent to ``p.c[-(i+1)]``):
+
+    >>> p[1]
+    2
+
+    Polynomials can be added, subtracted, multiplied, and divided
+    (returns quotient and remainder):
+
+    >>> p * p
+    poly1d([ 1,  4, 10, 12,  9])
+
+    >>> (p**3 + 4) / p
+    (poly1d([  1.,   4.,  10.,  12.,   9.]), poly1d([ 4.]))
+
+    ``asarray(p)`` gives the coefficient array, so polynomials can be
+    used in all functions that accept arrays:
+
+    >>> p**2 # square of polynomial
+    poly1d([ 1,  4, 10, 12,  9])
+
+    >>> np.square(p) # square of individual coefficients
+    array([1, 4, 9])
+
+    The variable used in the string representation of `p` can be modified,
+    using the `variable` parameter:
+
+    >>> p = np.poly1d([1,2,3], variable='z')
+    >>> print(p)
+       2
+    1 z + 2 z + 3
+
+    Construct a polynomial from its roots:
+
+    >>> np.poly1d([1, 2], True)
+    poly1d([ 1, -3,  2])
+
+    This is the same polynomial as obtained by:
+
+    >>> np.poly1d([1, -1]) * np.poly1d([1, -2])
+    poly1d([ 1, -3,  2])
+
+    """
+    coeffs = None
+    order = None
+    variable = None
+    __hash__ = None
+
+    def __init__(self, c_or_r, r=0, variable=None):
+        if isinstance(c_or_r, poly1d):
+            for key in c_or_r.__dict__.keys():
+                self.__dict__[key] = c_or_r.__dict__[key]
+            if variable is not None:
+                self.__dict__['variable'] = variable
+            return
+        if r:
+            c_or_r = poly(c_or_r)
+        c_or_r = atleast_1d(c_or_r)
+        if len(c_or_r.shape) > 1:
+            raise ValueError("Polynomial must be 1d only.")
+        c_or_r = trim_zeros(c_or_r, trim='f')
+        if len(c_or_r) == 0:
+            c_or_r = NX.array([0.])
+        self.__dict__['coeffs'] = c_or_r
+        self.__dict__['order'] = len(c_or_r) - 1
+        if variable is None:
+            variable = 'x'
+        self.__dict__['variable'] = variable
+
+    def __array__(self, t=None):
+        if t:
+            return NX.asarray(self.coeffs, t)
+        else:
+            return NX.asarray(self.coeffs)
+
+    def __repr__(self):
+        vals = repr(self.coeffs)
+        vals = vals[6:-1]
+        return "poly1d(%s)" % vals
+
+    def __len__(self):
+        return self.order
+
+    def __str__(self):
+        thestr = "0"
+        var = self.variable
+
+        # Remove leading zeros
+        coeffs = self.coeffs[NX.logical_or.accumulate(self.coeffs != 0)]
+        N = len(coeffs)-1
+
+        def fmt_float(q):
+            s = '%.4g' % q
+            if s.endswith('.0000'):
+                s = s[:-5]
+            return s
+
+        for k in range(len(coeffs)):
+            if not iscomplex(coeffs[k]):
+                coefstr = fmt_float(real(coeffs[k]))
+            elif real(coeffs[k]) == 0:
+                coefstr = '%sj' % fmt_float(imag(coeffs[k]))
+            else:
+                coefstr = '(%s + %sj)' % (fmt_float(real(coeffs[k])),
+                                          fmt_float(imag(coeffs[k])))
+
+            power = (N-k)
+            if power == 0:
+                if coefstr != '0':
+                    newstr = '%s' % (coefstr,)
+                else:
+                    if k == 0:
+                        newstr = '0'
+                    else:
+                        newstr = ''
+            elif power == 1:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == 'b':
+                    newstr = var
+                else:
+                    newstr = '%s %s' % (coefstr, var)
+            else:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == 'b':
+                    newstr = '%s**%d' % (var, power,)
+                else:
+                    newstr = '%s %s**%d' % (coefstr, var, power)
+
+            if k > 0:
+                if newstr != '':
+                    if newstr.startswith('-'):
+                        thestr = "%s - %s" % (thestr, newstr[1:])
+                    else:
+                        thestr = "%s + %s" % (thestr, newstr)
+            else:
+                thestr = newstr
+        return _raise_power(thestr)
+
+    def __call__(self, val):
+        return polyval(self.coeffs, val)
+
+    def __neg__(self):
+        return poly1d(-self.coeffs)
+
+    def __pos__(self):
+        return self
+
+    def __mul__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs * other)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))
+
+    def __rmul__(self, other):
+        if isscalar(other):
+            return poly1d(other * self.coeffs)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))
+
+    def __add__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))
+
+    def __radd__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))
+
+    def __pow__(self, val):
+        if not isscalar(val) or int(val) != val or val < 0:
+            raise ValueError("Power to non-negative integers only.")
+        res = [1]
+        for _ in range(val):
+            res = polymul(self.coeffs, res)
+        return poly1d(res)
+
+    def __sub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(self.coeffs, other.coeffs))
+
+    def __rsub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(other.coeffs, self.coeffs))
+
+    def __div__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs/other)
+        else:
+            other = poly1d(other)
+            return polydiv(self, other)
+
+    __truediv__ = __div__
+
+    def __rdiv__(self, other):
+        if isscalar(other):
+            return poly1d(other/self.coeffs)
+        else:
+            other = poly1d(other)
+            return polydiv(other, self)
+
+    __rtruediv__ = __rdiv__
+
+    def __eq__(self, other):
+        if self.coeffs.shape != other.coeffs.shape:
+            return False
+        return (self.coeffs == other.coeffs).all()
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __setattr__(self, key, val):
+        raise ValueError("Attributes cannot be changed this way.")
+
+    def __getattr__(self, key):
+        if key in ['r', 'roots']:
+            return roots(self.coeffs)
+        elif key in ['c', 'coef', 'coefficients']:
+            return self.coeffs
+        elif key in ['o']:
+            return self.order
+        else:
+            try:
+                return self.__dict__[key]
+            except KeyError:
+                raise AttributeError(
+                    "'%s' has no attribute '%s'" % (self.__class__, key))
+
+    def __getitem__(self, val):
+        ind = self.order - val
+        if val > self.order:
+            return 0
+        if val < 0:
+            return 0
+        return self.coeffs[ind]
+
+    def __setitem__(self, key, val):
+        ind = self.order - key
+        if key < 0:
+            raise ValueError("Does not support negative powers.")
+        if key > self.order:
+            zr = NX.zeros(key-self.order, self.coeffs.dtype)
+            self.__dict__['coeffs'] = NX.concatenate((zr, self.coeffs))
+            self.__dict__['order'] = key
+            ind = 0
+        self.__dict__['coeffs'][ind] = val
+        return
+
+    def __iter__(self):
+        return iter(self.coeffs)
+
+    def integ(self, m=1, k=0):
+        """
+        Return an antiderivative (indefinite integral) of this polynomial.
+
+        Refer to `polyint` for full documentation.
+
+        See Also
+        --------
+        polyint : equivalent function
+
+        """
+        return poly1d(polyint(self.coeffs, m=m, k=k))
+
+    def deriv(self, m=1):
+        """
+        Return a derivative of this polynomial.
+
+        Refer to `polyder` for full documentation.
+
+        See Also
+        --------
+        polyder : equivalent function
+
+        """
+        return poly1d(polyder(self.coeffs, m=m))
+
+# Stuff to do on module import
+
+warnings.simplefilter('always', RankWarning)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.py
new file mode 100644
index 0000000000..4ae1079d28
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.py
@@ -0,0 +1,1003 @@
+"""
+Collection of utilities to manipulate structured arrays.
+
+Most of these functions were initially implemented by John Hunter for
+matplotlib.  They have been rewritten and extended for convenience.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import numpy as np
+import numpy.ma as ma
+from numpy import ndarray, recarray
+from numpy.ma import MaskedArray
+from numpy.ma.mrecords import MaskedRecords
+from numpy.lib._iotools import _is_string_like
+from numpy.compat import basestring
+
+if sys.version_info[0] < 3:
+    from future_builtins import zip
+
+_check_fill_value = np.ma.core._check_fill_value
+
+
+__all__ = [
+    'append_fields', 'drop_fields', 'find_duplicates',
+    'get_fieldstructure', 'join_by', 'merge_arrays',
+    'rec_append_fields', 'rec_drop_fields', 'rec_join',
+    'recursive_fill_fields', 'rename_fields', 'stack_arrays',
+    ]
+
+
+def recursive_fill_fields(input, output):
+    """
+    Fills fields from output with fields from input,
+    with support for nested structures.
+
+    Parameters
+    ----------
+    input : ndarray
+        Input array.
+    output : ndarray
+        Output array.
+
+    Notes
+    -----
+    * `output` should be at least the same size as `input`
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)])
+    >>> b = np.zeros((3,), dtype=a.dtype)
+    >>> rfn.recursive_fill_fields(a, b)
+    array([(1, 10.0), (2, 20.0), (0, 0.0)],
+          dtype=[('A', '<i4'), ('B', '<f8')])
+
+    """
+    newdtype = output.dtype
+    for field in newdtype.names:
+        try:
+            current = input[field]
+        except ValueError:
+            continue
+        if current.dtype.names:
+            recursive_fill_fields(current, output[field])
+        else:
+            output[field][:len(current)] = current
+    return output
+
+
+def get_names(adtype):
+    """
+    Returns the field names of the input datatype as a tuple.
+
+    Parameters
+    ----------
+    adtype : dtype
+        Input datatype
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.get_names(np.empty((1,), dtype=int)) is None
+    True
+    >>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)]))
+    ('A', 'B')
+    >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
+    >>> rfn.get_names(adtype)
+    ('a', ('b', ('ba', 'bb')))
+    """
+    listnames = []
+    names = adtype.names
+    for name in names:
+        current = adtype[name]
+        if current.names:
+            listnames.append((name, tuple(get_names(current))))
+        else:
+            listnames.append(name)
+    return tuple(listnames) or None
+
+
+def get_names_flat(adtype):
+    """
+    Returns the field names of the input datatype as a tuple. Nested structure
+    are flattend beforehand.
+
+    Parameters
+    ----------
+    adtype : dtype
+        Input datatype
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.get_names_flat(np.empty((1,), dtype=int)) is None
+    True
+    >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', float)]))
+    ('A', 'B')
+    >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
+    >>> rfn.get_names_flat(adtype)
+    ('a', 'b', 'ba', 'bb')
+    """
+    listnames = []
+    names = adtype.names
+    for name in names:
+        listnames.append(name)
+        current = adtype[name]
+        if current.names:
+            listnames.extend(get_names_flat(current))
+    return tuple(listnames) or None
+
+
+def flatten_descr(ndtype):
+    """
+    Flatten a structured data-type description.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype = np.dtype([('a', '<i4'), ('b', [('ba', '<f8'), ('bb', '<i4')])])
+    >>> rfn.flatten_descr(ndtype)
+    (('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))
+
+    """
+    names = ndtype.names
+    if names is None:
+        return ndtype.descr
+    else:
+        descr = []
+        for field in names:
+            (typ, _) = ndtype.fields[field]
+            if typ.names:
+                descr.extend(flatten_descr(typ))
+            else:
+                descr.append((field, typ))
+        return tuple(descr)
+
+
+def zip_descr(seqarrays, flatten=False):
+    """
+    Combine the dtype description of a series of arrays.
+
+    Parameters
+    ----------
+    seqarrays : sequence of arrays
+        Sequence of arrays
+    flatten : {boolean}, optional
+        Whether to collapse nested descriptions.
+    """
+    newdtype = []
+    if flatten:
+        for a in seqarrays:
+            newdtype.extend(flatten_descr(a.dtype))
+    else:
+        for a in seqarrays:
+            current = a.dtype
+            names = current.names or ()
+            if len(names) > 1:
+                newdtype.append(('', current.descr))
+            else:
+                newdtype.extend(current.descr)
+    return np.dtype(newdtype).descr
+
+
+def get_fieldstructure(adtype, lastname=None, parents=None,):
+    """
+    Returns a dictionary with fields indexing lists of their parent fields.
+
+    This function is used to simplify access to fields nested in other fields.
+
+    Parameters
+    ----------
+    adtype : np.dtype
+        Input datatype
+    lastname : optional
+        Last processed field name (used internally during recursion).
+    parents : dictionary
+        Dictionary of parent fields (used interbally during recursion).
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype =  np.dtype([('A', int),
+    ...                     ('B', [('BA', int),
+    ...                            ('BB', [('BBA', int), ('BBB', int)])])])
+    >>> rfn.get_fieldstructure(ndtype)
+    ... # XXX: possible regression, order of BBA and BBB is swapped
+    {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
+
+    """
+    if parents is None:
+        parents = {}
+    names = adtype.names
+    for name in names:
+        current = adtype[name]
+        if current.names:
+            if lastname:
+                parents[name] = [lastname, ]
+            else:
+                parents[name] = []
+            parents.update(get_fieldstructure(current, name, parents))
+        else:
+            lastparent = [_ for _ in (parents.get(lastname, []) or [])]
+            if lastparent:
+                lastparent.append(lastname)
+            elif lastname:
+                lastparent = [lastname, ]
+            parents[name] = lastparent or []
+    return parents or None
+
+
+def _izip_fields_flat(iterable):
+    """
+    Returns an iterator of concatenated fields from a sequence of arrays,
+    collapsing any nested structure.
+
+    """
+    for element in iterable:
+        if isinstance(element, np.void):
+            for f in _izip_fields_flat(tuple(element)):
+                yield f
+        else:
+            yield element
+
+
+def _izip_fields(iterable):
+    """
+    Returns an iterator of concatenated fields from a sequence of arrays.
+
+    """
+    for element in iterable:
+        if (hasattr(element, '__iter__') and
+                not isinstance(element, basestring)):
+            for f in _izip_fields(element):
+                yield f
+        elif isinstance(element, np.void) and len(tuple(element)) == 1:
+            for f in _izip_fields(element):
+                yield f
+        else:
+            yield element
+
+
+def izip_records(seqarrays, fill_value=None, flatten=True):
+    """
+    Returns an iterator of concatenated items from a sequence of arrays.
+
+    Parameters
+    ----------
+    seqarrays : sequence of arrays
+        Sequence of arrays.
+    fill_value : {None, integer}
+        Value used to pad shorter iterables.
+    flatten : {True, False},
+        Whether to
+    """
+    # OK, that's a complete ripoff from Python2.6 itertools.izip_longest
+    def sentinel(counter=([fill_value] * (len(seqarrays) - 1)).pop):
+        "Yields the fill_value or raises IndexError"
+        yield counter()
+    #
+    fillers = itertools.repeat(fill_value)
+    iters = [itertools.chain(it, sentinel(), fillers) for it in seqarrays]
+    # Should we flatten the items, or just use a nested approach
+    if flatten:
+        zipfunc = _izip_fields_flat
+    else:
+        zipfunc = _izip_fields
+    #
+    try:
+        for tup in zip(*iters):
+            yield tuple(zipfunc(tup))
+    except IndexError:
+        pass
+
+
+def _fix_output(output, usemask=True, asrecarray=False):
+    """
+    Private function: return a recarray, a ndarray, a MaskedArray
+    or a MaskedRecords depending on the input parameters
+    """
+    if not isinstance(output, MaskedArray):
+        usemask = False
+    if usemask:
+        if asrecarray:
+            output = output.view(MaskedRecords)
+    else:
+        output = ma.filled(output)
+        if asrecarray:
+            output = output.view(recarray)
+    return output
+
+
+def _fix_defaults(output, defaults=None):
+    """
+    Update the fill_value and masked data of `output`
+    from the default given in a dictionary defaults.
+    """
+    names = output.dtype.names
+    (data, mask, fill_value) = (output.data, output.mask, output.fill_value)
+    for (k, v) in (defaults or {}).items():
+        if k in names:
+            fill_value[k] = v
+            data[k][mask[k]] = v
+    return output
+
+
+def merge_arrays(seqarrays, fill_value=-1, flatten=False,
+                 usemask=False, asrecarray=False):
+    """
+    Merge arrays field by field.
+
+    Parameters
+    ----------
+    seqarrays : sequence of ndarrays
+        Sequence of arrays
+    fill_value : {float}, optional
+        Filling value used to pad missing data on the shorter arrays.
+    flatten : {False, True}, optional
+        Whether to collapse nested fields.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (MaskedRecords) or not.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])))
+    masked_array(data = [(1, 10.0) (2, 20.0) (--, 30.0)],
+                 mask = [(False, False) (False, False) (True, False)],
+           fill_value = (999999, 1e+20),
+                dtype = [('f0', '<i4'), ('f1', '<f8')])
+
+    >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])),
+    ...              usemask=False)
+    array([(1, 10.0), (2, 20.0), (-1, 30.0)],
+          dtype=[('f0', '<i4'), ('f1', '<f8')])
+    >>> rfn.merge_arrays((np.array([1, 2]).view([('a', int)]),
+    ...               np.array([10., 20., 30.])),
+    ...              usemask=False, asrecarray=True)
+    rec.array([(1, 10.0), (2, 20.0), (-1, 30.0)],
+              dtype=[('a', '<i4'), ('f1', '<f8')])
+
+    Notes
+    -----
+    * Without a mask, the missing value will be filled with something,
+    * depending on what its corresponding type:
+            -1      for integers
+            -1.0    for floating point numbers
+            '-'     for characters
+            '-1'    for strings
+            True    for boolean values
+    * XXX: I just obtained these values empirically
+    """
+    # Only one item in the input sequence ?
+    if (len(seqarrays) == 1):
+        seqarrays = np.asanyarray(seqarrays[0])
+    # Do we have a single ndarray as input ?
+    if isinstance(seqarrays, (ndarray, np.void)):
+        seqdtype = seqarrays.dtype
+        if (not flatten) or \
+           (zip_descr((seqarrays,), flatten=True) == seqdtype.descr):
+            # Minimal processing needed: just make sure everythng's a-ok
+            seqarrays = seqarrays.ravel()
+            # Make sure we have named fields
+            if not seqdtype.names:
+                seqdtype = [('', seqdtype)]
+            # Find what type of array we must return
+            if usemask:
+                if asrecarray:
+                    seqtype = MaskedRecords
+                else:
+                    seqtype = MaskedArray
+            elif asrecarray:
+                seqtype = recarray
+            else:
+                seqtype = ndarray
+            return seqarrays.view(dtype=seqdtype, type=seqtype)
+        else:
+            seqarrays = (seqarrays,)
+    else:
+        # Make sure we have arrays in the input sequence
+        seqarrays = [np.asanyarray(_m) for _m in seqarrays]
+    # Find the sizes of the inputs and their maximum
+    sizes = tuple(a.size for a in seqarrays)
+    maxlength = max(sizes)
+    # Get the dtype of the output (flattening if needed)
+    newdtype = zip_descr(seqarrays, flatten=flatten)
+    # Initialize the sequences for data and mask
+    seqdata = []
+    seqmask = []
+    # If we expect some kind of MaskedArray, make a special loop.
+    if usemask:
+        for (a, n) in zip(seqarrays, sizes):
+            nbmissing = (maxlength - n)
+            # Get the data and mask
+            data = a.ravel().__array__()
+            mask = ma.getmaskarray(a).ravel()
+            # Get the filling value (if needed)
+            if nbmissing:
+                fval = _check_fill_value(fill_value, a.dtype)
+                if isinstance(fval, (ndarray, np.void)):
+                    if len(fval.dtype) == 1:
+                        fval = fval.item()[0]
+                        fmsk = True
+                    else:
+                        fval = np.array(fval, dtype=a.dtype, ndmin=1)
+                        fmsk = np.ones((1,), dtype=mask.dtype)
+            else:
+                fval = None
+                fmsk = True
+            # Store an iterator padding the input to the expected length
+            seqdata.append(itertools.chain(data, [fval] * nbmissing))
+            seqmask.append(itertools.chain(mask, [fmsk] * nbmissing))
+        # Create an iterator for the data
+        data = tuple(izip_records(seqdata, flatten=flatten))
+        output = ma.array(np.fromiter(data, dtype=newdtype, count=maxlength),
+                          mask=list(izip_records(seqmask, flatten=flatten)))
+        if asrecarray:
+            output = output.view(MaskedRecords)
+    else:
+        # Same as before, without the mask we don't need...
+        for (a, n) in zip(seqarrays, sizes):
+            nbmissing = (maxlength - n)
+            data = a.ravel().__array__()
+            if nbmissing:
+                fval = _check_fill_value(fill_value, a.dtype)
+                if isinstance(fval, (ndarray, np.void)):
+                    if len(fval.dtype) == 1:
+                        fval = fval.item()[0]
+                    else:
+                        fval = np.array(fval, dtype=a.dtype, ndmin=1)
+            else:
+                fval = None
+            seqdata.append(itertools.chain(data, [fval] * nbmissing))
+        output = np.fromiter(tuple(izip_records(seqdata, flatten=flatten)),
+                             dtype=newdtype, count=maxlength)
+        if asrecarray:
+            output = output.view(recarray)
+    # And we're done...
+    return output
+
+
+def drop_fields(base, drop_names, usemask=True, asrecarray=False):
+    """
+    Return a new array with fields in `drop_names` dropped.
+
+    Nested fields are supported.
+
+    Parameters
+    ----------
+    base : array
+        Input array
+    drop_names : string or sequence
+        String or sequence of strings corresponding to the names of the
+        fields to drop.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : string or sequence, optional
+        Whether to return a recarray or a mrecarray (`asrecarray=True`) or
+        a plain ndarray or masked array with flexible dtype. The default
+        is False.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+    ...   dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+    >>> rfn.drop_fields(a, 'a')
+    array([((2.0, 3),), ((5.0, 6),)],
+          dtype=[('b', [('ba', '<f8'), ('bb', '<i4')])])
+    >>> rfn.drop_fields(a, 'ba')
+    array([(1, (3,)), (4, (6,))],
+          dtype=[('a', '<i4'), ('b', [('bb', '<i4')])])
+    >>> rfn.drop_fields(a, ['ba', 'bb'])
+    array([(1,), (4,)],
+          dtype=[('a', '<i4')])
+    """
+    if _is_string_like(drop_names):
+        drop_names = [drop_names, ]
+    else:
+        drop_names = set(drop_names)
+
+    def _drop_descr(ndtype, drop_names):
+        names = ndtype.names
+        newdtype = []
+        for name in names:
+            current = ndtype[name]
+            if name in drop_names:
+                continue
+            if current.names:
+                descr = _drop_descr(current, drop_names)
+                if descr:
+                    newdtype.append((name, descr))
+            else:
+                newdtype.append((name, current))
+        return newdtype
+
+    newdtype = _drop_descr(base.dtype, drop_names)
+    if not newdtype:
+        return None
+
+    output = np.empty(base.shape, dtype=newdtype)
+    output = recursive_fill_fields(base, output)
+    return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
+
+
+def rec_drop_fields(base, drop_names):
+    """
+    Returns a new numpy.recarray with fields in `drop_names` dropped.
+    """
+    return drop_fields(base, drop_names, usemask=False, asrecarray=True)
+
+
+def rename_fields(base, namemapper):
+    """
+    Rename the fields from a flexible-datatype ndarray or recarray.
+
+    Nested fields are supported.
+
+    Parameters
+    ----------
+    base : ndarray
+        Input array whose fields must be modified.
+    namemapper : dictionary
+        Dictionary mapping old field names to their new version.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
+    ...   dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])])
+    >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'})
+    array([(1, (2.0, [3.0, 30.0])), (4, (5.0, [6.0, 60.0]))],
+          dtype=[('A', '<i4'), ('b', [('ba', '<f8'), ('BB', '<f8', 2)])])
+
+    """
+    def _recursive_rename_fields(ndtype, namemapper):
+        newdtype = []
+        for name in ndtype.names:
+            newname = namemapper.get(name, name)
+            current = ndtype[name]
+            if current.names:
+                newdtype.append(
+                    (newname, _recursive_rename_fields(current, namemapper))
+                    )
+            else:
+                newdtype.append((newname, current))
+        return newdtype
+    newdtype = _recursive_rename_fields(base.dtype, namemapper)
+    return base.view(newdtype)
+
+
+def append_fields(base, names, data, dtypes=None,
+                  fill_value=-1, usemask=True, asrecarray=False):
+    """
+    Add new fields to an existing array.
+
+    The names of the fields are given with the `names` arguments,
+    the corresponding values with the `data` arguments.
+    If a single field is appended, `names`, `data` and `dtypes` do not have
+    to be lists but just values.
+
+    Parameters
+    ----------
+    base : array
+        Input array to extend.
+    names : string, sequence
+        String or sequence of strings corresponding to the names
+        of the new fields.
+    data : array or sequence of arrays
+        Array or sequence of arrays storing the fields to add to the base.
+    dtypes : sequence of datatypes, optional
+        Datatype or sequence of datatypes.
+        If None, the datatypes are estimated from the `data`.
+    fill_value : {float}, optional
+        Filling value used to pad missing data on the shorter arrays.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (MaskedRecords) or not.
+
+    """
+    # Check the names
+    if isinstance(names, (tuple, list)):
+        if len(names) != len(data):
+            msg = "The number of arrays does not match the number of names"
+            raise ValueError(msg)
+    elif isinstance(names, basestring):
+        names = [names, ]
+        data = [data, ]
+    #
+    if dtypes is None:
+        data = [np.array(a, copy=False, subok=True) for a in data]
+        data = [a.view([(name, a.dtype)]) for (name, a) in zip(names, data)]
+    else:
+        if not isinstance(dtypes, (tuple, list)):
+            dtypes = [dtypes, ]
+        if len(data) != len(dtypes):
+            if len(dtypes) == 1:
+                dtypes = dtypes * len(data)
+            else:
+                msg = "The dtypes argument must be None, a dtype, or a list."
+                raise ValueError(msg)
+        data = [np.array(a, copy=False, subok=True, dtype=d).view([(n, d)])
+                for (a, n, d) in zip(data, names, dtypes)]
+    #
+    base = merge_arrays(base, usemask=usemask, fill_value=fill_value)
+    if len(data) > 1:
+        data = merge_arrays(data, flatten=True, usemask=usemask,
+                            fill_value=fill_value)
+    else:
+        data = data.pop()
+    #
+    output = ma.masked_all(max(len(base), len(data)),
+                           dtype=base.dtype.descr + data.dtype.descr)
+    output = recursive_fill_fields(base, output)
+    output = recursive_fill_fields(data, output)
+    #
+    return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
+
+
+def rec_append_fields(base, names, data, dtypes=None):
+    """
+    Add new fields to an existing array.
+
+    The names of the fields are given with the `names` arguments,
+    the corresponding values with the `data` arguments.
+    If a single field is appended, `names`, `data` and `dtypes` do not have
+    to be lists but just values.
+
+    Parameters
+    ----------
+    base : array
+        Input array to extend.
+    names : string, sequence
+        String or sequence of strings corresponding to the names
+        of the new fields.
+    data : array or sequence of arrays
+        Array or sequence of arrays storing the fields to add to the base.
+    dtypes : sequence of datatypes, optional
+        Datatype or sequence of datatypes.
+        If None, the datatypes are estimated from the `data`.
+
+    See Also
+    --------
+    append_fields
+
+    Returns
+    -------
+    appended_array : np.recarray
+    """
+    return append_fields(base, names, data=data, dtypes=dtypes,
+                         asrecarray=True, usemask=False)
+
+
+def stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False,
+                 autoconvert=False):
+    """
+    Superposes arrays fields by fields
+
+    Parameters
+    ----------
+    arrays : array or sequence
+        Sequence of input arrays.
+    defaults : dictionary, optional
+        Dictionary mapping field names to the corresponding default values.
+    usemask : {True, False}, optional
+        Whether to return a MaskedArray (or MaskedRecords is
+        `asrecarray==True`) or a ndarray.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (or MaskedRecords if `usemask==True`)
+        or just a flexible-type ndarray.
+    autoconvert : {False, True}, optional
+        Whether automatically cast the type of the field to the maximum.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> x = np.array([1, 2,])
+    >>> rfn.stack_arrays(x) is x
+    True
+    >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)])
+    >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+    ...   dtype=[('A', '|S3'), ('B', float), ('C', float)])
+    >>> test = rfn.stack_arrays((z,zz))
+    >>> test
+    masked_array(data = [('A', 1.0, --) ('B', 2.0, --) ('a', 10.0, 100.0) ('b', 20.0, 200.0)
+     ('c', 30.0, 300.0)],
+                 mask = [(False, False, True) (False, False, True) (False, False, False)
+     (False, False, False) (False, False, False)],
+           fill_value = ('N/A', 1e+20, 1e+20),
+                dtype = [('A', '|S3'), ('B', '<f8'), ('C', '<f8')])
+
+    """
+    if isinstance(arrays, ndarray):
+        return arrays
+    elif len(arrays) == 1:
+        return arrays[0]
+    seqarrays = [np.asanyarray(a).ravel() for a in arrays]
+    nrecords = [len(a) for a in seqarrays]
+    ndtype = [a.dtype for a in seqarrays]
+    fldnames = [d.names for d in ndtype]
+    #
+    dtype_l = ndtype[0]
+    newdescr = dtype_l.descr
+    names = [_[0] for _ in newdescr]
+    for dtype_n in ndtype[1:]:
+        for descr in dtype_n.descr:
+            name = descr[0] or ''
+            if name not in names:
+                newdescr.append(descr)
+                names.append(name)
+            else:
+                nameidx = names.index(name)
+                current_descr = newdescr[nameidx]
+                if autoconvert:
+                    if np.dtype(descr[1]) > np.dtype(current_descr[-1]):
+                        current_descr = list(current_descr)
+                        current_descr[-1] = descr[1]
+                        newdescr[nameidx] = tuple(current_descr)
+                elif descr[1] != current_descr[-1]:
+                    raise TypeError("Incompatible type '%s' <> '%s'" %
+                                    (dict(newdescr)[name], descr[1]))
+    # Only one field: use concatenate
+    if len(newdescr) == 1:
+        output = ma.concatenate(seqarrays)
+    else:
+        #
+        output = ma.masked_all((np.sum(nrecords),), newdescr)
+        offset = np.cumsum(np.r_[0, nrecords])
+        seen = []
+        for (a, n, i, j) in zip(seqarrays, fldnames, offset[:-1], offset[1:]):
+            names = a.dtype.names
+            if names is None:
+                output['f%i' % len(seen)][i:j] = a
+            else:
+                for name in n:
+                    output[name][i:j] = a[name]
+                    if name not in seen:
+                        seen.append(name)
+    #
+    return _fix_output(_fix_defaults(output, defaults),
+                       usemask=usemask, asrecarray=asrecarray)
+
+
+def find_duplicates(a, key=None, ignoremask=True, return_index=False):
+    """
+    Find the duplicates in a structured array along a given key
+
+    Parameters
+    ----------
+    a : array-like
+        Input array
+    key : {string, None}, optional
+        Name of the fields along which to check the duplicates.
+        If None, the search is performed by records
+    ignoremask : {True, False}, optional
+        Whether masked data should be discarded or considered as duplicates.
+    return_index : {False, True}, optional
+        Whether to return the indices of the duplicated values.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype = [('a', int)]
+    >>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3],
+    ...         mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype)
+    >>> rfn.find_duplicates(a, ignoremask=True, return_index=True)
+    ... # XXX: judging by the output, the ignoremask flag has no effect
+    """
+    a = np.asanyarray(a).ravel()
+    # Get a dictionary of fields
+    fields = get_fieldstructure(a.dtype)
+    # Get the sorting data (by selecting the corresponding field)
+    base = a
+    if key:
+        for f in fields[key]:
+            base = base[f]
+        base = base[key]
+    # Get the sorting indices and the sorted data
+    sortidx = base.argsort()
+    sortedbase = base[sortidx]
+    sorteddata = sortedbase.filled()
+    # Compare the sorting data
+    flag = (sorteddata[:-1] == sorteddata[1:])
+    # If masked data must be ignored, set the flag to false where needed
+    if ignoremask:
+        sortedmask = sortedbase.recordmask
+        flag[sortedmask[1:]] = False
+    flag = np.concatenate(([False], flag))
+    # We need to take the point on the left as well (else we're missing it)
+    flag[:-1] = flag[:-1] + flag[1:]
+    duplicates = a[sortidx][flag]
+    if return_index:
+        return (duplicates, sortidx[flag])
+    else:
+        return duplicates
+
+
+def join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
+                defaults=None, usemask=True, asrecarray=False):
+    """
+    Join arrays `r1` and `r2` on key `key`.
+
+    The key should be either a string or a sequence of string corresponding
+    to the fields used to join the array.  An exception is raised if the
+    `key` field cannot be found in the two input arrays.  Neither `r1` nor
+    `r2` should have any duplicates along `key`: the presence of duplicates
+    will make the output quite unreliable. Note that duplicates are not
+    looked for by the algorithm.
+
+    Parameters
+    ----------
+    key : {string, sequence}
+        A string or a sequence of strings corresponding to the fields used
+        for comparison.
+    r1, r2 : arrays
+        Structured arrays.
+    jointype : {'inner', 'outer', 'leftouter'}, optional
+        If 'inner', returns the elements common to both r1 and r2.
+        If 'outer', returns the common elements as well as the elements of
+        r1 not in r2 and the elements of not in r2.
+        If 'leftouter', returns the common elements and the elements of r1
+        not in r2.
+    r1postfix : string, optional
+        String appended to the names of the fields of r1 that are present
+        in r2 but absent of the key.
+    r2postfix : string, optional
+        String appended to the names of the fields of r2 that are present
+        in r1 but absent of the key.
+    defaults : {dictionary}, optional
+        Dictionary mapping field names to the corresponding default values.
+    usemask : {True, False}, optional
+        Whether to return a MaskedArray (or MaskedRecords is
+        `asrecarray==True`) or a ndarray.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (or MaskedRecords if `usemask==True`)
+        or just a flexible-type ndarray.
+
+    Notes
+    -----
+    * The output is sorted along the key.
+    * A temporary array is formed by dropping the fields not in the key for
+      the two arrays and concatenating the result. This array is then
+      sorted, and the common entries selected. The output is constructed by
+      filling the fields with the selected entries. Matching is not
+      preserved if there are some duplicates...
+
+    """
+    # Check jointype
+    if jointype not in ('inner', 'outer', 'leftouter'):
+        raise ValueError(
+                "The 'jointype' argument should be in 'inner', "
+                "'outer' or 'leftouter' (got '%s' instead)" % jointype
+                )
+    # If we have a single key, put it in a tuple
+    if isinstance(key, basestring):
+        key = (key,)
+
+    # Check the keys
+    for name in key:
+        if name not in r1.dtype.names:
+            raise ValueError('r1 does not have key field %s' % name)
+        if name not in r2.dtype.names:
+            raise ValueError('r2 does not have key field %s' % name)
+
+    # Make sure we work with ravelled arrays
+    r1 = r1.ravel()
+    r2 = r2.ravel()
+    # Fixme: nb2 below is never used. Commenting out for pyflakes.
+    # (nb1, nb2) = (len(r1), len(r2))
+    nb1 = len(r1)
+    (r1names, r2names) = (r1.dtype.names, r2.dtype.names)
+
+    # Check the names for collision
+    if (set.intersection(set(r1names), set(r2names)).difference(key) and
+            not (r1postfix or r2postfix)):
+        msg = "r1 and r2 contain common names, r1postfix and r2postfix "
+        msg += "can't be empty"
+        raise ValueError(msg)
+
+    # Make temporary arrays of just the keys
+    r1k = drop_fields(r1, [n for n in r1names if n not in key])
+    r2k = drop_fields(r2, [n for n in r2names if n not in key])
+
+    # Concatenate the two arrays for comparison
+    aux = ma.concatenate((r1k, r2k))
+    idx_sort = aux.argsort(order=key)
+    aux = aux[idx_sort]
+    #
+    # Get the common keys
+    flag_in = ma.concatenate(([False], aux[1:] == aux[:-1]))
+    flag_in[:-1] = flag_in[1:] + flag_in[:-1]
+    idx_in = idx_sort[flag_in]
+    idx_1 = idx_in[(idx_in < nb1)]
+    idx_2 = idx_in[(idx_in >= nb1)] - nb1
+    (r1cmn, r2cmn) = (len(idx_1), len(idx_2))
+    if jointype == 'inner':
+        (r1spc, r2spc) = (0, 0)
+    elif jointype == 'outer':
+        idx_out = idx_sort[~flag_in]
+        idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
+        idx_2 = np.concatenate((idx_2, idx_out[(idx_out >= nb1)] - nb1))
+        (r1spc, r2spc) = (len(idx_1) - r1cmn, len(idx_2) - r2cmn)
+    elif jointype == 'leftouter':
+        idx_out = idx_sort[~flag_in]
+        idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
+        (r1spc, r2spc) = (len(idx_1) - r1cmn, 0)
+    # Select the entries from each input
+    (s1, s2) = (r1[idx_1], r2[idx_2])
+    #
+    # Build the new description of the output array .......
+    # Start with the key fields
+    ndtype = [list(_) for _ in r1k.dtype.descr]
+    # Add the other fields
+    ndtype.extend(list(_) for _ in r1.dtype.descr if _[0] not in key)
+    # Find the new list of names (it may be different from r1names)
+    names = list(_[0] for _ in ndtype)
+    for desc in r2.dtype.descr:
+        desc = list(desc)
+        name = desc[0]
+        # Have we seen the current name already ?
+        if name in names:
+            nameidx = ndtype.index(desc)
+            current = ndtype[nameidx]
+            # The current field is part of the key: take the largest dtype
+            if name in key:
+                current[-1] = max(desc[1], current[-1])
+            # The current field is not part of the key: add the suffixes
+            else:
+                current[0] += r1postfix
+                desc[0] += r2postfix
+                ndtype.insert(nameidx + 1, desc)
+        #... we haven't: just add the description to the current list
+        else:
+            names.extend(desc[0])
+            ndtype.append(desc)
+    # Revert the elements to tuples
+    ndtype = [tuple(_) for _ in ndtype]
+    # Find the largest nb of common fields :
+    # r1cmn and r2cmn should be equal, but...
+    cmn = max(r1cmn, r2cmn)
+    # Construct an empty array
+    output = ma.masked_all((cmn + r1spc + r2spc,), dtype=ndtype)
+    names = output.dtype.names
+    for f in r1names:
+        selected = s1[f]
+        if f not in names or (f in r2names and not r2postfix and f not in key):
+            f += r1postfix
+        current = output[f]
+        current[:r1cmn] = selected[:r1cmn]
+        if jointype in ('outer', 'leftouter'):
+            current[cmn:cmn + r1spc] = selected[r1cmn:]
+    for f in r2names:
+        selected = s2[f]
+        if f not in names or (f in r1names and not r1postfix and f not in key):
+            f += r2postfix
+        current = output[f]
+        current[:r2cmn] = selected[:r2cmn]
+        if (jointype == 'outer') and r2spc:
+            current[-r2spc:] = selected[r2cmn:]
+    # Sort and finalize the output
+    output.sort(order=key)
+    kwargs = dict(usemask=usemask, asrecarray=asrecarray)
+    return _fix_output(_fix_defaults(output, defaults), **kwargs)
+
+
+def rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
+             defaults=None):
+    """
+    Join arrays `r1` and `r2` on keys.
+    Alternative to join_by, that always returns a np.recarray.
+
+    See Also
+    --------
+    join_by : equivalent function
+    """
+    kwargs = dict(jointype=jointype, r1postfix=r1postfix, r2postfix=r2postfix,
+                  defaults=defaults, usemask=False, asrecarray=True)
+    return join_by(key, r1, r2, **kwargs)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/scimath.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/scimath.py
new file mode 100644
index 0000000000..e07caf805e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/scimath.py
@@ -0,0 +1,566 @@
+"""
+Wrapper functions to more user-friendly calling of certain math functions
+whose output data-type is different than the input data-type in certain
+domains of the input.
+
+For example, for functions like `log` with branch cuts, the versions in this
+module provide the mathematically valid answers in the complex plane::
+
+  >>> import math
+  >>> from numpy.lib import scimath
+  >>> scimath.log(-math.exp(1)) == (1+1j*math.pi)
+  True
+
+Similarly, `sqrt`, other base logarithms, `power` and trig functions are
+correctly handled.  See their respective docstrings for specific examples.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy.core.numeric as nx
+import numpy.core.numerictypes as nt
+from numpy.core.numeric import asarray, any
+from numpy.lib.type_check import isreal
+
+
+__all__ = [
+    'sqrt', 'log', 'log2', 'logn', 'log10', 'power', 'arccos', 'arcsin',
+    'arctanh'
+    ]
+
+
+_ln2 = nx.log(2.0)
+
+
+def _tocomplex(arr):
+    """Convert its input `arr` to a complex array.
+
+    The input is returned as a complex array of the smallest type that will fit
+    the original data: types like single, byte, short, etc. become csingle,
+    while others become cdouble.
+
+    A copy of the input is always made.
+
+    Parameters
+    ----------
+    arr : array
+
+    Returns
+    -------
+    array
+        An array with the same input data as the input but in complex form.
+
+    Examples
+    --------
+
+    First, consider an input of type short:
+
+    >>> a = np.array([1,2,3],np.short)
+
+    >>> ac = np.lib.scimath._tocomplex(a); ac
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+
+    >>> ac.dtype
+    dtype('complex64')
+
+    If the input is of type double, the output is correspondingly of the
+    complex double type as well:
+
+    >>> b = np.array([1,2,3],np.double)
+
+    >>> bc = np.lib.scimath._tocomplex(b); bc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j])
+
+    >>> bc.dtype
+    dtype('complex128')
+
+    Note that even if the input was complex to begin with, a copy is still
+    made, since the astype() method always copies:
+
+    >>> c = np.array([1,2,3],np.csingle)
+
+    >>> cc = np.lib.scimath._tocomplex(c); cc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+
+    >>> c *= 2; c
+    array([ 2.+0.j,  4.+0.j,  6.+0.j], dtype=complex64)
+
+    >>> cc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+    """
+    if issubclass(arr.dtype.type, (nt.single, nt.byte, nt.short, nt.ubyte,
+                                   nt.ushort, nt.csingle)):
+        return arr.astype(nt.csingle)
+    else:
+        return arr.astype(nt.cdouble)
+
+def _fix_real_lt_zero(x):
+    """Convert `x` to complex if it has real, negative components.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_real_lt_zero([1,2])
+    array([1, 2])
+
+    >>> np.lib.scimath._fix_real_lt_zero([-1,2])
+    array([-1.+0.j,  2.+0.j])
+
+    """
+    x = asarray(x)
+    if any(isreal(x) & (x < 0)):
+        x = _tocomplex(x)
+    return x
+
+def _fix_int_lt_zero(x):
+    """Convert `x` to double if it has real, negative components.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_int_lt_zero([1,2])
+    array([1, 2])
+
+    >>> np.lib.scimath._fix_int_lt_zero([-1,2])
+    array([-1.,  2.])
+    """
+    x = asarray(x)
+    if any(isreal(x) & (x < 0)):
+        x = x * 1.0
+    return x
+
+def _fix_real_abs_gt_1(x):
+    """Convert `x` to complex if it has real components x_i with abs(x_i)>1.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_real_abs_gt_1([0,1])
+    array([0, 1])
+
+    >>> np.lib.scimath._fix_real_abs_gt_1([0,2])
+    array([ 0.+0.j,  2.+0.j])
+    """
+    x = asarray(x)
+    if any(isreal(x) & (abs(x) > 1)):
+        x = _tocomplex(x)
+    return x
+
+def sqrt(x):
+    """
+    Compute the square root of x.
+
+    For negative input elements, a complex value is returned
+    (unlike `numpy.sqrt` which returns NaN).
+
+    Parameters
+    ----------
+    x : array_like
+       The input value(s).
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The square root of `x`. If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.sqrt
+
+    Examples
+    --------
+    For real, non-negative inputs this works just like `numpy.sqrt`:
+
+    >>> np.lib.scimath.sqrt(1)
+    1.0
+    >>> np.lib.scimath.sqrt([1, 4])
+    array([ 1.,  2.])
+
+    But it automatically handles negative inputs:
+
+    >>> np.lib.scimath.sqrt(-1)
+    (0.0+1.0j)
+    >>> np.lib.scimath.sqrt([-1,4])
+    array([ 0.+1.j,  2.+0.j])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.sqrt(x)
+
+def log(x):
+    """
+    Compute the natural logarithm of `x`.
+
+    Return the "principal value" (for a description of this, see `numpy.log`)
+    of :math:`log_e(x)`. For real `x > 0`, this is a real number (``log(0)``
+    returns ``-inf`` and ``log(np.inf)`` returns ``inf``). Otherwise, the
+    complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose log is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.log
+
+    Notes
+    -----
+    For a log() that returns ``NAN`` when real `x < 0`, use `numpy.log`
+    (note, however, that otherwise `numpy.log` and this `log` are identical,
+    i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`, and,
+    notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+    >>> np.emath.log(np.exp(1))
+    1.0
+
+    Negative arguments are handled "correctly" (recall that
+    ``exp(log(x)) == x`` does *not* hold for real ``x < 0``):
+
+    >>> np.emath.log(-np.exp(1)) == (1 + np.pi * 1j)
+    True
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log(x)
+
+def log10(x):
+    """
+    Compute the logarithm base 10 of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.log10`) of :math:`log_{10}(x)`. For real `x > 0`, this
+    is a real number (``log10(0)`` returns ``-inf`` and ``log10(np.inf)``
+    returns ``inf``). Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose log base 10 is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base 10 of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.log10
+
+    Notes
+    -----
+    For a log10() that returns ``NAN`` when real `x < 0`, use `numpy.log10`
+    (note, however, that otherwise `numpy.log10` and this `log10` are
+    identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`,
+    and, notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+
+    (We set the printing precision so the example can be auto-tested)
+
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.log10(10**1)
+    1.0
+
+    >>> np.emath.log10([-10**1, -10**2, 10**2])
+    array([ 1.+1.3644j,  2.+1.3644j,  2.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log10(x)
+
+def logn(n, x):
+    """
+    Take log base n of x.
+
+    If `x` contains negative inputs, the answer is computed and returned in the
+    complex domain.
+
+    Parameters
+    ----------
+    n : int
+       The base in which the log is taken.
+    x : array_like
+       The value(s) whose log base `n` is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base `n` of the `x` value(s). If `x` was a scalar, so is
+       `out`, otherwise an array is returned.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.lib.scimath.logn(2, [4, 8])
+    array([ 2.,  3.])
+    >>> np.lib.scimath.logn(2, [-4, -8, 8])
+    array([ 2.+4.5324j,  3.+4.5324j,  3.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    n = _fix_real_lt_zero(n)
+    return nx.log(x)/nx.log(n)
+
+def log2(x):
+    """
+    Compute the logarithm base 2 of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.log2`) of :math:`log_2(x)`. For real `x > 0`, this is
+    a real number (``log2(0)`` returns ``-inf`` and ``log2(np.inf)`` returns
+    ``inf``). Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose log base 2 is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base 2 of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.log2
+
+    Notes
+    -----
+    For a log2() that returns ``NAN`` when real `x < 0`, use `numpy.log2`
+    (note, however, that otherwise `numpy.log2` and this `log2` are
+    identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`,
+    and, notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+    We set the printing precision so the example can be auto-tested:
+
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.log2(8)
+    3.0
+    >>> np.emath.log2([-4, -8, 8])
+    array([ 2.+4.5324j,  3.+4.5324j,  3.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log2(x)
+
+def power(x, p):
+    """
+    Return x to the power p, (x**p).
+
+    If `x` contains negative values, the output is converted to the
+    complex domain.
+
+    Parameters
+    ----------
+    x : array_like
+        The input value(s).
+    p : array_like of ints
+        The power(s) to which `x` is raised. If `x` contains multiple values,
+        `p` has to either be a scalar, or contain the same number of values
+        as `x`. In the latter case, the result is
+        ``x[0]**p[0], x[1]**p[1], ...``.
+
+    Returns
+    -------
+    out : ndarray or scalar
+        The result of ``x**p``. If `x` and `p` are scalars, so is `out`,
+        otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.power
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.lib.scimath.power([2, 4], 2)
+    array([ 4, 16])
+    >>> np.lib.scimath.power([2, 4], -2)
+    array([ 0.25  ,  0.0625])
+    >>> np.lib.scimath.power([-2, 4], 2)
+    array([  4.+0.j,  16.+0.j])
+
+    """
+    x = _fix_real_lt_zero(x)
+    p = _fix_int_lt_zero(p)
+    return nx.power(x, p)
+
+def arccos(x):
+    """
+    Compute the inverse cosine of x.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arccos`) of the inverse cosine of `x`. For real `x` such that
+    `abs(x) <= 1`, this is a real number in the closed interval
+    :math:`[0, \\pi]`.  Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose arccos is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse cosine(s) of the `x` value(s). If `x` was a scalar, so
+       is `out`, otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.arccos
+
+    Notes
+    -----
+    For an arccos() that returns ``NAN`` when real `x` is not in the
+    interval ``[-1,1]``, use `numpy.arccos`.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arccos(1) # a scalar is returned
+    0.0
+
+    >>> np.emath.arccos([1,2])
+    array([ 0.-0.j   ,  0.+1.317j])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arccos(x)
+
+def arcsin(x):
+    """
+    Compute the inverse sine of x.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arcsin`) of the inverse sine of `x`. For real `x` such that
+    `abs(x) <= 1`, this is a real number in the closed interval
+    :math:`[-\\pi/2, \\pi/2]`.  Otherwise, the complex principle value is
+    returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose arcsin is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse sine(s) of the `x` value(s). If `x` was a scalar, so
+       is `out`, otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.arcsin
+
+    Notes
+    -----
+    For an arcsin() that returns ``NAN`` when real `x` is not in the
+    interval ``[-1,1]``, use `numpy.arcsin`.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arcsin(0)
+    0.0
+
+    >>> np.emath.arcsin([0,1])
+    array([ 0.    ,  1.5708])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arcsin(x)
+
+def arctanh(x):
+    """
+    Compute the inverse hyperbolic tangent of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arctanh`) of `arctanh(x)`. For real `x` such that
+    `abs(x) < 1`, this is a real number.  If `abs(x) > 1`, or if `x` is
+    complex, the result is complex. Finally, `x = 1` returns``inf`` and
+    `x=-1` returns ``-inf``.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose arctanh is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse hyperbolic tangent(s) of the `x` value(s). If `x` was
+       a scalar so is `out`, otherwise an array is returned.
+
+
+    See Also
+    --------
+    numpy.arctanh
+
+    Notes
+    -----
+    For an arctanh() that returns ``NAN`` when real `x` is not in the
+    interval ``(-1,1)``, use `numpy.arctanh` (this latter, however, does
+    return +/-inf for `x = +/-1`).
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arctanh(np.matrix(np.eye(2)))
+    array([[ Inf,   0.],
+           [  0.,  Inf]])
+    >>> np.emath.arctanh([1j])
+    array([ 0.+0.7854j])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arctanh(x)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/setup.py
new file mode 100644
index 0000000000..d342410b8a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/setup.py
@@ -0,0 +1,12 @@
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+
+    config = Configuration('lib', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.py
new file mode 100644
index 0000000000..ffbe567216
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.py
@@ -0,0 +1,873 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import (
+    asarray, zeros, outer, concatenate, isscalar, array, asanyarray
+    )
+from numpy.core.fromnumeric import product, reshape
+from numpy.core import vstack, atleast_3d
+
+
+__all__ = [
+    'column_stack', 'row_stack', 'dstack', 'array_split', 'split',
+    'hsplit', 'vsplit', 'dsplit', 'apply_over_axes', 'expand_dims',
+    'apply_along_axis', 'kron', 'tile', 'get_array_wrap'
+    ]
+
+
+def apply_along_axis(func1d, axis, arr, *args, **kwargs):
+    """
+    Apply a function to 1-D slices along the given axis.
+
+    Execute `func1d(a, *args)` where `func1d` operates on 1-D arrays and `a`
+    is a 1-D slice of `arr` along `axis`.
+
+    Parameters
+    ----------
+    func1d : function
+        This function should accept 1-D arrays. It is applied to 1-D
+        slices of `arr` along the specified axis.
+    axis : integer
+        Axis along which `arr` is sliced.
+    arr : ndarray
+        Input array.
+    args : any
+        Additional arguments to `func1d`.
+    kwargs: any
+        Additional named arguments to `func1d`.
+
+        .. versionadded:: 1.9.0
+
+
+    Returns
+    -------
+    apply_along_axis : ndarray
+        The output array. The shape of `outarr` is identical to the shape of
+        `arr`, except along the `axis` dimension, where the length of `outarr`
+        is equal to the size of the return value of `func1d`.  If `func1d`
+        returns a scalar `outarr` will have one fewer dimensions than `arr`.
+
+    See Also
+    --------
+    apply_over_axes : Apply a function repeatedly over multiple axes.
+
+    Examples
+    --------
+    >>> def my_func(a):
+    ...     \"\"\"Average first and last element of a 1-D array\"\"\"
+    ...     return (a[0] + a[-1]) * 0.5
+    >>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])
+    >>> np.apply_along_axis(my_func, 0, b)
+    array([ 4.,  5.,  6.])
+    >>> np.apply_along_axis(my_func, 1, b)
+    array([ 2.,  5.,  8.])
+
+    For a function that doesn't return a scalar, the number of dimensions in
+    `outarr` is the same as `arr`.
+
+    >>> b = np.array([[8,1,7], [4,3,9], [5,2,6]])
+    >>> np.apply_along_axis(sorted, 1, b)
+    array([[1, 7, 8],
+           [3, 4, 9],
+           [2, 5, 6]])
+
+    """
+    arr = asarray(arr)
+    nd = arr.ndim
+    if axis < 0:
+        axis += nd
+    if (axis >= nd):
+        raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d."
+            % (axis, nd))
+    ind = [0]*(nd-1)
+    i = zeros(nd, 'O')
+    indlist = list(range(nd))
+    indlist.remove(axis)
+    i[axis] = slice(None, None)
+    outshape = asarray(arr.shape).take(indlist)
+    i.put(indlist, ind)
+    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+    #  if res is a number, then we have a smaller output array
+    if isscalar(res):
+        outarr = zeros(outshape, asarray(res).dtype)
+        outarr[tuple(ind)] = res
+        Ntot = product(outshape)
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= outshape[n]) and (n > (1-nd)):
+                ind[n-1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(ind)] = res
+            k += 1
+        return outarr
+    else:
+        Ntot = product(outshape)
+        holdshape = outshape
+        outshape = list(arr.shape)
+        outshape[axis] = len(res)
+        outarr = zeros(outshape, asarray(res).dtype)
+        outarr[tuple(i.tolist())] = res
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= holdshape[n]) and (n > (1-nd)):
+                ind[n-1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(i.tolist())] = res
+            k += 1
+        return outarr
+
+
+def apply_over_axes(func, a, axes):
+    """
+    Apply a function repeatedly over multiple axes.
+
+    `func` is called as `res = func(a, axis)`, where `axis` is the first
+    element of `axes`.  The result `res` of the function call must have
+    either the same dimensions as `a` or one less dimension.  If `res`
+    has one less dimension than `a`, a dimension is inserted before
+    `axis`.  The call to `func` is then repeated for each axis in `axes`,
+    with `res` as the first argument.
+
+    Parameters
+    ----------
+    func : function
+        This function must take two arguments, `func(a, axis)`.
+    a : array_like
+        Input array.
+    axes : array_like
+        Axes over which `func` is applied; the elements must be integers.
+
+    Returns
+    -------
+    apply_over_axis : ndarray
+        The output array.  The number of dimensions is the same as `a`,
+        but the shape can be different.  This depends on whether `func`
+        changes the shape of its output with respect to its input.
+
+    See Also
+    --------
+    apply_along_axis :
+        Apply a function to 1-D slices of an array along the given axis.
+
+    Notes
+    ------
+    This function is equivalent to tuple axis arguments to reorderable ufuncs
+    with keepdims=True. Tuple axis arguments to ufuncs have been availabe since
+    version 1.7.0.
+
+    Examples
+    --------
+    >>> a = np.arange(24).reshape(2,3,4)
+    >>> a
+    array([[[ 0,  1,  2,  3],
+            [ 4,  5,  6,  7],
+            [ 8,  9, 10, 11]],
+           [[12, 13, 14, 15],
+            [16, 17, 18, 19],
+            [20, 21, 22, 23]]])
+
+    Sum over axes 0 and 2. The result has same number of dimensions
+    as the original array:
+
+    >>> np.apply_over_axes(np.sum, a, [0,2])
+    array([[[ 60],
+            [ 92],
+            [124]]])
+
+    Tuple axis arguments to ufuncs are equivalent:
+
+    >>> np.sum(a, axis=(0,2), keepdims=True)
+    array([[[ 60],
+            [ 92],
+            [124]]])
+
+    """
+    val = asarray(a)
+    N = a.ndim
+    if array(axes).ndim == 0:
+        axes = (axes,)
+    for axis in axes:
+        if axis < 0:
+            axis = N + axis
+        args = (val, axis)
+        res = func(*args)
+        if res.ndim == val.ndim:
+            val = res
+        else:
+            res = expand_dims(res, axis)
+            if res.ndim == val.ndim:
+                val = res
+            else:
+                raise ValueError("function is not returning "
+                        "an array of the correct shape")
+    return val
+
+def expand_dims(a, axis):
+    """
+    Expand the shape of an array.
+
+    Insert a new axis, corresponding to a given position in the array shape.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int
+        Position (amongst axes) where new axis is to be inserted.
+
+    Returns
+    -------
+    res : ndarray
+        Output array. The number of dimensions is one greater than that of
+        the input array.
+
+    See Also
+    --------
+    doc.indexing, atleast_1d, atleast_2d, atleast_3d
+
+    Examples
+    --------
+    >>> x = np.array([1,2])
+    >>> x.shape
+    (2,)
+
+    The following is equivalent to ``x[np.newaxis,:]`` or ``x[np.newaxis]``:
+
+    >>> y = np.expand_dims(x, axis=0)
+    >>> y
+    array([[1, 2]])
+    >>> y.shape
+    (1, 2)
+
+    >>> y = np.expand_dims(x, axis=1)  # Equivalent to x[:,newaxis]
+    >>> y
+    array([[1],
+           [2]])
+    >>> y.shape
+    (2, 1)
+
+    Note that some examples may use ``None`` instead of ``np.newaxis``.  These
+    are the same objects:
+
+    >>> np.newaxis is None
+    True
+
+    """
+    a = asarray(a)
+    shape = a.shape
+    if axis < 0:
+        axis = axis + len(shape) + 1
+    return a.reshape(shape[:axis] + (1,) + shape[axis:])
+
+row_stack = vstack
+
+def column_stack(tup):
+    """
+    Stack 1-D arrays as columns into a 2-D array.
+
+    Take a sequence of 1-D arrays and stack them as columns
+    to make a single 2-D array. 2-D arrays are stacked as-is,
+    just like with `hstack`.  1-D arrays are turned into 2-D columns
+    first.
+
+    Parameters
+    ----------
+    tup : sequence of 1-D or 2-D arrays.
+        Arrays to stack. All of them must have the same first dimension.
+
+    Returns
+    -------
+    stacked : 2-D array
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    hstack, vstack, concatenate
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.column_stack((a,b))
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrays = []
+    for v in tup:
+        arr = array(v, copy=False, subok=True)
+        if arr.ndim < 2:
+            arr = array(arr, copy=False, subok=True, ndmin=2).T
+        arrays.append(arr)
+    return _nx.concatenate(arrays, 1)
+
+def dstack(tup):
+    """
+    Stack arrays in sequence depth wise (along third axis).
+
+    Takes a sequence of arrays and stack them along the third axis
+    to make a single array. Rebuilds arrays divided by `dsplit`.
+    This is a simple way to stack 2D arrays (images) into a single
+    3D array for processing.
+
+    Parameters
+    ----------
+    tup : sequence of arrays
+        Arrays to stack. All of them must have the same shape along all
+        but the third axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    vstack : Stack along first axis.
+    hstack : Stack along second axis.
+    concatenate : Join a sequence of arrays along an existing axis.
+    dsplit : Split array along third axis.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=2)``.
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.dstack((a,b))
+    array([[[1, 2],
+            [2, 3],
+            [3, 4]]])
+
+    >>> a = np.array([[1],[2],[3]])
+    >>> b = np.array([[2],[3],[4]])
+    >>> np.dstack((a,b))
+    array([[[1, 2]],
+           [[2, 3]],
+           [[3, 4]]])
+
+    """
+    return _nx.concatenate([atleast_3d(_m) for _m in tup], 2)
+
+def _replace_zero_by_x_arrays(sub_arys):
+    for i in range(len(sub_arys)):
+        if len(_nx.shape(sub_arys[i])) == 0:
+            sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
+        elif _nx.sometrue(_nx.equal(_nx.shape(sub_arys[i]), 0)):
+            sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
+    return sub_arys
+
+def array_split(ary, indices_or_sections, axis=0):
+    """
+    Split an array into multiple sub-arrays.
+
+    Please refer to the ``split`` documentation.  The only difference
+    between these functions is that ``array_split`` allows
+    `indices_or_sections` to be an integer that does *not* equally
+    divide the axis.
+
+    See Also
+    --------
+    split : Split array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(8.0)
+    >>> np.array_split(x, 3)
+        [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.])]
+
+    """
+    try:
+        Ntotal = ary.shape[axis]
+    except AttributeError:
+        Ntotal = len(ary)
+    try:
+        # handle scalar case.
+        Nsections = len(indices_or_sections) + 1
+        div_points = [0] + list(indices_or_sections) + [Ntotal]
+    except TypeError:
+        # indices_or_sections is a scalar, not an array.
+        Nsections = int(indices_or_sections)
+        if Nsections <= 0:
+            raise ValueError('number sections must be larger than 0.')
+        Neach_section, extras = divmod(Ntotal, Nsections)
+        section_sizes = ([0] +
+                         extras * [Neach_section+1] +
+                         (Nsections-extras) * [Neach_section])
+        div_points = _nx.array(section_sizes).cumsum()
+
+    sub_arys = []
+    sary = _nx.swapaxes(ary, axis, 0)
+    for i in range(Nsections):
+        st = div_points[i]
+        end = div_points[i + 1]
+        sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0))
+
+    return sub_arys
+
+
+def split(ary,indices_or_sections,axis=0):
+    """
+    Split an array into multiple sub-arrays.
+
+    Parameters
+    ----------
+    ary : ndarray
+        Array to be divided into sub-arrays.
+    indices_or_sections : int or 1-D array
+        If `indices_or_sections` is an integer, N, the array will be divided
+        into N equal arrays along `axis`.  If such a split is not possible,
+        an error is raised.
+
+        If `indices_or_sections` is a 1-D array of sorted integers, the entries
+        indicate where along `axis` the array is split.  For example,
+        ``[2, 3]`` would, for ``axis=0``, result in
+
+          - ary[:2]
+          - ary[2:3]
+          - ary[3:]
+
+        If an index exceeds the dimension of the array along `axis`,
+        an empty sub-array is returned correspondingly.
+    axis : int, optional
+        The axis along which to split, default is 0.
+
+    Returns
+    -------
+    sub-arrays : list of ndarrays
+        A list of sub-arrays.
+
+    Raises
+    ------
+    ValueError
+        If `indices_or_sections` is given as an integer, but
+        a split does not result in equal division.
+
+    See Also
+    --------
+    array_split : Split an array into multiple sub-arrays of equal or
+                  near-equal size.  Does not raise an exception if
+                  an equal division cannot be made.
+    hsplit : Split array into multiple sub-arrays horizontally (column-wise).
+    vsplit : Split array into multiple sub-arrays vertically (row wise).
+    dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
+    concatenate : Join a sequence of arrays along an existing axis.
+    stack : Join a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise).
+    vstack : Stack arrays in sequence vertically (row wise).
+    dstack : Stack arrays in sequence depth wise (along third dimension).
+
+    Examples
+    --------
+    >>> x = np.arange(9.0)
+    >>> np.split(x, 3)
+    [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.,  8.])]
+
+    >>> x = np.arange(8.0)
+    >>> np.split(x, [3, 5, 6, 10])
+    [array([ 0.,  1.,  2.]),
+     array([ 3.,  4.]),
+     array([ 5.]),
+     array([ 6.,  7.]),
+     array([], dtype=float64)]
+
+    """
+    try:
+        len(indices_or_sections)
+    except TypeError:
+        sections = indices_or_sections
+        N = ary.shape[axis]
+        if N % sections:
+            raise ValueError(
+                'array split does not result in an equal division')
+    res = array_split(ary, indices_or_sections, axis)
+    return res
+
+def hsplit(ary, indices_or_sections):
+    """
+    Split an array into multiple sub-arrays horizontally (column-wise).
+
+    Please refer to the `split` documentation.  `hsplit` is equivalent
+    to `split` with ``axis=1``, the array is always split along the second
+    axis regardless of the array dimension.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(4, 4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+    >>> np.hsplit(x, 2)
+    [array([[  0.,   1.],
+           [  4.,   5.],
+           [  8.,   9.],
+           [ 12.,  13.]]),
+     array([[  2.,   3.],
+           [  6.,   7.],
+           [ 10.,  11.],
+           [ 14.,  15.]])]
+    >>> np.hsplit(x, np.array([3, 6]))
+    [array([[  0.,   1.,   2.],
+           [  4.,   5.,   6.],
+           [  8.,   9.,  10.],
+           [ 12.,  13.,  14.]]),
+     array([[  3.],
+           [  7.],
+           [ 11.],
+           [ 15.]]),
+     array([], dtype=float64)]
+
+    With a higher dimensional array the split is still along the second axis.
+
+    >>> x = np.arange(8.0).reshape(2, 2, 2)
+    >>> x
+    array([[[ 0.,  1.],
+            [ 2.,  3.]],
+           [[ 4.,  5.],
+            [ 6.,  7.]]])
+    >>> np.hsplit(x, 2)
+    [array([[[ 0.,  1.]],
+           [[ 4.,  5.]]]),
+     array([[[ 2.,  3.]],
+           [[ 6.,  7.]]])]
+
+    """
+    if len(_nx.shape(ary)) == 0:
+        raise ValueError('hsplit only works on arrays of 1 or more dimensions')
+    if len(ary.shape) > 1:
+        return split(ary, indices_or_sections, 1)
+    else:
+        return split(ary, indices_or_sections, 0)
+
+def vsplit(ary, indices_or_sections):
+    """
+    Split an array into multiple sub-arrays vertically (row-wise).
+
+    Please refer to the ``split`` documentation.  ``vsplit`` is equivalent
+    to ``split`` with `axis=0` (default), the array is always split along the
+    first axis regardless of the array dimension.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(4, 4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+    >>> np.vsplit(x, 2)
+    [array([[ 0.,  1.,  2.,  3.],
+           [ 4.,  5.,  6.,  7.]]),
+     array([[  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])]
+    >>> np.vsplit(x, np.array([3, 6]))
+    [array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.]]),
+     array([[ 12.,  13.,  14.,  15.]]),
+     array([], dtype=float64)]
+
+    With a higher dimensional array the split is still along the first axis.
+
+    >>> x = np.arange(8.0).reshape(2, 2, 2)
+    >>> x
+    array([[[ 0.,  1.],
+            [ 2.,  3.]],
+           [[ 4.,  5.],
+            [ 6.,  7.]]])
+    >>> np.vsplit(x, 2)
+    [array([[[ 0.,  1.],
+            [ 2.,  3.]]]),
+     array([[[ 4.,  5.],
+            [ 6.,  7.]]])]
+
+    """
+    if len(_nx.shape(ary)) < 2:
+        raise ValueError('vsplit only works on arrays of 2 or more dimensions')
+    return split(ary, indices_or_sections, 0)
+
+def dsplit(ary, indices_or_sections):
+    """
+    Split array into multiple sub-arrays along the 3rd axis (depth).
+
+    Please refer to the `split` documentation.  `dsplit` is equivalent
+    to `split` with ``axis=2``, the array is always split along the third
+    axis provided the array dimension is greater than or equal to 3.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(2, 2, 4)
+    >>> x
+    array([[[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.]],
+           [[  8.,   9.,  10.,  11.],
+            [ 12.,  13.,  14.,  15.]]])
+    >>> np.dsplit(x, 2)
+    [array([[[  0.,   1.],
+            [  4.,   5.]],
+           [[  8.,   9.],
+            [ 12.,  13.]]]),
+     array([[[  2.,   3.],
+            [  6.,   7.]],
+           [[ 10.,  11.],
+            [ 14.,  15.]]])]
+    >>> np.dsplit(x, np.array([3, 6]))
+    [array([[[  0.,   1.,   2.],
+            [  4.,   5.,   6.]],
+           [[  8.,   9.,  10.],
+            [ 12.,  13.,  14.]]]),
+     array([[[  3.],
+            [  7.]],
+           [[ 11.],
+            [ 15.]]]),
+     array([], dtype=float64)]
+
+    """
+    if len(_nx.shape(ary)) < 3:
+        raise ValueError('dsplit only works on arrays of 3 or more dimensions')
+    return split(ary, indices_or_sections, 2)
+
+def get_array_prepare(*args):
+    """Find the wrapper for the array with the highest priority.
+
+    In case of ties, leftmost wins. If no wrapper is found, return None
+    """
+    wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
+                 x.__array_prepare__) for i, x in enumerate(args)
+                                   if hasattr(x, '__array_prepare__'))
+    if wrappers:
+        return wrappers[-1][-1]
+    return None
+
+def get_array_wrap(*args):
+    """Find the wrapper for the array with the highest priority.
+
+    In case of ties, leftmost wins. If no wrapper is found, return None
+    """
+    wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
+                 x.__array_wrap__) for i, x in enumerate(args)
+                                   if hasattr(x, '__array_wrap__'))
+    if wrappers:
+        return wrappers[-1][-1]
+    return None
+
+def kron(a, b):
+    """
+    Kronecker product of two arrays.
+
+    Computes the Kronecker product, a composite array made of blocks of the
+    second array scaled by the first.
+
+    Parameters
+    ----------
+    a, b : array_like
+
+    Returns
+    -------
+    out : ndarray
+
+    See Also
+    --------
+    outer : The outer product
+
+    Notes
+    -----
+    The function assumes that the number of dimensions of `a` and `b`
+    are the same, if necessary prepending the smallest with ones.
+    If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`,
+    the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`.
+    The elements are products of elements from `a` and `b`, organized
+    explicitly by::
+
+        kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN]
+
+    where::
+
+        kt = it * st + jt,  t = 0,...,N
+
+    In the common 2-D case (N=1), the block structure can be visualized::
+
+        [[ a[0,0]*b,   a[0,1]*b,  ... , a[0,-1]*b  ],
+         [  ...                              ...   ],
+         [ a[-1,0]*b,  a[-1,1]*b, ... , a[-1,-1]*b ]]
+
+
+    Examples
+    --------
+    >>> np.kron([1,10,100], [5,6,7])
+    array([  5,   6,   7,  50,  60,  70, 500, 600, 700])
+    >>> np.kron([5,6,7], [1,10,100])
+    array([  5,  50, 500,   6,  60, 600,   7,  70, 700])
+
+    >>> np.kron(np.eye(2), np.ones((2,2)))
+    array([[ 1.,  1.,  0.,  0.],
+           [ 1.,  1.,  0.,  0.],
+           [ 0.,  0.,  1.,  1.],
+           [ 0.,  0.,  1.,  1.]])
+
+    >>> a = np.arange(100).reshape((2,5,2,5))
+    >>> b = np.arange(24).reshape((2,3,4))
+    >>> c = np.kron(a,b)
+    >>> c.shape
+    (2, 10, 6, 20)
+    >>> I = (1,3,0,2)
+    >>> J = (0,2,1)
+    >>> J1 = (0,) + J             # extend to ndim=4
+    >>> S1 = (1,) + b.shape
+    >>> K = tuple(np.array(I) * np.array(S1) + np.array(J1))
+    >>> c[K] == a[I]*b[J]
+    True
+
+    """
+    b = asanyarray(b)
+    a = array(a, copy=False, subok=True, ndmin=b.ndim)
+    ndb, nda = b.ndim, a.ndim
+    if (nda == 0 or ndb == 0):
+        return _nx.multiply(a, b)
+    as_ = a.shape
+    bs = b.shape
+    if not a.flags.contiguous:
+        a = reshape(a, as_)
+    if not b.flags.contiguous:
+        b = reshape(b, bs)
+    nd = ndb
+    if (ndb != nda):
+        if (ndb > nda):
+            as_ = (1,)*(ndb-nda) + as_
+        else:
+            bs = (1,)*(nda-ndb) + bs
+            nd = nda
+    result = outer(a, b).reshape(as_+bs)
+    axis = nd-1
+    for _ in range(nd):
+        result = concatenate(result, axis=axis)
+    wrapper = get_array_prepare(a, b)
+    if wrapper is not None:
+        result = wrapper(result)
+    wrapper = get_array_wrap(a, b)
+    if wrapper is not None:
+        result = wrapper(result)
+    return result
+
+
+def tile(A, reps):
+    """
+    Construct an array by repeating A the number of times given by reps.
+
+    If `reps` has length ``d``, the result will have dimension of
+    ``max(d, A.ndim)``.
+
+    If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
+    axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
+    or shape (1, 1, 3) for 3-D replication. If this is not the desired
+    behavior, promote `A` to d-dimensions manually before calling this
+    function.
+
+    If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
+    Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
+    (1, 1, 2, 2).
+
+    Note : Although tile may be used for broadcasting, it is strongly
+    recommended to use numpy's broadcasting operations and functions.
+
+    Parameters
+    ----------
+    A : array_like
+        The input array.
+    reps : array_like
+        The number of repetitions of `A` along each axis.
+
+    Returns
+    -------
+    c : ndarray
+        The tiled output array.
+
+    See Also
+    --------
+    repeat : Repeat elements of an array.
+    broadcast_to : Broadcast an array to a new shape
+
+    Examples
+    --------
+    >>> a = np.array([0, 1, 2])
+    >>> np.tile(a, 2)
+    array([0, 1, 2, 0, 1, 2])
+    >>> np.tile(a, (2, 2))
+    array([[0, 1, 2, 0, 1, 2],
+           [0, 1, 2, 0, 1, 2]])
+    >>> np.tile(a, (2, 1, 2))
+    array([[[0, 1, 2, 0, 1, 2]],
+           [[0, 1, 2, 0, 1, 2]]])
+
+    >>> b = np.array([[1, 2], [3, 4]])
+    >>> np.tile(b, 2)
+    array([[1, 2, 1, 2],
+           [3, 4, 3, 4]])
+    >>> np.tile(b, (2, 1))
+    array([[1, 2],
+           [3, 4],
+           [1, 2],
+           [3, 4]])
+
+    >>> c = np.array([1,2,3,4])
+    >>> np.tile(c,(4,1))
+    array([[1, 2, 3, 4],
+           [1, 2, 3, 4],
+           [1, 2, 3, 4],
+           [1, 2, 3, 4]])
+    """
+    try:
+        tup = tuple(reps)
+    except TypeError:
+        tup = (reps,)
+    d = len(tup)
+    if all(x == 1 for x in tup) and isinstance(A, _nx.ndarray):
+        # Fixes the problem that the function does not make a copy if A is a
+        # numpy array and the repetitions are 1 in all dimensions
+        return _nx.array(A, copy=True, subok=True, ndmin=d)
+    else:
+        # Note that no copy of zero-sized arrays is made. However since they
+        # have no data there is no risk of an inadvertent overwrite.
+        c = _nx.array(A, copy=False, subok=True, ndmin=d)
+    if (d < c.ndim):
+        tup = (1,)*(c.ndim-d) + tup
+    shape_out = tuple(s*t for s, t in zip(c.shape, tup))
+    n = c.size
+    if n > 0:
+        for dim_in, nrep in zip(c.shape, tup):
+            if nrep != 1:
+                c = c.reshape(-1, n).repeat(nrep, 0)
+            n //= dim_in
+    return c.reshape(shape_out)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
new file mode 100644
index 0000000000..4c23ab3555
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
@@ -0,0 +1,200 @@
+"""
+Utilities that manipulate strides to achieve desirable effects.
+
+An explanation of strides can be found in the "ndarray.rst" file in the
+NumPy reference guide.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = ['broadcast_to', 'broadcast_arrays']
+
+
+class DummyArray(object):
+    """Dummy object that just exists to hang __array_interface__ dictionaries
+    and possibly keep alive a reference to a base array.
+    """
+
+    def __init__(self, interface, base=None):
+        self.__array_interface__ = interface
+        self.base = base
+
+
+def _maybe_view_as_subclass(original_array, new_array):
+    if type(original_array) is not type(new_array):
+        # if input was an ndarray subclass and subclasses were OK,
+        # then view the result as that subclass.
+        new_array = new_array.view(type=type(original_array))
+        # Since we have done something akin to a view from original_array, we
+        # should let the subclass finalize (if it has it implemented, i.e., is
+        # not None).
+        if new_array.__array_finalize__:
+            new_array.__array_finalize__(original_array)
+    return new_array
+
+
+def as_strided(x, shape=None, strides=None, subok=False):
+    """ Make an ndarray from the given array with the given shape and strides.
+    """
+    # first convert input to array, possibly keeping subclass
+    x = np.array(x, copy=False, subok=subok)
+    interface = dict(x.__array_interface__)
+    if shape is not None:
+        interface['shape'] = tuple(shape)
+    if strides is not None:
+        interface['strides'] = tuple(strides)
+    array = np.asarray(DummyArray(interface, base=x))
+
+    if array.dtype.fields is None and x.dtype.fields is not None:
+        # This should only happen if x.dtype is [('', 'Vx')]
+        array.dtype = x.dtype
+
+    return _maybe_view_as_subclass(x, array)
+
+
+def _broadcast_to(array, shape, subok, readonly):
+    shape = tuple(shape) if np.iterable(shape) else (shape,)
+    array = np.array(array, copy=False, subok=subok)
+    if not shape and array.shape:
+        raise ValueError('cannot broadcast a non-scalar to a scalar array')
+    if any(size < 0 for size in shape):
+        raise ValueError('all elements of broadcast shape must be non-'
+                         'negative')
+    needs_writeable = not readonly and array.flags.writeable
+    extras = ['reduce_ok'] if needs_writeable else []
+    op_flag = 'readwrite' if needs_writeable else 'readonly'
+    broadcast = np.nditer(
+        (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
+        op_flags=[op_flag], itershape=shape, order='C').itviews[0]
+    result = _maybe_view_as_subclass(array, broadcast)
+    if needs_writeable and not result.flags.writeable:
+        result.flags.writeable = True
+    return result
+
+
+def broadcast_to(array, shape, subok=False):
+    """Broadcast an array to a new shape.
+
+    Parameters
+    ----------
+    array : array_like
+        The array to broadcast.
+    shape : tuple
+        The shape of the desired array.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned array will be forced to be a base-class array (default).
+
+    Returns
+    -------
+    broadcast : array
+        A readonly view on the original array with the given shape. It is
+        typically not contiguous. Furthermore, more than one element of a
+        broadcasted array may refer to a single memory location.
+
+    Raises
+    ------
+    ValueError
+        If the array is not compatible with the new shape according to NumPy's
+        broadcasting rules.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> np.broadcast_to(x, (3, 3))
+    array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]])
+    """
+    return _broadcast_to(array, shape, subok=subok, readonly=True)
+
+
+def _broadcast_shape(*args):
+    """Returns the shape of the ararys that would result from broadcasting the
+    supplied arrays against each other.
+    """
+    if not args:
+        raise ValueError('must provide at least one argument')
+    # use the old-iterator because np.nditer does not handle size 0 arrays
+    # consistently
+    b = np.broadcast(*args[:32])
+    # unfortunately, it cannot handle 32 or more arguments directly
+    for pos in range(32, len(args), 31):
+        # ironically, np.broadcast does not properly handle np.broadcast
+        # objects (it treats them as scalars)
+        # use broadcasting to avoid allocating the full array
+        b = broadcast_to(0, b.shape)
+        b = np.broadcast(b, *args[pos:(pos + 31)])
+    return b.shape
+
+
+def broadcast_arrays(*args, **kwargs):
+    """
+    Broadcast any number of arrays against each other.
+
+    Parameters
+    ----------
+    `*args` : array_likes
+        The arrays to broadcast.
+
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned arrays will be forced to be a base-class array (default).
+
+    Returns
+    -------
+    broadcasted : list of arrays
+        These arrays are views on the original arrays.  They are typically
+        not contiguous.  Furthermore, more than one element of a
+        broadcasted array may refer to a single memory location.  If you
+        need to write to the arrays, make copies first.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3]])
+    >>> y = np.array([[1],[2],[3]])
+    >>> np.broadcast_arrays(x, y)
+    [array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]]), array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])]
+
+    Here is a useful idiom for getting contiguous copies instead of
+    non-contiguous views.
+
+    >>> [np.array(a) for a in np.broadcast_arrays(x, y)]
+    [array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]]), array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])]
+
+    """
+    # nditer is not used here to avoid the limit of 32 arrays.
+    # Otherwise, something like the following one-liner would suffice:
+    # return np.nditer(args, flags=['multi_index', 'zerosize_ok'],
+    #                  order='C').itviews
+
+    subok = kwargs.pop('subok', False)
+    if kwargs:
+        raise TypeError('broadcast_arrays() got an unexpected keyword '
+                        'argument {}'.format(kwargs.pop()))
+    args = [np.array(_m, copy=False, subok=subok) for _m in args]
+
+    shape = _broadcast_shape(*args)
+
+    if all(array.shape == shape for array in args):
+        # Common case where nothing needs to be broadcasted.
+        return args
+
+    # TODO: consider making the results of broadcast_arrays readonly to match
+    # broadcast_to. This will require a deprecation cycle.
+    return [_broadcast_to(array, shape, subok=subok, readonly=False)
+            for array in args]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
new file mode 100644
index 0000000000000000000000000000000000000000..12936c92d8f8a122f2342a7782f56e7506010c40
GIT binary patch
literal 258
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1J<8Ps^qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
zFV09TNL9B|&@j=_)KREaKmuG1Ov!nrxdoMa$@xX8dby=JC7FpuMTwPM@kOc0`FX`9
zMWx9lT!oAfRa|)~5ZOW|Z-&-T#-#S3LS_wbMsJo@sDhM|%7Rp`LY7b_e+zF0Z^rhZ
zLRJlL=1|5OKR-XO|NsC02NT}*B}tvJg=`vr$?@??rI|S;nR)T?Topx$dFiQKh3pY*
c3=9lUTUNd3Twll$%JyVOFNnpNT9Tv(01#|g4*&oF

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
new file mode 100644
index 0000000000000000000000000000000000000000..68a3b53a1df0574ad05b0e8bc53279e1110db9af
GIT binary patch
literal 366
zcmWIWW@Zs#00A||bhju0i}g&53=AO5%D})-p_f-sIoU7NHz1Oc!HuC>Jteg`xk%kg
zLA}P`LS08eJuSbeq$n{jKEEg>6(sJKm{Xjpqo7`#kywzbZl$1MqNAy!P^*9hxEh#}
z^Gb6ID)o}{i&FJ+OLIyx6N`!xE4ku}Qj_!Zic5-0lS{Y?86m2;@=_qOg-qTIt)Yxb
z?Lmdi8s3cFEUi!lDJ7K!sa%CDp-lc3-VEN1?LmdC8s5yIj5U6KeqR6o|NjpryzNVp
zI%5mjH2jj|<C97=b4oJv;^Vn0iW2kEQ@IM+BiI-i7@oGQdeOPQkRz1s$&OwSi!-$(
qNiV>gkx7IZcQAp14}=>UK_ocP0=!v4<}olbFftf3Ffgbxf}{Z9Ph;u;

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
new file mode 100644
index 0000000000000000000000000000000000000000..6776074b421bc04842c0389a7c237ad49cd0992a
GIT binary patch
literal 341
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1J<8Ps^qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
zFV09TNL9B|&@j=_)KREaKmuG1Ov!nrxdoMa$@xX8dby=JC7FpuMTwPM@kOc0`FX`9
zMWx9lT!jn}Ra|)~5ZOXTZ-&-FrsVkK{FKz>Vy@IY5QD3bIf9Xafg!1oC4!BCfgvZc
zBs0&jkhQIlEvS&ay^tfQkW<5((VL~UkPB*HN=aowDpw(Q1QP=TgTF-~k2ixiV|yWQ
zP$8d&H^j7>LViC#Kd=A)|NjRQ-u5Mh0!f{*g@PJ>$?@??rI|S;nR)T?Topx$dFiQK
zg+gG<pSG-e(Yd}*ID<KYhk=3N@RCD24)q>haj5gq`a+Qm*0w^?phB_Kl0xw$Jpi4U
BZkYf8

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
new file mode 100644
index 0000000000000000000000000000000000000000..05eac0b76d8a034ffa25a9af78d12a85d5d99d0f
GIT binary patch
literal 449
zcmWIWW@Zs#009NYbhnl7|EvjRWMBYcRt5%!3cb97%E^AAz5$Vp3~mh7>M5zk$wlf`
z3hFif7V0_*>S_5!B}IvO@%cq5sUUH;#GK+(9R>B`jKqRebt?r86CF(*g<1t9z}3K%
zoL8D#P^p)kUzDnsTbfgnnOIbmSjiP%l$xBMS6ot5nq0zF$N*8rm6rmMEoAg&Xf0$)
zj!(`{Nlh;1O3ec?xC)sg7#SECk_uTO*cccXauQ22^9&1F+X~r&3fbEWIf4o~HM|+U
zSy~IZpa!OtR2HOi6>>)~F)%RrTNLtmGk7z$7xD%b@@aTOOsgs6_w)1f`v3p`e=y-~
zUs5QL)EQeSsNt6!AD>j3nNyOP7az}6QIwdMp2}4y1h)KX%c>Wh>kEZ5m?L-?7#I#O
zIke+Y@8K1PIuETc6v<$1D-;bX6iY2B6i?C%@MdHZVa6Tupcnz+hDHzxj)wqmR*(-F
P7#SEDj6snD@;3tjQc{2A

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
new file mode 100644
index 0000000000000000000000000000000000000000..7c6997dd69eef019d6745dee125e92434b7954e3
GIT binary patch
literal 96
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
hFV09TNL9B|&@j@`)KREaKmuG0VDP~nOfh`02LKL&7mEM@

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
new file mode 100644
index 0000000000000000000000000000000000000000..d9bc36af7392dbee12a43c436e2178235ac60b13
GIT binary patch
literal 96
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
iFV09TNL9B|&@l4R(bQ3>RX_kP1~B+w52hGC*aH9)+!wb1

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
new file mode 100644
index 0000000000..f4bece352b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
@@ -0,0 +1,349 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from tempfile import mkdtemp, mkstemp, NamedTemporaryFile
+from shutil import rmtree
+
+from numpy.compat import asbytes
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, SkipTest
+    )
+import numpy.lib._datasource as datasource
+
+if sys.version_info[0] >= 3:
+    import urllib.request as urllib_request
+    from urllib.parse import urlparse
+    from urllib.error import URLError
+else:
+    import urllib2 as urllib_request
+    from urlparse import urlparse
+    from urllib2 import URLError
+
+
+def urlopen_stub(url, data=None):
+    '''Stub to replace urlopen for testing.'''
+    if url == valid_httpurl():
+        tmpfile = NamedTemporaryFile(prefix='urltmp_')
+        return tmpfile
+    else:
+        raise URLError('Name or service not known')
+
+# setup and teardown
+old_urlopen = None
+
+
+def setup():
+    global old_urlopen
+
+    old_urlopen = urllib_request.urlopen
+    urllib_request.urlopen = urlopen_stub
+
+
+def teardown():
+    urllib_request.urlopen = old_urlopen
+
+# A valid website for more robust testing
+http_path = 'http://www.google.com/'
+http_file = 'index.html'
+
+http_fakepath = 'http://fake.abc.web/site/'
+http_fakefile = 'fake.txt'
+
+malicious_files = ['/etc/shadow', '../../shadow',
+                   '..\\system.dat', 'c:\\windows\\system.dat']
+
+magic_line = asbytes('three is the magic number')
+
+
+# Utility functions used by many TestCases
+def valid_textfile(filedir):
+    # Generate and return a valid temporary file.
+    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir, text=True)
+    os.close(fd)
+    return path
+
+
+def invalid_textfile(filedir):
+    # Generate and return an invalid filename.
+    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir)
+    os.close(fd)
+    os.remove(path)
+    return path
+
+
+def valid_httpurl():
+    return http_path+http_file
+
+
+def invalid_httpurl():
+    return http_fakepath+http_fakefile
+
+
+def valid_baseurl():
+    return http_path
+
+
+def invalid_baseurl():
+    return http_fakepath
+
+
+def valid_httpfile():
+    return http_file
+
+
+def invalid_httpfile():
+    return http_fakefile
+
+
+class TestDataSourceOpen(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        fh = self.ds.open(valid_httpurl())
+        assert_(fh)
+        fh.close()
+
+    def test_InvalidHTTP(self):
+        url = invalid_httpurl()
+        self.assertRaises(IOError, self.ds.open, url)
+        try:
+            self.ds.open(url)
+        except IOError as e:
+            # Regression test for bug fixed in r4342.
+            assert_(e.errno is None)
+
+    def test_InvalidHTTPCacheURLError(self):
+        self.assertRaises(URLError, self.ds._cache, invalid_httpurl())
+
+    def test_ValidFile(self):
+        local_file = valid_textfile(self.tmpdir)
+        fh = self.ds.open(local_file)
+        assert_(fh)
+        fh.close()
+
+    def test_InvalidFile(self):
+        invalid_file = invalid_textfile(self.tmpdir)
+        self.assertRaises(IOError, self.ds.open, invalid_file)
+
+    def test_ValidGzipFile(self):
+        try:
+            import gzip
+        except ImportError:
+            # We don't have the gzip capabilities to test.
+            raise SkipTest
+        # Test datasource's internal file_opener for Gzip files.
+        filepath = os.path.join(self.tmpdir, 'foobar.txt.gz')
+        fp = gzip.open(filepath, 'w')
+        fp.write(magic_line)
+        fp.close()
+        fp = self.ds.open(filepath)
+        result = fp.readline()
+        fp.close()
+        self.assertEqual(magic_line, result)
+
+    def test_ValidBz2File(self):
+        try:
+            import bz2
+        except ImportError:
+            # We don't have the bz2 capabilities to test.
+            raise SkipTest
+        # Test datasource's internal file_opener for BZip2 files.
+        filepath = os.path.join(self.tmpdir, 'foobar.txt.bz2')
+        fp = bz2.BZ2File(filepath, 'w')
+        fp.write(magic_line)
+        fp.close()
+        fp = self.ds.open(filepath)
+        result = fp.readline()
+        fp.close()
+        self.assertEqual(magic_line, result)
+
+
+class TestDataSourceExists(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        assert_(self.ds.exists(valid_httpurl()))
+
+    def test_InvalidHTTP(self):
+        self.assertEqual(self.ds.exists(invalid_httpurl()), False)
+
+    def test_ValidFile(self):
+        # Test valid file in destpath
+        tmpfile = valid_textfile(self.tmpdir)
+        assert_(self.ds.exists(tmpfile))
+        # Test valid local file not in destpath
+        localdir = mkdtemp()
+        tmpfile = valid_textfile(localdir)
+        assert_(self.ds.exists(tmpfile))
+        rmtree(localdir)
+
+    def test_InvalidFile(self):
+        tmpfile = invalid_textfile(self.tmpdir)
+        self.assertEqual(self.ds.exists(tmpfile), False)
+
+
+class TestDataSourceAbspath(TestCase):
+    def setUp(self):
+        self.tmpdir = os.path.abspath(mkdtemp())
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(valid_httpurl())
+        local_path = os.path.join(self.tmpdir, netloc,
+                                  upath.strip(os.sep).strip('/'))
+        self.assertEqual(local_path, self.ds.abspath(valid_httpurl()))
+
+    def test_ValidFile(self):
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+        # Test with filename only
+        self.assertEqual(tmpfile, self.ds.abspath(tmpfilename))
+        # Test filename with complete path
+        self.assertEqual(tmpfile, self.ds.abspath(tmpfile))
+
+    def test_InvalidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(invalid_httpurl())
+        invalidhttp = os.path.join(self.tmpdir, netloc,
+                                   upath.strip(os.sep).strip('/'))
+        self.assertNotEqual(invalidhttp, self.ds.abspath(valid_httpurl()))
+
+    def test_InvalidFile(self):
+        invalidfile = valid_textfile(self.tmpdir)
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+        # Test with filename only
+        self.assertNotEqual(invalidfile, self.ds.abspath(tmpfilename))
+        # Test filename with complete path
+        self.assertNotEqual(invalidfile, self.ds.abspath(tmpfile))
+
+    def test_sandboxing(self):
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+
+        tmp_path = lambda x: os.path.abspath(self.ds.abspath(x))
+
+        assert_(tmp_path(valid_httpurl()).startswith(self.tmpdir))
+        assert_(tmp_path(invalid_httpurl()).startswith(self.tmpdir))
+        assert_(tmp_path(tmpfile).startswith(self.tmpdir))
+        assert_(tmp_path(tmpfilename).startswith(self.tmpdir))
+        for fn in malicious_files:
+            assert_(tmp_path(http_path+fn).startswith(self.tmpdir))
+            assert_(tmp_path(fn).startswith(self.tmpdir))
+
+    def test_windows_os_sep(self):
+        orig_os_sep = os.sep
+        try:
+            os.sep = '\\'
+            self.test_ValidHTTP()
+            self.test_ValidFile()
+            self.test_InvalidHTTP()
+            self.test_InvalidFile()
+            self.test_sandboxing()
+        finally:
+            os.sep = orig_os_sep
+
+
+class TestRepositoryAbspath(TestCase):
+    def setUp(self):
+        self.tmpdir = os.path.abspath(mkdtemp())
+        self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.repos
+
+    def test_ValidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(valid_httpurl())
+        local_path = os.path.join(self.repos._destpath, netloc,
+                                  upath.strip(os.sep).strip('/'))
+        filepath = self.repos.abspath(valid_httpfile())
+        self.assertEqual(local_path, filepath)
+
+    def test_sandboxing(self):
+        tmp_path = lambda x: os.path.abspath(self.repos.abspath(x))
+        assert_(tmp_path(valid_httpfile()).startswith(self.tmpdir))
+        for fn in malicious_files:
+            assert_(tmp_path(http_path+fn).startswith(self.tmpdir))
+            assert_(tmp_path(fn).startswith(self.tmpdir))
+
+    def test_windows_os_sep(self):
+        orig_os_sep = os.sep
+        try:
+            os.sep = '\\'
+            self.test_ValidHTTP()
+            self.test_sandboxing()
+        finally:
+            os.sep = orig_os_sep
+
+
+class TestRepositoryExists(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.repos
+
+    def test_ValidFile(self):
+        # Create local temp file
+        tmpfile = valid_textfile(self.tmpdir)
+        assert_(self.repos.exists(tmpfile))
+
+    def test_InvalidFile(self):
+        tmpfile = invalid_textfile(self.tmpdir)
+        self.assertEqual(self.repos.exists(tmpfile), False)
+
+    def test_RemoveHTTPFile(self):
+        assert_(self.repos.exists(valid_httpurl()))
+
+    def test_CachedHTTPFile(self):
+        localfile = valid_httpurl()
+        # Create a locally cached temp file with an URL based
+        # directory structure.  This is similar to what Repository.open
+        # would do.
+        scheme, netloc, upath, pms, qry, frg = urlparse(localfile)
+        local_path = os.path.join(self.repos._destpath, netloc)
+        os.mkdir(local_path, 0o0700)
+        tmpfile = valid_textfile(local_path)
+        assert_(self.repos.exists(tmpfile))
+
+
+class TestOpenFunc(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+
+    def test_DataSourceOpen(self):
+        local_file = valid_textfile(self.tmpdir)
+        # Test case where destpath is passed in
+        fp = datasource.open(local_file, destpath=self.tmpdir)
+        assert_(fp)
+        fp.close()
+        # Test case where default destpath is used
+        fp = datasource.open(local_file)
+        assert_(fp)
+        fp.close()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
new file mode 100644
index 0000000000..e0a917a216
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
@@ -0,0 +1,348 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import time
+from datetime import date
+
+import numpy as np
+from numpy.compat import asbytes, asbytes_nested
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_allclose,
+    assert_raises
+    )
+from numpy.lib._iotools import (
+    LineSplitter, NameValidator, StringConverter,
+    has_nested_fields, easy_dtype, flatten_dtype
+    )
+
+
+class TestLineSplitter(TestCase):
+    "Tests the LineSplitter class."
+
+    def test_no_delimiter(self):
+        "Test LineSplitter w/o delimiter"
+        strg = asbytes(" 1 2 3 4  5 # test")
+        test = LineSplitter()(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5']))
+        test = LineSplitter('')(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5']))
+
+    def test_space_delimiter(self):
+        "Test space delimiter"
+        strg = asbytes(" 1 2 3 4  5 # test")
+        test = LineSplitter(asbytes(' '))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+        test = LineSplitter(asbytes('  '))(strg)
+        assert_equal(test, asbytes_nested(['1 2 3 4', '5']))
+
+    def test_tab_delimiter(self):
+        "Test tab delimiter"
+        strg = asbytes(" 1\t 2\t 3\t 4\t 5  6")
+        test = LineSplitter(asbytes('\t'))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5  6']))
+        strg = asbytes(" 1  2\t 3  4\t 5  6")
+        test = LineSplitter(asbytes('\t'))(strg)
+        assert_equal(test, asbytes_nested(['1  2', '3  4', '5  6']))
+
+    def test_other_delimiter(self):
+        "Test LineSplitter on delimiter"
+        strg = asbytes("1,2,3,4,,5")
+        test = LineSplitter(asbytes(','))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+        #
+        strg = asbytes(" 1,2,3,4,,5 # test")
+        test = LineSplitter(asbytes(','))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+
+    def test_constant_fixed_width(self):
+        "Test LineSplitter w/ fixed-width fields"
+        strg = asbytes("  1  2  3  4     5   # test")
+        test = LineSplitter(3)(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5', '']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter(20)(strg)
+        assert_equal(test, asbytes_nested(['1     3  4  5  6']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter(30)(strg)
+        assert_equal(test, asbytes_nested(['1     3  4  5  6']))
+
+    def test_variable_fixed_width(self):
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter((3, 6, 6, 3))(strg)
+        assert_equal(test, asbytes_nested(['1', '3', '4  5', '6']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter((6, 6, 9))(strg)
+        assert_equal(test, asbytes_nested(['1', '3  4', '5  6']))
+
+# -----------------------------------------------------------------------------
+
+
+class TestNameValidator(TestCase):
+
+    def test_case_sensitivity(self):
+        "Test case sensitivity"
+        names = ['A', 'a', 'b', 'c']
+        test = NameValidator().validate(names)
+        assert_equal(test, ['A', 'a', 'b', 'c'])
+        test = NameValidator(case_sensitive=False).validate(names)
+        assert_equal(test, ['A', 'A_1', 'B', 'C'])
+        test = NameValidator(case_sensitive='upper').validate(names)
+        assert_equal(test, ['A', 'A_1', 'B', 'C'])
+        test = NameValidator(case_sensitive='lower').validate(names)
+        assert_equal(test, ['a', 'a_1', 'b', 'c'])
+
+        # check exceptions
+        assert_raises(ValueError, NameValidator, case_sensitive='foobar')
+
+    def test_excludelist(self):
+        "Test excludelist"
+        names = ['dates', 'data', 'Other Data', 'mask']
+        validator = NameValidator(excludelist=['dates', 'data', 'mask'])
+        test = validator.validate(names)
+        assert_equal(test, ['dates_', 'data_', 'Other_Data', 'mask_'])
+
+    def test_missing_names(self):
+        "Test validate missing names"
+        namelist = ('a', 'b', 'c')
+        validator = NameValidator()
+        assert_equal(validator(namelist), ['a', 'b', 'c'])
+        namelist = ('', 'b', 'c')
+        assert_equal(validator(namelist), ['f0', 'b', 'c'])
+        namelist = ('a', 'b', '')
+        assert_equal(validator(namelist), ['a', 'b', 'f0'])
+        namelist = ('', 'f0', '')
+        assert_equal(validator(namelist), ['f1', 'f0', 'f2'])
+
+    def test_validate_nb_names(self):
+        "Test validate nb names"
+        namelist = ('a', 'b', 'c')
+        validator = NameValidator()
+        assert_equal(validator(namelist, nbfields=1), ('a',))
+        assert_equal(validator(namelist, nbfields=5, defaultfmt="g%i"),
+                     ['a', 'b', 'c', 'g0', 'g1'])
+
+    def test_validate_wo_names(self):
+        "Test validate no names"
+        namelist = None
+        validator = NameValidator()
+        assert_(validator(namelist) is None)
+        assert_equal(validator(namelist, nbfields=3), ['f0', 'f1', 'f2'])
+
+# -----------------------------------------------------------------------------
+
+
+def _bytes_to_date(s):
+    if sys.version_info[0] >= 3:
+        return date(*time.strptime(s.decode('latin1'), "%Y-%m-%d")[:3])
+    else:
+        return date(*time.strptime(s, "%Y-%m-%d")[:3])
+
+
+class TestStringConverter(TestCase):
+    "Test StringConverter"
+
+    def test_creation(self):
+        "Test creation of a StringConverter"
+        converter = StringConverter(int, -99999)
+        assert_equal(converter._status, 1)
+        assert_equal(converter.default, -99999)
+
+    def test_upgrade(self):
+        "Tests the upgrade method."
+
+        converter = StringConverter()
+        assert_equal(converter._status, 0)
+
+        # test int
+        assert_equal(converter.upgrade(asbytes('0')), 0)
+        assert_equal(converter._status, 1)
+
+        # On systems where integer defaults to 32-bit, the statuses will be
+        # offset by one, so we check for this here.
+        import numpy.core.numeric as nx
+        status_offset = int(nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize)
+
+        # test int > 2**32
+        assert_equal(converter.upgrade(asbytes('17179869184')), 17179869184)
+        assert_equal(converter._status, 1 + status_offset)
+
+        # test float
+        assert_allclose(converter.upgrade(asbytes('0.')), 0.0)
+        assert_equal(converter._status, 2 + status_offset)
+
+        # test complex
+        assert_equal(converter.upgrade(asbytes('0j')), complex('0j'))
+        assert_equal(converter._status, 3 + status_offset)
+
+        # test str
+        assert_equal(converter.upgrade(asbytes('a')), asbytes('a'))
+        assert_equal(converter._status, len(converter._mapper) - 1)
+
+    def test_missing(self):
+        "Tests the use of missing values."
+        converter = StringConverter(missing_values=(asbytes('missing'),
+                                                    asbytes('missed')))
+        converter.upgrade(asbytes('0'))
+        assert_equal(converter(asbytes('0')), 0)
+        assert_equal(converter(asbytes('')), converter.default)
+        assert_equal(converter(asbytes('missing')), converter.default)
+        assert_equal(converter(asbytes('missed')), converter.default)
+        try:
+            converter('miss')
+        except ValueError:
+            pass
+
+    def test_upgrademapper(self):
+        "Tests updatemapper"
+        dateparser = _bytes_to_date
+        StringConverter.upgrade_mapper(dateparser, date(2000, 1, 1))
+        convert = StringConverter(dateparser, date(2000, 1, 1))
+        test = convert(asbytes('2001-01-01'))
+        assert_equal(test, date(2001, 1, 1))
+        test = convert(asbytes('2009-01-01'))
+        assert_equal(test, date(2009, 1, 1))
+        test = convert(asbytes(''))
+        assert_equal(test, date(2000, 1, 1))
+
+    def test_string_to_object(self):
+        "Make sure that string-to-object functions are properly recognized"
+        conv = StringConverter(_bytes_to_date)
+        assert_equal(conv._mapper[-2][0](0), 0j)
+        assert_(hasattr(conv, 'default'))
+
+    def test_keep_default(self):
+        "Make sure we don't lose an explicit default"
+        converter = StringConverter(None, missing_values=asbytes(''),
+                                    default=-999)
+        converter.upgrade(asbytes('3.14159265'))
+        assert_equal(converter.default, -999)
+        assert_equal(converter.type, np.dtype(float))
+        #
+        converter = StringConverter(
+            None, missing_values=asbytes(''), default=0)
+        converter.upgrade(asbytes('3.14159265'))
+        assert_equal(converter.default, 0)
+        assert_equal(converter.type, np.dtype(float))
+
+    def test_keep_default_zero(self):
+        "Check that we don't lose a default of 0"
+        converter = StringConverter(int, default=0,
+                                    missing_values=asbytes("N/A"))
+        assert_equal(converter.default, 0)
+
+    def test_keep_missing_values(self):
+        "Check that we're not losing missing values"
+        converter = StringConverter(int, default=0,
+                                    missing_values=asbytes("N/A"))
+        assert_equal(
+            converter.missing_values, set(asbytes_nested(['', 'N/A'])))
+
+    def test_int64_dtype(self):
+        "Check that int64 integer types can be specified"
+        converter = StringConverter(np.int64, default=0)
+        val = asbytes("-9223372036854775807")
+        assert_(converter(val) == -9223372036854775807)
+        val = asbytes("9223372036854775807")
+        assert_(converter(val) == 9223372036854775807)
+
+    def test_uint64_dtype(self):
+        "Check that uint64 integer types can be specified"
+        converter = StringConverter(np.uint64, default=0)
+        val = asbytes("9223372043271415339")
+        assert_(converter(val) == 9223372043271415339)
+
+
+class TestMiscFunctions(TestCase):
+
+    def test_has_nested_dtype(self):
+        "Test has_nested_dtype"
+        ndtype = np.dtype(np.float)
+        assert_equal(has_nested_fields(ndtype), False)
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        assert_equal(has_nested_fields(ndtype), False)
+        ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+        assert_equal(has_nested_fields(ndtype), True)
+
+    def test_easy_dtype(self):
+        "Test ndtype on dtypes"
+        # Simple case
+        ndtype = float
+        assert_equal(easy_dtype(ndtype), np.dtype(float))
+        # As string w/o names
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype),
+                     np.dtype([('f0', "i4"), ('f1', "f8")]))
+        # As string w/o names but different default format
+        assert_equal(easy_dtype(ndtype, defaultfmt="field_%03i"),
+                     np.dtype([('field_000', "i4"), ('field_001', "f8")]))
+        # As string w/ names
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names="a, b"),
+                     np.dtype([('a', "i4"), ('b', "f8")]))
+        # As string w/ names (too many)
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([('a', "i4"), ('b', "f8")]))
+        # As string w/ names (not enough)
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names=", b"),
+                     np.dtype([('f0', "i4"), ('b', "f8")]))
+        # ... (with different default format)
+        assert_equal(easy_dtype(ndtype, names="a", defaultfmt="f%02i"),
+                     np.dtype([('a', "i4"), ('f00', "f8")]))
+        # As list of tuples w/o names
+        ndtype = [('A', int), ('B', float)]
+        assert_equal(easy_dtype(ndtype), np.dtype([('A', int), ('B', float)]))
+        # As list of tuples w/ names
+        assert_equal(easy_dtype(ndtype, names="a,b"),
+                     np.dtype([('a', int), ('b', float)]))
+        # As list of tuples w/ not enough names
+        assert_equal(easy_dtype(ndtype, names="a"),
+                     np.dtype([('a', int), ('f0', float)]))
+        # As list of tuples w/ too many names
+        assert_equal(easy_dtype(ndtype, names="a,b,c"),
+                     np.dtype([('a', int), ('b', float)]))
+        # As list of types w/o names
+        ndtype = (int, float, float)
+        assert_equal(easy_dtype(ndtype),
+                     np.dtype([('f0', int), ('f1', float), ('f2', float)]))
+        # As list of types w names
+        ndtype = (int, float, float)
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([('a', int), ('b', float), ('c', float)]))
+        # As simple dtype w/ names
+        ndtype = np.dtype(float)
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([(_, float) for _ in ('a', 'b', 'c')]))
+        # As simple dtype w/o names (but multiple fields)
+        ndtype = np.dtype(float)
+        assert_equal(
+            easy_dtype(ndtype, names=['', '', ''], defaultfmt="f%02i"),
+            np.dtype([(_, float) for _ in ('f00', 'f01', 'f02')]))
+
+    def test_flatten_dtype(self):
+        "Testing flatten_dtype"
+        # Standard dtype
+        dt = np.dtype([("a", "f8"), ("b", "f8")])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, float])
+        # Recursive dtype
+        dt = np.dtype([("a", [("aa", '|S1'), ("ab", '|S2')]), ("b", int)])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [np.dtype('|S1'), np.dtype('|S2'), int])
+        # dtype with shaped fields
+        dt = np.dtype([("a", (float, 2)), ("b", (int, 3))])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, int])
+        dt_flat = flatten_dtype(dt, True)
+        assert_equal(dt_flat, [float] * 2 + [int] * 3)
+        # dtype w/ titles
+        dt = np.dtype([(("a", "A"), "f8"), (("b", "B"), "f8")])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, float])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__version.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
new file mode 100644
index 0000000000..993c9d5070
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
@@ -0,0 +1,70 @@
+"""Tests for the NumpyVersion class.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import assert_, run_module_suite, assert_raises
+from numpy.lib import NumpyVersion
+
+
+def test_main_versions():
+    assert_(NumpyVersion('1.8.0') == '1.8.0')
+    for ver in ['1.9.0', '2.0.0', '1.8.1']:
+        assert_(NumpyVersion('1.8.0') < ver)
+
+    for ver in ['1.7.0', '1.7.1', '0.9.9']:
+        assert_(NumpyVersion('1.8.0') > ver)
+
+
+def test_version_1_point_10():
+    # regression test for gh-2998.
+    assert_(NumpyVersion('1.9.0') < '1.10.0')
+    assert_(NumpyVersion('1.11.0') < '1.11.1')
+    assert_(NumpyVersion('1.11.0') == '1.11.0')
+    assert_(NumpyVersion('1.99.11') < '1.99.12')
+
+
+def test_alpha_beta_rc():
+    assert_(NumpyVersion('1.8.0rc1') == '1.8.0rc1')
+    for ver in ['1.8.0', '1.8.0rc2']:
+        assert_(NumpyVersion('1.8.0rc1') < ver)
+
+    for ver in ['1.8.0a2', '1.8.0b3', '1.7.2rc4']:
+        assert_(NumpyVersion('1.8.0rc1') > ver)
+
+    assert_(NumpyVersion('1.8.0b1') > '1.8.0a2')
+
+
+def test_dev_version():
+    assert_(NumpyVersion('1.9.0.dev-Unknown') < '1.9.0')
+    for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev-ffffffff']:
+        assert_(NumpyVersion('1.9.0.dev-f16acvda') < ver)
+
+    assert_(NumpyVersion('1.9.0.dev-f16acvda') == '1.9.0.dev-11111111')
+
+
+def test_dev_a_b_rc_mixed():
+    assert_(NumpyVersion('1.9.0a2.dev-f16acvda') == '1.9.0a2.dev-11111111')
+    assert_(NumpyVersion('1.9.0a2.dev-6acvda54') < '1.9.0a2')
+
+
+def test_dev0_version():
+    assert_(NumpyVersion('1.9.0.dev0+Unknown') < '1.9.0')
+    for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev0+ffffffff']:
+        assert_(NumpyVersion('1.9.0.dev0+f16acvda') < ver)
+
+    assert_(NumpyVersion('1.9.0.dev0+f16acvda') == '1.9.0.dev0+11111111')
+
+
+def test_dev0_a_b_rc_mixed():
+    assert_(NumpyVersion('1.9.0a2.dev0+f16acvda') == '1.9.0a2.dev0+11111111')
+    assert_(NumpyVersion('1.9.0a2.dev0+6acvda54') < '1.9.0a2')
+
+
+def test_raises():
+    for ver in ['1.9', '1,9.0', '1.7.x']:
+        assert_raises(ValueError, NumpyVersion, ver)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
new file mode 100644
index 0000000000..f19a0b13ab
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
@@ -0,0 +1,1058 @@
+"""Tests for the array padding functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (assert_array_equal, assert_raises, assert_allclose,
+                           TestCase)
+from numpy.lib import pad
+
+
+class TestConditionalShortcuts(TestCase):
+    def test_zero_padding_shortcuts(self):
+        test = np.arange(120).reshape(4, 5, 6)
+        pad_amt = [(0, 0) for axis in test.shape]
+        modes = ['constant',
+                 'edge',
+                 'linear_ramp',
+                 'maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 'reflect',
+                 'symmetric',
+                 'wrap',
+                 ]
+        for mode in modes:
+            assert_array_equal(test, pad(test, pad_amt, mode=mode))
+
+    def test_shallow_statistic_range(self):
+        test = np.arange(120).reshape(4, 5, 6)
+        pad_amt = [(1, 1) for axis in test.shape]
+        modes = ['maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 ]
+        for mode in modes:
+            assert_array_equal(pad(test, pad_amt, mode='edge'),
+                               pad(test, pad_amt, mode=mode, stat_length=1))
+
+    def test_clip_statistic_range(self):
+        test = np.arange(30).reshape(5, 6)
+        pad_amt = [(3, 3) for axis in test.shape]
+        modes = ['maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 ]
+        for mode in modes:
+            assert_array_equal(pad(test, pad_amt, mode=mode),
+                               pad(test, pad_amt, mode=mode, stat_length=30))
+
+
+class TestStatistic(TestCase):
+    def test_check_mean_stat_length(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), ))
+        b = np.array(
+            [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+             0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+             0.5, 0.5, 0.5, 0.5, 0.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             98., 98., 98., 98., 98., 98., 98., 98., 98., 98.,
+             98., 98., 98., 98., 98., 98., 98., 98., 98., 98.
+             ])
+        assert_array_equal(a, b)
+
+    def test_check_maximum_1(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'maximum')
+        b = np.array(
+            [99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_maximum_2(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'maximum')
+        b = np.array(
+            [100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100,
+
+             1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_maximum_stat_length(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'maximum', stat_length=10)
+        b = np.array(
+            [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10,
+
+              1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_1(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'minimum')
+        b = np.array(
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_2(self):
+        a = np.arange(100) + 2
+        a = pad(a, (25, 20), 'minimum')
+        b = np.array(
+            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2,
+
+             2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+             12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+             22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+             32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+             42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+             52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+             62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+             72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+             82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+             92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_stat_length(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'minimum', stat_length=10)
+        b = np.array(
+            [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+              1,  1,  1,  1,  1,
+
+              1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+             91, 91, 91, 91, 91, 91, 91, 91, 91, 91]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'median')
+        b = np.array(
+            [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_01(self):
+        a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
+        a = pad(a, 1, 'median')
+        b = np.array(
+            [[4, 4, 5, 4, 4],
+
+             [3, 3, 1, 4, 3],
+             [5, 4, 5, 9, 5],
+             [8, 9, 8, 2, 8],
+
+             [4, 4, 5, 4, 4]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_02(self):
+        a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
+        a = pad(a.T, 1, 'median').T
+        b = np.array(
+            [[5, 4, 5, 4, 5],
+
+             [3, 3, 1, 4, 3],
+             [5, 4, 5, 9, 5],
+             [8, 9, 8, 2, 8],
+
+             [5, 4, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_stat_length(self):
+        a = np.arange(100).astype('f')
+        a[1] = 2.
+        a[97] = 96.
+        a = pad(a, (25, 20), 'median', stat_length=(3, 5))
+        b = np.array(
+            [ 2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,
+              2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,
+              2.,  2.,  2.,  2.,  2.,
+
+              0.,  2.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 96., 98., 99.,
+
+             96., 96., 96., 96., 96., 96., 96., 96., 96., 96.,
+             96., 96., 96., 96., 96., 96., 96., 96., 96., 96.]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_mean_shape_one(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'mean', stat_length=2)
+        b = np.array(
+            [[4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_mean_2(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'mean')
+        b = np.array(
+            [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
+            )
+        assert_array_equal(a, b)
+
+
+class TestConstant(TestCase):
+    def test_check_constant(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'constant', constant_values=(10, 20))
+        b = np.array(
+            [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+             20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_constant_zeros(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'constant')
+        b = np.array(
+            [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_constant_float(self):
+        # If input array is int, but constant_values are float, the dtype of
+        # the array to be padded is kept
+        arr = np.arange(30).reshape(5, 6)
+        test = pad(arr, (1, 2), mode='constant',
+                   constant_values=1.1)
+        expected = np.array(
+            [[ 1,  1,  1,  1,  1,  1,  1,  1,  1],
+
+             [ 1,  0,  1,  2,  3,  4,  5,  1,  1],
+             [ 1,  6,  7,  8,  9, 10, 11,  1,  1],
+             [ 1, 12, 13, 14, 15, 16, 17,  1,  1],
+             [ 1, 18, 19, 20, 21, 22, 23,  1,  1],
+             [ 1, 24, 25, 26, 27, 28, 29,  1,  1],
+
+             [ 1,  1,  1,  1,  1,  1,  1,  1,  1],
+             [ 1,  1,  1,  1,  1,  1,  1,  1,  1]]
+            )
+        assert_allclose(test, expected)
+
+    def test_check_constant_float2(self):
+        # If input array is float, and constant_values are float, the dtype of
+        # the array to be padded is kept - here retaining the float constants
+        arr = np.arange(30).reshape(5, 6)
+        arr_float = arr.astype(np.float64)
+        test = pad(arr_float, ((1, 2), (1, 2)), mode='constant',
+                   constant_values=1.1)
+        expected = np.array(
+            [[  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1],
+
+             [  1.1,   0. ,   1. ,   2. ,   3. ,   4. ,   5. ,   1.1,   1.1],
+             [  1.1,   6. ,   7. ,   8. ,   9. ,  10. ,  11. ,   1.1,   1.1],
+             [  1.1,  12. ,  13. ,  14. ,  15. ,  16. ,  17. ,   1.1,   1.1],
+             [  1.1,  18. ,  19. ,  20. ,  21. ,  22. ,  23. ,   1.1,   1.1],
+             [  1.1,  24. ,  25. ,  26. ,  27. ,  28. ,  29. ,   1.1,   1.1],
+
+             [  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1],
+             [  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1]]
+            )
+        assert_allclose(test, expected)
+
+    def test_check_constant_float3(self):
+        a = np.arange(100, dtype=float)
+        a = pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2))
+        b = np.array(
+            [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
+             -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
+             -1.1, -1.1, -1.1, -1.1, -1.1,
+
+             0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2,
+             -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2]
+            )
+        assert_allclose(a, b)
+
+    def test_check_constant_odd_pad_amount(self):
+        arr = np.arange(30).reshape(5, 6)
+        test = pad(arr, ((1,), (2,)), mode='constant',
+                   constant_values=3)
+        expected = np.array(
+            [[ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
+
+             [ 3,  3,  0,  1,  2,  3,  4,  5,  3,  3],
+             [ 3,  3,  6,  7,  8,  9, 10, 11,  3,  3],
+             [ 3,  3, 12, 13, 14, 15, 16, 17,  3,  3],
+             [ 3,  3, 18, 19, 20, 21, 22, 23,  3,  3],
+             [ 3,  3, 24, 25, 26, 27, 28, 29,  3,  3],
+
+             [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3]]
+            )
+        assert_allclose(test, expected)
+
+
+class TestLinearRamp(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'linear_ramp', end_values=(4, 5))
+        b = np.array(
+            [4.00, 3.84, 3.68, 3.52, 3.36, 3.20, 3.04, 2.88, 2.72, 2.56,
+             2.40, 2.24, 2.08, 1.92, 1.76, 1.60, 1.44, 1.28, 1.12, 0.96,
+             0.80, 0.64, 0.48, 0.32, 0.16,
+
+             0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00,
+             10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
+             20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
+             30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
+             40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0,
+             50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0,
+             60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0,
+             70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
+             80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0,
+             90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0,
+
+             94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0,
+             47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.]
+            )
+        assert_allclose(a, b, rtol=1e-5, atol=1e-5)
+
+    def test_check_2d(self):
+        arr = np.arange(20).reshape(4, 5).astype(np.float64)
+        test = pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0))
+        expected = np.array(
+            [[0.,   0.,   0.,   0.,   0.,   0.,   0.,    0.,   0.],
+             [0.,   0.,   0.,  0.5,   1.,  1.5,   2.,    1.,   0.],
+             [0.,   0.,   0.,   1.,   2.,   3.,   4.,    2.,   0.],
+             [0.,  2.5,   5.,   6.,   7.,   8.,   9.,   4.5,   0.],
+             [0.,   5.,  10.,  11.,  12.,  13.,  14.,    7.,   0.],
+             [0.,  7.5,  15.,  16.,  17.,  18.,  19.,   9.5,   0.],
+             [0., 3.75,  7.5,   8.,  8.5,   9.,  9.5,  4.75,   0.],
+             [0.,   0.,   0.,   0.,   0.,   0.,   0.,    0.,   0.]])
+        assert_allclose(test, expected)
+
+
+class TestReflect(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'reflect')
+        b = np.array(
+            [25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
+             15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+             5, 4, 3, 2, 1,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             98, 97, 96, 95, 94, 93, 92, 91, 90, 89,
+             88, 87, 86, 85, 84, 83, 82, 81, 80, 79]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_odd_method(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'reflect', reflect_type='odd')
+        b = np.array(
+            [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16,
+             -15, -14, -13, -12, -11, -10, -9, -8, -7, -6,
+             -5, -4, -3, -2, -1,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+             110, 111, 112, 113, 114, 115, 116, 117, 118, 119]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'reflect')
+        b = np.array(
+            [[7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_shape(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'reflect')
+        b = np.array(
+            [[5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 2, 'reflect')
+        b = np.array([3, 2, 1, 2, 3, 2, 1])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 3, 'reflect')
+        b = np.array([2, 3, 2, 1, 2, 3, 2, 1, 2])
+        assert_array_equal(a, b)
+
+    def test_check_03(self):
+        a = pad([1, 2, 3], 4, 'reflect')
+        b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
+        assert_array_equal(a, b)
+
+
+class TestSymmetric(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'symmetric')
+        b = np.array(
+            [24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
+             14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
+             4, 3, 2, 1, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 98, 97, 96, 95, 94, 93, 92, 91, 90,
+             89, 88, 87, 86, 85, 84, 83, 82, 81, 80]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_odd_method(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'symmetric', reflect_type='odd')
+        b = np.array(
+            [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15,
+             -14, -13, -12, -11, -10, -9, -8, -7, -6, -5,
+             -4, -3, -2, -1, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+             109, 110, 111, 112, 113, 114, 115, 116, 117, 118]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'symmetric')
+        b = np.array(
+            [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
+            )
+
+        assert_array_equal(a, b)
+
+    def test_check_large_pad_odd(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'symmetric', reflect_type='odd')
+        b = np.array(
+            [[-3, -2, -2, -1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6],
+             [-3, -2, -2, -1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6],
+             [-1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8],
+             [-1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8],
+             [ 1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10],
+
+             [ 1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10],
+             [ 3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12],
+
+             [ 3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12],
+             [ 5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14],
+             [ 5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14],
+             [ 7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
+             [ 7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
+             [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18],
+             [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_shape(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'symmetric')
+        b = np.array(
+            [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 2, 'symmetric')
+        b = np.array([2, 1, 1, 2, 3, 3, 2])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 3, 'symmetric')
+        b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1])
+        assert_array_equal(a, b)
+
+    def test_check_03(self):
+        a = pad([1, 2, 3], 6, 'symmetric')
+        b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3])
+        assert_array_equal(a, b)
+
+
+class TestWrap(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'wrap')
+        b = np.array(
+            [75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+             85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+             95, 96, 97, 98, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = np.arange(12)
+        a = np.reshape(a, (3, 4))
+        a = pad(a, (10, 12), 'wrap')
+        b = np.array(
+            [[10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 3, 'wrap')
+        b = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 4, 'wrap')
+        b = np.array([3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1])
+        assert_array_equal(a, b)
+
+
+class TestStatLen(TestCase):
+    def test_check_simple(self):
+        a = np.arange(30)
+        a = np.reshape(a, (6, 5))
+        a = pad(a, ((2, 3), (3, 2)), mode='mean', stat_length=(3,))
+        b = np.array(
+            [[6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+             [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+
+             [1, 1, 1, 0, 1, 2, 3, 4, 3, 3],
+             [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+             [11, 11, 11, 10, 11, 12, 13, 14, 13, 13],
+             [16, 16, 16, 15, 16, 17, 18, 19, 18, 18],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [26, 26, 26, 25, 26, 27, 28, 29, 28, 28],
+
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestEdge(TestCase):
+    def test_check_simple(self):
+        a = np.arange(12)
+        a = np.reshape(a, (4, 3))
+        a = pad(a, ((2, 3), (3, 2)), 'edge')
+        b = np.array(
+            [[0, 0, 0, 0, 1, 2, 2, 2],
+             [0, 0, 0, 0, 1, 2, 2, 2],
+
+             [0, 0, 0, 0, 1, 2, 2, 2],
+             [3, 3, 3, 3, 4, 5, 5, 5],
+             [6, 6, 6, 6, 7, 8, 8, 8],
+             [9, 9, 9, 9, 10, 11, 11, 11],
+
+             [9, 9, 9, 9, 10, 11, 11, 11],
+             [9, 9, 9, 9, 10, 11, 11, 11],
+             [9, 9, 9, 9, 10, 11, 11, 11]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestZeroPadWidth(TestCase):
+    def test_zero_pad_width(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        for pad_width in (0, (0, 0), ((0, 0), (0, 0))):
+            assert_array_equal(arr, pad(arr, pad_width, mode='constant'))
+
+
+class TestLegacyVectorFunction(TestCase):
+    def test_legacy_vector_functionality(self):
+        def _padwithtens(vector, pad_width, iaxis, kwargs):
+            vector[:pad_width[0]] = 10
+            vector[-pad_width[1]:] = 10
+            return vector
+
+        a = np.arange(6).reshape(2, 3)
+        a = pad(a, 2, _padwithtens)
+        b = np.array(
+            [[10, 10, 10, 10, 10, 10, 10],
+             [10, 10, 10, 10, 10, 10, 10],
+
+             [10, 10,  0,  1,  2, 10, 10],
+             [10, 10,  3,  4,  5, 10, 10],
+
+             [10, 10, 10, 10, 10, 10, 10],
+             [10, 10, 10, 10, 10, 10, 10]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestNdarrayPadWidth(TestCase):
+    def test_check_simple(self):
+        a = np.arange(12)
+        a = np.reshape(a, (4, 3))
+        a = pad(a, np.array(((2, 3), (3, 2))), 'edge')
+        b = np.array(
+            [[0,  0,  0,    0,  1,  2,    2,  2],
+             [0,  0,  0,    0,  1,  2,    2,  2],
+
+             [0,  0,  0,    0,  1,  2,    2,  2],
+             [3,  3,  3,    3,  4,  5,    5,  5],
+             [6,  6,  6,    6,  7,  8,    8,  8],
+             [9,  9,  9,    9, 10, 11,   11, 11],
+
+             [9,  9,  9,    9, 10, 11,   11, 11],
+             [9,  9,  9,    9, 10, 11,   11, 11],
+             [9,  9,  9,    9, 10, 11,   11, 11]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestUnicodeInput(TestCase):
+    def test_unicode_mode(self):
+        try:
+            constant_mode = unicode('constant')
+        except NameError:
+            constant_mode = 'constant'
+        a = np.pad([1], 2, mode=constant_mode)
+        b = np.array([0, 0, 1, 0, 0])
+        assert_array_equal(a, b)
+
+
+class ValueError1(TestCase):
+    def test_check_simple(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((2, 3), (3, 2), (4, 5)),
+                      **kwargs)
+
+    def test_check_negative_stat_length(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(-3, ))
+        assert_raises(ValueError, pad, arr, ((2, 3), (3, 2)),
+                      **kwargs)
+
+    def test_check_negative_pad_width(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)),
+                      **kwargs)
+
+
+class ValueError2(TestCase):
+    def test_check_negative_pad_amount(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)),
+                      **kwargs)
+
+
+class ValueError3(TestCase):
+    def test_check_kwarg_not_allowed(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, 4, mode='mean',
+                      reflect_type='odd')
+
+    def test_mode_not_set(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(TypeError, pad, arr, 4)
+
+    def test_malformed_pad_amount(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, (4, 5, 6, 7), mode='constant')
+
+    def test_malformed_pad_amount2(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, ((3, 4, 5), (0, 1, 2)),
+                      mode='constant')
+
+    def test_pad_too_many_axes(self):
+        arr = np.arange(30).reshape(5, 6)
+
+        # Attempt to pad using a 3D array equivalent
+        bad_shape = (((3,), (4,), (5,)), ((0,), (1,), (2,)))
+        assert_raises(ValueError, pad, arr, bad_shape,
+                      mode='constant')
+
+
+class TypeError1(TestCase):
+    def test_float(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, ((-2.1, 3), (3, 2)))
+        assert_raises(TypeError, pad, arr, np.array(((-2.1, 3), (3, 2))))
+
+    def test_str(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, 'foo')
+        assert_raises(TypeError, pad, arr, np.array('foo'))
+
+    def test_object(self):
+        class FooBar(object):
+            pass
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, FooBar())
+
+    def test_complex(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, complex(1, -1))
+        assert_raises(TypeError, pad, arr, np.array(complex(1, -1)))
+
+    def test_check_wrong_pad_amount(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(TypeError, pad, arr, ((2, 3, 4), (3, 2)),
+                      **kwargs)
+
+
+if __name__ == "__main__":
+    np.testing.run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
new file mode 100644
index 0000000000..852183ffec
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
@@ -0,0 +1,309 @@
+"""Test functions for 1D array set operations.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_array_equal, assert_equal
+    )
+from numpy.lib.arraysetops import (
+    ediff1d, intersect1d, setxor1d, union1d, setdiff1d, unique, in1d
+    )
+
+
+class TestSetOps(TestCase):
+
+    def test_unique(self):
+
+        def check_all(a, b, i1, i2, c, dt):
+            base_msg = 'check {0} failed for type {1}'
+
+            msg = base_msg.format('values', dt)
+            v = unique(a)
+            assert_array_equal(v, b, msg)
+
+            msg = base_msg.format('return_index', dt)
+            v, j = unique(a, 1, 0, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, i1, msg)
+
+            msg = base_msg.format('return_inverse', dt)
+            v, j = unique(a, 0, 1, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, i2, msg)
+
+            msg = base_msg.format('return_counts', dt)
+            v, j = unique(a, 0, 0, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, c, msg)
+
+            msg = base_msg.format('return_index and return_inverse', dt)
+            v, j1, j2 = unique(a, 1, 1, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, i2, msg)
+
+            msg = base_msg.format('return_index and return_counts', dt)
+            v, j1, j2 = unique(a, 1, 0, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, c, msg)
+
+            msg = base_msg.format('return_inverse and return_counts', dt)
+            v, j1, j2 = unique(a, 0, 1, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i2, msg)
+            assert_array_equal(j2, c, msg)
+
+            msg = base_msg.format(('return_index, return_inverse '
+                                   'and return_counts'), dt)
+            v, j1, j2, j3 = unique(a, 1, 1, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, i2, msg)
+            assert_array_equal(j3, c, msg)
+
+        a = [5, 7, 1, 2, 1, 5, 7]*10
+        b = [1, 2, 5, 7]
+        i1 = [2, 3, 0, 1]
+        i2 = [2, 3, 0, 1, 0, 2, 3]*10
+        c = np.multiply([2, 1, 2, 2], 10)
+
+        # test for numeric arrays
+        types = []
+        types.extend(np.typecodes['AllInteger'])
+        types.extend(np.typecodes['AllFloat'])
+        types.append('datetime64[D]')
+        types.append('timedelta64[D]')
+        for dt in types:
+            aa = np.array(a, dt)
+            bb = np.array(b, dt)
+            check_all(aa, bb, i1, i2, c, dt)
+
+        # test for object arrays
+        dt = 'O'
+        aa = np.empty(len(a), dt)
+        aa[:] = a
+        bb = np.empty(len(b), dt)
+        bb[:] = b
+        check_all(aa, bb, i1, i2, c, dt)
+
+        # test for structured arrays
+        dt = [('', 'i'), ('', 'i')]
+        aa = np.array(list(zip(a, a)), dt)
+        bb = np.array(list(zip(b, b)), dt)
+        check_all(aa, bb, i1, i2, c, dt)
+
+        # test for ticket #2799
+        aa = [1. + 0.j, 1 - 1.j, 1]
+        assert_array_equal(np.unique(aa), [1. - 1.j, 1. + 0.j])
+
+        # test for ticket #4785
+        a = [(1, 2), (1, 2), (2, 3)]
+        unq = [1, 2, 3]
+        inv = [0, 1, 0, 1, 1, 2]
+        a1 = unique(a)
+        assert_array_equal(a1, unq)
+        a2, a2_inv = unique(a, return_inverse=True)
+        assert_array_equal(a2, unq)
+        assert_array_equal(a2_inv, inv)
+
+        # test for chararrays with return_inverse (gh-5099)
+        a = np.chararray(5)
+        a[...] = ''
+        a2, a2_inv = np.unique(a, return_inverse=True)
+        assert_array_equal(a2_inv, np.zeros(5))
+
+    def test_intersect1d(self):
+        # unique inputs
+        a = np.array([5, 7, 1, 2])
+        b = np.array([2, 4, 3, 1, 5])
+
+        ec = np.array([1, 2, 5])
+        c = intersect1d(a, b, assume_unique=True)
+        assert_array_equal(c, ec)
+
+        # non-unique inputs
+        a = np.array([5, 5, 7, 1, 2])
+        b = np.array([2, 1, 4, 3, 3, 1, 5])
+
+        ed = np.array([1, 2, 5])
+        c = intersect1d(a, b)
+        assert_array_equal(c, ed)
+
+        assert_array_equal([], intersect1d([], []))
+
+    def test_setxor1d(self):
+        a = np.array([5, 7, 1, 2])
+        b = np.array([2, 4, 3, 1, 5])
+
+        ec = np.array([3, 4, 7])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.array([1, 2, 3])
+        b = np.array([6, 5, 4])
+
+        ec = np.array([1, 2, 3, 4, 5, 6])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.array([1, 8, 2, 3])
+        b = np.array([6, 5, 4, 8])
+
+        ec = np.array([1, 2, 3, 4, 5, 6])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], setxor1d([], []))
+
+    def test_ediff1d(self):
+        zero_elem = np.array([])
+        one_elem = np.array([1])
+        two_elem = np.array([1, 2])
+
+        assert_array_equal([], ediff1d(zero_elem))
+        assert_array_equal([0], ediff1d(zero_elem, to_begin=0))
+        assert_array_equal([0], ediff1d(zero_elem, to_end=0))
+        assert_array_equal([-1, 0], ediff1d(zero_elem, to_begin=-1, to_end=0))
+        assert_array_equal([], ediff1d(one_elem))
+        assert_array_equal([1], ediff1d(two_elem))
+
+    def test_in1d(self):
+        # we use two different sizes for the b array here to test the
+        # two different paths in in1d().
+        for mult in (1, 10):
+            # One check without np.array, to make sure lists are handled correct
+            a = [5, 7, 1, 2]
+            b = [2, 4, 3, 1, 5] * mult
+            ec = np.array([True, False, True, True])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a[0] = 8
+            ec = np.array([False, False, True, True])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a[0], a[3] = 4, 8
+            ec = np.array([True, False, True, False])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
+            b = [2, 3, 4] * mult
+            ec = [False, True, False, True, True, True, True, True, True, False,
+                  True, False, False, False]
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            b = b + [5, 5, 4] * mult
+            ec = [True, True, True, True, True, True, True, True, True, True,
+                  True, False, True, True]
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 7, 1, 2])
+            b = np.array([2, 4, 3, 1, 5] * mult)
+            ec = np.array([True, False, True, True])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 7, 1, 1, 2])
+            b = np.array([2, 4, 3, 3, 1, 5] * mult)
+            ec = np.array([True, False, True, True, True])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 5])
+            b = np.array([2, 2] * mult)
+            ec = np.array([False, False])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+        a = np.array([5])
+        b = np.array([2])
+        ec = np.array([False])
+        c = in1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal(in1d([], []), [])
+
+    def test_in1d_char_array(self):
+        a = np.array(['a', 'b', 'c', 'd', 'e', 'c', 'e', 'b'])
+        b = np.array(['a', 'c'])
+
+        ec = np.array([True, False, True, False, False, True, False, False])
+        c = in1d(a, b)
+
+        assert_array_equal(c, ec)
+
+    def test_in1d_invert(self):
+        "Test in1d's invert parameter"
+        # We use two different sizes for the b array here to test the
+        # two different paths in in1d().
+        for mult in (1, 10):
+            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
+            b = [2, 3, 4] * mult
+            assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+    def test_in1d_ravel(self):
+        # Test that in1d ravels its input arrays. This is not documented
+        # behavior however. The test is to ensure consistentency.
+        a = np.arange(6).reshape(2, 3)
+        b = np.arange(3, 9).reshape(3, 2)
+        long_b = np.arange(3, 63).reshape(30, 2)
+        ec = np.array([False, False, False, True, True, True])
+
+        assert_array_equal(in1d(a, b, assume_unique=True), ec)
+        assert_array_equal(in1d(a, b, assume_unique=False), ec)
+        assert_array_equal(in1d(a, long_b, assume_unique=True), ec)
+        assert_array_equal(in1d(a, long_b, assume_unique=False), ec)
+
+    def test_union1d(self):
+        a = np.array([5, 4, 7, 1, 2])
+        b = np.array([2, 4, 3, 3, 2, 1, 5])
+
+        ec = np.array([1, 2, 3, 4, 5, 7])
+        c = union1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], union1d([], []))
+
+    def test_setdiff1d(self):
+        a = np.array([6, 5, 4, 7, 1, 2, 7, 4])
+        b = np.array([2, 4, 3, 3, 2, 1, 5])
+
+        ec = np.array([6, 7])
+        c = setdiff1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.arange(21)
+        b = np.arange(19)
+        ec = np.array([19, 20])
+        c = setdiff1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], setdiff1d([], []))
+        a = np.array((), np.uint32)
+        assert_equal(setdiff1d(a, []).dtype, np.uint32)
+
+    def test_setdiff1d_char_array(self):
+        a = np.array(['a', 'b', 'c'])
+        b = np.array(['a', 'b', 's'])
+        assert_array_equal(setdiff1d(a, b), np.array(['c']))
+
+    def test_manyways(self):
+        a = np.array([5, 7, 1, 2, 8])
+        b = np.array([9, 8, 2, 4, 3, 1, 5])
+
+        c1 = setxor1d(a, b)
+        aux1 = intersect1d(a, b)
+        aux2 = union1d(a, b)
+        c2 = setdiff1d(aux2, aux1)
+        assert_array_equal(c1, c2)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
new file mode 100644
index 0000000000..64ad7f4de4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
@@ -0,0 +1,52 @@
+from __future__ import division, absolute_import, print_function
+
+from operator import mul
+from functools import reduce
+
+import numpy as np
+from numpy.random import randint
+from numpy.lib import Arrayterator
+from numpy.testing import assert_
+
+
+def test():
+    np.random.seed(np.arange(10))
+
+    # Create a random array
+    ndims = randint(5)+1
+    shape = tuple(randint(10)+1 for dim in range(ndims))
+    els = reduce(mul, shape)
+    a = np.arange(els)
+    a.shape = shape
+
+    buf_size = randint(2*els)
+    b = Arrayterator(a, buf_size)
+
+    # Check that each block has at most ``buf_size`` elements
+    for block in b:
+        assert_(len(block.flat) <= (buf_size or els))
+
+    # Check that all elements are iterated correctly
+    assert_(list(b.flat) == list(a.flat))
+
+    # Slice arrayterator
+    start = [randint(dim) for dim in shape]
+    stop = [randint(dim)+1 for dim in shape]
+    step = [randint(dim)+1 for dim in shape]
+    slice_ = tuple(slice(*t) for t in zip(start, stop, step))
+    c = b[slice_]
+    d = a[slice_]
+
+    # Check that each block has at most ``buf_size`` elements
+    for block in c:
+        assert_(len(block.flat) <= (buf_size or els))
+
+    # Check that the arrayterator is sliced correctly
+    assert_(np.all(c.__array__() == d))
+
+    # Check that all elements are iterated correctly
+    assert_(list(c.flat) == list(d.flat))
+
+if __name__ == '__main__':
+    from numpy.testing import run_module_suite
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
new file mode 100644
index 0000000000..baa785424a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
@@ -0,0 +1,163 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_almost_equal,
+    assert_allclose
+    )
+
+
+class TestFinancial(TestCase):
+    def test_rate(self):
+        assert_almost_equal(np.rate(10, 0, -3500, 10000),
+                            0.1107, 4)
+
+    def test_irr(self):
+        v = [-150000, 15000, 25000, 35000, 45000, 60000]
+        assert_almost_equal(np.irr(v), 0.0524, 2)
+        v = [-100, 0, 0, 74]
+        assert_almost_equal(np.irr(v), -0.0955, 2)
+        v = [-100, 39, 59, 55, 20]
+        assert_almost_equal(np.irr(v), 0.28095, 2)
+        v = [-100, 100, 0, -7]
+        assert_almost_equal(np.irr(v), -0.0833, 2)
+        v = [-100, 100, 0, 7]
+        assert_almost_equal(np.irr(v), 0.06206, 2)
+        v = [-5, 10.5, 1, -8, 1]
+        assert_almost_equal(np.irr(v), 0.0886, 2)
+
+    def test_pv(self):
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0), -127128.17, 2)
+
+    def test_fv(self):
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0), 86609.36, 2)
+
+    def test_pmt(self):
+        res = np.pmt(0.08/12, 5*12, 15000)
+        tgt = -304.145914
+        assert_allclose(res, tgt)
+        # Test the edge case where rate == 0.0
+        res = np.pmt(0.0, 5*12, 15000)
+        tgt = -250.0
+        assert_allclose(res, tgt)
+        # Test the case where we use broadcast and
+        # the arguments passed in are arrays.
+        res = np.pmt([[0.0, 0.8],[0.3, 0.8]],[12, 3],[2000, 20000])
+        tgt = np.array([[-166.66667, -19311.258],[-626.90814, -19311.258]])
+        assert_allclose(res, tgt)
+
+    def test_ppmt(self):
+        np.round(np.ppmt(0.1/12, 1, 60, 55000), 2) == 710.25
+
+    def test_ipmt(self):
+        np.round(np.ipmt(0.1/12, 1, 24, 2000), 2) == 16.67
+
+    def test_nper(self):
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
+                            21.54, 2)
+
+    def test_nper2(self):
+        assert_almost_equal(np.nper(0.0, -2000, 0, 100000.),
+                            50.0, 1)
+
+    def test_npv(self):
+        assert_almost_equal(
+            np.npv(0.05, [-15000, 1500, 2500, 3500, 4500, 6000]),
+            122.89, 2)
+
+    def test_mirr(self):
+        val = [-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000]
+        assert_almost_equal(np.mirr(val, 0.08, 0.055), 0.0666, 4)
+
+        val = [-120000, 39000, 30000, 21000, 37000, 46000]
+        assert_almost_equal(np.mirr(val, 0.10, 0.12), 0.126094, 6)
+
+        val = [100, 200, -50, 300, -200]
+        assert_almost_equal(np.mirr(val, 0.05, 0.06), 0.3428, 4)
+
+        val = [39000, 30000, 21000, 37000, 46000]
+        assert_(np.isnan(np.mirr(val, 0.10, 0.12)))
+
+    def test_when(self):
+        #begin
+        assert_almost_equal(np.rate(10, 20, -3500, 10000, 1),
+                            np.rate(10, 20, -3500, 10000, 'begin'), 4)
+        #end
+        assert_almost_equal(np.rate(10, 20, -3500, 10000),
+                            np.rate(10, 20, -3500, 10000, 'end'), 4)
+        assert_almost_equal(np.rate(10, 20, -3500, 10000, 0),
+                            np.rate(10, 20, -3500, 10000, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 1),
+                            np.pv(0.07, 20, 12000, 0, 'begin'), 2)
+        # end
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0),
+                            np.pv(0.07, 20, 12000, 0, 'end'), 2)
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 0),
+                            np.pv(0.07, 20, 12000, 0, 'end'), 2)
+
+        # begin
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 1),
+                            np.fv(0.075, 20, -2000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0),
+                            np.fv(0.075, 20, -2000, 0, 'end'), 4)
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0),
+                            np.fv(0.075, 20, -2000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0, 1),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'end'), 4)
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0, 0),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0, 1),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'end'), 4)
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0, 0),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0, 1),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'end'), 4)
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0, 0),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., 1),
+                            np.nper(0.075, -2000, 0, 100000., 'begin'), 4)
+        # end
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
+                            np.nper(0.075, -2000, 0, 100000., 'end'), 4)
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., 0),
+                            np.nper(0.075, -2000, 0, 100000., 'end'), 4)
+
+    def test_broadcast(self):
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., [0, 1]),
+                            [21.5449442, 20.76156441], 4)
+
+        assert_almost_equal(np.ipmt(0.1/12, list(range(5)), 24, 2000),
+                            [-17.29165168, -16.66666667, -16.03647345,
+                                -15.40102862, -14.76028842], 4)
+
+        assert_almost_equal(np.ppmt(0.1/12, list(range(5)), 24, 2000),
+                            [-74.998201, -75.62318601, -76.25337923,
+                                -76.88882405, -77.52956425], 4)
+
+        assert_almost_equal(np.ppmt(0.1/12, list(range(5)), 24, 2000, 0,
+                                    [0, 0, 1, 'end', 'begin']),
+                            [-74.998201, -75.62318601, -75.62318601,
+                                -76.88882405, -76.88882405], 4)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_format.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
new file mode 100644
index 0000000000..a091ef5b3f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
@@ -0,0 +1,840 @@
+from __future__ import division, absolute_import, print_function
+
+r''' Test the .npy file format.
+
+Set up:
+
+    >>> import sys
+    >>> from io import BytesIO
+    >>> from numpy.lib import format
+    >>>
+    >>> scalars = [
+    ...     np.uint8,
+    ...     np.int8,
+    ...     np.uint16,
+    ...     np.int16,
+    ...     np.uint32,
+    ...     np.int32,
+    ...     np.uint64,
+    ...     np.int64,
+    ...     np.float32,
+    ...     np.float64,
+    ...     np.complex64,
+    ...     np.complex128,
+    ...     object,
+    ... ]
+    >>>
+    >>> basic_arrays = []
+    >>>
+    >>> for scalar in scalars:
+    ...     for endian in '<>':
+    ...         dtype = np.dtype(scalar).newbyteorder(endian)
+    ...         basic = np.arange(15).astype(dtype)
+    ...         basic_arrays.extend([
+    ...             np.array([], dtype=dtype),
+    ...             np.array(10, dtype=dtype),
+    ...             basic,
+    ...             basic.reshape((3,5)),
+    ...             basic.reshape((3,5)).T,
+    ...             basic.reshape((3,5))[::-1,::2],
+    ...         ])
+    ...
+    >>>
+    >>> Pdescr = [
+    ...     ('x', 'i4', (2,)),
+    ...     ('y', 'f8', (2, 2)),
+    ...     ('z', 'u1')]
+    >>>
+    >>>
+    >>> PbufferT = [
+    ...     ([3,2], [[6.,4.],[6.,4.]], 8),
+    ...     ([4,3], [[7.,5.],[7.,5.]], 9),
+    ...     ]
+    >>>
+    >>>
+    >>> Ndescr = [
+    ...     ('x', 'i4', (2,)),
+    ...     ('Info', [
+    ...         ('value', 'c16'),
+    ...         ('y2', 'f8'),
+    ...         ('Info2', [
+    ...             ('name', 'S2'),
+    ...             ('value', 'c16', (2,)),
+    ...             ('y3', 'f8', (2,)),
+    ...             ('z3', 'u4', (2,))]),
+    ...         ('name', 'S2'),
+    ...         ('z2', 'b1')]),
+    ...     ('color', 'S2'),
+    ...     ('info', [
+    ...         ('Name', 'U8'),
+    ...         ('Value', 'c16')]),
+    ...     ('y', 'f8', (2, 2)),
+    ...     ('z', 'u1')]
+    >>>
+    >>>
+    >>> NbufferT = [
+    ...     ([3,2], (6j, 6., ('nn', [6j,4j], [6.,4.], [1,2]), 'NN', True), 'cc', ('NN', 6j), [[6.,4.],[6.,4.]], 8),
+    ...     ([4,3], (7j, 7., ('oo', [7j,5j], [7.,5.], [2,1]), 'OO', False), 'dd', ('OO', 7j), [[7.,5.],[7.,5.]], 9),
+    ...     ]
+    >>>
+    >>>
+    >>> record_arrays = [
+    ...     np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')),
+    ...     np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')),
+    ...     np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')),
+    ...     np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')),
+    ... ]
+
+Test the magic string writing.
+
+    >>> format.magic(1, 0)
+    '\x93NUMPY\x01\x00'
+    >>> format.magic(0, 0)
+    '\x93NUMPY\x00\x00'
+    >>> format.magic(255, 255)
+    '\x93NUMPY\xff\xff'
+    >>> format.magic(2, 5)
+    '\x93NUMPY\x02\x05'
+
+Test the magic string reading.
+
+    >>> format.read_magic(BytesIO(format.magic(1, 0)))
+    (1, 0)
+    >>> format.read_magic(BytesIO(format.magic(0, 0)))
+    (0, 0)
+    >>> format.read_magic(BytesIO(format.magic(255, 255)))
+    (255, 255)
+    >>> format.read_magic(BytesIO(format.magic(2, 5)))
+    (2, 5)
+
+Test the header writing.
+
+    >>> for arr in basic_arrays + record_arrays:
+    ...     f = BytesIO()
+    ...     format.write_array_header_1_0(f, arr)   # XXX: arr is not a dict, items gets called on it
+    ...     print(repr(f.getvalue()))
+    ...
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<f4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>f4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<f8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>f8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<c8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>c8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (0,)}             \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': ()}               \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (15,)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (3, 5)}           \n"
+    "F\x00{'descr': '<c16', 'fortran_order': True, 'shape': (5, 3)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (3, 3)}           \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (0,)}             \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': ()}               \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (15,)}            \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 5)}           \n"
+    "F\x00{'descr': '>c16', 'fortran_order': True, 'shape': (5, 3)}            \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 3)}           \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "v\x00{'descr': [('x', '<i4', (2,)), ('y', '<f8', (2, 2)), ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}         \n"
+    "\x16\x02{'descr': [('x', '<i4', (2,)),\n           ('Info',\n            [('value', '<c16'),\n             ('y2', '<f8'),\n             ('Info2',\n              [('name', '|S2'),\n               ('value', '<c16', (2,)),\n               ('y3', '<f8', (2,)),\n               ('z3', '<u4', (2,))]),\n             ('name', '|S2'),\n             ('z2', '|b1')]),\n           ('color', '|S2'),\n           ('info', [('Name', '<U8'), ('Value', '<c16')]),\n           ('y', '<f8', (2, 2)),\n           ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}      \n"
+    "v\x00{'descr': [('x', '>i4', (2,)), ('y', '>f8', (2, 2)), ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}         \n"
+    "\x16\x02{'descr': [('x', '>i4', (2,)),\n           ('Info',\n            [('value', '>c16'),\n             ('y2', '>f8'),\n             ('Info2',\n              [('name', '|S2'),\n               ('value', '>c16', (2,)),\n               ('y3', '>f8', (2,)),\n               ('z3', '>u4', (2,))]),\n             ('name', '|S2'),\n             ('z2', '|b1')]),\n           ('color', '|S2'),\n           ('info', [('Name', '>U8'), ('Value', '>c16')]),\n           ('y', '>f8', (2, 2)),\n           ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}      \n"
+'''
+
+import sys
+import os
+import shutil
+import tempfile
+import warnings
+from io import BytesIO
+
+import numpy as np
+from numpy.compat import asbytes, asbytes_nested, sixu
+from numpy.testing import (
+    run_module_suite, assert_, assert_array_equal, assert_raises, raises,
+    dec, SkipTest
+    )
+from numpy.lib import format
+
+
+tempdir = None
+
+# Module-level setup.
+
+
+def setup_module():
+    global tempdir
+    tempdir = tempfile.mkdtemp()
+
+
+def teardown_module():
+    global tempdir
+    if tempdir is not None and os.path.isdir(tempdir):
+        shutil.rmtree(tempdir)
+        tempdir = None
+
+
+# Generate some basic arrays to test with.
+scalars = [
+    np.uint8,
+    np.int8,
+    np.uint16,
+    np.int16,
+    np.uint32,
+    np.int32,
+    np.uint64,
+    np.int64,
+    np.float32,
+    np.float64,
+    np.complex64,
+    np.complex128,
+    object,
+]
+basic_arrays = []
+for scalar in scalars:
+    for endian in '<>':
+        dtype = np.dtype(scalar).newbyteorder(endian)
+        basic = np.arange(1500).astype(dtype)
+        basic_arrays.extend([
+            # Empty
+            np.array([], dtype=dtype),
+            # Rank-0
+            np.array(10, dtype=dtype),
+            # 1-D
+            basic,
+            # 2-D C-contiguous
+            basic.reshape((30, 50)),
+            # 2-D F-contiguous
+            basic.reshape((30, 50)).T,
+            # 2-D non-contiguous
+            basic.reshape((30, 50))[::-1, ::2],
+        ])
+
+# More complicated record arrays.
+# This is the structure of the table used for plain objects:
+#
+# +-+-+-+
+# |x|y|z|
+# +-+-+-+
+
+# Structure of a plain array description:
+Pdescr = [
+    ('x', 'i4', (2,)),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+# A plain list of tuples with values for testing:
+PbufferT = [
+    # x     y                  z
+    ([3, 2], [[6., 4.], [6., 4.]], 8),
+    ([4, 3], [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+# This is the structure of the table used for nested objects (DON'T PANIC!):
+#
+# +-+---------------------------------+-----+----------+-+-+
+# |x|Info                             |color|info      |y|z|
+# | +-----+--+----------------+----+--+     +----+-----+ | |
+# | |value|y2|Info2           |name|z2|     |Name|Value| | |
+# | |     |  +----+-----+--+--+    |  |     |    |     | | |
+# | |     |  |name|value|y3|z3|    |  |     |    |     | | |
+# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+
+#
+
+# The corresponding nested array description:
+Ndescr = [
+    ('x', 'i4', (2,)),
+    ('Info', [
+        ('value', 'c16'),
+        ('y2', 'f8'),
+        ('Info2', [
+            ('name', 'S2'),
+            ('value', 'c16', (2,)),
+            ('y3', 'f8', (2,)),
+            ('z3', 'u4', (2,))]),
+        ('name', 'S2'),
+        ('z2', 'b1')]),
+    ('color', 'S2'),
+    ('info', [
+        ('Name', 'U8'),
+        ('Value', 'c16')]),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+NbufferT = [
+    # x     Info                                                color info        y                  z
+    #       value y2 Info2                            name z2         Name Value
+    #                name   value    y3       z3
+    ([3, 2], (6j, 6., ('nn', [6j, 4j], [6., 4.], [1, 2]), 'NN', True),
+     'cc', ('NN', 6j), [[6., 4.], [6., 4.]], 8),
+    ([4, 3], (7j, 7., ('oo', [7j, 5j], [7., 5.], [2, 1]), 'OO', False),
+     'dd', ('OO', 7j), [[7., 5.], [7., 5.]], 9),
+    ]
+
+record_arrays = [
+    np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')),
+    np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')),
+    np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')),
+    np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')),
+]
+
+
+#BytesIO that reads a random number of bytes at a time
+class BytesIOSRandomSize(BytesIO):
+    def read(self, size=None):
+        import random
+        size = random.randint(1, size)
+        return super(BytesIOSRandomSize, self).read(size)
+
+
+def roundtrip(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    f2 = BytesIO(f.getvalue())
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def roundtrip_randsize(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    f2 = BytesIOSRandomSize(f.getvalue())
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def roundtrip_truncated(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    #BytesIO is one byte short
+    f2 = BytesIO(f.getvalue()[0:-1])
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def assert_equal_(o1, o2):
+    assert_(o1 == o2)
+
+
+def test_roundtrip():
+    for arr in basic_arrays + record_arrays:
+        arr2 = roundtrip(arr)
+        yield assert_array_equal, arr, arr2
+
+
+def test_roundtrip_randsize():
+    for arr in basic_arrays + record_arrays:
+        if arr.dtype != object:
+            arr2 = roundtrip_randsize(arr)
+            yield assert_array_equal, arr, arr2
+
+
+def test_roundtrip_truncated():
+    for arr in basic_arrays:
+        if arr.dtype != object:
+            yield assert_raises, ValueError, roundtrip_truncated, arr
+
+
+def test_long_str():
+    # check items larger than internal buffer size, gh-4027
+    long_str_arr = np.ones(1, dtype=np.dtype((str, format.BUFFER_SIZE + 1)))
+    long_str_arr2 = roundtrip(long_str_arr)
+    assert_array_equal(long_str_arr, long_str_arr2)
+
+
+@dec.slow
+def test_memmap_roundtrip():
+    # Fixme: test crashes nose on windows.
+    if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
+        for arr in basic_arrays + record_arrays:
+            if arr.dtype.hasobject:
+                # Skip these since they can't be mmap'ed.
+                continue
+            # Write it out normally and through mmap.
+            nfn = os.path.join(tempdir, 'normal.npy')
+            mfn = os.path.join(tempdir, 'memmap.npy')
+            fp = open(nfn, 'wb')
+            try:
+                format.write_array(fp, arr)
+            finally:
+                fp.close()
+
+            fortran_order = (
+                arr.flags.f_contiguous and not arr.flags.c_contiguous)
+            ma = format.open_memmap(mfn, mode='w+', dtype=arr.dtype,
+                                    shape=arr.shape, fortran_order=fortran_order)
+            ma[...] = arr
+            del ma
+
+            # Check that both of these files' contents are the same.
+            fp = open(nfn, 'rb')
+            normal_bytes = fp.read()
+            fp.close()
+            fp = open(mfn, 'rb')
+            memmap_bytes = fp.read()
+            fp.close()
+            yield assert_equal_, normal_bytes, memmap_bytes
+
+            # Check that reading the file using memmap works.
+            ma = format.open_memmap(nfn, mode='r')
+            del ma
+
+
+def test_compressed_roundtrip():
+    arr = np.random.rand(200, 200)
+    npz_file = os.path.join(tempdir, 'compressed.npz')
+    np.savez_compressed(npz_file, arr=arr)
+    arr1 = np.load(npz_file)['arr']
+    assert_array_equal(arr, arr1)
+
+
+def test_python2_python3_interoperability():
+    if sys.version_info[0] >= 3:
+        fname = 'win64python2.npy'
+    else:
+        fname = 'python3.npy'
+    path = os.path.join(os.path.dirname(__file__), 'data', fname)
+    data = np.load(path)
+    assert_array_equal(data, np.ones(2))
+
+
+def test_pickle_python2_python3():
+    # Test that loading object arrays saved on Python 2 works both on
+    # Python 2 and Python 3 and vice versa
+    data_dir = os.path.join(os.path.dirname(__file__), 'data')
+
+    if sys.version_info[0] >= 3:
+        xrange = range
+    else:
+        import __builtin__
+        xrange = __builtin__.xrange
+
+    expected = np.array([None, xrange, sixu('\u512a\u826f'),
+                         asbytes('\xe4\xb8\x8d\xe8\x89\xaf')],
+                        dtype=object)
+
+    for fname in ['py2-objarr.npy', 'py2-objarr.npz',
+                  'py3-objarr.npy', 'py3-objarr.npz']:
+        path = os.path.join(data_dir, fname)
+
+        if (fname.endswith('.npz') and sys.version_info[0] == 2 and
+                sys.version_info[1] < 7):
+            # Reading object arrays directly from zipfile appears to fail
+            # on Py2.6, see cfae0143b4
+            continue
+
+        for encoding in ['bytes', 'latin1']:
+            if (sys.version_info[0] >= 3 and sys.version_info[1] < 4 and
+                    encoding == 'bytes'):
+                # The bytes encoding is available starting from Python 3.4
+                continue
+
+            data_f = np.load(path, encoding=encoding)
+            if fname.endswith('.npz'):
+                data = data_f['x']
+                data_f.close()
+            else:
+                data = data_f
+
+            if sys.version_info[0] >= 3:
+                if encoding == 'latin1' and fname.startswith('py2'):
+                    assert_(isinstance(data[3], str))
+                    assert_array_equal(data[:-1], expected[:-1])
+                    # mojibake occurs
+                    assert_array_equal(data[-1].encode(encoding), expected[-1])
+                else:
+                    assert_(isinstance(data[3], bytes))
+                    assert_array_equal(data, expected)
+            else:
+                assert_array_equal(data, expected)
+
+        if sys.version_info[0] >= 3:
+            if fname.startswith('py2'):
+                if fname.endswith('.npz'):
+                    data = np.load(path)
+                    assert_raises(UnicodeError, data.__getitem__, 'x')
+                    data.close()
+                    data = np.load(path, fix_imports=False, encoding='latin1')
+                    assert_raises(ImportError, data.__getitem__, 'x')
+                    data.close()
+                else:
+                    assert_raises(UnicodeError, np.load, path)
+                    assert_raises(ImportError, np.load, path,
+                                  encoding='latin1', fix_imports=False)
+
+
+def test_pickle_disallow():
+    data_dir = os.path.join(os.path.dirname(__file__), 'data')
+
+    path = os.path.join(data_dir, 'py2-objarr.npy')
+    assert_raises(ValueError, np.load, path,
+                  allow_pickle=False, encoding='latin1')
+
+    path = os.path.join(data_dir, 'py2-objarr.npz')
+    f = np.load(path, allow_pickle=False, encoding='latin1')
+    assert_raises(ValueError, f.__getitem__, 'x')
+
+    path = os.path.join(tempdir, 'pickle-disabled.npy')
+    assert_raises(ValueError, np.save, path, np.array([None], dtype=object),
+                  allow_pickle=False)
+
+
+def test_version_2_0():
+    f = BytesIO()
+    # requires more than 2 byte for header
+    dt = [(("%d" % i) * 100, float) for i in range(500)]
+    d = np.ones(1000, dtype=dt)
+
+    format.write_array(f, d, version=(2, 0))
+    with warnings.catch_warnings(record=True) as w:
+        warnings.filterwarnings('always', '', UserWarning)
+        format.write_array(f, d)
+        assert_(w[0].category is UserWarning)
+
+    f.seek(0)
+    n = format.read_array(f)
+    assert_array_equal(d, n)
+
+    # 1.0 requested but data cannot be saved this way
+    assert_raises(ValueError, format.write_array, f, d, (1, 0))
+
+
+def test_version_2_0_memmap():
+    # requires more than 2 byte for header
+    dt = [(("%d" % i) * 100, float) for i in range(500)]
+    d = np.ones(1000, dtype=dt)
+    tf = tempfile.mktemp('', 'mmap', dir=tempdir)
+
+    # 1.0 requested but data cannot be saved this way
+    assert_raises(ValueError, format.open_memmap, tf, mode='w+', dtype=d.dtype,
+                            shape=d.shape, version=(1, 0))
+
+    ma = format.open_memmap(tf, mode='w+', dtype=d.dtype,
+                            shape=d.shape, version=(2, 0))
+    ma[...] = d
+    del ma
+
+    with warnings.catch_warnings(record=True) as w:
+        warnings.filterwarnings('always', '', UserWarning)
+        ma = format.open_memmap(tf, mode='w+', dtype=d.dtype,
+                                shape=d.shape, version=None)
+        assert_(w[0].category is UserWarning)
+        ma[...] = d
+        del ma
+
+    ma = format.open_memmap(tf, mode='r')
+    assert_array_equal(ma, d)
+
+
+def test_write_version():
+    f = BytesIO()
+    arr = np.arange(1)
+    # These should pass.
+    format.write_array(f, arr, version=(1, 0))
+    format.write_array(f, arr)
+
+    format.write_array(f, arr, version=None)
+    format.write_array(f, arr)
+
+    format.write_array(f, arr, version=(2, 0))
+    format.write_array(f, arr)
+
+    # These should all fail.
+    bad_versions = [
+        (1, 1),
+        (0, 0),
+        (0, 1),
+        (2, 2),
+        (255, 255),
+    ]
+    for version in bad_versions:
+        try:
+            format.write_array(f, arr, version=version)
+        except ValueError:
+            pass
+        else:
+            raise AssertionError("we should have raised a ValueError for the bad version %r" % (version,))
+
+
+bad_version_magic = asbytes_nested([
+    '\x93NUMPY\x01\x01',
+    '\x93NUMPY\x00\x00',
+    '\x93NUMPY\x00\x01',
+    '\x93NUMPY\x02\x00',
+    '\x93NUMPY\x02\x02',
+    '\x93NUMPY\xff\xff',
+])
+malformed_magic = asbytes_nested([
+    '\x92NUMPY\x01\x00',
+    '\x00NUMPY\x01\x00',
+    '\x93numpy\x01\x00',
+    '\x93MATLB\x01\x00',
+    '\x93NUMPY\x01',
+    '\x93NUMPY',
+    '',
+])
+
+def test_read_magic():
+    s1 = BytesIO()
+    s2 = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+
+    format.write_array(s1, arr, version=(1, 0))
+    format.write_array(s2, arr, version=(2, 0))
+
+    s1.seek(0)
+    s2.seek(0)
+
+    version1 = format.read_magic(s1)
+    version2 = format.read_magic(s2)
+
+    assert_(version1 == (1, 0))
+    assert_(version2 == (2, 0))
+
+    assert_(s1.tell() == format.MAGIC_LEN)
+    assert_(s2.tell() == format.MAGIC_LEN)
+
+def test_read_magic_bad_magic():
+    for magic in malformed_magic:
+        f = BytesIO(magic)
+        yield raises(ValueError)(format.read_magic), f
+
+
+def test_read_version_1_0_bad_magic():
+    for magic in bad_version_magic + malformed_magic:
+        f = BytesIO(magic)
+        yield raises(ValueError)(format.read_array), f
+
+
+def test_bad_magic_args():
+    assert_raises(ValueError, format.magic, -1, 1)
+    assert_raises(ValueError, format.magic, 256, 1)
+    assert_raises(ValueError, format.magic, 1, -1)
+    assert_raises(ValueError, format.magic, 1, 256)
+
+
+def test_large_header():
+    s = BytesIO()
+    d = {'a': 1, 'b': 2}
+    format.write_array_header_1_0(s, d)
+
+    s = BytesIO()
+    d = {'a': 1, 'b': 2, 'c': 'x'*256*256}
+    assert_raises(ValueError, format.write_array_header_1_0, s, d)
+
+
+def test_read_array_header_1_0():
+    s = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+    format.write_array(s, arr, version=(1, 0))
+
+    s.seek(format.MAGIC_LEN)
+    shape, fortran, dtype = format.read_array_header_1_0(s)
+
+    assert_((shape, fortran, dtype) == ((3, 6), False, float))
+
+
+def test_read_array_header_2_0():
+    s = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+    format.write_array(s, arr, version=(2, 0))
+
+    s.seek(format.MAGIC_LEN)
+    shape, fortran, dtype = format.read_array_header_2_0(s)
+
+    assert_((shape, fortran, dtype) == ((3, 6), False, float))
+
+
+def test_bad_header():
+    # header of length less than 2 should fail
+    s = BytesIO()
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+    s = BytesIO(asbytes('1'))
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    # header shorter than indicated size should fail
+    s = BytesIO(asbytes('\x01\x00'))
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    # headers without the exact keys required should fail
+    d = {"shape": (1, 2),
+         "descr": "x"}
+    s = BytesIO()
+    format.write_array_header_1_0(s, d)
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    d = {"shape": (1, 2),
+         "fortran_order": False,
+         "descr": "x",
+         "extrakey": -1}
+    s = BytesIO()
+    format.write_array_header_1_0(s, d)
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+
+def test_large_file_support():
+    if (sys.platform == 'win32' or sys.platform == 'cygwin'):
+        raise SkipTest("Unknown if Windows has sparse filesystems")
+    # try creating a large sparse file
+    tf_name = os.path.join(tempdir, 'sparse_file')
+    try:
+        # seek past end would work too, but linux truncate somewhat
+        # increases the chances that we have a sparse filesystem and can
+        # avoid actually writing 5GB
+        import subprocess as sp
+        sp.check_call(["truncate", "-s", "5368709120", tf_name])
+    except:
+        raise SkipTest("Could not create 5GB large file")
+    # write a small array to the end
+    with open(tf_name, "wb") as f:
+        f.seek(5368709120)
+        d = np.arange(5)
+        np.save(f, d)
+    # read it back
+    with open(tf_name, "rb") as f:
+        f.seek(5368709120)
+        r = np.load(f)
+    assert_array_equal(r, d)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
new file mode 100644
index 0000000000..ea10cbc761
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
@@ -0,0 +1,2824 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, assert_array_almost_equal, assert_raises,
+    assert_allclose, assert_array_max_ulp, assert_warns,
+    assert_raises_regex, dec, clear_and_catch_warnings
+)
+import numpy.lib.function_base as nfb
+from numpy.random import rand
+from numpy.lib import (
+    add_newdoc_ufunc, angle, average, bartlett, blackman, corrcoef, cov,
+    delete, diff, digitize, extract, flipud, gradient, hamming, hanning,
+    histogram, histogramdd, i0, insert, interp, kaiser, meshgrid, msort,
+    piecewise, place, select, setxor1d, sinc, split, trapz, trim_zeros,
+    unwrap, unique, vectorize,
+)
+
+from numpy.compat import long
+
+
+class TestAny(TestCase):
+
+    def test_basic(self):
+        y1 = [0, 0, 1, 0]
+        y2 = [0, 0, 0, 0]
+        y3 = [1, 0, 1, 0]
+        assert_(np.any(y1))
+        assert_(np.any(y3))
+        assert_(not np.any(y2))
+
+    def test_nd(self):
+        y1 = [[0, 0, 0], [0, 1, 0], [1, 1, 0]]
+        assert_(np.any(y1))
+        assert_array_equal(np.sometrue(y1, axis=0), [1, 1, 0])
+        assert_array_equal(np.sometrue(y1, axis=1), [0, 1, 1])
+
+
+class TestAll(TestCase):
+
+    def test_basic(self):
+        y1 = [0, 1, 1, 0]
+        y2 = [0, 0, 0, 0]
+        y3 = [1, 1, 1, 1]
+        assert_(not np.all(y1))
+        assert_(np.all(y3))
+        assert_(not np.all(y2))
+        assert_(np.all(~np.array(y2)))
+
+    def test_nd(self):
+        y1 = [[0, 0, 1], [0, 1, 1], [1, 1, 1]]
+        assert_(not np.all(y1))
+        assert_array_equal(np.alltrue(y1, axis=0), [0, 0, 1])
+        assert_array_equal(np.alltrue(y1, axis=1), [0, 0, 1])
+
+
+class TestCopy(TestCase):
+
+    def test_basic(self):
+        a = np.array([[1, 2], [3, 4]])
+        a_copy = np.copy(a)
+        assert_array_equal(a, a_copy)
+        a_copy[0, 0] = 10
+        assert_equal(a[0, 0], 1)
+        assert_equal(a_copy[0, 0], 10)
+
+    def test_order(self):
+        # It turns out that people rely on np.copy() preserving order by
+        # default; changing this broke scikit-learn:
+        #   https://github.com/scikit-learn/scikit-learn/commit/7842748cf777412c506a8c0ed28090711d3a3783
+        a = np.array([[1, 2], [3, 4]])
+        assert_(a.flags.c_contiguous)
+        assert_(not a.flags.f_contiguous)
+        a_fort = np.array([[1, 2], [3, 4]], order="F")
+        assert_(not a_fort.flags.c_contiguous)
+        assert_(a_fort.flags.f_contiguous)
+        a_copy = np.copy(a)
+        assert_(a_copy.flags.c_contiguous)
+        assert_(not a_copy.flags.f_contiguous)
+        a_fort_copy = np.copy(a_fort)
+        assert_(not a_fort_copy.flags.c_contiguous)
+        assert_(a_fort_copy.flags.f_contiguous)
+
+
+class TestAverage(TestCase):
+
+    def test_basic(self):
+        y1 = np.array([1, 2, 3])
+        assert_(average(y1, axis=0) == 2.)
+        y2 = np.array([1., 2., 3.])
+        assert_(average(y2, axis=0) == 2.)
+        y3 = [0., 0., 0.]
+        assert_(average(y3, axis=0) == 0.)
+
+        y4 = np.ones((4, 4))
+        y4[0, 1] = 0
+        y4[1, 0] = 2
+        assert_almost_equal(y4.mean(0), average(y4, 0))
+        assert_almost_equal(y4.mean(1), average(y4, 1))
+
+        y5 = rand(5, 5)
+        assert_almost_equal(y5.mean(0), average(y5, 0))
+        assert_almost_equal(y5.mean(1), average(y5, 1))
+
+        y6 = np.matrix(rand(5, 5))
+        assert_array_equal(y6.mean(0), average(y6, 0))
+
+    def test_weights(self):
+        y = np.arange(10)
+        w = np.arange(10)
+        actual = average(y, weights=w)
+        desired = (np.arange(10) ** 2).sum() * 1. / np.arange(10).sum()
+        assert_almost_equal(actual, desired)
+
+        y1 = np.array([[1, 2, 3], [4, 5, 6]])
+        w0 = [1, 2]
+        actual = average(y1, weights=w0, axis=0)
+        desired = np.array([3., 4., 5.])
+        assert_almost_equal(actual, desired)
+
+        w1 = [0, 0, 1]
+        actual = average(y1, weights=w1, axis=1)
+        desired = np.array([3., 6.])
+        assert_almost_equal(actual, desired)
+
+        # This should raise an error. Can we test for that ?
+        # assert_equal(average(y1, weights=w1), 9./2.)
+
+        # 2D Case
+        w2 = [[0, 0, 1], [0, 0, 2]]
+        desired = np.array([3., 6.])
+        assert_array_equal(average(y1, weights=w2, axis=1), desired)
+        assert_equal(average(y1, weights=w2), 5.)
+
+        y3 = rand(5).astype(np.float32)
+        w3 = rand(5).astype(np.float64)
+
+        assert_(np.average(y3, weights=w3).dtype == np.result_type(y3, w3))
+
+    def test_returned(self):
+        y = np.array([[1, 2, 3], [4, 5, 6]])
+
+        # No weights
+        avg, scl = average(y, returned=True)
+        assert_equal(scl, 6.)
+
+        avg, scl = average(y, 0, returned=True)
+        assert_array_equal(scl, np.array([2., 2., 2.]))
+
+        avg, scl = average(y, 1, returned=True)
+        assert_array_equal(scl, np.array([3., 3.]))
+
+        # With weights
+        w0 = [1, 2]
+        avg, scl = average(y, weights=w0, axis=0, returned=True)
+        assert_array_equal(scl, np.array([3., 3., 3.]))
+
+        w1 = [1, 2, 3]
+        avg, scl = average(y, weights=w1, axis=1, returned=True)
+        assert_array_equal(scl, np.array([6., 6.]))
+
+        w2 = [[0, 0, 1], [1, 2, 3]]
+        avg, scl = average(y, weights=w2, axis=1, returned=True)
+        assert_array_equal(scl, np.array([1., 6.]))
+
+
+class TestSelect(TestCase):
+    choices = [np.array([1, 2, 3]),
+               np.array([4, 5, 6]),
+               np.array([7, 8, 9])]
+    conditions = [np.array([False, False, False]),
+                  np.array([False, True, False]),
+                  np.array([False, False, True])]
+
+    def _select(self, cond, values, default=0):
+        output = []
+        for m in range(len(cond)):
+            output += [V[m] for V, C in zip(values, cond) if C[m]] or [default]
+        return output
+
+    def test_basic(self):
+        choices = self.choices
+        conditions = self.conditions
+        assert_array_equal(select(conditions, choices, default=15),
+                           self._select(conditions, choices, default=15))
+
+        assert_equal(len(choices), 3)
+        assert_equal(len(conditions), 3)
+
+    def test_broadcasting(self):
+        conditions = [np.array(True), np.array([False, True, False])]
+        choices = [1, np.arange(12).reshape(4, 3)]
+        assert_array_equal(select(conditions, choices), np.ones((4, 3)))
+        # default can broadcast too:
+        assert_equal(select([True], [0], default=[0]).shape, (1,))
+
+    def test_return_dtype(self):
+        assert_equal(select(self.conditions, self.choices, 1j).dtype,
+                     np.complex_)
+        # But the conditions need to be stronger then the scalar default
+        # if it is scalar.
+        choices = [choice.astype(np.int8) for choice in self.choices]
+        assert_equal(select(self.conditions, choices).dtype, np.int8)
+
+        d = np.array([1, 2, 3, np.nan, 5, 7])
+        m = np.isnan(d)
+        assert_equal(select([m], [d]), [0, 0, 0, np.nan, 0, 0])
+
+    def test_deprecated_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter("always")
+            assert_equal(select([], [], 3j), 3j)
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, select, [], [])
+            warnings.simplefilter("error")
+            assert_raises(DeprecationWarning, select, [], [])
+
+    def test_non_bool_deprecation(self):
+        choices = self.choices
+        conditions = self.conditions[:]
+        with warnings.catch_warnings():
+            warnings.filterwarnings("always")
+            conditions[0] = conditions[0].astype(np.int_)
+            assert_warns(DeprecationWarning, select, conditions, choices)
+            conditions[0] = conditions[0].astype(np.uint8)
+            assert_warns(DeprecationWarning, select, conditions, choices)
+            warnings.filterwarnings("error")
+            assert_raises(DeprecationWarning, select, conditions, choices)
+
+    def test_many_arguments(self):
+        # This used to be limited by NPY_MAXARGS == 32
+        conditions = [np.array([False])] * 100
+        choices = [np.array([1])] * 100
+        select(conditions, choices)
+
+
+class TestInsert(TestCase):
+
+    def test_basic(self):
+        a = [1, 2, 3]
+        assert_equal(insert(a, 0, 1), [1, 1, 2, 3])
+        assert_equal(insert(a, 3, 1), [1, 2, 3, 1])
+        assert_equal(insert(a, [1, 1, 1], [1, 2, 3]), [1, 1, 2, 3, 2, 3])
+        assert_equal(insert(a, 1, [1, 2, 3]), [1, 1, 2, 3, 2, 3])
+        assert_equal(insert(a, [1, -1, 3], 9), [1, 9, 2, 9, 3, 9])
+        assert_equal(insert(a, slice(-1, None, -1), 9), [9, 1, 9, 2, 9, 3])
+        assert_equal(insert(a, [-1, 1, 3], [7, 8, 9]), [1, 8, 2, 7, 3, 9])
+        b = np.array([0, 1], dtype=np.float64)
+        assert_equal(insert(b, 0, b[0]), [0., 0., 1.])
+        assert_equal(insert(b, [], []), b)
+        # Bools will be treated differently in the future:
+        # assert_equal(insert(a, np.array([True]*4), 9), [9, 1, 9, 2, 9, 3, 9])
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_equal(
+                insert(a, np.array([True] * 4), 9), [1, 9, 9, 9, 9, 2, 3])
+            assert_(w[0].category is FutureWarning)
+
+    def test_multidim(self):
+        a = [[1, 1, 1]]
+        r = [[2, 2, 2],
+             [1, 1, 1]]
+        assert_equal(insert(a, 0, [1]), [1, 1, 1, 1])
+        assert_equal(insert(a, 0, [2, 2, 2], axis=0), r)
+        assert_equal(insert(a, 0, 2, axis=0), r)
+        assert_equal(insert(a, 2, 2, axis=1), [[1, 1, 2, 1]])
+
+        a = np.array([[1, 1], [2, 2], [3, 3]])
+        b = np.arange(1, 4).repeat(3).reshape(3, 3)
+        c = np.concatenate(
+            (a[:, 0:1], np.arange(1, 4).repeat(3).reshape(3, 3).T,
+             a[:, 1:2]), axis=1)
+        assert_equal(insert(a, [1], [[1], [2], [3]], axis=1), b)
+        assert_equal(insert(a, [1], [1, 2, 3], axis=1), c)
+        # scalars behave differently, in this case exactly opposite:
+        assert_equal(insert(a, 1, [1, 2, 3], axis=1), b)
+        assert_equal(insert(a, 1, [[1], [2], [3]], axis=1), c)
+
+        a = np.arange(4).reshape(2, 2)
+        assert_equal(insert(a[:, :1], 1, a[:, 1], axis=1), a)
+        assert_equal(insert(a[:1,:], 1, a[1,:], axis=0), a)
+
+        # negative axis value
+        a = np.arange(24).reshape((2, 3, 4))
+        assert_equal(insert(a, 1, a[:,:, 3], axis=-1),
+                     insert(a, 1, a[:,:, 3], axis=2))
+        assert_equal(insert(a, 1, a[:, 2,:], axis=-2),
+                     insert(a, 1, a[:, 2,:], axis=1))
+
+        # invalid axis value
+        assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=3)
+        assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=-4)
+
+        # negative axis value
+        a = np.arange(24).reshape((2, 3, 4))
+        assert_equal(insert(a, 1, a[:, :, 3], axis=-1),
+                     insert(a, 1, a[:, :, 3], axis=2))
+        assert_equal(insert(a, 1, a[:, 2, :], axis=-2),
+                     insert(a, 1, a[:, 2, :], axis=1))
+
+    def test_0d(self):
+        # This is an error in the future
+        a = np.array(1)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', DeprecationWarning)
+            assert_equal(insert(a, [], 2, axis=0), np.array(2))
+            assert_(w[0].category is DeprecationWarning)
+
+    def test_subclass(self):
+        class SubClass(np.ndarray):
+            pass
+        a = np.arange(10).view(SubClass)
+        assert_(isinstance(np.insert(a, 0, [0]), SubClass))
+        assert_(isinstance(np.insert(a, [], []), SubClass))
+        assert_(isinstance(np.insert(a, [0, 1], [1, 2]), SubClass))
+        assert_(isinstance(np.insert(a, slice(1, 2), [1, 2]), SubClass))
+        assert_(isinstance(np.insert(a, slice(1, -2, -1), []), SubClass))
+        # This is an error in the future:
+        a = np.array(1).view(SubClass)
+        assert_(isinstance(np.insert(a, 0, [0]), SubClass))
+
+    def test_index_array_copied(self):
+        x = np.array([1, 1, 1])
+        np.insert([0, 1, 2], x, [3, 4, 5])
+        assert_equal(x, np.array([1, 1, 1]))
+
+    def test_structured_array(self):
+        a = np.array([(1, 'a'), (2, 'b'), (3, 'c')],
+                     dtype=[('foo', 'i'), ('bar', 'a1')])
+        val = (4, 'd')
+        b = np.insert(a, 0, val)
+        assert_array_equal(b[0], np.array(val, dtype=b.dtype))
+        val = [(4, 'd')] * 2
+        b = np.insert(a, [0, 2], val)
+        assert_array_equal(b[[0, 3]], np.array(val, dtype=b.dtype))
+
+
+class TestAmax(TestCase):
+
+    def test_basic(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.amax(a), 10.0)
+        b = [[3, 6.0, 9.0],
+             [4, 10.0, 5.0],
+             [8, 3.0, 2.0]]
+        assert_equal(np.amax(b, axis=0), [8.0, 10.0, 9.0])
+        assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
+
+
+class TestAmin(TestCase):
+
+    def test_basic(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.amin(a), -5.0)
+        b = [[3, 6.0, 9.0],
+             [4, 10.0, 5.0],
+             [8, 3.0, 2.0]]
+        assert_equal(np.amin(b, axis=0), [3.0, 3.0, 2.0])
+        assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
+
+
+class TestPtp(TestCase):
+
+    def test_basic(self):
+        a = np.array([3, 4, 5, 10, -3, -5, 6.0])
+        assert_equal(a.ptp(axis=0), 15.0)
+        b = np.array([[3, 6.0, 9.0],
+                      [4, 10.0, 5.0],
+                      [8, 3.0, 2.0]])
+        assert_equal(b.ptp(axis=0), [5.0, 7.0, 7.0])
+        assert_equal(b.ptp(axis=-1), [6.0, 6.0, 6.0])
+
+
+class TestCumsum(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int8, np.uint8, np.int16, np.uint16, np.int32,
+                      np.uint32, np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+
+            tgt = np.array([1, 3, 13, 24, 30, 35, 39], ctype)
+            assert_array_equal(np.cumsum(a, axis=0), tgt)
+
+            tgt = np.array(
+                [[1, 2, 3, 4], [6, 8, 10, 13], [16, 11, 14, 18]], ctype)
+            assert_array_equal(np.cumsum(a2, axis=0), tgt)
+
+            tgt = np.array(
+                [[1, 3, 6, 10], [5, 11, 18, 27], [10, 13, 17, 22]], ctype)
+            assert_array_equal(np.cumsum(a2, axis=1), tgt)
+
+
+class TestProd(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, np.prod, a)
+                self.assertRaises(ArithmeticError, np.prod, a2, 1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+
+class TestCumprod(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, np.cumprod, a)
+                self.assertRaises(ArithmeticError, np.cumprod, a2, 1)
+                self.assertRaises(ArithmeticError, np.cumprod, a)
+            else:
+                assert_array_equal(np.cumprod(a, axis=-1),
+                                   np.array([1, 2, 20, 220,
+                                             1320, 6600, 26400], ctype))
+                assert_array_equal(np.cumprod(a2, axis=0),
+                                   np.array([[1, 2, 3, 4],
+                                             [5, 12, 21, 36],
+                                             [50, 36, 84, 180]], ctype))
+                assert_array_equal(np.cumprod(a2, axis=-1),
+                                   np.array([[1, 2, 6, 24],
+                                             [5, 30, 210, 1890],
+                                             [10, 30, 120, 600]], ctype))
+
+
+class TestDiff(TestCase):
+
+    def test_basic(self):
+        x = [1, 4, 6, 7, 12]
+        out = np.array([3, 2, 1, 5])
+        out2 = np.array([-1, -1, 4])
+        out3 = np.array([0, 5])
+        assert_array_equal(diff(x), out)
+        assert_array_equal(diff(x, n=2), out2)
+        assert_array_equal(diff(x, n=3), out3)
+
+    def test_nd(self):
+        x = 20 * rand(10, 20, 30)
+        out1 = x[:, :, 1:] - x[:, :, :-1]
+        out2 = out1[:, :, 1:] - out1[:, :, :-1]
+        out3 = x[1:, :, :] - x[:-1, :, :]
+        out4 = out3[1:, :, :] - out3[:-1, :, :]
+        assert_array_equal(diff(x), out1)
+        assert_array_equal(diff(x, n=2), out2)
+        assert_array_equal(diff(x, axis=0), out3)
+        assert_array_equal(diff(x, n=2, axis=0), out4)
+
+
+class TestDelete(TestCase):
+
+    def setUp(self):
+        self.a = np.arange(5)
+        self.nd_a = np.arange(5).repeat(2).reshape(1, 5, 2)
+
+    def _check_inverse_of_slicing(self, indices):
+        a_del = delete(self.a, indices)
+        nd_a_del = delete(self.nd_a, indices, axis=1)
+        msg = 'Delete failed for obj: %r' % indices
+        # NOTE: The cast should be removed after warning phase for bools
+        if not isinstance(indices, (slice, int, long, np.integer)):
+            indices = np.asarray(indices, dtype=np.intp)
+            indices = indices[(indices >= 0) & (indices < 5)]
+        assert_array_equal(setxor1d(a_del, self.a[indices, ]), self.a,
+                           err_msg=msg)
+        xor = setxor1d(nd_a_del[0,:, 0], self.nd_a[0, indices, 0])
+        assert_array_equal(xor, self.nd_a[0,:, 0], err_msg=msg)
+
+    def test_slices(self):
+        lims = [-6, -2, 0, 1, 2, 4, 5]
+        steps = [-3, -1, 1, 3]
+        for start in lims:
+            for stop in lims:
+                for step in steps:
+                    s = slice(start, stop, step)
+                    self._check_inverse_of_slicing(s)
+
+    def test_fancy(self):
+        # Deprecation/FutureWarning tests should be kept after change.
+        self._check_inverse_of_slicing(np.array([[0, 1], [2, 1]]))
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', category=DeprecationWarning)
+            assert_raises(DeprecationWarning, delete, self.a, [100])
+            assert_raises(DeprecationWarning, delete, self.a, [-100])
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', category=FutureWarning)
+            self._check_inverse_of_slicing([0, -1, 2, 2])
+            obj = np.array([True, False, False], dtype=bool)
+            self._check_inverse_of_slicing(obj)
+            assert_(w[0].category is FutureWarning)
+            assert_(w[1].category is FutureWarning)
+
+    def test_single(self):
+        self._check_inverse_of_slicing(0)
+        self._check_inverse_of_slicing(-4)
+
+    def test_0d(self):
+        a = np.array(1)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', DeprecationWarning)
+            assert_equal(delete(a, [], axis=0), a)
+            assert_(w[0].category is DeprecationWarning)
+
+    def test_subclass(self):
+        class SubClass(np.ndarray):
+            pass
+        a = self.a.view(SubClass)
+        assert_(isinstance(delete(a, 0), SubClass))
+        assert_(isinstance(delete(a, []), SubClass))
+        assert_(isinstance(delete(a, [0, 1]), SubClass))
+        assert_(isinstance(delete(a, slice(1, 2)), SubClass))
+        assert_(isinstance(delete(a, slice(1, -2)), SubClass))
+
+
+class TestGradient(TestCase):
+
+    def test_basic(self):
+        v = [[1, 1], [3, 4]]
+        x = np.array(v)
+        dx = [np.array([[2., 3.], [2., 3.]]),
+              np.array([[0., 0.], [1., 1.]])]
+        assert_array_equal(gradient(x), dx)
+        assert_array_equal(gradient(v), dx)
+
+    def test_badargs(self):
+        # for 2D array, gradient can take 0, 1, or 2 extra args
+        x = np.array([[1, 1], [3, 4]])
+        assert_raises(SyntaxError, gradient, x, np.array([1., 1.]),
+                      np.array([1., 1.]), np.array([1., 1.]))
+
+    def test_masked(self):
+        # Make sure that gradient supports subclasses like masked arrays
+        x = np.ma.array([[1, 1], [3, 4]],
+                        mask=[[False, False], [False, False]])
+        out = gradient(x)[0]
+        assert_equal(type(out), type(x))
+        # And make sure that the output and input don't have aliased mask
+        # arrays
+        assert_(x.mask is not out.mask)
+        # Also check that edge_order=2 doesn't alter the original mask
+        x2 = np.ma.arange(5)
+        x2[2] = np.ma.masked
+        np.gradient(x2, edge_order=2)
+        assert_array_equal(x2.mask, [False, False, True, False, False])
+
+    def test_datetime64(self):
+        # Make sure gradient() can handle special types like datetime64
+        x = np.array(
+            ['1910-08-16', '1910-08-11', '1910-08-10', '1910-08-12',
+             '1910-10-12', '1910-12-12', '1912-12-12'],
+            dtype='datetime64[D]')
+        dx = np.array(
+            [-5, -3, 0, 31, 61, 396, 731],
+            dtype='timedelta64[D]')
+        assert_array_equal(gradient(x), dx)
+        assert_(dx.dtype == np.dtype('timedelta64[D]'))
+
+    def test_timedelta64(self):
+        # Make sure gradient() can handle special types like timedelta64
+        x = np.array(
+            [-5, -3, 10, 12, 61, 321, 300],
+            dtype='timedelta64[D]')
+        dx = np.array(
+            [2, 7, 7, 25, 154, 119, -21],
+            dtype='timedelta64[D]')
+        assert_array_equal(gradient(x), dx)
+        assert_(dx.dtype == np.dtype('timedelta64[D]'))
+
+    def test_second_order_accurate(self):
+        # Testing that the relative numerical error is less that 3% for
+        # this example problem. This corresponds to second order
+        # accurate finite differences for all interior and boundary
+        # points.
+        x = np.linspace(0, 1, 10)
+        dx = x[1] - x[0]
+        y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
+        analytical = 6 * x ** 2 + 8 * x + 2
+        num_error = np.abs((np.gradient(y, dx, edge_order=2) / analytical) - 1)
+        assert_(np.all(num_error < 0.03) == True)
+
+    def test_specific_axes(self):
+        # Testing that gradient can work on a given axis only
+        v = [[1, 1], [3, 4]]
+        x = np.array(v)
+        dx = [np.array([[2., 3.], [2., 3.]]),
+              np.array([[0., 0.], [1., 1.]])]
+        assert_array_equal(gradient(x, axis=0), dx[0])
+        assert_array_equal(gradient(x, axis=1), dx[1])
+        assert_array_equal(gradient(x, axis=-1), dx[1])
+        assert_array_equal(gradient(x, axis=(1, 0)), [dx[1], dx[0]])
+
+        # test axis=None which means all axes
+        assert_almost_equal(gradient(x, axis=None), [dx[0], dx[1]])
+        # and is the same as no axis keyword given
+        assert_almost_equal(gradient(x, axis=None), gradient(x))
+
+        # test vararg order
+        assert_array_equal(gradient(x, 2, 3, axis=(1, 0)), [dx[1]/2.0, dx[0]/3.0])
+        # test maximal number of varargs
+        assert_raises(SyntaxError, gradient, x, 1, 2, axis=1)
+
+        assert_raises(ValueError, gradient, x, axis=3)
+        assert_raises(ValueError, gradient, x, axis=-3)
+        assert_raises(TypeError, gradient, x, axis=[1,])
+
+
+class TestAngle(TestCase):
+
+    def test_basic(self):
+        x = [1 + 3j, np.sqrt(2) / 2.0 + 1j * np.sqrt(2) / 2,
+             1, 1j, -1, -1j, 1 - 3j, -1 + 3j]
+        y = angle(x)
+        yo = [
+            np.arctan(3.0 / 1.0),
+            np.arctan(1.0), 0, np.pi / 2, np.pi, -np.pi / 2.0,
+            -np.arctan(3.0 / 1.0), np.pi - np.arctan(3.0 / 1.0)]
+        z = angle(x, deg=1)
+        zo = np.array(yo) * 180 / np.pi
+        assert_array_almost_equal(y, yo, 11)
+        assert_array_almost_equal(z, zo, 11)
+
+
+class TestTrimZeros(TestCase):
+
+    """
+    Only testing for integer splits.
+
+    """
+
+    def test_basic(self):
+        a = np.array([0, 0, 1, 2, 3, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 2, 3, 4]))
+
+    def test_leading_skip(self):
+        a = np.array([0, 0, 1, 0, 2, 3, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 0, 2, 3, 4]))
+
+    def test_trailing_skip(self):
+        a = np.array([0, 0, 1, 0, 2, 3, 0, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 0, 2, 3, 0, 4]))
+
+
+class TestExtins(TestCase):
+
+    def test_basic(self):
+        a = np.array([1, 3, 2, 1, 2, 3, 3])
+        b = extract(a > 1, a)
+        assert_array_equal(b, [3, 2, 2, 3, 3])
+
+    def test_place(self):
+        # Make sure that non-np.ndarray objects
+        # raise an error instead of doing nothing
+        assert_raises(TypeError, place, [1, 2, 3], [True, False], [0, 1])
+
+        a = np.array([1, 4, 3, 2, 5, 8, 7])
+        place(a, [0, 1, 0, 1, 0, 1, 0], [2, 4, 6])
+        assert_array_equal(a, [1, 2, 3, 4, 5, 6, 7])
+
+        place(a, np.zeros(7), [])
+        assert_array_equal(a, np.arange(1, 8))
+
+        place(a, [1, 0, 1, 0, 1, 0, 1], [8, 9])
+        assert_array_equal(a, [8, 2, 9, 4, 8, 6, 9])
+        assert_raises_regex(ValueError, "Cannot insert from an empty array",
+                            lambda: place(a, [0, 0, 0, 0, 0, 1, 0], []))
+
+    def test_both(self):
+        a = rand(10)
+        mask = a > 0.5
+        ac = a.copy()
+        c = extract(mask, a)
+        place(a, mask, 0)
+        place(a, mask, c)
+        assert_array_equal(a, ac)
+
+
+class TestVectorize(TestCase):
+
+    def test_simple(self):
+        def addsubtract(a, b):
+            if a > b:
+                return a - b
+            else:
+                return a + b
+
+        f = vectorize(addsubtract)
+        r = f([0, 3, 6, 9], [1, 3, 5, 7])
+        assert_array_equal(r, [1, 6, 1, 2])
+
+    def test_scalar(self):
+        def addsubtract(a, b):
+            if a > b:
+                return a - b
+            else:
+                return a + b
+
+        f = vectorize(addsubtract)
+        r = f([0, 3, 6, 9], 5)
+        assert_array_equal(r, [5, 8, 1, 4])
+
+    def test_large(self):
+        x = np.linspace(-3, 2, 10000)
+        f = vectorize(lambda x: x)
+        y = f(x)
+        assert_array_equal(y, x)
+
+    def test_ufunc(self):
+        import math
+        f = vectorize(math.cos)
+        args = np.array([0, 0.5 * np.pi, np.pi, 1.5 * np.pi, 2 * np.pi])
+        r1 = f(args)
+        r2 = np.cos(args)
+        assert_array_almost_equal(r1, r2)
+
+    def test_keywords(self):
+
+        def foo(a, b=1):
+            return a + b
+
+        f = vectorize(foo)
+        args = np.array([1, 2, 3])
+        r1 = f(args)
+        r2 = np.array([2, 3, 4])
+        assert_array_equal(r1, r2)
+        r1 = f(args, 2)
+        r2 = np.array([3, 4, 5])
+        assert_array_equal(r1, r2)
+
+    def test_keywords_no_func_code(self):
+        # This needs to test a function that has keywords but
+        # no func_code attribute, since otherwise vectorize will
+        # inspect the func_code.
+        import random
+        try:
+            vectorize(random.randrange)  # Should succeed
+        except:
+            raise AssertionError()
+
+    def test_keywords2_ticket_2100(self):
+        # Test kwarg support: enhancement ticket 2100
+
+        def foo(a, b=1):
+            return a + b
+
+        f = vectorize(foo)
+        args = np.array([1, 2, 3])
+        r1 = f(a=args)
+        r2 = np.array([2, 3, 4])
+        assert_array_equal(r1, r2)
+        r1 = f(b=1, a=args)
+        assert_array_equal(r1, r2)
+        r1 = f(args, b=2)
+        r2 = np.array([3, 4, 5])
+        assert_array_equal(r1, r2)
+
+    def test_keywords3_ticket_2100(self):
+        # Test excluded with mixed positional and kwargs: ticket 2100
+        def mypolyval(x, p):
+            _p = list(p)
+            res = _p.pop(0)
+            while _p:
+                res = res * x + _p.pop(0)
+            return res
+
+        vpolyval = np.vectorize(mypolyval, excluded=['p', 1])
+        ans = [3, 6]
+        assert_array_equal(ans, vpolyval(x=[0, 1], p=[1, 2, 3]))
+        assert_array_equal(ans, vpolyval([0, 1], p=[1, 2, 3]))
+        assert_array_equal(ans, vpolyval([0, 1], [1, 2, 3]))
+
+    def test_keywords4_ticket_2100(self):
+        # Test vectorizing function with no positional args.
+        @vectorize
+        def f(**kw):
+            res = 1.0
+            for _k in kw:
+                res *= kw[_k]
+            return res
+
+        assert_array_equal(f(a=[1, 2], b=[3, 4]), [3, 8])
+
+    def test_keywords5_ticket_2100(self):
+        # Test vectorizing function with no kwargs args.
+        @vectorize
+        def f(*v):
+            return np.prod(v)
+
+        assert_array_equal(f([1, 2], [3, 4]), [3, 8])
+
+    def test_coverage1_ticket_2100(self):
+        def foo():
+            return 1
+
+        f = vectorize(foo)
+        assert_array_equal(f(), 1)
+
+    def test_assigning_docstring(self):
+        def foo(x):
+            return x
+
+        doc = "Provided documentation"
+        f = vectorize(foo, doc=doc)
+        assert_equal(f.__doc__, doc)
+
+    def test_UnboundMethod_ticket_1156(self):
+        # Regression test for issue 1156
+        class Foo:
+            b = 2
+
+            def bar(self, a):
+                return a ** self.b
+
+        assert_array_equal(vectorize(Foo().bar)(np.arange(9)),
+                           np.arange(9) ** 2)
+        assert_array_equal(vectorize(Foo.bar)(Foo(), np.arange(9)),
+                           np.arange(9) ** 2)
+
+    def test_execution_order_ticket_1487(self):
+        # Regression test for dependence on execution order: issue 1487
+        f1 = vectorize(lambda x: x)
+        res1a = f1(np.arange(3))
+        res1b = f1(np.arange(0.1, 3))
+        f2 = vectorize(lambda x: x)
+        res2b = f2(np.arange(0.1, 3))
+        res2a = f2(np.arange(3))
+        assert_equal(res1a, res2a)
+        assert_equal(res1b, res2b)
+
+    def test_string_ticket_1892(self):
+        # Test vectorization over strings: issue 1892.
+        f = np.vectorize(lambda x: x)
+        s = '0123456789' * 10
+        assert_equal(s, f(s))
+
+    def test_cache(self):
+        # Ensure that vectorized func called exactly once per argument.
+        _calls = [0]
+
+        @vectorize
+        def f(x):
+            _calls[0] += 1
+            return x ** 2
+
+        f.cache = True
+        x = np.arange(5)
+        assert_array_equal(f(x), x * x)
+        assert_equal(_calls[0], len(x))
+
+    def test_otypes(self):
+        f = np.vectorize(lambda x: x)
+        f.otypes = 'i'
+        x = np.arange(5)
+        assert_array_equal(f(x), x)
+
+
+class TestDigitize(TestCase):
+
+    def test_forward(self):
+        x = np.arange(-6, 5)
+        bins = np.arange(-5, 5)
+        assert_array_equal(digitize(x, bins), np.arange(11))
+
+    def test_reverse(self):
+        x = np.arange(5, -6, -1)
+        bins = np.arange(5, -5, -1)
+        assert_array_equal(digitize(x, bins), np.arange(11))
+
+    def test_random(self):
+        x = rand(10)
+        bin = np.linspace(x.min(), x.max(), 10)
+        assert_(np.all(digitize(x, bin) != 0))
+
+    def test_right_basic(self):
+        x = [1, 5, 4, 10, 8, 11, 0]
+        bins = [1, 5, 10]
+        default_answer = [1, 2, 1, 3, 2, 3, 0]
+        assert_array_equal(digitize(x, bins), default_answer)
+        right_answer = [0, 1, 1, 2, 2, 3, 0]
+        assert_array_equal(digitize(x, bins, True), right_answer)
+
+    def test_right_open(self):
+        x = np.arange(-6, 5)
+        bins = np.arange(-6, 4)
+        assert_array_equal(digitize(x, bins, True), np.arange(11))
+
+    def test_right_open_reverse(self):
+        x = np.arange(5, -6, -1)
+        bins = np.arange(4, -6, -1)
+        assert_array_equal(digitize(x, bins, True), np.arange(11))
+
+    def test_right_open_random(self):
+        x = rand(10)
+        bins = np.linspace(x.min(), x.max(), 10)
+        assert_(np.all(digitize(x, bins, True) != 10))
+
+    def test_monotonic(self):
+        x = [-1, 0, 1, 2]
+        bins = [0, 0, 1]
+        assert_array_equal(digitize(x, bins, False), [0, 2, 3, 3])
+        assert_array_equal(digitize(x, bins, True), [0, 0, 2, 3])
+        bins = [1, 1, 0]
+        assert_array_equal(digitize(x, bins, False), [3, 2, 0, 0])
+        assert_array_equal(digitize(x, bins, True), [3, 3, 2, 0])
+        bins = [1, 1, 1, 1]
+        assert_array_equal(digitize(x, bins, False), [0, 0, 4, 4])
+        assert_array_equal(digitize(x, bins, True), [0, 0, 0, 4])
+        bins = [0, 0, 1, 0]
+        assert_raises(ValueError, digitize, x, bins)
+        bins = [1, 1, 0, 1]
+        assert_raises(ValueError, digitize, x, bins)
+
+    def test_casting_error(self):
+        x = [1, 2, 3 + 1.j]
+        bins = [1, 2, 3]
+        assert_raises(TypeError, digitize, x, bins)
+        x, bins = bins, x
+        assert_raises(TypeError, digitize, x, bins)
+
+    def test_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        assert_(not isinstance(digitize(b, a, False), A))
+        assert_(not isinstance(digitize(b, a, True), A))
+
+
+class TestUnwrap(TestCase):
+
+    def test_simple(self):
+        # check that unwrap removes jumps greather that 2*pi
+        assert_array_equal(unwrap([1, 1 + 2 * np.pi]), [1, 1])
+        # check that unwrap maintans continuity
+        assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi))
+
+
+class TestFilterwindows(TestCase):
+
+    def test_hanning(self):
+        # check symmetry
+        w = hanning(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.500, 4)
+
+    def test_hamming(self):
+        # check symmetry
+        w = hamming(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.9400, 4)
+
+    def test_bartlett(self):
+        # check symmetry
+        w = bartlett(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.4444, 4)
+
+    def test_blackman(self):
+        # check symmetry
+        w = blackman(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 3.7800, 4)
+
+
+class TestTrapz(TestCase):
+
+    def test_simple(self):
+        x = np.arange(-10, 10, .1)
+        r = trapz(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1)
+        # check integral of normal equals 1
+        assert_almost_equal(r, 1, 7)
+
+    def test_ndim(self):
+        x = np.linspace(0, 1, 3)
+        y = np.linspace(0, 2, 8)
+        z = np.linspace(0, 3, 13)
+
+        wx = np.ones_like(x) * (x[1] - x[0])
+        wx[0] /= 2
+        wx[-1] /= 2
+        wy = np.ones_like(y) * (y[1] - y[0])
+        wy[0] /= 2
+        wy[-1] /= 2
+        wz = np.ones_like(z) * (z[1] - z[0])
+        wz[0] /= 2
+        wz[-1] /= 2
+
+        q = x[:, None, None] + y[None,:, None] + z[None, None,:]
+
+        qx = (q * wx[:, None, None]).sum(axis=0)
+        qy = (q * wy[None, :, None]).sum(axis=1)
+        qz = (q * wz[None, None, :]).sum(axis=2)
+
+        # n-d `x`
+        r = trapz(q, x=x[:, None, None], axis=0)
+        assert_almost_equal(r, qx)
+        r = trapz(q, x=y[None,:, None], axis=1)
+        assert_almost_equal(r, qy)
+        r = trapz(q, x=z[None, None,:], axis=2)
+        assert_almost_equal(r, qz)
+
+        # 1-d `x`
+        r = trapz(q, x=x, axis=0)
+        assert_almost_equal(r, qx)
+        r = trapz(q, x=y, axis=1)
+        assert_almost_equal(r, qy)
+        r = trapz(q, x=z, axis=2)
+        assert_almost_equal(r, qz)
+
+    def test_masked(self):
+        # Testing that masked arrays behave as if the function is 0 where
+        # masked
+        x = np.arange(5)
+        y = x * x
+        mask = x == 2
+        ym = np.ma.array(y, mask=mask)
+        r = 13.0  # sum(0.5 * (0 + 1) * 1.0 + 0.5 * (9 + 16))
+        assert_almost_equal(trapz(ym, x), r)
+
+        xm = np.ma.array(x, mask=mask)
+        assert_almost_equal(trapz(ym, xm), r)
+
+        xm = np.ma.array(x, mask=mask)
+        assert_almost_equal(trapz(y, xm), r)
+
+    def test_matrix(self):
+        # Test to make sure matrices give the same answer as ndarrays
+        x = np.linspace(0, 5)
+        y = x * x
+        r = trapz(y, x)
+        mx = np.matrix(x)
+        my = np.matrix(y)
+        mr = trapz(my, mx)
+        assert_almost_equal(mr, r)
+
+
+class TestSinc(TestCase):
+
+    def test_simple(self):
+        assert_(sinc(0) == 1)
+        w = sinc(np.linspace(-1, 1, 100))
+        # check symmetry
+        assert_array_almost_equal(w, flipud(w), 7)
+
+    def test_array_like(self):
+        x = [0, 0.5]
+        y1 = sinc(np.array(x))
+        y2 = sinc(list(x))
+        y3 = sinc(tuple(x))
+        assert_array_equal(y1, y2)
+        assert_array_equal(y1, y3)
+
+
+class TestHistogram(TestCase):
+
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def test_simple(self):
+        n = 100
+        v = rand(n)
+        (a, b) = histogram(v)
+        # check if the sum of the bins equals the number of samples
+        assert_equal(np.sum(a, axis=0), n)
+        # check that the bin counts are evenly spaced when the data is from
+        # a linear function
+        (a, b) = histogram(np.linspace(0, 10, 100))
+        assert_array_equal(a, 10)
+
+    def test_one_bin(self):
+        # Ticket 632
+        hist, edges = histogram([1, 2, 3, 4], [1, 2])
+        assert_array_equal(hist, [2, ])
+        assert_array_equal(edges, [1, 2])
+        assert_raises(ValueError, histogram, [1, 2], bins=0)
+        h, e = histogram([1, 2], bins=1)
+        assert_equal(h, np.array([2]))
+        assert_allclose(e, np.array([1., 2.]))
+
+    def test_normed(self):
+        # Check that the integral of the density equals 1.
+        n = 100
+        v = rand(n)
+        a, b = histogram(v, normed=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+        # Check with non-constant bin widths (buggy but backwards
+        # compatible)
+        v = np.arange(10)
+        bins = [0, 1, 5, 9, 10]
+        a, b = histogram(v, bins, normed=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+    def test_density(self):
+        # Check that the integral of the density equals 1.
+        n = 100
+        v = rand(n)
+        a, b = histogram(v, density=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+        # Check with non-constant bin widths
+        v = np.arange(10)
+        bins = [0, 1, 3, 6, 10]
+        a, b = histogram(v, bins, density=True)
+        assert_array_equal(a, .1)
+        assert_equal(np.sum(a * diff(b)), 1)
+
+        # Variale bin widths are especially useful to deal with
+        # infinities.
+        v = np.arange(10)
+        bins = [0, 1, 3, 6, np.inf]
+        a, b = histogram(v, bins, density=True)
+        assert_array_equal(a, [.1, .1, .1, 0.])
+
+        # Taken from a bug report from N. Becker on the numpy-discussion
+        # mailing list Aug. 6, 2010.
+        counts, dmy = np.histogram(
+            [1, 2, 3, 4], [0.5, 1.5, np.inf], density=True)
+        assert_equal(counts, [.25, 0])
+
+    def test_outliers(self):
+        # Check that outliers are not tallied
+        a = np.arange(10) + .5
+
+        # Lower outliers
+        h, b = histogram(a, range=[0, 9])
+        assert_equal(h.sum(), 9)
+
+        # Upper outliers
+        h, b = histogram(a, range=[1, 10])
+        assert_equal(h.sum(), 9)
+
+        # Normalization
+        h, b = histogram(a, range=[1, 9], normed=True)
+        assert_almost_equal((h * diff(b)).sum(), 1, decimal=15)
+
+        # Weights
+        w = np.arange(10) + .5
+        h, b = histogram(a, range=[1, 9], weights=w, normed=True)
+        assert_equal((h * diff(b)).sum(), 1)
+
+        h, b = histogram(a, bins=8, range=[1, 9], weights=w)
+        assert_equal(h, w[1:-1])
+
+    def test_type(self):
+        # Check the type of the returned histogram
+        a = np.arange(10) + .5
+        h, b = histogram(a)
+        assert_(np.issubdtype(h.dtype, int))
+
+        h, b = histogram(a, normed=True)
+        assert_(np.issubdtype(h.dtype, float))
+
+        h, b = histogram(a, weights=np.ones(10, int))
+        assert_(np.issubdtype(h.dtype, int))
+
+        h, b = histogram(a, weights=np.ones(10, float))
+        assert_(np.issubdtype(h.dtype, float))
+
+    def test_f32_rounding(self):
+        # gh-4799, check that the rounding of the edges works with float32
+        x = np.array([276.318359, -69.593948, 21.329449], dtype=np.float32)
+        y = np.array([5005.689453, 4481.327637, 6010.369629], dtype=np.float32)
+        counts_hist, xedges, yedges = np.histogram2d(x, y, bins=100)
+        assert_equal(counts_hist.sum(), 3.)
+
+    def test_weights(self):
+        v = rand(100)
+        w = np.ones(100) * 5
+        a, b = histogram(v)
+        na, nb = histogram(v, normed=True)
+        wa, wb = histogram(v, weights=w)
+        nwa, nwb = histogram(v, weights=w, normed=True)
+        assert_array_almost_equal(a * 5, wa)
+        assert_array_almost_equal(na, nwa)
+
+        # Check weights are properly applied.
+        v = np.linspace(0, 10, 10)
+        w = np.concatenate((np.zeros(5), np.ones(5)))
+        wa, wb = histogram(v, bins=np.arange(11), weights=w)
+        assert_array_almost_equal(wa, w)
+
+        # Check with integer weights
+        wa, wb = histogram([1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1])
+        assert_array_equal(wa, [4, 5, 0, 1])
+        wa, wb = histogram(
+            [1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1], normed=True)
+        assert_array_almost_equal(wa, np.array([4, 5, 0, 1]) / 10. / 3. * 4)
+
+        # Check weights with non-uniform bin widths
+        a, b = histogram(
+            np.arange(9), [0, 1, 3, 6, 10],
+            weights=[2, 1, 1, 1, 1, 1, 1, 1, 1], density=True)
+        assert_almost_equal(a, [.2, .1, .1, .075])
+
+    def test_exotic_weights(self):
+
+        # Test the use of weights that are not integer or floats, but e.g.
+        # complex numbers or object types.
+
+        # Complex weights
+        values = np.array([1.3, 2.5, 2.3])
+        weights = np.array([1, -1, 2]) + 1j * np.array([2, 1, 2])
+
+        # Check with custom bins
+        wa, wb = histogram(values, bins=[0, 2, 3], weights=weights)
+        assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3]))
+
+        # Check with even bins
+        wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights)
+        assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3]))
+
+        # Decimal weights
+        from decimal import Decimal
+        values = np.array([1.3, 2.5, 2.3])
+        weights = np.array([Decimal(1), Decimal(2), Decimal(3)])
+
+        # Check with custom bins
+        wa, wb = histogram(values, bins=[0, 2, 3], weights=weights)
+        assert_array_almost_equal(wa, [Decimal(1), Decimal(5)])
+
+        # Check with even bins
+        wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights)
+        assert_array_almost_equal(wa, [Decimal(1), Decimal(5)])
+
+    def test_no_side_effects(self):
+        # This is a regression test that ensures that values passed to
+        # ``histogram`` are unchanged.
+        values = np.array([1.3, 2.5, 2.3])
+        np.histogram(values, range=[-10, 10], bins=100)
+        assert_array_almost_equal(values, [1.3, 2.5, 2.3])
+
+    def test_empty(self):
+        a, b = histogram([], bins=([0, 1]))
+        assert_array_equal(a, np.array([0]))
+        assert_array_equal(b, np.array([0, 1]))
+
+    def test_finite_range(self):
+        # Normal ranges should be fine
+        vals = np.linspace(0.0, 1.0, num=100)
+        histogram(vals, range=[0.25,0.75])
+        assert_raises(ValueError, histogram, vals, range=[np.nan,0.75])
+        assert_raises(ValueError, histogram, vals, range=[0.25,np.inf])
+        
+
+class TestHistogramOptimBinNums(TestCase):
+    """
+    Provide test coverage when using provided estimators for optimal number of
+    bins
+    """
+
+    def test_empty(self):
+        estimator_list = ['fd', 'scott', 'rice', 'sturges',
+                          'doane', 'sqrt', 'auto']
+        # check it can deal with empty data
+        for estimator in estimator_list:
+            a, b = histogram([], bins=estimator)
+            assert_array_equal(a, np.array([0]))
+            assert_array_equal(b, np.array([0, 1]))
+
+    def test_simple(self):
+        """
+        Straightforward testing with a mixture of linspace data (for
+        consistency). All test values have been precomputed and the values
+        shouldn't change
+        """
+        # Some basic sanity checking, with some fixed data.
+        # Checking for the correct number of bins
+        basic_test = {50:   {'fd': 4,  'scott': 4,  'rice': 8,  'sturges': 7, 
+                             'doane': 8, 'sqrt': 8, 'auto': 7},
+                      500:  {'fd': 8,  'scott': 8,  'rice': 16, 'sturges': 10,
+                             'doane': 12, 'sqrt': 23, 'auto': 10},
+                      5000: {'fd': 17, 'scott': 17, 'rice': 35, 'sturges': 14,
+                             'doane': 17, 'sqrt': 71, 'auto': 17}}
+
+        for testlen, expectedResults in basic_test.items():
+            # Create some sort of non uniform data to test with
+            # (2 peak uniform mixture)
+            x1 = np.linspace(-10, -1, testlen // 5 * 2)
+            x2 = np.linspace(1, 10, testlen // 5 * 3)
+            x = np.concatenate((x1, x2))
+            for estimator, numbins in expectedResults.items():
+                a, b = np.histogram(x, estimator)
+                assert_equal(len(a), numbins, err_msg="For the {0} estimator "
+                             "with datasize of {1}".format(estimator, testlen))
+
+    def test_small(self):
+        """
+        Smaller datasets have the potential to cause issues with the data
+        adaptive methods, especially the FD method. All bin numbers have been
+        precalculated.
+        """
+        small_dat = {1: {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1,
+                         'doane': 1, 'sqrt': 1},
+                     2: {'fd': 2, 'scott': 1, 'rice': 3, 'sturges': 2,
+                         'doane': 1, 'sqrt': 2},
+                     3: {'fd': 2, 'scott': 2, 'rice': 3, 'sturges': 3,
+                         'doane': 3, 'sqrt': 2}}
+
+        for testlen, expectedResults in small_dat.items():
+            testdat = np.arange(testlen)
+            for estimator, expbins in expectedResults.items():
+                a, b = np.histogram(testdat, estimator)
+                assert_equal(len(a), expbins, err_msg="For the {0} estimator "
+                             "with datasize of {1}".format(estimator, testlen))
+
+    def test_incorrect_methods(self):
+        """
+        Check a Value Error is thrown when an unknown string is passed in
+        """
+        check_list = ['mad', 'freeman', 'histograms', 'IQR']
+        for estimator in check_list:
+            assert_raises(ValueError, histogram, [1, 2, 3], estimator)
+
+    def test_novariance(self):
+        """
+        Check that methods handle no variance in data
+        Primarily for Scott and FD as the SD and IQR are both 0 in this case
+        """
+        novar_dataset = np.ones(100)
+        novar_resultdict = {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1,
+                            'doane': 1, 'sqrt': 1, 'auto': 1}
+
+        for estimator, numbins in novar_resultdict.items():
+            a, b = np.histogram(novar_dataset, estimator)
+            assert_equal(len(a), numbins, err_msg="{0} estimator, "
+                         "No Variance test".format(estimator))
+
+    def test_outlier(self):
+        """
+        Check the FD, Scott and Doane with outliers.
+
+        The FD estimates a smaller binwidth since it's less affected by
+        outliers. Since the range is so (artificially) large, this means more
+        bins, most of which will be empty, but the data of interest usually is
+        unaffected. The Scott estimator is more affected and returns fewer bins,
+        despite most of the variance being in one area of the data. The Doane
+        estimator lies somewhere between the other two.
+        """
+        xcenter = np.linspace(-10, 10, 50)
+        outlier_dataset = np.hstack((np.linspace(-110, -100, 5), xcenter))
+
+        outlier_resultdict = {'fd': 21, 'scott': 5, 'doane': 11}
+
+        for estimator, numbins in outlier_resultdict.items():
+            a, b = np.histogram(outlier_dataset, estimator)
+            assert_equal(len(a), numbins)
+
+    def test_simple_range(self):
+        """
+        Straightforward testing with a mixture of linspace data (for
+        consistency). Adding in a 3rd mixture that will then be
+        completely ignored. All test values have been precomputed and
+        the shouldn't change.
+        """
+        # some basic sanity checking, with some fixed data. Checking for the correct number of bins
+        basic_test = {50:   {'fd': 8,  'scott': 8,  'rice': 15, 'sturges': 14, 'auto': 14},
+                      500:  {'fd': 15, 'scott': 16, 'rice': 32, 'sturges': 20, 'auto': 20},
+                      5000: {'fd': 33, 'scott': 33, 'rice': 69, 'sturges': 27, 'auto': 33}}
+
+        for testlen, expectedResults in basic_test.items():
+            # create some sort of non uniform data to test with (3 peak uniform mixture)
+            x1 = np.linspace(-10, -1, testlen // 5 * 2)
+            x2 = np.linspace(1, 10, testlen // 5 * 3)
+            x3 = np.linspace(-100, -50, testlen)
+            x = np.hstack((x1, x2, x3))
+            for estimator, numbins in expectedResults.items():
+                a, b = np.histogram(x, estimator, range = (-20, 20))
+                msg = "For the {0} estimator with datasize of {1}".format(estimator, testlen)
+                assert_equal(len(a), numbins, err_msg=msg)
+
+    def test_simple_weighted(self):
+        """
+        Check that weighted data raises a TypeError
+        """
+        estimator_list = ['fd', 'scott', 'rice', 'sturges', 'auto']
+        for estimator in estimator_list:
+            assert_raises(TypeError, histogram, [1, 2, 3], estimator, weights=[1, 2, 3])
+
+
+class TestHistogramdd(TestCase):
+
+    def test_simple(self):
+        x = np.array([[-.5, .5, 1.5], [-.5, 1.5, 2.5], [-.5, 2.5, .5],
+                      [.5,  .5, 1.5], [.5,  1.5, 2.5], [.5,  2.5, 2.5]])
+        H, edges = histogramdd(x, (2, 3, 3),
+                               range=[[-1, 1], [0, 3], [0, 3]])
+        answer = np.array([[[0, 1, 0], [0, 0, 1], [1, 0, 0]],
+                           [[0, 1, 0], [0, 0, 1], [0, 0, 1]]])
+        assert_array_equal(H, answer)
+
+        # Check normalization
+        ed = [[-2, 0, 2], [0, 1, 2, 3], [0, 1, 2, 3]]
+        H, edges = histogramdd(x, bins=ed, normed=True)
+        assert_(np.all(H == answer / 12.))
+
+        # Check that H has the correct shape.
+        H, edges = histogramdd(x, (2, 3, 4),
+                               range=[[-1, 1], [0, 3], [0, 4]],
+                               normed=True)
+        answer = np.array([[[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]],
+                           [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0]]])
+        assert_array_almost_equal(H, answer / 6., 4)
+        # Check that a sequence of arrays is accepted and H has the correct
+        # shape.
+        z = [np.squeeze(y) for y in split(x, 3, axis=1)]
+        H, edges = histogramdd(
+            z, bins=(4, 3, 2), range=[[-2, 2], [0, 3], [0, 2]])
+        answer = np.array([[[0, 0], [0, 0], [0, 0]],
+                           [[0, 1], [0, 0], [1, 0]],
+                           [[0, 1], [0, 0], [0, 0]],
+                           [[0, 0], [0, 0], [0, 0]]])
+        assert_array_equal(H, answer)
+
+        Z = np.zeros((5, 5, 5))
+        Z[list(range(5)), list(range(5)), list(range(5))] = 1.
+        H, edges = histogramdd([np.arange(5), np.arange(5), np.arange(5)], 5)
+        assert_array_equal(H, Z)
+
+    def test_shape_3d(self):
+        # All possible permutations for bins of different lengths in 3D.
+        bins = ((5, 4, 6), (6, 4, 5), (5, 6, 4), (4, 6, 5), (6, 5, 4),
+                (4, 5, 6))
+        r = rand(10, 3)
+        for b in bins:
+            H, edges = histogramdd(r, b)
+            assert_(H.shape == b)
+
+    def test_shape_4d(self):
+        # All possible permutations for bins of different lengths in 4D.
+        bins = ((7, 4, 5, 6), (4, 5, 7, 6), (5, 6, 4, 7), (7, 6, 5, 4),
+                (5, 7, 6, 4), (4, 6, 7, 5), (6, 5, 7, 4), (7, 5, 4, 6),
+                (7, 4, 6, 5), (6, 4, 7, 5), (6, 7, 5, 4), (4, 6, 5, 7),
+                (4, 7, 5, 6), (5, 4, 6, 7), (5, 7, 4, 6), (6, 7, 4, 5),
+                (6, 5, 4, 7), (4, 7, 6, 5), (4, 5, 6, 7), (7, 6, 4, 5),
+                (5, 4, 7, 6), (5, 6, 7, 4), (6, 4, 5, 7), (7, 5, 6, 4))
+
+        r = rand(10, 4)
+        for b in bins:
+            H, edges = histogramdd(r, b)
+            assert_(H.shape == b)
+
+    def test_weights(self):
+        v = rand(100, 2)
+        hist, edges = histogramdd(v)
+        n_hist, edges = histogramdd(v, normed=True)
+        w_hist, edges = histogramdd(v, weights=np.ones(100))
+        assert_array_equal(w_hist, hist)
+        w_hist, edges = histogramdd(v, weights=np.ones(100) * 2, normed=True)
+        assert_array_equal(w_hist, n_hist)
+        w_hist, edges = histogramdd(v, weights=np.ones(100, int) * 2)
+        assert_array_equal(w_hist, 2 * hist)
+
+    def test_identical_samples(self):
+        x = np.zeros((10, 2), int)
+        hist, edges = histogramdd(x, bins=2)
+        assert_array_equal(edges[0], np.array([-0.5, 0., 0.5]))
+
+    def test_empty(self):
+        a, b = histogramdd([[], []], bins=([0, 1], [0, 1]))
+        assert_array_max_ulp(a, np.array([[0.]]))
+        a, b = np.histogramdd([[], [], []], bins=2)
+        assert_array_max_ulp(a, np.zeros((2, 2, 2)))
+
+    def test_bins_errors(self):
+        # There are two ways to specify bins. Check for the right errors
+        # when mixing those.
+        x = np.arange(8).reshape(2, 4)
+        assert_raises(ValueError, np.histogramdd, x, bins=[-1, 2, 4, 5])
+        assert_raises(ValueError, np.histogramdd, x, bins=[1, 0.99, 1, 1])
+        assert_raises(
+            ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 2, 3]])
+        assert_raises(
+            ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 3, -3]])
+        assert_(np.histogramdd(x, bins=[1, 1, 1, [1, 2, 3, 4]]))
+
+    def test_inf_edges(self):
+        # Test using +/-inf bin edges works. See #1788.
+        with np.errstate(invalid='ignore'):
+            x = np.arange(6).reshape(3, 2)
+            expected = np.array([[1, 0], [0, 1], [0, 1]])
+            h, e = np.histogramdd(x, bins=[3, [-np.inf, 2, 10]])
+            assert_allclose(h, expected)
+            h, e = np.histogramdd(x, bins=[3, np.array([-1, 2, np.inf])])
+            assert_allclose(h, expected)
+            h, e = np.histogramdd(x, bins=[3, [-np.inf, 3, np.inf]])
+            assert_allclose(h, expected)
+
+    def test_rightmost_binedge(self):
+        # Test event very close to rightmost binedge. See Github issue #4266
+        x = [0.9999999995]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0000000001]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0001]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 0.0)
+
+    def test_finite_range(self):
+        vals = np.random.random((100, 3))
+        histogramdd(vals, range=[[0.0, 1.0], [0.25, 0.75], [0.25, 0.5]])
+        assert_raises(ValueError, histogramdd, vals, 
+                      range=[[0.0, 1.0], [0.25, 0.75], [0.25, np.inf]])
+        assert_raises(ValueError, histogramdd, vals, 
+                      range=[[0.0, 1.0], [np.nan, 0.75], [0.25, 0.5]])
+
+
+class TestUnique(TestCase):
+
+    def test_simple(self):
+        x = np.array([4, 3, 2, 1, 1, 2, 3, 4, 0])
+        assert_(np.all(unique(x) == [0, 1, 2, 3, 4]))
+        assert_(unique(np.array([1, 1, 1, 1, 1])) == np.array([1]))
+        x = ['widget', 'ham', 'foo', 'bar', 'foo', 'ham']
+        assert_(np.all(unique(x) == ['bar', 'foo', 'ham', 'widget']))
+        x = np.array([5 + 6j, 1 + 1j, 1 + 10j, 10, 5 + 6j])
+        assert_(np.all(unique(x) == [1 + 1j, 1 + 10j, 5 + 6j, 10]))
+
+
+class TestCheckFinite(TestCase):
+
+    def test_simple(self):
+        a = [1, 2, 3]
+        b = [1, 2, np.inf]
+        c = [1, 2, np.nan]
+        np.lib.asarray_chkfinite(a)
+        assert_raises(ValueError, np.lib.asarray_chkfinite, b)
+        assert_raises(ValueError, np.lib.asarray_chkfinite, c)
+
+    def test_dtype_order(self):
+        # Regression test for missing dtype and order arguments
+        a = [1, 2, 3]
+        a = np.lib.asarray_chkfinite(a, order='F', dtype=np.float64)
+        assert_(a.dtype == np.float64)
+
+
+class catch_warn_nfb(clear_and_catch_warnings):
+
+    """
+    Context manager to catch, reset warnings in function_base module
+
+    """
+    class_modules = (nfb,)
+
+
+class TestCorrCoef(TestCase):
+    A = np.array(
+        [[0.15391142, 0.18045767, 0.14197213],
+         [0.70461506, 0.96474128, 0.27906989],
+         [0.9297531, 0.32296769, 0.19267156]])
+    B = np.array(
+        [[0.10377691, 0.5417086, 0.49807457],
+         [0.82872117, 0.77801674, 0.39226705],
+         [0.9314666, 0.66800209, 0.03538394]])
+    res1 = np.array(
+        [[1., 0.9379533, -0.04931983],
+         [0.9379533, 1., 0.30007991],
+         [-0.04931983, 0.30007991, 1.]])
+    res2 = np.array(
+        [[1., 0.9379533, -0.04931983, 0.30151751, 0.66318558, 0.51532523],
+         [0.9379533, 1., 0.30007991, -0.04781421, 0.88157256, 0.78052386],
+         [-0.04931983, 0.30007991, 1., -0.96717111, 0.71483595, 0.83053601],
+         [0.30151751, -0.04781421, -0.96717111, 1., -0.51366032, -0.66173113],
+         [0.66318558, 0.88157256, 0.71483595, -0.51366032, 1., 0.98317823],
+         [0.51532523, 0.78052386, 0.83053601, -0.66173113, 0.98317823, 1.]])
+
+    def test_non_array(self):
+        assert_almost_equal(np.corrcoef([0, 1, 0], [1, 0, 1]),
+                            [[1., -1.], [-1.,  1.]])
+
+    def test_simple(self):
+        tgt1 = corrcoef(self.A)
+        assert_almost_equal(tgt1, self.res1)
+        assert_(np.all(np.abs(tgt1) <= 1.0))
+
+        tgt2 = corrcoef(self.A, self.B)
+        assert_almost_equal(tgt2, self.res2)
+        assert_(np.all(np.abs(tgt2) <= 1.0))
+
+    def test_ddof(self):
+        # ddof raises DeprecationWarning
+        with catch_warn_nfb():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, self.A, ddof=-1)
+            warnings.simplefilter("ignore")
+            # ddof has no or negligible effect on the function
+            assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1)
+            assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2)
+            assert_almost_equal(corrcoef(self.A, ddof=3), self.res1)
+            assert_almost_equal(corrcoef(self.A, self.B, ddof=3), self.res2)
+
+    def test_bias(self):
+        # bias raises DeprecationWarning
+        with catch_warn_nfb():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, self.A, self.B, 1, 0)
+            assert_warns(DeprecationWarning, corrcoef, self.A, bias=0)
+            warnings.simplefilter("ignore")
+            # bias has no or negligible effect on the function
+            assert_almost_equal(corrcoef(self.A, bias=1), self.res1)
+
+    def test_complex(self):
+        x = np.array([[1, 2, 3], [1j, 2j, 3j]])
+        res = corrcoef(x)
+        tgt = np.array([[1., -1.j], [1.j, 1.]])
+        assert_allclose(res, tgt)
+        assert_(np.all(np.abs(res) <= 1.0))
+
+    def test_xy(self):
+        x = np.array([[1, 2, 3]])
+        y = np.array([[1j, 2j, 3j]])
+        assert_allclose(np.corrcoef(x, y), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(corrcoef(np.array([])), np.nan)
+            assert_array_equal(corrcoef(np.array([]).reshape(0, 2)),
+                               np.array([]).reshape(0, 0))
+            assert_array_equal(corrcoef(np.array([]).reshape(2, 0)),
+                               np.array([[np.nan, np.nan], [np.nan, np.nan]]))
+
+    def test_extreme(self):
+        x = [[1e-100, 1e100], [1e100, 1e-100]]
+        with np.errstate(all='raise'):
+            c = corrcoef(x)
+        assert_array_almost_equal(c, np.array([[1., -1.], [-1., 1.]]))
+        assert_(np.all(np.abs(c) <= 1.0))
+
+
+class TestCov(TestCase):
+    x1 = np.array([[0, 2], [1, 1], [2, 0]]).T
+    res1 = np.array([[1., -1.], [-1., 1.]])
+    x2 = np.array([0.0, 1.0, 2.0], ndmin=2)
+    frequencies = np.array([1, 4, 1])
+    x2_repeats = np.array([[0.0], [1.0], [1.0], [1.0], [1.0], [2.0]]).T
+    res2 = np.array([[0.4, -0.4], [-0.4, 0.4]])
+    unit_frequencies = np.ones(3, dtype=np.integer)
+    weights = np.array([1.0, 4.0, 1.0])
+    res3 = np.array([[2. / 3., -2. / 3.], [-2. / 3., 2. / 3.]])
+    unit_weights = np.ones(3)
+    x3 = np.array([0.3942, 0.5969, 0.7730, 0.9918, 0.7964])
+
+    def test_basic(self):
+        assert_allclose(cov(self.x1), self.res1)
+
+    def test_complex(self):
+        x = np.array([[1, 2, 3], [1j, 2j, 3j]])
+        assert_allclose(cov(x), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_xy(self):
+        x = np.array([[1, 2, 3]])
+        y = np.array([[1j, 2j, 3j]])
+        assert_allclose(cov(x, y), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(cov(np.array([])), np.nan)
+            assert_array_equal(cov(np.array([]).reshape(0, 2)),
+                               np.array([]).reshape(0, 0))
+            assert_array_equal(cov(np.array([]).reshape(2, 0)),
+                               np.array([[np.nan, np.nan], [np.nan, np.nan]]))
+
+    def test_wrong_ddof(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(cov(self.x1, ddof=5),
+                               np.array([[np.inf, -np.inf],
+                                         [-np.inf, np.inf]]))
+
+    def test_1D_rowvar(self):
+        assert_allclose(cov(self.x3), cov(self.x3, rowvar=0))
+        y = np.array([0.0780, 0.3107, 0.2111, 0.0334, 0.8501])
+        assert_allclose(cov(self.x3, y), cov(self.x3, y, rowvar=0))
+
+    def test_1D_variance(self):
+        assert_allclose(cov(self.x3, ddof=1), np.var(self.x3, ddof=1))
+
+    def test_fweights(self):
+        assert_allclose(cov(self.x2, fweights=self.frequencies),
+                        cov(self.x2_repeats))
+        assert_allclose(cov(self.x1, fweights=self.frequencies),
+                        self.res2)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies),
+                        self.res1)
+        nonint = self.frequencies + 0.5
+        assert_raises(TypeError, cov, self.x1, fweights=nonint)
+        f = np.ones((2, 3), dtype=np.integer)
+        assert_raises(RuntimeError, cov, self.x1, fweights=f)
+        f = np.ones(2, dtype=np.integer)
+        assert_raises(RuntimeError, cov, self.x1, fweights=f)
+        f = -1 * np.ones(3, dtype=np.integer)
+        assert_raises(ValueError, cov, self.x1, fweights=f)
+
+    def test_aweights(self):
+        assert_allclose(cov(self.x1, aweights=self.weights), self.res3)
+        assert_allclose(cov(self.x1, aweights=3.0 * self.weights),
+                        cov(self.x1, aweights=self.weights))
+        assert_allclose(cov(self.x1, aweights=self.unit_weights), self.res1)
+        w = np.ones((2, 3))
+        assert_raises(RuntimeError, cov, self.x1, aweights=w)
+        w = np.ones(2)
+        assert_raises(RuntimeError, cov, self.x1, aweights=w)
+        w = -1.0 * np.ones(3)
+        assert_raises(ValueError, cov, self.x1, aweights=w)
+
+    def test_unit_fweights_and_aweights(self):
+        assert_allclose(cov(self.x2, fweights=self.frequencies,
+                            aweights=self.unit_weights),
+                        cov(self.x2_repeats))
+        assert_allclose(cov(self.x1, fweights=self.frequencies,
+                            aweights=self.unit_weights),
+                        self.res2)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.unit_weights),
+                        self.res1)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.weights),
+                        self.res3)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=3.0 * self.weights),
+                        cov(self.x1, aweights=self.weights))
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.unit_weights),
+                        self.res1)
+
+
+class Test_I0(TestCase):
+
+    def test_simple(self):
+        assert_almost_equal(
+            i0(0.5),
+            np.array(1.0634833707413234))
+
+        A = np.array([0.49842636, 0.6969809, 0.22011976, 0.0155549])
+        assert_almost_equal(
+            i0(A),
+            np.array([1.06307822, 1.12518299, 1.01214991, 1.00006049]))
+
+        B = np.array([[0.827002, 0.99959078],
+                      [0.89694769, 0.39298162],
+                      [0.37954418, 0.05206293],
+                      [0.36465447, 0.72446427],
+                      [0.48164949, 0.50324519]])
+        assert_almost_equal(
+            i0(B),
+            np.array([[1.17843223, 1.26583466],
+                      [1.21147086, 1.03898290],
+                      [1.03633899, 1.00067775],
+                      [1.03352052, 1.13557954],
+                      [1.05884290, 1.06432317]]))
+
+
+class TestKaiser(TestCase):
+
+    def test_simple(self):
+        assert_(np.isfinite(kaiser(1, 1.0)))
+        assert_almost_equal(kaiser(0, 1.0),
+                            np.array([]))
+        assert_almost_equal(kaiser(2, 1.0),
+                            np.array([0.78984831, 0.78984831]))
+        assert_almost_equal(kaiser(5, 1.0),
+                            np.array([0.78984831, 0.94503323, 1.,
+                                      0.94503323, 0.78984831]))
+        assert_almost_equal(kaiser(5, 1.56789),
+                            np.array([0.58285404, 0.88409679, 1.,
+                                      0.88409679, 0.58285404]))
+
+    def test_int_beta(self):
+        kaiser(3, 4)
+
+
+class TestMsort(TestCase):
+
+    def test_simple(self):
+        A = np.array([[0.44567325, 0.79115165, 0.54900530],
+                      [0.36844147, 0.37325583, 0.96098397],
+                      [0.64864341, 0.52929049, 0.39172155]])
+        assert_almost_equal(
+            msort(A),
+            np.array([[0.36844147, 0.37325583, 0.39172155],
+                      [0.44567325, 0.52929049, 0.54900530],
+                      [0.64864341, 0.79115165, 0.96098397]]))
+
+
+class TestMeshgrid(TestCase):
+
+    def test_simple(self):
+        [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7])
+        assert_array_equal(X, np.array([[1, 2, 3],
+                                        [1, 2, 3],
+                                        [1, 2, 3],
+                                        [1, 2, 3]]))
+        assert_array_equal(Y, np.array([[4, 4, 4],
+                                        [5, 5, 5],
+                                        [6, 6, 6],
+                                        [7, 7, 7]]))
+
+    def test_single_input(self):
+        [X] = meshgrid([1, 2, 3, 4])
+        assert_array_equal(X, np.array([1, 2, 3, 4]))
+
+    def test_no_input(self):
+        args = []
+        assert_array_equal([], meshgrid(*args))
+
+    def test_indexing(self):
+        x = [1, 2, 3]
+        y = [4, 5, 6, 7]
+        [X, Y] = meshgrid(x, y, indexing='ij')
+        assert_array_equal(X, np.array([[1, 1, 1, 1],
+                                        [2, 2, 2, 2],
+                                        [3, 3, 3, 3]]))
+        assert_array_equal(Y, np.array([[4, 5, 6, 7],
+                                        [4, 5, 6, 7],
+                                        [4, 5, 6, 7]]))
+
+        # Test expected shapes:
+        z = [8, 9]
+        assert_(meshgrid(x, y)[0].shape == (4, 3))
+        assert_(meshgrid(x, y, indexing='ij')[0].shape == (3, 4))
+        assert_(meshgrid(x, y, z)[0].shape == (4, 3, 2))
+        assert_(meshgrid(x, y, z, indexing='ij')[0].shape == (3, 4, 2))
+
+        assert_raises(ValueError, meshgrid, x, y, indexing='notvalid')
+
+    def test_sparse(self):
+        [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7], sparse=True)
+        assert_array_equal(X, np.array([[1, 2, 3]]))
+        assert_array_equal(Y, np.array([[4], [5], [6], [7]]))
+
+    def test_invalid_arguments(self):
+        # Test that meshgrid complains about invalid arguments
+        # Regression test for issue #4755:
+        # https://github.com/numpy/numpy/issues/4755
+        assert_raises(TypeError, meshgrid,
+                      [1, 2, 3], [4, 5, 6, 7], indices='ij')
+
+
+class TestPiecewise(TestCase):
+
+    def test_simple(self):
+        # Condition is single bool list
+        x = piecewise([0, 0], [True, False], [1])
+        assert_array_equal(x, [1, 0])
+
+        # List of conditions: single bool list
+        x = piecewise([0, 0], [[True, False]], [1])
+        assert_array_equal(x, [1, 0])
+
+        # Conditions is single bool array
+        x = piecewise([0, 0], np.array([True, False]), [1])
+        assert_array_equal(x, [1, 0])
+
+        # Condition is single int array
+        x = piecewise([0, 0], np.array([1, 0]), [1])
+        assert_array_equal(x, [1, 0])
+
+        # List of conditions: int array
+        x = piecewise([0, 0], [np.array([1, 0])], [1])
+        assert_array_equal(x, [1, 0])
+
+        x = piecewise([0, 0], [[False, True]], [lambda x:-1])
+        assert_array_equal(x, [0, -1])
+
+    def test_two_conditions(self):
+        x = piecewise([1, 2], [[True, False], [False, True]], [3, 4])
+        assert_array_equal(x, [3, 4])
+
+    def test_scalar_domains_three_conditions(self):
+        x = piecewise(3, [True, False, False], [4, 2, 0])
+        assert_equal(x, 4)
+
+    def test_default(self):
+        # No value specified for x[1], should be 0
+        x = piecewise([1, 2], [True, False], [2])
+        assert_array_equal(x, [2, 0])
+
+        # Should set x[1] to 3
+        x = piecewise([1, 2], [True, False], [2, 3])
+        assert_array_equal(x, [2, 3])
+
+    def test_0d(self):
+        x = np.array(3)
+        y = piecewise(x, x > 3, [4, 0])
+        assert_(y.ndim == 0)
+        assert_(y == 0)
+
+        x = 5
+        y = piecewise(x, [[True], [False]], [1, 0])
+        assert_(y.ndim == 0)
+        assert_(y == 1)
+
+    def test_0d_comparison(self):
+        x = 3
+        piecewise(x, [x <= 3, x > 3], [4, 0])  # Should succeed.
+
+    def test_multidimensional_extrafunc(self):
+        x = np.array([[-2.5, -1.5, -0.5],
+                      [0.5, 1.5, 2.5]])
+        y = piecewise(x, [x < 0, x >= 2], [-1, 1, 3])
+        assert_array_equal(y, np.array([[-1., -1., -1.],
+                                        [3., 3., 1.]]))
+
+
+class TestBincount(TestCase):
+
+    def test_simple(self):
+        y = np.bincount(np.arange(4))
+        assert_array_equal(y, np.ones(4))
+
+    def test_simple2(self):
+        y = np.bincount(np.array([1, 5, 2, 4, 1]))
+        assert_array_equal(y, np.array([0, 2, 1, 0, 1, 1]))
+
+    def test_simple_weight(self):
+        x = np.arange(4)
+        w = np.array([0.2, 0.3, 0.5, 0.1])
+        y = np.bincount(x, w)
+        assert_array_equal(y, w)
+
+    def test_simple_weight2(self):
+        x = np.array([1, 2, 4, 5, 2])
+        w = np.array([0.2, 0.3, 0.5, 0.1, 0.2])
+        y = np.bincount(x, w)
+        assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1]))
+
+    def test_with_minlength(self):
+        x = np.array([0, 1, 0, 1, 1])
+        y = np.bincount(x, minlength=3)
+        assert_array_equal(y, np.array([2, 3, 0]))
+
+    def test_with_minlength_smaller_than_maxvalue(self):
+        x = np.array([0, 1, 1, 2, 2, 3, 3])
+        y = np.bincount(x, minlength=2)
+        assert_array_equal(y, np.array([1, 2, 2, 2]))
+
+    def test_with_minlength_and_weights(self):
+        x = np.array([1, 2, 4, 5, 2])
+        w = np.array([0.2, 0.3, 0.5, 0.1, 0.2])
+        y = np.bincount(x, w, 8)
+        assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1, 0, 0]))
+
+    def test_empty(self):
+        x = np.array([], dtype=int)
+        y = np.bincount(x)
+        assert_array_equal(x, y)
+
+    def test_empty_with_minlength(self):
+        x = np.array([], dtype=int)
+        y = np.bincount(x, minlength=5)
+        assert_array_equal(y, np.zeros(5, dtype=int))
+
+    def test_with_incorrect_minlength(self):
+        x = np.array([], dtype=int)
+        assert_raises_regex(TypeError, "an integer is required",
+                            lambda: np.bincount(x, minlength="foobar"))
+        assert_raises_regex(ValueError, "must be positive",
+                            lambda: np.bincount(x, minlength=-1))
+        assert_raises_regex(ValueError, "must be positive",
+                            lambda: np.bincount(x, minlength=0))
+
+        x = np.arange(5)
+        assert_raises_regex(TypeError, "an integer is required",
+                            lambda: np.bincount(x, minlength="foobar"))
+        assert_raises_regex(ValueError, "minlength must be positive",
+                            lambda: np.bincount(x, minlength=-1))
+        assert_raises_regex(ValueError, "minlength must be positive",
+                            lambda: np.bincount(x, minlength=0))
+
+
+class TestInterp(TestCase):
+
+    def test_exceptions(self):
+        assert_raises(ValueError, interp, 0, [], [])
+        assert_raises(ValueError, interp, 0, [0], [1, 2])
+        assert_raises(ValueError, interp, 0, [0, 1], [1, 2], period=0)
+        assert_raises(ValueError, interp, 0, [], [], period=360)
+        assert_raises(ValueError, interp, 0, [0], [1, 2], period=360)
+
+    def test_basic(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = np.linspace(0, 1, 50)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+
+    def test_right_left_behavior(self):
+        # Needs range of sizes to test different code paths.
+        # size ==1 is special cased, 1 < size < 5 is linear search, and
+        # size >= 5 goes through local search and possibly binary search.
+        for size in range(1, 10):
+            xp = np.arange(size, dtype=np.double)
+            yp = np.ones(size, dtype=np.double)
+            incpts = np.array([-1, 0, size - 1, size], dtype=np.double)
+            decpts = incpts[::-1]
+
+            incres = interp(incpts, xp, yp)
+            decres = interp(decpts, xp, yp)
+            inctgt = np.array([1, 1, 1, 1], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, left=0)
+            decres = interp(decpts, xp, yp, left=0)
+            inctgt = np.array([0, 1, 1, 1], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, right=2)
+            decres = interp(decpts, xp, yp, right=2)
+            inctgt = np.array([1, 1, 1, 2], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, left=0, right=2)
+            decres = interp(decpts, xp, yp, left=0, right=2)
+            inctgt = np.array([0, 1, 1, 2], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+    def test_scalar_interpolation_point(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = 0
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = .3
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.float32(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.float64(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.nan
+        assert_almost_equal(np.interp(x0, x, y), x0)
+
+    def test_zero_dimensional_interpolation_point(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = np.array(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.array(.3, dtype=object)
+        assert_almost_equal(np.interp(x0, x, y), .3)
+
+    def test_if_len_x_is_small(self):
+        xp = np.arange(0, 10, 0.0001)
+        fp = np.sin(xp)
+        assert_almost_equal(np.interp(np.pi, xp, fp), 0.0)
+
+    def test_period(self):
+        x = [-180, -170, -185, 185, -10, -5, 0, 365]
+        xp = [190, -190, 350, -350]
+        fp = [5, 10, 3, 4]
+        y = [7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75]
+        assert_almost_equal(np.interp(x, xp, fp, period=360), y)
+        x = np.array(x, order='F').reshape(2, -1)
+        y = np.array(y, order='C').reshape(2, -1)
+        assert_almost_equal(np.interp(x, xp, fp, period=360), y)
+
+
+def compare_results(res, desired):
+    for i in range(len(desired)):
+        assert_array_equal(res[i], desired[i])
+
+
+class TestPercentile(TestCase):
+
+    def test_basic(self):
+        x = np.arange(8) * 0.5
+        assert_equal(np.percentile(x, 0), 0.)
+        assert_equal(np.percentile(x, 100), 3.5)
+        assert_equal(np.percentile(x, 50), 1.75)
+        x[1] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(x, 0), np.nan)
+            assert_equal(np.percentile(x, 0, interpolation='nearest'), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_api(self):
+        d = np.ones(5)
+        np.percentile(d, 5, None, None, False)
+        np.percentile(d, 5, None, None, False, 'linear')
+        o = np.ones((1,))
+        np.percentile(d, 5, None, o, False, 'linear')
+
+    def test_2D(self):
+        x = np.array([[1, 1, 1],
+                      [1, 1, 1],
+                      [4, 4, 3],
+                      [1, 1, 1],
+                      [1, 1, 1]])
+        assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1])
+
+    def test_linear(self):
+
+        # Test defaults
+        assert_equal(np.percentile(range(10), 50), 4.5)
+
+        # explicitly specify interpolation_method 'linear' (the default)
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='linear'), 4.5)
+
+    def test_lower_higher(self):
+
+        # interpolation_method 'lower'/'higher'
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='lower'), 4)
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='higher'), 5)
+
+    def test_midpoint(self):
+        assert_equal(np.percentile(range(10), 51,
+                                   interpolation='midpoint'), 4.5)
+        assert_equal(np.percentile(range(11), 51,
+                                   interpolation='midpoint'), 5.5)
+        assert_equal(np.percentile(range(11), 50,
+                                   interpolation='midpoint'), 5)
+
+    def test_nearest(self):
+        assert_equal(np.percentile(range(10), 51,
+                                   interpolation='nearest'), 5)
+        assert_equal(np.percentile(range(10), 49,
+                                   interpolation='nearest'), 4)
+
+    def test_sequence(self):
+        x = np.arange(8) * 0.5
+        assert_equal(np.percentile(x, [0, 100, 50]), [0, 3.5, 1.75])
+
+    def test_axis(self):
+        x = np.arange(12).reshape(3, 4)
+
+        assert_equal(np.percentile(x, (25, 50, 100)), [2.75, 5.5, 11.0])
+
+        r0 = [[2, 3, 4, 5], [4, 5, 6, 7], [8, 9, 10, 11]]
+        assert_equal(np.percentile(x, (25, 50, 100), axis=0), r0)
+
+        r1 = [[0.75, 1.5, 3], [4.75, 5.5, 7], [8.75, 9.5, 11]]
+        assert_equal(np.percentile(x, (25, 50, 100), axis=1), np.array(r1).T)
+
+        # ensure qth axis is always first as with np.array(old_percentile(..))
+        x = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+        assert_equal(np.percentile(x, (25, 50)).shape, (2,))
+        assert_equal(np.percentile(x, (25, 50, 75)).shape, (3,))
+        assert_equal(np.percentile(x, (25, 50), axis=0).shape, (2, 4, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=1).shape, (2, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=2).shape, (2, 3, 4, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=3).shape, (2, 3, 4, 5))
+        assert_equal(
+            np.percentile(x, (25, 50, 75), axis=1).shape, (3, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50),
+                                   interpolation="higher").shape, (2,))
+        assert_equal(np.percentile(x, (25, 50, 75),
+                                   interpolation="higher").shape, (3,))
+        assert_equal(np.percentile(x, (25, 50), axis=0,
+                                   interpolation="higher").shape, (2, 4, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=1,
+                                   interpolation="higher").shape, (2, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=2,
+                                   interpolation="higher").shape, (2, 3, 4, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=3,
+                                   interpolation="higher").shape, (2, 3, 4, 5))
+        assert_equal(np.percentile(x, (25, 50, 75), axis=1,
+                                   interpolation="higher").shape, (3, 3, 5, 6))
+
+    def test_scalar_q(self):
+        # test for no empty dimensions for compatiblity with old percentile
+        x = np.arange(12).reshape(3, 4)
+        assert_equal(np.percentile(x, 50), 5.5)
+        self.assertTrue(np.isscalar(np.percentile(x, 50)))
+        r0 = np.array([4.,  5.,  6.,  7.])
+        assert_equal(np.percentile(x, 50, axis=0), r0)
+        assert_equal(np.percentile(x, 50, axis=0).shape, r0.shape)
+        r1 = np.array([1.5,  5.5,  9.5])
+        assert_almost_equal(np.percentile(x, 50, axis=1), r1)
+        assert_equal(np.percentile(x, 50, axis=1).shape, r1.shape)
+
+        out = np.empty(1)
+        assert_equal(np.percentile(x, 50, out=out), 5.5)
+        assert_equal(out, 5.5)
+        out = np.empty(4)
+        assert_equal(np.percentile(x, 50, axis=0, out=out), r0)
+        assert_equal(out, r0)
+        out = np.empty(3)
+        assert_equal(np.percentile(x, 50, axis=1, out=out), r1)
+        assert_equal(out, r1)
+
+        # test for no empty dimensions for compatiblity with old percentile
+        x = np.arange(12).reshape(3, 4)
+        assert_equal(np.percentile(x, 50, interpolation='lower'), 5.)
+        self.assertTrue(np.isscalar(np.percentile(x, 50)))
+        r0 = np.array([4.,  5.,  6.,  7.])
+        c0 = np.percentile(x, 50, interpolation='lower', axis=0)
+        assert_equal(c0, r0)
+        assert_equal(c0.shape, r0.shape)
+        r1 = np.array([1.,  5.,  9.])
+        c1 = np.percentile(x, 50, interpolation='lower', axis=1)
+        assert_almost_equal(c1, r1)
+        assert_equal(c1.shape, r1.shape)
+
+        out = np.empty((), dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', out=out)
+        assert_equal(c, 5)
+        assert_equal(out, 5)
+        out = np.empty(4, dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', axis=0, out=out)
+        assert_equal(c, r0)
+        assert_equal(out, r0)
+        out = np.empty(3, dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', axis=1, out=out)
+        assert_equal(c, r1)
+        assert_equal(out, r1)
+
+    def test_exception(self):
+        assert_raises(ValueError, np.percentile, [1, 2], 56,
+                      interpolation='foobar')
+        assert_raises(ValueError, np.percentile, [1], 101)
+        assert_raises(ValueError, np.percentile, [1], -1)
+        assert_raises(ValueError, np.percentile, [1], list(range(50)) + [101])
+        assert_raises(ValueError, np.percentile, [1], list(range(50)) + [-0.1])
+
+    def test_percentile_list(self):
+        assert_equal(np.percentile([1, 2, 3], 0), 1)
+
+    def test_percentile_out(self):
+        x = np.array([1, 2, 3])
+        y = np.zeros((3,))
+        p = (1, 2, 3)
+        np.percentile(x, p, out=y)
+        assert_equal(y, np.percentile(x, p))
+
+        x = np.array([[1, 2, 3],
+                      [4, 5, 6]])
+
+        y = np.zeros((3, 3))
+        np.percentile(x, p, axis=0, out=y)
+        assert_equal(y, np.percentile(x, p, axis=0))
+
+        y = np.zeros((3, 2))
+        np.percentile(x, p, axis=1, out=y)
+        assert_equal(y, np.percentile(x, p, axis=1))
+
+        x = np.arange(12).reshape(3, 4)
+        # q.dim > 1, float
+        r0 = np.array([[2.,  3.,  4., 5.], [4., 5., 6., 7.]])
+        out = np.empty((2, 4))
+        assert_equal(np.percentile(x, (25, 50), axis=0, out=out), r0)
+        assert_equal(out, r0)
+        r1 = np.array([[0.75,  4.75,  8.75], [1.5,  5.5,  9.5]])
+        out = np.empty((2, 3))
+        assert_equal(np.percentile(x, (25, 50), axis=1, out=out), r1)
+        assert_equal(out, r1)
+
+        # q.dim > 1, int
+        r0 = np.array([[0,  1,  2, 3], [4, 5, 6, 7]])
+        out = np.empty((2, 4), dtype=x.dtype)
+        c = np.percentile(x, (25, 50), interpolation='lower', axis=0, out=out)
+        assert_equal(c, r0)
+        assert_equal(out, r0)
+        r1 = np.array([[0,  4,  8], [1,  5,  9]])
+        out = np.empty((2, 3), dtype=x.dtype)
+        c = np.percentile(x, (25, 50), interpolation='lower', axis=1, out=out)
+        assert_equal(c, r1)
+        assert_equal(out, r1)
+
+    def test_percentile_empty_dim(self):
+        # empty dims are preserved
+        d = np.arange(11 * 2).reshape(11, 1, 2, 1)
+        assert_array_equal(np.percentile(d, 50, axis=0).shape, (1, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=1).shape, (11, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=2).shape, (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=3).shape, (11, 1, 2))
+        assert_array_equal(np.percentile(d, 50, axis=-1).shape, (11, 1, 2))
+        assert_array_equal(np.percentile(d, 50, axis=-2).shape, (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-3).shape, (11, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-4).shape, (1, 2, 1))
+
+        assert_array_equal(np.percentile(d, 50, axis=2,
+                                         interpolation='midpoint').shape,
+                           (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-2,
+                                         interpolation='midpoint').shape,
+                           (11, 1, 1))
+
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=0)).shape,
+                           (2, 1, 2, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=1)).shape,
+                           (2, 11, 2, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=2)).shape,
+                           (2, 11, 1, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=3)).shape,
+                           (2, 11, 1, 2))
+
+    def test_percentile_no_overwrite(self):
+        a = np.array([2, 3, 4, 1])
+        np.percentile(a, [50], overwrite_input=False)
+        assert_equal(a, np.array([2, 3, 4, 1]))
+
+        a = np.array([2, 3, 4, 1])
+        np.percentile(a, [50])
+        assert_equal(a, np.array([2, 3, 4, 1]))
+
+    def test_no_p_overwrite(self):
+        p = np.linspace(0., 100., num=5)
+        np.percentile(np.arange(100.), p, interpolation="midpoint")
+        assert_array_equal(p, np.linspace(0., 100., num=5))
+        p = np.linspace(0., 100., num=5).tolist()
+        np.percentile(np.arange(100.), p, interpolation="midpoint")
+        assert_array_equal(p, np.linspace(0., 100., num=5).tolist())
+
+    def test_percentile_overwrite(self):
+        a = np.array([2, 3, 4, 1])
+        b = np.percentile(a, [50], overwrite_input=True)
+        assert_equal(b, np.array([2.5]))
+
+        b = np.percentile([2, 3, 4, 1], [50], overwrite_input=True)
+        assert_equal(b, np.array([2.5]))
+
+    def test_extended_axis(self):
+        o = np.random.normal(size=(71, 23))
+        x = np.dstack([o] * 10)
+        assert_equal(np.percentile(x, 30, axis=(0, 1)), np.percentile(o, 30))
+        x = np.rollaxis(x, -1, 0)
+        assert_equal(np.percentile(x, 30, axis=(-2, -1)), np.percentile(o, 30))
+        x = x.swapaxes(0, 1).copy()
+        assert_equal(np.percentile(x, 30, axis=(0, -1)), np.percentile(o, 30))
+        x = x.swapaxes(0, 1).copy()
+
+        assert_equal(np.percentile(x, [25, 60], axis=(0, 1, 2)),
+                     np.percentile(x, [25, 60], axis=None))
+        assert_equal(np.percentile(x, [25, 60], axis=(0,)),
+                     np.percentile(x, [25, 60], axis=0))
+
+        d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11)
+        np.random.shuffle(d)
+        assert_equal(np.percentile(d, 25,  axis=(0, 1, 2))[0],
+                     np.percentile(d[:,:,:, 0].flatten(), 25))
+        assert_equal(np.percentile(d, [10, 90], axis=(0, 1, 3))[:, 1],
+                     np.percentile(d[:,:, 1,:].flatten(), [10, 90]))
+        assert_equal(np.percentile(d, 25, axis=(3, 1, -4))[2],
+                     np.percentile(d[:,:, 2,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(3, 1, 2))[2],
+                     np.percentile(d[2,:,:,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(3, 2))[2, 1],
+                     np.percentile(d[2, 1,:,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(1, -2))[2, 1],
+                     np.percentile(d[2,:,:, 1].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(1, 3))[2, 2],
+                     np.percentile(d[2,:, 2,:].flatten(), 25))
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.percentile, d, axis=-5, q=25)
+        assert_raises(IndexError, np.percentile, d, axis=(0, -5), q=25)
+        assert_raises(IndexError, np.percentile, d, axis=4, q=25)
+        assert_raises(IndexError, np.percentile, d, axis=(0, 4), q=25)
+        assert_raises(ValueError, np.percentile, d, axis=(1, 1), q=25)
+
+    def test_keepdims(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_equal(np.percentile(d, 7, axis=None, keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.percentile(d, 7, axis=(0, 1), keepdims=True).shape,
+                     (1, 1, 7, 11))
+        assert_equal(np.percentile(d, 7, axis=(0, 3), keepdims=True).shape,
+                     (1, 5, 7, 1))
+        assert_equal(np.percentile(d, 7, axis=(1,), keepdims=True).shape,
+                     (3, 1, 7, 11))
+        assert_equal(np.percentile(d, 7, (0, 1, 2, 3), keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.percentile(d, 7, axis=(0, 1, 3), keepdims=True).shape,
+                     (1, 1, 7, 1))
+
+        assert_equal(np.percentile(d, [1, 7], axis=(0, 1, 3),
+                                   keepdims=True).shape, (2, 1, 1, 7, 1))
+        assert_equal(np.percentile(d, [1, 7], axis=(0, 3),
+                                   keepdims=True).shape, (2, 1, 5, 7, 1))
+
+    def test_out(self):
+        o = np.zeros((4,))
+        d = np.ones((3, 4))
+        assert_equal(np.percentile(d, 0, 0, out=o), o)
+        assert_equal(np.percentile(d, 0, 0, interpolation='nearest', out=o), o)
+        o = np.zeros((3,))
+        assert_equal(np.percentile(d, 1, 1, out=o), o)
+        assert_equal(np.percentile(d, 1, 1, interpolation='nearest', out=o), o)
+
+        o = np.zeros(())
+        assert_equal(np.percentile(d, 2, out=o), o)
+        assert_equal(np.percentile(d, 2, interpolation='nearest', out=o), o)
+
+    def test_out_nan(self):
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            o = np.zeros((4,))
+            d = np.ones((3, 4))
+            d[2, 1] = np.nan
+            assert_equal(np.percentile(d, 0, 0, out=o), o)
+            assert_equal(
+                np.percentile(d, 0, 0, interpolation='nearest', out=o), o)
+            o = np.zeros((3,))
+            assert_equal(np.percentile(d, 1, 1, out=o), o)
+            assert_equal(
+                np.percentile(d, 1, 1, interpolation='nearest', out=o), o)
+            o = np.zeros(())
+            assert_equal(np.percentile(d, 1, out=o), o)
+            assert_equal(
+                np.percentile(d, 1, interpolation='nearest', out=o), o)
+
+    def test_nan_behavior(self):
+        a = np.arange(24, dtype=float)
+        a[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3), np.nan)
+            assert_equal(np.percentile(a, 0.3, axis=0), np.nan)
+            assert_equal(np.percentile(a, [0.3, 0.6], axis=0),
+                         np.array([np.nan] * 2))
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+            assert_(w[2].category is RuntimeWarning)
+
+        a = np.arange(24, dtype=float).reshape(2, 3, 4)
+        a[1, 2, 3] = np.nan
+        a[1, 1, 2] = np.nan
+
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3), np.nan)
+            assert_equal(np.percentile(a, 0.3).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis0 zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 0)
+        b[2, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, 0), b)
+
+        # axis0 not zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], 0)
+        b[:, 2, 3] = np.nan
+        b[:, 1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], 0), b)
+
+        # axis1 zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 1)
+        b[1, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, 1), b)
+        # axis1 not zerod
+        b = np.percentile(
+            np.arange(24, dtype=float).reshape(2, 3, 4), [0.3, 0.6], 1)
+        b[:, 1, 3] = np.nan
+        b[:, 1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], 1), b)
+
+        # axis02 zerod
+        b = np.percentile(
+            np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, (0, 2))
+        b[1] = np.nan
+        b[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, (0, 2)), b)
+        # axis02 not zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], (0, 2))
+        b[:, 1] = np.nan
+        b[:, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], (0, 2)), b)
+        # axis02 not zerod with nearest interpolation
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], (0, 2), interpolation='nearest')
+        b[:, 1] = np.nan
+        b[:, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(
+                a, [0.3, 0.6], (0, 2), interpolation='nearest'), b)
+
+
+class TestMedian(TestCase):
+
+    def test_basic(self):
+        a0 = np.array(1)
+        a1 = np.arange(2)
+        a2 = np.arange(6).reshape(2, 3)
+        assert_equal(np.median(a0), 1)
+        assert_allclose(np.median(a1), 0.5)
+        assert_allclose(np.median(a2), 2.5)
+        assert_allclose(np.median(a2, axis=0), [1.5,  2.5,  3.5])
+        assert_equal(np.median(a2, axis=1), [1, 4])
+        assert_allclose(np.median(a2, axis=None), 2.5)
+
+        a = np.array([0.0444502, 0.0463301, 0.141249, 0.0606775])
+        assert_almost_equal((a[1] + a[3]) / 2., np.median(a))
+        a = np.array([0.0463301, 0.0444502, 0.141249])
+        assert_equal(a[0], np.median(a))
+        a = np.array([0.0444502, 0.141249, 0.0463301])
+        assert_equal(a[-1], np.median(a))
+        # check array scalar result
+        assert_equal(np.median(a).ndim, 0)
+        a[1] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_axis_keyword(self):
+        a3 = np.array([[2, 3],
+                       [0, 1],
+                       [6, 7],
+                       [4, 5]])
+        for a in [a3, np.random.randint(0, 100, size=(2, 3, 4))]:
+            orig = a.copy()
+            np.median(a, axis=None)
+            for ax in range(a.ndim):
+                np.median(a, axis=ax)
+            assert_array_equal(a, orig)
+
+        assert_allclose(np.median(a3, axis=0), [3,  4])
+        assert_allclose(np.median(a3.T, axis=1), [3,  4])
+        assert_allclose(np.median(a3), 3.5)
+        assert_allclose(np.median(a3, axis=None), 3.5)
+        assert_allclose(np.median(a3.T), 3.5)
+
+    def test_overwrite_keyword(self):
+        a3 = np.array([[2, 3],
+                       [0, 1],
+                       [6, 7],
+                       [4, 5]])
+        a0 = np.array(1)
+        a1 = np.arange(2)
+        a2 = np.arange(6).reshape(2, 3)
+        assert_allclose(np.median(a0.copy(), overwrite_input=True), 1)
+        assert_allclose(np.median(a1.copy(), overwrite_input=True), 0.5)
+        assert_allclose(np.median(a2.copy(), overwrite_input=True), 2.5)
+        assert_allclose(np.median(a2.copy(), overwrite_input=True, axis=0),
+                        [1.5,  2.5,  3.5])
+        assert_allclose(
+            np.median(a2.copy(), overwrite_input=True, axis=1), [1, 4])
+        assert_allclose(
+            np.median(a2.copy(), overwrite_input=True, axis=None), 2.5)
+        assert_allclose(
+            np.median(a3.copy(), overwrite_input=True, axis=0), [3,  4])
+        assert_allclose(np.median(a3.T.copy(), overwrite_input=True, axis=1),
+                        [3,  4])
+
+        a4 = np.arange(3 * 4 * 5, dtype=np.float32).reshape((3, 4, 5))
+        map(np.random.shuffle, a4)
+        assert_allclose(np.median(a4, axis=None),
+                        np.median(a4.copy(), axis=None, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=0),
+                        np.median(a4.copy(), axis=0, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=1),
+                        np.median(a4.copy(), axis=1, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=2),
+                        np.median(a4.copy(), axis=2, overwrite_input=True))
+
+    def test_array_like(self):
+        x = [1, 2, 3]
+        assert_almost_equal(np.median(x), 2)
+        x2 = [x]
+        assert_almost_equal(np.median(x2), 2)
+        assert_allclose(np.median(x2, axis=0), x)
+
+    def test_subclass(self):
+        # gh-3846
+        class MySubClass(np.ndarray):
+
+            def __new__(cls, input_array, info=None):
+                obj = np.asarray(input_array).view(cls)
+                obj.info = info
+                return obj
+
+            def mean(self, axis=None, dtype=None, out=None):
+                return -7
+
+        a = MySubClass([1, 2, 3])
+        assert_equal(np.median(a), -7)
+
+    def test_out(self):
+        o = np.zeros((4,))
+        d = np.ones((3, 4))
+        assert_equal(np.median(d, 0, out=o), o)
+        o = np.zeros((3,))
+        assert_equal(np.median(d, 1, out=o), o)
+        o = np.zeros(())
+        assert_equal(np.median(d, out=o), o)
+
+    def test_out_nan(self):
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            o = np.zeros((4,))
+            d = np.ones((3, 4))
+            d[2, 1] = np.nan
+            assert_equal(np.median(d, 0, out=o), o)
+            o = np.zeros((3,))
+            assert_equal(np.median(d, 1, out=o), o)
+            o = np.zeros(())
+            assert_equal(np.median(d, out=o), o)
+
+    def test_nan_behavior(self):
+        a = np.arange(24, dtype=float)
+        a[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_equal(np.median(a, axis=0), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+
+        a = np.arange(24, dtype=float).reshape(2, 3, 4)
+        a[1, 2, 3] = np.nan
+        a[1, 1, 2] = np.nan
+
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_equal(np.median(a).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis0
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 0)
+        b[2, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, 0), b)
+            assert_equal(len(w), 1)
+
+        # axis1
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 1)
+        b[1, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, 1), b)
+            assert_equal(len(w), 1)
+
+        # axis02
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), (0, 2))
+        b[1] = np.nan
+        b[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, (0, 2)), b)
+            assert_equal(len(w), 1)
+
+    def test_empty(self):
+        # empty arrays
+        a = np.array([], dtype=float)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+        # multiple dimensions
+        a = np.array([], dtype=float, ndmin=3)
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis 0 and 1
+        b = np.array([], dtype=float, ndmin=2)
+        assert_equal(np.median(a, axis=0), b)
+        assert_equal(np.median(a, axis=1), b)
+
+        # axis 2
+        b = np.array(np.nan, dtype=float, ndmin=2)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, axis=2), b)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_object(self):
+        o = np.arange(7.)
+        assert_(type(np.median(o.astype(object))), float)
+        o[2] = np.nan
+        assert_(type(np.median(o.astype(object))), float)
+
+    def test_extended_axis(self):
+        o = np.random.normal(size=(71, 23))
+        x = np.dstack([o] * 10)
+        assert_equal(np.median(x, axis=(0, 1)), np.median(o))
+        x = np.rollaxis(x, -1, 0)
+        assert_equal(np.median(x, axis=(-2, -1)), np.median(o))
+        x = x.swapaxes(0, 1).copy()
+        assert_equal(np.median(x, axis=(0, -1)), np.median(o))
+
+        assert_equal(np.median(x, axis=(0, 1, 2)), np.median(x, axis=None))
+        assert_equal(np.median(x, axis=(0, )), np.median(x, axis=0))
+        assert_equal(np.median(x, axis=(-1, )), np.median(x, axis=-1))
+
+        d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11)
+        np.random.shuffle(d)
+        assert_equal(np.median(d, axis=(0, 1, 2))[0],
+                     np.median(d[:,:,:, 0].flatten()))
+        assert_equal(np.median(d, axis=(0, 1, 3))[1],
+                     np.median(d[:,:, 1,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 1, -4))[2],
+                     np.median(d[:,:, 2,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 1, 2))[2],
+                     np.median(d[2,:,:,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 2))[2, 1],
+                     np.median(d[2, 1,:,:].flatten()))
+        assert_equal(np.median(d, axis=(1, -2))[2, 1],
+                     np.median(d[2,:,:, 1].flatten()))
+        assert_equal(np.median(d, axis=(1, 3))[2, 2],
+                     np.median(d[2,:, 2,:].flatten()))
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.median, d, axis=-5)
+        assert_raises(IndexError, np.median, d, axis=(0, -5))
+        assert_raises(IndexError, np.median, d, axis=4)
+        assert_raises(IndexError, np.median, d, axis=(0, 4))
+        assert_raises(ValueError, np.median, d, axis=(1, 1))
+
+    def test_keepdims(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_equal(np.median(d, axis=None, keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.median(d, axis=(0, 1), keepdims=True).shape,
+                     (1, 1, 7, 11))
+        assert_equal(np.median(d, axis=(0, 3), keepdims=True).shape,
+                     (1, 5, 7, 1))
+        assert_equal(np.median(d, axis=(1,), keepdims=True).shape,
+                     (3, 1, 7, 11))
+        assert_equal(np.median(d, axis=(0, 1, 2, 3), keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.median(d, axis=(0, 1, 3), keepdims=True).shape,
+                     (1, 1, 7, 1))
+
+
+class TestAdd_newdoc_ufunc(TestCase):
+
+    def test_ufunc_arg(self):
+        assert_raises(TypeError, add_newdoc_ufunc, 2, "blah")
+        assert_raises(ValueError, add_newdoc_ufunc, np.add, "blah")
+
+    def test_string_arg(self):
+        assert_raises(TypeError, add_newdoc_ufunc, np.add, 3)
+
+
+class TestAdd_newdoc(TestCase):
+
+    @dec.skipif(sys.flags.optimize == 2)
+    def test_add_doc(self):
+        # test np.add_newdoc
+        tgt = "Current flat index into the array."
+        self.assertEqual(np.core.flatiter.index.__doc__[:len(tgt)], tgt)
+        self.assertTrue(len(np.core.ufunc.identity.__doc__) > 300)
+        self.assertTrue(len(np.lib.index_tricks.mgrid.__doc__) > 300)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
new file mode 100644
index 0000000000..bb2ae15096
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
@@ -0,0 +1,326 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, assert_array_almost_equal, assert_raises
+    )
+from numpy.lib.index_tricks import (
+    mgrid, ndenumerate, fill_diagonal, diag_indices, diag_indices_from,
+    index_exp, ndindex, r_, s_, ix_
+    )
+
+
+class TestRavelUnravelIndex(TestCase):
+    def test_basic(self):
+        assert_equal(np.unravel_index(2, (2, 2)), (1, 0))
+        assert_equal(np.ravel_multi_index((1, 0), (2, 2)), 2)
+        assert_equal(np.unravel_index(254, (17, 94)), (2, 66))
+        assert_equal(np.ravel_multi_index((2, 66), (17, 94)), 254)
+        assert_raises(ValueError, np.unravel_index, -1, (2, 2))
+        assert_raises(TypeError, np.unravel_index, 0.5, (2, 2))
+        assert_raises(ValueError, np.unravel_index, 4, (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (-3, 1), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (2, 1), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (0, -3), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (0, 2), (2, 2))
+        assert_raises(TypeError, np.ravel_multi_index, (0.1, 0.), (2, 2))
+
+        assert_equal(np.unravel_index((2*3 + 1)*6 + 4, (4, 3, 6)), [2, 1, 4])
+        assert_equal(
+            np.ravel_multi_index([2, 1, 4], (4, 3, 6)), (2*3 + 1)*6 + 4)
+
+        arr = np.array([[3, 6, 6], [4, 5, 1]])
+        assert_equal(np.ravel_multi_index(arr, (7, 6)), [22, 41, 37])
+        assert_equal(
+            np.ravel_multi_index(arr, (7, 6), order='F'), [31, 41, 13])
+        assert_equal(
+            np.ravel_multi_index(arr, (4, 6), mode='clip'), [22, 23, 19])
+        assert_equal(np.ravel_multi_index(arr, (4, 4), mode=('clip', 'wrap')),
+                     [12, 13, 13])
+        assert_equal(np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9)), 1621)
+
+        assert_equal(np.unravel_index(np.array([22, 41, 37]), (7, 6)),
+                     [[3, 6, 6], [4, 5, 1]])
+        assert_equal(
+            np.unravel_index(np.array([31, 41, 13]), (7, 6), order='F'),
+            [[3, 6, 6], [4, 5, 1]])
+        assert_equal(np.unravel_index(1621, (6, 7, 8, 9)), [3, 1, 4, 1])
+
+    def test_dtypes(self):
+        # Test with different data types
+        for dtype in [np.int16, np.uint16, np.int32,
+                      np.uint32, np.int64, np.uint64]:
+            coords = np.array(
+                [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0]], dtype=dtype)
+            shape = (5, 8)
+            uncoords = 8*coords[0]+coords[1]
+            assert_equal(np.ravel_multi_index(coords, shape), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape))
+            uncoords = coords[0]+5*coords[1]
+            assert_equal(
+                np.ravel_multi_index(coords, shape, order='F'), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape, order='F'))
+
+            coords = np.array(
+                [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0], [1, 3, 1, 0, 9, 5]],
+                dtype=dtype)
+            shape = (5, 8, 10)
+            uncoords = 10*(8*coords[0]+coords[1])+coords[2]
+            assert_equal(np.ravel_multi_index(coords, shape), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape))
+            uncoords = coords[0]+5*(coords[1]+8*coords[2])
+            assert_equal(
+                np.ravel_multi_index(coords, shape, order='F'), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape, order='F'))
+
+    def test_clipmodes(self):
+        # Test clipmodes
+        assert_equal(
+            np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12), mode='wrap'),
+            np.ravel_multi_index([1, 1, 6, 2], (4, 3, 7, 12)))
+        assert_equal(np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12),
+                                          mode=(
+                                              'wrap', 'raise', 'clip', 'raise')),
+                     np.ravel_multi_index([1, 1, 0, 2], (4, 3, 7, 12)))
+        assert_raises(
+            ValueError, np.ravel_multi_index, [5, 1, -1, 2], (4, 3, 7, 12))
+
+
+class TestGrid(TestCase):
+    def test_basic(self):
+        a = mgrid[-1:1:10j]
+        b = mgrid[-1:1:0.1]
+        assert_(a.shape == (10,))
+        assert_(b.shape == (20,))
+        assert_(a[0] == -1)
+        assert_almost_equal(a[-1], 1)
+        assert_(b[0] == -1)
+        assert_almost_equal(b[1]-b[0], 0.1, 11)
+        assert_almost_equal(b[-1], b[0]+19*0.1, 11)
+        assert_almost_equal(a[1]-a[0], 2.0/9.0, 11)
+
+    def test_linspace_equivalence(self):
+        y, st = np.linspace(2, 10, retstep=1)
+        assert_almost_equal(st, 8/49.0)
+        assert_array_almost_equal(y, mgrid[2:10:50j], 13)
+
+    def test_nd(self):
+        c = mgrid[-1:1:10j, -2:2:10j]
+        d = mgrid[-1:1:0.1, -2:2:0.2]
+        assert_(c.shape == (2, 10, 10))
+        assert_(d.shape == (2, 20, 20))
+        assert_array_equal(c[0][0, :], -np.ones(10, 'd'))
+        assert_array_equal(c[1][:, 0], -2*np.ones(10, 'd'))
+        assert_array_almost_equal(c[0][-1, :], np.ones(10, 'd'), 11)
+        assert_array_almost_equal(c[1][:, -1], 2*np.ones(10, 'd'), 11)
+        assert_array_almost_equal(d[0, 1, :] - d[0, 0, :],
+                                  0.1*np.ones(20, 'd'), 11)
+        assert_array_almost_equal(d[1, :, 1] - d[1, :, 0],
+                                  0.2*np.ones(20, 'd'), 11)
+
+
+class TestConcatenator(TestCase):
+    def test_1d(self):
+        assert_array_equal(r_[1, 2, 3, 4, 5, 6], np.array([1, 2, 3, 4, 5, 6]))
+        b = np.ones(5)
+        c = r_[b, 0, 0, b]
+        assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1])
+
+    def test_mixed_type(self):
+        g = r_[10.1, 1:10]
+        assert_(g.dtype == 'f8')
+
+    def test_more_mixed_type(self):
+        g = r_[-10.1, np.array([1]), np.array([2, 3, 4]), 10.0]
+        assert_(g.dtype == 'f8')
+
+    def test_2d(self):
+        b = np.random.rand(5, 5)
+        c = np.random.rand(5, 5)
+        d = r_['1', b, c]  # append columns
+        assert_(d.shape == (5, 10))
+        assert_array_equal(d[:, :5], b)
+        assert_array_equal(d[:, 5:], c)
+        d = r_[b, c]
+        assert_(d.shape == (10, 5))
+        assert_array_equal(d[:5, :], b)
+        assert_array_equal(d[5:, :], c)
+
+
+class TestNdenumerate(TestCase):
+    def test_basic(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(list(ndenumerate(a)),
+                     [((0, 0), 1), ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)])
+
+
+class TestIndexExpression(TestCase):
+    def test_regression_1(self):
+        # ticket #1196
+        a = np.arange(2)
+        assert_equal(a[:-1], a[s_[:-1]])
+        assert_equal(a[:-1], a[index_exp[:-1]])
+
+    def test_simple_1(self):
+        a = np.random.rand(4, 5, 6)
+
+        assert_equal(a[:, :3, [1, 2]], a[index_exp[:, :3, [1, 2]]])
+        assert_equal(a[:, :3, [1, 2]], a[s_[:, :3, [1, 2]]])
+
+
+class TestIx_(TestCase):
+    def test_regression_1(self):
+        # Test empty inputs create ouputs of indexing type, gh-5804
+        # Test both lists and arrays
+        for func in (range, np.arange):
+            a, = np.ix_(func(0))
+            assert_equal(a.dtype, np.intp)
+
+    def test_shape_and_dtype(self):
+        sizes = (4, 5, 3, 2)
+        # Test both lists and arrays
+        for func in (range, np.arange):
+            arrays = np.ix_(*[func(sz) for sz in sizes])
+            for k, (a, sz) in enumerate(zip(arrays, sizes)):
+                assert_equal(a.shape[k], sz)
+                assert_(all(sh == 1 for j, sh in enumerate(a.shape) if j != k))
+                assert_(np.issubdtype(a.dtype, int))
+
+    def test_bool(self):
+        bool_a = [True, False, True, True]
+        int_a, = np.nonzero(bool_a)
+        assert_equal(np.ix_(bool_a)[0], int_a)
+
+    def test_1d_only(self):
+        idx2d = [[1, 2, 3], [4, 5, 6]]
+        assert_raises(ValueError, np.ix_, idx2d)
+
+    def test_repeated_input(self):
+        length_of_vector = 5
+        x = np.arange(length_of_vector)
+        out = ix_(x, x)
+        assert_equal(out[0].shape, (length_of_vector, 1))
+        assert_equal(out[1].shape, (1, length_of_vector))
+        # check that input shape is not modified
+        assert_equal(x.shape, (length_of_vector,))
+
+
+def test_c_():
+    a = np.c_[np.array([[1, 2, 3]]), 0, 0, np.array([[4, 5, 6]])]
+    assert_equal(a, [[1, 2, 3, 0, 0, 4, 5, 6]])
+
+
+def test_fill_diagonal():
+    a = np.zeros((3, 3), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5]]))
+
+    #Test tall matrix
+    a = np.zeros((10, 3), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0]]))
+
+    #Test tall matrix wrap
+    a = np.zeros((10, 3), int)
+    fill_diagonal(a, 5, True)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [5, 0, 0],
+                  [0, 5, 0]]))
+
+    #Test wide matrix
+    a = np.zeros((3, 10), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+                  [0, 5, 0, 0, 0, 0, 0, 0, 0, 0],
+                  [0, 0, 5, 0, 0, 0, 0, 0, 0, 0]]))
+
+    # The same function can operate on a 4-d array:
+    a = np.zeros((3, 3, 3, 3), int)
+    fill_diagonal(a, 4)
+    i = np.array([0, 1, 2])
+    yield (assert_equal, np.where(a != 0), (i, i, i, i))
+
+
+def test_diag_indices():
+    di = diag_indices(4)
+    a = np.array([[1, 2, 3, 4],
+               [5, 6, 7, 8],
+               [9, 10, 11, 12],
+               [13, 14, 15, 16]])
+    a[di] = 100
+    yield (assert_array_equal, a,
+           np.array([[100, 2, 3, 4],
+                  [5, 100, 7, 8],
+                  [9, 10, 100, 12],
+                  [13, 14, 15, 100]]))
+
+    # Now, we create indices to manipulate a 3-d array:
+    d3 = diag_indices(2, 3)
+
+    # And use it to set the diagonal of a zeros array to 1:
+    a = np.zeros((2, 2, 2), int)
+    a[d3] = 1
+    yield (assert_array_equal, a,
+           np.array([[[1, 0],
+                   [0, 0]],
+
+                  [[0, 0],
+                   [0, 1]]]))
+
+
+def test_diag_indices_from():
+    x = np.random.random((4, 4))
+    r, c = diag_indices_from(x)
+    assert_array_equal(r, np.arange(4))
+    assert_array_equal(c, np.arange(4))
+
+
+def test_ndindex():
+    x = list(ndindex(1, 2, 3))
+    expected = [ix for ix, e in ndenumerate(np.zeros((1, 2, 3)))]
+    assert_array_equal(x, expected)
+
+    x = list(ndindex((1, 2, 3)))
+    assert_array_equal(x, expected)
+
+    # Test use of scalars and tuples
+    x = list(ndindex((3,)))
+    assert_array_equal(x, list(ndindex(3)))
+
+    # Make sure size argument is optional
+    x = list(ndindex())
+    assert_equal(x, [()])
+
+    x = list(ndindex(()))
+    assert_equal(x, [()])
+
+    # Make sure 0-sized ndindex works correctly
+    x = list(ndindex(*[0]))
+    assert_equal(x, [])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_io.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
new file mode 100644
index 0000000000..226dc88faa
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
@@ -0,0 +1,1888 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import gzip
+import os
+import threading
+from tempfile import NamedTemporaryFile
+import time
+import warnings
+import gc
+from io import BytesIO
+from datetime import datetime
+
+import numpy as np
+import numpy.ma as ma
+from numpy.lib._iotools import ConverterError, ConversionWarning
+from numpy.compat import asbytes, bytes, unicode
+from numpy.ma.testutils import assert_equal
+from numpy.testing import (
+    TestCase, run_module_suite, assert_warns, assert_,
+    assert_raises_regex, assert_raises, assert_allclose,
+    assert_array_equal,temppath
+)
+from numpy.testing.utils import tempdir
+
+
+class TextIO(BytesIO):
+    """Helper IO class.
+
+    Writes encode strings to bytes if needed, reads return bytes.
+    This makes it easier to emulate files opened in binary mode
+    without needing to explicitly convert strings to bytes in
+    setting up the test data.
+
+    """
+    def __init__(self, s=""):
+        BytesIO.__init__(self, asbytes(s))
+
+    def write(self, s):
+        BytesIO.write(self, asbytes(s))
+
+    def writelines(self, lines):
+        BytesIO.writelines(self, [asbytes(s) for s in lines])
+
+
+MAJVER, MINVER = sys.version_info[:2]
+IS_64BIT = sys.maxsize > 2**32
+
+
+def strptime(s, fmt=None):
+    """
+    This function is available in the datetime module only from Python >=
+    2.5.
+
+    """
+    if sys.version_info[0] >= 3:
+        return datetime(*time.strptime(s.decode('latin1'), fmt)[:3])
+    else:
+        return datetime(*time.strptime(s, fmt)[:3])
+
+
+class RoundtripTest(object):
+    def roundtrip(self, save_func, *args, **kwargs):
+        """
+        save_func : callable
+            Function used to save arrays to file.
+        file_on_disk : bool
+            If true, store the file on disk, instead of in a
+            string buffer.
+        save_kwds : dict
+            Parameters passed to `save_func`.
+        load_kwds : dict
+            Parameters passed to `numpy.load`.
+        args : tuple of arrays
+            Arrays stored to file.
+
+        """
+        save_kwds = kwargs.get('save_kwds', {})
+        load_kwds = kwargs.get('load_kwds', {})
+        file_on_disk = kwargs.get('file_on_disk', False)
+
+        if file_on_disk:
+            target_file = NamedTemporaryFile(delete=False)
+            load_file = target_file.name
+        else:
+            target_file = BytesIO()
+            load_file = target_file
+
+        try:
+            arr = args
+
+            save_func(target_file, *arr, **save_kwds)
+            target_file.flush()
+            target_file.seek(0)
+
+            if sys.platform == 'win32' and not isinstance(target_file, BytesIO):
+                target_file.close()
+
+            arr_reloaded = np.load(load_file, **load_kwds)
+
+            self.arr = arr
+            self.arr_reloaded = arr_reloaded
+        finally:
+            if not isinstance(target_file, BytesIO):
+                target_file.close()
+                # holds an open file descriptor so it can't be deleted on win
+                if not isinstance(arr_reloaded, np.lib.npyio.NpzFile):
+                    os.remove(target_file.name)
+
+    def check_roundtrips(self, a):
+        self.roundtrip(a)
+        self.roundtrip(a, file_on_disk=True)
+        self.roundtrip(np.asfortranarray(a))
+        self.roundtrip(np.asfortranarray(a), file_on_disk=True)
+        if a.shape[0] > 1:
+            # neither C nor Fortran contiguous for 2D arrays or more
+            self.roundtrip(np.asfortranarray(a)[1:])
+            self.roundtrip(np.asfortranarray(a)[1:], file_on_disk=True)
+
+    def test_array(self):
+        a = np.array([], float)
+        self.check_roundtrips(a)
+
+        a = np.array([[1, 2], [3, 4]], float)
+        self.check_roundtrips(a)
+
+        a = np.array([[1, 2], [3, 4]], int)
+        self.check_roundtrips(a)
+
+        a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.csingle)
+        self.check_roundtrips(a)
+
+        a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.cdouble)
+        self.check_roundtrips(a)
+
+    def test_array_object(self):
+        if sys.version_info[:2] >= (2, 7):
+            a = np.array([], object)
+            self.check_roundtrips(a)
+
+            a = np.array([[1, 2], [3, 4]], object)
+            self.check_roundtrips(a)
+        # Fails with UnpicklingError: could not find MARK on Python 2.6
+
+    def test_1D(self):
+        a = np.array([1, 2, 3, 4], int)
+        self.roundtrip(a)
+
+    @np.testing.dec.knownfailureif(sys.platform == 'win32', "Fail on Win32")
+    def test_mmap(self):
+        a = np.array([[1, 2.5], [4, 7.3]])
+        self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'})
+
+        a = np.asfortranarray([[1, 2.5], [4, 7.3]])
+        self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'})
+
+    def test_record(self):
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        self.check_roundtrips(a)
+
+    def test_format_2_0(self):
+        dt = [(("%d" % i) * 100, float) for i in range(500)]
+        a = np.ones(1000, dtype=dt)
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', UserWarning)
+            self.check_roundtrips(a)
+
+
+class TestSaveLoad(RoundtripTest, TestCase):
+    def roundtrip(self, *args, **kwargs):
+        RoundtripTest.roundtrip(self, np.save, *args, **kwargs)
+        assert_equal(self.arr[0], self.arr_reloaded)
+        assert_equal(self.arr[0].dtype, self.arr_reloaded.dtype)
+        assert_equal(self.arr[0].flags.fnc, self.arr_reloaded.flags.fnc)
+
+
+class TestSavezLoad(RoundtripTest, TestCase):
+    def roundtrip(self, *args, **kwargs):
+        RoundtripTest.roundtrip(self, np.savez, *args, **kwargs)
+        try:
+            for n, arr in enumerate(self.arr):
+                reloaded = self.arr_reloaded['arr_%d' % n]
+                assert_equal(arr, reloaded)
+                assert_equal(arr.dtype, reloaded.dtype)
+                assert_equal(arr.flags.fnc, reloaded.flags.fnc)
+        finally:
+            # delete tempfile, must be done here on windows
+            if self.arr_reloaded.fid:
+                self.arr_reloaded.fid.close()
+                os.remove(self.arr_reloaded.fid.name)
+
+    @np.testing.dec.skipif(not IS_64BIT, "Works only with 64bit systems")
+    @np.testing.dec.slow
+    def test_big_arrays(self):
+        L = (1 << 31) + 100000
+        a = np.empty(L, dtype=np.uint8)
+        with temppath(prefix="numpy_test_big_arrays_", suffix=".npz") as tmp:
+            np.savez(tmp, a=a)
+            del a
+            npfile = np.load(tmp)
+            a = npfile['a']  # Should succeed
+            npfile.close()
+            del a  # Avoid pyflakes unused variable warning.
+
+    def test_multiple_arrays(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        self.roundtrip(a, b)
+
+    def test_named_arrays(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        c = BytesIO()
+        np.savez(c, file_a=a, file_b=b)
+        c.seek(0)
+        l = np.load(c)
+        assert_equal(a, l['file_a'])
+        assert_equal(b, l['file_b'])
+
+    def test_BagObj(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        c = BytesIO()
+        np.savez(c, file_a=a, file_b=b)
+        c.seek(0)
+        l = np.load(c)
+        assert_equal(sorted(dir(l.f)), ['file_a','file_b'])
+        assert_equal(a, l.f.file_a)
+        assert_equal(b, l.f.file_b)
+
+    def test_savez_filename_clashes(self):
+        # Test that issue #852 is fixed
+        # and savez functions in multithreaded environment
+
+        def writer(error_list):
+            with temppath(suffix='.npz') as tmp:
+                arr = np.random.randn(500, 500)
+                try:
+                    np.savez(tmp, arr=arr)
+                except OSError as err:
+                    error_list.append(err)
+
+        errors = []
+        threads = [threading.Thread(target=writer, args=(errors,))
+                   for j in range(3)]
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+        if errors:
+            raise AssertionError(errors)
+
+    def test_not_closing_opened_fid(self):
+        # Test that issue #2178 is fixed:
+        # verify could seek on 'loaded' file
+        with temppath(suffix='.npz') as tmp:
+            with open(tmp, 'wb') as fp:
+                np.savez(fp, data='LOVELY LOAD')
+            with open(tmp, 'rb', 10000) as fp:
+                fp.seek(0)
+                assert_(not fp.closed)
+                np.load(fp)['data']
+                # fp must not get closed by .load
+                assert_(not fp.closed)
+                fp.seek(0)
+                assert_(not fp.closed)
+
+    def test_closing_fid(self):
+        # Test that issue #1517 (too many opened files) remains closed
+        # It might be a "weak" test since failed to get triggered on
+        # e.g. Debian sid of 2012 Jul 05 but was reported to
+        # trigger the failure on Ubuntu 10.04:
+        # http://projects.scipy.org/numpy/ticket/1517#comment:2
+        with temppath(suffix='.npz') as tmp:
+            np.savez(tmp, data='LOVELY LOAD')
+            # We need to check if the garbage collector can properly close
+            # numpy npz file returned by np.load when their reference count
+            # goes to zero.  Python 3 running in debug mode raises a
+            # ResourceWarning when file closing is left to the garbage
+            # collector, so we catch the warnings.  Because ResourceWarning
+            # is unknown in Python < 3.x, we take the easy way out and
+            # catch all warnings.
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore")
+                for i in range(1, 1025):
+                    try:
+                        np.load(tmp)["data"]
+                    except Exception as e:
+                        msg = "Failed to load data from a file: %s" % e
+                        raise AssertionError(msg)
+
+    def test_closing_zipfile_after_load(self):
+        # Check that zipfile owns file and can close it.  This needs to
+        # pass a file name to load for the test. On windows failure will
+        # cause a second error will be raised when the attempt to remove
+        # the open file is made.
+        prefix = 'numpy_test_closing_zipfile_after_load_'
+        with temppath(suffix='.npz', prefix=prefix) as tmp:
+            np.savez(tmp, lab='place holder')
+            data = np.load(tmp)
+            fp = data.zip.fp
+            data.close()
+            assert_(fp.closed)
+
+
+class TestSaveTxt(TestCase):
+    def test_array(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        fmt = "%.18e"
+        c = BytesIO()
+        np.savetxt(c, a, fmt=fmt)
+        c.seek(0)
+        assert_equal(c.readlines(),
+                     [asbytes((fmt + ' ' + fmt + '\n') % (1, 2)),
+                      asbytes((fmt + ' ' + fmt + '\n') % (3, 4))])
+
+        a = np.array([[1, 2], [3, 4]], int)
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1 2\n', b'3 4\n'])
+
+    def test_1D(self):
+        a = np.array([1, 2, 3, 4], int)
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'1\n', b'2\n', b'3\n', b'4\n'])
+
+    def test_record(self):
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1 2\n', b'3 4\n'])
+
+    def test_delimiter(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        c = BytesIO()
+        np.savetxt(c, a, delimiter=',', fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1,2\n', b'3,4\n'])
+
+    def test_format(self):
+        a = np.array([(1, 2), (3, 4)])
+        c = BytesIO()
+        # Sequence of formats
+        np.savetxt(c, a, fmt=['%02d', '%3.1f'])
+        c.seek(0)
+        assert_equal(c.readlines(), [b'01 2.0\n', b'03 4.0\n'])
+
+        # A single multiformat string
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%02d : %3.1f')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n'])
+
+        # Specify delimiter, should be overiden
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%02d : %3.1f', delimiter=',')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n'])
+
+        # Bad fmt, should raise a ValueError
+        c = BytesIO()
+        assert_raises(ValueError, np.savetxt, c, a, fmt=99)
+
+    def test_header_footer(self):
+        # Test the functionality of the header and footer keyword argument.
+
+        c = BytesIO()
+        a = np.array([(1, 2), (3, 4)], dtype=np.int)
+        test_header_footer = 'Test header / footer'
+        # Test the header keyword argument
+        np.savetxt(c, a, fmt='%1d', header=test_header_footer)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('# ' + test_header_footer + '\n1 2\n3 4\n'))
+        # Test the footer keyword argument
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%1d', footer=test_header_footer)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('1 2\n3 4\n# ' + test_header_footer + '\n'))
+        # Test the commentstr keyword argument used on the header
+        c = BytesIO()
+        commentstr = '% '
+        np.savetxt(c, a, fmt='%1d',
+                   header=test_header_footer, comments=commentstr)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes(commentstr + test_header_footer + '\n' + '1 2\n3 4\n'))
+        # Test the commentstr keyword argument used on the footer
+        c = BytesIO()
+        commentstr = '% '
+        np.savetxt(c, a, fmt='%1d',
+                   footer=test_header_footer, comments=commentstr)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('1 2\n3 4\n' + commentstr + test_header_footer + '\n'))
+
+    def test_file_roundtrip(self):
+        with temppath() as name:
+            a = np.array([(1, 2), (3, 4)])
+            np.savetxt(name, a)
+            b = np.loadtxt(name)
+            assert_array_equal(a, b)
+
+    def test_complex_arrays(self):
+        ncols = 2
+        nrows = 2
+        a = np.zeros((ncols, nrows), dtype=np.complex128)
+        re = np.pi
+        im = np.e
+        a[:] = re + 1.0j * im
+
+        # One format only
+        c = BytesIO()
+        np.savetxt(c, a, fmt=' %+.3e')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b' ( +3.142e+00+ +2.718e+00j)  ( +3.142e+00+ +2.718e+00j)\n',
+             b' ( +3.142e+00+ +2.718e+00j)  ( +3.142e+00+ +2.718e+00j)\n'])
+
+        # One format for each real and imaginary part
+        c = BytesIO()
+        np.savetxt(c, a, fmt='  %+.3e' * 2 * ncols)
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b'  +3.142e+00  +2.718e+00  +3.142e+00  +2.718e+00\n',
+             b'  +3.142e+00  +2.718e+00  +3.142e+00  +2.718e+00\n'])
+
+        # One format for each complex number
+        c = BytesIO()
+        np.savetxt(c, a, fmt=['(%.3e%+.3ej)'] * ncols)
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n',
+             b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n'])
+
+    def test_custom_writer(self):
+
+        class CustomWriter(list):
+            def write(self, text):
+                self.extend(text.split(b'\n'))
+
+        w = CustomWriter()
+        a = np.array([(1, 2), (3, 4)])
+        np.savetxt(w, a)
+        b = np.loadtxt(w)
+        assert_array_equal(a, b)
+
+
+class TestLoadTxt(TestCase):
+    def test_record(self):
+        c = TextIO()
+        c.write('1 2\n3 4')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=[('x', np.int32), ('y', np.int32)])
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        assert_array_equal(x, a)
+
+        d = TextIO()
+        d.write('M 64.0 75.0\nF 25.0 60.0')
+        d.seek(0)
+        mydescriptor = {'names': ('gender', 'age', 'weight'),
+                        'formats': ('S1', 'i4', 'f4')}
+        b = np.array([('M', 64.0, 75.0),
+                      ('F', 25.0, 60.0)], dtype=mydescriptor)
+        y = np.loadtxt(d, dtype=mydescriptor)
+        assert_array_equal(y, b)
+
+    def test_array(self):
+        c = TextIO()
+        c.write('1 2\n3 4')
+
+        c.seek(0)
+        x = np.loadtxt(c, dtype=np.int)
+        a = np.array([[1, 2], [3, 4]], int)
+        assert_array_equal(x, a)
+
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float)
+        a = np.array([[1, 2], [3, 4]], float)
+        assert_array_equal(x, a)
+
+    def test_1D(self):
+        c = TextIO()
+        c.write('1\n2\n3\n4\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int)
+        a = np.array([1, 2, 3, 4], int)
+        assert_array_equal(x, a)
+
+        c = TextIO()
+        c.write('1,2,3,4\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',')
+        a = np.array([1, 2, 3, 4], int)
+        assert_array_equal(x, a)
+
+    def test_missing(self):
+        c = TextIO()
+        c.write('1,2,3,,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       converters={3: lambda s: int(s or - 999)})
+        a = np.array([1, 2, 3, -999, 5], int)
+        assert_array_equal(x, a)
+
+    def test_converters_with_usecols(self):
+        c = TextIO()
+        c.write('1,2,3,,5\n6,7,8,9,10\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       converters={3: lambda s: int(s or - 999)},
+                       usecols=(1, 3,))
+        a = np.array([[2, -999], [7, 9]], int)
+        assert_array_equal(x, a)
+
+    def test_comments_unicode(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=unicode('#'))
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_comments_byte(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=b'#')
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_comments_multiple(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3\n@ comment2\n4,5,6 // comment3')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=['#', '@', '//'])
+        a = np.array([[1, 2, 3], [4, 5, 6]], int)
+        assert_array_equal(x, a)
+
+    def test_comments_multi_chars(self):
+        c = TextIO()
+        c.write('/* comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments='/*')
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+        # Check that '/*' is not transformed to ['/', '*']
+        c = TextIO()
+        c.write('*/ comment\n1,2,3,5\n')
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, dtype=int, delimiter=',',
+                      comments='/*')
+
+    def test_skiprows(self):
+        c = TextIO()
+        c.write('comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       skiprows=1)
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       skiprows=1)
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_usecols(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        c = BytesIO()
+        np.savetxt(c, a)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=(1,))
+        assert_array_equal(x, a[:, 1])
+
+        a = np.array([[1, 2, 3], [3, 4, 5]], float)
+        c = BytesIO()
+        np.savetxt(c, a)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=(1, 2))
+        assert_array_equal(x, a[:, 1:])
+
+        # Testing with arrays instead of tuples.
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=np.array([1, 2]))
+        assert_array_equal(x, a[:, 1:])
+
+        # Checking with dtypes defined converters.
+        data = '''JOE 70.1 25.3
+                BOB 60.5 27.9
+                '''
+        c = TextIO(data)
+        names = ['stid', 'temp']
+        dtypes = ['S4', 'f8']
+        arr = np.loadtxt(c, usecols=(0, 2), dtype=list(zip(names, dtypes)))
+        assert_equal(arr['stid'], [b"JOE", b"BOB"])
+        assert_equal(arr['temp'], [25.3, 27.9])
+
+    def test_fancy_dtype(self):
+        c = TextIO()
+        c.write('1,2,3.0\n4,5,6.0\n')
+        c.seek(0)
+        dt = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        x = np.loadtxt(c, dtype=dt, delimiter=',')
+        a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dt)
+        assert_array_equal(x, a)
+
+    def test_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 3))])
+        x = np.loadtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_3d_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6 7 8 9 10 11 12")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 2, 3))])
+        x = np.loadtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0,
+                       [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_empty_file(self):
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="loadtxt: Empty input file:")
+            c = TextIO()
+            x = np.loadtxt(c)
+            assert_equal(x.shape, (0,))
+            x = np.loadtxt(c, dtype=np.int64)
+            assert_equal(x.shape, (0,))
+            assert_(x.dtype == np.int64)
+
+    def test_unused_converter(self):
+        c = TextIO()
+        c.writelines(['1 21\n', '3 42\n'])
+        c.seek(0)
+        data = np.loadtxt(c, usecols=(1,),
+                          converters={0: lambda s: int(s, 16)})
+        assert_array_equal(data, [21, 42])
+
+        c.seek(0)
+        data = np.loadtxt(c, usecols=(1,),
+                          converters={1: lambda s: int(s, 16)})
+        assert_array_equal(data, [33, 66])
+
+    def test_dtype_with_object(self):
+        # Test using an explicit dtype with an object
+        data = """ 1; 2001-01-01
+                   2; 2002-01-31 """
+        ndtype = [('idx', int), ('code', np.object)]
+        func = lambda s: strptime(s.strip(), "%Y-%m-%d")
+        converters = {1: func}
+        test = np.loadtxt(TextIO(data), delimiter=";", dtype=ndtype,
+                          converters=converters)
+        control = np.array(
+            [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))],
+            dtype=ndtype)
+        assert_equal(test, control)
+
+    def test_uint64_type(self):
+        tgt = (9223372043271415339, 9223372043271415853)
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.uint64)
+        assert_equal(res, tgt)
+
+    def test_int64_type(self):
+        tgt = (-9223372036854775807, 9223372036854775807)
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.int64)
+        assert_equal(res, tgt)
+
+    def test_from_float_hex(self):
+        # IEEE doubles and floats only, otherwise the float32
+        # conversion may fail.
+        tgt = np.logspace(-10, 10, 5).astype(np.float32)
+        tgt = np.hstack((tgt, -tgt)).astype(np.float)
+        inp = '\n'.join(map(float.hex, tgt))
+        c = TextIO()
+        c.write(inp)
+        for dt in [np.float, np.float32]:
+            c.seek(0)
+            res = np.loadtxt(c, dtype=dt)
+            assert_equal(res, tgt, err_msg="%s" % dt)
+
+    def test_from_complex(self):
+        tgt = (complex(1, 1), complex(1, -1))
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.complex)
+        assert_equal(res, tgt)
+
+    def test_universal_newline(self):
+        with temppath() as name:
+            with open(name, 'w') as f:
+                f.write('1 21\r3 42\r')
+            data = np.loadtxt(name)
+        assert_array_equal(data, [[1, 21], [3, 42]])
+
+    def test_empty_field_after_tab(self):
+        c = TextIO()
+        c.write('1 \t2 \t3\tstart \n4\t5\t6\t  \n7\t8\t9.5\t')
+        c.seek(0)
+        dt = {'names': ('x', 'y', 'z', 'comment'),
+              'formats': ('<i4', '<i4', '<f4', '|S8')}
+        x = np.loadtxt(c, dtype=dt, delimiter='\t')
+        a = np.array([b'start ', b'  ', b''])
+        assert_array_equal(x['comment'], a)
+
+    def test_structure_unpack(self):
+        txt = TextIO("M 21 72\nF 35 58")
+        dt = {'names': ('a', 'b', 'c'), 'formats': ('|S1', '<i4', '<f4')}
+        a, b, c = np.loadtxt(txt, dtype=dt, unpack=True)
+        assert_(a.dtype.str == '|S1')
+        assert_(b.dtype.str == '<i4')
+        assert_(c.dtype.str == '<f4')
+        assert_array_equal(a, np.array([b'M', b'F']))
+        assert_array_equal(b, np.array([21, 35]))
+        assert_array_equal(c, np.array([72.,  58.]))
+
+    def test_ndmin_keyword(self):
+        c = TextIO()
+        c.write('1,2,3\n4,5,6')
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, ndmin=3)
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, ndmin=1.5)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',', ndmin=1)
+        a = np.array([[1, 2, 3], [4, 5, 6]])
+        assert_array_equal(x, a)
+
+        d = TextIO()
+        d.write('0,1,2')
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=2)
+        assert_(x.shape == (1, 3))
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=1)
+        assert_(x.shape == (3,))
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=0)
+        assert_(x.shape == (3,))
+
+        e = TextIO()
+        e.write('0\n1\n2')
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=2)
+        assert_(x.shape == (3, 1))
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=1)
+        assert_(x.shape == (3,))
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=0)
+        assert_(x.shape == (3,))
+
+        # Test ndmin kw with empty file.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="loadtxt: Empty input file:")
+            f = TextIO()
+            assert_(np.loadtxt(f, ndmin=2).shape == (0, 1,))
+            assert_(np.loadtxt(f, ndmin=1).shape == (0,))
+
+    def test_generator_source(self):
+        def count():
+            for i in range(10):
+                yield "%d" % i
+
+        res = np.loadtxt(count())
+        assert_array_equal(res, np.arange(10))
+
+    def test_bad_line(self):
+        c = TextIO()
+        c.write('1 2 3\n4 5 6\n2 3')
+        c.seek(0)
+
+        # Check for exception and that exception contains line number
+        assert_raises_regex(ValueError, "3", np.loadtxt, c)
+
+    def test_none_as_string(self):
+        # gh-5155, None should work as string when format demands it
+        c = TextIO()
+        c.write('100,foo,200\n300,None,400')
+        c.seek(0)
+        dt = np.dtype([('x', int), ('a', 'S10'), ('y', int)])
+        np.loadtxt(c, delimiter=',', dtype=dt, comments=None)  # Should succeed
+
+
+class Testfromregex(TestCase):
+    # np.fromregex expects files opened in binary mode.
+    def test_record(self):
+        c = TextIO()
+        c.write('1.312 foo\n1.534 bar\n4.444 qux')
+        c.seek(0)
+
+        dt = [('num', np.float64), ('val', 'S3')]
+        x = np.fromregex(c, r"([0-9.]+)\s+(...)", dt)
+        a = np.array([(1.312, 'foo'), (1.534, 'bar'), (4.444, 'qux')],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_record_2(self):
+        c = TextIO()
+        c.write('1312 foo\n1534 bar\n4444 qux')
+        c.seek(0)
+
+        dt = [('num', np.int32), ('val', 'S3')]
+        x = np.fromregex(c, r"(\d+)\s+(...)", dt)
+        a = np.array([(1312, 'foo'), (1534, 'bar'), (4444, 'qux')],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_record_3(self):
+        c = TextIO()
+        c.write('1312 foo\n1534 bar\n4444 qux')
+        c.seek(0)
+
+        dt = [('num', np.float64)]
+        x = np.fromregex(c, r"(\d+)\s+...", dt)
+        a = np.array([(1312,), (1534,), (4444,)], dtype=dt)
+        assert_array_equal(x, a)
+
+
+#####--------------------------------------------------------------------------
+
+
+class TestFromTxt(TestCase):
+    #
+    def test_record(self):
+        # Test w/ explicit dtype
+        data = TextIO('1 2\n3 4')
+        test = np.ndfromtxt(data, dtype=[('x', np.int32), ('y', np.int32)])
+        control = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        assert_equal(test, control)
+        #
+        data = TextIO('M 64.0 75.0\nF 25.0 60.0')
+        descriptor = {'names': ('gender', 'age', 'weight'),
+                      'formats': ('S1', 'i4', 'f4')}
+        control = np.array([('M', 64.0, 75.0), ('F', 25.0, 60.0)],
+                           dtype=descriptor)
+        test = np.ndfromtxt(data, dtype=descriptor)
+        assert_equal(test, control)
+
+    def test_array(self):
+        # Test outputing a standard ndarray
+        data = TextIO('1 2\n3 4')
+        control = np.array([[1, 2], [3, 4]], dtype=int)
+        test = np.ndfromtxt(data, dtype=int)
+        assert_array_equal(test, control)
+        #
+        data.seek(0)
+        control = np.array([[1, 2], [3, 4]], dtype=float)
+        test = np.loadtxt(data, dtype=float)
+        assert_array_equal(test, control)
+
+    def test_1D(self):
+        # Test squeezing to 1D
+        control = np.array([1, 2, 3, 4], int)
+        #
+        data = TextIO('1\n2\n3\n4\n')
+        test = np.ndfromtxt(data, dtype=int)
+        assert_array_equal(test, control)
+        #
+        data = TextIO('1,2,3,4\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',')
+        assert_array_equal(test, control)
+
+    def test_comments(self):
+        # Test the stripping of comments
+        control = np.array([1, 2, 3, 5], int)
+        # Comment on its own line
+        data = TextIO('# comment\n1,2,3,5\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',', comments='#')
+        assert_equal(test, control)
+        # Comment at the end of a line
+        data = TextIO('1,2,3,5# comment\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',', comments='#')
+        assert_equal(test, control)
+
+    def test_skiprows(self):
+        # Test row skipping
+        control = np.array([1, 2, 3, 5], int)
+        kwargs = dict(dtype=int, delimiter=',')
+        #
+        data = TextIO('comment\n1,2,3,5\n')
+        test = np.ndfromtxt(data, skip_header=1, **kwargs)
+        assert_equal(test, control)
+        #
+        data = TextIO('# comment\n1,2,3,5\n')
+        test = np.loadtxt(data, skiprows=1, **kwargs)
+        assert_equal(test, control)
+
+    def test_skip_footer(self):
+        data = ["# %i" % i for i in range(1, 6)]
+        data.append("A, B, C")
+        data.extend(["%i,%3.1f,%03s" % (i, i, i) for i in range(51)])
+        data[-1] = "99,99"
+        kwargs = dict(delimiter=",", names=True, skip_header=5, skip_footer=10)
+        test = np.genfromtxt(TextIO("\n".join(data)), **kwargs)
+        ctrl = np.array([("%f" % i, "%f" % i, "%f" % i) for i in range(41)],
+                        dtype=[(_, float) for _ in "ABC"])
+        assert_equal(test, ctrl)
+
+    def test_skip_footer_with_invalid(self):
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore")
+            basestr = '1 1\n2 2\n3 3\n4 4\n5  \n6  \n7  \n'
+            # Footer too small to get rid of all invalid values
+            assert_raises(ValueError, np.genfromtxt,
+                          TextIO(basestr), skip_footer=1)
+    #        except ValueError:
+    #            pass
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=1, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]))
+            #
+            a = np.genfromtxt(TextIO(basestr), skip_footer=3)
+            assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]))
+            #
+            basestr = '1 1\n2  \n3 3\n4 4\n5  \n6 6\n7 7\n'
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=1, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.], [6., 6.]]))
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=3, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.]]))
+
+    def test_header(self):
+        # Test retrieving a header
+        data = TextIO('gender age weight\nM 64.0 75.0\nF 25.0 60.0')
+        test = np.ndfromtxt(data, dtype=None, names=True)
+        control = {'gender': np.array([b'M', b'F']),
+                   'age': np.array([64.0, 25.0]),
+                   'weight': np.array([75.0, 60.0])}
+        assert_equal(test['gender'], control['gender'])
+        assert_equal(test['age'], control['age'])
+        assert_equal(test['weight'], control['weight'])
+
+    def test_auto_dtype(self):
+        # Test the automatic definition of the output dtype
+        data = TextIO('A 64 75.0 3+4j True\nBCD 25 60.0 5+6j False')
+        test = np.ndfromtxt(data, dtype=None)
+        control = [np.array([b'A', b'BCD']),
+                   np.array([64, 25]),
+                   np.array([75.0, 60.0]),
+                   np.array([3 + 4j, 5 + 6j]),
+                   np.array([True, False]), ]
+        assert_equal(test.dtype.names, ['f0', 'f1', 'f2', 'f3', 'f4'])
+        for (i, ctrl) in enumerate(control):
+            assert_equal(test['f%i' % i], ctrl)
+
+    def test_auto_dtype_uniform(self):
+        # Tests whether the output dtype can be uniformized
+        data = TextIO('1 2 3 4\n5 6 7 8\n')
+        test = np.ndfromtxt(data, dtype=None)
+        control = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        assert_equal(test, control)
+
+    def test_fancy_dtype(self):
+        # Check that a nested dtype isn't MIA
+        data = TextIO('1,2,3.0\n4,5,6.0\n')
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = np.ndfromtxt(data, dtype=fancydtype, delimiter=',')
+        control = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype)
+        assert_equal(test, control)
+
+    def test_names_overwrite(self):
+        # Test overwriting the names of the dtype
+        descriptor = {'names': ('g', 'a', 'w'),
+                      'formats': ('S1', 'i4', 'f4')}
+        data = TextIO(b'M 64.0 75.0\nF 25.0 60.0')
+        names = ('gender', 'age', 'weight')
+        test = np.ndfromtxt(data, dtype=descriptor, names=names)
+        descriptor['names'] = names
+        control = np.array([('M', 64.0, 75.0),
+                            ('F', 25.0, 60.0)], dtype=descriptor)
+        assert_equal(test, control)
+
+    def test_commented_header(self):
+        # Check that names can be retrieved even if the line is commented out.
+        data = TextIO("""
+#gender age weight
+M   21  72.100000
+F   35  58.330000
+M   33  21.99
+        """)
+        # The # is part of the first name and should be deleted automatically.
+        test = np.genfromtxt(data, names=True, dtype=None)
+        ctrl = np.array([('M', 21, 72.1), ('F', 35, 58.33), ('M', 33, 21.99)],
+                        dtype=[('gender', '|S1'), ('age', int), ('weight', float)])
+        assert_equal(test, ctrl)
+        # Ditto, but we should get rid of the first element
+        data = TextIO(b"""
+# gender age weight
+M   21  72.100000
+F   35  58.330000
+M   33  21.99
+        """)
+        test = np.genfromtxt(data, names=True, dtype=None)
+        assert_equal(test, ctrl)
+
+    def test_autonames_and_usecols(self):
+        # Tests names and usecols
+        data = TextIO('A B C D\n aaaa 121 45 9.1')
+        test = np.ndfromtxt(data, usecols=('A', 'C', 'D'),
+                            names=True, dtype=None)
+        control = np.array(('aaaa', 45, 9.1),
+                           dtype=[('A', '|S4'), ('C', int), ('D', float)])
+        assert_equal(test, control)
+
+    def test_converters_with_usecols(self):
+        # Test the combination user-defined converters and usecol
+        data = TextIO('1,2,3,,5\n6,7,8,9,10\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',',
+                            converters={3: lambda s: int(s or - 999)},
+                            usecols=(1, 3,))
+        control = np.array([[2, -999], [7, 9]], int)
+        assert_equal(test, control)
+
+    def test_converters_with_usecols_and_names(self):
+        # Tests names and usecols
+        data = TextIO('A B C D\n aaaa 121 45 9.1')
+        test = np.ndfromtxt(data, usecols=('A', 'C', 'D'), names=True,
+                            dtype=None, converters={'C': lambda s: 2 * int(s)})
+        control = np.array(('aaaa', 90, 9.1),
+                           dtype=[('A', '|S4'), ('C', int), ('D', float)])
+        assert_equal(test, control)
+
+    def test_converters_cornercases(self):
+        # Test the conversion to datetime.
+        converter = {
+            'date': lambda s: strptime(s, '%Y-%m-%d %H:%M:%SZ')}
+        data = TextIO('2009-02-03 12:00:00Z, 72214.0')
+        test = np.ndfromtxt(data, delimiter=',', dtype=None,
+                            names=['date', 'stid'], converters=converter)
+        control = np.array((datetime(2009, 2, 3), 72214.),
+                           dtype=[('date', np.object_), ('stid', float)])
+        assert_equal(test, control)
+
+    def test_converters_cornercases2(self):
+        # Test the conversion to datetime64.
+        converter = {
+            'date': lambda s: np.datetime64(strptime(s, '%Y-%m-%d %H:%M:%SZ'))}
+        data = TextIO('2009-02-03 12:00:00Z, 72214.0')
+        test = np.ndfromtxt(data, delimiter=',', dtype=None,
+                            names=['date', 'stid'], converters=converter)
+        control = np.array((datetime(2009, 2, 3), 72214.),
+                           dtype=[('date', 'datetime64[us]'), ('stid', float)])
+        assert_equal(test, control)
+
+    def test_unused_converter(self):
+        # Test whether unused converters are forgotten
+        data = TextIO("1 21\n  3 42\n")
+        test = np.ndfromtxt(data, usecols=(1,),
+                            converters={0: lambda s: int(s, 16)})
+        assert_equal(test, [21, 42])
+        #
+        data.seek(0)
+        test = np.ndfromtxt(data, usecols=(1,),
+                            converters={1: lambda s: int(s, 16)})
+        assert_equal(test, [33, 66])
+
+    def test_invalid_converter(self):
+        strip_rand = lambda x: float((b'r' in x.lower() and x.split()[-1]) or
+                                     (b'r' not in x.lower() and x.strip() or 0.0))
+        strip_per = lambda x: float((b'%' in x.lower() and x.split()[0]) or
+                                    (b'%' not in x.lower() and x.strip() or 0.0))
+        s = TextIO("D01N01,10/1/2003 ,1 %,R 75,400,600\r\n"
+                   "L24U05,12/5/2003, 2 %,1,300, 150.5\r\n"
+                   "D02N03,10/10/2004,R 1,,7,145.55")
+        kwargs = dict(
+            converters={2: strip_per, 3: strip_rand}, delimiter=",",
+            dtype=None)
+        assert_raises(ConverterError, np.genfromtxt, s, **kwargs)
+
+    def test_tricky_converter_bug1666(self):
+        # Test some corner cases
+        s = TextIO('q1,2\nq3,4')
+        cnv = lambda s: float(s[1:])
+        test = np.genfromtxt(s, delimiter=',', converters={0: cnv})
+        control = np.array([[1., 2.], [3., 4.]])
+        assert_equal(test, control)
+
+    def test_dtype_with_converters(self):
+        dstr = "2009; 23; 46"
+        test = np.ndfromtxt(TextIO(dstr,),
+                            delimiter=";", dtype=float, converters={0: bytes})
+        control = np.array([('2009', 23., 46)],
+                           dtype=[('f0', '|S4'), ('f1', float), ('f2', float)])
+        assert_equal(test, control)
+        test = np.ndfromtxt(TextIO(dstr,),
+                            delimiter=";", dtype=float, converters={0: float})
+        control = np.array([2009., 23., 46],)
+        assert_equal(test, control)
+
+    def test_dtype_with_converters_and_usecols(self):
+        dstr = "1,5,-1,1:1\n2,8,-1,1:n\n3,3,-2,m:n\n"
+        dmap = {'1:1':0, '1:n':1, 'm:1':2, 'm:n':3}
+        dtyp = [('e1','i4'),('e2','i4'),('e3','i2'),('n', 'i1')]
+        conv = {0: int, 1: int, 2: int, 3: lambda r: dmap[r.decode()]}
+        test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',',
+                             names=None, converters=conv)
+        control = np.rec.array([[1,5,-1,0], [2,8,-1,1], [3,3,-2,3]], dtype=dtyp)
+        assert_equal(test, control)
+        dtyp = [('e1','i4'),('e2','i4'),('n', 'i1')]
+        test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',',
+                             usecols=(0,1,3), names=None, converters=conv)
+        control = np.rec.array([[1,5,0], [2,8,1], [3,3,3]], dtype=dtyp)
+        assert_equal(test, control)
+
+    def test_dtype_with_object(self):
+        # Test using an explicit dtype with an object
+        data = """ 1; 2001-01-01
+                   2; 2002-01-31 """
+        ndtype = [('idx', int), ('code', np.object)]
+        func = lambda s: strptime(s.strip(), "%Y-%m-%d")
+        converters = {1: func}
+        test = np.genfromtxt(TextIO(data), delimiter=";", dtype=ndtype,
+                             converters=converters)
+        control = np.array(
+            [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))],
+            dtype=ndtype)
+        assert_equal(test, control)
+
+        ndtype = [('nest', [('idx', int), ('code', np.object)])]
+        try:
+            test = np.genfromtxt(TextIO(data), delimiter=";",
+                                 dtype=ndtype, converters=converters)
+        except NotImplementedError:
+            pass
+        else:
+            errmsg = "Nested dtype involving objects should be supported."
+            raise AssertionError(errmsg)
+
+    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 = np.genfromtxt(data, delimiter=",", names=None, dtype=float,
+                             usecols=(2, 3), converters={2: bytes})
+        control = np.array([('2001-01-01', 1.)],
+                           dtype=[('', '|S10'), ('', float)])
+        assert_equal(test, control)
+
+    def test_spacedelimiter(self):
+        # Test space delimiter
+        data = TextIO("1  2  3  4   5\n6  7  8  9  10")
+        test = np.ndfromtxt(data)
+        control = np.array([[1., 2., 3., 4., 5.],
+                            [6., 7., 8., 9., 10.]])
+        assert_equal(test, control)
+
+    def test_integer_delimiter(self):
+        # Test using an integer for delimiter
+        data = "  1  2  3\n  4  5 67\n890123  4"
+        test = np.genfromtxt(TextIO(data), delimiter=3)
+        control = np.array([[1, 2, 3], [4, 5, 67], [890, 123, 4]])
+        assert_equal(test, control)
+
+    def test_missing(self):
+        data = TextIO('1,2,3,,5\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',',
+                            converters={3: lambda s: int(s or - 999)})
+        control = np.array([1, 2, 3, -999, 5], int)
+        assert_equal(test, control)
+
+    def test_missing_with_tabs(self):
+        # Test w/ a delimiter tab
+        txt = "1\t2\t3\n\t2\t\n1\t\t3"
+        test = np.genfromtxt(TextIO(txt), delimiter="\t",
+                             usemask=True,)
+        ctrl_d = np.array([(1, 2, 3), (np.nan, 2, np.nan), (1, np.nan, 3)],)
+        ctrl_m = np.array([(0, 0, 0), (1, 0, 1), (0, 1, 0)], dtype=bool)
+        assert_equal(test.data, ctrl_d)
+        assert_equal(test.mask, ctrl_m)
+
+    def test_usecols(self):
+        # Test the selection of columns
+        # Select 1 column
+        control = np.array([[1, 2], [3, 4]], float)
+        data = TextIO()
+        np.savetxt(data, control)
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=(1,))
+        assert_equal(test, control[:, 1])
+        #
+        control = np.array([[1, 2, 3], [3, 4, 5]], float)
+        data = TextIO()
+        np.savetxt(data, control)
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=(1, 2))
+        assert_equal(test, control[:, 1:])
+        # Testing with arrays instead of tuples.
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=np.array([1, 2]))
+        assert_equal(test, control[:, 1:])
+
+    def test_usecols_as_css(self):
+        # Test giving usecols with a comma-separated string
+        data = "1 2 3\n4 5 6"
+        test = np.genfromtxt(TextIO(data),
+                             names="a, b, c", usecols="a, c")
+        ctrl = np.array([(1, 3), (4, 6)], dtype=[(_, float) for _ in "ac"])
+        assert_equal(test, ctrl)
+
+    def test_usecols_with_structured_dtype(self):
+        # Test usecols with an explicit structured dtype
+        data = TextIO("JOE 70.1 25.3\nBOB 60.5 27.9")
+        names = ['stid', 'temp']
+        dtypes = ['S4', 'f8']
+        test = np.ndfromtxt(
+            data, usecols=(0, 2), dtype=list(zip(names, dtypes)))
+        assert_equal(test['stid'], [b"JOE", b"BOB"])
+        assert_equal(test['temp'], [25.3, 27.9])
+
+    def test_usecols_with_integer(self):
+        # Test usecols with an integer
+        test = np.genfromtxt(TextIO(b"1 2 3\n4 5 6"), usecols=0)
+        assert_equal(test, np.array([1., 4.]))
+
+    def test_usecols_with_named_columns(self):
+        # Test usecols with named columns
+        ctrl = np.array([(1, 3), (4, 6)], dtype=[('a', float), ('c', float)])
+        data = "1 2 3\n4 5 6"
+        kwargs = dict(names="a, b, c")
+        test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs)
+        assert_equal(test, ctrl)
+        test = np.genfromtxt(TextIO(data),
+                             usecols=('a', 'c'), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_empty_file(self):
+        # Test that an empty file raises the proper warning.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="genfromtxt: Empty input file:")
+            data = TextIO()
+            test = np.genfromtxt(data)
+            assert_equal(test, np.array([]))
+
+    def test_fancy_dtype_alt(self):
+        # Check that a nested dtype isn't MIA
+        data = TextIO('1,2,3.0\n4,5,6.0\n')
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = np.mafromtxt(data, dtype=fancydtype, delimiter=',')
+        control = ma.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype)
+        assert_equal(test, control)
+
+    def test_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 3))])
+        x = np.ndfromtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_withmissing(self):
+        data = TextIO('A,B\n0,1\n2,N/A')
+        kwargs = dict(delimiter=",", missing_values="N/A", names=True)
+        test = np.mafromtxt(data, dtype=None, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        #
+        data.seek(0)
+        test = np.mafromtxt(data, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.float), ('B', np.float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_user_missing_values(self):
+        data = "A, B, C\n0, 0., 0j\n1, N/A, 1j\n-9, 2.2, N/A\n3, -99, 3j"
+        basekwargs = dict(dtype=None, delimiter=",", names=True,)
+        mdtype = [('A', int), ('B', float), ('C', complex)]
+        #
+        test = np.mafromtxt(TextIO(data), missing_values="N/A",
+                            **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+        #
+        basekwargs['dtype'] = mdtype
+        test = np.mafromtxt(TextIO(data),
+                            missing_values={0: -9, 1: -99, 2: -999j}, **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+        #
+        test = np.mafromtxt(TextIO(data),
+                            missing_values={0: -9, 'B': -99, 'C': -999j},
+                            **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+
+    def test_user_filling_values(self):
+        # Test with missing and filling values
+        ctrl = np.array([(0, 3), (4, -999)], dtype=[('a', int), ('b', int)])
+        data = "N/A, 2, 3\n4, ,???"
+        kwargs = dict(delimiter=",",
+                      dtype=int,
+                      names="a,b,c",
+                      missing_values={0: "N/A", 'b': " ", 2: "???"},
+                      filling_values={0: 0, 'b': 0, 2: -999})
+        test = np.genfromtxt(TextIO(data), **kwargs)
+        ctrl = np.array([(0, 2, 3), (4, 0, -999)],
+                        dtype=[(_, int) for _ in "abc"])
+        assert_equal(test, ctrl)
+        #
+        test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs)
+        ctrl = np.array([(0, 3), (4, -999)], dtype=[(_, int) for _ in "ac"])
+        assert_equal(test, ctrl)
+
+        data2 = "1,2,*,4\n5,*,7,8\n"
+        test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int,
+                             missing_values="*", filling_values=0)
+        ctrl = np.array([[1, 2, 0, 4], [5, 0, 7, 8]])
+        assert_equal(test, ctrl)
+        test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int,
+                             missing_values="*", filling_values=-1)
+        ctrl = np.array([[1, 2, -1, 4], [5, -1, 7, 8]])
+        assert_equal(test, ctrl)
+
+    def test_withmissing_float(self):
+        data = TextIO('A,B\n0,1.5\n2,-999.00')
+        test = np.mafromtxt(data, dtype=None, delimiter=',',
+                            missing_values='-999.0', names=True,)
+        control = ma.array([(0, 1.5), (2, -1.)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_with_masked_column_uniform(self):
+        # Test masked column
+        data = TextIO('1 2 3\n4 5 6\n')
+        test = np.genfromtxt(data, dtype=None,
+                             missing_values='2,5', usemask=True)
+        control = ma.array([[1, 2, 3], [4, 5, 6]], mask=[[0, 1, 0], [0, 1, 0]])
+        assert_equal(test, control)
+
+    def test_with_masked_column_various(self):
+        # Test masked column
+        data = TextIO('True 2 3\nFalse 5 6\n')
+        test = np.genfromtxt(data, dtype=None,
+                             missing_values='2,5', usemask=True)
+        control = ma.array([(1, 2, 3), (0, 5, 6)],
+                           mask=[(0, 1, 0), (0, 1, 0)],
+                           dtype=[('f0', bool), ('f1', bool), ('f2', int)])
+        assert_equal(test, control)
+
+    def test_invalid_raise(self):
+        # Test invalid raise
+        data = ["1, 1, 1, 1, 1"] * 50
+        for i in range(5):
+            data[10 * i] = "2, 2, 2, 2 2"
+        data.insert(0, "a, b, c, d, e")
+        mdata = TextIO("\n".join(data))
+        #
+        kwargs = dict(delimiter=",", dtype=None, names=True)
+        # XXX: is there a better way to get the return value of the
+        # callable in assert_warns ?
+        ret = {}
+
+        def f(_ret={}):
+            _ret['mtest'] = np.ndfromtxt(mdata, invalid_raise=False, **kwargs)
+        assert_warns(ConversionWarning, f, _ret=ret)
+        mtest = ret['mtest']
+        assert_equal(len(mtest), 45)
+        assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'abcde']))
+        #
+        mdata.seek(0)
+        assert_raises(ValueError, np.ndfromtxt, mdata,
+                      delimiter=",", names=True)
+
+    def test_invalid_raise_with_usecols(self):
+        # Test invalid_raise with usecols
+        data = ["1, 1, 1, 1, 1"] * 50
+        for i in range(5):
+            data[10 * i] = "2, 2, 2, 2 2"
+        data.insert(0, "a, b, c, d, e")
+        mdata = TextIO("\n".join(data))
+        kwargs = dict(delimiter=",", dtype=None, names=True,
+                      invalid_raise=False)
+        # XXX: is there a better way to get the return value of the
+        # callable in assert_warns ?
+        ret = {}
+
+        def f(_ret={}):
+            _ret['mtest'] = np.ndfromtxt(mdata, usecols=(0, 4), **kwargs)
+        assert_warns(ConversionWarning, f, _ret=ret)
+        mtest = ret['mtest']
+        assert_equal(len(mtest), 45)
+        assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'ae']))
+        #
+        mdata.seek(0)
+        mtest = np.ndfromtxt(mdata, usecols=(0, 1), **kwargs)
+        assert_equal(len(mtest), 50)
+        control = np.ones(50, dtype=[(_, int) for _ in 'ab'])
+        control[[10 * _ for _ in range(5)]] = (2, 2)
+        assert_equal(mtest, control)
+
+    def test_inconsistent_dtype(self):
+        # Test inconsistent dtype
+        data = ["1, 1, 1, 1, -1.1"] * 50
+        mdata = TextIO("\n".join(data))
+
+        converters = {4: lambda x: "(%s)" % x}
+        kwargs = dict(delimiter=",", converters=converters,
+                      dtype=[(_, int) for _ in 'abcde'],)
+        assert_raises(ValueError, np.genfromtxt, mdata, **kwargs)
+
+    def test_default_field_format(self):
+        # Test default format
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=None, defaultfmt="f%02i")
+        ctrl = np.array([(0, 1, 2.3), (4, 5, 6.7)],
+                        dtype=[("f00", int), ("f01", int), ("f02", float)])
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_wo_names(self):
+        # Test single dtype w/o names
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, defaultfmt="f%02i")
+        ctrl = np.array([[0., 1., 2.3], [4., 5., 6.7]], dtype=float)
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_w_explicit_names(self):
+        # Test single dtype w explicit names
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, names="a, b, c")
+        ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)],
+                        dtype=[(_, float) for _ in "abc"])
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_w_implicit_names(self):
+        # Test single dtype w implicit names
+        data = "a, b, c\n0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, names=True)
+        ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)],
+                        dtype=[(_, float) for _ in "abc"])
+        assert_equal(mtest, ctrl)
+
+    def test_easy_structured_dtype(self):
+        # Test easy structured dtype
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data), delimiter=",",
+                             dtype=(int, float, float), defaultfmt="f_%02i")
+        ctrl = np.array([(0, 1., 2.3), (4, 5., 6.7)],
+                        dtype=[("f_00", int), ("f_01", float), ("f_02", float)])
+        assert_equal(mtest, ctrl)
+
+    def test_autostrip(self):
+        # Test autostrip
+        data = "01/01/2003  , 1.3,   abcde"
+        kwargs = dict(delimiter=",", dtype=None)
+        mtest = np.ndfromtxt(TextIO(data), **kwargs)
+        ctrl = np.array([('01/01/2003  ', 1.3, '   abcde')],
+                        dtype=[('f0', '|S12'), ('f1', float), ('f2', '|S8')])
+        assert_equal(mtest, ctrl)
+        mtest = np.ndfromtxt(TextIO(data), autostrip=True, **kwargs)
+        ctrl = np.array([('01/01/2003', 1.3, 'abcde')],
+                        dtype=[('f0', '|S10'), ('f1', float), ('f2', '|S5')])
+        assert_equal(mtest, ctrl)
+
+    def test_replace_space(self):
+        # Test the 'replace_space' option
+        txt = "A.A, B (B), C:C\n1, 2, 3.14"
+        # Test default: replace ' ' by '_' and delete non-alphanum chars
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None)
+        ctrl_dtype = [("AA", int), ("B_B", int), ("CC", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no replace, no delete
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None,
+                             replace_space='', deletechars='')
+        ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no delete (spaces are replaced by _)
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None,
+                             deletechars='')
+        ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+
+    def test_replace_space_known_dtype(self):
+        # Test the 'replace_space' (and related) options when dtype != None
+        txt = "A.A, B (B), C:C\n1, 2, 3"
+        # Test default: replace ' ' by '_' and delete non-alphanum chars
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int)
+        ctrl_dtype = [("AA", int), ("B_B", int), ("CC", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no replace, no delete
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int,
+                             replace_space='', deletechars='')
+        ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no delete (spaces are replaced by _)
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int,
+                             deletechars='')
+        ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+
+    def test_incomplete_names(self):
+        # Test w/ incomplete names
+        data = "A,,C\n0,1,2\n3,4,5"
+        kwargs = dict(delimiter=",", names=True)
+        # w/ dtype=None
+        ctrl = np.array([(0, 1, 2), (3, 4, 5)],
+                        dtype=[(_, int) for _ in ('A', 'f0', 'C')])
+        test = np.ndfromtxt(TextIO(data), dtype=None, **kwargs)
+        assert_equal(test, ctrl)
+        # w/ default dtype
+        ctrl = np.array([(0, 1, 2), (3, 4, 5)],
+                        dtype=[(_, float) for _ in ('A', 'f0', 'C')])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+
+    def test_names_auto_completion(self):
+        # Make sure that names are properly completed
+        data = "1 2 3\n 4 5 6"
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, float, int), names="a")
+        ctrl = np.array([(1, 2, 3), (4, 5, 6)],
+                        dtype=[('a', int), ('f0', float), ('f1', int)])
+        assert_equal(test, ctrl)
+
+    def test_names_with_usecols_bug1636(self):
+        # Make sure we pick up the right names w/ usecols
+        data = "A,B,C,D,E\n0,1,2,3,4\n0,1,2,3,4\n0,1,2,3,4"
+        ctrl_names = ("A", "C", "E")
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, int, int), delimiter=",",
+                             usecols=(0, 2, 4), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+        #
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, int, int), delimiter=",",
+                             usecols=("A", "C", "E"), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+        #
+        test = np.genfromtxt(TextIO(data),
+                             dtype=int, delimiter=",",
+                             usecols=("A", "C", "E"), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+
+    def test_fixed_width_names(self):
+        # Test fix-width w/ names
+        data = "    A    B   C\n    0    1 2.3\n   45   67   9."
+        kwargs = dict(delimiter=(5, 5, 4), names=True, dtype=None)
+        ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)],
+                        dtype=[('A', int), ('B', int), ('C', float)])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+        #
+        kwargs = dict(delimiter=5, names=True, dtype=None)
+        ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)],
+                        dtype=[('A', int), ('B', int), ('C', float)])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_filling_values(self):
+        # Test missing values
+        data = b"1, 2, 3\n1, , 5\n0, 6, \n"
+        kwargs = dict(delimiter=",", dtype=None, filling_values=-999)
+        ctrl = np.array([[1, 2, 3], [1, -999, 5], [0, 6, -999]], dtype=int)
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_comments_is_none(self):
+        # Github issue 329 (None was previously being converted to 'None').
+        test = np.genfromtxt(TextIO("test1,testNonetherestofthedata"),
+                             dtype=None, comments=None, delimiter=',')
+        assert_equal(test[1], b'testNonetherestofthedata')
+        test = np.genfromtxt(TextIO("test1, testNonetherestofthedata"),
+                             dtype=None, comments=None, delimiter=',')
+        assert_equal(test[1], b' testNonetherestofthedata')
+
+    def test_recfromtxt(self):
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        kwargs = dict(delimiter=",", missing_values="N/A", names=True)
+        test = np.recfromtxt(data, **kwargs)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,N/A')
+        test = np.recfromtxt(data, dtype=None, usemask=True, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(test.A, [0, 2])
+
+    def test_recfromcsv(self):
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        kwargs = dict(missing_values="N/A", names=True, case_sensitive=True)
+        test = np.recfromcsv(data, dtype=None, **kwargs)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,N/A')
+        test = np.recfromcsv(data, dtype=None, usemask=True, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(test.A, [0, 2])
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        test = np.recfromcsv(data, missing_values='N/A',)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('a', np.int), ('b', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        dtype = [('a', np.int), ('b', np.float)]
+        test = np.recfromcsv(data, missing_values='N/A', dtype=dtype)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=dtype)
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+
+    def test_max_rows(self):
+        # Test the `max_rows` keyword argument.
+        data = '1 2\n3 4\n5 6\n7 8\n9 10\n'
+        txt = TextIO(data)
+        a1 = np.genfromtxt(txt, max_rows=3)
+        a2 = np.genfromtxt(txt)
+        assert_equal(a1, [[1, 2], [3, 4], [5, 6]])
+        assert_equal(a2, [[7, 8], [9, 10]])
+
+        # max_rows must be at least 1.
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=0)
+
+        # An input with several invalid rows.
+        data = '1 1\n2 2\n0 \n3 3\n4 4\n5  \n6  \n7  \n'
+
+        test = np.genfromtxt(TextIO(data), max_rows=2)
+        control = np.array([[1., 1.], [2., 2.]])
+        assert_equal(test, control)
+
+        # Test keywords conflict
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), skip_footer=1,
+                      max_rows=4)
+
+        # Test with invalid value
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=4)
+
+        # Test with invalid not raise
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore")
+
+            test = np.genfromtxt(TextIO(data), max_rows=4, invalid_raise=False)
+            control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])
+            assert_equal(test, control)
+
+            test = np.genfromtxt(TextIO(data), max_rows=5, invalid_raise=False)
+            control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])
+            assert_equal(test, control)
+
+        # Structured array with field names.
+        data = 'a b\n#c d\n1 1\n2 2\n#0 \n3 3\n4 4\n5  5\n'
+
+        # Test with header, names and comments
+        txt = TextIO(data)
+        test = np.genfromtxt(txt, skip_header=1, max_rows=3, names=True)
+        control = np.array([(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)],
+                      dtype=[('c', '<f8'), ('d', '<f8')])
+        assert_equal(test, control)
+        # To continue reading the same "file", don't use skip_header or
+        # names, and use the previously determined dtype.
+        test = np.genfromtxt(txt, max_rows=None, dtype=test.dtype)
+        control = np.array([(4.0, 4.0), (5.0, 5.0)],
+                      dtype=[('c', '<f8'), ('d', '<f8')])
+        assert_equal(test, control)
+
+    def test_gft_using_filename(self):
+        # Test that we can load data from a filename as well as a file
+        # object
+        tgt = np.arange(6).reshape((2, 3))
+        if sys.version_info[0] >= 3:
+            # python 3k is known to fail for '\r'
+            linesep = ('\n', '\r\n')
+        else:
+            linesep = ('\n', '\r\n', '\r')
+
+        for sep in linesep:
+            data = '0 1 2' + sep + '3 4 5'
+            with temppath() as name:
+                with open(name, 'w') as f:
+                    f.write(data)
+                res = np.genfromtxt(name)
+            assert_array_equal(res, tgt)
+
+    def test_gft_using_generator(self):
+        # gft doesn't work with unicode.
+        def count():
+            for i in range(10):
+                yield asbytes("%d" % i)
+
+        res = np.genfromtxt(count())
+        assert_array_equal(res, np.arange(10))
+
+    def test_auto_dtype_largeint(self):
+        # Regression test for numpy/numpy#5635 whereby large integers could
+        # cause OverflowErrors.
+
+        # Test the automatic definition of the output dtype
+        #
+        # 2**66 = 73786976294838206464 => should convert to float
+        # 2**34 = 17179869184 => should convert to int64
+        # 2**10 = 1024 => should convert to int (int32 on 32-bit systems,
+        #                 int64 on 64-bit systems)
+
+        data = TextIO('73786976294838206464 17179869184 1024')
+
+        test = np.ndfromtxt(data, dtype=None)
+
+        assert_equal(test.dtype.names, ['f0', 'f1', 'f2'])
+
+        assert_(test.dtype['f0'] == np.float)
+        assert_(test.dtype['f1'] == np.int64)
+        assert_(test.dtype['f2'] == np.integer)
+
+        assert_allclose(test['f0'], 73786976294838206464.)
+        assert_equal(test['f1'], 17179869184)
+        assert_equal(test['f2'], 1024)
+
+def test_gzip_load():
+    a = np.random.random((5, 5))
+
+    s = BytesIO()
+    f = gzip.GzipFile(fileobj=s, mode="w")
+
+    np.save(f, a)
+    f.close()
+    s.seek(0)
+
+    f = gzip.GzipFile(fileobj=s, mode="r")
+    assert_array_equal(np.load(f), a)
+
+
+def test_gzip_loadtxt():
+    # Thanks to another windows brokeness, we can't use
+    # NamedTemporaryFile: a file created from this function cannot be
+    # reopened by another open call. So we first put the gzipped string
+    # of the test reference array, write it to a securely opened file,
+    # which is then read from by the loadtxt function
+    s = BytesIO()
+    g = gzip.GzipFile(fileobj=s, mode='w')
+    g.write(b'1 2 3\n')
+    g.close()
+
+    s.seek(0)
+    with temppath(suffix='.gz') as name:
+        with open(name, 'wb') as f:
+            f.write(s.read())
+        res = np.loadtxt(name)
+    s.close()
+
+    assert_array_equal(res, [1, 2, 3])
+
+
+def test_gzip_loadtxt_from_string():
+    s = BytesIO()
+    f = gzip.GzipFile(fileobj=s, mode="w")
+    f.write(b'1 2 3\n')
+    f.close()
+    s.seek(0)
+
+    f = gzip.GzipFile(fileobj=s, mode="r")
+    assert_array_equal(np.loadtxt(f), [1, 2, 3])
+
+
+def test_npzfile_dict():
+    s = BytesIO()
+    x = np.zeros((3, 3))
+    y = np.zeros((3, 3))
+
+    np.savez(s, x=x, y=y)
+    s.seek(0)
+
+    z = np.load(s)
+
+    assert_('x' in z)
+    assert_('y' in z)
+    assert_('x' in z.keys())
+    assert_('y' in z.keys())
+
+    for f, a in z.items():
+        assert_(f in ['x', 'y'])
+        assert_equal(a.shape, (3, 3))
+
+    assert_(len(z.items()) == 2)
+
+    for f in z:
+        assert_(f in ['x', 'y'])
+
+    assert_('x' in z.keys())
+
+
+def test_load_refcount():
+    # Check that objects returned by np.load are directly freed based on
+    # their refcount, rather than needing the gc to collect them.
+
+    f = BytesIO()
+    np.savez(f, [1, 2, 3])
+    f.seek(0)
+
+    assert_(gc.isenabled())
+    gc.disable()
+    try:
+        gc.collect()
+        np.load(f)
+        # gc.collect returns the number of unreachable objects in cycles that
+        # were found -- we are checking that no cycles were created by np.load
+        n_objects_in_cycles = gc.collect()
+    finally:
+        gc.enable()
+    assert_equal(n_objects_in_cycles, 0)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
new file mode 100644
index 0000000000..989c563d99
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
@@ -0,0 +1,735 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal,
+    assert_raises, assert_array_equal
+    )
+
+
+# Test data
+_ndat = np.array([[0.6244, np.nan, 0.2692, 0.0116, np.nan, 0.1170],
+                  [0.5351, -0.9403, np.nan, 0.2100, 0.4759, 0.2833],
+                  [np.nan, np.nan, np.nan, 0.1042, np.nan, -0.5954],
+                  [0.1610, np.nan, np.nan, 0.1859, 0.3146, np.nan]])
+
+
+# Rows of _ndat with nans removed
+_rdat = [np.array([0.6244, 0.2692, 0.0116, 0.1170]),
+         np.array([0.5351, -0.9403, 0.2100, 0.4759, 0.2833]),
+         np.array([0.1042, -0.5954]),
+         np.array([0.1610, 0.1859, 0.3146])]
+
+
+class TestNanFunctions_MinMax(TestCase):
+
+    nanfuncs = [np.nanmin, np.nanmax]
+    stdfuncs = [np.min, np.max]
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for axis in [None, 0, 1]:
+                tgt = rf(mat, axis=axis, keepdims=True)
+                res = nf(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == tgt.ndim)
+
+    def test_out(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            resout = np.zeros(3)
+            tgt = rf(mat, axis=1)
+            res = nf(mat, axis=1, out=resout)
+            assert_almost_equal(res, resout)
+            assert_almost_equal(res, tgt)
+
+    def test_dtype_from_input(self):
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                mat = np.eye(3, dtype=c)
+                tgt = rf(mat, axis=1).dtype.type
+                res = nf(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, axis=None).dtype.type
+                res = nf(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_result_values(self):
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            tgt = [rf(d) for d in _rdat]
+            res = nf(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1, 'no warning raised')
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            # Check scalars
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(f(np.nan)))
+                assert_(len(w) == 1, 'no warning raised')
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_masked(self):
+        mat = np.ma.fix_invalid(_ndat)
+        msk = mat._mask.copy()
+        for f in [np.nanmin]:
+            res = f(mat, axis=1)
+            tgt = f(_ndat, axis=1)
+            assert_equal(res, tgt)
+            assert_equal(mat._mask, msk)
+            assert_(not np.isinf(mat).any())
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+        # check that rows of nan are dealt with for subclasses (#4628)
+        mat[1] = np.nan
+        for f in self.nanfuncs:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat, axis=0)
+                assert_(isinstance(res, np.matrix))
+                assert_(not np.any(np.isnan(res)))
+                assert_(len(w) == 0)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat, axis=1)
+                assert_(isinstance(res, np.matrix))
+                assert_(np.isnan(res[1, 0]) and not np.isnan(res[0, 0])
+                        and not np.isnan(res[2, 0]))
+                assert_(len(w) == 1, 'no warning raised')
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat)
+                assert_(np.isscalar(res))
+                assert_(res != np.nan)
+                assert_(len(w) == 0)
+
+
+class TestNanFunctions_ArgminArgmax(TestCase):
+
+    nanfuncs = [np.nanargmin, np.nanargmax]
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_result_values(self):
+        for f, fcmp in zip(self.nanfuncs, [np.greater, np.less]):
+            for row in _ndat:
+                with warnings.catch_warnings(record=True):
+                    warnings.simplefilter('always')
+                    ind = f(row)
+                    val = row[ind]
+                    # comparing with NaN is tricky as the result
+                    # is always false except for NaN != NaN
+                    assert_(not np.isnan(val))
+                    assert_(not fcmp(val, row).any())
+                    assert_(not np.equal(val, row[:ind]).any())
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                assert_raises(ValueError, f, mat, axis=axis)
+            assert_raises(ValueError, f, np.nan)
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for f in self.nanfuncs:
+            for axis in [0, None]:
+                assert_raises(ValueError, f, mat, axis=axis)
+            for axis in [1]:
+                res = f(mat, axis=axis)
+                assert_equal(res, np.zeros(0))
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+
+
+class TestNanFunctions_IntTypes(TestCase):
+
+    int_types = (np.int8, np.int16, np.int32, np.int64, np.uint8,
+                 np.uint16, np.uint32, np.uint64)
+
+    mat = np.array([127, 39, 93, 87, 46])
+
+    def integer_arrays(self):
+        for dtype in self.int_types:
+            yield self.mat.astype(dtype)
+
+    def test_nanmin(self):
+        tgt = np.min(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmin(mat), tgt)
+
+    def test_nanmax(self):
+        tgt = np.max(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmax(mat), tgt)
+
+    def test_nanargmin(self):
+        tgt = np.argmin(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanargmin(mat), tgt)
+
+    def test_nanargmax(self):
+        tgt = np.argmax(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanargmax(mat), tgt)
+
+    def test_nansum(self):
+        tgt = np.sum(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nansum(mat), tgt)
+
+    def test_nanprod(self):
+        tgt = np.prod(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanprod(mat), tgt)
+
+    def test_nanmean(self):
+        tgt = np.mean(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmean(mat), tgt)
+
+    def test_nanvar(self):
+        tgt = np.var(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanvar(mat), tgt)
+
+        tgt = np.var(mat, ddof=1)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanvar(mat, ddof=1), tgt)
+
+    def test_nanstd(self):
+        tgt = np.std(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanstd(mat), tgt)
+
+        tgt = np.std(self.mat, ddof=1)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanstd(mat, ddof=1), tgt)
+
+
+class SharedNanFunctionsTestsMixin(object):
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for axis in [None, 0, 1]:
+                tgt = rf(mat, axis=axis, keepdims=True)
+                res = nf(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == tgt.ndim)
+
+    def test_out(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            resout = np.zeros(3)
+            tgt = rf(mat, axis=1)
+            res = nf(mat, axis=1, out=resout)
+            assert_almost_equal(res, resout)
+            assert_almost_equal(res, tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type
+                res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type
+                res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_char(self):
+        mat = np.eye(3)
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                tgt = rf(mat, dtype=c, axis=1).dtype.type
+                res = nf(mat, dtype=c, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, dtype=c, axis=None).dtype.type
+                res = nf(mat, dtype=c, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_input(self):
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                mat = np.eye(3, dtype=c)
+                tgt = rf(mat, axis=1).dtype.type
+                res = nf(mat, axis=1).dtype.type
+                assert_(res is tgt, "res %s, tgt %s" % (res, tgt))
+                # scalar case
+                tgt = rf(mat, axis=None).dtype.type
+                res = nf(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_result_values(self):
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            tgt = [rf(d) for d in _rdat]
+            res = nf(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+
+
+class TestNanFunctions_SumProd(TestCase, SharedNanFunctionsTestsMixin):
+
+    nanfuncs = [np.nansum, np.nanprod]
+    stdfuncs = [np.sum, np.prod]
+
+    def test_allnans(self):
+        # Check for FutureWarning
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always')
+            res = np.nansum([np.nan]*3, axis=None)
+            assert_(res == 0, 'result is not 0')
+            assert_(len(w) == 0, 'warning raised')
+            # Check scalar
+            res = np.nansum(np.nan)
+            assert_(res == 0, 'result is not 0')
+            assert_(len(w) == 0, 'warning raised')
+            # Check there is no warning for not all-nan
+            np.nansum([0]*3, axis=None)
+            assert_(len(w) == 0, 'unwanted warning raised')
+
+    def test_empty(self):
+        for f, tgt_value in zip([np.nansum, np.nanprod], [0, 1]):
+            mat = np.zeros((0, 3))
+            tgt = [tgt_value]*3
+            res = f(mat, axis=0)
+            assert_equal(res, tgt)
+            tgt = []
+            res = f(mat, axis=1)
+            assert_equal(res, tgt)
+            tgt = tgt_value
+            res = f(mat, axis=None)
+            assert_equal(res, tgt)
+
+
+class TestNanFunctions_MeanVarStd(TestCase, SharedNanFunctionsTestsMixin):
+
+    nanfuncs = [np.nanmean, np.nanvar, np.nanstd]
+    stdfuncs = [np.mean, np.var, np.std]
+
+    def test_dtype_error(self):
+        for f in self.nanfuncs:
+            for dtype in [np.bool_, np.int_, np.object_]:
+                assert_raises(TypeError, f, _ndat, axis=1, dtype=dtype)
+
+    def test_out_dtype_error(self):
+        for f in self.nanfuncs:
+            for dtype in [np.bool_, np.int_, np.object_]:
+                out = np.empty(_ndat.shape[0], dtype=dtype)
+                assert_raises(TypeError, f, _ndat, axis=1, out=out)
+
+    def test_ddof(self):
+        nanfuncs = [np.nanvar, np.nanstd]
+        stdfuncs = [np.var, np.std]
+        for nf, rf in zip(nanfuncs, stdfuncs):
+            for ddof in [0, 1]:
+                tgt = [rf(d, ddof=ddof) for d in _rdat]
+                res = nf(_ndat, axis=1, ddof=ddof)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        nanfuncs = [np.nanvar, np.nanstd]
+        stdfuncs = [np.var, np.std]
+        dsize = [len(d) for d in _rdat]
+        for nf, rf in zip(nanfuncs, stdfuncs):
+            for ddof in range(5):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    tgt = [ddof >= d for d in dsize]
+                    res = nf(_ndat, axis=1, ddof=ddof)
+                    assert_equal(np.isnan(res), tgt)
+                    if any(tgt):
+                        assert_(len(w) == 1)
+                        assert_(issubclass(w[0].category, RuntimeWarning))
+                    else:
+                        assert_(len(w) == 0)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+                    # Check scalar
+                    assert_(np.isnan(f(np.nan)))
+                    assert_(len(w) == 2)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for f in self.nanfuncs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(mat, axis=axis), np.zeros([]))
+                    assert_(len(w) == 0)
+
+
+class TestNanFunctions_Median(TestCase):
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        np.nanmedian(ndat)
+        assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for axis in [None, 0, 1]:
+            tgt = np.median(mat, axis=axis, out=None, overwrite_input=False)
+            res = np.nanmedian(mat, axis=axis, out=None, overwrite_input=False)
+            assert_(res.ndim == tgt.ndim)
+
+        d = np.ones((3, 5, 7, 11))
+        # Randomly set some elements to NaN:
+        w = np.random.random((4, 200)) * np.array(d.shape)[:, None]
+        w = w.astype(np.intp)
+        d[tuple(w)] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', RuntimeWarning)
+            res = np.nanmedian(d, axis=None, keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanmedian(d, axis=(0, 1), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 11))
+            res = np.nanmedian(d, axis=(0, 3), keepdims=True)
+            assert_equal(res.shape, (1, 5, 7, 1))
+            res = np.nanmedian(d, axis=(1,), keepdims=True)
+            assert_equal(res.shape, (3, 1, 7, 11))
+            res = np.nanmedian(d, axis=(0, 1, 2, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanmedian(d, axis=(0, 1, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 1))
+
+    def test_out(self):
+        mat = np.random.rand(3, 3)
+        nan_mat = np.insert(mat, [0, 2], np.nan, axis=1)
+        resout = np.zeros(3)
+        tgt = np.median(mat, axis=1)
+        res = np.nanmedian(nan_mat, axis=1, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        # 0-d output:
+        resout = np.zeros(())
+        tgt = np.median(mat, axis=None)
+        res = np.nanmedian(nan_mat, axis=None, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        res = np.nanmedian(nan_mat, axis=(0, 1), out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+
+    def test_small_large(self):
+        # test the small and large code paths, current cutoff 400 elements
+        for s in [5, 20, 51, 200, 1000]:
+            d = np.random.randn(4, s)
+            # Randomly set some elements to NaN:
+            w = np.random.randint(0, d.size, size=d.size // 5)
+            d.ravel()[w] = np.nan
+            d[:,0] = 1.  # ensure at least one good value
+            # use normal median without nans to compare
+            tgt = []
+            for x in d:
+                nonan = np.compress(~np.isnan(x), x)
+                tgt.append(np.median(nonan, overwrite_input=True))
+
+            assert_array_equal(np.nanmedian(d, axis=-1), tgt)
+
+    def test_result_values(self):
+            tgt = [np.median(d) for d in _rdat]
+            res = np.nanmedian(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for axis in [None, 0, 1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                warnings.simplefilter('ignore', FutureWarning)
+                assert_(np.isnan(np.nanmedian(mat, axis=axis)).all())
+                if axis is None:
+                    assert_(len(w) == 1)
+                else:
+                    assert_(len(w) == 3)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+                # Check scalar
+                assert_(np.isnan(np.nanmedian(np.nan)))
+                if axis is None:
+                    assert_(len(w) == 2)
+                else:
+                    assert_(len(w) == 4)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for axis in [0, None]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanmedian(mat, axis=axis)).all())
+                assert_(len(w) == 1)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+        for axis in [1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_equal(np.nanmedian(mat, axis=axis), np.zeros([]))
+                assert_(len(w) == 0)
+
+    def test_scalar(self):
+        assert_(np.nanmedian(0.) == 0.)
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.nanmedian, d, axis=-5)
+        assert_raises(IndexError, np.nanmedian, d, axis=(0, -5))
+        assert_raises(IndexError, np.nanmedian, d, axis=4)
+        assert_raises(IndexError, np.nanmedian, d, axis=(0, 4))
+        assert_raises(ValueError, np.nanmedian, d, axis=(1, 1))
+
+    def test_float_special(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('ignore', RuntimeWarning)
+            a = np.array([[np.inf,  np.nan], [np.nan, np.nan]])
+            assert_equal(np.nanmedian(a, axis=0), [np.inf,  np.nan])
+            assert_equal(np.nanmedian(a, axis=1), [np.inf,  np.nan])
+            assert_equal(np.nanmedian(a), np.inf)
+
+            # minimum fill value check
+            a = np.array([[np.nan, np.nan, np.inf], [np.nan, np.nan, np.inf]])
+            assert_equal(np.nanmedian(a, axis=1), np.inf)
+
+            # no mask path
+            a = np.array([[np.inf, np.inf], [np.inf, np.inf]])
+            assert_equal(np.nanmedian(a, axis=1), np.inf)
+
+
+class TestNanFunctions_Percentile(TestCase):
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        np.nanpercentile(ndat, 30)
+        assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for axis in [None, 0, 1]:
+            tgt = np.percentile(mat, 70, axis=axis, out=None,
+                                overwrite_input=False)
+            res = np.nanpercentile(mat, 70, axis=axis, out=None,
+                                   overwrite_input=False)
+            assert_(res.ndim == tgt.ndim)
+
+        d = np.ones((3, 5, 7, 11))
+        # Randomly set some elements to NaN:
+        w = np.random.random((4, 200)) * np.array(d.shape)[:, None]
+        w = w.astype(np.intp)
+        d[tuple(w)] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', RuntimeWarning)
+            res = np.nanpercentile(d, 90, axis=None, keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanpercentile(d, 90, axis=(0, 1), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 11))
+            res = np.nanpercentile(d, 90, axis=(0, 3), keepdims=True)
+            assert_equal(res.shape, (1, 5, 7, 1))
+            res = np.nanpercentile(d, 90, axis=(1,), keepdims=True)
+            assert_equal(res.shape, (3, 1, 7, 11))
+            res = np.nanpercentile(d, 90, axis=(0, 1, 2, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanpercentile(d, 90, axis=(0, 1, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 1))
+
+    def test_out(self):
+        mat = np.random.rand(3, 3)
+        nan_mat = np.insert(mat, [0, 2], np.nan, axis=1)
+        resout = np.zeros(3)
+        tgt = np.percentile(mat, 42, axis=1)
+        res = np.nanpercentile(nan_mat, 42, axis=1, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        # 0-d output:
+        resout = np.zeros(())
+        tgt = np.percentile(mat, 42, axis=None)
+        res = np.nanpercentile(nan_mat, 42, axis=None, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        res = np.nanpercentile(nan_mat, 42, axis=(0, 1), out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+
+    def test_result_values(self):
+        tgt = [np.percentile(d, 28) for d in _rdat]
+        res = np.nanpercentile(_ndat, 28, axis=1)
+        assert_almost_equal(res, tgt)
+        # Transpose the array to fit the output convention of numpy.percentile
+        tgt = np.transpose([np.percentile(d, (28, 98)) for d in _rdat])
+        res = np.nanpercentile(_ndat, (28, 98), axis=1)
+        assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for axis in [None, 0, 1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanpercentile(mat, 60, axis=axis)).all())
+                if axis is None:
+                    assert_(len(w) == 1)
+                else:
+                    assert_(len(w) == 3)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+                # Check scalar
+                assert_(np.isnan(np.nanpercentile(np.nan, 60)))
+                if axis is None:
+                    assert_(len(w) == 2)
+                else:
+                    assert_(len(w) == 4)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for axis in [0, None]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanpercentile(mat, 40, axis=axis)).all())
+                assert_(len(w) == 1)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+        for axis in [1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_equal(np.nanpercentile(mat, 40, axis=axis), np.zeros([]))
+                assert_(len(w) == 0)
+
+    def test_scalar(self):
+        assert_(np.nanpercentile(0., 100) == 0.)
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=-5)
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=(0, -5))
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=4)
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=(0, 4))
+        assert_raises(ValueError, np.nanpercentile, d, q=5, axis=(1, 1))
+
+    def test_multiple_percentiles(self):
+        perc = [50, 100]
+        mat = np.ones((4, 3))
+        nan_mat = np.nan * mat
+        # For checking consistency in higher dimensional case
+        large_mat = np.ones((3, 4, 5))
+        large_mat[:, 0:2:4, :] = 0
+        large_mat[:, :, 3:] *= 2
+        for axis in [None, 0, 1]:
+            for keepdim in [False, True]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    val = np.percentile(mat, perc, axis=axis, keepdims=keepdim)
+                    nan_val = np.nanpercentile(nan_mat, perc, axis=axis,
+                                               keepdims=keepdim)
+                    assert_equal(nan_val.shape, val.shape)
+
+                    val = np.percentile(large_mat, perc, axis=axis,
+                                        keepdims=keepdim)
+                    nan_val = np.nanpercentile(large_mat, perc, axis=axis,
+                                               keepdims=keepdim)
+                    assert_equal(nan_val, val)
+
+        megamat = np.ones((3, 4, 5, 6))
+        assert_equal(np.nanpercentile(megamat, perc, axis=(1, 2)).shape, (2, 3, 6))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
new file mode 100644
index 0000000000..0de084ef9a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
@@ -0,0 +1,27 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_array_equal, assert_equal, assert_raises
+
+
+def test_packbits():
+    # Copied from the docstring.
+    a = [[[1, 0, 1], [0, 1, 0]],
+         [[1, 1, 0], [0, 0, 1]]]
+    for dtype in [np.bool, np.uint8, np.int]:
+        arr = np.array(a, dtype=dtype)
+        b = np.packbits(arr, axis=-1)
+        assert_equal(b.dtype, np.uint8)
+        assert_array_equal(b, np.array([[[160], [64]], [[192], [32]]]))
+
+    assert_raises(TypeError, np.packbits, np.array(a, dtype=float))
+
+
+def test_unpackbits():
+    # Copied from the docstring.
+    a = np.array([[2], [7], [23]], dtype=np.uint8)
+    b = np.unpackbits(a, axis=1)
+    assert_equal(b.dtype, np.uint8)
+    assert_array_equal(b, np.array([[0, 0, 0, 0, 0, 0, 1, 0],
+                                    [0, 0, 0, 0, 0, 1, 1, 1],
+                                    [0, 0, 0, 1, 0, 1, 1, 1]]))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
new file mode 100644
index 0000000000..5c15941e68
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
@@ -0,0 +1,188 @@
+from __future__ import division, absolute_import, print_function
+
+'''
+>>> p = np.poly1d([1.,2,3])
+>>> p
+poly1d([ 1.,  2.,  3.])
+>>> print(p)
+   2
+1 x + 2 x + 3
+>>> q = np.poly1d([3.,2,1])
+>>> q
+poly1d([ 3.,  2.,  1.])
+>>> print(q)
+   2
+3 x + 2 x + 1
+>>> print(np.poly1d([1.89999+2j, -3j, -5.12345678, 2+1j]))
+            3      2
+(1.9 + 2j) x - 3j x - 5.123 x + (2 + 1j)
+>>> print(np.poly1d([-3, -2, -1]))
+    2
+-3 x - 2 x - 1
+
+>>> p(0)
+3.0
+>>> p(5)
+38.0
+>>> q(0)
+1.0
+>>> q(5)
+86.0
+
+>>> p * q
+poly1d([  3.,   8.,  14.,   8.,   3.])
+>>> p / q
+(poly1d([ 0.33333333]), poly1d([ 1.33333333,  2.66666667]))
+>>> p + q
+poly1d([ 4.,  4.,  4.])
+>>> p - q
+poly1d([-2.,  0.,  2.])
+>>> p ** 4
+poly1d([   1.,    8.,   36.,  104.,  214.,  312.,  324.,  216.,   81.])
+
+>>> p(q)
+poly1d([  9.,  12.,  16.,   8.,   6.])
+>>> q(p)
+poly1d([  3.,  12.,  32.,  40.,  34.])
+
+>>> np.asarray(p)
+array([ 1.,  2.,  3.])
+>>> len(p)
+2
+
+>>> p[0], p[1], p[2], p[3]
+(3.0, 2.0, 1.0, 0)
+
+>>> p.integ()
+poly1d([ 0.33333333,  1.        ,  3.        ,  0.        ])
+>>> p.integ(1)
+poly1d([ 0.33333333,  1.        ,  3.        ,  0.        ])
+>>> p.integ(5)
+poly1d([ 0.00039683,  0.00277778,  0.025     ,  0.        ,  0.        ,
+        0.        ,  0.        ,  0.        ])
+>>> p.deriv()
+poly1d([ 2.,  2.])
+>>> p.deriv(2)
+poly1d([ 2.])
+
+>>> q = np.poly1d([1.,2,3], variable='y')
+>>> print(q)
+   2
+1 y + 2 y + 3
+>>> q = np.poly1d([1.,2,3], variable='lambda')
+>>> print(q)
+        2
+1 lambda + 2 lambda + 3
+
+>>> np.polydiv(np.poly1d([1,0,-1]), np.poly1d([1,1]))
+(poly1d([ 1., -1.]), poly1d([ 0.]))
+
+'''
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, rundocs
+    )
+
+
+class TestDocs(TestCase):
+    def test_doctests(self):
+        return rundocs()
+
+    def test_roots(self):
+        assert_array_equal(np.roots([1, 0, 0]), [0, 0])
+
+    def test_str_leading_zeros(self):
+        p = np.poly1d([4, 3, 2, 1])
+        p[3] = 0
+        assert_equal(str(p),
+                     "   2\n"
+                     "3 x + 2 x + 1")
+
+        p = np.poly1d([1, 2])
+        p[0] = 0
+        p[1] = 0
+        assert_equal(str(p), " \n0")
+
+    def test_polyfit(self):
+        c = np.array([3., 2., 1.])
+        x = np.linspace(0, 2, 7)
+        y = np.polyval(c, x)
+        err = [1, -1, 1, -1, 1, -1, 1]
+        weights = np.arange(8, 1, -1)**2/7.0
+
+        # check 1D case
+        m, cov = np.polyfit(x, y+err, 2, cov=True)
+        est = [3.8571, 0.2857, 1.619]
+        assert_almost_equal(est, m, decimal=4)
+        val0 = [[2.9388, -5.8776, 1.6327],
+                [-5.8776, 12.7347, -4.2449],
+                [1.6327, -4.2449, 2.3220]]
+        assert_almost_equal(val0, cov, decimal=4)
+
+        m2, cov2 = np.polyfit(x, y+err, 2, w=weights, cov=True)
+        assert_almost_equal([4.8927, -1.0177, 1.7768], m2, decimal=4)
+        val = [[8.7929, -10.0103, 0.9756],
+               [-10.0103, 13.6134, -1.8178],
+               [0.9756, -1.8178, 0.6674]]
+        assert_almost_equal(val, cov2, decimal=4)
+
+        # check 2D (n,1) case
+        y = y[:, np.newaxis]
+        c = c[:, np.newaxis]
+        assert_almost_equal(c, np.polyfit(x, y, 2))
+        # check 2D (n,2) case
+        yy = np.concatenate((y, y), axis=1)
+        cc = np.concatenate((c, c), axis=1)
+        assert_almost_equal(cc, np.polyfit(x, yy, 2))
+
+        m, cov = np.polyfit(x, yy + np.array(err)[:, np.newaxis], 2, cov=True)
+        assert_almost_equal(est, m[:, 0], decimal=4)
+        assert_almost_equal(est, m[:, 1], decimal=4)
+        assert_almost_equal(val0, cov[:, :, 0], decimal=4)
+        assert_almost_equal(val0, cov[:, :, 1], decimal=4)
+
+    def test_objects(self):
+        from decimal import Decimal
+        p = np.poly1d([Decimal('4.0'), Decimal('3.0'), Decimal('2.0')])
+        p2 = p * Decimal('1.333333333333333')
+        assert_(p2[1] == Decimal("3.9999999999999990"))
+        p2 = p.deriv()
+        assert_(p2[1] == Decimal('8.0'))
+        p2 = p.integ()
+        assert_(p2[3] == Decimal("1.333333333333333333333333333"))
+        assert_(p2[2] == Decimal('1.5'))
+        assert_(np.issubdtype(p2.coeffs.dtype, np.object_))
+        p = np.poly([Decimal(1), Decimal(2)])
+        assert_equal(np.poly([Decimal(1), Decimal(2)]),
+                     [1, Decimal(-3), Decimal(2)])
+
+    def test_complex(self):
+        p = np.poly1d([3j, 2j, 1j])
+        p2 = p.integ()
+        assert_((p2.coeffs == [1j, 1j, 1j, 0]).all())
+        p2 = p.deriv()
+        assert_((p2.coeffs == [6j, 2j]).all())
+
+    def test_integ_coeffs(self):
+        p = np.poly1d([3, 2, 1])
+        p2 = p.integ(3, k=[9, 7, 6])
+        assert_(
+            (p2.coeffs == [1/4./5., 1/3./4., 1/2./3., 9/1./2., 7, 6]).all())
+
+    def test_zero_dims(self):
+        try:
+            np.poly(np.zeros((0, 0)))
+        except ValueError:
+            pass
+
+    def test_poly_int_overflow(self):
+        """
+        Regression test for gh-5096.
+        """
+        v = np.arange(1, 21)
+        assert_almost_equal(np.poly(v), np.poly(np.diag(v)))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
new file mode 100644
index 0000000000..699a04716d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
@@ -0,0 +1,724 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.ma as ma
+from numpy.ma.mrecords import MaskedRecords
+from numpy.ma.testutils import assert_equal
+from numpy.testing import TestCase, run_module_suite, assert_
+from numpy.lib.recfunctions import (
+    drop_fields, rename_fields, get_fieldstructure, recursive_fill_fields,
+    find_duplicates, merge_arrays, append_fields, stack_arrays, join_by
+    )
+get_names = np.lib.recfunctions.get_names
+get_names_flat = np.lib.recfunctions.get_names_flat
+zip_descr = np.lib.recfunctions.zip_descr
+
+
+class TestRecFunctions(TestCase):
+    # Misc tests
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array([('A', 1.), ('B', 2.)],
+                     dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_zip_descr(self):
+        # Test zip_descr
+        (w, x, y, z) = self.data
+
+        # Std array
+        test = zip_descr((x, x), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int), ('', int)]))
+        test = zip_descr((x, x), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int), ('', int)]))
+
+        # Std & flexible-dtype
+        test = zip_descr((x, z), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int), ('A', '|S3'), ('B', float)]))
+        test = zip_descr((x, z), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('', [('A', '|S3'), ('B', float)])]))
+
+        # Standard & nested dtype
+        test = zip_descr((x, w), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('a', int),
+                               ('ba', float), ('bb', int)]))
+        test = zip_descr((x, w), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('', [('a', int),
+                                     ('b', [('ba', float), ('bb', int)])])]))
+
+    def test_drop_fields(self):
+        # Test drop_fields
+        a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+
+        # A basic field
+        test = drop_fields(a, 'a')
+        control = np.array([((2, 3.0),), ((5, 6.0),)],
+                           dtype=[('b', [('ba', float), ('bb', int)])])
+        assert_equal(test, control)
+
+        # Another basic field (but nesting two fields)
+        test = drop_fields(a, 'b')
+        control = np.array([(1,), (4,)], dtype=[('a', int)])
+        assert_equal(test, control)
+
+        # A nested sub-field
+        test = drop_fields(a, ['ba', ])
+        control = np.array([(1, (3.0,)), (4, (6.0,))],
+                           dtype=[('a', int), ('b', [('bb', int)])])
+        assert_equal(test, control)
+
+        # All the nested sub-field from a field: zap that field
+        test = drop_fields(a, ['ba', 'bb'])
+        control = np.array([(1,), (4,)], dtype=[('a', int)])
+        assert_equal(test, control)
+
+        test = drop_fields(a, ['a', 'b'])
+        assert_(test is None)
+
+    def test_rename_fields(self):
+        # Test rename fields
+        a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
+                     dtype=[('a', int),
+                            ('b', [('ba', float), ('bb', (float, 2))])])
+        test = rename_fields(a, {'a': 'A', 'bb': 'BB'})
+        newdtype = [('A', int), ('b', [('ba', float), ('BB', (float, 2))])]
+        control = a.view(newdtype)
+        assert_equal(test.dtype, newdtype)
+        assert_equal(test, control)
+
+    def test_get_names(self):
+        # Test get_names
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        test = get_names(ndtype)
+        assert_equal(test, ('A', 'B'))
+
+        ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])])
+        test = get_names(ndtype)
+        assert_equal(test, ('a', ('b', ('ba', 'bb'))))
+
+    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'))
+
+        ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])])
+        test = get_names_flat(ndtype)
+        assert_equal(test, ('a', 'b', 'ba', 'bb'))
+
+    def test_get_fieldstructure(self):
+        # Test get_fieldstructure
+
+        # No nested fields
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        test = get_fieldstructure(ndtype)
+        assert_equal(test, {'A': [], 'B': []})
+
+        # One 1-nested field
+        ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+        test = get_fieldstructure(ndtype)
+        assert_equal(test, {'A': [], 'B': [], 'BA': ['B', ], 'BB': ['B']})
+
+        # One 2-nested fields
+        ndtype = np.dtype([('A', int),
+                           ('B', [('BA', int),
+                                  ('BB', [('BBA', int), ('BBB', int)])])])
+        test = get_fieldstructure(ndtype)
+        control = {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'],
+                   'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
+        assert_equal(test, control)
+
+    def test_find_duplicates(self):
+        # Test find_duplicates
+        a = ma.array([(2, (2., 'B')), (1, (2., 'B')), (2, (2., 'B')),
+                      (1, (1., 'B')), (2, (2., 'B')), (2, (2., 'C'))],
+                     mask=[(0, (0, 0)), (0, (0, 0)), (0, (0, 0)),
+                           (0, (0, 0)), (1, (0, 0)), (0, (1, 0))],
+                     dtype=[('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+
+        test = find_duplicates(a, ignoremask=False, return_index=True)
+        control = [0, 2]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='A', return_index=True)
+        control = [0, 1, 2, 3, 5]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='B', return_index=True)
+        control = [0, 1, 2, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='BA', return_index=True)
+        control = [0, 1, 2, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='BB', return_index=True)
+        control = [0, 1, 2, 3, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+    def test_find_duplicates_ignoremask(self):
+        # Test the ignoremask option of find_duplicates
+        ndtype = [('a', int)]
+        a = ma.array([1, 1, 1, 2, 2, 3, 3],
+                     mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype)
+        test = find_duplicates(a, ignoremask=True, return_index=True)
+        control = [0, 1, 3, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, ignoremask=False, return_index=True)
+        control = [0, 1, 2, 3, 4, 6]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+
+class TestRecursiveFillFields(TestCase):
+    # Test recursive_fill_fields.
+    def test_simple_flexible(self):
+        # Test recursive_fill_fields on flexible-array
+        a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)])
+        b = np.zeros((3,), dtype=a.dtype)
+        test = recursive_fill_fields(a, b)
+        control = np.array([(1, 10.), (2, 20.), (0, 0.)],
+                           dtype=[('A', int), ('B', float)])
+        assert_equal(test, control)
+
+    def test_masked_flexible(self):
+        # Test recursive_fill_fields on masked flexible-array
+        a = ma.array([(1, 10.), (2, 20.)], mask=[(0, 1), (1, 0)],
+                     dtype=[('A', int), ('B', float)])
+        b = ma.zeros((3,), dtype=a.dtype)
+        test = recursive_fill_fields(a, b)
+        control = ma.array([(1, 10.), (2, 20.), (0, 0.)],
+                           mask=[(0, 1), (1, 0), (0, 0)],
+                           dtype=[('A', int), ('B', float)])
+        assert_equal(test, control)
+
+
+class TestMergeArrays(TestCase):
+    # Test merge_arrays
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array(
+            [(1, (2, 3.0)), (4, (5, 6.0))],
+            dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_solo(self):
+        # Test merge_arrays on a single array.
+        (_, x, _, z) = self.data
+
+        test = merge_arrays(x)
+        control = np.array([(1,), (2,)], dtype=[('f0', int)])
+        assert_equal(test, control)
+        test = merge_arrays((x,))
+        assert_equal(test, control)
+
+        test = merge_arrays(z, flatten=False)
+        assert_equal(test, z)
+        test = merge_arrays(z, flatten=True)
+        assert_equal(test, z)
+
+    def test_solo_w_flatten(self):
+        # Test merge_arrays on a single array w & w/o flattening
+        w = self.data[0]
+        test = merge_arrays(w, flatten=False)
+        assert_equal(test, w)
+
+        test = merge_arrays(w, flatten=True)
+        control = np.array([(1, 2, 3.0), (4, 5, 6.0)],
+                           dtype=[('a', int), ('ba', float), ('bb', int)])
+        assert_equal(test, control)
+
+    def test_standard(self):
+        # Test standard & standard
+        # Test merge arrays
+        (_, x, y, _) = self.data
+        test = merge_arrays((x, y), usemask=False)
+        control = np.array([(1, 10), (2, 20), (-1, 30)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, y), usemask=True)
+        control = ma.array([(1, 10), (2, 20), (-1, 30)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_flatten(self):
+        # Test standard & flexible
+        (_, x, _, z) = self.data
+        test = merge_arrays((x, z), flatten=True)
+        control = np.array([(1, 'A', 1.), (2, 'B', 2.)],
+                           dtype=[('f0', int), ('A', '|S3'), ('B', float)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, z), flatten=False)
+        control = np.array([(1, ('A', 1.)), (2, ('B', 2.))],
+                           dtype=[('f0', int),
+                                  ('f1', [('A', '|S3'), ('B', float)])])
+        assert_equal(test, control)
+
+    def test_flatten_wflexible(self):
+        # Test flatten standard & nested
+        (w, x, _, _) = self.data
+        test = merge_arrays((x, w), flatten=True)
+        control = np.array([(1, 1, 2, 3.0), (2, 4, 5, 6.0)],
+                           dtype=[('f0', int),
+                                  ('a', int), ('ba', float), ('bb', int)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, w), flatten=False)
+        controldtype = [('f0', int),
+                                ('f1', [('a', int),
+                                        ('b', [('ba', float), ('bb', int)])])]
+        control = np.array([(1., (1, (2, 3.0))), (2, (4, (5, 6.0)))],
+                           dtype=controldtype)
+        assert_equal(test, control)
+
+    def test_wmasked_arrays(self):
+        # Test merge_arrays masked arrays
+        (_, x, _, _) = self.data
+        mx = ma.array([1, 2, 3], mask=[1, 0, 0])
+        test = merge_arrays((x, mx), usemask=True)
+        control = ma.array([(1, 1), (2, 2), (-1, 3)],
+                           mask=[(0, 1), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+        test = merge_arrays((x, mx), usemask=True, asrecarray=True)
+        assert_equal(test, control)
+        assert_(isinstance(test, MaskedRecords))
+
+    def test_w_singlefield(self):
+        # Test single field
+        test = merge_arrays((np.array([1, 2]).view([('a', int)]),
+                             np.array([10., 20., 30.])),)
+        control = ma.array([(1, 10.), (2, 20.), (-1, 30.)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('a', int), ('f1', float)])
+        assert_equal(test, control)
+
+    def test_w_shorter_flex(self):
+        # Test merge_arrays w/ a shorter flexndarray.
+        z = self.data[-1]
+
+        # Fixme, this test looks incomplete and broken
+        #test = merge_arrays((z, np.array([10, 20, 30]).view([('C', int)])))
+        #control = np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)],
+        #                   dtype=[('A', '|S3'), ('B', float), ('C', int)])
+        #assert_equal(test, control)
+
+        # Hack to avoid pyflakes warnings about unused variables
+        merge_arrays((z, np.array([10, 20, 30]).view([('C', int)])))
+        np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)],
+                 dtype=[('A', '|S3'), ('B', float), ('C', int)])
+
+    def test_singlerecord(self):
+        (_, x, y, z) = self.data
+        test = merge_arrays((x[0], y[0], z[0]), usemask=False)
+        control = np.array([(1, 10, ('A', 1))],
+                           dtype=[('f0', int),
+                                  ('f1', int),
+                                  ('f2', [('A', '|S3'), ('B', float)])])
+        assert_equal(test, control)
+
+
+class TestAppendFields(TestCase):
+    # Test append_fields
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_append_single(self):
+        # Test simple case
+        (_, x, _, _) = self.data
+        test = append_fields(x, 'A', data=[10, 20, 30])
+        control = ma.array([(1, 10), (2, 20), (-1, 30)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('A', int)],)
+        assert_equal(test, control)
+
+    def test_append_double(self):
+        # Test simple case
+        (_, x, _, _) = self.data
+        test = append_fields(x, ('A', 'B'), data=[[10, 20, 30], [100, 200]])
+        control = ma.array([(1, 10, 100), (2, 20, 200), (-1, 30, -1)],
+                           mask=[(0, 0, 0), (0, 0, 0), (1, 0, 1)],
+                           dtype=[('f0', int), ('A', int), ('B', int)],)
+        assert_equal(test, control)
+
+    def test_append_on_flex(self):
+        # Test append_fields on flexible type arrays
+        z = self.data[-1]
+        test = append_fields(z, 'C', data=[10, 20, 30])
+        control = ma.array([('A', 1., 10), ('B', 2., 20), (-1, -1., 30)],
+                           mask=[(0, 0, 0), (0, 0, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', int)],)
+        assert_equal(test, control)
+
+    def test_append_on_nested(self):
+        # Test append_fields on nested fields
+        w = self.data[0]
+        test = append_fields(w, 'C', data=[10, 20, 30])
+        control = ma.array([(1, (2, 3.0), 10),
+                            (4, (5, 6.0), 20),
+                            (-1, (-1, -1.), 30)],
+                           mask=[(
+                               0, (0, 0), 0), (0, (0, 0), 0), (1, (1, 1), 0)],
+                           dtype=[('a', int),
+                                  ('b', [('ba', float), ('bb', int)]),
+                                  ('C', int)],)
+        assert_equal(test, control)
+
+
+class TestStackArrays(TestCase):
+    # Test stack_arrays
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_solo(self):
+        # Test stack_arrays on single arrays
+        (_, x, _, _) = self.data
+        test = stack_arrays((x,))
+        assert_equal(test, x)
+        self.assertTrue(test is x)
+
+        test = stack_arrays(x)
+        assert_equal(test, x)
+        self.assertTrue(test is x)
+
+    def test_unnamed_fields(self):
+        # Tests combinations of arrays w/o named fields
+        (_, x, y, _) = self.data
+
+        test = stack_arrays((x, x), usemask=False)
+        control = np.array([1, 2, 1, 2])
+        assert_equal(test, control)
+
+        test = stack_arrays((x, y), usemask=False)
+        control = np.array([1, 2, 10, 20, 30])
+        assert_equal(test, control)
+
+        test = stack_arrays((y, x), usemask=False)
+        control = np.array([10, 20, 30, 1, 2])
+        assert_equal(test, control)
+
+    def test_unnamed_and_named_fields(self):
+        # Test combination of arrays w/ & w/o named fields
+        (_, x, _, z) = self.data
+
+        test = stack_arrays((x, z))
+        control = ma.array([(1, -1, -1), (2, -1, -1),
+                            (-1, 'A', 1), (-1, 'B', 2)],
+                           mask=[(0, 1, 1), (0, 1, 1),
+                                 (1, 0, 0), (1, 0, 0)],
+                           dtype=[('f0', int), ('A', '|S3'), ('B', float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, x))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            (-1, -1, 1), (-1, -1, 2), ],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (1, 1, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('f2', int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, z, x))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            ('A', 1, -1), ('B', 2, -1),
+                            (-1, -1, 1), (-1, -1, 2), ],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 1), (0, 0, 1),
+                                 (1, 1, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('f2', int)])
+        assert_equal(test, control)
+
+    def test_matching_named_fields(self):
+        # Test combination of arrays w/ matching field names
+        (_, x, _, z) = self.data
+        zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                      dtype=[('A', '|S3'), ('B', float), ('C', float)])
+        test = stack_arrays((z, zz))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            (
+                                'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', float)],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 0), (0, 0, 0), (0, 0, 0)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, zz, x))
+        ndtype = [('A', '|S3'), ('B', float), ('C', float), ('f3', int)]
+        control = ma.array([('A', 1, -1, -1), ('B', 2, -1, -1),
+                            ('a', 10., 100., -1), ('b', 20., 200., -1),
+                            ('c', 30., 300., -1),
+                            (-1, -1, -1, 1), (-1, -1, -1, 2)],
+                           dtype=ndtype,
+                           mask=[(0, 0, 1, 1), (0, 0, 1, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (1, 1, 1, 0), (1, 1, 1, 0)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_defaults(self):
+        # Test defaults: no exception raised if keys of defaults are not fields.
+        (_, _, _, z) = self.data
+        zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                      dtype=[('A', '|S3'), ('B', float), ('C', float)])
+        defaults = {'A': '???', 'B': -999., 'C': -9999., 'D': -99999.}
+        test = stack_arrays((z, zz), defaults=defaults)
+        control = ma.array([('A', 1, -9999.), ('B', 2, -9999.),
+                            (
+                                'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', float)],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 0), (0, 0, 0), (0, 0, 0)])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_autoconversion(self):
+        # Tests autoconversion
+        adtype = [('A', int), ('B', bool), ('C', float)]
+        a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype)
+        bdtype = [('A', int), ('B', float), ('C', float)]
+        b = ma.array([(4, 5, 6)], dtype=bdtype)
+        control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)],
+                           dtype=bdtype)
+        test = stack_arrays((a, b), autoconvert=True)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        try:
+            test = stack_arrays((a, b), autoconvert=False)
+        except TypeError:
+            pass
+        else:
+            raise AssertionError
+
+    def test_checktitles(self):
+        # Test using titles in the field names
+        adtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)]
+        a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype)
+        bdtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)]
+        b = ma.array([(4, 5, 6)], dtype=bdtype)
+        test = stack_arrays((a, b))
+        control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)],
+                           dtype=bdtype)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+
+class TestJoinBy(TestCase):
+    def setUp(self):
+        self.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
+                                   np.arange(100, 110))),
+                          dtype=[('a', int), ('b', int), ('c', int)])
+        self.b = np.array(list(zip(np.arange(5, 15), np.arange(65, 75),
+                                   np.arange(100, 110))),
+                          dtype=[('a', int), ('b', int), ('d', int)])
+
+    def test_inner_join(self):
+        # Basic test of join_by
+        a, b = self.a, self.b
+
+        test = join_by('a', a, b, jointype='inner')
+        control = np.array([(5, 55, 65, 105, 100), (6, 56, 66, 106, 101),
+                            (7, 57, 67, 107, 102), (8, 58, 68, 108, 103),
+                            (9, 59, 69, 109, 104)],
+                           dtype=[('a', int), ('b1', int), ('b2', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_join(self):
+        a, b = self.a, self.b
+
+        # Fixme, this test is broken
+        #test = join_by(('a', 'b'), a, b)
+        #control = np.array([(5, 55, 105, 100), (6, 56, 106, 101),
+        #                    (7, 57, 107, 102), (8, 58, 108, 103),
+        #                    (9, 59, 109, 104)],
+        #                   dtype=[('a', int), ('b', int),
+        #                          ('c', int), ('d', int)])
+        #assert_equal(test, control)
+
+        # Hack to avoid pyflakes unused variable warnings
+        join_by(('a', 'b'), a, b)
+        np.array([(5, 55, 105, 100), (6, 56, 106, 101),
+                  (7, 57, 107, 102), (8, 58, 108, 103),
+                  (9, 59, 109, 104)],
+                  dtype=[('a', int), ('b', int),
+                         ('c', int), ('d', int)])
+
+    def test_outer_join(self):
+        a, b = self.a, self.b
+
+        test = join_by(('a', 'b'), a, b, 'outer')
+        control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1),
+                            (2, 52, 102, -1), (3, 53, 103, -1),
+                            (4, 54, 104, -1), (5, 55, 105, -1),
+                            (5, 65, -1, 100), (6, 56, 106, -1),
+                            (6, 66, -1, 101), (7, 57, 107, -1),
+                            (7, 67, -1, 102), (8, 58, 108, -1),
+                            (8, 68, -1, 103), (9, 59, 109, -1),
+                            (9, 69, -1, 104), (10, 70, -1, 105),
+                            (11, 71, -1, 106), (12, 72, -1, 107),
+                            (13, 73, -1, 108), (14, 74, -1, 109)],
+                           mask=[(0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 1, 0),
+                                 (0, 0, 1, 0), (0, 0, 1, 0),
+                                 (0, 0, 1, 0), (0, 0, 1, 0)],
+                           dtype=[('a', int), ('b', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_leftouter_join(self):
+        a, b = self.a, self.b
+
+        test = join_by(('a', 'b'), a, b, 'leftouter')
+        control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1),
+                            (2, 52, 102, -1), (3, 53, 103, -1),
+                            (4, 54, 104, -1), (5, 55, 105, -1),
+                            (6, 56, 106, -1), (7, 57, 107, -1),
+                            (8, 58, 108, -1), (9, 59, 109, -1)],
+                           mask=[(0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1)],
+                           dtype=[('a', int), ('b', int), ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+
+class TestJoinBy2(TestCase):
+    @classmethod
+    def setUp(cls):
+        cls.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
+                                  np.arange(100, 110))),
+                         dtype=[('a', int), ('b', int), ('c', int)])
+        cls.b = np.array(list(zip(np.arange(10), np.arange(65, 75),
+                                  np.arange(100, 110))),
+                         dtype=[('a', int), ('b', int), ('d', int)])
+
+    def test_no_r1postfix(self):
+        # Basic test of join_by no_r1postfix
+        a, b = self.a, self.b
+
+        test = join_by(
+            'a', a, b, r1postfix='', r2postfix='2', jointype='inner')
+        control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101),
+                            (2, 52, 67, 102, 102), (3, 53, 68, 103, 103),
+                            (4, 54, 69, 104, 104), (5, 55, 70, 105, 105),
+                            (6, 56, 71, 106, 106), (7, 57, 72, 107, 107),
+                            (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)],
+                           dtype=[('a', int), ('b', int), ('b2', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_no_postfix(self):
+        self.assertRaises(ValueError, join_by, 'a', self.a, self.b,
+                          r1postfix='', r2postfix='')
+
+    def test_no_r2postfix(self):
+        # Basic test of join_by no_r2postfix
+        a, b = self.a, self.b
+
+        test = join_by(
+            'a', a, b, r1postfix='1', r2postfix='', jointype='inner')
+        control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101),
+                            (2, 52, 67, 102, 102), (3, 53, 68, 103, 103),
+                            (4, 54, 69, 104, 104), (5, 55, 70, 105, 105),
+                            (6, 56, 71, 106, 106), (7, 57, 72, 107, 107),
+                            (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)],
+                           dtype=[('a', int), ('b1', int), ('b', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_two_keys_two_vars(self):
+        a = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2),
+                              np.arange(50, 60), np.arange(10, 20))),
+                     dtype=[('k', int), ('a', int), ('b', int), ('c', int)])
+
+        b = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2),
+                              np.arange(65, 75), np.arange(0, 10))),
+                     dtype=[('k', int), ('a', int), ('b', int), ('c', int)])
+
+        control = np.array([(10, 0, 50, 65, 10, 0), (11, 0, 51, 66, 11, 1),
+                            (10, 1, 52, 67, 12, 2), (11, 1, 53, 68, 13, 3),
+                            (10, 2, 54, 69, 14, 4), (11, 2, 55, 70, 15, 5),
+                            (10, 3, 56, 71, 16, 6), (11, 3, 57, 72, 17, 7),
+                            (10, 4, 58, 73, 18, 8), (11, 4, 59, 74, 19, 9)],
+                           dtype=[('k', int), ('a', int), ('b1', int),
+                                  ('b2', int), ('c1', int), ('c2', int)])
+        test = join_by(
+            ['a', 'k'], a, b, r1postfix='1', r2postfix='2', jointype='inner')
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test, control)
+
+class TestAppendFieldsObj(TestCase):
+    """
+    Test append_fields with arrays containing objects
+    """
+    # https://github.com/numpy/numpy/issues/2346
+
+    def setUp(self):
+        from datetime import date
+        self.data = dict(obj=date(2000, 1, 1))
+
+    def test_append_to_objects(self):
+        "Test append_fields when the base array contains objects"
+        obj = self.data['obj']
+        x = np.array([(obj, 1.), (obj, 2.)],
+                      dtype=[('A', object), ('B', float)])
+        y = np.array([10, 20], dtype=int)
+        test = append_fields(x, 'C', data=y, usemask=False)
+        control = np.array([(obj, 1.0, 10), (obj, 2.0, 20)],
+                           dtype=[('A', object), ('B', float), ('C', int)])
+        assert_equal(test, control)
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
new file mode 100644
index 0000000000..ee50dcfa4e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
@@ -0,0 +1,261 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_raises
+    )
+from numpy.testing.utils import _assert_valid_refcount
+from numpy.compat import unicode
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+    def test_poly1d(self, level=rlevel):
+        # Ticket #28
+        assert_equal(np.poly1d([1]) - np.poly1d([1, 0]),
+                     np.poly1d([-1, 1]))
+
+    def test_cov_parameters(self, level=rlevel):
+        # Ticket #91
+        x = np.random.random((3, 3))
+        y = x.copy()
+        np.cov(x, rowvar=1)
+        np.cov(y, rowvar=0)
+        assert_array_equal(x, y)
+
+    def test_mem_digitize(self, level=rlevel):
+        # Ticket #95
+        for i in range(100):
+            np.digitize([1, 2, 3, 4], [1, 3])
+            np.digitize([0, 1, 2, 3, 4], [1, 3])
+
+    def test_unique_zero_sized(self, level=rlevel):
+        # Ticket #205
+        assert_array_equal([], np.unique(np.array([])))
+
+    def test_mem_vectorise(self, level=rlevel):
+        # Ticket #325
+        vt = np.vectorize(lambda *args: args)
+        vt(np.zeros((1, 2, 1)), np.zeros((2, 1, 1)), np.zeros((1, 1, 2)))
+        vt(np.zeros((1, 2, 1)), np.zeros((2, 1, 1)), np.zeros((1,
+           1, 2)), np.zeros((2, 2)))
+
+    def test_mgrid_single_element(self, level=rlevel):
+        # Ticket #339
+        assert_array_equal(np.mgrid[0:0:1j], [0])
+        assert_array_equal(np.mgrid[0:0], [])
+
+    def test_refcount_vectorize(self, level=rlevel):
+        # Ticket #378
+        def p(x, y):
+            return 123
+        v = np.vectorize(p)
+        _assert_valid_refcount(v)
+
+    def test_poly1d_nan_roots(self, level=rlevel):
+        # Ticket #396
+        p = np.poly1d([np.nan, np.nan, 1], r=0)
+        self.assertRaises(np.linalg.LinAlgError, getattr, p, "r")
+
+    def test_mem_polymul(self, level=rlevel):
+        # Ticket #448
+        np.polymul([], [1.])
+
+    def test_mem_string_concat(self, level=rlevel):
+        # Ticket #469
+        x = np.array([])
+        np.append(x, 'asdasd\tasdasd')
+
+    def test_poly_div(self, level=rlevel):
+        # Ticket #553
+        u = np.poly1d([1, 2, 3])
+        v = np.poly1d([1, 2, 3, 4, 5])
+        q, r = np.polydiv(u, v)
+        assert_equal(q*v + r, u)
+
+    def test_poly_eq(self, level=rlevel):
+        # Ticket #554
+        x = np.poly1d([1, 2, 3])
+        y = np.poly1d([3, 4])
+        assert_(x != y)
+        assert_(x == x)
+
+    def test_polyfit_build(self):
+        # Ticket #628
+        ref = [-1.06123820e-06, 5.70886914e-04, -1.13822012e-01,
+               9.95368241e+00, -3.14526520e+02]
+        x = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+             104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+             116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129,
+             130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
+             146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
+             158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+             170, 171, 172, 173, 174, 175, 176]
+        y = [9.0, 3.0, 7.0, 4.0, 4.0, 8.0, 6.0, 11.0, 9.0, 8.0, 11.0, 5.0,
+             6.0, 5.0, 9.0, 8.0, 6.0, 10.0, 6.0, 10.0, 7.0, 6.0, 6.0, 6.0,
+             13.0, 4.0, 9.0, 11.0, 4.0, 5.0, 8.0, 5.0, 7.0, 7.0, 6.0, 12.0,
+             7.0, 7.0, 9.0, 4.0, 12.0, 6.0, 6.0, 4.0, 3.0, 9.0, 8.0, 8.0,
+             6.0, 7.0, 9.0, 10.0, 6.0, 8.0, 4.0, 7.0, 7.0, 10.0, 8.0, 8.0,
+             6.0, 3.0, 8.0, 4.0, 5.0, 7.0, 8.0, 6.0, 6.0, 4.0, 12.0, 9.0,
+             8.0, 8.0, 8.0, 6.0, 7.0, 4.0, 4.0, 5.0, 7.0]
+        tested = np.polyfit(x, y, 4)
+        assert_array_almost_equal(ref, tested)
+
+    def test_polydiv_type(self):
+        # Make polydiv work for complex types
+        msg = "Wrong type, should be complex"
+        x = np.ones(3, dtype=np.complex)
+        q, r = np.polydiv(x, x)
+        assert_(q.dtype == np.complex, msg)
+        msg = "Wrong type, should be float"
+        x = np.ones(3, dtype=np.int)
+        q, r = np.polydiv(x, x)
+        assert_(q.dtype == np.float, msg)
+
+    def test_histogramdd_too_many_bins(self):
+        # Ticket 928.
+        assert_raises(ValueError, np.histogramdd, np.ones((1, 10)), bins=2**10)
+
+    def test_polyint_type(self):
+        # Ticket #944
+        msg = "Wrong type, should be complex"
+        x = np.ones(3, dtype=np.complex)
+        assert_(np.polyint(x).dtype == np.complex, msg)
+        msg = "Wrong type, should be float"
+        x = np.ones(3, dtype=np.int)
+        assert_(np.polyint(x).dtype == np.float, msg)
+
+    def test_ndenumerate_crash(self):
+        # Ticket 1140
+        # Shouldn't crash:
+        list(np.ndenumerate(np.array([[]])))
+
+    def test_asfarray_none(self, level=rlevel):
+        # Test for changeset r5065
+        assert_array_equal(np.array([np.nan]), np.asfarray([None]))
+
+    def test_large_fancy_indexing(self, level=rlevel):
+        # Large enough to fail on 64-bit.
+        nbits = np.dtype(np.intp).itemsize * 8
+        thesize = int((2**nbits)**(1.0/5.0)+1)
+
+        def dp():
+            n = 3
+            a = np.ones((n,)*5)
+            i = np.random.randint(0, n, size=thesize)
+            a[np.ix_(i, i, i, i, i)] = 0
+
+        def dp2():
+            n = 3
+            a = np.ones((n,)*5)
+            i = np.random.randint(0, n, size=thesize)
+            a[np.ix_(i, i, i, i, i)]
+
+        self.assertRaises(ValueError, dp)
+        self.assertRaises(ValueError, dp2)
+
+    def test_void_coercion(self, level=rlevel):
+        dt = np.dtype([('a', 'f4'), ('b', 'i4')])
+        x = np.zeros((1,), dt)
+        assert_(np.r_[x, x].dtype == dt)
+
+    def test_who_with_0dim_array(self, level=rlevel):
+        # ticket #1243
+        import os
+        import sys
+
+        oldstdout = sys.stdout
+        sys.stdout = open(os.devnull, 'w')
+        try:
+            try:
+                np.who({'foo': np.array(1)})
+            except:
+                raise AssertionError("ticket #1243")
+        finally:
+            sys.stdout.close()
+            sys.stdout = oldstdout
+
+    def test_include_dirs(self):
+        # As a sanity check, just test that get_include
+        # includes something reasonable.  Somewhat
+        # related to ticket #1405.
+        include_dirs = [np.get_include()]
+        for path in include_dirs:
+            assert_(isinstance(path, (str, unicode)))
+            assert_(path != '')
+
+    def test_polyder_return_type(self):
+        # Ticket #1249
+        assert_(isinstance(np.polyder(np.poly1d([1]), 0), np.poly1d))
+        assert_(isinstance(np.polyder([1], 0), np.ndarray))
+        assert_(isinstance(np.polyder(np.poly1d([1]), 1), np.poly1d))
+        assert_(isinstance(np.polyder([1], 1), np.ndarray))
+
+    def test_append_fields_dtype_list(self):
+        # Ticket #1676
+        from numpy.lib.recfunctions import append_fields
+
+        base = np.array([1, 2, 3], dtype=np.int32)
+        names = ['a', 'b', 'c']
+        data = np.eye(3).astype(np.int32)
+        dlist = [np.float64, np.int32, np.int32]
+        try:
+            append_fields(base, names, data, dlist)
+        except:
+            raise AssertionError()
+
+    def test_loadtxt_fields_subarrays(self):
+        # For ticket #1936
+        if sys.version_info[0] >= 3:
+            from io import StringIO
+        else:
+            from StringIO import StringIO
+
+        dt = [("a", 'u1', 2), ("b", 'u1', 2)]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([((0, 1), (2, 3))], dtype=dt))
+
+        dt = [("a", [("a", 'u1', (1, 3)), ("b", 'u1')])]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([(((0, 1, 2), 3),)], dtype=dt))
+
+        dt = [("a", 'u1', (2, 2))]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([(((0, 1), (2, 3)),)], dtype=dt))
+
+        dt = [("a", 'u1', (2, 3, 2))]
+        x = np.loadtxt(StringIO("0 1 2 3 4 5 6 7 8 9 10 11"), dtype=dt)
+        data = [((((0, 1), (2, 3), (4, 5)), ((6, 7), (8, 9), (10, 11))),)]
+        assert_equal(x, np.array(data, dtype=dt))
+
+    def test_nansum_with_boolean(self):
+        # gh-2978
+        a = np.zeros(2, dtype=np.bool)
+        try:
+            np.nansum(a)
+        except:
+            raise AssertionError()
+
+    def test_py3_compat(self):
+        # gh-2561
+        # Test if the oldstyle class test is bypassed in python3
+        class C():
+            """Old-style class in python2, normal class in python3"""
+            pass
+
+        out = open(os.devnull, 'w')
+        try:
+            np.info(C(), output=out)
+        except AttributeError:
+            raise AssertionError()
+        finally:
+            out.close()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
new file mode 100644
index 0000000000..3f05f80c0b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
@@ -0,0 +1,380 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.lib.shape_base import (
+    apply_along_axis, apply_over_axes, array_split, split, hsplit, dsplit,
+    vsplit, dstack, kron, tile
+    )
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_raises, assert_warns
+    )
+
+
+class TestApplyAlongAxis(TestCase):
+    def test_simple(self):
+        a = np.ones((20, 10), 'd')
+        assert_array_equal(
+            apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1]))
+
+    def test_simple101(self, level=11):
+        a = np.ones((10, 101), 'd')
+        assert_array_equal(
+            apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1]))
+
+    def test_3d(self):
+        a = np.arange(27).reshape((3, 3, 3))
+        assert_array_equal(apply_along_axis(np.sum, 0, a),
+                           [[27, 30, 33], [36, 39, 42], [45, 48, 51]])
+
+
+class TestApplyOverAxes(TestCase):
+    def test_simple(self):
+        a = np.arange(24).reshape(2, 3, 4)
+        aoa_a = apply_over_axes(np.sum, a, [0, 2])
+        assert_array_equal(aoa_a, np.array([[[60], [92], [124]]]))
+
+
+class TestArraySplit(TestCase):
+    def test_integer_0_split(self):
+        a = np.arange(10)
+        assert_raises(ValueError, array_split, a, 0)
+
+    def test_integer_split(self):
+        a = np.arange(10)
+        res = array_split(a, 1)
+        desired = [np.arange(10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 2)
+        desired = [np.arange(5), np.arange(5, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 3)
+        desired = [np.arange(4), np.arange(4, 7), np.arange(7, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 4)
+        desired = [np.arange(3), np.arange(3, 6), np.arange(6, 8),
+                   np.arange(8, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 5)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 8), np.arange(8, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 6)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 8), np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 7)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 8)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 5),
+                   np.arange(5, 6), np.arange(6, 7), np.arange(7, 8),
+                   np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 9)
+        desired = [np.arange(2), np.arange(2, 3), np.arange(3, 4),
+                   np.arange(4, 5), np.arange(5, 6), np.arange(6, 7),
+                   np.arange(7, 8), np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 10)
+        desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3),
+                   np.arange(3, 4), np.arange(4, 5), np.arange(5, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 11)
+        desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3),
+                   np.arange(3, 4), np.arange(4, 5), np.arange(5, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10), np.array([])]
+        compare_results(res, desired)
+
+    def test_integer_split_2D_rows(self):
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3, axis=0)
+        tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]),
+                   np.zeros((0, 10))]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+
+        # Same thing for manual splits:
+        res = array_split(a, [0, 1, 2], axis=0)
+        tgt = [np.zeros((0, 10)), np.array([np.arange(10)]),
+               np.array([np.arange(10)])]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+
+    def test_integer_split_2D_cols(self):
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3, axis=-1)
+        desired = [np.array([np.arange(4), np.arange(4)]),
+                   np.array([np.arange(4, 7), np.arange(4, 7)]),
+                   np.array([np.arange(7, 10), np.arange(7, 10)])]
+        compare_results(res, desired)
+
+    def test_integer_split_2D_default(self):
+        """ This will fail if we change default axis
+        """
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3)
+        tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]),
+                   np.zeros((0, 10))]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+        # perhaps should check higher dimensions
+
+    def test_index_split_simple(self):
+        a = np.arange(10)
+        indices = [1, 5, 7]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.arange(0, 1), np.arange(1, 5), np.arange(5, 7),
+                   np.arange(7, 10)]
+        compare_results(res, desired)
+
+    def test_index_split_low_bound(self):
+        a = np.arange(10)
+        indices = [0, 5, 7]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.array([]), np.arange(0, 5), np.arange(5, 7),
+                   np.arange(7, 10)]
+        compare_results(res, desired)
+
+    def test_index_split_high_bound(self):
+        a = np.arange(10)
+        indices = [0, 5, 7, 10, 12]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.array([]), np.arange(0, 5), np.arange(5, 7),
+                   np.arange(7, 10), np.array([]), np.array([])]
+        compare_results(res, desired)
+
+
+class TestSplit(TestCase):
+    # The split function is essentially the same as array_split,
+    # except that it test if splitting will result in an
+    # equal split.  Only test for this case.
+
+    def test_equal_split(self):
+        a = np.arange(10)
+        res = split(a, 2)
+        desired = [np.arange(5), np.arange(5, 10)]
+        compare_results(res, desired)
+
+    def test_unequal_split(self):
+        a = np.arange(10)
+        assert_raises(ValueError, split, a, 3)
+
+
+class TestDstack(TestCase):
+    def test_0D_array(self):
+        a = np.array(1)
+        b = np.array(2)
+        res = dstack([a, b])
+        desired = np.array([[[1, 2]]])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = np.array([1])
+        b = np.array([2])
+        res = dstack([a, b])
+        desired = np.array([[[1, 2]]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = np.array([[1], [2]])
+        b = np.array([[1], [2]])
+        res = dstack([a, b])
+        desired = np.array([[[1, 1]], [[2, 2, ]]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array2(self):
+        a = np.array([1, 2])
+        b = np.array([1, 2])
+        res = dstack([a, b])
+        desired = np.array([[[1, 1], [2, 2]]])
+        assert_array_equal(res, desired)
+
+
+# array_split has more comprehensive test of splitting.
+# only do simple test on hsplit, vsplit, and dsplit
+class TestHsplit(TestCase):
+    """Only testing for integer splits.
+
+    """
+    def test_0D_array(self):
+        a = np.array(1)
+        try:
+            hsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_1D_array(self):
+        a = np.array([1, 2, 3, 4])
+        res = hsplit(a, 2)
+        desired = [np.array([1, 2]), np.array([3, 4])]
+        compare_results(res, desired)
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        res = hsplit(a, 2)
+        desired = [np.array([[1, 2], [1, 2]]), np.array([[3, 4], [3, 4]])]
+        compare_results(res, desired)
+
+
+class TestVsplit(TestCase):
+    """Only testing for integer splits.
+
+    """
+    def test_1D_array(self):
+        a = np.array([1, 2, 3, 4])
+        try:
+            vsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        res = vsplit(a, 2)
+        desired = [np.array([[1, 2, 3, 4]]), np.array([[1, 2, 3, 4]])]
+        compare_results(res, desired)
+
+
+class TestDsplit(TestCase):
+    # Only testing for integer splits.
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        try:
+            dsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_3D_array(self):
+        a = np.array([[[1, 2, 3, 4],
+                   [1, 2, 3, 4]],
+                  [[1, 2, 3, 4],
+                   [1, 2, 3, 4]]])
+        res = dsplit(a, 2)
+        desired = [np.array([[[1, 2], [1, 2]], [[1, 2], [1, 2]]]),
+                   np.array([[[3, 4], [3, 4]], [[3, 4], [3, 4]]])]
+        compare_results(res, desired)
+
+
+class TestSqueeze(TestCase):
+    def test_basic(self):
+        from numpy.random import rand
+
+        a = rand(20, 10, 10, 1, 1)
+        b = rand(20, 1, 10, 1, 20)
+        c = rand(1, 1, 20, 10)
+        assert_array_equal(np.squeeze(a), np.reshape(a, (20, 10, 10)))
+        assert_array_equal(np.squeeze(b), np.reshape(b, (20, 10, 20)))
+        assert_array_equal(np.squeeze(c), np.reshape(c, (20, 10)))
+
+        # Squeezing to 0-dim should still give an ndarray
+        a = [[[1.5]]]
+        res = np.squeeze(a)
+        assert_equal(res, 1.5)
+        assert_equal(res.ndim, 0)
+        assert_equal(type(res), np.ndarray)
+
+
+class TestKron(TestCase):
+    def test_return_type(self):
+        a = np.ones([2, 2])
+        m = np.asmatrix(a)
+        assert_equal(type(kron(a, a)), np.ndarray)
+        assert_equal(type(kron(m, m)), np.matrix)
+        assert_equal(type(kron(a, m)), np.matrix)
+        assert_equal(type(kron(m, a)), np.matrix)
+
+        class myarray(np.ndarray):
+            __array_priority__ = 0.0
+
+        ma = myarray(a.shape, a.dtype, a.data)
+        assert_equal(type(kron(a, a)), np.ndarray)
+        assert_equal(type(kron(ma, ma)), myarray)
+        assert_equal(type(kron(a, ma)), np.ndarray)
+        assert_equal(type(kron(ma, a)), myarray)
+
+
+class TestTile(TestCase):
+    def test_basic(self):
+        a = np.array([0, 1, 2])
+        b = [[1, 2], [3, 4]]
+        assert_equal(tile(a, 2), [0, 1, 2, 0, 1, 2])
+        assert_equal(tile(a, (2, 2)), [[0, 1, 2, 0, 1, 2], [0, 1, 2, 0, 1, 2]])
+        assert_equal(tile(a, (1, 2)), [[0, 1, 2, 0, 1, 2]])
+        assert_equal(tile(b, 2), [[1, 2, 1, 2], [3, 4, 3, 4]])
+        assert_equal(tile(b, (2, 1)), [[1, 2], [3, 4], [1, 2], [3, 4]])
+        assert_equal(tile(b, (2, 2)), [[1, 2, 1, 2], [3, 4, 3, 4],
+                                       [1, 2, 1, 2], [3, 4, 3, 4]])
+
+    def test_tile_one_repetition_on_array_gh4679(self):
+        a = np.arange(5)
+        b = tile(a, 1)
+        b += 2
+        assert_equal(a, np.arange(5))
+
+    def test_empty(self):
+        a = np.array([[[]]])
+        b = np.array([[], []])
+        c = tile(b, 2).shape
+        d = tile(a, (3, 2, 5)).shape
+        assert_equal(c, (2, 0))
+        assert_equal(d, (3, 2, 0))
+
+    def test_kroncompare(self):
+        from numpy.random import randint
+
+        reps = [(2,), (1, 2), (2, 1), (2, 2), (2, 3, 2), (3, 2)]
+        shape = [(3,), (2, 3), (3, 4, 3), (3, 2, 3), (4, 3, 2, 4), (2, 2)]
+        for s in shape:
+            b = randint(0, 10, size=s)
+            for r in reps:
+                a = np.ones(r, b.dtype)
+                large = tile(b, r)
+                klarge = kron(a, b)
+                assert_equal(large, klarge)
+
+
+class TestMayShareMemory(TestCase):
+    def test_basic(self):
+        d = np.ones((50, 60))
+        d2 = np.ones((30, 60, 6))
+        self.assertTrue(np.may_share_memory(d, d))
+        self.assertTrue(np.may_share_memory(d, d[::-1]))
+        self.assertTrue(np.may_share_memory(d, d[::2]))
+        self.assertTrue(np.may_share_memory(d, d[1:, ::-1]))
+
+        self.assertFalse(np.may_share_memory(d[::-1], d2))
+        self.assertFalse(np.may_share_memory(d[::2], d2))
+        self.assertFalse(np.may_share_memory(d[1:, ::-1], d2))
+        self.assertTrue(np.may_share_memory(d2[1:, ::-1], d2))
+
+
+# Utility
+def compare_results(res, desired):
+    for i in range(len(desired)):
+        assert_array_equal(res[i], desired[i])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
new file mode 100644
index 0000000000..06e6590023
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
@@ -0,0 +1,413 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_equal, assert_array_equal,
+    assert_raises, assert_
+    )
+from numpy.lib.stride_tricks import (
+    as_strided, broadcast_arrays, _broadcast_shape, broadcast_to
+)
+
+def assert_shapes_correct(input_shapes, expected_shape):
+    # Broadcast a list of arrays with the given input shapes and check the
+    # common output shape.
+
+    inarrays = [np.zeros(s) for s in input_shapes]
+    outarrays = broadcast_arrays(*inarrays)
+    outshapes = [a.shape for a in outarrays]
+    expected = [expected_shape] * len(inarrays)
+    assert_equal(outshapes, expected)
+
+
+def assert_incompatible_shapes_raise(input_shapes):
+    # Broadcast a list of arrays with the given (incompatible) input shapes
+    # and check that they raise a ValueError.
+
+    inarrays = [np.zeros(s) for s in input_shapes]
+    assert_raises(ValueError, broadcast_arrays, *inarrays)
+
+
+def assert_same_as_ufunc(shape0, shape1, transposed=False, flipped=False):
+    # Broadcast two shapes against each other and check that the data layout
+    # is the same as if a ufunc did the broadcasting.
+
+    x0 = np.zeros(shape0, dtype=int)
+    # Note that multiply.reduce's identity element is 1.0, so when shape1==(),
+    # this gives the desired n==1.
+    n = int(np.multiply.reduce(shape1))
+    x1 = np.arange(n).reshape(shape1)
+    if transposed:
+        x0 = x0.T
+        x1 = x1.T
+    if flipped:
+        x0 = x0[::-1]
+        x1 = x1[::-1]
+    # Use the add ufunc to do the broadcasting. Since we're adding 0s to x1, the
+    # result should be exactly the same as the broadcasted view of x1.
+    y = x0 + x1
+    b0, b1 = broadcast_arrays(x0, x1)
+    assert_array_equal(y, b1)
+
+
+def test_same():
+    x = np.arange(10)
+    y = np.arange(10)
+    bx, by = broadcast_arrays(x, y)
+    assert_array_equal(x, bx)
+    assert_array_equal(y, by)
+
+
+def test_one_off():
+    x = np.array([[1, 2, 3]])
+    y = np.array([[1], [2], [3]])
+    bx, by = broadcast_arrays(x, y)
+    bx0 = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
+    by0 = bx0.T
+    assert_array_equal(bx0, bx)
+    assert_array_equal(by0, by)
+
+
+def test_same_input_shapes():
+    # Check that the final shape is just the input shape.
+
+    data = [
+        (),
+        (1,),
+        (3,),
+        (0, 1),
+        (0, 3),
+        (1, 0),
+        (3, 0),
+        (1, 3),
+        (3, 1),
+        (3, 3),
+    ]
+    for shape in data:
+        input_shapes = [shape]
+        # Single input.
+        assert_shapes_correct(input_shapes, shape)
+        # Double input.
+        input_shapes2 = [shape, shape]
+        assert_shapes_correct(input_shapes2, shape)
+        # Triple input.
+        input_shapes3 = [shape, shape, shape]
+        assert_shapes_correct(input_shapes3, shape)
+
+
+def test_two_compatible_by_ones_input_shapes():
+    # Check that two different input shapes of the same length, but some have
+    # ones, broadcast to the correct shape.
+
+    data = [
+        [[(1,), (3,)], (3,)],
+        [[(1, 3), (3, 3)], (3, 3)],
+        [[(3, 1), (3, 3)], (3, 3)],
+        [[(1, 3), (3, 1)], (3, 3)],
+        [[(1, 1), (3, 3)], (3, 3)],
+        [[(1, 1), (1, 3)], (1, 3)],
+        [[(1, 1), (3, 1)], (3, 1)],
+        [[(1, 0), (0, 0)], (0, 0)],
+        [[(0, 1), (0, 0)], (0, 0)],
+        [[(1, 0), (0, 1)], (0, 0)],
+        [[(1, 1), (0, 0)], (0, 0)],
+        [[(1, 1), (1, 0)], (1, 0)],
+        [[(1, 1), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_shapes_correct(input_shapes, expected_shape)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_shapes_correct(input_shapes[::-1], expected_shape)
+
+
+def test_two_compatible_by_prepending_ones_input_shapes():
+    # Check that two different input shapes (of different lengths) broadcast
+    # to the correct shape.
+
+    data = [
+        [[(), (3,)], (3,)],
+        [[(3,), (3, 3)], (3, 3)],
+        [[(3,), (3, 1)], (3, 3)],
+        [[(1,), (3, 3)], (3, 3)],
+        [[(), (3, 3)], (3, 3)],
+        [[(1, 1), (3,)], (1, 3)],
+        [[(1,), (3, 1)], (3, 1)],
+        [[(1,), (1, 3)], (1, 3)],
+        [[(), (1, 3)], (1, 3)],
+        [[(), (3, 1)], (3, 1)],
+        [[(), (0,)], (0,)],
+        [[(0,), (0, 0)], (0, 0)],
+        [[(0,), (0, 1)], (0, 0)],
+        [[(1,), (0, 0)], (0, 0)],
+        [[(), (0, 0)], (0, 0)],
+        [[(1, 1), (0,)], (1, 0)],
+        [[(1,), (0, 1)], (0, 1)],
+        [[(1,), (1, 0)], (1, 0)],
+        [[(), (1, 0)], (1, 0)],
+        [[(), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_shapes_correct(input_shapes, expected_shape)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_shapes_correct(input_shapes[::-1], expected_shape)
+
+
+def test_incompatible_shapes_raise_valueerror():
+    # Check that a ValueError is raised for incompatible shapes.
+
+    data = [
+        [(3,), (4,)],
+        [(2, 3), (2,)],
+        [(3,), (3,), (4,)],
+        [(1, 3, 4), (2, 3, 3)],
+    ]
+    for input_shapes in data:
+        assert_incompatible_shapes_raise(input_shapes)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_incompatible_shapes_raise(input_shapes[::-1])
+
+
+def test_same_as_ufunc():
+    # Check that the data layout is the same as if a ufunc did the operation.
+
+    data = [
+        [[(1,), (3,)], (3,)],
+        [[(1, 3), (3, 3)], (3, 3)],
+        [[(3, 1), (3, 3)], (3, 3)],
+        [[(1, 3), (3, 1)], (3, 3)],
+        [[(1, 1), (3, 3)], (3, 3)],
+        [[(1, 1), (1, 3)], (1, 3)],
+        [[(1, 1), (3, 1)], (3, 1)],
+        [[(1, 0), (0, 0)], (0, 0)],
+        [[(0, 1), (0, 0)], (0, 0)],
+        [[(1, 0), (0, 1)], (0, 0)],
+        [[(1, 1), (0, 0)], (0, 0)],
+        [[(1, 1), (1, 0)], (1, 0)],
+        [[(1, 1), (0, 1)], (0, 1)],
+        [[(), (3,)], (3,)],
+        [[(3,), (3, 3)], (3, 3)],
+        [[(3,), (3, 1)], (3, 3)],
+        [[(1,), (3, 3)], (3, 3)],
+        [[(), (3, 3)], (3, 3)],
+        [[(1, 1), (3,)], (1, 3)],
+        [[(1,), (3, 1)], (3, 1)],
+        [[(1,), (1, 3)], (1, 3)],
+        [[(), (1, 3)], (1, 3)],
+        [[(), (3, 1)], (3, 1)],
+        [[(), (0,)], (0,)],
+        [[(0,), (0, 0)], (0, 0)],
+        [[(0,), (0, 1)], (0, 0)],
+        [[(1,), (0, 0)], (0, 0)],
+        [[(), (0, 0)], (0, 0)],
+        [[(1, 1), (0,)], (1, 0)],
+        [[(1,), (0, 1)], (0, 1)],
+        [[(1,), (1, 0)], (1, 0)],
+        [[(), (1, 0)], (1, 0)],
+        [[(), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_same_as_ufunc(input_shapes[0], input_shapes[1],
+                             "Shapes: %s %s" % (input_shapes[0], input_shapes[1]))
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_same_as_ufunc(input_shapes[1], input_shapes[0])
+        # Try them transposed, too.
+        assert_same_as_ufunc(input_shapes[0], input_shapes[1], True)
+        # ... and flipped for non-rank-0 inputs in order to test negative
+        # strides.
+        if () not in input_shapes:
+            assert_same_as_ufunc(input_shapes[0], input_shapes[1], False, True)
+            assert_same_as_ufunc(input_shapes[0], input_shapes[1], True, True)
+
+
+def test_broadcast_to_succeeds():
+    data = [
+        [np.array(0), (0,), np.array(0)],
+        [np.array(0), (1,), np.zeros(1)],
+        [np.array(0), (3,), np.zeros(3)],
+        [np.ones(1), (1,), np.ones(1)],
+        [np.ones(1), (2,), np.ones(2)],
+        [np.ones(1), (1, 2, 3), np.ones((1, 2, 3))],
+        [np.arange(3), (3,), np.arange(3)],
+        [np.arange(3), (1, 3), np.arange(3).reshape(1, -1)],
+        [np.arange(3), (2, 3), np.array([[0, 1, 2], [0, 1, 2]])],
+        # test if shape is not a tuple
+        [np.ones(0), 0, np.ones(0)],
+        [np.ones(1), 1, np.ones(1)],
+        [np.ones(1), 2, np.ones(2)],
+        # these cases with size 0 are strange, but they reproduce the behavior
+        # of broadcasting with ufuncs (see test_same_as_ufunc above)
+        [np.ones(1), (0,), np.ones(0)],
+        [np.ones((1, 2)), (0, 2), np.ones((0, 2))],
+        [np.ones((2, 1)), (2, 0), np.ones((2, 0))],
+    ]
+    for input_array, shape, expected in data:
+        actual = broadcast_to(input_array, shape)
+        assert_array_equal(expected, actual)
+
+
+def test_broadcast_to_raises():
+    data = [
+        [(0,), ()],
+        [(1,), ()],
+        [(3,), ()],
+        [(3,), (1,)],
+        [(3,), (2,)],
+        [(3,), (4,)],
+        [(1, 2), (2, 1)],
+        [(1, 1), (1,)],
+        [(1,), -1],
+        [(1,), (-1,)],
+        [(1, 2), (-1, 2)],
+    ]
+    for orig_shape, target_shape in data:
+        arr = np.zeros(orig_shape)
+        assert_raises(ValueError, lambda: broadcast_to(arr, target_shape))
+
+
+def test_broadcast_shape():
+    # broadcast_shape is already exercized indirectly by broadcast_arrays
+    assert_raises(ValueError, _broadcast_shape)
+    assert_equal(_broadcast_shape([1, 2]), (2,))
+    assert_equal(_broadcast_shape(np.ones((1, 1))), (1, 1))
+    assert_equal(_broadcast_shape(np.ones((1, 1)), np.ones((3, 4))), (3, 4))
+    assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 32)), (1, 2))
+    assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 100)), (1, 2))
+
+    # regression tests for gh-5862
+    assert_equal(_broadcast_shape(*([np.ones(2)] * 32 + [1])), (2,))
+    bad_args = [np.ones(2)] * 32 + [np.ones(3)] * 32
+    assert_raises(ValueError, lambda: _broadcast_shape(*bad_args))
+
+
+def test_as_strided():
+    a = np.array([None])
+    a_view = as_strided(a)
+    expected = np.array([None])
+    assert_array_equal(a_view, np.array([None]))
+
+    a = np.array([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,))
+    expected = np.array([1, 3])
+    assert_array_equal(a_view, expected)
+
+    a = np.array([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(3, 4), strides=(0, 1 * a.itemsize))
+    expected = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
+    assert_array_equal(a_view, expected)
+
+    # Regression test for gh-5081
+    dt = np.dtype([('num', 'i4'), ('obj', 'O')])
+    a = np.empty((4,), dtype=dt)
+    a['num'] = np.arange(1, 5)
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    expected_num = [[1, 2, 3, 4]] * 3
+    expected_obj = [[None]*4]*3
+    assert_equal(a_view.dtype, dt)
+    assert_array_equal(expected_num, a_view['num'])
+    assert_array_equal(expected_obj, a_view['obj'])
+
+    # Make sure that void types without fields are kept unchanged
+    a = np.empty((4,), dtype='V4')
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    assert_equal(a.dtype, a_view.dtype)
+
+    # Make sure that the only type that could fail is properly handled
+    dt = np.dtype({'names': [''], 'formats': ['V4']})
+    a = np.empty((4,), dtype=dt)
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    assert_equal(a.dtype, a_view.dtype)
+
+
+class VerySimpleSubClass(np.ndarray):
+    def __new__(cls, *args, **kwargs):
+        kwargs['subok'] = True
+        return np.array(*args, **kwargs).view(cls)
+
+
+class SimpleSubClass(VerySimpleSubClass):
+    def __new__(cls, *args, **kwargs):
+        kwargs['subok'] = True
+        self = np.array(*args, **kwargs).view(cls)
+        self.info = 'simple'
+        return self
+
+    def __array_finalize__(self, obj):
+        self.info = getattr(obj, 'info', '') + ' finalized'
+
+
+def test_subclasses():
+    # test that subclass is preserved only if subok=True
+    a = VerySimpleSubClass([1, 2, 3, 4])
+    assert_(type(a) is VerySimpleSubClass)
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,))
+    assert_(type(a_view) is np.ndarray)
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True)
+    assert_(type(a_view) is VerySimpleSubClass)
+    # test that if a subclass has __array_finalize__, it is used
+    a = SimpleSubClass([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+
+    # similar tests for broadcast_arrays
+    b = np.arange(len(a)).reshape(-1, 1)
+    a_view, b_view = broadcast_arrays(a, b)
+    assert_(type(a_view) is np.ndarray)
+    assert_(type(b_view) is np.ndarray)
+    assert_(a_view.shape == b_view.shape)
+    a_view, b_view = broadcast_arrays(a, b, subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+    assert_(type(b_view) is np.ndarray)
+    assert_(a_view.shape == b_view.shape)
+
+    # and for broadcast_to
+    shape = (2, 4)
+    a_view = broadcast_to(a, shape)
+    assert_(type(a_view) is np.ndarray)
+    assert_(a_view.shape == shape)
+    a_view = broadcast_to(a, shape, subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+    assert_(a_view.shape == shape)
+
+
+def test_writeable():
+    # broadcast_to should return a readonly array
+    original = np.array([1, 2, 3])
+    result = broadcast_to(original, (2, 3))
+    assert_equal(result.flags.writeable, False)
+    assert_raises(ValueError, result.__setitem__, slice(None), 0)
+
+    # but the result of broadcast_arrays needs to be writeable (for now), to
+    # preserve backwards compatibility
+    for results in [broadcast_arrays(original),
+                    broadcast_arrays(0, original)]:
+        for result in results:
+            assert_equal(result.flags.writeable, True)
+    # keep readonly input readonly
+    original.flags.writeable = False
+    _, result = broadcast_arrays(0, original)
+    assert_equal(result.flags.writeable, False)
+
+    # regresssion test for GH6491
+    shape = (2,)
+    strides = [0]
+    tricky_array = as_strided(np.array(0), shape, strides)
+    other = np.zeros((1,))
+    first, second = broadcast_arrays(tricky_array, other)
+    assert_(first.shape == second.shape)
+
+
+def test_reference_types():
+    input_array = np.array('a', dtype=object)
+    expected = np.array(['a'] * 3, dtype=object)
+    actual = broadcast_to(input_array, (3,))
+    assert_array_equal(expected, actual)
+
+    actual, _ = broadcast_arrays(input_array, np.ones(3))
+    assert_array_equal(expected, actual)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
new file mode 100644
index 0000000000..b65a8df97d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
@@ -0,0 +1,535 @@
+"""Test functions for matrix module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_array_max_ulp, assert_array_almost_equal, assert_raises, rand,
+    )
+
+from numpy import (
+    arange, rot90, add, fliplr, flipud, zeros, ones, eye, array, diag,
+    histogram2d, tri, mask_indices, triu_indices, triu_indices_from,
+    tril_indices, tril_indices_from, vander,
+    )
+
+import numpy as np
+from numpy.compat import asbytes_nested
+
+
+def get_mat(n):
+    data = arange(n)
+    data = add.outer(data, data)
+    return data
+
+
+class TestEye(TestCase):
+    def test_basic(self):
+        assert_equal(eye(4),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1]]))
+
+        assert_equal(eye(4, dtype='f'),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1]], 'f'))
+
+        assert_equal(eye(3) == 1,
+                     eye(3, dtype=bool))
+
+    def test_diag(self):
+        assert_equal(eye(4, k=1),
+                     array([[0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1],
+                            [0, 0, 0, 0]]))
+
+        assert_equal(eye(4, k=-1),
+                     array([[0, 0, 0, 0],
+                            [1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0]]))
+
+    def test_2d(self):
+        assert_equal(eye(4, 3),
+                     array([[1, 0, 0],
+                            [0, 1, 0],
+                            [0, 0, 1],
+                            [0, 0, 0]]))
+
+        assert_equal(eye(3, 4),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0]]))
+
+    def test_diag2d(self):
+        assert_equal(eye(3, 4, k=2),
+                     array([[0, 0, 1, 0],
+                            [0, 0, 0, 1],
+                            [0, 0, 0, 0]]))
+
+        assert_equal(eye(4, 3, k=-2),
+                     array([[0, 0, 0],
+                            [0, 0, 0],
+                            [1, 0, 0],
+                            [0, 1, 0]]))
+
+    def test_eye_bounds(self):
+        assert_equal(eye(2, 2, 1), [[0, 1], [0, 0]])
+        assert_equal(eye(2, 2, -1), [[0, 0], [1, 0]])
+        assert_equal(eye(2, 2, 2), [[0, 0], [0, 0]])
+        assert_equal(eye(2, 2, -2), [[0, 0], [0, 0]])
+        assert_equal(eye(3, 2, 2), [[0, 0], [0, 0], [0, 0]])
+        assert_equal(eye(3, 2, 1), [[0, 1], [0, 0], [0, 0]])
+        assert_equal(eye(3, 2, -1), [[0, 0], [1, 0], [0, 1]])
+        assert_equal(eye(3, 2, -2), [[0, 0], [0, 0], [1, 0]])
+        assert_equal(eye(3, 2, -3), [[0, 0], [0, 0], [0, 0]])
+
+    def test_strings(self):
+        assert_equal(eye(2, 2, dtype='S3'),
+                     asbytes_nested([['1', ''], ['', '1']]))
+
+    def test_bool(self):
+        assert_equal(eye(2, 2, dtype=bool), [[True, False], [False, True]])
+
+
+class TestDiag(TestCase):
+    def test_vector(self):
+        vals = (100 * arange(5)).astype('l')
+        b = zeros((5, 5))
+        for k in range(5):
+            b[k, k] = vals[k]
+        assert_equal(diag(vals), b)
+        b = zeros((7, 7))
+        c = b.copy()
+        for k in range(5):
+            b[k, k + 2] = vals[k]
+            c[k + 2, k] = vals[k]
+        assert_equal(diag(vals, k=2), b)
+        assert_equal(diag(vals, k=-2), c)
+
+    def test_matrix(self, vals=None):
+        if vals is None:
+            vals = (100 * get_mat(5) + 1).astype('l')
+        b = zeros((5,))
+        for k in range(5):
+            b[k] = vals[k, k]
+        assert_equal(diag(vals), b)
+        b = b * 0
+        for k in range(3):
+            b[k] = vals[k, k + 2]
+        assert_equal(diag(vals, 2), b[:3])
+        for k in range(3):
+            b[k] = vals[k + 2, k]
+        assert_equal(diag(vals, -2), b[:3])
+
+    def test_fortran_order(self):
+        vals = array((100 * get_mat(5) + 1), order='F', dtype='l')
+        self.test_matrix(vals)
+
+    def test_diag_bounds(self):
+        A = [[1, 2], [3, 4], [5, 6]]
+        assert_equal(diag(A, k=2), [])
+        assert_equal(diag(A, k=1), [2])
+        assert_equal(diag(A, k=0), [1, 4])
+        assert_equal(diag(A, k=-1), [3, 6])
+        assert_equal(diag(A, k=-2), [5])
+        assert_equal(diag(A, k=-3), [])
+
+    def test_failure(self):
+        self.assertRaises(ValueError, diag, [[[1]]])
+
+
+class TestFliplr(TestCase):
+    def test_basic(self):
+        self.assertRaises(ValueError, fliplr, ones(4))
+        a = get_mat(4)
+        b = a[:, ::-1]
+        assert_equal(fliplr(a), b)
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b = [[2, 1, 0],
+             [5, 4, 3]]
+        assert_equal(fliplr(a), b)
+
+
+class TestFlipud(TestCase):
+    def test_basic(self):
+        a = get_mat(4)
+        b = a[::-1, :]
+        assert_equal(flipud(a), b)
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b = [[3, 4, 5],
+             [0, 1, 2]]
+        assert_equal(flipud(a), b)
+
+
+class TestRot90(TestCase):
+    def test_basic(self):
+        self.assertRaises(ValueError, rot90, ones(4))
+
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b1 = [[2, 5],
+              [1, 4],
+              [0, 3]]
+        b2 = [[5, 4, 3],
+              [2, 1, 0]]
+        b3 = [[3, 0],
+              [4, 1],
+              [5, 2]]
+        b4 = [[0, 1, 2],
+              [3, 4, 5]]
+
+        for k in range(-3, 13, 4):
+            assert_equal(rot90(a, k=k), b1)
+        for k in range(-2, 13, 4):
+            assert_equal(rot90(a, k=k), b2)
+        for k in range(-1, 13, 4):
+            assert_equal(rot90(a, k=k), b3)
+        for k in range(0, 13, 4):
+            assert_equal(rot90(a, k=k), b4)
+
+    def test_axes(self):
+        a = ones((50, 40, 3))
+        assert_equal(rot90(a).shape, (40, 50, 3))
+
+
+class TestHistogram2d(TestCase):
+    def test_simple(self):
+        x = array(
+            [0.41702200, 0.72032449, 1.1437481e-4, 0.302332573, 0.146755891])
+        y = array(
+            [0.09233859, 0.18626021, 0.34556073, 0.39676747, 0.53881673])
+        xedges = np.linspace(0, 1, 10)
+        yedges = np.linspace(0, 1, 10)
+        H = histogram2d(x, y, (xedges, yedges))[0]
+        answer = array(
+            [[0, 0, 0, 1, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 1, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [1, 0, 1, 0, 0, 0, 0, 0, 0],
+             [0, 1, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0]])
+        assert_array_equal(H.T, answer)
+        H = histogram2d(x, y, xedges)[0]
+        assert_array_equal(H.T, answer)
+        H, xedges, yedges = histogram2d(list(range(10)), list(range(10)))
+        assert_array_equal(H, eye(10, 10))
+        assert_array_equal(xedges, np.linspace(0, 9, 11))
+        assert_array_equal(yedges, np.linspace(0, 9, 11))
+
+    def test_asym(self):
+        x = array([1, 1, 2, 3, 4, 4, 4, 5])
+        y = array([1, 3, 2, 0, 1, 2, 3, 4])
+        H, xed, yed = histogram2d(
+            x, y, (6, 5), range=[[0, 6], [0, 5]], normed=True)
+        answer = array(
+            [[0., 0, 0, 0, 0],
+             [0, 1, 0, 1, 0],
+             [0, 0, 1, 0, 0],
+             [1, 0, 0, 0, 0],
+             [0, 1, 1, 1, 0],
+             [0, 0, 0, 0, 1]])
+        assert_array_almost_equal(H, answer/8., 3)
+        assert_array_equal(xed, np.linspace(0, 6, 7))
+        assert_array_equal(yed, np.linspace(0, 5, 6))
+
+    def test_norm(self):
+        x = array([1, 2, 3, 1, 2, 3, 1, 2, 3])
+        y = array([1, 1, 1, 2, 2, 2, 3, 3, 3])
+        H, xed, yed = histogram2d(
+            x, y, [[1, 2, 3, 5], [1, 2, 3, 5]], normed=True)
+        answer = array([[1, 1, .5],
+                        [1, 1, .5],
+                        [.5, .5, .25]])/9.
+        assert_array_almost_equal(H, answer, 3)
+
+    def test_all_outliers(self):
+        r = rand(100) + 1. + 1e6  # histogramdd rounds by decimal=6
+        H, xed, yed = histogram2d(r, r, (4, 5), range=([0, 1], [0, 1]))
+        assert_array_equal(H, 0)
+
+    def test_empty(self):
+        a, edge1, edge2 = histogram2d([], [], bins=([0, 1], [0, 1]))
+        assert_array_max_ulp(a, array([[0.]]))
+
+        a, edge1, edge2 = histogram2d([], [], bins=4)
+        assert_array_max_ulp(a, np.zeros((4, 4)))
+
+    def test_binparameter_combination(self):
+        x = array(
+            [0, 0.09207008,  0.64575234,  0.12875982,  0.47390599,  
+             0.59944483, 1])
+        y = array(
+            [0, 0.14344267,  0.48988575,  0.30558665,  0.44700682,  
+             0.15886423, 1])
+        edges = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1)
+        H, xe, ye = histogram2d(x, y, (edges, 4))
+        answer = array(
+            [[ 2.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 1.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  1.]])
+        assert_array_equal(H, answer)
+        assert_array_equal(ye, array([0., 0.25, 0.5, 0.75, 1]))
+        H, xe, ye = histogram2d(x, y, (4, edges))
+        answer = array(
+            [[ 1.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])
+        assert_array_equal(H, answer)
+        assert_array_equal(xe, array([0., 0.25, 0.5, 0.75, 1]))
+
+
+class TestTri(TestCase):
+    def test_dtype(self):
+        out = array([[1, 0, 0],
+                     [1, 1, 0],
+                     [1, 1, 1]])
+        assert_array_equal(tri(3), out)
+        assert_array_equal(tri(3, dtype=bool), out.astype(bool))
+
+
+def test_tril_triu_ndim2():
+    for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']:
+        a = np.ones((2, 2), dtype=dtype)
+        b = np.tril(a)
+        c = np.triu(a)
+        yield assert_array_equal, b, [[1, 0], [1, 1]]
+        yield assert_array_equal, c, b.T
+        # should return the same dtype as the original array
+        yield assert_equal, b.dtype, a.dtype
+        yield assert_equal, c.dtype, a.dtype
+
+
+def test_tril_triu_ndim3():
+    for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']:
+        a = np.array([
+            [[1, 1], [1, 1]],
+            [[1, 1], [1, 0]],
+            [[1, 1], [0, 0]],
+            ], dtype=dtype)
+        a_tril_desired = np.array([
+            [[1, 0], [1, 1]],
+            [[1, 0], [1, 0]],
+            [[1, 0], [0, 0]],
+            ], dtype=dtype)
+        a_triu_desired = np.array([
+            [[1, 1], [0, 1]],
+            [[1, 1], [0, 0]],
+            [[1, 1], [0, 0]],
+            ], dtype=dtype)
+        a_triu_observed = np.triu(a)
+        a_tril_observed = np.tril(a)
+        yield assert_array_equal, a_triu_observed, a_triu_desired
+        yield assert_array_equal, a_tril_observed, a_tril_desired
+        yield assert_equal, a_triu_observed.dtype, a.dtype
+        yield assert_equal, a_tril_observed.dtype, a.dtype
+
+def test_tril_triu_with_inf():
+    # Issue 4859
+    arr = np.array([[1, 1, np.inf],
+                    [1, 1, 1],
+                    [np.inf, 1, 1]])
+    out_tril = np.array([[1, 0, 0],
+                         [1, 1, 0],
+                         [np.inf, 1, 1]])
+    out_triu = out_tril.T
+    assert_array_equal(np.triu(arr), out_triu)
+    assert_array_equal(np.tril(arr), out_tril)
+
+
+def test_tril_triu_dtype():
+    # Issue 4916
+    # tril and triu should return the same dtype as input
+    for c in np.typecodes['All']:
+        if c == 'V':
+            continue
+        arr = np.zeros((3, 3), dtype=c)
+        assert_equal(np.triu(arr).dtype, arr.dtype)
+        assert_equal(np.tril(arr).dtype, arr.dtype)
+
+    # check special cases
+    arr = np.array([['2001-01-01T12:00', '2002-02-03T13:56'],
+                    ['2004-01-01T12:00', '2003-01-03T13:45']],
+                   dtype='datetime64')
+    assert_equal(np.triu(arr).dtype, arr.dtype)
+    assert_equal(np.tril(arr).dtype, arr.dtype)
+
+    arr = np.zeros((3,3), dtype='f4,f4')
+    assert_equal(np.triu(arr).dtype, arr.dtype)
+    assert_equal(np.tril(arr).dtype, arr.dtype)
+
+
+def test_mask_indices():
+    # simple test without offset
+    iu = mask_indices(3, np.triu)
+    a = np.arange(9).reshape(3, 3)
+    yield (assert_array_equal, a[iu], array([0, 1, 2, 4, 5, 8]))
+    # Now with an offset
+    iu1 = mask_indices(3, np.triu, 1)
+    yield (assert_array_equal, a[iu1], array([1, 2, 5]))
+
+
+def test_tril_indices():
+    # indices without and with offset
+    il1 = tril_indices(4)
+    il2 = tril_indices(4, k=2)
+    il3 = tril_indices(4, m=5)
+    il4 = tril_indices(4, k=2, m=5)
+
+    a = np.array([[1, 2, 3, 4],
+                  [5, 6, 7, 8],
+                  [9, 10, 11, 12],
+                  [13, 14, 15, 16]])
+    b = np.arange(1, 21).reshape(4, 5)
+
+    # indexing:
+    yield (assert_array_equal, a[il1],
+           array([1, 5, 6, 9, 10, 11, 13, 14, 15, 16]))
+    yield (assert_array_equal, b[il3],
+           array([1, 6, 7, 11, 12, 13, 16, 17, 18, 19]))
+
+    # And for assigning values:
+    a[il1] = -1
+    yield (assert_array_equal, a,
+           array([[-1, 2, 3, 4],
+                  [-1, -1, 7, 8],
+                  [-1, -1, -1, 12],
+                  [-1, -1, -1, -1]]))
+    b[il3] = -1
+    yield (assert_array_equal, b,
+           array([[-1, 2, 3, 4, 5],
+                  [-1, -1, 8, 9, 10],
+                  [-1, -1, -1, 14, 15],
+                  [-1, -1, -1, -1, 20]]))
+    # These cover almost the whole array (two diagonals right of the main one):
+    a[il2] = -10
+    yield (assert_array_equal, a,
+           array([[-10, -10, -10, 4],
+                  [-10, -10, -10, -10],
+                  [-10, -10, -10, -10],
+                  [-10, -10, -10, -10]]))
+    b[il4] = -10
+    yield (assert_array_equal, b,
+           array([[-10, -10, -10, 4, 5],
+                  [-10, -10, -10, -10, 10],
+                  [-10, -10, -10, -10, -10],
+                  [-10, -10, -10, -10, -10]]))
+
+
+class TestTriuIndices(object):
+    def test_triu_indices(self):
+        iu1 = triu_indices(4)
+        iu2 = triu_indices(4, k=2)
+        iu3 = triu_indices(4, m=5)
+        iu4 = triu_indices(4, k=2, m=5)
+
+        a = np.array([[1, 2, 3, 4],
+                      [5, 6, 7, 8],
+                      [9, 10, 11, 12],
+                      [13, 14, 15, 16]])
+        b = np.arange(1, 21).reshape(4, 5)
+
+        # Both for indexing:
+        yield (assert_array_equal, a[iu1],
+               array([1, 2, 3, 4, 6, 7, 8, 11, 12, 16]))
+        yield (assert_array_equal, b[iu3],
+               array([1, 2, 3, 4, 5, 7, 8, 9, 10, 13, 14, 15, 19, 20]))
+
+        # And for assigning values:
+        a[iu1] = -1
+        yield (assert_array_equal, a,
+               array([[-1, -1, -1, -1],
+                      [5, -1, -1, -1],
+                      [9, 10, -1, -1],
+                      [13, 14, 15, -1]]))
+        b[iu3] = -1
+        yield (assert_array_equal, b,
+               array([[-1, -1, -1, -1, -1],
+                      [6, -1, -1, -1, -1],
+                      [11, 12, -1, -1, -1],
+                      [16, 17, 18, -1, -1]]))
+
+        # These cover almost the whole array (two diagonals right of the
+        # main one):
+        a[iu2] = -10
+        yield (assert_array_equal, a,
+               array([[-1, -1, -10, -10],
+                      [5, -1, -1, -10],
+                      [9, 10, -1, -1],
+                      [13, 14, 15, -1]]))
+        b[iu4] = -10
+        yield (assert_array_equal, b,
+               array([[-1, -1, -10, -10, -10],
+                      [6, -1, -1, -10, -10],
+                      [11, 12, -1, -1, -10],
+                      [16, 17, 18, -1, -1]]))
+
+
+class TestTrilIndicesFrom(object):
+    def test_exceptions(self):
+        assert_raises(ValueError, tril_indices_from, np.ones((2,)))
+        assert_raises(ValueError, tril_indices_from, np.ones((2, 2, 2)))
+        # assert_raises(ValueError, tril_indices_from, np.ones((2, 3)))
+
+
+class TestTriuIndicesFrom(object):
+    def test_exceptions(self):
+        assert_raises(ValueError, triu_indices_from, np.ones((2,)))
+        assert_raises(ValueError, triu_indices_from, np.ones((2, 2, 2)))
+        # assert_raises(ValueError, triu_indices_from, np.ones((2, 3)))
+
+
+class TestVander(object):
+    def test_basic(self):
+        c = np.array([0, 1, -2, 3])
+        v = vander(c)
+        powers = np.array([[0, 0, 0, 0, 1],
+                           [1, 1, 1, 1, 1],
+                           [16, -8, 4, -2, 1],
+                           [81, 27, 9, 3, 1]])
+        # Check default value of N:
+        yield (assert_array_equal, v, powers[:, 1:])
+        # Check a range of N values, including 0 and 5 (greater than default)
+        m = powers.shape[1]
+        for n in range(6):
+            v = vander(c, N=n)
+            yield (assert_array_equal, v, powers[:, m-n:m])
+
+    def test_dtypes(self):
+        c = array([11, -12, 13], dtype=np.int8)
+        v = vander(c)
+        expected = np.array([[121, 11, 1],
+                             [144, -12, 1],
+                             [169, 13, 1]])
+        yield (assert_array_equal, v, expected)
+
+        c = array([1.0+1j, 1.0-1j])
+        v = vander(c, N=3)
+        expected = np.array([[2j, 1+1j, 1],
+                             [-2j, 1-1j, 1]])
+        # The data is floating point, but the values are small integers,
+        # so assert_array_equal *should* be safe here (rather than, say,
+        # assert_array_almost_equal).
+        yield (assert_array_equal, v, expected)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
new file mode 100644
index 0000000000..f7430c27d1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
@@ -0,0 +1,332 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.compat import long
+from numpy.testing import (
+    TestCase, assert_, assert_equal, assert_array_equal, run_module_suite
+    )
+from numpy.lib.type_check import (
+    common_type, mintypecode, isreal, iscomplex, isposinf, isneginf,
+    nan_to_num, isrealobj, iscomplexobj, asfarray, real_if_close
+    )
+
+
+def assert_all(x):
+    assert_(np.all(x), x)
+
+
+class TestCommonType(TestCase):
+    def test_basic(self):
+        ai32 = np.array([[1, 2], [3, 4]], dtype=np.int32)
+        af16 = np.array([[1, 2], [3, 4]], dtype=np.float16)
+        af32 = np.array([[1, 2], [3, 4]], dtype=np.float32)
+        af64 = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        acs = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.csingle)
+        acd = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.cdouble)
+        assert_(common_type(ai32) == np.float64)
+        assert_(common_type(af16) == np.float16)
+        assert_(common_type(af32) == np.float32)
+        assert_(common_type(af64) == np.float64)
+        assert_(common_type(acs) == np.csingle)
+        assert_(common_type(acd) == np.cdouble)
+
+
+class TestMintypecode(TestCase):
+
+    def test_default_1(self):
+        for itype in '1bcsuwil':
+            assert_equal(mintypecode(itype), 'd')
+        assert_equal(mintypecode('f'), 'f')
+        assert_equal(mintypecode('d'), 'd')
+        assert_equal(mintypecode('F'), 'F')
+        assert_equal(mintypecode('D'), 'D')
+
+    def test_default_2(self):
+        for itype in '1bcsuwil':
+            assert_equal(mintypecode(itype+'f'), 'f')
+            assert_equal(mintypecode(itype+'d'), 'd')
+            assert_equal(mintypecode(itype+'F'), 'F')
+            assert_equal(mintypecode(itype+'D'), 'D')
+        assert_equal(mintypecode('ff'), 'f')
+        assert_equal(mintypecode('fd'), 'd')
+        assert_equal(mintypecode('fF'), 'F')
+        assert_equal(mintypecode('fD'), 'D')
+        assert_equal(mintypecode('df'), 'd')
+        assert_equal(mintypecode('dd'), 'd')
+        #assert_equal(mintypecode('dF',savespace=1),'F')
+        assert_equal(mintypecode('dF'), 'D')
+        assert_equal(mintypecode('dD'), 'D')
+        assert_equal(mintypecode('Ff'), 'F')
+        #assert_equal(mintypecode('Fd',savespace=1),'F')
+        assert_equal(mintypecode('Fd'), 'D')
+        assert_equal(mintypecode('FF'), 'F')
+        assert_equal(mintypecode('FD'), 'D')
+        assert_equal(mintypecode('Df'), 'D')
+        assert_equal(mintypecode('Dd'), 'D')
+        assert_equal(mintypecode('DF'), 'D')
+        assert_equal(mintypecode('DD'), 'D')
+
+    def test_default_3(self):
+        assert_equal(mintypecode('fdF'), 'D')
+        #assert_equal(mintypecode('fdF',savespace=1),'F')
+        assert_equal(mintypecode('fdD'), 'D')
+        assert_equal(mintypecode('fFD'), 'D')
+        assert_equal(mintypecode('dFD'), 'D')
+
+        assert_equal(mintypecode('ifd'), 'd')
+        assert_equal(mintypecode('ifF'), 'F')
+        assert_equal(mintypecode('ifD'), 'D')
+        assert_equal(mintypecode('idF'), 'D')
+        #assert_equal(mintypecode('idF',savespace=1),'F')
+        assert_equal(mintypecode('idD'), 'D')
+
+
+class TestIsscalar(TestCase):
+
+    def test_basic(self):
+        assert_(np.isscalar(3))
+        assert_(not np.isscalar([3]))
+        assert_(not np.isscalar((3,)))
+        assert_(np.isscalar(3j))
+        assert_(np.isscalar(long(10)))
+        assert_(np.isscalar(4.0))
+
+
+class TestReal(TestCase):
+
+    def test_real(self):
+        y = np.random.rand(10,)
+        assert_array_equal(y, np.real(y))
+
+    def test_cmplx(self):
+        y = np.random.rand(10,)+1j*np.random.rand(10,)
+        assert_array_equal(y.real, np.real(y))
+
+
+class TestImag(TestCase):
+
+    def test_real(self):
+        y = np.random.rand(10,)
+        assert_array_equal(0, np.imag(y))
+
+    def test_cmplx(self):
+        y = np.random.rand(10,)+1j*np.random.rand(10,)
+        assert_array_equal(y.imag, np.imag(y))
+
+
+class TestIscomplex(TestCase):
+
+    def test_fail(self):
+        z = np.array([-1, 0, 1])
+        res = iscomplex(z)
+        assert_(not np.sometrue(res, axis=0))
+
+    def test_pass(self):
+        z = np.array([-1j, 1, 0])
+        res = iscomplex(z)
+        assert_array_equal(res, [1, 0, 0])
+
+
+class TestIsreal(TestCase):
+
+    def test_pass(self):
+        z = np.array([-1, 0, 1j])
+        res = isreal(z)
+        assert_array_equal(res, [1, 1, 0])
+
+    def test_fail(self):
+        z = np.array([-1j, 1, 0])
+        res = isreal(z)
+        assert_array_equal(res, [0, 1, 1])
+
+
+class TestIscomplexobj(TestCase):
+
+    def test_basic(self):
+        z = np.array([-1, 0, 1])
+        assert_(not iscomplexobj(z))
+        z = np.array([-1j, 0, -1])
+        assert_(iscomplexobj(z))
+
+
+class TestIsrealobj(TestCase):
+    def test_basic(self):
+        z = np.array([-1, 0, 1])
+        assert_(isrealobj(z))
+        z = np.array([-1j, 0, -1])
+        assert_(not isrealobj(z))
+
+
+class TestIsnan(TestCase):
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isnan(z) == 0
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore'):
+            assert_all(np.isnan(np.array((1.,))/0.) == 0)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore'):
+            assert_all(np.isnan(np.array((-1.,))/0.) == 0)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isnan(np.array((0.,))/0.) == 1)
+
+    def test_integer(self):
+        assert_all(np.isnan(1) == 0)
+
+    def test_complex(self):
+        assert_all(np.isnan(1+1j) == 0)
+
+    def test_complex1(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isnan(np.array(0+0j)/0.) == 1)
+
+
+class TestIsfinite(TestCase):
+    # Fixme, wrong place, isfinite now ufunc
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isfinite(z) == 1
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((1.,))/0.) == 0)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((-1.,))/0.) == 0)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((0.,))/0.) == 0)
+
+    def test_integer(self):
+        assert_all(np.isfinite(1) == 1)
+
+    def test_complex(self):
+        assert_all(np.isfinite(1+1j) == 1)
+
+    def test_complex1(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array(1+1j)/0.) == 0)
+
+
+class TestIsinf(TestCase):
+    # Fixme, wrong place, isinf now ufunc
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isinf(z) == 0
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((1.,))/0.) == 1)
+
+    def test_posinf_scalar(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array(1.,)/0.) == 1)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((-1.,))/0.) == 1)
+
+    def test_neginf_scalar(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array(-1.)/0.) == 1)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((0.,))/0.) == 0)
+
+
+class TestIsposinf(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = isposinf(np.array((-1., 0, 1))/0.)
+        assert_(vals[0] == 0)
+        assert_(vals[1] == 0)
+        assert_(vals[2] == 1)
+
+
+class TestIsneginf(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = isneginf(np.array((-1., 0, 1))/0.)
+        assert_(vals[0] == 1)
+        assert_(vals[1] == 0)
+        assert_(vals[2] == 0)
+
+
+class TestNanToNum(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = nan_to_num(np.array((-1., 0, 1))/0.)
+        assert_all(vals[0] < -1e10) and assert_all(np.isfinite(vals[0]))
+        assert_(vals[1] == 0)
+        assert_all(vals[2] > 1e10) and assert_all(np.isfinite(vals[2]))
+
+    def test_integer(self):
+        vals = nan_to_num(1)
+        assert_all(vals == 1)
+        vals = nan_to_num([1])
+        assert_array_equal(vals, np.array([1], np.int))
+
+    def test_complex_good(self):
+        vals = nan_to_num(1+1j)
+        assert_all(vals == 1+1j)
+
+    def test_complex_bad(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            v = 1 + 1j
+            v += np.array(0+1.j)/0.
+        vals = nan_to_num(v)
+        # !! This is actually (unexpectedly) zero
+        assert_all(np.isfinite(vals))
+
+    def test_complex_bad2(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            v = 1 + 1j
+            v += np.array(-1+1.j)/0.
+        vals = nan_to_num(v)
+        assert_all(np.isfinite(vals))
+        # Fixme
+        #assert_all(vals.imag > 1e10)  and assert_all(np.isfinite(vals))
+        # !! This is actually (unexpectedly) positive
+        # !! inf.  Comment out for now, and see if it
+        # !! changes
+        #assert_all(vals.real < -1e10) and assert_all(np.isfinite(vals))
+
+
+class TestRealIfClose(TestCase):
+
+    def test_basic(self):
+        a = np.random.rand(10)
+        b = real_if_close(a+1e-15j)
+        assert_all(isrealobj(b))
+        assert_array_equal(a, b)
+        b = real_if_close(a+1e-7j)
+        assert_all(iscomplexobj(b))
+        b = real_if_close(a+1e-7j, tol=1e-6)
+        assert_all(isrealobj(b))
+
+
+class TestArrayConversion(TestCase):
+
+    def test_asfarray(self):
+        a = asfarray(np.array([1, 2, 3]))
+        assert_equal(a.__class__, np.ndarray)
+        assert_(np.issubdtype(a.dtype, np.float))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
new file mode 100644
index 0000000000..97d608ecfa
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
@@ -0,0 +1,65 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.core as nx
+import numpy.lib.ufunclike as ufl
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal
+    )
+
+
+class TestUfunclike(TestCase):
+
+    def test_isposinf(self):
+        a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0])
+        out = nx.zeros(a.shape, bool)
+        tgt = nx.array([True, False, False, False, False, False])
+
+        res = ufl.isposinf(a)
+        assert_equal(res, tgt)
+        res = ufl.isposinf(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+
+    def test_isneginf(self):
+        a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0])
+        out = nx.zeros(a.shape, bool)
+        tgt = nx.array([False, True, False, False, False, False])
+
+        res = ufl.isneginf(a)
+        assert_equal(res, tgt)
+        res = ufl.isneginf(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+
+    def test_fix(self):
+        a = nx.array([[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]])
+        out = nx.zeros(a.shape, float)
+        tgt = nx.array([[1., 1., 1., 1.], [-1., -1., -1., -1.]])
+
+        res = ufl.fix(a)
+        assert_equal(res, tgt)
+        res = ufl.fix(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+        assert_equal(ufl.fix(3.14), 3)
+
+    def test_fix_with_subclass(self):
+        class MyArray(nx.ndarray):
+            def __new__(cls, data, metadata=None):
+                res = nx.array(data, copy=True).view(cls)
+                res.metadata = metadata
+                return res
+
+            def __array_wrap__(self, obj, context=None):
+                obj.metadata = self.metadata
+                return obj
+
+        a = nx.array([1.1, -1.1])
+        m = MyArray(a, metadata='foo')
+        f = ufl.fix(m)
+        assert_array_equal(f, nx.array([1, -1]))
+        assert_(isinstance(f, MyArray))
+        assert_equal(f.metadata, 'foo')
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
new file mode 100644
index 0000000000..8fbd1c4457
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
@@ -0,0 +1,66 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.core import arange
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, dec
+    )
+from numpy.lib import deprecate
+import numpy.lib.utils as utils
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+
+@dec.skipif(sys.flags.optimize == 2)
+def test_lookfor():
+    out = StringIO()
+    utils.lookfor('eigenvalue', module='numpy', output=out,
+                  import_modules=False)
+    out = out.getvalue()
+    assert_('numpy.linalg.eig' in out)
+
+
+@deprecate
+def old_func(self, x):
+    return x
+
+
+@deprecate(message="Rather use new_func2")
+def old_func2(self, x):
+    return x
+
+
+def old_func3(self, x):
+    return x
+new_func3 = deprecate(old_func3, old_name="old_func3", new_name="new_func3")
+
+
+def test_deprecate_decorator():
+    assert_('deprecated' in old_func.__doc__)
+
+
+def test_deprecate_decorator_message():
+    assert_('Rather use new_func2' in old_func2.__doc__)
+
+
+def test_deprecate_fn():
+    assert_('old_func3' in new_func3.__doc__)
+    assert_('new_func3' in new_func3.__doc__)
+
+
+def test_safe_eval_nameconstant():
+    # Test if safe_eval supports Python 3.4 _ast.NameConstant
+    utils.safe_eval('None')
+
+
+def test_byte_bounds():
+    a = arange(12).reshape(3, 4)
+    low, high = utils.byte_bounds(a)
+    assert_equal(high - low, a.size * a.itemsize)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.py
new file mode 100644
index 0000000000..b2f350bb74
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.py
@@ -0,0 +1,1007 @@
+""" Basic functions for manipulating 2d arrays
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.core.numeric import (
+    asanyarray, arange, zeros, greater_equal, multiply, ones, asarray,
+    where, int8, int16, int32, int64, empty, promote_types, diagonal,
+    )
+from numpy.core import iinfo
+
+
+__all__ = [
+    'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'rot90', 'tri', 'triu',
+    'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices',
+    'tril_indices_from', 'triu_indices', 'triu_indices_from', ]
+
+
+i1 = iinfo(int8)
+i2 = iinfo(int16)
+i4 = iinfo(int32)
+
+
+def _min_int(low, high):
+    """ get small int that fits the range """
+    if high <= i1.max and low >= i1.min:
+        return int8
+    if high <= i2.max and low >= i2.min:
+        return int16
+    if high <= i4.max and low >= i4.min:
+        return int32
+    return int64
+
+
+def fliplr(m):
+    """
+    Flip array in the left/right direction.
+
+    Flip the entries in each row in the left/right direction.
+    Columns are preserved, but appear in a different order than before.
+
+    Parameters
+    ----------
+    m : array_like
+        Input array, must be at least 2-D.
+
+    Returns
+    -------
+    f : ndarray
+        A view of `m` with the columns reversed.  Since a view
+        is returned, this operation is :math:`\\mathcal O(1)`.
+
+    See Also
+    --------
+    flipud : Flip array in the up/down direction.
+    rot90 : Rotate array counterclockwise.
+
+    Notes
+    -----
+    Equivalent to A[:,::-1]. Requires the array to be at least 2-D.
+
+    Examples
+    --------
+    >>> A = np.diag([1.,2.,3.])
+    >>> A
+    array([[ 1.,  0.,  0.],
+           [ 0.,  2.,  0.],
+           [ 0.,  0.,  3.]])
+    >>> np.fliplr(A)
+    array([[ 0.,  0.,  1.],
+           [ 0.,  2.,  0.],
+           [ 3.,  0.,  0.]])
+
+    >>> A = np.random.randn(2,3,5)
+    >>> np.all(np.fliplr(A)==A[:,::-1,...])
+    True
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 2:
+        raise ValueError("Input must be >= 2-d.")
+    return m[:, ::-1]
+
+
+def flipud(m):
+    """
+    Flip array in the up/down direction.
+
+    Flip the entries in each column in the up/down direction.
+    Rows are preserved, but appear in a different order than before.
+
+    Parameters
+    ----------
+    m : array_like
+        Input array.
+
+    Returns
+    -------
+    out : array_like
+        A view of `m` with the rows reversed.  Since a view is
+        returned, this operation is :math:`\\mathcal O(1)`.
+
+    See Also
+    --------
+    fliplr : Flip array in the left/right direction.
+    rot90 : Rotate array counterclockwise.
+
+    Notes
+    -----
+    Equivalent to ``A[::-1,...]``.
+    Does not require the array to be two-dimensional.
+
+    Examples
+    --------
+    >>> A = np.diag([1.0, 2, 3])
+    >>> A
+    array([[ 1.,  0.,  0.],
+           [ 0.,  2.,  0.],
+           [ 0.,  0.,  3.]])
+    >>> np.flipud(A)
+    array([[ 0.,  0.,  3.],
+           [ 0.,  2.,  0.],
+           [ 1.,  0.,  0.]])
+
+    >>> A = np.random.randn(2,3,5)
+    >>> np.all(np.flipud(A)==A[::-1,...])
+    True
+
+    >>> np.flipud([1,2])
+    array([2, 1])
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 1:
+        raise ValueError("Input must be >= 1-d.")
+    return m[::-1, ...]
+
+
+def rot90(m, k=1):
+    """
+    Rotate an array by 90 degrees in the counter-clockwise direction.
+
+    The first two dimensions are rotated; therefore, the array must be at
+    least 2-D.
+
+    Parameters
+    ----------
+    m : array_like
+        Array of two or more dimensions.
+    k : integer
+        Number of times the array is rotated by 90 degrees.
+
+    Returns
+    -------
+    y : ndarray
+        Rotated array.
+
+    See Also
+    --------
+    fliplr : Flip an array horizontally.
+    flipud : Flip an array vertically.
+
+    Examples
+    --------
+    >>> m = np.array([[1,2],[3,4]], int)
+    >>> m
+    array([[1, 2],
+           [3, 4]])
+    >>> np.rot90(m)
+    array([[2, 4],
+           [1, 3]])
+    >>> np.rot90(m, 2)
+    array([[4, 3],
+           [2, 1]])
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 2:
+        raise ValueError("Input must >= 2-d.")
+    k = k % 4
+    if k == 0:
+        return m
+    elif k == 1:
+        return fliplr(m).swapaxes(0, 1)
+    elif k == 2:
+        return fliplr(flipud(m))
+    else:
+        # k == 3
+        return fliplr(m.swapaxes(0, 1))
+
+
+def eye(N, M=None, k=0, dtype=float):
+    """
+    Return a 2-D array with ones on the diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    N : int
+      Number of rows in the output.
+    M : int, optional
+      Number of columns in the output. If None, defaults to `N`.
+    k : int, optional
+      Index of the diagonal: 0 (the default) refers to the main diagonal,
+      a positive value refers to an upper diagonal, and a negative value
+      to a lower diagonal.
+    dtype : data-type, optional
+      Data-type of the returned array.
+
+    Returns
+    -------
+    I : ndarray of shape (N,M)
+      An array where all elements are equal to zero, except for the `k`-th
+      diagonal, whose values are equal to one.
+
+    See Also
+    --------
+    identity : (almost) equivalent function
+    diag : diagonal 2-D array from a 1-D array specified by the user.
+
+    Examples
+    --------
+    >>> np.eye(2, dtype=int)
+    array([[1, 0],
+           [0, 1]])
+    >>> np.eye(3, k=1)
+    array([[ 0.,  1.,  0.],
+           [ 0.,  0.,  1.],
+           [ 0.,  0.,  0.]])
+
+    """
+    if M is None:
+        M = N
+    m = zeros((N, M), dtype=dtype)
+    if k >= M:
+        return m
+    if k >= 0:
+        i = k
+    else:
+        i = (-k) * M
+    m[:M-k].flat[i::M+1] = 1
+    return m
+
+
+def diag(v, k=0):
+    """
+    Extract a diagonal or construct a diagonal array.
+
+    See the more detailed documentation for ``numpy.diagonal`` if you use this
+    function to extract a diagonal and wish to write to the resulting array;
+    whether it returns a copy or a view depends on what version of numpy you
+    are using.
+
+    Parameters
+    ----------
+    v : array_like
+        If `v` is a 2-D array, return a copy of its `k`-th diagonal.
+        If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
+        diagonal.
+    k : int, optional
+        Diagonal in question. The default is 0. Use `k>0` for diagonals
+        above the main diagonal, and `k<0` for diagonals below the main
+        diagonal.
+
+    Returns
+    -------
+    out : ndarray
+        The extracted diagonal or constructed diagonal array.
+
+    See Also
+    --------
+    diagonal : Return specified diagonals.
+    diagflat : Create a 2-D array with the flattened input as a diagonal.
+    trace : Sum along diagonals.
+    triu : Upper triangle of an array.
+    tril : Lower triangle of an array.
+
+    Examples
+    --------
+    >>> x = np.arange(9).reshape((3,3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5],
+           [6, 7, 8]])
+
+    >>> np.diag(x)
+    array([0, 4, 8])
+    >>> np.diag(x, k=1)
+    array([1, 5])
+    >>> np.diag(x, k=-1)
+    array([3, 7])
+
+    >>> np.diag(np.diag(x))
+    array([[0, 0, 0],
+           [0, 4, 0],
+           [0, 0, 8]])
+
+    """
+    v = asanyarray(v)
+    s = v.shape
+    if len(s) == 1:
+        n = s[0]+abs(k)
+        res = zeros((n, n), v.dtype)
+        if k >= 0:
+            i = k
+        else:
+            i = (-k) * n
+        res[:n-k].flat[i::n+1] = v
+        return res
+    elif len(s) == 2:
+        return diagonal(v, k)
+    else:
+        raise ValueError("Input must be 1- or 2-d.")
+
+
+def diagflat(v, k=0):
+    """
+    Create a two-dimensional array with the flattened input as a diagonal.
+
+    Parameters
+    ----------
+    v : array_like
+        Input data, which is flattened and set as the `k`-th
+        diagonal of the output.
+    k : int, optional
+        Diagonal to set; 0, the default, corresponds to the "main" diagonal,
+        a positive (negative) `k` giving the number of the diagonal above
+        (below) the main.
+
+    Returns
+    -------
+    out : ndarray
+        The 2-D output array.
+
+    See Also
+    --------
+    diag : MATLAB work-alike for 1-D and 2-D arrays.
+    diagonal : Return specified diagonals.
+    trace : Sum along diagonals.
+
+    Examples
+    --------
+    >>> np.diagflat([[1,2], [3,4]])
+    array([[1, 0, 0, 0],
+           [0, 2, 0, 0],
+           [0, 0, 3, 0],
+           [0, 0, 0, 4]])
+
+    >>> np.diagflat([1,2], 1)
+    array([[0, 1, 0],
+           [0, 0, 2],
+           [0, 0, 0]])
+
+    """
+    try:
+        wrap = v.__array_wrap__
+    except AttributeError:
+        wrap = None
+    v = asarray(v).ravel()
+    s = len(v)
+    n = s + abs(k)
+    res = zeros((n, n), v.dtype)
+    if (k >= 0):
+        i = arange(0, n-k)
+        fi = i+k+i*n
+    else:
+        i = arange(0, n+k)
+        fi = i+(i-k)*n
+    res.flat[fi] = v
+    if not wrap:
+        return res
+    return wrap(res)
+
+
+def tri(N, M=None, k=0, dtype=float):
+    """
+    An array with ones at and below the given diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    N : int
+        Number of rows in the array.
+    M : int, optional
+        Number of columns in the array.
+        By default, `M` is taken equal to `N`.
+    k : int, optional
+        The sub-diagonal at and below which the array is filled.
+        `k` = 0 is the main diagonal, while `k` < 0 is below it,
+        and `k` > 0 is above.  The default is 0.
+    dtype : dtype, optional
+        Data type of the returned array.  The default is float.
+
+    Returns
+    -------
+    tri : ndarray of shape (N, M)
+        Array with its lower triangle filled with ones and zero elsewhere;
+        in other words ``T[i,j] == 1`` for ``i <= j + k``, 0 otherwise.
+
+    Examples
+    --------
+    >>> np.tri(3, 5, 2, dtype=int)
+    array([[1, 1, 1, 0, 0],
+           [1, 1, 1, 1, 0],
+           [1, 1, 1, 1, 1]])
+
+    >>> np.tri(3, 5, -1)
+    array([[ 0.,  0.,  0.,  0.,  0.],
+           [ 1.,  0.,  0.,  0.,  0.],
+           [ 1.,  1.,  0.,  0.,  0.]])
+
+    """
+    if M is None:
+        M = N
+
+    m = greater_equal.outer(arange(N, dtype=_min_int(0, N)),
+                            arange(-k, M-k, dtype=_min_int(-k, M - k)))
+
+    # Avoid making a copy if the requested type is already bool
+    m = m.astype(dtype, copy=False)
+
+    return m
+
+
+def tril(m, k=0):
+    """
+    Lower triangle of an array.
+
+    Return a copy of an array with elements above the `k`-th diagonal zeroed.
+
+    Parameters
+    ----------
+    m : array_like, shape (M, N)
+        Input array.
+    k : int, optional
+        Diagonal above which to zero elements.  `k = 0` (the default) is the
+        main diagonal, `k < 0` is below it and `k > 0` is above.
+
+    Returns
+    -------
+    tril : ndarray, shape (M, N)
+        Lower triangle of `m`, of same shape and data-type as `m`.
+
+    See Also
+    --------
+    triu : same thing, only for the upper triangle
+
+    Examples
+    --------
+    >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
+    array([[ 0,  0,  0],
+           [ 4,  0,  0],
+           [ 7,  8,  0],
+           [10, 11, 12]])
+
+    """
+    m = asanyarray(m)
+    mask = tri(*m.shape[-2:], k=k, dtype=bool)
+
+    return where(mask, m, zeros(1, m.dtype))
+
+
+def triu(m, k=0):
+    """
+    Upper triangle of an array.
+
+    Return a copy of a matrix with the elements below the `k`-th diagonal
+    zeroed.
+
+    Please refer to the documentation for `tril` for further details.
+
+    See Also
+    --------
+    tril : lower triangle of an array
+
+    Examples
+    --------
+    >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
+    array([[ 1,  2,  3],
+           [ 4,  5,  6],
+           [ 0,  8,  9],
+           [ 0,  0, 12]])
+
+    """
+    m = asanyarray(m)
+    mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
+
+    return where(mask, zeros(1, m.dtype), m)
+
+
+# Originally borrowed from John Hunter and matplotlib
+def vander(x, N=None, increasing=False):
+    """
+    Generate a Vandermonde matrix.
+
+    The columns of the output matrix are powers of the input vector. The
+    order of the powers is determined by the `increasing` boolean argument.
+    Specifically, when `increasing` is False, the `i`-th output column is
+    the input vector raised element-wise to the power of ``N - i - 1``. Such
+    a matrix with a geometric progression in each row is named for Alexandre-
+    Theophile Vandermonde.
+
+    Parameters
+    ----------
+    x : array_like
+        1-D input array.
+    N : int, optional
+        Number of columns in the output.  If `N` is not specified, a square
+        array is returned (``N = len(x)``).
+    increasing : bool, optional
+        Order of the powers of the columns.  If True, the powers increase
+        from left to right, if False (the default) they are reversed.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    out : ndarray
+        Vandermonde matrix.  If `increasing` is False, the first column is
+        ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is
+        True, the columns are ``x^0, x^1, ..., x^(N-1)``.
+
+    See Also
+    --------
+    polynomial.polynomial.polyvander
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3, 5])
+    >>> N = 3
+    >>> np.vander(x, N)
+    array([[ 1,  1,  1],
+           [ 4,  2,  1],
+           [ 9,  3,  1],
+           [25,  5,  1]])
+
+    >>> np.column_stack([x**(N-1-i) for i in range(N)])
+    array([[ 1,  1,  1],
+           [ 4,  2,  1],
+           [ 9,  3,  1],
+           [25,  5,  1]])
+
+    >>> x = np.array([1, 2, 3, 5])
+    >>> np.vander(x)
+    array([[  1,   1,   1,   1],
+           [  8,   4,   2,   1],
+           [ 27,   9,   3,   1],
+           [125,  25,   5,   1]])
+    >>> np.vander(x, increasing=True)
+    array([[  1,   1,   1,   1],
+           [  1,   2,   4,   8],
+           [  1,   3,   9,  27],
+           [  1,   5,  25, 125]])
+
+    The determinant of a square Vandermonde matrix is the product
+    of the differences between the values of the input vector:
+
+    >>> np.linalg.det(np.vander(x))
+    48.000000000000043
+    >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1)
+    48
+
+    """
+    x = asarray(x)
+    if x.ndim != 1:
+        raise ValueError("x must be a one-dimensional array or sequence.")
+    if N is None:
+        N = len(x)
+
+    v = empty((len(x), N), dtype=promote_types(x.dtype, int))
+    tmp = v[:, ::-1] if not increasing else v
+
+    if N > 0:
+        tmp[:, 0] = 1
+    if N > 1:
+        tmp[:, 1:] = x[:, None]
+        multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1)
+
+    return v
+
+
+def histogram2d(x, y, bins=10, range=None, normed=False, weights=None):
+    """
+    Compute the bi-dimensional histogram of two data samples.
+
+    Parameters
+    ----------
+    x : array_like, shape (N,)
+        An array containing the x coordinates of the points to be
+        histogrammed.
+    y : array_like, shape (N,)
+        An array containing the y coordinates of the points to be
+        histogrammed.
+    bins : int or array_like or [int, int] or [array, array], optional
+        The bin specification:
+
+          * If int, the number of bins for the two dimensions (nx=ny=bins).
+          * If array_like, the bin edges for the two dimensions
+            (x_edges=y_edges=bins).
+          * If [int, int], the number of bins in each dimension
+            (nx, ny = bins).
+          * If [array, array], the bin edges in each dimension
+            (x_edges, y_edges = bins).
+          * A combination [int, array] or [array, int], where int
+            is the number of bins and array is the bin edges.
+
+    range : array_like, shape(2,2), optional
+        The leftmost and rightmost edges of the bins along each dimension
+        (if not specified explicitly in the `bins` parameters):
+        ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
+        will be considered outliers and not tallied in the histogram.
+    normed : bool, optional
+        If False, returns the number of samples in each bin. If True,
+        returns the bin density ``bin_count / sample_count / bin_area``.
+    weights : array_like, shape(N,), optional
+        An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
+        Weights are normalized to 1 if `normed` is True. If `normed` is
+        False, the values of the returned histogram are equal to the sum of
+        the weights belonging to the samples falling into each bin.
+
+    Returns
+    -------
+    H : ndarray, shape(nx, ny)
+        The bi-dimensional histogram of samples `x` and `y`. Values in `x`
+        are histogrammed along the first dimension and values in `y` are
+        histogrammed along the second dimension.
+    xedges : ndarray, shape(nx,)
+        The bin edges along the first dimension.
+    yedges : ndarray, shape(ny,)
+        The bin edges along the second dimension.
+
+    See Also
+    --------
+    histogram : 1D histogram
+    histogramdd : Multidimensional histogram
+
+    Notes
+    -----
+    When `normed` is True, then the returned histogram is the sample
+    density, defined such that the sum over bins of the product
+    ``bin_value * bin_area`` is 1.
+
+    Please note that the histogram does not follow the Cartesian convention
+    where `x` values are on the abscissa and `y` values on the ordinate
+    axis.  Rather, `x` is histogrammed along the first dimension of the
+    array (vertical), and `y` along the second dimension of the array
+    (horizontal).  This ensures compatibility with `histogramdd`.
+
+    Examples
+    --------
+    >>> import matplotlib as mpl
+    >>> import matplotlib.pyplot as plt
+
+    Construct a 2D-histogram with variable bin width. First define the bin
+    edges:
+
+    >>> xedges = [0, 1, 1.5, 3, 5]
+    >>> yedges = [0, 2, 3, 4, 6]
+
+    Next we create a histogram H with random bin content:
+
+    >>> x = np.random.normal(3, 1, 100)
+    >>> y = np.random.normal(1, 1, 100)
+    >>> H, xedges, yedges = np.histogram2d(y, x, bins=(xedges, yedges))
+
+    Or we fill the histogram H with a determined bin content:
+
+    >>> H = np.ones((4, 4)).cumsum().reshape(4, 4)
+    >>> print(H[::-1])  # This shows the bin content in the order as plotted
+    [[ 13.  14.  15.  16.]
+     [  9.  10.  11.  12.]
+     [  5.   6.   7.   8.]
+     [  1.   2.   3.   4.]]
+
+    Imshow can only do an equidistant representation of bins:
+
+    >>> fig = plt.figure(figsize=(7, 3))
+    >>> ax = fig.add_subplot(131)
+    >>> ax.set_title('imshow: equidistant')
+    >>> im = plt.imshow(H, interpolation='nearest', origin='low',
+                    extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
+
+    pcolormesh can display exact bin edges:
+
+    >>> ax = fig.add_subplot(132)
+    >>> ax.set_title('pcolormesh: exact bin edges')
+    >>> X, Y = np.meshgrid(xedges, yedges)
+    >>> ax.pcolormesh(X, Y, H)
+    >>> ax.set_aspect('equal')
+
+    NonUniformImage displays exact bin edges with interpolation:
+
+    >>> ax = fig.add_subplot(133)
+    >>> ax.set_title('NonUniformImage: interpolated')
+    >>> im = mpl.image.NonUniformImage(ax, interpolation='bilinear')
+    >>> xcenters = xedges[:-1] + 0.5 * (xedges[1:] - xedges[:-1])
+    >>> ycenters = yedges[:-1] + 0.5 * (yedges[1:] - yedges[:-1])
+    >>> im.set_data(xcenters, ycenters, H)
+    >>> ax.images.append(im)
+    >>> ax.set_xlim(xedges[0], xedges[-1])
+    >>> ax.set_ylim(yedges[0], yedges[-1])
+    >>> ax.set_aspect('equal')
+    >>> plt.show()
+
+    """
+    from numpy import histogramdd
+
+    try:
+        N = len(bins)
+    except TypeError:
+        N = 1
+
+    if N != 1 and N != 2:
+        xedges = yedges = asarray(bins, float)
+        bins = [xedges, yedges]
+    hist, edges = histogramdd([x, y], bins, range, normed, weights)
+    return hist, edges[0], edges[1]
+
+
+def mask_indices(n, mask_func, k=0):
+    """
+    Return the indices to access (n, n) arrays, given a masking function.
+
+    Assume `mask_func` is a function that, for a square array a of size
+    ``(n, n)`` with a possible offset argument `k`, when called as
+    ``mask_func(a, k)`` returns a new array with zeros in certain locations
+    (functions like `triu` or `tril` do precisely this). Then this function
+    returns the indices where the non-zero values would be located.
+
+    Parameters
+    ----------
+    n : int
+        The returned indices will be valid to access arrays of shape (n, n).
+    mask_func : callable
+        A function whose call signature is similar to that of `triu`, `tril`.
+        That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`.
+        `k` is an optional argument to the function.
+    k : scalar
+        An optional argument which is passed through to `mask_func`. Functions
+        like `triu`, `tril` take a second argument that is interpreted as an
+        offset.
+
+    Returns
+    -------
+    indices : tuple of arrays.
+        The `n` arrays of indices corresponding to the locations where
+        ``mask_func(np.ones((n, n)), k)`` is True.
+
+    See Also
+    --------
+    triu, tril, triu_indices, tril_indices
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    These are the indices that would allow you to access the upper triangular
+    part of any 3x3 array:
+
+    >>> iu = np.mask_indices(3, np.triu)
+
+    For example, if `a` is a 3x3 array:
+
+    >>> a = np.arange(9).reshape(3, 3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5],
+           [6, 7, 8]])
+    >>> a[iu]
+    array([0, 1, 2, 4, 5, 8])
+
+    An offset can be passed also to the masking function.  This gets us the
+    indices starting on the first diagonal right of the main one:
+
+    >>> iu1 = np.mask_indices(3, np.triu, 1)
+
+    with which we now extract only three elements:
+
+    >>> a[iu1]
+    array([1, 2, 5])
+
+    """
+    m = ones((n, n), int)
+    a = mask_func(m, k)
+    return where(a != 0)
+
+
+def tril_indices(n, k=0, m=None):
+    """
+    Return the indices for the lower-triangle of an (n, m) array.
+
+    Parameters
+    ----------
+    n : int
+        The row dimension of the arrays for which the returned
+        indices will be valid.
+    k : int, optional
+        Diagonal offset (see `tril` for details).
+    m : int, optional
+        .. versionadded:: 1.9.0
+
+        The column dimension of the arrays for which the returned
+        arrays will be valid.
+        By default `m` is taken equal to `n`.
+
+
+    Returns
+    -------
+    inds : tuple of arrays
+        The indices for the triangle. The returned tuple contains two arrays,
+        each with the indices along one dimension of the array.
+
+    See also
+    --------
+    triu_indices : similar function, for upper-triangular.
+    mask_indices : generic function accepting an arbitrary mask function.
+    tril, triu
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Compute two different sets of indices to access 4x4 arrays, one for the
+    lower triangular part starting at the main diagonal, and one starting two
+    diagonals further right:
+
+    >>> il1 = np.tril_indices(4)
+    >>> il2 = np.tril_indices(4, 2)
+
+    Here is how they can be used with a sample array:
+
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+
+    Both for indexing:
+
+    >>> a[il1]
+    array([ 0,  4,  5,  8,  9, 10, 12, 13, 14, 15])
+
+    And for assigning values:
+
+    >>> a[il1] = -1
+    >>> a
+    array([[-1,  1,  2,  3],
+           [-1, -1,  6,  7],
+           [-1, -1, -1, 11],
+           [-1, -1, -1, -1]])
+
+    These cover almost the whole array (two diagonals right of the main one):
+
+    >>> a[il2] = -10
+    >>> a
+    array([[-10, -10, -10,   3],
+           [-10, -10, -10, -10],
+           [-10, -10, -10, -10],
+           [-10, -10, -10, -10]])
+
+    """
+    return where(tri(n, m, k=k, dtype=bool))
+
+
+def tril_indices_from(arr, k=0):
+    """
+    Return the indices for the lower-triangle of arr.
+
+    See `tril_indices` for full details.
+
+    Parameters
+    ----------
+    arr : array_like
+        The indices will be valid for square arrays whose dimensions are
+        the same as arr.
+    k : int, optional
+        Diagonal offset (see `tril` for details).
+
+    See Also
+    --------
+    tril_indices, tril
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if arr.ndim != 2:
+        raise ValueError("input array must be 2-d")
+    return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1])
+
+
+def triu_indices(n, k=0, m=None):
+    """
+    Return the indices for the upper-triangle of an (n, m) array.
+
+    Parameters
+    ----------
+    n : int
+        The size of the arrays for which the returned indices will
+        be valid.
+    k : int, optional
+        Diagonal offset (see `triu` for details).
+    m : int, optional
+        .. versionadded:: 1.9.0
+
+        The column dimension of the arrays for which the returned
+        arrays will be valid.
+        By default `m` is taken equal to `n`.
+
+
+    Returns
+    -------
+    inds : tuple, shape(2) of ndarrays, shape(`n`)
+        The indices for the triangle. The returned tuple contains two arrays,
+        each with the indices along one dimension of the array.  Can be used
+        to slice a ndarray of shape(`n`, `n`).
+
+    See also
+    --------
+    tril_indices : similar function, for lower-triangular.
+    mask_indices : generic function accepting an arbitrary mask function.
+    triu, tril
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Compute two different sets of indices to access 4x4 arrays, one for the
+    upper triangular part starting at the main diagonal, and one starting two
+    diagonals further right:
+
+    >>> iu1 = np.triu_indices(4)
+    >>> iu2 = np.triu_indices(4, 2)
+
+    Here is how they can be used with a sample array:
+
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+
+    Both for indexing:
+
+    >>> a[iu1]
+    array([ 0,  1,  2,  3,  5,  6,  7, 10, 11, 15])
+
+    And for assigning values:
+
+    >>> a[iu1] = -1
+    >>> a
+    array([[-1, -1, -1, -1],
+           [ 4, -1, -1, -1],
+           [ 8,  9, -1, -1],
+           [12, 13, 14, -1]])
+
+    These cover only a small part of the whole array (two diagonals right
+    of the main one):
+
+    >>> a[iu2] = -10
+    >>> a
+    array([[ -1,  -1, -10, -10],
+           [  4,  -1,  -1, -10],
+           [  8,   9,  -1,  -1],
+           [ 12,  13,  14,  -1]])
+
+    """
+    return where(~tri(n, m, k=k-1, dtype=bool))
+
+
+def triu_indices_from(arr, k=0):
+    """
+    Return the indices for the upper-triangle of arr.
+
+    See `triu_indices` for full details.
+
+    Parameters
+    ----------
+    arr : ndarray, shape(N, N)
+        The indices will be valid for square arrays.
+    k : int, optional
+        Diagonal offset (see `triu` for details).
+
+    Returns
+    -------
+    triu_indices_from : tuple, shape(2) of ndarray, shape(N)
+        Indices for the upper-triangle of `arr`.
+
+    See Also
+    --------
+    triu_indices, triu
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if arr.ndim != 2:
+        raise ValueError("input array must be 2-d")
+    return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/type_check.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/type_check.py
new file mode 100644
index 0000000000..1313adff71
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/type_check.py
@@ -0,0 +1,596 @@
+"""Automatically adapted for numpy Sep 19, 2005 by convertcode.py
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['iscomplexobj', 'isrealobj', 'imag', 'iscomplex',
+           'isreal', 'nan_to_num', 'real', 'real_if_close',
+           'typename', 'asfarray', 'mintypecode', 'asscalar',
+           'common_type']
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import asarray, asanyarray, array, isnan, \
+                obj2sctype, zeros
+from .ufunclike import isneginf, isposinf
+
+_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb?'
+
+def mintypecode(typechars,typeset='GDFgdf',default='d'):
+    """
+    Return the character for the minimum-size type to which given types can
+    be safely cast.
+
+    The returned type character must represent the smallest size dtype such
+    that an array of the returned type can handle the data from an array of
+    all types in `typechars` (or if `typechars` is an array, then its
+    dtype.char).
+
+    Parameters
+    ----------
+    typechars : list of str or array_like
+        If a list of strings, each string should represent a dtype.
+        If array_like, the character representation of the array dtype is used.
+    typeset : str or list of str, optional
+        The set of characters that the returned character is chosen from.
+        The default set is 'GDFgdf'.
+    default : str, optional
+        The default character, this is returned if none of the characters in
+        `typechars` matches a character in `typeset`.
+
+    Returns
+    -------
+    typechar : str
+        The character representing the minimum-size type that was found.
+
+    See Also
+    --------
+    dtype, sctype2char, maximum_sctype
+
+    Examples
+    --------
+    >>> np.mintypecode(['d', 'f', 'S'])
+    'd'
+    >>> x = np.array([1.1, 2-3.j])
+    >>> np.mintypecode(x)
+    'D'
+
+    >>> np.mintypecode('abceh', default='G')
+    'G'
+
+    """
+    typecodes = [(isinstance(t, str) and t) or asarray(t).dtype.char
+                 for t in typechars]
+    intersection = [t for t in typecodes if t in typeset]
+    if not intersection:
+        return default
+    if 'F' in intersection and 'd' in intersection:
+        return 'D'
+    l = []
+    for t in intersection:
+        i = _typecodes_by_elsize.index(t)
+        l.append((i, t))
+    l.sort()
+    return l[0][1]
+
+def asfarray(a, dtype=_nx.float_):
+    """
+    Return an array converted to a float type.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    dtype : str or dtype object, optional
+        Float type code to coerce input array `a`.  If `dtype` is one of the
+        'int' dtypes, it is replaced with float64.
+
+    Returns
+    -------
+    out : ndarray
+        The input `a` as a float ndarray.
+
+    Examples
+    --------
+    >>> np.asfarray([2, 3])
+    array([ 2.,  3.])
+    >>> np.asfarray([2, 3], dtype='float')
+    array([ 2.,  3.])
+    >>> np.asfarray([2, 3], dtype='int8')
+    array([ 2.,  3.])
+
+    """
+    dtype = _nx.obj2sctype(dtype)
+    if not issubclass(dtype, _nx.inexact):
+        dtype = _nx.float_
+    return asarray(a, dtype=dtype)
+
+def real(val):
+    """
+    Return the real part of the elements of the array.
+
+    Parameters
+    ----------
+    val : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array. If `val` is real, the type of `val` is used for the
+        output.  If `val` has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real_if_close, imag, angle
+
+    Examples
+    --------
+    >>> a = np.array([1+2j, 3+4j, 5+6j])
+    >>> a.real
+    array([ 1.,  3.,  5.])
+    >>> a.real = 9
+    >>> a
+    array([ 9.+2.j,  9.+4.j,  9.+6.j])
+    >>> a.real = np.array([9, 8, 7])
+    >>> a
+    array([ 9.+2.j,  8.+4.j,  7.+6.j])
+
+    """
+    return asanyarray(val).real
+
+def imag(val):
+    """
+    Return the imaginary part of the elements of the array.
+
+    Parameters
+    ----------
+    val : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array. If `val` is real, the type of `val` is used for the
+        output.  If `val` has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real, angle, real_if_close
+
+    Examples
+    --------
+    >>> a = np.array([1+2j, 3+4j, 5+6j])
+    >>> a.imag
+    array([ 2.,  4.,  6.])
+    >>> a.imag = np.array([8, 10, 12])
+    >>> a
+    array([ 1. +8.j,  3.+10.j,  5.+12.j])
+
+    """
+    return asanyarray(val).imag
+
+def iscomplex(x):
+    """
+    Returns a bool array, where True if input element is complex.
+
+    What is tested is whether the input has a non-zero imaginary part, not if
+    the input type is complex.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray of bools
+        Output array.
+
+    See Also
+    --------
+    isreal
+    iscomplexobj : Return True if x is a complex type or an array of complex
+                   numbers.
+
+    Examples
+    --------
+    >>> np.iscomplex([1+1j, 1+0j, 4.5, 3, 2, 2j])
+    array([ True, False, False, False, False,  True], dtype=bool)
+
+    """
+    ax = asanyarray(x)
+    if issubclass(ax.dtype.type, _nx.complexfloating):
+        return ax.imag != 0
+    res = zeros(ax.shape, bool)
+    return +res  # convet to array-scalar if needed
+
+def isreal(x):
+    """
+    Returns a bool array, where True if input element is real.
+
+    If element has complex type with zero complex part, the return value
+    for that element is True.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Boolean array of same shape as `x`.
+
+    See Also
+    --------
+    iscomplex
+    isrealobj : Return True if x is not a complex type.
+
+    Examples
+    --------
+    >>> np.isreal([1+1j, 1+0j, 4.5, 3, 2, 2j])
+    array([False,  True,  True,  True,  True, False], dtype=bool)
+
+    """
+    return imag(x) == 0
+
+def iscomplexobj(x):
+    """
+    Check for a complex type or an array of complex numbers.
+
+    The type of the input is checked, not the value. Even if the input
+    has an imaginary part equal to zero, `iscomplexobj` evaluates to True.
+
+    Parameters
+    ----------
+    x : any
+        The input can be of any type and shape.
+
+    Returns
+    -------
+    iscomplexobj : bool
+        The return value, True if `x` is of a complex type or has at least
+        one complex element.
+
+    See Also
+    --------
+    isrealobj, iscomplex
+
+    Examples
+    --------
+    >>> np.iscomplexobj(1)
+    False
+    >>> np.iscomplexobj(1+0j)
+    True
+    >>> np.iscomplexobj([3, 1+0j, True])
+    True
+
+    """
+    return issubclass(asarray(x).dtype.type, _nx.complexfloating)
+
+def isrealobj(x):
+    """
+    Return True if x is a not complex type or an array of complex numbers.
+
+    The type of the input is checked, not the value. So even if the input
+    has an imaginary part equal to zero, `isrealobj` evaluates to False
+    if the data type is complex.
+
+    Parameters
+    ----------
+    x : any
+        The input can be of any type and shape.
+
+    Returns
+    -------
+    y : bool
+        The return value, False if `x` is of a complex type.
+
+    See Also
+    --------
+    iscomplexobj, isreal
+
+    Examples
+    --------
+    >>> np.isrealobj(1)
+    True
+    >>> np.isrealobj(1+0j)
+    False
+    >>> np.isrealobj([3, 1+0j, True])
+    False
+
+    """
+    return not issubclass(asarray(x).dtype.type, _nx.complexfloating)
+
+#-----------------------------------------------------------------------------
+
+def _getmaxmin(t):
+    from numpy.core import getlimits
+    f = getlimits.finfo(t)
+    return f.max, f.min
+
+def nan_to_num(x):
+    """
+    Replace nan with zero and inf with finite numbers.
+
+    Returns an array or scalar replacing Not a Number (NaN) with zero,
+    (positive) infinity with a very large number and negative infinity
+    with a very small (or negative) number.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data.
+
+    Returns
+    -------
+    out : ndarray
+        New Array with the same shape as `x` and dtype of the element in
+        `x`  with the greatest precision. If `x` is inexact, then NaN is
+        replaced by zero, and infinity (-infinity) is replaced by the
+        largest (smallest or most negative) floating point value that fits
+        in the output dtype. If `x` is not inexact, then a copy of `x` is
+        returned.
+
+    See Also
+    --------
+    isinf : Shows which elements are negative or negative infinity.
+    isneginf : Shows which elements are negative infinity.
+    isposinf : Shows which elements are positive infinity.
+    isnan : Shows which elements are Not a Number (NaN).
+    isfinite : Shows which elements are finite (not NaN, not infinity)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=8)
+    >>> x = np.array([np.inf, -np.inf, np.nan, -128, 128])
+    >>> np.nan_to_num(x)
+    array([  1.79769313e+308,  -1.79769313e+308,   0.00000000e+000,
+            -1.28000000e+002,   1.28000000e+002])
+
+    """
+    x = _nx.array(x, subok=True)
+    xtype = x.dtype.type
+    if not issubclass(xtype, _nx.inexact):
+        return x
+
+    iscomplex = issubclass(xtype, _nx.complexfloating)
+    isscalar = (x.ndim == 0)
+
+    x = x[None] if isscalar else x
+    dest = (x.real, x.imag) if iscomplex else (x,)
+    maxf, minf = _getmaxmin(x.real.dtype)
+    for d in dest:
+        _nx.copyto(d, 0.0, where=isnan(d))
+        _nx.copyto(d, maxf, where=isposinf(d))
+        _nx.copyto(d, minf, where=isneginf(d))
+    return x[0] if isscalar else x
+
+#-----------------------------------------------------------------------------
+
+def real_if_close(a,tol=100):
+    """
+    If complex input returns a real array if complex parts are close to zero.
+
+    "Close to zero" is defined as `tol` * (machine epsilon of the type for
+    `a`).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    tol : float
+        Tolerance in machine epsilons for the complex part of the elements
+        in the array.
+
+    Returns
+    -------
+    out : ndarray
+        If `a` is real, the type of `a` is used for the output.  If `a`
+        has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real, imag, angle
+
+    Notes
+    -----
+    Machine epsilon varies from machine to machine and between data types
+    but Python floats on most platforms have a machine epsilon equal to
+    2.2204460492503131e-16.  You can use 'np.finfo(np.float).eps' to print
+    out the machine epsilon for floats.
+
+    Examples
+    --------
+    >>> np.finfo(np.float).eps
+    2.2204460492503131e-16
+
+    >>> np.real_if_close([2.1 + 4e-14j], tol=1000)
+    array([ 2.1])
+    >>> np.real_if_close([2.1 + 4e-13j], tol=1000)
+    array([ 2.1 +4.00000000e-13j])
+
+    """
+    a = asanyarray(a)
+    if not issubclass(a.dtype.type, _nx.complexfloating):
+        return a
+    if tol > 1:
+        from numpy.core import getlimits
+        f = getlimits.finfo(a.dtype.type)
+        tol = f.eps * tol
+    if _nx.allclose(a.imag, 0, atol=tol):
+        a = a.real
+    return a
+
+
+def asscalar(a):
+    """
+    Convert an array of size 1 to its scalar equivalent.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array of size 1.
+
+    Returns
+    -------
+    out : scalar
+        Scalar representation of `a`. The output data type is the same type
+        returned by the input's `item` method.
+
+    Examples
+    --------
+    >>> np.asscalar(np.array([24]))
+    24
+
+    """
+    return a.item()
+
+#-----------------------------------------------------------------------------
+
+_namefromtype = {'S1': 'character',
+                 '?': 'bool',
+                 'b': 'signed char',
+                 'B': 'unsigned char',
+                 'h': 'short',
+                 'H': 'unsigned short',
+                 'i': 'integer',
+                 'I': 'unsigned integer',
+                 'l': 'long integer',
+                 'L': 'unsigned long integer',
+                 'q': 'long long integer',
+                 'Q': 'unsigned long long integer',
+                 'f': 'single precision',
+                 'd': 'double precision',
+                 'g': 'long precision',
+                 'F': 'complex single precision',
+                 'D': 'complex double precision',
+                 'G': 'complex long double precision',
+                 'S': 'string',
+                 'U': 'unicode',
+                 'V': 'void',
+                 'O': 'object'
+                 }
+
+def typename(char):
+    """
+    Return a description for the given data type code.
+
+    Parameters
+    ----------
+    char : str
+        Data type code.
+
+    Returns
+    -------
+    out : str
+        Description of the input data type code.
+
+    See Also
+    --------
+    dtype, typecodes
+
+    Examples
+    --------
+    >>> typechars = ['S1', '?', 'B', 'D', 'G', 'F', 'I', 'H', 'L', 'O', 'Q',
+    ...              'S', 'U', 'V', 'b', 'd', 'g', 'f', 'i', 'h', 'l', 'q']
+    >>> for typechar in typechars:
+    ...     print(typechar, ' : ', np.typename(typechar))
+    ...
+    S1  :  character
+    ?  :  bool
+    B  :  unsigned char
+    D  :  complex double precision
+    G  :  complex long double precision
+    F  :  complex single precision
+    I  :  unsigned integer
+    H  :  unsigned short
+    L  :  unsigned long integer
+    O  :  object
+    Q  :  unsigned long long integer
+    S  :  string
+    U  :  unicode
+    V  :  void
+    b  :  signed char
+    d  :  double precision
+    g  :  long precision
+    f  :  single precision
+    i  :  integer
+    h  :  short
+    l  :  long integer
+    q  :  long long integer
+
+    """
+    return _namefromtype[char]
+
+#-----------------------------------------------------------------------------
+
+#determine the "minimum common type" for a group of arrays.
+array_type = [[_nx.half, _nx.single, _nx.double, _nx.longdouble],
+              [None, _nx.csingle, _nx.cdouble, _nx.clongdouble]]
+array_precision = {_nx.half: 0,
+                   _nx.single: 1,
+                   _nx.double: 2,
+                   _nx.longdouble: 3,
+                   _nx.csingle: 1,
+                   _nx.cdouble: 2,
+                   _nx.clongdouble: 3}
+def common_type(*arrays):
+    """
+    Return a scalar type which is common to the input arrays.
+
+    The return type will always be an inexact (i.e. floating point) scalar
+    type, even if all the arrays are integer arrays. If one of the inputs is
+    an integer array, the minimum precision type that is returned is a
+    64-bit floating point dtype.
+
+    All input arrays can be safely cast to the returned dtype without loss
+    of information.
+
+    Parameters
+    ----------
+    array1, array2, ... : ndarrays
+        Input arrays.
+
+    Returns
+    -------
+    out : data type code
+        Data type code.
+
+    See Also
+    --------
+    dtype, mintypecode
+
+    Examples
+    --------
+    >>> np.common_type(np.arange(2, dtype=np.float32))
+    <type 'numpy.float32'>
+    >>> np.common_type(np.arange(2, dtype=np.float32), np.arange(2))
+    <type 'numpy.float64'>
+    >>> np.common_type(np.arange(4), np.array([45, 6.j]), np.array([45.0]))
+    <type 'numpy.complex128'>
+
+    """
+    is_complex = False
+    precision = 0
+    for a in arrays:
+        t = a.dtype.type
+        if iscomplexobj(a):
+            is_complex = True
+        if issubclass(t, _nx.integer):
+            p = 2  # array_precision[_nx.double]
+        else:
+            p = array_precision.get(t, None)
+            if p is None:
+                raise TypeError("can't get common type for non-numeric array")
+        precision = max(precision, p)
+    if is_complex:
+        return array_type[1][precision]
+    else:
+        return array_type[0][precision]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.py
new file mode 100644
index 0000000000..e91f64d0ef
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.py
@@ -0,0 +1,177 @@
+"""
+Module of functions that are like ufuncs in acting on arrays and optionally
+storing results in an output array.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['fix', 'isneginf', 'isposinf']
+
+import numpy.core.numeric as nx
+
+def fix(x, y=None):
+    """
+    Round to nearest integer towards zero.
+
+    Round an array of floats element-wise to nearest integer towards zero.
+    The rounded values are returned as floats.
+
+    Parameters
+    ----------
+    x : array_like
+        An array of floats to be rounded
+    y : ndarray, optional
+        Output array
+
+    Returns
+    -------
+    out : ndarray of floats
+        The array of rounded numbers
+
+    See Also
+    --------
+    trunc, floor, ceil
+    around : Round to given number of decimals
+
+    Examples
+    --------
+    >>> np.fix(3.14)
+    3.0
+    >>> np.fix(3)
+    3.0
+    >>> np.fix([2.1, 2.9, -2.1, -2.9])
+    array([ 2.,  2., -2., -2.])
+
+    """
+    x = nx.asanyarray(x)
+    y1 = nx.floor(x)
+    y2 = nx.ceil(x)
+    if y is None:
+        y = nx.asanyarray(y1)
+    y[...] = nx.where(x >= 0, y1, y2)
+    return y
+
+def isposinf(x, y=None):
+    """
+    Test element-wise for positive infinity, return result as bool array.
+
+    Parameters
+    ----------
+    x : array_like
+        The input array.
+    y : array_like, optional
+        A boolean array with the same shape as `x` to store the result.
+
+    Returns
+    -------
+    y : ndarray
+        A boolean array with the same dimensions as the input.
+        If second argument is not supplied then a boolean array is returned
+        with values True where the corresponding element of the input is
+        positive infinity and values False where the element of the input is
+        not positive infinity.
+
+        If a second argument is supplied the result is stored there. If the
+        type of that array is a numeric type the result is represented as zeros
+        and ones, if the type is boolean then as False and True.
+        The return value `y` is then a reference to that array.
+
+    See Also
+    --------
+    isinf, isneginf, isfinite, isnan
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754).
+
+    Errors result if the second argument is also supplied when `x` is a
+    scalar input, or if first and second arguments have different shapes.
+
+    Examples
+    --------
+    >>> np.isposinf(np.PINF)
+    array(True, dtype=bool)
+    >>> np.isposinf(np.inf)
+    array(True, dtype=bool)
+    >>> np.isposinf(np.NINF)
+    array(False, dtype=bool)
+    >>> np.isposinf([-np.inf, 0., np.inf])
+    array([False, False,  True], dtype=bool)
+
+    >>> x = np.array([-np.inf, 0., np.inf])
+    >>> y = np.array([2, 2, 2])
+    >>> np.isposinf(x, y)
+    array([0, 0, 1])
+    >>> y
+    array([0, 0, 1])
+
+    """
+    if y is None:
+        x = nx.asarray(x)
+        y = nx.empty(x.shape, dtype=nx.bool_)
+    nx.logical_and(nx.isinf(x), ~nx.signbit(x), y)
+    return y
+
+def isneginf(x, y=None):
+    """
+    Test element-wise for negative infinity, return result as bool array.
+
+    Parameters
+    ----------
+    x : array_like
+        The input array.
+    y : array_like, optional
+        A boolean array with the same shape and type as `x` to store the
+        result.
+
+    Returns
+    -------
+    y : ndarray
+        A boolean array with the same dimensions as the input.
+        If second argument is not supplied then a numpy boolean array is
+        returned with values True where the corresponding element of the
+        input is negative infinity and values False where the element of
+        the input is not negative infinity.
+
+        If a second argument is supplied the result is stored there. If the
+        type of that array is a numeric type the result is represented as
+        zeros and ones, if the type is boolean then as False and True. The
+        return value `y` is then a reference to that array.
+
+    See Also
+    --------
+    isinf, isposinf, isnan, isfinite
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754).
+
+    Errors result if the second argument is also supplied when x is a scalar
+    input, or if first and second arguments have different shapes.
+
+    Examples
+    --------
+    >>> np.isneginf(np.NINF)
+    array(True, dtype=bool)
+    >>> np.isneginf(np.inf)
+    array(False, dtype=bool)
+    >>> np.isneginf(np.PINF)
+    array(False, dtype=bool)
+    >>> np.isneginf([-np.inf, 0., np.inf])
+    array([ True, False, False], dtype=bool)
+
+    >>> x = np.array([-np.inf, 0., np.inf])
+    >>> y = np.array([2, 2, 2])
+    >>> np.isneginf(x, y)
+    array([1, 0, 0])
+    >>> y
+    array([1, 0, 0])
+
+    """
+    if y is None:
+        x = nx.asarray(x)
+        y = nx.empty(x.shape, dtype=nx.bool_)
+    nx.logical_and(nx.isinf(x), nx.signbit(x), y)
+    return y
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/user_array.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/user_array.py
new file mode 100644
index 0000000000..3103da57b7
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/user_array.py
@@ -0,0 +1,294 @@
+"""
+Standard container-class for easy multiple-inheritance.
+
+Try to inherit from the ndarray instead of using this class as this is not
+complete.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.core import (
+    array, asarray, absolute, add, subtract, multiply, divide,
+    remainder, power, left_shift, right_shift, bitwise_and, bitwise_or,
+    bitwise_xor, invert, less, less_equal, not_equal, equal, greater,
+    greater_equal, shape, reshape, arange, sin, sqrt, transpose
+)
+from numpy.compat import long
+
+
+class container(object):
+    """
+    container(data, dtype=None, copy=True)
+
+    Standard container-class for easy multiple-inheritance.
+
+    Methods
+    -------
+    copy
+    tostring
+    byteswap
+    astype
+
+    """
+    def __init__(self, data, dtype=None, copy=True):
+        self.array = array(data, dtype, copy=copy)
+
+    def __repr__(self):
+        if len(self.shape) > 0:
+            return self.__class__.__name__ + repr(self.array)[len("array"):]
+        else:
+            return self.__class__.__name__ + "(" + repr(self.array) + ")"
+
+    def __array__(self, t=None):
+        if t:
+            return self.array.astype(t)
+        return self.array
+
+    # Array as sequence
+    def __len__(self):
+        return len(self.array)
+
+    def __getitem__(self, index):
+        return self._rc(self.array[index])
+
+    def __getslice__(self, i, j):
+        return self._rc(self.array[i:j])
+
+    def __setitem__(self, index, value):
+        self.array[index] = asarray(value, self.dtype)
+
+    def __setslice__(self, i, j, value):
+        self.array[i:j] = asarray(value, self.dtype)
+
+    def __abs__(self):
+        return self._rc(absolute(self.array))
+
+    def __neg__(self):
+        return self._rc(-self.array)
+
+    def __add__(self, other):
+        return self._rc(self.array + asarray(other))
+
+    __radd__ = __add__
+
+    def __iadd__(self, other):
+        add(self.array, other, self.array)
+        return self
+
+    def __sub__(self, other):
+        return self._rc(self.array - asarray(other))
+
+    def __rsub__(self, other):
+        return self._rc(asarray(other) - self.array)
+
+    def __isub__(self, other):
+        subtract(self.array, other, self.array)
+        return self
+
+    def __mul__(self, other):
+        return self._rc(multiply(self.array, asarray(other)))
+
+    __rmul__ = __mul__
+
+    def __imul__(self, other):
+        multiply(self.array, other, self.array)
+        return self
+
+    def __div__(self, other):
+        return self._rc(divide(self.array, asarray(other)))
+
+    def __rdiv__(self, other):
+        return self._rc(divide(asarray(other), self.array))
+
+    def __idiv__(self, other):
+        divide(self.array, other, self.array)
+        return self
+
+    def __mod__(self, other):
+        return self._rc(remainder(self.array, other))
+
+    def __rmod__(self, other):
+        return self._rc(remainder(other, self.array))
+
+    def __imod__(self, other):
+        remainder(self.array, other, self.array)
+        return self
+
+    def __divmod__(self, other):
+        return (self._rc(divide(self.array, other)),
+                self._rc(remainder(self.array, other)))
+
+    def __rdivmod__(self, other):
+        return (self._rc(divide(other, self.array)),
+                self._rc(remainder(other, self.array)))
+
+    def __pow__(self, other):
+        return self._rc(power(self.array, asarray(other)))
+
+    def __rpow__(self, other):
+        return self._rc(power(asarray(other), self.array))
+
+    def __ipow__(self, other):
+        power(self.array, other, self.array)
+        return self
+
+    def __lshift__(self, other):
+        return self._rc(left_shift(self.array, other))
+
+    def __rshift__(self, other):
+        return self._rc(right_shift(self.array, other))
+
+    def __rlshift__(self, other):
+        return self._rc(left_shift(other, self.array))
+
+    def __rrshift__(self, other):
+        return self._rc(right_shift(other, self.array))
+
+    def __ilshift__(self, other):
+        left_shift(self.array, other, self.array)
+        return self
+
+    def __irshift__(self, other):
+        right_shift(self.array, other, self.array)
+        return self
+
+    def __and__(self, other):
+        return self._rc(bitwise_and(self.array, other))
+
+    def __rand__(self, other):
+        return self._rc(bitwise_and(other, self.array))
+
+    def __iand__(self, other):
+        bitwise_and(self.array, other, self.array)
+        return self
+
+    def __xor__(self, other):
+        return self._rc(bitwise_xor(self.array, other))
+
+    def __rxor__(self, other):
+        return self._rc(bitwise_xor(other, self.array))
+
+    def __ixor__(self, other):
+        bitwise_xor(self.array, other, self.array)
+        return self
+
+    def __or__(self, other):
+        return self._rc(bitwise_or(self.array, other))
+
+    def __ror__(self, other):
+        return self._rc(bitwise_or(other, self.array))
+
+    def __ior__(self, other):
+        bitwise_or(self.array, other, self.array)
+        return self
+
+    def __pos__(self):
+        return self._rc(self.array)
+
+    def __invert__(self):
+        return self._rc(invert(self.array))
+
+    def _scalarfunc(self, func):
+        if len(self.shape) == 0:
+            return func(self[0])
+        else:
+            raise TypeError(
+                "only rank-0 arrays can be converted to Python scalars.")
+
+    def __complex__(self):
+        return self._scalarfunc(complex)
+
+    def __float__(self):
+        return self._scalarfunc(float)
+
+    def __int__(self):
+        return self._scalarfunc(int)
+
+    def __long__(self):
+        return self._scalarfunc(long)
+
+    def __hex__(self):
+        return self._scalarfunc(hex)
+
+    def __oct__(self):
+        return self._scalarfunc(oct)
+
+    def __lt__(self, other):
+        return self._rc(less(self.array, other))
+
+    def __le__(self, other):
+        return self._rc(less_equal(self.array, other))
+
+    def __eq__(self, other):
+        return self._rc(equal(self.array, other))
+
+    def __ne__(self, other):
+        return self._rc(not_equal(self.array, other))
+
+    def __gt__(self, other):
+        return self._rc(greater(self.array, other))
+
+    def __ge__(self, other):
+        return self._rc(greater_equal(self.array, other))
+
+    def copy(self):
+        ""
+        return self._rc(self.array.copy())
+
+    def tostring(self):
+        ""
+        return self.array.tostring()
+
+    def byteswap(self):
+        ""
+        return self._rc(self.array.byteswap())
+
+    def astype(self, typecode):
+        ""
+        return self._rc(self.array.astype(typecode))
+
+    def _rc(self, a):
+        if len(shape(a)) == 0:
+            return a
+        else:
+            return self.__class__(a)
+
+    def __array_wrap__(self, *args):
+        return self.__class__(args[0])
+
+    def __setattr__(self, attr, value):
+        if attr == 'array':
+            object.__setattr__(self, attr, value)
+            return
+        try:
+            self.array.__setattr__(attr, value)
+        except AttributeError:
+            object.__setattr__(self, attr, value)
+
+    # Only called after other approaches fail.
+    def __getattr__(self, attr):
+        if (attr == 'array'):
+            return object.__getattribute__(self, attr)
+        return self.array.__getattribute__(attr)
+
+#############################################################
+# Test of class container
+#############################################################
+if __name__ == '__main__':
+    temp = reshape(arange(10000), (100, 100))
+
+    ua = container(temp)
+    # new object created begin test
+    print(dir(ua))
+    print(shape(ua), ua.shape)  # I have changed Numeric.py
+
+    ua_small = ua[:3, :5]
+    print(ua_small)
+    # this did not change ua[0,0], which is not normal behavior
+    ua_small[0, 0] = 10
+    print(ua_small[0, 0], ua[0, 0])
+    print(sin(ua_small) / 3. * 6. + sqrt(ua_small ** 2))
+    print(less(ua_small, 103), type(less(ua_small, 103)))
+    print(type(ua_small * reshape(arange(15), shape(ua_small))))
+    print(reshape(ua_small, (5, 3)))
+    print(transpose(ua_small))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/utils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/utils.py
new file mode 100644
index 0000000000..3f29699e97
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/lib/utils.py
@@ -0,0 +1,1122 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import types
+import re
+import warnings
+
+from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
+from numpy.core import ndarray, ufunc, asarray
+
+# getargspec and formatargspec were removed in Python 3.6
+from numpy.compat import getargspec, formatargspec
+
+__all__ = [
+    'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
+    'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
+    'lookfor', 'byte_bounds', 'safe_eval'
+    ]
+
+def get_include():
+    """
+    Return the directory that contains the NumPy \\*.h header files.
+
+    Extension modules that need to compile against NumPy should use this
+    function to locate the appropriate include directory.
+
+    Notes
+    -----
+    When using ``distutils``, for example in ``setup.py``.
+    ::
+
+        import numpy as np
+        ...
+        Extension('extension_name', ...
+                include_dirs=[np.get_include()])
+        ...
+
+    """
+    import numpy
+    if numpy.show_config is None:
+        # running from numpy source directory
+        d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
+    else:
+        # using installed numpy core headers
+        import numpy.core as core
+        d = os.path.join(os.path.dirname(core.__file__), 'include')
+    return d
+
+
+def _set_function_name(func, name):
+    func.__name__ = name
+    return func
+
+
+class _Deprecate(object):
+    """
+    Decorator class to deprecate old functions.
+
+    Refer to `deprecate` for details.
+
+    See Also
+    --------
+    deprecate
+
+    """
+
+    def __init__(self, old_name=None, new_name=None, message=None):
+        self.old_name = old_name
+        self.new_name = new_name
+        self.message = message
+
+    def __call__(self, func, *args, **kwargs):
+        """
+        Decorator call.  Refer to ``decorate``.
+
+        """
+        old_name = self.old_name
+        new_name = self.new_name
+        message = self.message
+
+        import warnings
+        if old_name is None:
+            try:
+                old_name = func.__name__
+            except AttributeError:
+                old_name = func.__name__
+        if new_name is None:
+            depdoc = "`%s` is deprecated!" % old_name
+        else:
+            depdoc = "`%s` is deprecated, use `%s` instead!" % \
+                     (old_name, new_name)
+
+        if message is not None:
+            depdoc += "\n" + message
+
+        def newfunc(*args,**kwds):
+            """`arrayrange` is deprecated, use `arange` instead!"""
+            warnings.warn(depdoc, DeprecationWarning)
+            return func(*args, **kwds)
+
+        newfunc = _set_function_name(newfunc, old_name)
+        doc = func.__doc__
+        if doc is None:
+            doc = depdoc
+        else:
+            doc = '\n\n'.join([depdoc, doc])
+        newfunc.__doc__ = doc
+        try:
+            d = func.__dict__
+        except AttributeError:
+            pass
+        else:
+            newfunc.__dict__.update(d)
+        return newfunc
+
+def deprecate(*args, **kwargs):
+    """
+    Issues a DeprecationWarning, adds warning to `old_name`'s
+    docstring, rebinds ``old_name.__name__`` and returns the new
+    function object.
+
+    This function may also be used as a decorator.
+
+    Parameters
+    ----------
+    func : function
+        The function to be deprecated.
+    old_name : str, optional
+        The name of the function to be deprecated. Default is None, in
+        which case the name of `func` is used.
+    new_name : str, optional
+        The new name for the function. Default is None, in which case the
+        deprecation message is that `old_name` is deprecated. If given, the
+        deprecation message is that `old_name` is deprecated and `new_name`
+        should be used instead.
+    message : str, optional
+        Additional explanation of the deprecation.  Displayed in the
+        docstring after the warning.
+
+    Returns
+    -------
+    old_func : function
+        The deprecated function.
+
+    Examples
+    --------
+    Note that ``olduint`` returns a value after printing Deprecation
+    Warning:
+
+    >>> olduint = np.deprecate(np.uint)
+    >>> olduint(6)
+    /usr/lib/python2.5/site-packages/numpy/lib/utils.py:114:
+    DeprecationWarning: uint32 is deprecated
+      warnings.warn(str1, DeprecationWarning)
+    6
+
+    """
+    # Deprecate may be run as a function or as a decorator
+    # If run as a function, we initialise the decorator class
+    # and execute its __call__ method.
+
+    if args:
+        fn = args[0]
+        args = args[1:]
+
+        # backward compatibility -- can be removed
+        # after next release
+        if 'newname' in kwargs:
+            kwargs['new_name'] = kwargs.pop('newname')
+        if 'oldname' in kwargs:
+            kwargs['old_name'] = kwargs.pop('oldname')
+
+        return _Deprecate(*args, **kwargs)(fn)
+    else:
+        return _Deprecate(*args, **kwargs)
+
+deprecate_with_doc = lambda msg: _Deprecate(message=msg)
+
+
+#--------------------------------------------
+# Determine if two arrays can share memory
+#--------------------------------------------
+
+def byte_bounds(a):
+    """
+    Returns pointers to the end-points of an array.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array. It must conform to the Python-side of the array
+        interface.
+
+    Returns
+    -------
+    (low, high) : tuple of 2 integers
+        The first integer is the first byte of the array, the second
+        integer is just past the last byte of the array.  If `a` is not
+        contiguous it will not use every byte between the (`low`, `high`)
+        values.
+
+    Examples
+    --------
+    >>> I = np.eye(2, dtype='f'); I.dtype
+    dtype('float32')
+    >>> low, high = np.byte_bounds(I)
+    >>> high - low == I.size*I.itemsize
+    True
+    >>> I = np.eye(2, dtype='G'); I.dtype
+    dtype('complex192')
+    >>> low, high = np.byte_bounds(I)
+    >>> high - low == I.size*I.itemsize
+    True
+
+    """
+    ai = a.__array_interface__
+    a_data = ai['data'][0]
+    astrides = ai['strides']
+    ashape = ai['shape']
+    bytes_a = asarray(a).dtype.itemsize
+
+    a_low = a_high = a_data
+    if astrides is None:
+        # contiguous case
+        a_high += a.size * bytes_a
+    else:
+        for shape, stride in zip(ashape, astrides):
+            if stride < 0:
+                a_low += (shape-1)*stride
+            else:
+                a_high += (shape-1)*stride
+        a_high += bytes_a
+    return a_low, a_high
+
+
+#-----------------------------------------------------------------------------
+# Function for output and information on the variables used.
+#-----------------------------------------------------------------------------
+
+
+def who(vardict=None):
+    """
+    Print the Numpy arrays in the given dictionary.
+
+    If there is no dictionary passed in or `vardict` is None then returns
+    Numpy arrays in the globals() dictionary (all Numpy arrays in the
+    namespace).
+
+    Parameters
+    ----------
+    vardict : dict, optional
+        A dictionary possibly containing ndarrays.  Default is globals().
+
+    Returns
+    -------
+    out : None
+        Returns 'None'.
+
+    Notes
+    -----
+    Prints out the name, shape, bytes and type of all of the ndarrays
+    present in `vardict`.
+
+    Examples
+    --------
+    >>> a = np.arange(10)
+    >>> b = np.ones(20)
+    >>> np.who()
+    Name            Shape            Bytes            Type
+    ===========================================================
+    a               10               40               int32
+    b               20               160              float64
+    Upper bound on total bytes  =       200
+
+    >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
+    ... 'idx':5}
+    >>> np.who(d)
+    Name            Shape            Bytes            Type
+    ===========================================================
+    y               3                24               float64
+    x               2                16               float64
+    Upper bound on total bytes  =       40
+
+    """
+    if vardict is None:
+        frame = sys._getframe().f_back
+        vardict = frame.f_globals
+    sta = []
+    cache = {}
+    for name in vardict.keys():
+        if isinstance(vardict[name], ndarray):
+            var = vardict[name]
+            idv = id(var)
+            if idv in cache.keys():
+                namestr = name + " (%s)" % cache[idv]
+                original = 0
+            else:
+                cache[idv] = name
+                namestr = name
+                original = 1
+            shapestr = " x ".join(map(str, var.shape))
+            bytestr = str(var.nbytes)
+            sta.append([namestr, shapestr, bytestr, var.dtype.name,
+                        original])
+
+    maxname = 0
+    maxshape = 0
+    maxbyte = 0
+    totalbytes = 0
+    for k in range(len(sta)):
+        val = sta[k]
+        if maxname < len(val[0]):
+            maxname = len(val[0])
+        if maxshape < len(val[1]):
+            maxshape = len(val[1])
+        if maxbyte < len(val[2]):
+            maxbyte = len(val[2])
+        if val[4]:
+            totalbytes += int(val[2])
+
+    if len(sta) > 0:
+        sp1 = max(10, maxname)
+        sp2 = max(10, maxshape)
+        sp3 = max(10, maxbyte)
+        prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
+        print(prval + "\n" + "="*(len(prval)+5) + "\n")
+
+    for k in range(len(sta)):
+        val = sta[k]
+        print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
+                                        val[1], ' '*(sp2-len(val[1])+5),
+                                        val[2], ' '*(sp3-len(val[2])+5),
+                                        val[3]))
+    print("\nUpper bound on total bytes  =       %d" % totalbytes)
+    return
+
+#-----------------------------------------------------------------------------
+
+
+# NOTE:  pydoc defines a help function which works simliarly to this
+#  except it uses a pager to take over the screen.
+
+# combine name and arguments and split to multiple lines of width
+# characters.  End lines on a comma and begin argument list indented with
+# the rest of the arguments.
+def _split_line(name, arguments, width):
+    firstwidth = len(name)
+    k = firstwidth
+    newstr = name
+    sepstr = ", "
+    arglist = arguments.split(sepstr)
+    for argument in arglist:
+        if k == firstwidth:
+            addstr = ""
+        else:
+            addstr = sepstr
+        k = k + len(argument) + len(addstr)
+        if k > width:
+            k = firstwidth + 1 + len(argument)
+            newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
+        else:
+            newstr = newstr + addstr + argument
+    return newstr
+
+_namedict = None
+_dictlist = None
+
+# Traverse all module directories underneath globals
+# to see if something is defined
+def _makenamedict(module='numpy'):
+    module = __import__(module, globals(), locals(), [])
+    thedict = {module.__name__:module.__dict__}
+    dictlist = [module.__name__]
+    totraverse = [module.__dict__]
+    while True:
+        if len(totraverse) == 0:
+            break
+        thisdict = totraverse.pop(0)
+        for x in thisdict.keys():
+            if isinstance(thisdict[x], types.ModuleType):
+                modname = thisdict[x].__name__
+                if modname not in dictlist:
+                    moddict = thisdict[x].__dict__
+                    dictlist.append(modname)
+                    totraverse.append(moddict)
+                    thedict[modname] = moddict
+    return thedict, dictlist
+
+
+def _info(obj, output=sys.stdout):
+    """Provide information about ndarray obj.
+
+    Parameters
+    ----------
+    obj: ndarray
+        Must be ndarray, not checked.
+    output:
+        Where printed output goes.
+
+    Notes
+    -----
+    Copied over from the numarray module prior to its removal.
+    Adapted somewhat as only numpy is an option now.
+
+    Called by info.
+
+    """
+    extra = ""
+    tic = ""
+    bp = lambda x: x
+    cls = getattr(obj, '__class__', type(obj))
+    nm = getattr(cls, '__name__', cls)
+    strides = obj.strides
+    endian = obj.dtype.byteorder
+
+    print("class: ", nm, file=output)
+    print("shape: ", obj.shape, file=output)
+    print("strides: ", strides, file=output)
+    print("itemsize: ", obj.itemsize, file=output)
+    print("aligned: ", bp(obj.flags.aligned), file=output)
+    print("contiguous: ", bp(obj.flags.contiguous), file=output)
+    print("fortran: ", obj.flags.fortran, file=output)
+    print(
+        "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
+        file=output
+        )
+    print("byteorder: ", end=' ', file=output)
+    if endian in ['|', '=']:
+        print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
+        byteswap = False
+    elif endian == '>':
+        print("%sbig%s" % (tic, tic), file=output)
+        byteswap = sys.byteorder != "big"
+    else:
+        print("%slittle%s" % (tic, tic), file=output)
+        byteswap = sys.byteorder != "little"
+    print("byteswap: ", bp(byteswap), file=output)
+    print("type: %s" % obj.dtype, file=output)
+
+
+def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'):
+    """
+    Get help information for a function, class, or module.
+
+    Parameters
+    ----------
+    object : object or str, optional
+        Input object or name to get information about. If `object` is a
+        numpy object, its docstring is given. If it is a string, available
+        modules are searched for matching objects.  If None, information
+        about `info` itself is returned.
+    maxwidth : int, optional
+        Printing width.
+    output : file like object, optional
+        File like object that the output is written to, default is
+        ``stdout``.  The object has to be opened in 'w' or 'a' mode.
+    toplevel : str, optional
+        Start search at this level.
+
+    See Also
+    --------
+    source, lookfor
+
+    Notes
+    -----
+    When used interactively with an object, ``np.info(obj)`` is equivalent
+    to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
+    prompt.
+
+    Examples
+    --------
+    >>> np.info(np.polyval) # doctest: +SKIP
+       polyval(p, x)
+         Evaluate the polynomial p at x.
+         ...
+
+    When using a string for `object` it is possible to get multiple results.
+
+    >>> np.info('fft') # doctest: +SKIP
+         *** Found in numpy ***
+    Core FFT routines
+    ...
+         *** Found in numpy.fft ***
+     fft(a, n=None, axis=-1)
+    ...
+         *** Repeat reference found in numpy.fft.fftpack ***
+         *** Total of 3 references found. ***
+
+    """
+    global _namedict, _dictlist
+    # Local import to speed up numpy's import time.
+    import pydoc
+    import inspect
+
+    if (hasattr(object, '_ppimport_importer') or
+           hasattr(object, '_ppimport_module')):
+        object = object._ppimport_module
+    elif hasattr(object, '_ppimport_attr'):
+        object = object._ppimport_attr
+
+    if object is None:
+        info(info)
+    elif isinstance(object, ndarray):
+        _info(object, output=output)
+    elif isinstance(object, str):
+        if _namedict is None:
+            _namedict, _dictlist = _makenamedict(toplevel)
+        numfound = 0
+        objlist = []
+        for namestr in _dictlist:
+            try:
+                obj = _namedict[namestr][object]
+                if id(obj) in objlist:
+                    print("\n     "
+                          "*** Repeat reference found in %s *** " % namestr,
+                          file=output
+                          )
+                else:
+                    objlist.append(id(obj))
+                    print("     *** Found in %s ***" % namestr, file=output)
+                    info(obj)
+                    print("-"*maxwidth, file=output)
+                numfound += 1
+            except KeyError:
+                pass
+        if numfound == 0:
+            print("Help for %s not found." % object, file=output)
+        else:
+            print("\n     "
+                  "*** Total of %d references found. ***" % numfound,
+                  file=output
+                  )
+
+    elif inspect.isfunction(object):
+        name = object.__name__
+        arguments = formatargspec(*getargspec(object))
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        print(inspect.getdoc(object), file=output)
+
+    elif inspect.isclass(object):
+        name = object.__name__
+        arguments = "()"
+        try:
+            if hasattr(object, '__init__'):
+                arguments = formatargspec(
+                        *getargspec(object.__init__.__func__)
+                        )
+                arglist = arguments.split(', ')
+                if len(arglist) > 1:
+                    arglist[1] = "("+arglist[1]
+                    arguments = ", ".join(arglist[1:])
+        except:
+            pass
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        doc1 = inspect.getdoc(object)
+        if doc1 is None:
+            if hasattr(object, '__init__'):
+                print(inspect.getdoc(object.__init__), file=output)
+        else:
+            print(inspect.getdoc(object), file=output)
+
+        methods = pydoc.allmethods(object)
+        if methods != []:
+            print("\n\nMethods:\n", file=output)
+            for meth in methods:
+                if meth[0] == '_':
+                    continue
+                thisobj = getattr(object, meth, None)
+                if thisobj is not None:
+                    methstr, other = pydoc.splitdoc(
+                            inspect.getdoc(thisobj) or "None"
+                            )
+                print("  %s  --  %s" % (meth, methstr), file=output)
+
+    elif (sys.version_info[0] < 3
+            and isinstance(object, types.InstanceType)):
+        # check for __call__ method
+        # types.InstanceType is the type of the instances of oldstyle classes
+        print("Instance of class: ", object.__class__.__name__, file=output)
+        print(file=output)
+        if hasattr(object, '__call__'):
+            arguments = formatargspec(
+                    *getargspec(object.__call__.__func__)
+                    )
+            arglist = arguments.split(', ')
+            if len(arglist) > 1:
+                arglist[1] = "("+arglist[1]
+                arguments = ", ".join(arglist[1:])
+            else:
+                arguments = "()"
+
+            if hasattr(object, 'name'):
+                name = "%s" % object.name
+            else:
+                name = "<name>"
+            if len(name+arguments) > maxwidth:
+                argstr = _split_line(name, arguments, maxwidth)
+            else:
+                argstr = name + arguments
+
+            print(" " + argstr + "\n", file=output)
+            doc = inspect.getdoc(object.__call__)
+            if doc is not None:
+                print(inspect.getdoc(object.__call__), file=output)
+            print(inspect.getdoc(object), file=output)
+
+        else:
+            print(inspect.getdoc(object), file=output)
+
+    elif inspect.ismethod(object):
+        name = object.__name__
+        arguments = formatargspec(
+                *getargspec(object.__func__)
+                )
+        arglist = arguments.split(', ')
+        if len(arglist) > 1:
+            arglist[1] = "("+arglist[1]
+            arguments = ", ".join(arglist[1:])
+        else:
+            arguments = "()"
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        print(inspect.getdoc(object), file=output)
+
+    elif hasattr(object, '__doc__'):
+        print(inspect.getdoc(object), file=output)
+
+
+def source(object, output=sys.stdout):
+    """
+    Print or write to a file the source code for a Numpy object.
+
+    The source code is only returned for objects written in Python. Many
+    functions and classes are defined in C and will therefore not return
+    useful information.
+
+    Parameters
+    ----------
+    object : numpy object
+        Input object. This can be any object (function, class, module,
+        ...).
+    output : file object, optional
+        If `output` not supplied then source code is printed to screen
+        (sys.stdout).  File object must be created with either write 'w' or
+        append 'a' modes.
+
+    See Also
+    --------
+    lookfor, info
+
+    Examples
+    --------
+    >>> np.source(np.interp)                        #doctest: +SKIP
+    In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
+    def interp(x, xp, fp, left=None, right=None):
+        \"\"\".... (full docstring printed)\"\"\"
+        if isinstance(x, (float, int, number)):
+            return compiled_interp([x], xp, fp, left, right).item()
+        else:
+            return compiled_interp(x, xp, fp, left, right)
+
+    The source code is only returned for objects written in Python.
+
+    >>> np.source(np.array)                         #doctest: +SKIP
+    Not available for this object.
+
+    """
+    # Local import to speed up numpy's import time.
+    import inspect
+    try:
+        print("In file: %s\n" % inspect.getsourcefile(object), file=output)
+        print(inspect.getsource(object), file=output)
+    except:
+        print("Not available for this object.", file=output)
+
+
+# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
+# where kind: "func", "class", "module", "object"
+# and index: index in breadth-first namespace traversal
+_lookfor_caches = {}
+
+# regexp whose match indicates that the string may contain a function
+# signature
+_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
+
+def lookfor(what, module=None, import_modules=True, regenerate=False,
+            output=None):
+    """
+    Do a keyword search on docstrings.
+
+    A list of of objects that matched the search is displayed,
+    sorted by relevance. All given keywords need to be found in the
+    docstring for it to be returned as a result, but the order does
+    not matter.
+
+    Parameters
+    ----------
+    what : str
+        String containing words to look for.
+    module : str or list, optional
+        Name of module(s) whose docstrings to go through.
+    import_modules : bool, optional
+        Whether to import sub-modules in packages. Default is True.
+    regenerate : bool, optional
+        Whether to re-generate the docstring cache. Default is False.
+    output : file-like, optional
+        File-like object to write the output to. If omitted, use a pager.
+
+    See Also
+    --------
+    source, info
+
+    Notes
+    -----
+    Relevance is determined only roughly, by checking if the keywords occur
+    in the function name, at the start of a docstring, etc.
+
+    Examples
+    --------
+    >>> np.lookfor('binary representation')
+    Search results for 'binary representation'
+    ------------------------------------------
+    numpy.binary_repr
+        Return the binary representation of the input number as a string.
+    numpy.core.setup_common.long_double_representation
+        Given a binary dump as given by GNU od -b, look for long double
+    numpy.base_repr
+        Return a string representation of a number in the given base system.
+    ...
+
+    """
+    import pydoc
+
+    # Cache
+    cache = _lookfor_generate_cache(module, import_modules, regenerate)
+
+    # Search
+    # XXX: maybe using a real stemming search engine would be better?
+    found = []
+    whats = str(what).lower().split()
+    if not whats:
+        return
+
+    for name, (docstring, kind, index) in cache.items():
+        if kind in ('module', 'object'):
+            # don't show modules or objects
+            continue
+        ok = True
+        doc = docstring.lower()
+        for w in whats:
+            if w not in doc:
+                ok = False
+                break
+        if ok:
+            found.append(name)
+
+    # Relevance sort
+    # XXX: this is full Harrison-Stetson heuristics now,
+    # XXX: it probably could be improved
+
+    kind_relevance = {'func': 1000, 'class': 1000,
+                      'module': -1000, 'object': -1000}
+
+    def relevance(name, docstr, kind, index):
+        r = 0
+        # do the keywords occur within the start of the docstring?
+        first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
+        r += sum([200 for w in whats if w in first_doc])
+        # do the keywords occur in the function name?
+        r += sum([30 for w in whats if w in name])
+        # is the full name long?
+        r += -len(name) * 5
+        # is the object of bad type?
+        r += kind_relevance.get(kind, -1000)
+        # is the object deep in namespace hierarchy?
+        r += -name.count('.') * 10
+        r += max(-index / 100, -100)
+        return r
+
+    def relevance_value(a):
+        return relevance(a, *cache[a])
+    found.sort(key=relevance_value)
+
+    # Pretty-print
+    s = "Search results for '%s'" % (' '.join(whats))
+    help_text = [s, "-"*len(s)]
+    for name in found[::-1]:
+        doc, kind, ix = cache[name]
+
+        doclines = [line.strip() for line in doc.strip().split("\n")
+                    if line.strip()]
+
+        # find a suitable short description
+        try:
+            first_doc = doclines[0].strip()
+            if _function_signature_re.search(first_doc):
+                first_doc = doclines[1].strip()
+        except IndexError:
+            first_doc = ""
+        help_text.append("%s\n    %s" % (name, first_doc))
+
+    if not found:
+        help_text.append("Nothing found.")
+
+    # Output
+    if output is not None:
+        output.write("\n".join(help_text))
+    elif len(help_text) > 10:
+        pager = pydoc.getpager()
+        pager("\n".join(help_text))
+    else:
+        print("\n".join(help_text))
+
+def _lookfor_generate_cache(module, import_modules, regenerate):
+    """
+    Generate docstring cache for given module.
+
+    Parameters
+    ----------
+    module : str, None, module
+        Module for which to generate docstring cache
+    import_modules : bool
+        Whether to import sub-modules in packages.
+    regenerate : bool
+        Re-generate the docstring cache
+
+    Returns
+    -------
+    cache : dict {obj_full_name: (docstring, kind, index), ...}
+        Docstring cache for the module, either cached one (regenerate=False)
+        or newly generated.
+
+    """
+    global _lookfor_caches
+    # Local import to speed up numpy's import time.
+    import inspect
+
+    if sys.version_info[0] >= 3:
+        # In Python3 stderr, stdout are text files.
+        from io import StringIO
+    else:
+        from StringIO import StringIO
+
+    if module is None:
+        module = "numpy"
+
+    if isinstance(module, str):
+        try:
+            __import__(module)
+        except ImportError:
+            return {}
+        module = sys.modules[module]
+    elif isinstance(module, list) or isinstance(module, tuple):
+        cache = {}
+        for mod in module:
+            cache.update(_lookfor_generate_cache(mod, import_modules,
+                                                 regenerate))
+        return cache
+
+    if id(module) in _lookfor_caches and not regenerate:
+        return _lookfor_caches[id(module)]
+
+    # walk items and collect docstrings
+    cache = {}
+    _lookfor_caches[id(module)] = cache
+    seen = {}
+    index = 0
+    stack = [(module.__name__, module)]
+    while stack:
+        name, item = stack.pop(0)
+        if id(item) in seen:
+            continue
+        seen[id(item)] = True
+
+        index += 1
+        kind = "object"
+
+        if inspect.ismodule(item):
+            kind = "module"
+            try:
+                _all = item.__all__
+            except AttributeError:
+                _all = None
+
+            # import sub-packages
+            if import_modules and hasattr(item, '__path__'):
+                for pth in item.__path__:
+                    for mod_path in os.listdir(pth):
+                        this_py = os.path.join(pth, mod_path)
+                        init_py = os.path.join(pth, mod_path, '__init__.py')
+                        if (os.path.isfile(this_py) and
+                                mod_path.endswith('.py')):
+                            to_import = mod_path[:-3]
+                        elif os.path.isfile(init_py):
+                            to_import = mod_path
+                        else:
+                            continue
+                        if to_import == '__init__':
+                            continue
+
+                        try:
+                            # Catch SystemExit, too
+                            base_exc = BaseException
+                        except NameError:
+                            # Python 2.4 doesn't have BaseException
+                            base_exc = Exception
+
+                        try:
+                            old_stdout = sys.stdout
+                            old_stderr = sys.stderr
+                            try:
+                                sys.stdout = StringIO()
+                                sys.stderr = StringIO()
+                                __import__("%s.%s" % (name, to_import))
+                            finally:
+                                sys.stdout = old_stdout
+                                sys.stderr = old_stderr
+                        except base_exc:
+                            continue
+
+            for n, v in _getmembers(item):
+                try:
+                    item_name = getattr(v, '__name__', "%s.%s" % (name, n))
+                    mod_name = getattr(v, '__module__', None)
+                except NameError:
+                    # ref. SWIG's global cvars
+                    #    NameError: Unknown C global variable
+                    item_name = "%s.%s" % (name, n)
+                    mod_name = None
+                if '.' not in item_name and mod_name:
+                    item_name = "%s.%s" % (mod_name, item_name)
+
+                if not item_name.startswith(name + '.'):
+                    # don't crawl "foreign" objects
+                    if isinstance(v, ufunc):
+                        # ... unless they are ufuncs
+                        pass
+                    else:
+                        continue
+                elif not (inspect.ismodule(v) or _all is None or n in _all):
+                    continue
+                stack.append(("%s.%s" % (name, n), v))
+        elif inspect.isclass(item):
+            kind = "class"
+            for n, v in _getmembers(item):
+                stack.append(("%s.%s" % (name, n), v))
+        elif hasattr(item, "__call__"):
+            kind = "func"
+
+        try:
+            doc = inspect.getdoc(item)
+        except NameError:
+            # ref SWIG's NameError: Unknown C global variable
+            doc = None
+        if doc is not None:
+            cache[name] = (doc, kind, index)
+
+    return cache
+
+def _getmembers(item):
+    import inspect
+    try:
+        members = inspect.getmembers(item)
+    except Exception:
+        members = [(x, getattr(item, x)) for x in dir(item)
+                   if hasattr(item, x)]
+    return members
+
+#-----------------------------------------------------------------------------
+
+# The following SafeEval class and company are adapted from Michael Spencer's
+# ASPN Python Cookbook recipe:
+#   http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/364469
+# Accordingly it is mostly Copyright 2006 by Michael Spencer.
+# The recipe, like most of the other ASPN Python Cookbook recipes was made
+# available under the Python license.
+#   http://www.python.org/license
+
+# It has been modified to:
+#   * handle unary -/+
+#   * support True/False/None
+#   * raise SyntaxError instead of a custom exception.
+
+class SafeEval(object):
+    """
+    Object to evaluate constant string expressions.
+
+    This includes strings with lists, dicts and tuples using the abstract
+    syntax tree created by ``compiler.parse``.
+
+    .. deprecated:: 1.10.0
+
+    See Also
+    --------
+    safe_eval
+
+    """
+    def __init__(self):
+        # 2014-10-15, 1.10
+        warnings.warn("SafeEval is deprecated in 1.10 and will be removed.",
+                      DeprecationWarning)
+
+    def visit(self, node):
+        cls = node.__class__
+        meth = getattr(self, 'visit' + cls.__name__, self.default)
+        return meth(node)
+
+    def default(self, node):
+        raise SyntaxError("Unsupported source construct: %s"
+                          % node.__class__)
+
+    def visitExpression(self, node):
+        return self.visit(node.body)
+
+    def visitNum(self, node):
+        return node.n
+
+    def visitStr(self, node):
+        return node.s
+
+    def visitBytes(self, node):
+        return node.s
+
+    def visitDict(self, node,**kw):
+        return dict([(self.visit(k), self.visit(v))
+                     for k, v in zip(node.keys, node.values)])
+
+    def visitTuple(self, node):
+        return tuple([self.visit(i) for i in node.elts])
+
+    def visitList(self, node):
+        return [self.visit(i) for i in node.elts]
+
+    def visitUnaryOp(self, node):
+        import ast
+        if isinstance(node.op, ast.UAdd):
+            return +self.visit(node.operand)
+        elif isinstance(node.op, ast.USub):
+            return -self.visit(node.operand)
+        else:
+            raise SyntaxError("Unknown unary op: %r" % node.op)
+
+    def visitName(self, node):
+        if node.id == 'False':
+            return False
+        elif node.id == 'True':
+            return True
+        elif node.id == 'None':
+            return None
+        else:
+            raise SyntaxError("Unknown name: %s" % node.id)
+
+    def visitNameConstant(self, node):
+        return node.value
+
+
+def safe_eval(source):
+    """
+    Protected string evaluation.
+
+    Evaluate a string containing a Python literal expression without
+    allowing the execution of arbitrary non-literal code.
+
+    Parameters
+    ----------
+    source : str
+        The string to evaluate.
+
+    Returns
+    -------
+    obj : object
+       The result of evaluating `source`.
+
+    Raises
+    ------
+    SyntaxError
+        If the code has invalid Python syntax, or if it contains
+        non-literal code.
+
+    Examples
+    --------
+    >>> np.safe_eval('1')
+    1
+    >>> np.safe_eval('[1, 2, 3]')
+    [1, 2, 3]
+    >>> np.safe_eval('{"foo": ("bar", 10.0)}')
+    {'foo': ('bar', 10.0)}
+
+    >>> np.safe_eval('import os')
+    Traceback (most recent call last):
+      ...
+    SyntaxError: invalid syntax
+
+    >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
+    Traceback (most recent call last):
+      ...
+    SyntaxError: Unsupported source construct: compiler.ast.CallFunc
+
+    """
+    # Local import to speed up numpy's import time.
+    import ast
+
+    return ast.literal_eval(source)
+#-----------------------------------------------------------------------------
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.py
new file mode 100644
index 0000000000..69445f541d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.py
@@ -0,0 +1,55 @@
+"""
+Core Linear Algebra Tools
+=========================
+
+=============== ==========================================================
+Linear algebra basics
+==========================================================================
+norm            Vector or matrix norm
+inv             Inverse of a square matrix
+solve           Solve a linear system of equations
+det             Determinant of a square matrix
+slogdet         Logarithm of the determinant of a square matrix
+lstsq           Solve linear least-squares problem
+pinv            Pseudo-inverse (Moore-Penrose) calculated using a singular
+                value decomposition
+matrix_power    Integer power of a square matrix
+matrix_rank     Calculate matrix rank using an SVD-based method
+=============== ==========================================================
+
+=============== ==========================================================
+Eigenvalues and decompositions
+==========================================================================
+eig             Eigenvalues and vectors of a square matrix
+eigh            Eigenvalues and eigenvectors of a Hermitian matrix
+eigvals         Eigenvalues of a square matrix
+eigvalsh        Eigenvalues of a Hermitian matrix
+qr              QR decomposition of a matrix
+svd             Singular value decomposition of a matrix
+cholesky        Cholesky decomposition of a matrix
+=============== ==========================================================
+
+=============== ==========================================================
+Tensor operations
+==========================================================================
+tensorsolve     Solve a linear tensor equation
+tensorinv       Calculate an inverse of a tensor
+=============== ==========================================================
+
+=============== ==========================================================
+Exceptions
+==========================================================================
+LinAlgError     Indicates a failed linear algebra operation
+=============== ==========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# To get sub-modules
+from .info import __doc__
+
+from .linalg import *
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..28574d186e61605bc4da704202b7a097548f3e47
GIT binary patch
literal 181248
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%0A^k_nf=NG8CY1b0InebZ
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/info.py
new file mode 100644
index 0000000000..646ecda04a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/info.py
@@ -0,0 +1,37 @@
+"""\
+Core Linear Algebra Tools
+-------------------------
+Linear algebra basics:
+
+- norm            Vector or matrix norm
+- inv             Inverse of a square matrix
+- solve           Solve a linear system of equations
+- det             Determinant of a square matrix
+- lstsq           Solve linear least-squares problem
+- pinv            Pseudo-inverse (Moore-Penrose) calculated using a singular
+                  value decomposition
+- matrix_power    Integer power of a square matrix
+
+Eigenvalues and decompositions:
+
+- eig             Eigenvalues and vectors of a square matrix
+- eigh            Eigenvalues and eigenvectors of a Hermitian matrix
+- eigvals         Eigenvalues of a square matrix
+- eigvalsh        Eigenvalues of a Hermitian matrix
+- qr              QR decomposition of a matrix
+- svd             Singular value decomposition of a matrix
+- cholesky        Cholesky decomposition of a matrix
+
+Tensor operations:
+
+- tensorsolve     Solve a linear tensor equation
+- tensorinv       Calculate an inverse of a tensor
+
+Exceptions:
+
+- LinAlgError     Indicates a failed linear algebra operation
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..5bef1005efbb7272a0b02e7e5c3e637ad7b2740d
GIT binary patch
literal 22016
zcmeZ`n!v!!z`(%5z`*eTKLf)K1_*F~P<Y7(1_lN``CWVrTR6`u?qKves~D1zS*%b{
zl%HOdn5&SSn3tDdqL7rTP*j?ykeR38;vcM#o1c=Z$IHv50yR0nm4U&Bk&9uU*>N+d
z5W@ooK4or3CP@Z01_p*8sN+N!7#IW?7#P3~JCF-zGeO+V2vq{se*wY?InMz07XyO=
zL?1{4NI%pVh6aey3=<d_)^LDzVkZtTFzf*Z5O!GxmJJLH5?JJBOk`kC067ec97ss7
zB(<W1fq}tA73v_6UqO)ol7!*}hJXaUl*E!m1_p*bATf~NnHU%tv_KpLc3?<2pjQM@
zD8R|Uz!1Q|z`(`8z@URr17bNa7&z#qX2hozCFTlnGcYhDFfcIiFfcH{Lms3G6vPG&
zdP&8_Al?g*-wQx2OxysnHx*(pD4IZF$^deo6RKLUy_pbo;IN(mb)O4{x&wO7K_MVf
zu+tYXFo4bT1BoE81B1Z<y^<WT`xHRJ8=&ey{s!@(7_6=+H77qA8ixlUX#<?5plU#r
z1A_sYi$S6z0|z(1kvPtx0?NuScBn8gbRO<xQF*aUl7XT1_Tn?e2XYsmC_a!|!h0N)
z4j7t`NEjZ7KHPjnVh1Q~M<1RL9v0mEMxZ-HMWyvpY0*N4f&;m&2l)F$85tOwUoaZp
z?l!$K@j&ikkoar<-ZF;cEGnQR_5WJ)8<t%lGdgd4;NK{Ep%|pE^x?uQ#Rqbme=za4
zJZ4}3DVAqoV0aO)!oUEwu=$8UbX@!)9)`|uy?fL_G1UBv5iC>sBxNBe9~yq^j$rAw
z1zGx9ytj<O@-Tl34<pzpu)Wut->`Ik_`ttW7HZ`^!`o0x8Tnfj85tPByw(H!Egu=6
zoaP^l{4L^)pdjIIISmqB5(08=iA;BhipFsl6&6sU?+j7l=nhd)=oC@;f1&vePctjX
z(~QkW1i%i2xO;-(ftTk0|Nn=(e<3K0K|!u8!NAaZpz~OX<3dn~gM<VmK=IN1n#J;7
zIe#~E>w%Kb&97PhU$DGa_Oa7M<%NVY1H*AvkZMp!9A^a?1!5T<IL-<RM-aQ6735E_
z3*dpb8x-y@+5Z3kpEjW#91btF{{R0!p|?bh0puHj1qX7Ev#4-@D6l~w^)D_dF)+M*
z^Y8!v<18xRSUCw2xD66;QDI>LDP~b&Sa2Zs#R?^myFe}gh0Duh|B(C}8s2$6EV%Pn
z=jG-%GOd?7MOQc+$StjeCY+Ms7q>y4u2JCtIRxYZkVn5OGB7m1;psfudb@<R`8RW^
zUT2L8M`w%*3rO}POcq%%<?sLh&2M;G50o+)zCF$gvgQB(|Nonh$aKDlj*E{y+`9!-
z;xfF*mSAA$b^ec}xA_NSdCv=Fm;ojGk>p;)KrCxL(0Q~}x%oF^=|Ye!vSVNU0o(k#
z3ml#xB?T|oL>L%g>Og@Ba<&q}B>vVYP?|vVH6ug;Odl*TZYe+l15I@?#M+lPL7@$m
z0|h_Gs_jrMM_=y#_y2$IHjq)U{PRZUIO~Ms1GykEP&RJ<#aJTM?W3a6?V_Ua!uKCI
z%ntD|K*OsuM1|)?xG)1lcZdql>+2IjJD-A!0G)2rEfc}Xh9TfUE;xIG^3YxeP!c}Q
zq5>8bJu~q@Znx-;i3f6<->@t`QhXp66mr4=2XZ@QR60YS{J+%vhNJU%cjyz4xF$p#
zEV!7#;XrQd{}Mrv1WN(frhvo)x&N;(+yRm~P-1bMMa2<e_b!l!O2k0Q{XyoisQiao
z%+YzM^->AvaTXPj&i|K=v#2<T9>{%hP>_M4H}wlRb-?rIaaNGU5he$6_Xn69$bDJ)
zA0B}FK{kYTK5c#@u@I!F^#IsVu&XXC1bMFYKnYJL$l?VMAD=utA-MSssKk%~CB_%#
z0-(_8by1Ny&Z3e6a;1w3%ZrQrppvG9qf<uZg{%Mr!wUle1_r}Rtp`duyG1ulI*{AU
z#Mpd9qw_-a;j{^%;hopP`RQ!)8=Y=Zg@OaQ-3~0>Q5=>xO2oi9ghl1WdXR|+IuG-=
z^fNFpbjK+)KV~e6>UNW{t`I1dZK&Y0<8N8az`)RaM5prxs{gxPR9rf9R5%Q8gF^BK
z#Ek;oE-DV4E-E|=WeN`Df{LoS{K&ddH7$W?LMSf4su*N`4!TlT6s5go45&u)1Rlsm
zafc{B1H(&GaA5|?-=W~tnbYf{64INa64P6w;?Y~8644u@;sUbJ6=HxwuZv1RXO4<S
zXN`(VXNihLr;CbAuZxOLXN-zKr;Cb6FVw@mE-E&iE-D<|Eh;Ubq|Ku8VizB%;O1{R
z1`1ji6(5kXfq@5dclrl{Q)xutf!tmEplU4O-~a!hOfd(dG61eJ1zn{YSY=6Bw~I;$
zTvZ0TDh7zE0FbKA92JGm8Wovt2aZk`6^U*al>iX41mgT|7Zo26H%0{{%LDZd3)nX-
zDlgo5LFw?t30{y-N_d)&<QN_RCxf&J-7YFIoiX6zm?szH02dXOA`s1@QUwV+ffpXU
zpvcbw>mU%`Ef77Rumy#;N@tCVLT8DJ2*}OQ@aE}sQ4xT;5ILNKz^>zO*#`+da5(p3
z4d)ksAmKa(q7od=V3io*ybr9hBo7pVpl}AO!U*RX5LF%^Rh>C1GMzOl5}?p@Q4v9e
zGuYXPaApCe60k2=R9?L228VA358m+AfrhWj6j1oOsL0HM&?567fo9O{qT+GfMTKVp
zM4V+2h-Oh)1(607*b$vBDhl8%0!ag)Oe*kV1vhH^G`<0)z}^;ctFJdkC7^c=I5qdy
zs8sZps1$%g;t0f0n_d@{8c_Uq=BPMy)~J|tx~N$6x~P<NmZ<1-x~LfRwy1P~GJ=bW
zMz4!XPN$2CO0SDb2FM+~E-ER|e3Sr<-xz3K0=W|u$04B1+ufqF1!M$^%8NX1Pzdq2
zm@zSca(WENC0DS<G0SgA9P>a_rodI+h6D;C*WLOBQTd1wY-SEz<z0x%`=I;@>IJ>n
z096TUEp@x7l)zPDq=+`C%07shHE@-$(9Mj2s!Rc?goHR;@dt?FZy*P-f(i(IsA6-3
z;?5iu3rJcs>2^`60WoVJArEpPh+Cqf(g_Ov7Fa}p5<m_}22zHB;sR72q(Fo~MHwhM
zKxKFgNJs{x9aJQMB83A~P<Dc9A!kl-n%%+)j*-?Spu7Yr^k7L4lq^7g;Rynlb0Q$h
zMa2b_iaT9YK)I#jxQmJnG&P(21NqiPMTZ%pP6d>@J6%*9x?R92PKF&K4omG8-H>Di
zO7$T3A}4Q9vH^K108~`GILX1l@R}3aJ~2Gdcm$NX!G%$883Tdxh#KWT2RMXK%73dM
zMEQ?MUjaWLDG}s8P{9ETJg`b=xr9)u23CnE|G}!DsSu%x0iufX@;{v&9M>n<K|Uc|
z{yTzV3c37eM=f8P-{7ooDJlQKu0t*VJ+X%Ki*Jx{MlS!sDlx)&A6O-#{0FPT2<I6P
zRiG3dLRR_D&jt?P3^u&sOLF-i0Eq{}<v%NG{4~B<!@$7M+oI9~qGD81de^9c!m4+V
z3TR}ecMG^S0Hw}|AaMK20#?d{+7CG@HqeRyRQS&TmE4fJKm%H%K<j`SXdO@itpiG+
zbwB~M4gl2^pgI6lKJj$7s2l;A#G>*dixm_~{4J@VLJ(3mu%u&+XNIqkc(#V91eG=r
zmC!l>kyEaHfv6M&sYH~*U}G_=ft66jPas7esCom11z0gg+Ngml-VRX=3Q@RXjPl(d
zs<;cGxHCt^1XK#c3Ux>+4iZ6>>)<d3RqPO#gCrqEJ1B@j<zNLw2voF#LK#%F7l4G|
zMLQ_0K}9<#tXW=kFoTohO=eI)m+*p$Oi+RV7n$8H;G}T3MFnIl$SWm~R8|9`TvP%;
z#rts=6%SCcem6$NqSHksq`L*2aE`mEI6zBzlRSuWaB1HOYJI}%4sgML+(iYYz=zi<
zE-EgddJa^#fSMPeN)A-Jbwk<~psEez2au;hZ3}@HXP6imUfO^<WsvqhxVf)z+(kv;
zD>DOVGy_z#gJ_Or5Erp1IDo6G<v|B>U$ilSf`GpTH2ig(MP)N6xgUQq11#EkjK8H3
zG;-vk!txm;0cxKxF)%diF?Jp<iD<pe-?A4pT$C~CK(3`TOG)a&DU%@mS&`rax!nw)
zZc!Sjb;8_jIsw#cd%@Uxpp&^o_eBH~*kvqdf)3<%vw_svfy_Ok5FHnPxZ4dhsPR8Q
z;`Ln6cuco5OQ(zqh<gG&o&f3;I)F^&UJUB%^#=ZLz0@hp-vY|NpuR;IBLl;K0b5Q6
z2F8UT1^lhOpppFvKFkaZ%|AFHVr`(l%Kr%--~_<mA^{q#`@zWH3L4w$v{8A{5Aim5
zSiJKvC=r0Vy2n{m@<I;ezF5h~zyRv5yMTKIENvkNau<X8fiD(-%z^j<-hYO>A8hl>
zNKn65;JAwl2grq>)*s09kl+Kk;LwAFS^y}Qg2U|Pg@6D5LxK;a4iR9yj0_AfH~#~5
z^guoX83-Eih8egZ_(1OKwID4LAt*+F1?4=5(WU?X|6kYxjk15Br~pUVW`v4h=-Ad9
zkZHTX4g?u#4v*e;gj)4~|Nl>zFk!-f)rd(4azS(mln#K>K2X{NO1nU52PnM;O0R&@
zOQ7@uC_M*C&w$b$P`U+5H$dqcC|v=iOQ3WCl+J<DDNs5AOs7qNK+yOEd`z+*oM`@o
z3U2<ECdhy+C{euF$H%|`SCt7WPFz$Z;NzAN5CKppPX^iz0(Gcax?NNZK&gEOAE^B4
zc2SW4@vN8`7{DXV-7YFJAOTHK#${0fSp*(@e&N9fs=qWkZ$uvk^+!Qw{1@c_WvL??
z(XfF$#CTS>i;4os9K-+MLVwDE<|8uv+YWrcad^Un2@4lEfHG(6ffD)VH#}(*{$Bu#
z^aikWJFs+$f@E6{l)h{}!t?nsDF1=R$Gc?>Ob_HX|NdX1*m}E!=fB8YF#k1U>6hay
zDj(Di<i2PHk1a|>A2z)GnyK?}uQOw}NGnKH>!s2UuTS=tF+kn7Pz5|fUc&zQFgQOS
zX9Wp>#spta0i_>EdsS!Q22d&Gq5__=I_{zZn*Cz1^?T;9yM+Jyg~eMO4&*i;(E*p(
zy)G&O;6bK6kU^&I7!?8I7!{HKqAMmI$n8A(Uvv$KKK@_y0Ej-;3kmoCq8A|Qjbl_K
zjAK+}3||}GH~iQ54{V7<=ZEhXI!!^YK(TDXjt!FgUH17ubJ+d*0VsUH<6j!bSrv*8
z<Z`kw9O!ms=?!H$&Z<&;AQ$8-(9j>KVi#p8JdnHiN5O&I#X7|Ya=TqQ7QZPtkPG%_
zr|XA>ARl$Qe)%tY1>&mXEGlzC4&?q9eFEYC7hM7xUUX4m0oelf?;WrV#|uRs1_n^j
zfpPO2nQj*qmF6GJB_gc{N+4tJ%|~Po@i2hH8#H1M>feA9Nr(yuD50!igHJDj)S--z
zg5tl~c8$Y<TqcmYC0xf@!5q+N*$<`?!R8-~CD!oykV8BSyEPUZ$Zh-$B1@j9O#lzu
zGyT8Ne3%6ySo#)OH7GrU#sgVEVFk)7V0W>oybxhyV0gVeZGzzeP^txc4NP>qsIY(&
zCNw>P`Cu6c0dns`21u#KAq~p1E-GNddt+2oj<cw&2sx13d;l~q!1Lk)7q~~P0Ih6U
z!1_RvEGjRia4|5vIL^hu@R}E5Fq8z>uLj+wGe8qI-}w7(f{H-fImHKZ4R7~`vrOpb
zvOHMM*ImWJ?9X9&g1>1KD4-5AHXq`#{9O8|lSQTT@CyrYOTP0sf6EO}15~E0+Z1HL
z!N*LD_d4A;j<bPkn-@+T3=GWfJe_W!VJZ<&2`>XmNG>WY3qh*8T_jk*$>0q*8Su0o
zD9P;x^@9WcG(Y-XV%Ge^q4~l75<O6WGRuN=fQ$gmphBZxq%%eZGCKPLY=S`RffCVX
zR*=USn~xZP>SDuhFTFq&mgojh+GA0X2n9EXSzb&7)g2%+!L9&}2fA|{XHj_)0+lZV
z4Z_E$upDPmIRdIO)8NDI3#Whr?m!9qVMsEAji37*X9dZClEI4^Yzz#&EDpUat#S+u
z3<qDZ9DKm?VlxM5QU&BXQ0QnL>2*<&Z+`G$F~}7=1R@XQ>Vk;oAME^nvq540gPXrE
z9@IVo3AY}Av;!83M1m%+_*+2@o^D%-$OE~%Wk5pz`CCAP4!c2$yPY{eGhVH4K-KwS
zp2puG!D7#DX8vu#9NpC{y&Vh;2Xea`KxFeTf!^&PMyKl${uVxvj$aD=Eu~-v2Y-tz
zsI3qJ4v3P_1Gz6^|Nj3E8)FAs1~vWl1Ze-gyO^chy7@2%^FENNy=@@!Mf>0X{~-!H
z!NNs17lH!9@OJBgdfwOTn-4Qu%Yp=Im-O01gHuPZ325elf$>APK<lNFd%eDAK(P-_
zKt3wqq8>CX4^KM$Ew?}^(e(tV0Rc9kn`H+$JG$NgCl}W<;Isx!DX)9s?HjNsx{X`E
z@wbBNn{IEG)|31#JOBOv|5EY)|Ns2kr-OXZd4U(Sydtf6KZwV`?{T5q^@!#v#tWUU
zXF5N;SpEm3()CPQXFEu~85ZdLP3<6q_(2A36YIR*c%I?^|Njkk4E!F~5xO%$y0^KW
z>0o<(6lClPX131b5QF{x{Quu+_j+A7FDRKXe(ZJxk4ttta&$YOB-o?B|AVS|P=a*;
z#naZ`kmk$;NPPsFpIA{0DvsxXW^iN|fM#jmuypG_0C8<W*`xJ#i3VtVo*5KSS3$F^
z$Npb$Jy6Qi`mKZm)Cx3F`G281nxpl0>1|Ls1UBsiIOnl6ACZAnWn~Ntmw@v}DJ*}0
z$}>=-3)GB1&Y}X&9~$6(bm!p`Cs5{w8rI1SDxW)@S^kTH+_(_x#7?kVVQQQ?{)>X_
zG(6D!hNbz4MD*bup#1&%3p_qS_JQ5d9iyVqdZ3gaI^_*ZpHPz^mUN3kZE3w!BHqnp
zdAOA8wO==f<;@a}&O_Z!9IXdRKf*PD?1k70nnH(}*X_a4=>@KZyjU4P6W)+uhAMu2
zvD=AbG02k63$Jg1>RXWeKpq9<Q1EO{k#6%3rV@$fAIzl^V28IJDB*wM`tSe$*BrfN
z3@@TtK#eE(d_7bNe`_mv9vc*oKNw5zfrG2{K#5>?1lTcqSr`~vZ+G4(eSe%4WId?N
zInD}-8!(GS1>(#ZkobE&4<3F{^Gn1bszLDuukQ{+=KmpDk3h9ve=+m#|Nk!wK~4Dy
z6DBY_*fd&z76p~C8Xh>DHX*ICLV}x-f64*=Z3jU5LG@i)qlIr2RQ~ljXu$!k55s~%
z6O*7e5Oa_X|Mns_{_Rd8t>1cGm?TQ14Np$!4&br8RnE>Fz+rj0h^P4=WAgzG%a5fm
zKocGy^P%azyGF$T)DxP^44Qgt{=resoz`dz%ACGYCETD{<O|>wJ7EV%?1dY+saf)T
zp$)@<T>kAHA`Ay|SwS-V+cVgDV>l#Q-<F&*{PvoALh~`k=EEA6?@H7_1rn%@+gYOm
z>f*i70{6yB?|}@z)d?{^Z9?-A8N*A_ofp7U)+K5Th9?p3VD3C|I4l_Af+LW*ATO{B
zx?@y$dM7~aZveTa@il}~#0Cn8)^8<Bh9@EQ4=6k?7eT{A2q`>HcAkiiJ3OKDAee^7
zui*hC`#&Fs`5$8Yd$8^N+Z)&z4&*}Gw_%3g;2MIveN=c#csoCU42DJ<#Pw_t{ZGOA
zQC!ZyJqqIH+a<>hFQrZR=Af=n!rpqaM6CHGWAh<!^xZ0bY4{CnYTAU(V_*ity_ewD
zmoRr;I1I6G+FwxD0L<ohz0i5#FhV`D{|={3fQ2t;JwfY%5@N$wfnfL^h>rVwIBi0=
zgGzMV_X`JK$iMyo%HQFr0T!boP{IT9Q9QK00Cw|>YmgbKXOQrM*2fJDpt`-}BLDVE
zHva8_BCY>>Lj)yC4t9I-Se__iXZGT-JW(VBN`QwnEdQ0hfP`86VQ@k%<$3)cWPkH(
z#^wVe-5xBhCrjD819)05m0WMVUH_uHfG4`~7$_BWeu#@lv`KG2MzBFm#Q&-m;Qr))
zRTD5B7+?!pdDrWs!c!#L_!7i!=48+X(O`-4*O~{LIT<1%4^II1KzD#j3{YboWY~lW
z6VUnpRdvAT{#Vt2(kf6|0ZPk2X$dGT0;L6@G!K+!fzp2_Li+1Jp!63o4e1T1fz~&~
zz7)R?tqmtk096+XrjX?lAU3Et9L^Xt>iIz)(w77I6Es2|Acx?CW+ooUAo!r!x(|{F
zK4?ZYKmx%B&5S<~L+~es9LOyYMesp(AY%v91G%7Z24T>07EteWqvU?Hm4nDSM%ko<
zKu%^-dUA4naePX-k*=X$N=^<#e0))AdS-D+Y7uy)Xli_BURpjwe0)kOHgT{4S-OU1
z5WQYy@j+1C&N+$2#i_*%3?-?>prx)1t`!BT$t9^N3W<3NiA6<;l?rM3MG6IpMTxno
zC8<RUs>PsH!a0criOJdVIhiG?daB?xo&hK-iWTzmOB9mx^GY()OY=)f(3790P*Pct
zN}N3zi6D#ebn_BRGRsmGk}6A574nNxQj4&-F*7sMKhxhoGm{~ap{g`5y|9SEFCa4B
z*~LH9$;XwUB(apCJijQL0UVGJ1@R2k#a5X*#a5ZM3~=35>8XW9X$(1F#W^X740#N>
z3=lztdXOGu4AKv>KGQ!1MEPfebmSDLFeEV)gPj3&MG@H4OfU&@ou^+2Ls4R0HbYKI
z5<^~5Mln<$ZkteTP023;c@#p$Go(P=4x!>1AVC6kQzl3j<fNkH{Jaz>2d_OTsCF?R
zB?^YT(%gbdz2y9&RK48NoRUm%QUaxUtP%=oiJ3X6DGDX|3YobD`9&oR@s2@3j*;<>
z0iH-qaH2}fFU?C~Ko-peC4v%#fJ$foq^#8B5`}y)g{H(W)W=7mAU`v&B(;cvfgv|P
zr8Fm1Avr&{0Bm()dSYf?afyPXlcz#iYEf}!ex8Csg=&RDQfY}o324bYOf)}D0qhBd
z%wn(#JZ1%uZkC&4h@+1cXbC>5^NJNp^Rn~u%kvac^HMSs^FU#VTWwBeNl8vBRH+Ww
z4=Jf7kc^#@nU<DXl$uupmCj2oE>=h^0c`*%$;?efjz&Ena6We}D#|ZnKxS8@7A56?
zmb^27#uOb24&*9m9?130%u6rVEjKfPnFWs5(xOx=E(XVxlp>Htss##=T&s|oo0y)e
zTb!C)l9`{!pr8<zSyWP*m=jo<T2u+vn3@7EdsI`v85``zM7Sv+|HJhJ6y<|F2h&xa
zS(2fUoS%{kjUNStP-xf{6sMM^<ST&Jn<s+o1#N^V$xqJDfk(P(iXLc|0-v6w%o2s-
z%&Jrcs9JYtXDbDbpwu!`9R;V-%$yR1q)G+f;K*Pjknx}-si|P9XRK$yz`!u7b~GH4
zOGeW}Q9k+k0+jbh5(ZB!F)%PNRs}II)^IRN^RTdVFfuS`FfcHHhD#r;|Nq|}6d;a#
z9L-G5d<wZ-d>qb)`B)seo%uN24)d`vFyt^WFnBO9Fnn46|Gzq@k?zRH(az+^$J55_
z$S2Uu;>@Q|%qQc_r%=kpC*XLPkH_&CABW>{J{BMDLa;bfGM|VupMn<`pMV>Zv<o*=
z9hwej(6*%-2FO0OEgS#;ZwB=j9r-v~LH4yXJM#&&u{iRHG_$(%8RYP(IP)1qgUKK;
z8O+5e;(VA-!0{L#kK=JZ4#%T>EFRpkV7U-584o5?!DJkmgos1PNU(?m0|SEvBLl;c
zP0+A$=2J-K;$!jRW?;Y-o}m3qpzyq~>Hq&P(C}<!a^humYiDj_X=Y_Q#dX;6nB#HB
zqdY7igFtG17#J89Z2tdWA6b1iNC9qpK>MLUdS`6@{~x?<3L0+)Om2{PV_*Pp(*jL|
z9NGN;zXa~^b6|4D5?o%~d00dpxzn(UreG0u0mUI`s}^X*Pr{b}{|ivv;0TXHXTAnT
zW&=hnW;k<a^NBd3#UyCs7|1_0TmSzDtwmr!qzg1N6|kGhgvC$>1_m1j1_qEDk8Jz@
z|1C6qL(?0=TsOWAjLi3#FkJ=Nj<<o4fuUq4b^Qw3b~IrZb^QuT7coo>3^#WF|9=y=
zUk@-c3o>zGde#vXx1h3M0TTm5$-e*pYoKPJmInq*+tD(%BRA6_G$BxS!kM37<x{}H
z|NlXAjG(v%l}`pt)1d{F6L$a~ha;$f0_91No1Pr}|6dlAmz?<&Likv4nhjD9%0pKU
z{{Iikw+w!K0x^6npq-=)CJYP=Zw~(d?*=jlnzt0PxF9w;a)ZXT7$O)L7$gq;{|_<)
zqzq&ph(<4CW1wX$&!PYSK?|@ze!xgq&U_A_tc9M|9l3q^Y@GQVa=~N<mZ)&z29;Bw
zvNGn-|No$+DiHIXctLB8ak&ZPW)R+S=>LCbkfWXX6hgT`rDOuAs0VK;1?7hqhyMSs
z1Ifd}AcYH39XNBRLRsK^4qCtfsvj&4|Njr(Ldbx->;kC;*)4PU|9_AhLB@l`Ky6zI
zBr#lW2l*GI|IeZS{{umqVQzzN8@2$^hyVY#f|fU^Y0`md0-uR9pF=&Lfis_jA6jAr
zC2UYy0EMT`k^lc!gVJ>%sNO*;!`~s5;f~xm(-){*2f1^}vH$<U`>wE;QwF|#I-Yz6
zQG7bid<Gd{(it<yLAUvW!uZIs|NqND{tkrJ)g^o~9()R6d@`<l3eJc$3W`6_8f1~<
z|Nnz%P`Uu+9fbgB*74-_<&*K`Q^)|<&LEwj8sC#U8q8+^h2tFt28NR3|Nnz%xc(Ao
z%sX*21%Z_&LIqqv20HU85RQ9>6VN;g-4+dsd!7^j{|kZq#Q@&T%>WwwlQ{AJzb#12
zk&mMdRQESCS03i$a6HDx!jQtiz>vYfz+iF$;Xf?-${-O-#p1-x6w1XX;)+(aICDEg
zS`N-gEeB9~0BtwVIe`dws9Tt#xuC9b;&z3yz-0piBLl;p6aW8fgWL{kM}YDJBLl+?
zm>FRI`0(*GGkd~}@Z@Ilfw7$t#(~WPt(B8G`Tsw7Gb{rG11P*edkrj3{{Ih3s|<ng
z@L`ICI>ZHJdK;4qlnZXV&0u6;XgT@+|8kJK5bZY~Q2Pz!5O|x-otr6u3#pOj$enqZ
zkH-_*qQjZyLHQVz<}aKiz8v^+^8bI(3>nBtxbi&A+#5)0@u>&70faS9{r?ZzDi2D#
z;C2|e;RVt;^6-l5Ea4zu8#OS1k|!K%G%zseG%zq2G%zq+P-0+k0<9WB8N(^4Okv2(
z%Pc`2o&%XQiib)FRDf3eLmj(hIs*gf+=?qmVjre6FnpQFz#uXast9z1!VCrmlSvE=
z3P@rmGZ+{gCNVHLAc@VG!N8C(384>}wPO+k!-Yu<3@;`zFnpWDz`!+`fk9z11B2OQ
z1_rmu3=C0|85nXVGcdGGW?+~$nSo)`WCn&)lNlIpO=e*DGMRxvXbJ;^)D#8=y(tU~
zHd7cFBBn4fWPuhzGcYhzO<`c@n8Ls?Z3+X!qA3gvtEMn8Y?{KruxAPb!?7t04CkgW
zFx;5J!0=!S1H-E+3=ChUFfja^!oa{W72-mXsSFGTP`1ZZ28N)i3=A<-85q*0GB6ZO
zWnie9%D~V9m7g$`fnmv128KOT85k~1Wng$Qm4V^MR0altX$%Z1(-;^`rZF&hOk-e3
zn8v_RGL3<uXBq>;f@us4JEk!(T$skd@MIbT1H*I%29fCu3@XzZ7%Zkk+%OtG_`~N4
zgG*{oYDubdQD#YIa$-&}bgcISgDYqh9$lCrmC>yzHPt6GsVK3ilHn+$duoYuX%T3s
zI-n>&IkmW$;TWcvX9~k9B+-zJqSV9`&lCm*7AE)95}(B463Fm1gBXbK3m*3ONX$#g
zNp)mka07{f42KR+GceSEM1m`eOHy+~GILWMi`_DFQb8<+86cUE%;aq6{L;J<28K6G
zo_U!inTa`>RTw^0XZA@=EW;3H&|>z<PfUUO(2;>*Ix~2<J0P_vEx#x?F)uk4Y<OxB
zLk>%DYDs8b2H2%3t`*6t1)%Y2x6B;S{6!^8a87D!0Yf`WNNQ1TW?o`RD##b0AY$la
z3CSsTPb~>c%qdM}n9YLI5Qg0>&@p%D_&Ec^K9~sDSqu#3pee<iocz4hip&y*i45_H
zxy9-6U=BkZV?3x@DM>BLWk_O-&&*F^U^v4VpOc@Q%}~q~57pzr9ABCT7L#X5Ov*1R
zVbEqtPRz*xo%iC)l2(+O%D@o8l2%@nS(3`Y(9V(zmD|fwTvC*in#aI!0L02m&Mjbg
z$WoS8P?VWhlE%QG0&*GF$xa4_OdQjr_eE0DQ*(+_;u(H|ScOGt@eJq1V3T8IGLTt~
zc!moyRZw+rKrFDjC-Sg4K?VkPhJZ@PqV)KH#G>NVkkW#jR8X5P05<;=?^qm`pP3R+
z0-9$sV?c<9R2HOyN{%*$fJ&Fl<dXQ{)Dq8<)ZE~bqRhN>28JmN0hO*rMe%N+v{1sp
zFb&H0OD%^d0FeG!P;vj{WKi}1HKiG5L&X9>;lseduolV>PA!2M&u|hXR+g9(ACy{L
zl3$bx$tw&Dr(oj2iDfXs3m~zI<ao!DlA_F{(vnnYF1iC1_XN+=K?L7G#ez!nKr=`X
zK?Vi}XU2d^h`M+P1<8F3D;WbSA<TI9)DlogFfed21yn+&??7T8Tj9=TILZ`I2@1P-
z&*I?HB+&FQ1A{4ZKxI5=vLywQ&ci@_P=<sU3>pGp;9!XlsEqf^&r1z1DJo3{&u@dy
zlA;Cnb`A1#^)WUA&#;5~3lkU^M99Rs#bwDwB@mM|CNMC7Fn9_dbqxT6%>)LVI43hH
zzaTX)DJQWQY*4@i1_o;5oXn(x%94!yJR?1GuqB|xIf`i;0s;rX!x11$Ky$7aG!T4{
z*eD*RA+X^<uFQr5xjn@PawQgw#`!RfW$fM(U|?`yWMGgrP%`j0NHRz_Xg8Q(aNXdS
z0jr^~p@N~AVT@s;;S|F|hGz_K7(Oy&G7>S8Hc~Y5F!DEwGHNvHFnVspYT|7YWRhW$
zXHsHPW71+W$7H3+R+Bv@hfU6zJTZA|^4EmTRLNA$RNK_uG{`j4G|jZjbc5-6Q#~_#
zvt+Xzvp%!wW}x#Q|C@!GN1G>^H<-7Y_n0p;Uv0k0T*t!1!rCI=VxPrfi&GXaEZ$mt
zvEZ{5wv@8$v7BN#$8w3~7Rx=Bhb<+n7FjK~T4!~}>Y~*Rt8Z4nt(dG8tW~Xbti7!L
zt;4L#t!u2Ct<7zmZM<xPY?5rUY>I5EY`SbF+5EQ&vyHY*vTd+!we7K8X1m&UldX=O
ziJi4wzTG~%!*-|aUf8|0`(npuFKjPm-(x?;evbVT`z`i+><@z`Mim$sKyyuU2Fnaq
z8*DPTU~tvoj=^68CPPj`Ekk`nGsAGh7{g>kB_mBELnBM00HX+_1fyc3YNKYOZlhO5
zpNxJQ@fxccI~n^JhZv_B*BI|MzGM8sSkJ`C#N8yzq}8O$WR}TNleH$-Odgm#HTi1t
z--O*%+*HL>+tk?9*)+&B$~4I|%e2U}%CyO}%XE_IEYn4%t4ueU?lL`Oddl>Y=`GVo
zrmsvtnf@|mG7~kkHuEuSH=A#^)9j-evpK)Hnz@;|lX;AJp?Q<}4D)T~r_Jw}KQVt}
z{@Yy6LfOK@BEllmBG01OqS~UtqQhdM#cYd(7OO0FTc}wYTLxK1Sms(@wftboYh_{O
zX4P)B)#{Mdb1N2WL2ET@U2AJ=U+YBcLhEkp_0|Wik6E9#eq{aL`mZ&U4Zn?wjj4^b
zjf+i|O^r>H%`BS*Hmhwm+U&47X>-};uZ@VUo~@&8l5K(Q1lyUmFKqwW3fXDd8Q7WG
z+1t6=RoK<pO|&~|cg60e-6Ok~cAxA-?Tzg%?d|PT?6d4A+E2G%Vt>y5qy0Zn{1`AW
zfKF=SFi<woHLx(SGYB+@HYhfzG|)A4H1szNGmJLeYIxZ2qTy}BM}{v9O^qCl{Efnl
z(u^97`i-U<%`tjv^wH?Ak*Kk<v7xcGv6Hcf@pR*j#`}$r8lN_1G0`&#GKn(TWU|ZT
zkjW{NOD4BW9+|u{`DF6Tgvpf4RLIoC6g24onNL?RP%$ttFfnj2a4`rl2r)=7NHHid
zC^2X-Xfap-8n_LB9925UWP!;NP%Co*gwJCjVITvN-vHsW7;qTy7zltw7$^k*9a={H

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.py
new file mode 100644
index 0000000000..9d486d2a5d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.py
@@ -0,0 +1,2409 @@
+"""Lite version of scipy.linalg.
+
+Notes
+-----
+This module is a lite version of the linalg.py module in SciPy which
+contains high-level Python interface to the LAPACK library.  The lite
+version only accesses the following LAPACK functions: dgesv, zgesv,
+dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf,
+zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr.
+"""
+from __future__ import division, absolute_import, print_function
+
+
+__all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv',
+           'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det',
+           'svd', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond', 'matrix_rank',
+           'LinAlgError', 'multi_dot']
+
+import warnings
+
+from numpy.core import (
+    array, asarray, zeros, empty, empty_like, transpose, intc, single, double,
+    csingle, cdouble, inexact, complexfloating, newaxis, ravel, all, Inf, dot,
+    add, multiply, sqrt, maximum, fastCopyAndTranspose, sum, isfinite, size,
+    finfo, errstate, geterrobj, longdouble, rollaxis, amin, amax, product, abs,
+    broadcast, atleast_2d, intp, asanyarray, isscalar
+    )
+from numpy.lib import triu, asfarray
+from numpy.linalg import lapack_lite, _umath_linalg
+from numpy.matrixlib.defmatrix import matrix_power
+from numpy.compat import asbytes
+
+# For Python2/3 compatibility
+_N = asbytes('N')
+_V = asbytes('V')
+_A = asbytes('A')
+_S = asbytes('S')
+_L = asbytes('L')
+
+fortran_int = intc
+
+# Error object
+class LinAlgError(Exception):
+    """
+    Generic Python-exception-derived object raised by linalg functions.
+
+    General purpose exception class, derived from Python's exception.Exception
+    class, programmatically raised in linalg functions when a Linear
+    Algebra-related condition would prevent further correct execution of the
+    function.
+
+    Parameters
+    ----------
+    None
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> LA.inv(np.zeros((2,2)))
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+      File "...linalg.py", line 350,
+        in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
+      File "...linalg.py", line 249,
+        in solve
+        raise LinAlgError('Singular matrix')
+    numpy.linalg.LinAlgError: Singular matrix
+
+    """
+    pass
+
+# Dealing with errors in _umath_linalg
+
+_linalg_error_extobj = None
+
+def _determine_error_states():
+    global _linalg_error_extobj
+    errobj = geterrobj()
+    bufsize = errobj[0]
+
+    with errstate(invalid='call', over='ignore',
+                  divide='ignore', under='ignore'):
+        invalid_call_errmask = geterrobj()[1]
+
+    _linalg_error_extobj = [bufsize, invalid_call_errmask, None]
+
+_determine_error_states()
+
+def _raise_linalgerror_singular(err, flag):
+    raise LinAlgError("Singular matrix")
+
+def _raise_linalgerror_nonposdef(err, flag):
+    raise LinAlgError("Matrix is not positive definite")
+
+def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
+    raise LinAlgError("Eigenvalues did not converge")
+
+def _raise_linalgerror_svd_nonconvergence(err, flag):
+    raise LinAlgError("SVD did not converge")
+
+def get_linalg_error_extobj(callback):
+    extobj = list(_linalg_error_extobj)
+    extobj[2] = callback
+    return extobj
+
+def _makearray(a):
+    new = asarray(a)
+    wrap = getattr(a, "__array_prepare__", new.__array_wrap__)
+    return new, wrap
+
+def isComplexType(t):
+    return issubclass(t, complexfloating)
+
+_real_types_map = {single : single,
+                   double : double,
+                   csingle : single,
+                   cdouble : double}
+
+_complex_types_map = {single : csingle,
+                      double : cdouble,
+                      csingle : csingle,
+                      cdouble : cdouble}
+
+def _realType(t, default=double):
+    return _real_types_map.get(t, default)
+
+def _complexType(t, default=cdouble):
+    return _complex_types_map.get(t, default)
+
+def _linalgRealType(t):
+    """Cast the type t to either double or cdouble."""
+    return double
+
+_complex_types_map = {single : csingle,
+                      double : cdouble,
+                      csingle : csingle,
+                      cdouble : cdouble}
+
+def _commonType(*arrays):
+    # in lite version, use higher precision (always double or cdouble)
+    result_type = single
+    is_complex = False
+    for a in arrays:
+        if issubclass(a.dtype.type, inexact):
+            if isComplexType(a.dtype.type):
+                is_complex = True
+            rt = _realType(a.dtype.type, default=None)
+            if rt is None:
+                # unsupported inexact scalar
+                raise TypeError("array type %s is unsupported in linalg" %
+                        (a.dtype.name,))
+        else:
+            rt = double
+        if rt is double:
+            result_type = double
+    if is_complex:
+        t = cdouble
+        result_type = _complex_types_map[result_type]
+    else:
+        t = double
+    return t, result_type
+
+
+# _fastCopyAndTranpose assumes the input is 2D (as all the calls in here are).
+
+_fastCT = fastCopyAndTranspose
+
+def _to_native_byte_order(*arrays):
+    ret = []
+    for arr in arrays:
+        if arr.dtype.byteorder not in ('=', '|'):
+            ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('=')))
+        else:
+            ret.append(arr)
+    if len(ret) == 1:
+        return ret[0]
+    else:
+        return ret
+
+def _fastCopyAndTranspose(type, *arrays):
+    cast_arrays = ()
+    for a in arrays:
+        if a.dtype.type is type:
+            cast_arrays = cast_arrays + (_fastCT(a),)
+        else:
+            cast_arrays = cast_arrays + (_fastCT(a.astype(type)),)
+    if len(cast_arrays) == 1:
+        return cast_arrays[0]
+    else:
+        return cast_arrays
+
+def _assertRank2(*arrays):
+    for a in arrays:
+        if len(a.shape) != 2:
+            raise LinAlgError('%d-dimensional array given. Array must be '
+                    'two-dimensional' % len(a.shape))
+
+def _assertRankAtLeast2(*arrays):
+    for a in arrays:
+        if len(a.shape) < 2:
+            raise LinAlgError('%d-dimensional array given. Array must be '
+                    'at least two-dimensional' % len(a.shape))
+
+def _assertSquareness(*arrays):
+    for a in arrays:
+        if max(a.shape) != min(a.shape):
+            raise LinAlgError('Array must be square')
+
+def _assertNdSquareness(*arrays):
+    for a in arrays:
+        if max(a.shape[-2:]) != min(a.shape[-2:]):
+            raise LinAlgError('Last 2 dimensions of the array must be square')
+
+def _assertFinite(*arrays):
+    for a in arrays:
+        if not (isfinite(a).all()):
+            raise LinAlgError("Array must not contain infs or NaNs")
+
+def _assertNoEmpty2d(*arrays):
+    for a in arrays:
+        if a.size == 0 and product(a.shape[-2:]) == 0:
+            raise LinAlgError("Arrays cannot be empty")
+
+
+# Linear equations
+
+def tensorsolve(a, b, axes=None):
+    """
+    Solve the tensor equation ``a x = b`` for x.
+
+    It is assumed that all indices of `x` are summed over in the product,
+    together with the rightmost indices of `a`, as is done in, for example,
+    ``tensordot(a, x, axes=len(b.shape))``.
+
+    Parameters
+    ----------
+    a : array_like
+        Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals
+        the shape of that sub-tensor of `a` consisting of the appropriate
+        number of its rightmost indices, and must be such that
+        ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be
+        'square').
+    b : array_like
+        Right-hand tensor, which can be of any shape.
+    axes : tuple of ints, optional
+        Axes in `a` to reorder to the right, before inversion.
+        If None (default), no reordering is done.
+
+    Returns
+    -------
+    x : ndarray, shape Q
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not 'square' (in the above sense).
+
+    See Also
+    --------
+    tensordot, tensorinv, einsum
+
+    Examples
+    --------
+    >>> a = np.eye(2*3*4)
+    >>> a.shape = (2*3, 4, 2, 3, 4)
+    >>> b = np.random.randn(2*3, 4)
+    >>> x = np.linalg.tensorsolve(a, b)
+    >>> x.shape
+    (2, 3, 4)
+    >>> np.allclose(np.tensordot(a, x, axes=3), b)
+    True
+
+    """
+    a, wrap = _makearray(a)
+    b = asarray(b)
+    an = a.ndim
+
+    if axes is not None:
+        allaxes = list(range(0, an))
+        for k in axes:
+            allaxes.remove(k)
+            allaxes.insert(an, k)
+        a = a.transpose(allaxes)
+
+    oldshape = a.shape[-(an-b.ndim):]
+    prod = 1
+    for k in oldshape:
+        prod *= k
+
+    a = a.reshape(-1, prod)
+    b = b.ravel()
+    res = wrap(solve(a, b))
+    res.shape = oldshape
+    return res
+
+def solve(a, b):
+    """
+    Solve a linear matrix equation, or system of linear scalar equations.
+
+    Computes the "exact" solution, `x`, of the well-determined, i.e., full
+    rank, linear matrix equation `ax = b`.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Coefficient matrix.
+    b : {(..., M,), (..., M, K)}, array_like
+        Ordinate or "dependent variable" values.
+
+    Returns
+    -------
+    x : {(..., M,), (..., M, K)} ndarray
+        Solution to the system a x = b.  Returned shape is identical to `b`.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not square.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The solutions are computed using LAPACK routine _gesv
+
+    `a` must be square and of full-rank, i.e., all rows (or, equivalently,
+    columns) must be linearly independent; if either is not true, use
+    `lstsq` for the least-squares best "solution" of the
+    system/equation.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pg. 22.
+
+    Examples
+    --------
+    Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``:
+
+    >>> a = np.array([[3,1], [1,2]])
+    >>> b = np.array([9,8])
+    >>> x = np.linalg.solve(a, b)
+    >>> x
+    array([ 2.,  3.])
+
+    Check that the solution is correct:
+
+    >>> np.allclose(np.dot(a, x), b)
+    True
+
+    """
+    a, _ = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    b, wrap = _makearray(b)
+    t, result_t = _commonType(a, b)
+
+    # We use the b = (..., M,) logic, only if the number of extra dimensions
+    # match exactly
+    if b.ndim == a.ndim - 1:
+        if a.shape[-1] == 0 and b.shape[-1] == 0:
+            # Legal, but the ufunc cannot handle the 0-sized inner dims
+            # let the ufunc handle all wrong cases.
+            a = a.reshape(a.shape[:-1])
+            bc = broadcast(a, b)
+            return wrap(empty(bc.shape, dtype=result_t))
+
+        gufunc = _umath_linalg.solve1
+    else:
+        if b.size == 0:
+            if (a.shape[-1] == 0 and b.shape[-2] == 0) or b.shape[-1] == 0:
+                a = a[:,:1].reshape(a.shape[:-1] + (1,))
+                bc = broadcast(a, b)
+                return wrap(empty(bc.shape, dtype=result_t))
+
+        gufunc = _umath_linalg.solve
+
+    signature = 'DD->D' if isComplexType(t) else 'dd->d'
+    extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
+    r = gufunc(a, b, signature=signature, extobj=extobj)
+
+    return wrap(r.astype(result_t, copy=False))
+
+
+def tensorinv(a, ind=2):
+    """
+    Compute the 'inverse' of an N-dimensional array.
+
+    The result is an inverse for `a` relative to the tensordot operation
+    ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy,
+    ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the
+    tensordot operation.
+
+    Parameters
+    ----------
+    a : array_like
+        Tensor to 'invert'. Its shape must be 'square', i. e.,
+        ``prod(a.shape[:ind]) == prod(a.shape[ind:])``.
+    ind : int, optional
+        Number of first indices that are involved in the inverse sum.
+        Must be a positive integer, default is 2.
+
+    Returns
+    -------
+    b : ndarray
+        `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not 'square' (in the above sense).
+
+    See Also
+    --------
+    tensordot, tensorsolve
+
+    Examples
+    --------
+    >>> a = np.eye(4*6)
+    >>> a.shape = (4, 6, 8, 3)
+    >>> ainv = np.linalg.tensorinv(a, ind=2)
+    >>> ainv.shape
+    (8, 3, 4, 6)
+    >>> b = np.random.randn(4, 6)
+    >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b))
+    True
+
+    >>> a = np.eye(4*6)
+    >>> a.shape = (24, 8, 3)
+    >>> ainv = np.linalg.tensorinv(a, ind=1)
+    >>> ainv.shape
+    (8, 3, 24)
+    >>> b = np.random.randn(24)
+    >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b))
+    True
+
+    """
+    a = asarray(a)
+    oldshape = a.shape
+    prod = 1
+    if ind > 0:
+        invshape = oldshape[ind:] + oldshape[:ind]
+        for k in oldshape[ind:]:
+            prod *= k
+    else:
+        raise ValueError("Invalid ind argument.")
+    a = a.reshape(prod, -1)
+    ia = inv(a)
+    return ia.reshape(*invshape)
+
+
+# Matrix inversion
+
+def inv(a):
+    """
+    Compute the (multiplicative) inverse of a matrix.
+
+    Given a square matrix `a`, return the matrix `ainv` satisfying
+    ``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Matrix to be inverted.
+
+    Returns
+    -------
+    ainv : (..., M, M) ndarray or matrix
+        (Multiplicative) inverse of the matrix `a`.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is not square or inversion fails.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    Examples
+    --------
+    >>> from numpy.linalg import inv
+    >>> a = np.array([[1., 2.], [3., 4.]])
+    >>> ainv = inv(a)
+    >>> np.allclose(np.dot(a, ainv), np.eye(2))
+    True
+    >>> np.allclose(np.dot(ainv, a), np.eye(2))
+    True
+
+    If a is a matrix object, then the return value is a matrix as well:
+
+    >>> ainv = inv(np.matrix(a))
+    >>> ainv
+    matrix([[-2. ,  1. ],
+            [ 1.5, -0.5]])
+
+    Inverses of several matrices can be computed at once:
+
+    >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
+    >>> inv(a)
+    array([[[-2. ,  1. ],
+            [ 1.5, -0.5]],
+           [[-5. ,  2. ],
+            [ 3. , -1. ]]])
+
+    """
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+
+    if a.shape[-1] == 0:
+        # The inner array is 0x0, the ufunc cannot handle this case
+        return wrap(empty_like(a, dtype=result_t))
+
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
+    ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
+    return wrap(ainv.astype(result_t, copy=False))
+
+
+# Cholesky decomposition
+
+def cholesky(a):
+    """
+    Cholesky decomposition.
+
+    Return the Cholesky decomposition, `L * L.H`, of the square matrix `a`,
+    where `L` is lower-triangular and .H is the conjugate transpose operator
+    (which is the ordinary transpose if `a` is real-valued).  `a` must be
+    Hermitian (symmetric if real-valued) and positive-definite.  Only `L` is
+    actually returned.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Hermitian (symmetric if all elements are real), positive-definite
+        input matrix.
+
+    Returns
+    -------
+    L : (..., M, M) array_like
+        Upper or lower-triangular Cholesky factor of `a`.  Returns a
+        matrix object if `a` is a matrix object.
+
+    Raises
+    ------
+    LinAlgError
+       If the decomposition fails, for example, if `a` is not
+       positive-definite.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The Cholesky decomposition is often used as a fast way of solving
+
+    .. math:: A \\mathbf{x} = \\mathbf{b}
+
+    (when `A` is both Hermitian/symmetric and positive-definite).
+
+    First, we solve for :math:`\\mathbf{y}` in
+
+    .. math:: L \\mathbf{y} = \\mathbf{b},
+
+    and then for :math:`\\mathbf{x}` in
+
+    .. math:: L.H \\mathbf{x} = \\mathbf{y}.
+
+    Examples
+    --------
+    >>> A = np.array([[1,-2j],[2j,5]])
+    >>> A
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> L = np.linalg.cholesky(A)
+    >>> L
+    array([[ 1.+0.j,  0.+0.j],
+           [ 0.+2.j,  1.+0.j]])
+    >>> np.dot(L, L.T.conj()) # verify that L * L.H = A
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like?
+    >>> np.linalg.cholesky(A) # an ndarray object is returned
+    array([[ 1.+0.j,  0.+0.j],
+           [ 0.+2.j,  1.+0.j]])
+    >>> # But a matrix object is returned if A is a matrix object
+    >>> LA.cholesky(np.matrix(A))
+    matrix([[ 1.+0.j,  0.+0.j],
+            [ 0.+2.j,  1.+0.j]])
+
+    """
+    extobj = get_linalg_error_extobj(_raise_linalgerror_nonposdef)
+    gufunc = _umath_linalg.cholesky_lo
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    r = gufunc(a, signature=signature, extobj=extobj)
+    return wrap(r.astype(result_t, copy=False))
+
+# QR decompostion
+
+def qr(a, mode='reduced'):
+    """
+    Compute the qr factorization of a matrix.
+
+    Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is
+    upper-triangular.
+
+    Parameters
+    ----------
+    a : array_like, shape (M, N)
+        Matrix to be factored.
+    mode : {'reduced', 'complete', 'r', 'raw', 'full', 'economic'}, optional
+        If K = min(M, N), then
+
+        'reduced'  : returns q, r with dimensions (M, K), (K, N) (default)
+        'complete' : returns q, r with dimensions (M, M), (M, N)
+        'r'        : returns r only with dimensions (K, N)
+        'raw'      : returns h, tau with dimensions (N, M), (K,)
+        'full'     : alias of 'reduced', deprecated
+        'economic' : returns h from 'raw', deprecated.
+
+        The options 'reduced', 'complete, and 'raw' are new in numpy 1.8,
+        see the notes for more information. The default is 'reduced' and to
+        maintain backward compatibility with earlier versions of numpy both
+        it and the old default 'full' can be omitted. Note that array h
+        returned in 'raw' mode is transposed for calling Fortran. The
+        'economic' mode is deprecated.  The modes 'full' and 'economic' may
+        be passed using only the first letter for backwards compatibility,
+        but all others must be spelled out. See the Notes for more
+        explanation.
+
+
+    Returns
+    -------
+    q : ndarray of float or complex, optional
+        A matrix with orthonormal columns. When mode = 'complete' the
+        result is an orthogonal/unitary matrix depending on whether or not
+        a is real/complex. The determinant may be either +/- 1 in that
+        case.
+    r : ndarray of float or complex, optional
+        The upper-triangular matrix.
+    (h, tau) : ndarrays of np.double or np.cdouble, optional
+        The array h contains the Householder reflectors that generate q
+        along with r. The tau array contains scaling factors for the
+        reflectors. In the deprecated  'economic' mode only h is returned.
+
+    Raises
+    ------
+    LinAlgError
+        If factoring fails.
+
+    Notes
+    -----
+    This is an interface to the LAPACK routines dgeqrf, zgeqrf,
+    dorgqr, and zungqr.
+
+    For more information on the qr factorization, see for example:
+    http://en.wikipedia.org/wiki/QR_factorization
+
+    Subclasses of `ndarray` are preserved except for the 'raw' mode. So if
+    `a` is of type `matrix`, all the return values will be matrices too.
+
+    New 'reduced', 'complete', and 'raw' options for mode were added in
+    Numpy 1.8 and the old option 'full' was made an alias of 'reduced'.  In
+    addition the options 'full' and 'economic' were deprecated.  Because
+    'full' was the previous default and 'reduced' is the new default,
+    backward compatibility can be maintained by letting `mode` default.
+    The 'raw' option was added so that LAPACK routines that can multiply
+    arrays by q using the Householder reflectors can be used. Note that in
+    this case the returned arrays are of type np.double or np.cdouble and
+    the h array is transposed to be FORTRAN compatible.  No routines using
+    the 'raw' return are currently exposed by numpy, but some are available
+    in lapack_lite and just await the necessary work.
+
+    Examples
+    --------
+    >>> a = np.random.randn(9, 6)
+    >>> q, r = np.linalg.qr(a)
+    >>> np.allclose(a, np.dot(q, r))  # a does equal qr
+    True
+    >>> r2 = np.linalg.qr(a, mode='r')
+    >>> r3 = np.linalg.qr(a, mode='economic')
+    >>> np.allclose(r, r2)  # mode='r' returns the same r as mode='full'
+    True
+    >>> # But only triu parts are guaranteed equal when mode='economic'
+    >>> np.allclose(r, np.triu(r3[:6,:6], k=0))
+    True
+
+    Example illustrating a common use of `qr`: solving of least squares
+    problems
+
+    What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for
+    the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points
+    and you'll see that it should be y0 = 0, m = 1.)  The answer is provided
+    by solving the over-determined matrix equation ``Ax = b``, where::
+
+      A = array([[0, 1], [1, 1], [1, 1], [2, 1]])
+      x = array([[y0], [m]])
+      b = array([[1], [0], [2], [1]])
+
+    If A = qr such that q is orthonormal (which is always possible via
+    Gram-Schmidt), then ``x = inv(r) * (q.T) * b``.  (In numpy practice,
+    however, we simply use `lstsq`.)
+
+    >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]])
+    >>> A
+    array([[0, 1],
+           [1, 1],
+           [1, 1],
+           [2, 1]])
+    >>> b = np.array([1, 0, 2, 1])
+    >>> q, r = LA.qr(A)
+    >>> p = np.dot(q.T, b)
+    >>> np.dot(LA.inv(r), p)
+    array([  1.1e-16,   1.0e+00])
+
+    """
+    if mode not in ('reduced', 'complete', 'r', 'raw'):
+        if mode in ('f', 'full'):
+            # 2013-04-01, 1.8
+            msg = "".join((
+                    "The 'full' option is deprecated in favor of 'reduced'.\n",
+                    "For backward compatibility let mode default."))
+            warnings.warn(msg, DeprecationWarning)
+            mode = 'reduced'
+        elif mode in ('e', 'economic'):
+            # 2013-04-01, 1.8
+            msg = "The 'economic' option is deprecated.",
+            warnings.warn(msg, DeprecationWarning)
+            mode = 'economic'
+        else:
+            raise ValueError("Unrecognized mode '%s'" % mode)
+
+    a, wrap = _makearray(a)
+    _assertRank2(a)
+    _assertNoEmpty2d(a)
+    m, n = a.shape
+    t, result_t = _commonType(a)
+    a = _fastCopyAndTranspose(t, a)
+    a = _to_native_byte_order(a)
+    mn = min(m, n)
+    tau = zeros((mn,), t)
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zgeqrf
+        routine_name = 'zgeqrf'
+    else:
+        lapack_routine = lapack_lite.dgeqrf
+        routine_name = 'dgeqrf'
+
+    # calculate optimal size of work data 'work'
+    lwork = 1
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, n, a, m, tau, work, -1, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # do qr decomposition
+    lwork = int(abs(work[0]))
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, n, a, m, tau, work, lwork, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # handle modes that don't return q
+    if mode == 'r':
+        r = _fastCopyAndTranspose(result_t, a[:, :mn])
+        return wrap(triu(r))
+
+    if mode == 'raw':
+        return a, tau
+
+    if mode == 'economic':
+        if t != result_t :
+            a = a.astype(result_t, copy=False)
+        return wrap(a.T)
+
+    #  generate q from a
+    if mode == 'complete' and m > n:
+        mc = m
+        q = empty((m, m), t)
+    else:
+        mc = mn
+        q = empty((n, m), t)
+    q[:n] = a
+
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zungqr
+        routine_name = 'zungqr'
+    else:
+        lapack_routine = lapack_lite.dorgqr
+        routine_name = 'dorgqr'
+
+    # determine optimal lwork
+    lwork = 1
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, mc, mn, q, m, tau, work, -1, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # compute q
+    lwork = int(abs(work[0]))
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, mc, mn, q, m, tau, work, lwork, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    q = _fastCopyAndTranspose(result_t, q[:mc])
+    r = _fastCopyAndTranspose(result_t, a[:, :mc])
+
+    return wrap(q), wrap(triu(r))
+
+
+# Eigenvalues
+
+
+def eigvals(a):
+    """
+    Compute the eigenvalues of a general matrix.
+
+    Main difference between `eigvals` and `eig`: the eigenvectors aren't
+    returned.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        A complex- or real-valued matrix whose eigenvalues will be computed.
+
+    Returns
+    -------
+    w : (..., M,) ndarray
+        The eigenvalues, each repeated according to its multiplicity.
+        They are not necessarily ordered, nor are they necessarily
+        real for real matrices.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eig : eigenvalues and right eigenvectors of general arrays
+    eigvalsh : eigenvalues of symmetric or Hermitian arrays.
+    eigh : eigenvalues and eigenvectors of symmetric/Hermitian arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    This is implemented using the _geev LAPACK routines which compute
+    the eigenvalues and eigenvectors of general square arrays.
+
+    Examples
+    --------
+    Illustration, using the fact that the eigenvalues of a diagonal matrix
+    are its diagonal elements, that multiplying a matrix on the left
+    by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose
+    of `Q`), preserves the eigenvalues of the "middle" matrix.  In other words,
+    if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as
+    ``A``:
+
+    >>> from numpy import linalg as LA
+    >>> x = np.random.random()
+    >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]])
+    >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :])
+    (1.0, 1.0, 0.0)
+
+    Now multiply a diagonal matrix by Q on one side and by Q.T on the other:
+
+    >>> D = np.diag((-1,1))
+    >>> LA.eigvals(D)
+    array([-1.,  1.])
+    >>> A = np.dot(Q, D)
+    >>> A = np.dot(A, Q.T)
+    >>> LA.eigvals(A)
+    array([ 1., -1.])
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    _assertFinite(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    signature = 'D->D' if isComplexType(t) else 'd->D'
+    w = _umath_linalg.eigvals(a, signature=signature, extobj=extobj)
+
+    if not isComplexType(t):
+        if all(w.imag == 0):
+            w = w.real
+            result_t = _realType(result_t)
+        else:
+            result_t = _complexType(result_t)
+
+    return w.astype(result_t, copy=False)
+
+def eigvalsh(a, UPLO='L'):
+    """
+    Compute the eigenvalues of a Hermitian or real symmetric matrix.
+
+    Main difference from eigh: the eigenvectors are not computed.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        A complex- or real-valued matrix whose eigenvalues are to be
+        computed.
+    UPLO : {'L', 'U'}, optional
+        Same as `lower`, with 'L' for lower and 'U' for upper triangular.
+        Deprecated.
+
+    Returns
+    -------
+    w : (..., M,) ndarray
+        The eigenvalues in ascending order, each repeated according to
+        its multiplicity.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigh : eigenvalues and eigenvectors of symmetric/Hermitian arrays.
+    eigvals : eigenvalues of general real or complex arrays.
+    eig : eigenvalues and right eigenvectors of general real or complex
+          arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The eigenvalues are computed using LAPACK routines _syevd, _heevd
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, -2j], [2j, 5]])
+    >>> LA.eigvalsh(a)
+    array([ 0.17157288,  5.82842712])
+
+    """
+    UPLO = UPLO.upper()
+    if UPLO not in ('L', 'U'):
+        raise ValueError("UPLO argument must be 'L' or 'U'")
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    if UPLO == 'L':
+        gufunc = _umath_linalg.eigvalsh_lo
+    else:
+        gufunc = _umath_linalg.eigvalsh_up
+
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->d' if isComplexType(t) else 'd->d'
+    w = gufunc(a, signature=signature, extobj=extobj)
+    return w.astype(_realType(result_t), copy=False)
+
+def _convertarray(a):
+    t, result_t = _commonType(a)
+    a = _fastCT(a.astype(t))
+    return a, t, result_t
+
+
+# Eigenvectors
+
+
+def eig(a):
+    """
+    Compute the eigenvalues and right eigenvectors of a square array.
+
+    Parameters
+    ----------
+    a : (..., M, M) array
+        Matrices for which the eigenvalues and right eigenvectors will
+        be computed
+
+    Returns
+    -------
+    w : (..., M) array
+        The eigenvalues, each repeated according to its multiplicity.
+        The eigenvalues are not necessarily ordered. The resulting
+        array will be of complex type, unless the imaginary part is
+        zero in which case it will be cast to a real type. When `a`
+        is real the resulting eigenvalues will be real (0 imaginary
+        part) or occur in conjugate pairs
+
+    v : (..., M, M) array
+        The normalized (unit "length") eigenvectors, such that the
+        column ``v[:,i]`` is the eigenvector corresponding to the
+        eigenvalue ``w[i]``.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigvals : eigenvalues of a non-symmetric array.
+
+    eigh : eigenvalues and eigenvectors of a symmetric or Hermitian
+           (conjugate symmetric) array.
+
+    eigvalsh : eigenvalues of a symmetric or Hermitian (conjugate symmetric)
+               array.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    This is implemented using the _geev LAPACK routines which compute
+    the eigenvalues and eigenvectors of general square arrays.
+
+    The number `w` is an eigenvalue of `a` if there exists a vector
+    `v` such that ``dot(a,v) = w * v``. Thus, the arrays `a`, `w`, and
+    `v` satisfy the equations ``dot(a[:,:], v[:,i]) = w[i] * v[:,i]``
+    for :math:`i \\in \\{0,...,M-1\\}`.
+
+    The array `v` of eigenvectors may not be of maximum rank, that is, some
+    of the columns may be linearly dependent, although round-off error may
+    obscure that fact. If the eigenvalues are all different, then theoretically
+    the eigenvectors are linearly independent. Likewise, the (complex-valued)
+    matrix of eigenvectors `v` is unitary if the matrix `a` is normal, i.e.,
+    if ``dot(a, a.H) = dot(a.H, a)``, where `a.H` denotes the conjugate
+    transpose of `a`.
+
+    Finally, it is emphasized that `v` consists of the *right* (as in
+    right-hand side) eigenvectors of `a`.  A vector `y` satisfying
+    ``dot(y.T, a) = z * y.T`` for some number `z` is called a *left*
+    eigenvector of `a`, and, in general, the left and right eigenvectors
+    of a matrix are not necessarily the (perhaps conjugate) transposes
+    of each other.
+
+    References
+    ----------
+    G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL,
+    Academic Press, Inc., 1980, Various pp.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+
+    (Almost) trivial example with real e-values and e-vectors.
+
+    >>> w, v = LA.eig(np.diag((1, 2, 3)))
+    >>> w; v
+    array([ 1.,  2.,  3.])
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    Real matrix possessing complex e-values and e-vectors; note that the
+    e-values are complex conjugates of each other.
+
+    >>> w, v = LA.eig(np.array([[1, -1], [1, 1]]))
+    >>> w; v
+    array([ 1. + 1.j,  1. - 1.j])
+    array([[ 0.70710678+0.j        ,  0.70710678+0.j        ],
+           [ 0.00000000-0.70710678j,  0.00000000+0.70710678j]])
+
+    Complex-valued matrix with real e-values (but complex-valued e-vectors);
+    note that a.conj().T = a, i.e., a is Hermitian.
+
+    >>> a = np.array([[1, 1j], [-1j, 1]])
+    >>> w, v = LA.eig(a)
+    >>> w; v
+    array([  2.00000000e+00+0.j,   5.98651912e-36+0.j]) # i.e., {2, 0}
+    array([[ 0.00000000+0.70710678j,  0.70710678+0.j        ],
+           [ 0.70710678+0.j        ,  0.00000000+0.70710678j]])
+
+    Be careful about round-off error!
+
+    >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]])
+    >>> # Theor. e-values are 1 +/- 1e-9
+    >>> w, v = LA.eig(a)
+    >>> w; v
+    array([ 1.,  1.])
+    array([[ 1.,  0.],
+           [ 0.,  1.]])
+
+    """
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    _assertFinite(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    signature = 'D->DD' if isComplexType(t) else 'd->DD'
+    w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj)
+
+    if not isComplexType(t) and all(w.imag == 0.0):
+        w = w.real
+        vt = vt.real
+        result_t = _realType(result_t)
+    else:
+        result_t = _complexType(result_t)
+
+    vt = vt.astype(result_t, copy=False)
+    return w.astype(result_t, copy=False), wrap(vt)
+
+
+def eigh(a, UPLO='L'):
+    """
+    Return the eigenvalues and eigenvectors of a Hermitian or symmetric matrix.
+
+    Returns two objects, a 1-D array containing the eigenvalues of `a`, and
+    a 2-D square array or matrix (depending on the input type) of the
+    corresponding eigenvectors (in columns).
+
+    Parameters
+    ----------
+    a : (..., M, M) array
+        Hermitian/Symmetric matrices whose eigenvalues and
+        eigenvectors are to be computed.
+    UPLO : {'L', 'U'}, optional
+        Specifies whether the calculation is done with the lower triangular
+        part of `a` ('L', default) or the upper triangular part ('U').
+
+    Returns
+    -------
+    w : (..., M) ndarray
+        The eigenvalues in ascending order, each repeated according to
+        its multiplicity.
+    v : {(..., M, M) ndarray, (..., M, M) matrix}
+        The column ``v[:, i]`` is the normalized eigenvector corresponding
+        to the eigenvalue ``w[i]``.  Will return a matrix object if `a` is
+        a matrix object.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigvalsh : eigenvalues of symmetric or Hermitian arrays.
+    eig : eigenvalues and right eigenvectors for non-symmetric arrays.
+    eigvals : eigenvalues of non-symmetric arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The eigenvalues/eigenvectors are computed using LAPACK routines _syevd,
+    _heevd
+
+    The eigenvalues of real symmetric or complex Hermitian matrices are
+    always real. [1]_ The array `v` of (column) eigenvectors is unitary
+    and `a`, `w`, and `v` satisfy the equations
+    ``dot(a, v[:, i]) = w[i] * v[:, i]``.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pg. 222.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, -2j], [2j, 5]])
+    >>> a
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> w, v = LA.eigh(a)
+    >>> w; v
+    array([ 0.17157288,  5.82842712])
+    array([[-0.92387953+0.j        , -0.38268343+0.j        ],
+           [ 0.00000000+0.38268343j,  0.00000000-0.92387953j]])
+
+    >>> np.dot(a, v[:, 0]) - w[0] * v[:, 0] # verify 1st e-val/vec pair
+    array([2.77555756e-17 + 0.j, 0. + 1.38777878e-16j])
+    >>> np.dot(a, v[:, 1]) - w[1] * v[:, 1] # verify 2nd e-val/vec pair
+    array([ 0.+0.j,  0.+0.j])
+
+    >>> A = np.matrix(a) # what happens if input is a matrix object
+    >>> A
+    matrix([[ 1.+0.j,  0.-2.j],
+            [ 0.+2.j,  5.+0.j]])
+    >>> w, v = LA.eigh(A)
+    >>> w; v
+    array([ 0.17157288,  5.82842712])
+    matrix([[-0.92387953+0.j        , -0.38268343+0.j        ],
+            [ 0.00000000+0.38268343j,  0.00000000-0.92387953j]])
+
+    """
+    UPLO = UPLO.upper()
+    if UPLO not in ('L', 'U'):
+        raise ValueError("UPLO argument must be 'L' or 'U'")
+
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    if UPLO == 'L':
+        gufunc = _umath_linalg.eigh_lo
+    else:
+        gufunc = _umath_linalg.eigh_up
+
+    signature = 'D->dD' if isComplexType(t) else 'd->dd'
+    w, vt = gufunc(a, signature=signature, extobj=extobj)
+    w = w.astype(_realType(result_t), copy=False)
+    vt = vt.astype(result_t, copy=False)
+    return w, wrap(vt)
+
+
+# Singular value decomposition
+
+def svd(a, full_matrices=1, compute_uv=1):
+    """
+    Singular Value Decomposition.
+
+    Factors the matrix `a` as ``u * np.diag(s) * v``, where `u` and `v`
+    are unitary and `s` is a 1-d array of `a`'s singular values.
+
+    Parameters
+    ----------
+    a : (..., M, N) array_like
+        A real or complex matrix of shape (`M`, `N`) .
+    full_matrices : bool, optional
+        If True (default), `u` and `v` have the shapes (`M`, `M`) and
+        (`N`, `N`), respectively.  Otherwise, the shapes are (`M`, `K`)
+        and (`K`, `N`), respectively, where `K` = min(`M`, `N`).
+    compute_uv : bool, optional
+        Whether or not to compute `u` and `v` in addition to `s`.  True
+        by default.
+
+    Returns
+    -------
+    u : { (..., M, M), (..., M, K) } array
+        Unitary matrices. The actual shape depends on the value of
+        ``full_matrices``. Only returned when ``compute_uv`` is True.
+    s : (..., K) array
+        The singular values for every matrix, sorted in descending order.
+    v : { (..., N, N), (..., K, N) } array
+        Unitary matrices. The actual shape depends on the value of
+        ``full_matrices``. Only returned when ``compute_uv`` is True.
+
+    Raises
+    ------
+    LinAlgError
+        If SVD computation does not converge.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The decomposition is performed using LAPACK routine _gesdd
+
+    The SVD is commonly written as ``a = U S V.H``.  The `v` returned
+    by this function is ``V.H`` and ``u = U``.
+
+    If ``U`` is a unitary matrix, it means that it
+    satisfies ``U.H = inv(U)``.
+
+    The rows of `v` are the eigenvectors of ``a.H a``. The columns
+    of `u` are the eigenvectors of ``a a.H``.  For row ``i`` in
+    `v` and column ``i`` in `u`, the corresponding eigenvalue is
+    ``s[i]**2``.
+
+    If `a` is a `matrix` object (as opposed to an `ndarray`), then so
+    are all the return values.
+
+    Examples
+    --------
+    >>> a = np.random.randn(9, 6) + 1j*np.random.randn(9, 6)
+
+    Reconstruction based on full SVD:
+
+    >>> U, s, V = np.linalg.svd(a, full_matrices=True)
+    >>> U.shape, V.shape, s.shape
+    ((9, 9), (6, 6), (6,))
+    >>> S = np.zeros((9, 6), dtype=complex)
+    >>> S[:6, :6] = np.diag(s)
+    >>> np.allclose(a, np.dot(U, np.dot(S, V)))
+    True
+
+    Reconstruction based on reduced SVD:
+
+    >>> U, s, V = np.linalg.svd(a, full_matrices=False)
+    >>> U.shape, V.shape, s.shape
+    ((9, 6), (6, 6), (6,))
+    >>> S = np.diag(s)
+    >>> np.allclose(a, np.dot(U, np.dot(S, V)))
+    True
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(_raise_linalgerror_svd_nonconvergence)
+
+    m = a.shape[-2]
+    n = a.shape[-1]
+    if compute_uv:
+        if full_matrices:
+            if m < n:
+                gufunc = _umath_linalg.svd_m_f
+            else:
+                gufunc = _umath_linalg.svd_n_f
+        else:
+            if m < n:
+                gufunc = _umath_linalg.svd_m_s
+            else:
+                gufunc = _umath_linalg.svd_n_s
+
+        signature = 'D->DdD' if isComplexType(t) else 'd->ddd'
+        u, s, vt = gufunc(a, signature=signature, extobj=extobj)
+        u = u.astype(result_t, copy=False)
+        s = s.astype(_realType(result_t), copy=False)
+        vt = vt.astype(result_t, copy=False)
+        return wrap(u), s, wrap(vt)
+    else:
+        if m < n:
+            gufunc = _umath_linalg.svd_m
+        else:
+            gufunc = _umath_linalg.svd_n
+
+        signature = 'D->d' if isComplexType(t) else 'd->d'
+        s = gufunc(a, signature=signature, extobj=extobj)
+        s = s.astype(_realType(result_t), copy=False)
+        return s
+
+def cond(x, p=None):
+    """
+    Compute the condition number of a matrix.
+
+    This function is capable of returning the condition number using
+    one of seven different norms, depending on the value of `p` (see
+    Parameters below).
+
+    Parameters
+    ----------
+    x : (..., M, N) array_like
+        The matrix whose condition number is sought.
+    p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional
+        Order of the norm:
+
+        =====  ============================
+        p      norm for matrices
+        =====  ============================
+        None   2-norm, computed directly using the ``SVD``
+        'fro'  Frobenius norm
+        inf    max(sum(abs(x), axis=1))
+        -inf   min(sum(abs(x), axis=1))
+        1      max(sum(abs(x), axis=0))
+        -1     min(sum(abs(x), axis=0))
+        2      2-norm (largest sing. value)
+        -2     smallest singular value
+        =====  ============================
+
+        inf means the numpy.inf object, and the Frobenius norm is
+        the root-of-sum-of-squares norm.
+
+    Returns
+    -------
+    c : {float, inf}
+        The condition number of the matrix. May be infinite.
+
+    See Also
+    --------
+    numpy.linalg.norm
+
+    Notes
+    -----
+    The condition number of `x` is defined as the norm of `x` times the
+    norm of the inverse of `x` [1]_; the norm can be the usual L2-norm
+    (root-of-sum-of-squares) or one of a number of other matrix norms.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL,
+           Academic Press, Inc., 1980, pg. 285.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]])
+    >>> a
+    array([[ 1,  0, -1],
+           [ 0,  1,  0],
+           [ 1,  0,  1]])
+    >>> LA.cond(a)
+    1.4142135623730951
+    >>> LA.cond(a, 'fro')
+    3.1622776601683795
+    >>> LA.cond(a, np.inf)
+    2.0
+    >>> LA.cond(a, -np.inf)
+    1.0
+    >>> LA.cond(a, 1)
+    2.0
+    >>> LA.cond(a, -1)
+    1.0
+    >>> LA.cond(a, 2)
+    1.4142135623730951
+    >>> LA.cond(a, -2)
+    0.70710678118654746
+    >>> min(LA.svd(a, compute_uv=0))*min(LA.svd(LA.inv(a), compute_uv=0))
+    0.70710678118654746
+
+    """
+    x = asarray(x)  # in case we have a matrix
+    if p is None:
+        s = svd(x, compute_uv=False)
+        return s[..., 0]/s[..., -1]
+    else:
+        return norm(x, p, axis=(-2, -1)) * norm(inv(x), p, axis=(-2, -1))
+
+
+def matrix_rank(M, tol=None):
+    """
+    Return matrix rank of array using SVD method
+
+    Rank of the array is the number of SVD singular values of the array that are
+    greater than `tol`.
+
+    Parameters
+    ----------
+    M : {(M,), (M, N)} array_like
+        array of <=2 dimensions
+    tol : {None, float}, optional
+       threshold below which SVD values are considered zero. If `tol` is
+       None, and ``S`` is an array with singular values for `M`, and
+       ``eps`` is the epsilon value for datatype of ``S``, then `tol` is
+       set to ``S.max() * max(M.shape) * eps``.
+
+    Notes
+    -----
+    The default threshold to detect rank deficiency is a test on the magnitude
+    of the singular values of `M`.  By default, we identify singular values less
+    than ``S.max() * max(M.shape) * eps`` as indicating rank deficiency (with
+    the symbols defined above). This is the algorithm MATLAB uses [1].  It also
+    appears in *Numerical recipes* in the discussion of SVD solutions for linear
+    least squares [2].
+
+    This default threshold is designed to detect rank deficiency accounting for
+    the numerical errors of the SVD computation.  Imagine that there is a column
+    in `M` that is an exact (in floating point) linear combination of other
+    columns in `M`. Computing the SVD on `M` will not produce a singular value
+    exactly equal to 0 in general: any difference of the smallest SVD value from
+    0 will be caused by numerical imprecision in the calculation of the SVD.
+    Our threshold for small SVD values takes this numerical imprecision into
+    account, and the default threshold will detect such numerical rank
+    deficiency.  The threshold may declare a matrix `M` rank deficient even if
+    the linear combination of some columns of `M` is not exactly equal to
+    another column of `M` but only numerically very close to another column of
+    `M`.
+
+    We chose our default threshold because it is in wide use.  Other thresholds
+    are possible.  For example, elsewhere in the 2007 edition of *Numerical
+    recipes* there is an alternative threshold of ``S.max() *
+    np.finfo(M.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
+    this threshold as being based on "expected roundoff error" (p 71).
+
+    The thresholds above deal with floating point roundoff error in the
+    calculation of the SVD.  However, you may have more information about the
+    sources of error in `M` that would make you consider other tolerance values
+    to detect *effective* rank deficiency.  The most useful measure of the
+    tolerance depends on the operations you intend to use on your matrix.  For
+    example, if your data come from uncertain measurements with uncertainties
+    greater than floating point epsilon, choosing a tolerance near that
+    uncertainty may be preferable.  The tolerance may be absolute if the
+    uncertainties are absolute rather than relative.
+
+    References
+    ----------
+    .. [1] MATLAB reference documention, "Rank"
+           http://www.mathworks.com/help/techdoc/ref/rank.html
+    .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery,
+           "Numerical Recipes (3rd edition)", Cambridge University Press, 2007,
+           page 795.
+
+    Examples
+    --------
+    >>> from numpy.linalg import matrix_rank
+    >>> matrix_rank(np.eye(4)) # Full rank matrix
+    4
+    >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
+    >>> matrix_rank(I)
+    3
+    >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
+    1
+    >>> matrix_rank(np.zeros((4,)))
+    0
+    """
+    M = asarray(M)
+    if M.ndim > 2:
+        raise TypeError('array should have 2 or fewer dimensions')
+    if M.ndim < 2:
+        return int(not all(M==0))
+    S = svd(M, compute_uv=False)
+    if tol is None:
+        tol = S.max() * max(M.shape) * finfo(S.dtype).eps
+    return sum(S > tol)
+
+
+# Generalized inverse
+
+def pinv(a, rcond=1e-15 ):
+    """
+    Compute the (Moore-Penrose) pseudo-inverse of a matrix.
+
+    Calculate the generalized inverse of a matrix using its
+    singular-value decomposition (SVD) and including all
+    *large* singular values.
+
+    Parameters
+    ----------
+    a : (M, N) array_like
+      Matrix to be pseudo-inverted.
+    rcond : float
+      Cutoff for small singular values.
+      Singular values smaller (in modulus) than
+      `rcond` * largest_singular_value (again, in modulus)
+      are set to zero.
+
+    Returns
+    -------
+    B : (N, M) ndarray
+      The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so
+      is `B`.
+
+    Raises
+    ------
+    LinAlgError
+      If the SVD computation does not converge.
+
+    Notes
+    -----
+    The pseudo-inverse of a matrix A, denoted :math:`A^+`, is
+    defined as: "the matrix that 'solves' [the least-squares problem]
+    :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then
+    :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`.
+
+    It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular
+    value decomposition of A, then
+    :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are
+    orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting
+    of A's so-called singular values, (followed, typically, by
+    zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix
+    consisting of the reciprocals of A's singular values
+    (again, followed by zeros). [1]_
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pp. 139-142.
+
+    Examples
+    --------
+    The following example checks that ``a * a+ * a == a`` and
+    ``a+ * a * a+ == a+``:
+
+    >>> a = np.random.randn(9, 6)
+    >>> B = np.linalg.pinv(a)
+    >>> np.allclose(a, np.dot(a, np.dot(B, a)))
+    True
+    >>> np.allclose(B, np.dot(B, np.dot(a, B)))
+    True
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    a = a.conjugate()
+    u, s, vt = svd(a, 0)
+    m = u.shape[0]
+    n = vt.shape[1]
+    cutoff = rcond*maximum.reduce(s)
+    for i in range(min(n, m)):
+        if s[i] > cutoff:
+            s[i] = 1./s[i]
+        else:
+            s[i] = 0.
+    res = dot(transpose(vt), multiply(s[:, newaxis], transpose(u)))
+    return wrap(res)
+
+# Determinant
+
+def slogdet(a):
+    """
+    Compute the sign and (natural) logarithm of the determinant of an array.
+
+    If an array has a very small or very large determinant, then a call to
+    `det` may overflow or underflow. This routine is more robust against such
+    issues, because it computes the logarithm of the determinant rather than
+    the determinant itself.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Input array, has to be a square 2-D array.
+
+    Returns
+    -------
+    sign : (...) array_like
+        A number representing the sign of the determinant. For a real matrix,
+        this is 1, 0, or -1. For a complex matrix, this is a complex number
+        with absolute value 1 (i.e., it is on the unit circle), or else 0.
+    logdet : (...) array_like
+        The natural log of the absolute value of the determinant.
+
+    If the determinant is zero, then `sign` will be 0 and `logdet` will be
+    -Inf. In all cases, the determinant is equal to ``sign * np.exp(logdet)``.
+
+    See Also
+    --------
+    det
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    .. versionadded:: 1.6.0.
+
+    The determinant is computed via LU factorization using the LAPACK
+    routine z/dgetrf.
+
+
+    Examples
+    --------
+    The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``:
+
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> (sign, logdet) = np.linalg.slogdet(a)
+    >>> (sign, logdet)
+    (-1, 0.69314718055994529)
+    >>> sign * np.exp(logdet)
+    -2.0
+
+    Computing log-determinants for a stack of matrices:
+
+    >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
+    >>> a.shape
+    (3, 2, 2)
+    >>> sign, logdet = np.linalg.slogdet(a)
+    >>> (sign, logdet)
+    (array([-1., -1., -1.]), array([ 0.69314718,  1.09861229,  2.07944154]))
+    >>> sign * np.exp(logdet)
+    array([-2., -3., -8.])
+
+    This routine succeeds where ordinary `det` does not:
+
+    >>> np.linalg.det(np.eye(500) * 0.1)
+    0.0
+    >>> np.linalg.slogdet(np.eye(500) * 0.1)
+    (1, -1151.2925464970228)
+
+    """
+    a = asarray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    real_t = _realType(result_t)
+    signature = 'D->Dd' if isComplexType(t) else 'd->dd'
+    sign, logdet = _umath_linalg.slogdet(a, signature=signature)
+    if isscalar(sign):
+        sign = sign.astype(result_t)
+    else:
+        sign = sign.astype(result_t, copy=False)
+    if isscalar(logdet):
+        logdet = logdet.astype(real_t)
+    else:
+        logdet = logdet.astype(real_t, copy=False)
+    return sign, logdet
+
+def det(a):
+    """
+    Compute the determinant of an array.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Input array to compute determinants for.
+
+    Returns
+    -------
+    det : (...) array_like
+        Determinant of `a`.
+
+    See Also
+    --------
+    slogdet : Another way to representing the determinant, more suitable
+      for large matrices where underflow/overflow may occur.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The determinant is computed via LU factorization using the LAPACK
+    routine z/dgetrf.
+
+    Examples
+    --------
+    The determinant of a 2-D array [[a, b], [c, d]] is ad - bc:
+
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.linalg.det(a)
+    -2.0
+
+    Computing determinants for a stack of matrices:
+
+    >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
+    >>> a.shape
+    (3, 2, 2)
+    >>> np.linalg.det(a)
+    array([-2., -3., -8.])
+
+    """
+    a = asarray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    r = _umath_linalg.det(a, signature=signature)
+    if isscalar(r):
+        r = r.astype(result_t)
+    else:
+        r = r.astype(result_t, copy=False)
+    return r
+
+# Linear Least Squares
+
+def lstsq(a, b, rcond=-1):
+    """
+    Return the least-squares solution to a linear matrix equation.
+
+    Solves the equation `a x = b` by computing a vector `x` that
+    minimizes the Euclidean 2-norm `|| b - a x ||^2`.  The equation may
+    be under-, well-, or over- determined (i.e., the number of
+    linearly independent rows of `a` can be less than, equal to, or
+    greater than its number of linearly independent columns).  If `a`
+    is square and of full rank, then `x` (but for round-off error) is
+    the "exact" solution of the equation.
+
+    Parameters
+    ----------
+    a : (M, N) array_like
+        "Coefficient" matrix.
+    b : {(M,), (M, K)} array_like
+        Ordinate or "dependent variable" values. If `b` is two-dimensional,
+        the least-squares solution is calculated for each of the `K` columns
+        of `b`.
+    rcond : float, optional
+        Cut-off ratio for small singular values of `a`.
+        Singular values are set to zero if they are smaller than `rcond`
+        times the largest singular value of `a`.
+
+    Returns
+    -------
+    x : {(N,), (N, K)} ndarray
+        Least-squares solution. If `b` is two-dimensional,
+        the solutions are in the `K` columns of `x`.
+    residuals : {(), (1,), (K,)} ndarray
+        Sums of residuals; squared Euclidean 2-norm for each column in
+        ``b - a*x``.
+        If the rank of `a` is < N or M <= N, this is an empty array.
+        If `b` is 1-dimensional, this is a (1,) shape array.
+        Otherwise the shape is (K,).
+    rank : int
+        Rank of matrix `a`.
+    s : (min(M, N),) ndarray
+        Singular values of `a`.
+
+    Raises
+    ------
+    LinAlgError
+        If computation does not converge.
+
+    Notes
+    -----
+    If `b` is a matrix, then all array results are returned as matrices.
+
+    Examples
+    --------
+    Fit a line, ``y = mx + c``, through some noisy data-points:
+
+    >>> x = np.array([0, 1, 2, 3])
+    >>> y = np.array([-1, 0.2, 0.9, 2.1])
+
+    By examining the coefficients, we see that the line should have a
+    gradient of roughly 1 and cut the y-axis at, more or less, -1.
+
+    We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]``
+    and ``p = [[m], [c]]``.  Now use `lstsq` to solve for `p`:
+
+    >>> A = np.vstack([x, np.ones(len(x))]).T
+    >>> A
+    array([[ 0.,  1.],
+           [ 1.,  1.],
+           [ 2.,  1.],
+           [ 3.,  1.]])
+
+    >>> m, c = np.linalg.lstsq(A, y)[0]
+    >>> print(m, c)
+    1.0 -0.95
+
+    Plot the data along with the fitted line:
+
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot(x, y, 'o', label='Original data', markersize=10)
+    >>> plt.plot(x, m*x + c, 'r', label='Fitted line')
+    >>> plt.legend()
+    >>> plt.show()
+
+    """
+    import math
+    a, _ = _makearray(a)
+    b, wrap = _makearray(b)
+    is_1d = len(b.shape) == 1
+    if is_1d:
+        b = b[:, newaxis]
+    _assertRank2(a, b)
+    m  = a.shape[0]
+    n  = a.shape[1]
+    n_rhs = b.shape[1]
+    ldb = max(n, m)
+    if m != b.shape[0]:
+        raise LinAlgError('Incompatible dimensions')
+    t, result_t = _commonType(a, b)
+    result_real_t = _realType(result_t)
+    real_t = _linalgRealType(t)
+    bstar = zeros((ldb, n_rhs), t)
+    bstar[:b.shape[0], :n_rhs] = b.copy()
+    a, bstar = _fastCopyAndTranspose(t, a, bstar)
+    a, bstar = _to_native_byte_order(a, bstar)
+    s = zeros((min(m, n),), real_t)
+    nlvl = max( 0, int( math.log( float(min(m, n))/2. ) ) + 1 )
+    iwork = zeros((3*min(m, n)*nlvl+11*min(m, n),), fortran_int)
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zgelsd
+        lwork = 1
+        rwork = zeros((lwork,), real_t)
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, -1, rwork, iwork, 0)
+        lwork = int(abs(work[0]))
+        rwork = zeros((lwork,), real_t)
+        a_real = zeros((m, n), real_t)
+        bstar_real = zeros((ldb, n_rhs,), real_t)
+        results = lapack_lite.dgelsd(m, n, n_rhs, a_real, m,
+                                     bstar_real, ldb, s, rcond,
+                                     0, rwork, -1, iwork, 0)
+        lrwork = int(rwork[0])
+        work = zeros((lwork,), t)
+        rwork = zeros((lrwork,), real_t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, lwork, rwork, iwork, 0)
+    else:
+        lapack_routine = lapack_lite.dgelsd
+        lwork = 1
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, -1, iwork, 0)
+        lwork = int(work[0])
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, lwork, iwork, 0)
+    if results['info'] > 0:
+        raise LinAlgError('SVD did not converge in Linear Least Squares')
+    resids = array([], result_real_t)
+    if is_1d:
+        x = array(ravel(bstar)[:n], dtype=result_t, copy=True)
+        if results['rank'] == n and m > n:
+            if isComplexType(t):
+                resids = array([sum(abs(ravel(bstar)[n:])**2)],
+                               dtype=result_real_t)
+            else:
+                resids = array([sum((ravel(bstar)[n:])**2)],
+                               dtype=result_real_t)
+    else:
+        x = array(transpose(bstar)[:n,:], dtype=result_t, copy=True)
+        if results['rank'] == n and m > n:
+            if isComplexType(t):
+                resids = sum(abs(transpose(bstar)[n:,:])**2, axis=0).astype(
+                    result_real_t, copy=False)
+            else:
+                resids = sum((transpose(bstar)[n:,:])**2, axis=0).astype(
+                    result_real_t, copy=False)
+
+    st = s[:min(n, m)].astype(result_real_t, copy=True)
+    return wrap(x), wrap(resids), results['rank'], st
+
+
+def _multi_svd_norm(x, row_axis, col_axis, op):
+    """Compute a function of the singular values of the 2-D matrices in `x`.
+
+    This is a private utility function used by numpy.linalg.norm().
+
+    Parameters
+    ----------
+    x : ndarray
+    row_axis, col_axis : int
+        The axes of `x` that hold the 2-D matrices.
+    op : callable
+        This should be either numpy.amin or numpy.amax or numpy.sum.
+
+    Returns
+    -------
+    result : float or ndarray
+        If `x` is 2-D, the return values is a float.
+        Otherwise, it is an array with ``x.ndim - 2`` dimensions.
+        The return values are either the minimum or maximum or sum of the
+        singular values of the matrices, depending on whether `op`
+        is `numpy.amin` or `numpy.amax` or `numpy.sum`.
+
+    """
+    if row_axis > col_axis:
+        row_axis -= 1
+    y = rollaxis(rollaxis(x, col_axis, x.ndim), row_axis, -1)
+    result = op(svd(y, compute_uv=0), axis=-1)
+    return result
+
+
+def norm(x, ord=None, axis=None, keepdims=False):
+    """
+    Matrix or vector norm.
+
+    This function is able to return one of eight different matrix norms,
+    or one of an infinite number of vector norms (described below), depending
+    on the value of the ``ord`` parameter.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.  If `axis` is None, `x` must be 1-D or 2-D.
+    ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional
+        Order of the norm (see table under ``Notes``). inf means numpy's
+        `inf` object.
+    axis : {int, 2-tuple of ints, None}, optional
+        If `axis` is an integer, it specifies the axis of `x` along which to
+        compute the vector norms.  If `axis` is a 2-tuple, it specifies the
+        axes that hold 2-D matrices, and the matrix norms of these matrices
+        are computed.  If `axis` is None then either a vector norm (when `x`
+        is 1-D) or a matrix norm (when `x` is 2-D) is returned.
+    keepdims : bool, optional
+        If this is set to True, the axes which are normed over are left in the
+        result as dimensions with size one.  With this option the result will
+        broadcast correctly against the original `x`.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    n : float or ndarray
+        Norm of the matrix or vector(s).
+
+    Notes
+    -----
+    For values of ``ord <= 0``, the result is, strictly speaking, not a
+    mathematical 'norm', but it may still be useful for various numerical
+    purposes.
+
+    The following norms can be calculated:
+
+    =====  ============================  ==========================
+    ord    norm for matrices             norm for vectors
+    =====  ============================  ==========================
+    None   Frobenius norm                2-norm
+    'fro'  Frobenius norm                --
+    'nuc'  nuclear norm                  --
+    inf    max(sum(abs(x), axis=1))      max(abs(x))
+    -inf   min(sum(abs(x), axis=1))      min(abs(x))
+    0      --                            sum(x != 0)
+    1      max(sum(abs(x), axis=0))      as below
+    -1     min(sum(abs(x), axis=0))      as below
+    2      2-norm (largest sing. value)  as below
+    -2     smallest singular value       as below
+    other  --                            sum(abs(x)**ord)**(1./ord)
+    =====  ============================  ==========================
+
+    The Frobenius norm is given by [1]_:
+
+        :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`
+
+    The nuclear norm is the sum of the singular values.
+
+    References
+    ----------
+    .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
+           Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.arange(9) - 4
+    >>> a
+    array([-4, -3, -2, -1,  0,  1,  2,  3,  4])
+    >>> b = a.reshape((3, 3))
+    >>> b
+    array([[-4, -3, -2],
+           [-1,  0,  1],
+           [ 2,  3,  4]])
+
+    >>> LA.norm(a)
+    7.745966692414834
+    >>> LA.norm(b)
+    7.745966692414834
+    >>> LA.norm(b, 'fro')
+    7.745966692414834
+    >>> LA.norm(a, np.inf)
+    4.0
+    >>> LA.norm(b, np.inf)
+    9.0
+    >>> LA.norm(a, -np.inf)
+    0.0
+    >>> LA.norm(b, -np.inf)
+    2.0
+
+    >>> LA.norm(a, 1)
+    20.0
+    >>> LA.norm(b, 1)
+    7.0
+    >>> LA.norm(a, -1)
+    -4.6566128774142013e-010
+    >>> LA.norm(b, -1)
+    6.0
+    >>> LA.norm(a, 2)
+    7.745966692414834
+    >>> LA.norm(b, 2)
+    7.3484692283495345
+
+    >>> LA.norm(a, -2)
+    nan
+    >>> LA.norm(b, -2)
+    1.8570331885190563e-016
+    >>> LA.norm(a, 3)
+    5.8480354764257312
+    >>> LA.norm(a, -3)
+    nan
+
+    Using the `axis` argument to compute vector norms:
+
+    >>> c = np.array([[ 1, 2, 3],
+    ...               [-1, 1, 4]])
+    >>> LA.norm(c, axis=0)
+    array([ 1.41421356,  2.23606798,  5.        ])
+    >>> LA.norm(c, axis=1)
+    array([ 3.74165739,  4.24264069])
+    >>> LA.norm(c, ord=1, axis=1)
+    array([ 6.,  6.])
+
+    Using the `axis` argument to compute matrix norms:
+
+    >>> m = np.arange(8).reshape(2,2,2)
+    >>> LA.norm(m, axis=(1,2))
+    array([  3.74165739,  11.22497216])
+    >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :])
+    (3.7416573867739413, 11.224972160321824)
+
+    """
+    x = asarray(x)
+
+    if not issubclass(x.dtype.type, inexact):
+        x = x.astype(float)
+
+    # Immediately handle some default, simple, fast, and common cases.
+    if axis is None:
+        ndim = x.ndim
+        if ((ord is None) or
+            (ord in ('f', 'fro') and ndim == 2) or
+            (ord == 2 and ndim == 1)):
+
+            x = x.ravel(order='K')
+            if isComplexType(x.dtype.type):
+                sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag)
+            else:
+                sqnorm = dot(x, x)
+            ret = sqrt(sqnorm)
+            if keepdims:
+                ret = ret.reshape(ndim*[1])
+            return ret
+
+    # Normalize the `axis` argument to a tuple.
+    nd = x.ndim
+    if axis is None:
+        axis = tuple(range(nd))
+    elif not isinstance(axis, tuple):
+        try:
+            axis = int(axis)
+        except:
+            raise TypeError("'axis' must be None, an integer or a tuple of integers")
+        axis = (axis,)
+
+    if len(axis) == 1:
+        if ord == Inf:
+            return abs(x).max(axis=axis, keepdims=keepdims)
+        elif ord == -Inf:
+            return abs(x).min(axis=axis, keepdims=keepdims)
+        elif ord == 0:
+            # Zero norm
+            return (x != 0).astype(float).sum(axis=axis, keepdims=keepdims)
+        elif ord == 1:
+            # special case for speedup
+            return add.reduce(abs(x), axis=axis, keepdims=keepdims)
+        elif ord is None or ord == 2:
+            # special case for speedup
+            s = (x.conj() * x).real
+            return sqrt(add.reduce(s, axis=axis, keepdims=keepdims))
+        else:
+            try:
+                ord + 1
+            except TypeError:
+                raise ValueError("Invalid norm order for vectors.")
+            if x.dtype.type is longdouble:
+                # Convert to a float type, so integer arrays give
+                # float results.  Don't apply asfarray to longdouble arrays,
+                # because it will downcast to float64.
+                absx = abs(x)
+            else:
+                absx = x if isComplexType(x.dtype.type) else asfarray(x)
+                if absx.dtype is x.dtype:
+                    absx = abs(absx)
+                else:
+                    # if the type changed, we can safely overwrite absx
+                    abs(absx, out=absx)
+            absx **= ord
+            return add.reduce(absx, axis=axis, keepdims=keepdims) ** (1.0 / ord)
+    elif len(axis) == 2:
+        row_axis, col_axis = axis
+        if row_axis < 0:
+            row_axis += nd
+        if col_axis < 0:
+            col_axis += nd
+        if not (0 <= row_axis < nd and 0 <= col_axis < nd):
+            raise ValueError('Invalid axis %r for an array with shape %r' %
+                             (axis, x.shape))
+        if row_axis == col_axis:
+            raise ValueError('Duplicate axes given.')
+        if ord == 2:
+            ret =  _multi_svd_norm(x, row_axis, col_axis, amax)
+        elif ord == -2:
+            ret = _multi_svd_norm(x, row_axis, col_axis, amin)
+        elif ord == 1:
+            if col_axis > row_axis:
+                col_axis -= 1
+            ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis)
+        elif ord == Inf:
+            if row_axis > col_axis:
+                row_axis -= 1
+            ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis)
+        elif ord == -1:
+            if col_axis > row_axis:
+                col_axis -= 1
+            ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis)
+        elif ord == -Inf:
+            if row_axis > col_axis:
+                row_axis -= 1
+            ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis)
+        elif ord in [None, 'fro', 'f']:
+            ret = sqrt(add.reduce((x.conj() * x).real, axis=axis))
+        elif ord == 'nuc':
+            ret = _multi_svd_norm(x, row_axis, col_axis, sum)
+        else:
+            raise ValueError("Invalid norm order for matrices.")
+        if keepdims:
+            ret_shape = list(x.shape)
+            ret_shape[axis[0]] = 1
+            ret_shape[axis[1]] = 1
+            ret = ret.reshape(ret_shape)
+        return ret
+    else:
+        raise ValueError("Improper number of dimensions to norm.")
+
+
+# multi_dot
+
+def multi_dot(arrays):
+    """
+    Compute the dot product of two or more arrays in a single function call,
+    while automatically selecting the fastest evaluation order.
+
+    `multi_dot` chains `numpy.dot` and uses optimal parenthesization
+    of the matrices [1]_ [2]_. Depending on the shapes of the matrices,
+    this can speed up the multiplication a lot.
+
+    If the first argument is 1-D it is treated as a row vector.
+    If the last argument is 1-D it is treated as a column vector.
+    The other arguments must be 2-D.
+
+    Think of `multi_dot` as::
+
+        def multi_dot(arrays): return functools.reduce(np.dot, arrays)
+
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        If the first argument is 1-D it is treated as row vector.
+        If the last argument is 1-D it is treated as column vector.
+        The other arguments must be 2-D.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of the supplied arrays.
+
+    See Also
+    --------
+    dot : dot multiplication with two arguments.
+
+    References
+    ----------
+
+    .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378
+    .. [2] http://en.wikipedia.org/wiki/Matrix_chain_multiplication
+
+    Examples
+    --------
+    `multi_dot` allows you to write::
+
+    >>> from numpy.linalg import multi_dot
+    >>> # Prepare some data
+    >>> A = np.random.random(10000, 100)
+    >>> B = np.random.random(100, 1000)
+    >>> C = np.random.random(1000, 5)
+    >>> D = np.random.random(5, 333)
+    >>> # the actual dot multiplication
+    >>> multi_dot([A, B, C, D])
+
+    instead of::
+
+    >>> np.dot(np.dot(np.dot(A, B), C), D)
+    >>> # or
+    >>> A.dot(B).dot(C).dot(D)
+
+
+    Example: multiplication costs of different parenthesizations
+    ------------------------------------------------------------
+
+    The cost for a matrix multiplication can be calculated with the
+    following function::
+
+        def cost(A, B): return A.shape[0] * A.shape[1] * B.shape[1]
+
+    Let's assume we have three matrices
+    :math:`A_{10x100}, B_{100x5}, C_{5x50}$`.
+
+    The costs for the two different parenthesizations are as follows::
+
+        cost((AB)C) = 10*100*5 + 10*5*50   = 5000 + 2500   = 7500
+        cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000
+
+    """
+    n = len(arrays)
+    # optimization only makes sense for len(arrays) > 2
+    if n < 2:
+        raise ValueError("Expecting at least two arrays.")
+    elif n == 2:
+        return dot(arrays[0], arrays[1])
+
+    arrays = [asanyarray(a) for a in arrays]
+
+    # save original ndim to reshape the result array into the proper form later
+    ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim
+    # Explicitly convert vectors to 2D arrays to keep the logic of the internal
+    # _multi_dot_* functions as simple as possible.
+    if arrays[0].ndim == 1:
+        arrays[0] = atleast_2d(arrays[0])
+    if arrays[-1].ndim == 1:
+        arrays[-1] = atleast_2d(arrays[-1]).T
+    _assertRank2(*arrays)
+
+    # _multi_dot_three is much faster than _multi_dot_matrix_chain_order
+    if n == 3:
+        result = _multi_dot_three(arrays[0], arrays[1], arrays[2])
+    else:
+        order = _multi_dot_matrix_chain_order(arrays)
+        result = _multi_dot(arrays, order, 0, n - 1)
+
+    # return proper shape
+    if ndim_first == 1 and ndim_last == 1:
+        return result[0, 0]  # scalar
+    elif ndim_first == 1 or ndim_last == 1:
+        return result.ravel()  # 1-D
+    else:
+        return result
+
+
+def _multi_dot_three(A, B, C):
+    """
+    Find the best order for three arrays and do the multiplication.
+
+    For three arguments `_multi_dot_three` is approximately 15 times faster
+    than `_multi_dot_matrix_chain_order`
+
+    """
+    # cost1 = cost((AB)C)
+    cost1 = (A.shape[0] * A.shape[1] * B.shape[1] +  # (AB)
+             A.shape[0] * B.shape[1] * C.shape[1])   # (--)C
+    # cost2 = cost((AB)C)
+    cost2 = (B.shape[0] * B.shape[1] * C.shape[1] +  #  (BC)
+             A.shape[0] * A.shape[1] * C.shape[1])   # A(--)
+
+    if cost1 < cost2:
+        return dot(dot(A, B), C)
+    else:
+        return dot(A, dot(B, C))
+
+
+def _multi_dot_matrix_chain_order(arrays, return_costs=False):
+    """
+    Return a np.array that encodes the optimal order of mutiplications.
+
+    The optimal order array is then used by `_multi_dot()` to do the
+    multiplication.
+
+    Also return the cost matrix if `return_costs` is `True`
+
+    The implementation CLOSELY follows Cormen, "Introduction to Algorithms",
+    Chapter 15.2, p. 370-378.  Note that Cormen uses 1-based indices.
+
+        cost[i, j] = min([
+            cost[prefix] + cost[suffix] + cost_mult(prefix, suffix)
+            for k in range(i, j)])
+
+    """
+    n = len(arrays)
+    # p stores the dimensions of the matrices
+    # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50]
+    p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]]
+    # m is a matrix of costs of the subproblems
+    # m[i,j]: min number of scalar multiplications needed to compute A_{i..j}
+    m = zeros((n, n), dtype=double)
+    # s is the actual ordering
+    # s[i, j] is the value of k at which we split the product A_i..A_j
+    s = empty((n, n), dtype=intp)
+
+    for l in range(1, n):
+        for i in range(n - l):
+            j = i + l
+            m[i, j] = Inf
+            for k in range(i, j):
+                q = m[i, k] + m[k+1, j] + p[i]*p[k+1]*p[j+1]
+                if q < m[i, j]:
+                    m[i, j] = q
+                    s[i, j] = k  # Note that Cormen uses 1-based index
+
+    return (s, m) if return_costs else s
+
+
+def _multi_dot(arrays, order, i, j):
+    """Actually do the multiplication with the given order."""
+    if i == j:
+        return arrays[i]
+    else:
+        return dot(_multi_dot(arrays, order, i, order[i, j]),
+                   _multi_dot(arrays, order, order[i, j] + 1, j))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/setup.py
new file mode 100644
index 0000000000..adc8f17848
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/setup.py
@@ -0,0 +1,57 @@
+from __future__ import division, print_function
+
+import os
+import sys
+
+def configuration(parent_package='', top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    from numpy.distutils.system_info import get_info
+    config = Configuration('linalg', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    # Configure lapack_lite
+
+    src_dir = 'lapack_lite'
+    lapack_lite_src = [
+        os.path.join(src_dir, 'python_xerbla.c'),
+        os.path.join(src_dir, 'zlapack_lite.c'),
+        os.path.join(src_dir, 'dlapack_lite.c'),
+        os.path.join(src_dir, 'blas_lite.c'),
+        os.path.join(src_dir, 'dlamch.c'),
+        os.path.join(src_dir, 'f2c_lite.c'),
+    ]
+    all_sources = config.paths(lapack_lite_src)
+
+    lapack_info = get_info('lapack_opt', 0)  # and {}
+
+    def get_lapack_lite_sources(ext, build_dir):
+        if not lapack_info:
+            print("### Warning:  Using unoptimized lapack ###")
+            return all_sources
+        else:
+            if sys.platform == 'win32':
+                print("### Warning:  python_xerbla.c is disabled ###")
+                return []
+            return [all_sources[0]]
+
+    config.add_extension(
+        'lapack_lite',
+        sources=['lapack_litemodule.c', get_lapack_lite_sources],
+        depends=['lapack_lite/f2c.h'],
+        extra_info=lapack_info,
+    )
+
+    # umath_linalg module
+    config.add_extension(
+        '_umath_linalg',
+        sources=['umath_linalg.c.src', get_lapack_lite_sources],
+        depends=['lapack_lite/f2c.h'],
+        extra_info=lapack_info,
+        libraries=['npymath'],
+    )
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
new file mode 100644
index 0000000000..dfb154190b
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
@@ -0,0 +1,59 @@
+from __future__ import division, absolute_import, print_function
+
+from subprocess import PIPE, Popen
+import sys
+import re
+
+from numpy.linalg import lapack_lite
+from numpy.testing import TestCase, dec, run_module_suite
+
+from numpy.compat import asbytes_nested
+
+
+class FindDependenciesLdd(object):
+
+    def __init__(self):
+        self.cmd = ['ldd']
+
+        try:
+            p = Popen(self.cmd, stdout=PIPE, stderr=PIPE)
+            stdout, stderr = p.communicate()
+        except OSError:
+            raise RuntimeError("command %s cannot be run" % self.cmd)
+
+    def get_dependencies(self, lfile):
+        p = Popen(self.cmd + [lfile], stdout=PIPE, stderr=PIPE)
+        stdout, stderr = p.communicate()
+        if not (p.returncode == 0):
+            raise RuntimeError("failed dependencies check for %s" % lfile)
+
+        return stdout
+
+    def grep_dependencies(self, lfile, deps):
+        stdout = self.get_dependencies(lfile)
+
+        rdeps = dict([(dep, re.compile(dep)) for dep in deps])
+        founds = []
+        for l in stdout.splitlines():
+            for k, v in rdeps.items():
+                if v.search(l):
+                    founds.append(k)
+
+        return founds
+
+
+class TestF77Mismatch(TestCase):
+
+    @dec.skipif(not(sys.platform[:5] == 'linux'),
+                "Skipping fortran compiler mismatch on non Linux platform")
+    def test_lapack(self):
+        f = FindDependenciesLdd()
+        deps = f.grep_dependencies(lapack_lite.__file__,
+                                   asbytes_nested(['libg2c', 'libgfortran']))
+        self.assertFalse(len(deps) > 1,
+                         """Both g77 and gfortran runtimes linked in lapack_lite ! This is likely to
+cause random crashes and wrong results. See numpy INSTALL.txt for more
+information.""")
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
new file mode 100644
index 0000000000..9b6fe343f5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
@@ -0,0 +1,26 @@
+"""Test deprecation and future warnings.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_warns, run_module_suite
+
+
+def test_qr_mode_full_future_warning():
+    """Check mode='full' FutureWarning.
+
+    In numpy 1.8 the mode options 'full' and 'economic' in linalg.qr were
+    deprecated. The release date will probably be sometime in the summer
+    of 2013.
+
+    """
+    a = np.eye(2)
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='full')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='f')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='economic')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='e')
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
new file mode 100644
index 0000000000..60486d4cec
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
@@ -0,0 +1,1443 @@
+""" Test functions for linalg module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import itertools
+import traceback
+import warnings
+
+import numpy as np
+from numpy import array, single, double, csingle, cdouble, dot, identity
+from numpy import multiply, atleast_2d, inf, asarray, matrix
+from numpy import linalg
+from numpy.linalg import matrix_power, norm, matrix_rank, multi_dot
+from numpy.linalg.linalg import _multi_dot_matrix_chain_order
+from numpy.testing import (
+    assert_, assert_equal, assert_raises, assert_array_equal,
+    assert_almost_equal, assert_allclose, run_module_suite,
+    dec, SkipTest
+)
+
+
+def ifthen(a, b):
+    return not a or b
+
+
+def imply(a, b):
+    return not a or b
+
+
+old_assert_almost_equal = assert_almost_equal
+
+
+def assert_almost_equal(a, b, **kw):
+    if asarray(a).dtype.type in (single, csingle):
+        decimal = 6
+    else:
+        decimal = 12
+    old_assert_almost_equal(a, b, decimal=decimal, **kw)
+
+
+def get_real_dtype(dtype):
+    return {single: single, double: double,
+            csingle: single, cdouble: double}[dtype]
+
+
+def get_complex_dtype(dtype):
+    return {single: csingle, double: cdouble,
+            csingle: csingle, cdouble: cdouble}[dtype]
+
+
+def get_rtol(dtype):
+    # Choose a safe rtol
+    if dtype in (single, csingle):
+        return 1e-5
+    else:
+        return 1e-11
+
+
+class LinalgCase(object):
+
+    def __init__(self, name, a, b, exception_cls=None):
+        assert_(isinstance(name, str))
+        self.name = name
+        self.a = a
+        self.b = b
+        self.exception_cls = exception_cls
+
+    def check(self, do):
+        if self.exception_cls is None:
+            do(self.a, self.b)
+        else:
+            assert_raises(self.exception_cls, do, self.a, self.b)
+
+    def __repr__(self):
+        return "<LinalgCase: %s>" % (self.name,)
+
+
+#
+# Base test cases
+#
+
+np.random.seed(1234)
+
+SQUARE_CASES = [
+    LinalgCase("single",
+               array([[1., 2.], [3., 4.]], dtype=single),
+               array([2., 1.], dtype=single)),
+    LinalgCase("double",
+               array([[1., 2.], [3., 4.]], dtype=double),
+               array([2., 1.], dtype=double)),
+    LinalgCase("double_2",
+               array([[1., 2.], [3., 4.]], dtype=double),
+               array([[2., 1., 4.], [3., 4., 6.]], dtype=double)),
+    LinalgCase("csingle",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j], dtype=csingle)),
+    LinalgCase("cdouble",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j], dtype=cdouble)),
+    LinalgCase("cdouble_2",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j, 1 + 3j], [1 - 2j, 1 - 3j, 1 - 6j]], dtype=cdouble)),
+    LinalgCase("empty",
+               atleast_2d(array([], dtype=double)),
+               atleast_2d(array([], dtype=double)),
+               linalg.LinAlgError),
+    LinalgCase("8x8",
+               np.random.rand(8, 8),
+               np.random.rand(8)),
+    LinalgCase("1x1",
+               np.random.rand(1, 1),
+               np.random.rand(1)),
+    LinalgCase("nonarray",
+               [[1, 2], [3, 4]],
+               [2, 1]),
+    LinalgCase("matrix_b_only",
+               array([[1., 2.], [3., 4.]]),
+               matrix([2., 1.]).T),
+    LinalgCase("matrix_a_and_b",
+               matrix([[1., 2.], [3., 4.]]),
+               matrix([2., 1.]).T),
+]
+
+NONSQUARE_CASES = [
+    LinalgCase("single_nsq_1",
+               array([[1., 2., 3.], [3., 4., 6.]], dtype=single),
+               array([2., 1.], dtype=single)),
+    LinalgCase("single_nsq_2",
+               array([[1., 2.], [3., 4.], [5., 6.]], dtype=single),
+               array([2., 1., 3.], dtype=single)),
+    LinalgCase("double_nsq_1",
+               array([[1., 2., 3.], [3., 4., 6.]], dtype=double),
+               array([2., 1.], dtype=double)),
+    LinalgCase("double_nsq_2",
+               array([[1., 2.], [3., 4.], [5., 6.]], dtype=double),
+               array([2., 1., 3.], dtype=double)),
+    LinalgCase("csingle_nsq_1",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j], dtype=csingle)),
+    LinalgCase("csingle_nsq_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j, 3. - 3j], dtype=csingle)),
+    LinalgCase("cdouble_nsq_1",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j, 3. - 3j], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_1_2",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_2_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)),
+    LinalgCase("8x11",
+               np.random.rand(8, 11),
+               np.random.rand(11)),
+    LinalgCase("1x5",
+               np.random.rand(1, 5),
+               np.random.rand(5)),
+    LinalgCase("5x1",
+               np.random.rand(5, 1),
+               np.random.rand(1)),
+]
+
+HERMITIAN_CASES = [
+    LinalgCase("hsingle",
+               array([[1., 2.], [2., 1.]], dtype=single),
+               None),
+    LinalgCase("hdouble",
+               array([[1., 2.], [2., 1.]], dtype=double),
+               None),
+    LinalgCase("hcsingle",
+               array([[1., 2 + 3j], [2 - 3j, 1]], dtype=csingle),
+               None),
+    LinalgCase("hcdouble",
+               array([[1., 2 + 3j], [2 - 3j, 1]], dtype=cdouble),
+               None),
+    LinalgCase("hempty",
+               atleast_2d(array([], dtype=double)),
+               None,
+               linalg.LinAlgError),
+    LinalgCase("hnonarray",
+               [[1, 2], [2, 1]],
+               None),
+    LinalgCase("matrix_b_only",
+               array([[1., 2.], [2., 1.]]),
+               None),
+    LinalgCase("hmatrix_a_and_b",
+               matrix([[1., 2.], [2., 1.]]),
+               None),
+    LinalgCase("hmatrix_1x1",
+               np.random.rand(1, 1),
+               None),
+]
+
+
+#
+# Gufunc test cases
+#
+
+GENERALIZED_SQUARE_CASES = []
+GENERALIZED_NONSQUARE_CASES = []
+GENERALIZED_HERMITIAN_CASES = []
+
+for tgt, src in ((GENERALIZED_SQUARE_CASES, SQUARE_CASES),
+                 (GENERALIZED_NONSQUARE_CASES, NONSQUARE_CASES),
+                 (GENERALIZED_HERMITIAN_CASES, HERMITIAN_CASES)):
+    for case in src:
+        if not isinstance(case.a, np.ndarray):
+            continue
+
+        a = np.array([case.a, 2 * case.a, 3 * case.a])
+        if case.b is None:
+            b = None
+        else:
+            b = np.array([case.b, 7 * case.b, 6 * case.b])
+        new_case = LinalgCase(case.name + "_tile3", a, b,
+                              case.exception_cls)
+        tgt.append(new_case)
+
+        a = np.array([case.a] * 2 * 3).reshape((3, 2) + case.a.shape)
+        if case.b is None:
+            b = None
+        else:
+            b = np.array([case.b] * 2 * 3).reshape((3, 2) + case.b.shape)
+        new_case = LinalgCase(case.name + "_tile213", a, b,
+                              case.exception_cls)
+        tgt.append(new_case)
+
+#
+# Generate stride combination variations of the above
+#
+
+
+def _stride_comb_iter(x):
+    """
+    Generate cartesian product of strides for all axes
+    """
+
+    if not isinstance(x, np.ndarray):
+        yield x, "nop"
+        return
+
+    stride_set = [(1,)] * x.ndim
+    stride_set[-1] = (1, 3, -4)
+    if x.ndim > 1:
+        stride_set[-2] = (1, 3, -4)
+    if x.ndim > 2:
+        stride_set[-3] = (1, -4)
+
+    for repeats in itertools.product(*tuple(stride_set)):
+        new_shape = [abs(a * b) for a, b in zip(x.shape, repeats)]
+        slices = tuple([slice(None, None, repeat) for repeat in repeats])
+
+        # new array with different strides, but same data
+        xi = np.empty(new_shape, dtype=x.dtype)
+        xi.view(np.uint32).fill(0xdeadbeef)
+        xi = xi[slices]
+        xi[...] = x
+        xi = xi.view(x.__class__)
+        assert_(np.all(xi == x))
+        yield xi, "stride_" + "_".join(["%+d" % j for j in repeats])
+
+        # generate also zero strides if possible
+        if x.ndim >= 1 and x.shape[-1] == 1:
+            s = list(x.strides)
+            s[-1] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0"
+        if x.ndim >= 2 and x.shape[-2] == 1:
+            s = list(x.strides)
+            s[-2] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0_x"
+        if x.ndim >= 2 and x.shape[:-2] == (1, 1):
+            s = list(x.strides)
+            s[-1] = 0
+            s[-2] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0_0"
+
+for src in (SQUARE_CASES,
+            NONSQUARE_CASES,
+            HERMITIAN_CASES,
+            GENERALIZED_SQUARE_CASES,
+            GENERALIZED_NONSQUARE_CASES,
+            GENERALIZED_HERMITIAN_CASES):
+
+    new_cases = []
+    for case in src:
+        for a, a_tag in _stride_comb_iter(case.a):
+            for b, b_tag in _stride_comb_iter(case.b):
+                new_case = LinalgCase(case.name + "_" + a_tag + "_" + b_tag, a, b,
+                                      exception_cls=case.exception_cls)
+                new_cases.append(new_case)
+    src.extend(new_cases)
+
+
+#
+# Test different routines against the above cases
+#
+
+def _check_cases(func, cases):
+    for case in cases:
+        try:
+            case.check(func)
+        except Exception:
+            msg = "In test case: %r\n\n" % case
+            msg += traceback.format_exc()
+            raise AssertionError(msg)
+
+
+class LinalgTestCase(object):
+
+    def test_sq_cases(self):
+        _check_cases(self.do, SQUARE_CASES)
+
+
+class LinalgNonsquareTestCase(object):
+
+    def test_sq_cases(self):
+        _check_cases(self.do, NONSQUARE_CASES)
+
+
+class LinalgGeneralizedTestCase(object):
+
+    @dec.slow
+    def test_generalized_sq_cases(self):
+        _check_cases(self.do, GENERALIZED_SQUARE_CASES)
+
+
+class LinalgGeneralizedNonsquareTestCase(object):
+
+    @dec.slow
+    def test_generalized_nonsq_cases(self):
+        _check_cases(self.do, GENERALIZED_NONSQUARE_CASES)
+
+
+class HermitianTestCase(object):
+
+    def test_herm_cases(self):
+        _check_cases(self.do, HERMITIAN_CASES)
+
+
+class HermitianGeneralizedTestCase(object):
+
+    @dec.slow
+    def test_generalized_herm_cases(self):
+        _check_cases(self.do, GENERALIZED_HERMITIAN_CASES)
+
+
+def dot_generalized(a, b):
+    a = asarray(a)
+    if a.ndim >= 3:
+        if a.ndim == b.ndim:
+            # matrix x matrix
+            new_shape = a.shape[:-1] + b.shape[-1:]
+        elif a.ndim == b.ndim + 1:
+            # matrix x vector
+            new_shape = a.shape[:-1]
+        else:
+            raise ValueError("Not implemented...")
+        r = np.empty(new_shape, dtype=np.common_type(a, b))
+        for c in itertools.product(*map(range, a.shape[:-2])):
+            r[c] = dot(a[c], b[c])
+        return r
+    else:
+        return dot(a, b)
+
+
+def identity_like_generalized(a):
+    a = asarray(a)
+    if a.ndim >= 3:
+        r = np.empty(a.shape, dtype=a.dtype)
+        for c in itertools.product(*map(range, a.shape[:-2])):
+            r[c] = identity(a.shape[-2])
+        return r
+    else:
+        return identity(a.shape[0])
+
+
+class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        x = linalg.solve(a, b)
+        assert_almost_equal(b, dot_generalized(a, x))
+        assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.solve(x, x).dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_0_size(self):
+        class ArraySubclass(np.ndarray):
+            pass
+        # Test system of 0x0 matrices
+        a = np.arange(8).reshape(2, 2, 2)
+        b = np.arange(6).reshape(1, 2, 3).view(ArraySubclass)
+
+        expected = linalg.solve(a, b)[:, 0:0, :]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, :])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        # Test errors for non-square and only b's dimension being 0
+        assert_raises(linalg.LinAlgError, linalg.solve, a[:, 0:0, 0:1], b)
+        assert_raises(ValueError, linalg.solve, a, b[:, 0:0, :])
+
+        # Test broadcasting error
+        b = np.arange(6).reshape(1, 3, 2)  # broadcasting error
+        assert_raises(ValueError, linalg.solve, a, b)
+        assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
+
+        # Test zero "single equations" with 0x0 matrices.
+        b = np.arange(2).reshape(1, 2).view(ArraySubclass)
+        expected = linalg.solve(a, b)[:, 0:0]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        b = np.arange(3).reshape(1, 3)
+        assert_raises(ValueError, linalg.solve, a, b)
+        assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
+        assert_raises(ValueError, linalg.solve, a[:, 0:0, 0:0], b)
+
+    def test_0_size_k(self):
+        # test zero multiple equation (K=0) case.
+        class ArraySubclass(np.ndarray):
+            pass
+        a = np.arange(4).reshape(1, 2, 2)
+        b = np.arange(6).reshape(3, 2, 1).view(ArraySubclass)
+
+        expected = linalg.solve(a, b)[:, :, 0:0]
+        result = linalg.solve(a, b[:, :, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        # test both zero.
+        expected = linalg.solve(a, b)[:, 0:0, 0:0]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+
+class TestInv(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        a_inv = linalg.inv(a)
+        assert_almost_equal(dot_generalized(a, a_inv),
+                            identity_like_generalized(a))
+        assert_(imply(isinstance(a, matrix), isinstance(a_inv, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.inv(x).dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_0_size(self):
+        # Check that all kinds of 0-sized arrays work
+        class ArraySubclass(np.ndarray):
+            pass
+        a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass)
+        res = linalg.inv(a)
+        assert_(res.dtype.type is np.float64)
+        assert_equal(a.shape, res.shape)
+        assert_(isinstance(a, ArraySubclass))
+
+        a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass)
+        res = linalg.inv(a)
+        assert_(res.dtype.type is np.complex64)
+        assert_equal(a.shape, res.shape)
+
+
+class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        ev = linalg.eigvals(a)
+        evalues, evectors = linalg.eig(a)
+        assert_almost_equal(ev, evalues)
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.eigvals(x).dtype, dtype)
+            x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+            assert_equal(linalg.eigvals(x).dtype, get_complex_dtype(dtype))
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestEig(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        evalues, evectors = linalg.eig(a)
+        assert_allclose(dot_generalized(a, evectors),
+                        np.asarray(evectors) * np.asarray(evalues)[..., None, :],
+                        rtol=get_rtol(evalues.dtype))
+        assert_(imply(isinstance(a, matrix), isinstance(evectors, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w, v = np.linalg.eig(x)
+            assert_equal(w.dtype, dtype)
+            assert_equal(v.dtype, dtype)
+
+            x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+            w, v = np.linalg.eig(x)
+            assert_equal(w.dtype, get_complex_dtype(dtype))
+            assert_equal(v.dtype, get_complex_dtype(dtype))
+
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        u, s, vt = linalg.svd(a, 0)
+        assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[..., None, :],
+                                           np.asarray(vt)),
+                        rtol=get_rtol(u.dtype))
+        assert_(imply(isinstance(a, matrix), isinstance(u, matrix)))
+        assert_(imply(isinstance(a, matrix), isinstance(vt, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            u, s, vh = linalg.svd(x)
+            assert_equal(u.dtype, dtype)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+            assert_equal(vh.dtype, dtype)
+            s = linalg.svd(x, compute_uv=False)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        c = asarray(a)  # a might be a matrix
+        s = linalg.svd(c, compute_uv=False)
+        old_assert_almost_equal(
+            s[..., 0] / s[..., -1], linalg.cond(a), decimal=5)
+
+    def test_stacked_arrays_explicitly(self):
+        A = np.array([[1., 2., 1.], [0, -2., 0], [6., 2., 3.]])
+        assert_equal(linalg.cond(A), linalg.cond(A[None, ...])[0])
+
+
+class TestCond2(LinalgTestCase):
+
+    def do(self, a, b):
+        c = asarray(a)  # a might be a matrix
+        s = linalg.svd(c, compute_uv=False)
+        old_assert_almost_equal(
+            s[..., 0] / s[..., -1], linalg.cond(a, 2), decimal=5)
+
+    def test_stacked_arrays_explicitly(self):
+        A = np.array([[1., 2., 1.], [0, -2., 0], [6., 2., 3.]])
+        assert_equal(linalg.cond(A, 2), linalg.cond(A[None, ...], 2)[0])
+
+
+class TestCondInf(object):
+
+    def test(self):
+        A = array([[1., 0, 0], [0, -2., 0], [0, 0, 3.]])
+        assert_almost_equal(linalg.cond(A, inf), 3.)
+
+
+class TestPinv(LinalgTestCase):
+
+    def do(self, a, b):
+        a_ginv = linalg.pinv(a)
+        assert_almost_equal(dot(a, a_ginv), identity(asarray(a).shape[0]))
+        assert_(imply(isinstance(a, matrix), isinstance(a_ginv, matrix)))
+
+
+class TestDet(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        d = linalg.det(a)
+        (s, ld) = linalg.slogdet(a)
+        if asarray(a).dtype.type in (single, double):
+            ad = asarray(a).astype(double)
+        else:
+            ad = asarray(a).astype(cdouble)
+        ev = linalg.eigvals(ad)
+        assert_almost_equal(d, multiply.reduce(ev, axis=-1))
+        assert_almost_equal(s * np.exp(ld), multiply.reduce(ev, axis=-1))
+
+        s = np.atleast_1d(s)
+        ld = np.atleast_1d(ld)
+        m = (s != 0)
+        assert_almost_equal(np.abs(s[m]), 1)
+        assert_equal(ld[~m], -inf)
+
+    def test_zero(self):
+        assert_equal(linalg.det([[0.0]]), 0.0)
+        assert_equal(type(linalg.det([[0.0]])), double)
+        assert_equal(linalg.det([[0.0j]]), 0.0)
+        assert_equal(type(linalg.det([[0.0j]])), cdouble)
+
+        assert_equal(linalg.slogdet([[0.0]]), (0.0, -inf))
+        assert_equal(type(linalg.slogdet([[0.0]])[0]), double)
+        assert_equal(type(linalg.slogdet([[0.0]])[1]), double)
+        assert_equal(linalg.slogdet([[0.0j]]), (0.0j, -inf))
+        assert_equal(type(linalg.slogdet([[0.0j]])[0]), cdouble)
+        assert_equal(type(linalg.slogdet([[0.0j]])[1]), double)
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(np.linalg.det(x).dtype, dtype)
+            ph, s = np.linalg.slogdet(x)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+            assert_equal(ph.dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase):
+
+    def do(self, a, b):
+        arr = np.asarray(a)
+        m, n = arr.shape
+        u, s, vt = linalg.svd(a, 0)
+        x, residuals, rank, sv = linalg.lstsq(a, b)
+        if m <= n:
+            assert_almost_equal(b, dot(a, x))
+            assert_equal(rank, m)
+        else:
+            assert_equal(rank, n)
+        assert_almost_equal(sv, sv.__array_wrap__(s))
+        if rank == n and m > n:
+            expect_resids = (
+                np.asarray(abs(np.dot(a, x) - b)) ** 2).sum(axis=0)
+            expect_resids = np.asarray(expect_resids)
+            if len(np.asarray(b).shape) == 1:
+                expect_resids.shape = (1,)
+                assert_equal(residuals.shape, expect_resids.shape)
+        else:
+            expect_resids = np.array([]).view(type(x))
+        assert_almost_equal(residuals, expect_resids)
+        assert_(np.issubdtype(residuals.dtype, np.floating))
+        assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+        assert_(imply(isinstance(b, matrix), isinstance(residuals, matrix)))
+
+
+class TestMatrixPower(object):
+    R90 = array([[0, 1], [-1, 0]])
+    Arb22 = array([[4, -7], [-2, 10]])
+    noninv = array([[1, 0], [0, 0]])
+    arbfloat = array([[0.1, 3.2], [1.2, 0.7]])
+
+    large = identity(10)
+    t = large[1, :].copy()
+    large[1, :] = large[0,:]
+    large[0, :] = t
+
+    def test_large_power(self):
+        assert_equal(
+            matrix_power(self.R90, 2 ** 100 + 2 ** 10 + 2 ** 5 + 1), self.R90)
+
+    def test_large_power_trailing_zero(self):
+        assert_equal(
+            matrix_power(self.R90, 2 ** 100 + 2 ** 10 + 2 ** 5), identity(2))
+
+    def testip_zero(self):
+        def tz(M):
+            mz = matrix_power(M, 0)
+            assert_equal(mz, identity(M.shape[0]))
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_one(self):
+        def tz(M):
+            mz = matrix_power(M, 1)
+            assert_equal(mz, M)
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_two(self):
+        def tz(M):
+            mz = matrix_power(M, 2)
+            assert_equal(mz, dot(M, M))
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_invert(self):
+        def tz(M):
+            mz = matrix_power(M, -1)
+            assert_almost_equal(identity(M.shape[0]), dot(mz, M))
+        for M in [self.R90, self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def test_invert_noninvertible(self):
+        import numpy.linalg
+        assert_raises(numpy.linalg.linalg.LinAlgError,
+                      lambda: matrix_power(self.noninv, -1))
+
+
+class TestBoolPower(object):
+
+    def test_square(self):
+        A = array([[True, False], [True, True]])
+        assert_equal(matrix_power(A, 2), A)
+
+
+class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase):
+
+    def do(self, a, b):
+        # note that eigenvalue arrays returned by eig must be sorted since
+        # their order isn't guaranteed.
+        ev = linalg.eigvalsh(a, 'L')
+        evalues, evectors = linalg.eig(a)
+        evalues.sort(axis=-1)
+        assert_allclose(ev, evalues, rtol=get_rtol(ev.dtype))
+
+        ev2 = linalg.eigvalsh(a, 'U')
+        assert_allclose(ev2, evalues, rtol=get_rtol(ev.dtype))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w = np.linalg.eigvalsh(x)
+            assert_equal(w.dtype, get_real_dtype(dtype))
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_invalid(self):
+        x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+        assert_raises(ValueError, np.linalg.eigvalsh, x, UPLO="lrong")
+        assert_raises(ValueError, np.linalg.eigvalsh, x, "lower")
+        assert_raises(ValueError, np.linalg.eigvalsh, x, "upper")
+
+    def test_UPLO(self):
+        Klo = np.array([[0, 0], [1, 0]], dtype=np.double)
+        Kup = np.array([[0, 1], [0, 0]], dtype=np.double)
+        tgt = np.array([-1, 1], dtype=np.double)
+        rtol = get_rtol(np.double)
+
+        # Check default is 'L'
+        w = np.linalg.eigvalsh(Klo)
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'L'
+        w = np.linalg.eigvalsh(Klo, UPLO='L')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'l'
+        w = np.linalg.eigvalsh(Klo, UPLO='l')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'U'
+        w = np.linalg.eigvalsh(Kup, UPLO='U')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'u'
+        w = np.linalg.eigvalsh(Kup, UPLO='u')
+        assert_allclose(w, tgt, rtol=rtol)
+
+
+class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
+
+    def do(self, a, b):
+        # note that eigenvalue arrays returned by eig must be sorted since
+        # their order isn't guaranteed.
+        ev, evc = linalg.eigh(a)
+        evalues, evectors = linalg.eig(a)
+        evalues.sort(axis=-1)
+        assert_almost_equal(ev, evalues)
+
+        assert_allclose(dot_generalized(a, evc),
+                        np.asarray(ev)[..., None, :] * np.asarray(evc),
+                        rtol=get_rtol(ev.dtype))
+
+        ev2, evc2 = linalg.eigh(a, 'U')
+        assert_almost_equal(ev2, evalues)
+
+        assert_allclose(dot_generalized(a, evc2),
+                        np.asarray(ev2)[..., None, :] * np.asarray(evc2),
+                        rtol=get_rtol(ev.dtype), err_msg=repr(a))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w, v = np.linalg.eigh(x)
+            assert_equal(w.dtype, get_real_dtype(dtype))
+            assert_equal(v.dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_invalid(self):
+        x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+        assert_raises(ValueError, np.linalg.eigh, x, UPLO="lrong")
+        assert_raises(ValueError, np.linalg.eigh, x, "lower")
+        assert_raises(ValueError, np.linalg.eigh, x, "upper")
+
+    def test_UPLO(self):
+        Klo = np.array([[0, 0], [1, 0]], dtype=np.double)
+        Kup = np.array([[0, 1], [0, 0]], dtype=np.double)
+        tgt = np.array([-1, 1], dtype=np.double)
+        rtol = get_rtol(np.double)
+
+        # Check default is 'L'
+        w, v = np.linalg.eigh(Klo)
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'L'
+        w, v = np.linalg.eigh(Klo, UPLO='L')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'l'
+        w, v = np.linalg.eigh(Klo, UPLO='l')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'U'
+        w, v = np.linalg.eigh(Kup, UPLO='U')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'u'
+        w, v = np.linalg.eigh(Kup, UPLO='u')
+        assert_allclose(w, tgt, rtol=rtol)
+
+
+class _TestNorm(object):
+
+    dt = None
+    dec = None
+
+    def test_empty(self):
+        assert_equal(norm([]), 0.0)
+        assert_equal(norm(array([], dtype=self.dt)), 0.0)
+        assert_equal(norm(atleast_2d(array([], dtype=self.dt))), 0.0)
+
+    def test_vector_return_type(self):
+        a = np.array([1, 0, 1])
+
+        exact_types = np.typecodes['AllInteger']
+        inexact_types = np.typecodes['AllFloat']
+
+        all_types = exact_types + inexact_types
+
+        for each_inexact_types in all_types:
+            at = a.astype(each_inexact_types)
+
+            an = norm(at, -np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 0.0)
+
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", RuntimeWarning)
+                an = norm(at, -1)
+                assert_(issubclass(an.dtype.type, np.floating))
+                assert_almost_equal(an, 0.0)
+
+            an = norm(at, 0)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2)
+
+            an = norm(at, 1)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0**(1.0/2.0))
+
+            an = norm(at, 4)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0**(1.0/4.0))
+
+            an = norm(at, np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 1.0)
+
+    def test_matrix_return_type(self):
+        a = np.array([[1, 0, 1], [0, 1, 1]])
+
+        exact_types = np.typecodes['AllInteger']
+
+        # float32, complex64, float64, complex128 types are the only types
+        # allowed by `linalg`, which performs the matrix operations used
+        # within `norm`.
+        inexact_types = 'fdFD'
+
+        all_types = exact_types + inexact_types
+
+        for each_inexact_types in all_types:
+            at = a.astype(each_inexact_types)
+
+            an = norm(at, -np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", RuntimeWarning)
+                an = norm(at, -1)
+                assert_(issubclass(an.dtype.type, np.floating))
+                assert_almost_equal(an, 1.0)
+
+            an = norm(at, 1)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 3.0**(1.0/2.0))
+
+            an = norm(at, -2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 1.0)
+
+            an = norm(at, np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 'fro')
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 'nuc')
+            assert_(issubclass(an.dtype.type, np.floating))
+            # Lower bar needed to support low precision floats.
+            # They end up being off by 1 in the 7th place.
+            old_assert_almost_equal(an, 2.7320508075688772, decimal=6)
+
+    def test_vector(self):
+        a = [1, 2, 3, 4]
+        b = [-1, -2, -3, -4]
+        c = [-1, 2, -3, 4]
+
+        def _test(v):
+            np.testing.assert_almost_equal(norm(v), 30 ** 0.5,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, inf), 4.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -inf), 1.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 1), 10.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -1), 12.0 / 25,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 2), 30 ** 0.5,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -2), ((205. / 144) ** -0.5),
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 0), 4,
+                                           decimal=self.dec)
+
+        for v in (a, b, c,):
+            _test(v)
+
+        for v in (array(a, dtype=self.dt), array(b, dtype=self.dt),
+                  array(c, dtype=self.dt)):
+            _test(v)
+
+    def test_matrix_2x2(self):
+        A = matrix([[1, 3], [5, 7]], dtype=self.dt)
+        assert_almost_equal(norm(A), 84 ** 0.5)
+        assert_almost_equal(norm(A, 'fro'), 84 ** 0.5)
+        assert_almost_equal(norm(A, 'nuc'), 10.0)
+        assert_almost_equal(norm(A, inf), 12.0)
+        assert_almost_equal(norm(A, -inf), 4.0)
+        assert_almost_equal(norm(A, 1), 10.0)
+        assert_almost_equal(norm(A, -1), 6.0)
+        assert_almost_equal(norm(A, 2), 9.1231056256176615)
+        assert_almost_equal(norm(A, -2), 0.87689437438234041)
+
+        assert_raises(ValueError, norm, A, 'nofro')
+        assert_raises(ValueError, norm, A, -3)
+        assert_raises(ValueError, norm, A, 0)
+
+    def test_matrix_3x3(self):
+        # This test has been added because the 2x2 example
+        # happened to have equal nuclear norm and induced 1-norm.
+        # The 1/10 scaling factor accommodates the absolute tolerance
+        # used in assert_almost_equal.
+        A = (1 / 10) * \
+            np.array([[1, 2, 3], [6, 0, 5], [3, 2, 1]], dtype=self.dt)
+        assert_almost_equal(norm(A), (1 / 10) * 89 ** 0.5)
+        assert_almost_equal(norm(A, 'fro'), (1 / 10) * 89 ** 0.5)
+        assert_almost_equal(norm(A, 'nuc'), 1.3366836911774836)
+        assert_almost_equal(norm(A, inf), 1.1)
+        assert_almost_equal(norm(A, -inf), 0.6)
+        assert_almost_equal(norm(A, 1), 1.0)
+        assert_almost_equal(norm(A, -1), 0.4)
+        assert_almost_equal(norm(A, 2), 0.88722940323461277)
+        assert_almost_equal(norm(A, -2), 0.19456584790481812)
+
+    def test_axis(self):
+        # Vector norms.
+        # Compare the use of `axis` with computing the norm of each row
+        # or column separately.
+        A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
+        for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]:
+            expected0 = [norm(A[:, k], ord=order) for k in range(A.shape[1])]
+            assert_almost_equal(norm(A, ord=order, axis=0), expected0)
+            expected1 = [norm(A[k, :], ord=order) for k in range(A.shape[0])]
+            assert_almost_equal(norm(A, ord=order, axis=1), expected1)
+
+        # Matrix norms.
+        B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+        nd = B.ndim
+        for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro']:
+            for axis in itertools.combinations(range(-nd, nd), 2):
+                row_axis, col_axis = axis
+                if row_axis < 0:
+                    row_axis += nd
+                if col_axis < 0:
+                    col_axis += nd
+                if row_axis == col_axis:
+                    assert_raises(ValueError, norm, B, ord=order, axis=axis)
+                else:
+                    n = norm(B, ord=order, axis=axis)
+
+                    # The logic using k_index only works for nd = 3.
+                    # This has to be changed if nd is increased.
+                    k_index = nd - (row_axis + col_axis)
+                    if row_axis < col_axis:
+                        expected = [norm(B[:].take(k, axis=k_index), ord=order)
+                                    for k in range(B.shape[k_index])]
+                    else:
+                        expected = [norm(B[:].take(k, axis=k_index).T, ord=order)
+                                    for k in range(B.shape[k_index])]
+                    assert_almost_equal(n, expected)
+
+    def test_keepdims(self):
+        A = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+
+        allclose_err = 'order {0}, axis = {1}'
+        shape_err = 'Shape mismatch found {0}, expected {1}, order={2}, axis={3}'
+
+        # check the order=None, axis=None case
+        expected = norm(A, ord=None, axis=None)
+        found = norm(A, ord=None, axis=None, keepdims=True)
+        assert_allclose(np.squeeze(found), expected,
+                        err_msg=allclose_err.format(None, None))
+        expected_shape = (1, 1, 1)
+        assert_(found.shape == expected_shape,
+                shape_err.format(found.shape, expected_shape, None, None))
+
+        # Vector norms.
+        for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]:
+            for k in range(A.ndim):
+                expected = norm(A, ord=order, axis=k)
+                found = norm(A, ord=order, axis=k, keepdims=True)
+                assert_allclose(np.squeeze(found), expected,
+                                err_msg=allclose_err.format(order, k))
+                expected_shape = list(A.shape)
+                expected_shape[k] = 1
+                expected_shape = tuple(expected_shape)
+                assert_(found.shape == expected_shape,
+                        shape_err.format(found.shape, expected_shape, order, k))
+
+        # Matrix norms.
+        for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro', 'nuc']:
+            for k in itertools.permutations(range(A.ndim), 2):
+                expected = norm(A, ord=order, axis=k)
+                found = norm(A, ord=order, axis=k, keepdims=True)
+                assert_allclose(np.squeeze(found), expected,
+                                err_msg=allclose_err.format(order, k))
+                expected_shape = list(A.shape)
+                expected_shape[k[0]] = 1
+                expected_shape[k[1]] = 1
+                expected_shape = tuple(expected_shape)
+                assert_(found.shape == expected_shape,
+                        shape_err.format(found.shape, expected_shape, order, k))
+
+    def test_bad_args(self):
+        # Check that bad arguments raise the appropriate exceptions.
+
+        A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
+        B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+
+        # Using `axis=<integer>` or passing in a 1-D array implies vector
+        # norms are being computed, so also using `ord='fro'`
+        # or `ord='nuc'` raises a ValueError.
+        assert_raises(ValueError, norm, A, 'fro', 0)
+        assert_raises(ValueError, norm, A, 'nuc', 0)
+        assert_raises(ValueError, norm, [3, 4], 'fro', None)
+        assert_raises(ValueError, norm, [3, 4], 'nuc', None)
+
+        # Similarly, norm should raise an exception when ord is any finite
+        # number other than 1, 2, -1 or -2 when computing matrix norms.
+        for order in [0, 3]:
+            assert_raises(ValueError, norm, A, order, None)
+            assert_raises(ValueError, norm, A, order, (0, 1))
+            assert_raises(ValueError, norm, B, order, (1, 2))
+
+        # Invalid axis
+        assert_raises(ValueError, norm, B, None, 3)
+        assert_raises(ValueError, norm, B, None, (2, 3))
+        assert_raises(ValueError, norm, B, None, (0, 1, 2))
+
+
+class TestNorm_NonSystematic(object):
+
+    def test_longdouble_norm(self):
+        # Non-regression test: p-norm of longdouble would previously raise
+        # UnboundLocalError.
+        x = np.arange(10, dtype=np.longdouble)
+        old_assert_almost_equal(norm(x, ord=3), 12.65, decimal=2)
+
+    def test_intmin(self):
+        # Non-regression test: p-norm of signed integer would previously do
+        # float cast and abs in the wrong order.
+        x = np.array([-2 ** 31], dtype=np.int32)
+        old_assert_almost_equal(norm(x, ord=3), 2 ** 31, decimal=5)
+
+    def test_complex_high_ord(self):
+        # gh-4156
+        d = np.empty((2,), dtype=np.clongdouble)
+        d[0] = 6 + 7j
+        d[1] = -6 + 7j
+        res = 11.615898132184
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=10)
+        d = d.astype(np.complex128)
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=9)
+        d = d.astype(np.complex64)
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=5)
+
+
+class TestNormDouble(_TestNorm):
+    dt = np.double
+    dec = 12
+
+
+class TestNormSingle(_TestNorm):
+    dt = np.float32
+    dec = 6
+
+
+class TestNormInt64(_TestNorm):
+    dt = np.int64
+    dec = 12
+
+
+class TestMatrixRank(object):
+
+    def test_matrix_rank(self):
+        # Full rank matrix
+        yield assert_equal, 4, matrix_rank(np.eye(4))
+        # rank deficient matrix
+        I = np.eye(4)
+        I[-1, -1] = 0.
+        yield assert_equal, matrix_rank(I), 3
+        # All zeros - zero rank
+        yield assert_equal, matrix_rank(np.zeros((4, 4))), 0
+        # 1 dimension - rank 1 unless all 0
+        yield assert_equal, matrix_rank([1, 0, 0, 0]), 1
+        yield assert_equal, matrix_rank(np.zeros((4,))), 0
+        # accepts array-like
+        yield assert_equal, matrix_rank([1]), 1
+        # greater than 2 dimensions raises error
+        yield assert_raises, TypeError, matrix_rank, np.zeros((2, 2, 2))
+        # works on scalar
+        yield assert_equal, matrix_rank(1), 1
+
+
+def test_reduced_rank():
+    # Test matrices with reduced rank
+    rng = np.random.RandomState(20120714)
+    for i in range(100):
+        # Make a rank deficient matrix
+        X = rng.normal(size=(40, 10))
+        X[:, 0] = X[:, 1] + X[:, 2]
+        # Assert that matrix_rank detected deficiency
+        assert_equal(matrix_rank(X), 9)
+        X[:, 3] = X[:, 4] + X[:, 5]
+        assert_equal(matrix_rank(X), 8)
+
+
+class TestQR(object):
+
+    def check_qr(self, a):
+        # This test expects the argument `a` to be an ndarray or
+        # a subclass of an ndarray of inexact type.
+        a_type = type(a)
+        a_dtype = a.dtype
+        m, n = a.shape
+        k = min(m, n)
+
+        # mode == 'complete'
+        q, r = linalg.qr(a, mode='complete')
+        assert_(q.dtype == a_dtype)
+        assert_(r.dtype == a_dtype)
+        assert_(isinstance(q, a_type))
+        assert_(isinstance(r, a_type))
+        assert_(q.shape == (m, m))
+        assert_(r.shape == (m, n))
+        assert_almost_equal(dot(q, r), a)
+        assert_almost_equal(dot(q.T.conj(), q), np.eye(m))
+        assert_almost_equal(np.triu(r), r)
+
+        # mode == 'reduced'
+        q1, r1 = linalg.qr(a, mode='reduced')
+        assert_(q1.dtype == a_dtype)
+        assert_(r1.dtype == a_dtype)
+        assert_(isinstance(q1, a_type))
+        assert_(isinstance(r1, a_type))
+        assert_(q1.shape == (m, k))
+        assert_(r1.shape == (k, n))
+        assert_almost_equal(dot(q1, r1), a)
+        assert_almost_equal(dot(q1.T.conj(), q1), np.eye(k))
+        assert_almost_equal(np.triu(r1), r1)
+
+        # mode == 'r'
+        r2 = linalg.qr(a, mode='r')
+        assert_(r2.dtype == a_dtype)
+        assert_(isinstance(r2, a_type))
+        assert_almost_equal(r2, r1)
+
+    def test_qr_empty(self):
+        a = np.zeros((0, 2))
+        assert_raises(linalg.LinAlgError, linalg.qr, a)
+
+    def test_mode_raw(self):
+        # The factorization is not unique and varies between libraries,
+        # so it is not possible to check against known values. Functional
+        # testing is a possibility, but awaits the exposure of more
+        # of the functions in lapack_lite. Consequently, this test is
+        # very limited in scope. Note that the results are in FORTRAN
+        # order, hence the h arrays are transposed.
+        a = array([[1, 2], [3, 4], [5, 6]], dtype=np.double)
+
+        # Test double
+        h, tau = linalg.qr(a, mode='raw')
+        assert_(h.dtype == np.double)
+        assert_(tau.dtype == np.double)
+        assert_(h.shape == (2, 3))
+        assert_(tau.shape == (2,))
+
+        h, tau = linalg.qr(a.T, mode='raw')
+        assert_(h.dtype == np.double)
+        assert_(tau.dtype == np.double)
+        assert_(h.shape == (3, 2))
+        assert_(tau.shape == (2,))
+
+    def test_mode_all_but_economic(self):
+        a = array([[1, 2], [3, 4]])
+        b = array([[1, 2], [3, 4], [5, 6]])
+        for dt in "fd":
+            m1 = a.astype(dt)
+            m2 = b.astype(dt)
+            self.check_qr(m1)
+            self.check_qr(m2)
+            self.check_qr(m2.T)
+            self.check_qr(matrix(m1))
+        for dt in "fd":
+            m1 = 1 + 1j * a.astype(dt)
+            m2 = 1 + 1j * b.astype(dt)
+            self.check_qr(m1)
+            self.check_qr(m2)
+            self.check_qr(m2.T)
+            self.check_qr(matrix(m1))
+
+
+def test_byteorder_check():
+    # Byte order check should pass for native order
+    if sys.byteorder == 'little':
+        native = '<'
+    else:
+        native = '>'
+
+    for dtt in (np.float32, np.float64):
+        arr = np.eye(4, dtype=dtt)
+        n_arr = arr.newbyteorder(native)
+        sw_arr = arr.newbyteorder('S').byteswap()
+        assert_equal(arr.dtype.byteorder, '=')
+        for routine in (linalg.inv, linalg.det, linalg.pinv):
+            # Normal call
+            res = routine(arr)
+            # Native but not '='
+            assert_array_equal(res, routine(n_arr))
+            # Swapped
+            assert_array_equal(res, routine(sw_arr))
+
+
+def test_generalized_raise_multiloop():
+    # It should raise an error even if the error doesn't occur in the
+    # last iteration of the ufunc inner loop
+
+    invertible = np.array([[1, 2], [3, 4]])
+    non_invertible = np.array([[1, 1], [1, 1]])
+
+    x = np.zeros([4, 4, 2, 2])[1::2]
+    x[...] = invertible
+    x[0, 0] = non_invertible
+
+    assert_raises(np.linalg.LinAlgError, np.linalg.inv, x)
+
+
+def test_xerbla_override():
+    # Check that our xerbla has been successfully linked in. If it is not,
+    # the default xerbla routine is called, which prints a message to stdout
+    # and may, or may not, abort the process depending on the LAPACK package.
+
+    XERBLA_OK = 255
+
+    try:
+        pid = os.fork()
+    except (OSError, AttributeError):
+        # fork failed, or not running on POSIX
+        raise SkipTest("Not POSIX or fork failed.")
+
+    if pid == 0:
+        # child; close i/o file handles
+        os.close(1)
+        os.close(0)
+        # Avoid producing core files.
+        import resource
+        resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
+        # These calls may abort.
+        try:
+            np.linalg.lapack_lite.xerbla()
+        except ValueError:
+            pass
+        except:
+            os._exit(os.EX_CONFIG)
+
+        try:
+            a = np.array([[1.]])
+            np.linalg.lapack_lite.dorgqr(
+                1, 1, 1, a,
+                0,  # <- invalid value
+                a, a, 0, 0)
+        except ValueError as e:
+            if "DORGQR parameter number 5" in str(e):
+                # success, reuse error code to mark success as
+                # FORTRAN STOP returns as success.
+                os._exit(XERBLA_OK)
+
+        # Did not abort, but our xerbla was not linked in.
+        os._exit(os.EX_CONFIG)
+    else:
+        # parent
+        pid, status = os.wait()
+        if os.WEXITSTATUS(status) != XERBLA_OK:
+            raise SkipTest('Numpy xerbla not linked in.')
+
+
+class TestMultiDot(object):
+
+    def test_basic_function_with_three_arguments(self):
+        # multi_dot with three arguments uses a fast hand coded algorithm to
+        # determine the optimal order. Therefore test it separately.
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+
+        assert_almost_equal(multi_dot([A, B, C]), A.dot(B).dot(C))
+        assert_almost_equal(multi_dot([A, B, C]), np.dot(A, np.dot(B, C)))
+
+    def test_basic_function_with_dynamic_programing_optimization(self):
+        # multi_dot with four or more arguments uses the dynamic programing
+        # optimization and therefore deserve a separate
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D = np.random.random((2, 1))
+        assert_almost_equal(multi_dot([A, B, C, D]), A.dot(B).dot(C).dot(D))
+
+    def test_vector_as_first_argument(self):
+        # The first argument can be 1-D
+        A1d = np.random.random(2)  # 1-D
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D = np.random.random((2, 2))
+
+        # the result should be 1-D
+        assert_equal(multi_dot([A1d, B, C, D]).shape, (2,))
+
+    def test_vector_as_last_argument(self):
+        # The last argument can be 1-D
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D1d = np.random.random(2)  # 1-D
+
+        # the result should be 1-D
+        assert_equal(multi_dot([A, B, C, D1d]).shape, (6,))
+
+    def test_vector_as_first_and_last_argument(self):
+        # The first and last arguments can be 1-D
+        A1d = np.random.random(2)  # 1-D
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D1d = np.random.random(2)  # 1-D
+
+        # the result should be a scalar
+        assert_equal(multi_dot([A1d, B, C, D1d]).shape, ())
+
+    def test_dynamic_programming_logic(self):
+        # Test for the dynamic programming part
+        # This test is directly taken from Cormen page 376.
+        arrays = [np.random.random((30, 35)),
+                  np.random.random((35, 15)),
+                  np.random.random((15, 5)),
+                  np.random.random((5, 10)),
+                  np.random.random((10, 20)),
+                  np.random.random((20, 25))]
+        m_expected = np.array([[0., 15750., 7875., 9375., 11875., 15125.],
+                               [0.,     0., 2625., 4375.,  7125., 10500.],
+                               [0.,     0.,    0.,  750.,  2500.,  5375.],
+                               [0.,     0.,    0.,    0.,  1000.,  3500.],
+                               [0.,     0.,    0.,    0.,     0.,  5000.],
+                               [0.,     0.,    0.,    0.,     0.,     0.]])
+        s_expected = np.array([[0,  1,  1,  3,  3,  3],
+                               [0,  0,  2,  3,  3,  3],
+                               [0,  0,  0,  3,  3,  3],
+                               [0,  0,  0,  0,  4,  5],
+                               [0,  0,  0,  0,  0,  5],
+                               [0,  0,  0,  0,  0,  0]], dtype=np.int)
+        s_expected -= 1  # Cormen uses 1-based index, python does not.
+
+        s, m = _multi_dot_matrix_chain_order(arrays, return_costs=True)
+
+        # Only the upper triangular part (without the diagonal) is interesting.
+        assert_almost_equal(np.triu(s[:-1, 1:]),
+                            np.triu(s_expected[:-1, 1:]))
+        assert_almost_equal(np.triu(m), np.triu(m_expected))
+
+    def test_too_few_input_arrays(self):
+        assert_raises(ValueError, multi_dot, [])
+        assert_raises(ValueError, multi_dot, [np.random.random((3, 3))])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
new file mode 100644
index 0000000000..54a67bce3e
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
@@ -0,0 +1,95 @@
+""" Test functions for linalg module
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy import linalg, arange, float64, array, dot, transpose
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_array_less
+)
+
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+
+    def test_eig_build(self, level=rlevel):
+        # Ticket #652
+        rva = array([1.03221168e+02 + 0.j,
+                     -1.91843603e+01 + 0.j,
+                     -6.04004526e-01 + 15.84422474j,
+                     -6.04004526e-01 - 15.84422474j,
+                     -1.13692929e+01 + 0.j,
+                     -6.57612485e-01 + 10.41755503j,
+                     -6.57612485e-01 - 10.41755503j,
+                     1.82126812e+01 + 0.j,
+                     1.06011014e+01 + 0.j,
+                     7.80732773e+00 + 0.j,
+                     -7.65390898e-01 + 0.j,
+                     1.51971555e-15 + 0.j,
+                     -1.51308713e-15 + 0.j])
+        a = arange(13 * 13, dtype=float64)
+        a.shape = (13, 13)
+        a = a % 17
+        va, ve = linalg.eig(a)
+        va.sort()
+        rva.sort()
+        assert_array_almost_equal(va, rva)
+
+    def test_eigh_build(self, level=rlevel):
+        # Ticket 662.
+        rvals = [68.60568999, 89.57756725, 106.67185574]
+
+        cov = array([[77.70273908,   3.51489954,  15.64602427],
+                     [3.51489954,  88.97013878,  -1.07431931],
+                     [15.64602427,  -1.07431931,  98.18223512]])
+
+        vals, vecs = linalg.eigh(cov)
+        assert_array_almost_equal(vals, rvals)
+
+    def test_svd_build(self, level=rlevel):
+        # Ticket 627.
+        a = array([[0., 1.], [1., 1.], [2., 1.], [3., 1.]])
+        m, n = a.shape
+        u, s, vh = linalg.svd(a)
+
+        b = dot(transpose(u[:, n:]), a)
+
+        assert_array_almost_equal(b, np.zeros((2, 2)))
+
+    def test_norm_vector_badarg(self):
+        # Regression for #786: Froebenius norm for vectors raises
+        # TypeError.
+        self.assertRaises(ValueError, linalg.norm, array([1., 2., 3.]), 'fro')
+
+    def test_lapack_endian(self):
+        # For bug #1482
+        a = array([[5.7998084,  -2.1825367],
+                   [-2.1825367,   9.85910595]], dtype='>f8')
+        b = array(a, dtype='<f8')
+
+        ap = linalg.cholesky(a)
+        bp = linalg.cholesky(b)
+        assert_array_equal(ap, bp)
+
+    def test_large_svd_32bit(self):
+        # See gh-4442, 64bit would require very large/slow matrices.
+        x = np.eye(1000, 66)
+        np.linalg.svd(x)
+
+    def test_svd_no_uv(self):
+        # gh-4733
+        for shape in (3, 4), (4, 4), (4, 3):
+            for t in float, complex:
+                a = np.ones(shape, dtype=t)
+                w = linalg.svd(a, compute_uv=False)
+                c = np.count_nonzero(np.absolute(w) > 0.5)
+                assert_equal(c, 1)
+                assert_equal(np.linalg.matrix_rank(a), 1)
+                assert_array_less(1, np.linalg.norm(a, ord=2))
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/__init__.py
new file mode 100644
index 0000000000..af3468b01c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/__init__.py
@@ -0,0 +1,56 @@
+"""
+=============
+Masked Arrays
+=============
+
+Arrays sometimes contain invalid or missing data.  When doing operations
+on such arrays, we wish to suppress invalid values, which is the purpose masked
+arrays fulfill (an example of typical use is given below).
+
+For example, examine the following array:
+
+>>> x = np.array([2, 1, 3, np.nan, 5, 2, 3, np.nan])
+
+When we try to calculate the mean of the data, the result is undetermined:
+
+>>> np.mean(x)
+nan
+
+The mean is calculated using roughly ``np.sum(x)/len(x)``, but since
+any number added to ``NaN`` [1]_ produces ``NaN``, this doesn't work.  Enter
+masked arrays:
+
+>>> m = np.ma.masked_array(x, np.isnan(x))
+>>> m
+masked_array(data = [2.0 1.0 3.0 -- 5.0 2.0 3.0 --],
+      mask = [False False False  True False False False  True],
+      fill_value=1e+20)
+
+Here, we construct a masked array that suppress all ``NaN`` values.  We
+may now proceed to calculate the mean of the other values:
+
+>>> np.mean(m)
+2.6666666666666665
+
+.. [1] Not-a-Number, a floating point value that is the result of an
+       invalid operation.
+
+.. moduleauthor:: Pierre Gerard-Marchant
+.. moduleauthor:: Jarrod Millman
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import core
+from .core import *
+
+from . import extras
+from .extras import *
+
+__all__ = ['core', 'extras']
+__all__ += core.__all__
+__all__ += extras.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/bench.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/bench.py
new file mode 100644
index 0000000000..0c1ee28528
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/bench.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+import timeit
+import numpy
+
+
+###############################################################################
+#                               Global variables                              #
+###############################################################################
+
+
+# Small arrays
+xs = numpy.random.uniform(-1, 1, 6).reshape(2, 3)
+ys = numpy.random.uniform(-1, 1, 6).reshape(2, 3)
+zs = xs + 1j * ys
+m1 = [[True, False, False], [False, False, True]]
+m2 = [[True, False, True], [False, False, True]]
+nmxs = numpy.ma.array(xs, mask=m1)
+nmys = numpy.ma.array(ys, mask=m2)
+nmzs = numpy.ma.array(zs, mask=m1)
+
+# Big arrays
+xl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100)
+yl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100)
+zl = xl + 1j * yl
+maskx = xl > 0.8
+masky = yl < -0.8
+nmxl = numpy.ma.array(xl, mask=maskx)
+nmyl = numpy.ma.array(yl, mask=masky)
+nmzl = numpy.ma.array(zl, mask=maskx)
+
+
+###############################################################################
+#                                 Functions                                   #
+###############################################################################
+
+
+def timer(s, v='', nloop=500, nrep=3):
+    units = ["s", "ms", "µs", "ns"]
+    scaling = [1, 1e3, 1e6, 1e9]
+    print("%s : %-50s : " % (v, s), end=' ')
+    varnames = ["%ss,nm%ss,%sl,nm%sl" % tuple(x*4) for x in 'xyz']
+    setup = 'from __main__ import numpy, ma, %s' % ','.join(varnames)
+    Timer = timeit.Timer(stmt=s, setup=setup)
+    best = min(Timer.repeat(nrep, nloop)) / nloop
+    if best > 0.0:
+        order = min(-int(numpy.floor(numpy.log10(best)) // 3), 3)
+    else:
+        order = 3
+    print("%d loops, best of %d: %.*g %s per loop" % (nloop, nrep,
+                                                      3,
+                                                      best * scaling[order],
+                                                      units[order]))
+
+
+def compare_functions_1v(func, nloop=500,
+                       xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl):
+    funcname = func.__name__
+    print("-"*50)
+    print("%s on small arrays" % funcname)
+    module, data = "numpy.ma", "nmxs"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+
+    print("%s on large arrays" % funcname)
+    module, data = "numpy.ma", "nmxl"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+    return
+
+def compare_methods(methodname, args, vars='x', nloop=500, test=True,
+                    xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl):
+    print("-"*50)
+    print("%s on small arrays" % methodname)
+    data, ver = "nm%ss" % vars, 'numpy.ma'
+    timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop)
+
+    print("%s on large arrays" % methodname)
+    data, ver = "nm%sl" % vars, 'numpy.ma'
+    timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop)
+    return
+
+def compare_functions_2v(func, nloop=500, test=True,
+                       xs=xs, nmxs=nmxs,
+                       ys=ys, nmys=nmys,
+                       xl=xl, nmxl=nmxl,
+                       yl=yl, nmyl=nmyl):
+    funcname = func.__name__
+    print("-"*50)
+    print("%s on small arrays" % funcname)
+    module, data = "numpy.ma", "nmxs,nmys"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+
+    print("%s on large arrays" % funcname)
+    module, data = "numpy.ma", "nmxl,nmyl"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+    return
+
+
+if __name__ == '__main__':
+    compare_functions_1v(numpy.sin)
+    compare_functions_1v(numpy.log)
+    compare_functions_1v(numpy.sqrt)
+
+    compare_functions_2v(numpy.multiply)
+    compare_functions_2v(numpy.divide)
+    compare_functions_2v(numpy.power)
+
+    compare_methods('ravel', '', nloop=1000)
+    compare_methods('conjugate', '', 'z', nloop=1000)
+    compare_methods('transpose', '', nloop=1000)
+    compare_methods('compressed', '', nloop=1000)
+    compare_methods('__getitem__', '0', nloop=1000)
+    compare_methods('__getitem__', '(0,0)', nloop=1000)
+    compare_methods('__getitem__', '[0,-1]', nloop=1000)
+    compare_methods('__setitem__', '0, 17', nloop=1000, test=False)
+    compare_methods('__setitem__', '(0,0), 17', nloop=1000, test=False)
+
+    print("-"*50)
+    print("__setitem__ on small arrays")
+    timer('nmxs.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma   ', nloop=10000)
+
+    print("-"*50)
+    print("__setitem__ on large arrays")
+    timer('nmxl.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma   ', nloop=10000)
+
+    print("-"*50)
+    print("where on small arrays")
+    timer('numpy.ma.where(nmxs>2,nmxs,nmys)', 'numpy.ma   ', nloop=1000)
+    print("-"*50)
+    print("where on large arrays")
+    timer('numpy.ma.where(nmxl>2,nmxl,nmyl)', 'numpy.ma   ', nloop=100)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/core.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/core.py
new file mode 100644
index 0000000000..5740771852
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/core.py
@@ -0,0 +1,7863 @@
+"""
+numpy.ma : a package to handle missing or invalid values.
+
+This package was initially written for numarray by Paul F. Dubois
+at Lawrence Livermore National Laboratory.
+In 2006, the package was completely rewritten by Pierre Gerard-Marchant
+(University of Georgia) to make the MaskedArray class a subclass of ndarray,
+and to improve support of structured arrays.
+
+
+Copyright 1999, 2000, 2001 Regents of the University of California.
+Released for unlimited redistribution.
+
+* Adapted for numpy_core 2005 by Travis Oliphant and (mainly) Paul Dubois.
+* Subclassing of the base `ndarray` 2006 by Pierre Gerard-Marchant
+  (pgmdevlist_AT_gmail_DOT_com)
+* Improvements suggested by Reggie Dugard (reggie_AT_merfinllc_DOT_com)
+
+.. moduleauthor:: Pierre Gerard-Marchant
+
+"""
+# pylint: disable-msg=E1002
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+from functools import reduce
+
+import numpy as np
+import numpy.core.umath as umath
+import numpy.core.numerictypes as ntypes
+from numpy import ndarray, amax, amin, iscomplexobj, bool_, _NoValue
+from numpy import array as narray
+from numpy.lib.function_base import angle
+from numpy.compat import (
+    getargspec, formatargspec, long, basestring, unicode, bytes, sixu
+    )
+from numpy import expand_dims as n_expand_dims
+
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+
+__all__ = [
+    'MAError', 'MaskError', 'MaskType', 'MaskedArray', 'abs', 'absolute',
+    'add', 'all', 'allclose', 'allequal', 'alltrue', 'amax', 'amin',
+    'angle', 'anom', 'anomalies', 'any', 'append', 'arange', 'arccos',
+    'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh',
+    'argmax', 'argmin', 'argsort', 'around', 'array', 'asanyarray',
+    'asarray', 'bitwise_and', 'bitwise_or', 'bitwise_xor', 'bool_', 'ceil',
+    'choose', 'clip', 'common_fill_value', 'compress', 'compressed',
+    'concatenate', 'conjugate', 'copy', 'cos', 'cosh', 'count', 'cumprod',
+    'cumsum', 'default_fill_value', 'diag', 'diagonal', 'diff', 'divide',
+    'dump', 'dumps', 'empty', 'empty_like', 'equal', 'exp', 'expand_dims',
+    'fabs', 'filled', 'fix_invalid', 'flatten_mask',
+    'flatten_structured_array', 'floor', 'floor_divide', 'fmod',
+    'frombuffer', 'fromflex', 'fromfunction', 'getdata', 'getmask',
+    'getmaskarray', 'greater', 'greater_equal', 'harden_mask', 'hypot',
+    'identity', 'ids', 'indices', 'inner', 'innerproduct', 'isMA',
+    'isMaskedArray', 'is_mask', 'is_masked', 'isarray', 'left_shift',
+    'less', 'less_equal', 'load', 'loads', 'log', 'log10', 'log2',
+    'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'make_mask',
+    'make_mask_descr', 'make_mask_none', 'mask_or', 'masked',
+    'masked_array', 'masked_equal', 'masked_greater',
+    'masked_greater_equal', 'masked_inside', 'masked_invalid',
+    'masked_less', 'masked_less_equal', 'masked_not_equal',
+    'masked_object', 'masked_outside', 'masked_print_option',
+    'masked_singleton', 'masked_values', 'masked_where', 'max', 'maximum',
+    'maximum_fill_value', 'mean', 'min', 'minimum', 'minimum_fill_value',
+    'mod', 'multiply', 'mvoid', 'ndim', 'negative', 'nomask', 'nonzero',
+    'not_equal', 'ones', 'outer', 'outerproduct', 'power', 'prod',
+    'product', 'ptp', 'put', 'putmask', 'rank', 'ravel', 'remainder',
+    'repeat', 'reshape', 'resize', 'right_shift', 'round', 'round_',
+    'set_fill_value', 'shape', 'sin', 'sinh', 'size', 'soften_mask',
+    'sometrue', 'sort', 'sqrt', 'squeeze', 'std', 'subtract', 'sum',
+    'swapaxes', 'take', 'tan', 'tanh', 'trace', 'transpose', 'true_divide',
+    'var', 'where', 'zeros',
+    ]
+
+MaskType = np.bool_
+nomask = MaskType(0)
+
+class MaskedArrayFutureWarning(FutureWarning):
+    pass
+
+
+def doc_note(initialdoc, note):
+    """
+    Adds a Notes section to an existing docstring.
+
+    """
+    if initialdoc is None:
+        return
+    if note is None:
+        return initialdoc
+    newdoc = """
+    %s
+
+    Notes
+    -----
+    %s
+    """
+    return newdoc % (initialdoc, note)
+
+
+def get_object_signature(obj):
+    """
+    Get the signature from obj
+
+    """
+    try:
+        sig = formatargspec(*getargspec(obj))
+    except TypeError:
+        sig = ''
+    return sig
+
+
+###############################################################################
+#                              Exceptions                                     #
+###############################################################################
+
+
+class MAError(Exception):
+    """
+    Class for masked array related errors.
+
+    """
+    pass
+
+
+class MaskError(MAError):
+    """
+    Class for mask related errors.
+
+    """
+    pass
+
+
+###############################################################################
+#                           Filling options                                   #
+###############################################################################
+
+
+# b: boolean - c: complex - f: floats - i: integer - O: object - S: string
+default_filler = {'b': True,
+                  'c': 1.e20 + 0.0j,
+                  'f': 1.e20,
+                  'i': 999999,
+                  'O': '?',
+                  'S': b'N/A',
+                  'u': 999999,
+                  'V': '???',
+                  'U': sixu('N/A')
+                  }
+
+# Add datetime64 and timedelta64 types
+for v in ["Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps",
+          "fs", "as"]:
+    default_filler["M8[" + v + "]"] = np.datetime64("NaT", v)
+    default_filler["m8[" + v + "]"] = np.timedelta64("NaT", v)
+
+max_filler = ntypes._minvals
+max_filler.update([(k, -np.inf) for k in [np.float32, np.float64]])
+min_filler = ntypes._maxvals
+min_filler.update([(k, +np.inf) for k in [np.float32, np.float64]])
+if 'float128' in ntypes.typeDict:
+    max_filler.update([(np.float128, -np.inf)])
+    min_filler.update([(np.float128, +np.inf)])
+
+
+def default_fill_value(obj):
+    """
+    Return the default fill value for the argument object.
+
+    The default filling value depends on the datatype of the input
+    array or the type of the input scalar:
+
+       ========  ========
+       datatype  default
+       ========  ========
+       bool      True
+       int       999999
+       float     1.e20
+       complex   1.e20+0j
+       object    '?'
+       string    'N/A'
+       ========  ========
+
+
+    Parameters
+    ----------
+    obj : ndarray, dtype or scalar
+        The array data-type or scalar for which the default fill value
+        is returned.
+
+    Returns
+    -------
+    fill_value : scalar
+        The default fill value.
+
+    Examples
+    --------
+    >>> np.ma.default_fill_value(1)
+    999999
+    >>> np.ma.default_fill_value(np.array([1.1, 2., np.pi]))
+    1e+20
+    >>> np.ma.default_fill_value(np.dtype(complex))
+    (1e+20+0j)
+
+    """
+    if hasattr(obj, 'dtype'):
+        defval = _check_fill_value(None, obj.dtype)
+    elif isinstance(obj, np.dtype):
+        if obj.subdtype:
+            defval = default_filler.get(obj.subdtype[0].kind, '?')
+        elif obj.kind in 'Mm':
+            defval = default_filler.get(obj.str[1:], '?')
+        else:
+            defval = default_filler.get(obj.kind, '?')
+    elif isinstance(obj, float):
+        defval = default_filler['f']
+    elif isinstance(obj, int) or isinstance(obj, long):
+        defval = default_filler['i']
+    elif isinstance(obj, bytes):
+        defval = default_filler['S']
+    elif isinstance(obj, unicode):
+        defval = default_filler['U']
+    elif isinstance(obj, complex):
+        defval = default_filler['c']
+    else:
+        defval = default_filler['O']
+    return defval
+
+
+def _recursive_extremum_fill_value(ndtype, extremum):
+    names = ndtype.names
+    if names:
+        deflist = []
+        for name in names:
+            fval = _recursive_extremum_fill_value(ndtype[name], extremum)
+            deflist.append(fval)
+        return tuple(deflist)
+    return extremum[ndtype]
+
+
+def minimum_fill_value(obj):
+    """
+    Return the maximum value that can be represented by the dtype of an object.
+
+    This function is useful for calculating a fill value suitable for
+    taking the minimum of an array with a given dtype.
+
+    Parameters
+    ----------
+    obj : ndarray or dtype
+        An object that can be queried for it's numeric type.
+
+    Returns
+    -------
+    val : scalar
+        The maximum representable value.
+
+    Raises
+    ------
+    TypeError
+        If `obj` isn't a suitable numeric type.
+
+    See Also
+    --------
+    maximum_fill_value : The inverse function.
+    set_fill_value : Set the filling value of a masked array.
+    MaskedArray.fill_value : Return current fill value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.int8()
+    >>> ma.minimum_fill_value(a)
+    127
+    >>> a = np.int32()
+    >>> ma.minimum_fill_value(a)
+    2147483647
+
+    An array of numeric data can also be passed.
+
+    >>> a = np.array([1, 2, 3], dtype=np.int8)
+    >>> ma.minimum_fill_value(a)
+    127
+    >>> a = np.array([1, 2, 3], dtype=np.float32)
+    >>> ma.minimum_fill_value(a)
+    inf
+
+    """
+    errmsg = "Unsuitable type for calculating minimum."
+    if hasattr(obj, 'dtype'):
+        return _recursive_extremum_fill_value(obj.dtype, min_filler)
+    elif isinstance(obj, float):
+        return min_filler[ntypes.typeDict['float_']]
+    elif isinstance(obj, int):
+        return min_filler[ntypes.typeDict['int_']]
+    elif isinstance(obj, long):
+        return min_filler[ntypes.typeDict['uint']]
+    elif isinstance(obj, np.dtype):
+        return min_filler[obj]
+    else:
+        raise TypeError(errmsg)
+
+
+def maximum_fill_value(obj):
+    """
+    Return the minimum value that can be represented by the dtype of an object.
+
+    This function is useful for calculating a fill value suitable for
+    taking the maximum of an array with a given dtype.
+
+    Parameters
+    ----------
+    obj : {ndarray, dtype}
+        An object that can be queried for it's numeric type.
+
+    Returns
+    -------
+    val : scalar
+        The minimum representable value.
+
+    Raises
+    ------
+    TypeError
+        If `obj` isn't a suitable numeric type.
+
+    See Also
+    --------
+    minimum_fill_value : The inverse function.
+    set_fill_value : Set the filling value of a masked array.
+    MaskedArray.fill_value : Return current fill value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.int8()
+    >>> ma.maximum_fill_value(a)
+    -128
+    >>> a = np.int32()
+    >>> ma.maximum_fill_value(a)
+    -2147483648
+
+    An array of numeric data can also be passed.
+
+    >>> a = np.array([1, 2, 3], dtype=np.int8)
+    >>> ma.maximum_fill_value(a)
+    -128
+    >>> a = np.array([1, 2, 3], dtype=np.float32)
+    >>> ma.maximum_fill_value(a)
+    -inf
+
+    """
+    errmsg = "Unsuitable type for calculating maximum."
+    if hasattr(obj, 'dtype'):
+        return _recursive_extremum_fill_value(obj.dtype, max_filler)
+    elif isinstance(obj, float):
+        return max_filler[ntypes.typeDict['float_']]
+    elif isinstance(obj, int):
+        return max_filler[ntypes.typeDict['int_']]
+    elif isinstance(obj, long):
+        return max_filler[ntypes.typeDict['uint']]
+    elif isinstance(obj, np.dtype):
+        return max_filler[obj]
+    else:
+        raise TypeError(errmsg)
+
+
+def _recursive_set_default_fill_value(dtypedescr):
+    deflist = []
+    for currentdescr in dtypedescr:
+        currenttype = currentdescr[1]
+        if isinstance(currenttype, list):
+            deflist.append(
+                tuple(_recursive_set_default_fill_value(currenttype)))
+        else:
+            deflist.append(default_fill_value(np.dtype(currenttype)))
+    return tuple(deflist)
+
+
+def _recursive_set_fill_value(fillvalue, dtypedescr):
+    fillvalue = np.resize(fillvalue, len(dtypedescr))
+    output_value = []
+    for (fval, descr) in zip(fillvalue, dtypedescr):
+        cdtype = descr[1]
+        if isinstance(cdtype, list):
+            output_value.append(tuple(_recursive_set_fill_value(fval, cdtype)))
+        else:
+            output_value.append(np.array(fval, dtype=cdtype).item())
+    return tuple(output_value)
+
+
+def _check_fill_value(fill_value, ndtype):
+    """
+    Private function validating the given `fill_value` for the given dtype.
+
+    If fill_value is None, it is set to the default corresponding to the dtype
+    if this latter is standard (no fields). If the datatype is flexible (named
+    fields), fill_value is set to a tuple whose elements are the default fill
+    values corresponding to each field.
+
+    If fill_value is not None, its value is forced to the given dtype.
+
+    """
+    ndtype = np.dtype(ndtype)
+    fields = ndtype.fields
+    if fill_value is None:
+        if fields:
+            descr = ndtype.descr
+            fill_value = np.array(_recursive_set_default_fill_value(descr),
+                                  dtype=ndtype,)
+        else:
+            fill_value = default_fill_value(ndtype)
+    elif fields:
+        fdtype = [(_[0], _[1]) for _ in ndtype.descr]
+        if isinstance(fill_value, (ndarray, np.void)):
+            try:
+                fill_value = np.array(fill_value, copy=False, dtype=fdtype)
+            except ValueError:
+                err_msg = "Unable to transform %s to dtype %s"
+                raise ValueError(err_msg % (fill_value, fdtype))
+        else:
+            descr = ndtype.descr
+            fill_value = np.asarray(fill_value, dtype=object)
+            fill_value = np.array(_recursive_set_fill_value(fill_value, descr),
+                                  dtype=ndtype)
+    else:
+        if isinstance(fill_value, basestring) and (ndtype.char not in 'OSVU'):
+            err_msg = "Cannot set fill value of string with array of dtype %s"
+            raise TypeError(err_msg % ndtype)
+        else:
+            # In case we want to convert 1e20 to int.
+            try:
+                fill_value = np.array(fill_value, copy=False, dtype=ndtype)
+            except OverflowError:
+                # Raise TypeError instead of OverflowError. OverflowError
+                # is seldom used, and the real problem here is that the
+                # passed fill_value is not compatible with the ndtype.
+                err_msg = "Fill value %s overflows dtype %s"
+                raise TypeError(err_msg % (fill_value, ndtype))
+    return np.array(fill_value)
+
+
+def set_fill_value(a, fill_value):
+    """
+    Set the filling value of a, if a is a masked array.
+
+    This function changes the fill value of the masked array `a` in place.
+    If `a` is not a masked array, the function returns silently, without
+    doing anything.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    fill_value : dtype
+        Filling value. A consistency test is performed to make sure
+        the value is compatible with the dtype of `a`.
+
+    Returns
+    -------
+    None
+        Nothing returned by this function.
+
+    See Also
+    --------
+    maximum_fill_value : Return the default fill value for a dtype.
+    MaskedArray.fill_value : Return current fill value.
+    MaskedArray.set_fill_value : Equivalent method.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(5)
+    >>> a
+    array([0, 1, 2, 3, 4])
+    >>> a = ma.masked_where(a < 3, a)
+    >>> a
+    masked_array(data = [-- -- -- 3 4],
+          mask = [ True  True  True False False],
+          fill_value=999999)
+    >>> ma.set_fill_value(a, -999)
+    >>> a
+    masked_array(data = [-- -- -- 3 4],
+          mask = [ True  True  True False False],
+          fill_value=-999)
+
+    Nothing happens if `a` is not a masked array.
+
+    >>> a = range(5)
+    >>> a
+    [0, 1, 2, 3, 4]
+    >>> ma.set_fill_value(a, 100)
+    >>> a
+    [0, 1, 2, 3, 4]
+    >>> a = np.arange(5)
+    >>> a
+    array([0, 1, 2, 3, 4])
+    >>> ma.set_fill_value(a, 100)
+    >>> a
+    array([0, 1, 2, 3, 4])
+
+    """
+    if isinstance(a, MaskedArray):
+        a.set_fill_value(fill_value)
+    return
+
+
+def get_fill_value(a):
+    """
+    Return the filling value of a, if any.  Otherwise, returns the
+    default filling value for that type.
+
+    """
+    if isinstance(a, MaskedArray):
+        result = a.fill_value
+    else:
+        result = default_fill_value(a)
+    return result
+
+
+def common_fill_value(a, b):
+    """
+    Return the common filling value of two masked arrays, if any.
+
+    If ``a.fill_value == b.fill_value``, return the fill value,
+    otherwise return None.
+
+    Parameters
+    ----------
+    a, b : MaskedArray
+        The masked arrays for which to compare fill values.
+
+    Returns
+    -------
+    fill_value : scalar or None
+        The common fill value, or None.
+
+    Examples
+    --------
+    >>> x = np.ma.array([0, 1.], fill_value=3)
+    >>> y = np.ma.array([0, 1.], fill_value=3)
+    >>> np.ma.common_fill_value(x, y)
+    3.0
+
+    """
+    t1 = get_fill_value(a)
+    t2 = get_fill_value(b)
+    if t1 == t2:
+        return t1
+    return None
+
+
+def filled(a, fill_value=None):
+    """
+    Return input as an array with masked data replaced by a fill value.
+
+    If `a` is not a `MaskedArray`, `a` itself is returned.
+    If `a` is a `MaskedArray` and `fill_value` is None, `fill_value` is set to
+    ``a.fill_value``.
+
+    Parameters
+    ----------
+    a : MaskedArray or array_like
+        An input object.
+    fill_value : scalar, optional
+        Filling value. Default is None.
+
+    Returns
+    -------
+    a : ndarray
+        The filled array.
+
+    See Also
+    --------
+    compressed
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
+    ...                                                   [1, 0, 0],
+    ...                                                   [0, 0, 0]])
+    >>> x.filled()
+    array([[999999,      1,      2],
+           [999999,      4,      5],
+           [     6,      7,      8]])
+
+    """
+    if hasattr(a, 'filled'):
+        return a.filled(fill_value)
+    elif isinstance(a, ndarray):
+        # Should we check for contiguity ? and a.flags['CONTIGUOUS']:
+        return a
+    elif isinstance(a, dict):
+        return np.array(a, 'O')
+    else:
+        return np.array(a)
+
+
+def get_masked_subclass(*arrays):
+    """
+    Return the youngest subclass of MaskedArray from a list of (masked) arrays.
+
+    In case of siblings, the first listed takes over.
+
+    """
+    if len(arrays) == 1:
+        arr = arrays[0]
+        if isinstance(arr, MaskedArray):
+            rcls = type(arr)
+        else:
+            rcls = MaskedArray
+    else:
+        arrcls = [type(a) for a in arrays]
+        rcls = arrcls[0]
+        if not issubclass(rcls, MaskedArray):
+            rcls = MaskedArray
+        for cls in arrcls[1:]:
+            if issubclass(cls, rcls):
+                rcls = cls
+    # Don't return MaskedConstant as result: revert to MaskedArray
+    if rcls.__name__ == 'MaskedConstant':
+        return MaskedArray
+    return rcls
+
+
+def getdata(a, subok=True):
+    """
+    Return the data of a masked array as an ndarray.
+
+    Return the data of `a` (if any) as an ndarray if `a` is a ``MaskedArray``,
+    else return `a` as a ndarray or subclass (depending on `subok`) if not.
+
+    Parameters
+    ----------
+    a : array_like
+        Input ``MaskedArray``, alternatively a ndarray or a subclass thereof.
+    subok : bool
+        Whether to force the output to be a `pure` ndarray (False) or to
+        return a subclass of ndarray if appropriate (True, default).
+
+    See Also
+    --------
+    getmask : Return the mask of a masked array, or nomask.
+    getmaskarray : Return the mask of a masked array, or full array of False.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getdata(a)
+    array([[1, 2],
+           [3, 4]])
+
+    Equivalently use the ``MaskedArray`` `data` attribute.
+
+    >>> a.data
+    array([[1, 2],
+           [3, 4]])
+
+    """
+    try:
+        data = a._data
+    except AttributeError:
+        data = np.array(a, copy=False, subok=subok)
+    if not subok:
+        return data.view(ndarray)
+    return data
+
+
+get_data = getdata
+
+
+def fix_invalid(a, mask=nomask, copy=True, fill_value=None):
+    """
+    Return input with invalid data masked and replaced by a fill value.
+
+    Invalid data means values of `nan`, `inf`, etc.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, a (subclass of) ndarray.
+    mask : sequence, optional
+        Mask. Must be convertible to an array of booleans with the same
+        shape as `data`. True indicates a masked (i.e. invalid) data.
+    copy : bool, optional
+        Whether to use a copy of `a` (True) or to fix `a` in place (False).
+        Default is True.
+    fill_value : scalar, optional
+        Value used for fixing invalid data. Default is None, in which case
+        the ``a.fill_value`` is used.
+
+    Returns
+    -------
+    b : MaskedArray
+        The input array with invalid entries fixed.
+
+    Notes
+    -----
+    A copy is performed by default.
+
+    Examples
+    --------
+    >>> x = np.ma.array([1., -1, np.nan, np.inf], mask=[1] + [0]*3)
+    >>> x
+    masked_array(data = [-- -1.0 nan inf],
+                 mask = [ True False False False],
+           fill_value = 1e+20)
+    >>> np.ma.fix_invalid(x)
+    masked_array(data = [-- -1.0 -- --],
+                 mask = [ True False  True  True],
+           fill_value = 1e+20)
+
+    >>> fixed = np.ma.fix_invalid(x)
+    >>> fixed.data
+    array([  1.00000000e+00,  -1.00000000e+00,   1.00000000e+20,
+             1.00000000e+20])
+    >>> x.data
+    array([  1.,  -1.,  NaN,  Inf])
+
+    """
+    a = masked_array(a, copy=copy, mask=mask, subok=True)
+    invalid = np.logical_not(np.isfinite(a._data))
+    if not invalid.any():
+        return a
+    a._mask |= invalid
+    if fill_value is None:
+        fill_value = a.fill_value
+    a._data[invalid] = fill_value
+    return a
+
+
+###############################################################################
+#                                  Ufuncs                                     #
+###############################################################################
+
+
+ufunc_domain = {}
+ufunc_fills = {}
+
+
+class _DomainCheckInterval:
+    """
+    Define a valid interval, so that :
+
+    ``domain_check_interval(a,b)(x) == True`` where
+    ``x < a`` or ``x > b``.
+
+    """
+
+    def __init__(self, a, b):
+        "domain_check_interval(a,b)(x) = true where x < a or y > b"
+        if (a > b):
+            (a, b) = (b, a)
+        self.a = a
+        self.b = b
+
+    def __call__(self, x):
+        "Execute the call behavior."
+        return umath.logical_or(umath.greater(x, self.b),
+                                umath.less(x, self.a))
+
+
+class _DomainTan:
+    """
+    Define a valid interval for the `tan` function, so that:
+
+    ``domain_tan(eps) = True`` where ``abs(cos(x)) < eps``
+
+    """
+
+    def __init__(self, eps):
+        "domain_tan(eps) = true where abs(cos(x)) < eps)"
+        self.eps = eps
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less(umath.absolute(umath.cos(x)), self.eps)
+
+
+class _DomainSafeDivide:
+    """
+    Define a domain for safe division.
+
+    """
+
+    def __init__(self, tolerance=None):
+        self.tolerance = tolerance
+
+    def __call__(self, a, b):
+        # Delay the selection of the tolerance to here in order to reduce numpy
+        # import times. The calculation of these parameters is a substantial
+        # component of numpy's import time.
+        if self.tolerance is None:
+            self.tolerance = np.finfo(float).tiny
+        # don't call ma ufuncs from __array_wrap__ which would fail for scalars
+        a, b = np.asarray(a), np.asarray(b)
+        return umath.absolute(a) * self.tolerance >= umath.absolute(b)
+
+
+class _DomainGreater:
+    """
+    DomainGreater(v)(x) is True where x <= v.
+
+    """
+
+    def __init__(self, critical_value):
+        "DomainGreater(v)(x) = true where x <= v"
+        self.critical_value = critical_value
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less_equal(x, self.critical_value)
+
+
+class _DomainGreaterEqual:
+    """
+    DomainGreaterEqual(v)(x) is True where x < v.
+
+    """
+
+    def __init__(self, critical_value):
+        "DomainGreaterEqual(v)(x) = true where x < v"
+        self.critical_value = critical_value
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less(x, self.critical_value)
+
+
+class _MaskedUnaryOperation:
+    """
+    Defines masked version of unary operations, where invalid values are
+    pre-masked.
+
+    Parameters
+    ----------
+    mufunc : callable
+        The function for which to define a masked version. Made available
+        as ``_MaskedUnaryOperation.f``.
+    fill : scalar, optional
+        Filling value, default is 0.
+    domain : class instance
+        Domain for the function. Should be one of the ``_Domain*``
+        classes. Default is None.
+
+    """
+
+    def __init__(self, mufunc, fill=0, domain=None):
+        self.f = mufunc
+        self.fill = fill
+        self.domain = domain
+        self.__doc__ = getattr(mufunc, "__doc__", str(mufunc))
+        self.__name__ = getattr(mufunc, "__name__", str(mufunc))
+        ufunc_domain[mufunc] = domain
+        ufunc_fills[mufunc] = fill
+
+    def __call__(self, a, *args, **kwargs):
+        """
+        Execute the call behavior.
+
+        """
+        d = getdata(a)
+        # Deal with domain
+        if self.domain is not None:
+            # Case 1.1. : Domained function
+            with np.errstate(divide='ignore', invalid='ignore'):
+                result = self.f(d, *args, **kwargs)
+            # Make a mask
+            m = ~umath.isfinite(result)
+            m |= self.domain(d)
+            m |= getmask(a)
+        else:
+            # Case 1.2. : Function without a domain
+            # Get the result and the mask
+            result = self.f(d, *args, **kwargs)
+            m = getmask(a)
+
+        if not result.ndim:
+            # Case 2.1. : The result is scalarscalar
+            if m:
+                return masked
+            return result
+
+        if m is not nomask:
+            # Case 2.2. The result is an array
+            # We need to fill the invalid data back w/ the input Now,
+            # that's plain silly: in C, we would just skip the element and
+            # keep the original, but we do have to do it that way in Python
+
+            # In case result has a lower dtype than the inputs (as in
+            # equal)
+            try:
+                np.copyto(result, d, where=m)
+            except TypeError:
+                pass
+        # Transform to
+        masked_result = result.view(get_masked_subclass(a))
+        masked_result._mask = m
+        masked_result._update_from(a)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of %s. [Invalid values are masked]" % str(self.f)
+
+
+class _MaskedBinaryOperation:
+    """
+    Define masked version of binary operations, where invalid
+    values are pre-masked.
+
+    Parameters
+    ----------
+    mbfunc : function
+        The function for which to define a masked version. Made available
+        as ``_MaskedBinaryOperation.f``.
+    domain : class instance
+        Default domain for the function. Should be one of the ``_Domain*``
+        classes. Default is None.
+    fillx : scalar, optional
+        Filling value for the first argument, default is 0.
+    filly : scalar, optional
+        Filling value for the second argument, default is 0.
+
+    """
+
+    def __init__(self, mbfunc, fillx=0, filly=0):
+        """
+        abfunc(fillx, filly) must be defined.
+
+        abfunc(x, filly) = x for all x to enable reduce.
+
+        """
+        self.f = mbfunc
+        self.fillx = fillx
+        self.filly = filly
+        self.__doc__ = getattr(mbfunc, "__doc__", str(mbfunc))
+        self.__name__ = getattr(mbfunc, "__name__", str(mbfunc))
+        ufunc_domain[mbfunc] = None
+        ufunc_fills[mbfunc] = (fillx, filly)
+
+    def __call__(self, a, b, *args, **kwargs):
+        """
+        Execute the call behavior.
+
+        """
+        # Get the data, as ndarray
+        (da, db) = (getdata(a), getdata(b))
+        # Get the result
+        with np.errstate():
+            np.seterr(divide='ignore', invalid='ignore')
+            result = self.f(da, db, *args, **kwargs)
+        # Get the mask for the result
+        (ma, mb) = (getmask(a), getmask(b))
+        if ma is nomask:
+            if mb is nomask:
+                m = nomask
+            else:
+                m = umath.logical_or(getmaskarray(a), mb)
+        elif mb is nomask:
+            m = umath.logical_or(ma, getmaskarray(b))
+        else:
+            m = umath.logical_or(ma, mb)
+
+        # Case 1. : scalar
+        if not result.ndim:
+            if m:
+                return masked
+            return result
+
+        # Case 2. : array
+        # Revert result to da where masked
+        if m is not nomask and m.any():
+            # any errors, just abort; impossible to guarantee masked values
+            try:
+                np.copyto(result, 0, casting='unsafe', where=m)
+                # avoid using "*" since this may be overlaid
+                masked_da = umath.multiply(m, da)
+                # only add back if it can be cast safely
+                if np.can_cast(masked_da.dtype, result.dtype, casting='safe'):
+                    result += masked_da
+            except:
+                pass
+
+        # Transforms to a (subclass of) MaskedArray
+        masked_result = result.view(get_masked_subclass(a, b))
+        masked_result._mask = m
+        if isinstance(a, MaskedArray):
+            masked_result._update_from(a)
+        elif isinstance(b, MaskedArray):
+            masked_result._update_from(b)
+        return masked_result
+
+    def reduce(self, target, axis=0, dtype=None):
+        """
+        Reduce `target` along the given `axis`.
+
+        """
+        tclass = get_masked_subclass(target)
+        m = getmask(target)
+        t = filled(target, self.filly)
+        if t.shape == ():
+            t = t.reshape(1)
+            if m is not nomask:
+                m = make_mask(m, copy=1)
+                m.shape = (1,)
+
+        if m is nomask:
+            tr = self.f.reduce(t, axis)
+            mr = nomask
+        else:
+            tr = self.f.reduce(t, axis, dtype=dtype or t.dtype)
+            mr = umath.logical_and.reduce(m, axis)
+
+        if not tr.shape:
+            if mr:
+                return masked
+            else:
+                return tr
+        masked_tr = tr.view(tclass)
+        masked_tr._mask = mr
+        return masked_tr
+
+    def outer(self, a, b):
+        """
+        Return the function applied to the outer product of a and b.
+
+        """
+        (da, db) = (getdata(a), getdata(b))
+        d = self.f.outer(da, db)
+        ma = getmask(a)
+        mb = getmask(b)
+        if ma is nomask and mb is nomask:
+            m = nomask
+        else:
+            ma = getmaskarray(a)
+            mb = getmaskarray(b)
+            m = umath.logical_or.outer(ma, mb)
+        if (not m.ndim) and m:
+            return masked
+        if m is not nomask:
+            np.copyto(d, da, where=m)
+        if not d.shape:
+            return d
+        masked_d = d.view(get_masked_subclass(a, b))
+        masked_d._mask = m
+        return masked_d
+
+    def accumulate(self, target, axis=0):
+        """Accumulate `target` along `axis` after filling with y fill
+        value.
+
+        """
+        tclass = get_masked_subclass(target)
+        t = filled(target, self.filly)
+        result = self.f.accumulate(t, axis)
+        masked_result = result.view(tclass)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of " + str(self.f)
+
+
+class _DomainedBinaryOperation:
+    """
+    Define binary operations that have a domain, like divide.
+
+    They have no reduce, outer or accumulate.
+
+    Parameters
+    ----------
+    mbfunc : function
+        The function for which to define a masked version. Made available
+        as ``_DomainedBinaryOperation.f``.
+    domain : class instance
+        Default domain for the function. Should be one of the ``_Domain*``
+        classes.
+    fillx : scalar, optional
+        Filling value for the first argument, default is 0.
+    filly : scalar, optional
+        Filling value for the second argument, default is 0.
+
+    """
+
+    def __init__(self, dbfunc, domain, fillx=0, filly=0):
+        """abfunc(fillx, filly) must be defined.
+           abfunc(x, filly) = x for all x to enable reduce.
+        """
+        self.f = dbfunc
+        self.domain = domain
+        self.fillx = fillx
+        self.filly = filly
+        self.__doc__ = getattr(dbfunc, "__doc__", str(dbfunc))
+        self.__name__ = getattr(dbfunc, "__name__", str(dbfunc))
+        ufunc_domain[dbfunc] = domain
+        ufunc_fills[dbfunc] = (fillx, filly)
+
+    def __call__(self, a, b, *args, **kwargs):
+        "Execute the call behavior."
+        # Get the data
+        (da, db) = (getdata(a), getdata(b))
+        # Get the result
+        with np.errstate(divide='ignore', invalid='ignore'):
+            result = self.f(da, db, *args, **kwargs)
+        # Get the mask as a combination of the source masks and invalid
+        m = ~umath.isfinite(result)
+        m |= getmask(a)
+        m |= getmask(b)
+        # Apply the domain
+        domain = ufunc_domain.get(self.f, None)
+        if domain is not None:
+            m |= filled(domain(da, db), True)
+        # Take care of the scalar case first
+        if (not m.ndim):
+            if m:
+                return masked
+            else:
+                return result
+        # When the mask is True, put back da if possible
+        # any errors, just abort; impossible to guarantee masked values
+        try:
+            np.copyto(result, 0, casting='unsafe', where=m)
+            # avoid using "*" since this may be overlaid
+            masked_da = umath.multiply(m, da)
+            # only add back if it can be cast safely
+            if np.can_cast(masked_da.dtype, result.dtype, casting='safe'):
+                result += masked_da
+        except:
+            pass
+
+        # Transforms to a (subclass of) MaskedArray
+        masked_result = result.view(get_masked_subclass(a, b))
+        masked_result._mask = m
+        if isinstance(a, MaskedArray):
+            masked_result._update_from(a)
+        elif isinstance(b, MaskedArray):
+            masked_result._update_from(b)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of " + str(self.f)
+
+
+# Unary ufuncs
+exp = _MaskedUnaryOperation(umath.exp)
+conjugate = _MaskedUnaryOperation(umath.conjugate)
+sin = _MaskedUnaryOperation(umath.sin)
+cos = _MaskedUnaryOperation(umath.cos)
+tan = _MaskedUnaryOperation(umath.tan)
+arctan = _MaskedUnaryOperation(umath.arctan)
+arcsinh = _MaskedUnaryOperation(umath.arcsinh)
+sinh = _MaskedUnaryOperation(umath.sinh)
+cosh = _MaskedUnaryOperation(umath.cosh)
+tanh = _MaskedUnaryOperation(umath.tanh)
+abs = absolute = _MaskedUnaryOperation(umath.absolute)
+angle = _MaskedUnaryOperation(angle)  # from numpy.lib.function_base
+fabs = _MaskedUnaryOperation(umath.fabs)
+negative = _MaskedUnaryOperation(umath.negative)
+floor = _MaskedUnaryOperation(umath.floor)
+ceil = _MaskedUnaryOperation(umath.ceil)
+around = _MaskedUnaryOperation(np.round_)
+logical_not = _MaskedUnaryOperation(umath.logical_not)
+
+# Domained unary ufuncs
+sqrt = _MaskedUnaryOperation(umath.sqrt, 0.0,
+                             _DomainGreaterEqual(0.0))
+log = _MaskedUnaryOperation(umath.log, 1.0,
+                            _DomainGreater(0.0))
+log2 = _MaskedUnaryOperation(umath.log2, 1.0,
+                             _DomainGreater(0.0))
+log10 = _MaskedUnaryOperation(umath.log10, 1.0,
+                              _DomainGreater(0.0))
+tan = _MaskedUnaryOperation(umath.tan, 0.0,
+                            _DomainTan(1e-35))
+arcsin = _MaskedUnaryOperation(umath.arcsin, 0.0,
+                               _DomainCheckInterval(-1.0, 1.0))
+arccos = _MaskedUnaryOperation(umath.arccos, 0.0,
+                               _DomainCheckInterval(-1.0, 1.0))
+arccosh = _MaskedUnaryOperation(umath.arccosh, 1.0,
+                                _DomainGreaterEqual(1.0))
+arctanh = _MaskedUnaryOperation(umath.arctanh, 0.0,
+                                _DomainCheckInterval(-1.0 + 1e-15, 1.0 - 1e-15))
+
+# Binary ufuncs
+add = _MaskedBinaryOperation(umath.add)
+subtract = _MaskedBinaryOperation(umath.subtract)
+multiply = _MaskedBinaryOperation(umath.multiply, 1, 1)
+arctan2 = _MaskedBinaryOperation(umath.arctan2, 0.0, 1.0)
+equal = _MaskedBinaryOperation(umath.equal)
+equal.reduce = None
+not_equal = _MaskedBinaryOperation(umath.not_equal)
+not_equal.reduce = None
+less_equal = _MaskedBinaryOperation(umath.less_equal)
+less_equal.reduce = None
+greater_equal = _MaskedBinaryOperation(umath.greater_equal)
+greater_equal.reduce = None
+less = _MaskedBinaryOperation(umath.less)
+less.reduce = None
+greater = _MaskedBinaryOperation(umath.greater)
+greater.reduce = None
+logical_and = _MaskedBinaryOperation(umath.logical_and)
+alltrue = _MaskedBinaryOperation(umath.logical_and, 1, 1).reduce
+logical_or = _MaskedBinaryOperation(umath.logical_or)
+sometrue = logical_or.reduce
+logical_xor = _MaskedBinaryOperation(umath.logical_xor)
+bitwise_and = _MaskedBinaryOperation(umath.bitwise_and)
+bitwise_or = _MaskedBinaryOperation(umath.bitwise_or)
+bitwise_xor = _MaskedBinaryOperation(umath.bitwise_xor)
+hypot = _MaskedBinaryOperation(umath.hypot)
+
+# Domained binary ufuncs
+divide = _DomainedBinaryOperation(umath.divide, _DomainSafeDivide(), 0, 1)
+true_divide = _DomainedBinaryOperation(umath.true_divide,
+                                       _DomainSafeDivide(), 0, 1)
+floor_divide = _DomainedBinaryOperation(umath.floor_divide,
+                                        _DomainSafeDivide(), 0, 1)
+remainder = _DomainedBinaryOperation(umath.remainder,
+                                     _DomainSafeDivide(), 0, 1)
+fmod = _DomainedBinaryOperation(umath.fmod, _DomainSafeDivide(), 0, 1)
+mod = _DomainedBinaryOperation(umath.mod, _DomainSafeDivide(), 0, 1)
+
+
+###############################################################################
+#                        Mask creation functions                              #
+###############################################################################
+
+
+def _recursive_make_descr(datatype, newtype=bool_):
+    "Private function allowing recursion in make_descr."
+    # Do we have some name fields ?
+    if datatype.names:
+        descr = []
+        for name in datatype.names:
+            field = datatype.fields[name]
+            if len(field) == 3:
+                # Prepend the title to the name
+                name = (field[-1], name)
+            descr.append((name, _recursive_make_descr(field[0], newtype)))
+        return descr
+    # Is this some kind of composite a la (np.float,2)
+    elif datatype.subdtype:
+        mdescr = list(datatype.subdtype)
+        mdescr[0] = _recursive_make_descr(datatype.subdtype[0], newtype)
+        return tuple(mdescr)
+    else:
+        return newtype
+
+
+def make_mask_descr(ndtype):
+    """
+    Construct a dtype description list from a given dtype.
+
+    Returns a new dtype object, with the type of all fields in `ndtype` to a
+    boolean type. Field names are not altered.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        The dtype to convert.
+
+    Returns
+    -------
+    result : dtype
+        A dtype that looks like `ndtype`, the type of all fields is boolean.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> dtype = np.dtype({'names':['foo', 'bar'],
+                          'formats':[np.float32, np.int]})
+    >>> dtype
+    dtype([('foo', '<f4'), ('bar', '<i4')])
+    >>> ma.make_mask_descr(dtype)
+    dtype([('foo', '|b1'), ('bar', '|b1')])
+    >>> ma.make_mask_descr(np.float32)
+    <type 'numpy.bool_'>
+
+    """
+    # Make sure we do have a dtype
+    if not isinstance(ndtype, np.dtype):
+        ndtype = np.dtype(ndtype)
+    return np.dtype(_recursive_make_descr(ndtype, np.bool))
+
+
+def getmask(a):
+    """
+    Return the mask of a masked array, or nomask.
+
+    Return the mask of `a` as an ndarray if `a` is a `MaskedArray` and the
+    mask is not `nomask`, else return `nomask`. To guarantee a full array
+    of booleans of the same shape as a, use `getmaskarray`.
+
+    Parameters
+    ----------
+    a : array_like
+        Input `MaskedArray` for which the mask is required.
+
+    See Also
+    --------
+    getdata : Return the data of a masked array as an ndarray.
+    getmaskarray : Return the mask of a masked array, or full array of False.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getmask(a)
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Equivalently use the `MaskedArray` `mask` attribute.
+
+    >>> a.mask
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Result when mask == `nomask`
+
+    >>> b = ma.masked_array([[1,2],[3,4]])
+    >>> b
+    masked_array(data =
+     [[1 2]
+     [3 4]],
+          mask =
+     False,
+          fill_value=999999)
+    >>> ma.nomask
+    False
+    >>> ma.getmask(b) == ma.nomask
+    True
+    >>> b.mask == ma.nomask
+    True
+
+    """
+    return getattr(a, '_mask', nomask)
+
+
+get_mask = getmask
+
+
+def getmaskarray(arr):
+    """
+    Return the mask of a masked array, or full boolean array of False.
+
+    Return the mask of `arr` as an ndarray if `arr` is a `MaskedArray` and
+    the mask is not `nomask`, else return a full boolean array of False of
+    the same shape as `arr`.
+
+    Parameters
+    ----------
+    arr : array_like
+        Input `MaskedArray` for which the mask is required.
+
+    See Also
+    --------
+    getmask : Return the mask of a masked array, or nomask.
+    getdata : Return the data of a masked array as an ndarray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getmaskarray(a)
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Result when mask == ``nomask``
+
+    >>> b = ma.masked_array([[1,2],[3,4]])
+    >>> b
+    masked_array(data =
+     [[1 2]
+     [3 4]],
+          mask =
+     False,
+          fill_value=999999)
+    >>> >ma.getmaskarray(b)
+    array([[False, False],
+           [False, False]], dtype=bool)
+
+    """
+    mask = getmask(arr)
+    if mask is nomask:
+        mask = make_mask_none(np.shape(arr), getattr(arr, 'dtype', None))
+    return mask
+
+
+def is_mask(m):
+    """
+    Return True if m is a valid, standard mask.
+
+    This function does not check the contents of the input, only that the
+    type is MaskType. In particular, this function returns False if the
+    mask has a flexible dtype.
+
+    Parameters
+    ----------
+    m : array_like
+        Array to test.
+
+    Returns
+    -------
+    result : bool
+        True if `m.dtype.type` is MaskType, False otherwise.
+
+    See Also
+    --------
+    isMaskedArray : Test whether input is an instance of MaskedArray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> m = ma.masked_equal([0, 1, 0, 2, 3], 0)
+    >>> m
+    masked_array(data = [-- 1 -- 2 3],
+          mask = [ True False  True False False],
+          fill_value=999999)
+    >>> ma.is_mask(m)
+    False
+    >>> ma.is_mask(m.mask)
+    True
+
+    Input must be an ndarray (or have similar attributes)
+    for it to be considered a valid mask.
+
+    >>> m = [False, True, False]
+    >>> ma.is_mask(m)
+    False
+    >>> m = np.array([False, True, False])
+    >>> m
+    array([False,  True, False], dtype=bool)
+    >>> ma.is_mask(m)
+    True
+
+    Arrays with complex dtypes don't return True.
+
+    >>> dtype = np.dtype({'names':['monty', 'pithon'],
+                          'formats':[np.bool, np.bool]})
+    >>> dtype
+    dtype([('monty', '|b1'), ('pithon', '|b1')])
+    >>> m = np.array([(True, False), (False, True), (True, False)],
+                     dtype=dtype)
+    >>> m
+    array([(True, False), (False, True), (True, False)],
+          dtype=[('monty', '|b1'), ('pithon', '|b1')])
+    >>> ma.is_mask(m)
+    False
+
+    """
+    try:
+        return m.dtype.type is MaskType
+    except AttributeError:
+        return False
+
+
+def make_mask(m, copy=False, shrink=True, dtype=MaskType):
+    """
+    Create a boolean mask from an array.
+
+    Return `m` as a boolean mask, creating a copy if necessary or requested.
+    The function can accept any sequence that is convertible to integers,
+    or ``nomask``.  Does not require that contents must be 0s and 1s, values
+    of 0 are interepreted as False, everything else as True.
+
+    Parameters
+    ----------
+    m : array_like
+        Potential mask.
+    copy : bool, optional
+        Whether to return a copy of `m` (True) or `m` itself (False).
+    shrink : bool, optional
+        Whether to shrink `m` to ``nomask`` if all its values are False.
+    dtype : dtype, optional
+        Data-type of the output mask. By default, the output mask has a
+        dtype of MaskType (bool). If the dtype is flexible, each field has
+        a boolean dtype. This is ignored when `m` is ``nomask``, in which
+        case ``nomask`` is always returned.
+
+    Returns
+    -------
+    result : ndarray
+        A boolean mask derived from `m`.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> m = [True, False, True, True]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+    >>> m = [1, 0, 1, 1]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+    >>> m = [1, 0, 2, -3]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+
+    Effect of the `shrink` parameter.
+
+    >>> m = np.zeros(4)
+    >>> m
+    array([ 0.,  0.,  0.,  0.])
+    >>> ma.make_mask(m)
+    False
+    >>> ma.make_mask(m, shrink=False)
+    array([False, False, False, False], dtype=bool)
+
+    Using a flexible `dtype`.
+
+    >>> m = [1, 0, 1, 1]
+    >>> n = [0, 1, 0, 0]
+    >>> arr = []
+    >>> for man, mouse in zip(m, n):
+    ...     arr.append((man, mouse))
+    >>> arr
+    [(1, 0), (0, 1), (1, 0), (1, 0)]
+    >>> dtype = np.dtype({'names':['man', 'mouse'],
+                          'formats':[np.int, np.int]})
+    >>> arr = np.array(arr, dtype=dtype)
+    >>> arr
+    array([(1, 0), (0, 1), (1, 0), (1, 0)],
+          dtype=[('man', '<i4'), ('mouse', '<i4')])
+    >>> ma.make_mask(arr, dtype=dtype)
+    array([(True, False), (False, True), (True, False), (True, False)],
+          dtype=[('man', '|b1'), ('mouse', '|b1')])
+
+    """
+    if m is nomask:
+        return nomask
+    elif isinstance(m, ndarray):
+        # We won't return after this point to make sure we can shrink the mask
+        # Fill the mask in case there are missing data
+        m = filled(m, True)
+        # Make sure the input dtype is valid
+        dtype = make_mask_descr(dtype)
+        if m.dtype == dtype:
+            if copy:
+                result = m.copy()
+            else:
+                result = m
+        else:
+            result = np.array(m, dtype=dtype, copy=copy)
+    else:
+        result = np.array(filled(m, True), dtype=MaskType)
+    # Bas les masques !
+    if shrink and (not result.dtype.names) and (not result.any()):
+        return nomask
+    else:
+        return result
+
+
+def make_mask_none(newshape, dtype=None):
+    """
+    Return a boolean mask of the given shape, filled with False.
+
+    This function returns a boolean ndarray with all entries False, that can
+    be used in common mask manipulations. If a complex dtype is specified, the
+    type of each field is converted to a boolean type.
+
+    Parameters
+    ----------
+    newshape : tuple
+        A tuple indicating the shape of the mask.
+    dtype : {None, dtype}, optional
+        If None, use a MaskType instance. Otherwise, use a new datatype with
+        the same fields as `dtype`, converted to boolean types.
+
+    Returns
+    -------
+    result : ndarray
+        An ndarray of appropriate shape and dtype, filled with False.
+
+    See Also
+    --------
+    make_mask : Create a boolean mask from an array.
+    make_mask_descr : Construct a dtype description list from a given dtype.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> ma.make_mask_none((3,))
+    array([False, False, False], dtype=bool)
+
+    Defining a more complex dtype.
+
+    >>> dtype = np.dtype({'names':['foo', 'bar'],
+                          'formats':[np.float32, np.int]})
+    >>> dtype
+    dtype([('foo', '<f4'), ('bar', '<i4')])
+    >>> ma.make_mask_none((3,), dtype=dtype)
+    array([(False, False), (False, False), (False, False)],
+          dtype=[('foo', '|b1'), ('bar', '|b1')])
+
+    """
+    if dtype is None:
+        result = np.zeros(newshape, dtype=MaskType)
+    else:
+        result = np.zeros(newshape, dtype=make_mask_descr(dtype))
+    return result
+
+
+def mask_or(m1, m2, copy=False, shrink=True):
+    """
+    Combine two masks with the ``logical_or`` operator.
+
+    The result may be a view on `m1` or `m2` if the other is `nomask`
+    (i.e. False).
+
+    Parameters
+    ----------
+    m1, m2 : array_like
+        Input masks.
+    copy : bool, optional
+        If copy is False and one of the inputs is `nomask`, return a view
+        of the other input mask. Defaults to False.
+    shrink : bool, optional
+        Whether to shrink the output to `nomask` if all its values are
+        False. Defaults to True.
+
+    Returns
+    -------
+    mask : output mask
+        The result masks values that are masked in either `m1` or `m2`.
+
+    Raises
+    ------
+    ValueError
+        If `m1` and `m2` have different flexible dtypes.
+
+    Examples
+    --------
+    >>> m1 = np.ma.make_mask([0, 1, 1, 0])
+    >>> m2 = np.ma.make_mask([1, 0, 0, 0])
+    >>> np.ma.mask_or(m1, m2)
+    array([ True,  True,  True, False], dtype=bool)
+
+    """
+
+    def _recursive_mask_or(m1, m2, newmask):
+        names = m1.dtype.names
+        for name in names:
+            current1 = m1[name]
+            if current1.dtype.names:
+                _recursive_mask_or(current1, m2[name], newmask[name])
+            else:
+                umath.logical_or(current1, m2[name], newmask[name])
+        return
+
+    if (m1 is nomask) or (m1 is False):
+        dtype = getattr(m2, 'dtype', MaskType)
+        return make_mask(m2, copy=copy, shrink=shrink, dtype=dtype)
+    if (m2 is nomask) or (m2 is False):
+        dtype = getattr(m1, 'dtype', MaskType)
+        return make_mask(m1, copy=copy, shrink=shrink, dtype=dtype)
+    if m1 is m2 and is_mask(m1):
+        return m1
+    (dtype1, dtype2) = (getattr(m1, 'dtype', None), getattr(m2, 'dtype', None))
+    if (dtype1 != dtype2):
+        raise ValueError("Incompatible dtypes '%s'<>'%s'" % (dtype1, dtype2))
+    if dtype1.names:
+        newmask = np.empty_like(m1)
+        _recursive_mask_or(m1, m2, newmask)
+        return newmask
+    return make_mask(umath.logical_or(m1, m2), copy=copy, shrink=shrink)
+
+
+def flatten_mask(mask):
+    """
+    Returns a completely flattened version of the mask, where nested fields
+    are collapsed.
+
+    Parameters
+    ----------
+    mask : array_like
+        Input array, which will be interpreted as booleans.
+
+    Returns
+    -------
+    flattened_mask : ndarray of bools
+        The flattened input.
+
+    Examples
+    --------
+    >>> mask = np.array([0, 0, 1], dtype=np.bool)
+    >>> flatten_mask(mask)
+    array([False, False,  True], dtype=bool)
+
+    >>> mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
+    >>> flatten_mask(mask)
+    array([False, False, False,  True], dtype=bool)
+
+    >>> mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
+    >>> mask = np.array([(0, (0, 0)), (0, (0, 1))], dtype=mdtype)
+    >>> flatten_mask(mask)
+    array([False, False, False, False, False,  True], dtype=bool)
+
+    """
+
+    def _flatmask(mask):
+        "Flatten the mask and returns a (maybe nested) sequence of booleans."
+        mnames = mask.dtype.names
+        if mnames:
+            return [flatten_mask(mask[name]) for name in mnames]
+        else:
+            return mask
+
+    def _flatsequence(sequence):
+        "Generates a flattened version of the sequence."
+        try:
+            for element in sequence:
+                if hasattr(element, '__iter__'):
+                    for f in _flatsequence(element):
+                        yield f
+                else:
+                    yield element
+        except TypeError:
+            yield sequence
+
+    mask = np.asarray(mask)
+    flattened = _flatsequence(_flatmask(mask))
+    return np.array([_ for _ in flattened], dtype=bool)
+
+
+def _check_mask_axis(mask, axis):
+    "Check whether there are masked values along the given axis"
+    if mask is not nomask:
+        return mask.all(axis=axis)
+    return nomask
+
+
+###############################################################################
+#                             Masking functions                               #
+###############################################################################
+
+def masked_where(condition, a, copy=True):
+    """
+    Mask an array where a condition is met.
+
+    Return `a` as an array masked where `condition` is True.
+    Any masked values of `a` or `condition` are also masked in the output.
+
+    Parameters
+    ----------
+    condition : array_like
+        Masking condition.  When `condition` tests floating point values for
+        equality, consider using ``masked_values`` instead.
+    a : array_like
+        Array to mask.
+    copy : bool
+        If True (default) make a copy of `a` in the result.  If False modify
+        `a` in place and return a view.
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `a` where `condition` is True.
+
+    See Also
+    --------
+    masked_values : Mask using floating point equality.
+    masked_equal : Mask where equal to a given value.
+    masked_not_equal : Mask where `not` equal to a given value.
+    masked_less_equal : Mask where less than or equal to a given value.
+    masked_greater_equal : Mask where greater than or equal to a given value.
+    masked_less : Mask where less than a given value.
+    masked_greater : Mask where greater than a given value.
+    masked_inside : Mask inside a given interval.
+    masked_outside : Mask outside a given interval.
+    masked_invalid : Mask invalid values (NaNs or infs).
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_where(a <= 2, a)
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+
+    Mask array `b` conditional on `a`.
+
+    >>> b = ['a', 'b', 'c', 'd']
+    >>> ma.masked_where(a == 2, b)
+    masked_array(data = [a b -- d],
+          mask = [False False  True False],
+          fill_value=N/A)
+
+    Effect of the `copy` argument.
+
+    >>> c = ma.masked_where(a <= 2, a)
+    >>> c
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+    >>> c[0] = 99
+    >>> c
+    masked_array(data = [99 -- -- 3],
+          mask = [False  True  True False],
+          fill_value=999999)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> c = ma.masked_where(a <= 2, a, copy=False)
+    >>> c[0] = 99
+    >>> c
+    masked_array(data = [99 -- -- 3],
+          mask = [False  True  True False],
+          fill_value=999999)
+    >>> a
+    array([99,  1,  2,  3])
+
+    When `condition` or `a` contain masked values.
+
+    >>> a = np.arange(4)
+    >>> a = ma.masked_where(a == 2, a)
+    >>> a
+    masked_array(data = [0 1 -- 3],
+          mask = [False False  True False],
+          fill_value=999999)
+    >>> b = np.arange(4)
+    >>> b = ma.masked_where(b == 0, b)
+    >>> b
+    masked_array(data = [-- 1 2 3],
+          mask = [ True False False False],
+          fill_value=999999)
+    >>> ma.masked_where(a == 3, b)
+    masked_array(data = [-- 1 -- --],
+          mask = [ True False  True  True],
+          fill_value=999999)
+
+    """
+    # Make sure that condition is a valid standard-type mask.
+    cond = make_mask(condition)
+    a = np.array(a, copy=copy, subok=True)
+
+    (cshape, ashape) = (cond.shape, a.shape)
+    if cshape and cshape != ashape:
+        raise IndexError("Inconsistant shape between the condition and the input"
+                         " (got %s and %s)" % (cshape, ashape))
+    if hasattr(a, '_mask'):
+        cond = mask_or(cond, a._mask)
+        cls = type(a)
+    else:
+        cls = MaskedArray
+    result = a.view(cls)
+    # Assign to *.mask so that structured masks are handled correctly.
+    result.mask = cond
+    return result
+
+
+def masked_greater(x, value, copy=True):
+    """
+    Mask an array where greater than a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x > value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_greater(a, 2)
+    masked_array(data = [0 1 2 --],
+          mask = [False False False  True],
+          fill_value=999999)
+
+    """
+    return masked_where(greater(x, value), x, copy=copy)
+
+
+def masked_greater_equal(x, value, copy=True):
+    """
+    Mask an array where greater than or equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x >= value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_greater_equal(a, 2)
+    masked_array(data = [0 1 -- --],
+          mask = [False False  True  True],
+          fill_value=999999)
+
+    """
+    return masked_where(greater_equal(x, value), x, copy=copy)
+
+
+def masked_less(x, value, copy=True):
+    """
+    Mask an array where less than a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x < value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_less(a, 2)
+    masked_array(data = [-- -- 2 3],
+          mask = [ True  True False False],
+          fill_value=999999)
+
+    """
+    return masked_where(less(x, value), x, copy=copy)
+
+
+def masked_less_equal(x, value, copy=True):
+    """
+    Mask an array where less than or equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x <= value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_less_equal(a, 2)
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+
+    """
+    return masked_where(less_equal(x, value), x, copy=copy)
+
+
+def masked_not_equal(x, value, copy=True):
+    """
+    Mask an array where `not` equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x != value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_not_equal(a, 2)
+    masked_array(data = [-- -- 2 --],
+          mask = [ True  True False  True],
+          fill_value=999999)
+
+    """
+    return masked_where(not_equal(x, value), x, copy=copy)
+
+
+def masked_equal(x, value, copy=True):
+    """
+    Mask an array where equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x == value).  For floating point arrays,
+    consider using ``masked_values(x, value)``.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_values : Mask using floating point equality.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_equal(a, 2)
+    masked_array(data = [0 1 -- 3],
+          mask = [False False  True False],
+          fill_value=999999)
+
+    """
+    output = masked_where(equal(x, value), x, copy=copy)
+    output.fill_value = value
+    return output
+
+
+def masked_inside(x, v1, v2, copy=True):
+    """
+    Mask an array inside a given interval.
+
+    Shortcut to ``masked_where``, where `condition` is True for `x` inside
+    the interval [v1,v2] (v1 <= x <= v2).  The boundaries `v1` and `v2`
+    can be given in either order.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The array `x` is prefilled with its filling value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
+    >>> ma.masked_inside(x, -0.3, 0.3)
+    masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
+          mask = [False False  True  True False False],
+          fill_value=1e+20)
+
+    The order of `v1` and `v2` doesn't matter.
+
+    >>> ma.masked_inside(x, 0.3, -0.3)
+    masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
+          mask = [False False  True  True False False],
+          fill_value=1e+20)
+
+    """
+    if v2 < v1:
+        (v1, v2) = (v2, v1)
+    xf = filled(x)
+    condition = (xf >= v1) & (xf <= v2)
+    return masked_where(condition, x, copy=copy)
+
+
+def masked_outside(x, v1, v2, copy=True):
+    """
+    Mask an array outside a given interval.
+
+    Shortcut to ``masked_where``, where `condition` is True for `x` outside
+    the interval [v1,v2] (x < v1)|(x > v2).
+    The boundaries `v1` and `v2` can be given in either order.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The array `x` is prefilled with its filling value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
+    >>> ma.masked_outside(x, -0.3, 0.3)
+    masked_array(data = [-- -- 0.01 0.2 -- --],
+          mask = [ True  True False False  True  True],
+          fill_value=1e+20)
+
+    The order of `v1` and `v2` doesn't matter.
+
+    >>> ma.masked_outside(x, 0.3, -0.3)
+    masked_array(data = [-- -- 0.01 0.2 -- --],
+          mask = [ True  True False False  True  True],
+          fill_value=1e+20)
+
+    """
+    if v2 < v1:
+        (v1, v2) = (v2, v1)
+    xf = filled(x)
+    condition = (xf < v1) | (xf > v2)
+    return masked_where(condition, x, copy=copy)
+
+
+def masked_object(x, value, copy=True, shrink=True):
+    """
+    Mask the array `x` where the data are exactly equal to value.
+
+    This function is similar to `masked_values`, but only suitable
+    for object arrays: for floating point, use `masked_values` instead.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to mask
+    value : object
+        Comparison value
+    copy : {True, False}, optional
+        Whether to return a copy of `x`.
+    shrink : {True, False}, optional
+        Whether to collapse a mask full of False to nomask
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `x` where equal to `value`.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_equal : Mask where equal to a given value (integers).
+    masked_values : Mask using floating point equality.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> food = np.array(['green_eggs', 'ham'], dtype=object)
+    >>> # don't eat spoiled food
+    >>> eat = ma.masked_object(food, 'green_eggs')
+    >>> print(eat)
+    [-- ham]
+    >>> # plain ol` ham is boring
+    >>> fresh_food = np.array(['cheese', 'ham', 'pineapple'], dtype=object)
+    >>> eat = ma.masked_object(fresh_food, 'green_eggs')
+    >>> print(eat)
+    [cheese ham pineapple]
+
+    Note that `mask` is set to ``nomask`` if possible.
+
+    >>> eat
+    masked_array(data = [cheese ham pineapple],
+          mask = False,
+          fill_value=?)
+
+    """
+    if isMaskedArray(x):
+        condition = umath.equal(x._data, value)
+        mask = x._mask
+    else:
+        condition = umath.equal(np.asarray(x), value)
+        mask = nomask
+    mask = mask_or(mask, make_mask(condition, shrink=shrink))
+    return masked_array(x, mask=mask, copy=copy, fill_value=value)
+
+
+def masked_values(x, value, rtol=1e-5, atol=1e-8, copy=True, shrink=True):
+    """
+    Mask using floating point equality.
+
+    Return a MaskedArray, masked where the data in array `x` are approximately
+    equal to `value`, i.e. where the following condition is True
+
+    (abs(x - value) <= atol+rtol*abs(value))
+
+    The fill_value is set to `value` and the mask is set to ``nomask`` if
+    possible.  For integers, consider using ``masked_equal``.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to mask.
+    value : float
+        Masking value.
+    rtol : float, optional
+        Tolerance parameter.
+    atol : float, optional
+        Tolerance parameter (1e-8).
+    copy : bool, optional
+        Whether to return a copy of `x`.
+    shrink : bool, optional
+        Whether to collapse a mask full of False to ``nomask``.
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `x` where approximately equal to `value`.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_equal : Mask where equal to a given value (integers).
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = np.array([1, 1.1, 2, 1.1, 3])
+    >>> ma.masked_values(x, 1.1)
+    masked_array(data = [1.0 -- 2.0 -- 3.0],
+          mask = [False  True False  True False],
+          fill_value=1.1)
+
+    Note that `mask` is set to ``nomask`` if possible.
+
+    >>> ma.masked_values(x, 1.5)
+    masked_array(data = [ 1.   1.1  2.   1.1  3. ],
+          mask = False,
+          fill_value=1.5)
+
+    For integers, the fill value will be different in general to the
+    result of ``masked_equal``.
+
+    >>> x = np.arange(5)
+    >>> x
+    array([0, 1, 2, 3, 4])
+    >>> ma.masked_values(x, 2)
+    masked_array(data = [0 1 -- 3 4],
+          mask = [False False  True False False],
+          fill_value=2)
+    >>> ma.masked_equal(x, 2)
+    masked_array(data = [0 1 -- 3 4],
+          mask = [False False  True False False],
+          fill_value=999999)
+
+    """
+    mabs = umath.absolute
+    xnew = filled(x, value)
+    if issubclass(xnew.dtype.type, np.floating):
+        condition = umath.less_equal(
+            mabs(xnew - value), atol + rtol * mabs(value))
+        mask = getattr(x, '_mask', nomask)
+    else:
+        condition = umath.equal(xnew, value)
+        mask = nomask
+    mask = mask_or(mask, make_mask(condition, shrink=shrink), shrink=shrink)
+    return masked_array(xnew, mask=mask, copy=copy, fill_value=value)
+
+
+def masked_invalid(a, copy=True):
+    """
+    Mask an array where invalid values occur (NaNs or infs).
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = ~(np.isfinite(a)). Any pre-existing mask is conserved.
+    Only applies to arrays with a dtype where NaNs or infs make sense
+    (i.e. floating point types), but accepts any array_like object.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(5, dtype=np.float)
+    >>> a[2] = np.NaN
+    >>> a[3] = np.PINF
+    >>> a
+    array([  0.,   1.,  NaN,  Inf,   4.])
+    >>> ma.masked_invalid(a)
+    masked_array(data = [0.0 1.0 -- -- 4.0],
+          mask = [False False  True  True False],
+          fill_value=1e+20)
+
+    """
+    a = np.array(a, copy=copy, subok=True)
+    mask = getattr(a, '_mask', None)
+    if mask is not None:
+        condition = ~(np.isfinite(getdata(a)))
+        if mask is not nomask:
+            condition |= mask
+        cls = type(a)
+    else:
+        condition = ~(np.isfinite(a))
+        cls = MaskedArray
+    result = a.view(cls)
+    result._mask = condition
+    return result
+
+
+###############################################################################
+#                            Printing options                                 #
+###############################################################################
+
+
+class _MaskedPrintOption:
+    """
+    Handle the string used to represent missing data in a masked array.
+
+    """
+
+    def __init__(self, display):
+        """
+        Create the masked_print_option object.
+
+        """
+        self._display = display
+        self._enabled = True
+
+    def display(self):
+        """
+        Display the string to print for masked values.
+
+        """
+        return self._display
+
+    def set_display(self, s):
+        """
+        Set the string to print for masked values.
+
+        """
+        self._display = s
+
+    def enabled(self):
+        """
+        Is the use of the display value enabled?
+
+        """
+        return self._enabled
+
+    def enable(self, shrink=1):
+        """
+        Set the enabling shrink to `shrink`.
+
+        """
+        self._enabled = shrink
+
+    def __str__(self):
+        return str(self._display)
+
+    __repr__ = __str__
+
+# if you single index into a masked location you get this object.
+masked_print_option = _MaskedPrintOption('--')
+
+
+def _recursive_printoption(result, mask, printopt):
+    """
+    Puts printoptions in result where mask is True.
+
+    Private function allowing for recursion
+
+    """
+    names = result.dtype.names
+    for name in names:
+        (curdata, curmask) = (result[name], mask[name])
+        if curdata.dtype.names:
+            _recursive_printoption(curdata, curmask, printopt)
+        else:
+            np.copyto(curdata, printopt, where=curmask)
+    return
+
+_print_templates = dict(long_std="""\
+masked_%(name)s(data =
+ %(data)s,
+       %(nlen)s mask =
+ %(mask)s,
+ %(nlen)s fill_value = %(fill)s)
+""",
+                        short_std="""\
+masked_%(name)s(data = %(data)s,
+       %(nlen)s mask = %(mask)s,
+%(nlen)s  fill_value = %(fill)s)
+""",
+                        long_flx="""\
+masked_%(name)s(data =
+ %(data)s,
+       %(nlen)s mask =
+ %(mask)s,
+%(nlen)s  fill_value = %(fill)s,
+      %(nlen)s dtype = %(dtype)s)
+""",
+                        short_flx="""\
+masked_%(name)s(data = %(data)s,
+%(nlen)s        mask = %(mask)s,
+%(nlen)s  fill_value = %(fill)s,
+%(nlen)s       dtype = %(dtype)s)
+""")
+
+###############################################################################
+#                          MaskedArray class                                  #
+###############################################################################
+
+
+def _recursive_filled(a, mask, fill_value):
+    """
+    Recursively fill `a` with `fill_value`.
+
+    """
+    names = a.dtype.names
+    for name in names:
+        current = a[name]
+        if current.dtype.names:
+            _recursive_filled(current, mask[name], fill_value[name])
+        else:
+            np.copyto(current, fill_value[name], where=mask[name])
+
+
+def flatten_structured_array(a):
+    """
+    Flatten a structured array.
+
+    The data type of the output is chosen such that it can represent all of the
+    (nested) fields.
+
+    Parameters
+    ----------
+    a : structured array
+
+    Returns
+    -------
+    output : masked array or ndarray
+        A flattened masked array if the input is a masked array, otherwise a
+        standard ndarray.
+
+    Examples
+    --------
+    >>> ndtype = [('a', int), ('b', float)]
+    >>> a = np.array([(1, 1), (2, 2)], dtype=ndtype)
+    >>> flatten_structured_array(a)
+    array([[1., 1.],
+           [2., 2.]])
+
+    """
+
+    def flatten_sequence(iterable):
+        """
+        Flattens a compound of nested iterables.
+
+        """
+        for elm in iter(iterable):
+            if hasattr(elm, '__iter__'):
+                for f in flatten_sequence(elm):
+                    yield f
+            else:
+                yield elm
+
+    a = np.asanyarray(a)
+    inishape = a.shape
+    a = a.ravel()
+    if isinstance(a, MaskedArray):
+        out = np.array([tuple(flatten_sequence(d.item())) for d in a._data])
+        out = out.view(MaskedArray)
+        out._mask = np.array([tuple(flatten_sequence(d.item()))
+                              for d in getmaskarray(a)])
+    else:
+        out = np.array([tuple(flatten_sequence(d.item())) for d in a])
+    if len(inishape) > 1:
+        newshape = list(out.shape)
+        newshape[0] = inishape
+        out.shape = tuple(flatten_sequence(newshape))
+    return out
+
+
+def _arraymethod(funcname, onmask=True):
+    """
+    Return a class method wrapper around a basic array method.
+
+    Creates a class method which returns a masked array, where the new
+    ``_data`` array is the output of the corresponding basic method called
+    on the original ``_data``.
+
+    If `onmask` is True, the new mask is the output of the method called
+    on the initial mask. Otherwise, the new mask is just a reference
+    to the initial mask.
+
+    Parameters
+    ----------
+    funcname : str
+        Name of the function to apply on data.
+    onmask : bool
+        Whether the mask must be processed also (True) or left
+        alone (False). Default is True. Make available as `_onmask`
+        attribute.
+
+    Returns
+    -------
+    method : instancemethod
+        Class method wrapper of the specified basic array method.
+
+    """
+    def wrapped_method(self, *args, **params):
+        result = getattr(self._data, funcname)(*args, **params)
+        result = result.view(type(self))
+        result._update_from(self)
+        mask = self._mask
+        if result.ndim:
+            if not onmask:
+                result.__setmask__(mask)
+            elif mask is not nomask:
+                result.__setmask__(getattr(mask, funcname)(*args, **params))
+        else:
+            if mask.ndim and (not mask.dtype.names and mask.all()):
+                return masked
+        return result
+    methdoc = getattr(ndarray, funcname, None) or getattr(np, funcname, None)
+    if methdoc is not None:
+        wrapped_method.__doc__ = methdoc.__doc__
+    wrapped_method.__name__ = funcname
+    return wrapped_method
+
+
+class MaskedIterator(object):
+    """
+    Flat iterator object to iterate over masked arrays.
+
+    A `MaskedIterator` iterator is returned by ``x.flat`` for any masked array
+    `x`. It allows iterating over the array as if it were a 1-D array,
+    either in a for-loop or by calling its `next` method.
+
+    Iteration is done in C-contiguous style, with the last index varying the
+    fastest. The iterator can also be indexed using basic slicing or
+    advanced indexing.
+
+    See Also
+    --------
+    MaskedArray.flat : Return a flat iterator over an array.
+    MaskedArray.flatten : Returns a flattened copy of an array.
+
+    Notes
+    -----
+    `MaskedIterator` is not exported by the `ma` module. Instead of
+    instantiating a `MaskedIterator` directly, use `MaskedArray.flat`.
+
+    Examples
+    --------
+    >>> x = np.ma.array(arange(6).reshape(2, 3))
+    >>> fl = x.flat
+    >>> type(fl)
+    <class 'numpy.ma.core.MaskedIterator'>
+    >>> for item in fl:
+    ...     print(item)
+    ...
+    0
+    1
+    2
+    3
+    4
+    5
+
+    Extracting more than a single element b indexing the `MaskedIterator`
+    returns a masked array:
+
+    >>> fl[2:4]
+    masked_array(data = [2 3],
+                 mask = False,
+           fill_value = 999999)
+
+    """
+
+    def __init__(self, ma):
+        self.ma = ma
+        self.dataiter = ma._data.flat
+
+        if ma._mask is nomask:
+            self.maskiter = None
+        else:
+            self.maskiter = ma._mask.flat
+
+    def __iter__(self):
+        return self
+
+    def __getitem__(self, indx):
+        result = self.dataiter.__getitem__(indx).view(type(self.ma))
+        if self.maskiter is not None:
+            _mask = self.maskiter.__getitem__(indx)
+            if isinstance(_mask, ndarray):
+                # set shape to match that of data; this is needed for matrices
+                _mask.shape = result.shape
+                result._mask = _mask
+            elif isinstance(_mask, np.void):
+                return mvoid(result, mask=_mask, hardmask=self.ma._hardmask)
+            elif _mask:  # Just a scalar, masked
+                return masked
+        return result
+
+    # This won't work if ravel makes a copy
+    def __setitem__(self, index, value):
+        self.dataiter[index] = getdata(value)
+        if self.maskiter is not None:
+            self.maskiter[index] = getmaskarray(value)
+
+    def __next__(self):
+        """
+        Return the next value, or raise StopIteration.
+
+        Examples
+        --------
+        >>> x = np.ma.array([3, 2], mask=[0, 1])
+        >>> fl = x.flat
+        >>> fl.next()
+        3
+        >>> fl.next()
+        masked_array(data = --,
+                     mask = True,
+               fill_value = 1e+20)
+        >>> fl.next()
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          File "/home/ralf/python/numpy/numpy/ma/core.py", line 2243, in next
+            d = self.dataiter.next()
+        StopIteration
+
+        """
+        d = next(self.dataiter)
+        if self.maskiter is not None:
+            m = next(self.maskiter)
+            if isinstance(m, np.void):
+                return mvoid(d, mask=m, hardmask=self.ma._hardmask)
+            elif m:  # Just a scalar, masked
+                return masked
+        return d
+
+    next = __next__
+
+
+class MaskedArray(ndarray):
+    """
+    An array class with possibly masked values.
+
+    Masked values of True exclude the corresponding element from any
+    computation.
+
+    Construction::
+
+      x = MaskedArray(data, mask=nomask, dtype=None, copy=False, subok=True,
+                      ndmin=0, fill_value=None, keep_mask=True, hard_mask=None,
+                      shrink=True, order=None)
+
+    Parameters
+    ----------
+    data : array_like
+        Input data.
+    mask : sequence, optional
+        Mask. Must be convertible to an array of booleans with the same
+        shape as `data`. True indicates a masked (i.e. invalid) data.
+    dtype : dtype, optional
+        Data type of the output.
+        If `dtype` is None, the type of the data argument (``data.dtype``)
+        is used. If `dtype` is not None and different from ``data.dtype``,
+        a copy is performed.
+    copy : bool, optional
+        Whether to copy the input data (True), or to use a reference instead.
+        Default is False.
+    subok : bool, optional
+        Whether to return a subclass of `MaskedArray` if possible (True) or a
+        plain `MaskedArray`. Default is True.
+    ndmin : int, optional
+        Minimum number of dimensions. Default is 0.
+    fill_value : scalar, optional
+        Value used to fill in the masked values when necessary.
+        If None, a default based on the data-type is used.
+    keep_mask : bool, optional
+        Whether to combine `mask` with the mask of the input data, if any
+        (True), or to use only `mask` for the output (False). Default is True.
+    hard_mask : bool, optional
+        Whether to use a hard mask or not. With a hard mask, masked values
+        cannot be unmasked. Default is False.
+    shrink : bool, optional
+        Whether to force compression of an empty mask. Default is True.
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C', then the array
+        will be in C-contiguous order (last-index varies the fastest).
+        If order is 'F', then the returned array will be in
+        Fortran-contiguous order (first-index varies the fastest).
+        If order is 'A' (default), then the returned array may be
+        in any order (either C-, Fortran-contiguous, or even discontiguous),
+        unless a copy is required, in which case it will be C-contiguous.
+
+    """
+
+    __array_priority__ = 15
+    _defaultmask = nomask
+    _defaulthardmask = False
+    _baseclass = ndarray
+    # Maximum number of elements per axis used when printing an array.
+    _print_width = 100
+
+    def __new__(cls, data=None, mask=nomask, dtype=None, copy=False,
+                subok=True, ndmin=0, fill_value=None, keep_mask=True,
+                hard_mask=None, shrink=True, order=None, **options):
+        """
+        Create a new masked array from scratch.
+
+        Notes
+        -----
+        A masked array can also be created by taking a .view(MaskedArray).
+
+        """
+        # Process data.
+        _data = np.array(data, dtype=dtype, copy=copy,
+                         order=order, subok=True, ndmin=ndmin)
+        _baseclass = getattr(data, '_baseclass', type(_data))
+        # Check that we're not erasing the mask.
+        if isinstance(data, MaskedArray) and (data.shape != _data.shape):
+            copy = True
+        # Careful, cls might not always be MaskedArray.
+        if not isinstance(data, cls) or not subok:
+            _data = ndarray.view(_data, cls)
+        else:
+            _data = ndarray.view(_data, type(data))
+        # Backwards compatibility w/ numpy.core.ma.
+        if hasattr(data, '_mask') and not isinstance(data, ndarray):
+            _data._mask = data._mask
+            # FIXME _sharedmask is never used.
+            _sharedmask = True
+        # Process mask.
+        # Number of named fields (or zero if none)
+        names_ = _data.dtype.names or ()
+        # Type of the mask
+        if names_:
+            mdtype = make_mask_descr(_data.dtype)
+        else:
+            mdtype = MaskType
+
+        if mask is nomask:
+            # Case 1. : no mask in input.
+            # Erase the current mask ?
+            if not keep_mask:
+                # With a reduced version
+                if shrink:
+                    _data._mask = nomask
+                # With full version
+                else:
+                    _data._mask = np.zeros(_data.shape, dtype=mdtype)
+            # Check whether we missed something
+            elif isinstance(data, (tuple, list)):
+                try:
+                    # If data is a sequence of masked array
+                    mask = np.array([getmaskarray(m) for m in data],
+                                    dtype=mdtype)
+                except ValueError:
+                    # If data is nested
+                    mask = nomask
+                # Force shrinking of the mask if needed (and possible)
+                if (mdtype == MaskType) and mask.any():
+                    _data._mask = mask
+                    _data._sharedmask = False
+            else:
+                if copy:
+                    _data._mask = _data._mask.copy()
+                    _data._sharedmask = False
+                    # Reset the shape of the original mask
+                    if getmask(data) is not nomask:
+                        data._mask.shape = data.shape
+                else:
+                    _data._sharedmask = True
+        else:
+            # Case 2. : With a mask in input.
+            # If mask is boolean, create an array of True or False
+            if mask is True and mdtype == MaskType:
+                mask = np.ones(_data.shape, dtype=mdtype)
+            elif mask is False and mdtype == MaskType:
+                mask = np.zeros(_data.shape, dtype=mdtype)
+            else:
+                # Read the mask with the current mdtype
+                try:
+                    mask = np.array(mask, copy=copy, dtype=mdtype)
+                # Or assume it's a sequence of bool/int
+                except TypeError:
+                    mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                    dtype=mdtype)
+            # Make sure the mask and the data have the same shape
+            if mask.shape != _data.shape:
+                (nd, nm) = (_data.size, mask.size)
+                if nm == 1:
+                    mask = np.resize(mask, _data.shape)
+                elif nm == nd:
+                    mask = np.reshape(mask, _data.shape)
+                else:
+                    msg = "Mask and data not compatible: data size is %i, " + \
+                          "mask size is %i."
+                    raise MaskError(msg % (nd, nm))
+                copy = True
+            # Set the mask to the new value
+            if _data._mask is nomask:
+                _data._mask = mask
+                _data._sharedmask = not copy
+            else:
+                if not keep_mask:
+                    _data._mask = mask
+                    _data._sharedmask = not copy
+                else:
+                    if names_:
+                        def _recursive_or(a, b):
+                            "do a|=b on each field of a, recursively"
+                            for name in a.dtype.names:
+                                (af, bf) = (a[name], b[name])
+                                if af.dtype.names:
+                                    _recursive_or(af, bf)
+                                else:
+                                    af |= bf
+                            return
+                        _recursive_or(_data._mask, mask)
+                    else:
+                        _data._mask = np.logical_or(mask, _data._mask)
+                    _data._sharedmask = False
+        # Update fill_value.
+        if fill_value is None:
+            fill_value = getattr(data, '_fill_value', None)
+        # But don't run the check unless we have something to check.
+        if fill_value is not None:
+            _data._fill_value = _check_fill_value(fill_value, _data.dtype)
+        # Process extra options ..
+        if hard_mask is None:
+            _data._hardmask = getattr(data, '_hardmask', False)
+        else:
+            _data._hardmask = hard_mask
+        _data._baseclass = _baseclass
+        return _data
+
+
+    def _update_from(self, obj):
+        """
+        Copies some attributes of obj to self.
+
+        """
+        if obj is not None and isinstance(obj, ndarray):
+            _baseclass = type(obj)
+        else:
+            _baseclass = ndarray
+        # We need to copy the _basedict to avoid backward propagation
+        _optinfo = {}
+        _optinfo.update(getattr(obj, '_optinfo', {}))
+        _optinfo.update(getattr(obj, '_basedict', {}))
+        if not isinstance(obj, MaskedArray):
+            _optinfo.update(getattr(obj, '__dict__', {}))
+        _dict = dict(_fill_value=getattr(obj, '_fill_value', None),
+                     _hardmask=getattr(obj, '_hardmask', False),
+                     _sharedmask=getattr(obj, '_sharedmask', False),
+                     _isfield=getattr(obj, '_isfield', False),
+                     _baseclass=getattr(obj, '_baseclass', _baseclass),
+                     _optinfo=_optinfo,
+                     _basedict=_optinfo)
+        self.__dict__.update(_dict)
+        self.__dict__.update(_optinfo)
+        return
+
+    def __array_finalize__(self, obj):
+        """
+        Finalizes the masked array.
+
+        """
+        # Get main attributes.
+        self._update_from(obj)
+
+        # We have to decide how to initialize self.mask, based on
+        # obj.mask. This is very difficult.  There might be some
+        # correspondence between the elements in the array we are being
+        # created from (= obj) and us. Or there might not. This method can
+        # be called in all kinds of places for all kinds of reasons -- could
+        # be empty_like, could be slicing, could be a ufunc, could be a view.
+        # The numpy subclassing interface simply doesn't give us any way
+        # to know, which means that at best this method will be based on
+        # guesswork and heuristics. To make things worse, there isn't even any
+        # clear consensus about what the desired behavior is. For instance,
+        # most users think that np.empty_like(marr) -- which goes via this
+        # method -- should return a masked array with an empty mask (see
+        # gh-3404 and linked discussions), but others disagree, and they have
+        # existing code which depends on empty_like returning an array that
+        # matches the input mask.
+        #
+        # Historically our algorithm was: if the template object mask had the
+        # same *number of elements* as us, then we used *it's mask object
+        # itself* as our mask, so that writes to us would also write to the
+        # original array. This is horribly broken in multiple ways.
+        #
+        # Now what we do instead is, if the template object mask has the same
+        # number of elements as us, and we do not have the same base pointer
+        # as the template object (b/c views like arr[...] should keep the same
+        # mask), then we make a copy of the template object mask and use
+        # that. This is also horribly broken but somewhat less so. Maybe.
+        if isinstance(obj, ndarray):
+            # XX: This looks like a bug -- shouldn't it check self.dtype
+            # instead?
+            if obj.dtype.names:
+                _mask = getattr(obj, '_mask',
+                                make_mask_none(obj.shape, obj.dtype))
+            else:
+                _mask = getattr(obj, '_mask', nomask)
+
+            # If self and obj point to exactly the same data, then probably
+            # self is a simple view of obj (e.g., self = obj[...]), so they
+            # should share the same mask. (This isn't 100% reliable, e.g. self
+            # could be the first row of obj, or have strange strides, but as a
+            # heuristic it's not bad.) In all other cases, we make a copy of
+            # the mask, so that future modifications to 'self' do not end up
+            # side-effecting 'obj' as well.
+            if (obj.__array_interface__["data"][0]
+                    != self.__array_interface__["data"][0]):
+                _mask = _mask.copy()
+        else:
+            _mask = nomask
+        self._mask = _mask
+        # Finalize the mask
+        if self._mask is not nomask:
+            try:
+                self._mask.shape = self.shape
+            except ValueError:
+                self._mask = nomask
+            except (TypeError, AttributeError):
+                # When _mask.shape is not writable (because it's a void)
+                pass
+        # Finalize the fill_value for structured arrays
+        if self.dtype.names:
+            if self._fill_value is None:
+                self._fill_value = _check_fill_value(None, self.dtype)
+        return
+
+    def __array_wrap__(self, obj, context=None):
+        """
+        Special hook for ufuncs.
+
+        Wraps the numpy array and sets the mask according to context.
+
+        """
+        result = obj.view(type(self))
+        result._update_from(self)
+
+        if context is not None:
+            result._mask = result._mask.copy()
+            (func, args, _) = context
+            m = reduce(mask_or, [getmaskarray(arg) for arg in args])
+            # Get the domain mask
+            domain = ufunc_domain.get(func, None)
+            if domain is not None:
+                # Take the domain, and make sure it's a ndarray
+                if len(args) > 2:
+                    d = filled(reduce(domain, args), True)
+                else:
+                    d = filled(domain(*args), True)
+                # Fill the result where the domain is wrong
+                try:
+                    # Binary domain: take the last value
+                    fill_value = ufunc_fills[func][-1]
+                except TypeError:
+                    # Unary domain: just use this one
+                    fill_value = ufunc_fills[func]
+                except KeyError:
+                    # Domain not recognized, use fill_value instead
+                    fill_value = self.fill_value
+                result = result.copy()
+                np.copyto(result, fill_value, where=d)
+                # Update the mask
+                if m is nomask:
+                    if d is not nomask:
+                        m = d
+                else:
+                    # Don't modify inplace, we risk back-propagation
+                    m = (m | d)
+            # Make sure the mask has the proper size
+            if result.shape == () and m:
+                return masked
+            else:
+                result._mask = m
+                result._sharedmask = False
+
+        return result
+
+    def view(self, dtype=None, type=None, fill_value=None):
+        """
+        Return a view of the MaskedArray data
+
+        Parameters
+        ----------
+        dtype : data-type or ndarray sub-class, optional
+            Data-type descriptor of the returned view, e.g., float32 or int16.
+            The default, None, results in the view having the same data-type
+            as `a`. As with ``ndarray.view``, dtype can also be specified as
+            an ndarray sub-class, which then specifies the type of the
+            returned object (this is equivalent to setting the ``type``
+            parameter).
+        type : Python type, optional
+            Type of the returned view, e.g., ndarray or matrix.  Again, the
+            default None results in type preservation.
+
+        Notes
+        -----
+
+        ``a.view()`` is used two different ways:
+
+        ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
+        of the array's memory with a different data-type.  This can cause a
+        reinterpretation of the bytes of memory.
+
+        ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
+        returns an instance of `ndarray_subclass` that looks at the same array
+        (same shape, dtype, etc.)  This does not cause a reinterpretation of the
+        memory.
+
+        If `fill_value` is not specified, but `dtype` is specified (and is not
+        an ndarray sub-class), the `fill_value` of the MaskedArray will be
+        reset. If neither `fill_value` nor `dtype` are specified (or if
+        `dtype` is an ndarray sub-class), then the fill value is preserved.
+        Finally, if `fill_value` is specified, but `dtype` is not, the fill
+        value is set to the specified value.
+
+        For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
+        bytes per entry than the previous dtype (for example, converting a
+        regular array to a structured array), then the behavior of the view
+        cannot be predicted just from the superficial appearance of ``a`` (shown
+        by ``print(a)``). It also depends on exactly how ``a`` is stored in
+        memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
+        defined as a slice or transpose, etc., the view may give different
+        results.
+        """
+
+        if dtype is None:
+            if type is None:
+                output = ndarray.view(self)
+            else:
+                output = ndarray.view(self, type)
+        elif type is None:
+            try:
+                if issubclass(dtype, ndarray):
+                    output = ndarray.view(self, dtype)
+                    dtype = None
+                else:
+                    output = ndarray.view(self, dtype)
+            except TypeError:
+                output = ndarray.view(self, dtype)
+        else:
+            output = ndarray.view(self, dtype, type)
+
+        # also make the mask be a view (so attr changes to the view's
+        # mask do no affect original object's mask)
+        # (especially important to avoid affecting np.masked singleton)
+        if (getattr(output, '_mask', nomask) is not nomask):
+            output._mask = output._mask.view()
+
+        # Make sure to reset the _fill_value if needed
+        if getattr(output, '_fill_value', None) is not None:
+            if fill_value is None:
+                if dtype is None:
+                    pass  # leave _fill_value as is
+                else:
+                    output._fill_value = None
+            else:
+                output.fill_value = fill_value
+        return output
+    view.__doc__ = ndarray.view.__doc__
+
+    def astype(self, newtype):
+        """
+        Returns a copy of the MaskedArray cast to given newtype.
+
+        Returns
+        -------
+        output : MaskedArray
+            A copy of self cast to input newtype.
+            The returned record shape matches self.shape.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3.1],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1.0 -- 3.1]
+         [-- 5.0 --]
+         [7.0 -- 9.0]]
+        >>> print(x.astype(int32))
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+
+        """
+        newtype = np.dtype(newtype)
+        output = self._data.astype(newtype).view(type(self))
+        output._update_from(self)
+        names = output.dtype.names
+        if names is None:
+            output._mask = self._mask.astype(bool)
+        else:
+            if self._mask is nomask:
+                output._mask = nomask
+            else:
+                output._mask = self._mask.astype([(n, bool) for n in names])
+        # Don't check _fill_value if it's None, that'll speed things up
+        if self._fill_value is not None:
+            output._fill_value = _check_fill_value(self._fill_value, newtype)
+        return output
+
+    def __getitem__(self, indx):
+        """
+        x.__getitem__(y) <==> x[y]
+
+        Return the item described by i, as a masked array.
+
+        """
+        dout = self.data[indx]
+        # We could directly use ndarray.__getitem__ on self.
+        # But then we would have to modify __array_finalize__ to prevent the
+        # mask of being reshaped if it hasn't been set up properly yet
+        # So it's easier to stick to the current version
+        _mask = self._mask
+        # Did we extract a single item?
+        if not getattr(dout, 'ndim', False):
+            # A record
+            if isinstance(dout, np.void):
+                mask = _mask[indx]
+                # We should always re-cast to mvoid, otherwise users can
+                # change masks on rows that already have masked values, but not
+                # on rows that have no masked values, which is inconsistent.
+                dout = mvoid(dout, mask=mask, hardmask=self._hardmask)
+            # Just a scalar
+            elif _mask is not nomask and _mask[indx]:
+                return masked
+        elif self.dtype.type is np.object_ and self.dtype is not dout.dtype:
+            # self contains an object array of arrays (yes, that happens).
+            # If masked, turn into a MaskedArray, with everything masked.
+            if _mask is not nomask and _mask[indx]:
+                return MaskedArray(dout, mask=True)
+        else:
+            # Force dout to MA
+            dout = dout.view(type(self))
+            # Inherit attributes from self
+            dout._update_from(self)
+            # Check the fill_value
+            if isinstance(indx, basestring):
+                if self._fill_value is not None:
+                    dout._fill_value = self._fill_value[indx]
+
+                    # If we're indexing a multidimensional field in a 
+                    # structured array (such as dtype("(2,)i2,(2,)i1")),
+                    # dimensionality goes up (M[field].ndim == M.ndim +
+                    # len(M.dtype[field].shape)).  That's fine for 
+                    # M[field] but problematic for M[field].fill_value 
+                    # which should have shape () to avoid breaking several
+                    # methods. There is no great way out, so set to
+                    # first element.  See issue #6723.
+                    if dout._fill_value.ndim > 0:
+                        if not (dout._fill_value ==
+                                dout._fill_value.flat[0]).all():
+                            warnings.warn(
+                                "Upon accessing multidimensional field "
+                                "{indx:s}, need to keep dimensionality "
+                                "of fill_value at 0. Discarding "
+                                "heterogeneous fill_value and setting "
+                                "all to {fv!s}.".format(indx=indx,
+                                    fv=dout._fill_value[0]))
+                        dout._fill_value = dout._fill_value.flat[0]
+                dout._isfield = True
+            # Update the mask if needed
+            if _mask is not nomask:
+                dout._mask = _mask[indx]
+                # set shape to match that of data; this is needed for matrices
+                dout._mask.shape = dout.shape
+                dout._sharedmask = True
+                # Note: Don't try to check for m.any(), that'll take too long
+        return dout
+
+    def __setitem__(self, indx, value):
+        """
+        x.__setitem__(i, y) <==> x[i]=y
+
+        Set item described by index. If value is masked, masks those
+        locations.
+
+        """
+        if self is masked:
+            raise MaskError('Cannot alter the masked element.')
+        _data = self._data
+        _mask = self._mask
+        if isinstance(indx, basestring):
+            _data[indx] = value
+            if _mask is nomask:
+                self._mask = _mask = make_mask_none(self.shape, self.dtype)
+            _mask[indx] = getmask(value)
+            return
+
+        _dtype = _data.dtype
+        nbfields = len(_dtype.names or ())
+
+        if value is masked:
+            # The mask wasn't set: create a full version.
+            if _mask is nomask:
+                _mask = self._mask = make_mask_none(self.shape, _dtype)
+            # Now, set the mask to its value.
+            if nbfields:
+                _mask[indx] = tuple([True] * nbfields)
+            else:
+                _mask[indx] = True
+            if not self._isfield:
+                self._sharedmask = False
+            return
+
+        # Get the _data part of the new value
+        dval = value
+        # Get the _mask part of the new value
+        mval = getattr(value, '_mask', nomask)
+        if nbfields and mval is nomask:
+            mval = tuple([False] * nbfields)
+        if _mask is nomask:
+            # Set the data, then the mask
+            _data[indx] = dval
+            if mval is not nomask:
+                _mask = self._mask = make_mask_none(self.shape, _dtype)
+                _mask[indx] = mval
+        elif not self._hardmask:
+            # Unshare the mask if necessary to avoid propagation
+            # We want to remove the unshare logic from this place in the
+            # future. Note that _sharedmask has lots of false positives.
+            if not self._isfield:
+                if self._sharedmask and not (
+                        # If no one else holds a reference (we have two
+                        # references (_mask and self._mask) -- add one for
+                        # getrefcount) and the array owns its own data
+                        # copying the mask should do nothing.
+                        (sys.getrefcount(_mask) == 3) and _mask.flags.owndata):
+                    # 2016.01.15 -- v1.11.0
+                    warnings.warn(
+                       "setting an item on a masked array which has a shared "
+                       "mask will not copy the mask and also change the "
+                       "original mask array in the future.\n"
+                       "Check the NumPy 1.11 release notes for more "
+                       "information.",
+                       MaskedArrayFutureWarning, stacklevel=2)
+                self.unshare_mask()
+                _mask = self._mask
+            # Set the data, then the mask
+            _data[indx] = dval
+            _mask[indx] = mval
+        elif hasattr(indx, 'dtype') and (indx.dtype == MaskType):
+            indx = indx * umath.logical_not(_mask)
+            _data[indx] = dval
+        else:
+            if nbfields:
+                err_msg = "Flexible 'hard' masks are not yet supported."
+                raise NotImplementedError(err_msg)
+            mindx = mask_or(_mask[indx], mval, copy=True)
+            dindx = self._data[indx]
+            if dindx.size > 1:
+                np.copyto(dindx, dval, where=~mindx)
+            elif mindx is nomask:
+                dindx = dval
+            _data[indx] = dindx
+            _mask[indx] = mindx
+        return
+
+    def __setattr__(self, attr, value):
+        super(MaskedArray, self).__setattr__(attr, value)
+        if attr == 'dtype' and self._mask is not nomask:
+            self._mask = self._mask.view(make_mask_descr(value), ndarray)
+            # Try to reset the shape of the mask (if we don't have a void)
+            # This raises a ValueError if the dtype change won't work
+            try:
+                self._mask.shape = self.shape
+            except (AttributeError, TypeError):
+                pass
+
+    def __getslice__(self, i, j):
+        """
+        x.__getslice__(i, j) <==> x[i:j]
+
+        Return the slice described by (i, j).  The use of negative indices
+        is not supported.
+
+        """
+        return self.__getitem__(slice(i, j))
+
+    def __setslice__(self, i, j, value):
+        """
+        x.__setslice__(i, j, value) <==> x[i:j]=value
+
+        Set the slice (i,j) of a to value. If value is masked, mask those
+        locations.
+
+        """
+        self.__setitem__(slice(i, j), value)
+
+    def __setmask__(self, mask, copy=False):
+        """
+        Set the mask.
+
+        """
+        idtype = self.dtype
+        current_mask = self._mask
+        if mask is masked:
+            mask = True
+
+        if (current_mask is nomask):
+            # Make sure the mask is set
+            # Just don't do anything if there's nothing to do.
+            if mask is nomask:
+                return
+            current_mask = self._mask = make_mask_none(self.shape, idtype)
+
+        if idtype.names is None:
+            # No named fields.
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                current_mask |= mask
+            # Softmask: set everything to False
+            # If it's obviously a compatible scalar, use a quick update
+            # method.
+            elif isinstance(mask, (int, float, np.bool_, np.number)):
+                current_mask[...] = mask
+            # Otherwise fall back to the slower, general purpose way.
+            else:
+                current_mask.flat = mask
+        else:
+            # Named fields w/
+            mdtype = current_mask.dtype
+            mask = np.array(mask, copy=False)
+            # Mask is a singleton
+            if not mask.ndim:
+                # It's a boolean : make a record
+                if mask.dtype.kind == 'b':
+                    mask = np.array(tuple([mask.item()] * len(mdtype)),
+                                    dtype=mdtype)
+                # It's a record: make sure the dtype is correct
+                else:
+                    mask = mask.astype(mdtype)
+            # Mask is a sequence
+            else:
+                # Make sure the new mask is a ndarray with the proper dtype
+                try:
+                    mask = np.array(mask, copy=copy, dtype=mdtype)
+                # Or assume it's a sequence of bool/int
+                except TypeError:
+                    mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                    dtype=mdtype)
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                for n in idtype.names:
+                    current_mask[n] |= mask[n]
+            # Softmask: set everything to False
+            # If it's obviously a compatible scalar, use a quick update
+            # method.
+            elif isinstance(mask, (int, float, np.bool_, np.number)):
+                current_mask[...] = mask
+            # Otherwise fall back to the slower, general purpose way.
+            else:
+                current_mask.flat = mask
+        # Reshape if needed
+        if current_mask.shape:
+            current_mask.shape = self.shape
+        return
+
+    _set_mask = __setmask__
+
+    def _get_mask(self):
+        """Return the current mask.
+
+        """
+        # We could try to force a reshape, but that wouldn't work in some
+        # cases.
+        return self._mask
+
+    mask = property(fget=_get_mask, fset=__setmask__, doc="Mask")
+
+    def _get_recordmask(self):
+        """
+        Return the mask of the records.
+
+        A record is masked when all the fields are masked.
+
+        """
+        _mask = self._mask.view(ndarray)
+        if _mask.dtype.names is None:
+            return _mask
+        return np.all(flatten_structured_array(_mask), axis=-1)
+
+    def _set_recordmask(self):
+        """
+        Return the mask of the records.
+
+        A record is masked when all the fields are masked.
+
+        """
+        raise NotImplementedError("Coming soon: setting the mask per records!")
+
+    recordmask = property(fget=_get_recordmask)
+
+    def harden_mask(self):
+        """
+        Force the mask to hard.
+
+        Whether the mask of a masked array is hard or soft is determined by
+        its `hardmask` property. `harden_mask` sets `hardmask` to True.
+
+        See Also
+        --------
+        hardmask
+
+        """
+        self._hardmask = True
+        return self
+
+    def soften_mask(self):
+        """
+        Force the mask to soft.
+
+        Whether the mask of a masked array is hard or soft is determined by
+        its `hardmask` property. `soften_mask` sets `hardmask` to False.
+
+        See Also
+        --------
+        hardmask
+
+        """
+        self._hardmask = False
+        return self
+
+    hardmask = property(fget=lambda self: self._hardmask,
+                        doc="Hardness of the mask")
+
+    def unshare_mask(self):
+        """
+        Copy the mask and set the sharedmask flag to False.
+
+        Whether the mask is shared between masked arrays can be seen from
+        the `sharedmask` property. `unshare_mask` ensures the mask is not shared.
+        A copy of the mask is only made if it was shared.
+
+        See Also
+        --------
+        sharedmask
+
+        """
+        if self._sharedmask:
+            self._mask = self._mask.copy()
+            self._sharedmask = False
+        return self
+
+    sharedmask = property(fget=lambda self: self._sharedmask,
+                          doc="Share status of the mask (read-only).")
+
+    def shrink_mask(self):
+        """
+        Reduce a mask to nomask when possible.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2 ], [3, 4]], mask=[0]*4)
+        >>> x.mask
+        array([[False, False],
+               [False, False]], dtype=bool)
+        >>> x.shrink_mask()
+        >>> x.mask
+        False
+
+        """
+        m = self._mask
+        if m.ndim and not m.any():
+            self._mask = nomask
+        return self
+
+    baseclass = property(fget=lambda self: self._baseclass,
+                         doc="Class of the underlying data (read-only).")
+
+    def _get_data(self):
+        """Return the current data, as a view of the original
+        underlying data.
+
+        """
+        return ndarray.view(self, self._baseclass)
+
+    _data = property(fget=_get_data)
+    data = property(fget=_get_data)
+
+    def _get_flat(self):
+        "Return a flat iterator."
+        return MaskedIterator(self)
+
+    def _set_flat(self, value):
+        "Set a flattened version of self to value."
+        y = self.ravel()
+        y[:] = value
+
+    flat = property(fget=_get_flat, fset=_set_flat,
+                    doc="Flat version of the array.")
+
+    def get_fill_value(self):
+        """
+        Return the filling value of the masked array.
+
+        Returns
+        -------
+        fill_value : scalar
+            The filling value.
+
+        Examples
+        --------
+        >>> for dt in [np.int32, np.int64, np.float64, np.complex128]:
+        ...     np.ma.array([0, 1], dtype=dt).get_fill_value()
+        ...
+        999999
+        999999
+        1e+20
+        (1e+20+0j)
+
+        >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
+        >>> x.get_fill_value()
+        -inf
+
+        """
+        if self._fill_value is None:
+            self._fill_value = _check_fill_value(None, self.dtype)
+        return self._fill_value[()]
+
+    def set_fill_value(self, value=None):
+        """
+        Set the filling value of the masked array.
+
+        Parameters
+        ----------
+        value : scalar, optional
+            The new filling value. Default is None, in which case a default
+            based on the data type is used.
+
+        See Also
+        --------
+        ma.set_fill_value : Equivalent function.
+
+        Examples
+        --------
+        >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
+        >>> x.fill_value
+        -inf
+        >>> x.set_fill_value(np.pi)
+        >>> x.fill_value
+        3.1415926535897931
+
+        Reset to default:
+
+        >>> x.set_fill_value()
+        >>> x.fill_value
+        1e+20
+
+        """
+        target = _check_fill_value(value, self.dtype)
+        _fill_value = self._fill_value
+        if _fill_value is None:
+            # Create the attribute if it was undefined
+            self._fill_value = target
+        else:
+            # Don't overwrite the attribute, just fill it (for propagation)
+            _fill_value[()] = target
+
+    fill_value = property(fget=get_fill_value, fset=set_fill_value,
+                          doc="Filling value.")
+
+    def filled(self, fill_value=None):
+        """
+        Return a copy of self, with masked values filled with a given value.
+        **However**, if there are no masked values to fill, self will be
+        returned instead as an ndarray.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries (None by default).
+            If None, the `fill_value` attribute of the array is used instead.
+
+        Returns
+        -------
+        filled_array : ndarray
+            A copy of ``self`` with invalid entries replaced by *fill_value*
+            (be it the function argument or the attribute of ``self``), or
+            ``self`` itself as an ndarray if there are no invalid entries to
+            be replaced.
+
+        Notes
+        -----
+        The result is **not** a MaskedArray!
+
+        Examples
+        --------
+        >>> x = np.ma.array([1,2,3,4,5], mask=[0,0,1,0,1], fill_value=-999)
+        >>> x.filled()
+        array([1, 2, -999, 4, -999])
+        >>> type(x.filled())
+        <type 'numpy.ndarray'>
+
+        Subclassing is preserved. This means that if the data part of the masked
+        array is a matrix, `filled` returns a matrix:
+
+        >>> x = np.ma.array(np.matrix([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
+        >>> x.filled()
+        matrix([[     1, 999999],
+                [999999,      4]])
+
+        """
+        m = self._mask
+        if m is nomask:
+            return self._data
+
+        if fill_value is None:
+            fill_value = self.fill_value
+        else:
+            fill_value = _check_fill_value(fill_value, self.dtype)
+
+        if self is masked_singleton:
+            return np.asanyarray(fill_value)
+
+        if m.dtype.names:
+            result = self._data.copy('K')
+            _recursive_filled(result, self._mask, fill_value)
+        elif not m.any():
+            return self._data
+        else:
+            result = self._data.copy('K')
+            try:
+                np.copyto(result, fill_value, where=m)
+            except (TypeError, AttributeError):
+                fill_value = narray(fill_value, dtype=object)
+                d = result.astype(object)
+                result = np.choose(m, (d, fill_value))
+            except IndexError:
+                # ok, if scalar
+                if self._data.shape:
+                    raise
+                elif m:
+                    result = np.array(fill_value, dtype=self.dtype)
+                else:
+                    result = self._data
+        return result
+
+    def compressed(self):
+        """
+        Return all the non-masked data as a 1-D array.
+
+        Returns
+        -------
+        data : ndarray
+            A new `ndarray` holding the non-masked data is returned.
+
+        Notes
+        -----
+        The result is **not** a MaskedArray!
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.arange(5), mask=[0]*2 + [1]*3)
+        >>> x.compressed()
+        array([0, 1])
+        >>> type(x.compressed())
+        <type 'numpy.ndarray'>
+
+        """
+        data = ndarray.ravel(self._data)
+        if self._mask is not nomask:
+            data = data.compress(np.logical_not(ndarray.ravel(self._mask)))
+        return data
+
+    def compress(self, condition, axis=None, out=None):
+        """
+        Return `a` where condition is ``True``.
+
+        If condition is a `MaskedArray`, missing values are considered
+        as ``False``.
+
+        Parameters
+        ----------
+        condition : var
+            Boolean 1-d array selecting which entries to return. If len(condition)
+            is less than the size of a along the axis, then output is truncated
+            to length of condition array.
+        axis : {None, int}, optional
+            Axis along which the operation must be performed.
+        out : {None, ndarray}, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        result : MaskedArray
+            A :class:`MaskedArray` object.
+
+        Notes
+        -----
+        Please note the difference with :meth:`compressed` !
+        The output of :meth:`compress` has a mask, the output of
+        :meth:`compressed` does not.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> x.compress([1, 0, 1])
+        masked_array(data = [1 3],
+              mask = [False False],
+              fill_value=999999)
+
+        >>> x.compress([1, 0, 1], axis=1)
+        masked_array(data =
+         [[1 3]
+         [-- --]
+         [7 9]],
+              mask =
+         [[False False]
+         [ True  True]
+         [False False]],
+              fill_value=999999)
+
+        """
+        # Get the basic components
+        (_data, _mask) = (self._data, self._mask)
+
+        # Force the condition to a regular ndarray and forget the missing
+        # values.
+        condition = np.array(condition, copy=False, subok=False)
+
+        _new = _data.compress(condition, axis=axis, out=out).view(type(self))
+        _new._update_from(self)
+        if _mask is not nomask:
+            _new._mask = _mask.compress(condition, axis=axis)
+        return _new
+
+    def __str__(self):
+        """
+        String representation.
+
+        """
+        if masked_print_option.enabled():
+            f = masked_print_option
+            if self is masked:
+                return str(f)
+            m = self._mask
+            if m is nomask:
+                res = self._data
+            else:
+                if m.shape == () and m.itemsize==len(m.dtype):
+                    if m.dtype.names:
+                        m = m.view((bool, len(m.dtype)))
+                        if m.any():
+                            return str(tuple((f if _m else _d) for _d, _m in
+                                             zip(self._data.tolist(), m)))
+                        else:
+                            return str(self._data)
+                    elif m:
+                        return str(f)
+                    else:
+                        return str(self._data)
+                # convert to object array to make filled work
+                names = self.dtype.names
+                if names is None:
+                    data = self._data
+                    mask = m
+                    # For big arrays, to avoid a costly conversion to the
+                    # object dtype, extract the corners before the conversion.
+                    for axis in range(self.ndim):
+                        if data.shape[axis] > self._print_width:
+                            ind = self._print_width // 2
+                            arr = np.split(data, (ind, -ind), axis=axis)
+                            data = np.concatenate((arr[0], arr[2]), axis=axis)
+                            arr = np.split(mask, (ind, -ind), axis=axis)
+                            mask = np.concatenate((arr[0], arr[2]), axis=axis)
+                    res = data.astype("O")
+                    res.view(ndarray)[mask] = f
+                else:
+                    rdtype = _recursive_make_descr(self.dtype, "O")
+                    res = self._data.astype(rdtype)
+                    _recursive_printoption(res, m, f)
+        else:
+            res = self.filled(self.fill_value)
+        return str(res)
+
+    def __repr__(self):
+        """
+        Literal string representation.
+
+        """
+        n = len(self.shape)
+        if self._baseclass is np.ndarray:
+            name = 'array'
+        else:
+            name = self._baseclass.__name__
+
+        parameters = dict(name=name, nlen=" " * len(name),
+                          data=str(self), mask=str(self._mask),
+                          fill=str(self.fill_value), dtype=str(self.dtype))
+        if self.dtype.names:
+            if n <= 1:
+                return _print_templates['short_flx'] % parameters
+            return _print_templates['long_flx'] % parameters
+        elif n <= 1:
+            return _print_templates['short_std'] % parameters
+        return _print_templates['long_std'] % parameters
+
+    def _delegate_binop(self, other):
+        # This emulates the logic in
+        # multiarray/number.c:PyArray_GenericBinaryFunction
+        if (not isinstance(other, np.ndarray)
+                and not hasattr(other, "__numpy_ufunc__")):
+            other_priority = getattr(other, "__array_priority__", -1000000)
+            if self.__array_priority__ < other_priority:
+                return True
+        return False
+
+    def __eq__(self, other):
+        """
+        Check whether other equals self elementwise.
+
+        """
+        if self is masked:
+            return masked
+        omask = getattr(other, '_mask', nomask)
+        if omask is nomask:
+            check = self.filled(0).__eq__(other)
+            try:
+                check = check.view(type(self))
+                check._mask = self._mask
+            except AttributeError:
+                # Dang, we have a bool instead of an array: return the bool
+                return check
+        else:
+            odata = filled(other, 0)
+            check = self.filled(0).__eq__(odata).view(type(self))
+            if self._mask is nomask:
+                check._mask = omask
+            else:
+                mask = mask_or(self._mask, omask)
+                if mask.dtype.names:
+                    if mask.size > 1:
+                        axis = 1
+                    else:
+                        axis = None
+                    try:
+                        mask = mask.view((bool_, len(self.dtype))).all(axis)
+                    except ValueError:
+                        mask = np.all([[f[n].all() for n in mask.dtype.names]
+                                       for f in mask], axis=axis)
+                check._mask = mask
+        return check
+
+    def __ne__(self, other):
+        """
+        Check whether other doesn't equal self elementwise
+
+        """
+        if self is masked:
+            return masked
+        omask = getattr(other, '_mask', nomask)
+        if omask is nomask:
+            check = self.filled(0).__ne__(other)
+            try:
+                check = check.view(type(self))
+                check._mask = self._mask
+            except AttributeError:
+                # In case check is a boolean (or a numpy.bool)
+                return check
+        else:
+            odata = filled(other, 0)
+            check = self.filled(0).__ne__(odata).view(type(self))
+            if self._mask is nomask:
+                check._mask = omask
+            else:
+                mask = mask_or(self._mask, omask)
+                if mask.dtype.names:
+                    if mask.size > 1:
+                        axis = 1
+                    else:
+                        axis = None
+                    try:
+                        mask = mask.view((bool_, len(self.dtype))).all(axis)
+                    except ValueError:
+                        mask = np.all([[f[n].all() for n in mask.dtype.names]
+                                       for f in mask], axis=axis)
+                check._mask = mask
+        return check
+
+    def __add__(self, other):
+        """
+        Add self to other, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return add(self, other)
+
+    def __radd__(self, other):
+        """
+        Add other to self, and return a new masked array.
+
+        """
+        # In analogy with __rsub__ and __rdiv__, use original order:
+        # we get here from `other + self`.
+        return add(other, self)
+
+    def __sub__(self, other):
+        """
+        Subtract other from self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return subtract(self, other)
+
+    def __rsub__(self, other):
+        """
+        Subtract self from other, and return a new masked array.
+
+        """
+        return subtract(other, self)
+
+    def __mul__(self, other):
+        "Multiply self by other, and return a new masked array."
+        if self._delegate_binop(other):
+            return NotImplemented
+        return multiply(self, other)
+
+    def __rmul__(self, other):
+        """
+        Multiply other by self, and return a new masked array.
+
+        """
+        # In analogy with __rsub__ and __rdiv__, use original order:
+        # we get here from `other * self`.
+        return multiply(other, self)
+
+    def __div__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return divide(self, other)
+
+    def __truediv__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return true_divide(self, other)
+
+    def __rtruediv__(self, other):
+        """
+        Divide self into other, and return a new masked array.
+
+        """
+        return true_divide(other, self)
+
+    def __floordiv__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return floor_divide(self, other)
+
+    def __rfloordiv__(self, other):
+        """
+        Divide self into other, and return a new masked array.
+
+        """
+        return floor_divide(other, self)
+
+    def __pow__(self, other):
+        """
+        Raise self to the power other, masking the potential NaNs/Infs
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return power(self, other)
+
+    def __rpow__(self, other):
+        """
+        Raise other to the power self, masking the potential NaNs/Infs
+
+        """
+        return power(other, self)
+
+    def __iadd__(self, other):
+        """
+        Add other to self in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        else:
+            if m is not nomask:
+                self._mask += m
+        self._data.__iadd__(np.where(self._mask, self.dtype.type(0),
+                                     getdata(other)))
+        return self
+
+    def __isub__(self, other):
+        """
+        Subtract other from self in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        elif m is not nomask:
+            self._mask += m
+        self._data.__isub__(np.where(self._mask, self.dtype.type(0),
+                                     getdata(other)))
+        return self
+
+    def __imul__(self, other):
+        """
+        Multiply self by other in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        elif m is not nomask:
+            self._mask += m
+        self._data.__imul__(np.where(self._mask, self.dtype.type(1),
+                                     getdata(other)))
+        return self
+
+    def __idiv__(self, other):
+        """
+        Divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__idiv__(np.where(self._mask, self.dtype.type(1),
+                                     other_data))
+        return self
+
+    def __ifloordiv__(self, other):
+        """
+        Floor divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.floor_divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__ifloordiv__(np.where(self._mask, self.dtype.type(1),
+                                          other_data))
+        return self
+
+    def __itruediv__(self, other):
+        """
+        True divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.true_divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__itruediv__(np.where(self._mask, self.dtype.type(1),
+                                         other_data))
+        return self
+
+    def __ipow__(self, other):
+        """
+        Raise self to the power other, in place.
+
+        """
+        other_data = getdata(other)
+        other_mask = getmask(other)
+        with np.errstate(divide='ignore', invalid='ignore'):
+            self._data.__ipow__(np.where(self._mask, self.dtype.type(1),
+                                         other_data))
+        invalid = np.logical_not(np.isfinite(self._data))
+        if invalid.any():
+            if self._mask is not nomask:
+                self._mask |= invalid
+            else:
+                self._mask = invalid
+            np.copyto(self._data, self.fill_value, where=invalid)
+        new_mask = mask_or(other_mask, invalid)
+        self._mask = mask_or(self._mask, new_mask)
+        return self
+
+    def __float__(self):
+        """
+        Convert to float.
+
+        """
+        if self.size > 1:
+            raise TypeError("Only length-1 arrays can be converted "
+                            "to Python scalars")
+        elif self._mask:
+            warnings.warn("Warning: converting a masked element to nan.")
+            return np.nan
+        return float(self.item())
+
+    def __int__(self):
+        """
+        Convert to int.
+
+        """
+        if self.size > 1:
+            raise TypeError("Only length-1 arrays can be converted "
+                            "to Python scalars")
+        elif self._mask:
+            raise MaskError('Cannot convert masked element to a Python int.')
+        return int(self.item())
+
+    def get_imag(self):
+        """
+        Return the imaginary part of the masked array.
+
+        The returned array is a view on the imaginary part of the `MaskedArray`
+        whose `get_imag` method is called.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        result : MaskedArray
+            The imaginary part of the masked array.
+
+        See Also
+        --------
+        get_real, real, imag
+
+        Examples
+        --------
+        >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
+        >>> x.get_imag()
+        masked_array(data = [1.0 -- 1.6],
+                     mask = [False  True False],
+               fill_value = 1e+20)
+
+        """
+        result = self._data.imag.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    imag = property(fget=get_imag, doc="Imaginary part.")
+
+    def get_real(self):
+        """
+        Return the real part of the masked array.
+
+        The returned array is a view on the real part of the `MaskedArray`
+        whose `get_real` method is called.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        result : MaskedArray
+            The real part of the masked array.
+
+        See Also
+        --------
+        get_imag, real, imag
+
+        Examples
+        --------
+        >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
+        >>> x.get_real()
+        masked_array(data = [1.0 -- 3.45],
+                     mask = [False  True False],
+               fill_value = 1e+20)
+
+        """
+        result = self._data.real.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+    real = property(fget=get_real, doc="Real part")
+
+    def count(self, axis=None):
+        """
+        Count the non-masked elements of the array along the given axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which to count the non-masked elements. If `axis` is
+            `None`, all non-masked elements are counted.
+
+        Returns
+        -------
+        result : int or ndarray
+            If `axis` is `None`, an integer count is returned. When `axis` is
+            not `None`, an array with shape determined by the lengths of the
+            remaining axes, is returned.
+
+        See Also
+        --------
+        count_masked : Count masked elements in array or along a given axis.
+
+        Examples
+        --------
+        >>> import numpy.ma as ma
+        >>> a = ma.arange(6).reshape((2, 3))
+        >>> a[1, :] = ma.masked
+        >>> a
+        masked_array(data =
+         [[0 1 2]
+         [-- -- --]],
+                     mask =
+         [[False False False]
+         [ True  True  True]],
+               fill_value = 999999)
+        >>> a.count()
+        3
+
+        When the `axis` keyword is specified an array of appropriate size is
+        returned.
+
+        >>> a.count(axis=0)
+        array([1, 1, 1])
+        >>> a.count(axis=1)
+        array([3, 0])
+
+        """
+        m = self._mask
+        s = self.shape
+        if m is nomask:
+            if axis is None:
+                return self.size
+            else:
+                n = s[axis]
+                t = list(s)
+                del t[axis]
+                return np.full(t, n, dtype=np.intp)
+        n1 = np.size(m, axis)
+        n2 = np.sum(m, axis=axis, dtype=np.intp)
+        if axis is None:
+            return (n1 - n2)
+        else:
+            return narray(n1 - n2)
+
+    flatten = _arraymethod('flatten')
+
+    def ravel(self, order='C'):
+        """
+        Returns a 1D version of self, as a view.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            The elements of `a` are read using this index order. 'C' means to
+            index the elements in C-like order, with the last axis index
+            changing fastest, back to the first axis index changing slowest.
+            'F' means to index the elements in Fortran-like index order, with
+            the first index changing fastest, and the last index changing
+            slowest. Note that the 'C' and 'F' options take no account of the
+            memory layout of the underlying array, and only refer to the order
+            of axis indexing.  'A' means to read the elements in Fortran-like
+            index order if `m` is Fortran *contiguous* in memory, C-like order
+            otherwise.  'K' means to read the elements in the order they occur
+            in memory, except for reversing the data when strides are negative.
+            By default, 'C' index order is used.
+
+        Returns
+        -------
+        MaskedArray
+            Output view is of shape ``(self.size,)`` (or
+            ``(np.ma.product(self.shape),)``).
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.ravel())
+        [1 -- 3 -- 5 -- 7 -- 9]
+
+        """
+        r = ndarray.ravel(self._data, order=order).view(type(self))
+        r._update_from(self)
+        if self._mask is not nomask:
+            r._mask = ndarray.ravel(self._mask, order=order).reshape(r.shape)
+        else:
+            r._mask = nomask
+        return r
+
+    repeat = _arraymethod('repeat')
+
+
+    def reshape(self, *s, **kwargs):
+        """
+        Give a new shape to the array without changing its data.
+
+        Returns a masked array containing the same data, but with a new shape.
+        The result is a view on the original array; if this is not possible, a
+        ValueError is raised.
+
+        Parameters
+        ----------
+        shape : int or tuple of ints
+            The new shape should be compatible with the original shape. If an
+            integer is supplied, then the result will be a 1-D array of that
+            length.
+        order : {'C', 'F'}, optional
+            Determines whether the array data should be viewed as in C
+            (row-major) or FORTRAN (column-major) order.
+
+        Returns
+        -------
+        reshaped_array : array
+            A new view on the array.
+
+        See Also
+        --------
+        reshape : Equivalent function in the masked array module.
+        numpy.ndarray.reshape : Equivalent method on ndarray object.
+        numpy.reshape : Equivalent function in the NumPy module.
+
+        Notes
+        -----
+        The reshaping operation cannot guarantee that a copy will not be made,
+        to modify the shape in place, use ``a.shape = s``
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2],[3,4]], mask=[1,0,0,1])
+        >>> print(x)
+        [[-- 2]
+         [3 --]]
+        >>> x = x.reshape((4,1))
+        >>> print(x)
+        [[--]
+         [2]
+         [3]
+         [--]]
+
+        """
+        kwargs.update(order=kwargs.get('order', 'C'))
+        result = self._data.reshape(*s, **kwargs).view(type(self))
+        result._update_from(self)
+        mask = self._mask
+        if mask is not nomask:
+            result._mask = mask.reshape(*s, **kwargs)
+        return result
+
+    def resize(self, newshape, refcheck=True, order=False):
+        """
+        .. warning::
+
+            This method does nothing, except raise a ValueError exception. A
+            masked array does not own its data and therefore cannot safely be
+            resized in place. Use the `numpy.ma.resize` function instead.
+
+        This method is difficult to implement safely and may be deprecated in
+        future releases of NumPy.
+
+        """
+        # Note : the 'order' keyword looks broken, let's just drop it
+        errmsg = "A masked array does not own its data "\
+                 "and therefore cannot be resized.\n" \
+                 "Use the numpy.ma.resize function instead."
+        raise ValueError(errmsg)
+
+    def put(self, indices, values, mode='raise'):
+        """
+        Set storage-indexed locations to corresponding values.
+
+        Sets self._data.flat[n] = values[n] for each n in indices.
+        If `values` is shorter than `indices` then it will repeat.
+        If `values` has some masked values, the initial mask is updated
+        in consequence, else the corresponding values are unmasked.
+
+        Parameters
+        ----------
+        indices : 1-D array_like
+            Target indices, interpreted as integers.
+        values : array_like
+            Values to place in self._data copy at target indices.
+        mode : {'raise', 'wrap', 'clip'}, optional
+            Specifies how out-of-bounds indices will behave.
+            'raise' : raise an error.
+            'wrap' : wrap around.
+            'clip' : clip to the range.
+
+        Notes
+        -----
+        `values` can be a scalar or length 1 array.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> x.put([0,4,8],[10,20,30])
+        >>> print(x)
+        [[10 -- 3]
+         [-- 20 --]
+         [7 -- 30]]
+
+        >>> x.put(4,999)
+        >>> print(x)
+        [[10 -- 3]
+         [-- 999 --]
+         [7 -- 30]]
+
+        """
+        # Hard mask: Get rid of the values/indices that fall on masked data
+        if self._hardmask and self._mask is not nomask:
+            mask = self._mask[indices]
+            indices = narray(indices, copy=False)
+            values = narray(values, copy=False, subok=True)
+            values.resize(indices.shape)
+            indices = indices[~mask]
+            values = values[~mask]
+
+        self._data.put(indices, values, mode=mode)
+
+        # short circut if neither self nor values are masked
+        if self._mask is nomask and getmask(values) is nomask:
+            return
+
+        m = getmaskarray(self).copy()
+
+        if getmask(values) is nomask:
+            m.put(indices, False, mode=mode)
+        else:
+            m.put(indices, values._mask, mode=mode)
+        m = make_mask(m, copy=False, shrink=True)
+        self._mask = m
+        return
+
+    def ids(self):
+        """
+        Return the addresses of the data and mask areas.
+
+        Parameters
+        ----------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([1, 2, 3], mask=[0, 1, 1])
+        >>> x.ids()
+        (166670640, 166659832)
+
+        If the array has no mask, the address of `nomask` is returned. This address
+        is typically not close to the data in memory:
+
+        >>> x = np.ma.array([1, 2, 3])
+        >>> x.ids()
+        (166691080, 3083169284L)
+
+        """
+        if self._mask is nomask:
+            return (self.ctypes.data, id(nomask))
+        return (self.ctypes.data, self._mask.ctypes.data)
+
+    def iscontiguous(self):
+        """
+        Return a boolean indicating whether the data is contiguous.
+
+        Parameters
+        ----------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([1, 2, 3])
+        >>> x.iscontiguous()
+        True
+
+        `iscontiguous` returns one of the flags of the masked array:
+
+        >>> x.flags
+          C_CONTIGUOUS : True
+          F_CONTIGUOUS : True
+          OWNDATA : False
+          WRITEABLE : True
+          ALIGNED : True
+          UPDATEIFCOPY : False
+
+        """
+        return self.flags['CONTIGUOUS']
+
+    def all(self, axis=None, out=None):
+        """
+        Check if all of the elements of `a` are true.
+
+        Performs a :func:`logical_and` over the given axis and returns the result.
+        Masked values are considered as True during computation.
+        For convenience, the output array is masked where ALL the values along the
+        current axis are masked: if the output would have been a scalar and that
+        all the values are masked, then the output is `masked`.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            Axis to perform the operation over.
+            If None, perform over flattened array.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        See Also
+        --------
+        all : equivalent function
+
+        Examples
+        --------
+        >>> np.ma.array([1,2,3]).all()
+        True
+        >>> a = np.ma.array([1,2,3], mask=True)
+        >>> (a.all() is np.ma.masked)
+        True
+
+        """
+        mask = _check_mask_axis(self._mask, axis)
+        if out is None:
+            d = self.filled(True).all(axis=axis).view(type(self))
+            if d.ndim:
+                d.__setmask__(mask)
+            elif mask:
+                return masked
+            return d
+        self.filled(True).all(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            if out.ndim or mask:
+                out.__setmask__(mask)
+        return out
+
+    def any(self, axis=None, out=None):
+        """
+        Check if any of the elements of `a` are true.
+
+        Performs a logical_or over the given axis and returns the result.
+        Masked values are considered as False during computation.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            Axis to perform the operation over.
+            If None, perform over flattened array and return a scalar.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        See Also
+        --------
+        any : equivalent function
+
+        """
+        mask = _check_mask_axis(self._mask, axis)
+        if out is None:
+            d = self.filled(False).any(axis=axis).view(type(self))
+            if d.ndim:
+                d.__setmask__(mask)
+            elif mask:
+                d = masked
+            return d
+        self.filled(False).any(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            if out.ndim or mask:
+                out.__setmask__(mask)
+        return out
+
+    def nonzero(self):
+        """
+        Return the indices of unmasked elements that are not zero.
+
+        Returns a tuple of arrays, one for each dimension, containing the
+        indices of the non-zero elements in that dimension. The corresponding
+        non-zero values can be obtained with::
+
+            a[a.nonzero()]
+
+        To group the indices by element, rather than dimension, use
+        instead::
+
+            np.transpose(a.nonzero())
+
+        The result of this is always a 2d array, with a row for each non-zero
+        element.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        tuple_of_arrays : tuple
+            Indices of elements that are non-zero.
+
+        See Also
+        --------
+        numpy.nonzero :
+            Function operating on ndarrays.
+        flatnonzero :
+            Return indices that are non-zero in the flattened version of the input
+            array.
+        ndarray.nonzero :
+            Equivalent ndarray method.
+        count_nonzero :
+            Counts the number of non-zero elements in the input array.
+
+        Examples
+        --------
+        >>> import numpy.ma as ma
+        >>> x = ma.array(np.eye(3))
+        >>> x
+        masked_array(data =
+         [[ 1.  0.  0.]
+         [ 0.  1.  0.]
+         [ 0.  0.  1.]],
+              mask =
+         False,
+              fill_value=1e+20)
+        >>> x.nonzero()
+        (array([0, 1, 2]), array([0, 1, 2]))
+
+        Masked elements are ignored.
+
+        >>> x[1, 1] = ma.masked
+        >>> x
+        masked_array(data =
+         [[1.0 0.0 0.0]
+         [0.0 -- 0.0]
+         [0.0 0.0 1.0]],
+              mask =
+         [[False False False]
+         [False  True False]
+         [False False False]],
+              fill_value=1e+20)
+        >>> x.nonzero()
+        (array([0, 2]), array([0, 2]))
+
+        Indices can also be grouped by element.
+
+        >>> np.transpose(x.nonzero())
+        array([[0, 0],
+               [2, 2]])
+
+        A common use for ``nonzero`` is to find the indices of an array, where
+        a condition is True.  Given an array `a`, the condition `a` > 3 is a
+        boolean array and since False is interpreted as 0, ma.nonzero(a > 3)
+        yields the indices of the `a` where the condition is true.
+
+        >>> a = ma.array([[1,2,3],[4,5,6],[7,8,9]])
+        >>> a > 3
+        masked_array(data =
+         [[False False False]
+         [ True  True  True]
+         [ True  True  True]],
+              mask =
+         False,
+              fill_value=999999)
+        >>> ma.nonzero(a > 3)
+        (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+        The ``nonzero`` method of the condition array can also be called.
+
+        >>> (a > 3).nonzero()
+        (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+        """
+        return narray(self.filled(0), copy=False).nonzero()
+
+    def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None):
+        """
+        (this docstring should be overwritten)
+        """
+        #!!!: implement out + test!
+        m = self._mask
+        if m is nomask:
+            result = super(MaskedArray, self).trace(offset=offset, axis1=axis1,
+                                                    axis2=axis2, out=out)
+            return result.astype(dtype)
+        else:
+            D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
+            return D.astype(dtype).filled(0).sum(axis=None, out=out)
+    trace.__doc__ = ndarray.trace.__doc__
+
+    def dot(self, b, out=None, strict=False):
+        """
+        a.dot(b, out=None)
+
+        Masked dot product of two arrays. Note that `out` and `strict` are
+        located in different positions than in `ma.dot`. In order to
+        maintain compatibility with the functional version, it is
+        recommended that the optional arguments be treated as keyword only.
+        At some point that may be mandatory.
+
+        .. versionadded:: 1.10.0
+
+        Parameters
+        ----------
+        b : masked_array_like
+            Inputs array.
+        out : masked_array, optional
+            Output argument. This must have the exact kind that would be
+            returned if it was not used. In particular, it must have the
+            right type, must be C-contiguous, and its dtype must be the
+            dtype that would be returned for `ma.dot(a,b)`. This is a
+            performance feature. Therefore, if these conditions are not
+            met, an exception is raised, instead of attempting to be
+            flexible.
+        strict : bool, optional
+            Whether masked data are propagated (True) or set to 0 (False)
+            for the computation. Default is False.  Propagating the mask
+            means that if a masked value appears in a row or column, the
+            whole row or column is considered masked.
+
+            .. versionadded:: 1.10.2
+
+        See Also
+        --------
+        numpy.ma.dot : equivalent function
+
+        """
+        return dot(self, b, out=out, strict=strict)
+
+    def sum(self, axis=None, dtype=None, out=None):
+        """
+        Return the sum of the array elements over the given axis.
+        Masked elements are set to 0 internally.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the sum is computed. The default
+            (`axis` = None) is to compute over the flattened array.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are summed. If dtype has the value None and
+            the type of a is an integer type of precision less than the default
+            platform integer, then the default platform integer precision is
+            used.  Otherwise, the dtype is the same as that of a.
+        out :  {None, ndarray}, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        sum_along_axis : MaskedArray or scalar
+            An array with the same shape as self, with the specified
+            axis removed.   If self is a 0-d array, or if `axis` is None, a scalar
+            is returned.  If an output array is specified, a reference to
+            `out` is returned.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.sum())
+        25
+        >>> print(x.sum(axis=1))
+        [4 5 16]
+        >>> print(x.sum(axis=0))
+        [8 5 12]
+        >>> print(type(x.sum(axis=0, dtype=np.int64)[0]))
+        <type 'numpy.int64'>
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        # No explicit output
+        if out is None:
+            result = self.filled(0).sum(axis, dtype=dtype)
+            rndim = getattr(result, 'ndim', 0)
+            if rndim:
+                result = result.view(type(self))
+                result.__setmask__(newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(0).sum(axis, dtype=dtype, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        return out
+
+    def cumsum(self, axis=None, dtype=None, out=None):
+        """
+        Return the cumulative sum of the elements along the given axis.
+        The cumulative sum is calculated over the flattened array by
+        default, otherwise over the specified axis.
+
+        Masked values are set to 0 internally during the computation.
+        However, their position is saved, and the result will be masked at
+        the same locations.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the sum is computed. The default (`axis` = None) is to
+            compute over the flattened array. `axis` may be negative, in which case
+            it counts from the   last to the first axis.
+        dtype : {None, dtype}, optional
+            Type of the returned array and of the accumulator in which the
+            elements are summed.  If `dtype` is not specified, it defaults
+            to the dtype of `a`, unless `a` has an integer dtype with a
+            precision less than that of the default platform integer.  In
+            that case, the default platform integer is used.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        cumsum : ndarray.
+            A new array holding the result is returned unless ``out`` is
+            specified, in which case a reference to ``out`` is returned.
+
+        Notes
+        -----
+        The mask is lost if `out` is not a valid :class:`MaskedArray` !
+
+        Arithmetic is modular when using integer types, and no error is
+        raised on overflow.
+
+        Examples
+        --------
+        >>> marr = np.ma.array(np.arange(10), mask=[0,0,0,1,1,1,0,0,0,0])
+        >>> print(marr.cumsum())
+        [0 1 3 -- -- -- 9 16 24 33]
+
+        """
+        result = self.filled(0).cumsum(axis=axis, dtype=dtype, out=out)
+        if out is not None:
+            if isinstance(out, MaskedArray):
+                out.__setmask__(self.mask)
+            return out
+        result = result.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    def prod(self, axis=None, dtype=None, out=None):
+        """
+        Return the product of the array elements over the given axis.
+        Masked elements are set to 1 internally for computation.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis over which the product is taken. If None is used, then the
+            product is over all the array elements.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are multiplied. If ``dtype`` has the value ``None``
+            and the type of a is an integer type of precision less than the default
+            platform integer, then the default platform integer precision is
+            used.  Otherwise, the dtype is the same as that of a.
+        out : {None, array}, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        product_along_axis : {array, scalar}, see dtype parameter above.
+            Returns an array whose shape is the same as a with the specified
+            axis removed. Returns a 0d array when a is 1d or axis=None.
+            Returns a reference to the specified output array if specified.
+
+        See Also
+        --------
+        prod : equivalent function
+
+        Notes
+        -----
+        Arithmetic is modular when using integer types, and no error is raised
+        on overflow.
+
+        Examples
+        --------
+        >>> np.prod([1.,2.])
+        2.0
+        >>> np.prod([1.,2.], dtype=np.int32)
+        2
+        >>> np.prod([[1.,2.],[3.,4.]])
+        24.0
+        >>> np.prod([[1.,2.],[3.,4.]], axis=1)
+        array([  2.,  12.])
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        # No explicit output
+        if out is None:
+            result = self.filled(1).prod(axis, dtype=dtype)
+            rndim = getattr(result, 'ndim', 0)
+            if rndim:
+                result = result.view(type(self))
+                result.__setmask__(newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(1).prod(axis, dtype=dtype, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        return out
+
+    product = prod
+
+    def cumprod(self, axis=None, dtype=None, out=None):
+        """
+        Return the cumulative product of the elements along the given axis.
+        The cumulative product is taken over the flattened array by
+        default, otherwise over the specified axis.
+
+        Masked values are set to 1 internally during the computation.
+        However, their position is saved, and the result will be masked at
+        the same locations.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the product is computed. The default
+            (`axis` = None) is to compute over the flattened array.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are multiplied. If ``dtype`` has the value ``None``
+            and the type of ``a`` is an integer type of precision less than the
+            default platform integer, then the default platform integer precision
+            is used.  Otherwise, the dtype is the same as that of ``a``.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        cumprod : ndarray
+            A new array holding the result is returned unless out is specified,
+            in which case a reference to out is returned.
+
+        Notes
+        -----
+        The mask is lost if `out` is not a valid MaskedArray !
+
+        Arithmetic is modular when using integer types, and no error is
+        raised on overflow.
+
+        """
+        result = self.filled(1).cumprod(axis=axis, dtype=dtype, out=out)
+        if out is not None:
+            if isinstance(out, MaskedArray):
+                out.__setmask__(self._mask)
+            return out
+        result = result.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    def mean(self, axis=None, dtype=None, out=None):
+        """
+        Returns the average of the array elements.
+
+        Masked entries are ignored.
+        The average is taken over the flattened array by default, otherwise over
+        the specified axis. Refer to `numpy.mean` for the full documentation.
+
+        Parameters
+        ----------
+        a : array_like
+            Array containing numbers whose mean is desired. If `a` is not an
+            array, a conversion is attempted.
+        axis : int, optional
+            Axis along which the means are computed. The default is to compute
+            the mean of the flattened array.
+        dtype : dtype, optional
+            Type to use in computing the mean. For integer inputs, the default
+            is float64; for floating point, inputs it is the same as the input
+            dtype.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        mean : ndarray, see dtype parameter above
+            If `out=None`, returns a new array containing the mean values,
+            otherwise a reference to the output array is returned.
+
+        See Also
+        --------
+        numpy.ma.mean : Equivalent function.
+        numpy.mean : Equivalent function on non-masked arrays.
+        numpy.ma.average: Weighted average.
+
+        Examples
+        --------
+        >>> a = np.ma.array([1,2,3], mask=[False, False, True])
+        >>> a
+        masked_array(data = [1 2 --],
+                     mask = [False False  True],
+               fill_value = 999999)
+        >>> a.mean()
+        1.5
+
+        """
+        if self._mask is nomask:
+            result = super(MaskedArray, self).mean(axis=axis, dtype=dtype)
+        else:
+            dsum = self.sum(axis=axis, dtype=dtype)
+            cnt = self.count(axis=axis)
+            if cnt.shape == () and (cnt == 0):
+                result = masked
+            else:
+                result = dsum * 1. / cnt
+        if out is not None:
+            out.flat = result
+            if isinstance(out, MaskedArray):
+                outmask = getattr(out, '_mask', nomask)
+                if (outmask is nomask):
+                    outmask = out._mask = make_mask_none(out.shape)
+                outmask.flat = getattr(result, '_mask', nomask)
+            return out
+        return result
+
+    def anom(self, axis=None, dtype=None):
+        """
+        Compute the anomalies (deviations from the arithmetic mean)
+        along the given axis.
+
+        Returns an array of anomalies, with the same shape as the input and
+        where the arithmetic mean is computed along the given axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis over which the anomalies are taken.
+            The default is to use the mean of the flattened array as reference.
+        dtype : dtype, optional
+            Type to use in computing the variance. For arrays of integer type
+             the default is float32; for arrays of float types it is the same as
+             the array type.
+
+        See Also
+        --------
+        mean : Compute the mean of the array.
+
+        Examples
+        --------
+        >>> a = np.ma.array([1,2,3])
+        >>> a.anom()
+        masked_array(data = [-1.  0.  1.],
+                     mask = False,
+               fill_value = 1e+20)
+
+        """
+        m = self.mean(axis, dtype)
+        if m is masked:
+            return m
+
+        if not axis:
+            return (self - m)
+        else:
+            return (self - expand_dims(m, axis))
+
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        ""
+        # Easy case: nomask, business as usual
+        if self._mask is nomask:
+            return self._data.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        # Some data are masked, yay!
+        cnt = self.count(axis=axis) - ddof
+        danom = self.anom(axis=axis, dtype=dtype)
+        if iscomplexobj(self):
+            danom = umath.absolute(danom) ** 2
+        else:
+            danom *= danom
+        dvar = divide(danom.sum(axis), cnt).view(type(self))
+        # Apply the mask if it's not a scalar
+        if dvar.ndim:
+            dvar._mask = mask_or(self._mask.all(axis), (cnt <= 0))
+            dvar._update_from(self)
+        elif getattr(dvar, '_mask', False):
+            # Make sure that masked is returned when the scalar is masked.
+            dvar = masked
+            if out is not None:
+                if isinstance(out, MaskedArray):
+                    out.flat = 0
+                    out.__setmask__(True)
+                elif out.dtype.kind in 'biu':
+                    errmsg = "Masked data information would be lost in one or "\
+                             "more location."
+                    raise MaskError(errmsg)
+                else:
+                    out.flat = np.nan
+                return out
+        # In case with have an explicit output
+        if out is not None:
+            # Set the data
+            out.flat = dvar
+            # Set the mask if needed
+            if isinstance(out, MaskedArray):
+                out.__setmask__(dvar.mask)
+            return out
+        return dvar
+    var.__doc__ = np.var.__doc__
+
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        ""
+        dvar = self.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        if dvar is not masked:
+            if out is not None:
+                np.power(out, 0.5, out=out, casting='unsafe')
+                return out
+            dvar = sqrt(dvar)
+        return dvar
+    std.__doc__ = np.std.__doc__
+
+    def round(self, decimals=0, out=None):
+        """
+        Return an array rounded a to the given number of decimals.
+
+        Refer to `numpy.around` for full documentation.
+
+        See Also
+        --------
+        numpy.around : equivalent function
+
+        """
+        result = self._data.round(decimals=decimals, out=out).view(type(self))
+        if result.ndim > 0:
+            result._mask = self._mask
+            result._update_from(self)
+        elif self._mask:
+            # Return masked when the scalar is masked
+            result = masked
+        # No explicit output: we're done
+        if out is None:
+            return result
+        if isinstance(out, MaskedArray):
+            out.__setmask__(self._mask)
+        return out
+    round.__doc__ = ndarray.round.__doc__
+
+    def argsort(self, axis=None, kind='quicksort', order=None, fill_value=None):
+        """
+        Return an ndarray of indices that sort the array along the
+        specified axis.  Masked values are filled beforehand to
+        `fill_value`.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which to sort.  The default is -1 (last axis).
+            If None, the flattened array is used.
+        fill_value : var, optional
+            Value used to fill the array before sorting.
+            The default is the `fill_value` attribute of the input array.
+        kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+            Sorting algorithm.
+        order : list, optional
+            When `a` is an array with fields defined, this argument specifies
+            which fields to compare first, second, etc.  Not all fields need be
+            specified.
+
+        Returns
+        -------
+        index_array : ndarray, int
+            Array of indices that sort `a` along the specified axis.
+            In other words, ``a[index_array]`` yields a sorted `a`.
+
+        See Also
+        --------
+        sort : Describes sorting algorithms used.
+        lexsort : Indirect stable sort with multiple keys.
+        ndarray.sort : Inplace sort.
+
+        Notes
+        -----
+        See `sort` for notes on the different sorting algorithms.
+
+        Examples
+        --------
+        >>> a = np.ma.array([3,2,1], mask=[False, False, True])
+        >>> a
+        masked_array(data = [3 2 --],
+                     mask = [False False  True],
+               fill_value = 999999)
+        >>> a.argsort()
+        array([1, 0, 2])
+
+        """
+        if fill_value is None:
+            fill_value = default_fill_value(self)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argsort(axis=axis, kind=kind, order=order)
+
+    def argmin(self, axis=None, fill_value=None, out=None):
+        """
+        Return array of indices to the minimum values along the given axis.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            If None, the index is into the flattened array, otherwise along
+            the specified axis
+        fill_value : {var}, optional
+            Value used to fill in the masked values.  If None, the output of
+            minimum_fill_value(self._data) is used instead.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        Returns
+        -------
+        ndarray or scalar
+            If multi-dimension input, returns a new ndarray of indices to the
+            minimum values along the given axis.  Otherwise, returns a scalar
+            of index to the minimum values along the given axis.
+
+        Examples
+        --------
+        >>> x = np.ma.array(arange(4), mask=[1,1,0,0])
+        >>> x.shape = (2,2)
+        >>> print(x)
+        [[-- --]
+         [2 3]]
+        >>> print(x.argmin(axis=0, fill_value=-1))
+        [0 0]
+        >>> print(x.argmin(axis=0, fill_value=9))
+        [1 1]
+
+        """
+        if fill_value is None:
+            fill_value = minimum_fill_value(self)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argmin(axis, out=out)
+
+    def argmax(self, axis=None, fill_value=None, out=None):
+        """
+        Returns array of indices of the maximum values along the given axis.
+        Masked values are treated as if they had the value fill_value.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            If None, the index is into the flattened array, otherwise along
+            the specified axis
+        fill_value : {var}, optional
+            Value used to fill in the masked values.  If None, the output of
+            maximum_fill_value(self._data) is used instead.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        Returns
+        -------
+        index_array : {integer_array}
+
+        Examples
+        --------
+        >>> a = np.arange(6).reshape(2,3)
+        >>> a.argmax()
+        5
+        >>> a.argmax(0)
+        array([1, 1, 1])
+        >>> a.argmax(1)
+        array([2, 2])
+
+        """
+        if fill_value is None:
+            fill_value = maximum_fill_value(self._data)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argmax(axis, out=out)
+
+    def sort(self, axis=-1, kind='quicksort', order=None,
+             endwith=True, fill_value=None):
+        """
+        Sort the array, in-place
+
+        Parameters
+        ----------
+        a : array_like
+            Array to be sorted.
+        axis : int, optional
+            Axis along which to sort. If None, the array is flattened before
+            sorting. The default is -1, which sorts along the last axis.
+        kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+            Sorting algorithm. Default is 'quicksort'.
+        order : list, optional
+            When `a` is a structured array, this argument specifies which fields
+            to compare first, second, and so on.  This list does not need to
+            include all of the fields.
+        endwith : {True, False}, optional
+            Whether missing values (if any) should be forced in the upper indices
+            (at the end of the array) (True) or lower indices (at the beginning).
+            When the array contains unmasked values of the largest (or smallest if
+            False) representable value of the datatype the ordering of these values
+            and the masked values is undefined.  To enforce the masked values are
+            at the end (beginning) in this case one must sort the mask.
+        fill_value : {var}, optional
+            Value used internally for the masked values.
+            If ``fill_value`` is not None, it supersedes ``endwith``.
+
+        Returns
+        -------
+        sorted_array : ndarray
+            Array of the same type and shape as `a`.
+
+        See Also
+        --------
+        ndarray.sort : Method to sort an array in-place.
+        argsort : Indirect sort.
+        lexsort : Indirect stable sort on multiple keys.
+        searchsorted : Find elements in a sorted array.
+
+        Notes
+        -----
+        See ``sort`` for notes on the different sorting algorithms.
+
+        Examples
+        --------
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # Default
+        >>> a.sort()
+        >>> print(a)
+        [1 3 5 -- --]
+
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # Put missing values in the front
+        >>> a.sort(endwith=False)
+        >>> print(a)
+        [-- -- 1 3 5]
+
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # fill_value takes over endwith
+        >>> a.sort(endwith=False, fill_value=3)
+        >>> print(a)
+        [1 -- -- 3 5]
+
+        """
+        if self._mask is nomask:
+            ndarray.sort(self, axis=axis, kind=kind, order=order)
+        else:
+            if self is masked:
+                return self
+            if fill_value is None:
+                if endwith:
+                    # nan > inf
+                    if np.issubdtype(self.dtype, np.floating):
+                        filler = np.nan
+                    else:
+                        filler = minimum_fill_value(self)
+                else:
+                    filler = maximum_fill_value(self)
+            else:
+                filler = fill_value
+
+            sidx = self.filled(filler).argsort(axis=axis, kind=kind,
+                                               order=order)
+            # save meshgrid memory for 1d arrays
+            if self.ndim == 1:
+                idx = sidx
+            else:
+                idx = np.meshgrid(*[np.arange(x) for x in self.shape], sparse=True,
+                                  indexing='ij')
+                idx[axis] = sidx
+            tmp_mask = self._mask[idx].flat
+            tmp_data = self._data[idx].flat
+            self._data.flat = tmp_data
+            self._mask.flat = tmp_mask
+        return
+
+    def min(self, axis=None, out=None, fill_value=None):
+        """
+        Return the minimum along a given axis.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to operate.  By default, ``axis`` is None and the
+            flattened input is used.
+        out : array_like, optional
+            Alternative output array in which to place the result.  Must be of
+            the same shape and buffer length as the expected output.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+            If None, use the output of `minimum_fill_value`.
+
+        Returns
+        -------
+        amin : array_like
+            New array holding the result.
+            If ``out`` was specified, ``out`` is returned.
+
+        See Also
+        --------
+        minimum_fill_value
+            Returns the minimum filling value for a given datatype.
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        if fill_value is None:
+            fill_value = minimum_fill_value(self)
+        # No explicit output
+        if out is None:
+            result = self.filled(fill_value).min(
+                axis=axis, out=out).view(type(self))
+            if result.ndim:
+                # Set the mask
+                result.__setmask__(newmask)
+                # Get rid of Infs
+                if newmask.ndim:
+                    np.copyto(result, result.fill_value, where=newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(fill_value).min(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        else:
+            if out.dtype.kind in 'biu':
+                errmsg = "Masked data information would be lost in one or more"\
+                         " location."
+                raise MaskError(errmsg)
+            np.copyto(out, np.nan, where=newmask)
+        return out
+
+    def mini(self, axis=None):
+        """
+        Return the array minimum along the specified axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            The axis along which to find the minima. Default is None, in which case
+            the minimum value in the whole array is returned.
+
+        Returns
+        -------
+        min : scalar or MaskedArray
+            If `axis` is None, the result is a scalar. Otherwise, if `axis` is
+            given and the array is at least 2-D, the result is a masked array with
+            dimension one smaller than the array on which `mini` is called.
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.arange(6), mask=[0 ,1, 0, 0, 0 ,1]).reshape(3, 2)
+        >>> print(x)
+        [[0 --]
+         [2 3]
+         [4 --]]
+        >>> x.mini()
+        0
+        >>> x.mini(axis=0)
+        masked_array(data = [0 3],
+                     mask = [False False],
+               fill_value = 999999)
+        >>> print(x.mini(axis=1))
+        [0 2 4]
+
+        """
+        if axis is None:
+            return minimum(self)
+        else:
+            return minimum.reduce(self, axis)
+
+    def max(self, axis=None, out=None, fill_value=None):
+        """
+        Return the maximum along a given axis.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to operate.  By default, ``axis`` is None and the
+            flattened input is used.
+        out : array_like, optional
+            Alternative output array in which to place the result.  Must
+            be of the same shape and buffer length as the expected output.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+            If None, use the output of maximum_fill_value().
+
+        Returns
+        -------
+        amax : array_like
+            New array holding the result.
+            If ``out`` was specified, ``out`` is returned.
+
+        See Also
+        --------
+        maximum_fill_value
+            Returns the maximum filling value for a given datatype.
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        if fill_value is None:
+            fill_value = maximum_fill_value(self)
+        # No explicit output
+        if out is None:
+            result = self.filled(fill_value).max(
+                axis=axis, out=out).view(type(self))
+            if result.ndim:
+                # Set the mask
+                result.__setmask__(newmask)
+                # Get rid of Infs
+                if newmask.ndim:
+                    np.copyto(result, result.fill_value, where=newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(fill_value).max(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        else:
+
+            if out.dtype.kind in 'biu':
+                errmsg = "Masked data information would be lost in one or more"\
+                         " location."
+                raise MaskError(errmsg)
+            np.copyto(out, np.nan, where=newmask)
+        return out
+
+    def ptp(self, axis=None, out=None, fill_value=None):
+        """
+        Return (maximum - minimum) along the the given dimension
+        (i.e. peak-to-peak value).
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to find the peaks.  If None (default) the
+            flattened array is used.
+        out : {None, array_like}, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+
+        Returns
+        -------
+        ptp : ndarray.
+            A new array holding the result, unless ``out`` was
+            specified, in which case a reference to ``out`` is returned.
+
+        """
+        if out is None:
+            result = self.max(axis=axis, fill_value=fill_value)
+            result -= self.min(axis=axis, fill_value=fill_value)
+            return result
+        out.flat = self.max(axis=axis, out=out, fill_value=fill_value)
+        min_value = self.min(axis=axis, fill_value=fill_value)
+        np.subtract(out, min_value, out=out, casting='unsafe')
+        return out
+
+    def take(self, indices, axis=None, out=None, mode='raise'):
+        """
+        """
+        (_data, _mask) = (self._data, self._mask)
+        cls = type(self)
+        # Make sure the indices are not masked
+        maskindices = getattr(indices, '_mask', nomask)
+        if maskindices is not nomask:
+            indices = indices.filled(0)
+        # Get the data
+        if out is None:
+            out = _data.take(indices, axis=axis, mode=mode).view(cls)
+        else:
+            np.take(_data, indices, axis=axis, mode=mode, out=out)
+        # Get the mask
+        if isinstance(out, MaskedArray):
+            if _mask is nomask:
+                outmask = maskindices
+            else:
+                outmask = _mask.take(indices, axis=axis, mode=mode)
+                outmask |= maskindices
+            out.__setmask__(outmask)
+        return out
+
+    # Array methods
+    copy = _arraymethod('copy')
+    diagonal = _arraymethod('diagonal')
+    transpose = _arraymethod('transpose')
+    T = property(fget=lambda self: self.transpose())
+    swapaxes = _arraymethod('swapaxes')
+    clip = _arraymethod('clip', onmask=False)
+    copy = _arraymethod('copy')
+    squeeze = _arraymethod('squeeze')
+
+    def tolist(self, fill_value=None):
+        """
+        Return the data portion of the masked array as a hierarchical Python list.
+
+        Data items are converted to the nearest compatible Python type.
+        Masked values are converted to `fill_value`. If `fill_value` is None,
+        the corresponding entries in the output list will be ``None``.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries. Default is None.
+
+        Returns
+        -------
+        result : list
+            The Python list representation of the masked array.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3], [4,5,6], [7,8,9]], mask=[0] + [1,0]*4)
+        >>> x.tolist()
+        [[1, None, 3], [None, 5, None], [7, None, 9]]
+        >>> x.tolist(-999)
+        [[1, -999, 3], [-999, 5, -999], [7, -999, 9]]
+
+        """
+        _mask = self._mask
+        # No mask ? Just return .data.tolist ?
+        if _mask is nomask:
+            return self._data.tolist()
+        # Explicit fill_value: fill the array and get the list
+        if fill_value is not None:
+            return self.filled(fill_value).tolist()
+        # Structured array.
+        names = self.dtype.names
+        if names:
+            result = self._data.astype([(_, object) for _ in names])
+            for n in names:
+                result[n][_mask[n]] = None
+            return result.tolist()
+        # Standard arrays.
+        if _mask is nomask:
+            return [None]
+        # Set temps to save time when dealing w/ marrays.
+        inishape = self.shape
+        result = np.array(self._data.ravel(), dtype=object)
+        result[_mask.ravel()] = None
+        result.shape = inishape
+        return result.tolist()
+
+    def tostring(self, fill_value=None, order='C'):
+        """
+        This function is a compatibility alias for tobytes. Despite its name it
+        returns bytes not strings.
+        """
+
+        return self.tobytes(fill_value, order='C')
+
+    def tobytes(self, fill_value=None, order='C'):
+        """
+        Return the array data as a string containing the raw bytes in the array.
+
+        The array is filled with a fill value before the string conversion.
+
+        .. versionadded:: 1.9.0
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            Value used to fill in the masked values. Deafult is None, in which
+            case `MaskedArray.fill_value` is used.
+        order : {'C','F','A'}, optional
+            Order of the data item in the copy. Default is 'C'.
+
+            - 'C'   -- C order (row major).
+            - 'F'   -- Fortran order (column major).
+            - 'A'   -- Any, current order of array.
+            - None  -- Same as 'A'.
+
+        See Also
+        --------
+        ndarray.tobytes
+        tolist, tofile
+
+        Notes
+        -----
+        As for `ndarray.tobytes`, information about the shape, dtype, etc.,
+        but also about `fill_value`, will be lost.
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.array([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
+        >>> x.tobytes()
+        '\\x01\\x00\\x00\\x00?B\\x0f\\x00?B\\x0f\\x00\\x04\\x00\\x00\\x00'
+
+        """
+        return self.filled(fill_value).tobytes(order=order)
+
+    def tofile(self, fid, sep="", format="%s"):
+        """
+        Save a masked array to a file in binary format.
+
+        .. warning::
+          This function is not implemented yet.
+
+        Raises
+        ------
+        NotImplementedError
+            When `tofile` is called.
+
+        """
+        raise NotImplementedError("MaskedArray.tofile() not implemented yet.")
+
+    def toflex(self):
+        """
+        Transforms a masked array into a flexible-type array.
+
+        The flexible type array that is returned will have two fields:
+
+        * the ``_data`` field stores the ``_data`` part of the array.
+        * the ``_mask`` field stores the ``_mask`` part of the array.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        record : ndarray
+            A new flexible-type `ndarray` with two fields: the first element
+            containing a value, the second element containing the corresponding
+            mask boolean. The returned record shape matches self.shape.
+
+        Notes
+        -----
+        A side-effect of transforming a masked array into a flexible `ndarray` is
+        that meta information (``fill_value``, ...) will be lost.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.toflex())
+        [[(1, False) (2, True) (3, False)]
+         [(4, True) (5, False) (6, True)]
+         [(7, False) (8, True) (9, False)]]
+
+        """
+        # Get the basic dtype.
+        ddtype = self.dtype
+        # Make sure we have a mask
+        _mask = self._mask
+        if _mask is None:
+            _mask = make_mask_none(self.shape, ddtype)
+        # And get its dtype
+        mdtype = self._mask.dtype
+
+        record = np.ndarray(shape=self.shape,
+                            dtype=[('_data', ddtype), ('_mask', mdtype)])
+        record['_data'] = self._data
+        record['_mask'] = self._mask
+        return record
+    torecords = toflex
+
+    # Pickling
+    def __getstate__(self):
+        """Return the internal state of the masked array, for pickling
+        purposes.
+
+        """
+        cf = 'CF'[self.flags.fnc]
+        state = (1,
+                 self.shape,
+                 self.dtype,
+                 self.flags.fnc,
+                 self._data.tobytes(cf),
+                 # self._data.tolist(),
+                 getmaskarray(self).tobytes(cf),
+                 # getmaskarray(self).tolist(),
+                 self._fill_value,
+                 )
+        return state
+
+    def __setstate__(self, state):
+        """Restore the internal state of the masked array, for
+        pickling purposes.  ``state`` is typically the output of the
+        ``__getstate__`` output, and is a 5-tuple:
+
+        - class name
+        - a tuple giving the shape of the data
+        - a typecode for the data
+        - a binary string for the data
+        - a binary string for the mask.
+
+        """
+        (_, shp, typ, isf, raw, msk, flv) = state
+        super(MaskedArray, self).__setstate__((shp, typ, isf, raw))
+        self._mask.__setstate__((shp, make_mask_descr(typ), isf, msk))
+        self.fill_value = flv
+
+    def __reduce__(self):
+        """Return a 3-tuple for pickling a MaskedArray.
+
+        """
+        return (_mareconstruct,
+                (self.__class__, self._baseclass, (0,), 'b',),
+                self.__getstate__())
+
+    def __deepcopy__(self, memo=None):
+        from copy import deepcopy
+        copied = MaskedArray.__new__(type(self), self, copy=True)
+        if memo is None:
+            memo = {}
+        memo[id(self)] = copied
+        for (k, v) in self.__dict__.items():
+            copied.__dict__[k] = deepcopy(v, memo)
+        return copied
+
+
+def _mareconstruct(subtype, baseclass, baseshape, basetype,):
+    """Internal function that builds a new MaskedArray from the
+    information stored in a pickle.
+
+    """
+    _data = ndarray.__new__(baseclass, baseshape, basetype)
+    _mask = ndarray.__new__(ndarray, baseshape, make_mask_descr(basetype))
+    return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
+
+class mvoid(MaskedArray):
+    """
+    Fake a 'void' object to use for masked array with structured dtypes.
+    """
+
+    def __new__(self, data, mask=nomask, dtype=None, fill_value=None,
+                hardmask=False, copy=False, subok=True):
+        _data = np.array(data, copy=copy, subok=subok, dtype=dtype)
+        _data = _data.view(self)
+        _data._hardmask = hardmask
+        if mask is not nomask:
+            if isinstance(mask, np.void):
+                _data._mask = mask
+            else:
+                try:
+                    # Mask is already a 0D array
+                    _data._mask = np.void(mask)
+                except TypeError:
+                    # Transform the mask to a void
+                    mdtype = make_mask_descr(dtype)
+                    _data._mask = np.array(mask, dtype=mdtype)[()]
+        if fill_value is not None:
+            _data.fill_value = fill_value
+        return _data
+
+    def _get_data(self):
+        # Make sure that the _data part is a np.void
+        return self.view(ndarray)[()]
+
+    _data = property(fget=_get_data)
+
+    def __getitem__(self, indx):
+        """
+        Get the index.
+
+        """
+        m = self._mask
+        if isinstance(m[indx], ndarray):
+            # Can happen when indx is a multi-dimensional field:
+            # A = ma.masked_array(data=[([0,1],)], mask=[([True,
+            #                     False],)], dtype=[("A", ">i2", (2,))])
+            # x = A[0]; y = x["A"]; then y.mask["A"].size==2
+            # and we can not say masked/unmasked.
+            # The result is no longer mvoid!
+            # See also issue #6724.
+            return masked_array(
+                data=self._data[indx], mask=m[indx],
+                fill_value=self._fill_value[indx],
+                hard_mask=self._hardmask)
+        if m is not nomask and m[indx]:
+            return masked
+        return self._data[indx]
+
+    def __setitem__(self, indx, value):
+        self._data[indx] = value
+        if self._hardmask:
+            self._mask[indx] |= getattr(value, "_mask", False)
+        else:
+            self._mask[indx] = getattr(value, "_mask", False)
+
+    def __str__(self):
+        m = self._mask
+        if m is nomask:
+            return self._data.__str__()
+        printopt = masked_print_option
+        rdtype = _recursive_make_descr(self._data.dtype, "O")
+        res = np.array([self._data]).astype(rdtype)
+        _recursive_printoption(res, self._mask, printopt)
+        return str(res[0])
+
+    __repr__ = __str__
+
+    def __iter__(self):
+        "Defines an iterator for mvoid"
+        (_data, _mask) = (self._data, self._mask)
+        if _mask is nomask:
+            for d in _data:
+                yield d
+        else:
+            for (d, m) in zip(_data, _mask):
+                if m:
+                    yield masked
+                else:
+                    yield d
+
+    def __len__(self):
+        return self._data.__len__()
+
+    def filled(self, fill_value=None):
+        """
+        Return a copy with masked fields filled with a given value.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries (None by default).
+            If None, the `fill_value` attribute is used instead.
+
+        Returns
+        -------
+        filled_void
+            A `np.void` object
+
+        See Also
+        --------
+        MaskedArray.filled
+
+        """
+        return asarray(self).filled(fill_value)[()]
+
+    def tolist(self):
+        """
+    Transforms the mvoid object into a tuple.
+
+    Masked fields are replaced by None.
+
+    Returns
+    -------
+    returned_tuple
+        Tuple of fields
+        """
+        _mask = self._mask
+        if _mask is nomask:
+            return self._data.tolist()
+        result = []
+        for (d, m) in zip(self._data, self._mask):
+            if m:
+                result.append(None)
+            else:
+                # .item() makes sure we return a standard Python object
+                result.append(d.item())
+        return tuple(result)
+
+
+##############################################################################
+#                                Shortcuts                                   #
+##############################################################################
+
+
+def isMaskedArray(x):
+    """
+    Test whether input is an instance of MaskedArray.
+
+    This function returns True if `x` is an instance of MaskedArray
+    and returns False otherwise.  Any object is accepted as input.
+
+    Parameters
+    ----------
+    x : object
+        Object to test.
+
+    Returns
+    -------
+    result : bool
+        True if `x` is a MaskedArray.
+
+    See Also
+    --------
+    isMA : Alias to isMaskedArray.
+    isarray : Alias to isMaskedArray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.eye(3, 3)
+    >>> a
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> m = ma.masked_values(a, 0)
+    >>> m
+    masked_array(data =
+     [[1.0 -- --]
+     [-- 1.0 --]
+     [-- -- 1.0]],
+          mask =
+     [[False  True  True]
+     [ True False  True]
+     [ True  True False]],
+          fill_value=0.0)
+    >>> ma.isMaskedArray(a)
+    False
+    >>> ma.isMaskedArray(m)
+    True
+    >>> ma.isMaskedArray([0, 1, 2])
+    False
+
+    """
+    return isinstance(x, MaskedArray)
+
+
+isarray = isMaskedArray
+isMA = isMaskedArray  # backward compatibility
+
+
+class MaskedConstant(MaskedArray):
+    # We define the masked singleton as a float for higher precedence.
+    # Note that it can be tricky sometimes w/ type comparison
+    _data = data = np.array(0.)
+    _mask = mask = np.array(True)
+    _baseclass = ndarray
+
+    def __new__(self):
+        return self._data.view(self)
+
+    def __array_finalize__(self, obj):
+        return
+
+    def __array_wrap__(self, obj):
+        return self
+
+    def __str__(self):
+        return str(masked_print_option._display)
+
+    def __repr__(self):
+        return 'masked'
+
+    def flatten(self):
+        return masked_array([self._data], dtype=float, mask=[True])
+
+    def __reduce__(self):
+        """Override of MaskedArray's __reduce__.
+        """
+        return (self.__class__, ())
+
+
+masked = masked_singleton = MaskedConstant()
+masked_array = MaskedArray
+
+
+def array(data, dtype=None, copy=False, order=None,
+          mask=nomask, fill_value=None, keep_mask=True,
+          hard_mask=False, shrink=True, subok=True, ndmin=0):
+    """
+    Shortcut to MaskedArray.
+
+    The options are in a different order for convenience and backwards
+    compatibility.
+
+    """
+    return MaskedArray(data, mask=mask, dtype=dtype, copy=copy,
+                       subok=subok, keep_mask=keep_mask,
+                       hard_mask=hard_mask, fill_value=fill_value,
+                       ndmin=ndmin, shrink=shrink, order=order)
+array.__doc__ = masked_array.__doc__
+
+
+def is_masked(x):
+    """
+    Determine whether input has masked values.
+
+    Accepts any object as input, but always returns False unless the
+    input is a MaskedArray containing masked values.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to check for masked values.
+
+    Returns
+    -------
+    result : bool
+        True if `x` is a MaskedArray with masked values, False otherwise.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.masked_equal([0, 1, 0, 2, 3], 0)
+    >>> x
+    masked_array(data = [-- 1 -- 2 3],
+          mask = [ True False  True False False],
+          fill_value=999999)
+    >>> ma.is_masked(x)
+    True
+    >>> x = ma.masked_equal([0, 1, 0, 2, 3], 42)
+    >>> x
+    masked_array(data = [0 1 0 2 3],
+          mask = False,
+          fill_value=999999)
+    >>> ma.is_masked(x)
+    False
+
+    Always returns False if `x` isn't a MaskedArray.
+
+    >>> x = [False, True, False]
+    >>> ma.is_masked(x)
+    False
+    >>> x = 'a string'
+    >>> ma.is_masked(x)
+    False
+
+    """
+    m = getmask(x)
+    if m is nomask:
+        return False
+    elif m.any():
+        return True
+    return False
+
+
+##############################################################################
+#                             Extrema functions                              #
+##############################################################################
+
+
+class _extrema_operation(object):
+    """
+    Generic class for maximum/minimum functions.
+
+    .. note::
+      This is the base class for `_maximum_operation` and
+      `_minimum_operation`.
+
+    """
+
+    def __call__(self, a, b=None):
+        "Executes the call behavior."
+        if b is None:
+            return self.reduce(a)
+        return where(self.compare(a, b), a, b)
+
+    def reduce(self, target, axis=None):
+        "Reduce target along the given axis."
+        target = narray(target, copy=False, subok=True)
+        m = getmask(target)
+        if axis is not None:
+            kargs = {'axis': axis}
+        else:
+            kargs = {}
+            target = target.ravel()
+            if not (m is nomask):
+                m = m.ravel()
+        if m is nomask:
+            t = self.ufunc.reduce(target, **kargs)
+        else:
+            target = target.filled(
+                self.fill_value_func(target)).view(type(target))
+            t = self.ufunc.reduce(target, **kargs)
+            m = umath.logical_and.reduce(m, **kargs)
+            if hasattr(t, '_mask'):
+                t._mask = m
+            elif m:
+                t = masked
+        return t
+
+    def outer(self, a, b):
+        "Return the function applied to the outer product of a and b."
+        ma = getmask(a)
+        mb = getmask(b)
+        if ma is nomask and mb is nomask:
+            m = nomask
+        else:
+            ma = getmaskarray(a)
+            mb = getmaskarray(b)
+            m = logical_or.outer(ma, mb)
+        result = self.ufunc.outer(filled(a), filled(b))
+        if not isinstance(result, MaskedArray):
+            result = result.view(MaskedArray)
+        result._mask = m
+        return result
+
+
+class _minimum_operation(_extrema_operation):
+
+    "Object to calculate minima"
+
+    def __init__(self):
+        """minimum(a, b) or minimum(a)
+In one argument case, returns the scalar minimum.
+        """
+        self.ufunc = umath.minimum
+        self.afunc = amin
+        self.compare = less
+        self.fill_value_func = minimum_fill_value
+
+
+class _maximum_operation(_extrema_operation):
+
+    "Object to calculate maxima"
+
+    def __init__(self):
+        """maximum(a, b) or maximum(a)
+           In one argument case returns the scalar maximum.
+        """
+        self.ufunc = umath.maximum
+        self.afunc = amax
+        self.compare = greater
+        self.fill_value_func = maximum_fill_value
+
+
+def min(obj, axis=None, out=None, fill_value=None):
+    try:
+        return obj.min(axis=axis, fill_value=fill_value, out=out)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a min method or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).min(axis=axis, fill_value=fill_value, out=out)
+min.__doc__ = MaskedArray.min.__doc__
+
+
+def max(obj, axis=None, out=None, fill_value=None):
+    try:
+        return obj.max(axis=axis, fill_value=fill_value, out=out)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a max method, or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).max(axis=axis, fill_value=fill_value, out=out)
+max.__doc__ = MaskedArray.max.__doc__
+
+
+def ptp(obj, axis=None, out=None, fill_value=None):
+    """
+    a.ptp(axis=None) =  a.max(axis) - a.min(axis)
+
+    """
+    try:
+        return obj.ptp(axis, out=out, fill_value=fill_value)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a ptp method or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).ptp(axis=axis, fill_value=fill_value, out=out)
+ptp.__doc__ = MaskedArray.ptp.__doc__
+
+
+##############################################################################
+#           Definition of functions from the corresponding methods           #
+##############################################################################
+
+
+class _frommethod:
+    """
+    Define functions from existing MaskedArray methods.
+
+    Parameters
+    ----------
+    methodname : str
+        Name of the method to transform.
+
+    """
+
+    def __init__(self, methodname, reversed=False):
+        self.__name__ = methodname
+        self.__doc__ = self.getdoc()
+        self.reversed = reversed
+
+    def getdoc(self):
+        "Return the doc of the function (from the doc of the method)."
+        meth = getattr(MaskedArray, self.__name__, None) or\
+            getattr(np, self.__name__, None)
+        signature = self.__name__ + get_object_signature(meth)
+        if meth is not None:
+            doc = """    %s\n%s""" % (
+                signature, getattr(meth, '__doc__', None))
+            return doc
+
+    def __call__(self, a, *args, **params):
+        if self.reversed:
+            args = list(args)
+            arr = args[0]
+            args[0] = a
+            a = arr
+        # Get the method from the array (if possible)
+        method_name = self.__name__
+        method = getattr(a, method_name, None)
+        if method is not None:
+            return method(*args, **params)
+        # Still here ? Then a is not a MaskedArray
+        method = getattr(MaskedArray, method_name, None)
+        if method is not None:
+            return method(MaskedArray(a), *args, **params)
+        # Still here ? OK, let's call the corresponding np function
+        method = getattr(np, method_name)
+        return method(a, *args, **params)
+
+
+all = _frommethod('all')
+anomalies = anom = _frommethod('anom')
+any = _frommethod('any')
+compress = _frommethod('compress', reversed=True)
+cumprod = _frommethod('cumprod')
+cumsum = _frommethod('cumsum')
+copy = _frommethod('copy')
+diagonal = _frommethod('diagonal')
+harden_mask = _frommethod('harden_mask')
+ids = _frommethod('ids')
+maximum = _maximum_operation()
+mean = _frommethod('mean')
+minimum = _minimum_operation()
+nonzero = _frommethod('nonzero')
+prod = _frommethod('prod')
+product = _frommethod('prod')
+ravel = _frommethod('ravel')
+repeat = _frommethod('repeat')
+shrink_mask = _frommethod('shrink_mask')
+soften_mask = _frommethod('soften_mask')
+std = _frommethod('std')
+sum = _frommethod('sum')
+swapaxes = _frommethod('swapaxes')
+#take = _frommethod('take')
+trace = _frommethod('trace')
+var = _frommethod('var')
+
+
+def take(a, indices, axis=None, out=None, mode='raise'):
+    """
+    """
+    a = masked_array(a)
+    return a.take(indices, axis=axis, out=out, mode=mode)
+
+
+def power(a, b, third=None):
+    """
+    Returns element-wise base array raised to power from second array.
+
+    This is the masked array version of `numpy.power`. For details see
+    `numpy.power`.
+
+    See Also
+    --------
+    numpy.power
+
+    Notes
+    -----
+    The *out* argument to `numpy.power` is not supported, `third` has to be
+    None.
+
+    """
+    if third is not None:
+        raise MaskError("3-argument power not supported.")
+    # Get the masks
+    ma = getmask(a)
+    mb = getmask(b)
+    m = mask_or(ma, mb)
+    # Get the rawdata
+    fa = getdata(a)
+    fb = getdata(b)
+    # Get the type of the result (so that we preserve subclasses)
+    if isinstance(a, MaskedArray):
+        basetype = type(a)
+    else:
+        basetype = MaskedArray
+    # Get the result and view it as a (subclass of) MaskedArray
+    with np.errstate(divide='ignore', invalid='ignore'):
+        result = np.where(m, fa, umath.power(fa, fb)).view(basetype)
+    result._update_from(a)
+    # Find where we're in trouble w/ NaNs and Infs
+    invalid = np.logical_not(np.isfinite(result.view(ndarray)))
+    # Add the initial mask
+    if m is not nomask:
+        if not (result.ndim):
+            return masked
+        result._mask = np.logical_or(m, invalid)
+    # Fix the invalid parts
+    if invalid.any():
+        if not result.ndim:
+            return masked
+        elif result._mask is nomask:
+            result._mask = invalid
+        result._data[invalid] = result.fill_value
+    return result
+
+
+def argsort(a, axis=None, kind='quicksort', order=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+    d = filled(a, fill_value)
+    if axis is None:
+        return d.argsort(kind=kind, order=order)
+    return d.argsort(axis, kind=kind, order=order)
+argsort.__doc__ = MaskedArray.argsort.__doc__
+
+
+def argmin(a, axis=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+    d = filled(a, fill_value)
+    return d.argmin(axis=axis)
+argmin.__doc__ = MaskedArray.argmin.__doc__
+
+
+def argmax(a, axis=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+        try:
+            fill_value = -fill_value
+        except:
+            pass
+    d = filled(a, fill_value)
+    return d.argmax(axis=axis)
+argmax.__doc__ = MaskedArray.argmax.__doc__
+
+
+def sort(a, axis=-1, kind='quicksort', order=None, endwith=True, fill_value=None):
+    "Function version of the eponymous method."
+    a = narray(a, copy=True, subok=True)
+    if axis is None:
+        a = a.flatten()
+        axis = 0
+    if fill_value is None:
+        if endwith:
+            # nan > inf
+            if np.issubdtype(a.dtype, np.floating):
+                filler = np.nan
+            else:
+                filler = minimum_fill_value(a)
+        else:
+            filler = maximum_fill_value(a)
+    else:
+        filler = fill_value
+
+    sindx = filled(a, filler).argsort(axis=axis, kind=kind, order=order)
+
+    # save meshgrid memory for 1d arrays
+    if a.ndim == 1:
+        indx = sindx
+    else:
+        indx = np.meshgrid(*[np.arange(x) for x in a.shape], sparse=True,
+                           indexing='ij')
+        indx[axis] = sindx
+    return a[indx]
+sort.__doc__ = MaskedArray.sort.__doc__
+
+
+def compressed(x):
+    """
+    Return all the non-masked data as a 1-D array.
+
+    This function is equivalent to calling the "compressed" method of a
+    `MaskedArray`, see `MaskedArray.compressed` for details.
+
+    See Also
+    --------
+    MaskedArray.compressed
+        Equivalent method.
+
+    """
+    if not isinstance(x, MaskedArray):
+        x = asanyarray(x)
+    return x.compressed()
+
+
+def concatenate(arrays, axis=0):
+    """
+    Concatenate a sequence of arrays along the given axis.
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        The arrays must have the same shape, except in the dimension
+        corresponding to `axis` (the first, by default).
+    axis : int, optional
+        The axis along which the arrays will be joined. Default is 0.
+
+    Returns
+    -------
+    result : MaskedArray
+        The concatenated array with any masked entries preserved.
+
+    See Also
+    --------
+    numpy.concatenate : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.arange(3)
+    >>> a[1] = ma.masked
+    >>> b = ma.arange(2, 5)
+    >>> a
+    masked_array(data = [0 -- 2],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> b
+    masked_array(data = [2 3 4],
+                 mask = False,
+           fill_value = 999999)
+    >>> ma.concatenate([a, b])
+    masked_array(data = [0 -- 2 2 3 4],
+                 mask = [False  True False False False False],
+           fill_value = 999999)
+
+    """
+    d = np.concatenate([getdata(a) for a in arrays], axis)
+    rcls = get_masked_subclass(*arrays)
+    data = d.view(rcls)
+    # Check whether one of the arrays has a non-empty mask.
+    for x in arrays:
+        if getmask(x) is not nomask:
+            break
+    else:
+        return data
+    # OK, so we have to concatenate the masks
+    dm = np.concatenate([getmaskarray(a) for a in arrays], axis)
+    # If we decide to keep a '_shrinkmask' option, we want to check that
+    # all of them are True, and then check for dm.any()
+    if not dm.dtype.fields and not dm.any():
+        data._mask = nomask
+    else:
+        data._mask = dm.reshape(d.shape)
+    return data
+
+
+def count(a, axis=None):
+    if isinstance(a, MaskedArray):
+        return a.count(axis)
+    return masked_array(a, copy=False).count(axis)
+count.__doc__ = MaskedArray.count.__doc__
+
+
+def diag(v, k=0):
+    """
+    Extract a diagonal or construct a diagonal array.
+
+    This function is the equivalent of `numpy.diag` that takes masked
+    values into account, see `numpy.diag` for details.
+
+    See Also
+    --------
+    numpy.diag : Equivalent function for ndarrays.
+
+    """
+    output = np.diag(v, k).view(MaskedArray)
+    if getmask(v) is not nomask:
+        output._mask = np.diag(v._mask, k)
+    return output
+
+
+def expand_dims(x, axis):
+    """
+    Expand the shape of an array.
+
+    Expands the shape of the array by including a new axis before the one
+    specified by the `axis` parameter. This function behaves the same as
+    `numpy.expand_dims` but preserves masked elements.
+
+    See Also
+    --------
+    numpy.expand_dims : Equivalent function in top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.array([1, 2, 4])
+    >>> x[1] = ma.masked
+    >>> x
+    masked_array(data = [1 -- 4],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> np.expand_dims(x, axis=0)
+    array([[1, 2, 4]])
+    >>> ma.expand_dims(x, axis=0)
+    masked_array(data =
+     [[1 -- 4]],
+                 mask =
+     [[False  True False]],
+           fill_value = 999999)
+
+    The same result can be achieved using slicing syntax with `np.newaxis`.
+
+    >>> x[np.newaxis, :]
+    masked_array(data =
+     [[1 -- 4]],
+                 mask =
+     [[False  True False]],
+           fill_value = 999999)
+
+    """
+    result = n_expand_dims(x, axis)
+    if isinstance(x, MaskedArray):
+        new_shape = result.shape
+        result = x.view()
+        result.shape = new_shape
+        if result._mask is not nomask:
+            result._mask.shape = new_shape
+    return result
+
+
+def left_shift(a, n):
+    """
+    Shift the bits of an integer to the left.
+
+    This is the masked array version of `numpy.left_shift`, for details
+    see that function.
+
+    See Also
+    --------
+    numpy.left_shift
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        d = umath.left_shift(filled(a), n)
+        return masked_array(d)
+    else:
+        d = umath.left_shift(filled(a, 0), n)
+        return masked_array(d, mask=m)
+
+
+def right_shift(a, n):
+    """
+    Shift the bits of an integer to the right.
+
+    This is the masked array version of `numpy.right_shift`, for details
+    see that function.
+
+    See Also
+    --------
+    numpy.right_shift
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        d = umath.right_shift(filled(a), n)
+        return masked_array(d)
+    else:
+        d = umath.right_shift(filled(a, 0), n)
+        return masked_array(d, mask=m)
+
+
+def put(a, indices, values, mode='raise'):
+    """
+    Set storage-indexed locations to corresponding values.
+
+    This function is equivalent to `MaskedArray.put`, see that method
+    for details.
+
+    See Also
+    --------
+    MaskedArray.put
+
+    """
+    # We can't use 'frommethod', the order of arguments is different
+    try:
+        return a.put(indices, values, mode=mode)
+    except AttributeError:
+        return narray(a, copy=False).put(indices, values, mode=mode)
+
+
+def putmask(a, mask, values):  # , mode='raise'):
+    """
+    Changes elements of an array based on conditional and input values.
+
+    This is the masked array version of `numpy.putmask`, for details see
+    `numpy.putmask`.
+
+    See Also
+    --------
+    numpy.putmask
+
+    Notes
+    -----
+    Using a masked array as `values` will **not** transform a `ndarray` into
+    a `MaskedArray`.
+
+    """
+    # We can't use 'frommethod', the order of arguments is different
+    if not isinstance(a, MaskedArray):
+        a = a.view(MaskedArray)
+    (valdata, valmask) = (getdata(values), getmask(values))
+    if getmask(a) is nomask:
+        if valmask is not nomask:
+            a._sharedmask = True
+            a._mask = make_mask_none(a.shape, a.dtype)
+            np.copyto(a._mask, valmask, where=mask)
+    elif a._hardmask:
+        if valmask is not nomask:
+            m = a._mask.copy()
+            np.copyto(m, valmask, where=mask)
+            a.mask |= m
+    else:
+        if valmask is nomask:
+            valmask = getmaskarray(values)
+        np.copyto(a._mask, valmask, where=mask)
+    np.copyto(a._data, valdata, where=mask)
+    return
+
+
+def transpose(a, axes=None):
+    """
+    Permute the dimensions of an array.
+
+    This function is exactly equivalent to `numpy.transpose`.
+
+    See Also
+    --------
+    numpy.transpose : Equivalent function in top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.arange(4).reshape((2,2))
+    >>> x[1, 1] = ma.masked
+    >>>> x
+    masked_array(data =
+     [[0 1]
+     [2 --]],
+                 mask =
+     [[False False]
+     [False  True]],
+           fill_value = 999999)
+    >>> ma.transpose(x)
+    masked_array(data =
+     [[0 2]
+     [1 --]],
+                 mask =
+     [[False False]
+     [False  True]],
+           fill_value = 999999)
+
+    """
+    # We can't use 'frommethod', as 'transpose' doesn't take keywords
+    try:
+        return a.transpose(axes)
+    except AttributeError:
+        return narray(a, copy=False).transpose(axes).view(MaskedArray)
+
+
+def reshape(a, new_shape, order='C'):
+    """
+    Returns an array containing the same data with a new shape.
+
+    Refer to `MaskedArray.reshape` for full documentation.
+
+    See Also
+    --------
+    MaskedArray.reshape : equivalent function
+
+    """
+    # We can't use 'frommethod', it whine about some parameters. Dmmit.
+    try:
+        return a.reshape(new_shape, order=order)
+    except AttributeError:
+        _tmp = narray(a, copy=False).reshape(new_shape, order=order)
+        return _tmp.view(MaskedArray)
+
+
+def resize(x, new_shape):
+    """
+    Return a new masked array with the specified size and shape.
+
+    This is the masked equivalent of the `numpy.resize` function. The new
+    array is filled with repeated copies of `x` (in the order that the
+    data are stored in memory). If `x` is masked, the new array will be
+    masked, and the new mask will be a repetition of the old one.
+
+    See Also
+    --------
+    numpy.resize : Equivalent function in the top level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.array([[1, 2] ,[3, 4]])
+    >>> a[0, 1] = ma.masked
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+                 mask =
+     [[False  True]
+     [False False]],
+           fill_value = 999999)
+    >>> np.resize(a, (3, 3))
+    array([[1, 2, 3],
+           [4, 1, 2],
+           [3, 4, 1]])
+    >>> ma.resize(a, (3, 3))
+    masked_array(data =
+     [[1 -- 3]
+     [4 1 --]
+     [3 4 1]],
+                 mask =
+     [[False  True False]
+     [False False  True]
+     [False False False]],
+           fill_value = 999999)
+
+    A MaskedArray is always returned, regardless of the input type.
+
+    >>> a = np.array([[1, 2] ,[3, 4]])
+    >>> ma.resize(a, (3, 3))
+    masked_array(data =
+     [[1 2 3]
+     [4 1 2]
+     [3 4 1]],
+                 mask =
+     False,
+           fill_value = 999999)
+
+    """
+    # We can't use _frommethods here, as N.resize is notoriously whiny.
+    m = getmask(x)
+    if m is not nomask:
+        m = np.resize(m, new_shape)
+    result = np.resize(x, new_shape).view(get_masked_subclass(x))
+    if result.ndim:
+        result._mask = m
+    return result
+
+
+def rank(obj):
+    """
+    maskedarray version of the numpy function.
+
+    .. note::
+        Deprecated since 1.10.0
+
+    """
+    # 2015-04-12, 1.10.0
+    warnings.warn(
+        "`rank` is deprecated; use the `ndim` function instead. ",
+        np.VisibleDeprecationWarning)
+    return np.ndim(getdata(obj))
+
+rank.__doc__ = np.rank.__doc__
+
+
+def ndim(obj):
+    """
+    maskedarray version of the numpy function.
+
+    """
+    return np.ndim(getdata(obj))
+
+ndim.__doc__ = np.ndim.__doc__
+
+
+def shape(obj):
+    "maskedarray version of the numpy function."
+    return np.shape(getdata(obj))
+shape.__doc__ = np.shape.__doc__
+
+
+def size(obj, axis=None):
+    "maskedarray version of the numpy function."
+    return np.size(getdata(obj), axis)
+size.__doc__ = np.size.__doc__
+
+
+##############################################################################
+#                            Extra functions                                 #
+##############################################################################
+
+
+def where(condition, x=_NoValue, y=_NoValue):
+    """
+    Return a masked array with elements from x or y, depending on condition.
+
+    Returns a masked array, shaped like condition, where the elements
+    are from `x` when `condition` is True, and from `y` otherwise.
+    If neither `x` nor `y` are given, the function returns a tuple of
+    indices where `condition` is True (the result of
+    ``condition.nonzero()``).
+
+    Parameters
+    ----------
+    condition : array_like, bool
+        The condition to meet. For each True element, yield the corresponding
+        element from `x`, otherwise from `y`.
+    x, y : array_like, optional
+        Values from which to choose. `x` and `y` need to have the same shape
+        as condition, or be broadcast-able to that shape.
+
+    Returns
+    -------
+    out : MaskedArray or tuple of ndarrays
+        The resulting masked array if `x` and `y` were given, otherwise
+        the result of ``condition.nonzero()``.
+
+    See Also
+    --------
+    numpy.where : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9.).reshape(3, 3), mask=[[0, 1, 0],
+    ...                                                    [1, 0, 1],
+    ...                                                    [0, 1, 0]])
+    >>> print(x)
+    [[0.0 -- 2.0]
+     [-- 4.0 --]
+     [6.0 -- 8.0]]
+    >>> np.ma.where(x > 5)    # return the indices where x > 5
+    (array([2, 2]), array([0, 2]))
+
+    >>> print(np.ma.where(x > 5, x, -3.1416))
+    [[-3.1416 -- -3.1416]
+     [-- -3.1416 --]
+     [6.0 -- 8.0]]
+
+    """
+    missing = (x is _NoValue, y is _NoValue).count(True)
+
+    if missing == 1:
+        raise ValueError("Must provide both 'x' and 'y' or neither.")
+    if missing == 2:
+        return filled(condition, 0).nonzero()
+
+    # Both x and y are provided
+
+    # Get the condition
+    fc = filled(condition, 0).astype(MaskType)
+    notfc = np.logical_not(fc)
+
+    # Get the data
+    xv = getdata(x)
+    yv = getdata(y)
+    if x is masked:
+        ndtype = yv.dtype
+    elif y is masked:
+        ndtype = xv.dtype
+    else:
+        ndtype = np.find_common_type([xv.dtype, yv.dtype], [])
+
+    # Construct an empty array and fill it
+    d = np.empty(fc.shape, dtype=ndtype).view(MaskedArray)
+    np.copyto(d._data, xv.astype(ndtype), where=fc)
+    np.copyto(d._data, yv.astype(ndtype), where=notfc)
+
+    # Create an empty mask and fill it
+    mask = np.zeros(fc.shape, dtype=MaskType)
+    np.copyto(mask, getmask(x), where=fc)
+    np.copyto(mask, getmask(y), where=notfc)
+    mask |= getmaskarray(condition)
+
+    # Use d._mask instead of d.mask to avoid copies
+    d._mask = mask if mask.any() else nomask
+
+    return d
+
+
+def choose(indices, choices, out=None, mode='raise'):
+    """
+    Use an index array to construct a new array from a set of choices.
+
+    Given an array of integers and a set of n choice arrays, this method
+    will create a new array that merges each of the choice arrays.  Where a
+    value in `a` is i, the new array will have the value that choices[i]
+    contains in the same place.
+
+    Parameters
+    ----------
+    a : ndarray of ints
+        This array must contain integers in ``[0, n-1]``, where n is the
+        number of choices.
+    choices : sequence of arrays
+        Choice arrays. The index array and all of the choices should be
+        broadcastable to the same shape.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and `dtype`.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' : raise an error
+        * 'wrap' : wrap around
+        * 'clip' : clip to the range
+
+    Returns
+    -------
+    merged_array : array
+
+    See Also
+    --------
+    choose : equivalent function
+
+    Examples
+    --------
+    >>> choice = np.array([[1,1,1], [2,2,2], [3,3,3]])
+    >>> a = np.array([2, 1, 0])
+    >>> np.ma.choose(a, choice)
+    masked_array(data = [3 2 1],
+          mask = False,
+          fill_value=999999)
+
+    """
+    def fmask(x):
+        "Returns the filled array, or True if masked."
+        if x is masked:
+            return True
+        return filled(x)
+
+    def nmask(x):
+        "Returns the mask, True if ``masked``, False if ``nomask``."
+        if x is masked:
+            return True
+        return getmask(x)
+    # Get the indices.
+    c = filled(indices, 0)
+    # Get the masks.
+    masks = [nmask(x) for x in choices]
+    data = [fmask(x) for x in choices]
+    # Construct the mask
+    outputmask = np.choose(c, masks, mode=mode)
+    outputmask = make_mask(mask_or(outputmask, getmask(indices)),
+                           copy=0, shrink=True)
+    # Get the choices.
+    d = np.choose(c, data, mode=mode, out=out).view(MaskedArray)
+    if out is not None:
+        if isinstance(out, MaskedArray):
+            out.__setmask__(outputmask)
+        return out
+    d.__setmask__(outputmask)
+    return d
+
+
+def round_(a, decimals=0, out=None):
+    """
+    Return a copy of a, rounded to 'decimals' places.
+
+    When 'decimals' is negative, it specifies the number of positions
+    to the left of the decimal point.  The real and imaginary parts of
+    complex numbers are rounded separately. Nothing is done if the
+    array is not of float type and 'decimals' is greater than or equal
+    to 0.
+
+    Parameters
+    ----------
+    decimals : int
+        Number of decimals to round to. May be negative.
+    out : array_like
+        Existing array to use for output.
+        If not given, returns a default copy of a.
+
+    Notes
+    -----
+    If out is given and does not have a mask attribute, the mask of a
+    is lost!
+
+    """
+    if out is None:
+        return np.round_(a, decimals, out)
+    else:
+        np.round_(getdata(a), decimals, out)
+        if hasattr(out, '_mask'):
+            out._mask = getmask(a)
+        return out
+round = round_
+
+
+# Needed by dot, so move here from extras.py. It will still be exported
+# from extras.py for compatibility.
+def mask_rowcols(a, axis=None):
+    """
+    Mask rows and/or columns of a 2D array that contain masked values.
+
+    Mask whole rows and/or columns of a 2D array that contain
+    masked values.  The masking behavior is selected using the
+    `axis` parameter.
+
+      - If `axis` is None, rows *and* columns are masked.
+      - If `axis` is 0, only rows are masked.
+      - If `axis` is 1 or -1, only columns are masked.
+
+    Parameters
+    ----------
+    a : array_like, MaskedArray
+        The array to mask.  If not a MaskedArray instance (or if no array
+        elements are masked).  The result is a MaskedArray with `mask` set
+        to `nomask` (False). Must be a 2D array.
+    axis : int, optional
+        Axis along which to perform the operation. If None, applies to a
+        flattened version of the array.
+
+    Returns
+    -------
+    a : MaskedArray
+        A modified version of the input array, masked depending on the value
+        of the `axis` parameter.
+
+    Raises
+    ------
+    NotImplementedError
+        If input array `a` is not 2D.
+
+    See Also
+    --------
+    mask_rows : Mask rows of a 2D array that contain masked values.
+    mask_cols : Mask cols of a 2D array that contain masked values.
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The input array's mask is modified by this function.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_rowcols(a)
+    masked_array(data =
+     [[0 -- 0]
+     [-- -- --]
+     [0 -- 0]],
+          mask =
+     [[False  True False]
+     [ True  True  True]
+     [False  True False]],
+          fill_value=999999)
+
+    """
+    a = array(a, subok=False)
+    if a.ndim != 2:
+        raise NotImplementedError("mask_rowcols works for 2D arrays only.")
+    m = getmask(a)
+    # Nothing is masked: return a
+    if m is nomask or not m.any():
+        return a
+    maskedval = m.nonzero()
+    a._mask = a._mask.copy()
+    if not axis:
+        a[np.unique(maskedval[0])] = masked
+    if axis in [None, 1, -1]:
+        a[:, np.unique(maskedval[1])] = masked
+    return a
+
+
+# Include masked dot here to avoid import problems in getting it from
+# extras.py. Note that it is not included in __all__, but rather exported
+# from extras in order to avoid backward compatibility problems.
+def dot(a, b, strict=False, out=None):
+    """
+    Return the dot product of two arrays.
+
+    This function is the equivalent of `numpy.dot` that takes masked values
+    into account. Note that `strict` and `out` are in different position
+    than in the method version. In order to maintain compatibility with the
+    corresponding method, it is recommended that the optional arguments be
+    treated as keyword only.  At some point that may be mandatory.
+
+    .. note::
+      Works only with 2-D arrays at the moment.
+
+
+    Parameters
+    ----------
+    a, b : masked_array_like
+        Inputs arrays.
+    strict : bool, optional
+        Whether masked data are propagated (True) or set to 0 (False) for
+        the computation. Default is False.  Propagating the mask means that
+        if a masked value appears in a row or column, the whole row or
+        column is considered masked.
+    out : masked_array, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+        .. versionadded:: 1.10.2
+
+    See Also
+    --------
+    numpy.dot : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> a = ma.array([[1, 2, 3], [4, 5, 6]], mask=[[1, 0, 0], [0, 0, 0]])
+    >>> b = ma.array([[1, 2], [3, 4], [5, 6]], mask=[[1, 0], [0, 0], [0, 0]])
+    >>> np.ma.dot(a, b)
+    masked_array(data =
+     [[21 26]
+     [45 64]],
+                 mask =
+     [[False False]
+     [False False]],
+           fill_value = 999999)
+    >>> np.ma.dot(a, b, strict=True)
+    masked_array(data =
+     [[-- --]
+     [-- 64]],
+                 mask =
+     [[ True  True]
+     [ True False]],
+           fill_value = 999999)
+
+    """
+    # !!!: Works only with 2D arrays. There should be a way to get it to run
+    # with higher dimension
+    if strict and (a.ndim == 2) and (b.ndim == 2):
+        a = mask_rowcols(a, 0)
+        b = mask_rowcols(b, 1)
+    am = ~getmaskarray(a)
+    bm = ~getmaskarray(b)
+
+    if out is None:
+        d = np.dot(filled(a, 0), filled(b, 0))
+        m = ~np.dot(am, bm)
+        if d.ndim == 0:
+            d = np.asarray(d)
+        r = d.view(get_masked_subclass(a, b))
+        r.__setmask__(m)
+        return r
+    else:
+        d = np.dot(filled(a, 0), filled(b, 0), out._data)
+        if out.mask.shape != d.shape:
+            out._mask = np.empty(d.shape, MaskType)
+        np.dot(am, bm, out._mask)
+        np.logical_not(out._mask, out._mask)
+        return out
+
+
+def inner(a, b):
+    """
+    Returns the inner product of a and b for arrays of floating point types.
+
+    Like the generic NumPy equivalent the product sum is over the last dimension
+    of a and b.
+
+    Notes
+    -----
+    The first argument is not conjugated.
+
+    """
+    fa = filled(a, 0)
+    fb = filled(b, 0)
+    if len(fa.shape) == 0:
+        fa.shape = (1,)
+    if len(fb.shape) == 0:
+        fb.shape = (1,)
+    return np.inner(fa, fb).view(MaskedArray)
+inner.__doc__ = doc_note(np.inner.__doc__,
+                         "Masked values are replaced by 0.")
+innerproduct = inner
+
+
+def outer(a, b):
+    "maskedarray version of the numpy function."
+    fa = filled(a, 0).ravel()
+    fb = filled(b, 0).ravel()
+    d = np.outer(fa, fb)
+    ma = getmask(a)
+    mb = getmask(b)
+    if ma is nomask and mb is nomask:
+        return masked_array(d)
+    ma = getmaskarray(a)
+    mb = getmaskarray(b)
+    m = make_mask(1 - np.outer(1 - ma, 1 - mb), copy=0)
+    return masked_array(d, mask=m)
+outer.__doc__ = doc_note(np.outer.__doc__,
+                         "Masked values are replaced by 0.")
+outerproduct = outer
+
+
+def allequal(a, b, fill_value=True):
+    """
+    Return True if all entries of a and b are equal, using
+    fill_value as a truth value where either or both are masked.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    fill_value : bool, optional
+        Whether masked values in a or b are considered equal (True) or not
+        (False).
+
+    Returns
+    -------
+    y : bool
+        Returns True if the two arrays are equal within the given
+        tolerance, False otherwise. If either array contains NaN,
+        then False is returned.
+
+    See Also
+    --------
+    all, any
+    numpy.ma.allclose
+
+    Examples
+    --------
+    >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
+    >>> a
+    masked_array(data = [10000000000.0 1e-07 --],
+          mask = [False False  True],
+          fill_value=1e+20)
+
+    >>> b = array([1e10, 1e-7, -42.0])
+    >>> b
+    array([  1.00000000e+10,   1.00000000e-07,  -4.20000000e+01])
+    >>> ma.allequal(a, b, fill_value=False)
+    False
+    >>> ma.allequal(a, b)
+    True
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    if m is nomask:
+        x = getdata(a)
+        y = getdata(b)
+        d = umath.equal(x, y)
+        return d.all()
+    elif fill_value:
+        x = getdata(a)
+        y = getdata(b)
+        d = umath.equal(x, y)
+        dm = array(d, mask=m, copy=False)
+        return dm.filled(True).all(None)
+    else:
+        return False
+
+
+def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8):
+    """
+    Returns True if two arrays are element-wise equal within a tolerance.
+
+    This function is equivalent to `allclose` except that masked values
+    are treated as equal (default) or unequal, depending on the `masked_equal`
+    argument.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    masked_equal : bool, optional
+        Whether masked values in `a` and `b` are considered equal (True) or not
+        (False). They are considered equal by default.
+    rtol : float, optional
+        Relative tolerance. The relative difference is equal to ``rtol * b``.
+        Default is 1e-5.
+    atol : float, optional
+        Absolute tolerance. The absolute difference is equal to `atol`.
+        Default is 1e-8.
+
+    Returns
+    -------
+    y : bool
+        Returns True if the two arrays are equal within the given
+        tolerance, False otherwise. If either array contains NaN, then
+        False is returned.
+
+    See Also
+    --------
+    all, any
+    numpy.allclose : the non-masked `allclose`.
+
+    Notes
+    -----
+    If the following equation is element-wise True, then `allclose` returns
+    True::
+
+      absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    Return True if all elements of `a` and `b` are equal subject to
+    given tolerances.
+
+    Examples
+    --------
+    >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
+    >>> a
+    masked_array(data = [10000000000.0 1e-07 --],
+                 mask = [False False  True],
+           fill_value = 1e+20)
+    >>> b = ma.array([1e10, 1e-8, -42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    False
+
+    >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
+    >>> b = ma.array([1.00001e10, 1e-9, -42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    True
+    >>> ma.allclose(a, b, masked_equal=False)
+    False
+
+    Masked values are not compared directly.
+
+    >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
+    >>> b = ma.array([1.00001e10, 1e-9, 42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    True
+    >>> ma.allclose(a, b, masked_equal=False)
+    False
+
+    """
+    x = masked_array(a, copy=False)
+    y = masked_array(b, copy=False)
+
+    # make sure y is an inexact type to avoid abs(MIN_INT); will cause
+    # casting of x later.
+    dtype = np.result_type(y, 1.)
+    if y.dtype != dtype:
+        y = masked_array(y, dtype=dtype, copy=False)
+
+    m = mask_or(getmask(x), getmask(y))
+    xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False)
+    # If we have some infs, they should fall at the same place.
+    if not np.all(xinf == filled(np.isinf(y), False)):
+        return False
+    # No infs at all
+    if not np.any(xinf):
+        d = filled(umath.less_equal(umath.absolute(x - y),
+                                    atol + rtol * umath.absolute(y)),
+                   masked_equal)
+        return np.all(d)
+
+    if not np.all(filled(x[xinf] == y[xinf], masked_equal)):
+        return False
+    x = x[~xinf]
+    y = y[~xinf]
+
+    d = filled(umath.less_equal(umath.absolute(x - y),
+                                atol + rtol * umath.absolute(y)),
+               masked_equal)
+
+    return np.all(d)
+
+
+def asarray(a, dtype=None, order=None):
+    """
+    Convert the input to a masked array of the given data-type.
+
+    No copy is performed if the input is already an `ndarray`. If `a` is
+    a subclass of `MaskedArray`, a base class `MaskedArray` is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to a masked array. This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists, ndarrays and masked arrays.
+    dtype : dtype, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major ('C') or column-major ('FORTRAN') memory
+        representation.  Default is 'C'.
+
+    Returns
+    -------
+    out : MaskedArray
+        Masked array interpretation of `a`.
+
+    See Also
+    --------
+    asanyarray : Similar to `asarray`, but conserves subclasses.
+
+    Examples
+    --------
+    >>> x = np.arange(10.).reshape(2, 5)
+    >>> x
+    array([[ 0.,  1.,  2.,  3.,  4.],
+           [ 5.,  6.,  7.,  8.,  9.]])
+    >>> np.ma.asarray(x)
+    masked_array(data =
+     [[ 0.  1.  2.  3.  4.]
+     [ 5.  6.  7.  8.  9.]],
+                 mask =
+     False,
+           fill_value = 1e+20)
+    >>> type(np.ma.asarray(x))
+    <class 'numpy.ma.core.MaskedArray'>
+
+    """
+    order = order or 'C'
+    return masked_array(a, dtype=dtype, copy=False, keep_mask=True,
+                        subok=False, order=order)
+
+
+def asanyarray(a, dtype=None):
+    """
+    Convert the input to a masked array, conserving subclasses.
+
+    If `a` is a subclass of `MaskedArray`, its class is conserved.
+    No copy is performed if the input is already an `ndarray`.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.
+    dtype : dtype, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major ('C') or column-major ('FORTRAN') memory
+        representation.  Default is 'C'.
+
+    Returns
+    -------
+    out : MaskedArray
+        MaskedArray interpretation of `a`.
+
+    See Also
+    --------
+    asarray : Similar to `asanyarray`, but does not conserve subclass.
+
+    Examples
+    --------
+    >>> x = np.arange(10.).reshape(2, 5)
+    >>> x
+    array([[ 0.,  1.,  2.,  3.,  4.],
+           [ 5.,  6.,  7.,  8.,  9.]])
+    >>> np.ma.asanyarray(x)
+    masked_array(data =
+     [[ 0.  1.  2.  3.  4.]
+     [ 5.  6.  7.  8.  9.]],
+                 mask =
+     False,
+           fill_value = 1e+20)
+    >>> type(np.ma.asanyarray(x))
+    <class 'numpy.ma.core.MaskedArray'>
+
+    """
+    return masked_array(a, dtype=dtype, copy=False, keep_mask=True, subok=True)
+
+
+##############################################################################
+#                               Pickling                                     #
+##############################################################################
+def dump(a, F):
+    """
+    Pickle a masked array to a file.
+
+    This is a wrapper around ``cPickle.dump``.
+
+    Parameters
+    ----------
+    a : MaskedArray
+        The array to be pickled.
+    F : str or file-like object
+        The file to pickle `a` to. If a string, the full path to the file.
+
+    """
+    if not hasattr(F, 'readline'):
+        F = open(F, 'w')
+    return pickle.dump(a, F)
+
+
+def dumps(a):
+    """
+    Return a string corresponding to the pickling of a masked array.
+
+    This is a wrapper around ``cPickle.dumps``.
+
+    Parameters
+    ----------
+    a : MaskedArray
+        The array for which the string representation of the pickle is
+        returned.
+
+    """
+    return pickle.dumps(a)
+
+
+def load(F):
+    """
+    Wrapper around ``cPickle.load`` which accepts either a file-like object
+    or a filename.
+
+    Parameters
+    ----------
+    F : str or file
+        The file or file name to load.
+
+    See Also
+    --------
+    dump : Pickle an array
+
+    Notes
+    -----
+    This is different from `numpy.load`, which does not use cPickle but loads
+    the NumPy binary .npy format.
+
+    """
+    if not hasattr(F, 'readline'):
+        F = open(F, 'r')
+    return pickle.load(F)
+
+
+def loads(strg):
+    """
+    Load a pickle from the current string.
+
+    The result of ``cPickle.loads(strg)`` is returned.
+
+    Parameters
+    ----------
+    strg : str
+        The string to load.
+
+    See Also
+    --------
+    dumps : Return a string corresponding to the pickling of a masked array.
+
+    """
+    return pickle.loads(strg)
+
+
+def fromfile(file, dtype=float, count=-1, sep=''):
+    raise NotImplementedError(
+        "fromfile() not yet implemented for a MaskedArray.")
+
+
+def fromflex(fxarray):
+    """
+    Build a masked array from a suitable flexible-type array.
+
+    The input array has to have a data-type with ``_data`` and ``_mask``
+    fields. This type of array is output by `MaskedArray.toflex`.
+
+    Parameters
+    ----------
+    fxarray : ndarray
+        The structured input array, containing ``_data`` and ``_mask``
+        fields. If present, other fields are discarded.
+
+    Returns
+    -------
+    result : MaskedArray
+        The constructed masked array.
+
+    See Also
+    --------
+    MaskedArray.toflex : Build a flexible-type array from a masked array.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[0] + [1, 0] * 4)
+    >>> rec = x.toflex()
+    >>> rec
+    array([[(0, False), (1, True), (2, False)],
+           [(3, True), (4, False), (5, True)],
+           [(6, False), (7, True), (8, False)]],
+          dtype=[('_data', '<i4'), ('_mask', '|b1')])
+    >>> x2 = np.ma.fromflex(rec)
+    >>> x2
+    masked_array(data =
+     [[0 -- 2]
+     [-- 4 --]
+     [6 -- 8]],
+                 mask =
+     [[False  True False]
+     [ True False  True]
+     [False  True False]],
+           fill_value = 999999)
+
+    Extra fields can be present in the structured array but are discarded:
+
+    >>> dt = [('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')]
+    >>> rec2 = np.zeros((2, 2), dtype=dt)
+    >>> rec2
+    array([[(0, False, 0.0), (0, False, 0.0)],
+           [(0, False, 0.0), (0, False, 0.0)]],
+          dtype=[('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')])
+    >>> y = np.ma.fromflex(rec2)
+    >>> y
+    masked_array(data =
+     [[0 0]
+     [0 0]],
+                 mask =
+     [[False False]
+     [False False]],
+           fill_value = 999999)
+
+    """
+    return masked_array(fxarray['_data'], mask=fxarray['_mask'])
+
+
+class _convert2ma:
+
+    """
+    Convert functions from numpy to numpy.ma.
+
+    Parameters
+    ----------
+        _methodname : string
+            Name of the method to transform.
+
+    """
+    __doc__ = None
+
+    def __init__(self, funcname, params=None):
+        self._func = getattr(np, funcname)
+        self.__doc__ = self.getdoc()
+        self._extras = params or {}
+
+    def getdoc(self):
+        "Return the doc of the function (from the doc of the method)."
+        doc = getattr(self._func, '__doc__', None)
+        sig = get_object_signature(self._func)
+        if doc:
+            # Add the signature of the function at the beginning of the doc
+            if sig:
+                sig = "%s%s\n" % (self._func.__name__, sig)
+            doc = sig + doc
+        return doc
+
+    def __call__(self, *args, **params):
+        # Find the common parameters to the call and the definition
+        _extras = self._extras
+        common_params = set(params).intersection(_extras)
+        # Drop the common parameters from the call
+        for p in common_params:
+            _extras[p] = params.pop(p)
+        # Get the result
+        result = self._func.__call__(*args, **params).view(MaskedArray)
+        if "fill_value" in common_params:
+            result.fill_value = _extras.get("fill_value", None)
+        if "hardmask" in common_params:
+            result._hardmask = bool(_extras.get("hard_mask", False))
+        return result
+
+arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False))
+clip = np.clip
+diff = np.diff
+empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False))
+empty_like = _convert2ma('empty_like')
+frombuffer = _convert2ma('frombuffer')
+fromfunction = _convert2ma('fromfunction')
+identity = _convert2ma(
+    'identity', params=dict(fill_value=None, hardmask=False))
+indices = np.indices
+ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False))
+ones_like = np.ones_like
+squeeze = np.squeeze
+zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False))
+zeros_like = np.zeros_like
+
+
+def append(a, b, axis=None):
+    """Append values to the end of an array.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Values are appended to a copy of this array.
+    b : array_like
+        These values are appended to a copy of `a`.  It must be of the
+        correct shape (the same shape as `a`, excluding `axis`).  If `axis`
+        is not specified, `b` can be any shape and will be flattened
+        before use.
+    axis : int, optional
+        The axis along which `v` are appended.  If `axis` is not given,
+        both `a` and `b` are flattened before use.
+
+    Returns
+    -------
+    append : MaskedArray
+        A copy of `a` with `b` appended to `axis`.  Note that `append`
+        does not occur in-place: a new array is allocated and filled.  If
+        `axis` is None, the result is a flattened array.
+
+    See Also
+    --------
+    numpy.append : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_values([1, 2, 3], 2)
+    >>> b = ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
+    >>> print(ma.append(a, b))
+    [1 -- 3 4 5 6 -- 8 9]
+    """
+    return concatenate([a, b], axis)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/extras.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/extras.py
new file mode 100644
index 0000000000..6e091652e5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/extras.py
@@ -0,0 +1,1819 @@
+"""
+Masked arrays add-ons.
+
+A collection of utilities for `numpy.ma`.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = [
+    'apply_along_axis', 'apply_over_axes', 'atleast_1d', 'atleast_2d',
+    'atleast_3d', 'average', 'clump_masked', 'clump_unmasked',
+    'column_stack', 'compress_cols', 'compress_nd', 'compress_rowcols',
+    'compress_rows', 'count_masked', 'corrcoef', 'cov', 'diagflat', 'dot',
+    'dstack', 'ediff1d', 'flatnotmasked_contiguous', 'flatnotmasked_edges',
+    'hsplit', 'hstack', 'in1d', 'intersect1d', 'mask_cols', 'mask_rowcols',
+    'mask_rows', 'masked_all', 'masked_all_like', 'median', 'mr_',
+    'notmasked_contiguous', 'notmasked_edges', 'polyfit', 'row_stack',
+    'setdiff1d', 'setxor1d', 'unique', 'union1d', 'vander', 'vstack',
+    ]
+
+import itertools
+import warnings
+
+from . import core as ma
+from .core import (
+    MaskedArray, MAError, add, array, asarray, concatenate, filled,
+    getmask, getmaskarray, make_mask_descr, masked, masked_array, mask_or,
+    nomask, ones, sort, zeros, getdata, get_masked_subclass, dot,
+    mask_rowcols
+    )
+
+import numpy as np
+from numpy import ndarray, array as nxarray
+import numpy.core.umath as umath
+from numpy.lib.index_tricks import AxisConcatenator
+
+
+def issequence(seq):
+    """
+    Is seq a sequence (ndarray, list or tuple)?
+
+    """
+    if isinstance(seq, (ndarray, tuple, list)):
+        return True
+    return False
+
+def count_masked(arr, axis=None):
+    """
+    Count the number of masked elements along the given axis.
+
+    Parameters
+    ----------
+    arr : array_like
+        An array with (possibly) masked elements.
+    axis : int, optional
+        Axis along which to count. If None (default), a flattened
+        version of the array is used.
+
+    Returns
+    -------
+    count : int, ndarray
+        The total number of masked elements (axis=None) or the number
+        of masked elements along each slice of the given axis.
+
+    See Also
+    --------
+    MaskedArray.count : Count non-masked elements.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(9).reshape((3,3))
+    >>> a = ma.array(a)
+    >>> a[1, 0] = ma.masked
+    >>> a[1, 2] = ma.masked
+    >>> a[2, 1] = ma.masked
+    >>> a
+    masked_array(data =
+     [[0 1 2]
+     [-- 4 --]
+     [6 -- 8]],
+          mask =
+     [[False False False]
+     [ True False  True]
+     [False  True False]],
+          fill_value=999999)
+    >>> ma.count_masked(a)
+    3
+
+    When the `axis` keyword is used an array is returned.
+
+    >>> ma.count_masked(a, axis=0)
+    array([1, 1, 1])
+    >>> ma.count_masked(a, axis=1)
+    array([0, 2, 1])
+
+    """
+    m = getmaskarray(arr)
+    return m.sum(axis)
+
+def masked_all(shape, dtype=float):
+    """
+    Empty masked array with all elements masked.
+
+    Return an empty masked array of the given shape and dtype, where all the
+    data are masked.
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of the required MaskedArray.
+    dtype : dtype, optional
+        Data type of the output.
+
+    Returns
+    -------
+    a : MaskedArray
+        A masked array with all data masked.
+
+    See Also
+    --------
+    masked_all_like : Empty masked array modelled on an existing array.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> ma.masked_all((3, 3))
+    masked_array(data =
+     [[-- -- --]
+     [-- -- --]
+     [-- -- --]],
+          mask =
+     [[ True  True  True]
+     [ True  True  True]
+     [ True  True  True]],
+          fill_value=1e+20)
+
+    The `dtype` parameter defines the underlying data type.
+
+    >>> a = ma.masked_all((3, 3))
+    >>> a.dtype
+    dtype('float64')
+    >>> a = ma.masked_all((3, 3), dtype=np.int32)
+    >>> a.dtype
+    dtype('int32')
+
+    """
+    a = masked_array(np.empty(shape, dtype),
+                     mask=np.ones(shape, make_mask_descr(dtype)))
+    return a
+
+def masked_all_like(arr):
+    """
+    Empty masked array with the properties of an existing array.
+
+    Return an empty masked array of the same shape and dtype as
+    the array `arr`, where all the data are masked.
+
+    Parameters
+    ----------
+    arr : ndarray
+        An array describing the shape and dtype of the required MaskedArray.
+
+    Returns
+    -------
+    a : MaskedArray
+        A masked array with all data masked.
+
+    Raises
+    ------
+    AttributeError
+        If `arr` doesn't have a shape attribute (i.e. not an ndarray)
+
+    See Also
+    --------
+    masked_all : Empty masked array with all elements masked.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> arr = np.zeros((2, 3), dtype=np.float32)
+    >>> arr
+    array([[ 0.,  0.,  0.],
+           [ 0.,  0.,  0.]], dtype=float32)
+    >>> ma.masked_all_like(arr)
+    masked_array(data =
+     [[-- -- --]
+     [-- -- --]],
+          mask =
+     [[ True  True  True]
+     [ True  True  True]],
+          fill_value=1e+20)
+
+    The dtype of the masked array matches the dtype of `arr`.
+
+    >>> arr.dtype
+    dtype('float32')
+    >>> ma.masked_all_like(arr).dtype
+    dtype('float32')
+
+    """
+    a = np.empty_like(arr).view(MaskedArray)
+    a._mask = np.ones(a.shape, dtype=make_mask_descr(a.dtype))
+    return a
+
+
+#####--------------------------------------------------------------------------
+#---- --- Standard functions ---
+#####--------------------------------------------------------------------------
+class _fromnxfunction:
+    """
+    Defines a wrapper to adapt NumPy functions to masked arrays.
+
+
+    An instance of `_fromnxfunction` can be called with the same parameters
+    as the wrapped NumPy function. The docstring of `newfunc` is adapted from
+    the wrapped function as well, see `getdoc`.
+
+    Parameters
+    ----------
+    funcname : str
+        The name of the function to be adapted. The function should be
+        in the NumPy namespace (i.e. ``np.funcname``).
+
+    """
+
+    def __init__(self, funcname):
+        self.__name__ = funcname
+        self.__doc__ = self.getdoc()
+
+    def getdoc(self):
+        """
+        Retrieve the docstring and signature from the function.
+
+        The ``__doc__`` attribute of the function is used as the docstring for
+        the new masked array version of the function. A note on application
+        of the function to the mask is appended.
+
+        .. warning::
+          If the function docstring already contained a Notes section, the
+          new docstring will have two Notes sections instead of appending a note
+          to the existing section.
+
+        Parameters
+        ----------
+        None
+
+        """
+        npfunc = getattr(np, self.__name__, None)
+        doc = getattr(npfunc, '__doc__', None)
+        if doc:
+            sig = self.__name__ + ma.get_object_signature(npfunc)
+            locdoc = "Notes\n-----\nThe function is applied to both the _data"\
+                     " and the _mask, if any."
+            return '\n'.join((sig, doc, locdoc))
+        return
+
+    def __call__(self, *args, **params):
+        func = getattr(np, self.__name__)
+        if len(args) == 1:
+            x = args[0]
+            if isinstance(x, ndarray):
+                _d = func(x.__array__(), **params)
+                _m = func(getmaskarray(x), **params)
+                return masked_array(_d, mask=_m)
+            elif isinstance(x, tuple) or isinstance(x, list):
+                _d = func(tuple([np.asarray(a) for a in x]), **params)
+                _m = func(tuple([getmaskarray(a) for a in x]), **params)
+                return masked_array(_d, mask=_m)
+            else:
+                _d = func(np.asarray(x), **params)
+                _m = func(getmaskarray(x), **params)
+                return masked_array(_d, mask=_m)
+        else:
+            arrays = []
+            args = list(args)
+            while len(args) > 0 and issequence(args[0]):
+                arrays.append(args.pop(0))
+            res = []
+            for x in arrays:
+                _d = func(np.asarray(x), *args, **params)
+                _m = func(getmaskarray(x), *args, **params)
+                res.append(masked_array(_d, mask=_m))
+            return res
+
+atleast_1d = _fromnxfunction('atleast_1d')
+atleast_2d = _fromnxfunction('atleast_2d')
+atleast_3d = _fromnxfunction('atleast_3d')
+#atleast_1d = np.atleast_1d
+#atleast_2d = np.atleast_2d
+#atleast_3d = np.atleast_3d
+
+vstack = row_stack = _fromnxfunction('vstack')
+hstack = _fromnxfunction('hstack')
+column_stack = _fromnxfunction('column_stack')
+dstack = _fromnxfunction('dstack')
+
+hsplit = _fromnxfunction('hsplit')
+
+diagflat = _fromnxfunction('diagflat')
+
+
+#####--------------------------------------------------------------------------
+#----
+#####--------------------------------------------------------------------------
+def flatten_inplace(seq):
+    """Flatten a sequence in place."""
+    k = 0
+    while (k != len(seq)):
+        while hasattr(seq[k], '__iter__'):
+            seq[k:(k + 1)] = seq[k]
+        k += 1
+    return seq
+
+
+def apply_along_axis(func1d, axis, arr, *args, **kwargs):
+    """
+    (This docstring should be overwritten)
+    """
+    arr = array(arr, copy=False, subok=True)
+    nd = arr.ndim
+    if axis < 0:
+        axis += nd
+    if (axis >= nd):
+        raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d."
+            % (axis, nd))
+    ind = [0] * (nd - 1)
+    i = np.zeros(nd, 'O')
+    indlist = list(range(nd))
+    indlist.remove(axis)
+    i[axis] = slice(None, None)
+    outshape = np.asarray(arr.shape).take(indlist)
+    i.put(indlist, ind)
+    j = i.copy()
+    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+    #  if res is a number, then we have a smaller output array
+    asscalar = np.isscalar(res)
+    if not asscalar:
+        try:
+            len(res)
+        except TypeError:
+            asscalar = True
+    # Note: we shouldn't set the dtype of the output from the first result
+    # so we force the type to object, and build a list of dtypes.  We'll
+    # just take the largest, to avoid some downcasting
+    dtypes = []
+    if asscalar:
+        dtypes.append(np.asarray(res).dtype)
+        outarr = zeros(outshape, object)
+        outarr[tuple(ind)] = res
+        Ntot = np.product(outshape)
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= outshape[n]) and (n > (1 - nd)):
+                ind[n - 1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(ind)] = res
+            dtypes.append(asarray(res).dtype)
+            k += 1
+    else:
+        res = array(res, copy=False, subok=True)
+        j = i.copy()
+        j[axis] = ([slice(None, None)] * res.ndim)
+        j.put(indlist, ind)
+        Ntot = np.product(outshape)
+        holdshape = outshape
+        outshape = list(arr.shape)
+        outshape[axis] = res.shape
+        dtypes.append(asarray(res).dtype)
+        outshape = flatten_inplace(outshape)
+        outarr = zeros(outshape, object)
+        outarr[tuple(flatten_inplace(j.tolist()))] = res
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= holdshape[n]) and (n > (1 - nd)):
+                ind[n - 1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            j.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(flatten_inplace(j.tolist()))] = res
+            dtypes.append(asarray(res).dtype)
+            k += 1
+    max_dtypes = np.dtype(np.asarray(dtypes).max())
+    if not hasattr(arr, '_mask'):
+        result = np.asarray(outarr, dtype=max_dtypes)
+    else:
+        result = asarray(outarr, dtype=max_dtypes)
+        result.fill_value = ma.default_fill_value(result)
+    return result
+apply_along_axis.__doc__ = np.apply_along_axis.__doc__
+
+
+def apply_over_axes(func, a, axes):
+    """
+    (This docstring will be overwritten)
+    """
+    val = asarray(a)
+    N = a.ndim
+    if array(axes).ndim == 0:
+        axes = (axes,)
+    for axis in axes:
+        if axis < 0:
+            axis = N + axis
+        args = (val, axis)
+        res = func(*args)
+        if res.ndim == val.ndim:
+            val = res
+        else:
+            res = ma.expand_dims(res, axis)
+            if res.ndim == val.ndim:
+                val = res
+            else:
+                raise ValueError("function is not returning "
+                        "an array of the correct shape")
+    return val
+
+if apply_over_axes.__doc__ is not None:
+    apply_over_axes.__doc__ = np.apply_over_axes.__doc__[
+        :np.apply_over_axes.__doc__.find('Notes')].rstrip() + \
+    """
+
+    Examples
+    --------
+    >>> a = ma.arange(24).reshape(2,3,4)
+    >>> a[:,0,1] = ma.masked
+    >>> a[:,1,:] = ma.masked
+    >>> print(a)
+    [[[0 -- 2 3]
+      [-- -- -- --]
+      [8 9 10 11]]
+
+     [[12 -- 14 15]
+      [-- -- -- --]
+      [20 21 22 23]]]
+    >>> print(ma.apply_over_axes(ma.sum, a, [0,2]))
+    [[[46]
+      [--]
+      [124]]]
+
+    Tuple axis arguments to ufuncs are equivalent:
+
+    >>> print(ma.sum(a, axis=(0,2)).reshape((1,-1,1)))
+    [[[46]
+      [--]
+      [124]]]
+    """
+
+
+def average(a, axis=None, weights=None, returned=False):
+    """
+    Return the weighted average of array over the given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Data to be averaged.
+        Masked entries are not taken into account in the computation.
+    axis : int, optional
+        Axis along which the average is computed. The default is to compute
+        the average of the flattened array.
+    weights : array_like, optional
+        The importance that each element has in the computation of the average.
+        The weights array can either be 1-D (in which case its length must be
+        the size of `a` along the given axis) or of the same shape as `a`.
+        If ``weights=None``, then all data in `a` are assumed to have a
+        weight equal to one.   If `weights` is complex, the imaginary parts
+        are ignored.
+    returned : bool, optional
+        Flag indicating whether a tuple ``(result, sum of weights)``
+        should be returned as output (True), or just the result (False).
+        Default is False.
+
+    Returns
+    -------
+    average, [sum_of_weights] : (tuple of) scalar or MaskedArray
+        The average along the specified axis. When returned is `True`,
+        return a tuple with the average as the first element and the sum
+        of the weights as the second element. The return type is `np.float64`
+        if `a` is of integer type and floats smaller than `float64`, or the
+        input data-type, otherwise. If returned, `sum_of_weights` is always
+        `float64`.
+
+    Examples
+    --------
+    >>> a = np.ma.array([1., 2., 3., 4.], mask=[False, False, True, True])
+    >>> np.ma.average(a, weights=[3, 1, 0, 0])
+    1.25
+
+    >>> x = np.ma.arange(6.).reshape(3, 2)
+    >>> print(x)
+    [[ 0.  1.]
+     [ 2.  3.]
+     [ 4.  5.]]
+    >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3],
+    ...                                 returned=True)
+    >>> print(avg)
+    [2.66666666667 3.66666666667]
+
+    """
+    a = asarray(a)
+    mask = a.mask
+    ash = a.shape
+    if ash == ():
+        ash = (1,)
+    if axis is None:
+        if mask is nomask:
+            if weights is None:
+                n = a.sum(axis=None)
+                d = float(a.size)
+            else:
+                w = filled(weights, 0.0).ravel()
+                n = umath.add.reduce(a._data.ravel() * w)
+                d = umath.add.reduce(w)
+                del w
+        else:
+            if weights is None:
+                n = a.filled(0).sum(axis=None)
+                d = float(umath.add.reduce((~mask).ravel()))
+            else:
+                w = array(filled(weights, 0.0), float, mask=mask).ravel()
+                n = add.reduce(a.ravel() * w)
+                d = add.reduce(w)
+                del w
+    else:
+        if mask is nomask:
+            if weights is None:
+                d = ash[axis] * 1.0
+                n = add.reduce(a._data, axis)
+            else:
+                w = filled(weights, 0.0)
+                wsh = w.shape
+                if wsh == ():
+                    wsh = (1,)
+                if wsh == ash:
+                    w = np.array(w, float, copy=0)
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis)
+                    del w
+                elif wsh == (ash[axis],):
+                    r = [None] * len(ash)
+                    r[axis] = slice(None, None, 1)
+                    w = eval("w[" + repr(tuple(r)) + "] * ones(ash, float)")
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                    del w, r
+                else:
+                    raise ValueError('average: weights wrong shape.')
+        else:
+            if weights is None:
+                n = add.reduce(a, axis)
+                d = umath.add.reduce((~mask), axis=axis, dtype=float)
+            else:
+                w = filled(weights, 0.0)
+                wsh = w.shape
+                if wsh == ():
+                    wsh = (1,)
+                if wsh == ash:
+                    w = array(w, dtype=float, mask=mask, copy=0)
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                elif wsh == (ash[axis],):
+                    r = [None] * len(ash)
+                    r[axis] = slice(None, None, 1)
+                    w = eval("w[" + repr(tuple(r)) +
+                             "] * masked_array(ones(ash, float), mask)")
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                else:
+                    raise ValueError('average: weights wrong shape.')
+                del w
+    if n is masked or d is masked:
+        return masked
+    result = n / d
+    del n
+
+    if isinstance(result, MaskedArray):
+        if ((axis is None) or (axis == 0 and a.ndim == 1)) and \
+           (result.mask is nomask):
+            result = result._data
+        if returned:
+            if not isinstance(d, MaskedArray):
+                d = masked_array(d)
+            if isinstance(d, ndarray) and (not d.shape == result.shape):
+                d = ones(result.shape, dtype=float) * d
+    if returned:
+        return result, d
+    else:
+        return result
+
+
+def median(a, axis=None, out=None, overwrite_input=False):
+    """
+    Compute the median along the specified axis.
+
+    Returns the median of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : int, optional
+        Axis along which the medians are computed. The default (None) is
+        to compute the median along a flattened version of the array.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array (a) for
+        calculations. The input array will be modified by the call to
+        median. This will save memory when you do not need to preserve
+        the contents of the input array. Treat the input as undefined,
+        but it will probably be fully or partially sorted. Default is
+        False. Note that, if `overwrite_input` is True, and the input
+        is not already an `ndarray`, an error will be raised.
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result is returned unless out is
+        specified, in which case a reference to out is returned.
+        Return data-type is `float64` for integers and floats smaller than
+        `float64`, or the input data-type, otherwise.
+
+    See Also
+    --------
+    mean
+
+    Notes
+    -----
+    Given a vector ``V`` with ``N`` non masked values, the median of ``V``
+    is the middle value of a sorted copy of ``V`` (``Vs``) - i.e.
+    ``Vs[(N-1)/2]``, when ``N`` is odd, or ``{Vs[N/2 - 1] + Vs[N/2]}/2``
+    when ``N`` is even.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(8), mask=[0]*4 + [1]*4)
+    >>> np.ma.median(x)
+    1.5
+
+    >>> x = np.ma.array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4)
+    >>> np.ma.median(x)
+    2.5
+    >>> np.ma.median(x, axis=-1, overwrite_input=True)
+    masked_array(data = [ 2.  5.],
+                 mask = False,
+           fill_value = 1e+20)
+
+    """
+    if not hasattr(a, 'mask') or np.count_nonzero(a.mask) == 0:
+        return masked_array(np.median(getdata(a, subok=True), axis=axis,
+                      out=out, overwrite_input=overwrite_input), copy=False)
+    if overwrite_input:
+        if axis is None:
+            asorted = a.ravel()
+            asorted.sort()
+        else:
+            a.sort(axis=axis)
+            asorted = a
+    else:
+        asorted = sort(a, axis=axis)
+    if axis is None:
+        axis = 0
+    elif axis < 0:
+        axis += a.ndim
+
+    counts = asorted.shape[axis] - (asorted.mask).sum(axis=axis)
+    h = counts // 2
+    # create indexing mesh grid for all but reduced axis
+    axes_grid = [np.arange(x) for i, x in enumerate(asorted.shape)
+                 if i != axis]
+    ind = np.meshgrid(*axes_grid, sparse=True, indexing='ij')
+    # insert indices of low and high median
+    ind.insert(axis, h - 1)
+    low = asorted[ind]
+    low._sharedmask = False
+    ind[axis] = h
+    high = asorted[ind]
+    # duplicate high if odd number of elements so mean does nothing
+    odd = counts % 2 == 1
+    if asorted.ndim == 1:
+        if odd:
+            low = high
+    else:
+        low[odd] = high[odd]
+
+    if np.issubdtype(asorted.dtype, np.inexact):
+        # avoid inf / x = masked
+        s = np.ma.sum([low, high], axis=0, out=out)
+        np.true_divide(s.data, 2., casting='unsafe', out=s.data)
+    else:
+        s = np.ma.mean([low, high], axis=0, out=out)
+    return s
+
+
+def compress_nd(x, axis=None):
+    """Supress slices from multiple dimensions which contain masked values.
+
+    Parameters
+    ----------
+    x : array_like, MaskedArray
+        The array to operate on. If not a MaskedArray instance (or if no array
+        elements are masked, `x` is interpreted as a MaskedArray with `mask`
+        set to `nomask`.
+    axis : tuple of ints or int, optional
+        Which dimensions to supress slices from can be configured with this
+        parameter.
+        - If axis is a tuple of ints, those are the axes to supress slices from.
+        - If axis is an int, then that is the only axis to supress slices from.
+        - If axis is None, all axis are selected.
+
+    Returns
+    -------
+    compress_array : ndarray
+        The compressed array.
+    """
+    x = asarray(x)
+    m = getmask(x)
+    # Set axis to tuple of ints
+    if isinstance(axis, int):
+        axis = (axis,)
+    elif axis is None:
+        axis = tuple(range(x.ndim))
+    elif not isinstance(axis, tuple):
+        raise ValueError('Invalid type for axis argument')
+    # Check axis input
+    axis = [ax + x.ndim if ax < 0 else ax for ax in axis]
+    if not all(0 <= ax < x.ndim for ax in axis):
+        raise ValueError("'axis' entry is out of bounds")
+    if len(axis) != len(set(axis)):
+        raise ValueError("duplicate value in 'axis'")
+    # Nothing is masked: return x
+    if m is nomask or not m.any():
+        return x._data
+    # All is masked: return empty
+    if m.all():
+        return nxarray([])
+    # Filter elements through boolean indexing
+    data = x._data
+    for ax in axis:
+        axes = tuple(list(range(ax)) + list(range(ax + 1, x.ndim)))
+        data = data[(slice(None),)*ax + (~m.any(axis=axes),)]
+    return data
+
+def compress_rowcols(x, axis=None):
+    """
+    Suppress the rows and/or columns of a 2-D array that contain
+    masked values.
+
+    The suppression behavior is selected with the `axis` parameter.
+
+    - If axis is None, both rows and columns are suppressed.
+    - If axis is 0, only rows are suppressed.
+    - If axis is 1 or -1, only columns are suppressed.
+
+    Parameters
+    ----------
+    x : array_like, MaskedArray
+        The array to operate on.  If not a MaskedArray instance (or if no array
+        elements are masked), `x` is interpreted as a MaskedArray with
+        `mask` set to `nomask`. Must be a 2D array.
+    axis : int, optional
+        Axis along which to perform the operation. Default is None.
+
+    Returns
+    -------
+    compressed_array : ndarray
+        The compressed array.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
+    ...                                                   [1, 0, 0],
+    ...                                                   [0, 0, 0]])
+    >>> x
+    masked_array(data =
+     [[-- 1 2]
+     [-- 4 5]
+     [6 7 8]],
+                 mask =
+     [[ True False False]
+     [ True False False]
+     [False False False]],
+           fill_value = 999999)
+
+    >>> np.ma.compress_rowcols(x)
+    array([[7, 8]])
+    >>> np.ma.compress_rowcols(x, 0)
+    array([[6, 7, 8]])
+    >>> np.ma.compress_rowcols(x, 1)
+    array([[1, 2],
+           [4, 5],
+           [7, 8]])
+
+    """
+    if asarray(x).ndim != 2:
+        raise NotImplementedError("compress_rowcols works for 2D arrays only.")
+    return compress_nd(x, axis=axis)
+
+
+def compress_rows(a):
+    """
+    Suppress whole rows of a 2-D array that contain masked values.
+
+    This is equivalent to ``np.ma.compress_rowcols(a, 0)``, see
+    `extras.compress_rowcols` for details.
+
+    See Also
+    --------
+    extras.compress_rowcols
+
+    """
+    a = asarray(a)
+    if a.ndim != 2:
+        raise NotImplementedError("compress_rows works for 2D arrays only.")
+    return compress_rowcols(a, 0)
+
+def compress_cols(a):
+    """
+    Suppress whole columns of a 2-D array that contain masked values.
+
+    This is equivalent to ``np.ma.compress_rowcols(a, 1)``, see
+    `extras.compress_rowcols` for details.
+
+    See Also
+    --------
+    extras.compress_rowcols
+
+    """
+    a = asarray(a)
+    if a.ndim != 2:
+        raise NotImplementedError("compress_cols works for 2D arrays only.")
+    return compress_rowcols(a, 1)
+
+def mask_rows(a, axis=None):
+    """
+    Mask rows of a 2D array that contain masked values.
+
+    This function is a shortcut to ``mask_rowcols`` with `axis` equal to 0.
+
+    See Also
+    --------
+    mask_rowcols : Mask rows and/or columns of a 2D array.
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_rows(a)
+    masked_array(data =
+     [[0 0 0]
+     [-- -- --]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [ True  True  True]
+     [False False False]],
+          fill_value=999999)
+
+    """
+    return mask_rowcols(a, 0)
+
+def mask_cols(a, axis=None):
+    """
+    Mask columns of a 2D array that contain masked values.
+
+    This function is a shortcut to ``mask_rowcols`` with `axis` equal to 1.
+
+    See Also
+    --------
+    mask_rowcols : Mask rows and/or columns of a 2D array.
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_cols(a)
+    masked_array(data =
+     [[0 -- 0]
+     [0 -- 0]
+     [0 -- 0]],
+          mask =
+     [[False  True False]
+     [False  True False]
+     [False  True False]],
+          fill_value=999999)
+
+    """
+    return mask_rowcols(a, 1)
+
+
+#####--------------------------------------------------------------------------
+#---- --- arraysetops ---
+#####--------------------------------------------------------------------------
+
+def ediff1d(arr, to_end=None, to_begin=None):
+    """
+    Compute the differences between consecutive elements of an array.
+
+    This function is the equivalent of `numpy.ediff1d` that takes masked
+    values into account, see `numpy.ediff1d` for details.
+
+    See Also
+    --------
+    numpy.ediff1d : Equivalent function for ndarrays.
+
+    """
+    arr = ma.asanyarray(arr).flat
+    ed = arr[1:] - arr[:-1]
+    arrays = [ed]
+    #
+    if to_begin is not None:
+        arrays.insert(0, to_begin)
+    if to_end is not None:
+        arrays.append(to_end)
+    #
+    if len(arrays) != 1:
+        # We'll save ourselves a copy of a potentially large array in the common
+        # case where neither to_begin or to_end was given.
+        ed = hstack(arrays)
+    #
+    return ed
+
+
+def unique(ar1, return_index=False, return_inverse=False):
+    """
+    Finds the unique elements of an array.
+
+    Masked values are considered the same element (masked). The output array
+    is always a masked array. See `numpy.unique` for more details.
+
+    See Also
+    --------
+    numpy.unique : Equivalent function for ndarrays.
+
+    """
+    output = np.unique(ar1,
+                       return_index=return_index,
+                       return_inverse=return_inverse)
+    if isinstance(output, tuple):
+        output = list(output)
+        output[0] = output[0].view(MaskedArray)
+        output = tuple(output)
+    else:
+        output = output.view(MaskedArray)
+    return output
+
+
+def intersect1d(ar1, ar2, assume_unique=False):
+    """
+    Returns the unique elements common to both arrays.
+
+    Masked values are considered equal one to the other.
+    The output is always a masked array.
+
+    See `numpy.intersect1d` for more details.
+
+    See Also
+    --------
+    numpy.intersect1d : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> x = array([1, 3, 3, 3], mask=[0, 0, 0, 1])
+    >>> y = array([3, 1, 1, 1], mask=[0, 0, 0, 1])
+    >>> intersect1d(x, y)
+    masked_array(data = [1 3 --],
+                 mask = [False False  True],
+           fill_value = 999999)
+
+    """
+    if assume_unique:
+        aux = ma.concatenate((ar1, ar2))
+    else:
+        # Might be faster than unique( intersect1d( ar1, ar2 ) )?
+        aux = ma.concatenate((unique(ar1), unique(ar2)))
+    aux.sort()
+    return aux[:-1][aux[1:] == aux[:-1]]
+
+
+def setxor1d(ar1, ar2, assume_unique=False):
+    """
+    Set exclusive-or of 1-D arrays with unique elements.
+
+    The output is always a masked array. See `numpy.setxor1d` for more details.
+
+    See Also
+    --------
+    numpy.setxor1d : Equivalent function for ndarrays.
+
+    """
+    if not assume_unique:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+
+    aux = ma.concatenate((ar1, ar2))
+    if aux.size == 0:
+        return aux
+    aux.sort()
+    auxf = aux.filled()
+#    flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
+    flag = ma.concatenate(([True], (auxf[1:] != auxf[:-1]), [True]))
+#    flag2 = ediff1d( flag ) == 0
+    flag2 = (flag[1:] == flag[:-1])
+    return aux[flag2]
+
+def in1d(ar1, ar2, assume_unique=False, invert=False):
+    """
+    Test whether each element of an array is also present in a second
+    array.
+
+    The output is always a masked array. See `numpy.in1d` for more details.
+
+    See Also
+    --------
+    numpy.in1d : Equivalent function for ndarrays.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if not assume_unique:
+        ar1, rev_idx = unique(ar1, return_inverse=True)
+        ar2 = unique(ar2)
+
+    ar = ma.concatenate((ar1, ar2))
+    # We need this to be a stable sort, so always use 'mergesort'
+    # here. The values from the first array should always come before
+    # the values from the second array.
+    order = ar.argsort(kind='mergesort')
+    sar = ar[order]
+    if invert:
+        bool_ar = (sar[1:] != sar[:-1])
+    else:
+        bool_ar = (sar[1:] == sar[:-1])
+    flag = ma.concatenate((bool_ar, [invert]))
+    indx = order.argsort(kind='mergesort')[:len(ar1)]
+
+    if assume_unique:
+        return flag[indx]
+    else:
+        return flag[indx][rev_idx]
+
+
+def union1d(ar1, ar2):
+    """
+    Union of two arrays.
+
+    The output is always a masked array. See `numpy.union1d` for more details.
+
+    See also
+    --------
+    numpy.union1d : Equivalent function for ndarrays.
+
+    """
+    return unique(ma.concatenate((ar1, ar2)))
+
+
+def setdiff1d(ar1, ar2, assume_unique=False):
+    """
+    Set difference of 1D arrays with unique elements.
+
+    The output is always a masked array. See `numpy.setdiff1d` for more
+    details.
+
+    See Also
+    --------
+    numpy.setdiff1d : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
+    >>> np.ma.setdiff1d(x, [1, 2])
+    masked_array(data = [3 --],
+                 mask = [False  True],
+           fill_value = 999999)
+
+    """
+    if assume_unique:
+        ar1 = ma.asarray(ar1).ravel()
+    else:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
+
+
+###############################################################################
+#                                Covariance                                   #
+###############################################################################
+
+
+def _covhelper(x, y=None, rowvar=True, allow_masked=True):
+    """
+    Private function for the computation of covariance and correlation
+    coefficients.
+
+    """
+    x = ma.array(x, ndmin=2, copy=True, dtype=float)
+    xmask = ma.getmaskarray(x)
+    # Quick exit if we can't process masked data
+    if not allow_masked and xmask.any():
+        raise ValueError("Cannot process masked data.")
+    #
+    if x.shape[0] == 1:
+        rowvar = True
+    # Make sure that rowvar is either 0 or 1
+    rowvar = int(bool(rowvar))
+    axis = 1 - rowvar
+    if rowvar:
+        tup = (slice(None), None)
+    else:
+        tup = (None, slice(None))
+    #
+    if y is None:
+        xnotmask = np.logical_not(xmask).astype(int)
+    else:
+        y = array(y, copy=False, ndmin=2, dtype=float)
+        ymask = ma.getmaskarray(y)
+        if not allow_masked and ymask.any():
+            raise ValueError("Cannot process masked data.")
+        if xmask.any() or ymask.any():
+            if y.shape == x.shape:
+                # Define some common mask
+                common_mask = np.logical_or(xmask, ymask)
+                if common_mask is not nomask:
+                    xmask = x._mask = y._mask = ymask = common_mask
+                    x._sharedmask = False
+                    y._sharedmask = False
+        x = ma.concatenate((x, y), axis)
+        xnotmask = np.logical_not(np.concatenate((xmask, ymask), axis)).astype(int)
+    x -= x.mean(axis=rowvar)[tup]
+    return (x, xnotmask, rowvar)
+
+
+def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None):
+    """
+    Estimate the covariance matrix.
+
+    Except for the handling of missing data this function does the same as
+    `numpy.cov`. For more details and examples, see `numpy.cov`.
+
+    By default, masked values are recognized as such. If `x` and `y` have the
+    same shape, a common mask is allocated: if ``x[i,j]`` is masked, then
+    ``y[i,j]`` will also be masked.
+    Setting `allow_masked` to False will raise an exception if values are
+    missing in either of the input arrays.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        form as `x`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : bool, optional
+        Default normalization (False) is by ``(N-1)``, where ``N`` is the
+        number of observations given (unbiased estimate). If `bias` is True,
+        then normalization is by ``N``. This keyword can be overridden by
+        the keyword ``ddof`` in numpy versions >= 1.5.
+    allow_masked : bool, optional
+        If True, masked values are propagated pair-wise: if a value is masked
+        in `x`, the corresponding value is masked in `y`.
+        If False, raises a `ValueError` exception when some values are missing.
+    ddof : {None, int}, optional
+        If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
+        the number of observations; this overrides the value implied by
+        ``bias``. The default value is ``None``.
+
+        .. versionadded:: 1.5
+
+    Raises
+    ------
+    ValueError
+        Raised if some values are missing and `allow_masked` is False.
+
+    See Also
+    --------
+    numpy.cov
+
+    """
+    # Check inputs
+    if ddof is not None and ddof != int(ddof):
+        raise ValueError("ddof must be an integer")
+    # Set up ddof
+    if ddof is None:
+        if bias:
+            ddof = 0
+        else:
+            ddof = 1
+
+    (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
+    if not rowvar:
+        fact = np.dot(xnotmask.T, xnotmask) * 1. - ddof
+        result = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
+    else:
+        fact = np.dot(xnotmask, xnotmask.T) * 1. - ddof
+        result = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
+    return result
+
+
+def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, allow_masked=True,
+             ddof=np._NoValue):
+    """
+    Return Pearson product-moment correlation coefficients.
+
+    Except for the handling of missing data this function does the same as
+    `numpy.corrcoef`. For more details and examples, see `numpy.corrcoef`.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        shape as `x`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+    allow_masked : bool, optional
+        If True, masked values are propagated pair-wise: if a value is masked
+        in `x`, the corresponding value is masked in `y`.
+        If False, raises an exception.  Because `bias` is deprecated, this
+        argument needs to be treated as keyword only to avoid a warning.
+    ddof : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+
+    See Also
+    --------
+    numpy.corrcoef : Equivalent function in top-level NumPy module.
+    cov : Estimate the covariance matrix.
+
+    Notes
+    -----
+    This function accepts but discards arguments `bias` and `ddof`.  This is
+    for backwards compatibility with previous versions of this function.  These
+    arguments had no effect on the return values of the function and can be
+    safely ignored in this and previous versions of numpy.
+    """
+    msg = 'bias and ddof have no effect and are deprecated'
+    if bias is not np._NoValue or ddof is not np._NoValue:
+        # 2015-03-15, 1.10
+        warnings.warn(msg, DeprecationWarning)
+    # Get the data
+    (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
+    # Compute the covariance matrix
+    if not rowvar:
+        fact = np.dot(xnotmask.T, xnotmask) * 1.
+        c = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
+    else:
+        fact = np.dot(xnotmask, xnotmask.T) * 1.
+        c = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
+    # Check whether we have a scalar
+    try:
+        diag = ma.diagonal(c)
+    except ValueError:
+        return 1
+    #
+    if xnotmask.all():
+        _denom = ma.sqrt(ma.multiply.outer(diag, diag))
+    else:
+        _denom = diagflat(diag)
+        _denom._sharedmask = False  # We know return is always a copy
+        n = x.shape[1 - rowvar]
+        if rowvar:
+            for i in range(n - 1):
+                for j in range(i + 1, n):
+                    _x = mask_cols(vstack((x[i], x[j]))).var(axis=1)
+                    _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
+        else:
+            for i in range(n - 1):
+                for j in range(i + 1, n):
+                    _x = mask_cols(
+                            vstack((x[:, i], x[:, j]))).var(axis=1)
+                    _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
+    return c / _denom
+
+#####--------------------------------------------------------------------------
+#---- --- Concatenation helpers ---
+#####--------------------------------------------------------------------------
+
+class MAxisConcatenator(AxisConcatenator):
+    """
+    Translate slice objects to concatenation along an axis.
+
+    For documentation on usage, see `mr_class`.
+
+    See Also
+    --------
+    mr_class
+
+    """
+
+    def __init__(self, axis=0):
+        AxisConcatenator.__init__(self, axis, matrix=False)
+
+    def __getitem__(self, key):
+        if isinstance(key, str):
+            raise MAError("Unavailable for masked array.")
+        if not isinstance(key, tuple):
+            key = (key,)
+        objs = []
+        scalars = []
+        final_dtypedescr = None
+        for k in range(len(key)):
+            scalar = False
+            if isinstance(key[k], slice):
+                step = key[k].step
+                start = key[k].start
+                stop = key[k].stop
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size = int(abs(step))
+                    newobj = np.linspace(start, stop, num=size)
+                else:
+                    newobj = np.arange(start, stop, step)
+            elif isinstance(key[k], str):
+                if (key[k] in 'rc'):
+                    self.matrix = True
+                    self.col = (key[k] == 'c')
+                    continue
+                try:
+                    self.axis = int(key[k])
+                    continue
+                except (ValueError, TypeError):
+                    raise ValueError("Unknown special directive")
+            elif type(key[k]) in np.ScalarType:
+                newobj = asarray([key[k]])
+                scalars.append(k)
+                scalar = True
+            else:
+                newobj = key[k]
+            objs.append(newobj)
+            if isinstance(newobj, ndarray) and not scalar:
+                if final_dtypedescr is None:
+                    final_dtypedescr = newobj.dtype
+                elif newobj.dtype > final_dtypedescr:
+                    final_dtypedescr = newobj.dtype
+        if final_dtypedescr is not None:
+            for k in scalars:
+                objs[k] = objs[k].astype(final_dtypedescr)
+        res = concatenate(tuple(objs), axis=self.axis)
+        return self._retval(res)
+
+class mr_class(MAxisConcatenator):
+    """
+    Translate slice objects to concatenation along the first axis.
+
+    This is the masked array version of `lib.index_tricks.RClass`.
+
+    See Also
+    --------
+    lib.index_tricks.RClass
+
+    Examples
+    --------
+    >>> np.ma.mr_[np.ma.array([1,2,3]), 0, 0, np.ma.array([4,5,6])]
+    array([1, 2, 3, 0, 0, 4, 5, 6])
+
+    """
+    def __init__(self):
+        MAxisConcatenator.__init__(self, 0)
+
+mr_ = mr_class()
+
+#####--------------------------------------------------------------------------
+#---- Find unmasked data ---
+#####--------------------------------------------------------------------------
+
+def flatnotmasked_edges(a):
+    """
+    Find the indices of the first and last unmasked values.
+
+    Expects a 1-D `MaskedArray`, returns None if all values are masked.
+
+    Parameters
+    ----------
+    a : array_like
+        Input 1-D `MaskedArray`
+
+    Returns
+    -------
+    edges : ndarray or None
+        The indices of first and last non-masked value in the array.
+        Returns None if all values are masked.
+
+    See Also
+    --------
+    flatnotmasked_contiguous, notmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 1-D arrays.
+
+    Examples
+    --------
+    >>> a = np.ma.arange(10)
+    >>> flatnotmasked_edges(a)
+    [0,-1]
+
+    >>> mask = (a < 3) | (a > 8) | (a == 5)
+    >>> a[mask] = np.ma.masked
+    >>> np.array(a[~a.mask])
+    array([3, 4, 6, 7, 8])
+
+    >>> flatnotmasked_edges(a)
+    array([3, 8])
+
+    >>> a[:] = np.ma.masked
+    >>> print(flatnotmasked_edges(ma))
+    None
+
+    """
+    m = getmask(a)
+    if m is nomask or not np.any(m):
+        return np.array([0, a.size - 1])
+    unmasked = np.flatnonzero(~m)
+    if len(unmasked) > 0:
+        return unmasked[[0, -1]]
+    else:
+        return None
+
+
+def notmasked_edges(a, axis=None):
+    """
+    Find the indices of the first and last unmasked values along an axis.
+
+    If all values are masked, return None.  Otherwise, return a list
+    of two tuples, corresponding to the indices of the first and last
+    unmasked values respectively.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None (default), applies to a flattened version of the array.
+
+    Returns
+    -------
+    edges : ndarray or list
+        An array of start and end indexes if there are any masked data in
+        the array. If there are no masked data in the array, `edges` is a
+        list of the first and last index.
+
+    See Also
+    --------
+    flatnotmasked_contiguous, flatnotmasked_edges, notmasked_contiguous,
+    clump_masked, clump_unmasked
+
+    Examples
+    --------
+    >>> a = np.arange(9).reshape((3, 3))
+    >>> m = np.zeros_like(a)
+    >>> m[1:, 1:] = 1
+
+    >>> am = np.ma.array(a, mask=m)
+    >>> np.array(am[~am.mask])
+    array([0, 1, 2, 3, 6])
+
+    >>> np.ma.notmasked_edges(ma)
+    array([0, 6])
+
+    """
+    a = asarray(a)
+    if axis is None or a.ndim == 1:
+        return flatnotmasked_edges(a)
+    m = getmaskarray(a)
+    idx = array(np.indices(a.shape), mask=np.asarray([m] * a.ndim))
+    return [tuple([idx[i].min(axis).compressed() for i in range(a.ndim)]),
+            tuple([idx[i].max(axis).compressed() for i in range(a.ndim)]), ]
+
+
+def flatnotmasked_contiguous(a):
+    """
+    Find contiguous unmasked data in a masked array along the given axis.
+
+    Parameters
+    ----------
+    a : narray
+        The input array.
+
+    Returns
+    -------
+    slice_list : list
+        A sorted sequence of slices (start index, end index).
+
+    See Also
+    --------
+    flatnotmasked_edges, notmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 2-D arrays at most.
+
+    Examples
+    --------
+    >>> a = np.ma.arange(10)
+    >>> np.ma.flatnotmasked_contiguous(a)
+    slice(0, 10, None)
+
+    >>> mask = (a < 3) | (a > 8) | (a == 5)
+    >>> a[mask] = np.ma.masked
+    >>> np.array(a[~a.mask])
+    array([3, 4, 6, 7, 8])
+
+    >>> np.ma.flatnotmasked_contiguous(a)
+    [slice(3, 5, None), slice(6, 9, None)]
+    >>> a[:] = np.ma.masked
+    >>> print(np.ma.flatnotmasked_edges(a))
+    None
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        return slice(0, a.size, None)
+    i = 0
+    result = []
+    for (k, g) in itertools.groupby(m.ravel()):
+        n = len(list(g))
+        if not k:
+            result.append(slice(i, i + n))
+        i += n
+    return result or None
+
+def notmasked_contiguous(a, axis=None):
+    """
+    Find contiguous unmasked data in a masked array along the given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None (default), applies to a flattened version of the array.
+
+    Returns
+    -------
+    endpoints : list
+        A list of slices (start and end indexes) of unmasked indexes
+        in the array.
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 2-D arrays at most.
+
+    Examples
+    --------
+    >>> a = np.arange(9).reshape((3, 3))
+    >>> mask = np.zeros_like(a)
+    >>> mask[1:, 1:] = 1
+
+    >>> ma = np.ma.array(a, mask=mask)
+    >>> np.array(ma[~ma.mask])
+    array([0, 1, 2, 3, 6])
+
+    >>> np.ma.notmasked_contiguous(ma)
+    [slice(0, 4, None), slice(6, 7, None)]
+
+    """
+    a = asarray(a)
+    nd = a.ndim
+    if nd > 2:
+        raise NotImplementedError("Currently limited to atmost 2D array.")
+    if axis is None or nd == 1:
+        return flatnotmasked_contiguous(a)
+    #
+    result = []
+    #
+    other = (axis + 1) % 2
+    idx = [0, 0]
+    idx[axis] = slice(None, None)
+    #
+    for i in range(a.shape[other]):
+        idx[other] = i
+        result.append(flatnotmasked_contiguous(a[idx]) or None)
+    return result
+
+
+def _ezclump(mask):
+    """
+    Finds the clumps (groups of data with the same values) for a 1D bool array.
+
+    Returns a series of slices.
+    """
+    if mask.ndim > 1:
+        mask = mask.ravel()
+    idx = (mask[1:] ^ mask[:-1]).nonzero()
+    idx = idx[0] + 1
+
+    if mask[0]:
+        if len(idx) == 0:
+            return [slice(0, mask.size)]
+
+        r = [slice(0, idx[0])]
+        r.extend((slice(left, right)
+                  for left, right in zip(idx[1:-1:2], idx[2::2])))
+    else:
+        if len(idx) == 0:
+            return []
+
+        r = [slice(left, right) for left, right in zip(idx[:-1:2], idx[1::2])]
+
+    if mask[-1]:
+        r.append(slice(idx[-1], mask.size))
+    return r
+
+
+def clump_unmasked(a):
+    """
+    Return list of slices corresponding to the unmasked clumps of a 1-D array.
+    (A "clump" is defined as a contiguous region of the array).
+
+    Parameters
+    ----------
+    a : ndarray
+        A one-dimensional masked array.
+
+    Returns
+    -------
+    slices : list of slice
+        The list of slices, one for each continuous region of unmasked
+        elements in `a`.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    notmasked_contiguous, clump_masked
+
+    Examples
+    --------
+    >>> a = np.ma.masked_array(np.arange(10))
+    >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
+    >>> np.ma.clump_unmasked(a)
+    [slice(3, 6, None), slice(7, 8, None)]
+
+    """
+    mask = getattr(a, '_mask', nomask)
+    if mask is nomask:
+        return [slice(0, a.size)]
+    return _ezclump(~mask)
+
+
+def clump_masked(a):
+    """
+    Returns a list of slices corresponding to the masked clumps of a 1-D array.
+    (A "clump" is defined as a contiguous region of the array).
+
+    Parameters
+    ----------
+    a : ndarray
+        A one-dimensional masked array.
+
+    Returns
+    -------
+    slices : list of slice
+        The list of slices, one for each continuous region of masked elements
+        in `a`.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    notmasked_contiguous, clump_unmasked
+
+    Examples
+    --------
+    >>> a = np.ma.masked_array(np.arange(10))
+    >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
+    >>> np.ma.clump_masked(a)
+    [slice(0, 3, None), slice(6, 7, None), slice(8, 10, None)]
+
+    """
+    mask = ma.getmask(a)
+    if mask is nomask:
+        return []
+    return _ezclump(mask)
+
+
+###############################################################################
+#                              Polynomial fit                                 #
+###############################################################################
+
+
+def vander(x, n=None):
+    """
+    Masked values in the input array result in rows of zeros.
+
+    """
+    _vander = np.vander(x, n)
+    m = getmask(x)
+    if m is not nomask:
+        _vander[m] = 0
+    return _vander
+
+vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__)
+
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
+    """
+    Any masked values in x is propagated in y, and vice-versa.
+
+    """
+    x = asarray(x)
+    y = asarray(y)
+
+    m = getmask(x)
+    if y.ndim == 1:
+        m = mask_or(m, getmask(y))
+    elif y.ndim == 2:
+        my = getmask(mask_rows(y))
+        if my is not nomask:
+            m = mask_or(m, my[:, 0])
+    else:
+        raise TypeError("Expected a 1D or 2D array for y!")
+
+    if w is not None:
+        w = asarray(w)
+        if w.ndim != 1:
+            raise TypeError("expected a 1-d array for weights")
+        if w.shape[0] != y.shape[0]:
+            raise TypeError("expected w and y to have the same length")
+        m = mask_or(m, getmask(w))
+
+    if m is not nomask:
+        not_m = ~m
+        if w is not None:
+            w = w[not_m]
+        return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov)
+    else:
+        return np.polyfit(x, y, deg, rcond, full, w, cov)
+
+polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.py
new file mode 100644
index 0000000000..382bcc9727
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.py
@@ -0,0 +1,796 @@
+""":mod:`numpy.ma..mrecords`
+
+Defines the equivalent of :class:`numpy.recarrays` for masked arrays,
+where fields can be accessed as attributes.
+Note that :class:`numpy.ma.MaskedArray` already supports structured datatypes
+and the masking of individual fields.
+
+.. moduleauthor:: Pierre Gerard-Marchant
+
+"""
+from __future__ import division, absolute_import, print_function
+
+#  We should make sure that no field is called '_mask','mask','_fieldmask',
+#  or whatever restricted keywords.  An idea would be to no bother in the
+#  first place, and then rename the invalid fields with a trailing
+#  underscore. Maybe we could just overload the parser function ?
+
+import sys
+import warnings
+
+import numpy as np
+import numpy.core.numerictypes as ntypes
+from numpy.compat import basestring
+from numpy import (
+        bool_, dtype, ndarray, recarray, array as narray
+        )
+from numpy.core.records import (
+        fromarrays as recfromarrays, fromrecords as recfromrecords
+        )
+
+_byteorderconv = np.core.records._byteorderconv
+_typestr = ntypes._typestr
+
+import numpy.ma as ma
+from numpy.ma import (
+        MAError, MaskedArray, masked, nomask, masked_array, getdata,
+        getmaskarray, filled
+        )
+
+_check_fill_value = ma.core._check_fill_value
+
+
+__all__ = [
+    'MaskedRecords', 'mrecarray', 'fromarrays', 'fromrecords',
+    'fromtextfile', 'addfield',
+    ]
+
+reserved_fields = ['_data', '_mask', '_fieldmask', 'dtype']
+
+
+def _getformats(data):
+    """
+    Returns the formats of arrays in arraylist as a comma-separated string.
+
+    """
+    if hasattr(data, 'dtype'):
+        return ",".join([desc[1] for desc in data.dtype.descr])
+
+    formats = ''
+    for obj in data:
+        obj = np.asarray(obj)
+        formats += _typestr[obj.dtype.type]
+        if issubclass(obj.dtype.type, ntypes.flexible):
+            formats += repr(obj.itemsize)
+        formats += ','
+    return formats[:-1]
+
+
+def _checknames(descr, names=None):
+    """
+    Checks that field names ``descr`` are not reserved keywords.
+
+    If this is the case, a default 'f%i' is substituted.  If the argument
+    `names` is not None, updates the field names to valid names.
+
+    """
+    ndescr = len(descr)
+    default_names = ['f%i' % i for i in range(ndescr)]
+    if names is None:
+        new_names = default_names
+    else:
+        if isinstance(names, (tuple, list)):
+            new_names = names
+        elif isinstance(names, str):
+            new_names = names.split(',')
+        else:
+            raise NameError("illegal input names %s" % repr(names))
+        nnames = len(new_names)
+        if nnames < ndescr:
+            new_names += default_names[nnames:]
+    ndescr = []
+    for (n, d, t) in zip(new_names, default_names, descr.descr):
+        if n in reserved_fields:
+            if t[0] in reserved_fields:
+                ndescr.append((d, t[1]))
+            else:
+                ndescr.append(t)
+        else:
+            ndescr.append((n, t[1]))
+    return np.dtype(ndescr)
+
+
+def _get_fieldmask(self):
+    mdescr = [(n, '|b1') for n in self.dtype.names]
+    fdmask = np.empty(self.shape, dtype=mdescr)
+    fdmask.flat = tuple([False] * len(mdescr))
+    return fdmask
+
+
+class MaskedRecords(MaskedArray, object):
+    """
+
+    Attributes
+    ----------
+    _data : recarray
+        Underlying data, as a record array.
+    _mask : boolean array
+        Mask of the records. A record is masked when all its fields are
+        masked.
+    _fieldmask : boolean recarray
+        Record array of booleans, setting the mask of each individual field
+        of each record.
+    _fill_value : record
+        Filling values for each field.
+
+    """
+
+    def __new__(cls, shape, dtype=None, buf=None, offset=0, strides=None,
+                formats=None, names=None, titles=None,
+                byteorder=None, aligned=False,
+                mask=nomask, hard_mask=False, fill_value=None, keep_mask=True,
+                copy=False,
+                **options):
+
+        self = recarray.__new__(cls, shape, dtype=dtype, buf=buf, offset=offset,
+                                strides=strides, formats=formats, names=names,
+                                titles=titles, byteorder=byteorder,
+                                aligned=aligned,)
+
+        mdtype = ma.make_mask_descr(self.dtype)
+        if mask is nomask or not np.size(mask):
+            if not keep_mask:
+                self._mask = tuple([False] * len(mdtype))
+        else:
+            mask = np.array(mask, copy=copy)
+            if mask.shape != self.shape:
+                (nd, nm) = (self.size, mask.size)
+                if nm == 1:
+                    mask = np.resize(mask, self.shape)
+                elif nm == nd:
+                    mask = np.reshape(mask, self.shape)
+                else:
+                    msg = "Mask and data not compatible: data size is %i, " + \
+                          "mask size is %i."
+                    raise MAError(msg % (nd, nm))
+                copy = True
+            if not keep_mask:
+                self.__setmask__(mask)
+                self._sharedmask = True
+            else:
+                if mask.dtype == mdtype:
+                    _mask = mask
+                else:
+                    _mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                     dtype=mdtype)
+                self._mask = _mask
+        return self
+
+    def __array_finalize__(self, obj):
+        # Make sure we have a _fieldmask by default
+        _mask = getattr(obj, '_mask', None)
+        if _mask is None:
+            objmask = getattr(obj, '_mask', nomask)
+            _dtype = ndarray.__getattribute__(self, 'dtype')
+            if objmask is nomask:
+                _mask = ma.make_mask_none(self.shape, dtype=_dtype)
+            else:
+                mdescr = ma.make_mask_descr(_dtype)
+                _mask = narray([tuple([m] * len(mdescr)) for m in objmask],
+                               dtype=mdescr).view(recarray)
+        # Update some of the attributes
+        _dict = self.__dict__
+        _dict.update(_mask=_mask)
+        self._update_from(obj)
+        if _dict['_baseclass'] == ndarray:
+            _dict['_baseclass'] = recarray
+        return
+
+    def _getdata(self):
+        """
+        Returns the data as a recarray.
+
+        """
+        return ndarray.view(self, recarray)
+
+    _data = property(fget=_getdata)
+
+    def _getfieldmask(self):
+        """
+        Alias to mask.
+
+        """
+        return self._mask
+
+    _fieldmask = property(fget=_getfieldmask)
+
+    def __len__(self):
+        """
+        Returns the length
+
+        """
+        # We have more than one record
+        if self.ndim:
+            return len(self._data)
+        # We have only one record: return the nb of fields
+        return len(self.dtype)
+
+    def __getattribute__(self, attr):
+        try:
+            return object.__getattribute__(self, attr)
+        except AttributeError:
+            # attr must be a fieldname
+            pass
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+        # So far, so good
+        _localdict = ndarray.__getattribute__(self, '__dict__')
+        _data = ndarray.view(self, _localdict['_baseclass'])
+        obj = _data.getfield(*res)
+        if obj.dtype.fields:
+            raise NotImplementedError("MaskedRecords is currently limited to"
+                                      "simple records.")
+        # Get some special attributes
+        # Reset the object's mask
+        hasmasked = False
+        _mask = _localdict.get('_mask', None)
+        if _mask is not None:
+            try:
+                _mask = _mask[attr]
+            except IndexError:
+                # Couldn't find a mask: use the default (nomask)
+                pass
+            hasmasked = _mask.view((np.bool, (len(_mask.dtype) or 1))).any()
+        if (obj.shape or hasmasked):
+            obj = obj.view(MaskedArray)
+            obj._baseclass = ndarray
+            obj._isfield = True
+            obj._mask = _mask
+            # Reset the field values
+            _fill_value = _localdict.get('_fill_value', None)
+            if _fill_value is not None:
+                try:
+                    obj._fill_value = _fill_value[attr]
+                except ValueError:
+                    obj._fill_value = None
+        else:
+            obj = obj.item()
+        return obj
+
+    def __setattr__(self, attr, val):
+        """
+        Sets the attribute attr to the value val.
+
+        """
+        # Should we call __setmask__ first ?
+        if attr in ['mask', 'fieldmask']:
+            self.__setmask__(val)
+            return
+        # Create a shortcut (so that we don't have to call getattr all the time)
+        _localdict = object.__getattribute__(self, '__dict__')
+        # Check whether we're creating a new field
+        newattr = attr not in _localdict
+        try:
+            # Is attr a generic attribute ?
+            ret = object.__setattr__(self, attr, val)
+        except:
+            # Not a generic attribute: exit if it's not a valid field
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            optinfo = ndarray.__getattribute__(self, '_optinfo') or {}
+            if not (attr in fielddict or attr in optinfo):
+                exctype, value = sys.exc_info()[:2]
+                raise exctype(value)
+        else:
+            # Get the list of names
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            # Check the attribute
+            if attr not in fielddict:
+                return ret
+            if newattr:
+                # We just added this one or this setattr worked on an
+                # internal attribute.
+                try:
+                    object.__delattr__(self, attr)
+                except:
+                    return ret
+        # Let's try to set the field
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+
+        if val is masked:
+            _fill_value = _localdict['_fill_value']
+            if _fill_value is not None:
+                dval = _localdict['_fill_value'][attr]
+            else:
+                dval = val
+            mval = True
+        else:
+            dval = filled(val)
+            mval = getmaskarray(val)
+        obj = ndarray.__getattribute__(self, '_data').setfield(dval, *res)
+        _localdict['_mask'].__setitem__(attr, mval)
+        return obj
+
+    def __getitem__(self, indx):
+        """
+        Returns all the fields sharing the same fieldname base.
+
+        The fieldname base is either `_data` or `_mask`.
+
+        """
+        _localdict = self.__dict__
+        _mask = ndarray.__getattribute__(self, '_mask')
+        _data = ndarray.view(self, _localdict['_baseclass'])
+        # We want a field
+        if isinstance(indx, basestring):
+            # Make sure _sharedmask is True to propagate back to _fieldmask
+            # Don't use _set_mask, there are some copies being made that
+            # break propagation Don't force the mask to nomask, that wreaks
+            # easy masking
+            obj = _data[indx].view(MaskedArray)
+            obj._mask = _mask[indx]
+            obj._sharedmask = True
+            fval = _localdict['_fill_value']
+            if fval is not None:
+                obj._fill_value = fval[indx]
+            # Force to masked if the mask is True
+            if not obj.ndim and obj._mask:
+                return masked
+            return obj
+        # We want some elements.
+        # First, the data.
+        obj = np.array(_data[indx], copy=False).view(mrecarray)
+        obj._mask = np.array(_mask[indx], copy=False).view(recarray)
+        return obj
+
+    def __setitem__(self, indx, value):
+        """
+        Sets the given record to value.
+
+        """
+        MaskedArray.__setitem__(self, indx, value)
+        if isinstance(indx, basestring):
+            self._mask[indx] = ma.getmaskarray(value)
+
+    def __str__(self):
+        """
+        Calculates the string representation.
+
+        """
+        if self.size > 1:
+            mstr = ["(%s)" % ",".join([str(i) for i in s])
+                    for s in zip(*[getattr(self, f) for f in self.dtype.names])]
+            return "[%s]" % ", ".join(mstr)
+        else:
+            mstr = ["%s" % ",".join([str(i) for i in s])
+                    for s in zip([getattr(self, f) for f in self.dtype.names])]
+            return "(%s)" % ", ".join(mstr)
+
+    def __repr__(self):
+        """
+        Calculates the repr representation.
+
+        """
+        _names = self.dtype.names
+        fmt = "%%%is : %%s" % (max([len(n) for n in _names]) + 4,)
+        reprstr = [fmt % (f, getattr(self, f)) for f in self.dtype.names]
+        reprstr.insert(0, 'masked_records(')
+        reprstr.extend([fmt % ('    fill_value', self.fill_value),
+                         '              )'])
+        return str("\n".join(reprstr))
+
+    def view(self, dtype=None, type=None):
+        """
+        Returns a view of the mrecarray.
+
+        """
+        # OK, basic copy-paste from MaskedArray.view.
+        if dtype is None:
+            if type is None:
+                output = ndarray.view(self)
+            else:
+                output = ndarray.view(self, type)
+        # Here again.
+        elif type is None:
+            try:
+                if issubclass(dtype, ndarray):
+                    output = ndarray.view(self, dtype)
+                    dtype = None
+                else:
+                    output = ndarray.view(self, dtype)
+            # OK, there's the change
+            except TypeError:
+                dtype = np.dtype(dtype)
+                # we need to revert to MaskedArray, but keeping the possibility
+                # of subclasses (eg, TimeSeriesRecords), so we'll force a type
+                # set to the first parent
+                if dtype.fields is None:
+                    basetype = self.__class__.__bases__[0]
+                    output = self.__array__().view(dtype, basetype)
+                    output._update_from(self)
+                else:
+                    output = ndarray.view(self, dtype)
+                output._fill_value = None
+        else:
+            output = ndarray.view(self, dtype, type)
+        # Update the mask, just like in MaskedArray.view
+        if (getattr(output, '_mask', nomask) is not nomask):
+            mdtype = ma.make_mask_descr(output.dtype)
+            output._mask = self._mask.view(mdtype, ndarray)
+            output._mask.shape = output.shape
+        return output
+
+    def harden_mask(self):
+        """
+        Forces the mask to hard.
+
+        """
+        self._hardmask = True
+
+    def soften_mask(self):
+        """
+        Forces the mask to soft
+
+        """
+        self._hardmask = False
+
+    def copy(self):
+        """
+        Returns a copy of the masked record.
+
+        """
+        copied = self._data.copy().view(type(self))
+        copied._mask = self._mask.copy()
+        return copied
+
+    def tolist(self, fill_value=None):
+        """
+        Return the data portion of the array as a list.
+
+        Data items are converted to the nearest compatible Python type.
+        Masked values are converted to fill_value. If fill_value is None,
+        the corresponding entries in the output list will be ``None``.
+
+        """
+        if fill_value is not None:
+            return self.filled(fill_value).tolist()
+        result = narray(self.filled().tolist(), dtype=object)
+        mask = narray(self._mask.tolist())
+        result[mask] = None
+        return result.tolist()
+
+    def __getstate__(self):
+        """Return the internal state of the masked array.
+
+        This is for pickling.
+
+        """
+        state = (1,
+                 self.shape,
+                 self.dtype,
+                 self.flags.fnc,
+                 self._data.tobytes(),
+                 self._mask.tobytes(),
+                 self._fill_value,
+                 )
+        return state
+
+    def __setstate__(self, state):
+        """
+        Restore the internal state of the masked array.
+
+        This is for pickling.  ``state`` is typically the output of the
+        ``__getstate__`` output, and is a 5-tuple:
+
+        - class name
+        - a tuple giving the shape of the data
+        - a typecode for the data
+        - a binary string for the data
+        - a binary string for the mask.
+
+        """
+        (ver, shp, typ, isf, raw, msk, flv) = state
+        ndarray.__setstate__(self, (shp, typ, isf, raw))
+        mdtype = dtype([(k, bool_) for (k, _) in self.dtype.descr])
+        self.__dict__['_mask'].__setstate__((shp, mdtype, isf, msk))
+        self.fill_value = flv
+
+    def __reduce__(self):
+        """
+        Return a 3-tuple for pickling a MaskedArray.
+
+        """
+        return (_mrreconstruct,
+                (self.__class__, self._baseclass, (0,), 'b',),
+                self.__getstate__())
+
+def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
+    """
+    Build a new MaskedArray from the information stored in a pickle.
+
+    """
+    _data = ndarray.__new__(baseclass, baseshape, basetype).view(subtype)
+    _mask = ndarray.__new__(ndarray, baseshape, 'b1')
+    return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
+mrecarray = MaskedRecords
+
+
+###############################################################################
+#                             Constructors                                    #
+###############################################################################
+
+
+def fromarrays(arraylist, dtype=None, shape=None, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None,
+               fill_value=None):
+    """
+    Creates a mrecarray from a (flat) list of masked arrays.
+
+    Parameters
+    ----------
+    arraylist : sequence
+        A list of (masked) arrays. Each element of the sequence is first converted
+        to a masked array if needed. If a 2D array is passed as argument, it is
+        processed line by line
+    dtype : {None, dtype}, optional
+        Data type descriptor.
+    shape : {None, integer}, optional
+        Number of records. If None, shape is defined from the shape of the
+        first array in the list.
+    formats : {None, sequence}, optional
+        Sequence of formats for each individual field. If None, the formats will
+        be autodetected by inspecting the fields and selecting the highest dtype
+        possible.
+    names : {None, sequence}, optional
+        Sequence of the names of each field.
+    fill_value : {None, sequence}, optional
+        Sequence of data to be used as filling values.
+
+    Notes
+    -----
+    Lists of tuples should be preferred over lists of lists for faster processing.
+
+    """
+    datalist = [getdata(x) for x in arraylist]
+    masklist = [np.atleast_1d(getmaskarray(x)) for x in arraylist]
+    _array = recfromarrays(datalist,
+                           dtype=dtype, shape=shape, formats=formats,
+                           names=names, titles=titles, aligned=aligned,
+                           byteorder=byteorder).view(mrecarray)
+    _array._mask.flat = list(zip(*masklist))
+    if fill_value is not None:
+        _array.fill_value = fill_value
+    return _array
+
+
+def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None,
+                titles=None, aligned=False, byteorder=None,
+                fill_value=None, mask=nomask):
+    """
+    Creates a MaskedRecords from a list of records.
+
+    Parameters
+    ----------
+    reclist : sequence
+        A list of records. Each element of the sequence is first converted
+        to a masked array if needed. If a 2D array is passed as argument, it is
+        processed line by line
+    dtype : {None, dtype}, optional
+        Data type descriptor.
+    shape : {None,int}, optional
+        Number of records. If None, ``shape`` is defined from the shape of the
+        first array in the list.
+    formats : {None, sequence}, optional
+        Sequence of formats for each individual field. If None, the formats will
+        be autodetected by inspecting the fields and selecting the highest dtype
+        possible.
+    names : {None, sequence}, optional
+        Sequence of the names of each field.
+    fill_value : {None, sequence}, optional
+        Sequence of data to be used as filling values.
+    mask : {nomask, sequence}, optional.
+        External mask to apply on the data.
+
+    Notes
+    -----
+    Lists of tuples should be preferred over lists of lists for faster processing.
+
+    """
+    # Grab the initial _fieldmask, if needed:
+    _mask = getattr(reclist, '_mask', None)
+    # Get the list of records.
+    if isinstance(reclist, ndarray):
+        # Make sure we don't have some hidden mask
+        if isinstance(reclist, MaskedArray):
+            reclist = reclist.filled().view(ndarray)
+        # Grab the initial dtype, just in case
+        if dtype is None:
+            dtype = reclist.dtype
+        reclist = reclist.tolist()
+    mrec = recfromrecords(reclist, dtype=dtype, shape=shape, formats=formats,
+                          names=names, titles=titles,
+                          aligned=aligned, byteorder=byteorder).view(mrecarray)
+    # Set the fill_value if needed
+    if fill_value is not None:
+        mrec.fill_value = fill_value
+    # Now, let's deal w/ the mask
+    if mask is not nomask:
+        mask = np.array(mask, copy=False)
+        maskrecordlength = len(mask.dtype)
+        if maskrecordlength:
+            mrec._mask.flat = mask
+        elif len(mask.shape) == 2:
+            mrec._mask.flat = [tuple(m) for m in mask]
+        else:
+            mrec.__setmask__(mask)
+    if _mask is not None:
+        mrec._mask[:] = _mask
+    return mrec
+
+
+def _guessvartypes(arr):
+    """
+    Tries to guess the dtypes of the str_ ndarray `arr`.
+
+    Guesses by testing element-wise conversion. Returns a list of dtypes.
+    The array is first converted to ndarray. If the array is 2D, the test
+    is performed on the first line. An exception is raised if the file is
+    3D or more.
+
+    """
+    vartypes = []
+    arr = np.asarray(arr)
+    if len(arr.shape) == 2:
+        arr = arr[0]
+    elif len(arr.shape) > 2:
+        raise ValueError("The array should be 2D at most!")
+    # Start the conversion loop.
+    for f in arr:
+        try:
+            int(f)
+        except ValueError:
+            try:
+                float(f)
+            except ValueError:
+                try:
+                    complex(f)
+                except ValueError:
+                    vartypes.append(arr.dtype)
+                else:
+                    vartypes.append(np.dtype(complex))
+            else:
+                vartypes.append(np.dtype(float))
+        else:
+            vartypes.append(np.dtype(int))
+    return vartypes
+
+
+def openfile(fname):
+    """
+    Opens the file handle of file `fname`.
+
+    """
+    # A file handle
+    if hasattr(fname, 'readline'):
+        return fname
+    # Try to open the file and guess its type
+    try:
+        f = open(fname)
+    except IOError:
+        raise IOError("No such file: '%s'" % fname)
+    if f.readline()[:2] != "\\x":
+        f.seek(0, 0)
+        return f
+    f.close()
+    raise NotImplementedError("Wow, binary file")
+
+
+def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='',
+                 varnames=None, vartypes=None):
+    """
+    Creates a mrecarray from data stored in the file `filename`.
+
+    Parameters
+    ----------
+    fname : {file name/handle}
+        Handle of an opened file.
+    delimitor : {None, string}, optional
+        Alphanumeric character used to separate columns in the file.
+        If None, any (group of) white spacestring(s) will be used.
+    commentchar : {'#', string}, optional
+        Alphanumeric character used to mark the start of a comment.
+    missingchar : {'', string}, optional
+        String indicating missing data, and used to create the masks.
+    varnames : {None, sequence}, optional
+        Sequence of the variable names. If None, a list will be created from
+        the first non empty line of the file.
+    vartypes : {None, sequence}, optional
+        Sequence of the variables dtypes. If None, it will be estimated from
+        the first non-commented line.
+
+
+    Ultra simple: the varnames are in the header, one line"""
+    # Try to open the file.
+    ftext = openfile(fname)
+
+    # Get the first non-empty line as the varnames
+    while True:
+        line = ftext.readline()
+        firstline = line[:line.find(commentchar)].strip()
+        _varnames = firstline.split(delimitor)
+        if len(_varnames) > 1:
+            break
+    if varnames is None:
+        varnames = _varnames
+
+    # Get the data.
+    _variables = masked_array([line.strip().split(delimitor) for line in ftext
+                               if line[0] != commentchar and len(line) > 1])
+    (_, nfields) = _variables.shape
+    ftext.close()
+
+    # Try to guess the dtype.
+    if vartypes is None:
+        vartypes = _guessvartypes(_variables[0])
+    else:
+        vartypes = [np.dtype(v) for v in vartypes]
+        if len(vartypes) != nfields:
+            msg = "Attempting to %i dtypes for %i fields!"
+            msg += " Reverting to default."
+            warnings.warn(msg % (len(vartypes), nfields))
+            vartypes = _guessvartypes(_variables[0])
+
+    # Construct the descriptor.
+    mdescr = [(n, f) for (n, f) in zip(varnames, vartypes)]
+    mfillv = [ma.default_fill_value(f) for f in vartypes]
+
+    # Get the data and the mask.
+    # We just need a list of masked_arrays. It's easier to create it like that:
+    _mask = (_variables.T == missingchar)
+    _datalist = [masked_array(a, mask=m, dtype=t, fill_value=f)
+                 for (a, m, t, f) in zip(_variables.T, _mask, vartypes, mfillv)]
+
+    return fromarrays(_datalist, dtype=mdescr)
+
+
+def addfield(mrecord, newfield, newfieldname=None):
+    """Adds a new field to the masked record array
+
+    Uses `newfield` as data and `newfieldname` as name. If `newfieldname`
+    is None, the new field name is set to 'fi', where `i` is the number of
+    existing fields.
+
+    """
+    _data = mrecord._data
+    _mask = mrecord._mask
+    if newfieldname is None or newfieldname in reserved_fields:
+        newfieldname = 'f%i' % len(_data.dtype)
+    newfield = ma.array(newfield)
+    # Get the new data.
+    # Create a new empty recarray
+    newdtype = np.dtype(_data.dtype.descr + [(newfieldname, newfield.dtype)])
+    newdata = recarray(_data.shape, newdtype)
+    # Add the exisintg field
+    [newdata.setfield(_data.getfield(*f), *f)
+         for f in _data.dtype.fields.values()]
+    # Add the new field
+    newdata.setfield(newfield._data, *newdata.dtype.fields[newfieldname])
+    newdata = newdata.view(MaskedRecords)
+    # Get the new mask
+    # Create a new empty recarray
+    newmdtype = np.dtype([(n, bool_) for n in newdtype.names])
+    newmask = recarray(_data.shape, newmdtype)
+    # Add the old masks
+    [newmask.setfield(_mask.getfield(*f), *f)
+         for f in _mask.dtype.fields.values()]
+    # Add the mask of the new field
+    newmask.setfield(getmaskarray(newfield),
+                     *newmask.dtype.fields[newfieldname])
+    newdata._mask = newmask
+    return newdata
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/setup.py
new file mode 100644
index 0000000000..6c6a52abad
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('ma', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    config = configuration(top_path='').todict()
+    setup(**config)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_core.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
new file mode 100644
index 0000000000..b163d3b264
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
@@ -0,0 +1,4260 @@
+# pylint: disable-msg=W0401,W0511,W0611,W0612,W0614,R0201,E1102
+"""Tests suite for MaskedArray & subclassing.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+"""
+from __future__ import division, absolute_import, print_function
+
+__author__ = "Pierre GF Gerard-Marchant"
+
+import warnings
+import pickle
+import operator
+import itertools
+from functools import reduce
+
+
+import numpy as np
+import numpy.ma.core
+import numpy.core.fromnumeric as fromnumeric
+import numpy.core.umath as umath
+from numpy.testing import TestCase, run_module_suite, assert_raises
+from numpy import ndarray
+from numpy.compat import asbytes, asbytes_nested
+from numpy.ma.testutils import (
+    assert_, assert_array_equal, assert_equal, assert_almost_equal,
+    assert_equal_records, fail_if_equal, assert_not_equal,
+    assert_mask_equal,
+    )
+from numpy.ma.core import (
+    MAError, MaskError, MaskType, MaskedArray, abs, absolute, add, all,
+    allclose, allequal, alltrue, angle, anom, arange, arccos, arctan2,
+    arcsin, arctan, argsort, array, asarray, choose, concatenate,
+    conjugate, cos, cosh, count, default_fill_value, diag, divide, empty,
+    empty_like, equal, exp, flatten_mask, filled, fix_invalid,
+    flatten_structured_array, fromflex, getmask, getmaskarray, greater,
+    greater_equal, identity, inner, isMaskedArray, less, less_equal, log,
+    log10, make_mask, make_mask_descr, mask_or, masked, masked_array,
+    masked_equal, masked_greater, masked_greater_equal, masked_inside,
+    masked_less, masked_less_equal, masked_not_equal, masked_outside,
+    masked_print_option, masked_values, masked_where, max, maximum,
+    maximum_fill_value, min, minimum, minimum_fill_value, mod, multiply,
+    mvoid, nomask, not_equal, ones, outer, power, product, put, putmask,
+    ravel, repeat, reshape, resize, shape, sin, sinh, sometrue, sort, sqrt,
+    subtract, sum, take, tan, tanh, transpose, where, zeros,
+    )
+
+pi = np.pi
+
+
+class TestMaskedArray(TestCase):
+    # Base test class for MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
+
+    def test_basicattributes(self):
+        # Tests some basic array attributes.
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        assert_equal(a.ndim, 1)
+        assert_equal(b.ndim, 1)
+        assert_equal(a.size, 3)
+        assert_equal(b.size, 3)
+        assert_equal(a.shape, (3,))
+        assert_equal(b.shape, (3,))
+
+    def test_basic0d(self):
+        # Checks masking a scalar
+        x = masked_array(0)
+        assert_equal(str(x), '0')
+        x = masked_array(0, mask=True)
+        assert_equal(str(x), str(masked_print_option))
+        x = masked_array(0, mask=False)
+        assert_equal(str(x), '0')
+        x = array(0, mask=1)
+        self.assertTrue(x.filled().dtype is x._data.dtype)
+
+    def test_basic1d(self):
+        # Test of basic array creation and properties in 1 dimension.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        self.assertTrue(not isMaskedArray(x))
+        self.assertTrue(isMaskedArray(xm))
+        self.assertTrue((xm - ym).filled(0).any())
+        fail_if_equal(xm.mask.astype(int), ym.mask.astype(int))
+        s = x.shape
+        assert_equal(np.shape(xm), s)
+        assert_equal(xm.shape, s)
+        assert_equal(xm.dtype, x.dtype)
+        assert_equal(zm.dtype, z.dtype)
+        assert_equal(xm.size, reduce(lambda x, y:x * y, s))
+        assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+        assert_array_equal(xm, xf)
+        assert_array_equal(filled(xm, 1.e20), xf)
+        assert_array_equal(x, xm)
+
+    def test_basic2d(self):
+        # Test of basic array creation and properties in 2 dimensions.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        for s in [(4, 3), (6, 2)]:
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+
+            self.assertTrue(not isMaskedArray(x))
+            self.assertTrue(isMaskedArray(xm))
+            assert_equal(shape(xm), s)
+            assert_equal(xm.shape, s)
+            assert_equal(xm.size, reduce(lambda x, y:x * y, s))
+            assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+            assert_equal(xm, xf)
+            assert_equal(filled(xm, 1.e20), xf)
+            assert_equal(x, xm)
+
+    def test_concatenate_basic(self):
+        # Tests concatenations.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # basic concatenation
+        assert_equal(np.concatenate((x, y)), concatenate((xm, ym)))
+        assert_equal(np.concatenate((x, y)), concatenate((x, y)))
+        assert_equal(np.concatenate((x, y)), concatenate((xm, y)))
+        assert_equal(np.concatenate((x, y, x)), concatenate((x, ym, x)))
+
+    def test_concatenate_alongaxis(self):
+        # Tests concatenations.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # Concatenation along an axis
+        s = (3, 4)
+        x.shape = y.shape = xm.shape = ym.shape = s
+        assert_equal(xm.mask, np.reshape(m1, s))
+        assert_equal(ym.mask, np.reshape(m2, s))
+        xmym = concatenate((xm, ym), 1)
+        assert_equal(np.concatenate((x, y), 1), xmym)
+        assert_equal(np.concatenate((xm.mask, ym.mask), 1), xmym._mask)
+
+        x = zeros(2)
+        y = array(ones(2), mask=[False, True])
+        z = concatenate((x, y))
+        assert_array_equal(z, [0, 0, 1, 1])
+        assert_array_equal(z.mask, [False, False, False, True])
+        z = concatenate((y, x))
+        assert_array_equal(z, [1, 1, 0, 0])
+        assert_array_equal(z.mask, [False, True, False, False])
+
+    def test_concatenate_flexible(self):
+        # Tests the concatenation on flexible arrays.
+        data = masked_array(list(zip(np.random.rand(10),
+                                     np.arange(10))),
+                            dtype=[('a', float), ('b', int)])
+
+        test = concatenate([data[:5], data[5:]])
+        assert_equal_records(test, data)
+
+    def test_creation_ndmin(self):
+        # Check the use of ndmin
+        x = array([1, 2, 3], mask=[1, 0, 0], ndmin=2)
+        assert_equal(x.shape, (1, 3))
+        assert_equal(x._data, [[1, 2, 3]])
+        assert_equal(x._mask, [[1, 0, 0]])
+
+    def test_creation_ndmin_from_maskedarray(self):
+        # Make sure we're not losing the original mask w/ ndmin
+        x = array([1, 2, 3])
+        x[-1] = masked
+        xx = array(x, ndmin=2, dtype=float)
+        assert_equal(x.shape, x._mask.shape)
+        assert_equal(xx.shape, xx._mask.shape)
+
+    def test_creation_maskcreation(self):
+        # Tests how masks are initialized at the creation of Maskedarrays.
+        data = arange(24, dtype=float)
+        data[[3, 6, 15]] = masked
+        dma_1 = MaskedArray(data)
+        assert_equal(dma_1.mask, data.mask)
+        dma_2 = MaskedArray(dma_1)
+        assert_equal(dma_2.mask, dma_1.mask)
+        dma_3 = MaskedArray(dma_1, mask=[1, 0, 0, 0] * 6)
+        fail_if_equal(dma_3.mask, dma_1.mask)
+
+        x = array([1, 2, 3], mask=True)
+        assert_equal(x._mask, [True, True, True])
+        x = array([1, 2, 3], mask=False)
+        assert_equal(x._mask, [False, False, False])
+        y = array([1, 2, 3], mask=x._mask, copy=False)
+        assert_(np.may_share_memory(x.mask, y.mask))
+        y = array([1, 2, 3], mask=x._mask, copy=True)
+        assert_(not np.may_share_memory(x.mask, y.mask))
+
+    def test_creation_with_list_of_maskedarrays(self):
+        # Tests creating a masked array from a list of masked arrays.
+        x = array(np.arange(5), mask=[1, 0, 0, 0, 0])
+        data = array((x, x[::-1]))
+        assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
+        assert_equal(data._mask, [[1, 0, 0, 0, 0], [0, 0, 0, 0, 1]])
+
+        x.mask = nomask
+        data = array((x, x[::-1]))
+        assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
+        self.assertTrue(data.mask is nomask)
+
+    def test_asarray(self):
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        xm.fill_value = -9999
+        xm._hardmask = True
+        xmm = asarray(xm)
+        assert_equal(xmm._data, xm._data)
+        assert_equal(xmm._mask, xm._mask)
+        assert_equal(xmm.fill_value, xm.fill_value)
+        assert_equal(xmm._hardmask, xm._hardmask)
+
+    def test_asarray_default_order(self):
+        # See Issue #6646
+        m = np.eye(3).T
+        self.assertFalse(m.flags.c_contiguous)
+
+        new_m = asarray(m)
+        self.assertTrue(new_m.flags.c_contiguous)
+
+    def test_asarray_enforce_order(self):
+        # See Issue #6646
+        m = np.eye(3).T
+        self.assertFalse(m.flags.c_contiguous)
+
+        new_m = asarray(m, order='C')
+        self.assertTrue(new_m.flags.c_contiguous)
+
+    def test_fix_invalid(self):
+        # Checks fix_invalid.
+        with np.errstate(invalid='ignore'):
+            data = masked_array([np.nan, 0., 1.], mask=[0, 0, 1])
+            data_fixed = fix_invalid(data)
+            assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
+            assert_equal(data_fixed._mask, [1., 0., 1.])
+
+    def test_maskedelement(self):
+        # Test of masked element
+        x = arange(6)
+        x[1] = masked
+        self.assertTrue(str(masked) == '--')
+        self.assertTrue(x[1] is masked)
+        assert_equal(filled(x[1], 0), 0)
+
+    def test_set_element_as_object(self):
+        # Tests setting elements with object
+        a = empty(1, dtype=object)
+        x = (1, 2, 3, 4, 5)
+        a[0] = x
+        assert_equal(a[0], x)
+        self.assertTrue(a[0] is x)
+
+        import datetime
+        dt = datetime.datetime.now()
+        a[0] = dt
+        self.assertTrue(a[0] is dt)
+
+    def test_indexing(self):
+        # Tests conversions and indexing
+        x1 = np.array([1, 2, 4, 3])
+        x2 = array(x1, mask=[1, 0, 0, 0])
+        x3 = array(x1, mask=[0, 1, 0, 1])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        assert_equal(np.sort(x1), sort(x2, endwith=False))
+        # tests of indexing
+        assert_(type(x2[1]) is type(x1[1]))
+        assert_(x1[1] == x2[1])
+        assert_(x2[0] is masked)
+        assert_equal(x1[2], x2[2])
+        assert_equal(x1[2:5], x2[2:5])
+        assert_equal(x1[:], x2[:])
+        assert_equal(x1[1:], x3[1:])
+        x1[2] = 9
+        x2[2] = 9
+        assert_equal(x1, x2)
+        x1[1:3] = 99
+        x2[1:3] = 99
+        assert_equal(x1, x2)
+        x2[1] = masked
+        assert_equal(x1, x2)
+        x2[1:3] = masked
+        assert_equal(x1, x2)
+        x2[:] = x1
+        x2[1] = masked
+        assert_(allequal(getmask(x2), array([0, 1, 0, 0])))
+        x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x3), array([0, 1, 1, 0])))
+        x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x4), array([0, 1, 1, 0])))
+        assert_(allequal(x4, array([1, 2, 3, 4])))
+        x1 = np.arange(5) * 1.0
+        x2 = masked_values(x1, 3.0)
+        assert_equal(x1, x2)
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_equal(3.0, x2.fill_value)
+        x1 = array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        s1 = x1[1]
+        s2 = x2[1]
+        assert_equal(type(s2), str)
+        assert_equal(type(s1), str)
+        assert_equal(s1, s2)
+        assert_(x1[1:1].shape == (0,))
+
+    def test_matrix_indexing(self):
+        # Tests conversions and indexing
+        x1 = np.matrix([[1, 2, 3], [4, 3, 2]])
+        x2 = array(x1, mask=[[1, 0, 0], [0, 1, 0]])
+        x3 = array(x1, mask=[[0, 1, 0], [1, 0, 0]])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        # tests of indexing
+        assert_(type(x2[1, 0]) is type(x1[1, 0]))
+        assert_(x1[1, 0] == x2[1, 0])
+        assert_(x2[1, 1] is masked)
+        assert_equal(x1[0, 2], x2[0, 2])
+        assert_equal(x1[0, 1:], x2[0, 1:])
+        assert_equal(x1[:, 2], x2[:, 2])
+        assert_equal(x1[:], x2[:])
+        assert_equal(x1[1:], x3[1:])
+        x1[0, 2] = 9
+        x2[0, 2] = 9
+        assert_equal(x1, x2)
+        x1[0, 1:] = 99
+        x2[0, 1:] = 99
+        assert_equal(x1, x2)
+        x2[0, 1] = masked
+        assert_equal(x1, x2)
+        x2[0, 1:] = masked
+        assert_equal(x1, x2)
+        x2[0, :] = x1[0, :]
+        x2[0, 1] = masked
+        assert_(allequal(getmask(x2), np.array([[0, 1, 0], [0, 1, 0]])))
+        x3[1, :] = masked_array([1, 2, 3], [1, 1, 0])
+        assert_(allequal(getmask(x3)[1], array([1, 1, 0])))
+        assert_(allequal(getmask(x3[1]), array([1, 1, 0])))
+        x4[1, :] = masked_array([1, 2, 3], [1, 1, 0])
+        assert_(allequal(getmask(x4[1]), array([1, 1, 0])))
+        assert_(allequal(x4[1], array([1, 2, 3])))
+        x1 = np.matrix(np.arange(5) * 1.0)
+        x2 = masked_values(x1, 3.0)
+        assert_equal(x1, x2)
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_equal(3.0, x2.fill_value)
+
+    def test_copy(self):
+        # Tests of some subtle points of copying and sizing.
+        n = [0, 0, 1, 0, 0]
+        m = make_mask(n)
+        m2 = make_mask(m)
+        self.assertTrue(m is m2)
+        m3 = make_mask(m, copy=1)
+        self.assertTrue(m is not m3)
+
+        x1 = np.arange(5)
+        y1 = array(x1, mask=m)
+        assert_equal(y1._data.__array_interface__, x1.__array_interface__)
+        self.assertTrue(allequal(x1, y1.data))
+        assert_equal(y1._mask.__array_interface__, m.__array_interface__)
+
+        y1a = array(y1)
+        self.assertTrue(y1a._data.__array_interface__ ==
+                        y1._data.__array_interface__)
+        self.assertTrue(y1a.mask is y1.mask)
+
+        y2 = array(x1, mask=m)
+        self.assertTrue(y2._data.__array_interface__ == x1.__array_interface__)
+        self.assertTrue(y2._mask.__array_interface__ == m.__array_interface__)
+        self.assertTrue(y2[2] is masked)
+        y2[2] = 9
+        self.assertTrue(y2[2] is not masked)
+        self.assertTrue(y2._mask.__array_interface__ != m.__array_interface__)
+        self.assertTrue(allequal(y2.mask, 0))
+
+        y3 = array(x1 * 1.0, mask=m)
+        self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype)
+
+        x4 = arange(4)
+        x4[2] = masked
+        y4 = resize(x4, (8,))
+        assert_equal(concatenate([x4, x4]), y4)
+        assert_equal(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
+        y5 = repeat(x4, (2, 2, 2, 2), axis=0)
+        assert_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
+        y6 = repeat(x4, 2, axis=0)
+        assert_equal(y5, y6)
+        y7 = x4.repeat((2, 2, 2, 2), axis=0)
+        assert_equal(y5, y7)
+        y8 = x4.repeat(2, 0)
+        assert_equal(y5, y8)
+
+        y9 = x4.copy()
+        assert_equal(y9._data, x4._data)
+        assert_equal(y9._mask, x4._mask)
+
+        x = masked_array([1, 2, 3], mask=[0, 1, 0])
+        # Copy is False by default
+        y = masked_array(x)
+        assert_equal(y._data.ctypes.data, x._data.ctypes.data)
+        assert_equal(y._mask.ctypes.data, x._mask.ctypes.data)
+        y = masked_array(x, copy=True)
+        assert_not_equal(y._data.ctypes.data, x._data.ctypes.data)
+        assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data)
+
+    def test_copy_immutable(self):
+        # Tests that the copy method is immutable, GitHub issue #5247
+        a = np.ma.array([1, 2, 3])
+        b = np.ma.array([4, 5, 6])
+        a_copy_method = a.copy
+        b.copy
+        assert_equal(a_copy_method(), [1, 2, 3])
+
+    def test_deepcopy(self):
+        from copy import deepcopy
+        a = array([0, 1, 2], mask=[False, True, False])
+        copied = deepcopy(a)
+        assert_equal(copied.mask, a.mask)
+        assert_not_equal(id(a._mask), id(copied._mask))
+
+        copied[1] = 1
+        assert_equal(copied.mask, [0, 0, 0])
+        assert_equal(a.mask, [0, 1, 0])
+
+        copied = deepcopy(a)
+        assert_equal(copied.mask, a.mask)
+        copied.mask[1] = False
+        assert_equal(copied.mask, [0, 0, 0])
+        assert_equal(a.mask, [0, 1, 0])
+
+    def test_str_repr(self):
+        a = array([0, 1, 2], mask=[False, True, False])
+        assert_equal(str(a), '[0 -- 2]')
+        assert_equal(repr(a), 'masked_array(data = [0 -- 2],\n'
+                              '             mask = [False  True False],\n'
+                              '       fill_value = 999999)\n')
+
+    def test_pickling(self):
+        # Tests pickling
+        a = arange(10)
+        a[::3] = masked
+        a.fill_value = 999
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled._data, a._data)
+        assert_equal(a_pickled.fill_value, 999)
+
+    def test_pickling_subbaseclass(self):
+        # Test pickling w/ a subclass of ndarray
+        a = array(np.matrix(list(range(10))), mask=[1, 0, 1, 0, 0] * 2)
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled, a)
+        self.assertTrue(isinstance(a_pickled._data, np.matrix))
+
+    def test_pickling_maskedconstant(self):
+        # Test pickling MaskedConstant
+        mc = np.ma.masked
+        mc_pickled = pickle.loads(mc.dumps())
+        assert_equal(mc_pickled._baseclass, mc._baseclass)
+        assert_equal(mc_pickled._mask, mc._mask)
+        assert_equal(mc_pickled._data, mc._data)
+
+    def test_pickling_wstructured(self):
+        # Tests pickling w/ structured array
+        a = array([(1, 1.), (2, 2.)], mask=[(0, 0), (0, 1)],
+                  dtype=[('a', int), ('b', float)])
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled, a)
+
+    def test_pickling_keepalignment(self):
+        # Tests pickling w/ F_CONTIGUOUS arrays
+        a = arange(10)
+        a.shape = (-1, 2)
+        b = a.T
+        test = pickle.loads(pickle.dumps(b))
+        assert_equal(test, b)
+
+    def test_single_element_subscript(self):
+        # Tests single element subscripts of Maskedarrays.
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        assert_equal(a[0].shape, ())
+        assert_equal(b[0].shape, ())
+        assert_equal(b[1].shape, ())
+
+    def test_topython(self):
+        # Tests some communication issues with Python.
+        assert_equal(1, int(array(1)))
+        assert_equal(1.0, float(array(1)))
+        assert_equal(1, int(array([[[1]]])))
+        assert_equal(1.0, float(array([[1]])))
+        self.assertRaises(TypeError, float, array([1, 1]))
+
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', UserWarning)
+            assert_(np.isnan(float(array([1], mask=[1]))))
+
+        a = array([1, 2, 3], mask=[1, 0, 0])
+        self.assertRaises(TypeError, lambda:float(a))
+        assert_equal(float(a[-1]), 3.)
+        self.assertTrue(np.isnan(float(a[0])))
+        self.assertRaises(TypeError, int, a)
+        assert_equal(int(a[-1]), 3)
+        self.assertRaises(MAError, lambda:int(a[0]))
+
+    def test_oddfeatures_1(self):
+        # Test of other odd features
+        x = arange(20)
+        x = x.reshape(4, 5)
+        x.flat[5] = 12
+        assert_(x[1, 0] == 12)
+        z = x + 10j * x
+        assert_equal(z.real, x)
+        assert_equal(z.imag, 10 * x)
+        assert_equal((z * conjugate(z)).real, 101 * x * x)
+        z.imag[...] = 0.0
+
+        x = arange(10)
+        x[3] = masked
+        assert_(str(x[3]) == str(masked))
+        c = x >= 8
+        assert_(count(where(c, masked, masked)) == 0)
+        assert_(shape(where(c, masked, masked)) == c.shape)
+
+        z = masked_where(c, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        assert_equal(x, z)
+
+    def test_oddfeatures_2(self):
+        # Tests some more features.
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+    def test_oddfeatures_3(self):
+        # Tests some generic features
+        atest = array([10], mask=True)
+        btest = array([20])
+        idx = atest.mask
+        atest[idx] = btest[idx]
+        assert_equal(atest, [20])
+
+    def test_filled_w_object_dtype(self):
+        a = np.ma.masked_all(1, dtype='O')
+        assert_equal(a.filled('x')[0], 'x')
+
+    def test_filled_w_flexible_dtype(self):
+        # Test filled w/ flexible dtype
+        flexi = array([(1, 1, 1)],
+                      dtype=[('i', int), ('s', '|S8'), ('f', float)])
+        flexi[0] = masked
+        assert_equal(flexi.filled(),
+                     np.array([(default_fill_value(0),
+                                default_fill_value('0'),
+                                default_fill_value(0.),)], dtype=flexi.dtype))
+        flexi[0] = masked
+        assert_equal(flexi.filled(1),
+                     np.array([(1, '1', 1.)], dtype=flexi.dtype))
+
+    def test_filled_w_mvoid(self):
+        # Test filled w/ mvoid
+        ndtype = [('a', int), ('b', float)]
+        a = mvoid((1, 2.), mask=[(0, 1)], dtype=ndtype)
+        # Filled using default
+        test = a.filled()
+        assert_equal(tuple(test), (1, default_fill_value(1.)))
+        # Explicit fill_value
+        test = a.filled((-1, -1))
+        assert_equal(tuple(test), (1, -1))
+        # Using predefined filling values
+        a.fill_value = (-999, -999)
+        assert_equal(tuple(a.filled()), (1, -999))
+
+    def test_filled_w_nested_dtype(self):
+        # Test filled w/ nested dtype
+        ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])]
+        a = array([(1, (1, 1)), (2, (2, 2))],
+                  mask=[(0, (1, 0)), (0, (0, 1))], dtype=ndtype)
+        test = a.filled(0)
+        control = np.array([(1, (0, 1)), (2, (2, 0))], dtype=ndtype)
+        assert_equal(test, control)
+
+        test = a['B'].filled(0)
+        control = np.array([(0, 1), (2, 0)], dtype=a['B'].dtype)
+        assert_equal(test, control)
+
+        # test if mask gets set correctly (see #6760)
+        Z = numpy.ma.zeros(2, numpy.dtype([("A", "(2,2)i1,(2,2)i1", (2,2))]))
+        assert_equal(Z.data.dtype, numpy.dtype([('A', [('f0', 'i1', (2, 2)),
+                                          ('f1', 'i1', (2, 2))], (2, 2))]))
+        assert_equal(Z.mask.dtype, numpy.dtype([('A', [('f0', '?', (2, 2)),
+                                          ('f1', '?', (2, 2))], (2, 2))]))
+
+    def test_filled_w_f_order(self):
+        # Test filled w/ F-contiguous array
+        a = array(np.array([(0, 1, 2), (4, 5, 6)], order='F'),
+                  mask=np.array([(0, 0, 1), (1, 0, 0)], order='F'),
+                  order='F')  # this is currently ignored
+        self.assertTrue(a.flags['F_CONTIGUOUS'])
+        self.assertTrue(a.filled(0).flags['F_CONTIGUOUS'])
+
+    def test_optinfo_propagation(self):
+        # Checks that _optinfo dictionary isn't back-propagated
+        x = array([1, 2, 3, ], dtype=float)
+        x._optinfo['info'] = '???'
+        y = x.copy()
+        assert_equal(y._optinfo['info'], '???')
+        y._optinfo['info'] = '!!!'
+        assert_equal(x._optinfo['info'], '???')
+
+    def test_fancy_printoptions(self):
+        # Test printing a masked array w/ fancy dtype.
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     mask=[(1, (0, 1)), (0, (1, 0))],
+                     dtype=fancydtype)
+        control = "[(--, (2, --)) (4, (--, 6.0))]"
+        assert_equal(str(test), control)
+
+        # Test 0-d array with multi-dimensional dtype
+        t_2d0 = masked_array(data = (0, [[0.0, 0.0, 0.0],
+                                        [0.0, 0.0, 0.0]],
+                                    0.0),
+                             mask = (False, [[True, False, True],
+                                             [False, False, True]],
+                                     False),
+                             dtype = "int, (2,3)float, float")
+        control = "(0, [[--, 0.0, --], [0.0, 0.0, --]], 0.0)"
+        assert_equal(str(t_2d0), control)
+
+
+    def test_flatten_structured_array(self):
+        # Test flatten_structured_array on arrays
+        # On ndarray
+        ndtype = [('a', int), ('b', float)]
+        a = np.array([(1, 1), (2, 2)], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = np.array([[1., 1.], [2., 2.]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        # On masked_array
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = array([[1., 1.], [2., 2.]],
+                        mask=[[0, 1], [1, 0]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test.mask, control.mask)
+        # On masked array with nested structure
+        ndtype = [('a', int), ('b', [('ba', int), ('bb', float)])]
+        a = array([(1, (1, 1.1)), (2, (2, 2.2))],
+                  mask=[(0, (1, 0)), (1, (0, 1))], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = array([[1., 1., 1.1], [2., 2., 2.2]],
+                        mask=[[0, 1, 0], [1, 0, 1]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test.mask, control.mask)
+        # Keeping the initial shape
+        ndtype = [('a', int), ('b', float)]
+        a = np.array([[(1, 1), ], [(2, 2), ]], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = np.array([[[1., 1.], ], [[2., 2.], ]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+
+    def test_void0d(self):
+        # Test creating a mvoid object
+        ndtype = [('a', int), ('b', int)]
+        a = np.array([(1, 2,)], dtype=ndtype)[0]
+        f = mvoid(a)
+        assert_(isinstance(f, mvoid))
+
+        a = masked_array([(1, 2)], mask=[(1, 0)], dtype=ndtype)[0]
+        assert_(isinstance(a, mvoid))
+
+        a = masked_array([(1, 2), (1, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        f = mvoid(a._data[0], a._mask[0])
+        assert_(isinstance(f, mvoid))
+
+    def test_mvoid_getitem(self):
+        # Test mvoid.__getitem__
+        ndtype = [('a', int), ('b', int)]
+        a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
+                         dtype=ndtype)
+        # w/o mask
+        f = a[0]
+        self.assertTrue(isinstance(f, mvoid))
+        assert_equal((f[0], f['a']), (1, 1))
+        assert_equal(f['b'], 2)
+        # w/ mask
+        f = a[1]
+        self.assertTrue(isinstance(f, mvoid))
+        self.assertTrue(f[0] is masked)
+        self.assertTrue(f['a'] is masked)
+        assert_equal(f[1], 4)
+
+        # exotic dtype
+        A = masked_array(data=[([0,1],)],
+                         mask=[([True, False],)],
+                         dtype=[("A", ">i2", (2,))])
+        assert_equal(A[0]["A"], A["A"][0])
+        assert_equal(A[0]["A"], masked_array(data=[0, 1],
+                         mask=[True, False], dtype=">i2"))
+
+    def test_mvoid_iter(self):
+        # Test iteration on __getitem__
+        ndtype = [('a', int), ('b', int)]
+        a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
+                         dtype=ndtype)
+        # w/o mask
+        assert_equal(list(a[0]), [1, 2])
+        # w/ mask
+        assert_equal(list(a[1]), [masked, 4])
+
+    def test_mvoid_print(self):
+        # Test printing a mvoid
+        mx = array([(1, 1), (2, 2)], dtype=[('a', int), ('b', int)])
+        assert_equal(str(mx[0]), "(1, 1)")
+        mx['b'][0] = masked
+        ini_display = masked_print_option._display
+        masked_print_option.set_display("-X-")
+        try:
+            assert_equal(str(mx[0]), "(1, -X-)")
+            assert_equal(repr(mx[0]), "(1, -X-)")
+        finally:
+            masked_print_option.set_display(ini_display)
+
+    def test_mvoid_multidim_print(self):
+
+        # regression test for gh-6019
+        t_ma = masked_array(data = [([1, 2, 3],)],
+                            mask = [([False, True, False],)],
+                            fill_value = ([999999, 999999, 999999],),
+                            dtype = [('a', '<i4', (3,))])
+        assert_(str(t_ma[0]) == "([1, --, 3],)")
+        assert_(repr(t_ma[0]) == "([1, --, 3],)")
+
+        # additonal tests with structured arrays
+
+        t_2d = masked_array(data = [([[1, 2], [3,4]],)],
+                            mask = [([[False, True], [True, False]],)],
+                            dtype = [('a', '<i4', (2,2))])
+        assert_(str(t_2d[0]) == "([[1, --], [--, 4]],)")
+        assert_(repr(t_2d[0]) == "([[1, --], [--, 4]],)")
+
+        t_0d = masked_array(data = [(1,2)],
+                            mask = [(True,False)],
+                            dtype = [('a', '<i4'), ('b', '<i4')])
+        assert_(str(t_0d[0]) == "(--, 2)")
+        assert_(repr(t_0d[0]) == "(--, 2)")
+
+        t_2d = masked_array(data = [([[1, 2], [3,4]], 1)],
+                            mask = [([[False, True], [True, False]], False)],
+                            dtype = [('a', '<i4', (2,2)), ('b', float)])
+        assert_(str(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
+        assert_(repr(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
+
+        t_ne = masked_array(data=[(1, (1, 1))],
+                            mask=[(True, (True, False))],
+                            dtype = [('a', '<i4'), ('b', 'i4,i4')])
+        assert_(str(t_ne[0]) == "(--, (--, 1))")
+        assert_(repr(t_ne[0]) == "(--, (--, 1))")
+
+    def test_object_with_array(self):
+        mx1 = masked_array([1.], mask=[True])
+        mx2 = masked_array([1., 2.])
+        mx = masked_array([mx1, mx2], mask=[False, True])
+        assert_(mx[0] is mx1)
+        assert_(mx[1] is not mx2)
+        assert_(np.all(mx[1].data == mx2.data))
+        assert_(np.all(mx[1].mask))
+        # check that we return a view.
+        mx[1].data[0] = 0.
+        assert_(mx2[0] == 0.)
+
+
+class TestMaskedArrayArithmetic(TestCase):
+    # Base test class for MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
+        self.err_status = np.geterr()
+        np.seterr(divide='ignore', invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.err_status)
+
+    def test_basic_arithmetic(self):
+        # Test of basic arithmetic.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        a2d = array([[1, 2], [0, 4]])
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        assert_equal(a2d * a2d, a2d * a2dm)
+        assert_equal(a2d + a2d, a2d + a2dm)
+        assert_equal(a2d - a2d, a2d - a2dm)
+        for s in [(12,), (4, 3), (2, 6)]:
+            x = x.reshape(s)
+            y = y.reshape(s)
+            xm = xm.reshape(s)
+            ym = ym.reshape(s)
+            xf = xf.reshape(s)
+            assert_equal(-x, -xm)
+            assert_equal(x + y, xm + ym)
+            assert_equal(x - y, xm - ym)
+            assert_equal(x * y, xm * ym)
+            assert_equal(x / y, xm / ym)
+            assert_equal(a10 + y, a10 + ym)
+            assert_equal(a10 - y, a10 - ym)
+            assert_equal(a10 * y, a10 * ym)
+            assert_equal(a10 / y, a10 / ym)
+            assert_equal(x + a10, xm + a10)
+            assert_equal(x - a10, xm - a10)
+            assert_equal(x * a10, xm * a10)
+            assert_equal(x / a10, xm / a10)
+            assert_equal(x ** 2, xm ** 2)
+            assert_equal(abs(x) ** 2.5, abs(xm) ** 2.5)
+            assert_equal(x ** y, xm ** ym)
+            assert_equal(np.add(x, y), add(xm, ym))
+            assert_equal(np.subtract(x, y), subtract(xm, ym))
+            assert_equal(np.multiply(x, y), multiply(xm, ym))
+            assert_equal(np.divide(x, y), divide(xm, ym))
+
+    def test_divide_on_different_shapes(self):
+        x = arange(6, dtype=float)
+        x.shape = (2, 3)
+        y = arange(3, dtype=float)
+
+        z = x / y
+        assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
+        assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
+
+        z = x / y[None,:]
+        assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
+        assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
+
+        y = arange(2, dtype=float)
+        z = x / y[:, None]
+        assert_equal(z, [[-1., -1., -1.], [3., 4., 5.]])
+        assert_equal(z.mask, [[1, 1, 1], [0, 0, 0]])
+
+    def test_mixed_arithmetic(self):
+        # Tests mixed arithmetics.
+        na = np.array([1])
+        ma = array([1])
+        self.assertTrue(isinstance(na + ma, MaskedArray))
+        self.assertTrue(isinstance(ma + na, MaskedArray))
+
+    def test_limits_arithmetic(self):
+        tiny = np.finfo(float).tiny
+        a = array([tiny, 1. / tiny, 0.])
+        assert_equal(getmaskarray(a / 2), [0, 0, 0])
+        assert_equal(getmaskarray(2 / a), [1, 0, 1])
+
+    def test_masked_singleton_arithmetic(self):
+        # Tests some scalar arithmetics on MaskedArrays.
+        # Masked singleton should remain masked no matter what
+        xm = array(0, mask=1)
+        self.assertTrue((1 / array(0)).mask)
+        self.assertTrue((1 + xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue(maximum(xm, xm).mask)
+        self.assertTrue(minimum(xm, xm).mask)
+
+    def test_masked_singleton_equality(self):
+        # Tests (in)equality on masked snigleton
+        a = array([1, 2, 3], mask=[1, 1, 0])
+        assert_((a[0] == 0) is masked)
+        assert_((a[0] != 0) is masked)
+        assert_equal((a[-1] == 0), False)
+        assert_equal((a[-1] != 0), True)
+
+    def test_arithmetic_with_masked_singleton(self):
+        # Checks that there's no collapsing to masked
+        x = masked_array([1, 2])
+        y = x * masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+        y = x[0] * masked
+        assert_(y is masked)
+        y = x + masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+
+    def test_arithmetic_with_masked_singleton_on_1d_singleton(self):
+        # Check that we're not losing the shape of a singleton
+        x = masked_array([1, ])
+        y = x + masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y.mask, [True, ])
+
+    def test_scalar_arithmetic(self):
+        x = array(0, mask=0)
+        assert_equal(x.filled().ctypes.data, x.ctypes.data)
+        # Make sure we don't lose the shape in some circumstances
+        xm = array((0, 0)) / 0.
+        assert_equal(xm.shape, (2,))
+        assert_equal(xm.mask, [1, 1])
+
+    def test_basic_ufuncs(self):
+        # Test various functions such as sin, cos.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.cos(x), cos(xm))
+        assert_equal(np.cosh(x), cosh(xm))
+        assert_equal(np.sin(x), sin(xm))
+        assert_equal(np.sinh(x), sinh(xm))
+        assert_equal(np.tan(x), tan(xm))
+        assert_equal(np.tanh(x), tanh(xm))
+        assert_equal(np.sqrt(abs(x)), sqrt(xm))
+        assert_equal(np.log(abs(x)), log(xm))
+        assert_equal(np.log10(abs(x)), log10(xm))
+        assert_equal(np.exp(x), exp(xm))
+        assert_equal(np.arcsin(z), arcsin(zm))
+        assert_equal(np.arccos(z), arccos(zm))
+        assert_equal(np.arctan(z), arctan(zm))
+        assert_equal(np.arctan2(x, y), arctan2(xm, ym))
+        assert_equal(np.absolute(x), absolute(xm))
+        assert_equal(np.angle(x + 1j*y), angle(xm + 1j*ym))
+        assert_equal(np.angle(x + 1j*y, deg=True), angle(xm + 1j*ym, deg=True))
+        assert_equal(np.equal(x, y), equal(xm, ym))
+        assert_equal(np.not_equal(x, y), not_equal(xm, ym))
+        assert_equal(np.less(x, y), less(xm, ym))
+        assert_equal(np.greater(x, y), greater(xm, ym))
+        assert_equal(np.less_equal(x, y), less_equal(xm, ym))
+        assert_equal(np.greater_equal(x, y), greater_equal(xm, ym))
+        assert_equal(np.conjugate(x), conjugate(xm))
+
+    def test_count_func(self):
+        # Tests count
+        assert_equal(1, count(1))
+        assert_equal(0, array(1, mask=[1]))
+
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        res = count(ott)
+        self.assertTrue(res.dtype.type is np.intp)
+        assert_equal(3, res)
+
+        ott = ott.reshape((2, 2))
+        res = count(ott)
+        assert_(res.dtype.type is np.intp)
+        assert_equal(3, res)
+        res = count(ott, 0)
+        assert_(isinstance(res, ndarray))
+        assert_equal([1, 2], res)
+        assert_(getmask(res) is nomask)
+
+        ott = array([0., 1., 2., 3.])
+        res = count(ott, 0)
+        assert_(isinstance(res, ndarray))
+        assert_(res.dtype.type is np.intp)
+
+        assert_raises(IndexError, ott.count, 1)
+
+    def test_minmax_func(self):
+        # Tests minimum and maximum.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # max doesn't work if shaped
+        xr = np.ravel(x)
+        xmr = ravel(xm)
+        # following are true because of careful selection of data
+        assert_equal(max(xr), maximum(xmr))
+        assert_equal(min(xr), minimum(xmr))
+
+        assert_equal(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3])
+        assert_equal(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9])
+        x = arange(5)
+        y = arange(5) - 2
+        x[3] = masked
+        y[0] = masked
+        assert_equal(minimum(x, y), where(less(x, y), x, y))
+        assert_equal(maximum(x, y), where(greater(x, y), x, y))
+        assert_(minimum(x) == 0)
+        assert_(maximum(x) == 4)
+
+        x = arange(4).reshape(2, 2)
+        x[-1, -1] = masked
+        assert_equal(maximum(x), 2)
+
+    def test_minimummaximum_func(self):
+        a = np.ones((2, 2))
+        aminimum = minimum(a, a)
+        self.assertTrue(isinstance(aminimum, MaskedArray))
+        assert_equal(aminimum, np.minimum(a, a))
+
+        aminimum = minimum.outer(a, a)
+        self.assertTrue(isinstance(aminimum, MaskedArray))
+        assert_equal(aminimum, np.minimum.outer(a, a))
+
+        amaximum = maximum(a, a)
+        self.assertTrue(isinstance(amaximum, MaskedArray))
+        assert_equal(amaximum, np.maximum(a, a))
+
+        amaximum = maximum.outer(a, a)
+        self.assertTrue(isinstance(amaximum, MaskedArray))
+        assert_equal(amaximum, np.maximum.outer(a, a))
+
+    def test_minmax_reduce(self):
+        # Test np.min/maximum.reduce on array w/ full False mask
+        a = array([1, 2, 3], mask=[False, False, False])
+        b = np.maximum.reduce(a)
+        assert_equal(b, 3)
+
+    def test_minmax_funcs_with_output(self):
+        # Tests the min/max functions with explicit outputs
+        mask = np.random.rand(12).round()
+        xm = array(np.random.uniform(0, 10, 12), mask=mask)
+        xm.shape = (3, 4)
+        for funcname in ('min', 'max'):
+            # Initialize
+            npfunc = getattr(np, funcname)
+            mafunc = getattr(numpy.ma.core, funcname)
+            # Use the np version
+            nout = np.empty((4,), dtype=int)
+            try:
+                result = npfunc(xm, axis=0, out=nout)
+            except MaskError:
+                pass
+            nout = np.empty((4,), dtype=float)
+            result = npfunc(xm, axis=0, out=nout)
+            self.assertTrue(result is nout)
+            # Use the ma version
+            nout.fill(-999)
+            result = mafunc(xm, axis=0, out=nout)
+            self.assertTrue(result is nout)
+
+    def test_minmax_methods(self):
+        # Additional tests on max/min
+        (_, _, _, _, _, xm, _, _, _, _) = self.d
+        xm.shape = (xm.size,)
+        assert_equal(xm.max(), 10)
+        self.assertTrue(xm[0].max() is masked)
+        self.assertTrue(xm[0].max(0) is masked)
+        self.assertTrue(xm[0].max(-1) is masked)
+        assert_equal(xm.min(), -10.)
+        self.assertTrue(xm[0].min() is masked)
+        self.assertTrue(xm[0].min(0) is masked)
+        self.assertTrue(xm[0].min(-1) is masked)
+        assert_equal(xm.ptp(), 20.)
+        self.assertTrue(xm[0].ptp() is masked)
+        self.assertTrue(xm[0].ptp(0) is masked)
+        self.assertTrue(xm[0].ptp(-1) is masked)
+
+        x = array([1, 2, 3], mask=True)
+        self.assertTrue(x.min() is masked)
+        self.assertTrue(x.max() is masked)
+        self.assertTrue(x.ptp() is masked)
+
+    def test_addsumprod(self):
+        # Tests add, sum, product.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.add.reduce(x), add.reduce(x))
+        assert_equal(np.add.accumulate(x), add.accumulate(x))
+        assert_equal(4, sum(array(4), axis=0))
+        assert_equal(4, sum(array(4), axis=0))
+        assert_equal(np.sum(x, axis=0), sum(x, axis=0))
+        assert_equal(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0))
+        assert_equal(np.sum(x, 0), sum(x, 0))
+        assert_equal(np.product(x, axis=0), product(x, axis=0))
+        assert_equal(np.product(x, 0), product(x, 0))
+        assert_equal(np.product(filled(xm, 1), axis=0), product(xm, axis=0))
+        s = (3, 4)
+        x.shape = y.shape = xm.shape = ym.shape = s
+        if len(s) > 1:
+            assert_equal(np.concatenate((x, y), 1), concatenate((xm, ym), 1))
+            assert_equal(np.add.reduce(x, 1), add.reduce(x, 1))
+            assert_equal(np.sum(x, 1), sum(x, 1))
+            assert_equal(np.product(x, 1), product(x, 1))
+
+    def test_binops_d2D(self):
+        # Test binary operations on 2D data
+        a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]])
+
+        test = a * b
+        control = array([[2., 3.], [2., 2.], [3., 3.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b * a
+        control = array([[2., 3.], [4., 5.], [6., 7.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        a = array([[1.], [2.], [3.]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]],
+                  mask=[[0, 0], [0, 0], [0, 1]])
+        test = a * b
+        control = array([[2, 3], [8, 10], [18, 3]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b * a
+        control = array([[2, 3], [8, 10], [18, 7]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_domained_binops_d2D(self):
+        # Test domained binary operations on 2D data
+        a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]])
+
+        test = a / b
+        control = array([[1. / 2., 1. / 3.], [2., 2.], [3., 3.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b / a
+        control = array([[2. / 1., 3. / 1.], [4., 5.], [6., 7.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        a = array([[1.], [2.], [3.]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]],
+                  mask=[[0, 0], [0, 0], [0, 1]])
+        test = a / b
+        control = array([[1. / 2, 1. / 3], [2. / 4, 2. / 5], [3. / 6, 3]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b / a
+        control = array([[2 / 1., 3 / 1.], [4 / 2., 5 / 2.], [6 / 3., 7]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_noshrinking(self):
+        # Check that we don't shrink a mask when not wanted
+        # Binary operations
+        a = masked_array([1., 2., 3.], mask=[False, False, False],
+                         shrink=False)
+        b = a + 1
+        assert_equal(b.mask, [0, 0, 0])
+        # In place binary operation
+        a += 1
+        assert_equal(a.mask, [0, 0, 0])
+        # Domained binary operation
+        b = a / 1.
+        assert_equal(b.mask, [0, 0, 0])
+        # In place binary operation
+        a /= 1.
+        assert_equal(a.mask, [0, 0, 0])
+
+    def test_noshink_on_creation(self):
+        # Check that the mask is not shrunk on array creation when not wanted
+        a = np.ma.masked_values([1., 2.5, 3.1], 1.5, shrink=False)
+        assert_equal(a.mask, [0, 0, 0])
+
+    def test_mod(self):
+        # Tests mod
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(mod(x, y), mod(xm, ym))
+        test = mod(ym, xm)
+        assert_equal(test, np.mod(ym, xm))
+        assert_equal(test.mask, mask_or(xm.mask, ym.mask))
+        test = mod(xm, ym)
+        assert_equal(test, np.mod(xm, ym))
+        assert_equal(test.mask, mask_or(mask_or(xm.mask, ym.mask), (ym == 0)))
+
+    def test_TakeTransposeInnerOuter(self):
+        # Test of take, transpose, inner, outer products
+        x = arange(24)
+        y = np.arange(24)
+        x[5:6] = masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert_equal(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1)))
+        assert_equal(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1))
+        assert_equal(np.inner(filled(x, 0), filled(y, 0)),
+                     inner(x, y))
+        assert_equal(np.outer(filled(x, 0), filled(y, 0)),
+                     outer(x, y))
+        y = array(['abc', 1, 'def', 2, 3], object)
+        y[2] = masked
+        t = take(y, [0, 3, 4])
+        assert_(t[0] == 'abc')
+        assert_(t[1] == 2)
+        assert_(t[2] == 3)
+
+    def test_imag_real(self):
+        # Check complex
+        xx = array([1 + 10j, 20 + 2j], mask=[1, 0])
+        assert_equal(xx.imag, [10, 2])
+        assert_equal(xx.imag.filled(), [1e+20, 2])
+        assert_equal(xx.imag.dtype, xx._data.imag.dtype)
+        assert_equal(xx.real, [1, 20])
+        assert_equal(xx.real.filled(), [1e+20, 20])
+        assert_equal(xx.real.dtype, xx._data.real.dtype)
+
+    def test_methods_with_output(self):
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        funclist = ('sum', 'prod', 'var', 'std', 'max', 'min', 'ptp', 'mean',)
+
+        for funcname in funclist:
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+            # A ndarray as explicit input
+            output = np.empty(4, dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0, out=output)
+            # ... the result should be the given output
+            assert_(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+
+            output = empty(4, dtype=int)
+            result = xmmeth(axis=0, out=output)
+            assert_(result is output)
+            assert_(output[0] is masked)
+
+    def test_eq_on_structured(self):
+        # Test the equality of structured arrays
+        ndtype = [('A', int), ('B', int)]
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
+        test = (a == a)
+        assert_equal(test, [True, True])
+        assert_equal(test.mask, [False, False])
+        b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        test = (a == b)
+        assert_equal(test, [False, True])
+        assert_equal(test.mask, [True, False])
+        b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = (a == b)
+        assert_equal(test, [True, False])
+        assert_equal(test.mask, [False, False])
+
+    def test_ne_on_structured(self):
+        # Test the equality of structured arrays
+        ndtype = [('A', int), ('B', int)]
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
+        test = (a != a)
+        assert_equal(test, [False, False])
+        assert_equal(test.mask, [False, False])
+        b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        test = (a != b)
+        assert_equal(test, [True, False])
+        assert_equal(test.mask, [True, False])
+        b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = (a != b)
+        assert_equal(test, [False, True])
+        assert_equal(test.mask, [False, False])
+
+    def test_eq_w_None(self):
+        # Really, comparisons with None should not be done, but check them
+        # anyway. Note that pep8 will flag these tests.
+
+        # With partial mask
+        a = array([1, 2], mask=[0, 1])
+        assert_equal(a == None, False)
+        assert_equal(a.data == None, False)
+        assert_equal(a.mask == None, False)
+        assert_equal(a != None, True)
+        # With nomask
+        a = array([1, 2], mask=False)
+        assert_equal(a == None, False)
+        assert_equal(a != None, True)
+        # With complete mask
+        a = array([1, 2], mask=True)
+        assert_equal(a == None, False)
+        assert_equal(a != None, True)
+        # Fully masked, even comparison to None should return "masked"
+        a = masked
+        assert_equal(a == None, masked)
+
+    def test_eq_w_scalar(self):
+        a = array(1)
+        assert_equal(a == 1, True)
+        assert_equal(a == 0, False)
+        assert_equal(a != 1, False)
+        assert_equal(a != 0, True)
+
+    def test_numpyarithmetics(self):
+        # Check that the mask is not back-propagated when using numpy functions
+        a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
+        control = masked_array([np.nan, np.nan, 0, np.log(2), -1],
+                               mask=[1, 1, 0, 0, 1])
+
+        test = log(a)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(a.mask, [0, 0, 0, 0, 1])
+
+        test = np.log(a)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(a.mask, [0, 0, 0, 0, 1])
+
+
+class TestMaskedArrayAttributes(TestCase):
+
+    def test_keepmask(self):
+        # Tests the keep mask flag
+        x = masked_array([1, 2, 3], mask=[1, 0, 0])
+        mx = masked_array(x)
+        assert_equal(mx.mask, x.mask)
+        mx = masked_array(x, mask=[0, 1, 0], keep_mask=False)
+        assert_equal(mx.mask, [0, 1, 0])
+        mx = masked_array(x, mask=[0, 1, 0], keep_mask=True)
+        assert_equal(mx.mask, [1, 1, 0])
+        # We default to true
+        mx = masked_array(x, mask=[0, 1, 0])
+        assert_equal(mx.mask, [1, 1, 0])
+
+    def test_hardmask(self):
+        # Test hard_mask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d, mask=m, hard_mask=True)
+        # We need to copy, to avoid updating d in xh !
+        xs = array(d, mask=m, hard_mask=False, copy=True)
+        xh[[1, 4]] = [10, 40]
+        xs[[1, 4]] = [10, 40]
+        assert_equal(xh._data, [0, 10, 2, 3, 4])
+        assert_equal(xs._data, [0, 10, 2, 3, 40])
+        assert_equal(xs.mask, [0, 0, 0, 1, 0])
+        self.assertTrue(xh._hardmask)
+        self.assertTrue(not xs._hardmask)
+        xh[1:4] = [10, 20, 30]
+        xs[1:4] = [10, 20, 30]
+        assert_equal(xh._data, [0, 10, 20, 3, 4])
+        assert_equal(xs._data, [0, 10, 20, 30, 40])
+        assert_equal(xs.mask, nomask)
+        xh[0] = masked
+        xs[0] = masked
+        assert_equal(xh.mask, [1, 0, 0, 1, 1])
+        assert_equal(xs.mask, [1, 0, 0, 0, 0])
+        xh[:] = 1
+        xs[:] = 1
+        assert_equal(xh._data, [0, 1, 1, 3, 4])
+        assert_equal(xs._data, [1, 1, 1, 1, 1])
+        assert_equal(xh.mask, [1, 0, 0, 1, 1])
+        assert_equal(xs.mask, nomask)
+        # Switch to soft mask
+        xh.soften_mask()
+        xh[:] = arange(5)
+        assert_equal(xh._data, [0, 1, 2, 3, 4])
+        assert_equal(xh.mask, nomask)
+        # Switch back to hard mask
+        xh.harden_mask()
+        xh[xh < 3] = masked
+        assert_equal(xh._data, [0, 1, 2, 3, 4])
+        assert_equal(xh._mask, [1, 1, 1, 0, 0])
+        xh[filled(xh > 1, False)] = 5
+        assert_equal(xh._data, [0, 1, 2, 5, 5])
+        assert_equal(xh._mask, [1, 1, 1, 0, 0])
+
+        xh = array([[1, 2], [3, 4]], mask=[[1, 0], [0, 0]], hard_mask=True)
+        xh[0] = 0
+        assert_equal(xh._data, [[1, 0], [3, 4]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+        xh[-1, -1] = 5
+        assert_equal(xh._data, [[1, 0], [3, 5]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+        xh[filled(xh < 5, False)] = 2
+        assert_equal(xh._data, [[1, 2], [2, 5]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+
+    def test_hardmask_again(self):
+        # Another test of hardmask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d, mask=m, hard_mask=True)
+        xh[4:5] = 999
+        xh[0:1] = 999
+        assert_equal(xh._data, [999, 1, 2, 3, 4])
+
+    def test_hardmask_oncemore_yay(self):
+        # OK, yet another test of hardmask
+        # Make sure that harden_mask/soften_mask//unshare_mask returns self
+        a = array([1, 2, 3], mask=[1, 0, 0])
+        b = a.harden_mask()
+        assert_equal(a, b)
+        b[0] = 0
+        assert_equal(a, b)
+        assert_equal(b, array([1, 2, 3], mask=[1, 0, 0]))
+        a = b.soften_mask()
+        a[0] = 0
+        assert_equal(a, b)
+        assert_equal(b, array([0, 2, 3], mask=[0, 0, 0]))
+
+    def test_smallmask(self):
+        # Checks the behaviour of _smallmask
+        a = arange(10)
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, nomask)
+        a = arange(10)
+        a._smallmask = False
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, zeros(10))
+
+    def test_shrink_mask(self):
+        # Tests .shrink_mask()
+        a = array([1, 2, 3], mask=[0, 0, 0])
+        b = a.shrink_mask()
+        assert_equal(a, b)
+        assert_equal(a.mask, nomask)
+
+    def test_flat(self):
+        # Test that flat can return all types of items [#4585, #4615]
+        # test simple access
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        assert_equal(test.flat[1], 2)
+        assert_equal(test.flat[2], masked)
+        self.assertTrue(np.all(test.flat[0:2] == test[0, 0:2]))
+        # Test flat on masked_matrices
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        test.flat = masked_array([3, 2, 1], mask=[1, 0, 0])
+        control = masked_array(np.matrix([[3, 2, 1]]), mask=[1, 0, 0])
+        assert_equal(test, control)
+        # Test setting
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        testflat = test.flat
+        testflat[:] = testflat[[2, 1, 0]]
+        assert_equal(test, control)
+        testflat[0] = 9
+        assert_equal(test[0, 0], 9)
+        # test 2-D record array
+        # ... on structured array w/ masked records
+        x = array([[(1, 1.1, 'one'), (2, 2.2, 'two'), (3, 3.3, 'thr')],
+                   [(4, 4.4, 'fou'), (5, 5.5, 'fiv'), (6, 6.6, 'six')]],
+                  dtype=[('a', int), ('b', float), ('c', '|S8')])
+        x['a'][0, 1] = masked
+        x['b'][1, 0] = masked
+        x['c'][0, 2] = masked
+        x[-1, -1] = masked
+        xflat = x.flat
+        assert_equal(xflat[0], x[0, 0])
+        assert_equal(xflat[1], x[0, 1])
+        assert_equal(xflat[2], x[0, 2])
+        assert_equal(xflat[:3], x[0])
+        assert_equal(xflat[3], x[1, 0])
+        assert_equal(xflat[4], x[1, 1])
+        assert_equal(xflat[5], x[1, 2])
+        assert_equal(xflat[3:], x[1])
+        assert_equal(xflat[-1], x[-1, -1])
+        i = 0
+        j = 0
+        for xf in xflat:
+            assert_equal(xf, x[j, i])
+            i += 1
+            if i >= x.shape[-1]:
+                i = 0
+                j += 1
+        # test that matrices keep the correct shape (#4615)
+        a = masked_array(np.matrix(np.eye(2)), mask=0)
+        b = a.flat
+        b01 = b[:2]
+        assert_equal(b01.data, array([[1., 0.]]))
+        assert_equal(b01.mask, array([[False, False]]))
+
+    def test_assign_dtype(self):
+        # check that the mask's dtype is updated when dtype is changed
+        a = np.zeros(4, dtype='f4,i4')
+
+        m = np.ma.array(a)
+        m.dtype = np.dtype('f4')
+        repr(m)  # raises?
+        assert_equal(m.dtype, np.dtype('f4'))
+
+        # check that dtype changes that change shape of mask too much
+        # are not allowed
+        def assign():
+            m = np.ma.array(a)
+            m.dtype = np.dtype('f8')
+        assert_raises(ValueError, assign)
+
+        b = a.view(dtype='f4', type=np.ma.MaskedArray)  # raises?
+        assert_equal(b.dtype, np.dtype('f4'))
+
+        # check that nomask is preserved
+        a = np.zeros(4, dtype='f4')
+        m = np.ma.array(a)
+        m.dtype = np.dtype('f4,i4')
+        assert_equal(m.dtype, np.dtype('f4,i4'))
+        assert_equal(m._mask, np.ma.nomask)
+
+
+class TestFillingValues(TestCase):
+
+    def test_check_on_scalar(self):
+        # Test _check_fill_value set to valid and invalid values
+        _check_fill_value = np.ma.core._check_fill_value
+
+        fval = _check_fill_value(0, int)
+        assert_equal(fval, 0)
+        fval = _check_fill_value(None, int)
+        assert_equal(fval, default_fill_value(0))
+
+        fval = _check_fill_value(0, "|S3")
+        assert_equal(fval, asbytes("0"))
+        fval = _check_fill_value(None, "|S3")
+        assert_equal(fval, default_fill_value(b"camelot!"))
+        self.assertRaises(TypeError, _check_fill_value, 1e+20, int)
+        self.assertRaises(TypeError, _check_fill_value, 'stuff', int)
+
+    def test_check_on_fields(self):
+        # Tests _check_fill_value with records
+        _check_fill_value = np.ma.core._check_fill_value
+        ndtype = [('a', int), ('b', float), ('c', "|S3")]
+        # A check on a list should return a single record
+        fval = _check_fill_value([-999, -12345678.9, "???"], ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        # A check on None should output the defaults
+        fval = _check_fill_value(None, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [default_fill_value(0),
+                                   default_fill_value(0.),
+                                   asbytes(default_fill_value("0"))])
+        #.....Using a structured type as fill_value should work
+        fill_val = np.array((-999, -12345678.9, "???"), dtype=ndtype)
+        fval = _check_fill_value(fill_val, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+
+        #.....Using a flexible type w/ a different type shouldn't matter
+        # BEHAVIOR in 1.5 and earlier: match structured types by position
+        #fill_val = np.array((-999, -12345678.9, "???"),
+        #                    dtype=[("A", int), ("B", float), ("C", "|S3")])
+        # BEHAVIOR in 1.6 and later: match structured types by name
+        fill_val = np.array(("???", -999, -12345678.9),
+                            dtype=[("c", "|S3"), ("a", int), ("b", float), ])
+        fval = _check_fill_value(fill_val, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+
+        #.....Using an object-array shouldn't matter either
+        fill_val = np.ndarray(shape=(1,), dtype=object)
+        fill_val[0] = (-999, -12345678.9, asbytes("???"))
+        fval = _check_fill_value(fill_val, object)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        # NOTE: This test was never run properly as "fill_value" rather than
+        # "fill_val" was assigned.  Written properly, it fails.
+        #fill_val = np.array((-999, -12345678.9, "???"))
+        #fval = _check_fill_value(fill_val, ndtype)
+        #self.assertTrue(isinstance(fval, ndarray))
+        #assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        #.....One-field-only flexible type should work as well
+        ndtype = [("a", int)]
+        fval = _check_fill_value(-999999999, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), (-999999999,))
+
+    def test_fillvalue_conversion(self):
+        # Tests the behavior of fill_value during conversion
+        # We had a tailored comment to make sure special attributes are
+        # properly dealt with
+        a = array(asbytes_nested(['3', '4', '5']))
+        a._optinfo.update({'comment':"updated!"})
+
+        b = array(a, dtype=int)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0))
+
+        b = array(a, dtype=float)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0.))
+
+        b = a.astype(int)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0))
+        assert_equal(b._optinfo['comment'], "updated!")
+
+        b = a.astype([('a', '|S3')])
+        assert_equal(b['a']._data, a._data)
+        assert_equal(b['a'].fill_value, a.fill_value)
+
+    def test_fillvalue(self):
+        # Yet more fun with the fill_value
+        data = masked_array([1, 2, 3], fill_value=-999)
+        series = data[[0, 2, 1]]
+        assert_equal(series._fill_value, data._fill_value)
+
+        mtype = [('f', float), ('s', '|S3')]
+        x = array([(1, 'a'), (2, 'b'), (pi, 'pi')], dtype=mtype)
+        x.fill_value = 999
+        assert_equal(x.fill_value.item(), [999., asbytes('999')])
+        assert_equal(x['f'].fill_value, 999)
+        assert_equal(x['s'].fill_value, asbytes('999'))
+
+        x.fill_value = (9, '???')
+        assert_equal(x.fill_value.item(), (9, asbytes('???')))
+        assert_equal(x['f'].fill_value, 9)
+        assert_equal(x['s'].fill_value, asbytes('???'))
+
+        x = array([1, 2, 3.1])
+        x.fill_value = 999
+        assert_equal(np.asarray(x.fill_value).dtype, float)
+        assert_equal(x.fill_value, 999.)
+        assert_equal(x._fill_value, np.array(999.))
+
+    def test_fillvalue_exotic_dtype(self):
+        # Tests yet more exotic flexible dtypes
+        _check_fill_value = np.ma.core._check_fill_value
+        ndtype = [('i', int), ('s', '|S8'), ('f', float)]
+        control = np.array((default_fill_value(0),
+                            default_fill_value('0'),
+                            default_fill_value(0.),),
+                           dtype=ndtype)
+        assert_equal(_check_fill_value(None, ndtype), control)
+        # The shape shouldn't matter
+        ndtype = [('f0', float, (2, 2))]
+        control = np.array((default_fill_value(0.),),
+                           dtype=[('f0', float)]).astype(ndtype)
+        assert_equal(_check_fill_value(None, ndtype), control)
+        control = np.array((0,), dtype=[('f0', float)]).astype(ndtype)
+        assert_equal(_check_fill_value(0, ndtype), control)
+
+        ndtype = np.dtype("int, (2,3)float, float")
+        control = np.array((default_fill_value(0),
+                            default_fill_value(0.),
+                            default_fill_value(0.),),
+                           dtype="int, float, float").astype(ndtype)
+        test = _check_fill_value(None, ndtype)
+        assert_equal(test, control)
+        control = np.array((0, 0, 0), dtype="int, float, float").astype(ndtype)
+        assert_equal(_check_fill_value(0, ndtype), control)
+        # but when indexing, fill value should become scalar not tuple
+        # See issue #6723
+        M = masked_array(control)
+        assert_equal(M["f1"].fill_value.ndim, 0)
+
+    def test_fillvalue_datetime_timedelta(self):
+        # Test default fillvalue for datetime64 and timedelta64 types.
+        # See issue #4476, this would return '?' which would cause errors
+        # elsewhere
+
+        for timecode in ("as", "fs", "ps", "ns", "us", "ms", "s", "m",
+                         "h", "D", "W", "M", "Y"):
+            control = numpy.datetime64("NaT", timecode)
+            test = default_fill_value(numpy.dtype("<M8[" + timecode + "]"))
+            assert_equal(test, control)
+
+            control = numpy.timedelta64("NaT", timecode)
+            test = default_fill_value(numpy.dtype("<m8[" + timecode + "]"))
+            assert_equal(test, control)
+
+    def test_extremum_fill_value(self):
+        # Tests extremum fill values for flexible type.
+        a = array([(1, (2, 3)), (4, (5, 6))],
+                  dtype=[('A', int), ('B', [('BA', int), ('BB', int)])])
+        test = a.fill_value
+        assert_equal(test['A'], default_fill_value(a['A']))
+        assert_equal(test['B']['BA'], default_fill_value(a['B']['BA']))
+        assert_equal(test['B']['BB'], default_fill_value(a['B']['BB']))
+
+        test = minimum_fill_value(a)
+        assert_equal(test[0], minimum_fill_value(a['A']))
+        assert_equal(test[1][0], minimum_fill_value(a['B']['BA']))
+        assert_equal(test[1][1], minimum_fill_value(a['B']['BB']))
+        assert_equal(test[1], minimum_fill_value(a['B']))
+
+        test = maximum_fill_value(a)
+        assert_equal(test[0], maximum_fill_value(a['A']))
+        assert_equal(test[1][0], maximum_fill_value(a['B']['BA']))
+        assert_equal(test[1][1], maximum_fill_value(a['B']['BB']))
+        assert_equal(test[1], maximum_fill_value(a['B']))
+
+    def test_fillvalue_individual_fields(self):
+        # Test setting fill_value on individual fields
+        ndtype = [('a', int), ('b', int)]
+        # Explicit fill_value
+        a = array(list(zip([1, 2, 3], [4, 5, 6])),
+                  fill_value=(-999, -999), dtype=ndtype)
+        aa = a['a']
+        aa.set_fill_value(10)
+        assert_equal(aa._fill_value, np.array(10))
+        assert_equal(tuple(a.fill_value), (10, -999))
+        a.fill_value['b'] = -10
+        assert_equal(tuple(a.fill_value), (10, -10))
+        # Implicit fill_value
+        t = array(list(zip([1, 2, 3], [4, 5, 6])), dtype=ndtype)
+        tt = t['a']
+        tt.set_fill_value(10)
+        assert_equal(tt._fill_value, np.array(10))
+        assert_equal(tuple(t.fill_value), (10, default_fill_value(0)))
+
+    def test_fillvalue_implicit_structured_array(self):
+        # Check that fill_value is always defined for structured arrays
+        ndtype = ('b', float)
+        adtype = ('a', float)
+        a = array([(1.,), (2.,)], mask=[(False,), (False,)],
+                  fill_value=(np.nan,), dtype=np.dtype([adtype]))
+        b = empty(a.shape, dtype=[adtype, ndtype])
+        b['a'] = a['a']
+        b['a'].set_fill_value(a['a'].fill_value)
+        f = b._fill_value[()]
+        assert_(np.isnan(f[0]))
+        assert_equal(f[-1], default_fill_value(1.))
+
+    def test_fillvalue_as_arguments(self):
+        # Test adding a fill_value parameter to empty/ones/zeros
+        a = empty(3, fill_value=999.)
+        assert_equal(a.fill_value, 999.)
+
+        a = ones(3, fill_value=999., dtype=float)
+        assert_equal(a.fill_value, 999.)
+
+        a = zeros(3, fill_value=0., dtype=complex)
+        assert_equal(a.fill_value, 0.)
+
+        a = identity(3, fill_value=0., dtype=complex)
+        assert_equal(a.fill_value, 0.)
+
+    def test_shape_argument(self):
+        # Test that shape can be provides as an argument
+        # GH issue 6106
+        a = empty(shape=(3, ))
+        assert_equal(a.shape, (3, ))
+
+        a = ones(shape=(3, ), dtype=float)
+        assert_equal(a.shape, (3, ))
+
+        a = zeros(shape=(3, ), dtype=complex)
+        assert_equal(a.shape, (3, ))
+
+    def test_fillvalue_in_view(self):
+        # Test the behavior of fill_value in view
+
+        # Create initial masked array
+        x = array([1, 2, 3], fill_value=1, dtype=np.int64)
+
+        # Check that fill_value is preserved by default
+        y = x.view()
+        assert_(y.fill_value == 1)
+
+        # Check that fill_value is preserved if dtype is specified and the
+        # dtype is an ndarray sub-class and has a _fill_value attribute
+        y = x.view(MaskedArray)
+        assert_(y.fill_value == 1)
+
+        # Check that fill_value is preserved if type is specified and the
+        # dtype is an ndarray sub-class and has a _fill_value attribute (by
+        # default, the first argument is dtype, not type)
+        y = x.view(type=MaskedArray)
+        assert_(y.fill_value == 1)
+
+        # Check that code does not crash if passed an ndarray sub-class that
+        # does not have a _fill_value attribute
+        y = x.view(np.ndarray)
+        y = x.view(type=np.ndarray)
+
+        # Check that fill_value can be overriden with view
+        y = x.view(MaskedArray, fill_value=2)
+        assert_(y.fill_value == 2)
+
+        # Check that fill_value can be overriden with view (using type=)
+        y = x.view(type=MaskedArray, fill_value=2)
+        assert_(y.fill_value == 2)
+
+        # Check that fill_value gets reset if passed a dtype but not a
+        # fill_value. This is because even though in some cases one can safely
+        # cast the fill_value, e.g. if taking an int64 view of an int32 array,
+        # in other cases, this cannot be done (e.g. int32 view of an int64
+        # array with a large fill_value).
+        y = x.view(dtype=np.int32)
+        assert_(y.fill_value == 999999)
+
+
+class TestUfuncs(TestCase):
+    # Test class for the application of ufuncs on MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        self.d = (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6),
+                  array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),)
+        self.err_status = np.geterr()
+        np.seterr(divide='ignore', invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.err_status)
+
+    def test_testUfuncRegression(self):
+        # Tests new ufuncs on MaskedArrays.
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+                  'sin', 'cos', 'tan',
+                  'arcsin', 'arccos', 'arctan',
+                  'sinh', 'cosh', 'tanh',
+                  'arcsinh',
+                  'arccosh',
+                  'arctanh',
+                  'absolute', 'fabs', 'negative',
+                  'floor', 'ceil',
+                  'logical_not',
+                  'add', 'subtract', 'multiply',
+                  'divide', 'true_divide', 'floor_divide',
+                  'remainder', 'fmod', 'hypot', 'arctan2',
+                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+                  'less', 'greater',
+                  'logical_and', 'logical_or', 'logical_xor',
+                  ]:
+            try:
+                uf = getattr(umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(numpy.ma.core, f)
+            args = self.d[:uf.nin]
+            ur = uf(*args)
+            mr = mf(*args)
+            assert_equal(ur.filled(0), mr.filled(0), f)
+            assert_mask_equal(ur.mask, mr.mask, err_msg=f)
+
+    def test_reduce(self):
+        # Tests reduce on MaskedArrays.
+        a = self.d[0]
+        self.assertTrue(not alltrue(a, axis=0))
+        self.assertTrue(sometrue(a, axis=0))
+        assert_equal(sum(a[:3], axis=0), 0)
+        assert_equal(product(a, axis=0), 0)
+        assert_equal(add.reduce(a), pi)
+
+    def test_minmax(self):
+        # Tests extrema on MaskedArrays.
+        a = arange(1, 13).reshape(3, 4)
+        amask = masked_where(a < 5, a)
+        assert_equal(amask.max(), a.max())
+        assert_equal(amask.min(), 5)
+        assert_equal(amask.max(0), a.max(0))
+        assert_equal(amask.min(0), [5, 6, 7, 8])
+        self.assertTrue(amask.max(1)[0].mask)
+        self.assertTrue(amask.min(1)[0].mask)
+
+    def test_ndarray_mask(self):
+        # Check that the mask of the result is a ndarray (not a MaskedArray...)
+        a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
+        test = np.sqrt(a)
+        control = masked_array([-1, 0, 1, np.sqrt(2), -1],
+                               mask=[1, 0, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        self.assertTrue(not isinstance(test.mask, MaskedArray))
+
+    def test_treatment_of_NotImplemented(self):
+        # Check that NotImplemented is returned at appropriate places
+
+        a = masked_array([1., 2.], mask=[1, 0])
+        self.assertRaises(TypeError, operator.mul, a, "abc")
+        self.assertRaises(TypeError, operator.truediv, a, "abc")
+
+        class MyClass(object):
+            __array_priority__ = a.__array_priority__ + 1
+
+            def __mul__(self, other):
+                return "My mul"
+
+            def __rmul__(self, other):
+                return "My rmul"
+
+        me = MyClass()
+        assert_(me * a == "My mul")
+        assert_(a * me == "My rmul")
+
+        # and that __array_priority__ is respected
+        class MyClass2(object):
+            __array_priority__ = 100
+
+            def __mul__(self, other):
+                return "Me2mul"
+
+            def __rmul__(self, other):
+                return "Me2rmul"
+
+            def __rdiv__(self, other):
+                return "Me2rdiv"
+
+            __rtruediv__ = __rdiv__
+
+        me_too = MyClass2()
+        assert_(a.__mul__(me_too) is NotImplemented)
+        assert_(all(multiply.outer(a, me_too) == "Me2rmul"))
+        assert_(a.__truediv__(me_too) is NotImplemented)
+        assert_(me_too * a == "Me2mul")
+        assert_(a * me_too == "Me2rmul")
+        assert_(a / me_too == "Me2rdiv")
+
+
+class TestMaskedArrayInPlaceArithmetics(TestCase):
+    # Test MaskedArray Arithmetics
+
+    def setUp(self):
+        x = arange(10)
+        y = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        self.intdata = (x, y, xm)
+        self.floatdata = (x.astype(float), y.astype(float), xm.astype(float))
+        self.othertypes = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        self.othertypes = [np.dtype(_).type for _ in self.othertypes]
+        self.uint8data = (
+            x.astype(np.uint8),
+            y.astype(np.uint8),
+            xm.astype(np.uint8)
+        )
+
+    def test_inplace_addition_scalar(self):
+        # Test of inplace additions
+        (x, y, xm) = self.intdata
+        xm[2] = masked
+        x += 1
+        assert_equal(x, y + 1)
+        xm += 1
+        assert_equal(xm, y + 1)
+
+        (x, _, xm) = self.floatdata
+        id1 = x.data.ctypes._data
+        x += 1.
+        assert_(id1 == x.data.ctypes._data)
+        assert_equal(x, y + 1.)
+
+    def test_inplace_addition_array(self):
+        # Test of inplace additions
+        (x, y, xm) = self.intdata
+        m = xm.mask
+        a = arange(10, dtype=np.int16)
+        a[-1] = masked
+        x += a
+        xm += a
+        assert_equal(x, y + a)
+        assert_equal(xm, y + a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_subtraction_scalar(self):
+        # Test of inplace subtractions
+        (x, y, xm) = self.intdata
+        x -= 1
+        assert_equal(x, y - 1)
+        xm -= 1
+        assert_equal(xm, y - 1)
+
+    def test_inplace_subtraction_array(self):
+        # Test of inplace subtractions
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x -= a
+        xm -= a
+        assert_equal(x, y - a)
+        assert_equal(xm, y - a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_multiplication_scalar(self):
+        # Test of inplace multiplication
+        (x, y, xm) = self.floatdata
+        x *= 2.0
+        assert_equal(x, y * 2)
+        xm *= 2.0
+        assert_equal(xm, y * 2)
+
+    def test_inplace_multiplication_array(self):
+        # Test of inplace multiplication
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x *= a
+        xm *= a
+        assert_equal(x, y * a)
+        assert_equal(xm, y * a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_division_scalar_int(self):
+        # Test of inplace division
+        (x, y, xm) = self.intdata
+        x = arange(10) * 2
+        xm = arange(10) * 2
+        xm[2] = masked
+        x //= 2
+        assert_equal(x, y)
+        xm //= 2
+        assert_equal(xm, y)
+
+    def test_inplace_division_scalar_float(self):
+        # Test of inplace division
+        (x, y, xm) = self.floatdata
+        x /= 2.0
+        assert_equal(x, y / 2.0)
+        xm /= arange(10)
+        assert_equal(xm, ones((10,)))
+
+    def test_inplace_division_array_float(self):
+        # Test of inplace division
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x /= a
+        xm /= a
+        assert_equal(x, y / a)
+        assert_equal(xm, y / a)
+        assert_equal(xm.mask, mask_or(mask_or(m, a.mask), (a == 0)))
+
+    def test_inplace_division_misc(self):
+
+        x = [1., 1., 1., -2., pi / 2., 4., 5., -10., 10., 1., 2., 3.]
+        y = [5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+
+        z = xm / ym
+        assert_equal(z._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
+        assert_equal(z._data,
+                     [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
+
+        xm = xm.copy()
+        xm /= ym
+        assert_equal(xm._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
+        assert_equal(z._data,
+                     [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
+
+    def test_datafriendly_add(self):
+        # Test keeping data w/ (inplace) addition
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        # Test add w/ scalar
+        xx = x + 1
+        assert_equal(xx.data, [2, 3, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test iadd w/ scalar
+        x += 1
+        assert_equal(x.data, [2, 3, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test add w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x + array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 4, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test iadd w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x += array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 4, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_sub(self):
+        # Test keeping data w/ (inplace) subtraction
+        # Test sub w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x - 1
+        assert_equal(xx.data, [0, 1, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test isub w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x -= 1
+        assert_equal(x.data, [0, 1, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test sub w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x - array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 0, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test isub w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x -= array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 0, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_mul(self):
+        # Test keeping data w/ (inplace) multiplication
+        # Test mul w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x * 2
+        assert_equal(xx.data, [2, 4, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test imul w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x *= 2
+        assert_equal(x.data, [2, 4, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test mul w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x * array([10, 20, 30], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 40, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test imul w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x *= array([10, 20, 30], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 40, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_div(self):
+        # Test keeping data w/ (inplace) division
+        # Test div on scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x / 2.
+        assert_equal(xx.data, [1 / 2., 2 / 2., 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test idiv on scalar
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        x /= 2.
+        assert_equal(x.data, [1 / 2., 2 / 2., 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test div on array
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        xx = x / array([10., 20., 30.], mask=[1, 0, 0])
+        assert_equal(xx.data, [1., 2. / 20., 3.])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test idiv on array
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        x /= array([10., 20., 30.], mask=[1, 0, 0])
+        assert_equal(x.data, [1., 2 / 20., 3.])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_pow(self):
+        # Test keeping data w/ (inplace) power
+        # Test pow on scalar
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        xx = x ** 2.5
+        assert_equal(xx.data, [1., 2. ** 2.5, 3.])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test ipow on scalar
+        x **= 2.5
+        assert_equal(x.data, [1., 2. ** 2.5, 3])
+        assert_equal(x.mask, [0, 0, 1])
+
+    def test_datafriendly_add_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a += b
+        assert_equal(a, [[2, 2], [4, 4]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a += b
+        assert_equal(a, [[2, 2], [4, 4]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_datafriendly_sub_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a -= b
+        assert_equal(a, [[0, 0], [2, 2]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a -= b
+        assert_equal(a, [[0, 0], [2, 2]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_datafriendly_mul_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a *= b
+        assert_equal(a, [[1, 1], [3, 3]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a *= b
+        assert_equal(a, [[1, 1], [3, 3]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_inplace_addition_scalar_type(self):
+        # Test of inplace additions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                xm[2] = masked
+                x += t(1)
+                assert_equal(x, y + t(1))
+                xm += t(1)
+                assert_equal(xm, y + t(1))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_addition_array_type(self):
+        # Test of inplace additions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x += a
+                xm += a
+                assert_equal(x, y + a)
+                assert_equal(xm, y + a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_subtraction_scalar_type(self):
+        # Test of inplace subtractions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x -= t(1)
+                assert_equal(x, y - t(1))
+                xm -= t(1)
+                assert_equal(xm, y - t(1))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_subtraction_array_type(self):
+        # Test of inplace subtractions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x -= a
+                xm -= a
+                assert_equal(x, y - a)
+                assert_equal(xm, y - a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_multiplication_scalar_type(self):
+        # Test of inplace multiplication
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x *= t(2)
+                assert_equal(x, y * t(2))
+                xm *= t(2)
+                assert_equal(xm, y * t(2))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_multiplication_array_type(self):
+        # Test of inplace multiplication
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x *= a
+                xm *= a
+                assert_equal(x, y * a)
+                assert_equal(xm, y * a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_floor_division_scalar_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x = arange(10, dtype=t) * t(2)
+                xm = arange(10, dtype=t) * t(2)
+                xm[2] = masked
+                x //= t(2)
+                xm //= t(2)
+                assert_equal(x, y)
+                assert_equal(xm, y)
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_floor_division_array_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x //= a
+                xm //= a
+                assert_equal(x, y // a)
+                assert_equal(xm, y // a)
+                assert_equal(
+                    xm.mask,
+                    mask_or(mask_or(m, a.mask), (a == t(0)))
+                )
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_division_scalar_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x = arange(10, dtype=t) * t(2)
+                xm = arange(10, dtype=t) * t(2)
+                xm[2] = masked
+
+                # May get a DeprecationWarning or a TypeError.
+                #
+                # This is a consequence of the fact that this is true divide
+                # and will require casting to float for calculation and
+                # casting back to the original type. This will only be raised
+                # with integers. Whether it is an error or warning is only
+                # dependent on how stringent the casting rules are.
+                #
+                # Will handle the same way.
+                try:
+                    x /= t(2)
+                    assert_equal(x, y)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+                try:
+                    xm /= t(2)
+                    assert_equal(xm, y)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+
+                if issubclass(t, np.integer):
+                    assert_equal(len(w), 2, "Failed on type=%s." % t)
+                else:
+                    assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_division_array_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+
+                # May get a DeprecationWarning or a TypeError.
+                #
+                # This is a consequence of the fact that this is true divide
+                # and will require casting to float for calculation and
+                # casting back to the original type. This will only be raised
+                # with integers. Whether it is an error or warning is only
+                # dependent on how stringent the casting rules are.
+                #
+                # Will handle the same way.
+                try:
+                    x /= a
+                    assert_equal(x, y / a)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+                try:
+                    xm /= a
+                    assert_equal(xm, y / a)
+                    assert_equal(
+                        xm.mask,
+                        mask_or(mask_or(m, a.mask), (a == t(0)))
+                    )
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+
+                if issubclass(t, np.integer):
+                    assert_equal(len(w), 2, "Failed on type=%s." % t)
+                else:
+                    assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_pow_type(self):
+        # Test keeping data w/ (inplace) power
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                # Test pow on scalar
+                x = array([1, 2, 3], mask=[0, 0, 1], dtype=t)
+                xx = x ** t(2)
+                xx_r = array([1, 2 ** 2, 3], mask=[0, 0, 1], dtype=t)
+                assert_equal(xx.data, xx_r.data)
+                assert_equal(xx.mask, xx_r.mask)
+                # Test ipow on scalar
+                x **= t(2)
+                assert_equal(x.data, xx_r.data)
+                assert_equal(x.mask, xx_r.mask)
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+
+class TestMaskedArrayMethods(TestCase):
+    # Test class for miscellaneous MaskedArrays methods.
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_generic_methods(self):
+        # Tests some MaskedArray methods.
+        a = array([1, 3, 2])
+        assert_equal(a.any(), a._data.any())
+        assert_equal(a.all(), a._data.all())
+        assert_equal(a.argmax(), a._data.argmax())
+        assert_equal(a.argmin(), a._data.argmin())
+        assert_equal(a.choose(0, 1, 2, 3, 4), a._data.choose(0, 1, 2, 3, 4))
+        assert_equal(a.compress([1, 0, 1]), a._data.compress([1, 0, 1]))
+        assert_equal(a.conj(), a._data.conj())
+        assert_equal(a.conjugate(), a._data.conjugate())
+
+        m = array([[1, 2], [3, 4]])
+        assert_equal(m.diagonal(), m._data.diagonal())
+        assert_equal(a.sum(), a._data.sum())
+        assert_equal(a.take([1, 2]), a._data.take([1, 2]))
+        assert_equal(m.transpose(), m._data.transpose())
+
+    def test_allclose(self):
+        # Tests allclose on arrays
+        a = np.random.rand(10)
+        b = a + np.random.rand(10) * 1e-8
+        self.assertTrue(allclose(a, b))
+        # Test allclose w/ infs
+        a[0] = np.inf
+        self.assertTrue(not allclose(a, b))
+        b[0] = np.inf
+        self.assertTrue(allclose(a, b))
+        # Test allclose w/ masked
+        a = masked_array(a)
+        a[-1] = masked
+        self.assertTrue(allclose(a, b, masked_equal=True))
+        self.assertTrue(not allclose(a, b, masked_equal=False))
+        # Test comparison w/ scalar
+        a *= 1e-8
+        a[0] = 0
+        self.assertTrue(allclose(a, 0, masked_equal=True))
+
+        # Test that the function works for MIN_INT integer typed arrays
+        a = masked_array([np.iinfo(np.int_).min], dtype=np.int_)
+        self.assertTrue(allclose(a, a))
+
+    def test_allany(self):
+        # Checks the any/all methods/functions.
+        x = np.array([[0.13, 0.26, 0.90],
+                      [0.28, 0.33, 0.63],
+                      [0.31, 0.87, 0.70]])
+        m = np.array([[True, False, False],
+                      [False, False, False],
+                      [True, True, False]], dtype=np.bool_)
+        mx = masked_array(x, mask=m)
+        mxbig = (mx > 0.5)
+        mxsmall = (mx < 0.5)
+
+        self.assertFalse(mxbig.all())
+        self.assertTrue(mxbig.any())
+        assert_equal(mxbig.all(0), [False, False, True])
+        assert_equal(mxbig.all(1), [False, False, True])
+        assert_equal(mxbig.any(0), [False, False, True])
+        assert_equal(mxbig.any(1), [True, True, True])
+
+        self.assertFalse(mxsmall.all())
+        self.assertTrue(mxsmall.any())
+        assert_equal(mxsmall.all(0), [True, True, False])
+        assert_equal(mxsmall.all(1), [False, False, False])
+        assert_equal(mxsmall.any(0), [True, True, False])
+        assert_equal(mxsmall.any(1), [True, True, False])
+
+    def test_allany_onmatrices(self):
+        x = np.array([[0.13, 0.26, 0.90],
+                      [0.28, 0.33, 0.63],
+                      [0.31, 0.87, 0.70]])
+        X = np.matrix(x)
+        m = np.array([[True, False, False],
+                      [False, False, False],
+                      [True, True, False]], dtype=np.bool_)
+        mX = masked_array(X, mask=m)
+        mXbig = (mX > 0.5)
+        mXsmall = (mX < 0.5)
+
+        self.assertFalse(mXbig.all())
+        self.assertTrue(mXbig.any())
+        assert_equal(mXbig.all(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.all(1), np.matrix([False, False, True]).T)
+        assert_equal(mXbig.any(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.any(1), np.matrix([True, True, True]).T)
+
+        self.assertFalse(mXsmall.all())
+        self.assertTrue(mXsmall.any())
+        assert_equal(mXsmall.all(0), np.matrix([True, True, False]))
+        assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T)
+        assert_equal(mXsmall.any(0), np.matrix([True, True, False]))
+        assert_equal(mXsmall.any(1), np.matrix([True, True, False]).T)
+
+    def test_allany_oddities(self):
+        # Some fun with all and any
+        store = empty((), dtype=bool)
+        full = array([1, 2, 3], mask=True)
+
+        self.assertTrue(full.all() is masked)
+        full.all(out=store)
+        self.assertTrue(store)
+        self.assertTrue(store._mask, True)
+        self.assertTrue(store is not masked)
+
+        store = empty((), dtype=bool)
+        self.assertTrue(full.any() is masked)
+        full.any(out=store)
+        self.assertTrue(not store)
+        self.assertTrue(store._mask, True)
+        self.assertTrue(store is not masked)
+
+    def test_argmax_argmin(self):
+        # Tests argmin & argmax on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+
+        assert_equal(mx.argmin(), 35)
+        assert_equal(mX.argmin(), 35)
+        assert_equal(m2x.argmin(), 4)
+        assert_equal(m2X.argmin(), 4)
+        assert_equal(mx.argmax(), 28)
+        assert_equal(mX.argmax(), 28)
+        assert_equal(m2x.argmax(), 31)
+        assert_equal(m2X.argmax(), 31)
+
+        assert_equal(mX.argmin(0), [2, 2, 2, 5, 0, 5])
+        assert_equal(m2X.argmin(0), [2, 2, 4, 5, 0, 4])
+        assert_equal(mX.argmax(0), [0, 5, 0, 5, 4, 0])
+        assert_equal(m2X.argmax(0), [5, 5, 0, 5, 1, 0])
+
+        assert_equal(mX.argmin(1), [4, 1, 0, 0, 5, 5, ])
+        assert_equal(m2X.argmin(1), [4, 4, 0, 0, 5, 3])
+        assert_equal(mX.argmax(1), [2, 4, 1, 1, 4, 1])
+        assert_equal(m2X.argmax(1), [2, 4, 1, 1, 1, 1])
+
+    def test_clip(self):
+        # Tests clip on MaskedArrays.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0])
+        mx = array(x, mask=m)
+        clipped = mx.clip(2, 8)
+        assert_equal(clipped.mask, mx.mask)
+        assert_equal(clipped._data, x.clip(2, 8))
+        assert_equal(clipped._data, mx._data.clip(2, 8))
+
+    def test_compress(self):
+        # test compress
+        a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
+        condition = (a > 1.5) & (a < 3.5)
+        assert_equal(a.compress(condition), [2., 3.])
+
+        a[[2, 3]] = masked
+        b = a.compress(condition)
+        assert_equal(b._data, [2., 3.])
+        assert_equal(b._mask, [0, 1])
+        assert_equal(b.fill_value, 9999)
+        assert_equal(b, a[condition])
+
+        condition = (a < 4.)
+        b = a.compress(condition)
+        assert_equal(b._data, [1., 2., 3.])
+        assert_equal(b._mask, [0, 0, 1])
+        assert_equal(b.fill_value, 9999)
+        assert_equal(b, a[condition])
+
+        a = masked_array([[10, 20, 30], [40, 50, 60]],
+                         mask=[[0, 0, 1], [1, 0, 0]])
+        b = a.compress(a.ravel() >= 22)
+        assert_equal(b._data, [30, 40, 50, 60])
+        assert_equal(b._mask, [1, 1, 0, 0])
+
+        x = np.array([3, 1, 2])
+        b = a.compress(x >= 2, axis=1)
+        assert_equal(b._data, [[10, 30], [40, 60]])
+        assert_equal(b._mask, [[0, 1], [1, 0]])
+
+    def test_compressed(self):
+        # Tests compressed
+        a = array([1, 2, 3, 4], mask=[0, 0, 0, 0])
+        b = a.compressed()
+        assert_equal(b, a)
+        a[0] = masked
+        b = a.compressed()
+        assert_equal(b, [2, 3, 4])
+
+        a = array(np.matrix([1, 2, 3, 4]), mask=[0, 0, 0, 0])
+        b = a.compressed()
+        assert_equal(b, a)
+        self.assertTrue(isinstance(b, np.matrix))
+        a[0, 0] = masked
+        b = a.compressed()
+        assert_equal(b, [[2, 3, 4]])
+
+    def test_empty(self):
+        # Tests empty/like
+        datatype = [('a', int), ('b', float), ('c', '|S8')]
+        a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')],
+                         dtype=datatype)
+        assert_equal(len(a.fill_value.item()), len(datatype))
+
+        b = empty_like(a)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+
+        b = empty(len(a), dtype=datatype)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+
+        # check empty_like mask handling
+        a = masked_array([1, 2, 3], mask=[False, True, False])
+        b = empty_like(a)
+        assert_(not np.may_share_memory(a.mask, b.mask))
+        b = a.view(masked_array)
+        assert_(np.may_share_memory(a.mask, b.mask))
+
+    def test_put(self):
+        # Tests put.
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        x = array(d, mask=m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+        x[[1, 4]] = [10, 40]
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is not masked)
+        assert_equal(x, [0, 10, 2, -1, 40])
+
+        x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
+        i = [0, 2, 4, 6]
+        x.put(i, [6, 4, 2, 0])
+        assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
+        assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
+        x.put(i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
+        assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
+        assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
+
+        x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
+        put(x, i, [6, 4, 2, 0])
+        assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
+        assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
+        put(x, i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
+        assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
+        assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
+
+    def test_put_nomask(self):
+        # GitHub issue 6425
+        x = zeros(10)
+        z = array([3., -1.], mask=[False, True])
+
+        x.put([1, 2], z)
+        self.assertTrue(x[0] is not masked)
+        assert_equal(x[0], 0)
+        self.assertTrue(x[1] is not masked)
+        assert_equal(x[1], 3)
+        self.assertTrue(x[2] is masked)
+        self.assertTrue(x[3] is not masked)
+        assert_equal(x[3], 0)
+
+    def test_put_hardmask(self):
+        # Tests put on hardmask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d + 1, mask=m, hard_mask=True, copy=True)
+        xh.put([4, 2, 0, 1, 3], [1, 2, 3, 4, 5])
+        assert_equal(xh._data, [3, 4, 2, 4, 5])
+
+    def test_putmask(self):
+        x = arange(6) + 1
+        mx = array(x, mask=[0, 0, 0, 1, 1, 1])
+        mask = [0, 0, 1, 0, 0, 1]
+        # w/o mask, w/o masked values
+        xx = x.copy()
+        putmask(xx, mask, 99)
+        assert_equal(xx, [1, 2, 99, 4, 5, 99])
+        # w/ mask, w/o masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, 99)
+        assert_equal(mxx._data, [1, 2, 99, 4, 5, 99])
+        assert_equal(mxx._mask, [0, 0, 0, 1, 1, 0])
+        # w/o mask, w/ masked values
+        values = array([10, 20, 30, 40, 50, 60], mask=[1, 1, 1, 0, 0, 0])
+        xx = x.copy()
+        putmask(xx, mask, values)
+        assert_equal(xx._data, [1, 2, 30, 4, 5, 60])
+        assert_equal(xx._mask, [0, 0, 1, 0, 0, 0])
+        # w/ mask, w/ masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, values)
+        assert_equal(mxx._data, [1, 2, 30, 4, 5, 60])
+        assert_equal(mxx._mask, [0, 0, 1, 1, 1, 0])
+        # w/ mask, w/ masked values + hardmask
+        mxx = mx.copy()
+        mxx.harden_mask()
+        putmask(mxx, mask, values)
+        assert_equal(mxx, [1, 2, 30, 4, 5, 60])
+
+    def test_ravel(self):
+        # Tests ravel
+        a = array([[1, 2, 3, 4, 5]], mask=[[0, 1, 0, 0, 0]])
+        aravel = a.ravel()
+        assert_equal(aravel._mask.shape, aravel.shape)
+        a = array([0, 0], mask=[1, 1])
+        aravel = a.ravel()
+        assert_equal(aravel._mask.shape, a.shape)
+        a = array(np.matrix([1, 2, 3, 4, 5]), mask=[[0, 1, 0, 0, 0]])
+        aravel = a.ravel()
+        assert_equal(aravel.shape, (1, 5))
+        assert_equal(aravel._mask.shape, a.shape)
+        # Checks that small_mask is preserved
+        a = array([1, 2, 3, 4], mask=[0, 0, 0, 0], shrink=False)
+        assert_equal(a.ravel()._mask, [0, 0, 0, 0])
+        # Test that the fill_value is preserved
+        a.fill_value = -99
+        a.shape = (2, 2)
+        ar = a.ravel()
+        assert_equal(ar._mask, [0, 0, 0, 0])
+        assert_equal(ar._data, [1, 2, 3, 4])
+        assert_equal(ar.fill_value, -99)
+        # Test index ordering
+        assert_equal(a.ravel(order='C'), [1, 2, 3, 4])
+        assert_equal(a.ravel(order='F'), [1, 3, 2, 4])
+
+    def test_reshape(self):
+        # Tests reshape
+        x = arange(4)
+        x[0] = masked
+        y = x.reshape(2, 2)
+        assert_equal(y.shape, (2, 2,))
+        assert_equal(y._mask.shape, (2, 2,))
+        assert_equal(x.shape, (4,))
+        assert_equal(x._mask.shape, (4,))
+
+    def test_sort(self):
+        # Test sort
+        x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
+
+        sortedx = sort(x)
+        assert_equal(sortedx._data, [1, 2, 3, 4])
+        assert_equal(sortedx._mask, [0, 0, 0, 1])
+
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [4, 1, 2, 3])
+        assert_equal(sortedx._mask, [1, 0, 0, 0])
+
+        x.sort()
+        assert_equal(x._data, [1, 2, 3, 4])
+        assert_equal(x._mask, [0, 0, 0, 1])
+
+        x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
+        x.sort(endwith=False)
+        assert_equal(x._data, [4, 1, 2, 3])
+        assert_equal(x._mask, [1, 0, 0, 0])
+
+        x = [1, 4, 2, 3]
+        sortedx = sort(x)
+        self.assertTrue(not isinstance(sorted, MaskedArray))
+
+        x = array([0, 1, -1, -2, 2], mask=nomask, dtype=np.int8)
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [-2, -1, 0, 1, 2])
+        x = array([0, 1, -1, -2, 2], mask=[0, 1, 0, 0, 1], dtype=np.int8)
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [1, 2, -2, -1, 0])
+        assert_equal(sortedx._mask, [1, 1, 0, 0, 0])
+
+    def test_sort_2d(self):
+        # Check sort of 2D array.
+        # 2D array w/o mask
+        a = masked_array([[8, 4, 1], [2, 0, 9]])
+        a.sort(0)
+        assert_equal(a, [[2, 0, 1], [8, 4, 9]])
+        a = masked_array([[8, 4, 1], [2, 0, 9]])
+        a.sort(1)
+        assert_equal(a, [[1, 4, 8], [0, 2, 9]])
+        # 2D array w/mask
+        a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
+        a.sort(0)
+        assert_equal(a, [[2, 0, 1], [8, 4, 9]])
+        assert_equal(a._mask, [[0, 0, 0], [1, 0, 1]])
+        a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
+        a.sort(1)
+        assert_equal(a, [[1, 4, 8], [0, 2, 9]])
+        assert_equal(a._mask, [[0, 0, 1], [0, 0, 1]])
+        # 3D
+        a = masked_array([[[7, 8, 9], [4, 5, 6], [1, 2, 3]],
+                          [[1, 2, 3], [7, 8, 9], [4, 5, 6]],
+                          [[7, 8, 9], [1, 2, 3], [4, 5, 6]],
+                          [[4, 5, 6], [1, 2, 3], [7, 8, 9]]])
+        a[a % 4 == 0] = masked
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(0)
+        an.sort(0)
+        assert_equal(am, an)
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(1)
+        an.sort(1)
+        assert_equal(am, an)
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(2)
+        an.sort(2)
+        assert_equal(am, an)
+
+    def test_sort_flexible(self):
+        # Test sort on flexible dtype.
+        a = array(
+            data=[(3, 3), (3, 2), (2, 2), (2, 1), (1, 0), (1, 1), (1, 2)],
+            mask=[(0, 0), (0, 1), (0, 0), (0, 0), (1, 0), (0, 0), (0, 0)],
+            dtype=[('A', int), ('B', int)])
+
+        test = sort(a)
+        b = array(
+            data=[(1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (3, 2), (1, 0)],
+            mask=[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (1, 0)],
+            dtype=[('A', int), ('B', int)])
+        assert_equal(test, b)
+        assert_equal(test.mask, b.mask)
+
+        test = sort(a, endwith=False)
+        b = array(
+            data=[(1, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 2), (3, 3), ],
+            mask=[(1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (0, 0), ],
+            dtype=[('A', int), ('B', int)])
+        assert_equal(test, b)
+        assert_equal(test.mask, b.mask)
+
+    def test_argsort(self):
+        # Test argsort
+        a = array([1, 5, 2, 4, 3], mask=[1, 0, 0, 1, 0])
+        assert_equal(np.argsort(a), argsort(a))
+
+    def test_squeeze(self):
+        # Check squeeze
+        data = masked_array([[1, 2, 3]])
+        assert_equal(data.squeeze(), [1, 2, 3])
+        data = masked_array([[1, 2, 3]], mask=[[1, 1, 1]])
+        assert_equal(data.squeeze(), [1, 2, 3])
+        assert_equal(data.squeeze()._mask, [1, 1, 1])
+        data = masked_array([[1]], mask=True)
+        self.assertTrue(data.squeeze() is masked)
+
+    def test_swapaxes(self):
+        # Tests swapaxes on MaskedArrays.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        m = np.array([0, 1, 0, 1, 0, 0,
+                      1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0,
+                      0, 0, 1, 0, 1, 0])
+        mX = array(x, mask=m).reshape(6, 6)
+        mXX = mX.reshape(3, 2, 2, 3)
+
+        mXswapped = mX.swapaxes(0, 1)
+        assert_equal(mXswapped[-1], mX[:, -1])
+
+        mXXswapped = mXX.swapaxes(0, 2)
+        assert_equal(mXXswapped.shape, (2, 2, 3, 3))
+
+    def test_take(self):
+        # Tests take
+        x = masked_array([10, 20, 30, 40], [0, 1, 0, 1])
+        assert_equal(x.take([0, 0, 3]), masked_array([10, 10, 40], [0, 0, 1]))
+        assert_equal(x.take([0, 0, 3]), x[[0, 0, 3]])
+        assert_equal(x.take([[0, 1], [0, 1]]),
+                     masked_array([[10, 20], [10, 20]], [[0, 1], [0, 1]]))
+
+        x = array([[10, 20, 30], [40, 50, 60]], mask=[[0, 0, 1], [1, 0, 0, ]])
+        assert_equal(x.take([0, 2], axis=1),
+                     array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
+        assert_equal(take(x, [0, 2], axis=1),
+                     array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
+
+    def test_take_masked_indices(self):
+        # Test take w/ masked indices
+        a = np.array((40, 18, 37, 9, 22))
+        indices = np.arange(3)[None,:] + np.arange(5)[:, None]
+        mindices = array(indices, mask=(indices >= len(a)))
+        # No mask
+        test = take(a, mindices, mode='clip')
+        ctrl = array([[40, 18, 37],
+                      [18, 37, 9],
+                      [37, 9, 22],
+                      [9, 22, 22],
+                      [22, 22, 22]])
+        assert_equal(test, ctrl)
+        # Masked indices
+        test = take(a, mindices)
+        ctrl = array([[40, 18, 37],
+                      [18, 37, 9],
+                      [37, 9, 22],
+                      [9, 22, 40],
+                      [22, 40, 40]])
+        ctrl[3, 2] = ctrl[4, 1] = ctrl[4, 2] = masked
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        # Masked input + masked indices
+        a = array((40, 18, 37, 9, 22), mask=(0, 1, 0, 0, 0))
+        test = take(a, mindices)
+        ctrl[0, 1] = ctrl[1, 0] = masked
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+
+    def test_tolist(self):
+        # Tests to list
+        # ... on 1D
+        x = array(np.arange(12))
+        x[[1, -2]] = masked
+        xlist = x.tolist()
+        self.assertTrue(xlist[1] is None)
+        self.assertTrue(xlist[-2] is None)
+        # ... on 2D
+        x.shape = (3, 4)
+        xlist = x.tolist()
+        ctrl = [[0, None, 2, 3], [4, 5, 6, 7], [8, 9, None, 11]]
+        assert_equal(xlist[0], [0, None, 2, 3])
+        assert_equal(xlist[1], [4, 5, 6, 7])
+        assert_equal(xlist[2], [8, 9, None, 11])
+        assert_equal(xlist, ctrl)
+        # ... on structured array w/ masked records
+        x = array(list(zip([1, 2, 3],
+                           [1.1, 2.2, 3.3],
+                           ['one', 'two', 'thr'])),
+                  dtype=[('a', int), ('b', float), ('c', '|S8')])
+        x[-1] = masked
+        assert_equal(x.tolist(),
+                     [(1, 1.1, asbytes('one')),
+                      (2, 2.2, asbytes('two')),
+                      (None, None, None)])
+        # ... on structured array w/ masked fields
+        a = array([(1, 2,), (3, 4)], mask=[(0, 1), (0, 0)],
+                  dtype=[('a', int), ('b', int)])
+        test = a.tolist()
+        assert_equal(test, [[1, None], [3, 4]])
+        # ... on mvoid
+        a = a[0]
+        test = a.tolist()
+        assert_equal(test, [1, None])
+
+    def test_tolist_specialcase(self):
+        # Test mvoid.tolist: make sure we return a standard Python object
+        a = array([(0, 1), (2, 3)], dtype=[('a', int), ('b', int)])
+        # w/o mask: each entry is a np.void whose elements are standard Python
+        for entry in a:
+            for item in entry.tolist():
+                assert_(not isinstance(item, np.generic))
+        # w/ mask: each entry is a ma.void whose elements should be
+        # standard Python
+        a.mask[0] = (0, 1)
+        for entry in a:
+            for item in entry.tolist():
+                assert_(not isinstance(item, np.generic))
+
+    def test_toflex(self):
+        # Test the conversion to records
+        data = arange(10)
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        ndtype = [('i', int), ('s', '|S3'), ('f', float)]
+        data = array([(i, s, f) for (i, s, f) in zip(np.arange(10),
+                                                     'ABCDEFGHIJKLM',
+                                                     np.random.rand(10))],
+                     dtype=ndtype)
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        ndtype = np.dtype("int, (2,3)float, float")
+        data = array([(i, f, ff) for (i, f, ff) in zip(np.arange(10),
+                                                       np.random.rand(10),
+                                                       np.random.rand(10))],
+                     dtype=ndtype)
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal_records(record['_data'], data._data)
+        assert_equal_records(record['_mask'], data._mask)
+
+    def test_fromflex(self):
+        # Test the reconstruction of a masked_array from a record
+        a = array([1, 2, 3])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.mask, a.mask)
+
+        a = array([1, 2, 3], mask=[0, 0, 1])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.mask, a.mask)
+
+        a = array([(1, 1.), (2, 2.), (3, 3.)], mask=[(1, 0), (0, 0), (0, 1)],
+                  dtype=[('A', int), ('B', float)])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.data, a.data)
+
+    def test_arraymethod(self):
+        # Test a _arraymethod w/ n argument
+        marray = masked_array([[1, 2, 3, 4, 5]], mask=[0, 0, 1, 0, 0])
+        control = masked_array([[1], [2], [3], [4], [5]],
+                               mask=[0, 0, 1, 0, 0])
+        assert_equal(marray.T, control)
+        assert_equal(marray.transpose(), control)
+
+        assert_equal(MaskedArray.cumsum(marray.T, 0), control.cumsum(0))
+
+
+class TestMaskedArrayMathMethods(TestCase):
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_cumsumprod(self):
+        # Tests cumsum & cumprod on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        mXcp = mX.cumsum(0)
+        assert_equal(mXcp._data, mX.filled(0).cumsum(0))
+        mXcp = mX.cumsum(1)
+        assert_equal(mXcp._data, mX.filled(0).cumsum(1))
+
+        mXcp = mX.cumprod(0)
+        assert_equal(mXcp._data, mX.filled(1).cumprod(0))
+        mXcp = mX.cumprod(1)
+        assert_equal(mXcp._data, mX.filled(1).cumprod(1))
+
+    def test_cumsumprod_with_output(self):
+        # Tests cumsum/cumprod w/ output
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        for funcname in ('cumsum', 'cumprod'):
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+
+            # A ndarray as explicit input
+            output = np.empty((3, 4), dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0, out=output)
+            # ... the result should be the given output
+            self.assertTrue(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+
+            output = empty((3, 4), dtype=int)
+            result = xmmeth(axis=0, out=output)
+            self.assertTrue(result is output)
+
+    def test_ptp(self):
+        # Tests ptp on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        (n, m) = X.shape
+        assert_equal(mx.ptp(), mx.compressed().ptp())
+        rows = np.zeros(n, np.float)
+        cols = np.zeros(m, np.float)
+        for k in range(m):
+            cols[k] = mX[:, k].compressed().ptp()
+        for k in range(n):
+            rows[k] = mX[k].compressed().ptp()
+        assert_equal(mX.ptp(0), cols)
+        assert_equal(mX.ptp(1), rows)
+
+    def test_add_object(self):
+        x = masked_array(['a', 'b'], mask=[1, 0], dtype=object)
+        y = x + 'x'
+        assert_equal(y[1], 'bx')
+        assert_(y.mask[0])
+
+    def test_sum_object(self):
+        # Test sum on object dtype
+        a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=np.object)
+        assert_equal(a.sum(), 5)
+        a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
+        assert_equal(a.sum(axis=0), [5, 7, 9])
+
+    def test_prod_object(self):
+        # Test prod on object dtype
+        a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=np.object)
+        assert_equal(a.prod(), 2 * 3)
+        a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
+        assert_equal(a.prod(axis=0), [4, 10, 18])
+
+    def test_meananom_object(self):
+        # Test mean/anom on object dtype
+        a = masked_array([1, 2, 3], dtype=np.object)
+        assert_equal(a.mean(), 2)
+        assert_equal(a.anom(), [-1, 0, 1])
+
+    def test_trace(self):
+        # Tests trace on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        mXdiag = mX.diagonal()
+        assert_equal(mX.trace(), mX.diagonal().compressed().sum())
+        assert_almost_equal(mX.trace(),
+                            X.trace() - sum(mXdiag.mask * X.diagonal(),
+                                            axis=0))
+        assert_equal(np.trace(mX), mX.trace())
+
+    def test_dot(self):
+        # Tests dot on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        fx = mx.filled(0)
+        r = mx.dot(mx)
+        assert_almost_equal(r.filled(0), fx.dot(fx))
+        assert_(r.mask is nomask)
+
+        fX = mX.filled(0)
+        r = mX.dot(mX)
+        assert_almost_equal(r.filled(0), fX.dot(fX))
+        assert_(r.mask[1,3])
+        r1 = empty_like(r)
+        mX.dot(mX, out=r1)
+        assert_almost_equal(r, r1)
+
+        mYY = mXX.swapaxes(-1, -2)
+        fXX, fYY = mXX.filled(0), mYY.filled(0)
+        r = mXX.dot(mYY)
+        assert_almost_equal(r.filled(0), fXX.dot(fYY))
+        r1 = empty_like(r)
+        mXX.dot(mYY, out=r1)
+        assert_almost_equal(r, r1)
+
+    def test_dot_shape_mismatch(self):
+        # regression test
+        x = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]])
+        y = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]])
+        z = masked_array([[0,1],[3,3]])
+        x.dot(y, out=z)
+        assert_almost_equal(z.filled(0), [[1, 0], [15, 16]])
+        assert_almost_equal(z.mask, [[0, 1], [0, 0]])
+
+    def test_varstd(self):
+        # Tests var & std on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        assert_almost_equal(mX.var(axis=None), mX.compressed().var())
+        assert_almost_equal(mX.std(axis=None), mX.compressed().std())
+        assert_almost_equal(mX.std(axis=None, ddof=1),
+                            mX.compressed().std(ddof=1))
+        assert_almost_equal(mX.var(axis=None, ddof=1),
+                            mX.compressed().var(ddof=1))
+        assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
+        assert_equal(mX.var().shape, X.var().shape)
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        assert_almost_equal(mX.var(axis=None, ddof=2),
+                            mX.compressed().var(ddof=2))
+        assert_almost_equal(mX.std(axis=None, ddof=2),
+                            mX.compressed().std(ddof=2))
+        for k in range(6):
+            assert_almost_equal(mXvar1[k], mX[k].compressed().var())
+            assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
+            assert_almost_equal(np.sqrt(mXvar0[k]),
+                                mX[:, k].compressed().std())
+
+    def test_varstd_specialcases(self):
+        # Test a special case for var
+        nout = np.array(-1, dtype=float)
+        mout = array(-1, dtype=float)
+
+        x = array(arange(10), mask=True)
+        for methodname in ('var', 'std'):
+            method = getattr(x, methodname)
+            self.assertTrue(method() is masked)
+            self.assertTrue(method(0) is masked)
+            self.assertTrue(method(-1) is masked)
+            # Using a masked array as explicit output
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                method(out=mout)
+            self.assertTrue(mout is not masked)
+            assert_equal(mout.mask, True)
+            # Using a ndarray as explicit output
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                method(out=nout)
+            self.assertTrue(np.isnan(nout))
+
+        x = array(arange(10), mask=True)
+        x[-1] = 9
+        for methodname in ('var', 'std'):
+            method = getattr(x, methodname)
+            self.assertTrue(method(ddof=1) is masked)
+            self.assertTrue(method(0, ddof=1) is masked)
+            self.assertTrue(method(-1, ddof=1) is masked)
+            # Using a masked array as explicit output
+            method(out=mout, ddof=1)
+            self.assertTrue(mout is not masked)
+            assert_equal(mout.mask, True)
+            # Using a ndarray as explicit output
+            method(out=nout, ddof=1)
+            self.assertTrue(np.isnan(nout))
+
+    def test_varstd_ddof(self):
+        a = array([[1, 1, 0], [1, 1, 0]], mask=[[0, 0, 1], [0, 0, 1]])
+        test = a.std(axis=0, ddof=0)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [0, 0, 1])
+        test = a.std(axis=0, ddof=1)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [0, 0, 1])
+        test = a.std(axis=0, ddof=2)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [1, 1, 1])
+
+    def test_diag(self):
+        # Test diag
+        x = arange(9).reshape((3, 3))
+        x[1, 1] = masked
+        out = np.diag(x)
+        assert_equal(out, [0, 4, 8])
+        out = diag(x)
+        assert_equal(out, [0, 4, 8])
+        assert_equal(out.mask, [0, 1, 0])
+        out = diag(out)
+        control = array([[0, 0, 0], [0, 4, 0], [0, 0, 8]],
+                        mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(out, control)
+
+    def test_axis_methods_nomask(self):
+        # Test the combination nomask & methods w/ axis
+        a = array([[1, 2, 3], [4, 5, 6]])
+
+        assert_equal(a.sum(0), [5, 7, 9])
+        assert_equal(a.sum(-1), [6, 15])
+        assert_equal(a.sum(1), [6, 15])
+
+        assert_equal(a.prod(0), [4, 10, 18])
+        assert_equal(a.prod(-1), [6, 120])
+        assert_equal(a.prod(1), [6, 120])
+
+        assert_equal(a.min(0), [1, 2, 3])
+        assert_equal(a.min(-1), [1, 4])
+        assert_equal(a.min(1), [1, 4])
+
+        assert_equal(a.max(0), [4, 5, 6])
+        assert_equal(a.max(-1), [3, 6])
+        assert_equal(a.max(1), [3, 6])
+
+
+class TestMaskedArrayMathMethodsComplex(TestCase):
+    # Test class for miscellaneous MaskedArrays methods.
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375j, 7.545j, 8.828j, 8.5j, 1.757j, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479j,
+                      7.189j, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993j])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_varstd(self):
+        # Tests var & std on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        assert_almost_equal(mX.var(axis=None), mX.compressed().var())
+        assert_almost_equal(mX.std(axis=None), mX.compressed().std())
+        assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
+        assert_equal(mX.var().shape, X.var().shape)
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        assert_almost_equal(mX.var(axis=None, ddof=2),
+                            mX.compressed().var(ddof=2))
+        assert_almost_equal(mX.std(axis=None, ddof=2),
+                            mX.compressed().std(ddof=2))
+        for k in range(6):
+            assert_almost_equal(mXvar1[k], mX[k].compressed().var())
+            assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
+            assert_almost_equal(np.sqrt(mXvar0[k]),
+                                mX[:, k].compressed().std())
+
+
+class TestMaskedArrayFunctions(TestCase):
+    # Test class for miscellaneous functions.
+
+    def setUp(self):
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        xm.set_fill_value(1e+20)
+        self.info = (xm, ym)
+
+    def test_masked_where_bool(self):
+        x = [1, 2]
+        y = masked_where(False, x)
+        assert_equal(y, [1, 2])
+        assert_equal(y[1], 2)
+
+    def test_masked_equal_wlist(self):
+        x = [1, 2, 3]
+        mx = masked_equal(x, 3)
+        assert_equal(mx, x)
+        assert_equal(mx._mask, [0, 0, 1])
+        mx = masked_not_equal(x, 3)
+        assert_equal(mx, x)
+        assert_equal(mx._mask, [1, 1, 0])
+
+    def test_masked_equal_fill_value(self):
+        x = [1, 2, 3]
+        mx = masked_equal(x, 3)
+        assert_equal(mx._mask, [0, 0, 1])
+        assert_equal(mx.fill_value, 3)
+
+    def test_masked_where_condition(self):
+        # Tests masking functions.
+        x = array([1., 2., 3., 4., 5.])
+        x[2] = masked
+        assert_equal(masked_where(greater(x, 2), x), masked_greater(x, 2))
+        assert_equal(masked_where(greater_equal(x, 2), x),
+                     masked_greater_equal(x, 2))
+        assert_equal(masked_where(less(x, 2), x), masked_less(x, 2))
+        assert_equal(masked_where(less_equal(x, 2), x),
+                     masked_less_equal(x, 2))
+        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
+        assert_equal(masked_where(equal(x, 2), x), masked_equal(x, 2))
+        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
+        assert_equal(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]),
+                     [99, 99, 3, 4, 5])
+
+    def test_masked_where_oddities(self):
+        # Tests some generic features.
+        atest = ones((10, 10, 10), dtype=float)
+        btest = zeros(atest.shape, MaskType)
+        ctest = masked_where(btest, atest)
+        assert_equal(atest, ctest)
+
+    def test_masked_where_shape_constraint(self):
+        a = arange(10)
+        try:
+            test = masked_equal(1, a)
+        except IndexError:
+            pass
+        else:
+            raise AssertionError("Should have failed...")
+        test = masked_equal(a, 1)
+        assert_equal(test.mask, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0])
+
+    def test_masked_where_structured(self):
+        # test that masked_where on a structured array sets a structured
+        # mask (see issue #2972)
+        a = np.zeros(10, dtype=[("A", "<f2"), ("B", "<f4")])
+        am = np.ma.masked_where(a["A"] < 5, a)
+        assert_equal(am.mask.dtype.names, am.dtype.names)
+        assert_equal(am["A"],
+                    np.ma.masked_array(np.zeros(10), np.ones(10)))
+
+    def test_masked_otherfunctions(self):
+        assert_equal(masked_inside(list(range(5)), 1, 3),
+                     [0, 199, 199, 199, 4])
+        assert_equal(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199])
+        assert_equal(masked_inside(array(list(range(5)),
+                                         mask=[1, 0, 0, 0, 0]), 1, 3).mask,
+                     [1, 1, 1, 1, 0])
+        assert_equal(masked_outside(array(list(range(5)),
+                                          mask=[0, 1, 0, 0, 0]), 1, 3).mask,
+                     [1, 1, 0, 0, 1])
+        assert_equal(masked_equal(array(list(range(5)),
+                                        mask=[1, 0, 0, 0, 0]), 2).mask,
+                     [1, 0, 1, 0, 0])
+        assert_equal(masked_not_equal(array([2, 2, 1, 2, 1],
+                                            mask=[1, 0, 0, 0, 0]), 2).mask,
+                     [1, 0, 1, 0, 1])
+
+    def test_round(self):
+        a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890],
+                  mask=[0, 1, 0, 0, 0])
+        assert_equal(a.round(), [1., 2., 3., 5., 6.])
+        assert_equal(a.round(1), [1.2, 2.3, 3.5, 4.6, 5.7])
+        assert_equal(a.round(3), [1.235, 2.346, 3.457, 4.568, 5.679])
+        b = empty_like(a)
+        a.round(out=b)
+        assert_equal(b, [1., 2., 3., 5., 6.])
+
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+    def test_round_with_output(self):
+        # Testing round with an explicit output
+
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        # A ndarray as explicit input
+        output = np.empty((3, 4), dtype=float)
+        output.fill(-9999)
+        result = np.round(xm, decimals=2, out=output)
+        # ... the result should be the given output
+        self.assertTrue(result is output)
+        assert_equal(result, xm.round(decimals=2, out=output))
+
+        output = empty((3, 4), dtype=float)
+        result = xm.round(decimals=2, out=output)
+        self.assertTrue(result is output)
+
+    def test_round_with_scalar(self):
+        # Testing round with scalar/zero dimension input
+        # GH issue 2244
+        a = array(1.1, mask=[False])
+        assert_equal(a.round(), 1)
+
+        a = array(1.1, mask=[True])
+        assert_(a.round() is masked)
+
+        a = array(1.1, mask=[False])
+        output = np.empty(1, dtype=float)
+        output.fill(-9999)
+        a.round(out=output)
+        assert_equal(output, 1)
+
+        a = array(1.1, mask=[False])
+        output = array(-9999., mask=[True])
+        a.round(out=output)
+        assert_equal(output[()], 1)
+
+        a = array(1.1, mask=[True])
+        output = array(-9999., mask=[False])
+        a.round(out=output)
+        assert_(output[()] is masked)
+
+    def test_identity(self):
+        a = identity(5)
+        self.assertTrue(isinstance(a, MaskedArray))
+        assert_equal(a, np.identity(5))
+
+    def test_power(self):
+        x = -1.1
+        assert_almost_equal(power(x, 2.), 1.21)
+        self.assertTrue(power(x, masked) is masked)
+        x = array([-1.1, -1.1, 1.1, 1.1, 0.])
+        b = array([0.5, 2., 0.5, 2., -1.], mask=[0, 0, 0, 0, 1])
+        y = power(x, b)
+        assert_almost_equal(y, [0, 1.21, 1.04880884817, 1.21, 0.])
+        assert_equal(y._mask, [1, 0, 0, 0, 1])
+        b.mask = nomask
+        y = power(x, b)
+        assert_equal(y._mask, [1, 0, 0, 0, 1])
+        z = x ** b
+        assert_equal(z._mask, y._mask)
+        assert_almost_equal(z, y)
+        assert_almost_equal(z._data, y._data)
+        x **= b
+        assert_equal(x._mask, y._mask)
+        assert_almost_equal(x, y)
+        assert_almost_equal(x._data, y._data)
+
+    def test_power_w_broadcasting(self):
+        # Test power w/ broadcasting
+        a2 = np.array([[1., 2., 3.], [4., 5., 6.]])
+        a2m = array(a2, mask=[[1, 0, 0], [0, 0, 1]])
+        b1 = np.array([2, 4, 3])
+        b2 = np.array([b1, b1])
+        b2m = array(b2, mask=[[0, 1, 0], [0, 1, 0]])
+
+        ctrl = array([[1 ** 2, 2 ** 4, 3 ** 3], [4 ** 2, 5 ** 4, 6 ** 3]],
+                     mask=[[1, 1, 0], [0, 1, 1]])
+        # No broadcasting, base & exp w/ mask
+        test = a2m ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        # No broadcasting, base w/ mask, exp w/o mask
+        test = a2m ** b2
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, a2m.mask)
+        # No broadcasting, base w/o mask, exp w/ mask
+        test = a2 ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, b2m.mask)
+
+        ctrl = array([[2 ** 2, 4 ** 4, 3 ** 3], [2 ** 2, 4 ** 4, 3 ** 3]],
+                     mask=[[0, 1, 0], [0, 1, 0]])
+        test = b1 ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        test = b2m ** b1
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+
+    def test_where(self):
+        # Test the where function
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        xm.set_fill_value(1e+20)
+
+        d = where(xm > 2, xm, -9)
+        assert_equal(d, [-9., -9., -9., -9., -9., 4.,
+                         -9., -9., 10., -9., -9., 3.])
+        assert_equal(d._mask, xm._mask)
+        d = where(xm > 2, -9, ym)
+        assert_equal(d, [5., 0., 3., 2., -1., -9.,
+                         -9., -10., -9., 1., 0., -9.])
+        assert_equal(d._mask, [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0])
+        d = where(xm > 2, xm, masked)
+        assert_equal(d, [-9., -9., -9., -9., -9., 4.,
+                         -9., -9., 10., -9., -9., 3.])
+        tmp = xm._mask.copy()
+        tmp[(xm <= 2).filled(True)] = True
+        assert_equal(d._mask, tmp)
+
+        ixm = xm.astype(int)
+        d = where(ixm > 2, ixm, masked)
+        assert_equal(d, [-9, -9, -9, -9, -9, 4, -9, -9, 10, -9, -9, 3])
+        assert_equal(d.dtype, ixm.dtype)
+
+    def test_where_object(self):
+        a = np.array(None)
+        b = masked_array(None)
+        r = b.copy()
+        assert_equal(np.ma.where(True, a, a), r)
+        assert_equal(np.ma.where(True, b, b), r)
+
+    def test_where_with_masked_choice(self):
+        x = arange(10)
+        x[3] = masked
+        c = x >= 8
+        # Set False to masked
+        z = where(c, x, masked)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is masked)
+        assert_(z[7] is masked)
+        assert_(z[8] is not masked)
+        assert_(z[9] is not masked)
+        assert_equal(x, z)
+        # Set True to masked
+        z = where(c, masked, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+
+    def test_where_with_masked_condition(self):
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+        x = arange(1, 6)
+        x[-1] = masked
+        y = arange(1, 6) * 10
+        y[2] = masked
+        c = array([1, 1, 1, 0, 0], mask=[1, 0, 0, 0, 0])
+        cm = c.filled(1)
+        z = where(c, x, y)
+        zm = where(cm, x, y)
+        assert_equal(z, zm)
+        assert_(getmask(zm) is nomask)
+        assert_equal(zm, [1, 2, 3, 40, 50])
+        z = where(c, masked, 1)
+        assert_equal(z, [99, 99, 99, 1, 1])
+        z = where(c, 1, masked)
+        assert_equal(z, [99, 1, 1, 99, 99])
+
+    def test_where_type(self):
+        # Test the type conservation with where
+        x = np.arange(4, dtype=np.int32)
+        y = np.arange(4, dtype=np.float32) * 2.2
+        test = where(x > 1.5, y, x).dtype
+        control = np.find_common_type([np.int32, np.float32], [])
+        assert_equal(test, control)
+
+    def test_choose(self):
+        # Test choose
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        chosen = choose([2, 3, 1, 0], choices)
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        chosen = choose([2, 4, 1, 0], choices, mode='clip')
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        chosen = choose([2, 4, 1, 0], choices, mode='wrap')
+        assert_equal(chosen, array([20, 1, 12, 3]))
+        # Check with some masked indices
+        indices_ = array([2, 4, 1, 0], mask=[1, 0, 0, 1])
+        chosen = choose(indices_, choices, mode='wrap')
+        assert_equal(chosen, array([99, 1, 12, 99]))
+        assert_equal(chosen.mask, [1, 0, 0, 1])
+        # Check with some masked choices
+        choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
+                                       [1, 0, 0, 0], [0, 0, 0, 0]])
+        indices_ = [2, 3, 1, 0]
+        chosen = choose(indices_, choices, mode='wrap')
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        assert_equal(chosen.mask, [1, 0, 0, 1])
+
+    def test_choose_with_out(self):
+        # Test choose with an explicit out keyword
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        store = empty(4, dtype=int)
+        chosen = choose([2, 3, 1, 0], choices, out=store)
+        assert_equal(store, array([20, 31, 12, 3]))
+        self.assertTrue(store is chosen)
+        # Check with some masked indices + out
+        store = empty(4, dtype=int)
+        indices_ = array([2, 3, 1, 0], mask=[1, 0, 0, 1])
+        chosen = choose(indices_, choices, mode='wrap', out=store)
+        assert_equal(store, array([99, 31, 12, 99]))
+        assert_equal(store.mask, [1, 0, 0, 1])
+        # Check with some masked choices + out ina ndarray !
+        choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
+                                       [1, 0, 0, 0], [0, 0, 0, 0]])
+        indices_ = [2, 3, 1, 0]
+        store = empty(4, dtype=int).view(ndarray)
+        chosen = choose(indices_, choices, mode='wrap', out=store)
+        assert_equal(store, array([999999, 31, 12, 999999]))
+
+    def test_reshape(self):
+        a = arange(10)
+        a[0] = masked
+        # Try the default
+        b = a.reshape((5, 2))
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['C'])
+        # Try w/ arguments as list instead of tuple
+        b = a.reshape(5, 2)
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['C'])
+        # Try w/ order
+        b = a.reshape((5, 2), order='F')
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['F'])
+        # Try w/ order
+        b = a.reshape(5, 2, order='F')
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['F'])
+
+        c = np.reshape(a, (2, 5))
+        self.assertTrue(isinstance(c, MaskedArray))
+        assert_equal(c.shape, (2, 5))
+        self.assertTrue(c[0, 0] is masked)
+        self.assertTrue(c.flags['C'])
+
+    def test_make_mask_descr(self):
+        # Test make_mask_descr
+        # Flexible
+        ntype = [('a', np.float), ('b', np.float)]
+        test = make_mask_descr(ntype)
+        assert_equal(test, [('a', np.bool), ('b', np.bool)])
+        # Standard w/ shape
+        ntype = (np.float, 2)
+        test = make_mask_descr(ntype)
+        assert_equal(test, (np.bool, 2))
+        # Standard standard
+        ntype = np.float
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype(np.bool))
+        # Nested
+        ntype = [('a', np.float), ('b', [('ba', np.float), ('bb', np.float)])]
+        test = make_mask_descr(ntype)
+        control = np.dtype([('a', 'b1'), ('b', [('ba', 'b1'), ('bb', 'b1')])])
+        assert_equal(test, control)
+        # Named+ shape
+        ntype = [('a', (np.float, 2))]
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype([('a', (np.bool, 2))]))
+        # 2 names
+        ntype = [(('A', 'a'), float)]
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype([(('A', 'a'), bool)]))
+
+    def test_make_mask(self):
+        # Test make_mask
+        # w/ a list as an input
+        mask = [0, 1]
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [0, 1])
+        # w/ a ndarray as an input
+        mask = np.array([0, 1], dtype=np.bool)
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [0, 1])
+        # w/ a flexible-type ndarray as an input - use default
+        mdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [1, 1])
+        # w/ a flexible-type ndarray as an input - use input dtype
+        mdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask, dtype=mask.dtype)
+        assert_equal(test.dtype, mdtype)
+        assert_equal(test, mask)
+        # w/ a flexible-type ndarray as an input - use input dtype
+        mdtype = [('a', np.float), ('b', np.float)]
+        bdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask, dtype=mask.dtype)
+        assert_equal(test.dtype, bdtype)
+        assert_equal(test, np.array([(0, 0), (0, 1)], dtype=bdtype))
+
+        # test that nomask is returned when m is nomask.
+        bools = [True, False]
+        dtypes = [MaskType, np.float]
+        msgformat = 'copy=%s, shrink=%s, dtype=%s'
+        for cpy, shr, dt in itertools.product(bools, bools, dtypes):
+            res = make_mask(nomask, copy=cpy, shrink=shr, dtype=dt)
+            assert_(res is nomask, msgformat % (cpy, shr, dt))
+
+
+    def test_mask_or(self):
+        # Initialize
+        mtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1), (1, 0), (0, 0)], dtype=mtype)
+        # Test using nomask as input
+        test = mask_or(mask, nomask)
+        assert_equal(test, mask)
+        test = mask_or(nomask, mask)
+        assert_equal(test, mask)
+        # Using False as input
+        test = mask_or(mask, False)
+        assert_equal(test, mask)
+        # Using another array w / the same dtype
+        other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=mtype)
+        test = mask_or(mask, other)
+        control = np.array([(0, 1), (0, 1), (1, 1), (0, 1)], dtype=mtype)
+        assert_equal(test, control)
+        # Using another array w / a different dtype
+        othertype = [('A', np.bool), ('B', np.bool)]
+        other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=othertype)
+        try:
+            test = mask_or(mask, other)
+        except ValueError:
+            pass
+        # Using nested arrays
+        dtype = [('a', np.bool), ('b', [('ba', np.bool), ('bb', np.bool)])]
+        amask = np.array([(0, (1, 0)), (0, (1, 0))], dtype=dtype)
+        bmask = np.array([(1, (0, 1)), (0, (0, 0))], dtype=dtype)
+        cntrl = np.array([(1, (1, 1)), (0, (1, 0))], dtype=dtype)
+        assert_equal(mask_or(amask, bmask), cntrl)
+
+    def test_flatten_mask(self):
+        # Tests flatten mask
+        # Standarad dtype
+        mask = np.array([0, 0, 1], dtype=np.bool)
+        assert_equal(flatten_mask(mask), mask)
+        # Flexible dtype
+        mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
+        test = flatten_mask(mask)
+        control = np.array([0, 0, 0, 1], dtype=bool)
+        assert_equal(test, control)
+
+        mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
+        data = [(0, (0, 0)), (0, (0, 1))]
+        mask = np.array(data, dtype=mdtype)
+        test = flatten_mask(mask)
+        control = np.array([0, 0, 0, 0, 0, 1], dtype=bool)
+        assert_equal(test, control)
+
+    def test_on_ndarray(self):
+        # Test functions on ndarrays
+        a = np.array([1, 2, 3, 4])
+        m = array(a, mask=False)
+        test = anom(a)
+        assert_equal(test, m.anom())
+        test = reshape(a, (2, 2))
+        assert_equal(test, m.reshape(2, 2))
+
+    def test_compress(self):
+        # Test compress function on ndarray and masked array
+        # Address Github #2495.
+        arr = np.arange(8)
+        arr.shape = 4, 2
+        cond = np.array([True, False, True, True])
+        control = arr[[0, 2, 3]]
+        test = np.ma.compress(cond, arr, axis=0)
+        assert_equal(test, control)
+        marr = np.ma.array(arr)
+        test = np.ma.compress(cond, marr, axis=0)
+        assert_equal(test, control)
+
+    def test_compressed(self):
+        # Test ma.compressed function.
+        # Address gh-4026
+        a = np.ma.array([1, 2])
+        test = np.ma.compressed(a)
+        assert_(type(test) is np.ndarray)
+
+        # Test case when input data is ndarray subclass
+        class A(np.ndarray):
+            pass
+
+        a = np.ma.array(A(shape=0))
+        test = np.ma.compressed(a)
+        assert_(type(test) is A)
+
+        # Test that compress flattens
+        test = np.ma.compressed([[1],[2]])
+        assert_equal(test.ndim, 1)
+        test = np.ma.compressed([[[[[1]]]]])
+        assert_equal(test.ndim, 1)
+
+        # Test case when input is MaskedArray subclass
+        class M(MaskedArray):
+            pass
+
+        test = np.ma.compressed(M(shape=(0,1,2)))
+        assert_equal(test.ndim, 1)
+
+        # with .compessed() overriden
+        class M(MaskedArray):
+            def compressed(self):
+                return 42
+
+        test = np.ma.compressed(M(shape=(0,1,2)))
+        assert_equal(test, 42)
+
+
+class TestMaskedFields(TestCase):
+
+    def setUp(self):
+        ilist = [1, 2, 3, 4, 5]
+        flist = [1.1, 2.2, 3.3, 4.4, 5.5]
+        slist = ['one', 'two', 'three', 'four', 'five']
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mdtype = [('a', bool), ('b', bool), ('c', bool)]
+        mask = [0, 1, 0, 0, 1]
+        base = array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype)
+        self.data = dict(base=base, mask=mask, ddtype=ddtype, mdtype=mdtype)
+
+    def test_set_records_masks(self):
+        base = self.data['base']
+        mdtype = self.data['mdtype']
+        # Set w/ nomask or masked
+        base.mask = nomask
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = masked
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ simple boolean
+        base.mask = False
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = True
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ list
+        base.mask = [0, 0, 0, 1, 1]
+        assert_equal_records(base._mask,
+                             np.array([(x, x, x) for x in [0, 0, 0, 1, 1]],
+                                      dtype=mdtype))
+
+    def test_set_record_element(self):
+        # Check setting an element of a record)
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[0] = (pi, pi, 'pi')
+
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a._data, [3, 2, 3, 4, 5])
+
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b._data, [pi, 2.2, 3.3, 4.4, 5.5])
+
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c._data,
+                     asbytes_nested(['pi', 'two', 'three', 'four', 'five']))
+
+    def test_set_record_slice(self):
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[:3] = (pi, pi, 'pi')
+
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a._data, [3, 3, 3, 4, 5])
+
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b._data, [pi, pi, pi, 4.4, 5.5])
+
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c._data,
+                     asbytes_nested(['pi', 'pi', 'pi', 'four', 'five']))
+
+    def test_mask_element(self):
+        "Check record access"
+        base = self.data['base']
+        base[0] = masked
+
+        for n in ('a', 'b', 'c'):
+            assert_equal(base[n].mask, [1, 1, 0, 0, 1])
+            assert_equal(base[n]._data, base._data[n])
+
+    def test_getmaskarray(self):
+        # Test getmaskarray on flexible dtype
+        ndtype = [('a', int), ('b', float)]
+        test = empty(3, dtype=ndtype)
+        assert_equal(getmaskarray(test),
+                     np.array([(0, 0), (0, 0), (0, 0)],
+                              dtype=[('a', '|b1'), ('b', '|b1')]))
+        test[:] = masked
+        assert_equal(getmaskarray(test),
+                     np.array([(1, 1), (1, 1), (1, 1)],
+                              dtype=[('a', '|b1'), ('b', '|b1')]))
+
+    def test_view(self):
+        # Test view w/ flexible dtype
+        iterator = list(zip(np.arange(10), np.random.rand(10)))
+        data = np.array(iterator)
+        a = array(iterator, dtype=[('a', float), ('b', float)])
+        a.mask[0] = (1, 0)
+        controlmask = np.array([1] + 19 * [0], dtype=bool)
+        # Transform globally to simple dtype
+        test = a.view(float)
+        assert_equal(test, data.ravel())
+        assert_equal(test.mask, controlmask)
+        # Transform globally to dty
+        test = a.view((float, 2))
+        assert_equal(test, data)
+        assert_equal(test.mask, controlmask.reshape(-1, 2))
+
+        test = a.view((float, 2), np.matrix)
+        assert_equal(test, data)
+        self.assertTrue(isinstance(test, np.matrix))
+
+    def test_getitem(self):
+        ndtype = [('a', float), ('b', float)]
+        a = array(list(zip(np.random.rand(10), np.arange(10))), dtype=ndtype)
+        a.mask = np.array(list(zip([0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
+                                   [1, 0, 0, 0, 0, 0, 0, 0, 1, 0])),
+                          dtype=[('a', bool), ('b', bool)])
+        # No mask
+        self.assertTrue(isinstance(a[1], MaskedArray))
+        # One element masked
+        self.assertTrue(isinstance(a[0], MaskedArray))
+        assert_equal_records(a[0]._data, a._data[0])
+        assert_equal_records(a[0]._mask, a._mask[0])
+        # All element masked
+        self.assertTrue(isinstance(a[-2], MaskedArray))
+        assert_equal_records(a[-2]._data, a._data[-2])
+        assert_equal_records(a[-2]._mask, a._mask[-2])
+
+    def test_setitem(self):
+        # Issue 4866: check that one can set individual items in [record][col]
+        # and [col][record] order
+        ndtype = np.dtype([('a', float), ('b', int)])
+        ma = np.ma.MaskedArray([(1.0, 1), (2.0, 2)], dtype=ndtype)
+        ma['a'][1] = 3.0
+        assert_equal(ma['a'], np.array([1.0, 3.0]))
+        ma[1]['a'] = 4.0
+        assert_equal(ma['a'], np.array([1.0, 4.0]))
+        # Issue 2403
+        mdtype = np.dtype([('a', bool), ('b', bool)])
+        # soft mask
+        control = np.array([(False, True), (True, True)], dtype=mdtype)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a['a'][0] = 2
+        assert_equal(a.mask, control)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a[0]['a'] = 2
+        assert_equal(a.mask, control)
+        # hard mask
+        control = np.array([(True, True), (True, True)], dtype=mdtype)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a.harden_mask()
+        a['a'][0] = 2
+        assert_equal(a.mask, control)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a.harden_mask()
+        a[0]['a'] = 2
+        assert_equal(a.mask, control)
+
+    def test_element_len(self):
+        # check that len() works for mvoid (Github issue #576)
+        for rec in self.data['base']:
+            assert_equal(len(rec), len(self.data['ddtype']))
+
+
+class TestMaskedView(TestCase):
+
+    def setUp(self):
+        iterator = list(zip(np.arange(10), np.random.rand(10)))
+        data = np.array(iterator)
+        a = array(iterator, dtype=[('a', float), ('b', float)])
+        a.mask[0] = (1, 0)
+        controlmask = np.array([1] + 19 * [0], dtype=bool)
+        self.data = (data, a, controlmask)
+
+    def test_view_to_nothing(self):
+        (data, a, controlmask) = self.data
+        test = a.view()
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test._data, a._data)
+        assert_equal(test._mask, a._mask)
+
+    def test_view_to_type(self):
+        (data, a, controlmask) = self.data
+        test = a.view(np.ndarray)
+        self.assertTrue(not isinstance(test, MaskedArray))
+        assert_equal(test, a._data)
+        assert_equal_records(test, data.view(a.dtype).squeeze())
+
+    def test_view_to_simple_dtype(self):
+        (data, a, controlmask) = self.data
+        # View globally
+        test = a.view(float)
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data.ravel())
+        assert_equal(test.mask, controlmask)
+
+    def test_view_to_flexible_dtype(self):
+        (data, a, controlmask) = self.data
+
+        test = a.view([('A', float), ('B', float)])
+        assert_equal(test.mask.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'])
+        assert_equal(test['B'], a['b'])
+
+        test = a[0].view([('A', float), ('B', float)])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.mask.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'][0])
+        assert_equal(test['B'], a['b'][0])
+
+        test = a[-1].view([('A', float), ('B', float)])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'][-1])
+        assert_equal(test['B'], a['b'][-1])
+
+    def test_view_to_subdtype(self):
+        (data, a, controlmask) = self.data
+        # View globally
+        test = a.view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data)
+        assert_equal(test.mask, controlmask.reshape(-1, 2))
+        # View on 1 masked element
+        test = a[0].view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data[0])
+        assert_equal(test.mask, (1, 0))
+        # View on 1 unmasked element
+        test = a[-1].view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data[-1])
+
+    def test_view_to_dtype_and_type(self):
+        (data, a, controlmask) = self.data
+
+        test = a.view((float, 2), np.matrix)
+        assert_equal(test, data)
+        self.assertTrue(isinstance(test, np.matrix))
+        self.assertTrue(not isinstance(test, MaskedArray))
+
+
+def test_masked_array():
+    a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0])
+    assert_equal(np.argwhere(a), [[1], [3]])
+
+def test_append_masked_array():
+    a = np.ma.masked_equal([1,2,3], value=2)
+    b = np.ma.masked_equal([4,3,2], value=2)
+
+    result = np.ma.append(a, b)
+    expected_data = [1, 2, 3, 4, 3, 2]
+    expected_mask = [False, True, False, False, False, True]
+    assert_array_equal(result.data, expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+    a = np.ma.masked_all((2,2))
+    b = np.ma.ones((3,1))
+
+    result = np.ma.append(a, b)
+    expected_data = [1] * 3
+    expected_mask = [True] * 4 + [False] * 3
+    assert_array_equal(result.data[-3], expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+    result = np.ma.append(a, b, axis=None)
+    assert_array_equal(result.data[-3], expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+
+def test_append_masked_array_along_axis():
+    a = np.ma.masked_equal([1,2,3], value=2)
+    b = np.ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
+
+    # When `axis` is specified, `values` must have the correct shape.
+    assert_raises(ValueError, np.ma.append, a, b, axis=0)
+
+    result = np.ma.append(a[np.newaxis,:], b, axis=0)
+    expected = np.ma.arange(1, 10)
+    expected[[1, 6]] = np.ma.masked
+    expected = expected.reshape((3,3))
+    assert_array_equal(result.data, expected.data)
+    assert_array_equal(result.mask, expected.mask)
+
+
+def test_default_fill_value_complex():
+    # regression test for Python 3, where 'unicode' was not defined
+    assert_(default_fill_value(1 + 1j) == 1.e20 + 0.0j)
+
+###############################################################################
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
new file mode 100644
index 0000000000..6138d05739
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
@@ -0,0 +1,1188 @@
+# pylint: disable-msg=W0611, W0612, W0511
+"""Tests suite for MaskedArray.
+Adapted from the original test_ma by Pierre Gerard-Marchant
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: test_extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_warns, clear_and_catch_warnings
+    )
+from numpy.ma.testutils import (
+    assert_, assert_array_equal, assert_equal, assert_almost_equal
+    )
+from numpy.ma.core import (
+    array, arange, masked, MaskedArray, masked_array, getmaskarray, shape,
+    nomask, ones, zeros, count
+    )
+from numpy.ma.extras import (
+    atleast_1d, atleast_2d, atleast_3d, mr_, dot, polyfit, cov, corrcoef,
+    median, average, unique, setxor1d, setdiff1d, union1d, intersect1d, in1d,
+    ediff1d, apply_over_axes, apply_along_axis, compress_nd, compress_rowcols,
+    mask_rowcols, clump_masked, clump_unmasked, flatnotmasked_contiguous,
+    notmasked_contiguous, notmasked_edges, masked_all, masked_all_like,
+    diagflat
+    )
+import numpy.ma.extras as mae
+
+
+class TestGeneric(TestCase):
+    #
+    def test_masked_all(self):
+        # Tests masked_all
+        # Standard dtype
+        test = masked_all((2,), dtype=float)
+        control = array([1, 1], mask=[1, 1], dtype=float)
+        assert_equal(test, control)
+        # Flexible dtype
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']})
+        test = masked_all((2,), dtype=dt)
+        control = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((2, 2), dtype=dt)
+        control = array([[(0, 0), (0, 0)], [(0, 0), (0, 0)]],
+                        mask=[[(1, 1), (1, 1)], [(1, 1), (1, 1)]],
+                        dtype=dt)
+        assert_equal(test, control)
+        # Nested dtype
+        dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])])
+        test = masked_all((2,), dtype=dt)
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((2,), dtype=dt)
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((1, 1), dtype=dt)
+        control = array([[(1, (1, 1))]], mask=[[(1, (1, 1))]], dtype=dt)
+        assert_equal(test, control)
+
+    def test_masked_all_like(self):
+        # Tests masked_all
+        # Standard dtype
+        base = array([1, 2], dtype=float)
+        test = masked_all_like(base)
+        control = array([1, 1], mask=[1, 1], dtype=float)
+        assert_equal(test, control)
+        # Flexible dtype
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']})
+        base = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt)
+        test = masked_all_like(base)
+        control = array([(10, 10), (10, 10)], mask=[(1, 1), (1, 1)], dtype=dt)
+        assert_equal(test, control)
+        # Nested dtype
+        dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])])
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        test = masked_all_like(control)
+        assert_equal(test, control)
+
+    def check_clump(self, f):
+        for i in range(1, 7):
+            for j in range(2**i):
+                k = np.arange(i, dtype=int)
+                ja = np.full(i, j, dtype=int)
+                a = masked_array(2**k)
+                a.mask = (ja & (2**k)) != 0
+                s = 0
+                for sl in f(a):
+                    s += a.data[sl].sum()
+                if f == clump_unmasked:
+                    assert_equal(a.compressed().sum(), s)
+                else:
+                    a.mask = ~a.mask
+                    assert_equal(a.compressed().sum(), s)
+
+    def test_clump_masked(self):
+        # Test clump_masked
+        a = masked_array(np.arange(10))
+        a[[0, 1, 2, 6, 8, 9]] = masked
+        #
+        test = clump_masked(a)
+        control = [slice(0, 3), slice(6, 7), slice(8, 10)]
+        assert_equal(test, control)
+
+        self.check_clump(clump_masked)
+
+    def test_clump_unmasked(self):
+        # Test clump_unmasked
+        a = masked_array(np.arange(10))
+        a[[0, 1, 2, 6, 8, 9]] = masked
+        test = clump_unmasked(a)
+        control = [slice(3, 6), slice(7, 8), ]
+        assert_equal(test, control)
+
+        self.check_clump(clump_unmasked)
+
+    def test_flatnotmasked_contiguous(self):
+        # Test flatnotmasked_contiguous
+        a = arange(10)
+        # No mask
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, slice(0, a.size))
+        # Some mask
+        a[(a < 3) | (a > 8) | (a == 5)] = masked
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, [slice(3, 5), slice(6, 9)])
+        #
+        a[:] = masked
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, None)
+
+
+class TestAverage(TestCase):
+    # Several tests of average. Why so many ? Good point...
+    def test_testAverage1(self):
+        # Test of average.
+        ott = array([0., 1., 2., 3.], mask=[True, False, False, False])
+        assert_equal(2.0, average(ott, axis=0))
+        assert_equal(2.0, average(ott, weights=[1., 1., 2., 1.]))
+        result, wts = average(ott, weights=[1., 1., 2., 1.], returned=1)
+        assert_equal(2.0, result)
+        self.assertTrue(wts == 4.0)
+        ott[:] = masked
+        assert_equal(average(ott, axis=0).mask, [True])
+        ott = array([0., 1., 2., 3.], mask=[True, False, False, False])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = masked
+        assert_equal(average(ott, axis=0), [2.0, 0.0])
+        assert_equal(average(ott, axis=1).mask[0], [True])
+        assert_equal([2., 0.], average(ott, axis=0))
+        result, wts = average(ott, axis=0, returned=1)
+        assert_equal(wts, [1., 0.])
+
+    def test_testAverage2(self):
+        # More tests of average.
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = arange(6, dtype=np.float_)
+        assert_equal(average(x, axis=0), 2.5)
+        assert_equal(average(x, axis=0, weights=w1), 2.5)
+        y = array([arange(6, dtype=np.float_), 2.0 * arange(6)])
+        assert_equal(average(y, None), np.add.reduce(np.arange(6)) * 3. / 12.)
+        assert_equal(average(y, axis=0), np.arange(6) * 3. / 2.)
+        assert_equal(average(y, axis=1),
+                     [average(x, axis=0), average(x, axis=0) * 2.0])
+        assert_equal(average(y, None, weights=w2), 20. / 6.)
+        assert_equal(average(y, axis=0, weights=w2),
+                     [0., 1., 2., 3., 4., 10.])
+        assert_equal(average(y, axis=1),
+                     [average(x, axis=0), average(x, axis=0) * 2.0])
+        m1 = zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        assert_equal(average(masked_array(x, m1), axis=0), 2.5)
+        assert_equal(average(masked_array(x, m2), axis=0), 2.5)
+        assert_equal(average(masked_array(x, m4), axis=0).mask, [True])
+        assert_equal(average(masked_array(x, m5), axis=0), 0.0)
+        assert_equal(count(average(masked_array(x, m4), axis=0)), 0)
+        z = masked_array(y, m3)
+        assert_equal(average(z, None), 20. / 6.)
+        assert_equal(average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5])
+        assert_equal(average(z, axis=1), [2.5, 5.0])
+        assert_equal(average(z, axis=0, weights=w2),
+                     [0., 1., 99., 99., 4.0, 10.0])
+
+    def test_testAverage3(self):
+        # Yet more tests of average!
+        a = arange(6)
+        b = arange(6) * 3
+        r1, w1 = average([[a, b], [b, a]], axis=1, returned=1)
+        assert_equal(shape(r1), shape(w1))
+        assert_equal(r1.shape, w1.shape)
+        r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=1)
+        assert_equal(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), returned=1)
+        assert_equal(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=1)
+        assert_equal(shape(w2), shape(r2))
+        a2d = array([[1, 2], [0, 4]], float)
+        a2dm = masked_array(a2d, [[False, False], [True, False]])
+        a2da = average(a2d, axis=0)
+        assert_equal(a2da, [0.5, 3.0])
+        a2dma = average(a2dm, axis=0)
+        assert_equal(a2dma, [1.0, 3.0])
+        a2dma = average(a2dm, axis=None)
+        assert_equal(a2dma, 7. / 3.)
+        a2dma = average(a2dm, axis=1)
+        assert_equal(a2dma, [1.5, 4.0])
+
+    def test_onintegers_with_mask(self):
+        # Test average on integers with mask
+        a = average(array([1, 2]))
+        assert_equal(a, 1.5)
+        a = average(array([1, 2, 3, 4], mask=[False, False, True, True]))
+        assert_equal(a, 1.5)
+
+    def test_complex(self):
+        # Test with complex data.
+        # (Regression test for https://github.com/numpy/numpy/issues/2684)
+        mask = np.array([[0, 0, 0, 1, 0],
+                         [0, 1, 0, 0, 0]], dtype=bool)
+        a = masked_array([[0, 1+2j, 3+4j, 5+6j, 7+8j],
+                          [9j, 0+1j, 2+3j, 4+5j, 7+7j]],
+                         mask=mask)
+
+        av = average(a)
+        expected = np.average(a.compressed())
+        assert_almost_equal(av.real, expected.real)
+        assert_almost_equal(av.imag, expected.imag)
+
+        av0 = average(a, axis=0)
+        expected0 = average(a.real, axis=0) + average(a.imag, axis=0)*1j
+        assert_almost_equal(av0.real, expected0.real)
+        assert_almost_equal(av0.imag, expected0.imag)
+
+        av1 = average(a, axis=1)
+        expected1 = average(a.real, axis=1) + average(a.imag, axis=1)*1j
+        assert_almost_equal(av1.real, expected1.real)
+        assert_almost_equal(av1.imag, expected1.imag)
+
+        # Test with the 'weights' argument.
+        wts = np.array([[0.5, 1.0, 2.0, 1.0, 0.5],
+                        [1.0, 1.0, 1.0, 1.0, 1.0]])
+        wav = average(a, weights=wts)
+        expected = np.average(a.compressed(), weights=wts[~mask])
+        assert_almost_equal(wav.real, expected.real)
+        assert_almost_equal(wav.imag, expected.imag)
+
+        wav0 = average(a, weights=wts, axis=0)
+        expected0 = (average(a.real, weights=wts, axis=0) +
+                     average(a.imag, weights=wts, axis=0)*1j)
+        assert_almost_equal(wav0.real, expected0.real)
+        assert_almost_equal(wav0.imag, expected0.imag)
+
+        wav1 = average(a, weights=wts, axis=1)
+        expected1 = (average(a.real, weights=wts, axis=1) +
+                     average(a.imag, weights=wts, axis=1)*1j)
+        assert_almost_equal(wav1.real, expected1.real)
+        assert_almost_equal(wav1.imag, expected1.imag)
+
+
+class TestConcatenator(TestCase):
+    # Tests for mr_, the equivalent of r_ for masked arrays.
+
+    def test_1d(self):
+        # Tests mr_ on 1D arrays.
+        assert_array_equal(mr_[1, 2, 3, 4, 5, 6], array([1, 2, 3, 4, 5, 6]))
+        b = ones(5)
+        m = [1, 0, 0, 0, 0]
+        d = masked_array(b, mask=m)
+        c = mr_[d, 0, 0, d]
+        self.assertTrue(isinstance(c, MaskedArray))
+        assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1])
+        assert_array_equal(c.mask, mr_[m, 0, 0, m])
+
+    def test_2d(self):
+        # Tests mr_ on 2D arrays.
+        a_1 = np.random.rand(5, 5)
+        a_2 = np.random.rand(5, 5)
+        m_1 = np.round_(np.random.rand(5, 5), 0)
+        m_2 = np.round_(np.random.rand(5, 5), 0)
+        b_1 = masked_array(a_1, mask=m_1)
+        b_2 = masked_array(a_2, mask=m_2)
+        # append columns
+        d = mr_['1', b_1, b_2]
+        self.assertTrue(d.shape == (5, 10))
+        assert_array_equal(d[:, :5], b_1)
+        assert_array_equal(d[:, 5:], b_2)
+        assert_array_equal(d.mask, np.r_['1', m_1, m_2])
+        d = mr_[b_1, b_2]
+        self.assertTrue(d.shape == (10, 5))
+        assert_array_equal(d[:5,:], b_1)
+        assert_array_equal(d[5:,:], b_2)
+        assert_array_equal(d.mask, np.r_[m_1, m_2])
+
+
+class TestNotMasked(TestCase):
+    # Tests notmasked_edges and notmasked_contiguous.
+
+    def test_edges(self):
+        # Tests unmasked_edges
+        data = masked_array(np.arange(25).reshape(5, 5),
+                            mask=[[0, 0, 1, 0, 0],
+                                  [0, 0, 0, 1, 1],
+                                  [1, 1, 0, 0, 0],
+                                  [0, 0, 0, 0, 0],
+                                  [1, 1, 1, 0, 0]],)
+        test = notmasked_edges(data, None)
+        assert_equal(test, [0, 24])
+        test = notmasked_edges(data, 0)
+        assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(3, 3, 3, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data, 1)
+        assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 2, 0, 3)])
+        assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 2, 4, 4, 4)])
+        #
+        test = notmasked_edges(data.data, None)
+        assert_equal(test, [0, 24])
+        test = notmasked_edges(data.data, 0)
+        assert_equal(test[0], [(0, 0, 0, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(4, 4, 4, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data.data, -1)
+        assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 0, 0, 0)])
+        assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 4, 4, 4, 4)])
+        #
+        data[-2] = masked
+        test = notmasked_edges(data, 0)
+        assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(1, 1, 2, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data, -1)
+        assert_equal(test[0], [(0, 1, 2, 4), (0, 0, 2, 3)])
+        assert_equal(test[1], [(0, 1, 2, 4), (4, 2, 4, 4)])
+
+    def test_contiguous(self):
+        # Tests notmasked_contiguous
+        a = masked_array(np.arange(24).reshape(3, 8),
+                         mask=[[0, 0, 0, 0, 1, 1, 1, 1],
+                               [1, 1, 1, 1, 1, 1, 1, 1],
+                               [0, 0, 0, 0, 0, 0, 1, 0], ])
+        tmp = notmasked_contiguous(a, None)
+        assert_equal(tmp[-1], slice(23, 24, None))
+        assert_equal(tmp[-2], slice(16, 22, None))
+        assert_equal(tmp[-3], slice(0, 4, None))
+        #
+        tmp = notmasked_contiguous(a, 0)
+        self.assertTrue(len(tmp[-1]) == 1)
+        self.assertTrue(tmp[-2] is None)
+        assert_equal(tmp[-3], tmp[-1])
+        self.assertTrue(len(tmp[0]) == 2)
+        #
+        tmp = notmasked_contiguous(a, 1)
+        assert_equal(tmp[0][-1], slice(0, 4, None))
+        self.assertTrue(tmp[1] is None)
+        assert_equal(tmp[2][-1], slice(7, 8, None))
+        assert_equal(tmp[2][-2], slice(0, 6, None))
+
+
+class TestCompressFunctions(TestCase):
+
+    def test_compress_nd(self):
+        # Tests compress_nd
+        x = np.array(list(range(3*4*5))).reshape(3, 4, 5)
+        m = np.zeros((3,4,5)).astype(bool)
+        m[1,1,1] = True
+        x = array(x, mask=m)
+
+        # axis=None
+        a = compress_nd(x)
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[40, 42, 43, 44],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        # axis=0
+        a = compress_nd(x, 0)
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [ 5,  6,  7,  8,  9],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[40, 41, 42, 43, 44],
+                          [45, 46, 47, 48, 49],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+
+        # axis=1
+        a = compress_nd(x, 1)
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[20, 21, 22, 23, 24],
+                          [30, 31, 32, 33, 34],
+                          [35, 36, 37, 38, 39]],
+                         [[40, 41, 42, 43, 44],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (1,))
+        a3 = compress_nd(x, -2)
+        a4 = compress_nd(x, (-2,))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=2
+        a = compress_nd(x, 2)
+        assert_equal(a, [[[ 0, 2,  3,  4],
+                          [ 5, 7,  8,  9],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[20, 22, 23, 24],
+                          [25, 27, 28, 29],
+                          [30, 32, 33, 34],
+                          [35, 37, 38, 39]],
+                         [[40, 42, 43, 44],
+                          [45, 47, 48, 49],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (2,))
+        a3 = compress_nd(x, -1)
+        a4 = compress_nd(x, (-1,))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=(0, 1)
+        a = compress_nd(x, (0, 1))
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[40, 41, 42, 43, 44],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+        a2 = compress_nd(x, (0, -2))
+        assert_equal(a, a2)
+
+        # axis=(1, 2)
+        a = compress_nd(x, (1, 2))
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[20, 22, 23, 24],
+                          [30, 32, 33, 34],
+                          [35, 37, 38, 39]],
+                         [[40, 42, 43, 44],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (-2, 2))
+        a3 = compress_nd(x, (1, -1))
+        a4 = compress_nd(x, (-2, -1))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=(0, 2)
+        a = compress_nd(x, (0, 2))
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [ 5,  7,  8,  9],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[40, 42, 43, 44],
+                          [45, 47, 48, 49],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (0, -1))
+        assert_equal(a, a2)
+
+    def test_compress_rowcols(self):
+        # Tests compress_rowcols
+        x = array(np.arange(9).reshape(3, 3),
+                  mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[4, 5], [7, 8]])
+        assert_equal(compress_rowcols(x, 0), [[3, 4, 5], [6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1), [[1, 2], [4, 5], [7, 8]])
+        x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[0, 2], [6, 8]])
+        assert_equal(compress_rowcols(x, 0), [[0, 1, 2], [6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1), [[0, 2], [3, 5], [6, 8]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[8]])
+        assert_equal(compress_rowcols(x, 0), [[6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1,), [[2], [5], [8]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        assert_equal(compress_rowcols(x).size, 0)
+        assert_equal(compress_rowcols(x, 0).size, 0)
+        assert_equal(compress_rowcols(x, 1).size, 0)
+
+    def test_mask_rowcols(self):
+        # Tests mask_rowcols.
+        x = array(np.arange(9).reshape(3, 3),
+                  mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[1, 1, 1], [1, 0, 0], [1, 0, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[1, 1, 1], [0, 0, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1).mask,
+                     [[1, 0, 0], [1, 0, 0], [1, 0, 0]])
+        x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[0, 1, 0], [1, 1, 1], [0, 1, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[0, 0, 0], [1, 1, 1], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1).mask,
+                     [[0, 1, 0], [0, 1, 0], [0, 1, 0]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[1, 1, 1], [1, 1, 1], [1, 1, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[1, 1, 1], [1, 1, 1], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1,).mask,
+                     [[1, 1, 0], [1, 1, 0], [1, 1, 0]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        self.assertTrue(mask_rowcols(x).all() is masked)
+        self.assertTrue(mask_rowcols(x, 0).all() is masked)
+        self.assertTrue(mask_rowcols(x, 1).all() is masked)
+        self.assertTrue(mask_rowcols(x).mask.all())
+        self.assertTrue(mask_rowcols(x, 0).mask.all())
+        self.assertTrue(mask_rowcols(x, 1).mask.all())
+
+    def test_dot(self):
+        # Tests dot product
+        n = np.arange(1, 7)
+        #
+        m = [1, 0, 0, 0, 0, 0]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 1], [1, 0]])
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[1, 1, 1], [1, 0, 0], [1, 0, 0]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        m = [0, 0, 0, 0, 0, 1]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[0, 1], [1, 1]])
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [1, 1, 1]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        assert_equal(c, dot(a, b))
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        m = [0, 0, 0, 0, 0, 0]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b)
+        assert_equal(c.mask, nomask)
+        c = dot(b, a)
+        assert_equal(c.mask, nomask)
+        #
+        a = masked_array(n, mask=[1, 0, 0, 0, 0, 0]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 1], [0, 0]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[1, 0, 0], [1, 0, 0], [1, 0, 0]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[0, 0], [1, 1]])
+        c = dot(a, b)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [0, 0, 1]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 1, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 0], [1, 1]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [1, 1, 1], [0, 0, 1]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+
+    def test_dot_returns_maskedarray(self):
+        # See gh-6611
+        a = np.eye(3)
+        b = array(a)
+        assert_(type(dot(a, a)) is MaskedArray)
+        assert_(type(dot(a, b)) is MaskedArray)
+        assert_(type(dot(b, a)) is MaskedArray)
+        assert_(type(dot(b, b)) is MaskedArray)
+
+    def test_dot_out(self):
+        a = array(np.eye(3))
+        out = array(np.zeros((3, 3)))
+        res = dot(a, a, out=out)
+        assert_(res is out)
+        assert_equal(a, res)
+
+
+class TestApplyAlongAxis(TestCase):
+    # Tests 2D functions
+    def test_3d(self):
+        a = arange(12.).reshape(2, 2, 3)
+
+        def myfunc(b):
+            return b[1]
+
+        xa = apply_along_axis(myfunc, 2, a)
+        assert_equal(xa, [[1, 4], [7, 10]])
+
+    # Tests kwargs functions
+    def test_3d_kwargs(self):
+        a = arange(12).reshape(2, 2, 3)
+
+        def myfunc(b, offset=0):
+            return b[1+offset]
+
+        xa = apply_along_axis(myfunc, 2, a, offset=1)
+        assert_equal(xa, [[2, 5], [8, 11]])
+
+
+class TestApplyOverAxes(TestCase):
+    # Tests apply_over_axes
+    def test_basic(self):
+        a = arange(24).reshape(2, 3, 4)
+        test = apply_over_axes(np.sum, a, [0, 2])
+        ctrl = np.array([[[60], [92], [124]]])
+        assert_equal(test, ctrl)
+        a[(a % 2).astype(np.bool)] = masked
+        test = apply_over_axes(np.sum, a, [0, 2])
+        ctrl = np.array([[[28], [44], [60]]])
+        assert_equal(test, ctrl)
+
+
+class TestMedian(TestCase):
+    def test_pytype(self):
+        r = np.ma.median([[np.inf, np.inf], [np.inf, np.inf]], axis=-1)
+        assert_equal(r, np.inf)
+
+    def test_non_masked(self):
+        assert_equal(np.ma.median(np.arange(9)), 4.)
+        assert_equal(np.ma.median(range(9)), 4)
+
+    def test_2d(self):
+        # Tests median w/ 2D
+        (n, p) = (101, 30)
+        x = masked_array(np.linspace(-1., 1., n),)
+        x[:10] = x[-10:] = masked
+        z = masked_array(np.empty((n, p), dtype=float))
+        z[:, 0] = x[:]
+        idx = np.arange(len(x))
+        for i in range(1, p):
+            np.random.shuffle(idx)
+            z[:, i] = x[idx]
+        assert_equal(median(z[:, 0]), 0)
+        assert_equal(median(z), 0)
+        assert_equal(median(z, axis=0), np.zeros(p))
+        assert_equal(median(z.T, axis=1), np.zeros(p))
+
+    def test_2d_waxis(self):
+        # Tests median w/ 2D arrays and different axis.
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        assert_equal(median(x), 14.5)
+        assert_equal(median(x, axis=0), [13.5, 14.5, 15.5])
+        assert_equal(median(x, axis=1), [0, 0, 0, 10, 13, 16, 19, 0, 0, 0])
+        assert_equal(median(x, axis=1).mask, [1, 1, 1, 0, 0, 0, 0, 1, 1, 1])
+
+    def test_3d(self):
+        # Tests median w/ 3D
+        x = np.ma.arange(24).reshape(3, 4, 2)
+        x[x % 3 == 0] = masked
+        assert_equal(median(x, 0), [[12, 9], [6, 15], [12, 9], [18, 15]])
+        x.shape = (4, 3, 2)
+        assert_equal(median(x, 0), [[99, 10], [11, 99], [13, 14]])
+        x = np.ma.arange(24).reshape(4, 3, 2)
+        x[x % 5 == 0] = masked
+        assert_equal(median(x, 0), [[12, 10], [8, 9], [16, 17]])
+
+    def test_neg_axis(self):
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        assert_equal(median(x, axis=-1), median(x, axis=1))
+
+    def test_out(self):
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        out = masked_array(np.ones(10))
+        r = median(x, axis=1, out=out)
+        assert_equal(r, out)
+        assert_(type(r) == MaskedArray)
+
+
+class TestCov(TestCase):
+
+    def setUp(self):
+        self.data = array(np.random.rand(12))
+
+    def test_1d_wo_missing(self):
+        # Test cov on 1D variable w/o missing values
+        x = self.data
+        assert_almost_equal(np.cov(x), cov(x))
+        assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(x, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+
+    def test_2d_wo_missing(self):
+        # Test cov on 1 2D variable w/o missing values
+        x = self.data.reshape(3, 4)
+        assert_almost_equal(np.cov(x), cov(x))
+        assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(x, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+
+    def test_1d_w_missing(self):
+        # Test cov 1 1D variable w/missing values
+        x = self.data
+        x[-1] = masked
+        x -= x.mean()
+        nx = x.compressed()
+        assert_almost_equal(np.cov(nx), cov(x))
+        assert_almost_equal(np.cov(nx, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(nx, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+        #
+        try:
+            cov(x, allow_masked=False)
+        except ValueError:
+            pass
+        #
+        # 2 1D variables w/ missing values
+        nx = x[1:-1]
+        assert_almost_equal(np.cov(nx, nx[::-1]), cov(x, x[::-1]))
+        assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False),
+                            cov(x, x[::-1], rowvar=False))
+        assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False, bias=True),
+                            cov(x, x[::-1], rowvar=False, bias=True))
+
+    def test_2d_w_missing(self):
+        # Test cov on 2D variable w/ missing value
+        x = self.data
+        x[-1] = masked
+        x = x.reshape(3, 4)
+        valid = np.logical_not(getmaskarray(x)).astype(int)
+        frac = np.dot(valid, valid.T)
+        xf = (x - x.mean(1)[:, None]).filled(0)
+        assert_almost_equal(cov(x),
+                            np.cov(xf) * (x.shape[1] - 1) / (frac - 1.))
+        assert_almost_equal(cov(x, bias=True),
+                            np.cov(xf, bias=True) * x.shape[1] / frac)
+        frac = np.dot(valid.T, valid)
+        xf = (x - x.mean(0)).filled(0)
+        assert_almost_equal(cov(x, rowvar=False),
+                            (np.cov(xf, rowvar=False) *
+                             (x.shape[0] - 1) / (frac - 1.)))
+        assert_almost_equal(cov(x, rowvar=False, bias=True),
+                            (np.cov(xf, rowvar=False, bias=True) *
+                             x.shape[0] / frac))
+
+
+class catch_warn_mae(clear_and_catch_warnings):
+    """ Context manager to catch, reset warnings in ma.extras module
+    """
+    class_modules = (mae,)
+
+
+class TestCorrcoef(TestCase):
+
+    def setUp(self):
+        self.data = array(np.random.rand(12))
+        self.data2 = array(np.random.rand(12))
+
+    def test_ddof(self):
+        # ddof raises DeprecationWarning
+        x, y = self.data, self.data2
+        expected = np.corrcoef(x)
+        expected2 = np.corrcoef(x, y)
+        with catch_warn_mae():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, x, ddof=-1)
+            warnings.simplefilter("ignore")
+            # ddof has no or negligible effect on the function
+            assert_almost_equal(np.corrcoef(x, ddof=0), corrcoef(x, ddof=0))
+            assert_almost_equal(corrcoef(x, ddof=-1), expected)
+            assert_almost_equal(corrcoef(x, y, ddof=-1), expected2)
+            assert_almost_equal(corrcoef(x, ddof=3), expected)
+            assert_almost_equal(corrcoef(x, y, ddof=3), expected2)
+
+    def test_bias(self):
+        x, y = self.data, self.data2
+        expected = np.corrcoef(x)
+        # bias raises DeprecationWarning
+        with catch_warn_mae():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, x, y, True, False)
+            assert_warns(DeprecationWarning, corrcoef, x, y, True, True)
+            assert_warns(DeprecationWarning, corrcoef, x, bias=False)
+            warnings.simplefilter("ignore")
+            # bias has no or negligible effect on the function
+            assert_almost_equal(corrcoef(x, bias=1), expected)
+
+    def test_1d_wo_missing(self):
+        # Test cov on 1D variable w/o missing values
+        x = self.data
+        assert_almost_equal(np.corrcoef(x), corrcoef(x))
+        assert_almost_equal(np.corrcoef(x, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+
+    def test_2d_wo_missing(self):
+        # Test corrcoef on 1 2D variable w/o missing values
+        x = self.data.reshape(3, 4)
+        assert_almost_equal(np.corrcoef(x), corrcoef(x))
+        assert_almost_equal(np.corrcoef(x, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+
+    def test_1d_w_missing(self):
+        # Test corrcoef 1 1D variable w/missing values
+        x = self.data
+        x[-1] = masked
+        x -= x.mean()
+        nx = x.compressed()
+        assert_almost_equal(np.corrcoef(nx), corrcoef(x))
+        assert_almost_equal(np.corrcoef(nx, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(nx, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+        try:
+            corrcoef(x, allow_masked=False)
+        except ValueError:
+            pass
+        # 2 1D variables w/ missing values
+        nx = x[1:-1]
+        assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1]))
+        assert_almost_equal(np.corrcoef(nx, nx[::-1], rowvar=False),
+                            corrcoef(x, x[::-1], rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            # ddof and bias have no or negligible effect on the function
+            assert_almost_equal(np.corrcoef(nx, nx[::-1]),
+                                corrcoef(x, x[::-1], bias=1))
+            assert_almost_equal(np.corrcoef(nx, nx[::-1]),
+                                corrcoef(x, x[::-1], ddof=2))
+
+    def test_2d_w_missing(self):
+        # Test corrcoef on 2D variable w/ missing value
+        x = self.data
+        x[-1] = masked
+        x = x.reshape(3, 4)
+
+        test = corrcoef(x)
+        control = np.corrcoef(x)
+        assert_almost_equal(test[:-1, :-1], control[:-1, :-1])
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            # ddof and bias have no or negligible effect on the function
+            assert_almost_equal(corrcoef(x, ddof=-2)[:-1, :-1],
+                                control[:-1, :-1])
+            assert_almost_equal(corrcoef(x, ddof=3)[:-1, :-1],
+                                control[:-1, :-1])
+            assert_almost_equal(corrcoef(x, bias=1)[:-1, :-1],
+                                control[:-1, :-1])
+
+
+class TestPolynomial(TestCase):
+    #
+    def test_polyfit(self):
+        # Tests polyfit
+        # On ndarrays
+        x = np.random.rand(10)
+        y = np.random.rand(20).reshape(-1, 2)
+        assert_almost_equal(polyfit(x, y, 3), np.polyfit(x, y, 3))
+        # ON 1D maskedarrays
+        x = x.view(MaskedArray)
+        x[0] = masked
+        y = y.view(MaskedArray)
+        y[0, 0] = y[-1, -1] = masked
+        #
+        (C, R, K, S, D) = polyfit(x, y[:, 0], 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:], y[1:, 0].compressed(), 3,
+                                     full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        (C, R, K, S, D) = polyfit(x, y[:, -1], 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1, -1], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        w = np.random.rand(10) + 1
+        wo = w.copy()
+        xs = x[1:-1]
+        ys = y[1:-1]
+        ws = w[1:-1]
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True, w=w)
+        (c, r, k, s, d) = np.polyfit(xs, ys, 3, full=True, w=ws)
+        assert_equal(w, wo)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+
+    def test_polyfit_with_masked_NaNs(self):
+        x = np.random.rand(10)
+        y = np.random.rand(20).reshape(-1, 2)
+
+        x[0] = np.nan
+        y[-1,-1] = np.nan
+        x = x.view(MaskedArray)
+        y = y.view(MaskedArray)
+        x[0] = masked
+        y[-1,-1] = masked
+
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+
+
+class TestArraySetOps(TestCase):
+
+    def test_unique_onlist(self):
+        # Test unique on list
+        data = [1, 1, 1, 2, 2, 3]
+        test = unique(data, return_index=True, return_inverse=True)
+        self.assertTrue(isinstance(test[0], MaskedArray))
+        assert_equal(test[0], masked_array([1, 2, 3], mask=[0, 0, 0]))
+        assert_equal(test[1], [0, 3, 5])
+        assert_equal(test[2], [0, 0, 0, 1, 1, 2])
+
+    def test_unique_onmaskedarray(self):
+        # Test unique on masked data w/use_mask=True
+        data = masked_array([1, 1, 1, 2, 2, 3], mask=[0, 0, 1, 0, 1, 0])
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1]))
+        assert_equal(test[1], [0, 3, 5, 2])
+        assert_equal(test[2], [0, 0, 3, 1, 3, 2])
+        #
+        data.fill_value = 3
+        data = masked_array(data=[1, 1, 1, 2, 2, 3],
+                            mask=[0, 0, 1, 0, 1, 0], fill_value=3)
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1]))
+        assert_equal(test[1], [0, 3, 5, 2])
+        assert_equal(test[2], [0, 0, 3, 1, 3, 2])
+
+    def test_unique_allmasked(self):
+        # Test all masked
+        data = masked_array([1, 1, 1], mask=True)
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, ], mask=[True]))
+        assert_equal(test[1], [0])
+        assert_equal(test[2], [0, 0, 0])
+        #
+        # Test masked
+        data = masked
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array(masked))
+        assert_equal(test[1], [0])
+        assert_equal(test[2], [0])
+
+    def test_ediff1d(self):
+        # Tests mediff1d
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        control = array([1, 1, 1, 4], mask=[1, 0, 0, 1])
+        test = ediff1d(x)
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_tobegin(self):
+        # Test ediff1d w/ to_begin
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_begin=masked)
+        control = array([0, 1, 1, 1, 4], mask=[1, 1, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_begin=[1, 2, 3])
+        control = array([1, 2, 3, 1, 1, 1, 4], mask=[0, 0, 0, 1, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_toend(self):
+        # Test ediff1d w/ to_end
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_end=masked)
+        control = array([1, 1, 1, 4, 0], mask=[1, 0, 0, 1, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=[1, 2, 3])
+        control = array([1, 1, 1, 4, 1, 2, 3], mask=[1, 0, 0, 1, 0, 0, 0])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_tobegin_toend(self):
+        # Test ediff1d w/ to_begin and to_end
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_end=masked, to_begin=masked)
+        control = array([0, 1, 1, 1, 4, 0], mask=[1, 1, 0, 0, 1, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=[1, 2, 3], to_begin=masked)
+        control = array([0, 1, 1, 1, 4, 1, 2, 3],
+                        mask=[1, 1, 0, 0, 1, 0, 0, 0])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_ndarray(self):
+        # Test ediff1d w/ a ndarray
+        x = np.arange(5)
+        test = ediff1d(x)
+        control = array([1, 1, 1, 1], mask=[0, 0, 0, 0])
+        assert_equal(test, control)
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=masked, to_begin=masked)
+        control = array([0, 1, 1, 1, 1, 0], mask=[1, 0, 0, 0, 0, 1])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_intersect1d(self):
+        # Test intersect1d
+        x = array([1, 3, 3, 3], mask=[0, 0, 0, 1])
+        y = array([3, 1, 1, 1], mask=[0, 0, 0, 1])
+        test = intersect1d(x, y)
+        control = array([1, 3, -1], mask=[0, 0, 1])
+        assert_equal(test, control)
+
+    def test_setxor1d(self):
+        # Test setxor1d
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = setxor1d(a, b)
+        assert_equal(test, array([3, 4, 7]))
+        #
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = [1, 2, 3, 4, 5]
+        test = setxor1d(a, b)
+        assert_equal(test, array([3, 4, 7, -1], mask=[0, 0, 0, 1]))
+        #
+        a = array([1, 2, 3])
+        b = array([6, 5, 4])
+        test = setxor1d(a, b)
+        assert_(isinstance(test, MaskedArray))
+        assert_equal(test, [1, 2, 3, 4, 5, 6])
+        #
+        a = array([1, 8, 2, 3], mask=[0, 1, 0, 0])
+        b = array([6, 5, 4, 8], mask=[0, 0, 0, 1])
+        test = setxor1d(a, b)
+        assert_(isinstance(test, MaskedArray))
+        assert_equal(test, [1, 2, 3, 4, 5, 6])
+        #
+        assert_array_equal([], setxor1d([], []))
+
+    def test_in1d(self):
+        # Test in1d
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = in1d(a, b)
+        assert_equal(test, [True, True, True, False, True])
+        #
+        a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 5, -1], mask=[0, 0, 1])
+        test = in1d(a, b)
+        assert_equal(test, [True, True, False, True, True])
+        #
+        assert_array_equal([], in1d([], []))
+
+    def test_in1d_invert(self):
+        # Test in1d's invert parameter
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+        a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 5, -1], mask=[0, 0, 1])
+        assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+        assert_array_equal([], in1d([], [], invert=True))
+
+    def test_union1d(self):
+        # Test union1d
+        a = array([1, 2, 5, 7, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = union1d(a, b)
+        control = array([1, 2, 3, 4, 5, 7, -1], mask=[0, 0, 0, 0, 0, 0, 1])
+        assert_equal(test, control)
+        #
+        assert_array_equal([], union1d([], []))
+
+    def test_setdiff1d(self):
+        # Test setdiff1d
+        a = array([6, 5, 4, 7, 7, 1, 2, 1], mask=[0, 0, 0, 0, 0, 0, 0, 1])
+        b = array([2, 4, 3, 3, 2, 1, 5])
+        test = setdiff1d(a, b)
+        assert_equal(test, array([6, 7, -1], mask=[0, 0, 1]))
+        #
+        a = arange(10)
+        b = arange(8)
+        assert_equal(setdiff1d(a, b), array([8, 9]))
+        a = array([], np.uint32, mask=[])
+        assert_equal(setdiff1d(a, []).dtype, np.uint32)
+
+    def test_setdiff1d_char_array(self):
+        # Test setdiff1d_charray
+        a = np.array(['a', 'b', 'c'])
+        b = np.array(['a', 'b', 's'])
+        assert_array_equal(setdiff1d(a, b), np.array(['c']))
+
+
+class TestShapeBase(TestCase):
+
+    def test_atleast2d(self):
+        # Test atleast_2d
+        a = masked_array([0, 1, 2], mask=[0, 1, 0])
+        b = atleast_2d(a)
+        assert_equal(b.shape, (1, 3))
+        assert_equal(b.mask.shape, b.data.shape)
+        assert_equal(a.shape, (3,))
+        assert_equal(a.mask.shape, a.data.shape)
+
+    def test_shape_scalar(self):
+        # the atleast and diagflat function should work with scalars
+        # GitHub issue #3367
+        b = atleast_1d(1.0)
+        assert_equal(b.shape, (1, ))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = atleast_2d(1.0)
+        assert_equal(b.shape, (1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = atleast_3d(1.0)
+        assert_equal(b.shape, (1, 1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = diagflat(1.0)
+        assert_equal(b.shape, (1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
new file mode 100644
index 0000000000..574c652710
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
@@ -0,0 +1,516 @@
+# pylint: disable-msg=W0611, W0612, W0511,R0201
+"""Tests suite for mrecords.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import pickle
+
+import numpy as np
+import numpy.ma as ma
+from numpy import recarray
+from numpy.compat import asbytes, asbytes_nested
+from numpy.ma import masked, nomask
+from numpy.testing import TestCase, run_module_suite, temppath
+from numpy.core.records import (
+    fromrecords as recfromrecords, fromarrays as recfromarrays
+    )
+from numpy.ma.mrecords import (
+    MaskedRecords, mrecarray, fromarrays, fromtextfile, fromrecords,
+    addfield
+    )
+from numpy.ma.testutils import (
+    assert_, assert_equal,
+    assert_equal_records,
+    )
+
+
+class TestMRecords(TestCase):
+    # Base test class for MaskedArrays.
+    def __init__(self, *args, **kwds):
+        TestCase.__init__(self, *args, **kwds)
+        self.setup()
+
+    def setup(self):
+        # Generic setup
+        ilist = [1, 2, 3, 4, 5]
+        flist = [1.1, 2.2, 3.3, 4.4, 5.5]
+        slist = asbytes_nested(['one', 'two', 'three', 'four', 'five'])
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mask = [0, 1, 0, 0, 1]
+        self.base = ma.array(list(zip(ilist, flist, slist)),
+                             mask=mask, dtype=ddtype)
+
+    def test_byview(self):
+        # Test creation by view
+        base = self.base
+        mbase = base.view(mrecarray)
+        assert_equal(mbase.recordmask, base.recordmask)
+        assert_equal_records(mbase._mask, base._mask)
+        assert_(isinstance(mbase._data, recarray))
+        assert_equal_records(mbase._data, base._data.view(recarray))
+        for field in ('a', 'b', 'c'):
+            assert_equal(base[field], mbase[field])
+        assert_equal_records(mbase.view(mrecarray), mbase)
+
+    def test_get(self):
+        # Tests fields retrieval
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # As fields..........
+        for field in ('a', 'b', 'c'):
+            assert_equal(getattr(mbase, field), mbase[field])
+            assert_equal(base[field], mbase[field])
+        # as elements .......
+        mbase_first = mbase[0]
+        assert_(isinstance(mbase_first, mrecarray))
+        assert_equal(mbase_first.dtype, mbase.dtype)
+        assert_equal(mbase_first.tolist(), (1, 1.1, asbytes('one')))
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_first.recordmask, nomask)
+        assert_equal(mbase_first._mask.item(), (False, False, False))
+        assert_equal(mbase_first['a'], mbase['a'][0])
+        mbase_last = mbase[-1]
+        assert_(isinstance(mbase_last, mrecarray))
+        assert_equal(mbase_last.dtype, mbase.dtype)
+        assert_equal(mbase_last.tolist(), (None, None, None))
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_last.recordmask, True)
+        assert_equal(mbase_last._mask.item(), (True, True, True))
+        assert_equal(mbase_last['a'], mbase['a'][-1])
+        assert_((mbase_last['a'] is masked))
+        # as slice ..........
+        mbase_sl = mbase[:2]
+        assert_(isinstance(mbase_sl, mrecarray))
+        assert_equal(mbase_sl.dtype, mbase.dtype)
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_sl.recordmask, [0, 1])
+        assert_equal_records(mbase_sl.mask,
+                             np.array([(False, False, False),
+                                       (True, True, True)],
+                                      dtype=mbase._mask.dtype))
+        assert_equal_records(mbase_sl, base[:2].view(mrecarray))
+        for field in ('a', 'b', 'c'):
+            assert_equal(getattr(mbase_sl, field), base[:2][field])
+
+    def test_set_fields(self):
+        # Tests setting fields.
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase = mbase.copy()
+        mbase.fill_value = (999999, 1e20, 'N/A')
+        # Change the data, the mask should be conserved
+        mbase.a._data[:] = 5
+        assert_equal(mbase['a']._data, [5, 5, 5, 5, 5])
+        assert_equal(mbase['a']._mask, [0, 1, 0, 0, 1])
+        # Change the elements, and the mask will follow
+        mbase.a = 1
+        assert_equal(mbase['a']._data, [1]*5)
+        assert_equal(ma.getmaskarray(mbase['a']), [0]*5)
+        # Use to be _mask, now it's recordmask
+        assert_equal(mbase.recordmask, [False]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 0),
+                               (0, 1, 1),
+                               (0, 0, 0),
+                               (0, 0, 0),
+                               (0, 1, 1)],
+                              dtype=bool))
+        # Set a field to mask ........................
+        mbase.c = masked
+        # Use to be mask, and now it's still mask !
+        assert_equal(mbase.c.mask, [1]*5)
+        assert_equal(mbase.c.recordmask, [1]*5)
+        assert_equal(ma.getmaskarray(mbase['c']), [1]*5)
+        assert_equal(ma.getdata(mbase['c']), [asbytes('N/A')]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 1),
+                               (0, 1, 1),
+                               (0, 0, 1),
+                               (0, 0, 1),
+                               (0, 1, 1)],
+                              dtype=bool))
+        # Set fields by slices .......................
+        mbase = base.view(mrecarray).copy()
+        mbase.a[3:] = 5
+        assert_equal(mbase.a, [1, 2, 3, 5, 5])
+        assert_equal(mbase.a._mask, [0, 1, 0, 0, 0])
+        mbase.b[3:] = masked
+        assert_equal(mbase.b, base['b'])
+        assert_equal(mbase.b._mask, [0, 1, 0, 1, 1])
+        # Set fields globally..........................
+        ndtype = [('alpha', '|S1'), ('num', int)]
+        data = ma.array([('a', 1), ('b', 2), ('c', 3)], dtype=ndtype)
+        rdata = data.view(MaskedRecords)
+        val = ma.array([10, 20, 30], mask=[1, 0, 0])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            rdata['num'] = val
+            assert_equal(rdata.num, val)
+            assert_equal(rdata.num.mask, [1, 0, 0])
+
+    def test_set_fields_mask(self):
+        # Tests setting the mask of a field.
+        base = self.base.copy()
+        # This one has already a mask....
+        mbase = base.view(mrecarray)
+        mbase['a'][-2] = masked
+        assert_equal(mbase.a, [1, 2, 3, 4, 5])
+        assert_equal(mbase.a._mask, [0, 1, 0, 1, 1])
+        # This one has not yet
+        mbase = fromarrays([np.arange(5), np.random.rand(5)],
+                           dtype=[('a', int), ('b', float)])
+        mbase['a'][-2] = masked
+        assert_equal(mbase.a, [0, 1, 2, 3, 4])
+        assert_equal(mbase.a._mask, [0, 0, 0, 1, 0])
+
+    def test_set_mask(self):
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # Set the mask to True .......................
+        mbase.mask = masked
+        assert_equal(ma.getmaskarray(mbase['b']), [1]*5)
+        assert_equal(mbase['a']._mask, mbase['b']._mask)
+        assert_equal(mbase['a']._mask, mbase['c']._mask)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(1, 1, 1)]*5, dtype=bool))
+        # Delete the mask ............................
+        mbase.mask = nomask
+        assert_equal(ma.getmaskarray(mbase['c']), [0]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 0)]*5, dtype=bool))
+
+    def test_set_mask_fromarray(self):
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # Sets the mask w/ an array
+        mbase.mask = [1, 0, 0, 0, 1]
+        assert_equal(mbase.a.mask, [1, 0, 0, 0, 1])
+        assert_equal(mbase.b.mask, [1, 0, 0, 0, 1])
+        assert_equal(mbase.c.mask, [1, 0, 0, 0, 1])
+        # Yay, once more !
+        mbase.mask = [0, 0, 0, 0, 1]
+        assert_equal(mbase.a.mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.b.mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.c.mask, [0, 0, 0, 0, 1])
+
+    def test_set_mask_fromfields(self):
+        mbase = self.base.copy().view(mrecarray)
+
+        nmask = np.array(
+            [(0, 1, 0), (0, 1, 0), (1, 0, 1), (1, 0, 1), (0, 0, 0)],
+            dtype=[('a', bool), ('b', bool), ('c', bool)])
+        mbase.mask = nmask
+        assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
+        assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
+        assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
+        # Reinitalizes and redo
+        mbase.mask = False
+        mbase.fieldmask = nmask
+        assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
+        assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
+        assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
+
+    def test_set_elements(self):
+        base = self.base.copy()
+        # Set an element to mask .....................
+        mbase = base.view(mrecarray).copy()
+        mbase[-2] = masked
+        assert_equal(
+            mbase._mask.tolist(),
+            np.array([(0, 0, 0), (1, 1, 1), (0, 0, 0), (1, 1, 1), (1, 1, 1)],
+                     dtype=bool))
+        # Used to be mask, now it's recordmask!
+        assert_equal(mbase.recordmask, [0, 1, 0, 1, 1])
+        # Set slices .................................
+        mbase = base.view(mrecarray).copy()
+        mbase[:2] = (5, 5, 5)
+        assert_equal(mbase.a._data, [5, 5, 3, 4, 5])
+        assert_equal(mbase.a._mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.b._data, [5., 5., 3.3, 4.4, 5.5])
+        assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.c._data,
+                     asbytes_nested(['5', '5', 'three', 'four', 'five']))
+        assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
+
+        mbase = base.view(mrecarray).copy()
+        mbase[:2] = masked
+        assert_equal(mbase.a._data, [1, 2, 3, 4, 5])
+        assert_equal(mbase.a._mask, [1, 1, 0, 0, 1])
+        assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 4.4, 5.5])
+        assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
+        assert_equal(mbase.c._data,
+                     asbytes_nested(['one', 'two', 'three', 'four', 'five']))
+        assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
+
+    def test_setslices_hardmask(self):
+        # Tests setting slices w/ hardmask.
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase.harden_mask()
+        try:
+            mbase[-2:] = (5, 5, 5)
+            assert_equal(mbase.a._data, [1, 2, 3, 5, 5])
+            assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 5, 5.5])
+            assert_equal(mbase.c._data,
+                         asbytes_nested(['one', 'two', 'three', '5', 'five']))
+            assert_equal(mbase.a._mask, [0, 1, 0, 0, 1])
+            assert_equal(mbase.b._mask, mbase.a._mask)
+            assert_equal(mbase.b._mask, mbase.c._mask)
+        except NotImplementedError:
+            # OK, not implemented yet...
+            pass
+        except AssertionError:
+            raise
+        else:
+            raise Exception("Flexible hard masks should be supported !")
+        # Not using a tuple should crash
+        try:
+            mbase[-2:] = 3
+        except (NotImplementedError, TypeError):
+            pass
+        else:
+            raise TypeError("Should have expected a readable buffer object!")
+
+    def test_hardmask(self):
+        # Test hardmask
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase.harden_mask()
+        self.assertTrue(mbase._hardmask)
+        mbase.mask = nomask
+        assert_equal_records(mbase._mask, base._mask)
+        mbase.soften_mask()
+        self.assertTrue(not mbase._hardmask)
+        mbase.mask = nomask
+        # So, the mask of a field is no longer set to nomask...
+        assert_equal_records(mbase._mask,
+                             ma.make_mask_none(base.shape, base.dtype))
+        self.assertTrue(ma.make_mask(mbase['b']._mask) is nomask)
+        assert_equal(mbase['a']._mask, mbase['b']._mask)
+
+    def test_pickling(self):
+        # Test pickling
+        base = self.base.copy()
+        mrec = base.view(mrecarray)
+        _ = pickle.dumps(mrec)
+        mrec_ = pickle.loads(_)
+        assert_equal(mrec_.dtype, mrec.dtype)
+        assert_equal_records(mrec_._data, mrec._data)
+        assert_equal(mrec_._mask, mrec._mask)
+        assert_equal_records(mrec_._mask, mrec._mask)
+
+    def test_filled(self):
+        # Test filling the array
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(99999, 99999., 'N/A'))
+        mrecfilled = mrec.filled()
+        assert_equal(mrecfilled['a'], np.array((1, 2, 99999), dtype=int))
+        assert_equal(mrecfilled['b'], np.array((1.1, 2.2, 99999.),
+                                               dtype=float))
+        assert_equal(mrecfilled['c'], np.array(('one', 'two', 'N/A'),
+                                               dtype='|S8'))
+
+    def test_tolist(self):
+        # Test tolist.
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[1, 0, 0], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(99999, 99999., 'N/A'))
+
+        assert_equal(mrec.tolist(),
+                     [(1, 1.1, None), (2, 2.2, asbytes('two')),
+                      (None, None, asbytes('three'))])
+
+    def test_withnames(self):
+        # Test the creation w/ format and names
+        x = mrecarray(1, formats=float, names='base')
+        x[0]['base'] = 10
+        assert_equal(x['base'][0], 10)
+
+    def test_exotic_formats(self):
+        # Test that 'exotic' formats are processed properly
+        easy = mrecarray(1, dtype=[('i', int), ('s', '|S8'), ('f', float)])
+        easy[0] = masked
+        assert_equal(easy.filled(1).item(), (1, asbytes('1'), 1.))
+
+        solo = mrecarray(1, dtype=[('f0', '<f8', (2, 2))])
+        solo[0] = masked
+        assert_equal(solo.filled(1).item(),
+                     np.array((1,), dtype=solo.dtype).item())
+
+        mult = mrecarray(2, dtype="i4, (2,3)float, float")
+        mult[0] = masked
+        mult[1] = (1, 1, 1)
+        mult.filled(0)
+        assert_equal_records(mult.filled(0),
+                             np.array([(0, 0, 0), (1, 1, 1)],
+                                      dtype=mult.dtype))
+
+
+class TestView(TestCase):
+
+    def setUp(self):
+        (a, b) = (np.arange(10), np.random.rand(10))
+        ndtype = [('a', np.float), ('b', np.float)]
+        arr = np.array(list(zip(a, b)), dtype=ndtype)
+
+        mrec = fromarrays([a, b], dtype=ndtype, fill_value=(-9., -99.))
+        mrec.mask[3] = (False, True)
+        self.data = (mrec, a, b, arr)
+
+    def test_view_by_itself(self):
+        (mrec, a, b, arr) = self.data
+        test = mrec.view()
+        self.assertTrue(isinstance(test, MaskedRecords))
+        assert_equal_records(test, mrec)
+        assert_equal_records(test._mask, mrec._mask)
+
+    def test_view_simple_dtype(self):
+        (mrec, a, b, arr) = self.data
+        ntype = (np.float, 2)
+        test = mrec.view(ntype)
+        self.assertTrue(isinstance(test, ma.MaskedArray))
+        assert_equal(test, np.array(list(zip(a, b)), dtype=np.float))
+        self.assertTrue(test[3, 1] is ma.masked)
+
+    def test_view_flexible_type(self):
+        (mrec, a, b, arr) = self.data
+        alttype = [('A', np.float), ('B', np.float)]
+        test = mrec.view(alttype)
+        self.assertTrue(isinstance(test, MaskedRecords))
+        assert_equal_records(test, arr.view(alttype))
+        self.assertTrue(test['B'][3] is masked)
+        assert_equal(test.dtype, np.dtype(alttype))
+        self.assertTrue(test._fill_value is None)
+
+
+##############################################################################
+class TestMRecordsImport(TestCase):
+    # Base test class for MaskedArrays.
+    def __init__(self, *args, **kwds):
+        TestCase.__init__(self, *args, **kwds)
+        self.setup()
+
+    def setup(self):
+        # Generic setup
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(list(map(asbytes, ['one', 'two', 'three'])),
+                      mask=[0, 0, 1], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(asbytes('99999'), asbytes('99999.'),
+                                      asbytes('N/A')))
+        nrec = recfromarrays((_a._data, _b._data, _c._data), dtype=ddtype)
+        self.data = (mrec, nrec, ddtype)
+
+    def test_fromarrays(self):
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
+        (mrec, nrec, _) = self.data
+        for (f, l) in zip(('a', 'b', 'c'), (_a, _b, _c)):
+            assert_equal(getattr(mrec, f)._mask, l._mask)
+        # One record only
+        _x = ma.array([1, 1.1, 'one'], mask=[1, 0, 0],)
+        assert_equal_records(fromarrays(_x, dtype=mrec.dtype), mrec[0])
+
+    def test_fromrecords(self):
+        # Test construction from records.
+        (mrec, nrec, ddtype) = self.data
+        #......
+        palist = [(1, 'abc', 3.7000002861022949, 0),
+                  (2, 'xy', 6.6999998092651367, 1),
+                  (0, ' ', 0.40000000596046448, 0)]
+        pa = recfromrecords(palist, names='c1, c2, c3, c4')
+        mpa = fromrecords(palist, names='c1, c2, c3, c4')
+        assert_equal_records(pa, mpa)
+        #.....
+        _mrec = fromrecords(nrec)
+        assert_equal(_mrec.dtype, mrec.dtype)
+        for field in _mrec.dtype.names:
+            assert_equal(getattr(_mrec, field), getattr(mrec._data, field))
+
+        _mrec = fromrecords(nrec.tolist(), names='c1,c2,c3')
+        assert_equal(_mrec.dtype, [('c1', int), ('c2', float), ('c3', '|S5')])
+        for (f, n) in zip(('c1', 'c2', 'c3'), ('a', 'b', 'c')):
+            assert_equal(getattr(_mrec, f), getattr(mrec._data, n))
+
+        _mrec = fromrecords(mrec)
+        assert_equal(_mrec.dtype, mrec.dtype)
+        assert_equal_records(_mrec._data, mrec.filled())
+        assert_equal_records(_mrec._mask, mrec._mask)
+
+    def test_fromrecords_wmask(self):
+        # Tests construction from records w/ mask.
+        (mrec, nrec, ddtype) = self.data
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=[0, 1, 0,])
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), [(0, 0, 0), (1, 1, 1), (0, 0, 0)])
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=True)
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), [(1, 1, 1), (1, 1, 1), (1, 1, 1)])
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=mrec._mask)
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype,
+                            mask=mrec._mask.tolist())
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
+
+    def test_fromtextfile(self):
+        # Tests reading from a text file.
+        fcontent = (
+"""#
+'One (S)','Two (I)','Three (F)','Four (M)','Five (-)','Six (C)'
+'strings',1,1.0,'mixed column',,1
+'with embedded "double quotes"',2,2.0,1.0,,1
+'strings',3,3.0E5,3,,1
+'strings',4,-1e-10,,,1
+""")
+        with temppath() as path:
+            with open(path, 'w') as f:
+                f.write(fcontent)
+            mrectxt = fromtextfile(path, delimitor=',', varnames='ABCDEFG')
+        self.assertTrue(isinstance(mrectxt, MaskedRecords))
+        assert_equal(mrectxt.F, [1, 1, 1, 1])
+        assert_equal(mrectxt.E._mask, [1, 1, 1, 1])
+        assert_equal(mrectxt.C, [1, 2, 3.e+5, -1e-10])
+
+    def test_addfield(self):
+        # Tests addfield
+        (mrec, nrec, ddtype) = self.data
+        (d, m) = ([100, 200, 300], [1, 0, 0])
+        mrec = addfield(mrec, ma.array(d, mask=m))
+        assert_equal(mrec.f3, d)
+        assert_equal(mrec.f3._mask, m)
+
+
+def test_record_array_with_object_field():
+    # Trac #1839
+    y = ma.masked_array(
+        [(1, '2'), (3, '4')],
+        mask=[(0, 0), (0, 1)],
+        dtype=[('a', int), ('b', np.object)])
+    # getting an item used to fail
+    y[1]
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
new file mode 100644
index 0000000000..6ce29cc030
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
@@ -0,0 +1,821 @@
+from __future__ import division, absolute_import, print_function
+
+from functools import reduce
+
+import numpy as np
+import numpy.core.umath as umath
+import numpy.core.fromnumeric as fromnumeric
+from numpy.testing import TestCase, run_module_suite, assert_
+from numpy.ma.testutils import assert_array_equal
+from numpy.ma import (
+    MaskType, MaskedArray, absolute, add, all, allclose, allequal, alltrue,
+    arange, arccos, arcsin, arctan, arctan2, array, average, choose,
+    concatenate, conjugate, cos, cosh, count, divide, equal, exp, filled,
+    getmask, greater, greater_equal, inner, isMaskedArray, less,
+    less_equal, log, log10, make_mask, masked, masked_array, masked_equal,
+    masked_greater, masked_greater_equal, masked_inside, masked_less,
+    masked_less_equal, masked_not_equal, masked_outside,
+    masked_print_option, masked_values, masked_where, maximum, minimum,
+    multiply, nomask, nonzero, not_equal, ones, outer, product, put, ravel,
+    repeat, resize, shape, sin, sinh, sometrue, sort, sqrt, subtract, sum,
+    take, tan, tanh, transpose, where, zeros,
+    )
+
+pi = np.pi
+
+
+def eq(v, w, msg=''):
+    result = allclose(v, w)
+    if not result:
+        print("Not eq:%s\n%s\n----%s" % (msg, str(v), str(w)))
+    return result
+
+
+class TestMa(TestCase):
+
+    def setUp(self):
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = array(x, mask=m1)
+        ym = array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        s = x.shape
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf, s)
+
+    def test_testBasic1d(self):
+        # Test of basic array creation and properties in 1 dimension.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertFalse(isMaskedArray(x))
+        self.assertTrue(isMaskedArray(xm))
+        self.assertEqual(shape(xm), s)
+        self.assertEqual(xm.shape, s)
+        self.assertEqual(xm.dtype, x.dtype)
+        self.assertEqual(xm.size, reduce(lambda x, y:x * y, s))
+        self.assertEqual(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+        self.assertTrue(eq(xm, xf))
+        self.assertTrue(eq(filled(xm, 1.e20), xf))
+        self.assertTrue(eq(x, xm))
+
+    def test_testBasic2d(self):
+        # Test of basic array creation and properties in 2 dimensions.
+        for s in [(4, 3), (6, 2)]:
+            (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+
+            self.assertFalse(isMaskedArray(x))
+            self.assertTrue(isMaskedArray(xm))
+            self.assertEqual(shape(xm), s)
+            self.assertEqual(xm.shape, s)
+            self.assertEqual(xm.size, reduce(lambda x, y:x * y, s))
+            self.assertEqual(count(xm),
+                             len(m1) - reduce(lambda x, y:x + y, m1))
+            self.assertTrue(eq(xm, xf))
+            self.assertTrue(eq(filled(xm, 1.e20), xf))
+            self.assertTrue(eq(x, xm))
+            self.setUp()
+
+    def test_testArithmetic(self):
+        # Test of basic arithmetic.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        a2d = array([[1, 2], [0, 4]])
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        self.assertTrue(eq(a2d * a2d, a2d * a2dm))
+        self.assertTrue(eq(a2d + a2d, a2d + a2dm))
+        self.assertTrue(eq(a2d - a2d, a2d - a2dm))
+        for s in [(12,), (4, 3), (2, 6)]:
+            x = x.reshape(s)
+            y = y.reshape(s)
+            xm = xm.reshape(s)
+            ym = ym.reshape(s)
+            xf = xf.reshape(s)
+            self.assertTrue(eq(-x, -xm))
+            self.assertTrue(eq(x + y, xm + ym))
+            self.assertTrue(eq(x - y, xm - ym))
+            self.assertTrue(eq(x * y, xm * ym))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(x / y, xm / ym))
+            self.assertTrue(eq(a10 + y, a10 + ym))
+            self.assertTrue(eq(a10 - y, a10 - ym))
+            self.assertTrue(eq(a10 * y, a10 * ym))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(a10 / y, a10 / ym))
+            self.assertTrue(eq(x + a10, xm + a10))
+            self.assertTrue(eq(x - a10, xm - a10))
+            self.assertTrue(eq(x * a10, xm * a10))
+            self.assertTrue(eq(x / a10, xm / a10))
+            self.assertTrue(eq(x ** 2, xm ** 2))
+            self.assertTrue(eq(abs(x) ** 2.5, abs(xm) ** 2.5))
+            self.assertTrue(eq(x ** y, xm ** ym))
+            self.assertTrue(eq(np.add(x, y), add(xm, ym)))
+            self.assertTrue(eq(np.subtract(x, y), subtract(xm, ym)))
+            self.assertTrue(eq(np.multiply(x, y), multiply(xm, ym)))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(np.divide(x, y), divide(xm, ym)))
+
+    def test_testMixedArithmetic(self):
+        na = np.array([1])
+        ma = array([1])
+        self.assertTrue(isinstance(na + ma, MaskedArray))
+        self.assertTrue(isinstance(ma + na, MaskedArray))
+
+    def test_testUfuncs1(self):
+        # Test various functions such as sin, cos.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertTrue(eq(np.cos(x), cos(xm)))
+        self.assertTrue(eq(np.cosh(x), cosh(xm)))
+        self.assertTrue(eq(np.sin(x), sin(xm)))
+        self.assertTrue(eq(np.sinh(x), sinh(xm)))
+        self.assertTrue(eq(np.tan(x), tan(xm)))
+        self.assertTrue(eq(np.tanh(x), tanh(xm)))
+        with np.errstate(divide='ignore', invalid='ignore'):
+            self.assertTrue(eq(np.sqrt(abs(x)), sqrt(xm)))
+            self.assertTrue(eq(np.log(abs(x)), log(xm)))
+            self.assertTrue(eq(np.log10(abs(x)), log10(xm)))
+        self.assertTrue(eq(np.exp(x), exp(xm)))
+        self.assertTrue(eq(np.arcsin(z), arcsin(zm)))
+        self.assertTrue(eq(np.arccos(z), arccos(zm)))
+        self.assertTrue(eq(np.arctan(z), arctan(zm)))
+        self.assertTrue(eq(np.arctan2(x, y), arctan2(xm, ym)))
+        self.assertTrue(eq(np.absolute(x), absolute(xm)))
+        self.assertTrue(eq(np.equal(x, y), equal(xm, ym)))
+        self.assertTrue(eq(np.not_equal(x, y), not_equal(xm, ym)))
+        self.assertTrue(eq(np.less(x, y), less(xm, ym)))
+        self.assertTrue(eq(np.greater(x, y), greater(xm, ym)))
+        self.assertTrue(eq(np.less_equal(x, y), less_equal(xm, ym)))
+        self.assertTrue(eq(np.greater_equal(x, y), greater_equal(xm, ym)))
+        self.assertTrue(eq(np.conjugate(x), conjugate(xm)))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((xm, ym))))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((x, y))))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((xm, y))))
+        self.assertTrue(eq(np.concatenate((x, y, x)), concatenate((x, ym, x))))
+
+    def test_xtestCount(self):
+        # Test count
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        self.assertEqual(3, count(ott))
+        self.assertEqual(1, count(1))
+        self.assertTrue(eq(0, array(1, mask=[1])))
+        ott = ott.reshape((2, 2))
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        assert_(isinstance(count(ott, 0), np.ndarray))
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        self.assertTrue(eq(3, count(ott)))
+        assert_(getmask(count(ott, 0)) is nomask)
+        self.assertTrue(eq([1, 2], count(ott, 0)))
+
+    def test_testMinMax(self):
+        # Test minimum and maximum.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        xr = np.ravel(x)  # max doesn't work if shaped
+        xmr = ravel(xm)
+
+        # true because of careful selection of data
+        self.assertTrue(eq(max(xr), maximum(xmr)))
+        self.assertTrue(eq(min(xr), minimum(xmr)))
+
+    def test_testAddSumProd(self):
+        # Test add, sum, product.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertTrue(eq(np.add.reduce(x), add.reduce(x)))
+        self.assertTrue(eq(np.add.accumulate(x), add.accumulate(x)))
+        self.assertTrue(eq(4, sum(array(4), axis=0)))
+        self.assertTrue(eq(4, sum(array(4), axis=0)))
+        self.assertTrue(eq(np.sum(x, axis=0), sum(x, axis=0)))
+        self.assertTrue(eq(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0)))
+        self.assertTrue(eq(np.sum(x, 0), sum(x, 0)))
+        self.assertTrue(eq(np.product(x, axis=0), product(x, axis=0)))
+        self.assertTrue(eq(np.product(x, 0), product(x, 0)))
+        self.assertTrue(eq(np.product(filled(xm, 1), axis=0),
+                           product(xm, axis=0)))
+        if len(s) > 1:
+            self.assertTrue(eq(np.concatenate((x, y), 1),
+                               concatenate((xm, ym), 1)))
+            self.assertTrue(eq(np.add.reduce(x, 1), add.reduce(x, 1)))
+            self.assertTrue(eq(np.sum(x, 1), sum(x, 1)))
+            self.assertTrue(eq(np.product(x, 1), product(x, 1)))
+
+    def test_testCI(self):
+        # Test of conversions and indexing
+        x1 = np.array([1, 2, 4, 3])
+        x2 = array(x1, mask=[1, 0, 0, 0])
+        x3 = array(x1, mask=[0, 1, 0, 1])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        assert_(eq(np.sort(x1), sort(x2, fill_value=0)))
+        # tests of indexing
+        assert_(type(x2[1]) is type(x1[1]))
+        assert_(x1[1] == x2[1])
+        assert_(x2[0] is masked)
+        assert_(eq(x1[2], x2[2]))
+        assert_(eq(x1[2:5], x2[2:5]))
+        assert_(eq(x1[:], x2[:]))
+        assert_(eq(x1[1:], x3[1:]))
+        x1[2] = 9
+        x2[2] = 9
+        assert_(eq(x1, x2))
+        x1[1:3] = 99
+        x2[1:3] = 99
+        assert_(eq(x1, x2))
+        x2[1] = masked
+        assert_(eq(x1, x2))
+        x2[1:3] = masked
+        assert_(eq(x1, x2))
+        x2[:] = x1
+        x2[1] = masked
+        assert_(allequal(getmask(x2), array([0, 1, 0, 0])))
+        x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x3), array([0, 1, 1, 0])))
+        x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x4), array([0, 1, 1, 0])))
+        assert_(allequal(x4, array([1, 2, 3, 4])))
+        x1 = np.arange(5) * 1.0
+        x2 = masked_values(x1, 3.0)
+        assert_(eq(x1, x2))
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_(eq(3.0, x2.fill_value))
+        x1 = array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        s1 = x1[1]
+        s2 = x2[1]
+        self.assertEqual(type(s2), str)
+        self.assertEqual(type(s1), str)
+        self.assertEqual(s1, s2)
+        assert_(x1[1:1].shape == (0,))
+
+    def test_testCopySize(self):
+        # Tests of some subtle points of copying and sizing.
+        n = [0, 0, 1, 0, 0]
+        m = make_mask(n)
+        m2 = make_mask(m)
+        self.assertTrue(m is m2)
+        m3 = make_mask(m, copy=1)
+        self.assertTrue(m is not m3)
+
+        x1 = np.arange(5)
+        y1 = array(x1, mask=m)
+        self.assertTrue(y1._data is not x1)
+        self.assertTrue(allequal(x1, y1._data))
+        self.assertTrue(y1.mask is m)
+
+        y1a = array(y1, copy=0)
+        self.assertTrue(y1a.mask is y1.mask)
+
+        y2 = array(x1, mask=m, copy=0)
+        self.assertTrue(y2.mask is m)
+        self.assertTrue(y2[2] is masked)
+        y2[2] = 9
+        self.assertTrue(y2[2] is not masked)
+        self.assertTrue(y2.mask is not m)
+        self.assertTrue(allequal(y2.mask, 0))
+
+        y3 = array(x1 * 1.0, mask=m)
+        self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype)
+
+        x4 = arange(4)
+        x4[2] = masked
+        y4 = resize(x4, (8,))
+        self.assertTrue(eq(concatenate([x4, x4]), y4))
+        self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0]))
+        y5 = repeat(x4, (2, 2, 2, 2), axis=0)
+        self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3]))
+        y6 = repeat(x4, 2, axis=0)
+        self.assertTrue(eq(y5, y6))
+
+    def test_testPut(self):
+        # Test of put
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        x = array(d, mask=m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+        x[[1, 4]] = [10, 40]
+        self.assertTrue(x.mask is not m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is not masked)
+        self.assertTrue(eq(x, [0, 10, 2, -1, 40]))
+
+        x = array(d, mask=m)
+        x.put([0, 1, 2], [-1, 100, 200])
+        self.assertTrue(eq(x, [-1, 100, 200, 0, 0]))
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+
+    def test_testMaPut(self):
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
+        i = np.nonzero(m)[0]
+        put(ym, i, zm)
+        assert_(all(take(ym, i, axis=0) == zm))
+
+    def test_testOddFeatures(self):
+        # Test of other odd features
+        x = arange(20)
+        x = x.reshape(4, 5)
+        x.flat[5] = 12
+        assert_(x[1, 0] == 12)
+        z = x + 10j * x
+        assert_(eq(z.real, x))
+        assert_(eq(z.imag, 10 * x))
+        assert_(eq((z * conjugate(z)).real, 101 * x * x))
+        z.imag[...] = 0.0
+
+        x = arange(10)
+        x[3] = masked
+        assert_(str(x[3]) == str(masked))
+        c = x >= 8
+        assert_(count(where(c, masked, masked)) == 0)
+        assert_(shape(where(c, masked, masked)) == c.shape)
+        z = where(c, x, masked)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is masked)
+        assert_(z[7] is masked)
+        assert_(z[8] is not masked)
+        assert_(z[9] is not masked)
+        assert_(eq(x, z))
+        z = where(c, masked, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        z = masked_where(c, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        assert_(eq(x, z))
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+        assert_(eq(masked_where(greater(x, 2), x), masked_greater(x, 2)))
+        assert_(eq(masked_where(greater_equal(x, 2), x),
+                   masked_greater_equal(x, 2)))
+        assert_(eq(masked_where(less(x, 2), x), masked_less(x, 2)))
+        assert_(eq(masked_where(less_equal(x, 2), x), masked_less_equal(x, 2)))
+        assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)))
+        assert_(eq(masked_where(equal(x, 2), x), masked_equal(x, 2)))
+        assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)))
+        assert_(eq(masked_inside(list(range(5)), 1, 3), [0, 199, 199, 199, 4]))
+        assert_(eq(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199]))
+        assert_(eq(masked_inside(array(list(range(5)),
+                                       mask=[1, 0, 0, 0, 0]), 1, 3).mask,
+                   [1, 1, 1, 1, 0]))
+        assert_(eq(masked_outside(array(list(range(5)),
+                                        mask=[0, 1, 0, 0, 0]), 1, 3).mask,
+                   [1, 1, 0, 0, 1]))
+        assert_(eq(masked_equal(array(list(range(5)),
+                                      mask=[1, 0, 0, 0, 0]), 2).mask,
+                   [1, 0, 1, 0, 0]))
+        assert_(eq(masked_not_equal(array([2, 2, 1, 2, 1],
+                                          mask=[1, 0, 0, 0, 0]), 2).mask,
+                   [1, 0, 1, 0, 1]))
+        assert_(eq(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]),
+                   [99, 99, 3, 4, 5]))
+        atest = ones((10, 10, 10), dtype=np.float32)
+        btest = zeros(atest.shape, MaskType)
+        ctest = masked_where(btest, atest)
+        assert_(eq(atest, ctest))
+        z = choose(c, (-x, x))
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+        x = arange(6)
+        x[5] = masked
+        y = arange(6) * 10
+        y[2] = masked
+        c = array([1, 1, 1, 0, 0, 0], mask=[1, 0, 0, 0, 0, 0])
+        cm = c.filled(1)
+        z = where(c, x, y)
+        zm = where(cm, x, y)
+        assert_(eq(z, zm))
+        assert_(getmask(zm) is nomask)
+        assert_(eq(zm, [0, 1, 2, 30, 40, 50]))
+        z = where(c, masked, 1)
+        assert_(eq(z, [99, 99, 99, 1, 1, 1]))
+        z = where(c, 1, masked)
+        assert_(eq(z, [99, 1, 1, 99, 99, 99]))
+
+    def test_testMinMax2(self):
+        # Test of minumum, maximum.
+        assert_(eq(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3]))
+        assert_(eq(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9]))
+        x = arange(5)
+        y = arange(5) - 2
+        x[3] = masked
+        y[0] = masked
+        assert_(eq(minimum(x, y), where(less(x, y), x, y)))
+        assert_(eq(maximum(x, y), where(greater(x, y), x, y)))
+        assert_(minimum(x) == 0)
+        assert_(maximum(x) == 4)
+
+    def test_testTakeTransposeInnerOuter(self):
+        # Test of take, transpose, inner, outer products
+        x = arange(24)
+        y = np.arange(24)
+        x[5:6] = masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert_(eq(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1))))
+        assert_(eq(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1)))
+        assert_(eq(np.inner(filled(x, 0), filled(y, 0)),
+                   inner(x, y)))
+        assert_(eq(np.outer(filled(x, 0), filled(y, 0)),
+                   outer(x, y)))
+        y = array(['abc', 1, 'def', 2, 3], object)
+        y[2] = masked
+        t = take(y, [0, 3, 4])
+        assert_(t[0] == 'abc')
+        assert_(t[1] == 2)
+        assert_(t[2] == 3)
+
+    def test_testInplace(self):
+        # Test of inplace operations and rich comparisons
+        y = arange(10)
+
+        x = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        x += 1
+        assert_(eq(x, y + 1))
+        xm += 1
+        assert_(eq(x, y + 1))
+
+        x = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        x -= 1
+        assert_(eq(x, y - 1))
+        xm -= 1
+        assert_(eq(xm, y - 1))
+
+        x = arange(10) * 1.0
+        xm = arange(10) * 1.0
+        xm[2] = masked
+        x *= 2.0
+        assert_(eq(x, y * 2))
+        xm *= 2.0
+        assert_(eq(xm, y * 2))
+
+        x = arange(10) * 2
+        xm = arange(10)
+        xm[2] = masked
+        x //= 2
+        assert_(eq(x, y))
+        xm //= 2
+        assert_(eq(x, y))
+
+        x = arange(10) * 1.0
+        xm = arange(10) * 1.0
+        xm[2] = masked
+        x /= 2.0
+        assert_(eq(x, y / 2.0))
+        xm /= arange(10)
+        assert_(eq(xm, ones((10,))))
+
+        x = arange(10).astype(np.float32)
+        xm = arange(10)
+        xm[2] = masked
+        x += 1.
+        assert_(eq(x, y + 1.))
+
+    def test_testPickle(self):
+        # Test of pickling
+        import pickle
+        x = arange(12)
+        x[4:10:2] = masked
+        x = x.reshape(4, 3)
+        s = pickle.dumps(x)
+        y = pickle.loads(s)
+        assert_(eq(x, y))
+
+    def test_testMasked(self):
+        # Test of masked element
+        xx = arange(6)
+        xx[1] = masked
+        self.assertTrue(str(masked) == '--')
+        self.assertTrue(xx[1] is masked)
+        self.assertEqual(filled(xx[1], 0), 0)
+
+    def test_testAverage1(self):
+        # Test of average.
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assertTrue(eq(2.0, average(ott, axis=0)))
+        self.assertTrue(eq(2.0, average(ott, weights=[1., 1., 2., 1.])))
+        result, wts = average(ott, weights=[1., 1., 2., 1.], returned=1)
+        self.assertTrue(eq(2.0, result))
+        self.assertTrue(wts == 4.0)
+        ott[:] = masked
+        self.assertTrue(average(ott, axis=0) is masked)
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = masked
+        self.assertTrue(eq(average(ott, axis=0), [2.0, 0.0]))
+        self.assertTrue(average(ott, axis=1)[0] is masked)
+        self.assertTrue(eq([2., 0.], average(ott, axis=0)))
+        result, wts = average(ott, axis=0, returned=1)
+        self.assertTrue(eq(wts, [1., 0.]))
+
+    def test_testAverage2(self):
+        # More tests of average.
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = arange(6)
+        self.assertTrue(allclose(average(x, axis=0), 2.5))
+        self.assertTrue(allclose(average(x, axis=0, weights=w1), 2.5))
+        y = array([arange(6), 2.0 * arange(6)])
+        self.assertTrue(allclose(average(y, None),
+                                 np.add.reduce(np.arange(6)) * 3. / 12.))
+        self.assertTrue(allclose(average(y, axis=0), np.arange(6) * 3. / 2.))
+        self.assertTrue(allclose(average(y, axis=1),
+                                 [average(x, axis=0), average(x, axis=0)*2.0]))
+        self.assertTrue(allclose(average(y, None, weights=w2), 20. / 6.))
+        self.assertTrue(allclose(average(y, axis=0, weights=w2),
+                                 [0., 1., 2., 3., 4., 10.]))
+        self.assertTrue(allclose(average(y, axis=1),
+                                 [average(x, axis=0), average(x, axis=0)*2.0]))
+        m1 = zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        self.assertTrue(allclose(average(masked_array(x, m1), axis=0), 2.5))
+        self.assertTrue(allclose(average(masked_array(x, m2), axis=0), 2.5))
+        self.assertTrue(average(masked_array(x, m4), axis=0) is masked)
+        self.assertEqual(average(masked_array(x, m5), axis=0), 0.0)
+        self.assertEqual(count(average(masked_array(x, m4), axis=0)), 0)
+        z = masked_array(y, m3)
+        self.assertTrue(allclose(average(z, None), 20. / 6.))
+        self.assertTrue(allclose(average(z, axis=0),
+                                 [0., 1., 99., 99., 4.0, 7.5]))
+        self.assertTrue(allclose(average(z, axis=1), [2.5, 5.0]))
+        self.assertTrue(allclose(average(z, axis=0, weights=w2),
+                                 [0., 1., 99., 99., 4.0, 10.0]))
+
+        a = arange(6)
+        b = arange(6) * 3
+        r1, w1 = average([[a, b], [b, a]], axis=1, returned=1)
+        self.assertEqual(shape(r1), shape(w1))
+        self.assertEqual(r1.shape, w1.shape)
+        r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=1)
+        self.assertEqual(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), returned=1)
+        self.assertEqual(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=1)
+        self.assertTrue(shape(w2) == shape(r2))
+        a2d = array([[1, 2], [0, 4]], float)
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        a2da = average(a2d, axis=0)
+        self.assertTrue(eq(a2da, [0.5, 3.0]))
+        a2dma = average(a2dm, axis=0)
+        self.assertTrue(eq(a2dma, [1.0, 3.0]))
+        a2dma = average(a2dm, axis=None)
+        self.assertTrue(eq(a2dma, 7. / 3.))
+        a2dma = average(a2dm, axis=1)
+        self.assertTrue(eq(a2dma, [1.5, 4.0]))
+
+    def test_testToPython(self):
+        self.assertEqual(1, int(array(1)))
+        self.assertEqual(1.0, float(array(1)))
+        self.assertEqual(1, int(array([[[1]]])))
+        self.assertEqual(1.0, float(array([[1]])))
+        self.assertRaises(TypeError, float, array([1, 1]))
+        self.assertRaises(ValueError, bool, array([0, 1]))
+        self.assertRaises(ValueError, bool, array([0, 0], mask=[0, 1]))
+
+    def test_testScalarArithmetic(self):
+        xm = array(0, mask=1)
+        #TODO FIXME: Find out what the following raises a warning in r8247
+        with np.errstate(divide='ignore'):
+            self.assertTrue((1 / array(0)).mask)
+        self.assertTrue((1 + xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue(maximum(xm, xm).mask)
+        self.assertTrue(minimum(xm, xm).mask)
+        self.assertTrue(xm.filled().dtype is xm._data.dtype)
+        x = array(0, mask=0)
+        self.assertTrue(x.filled() == x._data)
+        self.assertEqual(str(xm), str(masked_print_option))
+
+    def test_testArrayMethods(self):
+        a = array([1, 3, 2])
+        self.assertTrue(eq(a.any(), a._data.any()))
+        self.assertTrue(eq(a.all(), a._data.all()))
+        self.assertTrue(eq(a.argmax(), a._data.argmax()))
+        self.assertTrue(eq(a.argmin(), a._data.argmin()))
+        self.assertTrue(eq(a.choose(0, 1, 2, 3, 4),
+                           a._data.choose(0, 1, 2, 3, 4)))
+        self.assertTrue(eq(a.compress([1, 0, 1]), a._data.compress([1, 0, 1])))
+        self.assertTrue(eq(a.conj(), a._data.conj()))
+        self.assertTrue(eq(a.conjugate(), a._data.conjugate()))
+        m = array([[1, 2], [3, 4]])
+        self.assertTrue(eq(m.diagonal(), m._data.diagonal()))
+        self.assertTrue(eq(a.sum(), a._data.sum()))
+        self.assertTrue(eq(a.take([1, 2]), a._data.take([1, 2])))
+        self.assertTrue(eq(m.transpose(), m._data.transpose()))
+
+    def test_testArrayAttributes(self):
+        a = array([1, 3, 2])
+        self.assertEqual(a.ndim, 1)
+
+    def test_testAPI(self):
+        self.assertFalse([m for m in dir(np.ndarray)
+                          if m not in dir(MaskedArray) and
+                          not m.startswith('_')])
+
+    def test_testSingleElementSubscript(self):
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        self.assertEqual(a[0].shape, ())
+        self.assertEqual(b[0].shape, ())
+        self.assertEqual(b[1].shape, ())
+
+
+class TestUfuncs(TestCase):
+    def setUp(self):
+        self.d = (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6),
+                  array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),)
+
+    def test_testUfuncRegression(self):
+        f_invalid_ignore = [
+            'sqrt', 'arctanh', 'arcsin', 'arccos',
+            'arccosh', 'arctanh', 'log', 'log10', 'divide',
+            'true_divide', 'floor_divide', 'remainder', 'fmod']
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+                  'sin', 'cos', 'tan',
+                  'arcsin', 'arccos', 'arctan',
+                  'sinh', 'cosh', 'tanh',
+                  'arcsinh',
+                  'arccosh',
+                  'arctanh',
+                  'absolute', 'fabs', 'negative',
+                  'floor', 'ceil',
+                  'logical_not',
+                  'add', 'subtract', 'multiply',
+                  'divide', 'true_divide', 'floor_divide',
+                  'remainder', 'fmod', 'hypot', 'arctan2',
+                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+                  'less', 'greater',
+                  'logical_and', 'logical_or', 'logical_xor']:
+            try:
+                uf = getattr(umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(np.ma, f)
+            args = self.d[:uf.nin]
+            with np.errstate():
+                if f in f_invalid_ignore:
+                    np.seterr(invalid='ignore')
+                if f in ['arctanh', 'log', 'log10']:
+                    np.seterr(divide='ignore')
+                ur = uf(*args)
+                mr = mf(*args)
+            self.assertTrue(eq(ur.filled(0), mr.filled(0), f))
+            self.assertTrue(eqmask(ur.mask, mr.mask))
+
+    def test_reduce(self):
+        a = self.d[0]
+        self.assertFalse(alltrue(a, axis=0))
+        self.assertTrue(sometrue(a, axis=0))
+        self.assertEqual(sum(a[:3], axis=0), 0)
+        self.assertEqual(product(a, axis=0), 0)
+
+    def test_minmax(self):
+        a = arange(1, 13).reshape(3, 4)
+        amask = masked_where(a < 5, a)
+        self.assertEqual(amask.max(), a.max())
+        self.assertEqual(amask.min(), 5)
+        self.assertTrue((amask.max(0) == a.max(0)).all())
+        self.assertTrue((amask.min(0) == [5, 6, 7, 8]).all())
+        self.assertTrue(amask.max(1)[0].mask)
+        self.assertTrue(amask.min(1)[0].mask)
+
+    def test_nonzero(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = array([1, 0, 2, 0], mask=[0, 0, 1, 1])
+            self.assertTrue(eq(nonzero(x), [0]))
+
+
+class TestArrayMethods(TestCase):
+
+    def setUp(self):
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                      1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0,
+                      0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        self.d = (x, X, XX, m, mx, mX, mXX)
+
+    def test_trace(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXdiag = mX.diagonal()
+        self.assertEqual(mX.trace(), mX.diagonal().compressed().sum())
+        self.assertTrue(eq(mX.trace(),
+                           X.trace() - sum(mXdiag.mask * X.diagonal(),
+                                           axis=0)))
+
+    def test_clip(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        clipped = mx.clip(2, 8)
+        self.assertTrue(eq(clipped.mask, mx.mask))
+        self.assertTrue(eq(clipped._data, x.clip(2, 8)))
+        self.assertTrue(eq(clipped._data, mx._data.clip(2, 8)))
+
+    def test_ptp(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        (n, m) = X.shape
+        self.assertEqual(mx.ptp(), mx.compressed().ptp())
+        rows = np.zeros(n, np.float_)
+        cols = np.zeros(m, np.float_)
+        for k in range(m):
+            cols[k] = mX[:, k].compressed().ptp()
+        for k in range(n):
+            rows[k] = mX[k].compressed().ptp()
+        self.assertTrue(eq(mX.ptp(0), cols))
+        self.assertTrue(eq(mX.ptp(1), rows))
+
+    def test_swapaxes(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXswapped = mX.swapaxes(0, 1)
+        self.assertTrue(eq(mXswapped[-1], mX[:, -1]))
+        mXXswapped = mXX.swapaxes(0, 2)
+        self.assertEqual(mXXswapped.shape, (2, 2, 3, 3))
+
+    def test_cumprod(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXcp = mX.cumprod(0)
+        self.assertTrue(eq(mXcp._data, mX.filled(1).cumprod(0)))
+        mXcp = mX.cumprod(1)
+        self.assertTrue(eq(mXcp._data, mX.filled(1).cumprod(1)))
+
+    def test_cumsum(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXcp = mX.cumsum(0)
+        self.assertTrue(eq(mXcp._data, mX.filled(0).cumsum(0)))
+        mXcp = mX.cumsum(1)
+        self.assertTrue(eq(mXcp._data, mX.filled(0).cumsum(1)))
+
+    def test_varstd(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        self.assertTrue(eq(mX.var(axis=None), mX.compressed().var()))
+        self.assertTrue(eq(mX.std(axis=None), mX.compressed().std()))
+        self.assertTrue(eq(mXX.var(axis=3).shape, XX.var(axis=3).shape))
+        self.assertTrue(eq(mX.var().shape, X.var().shape))
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        for k in range(6):
+            self.assertTrue(eq(mXvar1[k], mX[k].compressed().var()))
+            self.assertTrue(eq(mXvar0[k], mX[:, k].compressed().var()))
+            self.assertTrue(eq(np.sqrt(mXvar0[k]),
+                               mX[:, k].compressed().std()))
+
+
+def eqmask(m1, m2):
+    if m1 is nomask:
+        return m2 is nomask
+    if m2 is nomask:
+        return m1 is nomask
+    return (m1 == m2).all()
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
new file mode 100644
index 0000000000..dba74d357c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
@@ -0,0 +1,80 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (assert_, TestCase, assert_array_equal,
+                           assert_allclose, run_module_suite)
+from numpy.compat import sixu
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+    def test_masked_array_create(self,level=rlevel):
+        # Ticket #17
+        x = np.ma.masked_array([0, 1, 2, 3, 0, 4, 5, 6],
+                               mask=[0, 0, 0, 1, 1, 1, 0, 0])
+        assert_array_equal(np.ma.nonzero(x), [[1, 2, 6, 7]])
+
+    def test_masked_array(self,level=rlevel):
+        # Ticket #61
+        np.ma.array(1, mask=[1])
+
+    def test_mem_masked_where(self,level=rlevel):
+        # Ticket #62
+        from numpy.ma import masked_where, MaskType
+        a = np.zeros((1, 1))
+        b = np.zeros(a.shape, MaskType)
+        c = masked_where(b, a)
+        a-c
+
+    def test_masked_array_multiply(self,level=rlevel):
+        # Ticket #254
+        a = np.ma.zeros((4, 1))
+        a[2, 0] = np.ma.masked
+        b = np.zeros((4, 2))
+        a*b
+        b*a
+
+    def test_masked_array_repeat(self, level=rlevel):
+        # Ticket #271
+        np.ma.array([1], mask=False).repeat(10)
+
+    def test_masked_array_repr_unicode(self):
+        # Ticket #1256
+        repr(np.ma.array(sixu("Unicode")))
+
+    def test_atleast_2d(self):
+        # Ticket #1559
+        a = np.ma.masked_array([0.0, 1.2, 3.5], mask=[False, True, False])
+        b = np.atleast_2d(a)
+        assert_(a.mask.ndim == 1)
+        assert_(b.mask.ndim == 2)
+
+    def test_set_fill_value_unicode_py3(self):
+        # Ticket #2733
+        a = np.ma.masked_array(['a', 'b', 'c'], mask=[1, 0, 0])
+        a.fill_value = 'X'
+        assert_(a.fill_value == 'X')
+
+    def test_var_sets_maskedarray_scalar(self):
+        # Issue gh-2757
+        a = np.ma.array(np.arange(5), mask=True)
+        mout = np.ma.array(-1, dtype=float)
+        a.var(out=mout)
+        assert_(mout._data == 0)
+
+    def test_ddof_corrcoef(self):
+        # See gh-3336
+        x = np.ma.masked_equal([1, 2, 3, 4, 5], 4)
+        y = np.array([2, 2.5, 3.1, 3, 5])
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            r0 = np.ma.corrcoef(x, y, ddof=0)
+            r1 = np.ma.corrcoef(x, y, ddof=1)
+            # ddof should not have an effect (it gets cancelled out)
+            assert_allclose(r0.data, r1.data)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
new file mode 100644
index 0000000000..814ed5977f
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
@@ -0,0 +1,358 @@
+# pylint: disable-msg=W0611, W0612, W0511,R0201
+"""Tests suite for MaskedArray & subclassing.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: test_subclassing.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_raises
+from numpy.ma.testutils import assert_equal
+from numpy.ma.core import (
+    array, arange, masked, MaskedArray, masked_array, log, add, hypot,
+    divide, asarray, asanyarray, nomask
+    )
+# from numpy.ma.core import (
+
+
+class SubArray(np.ndarray):
+    # Defines a generic np.ndarray subclass, that stores some metadata
+    # in the  dictionary `info`.
+    def __new__(cls,arr,info={}):
+        x = np.asanyarray(arr).view(cls)
+        x.info = info.copy()
+        return x
+
+    def __array_finalize__(self, obj):
+        if callable(getattr(super(SubArray, self),
+                            '__array_finalize__', None)):
+            super(SubArray, self).__array_finalize__(obj)
+        self.info = getattr(obj, 'info', {}).copy()
+        return
+
+    def __add__(self, other):
+        result = super(SubArray, self).__add__(other)
+        result.info['added'] = result.info.get('added', 0) + 1
+        return result
+
+    def __iadd__(self, other):
+        result = super(SubArray, self).__iadd__(other)
+        result.info['iadded'] = result.info.get('iadded', 0) + 1
+        return result
+
+
+subarray = SubArray
+
+
+class SubMaskedArray(MaskedArray):
+    """Pure subclass of MaskedArray, keeping some info on subclass."""
+    def __new__(cls, info=None, **kwargs):
+        obj = super(SubMaskedArray, cls).__new__(cls, **kwargs)
+        obj._optinfo['info'] = info
+        return obj
+
+
+class MSubArray(SubArray, MaskedArray):
+
+    def __new__(cls, data, info={}, mask=nomask):
+        subarr = SubArray(data, info)
+        _data = MaskedArray.__new__(cls, data=subarr, mask=mask)
+        _data.info = subarr.info
+        return _data
+
+    def _get_series(self):
+        _view = self.view(MaskedArray)
+        _view._sharedmask = False
+        return _view
+    _series = property(fget=_get_series)
+
+msubarray = MSubArray
+
+
+class MMatrix(MaskedArray, np.matrix,):
+
+    def __new__(cls, data, mask=nomask):
+        mat = np.matrix(data)
+        _data = MaskedArray.__new__(cls, data=mat, mask=mask)
+        return _data
+
+    def __array_finalize__(self, obj):
+        np.matrix.__array_finalize__(self, obj)
+        MaskedArray.__array_finalize__(self, obj)
+        return
+
+    def _get_series(self):
+        _view = self.view(MaskedArray)
+        _view._sharedmask = False
+        return _view
+    _series = property(fget=_get_series)
+
+mmatrix = MMatrix
+
+
+# Also a subclass that overrides __str__, __repr__ and __setitem__, disallowing
+# setting to non-class values (and thus np.ma.core.masked_print_option)
+# and overrides __array_wrap__, updating the info dict, to check that this
+# doesn't get destroyed by MaskedArray._update_from.  But this one also needs
+# its own iterator...
+class CSAIterator(object):
+    """
+    Flat iterator object that uses its own setter/getter
+    (works around ndarray.flat not propagating subclass setters/getters
+    see https://github.com/numpy/numpy/issues/4564)
+    roughly following MaskedIterator
+    """
+    def __init__(self, a):
+        self._original = a
+        self._dataiter = a.view(np.ndarray).flat
+
+    def __iter__(self):
+        return self
+
+    def __getitem__(self, indx):
+        out = self._dataiter.__getitem__(indx)
+        if not isinstance(out, np.ndarray):
+            out = out.__array__()
+        out = out.view(type(self._original))
+        return out
+
+    def __setitem__(self, index, value):
+        self._dataiter[index] = self._original._validate_input(value)
+
+    def __next__(self):
+        return next(self._dataiter).__array__().view(type(self._original))
+
+    next = __next__
+
+
+class ComplicatedSubArray(SubArray):
+
+    def __str__(self):
+        return 'myprefix {0} mypostfix'.format(self.view(SubArray))
+
+    def __repr__(self):
+        # Return a repr that does not start with 'name('
+        return '<{0} {1}>'.format(self.__class__.__name__, self)
+
+    def _validate_input(self, value):
+        if not isinstance(value, ComplicatedSubArray):
+            raise ValueError("Can only set to MySubArray values")
+        return value
+
+    def __setitem__(self, item, value):
+        # validation ensures direct assignment with ndarray or
+        # masked_print_option will fail
+        super(ComplicatedSubArray, self).__setitem__(
+            item, self._validate_input(value))
+
+    def __getitem__(self, item):
+        # ensure getter returns our own class also for scalars
+        value = super(ComplicatedSubArray, self).__getitem__(item)
+        if not isinstance(value, np.ndarray):  # scalar
+            value = value.__array__().view(ComplicatedSubArray)
+        return value
+
+    @property
+    def flat(self):
+        return CSAIterator(self)
+
+    @flat.setter
+    def flat(self, value):
+        y = self.ravel()
+        y[:] = value
+
+    def __array_wrap__(self, obj, context=None):
+        obj = super(ComplicatedSubArray, self).__array_wrap__(obj, context)
+        if context is not None and context[0] is np.multiply:
+            obj.info['multiplied'] = obj.info.get('multiplied', 0) + 1
+
+        return obj
+
+
+class TestSubclassing(TestCase):
+    # Test suite for masked subclasses of ndarray.
+
+    def setUp(self):
+        x = np.arange(5)
+        mx = mmatrix(x, mask=[0, 1, 0, 0, 0])
+        self.data = (x, mx)
+
+    def test_data_subclassing(self):
+        # Tests whether the subclass is kept.
+        x = np.arange(5)
+        m = [0, 0, 1, 0, 0]
+        xsub = SubArray(x)
+        xmsub = masked_array(xsub, mask=m)
+        self.assertTrue(isinstance(xmsub, MaskedArray))
+        assert_equal(xmsub._data, xsub)
+        self.assertTrue(isinstance(xmsub._data, SubArray))
+
+    def test_maskedarray_subclassing(self):
+        # Tests subclassing MaskedArray
+        (x, mx) = self.data
+        self.assertTrue(isinstance(mx._data, np.matrix))
+
+    def test_masked_unary_operations(self):
+        # Tests masked_unary_operation
+        (x, mx) = self.data
+        with np.errstate(divide='ignore'):
+            self.assertTrue(isinstance(log(mx), mmatrix))
+            assert_equal(log(x), np.log(x))
+
+    def test_masked_binary_operations(self):
+        # Tests masked_binary_operation
+        (x, mx) = self.data
+        # Result should be a mmatrix
+        self.assertTrue(isinstance(add(mx, mx), mmatrix))
+        self.assertTrue(isinstance(add(mx, x), mmatrix))
+        # Result should work
+        assert_equal(add(mx, x), mx+x)
+        self.assertTrue(isinstance(add(mx, mx)._data, np.matrix))
+        self.assertTrue(isinstance(add.outer(mx, mx), mmatrix))
+        self.assertTrue(isinstance(hypot(mx, mx), mmatrix))
+        self.assertTrue(isinstance(hypot(mx, x), mmatrix))
+
+    def test_masked_binary_operations2(self):
+        # Tests domained_masked_binary_operation
+        (x, mx) = self.data
+        xmx = masked_array(mx.data.__array__(), mask=mx.mask)
+        self.assertTrue(isinstance(divide(mx, mx), mmatrix))
+        self.assertTrue(isinstance(divide(mx, x), mmatrix))
+        assert_equal(divide(mx, mx), divide(xmx, xmx))
+
+    def test_attributepropagation(self):
+        x = array(arange(5), mask=[0]+[1]*4)
+        my = masked_array(subarray(x))
+        ym = msubarray(x)
+        #
+        z = (my+1)
+        self.assertTrue(isinstance(z, MaskedArray))
+        self.assertTrue(not isinstance(z, MSubArray))
+        self.assertTrue(isinstance(z._data, SubArray))
+        assert_equal(z._data.info, {})
+        #
+        z = (ym+1)
+        self.assertTrue(isinstance(z, MaskedArray))
+        self.assertTrue(isinstance(z, MSubArray))
+        self.assertTrue(isinstance(z._data, SubArray))
+        self.assertTrue(z._data.info['added'] > 0)
+        # Test that inplace methods from data get used (gh-4617)
+        ym += 1
+        self.assertTrue(isinstance(ym, MaskedArray))
+        self.assertTrue(isinstance(ym, MSubArray))
+        self.assertTrue(isinstance(ym._data, SubArray))
+        self.assertTrue(ym._data.info['iadded'] > 0)
+        #
+        ym._set_mask([1, 0, 0, 0, 1])
+        assert_equal(ym._mask, [1, 0, 0, 0, 1])
+        ym._series._set_mask([0, 0, 0, 0, 1])
+        assert_equal(ym._mask, [0, 0, 0, 0, 1])
+        #
+        xsub = subarray(x, info={'name':'x'})
+        mxsub = masked_array(xsub)
+        self.assertTrue(hasattr(mxsub, 'info'))
+        assert_equal(mxsub.info, xsub.info)
+
+    def test_subclasspreservation(self):
+        # Checks that masked_array(...,subok=True) preserves the class.
+        x = np.arange(5)
+        m = [0, 0, 1, 0, 0]
+        xinfo = [(i, j) for (i, j) in zip(x, m)]
+        xsub = MSubArray(x, mask=m, info={'xsub':xinfo})
+        #
+        mxsub = masked_array(xsub, subok=False)
+        self.assertTrue(not isinstance(mxsub, MSubArray))
+        self.assertTrue(isinstance(mxsub, MaskedArray))
+        assert_equal(mxsub._mask, m)
+        #
+        mxsub = asarray(xsub)
+        self.assertTrue(not isinstance(mxsub, MSubArray))
+        self.assertTrue(isinstance(mxsub, MaskedArray))
+        assert_equal(mxsub._mask, m)
+        #
+        mxsub = masked_array(xsub, subok=True)
+        self.assertTrue(isinstance(mxsub, MSubArray))
+        assert_equal(mxsub.info, xsub.info)
+        assert_equal(mxsub._mask, xsub._mask)
+        #
+        mxsub = asanyarray(xsub)
+        self.assertTrue(isinstance(mxsub, MSubArray))
+        assert_equal(mxsub.info, xsub.info)
+        assert_equal(mxsub._mask, m)
+
+    def test_subclass_items(self):
+        """test that getter and setter go via baseclass"""
+        x = np.arange(5)
+        xcsub = ComplicatedSubArray(x)
+        mxcsub = masked_array(xcsub, mask=[True, False, True, False, False])
+        # getter should  return a ComplicatedSubArray, even for single item
+        # first check we wrote ComplicatedSubArray correctly
+        self.assertTrue(isinstance(xcsub[1], ComplicatedSubArray))
+        self.assertTrue(isinstance(xcsub[1:4], ComplicatedSubArray))
+        # now that it propagates inside the MaskedArray
+        self.assertTrue(isinstance(mxcsub[1], ComplicatedSubArray))
+        self.assertTrue(mxcsub[0] is masked)
+        self.assertTrue(isinstance(mxcsub[1:4].data, ComplicatedSubArray))
+        # also for flattened version (which goes via MaskedIterator)
+        self.assertTrue(isinstance(mxcsub.flat[1].data, ComplicatedSubArray))
+        self.assertTrue(mxcsub[0] is masked)
+        self.assertTrue(isinstance(mxcsub.flat[1:4].base, ComplicatedSubArray))
+
+        # setter should only work with ComplicatedSubArray input
+        # first check we wrote ComplicatedSubArray correctly
+        assert_raises(ValueError, xcsub.__setitem__, 1, x[4])
+        # now that it propagates inside the MaskedArray
+        assert_raises(ValueError, mxcsub.__setitem__, 1, x[4])
+        assert_raises(ValueError, mxcsub.__setitem__, slice(1, 4), x[1:4])
+        mxcsub[1] = xcsub[4]
+        mxcsub[1:4] = xcsub[1:4]
+        # also for flattened version (which goes via MaskedIterator)
+        assert_raises(ValueError, mxcsub.flat.__setitem__, 1, x[4])
+        assert_raises(ValueError, mxcsub.flat.__setitem__, slice(1, 4), x[1:4])
+        mxcsub.flat[1] = xcsub[4]
+        mxcsub.flat[1:4] = xcsub[1:4]
+
+    def test_subclass_repr(self):
+        """test that repr uses the name of the subclass
+        and 'array' for np.ndarray"""
+        x = np.arange(5)
+        mx = masked_array(x, mask=[True, False, True, False, False])
+        self.assertTrue(repr(mx).startswith('masked_array'))
+        xsub = SubArray(x)
+        mxsub = masked_array(xsub, mask=[True, False, True, False, False])
+        self.assertTrue(repr(mxsub).startswith(
+            'masked_{0}(data = [-- 1 -- 3 4]'.format(SubArray.__name__)))
+
+    def test_subclass_str(self):
+        """test str with subclass that has overridden str, setitem"""
+        # first without override
+        x = np.arange(5)
+        xsub = SubArray(x)
+        mxsub = masked_array(xsub, mask=[True, False, True, False, False])
+        self.assertTrue(str(mxsub) == '[-- 1 -- 3 4]')
+
+        xcsub = ComplicatedSubArray(x)
+        assert_raises(ValueError, xcsub.__setitem__, 0,
+                      np.ma.core.masked_print_option)
+        mxcsub = masked_array(xcsub, mask=[True, False, True, False, False])
+        self.assertTrue(str(mxcsub) == 'myprefix [-- 1 -- 3 4] mypostfix')
+
+    def test_pure_subclass_info_preservation(self):
+        # Test that ufuncs and methods conserve extra information consistently;
+        # see gh-7122.
+        arr1 = SubMaskedArray('test', data=[1,2,3,4,5,6])
+        arr2 = SubMaskedArray(data=[0,1,2,3,4,5])
+        diff1 = np.subtract(arr1, arr2)
+        self.assertTrue('info' in diff1._optinfo)
+        self.assertTrue(diff1._optinfo['info'] == 'test')
+        diff2 = arr1 - arr2
+        self.assertTrue('info' in diff2._optinfo)
+        self.assertTrue(diff2._optinfo['info'] == 'test')
+
+
+###############################################################################
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/testutils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/testutils.py
new file mode 100644
index 0000000000..8dc8218784
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/testutils.py
@@ -0,0 +1,289 @@
+"""Miscellaneous functions for testing masked arrays and subclasses
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: testutils.py 3529 2007-11-13 08:01:14Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import operator
+
+import numpy as np
+from numpy import ndarray, float_
+import numpy.core.umath as umath
+from numpy.testing import (
+    TestCase, assert_, assert_allclose, assert_array_almost_equal_nulp,
+    assert_raises, build_err_msg, run_module_suite,
+    )
+import numpy.testing.utils as utils
+from .core import mask_or, getmask, masked_array, nomask, masked, filled
+
+__all__masked = [
+    'almost', 'approx', 'assert_almost_equal', 'assert_array_almost_equal',
+    'assert_array_approx_equal', 'assert_array_compare',
+    'assert_array_equal', 'assert_array_less', 'assert_close',
+    'assert_equal', 'assert_equal_records', 'assert_mask_equal',
+    'assert_not_equal', 'fail_if_array_equal',
+    ]
+
+# Include some normal test functions to avoid breaking other projects who
+# have mistakenly included them from this file. SciPy is one. That is
+# unfortunate, as some of these functions are not intended to work with
+# masked arrays. But there was no way to tell before.
+__some__from_testing = [
+    'TestCase', 'assert_', 'assert_allclose',
+    'assert_array_almost_equal_nulp', 'assert_raises', 'run_module_suite',
+    ]
+
+__all__ = __all__masked + __some__from_testing
+
+
+def approx(a, b, fill_value=True, rtol=1e-5, atol=1e-8):
+    """
+    Returns true if all components of a and b are equal to given tolerances.
+
+    If fill_value is True, masked values considered equal. Otherwise,
+    masked values are considered unequal.  The relative error rtol should
+    be positive and << 1.0 The absolute error atol comes into play for
+    those elements of b that are very small or zero; it says how small a
+    must be also.
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    d1 = filled(a)
+    d2 = filled(b)
+    if d1.dtype.char == "O" or d2.dtype.char == "O":
+        return np.equal(d1, d2).ravel()
+    x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_)
+    y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_)
+    d = np.less_equal(umath.absolute(x - y), atol + rtol * umath.absolute(y))
+    return d.ravel()
+
+
+def almost(a, b, decimal=6, fill_value=True):
+    """
+    Returns True if a and b are equal up to decimal places.
+
+    If fill_value is True, masked values considered equal. Otherwise,
+    masked values are considered unequal.
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    d1 = filled(a)
+    d2 = filled(b)
+    if d1.dtype.char == "O" or d2.dtype.char == "O":
+        return np.equal(d1, d2).ravel()
+    x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_)
+    y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_)
+    d = np.around(np.abs(x - y), decimal) <= 10.0 ** (-decimal)
+    return d.ravel()
+
+
+def _assert_equal_on_sequences(actual, desired, err_msg=''):
+    """
+    Asserts the equality of two non-array sequences.
+
+    """
+    assert_equal(len(actual), len(desired), err_msg)
+    for k in range(len(desired)):
+        assert_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg))
+    return
+
+
+def assert_equal_records(a, b):
+    """
+    Asserts that two records are equal.
+
+    Pretty crude for now.
+
+    """
+    assert_equal(a.dtype, b.dtype)
+    for f in a.dtype.names:
+        (af, bf) = (operator.getitem(a, f), operator.getitem(b, f))
+        if not (af is masked) and not (bf is masked):
+            assert_equal(operator.getitem(a, f), operator.getitem(b, f))
+    return
+
+
+def assert_equal(actual, desired, err_msg=''):
+    """
+    Asserts that two items are equal.
+
+    """
+    # Case #1: dictionary .....
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        assert_equal(len(actual), len(desired), err_msg)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError("%s not in %s" % (k, actual))
+            assert_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg))
+        return
+    # Case #2: lists .....
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        return _assert_equal_on_sequences(actual, desired, err_msg='')
+    if not (isinstance(actual, ndarray) or isinstance(desired, ndarray)):
+        msg = build_err_msg([actual, desired], err_msg,)
+        if not desired == actual:
+            raise AssertionError(msg)
+        return
+    # Case #4. arrays or equivalent
+    if ((actual is masked) and not (desired is masked)) or \
+            ((desired is masked) and not (actual is masked)):
+        msg = build_err_msg([actual, desired],
+                            err_msg, header='', names=('x', 'y'))
+        raise ValueError(msg)
+    actual = np.array(actual, copy=False, subok=True)
+    desired = np.array(desired, copy=False, subok=True)
+    (actual_dtype, desired_dtype) = (actual.dtype, desired.dtype)
+    if actual_dtype.char == "S" and desired_dtype.char == "S":
+        return _assert_equal_on_sequences(actual.tolist(),
+                                          desired.tolist(),
+                                          err_msg='')
+    return assert_array_equal(actual, desired, err_msg)
+
+
+def fail_if_equal(actual, desired, err_msg='',):
+    """
+    Raises an assertion error if two items are equal.
+
+    """
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        fail_if_equal(len(actual), len(desired), err_msg)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError(repr(k))
+            fail_if_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg))
+        return
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        fail_if_equal(len(actual), len(desired), err_msg)
+        for k in range(len(desired)):
+            fail_if_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg))
+        return
+    if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray):
+        return fail_if_array_equal(actual, desired, err_msg)
+    msg = build_err_msg([actual, desired], err_msg)
+    if not desired != actual:
+        raise AssertionError(msg)
+
+
+assert_not_equal = fail_if_equal
+
+
+def assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True):
+    """
+    Asserts that two items are almost equal.
+
+    The test is equivalent to abs(desired-actual) < 0.5 * 10**(-decimal).
+
+    """
+    if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray):
+        return assert_array_almost_equal(actual, desired, decimal=decimal,
+                                         err_msg=err_msg, verbose=verbose)
+    msg = build_err_msg([actual, desired],
+                        err_msg=err_msg, verbose=verbose)
+    if not round(abs(desired - actual), decimal) == 0:
+        raise AssertionError(msg)
+
+
+assert_close = assert_almost_equal
+
+
+def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='',
+                         fill_value=True):
+    """
+    Asserts that comparison between two masked arrays is satisfied.
+
+    The comparison is elementwise.
+
+    """
+    # Allocate a common mask and refill
+    m = mask_or(getmask(x), getmask(y))
+    x = masked_array(x, copy=False, mask=m, keep_mask=False, subok=False)
+    y = masked_array(y, copy=False, mask=m, keep_mask=False, subok=False)
+    if ((x is masked) and not (y is masked)) or \
+            ((y is masked) and not (x is masked)):
+        msg = build_err_msg([x, y], err_msg=err_msg, verbose=verbose,
+                            header=header, names=('x', 'y'))
+        raise ValueError(msg)
+    # OK, now run the basic tests on filled versions
+    return utils.assert_array_compare(comparison,
+                                      x.filled(fill_value),
+                                      y.filled(fill_value),
+                                      err_msg=err_msg,
+                                      verbose=verbose, header=header)
+
+
+def assert_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Checks the elementwise equality of two masked arrays.
+
+    """
+    assert_array_compare(operator.__eq__, x, y,
+                         err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not equal')
+
+
+def fail_if_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Raises an assertion error if two masked arrays are not equal elementwise.
+
+    """
+    def compare(x, y):
+        return (not np.alltrue(approx(x, y)))
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not equal')
+
+
+def assert_array_approx_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Checks the equality of two masked arrays, up to given number odecimals.
+
+    The equality is checked elementwise.
+
+    """
+    def compare(x, y):
+        "Returns the result of the loose comparison between x and y)."
+        return approx(x, y, rtol=10. ** -decimal)
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not almost equal')
+
+
+def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Checks the equality of two masked arrays, up to given number odecimals.
+
+    The equality is checked elementwise.
+
+    """
+    def compare(x, y):
+        "Returns the result of the loose comparison between x and y)."
+        return almost(x, y, decimal)
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not almost equal')
+
+
+def assert_array_less(x, y, err_msg='', verbose=True):
+    """
+    Checks that x is smaller than y elementwise.
+
+    """
+    assert_array_compare(operator.__lt__, x, y,
+                         err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not less-ordered')
+
+
+def assert_mask_equal(m1, m2, err_msg=''):
+    """
+    Asserts the equality of two masks.
+
+    """
+    if m1 is nomask:
+        assert_(m2 is nomask)
+    if m2 is nomask:
+        assert_(m1 is nomask)
+    assert_array_equal(m1, m2, err_msg=err_msg)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
new file mode 100644
index 0000000000..dae4b141b0
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
@@ -0,0 +1,440 @@
+from __future__ import division, absolute_import, print_function
+
+import timeit
+from functools import reduce
+
+import numpy as np
+from numpy import float_
+import numpy.core.fromnumeric as fromnumeric
+
+from numpy.testing.utils import build_err_msg
+
+# Fixme: this does not look right.
+np.seterr(all='ignore')
+
+pi = np.pi
+
+
+class ModuleTester(object):
+    def __init__(self, module):
+        self.module = module
+        self.allequal = module.allequal
+        self.arange = module.arange
+        self.array = module.array
+        self.concatenate = module.concatenate
+        self.count = module.count
+        self.equal = module.equal
+        self.filled = module.filled
+        self.getmask = module.getmask
+        self.getmaskarray = module.getmaskarray
+        self.id = id
+        self.inner = module.inner
+        self.make_mask = module.make_mask
+        self.masked = module.masked
+        self.masked_array = module.masked_array
+        self.masked_values = module.masked_values
+        self.mask_or = module.mask_or
+        self.nomask = module.nomask
+        self.ones = module.ones
+        self.outer = module.outer
+        self.repeat = module.repeat
+        self.resize = module.resize
+        self.sort = module.sort
+        self.take = module.take
+        self.transpose = module.transpose
+        self.zeros = module.zeros
+        self.MaskType = module.MaskType
+        try:
+            self.umath = module.umath
+        except AttributeError:
+            self.umath = module.core.umath
+        self.testnames = []
+
+    def assert_array_compare(self, comparison, x, y, err_msg='', header='',
+                         fill_value=True):
+        """
+        Assert that a comparison of two masked arrays is satisfied elementwise.
+
+        """
+        xf = self.filled(x)
+        yf = self.filled(y)
+        m = self.mask_or(self.getmask(x), self.getmask(y))
+
+        x = self.filled(self.masked_array(xf, mask=m), fill_value)
+        y = self.filled(self.masked_array(yf, mask=m), fill_value)
+        if (x.dtype.char != "O"):
+            x = x.astype(float_)
+            if isinstance(x, np.ndarray) and x.size > 1:
+                x[np.isnan(x)] = 0
+            elif np.isnan(x):
+                x = 0
+        if (y.dtype.char != "O"):
+            y = y.astype(float_)
+            if isinstance(y, np.ndarray) and y.size > 1:
+                y[np.isnan(y)] = 0
+            elif np.isnan(y):
+                y = 0
+        try:
+            cond = (x.shape == () or y.shape == ()) or x.shape == y.shape
+            if not cond:
+                msg = build_err_msg([x, y],
+                                    err_msg
+                                    + '\n(shapes %s, %s mismatch)' % (x.shape,
+                                                                      y.shape),
+                                    header=header,
+                                    names=('x', 'y'))
+                assert cond, msg
+            val = comparison(x, y)
+            if m is not self.nomask and fill_value:
+                val = self.masked_array(val, mask=m)
+            if isinstance(val, bool):
+                cond = val
+                reduced = [0]
+            else:
+                reduced = val.ravel()
+                cond = reduced.all()
+                reduced = reduced.tolist()
+            if not cond:
+                match = 100-100.0*reduced.count(1)/len(reduced)
+                msg = build_err_msg([x, y],
+                                    err_msg
+                                    + '\n(mismatch %s%%)' % (match,),
+                                    header=header,
+                                    names=('x', 'y'))
+                assert cond, msg
+        except ValueError:
+            msg = build_err_msg([x, y], err_msg, header=header, names=('x', 'y'))
+            raise ValueError(msg)
+
+    def assert_array_equal(self, x, y, err_msg=''):
+        """
+        Checks the elementwise equality of two masked arrays.
+
+        """
+        self.assert_array_compare(self.equal, x, y, err_msg=err_msg,
+                                  header='Arrays are not equal')
+
+    def test_0(self):
+        """
+        Tests creation
+
+        """
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        xm = self.masked_array(x, mask=m)
+        xm[0]
+
+    def test_1(self):
+        """
+        Tests creation
+
+        """
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = self.masked_array(x, mask=m1)
+        ym = self.masked_array(y, mask=m2)
+        xf = np.where(m1, 1.e+20, x)
+        xm.set_fill_value(1.e+20)
+
+        assert((xm-ym).filled(0).any())
+        s = x.shape
+        assert(xm.size == reduce(lambda x, y:x*y, s))
+        assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
+
+        for s in [(4, 3), (6, 2)]:
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+            assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
+
+    def test_2(self):
+        """
+        Tests conversions and indexing.
+
+        """
+        x1 = np.array([1, 2, 4, 3])
+        x2 = self.array(x1, mask=[1, 0, 0, 0])
+        x3 = self.array(x1, mask=[0, 1, 0, 1])
+        x4 = self.array(x1)
+        # test conversion to strings, no errors
+        str(x2)
+        repr(x2)
+        # tests of indexing
+        assert type(x2[1]) is type(x1[1])
+        assert x1[1] == x2[1]
+        x1[2] = 9
+        x2[2] = 9
+        self.assert_array_equal(x1, x2)
+        x1[1:3] = 99
+        x2[1:3] = 99
+        x2[1] = self.masked
+        x2[1:3] = self.masked
+        x2[:] = x1
+        x2[1] = self.masked
+        x3[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        x4[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        x1 = np.arange(5)*1.0
+        x2 = self.masked_values(x1, 3.0)
+        x1 = self.array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        # check that no error occurs.
+        x1[1]
+        x2[1]
+        assert x1[1:1].shape == (0,)
+        # Tests copy-size
+        n = [0, 0, 1, 0, 0]
+        m = self.make_mask(n)
+        m2 = self.make_mask(m)
+        assert(m is m2)
+        m3 = self.make_mask(m, copy=1)
+        assert(m is not m3)
+
+    def test_3(self):
+        """
+        Tests resize/repeat
+
+        """
+        x4 = self.arange(4)
+        x4[2] = self.masked
+        y4 = self.resize(x4, (8,))
+        assert self.allequal(self.concatenate([x4, x4]), y4)
+        assert self.allequal(self.getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
+        y5 = self.repeat(x4, (2, 2, 2, 2), axis=0)
+        self.assert_array_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
+        y6 = self.repeat(x4, 2, axis=0)
+        assert self.allequal(y5, y6)
+        y7 = x4.repeat((2, 2, 2, 2), axis=0)
+        assert self.allequal(y5, y7)
+        y8 = x4.repeat(2, 0)
+        assert self.allequal(y5, y8)
+
+    def test_4(self):
+        """
+        Test of take, transpose, inner, outer products.
+
+        """
+        x = self.arange(24)
+        y = np.arange(24)
+        x[5:6] = self.masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert self.allequal(np.transpose(y, (2, 0, 1)), self.transpose(x, (2, 0, 1)))
+        assert self.allequal(np.take(y, (2, 0, 1), 1), self.take(x, (2, 0, 1), 1))
+        assert self.allequal(np.inner(self.filled(x, 0), self.filled(y, 0)),
+                            self.inner(x, y))
+        assert self.allequal(np.outer(self.filled(x, 0), self.filled(y, 0)),
+                            self.outer(x, y))
+        y = self.array(['abc', 1, 'def', 2, 3], object)
+        y[2] = self.masked
+        t = self.take(y, [0, 3, 4])
+        assert t[0] == 'abc'
+        assert t[1] == 2
+        assert t[2] == 3
+
+    def test_5(self):
+        """
+        Tests inplace w/ scalar
+
+        """
+        x = self.arange(10)
+        y = self.arange(10)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x += 1
+        assert self.allequal(x, y+1)
+        xm += 1
+        assert self.allequal(xm, y+1)
+
+        x = self.arange(10)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x -= 1
+        assert self.allequal(x, y-1)
+        xm -= 1
+        assert self.allequal(xm, y-1)
+
+        x = self.arange(10)*1.0
+        xm = self.arange(10)*1.0
+        xm[2] = self.masked
+        x *= 2.0
+        assert self.allequal(x, y*2)
+        xm *= 2.0
+        assert self.allequal(xm, y*2)
+
+        x = self.arange(10)*2
+        xm = self.arange(10)*2
+        xm[2] = self.masked
+        x /= 2
+        assert self.allequal(x, y)
+        xm /= 2
+        assert self.allequal(xm, y)
+
+        x = self.arange(10)*1.0
+        xm = self.arange(10)*1.0
+        xm[2] = self.masked
+        x /= 2.0
+        assert self.allequal(x, y/2.0)
+        xm /= self.arange(10)
+        self.assert_array_equal(xm, self.ones((10,)))
+
+        x = self.arange(10).astype(float_)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x += 1.
+        assert self.allequal(x, y + 1.)
+
+    def test_6(self):
+        """
+        Tests inplace w/ array
+
+        """
+        x = self.arange(10, dtype=float_)
+        y = self.arange(10)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x += a
+        xm += a
+        assert self.allequal(x, y+a)
+        assert self.allequal(xm, y+a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x -= a
+        xm -= a
+        assert self.allequal(x, y-a)
+        assert self.allequal(xm, y-a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x *= a
+        xm *= a
+        assert self.allequal(x, y*a)
+        assert self.allequal(xm, y*a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x /= a
+        xm /= a
+
+    def test_7(self):
+        "Tests ufunc"
+        d = (self.array([1.0, 0, -1, pi/2]*2, mask=[0, 1]+[0]*6),
+             self.array([1.0, 0, -1, pi/2]*2, mask=[1, 0]+[0]*6),)
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+#                  'sin', 'cos', 'tan',
+#                  'arcsin', 'arccos', 'arctan',
+#                  'sinh', 'cosh', 'tanh',
+#                  'arcsinh',
+#                  'arccosh',
+#                  'arctanh',
+#                  'absolute', 'fabs', 'negative',
+#                  # 'nonzero', 'around',
+#                  'floor', 'ceil',
+#                  # 'sometrue', 'alltrue',
+#                  'logical_not',
+#                  'add', 'subtract', 'multiply',
+#                  'divide', 'true_divide', 'floor_divide',
+#                  'remainder', 'fmod', 'hypot', 'arctan2',
+#                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+#                  'less', 'greater',
+#                  'logical_and', 'logical_or', 'logical_xor',
+                  ]:
+            try:
+                uf = getattr(self.umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(self.module, f)
+            args = d[:uf.nin]
+            ur = uf(*args)
+            mr = mf(*args)
+            self.assert_array_equal(ur.filled(0), mr.filled(0), f)
+            self.assert_array_equal(ur._mask, mr._mask)
+
+    def test_99(self):
+        # test average
+        ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assert_array_equal(2.0, self.average(ott, axis=0))
+        self.assert_array_equal(2.0, self.average(ott, weights=[1., 1., 2., 1.]))
+        result, wts = self.average(ott, weights=[1., 1., 2., 1.], returned=1)
+        self.assert_array_equal(2.0, result)
+        assert(wts == 4.0)
+        ott[:] = self.masked
+        assert(self.average(ott, axis=0) is self.masked)
+        ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = self.masked
+        self.assert_array_equal(self.average(ott, axis=0), [2.0, 0.0])
+        assert(self.average(ott, axis=1)[0] is self.masked)
+        self.assert_array_equal([2., 0.], self.average(ott, axis=0))
+        result, wts = self.average(ott, axis=0, returned=1)
+        self.assert_array_equal(wts, [1., 0.])
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = self.arange(6)
+        self.assert_array_equal(self.average(x, axis=0), 2.5)
+        self.assert_array_equal(self.average(x, axis=0, weights=w1), 2.5)
+        y = self.array([self.arange(6), 2.0*self.arange(6)])
+        self.assert_array_equal(self.average(y, None), np.add.reduce(np.arange(6))*3./12.)
+        self.assert_array_equal(self.average(y, axis=0), np.arange(6) * 3./2.)
+        self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
+        self.assert_array_equal(self.average(y, None, weights=w2), 20./6.)
+        self.assert_array_equal(self.average(y, axis=0, weights=w2), [0., 1., 2., 3., 4., 10.])
+        self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
+        m1 = self.zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = self.ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        self.assert_array_equal(self.average(self.masked_array(x, m1), axis=0), 2.5)
+        self.assert_array_equal(self.average(self.masked_array(x, m2), axis=0), 2.5)
+        self.assert_array_equal(self.average(self.masked_array(x, m5), axis=0), 0.0)
+        self.assert_array_equal(self.count(self.average(self.masked_array(x, m4), axis=0)), 0)
+        z = self.masked_array(y, m3)
+        self.assert_array_equal(self.average(z, None), 20./6.)
+        self.assert_array_equal(self.average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5])
+        self.assert_array_equal(self.average(z, axis=1), [2.5, 5.0])
+        self.assert_array_equal(self.average(z, axis=0, weights=w2), [0., 1., 99., 99., 4.0, 10.0])
+
+    def test_A(self):
+        x = self.arange(24)
+        x[5:6] = self.masked
+        x = x.reshape(2, 3, 4)
+
+
+if __name__ == '__main__':
+    setup_base = ("from __main__ import ModuleTester \n"
+                  "import numpy\n"
+                  "tester = ModuleTester(module)\n")
+    setup_cur = "import numpy.ma.core as module\n" + setup_base
+    (nrepeat, nloop) = (10, 10)
+
+    if 1:
+        for i in range(1, 8):
+            func = 'tester.test_%i()' % i
+            cur = timeit.Timer(func, setup_cur).repeat(nrepeat, nloop*10)
+            cur = np.sort(cur)
+            print("#%i" % i + 50*'.')
+            print(eval("ModuleTester.test_%i.__doc__" % i))
+            print("core_current : %.3f - %.3f" % (cur[0], cur[1]))
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/version.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/version.py
new file mode 100644
index 0000000000..a2c5c42a80
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/ma/version.py
@@ -0,0 +1,14 @@
+"""Version number
+
+"""
+from __future__ import division, absolute_import, print_function
+
+version = '1.00'
+release = False
+
+if not release:
+    from . import core
+    from . import extras
+    revision = [core.__revision__.split(':')[-1][:-1].strip(),
+                extras.__revision__.split(':')[-1][:-1].strip(),]
+    version += '.dev%04i' % max([int(rev) for rev in revision])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matlib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matlib.py
new file mode 100644
index 0000000000..656ca34588
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matlib.py
@@ -0,0 +1,358 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.matrixlib.defmatrix import matrix, asmatrix
+# need * as we're copying the numpy namespace
+from numpy import *
+
+__version__ = np.__version__
+
+__all__ = np.__all__[:] # copy numpy namespace
+__all__ += ['rand', 'randn', 'repmat']
+
+def empty(shape, dtype=None, order='C'):
+    """Return a new matrix of given shape and type, without initializing entries.
+
+    Parameters
+    ----------
+    shape : int or tuple of int
+        Shape of the empty matrix.
+    dtype : data-type, optional
+        Desired output data-type.
+    order : {'C', 'F'}, optional
+        Whether to store multi-dimensional data in row-major
+        (C-style) or column-major (Fortran-style) order in
+        memory.
+
+    See Also
+    --------
+    empty_like, zeros
+
+    Notes
+    -----
+    `empty`, unlike `zeros`, does not set the matrix values to zero,
+    and may therefore be marginally faster.  On the other hand, it requires
+    the user to manually set all the values in the array, and should be
+    used with caution.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.empty((2, 2))    # filled with random data
+    matrix([[  6.76425276e-320,   9.79033856e-307],
+            [  7.39337286e-309,   3.22135945e-309]])        #random
+    >>> np.matlib.empty((2, 2), dtype=int)
+    matrix([[ 6600475,        0],
+            [ 6586976, 22740995]])                          #random
+
+    """
+    return ndarray.__new__(matrix, shape, dtype, order=order)
+
+def ones(shape, dtype=None, order='C'):
+    """
+    Matrix of ones.
+
+    Return a matrix of given shape and type, filled with ones.
+
+    Parameters
+    ----------
+    shape : {sequence of ints, int}
+        Shape of the matrix
+    dtype : data-type, optional
+        The desired data-type for the matrix, default is np.float64.
+    order : {'C', 'F'}, optional
+        Whether to store matrix in C- or Fortran-contiguous order,
+        default is 'C'.
+
+    Returns
+    -------
+    out : matrix
+        Matrix of ones of given shape, dtype, and order.
+
+    See Also
+    --------
+    ones : Array of ones.
+    matlib.zeros : Zero matrix.
+
+    Notes
+    -----
+    If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
+    `out` becomes a single row matrix of shape ``(1,N)``.
+
+    Examples
+    --------
+    >>> np.matlib.ones((2,3))
+    matrix([[ 1.,  1.,  1.],
+            [ 1.,  1.,  1.]])
+
+    >>> np.matlib.ones(2)
+    matrix([[ 1.,  1.]])
+
+    """
+    a = ndarray.__new__(matrix, shape, dtype, order=order)
+    a.fill(1)
+    return a
+
+def zeros(shape, dtype=None, order='C'):
+    """
+    Return a matrix of given shape and type, filled with zeros.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the matrix
+    dtype : data-type, optional
+        The desired data-type for the matrix, default is float.
+    order : {'C', 'F'}, optional
+        Whether to store the result in C- or Fortran-contiguous order,
+        default is 'C'.
+
+    Returns
+    -------
+    out : matrix
+        Zero matrix of given shape, dtype, and order.
+
+    See Also
+    --------
+    numpy.zeros : Equivalent array function.
+    matlib.ones : Return a matrix of ones.
+
+    Notes
+    -----
+    If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
+    `out` becomes a single row matrix of shape ``(1,N)``.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.zeros((2, 3))
+    matrix([[ 0.,  0.,  0.],
+            [ 0.,  0.,  0.]])
+
+    >>> np.matlib.zeros(2)
+    matrix([[ 0.,  0.]])
+
+    """
+    a = ndarray.__new__(matrix, shape, dtype, order=order)
+    a.fill(0)
+    return a
+
+def identity(n,dtype=None):
+    """
+    Returns the square identity matrix of given size.
+
+    Parameters
+    ----------
+    n : int
+        Size of the returned identity matrix.
+    dtype : data-type, optional
+        Data-type of the output. Defaults to ``float``.
+
+    Returns
+    -------
+    out : matrix
+        `n` x `n` matrix with its main diagonal set to one,
+        and all other elements zero.
+
+    See Also
+    --------
+    numpy.identity : Equivalent array function.
+    matlib.eye : More general matrix identity function.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.identity(3, dtype=int)
+    matrix([[1, 0, 0],
+            [0, 1, 0],
+            [0, 0, 1]])
+
+    """
+    a = array([1]+n*[0], dtype=dtype)
+    b = empty((n, n), dtype=dtype)
+    b.flat = a
+    return b
+
+def eye(n,M=None, k=0, dtype=float):
+    """
+    Return a matrix with ones on the diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    n : int
+        Number of rows in the output.
+    M : int, optional
+        Number of columns in the output, defaults to `n`.
+    k : int, optional
+        Index of the diagonal: 0 refers to the main diagonal,
+        a positive value refers to an upper diagonal,
+        and a negative value to a lower diagonal.
+    dtype : dtype, optional
+        Data-type of the returned matrix.
+
+    Returns
+    -------
+    I : matrix
+        A `n` x `M` matrix where all elements are equal to zero,
+        except for the `k`-th diagonal, whose values are equal to one.
+
+    See Also
+    --------
+    numpy.eye : Equivalent array function.
+    identity : Square identity matrix.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.eye(3, k=1, dtype=float)
+    matrix([[ 0.,  1.,  0.],
+            [ 0.,  0.,  1.],
+            [ 0.,  0.,  0.]])
+
+    """
+    return asmatrix(np.eye(n, M, k, dtype))
+
+def rand(*args):
+    """
+    Return a matrix of random values with given shape.
+
+    Create a matrix of the given shape and propagate it with
+    random samples from a uniform distribution over ``[0, 1)``.
+
+    Parameters
+    ----------
+    \\*args : Arguments
+        Shape of the output.
+        If given as N integers, each integer specifies the size of one
+        dimension.
+        If given as a tuple, this tuple gives the complete shape.
+
+    Returns
+    -------
+    out : ndarray
+        The matrix of random values with shape given by `\\*args`.
+
+    See Also
+    --------
+    randn, numpy.random.rand
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.rand(2, 3)
+    matrix([[ 0.68340382,  0.67926887,  0.83271405],
+            [ 0.00793551,  0.20468222,  0.95253525]])       #random
+    >>> np.matlib.rand((2, 3))
+    matrix([[ 0.84682055,  0.73626594,  0.11308016],
+            [ 0.85429008,  0.3294825 ,  0.89139555]])       #random
+
+    If the first argument is a tuple, other arguments are ignored:
+
+    >>> np.matlib.rand((2, 3), 4)
+    matrix([[ 0.46898646,  0.15163588,  0.95188261],
+            [ 0.59208621,  0.09561818,  0.00583606]])       #random
+
+    """
+    if isinstance(args[0], tuple):
+        args = args[0]
+    return asmatrix(np.random.rand(*args))
+
+def randn(*args):
+    """
+    Return a random matrix with data from the "standard normal" distribution.
+
+    `randn` generates a matrix filled with random floats sampled from a
+    univariate "normal" (Gaussian) distribution of mean 0 and variance 1.
+
+    Parameters
+    ----------
+    \\*args : Arguments
+        Shape of the output.
+        If given as N integers, each integer specifies the size of one
+        dimension. If given as a tuple, this tuple gives the complete shape.
+
+    Returns
+    -------
+    Z : matrix of floats
+        A matrix of floating-point samples drawn from the standard normal
+        distribution.
+
+    See Also
+    --------
+    rand, random.randn
+
+    Notes
+    -----
+    For random samples from :math:`N(\\mu, \\sigma^2)`, use:
+
+    ``sigma * np.matlib.randn(...) + mu``
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.randn(1)
+    matrix([[-0.09542833]])                                 #random
+    >>> np.matlib.randn(1, 2, 3)
+    matrix([[ 0.16198284,  0.0194571 ,  0.18312985],
+            [-0.7509172 ,  1.61055   ,  0.45298599]])       #random
+
+    Two-by-four matrix of samples from :math:`N(3, 6.25)`:
+
+    >>> 2.5 * np.matlib.randn((2, 4)) + 3
+    matrix([[ 4.74085004,  8.89381862,  4.09042411,  4.83721922],
+            [ 7.52373709,  5.07933944, -2.64043543,  0.45610557]])  #random
+
+    """
+    if isinstance(args[0], tuple):
+        args = args[0]
+    return asmatrix(np.random.randn(*args))
+
+def repmat(a, m, n):
+    """
+    Repeat a 0-D to 2-D array or matrix MxN times.
+
+    Parameters
+    ----------
+    a : array_like
+        The array or matrix to be repeated.
+    m, n : int
+        The number of times `a` is repeated along the first and second axes.
+
+    Returns
+    -------
+    out : ndarray
+        The result of repeating `a`.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> a0 = np.array(1)
+    >>> np.matlib.repmat(a0, 2, 3)
+    array([[1, 1, 1],
+           [1, 1, 1]])
+
+    >>> a1 = np.arange(4)
+    >>> np.matlib.repmat(a1, 2, 2)
+    array([[0, 1, 2, 3, 0, 1, 2, 3],
+           [0, 1, 2, 3, 0, 1, 2, 3]])
+
+    >>> a2 = np.asmatrix(np.arange(6).reshape(2, 3))
+    >>> np.matlib.repmat(a2, 2, 3)
+    matrix([[0, 1, 2, 0, 1, 2, 0, 1, 2],
+            [3, 4, 5, 3, 4, 5, 3, 4, 5],
+            [0, 1, 2, 0, 1, 2, 0, 1, 2],
+            [3, 4, 5, 3, 4, 5, 3, 4, 5]])
+
+    """
+    a = asanyarray(a)
+    ndim = a.ndim
+    if ndim == 0:
+        origrows, origcols = (1, 1)
+    elif ndim == 1:
+        origrows, origcols = (1, a.shape[0])
+    else:
+        origrows, origcols = a.shape
+    rows = origrows * m
+    cols = origcols * n
+    c = a.reshape(1, a.size).repeat(m, 0).reshape(rows, origcols).repeat(n, 0)
+    return c.reshape(rows, cols)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
new file mode 100644
index 0000000000..b2b76837a8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
@@ -0,0 +1,12 @@
+"""Sub-package containing the matrix class and related functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from .defmatrix import *
+
+__all__ = defmatrix.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
new file mode 100644
index 0000000000..1a29fb67b0
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
@@ -0,0 +1,1242 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['matrix', 'bmat', 'mat', 'asmatrix']
+
+import sys
+import numpy.core.numeric as N
+from numpy.core.numeric import concatenate, isscalar, binary_repr, identity, asanyarray
+from numpy.core.numerictypes import issubdtype
+
+# make translation table
+_numchars = '0123456789.-+jeEL'
+
+if sys.version_info[0] >= 3:
+    class _NumCharTable:
+        def __getitem__(self, i):
+            if chr(i) in _numchars:
+                return chr(i)
+            else:
+                return None
+    _table = _NumCharTable()
+    def _eval(astr):
+        str_ = astr.translate(_table)
+        if not str_:
+            raise TypeError("Invalid data string supplied: " + astr)
+        else:
+            return eval(str_)
+
+else:
+    _table = [None]*256
+    for k in range(256):
+        _table[k] = chr(k)
+    _table = ''.join(_table)
+
+    _todelete = []
+    for k in _table:
+        if k not in _numchars:
+            _todelete.append(k)
+    _todelete = ''.join(_todelete)
+    del k
+
+    def _eval(astr):
+        str_ = astr.translate(_table, _todelete)
+        if not str_:
+            raise TypeError("Invalid data string supplied: " + astr)
+        else:
+            return eval(str_)
+
+def _convert_from_string(data):
+    rows = data.split(';')
+    newdata = []
+    count = 0
+    for row in rows:
+        trow = row.split(',')
+        newrow = []
+        for col in trow:
+            temp = col.split()
+            newrow.extend(map(_eval, temp))
+        if count == 0:
+            Ncols = len(newrow)
+        elif len(newrow) != Ncols:
+            raise ValueError("Rows not the same size.")
+        count += 1
+        newdata.append(newrow)
+    return newdata
+
+def asmatrix(data, dtype=None):
+    """
+    Interpret the input as a matrix.
+
+    Unlike `matrix`, `asmatrix` does not make a copy if the input is already
+    a matrix or an ndarray.  Equivalent to ``matrix(data, copy=False)``.
+
+    Parameters
+    ----------
+    data : array_like
+        Input data.
+    dtype : data-type
+       Data-type of the output matrix.
+
+    Returns
+    -------
+    mat : matrix
+        `data` interpreted as a matrix.
+
+    Examples
+    --------
+    >>> x = np.array([[1, 2], [3, 4]])
+
+    >>> m = np.asmatrix(x)
+
+    >>> x[0,0] = 5
+
+    >>> m
+    matrix([[5, 2],
+            [3, 4]])
+
+    """
+    return matrix(data, dtype=dtype, copy=False)
+
+def matrix_power(M, n):
+    """
+    Raise a square matrix to the (integer) power `n`.
+
+    For positive integers `n`, the power is computed by repeated matrix
+    squarings and matrix multiplications. If ``n == 0``, the identity matrix
+    of the same shape as M is returned. If ``n < 0``, the inverse
+    is computed and then raised to the ``abs(n)``.
+
+    Parameters
+    ----------
+    M : ndarray or matrix object
+        Matrix to be "powered."  Must be square, i.e. ``M.shape == (m, m)``,
+        with `m` a positive integer.
+    n : int
+        The exponent can be any integer or long integer, positive,
+        negative, or zero.
+
+    Returns
+    -------
+    M**n : ndarray or matrix object
+        The return value is the same shape and type as `M`;
+        if the exponent is positive or zero then the type of the
+        elements is the same as those of `M`. If the exponent is
+        negative the elements are floating-point.
+
+    Raises
+    ------
+    LinAlgError
+        If the matrix is not numerically invertible.
+
+    See Also
+    --------
+    matrix
+        Provides an equivalent function as the exponentiation operator
+        (``**``, not ``^``).
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit
+    >>> LA.matrix_power(i, 3) # should = -i
+    array([[ 0, -1],
+           [ 1,  0]])
+    >>> LA.matrix_power(np.matrix(i), 3) # matrix arg returns matrix
+    matrix([[ 0, -1],
+            [ 1,  0]])
+    >>> LA.matrix_power(i, 0)
+    array([[1, 0],
+           [0, 1]])
+    >>> LA.matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements
+    array([[ 0.,  1.],
+           [-1.,  0.]])
+
+    Somewhat more sophisticated example
+
+    >>> q = np.zeros((4, 4))
+    >>> q[0:2, 0:2] = -i
+    >>> q[2:4, 2:4] = i
+    >>> q # one of the three quarternion units not equal to 1
+    array([[ 0., -1.,  0.,  0.],
+           [ 1.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  1.],
+           [ 0.,  0., -1.,  0.]])
+    >>> LA.matrix_power(q, 2) # = -np.eye(4)
+    array([[-1.,  0.,  0.,  0.],
+           [ 0., -1.,  0.,  0.],
+           [ 0.,  0., -1.,  0.],
+           [ 0.,  0.,  0., -1.]])
+
+    """
+    M = asanyarray(M)
+    if len(M.shape) != 2 or M.shape[0] != M.shape[1]:
+        raise ValueError("input must be a square array")
+    if not issubdtype(type(n), int):
+        raise TypeError("exponent must be an integer")
+
+    from numpy.linalg import inv
+
+    if n==0:
+        M = M.copy()
+        M[:] = identity(M.shape[0])
+        return M
+    elif n<0:
+        M = inv(M)
+        n *= -1
+
+    result = M
+    if n <= 3:
+        for _ in range(n-1):
+            result=N.dot(result, M)
+        return result
+
+    # binary decomposition to reduce the number of Matrix
+    # multiplications for n > 3.
+    beta = binary_repr(n)
+    Z, q, t = M, 0, len(beta)
+    while beta[t-q-1] == '0':
+        Z = N.dot(Z, Z)
+        q += 1
+    result = Z
+    for k in range(q+1, t):
+        Z = N.dot(Z, Z)
+        if beta[t-k-1] == '1':
+            result = N.dot(result, Z)
+    return result
+
+
+class matrix(N.ndarray):
+    """
+    matrix(data, dtype=None, copy=True)
+
+    Returns a matrix from an array-like object, or from a string of data.
+    A matrix is a specialized 2-D array that retains its 2-D nature
+    through operations.  It has certain special operators, such as ``*``
+    (matrix multiplication) and ``**`` (matrix power).
+
+    Parameters
+    ----------
+    data : array_like or string
+       If `data` is a string, it is interpreted as a matrix with commas
+       or spaces separating columns, and semicolons separating rows.
+    dtype : data-type
+       Data-type of the output matrix.
+    copy : bool
+       If `data` is already an `ndarray`, then this flag determines
+       whether the data is copied (the default), or whether a view is
+       constructed.
+
+    See Also
+    --------
+    array
+
+    Examples
+    --------
+    >>> a = np.matrix('1 2; 3 4')
+    >>> print(a)
+    [[1 2]
+     [3 4]]
+
+    >>> np.matrix([[1, 2], [3, 4]])
+    matrix([[1, 2],
+            [3, 4]])
+
+    """
+    __array_priority__ = 10.0
+    def __new__(subtype, data, dtype=None, copy=True):
+        if isinstance(data, matrix):
+            dtype2 = data.dtype
+            if (dtype is None):
+                dtype = dtype2
+            if (dtype2 == dtype) and (not copy):
+                return data
+            return data.astype(dtype)
+
+        if isinstance(data, N.ndarray):
+            if dtype is None:
+                intype = data.dtype
+            else:
+                intype = N.dtype(dtype)
+            new = data.view(subtype)
+            if intype != data.dtype:
+                return new.astype(intype)
+            if copy: return new.copy()
+            else: return new
+
+        if isinstance(data, str):
+            data = _convert_from_string(data)
+
+        # now convert data to an array
+        arr = N.array(data, dtype=dtype, copy=copy)
+        ndim = arr.ndim
+        shape = arr.shape
+        if (ndim > 2):
+            raise ValueError("matrix must be 2-dimensional")
+        elif ndim == 0:
+            shape = (1, 1)
+        elif ndim == 1:
+            shape = (1, shape[0])
+
+        order = 'C'
+        if (ndim == 2) and arr.flags.fortran:
+            order = 'F'
+
+        if not (order or arr.flags.contiguous):
+            arr = arr.copy()
+
+        ret = N.ndarray.__new__(subtype, shape, arr.dtype,
+                                buffer=arr,
+                                order=order)
+        return ret
+
+    def __array_finalize__(self, obj):
+        self._getitem = False
+        if (isinstance(obj, matrix) and obj._getitem): return
+        ndim = self.ndim
+        if (ndim == 2):
+            return
+        if (ndim > 2):
+            newshape = tuple([x for x in self.shape if x > 1])
+            ndim = len(newshape)
+            if ndim == 2:
+                self.shape = newshape
+                return
+            elif (ndim > 2):
+                raise ValueError("shape too large to be a matrix.")
+        else:
+            newshape = self.shape
+        if ndim == 0:
+            self.shape = (1, 1)
+        elif ndim == 1:
+            self.shape = (1, newshape[0])
+        return
+
+    def __getitem__(self, index):
+        self._getitem = True
+
+        try:
+            out = N.ndarray.__getitem__(self, index)
+        finally:
+            self._getitem = False
+
+        if not isinstance(out, N.ndarray):
+            return out
+
+        if out.ndim == 0:
+            return out[()]
+        if out.ndim == 1:
+            sh = out.shape[0]
+            # Determine when we should have a column array
+            try:
+                n = len(index)
+            except:
+                n = 0
+            if n > 1 and isscalar(index[1]):
+                out.shape = (sh, 1)
+            else:
+                out.shape = (1, sh)
+        return out
+
+    def __mul__(self, other):
+        if isinstance(other, (N.ndarray, list, tuple)) :
+            # This promotes 1-D vectors to row vectors
+            return N.dot(self, asmatrix(other))
+        if isscalar(other) or not hasattr(other, '__rmul__') :
+            return N.dot(self, other)
+        return NotImplemented
+
+    def __rmul__(self, other):
+        return N.dot(other, self)
+
+    def __imul__(self, other):
+        self[:] = self * other
+        return self
+
+    def __pow__(self, other):
+        return matrix_power(self, other)
+
+    def __ipow__(self, other):
+        self[:] = self ** other
+        return self
+
+    def __rpow__(self, other):
+        return NotImplemented
+
+    def __repr__(self):
+        s = repr(self.__array__()).replace('array', 'matrix')
+        # now, 'matrix' has 6 letters, and 'array' 5, so the columns don't
+        # line up anymore. We need to add a space.
+        l = s.splitlines()
+        for i in range(1, len(l)):
+            if l[i]:
+                l[i] = ' ' + l[i]
+        return '\n'.join(l)
+
+    def __str__(self):
+        return str(self.__array__())
+
+    def _align(self, axis):
+        """A convenience function for operations that need to preserve axis
+        orientation.
+        """
+        if axis is None:
+            return self[0, 0]
+        elif axis==0:
+            return self
+        elif axis==1:
+            return self.transpose()
+        else:
+            raise ValueError("unsupported axis")
+
+    def _collapse(self, axis):
+        """A convenience function for operations that want to collapse
+        to a scalar like _align, but are using keepdims=True
+        """
+        if axis is None:
+            return self[0, 0]
+        else:
+            return self
+
+    # Necessary because base-class tolist expects dimension
+    #  reduction by x[0]
+    def tolist(self):
+        """
+        Return the matrix as a (possibly nested) list.
+
+        See `ndarray.tolist` for full documentation.
+
+        See Also
+        --------
+        ndarray.tolist
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.tolist()
+        [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
+
+        """
+        return self.__array__().tolist()
+
+    # To preserve orientation of result...
+    def sum(self, axis=None, dtype=None, out=None):
+        """
+        Returns the sum of the matrix elements, along the given axis.
+
+        Refer to `numpy.sum` for full documentation.
+
+        See Also
+        --------
+        numpy.sum
+
+        Notes
+        -----
+        This is the same as `ndarray.sum`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix([[1, 2], [4, 3]])
+        >>> x.sum()
+        10
+        >>> x.sum(axis=1)
+        matrix([[3],
+                [7]])
+        >>> x.sum(axis=1, dtype='float')
+        matrix([[ 3.],
+                [ 7.]])
+        >>> out = np.zeros((1, 2), dtype='float')
+        >>> x.sum(axis=1, dtype='float', out=out)
+        matrix([[ 3.],
+                [ 7.]])
+
+        """
+        return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+
+    # To update docstring from array to matrix...
+    def squeeze(self, axis=None):
+        """
+        Return a possibly reshaped matrix.
+
+        Refer to `numpy.squeeze` for more documentation.
+
+        Parameters
+        ----------
+        axis : None or int or tuple of ints, optional
+            Selects a subset of the single-dimensional entries in the shape.
+            If an axis is selected with shape entry greater than one,
+            an error is raised.
+
+        Returns
+        -------
+        squeezed : matrix
+            The matrix, but as a (1, N) matrix if it had shape (N, 1).
+
+        See Also
+        --------
+        numpy.squeeze : related function
+
+        Notes
+        -----
+        If `m` has a single column then that column is returned
+        as the single row of a matrix.  Otherwise `m` is returned.
+        The returned matrix is always either `m` itself or a view into `m`.
+        Supplying an axis keyword argument will not affect the returned matrix
+        but it may cause an error to be raised.
+
+        Examples
+        --------
+        >>> c = np.matrix([[1], [2]])
+        >>> c
+        matrix([[1],
+                [2]])
+        >>> c.squeeze()
+        matrix([[1, 2]])
+        >>> r = c.T
+        >>> r
+        matrix([[1, 2]])
+        >>> r.squeeze()
+        matrix([[1, 2]])
+        >>> m = np.matrix([[1, 2], [3, 4]])
+        >>> m.squeeze()
+        matrix([[1, 2],
+                [3, 4]])
+
+        """
+        return N.ndarray.squeeze(self, axis=axis)
+
+
+    # To update docstring from array to matrix...
+    def flatten(self, order='C'):
+        """
+        Return a flattened copy of the matrix.
+
+        All `N` elements of the matrix are placed into a single row.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            'C' means to flatten in row-major (C-style) order. 'F' means to
+            flatten in column-major (Fortran-style) order. 'A' means to
+            flatten in column-major order if `m` is Fortran *contiguous* in
+            memory, row-major order otherwise. 'K' means to flatten `m` in
+            the order the elements occur in memory. The default is 'C'.
+
+        Returns
+        -------
+        y : matrix
+            A copy of the matrix, flattened to a `(1, N)` matrix where `N`
+            is the number of elements in the original matrix.
+
+        See Also
+        --------
+        ravel : Return a flattened array.
+        flat : A 1-D flat iterator over the matrix.
+
+        Examples
+        --------
+        >>> m = np.matrix([[1,2], [3,4]])
+        >>> m.flatten()
+        matrix([[1, 2, 3, 4]])
+        >>> m.flatten('F')
+        matrix([[1, 3, 2, 4]])
+
+        """
+        return N.ndarray.flatten(self, order=order)
+
+    def mean(self, axis=None, dtype=None, out=None):
+        """
+        Returns the average of the matrix elements along the given axis.
+
+        Refer to `numpy.mean` for full documentation.
+
+        See Also
+        --------
+        numpy.mean
+
+        Notes
+        -----
+        Same as `ndarray.mean` except that, where that returns an `ndarray`,
+        this returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.mean()
+        5.5
+        >>> x.mean(0)
+        matrix([[ 4.,  5.,  6.,  7.]])
+        >>> x.mean(1)
+        matrix([[ 1.5],
+                [ 5.5],
+                [ 9.5]])
+
+        """
+        return N.ndarray.mean(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        """
+        Return the standard deviation of the array elements along the given axis.
+
+        Refer to `numpy.std` for full documentation.
+
+        See Also
+        --------
+        numpy.std
+
+        Notes
+        -----
+        This is the same as `ndarray.std`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.std()
+        3.4520525295346629
+        >>> x.std(0)
+        matrix([[ 3.26598632,  3.26598632,  3.26598632,  3.26598632]])
+        >>> x.std(1)
+        matrix([[ 1.11803399],
+                [ 1.11803399],
+                [ 1.11803399]])
+
+        """
+        return N.ndarray.std(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
+
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        """
+        Returns the variance of the matrix elements, along the given axis.
+
+        Refer to `numpy.var` for full documentation.
+
+        See Also
+        --------
+        numpy.var
+
+        Notes
+        -----
+        This is the same as `ndarray.var`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.var()
+        11.916666666666666
+        >>> x.var(0)
+        matrix([[ 10.66666667,  10.66666667,  10.66666667,  10.66666667]])
+        >>> x.var(1)
+        matrix([[ 1.25],
+                [ 1.25],
+                [ 1.25]])
+
+        """
+        return N.ndarray.var(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
+
+    def prod(self, axis=None, dtype=None, out=None):
+        """
+        Return the product of the array elements over the given axis.
+
+        Refer to `prod` for full documentation.
+
+        See Also
+        --------
+        prod, ndarray.prod
+
+        Notes
+        -----
+        Same as `ndarray.prod`, except, where that returns an `ndarray`, this
+        returns a `matrix` object instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.prod()
+        0
+        >>> x.prod(0)
+        matrix([[  0,  45, 120, 231]])
+        >>> x.prod(1)
+        matrix([[   0],
+                [ 840],
+                [7920]])
+
+        """
+        return N.ndarray.prod(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+    def any(self, axis=None, out=None):
+        """
+        Test whether any array element along a given axis evaluates to True.
+
+        Refer to `numpy.any` for full documentation.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which logical OR is performed
+        out : ndarray, optional
+            Output to existing array instead of creating new one, must have
+            same shape as expected output
+
+        Returns
+        -------
+            any : bool, ndarray
+                Returns a single bool if `axis` is ``None``; otherwise,
+                returns `ndarray`
+
+        """
+        return N.ndarray.any(self, axis, out, keepdims=True)._collapse(axis)
+
+    def all(self, axis=None, out=None):
+        """
+        Test whether all matrix elements along a given axis evaluate to True.
+
+        Parameters
+        ----------
+        See `numpy.all` for complete descriptions
+
+        See Also
+        --------
+        numpy.all
+
+        Notes
+        -----
+        This is the same as `ndarray.all`, but it returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> y = x[0]; y
+        matrix([[0, 1, 2, 3]])
+        >>> (x == y)
+        matrix([[ True,  True,  True,  True],
+                [False, False, False, False],
+                [False, False, False, False]], dtype=bool)
+        >>> (x == y).all()
+        False
+        >>> (x == y).all(0)
+        matrix([[False, False, False, False]], dtype=bool)
+        >>> (x == y).all(1)
+        matrix([[ True],
+                [False],
+                [False]], dtype=bool)
+
+        """
+        return N.ndarray.all(self, axis, out, keepdims=True)._collapse(axis)
+
+    def max(self, axis=None, out=None):
+        """
+        Return the maximum value along an axis.
+
+        Parameters
+        ----------
+        See `amax` for complete descriptions
+
+        See Also
+        --------
+        amax, ndarray.max
+
+        Notes
+        -----
+        This is the same as `ndarray.max`, but returns a `matrix` object
+        where `ndarray.max` would return an ndarray.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.max()
+        11
+        >>> x.max(0)
+        matrix([[ 8,  9, 10, 11]])
+        >>> x.max(1)
+        matrix([[ 3],
+                [ 7],
+                [11]])
+
+        """
+        return N.ndarray.max(self, axis, out, keepdims=True)._collapse(axis)
+
+    def argmax(self, axis=None, out=None):
+        """
+        Indexes of the maximum values along an axis.
+
+        Return the indexes of the first occurrences of the maximum values
+        along the specified axis.  If axis is None, the index is for the
+        flattened matrix.
+
+        Parameters
+        ----------
+        See `numpy.argmax` for complete descriptions
+
+        See Also
+        --------
+        numpy.argmax
+
+        Notes
+        -----
+        This is the same as `ndarray.argmax`, but returns a `matrix` object
+        where `ndarray.argmax` would return an `ndarray`.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.argmax()
+        11
+        >>> x.argmax(0)
+        matrix([[2, 2, 2, 2]])
+        >>> x.argmax(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.argmax(self, axis, out)._align(axis)
+
+    def min(self, axis=None, out=None):
+        """
+        Return the minimum value along an axis.
+
+        Parameters
+        ----------
+        See `amin` for complete descriptions.
+
+        See Also
+        --------
+        amin, ndarray.min
+
+        Notes
+        -----
+        This is the same as `ndarray.min`, but returns a `matrix` object
+        where `ndarray.min` would return an ndarray.
+
+        Examples
+        --------
+        >>> x = -np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[  0,  -1,  -2,  -3],
+                [ -4,  -5,  -6,  -7],
+                [ -8,  -9, -10, -11]])
+        >>> x.min()
+        -11
+        >>> x.min(0)
+        matrix([[ -8,  -9, -10, -11]])
+        >>> x.min(1)
+        matrix([[ -3],
+                [ -7],
+                [-11]])
+
+        """
+        return N.ndarray.min(self, axis, out, keepdims=True)._collapse(axis)
+
+    def argmin(self, axis=None, out=None):
+        """
+        Indexes of the minimum values along an axis.
+
+        Return the indexes of the first occurrences of the minimum values
+        along the specified axis.  If axis is None, the index is for the
+        flattened matrix.
+
+        Parameters
+        ----------
+        See `numpy.argmin` for complete descriptions.
+
+        See Also
+        --------
+        numpy.argmin
+
+        Notes
+        -----
+        This is the same as `ndarray.argmin`, but returns a `matrix` object
+        where `ndarray.argmin` would return an `ndarray`.
+
+        Examples
+        --------
+        >>> x = -np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[  0,  -1,  -2,  -3],
+                [ -4,  -5,  -6,  -7],
+                [ -8,  -9, -10, -11]])
+        >>> x.argmin()
+        11
+        >>> x.argmin(0)
+        matrix([[2, 2, 2, 2]])
+        >>> x.argmin(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.argmin(self, axis, out)._align(axis)
+
+    def ptp(self, axis=None, out=None):
+        """
+        Peak-to-peak (maximum - minimum) value along the given axis.
+
+        Refer to `numpy.ptp` for full documentation.
+
+        See Also
+        --------
+        numpy.ptp
+
+        Notes
+        -----
+        Same as `ndarray.ptp`, except, where that would return an `ndarray` object,
+        this returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.ptp()
+        11
+        >>> x.ptp(0)
+        matrix([[8, 8, 8, 8]])
+        >>> x.ptp(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.ptp(self, axis, out)._align(axis)
+
+    def getI(self):
+        """
+        Returns the (multiplicative) inverse of invertible `self`.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            If `self` is non-singular, `ret` is such that ``ret * self`` ==
+            ``self * ret`` == ``np.matrix(np.eye(self[0,:].size)`` all return
+            ``True``.
+
+        Raises
+        ------
+        numpy.linalg.LinAlgError: Singular matrix
+            If `self` is singular.
+
+        See Also
+        --------
+        linalg.inv
+
+        Examples
+        --------
+        >>> m = np.matrix('[1, 2; 3, 4]'); m
+        matrix([[1, 2],
+                [3, 4]])
+        >>> m.getI()
+        matrix([[-2. ,  1. ],
+                [ 1.5, -0.5]])
+        >>> m.getI() * m
+        matrix([[ 1.,  0.],
+                [ 0.,  1.]])
+
+        """
+        M, N = self.shape
+        if M == N:
+            from numpy.dual import inv as func
+        else:
+            from numpy.dual import pinv as func
+        return asmatrix(func(self))
+
+    def getA(self):
+        """
+        Return `self` as an `ndarray` object.
+
+        Equivalent to ``np.asarray(self)``.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : ndarray
+            `self` as an `ndarray`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.getA()
+        array([[ 0,  1,  2,  3],
+               [ 4,  5,  6,  7],
+               [ 8,  9, 10, 11]])
+
+        """
+        return self.__array__()
+
+    def getA1(self):
+        """
+        Return `self` as a flattened `ndarray`.
+
+        Equivalent to ``np.asarray(x).ravel()``
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : ndarray
+            `self`, 1-D, as an `ndarray`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.getA1()
+        array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
+
+        """
+        return self.__array__().ravel()
+
+
+    def ravel(self, order='C'):
+        """
+        Return a flattened matrix.
+
+        Refer to `numpy.ravel` for more documentation.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            The elements of `m` are read using this index order. 'C' means to
+            index the elements in C-like order, with the last axis index
+            changing fastest, back to the first axis index changing slowest.
+            'F' means to index the elements in Fortran-like index order, with
+            the first index changing fastest, and the last index changing
+            slowest. Note that the 'C' and 'F' options take no account of the
+            memory layout of the underlying array, and only refer to the order
+            of axis indexing.  'A' means to read the elements in Fortran-like
+            index order if `m` is Fortran *contiguous* in memory, C-like order
+            otherwise.  'K' means to read the elements in the order they occur
+            in memory, except for reversing the data when strides are negative.
+            By default, 'C' index order is used.
+
+        Returns
+        -------
+        ret : matrix
+            Return the matrix flattened to shape `(1, N)` where `N`
+            is the number of elements in the original matrix.
+            A copy is made only if necessary.
+
+        See Also
+        --------
+        matrix.flatten : returns a similar output matrix but always a copy
+        matrix.flat : a flat iterator on the array.
+        numpy.ravel : related function which returns an ndarray
+
+        """
+        return N.ndarray.ravel(self, order=order)
+
+
+    def getT(self):
+        """
+        Returns the transpose of the matrix.
+
+        Does *not* conjugate!  For the complex conjugate transpose, use ``.H``.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            The (non-conjugated) transpose of the matrix.
+
+        See Also
+        --------
+        transpose, getH
+
+        Examples
+        --------
+        >>> m = np.matrix('[1, 2; 3, 4]')
+        >>> m
+        matrix([[1, 2],
+                [3, 4]])
+        >>> m.getT()
+        matrix([[1, 3],
+                [2, 4]])
+
+        """
+        return self.transpose()
+
+    def getH(self):
+        """
+        Returns the (complex) conjugate transpose of `self`.
+
+        Equivalent to ``np.transpose(self)`` if `self` is real-valued.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            complex conjugate transpose of `self`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4)))
+        >>> z = x - 1j*x; z
+        matrix([[  0. +0.j,   1. -1.j,   2. -2.j,   3. -3.j],
+                [  4. -4.j,   5. -5.j,   6. -6.j,   7. -7.j],
+                [  8. -8.j,   9. -9.j,  10.-10.j,  11.-11.j]])
+        >>> z.getH()
+        matrix([[  0. +0.j,   4. +4.j,   8. +8.j],
+                [  1. +1.j,   5. +5.j,   9. +9.j],
+                [  2. +2.j,   6. +6.j,  10.+10.j],
+                [  3. +3.j,   7. +7.j,  11.+11.j]])
+
+        """
+        if issubclass(self.dtype.type, N.complexfloating):
+            return self.transpose().conjugate()
+        else:
+            return self.transpose()
+
+    T = property(getT, None)
+    A = property(getA, None)
+    A1 = property(getA1, None)
+    H = property(getH, None)
+    I = property(getI, None)
+
+def _from_string(str, gdict, ldict):
+    rows = str.split(';')
+    rowtup = []
+    for row in rows:
+        trow = row.split(',')
+        newrow = []
+        for x in trow:
+            newrow.extend(x.split())
+        trow = newrow
+        coltup = []
+        for col in trow:
+            col = col.strip()
+            try:
+                thismat = ldict[col]
+            except KeyError:
+                try:
+                    thismat = gdict[col]
+                except KeyError:
+                    raise KeyError("%s not found" % (col,))
+
+            coltup.append(thismat)
+        rowtup.append(concatenate(coltup, axis=-1))
+    return concatenate(rowtup, axis=0)
+
+
+def bmat(obj, ldict=None, gdict=None):
+    """
+    Build a matrix object from a string, nested sequence, or array.
+
+    Parameters
+    ----------
+    obj : str or array_like
+        Input data.  Names of variables in the current scope may be
+        referenced, even if `obj` is a string.
+    ldict : dict, optional
+        A dictionary that replaces local operands in current frame.
+        Ignored if `obj` is not a string or `gdict` is `None`.
+    gdict : dict, optional
+        A dictionary that replaces global operands in current frame.
+        Ignored if `obj` is not a string.
+
+    Returns
+    -------
+    out : matrix
+        Returns a matrix object, which is a specialized 2-D array.
+
+    See Also
+    --------
+    matrix
+
+    Examples
+    --------
+    >>> A = np.mat('1 1; 1 1')
+    >>> B = np.mat('2 2; 2 2')
+    >>> C = np.mat('3 4; 5 6')
+    >>> D = np.mat('7 8; 9 0')
+
+    All the following expressions construct the same block matrix:
+
+    >>> np.bmat([[A, B], [C, D]])
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+    >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]])
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+    >>> np.bmat('A,B; C,D')
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+
+    """
+    if isinstance(obj, str):
+        if gdict is None:
+            # get previous frame
+            frame = sys._getframe().f_back
+            glob_dict = frame.f_globals
+            loc_dict = frame.f_locals
+        else:
+            glob_dict = gdict
+            loc_dict = ldict
+
+        return matrix(_from_string(obj, glob_dict, loc_dict))
+
+    if isinstance(obj, (tuple, list)):
+        # [[A,B],[C,D]]
+        arr_rows = []
+        for row in obj:
+            if isinstance(row, N.ndarray):  # not 2-d
+                return matrix(concatenate(obj, axis=-1))
+            else:
+                arr_rows.append(concatenate(row, axis=-1))
+        return matrix(concatenate(arr_rows, axis=0))
+    if isinstance(obj, N.ndarray):
+        return matrix(obj)
+
+mat = asmatrix
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.py
new file mode 100644
index 0000000000..aa8e0a09be
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+import os
+
+def configuration(parent_package='', top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('matrixlib', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    config = configuration(top_path='').todict()
+    setup(**config)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
new file mode 100644
index 0000000000..6aa24e4ff1
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
@@ -0,0 +1,449 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+
+import numpy as np
+from numpy import matrix, asmatrix, bmat
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_almost_equal,
+    assert_array_equal, assert_array_almost_equal, assert_raises
+)
+from numpy.matrixlib.defmatrix import matrix_power
+from numpy.matrixlib import mat
+
+class TestCtor(TestCase):
+    def test_basic(self):
+        A = np.array([[1, 2], [3, 4]])
+        mA = matrix(A)
+        assert_(np.all(mA.A == A))
+
+        B = bmat("A,A;A,A")
+        C = bmat([[A, A], [A, A]])
+        D = np.array([[1, 2, 1, 2],
+                      [3, 4, 3, 4],
+                      [1, 2, 1, 2],
+                      [3, 4, 3, 4]])
+        assert_(np.all(B.A == D))
+        assert_(np.all(C.A == D))
+
+        E = np.array([[5, 6], [7, 8]])
+        AEresult = matrix([[1, 2, 5, 6], [3, 4, 7, 8]])
+        assert_(np.all(bmat([A, E]) == AEresult))
+
+        vec = np.arange(5)
+        mvec = matrix(vec)
+        assert_(mvec.shape == (1, 5))
+
+    def test_exceptions(self):
+        # Check for TypeError when called with invalid string data.
+        assert_raises(TypeError, matrix, "invalid")
+
+    def test_bmat_nondefault_str(self):
+        A = np.array([[1, 2], [3, 4]])
+        B = np.array([[5, 6], [7, 8]])
+        Aresult = np.array([[1, 2, 1, 2],
+                            [3, 4, 3, 4],
+                            [1, 2, 1, 2],
+                            [3, 4, 3, 4]])
+        mixresult = np.array([[1, 2, 5, 6],
+                              [3, 4, 7, 8],
+                              [5, 6, 1, 2],
+                              [7, 8, 3, 4]])
+        assert_(np.all(bmat("A,A;A,A") == Aresult))
+        assert_(np.all(bmat("A,A;A,A", ldict={'A':B}) == Aresult))
+        assert_raises(TypeError, bmat, "A,A;A,A", gdict={'A':B})
+        assert_(
+            np.all(bmat("A,A;A,A", ldict={'A':A}, gdict={'A':B}) == Aresult))
+        b2 = bmat("A,B;C,D", ldict={'A':A,'B':B}, gdict={'C':B,'D':A})
+        assert_(np.all(b2 == mixresult))
+
+
+class TestProperties(TestCase):
+    def test_sum(self):
+        """Test whether matrix.sum(axis=1) preserves orientation.
+        Fails in NumPy <= 0.9.6.2127.
+        """
+        M = matrix([[1, 2, 0, 0],
+                   [3, 4, 0, 0],
+                   [1, 2, 1, 2],
+                   [3, 4, 3, 4]])
+        sum0 = matrix([8, 12, 4, 6])
+        sum1 = matrix([3, 7, 6, 14]).T
+        sumall = 30
+        assert_array_equal(sum0, M.sum(axis=0))
+        assert_array_equal(sum1, M.sum(axis=1))
+        assert_equal(sumall, M.sum())
+
+        assert_array_equal(sum0, np.sum(M, axis=0))
+        assert_array_equal(sum1, np.sum(M, axis=1))
+        assert_equal(sumall, np.sum(M))
+
+    def test_prod(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.prod(), 720)
+        assert_equal(x.prod(0), matrix([[4, 10, 18]]))
+        assert_equal(x.prod(1), matrix([[6], [120]]))
+
+        assert_equal(np.prod(x), 720)
+        assert_equal(np.prod(x, axis=0), matrix([[4, 10, 18]]))
+        assert_equal(np.prod(x, axis=1), matrix([[6], [120]]))
+
+        y = matrix([0, 1, 3])
+        assert_(y.prod() == 0)
+
+    def test_max(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.max(), 6)
+        assert_equal(x.max(0), matrix([[4, 5, 6]]))
+        assert_equal(x.max(1), matrix([[3], [6]]))
+
+        assert_equal(np.max(x), 6)
+        assert_equal(np.max(x, axis=0), matrix([[4, 5, 6]]))
+        assert_equal(np.max(x, axis=1), matrix([[3], [6]]))
+
+    def test_min(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.min(), 1)
+        assert_equal(x.min(0), matrix([[1, 2, 3]]))
+        assert_equal(x.min(1), matrix([[1], [4]]))
+
+        assert_equal(np.min(x), 1)
+        assert_equal(np.min(x, axis=0), matrix([[1, 2, 3]]))
+        assert_equal(np.min(x, axis=1), matrix([[1], [4]]))
+
+    def test_ptp(self):
+        x = np.arange(4).reshape((2, 2))
+        assert_(x.ptp() == 3)
+        assert_(np.all(x.ptp(0) == np.array([2, 2])))
+        assert_(np.all(x.ptp(1) == np.array([1, 1])))
+
+    def test_var(self):
+        x = np.arange(9).reshape((3, 3))
+        mx = x.view(np.matrix)
+        assert_equal(x.var(ddof=0), mx.var(ddof=0))
+        assert_equal(x.var(ddof=1), mx.var(ddof=1))
+
+    def test_basic(self):
+        import numpy.linalg as linalg
+
+        A = np.array([[1., 2.],
+                      [3., 4.]])
+        mA = matrix(A)
+        assert_(np.allclose(linalg.inv(A), mA.I))
+        assert_(np.all(np.array(np.transpose(A) == mA.T)))
+        assert_(np.all(np.array(np.transpose(A) == mA.H)))
+        assert_(np.all(A == mA.A))
+
+        B = A + 2j*A
+        mB = matrix(B)
+        assert_(np.allclose(linalg.inv(B), mB.I))
+        assert_(np.all(np.array(np.transpose(B) == mB.T)))
+        assert_(np.all(np.array(np.transpose(B).conj() == mB.H)))
+
+    def test_pinv(self):
+        x = matrix(np.arange(6).reshape(2, 3))
+        xpinv = matrix([[-0.77777778,  0.27777778],
+                        [-0.11111111,  0.11111111],
+                        [ 0.55555556, -0.05555556]])
+        assert_almost_equal(x.I, xpinv)
+
+    def test_comparisons(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = matrix(A)
+        mB = matrix(A) + 0.1
+        assert_(np.all(mB == A+0.1))
+        assert_(np.all(mB == matrix(A+0.1)))
+        assert_(not np.any(mB == matrix(A-0.1)))
+        assert_(np.all(mA < mB))
+        assert_(np.all(mA <= mB))
+        assert_(np.all(mA <= mA))
+        assert_(not np.any(mA < mA))
+
+        assert_(not np.any(mB < mA))
+        assert_(np.all(mB >= mA))
+        assert_(np.all(mB >= mB))
+        assert_(not np.any(mB > mB))
+
+        assert_(np.all(mA == mA))
+        assert_(not np.any(mA == mB))
+        assert_(np.all(mB != mA))
+
+        assert_(not np.all(abs(mA) > 0))
+        assert_(np.all(abs(mB > 0)))
+
+    def test_asmatrix(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = asmatrix(A)
+        A[0, 0] = -10
+        assert_(A[0, 0] == mA[0, 0])
+
+    def test_noaxis(self):
+        A = matrix([[1, 0], [0, 1]])
+        assert_(A.sum() == matrix(2))
+        assert_(A.mean() == matrix(0.5))
+
+    def test_repr(self):
+        A = matrix([[1, 0], [0, 1]])
+        assert_(repr(A) == "matrix([[1, 0],\n        [0, 1]])")
+
+class TestCasting(TestCase):
+    def test_basic(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = matrix(A)
+
+        mB = mA.copy()
+        O = np.ones((10, 10), np.float64) * 0.1
+        mB = mB + O
+        assert_(mB.dtype.type == np.float64)
+        assert_(np.all(mA != mB))
+        assert_(np.all(mB == mA+0.1))
+
+        mC = mA.copy()
+        O = np.ones((10, 10), np.complex128)
+        mC = mC * O
+        assert_(mC.dtype.type == np.complex128)
+        assert_(np.all(mA != mB))
+
+
+class TestAlgebra(TestCase):
+    def test_basic(self):
+        import numpy.linalg as linalg
+
+        A = np.array([[1., 2.], [3., 4.]])
+        mA = matrix(A)
+
+        B = np.identity(2)
+        for i in range(6):
+            assert_(np.allclose((mA ** i).A, B))
+            B = np.dot(B, A)
+
+        Ainv = linalg.inv(A)
+        B = np.identity(2)
+        for i in range(6):
+            assert_(np.allclose((mA ** -i).A, B))
+            B = np.dot(B, Ainv)
+
+        assert_(np.allclose((mA * mA).A, np.dot(A, A)))
+        assert_(np.allclose((mA + mA).A, (A + A)))
+        assert_(np.allclose((3*mA).A, (3*A)))
+
+        mA2 = matrix(A)
+        mA2 *= 3
+        assert_(np.allclose(mA2.A, 3*A))
+
+    def test_pow(self):
+        """Test raising a matrix to an integer power works as expected."""
+        m = matrix("1. 2.; 3. 4.")
+        m2 = m.copy()
+        m2 **= 2
+        mi = m.copy()
+        mi **= -1
+        m4 = m2.copy()
+        m4 **= 2
+        assert_array_almost_equal(m2, m**2)
+        assert_array_almost_equal(m4, np.dot(m2, m2))
+        assert_array_almost_equal(np.dot(mi, m), np.eye(2))
+
+    def test_notimplemented(self):
+        '''Check that 'not implemented' operations produce a failure.'''
+        A = matrix([[1., 2.],
+                    [3., 4.]])
+
+        # __rpow__
+        try:
+            1.0**A
+        except TypeError:
+            pass
+        else:
+            self.fail("matrix.__rpow__ doesn't raise a TypeError")
+
+        # __mul__ with something not a list, ndarray, tuple, or scalar
+        try:
+            A*object()
+        except TypeError:
+            pass
+        else:
+            self.fail("matrix.__mul__ with non-numeric object doesn't raise"
+                      "a TypeError")
+
+class TestMatrixReturn(TestCase):
+    def test_instance_methods(self):
+        a = matrix([1.0], dtype='f8')
+        methodargs = {
+            'astype': ('intc',),
+            'clip': (0.0, 1.0),
+            'compress': ([1],),
+            'repeat': (1,),
+            'reshape': (1,),
+            'swapaxes': (0, 0),
+            'dot': np.array([1.0]),
+            }
+        excluded_methods = [
+            'argmin', 'choose', 'dump', 'dumps', 'fill', 'getfield',
+            'getA', 'getA1', 'item', 'nonzero', 'put', 'putmask', 'resize',
+            'searchsorted', 'setflags', 'setfield', 'sort',
+            'partition', 'argpartition',
+            'take', 'tofile', 'tolist', 'tostring', 'tobytes', 'all', 'any',
+            'sum', 'argmax', 'argmin', 'min', 'max', 'mean', 'var', 'ptp',
+            'prod', 'std', 'ctypes', 'itemset',
+            ]
+        for attrib in dir(a):
+            if attrib.startswith('_') or attrib in excluded_methods:
+                continue
+            f = getattr(a, attrib)
+            if isinstance(f, collections.Callable):
+                # reset contents of a
+                a.astype('f8')
+                a.fill(1.0)
+                if attrib in methodargs:
+                    args = methodargs[attrib]
+                else:
+                    args = ()
+                b = f(*args)
+                assert_(type(b) is matrix, "%s" % attrib)
+        assert_(type(a.real) is matrix)
+        assert_(type(a.imag) is matrix)
+        c, d = matrix([0.0]).nonzero()
+        assert_(type(c) is np.ndarray)
+        assert_(type(d) is np.ndarray)
+
+
+class TestIndexing(TestCase):
+    def test_basic(self):
+        x = asmatrix(np.zeros((3, 2), float))
+        y = np.zeros((3, 1), float)
+        y[:, 0] = [0.8, 0.2, 0.3]
+        x[:, 1] = y > 0.5
+        assert_equal(x, [[0, 1], [0, 0], [0, 0]])
+
+
+class TestNewScalarIndexing(TestCase):
+    def setUp(self):
+        self.a = matrix([[1, 2], [3, 4]])
+
+    def test_dimesions(self):
+        a = self.a
+        x = a[0]
+        assert_equal(x.ndim, 2)
+
+    def test_array_from_matrix_list(self):
+        a = self.a
+        x = np.array([a, a])
+        assert_equal(x.shape, [2, 2, 2])
+
+    def test_array_to_list(self):
+        a = self.a
+        assert_equal(a.tolist(), [[1, 2], [3, 4]])
+
+    def test_fancy_indexing(self):
+        a = self.a
+        x = a[1, [0, 1, 0]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[3,  4,  3]]))
+        x = a[[1, 0]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[3,  4], [1, 2]]))
+        x = a[[[1], [0]], [[1, 0], [0, 1]]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[4,  3], [1,  2]]))
+
+    def test_matrix_element(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x[0][0], matrix([[1, 2, 3]]))
+        assert_equal(x[0][0].shape, (1, 3))
+        assert_equal(x[0].shape, (1, 3))
+        assert_equal(x[:, 0].shape, (2, 1))
+
+        x = matrix(0)
+        assert_equal(x[0, 0], 0)
+        assert_equal(x[0], 0)
+        assert_equal(x[:, 0].shape, x.shape)
+
+    def test_scalar_indexing(self):
+        x = asmatrix(np.zeros((3, 2), float))
+        assert_equal(x[0, 0], x[0][0])
+
+    def test_row_column_indexing(self):
+        x = asmatrix(np.eye(2))
+        assert_array_equal(x[0,:], [[1, 0]])
+        assert_array_equal(x[1,:], [[0, 1]])
+        assert_array_equal(x[:, 0], [[1], [0]])
+        assert_array_equal(x[:, 1], [[0], [1]])
+
+    def test_boolean_indexing(self):
+        A = np.arange(6)
+        A.shape = (3, 2)
+        x = asmatrix(A)
+        assert_array_equal(x[:, np.array([True, False])], x[:, 0])
+        assert_array_equal(x[np.array([True, False, False]),:], x[0,:])
+
+    def test_list_indexing(self):
+        A = np.arange(6)
+        A.shape = (3, 2)
+        x = asmatrix(A)
+        assert_array_equal(x[:, [1, 0]], x[:, ::-1])
+        assert_array_equal(x[[2, 1, 0],:], x[::-1,:])
+
+
+class TestPower(TestCase):
+    def test_returntype(self):
+        a = np.array([[0, 1], [0, 0]])
+        assert_(type(matrix_power(a, 2)) is np.ndarray)
+        a = mat(a)
+        assert_(type(matrix_power(a, 2)) is matrix)
+
+    def test_list(self):
+        assert_array_equal(matrix_power([[0, 1], [0, 0]], 2), [[0, 0], [0, 0]])
+
+
+class TestShape(TestCase):
+    def setUp(self):
+        self.a = np.array([[1], [2]])
+        self.m = matrix([[1], [2]])
+
+    def test_shape(self):
+        assert_equal(self.a.shape, (2, 1))
+        assert_equal(self.m.shape, (2, 1))
+
+    def test_numpy_ravel(self):
+        assert_equal(np.ravel(self.a).shape, (2,))
+        assert_equal(np.ravel(self.m).shape, (2,))
+
+    def test_member_ravel(self):
+        assert_equal(self.a.ravel().shape, (2,))
+        assert_equal(self.m.ravel().shape, (1, 2))
+
+    def test_member_flatten(self):
+        assert_equal(self.a.flatten().shape, (2,))
+        assert_equal(self.m.flatten().shape, (1, 2))
+
+    def test_numpy_ravel_order(self):
+        x = np.array([[1, 2, 3], [4, 5, 6]])
+        assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
+        assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
+        assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
+
+    def test_matrix_ravel_order(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.ravel(), [[1, 2, 3, 4, 5, 6]])
+        assert_equal(x.ravel(order='F'), [[1, 4, 2, 5, 3, 6]])
+        assert_equal(x.T.ravel(), [[1, 4, 2, 5, 3, 6]])
+        assert_equal(x.T.ravel(order='A'), [[1, 2, 3, 4, 5, 6]])
+
+    def test_array_memory_sharing(self):
+        assert_(np.may_share_memory(self.a, self.a.ravel()))
+        assert_(not np.may_share_memory(self.a, self.a.flatten()))
+
+    def test_matrix_memory_sharing(self):
+        assert_(np.may_share_memory(self.m, self.m.ravel()))
+        assert_(not np.may_share_memory(self.m, self.m.flatten()))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
new file mode 100644
index 0000000000..d27e24ec96
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal
+)
+
+class TestView(TestCase):
+    def test_type(self):
+        x = np.array([1, 2, 3])
+        assert_(isinstance(x.view(np.matrix), np.matrix))
+
+    def test_keywords(self):
+        x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i2', type=np.matrix)
+        assert_array_equal(y, [[513]])
+
+        assert_(isinstance(y, np.matrix))
+        assert_equal(y.dtype, np.dtype('<i2'))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
new file mode 100644
index 0000000000..28329da393
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_equal, TestCase, run_module_suite
+
+class TestDot(TestCase):
+    def test_matscalar(self):
+        b1 = np.matrix(np.ones((3, 3), dtype=complex))
+        assert_equal(b1*1.0, b1)
+
+
+def test_diagonal():
+    b1 = np.matrix([[1,2],[3,4]])
+    diag_b1 = np.matrix([[1, 4]])
+    array_b1 = np.array([1, 4])
+
+    assert_equal(b1.diagonal(), diag_b1)
+    assert_equal(np.diagonal(b1), array_b1)
+    assert_equal(np.diag(b1), array_b1)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
new file mode 100644
index 0000000000..0839fbf28a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
@@ -0,0 +1,37 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal
+
+rlevel = 1
+
+class TestRegression(TestCase):
+    def test_kron_matrix(self, level=rlevel):
+        # Ticket #71
+        x = np.matrix('[1 0; 1 0]')
+        assert_equal(type(np.kron(x, x)), type(x))
+
+    def test_matrix_properties(self,level=rlevel):
+        # Ticket #125
+        a = np.matrix([1.0], dtype=float)
+        assert_(type(a.real) is np.matrix)
+        assert_(type(a.imag) is np.matrix)
+        c, d = np.matrix([0.0]).nonzero()
+        assert_(type(c) is np.ndarray)
+        assert_(type(d) is np.ndarray)
+
+    def test_matrix_multiply_by_1d_vector(self, level=rlevel):
+        # Ticket #473
+        def mul():
+            np.mat(np.eye(2))*np.ones(2)
+
+        self.assertRaises(ValueError, mul)
+
+    def test_matrix_std_argmax(self,level=rlevel):
+        # Ticket #83
+        x = np.asmatrix(np.random.uniform(0, 1, (3, 3)))
+        self.assertEqual(x.std().shape, ())
+        self.assertEqual(x.argmax().shape, ())
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.py
new file mode 100644
index 0000000000..82c350e9b2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.py
@@ -0,0 +1,27 @@
+"""
+A sub-package for efficiently dealing with polynomials.
+
+Within the documentation for this sub-package, a "finite power series,"
+i.e., a polynomial (also referred to simply as a "series") is represented
+by a 1-D numpy array of the polynomial's coefficients, ordered from lowest
+order term to highest.  For example, array([1,2,3]) represents
+``P_0 + 2*P_1 + 3*P_2``, where P_n is the n-th order basis polynomial
+applicable to the specific module in question, e.g., `polynomial` (which
+"wraps" the "standard" basis) or `chebyshev`.  For optimal performance,
+all operations on polynomials, including evaluation at an argument, are
+implemented as operations on the coefficients.  Additional (module-specific)
+information can be found in the docstring for the module of interest.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from .polynomial import Polynomial
+from .chebyshev import Chebyshev
+from .legendre import Legendre
+from .hermite import Hermite
+from .hermite_e import HermiteE
+from .laguerre import Laguerre
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
new file mode 100644
index 0000000000..6fa72b6f92
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
@@ -0,0 +1,965 @@
+"""
+Abstract base class for the various polynomial Classes.
+
+The ABCPolyBase class provides the methods needed to implement the common API
+for the various polynomial classes. It operates as a mixin, but uses the
+abc module from the stdlib, hence it is only available for Python >= 2.6.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from abc import ABCMeta, abstractmethod, abstractproperty
+from numbers import Number
+
+import numpy as np
+from . import polyutils as pu
+
+__all__ = ['ABCPolyBase']
+
+class ABCPolyBase(object):
+    """An abstract base class for series classes.
+
+    ABCPolyBase provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' along with the
+    methods listed below.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    coef : array_like
+        Series coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``, where
+        ``P_i`` is the basis polynomials of degree ``i``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is the derived class domain.
+    window : (2,) array_like, optional
+        Window, see domain for its use. The default value is the
+        derived class window.
+
+    Attributes
+    ----------
+    coef : (N,) ndarray
+        Series coefficients in order of increasing degree.
+    domain : (2,) ndarray
+        Domain that is mapped to window.
+    window : (2,) ndarray
+        Window that domain is mapped to.
+
+    Class Attributes
+    ----------------
+    maxpower : int
+        Maximum power allowed, i.e., the largest number ``n`` such that
+        ``p(x)**n`` is allowed. This is to limit runaway polynomial size.
+    domain : (2,) ndarray
+        Default domain of the class.
+    window : (2,) ndarray
+        Default window of the class.
+
+    """
+    __metaclass__ = ABCMeta
+
+    # Not hashable
+    __hash__ = None
+
+    # Don't let participate in array operations. Value doesn't matter.
+    __array_priority__ = 1000
+
+    # Limit runaway size. T_n^m has degree n*m
+    maxpower = 100
+
+    @abstractproperty
+    def domain(self):
+        pass
+
+    @abstractproperty
+    def window(self):
+        pass
+
+    @abstractproperty
+    def nickname(self):
+        pass
+
+    @abstractmethod
+    def _add(self):
+        pass
+
+    @abstractmethod
+    def _sub(self):
+        pass
+
+    @abstractmethod
+    def _mul(self):
+        pass
+
+    @abstractmethod
+    def _div(self):
+        pass
+
+    @abstractmethod
+    def _pow(self):
+        pass
+
+    @abstractmethod
+    def _val(self):
+        pass
+
+    @abstractmethod
+    def _int(self):
+        pass
+
+    @abstractmethod
+    def _der(self):
+        pass
+
+    @abstractmethod
+    def _fit(self):
+        pass
+
+    @abstractmethod
+    def _line(self):
+        pass
+
+    @abstractmethod
+    def _roots(self):
+        pass
+
+    @abstractmethod
+    def _fromroots(self):
+        pass
+
+    def has_samecoef(self, other):
+        """Check if coefficients match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``coef`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the coefficients are the same, False otherwise.
+
+        """
+        if len(self.coef) != len(other.coef):
+            return False
+        elif not np.all(self.coef == other.coef):
+            return False
+        else:
+            return True
+
+    def has_samedomain(self, other):
+        """Check if domains match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``domain`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the domains are the same, False otherwise.
+
+        """
+        return np.all(self.domain == other.domain)
+
+    def has_samewindow(self, other):
+        """Check if windows match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``window`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the windows are the same, False otherwise.
+
+        """
+        return np.all(self.window == other.window)
+
+    def has_sametype(self, other):
+        """Check if types match.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        other : object
+            Class instance.
+
+        Returns
+        -------
+        bool : boolean
+            True if other is same class as self
+
+        """
+        return isinstance(other, self.__class__)
+
+    def _get_coefficients(self, other):
+        """Interpret other as polynomial coefficients.
+
+        The `other` argument is checked to see if it is of the same
+        class as self with identical domain and window. If so,
+        return its coefficients, otherwise return `other`.
+
+        .. versionadded:: 1.9.0
+
+        Parameters
+        ----------
+        other : anything
+            Object to be checked.
+
+        Returns
+        -------
+        coef:
+            The coefficients of`other` if it is a compatible instance,
+            of ABCPolyBase, otherwise `other`.
+
+        Raises
+        ------
+        TypeError:
+            When `other` is an incompatible instance of ABCPolyBase.
+
+        """
+        if isinstance(other, ABCPolyBase):
+            if not isinstance(other, self.__class__):
+                raise TypeError("Polynomial types differ")
+            elif not np.all(self.domain == other.domain):
+                raise TypeError("Domains differ")
+            elif not np.all(self.window == other.window):
+                raise TypeError("Windows differ")
+            return other.coef
+        return other
+
+    def __init__(self, coef, domain=None, window=None):
+        [coef] = pu.as_series([coef], trim=False)
+        self.coef = coef
+
+        if domain is not None:
+            [domain] = pu.as_series([domain], trim=False)
+            if len(domain) != 2:
+                raise ValueError("Domain has wrong number of elements.")
+            self.domain = domain
+
+        if window is not None:
+            [window] = pu.as_series([window], trim=False)
+            if len(window) != 2:
+                raise ValueError("Window has wrong number of elements.")
+            self.window = window
+
+    def __repr__(self):
+        format = "%s(%s, %s, %s)"
+        coef = repr(self.coef)[6:-1]
+        domain = repr(self.domain)[6:-1]
+        window = repr(self.window)[6:-1]
+        name = self.__class__.__name__
+        return format % (name, coef, domain, window)
+
+    def __str__(self):
+        format = "%s(%s)"
+        coef = str(self.coef)
+        name = self.nickname
+        return format % (name, coef)
+
+    # Pickle and copy
+
+    def __getstate__(self):
+        ret = self.__dict__.copy()
+        ret['coef'] = self.coef.copy()
+        ret['domain'] = self.domain.copy()
+        ret['window'] = self.window.copy()
+        return ret
+
+    def __setstate__(self, dict):
+        self.__dict__ = dict
+
+    # Call
+
+    def __call__(self, arg):
+        off, scl = pu.mapparms(self.domain, self.window)
+        arg = off + scl*arg
+        return self._val(arg, self.coef)
+
+    def __iter__(self):
+        return iter(self.coef)
+
+    def __len__(self):
+        return len(self.coef)
+
+    # Numeric properties.
+
+    def __neg__(self):
+        return self.__class__(-self.coef, self.domain, self.window)
+
+    def __pos__(self):
+        return self
+
+    def __add__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._add(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __sub__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._sub(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __mul__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._mul(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __div__(self, other):
+        # set to __floordiv__,  /, for now.
+        return self.__floordiv__(other)
+
+    def __truediv__(self, other):
+        # there is no true divide if the rhs is not a Number, although it
+        # could return the first n elements of an infinite series.
+        # It is hard to see where n would come from, though.
+        if not isinstance(other, Number) or isinstance(other, bool):
+            form = "unsupported types for true division: '%s', '%s'"
+            raise TypeError(form % (type(self), type(other)))
+        return self.__floordiv__(other)
+
+    def __floordiv__(self, other):
+        res = self.__divmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[0]
+
+    def __mod__(self, other):
+        res = self.__divmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[1]
+
+    def __divmod__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            quo, rem = self._div(self.coef, othercoef)
+        except (TypeError, ZeroDivisionError) as e:
+            raise e
+        except:
+            return NotImplemented
+        quo = self.__class__(quo, self.domain, self.window)
+        rem = self.__class__(rem, self.domain, self.window)
+        return quo, rem
+
+    def __pow__(self, other):
+        coef = self._pow(self.coef, other, maxpower=self.maxpower)
+        res = self.__class__(coef, self.domain, self.window)
+        return res
+
+    def __radd__(self, other):
+        try:
+            coef = self._add(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rsub__(self, other):
+        try:
+            coef = self._sub(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rmul__(self, other):
+        try:
+            coef = self._mul(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rdiv__(self, other):
+        # set to __floordiv__ /.
+        return self.__rfloordiv__(other)
+
+    def __rtruediv__(self, other):
+        # An instance of ABCPolyBase is not considered a
+        # Number.
+        return NotImplemented
+
+    def __rfloordiv__(self, other):
+        res = self.__rdivmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[0]
+
+    def __rmod__(self, other):
+        res = self.__rdivmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[1]
+
+    def __rdivmod__(self, other):
+        try:
+            quo, rem = self._div(other, self.coef)
+        except ZeroDivisionError as e:
+            raise e
+        except:
+            return NotImplemented
+        quo = self.__class__(quo, self.domain, self.window)
+        rem = self.__class__(rem, self.domain, self.window)
+        return quo, rem
+
+    # Enhance me
+    # some augmented arithmetic operations could be added here
+
+    def __eq__(self, other):
+        res = (isinstance(other, self.__class__) and
+               np.all(self.domain == other.domain) and
+               np.all(self.window == other.window) and
+               (self.coef.shape == other.coef.shape) and
+               np.all(self.coef == other.coef))
+        return res
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    #
+    # Extra methods.
+    #
+
+    def copy(self):
+        """Return a copy.
+
+        Returns
+        -------
+        new_series : series
+            Copy of self.
+
+        """
+        return self.__class__(self.coef, self.domain, self.window)
+
+    def degree(self):
+        """The degree of the series.
+
+        .. versionadded:: 1.5.0
+
+        Returns
+        -------
+        degree : int
+            Degree of the series, one less than the number of coefficients.
+
+        """
+        return len(self) - 1
+
+    def cutdeg(self, deg):
+        """Truncate series to the given degree.
+
+        Reduce the degree of the series to `deg` by discarding the
+        high order terms. If `deg` is greater than the current degree a
+        copy of the current series is returned. This can be useful in least
+        squares where the coefficients of the high degree terms may be very
+        small.
+
+        .. versionadded:: 1.5.0
+
+        Parameters
+        ----------
+        deg : non-negative int
+            The series is reduced to degree `deg` by discarding the high
+            order terms. The value of `deg` must be a non-negative integer.
+
+        Returns
+        -------
+        new_series : series
+            New instance of series with reduced degree.
+
+        """
+        return self.truncate(deg + 1)
+
+    def trim(self, tol=0):
+        """Remove trailing coefficients
+
+        Remove trailing coefficients until a coefficient is reached whose
+        absolute value greater than `tol` or the beginning of the series is
+        reached. If all the coefficients would be removed the series is set
+        to ``[0]``. A new series instance is returned with the new
+        coefficients.  The current instance remains unchanged.
+
+        Parameters
+        ----------
+        tol : non-negative number.
+            All trailing coefficients less than `tol` will be removed.
+
+        Returns
+        -------
+        new_series : series
+            Contains the new set of coefficients.
+
+        """
+        coef = pu.trimcoef(self.coef, tol)
+        return self.__class__(coef, self.domain, self.window)
+
+    def truncate(self, size):
+        """Truncate series to length `size`.
+
+        Reduce the series to length `size` by discarding the high
+        degree terms. The value of `size` must be a positive integer. This
+        can be useful in least squares where the coefficients of the
+        high degree terms may be very small.
+
+        Parameters
+        ----------
+        size : positive int
+            The series is reduced to length `size` by discarding the high
+            degree terms. The value of `size` must be a positive integer.
+
+        Returns
+        -------
+        new_series : series
+            New instance of series with truncated coefficients.
+
+        """
+        isize = int(size)
+        if isize != size or isize < 1:
+            raise ValueError("size must be a positive integer")
+        if isize >= len(self.coef):
+            coef = self.coef
+        else:
+            coef = self.coef[:isize]
+        return self.__class__(coef, self.domain, self.window)
+
+    def convert(self, domain=None, kind=None, window=None):
+        """Convert series to a different kind and/or domain and/or window.
+
+        Parameters
+        ----------
+        domain : array_like, optional
+            The domain of the converted series. If the value is None,
+            the default domain of `kind` is used.
+        kind : class, optional
+            The polynomial series type class to which the current instance
+            should be converted. If kind is None, then the class of the
+            current instance is used.
+        window : array_like, optional
+            The window of the converted series. If the value is None,
+            the default window of `kind` is used.
+
+        Returns
+        -------
+        new_series : series
+            The returned class can be of different type than the current
+            instance and/or have a different domain and/or different
+            window.
+
+        Notes
+        -----
+        Conversion between domains and class types can result in
+        numerically ill defined series.
+
+        Examples
+        --------
+
+        """
+        if kind is None:
+            kind = self.__class__
+        if domain is None:
+            domain = kind.domain
+        if window is None:
+            window = kind.window
+        return self(kind.identity(domain, window=window))
+
+    def mapparms(self):
+        """Return the mapping parameters.
+
+        The returned values define a linear map ``off + scl*x`` that is
+        applied to the input arguments before the series is evaluated. The
+        map depends on the ``domain`` and ``window``; if the current
+        ``domain`` is equal to the ``window`` the resulting map is the
+        identity.  If the coefficients of the series instance are to be
+        used by themselves outside this class, then the linear function
+        must be substituted for the ``x`` in the standard representation of
+        the base polynomials.
+
+        Returns
+        -------
+        off, scl : float or complex
+            The mapping function is defined by ``off + scl*x``.
+
+        Notes
+        -----
+        If the current domain is the interval ``[l1, r1]`` and the window
+        is ``[l2, r2]``, then the linear mapping function ``L`` is
+        defined by the equations::
+
+            L(l1) = l2
+            L(r1) = r2
+
+        """
+        return pu.mapparms(self.domain, self.window)
+
+    def integ(self, m=1, k=[], lbnd=None):
+        """Integrate.
+
+        Return a series instance that is the definite integral of the
+        current series.
+
+        Parameters
+        ----------
+        m : non-negative int
+            The number of integrations to perform.
+        k : array_like
+            Integration constants. The first constant is applied to the
+            first integration, the second to the second, and so on. The
+            list of values must less than or equal to `m` in length and any
+            missing values are set to zero.
+        lbnd : Scalar
+            The lower bound of the definite integral.
+
+        Returns
+        -------
+        new_series : series
+            A new series representing the integral. The domain is the same
+            as the domain of the integrated series.
+
+        """
+        off, scl = self.mapparms()
+        if lbnd is None:
+            lbnd = 0
+        else:
+            lbnd = off + scl*lbnd
+        coef = self._int(self.coef, m, k, lbnd, 1./scl)
+        return self.__class__(coef, self.domain, self.window)
+
+    def deriv(self, m=1):
+        """Differentiate.
+
+        Return a series instance of that is the derivative of the current
+        series.
+
+        Parameters
+        ----------
+        m : non-negative int
+            Find the derivative of order `m`.
+
+        Returns
+        -------
+        new_series : series
+            A new series representing the derivative. The domain is the same
+            as the domain of the differentiated series.
+
+        """
+        off, scl = self.mapparms()
+        coef = self._der(self.coef, m, scl)
+        return self.__class__(coef, self.domain, self.window)
+
+    def roots(self):
+        """Return the roots of the series polynomial.
+
+        Compute the roots for the series. Note that the accuracy of the
+        roots decrease the further outside the domain they lie.
+
+        Returns
+        -------
+        roots : ndarray
+            Array containing the roots of the series.
+
+        """
+        roots = self._roots(self.coef)
+        return pu.mapdomain(roots, self.window, self.domain)
+
+    def linspace(self, n=100, domain=None):
+        """Return x, y values at equally spaced points in domain.
+
+        Returns the x, y values at `n` linearly spaced points across the
+        domain.  Here y is the value of the polynomial at the points x. By
+        default the domain is the same as that of the series instance.
+        This method is intended mostly as a plotting aid.
+
+        .. versionadded:: 1.5.0
+
+        Parameters
+        ----------
+        n : int, optional
+            Number of point pairs to return. The default value is 100.
+        domain : {None, array_like}, optional
+            If not None, the specified domain is used instead of that of
+            the calling instance. It should be of the form ``[beg,end]``.
+            The default is None which case the class domain is used.
+
+        Returns
+        -------
+        x, y : ndarray
+            x is equal to linspace(self.domain[0], self.domain[1], n) and
+            y is the series evaluated at element of x.
+
+        """
+        if domain is None:
+            domain = self.domain
+        x = np.linspace(domain[0], domain[1], n)
+        y = self(x)
+        return x, y
+
+    @classmethod
+    def fit(cls, x, y, deg, domain=None, rcond=None, full=False, w=None,
+        window=None):
+        """Least squares fit to data.
+
+        Return a series instance that is the least squares fit to the data
+        `y` sampled at `x`. The domain of the returned instance can be
+        specified and this will often result in a superior fit with less
+        chance of ill conditioning.
+
+        Parameters
+        ----------
+        x : array_like, shape (M,)
+            x-coordinates of the M sample points ``(x[i], y[i])``.
+        y : array_like, shape (M,) or (M, K)
+            y-coordinates of the sample points. Several data sets of sample
+            points sharing the same x-coordinates can be fitted at once by
+            passing in a 2D-array that contains one dataset per column.
+        deg : int or 1-D array_like
+            Degree(s) of the fitting polynomials. If `deg` is a single integer
+            all terms up to and including the `deg`'th term are included in the
+            fit. For Numpy versions >= 1.11 a list of integers specifying the
+            degrees of the terms to include may be used instead.
+        domain : {None, [beg, end], []}, optional
+            Domain to use for the returned series. If ``None``,
+            then a minimal domain that covers the points `x` is chosen.  If
+            ``[]`` the class domain is used. The default value was the
+            class domain in NumPy 1.4 and ``None`` in later versions.
+            The ``[]`` option was added in numpy 1.5.0.
+        rcond : float, optional
+            Relative condition number of the fit. Singular values smaller
+            than this relative to the largest singular value will be
+            ignored. The default value is len(x)*eps, where eps is the
+            relative precision of the float type, about 2e-16 in most
+            cases.
+        full : bool, optional
+            Switch determining nature of return value. When it is False
+            (the default) just the coefficients are returned, when True
+            diagnostic information from the singular value decomposition is
+            also returned.
+        w : array_like, shape (M,), optional
+            Weights. If not None the contribution of each point
+            ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+            weights are chosen so that the errors of the products
+            ``w[i]*y[i]`` all have the same variance.  The default value is
+            None.
+
+            .. versionadded:: 1.5.0
+        window : {[beg, end]}, optional
+            Window to use for the returned series. The default
+            value is the default class domain
+
+            .. versionadded:: 1.6.0
+
+        Returns
+        -------
+        new_series : series
+            A series that represents the least squares fit to the data and
+            has the domain specified in the call.
+
+        [resid, rank, sv, rcond] : list
+            These values are only returned if `full` = True
+
+            resid -- sum of squared residuals of the least squares fit
+            rank -- the numerical rank of the scaled Vandermonde matrix
+            sv -- singular values of the scaled Vandermonde matrix
+            rcond -- value of `rcond`.
+
+            For more details, see `linalg.lstsq`.
+
+        """
+        if domain is None:
+            domain = pu.getdomain(x)
+        elif type(domain) is list and len(domain) == 0:
+            domain = cls.domain
+
+        if window is None:
+            window = cls.window
+
+        xnew = pu.mapdomain(x, domain, window)
+        res = cls._fit(xnew, y, deg, w=w, rcond=rcond, full=full)
+        if full:
+            [coef, status] = res
+            return cls(coef, domain=domain, window=window), status
+        else:
+            coef = res
+            return cls(coef, domain=domain, window=window)
+
+    @classmethod
+    def fromroots(cls, roots, domain=[], window=None):
+        """Return series instance that has the specified roots.
+
+        Returns a series representing the product
+        ``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is a
+        list of roots.
+
+        Parameters
+        ----------
+        roots : array_like
+            List of roots.
+        domain : {[], None, array_like}, optional
+            Domain for the resulting series. If None the domain is the
+            interval from the smallest root to the largest. If [] the
+            domain is the class domain. The default is [].
+        window : {None, array_like}, optional
+            Window for the returned series. If None the class window is
+            used. The default is None.
+
+        Returns
+        -------
+        new_series : series
+            Series with the specified roots.
+
+        """
+        [roots] = pu.as_series([roots], trim=False)
+        if domain is None:
+            domain = pu.getdomain(roots)
+        elif type(domain) is list and len(domain) == 0:
+            domain = cls.domain
+
+        if window is None:
+            window = cls.window
+
+        deg = len(roots)
+        off, scl = pu.mapparms(domain, window)
+        rnew = off + scl*roots
+        coef = cls._fromroots(rnew) / scl**deg
+        return cls(coef, domain=domain, window=window)
+
+    @classmethod
+    def identity(cls, domain=None, window=None):
+        """Identity function.
+
+        If ``p`` is the returned series, then ``p(x) == x`` for all
+        values of x.
+
+        Parameters
+        ----------
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+             Series of representing the identity.
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        off, scl = pu.mapparms(window, domain)
+        coef = cls._line(off, scl)
+        return cls(coef, domain, window)
+
+    @classmethod
+    def basis(cls, deg, domain=None, window=None):
+        """Series basis polynomial of degree `deg`.
+
+        Returns the series representing the basis polynomial of degree `deg`.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        deg : int
+            Degree of the basis polynomial for the series. Must be >= 0.
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+            A series with the coefficient of the `deg` term set to one and
+            all others zero.
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        ideg = int(deg)
+
+        if ideg != deg or ideg < 0:
+            raise ValueError("deg must be non-negative integer")
+        return cls([0]*ideg + [1], domain, window)
+
+    @classmethod
+    def cast(cls, series, domain=None, window=None):
+        """Convert series to series of this class.
+
+        The `series` is expected to be an instance of some polynomial
+        series of one of the types supported by by the numpy.polynomial
+        module, but could be some other class that supports the convert
+        method.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        series : series
+            The series instance to be converted.
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+            A series of the same kind as the calling class and equal to
+            `series` when evaluated.
+
+        See Also
+        --------
+        convert : similar instance method
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        return series.convert(domain, cls, window)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
new file mode 100644
index 0000000000..2537bea32d
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
@@ -0,0 +1,2080 @@
+"""
+Objects for dealing with Chebyshev series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Chebyshev series, including a `Chebyshev` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `chebdomain` -- Chebyshev series default domain, [-1,1].
+- `chebzero` -- (Coefficients of the) Chebyshev series that evaluates
+  identically to 0.
+- `chebone` -- (Coefficients of the) Chebyshev series that evaluates
+  identically to 1.
+- `chebx` -- (Coefficients of the) Chebyshev series for the identity map,
+  ``f(x) = x``.
+
+Arithmetic
+----------
+- `chebadd` -- add two Chebyshev series.
+- `chebsub` -- subtract one Chebyshev series from another.
+- `chebmul` -- multiply two Chebyshev series.
+- `chebdiv` -- divide one Chebyshev series by another.
+- `chebpow` -- raise a Chebyshev series to an positive integer power
+- `chebval` -- evaluate a Chebyshev series at given points.
+- `chebval2d` -- evaluate a 2D Chebyshev series at given points.
+- `chebval3d` -- evaluate a 3D Chebyshev series at given points.
+- `chebgrid2d` -- evaluate a 2D Chebyshev series on a Cartesian product.
+- `chebgrid3d` -- evaluate a 3D Chebyshev series on a Cartesian product.
+
+Calculus
+--------
+- `chebder` -- differentiate a Chebyshev series.
+- `chebint` -- integrate a Chebyshev series.
+
+Misc Functions
+--------------
+- `chebfromroots` -- create a Chebyshev series with specified roots.
+- `chebroots` -- find the roots of a Chebyshev series.
+- `chebvander` -- Vandermonde-like matrix for Chebyshev polynomials.
+- `chebvander2d` -- Vandermonde-like matrix for 2D power series.
+- `chebvander3d` -- Vandermonde-like matrix for 3D power series.
+- `chebgauss` -- Gauss-Chebyshev quadrature, points and weights.
+- `chebweight` -- Chebyshev weight function.
+- `chebcompanion` -- symmetrized companion matrix in Chebyshev form.
+- `chebfit` -- least-squares fit returning a Chebyshev series.
+- `chebpts1` -- Chebyshev points of the first kind.
+- `chebpts2` -- Chebyshev points of the second kind.
+- `chebtrim` -- trim leading coefficients from a Chebyshev series.
+- `chebline` -- Chebyshev series representing given straight line.
+- `cheb2poly` -- convert a Chebyshev series to a polynomial.
+- `poly2cheb` -- convert a polynomial to a Chebyshev series.
+
+Classes
+-------
+- `Chebyshev` -- A Chebyshev series class.
+
+See also
+--------
+`numpy.polynomial`
+
+Notes
+-----
+The implementations of multiplication, division, integration, and
+differentiation use the algebraic identities [1]_:
+
+.. math ::
+    T_n(x) = \\frac{z^n + z^{-n}}{2} \\\\
+    z\\frac{dx}{dz} = \\frac{z - z^{-1}}{2}.
+
+where
+
+.. math :: x = \\frac{z + z^{-1}}{2}.
+
+These identities allow a Chebyshev series to be expressed as a finite,
+symmetric Laurent series.  In this module, this sort of Laurent series
+is referred to as a "z-series."
+
+References
+----------
+.. [1] A. T. Benjamin, et al., "Combinatorial Trigonometry with Chebyshev
+  Polynomials," *Journal of Statistical Planning and Inference 14*, 2008
+  (preprint: http://www.math.hmc.edu/~benjamin/papers/CombTrig.pdf, pg. 4)
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'chebzero', 'chebone', 'chebx', 'chebdomain', 'chebline', 'chebadd',
+    'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval',
+    'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots',
+    'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1',
+    'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d',
+    'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion',
+    'chebgauss', 'chebweight']
+
+chebtrim = pu.trimcoef
+
+#
+# A collection of functions for manipulating z-series. These are private
+# functions and do minimal error checking.
+#
+
+def _cseries_to_zseries(c):
+    """Covert Chebyshev series to z-series.
+
+    Covert a Chebyshev series to the equivalent z-series. The result is
+    never an empty array. The dtype of the return is the same as that of
+    the input. No checks are run on the arguments as this routine is for
+    internal use.
+
+    Parameters
+    ----------
+    c : 1-D ndarray
+        Chebyshev coefficients, ordered from low to high
+
+    Returns
+    -------
+    zs : 1-D ndarray
+        Odd length symmetric z-series, ordered from  low to high.
+
+    """
+    n = c.size
+    zs = np.zeros(2*n-1, dtype=c.dtype)
+    zs[n-1:] = c/2
+    return zs + zs[::-1]
+
+
+def _zseries_to_cseries(zs):
+    """Covert z-series to a Chebyshev series.
+
+    Covert a z series to the equivalent Chebyshev series. The result is
+    never an empty array. The dtype of the return is the same as that of
+    the input. No checks are run on the arguments as this routine is for
+    internal use.
+
+    Parameters
+    ----------
+    zs : 1-D ndarray
+        Odd length symmetric z-series, ordered from  low to high.
+
+    Returns
+    -------
+    c : 1-D ndarray
+        Chebyshev coefficients, ordered from  low to high.
+
+    """
+    n = (zs.size + 1)//2
+    c = zs[n-1:].copy()
+    c[1:n] *= 2
+    return c
+
+
+def _zseries_mul(z1, z2):
+    """Multiply two z-series.
+
+    Multiply two z-series to produce a z-series.
+
+    Parameters
+    ----------
+    z1, z2 : 1-D ndarray
+        The arrays must be 1-D but this is not checked.
+
+    Returns
+    -------
+    product : 1-D ndarray
+        The product z-series.
+
+    Notes
+    -----
+    This is simply convolution. If symmetric/anti-symmetric z-series are
+    denoted by S/A then the following rules apply:
+
+    S*S, A*A -> S
+    S*A, A*S -> A
+
+    """
+    return np.convolve(z1, z2)
+
+
+def _zseries_div(z1, z2):
+    """Divide the first z-series by the second.
+
+    Divide `z1` by `z2` and return the quotient and remainder as z-series.
+    Warning: this implementation only applies when both z1 and z2 have the
+    same symmetry, which is sufficient for present purposes.
+
+    Parameters
+    ----------
+    z1, z2 : 1-D ndarray
+        The arrays must be 1-D and have the same symmetry, but this is not
+        checked.
+
+    Returns
+    -------
+
+    (quotient, remainder) : 1-D ndarrays
+        Quotient and remainder as z-series.
+
+    Notes
+    -----
+    This is not the same as polynomial division on account of the desired form
+    of the remainder. If symmetric/anti-symmetric z-series are denoted by S/A
+    then the following rules apply:
+
+    S/S -> S,S
+    A/A -> S,A
+
+    The restriction to types of the same symmetry could be fixed but seems like
+    unneeded generality. There is no natural form for the remainder in the case
+    where there is no symmetry.
+
+    """
+    z1 = z1.copy()
+    z2 = z2.copy()
+    len1 = len(z1)
+    len2 = len(z2)
+    if len2 == 1:
+        z1 /= z2
+        return z1, z1[:1]*0
+    elif len1 < len2:
+        return z1[:1]*0, z1
+    else:
+        dlen = len1 - len2
+        scl = z2[0]
+        z2 /= scl
+        quo = np.empty(dlen + 1, dtype=z1.dtype)
+        i = 0
+        j = dlen
+        while i < j:
+            r = z1[i]
+            quo[i] = z1[i]
+            quo[dlen - i] = r
+            tmp = r*z2
+            z1[i:i+len2] -= tmp
+            z1[j:j+len2] -= tmp
+            i += 1
+            j -= 1
+        r = z1[i]
+        quo[i] = r
+        tmp = r*z2
+        z1[i:i+len2] -= tmp
+        quo /= scl
+        rem = z1[i+1:i-1+len2].copy()
+        return quo, rem
+
+
+def _zseries_der(zs):
+    """Differentiate a z-series.
+
+    The derivative is with respect to x, not z. This is achieved using the
+    chain rule and the value of dx/dz given in the module notes.
+
+    Parameters
+    ----------
+    zs : z-series
+        The z-series to differentiate.
+
+    Returns
+    -------
+    derivative : z-series
+        The derivative
+
+    Notes
+    -----
+    The zseries for x (ns) has been multiplied by two in order to avoid
+    using floats that are incompatible with Decimal and likely other
+    specialized scalar types. This scaling has been compensated by
+    multiplying the value of zs by two also so that the two cancels in the
+    division.
+
+    """
+    n = len(zs)//2
+    ns = np.array([-1, 0, 1], dtype=zs.dtype)
+    zs *= np.arange(-n, n+1)*2
+    d, r = _zseries_div(zs, ns)
+    return d
+
+
+def _zseries_int(zs):
+    """Integrate a z-series.
+
+    The integral is with respect to x, not z. This is achieved by a change
+    of variable using dx/dz given in the module notes.
+
+    Parameters
+    ----------
+    zs : z-series
+        The z-series to integrate
+
+    Returns
+    -------
+    integral : z-series
+        The indefinite integral
+
+    Notes
+    -----
+    The zseries for x (ns) has been multiplied by two in order to avoid
+    using floats that are incompatible with Decimal and likely other
+    specialized scalar types. This scaling has been compensated by
+    dividing the resulting zs by two.
+
+    """
+    n = 1 + len(zs)//2
+    ns = np.array([-1, 0, 1], dtype=zs.dtype)
+    zs = _zseries_mul(zs, ns)
+    div = np.arange(-n, n+1)*2
+    zs[:n] /= div[:n]
+    zs[n+1:] /= div[n+1:]
+    zs[n] = 0
+    return zs
+
+#
+# Chebyshev series functions
+#
+
+
+def poly2cheb(pol):
+    """
+    Convert a polynomial to a Chebyshev series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Chebyshev series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Chebyshev
+        series.
+
+    See Also
+    --------
+    cheb2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> p = P.Polynomial(range(4))
+    >>> p
+    Polynomial([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> c = p.convert(kind=P.Chebyshev)
+    >>> c
+    Chebyshev([ 1.  ,  3.25,  1.  ,  0.75], [-1.,  1.])
+    >>> P.poly2cheb(range(4))
+    array([ 1.  ,  3.25,  1.  ,  0.75])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = chebadd(chebmulx(res), pol[i])
+    return res
+
+
+def cheb2poly(c):
+    """
+    Convert a Chebyshev series to a polynomial.
+
+    Convert an array representing the coefficients of a Chebyshev series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Chebyshev series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2cheb
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> c = P.Chebyshev(range(4))
+    >>> c
+    Chebyshev([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> p = c.convert(kind=P.Polynomial)
+    >>> p
+    Polynomial([ -2.,  -8.,   4.,  12.], [-1.,  1.])
+    >>> P.cheb2poly(range(4))
+    array([ -2.,  -8.,   4.,  12.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n < 3:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1)
+            c1 = polyadd(tmp, polymulx(c1)*2)
+        return polyadd(c0, polymulx(c1))
+
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Chebyshev default domain.
+chebdomain = np.array([-1, 1])
+
+# Chebyshev coefficients representing zero.
+chebzero = np.array([0])
+
+# Chebyshev coefficients representing one.
+chebone = np.array([1])
+
+# Chebyshev coefficients representing the identity x.
+chebx = np.array([0, 1])
+
+
+def chebline(off, scl):
+    """
+    Chebyshev series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Chebyshev series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as C
+    >>> C.chebline(3,2)
+    array([3, 2])
+    >>> C.chebval(-3, C.chebline(3,2)) # should be -3
+    -3.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def chebfromroots(roots):
+    """
+    Generate a Chebyshev series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Chebyshev form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * T_1(x) + ... +  c_n * T_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Chebyshev form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as C
+    >>> C.chebfromroots((-1,0,1)) # x^3 - x relative to the standard basis
+    array([ 0.  , -0.25,  0.  ,  0.25])
+    >>> j = complex(0,1)
+    >>> C.chebfromroots((-j,j)) # x^2 + 1 relative to the standard basis
+    array([ 1.5+0.j,  0.0+0.j,  0.5+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [chebline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [chebmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = chebmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def chebadd(c1, c2):
+    """
+    Add one Chebyshev series to another.
+
+    Returns the sum of two Chebyshev series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Chebyshev series of their sum.
+
+    See Also
+    --------
+    chebsub, chebmul, chebdiv, chebpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Chebyshev series
+    is a Chebyshev series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebadd(c1,c2)
+    array([ 4.,  4.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def chebsub(c1, c2):
+    """
+    Subtract one Chebyshev series from another.
+
+    Returns the difference of two Chebyshev series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Chebyshev series coefficients representing their difference.
+
+    See Also
+    --------
+    chebadd, chebmul, chebdiv, chebpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Chebyshev
+    series is a Chebyshev series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebsub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> C.chebsub(c2,c1) # -C.chebsub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def chebmulx(c):
+    """Multiply a Chebyshev series by x.
+
+    Multiply the polynomial `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    if len(c) > 1:
+        tmp = c[1:]/2
+        prd[2:] = tmp
+        prd[0:-2] += tmp
+    return prd
+
+
+def chebmul(c1, c2):
+    """
+    Multiply one Chebyshev series by another.
+
+    Returns the product of two Chebyshev series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Chebyshev series coefficients representing their product.
+
+    See Also
+    --------
+    chebadd, chebsub, chebdiv, chebpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Chebyshev polynomial basis set.  Thus, to express
+    the product as a C-series, it is typically necessary to "reproject"
+    the product onto said basis set, which typically produces
+    "unintuitive live" (but correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebmul(c1,c2) # multiplication requires "reprojection"
+    array([  6.5,  12. ,  12. ,   4. ,   1.5])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    z1 = _cseries_to_zseries(c1)
+    z2 = _cseries_to_zseries(c2)
+    prd = _zseries_mul(z1, z2)
+    ret = _zseries_to_cseries(prd)
+    return pu.trimseq(ret)
+
+
+def chebdiv(c1, c2):
+    """
+    Divide one Chebyshev series by another.
+
+    Returns the quotient-with-remainder of two Chebyshev series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Chebyshev series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    chebadd, chebsub, chebmul, chebpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one C-series by another
+    results in quotient and remainder terms that are not in the Chebyshev
+    polynomial basis set.  Thus, to express these results as C-series, it
+    is typically necessary to "reproject" the results onto said basis
+    set, which typically produces "unintuitive" (but correct) results;
+    see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebdiv(c1,c2) # quotient "intuitive," remainder not
+    (array([ 3.]), array([-8., -4.]))
+    >>> c2 = (0,1,2,3)
+    >>> C.chebdiv(c2,c1) # neither "intuitive"
+    (array([ 0.,  2.]), array([-2., -4.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        z1 = _cseries_to_zseries(c1)
+        z2 = _cseries_to_zseries(c2)
+        quo, rem = _zseries_div(z1, z2)
+        quo = pu.trimseq(_zseries_to_cseries(quo))
+        rem = pu.trimseq(_zseries_to_cseries(rem))
+        return quo, rem
+
+
+def chebpow(c, pow, maxpower=16):
+    """Raise a Chebyshev series to a power.
+
+    Returns the Chebyshev series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``T_0 + 2*T_1 + 3*T_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Chebyshev series of power.
+
+    See Also
+    --------
+    chebadd, chebsub, chebmul, chebdiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        zs = _cseries_to_zseries(c)
+        prd = zs
+        for i in range(2, power + 1):
+            prd = np.convolve(prd, zs)
+        return _zseries_to_cseries(prd)
+
+
+def chebder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Chebyshev series.
+
+    Returns the Chebyshev series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*T_0 + 2*T_1 + 3*T_2``
+    while [[1,2],[1,2]] represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) +
+    2*T_0(x)*T_1(y) + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Chebyshev series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Chebyshev series of the derivative.
+
+    See Also
+    --------
+    chebint
+
+    Notes
+    -----
+    In general, the result of differentiating a C-series needs to be
+    "reprojected" onto the C-series basis set. Thus, typically, the
+    result of this function is "unintuitive," albeit correct; see Examples
+    section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c = (1,2,3,4)
+    >>> C.chebder(c)
+    array([ 14.,  12.,  24.])
+    >>> C.chebder(c,3)
+    array([ 96.])
+    >>> C.chebder(c,scl=-1)
+    array([-14., -12., -24.])
+    >>> C.chebder(c,2,-1)
+    array([ 12.,  96.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 2, -1):
+                der[j - 1] = (2*j)*c[j]
+                c[j - 2] += (j*c[j])/(j - 2)
+            if n > 1:
+                der[1] = 4*c[2]
+            der[0] = c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Chebyshev series.
+
+    Returns the Chebyshev series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``T_0 + 2*T_1 + 3*T_2`` while [[1,2],[1,2]]
+    represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 2*T_0(x)*T_1(y) +
+    2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Chebyshev series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at zero
+        is the first value in the list, the value of the second integral
+        at zero is the second value, etc.  If ``k == []`` (the default),
+        all constants are set to zero.  If ``m == 1``, a single scalar can
+        be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        C-series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 1``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    chebder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a`- perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c = (1,2,3)
+    >>> C.chebint(c)
+    array([ 0.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,3)
+    array([ 0.03125   , -0.1875    ,  0.04166667, -0.05208333,  0.01041667,
+            0.00625   ])
+    >>> C.chebint(c, k=3)
+    array([ 3.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,lbnd=-2)
+    array([ 8.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,scl=-2)
+    array([-1.,  1., -1., -1.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            if n > 1:
+                tmp[2] = c[1]/4
+            for j in range(2, n):
+                t = c[j]/(2*j + 1)
+                tmp[j + 1] = c[j]/(2*(j + 1))
+                tmp[j - 1] -= c[j]/(2*(j - 1))
+            tmp[0] += k[i] - chebval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def chebval(x, c, tensor=True):
+    """
+    Evaluate a Chebyshev series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * T_0(x) + c_1 * T_1(x) + ... + c_n * T_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    chebval2d, chebgrid2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        x2 = 2*x
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            c0 = c[-i] - c1
+            c1 = tmp + c1*x2
+    return c0 + c1*x
+
+
+def chebval2d(x, y, c):
+    """
+    Evaluate a 2-D Chebyshev series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * T_i(x) * T_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than 2 the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points formed
+        from pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebgrid2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = chebval(x, c)
+    c = chebval(y, c, tensor=False)
+    return c
+
+
+def chebgrid2d(x, y, c):
+    """
+    Evaluate a 2-D Chebyshev series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * T_i(a) * T_j(b),
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = chebval(x, c)
+    c = chebval(y, c)
+    return c
+
+
+def chebval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Chebyshev series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * T_i(x) * T_j(y) * T_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebgrid2d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = chebval(x, c)
+    c = chebval(y, c, tensor=False)
+    c = chebval(z, c, tensor=False)
+    return c
+
+
+def chebgrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * T_i(a) * T_j(b) * T_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebgrid2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = chebval(x, c)
+    c = chebval(y, c)
+    c = chebval(z, c)
+    return c
+
+
+def chebvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = T_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Chebyshev polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    matrix ``V = chebvander(x, n)``, then ``np.dot(V, c)`` and
+    ``chebval(x, c)`` are the same up to roundoff.  This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Chebyshev series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Chebyshev polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    # Use forward recursion to generate the entries.
+    v[0] = x*0 + 1
+    if ideg > 0:
+        x2 = 2*x
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = v[i-1]*x2 - v[i-2]
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def chebvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = T_i(x) * T_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Chebyshev polynomials.
+
+    If ``V = chebvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``chebval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Chebyshev
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    chebvander, chebvander3d. chebval2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = chebvander(x, degx)
+    vy = chebvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def chebvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = T_i(x)*T_j(y)*T_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Chebyshev polynomials.
+
+    If ``V = chebvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and ``np.dot(V, c.flat)`` and ``chebval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Chebyshev
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    chebvander, chebvander3d. chebval2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = chebvander(x, degx)
+    vy = chebvander(y, degy)
+    vz = chebvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def chebfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Chebyshev series to data.
+
+    Return the coefficients of a Legendre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Chebyshev coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    polyfit, legfit, lagfit, hermfit, hermefit
+    chebval : Evaluates a Chebyshev series.
+    chebvander : Vandermonde matrix of Chebyshev series.
+    chebweight : Chebyshev weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Chebyshev series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where :math:`w_j` are the weights. This problem is solved by setting up
+    as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Chebyshev series are usually better conditioned than fits
+    using power series, but much can depend on the distribution of the
+    sample points and the smoothness of the data. If the quality of the fit
+    is inadequate splines may be a good alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = chebvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = chebvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax + 1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax + 1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def chebcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is a Chebyshev basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.array([1.] + [np.sqrt(.5)]*(n-1))
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[0] = np.sqrt(.5)
+    top[1:] = 1/2
+    bot[...] = top
+    mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*.5
+    return mat
+
+
+def chebroots(c):
+    """
+    Compute the roots of a Chebyshev series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * T_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Chebyshev series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as cheb
+    >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots
+    array([ -5.00000000e-01,   2.60860684e-17,   1.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = chebcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def chebgauss(deg):
+    """
+    Gauss-Chebyshev quadrature.
+
+    Computes the sample points and weights for Gauss-Chebyshev quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
+    the weight function :math:`f(x) = 1/\sqrt{1 - x^2}`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. For Gauss-Chebyshev there are closed form solutions for
+    the sample points and weights. If n = `deg`, then
+
+    .. math:: x_i = \cos(\pi (2 i - 1) / (2 n))
+
+    .. math:: w_i = \pi / n
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    x = np.cos(np.pi * np.arange(1, 2*ideg, 2) / (2.0*ideg))
+    w = np.ones(ideg)*(np.pi/ideg)
+
+    return x, w
+
+
+def chebweight(x):
+    """
+    The weight function of the Chebyshev polynomials.
+
+    The weight function is :math:`1/\sqrt{1 - x^2}` and the interval of
+    integration is :math:`[-1, 1]`. The Chebyshev polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    w = 1./(np.sqrt(1. + x) * np.sqrt(1. - x))
+    return w
+
+
+def chebpts1(npts):
+    """
+    Chebyshev points of the first kind.
+
+    The Chebyshev points of the first kind are the points ``cos(x)``,
+    where ``x = [pi*(k + .5)/npts for k in range(npts)]``.
+
+    Parameters
+    ----------
+    npts : int
+        Number of sample points desired.
+
+    Returns
+    -------
+    pts : ndarray
+        The Chebyshev points of the first kind.
+
+    See Also
+    --------
+    chebpts2
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    _npts = int(npts)
+    if _npts != npts:
+        raise ValueError("npts must be integer")
+    if _npts < 1:
+        raise ValueError("npts must be >= 1")
+
+    x = np.linspace(-np.pi, 0, _npts, endpoint=False) + np.pi/(2*_npts)
+    return np.cos(x)
+
+
+def chebpts2(npts):
+    """
+    Chebyshev points of the second kind.
+
+    The Chebyshev points of the second kind are the points ``cos(x)``,
+    where ``x = [pi*k/(npts - 1) for k in range(npts)]``.
+
+    Parameters
+    ----------
+    npts : int
+        Number of sample points desired.
+
+    Returns
+    -------
+    pts : ndarray
+        The Chebyshev points of the second kind.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    _npts = int(npts)
+    if _npts != npts:
+        raise ValueError("npts must be integer")
+    if _npts < 2:
+        raise ValueError("npts must be >= 2")
+
+    x = np.linspace(-np.pi, 0, _npts)
+    return np.cos(x)
+
+
+#
+# Chebyshev series class
+#
+
+class Chebyshev(ABCPolyBase):
+    """A Chebyshev series class.
+
+    The Chebyshev class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    methods listed below.
+
+    Parameters
+    ----------
+    coef : array_like
+        Chebyshev coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*T_0(x) + 2*T_1(x) + 3*T_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(chebadd)
+    _sub = staticmethod(chebsub)
+    _mul = staticmethod(chebmul)
+    _div = staticmethod(chebdiv)
+    _pow = staticmethod(chebpow)
+    _val = staticmethod(chebval)
+    _int = staticmethod(chebint)
+    _der = staticmethod(chebder)
+    _fit = staticmethod(chebfit)
+    _line = staticmethod(chebline)
+    _roots = staticmethod(chebroots)
+    _fromroots = staticmethod(chebfromroots)
+
+    # Virtual properties
+    nickname = 'cheb'
+    domain = np.array(chebdomain)
+    window = np.array(chebdomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.py
new file mode 100644
index 0000000000..e234c8e231
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.py
@@ -0,0 +1,1854 @@
+"""
+Objects for dealing with Hermite series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Hermite series, including a `Hermite` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `hermdomain` -- Hermite series default domain, [-1,1].
+- `hermzero` -- Hermite series that evaluates identically to 0.
+- `hermone` -- Hermite series that evaluates identically to 1.
+- `hermx` -- Hermite series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `hermmulx` -- multiply a Hermite series in ``P_i(x)`` by ``x``.
+- `hermadd` -- add two Hermite series.
+- `hermsub` -- subtract one Hermite series from another.
+- `hermmul` -- multiply two Hermite series.
+- `hermdiv` -- divide one Hermite series by another.
+- `hermval` -- evaluate a Hermite series at given points.
+- `hermval2d` -- evaluate a 2D Hermite series at given points.
+- `hermval3d` -- evaluate a 3D Hermite series at given points.
+- `hermgrid2d` -- evaluate a 2D Hermite series on a Cartesian product.
+- `hermgrid3d` -- evaluate a 3D Hermite series on a Cartesian product.
+
+Calculus
+--------
+- `hermder` -- differentiate a Hermite series.
+- `hermint` -- integrate a Hermite series.
+
+Misc Functions
+--------------
+- `hermfromroots` -- create a Hermite series with specified roots.
+- `hermroots` -- find the roots of a Hermite series.
+- `hermvander` -- Vandermonde-like matrix for Hermite polynomials.
+- `hermvander2d` -- Vandermonde-like matrix for 2D power series.
+- `hermvander3d` -- Vandermonde-like matrix for 3D power series.
+- `hermgauss` -- Gauss-Hermite quadrature, points and weights.
+- `hermweight` -- Hermite weight function.
+- `hermcompanion` -- symmetrized companion matrix in Hermite form.
+- `hermfit` -- least-squares fit returning a Hermite series.
+- `hermtrim` -- trim leading coefficients from a Hermite series.
+- `hermline` -- Hermite series of given straight line.
+- `herm2poly` -- convert a Hermite series to a polynomial.
+- `poly2herm` -- convert a polynomial to a Hermite series.
+
+Classes
+-------
+- `Hermite` -- A Hermite series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd',
+    'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
+    'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
+    'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
+    'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
+    'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
+
+hermtrim = pu.trimcoef
+
+
+def poly2herm(pol):
+    """
+    poly2herm(pol)
+
+    Convert a polynomial to a Hermite series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Hermite series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Hermite
+        series.
+
+    See Also
+    --------
+    herm2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import poly2herm
+    >>> poly2herm(np.arange(4))
+    array([ 1.   ,  2.75 ,  0.5  ,  0.375])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = hermadd(hermmulx(res), pol[i])
+    return res
+
+
+def herm2poly(c):
+    """
+    Convert a Hermite series to a polynomial.
+
+    Convert an array representing the coefficients of a Hermite series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Hermite series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2herm
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import herm2poly
+    >>> herm2poly([ 1.   ,  2.75 ,  0.5  ,  0.375])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    if n == 2:
+        c[1] *= 2
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1*(2*(i - 1)))
+            c1 = polyadd(tmp, polymulx(c1)*2)
+        return polyadd(c0, polymulx(c1)*2)
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Hermite
+hermdomain = np.array([-1, 1])
+
+# Hermite coefficients representing zero.
+hermzero = np.array([0])
+
+# Hermite coefficients representing one.
+hermone = np.array([1])
+
+# Hermite coefficients representing the identity x.
+hermx = np.array([0, 1/2])
+
+
+def hermline(off, scl):
+    """
+    Hermite series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Hermite series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermline, hermval
+    >>> hermval(0,hermline(3, 2))
+    3.0
+    >>> hermval(1,hermline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl/2])
+    else:
+        return np.array([off])
+
+
+def hermfromroots(roots):
+    """
+    Generate a Hermite series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Hermite form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * H_1(x) + ... +  c_n * H_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Hermite form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, chebfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermfromroots, hermval
+    >>> coef = hermfromroots((-1, 0, 1))
+    >>> hermval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = hermfromroots((-1j, 1j))
+    >>> hermval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [hermline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [hermmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = hermmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def hermadd(c1, c2):
+    """
+    Add one Hermite series to another.
+
+    Returns the sum of two Hermite series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Hermite series of their sum.
+
+    See Also
+    --------
+    hermsub, hermmul, hermdiv, hermpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Hermite series
+    is a Hermite series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermadd
+    >>> hermadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermsub(c1, c2):
+    """
+    Subtract one Hermite series from another.
+
+    Returns the difference of two Hermite series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their difference.
+
+    See Also
+    --------
+    hermadd, hermmul, hermdiv, hermpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Hermite
+    series is a Hermite series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermsub
+    >>> hermsub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermmulx(c):
+    """Multiply a Hermite series by x.
+
+    Multiply the Hermite series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Hermite
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (P_{i + 1}(x)/2 + i*P_{i - 1}(x))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermmulx
+    >>> hermmulx([1, 2, 3])
+    array([ 2. ,  6.5,  1. ,  1.5])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]/2
+    for i in range(1, len(c)):
+        prd[i + 1] = c[i]/2
+        prd[i - 1] += c[i]*i
+    return prd
+
+
+def hermmul(c1, c2):
+    """
+    Multiply one Hermite series by another.
+
+    Returns the product of two Hermite series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their product.
+
+    See Also
+    --------
+    hermadd, hermsub, hermdiv, hermpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Hermite polynomial basis set.  Thus, to express
+    the product as a Hermite series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermmul
+    >>> hermmul([1, 2, 3], [0, 1, 2])
+    array([ 52.,  29.,  52.,   7.,   6.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = hermsub(c[-i]*xs, c1*(2*(nd - 1)))
+            c1 = hermadd(tmp, hermmulx(c1)*2)
+    return hermadd(c0, hermmulx(c1)*2)
+
+
+def hermdiv(c1, c2):
+    """
+    Divide one Hermite series by another.
+
+    Returns the quotient-with-remainder of two Hermite series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Hermite series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    hermadd, hermsub, hermmul, hermpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Hermite series by another
+    results in quotient and remainder terms that are not in the Hermite
+    polynomial basis set.  Thus, to express these results as a Hermite
+    series, it is necessary to "reproject" the results onto the Hermite
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermdiv
+    >>> hermdiv([ 52.,  29.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> hermdiv([ 54.,  31.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 2.,  2.]))
+    >>> hermdiv([ 53.,  30.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  1.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = hermmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def hermpow(c, pow, maxpower=16):
+    """Raise a Hermite series to a power.
+
+    Returns the Hermite series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Hermite series of power.
+
+    See Also
+    --------
+    hermadd, hermsub, hermmul, hermdiv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermpow
+    >>> hermpow([1, 2, 3], 2)
+    array([ 81.,  52.,  82.,  12.,   9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = hermmul(prd, c)
+        return prd
+
+
+def hermder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Hermite series.
+
+    Returns the Hermite series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2``
+    while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) +
+    2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite series coefficients. If `c` is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Hermite series of the derivative.
+
+    See Also
+    --------
+    hermint
+
+    Notes
+    -----
+    In general, the result of differentiating a Hermite series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermder
+    >>> hermder([ 1. ,  0.5,  0.5,  0.5])
+    array([ 1.,  2.,  3.])
+    >>> hermder([-0.5,  1./2.,  1./8.,  1./12.,  1./16.], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 0, -1):
+                der[j - 1] = (2*j)*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Hermite series.
+
+    Returns the Hermite series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
+    represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
+    2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Hermite series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    hermder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermint
+    >>> hermint([1,2,3]) # integrate once, value 0 at 0.
+    array([ 1. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0
+    array([-0.5       ,  0.5       ,  0.125     ,  0.08333333,  0.0625    ])
+    >>> hermint([1,2,3], k=1) # integrate once, value 1 at 0.
+    array([ 2. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1
+    array([-2. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1)
+    array([ 1.66666667, -0.5       ,  0.125     ,  0.08333333,  0.0625    ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]/2
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(2*(j + 1))
+            tmp[0] += k[i] - hermval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermval(x, c, tensor=True):
+    """
+    Evaluate an Hermite series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    hermval2d, hermgrid2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermval
+    >>> coef = [1,2,3]
+    >>> hermval(1, coef)
+    11.0
+    >>> hermval([[1,2],[3,4]], coef)
+    array([[  11.,   51.],
+           [ 115.,  203.]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    x2 = x*2
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - c1*(2*(nd - 1))
+            c1 = tmp + c1*x2
+    return c0 + c1*x2
+
+
+def hermval2d(x, y, c):
+    """
+    Evaluate a 2-D Hermite series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermgrid2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = hermval(x, c)
+    c = hermval(y, c, tensor=False)
+    return c
+
+
+def hermgrid2d(x, y, c):
+    """
+    Evaluate a 2-D Hermite series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermval(x, c)
+    c = hermval(y, c)
+    return c
+
+
+def hermval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermgrid2d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = hermval(x, c)
+    c = hermval(y, c, tensor=False)
+    c = hermval(z, c, tensor=False)
+    return c
+
+
+def hermgrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermgrid2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermval(x, c)
+    c = hermval(y, c)
+    c = hermval(z, c)
+    return c
+
+
+def hermvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = H_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Hermite polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and
+    ``hermval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Hermite series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Hermite polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermvander
+    >>> x = np.array([-1, 0, 1])
+    >>> hermvander(x, 3)
+    array([[ 1., -2.,  2.,  4.],
+           [ 1.,  0., -2., -0.],
+           [ 1.,  2.,  2., -4.]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        x2 = x*2
+        v[1] = x2
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x2 - v[i-2]*(2*(i - 1)))
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def hermvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = H_i(x) * H_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Hermite polynomials.
+
+    If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``hermval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Hermite
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    hermvander, hermvander3d. hermval2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = hermvander(x, degx)
+    vy = hermvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def hermvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = H_i(x)*H_j(y)*H_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Hermite polynomials.
+
+    If ``V = hermvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``hermval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Hermite
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermvander, hermvander3d. hermval2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = hermvander(x, degx)
+    vy = hermvander(y, degy)
+    vz = hermvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def hermfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Hermite series to data.
+
+    Return the coefficients of a Hermite series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Hermite coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, lagfit, polyfit, hermefit
+    hermval : Evaluates a Hermite series.
+    hermvander : Vandermonde matrix of Hermite series.
+    hermweight : Hermite weight function
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Hermite series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Hermite series are probably most useful when the data can be
+    approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Hermite
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `hermweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermfit, hermval
+    >>> x = np.linspace(-10, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = hermval(x, [1, 2, 3]) + err
+    >>> hermfit(x, y, 2)
+    array([ 0.97902637,  1.99849131,  3.00006   ])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = hermvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = hermvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def hermcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an Hermite basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-.5*c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.hstack((1., 1./np.sqrt(2.*np.arange(n - 1, 0, -1))))
+    scl = np.multiply.accumulate(scl)[::-1]
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.sqrt(.5*np.arange(1, n))
+    bot[...] = top
+    mat[:, -1] -= scl*c[:-1]/(2.0*c[-1])
+    return mat
+
+
+def hermroots(c):
+    """
+    Compute the roots of a Hermite series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * H_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, chebroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Hermite series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermroots, hermfromroots
+    >>> coef = hermfromroots([-1, 0, 1])
+    >>> coef
+    array([ 0.   ,  0.25 ,  0.   ,  0.125])
+    >>> hermroots(coef)
+    array([ -1.00000000e+00,  -1.38777878e-17,   1.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-.5*c[0]/c[1]])
+
+    m = hermcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def _normed_hermite_n(x, n):
+    """
+    Evaluate a normalized Hermite polynomial.
+
+    Compute the value of the normalized Hermite polynomial of degree ``n``
+    at the points ``x``.
+
+
+    Parameters
+    ----------
+    x : ndarray of double.
+        Points at which to evaluate the function
+    n : int
+        Degree of the normalized Hermite function to be evaluated.
+
+    Returns
+    -------
+    values : ndarray
+        The shape of the return value is described above.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    This function is needed for finding the Gauss points and integration
+    weights for high degrees. The values of the standard Hermite functions
+    overflow when n >= 207.
+
+    """
+    if n == 0:
+        return np.ones(x.shape)/np.sqrt(np.sqrt(np.pi))
+
+    c0 = 0.
+    c1 = 1./np.sqrt(np.sqrt(np.pi))
+    nd = float(n)
+    for i in range(n - 1):
+        tmp = c0
+        c0 = -c1*np.sqrt((nd - 1.)/nd)
+        c1 = tmp + c1*x*np.sqrt(2./nd)
+        nd = nd - 1.0
+    return c0 + c1*x*np.sqrt(2)
+
+
+def hermgauss(deg):
+    """
+    Gauss-Hermite quadrature.
+
+    Computes the sample points and weights for Gauss-Hermite quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-\inf, \inf]`
+    with the weight function :math:`f(x) = \exp(-x^2)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (H'_n(x_k) * H_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`H_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1], dtype=np.float64)
+    m = hermcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = _normed_hermite_n(x, ideg)
+    df = _normed_hermite_n(x, ideg - 1) * np.sqrt(2*ideg)
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = _normed_hermite_n(x, ideg - 1)
+    fm /= np.abs(fm).max()
+    w = 1/(fm * fm)
+
+    # for Hermite we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= np.sqrt(np.pi) / w.sum()
+
+    return x, w
+
+
+def hermweight(x):
+    """
+    Weight function of the Hermite polynomials.
+
+    The weight function is :math:`\exp(-x^2)` and the interval of
+    integration is :math:`[-\inf, \inf]`. the Hermite polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-x**2)
+    return w
+
+
+#
+# Hermite series class
+#
+
+class Hermite(ABCPolyBase):
+    """An Hermite series class.
+
+    The Hermite class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Hermite coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*H_0(x) + 2*H_1(X) + 3*H_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(hermadd)
+    _sub = staticmethod(hermsub)
+    _mul = staticmethod(hermmul)
+    _div = staticmethod(hermdiv)
+    _pow = staticmethod(hermpow)
+    _val = staticmethod(hermval)
+    _int = staticmethod(hermint)
+    _der = staticmethod(hermder)
+    _fit = staticmethod(hermfit)
+    _line = staticmethod(hermline)
+    _roots = staticmethod(hermroots)
+    _fromroots = staticmethod(hermfromroots)
+
+    # Virtual properties
+    nickname = 'herm'
+    domain = np.array(hermdomain)
+    window = np.array(hermdomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
new file mode 100644
index 0000000000..08e83899aa
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
@@ -0,0 +1,1851 @@
+"""
+Objects for dealing with Hermite_e series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Hermite_e series, including a `HermiteE` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `hermedomain` -- Hermite_e series default domain, [-1,1].
+- `hermezero` -- Hermite_e series that evaluates identically to 0.
+- `hermeone` -- Hermite_e series that evaluates identically to 1.
+- `hermex` -- Hermite_e series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `hermemulx` -- multiply a Hermite_e series in ``P_i(x)`` by ``x``.
+- `hermeadd` -- add two Hermite_e series.
+- `hermesub` -- subtract one Hermite_e series from another.
+- `hermemul` -- multiply two Hermite_e series.
+- `hermediv` -- divide one Hermite_e series by another.
+- `hermeval` -- evaluate a Hermite_e series at given points.
+- `hermeval2d` -- evaluate a 2D Hermite_e series at given points.
+- `hermeval3d` -- evaluate a 3D Hermite_e series at given points.
+- `hermegrid2d` -- evaluate a 2D Hermite_e series on a Cartesian product.
+- `hermegrid3d` -- evaluate a 3D Hermite_e series on a Cartesian product.
+
+Calculus
+--------
+- `hermeder` -- differentiate a Hermite_e series.
+- `hermeint` -- integrate a Hermite_e series.
+
+Misc Functions
+--------------
+- `hermefromroots` -- create a Hermite_e series with specified roots.
+- `hermeroots` -- find the roots of a Hermite_e series.
+- `hermevander` -- Vandermonde-like matrix for Hermite_e polynomials.
+- `hermevander2d` -- Vandermonde-like matrix for 2D power series.
+- `hermevander3d` -- Vandermonde-like matrix for 3D power series.
+- `hermegauss` -- Gauss-Hermite_e quadrature, points and weights.
+- `hermeweight` -- Hermite_e weight function.
+- `hermecompanion` -- symmetrized companion matrix in Hermite_e form.
+- `hermefit` -- least-squares fit returning a Hermite_e series.
+- `hermetrim` -- trim leading coefficients from a Hermite_e series.
+- `hermeline` -- Hermite_e series of given straight line.
+- `herme2poly` -- convert a Hermite_e series to a polynomial.
+- `poly2herme` -- convert a polynomial to a Hermite_e series.
+
+Classes
+-------
+- `HermiteE` -- A Hermite_e series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'hermezero', 'hermeone', 'hermex', 'hermedomain', 'hermeline',
+    'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv',
+    'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly',
+    'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim',
+    'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d',
+    'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion',
+    'hermegauss', 'hermeweight']
+
+hermetrim = pu.trimcoef
+
+
+def poly2herme(pol):
+    """
+    poly2herme(pol)
+
+    Convert a polynomial to a Hermite series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Hermite series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Hermite
+        series.
+
+    See Also
+    --------
+    herme2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import poly2herme
+    >>> poly2herme(np.arange(4))
+    array([  2.,  10.,   2.,   3.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = hermeadd(hermemulx(res), pol[i])
+    return res
+
+
+def herme2poly(c):
+    """
+    Convert a Hermite series to a polynomial.
+
+    Convert an array representing the coefficients of a Hermite series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Hermite series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2herme
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import herme2poly
+    >>> herme2poly([  2.,  10.,   2.,   3.])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    if n == 2:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1*(i - 1))
+            c1 = polyadd(tmp, polymulx(c1))
+        return polyadd(c0, polymulx(c1))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Hermite
+hermedomain = np.array([-1, 1])
+
+# Hermite coefficients representing zero.
+hermezero = np.array([0])
+
+# Hermite coefficients representing one.
+hermeone = np.array([1])
+
+# Hermite coefficients representing the identity x.
+hermex = np.array([0, 1])
+
+
+def hermeline(off, scl):
+    """
+    Hermite series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Hermite series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeline
+    >>> from numpy.polynomial.hermite_e import hermeline, hermeval
+    >>> hermeval(0,hermeline(3, 2))
+    3.0
+    >>> hermeval(1,hermeline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def hermefromroots(roots):
+    """
+    Generate a HermiteE series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in HermiteE form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * He_1(x) + ... +  c_n * He_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in HermiteE form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, hermfromroots,
+    chebfromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermefromroots, hermeval
+    >>> coef = hermefromroots((-1, 0, 1))
+    >>> hermeval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = hermefromroots((-1j, 1j))
+    >>> hermeval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [hermeline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [hermemul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = hermemul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def hermeadd(c1, c2):
+    """
+    Add one Hermite series to another.
+
+    Returns the sum of two Hermite series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Hermite series of their sum.
+
+    See Also
+    --------
+    hermesub, hermemul, hermediv, hermepow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Hermite series
+    is a Hermite series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeadd
+    >>> hermeadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermesub(c1, c2):
+    """
+    Subtract one Hermite series from another.
+
+    Returns the difference of two Hermite series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their difference.
+
+    See Also
+    --------
+    hermeadd, hermemul, hermediv, hermepow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Hermite
+    series is a Hermite series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermesub
+    >>> hermesub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermemulx(c):
+    """Multiply a Hermite series by x.
+
+    Multiply the Hermite series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Hermite
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (P_{i + 1}(x) + iP_{i - 1}(x)))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermemulx
+    >>> hermemulx([1, 2, 3])
+    array([ 2.,  7.,  2.,  3.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    for i in range(1, len(c)):
+        prd[i + 1] = c[i]
+        prd[i - 1] += c[i]*i
+    return prd
+
+
+def hermemul(c1, c2):
+    """
+    Multiply one Hermite series by another.
+
+    Returns the product of two Hermite series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their product.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermediv, hermepow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Hermite polynomial basis set.  Thus, to express
+    the product as a Hermite series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermemul
+    >>> hermemul([1, 2, 3], [0, 1, 2])
+    array([ 14.,  15.,  28.,   7.,   6.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = hermesub(c[-i]*xs, c1*(nd - 1))
+            c1 = hermeadd(tmp, hermemulx(c1))
+    return hermeadd(c0, hermemulx(c1))
+
+
+def hermediv(c1, c2):
+    """
+    Divide one Hermite series by another.
+
+    Returns the quotient-with-remainder of two Hermite series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Hermite series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermemul, hermepow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Hermite series by another
+    results in quotient and remainder terms that are not in the Hermite
+    polynomial basis set.  Thus, to express these results as a Hermite
+    series, it is necessary to "reproject" the results onto the Hermite
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermediv
+    >>> hermediv([ 14.,  15.,  28.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> hermediv([ 15.,  17.,  28.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  2.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = hermemul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def hermepow(c, pow, maxpower=16):
+    """Raise a Hermite series to a power.
+
+    Returns the Hermite series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Hermite series of power.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermemul, hermediv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermepow
+    >>> hermepow([1, 2, 3], 2)
+    array([ 23.,  28.,  46.,  12.,   9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = hermemul(prd, c)
+        return prd
+
+
+def hermeder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Hermite_e series.
+
+    Returns the series coefficients `c` differentiated `m` times along
+    `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*He_0 + 2*He_1 + 3*He_2``
+    while [[1,2],[1,2]] represents ``1*He_0(x)*He_0(y) + 1*He_1(x)*He_0(y)
+    + 2*He_0(x)*He_1(y) + 2*He_1(x)*He_1(y)`` if axis=0 is ``x`` and axis=1
+    is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite_e series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Hermite series of the derivative.
+
+    See Also
+    --------
+    hermeint
+
+    Notes
+    -----
+    In general, the result of differentiating a Hermite series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeder
+    >>> hermeder([ 1.,  1.,  1.,  1.])
+    array([ 1.,  2.,  3.])
+    >>> hermeder([-0.25,  1.,  1./2.,  1./3.,  1./4 ], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        return c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 0, -1):
+                der[j - 1] = j*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermeint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Hermite_e series.
+
+    Returns the Hermite_e series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
+    represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
+    2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite_e series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Hermite_e series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    hermeder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeint
+    >>> hermeint([1, 2, 3]) # integrate once, value 0 at 0.
+    array([ 1.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], m=2) # integrate twice, value & deriv 0 at 0
+    array([-0.25      ,  1.        ,  0.5       ,  0.33333333,  0.25      ])
+    >>> hermeint([1, 2, 3], k=1) # integrate once, value 1 at 0.
+    array([ 2.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], lbnd=-1) # integrate once, value 0 at -1
+    array([-1.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], m=2, k=[1, 2], lbnd=-1)
+    array([ 1.83333333,  0.        ,  0.5       ,  0.33333333,  0.25      ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(j + 1)
+            tmp[0] += k[i] - hermeval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermeval(x, c, tensor=True):
+    """
+    Evaluate an HermiteE series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * He_0(x) + c_1 * He_1(x) + ... + c_n * He_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    hermeval2d, hermegrid2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeval
+    >>> coef = [1,2,3]
+    >>> hermeval(1, coef)
+    3.0
+    >>> hermeval([[1,2],[3,4]], coef)
+    array([[  3.,  14.],
+           [ 31.,  54.]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - c1*(nd - 1)
+            c1 = tmp + c1*x
+    return c0 + c1*x
+
+
+def hermeval2d(x, y, c):
+    """
+    Evaluate a 2-D HermiteE series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * He_i(x) * He_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermegrid2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = hermeval(x, c)
+    c = hermeval(y, c, tensor=False)
+    return c
+
+
+def hermegrid2d(x, y, c):
+    """
+    Evaluate a 2-D HermiteE series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermeval(x, c)
+    c = hermeval(y, c)
+    return c
+
+
+def hermeval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite_e series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * He_i(x) * He_j(y) * He_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermegrid2d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = hermeval(x, c)
+    c = hermeval(y, c, tensor=False)
+    c = hermeval(z, c, tensor=False)
+    return c
+
+
+def hermegrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * He_i(a) * He_j(b) * He_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermegrid2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermeval(x, c)
+    c = hermeval(y, c)
+    c = hermeval(z, c)
+    return c
+
+
+def hermevander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = He_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the HermiteE polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = hermevander(x, n)``, then ``np.dot(V, c)`` and
+    ``hermeval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of HermiteE series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding HermiteE polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermevander
+    >>> x = np.array([-1, 0, 1])
+    >>> hermevander(x, 3)
+    array([[ 1., -1.,  0.,  2.],
+           [ 1.,  0., -1., -0.],
+           [ 1.,  1.,  0., -2.]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x - v[i-2]*(i - 1))
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def hermevander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = He_i(x) * He_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the HermiteE polynomials.
+
+    If ``V = hermevander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``hermeval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D HermiteE
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    hermevander, hermevander3d. hermeval2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = hermevander(x, degx)
+    vy = hermevander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def hermevander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then Hehe pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = He_i(x)*He_j(y)*He_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the HermiteE polynomials.
+
+    If ``V = hermevander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``hermeval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D HermiteE
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermevander, hermevander3d. hermeval2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = hermevander(x, degx)
+    vy = hermevander(y, degy)
+    vz = hermevander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def hermefit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Hermite series to data.
+
+    Return the coefficients of a HermiteE series of degree `deg` that is
+    the least squares fit to the data values `y` given at points `x`. If
+    `y` is 1-D the returned coefficients will also be 1-D. If `y` is 2-D
+    multiple fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Hermite coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, polyfit, hermfit, polyfit
+    hermeval : Evaluates a Hermite series.
+    hermevander : pseudo Vandermonde matrix of Hermite series.
+    hermeweight : HermiteE weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the HermiteE series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the pseudo Vandermonde matrix of `x`, the elements of `c`
+    are the coefficients to be solved for, and the elements of `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using HermiteE series are probably most useful when the data can
+    be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the HermiteE
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `hermeweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermefik, hermeval
+    >>> x = np.linspace(-10, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = hermeval(x, [1, 2, 3]) + err
+    >>> hermefit(x, y, 2)
+    array([ 1.01690445,  1.99951418,  2.99948696])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = hermevander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = hermevander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def hermecompanion(c):
+    """
+    Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an HermiteE basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of HermiteE series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.hstack((1., 1./np.sqrt(np.arange(n - 1, 0, -1))))
+    scl = np.multiply.accumulate(scl)[::-1]
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.sqrt(np.arange(1, n))
+    bot[...] = top
+    mat[:, -1] -= scl*c[:-1]/c[-1]
+    return mat
+
+
+def hermeroots(c):
+    """
+    Compute the roots of a HermiteE series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * He_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, hermroots, chebroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The HermiteE series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeroots, hermefromroots
+    >>> coef = hermefromroots([-1, 0, 1])
+    >>> coef
+    array([ 0.,  2.,  0.,  1.])
+    >>> hermeroots(coef)
+    array([-1.,  0.,  1.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = hermecompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def _normed_hermite_e_n(x, n):
+    """
+    Evaluate a normalized HermiteE polynomial.
+
+    Compute the value of the normalized HermiteE polynomial of degree ``n``
+    at the points ``x``.
+
+
+    Parameters
+    ----------
+    x : ndarray of double.
+        Points at which to evaluate the function
+    n : int
+        Degree of the normalized HermiteE function to be evaluated.
+
+    Returns
+    -------
+    values : ndarray
+        The shape of the return value is described above.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    This function is needed for finding the Gauss points and integration
+    weights for high degrees. The values of the standard HermiteE functions
+    overflow when n >= 207.
+
+    """
+    if n == 0:
+        return np.ones(x.shape)/np.sqrt(np.sqrt(2*np.pi))
+
+    c0 = 0.
+    c1 = 1./np.sqrt(np.sqrt(2*np.pi))
+    nd = float(n)
+    for i in range(n - 1):
+        tmp = c0
+        c0 = -c1*np.sqrt((nd - 1.)/nd)
+        c1 = tmp + c1*x*np.sqrt(1./nd)
+        nd = nd - 1.0
+    return c0 + c1*x
+
+
+def hermegauss(deg):
+    """
+    Gauss-HermiteE quadrature.
+
+    Computes the sample points and weights for Gauss-HermiteE quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-\inf, \inf]`
+    with the weight function :math:`f(x) = \exp(-x^2/2)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (He'_n(x_k) * He_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`He_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = hermecompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = _normed_hermite_e_n(x, ideg)
+    df = _normed_hermite_e_n(x, ideg - 1) * np.sqrt(ideg)
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = _normed_hermite_e_n(x, ideg - 1)
+    fm /= np.abs(fm).max()
+    w = 1/(fm * fm)
+
+    # for Hermite_e we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= np.sqrt(2*np.pi) / w.sum()
+
+    return x, w
+
+
+def hermeweight(x):
+    """Weight function of the Hermite_e polynomials.
+
+    The weight function is :math:`\exp(-x^2/2)` and the interval of
+    integration is :math:`[-\inf, \inf]`. the HermiteE polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-.5*x**2)
+    return w
+
+
+#
+# HermiteE series class
+#
+
+class HermiteE(ABCPolyBase):
+    """An HermiteE series class.
+
+    The HermiteE class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        HermiteE coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*He_0(x) + 2*He_1(X) + 3*He_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(hermeadd)
+    _sub = staticmethod(hermesub)
+    _mul = staticmethod(hermemul)
+    _div = staticmethod(hermediv)
+    _pow = staticmethod(hermepow)
+    _val = staticmethod(hermeval)
+    _int = staticmethod(hermeint)
+    _der = staticmethod(hermeder)
+    _fit = staticmethod(hermefit)
+    _line = staticmethod(hermeline)
+    _roots = staticmethod(hermeroots)
+    _fromroots = staticmethod(hermefromroots)
+
+    # Virtual properties
+    nickname = 'herme'
+    domain = np.array(hermedomain)
+    window = np.array(hermedomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
new file mode 100644
index 0000000000..d459551ae8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
@@ -0,0 +1,1804 @@
+"""
+Objects for dealing with Laguerre series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Laguerre series, including a `Laguerre` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `lagdomain` -- Laguerre series default domain, [-1,1].
+- `lagzero` -- Laguerre series that evaluates identically to 0.
+- `lagone` -- Laguerre series that evaluates identically to 1.
+- `lagx` -- Laguerre series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `lagmulx` -- multiply a Laguerre series in ``P_i(x)`` by ``x``.
+- `lagadd` -- add two Laguerre series.
+- `lagsub` -- subtract one Laguerre series from another.
+- `lagmul` -- multiply two Laguerre series.
+- `lagdiv` -- divide one Laguerre series by another.
+- `lagval` -- evaluate a Laguerre series at given points.
+- `lagval2d` -- evaluate a 2D Laguerre series at given points.
+- `lagval3d` -- evaluate a 3D Laguerre series at given points.
+- `laggrid2d` -- evaluate a 2D Laguerre series on a Cartesian product.
+- `laggrid3d` -- evaluate a 3D Laguerre series on a Cartesian product.
+
+Calculus
+--------
+- `lagder` -- differentiate a Laguerre series.
+- `lagint` -- integrate a Laguerre series.
+
+Misc Functions
+--------------
+- `lagfromroots` -- create a Laguerre series with specified roots.
+- `lagroots` -- find the roots of a Laguerre series.
+- `lagvander` -- Vandermonde-like matrix for Laguerre polynomials.
+- `lagvander2d` -- Vandermonde-like matrix for 2D power series.
+- `lagvander3d` -- Vandermonde-like matrix for 3D power series.
+- `laggauss` -- Gauss-Laguerre quadrature, points and weights.
+- `lagweight` -- Laguerre weight function.
+- `lagcompanion` -- symmetrized companion matrix in Laguerre form.
+- `lagfit` -- least-squares fit returning a Laguerre series.
+- `lagtrim` -- trim leading coefficients from a Laguerre series.
+- `lagline` -- Laguerre series of given straight line.
+- `lag2poly` -- convert a Laguerre series to a polynomial.
+- `poly2lag` -- convert a polynomial to a Laguerre series.
+
+Classes
+-------
+- `Laguerre` -- A Laguerre series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd',
+    'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder',
+    'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander',
+    'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d',
+    'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion',
+    'laggauss', 'lagweight']
+
+lagtrim = pu.trimcoef
+
+
+def poly2lag(pol):
+    """
+    poly2lag(pol)
+
+    Convert a polynomial to a Laguerre series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Laguerre series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Laguerre
+        series.
+
+    See Also
+    --------
+    lag2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import poly2lag
+    >>> poly2lag(np.arange(4))
+    array([ 23., -63.,  58., -18.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = lagadd(lagmulx(res), pol[i])
+    return res
+
+
+def lag2poly(c):
+    """
+    Convert a Laguerre series to a polynomial.
+
+    Convert an array representing the coefficients of a Laguerre series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Laguerre series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2lag
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lag2poly
+    >>> lag2poly([ 23., -63.,  58., -18.])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], (c1*(i - 1))/i)
+            c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i)
+        return polyadd(c0, polysub(c1, polymulx(c1)))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Laguerre
+lagdomain = np.array([0, 1])
+
+# Laguerre coefficients representing zero.
+lagzero = np.array([0])
+
+# Laguerre coefficients representing one.
+lagone = np.array([1])
+
+# Laguerre coefficients representing the identity x.
+lagx = np.array([1, -1])
+
+
+def lagline(off, scl):
+    """
+    Laguerre series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Laguerre series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagline, lagval
+    >>> lagval(0,lagline(3, 2))
+    3.0
+    >>> lagval(1,lagline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off + scl, -scl])
+    else:
+        return np.array([off])
+
+
+def lagfromroots(roots):
+    """
+    Generate a Laguerre series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Laguerre form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * L_1(x) + ... +  c_n * L_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Laguerre form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, chebfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagfromroots, lagval
+    >>> coef = lagfromroots((-1, 0, 1))
+    >>> lagval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = lagfromroots((-1j, 1j))
+    >>> lagval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [lagline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [lagmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = lagmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def lagadd(c1, c2):
+    """
+    Add one Laguerre series to another.
+
+    Returns the sum of two Laguerre series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Laguerre series of their sum.
+
+    See Also
+    --------
+    lagsub, lagmul, lagdiv, lagpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Laguerre series
+    is a Laguerre series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagadd
+    >>> lagadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def lagsub(c1, c2):
+    """
+    Subtract one Laguerre series from another.
+
+    Returns the difference of two Laguerre series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Laguerre series coefficients representing their difference.
+
+    See Also
+    --------
+    lagadd, lagmul, lagdiv, lagpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Laguerre
+    series is a Laguerre series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagsub
+    >>> lagsub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def lagmulx(c):
+    """Multiply a Laguerre series by x.
+
+    Multiply the Laguerre series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Laguerre
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagmulx
+    >>> lagmulx([1, 2, 3])
+    array([ -1.,  -1.,  11.,  -9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]
+    prd[1] = -c[0]
+    for i in range(1, len(c)):
+        prd[i + 1] = -c[i]*(i + 1)
+        prd[i] += c[i]*(2*i + 1)
+        prd[i - 1] -= c[i]*i
+    return prd
+
+
+def lagmul(c1, c2):
+    """
+    Multiply one Laguerre series by another.
+
+    Returns the product of two Laguerre series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Laguerre series coefficients representing their product.
+
+    See Also
+    --------
+    lagadd, lagsub, lagdiv, lagpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Laguerre polynomial basis set.  Thus, to express
+    the product as a Laguerre series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagmul
+    >>> lagmul([1, 2, 3], [0, 1, 2])
+    array([  8., -13.,  38., -51.,  36.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd)
+            c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd)
+    return lagadd(c0, lagsub(c1, lagmulx(c1)))
+
+
+def lagdiv(c1, c2):
+    """
+    Divide one Laguerre series by another.
+
+    Returns the quotient-with-remainder of two Laguerre series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Laguerre series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    lagadd, lagsub, lagmul, lagpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Laguerre series by another
+    results in quotient and remainder terms that are not in the Laguerre
+    polynomial basis set.  Thus, to express these results as a Laguerre
+    series, it is necessary to "reproject" the results onto the Laguerre
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagdiv
+    >>> lagdiv([  8., -13.,  38., -51.,  36.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> lagdiv([  9., -12.,  38., -51.,  36.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  1.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = lagmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def lagpow(c, pow, maxpower=16):
+    """Raise a Laguerre series to a power.
+
+    Returns the Laguerre series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Laguerre series of power.
+
+    See Also
+    --------
+    lagadd, lagsub, lagmul, lagdiv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagpow
+    >>> lagpow([1, 2, 3], 2)
+    array([ 14., -16.,  56., -72.,  54.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = lagmul(prd, c)
+        return prd
+
+
+def lagder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Laguerre series.
+
+    Returns the Laguerre series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
+    while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
+    2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Laguerre series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Laguerre series of the derivative.
+
+    See Also
+    --------
+    lagint
+
+    Notes
+    -----
+    In general, the result of differentiating a Laguerre series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagder
+    >>> lagder([ 1.,  1.,  1., -3.])
+    array([ 1.,  2.,  3.])
+    >>> lagder([ 1.,  0.,  0., -4.,  3.], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 1, -1):
+                der[j - 1] = -c[j]
+                c[j - 1] += c[j]
+            der[0] = -c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def lagint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Laguerre series.
+
+    Returns the Laguerre series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
+    represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
+    2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Laguerre series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Laguerre series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    lagder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagint
+    >>> lagint([1,2,3])
+    array([ 1.,  1.,  1., -3.])
+    >>> lagint([1,2,3], m=2)
+    array([ 1.,  0.,  0., -4.,  3.])
+    >>> lagint([1,2,3], k=1)
+    array([ 2.,  1.,  1., -3.])
+    >>> lagint([1,2,3], lbnd=-1)
+    array([ 11.5,   1. ,   1. ,  -3. ])
+    >>> lagint([1,2], m=2, k=[1,2], lbnd=-1)
+    array([ 11.16666667,  -5.        ,  -3.        ,   2.        ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]
+            tmp[1] = -c[0]
+            for j in range(1, n):
+                tmp[j] += c[j]
+                tmp[j + 1] = -c[j]
+            tmp[0] += k[i] - lagval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def lagval(x, c, tensor=True):
+    """
+    Evaluate a Laguerre series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    lagval2d, laggrid2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagval
+    >>> coef = [1,2,3]
+    >>> lagval(1, coef)
+    -0.5
+    >>> lagval([[1,2],[3,4]], coef)
+    array([[-0.5, -4. ],
+           [-4.5, -2. ]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - (c1*(nd - 1))/nd
+            c1 = tmp + (c1*((2*nd - 1) - x))/nd
+    return c0 + c1*(1 - x)
+
+
+def lagval2d(x, y, c):
+    """
+    Evaluate a 2-D Laguerre series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    lagval, laggrid2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = lagval(x, c)
+    c = lagval(y, c, tensor=False)
+    return c
+
+
+def laggrid2d(x, y, c):
+    """
+    Evaluate a 2-D Laguerre series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    lagval, lagval2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = lagval(x, c)
+    c = lagval(y, c)
+    return c
+
+
+def lagval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Laguerre series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimension polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    lagval, lagval2d, laggrid2d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = lagval(x, c)
+    c = lagval(y, c, tensor=False)
+    c = lagval(z, c, tensor=False)
+    return c
+
+
+def laggrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Laguerre series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    lagval, lagval2d, laggrid2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = lagval(x, c)
+    c = lagval(y, c)
+    c = lagval(z, c)
+    return c
+
+
+def lagvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = L_i(x)
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Laguerre polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and
+    ``lagval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Laguerre series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Laguerre polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagvander
+    >>> x = np.array([0, 1, 2])
+    >>> lagvander(x, 3)
+    array([[ 1.        ,  1.        ,  1.        ,  1.        ],
+           [ 1.        ,  0.        , -0.5       , -0.66666667],
+           [ 1.        , -1.        , -1.        , -0.33333333]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = 1 - x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def lagvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = L_i(x) * L_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Laguerre polynomials.
+
+    If ``V = lagvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``lagval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Laguerre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    lagvander, lagvander3d. lagval2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = lagvander(x, degx)
+    vy = lagvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def lagvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Laguerre polynomials.
+
+    If ``V = lagvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``lagval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Laguerre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    lagvander, lagvander3d. lagval2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = lagvander(x, degx)
+    vy = lagvander(y, degy)
+    vz = lagvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def lagfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Laguerre series to data.
+
+    Return the coefficients of a Laguerre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Laguerre coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, polyfit, hermfit, hermefit
+    lagval : Evaluates a Laguerre series.
+    lagvander : pseudo Vandermonde matrix of Laguerre series.
+    lagweight : Laguerre weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Laguerre series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Laguerre series are probably most useful when the data can
+    be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Laguerre
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `lagweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagfit, lagval
+    >>> x = np.linspace(0, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = lagval(x, [1, 2, 3]) + err
+    >>> lagfit(x, y, 2)
+    array([ 0.96971004,  2.00193749,  3.00288744])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = lagvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = lagvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def lagcompanion(c):
+    """
+    Return the companion matrix of c.
+
+    The usual companion matrix of the Laguerre polynomials is already
+    symmetric when `c` is a basis Laguerre polynomial, so no scaling is
+    applied.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[1 + c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    top = mat.reshape(-1)[1::n+1]
+    mid = mat.reshape(-1)[0::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = -np.arange(1, n)
+    mid[...] = 2.*np.arange(n) + 1.
+    bot[...] = top
+    mat[:, -1] += (c[:-1]/c[-1])*n
+    return mat
+
+
+def lagroots(c):
+    """
+    Compute the roots of a Laguerre series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * L_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, chebroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Laguerre series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagroots, lagfromroots
+    >>> coef = lagfromroots([0, 1, 2])
+    >>> coef
+    array([  2.,  -8.,  12.,  -6.])
+    >>> lagroots(coef)
+    array([ -4.44089210e-16,   1.00000000e+00,   2.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([1 + c[0]/c[1]])
+
+    m = lagcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def laggauss(deg):
+    """
+    Gauss-Laguerre quadrature.
+
+    Computes the sample points and weights for Gauss-Laguerre quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[0, \inf]`
+    with the weight function :math:`f(x) = \exp(-x)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100 higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`L_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = lagcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = lagval(x, c)
+    df = lagval(x, lagder(c))
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = lagval(x, c[1:])
+    fm /= np.abs(fm).max()
+    df /= np.abs(df).max()
+    w = 1/(fm * df)
+
+    # scale w to get the right value, 1 in this case
+    w /= w.sum()
+
+    return x, w
+
+
+def lagweight(x):
+    """Weight function of the Laguerre polynomials.
+
+    The weight function is :math:`exp(-x)` and the interval of integration
+    is :math:`[0, \inf]`. The Laguerre polynomials are orthogonal, but not
+    normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-x)
+    return w
+
+#
+# Laguerre series class
+#
+
+class Laguerre(ABCPolyBase):
+    """A Laguerre series class.
+
+    The Laguerre class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Laguerre coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [0, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [0, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(lagadd)
+    _sub = staticmethod(lagsub)
+    _mul = staticmethod(lagmul)
+    _div = staticmethod(lagdiv)
+    _pow = staticmethod(lagpow)
+    _val = staticmethod(lagval)
+    _int = staticmethod(lagint)
+    _der = staticmethod(lagder)
+    _fit = staticmethod(lagfit)
+    _line = staticmethod(lagline)
+    _roots = staticmethod(lagroots)
+    _fromroots = staticmethod(lagfromroots)
+
+    # Virtual properties
+    nickname = 'lag'
+    domain = np.array(lagdomain)
+    window = np.array(lagdomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.py
new file mode 100644
index 0000000000..54e9895db9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.py
@@ -0,0 +1,1834 @@
+"""
+Legendre Series (:mod: `numpy.polynomial.legendre`)
+===================================================
+
+.. currentmodule:: numpy.polynomial.polynomial
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Legendre series, including a `Legendre` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   legdomain            Legendre series default domain, [-1,1].
+   legzero              Legendre series that evaluates identically to 0.
+   legone               Legendre series that evaluates identically to 1.
+   legx                 Legendre series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+
+.. autosummary::
+   :toctree: generated/
+
+   legmulx              multiply a Legendre series in P_i(x) by x.
+   legadd               add two Legendre series.
+   legsub               subtract one Legendre series from another.
+   legmul               multiply two Legendre series.
+   legdiv               divide one Legendre series by another.
+   legpow               raise a Legendre series to an positive integer power
+   legval               evaluate a Legendre series at given points.
+   legval2d             evaluate a 2D Legendre series at given points.
+   legval3d             evaluate a 3D Legendre series at given points.
+   leggrid2d            evaluate a 2D Legendre series on a Cartesian product.
+   leggrid3d            evaluate a 3D Legendre series on a Cartesian product.
+
+Calculus
+--------
+
+.. autosummary::
+   :toctree: generated/
+
+   legder               differentiate a Legendre series.
+   legint               integrate a Legendre series.
+
+Misc Functions
+--------------
+
+.. autosummary::
+   :toctree: generated/
+
+   legfromroots          create a Legendre series with specified roots.
+   legroots              find the roots of a Legendre series.
+   legvander             Vandermonde-like matrix for Legendre polynomials.
+   legvander2d           Vandermonde-like matrix for 2D power series.
+   legvander3d           Vandermonde-like matrix for 3D power series.
+   leggauss              Gauss-Legendre quadrature, points and weights.
+   legweight             Legendre weight function.
+   legcompanion          symmetrized companion matrix in Legendre form.
+   legfit                least-squares fit returning a Legendre series.
+   legtrim               trim leading coefficients from a Legendre series.
+   legline               Legendre series representing given straight line.
+   leg2poly              convert a Legendre series to a polynomial.
+   poly2leg              convert a polynomial to a Legendre series.
+
+Classes
+-------
+    Legendre            A Legendre series class.
+
+See also
+--------
+numpy.polynomial.polynomial
+numpy.polynomial.chebyshev
+numpy.polynomial.laguerre
+numpy.polynomial.hermite
+numpy.polynomial.hermite_e
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'legzero', 'legone', 'legx', 'legdomain', 'legline', 'legadd',
+    'legsub', 'legmulx', 'legmul', 'legdiv', 'legpow', 'legval', 'legder',
+    'legint', 'leg2poly', 'poly2leg', 'legfromroots', 'legvander',
+    'legfit', 'legtrim', 'legroots', 'Legendre', 'legval2d', 'legval3d',
+    'leggrid2d', 'leggrid3d', 'legvander2d', 'legvander3d', 'legcompanion',
+    'leggauss', 'legweight']
+
+legtrim = pu.trimcoef
+
+
+def poly2leg(pol):
+    """
+    Convert a polynomial to a Legendre series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Legendre series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Legendre
+        series.
+
+    See Also
+    --------
+    leg2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> p = P.Polynomial(np.arange(4))
+    >>> p
+    Polynomial([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> c = P.Legendre(P.poly2leg(p.coef))
+    >>> c
+    Legendre([ 1.  ,  3.25,  1.  ,  0.75], [-1.,  1.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = legadd(legmulx(res), pol[i])
+    return res
+
+
+def leg2poly(c):
+    """
+    Convert a Legendre series to a polynomial.
+
+    Convert an array representing the coefficients of a Legendre series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Legendre series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2leg
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> c = P.Legendre(range(4))
+    >>> c
+    Legendre([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> p = c.convert(kind=P.Polynomial)
+    >>> p
+    Polynomial([-1. , -3.5,  3. ,  7.5], [-1.,  1.])
+    >>> P.leg2poly(range(4))
+    array([-1. , -3.5,  3. ,  7.5])
+
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n < 3:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], (c1*(i - 1))/i)
+            c1 = polyadd(tmp, (polymulx(c1)*(2*i - 1))/i)
+        return polyadd(c0, polymulx(c1))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Legendre
+legdomain = np.array([-1, 1])
+
+# Legendre coefficients representing zero.
+legzero = np.array([0])
+
+# Legendre coefficients representing one.
+legone = np.array([1])
+
+# Legendre coefficients representing the identity x.
+legx = np.array([0, 1])
+
+
+def legline(off, scl):
+    """
+    Legendre series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Legendre series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as L
+    >>> L.legline(3,2)
+    array([3, 2])
+    >>> L.legval(-3, L.legline(3,2)) # should be -3
+    -3.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def legfromroots(roots):
+    """
+    Generate a Legendre series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Legendre form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * L_1(x) + ... +  c_n * L_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Legendre form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, chebfromroots, lagfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as L
+    >>> L.legfromroots((-1,0,1)) # x^3 - x relative to the standard basis
+    array([ 0. , -0.4,  0. ,  0.4])
+    >>> j = complex(0,1)
+    >>> L.legfromroots((-j,j)) # x^2 + 1 relative to the standard basis
+    array([ 1.33333333+0.j,  0.00000000+0.j,  0.66666667+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [legline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [legmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = legmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def legadd(c1, c2):
+    """
+    Add one Legendre series to another.
+
+    Returns the sum of two Legendre series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Legendre series of their sum.
+
+    See Also
+    --------
+    legsub, legmul, legdiv, legpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Legendre series
+    is a Legendre series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legadd(c1,c2)
+    array([ 4.,  4.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def legsub(c1, c2):
+    """
+    Subtract one Legendre series from another.
+
+    Returns the difference of two Legendre series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Legendre series coefficients representing their difference.
+
+    See Also
+    --------
+    legadd, legmul, legdiv, legpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Legendre
+    series is a Legendre series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legsub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> L.legsub(c2,c1) # -C.legsub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def legmulx(c):
+    """Multiply a Legendre series by x.
+
+    Multiply the Legendre series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Legendre
+    polynomials in the form
+
+    .. math::
+
+      xP_i(x) = ((i + 1)*P_{i + 1}(x) + i*P_{i - 1}(x))/(2i + 1)
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    for i in range(1, len(c)):
+        j = i + 1
+        k = i - 1
+        s = i + j
+        prd[j] = (c[i]*j)/s
+        prd[k] += (c[i]*i)/s
+    return prd
+
+
+def legmul(c1, c2):
+    """
+    Multiply one Legendre series by another.
+
+    Returns the product of two Legendre series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Legendre series coefficients representing their product.
+
+    See Also
+    --------
+    legadd, legsub, legdiv, legpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Legendre polynomial basis set.  Thus, to express
+    the product as a Legendre series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2)
+    >>> P.legmul(c1,c2) # multiplication requires "reprojection"
+    array([  4.33333333,  10.4       ,  11.66666667,   3.6       ])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = legsub(c[-i]*xs, (c1*(nd - 1))/nd)
+            c1 = legadd(tmp, (legmulx(c1)*(2*nd - 1))/nd)
+    return legadd(c0, legmulx(c1))
+
+
+def legdiv(c1, c2):
+    """
+    Divide one Legendre series by another.
+
+    Returns the quotient-with-remainder of two Legendre series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    quo, rem : ndarrays
+        Of Legendre series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    legadd, legsub, legmul, legpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Legendre series by another
+    results in quotient and remainder terms that are not in the Legendre
+    polynomial basis set.  Thus, to express these results as a Legendre
+    series, it is necessary to "reproject" the results onto the Legendre
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legdiv(c1,c2) # quotient "intuitive," remainder not
+    (array([ 3.]), array([-8., -4.]))
+    >>> c2 = (0,1,2,3)
+    >>> L.legdiv(c2,c1) # neither "intuitive"
+    (array([-0.07407407,  1.66666667]), array([-1.03703704, -2.51851852]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = legmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def legpow(c, pow, maxpower=16):
+    """Raise a Legendre series to a power.
+
+    Returns the Legendre series `c` raised to the power `pow`. The
+    arguement `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Legendre series of power.
+
+    See Also
+    --------
+    legadd, legsub, legmul, legdiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = legmul(prd, c)
+        return prd
+
+
+def legder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Legendre series.
+
+    Returns the Legendre series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
+    while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
+    2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Legendre series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Legendre series of the derivative.
+
+    See Also
+    --------
+    legint
+
+    Notes
+    -----
+    In general, the result of differentiating a Legendre series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c = (1,2,3,4)
+    >>> L.legder(c)
+    array([  6.,   9.,  20.])
+    >>> L.legder(c, 3)
+    array([ 60.])
+    >>> L.legder(c, scl=-1)
+    array([ -6.,  -9., -20.])
+    >>> L.legder(c, 2,-1)
+    array([  9.,  60.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 2, -1):
+                der[j - 1] = (2*j - 1)*c[j]
+                c[j - 2] += c[j]
+            if n > 1:
+                der[1] = 3*c[2]
+            der[0] = c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def legint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Legendre series.
+
+    Returns the Legendre series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
+    represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
+    2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Legendre series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Legendre series coefficient array of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    legder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c = (1,2,3)
+    >>> L.legint(c)
+    array([ 0.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, 3)
+    array([  1.66666667e-02,  -1.78571429e-02,   4.76190476e-02,
+            -1.73472348e-18,   1.90476190e-02,   9.52380952e-03])
+    >>> L.legint(c, k=3)
+    array([ 3.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, lbnd=-2)
+    array([ 7.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, scl=2)
+    array([ 0.66666667,  0.8       ,  1.33333333,  1.2       ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            if n > 1:
+                tmp[2] = c[1]/3
+            for j in range(2, n):
+                t = c[j]/(2*j + 1)
+                tmp[j + 1] = t
+                tmp[j - 1] -= t
+            tmp[0] += k[i] - legval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def legval(x, c, tensor=True):
+    """
+    Evaluate a Legendre series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    legval2d, leggrid2d, legval3d, leggrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - (c1*(nd - 1))/nd
+            c1 = tmp + (c1*x*(2*nd - 1))/nd
+    return c0 + c1*x
+
+
+def legval2d(x, y, c):
+    """
+    Evaluate a 2-D Legendre series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Legendre series at points formed
+        from pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    legval, leggrid2d, legval3d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = legval(x, c)
+    c = legval(y, c, tensor=False)
+    return c
+
+
+def leggrid2d(x, y, c):
+    """
+    Evaluate a 2-D Legendre series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    legval, legval2d, legval3d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = legval(x, c)
+    c = legval(y, c)
+    return c
+
+
+def legval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Legendre series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    legval, legval2d, leggrid2d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = legval(x, c)
+    c = legval(y, c, tensor=False)
+    c = legval(z, c, tensor=False)
+    return c
+
+
+def leggrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Legendre series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    legval, legval2d, leggrid2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = legval(x, c)
+    c = legval(y, c)
+    c = legval(z, c)
+    return c
+
+
+def legvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = L_i(x)
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Legendre polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = legvander(x, n)``, then ``np.dot(V, c)`` and
+    ``legval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Legendre series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Legendre polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    # Use forward recursion to generate the entries. This is not as accurate
+    # as reverse recursion in this application but it is more efficient.
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x*(2*i - 1) - v[i-2]*(i - 1))/i
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def legvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = L_i(x) * L_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Legendre polynomials.
+
+    If ``V = legvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``legval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Legendre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    legvander, legvander3d. legval2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = legvander(x, degx)
+    vy = legvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def legvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Legendre polynomials.
+
+    If ``V = legvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and ``np.dot(V, c.flat)`` and ``legval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Legendre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    legvander, legvander3d. legval2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = legvander(x, degx)
+    vy = legvander(y, degy)
+    vz = legvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def legfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Legendre series to data.
+
+    Return the coefficients of a Legendre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Legendre coefficients ordered from low to high. If `y` was
+        2-D, the coefficients for the data in column k of `y` are in
+        column `k`. If `deg` is specified as a list, coefficients for
+        terms not included in the fit are set equal to zero in the
+        returned `coef`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, polyfit, lagfit, hermfit, hermefit
+    legval : Evaluates a Legendre series.
+    legvander : Vandermonde matrix of Legendre series.
+    legweight : Legendre weight function (= 1).
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Legendre series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where :math:`w_j` are the weights. This problem is solved by setting up
+    as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Legendre series are usually better conditioned than fits
+    using power series, but much can depend on the distribution of the
+    sample points and the smoothness of the data. If the quality of the fit
+    is inadequate splines may be a good alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = legvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = legvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def legcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an Legendre basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = 1./np.sqrt(2*np.arange(n) + 1)
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.arange(1, n)*scl[:n-1]*scl[1:n]
+    bot[...] = top
+    mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*(n/(2*n - 1))
+    return mat
+
+
+def legroots(c):
+    """
+    Compute the roots of a Legendre series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * L_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, chebroots, lagroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such values.
+    Roots with multiplicity greater than 1 will also show larger errors as
+    the value of the series near such points is relatively insensitive to
+    errors in the roots. Isolated roots near the origin can be improved by
+    a few iterations of Newton's method.
+
+    The Legendre series basis polynomials aren't powers of ``x`` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as leg
+    >>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0, all real roots
+    array([-0.85099543, -0.11407192,  0.51506735])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = legcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def leggauss(deg):
+    """
+    Gauss-Legendre quadrature.
+
+    Computes the sample points and weights for Gauss-Legendre quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
+    the weight function :math:`f(x) = 1`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`L_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = legcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = legval(x, c)
+    df = legval(x, legder(c))
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = legval(x, c[1:])
+    fm /= np.abs(fm).max()
+    df /= np.abs(df).max()
+    w = 1/(fm * df)
+
+    # for Legendre we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= 2. / w.sum()
+
+    return x, w
+
+
+def legweight(x):
+    """
+    Weight function of the Legendre polynomials.
+
+    The weight function is :math:`1` and the interval of integration is
+    :math:`[-1, 1]`. The Legendre polynomials are orthogonal, but not
+    normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = x*0.0 + 1.0
+    return w
+
+#
+# Legendre series class
+#
+
+class Legendre(ABCPolyBase):
+    """A Legendre series class.
+
+    The Legendre class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Legendre coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(legadd)
+    _sub = staticmethod(legsub)
+    _mul = staticmethod(legmul)
+    _div = staticmethod(legdiv)
+    _pow = staticmethod(legpow)
+    _val = staticmethod(legval)
+    _int = staticmethod(legint)
+    _der = staticmethod(legder)
+    _fit = staticmethod(legfit)
+    _line = staticmethod(legline)
+    _roots = staticmethod(legroots)
+    _fromroots = staticmethod(legfromroots)
+
+    # Virtual properties
+    nickname = 'leg'
+    domain = np.array(legdomain)
+    window = np.array(legdomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
new file mode 100644
index 0000000000..5d05f59919
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
@@ -0,0 +1,1556 @@
+"""
+Objects for dealing with polynomials.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with polynomials, including a `Polynomial` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with polynomial objects is in
+the docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `polydomain` -- Polynomial default domain, [-1,1].
+- `polyzero` -- (Coefficients of the) "zero polynomial."
+- `polyone` -- (Coefficients of the) constant polynomial 1.
+- `polyx` -- (Coefficients of the) identity map polynomial, ``f(x) = x``.
+
+Arithmetic
+----------
+- `polyadd` -- add two polynomials.
+- `polysub` -- subtract one polynomial from another.
+- `polymul` -- multiply two polynomials.
+- `polydiv` -- divide one polynomial by another.
+- `polypow` -- raise a polynomial to an positive integer power
+- `polyval` -- evaluate a polynomial at given points.
+- `polyval2d` -- evaluate a 2D polynomial at given points.
+- `polyval3d` -- evaluate a 3D polynomial at given points.
+- `polygrid2d` -- evaluate a 2D polynomial on a Cartesian product.
+- `polygrid3d` -- evaluate a 3D polynomial on a Cartesian product.
+
+Calculus
+--------
+- `polyder` -- differentiate a polynomial.
+- `polyint` -- integrate a polynomial.
+
+Misc Functions
+--------------
+- `polyfromroots` -- create a polynomial with specified roots.
+- `polyroots` -- find the roots of a polynomial.
+- `polyvander` -- Vandermonde-like matrix for powers.
+- `polyvander2d` -- Vandermonde-like matrix for 2D power series.
+- `polyvander3d` -- Vandermonde-like matrix for 3D power series.
+- `polycompanion` -- companion matrix in power series form.
+- `polyfit` -- least-squares fit returning a polynomial.
+- `polytrim` -- trim leading coefficients from a polynomial.
+- `polyline` -- polynomial representing given straight line.
+
+Classes
+-------
+- `Polynomial` -- polynomial class.
+
+See Also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = [
+    'polyzero', 'polyone', 'polyx', 'polydomain', 'polyline', 'polyadd',
+    'polysub', 'polymulx', 'polymul', 'polydiv', 'polypow', 'polyval',
+    'polyder', 'polyint', 'polyfromroots', 'polyvander', 'polyfit',
+    'polytrim', 'polyroots', 'Polynomial', 'polyval2d', 'polyval3d',
+    'polygrid2d', 'polygrid3d', 'polyvander2d', 'polyvander3d']
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+polytrim = pu.trimcoef
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Polynomial default domain.
+polydomain = np.array([-1, 1])
+
+# Polynomial coefficients representing zero.
+polyzero = np.array([0])
+
+# Polynomial coefficients representing one.
+polyone = np.array([1])
+
+# Polynomial coefficients representing the identity x.
+polyx = np.array([0, 1])
+
+#
+# Polynomial series functions
+#
+
+
+def polyline(off, scl):
+    """
+    Returns an array representing a linear polynomial.
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The "y-intercept" and "slope" of the line, respectively.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the linear polynomial ``off +
+        scl*x``.
+
+    See Also
+    --------
+    chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> P.polyline(1,-1)
+    array([ 1, -1])
+    >>> P.polyval(1, P.polyline(1,-1)) # should be 0
+    0.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def polyfromroots(roots):
+    """
+    Generate a monic polynomial with given roots.
+
+    Return the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    where the `r_n` are the roots specified in `roots`.  If a zero has
+    multiplicity n, then it must appear in `roots` n times. For instance,
+    if 2 is a root of multiplicity three and 3 is a root of multiplicity 2,
+    then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear
+    in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * x + ... +  x^n
+
+    The coefficient of the last term is 1 for monic polynomials in this
+    form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of the polynomial's coefficients If all the roots are
+        real, then `out` is also real, otherwise it is complex.  (see
+        Examples below).
+
+    See Also
+    --------
+    chebfromroots, legfromroots, lagfromroots, hermfromroots
+    hermefromroots
+
+    Notes
+    -----
+    The coefficients are determined by multiplying together linear factors
+    of the form `(x - r_i)`, i.e.
+
+    .. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n)
+
+    where ``n == len(roots) - 1``; note that this implies that `1` is always
+    returned for :math:`a_n`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x
+    array([ 0., -1.,  0.,  1.])
+    >>> j = complex(0,1)
+    >>> P.polyfromroots((-j,j)) # complex returned, though values are real
+    array([ 1.+0.j,  0.+0.j,  1.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [polyline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [polymul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = polymul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def polyadd(c1, c2):
+    """
+    Add one polynomial to another.
+
+    Returns the sum of two polynomials `c1` + `c2`.  The arguments are
+    sequences of coefficients from lowest order term to highest, i.e.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to high.
+
+    Returns
+    -------
+    out : ndarray
+        The coefficient array representing their sum.
+
+    See Also
+    --------
+    polysub, polymul, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> sum = P.polyadd(c1,c2); sum
+    array([ 4.,  4.,  4.])
+    >>> P.polyval(2, sum) # 4 + 4(2) + 4(2**2)
+    28.0
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def polysub(c1, c2):
+    """
+    Subtract one polynomial from another.
+
+    Returns the difference of two polynomials `c1` - `c2`.  The arguments
+    are sequences of coefficients from lowest order term to highest, i.e.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of coefficients representing their difference.
+
+    See Also
+    --------
+    polyadd, polymul, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polysub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> P.polysub(c2,c1) # -P.polysub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def polymulx(c):
+    """Multiply a polynomial by x.
+
+    Multiply the polynomial `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1:] = c
+    return prd
+
+
+def polymul(c1, c2):
+    """
+    Multiply one polynomial by another.
+
+    Returns the product of two polynomials `c1` * `c2`.  The arguments are
+    sequences of coefficients, from lowest order term to highest, e.g.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2.``
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of coefficients representing a polynomial, relative to the
+        "standard" basis, and ordered from lowest order term to highest.
+
+    Returns
+    -------
+    out : ndarray
+        Of the coefficients of their product.
+
+    See Also
+    --------
+    polyadd, polysub, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polymul(c1,c2)
+    array([  3.,   8.,  14.,   8.,   3.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    ret = np.convolve(c1, c2)
+    return pu.trimseq(ret)
+
+
+def polydiv(c1, c2):
+    """
+    Divide one polynomial by another.
+
+    Returns the quotient-with-remainder of two polynomials `c1` / `c2`.
+    The arguments are sequences of coefficients, from lowest order term
+    to highest, e.g., [1,2,3] represents ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of coefficient series representing the quotient and remainder.
+
+    See Also
+    --------
+    polyadd, polysub, polymul, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polydiv(c1,c2)
+    (array([ 3.]), array([-8., -4.]))
+    >>> P.polydiv(c2,c1)
+    (array([ 0.33333333]), array([ 2.66666667,  1.33333333]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    len1 = len(c1)
+    len2 = len(c2)
+    if len2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    elif len1 < len2:
+        return c1[:1]*0, c1
+    else:
+        dlen = len1 - len2
+        scl = c2[-1]
+        c2 = c2[:-1]/scl
+        i = dlen
+        j = len1 - 1
+        while i >= 0:
+            c1[i:j] -= c2*c1[j]
+            i -= 1
+            j -= 1
+        return c1[j+1:]/scl, pu.trimseq(c1[:j+1])
+
+
+def polypow(c, pow, maxpower=None):
+    """Raise a polynomial to a power.
+
+    Returns the polynomial `c` raised to the power `pow`. The argument
+    `c` is a sequence of coefficients ordered from low to high. i.e.,
+    [1,2,3] is the series  ``1 + 2*x + 3*x**2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of array of series coefficients ordered from low to
+        high degree.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Power series of power.
+
+    See Also
+    --------
+    polyadd, polysub, polymul, polydiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = np.convolve(prd, c)
+        return prd
+
+
+def polyder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a polynomial.
+
+    Returns the polynomial coefficients `c` differentiated `m` times along
+    `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable).  The
+    argument `c` is an array of coefficients from low to high degree along
+    each axis, e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``
+    while [[1,2],[1,2]] represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is
+    ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of polynomial coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree
+        in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change
+        of variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Polynomial coefficients of the derivative.
+
+    See Also
+    --------
+    polyint
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3
+    >>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2
+    array([  2.,   6.,  12.])
+    >>> P.polyder(c,3) # (d**3/dx**3)(c) = 24
+    array([ 24.])
+    >>> P.polyder(c,scl=-1) # (d/d(-x))(c) = -2 - 6x - 12x**2
+    array([ -2.,  -6., -12.])
+    >>> P.polyder(c,2,-1) # (d**2/d(-x)**2)(c) = 6 + 24x
+    array([  6.,  24.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype fails with NA
+        c = c + 0.0
+    cdt = c.dtype
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=cdt)
+            for j in range(n, 0, -1):
+                der[j - 1] = j*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a polynomial.
+
+    Returns the polynomial coefficients `c` integrated `m` times from
+    `lbnd` along `axis`.  At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.) The argument `c` is an array of
+    coefficients, from low to high degree along each axis, e.g., [1,2,3]
+    represents the polynomial ``1 + 2*x + 3*x**2`` while [[1,2],[1,2]]
+    represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients, ordered from low to high.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at zero
+        is the first value in the list, the value of the second integral
+        at zero is the second value, etc.  If ``k == []`` (the default),
+        all constants are set to zero.  If ``m == 1``, a single scalar can
+        be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Coefficient array of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 1``, ``len(k) > m``.
+
+    See Also
+    --------
+    polyder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.  Why
+    is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`. Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c = (1,2,3)
+    >>> P.polyint(c) # should return array([0, 1, 1, 1])
+    array([ 0.,  1.,  1.,  1.])
+    >>> P.polyint(c,3) # should return array([0, 0, 0, 1/6, 1/12, 1/20])
+    array([ 0.        ,  0.        ,  0.        ,  0.16666667,  0.08333333,
+            0.05      ])
+    >>> P.polyint(c,k=3) # should return array([3, 1, 1, 1])
+    array([ 3.,  1.,  1.,  1.])
+    >>> P.polyint(c,lbnd=-2) # should return array([6, 1, 1, 1])
+    array([ 6.,  1.,  1.,  1.])
+    >>> P.polyint(c,scl=-2) # should return array([0, -2, -2, -2])
+    array([ 0., -2., -2., -2.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype doesn't preserve mask attribute.
+        c = c + 0.0
+    cdt = c.dtype
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    k = list(k) + [0]*(cnt - len(k))
+    c = np.rollaxis(c, iaxis)
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=cdt)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(j + 1)
+            tmp[0] += k[i] - polyval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def polyval(x, c, tensor=True):
+    """
+    Evaluate a polynomial at points x.
+
+    If `c` is of length `n + 1`, this function returns the value
+
+    .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The shape of the returned array is described above.
+
+    See Also
+    --------
+    polyval2d, polygrid2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+    The evaluation uses Horner's method.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.polynomial import polyval
+    >>> polyval(1, [1,2,3])
+    6.0
+    >>> a = np.arange(4).reshape(2,2)
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> polyval(a, [1,2,3])
+    array([[  1.,   6.],
+           [ 17.,  34.]])
+    >>> coef = np.arange(4).reshape(2,2) # multidimensional coefficients
+    >>> coef
+    array([[0, 1],
+           [2, 3]])
+    >>> polyval([1,2], coef, tensor=True)
+    array([[ 2.,  4.],
+           [ 4.,  7.]])
+    >>> polyval([1,2], coef, tensor=False)
+    array([ 2.,  7.])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype fails with NA
+        c = c + 0.0
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    c0 = c[-1] + x*0
+    for i in range(2, len(c) + 1):
+        c0 = c[-i] + c0*x
+    return c0
+
+
+def polyval2d(x, y, c):
+    """
+    Evaluate a 2-D polynomial at points (x, y).
+
+    This function returns the value
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * x^i * y^j
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in `c[i,j]`. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    polyval, polygrid2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = polyval(x, c)
+    c = polyval(y, c, tensor=False)
+    return c
+
+
+def polygrid2d(x, y, c):
+    """
+    Evaluate a 2-D polynomial on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * a^i * b^j
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    polyval, polyval2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    c = polyval(x, c)
+    c = polyval(y, c)
+    return c
+
+
+def polyval3d(x, y, z, c):
+    """
+    Evaluate a 3-D polynomial at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * x^i * y^j * z^k
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    polyval, polyval2d, polygrid2d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = polyval(x, c)
+    c = polyval(y, c, tensor=False)
+    c = polyval(z, c, tensor=False)
+    return c
+
+
+def polygrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D polynomial on the Cartesian product of x, y and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * a^i * b^j * c^k
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    polyval, polyval2d, polygrid2d, polyval3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    c = polyval(x, c)
+    c = polyval(y, c)
+    c = polyval(z, c)
+    return c
+
+
+def polyvander(x, deg):
+    """Vandermonde matrix of given degree.
+
+    Returns the Vandermonde matrix of degree `deg` and sample points
+    `x`. The Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = x^i,
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the power of `x`.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    matrix ``V = polyvander(x, n)``, then ``np.dot(V, c)`` and
+    ``polyval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of polynomials of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray.
+        The Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where the last index is the power of `x`.
+        The dtype will be the same as the converted `x`.
+
+    See Also
+    --------
+    polyvander2d, polyvander3d
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = v[i-1]*x
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def polyvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = x^i * y^j,
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the powers of
+    `x` and `y`.
+
+    If ``V = polyvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``polyval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D polynomials
+    of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    polyvander, polyvander3d. polyval2d, polyval3d
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = polyvander(x, degx)
+    vy = polyvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    # einsum bug
+    #v = np.einsum("...i,...j->...ij", vx, vy)
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def polyvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = x^i * y^j * z^k,
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the powers of `x`, `y`, and `z`.
+
+    If ``V = polyvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``polyval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D polynomials
+    of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    polyvander, polyvander3d. polyval2d, polyval3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = polyvander(x, degx)
+    vy = polyvander(y, degy)
+    vz = polyvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    # einsum bug
+    #v = np.einsum("...i, ...j, ...k->...ijk", vx, vy, vz)
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least-squares fit of a polynomial to data.
+
+    Return the coefficients of a polynomial of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * x + ... + c_n * x^n,
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (`M`,)
+        x-coordinates of the `M` sample (data) points ``(x[i], y[i])``.
+    y : array_like, shape (`M`,) or (`M`, `K`)
+        y-coordinates of the sample points.  Several sets of sample points
+        sharing the same x-coordinates can be (independently) fit with one
+        call to `polyfit` by passing in for `y` a 2-D array that contains
+        one data set per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit.  Singular values smaller
+        than `rcond`, relative to the largest singular value, will be
+        ignored.  The default value is ``len(x)*eps``, where `eps` is the
+        relative precision of the platform's float type, about 2e-16 in
+        most cases.
+    full : bool, optional
+        Switch determining the nature of the return value.  When ``False``
+        (the default) just the coefficients are returned; when ``True``,
+        diagnostic information from the singular value decomposition (used
+        to solve the fit's matrix equation) is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (`deg` + 1,) or (`deg` + 1, `K`)
+        Polynomial coefficients ordered from low to high.  If `y` was 2-D,
+        the coefficients in column `k` of `coef` represent the polynomial
+        fit to the data in `y`'s `k`-th column.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Raises
+    ------
+    RankWarning
+        Raised if the matrix in the least-squares fit is rank deficient.
+        The warning is only raised if `full` == False.  The warnings can
+        be turned off by:
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, lagfit, hermfit, hermefit
+    polyval : Evaluates a polynomial.
+    polyvander : Vandermonde matrix for powers.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the polynomial `p` that minimizes
+    the sum of the weighted squared errors
+
+    .. math :: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) over-determined matrix equation:
+
+    .. math :: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected (and `full` == ``False``), a `RankWarning` will be raised.
+    This means that the coefficient values may be poorly determined.
+    Fitting to a lower order polynomial will usually get rid of the warning
+    (but may not be what you want, of course; if you have independent
+    reason(s) for choosing the degree which isn't working, you may have to:
+    a) reconsider those reasons, and/or b) reconsider the quality of your
+    data).  The `rcond` parameter can also be set to a value smaller than
+    its default, but the resulting fit may be spurious and have large
+    contributions from roundoff error.
+
+    Polynomial fits using double precision tend to "fail" at about
+    (polynomial) degree 20. Fits using Chebyshev or Legendre series are
+    generally better conditioned, but much can still depend on the
+    distribution of the sample points and the smoothness of the data.  If
+    the quality of the fit is inadequate, splines may be a good
+    alternative.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1]
+    >>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + N(0,1) "noise"
+    >>> c, stats = P.polyfit(x,y,3,full=True)
+    >>> c # c[0], c[2] should be approx. 0, c[1] approx. -1, c[3] approx. 1
+    array([ 0.01909725, -1.30598256, -0.00577963,  1.02644286])
+    >>> stats # note the large SSR, explaining the rather poor results
+    [array([ 38.06116253]), 4, array([ 1.38446749,  1.32119158,  0.50443316,
+    0.28853036]), 1.1324274851176597e-014]
+
+    Same thing without the added noise
+
+    >>> y = x**3 - x
+    >>> c, stats = P.polyfit(x,y,3,full=True)
+    >>> c # c[0], c[2] should be "very close to 0", c[1] ~= -1, c[3] ~= 1
+    array([ -1.73362882e-17,  -1.00000000e+00,  -2.67471909e-16,
+             1.00000000e+00])
+    >>> stats # note the minuscule SSR
+    [array([  7.46346754e-31]), 4, array([ 1.38446749,  1.32119158,
+    0.50443316,  0.28853036]), 1.1324274851176597e-014]
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = polyvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = polyvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim == 1:
+        if c.ndim == 2:
+            cc = np.zeros((lmax + 1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax + 1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def polycompanion(c):
+    """
+    Return the companion matrix of c.
+
+    The companion matrix for power series cannot be made symmetric by
+    scaling the basis, so this function differs from those for the
+    orthogonal polynomials.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    bot = mat.reshape(-1)[n::n+1]
+    bot[...] = 1
+    mat[:, -1] -= c[:-1]/c[-1]
+    return mat
+
+
+def polyroots(c):
+    """
+    Compute the roots of a polynomial.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * x^i.
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of polynomial coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the polynomial. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    chebroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the power series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.polynomial as poly
+    >>> poly.polyroots(poly.polyfromroots((-1,0,1)))
+    array([-1.,  0.,  1.])
+    >>> poly.polyroots(poly.polyfromroots((-1,0,1))).dtype
+    dtype('float64')
+    >>> j = complex(0,1)
+    >>> poly.polyroots(poly.polyfromroots((-j,0,j)))
+    array([  0.00000000e+00+0.j,   0.00000000e+00+1.j,   2.77555756e-17-1.j])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = polycompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+#
+# polynomial class
+#
+
+class Polynomial(ABCPolyBase):
+    """A power series class.
+
+    The Polynomial class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Polynomial coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` give ``1 + 2*x + 3*x**2``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(polyadd)
+    _sub = staticmethod(polysub)
+    _mul = staticmethod(polymul)
+    _div = staticmethod(polydiv)
+    _pow = staticmethod(polypow)
+    _val = staticmethod(polyval)
+    _int = staticmethod(polyint)
+    _der = staticmethod(polyder)
+    _fit = staticmethod(polyfit)
+    _line = staticmethod(polyline)
+    _roots = staticmethod(polyroots)
+    _fromroots = staticmethod(polyfromroots)
+
+    # Virtual properties
+    nickname = 'poly'
+    domain = np.array(polydomain)
+    window = np.array(polydomain)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
new file mode 100644
index 0000000000..c1b7528d5a
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
@@ -0,0 +1,403 @@
+"""
+Utililty classes and functions for the polynomial modules.
+
+This module provides: error and warning objects; a polynomial base class;
+and some routines used in both the `polynomial` and `chebyshev` modules.
+
+Error objects
+-------------
+
+.. autosummary::
+   :toctree: generated/
+
+   PolyError            base class for this sub-package's errors.
+   PolyDomainError      raised when domains are mismatched.
+
+Warning objects
+---------------
+
+.. autosummary::
+   :toctree: generated/
+
+   RankWarning  raised in least-squares fit for rank-deficient matrix.
+
+Base class
+----------
+
+.. autosummary::
+   :toctree: generated/
+
+   PolyBase Obsolete base class for the polynomial classes. Do not use.
+
+Functions
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   as_series    convert list of array_likes into 1-D arrays of common type.
+   trimseq      remove trailing zeros.
+   trimcoef     remove small trailing coefficients.
+   getdomain    return the domain appropriate for a given set of abscissae.
+   mapdomain    maps points between domains.
+   mapparms     parameters of the linear map between domains.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = [
+    'RankWarning', 'PolyError', 'PolyDomainError', 'as_series', 'trimseq',
+    'trimcoef', 'getdomain', 'mapdomain', 'mapparms', 'PolyBase']
+
+#
+# Warnings and Exceptions
+#
+
+class RankWarning(UserWarning):
+    """Issued by chebfit when the design matrix is rank deficient."""
+    pass
+
+class PolyError(Exception):
+    """Base class for errors in this module."""
+    pass
+
+class PolyDomainError(PolyError):
+    """Issued by the generic Poly class when two domains don't match.
+
+    This is raised when an binary operation is passed Poly objects with
+    different domains.
+
+    """
+    pass
+
+#
+# Base class for all polynomial types
+#
+
+class PolyBase(object):
+    """
+    Base class for all polynomial types.
+
+    Deprecated in numpy 1.9.0, use the abstract
+    ABCPolyBase class instead. Note that the latter
+    reguires a number of virtual functions to be
+    implemented.
+
+    """
+    pass
+
+#
+# Helper functions to convert inputs to 1-D arrays
+#
+def trimseq(seq):
+    """Remove small Poly series coefficients.
+
+    Parameters
+    ----------
+    seq : sequence
+        Sequence of Poly series coefficients. This routine fails for
+        empty sequences.
+
+    Returns
+    -------
+    series : sequence
+        Subsequence with trailing zeros removed. If the resulting sequence
+        would be empty, return the first element. The returned sequence may
+        or may not be a view.
+
+    Notes
+    -----
+    Do not lose the type info if the sequence contains unknown objects.
+
+    """
+    if len(seq) == 0:
+        return seq
+    else:
+        for i in range(len(seq) - 1, -1, -1):
+            if seq[i] != 0:
+                break
+        return seq[:i+1]
+
+
+def as_series(alist, trim=True):
+    """
+    Return argument as a list of 1-d arrays.
+
+    The returned list contains array(s) of dtype double, complex double, or
+    object.  A 1-d argument of shape ``(N,)`` is parsed into ``N`` arrays of
+    size one; a 2-d argument of shape ``(M,N)`` is parsed into ``M`` arrays
+    of size ``N`` (i.e., is "parsed by row"); and a higher dimensional array
+    raises a Value Error if it is not first reshaped into either a 1-d or 2-d
+    array.
+
+    Parameters
+    ----------
+    alist : array_like
+        A 1- or 2-d array_like
+    trim : boolean, optional
+        When True, trailing zeros are removed from the inputs.
+        When False, the inputs are passed through intact.
+
+    Returns
+    -------
+    [a1, a2,...] : list of 1-D arrays
+        A copy of the input data as a list of 1-d arrays.
+
+    Raises
+    ------
+    ValueError
+        Raised when `as_series` cannot convert its input to 1-d arrays, or at
+        least one of the resulting arrays is empty.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> a = np.arange(4)
+    >>> P.as_series(a)
+    [array([ 0.]), array([ 1.]), array([ 2.]), array([ 3.])]
+    >>> b = np.arange(6).reshape((2,3))
+    >>> P.as_series(b)
+    [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.])]
+
+    """
+    arrays = [np.array(a, ndmin=1, copy=0) for a in alist]
+    if min([a.size for a in arrays]) == 0:
+        raise ValueError("Coefficient array is empty")
+    if any([a.ndim != 1 for a in arrays]):
+        raise ValueError("Coefficient array is not 1-d")
+    if trim:
+        arrays = [trimseq(a) for a in arrays]
+
+    if any([a.dtype == np.dtype(object) for a in arrays]):
+        ret = []
+        for a in arrays:
+            if a.dtype != np.dtype(object):
+                tmp = np.empty(len(a), dtype=np.dtype(object))
+                tmp[:] = a[:]
+                ret.append(tmp)
+            else:
+                ret.append(a.copy())
+    else:
+        try:
+            dtype = np.common_type(*arrays)
+        except:
+            raise ValueError("Coefficient arrays have no common type")
+        ret = [np.array(a, copy=1, dtype=dtype) for a in arrays]
+    return ret
+
+
+def trimcoef(c, tol=0):
+    """
+    Remove "small" "trailing" coefficients from a polynomial.
+
+    "Small" means "small in absolute value" and is controlled by the
+    parameter `tol`; "trailing" means highest order coefficient(s), e.g., in
+    ``[0, 1, 1, 0, 0]`` (which represents ``0 + x + x**2 + 0*x**3 + 0*x**4``)
+    both the 3-rd and 4-th order coefficients would be "trimmed."
+
+    Parameters
+    ----------
+    c : array_like
+        1-d array of coefficients, ordered from lowest order to highest.
+    tol : number, optional
+        Trailing (i.e., highest order) elements with absolute value less
+        than or equal to `tol` (default value is zero) are removed.
+
+    Returns
+    -------
+    trimmed : ndarray
+        1-d array with trailing zeros removed.  If the resulting series
+        would be empty, a series containing a single zero is returned.
+
+    Raises
+    ------
+    ValueError
+        If `tol` < 0
+
+    See Also
+    --------
+    trimseq
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> P.trimcoef((0,0,3,0,5,0,0))
+    array([ 0.,  0.,  3.,  0.,  5.])
+    >>> P.trimcoef((0,0,1e-3,0,1e-5,0,0),1e-3) # item == tol is trimmed
+    array([ 0.])
+    >>> i = complex(0,1) # works for complex
+    >>> P.trimcoef((3e-4,1e-3*(1-i),5e-4,2e-5*(1+i)), 1e-3)
+    array([ 0.0003+0.j   ,  0.0010-0.001j])
+
+    """
+    if tol < 0:
+        raise ValueError("tol must be non-negative")
+
+    [c] = as_series([c])
+    [ind] = np.where(np.abs(c) > tol)
+    if len(ind) == 0:
+        return c[:1]*0
+    else:
+        return c[:ind[-1] + 1].copy()
+
+def getdomain(x):
+    """
+    Return a domain suitable for given abscissae.
+
+    Find a domain suitable for a polynomial or Chebyshev series
+    defined at the values supplied.
+
+    Parameters
+    ----------
+    x : array_like
+        1-d array of abscissae whose domain will be determined.
+
+    Returns
+    -------
+    domain : ndarray
+        1-d array containing two values.  If the inputs are complex, then
+        the two returned points are the lower left and upper right corners
+        of the smallest rectangle (aligned with the axes) in the complex
+        plane containing the points `x`. If the inputs are real, then the
+        two points are the ends of the smallest interval containing the
+        points `x`.
+
+    See Also
+    --------
+    mapparms, mapdomain
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polyutils as pu
+    >>> points = np.arange(4)**2 - 5; points
+    array([-5, -4, -1,  4])
+    >>> pu.getdomain(points)
+    array([-5.,  4.])
+    >>> c = np.exp(complex(0,1)*np.pi*np.arange(12)/6) # unit circle
+    >>> pu.getdomain(c)
+    array([-1.-1.j,  1.+1.j])
+
+    """
+    [x] = as_series([x], trim=False)
+    if x.dtype.char in np.typecodes['Complex']:
+        rmin, rmax = x.real.min(), x.real.max()
+        imin, imax = x.imag.min(), x.imag.max()
+        return np.array((complex(rmin, imin), complex(rmax, imax)))
+    else:
+        return np.array((x.min(), x.max()))
+
+def mapparms(old, new):
+    """
+    Linear map parameters between domains.
+
+    Return the parameters of the linear map ``offset + scale*x`` that maps
+    `old` to `new` such that ``old[i] -> new[i]``, ``i = 0, 1``.
+
+    Parameters
+    ----------
+    old, new : array_like
+        Domains. Each domain must (successfully) convert to a 1-d array
+        containing precisely two values.
+
+    Returns
+    -------
+    offset, scale : scalars
+        The map ``L(x) = offset + scale*x`` maps the first domain to the
+        second.
+
+    See Also
+    --------
+    getdomain, mapdomain
+
+    Notes
+    -----
+    Also works for complex numbers, and thus can be used to calculate the
+    parameters required to map any line in the complex plane to any other
+    line therein.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> P.mapparms((-1,1),(-1,1))
+    (0.0, 1.0)
+    >>> P.mapparms((1,-1),(-1,1))
+    (0.0, -1.0)
+    >>> i = complex(0,1)
+    >>> P.mapparms((-i,-1),(1,i))
+    ((1+1j), (1+0j))
+
+    """
+    oldlen = old[1] - old[0]
+    newlen = new[1] - new[0]
+    off = (old[1]*new[0] - old[0]*new[1])/oldlen
+    scl = newlen/oldlen
+    return off, scl
+
+def mapdomain(x, old, new):
+    """
+    Apply linear map to input points.
+
+    The linear map ``offset + scale*x`` that maps the domain `old` to
+    the domain `new` is applied to the points `x`.
+
+    Parameters
+    ----------
+    x : array_like
+        Points to be mapped. If `x` is a subtype of ndarray the subtype
+        will be preserved.
+    old, new : array_like
+        The two domains that determine the map.  Each must (successfully)
+        convert to 1-d arrays containing precisely two values.
+
+    Returns
+    -------
+    x_out : ndarray
+        Array of points of the same shape as `x`, after application of the
+        linear map between the two domains.
+
+    See Also
+    --------
+    getdomain, mapparms
+
+    Notes
+    -----
+    Effectively, this implements:
+
+    .. math ::
+        x\\_out = new[0] + m(x - old[0])
+
+    where
+
+    .. math ::
+        m = \\frac{new[1]-new[0]}{old[1]-old[0]}
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> old_domain = (-1,1)
+    >>> new_domain = (0,2*np.pi)
+    >>> x = np.linspace(-1,1,6); x
+    array([-1. , -0.6, -0.2,  0.2,  0.6,  1. ])
+    >>> x_out = P.mapdomain(x, old_domain, new_domain); x_out
+    array([ 0.        ,  1.25663706,  2.51327412,  3.76991118,  5.02654825,
+            6.28318531])
+    >>> x - P.mapdomain(x_out, new_domain, old_domain)
+    array([ 0.,  0.,  0.,  0.,  0.,  0.])
+
+    Also works for complex numbers (and thus can be used to map any line in
+    the complex plane to any other line therein).
+
+    >>> i = complex(0,1)
+    >>> old = (-1 - i, 1 + i)
+    >>> new = (-1 + i, 1 - i)
+    >>> z = np.linspace(old[0], old[1], 6); z
+    array([-1.0-1.j , -0.6-0.6j, -0.2-0.2j,  0.2+0.2j,  0.6+0.6j,  1.0+1.j ])
+    >>> new_z = P.mapdomain(z, old, new); new_z
+    array([-1.0+1.j , -0.6+0.6j, -0.2+0.2j,  0.2-0.2j,  0.6-0.6j,  1.0-1.j ])
+
+    """
+    x = np.asanyarray(x)
+    off, scl = mapparms(old, new)
+    return off + scl*x
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.py
new file mode 100644
index 0000000000..cb59ee1e56
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.py
@@ -0,0 +1,11 @@
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('polynomial', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
new file mode 100644
index 0000000000..8d992c4f09
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
@@ -0,0 +1,585 @@
+"""Tests for chebyshev module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.chebyshev as cheb
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+def trim(x):
+    return cheb.chebtrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestPrivate(TestCase):
+
+    def test__cseries_to_zseries(self):
+        for i in range(5):
+            inp = np.array([2] + [1]*i, np.double)
+            tgt = np.array([.5]*i + [2] + [.5]*i, np.double)
+            res = cheb._cseries_to_zseries(inp)
+            assert_equal(res, tgt)
+
+    def test__zseries_to_cseries(self):
+        for i in range(5):
+            inp = np.array([.5]*i + [2] + [.5]*i, np.double)
+            tgt = np.array([2] + [1]*i, np.double)
+            res = cheb._zseries_to_cseries(inp)
+            assert_equal(res, tgt)
+
+
+class TestConstants(TestCase):
+
+    def test_chebdomain(self):
+        assert_equal(cheb.chebdomain, [-1, 1])
+
+    def test_chebzero(self):
+        assert_equal(cheb.chebzero, [0])
+
+    def test_chebone(self):
+        assert_equal(cheb.chebone, [1])
+
+    def test_chebx(self):
+        assert_equal(cheb.chebx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+
+    def test_chebadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = cheb.chebadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = cheb.chebsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebmulx(self):
+        assert_equal(cheb.chebmulx([0]), [0])
+        assert_equal(cheb.chebmulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [.5, 0, .5]
+            assert_equal(cheb.chebmulx(ser), tgt)
+
+    def test_chebmul(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(i + j + 1)
+                tgt[i + j] += .5
+                tgt[abs(i - j)] += .5
+                res = cheb.chebmul([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = cheb.chebadd(ci, cj)
+                quo, rem = cheb.chebdiv(tgt, ci)
+                res = cheb.chebadd(cheb.chebmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2.5, 2., 1.5])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_chebval(self):
+        #check empty input
+        assert_equal(cheb.chebval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Tlist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = cheb.chebval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(cheb.chebval(x, [1]).shape, dims)
+            assert_equal(cheb.chebval(x, [1, 0]).shape, dims)
+            assert_equal(cheb.chebval(x, [1, 0, 0]).shape, dims)
+
+    def test_chebval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, cheb.chebval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = cheb.chebval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_chebval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, cheb.chebval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = cheb.chebval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_chebgrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = cheb.chebgrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebgrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_chebgrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = cheb.chebgrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebgrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_chebint(self):
+        # check exceptions
+        assert_raises(ValueError, cheb.chebint, [0], .5)
+        assert_raises(ValueError, cheb.chebint, [0], -1)
+        assert_raises(ValueError, cheb.chebint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = cheb.chebint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i])
+            res = cheb.cheb2poly(chebint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(cheb.chebval(-1, chebint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i], scl=2)
+            res = cheb.cheb2poly(chebint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1)
+                res = cheb.chebint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k])
+                res = cheb.chebint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k], lbnd=-1)
+                res = cheb.chebint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k], scl=2)
+                res = cheb.chebint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([cheb.chebint(c) for c in c2d.T]).T
+        res = cheb.chebint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebint(c) for c in c2d])
+        res = cheb.chebint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebint(c, k=3) for c in c2d])
+        res = cheb.chebint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_chebder(self):
+        # check exceptions
+        assert_raises(ValueError, cheb.chebder, [0], .5)
+        assert_raises(ValueError, cheb.chebder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = cheb.chebder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = cheb.chebder(cheb.chebint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = cheb.chebder(cheb.chebint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([cheb.chebder(c) for c in c2d.T]).T
+        res = cheb.chebder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebder(c) for c in c2d])
+        res = cheb.chebder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_chebvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = cheb.chebvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = cheb.chebvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+    def test_chebvander2d(self):
+        # also tests chebval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = cheb.chebvander2d(x1, x2, [1, 2])
+        tgt = cheb.chebval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = cheb.chebvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_chebvander3d(self):
+        # also tests chebval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = cheb.chebvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = cheb.chebval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = cheb.chebvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_chebfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, cheb.chebfit, [1], [1], -1)
+        assert_raises(TypeError, cheb.chebfit, [[1]], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, cheb.chebfit, [1, 2], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [1, 2], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, cheb.chebfit, [1], [1], [-1,])
+        assert_raises(ValueError, cheb.chebfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, cheb.chebfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = cheb.chebfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(cheb.chebval(x, coef3), y)
+        coef3 = cheb.chebfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(cheb.chebval(x, coef3), y)
+        #
+        coef4 = cheb.chebfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        coef4 = cheb.chebfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = cheb.chebfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        #
+        coef2d = cheb.chebfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = cheb.chebfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = cheb.chebfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = cheb.chebfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(cheb.chebfit(x, x, 1), [0, 1])
+        assert_almost_equal(cheb.chebfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = cheb.chebfit(x, y, 4)
+        assert_almost_equal(cheb.chebval(x, coef1), y)
+        coef2 = cheb.chebfit(x, y, [0, 2, 4])
+        assert_almost_equal(cheb.chebval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, cheb.chebcompanion, [])
+        assert_raises(ValueError, cheb.chebcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(cheb.chebcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(cheb.chebcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = cheb.chebgauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = cheb.chebvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.pi
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_chebfromroots(self):
+        res = cheb.chebfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            tgt = [0]*i + [1]
+            res = cheb.chebfromroots(roots)*2**(i-1)
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebroots(self):
+        assert_almost_equal(cheb.chebroots([1]), [])
+        assert_almost_equal(cheb.chebroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = cheb.chebroots(cheb.chebfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, cheb.chebtrim, coef, -1)
+
+        # Test results
+        assert_equal(cheb.chebtrim(coef), coef[:-1])
+        assert_equal(cheb.chebtrim(coef, 1), coef[:-3])
+        assert_equal(cheb.chebtrim(coef, 2), [0])
+
+    def test_chebline(self):
+        assert_equal(cheb.chebline(3, 4), [3, 4])
+
+    def test_cheb2poly(self):
+        for i in range(10):
+            assert_almost_equal(cheb.cheb2poly([0]*i + [1]), Tlist[i])
+
+    def test_poly2cheb(self):
+        for i in range(10):
+            assert_almost_equal(cheb.poly2cheb(Tlist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-1, 1, 11)[1:-1]
+        tgt = 1./(np.sqrt(1 + x) * np.sqrt(1 - x))
+        res = cheb.chebweight(x)
+        assert_almost_equal(res, tgt)
+
+    def test_chebpts1(self):
+        #test exceptions
+        assert_raises(ValueError, cheb.chebpts1, 1.5)
+        assert_raises(ValueError, cheb.chebpts1, 0)
+
+        #test points
+        tgt = [0]
+        assert_almost_equal(cheb.chebpts1(1), tgt)
+        tgt = [-0.70710678118654746, 0.70710678118654746]
+        assert_almost_equal(cheb.chebpts1(2), tgt)
+        tgt = [-0.86602540378443871, 0, 0.86602540378443871]
+        assert_almost_equal(cheb.chebpts1(3), tgt)
+        tgt = [-0.9238795325, -0.3826834323, 0.3826834323, 0.9238795325]
+        assert_almost_equal(cheb.chebpts1(4), tgt)
+
+    def test_chebpts2(self):
+        #test exceptions
+        assert_raises(ValueError, cheb.chebpts2, 1.5)
+        assert_raises(ValueError, cheb.chebpts2, 1)
+
+        #test points
+        tgt = [-1, 1]
+        assert_almost_equal(cheb.chebpts2(2), tgt)
+        tgt = [-1, 0, 1]
+        assert_almost_equal(cheb.chebpts2(3), tgt)
+        tgt = [-1, -0.5, .5, 1]
+        assert_almost_equal(cheb.chebpts2(4), tgt)
+        tgt = [-1.0, -0.707106781187, 0, 0.707106781187, 1.0]
+        assert_almost_equal(cheb.chebpts2(5), tgt)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
new file mode 100644
index 0000000000..a7cf7209c6
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
@@ -0,0 +1,579 @@
+"""Test inter-conversion of different polynomial classes.
+
+This tests the convert and cast methods of all the polynomial classes.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import operator as op
+from numbers import Number
+
+import numpy as np
+from numpy.polynomial import (
+    Polynomial, Legendre, Chebyshev, Laguerre, Hermite, HermiteE)
+from numpy.testing import (
+    assert_almost_equal, assert_raises, assert_equal, assert_,
+    run_module_suite)
+from numpy.compat import long
+
+
+classes = (
+    Polynomial, Legendre, Chebyshev, Laguerre,
+    Hermite, HermiteE)
+
+
+def test_class_methods():
+    for Poly1 in classes:
+        for Poly2 in classes:
+            yield check_conversion, Poly1, Poly2
+            yield check_cast, Poly1, Poly2
+    for Poly in classes:
+        yield check_call, Poly
+        yield check_identity, Poly
+        yield check_basis, Poly
+        yield check_fromroots, Poly
+        yield check_fit, Poly
+        yield check_equal, Poly
+        yield check_not_equal, Poly
+        yield check_add, Poly
+        yield check_sub, Poly
+        yield check_mul, Poly
+        yield check_floordiv, Poly
+        yield check_truediv, Poly
+        yield check_mod, Poly
+        yield check_divmod, Poly
+        yield check_pow, Poly
+        yield check_integ, Poly
+        yield check_deriv, Poly
+        yield check_roots, Poly
+        yield check_linspace, Poly
+        yield check_mapparms, Poly
+        yield check_degree, Poly
+        yield check_copy, Poly
+        yield check_cutdeg, Poly
+        yield check_truncate, Poly
+        yield check_trim, Poly
+
+
+#
+# helper functions
+#
+random = np.random.random
+
+
+def assert_poly_almost_equal(p1, p2, msg=""):
+    try:
+        assert_(np.all(p1.domain == p2.domain))
+        assert_(np.all(p1.window == p2.window))
+        assert_almost_equal(p1.coef, p2.coef)
+    except AssertionError:
+        msg = "Result: %s\nTarget: %s", (p1, p2)
+        raise AssertionError(msg)
+
+
+#
+# conversion methods that depend on two classes
+#
+
+
+def check_conversion(Poly1, Poly2):
+    x = np.linspace(0, 1, 10)
+    coef = random((3,))
+
+    d1 = Poly1.domain + random((2,))*.25
+    w1 = Poly1.window + random((2,))*.25
+    p1 = Poly1(coef, domain=d1, window=w1)
+
+    d2 = Poly2.domain + random((2,))*.25
+    w2 = Poly2.window + random((2,))*.25
+    p2 = p1.convert(kind=Poly2, domain=d2, window=w2)
+
+    assert_almost_equal(p2.domain, d2)
+    assert_almost_equal(p2.window, w2)
+    assert_almost_equal(p2(x), p1(x))
+
+
+def check_cast(Poly1, Poly2):
+    x = np.linspace(0, 1, 10)
+    coef = random((3,))
+
+    d1 = Poly1.domain + random((2,))*.25
+    w1 = Poly1.window + random((2,))*.25
+    p1 = Poly1(coef, domain=d1, window=w1)
+
+    d2 = Poly2.domain + random((2,))*.25
+    w2 = Poly2.window + random((2,))*.25
+    p2 = Poly2.cast(p1, domain=d2, window=w2)
+
+    assert_almost_equal(p2.domain, d2)
+    assert_almost_equal(p2.window, w2)
+    assert_almost_equal(p2(x), p1(x))
+
+
+#
+# methods that depend on one class
+#
+
+
+def check_identity(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    x = np.linspace(d[0], d[1], 11)
+    p = Poly.identity(domain=d, window=w)
+    assert_equal(p.domain, d)
+    assert_equal(p.window, w)
+    assert_almost_equal(p(x), x)
+
+
+def check_basis(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly.basis(5, domain=d, window=w)
+    assert_equal(p.domain, d)
+    assert_equal(p.window, w)
+    assert_equal(p.coef, [0]*5 + [1])
+
+
+def check_fromroots(Poly):
+    # check that requested roots are zeros of a polynomial
+    # of correct degree, domain, and window.
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    r = random((5,))
+    p1 = Poly.fromroots(r, domain=d, window=w)
+    assert_equal(p1.degree(), len(r))
+    assert_equal(p1.domain, d)
+    assert_equal(p1.window, w)
+    assert_almost_equal(p1(r), 0)
+
+    # check that polynomial is monic
+    pdom = Polynomial.domain
+    pwin = Polynomial.window
+    p2 = Polynomial.cast(p1, domain=pdom, window=pwin)
+    assert_almost_equal(p2.coef[-1], 1)
+
+
+def check_fit(Poly):
+
+    def f(x):
+        return x*(x - 1)*(x - 2)
+    x = np.linspace(0, 3)
+    y = f(x)
+
+    # check default value of domain and window
+    p = Poly.fit(x, y, 3)
+    assert_almost_equal(p.domain, [0, 3])
+    assert_almost_equal(p(x), y)
+    assert_equal(p.degree(), 3)
+
+    # check with given domains and window
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly.fit(x, y, 3, domain=d, window=w)
+    assert_almost_equal(p(x), y)
+    assert_almost_equal(p.domain, d)
+    assert_almost_equal(p.window, w)
+    p = Poly.fit(x, y, [0, 1, 2, 3], domain=d, window=w)
+    assert_almost_equal(p(x), y)
+    assert_almost_equal(p.domain, d)
+    assert_almost_equal(p.window, w)
+
+    # check with class domain default
+    p = Poly.fit(x, y, 3, [])
+    assert_equal(p.domain, Poly.domain)
+    assert_equal(p.window, Poly.window)
+    p = Poly.fit(x, y, [0, 1, 2, 3], [])
+    assert_equal(p.domain, Poly.domain)
+    assert_equal(p.window, Poly.window)
+
+    # check that fit accepts weights.
+    w = np.zeros_like(x)
+    z = y + random(y.shape)*.25
+    w[::2] = 1
+    p1 = Poly.fit(x[::2], z[::2], 3)
+    p2 = Poly.fit(x, z, 3, w=w)
+    p3 = Poly.fit(x, z, [0, 1, 2, 3], w=w)
+    assert_almost_equal(p1(x), p2(x))
+    assert_almost_equal(p2(x), p3(x))
+
+
+def check_equal(Poly):
+    p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+    p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+    p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+    p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+    assert_(p1 == p1)
+    assert_(not p1 == p2)
+    assert_(not p1 == p3)
+    assert_(not p1 == p4)
+
+
+def check_not_equal(Poly):
+    p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+    p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+    p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+    p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+    assert_(not p1 != p1)
+    assert_(p1 != p2)
+    assert_(p1 != p3)
+    assert_(p1 != p4)
+
+
+def check_add(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 + p2
+    assert_poly_almost_equal(p2 + p1, p3)
+    assert_poly_almost_equal(p1 + c2, p3)
+    assert_poly_almost_equal(c2 + p1, p3)
+    assert_poly_almost_equal(p1 + tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) + p1, p3)
+    assert_poly_almost_equal(p1 + np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) + p1, p3)
+    assert_raises(TypeError, op.add, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.add, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.add, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.add, p1, Polynomial([0]))
+
+
+def check_sub(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 - p2
+    assert_poly_almost_equal(p2 - p1, -p3)
+    assert_poly_almost_equal(p1 - c2, p3)
+    assert_poly_almost_equal(c2 - p1, -p3)
+    assert_poly_almost_equal(p1 - tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) - p1, -p3)
+    assert_poly_almost_equal(p1 - np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) - p1, -p3)
+    assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.sub, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.sub, p1, Polynomial([0]))
+
+
+def check_mul(Poly):
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 * p2
+    assert_poly_almost_equal(p2 * p1, p3)
+    assert_poly_almost_equal(p1 * c2, p3)
+    assert_poly_almost_equal(c2 * p1, p3)
+    assert_poly_almost_equal(p1 * tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) * p1, p3)
+    assert_poly_almost_equal(p1 * np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) * p1, p3)
+    assert_poly_almost_equal(p1 * 2, p1 * Poly([2]))
+    assert_poly_almost_equal(2 * p1, p1 * Poly([2]))
+    assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.mul, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.mul, p1, Polynomial([0]))
+
+
+def check_floordiv(Poly):
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    assert_poly_almost_equal(p4 // p2, p1)
+    assert_poly_almost_equal(p4 // c2, p1)
+    assert_poly_almost_equal(c4 // p2, p1)
+    assert_poly_almost_equal(p4 // tuple(c2), p1)
+    assert_poly_almost_equal(tuple(c4) // p2, p1)
+    assert_poly_almost_equal(p4 // np.array(c2), p1)
+    assert_poly_almost_equal(np.array(c4) // p2, p1)
+    assert_poly_almost_equal(2 // p2, Poly([0]))
+    assert_poly_almost_equal(p2 // 2, 0.5*p2)
+    assert_raises(
+        TypeError, op.floordiv, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(
+        TypeError, op.floordiv, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.floordiv, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.floordiv, p1, Polynomial([0]))
+
+
+def check_truediv(Poly):
+    # true division is valid only if the denominator is a Number and
+    # not a python bool.
+    p1 = Poly([1,2,3])
+    p2 = p1 * 5
+
+    for stype in np.ScalarType:
+        if not issubclass(stype, Number) or issubclass(stype, bool):
+            continue
+        s = stype(5)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for stype in (int, long, float):
+        s = stype(5)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for stype in [complex]:
+        s = stype(5, 0)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for s in [tuple(), list(), dict(), bool(), np.array([1])]:
+        assert_raises(TypeError, op.truediv, p2, s)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for ptype in classes:
+        assert_raises(TypeError, op.truediv, p2, ptype(1))
+
+
+def check_mod(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    assert_poly_almost_equal(p4 % p2, p3)
+    assert_poly_almost_equal(p4 % c2, p3)
+    assert_poly_almost_equal(c4 % p2, p3)
+    assert_poly_almost_equal(p4 % tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c4) % p2, p3)
+    assert_poly_almost_equal(p4 % np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c4) % p2, p3)
+    assert_poly_almost_equal(2 % p2, Poly([2]))
+    assert_poly_almost_equal(p2 % 2, Poly([0]))
+    assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.mod, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.mod, p1, Polynomial([0]))
+
+
+def check_divmod(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    quo, rem = divmod(p4, p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, c2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(c4, p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, tuple(c2))
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(tuple(c4), p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, np.array(c2))
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(np.array(c4), p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p2, 2)
+    assert_poly_almost_equal(quo, 0.5*p2)
+    assert_poly_almost_equal(rem, Poly([0]))
+    quo, rem = divmod(2, p2)
+    assert_poly_almost_equal(quo, Poly([0]))
+    assert_poly_almost_equal(rem, Poly([2]))
+    assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, divmod, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, divmod, p1, Polynomial([0]))
+
+
+def check_roots(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    tgt = np.sort(random((5,)))
+    res = np.sort(Poly.fromroots(tgt, domain=d, window=w).roots())
+    assert_almost_equal(res, tgt)
+    # default domain and window
+    res = np.sort(Poly.fromroots(tgt).roots())
+    assert_almost_equal(res, tgt)
+
+
+def check_degree(Poly):
+    p = Poly.basis(5)
+    assert_equal(p.degree(), 5)
+
+
+def check_copy(Poly):
+    p1 = Poly.basis(5)
+    p2 = p1.copy()
+    assert_(p1 == p2)
+    assert_(p1 is not p2)
+    assert_(p1.coef is not p2.coef)
+    assert_(p1.domain is not p2.domain)
+    assert_(p1.window is not p2.window)
+
+
+def check_integ(Poly):
+    P = Polynomial
+    # Check defaults
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ())
+    p2 = P.cast(p0.integ(2))
+    assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+    # Check with k
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ(k=1))
+    p2 = P.cast(p0.integ(2, k=[1, 1]))
+    assert_poly_almost_equal(p1, P([1, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([1, 1, 1, 1, 1]))
+    # Check with lbnd
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ(lbnd=1))
+    p2 = P.cast(p0.integ(2, lbnd=1))
+    assert_poly_almost_equal(p1, P([-9, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([6, -9, 1, 1, 1]))
+    # Check scaling
+    d = 2*Poly.domain
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]), domain=d)
+    p1 = P.cast(p0.integ())
+    p2 = P.cast(p0.integ(2))
+    assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+
+
+def check_deriv(Poly):
+    # Check that the derivative is the inverse of integration. It is
+    # assumes that the integration has been checked elsewhere.
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p1 = Poly([1, 2, 3], domain=d, window=w)
+    p2 = p1.integ(2, k=[1, 2])
+    p3 = p1.integ(1, k=[1])
+    assert_almost_equal(p2.deriv(1).coef, p3.coef)
+    assert_almost_equal(p2.deriv(2).coef, p1.coef)
+    # default domain and window
+    p1 = Poly([1, 2, 3])
+    p2 = p1.integ(2, k=[1, 2])
+    p3 = p1.integ(1, k=[1])
+    assert_almost_equal(p2.deriv(1).coef, p3.coef)
+    assert_almost_equal(p2.deriv(2).coef, p1.coef)
+
+
+def check_linspace(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly([1, 2, 3], domain=d, window=w)
+    # check default domain
+    xtgt = np.linspace(d[0], d[1], 20)
+    ytgt = p(xtgt)
+    xres, yres = p.linspace(20)
+    assert_almost_equal(xres, xtgt)
+    assert_almost_equal(yres, ytgt)
+    # check specified domain
+    xtgt = np.linspace(0, 2, 20)
+    ytgt = p(xtgt)
+    xres, yres = p.linspace(20, domain=[0, 2])
+    assert_almost_equal(xres, xtgt)
+    assert_almost_equal(yres, ytgt)
+
+
+def check_pow(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    tgt = Poly([1], domain=d, window=w)
+    tst = Poly([1, 2, 3], domain=d, window=w)
+    for i in range(5):
+        assert_poly_almost_equal(tst**i, tgt)
+        tgt = tgt * tst
+    # default domain and window
+    tgt = Poly([1])
+    tst = Poly([1, 2, 3])
+    for i in range(5):
+        assert_poly_almost_equal(tst**i, tgt)
+        tgt = tgt * tst
+    # check error for invalid powers
+    assert_raises(ValueError, op.pow, tgt, 1.5)
+    assert_raises(ValueError, op.pow, tgt, -1)
+
+
+def check_call(Poly):
+    P = Polynomial
+    d = Poly.domain
+    x = np.linspace(d[0], d[1], 11)
+
+    # Check defaults
+    p = Poly.cast(P([1, 2, 3]))
+    tgt = 1 + x*(2 + 3*x)
+    res = p(x)
+    assert_almost_equal(res, tgt)
+
+
+def check_cutdeg(Poly):
+    p = Poly([1, 2, 3])
+    assert_raises(ValueError, p.cutdeg, .5)
+    assert_raises(ValueError, p.cutdeg, -1)
+    assert_equal(len(p.cutdeg(3)), 3)
+    assert_equal(len(p.cutdeg(2)), 3)
+    assert_equal(len(p.cutdeg(1)), 2)
+    assert_equal(len(p.cutdeg(0)), 1)
+
+
+def check_truncate(Poly):
+    p = Poly([1, 2, 3])
+    assert_raises(ValueError, p.truncate, .5)
+    assert_raises(ValueError, p.truncate, 0)
+    assert_equal(len(p.truncate(4)), 3)
+    assert_equal(len(p.truncate(3)), 3)
+    assert_equal(len(p.truncate(2)), 2)
+    assert_equal(len(p.truncate(1)), 1)
+
+
+def check_trim(Poly):
+    c = [1, 1e-6, 1e-12, 0]
+    p = Poly(c)
+    assert_equal(p.trim().coef, c[:3])
+    assert_equal(p.trim(1e-10).coef, c[:2])
+    assert_equal(p.trim(1e-5).coef, c[:1])
+
+
+def check_mapparms(Poly):
+    # check with defaults. Should be identity.
+    d = Poly.domain
+    w = Poly.window
+    p = Poly([1], domain=d, window=w)
+    assert_almost_equal([0, 1], p.mapparms())
+    #
+    w = 2*d + 1
+    p = Poly([1], domain=d, window=w)
+    assert_almost_equal([1, 2], p.mapparms())
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
new file mode 100644
index 0000000000..04da72b265
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
@@ -0,0 +1,547 @@
+"""Tests for hermite module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.hermite as herm
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+H0 = np.array([1])
+H1 = np.array([0, 2])
+H2 = np.array([-2, 0, 4])
+H3 = np.array([0, -12, 0, 8])
+H4 = np.array([12, 0, -48, 0, 16])
+H5 = np.array([0, 120, 0, -160, 0, 32])
+H6 = np.array([-120, 0, 720, 0, -480, 0, 64])
+H7 = np.array([0, -1680, 0, 3360, 0, -1344, 0, 128])
+H8 = np.array([1680, 0, -13440, 0, 13440, 0, -3584, 0, 256])
+H9 = np.array([0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512])
+
+Hlist = [H0, H1, H2, H3, H4, H5, H6, H7, H8, H9]
+
+
+def trim(x):
+    return herm.hermtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_hermdomain(self):
+        assert_equal(herm.hermdomain, [-1, 1])
+
+    def test_hermzero(self):
+        assert_equal(herm.hermzero, [0])
+
+    def test_hermone(self):
+        assert_equal(herm.hermone, [1])
+
+    def test_hermx(self):
+        assert_equal(herm.hermx, [0, .5])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_hermadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = herm.hermadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = herm.hermsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermmulx(self):
+        assert_equal(herm.hermmulx([0]), [0])
+        assert_equal(herm.hermmulx([1]), [0, .5])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i, 0, .5]
+            assert_equal(herm.hermmulx(ser), tgt)
+
+    def test_hermmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = herm.hermval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = herm.hermval(self.x, pol2)
+                pol3 = herm.hermmul(pol1, pol2)
+                val3 = herm.hermval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_hermdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = herm.hermadd(ci, cj)
+                quo, rem = herm.hermdiv(tgt, ci)
+                res = herm.hermadd(herm.hermmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2.5, 1., .75])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_hermval(self):
+        #check empty input
+        assert_equal(herm.hermval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Hlist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = herm.hermval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(herm.hermval(x, [1]).shape, dims)
+            assert_equal(herm.hermval(x, [1, 0]).shape, dims)
+            assert_equal(herm.hermval(x, [1, 0, 0]).shape, dims)
+
+    def test_hermval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herm.hermval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = herm.hermval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herm.hermval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = herm.hermval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermgrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = herm.hermgrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermgrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_hermgrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = herm.hermgrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermgrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_hermint(self):
+        # check exceptions
+        assert_raises(ValueError, herm.hermint, [0], .5)
+        assert_raises(ValueError, herm.hermint, [0], -1)
+        assert_raises(ValueError, herm.hermint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = herm.hermint([0], m=i, k=k)
+            assert_almost_equal(res, [0, .5])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i])
+            res = herm.herm2poly(hermint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(herm.hermval(-1, hermint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i], scl=2)
+            res = herm.herm2poly(hermint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1)
+                res = herm.hermint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k])
+                res = herm.hermint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k], lbnd=-1)
+                res = herm.hermint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k], scl=2)
+                res = herm.hermint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herm.hermint(c) for c in c2d.T]).T
+        res = herm.hermint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermint(c) for c in c2d])
+        res = herm.hermint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermint(c, k=3) for c in c2d])
+        res = herm.hermint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_hermder(self):
+        # check exceptions
+        assert_raises(ValueError, herm.hermder, [0], .5)
+        assert_raises(ValueError, herm.hermder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = herm.hermder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herm.hermder(herm.hermint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herm.hermder(herm.hermint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herm.hermder(c) for c in c2d.T]).T
+        res = herm.hermder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermder(c) for c in c2d])
+        res = herm.hermder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_hermvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = herm.hermvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = herm.hermvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+    def test_hermvander2d(self):
+        # also tests hermval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = herm.hermvander2d(x1, x2, [1, 2])
+        tgt = herm.hermval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herm.hermvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_hermvander3d(self):
+        # also tests hermval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = herm.hermvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = herm.hermval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herm.hermvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_hermfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, herm.hermfit, [1], [1], -1)
+        assert_raises(TypeError, herm.hermfit, [[1]], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, herm.hermfit, [1, 2], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [1, 2], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, herm.hermfit, [1], [1], [-1,])
+        assert_raises(ValueError, herm.hermfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, herm.hermfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = herm.hermfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herm.hermval(x, coef3), y)
+        coef3 = herm.hermfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herm.hermval(x, coef3), y)
+        #
+        coef4 = herm.hermfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        coef4 = herm.hermfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = herm.hermfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        #
+        coef2d = herm.hermfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = herm.hermfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = herm.hermfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = herm.hermfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(herm.hermfit(x, x, 1), [0, .5])
+        assert_almost_equal(herm.hermfit(x, x, [0, 1]), [0, .5])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = herm.hermfit(x, y, 4)
+        assert_almost_equal(herm.hermval(x, coef1), y)
+        coef2 = herm.hermfit(x, y, [0, 2, 4])
+        assert_almost_equal(herm.hermval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, herm.hermcompanion, [])
+        assert_raises(ValueError, herm.hermcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(herm.hermcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(herm.hermcompanion([1, 2])[0, 0] == -.25)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = herm.hermgauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = herm.hermvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.sqrt(np.pi)
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_hermfromroots(self):
+        res = herm.hermfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = herm.hermfromroots(roots)
+            res = herm.hermval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(herm.herm2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_hermroots(self):
+        assert_almost_equal(herm.hermroots([1]), [])
+        assert_almost_equal(herm.hermroots([1, 1]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = herm.hermroots(herm.hermfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, herm.hermtrim, coef, -1)
+
+        # Test results
+        assert_equal(herm.hermtrim(coef), coef[:-1])
+        assert_equal(herm.hermtrim(coef, 1), coef[:-3])
+        assert_equal(herm.hermtrim(coef, 2), [0])
+
+    def test_hermline(self):
+        assert_equal(herm.hermline(3, 4), [3, 2])
+
+    def test_herm2poly(self):
+        for i in range(10):
+            assert_almost_equal(herm.herm2poly([0]*i + [1]), Hlist[i])
+
+    def test_poly2herm(self):
+        for i in range(10):
+            assert_almost_equal(herm.poly2herm(Hlist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-5, 5, 11)
+        tgt = np.exp(-x**2)
+        res = herm.hermweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
new file mode 100644
index 0000000000..1162502dc5
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
@@ -0,0 +1,548 @@
+"""Tests for hermite_e module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.hermite_e as herme
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+He0 = np.array([1])
+He1 = np.array([0, 1])
+He2 = np.array([-1, 0, 1])
+He3 = np.array([0, -3, 0, 1])
+He4 = np.array([3, 0, -6, 0, 1])
+He5 = np.array([0, 15, 0, -10, 0, 1])
+He6 = np.array([-15, 0, 45, 0, -15, 0, 1])
+He7 = np.array([0, -105, 0, 105, 0, -21, 0, 1])
+He8 = np.array([105, 0, -420, 0, 210, 0, -28, 0, 1])
+He9 = np.array([0, 945, 0, -1260, 0, 378, 0, -36, 0, 1])
+
+Helist = [He0, He1, He2, He3, He4, He5, He6, He7, He8, He9]
+
+
+def trim(x):
+    return herme.hermetrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_hermedomain(self):
+        assert_equal(herme.hermedomain, [-1, 1])
+
+    def test_hermezero(self):
+        assert_equal(herme.hermezero, [0])
+
+    def test_hermeone(self):
+        assert_equal(herme.hermeone, [1])
+
+    def test_hermex(self):
+        assert_equal(herme.hermex, [0, 1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_hermeadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = herme.hermeadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermesub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = herme.hermesub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermemulx(self):
+        assert_equal(herme.hermemulx([0]), [0])
+        assert_equal(herme.hermemulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i, 0, 1]
+            assert_equal(herme.hermemulx(ser), tgt)
+
+    def test_hermemul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = herme.hermeval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = herme.hermeval(self.x, pol2)
+                pol3 = herme.hermemul(pol1, pol2)
+                val3 = herme.hermeval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_hermediv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = herme.hermeadd(ci, cj)
+                quo, rem = herme.hermediv(tgt, ci)
+                res = herme.hermeadd(herme.hermemul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([4., 2., 3.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_hermeval(self):
+        #check empty input
+        assert_equal(herme.hermeval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Helist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = herme.hermeval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(herme.hermeval(x, [1]).shape, dims)
+            assert_equal(herme.hermeval(x, [1, 0]).shape, dims)
+            assert_equal(herme.hermeval(x, [1, 0, 0]).shape, dims)
+
+    def test_hermeval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herme.hermeval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = herme.hermeval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermeval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermeval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herme.hermeval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = herme.hermeval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermeval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermegrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = herme.hermegrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermegrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_hermegrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = herme.hermegrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermegrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_hermeint(self):
+        # check exceptions
+        assert_raises(ValueError, herme.hermeint, [0], .5)
+        assert_raises(ValueError, herme.hermeint, [0], -1)
+        assert_raises(ValueError, herme.hermeint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = herme.hermeint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i])
+            res = herme.herme2poly(hermeint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(herme.hermeval(-1, hermeint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i], scl=2)
+            res = herme.herme2poly(hermeint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1)
+                res = herme.hermeint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k])
+                res = herme.hermeint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k], lbnd=-1)
+                res = herme.hermeint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k], scl=2)
+                res = herme.hermeint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermeint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herme.hermeint(c) for c in c2d.T]).T
+        res = herme.hermeint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeint(c) for c in c2d])
+        res = herme.hermeint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeint(c, k=3) for c in c2d])
+        res = herme.hermeint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_hermeder(self):
+        # check exceptions
+        assert_raises(ValueError, herme.hermeder, [0], .5)
+        assert_raises(ValueError, herme.hermeder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = herme.hermeder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herme.hermeder(herme.hermeint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herme.hermeder(
+                    herme.hermeint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermeder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herme.hermeder(c) for c in c2d.T]).T
+        res = herme.hermeder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeder(c) for c in c2d])
+        res = herme.hermeder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_hermevander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = herme.hermevander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = herme.hermevander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+    def test_hermevander2d(self):
+        # also tests hermeval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = herme.hermevander2d(x1, x2, [1, 2])
+        tgt = herme.hermeval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herme.hermevander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_hermevander3d(self):
+        # also tests hermeval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = herme.hermevander3d(x1, x2, x3, [1, 2, 3])
+        tgt = herme.hermeval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herme.hermevander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_hermefit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, herme.hermefit, [1], [1], -1)
+        assert_raises(TypeError, herme.hermefit, [[1]], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [[[1]]], 0)
+        assert_raises(TypeError, herme.hermefit, [1, 2], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [1, 2], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, herme.hermefit, [1], [1], [-1,])
+        assert_raises(ValueError, herme.hermefit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, herme.hermefit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = herme.hermefit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herme.hermeval(x, coef3), y)
+        coef3 = herme.hermefit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herme.hermeval(x, coef3), y)
+        #
+        coef4 = herme.hermefit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        coef4 = herme.hermefit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = herme.hermefit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        #
+        coef2d = herme.hermefit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = herme.hermefit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = herme.hermefit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = herme.hermefit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(herme.hermefit(x, x, 1), [0, 1])
+        assert_almost_equal(herme.hermefit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = herme.hermefit(x, y, 4)
+        assert_almost_equal(herme.hermeval(x, coef1), y)
+        coef2 = herme.hermefit(x, y, [0, 2, 4])
+        assert_almost_equal(herme.hermeval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, herme.hermecompanion, [])
+        assert_raises(ValueError, herme.hermecompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(herme.hermecompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(herme.hermecompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = herme.hermegauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = herme.hermevander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.sqrt(2*np.pi)
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_hermefromroots(self):
+        res = herme.hermefromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = herme.hermefromroots(roots)
+            res = herme.hermeval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(herme.herme2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_hermeroots(self):
+        assert_almost_equal(herme.hermeroots([1]), [])
+        assert_almost_equal(herme.hermeroots([1, 1]), [-1])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = herme.hermeroots(herme.hermefromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermetrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, herme.hermetrim, coef, -1)
+
+        # Test results
+        assert_equal(herme.hermetrim(coef), coef[:-1])
+        assert_equal(herme.hermetrim(coef, 1), coef[:-3])
+        assert_equal(herme.hermetrim(coef, 2), [0])
+
+    def test_hermeline(self):
+        assert_equal(herme.hermeline(3, 4), [3, 4])
+
+    def test_herme2poly(self):
+        for i in range(10):
+            assert_almost_equal(herme.herme2poly([0]*i + [1]), Helist[i])
+
+    def test_poly2herme(self):
+        for i in range(10):
+            assert_almost_equal(herme.poly2herme(Helist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-5, 5, 11)
+        tgt = np.exp(-.5*x**2)
+        res = herme.hermeweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
new file mode 100644
index 0000000000..c254760888
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
@@ -0,0 +1,529 @@
+"""Tests for laguerre module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.laguerre as lag
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+L0 = np.array([1])/1
+L1 = np.array([1, -1])/1
+L2 = np.array([2, -4, 1])/2
+L3 = np.array([6, -18, 9, -1])/6
+L4 = np.array([24, -96, 72, -16, 1])/24
+L5 = np.array([120, -600, 600, -200, 25, -1])/120
+L6 = np.array([720, -4320, 5400, -2400, 450, -36, 1])/720
+
+Llist = [L0, L1, L2, L3, L4, L5, L6]
+
+
+def trim(x):
+    return lag.lagtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_lagdomain(self):
+        assert_equal(lag.lagdomain, [0, 1])
+
+    def test_lagzero(self):
+        assert_equal(lag.lagzero, [0])
+
+    def test_lagone(self):
+        assert_equal(lag.lagone, [1])
+
+    def test_lagx(self):
+        assert_equal(lag.lagx, [1, -1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_lagadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = lag.lagadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_lagsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = lag.lagsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_lagmulx(self):
+        assert_equal(lag.lagmulx([0]), [0])
+        assert_equal(lag.lagmulx([1]), [1, -1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [-i, 2*i + 1, -(i + 1)]
+            assert_almost_equal(lag.lagmulx(ser), tgt)
+
+    def test_lagmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = lag.lagval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = lag.lagval(self.x, pol2)
+                pol3 = lag.lagmul(pol1, pol2)
+                val3 = lag.lagval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_lagdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = lag.lagadd(ci, cj)
+                quo, rem = lag.lagdiv(tgt, ci)
+                res = lag.lagadd(lag.lagmul(quo, ci), rem)
+                assert_almost_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([9., -14., 6.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_lagval(self):
+        #check empty input
+        assert_equal(lag.lagval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Llist]
+        for i in range(7):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = lag.lagval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(lag.lagval(x, [1]).shape, dims)
+            assert_equal(lag.lagval(x, [1, 0]).shape, dims)
+            assert_equal(lag.lagval(x, [1, 0, 0]).shape, dims)
+
+    def test_lagval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, lag.lagval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = lag.lagval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.lagval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_lagval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, lag.lagval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = lag.lagval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.lagval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_laggrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = lag.laggrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.laggrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_laggrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = lag.laggrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.laggrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_lagint(self):
+        # check exceptions
+        assert_raises(ValueError, lag.lagint, [0], .5)
+        assert_raises(ValueError, lag.lagint, [0], -1)
+        assert_raises(ValueError, lag.lagint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = lag.lagint([0], m=i, k=k)
+            assert_almost_equal(res, [1, -1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i])
+            res = lag.lag2poly(lagint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(lag.lagval(-1, lagint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i], scl=2)
+            res = lag.lag2poly(lagint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1)
+                res = lag.lagint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k])
+                res = lag.lagint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k], lbnd=-1)
+                res = lag.lagint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k], scl=2)
+                res = lag.lagint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([lag.lagint(c) for c in c2d.T]).T
+        res = lag.lagint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagint(c) for c in c2d])
+        res = lag.lagint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagint(c, k=3) for c in c2d])
+        res = lag.lagint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_lagder(self):
+        # check exceptions
+        assert_raises(ValueError, lag.lagder, [0], .5)
+        assert_raises(ValueError, lag.lagder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = lag.lagder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = lag.lagder(lag.lagint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = lag.lagder(lag.lagint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([lag.lagder(c) for c in c2d.T]).T
+        res = lag.lagder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagder(c) for c in c2d])
+        res = lag.lagder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_lagvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = lag.lagvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = lag.lagvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+    def test_lagvander2d(self):
+        # also tests lagval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = lag.lagvander2d(x1, x2, [1, 2])
+        tgt = lag.lagval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = lag.lagvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_lagvander3d(self):
+        # also tests lagval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = lag.lagvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = lag.lagval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = lag.lagvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_lagfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        # Test exceptions
+        assert_raises(ValueError, lag.lagfit, [1], [1], -1)
+        assert_raises(TypeError, lag.lagfit, [[1]], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, lag.lagfit, [1, 2], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [1, 2], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, lag.lagfit, [1], [1], [-1,])
+        assert_raises(ValueError, lag.lagfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, lag.lagfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = lag.lagfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(lag.lagval(x, coef3), y)
+        coef3 = lag.lagfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(lag.lagval(x, coef3), y)
+        #
+        coef4 = lag.lagfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(lag.lagval(x, coef4), y)
+        coef4 = lag.lagfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(lag.lagval(x, coef4), y)
+        #
+        coef2d = lag.lagfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = lag.lagfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = lag.lagfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = lag.lagfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(lag.lagfit(x, x, 1), [1, -1])
+        assert_almost_equal(lag.lagfit(x, x, [0, 1]), [1, -1])
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, lag.lagcompanion, [])
+        assert_raises(ValueError, lag.lagcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(lag.lagcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(lag.lagcompanion([1, 2])[0, 0] == 1.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = lag.laggauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = lag.lagvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = 1.0
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_lagfromroots(self):
+        res = lag.lagfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = lag.lagfromroots(roots)
+            res = lag.lagval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(lag.lag2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_lagroots(self):
+        assert_almost_equal(lag.lagroots([1]), [])
+        assert_almost_equal(lag.lagroots([0, 1]), [1])
+        for i in range(2, 5):
+            tgt = np.linspace(0, 3, i)
+            res = lag.lagroots(lag.lagfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, lag.lagtrim, coef, -1)
+
+        # Test results
+        assert_equal(lag.lagtrim(coef), coef[:-1])
+        assert_equal(lag.lagtrim(coef, 1), coef[:-3])
+        assert_equal(lag.lagtrim(coef, 2), [0])
+
+    def test_lagline(self):
+        assert_equal(lag.lagline(3, 4), [7, -4])
+
+    def test_lag2poly(self):
+        for i in range(7):
+            assert_almost_equal(lag.lag2poly([0]*i + [1]), Llist[i])
+
+    def test_poly2lag(self):
+        for i in range(7):
+            assert_almost_equal(lag.poly2lag(Llist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(0, 10, 11)
+        tgt = np.exp(-x)
+        res = lag.lagweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
new file mode 100644
index 0000000000..9c259d14c4
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
@@ -0,0 +1,548 @@
+"""Tests for legendre module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.legendre as leg
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+L0 = np.array([1])
+L1 = np.array([0, 1])
+L2 = np.array([-1, 0, 3])/2
+L3 = np.array([0, -3, 0, 5])/2
+L4 = np.array([3, 0, -30, 0, 35])/8
+L5 = np.array([0, 15, 0, -70, 0, 63])/8
+L6 = np.array([-5, 0, 105, 0, -315, 0, 231])/16
+L7 = np.array([0, -35, 0, 315, 0, -693, 0, 429])/16
+L8 = np.array([35, 0, -1260, 0, 6930, 0, -12012, 0, 6435])/128
+L9 = np.array([0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155])/128
+
+Llist = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9]
+
+
+def trim(x):
+    return leg.legtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_legdomain(self):
+        assert_equal(leg.legdomain, [-1, 1])
+
+    def test_legzero(self):
+        assert_equal(leg.legzero, [0])
+
+    def test_legone(self):
+        assert_equal(leg.legone, [1])
+
+    def test_legx(self):
+        assert_equal(leg.legx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-1, 1, 100)
+
+    def test_legadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = leg.legadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_legsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = leg.legsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_legmulx(self):
+        assert_equal(leg.legmulx([0]), [0])
+        assert_equal(leg.legmulx([1]), [0, 1])
+        for i in range(1, 5):
+            tmp = 2*i + 1
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i/tmp, 0, (i + 1)/tmp]
+            assert_equal(leg.legmulx(ser), tgt)
+
+    def test_legmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = leg.legval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = leg.legval(self.x, pol2)
+                pol3 = leg.legmul(pol1, pol2)
+                val3 = leg.legval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_legdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = leg.legadd(ci, cj)
+                quo, rem = leg.legdiv(tgt, ci)
+                res = leg.legadd(leg.legmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2., 2., 2.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_legval(self):
+        #check empty input
+        assert_equal(leg.legval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Llist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = leg.legval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(leg.legval(x, [1]).shape, dims)
+            assert_equal(leg.legval(x, [1, 0]).shape, dims)
+            assert_equal(leg.legval(x, [1, 0, 0]).shape, dims)
+
+    def test_legval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, leg.legval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = leg.legval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.legval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_legval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, leg.legval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = leg.legval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.legval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_leggrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = leg.leggrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.leggrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_leggrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = leg.leggrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.leggrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_legint(self):
+        # check exceptions
+        assert_raises(ValueError, leg.legint, [0], .5)
+        assert_raises(ValueError, leg.legint, [0], -1)
+        assert_raises(ValueError, leg.legint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = leg.legint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i])
+            res = leg.leg2poly(legint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(leg.legval(-1, legint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i], scl=2)
+            res = leg.leg2poly(legint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1)
+                res = leg.legint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k])
+                res = leg.legint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k], lbnd=-1)
+                res = leg.legint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k], scl=2)
+                res = leg.legint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([leg.legint(c) for c in c2d.T]).T
+        res = leg.legint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legint(c) for c in c2d])
+        res = leg.legint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legint(c, k=3) for c in c2d])
+        res = leg.legint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_legder(self):
+        # check exceptions
+        assert_raises(ValueError, leg.legder, [0], .5)
+        assert_raises(ValueError, leg.legder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = leg.legder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = leg.legder(leg.legint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([leg.legder(c) for c in c2d.T]).T
+        res = leg.legder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legder(c) for c in c2d])
+        res = leg.legder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_legvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = leg.legvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = leg.legvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+    def test_legvander2d(self):
+        # also tests polyval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = leg.legvander2d(x1, x2, [1, 2])
+        tgt = leg.legval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = leg.legvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_legvander3d(self):
+        # also tests polyval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = leg.legvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = leg.legval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = leg.legvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_legfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, leg.legfit, [1], [1], -1)
+        assert_raises(TypeError, leg.legfit, [[1]], [1], 0)
+        assert_raises(TypeError, leg.legfit, [], [1], 0)
+        assert_raises(TypeError, leg.legfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, leg.legfit, [1, 2], [1], 0)
+        assert_raises(TypeError, leg.legfit, [1], [1, 2], 0)
+        assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, leg.legfit, [1], [1], [-1,])
+        assert_raises(ValueError, leg.legfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, leg.legfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = leg.legfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(leg.legval(x, coef3), y)
+        coef3 = leg.legfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(leg.legval(x, coef3), y)
+        #
+        coef4 = leg.legfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        coef4 = leg.legfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = leg.legfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        #
+        coef2d = leg.legfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = leg.legfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = leg.legfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = leg.legfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = leg.legfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = leg.legfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(leg.legfit(x, x, 1), [0, 1])
+        assert_almost_equal(leg.legfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = leg.legfit(x, y, 4)
+        assert_almost_equal(leg.legval(x, coef1), y)
+        coef2 = leg.legfit(x, y, [0, 2, 4])
+        assert_almost_equal(leg.legval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, leg.legcompanion, [])
+        assert_raises(ValueError, leg.legcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(leg.legcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(leg.legcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = leg.leggauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = leg.legvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = 2.0
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_legfromroots(self):
+        res = leg.legfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = leg.legfromroots(roots)
+            res = leg.legval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(leg.leg2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_legroots(self):
+        assert_almost_equal(leg.legroots([1]), [])
+        assert_almost_equal(leg.legroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = leg.legroots(leg.legfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, leg.legtrim, coef, -1)
+
+        # Test results
+        assert_equal(leg.legtrim(coef), coef[:-1])
+        assert_equal(leg.legtrim(coef, 1), coef[:-3])
+        assert_equal(leg.legtrim(coef, 2), [0])
+
+    def test_legline(self):
+        assert_equal(leg.legline(3, 4), [3, 4])
+
+    def test_leg2poly(self):
+        for i in range(10):
+            assert_almost_equal(leg.leg2poly([0]*i + [1]), Llist[i])
+
+    def test_poly2leg(self):
+        for i in range(10):
+            assert_almost_equal(leg.poly2leg(Llist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-1, 1, 11)
+        tgt = 1.
+        res = leg.legweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
new file mode 100644
index 0000000000..00a52ebce8
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
@@ -0,0 +1,504 @@
+"""Tests for polynomial module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.polynomial as poly
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+def trim(x):
+    return poly.polytrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestConstants(TestCase):
+
+    def test_polydomain(self):
+        assert_equal(poly.polydomain, [-1, 1])
+
+    def test_polyzero(self):
+        assert_equal(poly.polyzero, [0])
+
+    def test_polyone(self):
+        assert_equal(poly.polyone, [1])
+
+    def test_polyx(self):
+        assert_equal(poly.polyx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+
+    def test_polyadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = poly.polyadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polysub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = poly.polysub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polymulx(self):
+        assert_equal(poly.polymulx([0]), [0])
+        assert_equal(poly.polymulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i + 1) + [1]
+            assert_equal(poly.polymulx(ser), tgt)
+
+    def test_polymul(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(i + j + 1)
+                tgt[i + j] += 1
+                res = poly.polymul([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polydiv(self):
+        # check zero division
+        assert_raises(ZeroDivisionError, poly.polydiv, [1], [0])
+
+        # check scalar division
+        quo, rem = poly.polydiv([2], [2])
+        assert_equal((quo, rem), (1, 0))
+        quo, rem = poly.polydiv([2, 2], [2])
+        assert_equal((quo, rem), ((1, 1), 0))
+
+        # check rest.
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1, 2]
+                cj = [0]*j + [1, 2]
+                tgt = poly.polyadd(ci, cj)
+                quo, rem = poly.polydiv(tgt, ci)
+                res = poly.polyadd(poly.polymul(quo, ci), rem)
+                assert_equal(res, tgt, err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([1., 2., 3.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = poly.polyval(x, [1., 2., 3.])
+
+    def test_polyval(self):
+        #check empty input
+        assert_equal(poly.polyval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [x**i for i in range(5)]
+        for i in range(5):
+            tgt = y[i]
+            res = poly.polyval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt)
+        tgt = x*(x**2 - 1)
+        res = poly.polyval(x, [0, -1, 0, 1])
+        assert_almost_equal(res, tgt)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(poly.polyval(x, [1]).shape, dims)
+            assert_equal(poly.polyval(x, [1, 0]).shape, dims)
+            assert_equal(poly.polyval(x, [1, 0, 0]).shape, dims)
+
+    def test_polyval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, poly.polyval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = poly.polyval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polyval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_polyval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, poly.polyval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = poly.polyval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polyval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_polygrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = poly.polygrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polygrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_polygrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = poly.polygrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polygrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_polyint(self):
+        # check exceptions
+        assert_raises(ValueError, poly.polyint, [0], .5)
+        assert_raises(ValueError, poly.polyint, [0], -1)
+        assert_raises(ValueError, poly.polyint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = poly.polyint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            res = poly.polyint(pol, m=1, k=[i])
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            res = poly.polyint(pol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(poly.polyval(-1, res), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            res = poly.polyint(pol, m=1, k=[i], scl=2)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1)
+                res = poly.polyint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k])
+                res = poly.polyint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k], lbnd=-1)
+                res = poly.polyint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k], scl=2)
+                res = poly.polyint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([poly.polyint(c) for c in c2d.T]).T
+        res = poly.polyint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyint(c) for c in c2d])
+        res = poly.polyint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyint(c, k=3) for c in c2d])
+        res = poly.polyint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_polyder(self):
+        # check exceptions
+        assert_raises(ValueError, poly.polyder, [0], .5)
+        assert_raises(ValueError, poly.polyder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = poly.polyder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = poly.polyder(poly.polyint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = poly.polyder(poly.polyint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([poly.polyder(c) for c in c2d.T]).T
+        res = poly.polyder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyder(c) for c in c2d])
+        res = poly.polyder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_polyvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = poly.polyvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = poly.polyvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+    def test_polyvander2d(self):
+        # also tests polyval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = poly.polyvander2d(x1, x2, [1, 2])
+        tgt = poly.polyval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = poly.polyvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_polyvander3d(self):
+        # also tests polyval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = poly.polyvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = poly.polyval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, poly.polycompanion, [])
+        assert_raises(ValueError, poly.polycompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(poly.polycompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(poly.polycompanion([1, 2])[0, 0] == -.5)
+
+
+class TestMisc(TestCase):
+
+    def test_polyfromroots(self):
+        res = poly.polyfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            tgt = Tlist[i]
+            res = poly.polyfromroots(roots)*2**(i-1)
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyroots(self):
+        assert_almost_equal(poly.polyroots([1]), [])
+        assert_almost_equal(poly.polyroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = poly.polyroots(poly.polyfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, poly.polyfit, [1], [1], -1)
+        assert_raises(TypeError, poly.polyfit, [[1]], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, poly.polyfit, [1, 2], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [1, 2], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, poly.polyfit, [1], [1], [-1,])
+        assert_raises(ValueError, poly.polyfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, poly.polyfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = poly.polyfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(poly.polyval(x, coef3), y)
+        coef3 = poly.polyfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(poly.polyval(x, coef3), y)
+        #
+        coef4 = poly.polyfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(poly.polyval(x, coef4), y)
+        coef4 = poly.polyfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(poly.polyval(x, coef4), y)
+        #
+        coef2d = poly.polyfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = poly.polyfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        yw[0::2] = 0
+        wcoef3 = poly.polyfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = poly.polyfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(poly.polyfit(x, x, 1), [0, 1])
+        assert_almost_equal(poly.polyfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Polyendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = poly.polyfit(x, y, 4)
+        assert_almost_equal(poly.polyval(x, coef1), y)
+        coef2 = poly.polyfit(x, y, [0, 2, 4])
+        assert_almost_equal(poly.polyval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+    def test_polytrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, poly.polytrim, coef, -1)
+
+        # Test results
+        assert_equal(poly.polytrim(coef), coef[:-1])
+        assert_equal(poly.polytrim(coef, 1), coef[:-3])
+        assert_equal(poly.polytrim(coef, 2), [0])
+
+    def test_polyline(self):
+        assert_equal(poly.polyline(3, 4), [3, 4])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
new file mode 100644
index 0000000000..974e2e09a3
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
@@ -0,0 +1,109 @@
+"""Tests for polyutils module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.polyutils as pu
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+class TestMisc(TestCase):
+
+    def test_trimseq(self):
+        for i in range(5):
+            tgt = [1]
+            res = pu.trimseq([1] + [0]*5)
+            assert_equal(res, tgt)
+
+    def test_as_series(self):
+        # check exceptions
+        assert_raises(ValueError, pu.as_series, [[]])
+        assert_raises(ValueError, pu.as_series, [[[1, 2]]])
+        assert_raises(ValueError, pu.as_series, [[1], ['a']])
+        # check common types
+        types = ['i', 'd', 'O']
+        for i in range(len(types)):
+            for j in range(i):
+                ci = np.ones(1, types[i])
+                cj = np.ones(1, types[j])
+                [resi, resj] = pu.as_series([ci, cj])
+                assert_(resi.dtype.char == resj.dtype.char)
+                assert_(resj.dtype.char == types[i])
+
+    def test_trimcoef(self):
+        coef = [2, -1, 1, 0]
+        # Test exceptions
+        assert_raises(ValueError, pu.trimcoef, coef, -1)
+        # Test results
+        assert_equal(pu.trimcoef(coef), coef[:-1])
+        assert_equal(pu.trimcoef(coef, 1), coef[:-3])
+        assert_equal(pu.trimcoef(coef, 2), [0])
+
+
+class TestDomain(TestCase):
+
+    def test_getdomain(self):
+        # test for real values
+        x = [1, 10, 3, -1]
+        tgt = [-1, 10]
+        res = pu.getdomain(x)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        x = [1 + 1j, 1 - 1j, 0, 2]
+        tgt = [-1j, 2 + 1j]
+        res = pu.getdomain(x)
+        assert_almost_equal(res, tgt)
+
+    def test_mapdomain(self):
+        # test for real values
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = dom2
+        res = pu. mapdomain(dom1, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        dom1 = [0 - 1j, 2 + 1j]
+        dom2 = [-2, 2]
+        tgt = dom2
+        x = dom1
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for multidimensional arrays
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = np.array([dom2, dom2])
+        x = np.array([dom1, dom1])
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test that subtypes are preserved.
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        x = np.matrix([dom1, dom1])
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_(isinstance(res, np.matrix))
+
+    def test_mapparms(self):
+        # test for real values
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = [1, .5]
+        res = pu. mapparms(dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        dom1 = [0 - 1j, 2 + 1j]
+        dom2 = [-2, 2]
+        tgt = [-1 + 1j, 1 - 1j]
+        res = pu.mapparms(dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
new file mode 100644
index 0000000000..86cd257328
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
@@ -0,0 +1,74 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.polynomial as poly
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+class test_str(TestCase):
+    def test_polynomial_str(self):
+        res = str(poly.Polynomial([0, 1]))
+        tgt = 'poly([0., 1.])'
+        assert_(res, tgt)
+
+    def test_chebyshev_str(self):
+        res = str(poly.Chebyshev([0, 1]))
+        tgt = 'leg([0., 1.])'
+        assert_(res, tgt)
+
+    def test_legendre_str(self):
+        res = str(poly.Legendre([0, 1]))
+        tgt = 'leg([0., 1.])'
+        assert_(res, tgt)
+
+    def test_hermite_str(self):
+        res = str(poly.Hermite([0, 1]))
+        tgt = 'herm([0., 1.])'
+        assert_(res, tgt)
+
+    def test_hermiteE_str(self):
+        res = str(poly.HermiteE([0, 1]))
+        tgt = 'herme([0., 1.])'
+        assert_(res, tgt)
+
+    def test_laguerre_str(self):
+        res = str(poly.Laguerre([0, 1]))
+        tgt = 'lag([0., 1.])'
+        assert_(res, tgt)
+
+
+class test_repr(TestCase):
+    def test_polynomial_str(self):
+        res = repr(poly.Polynomial([0, 1]))
+        tgt = 'Polynomial([0., 1.])'
+        assert_(res, tgt)
+
+    def test_chebyshev_str(self):
+        res = repr(poly.Chebyshev([0, 1]))
+        tgt = 'Chebyshev([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_legendre_repr(self):
+        res = repr(poly.Legendre([0, 1]))
+        tgt = 'Legendre([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_hermite_repr(self):
+        res = repr(poly.Hermite([0, 1]))
+        tgt = 'Hermite([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_hermiteE_repr(self):
+        res = repr(poly.HermiteE([0, 1]))
+        tgt = 'HermiteE([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_laguerre_repr(self):
+        res = repr(poly.Laguerre([0, 1]))
+        tgt = 'Laguerre([0., 1.], [0., 1.], [0., 1.])'
+        assert_(res, tgt)
+
+
+#
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/__init__.py
new file mode 100644
index 0000000000..6c7d3140fe
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/__init__.py
@@ -0,0 +1,122 @@
+"""
+========================
+Random Number Generation
+========================
+
+==================== =========================================================
+Utility functions
+==============================================================================
+random               Uniformly distributed values of a given shape.
+bytes                Uniformly distributed random bytes.
+random_integers      Uniformly distributed integers in a given range.
+random_sample        Uniformly distributed floats in a given range.
+random               Alias for random_sample
+ranf                 Alias for random_sample
+sample               Alias for random_sample
+choice               Generate a weighted random sample from a given array-like
+permutation          Randomly permute a sequence / generate a random sequence.
+shuffle              Randomly permute a sequence in place.
+seed                 Seed the random number generator.
+==================== =========================================================
+
+==================== =========================================================
+Compatibility functions
+==============================================================================
+rand                 Uniformly distributed values.
+randn                Normally distributed values.
+ranf                 Uniformly distributed floating point numbers.
+randint              Uniformly distributed integers in a given range.
+==================== =========================================================
+
+==================== =========================================================
+Univariate distributions
+==============================================================================
+beta                 Beta distribution over ``[0, 1]``.
+binomial             Binomial distribution.
+chisquare            :math:`\\chi^2` distribution.
+exponential          Exponential distribution.
+f                    F (Fisher-Snedecor) distribution.
+gamma                Gamma distribution.
+geometric            Geometric distribution.
+gumbel               Gumbel distribution.
+hypergeometric       Hypergeometric distribution.
+laplace              Laplace distribution.
+logistic             Logistic distribution.
+lognormal            Log-normal distribution.
+logseries            Logarithmic series distribution.
+negative_binomial    Negative binomial distribution.
+noncentral_chisquare Non-central chi-square distribution.
+noncentral_f         Non-central F distribution.
+normal               Normal / Gaussian distribution.
+pareto               Pareto distribution.
+poisson              Poisson distribution.
+power                Power distribution.
+rayleigh             Rayleigh distribution.
+triangular           Triangular distribution.
+uniform              Uniform distribution.
+vonmises             Von Mises circular distribution.
+wald                 Wald (inverse Gaussian) distribution.
+weibull              Weibull distribution.
+zipf                 Zipf's distribution over ranked data.
+==================== =========================================================
+
+==================== =========================================================
+Multivariate distributions
+==============================================================================
+dirichlet            Multivariate generalization of Beta distribution.
+multinomial          Multivariate generalization of the binomial distribution.
+multivariate_normal  Multivariate generalization of the normal distribution.
+==================== =========================================================
+
+==================== =========================================================
+Standard distributions
+==============================================================================
+standard_cauchy      Standard Cauchy-Lorentz distribution.
+standard_exponential Standard exponential distribution.
+standard_gamma       Standard Gamma distribution.
+standard_normal      Standard normal distribution.
+standard_t           Standard Student's t-distribution.
+==================== =========================================================
+
+==================== =========================================================
+Internal functions
+==============================================================================
+get_state            Get tuple representing internal state of generator.
+set_state            Set state of generator.
+==================== =========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+# To get sub-modules
+from .info import __doc__, __all__
+
+
+with warnings.catch_warnings():
+    warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
+    from .mtrand import *
+
+# Some aliases:
+ranf = random = sample = random_sample
+__all__.extend(['ranf', 'random', 'sample'])
+
+def __RandomState_ctor():
+    """Return a RandomState instance.
+
+    This function exists solely to assist (un)pickling.
+
+    Note that the state of the RandomState returned here is irrelevant, as this function's
+    entire purpose is to return a newly allocated RandomState whose state pickle can set.
+    Consequently the RandomState returned by this function is a freshly allocated copy
+    with a seed=0.
+
+    See https://github.com/numpy/numpy/issues/4763 for a detailed discussion
+
+    """
+    return RandomState(seed=0)
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/info.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/info.py
new file mode 100644
index 0000000000..be9c8d9bd2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/info.py
@@ -0,0 +1,139 @@
+"""
+========================
+Random Number Generation
+========================
+
+==================== =========================================================
+Utility functions
+==============================================================================
+random_sample        Uniformly distributed floats over ``[0, 1)``.
+random               Alias for `random_sample`.
+bytes                Uniformly distributed random bytes.
+random_integers      Uniformly distributed integers in a given range.
+permutation          Randomly permute a sequence / generate a random sequence.
+shuffle              Randomly permute a sequence in place.
+seed                 Seed the random number generator.
+choice               Random sample from 1-D array.
+
+==================== =========================================================
+
+==================== =========================================================
+Compatibility functions
+==============================================================================
+rand                 Uniformly distributed values.
+randn                Normally distributed values.
+ranf                 Uniformly distributed floating point numbers.
+randint              Uniformly distributed integers in a given range.
+==================== =========================================================
+
+==================== =========================================================
+Univariate distributions
+==============================================================================
+beta                 Beta distribution over ``[0, 1]``.
+binomial             Binomial distribution.
+chisquare            :math:`\\chi^2` distribution.
+exponential          Exponential distribution.
+f                    F (Fisher-Snedecor) distribution.
+gamma                Gamma distribution.
+geometric            Geometric distribution.
+gumbel               Gumbel distribution.
+hypergeometric       Hypergeometric distribution.
+laplace              Laplace distribution.
+logistic             Logistic distribution.
+lognormal            Log-normal distribution.
+logseries            Logarithmic series distribution.
+negative_binomial    Negative binomial distribution.
+noncentral_chisquare Non-central chi-square distribution.
+noncentral_f         Non-central F distribution.
+normal               Normal / Gaussian distribution.
+pareto               Pareto distribution.
+poisson              Poisson distribution.
+power                Power distribution.
+rayleigh             Rayleigh distribution.
+triangular           Triangular distribution.
+uniform              Uniform distribution.
+vonmises             Von Mises circular distribution.
+wald                 Wald (inverse Gaussian) distribution.
+weibull              Weibull distribution.
+zipf                 Zipf's distribution over ranked data.
+==================== =========================================================
+
+==================== =========================================================
+Multivariate distributions
+==============================================================================
+dirichlet            Multivariate generalization of Beta distribution.
+multinomial          Multivariate generalization of the binomial distribution.
+multivariate_normal  Multivariate generalization of the normal distribution.
+==================== =========================================================
+
+==================== =========================================================
+Standard distributions
+==============================================================================
+standard_cauchy      Standard Cauchy-Lorentz distribution.
+standard_exponential Standard exponential distribution.
+standard_gamma       Standard Gamma distribution.
+standard_normal      Standard normal distribution.
+standard_t           Standard Student's t-distribution.
+==================== =========================================================
+
+==================== =========================================================
+Internal functions
+==============================================================================
+get_state            Get tuple representing internal state of generator.
+set_state            Set state of generator.
+==================== =========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
+
+__all__ = [
+    'beta',
+    'binomial',
+    'bytes',
+    'chisquare',
+    'choice',
+    'dirichlet',
+    'exponential',
+    'f',
+    'gamma',
+    'geometric',
+    'get_state',
+    'gumbel',
+    'hypergeometric',
+    'laplace',
+    'logistic',
+    'lognormal',
+    'logseries',
+    'multinomial',
+    'multivariate_normal',
+    'negative_binomial',
+    'noncentral_chisquare',
+    'noncentral_f',
+    'normal',
+    'pareto',
+    'permutation',
+    'poisson',
+    'power',
+    'rand',
+    'randint',
+    'randn',
+    'random_integers',
+    'random_sample',
+    'rayleigh',
+    'seed',
+    'set_state',
+    'shuffle',
+    'standard_cauchy',
+    'standard_exponential',
+    'standard_gamma',
+    'standard_normal',
+    'standard_t',
+    'triangular',
+    'uniform',
+    'vonmises',
+    'wald',
+    'weibull',
+    'zipf'
+]
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/mtrand.pyd b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/mtrand.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..1cb77041d623f4100418739ed64807696f6e34e6
GIT binary patch
literal 677888
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/randomkit.h b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/randomkit.h
new file mode 100644
index 0000000000..fcdd606a14
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/randomkit.h
@@ -0,0 +1,226 @@
+/* Random kit 1.3 */
+
+/*
+ * Copyright (c) 2003-2005, Jean-Sebastien Roy (js@jeannot.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* @(#) $Jeannot: randomkit.h,v 1.24 2005/07/21 22:14:09 js Exp $ */
+
+/*
+ * Typical use:
+ *
+ * {
+ *  rk_state state;
+ *  unsigned long seed = 1, random_value;
+ *
+ *  rk_seed(seed, &state); // Initialize the RNG
+ *  ...
+ *  random_value = rk_random(&state); // Generate random values in [0..RK_MAX]
+ * }
+ *
+ * Instead of rk_seed, you can use rk_randomseed which will get a random seed
+ * from /dev/urandom (or the clock, if /dev/urandom is unavailable):
+ *
+ * {
+ *  rk_state state;
+ *  unsigned long random_value;
+ *
+ *  rk_randomseed(&state); // Initialize the RNG with a random seed
+ *  ...
+ *  random_value = rk_random(&state); // Generate random values in [0..RK_MAX]
+ * }
+ */
+
+/*
+ * Useful macro:
+ *  RK_DEV_RANDOM: the device used for random seeding.
+ *                 defaults to "/dev/urandom"
+ */
+
+#ifndef _RANDOMKIT_
+#define _RANDOMKIT_
+
+#include <stddef.h>
+#include <numpy/npy_common.h>
+
+
+#define RK_STATE_LEN 624
+
+typedef struct rk_state_
+{
+    unsigned long key[RK_STATE_LEN];
+    int pos;
+    int has_gauss; /* !=0: gauss contains a gaussian deviate */
+    double gauss;
+
+    /* The rk_state structure has been extended to store the following
+     * information for the binomial generator. If the input values of n or p
+     * are different than nsave and psave, then the other parameters will be
+     * recomputed. RTK 2005-09-02 */
+
+    int has_binomial; /* !=0: following parameters initialized for
+                              binomial */
+    double psave;
+    long nsave;
+    double r;
+    double q;
+    double fm;
+    long m;
+    double p1;
+    double xm;
+    double xl;
+    double xr;
+    double c;
+    double laml;
+    double lamr;
+    double p2;
+    double p3;
+    double p4;
+
+}
+rk_state;
+
+typedef enum {
+    RK_NOERR = 0, /* no error */
+    RK_ENODEV = 1, /* no RK_DEV_RANDOM device */
+    RK_ERR_MAX = 2
+} rk_error;
+
+/* error strings */
+extern char *rk_strerror[RK_ERR_MAX];
+
+/* Maximum generated random value */
+#define RK_MAX 0xFFFFFFFFUL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Initialize the RNG state using the given seed.
+ */
+extern void rk_seed(unsigned long seed, rk_state *state);
+
+/*
+ * Initialize the RNG state using a random seed.
+ * Uses /dev/random or, when unavailable, the clock (see randomkit.c).
+ * Returns RK_NOERR when no errors occurs.
+ * Returns RK_ENODEV when the use of RK_DEV_RANDOM failed (for example because
+ * there is no such device). In this case, the RNG was initialized using the
+ * clock.
+ */
+extern rk_error rk_randomseed(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and RK_MAX inclusive
+ */
+extern unsigned long rk_random(rk_state *state);
+
+/*
+ * Returns a random long between 0 and LONG_MAX inclusive
+ */
+extern long rk_long(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and ULONG_MAX inclusive
+ */
+extern unsigned long rk_ulong(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and max inclusive.
+ */
+extern unsigned long rk_interval(unsigned long max, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint64 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint64(npy_uint64 off, npy_uint64 rng, npy_intp cnt,
+                             npy_uint64 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint32 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint32(npy_uint32 off, npy_uint32 rng, npy_intp cnt,
+                             npy_uint32 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint16 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint16(npy_uint16 off, npy_uint16 rng, npy_intp cnt,
+                             npy_uint16 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint8 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint8(npy_uint8 off, npy_uint8 rng, npy_intp cnt,
+                            npy_uint8 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_bool between off and off + rng
+ * inclusive. It is assumed tha npy_bool as the same size as npy_uint8.
+ */
+extern void rk_random_bool(npy_bool off, npy_bool rng, npy_intp cnt,
+                           npy_bool *out, rk_state *state);
+
+/*
+ * Returns a random double between 0.0 and 1.0, 1.0 excluded.
+ */
+extern double rk_double(rk_state *state);
+
+/*
+ * fill the buffer with size random bytes
+ */
+extern void rk_fill(void *buffer, size_t size, rk_state *state);
+
+/*
+ * fill the buffer with randombytes from the random device
+ * Returns RK_ENODEV if the device is unavailable, or RK_NOERR if it is
+ * On Unix, if strong is defined, RK_DEV_RANDOM is used. If not, RK_DEV_URANDOM
+ * is used instead. This parameter has no effect on Windows.
+ * Warning: on most unixes RK_DEV_RANDOM will wait for enough entropy to answer
+ * which can take a very long time on quiet systems.
+ */
+extern rk_error rk_devfill(void *buffer, size_t size, int strong);
+
+/*
+ * fill the buffer using rk_devfill if the random device is available and using
+ * rk_fill if is is not
+ * parameters have the same meaning as rk_fill and rk_devfill
+ * Returns RK_ENODEV if the device is unavailable, or RK_NOERR if it is
+ */
+extern rk_error rk_altfill(void *buffer, size_t size, int strong,
+                            rk_state *state);
+
+/*
+ * return a random gaussian deviate with variance unity and zero mean.
+ */
+extern double rk_gauss(rk_state *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RANDOMKIT_ */
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/setup.py
new file mode 100644
index 0000000000..9d905900cd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/setup.py
@@ -0,0 +1,61 @@
+from __future__ import division, print_function
+
+from os.path import join, split, dirname
+import os
+import sys
+from distutils.dep_util import newer
+from distutils.msvccompiler import get_build_version as get_msvc_build_version
+
+def needs_mingw_ftime_workaround():
+    # We need the mingw workaround for _ftime if the msvc runtime version is
+    # 7.1 or above and we build with mingw ...
+    # ... but we can't easily detect compiler version outside distutils command
+    # context, so we will need to detect in randomkit whether we build with gcc
+    msver = get_msvc_build_version()
+    if msver and msver >= 8:
+        return True
+
+    return False
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration, get_mathlibs
+    config = Configuration('random', parent_package, top_path)
+
+    def generate_libraries(ext, build_dir):
+        config_cmd = config.get_config_cmd()
+        libs = get_mathlibs()
+        if sys.platform == 'win32':
+            libs.append('Advapi32')
+        ext.libraries.extend(libs)
+        return None
+
+    # enable unix large file support on 32 bit systems
+    # (64 bit off_t, lseek -> lseek64 etc.)
+    defs = [('_FILE_OFFSET_BITS', '64'),
+            ('_LARGEFILE_SOURCE', '1'),
+            ('_LARGEFILE64_SOURCE', '1')]
+    if needs_mingw_ftime_workaround():
+        defs.append(("NPY_NEEDS_MINGW_TIME_WORKAROUND", None))
+
+    libs = []
+    # Configure mtrand
+    config.add_extension('mtrand',
+                         sources=[join('mtrand', x) for x in
+                                  ['mtrand.c', 'randomkit.c', 'initarray.c',
+                                   'distributions.c']]+[generate_libraries],
+                         libraries=libs,
+                         depends=[join('mtrand', '*.h'),
+                                  join('mtrand', '*.pyx'),
+                                  join('mtrand', '*.pxi'),],
+                         define_macros=defs,
+                         )
+
+    config.add_data_files(('.', join('mtrand', 'randomkit.h')))
+    config.add_data_dir('tests')
+
+    return config
+
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_random.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_random.py
new file mode 100644
index 0000000000..4ad94505cd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_random.py
@@ -0,0 +1,856 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+        TestCase, run_module_suite, assert_, assert_raises, assert_equal,
+        assert_warns)
+from numpy import random
+from numpy.compat import asbytes
+import sys
+import warnings
+
+
+
+class TestSeed(TestCase):
+    def test_scalar(self):
+        s = np.random.RandomState(0)
+        assert_equal(s.randint(1000), 684)
+        s = np.random.RandomState(4294967295)
+        assert_equal(s.randint(1000), 419)
+
+    def test_array(self):
+        s = np.random.RandomState(range(10))
+        assert_equal(s.randint(1000), 468)
+        s = np.random.RandomState(np.arange(10))
+        assert_equal(s.randint(1000), 468)
+        s = np.random.RandomState([0])
+        assert_equal(s.randint(1000), 973)
+        s = np.random.RandomState([4294967295])
+        assert_equal(s.randint(1000), 265)
+
+    def test_invalid_scalar(self):
+        # seed must be an unsigned 32 bit integer
+        assert_raises(TypeError, np.random.RandomState, -0.5)
+        assert_raises(ValueError, np.random.RandomState, -1)
+
+    def test_invalid_array(self):
+        # seed must be an unsigned 32 bit integer
+        assert_raises(TypeError, np.random.RandomState, [-0.5])
+        assert_raises(ValueError, np.random.RandomState, [-1])
+        assert_raises(ValueError, np.random.RandomState, [4294967296])
+        assert_raises(ValueError, np.random.RandomState, [1, 2, 4294967296])
+        assert_raises(ValueError, np.random.RandomState, [1, -2, 4294967296])
+
+
+class TestBinomial(TestCase):
+    def test_n_zero(self):
+        # Tests the corner case of n == 0 for the binomial distribution.
+        # binomial(0, p) should be zero for any p in [0, 1].
+        # This test addresses issue #3480.
+        zeros = np.zeros(2, dtype='int')
+        for p in [0, .5, 1]:
+            assert_(random.binomial(0, p) == 0)
+            np.testing.assert_array_equal(random.binomial(zeros, p), zeros)
+
+    def test_p_is_nan(self):
+        # Issue #4571.
+        assert_raises(ValueError, random.binomial, 1, np.nan)
+
+
+class TestMultinomial(TestCase):
+    def test_basic(self):
+        random.multinomial(100, [0.2, 0.8])
+
+    def test_zero_probability(self):
+        random.multinomial(100, [0.2, 0.8, 0.0, 0.0, 0.0])
+
+    def test_int_negative_interval(self):
+        assert_(-5 <= random.randint(-5, -1) < -1)
+        x = random.randint(-5, -1, 5)
+        assert_(np.all(-5 <= x))
+        assert_(np.all(x < -1))
+
+    def test_size(self):
+        # gh-3173
+        p = [0.5, 0.5]
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, [2, 2]).shape, (2, 2, 2))
+        assert_equal(np.random.multinomial(1, p, (2, 2)).shape, (2, 2, 2))
+        assert_equal(np.random.multinomial(1, p, np.array((2, 2))).shape,
+                     (2, 2, 2))
+
+        assert_raises(TypeError, np.random.multinomial, 1, p,
+                      np.float(1))
+
+
+class TestSetState(TestCase):
+    def setUp(self):
+        self.seed = 1234567890
+        self.prng = random.RandomState(self.seed)
+        self.state = self.prng.get_state()
+
+    def test_basic(self):
+        old = self.prng.tomaxint(16)
+        self.prng.set_state(self.state)
+        new = self.prng.tomaxint(16)
+        assert_(np.all(old == new))
+
+    def test_gaussian_reset(self):
+        # Make sure the cached every-other-Gaussian is reset.
+        old = self.prng.standard_normal(size=3)
+        self.prng.set_state(self.state)
+        new = self.prng.standard_normal(size=3)
+        assert_(np.all(old == new))
+
+    def test_gaussian_reset_in_media_res(self):
+        # When the state is saved with a cached Gaussian, make sure the
+        # cached Gaussian is restored.
+
+        self.prng.standard_normal()
+        state = self.prng.get_state()
+        old = self.prng.standard_normal(size=3)
+        self.prng.set_state(state)
+        new = self.prng.standard_normal(size=3)
+        assert_(np.all(old == new))
+
+    def test_backwards_compatibility(self):
+        # Make sure we can accept old state tuples that do not have the
+        # cached Gaussian value.
+        old_state = self.state[:-2]
+        x1 = self.prng.standard_normal(size=16)
+        self.prng.set_state(old_state)
+        x2 = self.prng.standard_normal(size=16)
+        self.prng.set_state(self.state)
+        x3 = self.prng.standard_normal(size=16)
+        assert_(np.all(x1 == x2))
+        assert_(np.all(x1 == x3))
+
+    def test_negative_binomial(self):
+        # Ensure that the negative binomial results take floating point
+        # arguments without truncation.
+        self.prng.negative_binomial(0.5, 0.5)
+
+
+class TestRandint(TestCase):
+
+    rfunc = np.random.randint
+
+    # valid integer/boolean types
+    itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16,
+             np.int32, np.uint32, np.int64, np.uint64]
+
+    def test_unsupported_type(self):
+        assert_raises(TypeError, self.rfunc, 1, dtype=np.float)
+
+    def test_bounds_checking(self):
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+            assert_raises(ValueError, self.rfunc, lbnd - 1, ubnd, dtype=dt)
+            assert_raises(ValueError, self.rfunc, lbnd, ubnd + 1, dtype=dt)
+            assert_raises(ValueError, self.rfunc, ubnd, lbnd, dtype=dt)
+            assert_raises(ValueError, self.rfunc, 1, 0, dtype=dt)
+
+    def test_rng_zero_and_extremes(self):
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+            tgt = ubnd - 1
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+            tgt = lbnd
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+            tgt = (lbnd + ubnd)//2
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+
+    def test_in_bounds_fuzz(self):
+        # Don't use fixed seed
+        np.random.seed()
+        for dt in self.itype[1:]:
+            for ubnd in [4, 8, 16]:
+                vals = self.rfunc(2, ubnd, size=2**16, dtype=dt)
+                assert_(vals.max() < ubnd)
+                assert_(vals.min() >= 2)
+        vals = self.rfunc(0, 2, size=2**16, dtype=np.bool)
+        assert_(vals.max() < 2)
+        assert_(vals.min() >= 0)
+
+    def test_repeatability(self):
+        import hashlib
+        # We use a md5 hash of generated sequences of 1000 samples
+        # in the range [0, 6) for all but np.bool, where the range
+        # is [0, 2). Hashes are for little endian numbers.
+        tgt = {'bool': '7dd3170d7aa461d201a65f8bcf3944b0',
+               'int16': '1b7741b80964bb190c50d541dca1cac1',
+               'int32': '4dc9fcc2b395577ebb51793e58ed1a05',
+               'int64': '17db902806f448331b5a758d7d2ee672',
+               'int8': '27dd30c4e08a797063dffac2490b0be6',
+               'uint16': '1b7741b80964bb190c50d541dca1cac1',
+               'uint32': '4dc9fcc2b395577ebb51793e58ed1a05',
+               'uint64': '17db902806f448331b5a758d7d2ee672',
+               'uint8': '27dd30c4e08a797063dffac2490b0be6'}
+
+        for dt in self.itype[1:]:
+            np.random.seed(1234)
+
+            # view as little endian for hash
+            if sys.byteorder == 'little':
+                val = self.rfunc(0, 6, size=1000, dtype=dt)
+            else:
+                val = self.rfunc(0, 6, size=1000, dtype=dt).byteswap()
+
+            res = hashlib.md5(val.view(np.int8)).hexdigest()
+            assert_(tgt[np.dtype(dt).name] == res)
+
+        # bools do not depend on endianess
+        np.random.seed(1234)
+        val = self.rfunc(0, 2, size=1000, dtype=np.bool).view(np.int8)
+        res = hashlib.md5(val).hexdigest()
+        assert_(tgt[np.dtype(np.bool).name] == res)
+
+    def test_respect_dtype_singleton(self):
+        # See gh-7203
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+
+            sample = self.rfunc(lbnd, ubnd, dtype=dt)
+            self.assertEqual(sample.dtype, np.dtype(dt))
+
+        for dt in (np.bool, np.int, np.long):
+            lbnd = 0 if dt is np.bool else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool else np.iinfo(dt).max + 1
+
+            # gh-7284: Ensure that we get Python data types
+            sample = self.rfunc(lbnd, ubnd, dtype=dt)
+            self.assertFalse(hasattr(sample, 'dtype'))
+            self.assertEqual(type(sample), dt)
+
+
+class TestRandomDist(TestCase):
+    # Make sure the random distribution returns the correct value for a
+    # given seed
+
+    def setUp(self):
+        self.seed = 1234567890
+
+    def test_rand(self):
+        np.random.seed(self.seed)
+        actual = np.random.rand(3, 2)
+        desired = np.array([[0.61879477158567997, 0.59162362775974664],
+                            [0.88868358904449662, 0.89165480011560816],
+                            [0.4575674820298663, 0.7781880808593471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_randn(self):
+        np.random.seed(self.seed)
+        actual = np.random.randn(3, 2)
+        desired = np.array([[1.34016345771863121, 1.73759122771936081],
+                           [1.498988344300628, -0.2286433324536169],
+                           [2.031033998682787, 2.17032494605655257]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_randint(self):
+        np.random.seed(self.seed)
+        actual = np.random.randint(-99, 99, size=(3, 2))
+        desired = np.array([[31, 3],
+                            [-52, 41],
+                            [-48, -66]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_random_integers(self):
+        np.random.seed(self.seed)
+        actual = np.random.random_integers(-99, 99, size=(3, 2))
+        desired = np.array([[31, 3],
+                            [-52, 41],
+                            [-48, -66]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_random_integers_max_int(self):
+        # Tests whether random_integers can generate the
+        # maximum allowed Python int that can be converted
+        # into a C long. Previous implementations of this
+        # method have thrown an OverflowError when attempting
+        # to generate this integer.
+        actual = np.random.random_integers(np.iinfo('l').max,
+                                           np.iinfo('l').max)
+        desired = np.iinfo('l').max
+        np.testing.assert_equal(actual, desired)
+
+    def test_random_integers_deprecated(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", DeprecationWarning)
+
+            # DeprecationWarning raised with high == None
+            assert_raises(DeprecationWarning,
+                          np.random.random_integers,
+                          np.iinfo('l').max)
+
+            # DeprecationWarning raised with high != None
+            assert_raises(DeprecationWarning,
+                          np.random.random_integers,
+                          np.iinfo('l').max, np.iinfo('l').max)
+
+    def test_random_sample(self):
+        np.random.seed(self.seed)
+        actual = np.random.random_sample((3, 2))
+        desired = np.array([[0.61879477158567997, 0.59162362775974664],
+                            [0.88868358904449662, 0.89165480011560816],
+                            [0.4575674820298663, 0.7781880808593471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_choice_uniform_replace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 4)
+        desired = np.array([2, 3, 2, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_nonuniform_replace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 4, p=[0.4, 0.4, 0.1, 0.1])
+        desired = np.array([1, 1, 2, 2])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_uniform_noreplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 3, replace=False)
+        desired = np.array([0, 1, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_nonuniform_noreplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 3, replace=False,
+                                  p=[0.1, 0.3, 0.5, 0.1])
+        desired = np.array([2, 3, 1])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_noninteger(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(['a', 'b', 'c', 'd'], 4)
+        desired = np.array(['c', 'd', 'c', 'd'])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_exceptions(self):
+        sample = np.random.choice
+        assert_raises(ValueError, sample, -1, 3)
+        assert_raises(ValueError, sample, 3., 3)
+        assert_raises(ValueError, sample, [[1, 2], [3, 4]], 3)
+        assert_raises(ValueError, sample, [], 3)
+        assert_raises(ValueError, sample, [1, 2, 3, 4], 3,
+                                          p=[[0.25, 0.25], [0.25, 0.25]])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4, 0.2])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[1.1, -0.1])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4])
+        assert_raises(ValueError, sample, [1, 2, 3], 4, replace=False)
+        assert_raises(ValueError, sample, [1, 2, 3], 2, replace=False,
+                                          p=[1, 0, 0])
+
+    def test_choice_return_shape(self):
+        p = [0.1, 0.9]
+        # Check scalar
+        assert_(np.isscalar(np.random.choice(2, replace=True)))
+        assert_(np.isscalar(np.random.choice(2, replace=False)))
+        assert_(np.isscalar(np.random.choice(2, replace=True, p=p)))
+        assert_(np.isscalar(np.random.choice(2, replace=False, p=p)))
+        assert_(np.isscalar(np.random.choice([1, 2], replace=True)))
+        assert_(np.random.choice([None], replace=True) is None)
+        a = np.array([1, 2])
+        arr = np.empty(1, dtype=object)
+        arr[0] = a
+        assert_(np.random.choice(arr, replace=True) is a)
+
+        # Check 0-d array
+        s = tuple()
+        assert_(not np.isscalar(np.random.choice(2, s, replace=True)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=False)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=True, p=p)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=False, p=p)))
+        assert_(not np.isscalar(np.random.choice([1, 2], s, replace=True)))
+        assert_(np.random.choice([None], s, replace=True).ndim == 0)
+        a = np.array([1, 2])
+        arr = np.empty(1, dtype=object)
+        arr[0] = a
+        assert_(np.random.choice(arr, s, replace=True).item() is a)
+
+        # Check multi dimensional array
+        s = (2, 3)
+        p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2]
+        assert_(np.random.choice(6, s, replace=True).shape, s)
+        assert_(np.random.choice(6, s, replace=False).shape, s)
+        assert_(np.random.choice(6, s, replace=True, p=p).shape, s)
+        assert_(np.random.choice(6, s, replace=False, p=p).shape, s)
+        assert_(np.random.choice(np.arange(6), s, replace=True).shape, s)
+
+    def test_bytes(self):
+        np.random.seed(self.seed)
+        actual = np.random.bytes(10)
+        desired = asbytes('\x82Ui\x9e\xff\x97+Wf\xa5')
+        np.testing.assert_equal(actual, desired)
+
+    def test_shuffle(self):
+        # Test lists, arrays (of various dtypes), and multidimensional versions
+        # of both, c-contiguous or not:
+        for conv in [lambda x: np.array([]),
+                     lambda x: x,
+                     lambda x: np.asarray(x).astype(np.int8),
+                     lambda x: np.asarray(x).astype(np.float32),
+                     lambda x: np.asarray(x).astype(np.complex64),
+                     lambda x: np.asarray(x).astype(object),
+                     lambda x: [(i, i) for i in x],
+                     lambda x: np.asarray([[i, i] for i in x]),
+                     lambda x: np.vstack([x, x]).T,
+                     # gh-4270
+                     lambda x: np.asarray([(i, i) for i in x],
+                                          [("a", object, 1),
+                                           ("b", np.int32, 1)])]:
+            np.random.seed(self.seed)
+            alist = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
+            np.random.shuffle(alist)
+            actual = alist
+            desired = conv([0, 1, 9, 6, 2, 4, 5, 8, 7, 3])
+            np.testing.assert_array_equal(actual, desired)
+
+    def test_shuffle_masked(self):
+        # gh-3263
+        a = np.ma.masked_values(np.reshape(range(20), (5,4)) % 3 - 1, -1)
+        b = np.ma.masked_values(np.arange(20) % 3 - 1, -1)
+        a_orig = a.copy()
+        b_orig = b.copy()
+        for i in range(50):
+            np.random.shuffle(a)
+            assert_equal(
+                sorted(a.data[~a.mask]), sorted(a_orig.data[~a_orig.mask]))
+            np.random.shuffle(b)
+            assert_equal(
+                sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask]))
+
+    def test_beta(self):
+        np.random.seed(self.seed)
+        actual = np.random.beta(.1, .9, size=(3, 2))
+        desired = np.array(
+                [[1.45341850513746058e-02, 5.31297615662868145e-04],
+                 [1.85366619058432324e-06, 4.19214516800110563e-03],
+                 [1.58405155108498093e-04, 1.26252891949397652e-04]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_binomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.binomial(100.123, .456, size=(3, 2))
+        desired = np.array([[37, 43],
+                         [42, 48],
+                         [46, 45]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_chisquare(self):
+        np.random.seed(self.seed)
+        actual = np.random.chisquare(50, size=(3, 2))
+        desired = np.array([[63.87858175501090585, 68.68407748911370447],
+                            [65.77116116901505904, 47.09686762438974483],
+                            [72.3828403199695174, 74.18408615260374006]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=13)
+
+    def test_dirichlet(self):
+        np.random.seed(self.seed)
+        alpha = np.array([51.72840233779265162, 39.74494232180943953])
+        actual = np.random.mtrand.dirichlet(alpha, size=(3, 2))
+        desired = np.array([[[0.54539444573611562, 0.45460555426388438],
+                             [0.62345816822039413, 0.37654183177960598]],
+                            [[0.55206000085785778, 0.44793999914214233],
+                             [0.58964023305154301, 0.41035976694845688]],
+                            [[0.59266909280647828, 0.40733090719352177],
+                             [0.56974431743975207, 0.43025568256024799]]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_dirichlet_size(self):
+        # gh-3173
+        p = np.array([51.72840233779265162, 39.74494232180943953])
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, [2, 2]).shape, (2, 2, 2))
+        assert_equal(np.random.dirichlet(p, (2, 2)).shape, (2, 2, 2))
+        assert_equal(np.random.dirichlet(p, np.array((2, 2))).shape, (2, 2, 2))
+
+        assert_raises(TypeError, np.random.dirichlet, p, np.float(1))
+
+    def test_exponential(self):
+        np.random.seed(self.seed)
+        actual = np.random.exponential(1.1234, size=(3, 2))
+        desired = np.array([[1.08342649775011624, 1.00607889924557314],
+                            [2.46628830085216721, 2.49668106809923884],
+                            [0.68717433461363442, 1.69175666993575979]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_f(self):
+        np.random.seed(self.seed)
+        actual = np.random.f(12, 77, size=(3, 2))
+        desired = np.array([[1.21975394418575878, 1.75135759791559775],
+                            [1.44803115017146489, 1.22108959480396262],
+                            [1.02176975757740629, 1.34431827623300415]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_gamma(self):
+        np.random.seed(self.seed)
+        actual = np.random.gamma(5, 3, size=(3, 2))
+        desired = np.array([[24.60509188649287182, 28.54993563207210627],
+                            [26.13476110204064184, 12.56988482927716078],
+                            [31.71863275789960568, 33.30143302795922011]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_geometric(self):
+        np.random.seed(self.seed)
+        actual = np.random.geometric(.123456789, size=(3, 2))
+        desired = np.array([[8, 7],
+                            [17, 17],
+                            [5, 12]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_gumbel(self):
+        np.random.seed(self.seed)
+        actual = np.random.gumbel(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[0.19591898743416816, 0.34405539668096674],
+                            [-1.4492522252274278, -1.47374816298446865],
+                            [1.10651090478803416, -0.69535848626236174]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_hypergeometric(self):
+        np.random.seed(self.seed)
+        actual = np.random.hypergeometric(10.1, 5.5, 14, size=(3, 2))
+        desired = np.array([[10, 10],
+                            [10, 10],
+                            [9, 9]])
+        np.testing.assert_array_equal(actual, desired)
+
+        # Test nbad = 0
+        actual = np.random.hypergeometric(5, 0, 3, size=4)
+        desired = np.array([3, 3, 3, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+        actual = np.random.hypergeometric(15, 0, 12, size=4)
+        desired = np.array([12, 12, 12, 12])
+        np.testing.assert_array_equal(actual, desired)
+
+        # Test ngood = 0
+        actual = np.random.hypergeometric(0, 5, 3, size=4)
+        desired = np.array([0, 0, 0, 0])
+        np.testing.assert_array_equal(actual, desired)
+
+        actual = np.random.hypergeometric(0, 15, 12, size=4)
+        desired = np.array([0, 0, 0, 0])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_laplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.laplace(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[0.66599721112760157, 0.52829452552221945],
+                            [3.12791959514407125, 3.18202813572992005],
+                            [-0.05391065675859356, 1.74901336242837324]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_logistic(self):
+        np.random.seed(self.seed)
+        actual = np.random.logistic(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[1.09232835305011444, 0.8648196662399954],
+                            [4.27818590694950185, 4.33897006346929714],
+                            [-0.21682183359214885, 2.63373365386060332]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_lognormal(self):
+        np.random.seed(self.seed)
+        actual = np.random.lognormal(mean=.123456789, sigma=2.0, size=(3, 2))
+        desired = np.array([[16.50698631688883822, 36.54846706092654784],
+                            [22.67886599981281748, 0.71617561058995771],
+                            [65.72798501792723869, 86.84341601437161273]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=13)
+
+    def test_logseries(self):
+        np.random.seed(self.seed)
+        actual = np.random.logseries(p=.923456789, size=(3, 2))
+        desired = np.array([[2, 2],
+                            [6, 17],
+                            [3, 6]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_multinomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.multinomial(20, [1/6.]*6, size=(3, 2))
+        desired = np.array([[[4, 3, 5, 4, 2, 2],
+                             [5, 2, 8, 2, 2, 1]],
+                            [[3, 4, 3, 6, 0, 4],
+                             [2, 1, 4, 3, 6, 4]],
+                            [[4, 4, 2, 5, 2, 3],
+                             [4, 3, 4, 2, 3, 4]]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_multivariate_normal(self):
+        np.random.seed(self.seed)
+        mean = (.123456789, 10)
+        # Hmm... not even symmetric.
+        cov = [[1, 0], [1, 0]]
+        size = (3, 2)
+        actual = np.random.multivariate_normal(mean, cov, size)
+        desired = np.array([[[-1.47027513018564449, 10.],
+                             [-1.65915081534845532, 10.]],
+                            [[-2.29186329304599745, 10.],
+                             [-1.77505606019580053, 10.]],
+                            [[-0.54970369430044119, 10.],
+                             [0.29768848031692957, 10.]]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+        # Check for default size, was raising deprecation warning
+        actual = np.random.multivariate_normal(mean, cov)
+        desired = np.array([-0.79441224511977482, 10.])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+        # Check that non positive-semidefinite covariance raises warning
+        mean = [0, 0]
+        cov = [[1, 1 + 1e-10], [1 + 1e-10, 1]]
+        assert_warns(RuntimeWarning, np.random.multivariate_normal, mean, cov)
+
+    def test_negative_binomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.negative_binomial(n=100, p=.12345, size=(3, 2))
+        desired = np.array([[848, 841],
+                            [892, 611],
+                            [779, 647]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_noncentral_chisquare(self):
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_chisquare(df=5, nonc=5, size=(3, 2))
+        desired = np.array([[23.91905354498517511, 13.35324692733826346],
+                            [31.22452661329736401, 16.60047399466177254],
+                            [5.03461598262724586, 17.94973089023519464]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+        actual = np.random.noncentral_chisquare(df=.5, nonc=.2, size=(3, 2))
+        desired = np.array([[ 1.47145377828516666,  0.15052899268012659],
+                            [ 0.00943803056963588,  1.02647251615666169],
+                            [ 0.332334982684171  ,  0.15451287602753125]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_chisquare(df=5, nonc=0, size=(3, 2))
+        desired = np.array([[9.597154162763948, 11.725484450296079],
+                            [10.413711048138335, 3.694475922923986],
+                            [13.484222138963087, 14.377255424602957]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_noncentral_f(self):
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_f(dfnum=5, dfden=2, nonc=1,
+                                        size=(3, 2))
+        desired = np.array([[1.40598099674926669, 0.34207973179285761],
+                            [3.57715069265772545, 7.92632662577829805],
+                            [0.43741599463544162, 1.1774208752428319]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_normal(self):
+        np.random.seed(self.seed)
+        actual = np.random.normal(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[2.80378370443726244, 3.59863924443872163],
+                            [3.121433477601256, -0.33382987590723379],
+                            [4.18552478636557357, 4.46410668111310471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_pareto(self):
+        np.random.seed(self.seed)
+        actual = np.random.pareto(a=.123456789, size=(3, 2))
+        desired = np.array(
+                [[2.46852460439034849e+03, 1.41286880810518346e+03],
+                 [5.28287797029485181e+07, 6.57720981047328785e+07],
+                 [1.40840323350391515e+02, 1.98390255135251704e+05]])
+        # For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this
+        # matrix differs by 24 nulps. Discussion:
+        #   http://mail.scipy.org/pipermail/numpy-discussion/2012-September/063801.html
+        # Consensus is that this is probably some gcc quirk that affects
+        # rounding but not in any important way, so we just use a looser
+        # tolerance on this test:
+        np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=30)
+
+    def test_poisson(self):
+        np.random.seed(self.seed)
+        actual = np.random.poisson(lam=.123456789, size=(3, 2))
+        desired = np.array([[0, 0],
+                         [1, 0],
+                         [0, 0]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_poisson_exceptions(self):
+        lambig = np.iinfo('l').max
+        lamneg = -1
+        assert_raises(ValueError, np.random.poisson, lamneg)
+        assert_raises(ValueError, np.random.poisson, [lamneg]*10)
+        assert_raises(ValueError, np.random.poisson, lambig)
+        assert_raises(ValueError, np.random.poisson, [lambig]*10)
+
+    def test_power(self):
+        np.random.seed(self.seed)
+        actual = np.random.power(a=.123456789, size=(3, 2))
+        desired = np.array([[0.02048932883240791, 0.01424192241128213],
+                            [0.38446073748535298, 0.39499689943484395],
+                            [0.00177699707563439, 0.13115505880863756]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_rayleigh(self):
+        np.random.seed(self.seed)
+        actual = np.random.rayleigh(scale=10, size=(3, 2))
+        desired = np.array([[13.8882496494248393, 13.383318339044731],
+                            [20.95413364294492098, 21.08285015800712614],
+                            [11.06066537006854311, 17.35468505778271009]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_standard_cauchy(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_cauchy(size=(3, 2))
+        desired = np.array([[0.77127660196445336, -6.55601161955910605],
+                            [0.93582023391158309, -2.07479293013759447],
+                            [-4.74601644297011926, 0.18338989290760804]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_exponential(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_exponential(size=(3, 2))
+        desired = np.array([[0.96441739162374596, 0.89556604882105506],
+                            [2.1953785836319808, 2.22243285392490542],
+                            [0.6116915921431676, 1.50592546727413201]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_gamma(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_gamma(shape=3, size=(3, 2))
+        desired = np.array([[5.50841531318455058, 6.62953470301903103],
+                            [5.93988484943779227, 2.31044849402133989],
+                            [7.54838614231317084, 8.012756093271868]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_standard_normal(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_normal(size=(3, 2))
+        desired = np.array([[1.34016345771863121, 1.73759122771936081],
+                            [1.498988344300628, -0.2286433324536169],
+                            [2.031033998682787, 2.17032494605655257]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_t(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_t(df=10, size=(3, 2))
+        desired = np.array([[0.97140611862659965, -0.08830486548450577],
+                            [1.36311143689505321, -0.55317463909867071],
+                            [-0.18473749069684214, 0.61181537341755321]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_triangular(self):
+        np.random.seed(self.seed)
+        actual = np.random.triangular(left=5.12, mode=10.23, right=20.34,
+                                      size=(3, 2))
+        desired = np.array([[12.68117178949215784, 12.4129206149193152],
+                            [16.20131377335158263, 16.25692138747600524],
+                            [11.20400690911820263, 14.4978144835829923]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_uniform(self):
+        np.random.seed(self.seed)
+        actual = np.random.uniform(low=1.23, high=10.54, size=(3, 2))
+        desired = np.array([[6.99097932346268003, 6.73801597444323974],
+                            [9.50364421400426274, 9.53130618907631089],
+                            [5.48995325769805476, 8.47493103280052118]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_uniform_range_bounds(self):
+        fmin = np.finfo('float').min
+        fmax = np.finfo('float').max
+
+        func = np.random.uniform
+        np.testing.assert_raises(OverflowError, func, -np.inf, 0)
+        np.testing.assert_raises(OverflowError, func,  0,      np.inf)
+        np.testing.assert_raises(OverflowError, func,  fmin,   fmax)
+
+        # (fmax / 1e17) - fmin is within range, so this should not throw
+        np.random.uniform(low=fmin, high=fmax / 1e17)
+
+    def test_vonmises(self):
+        np.random.seed(self.seed)
+        actual = np.random.vonmises(mu=1.23, kappa=1.54, size=(3, 2))
+        desired = np.array([[2.28567572673902042, 2.89163838442285037],
+                            [0.38198375564286025, 2.57638023113890746],
+                            [1.19153771588353052, 1.83509849681825354]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_vonmises_small(self):
+        # check infinite loop, gh-4720
+        np.random.seed(self.seed)
+        r = np.random.vonmises(mu=0., kappa=1.1e-8, size=10**6)
+        np.testing.assert_(np.isfinite(r).all())
+
+    def test_wald(self):
+        np.random.seed(self.seed)
+        actual = np.random.wald(mean=1.23, scale=1.54, size=(3, 2))
+        desired = np.array([[3.82935265715889983, 5.13125249184285526],
+                            [0.35045403618358717, 1.50832396872003538],
+                            [0.24124319895843183, 0.22031101461955038]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_weibull(self):
+        np.random.seed(self.seed)
+        actual = np.random.weibull(a=1.23, size=(3, 2))
+        desired = np.array([[0.97097342648766727, 0.91422896443565516],
+                            [1.89517770034962929, 1.91414357960479564],
+                            [0.67057783752390987, 1.39494046635066793]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_zipf(self):
+        np.random.seed(self.seed)
+        actual = np.random.zipf(a=1.23, size=(3, 2))
+        desired = np.array([[66, 29],
+                            [1, 1],
+                            [3, 13]])
+        np.testing.assert_array_equal(actual, desired)
+
+
+class TestThread(object):
+    # make sure each state produces the same sequence even in threads
+    def setUp(self):
+        self.seeds = range(4)
+
+    def check_function(self, function, sz):
+        from threading import Thread
+
+        out1 = np.empty((len(self.seeds),) + sz)
+        out2 = np.empty((len(self.seeds),) + sz)
+
+        # threaded generation
+        t = [Thread(target=function, args=(np.random.RandomState(s), o))
+             for s, o in zip(self.seeds, out1)]
+        [x.start() for x in t]
+        [x.join() for x in t]
+
+        # the same serial
+        for s, o in zip(self.seeds, out2):
+            function(np.random.RandomState(s), o)
+
+        # these platforms change x87 fpu precision mode in threads
+        if (np.intp().dtype.itemsize == 4 and sys.platform == "win32"):
+            np.testing.assert_array_almost_equal(out1, out2)
+        else:
+            np.testing.assert_array_equal(out1, out2)
+
+    def test_normal(self):
+        def gen_random(state, out):
+            out[...] = state.normal(size=10000)
+        self.check_function(gen_random, sz=(10000,))
+
+    def test_exp(self):
+        def gen_random(state, out):
+            out[...] = state.exponential(scale=np.ones((100, 1000)))
+        self.check_function(gen_random, sz=(100, 1000))
+
+    def test_multinomial(self):
+        def gen_random(state, out):
+            out[...] = state.multinomial(10, [1/6.]*6, size=10000)
+        self.check_function(gen_random, sz=(10000,6))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_regression.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
new file mode 100644
index 0000000000..133a1aa5ad
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
@@ -0,0 +1,117 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.testing import (TestCase, run_module_suite, assert_,
+                           assert_array_equal, assert_raises)
+from numpy import random
+from numpy.compat import long
+import numpy as np
+
+
+class TestRegression(TestCase):
+
+    def test_VonMises_range(self):
+        # Make sure generated random variables are in [-pi, pi].
+        # Regression test for ticket #986.
+        for mu in np.linspace(-7., 7., 5):
+            r = random.mtrand.vonmises(mu, 1, 50)
+            assert_(np.all(r > -np.pi) and np.all(r <= np.pi))
+
+    def test_hypergeometric_range(self):
+        # Test for ticket #921
+        assert_(np.all(np.random.hypergeometric(3, 18, 11, size=10) < 4))
+        assert_(np.all(np.random.hypergeometric(18, 3, 11, size=10) > 0))
+
+        # Test for ticket #5623
+        args = [
+            (2**20 - 2, 2**20 - 2, 2**20 - 2),  # Check for 32-bit systems
+        ]
+        is_64bits = sys.maxsize > 2**32
+        if is_64bits and sys.platform != 'win32':
+            args.append((2**40 - 2, 2**40 - 2, 2**40 - 2)) # Check for 64-bit systems
+        for arg in args:
+            assert_(np.random.hypergeometric(*arg) > 0)
+
+    def test_logseries_convergence(self):
+        # Test for ticket #923
+        N = 1000
+        np.random.seed(0)
+        rvsn = np.random.logseries(0.8, size=N)
+        # these two frequency counts should be close to theoretical
+        # numbers with this large sample
+        # theoretical large N result is 0.49706795
+        freq = np.sum(rvsn == 1) / float(N)
+        msg = "Frequency was %f, should be > 0.45" % freq
+        assert_(freq > 0.45, msg)
+        # theoretical large N result is 0.19882718
+        freq = np.sum(rvsn == 2) / float(N)
+        msg = "Frequency was %f, should be < 0.23" % freq
+        assert_(freq < 0.23, msg)
+
+    def test_permutation_longs(self):
+        np.random.seed(1234)
+        a = np.random.permutation(12)
+        np.random.seed(1234)
+        b = np.random.permutation(long(12))
+        assert_array_equal(a, b)
+
+    def test_randint_range(self):
+        # Test for ticket #1690
+        lmax = np.iinfo('l').max
+        lmin = np.iinfo('l').min
+        try:
+            random.randint(lmin, lmax)
+        except:
+            raise AssertionError
+
+    def test_shuffle_mixed_dimension(self):
+        # Test for trac ticket #2074
+        for t in [[1, 2, 3, None],
+                  [(1, 1), (2, 2), (3, 3), None],
+                  [1, (2, 2), (3, 3), None],
+                  [(1, 1), 2, 3, None]]:
+            np.random.seed(12345)
+            shuffled = list(t)
+            random.shuffle(shuffled)
+            assert_array_equal(shuffled, [t[0], t[3], t[1], t[2]])
+
+    def test_call_within_randomstate(self):
+        # Check that custom RandomState does not call into global state
+        m = np.random.RandomState()
+        res = np.array([0, 8, 7, 2, 1, 9, 4, 7, 0, 3])
+        for i in range(3):
+            np.random.seed(i)
+            m.seed(4321)
+            # If m.state is not honored, the result will change
+            assert_array_equal(m.choice(10, size=10, p=np.ones(10)/10.), res)
+
+    def test_multivariate_normal_size_types(self):
+        # Test for multivariate_normal issue with 'size' argument.
+        # Check that the multivariate_normal size argument can be a
+        # numpy integer.
+        np.random.multivariate_normal([0], [[0]], size=1)
+        np.random.multivariate_normal([0], [[0]], size=np.int_(1))
+        np.random.multivariate_normal([0], [[0]], size=np.int64(1))
+
+    def test_beta_small_parameters(self):
+        # Test that beta with small a and b parameters does not produce
+        # NaNs due to roundoff errors causing 0 / 0, gh-5851
+        np.random.seed(1234567890)
+        x = np.random.beta(0.0001, 0.0001, size=100)
+        assert_(not np.any(np.isnan(x)), 'Nans in np.random.beta')
+
+    def test_choice_sum_of_probs_tolerance(self):
+        # The sum of probs should be 1.0 with some tolerance.
+        # For low precision dtypes the tolerance was too tight.
+        # See numpy github issue 6123.
+        np.random.seed(1234)
+        a = [1, 2, 3]
+        counts = [4, 4, 2]
+        for dt in np.float16, np.float32, np.float64:
+            probs = np.array(counts, dtype=dt) / sum(counts)
+            c = np.random.choice(a, p=probs)
+            assert_(c in a)
+            assert_raises(ValueError, np.random.choice, a, p=probs*0.9)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/setup.py
new file mode 100644
index 0000000000..dcb87721cd
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/setup.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('numpy', parent_package, top_path)
+
+    config.add_subpackage('compat')
+    config.add_subpackage('core')
+    config.add_subpackage('distutils')
+    config.add_subpackage('doc')
+    config.add_subpackage('f2py')
+    config.add_subpackage('fft')
+    config.add_subpackage('lib')
+    config.add_subpackage('linalg')
+    config.add_subpackage('ma')
+    config.add_subpackage('matrixlib')
+    config.add_subpackage('polynomial')
+    config.add_subpackage('random')
+    config.add_subpackage('testing')
+    config.add_data_dir('doc')
+    config.add_data_dir('tests')
+    config.make_config_py() # installs __config__.py
+    return config
+
+if __name__ == '__main__':
+    print('This is the wrong setup.py file to run')
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/__init__.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/__init__.py
new file mode 100644
index 0000000000..625fdecdc9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/__init__.py
@@ -0,0 +1,15 @@
+"""Common test support for all numpy test scripts.
+
+This single module should provide all the common functionality for numpy tests
+in a single location, so that test scripts can just import it and work right
+away.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from unittest import TestCase
+
+from . import decorators as dec
+from .nosetester import run_module_suite, NoseTester as Tester
+from .utils import *
+test = nosetester._numpy_tester().test
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/decorators.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/decorators.py
new file mode 100644
index 0000000000..6cde298e1c
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/decorators.py
@@ -0,0 +1,272 @@
+"""
+Decorators for labeling and modifying behavior of test objects.
+
+Decorators that merely return a modified version of the original
+function object are straightforward. Decorators that return a new
+function object need to use
+::
+
+  nose.tools.make_decorator(original_function)(decorator)
+
+in returning the decorator, in order to preserve meta-data such as
+function name, setup and teardown functions and so on - see
+``nose.tools`` for more information.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import collections
+
+from .utils import SkipTest
+
+def slow(t):
+    """
+    Label a test as 'slow'.
+
+    The exact definition of a slow test is obviously both subjective and
+    hardware-dependent, but in general any individual test that requires more
+    than a second or two should be labeled as slow (the whole suite consits of
+    thousands of tests, so even a second is significant).
+
+    Parameters
+    ----------
+    t : callable
+        The test to label as slow.
+
+    Returns
+    -------
+    t : callable
+        The decorated test `t`.
+
+    Examples
+    --------
+    The `numpy.testing` module includes ``import decorators as dec``.
+    A test can be decorated as slow like this::
+
+      from numpy.testing import *
+
+      @dec.slow
+      def test_big(self):
+          print('Big, slow test')
+
+    """
+
+    t.slow = True
+    return t
+
+def setastest(tf=True):
+    """
+    Signals to nose that this function is or is not a test.
+
+    Parameters
+    ----------
+    tf : bool
+        If True, specifies that the decorated callable is a test.
+        If False, specifies that the decorated callable is not a test.
+        Default is True.
+
+    Notes
+    -----
+    This decorator can't use the nose namespace, because it can be
+    called from a non-test module. See also ``istest`` and ``nottest`` in
+    ``nose.tools``.
+
+    Examples
+    --------
+    `setastest` can be used in the following way::
+
+      from numpy.testing.decorators import setastest
+
+      @setastest(False)
+      def func_with_test_in_name(arg1, arg2):
+          pass
+
+    """
+    def set_test(t):
+        t.__test__ = tf
+        return t
+    return set_test
+
+def skipif(skip_condition, msg=None):
+    """
+    Make function raise SkipTest exception if a given condition is true.
+
+    If the condition is a callable, it is used at runtime to dynamically
+    make the decision. This is useful for tests that may require costly
+    imports, to delay the cost until the test suite is actually executed.
+
+    Parameters
+    ----------
+    skip_condition : bool or callable
+        Flag to determine whether to skip the decorated test.
+    msg : str, optional
+        Message to give on raising a SkipTest exception. Default is None.
+
+    Returns
+    -------
+    decorator : function
+        Decorator which, when applied to a function, causes SkipTest
+        to be raised when `skip_condition` is True, and the function
+        to be called normally otherwise.
+
+    Notes
+    -----
+    The decorator itself is decorated with the ``nose.tools.make_decorator``
+    function in order to transmit function name, and various other metadata.
+
+    """
+
+    def skip_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+
+        # Allow for both boolean or callable skip conditions.
+        if isinstance(skip_condition, collections.Callable):
+            skip_val = lambda: skip_condition()
+        else:
+            skip_val = lambda: skip_condition
+
+        def get_msg(func,msg=None):
+            """Skip message with information about function being skipped."""
+            if msg is None:
+                out = 'Test skipped due to test condition'
+            else:
+                out = msg
+
+            return "Skipping test: %s: %s" % (func.__name__, out)
+
+        # We need to define *two* skippers because Python doesn't allow both
+        # return with value and yield inside the same function.
+        def skipper_func(*args, **kwargs):
+            """Skipper for normal test functions."""
+            if skip_val():
+                raise SkipTest(get_msg(f, msg))
+            else:
+                return f(*args, **kwargs)
+
+        def skipper_gen(*args, **kwargs):
+            """Skipper for test generators."""
+            if skip_val():
+                raise SkipTest(get_msg(f, msg))
+            else:
+                for x in f(*args, **kwargs):
+                    yield x
+
+        # Choose the right skipper to use when building the actual decorator.
+        if nose.util.isgenerator(f):
+            skipper = skipper_gen
+        else:
+            skipper = skipper_func
+
+        return nose.tools.make_decorator(f)(skipper)
+
+    return skip_decorator
+
+
+def knownfailureif(fail_condition, msg=None):
+    """
+    Make function raise KnownFailureException exception if given condition is true.
+
+    If the condition is a callable, it is used at runtime to dynamically
+    make the decision. This is useful for tests that may require costly
+    imports, to delay the cost until the test suite is actually executed.
+
+    Parameters
+    ----------
+    fail_condition : bool or callable
+        Flag to determine whether to mark the decorated test as a known
+        failure (if True) or not (if False).
+    msg : str, optional
+        Message to give on raising a KnownFailureException exception.
+        Default is None.
+
+    Returns
+    -------
+    decorator : function
+        Decorator, which, when applied to a function, causes
+        KnownFailureException to be raised when `fail_condition` is True,
+        and the function to be called normally otherwise.
+
+    Notes
+    -----
+    The decorator itself is decorated with the ``nose.tools.make_decorator``
+    function in order to transmit function name, and various other metadata.
+
+    """
+    if msg is None:
+        msg = 'Test skipped due to known failure'
+
+    # Allow for both boolean or callable known failure conditions.
+    if isinstance(fail_condition, collections.Callable):
+        fail_val = lambda: fail_condition()
+    else:
+        fail_val = lambda: fail_condition
+
+    def knownfail_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+        from .noseclasses import KnownFailureException
+
+        def knownfailer(*args, **kwargs):
+            if fail_val():
+                raise KnownFailureException(msg)
+            else:
+                return f(*args, **kwargs)
+        return nose.tools.make_decorator(f)(knownfailer)
+
+    return knownfail_decorator
+
+def deprecated(conditional=True):
+    """
+    Filter deprecation warnings while running the test suite.
+
+    This decorator can be used to filter DeprecationWarning's, to avoid
+    printing them during the test suite run, while checking that the test
+    actually raises a DeprecationWarning.
+
+    Parameters
+    ----------
+    conditional : bool or callable, optional
+        Flag to determine whether to mark test as deprecated or not. If the
+        condition is a callable, it is used at runtime to dynamically make the
+        decision. Default is True.
+
+    Returns
+    -------
+    decorator : function
+        The `deprecated` decorator itself.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    def deprecate_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+
+        def _deprecated_imp(*args, **kwargs):
+            # Poor man's replacement for the with statement
+            with warnings.catch_warnings(record=True) as l:
+                warnings.simplefilter('always')
+                f(*args, **kwargs)
+                if not len(l) > 0:
+                    raise AssertionError("No warning raised when calling %s"
+                            % f.__name__)
+                if not l[0].category is DeprecationWarning:
+                    raise AssertionError("First warning for %s is not a "
+                            "DeprecationWarning( is %s)" % (f.__name__, l[0]))
+
+        if isinstance(conditional, collections.Callable):
+            cond = conditional()
+        else:
+            cond = conditional
+        if cond:
+            return nose.tools.make_decorator(f)(_deprecated_imp)
+        else:
+            return f
+    return deprecate_decorator
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.py
new file mode 100644
index 0000000000..ee9d1b4dfe
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.py
@@ -0,0 +1,340 @@
+# These classes implement a doctest runner plugin for nose, a "known failure"
+# error class, and a customized TestProgram for NumPy.
+
+# Because this module imports nose directly, it should not
+# be used except by nosetester.py to avoid a general NumPy
+# dependency on nose.
+from __future__ import division, absolute_import, print_function
+
+import os
+import doctest
+import inspect
+
+import nose
+from nose.plugins import doctests as npd
+from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
+from nose.plugins.base import Plugin
+from nose.util import src
+import numpy
+from .nosetester import get_package_name
+from .utils import KnownFailureException, KnownFailureTest
+
+
+# Some of the classes in this module begin with 'Numpy' to clearly distinguish
+# them from the plethora of very similar names from nose/unittest/doctest
+
+#-----------------------------------------------------------------------------
+# Modified version of the one in the stdlib, that fixes a python bug (doctests
+# not found in extension modules, http://bugs.python.org/issue3158)
+class NumpyDocTestFinder(doctest.DocTestFinder):
+
+    def _from_module(self, module, object):
+        """
+        Return true if the given object is defined in the given
+        module.
+        """
+        if module is None:
+            return True
+        elif inspect.isfunction(object):
+            return module.__dict__ is object.__globals__
+        elif inspect.isbuiltin(object):
+            return module.__name__ == object.__module__
+        elif inspect.isclass(object):
+            return module.__name__ == object.__module__
+        elif inspect.ismethod(object):
+            # This one may be a bug in cython that fails to correctly set the
+            # __module__ attribute of methods, but since the same error is easy
+            # to make by extension code writers, having this safety in place
+            # isn't such a bad idea
+            return module.__name__ == object.__self__.__class__.__module__
+        elif inspect.getmodule(object) is not None:
+            return module is inspect.getmodule(object)
+        elif hasattr(object, '__module__'):
+            return module.__name__ == object.__module__
+        elif isinstance(object, property):
+            return True  # [XX] no way not be sure.
+        else:
+            raise ValueError("object must be a class or function")
+
+    def _find(self, tests, obj, name, module, source_lines, globs, seen):
+        """
+        Find tests for the given object and any contained objects, and
+        add them to `tests`.
+        """
+
+        doctest.DocTestFinder._find(self, tests, obj, name, module,
+                                    source_lines, globs, seen)
+
+        # Below we re-run pieces of the above method with manual modifications,
+        # because the original code is buggy and fails to correctly identify
+        # doctests in extension modules.
+
+        # Local shorthands
+        from inspect import (
+            isroutine, isclass, ismodule, isfunction, ismethod
+            )
+
+        # Look for tests in a module's contained objects.
+        if ismodule(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                valname1 = '%s.%s' % (name, valname)
+                if ( (isroutine(val) or isclass(val))
+                     and self._from_module(module, val)):
+
+                    self._find(tests, val, valname1, module, source_lines,
+                               globs, seen)
+
+        # Look for tests in a class's contained objects.
+        if isclass(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                # Special handling for staticmethod/classmethod.
+                if isinstance(val, staticmethod):
+                    val = getattr(obj, valname)
+                if isinstance(val, classmethod):
+                    val = getattr(obj, valname).__func__
+
+                # Recurse to methods, properties, and nested classes.
+                if ((isfunction(val) or isclass(val) or
+                     ismethod(val) or isinstance(val, property)) and
+                      self._from_module(module, val)):
+                    valname = '%s.%s' % (name, valname)
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+
+# second-chance checker; if the default comparison doesn't
+# pass, then see if the expected output string contains flags that
+# tell us to ignore the output
+class NumpyOutputChecker(doctest.OutputChecker):
+    def check_output(self, want, got, optionflags):
+        ret = doctest.OutputChecker.check_output(self, want, got,
+                                                 optionflags)
+        if not ret:
+            if "#random" in want:
+                return True
+
+            # it would be useful to normalize endianness so that
+            # bigendian machines don't fail all the tests (and there are
+            # actually some bigendian examples in the doctests). Let's try
+            # making them all little endian
+            got = got.replace("'>", "'<")
+            want = want.replace("'>", "'<")
+
+            # try to normalize out 32 and 64 bit default int sizes
+            for sz in [4, 8]:
+                got = got.replace("'<i%d'" % sz, "int")
+                want = want.replace("'<i%d'" % sz, "int")
+
+            ret = doctest.OutputChecker.check_output(self, want,
+                    got, optionflags)
+
+        return ret
+
+
+# Subclass nose.plugins.doctests.DocTestCase to work around a bug in
+# its constructor that blocks non-default arguments from being passed
+# down into doctest.DocTestCase
+class NumpyDocTestCase(npd.DocTestCase):
+    def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
+                 checker=None, obj=None, result_var='_'):
+        self._result_var = result_var
+        self._nose_obj = obj
+        doctest.DocTestCase.__init__(self, test,
+                                     optionflags=optionflags,
+                                     setUp=setUp, tearDown=tearDown,
+                                     checker=checker)
+
+
+print_state = numpy.get_printoptions()
+
+class NumpyDoctest(npd.Doctest):
+    name = 'numpydoctest'   # call nosetests with --with-numpydoctest
+    score = 1000  # load late, after doctest builtin
+
+    # always use whitespace and ellipsis options for doctests
+    doctest_optflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
+
+    # files that should be ignored for doctests
+    doctest_ignore = ['generate_numpy_api.py',
+                      'setup.py']
+
+    # Custom classes; class variables to allow subclassing
+    doctest_case_class = NumpyDocTestCase
+    out_check_class = NumpyOutputChecker
+    test_finder_class = NumpyDocTestFinder
+
+    # Don't use the standard doctest option handler; hard-code the option values
+    def options(self, parser, env=os.environ):
+        Plugin.options(self, parser, env)
+        # Test doctests in 'test' files / directories. Standard plugin default
+        # is False
+        self.doctest_tests = True
+        # Variable name; if defined, doctest results stored in this variable in
+        # the top-level namespace.  None is the standard default
+        self.doctest_result_var = None
+
+    def configure(self, options, config):
+        # parent method sets enabled flag from command line --with-numpydoctest
+        Plugin.configure(self, options, config)
+        self.finder = self.test_finder_class()
+        self.parser = doctest.DocTestParser()
+        if self.enabled:
+            # Pull standard doctest out of plugin list; there's no reason to run
+            # both.  In practice the Unplugger plugin above would cover us when
+            # run from a standard numpy.test() call; this is just in case
+            # someone wants to run our plugin outside the numpy.test() machinery
+            config.plugins.plugins = [p for p in config.plugins.plugins
+                                      if p.name != 'doctest']
+
+    def set_test_context(self, test):
+        """ Configure `test` object to set test context
+
+        We set the numpy / scipy standard doctest namespace
+
+        Parameters
+        ----------
+        test : test object
+            with ``globs`` dictionary defining namespace
+
+        Returns
+        -------
+        None
+
+        Notes
+        -----
+        `test` object modified in place
+        """
+        # set the namespace for tests
+        pkg_name = get_package_name(os.path.dirname(test.filename))
+
+        # Each doctest should execute in an environment equivalent to
+        # starting Python and executing "import numpy as np", and,
+        # for SciPy packages, an additional import of the local
+        # package (so that scipy.linalg.basic.py's doctests have an
+        # implicit "from scipy import linalg" as well.
+        #
+        # Note: __file__ allows the doctest in NoseTester to run
+        # without producing an error
+        test.globs = {'__builtins__':__builtins__,
+                      '__file__':'__main__',
+                      '__name__':'__main__',
+                      'np':numpy}
+        # add appropriate scipy import for SciPy tests
+        if 'scipy' in pkg_name:
+            p = pkg_name.split('.')
+            p2 = p[-1]
+            test.globs[p2] = __import__(pkg_name, test.globs, {}, [p2])
+
+    # Override test loading to customize test context (with set_test_context
+    # method), set standard docstring options, and install our own test output
+    # checker
+    def loadTestsFromModule(self, module):
+        if not self.matches(module.__name__):
+            npd.log.debug("Doctest doesn't want module %s", module)
+            return
+        try:
+            tests = self.finder.find(module)
+        except AttributeError:
+            # nose allows module.__test__ = False; doctest does not and
+            # throws AttributeError
+            return
+        if not tests:
+            return
+        tests.sort()
+        module_file = src(module.__file__)
+        for test in tests:
+            if not test.examples:
+                continue
+            if not test.filename:
+                test.filename = module_file
+            # Set test namespace; test altered in place
+            self.set_test_context(test)
+            yield self.doctest_case_class(test,
+                                          optionflags=self.doctest_optflags,
+                                          checker=self.out_check_class(),
+                                          result_var=self.doctest_result_var)
+
+    # Add an afterContext method to nose.plugins.doctests.Doctest in order
+    # to restore print options to the original state after each doctest
+    def afterContext(self):
+        numpy.set_printoptions(**print_state)
+
+    # Ignore NumPy-specific build files that shouldn't be searched for tests
+    def wantFile(self, file):
+        bn = os.path.basename(file)
+        if bn in self.doctest_ignore:
+            return False
+        return npd.Doctest.wantFile(self, file)
+
+
+class Unplugger(object):
+    """ Nose plugin to remove named plugin late in loading
+
+    By default it removes the "doctest" plugin.
+    """
+    name = 'unplugger'
+    enabled = True  # always enabled
+    score = 4000  # load late in order to be after builtins
+
+    def __init__(self, to_unplug='doctest'):
+        self.to_unplug = to_unplug
+
+    def options(self, parser, env):
+        pass
+
+    def configure(self, options, config):
+        # Pull named plugin out of plugins list
+        config.plugins.plugins = [p for p in config.plugins.plugins
+                                  if p.name != self.to_unplug]
+
+
+class KnownFailurePlugin(ErrorClassPlugin):
+    '''Plugin that installs a KNOWNFAIL error class for the
+    KnownFailureClass exception.  When KnownFailure is raised,
+    the exception will be logged in the knownfail attribute of the
+    result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the
+    exception will not be counted as an error or failure.'''
+    enabled = True
+    knownfail = ErrorClass(KnownFailureException,
+                           label='KNOWNFAIL',
+                           isfailure=False)
+
+    def options(self, parser, env=os.environ):
+        env_opt = 'NOSE_WITHOUT_KNOWNFAIL'
+        parser.add_option('--no-knownfail', action='store_true',
+                          dest='noKnownFail', default=env.get(env_opt, False),
+                          help='Disable special handling of KnownFailure '
+                               'exceptions')
+
+    def configure(self, options, conf):
+        if not self.can_configure:
+            return
+        self.conf = conf
+        disable = getattr(options, 'noKnownFail', False)
+        if disable:
+            self.enabled = False
+
+KnownFailure = KnownFailurePlugin   # backwards compat
+
+
+# Class allows us to save the results of the tests in runTests - see runTests
+# method docstring for details
+class NumpyTestProgram(nose.core.TestProgram):
+    def runTests(self):
+        """Run Tests. Returns true on success, false on failure, and
+        sets self.success to the same value.
+
+        Because nose currently discards the test result object, but we need
+        to return it to the user, override TestProgram.runTests to retain
+        the result
+        """
+        if self.testRunner is None:
+            self.testRunner = nose.core.TextTestRunner(stream=self.config.stream,
+                                                       verbosity=self.config.verbosity,
+                                                       config=self.config)
+        plug_runner = self.config.plugins.prepareTestRunner(self.testRunner)
+        if plug_runner is not None:
+            self.testRunner = plug_runner
+        self.result = self.testRunner.run(self.test)
+        self.success = self.result.wasSuccessful()
+        return self.success
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.py
new file mode 100644
index 0000000000..e3205837c9
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.py
@@ -0,0 +1,516 @@
+"""
+Nose test running.
+
+This module implements ``test()`` and ``bench()`` functions for NumPy modules.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import warnings
+from numpy.compat import basestring
+import numpy as np
+
+
+def get_package_name(filepath):
+    """
+    Given a path where a package is installed, determine its name.
+
+    Parameters
+    ----------
+    filepath : str
+        Path to a file. If the determination fails, "numpy" is returned.
+
+    Examples
+    --------
+    >>> np.testing.nosetester.get_package_name('nonsense')
+    'numpy'
+
+    """
+
+    fullpath = filepath[:]
+    pkg_name = []
+    while 'site-packages' in filepath or 'dist-packages' in filepath:
+        filepath, p2 = os.path.split(filepath)
+        if p2 in ('site-packages', 'dist-packages'):
+            break
+        pkg_name.append(p2)
+
+    # if package name determination failed, just default to numpy/scipy
+    if not pkg_name:
+        if 'scipy' in fullpath:
+            return 'scipy'
+        else:
+            return 'numpy'
+
+    # otherwise, reverse to get correct order and return
+    pkg_name.reverse()
+
+    # don't include the outer egg directory
+    if pkg_name[0].endswith('.egg'):
+        pkg_name.pop(0)
+
+    return '.'.join(pkg_name)
+
+def import_nose():
+    """ Import nose only when needed.
+    """
+    fine_nose = True
+    minimum_nose_version = (1, 0, 0)
+    try:
+        import nose
+    except ImportError:
+        fine_nose = False
+    else:
+        if nose.__versioninfo__ < minimum_nose_version:
+            fine_nose = False
+
+    if not fine_nose:
+        msg = ('Need nose >= %d.%d.%d for tests - see '
+               'http://somethingaboutorange.com/mrl/projects/nose' %
+               minimum_nose_version)
+        raise ImportError(msg)
+
+    return nose
+
+def run_module_suite(file_to_run=None, argv=None):
+    """
+    Run a test module.
+
+    Equivalent to calling ``$ nosetests <argv> <file_to_run>`` from
+    the command line
+
+    Parameters
+    ----------
+    file_to_run : str, optional
+        Path to test module, or None.
+        By default, run the module from which this function is called.
+    argv : list of strings
+        Arguments to be passed to the nose test runner. ``argv[0]`` is
+        ignored. All command line arguments accepted by ``nosetests``
+        will work. If it is the default value None, sys.argv is used.
+
+        .. versionadded:: 1.9.0
+
+    Examples
+    --------
+    Adding the following::
+
+        if __name__ == "__main__" :
+            run_module_suite(argv=sys.argv)
+
+    at the end of a test module will run the tests when that module is
+    called in the python interpreter.
+
+    Alternatively, calling::
+
+    >>> run_module_suite(file_to_run="numpy/tests/test_matlib.py")
+
+    from an interpreter will run all the test routine in 'test_matlib.py'.
+    """
+    if file_to_run is None:
+        f = sys._getframe(1)
+        file_to_run = f.f_locals.get('__file__', None)
+        if file_to_run is None:
+            raise AssertionError
+
+    if argv is None:
+        argv = sys.argv + [file_to_run]
+    else:
+        argv = argv + [file_to_run]
+
+    nose = import_nose()
+    from .noseclasses import KnownFailurePlugin
+    nose.run(argv=argv, addplugins=[KnownFailurePlugin()])
+
+
+class NoseTester(object):
+    """
+    Nose test runner.
+
+    This class is made available as numpy.testing.Tester, and a test function
+    is typically added to a package's __init__.py like so::
+
+      from numpy.testing import Tester
+      test = Tester().test
+
+    Calling this test function finds and runs all tests associated with the
+    package and all its sub-packages.
+
+    Attributes
+    ----------
+    package_path : str
+        Full path to the package to test.
+    package_name : str
+        Name of the package to test.
+
+    Parameters
+    ----------
+    package : module, str or None, optional
+        The package to test. If a string, this should be the full path to
+        the package. If None (default), `package` is set to the module from
+        which `NoseTester` is initialized.
+    raise_warnings : None, str or sequence of warnings, optional
+        This specifies which warnings to configure as 'raise' instead
+        of 'warn' during the test execution.  Valid strings are:
+
+          - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
+          - "release" : equals ``()``, don't raise on any warnings.
+
+        Default is "release".
+    depth : int, optional
+        If `package` is None, then this can be used to initialize from the
+        module of the caller of (the caller of (...)) the code that
+        initializes `NoseTester`. Default of 0 means the module of the
+        immediate caller; higher values are useful for utility routines that
+        want to initialize `NoseTester` objects on behalf of other code.
+
+    """
+    def __init__(self, package=None, raise_warnings="release", depth=0):
+        # Back-compat: 'None' used to mean either "release" or "develop"
+        # depending on whether this was a release or develop version of
+        # numpy. Those semantics were fine for testing numpy, but not so
+        # helpful for downstream projects like scipy that use
+        # numpy.testing. (They want to set this based on whether *they* are a
+        # release or develop version, not whether numpy is.) So we continue to
+        # accept 'None' for back-compat, but it's now just an alias for the
+        # default "release".
+        if raise_warnings is None:
+            raise_warnings = "release"
+
+        package_name = None
+        if package is None:
+            f = sys._getframe(1 + depth)
+            package_path = f.f_locals.get('__file__', None)
+            if package_path is None:
+                raise AssertionError
+            package_path = os.path.dirname(package_path)
+            package_name = f.f_locals.get('__name__', None)
+        elif isinstance(package, type(os)):
+            package_path = os.path.dirname(package.__file__)
+            package_name = getattr(package, '__name__', None)
+        else:
+            package_path = str(package)
+
+        self.package_path = package_path
+
+        # Find the package name under test; this name is used to limit coverage
+        # reporting (if enabled).
+        if package_name is None:
+            package_name = get_package_name(package_path)
+        self.package_name = package_name
+
+        # Set to "release" in constructor in maintenance branches.
+        self.raise_warnings = raise_warnings
+
+    def _test_argv(self, label, verbose, extra_argv):
+        ''' Generate argv for nosetest command
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            see ``test`` docstring
+        verbose : int, optional
+            Verbosity value for test outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+
+        Returns
+        -------
+        argv : list
+            command line arguments that will be passed to nose
+        '''
+        argv = [__file__, self.package_path, '-s']
+        if label and label != 'full':
+            if not isinstance(label, basestring):
+                raise TypeError('Selection label should be a string')
+            if label == 'fast':
+                label = 'not slow'
+            argv += ['-A', label]
+        argv += ['--verbosity', str(verbose)]
+
+        # When installing with setuptools, and also in some other cases, the
+        # test_*.py files end up marked +x executable. Nose, by default, does
+        # not run files marked with +x as they might be scripts. However, in
+        # our case nose only looks for test_*.py files under the package
+        # directory, which should be safe.
+        argv += ['--exe']
+
+        if extra_argv:
+            argv += extra_argv
+        return argv
+
+    def _show_system_info(self):
+        nose = import_nose()
+
+        import numpy
+        print("NumPy version %s" % numpy.__version__)
+        relaxed_strides = numpy.ones((10, 1), order="C").flags.f_contiguous
+        print("NumPy relaxed strides checking option:", relaxed_strides)
+        npdir = os.path.dirname(numpy.__file__)
+        print("NumPy is installed in %s" % npdir)
+
+        if 'scipy' in self.package_name:
+            import scipy
+            print("SciPy version %s" % scipy.__version__)
+            spdir = os.path.dirname(scipy.__file__)
+            print("SciPy is installed in %s" % spdir)
+
+        pyversion = sys.version.replace('\n', '')
+        print("Python version %s" % pyversion)
+        print("nose version %d.%d.%d" % nose.__versioninfo__)
+
+    def _get_custom_doctester(self):
+        """ Return instantiated plugin for doctests
+
+        Allows subclassing of this class to override doctester
+
+        A return value of None means use the nose builtin doctest plugin
+        """
+        from .noseclasses import NumpyDoctest
+        return NumpyDoctest()
+
+    def prepare_test_args(self, label='fast', verbose=1, extra_argv=None,
+                          doctests=False, coverage=False):
+        """
+        Run tests for module using nose.
+
+        This method does the heavy lifting for the `test` method. It takes all
+        the same arguments, for details see `test`.
+
+        See Also
+        --------
+        test
+
+        """
+        # fail with nice error message if nose is not present
+        import_nose()
+        # compile argv
+        argv = self._test_argv(label, verbose, extra_argv)
+        # our way of doing coverage
+        if coverage:
+            argv += ['--cover-package=%s' % self.package_name, '--with-coverage',
+                   '--cover-tests', '--cover-erase']
+        # construct list of plugins
+        import nose.plugins.builtin
+        from .noseclasses import KnownFailurePlugin, Unplugger
+        plugins = [KnownFailurePlugin()]
+        plugins += [p() for p in nose.plugins.builtin.plugins]
+        # add doctesting if required
+        doctest_argv = '--with-doctest' in argv
+        if doctests == False and doctest_argv:
+            doctests = True
+        plug = self._get_custom_doctester()
+        if plug is None:
+            # use standard doctesting
+            if doctests and not doctest_argv:
+                argv += ['--with-doctest']
+        else:  # custom doctesting
+            if doctest_argv:  # in fact the unplugger would take care of this
+                argv.remove('--with-doctest')
+            plugins += [Unplugger('doctest'), plug]
+            if doctests:
+                argv += ['--with-' + plug.name]
+        return argv, plugins
+
+    def test(self, label='fast', verbose=1, extra_argv=None,
+            doctests=False, coverage=False,
+            raise_warnings=None):
+        """
+        Run tests for module using nose.
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            Identifies the tests to run. This can be a string to pass to
+            the nosetests executable with the '-A' option, or one of several
+            special values.  Special values are:
+            * 'fast' - the default - which corresponds to the ``nosetests -A``
+              option of 'not slow'.
+            * 'full' - fast (as above) and slow tests as in the
+              'no -A' option to nosetests - this is the same as ''.
+            * None or '' - run all tests.
+            attribute_identifier - string passed directly to nosetests as '-A'.
+        verbose : int, optional
+            Verbosity value for test outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+        doctests : bool, optional
+            If True, run doctests in module. Default is False.
+        coverage : bool, optional
+            If True, report coverage of NumPy code. Default is False.
+            (This requires the `coverage module:
+             <http://nedbatchelder.com/code/modules/coverage.html>`_).
+        raise_warnings : str or sequence of warnings, optional
+            This specifies which warnings to configure as 'raise' instead
+            of 'warn' during the test execution.  Valid strings are:
+
+              - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
+              - "release" : equals ``()``, don't raise on any warnings.
+
+        Returns
+        -------
+        result : object
+            Returns the result of running the tests as a
+            ``nose.result.TextTestResult`` object.
+
+        Notes
+        -----
+        Each NumPy module exposes `test` in its namespace to run all tests for it.
+        For example, to run all tests for numpy.lib:
+
+        >>> np.lib.test() #doctest: +SKIP
+
+        Examples
+        --------
+        >>> result = np.lib.test() #doctest: +SKIP
+        Running unit tests for numpy.lib
+        ...
+        Ran 976 tests in 3.933s
+
+        OK
+
+        >>> result.errors #doctest: +SKIP
+        []
+        >>> result.knownfail #doctest: +SKIP
+        []
+        """
+
+        # cap verbosity at 3 because nose becomes *very* verbose beyond that
+        verbose = min(verbose, 3)
+
+        from . import utils
+        utils.verbose = verbose
+
+        if doctests:
+            print("Running unit tests and doctests for %s" % self.package_name)
+        else:
+            print("Running unit tests for %s" % self.package_name)
+
+        self._show_system_info()
+
+        # reset doctest state on every run
+        import doctest
+        doctest.master = None
+
+        if raise_warnings is None:
+            raise_warnings = self.raise_warnings
+
+        _warn_opts = dict(develop=(DeprecationWarning, RuntimeWarning),
+                          release=())
+        if isinstance(raise_warnings, basestring):
+            raise_warnings = _warn_opts[raise_warnings]
+
+        with warnings.catch_warnings():
+            # Reset the warning filters to the default state,
+            # so that running the tests is more repeatable.
+            warnings.resetwarnings()
+            # Set all warnings to 'warn', this is because the default 'once'
+            # has the bad property of possibly shadowing later warnings.
+            warnings.filterwarnings('always')
+            # Force the requested warnings to raise
+            for warningtype in raise_warnings:
+                warnings.filterwarnings('error', category=warningtype)
+            # Filter out annoying import messages.
+            warnings.filterwarnings('ignore', message='Not importing directory')
+            warnings.filterwarnings("ignore", message="numpy.dtype size changed")
+            warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
+            warnings.filterwarnings("ignore", category=np.ModuleDeprecationWarning)
+            warnings.filterwarnings("ignore", category=FutureWarning)
+            # Filter out boolean '-' deprecation messages. This allows
+            # older versions of scipy to test without a flood of messages.
+            warnings.filterwarnings("ignore", message=".*boolean negative.*")
+            warnings.filterwarnings("ignore", message=".*boolean subtract.*")
+            # Filter out some deprecation warnings inside nose 1.3.7 when run
+            # on python 3.5b2. See
+            #     https://github.com/nose-devs/nose/issues/929
+            warnings.filterwarnings("ignore", message=".*getargspec.*",
+                                    category=DeprecationWarning,
+                                    module="nose\.")
+
+            from .noseclasses import NumpyTestProgram
+
+            argv, plugins = self.prepare_test_args(
+                    label, verbose, extra_argv, doctests, coverage)
+            t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins)
+
+        return t.result
+
+    def bench(self, label='fast', verbose=1, extra_argv=None):
+        """
+        Run benchmarks for module using nose.
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            Identifies the benchmarks to run. This can be a string to pass to
+            the nosetests executable with the '-A' option, or one of several
+            special values.  Special values are:
+            * 'fast' - the default - which corresponds to the ``nosetests -A``
+              option of 'not slow'.
+            * 'full' - fast (as above) and slow benchmarks as in the
+              'no -A' option to nosetests - this is the same as ''.
+            * None or '' - run all tests.
+            attribute_identifier - string passed directly to nosetests as '-A'.
+        verbose : int, optional
+            Verbosity value for benchmark outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+
+        Returns
+        -------
+        success : bool
+            Returns True if running the benchmarks works, False if an error
+            occurred.
+
+        Notes
+        -----
+        Benchmarks are like tests, but have names starting with "bench" instead
+        of "test", and can be found under the "benchmarks" sub-directory of the
+        module.
+
+        Each NumPy module exposes `bench` in its namespace to run all benchmarks
+        for it.
+
+        Examples
+        --------
+        >>> success = np.lib.bench() #doctest: +SKIP
+        Running benchmarks for numpy.lib
+        ...
+        using 562341 items:
+        unique:
+        0.11
+        unique1d:
+        0.11
+        ratio: 1.0
+        nUnique: 56230 == 56230
+        ...
+        OK
+
+        >>> success #doctest: +SKIP
+        True
+
+        """
+
+        print("Running benchmarks for %s" % self.package_name)
+        self._show_system_info()
+
+        argv = self._test_argv(label, verbose, extra_argv)
+        argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep]
+
+        # import nose or make informative error
+        nose = import_nose()
+
+        # get plugin to disable doctests
+        from .noseclasses import Unplugger
+        add_plugins = [Unplugger('doctest')]
+
+        return nose.run(argv=argv, addplugins=add_plugins)
+
+def _numpy_tester():
+    if hasattr(np, "__version__") and ".dev0" in np.__version__:
+        mode = "develop"
+    else:
+        mode = "release"
+    return NoseTester(raise_warnings=mode, depth=1)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
new file mode 100644
index 0000000000..634b8ae542
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2
+"""Prints type-coercion tables for the built-in NumPy types
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+# Generic object that can be added, but doesn't do anything else
+class GenericObject(object):
+    def __init__(self, v):
+        self.v = v
+
+    def __add__(self, other):
+        return self
+
+    def __radd__(self, other):
+        return self
+
+    dtype = np.dtype('O')
+
+def print_cancast_table(ntypes):
+    print('X', end=' ')
+    for char in ntypes:
+        print(char, end=' ')
+    print()
+    for row in ntypes:
+        print(row, end=' ')
+        for col in ntypes:
+            print(int(np.can_cast(row, col)), end=' ')
+        print()
+
+def print_coercion_table(ntypes, inputfirstvalue, inputsecondvalue, firstarray, use_promote_types=False):
+    print('+', end=' ')
+    for char in ntypes:
+        print(char, end=' ')
+    print()
+    for row in ntypes:
+        if row == 'O':
+            rowtype = GenericObject
+        else:
+            rowtype = np.obj2sctype(row)
+
+        print(row, end=' ')
+        for col in ntypes:
+            if col == 'O':
+                coltype = GenericObject
+            else:
+                coltype = np.obj2sctype(col)
+            try:
+                if firstarray:
+                    rowvalue = np.array([rowtype(inputfirstvalue)], dtype=rowtype)
+                else:
+                    rowvalue = rowtype(inputfirstvalue)
+                colvalue = coltype(inputsecondvalue)
+                if use_promote_types:
+                    char = np.promote_types(rowvalue.dtype, colvalue.dtype).char
+                else:
+                    value = np.add(rowvalue, colvalue)
+                    if isinstance(value, np.ndarray):
+                        char = value.dtype.char
+                    else:
+                        char = np.dtype(type(value)).char
+            except ValueError:
+                char = '!'
+            except OverflowError:
+                char = '@'
+            except TypeError:
+                char = '#'
+            print(char, end=' ')
+        print()
+
+print("can cast")
+print_cancast_table(np.typecodes['All'])
+print()
+print("In these tables, ValueError is '!', OverflowError is '@', TypeError is '#'")
+print()
+print("scalar + scalar")
+print_coercion_table(np.typecodes['All'], 0, 0, False)
+print()
+print("scalar + neg scalar")
+print_coercion_table(np.typecodes['All'], 0, -1, False)
+print()
+print("array + scalar")
+print_coercion_table(np.typecodes['All'], 0, 0, True)
+print()
+print("array + neg scalar")
+print_coercion_table(np.typecodes['All'], 0, -1, True)
+print()
+print("promote_types")
+print_coercion_table(np.typecodes['All'], 0, 0, False, True)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/setup.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/setup.py
new file mode 100644
index 0000000000..32c7413aae
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/setup.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('testing', parent_package, top_path)
+
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(maintainer="NumPy Developers",
+          maintainer_email="numpy-dev@numpy.org",
+          description="NumPy test module",
+          url="http://www.numpy.org",
+          license="NumPy License (BSD Style)",
+          configuration=configuration,
+          )
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
new file mode 100644
index 0000000000..7dbb5a8286
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
@@ -0,0 +1,182 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import (dec, assert_, assert_raises, run_module_suite,
+                           SkipTest, KnownFailureException)
+import nose
+
+def test_slow():
+    @dec.slow
+    def slow_func(x, y, z):
+        pass
+
+    assert_(slow_func.slow)
+
+def test_setastest():
+    @dec.setastest()
+    def f_default(a):
+        pass
+
+    @dec.setastest(True)
+    def f_istest(a):
+        pass
+
+    @dec.setastest(False)
+    def f_isnottest(a):
+        pass
+
+    assert_(f_default.__test__)
+    assert_(f_istest.__test__)
+    assert_(not f_isnottest.__test__)
+
+class DidntSkipException(Exception):
+    pass
+
+def test_skip_functions_hardcoded():
+    @dec.skipif(True)
+    def f1(x):
+        raise DidntSkipException
+
+    try:
+        f1('a')
+    except DidntSkipException:
+        raise Exception('Failed to skip')
+    except SkipTest:
+        pass
+
+    @dec.skipif(False)
+    def f2(x):
+        raise DidntSkipException
+
+    try:
+        f2('a')
+    except DidntSkipException:
+        pass
+    except SkipTest:
+        raise Exception('Skipped when not expected to')
+
+
+def test_skip_functions_callable():
+    def skip_tester():
+        return skip_flag == 'skip me!'
+
+    @dec.skipif(skip_tester)
+    def f1(x):
+        raise DidntSkipException
+
+    try:
+        skip_flag = 'skip me!'
+        f1('a')
+    except DidntSkipException:
+        raise Exception('Failed to skip')
+    except SkipTest:
+        pass
+
+    @dec.skipif(skip_tester)
+    def f2(x):
+        raise DidntSkipException
+
+    try:
+        skip_flag = 'five is right out!'
+        f2('a')
+    except DidntSkipException:
+        pass
+    except SkipTest:
+        raise Exception('Skipped when not expected to')
+
+
+def test_skip_generators_hardcoded():
+    @dec.knownfailureif(True, "This test is known to fail")
+    def g1(x):
+        for i in range(x):
+            yield i
+
+    try:
+        for j in g1(10):
+            pass
+    except KnownFailureException:
+        pass
+    else:
+        raise Exception('Failed to mark as known failure')
+
+    @dec.knownfailureif(False, "This test is NOT known to fail")
+    def g2(x):
+        for i in range(x):
+            yield i
+        raise DidntSkipException('FAIL')
+
+    try:
+        for j in g2(10):
+            pass
+    except KnownFailureException:
+        raise Exception('Marked incorretly as known failure')
+    except DidntSkipException:
+        pass
+
+
+def test_skip_generators_callable():
+    def skip_tester():
+        return skip_flag == 'skip me!'
+
+    @dec.knownfailureif(skip_tester, "This test is known to fail")
+    def g1(x):
+        for i in range(x):
+            yield i
+
+    try:
+        skip_flag = 'skip me!'
+        for j in g1(10):
+            pass
+    except KnownFailureException:
+        pass
+    else:
+        raise Exception('Failed to mark as known failure')
+
+    @dec.knownfailureif(skip_tester, "This test is NOT known to fail")
+    def g2(x):
+        for i in range(x):
+            yield i
+        raise DidntSkipException('FAIL')
+
+    try:
+        skip_flag = 'do not skip'
+        for j in g2(10):
+            pass
+    except KnownFailureException:
+        raise Exception('Marked incorretly as known failure')
+    except DidntSkipException:
+        pass
+
+
+def test_deprecated():
+    @dec.deprecated(True)
+    def non_deprecated_func():
+        pass
+
+    @dec.deprecated()
+    def deprecated_func():
+        import warnings
+        warnings.warn("TEST: deprecated func", DeprecationWarning)
+
+    @dec.deprecated()
+    def deprecated_func2():
+        import warnings
+        warnings.warn("AHHHH")
+        raise ValueError
+
+    @dec.deprecated()
+    def deprecated_func3():
+        import warnings
+        warnings.warn("AHHHH")
+
+    # marked as deprecated, but does not raise DeprecationWarning
+    assert_raises(AssertionError, non_deprecated_func)
+    # should be silent
+    deprecated_func()
+    # fails if deprecated decorator just disables test. See #1453.
+    assert_raises(ValueError, deprecated_func2)
+    # first warnings is not a DeprecationWarning
+    assert_raises(AssertionError, deprecated_func3)
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
new file mode 100644
index 0000000000..43f9fb6ceb
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
@@ -0,0 +1,56 @@
+""" Doctests for NumPy-specific nose/doctest modifications
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# try the #random directive on the output line
+def check_random_directive():
+    '''
+    >>> 2+2
+    <BadExample object at 0x084D05AC>  #random: may vary on your system
+    '''
+
+# check the implicit "import numpy as np"
+def check_implicit_np():
+    '''
+    >>> np.array([1,2,3])
+    array([1, 2, 3])
+    '''
+
+# there's some extraneous whitespace around the correct responses
+def check_whitespace_enabled():
+    '''
+    # whitespace after the 3
+    >>> 1+2
+    3
+
+    # whitespace before the 7
+    >>> 3+4
+     7
+    '''
+
+def check_empty_output():
+    """ Check that no output does not cause an error.
+
+    This is related to nose bug 445; the numpy plugin changed the
+    doctest-result-variable default and therefore hit this bug:
+    http://code.google.com/p/python-nose/issues/detail?id=445
+
+    >>> a = 10
+    """
+
+def check_skip():
+    """ Check skip directive
+
+    The test below should not run
+
+    >>> 1/0 #doctest: +SKIP
+    """
+
+
+if __name__ == '__main__':
+    # Run tests outside numpy test rig
+    import nose
+    from numpy.testing.noseclasses import NumpyDoctest
+    argv = ['', __file__, '--with-numpydoctest']
+    nose.core.TestProgram(argv=argv, addplugins=[NumpyDoctest()])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
new file mode 100644
index 0000000000..7de57d4080
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
@@ -0,0 +1,848 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+import os
+
+import numpy as np
+from numpy.testing import (
+    assert_equal, assert_array_equal, assert_almost_equal,
+    assert_array_almost_equal, build_err_msg, raises, assert_raises,
+    assert_warns, assert_no_warnings, assert_allclose, assert_approx_equal,
+    assert_array_almost_equal_nulp, assert_array_max_ulp,
+    clear_and_catch_warnings, run_module_suite,
+    assert_string_equal, assert_, tempdir, temppath, 
+    )
+import unittest
+
+
+class _GenericTest(object):
+
+    def _test_equal(self, a, b):
+        self._assert_func(a, b)
+
+    def _test_not_equal(self, a, b):
+        try:
+            self._assert_func(a, b)
+        except AssertionError:
+            pass
+        else:
+            raise AssertionError("a and b are found equal but are not")
+
+    def test_array_rank1_eq(self):
+        """Test two equal array of rank 1 are found equal."""
+        a = np.array([1, 2])
+        b = np.array([1, 2])
+
+        self._test_equal(a, b)
+
+    def test_array_rank1_noteq(self):
+        """Test two different array of rank 1 are found not equal."""
+        a = np.array([1, 2])
+        b = np.array([2, 2])
+
+        self._test_not_equal(a, b)
+
+    def test_array_rank2_eq(self):
+        """Test two equal array of rank 2 are found equal."""
+        a = np.array([[1, 2], [3, 4]])
+        b = np.array([[1, 2], [3, 4]])
+
+        self._test_equal(a, b)
+
+    def test_array_diffshape(self):
+        """Test two arrays with different shapes are found not equal."""
+        a = np.array([1, 2])
+        b = np.array([[1, 2], [1, 2]])
+
+        self._test_not_equal(a, b)
+
+    def test_objarray(self):
+        """Test object arrays."""
+        a = np.array([1, 1], dtype=np.object)
+        self._test_equal(a, 1)
+
+    def test_array_likes(self):
+        self._test_equal([1, 2, 3], (1, 2, 3))
+
+
+class TestArrayEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_array_equal
+
+    def test_generic_rank1(self):
+        """Test rank 1 array for all dtypes."""
+        def foo(t):
+            a = np.empty(2, t)
+            a.fill(1)
+            b = a.copy()
+            c = a.copy()
+            c.fill(0)
+            self._test_equal(a, b)
+            self._test_not_equal(c, b)
+
+        # Test numeric types and object
+        for t in '?bhilqpBHILQPfdgFDG':
+            foo(t)
+
+        # Test strings
+        for t in ['S1', 'U1']:
+            foo(t)
+
+    def test_generic_rank3(self):
+        """Test rank 3 array for all dtypes."""
+        def foo(t):
+            a = np.empty((4, 2, 3), t)
+            a.fill(1)
+            b = a.copy()
+            c = a.copy()
+            c.fill(0)
+            self._test_equal(a, b)
+            self._test_not_equal(c, b)
+
+        # Test numeric types and object
+        for t in '?bhilqpBHILQPfdgFDG':
+            foo(t)
+
+        # Test strings
+        for t in ['S1', 'U1']:
+            foo(t)
+
+    def test_nan_array(self):
+        """Test arrays with nan values in them."""
+        a = np.array([1, 2, np.nan])
+        b = np.array([1, 2, np.nan])
+
+        self._test_equal(a, b)
+
+        c = np.array([1, 2, 3])
+        self._test_not_equal(c, b)
+
+    def test_string_arrays(self):
+        """Test two arrays with different shapes are found not equal."""
+        a = np.array(['floupi', 'floupa'])
+        b = np.array(['floupi', 'floupa'])
+
+        self._test_equal(a, b)
+
+        c = np.array(['floupipi', 'floupa'])
+
+        self._test_not_equal(c, b)
+
+    def test_recarrays(self):
+        """Test record arrays."""
+        a = np.empty(2, [('floupi', np.float), ('floupa', np.float)])
+        a['floupi'] = [1, 2]
+        a['floupa'] = [1, 2]
+        b = a.copy()
+
+        self._test_equal(a, b)
+
+        c = np.empty(2, [('floupipi', np.float), ('floupa', np.float)])
+        c['floupipi'] = a['floupi'].copy()
+        c['floupa'] = a['floupa'].copy()
+
+        self._test_not_equal(c, b)
+
+
+class TestBuildErrorMessage(unittest.TestCase):
+
+    def test_build_err_msg_defaults(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg)
+        b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([ '
+             '1.00001,  2.00002,  3.00003])\n DESIRED: array([ 1.00002,  '
+             '2.00003,  3.00004])')
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_no_verbose(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, verbose=False)
+        b = '\nItems are not equal: There is a mismatch'
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_custom_names(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, names=('FOO', 'BAR'))
+        b = ('\nItems are not equal: There is a mismatch\n FOO: array([ '
+             '1.00001,  2.00002,  3.00003])\n BAR: array([ 1.00002,  2.00003,  '
+             '3.00004])')
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_custom_precision(self):
+        x = np.array([1.000000001, 2.00002, 3.00003])
+        y = np.array([1.000000002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, precision=10)
+        b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([ '
+             '1.000000001,  2.00002    ,  3.00003    ])\n DESIRED: array([ '
+             '1.000000002,  2.00003    ,  3.00004    ])')
+        self.assertEqual(a, b)
+
+
+class TestEqual(TestArrayEqual):
+
+    def setUp(self):
+        self._assert_func = assert_equal
+
+    def test_nan_items(self):
+        self._assert_func(np.nan, np.nan)
+        self._assert_func([np.nan], [np.nan])
+        self._test_not_equal(np.nan, [np.nan])
+        self._test_not_equal(np.nan, 1)
+
+    def test_inf_items(self):
+        self._assert_func(np.inf, np.inf)
+        self._assert_func([np.inf], [np.inf])
+        self._test_not_equal(np.inf, [np.inf])
+
+    def test_non_numeric(self):
+        self._assert_func('ab', 'ab')
+        self._test_not_equal('ab', 'abb')
+
+    def test_complex_item(self):
+        self._assert_func(complex(1, 2), complex(1, 2))
+        self._assert_func(complex(1, np.nan), complex(1, np.nan))
+        self._test_not_equal(complex(1, np.nan), complex(1, 2))
+        self._test_not_equal(complex(np.nan, 1), complex(1, np.nan))
+        self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2))
+
+    def test_negative_zero(self):
+        self._test_not_equal(np.PZERO, np.NZERO)
+
+    def test_complex(self):
+        x = np.array([complex(1, 2), complex(1, np.nan)])
+        y = np.array([complex(1, 2), complex(1, 2)])
+        self._assert_func(x, x)
+        self._test_not_equal(x, y)
+
+
+class TestArrayAlmostEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_array_almost_equal
+
+    def test_simple(self):
+        x = np.array([1234.2222])
+        y = np.array([1234.2223])
+
+        self._assert_func(x, y, decimal=3)
+        self._assert_func(x, y, decimal=4)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, decimal=5))
+
+    def test_nan(self):
+        anan = np.array([np.nan])
+        aone = np.array([1])
+        ainf = np.array([np.inf])
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+    def test_inf(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        b = a.copy()
+        a[0, 0] = np.inf
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(a, b))
+
+    def test_subclass(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        b = np.ma.masked_array([[1., 2.], [0., 4.]],
+                               [[False, False], [True, False]])
+        assert_array_almost_equal(a, b)
+        assert_array_almost_equal(b, a)
+        assert_array_almost_equal(b, b)
+
+
+class TestAlmostEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_almost_equal
+
+    def test_nan_item(self):
+        self._assert_func(np.nan, np.nan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.nan, 1))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.nan, np.inf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.inf, np.nan))
+
+    def test_inf_item(self):
+        self._assert_func(np.inf, np.inf)
+        self._assert_func(-np.inf, -np.inf)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.inf, 1))
+
+    def test_simple_item(self):
+        self._test_not_equal(1, 2)
+
+    def test_complex_item(self):
+        self._assert_func(complex(1, 2), complex(1, 2))
+        self._assert_func(complex(1, np.nan), complex(1, np.nan))
+        self._assert_func(complex(np.inf, np.nan), complex(np.inf, np.nan))
+        self._test_not_equal(complex(1, np.nan), complex(1, 2))
+        self._test_not_equal(complex(np.nan, 1), complex(1, np.nan))
+        self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2))
+
+    def test_complex(self):
+        x = np.array([complex(1, 2), complex(1, np.nan)])
+        z = np.array([complex(1, 2), complex(np.nan, 1)])
+        y = np.array([complex(1, 2), complex(1, 2)])
+        self._assert_func(x, x)
+        self._test_not_equal(x, y)
+        self._test_not_equal(x, z)
+
+    def test_error_message(self):
+        """Check the message is formatted correctly for the decimal value"""
+        x = np.array([1.00000000001, 2.00000000002, 3.00003])
+        y = np.array([1.00000000002, 2.00000000003, 3.00004])
+
+        # test with a different amount of decimal digits
+        # note that we only check for the formatting of the arrays themselves
+        b = ('x: array([ 1.00000000001,  2.00000000002,  3.00003     '
+             ' ])\n y: array([ 1.00000000002,  2.00000000003,  3.00004      ])')
+        try:
+            self._assert_func(x, y, decimal=12)
+        except AssertionError as e:
+            # remove anything that's not the array string
+            self.assertEqual(str(e).split('%)\n ')[1], b)
+
+        # with the default value of decimal digits, only the 3rd element differs
+        # note that we only check for the formatting of the arrays themselves
+        b = ('x: array([ 1.     ,  2.     ,  3.00003])\n y: array([ 1.     ,  '
+             '2.     ,  3.00004])')
+        try:
+            self._assert_func(x, y)
+        except AssertionError as e:
+            # remove anything that's not the array string
+            self.assertEqual(str(e).split('%)\n ')[1], b)
+
+
+class TestApproxEqual(unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_approx_equal
+
+    def test_simple_arrays(self):
+        x = np.array([1234.22])
+        y = np.array([1234.23])
+
+        self._assert_func(x, y, significant=5)
+        self._assert_func(x, y, significant=6)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, significant=7))
+
+    def test_simple_items(self):
+        x = 1234.22
+        y = 1234.23
+
+        self._assert_func(x, y, significant=4)
+        self._assert_func(x, y, significant=5)
+        self._assert_func(x, y, significant=6)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, significant=7))
+
+    def test_nan_array(self):
+        anan = np.array(np.nan)
+        aone = np.array(1)
+        ainf = np.array(np.inf)
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+    def test_nan_items(self):
+        anan = np.array(np.nan)
+        aone = np.array(1)
+        ainf = np.array(np.inf)
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+
+class TestRaises(unittest.TestCase):
+
+    def setUp(self):
+        class MyException(Exception):
+            pass
+
+        self.e = MyException
+
+    def raises_exception(self, e):
+        raise e
+
+    def does_not_raise_exception(self):
+        pass
+
+    def test_correct_catch(self):
+        raises(self.e)(self.raises_exception)(self.e)  # raises?
+
+    def test_wrong_exception(self):
+        try:
+            raises(self.e)(self.raises_exception)(RuntimeError)  # raises?
+        except RuntimeError:
+            return
+        else:
+            raise AssertionError("should have caught RuntimeError")
+
+    def test_catch_no_raise(self):
+        try:
+            raises(self.e)(self.does_not_raise_exception)()  # raises?
+        except AssertionError:
+            return
+        else:
+            raise AssertionError("should have raised an AssertionError")
+
+
+class TestWarns(unittest.TestCase):
+
+    def test_warn(self):
+        def f():
+            warnings.warn("yo")
+            return 3
+
+        before_filters = sys.modules['warnings'].filters[:]
+        assert_equal(assert_warns(UserWarning, f), 3)
+        after_filters = sys.modules['warnings'].filters
+
+        assert_raises(AssertionError, assert_no_warnings, f)
+        assert_equal(assert_no_warnings(lambda x: x, 1), 1)
+
+        # Check that the warnings state is unchanged
+        assert_equal(before_filters, after_filters,
+                     "assert_warns does not preserver warnings state")
+
+    def test_context_manager(self):
+
+        before_filters = sys.modules['warnings'].filters[:]
+        with assert_warns(UserWarning):
+            warnings.warn("yo")
+        after_filters = sys.modules['warnings'].filters
+
+        def no_warnings():
+            with assert_no_warnings():
+                warnings.warn("yo")
+
+        assert_raises(AssertionError, no_warnings)
+        assert_equal(before_filters, after_filters,
+                     "assert_warns does not preserver warnings state")
+
+    def test_warn_wrong_warning(self):
+        def f():
+            warnings.warn("yo", DeprecationWarning)
+
+        failed = False
+        filters = sys.modules['warnings'].filters[:]
+        try:
+            try:
+                # Should raise an AssertionError
+                assert_warns(UserWarning, f)
+                failed = True
+            except AssertionError:
+                pass
+        finally:
+            sys.modules['warnings'].filters = filters
+
+        if failed:
+            raise AssertionError("wrong warning caught by assert_warn")
+
+
+class TestAssertAllclose(unittest.TestCase):
+    
+    def test_simple(self):
+        x = 1e-3
+        y = 1e-9
+
+        assert_allclose(x, y, atol=1)
+        self.assertRaises(AssertionError, assert_allclose, x, y)
+
+        a = np.array([x, y, x, y])
+        b = np.array([x, y, x, x])
+
+        assert_allclose(a, b, atol=1)
+        self.assertRaises(AssertionError, assert_allclose, a, b)
+
+        b[-1] = y * (1 + 1e-8)
+        assert_allclose(a, b)
+        self.assertRaises(AssertionError, assert_allclose, a, b,
+                          rtol=1e-9)
+
+        assert_allclose(6, 10, rtol=0.5)
+        self.assertRaises(AssertionError, assert_allclose, 10, 6, rtol=0.5)
+
+    def test_min_int(self):
+        a = np.array([np.iinfo(np.int_).min], dtype=np.int_)
+        # Should not raise:
+        assert_allclose(a, a)
+
+    def test_report_fail_percentage(self):
+        a = np.array([1, 1, 1, 1])
+        b = np.array([1, 1, 1, 2])
+        try:
+            assert_allclose(a, b)
+            msg = ''
+        except AssertionError as exc:
+            msg = exc.args[0]
+        self.assertTrue("mismatch 25.0%" in msg)
+
+
+class TestArrayAlmostEqualNulp(unittest.TestCase):
+
+    def test_float64_pass(self):
+        # The number of units of least precision
+        # In this case, use a few places above the lowest level (ie nulp=1)
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        # Addition
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+        # Subtraction
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+    def test_float64_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+    def test_float32_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+    def test_float32_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+    def test_complex128_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        # The test condition needs to be at least a factor of sqrt(2) smaller
+        # because the real and imaginary parts both change
+        y = x + x*eps*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+    def test_complex128_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        # The test condition needs to be at least a factor of sqrt(2) smaller
+        # because the real and imaginary parts both change
+        y = x + x*eps*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+    def test_complex64_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x + x*eps*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+    def test_complex64_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x + x*eps*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+
+class TestULP(unittest.TestCase):
+
+    def test_equal(self):
+        x = np.random.randn(10)
+        assert_array_max_ulp(x, x, maxulp=0)
+
+    def test_single(self):
+        # Generate 1 + small deviation, check that adding eps gives a few UNL
+        x = np.ones(10).astype(np.float32)
+        x += 0.01 * np.random.randn(10).astype(np.float32)
+        eps = np.finfo(np.float32).eps
+        assert_array_max_ulp(x, x+eps, maxulp=20)
+
+    def test_double(self):
+        # Generate 1 + small deviation, check that adding eps gives a few UNL
+        x = np.ones(10).astype(np.float64)
+        x += 0.01 * np.random.randn(10).astype(np.float64)
+        eps = np.finfo(np.float64).eps
+        assert_array_max_ulp(x, x+eps, maxulp=200)
+
+    def test_inf(self):
+        for dt in [np.float32, np.float64]:
+            inf = np.array([np.inf]).astype(dt)
+            big = np.array([np.finfo(dt).max])
+            assert_array_max_ulp(inf, big, maxulp=200)
+
+    def test_nan(self):
+        # Test that nan is 'far' from small, tiny, inf, max and min
+        for dt in [np.float32, np.float64]:
+            if dt == np.float32:
+                maxulp = 1e6
+            else:
+                maxulp = 1e12
+            inf = np.array([np.inf]).astype(dt)
+            nan = np.array([np.nan]).astype(dt)
+            big = np.array([np.finfo(dt).max])
+            tiny = np.array([np.finfo(dt).tiny])
+            zero = np.array([np.PZERO]).astype(dt)
+            nzero = np.array([np.NZERO]).astype(dt)
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, inf,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, big,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, tiny,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, zero,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, nzero,
+                                                               maxulp=maxulp))
+
+class TestStringEqual(unittest.TestCase):
+    def test_simple(self):
+        assert_string_equal("hello", "hello")
+        assert_string_equal("hello\nmultiline", "hello\nmultiline")
+
+        try:
+            assert_string_equal("foo\nbar", "hello\nbar")
+        except AssertionError as exc:
+            assert_equal(str(exc), "Differences in strings:\n- foo\n+ hello")
+        else:
+            raise AssertionError("exception not raised")
+
+        self.assertRaises(AssertionError,
+                          lambda: assert_string_equal("foo", "hello"))
+
+
+def assert_warn_len_equal(mod, n_in_context):
+    mod_warns = mod.__warningregistry__
+    # Python 3.4 appears to clear any pre-existing warnings of the same type,
+    # when raising warnings inside a catch_warnings block. So, there is a
+    # warning generated by the tests within the context manager, but no
+    # previous warnings.
+    if 'version' in mod_warns:
+        assert_equal(len(mod_warns), 2)  # including 'version'
+    else:
+        assert_equal(len(mod_warns), n_in_context)
+
+
+def _get_fresh_mod():
+    # Get this module, with warning registry empty
+    my_mod = sys.modules[__name__]
+    try:
+        my_mod.__warningregistry__.clear()
+    except AttributeError:
+        pass
+    return my_mod
+
+
+def test_clear_and_catch_warnings():
+    # Initial state of module, no warnings
+    my_mod = _get_fresh_mod()
+    assert_equal(getattr(my_mod, '__warningregistry__', {}), {})
+    with clear_and_catch_warnings(modules=[my_mod]):
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_equal(my_mod.__warningregistry__, {})
+    # Without specified modules, don't clear warnings during context
+    with clear_and_catch_warnings():
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_warn_len_equal(my_mod, 1)
+    # Confirm that specifying module keeps old warning, does not add new
+    with clear_and_catch_warnings(modules=[my_mod]):
+        warnings.simplefilter('ignore')
+        warnings.warn('Another warning')
+    assert_warn_len_equal(my_mod, 1)
+    # Another warning, no module spec does add to warnings dict, except on
+    # Python 3.4 (see comments in `assert_warn_len_equal`)
+    with clear_and_catch_warnings():
+        warnings.simplefilter('ignore')
+        warnings.warn('Another warning')
+    assert_warn_len_equal(my_mod, 2)
+
+
+def test_tempdir():
+    with tempdir() as tdir:
+        fpath = os.path.join(tdir, 'tmp')
+        with open(fpath, 'w'):
+            pass
+    assert_(not os.path.isdir(tdir))
+
+    raised = False
+    try:
+        with tempdir() as tdir:
+            raise ValueError()
+    except ValueError:
+        raised = True
+    assert_(raised)
+    assert_(not os.path.isdir(tdir))
+
+
+
+def test_temppath():
+    with temppath() as fpath:
+        with open(fpath, 'w') as f:
+            pass
+    assert_(not os.path.isfile(fpath))
+
+    raised = False
+    try:
+        with temppath() as fpath:
+            raise ValueError()
+    except ValueError:
+        raised = True
+    assert_(raised)
+    assert_(not os.path.isfile(fpath))
+
+
+class my_cacw(clear_and_catch_warnings):
+
+    class_modules = (sys.modules[__name__],)
+
+
+def test_clear_and_catch_warnings_inherit():
+    # Test can subclass and add default modules
+    my_mod = _get_fresh_mod()
+    with my_cacw():
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_equal(my_mod.__warningregistry__, {})
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/utils.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/utils.py
new file mode 100644
index 0000000000..f2588788df
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/testing/utils.py
@@ -0,0 +1,1939 @@
+"""
+Utility function to facilitate testing.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import re
+import operator
+import warnings
+from functools import partial
+import shutil
+import contextlib
+from tempfile import mkdtemp, mkstemp
+
+from .nosetester import import_nose
+from numpy.core import float32, empty, arange, array_repr, ndarray
+from numpy.lib.utils import deprecate
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+__all__ = ['assert_equal', 'assert_almost_equal', 'assert_approx_equal',
+           'assert_array_equal', 'assert_array_less', 'assert_string_equal',
+           'assert_array_almost_equal', 'assert_raises', 'build_err_msg',
+           'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal',
+           'raises', 'rand', 'rundocs', 'runstring', 'verbose', 'measure',
+           'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex',
+           'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings',
+           'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings',
+           'SkipTest', 'KnownFailureException', 'temppath', 'tempdir']
+
+
+class KnownFailureException(Exception):
+    '''Raise this exception to mark a test as a known failing test.'''
+    pass
+
+KnownFailureTest = KnownFailureException  # backwards compat
+
+
+# nose.SkipTest is unittest.case.SkipTest
+# import it into the namespace, so that it's available as np.testing.SkipTest
+try:
+    from unittest.case import SkipTest
+except ImportError:
+    # on py2.6 unittest.case is not available. Ask nose for a replacement.
+    SkipTest = import_nose().SkipTest
+
+
+verbose = 0
+
+def assert_(val, msg=''):
+    """
+    Assert that works in release mode.
+    Accepts callable msg to allow deferring evaluation until failure.
+
+    The Python built-in ``assert`` does not work when executing code in
+    optimized mode (the ``-O`` flag) - no byte-code is generated for it.
+
+    For documentation on usage, refer to the Python documentation.
+
+    """
+    if not val:
+        try:
+            smsg = msg()
+        except TypeError:
+            smsg = msg
+        raise AssertionError(smsg)
+
+def gisnan(x):
+    """like isnan, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isnan and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isnan
+    st = isnan(x)
+    if isinstance(st, type(NotImplemented)):
+        raise TypeError("isnan not supported for this type")
+    return st
+
+def gisfinite(x):
+    """like isfinite, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isfinite and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isfinite, errstate
+    with errstate(invalid='ignore'):
+        st = isfinite(x)
+        if isinstance(st, type(NotImplemented)):
+            raise TypeError("isfinite not supported for this type")
+    return st
+
+def gisinf(x):
+    """like isinf, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isinf and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isinf, errstate
+    with errstate(invalid='ignore'):
+        st = isinf(x)
+        if isinstance(st, type(NotImplemented)):
+            raise TypeError("isinf not supported for this type")
+    return st
+
+@deprecate(message="numpy.testing.rand is deprecated in numpy 1.11. "
+                   "Use numpy.random.rand instead.")
+def rand(*args):
+    """Returns an array of random numbers with the given shape.
+
+    This only uses the standard library, so it is useful for testing purposes.
+    """
+    import random
+    from numpy.core import zeros, float64
+    results = zeros(args, float64)
+    f = results.flat
+    for i in range(len(f)):
+        f[i] = random.random()
+    return results
+
+if os.name == 'nt':
+    # Code "stolen" from enthought/debug/memusage.py
+    def GetPerformanceAttributes(object, counter, instance=None,
+                                 inum=-1, format=None, machine=None):
+        # NOTE: Many counters require 2 samples to give accurate results,
+        # including "% Processor Time" (as by definition, at any instant, a
+        # thread's CPU usage is either 0 or 100).  To read counters like this,
+        # you should copy this function, but keep the counter open, and call
+        # CollectQueryData() each time you need to know.
+        # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
+        # My older explanation for this was that the "AddCounter" process forced
+        # the CPU to 100%, but the above makes more sense :)
+        import win32pdh
+        if format is None:
+            format = win32pdh.PDH_FMT_LONG
+        path = win32pdh.MakeCounterPath( (machine, object, instance, None, inum, counter))
+        hq = win32pdh.OpenQuery()
+        try:
+            hc = win32pdh.AddCounter(hq, path)
+            try:
+                win32pdh.CollectQueryData(hq)
+                type, val = win32pdh.GetFormattedCounterValue(hc, format)
+                return val
+            finally:
+                win32pdh.RemoveCounter(hc)
+        finally:
+            win32pdh.CloseQuery(hq)
+
+    def memusage(processName="python", instance=0):
+        # from win32pdhutil, part of the win32all package
+        import win32pdh
+        return GetPerformanceAttributes("Process", "Virtual Bytes",
+                                        processName, instance,
+                                        win32pdh.PDH_FMT_LONG, None)
+elif sys.platform[:5] == 'linux':
+
+    def memusage(_proc_pid_stat='/proc/%s/stat' % (os.getpid())):
+        """
+        Return virtual memory size in bytes of the running python.
+
+        """
+        try:
+            f = open(_proc_pid_stat, 'r')
+            l = f.readline().split(' ')
+            f.close()
+            return int(l[22])
+        except:
+            return
+else:
+    def memusage():
+        """
+        Return memory usage of running python. [Not implemented]
+
+        """
+        raise NotImplementedError
+
+
+if sys.platform[:5] == 'linux':
+    def jiffies(_proc_pid_stat='/proc/%s/stat' % (os.getpid()),
+                _load_time=[]):
+        """
+        Return number of jiffies elapsed.
+
+        Return number of jiffies (1/100ths of a second) that this
+        process has been scheduled in user mode. See man 5 proc.
+
+        """
+        import time
+        if not _load_time:
+            _load_time.append(time.time())
+        try:
+            f = open(_proc_pid_stat, 'r')
+            l = f.readline().split(' ')
+            f.close()
+            return int(l[13])
+        except:
+            return int(100*(time.time()-_load_time[0]))
+else:
+    # os.getpid is not in all platforms available.
+    # Using time is safe but inaccurate, especially when process
+    # was suspended or sleeping.
+    def jiffies(_load_time=[]):
+        """
+        Return number of jiffies elapsed.
+
+        Return number of jiffies (1/100ths of a second) that this
+        process has been scheduled in user mode. See man 5 proc.
+
+        """
+        import time
+        if not _load_time:
+            _load_time.append(time.time())
+        return int(100*(time.time()-_load_time[0]))
+
+
+def build_err_msg(arrays, err_msg, header='Items are not equal:',
+                  verbose=True, names=('ACTUAL', 'DESIRED'), precision=8):
+    msg = ['\n' + header]
+    if err_msg:
+        if err_msg.find('\n') == -1 and len(err_msg) < 79-len(header):
+            msg = [msg[0] + ' ' + err_msg]
+        else:
+            msg.append(err_msg)
+    if verbose:
+        for i, a in enumerate(arrays):
+
+            if isinstance(a, ndarray):
+                # precision argument is only needed if the objects are ndarrays
+                r_func = partial(array_repr, precision=precision)
+            else:
+                r_func = repr
+
+            try:
+                r = r_func(a)
+            except:
+                r = '[repr failed]'
+            if r.count('\n') > 3:
+                r = '\n'.join(r.splitlines()[:3])
+                r += '...'
+            msg.append(' %s: %s' % (names[i], r))
+    return '\n'.join(msg)
+
+def assert_equal(actual,desired,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal.
+
+    Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
+    check that all elements of these objects are equal. An exception is raised
+    at the first conflicting values.
+
+    Parameters
+    ----------
+    actual : array_like
+        The object to check.
+    desired : array_like
+        The expected object.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal.
+
+    Examples
+    --------
+    >>> np.testing.assert_equal([4,5], [4,6])
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal:
+    item=1
+     ACTUAL: 5
+     DESIRED: 6
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        assert_equal(len(actual), len(desired), err_msg, verbose)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError(repr(k))
+            assert_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg), verbose)
+        return
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        assert_equal(len(actual), len(desired), err_msg, verbose)
+        for k in range(len(desired)):
+            assert_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg), verbose)
+        return
+    from numpy.core import ndarray, isscalar, signbit
+    from numpy.lib import iscomplexobj, real, imag
+    if isinstance(actual, ndarray) or isinstance(desired, ndarray):
+        return assert_array_equal(actual, desired, err_msg, verbose)
+    msg = build_err_msg([actual, desired], err_msg, verbose=verbose)
+
+    # Handle complex numbers: separate into real/imag to handle
+    # nan/inf/negative zero correctly
+    # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
+    try:
+        usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
+    except ValueError:
+        usecomplex = False
+
+    if usecomplex:
+        if iscomplexobj(actual):
+            actualr = real(actual)
+            actuali = imag(actual)
+        else:
+            actualr = actual
+            actuali = 0
+        if iscomplexobj(desired):
+            desiredr = real(desired)
+            desiredi = imag(desired)
+        else:
+            desiredr = desired
+            desiredi = 0
+        try:
+            assert_equal(actualr, desiredr)
+            assert_equal(actuali, desiredi)
+        except AssertionError:
+            raise AssertionError(msg)
+
+    # Inf/nan/negative zero handling
+    try:
+        # isscalar test to check cases such as [np.nan] != np.nan
+        if isscalar(desired) != isscalar(actual):
+            raise AssertionError(msg)
+
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            isdesnan = gisnan(desired)
+            isactnan = gisnan(actual)
+            if isdesnan or isactnan:
+                if not (isdesnan and isactnan):
+                    raise AssertionError(msg)
+            else:
+                if not desired == actual:
+                    raise AssertionError(msg)
+            return
+        elif desired == 0 and actual == 0:
+            if not signbit(desired) == signbit(actual):
+                raise AssertionError(msg)
+    # If TypeError or ValueError raised while using isnan and co, just handle
+    # as before
+    except (TypeError, ValueError, NotImplementedError):
+        pass
+
+    # Explicitly use __eq__ for comparison, ticket #2552
+    if not (desired == actual):
+        raise AssertionError(msg)
+
+def print_assert_equal(test_string, actual, desired):
+    """
+    Test if two objects are equal, and print an error message if test fails.
+
+    The test is performed with ``actual == desired``.
+
+    Parameters
+    ----------
+    test_string : str
+        The message supplied to AssertionError.
+    actual : object
+        The object to test for equality against `desired`.
+    desired : object
+        The expected result.
+
+    Examples
+    --------
+    >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1])
+    >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 2])
+    Traceback (most recent call last):
+    ...
+    AssertionError: Test XYZ of func xyz failed
+    ACTUAL:
+    [0, 1]
+    DESIRED:
+    [0, 2]
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import pprint
+
+    if not (actual == desired):
+        msg = StringIO()
+        msg.write(test_string)
+        msg.write(' failed\nACTUAL: \n')
+        pprint.pprint(actual, msg)
+        msg.write('DESIRED: \n')
+        pprint.pprint(desired, msg)
+        raise AssertionError(msg.getvalue())
+
+def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two items are not equal up to desired
+    precision.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    The test is equivalent to ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
+
+    Given two objects (numbers or ndarrays), check that all elements of these
+    objects are almost equal. An exception is raised at conflicting values.
+    For ndarrays this delegates to assert_array_almost_equal
+
+    Parameters
+    ----------
+    actual : array_like
+        The object to check.
+    desired : array_like
+        The expected object.
+    decimal : int, optional
+        Desired precision, default is 7.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    >>> import numpy.testing as npt
+    >>> npt.assert_almost_equal(2.3333333333333, 2.33333334)
+    >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal:
+     ACTUAL: 2.3333333333333002
+     DESIRED: 2.3333333399999998
+
+    >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]),
+    ...                         np.array([1.0,2.33333334]), decimal=9)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Arrays are not almost equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.        ,  2.33333333])
+     y: array([ 1.        ,  2.33333334])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import ndarray
+    from numpy.lib import iscomplexobj, real, imag
+
+    # Handle complex numbers: separate into real/imag to handle
+    # nan/inf/negative zero correctly
+    # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
+    try:
+        usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
+    except ValueError:
+        usecomplex = False
+
+    def _build_err_msg():
+        header = ('Arrays are not almost equal to %d decimals' % decimal)
+        return build_err_msg([actual, desired], err_msg, verbose=verbose,
+                             header=header)
+
+    if usecomplex:
+        if iscomplexobj(actual):
+            actualr = real(actual)
+            actuali = imag(actual)
+        else:
+            actualr = actual
+            actuali = 0
+        if iscomplexobj(desired):
+            desiredr = real(desired)
+            desiredi = imag(desired)
+        else:
+            desiredr = desired
+            desiredi = 0
+        try:
+            assert_almost_equal(actualr, desiredr, decimal=decimal)
+            assert_almost_equal(actuali, desiredi, decimal=decimal)
+        except AssertionError:
+            raise AssertionError(_build_err_msg())
+
+    if isinstance(actual, (ndarray, tuple, list)) \
+            or isinstance(desired, (ndarray, tuple, list)):
+        return assert_array_almost_equal(actual, desired, decimal, err_msg)
+    try:
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            if gisnan(desired) or gisnan(actual):
+                if not (gisnan(desired) and gisnan(actual)):
+                    raise AssertionError(_build_err_msg())
+            else:
+                if not desired == actual:
+                    raise AssertionError(_build_err_msg())
+            return
+    except (NotImplementedError, TypeError):
+        pass
+    if round(abs(desired - actual), decimal) != 0:
+        raise AssertionError(_build_err_msg())
+
+
+def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two items are not equal up to significant
+    digits.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    Given two numbers, check that they are approximately equal.
+    Approximately equal is defined as the number of significant digits
+    that agree.
+
+    Parameters
+    ----------
+    actual : scalar
+        The object to check.
+    desired : scalar
+        The expected object.
+    significant : int, optional
+        Desired precision, default is 7.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    >>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20)
+    >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20,
+                                       significant=8)
+    >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20,
+                                       significant=8)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal to 8 significant digits:
+     ACTUAL: 1.234567e-021
+     DESIRED: 1.2345672000000001e-021
+
+    the evaluated condition that raises the exception is
+
+    >>> abs(0.12345670e-20/1e-21 - 0.12345672e-20/1e-21) >= 10**-(8-1)
+    True
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+
+    (actual, desired) = map(float, (actual, desired))
+    if desired == actual:
+        return
+    # Normalized the numbers to be in range (-10.0,10.0)
+    # scale = float(pow(10,math.floor(math.log10(0.5*(abs(desired)+abs(actual))))))
+    with np.errstate(invalid='ignore'):
+        scale = 0.5*(np.abs(desired) + np.abs(actual))
+        scale = np.power(10, np.floor(np.log10(scale)))
+    try:
+        sc_desired = desired/scale
+    except ZeroDivisionError:
+        sc_desired = 0.0
+    try:
+        sc_actual = actual/scale
+    except ZeroDivisionError:
+        sc_actual = 0.0
+    msg = build_err_msg([actual, desired], err_msg,
+                header='Items are not equal to %d significant digits:' %
+                                 significant,
+                verbose=verbose)
+    try:
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            if gisnan(desired) or gisnan(actual):
+                if not (gisnan(desired) and gisnan(actual)):
+                    raise AssertionError(msg)
+            else:
+                if not desired == actual:
+                    raise AssertionError(msg)
+            return
+    except (TypeError, NotImplementedError):
+        pass
+    if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant-1)):
+        raise AssertionError(msg)
+
+def assert_array_compare(comparison, x, y, err_msg='', verbose=True,
+                         header='', precision=6):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import array, isnan, isinf, any, all, inf
+    x = array(x, copy=False, subok=True)
+    y = array(y, copy=False, subok=True)
+
+    def safe_comparison(*args, **kwargs):
+        # There are a number of cases where comparing two arrays hits special
+        # cases in array_richcompare, specifically around strings and void
+        # dtypes. Basically, we just can't do comparisons involving these
+        # types, unless both arrays have exactly the *same* type. So
+        # e.g. you can apply == to two string arrays, or two arrays with
+        # identical structured dtypes. But if you compare a non-string array
+        # to a string array, or two arrays with non-identical structured
+        # dtypes, or anything like that, then internally stuff blows up.
+        # Currently, when things blow up, we just return a scalar False or
+        # True. But we also emit a DeprecationWarning, b/c eventually we
+        # should raise an error here. (Ideally we might even make this work
+        # properly, but since that will require rewriting a bunch of how
+        # ufuncs work then we are not counting on that.)
+        #
+        # The point of this little function is to let the DeprecationWarning
+        # pass (or maybe eventually catch the errors and return False, I
+        # dunno, that's a little trickier and we can figure that out when the
+        # time comes).
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            return comparison(*args, **kwargs)
+
+    def isnumber(x):
+        return x.dtype.char in '?bhilqpBHILQPefdgFDG'
+
+    def chk_same_position(x_id, y_id, hasval='nan'):
+        """Handling nan/inf: check that x and y have the nan/inf at the same
+        locations."""
+        try:
+            assert_array_equal(x_id, y_id)
+        except AssertionError:
+            msg = build_err_msg([x, y],
+                                err_msg + '\nx and y %s location mismatch:'
+                                % (hasval), verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            raise AssertionError(msg)
+
+    try:
+        cond = (x.shape == () or y.shape == ()) or x.shape == y.shape
+        if not cond:
+            msg = build_err_msg([x, y],
+                                err_msg
+                                + '\n(shapes %s, %s mismatch)' % (x.shape,
+                                                                  y.shape),
+                                verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            if not cond:
+                raise AssertionError(msg)
+
+        if isnumber(x) and isnumber(y):
+            x_isnan, y_isnan = isnan(x), isnan(y)
+            x_isinf, y_isinf = isinf(x), isinf(y)
+
+            # Validate that the special values are in the same place
+            if any(x_isnan) or any(y_isnan):
+                chk_same_position(x_isnan, y_isnan, hasval='nan')
+            if any(x_isinf) or any(y_isinf):
+                # Check +inf and -inf separately, since they are different
+                chk_same_position(x == +inf, y == +inf, hasval='+inf')
+                chk_same_position(x == -inf, y == -inf, hasval='-inf')
+
+            # Combine all the special values
+            x_id, y_id = x_isnan, y_isnan
+            x_id |= x_isinf
+            y_id |= y_isinf
+
+            # Only do the comparison if actual values are left
+            if all(x_id):
+                return
+
+            if any(x_id):
+                val = safe_comparison(x[~x_id], y[~y_id])
+            else:
+                val = safe_comparison(x, y)
+        else:
+            val = safe_comparison(x, y)
+
+        if isinstance(val, bool):
+            cond = val
+            reduced = [0]
+        else:
+            reduced = val.ravel()
+            cond = reduced.all()
+            reduced = reduced.tolist()
+        if not cond:
+            match = 100-100.0*reduced.count(1)/len(reduced)
+            msg = build_err_msg([x, y],
+                                err_msg
+                                + '\n(mismatch %s%%)' % (match,),
+                                verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            if not cond:
+                raise AssertionError(msg)
+    except ValueError:
+        import traceback
+        efmt = traceback.format_exc()
+        header = 'error during assertion:\n\n%s\n\n%s' % (efmt, header)
+
+        msg = build_err_msg([x, y], err_msg, verbose=verbose, header=header,
+                            names=('x', 'y'), precision=precision)
+        raise ValueError(msg)
+
+def assert_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two array_like objects are not equal.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of these objects are equal. An exception is raised at
+    shape mismatch or conflicting values. In contrast to the standard usage
+    in numpy, NaNs are compared like numbers, no assertion is raised if
+    both objects have NaNs in the same positions.
+
+    The usual caution for verifying equality with floating point numbers is
+    advised.
+
+    Parameters
+    ----------
+    x : array_like
+        The actual object to check.
+    y : array_like
+        The desired, expected object.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired objects are not equal.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    The first assert does not raise an exception:
+
+    >>> np.testing.assert_array_equal([1.0,2.33333,np.nan],
+    ...                               [np.exp(0),2.33333, np.nan])
+
+    Assert fails with numerical inprecision with floats:
+
+    >>> np.testing.assert_array_equal([1.0,np.pi,np.nan],
+    ...                               [1, np.sqrt(np.pi)**2, np.nan])
+    ...
+    <type 'exceptions.ValueError'>:
+    AssertionError:
+    Arrays are not equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.        ,  3.14159265,         NaN])
+     y: array([ 1.        ,  3.14159265,         NaN])
+
+    Use `assert_allclose` or one of the nulp (number of floating point values)
+    functions for these cases instead:
+
+    >>> np.testing.assert_allclose([1.0,np.pi,np.nan],
+    ...                            [1, np.sqrt(np.pi)**2, np.nan],
+    ...                            rtol=1e-10, atol=0)
+
+    """
+    assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
+                         verbose=verbose, header='Arrays are not equal')
+
+def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal up to desired
+    precision.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    The test verifies identical shapes and verifies values with
+    ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of these objects are almost equal. An exception is raised at
+    shape mismatch or conflicting values. In contrast to the standard usage
+    in numpy, NaNs are compared like numbers, no assertion is raised if
+    both objects have NaNs in the same positions.
+
+    Parameters
+    ----------
+    x : array_like
+        The actual object to check.
+    y : array_like
+        The desired, expected object.
+    decimal : int, optional
+        Desired precision, default is 6.
+    err_msg : str, optional
+      The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    the first assert does not raise an exception
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan],
+                                             [1.0,2.333,np.nan])
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
+    ...                                      [1.0,2.33339,np.nan], decimal=5)
+    ...
+    <type 'exceptions.AssertionError'>:
+    AssertionError:
+    Arrays are not almost equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.     ,  2.33333,      NaN])
+     y: array([ 1.     ,  2.33339,      NaN])
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
+    ...                                      [1.0,2.33333, 5], decimal=5)
+    <type 'exceptions.ValueError'>:
+    ValueError:
+    Arrays are not almost equal
+     x: array([ 1.     ,  2.33333,      NaN])
+     y: array([ 1.     ,  2.33333,  5.     ])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import around, number, float_, result_type, array
+    from numpy.core.numerictypes import issubdtype
+    from numpy.core.fromnumeric import any as npany
+
+    def compare(x, y):
+        try:
+            if npany(gisinf(x)) or npany( gisinf(y)):
+                xinfid = gisinf(x)
+                yinfid = gisinf(y)
+                if not xinfid == yinfid:
+                    return False
+                # if one item, x and y is +- inf
+                if x.size == y.size == 1:
+                    return x == y
+                x = x[~xinfid]
+                y = y[~yinfid]
+        except (TypeError, NotImplementedError):
+            pass
+
+        # make sure y is an inexact type to avoid abs(MIN_INT); will cause
+        # casting of x later.
+        dtype = result_type(y, 1.)
+        y = array(y, dtype=dtype, copy=False, subok=True)
+        z = abs(x-y)
+
+        if not issubdtype(z.dtype, number):
+            z = z.astype(float_)  # handle object arrays
+
+        return around(z, decimal) <= 10.0**(-decimal)
+
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+             header=('Arrays are not almost equal to %d decimals' % decimal),
+             precision=decimal)
+
+
+def assert_array_less(x, y, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two array_like objects are not ordered by less
+    than.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of the first object are strictly smaller than those of the
+    second object. An exception is raised at shape mismatch or incorrectly
+    ordered values. Shape mismatch does not raise if an object has zero
+    dimension. In contrast to the standard usage in numpy, NaNs are
+    compared, no assertion is raised if both objects have NaNs in the same
+    positions.
+
+
+
+    Parameters
+    ----------
+    x : array_like
+      The smaller object to check.
+    y : array_like
+      The larger object to compare.
+    err_msg : string
+      The error message to be printed in case of failure.
+    verbose : bool
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired objects are not equal.
+
+    See Also
+    --------
+    assert_array_equal: tests objects for equality
+    assert_array_almost_equal: test objects for equality up to precision
+
+
+
+    Examples
+    --------
+    >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan])
+    >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan])
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (mismatch 50.0%)
+     x: array([  1.,   1.,  NaN])
+     y: array([  1.,   2.,  NaN])
+
+    >>> np.testing.assert_array_less([1.0, 4.0], 3)
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (mismatch 50.0%)
+     x: array([ 1.,  4.])
+     y: array(3)
+
+    >>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4])
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (shapes (3,), (1,) mismatch)
+     x: array([ 1.,  2.,  3.])
+     y: array([4])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    assert_array_compare(operator.__lt__, x, y, err_msg=err_msg,
+                         verbose=verbose,
+                         header='Arrays are not less-ordered')
+
+def runstring(astr, dict):
+    exec(astr, dict)
+
+def assert_string_equal(actual, desired):
+    """
+    Test if two strings are equal.
+
+    If the given strings are equal, `assert_string_equal` does nothing.
+    If they are not equal, an AssertionError is raised, and the diff
+    between the strings is shown.
+
+    Parameters
+    ----------
+    actual : str
+        The string to test for equality against the expected string.
+    desired : str
+        The expected string.
+
+    Examples
+    --------
+    >>> np.testing.assert_string_equal('abc', 'abc')
+    >>> np.testing.assert_string_equal('abc', 'abcd')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ...
+    AssertionError: Differences in strings:
+    - abc+ abcd?    +
+
+    """
+    # delay import of difflib to reduce startup time
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import difflib
+
+    if not isinstance(actual, str):
+        raise AssertionError(repr(type(actual)))
+    if not isinstance(desired, str):
+        raise AssertionError(repr(type(desired)))
+    if re.match(r'\A'+desired+r'\Z', actual, re.M):
+        return
+
+    diff = list(difflib.Differ().compare(actual.splitlines(1), desired.splitlines(1)))
+    diff_list = []
+    while diff:
+        d1 = diff.pop(0)
+        if d1.startswith('  '):
+            continue
+        if d1.startswith('- '):
+            l = [d1]
+            d2 = diff.pop(0)
+            if d2.startswith('? '):
+                l.append(d2)
+                d2 = diff.pop(0)
+            if not d2.startswith('+ '):
+                raise AssertionError(repr(d2))
+            l.append(d2)
+            if diff:
+                d3 = diff.pop(0)
+                if d3.startswith('? '):
+                    l.append(d3)
+                else:
+                    diff.insert(0, d3)
+            if re.match(r'\A'+d2[2:]+r'\Z', d1[2:]):
+                continue
+            diff_list.extend(l)
+            continue
+        raise AssertionError(repr(d1))
+    if not diff_list:
+        return
+    msg = 'Differences in strings:\n%s' % (''.join(diff_list)).rstrip()
+    if actual != desired:
+        raise AssertionError(msg)
+
+
+def rundocs(filename=None, raise_on_error=True):
+    """
+    Run doctests found in the given file.
+
+    By default `rundocs` raises an AssertionError on failure.
+
+    Parameters
+    ----------
+    filename : str
+        The path to the file for which the doctests are run.
+    raise_on_error : bool
+        Whether to raise an AssertionError when a doctest fails. Default is
+        True.
+
+    Notes
+    -----
+    The doctests can be run by the user/developer by adding the ``doctests``
+    argument to the ``test()`` call. For example, to run all tests (including
+    doctests) for `numpy.lib`:
+
+    >>> np.lib.test(doctests=True) #doctest: +SKIP
+    """
+    import doctest
+    import imp
+    if filename is None:
+        f = sys._getframe(1)
+        filename = f.f_globals['__file__']
+    name = os.path.splitext(os.path.basename(filename))[0]
+    path = [os.path.dirname(filename)]
+    file, pathname, description = imp.find_module(name, path)
+    try:
+        m = imp.load_module(name, file, pathname, description)
+    finally:
+        file.close()
+
+    tests = doctest.DocTestFinder().find(m)
+    runner = doctest.DocTestRunner(verbose=False)
+
+    msg = []
+    if raise_on_error:
+        out = lambda s: msg.append(s)
+    else:
+        out = None
+
+    for test in tests:
+        runner.run(test, out=out)
+
+    if runner.failures > 0 and raise_on_error:
+        raise AssertionError("Some doctests failed:\n%s" % "\n".join(msg))
+
+
+def raises(*args,**kwargs):
+    nose = import_nose()
+    return nose.tools.raises(*args,**kwargs)
+
+
+def assert_raises(*args,**kwargs):
+    """
+    assert_raises(exception_class, callable, *args, **kwargs)
+
+    Fail unless an exception of class exception_class is thrown
+    by callable when invoked with arguments args and keyword
+    arguments kwargs. If a different type of exception is
+    thrown, it will not be caught, and the test case will be
+    deemed to have suffered an error, exactly as for an
+    unexpected exception.
+
+    Alternatively, `assert_raises` can be used as a context manager:
+
+    >>> from numpy.testing import assert_raises
+    >>> with assert_raises(ZeroDivisionError):
+    ...   1 / 0
+
+    is equivalent to
+
+    >>> def div(x, y):
+    ...    return x / y
+    >>> assert_raises(ZeroDivisionError, div, 1, 0)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    nose = import_nose()
+    return nose.tools.assert_raises(*args,**kwargs)
+
+
+assert_raises_regex_impl = None
+
+
+def assert_raises_regex(exception_class, expected_regexp,
+                        callable_obj=None, *args, **kwargs):
+    """
+    Fail unless an exception of class exception_class and with message that
+    matches expected_regexp is thrown by callable when invoked with arguments
+    args and keyword arguments kwargs.
+
+    Name of this function adheres to Python 3.2+ reference, but should work in
+    all versions down to 2.6.
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    nose = import_nose()
+
+    global assert_raises_regex_impl
+    if assert_raises_regex_impl is None:
+        try:
+            # Python 3.2+
+            assert_raises_regex_impl = nose.tools.assert_raises_regex
+        except AttributeError:
+            try:
+                # 2.7+
+                assert_raises_regex_impl = nose.tools.assert_raises_regexp
+            except AttributeError:
+                # 2.6
+
+                # This class is copied from Python2.7 stdlib almost verbatim
+                class _AssertRaisesContext(object):
+                    """A context manager used to implement TestCase.assertRaises* methods."""
+
+                    def __init__(self, expected, expected_regexp=None):
+                        self.expected = expected
+                        self.expected_regexp = expected_regexp
+
+                    def failureException(self, msg):
+                        return AssertionError(msg)
+
+                    def __enter__(self):
+                        return self
+
+                    def __exit__(self, exc_type, exc_value, tb):
+                        if exc_type is None:
+                            try:
+                                exc_name = self.expected.__name__
+                            except AttributeError:
+                                exc_name = str(self.expected)
+                            raise self.failureException(
+                                "{0} not raised".format(exc_name))
+                        if not issubclass(exc_type, self.expected):
+                            # let unexpected exceptions pass through
+                            return False
+                        self.exception = exc_value  # store for later retrieval
+                        if self.expected_regexp is None:
+                            return True
+
+                        expected_regexp = self.expected_regexp
+                        if isinstance(expected_regexp, basestring):
+                            expected_regexp = re.compile(expected_regexp)
+                        if not expected_regexp.search(str(exc_value)):
+                            raise self.failureException(
+                                '"%s" does not match "%s"' %
+                                (expected_regexp.pattern, str(exc_value)))
+                        return True
+
+                def impl(cls, regex, callable_obj, *a, **kw):
+                    mgr = _AssertRaisesContext(cls, regex)
+                    if callable_obj is None:
+                        return mgr
+                    with mgr:
+                        callable_obj(*a, **kw)
+                assert_raises_regex_impl = impl
+
+    return assert_raises_regex_impl(exception_class, expected_regexp,
+                                    callable_obj, *args, **kwargs)
+
+
+def decorate_methods(cls, decorator, testmatch=None):
+    """
+    Apply a decorator to all methods in a class matching a regular expression.
+
+    The given decorator is applied to all public methods of `cls` that are
+    matched by the regular expression `testmatch`
+    (``testmatch.search(methodname)``). Methods that are private, i.e. start
+    with an underscore, are ignored.
+
+    Parameters
+    ----------
+    cls : class
+        Class whose methods to decorate.
+    decorator : function
+        Decorator to apply to methods
+    testmatch : compiled regexp or str, optional
+        The regular expression. Default value is None, in which case the
+        nose default (``re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)``)
+        is used.
+        If `testmatch` is a string, it is compiled to a regular expression
+        first.
+
+    """
+    if testmatch is None:
+        testmatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
+    else:
+        testmatch = re.compile(testmatch)
+    cls_attr = cls.__dict__
+
+    # delayed import to reduce startup time
+    from inspect import isfunction
+
+    methods = [_m for _m in cls_attr.values() if isfunction(_m)]
+    for function in methods:
+        try:
+            if hasattr(function, 'compat_func_name'):
+                funcname = function.compat_func_name
+            else:
+                funcname = function.__name__
+        except AttributeError:
+            # not a function
+            continue
+        if testmatch.search(funcname) and not funcname.startswith('_'):
+            setattr(cls, funcname, decorator(function))
+    return
+
+
+def measure(code_str,times=1,label=None):
+    """
+    Return elapsed time for executing code in the namespace of the caller.
+
+    The supplied code string is compiled with the Python builtin ``compile``.
+    The precision of the timing is 10 milli-seconds. If the code will execute
+    fast on this timescale, it can be executed many times to get reasonable
+    timing accuracy.
+
+    Parameters
+    ----------
+    code_str : str
+        The code to be timed.
+    times : int, optional
+        The number of times the code is executed. Default is 1. The code is
+        only compiled once.
+    label : str, optional
+        A label to identify `code_str` with. This is passed into ``compile``
+        as the second argument (for run-time error messages).
+
+    Returns
+    -------
+    elapsed : float
+        Total elapsed time in seconds for executing `code_str` `times` times.
+
+    Examples
+    --------
+    >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)',
+    ...                            times=times)
+    >>> print("Time for a single execution : ", etime / times, "s")
+    Time for a single execution :  0.005 s
+
+    """
+    frame = sys._getframe(1)
+    locs, globs = frame.f_locals, frame.f_globals
+
+    code = compile(code_str,
+                   'Test name: %s ' % label,
+                   'exec')
+    i = 0
+    elapsed = jiffies()
+    while i < times:
+        i += 1
+        exec(code, globs, locs)
+    elapsed = jiffies() - elapsed
+    return 0.01*elapsed
+
+
+def _assert_valid_refcount(op):
+    """
+    Check that ufuncs don't mishandle refcount of object `1`.
+    Used in a few regression tests.
+    """
+    import numpy as np
+
+    b = np.arange(100*100).reshape(100, 100)
+    c = b
+    i = 1
+
+    rc = sys.getrefcount(i)
+    for j in range(15):
+        d = op(b, c)
+    assert_(sys.getrefcount(i) >= rc)
+    del d  # for pyflakes
+
+
+def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=False,
+                    err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal up to desired
+    tolerance.
+
+    The test is equivalent to ``allclose(actual, desired, rtol, atol)``.
+    It compares the difference between `actual` and `desired` to
+    ``atol + rtol * abs(desired)``.
+
+    .. versionadded:: 1.5.0
+
+    Parameters
+    ----------
+    actual : array_like
+        Array obtained.
+    desired : array_like
+        Array desired.
+    rtol : float, optional
+        Relative tolerance.
+    atol : float, optional
+        Absolute tolerance.
+    equal_nan : bool, optional.
+        If True, NaNs will compare equal.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_array_almost_equal_nulp, assert_array_max_ulp
+
+    Examples
+    --------
+    >>> x = [1e-5, 1e-3, 1e-1]
+    >>> y = np.arccos(np.cos(x))
+    >>> assert_allclose(x, y, rtol=1e-5, atol=0)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+
+    def compare(x, y):
+        return np.core.numeric.isclose(x, y, rtol=rtol, atol=atol,
+                                       equal_nan=equal_nan)
+
+    actual, desired = np.asanyarray(actual), np.asanyarray(desired)
+    header = 'Not equal to tolerance rtol=%g, atol=%g' % (rtol, atol)
+    assert_array_compare(compare, actual, desired, err_msg=str(err_msg),
+                         verbose=verbose, header=header)
+
+def assert_array_almost_equal_nulp(x, y, nulp=1):
+    """
+    Compare two arrays relatively to their spacing.
+
+    This is a relatively robust method to compare two arrays whose amplitude
+    is variable.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Input arrays.
+    nulp : int, optional
+        The maximum number of unit in the last place for tolerance (see Notes).
+        Default is 1.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    AssertionError
+        If the spacing between `x` and `y` for one or more elements is larger
+        than `nulp`.
+
+    See Also
+    --------
+    assert_array_max_ulp : Check that all items of arrays differ in at most
+        N Units in the Last Place.
+    spacing : Return the distance between x and the nearest adjacent number.
+
+    Notes
+    -----
+    An assertion is raised if the following condition is not met::
+
+        abs(x - y) <= nulps * spacing(maximum(abs(x), abs(y)))
+
+    Examples
+    --------
+    >>> x = np.array([1., 1e-10, 1e-20])
+    >>> eps = np.finfo(x.dtype).eps
+    >>> np.testing.assert_array_almost_equal_nulp(x, x*eps/2 + x)
+
+    >>> np.testing.assert_array_almost_equal_nulp(x, x*eps + x)
+    Traceback (most recent call last):
+      ...
+    AssertionError: X and Y are not equal to 1 ULP (max is 2)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+    ax = np.abs(x)
+    ay = np.abs(y)
+    ref = nulp * np.spacing(np.where(ax > ay, ax, ay))
+    if not np.all(np.abs(x-y) <= ref):
+        if np.iscomplexobj(x) or np.iscomplexobj(y):
+            msg = "X and Y are not equal to %d ULP" % nulp
+        else:
+            max_nulp = np.max(nulp_diff(x, y))
+            msg = "X and Y are not equal to %d ULP (max is %g)" % (nulp, max_nulp)
+        raise AssertionError(msg)
+
+def assert_array_max_ulp(a, b, maxulp=1, dtype=None):
+    """
+    Check that all items of arrays differ in at most N Units in the Last Place.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to be compared.
+    maxulp : int, optional
+        The maximum number of units in the last place that elements of `a` and
+        `b` can differ. Default is 1.
+    dtype : dtype, optional
+        Data-type to convert `a` and `b` to if given. Default is None.
+
+    Returns
+    -------
+    ret : ndarray
+        Array containing number of representable floating point numbers between
+        items in `a` and `b`.
+
+    Raises
+    ------
+    AssertionError
+        If one or more elements differ by more than `maxulp`.
+
+    See Also
+    --------
+    assert_array_almost_equal_nulp : Compare two arrays relatively to their
+        spacing.
+
+    Examples
+    --------
+    >>> a = np.linspace(0., 1., 100)
+    >>> res = np.testing.assert_array_max_ulp(a, np.arcsin(np.sin(a)))
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+    ret = nulp_diff(a, b, dtype)
+    if not np.all(ret <= maxulp):
+        raise AssertionError("Arrays are not almost equal up to %g ULP" %
+                             maxulp)
+    return ret
+
+def nulp_diff(x, y, dtype=None):
+    """For each item in x and y, return the number of representable floating
+    points between them.
+
+    Parameters
+    ----------
+    x : array_like
+        first input array
+    y : array_like
+        second input array
+    dtype : dtype, optional
+        Data-type to convert `x` and `y` to if given. Default is None.
+
+    Returns
+    -------
+    nulp : array_like
+        number of representable floating point numbers between each item in x
+        and y.
+
+    Examples
+    --------
+    # By definition, epsilon is the smallest number such as 1 + eps != 1, so
+    # there should be exactly one ULP between 1 and 1 + eps
+    >>> nulp_diff(1, 1 + np.finfo(x.dtype).eps)
+    1.0
+    """
+    import numpy as np
+    if dtype:
+        x = np.array(x, dtype=dtype)
+        y = np.array(y, dtype=dtype)
+    else:
+        x = np.array(x)
+        y = np.array(y)
+
+    t = np.common_type(x, y)
+    if np.iscomplexobj(x) or np.iscomplexobj(y):
+        raise NotImplementedError("_nulp not implemented for complex array")
+
+    x = np.array(x, dtype=t)
+    y = np.array(y, dtype=t)
+
+    if not x.shape == y.shape:
+        raise ValueError("x and y do not have the same shape: %s - %s" %
+                         (x.shape, y.shape))
+
+    def _diff(rx, ry, vdt):
+        diff = np.array(rx-ry, dtype=vdt)
+        return np.abs(diff)
+
+    rx = integer_repr(x)
+    ry = integer_repr(y)
+    return _diff(rx, ry, t)
+
+def _integer_repr(x, vdt, comp):
+    # Reinterpret binary representation of the float as sign-magnitude:
+    # take into account two-complement representation
+    # See also
+    # http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
+    rx = x.view(vdt)
+    if not (rx.size == 1):
+        rx[rx < 0] = comp - rx[rx < 0]
+    else:
+        if rx < 0:
+            rx = comp - rx
+
+    return rx
+
+def integer_repr(x):
+    """Return the signed-magnitude interpretation of the binary representation of
+    x."""
+    import numpy as np
+    if x.dtype == np.float32:
+        return _integer_repr(x, np.int32, np.int32(-2**31))
+    elif x.dtype == np.float64:
+        return _integer_repr(x, np.int64, np.int64(-2**63))
+    else:
+        raise ValueError("Unsupported dtype %s" % x.dtype)
+
+# The following two classes are copied from python 2.6 warnings module (context
+# manager)
+class WarningMessage(object):
+
+    """
+    Holds the result of a single showwarning() call.
+
+    Deprecated in 1.8.0
+
+    Notes
+    -----
+    `WarningMessage` is copied from the Python 2.6 warnings module,
+    so it can be used in NumPy with older Python versions.
+
+    """
+
+    _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
+                        "line")
+
+    def __init__(self, message, category, filename, lineno, file=None,
+                    line=None):
+        local_values = locals()
+        for attr in self._WARNING_DETAILS:
+            setattr(self, attr, local_values[attr])
+        if category:
+            self._category_name = category.__name__
+        else:
+            self._category_name = None
+
+    def __str__(self):
+        return ("{message : %r, category : %r, filename : %r, lineno : %s, "
+                    "line : %r}" % (self.message, self._category_name,
+                                    self.filename, self.lineno, self.line))
+
+class WarningManager(object):
+    """
+    A context manager that copies and restores the warnings filter upon
+    exiting the context.
+
+    The 'record' argument specifies whether warnings should be captured by a
+    custom implementation of ``warnings.showwarning()`` and be appended to a
+    list returned by the context manager. Otherwise None is returned by the
+    context manager. The objects appended to the list are arguments whose
+    attributes mirror the arguments to ``showwarning()``.
+
+    The 'module' argument is to specify an alternative module to the module
+    named 'warnings' and imported under that name. This argument is only useful
+    when testing the warnings module itself.
+
+    Deprecated in 1.8.0
+
+    Notes
+    -----
+    `WarningManager` is a copy of the ``catch_warnings`` context manager
+    from the Python 2.6 warnings module, with slight modifications.
+    It is copied so it can be used in NumPy with older Python versions.
+
+    """
+
+    def __init__(self, record=False, module=None):
+        self._record = record
+        if module is None:
+            self._module = sys.modules['warnings']
+        else:
+            self._module = module
+        self._entered = False
+
+    def __enter__(self):
+        if self._entered:
+            raise RuntimeError("Cannot enter %r twice" % self)
+        self._entered = True
+        self._filters = self._module.filters
+        self._module.filters = self._filters[:]
+        self._showwarning = self._module.showwarning
+        if self._record:
+            log = []
+
+            def showwarning(*args, **kwargs):
+                log.append(WarningMessage(*args, **kwargs))
+            self._module.showwarning = showwarning
+            return log
+        else:
+            return None
+
+    def __exit__(self):
+        if not self._entered:
+            raise RuntimeError("Cannot exit %r without entering first" % self)
+        self._module.filters = self._filters
+        self._module.showwarning = self._showwarning
+
+
+@contextlib.contextmanager
+def _assert_warns_context(warning_class, name=None):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    with warnings.catch_warnings(record=True) as l:
+        warnings.simplefilter('always')
+        yield
+        if not len(l) > 0:
+            name_str = " when calling %s" % name if name is not None else ""
+            raise AssertionError("No warning raised" + name_str)
+        if not l[0].category is warning_class:
+            name_str = "%s " % name if name is not None else ""
+            raise AssertionError("First warning %sis not a %s (is %s)"
+                                 % (name_str, warning_class, l[0]))
+
+
+def assert_warns(warning_class, *args, **kwargs):
+    """
+    Fail unless the given callable throws the specified warning.
+
+    A warning of class warning_class should be thrown by the callable when
+    invoked with arguments args and keyword arguments kwargs.
+    If a different type of warning is thrown, it will not be caught, and the
+    test case will be deemed to have suffered an error.
+
+    If called with all arguments other than the warning class omitted, may be
+    used as a context manager:
+
+        with assert_warns(SomeWarning):
+            do_something()
+
+    The ability to be used as a context manager is new in NumPy v1.11.0.
+
+    .. versionadded:: 1.4.0
+
+    Parameters
+    ----------
+    warning_class : class
+        The class defining the warning that `func` is expected to throw.
+    func : callable
+        The callable to test.
+    \\*args : Arguments
+        Arguments passed to `func`.
+    \\*\\*kwargs : Kwargs
+        Keyword arguments passed to `func`.
+
+    Returns
+    -------
+    The value returned by `func`.
+
+    """
+    if not args:
+        return _assert_warns_context(warning_class)
+
+    func = args[0]
+    args = args[1:]
+    with _assert_warns_context(warning_class, name=func.__name__):
+        return func(*args, **kwargs)
+
+
+@contextlib.contextmanager
+def _assert_no_warnings_context(name=None):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    with warnings.catch_warnings(record=True) as l:
+        warnings.simplefilter('always')
+        yield
+        if len(l) > 0:
+            name_str = " when calling %s" % name if name is not None else ""
+            raise AssertionError("Got warnings%s: %s" % (name_str, l))
+
+
+def assert_no_warnings(*args, **kwargs):
+    """
+    Fail if the given callable produces any warnings.
+
+    If called with all arguments omitted, may be used as a context manager:
+
+        with assert_no_warnings():
+            do_something()
+
+    The ability to be used as a context manager is new in NumPy v1.11.0.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    func : callable
+        The callable to test.
+    \\*args : Arguments
+        Arguments passed to `func`.
+    \\*\\*kwargs : Kwargs
+        Keyword arguments passed to `func`.
+
+    Returns
+    -------
+    The value returned by `func`.
+
+    """
+    if not args:
+        return _assert_no_warnings_context()
+
+    func = args[0]
+    args = args[1:]
+    with _assert_no_warnings_context(name=func.__name__):
+        return func(*args, **kwargs)
+
+
+def _gen_alignment_data(dtype=float32, type='binary', max_size=24):
+    """
+    generator producing data with different alignment and offsets
+    to test simd vectorization
+
+    Parameters
+    ----------
+    dtype : dtype
+        data type to produce
+    type : string
+        'unary': create data for unary operations, creates one input
+                 and output array
+        'binary': create data for unary operations, creates two input
+                 and output array
+    max_size : integer
+        maximum size of data to produce
+
+    Returns
+    -------
+    if type is 'unary' yields one output, one input array and a message
+    containing information on the data
+    if type is 'binary' yields one output array, two input array and a message
+    containing information on the data
+
+    """
+    ufmt = 'unary offset=(%d, %d), size=%d, dtype=%r, %s'
+    bfmt = 'binary offset=(%d, %d, %d), size=%d, dtype=%r, %s'
+    for o in range(3):
+        for s in range(o + 2, max(o + 3, max_size)):
+            if type == 'unary':
+                inp = lambda: arange(s, dtype=dtype)[o:]
+                out = empty((s,), dtype=dtype)[o:]
+                yield out, inp(), ufmt % (o, o, s, dtype, 'out of place')
+                yield inp(), inp(), ufmt % (o, o, s, dtype, 'in place')
+                yield out[1:], inp()[:-1], ufmt % \
+                    (o + 1, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp()[1:], ufmt % \
+                    (o, o + 1, s - 1, dtype, 'out of place')
+                yield inp()[:-1], inp()[1:], ufmt % \
+                    (o, o + 1, s - 1, dtype, 'aliased')
+                yield inp()[1:], inp()[:-1], ufmt % \
+                    (o + 1, o, s - 1, dtype, 'aliased')
+            if type == 'binary':
+                inp1 = lambda: arange(s, dtype=dtype)[o:]
+                inp2 = lambda: arange(s, dtype=dtype)[o:]
+                out = empty((s,), dtype=dtype)[o:]
+                yield out, inp1(), inp2(),  bfmt % \
+                    (o, o, o, s, dtype, 'out of place')
+                yield inp1(), inp1(), inp2(), bfmt % \
+                    (o, o, o, s, dtype, 'in place1')
+                yield inp2(), inp1(), inp2(), bfmt % \
+                    (o, o, o, s, dtype, 'in place2')
+                yield out[1:], inp1()[:-1], inp2()[:-1], bfmt % \
+                    (o + 1, o, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp1()[1:], inp2()[:-1], bfmt % \
+                    (o, o + 1, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp1()[:-1], inp2()[1:], bfmt % \
+                    (o, o, o + 1, s - 1, dtype, 'out of place')
+                yield inp1()[1:], inp1()[:-1], inp2()[:-1], bfmt % \
+                    (o + 1, o, o, s - 1, dtype, 'aliased')
+                yield inp1()[:-1], inp1()[1:], inp2()[:-1], bfmt % \
+                    (o, o + 1, o, s - 1, dtype, 'aliased')
+                yield inp1()[:-1], inp1()[:-1], inp2()[1:], bfmt % \
+                    (o, o, o + 1, s - 1, dtype, 'aliased')
+
+
+class IgnoreException(Exception):
+    "Ignoring this exception due to disabled feature"
+
+
+@contextlib.contextmanager
+def tempdir(*args, **kwargs):
+    """Context manager to provide a temporary test folder.
+
+    All arguments are passed as this to the underlying tempfile.mkdtemp
+    function.
+
+    """
+    tmpdir = mkdtemp(*args, **kwargs)
+    try:
+        yield tmpdir
+    finally:
+        shutil.rmtree(tmpdir)
+
+@contextlib.contextmanager
+def temppath(*args, **kwargs):
+    """Context manager for temporary files.
+
+    Context manager that returns the path to a closed temporary file. Its
+    parameters are the same as for tempfile.mkstemp and are passed directly
+    to that function. The underlying file is removed when the context is
+    exited, so it should be closed at that time.
+  
+    Windows does not allow a temporary file to be opened if it is already
+    open, so the underlying file must be closed after opening before it
+    can be opened again.
+
+    """
+    fd, path = mkstemp(*args, **kwargs)
+    os.close(fd)
+    try:
+        yield path
+    finally:
+        os.remove(path)
+
+
+class clear_and_catch_warnings(warnings.catch_warnings):
+    """ Context manager that resets warning registry for catching warnings
+
+    Warnings can be slippery, because, whenever a warning is triggered, Python
+    adds a ``__warningregistry__`` member to the *calling* module.  This makes
+    it impossible to retrigger the warning in this module, whatever you put in
+    the warnings filters.  This context manager accepts a sequence of `modules`
+    as a keyword argument to its constructor and:
+
+    * stores and removes any ``__warningregistry__`` entries in given `modules`
+      on entry;
+    * resets ``__warningregistry__`` to its previous state on exit.
+
+    This makes it possible to trigger any warning afresh inside the context
+    manager without disturbing the state of warnings outside.
+
+    For compatibility with Python 3.0, please consider all arguments to be
+    keyword-only.
+
+    Parameters
+    ----------
+    record : bool, optional
+        Specifies whether warnings should be captured by a custom
+        implementation of ``warnings.showwarning()`` and be appended to a list
+        returned by the context manager. Otherwise None is returned by the
+        context manager. The objects appended to the list are arguments whose
+        attributes mirror the arguments to ``showwarning()``.
+    modules : sequence, optional
+        Sequence of modules for which to reset warnings registry on entry and
+        restore on exit
+
+    Examples
+    --------
+    >>> import warnings
+    >>> with clear_and_catch_warnings(modules=[np.core.fromnumeric]):
+    ...     warnings.simplefilter('always')
+    ...     # do something that raises a warning in np.core.fromnumeric
+    """
+    class_modules = ()
+
+    def __init__(self, record=False, modules=()):
+        self.modules = set(modules).union(self.class_modules)
+        self._warnreg_copies = {}
+        super(clear_and_catch_warnings, self).__init__(record=record)
+
+    def __enter__(self):
+        for mod in self.modules:
+            if hasattr(mod, '__warningregistry__'):
+                mod_reg = mod.__warningregistry__
+                self._warnreg_copies[mod] = mod_reg.copy()
+                mod_reg.clear()
+        return super(clear_and_catch_warnings, self).__enter__()
+
+    def __exit__(self, *exc_info):
+        super(clear_and_catch_warnings, self).__exit__(*exc_info)
+        for mod in self.modules:
+            if hasattr(mod, '__warningregistry__'):
+                mod.__warningregistry__.clear()
+            if mod in self._warnreg_copies:
+                mod.__warningregistry__.update(self._warnreg_copies[mod])
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
new file mode 100644
index 0000000000..5e888eb652
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
@@ -0,0 +1,106 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.ctypeslib import ndpointer, load_library
+from numpy.distutils.misc_util import get_shared_lib_extension
+from numpy.testing import TestCase, run_module_suite, dec
+
+try:
+    cdll = load_library('multiarray', np.core.multiarray.__file__)
+    _HAS_CTYPE = True
+except ImportError:
+    _HAS_CTYPE = False
+
+class TestLoadLibrary(TestCase):
+    @dec.skipif(not _HAS_CTYPE,
+                "ctypes not available on this python installation")
+    @dec.knownfailureif(sys.platform ==
+                        'cygwin', "This test is known to fail on cygwin")
+    def test_basic(self):
+        try:
+            # Should succeed
+            load_library('multiarray', np.core.multiarray.__file__)
+        except ImportError as e:
+            msg = ("ctypes is not available on this python: skipping the test"
+                   " (import error was: %s)" % str(e))
+            print(msg)
+
+    @dec.skipif(not _HAS_CTYPE,
+                "ctypes not available on this python installation")
+    @dec.knownfailureif(sys.platform ==
+                        'cygwin', "This test is known to fail on cygwin")
+    def test_basic2(self):
+        # Regression for #801: load_library with a full library name
+        # (including extension) does not work.
+        try:
+            try:
+                so = get_shared_lib_extension(is_python_ext=True)
+                # Should succeed
+                load_library('multiarray%s' % so, np.core.multiarray.__file__)
+            except ImportError:
+                print("No distutils available, skipping test.")
+        except ImportError as e:
+            msg = ("ctypes is not available on this python: skipping the test"
+                   " (import error was: %s)" % str(e))
+            print(msg)
+
+class TestNdpointer(TestCase):
+    def test_dtype(self):
+        dt = np.intc
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.array([1], dt)))
+        dt = '<i4'
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.array([1], dt)))
+        dt = np.dtype('>i4')
+        p = ndpointer(dtype=dt)
+        p.from_param(np.array([1], dt))
+        self.assertRaises(TypeError, p.from_param,
+                          np.array([1], dt.newbyteorder('swap')))
+        dtnames = ['x', 'y']
+        dtformats = [np.intc, np.float64]
+        dtdescr = {'names': dtnames, 'formats': dtformats}
+        dt = np.dtype(dtdescr)
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.zeros((10,), dt)))
+        samedt = np.dtype(dtdescr)
+        p = ndpointer(dtype=samedt)
+        self.assertTrue(p.from_param(np.zeros((10,), dt)))
+        dt2 = np.dtype(dtdescr, align=True)
+        if dt.itemsize != dt2.itemsize:
+            self.assertRaises(TypeError, p.from_param, np.zeros((10,), dt2))
+        else:
+            self.assertTrue(p.from_param(np.zeros((10,), dt2)))
+
+    def test_ndim(self):
+        p = ndpointer(ndim=0)
+        self.assertTrue(p.from_param(np.array(1)))
+        self.assertRaises(TypeError, p.from_param, np.array([1]))
+        p = ndpointer(ndim=1)
+        self.assertRaises(TypeError, p.from_param, np.array(1))
+        self.assertTrue(p.from_param(np.array([1])))
+        p = ndpointer(ndim=2)
+        self.assertTrue(p.from_param(np.array([[1]])))
+
+    def test_shape(self):
+        p = ndpointer(shape=(1, 2))
+        self.assertTrue(p.from_param(np.array([[1, 2]])))
+        self.assertRaises(TypeError, p.from_param, np.array([[1], [2]]))
+        p = ndpointer(shape=())
+        self.assertTrue(p.from_param(np.array(1)))
+
+    def test_flags(self):
+        x = np.array([[1, 2], [3, 4]], order='F')
+        p = ndpointer(flags='FORTRAN')
+        self.assertTrue(p.from_param(x))
+        p = ndpointer(flags='CONTIGUOUS')
+        self.assertRaises(TypeError, p.from_param, x)
+        p = ndpointer(flags=x.flags.num)
+        self.assertTrue(p.from_param(x))
+        self.assertRaises(TypeError, p.from_param, np.array([[1, 2], [3, 4]]))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_matlib.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_matlib.py
new file mode 100644
index 0000000000..3ff6cd7ed2
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_matlib.py
@@ -0,0 +1,55 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.matlib
+from numpy.testing import assert_array_equal, assert_, run_module_suite
+
+def test_empty():
+    x = numpy.matlib.empty((2,))
+    assert_(isinstance(x, np.matrix))
+    assert_(x.shape, (1, 2))
+
+def test_ones():
+    assert_array_equal(numpy.matlib.ones((2, 3)),
+                       np.matrix([[ 1.,  1.,  1.],
+                                 [ 1.,  1.,  1.]]))
+
+    assert_array_equal(numpy.matlib.ones(2), np.matrix([[ 1.,  1.]]))
+
+def test_zeros():
+    assert_array_equal(numpy.matlib.zeros((2, 3)),
+                       np.matrix([[ 0.,  0.,  0.],
+                                 [ 0.,  0.,  0.]]))
+
+    assert_array_equal(numpy.matlib.zeros(2), np.matrix([[ 0.,  0.]]))
+
+def test_identity():
+    x = numpy.matlib.identity(2, dtype=np.int)
+    assert_array_equal(x, np.matrix([[1, 0], [0, 1]]))
+
+def test_eye():
+    x = numpy.matlib.eye(3, k=1, dtype=int)
+    assert_array_equal(x, np.matrix([[ 0,  1,  0],
+                                     [ 0,  0,  1],
+                                     [ 0,  0,  0]]))
+
+def test_rand():
+    x = numpy.matlib.rand(3)
+    # check matrix type, array would have shape (3,)
+    assert_(x.ndim == 2)
+
+def test_randn():
+    x = np.matlib.randn(3)
+    # check matrix type, array would have shape (3,)
+    assert_(x.ndim == 2)
+
+def test_repmat():
+    a1 = np.arange(4)
+    x = numpy.matlib.repmat(a1, 2, 2)
+    y = np.array([[0, 1, 2, 3, 0, 1, 2, 3],
+                  [0, 1, 2, 3, 0, 1, 2, 3]])
+    assert_array_equal(x, y)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
new file mode 100644
index 0000000000..b61d0d5f19
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+
+import numpy as np
+from numpy.testing import assert_, run_module_suite
+
+
+def test_valid_numpy_version():
+    # Verify that the numpy version is a valid one (no .post suffix or other
+    # nonsense).  See gh-6431 for an issue caused by an invalid version.
+    version_pattern = r"^[0-9]+\.[0-9]+\.[0-9]+(|a[0-9]|b[0-9]|rc[0-9])"
+    dev_suffix = r"(\.dev0\+([0-9a-f]{7}|Unknown))"
+    if np.version.release:
+        res = re.match(version_pattern, np.__version__)
+    else:
+        res = re.match(version_pattern + dev_suffix, np.__version__)
+
+    assert_(res is not None, np.__version__)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_scripts.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_scripts.py
new file mode 100644
index 0000000000..19ddff0d36
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/tests/test_scripts.py
@@ -0,0 +1,99 @@
+""" Test scripts
+
+Test that we can run executable scripts that have been installed with numpy.
+"""
+from __future__ import division, print_function, absolute_import
+
+import os
+from os.path import join as pathjoin, isfile, dirname, basename
+import sys
+from subprocess import Popen, PIPE
+import numpy as np
+from numpy.compat.py3k import basestring, asbytes
+from nose.tools import assert_equal
+from numpy.testing.decorators import skipif
+from numpy.testing import assert_
+
+is_inplace = isfile(pathjoin(dirname(np.__file__),  '..', 'setup.py'))
+
+def run_command(cmd, check_code=True):
+    """ Run command sequence `cmd` returning exit code, stdout, stderr
+
+    Parameters
+    ----------
+    cmd : str or sequence
+        string with command name or sequence of strings defining command
+    check_code : {True, False}, optional
+        If True, raise error for non-zero return code
+
+    Returns
+    -------
+    returncode : int
+        return code from execution of `cmd`
+    stdout : bytes (python 3) or str (python 2)
+        stdout from `cmd`
+    stderr : bytes (python 3) or str (python 2)
+        stderr from `cmd`
+
+    Raises
+    ------
+    RuntimeError
+        If `check_code` is True, and return code !=0
+    """
+    cmd = [cmd] if isinstance(cmd, basestring) else list(cmd)
+    if os.name == 'nt':
+        # Quote any arguments with spaces. The quotes delimit the arguments
+        # on Windows, and the arguments might be file paths with spaces.
+        # On Unix the list elements are each separate arguments.
+        cmd = ['"{0}"'.format(c) if ' ' in c else c for c in cmd]
+    proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
+    stdout, stderr = proc.communicate()
+    if proc.poll() == None:
+        proc.terminate()
+    if check_code and proc.returncode != 0:
+        raise RuntimeError('\n'.join(
+            ['Command "{0}" failed with',
+             'stdout', '------', '{1}', '',
+             'stderr', '------', '{2}']).format(cmd, stdout, stderr))
+    return proc.returncode, stdout, stderr
+
+
+@skipif(is_inplace)
+def test_f2py():
+    # test that we can run f2py script
+    if sys.platform == 'win32':
+        exe_dir = dirname(sys.executable)
+
+        if exe_dir.endswith('Scripts'): # virtualenv
+            f2py_cmd = r"%s\f2py.py" % exe_dir
+        else:
+            f2py_cmd = r"%s\Scripts\f2py.py" % exe_dir
+
+        code, stdout, stderr = run_command([sys.executable, f2py_cmd, '-v'])
+        success = stdout.strip() == asbytes('2')
+        assert_(success, "Warning: f2py not found in path")
+    else:
+        version = sys.version_info
+
+        # Python 2.6 'sys.version_info'
+        # is just a tuple, but this changes
+        # in Python 2.7 to have a more user-
+        # friendly interface with version[0]
+        # being the 'major' version and
+        # version[1] being the minor version
+        major = str(version[0])
+        minor = str(version[1])
+
+        f2py_cmds = ('f2py', 'f2py' + major, 'f2py' + major + '.' + minor)
+        success = False
+
+        for f2py_cmd in f2py_cmds:
+            try:
+                code, stdout, stderr = run_command([f2py_cmd, '-v'])
+                assert_equal(stdout.strip(), asbytes('2'))
+                success = True
+                break
+            except:
+                pass
+        msg = "Warning: neither %s nor %s nor %s found in path" % f2py_cmds
+        assert_(success, msg)
diff --git a/tools/msys/mingw32/lib/python2.7/site-packages/numpy/version.py b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/version.py
new file mode 100644
index 0000000000..7c29e33627
--- /dev/null
+++ b/tools/msys/mingw32/lib/python2.7/site-packages/numpy/version.py
@@ -0,0 +1,12 @@
+
+# THIS FILE IS GENERATED FROM NUMPY SETUP.PY
+#
+# To compare versions robustly, use `numpy.lib.NumpyVersion`
+short_version = '1.11.0'
+version = '1.11.0'
+full_version = '1.11.0'
+git_revision = '4092a9e160cc247a4a45724579a0c829733688ca'
+release = True
+
+if not release:
+    version = full_version
diff --git a/tools/msys/mingw32/share/licenses/python2-numpy/LICENSE.txt b/tools/msys/mingw32/share/licenses/python2-numpy/LICENSE.txt
new file mode 100644
index 0000000000..9014534ab4
--- /dev/null
+++ b/tools/msys/mingw32/share/licenses/python2-numpy/LICENSE.txt
@@ -0,0 +1,30 @@
+Copyright (c) 2005-2016, NumPy Developers.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+
+    * Neither the name of the NumPy Developers nor the names of any
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/msys/mingw64/bin/f2py2.py b/tools/msys/mingw64/bin/f2py2.py
new file mode 100644
index 0000000000..d623edc17d
--- /dev/null
+++ b/tools/msys/mingw64/bin/f2py2.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python2.exe
+# See http://cens.ioc.ee/projects/f2py2e/
+from __future__ import division, print_function
+
+import os
+import sys
+for mode in ["g3-numpy", "2e-numeric", "2e-numarray", "2e-numpy"]:
+    try:
+        i = sys.argv.index("--" + mode)
+        del sys.argv[i]
+        break
+    except ValueError:
+        pass
+os.environ["NO_SCIPY_IMPORT"] = "f2py"
+if mode == "g3-numpy":
+    sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
+    sys.exit(1)
+elif mode == "2e-numeric":
+    from f2py2e import main
+elif mode == "2e-numarray":
+    sys.argv.append("-DNUMARRAY")
+    from f2py2e import main
+elif mode == "2e-numpy":
+    from numpy.f2py import main
+else:
+    sys.stderr.write("Unknown mode: " + repr(mode) + "\\n")
+    sys.exit(1)
+main()
diff --git a/tools/msys/mingw64/include/python2.7/numpy/__multiarray_api.h b/tools/msys/mingw64/include/python2.7/numpy/__multiarray_api.h
new file mode 100644
index 0000000000..aefb9de029
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/__multiarray_api.h
@@ -0,0 +1,1540 @@
+
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCVersion \
+       (void);
+extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type;
+
+extern NPY_NO_EXPORT int NPY_NUMUSERTYPES;
+
+extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type;
+
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type;
+
+NPY_NO_EXPORT  int PyArray_SetNumericOps \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_GetNumericOps \
+       (void);
+NPY_NO_EXPORT  int PyArray_INCREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_XDECREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  void PyArray_SetStringFunction \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromType \
+       (int);
+NPY_NO_EXPORT  PyObject * PyArray_TypeObjectFromType \
+       (int);
+NPY_NO_EXPORT  char * PyArray_Zero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  char * PyArray_One \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_CastTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CastAnyTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CanCastSafely \
+       (int, int);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTo \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_ObjectType \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromObject \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArrayObject ** PyArray_ConvertToCommonType \
+       (PyObject *, int *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromScalar \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromTypeObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_Size \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Scalar \
+       (void *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_ScalarAsCtype \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_CastScalarToCtype \
+       (PyObject *, void *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_CastScalarDirect \
+       (PyObject *, PyArray_Descr *, void *, int);
+NPY_NO_EXPORT  PyObject * PyArray_ScalarFromObject \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+       (PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromDims \
+       (int, int *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \
+       (int, int *, PyArray_Descr *, char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \
+       (PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromFile \
+       (FILE *, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromString \
+       (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromBuffer \
+       (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \
+       (PyObject *, PyArray_Descr *, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \
+       (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Byteswap \
+       (PyArrayObject *, npy_bool);
+NPY_NO_EXPORT  PyObject * PyArray_Resize \
+       (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_MoveInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyAnyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_ToList \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ToString \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_ToFile \
+       (PyArrayObject *, FILE *, char *, char *);
+NPY_NO_EXPORT  int PyArray_Dump \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Dumps \
+       (PyObject *, int);
+NPY_NO_EXPORT  int PyArray_ValidType \
+       (int);
+NPY_NO_EXPORT  void PyArray_UpdateFlags \
+       (PyArrayObject *, int);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \
+       (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \
+       (PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNew \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewFromType \
+       (int);
+NPY_NO_EXPORT  double PyArray_GetPriority \
+       (PyObject *, double);
+NPY_NO_EXPORT  PyObject * PyArray_IterNew \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterNew \
+       (int, ...);
+NPY_NO_EXPORT  int PyArray_PyIntAsInt \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_PyIntAsIntp \
+       (PyObject *);
+NPY_NO_EXPORT  int PyArray_Broadcast \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  void PyArray_FillObjectArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  int PyArray_FillWithScalar \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CheckStrides \
+       (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewByteorder \
+       (PyArray_Descr *, char);
+NPY_NO_EXPORT  PyObject * PyArray_IterAllButAxis \
+       (PyObject *, int *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromStructInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromArrayAttr \
+       (PyObject *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT  NPY_SCALARKIND PyArray_ScalarKind \
+       (int, PyArrayObject **);
+NPY_NO_EXPORT  int PyArray_CanCoerceScalar \
+       (int, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  PyObject * PyArray_NewFlagsObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastScalar \
+       (PyTypeObject *, PyTypeObject *);
+NPY_NO_EXPORT  int PyArray_CompareUCS4 \
+       (npy_ucs4 *, npy_ucs4 *, size_t);
+NPY_NO_EXPORT  int PyArray_RemoveSmallest \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  int PyArray_ElementStrides \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_Item_INCREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_Item_XDECREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  PyObject * PyArray_FieldNames \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Transpose \
+       (PyArrayObject *, PyArray_Dims *);
+NPY_NO_EXPORT  PyObject * PyArray_TakeFrom \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutTo \
+       (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutMask \
+       (PyArrayObject *, PyObject*, PyObject*);
+NPY_NO_EXPORT  PyObject * PyArray_Repeat \
+       (PyArrayObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Choose \
+       (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  int PyArray_Sort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgSort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_SearchSorted \
+       (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMax \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMin \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Reshape \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Newshape \
+       (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Squeeze \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \
+       (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+NPY_NO_EXPORT  PyObject * PyArray_SwapAxes \
+       (PyArrayObject *, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Max \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Min \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Ptp \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Mean \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Trace \
+       (PyArrayObject *, int, int, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Diagonal \
+       (PyArrayObject *, int, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Clip \
+       (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Conjugate \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Nonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Std \
+       (PyArrayObject *, int, int, PyArrayObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Sum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumSum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Prod \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumProd \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_All \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Any \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Compress \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Flatten \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Ravel \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  npy_intp PyArray_MultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_MultiplyIntList \
+       (int *, int);
+NPY_NO_EXPORT  void * PyArray_GetPtr \
+       (PyArrayObject *, npy_intp*);
+NPY_NO_EXPORT  int PyArray_CompareLists \
+       (npy_intp *, npy_intp *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \
+       (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+NPY_NO_EXPORT  int PyArray_As1D \
+       (PyObject **, char **, int *, int);
+NPY_NO_EXPORT  int PyArray_As2D \
+       (PyObject **, char ***, int *, int *, int);
+NPY_NO_EXPORT  int PyArray_Free \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_Converter \
+       (PyObject *, PyObject **);
+NPY_NO_EXPORT  int PyArray_IntpFromSequence \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Concatenate \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_InnerProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CopyAndTranspose \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  int PyArray_TypestrConvert \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_DescrConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_IntpConverter \
+       (PyObject *, PyArray_Dims *);
+NPY_NO_EXPORT  int PyArray_BufferConverter \
+       (PyObject *, PyArray_Chunk *);
+NPY_NO_EXPORT  int PyArray_AxisConverter \
+       (PyObject *, int *);
+NPY_NO_EXPORT  int PyArray_BoolConverter \
+       (PyObject *, npy_bool *);
+NPY_NO_EXPORT  int PyArray_ByteorderConverter \
+       (PyObject *, char *);
+NPY_NO_EXPORT  int PyArray_OrderConverter \
+       (PyObject *, NPY_ORDER *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Where \
+       (PyObject *, PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Arange \
+       (double, double, double, int);
+NPY_NO_EXPORT  PyObject * PyArray_ArangeObj \
+       (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_SortkindConverter \
+       (PyObject *, NPY_SORTKIND *);
+NPY_NO_EXPORT  PyObject * PyArray_LexSort \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Round \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypenums \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_RegisterDataType \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_RegisterCastFunc \
+       (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+NPY_NO_EXPORT  int PyArray_RegisterCanCast \
+       (PyArray_Descr *, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  void PyArray_InitArrFuncs \
+       (PyArray_ArrFuncs *);
+NPY_NO_EXPORT  PyObject * PyArray_IntTupleFromIntp \
+       (int, npy_intp *);
+NPY_NO_EXPORT  int PyArray_TypeNumFromName \
+       (char *);
+NPY_NO_EXPORT  int PyArray_ClipmodeConverter \
+       (PyObject *, NPY_CLIPMODE *);
+NPY_NO_EXPORT  int PyArray_OutputConverter \
+       (PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  PyObject * PyArray_BroadcastToShape \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  void _PyArray_SigintHandler \
+       (int);
+NPY_NO_EXPORT  void* _PyArray_GetSigintBuf \
+       (void);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_SearchsideConverter \
+       (PyObject *, void *);
+NPY_NO_EXPORT  PyObject * PyArray_CheckAxis \
+       (PyArrayObject *, int *, int);
+NPY_NO_EXPORT  npy_intp PyArray_OverflowMultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_CompareString \
+       (char *, char *, size_t);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterFromObjects \
+       (PyObject **, int, int, ...);
+NPY_NO_EXPORT  int PyArray_GetEndianness \
+       (void);
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCFeatureVersion \
+       (void);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate2 \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject* PyArray_NeighborhoodIterNew \
+       (PyArrayIterObject *, npy_intp *, int, PyArrayObject*);
+extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject NpyIter_Type;
+
+NPY_NO_EXPORT  void PyArray_SetDatetimeParseFunction \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_DatetimeToDatetimeStruct \
+       (npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  void PyArray_TimedeltaToTimedeltaStruct \
+       (npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_DatetimeStructToDatetime \
+       (NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_TimedeltaStructToTimedelta \
+       (NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  NpyIter * NpyIter_New \
+       (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*);
+NPY_NO_EXPORT  NpyIter * NpyIter_MultiNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **);
+NPY_NO_EXPORT  NpyIter * NpyIter_AdvancedNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp);
+NPY_NO_EXPORT  NpyIter * NpyIter_Copy \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Deallocate \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasDelayedBufAlloc \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_EnableExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerStrideArray \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerLoopSizePtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Reset \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_ResetBasePointers \
+       (NpyIter *, char **, char **);
+NPY_NO_EXPORT  int NpyIter_ResetToIterIndexRange \
+       (NpyIter *, npy_intp, npy_intp, char **);
+NPY_NO_EXPORT  int NpyIter_GetNDim \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetNOp \
+       (NpyIter *);
+NPY_NO_EXPORT  NpyIter_IterNextFunc * NpyIter_GetIterNext \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterSize \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetIterIndexRange \
+       (NpyIter *, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIterIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  npy_bool NpyIter_HasMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetShape \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_GotoMultiIndex \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsBuffered \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsGrowInner \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetBufferSize \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetIndexPtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  char ** NpyIter_GetDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArray_Descr ** NpyIter_GetDescrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject ** NpyIter_GetOperandArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject * NpyIter_GetIterView \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  void NpyIter_GetReadFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_GetWriteFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_DebugPrint \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IterationNeedsAPI \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetInnerFixedStrideArray \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveAxis \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetAxisStrideArray \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_bool NpyIter_RequiresBuffering \
+       (NpyIter *);
+NPY_NO_EXPORT  char ** NpyIter_GetInitialDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_CreateCompatibleStrides \
+       (NpyIter *, npy_intp, npy_intp *);
+NPY_NO_EXPORT  int PyArray_CastingConverter \
+       (PyObject *, NPY_CASTING *);
+NPY_NO_EXPORT  npy_intp PyArray_CountNonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_PromoteTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_MinScalarType \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_ResultType \
+       (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastArrayTo \
+       (PyArrayObject *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTypeTo \
+       (PyArray_Descr *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  PyArrayObject * PyArray_EinsteinSum \
+       (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \
+       (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_GetArrayParamsFromObject \
+       (PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *);
+NPY_NO_EXPORT  int PyArray_ConvertClipmodeSequence \
+       (PyObject *, NPY_CLIPMODE *, int);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct2 \
+       (PyObject *, PyObject *, PyArrayObject*);
+NPY_NO_EXPORT  npy_bool NpyIter_IsFirstVisit \
+       (NpyIter *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_CreateSortedStridePerm \
+       (int, npy_intp *, npy_stride_sort_item *);
+NPY_NO_EXPORT  void PyArray_RemoveAxesInPlace \
+       (PyArrayObject *, npy_bool *);
+NPY_NO_EXPORT  void PyArray_DebugPrint \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_FailUnlessWriteable \
+       (PyArrayObject *, const char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  void * PyDataMem_NEW \
+       (size_t);
+NPY_NO_EXPORT  void PyDataMem_FREE \
+       (void *);
+NPY_NO_EXPORT  void * PyDataMem_RENEW \
+       (void *, size_t);
+NPY_NO_EXPORT  PyDataMem_EventHookFunc * PyDataMem_SetEventHook \
+       (PyDataMem_EventHookFunc *, void *, void **);
+extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING;
+
+NPY_NO_EXPORT  void PyArray_MapIterSwapAxes \
+       (PyArrayMapIterObject *, PyArrayObject **, int);
+NPY_NO_EXPORT  PyObject * PyArray_MapIterArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_MapIterNext \
+       (PyArrayMapIterObject *);
+NPY_NO_EXPORT  int PyArray_Partition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgPartition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  int PyArray_SelectkindConverter \
+       (PyObject *, NPY_SELECTKIND *);
+NPY_NO_EXPORT  void * PyDataMem_NEW_ZEROED \
+       (size_t, size_t);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \
+       (PyObject *);
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+#define PyArray_GetNDArrayCVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[40])
+#define PyArray_GetNumericOps \
+        (*(PyObject * (*)(void)) \
+         PyArray_API[41])
+#define PyArray_INCREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[42])
+#define PyArray_XDECREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[43])
+#define PyArray_SetStringFunction \
+        (*(void (*)(PyObject *, int)) \
+         PyArray_API[44])
+#define PyArray_DescrFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+        (*(PyObject * (*)(int)) \
+         PyArray_API[46])
+#define PyArray_Zero \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[47])
+#define PyArray_One \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[48])
+#define PyArray_CastToType \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[49])
+#define PyArray_CastTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[50])
+#define PyArray_CastAnyTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[51])
+#define PyArray_CanCastSafely \
+        (*(int (*)(int, int)) \
+         PyArray_API[52])
+#define PyArray_CanCastTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[53])
+#define PyArray_ObjectType \
+        (*(int (*)(PyObject *, int)) \
+         PyArray_API[54])
+#define PyArray_DescrFromObject \
+        (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+        (*(PyArrayObject ** (*)(PyObject *, int *)) \
+         PyArray_API[56])
+#define PyArray_DescrFromScalar \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[58])
+#define PyArray_Size \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[59])
+#define PyArray_Scalar \
+        (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[60])
+#define PyArray_FromScalar \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+        (*(void (*)(PyObject *, void *)) \
+         PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+        (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+         PyArray_API[63])
+#define PyArray_CastScalarDirect \
+        (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+         PyArray_API[64])
+#define PyArray_ScalarFromObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[65])
+#define PyArray_GetCastFunc \
+        (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+         PyArray_API[66])
+#define PyArray_FromDims \
+        (*(PyObject * (*)(int, int *, int)) \
+         PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+        (*(PyObject * (*)(int, int *, PyArray_Descr *, char *)) \
+         PyArray_API[68])
+#define PyArray_FromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[69])
+#define PyArray_EnsureArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[71])
+#define PyArray_FromFile \
+        (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[72])
+#define PyArray_FromString \
+        (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[73])
+#define PyArray_FromBuffer \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+         PyArray_API[74])
+#define PyArray_FromIter \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+         PyArray_API[75])
+#define PyArray_Return \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[76])
+#define PyArray_GetField \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[77])
+#define PyArray_SetField \
+        (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+         PyArray_API[78])
+#define PyArray_Byteswap \
+        (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+         PyArray_API[79])
+#define PyArray_Resize \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER)) \
+         PyArray_API[80])
+#define PyArray_MoveInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[81])
+#define PyArray_CopyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[82])
+#define PyArray_CopyAnyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[83])
+#define PyArray_CopyObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[84])
+#define PyArray_NewCopy \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[85])
+#define PyArray_ToList \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[86])
+#define PyArray_ToString \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[87])
+#define PyArray_ToFile \
+        (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+         PyArray_API[88])
+#define PyArray_Dump \
+        (*(int (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[89])
+#define PyArray_Dumps \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[90])
+#define PyArray_ValidType \
+        (*(int (*)(int)) \
+         PyArray_API[91])
+#define PyArray_UpdateFlags \
+        (*(void (*)(PyArrayObject *, int)) \
+         PyArray_API[92])
+#define PyArray_New \
+        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
+         PyArray_API[93])
+#define PyArray_NewFromDescr \
+        (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *)) \
+         PyArray_API[94])
+#define PyArray_DescrNew \
+        (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+         PyArray_API[95])
+#define PyArray_DescrNewFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[96])
+#define PyArray_GetPriority \
+        (*(double (*)(PyObject *, double)) \
+         PyArray_API[97])
+#define PyArray_IterNew \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[98])
+#define PyArray_MultiIterNew \
+        (*(PyObject * (*)(int, ...)) \
+         PyArray_API[99])
+#define PyArray_PyIntAsInt \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[101])
+#define PyArray_Broadcast \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[102])
+#define PyArray_FillObjectArray \
+        (*(void (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[103])
+#define PyArray_FillWithScalar \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[104])
+#define PyArray_CheckStrides \
+        (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)) \
+         PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+         PyArray_API[106])
+#define PyArray_IterAllButAxis \
+        (*(PyObject * (*)(PyObject *, int *)) \
+         PyArray_API[107])
+#define PyArray_CheckFromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[108])
+#define PyArray_FromArray \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[109])
+#define PyArray_FromInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[110])
+#define PyArray_FromStructInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[111])
+#define PyArray_FromArrayAttr \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[112])
+#define PyArray_ScalarKind \
+        (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+         PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+        (*(int (*)(int, int, NPY_SCALARKIND)) \
+         PyArray_API[114])
+#define PyArray_NewFlagsObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[115])
+#define PyArray_CanCastScalar \
+        (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+         PyArray_API[116])
+#define PyArray_CompareUCS4 \
+        (*(int (*)(npy_ucs4 *, npy_ucs4 *, size_t)) \
+         PyArray_API[117])
+#define PyArray_RemoveSmallest \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[118])
+#define PyArray_ElementStrides \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[119])
+#define PyArray_Item_INCREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[120])
+#define PyArray_Item_XDECREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[121])
+#define PyArray_FieldNames \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[122])
+#define PyArray_Transpose \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+         PyArray_API[123])
+#define PyArray_TakeFrom \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[124])
+#define PyArray_PutTo \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+         PyArray_API[125])
+#define PyArray_PutMask \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+         PyArray_API[126])
+#define PyArray_Repeat \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+         PyArray_API[127])
+#define PyArray_Choose \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[128])
+#define PyArray_Sort \
+        (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[129])
+#define PyArray_ArgSort \
+        (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[130])
+#define PyArray_SearchSorted \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \
+         PyArray_API[131])
+#define PyArray_ArgMax \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[132])
+#define PyArray_ArgMin \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[133])
+#define PyArray_Reshape \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[134])
+#define PyArray_Newshape \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+         PyArray_API[135])
+#define PyArray_Squeeze \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[136])
+#define PyArray_View \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+         PyArray_API[137])
+#define PyArray_SwapAxes \
+        (*(PyObject * (*)(PyArrayObject *, int, int)) \
+         PyArray_API[138])
+#define PyArray_Max \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[139])
+#define PyArray_Min \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[140])
+#define PyArray_Ptp \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[141])
+#define PyArray_Mean \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[142])
+#define PyArray_Trace \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+         PyArray_API[143])
+#define PyArray_Diagonal \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+         PyArray_API[144])
+#define PyArray_Clip \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+         PyArray_API[145])
+#define PyArray_Conjugate \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[146])
+#define PyArray_Nonzero \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[147])
+#define PyArray_Std \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+         PyArray_API[148])
+#define PyArray_Sum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[149])
+#define PyArray_CumSum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[150])
+#define PyArray_Prod \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[151])
+#define PyArray_CumProd \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[152])
+#define PyArray_All \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[153])
+#define PyArray_Any \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[154])
+#define PyArray_Compress \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+         PyArray_API[155])
+#define PyArray_Flatten \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[156])
+#define PyArray_Ravel \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[157])
+#define PyArray_MultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[158])
+#define PyArray_MultiplyIntList \
+        (*(int (*)(int *, int)) \
+         PyArray_API[159])
+#define PyArray_GetPtr \
+        (*(void * (*)(PyArrayObject *, npy_intp*)) \
+         PyArray_API[160])
+#define PyArray_CompareLists \
+        (*(int (*)(npy_intp *, npy_intp *, int)) \
+         PyArray_API[161])
+#define PyArray_AsCArray \
+        (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+         PyArray_API[162])
+#define PyArray_As1D \
+        (*(int (*)(PyObject **, char **, int *, int)) \
+         PyArray_API[163])
+#define PyArray_As2D \
+        (*(int (*)(PyObject **, char ***, int *, int *, int)) \
+         PyArray_API[164])
+#define PyArray_Free \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[165])
+#define PyArray_Converter \
+        (*(int (*)(PyObject *, PyObject **)) \
+         PyArray_API[166])
+#define PyArray_IntpFromSequence \
+        (*(int (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[167])
+#define PyArray_Concatenate \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[168])
+#define PyArray_InnerProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[169])
+#define PyArray_MatrixProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[171])
+#define PyArray_Correlate \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[172])
+#define PyArray_TypestrConvert \
+        (*(int (*)(int, int)) \
+         PyArray_API[173])
+#define PyArray_DescrConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[174])
+#define PyArray_DescrConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[175])
+#define PyArray_IntpConverter \
+        (*(int (*)(PyObject *, PyArray_Dims *)) \
+         PyArray_API[176])
+#define PyArray_BufferConverter \
+        (*(int (*)(PyObject *, PyArray_Chunk *)) \
+         PyArray_API[177])
+#define PyArray_AxisConverter \
+        (*(int (*)(PyObject *, int *)) \
+         PyArray_API[178])
+#define PyArray_BoolConverter \
+        (*(int (*)(PyObject *, npy_bool *)) \
+         PyArray_API[179])
+#define PyArray_ByteorderConverter \
+        (*(int (*)(PyObject *, char *)) \
+         PyArray_API[180])
+#define PyArray_OrderConverter \
+        (*(int (*)(PyObject *, NPY_ORDER *)) \
+         PyArray_API[181])
+#define PyArray_EquivTypes \
+        (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[182])
+#define PyArray_Zeros \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[183])
+#define PyArray_Empty \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[184])
+#define PyArray_Where \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+         PyArray_API[185])
+#define PyArray_Arange \
+        (*(PyObject * (*)(double, double, double, int)) \
+         PyArray_API[186])
+#define PyArray_ArangeObj \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+         PyArray_API[187])
+#define PyArray_SortkindConverter \
+        (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+         PyArray_API[188])
+#define PyArray_LexSort \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[189])
+#define PyArray_Round \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[190])
+#define PyArray_EquivTypenums \
+        (*(unsigned char (*)(int, int)) \
+         PyArray_API[191])
+#define PyArray_RegisterDataType \
+        (*(int (*)(PyArray_Descr *)) \
+         PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+        (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+         PyArray_API[193])
+#define PyArray_RegisterCanCast \
+        (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+         PyArray_API[194])
+#define PyArray_InitArrFuncs \
+        (*(void (*)(PyArray_ArrFuncs *)) \
+         PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+        (*(PyObject * (*)(int, npy_intp *)) \
+         PyArray_API[196])
+#define PyArray_TypeNumFromName \
+        (*(int (*)(char *)) \
+         PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+         PyArray_API[198])
+#define PyArray_OutputConverter \
+        (*(int (*)(PyObject *, PyArrayObject **)) \
+         PyArray_API[199])
+#define PyArray_BroadcastToShape \
+        (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[200])
+#define _PyArray_SigintHandler \
+        (*(void (*)(int)) \
+         PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+        (*(void* (*)(void)) \
+         PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[204])
+#define PyArray_SearchsideConverter \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[205])
+#define PyArray_CheckAxis \
+        (*(PyObject * (*)(PyArrayObject *, int *, int)) \
+         PyArray_API[206])
+#define PyArray_OverflowMultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[207])
+#define PyArray_CompareString \
+        (*(int (*)(char *, char *, size_t)) \
+         PyArray_API[208])
+#define PyArray_MultiIterFromObjects \
+        (*(PyObject * (*)(PyObject **, int, int, ...)) \
+         PyArray_API[209])
+#define PyArray_GetEndianness \
+        (*(int (*)(void)) \
+         PyArray_API[210])
+#define PyArray_GetNDArrayCFeatureVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[211])
+#define PyArray_Correlate2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[212])
+#define PyArray_NeighborhoodIterNew \
+        (*(PyObject* (*)(PyArrayIterObject *, npy_intp *, int, PyArrayObject*)) \
+         PyArray_API[213])
+#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214])
+#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215])
+#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216])
+#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217])
+#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218])
+#define PyArray_SetDatetimeParseFunction \
+        (*(void (*)(PyObject *)) \
+         PyArray_API[219])
+#define PyArray_DatetimeToDatetimeStruct \
+        (*(void (*)(npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[220])
+#define PyArray_TimedeltaToTimedeltaStruct \
+        (*(void (*)(npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[221])
+#define PyArray_DatetimeStructToDatetime \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[222])
+#define PyArray_TimedeltaStructToTimedelta \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[223])
+#define NpyIter_New \
+        (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \
+         PyArray_API[224])
+#define NpyIter_MultiNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \
+         PyArray_API[225])
+#define NpyIter_AdvancedNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \
+         PyArray_API[226])
+#define NpyIter_Copy \
+        (*(NpyIter * (*)(NpyIter *)) \
+         PyArray_API[227])
+#define NpyIter_Deallocate \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[228])
+#define NpyIter_HasDelayedBufAlloc \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[229])
+#define NpyIter_HasExternalLoop \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[230])
+#define NpyIter_EnableExternalLoop \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[231])
+#define NpyIter_GetInnerStrideArray \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[232])
+#define NpyIter_GetInnerLoopSizePtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[233])
+#define NpyIter_Reset \
+        (*(int (*)(NpyIter *, char **)) \
+         PyArray_API[234])
+#define NpyIter_ResetBasePointers \
+        (*(int (*)(NpyIter *, char **, char **)) \
+         PyArray_API[235])
+#define NpyIter_ResetToIterIndexRange \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \
+         PyArray_API[236])
+#define NpyIter_GetNDim \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[237])
+#define NpyIter_GetNOp \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[238])
+#define NpyIter_GetIterNext \
+        (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[239])
+#define NpyIter_GetIterSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[240])
+#define NpyIter_GetIterIndexRange \
+        (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \
+         PyArray_API[241])
+#define NpyIter_GetIterIndex \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[242])
+#define NpyIter_GotoIterIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[243])
+#define NpyIter_HasMultiIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[244])
+#define NpyIter_GetShape \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[245])
+#define NpyIter_GetGetMultiIndex \
+        (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[246])
+#define NpyIter_GotoMultiIndex \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[247])
+#define NpyIter_RemoveMultiIndex \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[248])
+#define NpyIter_HasIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[249])
+#define NpyIter_IsBuffered \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[250])
+#define NpyIter_IsGrowInner \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[251])
+#define NpyIter_GetBufferSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[252])
+#define NpyIter_GetIndexPtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[253])
+#define NpyIter_GotoIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[254])
+#define NpyIter_GetDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[255])
+#define NpyIter_GetDescrArray \
+        (*(PyArray_Descr ** (*)(NpyIter *)) \
+         PyArray_API[256])
+#define NpyIter_GetOperandArray \
+        (*(PyArrayObject ** (*)(NpyIter *)) \
+         PyArray_API[257])
+#define NpyIter_GetIterView \
+        (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \
+         PyArray_API[258])
+#define NpyIter_GetReadFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[259])
+#define NpyIter_GetWriteFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[260])
+#define NpyIter_DebugPrint \
+        (*(void (*)(NpyIter *)) \
+         PyArray_API[261])
+#define NpyIter_IterationNeedsAPI \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[262])
+#define NpyIter_GetInnerFixedStrideArray \
+        (*(void (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[263])
+#define NpyIter_RemoveAxis \
+        (*(int (*)(NpyIter *, int)) \
+         PyArray_API[264])
+#define NpyIter_GetAxisStrideArray \
+        (*(npy_intp * (*)(NpyIter *, int)) \
+         PyArray_API[265])
+#define NpyIter_RequiresBuffering \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[266])
+#define NpyIter_GetInitialDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[267])
+#define NpyIter_CreateCompatibleStrides \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \
+         PyArray_API[268])
+#define PyArray_CastingConverter \
+        (*(int (*)(PyObject *, NPY_CASTING *)) \
+         PyArray_API[269])
+#define PyArray_CountNonzero \
+        (*(npy_intp (*)(PyArrayObject *)) \
+         PyArray_API[270])
+#define PyArray_PromoteTypes \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[271])
+#define PyArray_MinScalarType \
+        (*(PyArray_Descr * (*)(PyArrayObject *)) \
+         PyArray_API[272])
+#define PyArray_ResultType \
+        (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \
+         PyArray_API[273])
+#define PyArray_CanCastArrayTo \
+        (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[274])
+#define PyArray_CanCastTypeTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[275])
+#define PyArray_EinsteinSum \
+        (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \
+         PyArray_API[276])
+#define PyArray_NewLikeArray \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \
+         PyArray_API[277])
+#define PyArray_GetArrayParamsFromObject \
+        (*(int (*)(PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *)) \
+         PyArray_API[278])
+#define PyArray_ConvertClipmodeSequence \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \
+         PyArray_API[279])
+#define PyArray_MatrixProduct2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \
+         PyArray_API[280])
+#define NpyIter_IsFirstVisit \
+        (*(npy_bool (*)(NpyIter *, int)) \
+         PyArray_API[281])
+#define PyArray_SetBaseObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[282])
+#define PyArray_CreateSortedStridePerm \
+        (*(void (*)(int, npy_intp *, npy_stride_sort_item *)) \
+         PyArray_API[283])
+#define PyArray_RemoveAxesInPlace \
+        (*(void (*)(PyArrayObject *, npy_bool *)) \
+         PyArray_API[284])
+#define PyArray_DebugPrint \
+        (*(void (*)(PyArrayObject *)) \
+         PyArray_API[285])
+#define PyArray_FailUnlessWriteable \
+        (*(int (*)(PyArrayObject *, const char *)) \
+         PyArray_API[286])
+#define PyArray_SetUpdateIfCopyBase \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[287])
+#define PyDataMem_NEW \
+        (*(void * (*)(size_t)) \
+         PyArray_API[288])
+#define PyDataMem_FREE \
+        (*(void (*)(void *)) \
+         PyArray_API[289])
+#define PyDataMem_RENEW \
+        (*(void * (*)(void *, size_t)) \
+         PyArray_API[290])
+#define PyDataMem_SetEventHook \
+        (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \
+         PyArray_API[291])
+#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292])
+#define PyArray_MapIterSwapAxes \
+        (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \
+         PyArray_API[293])
+#define PyArray_MapIterArray \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[294])
+#define PyArray_MapIterNext \
+        (*(void (*)(PyArrayMapIterObject *)) \
+         PyArray_API[295])
+#define PyArray_Partition \
+        (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[296])
+#define PyArray_ArgPartition \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[297])
+#define PyArray_SelectkindConverter \
+        (*(int (*)(PyObject *, NPY_SELECTKIND *)) \
+         PyArray_API[298])
+#define PyDataMem_NEW_ZEROED \
+        (*(void * (*)(size_t, size_t)) \
+         PyArray_API[299])
+#define PyArray_CheckAnyScalarExact \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[300])
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/__ufunc_api.h b/tools/msys/mingw64/include/python2.7/numpy/__ufunc_api.h
new file mode 100644
index 0000000000..bad86bda54
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/__ufunc_api.h
@@ -0,0 +1,320 @@
+
+#ifdef _UMATHMODULE
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndData \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForType \
+       (PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *);
+NPY_NO_EXPORT  int PyUFunc_GenericFunction \
+       (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  void PyUFunc_f_f_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_g_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F_As_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_G_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_gg_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F_As_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_GG_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_On_Om \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_GetPyValues \
+       (char *, int *, int *, PyObject **);
+NPY_NO_EXPORT  int PyUFunc_checkfperr \
+       (int, PyObject *, int *);
+NPY_NO_EXPORT  void PyUFunc_clearfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_getfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_handlefperr \
+       (int, PyObject *, int, int *);
+NPY_NO_EXPORT  int PyUFunc_ReplaceLoopBySignature \
+       (PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *);
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndDataAndSignature \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *);
+NPY_NO_EXPORT  int PyUFunc_SetUsesArraysAsData \
+       (void **, size_t);
+NPY_NO_EXPORT  void PyUFunc_e_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_DefaultTypeResolver \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_ValidateCasting \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForDescr \
+       (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *);
+
+#else
+
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+#else
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+void **PyUFunc_API;
+#else
+static void **PyUFunc_API=NULL;
+#endif
+#endif
+
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+#define PyUFunc_FromFuncAndData \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \
+         PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+        (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *)) \
+         PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+        (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+         PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[4])
+#define PyUFunc_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[5])
+#define PyUFunc_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[6])
+#define PyUFunc_g_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[8])
+#define PyUFunc_F_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[9])
+#define PyUFunc_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[10])
+#define PyUFunc_G_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[11])
+#define PyUFunc_O_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[13])
+#define PyUFunc_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[14])
+#define PyUFunc_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[15])
+#define PyUFunc_gg_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[17])
+#define PyUFunc_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[18])
+#define PyUFunc_FF_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[19])
+#define PyUFunc_GG_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[20])
+#define PyUFunc_OO_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[23])
+#define PyUFunc_On_Om \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+        (*(int (*)(char *, int *, int *, PyObject **)) \
+         PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+        (*(int (*)(int, PyObject *, int *)) \
+         PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+        (*(void (*)(void)) \
+         PyUFunc_API[27])
+#define PyUFunc_getfperr \
+        (*(int (*)(void)) \
+         PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+        (*(int (*)(int, PyObject *, int, int *)) \
+         PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+        (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)) \
+         PyUFunc_API[30])
+#define PyUFunc_FromFuncAndDataAndSignature \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \
+         PyUFunc_API[31])
+#define PyUFunc_SetUsesArraysAsData \
+        (*(int (*)(void **, size_t)) \
+         PyUFunc_API[32])
+#define PyUFunc_e_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[33])
+#define PyUFunc_e_e_As_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[34])
+#define PyUFunc_e_e_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[35])
+#define PyUFunc_ee_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[36])
+#define PyUFunc_ee_e_As_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[37])
+#define PyUFunc_ee_e_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[38])
+#define PyUFunc_DefaultTypeResolver \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \
+         PyUFunc_API[39])
+#define PyUFunc_ValidateCasting \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \
+         PyUFunc_API[40])
+#define PyUFunc_RegisterLoopForDescr \
+        (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \
+         PyUFunc_API[41])
+
+static NPY_INLINE int
+_import_umath(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyUFunc_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
+      return -1;
+  }
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_UMATH_RETVAL NULL
+#else
+#define NUMPY_IMPORT_UMATH_RETVAL
+#endif
+
+#define import_umath() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return NUMPY_IMPORT_UMATH_RETVAL;\
+        }\
+    } while(0)
+
+#define import_umath1(ret) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_umath2(ret, msg) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError, msg);\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_ufunc() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+        }\
+    } while(0)
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/_neighborhood_iterator_imp.h b/tools/msys/mingw64/include/python2.7/numpy/_neighborhood_iterator_imp.h
new file mode 100644
index 0000000000..e8860cbc73
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/_neighborhood_iterator_imp.h
@@ -0,0 +1,90 @@
+#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#error You should not include this header directly
+#endif
+/*
+ * Private API (here for inline)
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter);
+
+/*
+ * Update to next item of the iterator
+ *
+ * Note: this simply increment the coordinates vector, last dimension
+ * incremented first , i.e, for dimension 3
+ * ...
+ * -1, -1, -1
+ * -1, -1,  0
+ * -1, -1,  1
+ *  ....
+ * -1,  0, -1
+ * -1,  0,  0
+ *  ....
+ * 0,  -1, -1
+ * 0,  -1,  0
+ *  ....
+ */
+#define _UPDATE_COORD_ITER(c) \
+    wb = iter->coordinates[c] < iter->bounds[c][1]; \
+    if (wb) { \
+        iter->coordinates[c] += 1; \
+        return 0; \
+    } \
+    else { \
+        iter->coordinates[c] = iter->bounds[c][0]; \
+    }
+
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i, wb;
+
+    for (i = iter->nd - 1; i >= 0; --i) {
+        _UPDATE_COORD_ITER(i)
+    }
+
+    return 0;
+}
+
+/*
+ * Version optimized for 2d arrays, manual loop unrolling
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp wb;
+
+    _UPDATE_COORD_ITER(1)
+    _UPDATE_COORD_ITER(0)
+
+    return 0;
+}
+#undef _UPDATE_COORD_ITER
+
+/*
+ * Advance to the next neighbour
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter)
+{
+    _PyArrayNeighborhoodIter_IncrCoord (iter);
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
+
+/*
+ * Reset functions
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i;
+
+    for (i = 0; i < iter->nd; ++i) {
+        iter->coordinates[i] = iter->bounds[i][0];
+    }
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
diff --git a/tools/msys/mingw64/include/python2.7/numpy/_numpyconfig.h b/tools/msys/mingw64/include/python2.7/numpy/_numpyconfig.h
new file mode 100644
index 0000000000..74ea19b4ff
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/_numpyconfig.h
@@ -0,0 +1,31 @@
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_FLOAT 4
+#define NPY_SIZEOF_COMPLEX_FLOAT 8
+#define NPY_SIZEOF_DOUBLE 8
+#define NPY_SIZEOF_COMPLEX_DOUBLE 16
+#define NPY_SIZEOF_LONGDOUBLE 16
+#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 32
+#define NPY_SIZEOF_PY_INTPTR_T 8
+#define NPY_SIZEOF_OFF_T 4
+#define NPY_SIZEOF_PY_LONG_LONG 8
+#define NPY_SIZEOF_LONGLONG 8
+#define NPY_NO_SIGNAL 1
+#define NPY_NO_SMP 0
+#define NPY_HAVE_DECL_ISNAN
+#define NPY_HAVE_DECL_ISINF
+#define NPY_HAVE_DECL_ISFINITE
+#define NPY_HAVE_DECL_SIGNBIT
+#define NPY_USE_C99_COMPLEX 1
+#define NPY_HAVE_COMPLEX_DOUBLE 1
+#define NPY_HAVE_COMPLEX_FLOAT 1
+#define NPY_HAVE_COMPLEX_LONG_DOUBLE 1
+#define NPY_USE_C99_FORMATS 1
+#define NPY_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#define NPY_ABI_VERSION 0x01000009
+#define NPY_API_VERSION 0x0000000A
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/arrayobject.h b/tools/msys/mingw64/include/python2.7/numpy/arrayobject.h
new file mode 100644
index 0000000000..4f46d6b1ac
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/arrayobject.h
@@ -0,0 +1,11 @@
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/arrayscalars.h b/tools/msys/mingw64/include/python2.7/numpy/arrayscalars.h
new file mode 100644
index 0000000000..64450e7132
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/arrayscalars.h
@@ -0,0 +1,175 @@
+#ifndef _NPY_ARRAYSCALARS_H_
+#define _NPY_ARRAYSCALARS_H_
+
+#ifndef _MULTIARRAYMODULE
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+#endif
+
+
+typedef struct {
+        PyObject_HEAD
+        signed char obval;
+} PyByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        short obval;
+} PyShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        int obval;
+} PyIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        long obval;
+} PyLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longlong obval;
+} PyLongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned char obval;
+} PyUByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned short obval;
+} PyUShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned int obval;
+} PyUIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned long obval;
+} PyULongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_ulonglong obval;
+} PyULongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_half obval;
+} PyHalfScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        float obval;
+} PyFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        double obval;
+} PyDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longdouble obval;
+} PyLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cfloat obval;
+} PyCFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cdouble obval;
+} PyCDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        PyObject * obval;
+} PyObjectScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_datetime obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyDatetimeScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_timedelta obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyTimedeltaScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        char obval;
+} PyScalarObject;
+
+#define PyStringScalarObject PyStringObject
+#define PyUnicodeScalarObject PyUnicodeObject
+
+typedef struct {
+        PyObject_VAR_HEAD
+        char *obval;
+        PyArray_Descr *descr;
+        int flags;
+        PyObject *base;
+} PyVoidScalarObject;
+
+/* Macros
+     Py<Cls><bitsize>ScalarObject
+     Py<Cls><bitsize>ArrType_Type
+   are defined in ndarrayobject.h
+*/
+
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+        ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i)                  \
+        return Py_INCREF(PyArrayScalar_FromLong(i)), \
+                PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE              \
+        return Py_INCREF(PyArrayScalar_False),  \
+                PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE               \
+        return Py_INCREF(PyArrayScalar_True),   \
+                PyArrayScalar_True
+
+#define PyArrayScalar_New(cls) \
+        Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls)             \
+        ((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+        PyArrayScalar_VAL(obj, cls) = val
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/halffloat.h b/tools/msys/mingw64/include/python2.7/numpy/halffloat.h
new file mode 100644
index 0000000000..ab0d221fb4
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/halffloat.h
@@ -0,0 +1,70 @@
+#ifndef __NPY_HALFFLOAT_H__
+#define __NPY_HALFFLOAT_H__
+
+#include <Python.h>
+#include <numpy/npy_math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Half-precision routines
+ */
+
+/* Conversions */
+float npy_half_to_float(npy_half h);
+double npy_half_to_double(npy_half h);
+npy_half npy_float_to_half(float f);
+npy_half npy_double_to_half(double d);
+/* Comparisons */
+int npy_half_eq(npy_half h1, npy_half h2);
+int npy_half_ne(npy_half h1, npy_half h2);
+int npy_half_le(npy_half h1, npy_half h2);
+int npy_half_lt(npy_half h1, npy_half h2);
+int npy_half_ge(npy_half h1, npy_half h2);
+int npy_half_gt(npy_half h1, npy_half h2);
+/* faster *_nonan variants for when you know h1 and h2 are not NaN */
+int npy_half_eq_nonan(npy_half h1, npy_half h2);
+int npy_half_lt_nonan(npy_half h1, npy_half h2);
+int npy_half_le_nonan(npy_half h1, npy_half h2);
+/* Miscellaneous functions */
+int npy_half_iszero(npy_half h);
+int npy_half_isnan(npy_half h);
+int npy_half_isinf(npy_half h);
+int npy_half_isfinite(npy_half h);
+int npy_half_signbit(npy_half h);
+npy_half npy_half_copysign(npy_half x, npy_half y);
+npy_half npy_half_spacing(npy_half h);
+npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
+
+/*
+ * Half-precision constants
+ */
+
+#define NPY_HALF_ZERO   (0x0000u)
+#define NPY_HALF_PZERO  (0x0000u)
+#define NPY_HALF_NZERO  (0x8000u)
+#define NPY_HALF_ONE    (0x3c00u)
+#define NPY_HALF_NEGONE (0xbc00u)
+#define NPY_HALF_PINF   (0x7c00u)
+#define NPY_HALF_NINF   (0xfc00u)
+#define NPY_HALF_NAN    (0x7e00u)
+
+#define NPY_MAX_HALF    (0x7bffu)
+
+/*
+ * Bit-level conversions
+ */
+
+npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f);
+npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d);
+npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h);
+npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/multiarray_api.txt b/tools/msys/mingw64/include/python2.7/numpy/multiarray_api.txt
new file mode 100644
index 0000000000..3a0683da3c
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/multiarray_api.txt
@@ -0,0 +1,2449 @@
+
+===========
+Numpy C-API
+===========
+::
+
+  unsigned int
+  PyArray_GetNDArrayCVersion(void )
+
+
+Included at the very first so not auto-grabbed and thus not labeled.
+
+::
+
+  int
+  PyArray_SetNumericOps(PyObject *dict)
+
+Set internal structure with number functions that all arrays will use
+
+::
+
+  PyObject *
+  PyArray_GetNumericOps(void )
+
+Get dictionary showing number functions that all arrays will use
+
+::
+
+  int
+  PyArray_INCREF(PyArrayObject *mp)
+
+For object arrays, increment all internal references.
+
+::
+
+  int
+  PyArray_XDECREF(PyArrayObject *mp)
+
+Decrement all internal references for object arrays.
+(or arrays with object fields)
+
+::
+
+  void
+  PyArray_SetStringFunction(PyObject *op, int repr)
+
+Set the array print function to be a Python function.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromType(int type)
+
+Get the PyArray_Descr structure for a type.
+
+::
+
+  PyObject *
+  PyArray_TypeObjectFromType(int type)
+
+Get a typeobject from a type-number -- can return NULL.
+
+New reference
+
+::
+
+  char *
+  PyArray_Zero(PyArrayObject *arr)
+
+Get pointer to zero of correct type for array.
+
+::
+
+  char *
+  PyArray_One(PyArrayObject *arr)
+
+Get pointer to one of correct type for array
+
+::
+
+  PyObject *
+  PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int
+                     is_f_order)
+
+For backward compatibility
+
+Cast an array using typecode structure.
+steals reference to dtype --- cannot be NULL
+
+This function always makes a copy of arr, even if the dtype
+doesn't change.
+
+::
+
+  int
+  PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.
+
+::
+
+  int
+  PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.  Arrays don't have to be "broadcastable"
+Only requirement is they have the same number of elements.
+
+::
+
+  int
+  PyArray_CanCastSafely(int fromtype, int totype)
+
+Check the type coercion rules.
+
+::
+
+  npy_bool
+  PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
+
+leaves reference count alone --- cannot be NULL
+
+PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
+parameter.
+
+::
+
+  int
+  PyArray_ObjectType(PyObject *op, int minimum_type)
+
+Return the typecode of the array a Python object would be converted to
+
+Returns the type number the result should have, or NPY_NOTYPE on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
+
+new reference -- accepts NULL for mintype
+
+::
+
+  PyArrayObject **
+  PyArray_ConvertToCommonType(PyObject *op, int *retn)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromScalar(PyObject *sc)
+
+Return descr object from array scalar.
+
+New reference
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromTypeObject(PyObject *type)
+
+
+::
+
+  npy_intp
+  PyArray_Size(PyObject *op)
+
+Compute the size of an array (in number of items)
+
+::
+
+  PyObject *
+  PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
+
+Get scalar-equivalent to a region of memory described by a descriptor.
+
+::
+
+  PyObject *
+  PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
+
+Get 0-dim array from scalar
+
+0-dim array from array-scalar object
+always contains a copy of the data
+unless outcode is NULL, it is of void type and the referrer does
+not own it either.
+
+steals reference to outcode
+
+::
+
+  void
+  PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
+
+Convert to c-type
+
+no error checking is performed -- ctypeptr must be same type as scalar
+in case of flexible type, the data is not copied
+into ctypeptr which is expected to be a pointer to pointer
+
+::
+
+  int
+  PyArray_CastScalarToCtype(PyObject *scalar, void
+                            *ctypeptr, PyArray_Descr *outcode)
+
+Cast Scalar to c-type
+
+The output buffer must be large-enough to receive the value
+Even for flexible types which is different from ScalarAsCtype
+where only a reference for flexible types is returned
+
+This may not work right on narrow builds for NumPy unicode scalars.
+
+::
+
+  int
+  PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr
+                           *indescr, void *ctypeptr, int outtype)
+
+Cast Scalar to c-type
+
+::
+
+  PyObject *
+  PyArray_ScalarFromObject(PyObject *object)
+
+Get an Array Scalar From a Python Object
+
+Returns NULL if unsuccessful but error is only set if another error occurred.
+Currently only Numeric-like object supported.
+
+::
+
+  PyArray_VectorUnaryFunc *
+  PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
+
+Get a cast function to cast from the input descriptor to the
+output type_number (must be a registered data-type).
+Returns NULL if un-successful.
+
+::
+
+  PyObject *
+  PyArray_FromDims(int nd, int *d, int type)
+
+Construct an empty array from dimensions and typenum
+
+::
+
+  PyObject *
+  PyArray_FromDimsAndDataAndDescr(int nd, int *d, PyArray_Descr
+                                  *descr, char *data)
+
+Like FromDimsAndData but uses the Descr structure instead of typecode
+as input.
+
+::
+
+  PyObject *
+  PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int
+                  min_depth, int max_depth, int flags, PyObject
+                  *context)
+
+Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
+Steals a reference to newtype --- which can be NULL
+
+::
+
+  PyObject *
+  PyArray_EnsureArray(PyObject *op)
+
+This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY)
+that special cases Arrays and PyArray_Scalars up front
+It *steals a reference* to the object
+It also guarantees that the result is PyArray_Type
+Because it decrefs op if any conversion needs to take place
+so it can be used like PyArray_EnsureArray(some_function(...))
+
+::
+
+  PyObject *
+  PyArray_EnsureAnyArray(PyObject *op)
+
+
+::
+
+  PyObject *
+  PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char
+                   *sep)
+
+
+Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
+array corresponding to the data encoded in that file.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+For memory-mapped files, use the buffer interface. No more data than
+necessary is read by this routine.
+
+::
+
+  PyObject *
+  PyArray_FromString(char *data, npy_intp slen, PyArray_Descr
+                     *dtype, npy_intp num, char *sep)
+
+
+Given a pointer to a string ``data``, a string length ``slen``, and
+a ``PyArray_Descr``, return an array corresponding to the data
+encoded in that string.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+If ``slen`` is < 0, then the end of string is used for text data.
+It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs
+would be the norm).
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+::
+
+  PyObject *
+  PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp
+                     count, npy_intp offset)
+
+
+::
+
+  PyObject *
+  PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count)
+
+
+steals a reference to dtype (which cannot be NULL)
+
+::
+
+  PyObject *
+  PyArray_Return(PyArrayObject *mp)
+
+
+Return either an array or the appropriate Python object if the array
+is 0d and matches a Python type.
+steals reference to mp
+
+::
+
+  PyObject *
+  PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int
+                   offset)
+
+Get a subset of bytes from each element of the array
+steals reference to typed, must not be NULL
+
+::
+
+  int
+  PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int
+                   offset, PyObject *val)
+
+Set a subset of bytes from each element of the array
+steals reference to dtype, must not be NULL
+
+::
+
+  PyObject *
+  PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)
+
+
+::
+
+  PyObject *
+  PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int
+                 refcheck, NPY_ORDER order)
+
+Resize (reallocate data).  Only works if nothing else is referencing this
+array and it is contiguous.  If refcheck is 0, then the reference count is
+not checked and assumed to be 1.  You still must own this data and have no
+weak-references and no base object.
+
+::
+
+  int
+  PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src)
+
+Move the memory of one array into another, allowing for overlapping data.
+
+Returns 0 on success, negative on failure.
+
+::
+
+  int
+  PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array.
+Broadcast to the destination shape if necessary.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  int
+  PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array -- memory must not overlap
+Does not require src and dest to have "broadcastable" shapes
+(only the same number of elements).
+
+TODO: For NumPy 2.0, this could accept an order parameter which
+only allows NPY_CORDER and NPY_FORDER.  Could also rename
+this to CopyAsFlat to make the name more intuitive.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
+
+
+::
+
+  PyObject *
+  PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order)
+
+Copy an array.
+
+::
+
+  PyObject *
+  PyArray_ToList(PyArrayObject *self)
+
+To List
+
+::
+
+  PyObject *
+  PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
+
+
+::
+
+  int
+  PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
+
+To File
+
+::
+
+  int
+  PyArray_Dump(PyObject *self, PyObject *file, int protocol)
+
+
+::
+
+  PyObject *
+  PyArray_Dumps(PyObject *self, int protocol)
+
+
+::
+
+  int
+  PyArray_ValidType(int type)
+
+Is the typenum valid?
+
+::
+
+  void
+  PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
+
+Update Several Flags at once.
+
+::
+
+  PyObject *
+  PyArray_New(PyTypeObject *subtype, int nd, npy_intp *dims, int
+              type_num, npy_intp *strides, void *data, int itemsize, int
+              flags, PyObject *obj)
+
+Generic new array creation routine.
+
+::
+
+  PyObject *
+  PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int
+                       nd, npy_intp *dims, npy_intp *strides, void
+                       *data, int flags, PyObject *obj)
+
+Generic new array creation routine.
+
+steals a reference to descr (even on failure)
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNew(PyArray_Descr *base)
+
+base cannot be NULL
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewFromType(int type_num)
+
+
+::
+
+  double
+  PyArray_GetPriority(PyObject *obj, double default_)
+
+Get Priority from object
+
+::
+
+  PyObject *
+  PyArray_IterNew(PyObject *obj)
+
+Get Iterator.
+
+::
+
+  PyObject *
+  PyArray_MultiIterNew(int n, ... )
+
+Get MultiIterator,
+
+::
+
+  int
+  PyArray_PyIntAsInt(PyObject *o)
+
+
+::
+
+  npy_intp
+  PyArray_PyIntAsIntp(PyObject *o)
+
+
+::
+
+  int
+  PyArray_Broadcast(PyArrayMultiIterObject *mit)
+
+
+::
+
+  void
+  PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
+
+Assumes contiguous
+
+::
+
+  int
+  PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
+
+
+::
+
+  npy_bool
+  PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp
+                       offset, npy_intp *dims, npy_intp *newstrides)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+
+
+returns a copy of the PyArray_Descr structure with the byteorder
+altered:
+no arguments:  The byteorder is swapped (in all subfields as well)
+single argument:  The byteorder is forced to the given state
+(in all subfields as well)
+
+Valid states:  ('big', '>') or ('little' or '<')
+('native', or '=')
+
+If a descr structure with | is encountered it's own
+byte-order is not changed but any fields are:
+
+
+Deep bytorder change of a data-type descriptor
+Leaves reference count of self unchanged --- does not DECREF self ***
+
+::
+
+  PyObject *
+  PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
+
+Get Iterator that iterates over all but one axis (don't use this with
+PyArray_ITER_GOTO1D).  The axis will be over-written if negative
+with the axis having the smallest stride.
+
+::
+
+  PyObject *
+  PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int
+                       min_depth, int max_depth, int requires, PyObject
+                       *context)
+
+steals a reference to descr -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int
+                    flags)
+
+steals reference to newtype --- acc. NULL
+
+::
+
+  PyObject *
+  PyArray_FromInterface(PyObject *origin)
+
+
+::
+
+  PyObject *
+  PyArray_FromStructInterface(PyObject *input)
+
+
+::
+
+  PyObject *
+  PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject
+                        *context)
+
+
+::
+
+  NPY_SCALARKIND
+  PyArray_ScalarKind(int typenum, PyArrayObject **arr)
+
+ScalarKind
+
+Returns the scalar kind of a type number, with an
+optional tweak based on the scalar value itself.
+If no scalar is provided, it returns INTPOS_SCALAR
+for both signed and unsigned integers, otherwise
+it checks the sign of any signed integer to choose
+INTNEG_SCALAR when appropriate.
+
+::
+
+  int
+  PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND
+                          scalar)
+
+
+Determines whether the data type 'thistype', with
+scalar kind 'scalar', can be coerced into 'neededtype'.
+
+::
+
+  PyObject *
+  PyArray_NewFlagsObject(PyObject *obj)
+
+
+Get New ArrayFlagsObject
+
+::
+
+  npy_bool
+  PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
+
+See if array scalars can be cast.
+
+TODO: For NumPy 2.0, add a NPY_CASTING parameter.
+
+::
+
+  int
+  PyArray_CompareUCS4(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
+
+
+::
+
+  int
+  PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
+
+Adjusts previously broadcasted iterators so that the axis with
+the smallest sum of iterator strides is not iterated over.
+Returns dimension which is smallest in the range [0,multi->nd).
+A -1 is returned if multi->nd == 0.
+
+don't use with PyArray_ITER_GOTO1D because factors are not adjusted
+
+::
+
+  int
+  PyArray_ElementStrides(PyObject *obj)
+
+
+::
+
+  void
+  PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  void
+  PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  PyObject *
+  PyArray_FieldNames(PyObject *fields)
+
+Return the tuple of ordered field names from a dictionary.
+
+::
+
+  PyObject *
+  PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
+
+Return Transpose.
+
+::
+
+  PyObject *
+  PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int
+                   axis, PyArrayObject *out, NPY_CLIPMODE clipmode)
+
+Take
+
+::
+
+  PyObject *
+  PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject
+                *indices0, NPY_CLIPMODE clipmode)
+
+Put values into an array
+
+::
+
+  PyObject *
+  PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0)
+
+Put values into an array according to a mask.
+
+::
+
+  PyObject *
+  PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis)
+
+Repeat the array.
+
+::
+
+  PyObject *
+  PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject
+                 *out, NPY_CLIPMODE clipmode)
+
+
+::
+
+  int
+  PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+Sort an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+ArgSort an array
+
+::
+
+  PyObject *
+  PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE
+                       side, PyObject *perm)
+
+
+Search the sorted array op1 for the location of the items in op2. The
+result is an array of indexes, one for each element in op2, such that if
+the item were to be inserted in op1 just before that index the array
+would still be in sorted order.
+
+Parameters
+----------
+op1 : PyArrayObject *
+Array to be searched, must be 1-D.
+op2 : PyObject *
+Array of items whose insertion indexes in op1 are wanted
+side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT}
+If NPY_SEARCHLEFT, return first valid insertion indexes
+If NPY_SEARCHRIGHT, return last valid insertion indexes
+perm : PyObject *
+Permutation array that sorts op1 (optional)
+
+Returns
+-------
+ret : PyObject *
+New reference to npy_intp array containing indexes where items in op2
+could be validly inserted into op1. NULL on error.
+
+Notes
+-----
+Binary search is used to find the indexes.
+
+::
+
+  PyObject *
+  PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMax
+
+::
+
+  PyObject *
+  PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMin
+
+::
+
+  PyObject *
+  PyArray_Reshape(PyArrayObject *self, PyObject *shape)
+
+Reshape
+
+::
+
+  PyObject *
+  PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER
+                   order)
+
+New shape for an array
+
+::
+
+  PyObject *
+  PyArray_Squeeze(PyArrayObject *self)
+
+
+return a new view of the array object with all of its unit-length
+dimensions squeezed out if needed, otherwise
+return the same array.
+
+::
+
+  PyObject *
+  PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject
+               *pytype)
+
+View
+steals a reference to type -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2)
+
+SwapAxes
+
+::
+
+  PyObject *
+  PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Max
+
+::
+
+  PyObject *
+  PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Min
+
+::
+
+  PyObject *
+  PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Ptp
+
+::
+
+  PyObject *
+  PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Mean
+
+::
+
+  PyObject *
+  PyArray_Trace(PyArrayObject *self, int offset, int axis1, int
+                axis2, int rtype, PyArrayObject *out)
+
+Trace
+
+::
+
+  PyObject *
+  PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int
+                   axis2)
+
+Diagonal
+
+In NumPy versions prior to 1.7,  this function always returned a copy of
+the diagonal array. In 1.7, the code has been updated to compute a view
+onto 'self', but it still copies this array before returning, as well as
+setting the internal WARN_ON_WRITE flag. In a future version, it will
+simply return a view onto self.
+
+::
+
+  PyObject *
+  PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject
+               *max, PyArrayObject *out)
+
+Clip
+
+::
+
+  PyObject *
+  PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
+
+Conjugate
+
+::
+
+  PyObject *
+  PyArray_Nonzero(PyArrayObject *self)
+
+Nonzero
+
+TODO: In NumPy 2.0, should make the iteration order a parameter.
+
+::
+
+  PyObject *
+  PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out, int variance)
+
+Set variance to 1 to by-pass square-root calculation and return variance
+Std
+
+::
+
+  PyObject *
+  PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out)
+
+Sum
+
+::
+
+  PyObject *
+  PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+                 *out)
+
+CumSum
+
+::
+
+  PyObject *
+  PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Prod
+
+::
+
+  PyObject *
+  PyArray_CumProd(PyArrayObject *self, int axis, int
+                  rtype, PyArrayObject *out)
+
+CumProd
+
+::
+
+  PyObject *
+  PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)
+
+All
+
+::
+
+  PyObject *
+  PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)
+
+Any
+
+::
+
+  PyObject *
+  PyArray_Compress(PyArrayObject *self, PyObject *condition, int
+                   axis, PyArrayObject *out)
+
+Compress
+
+::
+
+  PyObject *
+  PyArray_Flatten(PyArrayObject *a, NPY_ORDER order)
+
+Flatten
+
+::
+
+  PyObject *
+  PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order)
+
+Ravel
+Returns a contiguous array
+
+::
+
+  npy_intp
+  PyArray_MultiplyList(npy_intp *l1, int n)
+
+Multiply a List
+
+::
+
+  int
+  PyArray_MultiplyIntList(int *l1, int n)
+
+Multiply a List of ints
+
+::
+
+  void *
+  PyArray_GetPtr(PyArrayObject *obj, npy_intp*ind)
+
+Produce a pointer into array
+
+::
+
+  int
+  PyArray_CompareLists(npy_intp *l1, npy_intp *l2, int n)
+
+Compare Lists
+
+::
+
+  int
+  PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int
+                   nd, PyArray_Descr*typedescr)
+
+Simulate a C-array
+steals a reference to typedescr -- can be NULL
+
+::
+
+  int
+  PyArray_As1D(PyObject **op, char **ptr, int *d1, int typecode)
+
+Convert to a 1D C-array
+
+::
+
+  int
+  PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, int
+               typecode)
+
+Convert to a 2D C-array
+
+::
+
+  int
+  PyArray_Free(PyObject *op, void *ptr)
+
+Free pointers created if As2D is called
+
+::
+
+  int
+  PyArray_Converter(PyObject *object, PyObject **address)
+
+
+Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
+
+This conversion function can be used with the "O&" argument for
+PyArg_ParseTuple.  It will immediately return an object of array type
+or will convert to a NPY_ARRAY_CARRAY any other object.
+
+If you use PyArray_Converter, you must DECREF the array when finished
+as you get a new reference to it.
+
+::
+
+  int
+  PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
+
+PyArray_IntpFromSequence
+Returns the number of integers converted or -1 if an error occurred.
+vals must be large enough to hold maxvals
+
+::
+
+  PyObject *
+  PyArray_Concatenate(PyObject *op, int axis)
+
+Concatenate
+
+Concatenate an arbitrary Python sequence into an array.
+op is a python object supporting the sequence interface.
+Its elements will be concatenated together to form a single
+multidimensional array. If axis is NPY_MAXDIMS or bigger, then
+each sequence object will be flattened before concatenation
+
+::
+
+  PyObject *
+  PyArray_InnerProduct(PyObject *op1, PyObject *op2)
+
+Numeric.innerproduct(a,v)
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct(PyObject *op1, PyObject *op2)
+
+Numeric.matrixproduct(a,v)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  PyObject *
+  PyArray_CopyAndTranspose(PyObject *op)
+
+Copy and Transpose
+
+Could deprecate this function, as there isn't a speed benefit over
+calling Transpose and then Copy.
+
+::
+
+  PyObject *
+  PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
+
+Numeric.correlate(a1,a2,mode)
+
+::
+
+  int
+  PyArray_TypestrConvert(int itemsize, int gentype)
+
+Typestr converter
+
+::
+
+  int
+  PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
+This function takes a Python object representing a type and converts it
+to a the correct PyArray_Descr * structure to describe the type.
+
+Many objects can be used to represent a data-type which in NumPy is
+quite a flexible concept.
+
+This is the central code that converts Python objects to
+Type-descriptor objects that are used throughout numpy.
+
+Returns a new reference in *at, but the returned should not be
+modified as it may be one of the canonical immutable objects or
+a reference to the input obj.
+
+::
+
+  int
+  PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NULL
+
+::
+
+  int
+  PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)
+
+Get intp chunk from sequence
+
+This function takes a Python sequence object and allocates and
+fills in an intp array with the converted values.
+
+Remember to free the pointer seq.ptr when done using
+PyDimMem_FREE(seq.ptr)**
+
+::
+
+  int
+  PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
+
+Get buffer chunk from object
+
+this function takes a Python object which exposes the (single-segment)
+buffer interface and returns a pointer to the data segment
+
+You should increment the reference count by one of buf->base
+if you will hang on to a reference
+
+You only get a borrowed reference to the object. Do not free the
+memory...
+
+::
+
+  int
+  PyArray_AxisConverter(PyObject *obj, int *axis)
+
+Get axis from an object (possibly None) -- a converter function,
+
+See also PyArray_ConvertMultiAxis, which also handles a tuple of axes.
+
+::
+
+  int
+  PyArray_BoolConverter(PyObject *object, npy_bool *val)
+
+Convert an object to true / false
+
+::
+
+  int
+  PyArray_ByteorderConverter(PyObject *obj, char *endian)
+
+Convert object to endian
+
+::
+
+  int
+  PyArray_OrderConverter(PyObject *object, NPY_ORDER *val)
+
+Convert an object to FORTRAN / C / ANY / KEEP
+
+::
+
+  unsigned char
+  PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+
+This function returns true if the two typecodes are
+equivalent (same basic kind and same itemsize).
+
+::
+
+  PyObject *
+  PyArray_Zeros(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Zeros
+
+steal a reference
+accepts NULL type
+
+::
+
+  PyObject *
+  PyArray_Empty(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Empty
+
+accepts NULL type
+steals referenct to type
+
+::
+
+  PyObject *
+  PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)
+
+Where
+
+::
+
+  PyObject *
+  PyArray_Arange(double start, double stop, double step, int type_num)
+
+Arange,
+
+::
+
+  PyObject *
+  PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject
+                    *step, PyArray_Descr *dtype)
+
+
+ArangeObj,
+
+this doesn't change the references
+
+::
+
+  int
+  PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
+
+Convert object to sort kind
+
+::
+
+  PyObject *
+  PyArray_LexSort(PyObject *sort_keys, int axis)
+
+LexSort an array providing indices that will sort a collection of arrays
+lexicographically.  The first key is sorted on first, followed by the second key
+-- requires that arg"merge"sort is available for each sort_key
+
+Returns an index array that shows the indexes for the lexicographic sort along
+the given axis.
+
+::
+
+  PyObject *
+  PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out)
+
+Round
+
+::
+
+  unsigned char
+  PyArray_EquivTypenums(int typenum1, int typenum2)
+
+
+::
+
+  int
+  PyArray_RegisterDataType(PyArray_Descr *descr)
+
+Register Data type
+Does not change the reference count of descr
+
+::
+
+  int
+  PyArray_RegisterCastFunc(PyArray_Descr *descr, int
+                           totype, PyArray_VectorUnaryFunc *castfunc)
+
+Register Casting Function
+Replaces any function currently stored.
+
+::
+
+  int
+  PyArray_RegisterCanCast(PyArray_Descr *descr, int
+                          totype, NPY_SCALARKIND scalar)
+
+Register a type number indicating that a descriptor can be cast
+to it safely
+
+::
+
+  void
+  PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
+
+Initialize arrfuncs to NULL
+
+::
+
+  PyObject *
+  PyArray_IntTupleFromIntp(int len, npy_intp *vals)
+
+PyArray_IntTupleFromIntp
+
+::
+
+  int
+  PyArray_TypeNumFromName(char *str)
+
+
+::
+
+  int
+  PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)
+
+Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP
+
+::
+
+  int
+  PyArray_OutputConverter(PyObject *object, PyArrayObject **address)
+
+Useful to pass as converter function for O& processing in
+PyArgs_ParseTuple for output arrays
+
+::
+
+  PyObject *
+  PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd)
+
+Get Iterator broadcast to a particular shape
+
+::
+
+  void
+  _PyArray_SigintHandler(int signum)
+
+
+::
+
+  void*
+  _PyArray_GetSigintBuf(void )
+
+
+::
+
+  int
+  PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to DEFAULT type.
+
+any object with the .fields attribute and/or .itemsize attribute (if the
+.fields attribute does not give the total size -- i.e. a partial record
+naming).  If itemsize is given it must be >= size computed from fields
+
+The .fields attribute must return a convertible dictionary if present.
+Result inherits from NPY_VOID.
+
+::
+
+  int
+  PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to NULL.
+
+::
+
+  int
+  PyArray_SearchsideConverter(PyObject *obj, void *addr)
+
+Convert object to searchsorted side
+
+::
+
+  PyObject *
+  PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
+
+PyArray_CheckAxis
+
+check that axis is valid
+convert 0-d arrays to 1-d arrays
+
+::
+
+  npy_intp
+  PyArray_OverflowMultiplyList(npy_intp *l1, int n)
+
+Multiply a List of Non-negative numbers with over-flow detection.
+
+::
+
+  int
+  PyArray_CompareString(char *s1, char *s2, size_t len)
+
+
+::
+
+  PyObject *
+  PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... )
+
+Get MultiIterator from array of Python objects and any additional
+
+PyObject **mps -- array of PyObjects
+int n - number of PyObjects in the array
+int nadd - number of additional arrays to include in the iterator.
+
+Returns a multi-iterator object.
+
+::
+
+  int
+  PyArray_GetEndianness(void )
+
+
+::
+
+  unsigned int
+  PyArray_GetNDArrayCFeatureVersion(void )
+
+Returns the built-in (at compilation time) C API version
+
+::
+
+  PyObject *
+  PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)
+
+correlate(a1,a2,mode)
+
+This function computes the usual correlation (correlate(a1, a2) !=
+correlate(a2, a1), and conjugate the second argument for complex inputs
+
+::
+
+  PyObject*
+  PyArray_NeighborhoodIterNew(PyArrayIterObject *x, npy_intp
+                              *bounds, int mode, PyArrayObject*fill)
+
+A Neighborhood Iterator object.
+
+::
+
+  void
+  PyArray_SetDatetimeParseFunction(PyObject *op)
+
+This function is scheduled to be removed
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *result)
+
+Fill the datetime struct from the value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_TimedeltaToTimedeltaStruct(npy_timedelta val, NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *result)
+
+Fill the timedelta struct from the timedelta value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *d)
+
+Create a datetime value from a filled datetime struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *d)
+
+Create a timdelta value from a filled timedelta struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  NpyIter *
+  NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER
+              order, NPY_CASTING casting, PyArray_Descr*dtype)
+
+Allocate a new iterator for one array object.
+
+::
+
+  NpyIter *
+  NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32
+                   flags, NPY_ORDER order, NPY_CASTING
+                   casting, npy_uint32 *op_flags, PyArray_Descr
+                   **op_request_dtypes)
+
+Allocate a new iterator for more than one array object, using
+standard NumPy broadcasting rules and the default buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32
+                      flags, NPY_ORDER order, NPY_CASTING
+                      casting, npy_uint32 *op_flags, PyArray_Descr
+                      **op_request_dtypes, int oa_ndim, int
+                      **op_axes, npy_intp *itershape, npy_intp
+                      buffersize)
+
+Allocate a new iterator for multiple array objects, and advanced
+options for controlling the broadcasting, shape, and buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_Copy(NpyIter *iter)
+
+Makes a copy of the iterator
+
+::
+
+  int
+  NpyIter_Deallocate(NpyIter *iter)
+
+Deallocate an iterator
+
+::
+
+  npy_bool
+  NpyIter_HasDelayedBufAlloc(NpyIter *iter)
+
+Whether the buffer allocation is being delayed
+
+::
+
+  npy_bool
+  NpyIter_HasExternalLoop(NpyIter *iter)
+
+Whether the iterator handles the inner loop
+
+::
+
+  int
+  NpyIter_EnableExternalLoop(NpyIter *iter)
+
+Removes the inner loop handling (so HasExternalLoop returns true)
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerStrideArray(NpyIter *iter)
+
+Get the array of strides for the inner loop (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerLoopSizePtr(NpyIter *iter)
+
+Get a pointer to the size of the inner loop  (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_Reset(NpyIter *iter, char **errmsg)
+
+Resets the iterator to its initial state
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char
+                            **errmsg)
+
+Resets the iterator to its initial state, with new base data pointers.
+This function requires great caution.
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp
+                                iend, char **errmsg)
+
+Resets the iterator to a new iterator index range
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GetNDim(NpyIter *iter)
+
+Gets the number of dimensions being iterated
+
+::
+
+  int
+  NpyIter_GetNOp(NpyIter *iter)
+
+Gets the number of operands being iterated
+
+::
+
+  NpyIter_IterNextFunc *
+  NpyIter_GetIterNext(NpyIter *iter, char **errmsg)
+
+Compute the specialized iteration function for an iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  npy_intp
+  NpyIter_GetIterSize(NpyIter *iter)
+
+Gets the number of elements being iterated
+
+::
+
+  void
+  NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp
+                            *iend)
+
+Gets the range of iteration indices being iterated
+
+::
+
+  npy_intp
+  NpyIter_GetIterIndex(NpyIter *iter)
+
+Gets the current iteration index
+
+::
+
+  int
+  NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex)
+
+Sets the iterator position to the specified iterindex,
+which matches the iteration order of the iterator.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  npy_bool
+  NpyIter_HasMultiIndex(NpyIter *iter)
+
+Whether the iterator is tracking a multi-index
+
+::
+
+  int
+  NpyIter_GetShape(NpyIter *iter, npy_intp *outshape)
+
+Gets the broadcast shape if a multi-index is being tracked by the iterator,
+otherwise gets the shape of the iteration as Fortran-order
+(fastest-changing index first).
+
+The reason Fortran-order is returned when a multi-index
+is not enabled is that this is providing a direct view into how
+the iterator traverses the n-dimensional space. The iterator organizes
+its memory from fastest index to slowest index, and when
+a multi-index is enabled, it uses a permutation to recover the original
+order.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  NpyIter_GetMultiIndexFunc *
+  NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg)
+
+Compute a specialized get_multi_index function for the iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp *multi_index)
+
+Sets the iterator to the specified multi-index, which must have the
+correct number of entries for 'ndim'.  It is only valid
+when NPY_ITER_MULTI_INDEX was passed to the constructor.  This operation
+fails if the multi-index is out of bounds.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  int
+  NpyIter_RemoveMultiIndex(NpyIter *iter)
+
+Removes multi-index support from an iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_bool
+  NpyIter_HasIndex(NpyIter *iter)
+
+Whether the iterator is tracking an index
+
+::
+
+  npy_bool
+  NpyIter_IsBuffered(NpyIter *iter)
+
+Whether the iterator is buffered
+
+::
+
+  npy_bool
+  NpyIter_IsGrowInner(NpyIter *iter)
+
+Whether the inner loop can grow if buffering is unneeded
+
+::
+
+  npy_intp
+  NpyIter_GetBufferSize(NpyIter *iter)
+
+Gets the size of the buffer, or 0 if buffering is not enabled
+
+::
+
+  npy_intp *
+  NpyIter_GetIndexPtr(NpyIter *iter)
+
+Get a pointer to the index, if it is being tracked
+
+::
+
+  int
+  NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index)
+
+If the iterator is tracking an index, sets the iterator
+to the specified index.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  char **
+  NpyIter_GetDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  PyArray_Descr **
+  NpyIter_GetDescrArray(NpyIter *iter)
+
+Get the array of data type pointers (1 per object being iterated)
+
+::
+
+  PyArrayObject **
+  NpyIter_GetOperandArray(NpyIter *iter)
+
+Get the array of objects being iterated
+
+::
+
+  PyArrayObject *
+  NpyIter_GetIterView(NpyIter *iter, npy_intp i)
+
+Returns a view to the i-th object with the iterator's internal axes
+
+::
+
+  void
+  NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags)
+
+Gets an array of read flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags)
+
+Gets an array of write flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_DebugPrint(NpyIter *iter)
+
+For debugging
+
+::
+
+  npy_bool
+  NpyIter_IterationNeedsAPI(NpyIter *iter)
+
+Whether the iteration loop, and in particular the iternext()
+function, needs API access.  If this is true, the GIL must
+be retained while iterating.
+
+::
+
+  void
+  NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides)
+
+Get an array of strides which are fixed.  Any strides which may
+change during iteration receive the value NPY_MAX_INTP.  Once
+the iterator is ready to iterate, call this to get the strides
+which will always be fixed in the inner loop, then choose optimized
+inner loop functions which take advantage of those fixed strides.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_RemoveAxis(NpyIter *iter, int axis)
+
+Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX
+was set for iterator creation, and does not work if buffering is
+enabled. This function also resets the iterator to its initial state.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetAxisStrideArray(NpyIter *iter, int axis)
+
+Gets the array of strides for the specified axis.
+If the iterator is tracking a multi-index, gets the strides
+for the axis specified, otherwise gets the strides for
+the iteration axis as Fortran order (fastest-changing axis first).
+
+Returns NULL if an error occurs.
+
+::
+
+  npy_bool
+  NpyIter_RequiresBuffering(NpyIter *iter)
+
+Whether the iteration could be done with no buffering.
+
+::
+
+  char **
+  NpyIter_GetInitialDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated),
+directly into the arrays (never pointing to a buffer), for starting
+unbuffered iteration. This always returns the addresses for the
+iterator position as reset to iterator index 0.
+
+These pointers are different from the pointers accepted by
+NpyIter_ResetBasePointers, because the direction along some
+axes may have been reversed, requiring base offsets.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp
+                                  itemsize, npy_intp *outstrides)
+
+Builds a set of strides which are the same as the strides of an
+output array created using the NPY_ITER_ALLOCATE flag, where NULL
+was passed for op_axes.  This is for data packed contiguously,
+but not necessarily in C or Fortran order. This should be used
+together with NpyIter_GetShape and NpyIter_GetNDim.
+
+A use case for this function is to match the shape and layout of
+the iterator and tack on one or more dimensions.  For example,
+in order to generate a vector per input value for a numerical gradient,
+you pass in ndim*itemsize for itemsize, then add another dimension to
+the end with size ndim and stride itemsize.  To do the Hessian matrix,
+you do the same thing but add two dimensions, or take advantage of
+the symmetry and pack it into 1 dimension with a particular encoding.
+
+This function may only be called if the iterator is tracking a multi-index
+and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from
+being iterated in reverse order.
+
+If an array is created with this method, simply adding 'itemsize'
+for each iteration will traverse the new array matching the
+iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  int
+  PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)
+
+Convert any Python object, *obj*, to an NPY_CASTING enum.
+
+::
+
+  npy_intp
+  PyArray_CountNonzero(PyArrayObject *self)
+
+Counts the number of non-zero elements in the array.
+
+Returns -1 on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+Produces the smallest size and lowest kind type to which both
+input types can be cast.
+
+::
+
+  PyArray_Descr *
+  PyArray_MinScalarType(PyArrayObject *arr)
+
+If arr is a scalar (has 0 dimensions) with a built-in number data type,
+finds the smallest type size/kind which can still represent its data.
+Otherwise, returns the array's data type.
+
+
+::
+
+  PyArray_Descr *
+  PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp
+                     ndtypes, PyArray_Descr **dtypes)
+
+Produces the result type of a bunch of inputs, using the UFunc
+type promotion rules. Use this function when you have a set of
+input arrays, and need to determine an output array dtype.
+
+If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
+of the scalars is greater than the maximum "kind" of the arrays, does
+a regular type promotion.
+
+Otherwise, does a type promotion on the MinScalarType
+of all the inputs.  Data types passed directly are treated as array
+types.
+
+
+::
+
+  npy_bool
+  PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr
+                         *to, NPY_CASTING casting)
+
+Returns 1 if the array object may be cast to the given data type using
+the casting rule, 0 otherwise.  This differs from PyArray_CanCastTo in
+that it handles scalar arrays (0 dimensions) specially, by checking
+their value.
+
+::
+
+  npy_bool
+  PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr
+                        *to, NPY_CASTING casting)
+
+Returns true if data of type 'from' may be cast to data of type
+'to' according to the rule 'casting'.
+
+::
+
+  PyArrayObject *
+  PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject
+                      **op_in, PyArray_Descr *dtype, NPY_ORDER
+                      order, NPY_CASTING casting, PyArrayObject *out)
+
+This function provides summation of array elements according to
+the Einstein summation convention.  For example:
+- trace(a)        -> einsum("ii", a)
+- transpose(a)    -> einsum("ji", a)
+- multiply(a,b)   -> einsum(",", a, b)
+- inner(a,b)      -> einsum("i,i", a, b)
+- outer(a,b)      -> einsum("i,j", a, b)
+- matvec(a,b)     -> einsum("ij,j", a, b)
+- matmat(a,b)     -> einsum("ij,jk", a, b)
+
+subscripts: The string of subscripts for einstein summation.
+nop:        The number of operands
+op_in:      The array of operands
+dtype:      Either NULL, or the data type to force the calculation as.
+order:      The order for the calculation/the output axes.
+casting:    What kind of casts should be permitted.
+out:        Either NULL, or an array into which the output should be placed.
+
+By default, the labels get placed in alphabetical order
+at the end of the output. So, if c = einsum("i,j", a, b)
+then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b)
+then c[i,j] = a[j]*b[i].
+
+Alternatively, you can control the output order or prevent
+an axis from being summed/force an axis to be summed by providing
+indices for the output. This allows us to turn 'trace' into
+'diag', for example.
+- diag(a)         -> einsum("ii->i", a)
+- sum(a, axis=0)  -> einsum("i...->", a)
+
+Subscripts at the beginning and end may be specified by
+putting an ellipsis "..." in the middle.  For example,
+the function einsum("i...i", a) takes the diagonal of
+the first and last dimensions of the operand, and
+einsum("ij...,jk...->ik...") takes the matrix product using
+the first two indices of each operand instead of the last two.
+
+When there is only one operand, no axes being summed, and
+no output parameter, this function returns a view
+into the operand instead of making a copy.
+
+::
+
+  PyObject *
+  PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER
+                       order, PyArray_Descr *dtype, int subok)
+
+Creates a new array with the same shape as the provided one,
+with possible memory layout order and data type changes.
+
+prototype - The array the new one should be like.
+order     - NPY_CORDER - C-contiguous result.
+NPY_FORTRANORDER - Fortran-contiguous result.
+NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise.
+NPY_KEEPORDER - Keeps the axis ordering of prototype.
+dtype     - If not NULL, overrides the data type of the result.
+subok     - If 1, use the prototype's array subtype, otherwise
+always create a base-class array.
+
+NOTE: If dtype is not NULL, steals the dtype reference.
+
+::
+
+  int
+  PyArray_GetArrayParamsFromObject(PyObject *op, PyArray_Descr
+                                   *requested_dtype, npy_bool
+                                   writeable, PyArray_Descr
+                                   **out_dtype, int *out_ndim, npy_intp
+                                   *out_dims, PyArrayObject
+                                   **out_arr, PyObject *context)
+
+Retrieves the array parameters for viewing/converting an arbitrary
+PyObject* to a NumPy array. This allows the "innate type and shape"
+of Python list-of-lists to be discovered without
+actually converting to an array.
+
+In some cases, such as structured arrays and the __array__ interface,
+a data type needs to be used to make sense of the object.  When
+this is needed, provide a Descr for 'requested_dtype', otherwise
+provide NULL. This reference is not stolen. Also, if the requested
+dtype doesn't modify the interpretation of the input, out_dtype will
+still get the "innate" dtype of the object, not the dtype passed
+in 'requested_dtype'.
+
+If writing to the value in 'op' is desired, set the boolean
+'writeable' to 1.  This raises an error when 'op' is a scalar, list
+of lists, or other non-writeable 'op'.
+
+Result: When success (0 return value) is returned, either out_arr
+is filled with a non-NULL PyArrayObject and
+the rest of the parameters are untouched, or out_arr is
+filled with NULL, and the rest of the parameters are
+filled.
+
+Typical usage:
+
+PyArrayObject *arr = NULL;
+PyArray_Descr *dtype = NULL;
+int ndim = 0;
+npy_intp dims[NPY_MAXDIMS];
+
+if (PyArray_GetArrayParamsFromObject(op, NULL, 1, &dtype,
+&ndim, dims, &arr, NULL) < 0) {
+return NULL;
+}
+if (arr == NULL) {
+... validate/change dtype, validate flags, ndim, etc ...
+// Could make custom strides here too
+arr = PyArray_NewFromDescr(&PyArray_Type, dtype, ndim,
+dims, NULL,
+is_f_order ? NPY_ARRAY_F_CONTIGUOUS : 0,
+NULL);
+if (arr == NULL) {
+return NULL;
+}
+if (PyArray_CopyObject(arr, op) < 0) {
+Py_DECREF(arr);
+return NULL;
+}
+}
+else {
+... in this case the other parameters weren't filled, just
+validate and possibly copy arr itself ...
+}
+... use arr ...
+
+::
+
+  int
+  PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE
+                                  *modes, int n)
+
+Convert an object to an array of n NPY_CLIPMODE values.
+This is intended to be used in functions where a different mode
+could be applied to each axis, like in ravel_multi_index.
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct2(PyObject *op1, PyObject
+                         *op2, PyArrayObject*out)
+
+Numeric.matrixproduct2(a,v,out)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  npy_bool
+  NpyIter_IsFirstVisit(NpyIter *iter, int iop)
+
+Checks to see whether this is the first time the elements
+of the specified reduction operand which the iterator points at are
+being seen for the first time. The function returns
+a reasonable answer for reduction operands and when buffering is
+disabled. The answer may be incorrect for buffered non-reduction
+operands.
+
+This function is intended to be used in EXTERNAL_LOOP mode only,
+and will produce some wrong answers when that mode is not enabled.
+
+If this function returns true, the caller should also
+check the inner loop stride of the operand, because if
+that stride is 0, then only the first element of the innermost
+external loop is being visited for the first time.
+
+WARNING: For performance reasons, 'iop' is not bounds-checked,
+it is not confirmed that 'iop' is actually a reduction
+operand, and it is not confirmed that EXTERNAL_LOOP
+mode is enabled. These checks are the responsibility of
+the caller, and should be done outside of any inner loops.
+
+::
+
+  int
+  PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)
+
+Sets the 'base' attribute of the array. This steals a reference
+to 'obj'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void
+  PyArray_CreateSortedStridePerm(int ndim, npy_intp
+                                 *strides, npy_stride_sort_item
+                                 *out_strideperm)
+
+
+This function populates the first ndim elements
+of strideperm with sorted descending by their absolute values.
+For example, the stride array (4, -2, 12) becomes
+[(2, 12), (0, 4), (1, -2)].
+
+::
+
+  void
+  PyArray_RemoveAxesInPlace(PyArrayObject *arr, npy_bool *flags)
+
+
+Removes the axes flagged as True from the array,
+modifying it in place. If an axis flagged for removal
+has a shape entry bigger than one, this effectively selects
+index zero for that axis.
+
+WARNING: If an axis flagged for removal has a shape equal to zero,
+the array will point to invalid memory. The caller must
+validate this!
+If an axis flagged for removal has a shape larger then one,
+the aligned flag (and in the future the contiguous flags),
+may need explicite update.
+(check also NPY_RELAXED_STRIDES_CHECKING)
+
+For example, this can be used to remove the reduction axes
+from a reduction result once its computation is complete.
+
+::
+
+  void
+  PyArray_DebugPrint(PyArrayObject *obj)
+
+Prints the raw data of the ndarray in a form useful for debugging
+low-level C issues.
+
+::
+
+  int
+  PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)
+
+
+This function does nothing if obj is writeable, and raises an exception
+(and returns -1) if obj is not writeable. It may also do other
+house-keeping, such as issuing warnings on arrays which are transitioning
+to become views. Always call this function at some point before writing to
+an array.
+
+'name' is a name for the array, used to give better error
+messages. Something like "assignment destination", "output array", or even
+just "array".
+
+::
+
+  int
+  PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base)
+
+
+Precondition: 'arr' is a copy of 'base' (though possibly with different
+strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the
+->base pointer on 'arr', so that when 'arr' is destructed, it will copy any
+changes back to 'base'.
+
+Steals a reference to 'base'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void *
+  PyDataMem_NEW(size_t size)
+
+Allocates memory for array data.
+
+::
+
+  void
+  PyDataMem_FREE(void *ptr)
+
+Free memory for array data.
+
+::
+
+  void *
+  PyDataMem_RENEW(void *ptr, size_t size)
+
+Reallocate/resize memory for array data.
+
+::
+
+  PyDataMem_EventHookFunc *
+  PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void
+                         *user_data, void **old_data)
+
+Sets the allocation event hook for numpy array data.
+Takes a PyDataMem_EventHookFunc *, which has the signature:
+void hook(void *old, void *new, size_t size, void *user_data).
+Also takes a void *user_data, and void **old_data.
+
+Returns a pointer to the previous hook or NULL.  If old_data is
+non-NULL, the previous user_data pointer will be copied to it.
+
+If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW:
+result = PyDataMem_NEW(size)        -> (*hook)(NULL, result, size, user_data)
+PyDataMem_FREE(ptr)                 -> (*hook)(ptr, NULL, 0, user_data)
+result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data)
+
+When the hook is called, the GIL will be held by the calling
+thread.  The hook should be written to be reentrant, if it performs
+operations that might cause new allocation events (such as the
+creation/descruction numpy objects, or creating/destroying Python
+objects which might cause a gc)
+
+::
+
+  void
+  PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject
+                          **ret, int getmap)
+
+
+::
+
+  PyObject *
+  PyArray_MapIterArray(PyArrayObject *a, PyObject *index)
+
+
+Use advanced indexing to iterate an array. Please note
+that most of this public API is currently not guaranteed
+to stay the same between versions. If you plan on using
+it, please consider adding more utility functions here
+to accommodate new features.
+
+::
+
+  void
+  PyArray_MapIterNext(PyArrayMapIterObject *mit)
+
+This function needs to update the state of the map iterator
+and point mit->dataptr to the memory-location of the next object
+
+Note that this function never handles an extra operand but provides
+compatibility for an old (exposed) API.
+
+::
+
+  int
+  PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int
+                    axis, NPY_SELECTKIND which)
+
+Partition an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int
+                       axis, NPY_SELECTKIND which)
+
+ArgPartition an array
+
+::
+
+  int
+  PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind)
+
+Convert object to select kind
+
+::
+
+  void *
+  PyDataMem_NEW_ZEROED(size_t size, size_t elsize)
+
+Allocates zeroed memory for array data.
+
+::
+
+  int
+  PyArray_CheckAnyScalarExact(PyObject *obj)
+
+return true an object is exactly a numpy scalar
+
diff --git a/tools/msys/mingw64/include/python2.7/numpy/ndarrayobject.h b/tools/msys/mingw64/include/python2.7/numpy/ndarrayobject.h
new file mode 100644
index 0000000000..c97a3a797a
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/ndarrayobject.h
@@ -0,0 +1,246 @@
+/*
+ * DON'T INCLUDE THIS DIRECTLY.
+ */
+
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#ifdef __cplusplus
+#define CONFUSE_EMACS {
+#define CONFUSE_EMACS2 }
+extern "C" CONFUSE_EMACS
+#undef CONFUSE_EMACS
+#undef CONFUSE_EMACS2
+/* ... otherwise a semi-smart identer (like emacs) tries to indent
+       everything when you're typing */
+#endif
+
+#include <Python.h>
+#include "ndarraytypes.h"
+
+/* Includes the "function" C-API -- these are all stored in a
+   list of pointers --- one for each file
+   The two lists are concatenated into one in multiarray.
+
+   They are available as import_array()
+*/
+
+#include "__multiarray_api.h"
+
+
+/* C-API that requries previous API to be defined */
+
+#define PyArray_DescrCheck(op) (((PyObject*)(op))->ob_type==&PyArrayDescr_Type)
+
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
+
+#define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
+        ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
+         (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
+         (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
+          Py_NotImplemented))
+
+#define PyArray_HasArrayInterface(op, out)                                    \
+        PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
+                               (PyArray_NDIM((PyArrayObject *)op) == 0))
+
+#define PyArray_IsScalar(obj, cls)                                            \
+        (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
+                                PyArray_IsZeroDim(m))
+#if PY_MAJOR_VERSION >= 3
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyFloat_Check(obj) || PyComplex_Check(obj) ||                        \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj)                       \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) ||                 \
+         PyUnicode_Check(obj))
+#else
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyInt_Check(obj) || PyFloat_Check(obj) || PyComplex_Check(obj) ||    \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyInt_Check(obj)                        \
+              || PyLong_Check(obj)                                            \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyString_Check(obj) ||                \
+         PyUnicode_Check(obj))
+#endif
+
+#define PyArray_IsAnyScalar(obj)                                              \
+        (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
+                                     PyArray_CheckScalar(obj))
+
+
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
+                                  Py_INCREF(m), (m) :                         \
+                                  (PyArrayObject *)(PyArray_Copy(m)))
+
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
+                                  PyArray_CompareLists(PyArray_DIMS(a1),      \
+                                                       PyArray_DIMS(a2),      \
+                                                       PyArray_NDIM(a1)))
+
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
+                                                      NULL)
+
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
+                                PyArray_DescrFromType(type), 0, 0, 0, NULL)
+
+#define PyArray_FROM_OTF(m, type, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
+
+#define PyArray_FROMANY(m, type, min, max, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
+
+#define PyArray_ZEROS(m, dims, type, is_f_order) \
+        PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_EMPTY(m, dims, type, is_f_order) \
+        PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
+                                           PyArray_NBYTES(obj))
+
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
+
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT, NULL)
+
+#define PyArray_EquivArrTypes(a1, a2) \
+        PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+
+#define PyArray_EquivByteorders(b1, b2) \
+        (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+
+#define PyArray_SimpleNew(nd, dims, typenum) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
+                    data, 0, NPY_ARRAY_CARRAY, NULL)
+
+#define PyArray_SimpleNewFromDescr(nd, dims, descr) \
+        PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
+                             NULL, NULL, 0, NULL)
+
+#define PyArray_ToScalar(data, arr) \
+        PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+
+
+/* These might be faster without the dereferencing of obj
+   going on inside -- of course an optimizing compiler should
+   inline the constants inside a for loop making it a moot point
+*/
+
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
+                                         (i)*PyArray_STRIDES(obj)[0]))
+
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1]))
+
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2]))
+
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2] + \
+                                            (l)*PyArray_STRIDES(obj)[3]))
+
+static NPY_INLINE void
+PyArray_XDECREF_ERR(PyArrayObject *arr)
+{
+    if (arr != NULL) {
+        if (PyArray_FLAGS(arr) & NPY_ARRAY_UPDATEIFCOPY) {
+            PyArrayObject *base = (PyArrayObject *)PyArray_BASE(arr);
+            PyArray_ENABLEFLAGS(base, NPY_ARRAY_WRITEABLE);
+            PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
+        }
+        Py_DECREF(arr);
+    }
+}
+
+#define PyArray_DESCR_REPLACE(descr) do { \
+                PyArray_Descr *_new_; \
+                _new_ = PyArray_DescrNew(descr); \
+                Py_XDECREF(descr); \
+                descr = _new_; \
+        } while(0)
+
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+
+#define PyArray_FromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_BEHAVED | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                        max_depth, NPY_ARRAY_ENSURECOPY | \
+                                   NPY_ARRAY_DEFAULT | \
+                                   NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_Cast(mp, type_num)                                            \
+        PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+
+#define PyArray_Take(ap, items, axis)                                         \
+        PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+
+#define PyArray_Put(ap, items, values)                                        \
+        PyArray_PutTo(ap, items, values, NPY_RAISE)
+
+/* Compatibility with old Numeric stuff -- don't use in new code */
+
+#define PyArray_FromDimsAndData(nd, d, type, data)                            \
+        PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
+                                        data)
+
+
+/*
+   Check to see if this key in the dictionary is the "title"
+   entry of the tuple (i.e. a duplicate dictionary entry in the fields
+   dict.
+*/
+
+#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \
+                                   (PyTuple_GET_ITEM((value), 2) == (key)))
+
+
+#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
+#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* NPY_NDARRAYOBJECT_H */
diff --git a/tools/msys/mingw64/include/python2.7/numpy/ndarraytypes.h b/tools/msys/mingw64/include/python2.7/numpy/ndarraytypes.h
new file mode 100644
index 0000000000..f1fe89f1a1
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/ndarraytypes.h
@@ -0,0 +1,1793 @@
+#ifndef NDARRAYTYPES_H
+#define NDARRAYTYPES_H
+
+#include "npy_common.h"
+#include "npy_endian.h"
+#include "npy_cpu.h"
+#include "utils.h"
+
+#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN
+
+/* Only use thread if configured in config and python supports it */
+#if defined WITH_THREAD && !NPY_NO_SMP
+        #define NPY_ALLOW_THREADS 1
+#else
+        #define NPY_ALLOW_THREADS 0
+#endif
+
+
+
+/*
+ * There are several places in the code where an array of dimensions
+ * is allocated statically.  This is the size of that static
+ * allocation.
+ *
+ * The array creation itself could have arbitrary dimensions but all
+ * the places where static allocation is used would need to be changed
+ * to dynamic (including inside of several structures)
+ */
+
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+
+/*
+ * Binary compatibility version number.  This number is increased
+ * whenever the C-API is changed such that binary compatibility is
+ * broken, i.e. whenever a recompile of extension modules is needed.
+ */
+#define NPY_VERSION NPY_ABI_VERSION
+
+/*
+ * Minor API version.  This number is increased whenever a change is
+ * made to the C-API -- whether it breaks binary compatibility or not.
+ * Some changes, such as adding a function pointer to the end of the
+ * function table, can be made without breaking binary compatibility.
+ * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION)
+ * would be increased.  Whenever binary compatibility is broken, both
+ * NPY_VERSION and NPY_FEATURE_VERSION should be increased.
+ */
+#define NPY_FEATURE_VERSION NPY_API_VERSION
+
+enum NPY_TYPES {    NPY_BOOL=0,
+                    NPY_BYTE, NPY_UBYTE,
+                    NPY_SHORT, NPY_USHORT,
+                    NPY_INT, NPY_UINT,
+                    NPY_LONG, NPY_ULONG,
+                    NPY_LONGLONG, NPY_ULONGLONG,
+                    NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+                    NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+                    NPY_OBJECT=17,
+                    NPY_STRING, NPY_UNICODE,
+                    NPY_VOID,
+                    /*
+                     * New 1.6 types appended, may be integrated
+                     * into the above in 2.0.
+                     */
+                    NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF,
+
+                    NPY_NTYPES,
+                    NPY_NOTYPE,
+                    NPY_CHAR,      /* special flag */
+                    NPY_USERDEF=256,  /* leave room for characters */
+
+                    /* The number of types not including the new 1.6 types */
+                    NPY_NTYPES_ABI_COMPATIBLE=21
+};
+
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+
+/* How many floating point types are there (excluding half) */
+#define NPY_NUM_FLOATTYPE 3
+
+/*
+ * These characters correspond to the array type and the struct
+ * module
+ */
+
+enum NPY_TYPECHAR {
+        NPY_BOOLLTR = '?',
+        NPY_BYTELTR = 'b',
+        NPY_UBYTELTR = 'B',
+        NPY_SHORTLTR = 'h',
+        NPY_USHORTLTR = 'H',
+        NPY_INTLTR = 'i',
+        NPY_UINTLTR = 'I',
+        NPY_LONGLTR = 'l',
+        NPY_ULONGLTR = 'L',
+        NPY_LONGLONGLTR = 'q',
+        NPY_ULONGLONGLTR = 'Q',
+        NPY_HALFLTR = 'e',
+        NPY_FLOATLTR = 'f',
+        NPY_DOUBLELTR = 'd',
+        NPY_LONGDOUBLELTR = 'g',
+        NPY_CFLOATLTR = 'F',
+        NPY_CDOUBLELTR = 'D',
+        NPY_CLONGDOUBLELTR = 'G',
+        NPY_OBJECTLTR = 'O',
+        NPY_STRINGLTR = 'S',
+        NPY_STRINGLTR2 = 'a',
+        NPY_UNICODELTR = 'U',
+        NPY_VOIDLTR = 'V',
+        NPY_DATETIMELTR = 'M',
+        NPY_TIMEDELTALTR = 'm',
+        NPY_CHARLTR = 'c',
+
+        /*
+         * No Descriptor, just a define -- this let's
+         * Python users specify an array of integers
+         * large enough to hold a pointer on the
+         * platform
+         */
+        NPY_INTPLTR = 'p',
+        NPY_UINTPLTR = 'P',
+
+        /*
+         * These are for dtype 'kinds', not dtype 'typecodes'
+         * as the above are for.
+         */
+        NPY_GENBOOLLTR ='b',
+        NPY_SIGNEDLTR = 'i',
+        NPY_UNSIGNEDLTR = 'u',
+        NPY_FLOATINGLTR = 'f',
+        NPY_COMPLEXLTR = 'c'
+};
+
+typedef enum {
+        NPY_QUICKSORT=0,
+        NPY_HEAPSORT=1,
+        NPY_MERGESORT=2
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_MERGESORT + 1)
+
+
+typedef enum {
+        NPY_INTROSELECT=0
+} NPY_SELECTKIND;
+#define NPY_NSELECTS (NPY_INTROSELECT + 1)
+
+
+typedef enum {
+        NPY_SEARCHLEFT=0,
+        NPY_SEARCHRIGHT=1
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+
+
+typedef enum {
+        NPY_NOSCALAR=-1,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+
+/* For specifying array memory layout or iteration order */
+typedef enum {
+        /* Fortran order if inputs are all Fortran, C otherwise */
+        NPY_ANYORDER=-1,
+        /* C order */
+        NPY_CORDER=0,
+        /* Fortran order */
+        NPY_FORTRANORDER=1,
+        /* An order as close to the inputs as possible */
+        NPY_KEEPORDER=2
+} NPY_ORDER;
+
+/* For specifying allowed casting in operations which support it */
+typedef enum {
+        /* Only allow identical types */
+        NPY_NO_CASTING=0,
+        /* Allow identical and byte swapped types */
+        NPY_EQUIV_CASTING=1,
+        /* Only allow safe casts */
+        NPY_SAFE_CASTING=2,
+        /* Allow safe casts or casts within the same kind */
+        NPY_SAME_KIND_CASTING=3,
+        /* Allow any casts */
+        NPY_UNSAFE_CASTING=4
+} NPY_CASTING;
+
+typedef enum {
+        NPY_CLIP=0,
+        NPY_WRAP=1,
+        NPY_RAISE=2
+} NPY_CLIPMODE;
+
+/* The special not-a-time (NaT) value */
+#define NPY_DATETIME_NAT NPY_MIN_INT64
+
+/*
+ * Upper bound on the length of a DATETIME ISO 8601 string
+ *   YEAR: 21 (64-bit year)
+ *   MONTH: 3
+ *   DAY: 3
+ *   HOURS: 3
+ *   MINUTES: 3
+ *   SECONDS: 3
+ *   ATTOSECONDS: 1 + 3*6
+ *   TIMEZONE: 5
+ *   NULL TERMINATOR: 1
+ */
+#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
+
+typedef enum {
+        NPY_FR_Y = 0,  /* Years */
+        NPY_FR_M = 1,  /* Months */
+        NPY_FR_W = 2,  /* Weeks */
+        /* Gap where 1.6 NPY_FR_B (value 3) was */
+        NPY_FR_D = 4,  /* Days */
+        NPY_FR_h = 5,  /* hours */
+        NPY_FR_m = 6,  /* minutes */
+        NPY_FR_s = 7,  /* seconds */
+        NPY_FR_ms = 8, /* milliseconds */
+        NPY_FR_us = 9, /* microseconds */
+        NPY_FR_ns = 10,/* nanoseconds */
+        NPY_FR_ps = 11,/* picoseconds */
+        NPY_FR_fs = 12,/* femtoseconds */
+        NPY_FR_as = 13,/* attoseconds */
+        NPY_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */
+} NPY_DATETIMEUNIT;
+
+/*
+ * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS
+ *       is technically one more than the actual number of units.
+ */
+#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1)
+#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC
+
+/*
+ * Business day conventions for mapping invalid business
+ * days to valid business days.
+ */
+typedef enum {
+    /* Go forward in time to the following business day. */
+    NPY_BUSDAY_FORWARD,
+    NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD,
+    /* Go backward in time to the preceding business day. */
+    NPY_BUSDAY_BACKWARD,
+    NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD,
+    /*
+     * Go forward in time to the following business day, unless it
+     * crosses a month boundary, in which case go backward
+     */
+    NPY_BUSDAY_MODIFIEDFOLLOWING,
+    /*
+     * Go backward in time to the preceding business day, unless it
+     * crosses a month boundary, in which case go forward.
+     */
+    NPY_BUSDAY_MODIFIEDPRECEDING,
+    /* Produce a NaT for non-business days. */
+    NPY_BUSDAY_NAT,
+    /* Raise an exception for non-business days. */
+    NPY_BUSDAY_RAISE
+} NPY_BUSDAY_ROLL;
+
+/************************************************************
+ * NumPy Auxiliary Data for inner loops, sort functions, etc.
+ ************************************************************/
+
+/*
+ * When creating an auxiliary data struct, this should always appear
+ * as the first member, like this:
+ *
+ * typedef struct {
+ *     NpyAuxData base;
+ *     double constant;
+ * } constant_multiplier_aux_data;
+ */
+typedef struct NpyAuxData_tag NpyAuxData;
+
+/* Function pointers for freeing or cloning auxiliary data */
+typedef void (NpyAuxData_FreeFunc) (NpyAuxData *);
+typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *);
+
+struct NpyAuxData_tag {
+    NpyAuxData_FreeFunc *free;
+    NpyAuxData_CloneFunc *clone;
+    /* To allow for a bit of expansion without breaking the ABI */
+    void *reserved[2];
+};
+
+/* Macros to use for freeing and cloning auxiliary data */
+#define NPY_AUXDATA_FREE(auxdata) \
+    do { \
+        if ((auxdata) != NULL) { \
+            (auxdata)->free(auxdata); \
+        } \
+    } while(0)
+#define NPY_AUXDATA_CLONE(auxdata) \
+    ((auxdata)->clone(auxdata))
+
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+
+  /*
+   * Macros to define how array, and dimension/strides data is
+   * allocated.
+   */
+
+  /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */
+
+#define NPY_USE_PYMEM 1
+
+#if NPY_USE_PYMEM == 1
+#define PyArray_malloc PyMem_Malloc
+#define PyArray_free PyMem_Free
+#define PyArray_realloc PyMem_Realloc
+#else
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+#endif
+
+/* Dimensions and strides */
+#define PyDimMem_NEW(size)                                         \
+    ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+
+#define PyDimMem_RENEW(ptr,size)                                   \
+        ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+
+/* forward declaration */
+struct _PyArray_Descr;
+
+/* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+                                     npy_intp, int, void *);
+
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+
+
+/*
+ * These assume aligned and notswapped data -- a buffer will be used
+ * before or contiguous data will be obtained
+ */
+
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+                               npy_intp, void *);
+
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+                                       void *);
+
+/*
+ * XXX the ignore argument should be removed next time the API version
+ * is bumped. It used to be the separator.
+ */
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+                               char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+                                  struct _PyArray_Descr *);
+
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
+                                    npy_intp *, npy_intp *,
+                                    void *);
+typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
+                                       npy_intp *, npy_intp *,
+                                       void *);
+
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+
+typedef int (PyArray_ScalarKindFunc)(void *);
+
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in,
+                                       void *values, npy_intp nv);
+typedef int  (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray,
+                                       npy_intp nindarray, npy_intp n_outer,
+                                       npy_intp m_middle, npy_intp nelem,
+                                       NPY_CLIPMODE clipmode);
+
+typedef struct {
+        npy_intp *ptr;
+        int len;
+} PyArray_Dims;
+
+typedef struct {
+        /*
+         * Functions to cast to most other standard types
+         * Can have some NULL entries. The types
+         * DATETIME, TIMEDELTA, and HALF go into the castdict
+         * even though they are built-in.
+         */
+        PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
+
+        /* The next four functions *cannot* be NULL */
+
+        /*
+         * Functions to get and set items with standard Python types
+         * -- not array scalars
+         */
+        PyArray_GetItemFunc *getitem;
+        PyArray_SetItemFunc *setitem;
+
+        /*
+         * Copy and/or swap data.  Memory areas may not overlap
+         * Use memmove first if they might
+         */
+        PyArray_CopySwapNFunc *copyswapn;
+        PyArray_CopySwapFunc *copyswap;
+
+        /*
+         * Function to compare items
+         * Can be NULL
+         */
+        PyArray_CompareFunc *compare;
+
+        /*
+         * Function to select largest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmax;
+
+        /*
+         * Function to compute dot product
+         * Can be NULL
+         */
+        PyArray_DotFunc *dotfunc;
+
+        /*
+         * Function to scan an ASCII file and
+         * place a single value plus possible separator
+         * Can be NULL
+         */
+        PyArray_ScanFunc *scanfunc;
+
+        /*
+         * Function to read a single value from a string
+         * and adjust the pointer; Can be NULL
+         */
+        PyArray_FromStrFunc *fromstr;
+
+        /*
+         * Function to determine if data is zero or not
+         * If NULL a default version is
+         * used at Registration time.
+         */
+        PyArray_NonzeroFunc *nonzero;
+
+        /*
+         * Used for arange.
+         * Can be NULL.
+         */
+        PyArray_FillFunc *fill;
+
+        /*
+         * Function to fill arrays with scalar values
+         * Can be NULL
+         */
+        PyArray_FillWithScalarFunc *fillwithscalar;
+
+        /*
+         * Sorting functions
+         * Can be NULL
+         */
+        PyArray_SortFunc *sort[NPY_NSORTS];
+        PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+
+        /*
+         * Dictionary of additional casting functions
+         * PyArray_VectorUnaryFuncs
+         * which can be populated to support casting
+         * to other registered types. Can be NULL
+         */
+        PyObject *castdict;
+
+        /*
+         * Functions useful for generalizing
+         * the casting rules.
+         * Can be NULL;
+         */
+        PyArray_ScalarKindFunc *scalarkind;
+        int **cancastscalarkindto;
+        int *cancastto;
+
+        PyArray_FastClipFunc *fastclip;
+        PyArray_FastPutmaskFunc *fastputmask;
+        PyArray_FastTakeFunc *fasttake;
+
+        /*
+         * Function to select smallest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmin;
+
+} PyArray_ArrFuncs;
+
+/* The item must be reference counted when it is inserted or extracted. */
+#define NPY_ITEM_REFCOUNT   0x01
+/* Same as needing REFCOUNT */
+#define NPY_ITEM_HASOBJECT  0x01
+/* Convert to list for pickling */
+#define NPY_LIST_PICKLE     0x02
+/* The item is a POINTER  */
+#define NPY_ITEM_IS_POINTER 0x04
+/* memory needs to be initialized for this data-type */
+#define NPY_NEEDS_INIT      0x08
+/* operations need Python C-API so don't give-up thread. */
+#define NPY_NEEDS_PYAPI     0x10
+/* Use f.getitem when extracting elements of this data-type */
+#define NPY_USE_GETITEM     0x20
+/* Use f.setitem when setting creating 0-d array from this data-type.*/
+#define NPY_USE_SETITEM     0x40
+/* A sticky flag specifically for structured arrays */
+#define NPY_ALIGNED_STRUCT  0x80
+
+/*
+ *These are inherited for global data-type if any data-types in the
+ * field have them
+ */
+#define NPY_FROM_FIELDS    (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \
+                            NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \
+                                NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+                                NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+
+#define PyDataType_FLAGCHK(dtype, flag) \
+        (((dtype)->flags & (flag)) == (flag))
+
+#define PyDataType_REFCHK(dtype) \
+        PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+
+typedef struct _PyArray_Descr {
+        PyObject_HEAD
+        /*
+         * the type object representing an
+         * instance of this type -- should not
+         * be two type_numbers with the same type
+         * object.
+         */
+        PyTypeObject *typeobj;
+        /* kind for this type */
+        char kind;
+        /* unique-character representing this type */
+        char type;
+        /*
+         * '>' (big), '<' (little), '|'
+         * (not-applicable), or '=' (native).
+         */
+        char byteorder;
+        /* flags describing data type */
+        char flags;
+        /* number representing this type */
+        int type_num;
+        /* element size (itemsize) for this type */
+        int elsize;
+        /* alignment needed for this type */
+        int alignment;
+        /*
+         * Non-NULL if this type is
+         * is an array (C-contiguous)
+         * of some other type
+         */
+        struct _arr_descr *subarray;
+        /*
+         * The fields dictionary for this type
+         * For statically defined descr this
+         * is always Py_None
+         */
+        PyObject *fields;
+        /*
+         * An ordered tuple of field names or NULL
+         * if no fields are defined
+         */
+        PyObject *names;
+        /*
+         * a table of functions specific for each
+         * basic data descriptor
+         */
+        PyArray_ArrFuncs *f;
+        /* Metadata about this dtype */
+        PyObject *metadata;
+        /*
+         * Metadata specific to the C implementation
+         * of the particular dtype. This was added
+         * for NumPy 1.7.0.
+         */
+        NpyAuxData *c_metadata;
+        /* Cached hash value (-1 if not yet computed).
+         * This was added for NumPy 2.0.0.
+         */
+        npy_hash_t hash;
+} PyArray_Descr;
+
+typedef struct _arr_descr {
+        PyArray_Descr *base;
+        PyObject *shape;       /* a tuple */
+} PyArray_ArrayDescr;
+
+/*
+ * The main array object structure.
+ *
+ * It has been recommended to use the inline functions defined below
+ * (PyArray_DATA and friends) to access fields here for a number of
+ * releases. Direct access to the members themselves is deprecated.
+ * To ensure that your code does not use deprecated access,
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
+ */
+/* This struct will be moved to a private header in a future release */
+typedef struct tagPyArrayObject_fields {
+    PyObject_HEAD
+    /* Pointer to the raw data buffer */
+    char *data;
+    /* The number of dimensions, also called 'ndim' */
+    int nd;
+    /* The size in each dimension, also called 'shape' */
+    npy_intp *dimensions;
+    /*
+     * Number of bytes to jump to get to the
+     * next element in each dimension
+     */
+    npy_intp *strides;
+    /*
+     * This object is decref'd upon
+     * deletion of array. Except in the
+     * case of UPDATEIFCOPY which has
+     * special handling.
+     *
+     * For views it points to the original
+     * array, collapsed so no chains of
+     * views occur.
+     *
+     * For creation from buffer object it
+     * points to an object that shold be
+     * decref'd on deletion
+     *
+     * For UPDATEIFCOPY flag this is an
+     * array to-be-updated upon deletion
+     * of this one
+     */
+    PyObject *base;
+    /* Pointer to type structure */
+    PyArray_Descr *descr;
+    /* Flags describing array -- see below */
+    int flags;
+    /* For weak references */
+    PyObject *weakreflist;
+} PyArrayObject_fields;
+
+/*
+ * To hide the implementation details, we only expose
+ * the Python struct HEAD.
+ */
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+/*
+ * Can't put this in npy_deprecated_api.h like the others.
+ * PyArrayObject field access is deprecated as of NumPy 1.7.
+ */
+typedef PyArrayObject_fields PyArrayObject;
+#else
+typedef struct tagPyArrayObject {
+        PyObject_HEAD
+} PyArrayObject;
+#endif
+
+#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
+
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+        PyObject_HEAD
+        PyObject *arr;
+        int flags;
+} PyArrayFlagsObject;
+
+/* Mirrors buffer object to ptr */
+
+typedef struct {
+        PyObject_HEAD
+        PyObject *base;
+        void *ptr;
+        npy_intp len;
+        int flags;
+} PyArray_Chunk;
+
+typedef struct {
+    NPY_DATETIMEUNIT base;
+    int num;
+} PyArray_DatetimeMetaData;
+
+typedef struct {
+    NpyAuxData base;
+    PyArray_DatetimeMetaData meta;
+} PyArray_DatetimeDTypeMetaData;
+
+/*
+ * This structure contains an exploded view of a date-time value.
+ * NaT is represented by year == NPY_DATETIME_NAT.
+ */
+typedef struct {
+        npy_int64 year;
+        npy_int32 month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+
+/* This is not used internally. */
+typedef struct {
+        npy_int64 day;
+        npy_int32 sec, us, ps, as;
+} npy_timedeltastruct;
+
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+
+/*
+ * Means c-style contiguous (last index varies the fastest). The data
+ * elements right after each other.
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_C_CONTIGUOUS    0x0001
+
+/*
+ * Set if array is a contiguous Fortran array: the first index varies
+ * the fastest in memory (strides array is reverse of C-contiguous
+ * array)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_F_CONTIGUOUS    0x0002
+
+/*
+ * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a
+ * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
+ * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
+ * at the same time if they have either zero or one element.
+ * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
+ * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
+ * and the array is contiguous if ndarray.squeeze() is contiguous.
+ * I.e. dimensions for which `ndarray.shape[dimension] == 1` are
+ * ignored.
+ */
+
+/*
+ * If set, the array owns the data: it will be free'd when the array
+ * is deleted.
+ *
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_OWNDATA         0x0004
+
+/*
+ * An array never has the next four set; they're only used as parameter
+ * flags to the the various FromAny functions
+ *
+ * This flag may be requested in constructor functions.
+ */
+
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_ARRAY_FORCECAST       0x0010
+
+/*
+ * Always copy the array. Returned arrays are always CONTIGUOUS,
+ * ALIGNED, and WRITEABLE.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSURECOPY      0x0020
+
+/*
+ * Make sure the returned array is a base-class ndarray
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSUREARRAY     0x0040
+
+/*
+ * Make sure that the strides are in units of the element size Needed
+ * for some operations with record-arrays.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ELEMENTSTRIDES  0x0080
+
+/*
+ * Array data is aligned on the appropiate memory address for the type
+ * stored according to how the compiler would align things (e.g., an
+ * array of integers (4 bytes each) starts on a memory address that's
+ * a multiple of 4)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_ALIGNED         0x0100
+
+/*
+ * Array data has the native endianness
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_NOTSWAPPED      0x0200
+
+/*
+ * Array data is writeable
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_WRITEABLE       0x0400
+
+/*
+ * If this flag is set, then base contains a pointer to an array of
+ * the same size that should be updated with the current contents of
+ * this array when this array is deallocated
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_UPDATEIFCOPY    0x1000
+
+/*
+ * NOTE: there are also internal flags defined in multiarray/arrayobject.h,
+ * which start at bit 31 and work down.
+ */
+
+#define NPY_ARRAY_BEHAVED      (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE)
+#define NPY_ARRAY_BEHAVED_NS   (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE | \
+                                NPY_ARRAY_NOTSWAPPED)
+#define NPY_ARRAY_CARRAY       (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_CARRAY_RO    (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_FARRAY       (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_FARRAY_RO    (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_DEFAULT      (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_IN_ARRAY     (NPY_ARRAY_CARRAY_RO)
+#define NPY_ARRAY_OUT_ARRAY    (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_INOUT_ARRAY  (NPY_ARRAY_CARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+#define NPY_ARRAY_IN_FARRAY    (NPY_ARRAY_FARRAY_RO)
+#define NPY_ARRAY_OUT_FARRAY   (NPY_ARRAY_FARRAY)
+#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+
+#define NPY_ARRAY_UPDATE_ALL   (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+
+/* This flag is for the array interface, not PyArrayObject */
+#define NPY_ARR_HAS_DESCR  0x0800
+
+
+
+
+/*
+ * Size of internal buffers used for alignment Make BUFSIZE a multiple
+ * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned
+ */
+#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000)
+#define NPY_BUFSIZE 8192
+/* buffer stress test size: */
+/*#define NPY_BUFSIZE 17*/
+
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+
+/*
+ * C API: consists of Macros and functions.  The MACROS are defined
+ * here.
+ */
+
+
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED)
+
+#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS)
+
+/* the variable is used in some places, so always define it */
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+#define NPY_END_THREADS   do { if (_save) \
+                { PyEval_RestoreThread(_save); _save = NULL;} } while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+                { _save = PyEval_SaveThread();} } while (0);
+
+#define NPY_BEGIN_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_BEGIN_THREADS;} while (0);
+
+#define NPY_END_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_END_THREADS; } while (0);
+
+#define NPY_ALLOW_C_API_DEF  PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API      do {__save__ = PyGILState_Ensure();} while (0);
+#define NPY_DISABLE_C_API    do {PyGILState_Release(__save__);} while (0);
+#else
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size)
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+#endif
+
+/**********************************
+ * The nditer object, added in 1.6
+ **********************************/
+
+/* The actual structure of the iterator is an internal detail */
+typedef struct NpyIter_InternalOnly NpyIter;
+
+/* Iterator function pointers that may be specialized */
+typedef int (NpyIter_IterNextFunc)(NpyIter *iter);
+typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter,
+                                      npy_intp *outcoords);
+
+/*** Global flags that may be passed to the iterator constructors ***/
+
+/* Track an index representing C order */
+#define NPY_ITER_C_INDEX                    0x00000001
+/* Track an index representing Fortran order */
+#define NPY_ITER_F_INDEX                    0x00000002
+/* Track a multi-index */
+#define NPY_ITER_MULTI_INDEX                0x00000004
+/* User code external to the iterator does the 1-dimensional innermost loop */
+#define NPY_ITER_EXTERNAL_LOOP              0x00000008
+/* Convert all the operands to a common data type */
+#define NPY_ITER_COMMON_DTYPE               0x00000010
+/* Operands may hold references, requiring API access during iteration */
+#define NPY_ITER_REFS_OK                    0x00000020
+/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */
+#define NPY_ITER_ZEROSIZE_OK                0x00000040
+/* Permits reductions (size-0 stride with dimension size > 1) */
+#define NPY_ITER_REDUCE_OK                  0x00000080
+/* Enables sub-range iteration */
+#define NPY_ITER_RANGED                     0x00000100
+/* Enables buffering */
+#define NPY_ITER_BUFFERED                   0x00000200
+/* When buffering is enabled, grows the inner loop if possible */
+#define NPY_ITER_GROWINNER                  0x00000400
+/* Delay allocation of buffers until first Reset* call */
+#define NPY_ITER_DELAY_BUFALLOC             0x00000800
+/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */
+#define NPY_ITER_DONT_NEGATE_STRIDES        0x00001000
+
+/*** Per-operand flags that may be passed to the iterator constructors ***/
+
+/* The operand will be read from and written to */
+#define NPY_ITER_READWRITE                  0x00010000
+/* The operand will only be read from */
+#define NPY_ITER_READONLY                   0x00020000
+/* The operand will only be written to */
+#define NPY_ITER_WRITEONLY                  0x00040000
+/* The operand's data must be in native byte order */
+#define NPY_ITER_NBO                        0x00080000
+/* The operand's data must be aligned */
+#define NPY_ITER_ALIGNED                    0x00100000
+/* The operand's data must be contiguous (within the inner loop) */
+#define NPY_ITER_CONTIG                     0x00200000
+/* The operand may be copied to satisfy requirements */
+#define NPY_ITER_COPY                       0x00400000
+/* The operand may be copied with UPDATEIFCOPY to satisfy requirements */
+#define NPY_ITER_UPDATEIFCOPY               0x00800000
+/* Allocate the operand if it is NULL */
+#define NPY_ITER_ALLOCATE                   0x01000000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE                 0x02000000
+/* This is a virtual array slot, operand is NULL but temporary data is there */
+#define NPY_ITER_VIRTUAL                    0x04000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST               0x08000000
+/* A mask is being used on this array, affects buffer -> array copy */
+#define NPY_ITER_WRITEMASKED                0x10000000
+/* This array is the mask for all WRITEMASKED operands */
+#define NPY_ITER_ARRAYMASK                  0x20000000
+
+#define NPY_ITER_GLOBAL_FLAGS               0x0000ffff
+#define NPY_ITER_PER_OP_FLAGS               0xffff0000
+
+
+/*****************************
+ * Basic iterator object
+ *****************************/
+
+/* FWD declaration */
+typedef struct PyArrayIterObject_tag PyArrayIterObject;
+
+/*
+ * type of the function which translates a set of coordinates to a
+ * pointer to the data
+ */
+typedef char* (*npy_iter_get_dataptr_t)(PyArrayIterObject* iter, npy_intp*);
+
+struct PyArrayIterObject_tag {
+        PyObject_HEAD
+        int               nd_m1;            /* number of dimensions - 1 */
+        npy_intp          index, size;
+        npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+        npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+        npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+        npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+        npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+        PyArrayObject     *ao;
+        char              *dataptr;        /* pointer to current item*/
+        npy_bool          contiguous;
+
+        npy_intp          bounds[NPY_MAXDIMS][2];
+        npy_intp          limits[NPY_MAXDIMS][2];
+        npy_intp          limits_sizes[NPY_MAXDIMS];
+        npy_iter_get_dataptr_t translate;
+} ;
+
+
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) do { \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        memset(_PyAIT(it)->coordinates, 0, \
+               (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \
+} while (0)
+
+#define _PyArray_ITER_NEXT1(it) do { \
+        (it)->dataptr += _PyAIT(it)->strides[0]; \
+        (it)->coordinates[0]++; \
+} while (0)
+
+#define _PyArray_ITER_NEXT2(it) do { \
+        if ((it)->coordinates[1] < (it)->dims_m1[1]) { \
+                (it)->coordinates[1]++; \
+                (it)->dataptr += (it)->strides[1]; \
+        } \
+        else { \
+                (it)->coordinates[1] = 0; \
+                (it)->coordinates[0]++; \
+                (it)->dataptr += (it)->strides[0] - \
+                        (it)->backstrides[1]; \
+        } \
+} while (0)
+
+#define PyArray_ITER_NEXT(it) do { \
+        _PyAIT(it)->index++; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyArray_ITER_NEXT1(_PyAIT(it)); \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else if (_PyAIT(it)->nd_m1 == 1) { \
+                _PyArray_ITER_NEXT2(_PyAIT(it)); \
+        } \
+        else { \
+                int __npy_i; \
+                for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+                        if (_PyAIT(it)->coordinates[__npy_i] < \
+                            _PyAIT(it)->dims_m1[__npy_i]) { \
+                                _PyAIT(it)->coordinates[__npy_i]++; \
+                                _PyAIT(it)->dataptr += \
+                                        _PyAIT(it)->strides[__npy_i]; \
+                                break; \
+                        } \
+                        else { \
+                                _PyAIT(it)->coordinates[__npy_i] = 0; \
+                                _PyAIT(it)->dataptr -= \
+                                        _PyAIT(it)->backstrides[__npy_i]; \
+                        } \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO(it, destination) do { \
+        int __npy_i; \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \
+                if (destination[__npy_i] < 0) { \
+                        destination[__npy_i] += \
+                                _PyAIT(it)->dims_m1[__npy_i]+1; \
+                } \
+                _PyAIT(it)->dataptr += destination[__npy_i] * \
+                        _PyAIT(it)->strides[__npy_i]; \
+                _PyAIT(it)->coordinates[__npy_i] = \
+                        destination[__npy_i]; \
+                _PyAIT(it)->index += destination[__npy_i] * \
+                        ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \
+                          _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO1D(it, ind) do { \
+        int __npy_i; \
+        npy_intp __npy_ind = (npy_intp) (ind); \
+        if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \
+        _PyAIT(it)->index = __npy_ind; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * _PyAIT(it)->strides[0]; \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+                for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
+                     __npy_i++) { \
+                        _PyAIT(it)->dataptr += \
+                                (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+                                * _PyAIT(it)->strides[__npy_i]; \
+                        __npy_ind %= _PyAIT(it)->factors[__npy_i]; \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+
+
+/*
+ * Any object passed to PyArray_Broadcast must be binary compatible
+ * with this structure.
+ */
+
+typedef struct {
+        PyObject_HEAD
+        int                  numiter;                 /* number of iters */
+        npy_intp             size;                    /* broadcasted size */
+        npy_intp             index;                   /* current index */
+        int                  nd;                      /* number of dims */
+        npy_intp             dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject    *iters[NPY_MAXARGS];     /* iterators */
+} PyArrayMultiIterObject;
+
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) do {                                   \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index = 0;                                             \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;  __npy_mi++) {    \
+                PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]);           \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_NEXT(multi) do {                                    \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index++;                                               \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;   __npy_mi++) {   \
+                PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]);            \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_GOTO(multi, dest) do {                            \
+        int __npy_mi;                                                       \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {   \
+                PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest);    \
+        }                                                                   \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;              \
+} while (0)
+
+#define PyArray_MultiIter_GOTO1D(multi, ind) do {                          \
+        int __npy_mi;                                                      \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {  \
+                PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind);  \
+        }                                                                  \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;             \
+} while (0)
+
+#define PyArray_MultiIter_DATA(multi, i)                \
+        ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+
+#define PyArray_MultiIter_NEXTi(multi, i)               \
+        PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+
+#define PyArray_MultiIter_NOTDONE(multi)                \
+        (_PyMIT(multi)->index < _PyMIT(multi)->size)
+
+
+/*
+ * Store the information needed for fancy-indexing over an array. The
+ * fields are slightly unordered to keep consec, dataptr and subspace
+ * where they were originally.
+ */
+typedef struct {
+        PyObject_HEAD
+        /*
+         * Multi-iterator portion --- needs to be present in this
+         * order to work with PyArray_Broadcast
+         */
+
+        int                   numiter;                 /* number of index-array
+                                                          iterators */
+        npy_intp              size;                    /* size of broadcasted
+                                                          result */
+        npy_intp              index;                   /* current index */
+        int                   nd;                      /* number of dims */
+        npy_intp              dimensions[NPY_MAXDIMS]; /* dimensions */
+        NpyIter               *outer;                  /* index objects
+                                                          iterator */
+        void                  *unused[NPY_MAXDIMS - 2];
+        PyArrayObject         *array;
+        /* Flat iterator for the indexed array. For compatibility solely. */
+        PyArrayIterObject     *ait;
+
+        /*
+         * Subspace array. For binary compatibility (was an iterator,
+         * but only the check for NULL should be used).
+         */
+        PyArrayObject         *subspace;
+
+        /*
+         * if subspace iteration, then this is the array of axes in
+         * the underlying array represented by the index objects
+         */
+        int                   iteraxes[NPY_MAXDIMS];
+        npy_intp              fancy_strides[NPY_MAXDIMS];
+
+        /* pointer when all fancy indices are 0 */
+        char                  *baseoffset;
+
+        /*
+         * after binding consec denotes at which axis the fancy axes
+         * are inserted.
+         */
+        int                   consec;
+        char                  *dataptr;
+
+        int                   nd_fancy;
+        npy_intp              fancy_dims[NPY_MAXDIMS];
+
+        /* Whether the iterator (any of the iterators) requires API */
+        int                   needs_api;
+
+        /*
+         * Extra op information.
+         */
+        PyArrayObject         *extra_op;
+        PyArray_Descr         *extra_op_dtype;         /* desired dtype */
+        npy_uint32            *extra_op_flags;         /* Iterator flags */
+
+        NpyIter               *extra_op_iter;
+        NpyIter_IterNextFunc  *extra_op_next;
+        char                  **extra_op_ptrs;
+
+        /*
+         * Information about the iteration state.
+         */
+        NpyIter_IterNextFunc  *outer_next;
+        char                  **outer_ptrs;
+        npy_intp              *outer_strides;
+
+        /*
+         * Information about the subspace iterator.
+         */
+        NpyIter               *subspace_iter;
+        NpyIter_IterNextFunc  *subspace_next;
+        char                  **subspace_ptrs;
+        npy_intp              *subspace_strides;
+
+        /* Count for the external loop (which ever it is) for API iteration */
+        npy_intp              iter_count;
+
+} PyArrayMapIterObject;
+
+enum {
+    NPY_NEIGHBORHOOD_ITER_ZERO_PADDING,
+    NPY_NEIGHBORHOOD_ITER_ONE_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING,
+    NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING
+};
+
+typedef struct {
+    PyObject_HEAD
+
+    /*
+     * PyArrayIterObject part: keep this in this exact order
+     */
+    int               nd_m1;            /* number of dimensions - 1 */
+    npy_intp          index, size;
+    npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+    npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+    npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+    npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+    npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+    PyArrayObject     *ao;
+    char              *dataptr;        /* pointer to current item*/
+    npy_bool          contiguous;
+
+    npy_intp          bounds[NPY_MAXDIMS][2];
+    npy_intp          limits[NPY_MAXDIMS][2];
+    npy_intp          limits_sizes[NPY_MAXDIMS];
+    npy_iter_get_dataptr_t translate;
+
+    /*
+     * New members
+     */
+    npy_intp nd;
+
+    /* Dimensions is the dimension of the array */
+    npy_intp dimensions[NPY_MAXDIMS];
+
+    /*
+     * Neighborhood points coordinates are computed relatively to the
+     * point pointed by _internal_iter
+     */
+    PyArrayIterObject* _internal_iter;
+    /*
+     * To keep a reference to the representation of the constant value
+     * for constant padding
+     */
+    char* constant;
+
+    int mode;
+} PyArrayNeighborhoodIterObject;
+
+/*
+ * Neighborhood iterator API
+ */
+
+/* General: those work for any mode */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter);
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter);
+#if 0
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
+#endif
+
+/*
+ * Include inline implementations - functions defined there are not
+ * considered public API
+ */
+#define _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#include "_neighborhood_iterator_imp.h"
+#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+
+/* The default array type */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+
+/*
+ * All sorts of useful ways to look into a PyArrayObject. It is recommended
+ * to use PyArrayObject * objects instead of always casting from PyObject *,
+ * for improved type checking.
+ *
+ * In many cases here the macro versions of the accessors are deprecated,
+ * but can't be immediately changed to inline functions because the
+ * preexisting macros accept PyObject * and do automatic casts. Inline
+ * functions accepting PyArrayObject * provides for some compile-time
+ * checking of correctness when working with these objects in C.
+ */
+
+#define PyArray_ISONESEGMENT(m) (PyArray_NDIM(m) == 0 || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS))
+
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \
+                             (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)))
+
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
+                               NPY_ARRAY_F_CONTIGUOUS : 0))
+
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
+/*
+ * Changing access macros into functions, to allow for future hiding
+ * of the internal memory layout. This later hiding will allow the 2.x series
+ * to change the internal representation of arrays without affecting
+ * ABI compatibility.
+ */
+
+static NPY_INLINE int
+PyArray_NDIM(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->nd;
+}
+
+static NPY_INLINE void *
+PyArray_DATA(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE char *
+PyArray_BYTES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_DIMS(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_STRIDES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->strides;
+}
+
+static NPY_INLINE npy_intp
+PyArray_DIM(const PyArrayObject *arr, int idim)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions[idim];
+}
+
+static NPY_INLINE npy_intp
+PyArray_STRIDE(const PyArrayObject *arr, int istride)
+{
+    return ((PyArrayObject_fields *)arr)->strides[istride];
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject *
+PyArray_BASE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->base;
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr *
+PyArray_DESCR(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE int
+PyArray_FLAGS(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->flags;
+}
+
+static NPY_INLINE npy_intp
+PyArray_ITEMSIZE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->elsize;
+}
+
+static NPY_INLINE int
+PyArray_TYPE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->type_num;
+}
+
+static NPY_INLINE int
+PyArray_CHKFLAGS(const PyArrayObject *arr, int flags)
+{
+    return (PyArray_FLAGS(arr) & flags) == flags;
+}
+
+static NPY_INLINE PyObject *
+PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->getitem(
+                                        (void *)itemptr, (PyArrayObject *)arr);
+}
+
+static NPY_INLINE int
+PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->setitem(
+                                                        v, itemptr, arr);
+}
+
+#else
+
+/* These macros are deprecated as of NumPy 1.7. */
+#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd)
+#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags)
+#define PyArray_CHKFLAGS(m, FLAGS) \
+        ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS))
+#define PyArray_ITEMSIZE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->type_num)
+#define PyArray_GETITEM(obj,itemptr) \
+        PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+
+#define PyArray_SETITEM(obj,itemptr,v) \
+        PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \
+                                     (char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+#endif
+
+static NPY_INLINE PyArray_Descr *
+PyArray_DTYPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_SHAPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+/*
+ * Enables the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags |= flags;
+}
+
+/*
+ * Clears the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags &= ~flags;
+}
+
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) ||   \
+                                 ((type) == NPY_USHORT) ||     \
+                                 ((type) == NPY_UINT) ||       \
+                                 ((type) == NPY_ULONG) ||      \
+                                 ((type) == NPY_ULONGLONG))
+
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) ||      \
+                               ((type) == NPY_SHORT) ||        \
+                               ((type) == NPY_INT) ||          \
+                               ((type) == NPY_LONG) ||         \
+                               ((type) == NPY_LONGLONG))
+
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) &&     \
+                                ((type) <= NPY_ULONGLONG))
+
+#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \
+                              ((type) <= NPY_LONGDOUBLE)) || \
+                              ((type) == NPY_HALF))
+
+#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \
+                                  ((type) == NPY_HALF))
+
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) ||    \
+                                  ((type) == NPY_UNICODE))
+
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) &&   \
+                                ((type) <= NPY_CLONGDOUBLE))
+
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) ||      \
+                                  ((type) == NPY_DOUBLE) ||    \
+                                  ((type) == NPY_CDOUBLE) ||   \
+                                  ((type) == NPY_BOOL) ||      \
+                                  ((type) == NPY_OBJECT ))
+
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) &&  \
+                                    ((type) <=NPY_VOID))
+
+#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) &&  \
+                                    ((type) <=NPY_TIMEDELTA))
+
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+                                   ((type) < NPY_USERDEF+     \
+                                    NPY_NUMUSERTYPES))
+
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) ||  \
+                                    PyTypeNum_ISUSERDEF(type))
+
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+
+
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(_PyADt(obj))
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL)
+
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+
+    /*
+     * FIXME: This should check for a flag on the data-type that
+     * states whether or not it is variable length.  Because the
+     * ISFLEXIBLE check is hard-coded to the built-in data-types.
+     */
+#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+
+#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj))
+
+
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#else
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#endif
+
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) &&       \
+                                    PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED)
+
+
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+
+/************************************************************
+ * A struct used by PyArray_CreateSortedStridePerm, new in 1.7.
+ ************************************************************/
+
+typedef struct {
+    npy_intp perm, stride;
+} npy_stride_sort_item;
+
+/************************************************************
+ * This is the form of the struct that's returned pointed by the
+ * PyCObject attribute of an array __array_struct__. See
+ * http://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full
+ * documentation.
+ ************************************************************/
+typedef struct {
+    int two;              /*
+                           * contains the integer 2 as a sanity
+                           * check
+                           */
+
+    int nd;               /* number of dimensions */
+
+    char typekind;        /*
+                           * kind in array --- character code of
+                           * typestr
+                           */
+
+    int itemsize;         /* size of each element */
+
+    int flags;            /*
+                           * how should be data interpreted. Valid
+                           * flags are CONTIGUOUS (1), F_CONTIGUOUS (2),
+                           * ALIGNED (0x100), NOTSWAPPED (0x200), and
+                           * WRITEABLE (0x400).  ARR_HAS_DESCR (0x800)
+                           * states that arrdescr field is present in
+                           * structure
+                           */
+
+    npy_intp *shape;       /*
+                            * A length-nd array of shape
+                            * information
+                            */
+
+    npy_intp *strides;    /* A length-nd array of stride information */
+
+    void *data;           /* A pointer to the first element of the array */
+
+    PyObject *descr;      /*
+                           * A list of fields or NULL (ignored if flags
+                           * does not have ARR_HAS_DESCR flag set)
+                           */
+} PyArrayInterface;
+
+/*
+ * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions.
+ * See the documentation for PyDataMem_SetEventHook.
+ */
+typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
+                                       void *user_data);
+
+/*
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+ */
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
+#endif
+#define NPY_DEPRECATED_INCLUDES
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+#include "npy_1_7_deprecated_api.h"
+#endif
+/*
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ *
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ *
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ *     (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+ */
+#undef NPY_DEPRECATED_INCLUDES
+
+#endif /* NPY_ARRAYTYPES_H */
diff --git a/tools/msys/mingw64/include/python2.7/numpy/noprefix.h b/tools/msys/mingw64/include/python2.7/numpy/noprefix.h
new file mode 100644
index 0000000000..8306170876
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/noprefix.h
@@ -0,0 +1,209 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+
+/*
+ * You can directly include noprefix.h as a backward
+ * compatibility measure
+ */
+#ifndef NPY_NO_PREFIX
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+#endif
+
+#define SIGSETJMP   NPY_SIGSETJMP
+#define SIGLONGJMP  NPY_SIGLONGJMP
+#define SIGJMP_BUF  NPY_SIGJMP_BUF
+
+#define MAX_DIMS NPY_MAXDIMS
+
+#define longlong    npy_longlong
+#define ulonglong   npy_ulonglong
+#define Bool        npy_bool
+#define longdouble  npy_longdouble
+#define byte        npy_byte
+
+#ifndef _BSD_SOURCE
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#endif
+
+#define ubyte       npy_ubyte
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#define cfloat      npy_cfloat
+#define cdouble     npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8        npy_int8
+#define UInt8       npy_uint8
+#define Int16       npy_int16
+#define UInt16      npy_uint16
+#define Int32       npy_int32
+#define UInt32      npy_uint32
+#define Int64       npy_int64
+#define UInt64      npy_uint64
+#define Int128      npy_int128
+#define UInt128     npy_uint128
+#define Int256      npy_int256
+#define UInt256     npy_uint256
+#define Float16     npy_float16
+#define Complex32   npy_complex32
+#define Float32     npy_float32
+#define Complex64   npy_complex64
+#define Float64     npy_float64
+#define Complex128  npy_complex128
+#define Float80     npy_float80
+#define Complex160  npy_complex160
+#define Float96     npy_float96
+#define Complex192  npy_complex192
+#define Float128    npy_float128
+#define Complex256  npy_complex256
+#define intp        npy_intp
+#define uintp       npy_uintp
+#define datetime    npy_datetime
+#define timedelta   npy_timedelta
+
+#define SIZEOF_LONGLONG         NPY_SIZEOF_LONGLONG
+#define SIZEOF_INTP             NPY_SIZEOF_INTP
+#define SIZEOF_UINTP            NPY_SIZEOF_UINTP
+#define SIZEOF_HALF             NPY_SIZEOF_HALF
+#define SIZEOF_LONGDOUBLE       NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_DATETIME         NPY_SIZEOF_DATETIME
+#define SIZEOF_TIMEDELTA        NPY_SIZEOF_TIMEDELTA
+
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX
+
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT   NPY_MAX_INT
+#define MIN_INT   NPY_MIN_INT
+#define MAX_UINT  NPY_MAX_UINT
+#define MAX_LONG  NPY_MAX_LONG
+#define MIN_LONG  NPY_MIN_LONG
+#define MAX_ULONG  NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+#define MIN_DATETIME NPY_MIN_DATETIME
+#define MAX_DATETIME NPY_MAX_DATETIME
+#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA
+#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA
+
+#define BITSOF_BOOL       NPY_BITSOF_BOOL
+#define BITSOF_CHAR       NPY_BITSOF_CHAR
+#define BITSOF_SHORT      NPY_BITSOF_SHORT
+#define BITSOF_INT        NPY_BITSOF_INT
+#define BITSOF_LONG       NPY_BITSOF_LONG
+#define BITSOF_LONGLONG   NPY_BITSOF_LONGLONG
+#define BITSOF_HALF       NPY_BITSOF_HALF
+#define BITSOF_FLOAT      NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE     NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+#define BITSOF_DATETIME   NPY_BITSOF_DATETIME
+#define BITSOF_TIMEDELTA   NPY_BITSOF_TIMEDELTA
+
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS     NPY_BEGIN_THREADS
+#define END_THREADS       NPY_END_THREADS
+#define ALLOW_C_API_DEF   NPY_ALLOW_C_API_DEF
+#define ALLOW_C_API       NPY_ALLOW_C_API
+#define DISABLE_C_API     NPY_DISABLE_C_API
+
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#endif
+
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#endif
+
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+
+#define CONTIGUOUS         NPY_CONTIGUOUS
+#define C_CONTIGUOUS       NPY_C_CONTIGUOUS
+#define FORTRAN            NPY_FORTRAN
+#define F_CONTIGUOUS       NPY_F_CONTIGUOUS
+#define OWNDATA            NPY_OWNDATA
+#define FORCECAST          NPY_FORCECAST
+#define ENSURECOPY         NPY_ENSURECOPY
+#define ENSUREARRAY        NPY_ENSUREARRAY
+#define ELEMENTSTRIDES     NPY_ELEMENTSTRIDES
+#define ALIGNED            NPY_ALIGNED
+#define NOTSWAPPED         NPY_NOTSWAPPED
+#define WRITEABLE          NPY_WRITEABLE
+#define UPDATEIFCOPY       NPY_UPDATEIFCOPY
+#define ARR_HAS_DESCR      NPY_ARR_HAS_DESCR
+#define BEHAVED            NPY_BEHAVED
+#define BEHAVED_NS         NPY_BEHAVED_NS
+#define CARRAY             NPY_CARRAY
+#define CARRAY_RO          NPY_CARRAY_RO
+#define FARRAY             NPY_FARRAY
+#define FARRAY_RO          NPY_FARRAY_RO
+#define DEFAULT            NPY_DEFAULT
+#define IN_ARRAY           NPY_IN_ARRAY
+#define OUT_ARRAY          NPY_OUT_ARRAY
+#define INOUT_ARRAY        NPY_INOUT_ARRAY
+#define IN_FARRAY          NPY_IN_FARRAY
+#define OUT_FARRAY         NPY_OUT_FARRAY
+#define INOUT_FARRAY       NPY_INOUT_FARRAY
+#define UPDATE_ALL         NPY_UPDATE_ALL
+
+#define OWN_DATA          NPY_OWNDATA
+#define BEHAVED_FLAGS     NPY_BEHAVED
+#define BEHAVED_FLAGS_NS  NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO   NPY_CARRAY_RO
+#define CARRAY_FLAGS      NPY_CARRAY
+#define FARRAY_FLAGS      NPY_FARRAY
+#define FARRAY_FLAGS_RO   NPY_FARRAY_RO
+#define DEFAULT_FLAGS     NPY_DEFAULT
+#define UPDATE_ALL_FLAGS  NPY_UPDATE_ALL_FLAGS
+
+#ifndef MIN
+#define MIN PyArray_MIN
+#endif
+#ifndef MAX
+#define MAX PyArray_MAX
+#endif
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_1_7_deprecated_api.h b/tools/msys/mingw64/include/python2.7/numpy/npy_1_7_deprecated_api.h
new file mode 100644
index 0000000000..4c318bc478
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_1_7_deprecated_api.h
@@ -0,0 +1,130 @@
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+#endif
+
+#if defined(_WIN32)
+#define _WARN___STR2__(x) #x
+#define _WARN___STR1__(x) _WARN___STR2__(x)
+#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: "
+#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
+                         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+#elif defined(__GNUC__)
+#warning "Using deprecated NumPy API, disable it by " \
+         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+#endif
+/* TODO: How to do this warning message for other compilers? */
+
+/*
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
+ *
+ * This is an attempt to remove bad API, the proliferation of macros,
+ * and namespace pollution currently produced by the NumPy headers.
+ */
+
+/* These array flags are deprecated as of NumPy 1.7 */
+#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
+
+/*
+ * The consistent NPY_ARRAY_* names which don't pollute the NPY_*
+ * namespace were added in NumPy 1.7.
+ *
+ * These versions of the carray flags are deprecated, but
+ * probably should only be removed after two releases instead of one.
+ */
+#define NPY_C_CONTIGUOUS   NPY_ARRAY_C_CONTIGUOUS
+#define NPY_F_CONTIGUOUS   NPY_ARRAY_F_CONTIGUOUS
+#define NPY_OWNDATA        NPY_ARRAY_OWNDATA
+#define NPY_FORCECAST      NPY_ARRAY_FORCECAST
+#define NPY_ENSURECOPY     NPY_ARRAY_ENSURECOPY
+#define NPY_ENSUREARRAY    NPY_ARRAY_ENSUREARRAY
+#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES
+#define NPY_ALIGNED        NPY_ARRAY_ALIGNED
+#define NPY_NOTSWAPPED     NPY_ARRAY_NOTSWAPPED
+#define NPY_WRITEABLE      NPY_ARRAY_WRITEABLE
+#define NPY_UPDATEIFCOPY   NPY_ARRAY_UPDATEIFCOPY
+#define NPY_BEHAVED        NPY_ARRAY_BEHAVED
+#define NPY_BEHAVED_NS     NPY_ARRAY_BEHAVED_NS
+#define NPY_CARRAY         NPY_ARRAY_CARRAY
+#define NPY_CARRAY_RO      NPY_ARRAY_CARRAY_RO
+#define NPY_FARRAY         NPY_ARRAY_FARRAY
+#define NPY_FARRAY_RO      NPY_ARRAY_FARRAY_RO
+#define NPY_DEFAULT        NPY_ARRAY_DEFAULT
+#define NPY_IN_ARRAY       NPY_ARRAY_IN_ARRAY
+#define NPY_OUT_ARRAY      NPY_ARRAY_OUT_ARRAY
+#define NPY_INOUT_ARRAY    NPY_ARRAY_INOUT_ARRAY
+#define NPY_IN_FARRAY      NPY_ARRAY_IN_FARRAY
+#define NPY_OUT_FARRAY     NPY_ARRAY_OUT_FARRAY
+#define NPY_INOUT_FARRAY   NPY_ARRAY_INOUT_FARRAY
+#define NPY_UPDATE_ALL     NPY_ARRAY_UPDATE_ALL
+
+/* This way of accessing the default type is deprecated as of NumPy 1.7 */
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+
+/* These DATETIME bits aren't used internally */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer(                   \
+                PyDict_GetItemString(                                         \
+                    descr->metadata, NPY_METADATA_DTSTR), NULL))))
+#else
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(                    \
+                PyDict_GetItemString(descr->metadata, NPY_METADATA_DTSTR)))))
+#endif
+
+/*
+ * Deprecated as of NumPy 1.7, this kind of shortcut doesn't
+ * belong in the public API.
+ */
+#define NPY_AO PyArrayObject
+
+/*
+ * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't
+ * belong in the public API.
+ */
+#define fortran fortran_
+
+/*
+ * Deprecated as of NumPy 1.7, as it is a namespace-polluting
+ * macro.
+ */
+#define FORTRAN_IF PyArray_FORTRAN_IF
+
+/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */
+#define NPY_METADATA_DTSTR "__timeunit__"
+
+/*
+ * Deprecated as of NumPy 1.7.
+ * The reasoning:
+ *  - These are for datetime, but there's no datetime "namespace".
+ *  - They just turn NPY_STR_<x> into "<x>", which is just
+ *    making something simple be indirected.
+ */
+#define NPY_STR_Y "Y"
+#define NPY_STR_M "M"
+#define NPY_STR_W "W"
+#define NPY_STR_D "D"
+#define NPY_STR_h "h"
+#define NPY_STR_m "m"
+#define NPY_STR_s "s"
+#define NPY_STR_ms "ms"
+#define NPY_STR_us "us"
+#define NPY_STR_ns "ns"
+#define NPY_STR_ps "ps"
+#define NPY_STR_fs "fs"
+#define NPY_STR_as "as"
+
+/*
+ * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be
+ * removed in the next major release.
+ */
+#include "old_defines.h"
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_3kcompat.h b/tools/msys/mingw64/include/python2.7/numpy/npy_3kcompat.h
new file mode 100644
index 0000000000..db60a312c3
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_3kcompat.h
@@ -0,0 +1,496 @@
+/*
+ * This is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ *
+ * If you want to use this for your own projects, it's recommended to make a
+ * copy of it. Although the stuff below is unlikely to change, we don't provide
+ * strong backwards compatibility guarantees at the moment.
+ */
+
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+
+#include <Python.h>
+#include <stdio.h>
+
+#if PY_VERSION_HEX >= 0x03000000
+#ifndef NPY_PY3K
+#define NPY_PY3K 1
+#endif
+#endif
+
+#include "numpy/npy_common.h"
+#include "numpy/ndarrayobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * PyInt -> PyLong
+ */
+
+#if defined(NPY_PY3K)
+/* Return True only if the long fits in a C long */
+static NPY_INLINE int PyInt_Check(PyObject *op) {
+    int overflow = 0;
+    if (!PyLong_Check(op)) {
+        return 0;
+    }
+    PyLong_AsLongAndOverflow(op, &overflow);
+    return (overflow == 0);
+}
+
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+
+/* NOTE:
+ *
+ * Since the PyLong type is very different from the fixed-range PyInt,
+ * we don't define PyInt_Type -> PyLong_Type.
+ */
+#endif /* NPY_PY3K */
+
+/*
+ * PyString -> PyBytes
+ */
+
+#if defined(NPY_PY3K)
+
+#define PyString_Type PyBytes_Type
+#define PyString_Check PyBytes_Check
+#define PyStringObject PyBytesObject
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define PyString_FromFormat PyBytes_FromFormat
+#define PyString_Concat PyBytes_Concat
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_Size PyBytes_Size
+
+#define PyUString_Type PyUnicode_Type
+#define PyUString_Check PyUnicode_Check
+#define PyUStringObject PyUnicodeObject
+#define PyUString_FromString PyUnicode_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyUString_FromFormat PyUnicode_FromFormat
+#define PyUString_Concat PyUnicode_Concat2
+#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_Size PyUnicode_Size
+#define PyUString_InternFromString PyUnicode_InternFromString
+#define PyUString_Format PyUnicode_Format
+
+#else
+
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytesObject PyStringObject
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_Size PyString_Size
+
+#define PyUString_Type PyString_Type
+#define PyUString_Check PyString_Check
+#define PyUStringObject PyStringObject
+#define PyUString_FromString PyString_FromString
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#define PyUString_FromFormat PyString_FromFormat
+#define PyUString_Concat PyString_Concat
+#define PyUString_ConcatAndDel PyString_ConcatAndDel
+#define PyUString_GET_SIZE PyString_GET_SIZE
+#define PyUString_Size PyString_Size
+#define PyUString_InternFromString PyString_InternFromString
+#define PyUString_Format PyString_Format
+
+#endif /* NPY_PY3K */
+
+
+static NPY_INLINE void
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    Py_DECREF(right);
+    *left = newobj;
+}
+
+static NPY_INLINE void
+PyUnicode_Concat2(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    *left = newobj;
+}
+
+/*
+ * PyFile_* compatibility
+ */
+#if defined(NPY_PY3K)
+/*
+ * Get a FILE* handle to the file represented by the Python object
+ */
+static NPY_INLINE FILE*
+npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
+{
+    int fd, fd2, unbuf;
+    PyObject *ret, *os, *io, *io_raw;
+    npy_off_t pos;
+    FILE *handle;
+
+    /* Flush first to ensure things end up in the file in the correct order */
+    ret = PyObject_CallMethod(file, "flush", "");
+    if (ret == NULL) {
+        return NULL;
+    }
+    Py_DECREF(ret);
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return NULL;
+    }
+
+    /*
+     * The handle needs to be dup'd because we have to call fclose
+     * at the end
+     */
+    os = PyImport_ImportModule("os");
+    if (os == NULL) {
+        return NULL;
+    }
+    ret = PyObject_CallMethod(os, "dup", "i", fd);
+    Py_DECREF(os);
+    if (ret == NULL) {
+        return NULL;
+    }
+    fd2 = PyNumber_AsSsize_t(ret, NULL);
+    Py_DECREF(ret);
+
+    /* Convert to FILE* handle */
+#ifdef _WIN32
+    handle = _fdopen(fd2, mode);
+#else
+    handle = fdopen(fd2, mode);
+#endif
+    if (handle == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "Getting a FILE* from a Python file object failed");
+    }
+
+    /* Record the original raw file handle position */
+    *orig_pos = npy_ftell(handle);
+    if (*orig_pos == -1) {
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return handle;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+            fclose(handle);
+            return NULL;
+        }
+    }
+
+    /* Seek raw handle to the Python-side position */
+    ret = PyObject_CallMethod(file, "tell", "");
+    if (ret == NULL) {
+        fclose(handle);
+        return NULL;
+    }
+    pos = PyLong_AsLongLong(ret);
+    Py_DECREF(ret);
+    if (PyErr_Occurred()) {
+        fclose(handle);
+        return NULL;
+    }
+    if (npy_fseek(handle, pos, SEEK_SET) == -1) {
+        PyErr_SetString(PyExc_IOError, "seeking file failed");
+        fclose(handle);
+        return NULL;
+    }
+    return handle;
+}
+
+/*
+ * Close the dup-ed file handle, and seek the Python one to the current position
+ */
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
+{
+    int fd, unbuf;
+    PyObject *ret, *io, *io_raw;
+    npy_off_t position;
+
+    position = npy_ftell(handle);
+
+    /* Close the FILE* handle */
+    fclose(handle);
+
+    /*
+     * Restore original file handle position, in order to not confuse
+     * Python-side data structures
+     */
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return -1;
+    }
+
+    if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
+
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            return -1;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            return -1;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return 0;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "seeking file failed");
+            return -1;
+        }
+    }
+
+    if (position == -1) {
+        PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+        return -1;
+    }
+
+    /* Seek Python-side handle to the FILE* handle position */
+    ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+static NPY_INLINE int
+npy_PyFile_Check(PyObject *file)
+{
+    int fd;
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        PyErr_Clear();
+        return 0;
+    }
+    return 1;
+}
+
+#else
+
+static NPY_INLINE FILE *
+npy_PyFile_Dup2(PyObject *file,
+                const char *NPY_UNUSED(mode), npy_off_t *NPY_UNUSED(orig_pos))
+{
+    FILE * fp = PyFile_AsFile(file);
+    if (fp == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "first argument must be an open file");
+        return NULL;
+    }
+    return fp;
+}
+
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *NPY_UNUSED(file), FILE* NPY_UNUSED(handle),
+                     npy_off_t NPY_UNUSED(orig_pos))
+{
+    return 0;
+}
+
+#define npy_PyFile_Check PyFile_Check
+
+#endif
+
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+{
+    PyObject *open;
+    open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+    if (open == NULL) {
+        return NULL;
+    }
+    return PyObject_CallFunction(open, "Os", filename, mode);
+}
+
+static NPY_INLINE int
+npy_PyFile_CloseFile(PyObject *file)
+{
+    PyObject *ret;
+
+    ret = PyObject_CallMethod(file, "close", NULL);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+/*
+ * PyObject_Cmp
+ */
+#if defined(NPY_PY3K)
+static NPY_INLINE int
+PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp)
+{
+    int v;
+    v = PyObject_RichCompareBool(i1, i2, Py_LT);
+    if (v == 1) {
+        *cmp = -1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_GT);
+    if (v == 1) {
+        *cmp = 1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_EQ);
+    if (v == 1) {
+        *cmp = 0;
+        return 1;
+    }
+    else {
+        *cmp = 0;
+        return -1;
+    }
+}
+#endif
+
+/*
+ * PyCObject functions adapted to PyCapsules.
+ *
+ * The main job here is to get rid of the improved error handling
+ * of PyCapsules. It's a shame...
+ */
+#if PY_VERSION_HEX >= 0x03000000
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *))
+{
+    PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor);
+    if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) {
+        PyErr_Clear();
+        Py_DECREF(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCapsule_GetContext(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context,
+        void (*dtor)(void *, void *))
+{
+    return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor);
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCObject_GetDesc(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NPY_3KCOMPAT_H_ */
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_common.h b/tools/msys/mingw64/include/python2.7/numpy/npy_common.h
new file mode 100644
index 0000000000..baf5549d97
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_common.h
@@ -0,0 +1,1069 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+
+/* numpconfig.h is auto-generated */
+#include "numpyconfig.h"
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+
+/* need Python.h for npy_intp, npy_uintp */
+#include <Python.h>
+
+/*
+ * gcc does not unroll even with -O3
+ * use with care, unrolling on modern cpus rarely speeds things up
+ */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS
+#define NPY_GCC_UNROLL_LOOPS \
+    __attribute__((optimize("unroll-loops")))
+#else
+#define NPY_GCC_UNROLL_LOOPS
+#endif
+
+/* highest gcc optimization level, enabled autovectorizer */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3
+#define NPY_GCC_OPT_3 __attribute__((optimize("O3")))
+#else
+#define NPY_GCC_OPT_3
+#endif
+
+/*
+ * mark an argument (starting from 1) that must not be NULL and is not checked
+ * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check
+ */
+#ifdef HAVE_ATTRIBUTE_NONNULL
+#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n)))
+#else
+#define NPY_GCC_NONNULL(n)
+#endif
+
+#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS
+#define NPY_HAVE_SSE_INTRINSICS
+#endif
+
+#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD
+#define NPY_HAVE_SSE2_INTRINSICS
+#endif
+
+/*
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ *
+ * if (NPY_UNLIKELY(failure == 0))
+ *    return NULL;
+ *
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+ */
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#endif
+
+#ifdef HAVE___BUILTIN_PREFETCH
+/* unlike _mm_prefetch also works on non-x86 */
+#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc))
+#else
+#ifdef HAVE__MM_PREFETCH
+/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */
+#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \
+                                             (loc == 1 ? _MM_HINT_T2 : \
+                                              (loc == 2 ? _MM_HINT_T1 : \
+                                               (loc == 3 ? _MM_HINT_T0 : -1))))
+#else
+#define NPY_PREFETCH(x, rw,loc)
+#endif
+#endif
+
+#if defined(_MSC_VER)
+        #define NPY_INLINE __inline
+#elif defined(__GNUC__)
+	#if defined(__STRICT_ANSI__)
+		#define NPY_INLINE __inline__
+	#else
+		#define NPY_INLINE inline
+	#endif
+#else
+        #define NPY_INLINE
+#endif
+
+#ifdef HAVE___THREAD
+    #define NPY_TLS __thread
+#else
+    #ifdef HAVE___DECLSPEC_THREAD_
+        #define NPY_TLS __declspec(thread)
+    #else
+        #define NPY_TLS
+    #endif
+#endif
+
+#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE
+  #define NPY_RETURNS_BORROWED_REF \
+    __attribute__((cpychecker_returns_borrowed_ref))
+#else
+  #define NPY_RETURNS_BORROWED_REF
+#endif
+
+#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE
+  #define NPY_STEALS_REF_TO_ARG(n) \
+   __attribute__((cpychecker_steals_reference_to_arg(n)))
+#else
+ #define NPY_STEALS_REF_TO_ARG(n)
+#endif
+
+/* 64 bit file position support, also on win-amd64. Ticket #1660 */
+#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \
+    defined(__MINGW32__) || defined(__MINGW64__)
+    #include <io.h>
+
+/* mingw based on 3.4.5 has lseek but not ftell/fseek */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+extern int __cdecl _fseeki64(FILE *, long long, int);
+extern long long __cdecl _ftelli64(FILE *);
+#endif
+
+    #define npy_fseek _fseeki64
+    #define npy_ftell _ftelli64
+    #define npy_lseek _lseeki64
+    #define npy_off_t npy_int64
+
+    #if NPY_SIZEOF_INT == 8
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_LONG == 8
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_LONGLONG == 8
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#else
+#ifdef HAVE_FSEEKO
+    #define npy_fseek fseeko
+#else
+    #define npy_fseek fseek
+#endif
+#ifdef HAVE_FTELLO
+    #define npy_ftell ftello
+#else
+    #define npy_ftell ftell
+#endif
+    #include <sys/types.h>
+    #define npy_lseek lseek
+    #define npy_off_t off_t
+
+    #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT
+        #define NPY_OFF_T_PYFMT "h"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#endif
+
+/* enums for detected endianness */
+enum {
+        NPY_CPU_UNKNOWN_ENDIAN,
+        NPY_CPU_LITTLE,
+        NPY_CPU_BIG
+};
+
+/*
+ * This is to typedef npy_intp to the appropriate pointer size for this
+ * platform.  Py_intptr_t, Py_uintptr_t are defined in pyport.h.
+ */
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+
+/*
+ * Define sizes that were not defined in numpyconfig.h.
+ */
+#define NPY_SIZEOF_CHAR 1
+#define NPY_SIZEOF_BYTE 1
+#define NPY_SIZEOF_DATETIME 8
+#define NPY_SIZEOF_TIMEDELTA 8
+#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_HALF 2
+#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT
+#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE
+#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE
+
+#ifdef constchar
+#undef constchar
+#endif
+
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+
+/* NPY_INTP_FMT Note:
+ *      Unlike the other NPY_*_FMT macros which are used with
+ *      PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and
+ *      PyString_Format. These functions use different formatting
+ *      codes which are portably specified according to the Python
+ *      documentation. See ticket #1795.
+ *
+ *      On Windows x64, the LONGLONG formatter should be used, but
+ *      in Python 2.6 the %lld formatter is not supported. In this
+ *      case we work around the problem by using the %zd formatter.
+ */
+#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT
+        #define NPY_INTP NPY_INT
+        #define NPY_UINTP NPY_UINT
+        #define PyIntpArrType_Type PyIntArrType_Type
+        #define PyUIntpArrType_Type PyUIntArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_INT
+        #define NPY_MIN_INTP NPY_MIN_INT
+        #define NPY_MAX_UINTP NPY_MAX_UINT
+        #define NPY_INTP_FMT "d"
+#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG
+        #define NPY_INTP NPY_LONG
+        #define NPY_UINTP NPY_ULONG
+        #define PyIntpArrType_Type PyLongArrType_Type
+        #define PyUIntpArrType_Type PyULongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONG
+        #define NPY_MIN_INTP NPY_MIN_LONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONG
+        #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG)
+        #define NPY_INTP NPY_LONGLONG
+        #define NPY_UINTP NPY_ULONGLONG
+        #define PyIntpArrType_Type PyLongLongArrType_Type
+        #define PyUIntpArrType_Type PyULongLongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONGLONG
+        #define NPY_MIN_INTP NPY_MIN_LONGLONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+    #if (PY_VERSION_HEX >= 0x02070000)
+        #define NPY_INTP_FMT "lld"
+    #else
+        #define NPY_INTP_FMT "zd"
+    #endif
+#endif
+
+/*
+ * We can only use C99 formats for npy_int_p if it is the same as
+ * intp_t, hence the condition on HAVE_UNITPTR_T
+ */
+#if (NPY_USE_C99_FORMATS) == 1 \
+        && (defined HAVE_UINTPTR_T) \
+        && (defined HAVE_INTTYPES_H)
+        #include <inttypes.h>
+        #undef NPY_INTP_FMT
+        #define NPY_INTP_FMT PRIdPTR
+#endif
+
+
+/*
+ * Some platforms don't define bool, long long, or long double.
+ * Handle that here.
+ */
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_HALF_FMT "g"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_FMT         "I64d"
+#    define NPY_ULONGLONG_FMT        "I64u"
+#  else
+#    define NPY_LONGLONG_FMT         "lld"
+#    define NPY_ULONGLONG_FMT        "llu"
+#  endif
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_SUFFIX(x)   (x##i64)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##Ui64)
+#  else
+#    define NPY_LONGLONG_SUFFIX(x)   (x##LL)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##ULL)
+#  endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+#  define NPY_LONGLONG_SUFFIX(x)  (x##L)
+#  define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+        typedef double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "g"
+#else
+        typedef long double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+/* These are for completeness */
+typedef char npy_char;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+typedef float npy_float;
+typedef double npy_double;
+
+/*
+ * Hash value compatibility.
+ * As of Python 3.2 hash values are of type Py_hash_t.
+ * Previous versions use C long.
+ */
+#if PY_VERSION_HEX < 0x03020000
+typedef long npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_LONG
+#else
+typedef Py_hash_t npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP
+#endif
+
+/*
+ * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being
+ * able to do .real/.imag. Will have to convert code first.
+ */
+#if 0
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE)
+typedef complex npy_cdouble;
+#else
+typedef struct { double real, imag; } npy_cdouble;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT)
+typedef complex float npy_cfloat;
+#else
+typedef struct { float real, imag; } npy_cfloat;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE)
+typedef complex long double npy_clongdouble;
+#else
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+#endif
+#endif
+#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE
+#error npy_cdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { double real, imag; } npy_cdouble;
+
+#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT
+#error npy_cfloat definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { float real, imag; } npy_cfloat;
+
+#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE
+#error npy_clongdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { npy_longdouble real, imag; } npy_clongdouble;
+
+/*
+ * numarray-style bit-width typedefs
+ */
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define NPY_MIN_DATETIME NPY_MIN_INT64
+#define NPY_MAX_DATETIME NPY_MAX_INT64
+#define NPY_MIN_TIMEDELTA NPY_MIN_INT64
+#define NPY_MAX_TIMEDELTA NPY_MAX_INT64
+
+        /* Need to find the number of bits for each type and
+           make definitions accordingly.
+
+           C states that sizeof(char) == 1 by definition
+
+           So, just using the sizeof keyword won't help.
+
+           It also looks like Python itself uses sizeof(char) quite a
+           bit, which by definition should be 1 all the time.
+
+           Idea: Make Use of CHAR_BIT which should tell us how many
+           BITS per CHARACTER
+        */
+
+        /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT   INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif
+#define NPY_MIN_INT   INT_MIN
+#define NPY_MAX_UINT  UINT_MAX
+#define NPY_MAX_LONG  LONG_MAX
+#define NPY_MIN_LONG  LONG_MIN
+#define NPY_MAX_ULONG  ULONG_MAX
+
+#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT)
+#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT)
+#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT)
+#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT)
+#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT)
+#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT)
+#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT)
+#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT)
+#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT)
+
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+        typedef long npy_int8;
+        typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+        typedef long npy_int16;
+        typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+        typedef long npy_int32;
+        typedef unsigned long npy_uint32;
+        typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+        typedef long npy_int64;
+        typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#define MyPyLong_FromInt64 PyLong_FromLong
+#define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+        typedef long npy_int128;
+        typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#endif
+
+#if NPY_BITSOF_LONGLONG == 8
+#  ifndef NPY_INT8
+#    define NPY_INT8 NPY_LONGLONG
+#    define NPY_UINT8 NPY_ULONGLONG
+        typedef npy_longlong npy_int8;
+        typedef npy_ulonglong npy_uint8;
+#    define PyInt8ScalarObject PyLongLongScalarObject
+#    define PyInt8ArrType_Type PyLongLongArrType_Type
+#    define PyUInt8ScalarObject PyULongLongScalarObject
+#    define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT8
+#  define NPY_MIN_LONGLONG NPY_MIN_INT8
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+#  ifndef NPY_INT16
+#    define NPY_INT16 NPY_LONGLONG
+#    define NPY_UINT16 NPY_ULONGLONG
+        typedef npy_longlong npy_int16;
+        typedef npy_ulonglong npy_uint16;
+#    define PyInt16ScalarObject PyLongLongScalarObject
+#    define PyInt16ArrType_Type PyLongLongArrType_Type
+#    define PyUInt16ScalarObject PyULongLongScalarObject
+#    define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT16
+#  define NPY_MIN_LONGLONG NPY_MIN_INT16
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+#  ifndef NPY_INT32
+#    define NPY_INT32 NPY_LONGLONG
+#    define NPY_UINT32 NPY_ULONGLONG
+        typedef npy_longlong npy_int32;
+        typedef npy_ulonglong npy_uint32;
+        typedef npy_ulonglong npy_ucs4;
+#    define PyInt32ScalarObject PyLongLongScalarObject
+#    define PyInt32ArrType_Type PyLongLongArrType_Type
+#    define PyUInt32ScalarObject PyULongLongScalarObject
+#    define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT32
+#  define NPY_MIN_LONGLONG NPY_MIN_INT32
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+#  ifndef NPY_INT64
+#    define NPY_INT64 NPY_LONGLONG
+#    define NPY_UINT64 NPY_ULONGLONG
+        typedef npy_longlong npy_int64;
+        typedef npy_ulonglong npy_uint64;
+#    define PyInt64ScalarObject PyLongLongScalarObject
+#    define PyInt64ArrType_Type PyLongLongArrType_Type
+#    define PyUInt64ScalarObject PyULongLongScalarObject
+#    define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLongLong
+#    define MyPyLong_AsInt64 PyLong_AsLongLong
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT64
+#  define NPY_MIN_LONGLONG NPY_MIN_INT64
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+#  ifndef NPY_INT128
+#    define NPY_INT128 NPY_LONGLONG
+#    define NPY_UINT128 NPY_ULONGLONG
+        typedef npy_longlong npy_int128;
+        typedef npy_ulonglong npy_uint128;
+#    define PyInt128ScalarObject PyLongLongScalarObject
+#    define PyInt128ArrType_Type PyLongLongArrType_Type
+#    define PyUInt128ScalarObject PyULongLongScalarObject
+#    define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT128
+#  define NPY_MIN_LONGLONG NPY_MIN_INT128
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+#  define NPY_INT256 NPY_LONGLONG
+#  define NPY_UINT256 NPY_ULONGLONG
+        typedef npy_longlong npy_int256;
+        typedef npy_ulonglong npy_uint256;
+#  define PyInt256ScalarObject PyLongLongScalarObject
+#  define PyInt256ArrType_Type PyLongLongArrType_Type
+#  define PyUInt256ScalarObject PyULongLongScalarObject
+#  define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+#  define NPY_MAX_LONGLONG NPY_MAX_INT256
+#  define NPY_MIN_LONGLONG NPY_MIN_INT256
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#endif
+
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+        typedef int npy_int8;
+        typedef unsigned int npy_uint8;
+#    define PyInt8ScalarObject PyIntScalarObject
+#    define PyInt8ArrType_Type PyIntArrType_Type
+#    define PyUInt8ScalarObject PyUIntScalarObject
+#    define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+        typedef int npy_int16;
+        typedef unsigned int npy_uint16;
+#    define PyInt16ScalarObject PyIntScalarObject
+#    define PyInt16ArrType_Type PyIntArrType_Type
+#    define PyUInt16ScalarObject PyIntUScalarObject
+#    define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+        typedef int npy_int32;
+        typedef unsigned int npy_uint32;
+        typedef unsigned int npy_ucs4;
+#    define PyInt32ScalarObject PyIntScalarObject
+#    define PyInt32ArrType_Type PyIntArrType_Type
+#    define PyUInt32ScalarObject PyUIntScalarObject
+#    define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+        typedef int npy_int64;
+        typedef unsigned int npy_uint64;
+#    define PyInt64ScalarObject PyIntScalarObject
+#    define PyInt64ArrType_Type PyIntArrType_Type
+#    define PyUInt64ScalarObject PyUIntScalarObject
+#    define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+        typedef int npy_int128;
+        typedef unsigned int npy_uint128;
+#    define PyInt128ScalarObject PyIntScalarObject
+#    define PyInt128ArrType_Type PyIntArrType_Type
+#    define PyUInt128ScalarObject PyUIntScalarObject
+#    define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#endif
+#endif
+
+#if NPY_BITSOF_SHORT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+        typedef short npy_int8;
+        typedef unsigned short npy_uint8;
+#    define PyInt8ScalarObject PyShortScalarObject
+#    define PyInt8ArrType_Type PyShortArrType_Type
+#    define PyUInt8ScalarObject PyUShortScalarObject
+#    define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+        typedef short npy_int16;
+        typedef unsigned short npy_uint16;
+#    define PyInt16ScalarObject PyShortScalarObject
+#    define PyInt16ArrType_Type PyShortArrType_Type
+#    define PyUInt16ScalarObject PyUShortScalarObject
+#    define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+        typedef short npy_int32;
+        typedef unsigned short npy_uint32;
+        typedef unsigned short npy_ucs4;
+#    define PyInt32ScalarObject PyShortScalarObject
+#    define PyInt32ArrType_Type PyShortArrType_Type
+#    define PyUInt32ScalarObject PyUShortScalarObject
+#    define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+        typedef short npy_int64;
+        typedef unsigned short npy_uint64;
+#    define PyInt64ScalarObject PyShortScalarObject
+#    define PyInt64ArrType_Type PyShortArrType_Type
+#    define PyUInt64ScalarObject PyUShortScalarObject
+#    define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_SHORT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+        typedef short npy_int128;
+        typedef unsigned short npy_uint128;
+#    define PyInt128ScalarObject PyShortScalarObject
+#    define PyInt128ArrType_Type PyShortArrType_Type
+#    define PyUInt128ScalarObject PyUShortScalarObject
+#    define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_CHAR == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+        typedef signed char npy_int8;
+        typedef unsigned char npy_uint8;
+#    define PyInt8ScalarObject PyByteScalarObject
+#    define PyInt8ArrType_Type PyByteArrType_Type
+#    define PyUInt8ScalarObject PyUByteScalarObject
+#    define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+        typedef signed char npy_int16;
+        typedef unsigned char npy_uint16;
+#    define PyInt16ScalarObject PyByteScalarObject
+#    define PyInt16ArrType_Type PyByteArrType_Type
+#    define PyUInt16ScalarObject PyUByteScalarObject
+#    define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+        typedef signed char npy_int32;
+        typedef unsigned char npy_uint32;
+        typedef unsigned char npy_ucs4;
+#    define PyInt32ScalarObject PyByteScalarObject
+#    define PyInt32ArrType_Type PyByteArrType_Type
+#    define PyUInt32ScalarObject PyUByteScalarObject
+#    define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+        typedef signed char npy_int64;
+        typedef unsigned char npy_uint64;
+#    define PyInt64ScalarObject PyByteScalarObject
+#    define PyInt64ArrType_Type PyByteArrType_Type
+#    define PyUInt64ScalarObject PyUByteScalarObject
+#    define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_CHAR == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+        typedef signed char npy_int128;
+        typedef unsigned char npy_uint128;
+#    define PyInt128ScalarObject PyByteScalarObject
+#    define PyInt128ArrType_Type PyByteArrType_Type
+#    define PyUInt128ScalarObject PyUByteScalarObject
+#    define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+        typedef double npy_float32;
+        typedef npy_cdouble npy_complex64;
+#    define PyFloat32ScalarObject PyDoubleScalarObject
+#    define PyComplex64ScalarObject PyCDoubleScalarObject
+#    define PyFloat32ArrType_Type PyDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+        typedef double npy_float64;
+        typedef npy_cdouble npy_complex128;
+#    define PyFloat64ScalarObject PyDoubleScalarObject
+#    define PyComplex128ScalarObject PyCDoubleScalarObject
+#    define PyFloat64ArrType_Type PyDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+        typedef double npy_float80;
+        typedef npy_cdouble npy_complex160;
+#    define PyFloat80ScalarObject PyDoubleScalarObject
+#    define PyComplex160ScalarObject PyCDoubleScalarObject
+#    define PyFloat80ArrType_Type PyDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+        typedef double npy_float96;
+        typedef npy_cdouble npy_complex192;
+#    define PyFloat96ScalarObject PyDoubleScalarObject
+#    define PyComplex192ScalarObject PyCDoubleScalarObject
+#    define PyFloat96ArrType_Type PyDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+        typedef double npy_float128;
+        typedef npy_cdouble npy_complex256;
+#    define PyFloat128ScalarObject PyDoubleScalarObject
+#    define PyComplex256ScalarObject PyCDoubleScalarObject
+#    define PyFloat128ArrType_Type PyDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_FLOAT == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+        typedef float npy_float32;
+        typedef npy_cfloat npy_complex64;
+#    define PyFloat32ScalarObject PyFloatScalarObject
+#    define PyComplex64ScalarObject PyCFloatScalarObject
+#    define PyFloat32ArrType_Type PyFloatArrType_Type
+#    define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+        typedef float npy_float64;
+        typedef npy_cfloat npy_complex128;
+#    define PyFloat64ScalarObject PyFloatScalarObject
+#    define PyComplex128ScalarObject PyCFloatScalarObject
+#    define PyFloat64ArrType_Type PyFloatArrType_Type
+#    define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+        typedef float npy_float80;
+        typedef npy_cfloat npy_complex160;
+#    define PyFloat80ScalarObject PyFloatScalarObject
+#    define PyComplex160ScalarObject PyCFloatScalarObject
+#    define PyFloat80ArrType_Type PyFloatArrType_Type
+#    define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+        typedef float npy_float96;
+        typedef npy_cfloat npy_complex192;
+#    define PyFloat96ScalarObject PyFloatScalarObject
+#    define PyComplex192ScalarObject PyCFloatScalarObject
+#    define PyFloat96ArrType_Type PyFloatArrType_Type
+#    define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+        typedef float npy_float128;
+        typedef npy_cfloat npy_complex256;
+#    define PyFloat128ScalarObject PyFloatScalarObject
+#    define PyComplex256ScalarObject PyCFloatScalarObject
+#    define PyFloat128ArrType_Type PyFloatArrType_Type
+#    define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+#endif
+#endif
+
+/* half/float16 isn't a floating-point type in C */
+#define NPY_FLOAT16 NPY_HALF
+typedef npy_uint16 npy_half;
+typedef npy_half npy_float16;
+
+#if NPY_BITSOF_LONGDOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float32;
+        typedef npy_clongdouble npy_complex64;
+#    define PyFloat32ScalarObject PyLongDoubleScalarObject
+#    define PyComplex64ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float64;
+        typedef npy_clongdouble npy_complex128;
+#    define PyFloat64ScalarObject PyLongDoubleScalarObject
+#    define PyComplex128ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float80;
+        typedef npy_clongdouble npy_complex160;
+#    define PyFloat80ScalarObject PyLongDoubleScalarObject
+#    define PyComplex160ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float96;
+        typedef npy_clongdouble npy_complex192;
+#    define PyFloat96ScalarObject PyLongDoubleScalarObject
+#    define PyComplex192ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float128;
+        typedef npy_clongdouble npy_complex256;
+#    define PyFloat128ScalarObject PyLongDoubleScalarObject
+#    define PyComplex256ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float256;
+        typedef npy_clongdouble npy_complex512;
+#    define PyFloat256ScalarObject PyLongDoubleScalarObject
+#    define PyComplex512ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+#endif
+
+/* datetime typedefs */
+typedef npy_int64 npy_timedelta;
+typedef npy_int64 npy_datetime;
+#define NPY_DATETIME_FMT NPY_INT64_FMT
+#define NPY_TIMEDELTA_FMT NPY_INT64_FMT
+
+/* End of typedefs for numarray style bit-width names */
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_cpu.h b/tools/msys/mingw64/include/python2.7/numpy/npy_cpu.h
new file mode 100644
index 0000000000..60abae4e0b
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_cpu.h
@@ -0,0 +1,92 @@
+/*
+ * This set (target) cpu specific macros:
+ *      - Possible values:
+ *              NPY_CPU_X86
+ *              NPY_CPU_AMD64
+ *              NPY_CPU_PPC
+ *              NPY_CPU_PPC64
+ *              NPY_CPU_PPC64LE
+ *              NPY_CPU_SPARC
+ *              NPY_CPU_S390
+ *              NPY_CPU_IA64
+ *              NPY_CPU_HPPA
+ *              NPY_CPU_ALPHA
+ *              NPY_CPU_ARMEL
+ *              NPY_CPU_ARMEB
+ *              NPY_CPU_SH_LE
+ *              NPY_CPU_SH_BE
+ */
+#ifndef _NPY_CPUARCH_H_
+#define _NPY_CPUARCH_H_
+
+#include "numpyconfig.h"
+#include <string.h> /* for memcpy */
+
+#if defined( __i386__ ) || defined(i386) || defined(_M_IX86)
+    /*
+     * __i386__ is defined by gcc and Intel compiler on Linux,
+     * _M_IX86 by VS compiler,
+     * i386 by Sun compilers on opensolaris at least
+     */
+    #define NPY_CPU_X86
+#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64)
+    /*
+     * both __x86_64__ and __amd64__ are defined by gcc
+     * __x86_64 defined by sun compiler on opensolaris at least
+     * _M_AMD64 defined by MS compiler
+     */
+    #define NPY_CPU_AMD64
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC)
+    /*
+     * __ppc__ is defined by gcc, I remember having seen __powerpc__ once,
+     * but can't find it ATM
+     * _ARCH_PPC is used by at least gcc on AIX
+     */
+    #define NPY_CPU_PPC
+#elif defined(__ppc64le__)
+    #define NPY_CPU_PPC64LE
+#elif defined(__ppc64__)
+    #define NPY_CPU_PPC64
+#elif defined(__sparc__) || defined(__sparc)
+    /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */
+    #define NPY_CPU_SPARC
+#elif defined(__s390__)
+    #define NPY_CPU_S390
+#elif defined(__ia64)
+    #define NPY_CPU_IA64
+#elif defined(__hppa)
+    #define NPY_CPU_HPPA
+#elif defined(__alpha__)
+    #define NPY_CPU_ALPHA
+#elif defined(__arm__) && defined(__ARMEL__)
+    #define NPY_CPU_ARMEL
+#elif defined(__arm__) && defined(__ARMEB__)
+    #define NPY_CPU_ARMEB
+#elif defined(__sh__) && defined(__LITTLE_ENDIAN__)
+    #define NPY_CPU_SH_LE
+#elif defined(__sh__) && defined(__BIG_ENDIAN__)
+    #define NPY_CPU_SH_BE
+#elif defined(__MIPSEL__)
+    #define NPY_CPU_MIPSEL
+#elif defined(__MIPSEB__)
+    #define NPY_CPU_MIPSEB
+#elif defined(__or1k__)
+    #define NPY_CPU_OR1K
+#elif defined(__aarch64__)
+    #define NPY_CPU_AARCH64
+#elif defined(__mc68000__)
+    #define NPY_CPU_M68K
+#else
+    #error Unknown CPU, please report this to numpy maintainers with \
+    information about your platform (OS, CPU and compiler)
+#endif
+
+#define NPY_COPY_PYOBJECT_PTR(dst, src) memcpy(dst, src, sizeof(PyObject *))
+
+#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
+#else
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_endian.h b/tools/msys/mingw64/include/python2.7/numpy/npy_endian.h
new file mode 100644
index 0000000000..a8ec572458
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_endian.h
@@ -0,0 +1,61 @@
+#ifndef _NPY_ENDIAN_H_
+#define _NPY_ENDIAN_H_
+
+/*
+ * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in
+ * endian.h
+ */
+
+#ifdef NPY_HAVE_ENDIAN_H
+    /* Use endian.h if available */
+    #include <endian.h>
+
+    #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    BIG_ENDIAN
+    #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    _BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    _BIG_ENDIAN
+    #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    __BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    __BIG_ENDIAN
+    #endif
+#endif
+
+#ifndef NPY_BYTE_ORDER
+    /* Set endianness info using target CPU */
+    #include "npy_cpu.h"
+
+    #define NPY_LITTLE_ENDIAN 1234
+    #define NPY_BIG_ENDIAN 4321
+
+    #if defined(NPY_CPU_X86)            \
+            || defined(NPY_CPU_AMD64)   \
+            || defined(NPY_CPU_IA64)    \
+            || defined(NPY_CPU_ALPHA)   \
+            || defined(NPY_CPU_ARMEL)   \
+            || defined(NPY_CPU_AARCH64) \
+            || defined(NPY_CPU_SH_LE)   \
+            || defined(NPY_CPU_MIPSEL)  \
+            || defined(NPY_CPU_PPC64LE)
+        #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
+    #elif defined(NPY_CPU_PPC)          \
+            || defined(NPY_CPU_SPARC)   \
+            || defined(NPY_CPU_S390)    \
+            || defined(NPY_CPU_HPPA)    \
+            || defined(NPY_CPU_PPC64)   \
+            || defined(NPY_CPU_ARMEB)   \
+            || defined(NPY_CPU_SH_BE)   \
+            || defined(NPY_CPU_MIPSEB)  \
+            || defined(NPY_CPU_OR1K)    \
+            || defined(NPY_CPU_M68K)
+        #define NPY_BYTE_ORDER NPY_BIG_ENDIAN
+    #else
+        #error Unknown CPU: can not set endianness
+    #endif
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_interrupt.h b/tools/msys/mingw64/include/python2.7/numpy/npy_interrupt.h
new file mode 100644
index 0000000000..f71fd689eb
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_interrupt.h
@@ -0,0 +1,117 @@
+
+/* Signal handling:
+
+This header file defines macros that allow your code to handle
+interrupts received during processing.  Interrupts that
+could reasonably be handled:
+
+SIGINT, SIGABRT, SIGALRM, SIGSEGV
+
+****Warning***************
+
+Do not allow code that creates temporary memory or increases reference
+counts of Python objects to be interrupted unless you handle it
+differently.
+
+**************************
+
+The mechanism for handling interrupts is conceptually simple:
+
+  - replace the signal handler with our own home-grown version
+     and store the old one.
+  - run the code to be interrupted -- if an interrupt occurs
+     the handler should basically just cause a return to the
+     calling function for finish work.
+  - restore the old signal handler
+
+Of course, every code that allows interrupts must account for
+returning via the interrupt and handle clean-up correctly.  But,
+even still, the simple paradigm is complicated by at least three
+factors.
+
+ 1) platform portability (i.e. Microsoft says not to use longjmp
+     to return from signal handling.  They have a __try  and __except
+     extension to C instead but what about mingw?).
+
+ 2) how to handle threads: apparently whether signals are delivered to
+    every thread of the process or the "invoking" thread is platform
+    dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance.  For now, assume the
+    code will not call-back into itself.
+
+Ideas:
+
+ 1) Start by implementing an approach that works on platforms that
+    can use setjmp and longjmp functionality and does nothing
+    on other platforms.
+
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
+
+ 3) Add a default signal_handler function to the C-API but have the rest
+    use macros.
+
+
+Simple Interface:
+
+
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
+[code]
+NPY_SIGINT_OFF
+
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects.  In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
+
+Interrupt handling does not work well with threads.
+
+*/
+
+/* Add signal handling macros
+   Make the global variable and signal handler part of the C-API
+*/
+
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef sigsetjmp
+
+#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF jmp_buf
+
+#else
+
+#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF sigjmp_buf
+
+#endif
+
+#    define NPY_SIGINT_ON {                                             \
+                   PyOS_sighandler_t _npy_sig_save;                     \
+                   _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+                   if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+                                 1) == 0) {                             \
+
+#    define NPY_SIGINT_OFF }                                      \
+        PyOS_setsig(SIGINT, _npy_sig_save);                       \
+        }
+
+#else /* NPY_NO_SIGNAL  */
+
+#define NPY_SIGINT_ON
+#define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
+#endif /* NPY_INTERRUPT_H */
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_math.h b/tools/msys/mingw64/include/python2.7/numpy/npy_math.h
new file mode 100644
index 0000000000..e76508de04
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_math.h
@@ -0,0 +1,529 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#ifdef __SUNPRO_CC
+#include <sunmath.h>
+#endif
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+#include <numpy/npy_common.h>
+
+
+/*
+ * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
+ * for INFINITY)
+ *
+ * XXX: I should test whether INFINITY and NAN are available on the platform
+ */
+NPY_INLINE static float __npy_inff(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nanf(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_pzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL};
+    return __bint.__f;
+}
+
+#define NPY_INFINITYF __npy_inff()
+#define NPY_NANF __npy_nanf()
+#define NPY_PZEROF __npy_pzerof()
+#define NPY_NZEROF __npy_nzerof()
+
+#define NPY_INFINITY ((npy_double)NPY_INFINITYF)
+#define NPY_NAN ((npy_double)NPY_NANF)
+#define NPY_PZERO ((npy_double)NPY_PZEROF)
+#define NPY_NZERO ((npy_double)NPY_NZEROF)
+
+#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF)
+#define NPY_NANL ((npy_longdouble)NPY_NANF)
+#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF)
+#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF)
+
+/*
+ * Useful constants
+ */
+#define NPY_E         2.718281828459045235360287471352662498  /* e */
+#define NPY_LOG2E     1.442695040888963407359924681001892137  /* log_2 e */
+#define NPY_LOG10E    0.434294481903251827651128918916605082  /* log_10 e */
+#define NPY_LOGE2     0.693147180559945309417232121458176568  /* log_e 2 */
+#define NPY_LOGE10    2.302585092994045684017991454684364208  /* log_e 10 */
+#define NPY_PI        3.141592653589793238462643383279502884  /* pi */
+#define NPY_PI_2      1.570796326794896619231321691639751442  /* pi/2 */
+#define NPY_PI_4      0.785398163397448309615660845819875721  /* pi/4 */
+#define NPY_1_PI      0.318309886183790671537767526745028724  /* 1/pi */
+#define NPY_2_PI      0.636619772367581343075535053490057448  /* 2/pi */
+#define NPY_EULER     0.577215664901532860606512090082402431  /* Euler constant */
+#define NPY_SQRT2     1.414213562373095048801688724209698079  /* sqrt(2) */
+#define NPY_SQRT1_2   0.707106781186547524400844362104849039  /* 1/sqrt(2) */
+
+#define NPY_Ef        2.718281828459045235360287471352662498F /* e */
+#define NPY_LOG2Ef    1.442695040888963407359924681001892137F /* log_2 e */
+#define NPY_LOG10Ef   0.434294481903251827651128918916605082F /* log_10 e */
+#define NPY_LOGE2f    0.693147180559945309417232121458176568F /* log_e 2 */
+#define NPY_LOGE10f   2.302585092994045684017991454684364208F /* log_e 10 */
+#define NPY_PIf       3.141592653589793238462643383279502884F /* pi */
+#define NPY_PI_2f     1.570796326794896619231321691639751442F /* pi/2 */
+#define NPY_PI_4f     0.785398163397448309615660845819875721F /* pi/4 */
+#define NPY_1_PIf     0.318309886183790671537767526745028724F /* 1/pi */
+#define NPY_2_PIf     0.636619772367581343075535053490057448F /* 2/pi */
+#define NPY_EULERf    0.577215664901532860606512090082402431F /* Euler constant */
+#define NPY_SQRT2f    1.414213562373095048801688724209698079F /* sqrt(2) */
+#define NPY_SQRT1_2f  0.707106781186547524400844362104849039F /* 1/sqrt(2) */
+
+#define NPY_El        2.718281828459045235360287471352662498L /* e */
+#define NPY_LOG2El    1.442695040888963407359924681001892137L /* log_2 e */
+#define NPY_LOG10El   0.434294481903251827651128918916605082L /* log_10 e */
+#define NPY_LOGE2l    0.693147180559945309417232121458176568L /* log_e 2 */
+#define NPY_LOGE10l   2.302585092994045684017991454684364208L /* log_e 10 */
+#define NPY_PIl       3.141592653589793238462643383279502884L /* pi */
+#define NPY_PI_2l     1.570796326794896619231321691639751442L /* pi/2 */
+#define NPY_PI_4l     0.785398163397448309615660845819875721L /* pi/4 */
+#define NPY_1_PIl     0.318309886183790671537767526745028724L /* 1/pi */
+#define NPY_2_PIl     0.636619772367581343075535053490057448L /* 2/pi */
+#define NPY_EULERl    0.577215664901532860606512090082402431L /* Euler constant */
+#define NPY_SQRT2l    1.414213562373095048801688724209698079L /* sqrt(2) */
+#define NPY_SQRT1_2l  0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+
+/*
+ * C99 double math funcs
+ */
+double npy_sin(double x);
+double npy_cos(double x);
+double npy_tan(double x);
+double npy_sinh(double x);
+double npy_cosh(double x);
+double npy_tanh(double x);
+
+double npy_asin(double x);
+double npy_acos(double x);
+double npy_atan(double x);
+
+double npy_log(double x);
+double npy_log10(double x);
+double npy_exp(double x);
+double npy_sqrt(double x);
+double npy_cbrt(double x);
+
+double npy_fabs(double x);
+double npy_ceil(double x);
+double npy_fmod(double x, double y);
+double npy_floor(double x);
+
+double npy_expm1(double x);
+double npy_log1p(double x);
+double npy_hypot(double x, double y);
+double npy_acosh(double x);
+double npy_asinh(double xx);
+double npy_atanh(double x);
+double npy_rint(double x);
+double npy_trunc(double x);
+double npy_exp2(double x);
+double npy_log2(double x);
+
+double npy_atan2(double x, double y);
+double npy_pow(double x, double y);
+double npy_modf(double x, double* y);
+double npy_frexp(double x, int* y);
+double npy_ldexp(double n, int y);
+
+double npy_copysign(double x, double y);
+double npy_nextafter(double x, double y);
+double npy_spacing(double x);
+
+/*
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+ */
+
+/* use builtins to avoid function calls in tight loops
+ * only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISNAN
+    #define npy_isnan(x) __builtin_isnan(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISNAN
+        #define npy_isnan(x) ((x) != (x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isnan(x) _isnan((x))
+        #else
+            #define npy_isnan(x) isnan(x)
+        #endif
+    #endif
+#endif
+
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISFINITE
+    #define npy_isfinite(x) __builtin_isfinite(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISFINITE
+        #ifdef _MSC_VER
+            #define npy_isfinite(x) _finite((x))
+        #else
+            #define npy_isfinite(x) !npy_isnan((x) + (-x))
+        #endif
+    #else
+        #define npy_isfinite(x) isfinite((x))
+    #endif
+#endif
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISINF
+    #define npy_isinf(x) __builtin_isinf(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISINF
+        #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+        #else
+            #define npy_isinf(x) isinf((x))
+        #endif
+    #endif
+#endif
+
+#ifndef NPY_HAVE_DECL_SIGNBIT
+    int _npy_signbit_f(float x);
+    int _npy_signbit_d(double x);
+    int _npy_signbit_ld(long double x);
+    #define npy_signbit(x) \
+        (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+         : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+         : _npy_signbit_f (x))
+#else
+    #define npy_signbit(x) signbit((x))
+#endif
+
+/*
+ * float C99 math functions
+ */
+
+float npy_sinf(float x);
+float npy_cosf(float x);
+float npy_tanf(float x);
+float npy_sinhf(float x);
+float npy_coshf(float x);
+float npy_tanhf(float x);
+float npy_fabsf(float x);
+float npy_floorf(float x);
+float npy_ceilf(float x);
+float npy_rintf(float x);
+float npy_truncf(float x);
+float npy_sqrtf(float x);
+float npy_cbrtf(float x);
+float npy_log10f(float x);
+float npy_logf(float x);
+float npy_expf(float x);
+float npy_expm1f(float x);
+float npy_asinf(float x);
+float npy_acosf(float x);
+float npy_atanf(float x);
+float npy_asinhf(float x);
+float npy_acoshf(float x);
+float npy_atanhf(float x);
+float npy_log1pf(float x);
+float npy_exp2f(float x);
+float npy_log2f(float x);
+
+float npy_atan2f(float x, float y);
+float npy_hypotf(float x, float y);
+float npy_powf(float x, float y);
+float npy_fmodf(float x, float y);
+
+float npy_modff(float x, float* y);
+float npy_frexpf(float x, int* y);
+float npy_ldexpf(float x, int y);
+
+float npy_copysignf(float x, float y);
+float npy_nextafterf(float x, float y);
+float npy_spacingf(float x);
+
+/*
+ * long double C99 math functions
+ */
+
+npy_longdouble npy_sinl(npy_longdouble x);
+npy_longdouble npy_cosl(npy_longdouble x);
+npy_longdouble npy_tanl(npy_longdouble x);
+npy_longdouble npy_sinhl(npy_longdouble x);
+npy_longdouble npy_coshl(npy_longdouble x);
+npy_longdouble npy_tanhl(npy_longdouble x);
+npy_longdouble npy_fabsl(npy_longdouble x);
+npy_longdouble npy_floorl(npy_longdouble x);
+npy_longdouble npy_ceill(npy_longdouble x);
+npy_longdouble npy_rintl(npy_longdouble x);
+npy_longdouble npy_truncl(npy_longdouble x);
+npy_longdouble npy_sqrtl(npy_longdouble x);
+npy_longdouble npy_cbrtl(npy_longdouble x);
+npy_longdouble npy_log10l(npy_longdouble x);
+npy_longdouble npy_logl(npy_longdouble x);
+npy_longdouble npy_expl(npy_longdouble x);
+npy_longdouble npy_expm1l(npy_longdouble x);
+npy_longdouble npy_asinl(npy_longdouble x);
+npy_longdouble npy_acosl(npy_longdouble x);
+npy_longdouble npy_atanl(npy_longdouble x);
+npy_longdouble npy_asinhl(npy_longdouble x);
+npy_longdouble npy_acoshl(npy_longdouble x);
+npy_longdouble npy_atanhl(npy_longdouble x);
+npy_longdouble npy_log1pl(npy_longdouble x);
+npy_longdouble npy_exp2l(npy_longdouble x);
+npy_longdouble npy_log2l(npy_longdouble x);
+
+npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+
+npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_spacingl(npy_longdouble x);
+
+/*
+ * Non standard functions
+ */
+double npy_deg2rad(double x);
+double npy_rad2deg(double x);
+double npy_logaddexp(double x, double y);
+double npy_logaddexp2(double x, double y);
+double npy_divmod(double x, double y, double *modulus);
+
+float npy_deg2radf(float x);
+float npy_rad2degf(float x);
+float npy_logaddexpf(float x, float y);
+float npy_logaddexp2f(float x, float y);
+float npy_divmodf(float x, float y, float *modulus);
+
+npy_longdouble npy_deg2radl(npy_longdouble x);
+npy_longdouble npy_rad2degl(npy_longdouble x);
+npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+                           npy_longdouble *modulus);
+
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+
+/*
+ * Complex declarations
+ */
+
+/*
+ * C99 specifies that complex numbers have the same representation as
+ * an array of two elements, where the first element is the real part
+ * and the second element is the imaginary part.
+ */
+#define __NPY_CPACK_IMP(x, y, type, ctype)   \
+    union {                                  \
+        ctype z;                             \
+        type a[2];                           \
+    } z1;;                                   \
+                                             \
+    z1.a[0] = (x);                           \
+    z1.a[1] = (y);                           \
+                                             \
+    return z1.z;
+
+static NPY_INLINE npy_cdouble npy_cpack(double x, double y)
+{
+    __NPY_CPACK_IMP(x, y, double, npy_cdouble);
+}
+
+static NPY_INLINE npy_cfloat npy_cpackf(float x, float y)
+{
+    __NPY_CPACK_IMP(x, y, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y)
+{
+    __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CPACK_IMP
+
+/*
+ * Same remark as above, but in the other direction: extract first/second
+ * member of complex number, assuming a C99-compatible representation
+ *
+ * Those are defineds as static inline, and such as a reasonable compiler would
+ * most likely compile this to one or two instructions (on CISC at least)
+ */
+#define __NPY_CEXTRACT_IMP(z, index, type, ctype)   \
+    union {                                         \
+        ctype z;                                    \
+        type a[2];                                  \
+    } __z_repr;                                     \
+    __z_repr.z = z;                                 \
+                                                    \
+    return __z_repr.a[index];
+
+static NPY_INLINE double npy_creal(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble);
+}
+
+static NPY_INLINE double npy_cimag(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble);
+}
+
+static NPY_INLINE float npy_crealf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat);
+}
+
+static NPY_INLINE float npy_cimagf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble);
+}
+
+static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CEXTRACT_IMP
+
+/*
+ * Double precision complex functions
+ */
+double npy_cabs(npy_cdouble z);
+double npy_carg(npy_cdouble z);
+
+npy_cdouble npy_cexp(npy_cdouble z);
+npy_cdouble npy_clog(npy_cdouble z);
+npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y);
+
+npy_cdouble npy_csqrt(npy_cdouble z);
+
+npy_cdouble npy_ccos(npy_cdouble z);
+npy_cdouble npy_csin(npy_cdouble z);
+npy_cdouble npy_ctan(npy_cdouble z);
+
+npy_cdouble npy_ccosh(npy_cdouble z);
+npy_cdouble npy_csinh(npy_cdouble z);
+npy_cdouble npy_ctanh(npy_cdouble z);
+
+npy_cdouble npy_cacos(npy_cdouble z);
+npy_cdouble npy_casin(npy_cdouble z);
+npy_cdouble npy_catan(npy_cdouble z);
+
+npy_cdouble npy_cacosh(npy_cdouble z);
+npy_cdouble npy_casinh(npy_cdouble z);
+npy_cdouble npy_catanh(npy_cdouble z);
+
+/*
+ * Single precision complex functions
+ */
+float npy_cabsf(npy_cfloat z);
+float npy_cargf(npy_cfloat z);
+
+npy_cfloat npy_cexpf(npy_cfloat z);
+npy_cfloat npy_clogf(npy_cfloat z);
+npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y);
+
+npy_cfloat npy_csqrtf(npy_cfloat z);
+
+npy_cfloat npy_ccosf(npy_cfloat z);
+npy_cfloat npy_csinf(npy_cfloat z);
+npy_cfloat npy_ctanf(npy_cfloat z);
+
+npy_cfloat npy_ccoshf(npy_cfloat z);
+npy_cfloat npy_csinhf(npy_cfloat z);
+npy_cfloat npy_ctanhf(npy_cfloat z);
+
+npy_cfloat npy_cacosf(npy_cfloat z);
+npy_cfloat npy_casinf(npy_cfloat z);
+npy_cfloat npy_catanf(npy_cfloat z);
+
+npy_cfloat npy_cacoshf(npy_cfloat z);
+npy_cfloat npy_casinhf(npy_cfloat z);
+npy_cfloat npy_catanhf(npy_cfloat z);
+
+
+/*
+ * Extended precision complex functions
+ */
+npy_longdouble npy_cabsl(npy_clongdouble z);
+npy_longdouble npy_cargl(npy_clongdouble z);
+
+npy_clongdouble npy_cexpl(npy_clongdouble z);
+npy_clongdouble npy_clogl(npy_clongdouble z);
+npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y);
+
+npy_clongdouble npy_csqrtl(npy_clongdouble z);
+
+npy_clongdouble npy_ccosl(npy_clongdouble z);
+npy_clongdouble npy_csinl(npy_clongdouble z);
+npy_clongdouble npy_ctanl(npy_clongdouble z);
+
+npy_clongdouble npy_ccoshl(npy_clongdouble z);
+npy_clongdouble npy_csinhl(npy_clongdouble z);
+npy_clongdouble npy_ctanhl(npy_clongdouble z);
+
+npy_clongdouble npy_cacosl(npy_clongdouble z);
+npy_clongdouble npy_casinl(npy_clongdouble z);
+npy_clongdouble npy_catanl(npy_clongdouble z);
+
+npy_clongdouble npy_cacoshl(npy_clongdouble z);
+npy_clongdouble npy_casinhl(npy_clongdouble z);
+npy_clongdouble npy_catanhl(npy_clongdouble z);
+
+
+/*
+ * Functions that set the floating point error
+ * status word.
+ */
+
+/*
+ * platform-dependent code translates floating point
+ * status to an integer sum of these values
+ */
+#define NPY_FPE_DIVIDEBYZERO  1
+#define NPY_FPE_OVERFLOW      2
+#define NPY_FPE_UNDERFLOW     4
+#define NPY_FPE_INVALID       8
+
+int npy_get_floatstatus(void);
+int npy_clear_floatstatus(void);
+void npy_set_floatstatus_divbyzero(void);
+void npy_set_floatstatus_overflow(void);
+void npy_set_floatstatus_underflow(void);
+void npy_set_floatstatus_invalid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_no_deprecated_api.h b/tools/msys/mingw64/include/python2.7/numpy/npy_no_deprecated_api.h
new file mode 100644
index 0000000000..6183dc2784
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_no_deprecated_api.h
@@ -0,0 +1,19 @@
+/*
+ * This include file is provided for inclusion in Cython *.pyd files where
+ * one would like to define the NPY_NO_DEPRECATED_API macro. It can be
+ * included by
+ *
+ * cdef extern from "npy_no_deprecated_api.h": pass
+ *
+ */
+#ifndef NPY_NO_DEPRECATED_API
+
+/* put this check here since there may be multiple includes in C extensions. */
+#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \
+    defined(OLD_DEFINES_H)
+#error "npy_no_deprecated_api.h" must be first among numpy includes.
+#else
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/npy_os.h b/tools/msys/mingw64/include/python2.7/numpy/npy_os.h
new file mode 100644
index 0000000000..9228c3916e
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/npy_os.h
@@ -0,0 +1,30 @@
+#ifndef _NPY_OS_H_
+#define _NPY_OS_H_
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+    #define NPY_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
+            defined(__OpenBSD__) || defined(__DragonFly__)
+    #define NPY_OS_BSD
+    #ifdef __FreeBSD__
+        #define NPY_OS_FREEBSD
+    #elif defined(__NetBSD__)
+        #define NPY_OS_NETBSD
+    #elif defined(__OpenBSD__)
+        #define NPY_OS_OPENBSD
+    #elif defined(__DragonFly__)
+        #define NPY_OS_DRAGONFLY
+    #endif
+#elif defined(sun) || defined(__sun)
+    #define NPY_OS_SOLARIS
+#elif defined(__CYGWIN__)
+    #define NPY_OS_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+    #define NPY_OS_WIN32
+#elif defined(__APPLE__)
+    #define NPY_OS_DARWIN
+#else
+    #define NPY_OS_UNKNOWN
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/numpyconfig.h b/tools/msys/mingw64/include/python2.7/numpy/numpyconfig.h
new file mode 100644
index 0000000000..cbf4a62b9f
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/numpyconfig.h
@@ -0,0 +1,37 @@
+#ifndef _NPY_NUMPYCONFIG_H_
+#define _NPY_NUMPYCONFIG_H_
+
+#include "_numpyconfig.h"
+
+/*
+ * On Mac OS X, because there is only one configuration stage for all the archs
+ * in universal builds, any macro which depends on the arch needs to be
+ * harcoded
+ */
+#ifdef __APPLE__
+    #undef NPY_SIZEOF_LONG
+    #undef NPY_SIZEOF_PY_INTPTR_T
+
+    #ifdef __LP64__
+        #define NPY_SIZEOF_LONG         8
+        #define NPY_SIZEOF_PY_INTPTR_T  8
+    #else
+        #define NPY_SIZEOF_LONG         4
+        #define NPY_SIZEOF_PY_INTPTR_T  4
+    #endif
+#endif
+
+/**
+ * To help with the NPY_NO_DEPRECATED_API macro, we include API version
+ * numbers for specific versions of NumPy. To exclude all API that was
+ * deprecated as of 1.7, add the following before #including any NumPy
+ * headers:
+ *   #define NPY_NO_DEPRECATED_API  NPY_1_7_API_VERSION
+ */
+#define NPY_1_7_API_VERSION 0x00000007
+#define NPY_1_8_API_VERSION 0x00000008
+#define NPY_1_9_API_VERSION 0x00000008
+#define NPY_1_10_API_VERSION 0x00000008
+#define NPY_1_11_API_VERSION 0x00000008
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/old_defines.h b/tools/msys/mingw64/include/python2.7/numpy/old_defines.h
new file mode 100644
index 0000000000..abf81595ae
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/old_defines.h
@@ -0,0 +1,187 @@
+/* This header is deprecated as of NumPy 1.7 */
+#ifndef OLD_DEFINES_H
+#define OLD_DEFINES_H
+
+#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION
+#error The header "old_defines.h" is deprecated as of NumPy 1.7.
+#endif
+
+#define NDARRAY_VERSION NPY_VERSION
+
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+
+#define PyArray_TYPES       NPY_TYPES
+#define PyArray_BOOL        NPY_BOOL
+#define PyArray_BYTE        NPY_BYTE
+#define PyArray_UBYTE       NPY_UBYTE
+#define PyArray_SHORT       NPY_SHORT
+#define PyArray_USHORT      NPY_USHORT
+#define PyArray_INT         NPY_INT
+#define PyArray_UINT        NPY_UINT
+#define PyArray_LONG        NPY_LONG
+#define PyArray_ULONG       NPY_ULONG
+#define PyArray_LONGLONG    NPY_LONGLONG
+#define PyArray_ULONGLONG   NPY_ULONGLONG
+#define PyArray_HALF        NPY_HALF
+#define PyArray_FLOAT       NPY_FLOAT
+#define PyArray_DOUBLE      NPY_DOUBLE
+#define PyArray_LONGDOUBLE  NPY_LONGDOUBLE
+#define PyArray_CFLOAT      NPY_CFLOAT
+#define PyArray_CDOUBLE     NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT      NPY_OBJECT
+#define PyArray_STRING      NPY_STRING
+#define PyArray_UNICODE     NPY_UNICODE
+#define PyArray_VOID        NPY_VOID
+#define PyArray_DATETIME    NPY_DATETIME
+#define PyArray_TIMEDELTA   NPY_TIMEDELTA
+#define PyArray_NTYPES      NPY_NTYPES
+#define PyArray_NOTYPE      NPY_NOTYPE
+#define PyArray_CHAR        NPY_CHAR
+#define PyArray_USERDEF     NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+
+#define PyArray_INTP        NPY_INTP
+#define PyArray_UINTP       NPY_UINTP
+
+#define PyArray_INT8    NPY_INT8
+#define PyArray_UINT8   NPY_UINT8
+#define PyArray_INT16   NPY_INT16
+#define PyArray_UINT16  NPY_UINT16
+#define PyArray_INT32   NPY_INT32
+#define PyArray_UINT32  NPY_UINT32
+
+#ifdef NPY_INT64
+#define PyArray_INT64   NPY_INT64
+#define PyArray_UINT64  NPY_UINT64
+#endif
+
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#endif
+
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16  NPY_FLOAT16
+#define PyArray_COMPLEX32  NPY_COMPLEX32
+#endif
+
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80  NPY_FLOAT80
+#define PyArray_COMPLEX160  NPY_COMPLEX160
+#endif
+
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96  NPY_FLOAT96
+#define PyArray_COMPLEX192  NPY_COMPLEX192
+#endif
+
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128  NPY_FLOAT128
+#define PyArray_COMPLEX256  NPY_COMPLEX256
+#endif
+
+#define PyArray_FLOAT32    NPY_FLOAT32
+#define PyArray_COMPLEX64  NPY_COMPLEX64
+#define PyArray_FLOAT64    NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+
+
+#define PyArray_TYPECHAR        NPY_TYPECHAR
+#define PyArray_BOOLLTR         NPY_BOOLLTR
+#define PyArray_BYTELTR         NPY_BYTELTR
+#define PyArray_UBYTELTR        NPY_UBYTELTR
+#define PyArray_SHORTLTR        NPY_SHORTLTR
+#define PyArray_USHORTLTR       NPY_USHORTLTR
+#define PyArray_INTLTR          NPY_INTLTR
+#define PyArray_UINTLTR         NPY_UINTLTR
+#define PyArray_LONGLTR         NPY_LONGLTR
+#define PyArray_ULONGLTR        NPY_ULONGLTR
+#define PyArray_LONGLONGLTR     NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR    NPY_ULONGLONGLTR
+#define PyArray_HALFLTR         NPY_HALFLTR
+#define PyArray_FLOATLTR        NPY_FLOATLTR
+#define PyArray_DOUBLELTR       NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR   NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR       NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR      NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR  NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR       NPY_OBJECTLTR
+#define PyArray_STRINGLTR       NPY_STRINGLTR
+#define PyArray_STRINGLTR2      NPY_STRINGLTR2
+#define PyArray_UNICODELTR      NPY_UNICODELTR
+#define PyArray_VOIDLTR         NPY_VOIDLTR
+#define PyArray_DATETIMELTR     NPY_DATETIMELTR
+#define PyArray_TIMEDELTALTR    NPY_TIMEDELTALTR
+#define PyArray_CHARLTR         NPY_CHARLTR
+#define PyArray_INTPLTR         NPY_INTPLTR
+#define PyArray_UINTPLTR        NPY_UINTPLTR
+#define PyArray_GENBOOLLTR      NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR       NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR     NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR     NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR      NPY_COMPLEXLTR
+
+#define PyArray_QUICKSORT   NPY_QUICKSORT
+#define PyArray_HEAPSORT    NPY_HEAPSORT
+#define PyArray_MERGESORT   NPY_MERGESORT
+#define PyArray_SORTKIND    NPY_SORTKIND
+#define PyArray_NSORTS      NPY_NSORTS
+
+#define PyArray_NOSCALAR       NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR    NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR  NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR  NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR   NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR  NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND     NPY_SCALARKIND
+#define PyArray_NSCALARKINDS   NPY_NSCALARKINDS
+
+#define PyArray_ANYORDER     NPY_ANYORDER
+#define PyArray_CORDER       NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER        NPY_ORDER
+
+#define PyDescr_ISBOOL      PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED  PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED    PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER   PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT     PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER    PyDataType_ISNUMBER
+#define PyDescr_ISSTRING    PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX   PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON    PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE  PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF   PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED  PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT    PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS   PyDataType_HASFIELDS
+
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+
+#define PyArray_RemoveLargest PyArray_RemoveSmallest
+
+#define PyArray_UCS4 npy_ucs4
+
+#endif
diff --git a/tools/msys/mingw64/include/python2.7/numpy/oldnumeric.h b/tools/msys/mingw64/include/python2.7/numpy/oldnumeric.h
new file mode 100644
index 0000000000..748f06da31
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/oldnumeric.h
@@ -0,0 +1,23 @@
+#include "arrayobject.h"
+
+#ifndef REFCOUNT
+#  define REFCOUNT NPY_REFCOUNT
+#  define MAX_ELSIZE 16
+#endif
+
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE NPY_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define OWN_DATA NPY_OWNDATA
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
diff --git a/tools/msys/mingw64/include/python2.7/numpy/ufunc_api.txt b/tools/msys/mingw64/include/python2.7/numpy/ufunc_api.txt
new file mode 100644
index 0000000000..172749633f
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/ufunc_api.txt
@@ -0,0 +1,321 @@
+
+=================
+Numpy Ufunc C-API
+=================
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void
+                          **data, char *types, int ntypes, int nin, int
+                          nout, int identity, const char *name, const
+                          char *doc, int unused)
+
+
+::
+
+  int
+  PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int
+                              usertype, PyUFuncGenericFunction
+                              function, int *arg_types, void *data)
+
+
+::
+
+  int
+  PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject
+                          *kwds, PyArrayObject **op)
+
+
+This generic function is called with the ufunc object, the arguments to it,
+and an array of (pointers to) PyArrayObjects which are NULL.
+
+'op' is an array of at least NPY_MAXARGS PyArrayObject *.
+
+::
+
+  void
+  PyUFunc_f_f_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_g_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_F_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_G_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_O_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_gg_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_GG_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_O_O_method(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O_method(char **args, npy_intp *dimensions, npy_intp
+                      *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_On_Om(char **args, npy_intp *dimensions, npy_intp *steps, void
+                *func)
+
+
+::
+
+  int
+  PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject
+                      **errobj)
+
+
+On return, if errobj is populated with a non-NULL value, the caller
+owns a new reference to errobj.
+
+::
+
+  int
+  PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first)
+
+
+::
+
+  void
+  PyUFunc_clearfperr()
+
+
+::
+
+  int
+  PyUFunc_getfperr(void )
+
+
+::
+
+  int
+  PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int
+                      *first)
+
+
+::
+
+  int
+  PyUFunc_ReplaceLoopBySignature(PyUFuncObject
+                                 *func, PyUFuncGenericFunction
+                                 newfunc, int
+                                 *signature, PyUFuncGenericFunction
+                                 *oldfunc)
+
+
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void
+                                      **data, char *types, int
+                                      ntypes, int nin, int nout, int
+                                      identity, const char *name, const
+                                      char *doc, int unused, const char
+                                      *signature)
+
+
+::
+
+  int
+  PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+
+
+::
+
+  void
+  PyUFunc_e_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_f_f(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_ff_f(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  int
+  PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING
+                              casting, PyArrayObject
+                              **operands, PyObject
+                              *type_tup, PyArray_Descr **out_dtypes)
+
+
+This function applies the default type resolution rules
+for the provided ufunc.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING
+                          casting, PyArrayObject
+                          **operands, PyArray_Descr **dtypes)
+
+
+Validates that the input operands can be cast to
+the input types, and the output types can be cast to
+the output operands where provided.
+
+Returns 0 on success, -1 (with exception raised) on validation failure.
+
+::
+
+  int
+  PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr
+                               *user_dtype, PyUFuncGenericFunction
+                               function, PyArray_Descr
+                               **arg_dtypes, void *data)
+
+
diff --git a/tools/msys/mingw64/include/python2.7/numpy/ufuncobject.h b/tools/msys/mingw64/include/python2.7/numpy/ufuncobject.h
new file mode 100644
index 0000000000..1cca64b75b
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/ufuncobject.h
@@ -0,0 +1,357 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+
+#include <numpy/npy_math.h>
+#include <numpy/npy_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The legacy generic inner loop for a standard element-wise or
+ * generalized ufunc.
+ */
+typedef void (*PyUFuncGenericFunction)
+            (char **args,
+             npy_intp *dimensions,
+             npy_intp *strides,
+             void *innerloopdata);
+
+/*
+ * The most generic one-dimensional inner loop for
+ * a masked standard element-wise ufunc. "Masked" here means that it skips
+ * doing calculations on any items for which the maskptr array has a true
+ * value.
+ */
+typedef void (PyUFunc_MaskedStridedInnerLoopFunc)(
+                char **dataptrs, npy_intp *strides,
+                char *maskptr, npy_intp mask_stride,
+                npy_intp count,
+                NpyAuxData *innerloopdata);
+
+/* Forward declaration for the type resolver and loop selector typedefs */
+struct _tagPyUFuncObject;
+
+/*
+ * Given the operands for calling a ufunc, should determine the
+ * calculation input and output data types and return an inner loop function.
+ * This function should validate that the casting rule is being followed,
+ * and fail if it is not.
+ *
+ * For backwards compatibility, the regular type resolution function does not
+ * support auxiliary data with object semantics. The type resolution call
+ * which returns a masked generic function returns a standard NpyAuxData
+ * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros
+ * work.
+ *
+ * ufunc:             The ufunc object.
+ * casting:           The 'casting' parameter provided to the ufunc.
+ * operands:          An array of length (ufunc->nin + ufunc->nout),
+ *                    with the output parameters possibly NULL.
+ * type_tup:          Either NULL, or the type_tup passed to the ufunc.
+ * out_dtypes:        An array which should be populated with new
+ *                    references to (ufunc->nin + ufunc->nout) new
+ *                    dtypes, one for each input and output. These
+ *                    dtypes should all be in native-endian format.
+ *
+ * Should return 0 on success, -1 on failure (with exception set),
+ * or -2 if Py_NotImplemented should be returned.
+ */
+typedef int (PyUFunc_TypeResolutionFunc)(
+                                struct _tagPyUFuncObject *ufunc,
+                                NPY_CASTING casting,
+                                PyArrayObject **operands,
+                                PyObject *type_tup,
+                                PyArray_Descr **out_dtypes);
+
+/*
+ * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc,
+ * and an array of fixed strides (the array will contain NPY_MAX_INTP for
+ * strides which are not necessarily fixed), returns an inner loop
+ * with associated auxiliary data.
+ *
+ * For backwards compatibility, there is a variant of the inner loop
+ * selection which returns an inner loop irrespective of the strides,
+ * and with a void* static auxiliary data instead of an NpyAuxData *
+ * dynamically allocatable auxiliary data.
+ *
+ * ufunc:             The ufunc object.
+ * dtypes:            An array which has been populated with dtypes,
+ *                    in most cases by the type resolution funciton
+ *                    for the same ufunc.
+ * fixed_strides:     For each input/output, either the stride that
+ *                    will be used every time the function is called
+ *                    or NPY_MAX_INTP if the stride might change or
+ *                    is not known ahead of time. The loop selection
+ *                    function may use this stride to pick inner loops
+ *                    which are optimized for contiguous or 0-stride
+ *                    cases.
+ * out_innerloop:     Should be populated with the correct ufunc inner
+ *                    loop for the given type.
+ * out_innerloopdata: Should be populated with the void* data to
+ *                    be passed into the out_innerloop function.
+ * out_needs_api:     If the inner loop needs to use the Python API,
+ *                    should set the to 1, otherwise should leave
+ *                    this untouched.
+ */
+typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyUFuncGenericFunction *out_innerloop,
+                            void **out_innerloopdata,
+                            int *out_needs_api);
+typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyArray_Descr *mask_dtype,
+                            npy_intp *fixed_strides,
+                            npy_intp fixed_mask_stride,
+                            PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
+                            NpyAuxData **out_innerloopdata,
+                            int *out_needs_api);
+
+typedef struct _tagPyUFuncObject {
+        PyObject_HEAD
+        /*
+         * nin: Number of inputs
+         * nout: Number of outputs
+         * nargs: Always nin + nout (Why is it stored?)
+         */
+        int nin, nout, nargs;
+
+        /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */
+        int identity;
+
+        /* Array of one-dimensional core loops */
+        PyUFuncGenericFunction *functions;
+        /* Array of funcdata that gets passed into the functions */
+        void **data;
+        /* The number of elements in 'functions' and 'data' */
+        int ntypes;
+
+        /* Used to be unused field 'check_return' */
+        int reserved1;
+
+        /* The name of the ufunc */
+        const char *name;
+
+        /* Array of type numbers, of size ('nargs' * 'ntypes') */
+        char *types;
+
+        /* Documentation string */
+        const char *doc;
+
+        void *ptr;
+        PyObject *obj;
+        PyObject *userloops;
+
+        /* generalized ufunc parameters */
+
+        /* 0 for scalar ufunc; 1 for generalized ufunc */
+        int core_enabled;
+        /* number of distinct dimension names in signature */
+        int core_num_dim_ix;
+
+        /*
+         * dimension indices of input/output argument k are stored in
+         * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1]
+         */
+
+        /* numbers of core dimensions of each argument */
+        int *core_num_dims;
+        /*
+         * dimension indices in a flatted form; indices
+         * are in the range of [0,core_num_dim_ix)
+         */
+        int *core_dim_ixs;
+        /*
+         * positions of 1st core dimensions of each
+         * argument in core_dim_ixs
+         */
+        int *core_offsets;
+        /* signature string for printing purpose */
+        char *core_signature;
+
+        /*
+         * A function which resolves the types and fills an array
+         * with the dtypes for the inputs and outputs.
+         */
+        PyUFunc_TypeResolutionFunc *type_resolver;
+        /*
+         * A function which returns an inner loop written for
+         * NumPy 1.6 and earlier ufuncs. This is for backwards
+         * compatibility, and may be NULL if inner_loop_selector
+         * is specified.
+         */
+        PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
+        /*
+         * This was blocked off to be the "new" inner loop selector in 1.7,
+         * but this was never implemented. (This is also why the above
+         * selector is called the "legacy" selector.)
+         */
+        void *reserved2;
+        /*
+         * A function which returns a masked inner loop for the ufunc.
+         */
+        PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+
+        /*
+         * List of flags for each operand when ufunc is called by nditer object.
+         * These flags will be used in addition to the default flags for each
+         * operand set by nditer object.
+         */
+        npy_uint32 *op_flags;
+
+        /*
+         * List of global flags used when ufunc is called by nditer object.
+         * These flags will be used in addition to the default global flags
+         * set by nditer object.
+         */
+        npy_uint32 iter_flags;
+} PyUFuncObject;
+
+#include "arrayobject.h"
+
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN   1
+#define UFUNC_ERR_RAISE  2
+#define UFUNC_ERR_CALL   3
+#define UFUNC_ERR_PRINT  4
+#define UFUNC_ERR_LOG    5
+
+        /* Python side integer mask */
+
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW     3
+#define UFUNC_SHIFT_UNDERFLOW    6
+#define UFUNC_SHIFT_INVALID      9
+
+
+#define UFUNC_OBJ_ISOBJECT      1
+#define UFUNC_OBJ_NEEDS_API     2
+
+   /* Default user error mode */
+#define UFUNC_ERR_DEFAULT                               \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) +  \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) +      \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
+
+#if NPY_ALLOW_THREADS
+#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0);
+#define NPY_LOOP_END_THREADS   do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0);
+#else
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+#endif
+
+/*
+ * UFunc has unit of 1, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_One 1
+/*
+ * UFunc has unit of 0, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_Zero 0
+/*
+ * UFunc has no unit, and the order of operations cannot be reordered.
+ * This case does not allow reduction with multiple axes at once.
+ */
+#define PyUFunc_None -1
+/*
+ * UFunc has no unit, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_ReorderableNone -2
+
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+
+
+typedef struct {
+        int nin;
+        int nout;
+        PyObject *callable;
+} PyUFunc_PyFuncData;
+
+/* A linked-list of function information for
+   user-defined 1-d loops.
+ */
+typedef struct _loop1d_info {
+        PyUFuncGenericFunction func;
+        void *data;
+        int *arg_types;
+        struct _loop1d_info *next;
+        int nargs;
+        PyArray_Descr **arg_dtypes;
+} PyUFunc_Loop1d;
+
+
+#include "__ufunc_api.h"
+
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+
+#define UFUNC_CHECK_ERROR(arg) \
+        do {if ((((arg)->obj & UFUNC_OBJ_NEEDS_API) && PyErr_Occurred()) || \
+            ((arg)->errormask && \
+             PyUFunc_checkfperr((arg)->errormask, \
+                                (arg)->errobj, \
+                                &(arg)->first))) \
+                goto fail;} while (0)
+
+
+/* keep in sync with ieee754.c.src */
+#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
+      defined(__NetBSD__) || \
+      defined(__GLIBC__) || defined(__APPLE__) || \
+      defined(__CYGWIN__) || defined(__MINGW32__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version >= 502114)) || \
+      defined(_AIX) || \
+      defined(_MSC_VER) || \
+      defined(__osf__) && defined(__alpha)
+#else
+#define NO_FLOATING_POINT_SUPPORT
+#endif
+
+
+/*
+ * THESE MACROS ARE DEPRECATED.
+ * Use npy_set_floatstatus_* in the npymath library.
+ */
+#define UFUNC_FPE_DIVIDEBYZERO  NPY_FPE_DIVIDEBYZERO
+#define UFUNC_FPE_OVERFLOW      NPY_FPE_OVERFLOW
+#define UFUNC_FPE_UNDERFLOW     NPY_FPE_UNDERFLOW
+#define UFUNC_FPE_INVALID       NPY_FPE_INVALID
+
+#define UFUNC_CHECK_STATUS(ret) \
+    { \
+       ret = npy_clear_floatstatus(); \
+    }
+#define generate_divbyzero_error() npy_set_floatstatus_divbyzero()
+#define generate_overflow_error() npy_set_floatstatus_overflow()
+
+  /* Make sure it gets defined if it isn't already */
+#ifndef UFUNC_NOFPE
+/* Clear the floating point exception default of Borland C++ */
+#if defined(__BORLANDC__)
+#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM);
+#else
+#define UFUNC_NOFPE
+#endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UFUNCOBJECT_H */
diff --git a/tools/msys/mingw64/include/python2.7/numpy/utils.h b/tools/msys/mingw64/include/python2.7/numpy/utils.h
new file mode 100644
index 0000000000..cc968a3544
--- /dev/null
+++ b/tools/msys/mingw64/include/python2.7/numpy/utils.h
@@ -0,0 +1,19 @@
+#ifndef __NUMPY_UTILS_HEADER__
+#define __NUMPY_UTILS_HEADER__
+
+#ifndef __COMP_NPY_UNUSED
+        #if defined(__GNUC__)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        # elif defined(__ICC)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        #else
+                #define __COMP_NPY_UNUSED
+        #endif
+#endif
+
+/* Use this to tag a variable as not used. It will remove unused variable
+ * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable
+ * to avoid accidental use */
+#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
new file mode 100644
index 0000000000..cebc908ba3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
@@ -0,0 +1,47 @@
+Metadata-Version: 1.1
+Name: numpy
+Version: 1.11.0
+Summary: NumPy: array processing for numbers, strings, records, and objects.
+Home-page: http://www.numpy.org
+Author: NumPy Developers
+Author-email: numpy-discussion@scipy.org
+License: BSD
+Download-URL: http://sourceforge.net/projects/numpy/files/NumPy/
+Description: NumPy is a general-purpose array-processing package designed to
+        efficiently manipulate large multi-dimensional arrays of arbitrary
+        records without sacrificing too much speed for small multi-dimensional
+        arrays.  NumPy is built on the Numeric code base and adds features
+        introduced by numarray as well as an extended C-API and the ability to
+        create arrays of arbitrary type which also makes NumPy suitable for
+        interfacing with general-purpose data-base applications.
+        
+        There are also basic facilities for discrete fourier transform,
+        basic linear algebra and random number generation.
+        
+        
+Platform: Windows
+Platform: Linux
+Platform: Solaris
+Platform: Mac OS-X
+Platform: Unix
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Science/Research
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Software Development
+Classifier: Topic :: Scientific/Engineering
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: Unix
+Classifier: Operating System :: MacOS
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
new file mode 100644
index 0000000000..08df5f1808
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
@@ -0,0 +1,1054 @@
+INSTALL.rst.txt
+LICENSE.txt
+MANIFEST.in
+THANKS.txt
+setup.py
+site.cfg.example
+doc/Makefile
+doc/postprocess.py
+doc/f2py/BUGS.txt
+doc/f2py/FAQ.txt
+doc/f2py/HISTORY.txt
+doc/f2py/Makefile
+doc/f2py/OLDNEWS.txt
+doc/f2py/README.txt
+doc/f2py/Release-1.x.txt
+doc/f2py/Release-2.x.txt
+doc/f2py/Release-3.x.txt
+doc/f2py/Release-4.x.txt
+doc/f2py/TESTING.txt
+doc/f2py/THANKS.txt
+doc/f2py/TODO.txt
+doc/f2py/apps.tex
+doc/f2py/bugs.tex
+doc/f2py/collectinput.py
+doc/f2py/commands.tex
+doc/f2py/default.css
+doc/f2py/docutils.conf
+doc/f2py/f2py.1
+doc/f2py/f2py2e.tex
+doc/f2py/fortranobject.tex
+doc/f2py/hello.f
+doc/f2py/index.html
+doc/f2py/intro.tex
+doc/f2py/multiarrays.txt
+doc/f2py/notes.tex
+doc/f2py/oldnews.html
+doc/f2py/options.tex
+doc/f2py/pyforttest.pyf
+doc/f2py/pytest.py
+doc/f2py/python9.tex
+doc/f2py/signaturefile.tex
+doc/f2py/simple.f
+doc/f2py/simple_session.dat
+doc/f2py/using_F_compiler.txt
+doc/f2py/win32_notes.txt
+doc/f2py/ex1/arr.f
+doc/f2py/ex1/bar.f
+doc/f2py/ex1/foo.f
+doc/f2py/ex1/foobar-smart.f90
+doc/f2py/ex1/foobar.f90
+doc/f2py/ex1/foobarmodule.tex
+doc/f2py/ex1/runme
+doc/f2py/f2python9-final/README.txt
+doc/f2py/f2python9-final/aerostructure.jpg
+doc/f2py/f2python9-final/flow.jpg
+doc/f2py/f2python9-final/mk_html.sh
+doc/f2py/f2python9-final/mk_pdf.sh
+doc/f2py/f2python9-final/mk_ps.sh
+doc/f2py/f2python9-final/structure.jpg
+doc/f2py/f2python9-final/src/examples/exp1.f
+doc/f2py/f2python9-final/src/examples/exp1mess.txt
+doc/f2py/f2python9-final/src/examples/exp1session.txt
+doc/f2py/f2python9-final/src/examples/foo.pyf
+doc/f2py/f2python9-final/src/examples/foom.pyf
+doc/f2py/multiarray/array_from_pyobj.c
+doc/f2py/multiarray/bar.c
+doc/f2py/multiarray/foo.f
+doc/f2py/multiarray/fortran_array_from_pyobj.txt
+doc/f2py/multiarray/fun.pyf
+doc/f2py/multiarray/run.pyf
+doc/f2py/multiarray/transpose.txt
+doc/release/1.10.0-notes.rst
+doc/release/1.10.1-notes.rst
+doc/release/1.10.2-notes.rst
+doc/release/1.10.3-notes.rst
+doc/release/1.10.4-notes.rst
+doc/release/1.11.0-notes.rst
+doc/release/1.3.0-notes.rst
+doc/release/1.4.0-notes.rst
+doc/release/1.5.0-notes.rst
+doc/release/1.6.0-notes.rst
+doc/release/1.6.1-notes.rst
+doc/release/1.6.2-notes.rst
+doc/release/1.7.0-notes.rst
+doc/release/1.7.1-notes.rst
+doc/release/1.7.2-notes.rst
+doc/release/1.8.0-notes.rst
+doc/release/1.8.1-notes.rst
+doc/release/1.8.2-notes.rst
+doc/release/1.9.0-notes.rst
+doc/release/1.9.1-notes.rst
+doc/release/1.9.2-notes.rst
+doc/release/time_based_proposal.rst
+doc/scipy-sphinx-theme/.git
+doc/scipy-sphinx-theme/.gitignore
+doc/scipy-sphinx-theme/Makefile
+doc/scipy-sphinx-theme/README.rst
+doc/scipy-sphinx-theme/conf.py
+doc/scipy-sphinx-theme/index.rst
+doc/scipy-sphinx-theme/test_autodoc.rst
+doc/scipy-sphinx-theme/test_autodoc_2.rst
+doc/scipy-sphinx-theme/test_autodoc_3.rst
+doc/scipy-sphinx-theme/test_autodoc_4.rst
+doc/scipy-sphinx-theme/test_optimize.rst
+doc/scipy-sphinx-theme/_static/scipyshiny_small.png
+doc/scipy-sphinx-theme/_theme/scipy/layout.html
+doc/scipy-sphinx-theme/_theme/scipy/searchbox.html
+doc/scipy-sphinx-theme/_theme/scipy/sourcelink.html
+doc/scipy-sphinx-theme/_theme/scipy/theme.conf
+doc/scipy-sphinx-theme/_theme/scipy/static/scipy.css_t
+doc/scipy-sphinx-theme/_theme/scipy/static/css/extend.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/pygments.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/scipy-central.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/spc-bootstrap.css
+doc/scipy-sphinx-theme/_theme/scipy/static/css/spc-extend.css
+doc/scipy-sphinx-theme/_theme/scipy/static/img/all-icons.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/contents.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/create-new-account-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon-tiniest.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/external-link-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/glyphicons-halflings-white.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/glyphicons-halflings.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/important-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/information-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/internet-web-browser.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/multiple-file-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/navigation.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/person-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/person-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipy-logo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipy_org_logo.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipycentral_logo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/scipyshiny_small.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/send-email-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon-shrunk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-icon.svg
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon-tiniest.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon-tiny.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/single-file-list-icon.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/transparent-pixel.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/ui-anim_basic_16x16.gif
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ad.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ae.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-af.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ag.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ai.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-al.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-am.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ao.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-aq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ar.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-as.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-at.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-au.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-aw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-az.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ba.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-be.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-br.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-by.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-bz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ca.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ch.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ci.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ck.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-co.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cx.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-cz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-de.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-do.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-dz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ec.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ee.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-eg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-er.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-es.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-et.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-fr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ga.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ge.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-gy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ht.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-hu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-id.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ie.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-il.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-im.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-in.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-io.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-iq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ir.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-is.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-it.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-je.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-jp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ke.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ki.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-km.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ky.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-kz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-la.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-li.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ls.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-lv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ly.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ma.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-md.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-me.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ml.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mo.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mp.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mq.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ms.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mx.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-my.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-mz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-na.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ne.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ng.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ni.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-no.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-np.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-nz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-om.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pe.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ph.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ps.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-pw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-py.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-qa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-re.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ro.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-rs.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ru.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-rw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sa.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sb.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sd.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-se.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sh.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-si.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-so.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-st.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-sz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-td.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-th.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tj.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tk.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tl.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-to.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tr.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tt.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tv.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-tz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ua.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ug.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-um.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-us.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-uy.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-uz.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-va.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vc.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ve.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vg.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vi.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vn.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-vu.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-wf.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ws.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-ye.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-za.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-zm.png
+doc/scipy-sphinx-theme/_theme/scipy/static/img/flags/flag-zw.png
+doc/scipy-sphinx-theme/_theme/scipy/static/js/copybutton.js
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-bootstrap.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-content.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-extend.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-footer.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-header.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-rightsidebar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/spc-utils.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/accordion.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/alerts.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/bootstrap.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/breadcrumbs.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/button-groups.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/buttons.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/carousel.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/close.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/code.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/component-animations.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/dropdowns.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/forms.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/grid.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/hero-unit.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/labels-badges.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/layouts.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/media.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/mixins.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/modals.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/navbar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/navs.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/pager.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/pagination.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/popovers.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/progress-bars.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/reset.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-1200px-min.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-767px-max.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-768px-979px.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-navbar.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive-utilities.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/responsive.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/scaffolding.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/sprites.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/tables.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/thumbnails.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/tooltip.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/type.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/utilities.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/variables.less
+doc/scipy-sphinx-theme/_theme/scipy/static/less/bootstrap/wells.less
+doc/source/about.rst
+doc/source/bugs.rst
+doc/source/conf.py
+doc/source/contents.rst
+doc/source/glossary.rst
+doc/source/license.rst
+doc/source/release.rst
+doc/source/_templates/indexcontent.html
+doc/source/_templates/indexsidebar.html
+doc/source/_templates/layout.html
+doc/source/_templates/autosummary/class.rst
+doc/source/dev/development_environment.rst
+doc/source/dev/gitwash_links.txt
+doc/source/dev/index.rst
+doc/source/dev/gitwash/configure_git.rst
+doc/source/dev/gitwash/development_setup.rst
+doc/source/dev/gitwash/development_workflow.rst
+doc/source/dev/gitwash/dot2_dot3.rst
+doc/source/dev/gitwash/following_latest.rst
+doc/source/dev/gitwash/forking_button.png
+doc/source/dev/gitwash/git_development.rst
+doc/source/dev/gitwash/git_intro.rst
+doc/source/dev/gitwash/git_links.inc
+doc/source/dev/gitwash/git_resources.rst
+doc/source/dev/gitwash/index.rst
+doc/source/dev/gitwash/pull_button.png
+doc/source/dev/governance/governance.rst
+doc/source/dev/governance/index.rst
+doc/source/dev/governance/people.rst
+doc/source/f2py/advanced.rst
+doc/source/f2py/allocarr.f90
+doc/source/f2py/allocarr_session.dat
+doc/source/f2py/array.f
+doc/source/f2py/array_session.dat
+doc/source/f2py/calculate.f
+doc/source/f2py/calculate_session.dat
+doc/source/f2py/callback.f
+doc/source/f2py/callback2.pyf
+doc/source/f2py/callback_session.dat
+doc/source/f2py/common.f
+doc/source/f2py/common_session.dat
+doc/source/f2py/compile_session.dat
+doc/source/f2py/distutils.rst
+doc/source/f2py/extcallback.f
+doc/source/f2py/extcallback_session.dat
+doc/source/f2py/fib1.f
+doc/source/f2py/fib1.pyf
+doc/source/f2py/fib2.pyf
+doc/source/f2py/fib3.f
+doc/source/f2py/ftype.f
+doc/source/f2py/ftype_session.dat
+doc/source/f2py/getting-started.rst
+doc/source/f2py/index.rst
+doc/source/f2py/moddata.f90
+doc/source/f2py/moddata_session.dat
+doc/source/f2py/python-usage.rst
+doc/source/f2py/run_main_session.dat
+doc/source/f2py/scalar.f
+doc/source/f2py/scalar_session.dat
+doc/source/f2py/setup_example.py
+doc/source/f2py/signature-file.rst
+doc/source/f2py/spam.pyf
+doc/source/f2py/spam_session.dat
+doc/source/f2py/string.f
+doc/source/f2py/string_session.dat
+doc/source/f2py/usage.rst
+doc/source/f2py/var.pyf
+doc/source/f2py/var_session.dat
+doc/source/neps/datetime-proposal.rst
+doc/source/neps/datetime-proposal3.rst
+doc/source/neps/deferred-ufunc-evaluation.rst
+doc/source/neps/generalized-ufuncs.rst
+doc/source/neps/groupby_additions.rst
+doc/source/neps/index.rst
+doc/source/neps/math_config_clean.rst
+doc/source/neps/missing-data.rst
+doc/source/neps/new-iterator-ufunc.rst
+doc/source/neps/newbugtracker.rst
+doc/source/neps/npy-format.rst
+doc/source/neps/structured_array_extensions.rst
+doc/source/neps/ufunc-overrides.rst
+doc/source/neps/warnfix.rst
+doc/source/reference/arrays.classes.rst
+doc/source/reference/arrays.datetime.rst
+doc/source/reference/arrays.dtypes.rst
+doc/source/reference/arrays.indexing.rst
+doc/source/reference/arrays.interface.rst
+doc/source/reference/arrays.ndarray.rst
+doc/source/reference/arrays.nditer.rst
+doc/source/reference/arrays.rst
+doc/source/reference/arrays.scalars.rst
+doc/source/reference/c-api.array.rst
+doc/source/reference/c-api.config.rst
+doc/source/reference/c-api.coremath.rst
+doc/source/reference/c-api.deprecations.rst
+doc/source/reference/c-api.dtype.rst
+doc/source/reference/c-api.generalized-ufuncs.rst
+doc/source/reference/c-api.iterator.rst
+doc/source/reference/c-api.rst
+doc/source/reference/c-api.types-and-structures.rst
+doc/source/reference/c-api.ufunc.rst
+doc/source/reference/distutils.rst
+doc/source/reference/index.rst
+doc/source/reference/internals.code-explanations.rst
+doc/source/reference/internals.rst
+doc/source/reference/maskedarray.baseclass.rst
+doc/source/reference/maskedarray.generic.rst
+doc/source/reference/maskedarray.rst
+doc/source/reference/routines.array-creation.rst
+doc/source/reference/routines.array-manipulation.rst
+doc/source/reference/routines.bitwise.rst
+doc/source/reference/routines.char.rst
+doc/source/reference/routines.ctypeslib.rst
+doc/source/reference/routines.datetime.rst
+doc/source/reference/routines.dtype.rst
+doc/source/reference/routines.dual.rst
+doc/source/reference/routines.emath.rst
+doc/source/reference/routines.err.rst
+doc/source/reference/routines.fft.rst
+doc/source/reference/routines.financial.rst
+doc/source/reference/routines.functional.rst
+doc/source/reference/routines.help.rst
+doc/source/reference/routines.indexing.rst
+doc/source/reference/routines.io.rst
+doc/source/reference/routines.linalg.rst
+doc/source/reference/routines.logic.rst
+doc/source/reference/routines.ma.rst
+doc/source/reference/routines.math.rst
+doc/source/reference/routines.matlib.rst
+doc/source/reference/routines.numarray.rst
+doc/source/reference/routines.oldnumeric.rst
+doc/source/reference/routines.other.rst
+doc/source/reference/routines.padding.rst
+doc/source/reference/routines.polynomials.chebyshev.rst
+doc/source/reference/routines.polynomials.classes.rst
+doc/source/reference/routines.polynomials.hermite.rst
+doc/source/reference/routines.polynomials.hermite_e.rst
+doc/source/reference/routines.polynomials.laguerre.rst
+doc/source/reference/routines.polynomials.legendre.rst
+doc/source/reference/routines.polynomials.package.rst
+doc/source/reference/routines.polynomials.poly1d.rst
+doc/source/reference/routines.polynomials.polynomial.rst
+doc/source/reference/routines.polynomials.rst
+doc/source/reference/routines.random.rst
+doc/source/reference/routines.rst
+doc/source/reference/routines.set.rst
+doc/source/reference/routines.sort.rst
+doc/source/reference/routines.statistics.rst
+doc/source/reference/routines.testing.rst
+doc/source/reference/routines.window.rst
+doc/source/reference/swig.interface-file.rst
+doc/source/reference/swig.rst
+doc/source/reference/swig.testing.rst
+doc/source/reference/ufuncs.rst
+doc/source/reference/figures/dtype-hierarchy.dia
+doc/source/reference/figures/dtype-hierarchy.pdf
+doc/source/reference/figures/dtype-hierarchy.png
+doc/source/reference/figures/threefundamental.fig
+doc/source/reference/figures/threefundamental.pdf
+doc/source/reference/figures/threefundamental.png
+doc/source/user/basics.broadcasting.rst
+doc/source/user/basics.byteswapping.rst
+doc/source/user/basics.creation.rst
+doc/source/user/basics.indexing.rst
+doc/source/user/basics.io.genfromtxt.rst
+doc/source/user/basics.io.rst
+doc/source/user/basics.rec.rst
+doc/source/user/basics.rst
+doc/source/user/basics.subclassing.rst
+doc/source/user/basics.types.rst
+doc/source/user/building.rst
+doc/source/user/c-info.beyond-basics.rst
+doc/source/user/c-info.how-to-extend.rst
+doc/source/user/c-info.python-as-glue.rst
+doc/source/user/c-info.rst
+doc/source/user/c-info.ufunc-tutorial.rst
+doc/source/user/index.rst
+doc/source/user/install.rst
+doc/source/user/misc.rst
+doc/source/user/numpy-for-matlab-users.rst
+doc/source/user/quickstart.rst
+doc/source/user/setting-up.rst
+doc/source/user/whatisnumpy.rst
+doc/sphinxext/.git
+doc/sphinxext/.gitignore
+doc/sphinxext/.travis.yml
+doc/sphinxext/LICENSE.txt
+doc/sphinxext/MANIFEST.in
+doc/sphinxext/README.rst
+doc/sphinxext/setup.py
+doc/sphinxext/numpydoc/__init__.py
+doc/sphinxext/numpydoc/comment_eater.py
+doc/sphinxext/numpydoc/compiler_unparse.py
+doc/sphinxext/numpydoc/docscrape.py
+doc/sphinxext/numpydoc/docscrape_sphinx.py
+doc/sphinxext/numpydoc/linkcode.py
+doc/sphinxext/numpydoc/numpydoc.py
+doc/sphinxext/numpydoc/phantom_import.py
+doc/sphinxext/numpydoc/plot_directive.py
+doc/sphinxext/numpydoc/traitsdoc.py
+doc/sphinxext/numpydoc/tests/test_docscrape.py
+doc/sphinxext/numpydoc/tests/test_linkcode.py
+doc/sphinxext/numpydoc/tests/test_phantom_import.py
+doc/sphinxext/numpydoc/tests/test_plot_directive.py
+doc/sphinxext/numpydoc/tests/test_traitsdoc.py
+numpy/__init__.py
+numpy/_import_tools.py
+numpy/add_newdocs.py
+numpy/ctypeslib.py
+numpy/dual.py
+numpy/matlib.py
+numpy/setup.py
+numpy/version.py
+numpy.egg-info/PKG-INFO
+numpy.egg-info/SOURCES.txt
+numpy.egg-info/dependency_links.txt
+numpy.egg-info/top_level.txt
+numpy/_build_utils/README
+numpy/_build_utils/__init__.py
+numpy/_build_utils/apple_accelerate.py
+numpy/_build_utils/common.py
+numpy/_build_utils/src/apple_sgemv_fix.c
+numpy/compat/__init__.py
+numpy/compat/_inspect.py
+numpy/compat/py3k.py
+numpy/compat/setup.py
+numpy/core/__init__.py
+numpy/core/_internal.py
+numpy/core/_methods.py
+numpy/core/arrayprint.py
+numpy/core/cversions.py
+numpy/core/defchararray.py
+numpy/core/fromnumeric.py
+numpy/core/function_base.py
+numpy/core/getlimits.py
+numpy/core/info.py
+numpy/core/machar.py
+numpy/core/memmap.py
+numpy/core/mlib.ini.in
+numpy/core/npymath.ini.in
+numpy/core/numeric.py
+numpy/core/numerictypes.py
+numpy/core/records.py
+numpy/core/setup.py
+numpy/core/setup_common.py
+numpy/core/shape_base.py
+numpy/core/code_generators/__init__.py
+numpy/core/code_generators/cversions.txt
+numpy/core/code_generators/genapi.py
+numpy/core/code_generators/generate_numpy_api.py
+numpy/core/code_generators/generate_ufunc_api.py
+numpy/core/code_generators/generate_umath.py
+numpy/core/code_generators/numpy_api.py
+numpy/core/code_generators/ufunc_docstrings.py
+numpy/core/include/numpy/_neighborhood_iterator_imp.h
+numpy/core/include/numpy/_numpyconfig.h.in
+numpy/core/include/numpy/arrayobject.h
+numpy/core/include/numpy/arrayscalars.h
+numpy/core/include/numpy/halffloat.h
+numpy/core/include/numpy/ndarrayobject.h
+numpy/core/include/numpy/ndarraytypes.h
+numpy/core/include/numpy/noprefix.h
+numpy/core/include/numpy/npy_1_7_deprecated_api.h
+numpy/core/include/numpy/npy_3kcompat.h
+numpy/core/include/numpy/npy_common.h
+numpy/core/include/numpy/npy_cpu.h
+numpy/core/include/numpy/npy_endian.h
+numpy/core/include/numpy/npy_interrupt.h
+numpy/core/include/numpy/npy_math.h
+numpy/core/include/numpy/npy_no_deprecated_api.h
+numpy/core/include/numpy/npy_os.h
+numpy/core/include/numpy/numpyconfig.h
+numpy/core/include/numpy/old_defines.h
+numpy/core/include/numpy/oldnumeric.h
+numpy/core/include/numpy/ufuncobject.h
+numpy/core/include/numpy/utils.h
+numpy/core/src/dummymodule.c
+numpy/core/src/multiarray/_datetime.h
+numpy/core/src/multiarray/alloc.c
+numpy/core/src/multiarray/alloc.h
+numpy/core/src/multiarray/array_assign.c
+numpy/core/src/multiarray/array_assign.h
+numpy/core/src/multiarray/array_assign_array.c
+numpy/core/src/multiarray/array_assign_scalar.c
+numpy/core/src/multiarray/arrayobject.c
+numpy/core/src/multiarray/arrayobject.h
+numpy/core/src/multiarray/arraytypes.h
+numpy/core/src/multiarray/buffer.c
+numpy/core/src/multiarray/buffer.h
+numpy/core/src/multiarray/calculation.c
+numpy/core/src/multiarray/calculation.h
+numpy/core/src/multiarray/cblasfuncs.c
+numpy/core/src/multiarray/cblasfuncs.h
+numpy/core/src/multiarray/common.c
+numpy/core/src/multiarray/common.h
+numpy/core/src/multiarray/compiled_base.c
+numpy/core/src/multiarray/compiled_base.h
+numpy/core/src/multiarray/conversion_utils.c
+numpy/core/src/multiarray/conversion_utils.h
+numpy/core/src/multiarray/convert.c
+numpy/core/src/multiarray/convert.h
+numpy/core/src/multiarray/convert_datatype.c
+numpy/core/src/multiarray/convert_datatype.h
+numpy/core/src/multiarray/ctors.c
+numpy/core/src/multiarray/ctors.h
+numpy/core/src/multiarray/datetime.c
+numpy/core/src/multiarray/datetime_busday.c
+numpy/core/src/multiarray/datetime_busday.h
+numpy/core/src/multiarray/datetime_busdaycal.c
+numpy/core/src/multiarray/datetime_busdaycal.h
+numpy/core/src/multiarray/datetime_strings.c
+numpy/core/src/multiarray/datetime_strings.h
+numpy/core/src/multiarray/descriptor.c
+numpy/core/src/multiarray/descriptor.h
+numpy/core/src/multiarray/dtype_transfer.c
+numpy/core/src/multiarray/flagsobject.c
+numpy/core/src/multiarray/getset.c
+numpy/core/src/multiarray/getset.h
+numpy/core/src/multiarray/hashdescr.c
+numpy/core/src/multiarray/hashdescr.h
+numpy/core/src/multiarray/item_selection.c
+numpy/core/src/multiarray/item_selection.h
+numpy/core/src/multiarray/iterators.c
+numpy/core/src/multiarray/iterators.h
+numpy/core/src/multiarray/mapping.c
+numpy/core/src/multiarray/mapping.h
+numpy/core/src/multiarray/methods.c
+numpy/core/src/multiarray/methods.h
+numpy/core/src/multiarray/multiarraymodule.c
+numpy/core/src/multiarray/multiarraymodule.h
+numpy/core/src/multiarray/nditer_api.c
+numpy/core/src/multiarray/nditer_constr.c
+numpy/core/src/multiarray/nditer_impl.h
+numpy/core/src/multiarray/nditer_pywrap.c
+numpy/core/src/multiarray/nditer_pywrap.h
+numpy/core/src/multiarray/number.c
+numpy/core/src/multiarray/number.h
+numpy/core/src/multiarray/numpymemoryview.c
+numpy/core/src/multiarray/numpymemoryview.h
+numpy/core/src/multiarray/numpyos.c
+numpy/core/src/multiarray/numpyos.h
+numpy/core/src/multiarray/python_xerbla.c
+numpy/core/src/multiarray/refcount.c
+numpy/core/src/multiarray/refcount.h
+numpy/core/src/multiarray/scalarapi.c
+numpy/core/src/multiarray/scalartypes.h
+numpy/core/src/multiarray/sequence.c
+numpy/core/src/multiarray/sequence.h
+numpy/core/src/multiarray/shape.c
+numpy/core/src/multiarray/shape.h
+numpy/core/src/multiarray/ucsnarrow.c
+numpy/core/src/multiarray/ucsnarrow.h
+numpy/core/src/multiarray/usertypes.c
+numpy/core/src/multiarray/usertypes.h
+numpy/core/src/multiarray/vdot.c
+numpy/core/src/multiarray/vdot.h
+numpy/core/src/npymath/_signbit.c
+numpy/core/src/npymath/halffloat.c
+numpy/core/src/npymath/ieee754.c.src
+numpy/core/src/npymath/npy_math.c.src
+numpy/core/src/npymath/npy_math_common.h
+numpy/core/src/npymath/npy_math_complex.c.src
+numpy/core/src/npymath/npy_math_private.h
+numpy/core/src/npysort/binsearch.c.src
+numpy/core/src/npysort/heapsort.c.src
+numpy/core/src/npysort/mergesort.c.src
+numpy/core/src/npysort/npysort_common.h
+numpy/core/src/npysort/quicksort.c.src
+numpy/core/src/npysort/selection.c.src
+numpy/core/src/private/lowlevel_strided_loops.h
+numpy/core/src/private/mem_overlap.c
+numpy/core/src/private/mem_overlap.h
+numpy/core/src/private/npy_binsearch.h.src
+numpy/core/src/private/npy_cblas.h
+numpy/core/src/private/npy_config.h
+numpy/core/src/private/npy_extint128.h
+numpy/core/src/private/npy_fpmath.h
+numpy/core/src/private/npy_import.h
+numpy/core/src/private/npy_partition.h.src
+numpy/core/src/private/npy_pycompat.h
+numpy/core/src/private/npy_sort.h
+numpy/core/src/private/templ_common.h.src
+numpy/core/src/private/ufunc_override.h
+numpy/core/src/umath/reduction.c
+numpy/core/src/umath/reduction.h
+numpy/core/src/umath/simd.inc.src
+numpy/core/src/umath/ufunc_object.c
+numpy/core/src/umath/ufunc_object.h
+numpy/core/src/umath/ufunc_type_resolution.c
+numpy/core/src/umath/ufunc_type_resolution.h
+numpy/core/src/umath/umathmodule.c
+numpy/distutils/__init__.py
+numpy/distutils/__version__.py
+numpy/distutils/ccompiler.py
+numpy/distutils/compat.py
+numpy/distutils/conv_template.py
+numpy/distutils/core.py
+numpy/distutils/cpuinfo.py
+numpy/distutils/environment.py
+numpy/distutils/exec_command.py
+numpy/distutils/extension.py
+numpy/distutils/from_template.py
+numpy/distutils/info.py
+numpy/distutils/intelccompiler.py
+numpy/distutils/lib2def.py
+numpy/distutils/line_endings.py
+numpy/distutils/log.py
+numpy/distutils/mingw32ccompiler.py
+numpy/distutils/misc_util.py
+numpy/distutils/msvc9compiler.py
+numpy/distutils/msvccompiler.py
+numpy/distutils/npy_pkg_config.py
+numpy/distutils/numpy_distribution.py
+numpy/distutils/pathccompiler.py
+numpy/distutils/setup.py
+numpy/distutils/system_info.py
+numpy/distutils/unixccompiler.py
+numpy/distutils/command/__init__.py
+numpy/distutils/command/autodist.py
+numpy/distutils/command/bdist_rpm.py
+numpy/distutils/command/build.py
+numpy/distutils/command/build_clib.py
+numpy/distutils/command/build_ext.py
+numpy/distutils/command/build_py.py
+numpy/distutils/command/build_scripts.py
+numpy/distutils/command/build_src.py
+numpy/distutils/command/config.py
+numpy/distutils/command/config_compiler.py
+numpy/distutils/command/develop.py
+numpy/distutils/command/egg_info.py
+numpy/distutils/command/install.py
+numpy/distutils/command/install_clib.py
+numpy/distutils/command/install_data.py
+numpy/distutils/command/install_headers.py
+numpy/distutils/command/sdist.py
+numpy/distutils/fcompiler/__init__.py
+numpy/distutils/fcompiler/absoft.py
+numpy/distutils/fcompiler/compaq.py
+numpy/distutils/fcompiler/g95.py
+numpy/distutils/fcompiler/gnu.py
+numpy/distutils/fcompiler/hpux.py
+numpy/distutils/fcompiler/ibm.py
+numpy/distutils/fcompiler/intel.py
+numpy/distutils/fcompiler/lahey.py
+numpy/distutils/fcompiler/mips.py
+numpy/distutils/fcompiler/nag.py
+numpy/distutils/fcompiler/none.py
+numpy/distutils/fcompiler/pathf95.py
+numpy/distutils/fcompiler/pg.py
+numpy/distutils/fcompiler/sun.py
+numpy/distutils/fcompiler/vast.py
+numpy/doc/__init__.py
+numpy/doc/basics.py
+numpy/doc/broadcasting.py
+numpy/doc/byteswapping.py
+numpy/doc/constants.py
+numpy/doc/creation.py
+numpy/doc/glossary.py
+numpy/doc/indexing.py
+numpy/doc/internals.py
+numpy/doc/misc.py
+numpy/doc/structured_arrays.py
+numpy/doc/subclassing.py
+numpy/doc/ufuncs.py
+numpy/f2py/__init__.py
+numpy/f2py/__main__.py
+numpy/f2py/__version__.py
+numpy/f2py/auxfuncs.py
+numpy/f2py/capi_maps.py
+numpy/f2py/cb_rules.py
+numpy/f2py/cfuncs.py
+numpy/f2py/common_rules.py
+numpy/f2py/crackfortran.py
+numpy/f2py/diagnose.py
+numpy/f2py/f2py2e.py
+numpy/f2py/f2py_testing.py
+numpy/f2py/f90mod_rules.py
+numpy/f2py/func2subr.py
+numpy/f2py/info.py
+numpy/f2py/rules.py
+numpy/f2py/setup.py
+numpy/f2py/use_rules.py
+numpy/fft/__init__.py
+numpy/fft/fftpack.c
+numpy/fft/fftpack.h
+numpy/fft/fftpack.py
+numpy/fft/fftpack_litemodule.c
+numpy/fft/helper.py
+numpy/fft/info.py
+numpy/fft/setup.py
+numpy/lib/__init__.py
+numpy/lib/_datasource.py
+numpy/lib/_iotools.py
+numpy/lib/_version.py
+numpy/lib/arraypad.py
+numpy/lib/arraysetops.py
+numpy/lib/arrayterator.py
+numpy/lib/financial.py
+numpy/lib/format.py
+numpy/lib/function_base.py
+numpy/lib/index_tricks.py
+numpy/lib/info.py
+numpy/lib/nanfunctions.py
+numpy/lib/npyio.py
+numpy/lib/polynomial.py
+numpy/lib/recfunctions.py
+numpy/lib/scimath.py
+numpy/lib/setup.py
+numpy/lib/shape_base.py
+numpy/lib/stride_tricks.py
+numpy/lib/twodim_base.py
+numpy/lib/type_check.py
+numpy/lib/ufunclike.py
+numpy/lib/user_array.py
+numpy/lib/utils.py
+numpy/linalg/__init__.py
+numpy/linalg/info.py
+numpy/linalg/lapack_litemodule.c
+numpy/linalg/linalg.py
+numpy/linalg/setup.py
+numpy/linalg/lapack_lite/blas_lite.c
+numpy/linalg/lapack_lite/dlamch.c
+numpy/linalg/lapack_lite/dlapack_lite.c
+numpy/linalg/lapack_lite/f2c.h
+numpy/linalg/lapack_lite/f2c_lite.c
+numpy/linalg/lapack_lite/python_xerbla.c
+numpy/linalg/lapack_lite/zlapack_lite.c
+numpy/ma/__init__.py
+numpy/ma/bench.py
+numpy/ma/core.py
+numpy/ma/extras.py
+numpy/ma/mrecords.py
+numpy/ma/setup.py
+numpy/ma/testutils.py
+numpy/ma/timer_comparison.py
+numpy/ma/version.py
+numpy/matrixlib/__init__.py
+numpy/matrixlib/defmatrix.py
+numpy/matrixlib/setup.py
+numpy/polynomial/__init__.py
+numpy/polynomial/_polybase.py
+numpy/polynomial/chebyshev.py
+numpy/polynomial/hermite.py
+numpy/polynomial/hermite_e.py
+numpy/polynomial/laguerre.py
+numpy/polynomial/legendre.py
+numpy/polynomial/polynomial.py
+numpy/polynomial/polyutils.py
+numpy/polynomial/setup.py
+numpy/random/__init__.py
+numpy/random/info.py
+numpy/random/setup.py
+numpy/random/mtrand/Python.pxi
+numpy/random/mtrand/distributions.c
+numpy/random/mtrand/distributions.h
+numpy/random/mtrand/generate_mtrand_c.py
+numpy/random/mtrand/initarray.c
+numpy/random/mtrand/initarray.h
+numpy/random/mtrand/mt_compat.h
+numpy/random/mtrand/mtrand.c
+numpy/random/mtrand/mtrand.pyx
+numpy/random/mtrand/mtrand_py_helper.h
+numpy/random/mtrand/numpy.pxd
+numpy/random/mtrand/randomkit.c
+numpy/random/mtrand/randomkit.h
+numpy/testing/__init__.py
+numpy/testing/decorators.py
+numpy/testing/noseclasses.py
+numpy/testing/nosetester.py
+numpy/testing/print_coercion_tables.py
+numpy/testing/setup.py
+numpy/testing/utils.py
+tools/swig/Makefile
+tools/swig/README
+tools/swig/numpy.i
+tools/swig/pyfragments.swg
+tools/swig/test/Array.i
+tools/swig/test/Array1.cxx
+tools/swig/test/Array1.h
+tools/swig/test/Array2.cxx
+tools/swig/test/Array2.h
+tools/swig/test/ArrayZ.cxx
+tools/swig/test/ArrayZ.h
+tools/swig/test/Farray.cxx
+tools/swig/test/Farray.h
+tools/swig/test/Farray.i
+tools/swig/test/Flat.cxx
+tools/swig/test/Flat.h
+tools/swig/test/Flat.i
+tools/swig/test/Fortran.cxx
+tools/swig/test/Fortran.h
+tools/swig/test/Fortran.i
+tools/swig/test/Makefile
+tools/swig/test/Matrix.cxx
+tools/swig/test/Matrix.h
+tools/swig/test/Matrix.i
+tools/swig/test/SuperTensor.cxx
+tools/swig/test/SuperTensor.h
+tools/swig/test/SuperTensor.i
+tools/swig/test/Tensor.cxx
+tools/swig/test/Tensor.h
+tools/swig/test/Tensor.i
+tools/swig/test/Vector.cxx
+tools/swig/test/Vector.h
+tools/swig/test/Vector.i
+tools/swig/test/setup.py
+tools/swig/test/testArray.py
+tools/swig/test/testFarray.py
+tools/swig/test/testFlat.py
+tools/swig/test/testFortran.py
+tools/swig/test/testMatrix.py
+tools/swig/test/testSuperTensor.py
+tools/swig/test/testTensor.py
+tools/swig/test/testVector.py
\ No newline at end of file
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
new file mode 100644
index 0000000000..24ce15ab7e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
@@ -0,0 +1 @@
+numpy
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__config__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__config__.py
new file mode 100644
index 0000000000..2c2719980e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__config__.py
@@ -0,0 +1,26 @@
+# This file is generated by C:/repo/mingw-w64-python-numpy/src/numpy-py2-x86_64/setup.py
+# It contains system_info results at the time of building this package.
+__all__ = ["get_info","show"]
+
+lapack_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+openblas_lapack_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_mkl_info={}
+openblas_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    
\ No newline at end of file
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__init__.py
new file mode 100644
index 0000000000..0fcd5097d2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/__init__.py
@@ -0,0 +1,229 @@
+"""
+NumPy
+=====
+
+Provides
+  1. An array object of arbitrary homogeneous items
+  2. Fast mathematical operations over arrays
+  3. Linear Algebra, Fourier Transforms, Random Number Generation
+
+How to use the documentation
+----------------------------
+Documentation is available in two forms: docstrings provided
+with the code, and a loose standing reference guide, available from
+`the NumPy homepage <http://www.scipy.org>`_.
+
+We recommend exploring the docstrings using
+`IPython <http://ipython.scipy.org>`_, an advanced Python shell with
+TAB-completion and introspection capabilities.  See below for further
+instructions.
+
+The docstring examples assume that `numpy` has been imported as `np`::
+
+  >>> import numpy as np
+
+Code snippets are indicated by three greater-than signs::
+
+  >>> x = 42
+  >>> x = x + 1
+
+Use the built-in ``help`` function to view a function's docstring::
+
+  >>> help(np.sort)
+  ... # doctest: +SKIP
+
+For some objects, ``np.info(obj)`` may provide additional help.  This is
+particularly true if you see the line "Help on ufunc object:" at the top
+of the help() page.  Ufuncs are implemented in C, not Python, for speed.
+The native Python help() does not know how to view their help, but our
+np.info() function does.
+
+To search for documents containing a keyword, do::
+
+  >>> np.lookfor('keyword')
+  ... # doctest: +SKIP
+
+General-purpose documents like a glossary and help on the basic concepts
+of numpy are available under the ``doc`` sub-module::
+
+  >>> from numpy import doc
+  >>> help(doc)
+  ... # doctest: +SKIP
+
+Available subpackages
+---------------------
+doc
+    Topical documentation on broadcasting, indexing, etc.
+lib
+    Basic functions used by several sub-packages.
+random
+    Core Random Tools
+linalg
+    Core Linear Algebra Tools
+fft
+    Core FFT routines
+polynomial
+    Polynomial tools
+testing
+    Numpy testing tools
+f2py
+    Fortran to Python Interface Generator.
+distutils
+    Enhancements to distutils with support for
+    Fortran compilers support and more.
+
+Utilities
+---------
+test
+    Run numpy unittests
+show_config
+    Show numpy build configuration
+dual
+    Overwrite certain functions with high-performance Scipy tools
+matlib
+    Make everything matrices.
+__version__
+    Numpy version string
+
+Viewing documentation using IPython
+-----------------------------------
+Start IPython with the NumPy profile (``ipython -p numpy``), which will
+import `numpy` under the alias `np`.  Then, use the ``cpaste`` command to
+paste examples into the shell.  To see which functions are available in
+`numpy`, type ``np.<TAB>`` (where ``<TAB>`` refers to the TAB key), or use
+``np.*cos*?<ENTER>`` (where ``<ENTER>`` refers to the ENTER key) to narrow
+down the list.  To view the docstring for a function, use
+``np.cos?<ENTER>`` (to view the docstring) and ``np.cos??<ENTER>`` (to view
+the source code).
+
+Copies vs. in-place operation
+-----------------------------
+Most of the functions in `numpy` return a copy of the array argument
+(e.g., `np.sort`).  In-place versions of these functions are often
+available as array methods, i.e. ``x = np.array([1,2,3]); x.sort()``.
+Exceptions to this rule are documented.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+
+class ModuleDeprecationWarning(DeprecationWarning):
+    """Module deprecation warning.
+
+    The nose tester turns ordinary Deprecation warnings into test failures.
+    That makes it hard to deprecate whole modules, because they get
+    imported by default. So this is a special Deprecation warning that the
+    nose tester will let pass without making tests fail.
+
+    """
+    pass
+
+
+class VisibleDeprecationWarning(UserWarning):
+    """Visible deprecation warning.
+
+    By default, python will not show deprecation warnings, so this class
+    can be used when a very visible warning is helpful, for example because
+    the usage is most likely a user bug.
+
+    """
+    pass
+
+
+class _NoValue:
+    """Special keyword value.
+
+    This class may be used as the default value assigned to a
+    deprecated keyword in order to check if it has been given a user
+    defined value.
+    """
+    pass
+
+
+# oldnumeric and numarray were removed in 1.9. In case some packages import
+# but do not use them, we define them here for backward compatibility.
+oldnumeric = 'removed'
+numarray = 'removed'
+
+
+# We first need to detect if we're being called as part of the numpy setup
+# procedure itself in a reliable manner.
+try:
+    __NUMPY_SETUP__
+except NameError:
+    __NUMPY_SETUP__ = False
+
+
+if __NUMPY_SETUP__:
+    import sys as _sys
+    _sys.stderr.write('Running from numpy source directory.\n')
+    del _sys
+else:
+    try:
+        from numpy.__config__ import show as show_config
+    except ImportError:
+        msg = """Error importing numpy: you should not try to import numpy from
+        its source directory; please exit the numpy source tree, and relaunch
+        your python interpreter from there."""
+        raise ImportError(msg)
+    from .version import git_revision as __git_revision__
+    from .version import version as __version__
+
+    from ._import_tools import PackageLoader
+
+    def pkgload(*packages, **options):
+        loader = PackageLoader(infunc=True)
+        return loader(*packages, **options)
+
+    from . import add_newdocs
+    __all__ = ['add_newdocs',
+               'ModuleDeprecationWarning',
+               'VisibleDeprecationWarning']
+
+    pkgload.__doc__ = PackageLoader.__call__.__doc__
+
+    # We don't actually use this ourselves anymore, but I'm not 100% sure that
+    # no-one else in the world is using it (though I hope not)
+    from .testing import Tester
+    test = testing.nosetester._numpy_tester().test
+    bench = testing.nosetester._numpy_tester().bench
+
+    from . import core
+    from .core import *
+    from . import compat
+    from . import lib
+    from .lib import *
+    from . import linalg
+    from . import fft
+    from . import polynomial
+    from . import random
+    from . import ctypeslib
+    from . import ma
+    from . import matrixlib as _mat
+    from .matrixlib import *
+    from .compat import long
+
+    # Make these accessible from numpy name-space
+    #  but not imported in from numpy import *
+    if sys.version_info[0] >= 3:
+        from builtins import bool, int, float, complex, object, str
+        unicode = str
+    else:
+        from __builtin__ import bool, int, float, complex, object, unicode, str
+
+    from .core import round, abs, max, min
+
+    __all__.extend(['__version__', 'pkgload', 'PackageLoader',
+               'show_config'])
+    __all__.extend(core.__all__)
+    __all__.extend(_mat.__all__)
+    __all__.extend(lib.__all__)
+    __all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma'])
+
+    # Filter annoying Cython warnings that serve no good purpose.
+    import warnings
+    warnings.filterwarnings("ignore", message="numpy.dtype size changed")
+    warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
+    warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/_import_tools.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/_import_tools.py
new file mode 100644
index 0000000000..0d11d699cf
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/_import_tools.py
@@ -0,0 +1,353 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import warnings
+
+__all__ = ['PackageLoader']
+
+class PackageLoader(object):
+    def __init__(self, verbose=False, infunc=False):
+        """ Manages loading packages.
+        """
+
+        if infunc:
+            _level = 2
+        else:
+            _level = 1
+        self.parent_frame = frame = sys._getframe(_level)
+        self.parent_name = eval('__name__', frame.f_globals, frame.f_locals)
+        parent_path = eval('__path__', frame.f_globals, frame.f_locals)
+        if isinstance(parent_path, str):
+            parent_path = [parent_path]
+        self.parent_path = parent_path
+        if '__all__' not in frame.f_locals:
+            exec('__all__ = []', frame.f_globals, frame.f_locals)
+        self.parent_export_names = eval('__all__', frame.f_globals, frame.f_locals)
+
+        self.info_modules = {}
+        self.imported_packages = []
+        self.verbose = None
+
+    def _get_info_files(self, package_dir, parent_path, parent_package=None):
+        """ Return list of (package name,info.py file) from parent_path subdirectories.
+        """
+        from glob import glob
+        files = glob(os.path.join(parent_path, package_dir, 'info.py'))
+        for info_file in glob(os.path.join(parent_path, package_dir, 'info.pyc')):
+            if info_file[:-1] not in files:
+                files.append(info_file)
+        info_files = []
+        for info_file in files:
+            package_name = os.path.dirname(info_file[len(parent_path)+1:])\
+                           .replace(os.sep, '.')
+            if parent_package:
+                package_name = parent_package + '.' + package_name
+            info_files.append((package_name, info_file))
+            info_files.extend(self._get_info_files('*',
+                                                   os.path.dirname(info_file),
+                                                   package_name))
+        return info_files
+
+    def _init_info_modules(self, packages=None):
+        """Initialize info_modules = {<package_name>: <package info.py module>}.
+        """
+        import imp
+        info_files = []
+        info_modules = self.info_modules
+
+        if packages is None:
+            for path in self.parent_path:
+                info_files.extend(self._get_info_files('*', path))
+        else:
+            for package_name in packages:
+                package_dir = os.path.join(*package_name.split('.'))
+                for path in self.parent_path:
+                    names_files = self._get_info_files(package_dir, path)
+                    if names_files:
+                        info_files.extend(names_files)
+                        break
+                else:
+                    try:
+                        exec('import %s.info as info' % (package_name))
+                        info_modules[package_name] = info
+                    except ImportError as msg:
+                        self.warn('No scipy-style subpackage %r found in %s. '\
+                                  'Ignoring: %s'\
+                                  % (package_name, ':'.join(self.parent_path), msg))
+
+        for package_name, info_file in info_files:
+            if package_name in info_modules:
+                continue
+            fullname = self.parent_name +'.'+ package_name
+            if info_file[-1]=='c':
+                filedescriptor = ('.pyc', 'rb', 2)
+            else:
+                filedescriptor = ('.py', 'U', 1)
+
+            try:
+                info_module = imp.load_module(fullname+'.info',
+                                              open(info_file, filedescriptor[1]),
+                                              info_file,
+                                              filedescriptor)
+            except Exception as msg:
+                self.error(msg)
+                info_module = None
+
+            if info_module is None or getattr(info_module, 'ignore', False):
+                info_modules.pop(package_name, None)
+            else:
+                self._init_info_modules(getattr(info_module, 'depends', []))
+                info_modules[package_name] = info_module
+
+        return
+
+    def _get_sorted_names(self):
+        """ Return package names sorted in the order as they should be
+        imported due to dependence relations between packages.
+        """
+
+        depend_dict = {}
+        for name, info_module in self.info_modules.items():
+            depend_dict[name] = getattr(info_module, 'depends', [])
+        package_names = []
+
+        for name in list(depend_dict.keys()):
+            if not depend_dict[name]:
+                package_names.append(name)
+                del depend_dict[name]
+
+        while depend_dict:
+            for name, lst in list(depend_dict.items()):
+                new_lst = [n for n in lst if n in depend_dict]
+                if not new_lst:
+                    package_names.append(name)
+                    del depend_dict[name]
+                else:
+                    depend_dict[name] = new_lst
+
+        return package_names
+
+    def __call__(self,*packages, **options):
+        """Load one or more packages into parent package top-level namespace.
+
+       This function is intended to shorten the need to import many
+       subpackages, say of scipy, constantly with statements such as
+
+         import scipy.linalg, scipy.fftpack, scipy.etc...
+
+       Instead, you can say:
+
+         import scipy
+         scipy.pkgload('linalg','fftpack',...)
+
+       or
+
+         scipy.pkgload()
+
+       to load all of them in one call.
+
+       If a name which doesn't exist in scipy's namespace is
+       given, a warning is shown.
+
+       Parameters
+       ----------
+        *packages : arg-tuple
+             the names (one or more strings) of all the modules one
+             wishes to load into the top-level namespace.
+        verbose= : integer
+             verbosity level [default: -1].
+             verbose=-1 will suspend also warnings.
+        force= : bool
+             when True, force reloading loaded packages [default: False].
+        postpone= : bool
+             when True, don't load packages [default: False]
+
+        """
+        # 2014-10-29, 1.10
+        warnings.warn('pkgload and PackageLoader are obsolete '
+                'and will be removed in a future version of numpy',
+                DeprecationWarning)
+        frame = self.parent_frame
+        self.info_modules = {}
+        if options.get('force', False):
+            self.imported_packages = []
+        self.verbose = verbose = options.get('verbose', -1)
+        postpone = options.get('postpone', None)
+        self._init_info_modules(packages or None)
+
+        self.log('Imports to %r namespace\n----------------------------'\
+                 % self.parent_name)
+
+        for package_name in self._get_sorted_names():
+            if package_name in self.imported_packages:
+                continue
+            info_module = self.info_modules[package_name]
+            global_symbols = getattr(info_module, 'global_symbols', [])
+            postpone_import = getattr(info_module, 'postpone_import', False)
+            if (postpone and not global_symbols) \
+                   or (postpone_import and postpone is not None):
+                continue
+
+            old_object = frame.f_locals.get(package_name, None)
+
+            cmdstr = 'import '+package_name
+            if self._execcmd(cmdstr):
+                continue
+            self.imported_packages.append(package_name)
+
+            if verbose!=-1:
+                new_object = frame.f_locals.get(package_name)
+                if old_object is not None and old_object is not new_object:
+                    self.warn('Overwriting %s=%s (was %s)' \
+                              % (package_name, self._obj2repr(new_object),
+                                 self._obj2repr(old_object)))
+
+            if '.' not in package_name:
+                self.parent_export_names.append(package_name)
+
+            for symbol in global_symbols:
+                if symbol=='*':
+                    symbols = eval('getattr(%s,"__all__",None)'\
+                                   % (package_name),
+                                   frame.f_globals, frame.f_locals)
+                    if symbols is None:
+                        symbols = eval('dir(%s)' % (package_name),
+                                       frame.f_globals, frame.f_locals)
+                        symbols = [s for s in symbols if not s.startswith('_')]
+                else:
+                    symbols = [symbol]
+
+                if verbose!=-1:
+                    old_objects = {}
+                    for s in symbols:
+                        if s in frame.f_locals:
+                            old_objects[s] = frame.f_locals[s]
+
+                cmdstr = 'from '+package_name+' import '+symbol
+                if self._execcmd(cmdstr):
+                    continue
+
+                if verbose!=-1:
+                    for s, old_object in old_objects.items():
+                        new_object = frame.f_locals[s]
+                        if new_object is not old_object:
+                            self.warn('Overwriting %s=%s (was %s)' \
+                                      % (s, self._obj2repr(new_object),
+                                         self._obj2repr(old_object)))
+
+                if symbol=='*':
+                    self.parent_export_names.extend(symbols)
+                else:
+                    self.parent_export_names.append(symbol)
+
+        return
+
+    def _execcmd(self, cmdstr):
+        """ Execute command in parent_frame."""
+        frame = self.parent_frame
+        try:
+            exec (cmdstr, frame.f_globals, frame.f_locals)
+        except Exception as msg:
+            self.error('%s -> failed: %s' % (cmdstr, msg))
+            return True
+        else:
+            self.log('%s -> success' % (cmdstr))
+        return
+
+    def _obj2repr(self, obj):
+        """ Return repr(obj) with"""
+        module = getattr(obj, '__module__', None)
+        file = getattr(obj, '__file__', None)
+        if module is not None:
+            return repr(obj) + ' from ' + module
+        if file is not None:
+            return repr(obj) + ' from ' + file
+        return repr(obj)
+
+    def log(self, mess):
+        if self.verbose>1:
+            print(str(mess), file=sys.stderr)
+    def warn(self, mess):
+        if self.verbose>=0:
+            print(str(mess), file=sys.stderr)
+    def error(self, mess):
+        if self.verbose!=-1:
+            print(str(mess), file=sys.stderr)
+
+    def _get_doc_title(self, info_module):
+        """ Get the title from a package info.py file.
+        """
+        title = getattr(info_module, '__doc_title__', None)
+        if title is not None:
+            return title
+        title = getattr(info_module, '__doc__', None)
+        if title is not None:
+            title = title.lstrip().split('\n', 1)[0]
+            return title
+        return '* Not Available *'
+
+    def _format_titles(self,titles,colsep='---'):
+        display_window_width = 70 # How to determine the correct value in runtime??
+        lengths = [len(name)-name.find('.')-1 for (name, title) in titles]+[0]
+        max_length = max(lengths)
+        lines = []
+        for (name, title) in titles:
+            name = name[name.find('.')+1:]
+            w = max_length - len(name)
+            words = title.split()
+            line = '%s%s %s' % (name, w*' ', colsep)
+            tab = len(line) * ' '
+            while words:
+                word = words.pop(0)
+                if len(line)+len(word)>display_window_width:
+                    lines.append(line)
+                    line = tab
+                line += ' ' + word
+            else:
+                lines.append(line)
+        return '\n'.join(lines)
+
+    def get_pkgdocs(self):
+        """ Return documentation summary of subpackages.
+        """
+        import sys
+        self.info_modules = {}
+        self._init_info_modules(None)
+
+        titles = []
+        symbols = []
+        for package_name, info_module in self.info_modules.items():
+            global_symbols = getattr(info_module, 'global_symbols', [])
+            fullname = self.parent_name +'.'+ package_name
+            note = ''
+            if fullname not in sys.modules:
+                note = ' [*]'
+            titles.append((fullname, self._get_doc_title(info_module) + note))
+            if global_symbols:
+                symbols.append((package_name, ', '.join(global_symbols)))
+
+        retstr = self._format_titles(titles) +\
+               '\n  [*] - using a package requires explicit import (see pkgload)'
+
+
+        if symbols:
+            retstr += """\n\nGlobal symbols from subpackages"""\
+                      """\n-------------------------------\n""" +\
+                      self._format_titles(symbols, '-->')
+
+        return retstr
+
+class PackageLoaderDebug(PackageLoader):
+    def _execcmd(self, cmdstr):
+        """ Execute command in parent_frame."""
+        frame = self.parent_frame
+        print('Executing', repr(cmdstr), '...', end=' ')
+        sys.stdout.flush()
+        exec (cmdstr, frame.f_globals, frame.f_locals)
+        print('ok')
+        sys.stdout.flush()
+        return
+
+if int(os.environ.get('NUMPY_IMPORT_DEBUG', '0')):
+    PackageLoader = PackageLoaderDebug
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/add_newdocs.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/add_newdocs.py
new file mode 100644
index 0000000000..8940f537d5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/add_newdocs.py
@@ -0,0 +1,7671 @@
+"""
+This is only meant to add docs to objects defined in C-extension modules.
+The purpose is to allow easier editing of the docstrings without
+requiring a re-compile.
+
+NOTE: Many of the methods of ndarray have corresponding functions.
+      If you update these docstrings, please keep also the ones in
+      core/fromnumeric.py, core/defmatrix.py up-to-date.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.lib import add_newdoc
+
+###############################################################################
+#
+# flatiter
+#
+# flatiter needs a toplevel description
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'flatiter',
+    """
+    Flat iterator object to iterate over arrays.
+
+    A `flatiter` iterator is returned by ``x.flat`` for any array `x`.
+    It allows iterating over the array as if it were a 1-D array,
+    either in a for-loop or by calling its `next` method.
+
+    Iteration is done in row-major, C-style order (the last
+    index varying the fastest). The iterator can also be indexed using
+    basic slicing or advanced indexing.
+
+    See Also
+    --------
+    ndarray.flat : Return a flat iterator over an array.
+    ndarray.flatten : Returns a flattened copy of an array.
+
+    Notes
+    -----
+    A `flatiter` iterator can not be constructed directly from Python code
+    by calling the `flatiter` constructor.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> type(fl)
+    <type 'numpy.flatiter'>
+    >>> for item in fl:
+    ...     print(item)
+    ...
+    0
+    1
+    2
+    3
+    4
+    5
+
+    >>> fl[2:4]
+    array([2, 3])
+
+    """)
+
+# flatiter attributes
+
+add_newdoc('numpy.core', 'flatiter', ('base',
+    """
+    A reference to the array that is iterated over.
+
+    Examples
+    --------
+    >>> x = np.arange(5)
+    >>> fl = x.flat
+    >>> fl.base is x
+    True
+
+    """))
+
+
+
+add_newdoc('numpy.core', 'flatiter', ('coords',
+    """
+    An N-dimensional tuple of current coordinates.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> fl.coords
+    (0, 0)
+    >>> fl.next()
+    0
+    >>> fl.coords
+    (0, 1)
+
+    """))
+
+
+
+add_newdoc('numpy.core', 'flatiter', ('index',
+    """
+    Current flat index into the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> fl = x.flat
+    >>> fl.index
+    0
+    >>> fl.next()
+    0
+    >>> fl.index
+    1
+
+    """))
+
+# flatiter functions
+
+add_newdoc('numpy.core', 'flatiter', ('__array__',
+    """__array__(type=None) Get array from iterator
+
+    """))
+
+
+add_newdoc('numpy.core', 'flatiter', ('copy',
+    """
+    copy()
+
+    Get a copy of the iterator as a 1-D array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> fl = x.flat
+    >>> fl.copy()
+    array([0, 1, 2, 3, 4, 5])
+
+    """))
+
+
+###############################################################################
+#
+# nditer
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'nditer',
+    """
+    Efficient multi-dimensional iterator object to iterate over arrays.
+    To get started using this object, see the
+    :ref:`introductory guide to array iteration <arrays.nditer>`.
+
+    Parameters
+    ----------
+    op : ndarray or sequence of array_like
+        The array(s) to iterate over.
+    flags : sequence of str, optional
+        Flags to control the behavior of the iterator.
+
+          * "buffered" enables buffering when required.
+          * "c_index" causes a C-order index to be tracked.
+          * "f_index" causes a Fortran-order index to be tracked.
+          * "multi_index" causes a multi-index, or a tuple of indices
+            with one per iteration dimension, to be tracked.
+          * "common_dtype" causes all the operands to be converted to
+            a common data type, with copying or buffering as necessary.
+          * "delay_bufalloc" delays allocation of the buffers until
+            a reset() call is made. Allows "allocate" operands to
+            be initialized before their values are copied into the buffers.
+          * "external_loop" causes the `values` given to be
+            one-dimensional arrays with multiple values instead of
+            zero-dimensional arrays.
+          * "grow_inner" allows the `value` array sizes to be made
+            larger than the buffer size when both "buffered" and
+            "external_loop" is used.
+          * "ranged" allows the iterator to be restricted to a sub-range
+            of the iterindex values.
+          * "refs_ok" enables iteration of reference types, such as
+            object arrays.
+          * "reduce_ok" enables iteration of "readwrite" operands
+            which are broadcasted, also known as reduction operands.
+          * "zerosize_ok" allows `itersize` to be zero.
+    op_flags : list of list of str, optional
+        This is a list of flags for each operand. At minimum, one of
+        "readonly", "readwrite", or "writeonly" must be specified.
+
+          * "readonly" indicates the operand will only be read from.
+          * "readwrite" indicates the operand will be read from and written to.
+          * "writeonly" indicates the operand will only be written to.
+          * "no_broadcast" prevents the operand from being broadcasted.
+          * "contig" forces the operand data to be contiguous.
+          * "aligned" forces the operand data to be aligned.
+          * "nbo" forces the operand data to be in native byte order.
+          * "copy" allows a temporary read-only copy if required.
+          * "updateifcopy" allows a temporary read-write copy if required.
+          * "allocate" causes the array to be allocated if it is None
+            in the `op` parameter.
+          * "no_subtype" prevents an "allocate" operand from using a subtype.
+          * "arraymask" indicates that this operand is the mask to use
+            for selecting elements when writing to operands with the
+            'writemasked' flag set. The iterator does not enforce this,
+            but when writing from a buffer back to the array, it only
+            copies those elements indicated by this mask.
+          * 'writemasked' indicates that only elements where the chosen
+            'arraymask' operand is True will be written to.
+    op_dtypes : dtype or tuple of dtype(s), optional
+        The required data type(s) of the operands. If copying or buffering
+        is enabled, the data will be converted to/from their original types.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the iteration order. 'C' means C order, 'F' means
+        Fortran order, 'A' means 'F' order if all the arrays are Fortran
+        contiguous, 'C' order otherwise, and 'K' means as close to the
+        order the array elements appear in memory as possible. This also
+        affects the element memory order of "allocate" operands, as they
+        are allocated to be compatible with iteration order.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur when making a copy
+        or buffering.  Setting this to 'unsafe' is not recommended,
+        as it can adversely affect accumulations.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    op_axes : list of list of ints, optional
+        If provided, is a list of ints or None for each operands.
+        The list of axes for an operand is a mapping from the dimensions
+        of the iterator to the dimensions of the operand. A value of
+        -1 can be placed for entries, causing that dimension to be
+        treated as "newaxis".
+    itershape : tuple of ints, optional
+        The desired shape of the iterator. This allows "allocate" operands
+        with a dimension mapped by op_axes not corresponding to a dimension
+        of a different operand to get a value not equal to 1 for that
+        dimension.
+    buffersize : int, optional
+        When buffering is enabled, controls the size of the temporary
+        buffers. Set to 0 for the default value.
+
+    Attributes
+    ----------
+    dtypes : tuple of dtype(s)
+        The data types of the values provided in `value`. This may be
+        different from the operand data types if buffering is enabled.
+    finished : bool
+        Whether the iteration over the operands is finished or not.
+    has_delayed_bufalloc : bool
+        If True, the iterator was created with the "delay_bufalloc" flag,
+        and no reset() function was called on it yet.
+    has_index : bool
+        If True, the iterator was created with either the "c_index" or
+        the "f_index" flag, and the property `index` can be used to
+        retrieve it.
+    has_multi_index : bool
+        If True, the iterator was created with the "multi_index" flag,
+        and the property `multi_index` can be used to retrieve it.
+    index :
+        When the "c_index" or "f_index" flag was used, this property
+        provides access to the index. Raises a ValueError if accessed
+        and `has_index` is False.
+    iterationneedsapi : bool
+        Whether iteration requires access to the Python API, for example
+        if one of the operands is an object array.
+    iterindex : int
+        An index which matches the order of iteration.
+    itersize : int
+        Size of the iterator.
+    itviews :
+        Structured view(s) of `operands` in memory, matching the reordered
+        and optimized iterator access pattern.
+    multi_index :
+        When the "multi_index" flag was used, this property
+        provides access to the index. Raises a ValueError if accessed
+        accessed and `has_multi_index` is False.
+    ndim : int
+        The iterator's dimension.
+    nop : int
+        The number of iterator operands.
+    operands : tuple of operand(s)
+        The array(s) to be iterated over.
+    shape : tuple of ints
+        Shape tuple, the shape of the iterator.
+    value :
+        Value of `operands` at current iteration. Normally, this is a
+        tuple of array scalars, but if the flag "external_loop" is used,
+        it is a tuple of one dimensional arrays.
+
+    Notes
+    -----
+    `nditer` supersedes `flatiter`.  The iterator implementation behind
+    `nditer` is also exposed by the Numpy C API.
+
+    The Python exposure supplies two iteration interfaces, one which follows
+    the Python iterator protocol, and another which mirrors the C-style
+    do-while pattern.  The native Python approach is better in most cases, but
+    if you need the iterator's coordinates or index, use the C-style pattern.
+
+    Examples
+    --------
+    Here is how we might write an ``iter_add`` function, using the
+    Python iterator protocol::
+
+        def iter_add_py(x, y, out=None):
+            addop = np.add
+            it = np.nditer([x, y, out], [],
+                        [['readonly'], ['readonly'], ['writeonly','allocate']])
+            for (a, b, c) in it:
+                addop(a, b, out=c)
+            return it.operands[2]
+
+    Here is the same function, but following the C-style pattern::
+
+        def iter_add(x, y, out=None):
+            addop = np.add
+
+            it = np.nditer([x, y, out], [],
+                        [['readonly'], ['readonly'], ['writeonly','allocate']])
+
+            while not it.finished:
+                addop(it[0], it[1], out=it[2])
+                it.iternext()
+
+            return it.operands[2]
+
+    Here is an example outer product function::
+
+        def outer_it(x, y, out=None):
+            mulop = np.multiply
+
+            it = np.nditer([x, y, out], ['external_loop'],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']],
+                    op_axes=[range(x.ndim)+[-1]*y.ndim,
+                             [-1]*x.ndim+range(y.ndim),
+                             None])
+
+            for (a, b, c) in it:
+                mulop(a, b, out=c)
+
+            return it.operands[2]
+
+        >>> a = np.arange(2)+1
+        >>> b = np.arange(3)+1
+        >>> outer_it(a,b)
+        array([[1, 2, 3],
+               [2, 4, 6]])
+
+    Here is an example function which operates like a "lambda" ufunc::
+
+        def luf(lamdaexpr, *args, **kwargs):
+            "luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)"
+            nargs = len(args)
+            op = (kwargs.get('out',None),) + args
+            it = np.nditer(op, ['buffered','external_loop'],
+                    [['writeonly','allocate','no_broadcast']] +
+                                    [['readonly','nbo','aligned']]*nargs,
+                    order=kwargs.get('order','K'),
+                    casting=kwargs.get('casting','safe'),
+                    buffersize=kwargs.get('buffersize',0))
+            while not it.finished:
+                it[0] = lamdaexpr(*it[1:])
+                it.iternext()
+            return it.operands[0]
+
+        >>> a = np.arange(5)
+        >>> b = np.ones(5)
+        >>> luf(lambda i,j:i*i + j/2, a, b)
+        array([  0.5,   1.5,   4.5,   9.5,  16.5])
+
+    """)
+
+# nditer methods
+
+add_newdoc('numpy.core', 'nditer', ('copy',
+    """
+    copy()
+
+    Get a copy of the iterator in its current state.
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> y = x + 1
+    >>> it = np.nditer([x, y])
+    >>> it.next()
+    (array(0), array(1))
+    >>> it2 = it.copy()
+    >>> it2.next()
+    (array(1), array(2))
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('debug_print',
+    """
+    debug_print()
+
+    Print the current state of the `nditer` instance and debug info to stdout.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('enable_external_loop',
+    """
+    enable_external_loop()
+
+    When the "external_loop" was not used during construction, but
+    is desired, this modifies the iterator to behave as if the flag
+    was specified.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('iternext',
+    """
+    iternext()
+
+    Check whether iterations are left, and perform a single internal iteration
+    without returning the result.  Used in the C-style pattern do-while
+    pattern.  For an example, see `nditer`.
+
+    Returns
+    -------
+    iternext : bool
+        Whether or not there are iterations left.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('remove_axis',
+    """
+    remove_axis(i)
+
+    Removes axis `i` from the iterator. Requires that the flag "multi_index"
+    be enabled.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('remove_multi_index',
+    """
+    remove_multi_index()
+
+    When the "multi_index" flag was specified, this removes it, allowing
+    the internal iteration structure to be optimized further.
+
+    """))
+
+add_newdoc('numpy.core', 'nditer', ('reset',
+    """
+    reset()
+
+    Reset the iterator to its initial state.
+
+    """))
+
+
+
+###############################################################################
+#
+# broadcast
+#
+###############################################################################
+
+add_newdoc('numpy.core', 'broadcast',
+    """
+    Produce an object that mimics broadcasting.
+
+    Parameters
+    ----------
+    in1, in2, ... : array_like
+        Input parameters.
+
+    Returns
+    -------
+    b : broadcast object
+        Broadcast the input parameters against one another, and
+        return an object that encapsulates the result.
+        Amongst others, it has ``shape`` and ``nd`` properties, and
+        may be used as an iterator.
+
+    Examples
+    --------
+    Manually adding two vectors, using broadcasting:
+
+    >>> x = np.array([[1], [2], [3]])
+    >>> y = np.array([4, 5, 6])
+    >>> b = np.broadcast(x, y)
+
+    >>> out = np.empty(b.shape)
+    >>> out.flat = [u+v for (u,v) in b]
+    >>> out
+    array([[ 5.,  6.,  7.],
+           [ 6.,  7.,  8.],
+           [ 7.,  8.,  9.]])
+
+    Compare against built-in broadcasting:
+
+    >>> x + y
+    array([[5, 6, 7],
+           [6, 7, 8],
+           [7, 8, 9]])
+
+    """)
+
+# attributes
+
+add_newdoc('numpy.core', 'broadcast', ('index',
+    """
+    current index in broadcasted result
+
+    Examples
+    --------
+    >>> x = np.array([[1], [2], [3]])
+    >>> y = np.array([4, 5, 6])
+    >>> b = np.broadcast(x, y)
+    >>> b.index
+    0
+    >>> b.next(), b.next(), b.next()
+    ((1, 4), (1, 5), (1, 6))
+    >>> b.index
+    3
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('iters',
+    """
+    tuple of iterators along ``self``'s "components."
+
+    Returns a tuple of `numpy.flatiter` objects, one for each "component"
+    of ``self``.
+
+    See Also
+    --------
+    numpy.flatiter
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> row, col = b.iters
+    >>> row.next(), col.next()
+    (1, 4)
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('nd',
+    """
+    Number of dimensions of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.nd
+    2
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('numiter',
+    """
+    Number of iterators possessed by the broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.numiter
+    2
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('shape',
+    """
+    Shape of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.shape
+    (3, 3)
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('size',
+    """
+    Total size of broadcasted result.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]])
+    >>> b = np.broadcast(x, y)
+    >>> b.size
+    9
+
+    """))
+
+add_newdoc('numpy.core', 'broadcast', ('reset',
+    """
+    reset()
+
+    Reset the broadcasted result's iterator(s).
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    None
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> y = np.array([[4], [5], [6]]
+    >>> b = np.broadcast(x, y)
+    >>> b.index
+    0
+    >>> b.next(), b.next(), b.next()
+    ((1, 4), (2, 4), (3, 4))
+    >>> b.index
+    3
+    >>> b.reset()
+    >>> b.index
+    0
+
+    """))
+
+###############################################################################
+#
+# numpy functions
+#
+###############################################################################
+
+add_newdoc('numpy.core.multiarray', 'array',
+    """
+    array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
+
+    Create an array.
+
+    Parameters
+    ----------
+    object : array_like
+        An array, any object exposing the array interface, an
+        object whose __array__ method returns an array, or any
+        (nested) sequence.
+    dtype : data-type, optional
+        The desired data-type for the array.  If not given, then
+        the type will be determined as the minimum type required
+        to hold the objects in the sequence.  This argument can only
+        be used to 'upcast' the array.  For downcasting, use the
+        .astype(t) method.
+    copy : bool, optional
+        If true (default), then the object is copied.  Otherwise, a copy
+        will only be made if __array__ returns a copy, if obj is a
+        nested sequence, or if a copy is needed to satisfy any of the other
+        requirements (`dtype`, `order`, etc.).
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C', then the array
+        will be in C-contiguous order (last-index varies the fastest).
+        If order is 'F', then the returned array will be in
+        Fortran-contiguous order (first-index varies the fastest).
+        If order is 'A' (default), then the returned array may be
+        in any order (either C-, Fortran-contiguous, or even discontiguous),
+        unless a copy is required, in which case it will be C-contiguous.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned array will be forced to be a base-class array (default).
+    ndmin : int, optional
+        Specifies the minimum number of dimensions that the resulting
+        array should have.  Ones will be pre-pended to the shape as
+        needed to meet this requirement.
+
+    Returns
+    -------
+    out : ndarray
+        An array object satisfying the specified requirements.
+
+    See Also
+    --------
+    empty, empty_like, zeros, zeros_like, ones, ones_like, fill
+
+    Examples
+    --------
+    >>> np.array([1, 2, 3])
+    array([1, 2, 3])
+
+    Upcasting:
+
+    >>> np.array([1, 2, 3.0])
+    array([ 1.,  2.,  3.])
+
+    More than one dimension:
+
+    >>> np.array([[1, 2], [3, 4]])
+    array([[1, 2],
+           [3, 4]])
+
+    Minimum dimensions 2:
+
+    >>> np.array([1, 2, 3], ndmin=2)
+    array([[1, 2, 3]])
+
+    Type provided:
+
+    >>> np.array([1, 2, 3], dtype=complex)
+    array([ 1.+0.j,  2.+0.j,  3.+0.j])
+
+    Data-type consisting of more than one element:
+
+    >>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
+    >>> x['a']
+    array([1, 3])
+
+    Creating an array from sub-classes:
+
+    >>> np.array(np.mat('1 2; 3 4'))
+    array([[1, 2],
+           [3, 4]])
+
+    >>> np.array(np.mat('1 2; 3 4'), subok=True)
+    matrix([[1, 2],
+            [3, 4]])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'empty',
+    """
+    empty(shape, dtype=float, order='C')
+
+    Return a new array of given shape and type, without initializing entries.
+
+    Parameters
+    ----------
+    shape : int or tuple of int
+        Shape of the empty array
+    dtype : data-type, optional
+        Desired output data-type.
+    order : {'C', 'F'}, optional
+        Whether to store multi-dimensional data in row-major
+        (C-style) or column-major (Fortran-style) order in
+        memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of uninitialized (arbitrary) data of the given shape, dtype, and
+        order.  Object arrays will be initialized to None.
+
+    See Also
+    --------
+    empty_like, zeros, ones
+
+    Notes
+    -----
+    `empty`, unlike `zeros`, does not set the array values to zero,
+    and may therefore be marginally faster.  On the other hand, it requires
+    the user to manually set all the values in the array, and should be
+    used with caution.
+
+    Examples
+    --------
+    >>> np.empty([2, 2])
+    array([[ -9.74499359e+001,   6.69583040e-309],
+           [  2.13182611e-314,   3.06959433e-309]])         #random
+
+    >>> np.empty([2, 2], dtype=int)
+    array([[-1073741821, -1067949133],
+           [  496041986,    19249760]])                     #random
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'empty_like',
+    """
+    empty_like(a, dtype=None, order='K', subok=True)
+
+    Return a new array with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of the
+        returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if ``a`` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of ``a`` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of uninitialized (arbitrary) data with the same
+        shape and type as `a`.
+
+    See Also
+    --------
+    ones_like : Return an array of ones with shape and type of input.
+    zeros_like : Return an array of zeros with shape and type of input.
+    empty : Return a new uninitialized array.
+    ones : Return a new array setting values to one.
+    zeros : Return a new array setting values to zero.
+
+    Notes
+    -----
+    This function does *not* initialize the returned array; to do that use
+    `zeros_like` or `ones_like` instead.  It may be marginally faster than
+    the functions that do set the array values.
+
+    Examples
+    --------
+    >>> a = ([1,2,3], [4,5,6])                         # a is array-like
+    >>> np.empty_like(a)
+    array([[-1073741821, -1073741821,           3],    #random
+           [          0,           0, -1073741821]])
+    >>> a = np.array([[1., 2., 3.],[4.,5.,6.]])
+    >>> np.empty_like(a)
+    array([[ -2.00000715e+000,   1.48219694e-323,  -2.00000572e+000],#random
+           [  4.38791518e-305,  -2.00000715e+000,   4.17269252e-309]])
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'scalar',
+    """
+    scalar(dtype, obj)
+
+    Return a new scalar array of the given type initialized with obj.
+
+    This function is meant mainly for pickle support. `dtype` must be a
+    valid data-type descriptor. If `dtype` corresponds to an object
+    descriptor, then `obj` can be any object, otherwise `obj` must be a
+    string. If `obj` is not given, it will be interpreted as None for object
+    type and as zeros for all other types.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'zeros',
+    """
+    zeros(shape, dtype=float, order='C')
+
+    Return a new array of given shape and type, filled with zeros.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `numpy.int8`.  Default is
+        `numpy.float64`.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of zeros with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> np.zeros(5)
+    array([ 0.,  0.,  0.,  0.,  0.])
+
+    >>> np.zeros((5,), dtype=np.int)
+    array([0, 0, 0, 0, 0])
+
+    >>> np.zeros((2, 1))
+    array([[ 0.],
+           [ 0.]])
+
+    >>> s = (2,2)
+    >>> np.zeros(s)
+    array([[ 0.,  0.],
+           [ 0.,  0.]])
+
+    >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
+    array([(0, 0), (0, 0)],
+          dtype=[('x', '<i4'), ('y', '<i4')])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'count_nonzero',
+    """
+    count_nonzero(a)
+
+    Counts the number of non-zero values in the array ``a``.
+
+    Parameters
+    ----------
+    a : array_like
+        The array for which to count non-zeros.
+
+    Returns
+    -------
+    count : int or array of int
+        Number of non-zero values in the array.
+
+    See Also
+    --------
+    nonzero : Return the coordinates of all the non-zero values.
+
+    Examples
+    --------
+    >>> np.count_nonzero(np.eye(4))
+    4
+    >>> np.count_nonzero([[0,1,7,0,0],[3,0,0,2,19]])
+    5
+    """)
+
+add_newdoc('numpy.core.multiarray', 'set_typeDict',
+    """set_typeDict(dict)
+
+    Set the internal dictionary that can look up an array type using a
+    registered code.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromstring',
+    """
+    fromstring(string, dtype=float, count=-1, sep='')
+
+    A new 1-D array initialized from raw binary or text data in a string.
+
+    Parameters
+    ----------
+    string : str
+        A string containing the data.
+    dtype : data-type, optional
+        The data type of the array; default: float.  For binary input data,
+        the data must be in exactly this format.
+    count : int, optional
+        Read this number of `dtype` elements from the data.  If this is
+        negative (the default), the count will be determined from the
+        length of the data.
+    sep : str, optional
+        If not provided or, equivalently, the empty string, the data will
+        be interpreted as binary data; otherwise, as ASCII text with
+        decimal numbers.  Also in this latter case, this argument is
+        interpreted as the string separating numbers in the data; extra
+        whitespace between elements is also ignored.
+
+    Returns
+    -------
+    arr : ndarray
+        The constructed array.
+
+    Raises
+    ------
+    ValueError
+        If the string is not the correct size to satisfy the requested
+        `dtype` and `count`.
+
+    See Also
+    --------
+    frombuffer, fromfile, fromiter
+
+    Examples
+    --------
+    >>> np.fromstring('\\x01\\x02', dtype=np.uint8)
+    array([1, 2], dtype=uint8)
+    >>> np.fromstring('1 2', dtype=int, sep=' ')
+    array([1, 2])
+    >>> np.fromstring('1, 2', dtype=int, sep=',')
+    array([1, 2])
+    >>> np.fromstring('\\x01\\x02\\x03\\x04\\x05', dtype=np.uint8, count=3)
+    array([1, 2, 3], dtype=uint8)
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromiter',
+    """
+    fromiter(iterable, dtype, count=-1)
+
+    Create a new 1-dimensional array from an iterable object.
+
+    Parameters
+    ----------
+    iterable : iterable object
+        An iterable object providing data for the array.
+    dtype : data-type
+        The data-type of the returned array.
+    count : int, optional
+        The number of items to read from *iterable*.  The default is -1,
+        which means all data is read.
+
+    Returns
+    -------
+    out : ndarray
+        The output array.
+
+    Notes
+    -----
+    Specify `count` to improve performance.  It allows ``fromiter`` to
+    pre-allocate the output array, instead of resizing it on demand.
+
+    Examples
+    --------
+    >>> iterable = (x*x for x in range(5))
+    >>> np.fromiter(iterable, np.float)
+    array([  0.,   1.,   4.,   9.,  16.])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'fromfile',
+    """
+    fromfile(file, dtype=float, count=-1, sep='')
+
+    Construct an array from data in a text or binary file.
+
+    A highly efficient way of reading binary data with a known data-type,
+    as well as parsing simply formatted text files.  Data written using the
+    `tofile` method can be read using this function.
+
+    Parameters
+    ----------
+    file : file or str
+        Open file object or filename.
+    dtype : data-type
+        Data type of the returned array.
+        For binary files, it is used to determine the size and byte-order
+        of the items in the file.
+    count : int
+        Number of items to read. ``-1`` means all items (i.e., the complete
+        file).
+    sep : str
+        Separator between items if file is a text file.
+        Empty ("") separator means the file should be treated as binary.
+        Spaces (" ") in the separator match zero or more whitespace characters.
+        A separator consisting only of spaces must match at least one
+        whitespace.
+
+    See also
+    --------
+    load, save
+    ndarray.tofile
+    loadtxt : More flexible way of loading data from a text file.
+
+    Notes
+    -----
+    Do not rely on the combination of `tofile` and `fromfile` for
+    data storage, as the binary files generated are are not platform
+    independent.  In particular, no byte-order or data-type information is
+    saved.  Data can be stored in the platform independent ``.npy`` format
+    using `save` and `load` instead.
+
+    Examples
+    --------
+    Construct an ndarray:
+
+    >>> dt = np.dtype([('time', [('min', int), ('sec', int)]),
+    ...                ('temp', float)])
+    >>> x = np.zeros((1,), dtype=dt)
+    >>> x['time']['min'] = 10; x['temp'] = 98.25
+    >>> x
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    Save the raw data to disk:
+
+    >>> import os
+    >>> fname = os.tmpnam()
+    >>> x.tofile(fname)
+
+    Read the raw data from disk:
+
+    >>> np.fromfile(fname, dtype=dt)
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    The recommended way to store and load data:
+
+    >>> np.save(fname, x)
+    >>> np.load(fname + '.npy')
+    array([((10, 0), 98.25)],
+          dtype=[('time', [('min', '<i4'), ('sec', '<i4')]), ('temp', '<f8')])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'frombuffer',
+    """
+    frombuffer(buffer, dtype=float, count=-1, offset=0)
+
+    Interpret a buffer as a 1-dimensional array.
+
+    Parameters
+    ----------
+    buffer : buffer_like
+        An object that exposes the buffer interface.
+    dtype : data-type, optional
+        Data-type of the returned array; default: float.
+    count : int, optional
+        Number of items to read. ``-1`` means all data in the buffer.
+    offset : int, optional
+        Start reading the buffer from this offset; default: 0.
+
+    Notes
+    -----
+    If the buffer has data that is not in machine byte-order, this should
+    be specified as part of the data-type, e.g.::
+
+      >>> dt = np.dtype(int)
+      >>> dt = dt.newbyteorder('>')
+      >>> np.frombuffer(buf, dtype=dt)
+
+    The data of the resulting array will not be byteswapped, but will be
+    interpreted correctly.
+
+    Examples
+    --------
+    >>> s = 'hello world'
+    >>> np.frombuffer(s, dtype='S1', count=5, offset=6)
+    array(['w', 'o', 'r', 'l', 'd'],
+          dtype='|S1')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'concatenate',
+    """
+    concatenate((a1, a2, ...), axis=0)
+
+    Join a sequence of arrays along an existing axis.
+
+    Parameters
+    ----------
+    a1, a2, ... : sequence of array_like
+        The arrays must have the same shape, except in the dimension
+        corresponding to `axis` (the first, by default).
+    axis : int, optional
+        The axis along which the arrays will be joined.  Default is 0.
+
+    Returns
+    -------
+    res : ndarray
+        The concatenated array.
+
+    See Also
+    --------
+    ma.concatenate : Concatenate function that preserves input masks.
+    array_split : Split an array into multiple sub-arrays of equal or
+                  near-equal size.
+    split : Split array into a list of multiple sub-arrays of equal size.
+    hsplit : Split array into multiple sub-arrays horizontally (column wise)
+    vsplit : Split array into multiple sub-arrays vertically (row wise)
+    dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
+    stack : Stack a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise)
+    vstack : Stack arrays in sequence vertically (row wise)
+    dstack : Stack arrays in sequence depth wise (along third dimension)
+
+    Notes
+    -----
+    When one or more of the arrays to be concatenated is a MaskedArray,
+    this function will return a MaskedArray object instead of an ndarray,
+    but the input masks are *not* preserved. In cases where a MaskedArray
+    is expected as input, use the ma.concatenate function from the masked
+    array module instead.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> b = np.array([[5, 6]])
+    >>> np.concatenate((a, b), axis=0)
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    >>> np.concatenate((a, b.T), axis=1)
+    array([[1, 2, 5],
+           [3, 4, 6]])
+
+    This function will not preserve masking of MaskedArray inputs.
+
+    >>> a = np.ma.arange(3)
+    >>> a[1] = np.ma.masked
+    >>> b = np.arange(2, 5)
+    >>> a
+    masked_array(data = [0 -- 2],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> b
+    array([2, 3, 4])
+    >>> np.concatenate([a, b])
+    masked_array(data = [0 1 2 2 3 4],
+                 mask = False,
+           fill_value = 999999)
+    >>> np.ma.concatenate([a, b])
+    masked_array(data = [0 -- 2 2 3 4],
+                 mask = [False  True False False False False],
+           fill_value = 999999)
+
+    """)
+
+add_newdoc('numpy.core', 'inner',
+    """
+    inner(a, b)
+
+    Inner product of two arrays.
+
+    Ordinary inner product of vectors for 1-D arrays (without complex
+    conjugation), in higher dimensions a sum product over the last axes.
+
+    Parameters
+    ----------
+    a, b : array_like
+        If `a` and `b` are nonscalar, their last dimensions must match.
+
+    Returns
+    -------
+    out : ndarray
+        `out.shape = a.shape[:-1] + b.shape[:-1]`
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` and `b` has different size.
+
+    See Also
+    --------
+    tensordot : Sum products over arbitrary axes.
+    dot : Generalised matrix product, using second last dimension of `b`.
+    einsum : Einstein summation convention.
+
+    Notes
+    -----
+    For vectors (1-D arrays) it computes the ordinary inner-product::
+
+        np.inner(a, b) = sum(a[:]*b[:])
+
+    More generally, if `ndim(a) = r > 0` and `ndim(b) = s > 0`::
+
+        np.inner(a, b) = np.tensordot(a, b, axes=(-1,-1))
+
+    or explicitly::
+
+        np.inner(a, b)[i0,...,ir-1,j0,...,js-1]
+             = sum(a[i0,...,ir-1,:]*b[j0,...,js-1,:])
+
+    In addition `a` or `b` may be scalars, in which case::
+
+       np.inner(a,b) = a*b
+
+    Examples
+    --------
+    Ordinary inner product for vectors:
+
+    >>> a = np.array([1,2,3])
+    >>> b = np.array([0,1,0])
+    >>> np.inner(a, b)
+    2
+
+    A multidimensional example:
+
+    >>> a = np.arange(24).reshape((2,3,4))
+    >>> b = np.arange(4)
+    >>> np.inner(a, b)
+    array([[ 14,  38,  62],
+           [ 86, 110, 134]])
+
+    An example where `b` is a scalar:
+
+    >>> np.inner(np.eye(2), 7)
+    array([[ 7.,  0.],
+           [ 0.,  7.]])
+
+    """)
+
+add_newdoc('numpy.core', 'fastCopyAndTranspose',
+    """_fastCopyAndTranspose(a)""")
+
+add_newdoc('numpy.core.multiarray', 'correlate',
+    """cross_correlate(a,v, mode=0)""")
+
+add_newdoc('numpy.core.multiarray', 'arange',
+    """
+    arange([start,] stop[, step,], dtype=None)
+
+    Return evenly spaced values within a given interval.
+
+    Values are generated within the half-open interval ``[start, stop)``
+    (in other words, the interval including `start` but excluding `stop`).
+    For integer arguments the function is equivalent to the Python built-in
+    `range <http://docs.python.org/lib/built-in-funcs.html>`_ function,
+    but returns an ndarray rather than a list.
+
+    When using a non-integer step, such as 0.1, the results will often not
+    be consistent.  It is better to use ``linspace`` for these cases.
+
+    Parameters
+    ----------
+    start : number, optional
+        Start of interval.  The interval includes this value.  The default
+        start value is 0.
+    stop : number
+        End of interval.  The interval does not include this value, except
+        in some cases where `step` is not an integer and floating point
+        round-off affects the length of `out`.
+    step : number, optional
+        Spacing between values.  For any output `out`, this is the distance
+        between two adjacent values, ``out[i+1] - out[i]``.  The default
+        step size is 1.  If `step` is specified, `start` must also be given.
+    dtype : dtype
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+    Returns
+    -------
+    arange : ndarray
+        Array of evenly spaced values.
+
+        For floating point arguments, the length of the result is
+        ``ceil((stop - start)/step)``.  Because of floating point overflow,
+        this rule may result in the last element of `out` being greater
+        than `stop`.
+
+    See Also
+    --------
+    linspace : Evenly spaced numbers with careful handling of endpoints.
+    ogrid: Arrays of evenly spaced numbers in N-dimensions.
+    mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions.
+
+    Examples
+    --------
+    >>> np.arange(3)
+    array([0, 1, 2])
+    >>> np.arange(3.0)
+    array([ 0.,  1.,  2.])
+    >>> np.arange(3,7)
+    array([3, 4, 5, 6])
+    >>> np.arange(3,7,2)
+    array([3, 5])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', '_get_ndarray_c_version',
+    """_get_ndarray_c_version()
+
+    Return the compile time NDARRAY_VERSION number.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', '_reconstruct',
+    """_reconstruct(subtype, shape, dtype)
+
+    Construct an empty array. Used by Pickles.
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'set_string_function',
+    """
+    set_string_function(f, repr=1)
+
+    Internal method to set a function to be used when pretty printing arrays.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'set_numeric_ops',
+    """
+    set_numeric_ops(op1=func1, op2=func2, ...)
+
+    Set numerical operators for array objects.
+
+    Parameters
+    ----------
+    op1, op2, ... : callable
+        Each ``op = func`` pair describes an operator to be replaced.
+        For example, ``add = lambda x, y: np.add(x, y) % 5`` would replace
+        addition by modulus 5 addition.
+
+    Returns
+    -------
+    saved_ops : list of callables
+        A list of all operators, stored before making replacements.
+
+    Notes
+    -----
+    .. WARNING::
+       Use with care!  Incorrect usage may lead to memory errors.
+
+    A function replacing an operator cannot make use of that operator.
+    For example, when replacing add, you may not use ``+``.  Instead,
+    directly call ufuncs.
+
+    Examples
+    --------
+    >>> def add_mod5(x, y):
+    ...     return np.add(x, y) % 5
+    ...
+    >>> old_funcs = np.set_numeric_ops(add=add_mod5)
+
+    >>> x = np.arange(12).reshape((3, 4))
+    >>> x + x
+    array([[0, 2, 4, 1],
+           [3, 0, 2, 4],
+           [1, 3, 0, 2]])
+
+    >>> ignore = np.set_numeric_ops(**old_funcs) # restore operators
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'where',
+    """
+    where(condition, [x, y])
+
+    Return elements, either from `x` or `y`, depending on `condition`.
+
+    If only `condition` is given, return ``condition.nonzero()``.
+
+    Parameters
+    ----------
+    condition : array_like, bool
+        When True, yield `x`, otherwise yield `y`.
+    x, y : array_like, optional
+        Values from which to choose. `x` and `y` need to have the same
+        shape as `condition`.
+
+    Returns
+    -------
+    out : ndarray or tuple of ndarrays
+        If both `x` and `y` are specified, the output array contains
+        elements of `x` where `condition` is True, and elements from
+        `y` elsewhere.
+
+        If only `condition` is given, return the tuple
+        ``condition.nonzero()``, the indices where `condition` is True.
+
+    See Also
+    --------
+    nonzero, choose
+
+    Notes
+    -----
+    If `x` and `y` are given and input arrays are 1-D, `where` is
+    equivalent to::
+
+        [xv if c else yv for (c,xv,yv) in zip(condition,x,y)]
+
+    Examples
+    --------
+    >>> np.where([[True, False], [True, True]],
+    ...          [[1, 2], [3, 4]],
+    ...          [[9, 8], [7, 6]])
+    array([[1, 8],
+           [3, 4]])
+
+    >>> np.where([[0, 1], [1, 0]])
+    (array([0, 1]), array([1, 0]))
+
+    >>> x = np.arange(9.).reshape(3, 3)
+    >>> np.where( x > 5 )
+    (array([2, 2, 2]), array([0, 1, 2]))
+    >>> x[np.where( x > 3.0 )]               # Note: result is 1D.
+    array([ 4.,  5.,  6.,  7.,  8.])
+    >>> np.where(x < 5, x, -1)               # Note: broadcasting.
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -1.],
+           [-1., -1., -1.]])
+
+    Find the indices of elements of `x` that are in `goodvalues`.
+
+    >>> goodvalues = [3, 4, 7]
+    >>> ix = np.in1d(x.ravel(), goodvalues).reshape(x.shape)
+    >>> ix
+    array([[False, False, False],
+           [ True,  True, False],
+           [False,  True, False]], dtype=bool)
+    >>> np.where(ix)
+    (array([1, 1, 2]), array([0, 1, 1]))
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'lexsort',
+    """
+    lexsort(keys, axis=-1)
+
+    Perform an indirect sort using a sequence of keys.
+
+    Given multiple sorting keys, which can be interpreted as columns in a
+    spreadsheet, lexsort returns an array of integer indices that describes
+    the sort order by multiple columns. The last key in the sequence is used
+    for the primary sort order, the second-to-last key for the secondary sort
+    order, and so on. The keys argument must be a sequence of objects that
+    can be converted to arrays of the same shape. If a 2D array is provided
+    for the keys argument, it's rows are interpreted as the sorting keys and
+    sorting is according to the last row, second last row etc.
+
+    Parameters
+    ----------
+    keys : (k, N) array or tuple containing k (N,)-shaped sequences
+        The `k` different "columns" to be sorted.  The last column (or row if
+        `keys` is a 2D array) is the primary sort key.
+    axis : int, optional
+        Axis to be indirectly sorted.  By default, sort over the last axis.
+
+    Returns
+    -------
+    indices : (N,) ndarray of ints
+        Array of indices that sort the keys along the specified axis.
+
+    See Also
+    --------
+    argsort : Indirect sort.
+    ndarray.sort : In-place sort.
+    sort : Return a sorted copy of an array.
+
+    Examples
+    --------
+    Sort names: first by surname, then by name.
+
+    >>> surnames =    ('Hertz',    'Galilei', 'Hertz')
+    >>> first_names = ('Heinrich', 'Galileo', 'Gustav')
+    >>> ind = np.lexsort((first_names, surnames))
+    >>> ind
+    array([1, 2, 0])
+
+    >>> [surnames[i] + ", " + first_names[i] for i in ind]
+    ['Galilei, Galileo', 'Hertz, Gustav', 'Hertz, Heinrich']
+
+    Sort two columns of numbers:
+
+    >>> a = [1,5,1,4,3,4,4] # First column
+    >>> b = [9,4,0,4,0,2,1] # Second column
+    >>> ind = np.lexsort((b,a)) # Sort by a, then by b
+    >>> print(ind)
+    [2 0 4 6 5 3 1]
+
+    >>> [(a[i],b[i]) for i in ind]
+    [(1, 0), (1, 9), (3, 0), (4, 1), (4, 2), (4, 4), (5, 4)]
+
+    Note that sorting is first according to the elements of ``a``.
+    Secondary sorting is according to the elements of ``b``.
+
+    A normal ``argsort`` would have yielded:
+
+    >>> [(a[i],b[i]) for i in np.argsort(a)]
+    [(1, 9), (1, 0), (3, 0), (4, 4), (4, 2), (4, 1), (5, 4)]
+
+    Structured arrays are sorted lexically by ``argsort``:
+
+    >>> x = np.array([(1,9), (5,4), (1,0), (4,4), (3,0), (4,2), (4,1)],
+    ...              dtype=np.dtype([('x', int), ('y', int)]))
+
+    >>> np.argsort(x) # or np.argsort(x, order=('x', 'y'))
+    array([2, 0, 4, 6, 5, 3, 1])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'can_cast',
+    """
+    can_cast(from, totype, casting = 'safe')
+
+    Returns True if cast between data types can occur according to the
+    casting rule.  If from is a scalar or array scalar, also returns
+    True if the scalar value can be cast without overflow or truncation
+    to an integer.
+
+    Parameters
+    ----------
+    from : dtype, dtype specifier, scalar, or array
+        Data type, scalar, or array to cast from.
+    totype : dtype or dtype specifier
+        Data type to cast to.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+
+    Returns
+    -------
+    out : bool
+        True if cast can occur according to the casting rule.
+
+    Notes
+    -----
+    Starting in NumPy 1.9, can_cast function now returns False in 'safe'
+    casting mode for integer/float dtype and string dtype if the string dtype
+    length is not long enough to store the max integer/float value converted
+    to a string. Previously can_cast in 'safe' mode returned True for
+    integer/float dtype and a string dtype of any length.
+
+    See also
+    --------
+    dtype, result_type
+
+    Examples
+    --------
+    Basic examples
+
+    >>> np.can_cast(np.int32, np.int64)
+    True
+    >>> np.can_cast(np.float64, np.complex)
+    True
+    >>> np.can_cast(np.complex, np.float)
+    False
+
+    >>> np.can_cast('i8', 'f8')
+    True
+    >>> np.can_cast('i8', 'f4')
+    False
+    >>> np.can_cast('i4', 'S4')
+    False
+
+    Casting scalars
+
+    >>> np.can_cast(100, 'i1')
+    True
+    >>> np.can_cast(150, 'i1')
+    False
+    >>> np.can_cast(150, 'u1')
+    True
+
+    >>> np.can_cast(3.5e100, np.float32)
+    False
+    >>> np.can_cast(1000.0, np.float32)
+    True
+
+    Array scalar checks the value, array does not
+
+    >>> np.can_cast(np.array(1000.0), np.float32)
+    True
+    >>> np.can_cast(np.array([1000.0]), np.float32)
+    False
+
+    Using the casting rules
+
+    >>> np.can_cast('i8', 'i8', 'no')
+    True
+    >>> np.can_cast('<i8', '>i8', 'no')
+    False
+
+    >>> np.can_cast('<i8', '>i8', 'equiv')
+    True
+    >>> np.can_cast('<i4', '>i8', 'equiv')
+    False
+
+    >>> np.can_cast('<i4', '>i8', 'safe')
+    True
+    >>> np.can_cast('<i8', '>i4', 'safe')
+    False
+
+    >>> np.can_cast('<i8', '>i4', 'same_kind')
+    True
+    >>> np.can_cast('<i8', '>u4', 'same_kind')
+    False
+
+    >>> np.can_cast('<i8', '>u4', 'unsafe')
+    True
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'promote_types',
+    """
+    promote_types(type1, type2)
+
+    Returns the data type with the smallest size and smallest scalar
+    kind to which both ``type1`` and ``type2`` may be safely cast.
+    The returned data type is always in native byte order.
+
+    This function is symmetric and associative.
+
+    Parameters
+    ----------
+    type1 : dtype or dtype specifier
+        First data type.
+    type2 : dtype or dtype specifier
+        Second data type.
+
+    Returns
+    -------
+    out : dtype
+        The promoted data type.
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    Starting in NumPy 1.9, promote_types function now returns a valid string
+    length when given an integer or float dtype as one argument and a string
+    dtype as another argument. Previously it always returned the input string
+    dtype, even if it wasn't long enough to store the max integer/float value
+    converted to a string.
+
+    See Also
+    --------
+    result_type, dtype, can_cast
+
+    Examples
+    --------
+    >>> np.promote_types('f4', 'f8')
+    dtype('float64')
+
+    >>> np.promote_types('i8', 'f4')
+    dtype('float64')
+
+    >>> np.promote_types('>i8', '<c8')
+    dtype('complex128')
+
+    >>> np.promote_types('i4', 'S8')
+    dtype('S11')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'min_scalar_type',
+    """
+    min_scalar_type(a)
+
+    For scalar ``a``, returns the data type with the smallest size
+    and smallest scalar kind which can hold its value.  For non-scalar
+    array ``a``, returns the vector's dtype unmodified.
+
+    Floating point values are not demoted to integers,
+    and complex values are not demoted to floats.
+
+    Parameters
+    ----------
+    a : scalar or array_like
+        The value whose minimal data type is to be found.
+
+    Returns
+    -------
+    out : dtype
+        The minimal data type.
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    See Also
+    --------
+    result_type, promote_types, dtype, can_cast
+
+    Examples
+    --------
+    >>> np.min_scalar_type(10)
+    dtype('uint8')
+
+    >>> np.min_scalar_type(-260)
+    dtype('int16')
+
+    >>> np.min_scalar_type(3.1)
+    dtype('float16')
+
+    >>> np.min_scalar_type(1e50)
+    dtype('float64')
+
+    >>> np.min_scalar_type(np.arange(4,dtype='f8'))
+    dtype('float64')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'result_type',
+    """
+    result_type(*arrays_and_dtypes)
+
+    Returns the type that results from applying the NumPy
+    type promotion rules to the arguments.
+
+    Type promotion in NumPy works similarly to the rules in languages
+    like C++, with some slight differences.  When both scalars and
+    arrays are used, the array's type takes precedence and the actual value
+    of the scalar is taken into account.
+
+    For example, calculating 3*a, where a is an array of 32-bit floats,
+    intuitively should result in a 32-bit float output.  If the 3 is a
+    32-bit integer, the NumPy rules indicate it can't convert losslessly
+    into a 32-bit float, so a 64-bit float should be the result type.
+    By examining the value of the constant, '3', we see that it fits in
+    an 8-bit integer, which can be cast losslessly into the 32-bit float.
+
+    Parameters
+    ----------
+    arrays_and_dtypes : list of arrays and dtypes
+        The operands of some operation whose result type is needed.
+
+    Returns
+    -------
+    out : dtype
+        The result type.
+
+    See also
+    --------
+    dtype, promote_types, min_scalar_type, can_cast
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    The specific algorithm used is as follows.
+
+    Categories are determined by first checking which of boolean,
+    integer (int/uint), or floating point (float/complex) the maximum
+    kind of all the arrays and the scalars are.
+
+    If there are only scalars or the maximum category of the scalars
+    is higher than the maximum category of the arrays,
+    the data types are combined with :func:`promote_types`
+    to produce the return value.
+
+    Otherwise, `min_scalar_type` is called on each array, and
+    the resulting data types are all combined with :func:`promote_types`
+    to produce the return value.
+
+    The set of int values is not a subset of the uint values for types
+    with the same number of bits, something not reflected in
+    :func:`min_scalar_type`, but handled as a special case in `result_type`.
+
+    Examples
+    --------
+    >>> np.result_type(3, np.arange(7, dtype='i1'))
+    dtype('int8')
+
+    >>> np.result_type('i4', 'c8')
+    dtype('complex128')
+
+    >>> np.result_type(3.0, -2)
+    dtype('float64')
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'newbuffer',
+    """
+    newbuffer(size)
+
+    Return a new uninitialized buffer object.
+
+    Parameters
+    ----------
+    size : int
+        Size in bytes of returned buffer object.
+
+    Returns
+    -------
+    newbuffer : buffer object
+        Returned, uninitialized buffer object of `size` bytes.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'getbuffer',
+    """
+    getbuffer(obj [,offset[, size]])
+
+    Create a buffer object from the given object referencing a slice of
+    length size starting at offset.
+
+    Default is the entire buffer. A read-write buffer is attempted followed
+    by a read-only buffer.
+
+    Parameters
+    ----------
+    obj : object
+
+    offset : int, optional
+
+    size : int, optional
+
+    Returns
+    -------
+    buffer_obj : buffer
+
+    Examples
+    --------
+    >>> buf = np.getbuffer(np.ones(5), 1, 3)
+    >>> len(buf)
+    3
+    >>> buf[0]
+    '\\x00'
+    >>> buf
+    <read-write buffer for 0x8af1e70, size 3, offset 1 at 0x8ba4ec0>
+
+    """)
+
+add_newdoc('numpy.core', 'dot',
+    """
+    dot(a, b, out=None)
+
+    Dot product of two arrays.
+
+    For 2-D arrays it is equivalent to matrix multiplication, and for 1-D
+    arrays to inner product of vectors (without complex conjugation). For
+    N dimensions it is a sum product over the last axis of `a` and
+    the second-to-last of `b`::
+
+        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
+
+    Parameters
+    ----------
+    a : array_like
+        First argument.
+    b : array_like
+        Second argument.
+    out : ndarray, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of `a` and `b`.  If `a` and `b` are both
+        scalars or both 1-D arrays then a scalar is returned; otherwise
+        an array is returned.
+        If `out` is given, then it is returned.
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` is not the same size as
+        the second-to-last dimension of `b`.
+
+    See Also
+    --------
+    vdot : Complex-conjugating dot product.
+    tensordot : Sum products over arbitrary axes.
+    einsum : Einstein summation convention.
+    matmul : '@' operator as method with out parameter.
+
+    Examples
+    --------
+    >>> np.dot(3, 4)
+    12
+
+    Neither argument is complex-conjugated:
+
+    >>> np.dot([2j, 3j], [2j, 3j])
+    (-13+0j)
+
+    For 2-D arrays it is the matrix product:
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [[4, 1], [2, 2]]
+    >>> np.dot(a, b)
+    array([[4, 1],
+           [2, 2]])
+
+    >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
+    >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))
+    >>> np.dot(a, b)[2,3,2,1,2,2]
+    499128
+    >>> sum(a[2,3,2,:] * b[1,2,:,2])
+    499128
+
+    """)
+
+add_newdoc('numpy.core', 'matmul',
+    """
+    matmul(a, b, out=None)
+
+    Matrix product of two arrays.
+
+    The behavior depends on the arguments in the following way.
+
+    - If both arguments are 2-D they are multiplied like conventional
+      matrices.
+    - If either argument is N-D, N > 2, it is treated as a stack of
+      matrices residing in the last two indexes and broadcast accordingly.
+    - If the first argument is 1-D, it is promoted to a matrix by
+      prepending a 1 to its dimensions. After matrix multiplication
+      the prepended 1 is removed.
+    - If the second argument is 1-D, it is promoted to a matrix by
+      appending a 1 to its dimensions. After matrix multiplication
+      the appended 1 is removed.
+
+    Multiplication by a scalar is not allowed, use ``*`` instead. Note that
+    multiplying a stack of matrices with a vector will result in a stack of
+    vectors, but matmul will not recognize it as such.
+
+    ``matmul`` differs from ``dot`` in two important ways.
+
+    - Multiplication by scalars is not allowed.
+    - Stacks of matrices are broadcast together as if the matrices
+      were elements.
+
+    .. warning::
+       This function is preliminary and included in Numpy 1.10 for testing
+       and documentation. Its semantics will not change, but the number and
+       order of the optional arguments will.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    a : array_like
+        First argument.
+    b : array_like
+        Second argument.
+    out : ndarray, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of `a` and `b`.  If `a` and `b` are both
+        1-D arrays then a scalar is returned; otherwise an array is
+        returned.  If `out` is given, then it is returned.
+
+    Raises
+    ------
+    ValueError
+        If the last dimension of `a` is not the same size as
+        the second-to-last dimension of `b`.
+
+        If scalar value is passed.
+
+    See Also
+    --------
+    vdot : Complex-conjugating dot product.
+    tensordot : Sum products over arbitrary axes.
+    einsum : Einstein summation convention.
+    dot : alternative matrix product with different broadcasting rules.
+
+    Notes
+    -----
+    The matmul function implements the semantics of the `@` operator introduced
+    in Python 3.5 following PEP465.
+
+    Examples
+    --------
+    For 2-D arrays it is the matrix product:
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [[4, 1], [2, 2]]
+    >>> np.matmul(a, b)
+    array([[4, 1],
+           [2, 2]])
+
+    For 2-D mixed with 1-D, the result is the usual.
+
+    >>> a = [[1, 0], [0, 1]]
+    >>> b = [1, 2]
+    >>> np.matmul(a, b)
+    array([1, 2])
+    >>> np.matmul(b, a)
+    array([1, 2])
+
+
+    Broadcasting is conventional for stacks of arrays
+
+    >>> a = np.arange(2*2*4).reshape((2,2,4))
+    >>> b = np.arange(2*2*4).reshape((2,4,2))
+    >>> np.matmul(a,b).shape
+    (2, 2, 2)
+    >>> np.matmul(a,b)[0,1,1]
+    98
+    >>> sum(a[0,1,:] * b[0,:,1])
+    98
+
+    Vector, vector returns the scalar inner product, but neither argument
+    is complex-conjugated:
+
+    >>> np.matmul([2j, 3j], [2j, 3j])
+    (-13+0j)
+
+    Scalar multiplication raises an error.
+
+    >>> np.matmul([1,2], 3)
+    Traceback (most recent call last):
+    ...
+    ValueError: Scalar operands are not allowed, use '*' instead
+
+    """)
+
+
+add_newdoc('numpy.core', 'einsum',
+    """
+    einsum(subscripts, *operands, out=None, dtype=None, order='K', casting='safe')
+
+    Evaluates the Einstein summation convention on the operands.
+
+    Using the Einstein summation convention, many common multi-dimensional
+    array operations can be represented in a simple fashion.  This function
+    provides a way to compute such summations. The best way to understand this
+    function is to try the examples below, which show how many common NumPy
+    functions can be implemented as calls to `einsum`.
+
+    Parameters
+    ----------
+    subscripts : str
+        Specifies the subscripts for summation.
+    operands : list of array_like
+        These are the arrays for the operation.
+    out : ndarray, optional
+        If provided, the calculation is done into this array.
+    dtype : data-type, optional
+        If provided, forces the calculation to use the data type specified.
+        Note that you may have to also give a more liberal `casting`
+        parameter to allow the conversions.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the output. 'C' means it should
+        be C contiguous. 'F' means it should be Fortran contiguous,
+        'A' means it should be 'F' if the inputs are all 'F', 'C' otherwise.
+        'K' means it should be as close to the layout as the inputs as
+        is possible, including arbitrarily permuted axes.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur.  Setting this to
+        'unsafe' is not recommended, as it can adversely affect accumulations.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+
+    Returns
+    -------
+    output : ndarray
+        The calculation based on the Einstein summation convention.
+
+    See Also
+    --------
+    dot, inner, outer, tensordot
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    The subscripts string is a comma-separated list of subscript labels,
+    where each label refers to a dimension of the corresponding operand.
+    Repeated subscripts labels in one operand take the diagonal.  For example,
+    ``np.einsum('ii', a)`` is equivalent to ``np.trace(a)``.
+
+    Whenever a label is repeated, it is summed, so ``np.einsum('i,i', a, b)``
+    is equivalent to ``np.inner(a,b)``.  If a label appears only once,
+    it is not summed, so ``np.einsum('i', a)`` produces a view of ``a``
+    with no changes.
+
+    The order of labels in the output is by default alphabetical.  This
+    means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while
+    ``np.einsum('ji', a)`` takes its transpose.
+
+    The output can be controlled by specifying output subscript labels
+    as well.  This specifies the label order, and allows summing to
+    be disallowed or forced when desired.  The call ``np.einsum('i->', a)``
+    is like ``np.sum(a, axis=-1)``, and ``np.einsum('ii->i', a)``
+    is like ``np.diag(a)``.  The difference is that `einsum` does not
+    allow broadcasting by default.
+
+    To enable and control broadcasting, use an ellipsis.  Default
+    NumPy-style broadcasting is done by adding an ellipsis
+    to the left of each term, like ``np.einsum('...ii->...i', a)``.
+    To take the trace along the first and last axes,
+    you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix
+    product with the left-most indices instead of rightmost, you can do
+    ``np.einsum('ij...,jk...->ik...', a, b)``.
+
+    When there is only one operand, no axes are summed, and no output
+    parameter is provided, a view into the operand is returned instead
+    of a new array.  Thus, taking the diagonal as ``np.einsum('ii->i', a)``
+    produces a view.
+
+    An alternative way to provide the subscripts and operands is as
+    ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``. The examples
+    below have corresponding `einsum` calls with the two parameter methods.
+
+    .. versionadded:: 1.10.0
+
+    Views returned from einsum are now writeable whenever the input array
+    is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now
+    have the same effect as ``np.swapaxes(a, 0, 2)`` and
+    ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
+    of a 2D array.
+
+    Examples
+    --------
+    >>> a = np.arange(25).reshape(5,5)
+    >>> b = np.arange(5)
+    >>> c = np.arange(6).reshape(2,3)
+
+    >>> np.einsum('ii', a)
+    60
+    >>> np.einsum(a, [0,0])
+    60
+    >>> np.trace(a)
+    60
+
+    >>> np.einsum('ii->i', a)
+    array([ 0,  6, 12, 18, 24])
+    >>> np.einsum(a, [0,0], [0])
+    array([ 0,  6, 12, 18, 24])
+    >>> np.diag(a)
+    array([ 0,  6, 12, 18, 24])
+
+    >>> np.einsum('ij,j', a, b)
+    array([ 30,  80, 130, 180, 230])
+    >>> np.einsum(a, [0,1], b, [1])
+    array([ 30,  80, 130, 180, 230])
+    >>> np.dot(a, b)
+    array([ 30,  80, 130, 180, 230])
+    >>> np.einsum('...j,j', a, b)
+    array([ 30,  80, 130, 180, 230])
+
+    >>> np.einsum('ji', c)
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+    >>> np.einsum(c, [1,0])
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+    >>> c.T
+    array([[0, 3],
+           [1, 4],
+           [2, 5]])
+
+    >>> np.einsum('..., ...', 3, c)
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+    >>> np.einsum(3, [Ellipsis], c, [Ellipsis])
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+    >>> np.multiply(3, c)
+    array([[ 0,  3,  6],
+           [ 9, 12, 15]])
+
+    >>> np.einsum('i,i', b, b)
+    30
+    >>> np.einsum(b, [0], b, [0])
+    30
+    >>> np.inner(b,b)
+    30
+
+    >>> np.einsum('i,j', np.arange(2)+1, b)
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+    >>> np.einsum(np.arange(2)+1, [0], b, [1])
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+    >>> np.outer(np.arange(2)+1, b)
+    array([[0, 1, 2, 3, 4],
+           [0, 2, 4, 6, 8]])
+
+    >>> np.einsum('i...->...', a)
+    array([50, 55, 60, 65, 70])
+    >>> np.einsum(a, [0,Ellipsis], [Ellipsis])
+    array([50, 55, 60, 65, 70])
+    >>> np.sum(a, axis=0)
+    array([50, 55, 60, 65, 70])
+
+    >>> a = np.arange(60.).reshape(3,4,5)
+    >>> b = np.arange(24.).reshape(4,3,2)
+    >>> np.einsum('ijk,jil->kl', a, b)
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3])
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> np.tensordot(a,b, axes=([1,0],[0,1]))
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+
+    >>> a = np.arange(6).reshape((3,2))
+    >>> b = np.arange(12).reshape((4,3))
+    >>> np.einsum('ki,jk->ij', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+    >>> np.einsum('ki,...k->i...', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+    >>> np.einsum('k...,jk', a, b)
+    array([[10, 28, 46, 64],
+           [13, 40, 67, 94]])
+
+    >>> # since version 1.10.0
+    >>> a = np.zeros((3, 3))
+    >>> np.einsum('ii->i', a)[:] = 1
+    >>> a
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """)
+
+add_newdoc('numpy.core', 'vdot',
+    """
+    vdot(a, b)
+
+    Return the dot product of two vectors.
+
+    The vdot(`a`, `b`) function handles complex numbers differently than
+    dot(`a`, `b`).  If the first argument is complex the complex conjugate
+    of the first argument is used for the calculation of the dot product.
+
+    Note that `vdot` handles multidimensional arrays differently than `dot`:
+    it does *not* perform a matrix product, but flattens input arguments
+    to 1-D vectors first. Consequently, it should only be used for vectors.
+
+    Parameters
+    ----------
+    a : array_like
+        If `a` is complex the complex conjugate is taken before calculation
+        of the dot product.
+    b : array_like
+        Second argument to the dot product.
+
+    Returns
+    -------
+    output : ndarray
+        Dot product of `a` and `b`.  Can be an int, float, or
+        complex depending on the types of `a` and `b`.
+
+    See Also
+    --------
+    dot : Return the dot product without using the complex conjugate of the
+          first argument.
+
+    Examples
+    --------
+    >>> a = np.array([1+2j,3+4j])
+    >>> b = np.array([5+6j,7+8j])
+    >>> np.vdot(a, b)
+    (70-8j)
+    >>> np.vdot(b, a)
+    (70+8j)
+
+    Note that higher-dimensional arrays are flattened!
+
+    >>> a = np.array([[1, 4], [5, 6]])
+    >>> b = np.array([[4, 1], [2, 2]])
+    >>> np.vdot(a, b)
+    30
+    >>> np.vdot(b, a)
+    30
+    >>> 1*4 + 4*1 + 5*2 + 6*2
+    30
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for ndarray attributes and methods
+#
+##############################################################################
+
+
+##############################################################################
+#
+# ndarray object
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray',
+    """
+    ndarray(shape, dtype=float, buffer=None, offset=0,
+            strides=None, order=None)
+
+    An array object represents a multidimensional, homogeneous array
+    of fixed-size items.  An associated data-type object describes the
+    format of each element in the array (its byte-order, how many bytes it
+    occupies in memory, whether it is an integer, a floating point number,
+    or something else, etc.)
+
+    Arrays should be constructed using `array`, `zeros` or `empty` (refer
+    to the See Also section below).  The parameters given here refer to
+    a low-level method (`ndarray(...)`) for instantiating an array.
+
+    For more information, refer to the `numpy` module and examine the
+    the methods and attributes of an array.
+
+    Parameters
+    ----------
+    (for the __new__ method; see Notes below)
+
+    shape : tuple of ints
+        Shape of created array.
+    dtype : data-type, optional
+        Any object that can be interpreted as a numpy data type.
+    buffer : object exposing buffer interface, optional
+        Used to fill the array with data.
+    offset : int, optional
+        Offset of array data in buffer.
+    strides : tuple of ints, optional
+        Strides of data in memory.
+    order : {'C', 'F'}, optional
+        Row-major (C-style) or column-major (Fortran-style) order.
+
+    Attributes
+    ----------
+    T : ndarray
+        Transpose of the array.
+    data : buffer
+        The array's elements, in memory.
+    dtype : dtype object
+        Describes the format of the elements in the array.
+    flags : dict
+        Dictionary containing information related to memory use, e.g.,
+        'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
+    flat : numpy.flatiter object
+        Flattened version of the array as an iterator.  The iterator
+        allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
+        assignment examples; TODO).
+    imag : ndarray
+        Imaginary part of the array.
+    real : ndarray
+        Real part of the array.
+    size : int
+        Number of elements in the array.
+    itemsize : int
+        The memory use of each array element in bytes.
+    nbytes : int
+        The total number of bytes required to store the array data,
+        i.e., ``itemsize * size``.
+    ndim : int
+        The array's number of dimensions.
+    shape : tuple of ints
+        Shape of the array.
+    strides : tuple of ints
+        The step-size required to move from one element to the next in
+        memory. For example, a contiguous ``(3, 4)`` array of type
+        ``int16`` in C-order has strides ``(8, 2)``.  This implies that
+        to move from element to element in memory requires jumps of 2 bytes.
+        To move from row-to-row, one needs to jump 8 bytes at a time
+        (``2 * 4``).
+    ctypes : ctypes object
+        Class containing properties of the array needed for interaction
+        with ctypes.
+    base : ndarray
+        If the array is a view into another array, that array is its `base`
+        (unless that array is also a view).  The `base` array is where the
+        array data is actually stored.
+
+    See Also
+    --------
+    array : Construct an array.
+    zeros : Create an array, each element of which is zero.
+    empty : Create an array, but leave its allocated memory unchanged (i.e.,
+            it contains "garbage").
+    dtype : Create a data-type.
+
+    Notes
+    -----
+    There are two modes of creating an array using ``__new__``:
+
+    1. If `buffer` is None, then only `shape`, `dtype`, and `order`
+       are used.
+    2. If `buffer` is an object exposing the buffer interface, then
+       all keywords are interpreted.
+
+    No ``__init__`` method is needed because the array is fully initialized
+    after the ``__new__`` method.
+
+    Examples
+    --------
+    These examples illustrate the low-level `ndarray` constructor.  Refer
+    to the `See Also` section above for easier ways of constructing an
+    ndarray.
+
+    First mode, `buffer` is None:
+
+    >>> np.ndarray(shape=(2,2), dtype=float, order='F')
+    array([[ -1.13698227e+002,   4.25087011e-303],
+           [  2.88528414e-306,   3.27025015e-309]])         #random
+
+    Second mode:
+
+    >>> np.ndarray((2,), buffer=np.array([1,2,3]),
+    ...            offset=np.int_().itemsize,
+    ...            dtype=int) # offset = 1*itemsize, i.e. skip first element
+    array([2, 3])
+
+    """)
+
+
+##############################################################################
+#
+# ndarray attributes
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_interface__',
+    """Array protocol: Python side."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_finalize__',
+    """None."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_priority__',
+    """Array priority."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_struct__',
+    """Array protocol: C-struct side."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('_as_parameter_',
+    """Allow the array to be interpreted as a ctypes object by returning the
+    data-memory location as an integer
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('base',
+    """
+    Base object if memory is from some other object.
+
+    Examples
+    --------
+    The base of an array that owns its memory is None:
+
+    >>> x = np.array([1,2,3,4])
+    >>> x.base is None
+    True
+
+    Slicing creates a view, whose memory is shared with x:
+
+    >>> y = x[2:]
+    >>> y.base is x
+    True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ctypes',
+    """
+    An object to simplify the interaction of the array with the ctypes
+    module.
+
+    This attribute creates an object that makes it easier to use arrays
+    when calling shared libraries with the ctypes module. The returned
+    object has, among others, data, shape, and strides attributes (see
+    Notes below) which themselves return ctypes objects that can be used
+    as arguments to a shared library.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    c : Python object
+        Possessing attributes data, shape, strides, etc.
+
+    See Also
+    --------
+    numpy.ctypeslib
+
+    Notes
+    -----
+    Below are the public attributes of this object which were documented
+    in "Guide to NumPy" (we have omitted undocumented public attributes,
+    as well as documented private attributes):
+
+    * data: A pointer to the memory area of the array as a Python integer.
+      This memory area may contain data that is not aligned, or not in correct
+      byte-order. The memory area may not even be writeable. The array
+      flags and data-type of this array should be respected when passing this
+      attribute to arbitrary C-code to avoid trouble that can include Python
+      crashing. User Beware! The value of this attribute is exactly the same
+      as self._array_interface_['data'][0].
+
+    * shape (c_intp*self.ndim): A ctypes array of length self.ndim where
+      the basetype is the C-integer corresponding to dtype('p') on this
+      platform. This base-type could be c_int, c_long, or c_longlong
+      depending on the platform. The c_intp type is defined accordingly in
+      numpy.ctypeslib. The ctypes array contains the shape of the underlying
+      array.
+
+    * strides (c_intp*self.ndim): A ctypes array of length self.ndim where
+      the basetype is the same as for the shape attribute. This ctypes array
+      contains the strides information from the underlying array. This strides
+      information is important for showing how many bytes must be jumped to
+      get to the next element in the array.
+
+    * data_as(obj): Return the data pointer cast to a particular c-types object.
+      For example, calling self._as_parameter_ is equivalent to
+      self.data_as(ctypes.c_void_p). Perhaps you want to use the data as a
+      pointer to a ctypes array of floating-point data:
+      self.data_as(ctypes.POINTER(ctypes.c_double)).
+
+    * shape_as(obj): Return the shape tuple as an array of some other c-types
+      type. For example: self.shape_as(ctypes.c_short).
+
+    * strides_as(obj): Return the strides tuple as an array of some other
+      c-types type. For example: self.strides_as(ctypes.c_longlong).
+
+    Be careful using the ctypes attribute - especially on temporary
+    arrays or arrays constructed on the fly. For example, calling
+    ``(a+b).ctypes.data_as(ctypes.c_void_p)`` returns a pointer to memory
+    that is invalid because the array created as (a+b) is deallocated
+    before the next Python statement. You can avoid this problem using
+    either ``c=a+b`` or ``ct=(a+b).ctypes``. In the latter case, ct will
+    hold a reference to the array until ct is deleted or re-assigned.
+
+    If the ctypes module is not available, then the ctypes attribute
+    of array objects still returns something useful, but ctypes objects
+    are not returned and errors may be raised instead. In particular,
+    the object will still have the as parameter attribute which will
+    return an integer equal to the data attribute.
+
+    Examples
+    --------
+    >>> import ctypes
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+    >>> x.ctypes.data
+    30439712
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long))
+    <ctypes.LP_c_long object at 0x01F01300>
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_long)).contents
+    c_long(0)
+    >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_longlong)).contents
+    c_longlong(4294967296L)
+    >>> x.ctypes.shape
+    <numpy.core._internal.c_long_Array_2 object at 0x01FFD580>
+    >>> x.ctypes.shape_as(ctypes.c_long)
+    <numpy.core._internal.c_long_Array_2 object at 0x01FCE620>
+    >>> x.ctypes.strides
+    <numpy.core._internal.c_long_Array_2 object at 0x01FCE620>
+    >>> x.ctypes.strides_as(ctypes.c_longlong)
+    <numpy.core._internal.c_longlong_Array_2 object at 0x01F01300>
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('data',
+    """Python buffer object pointing to the start of the array's data."""))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dtype',
+    """
+    Data-type of the array's elements.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    d : numpy dtype object
+
+    See Also
+    --------
+    numpy.dtype
+
+    Examples
+    --------
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+    >>> x.dtype
+    dtype('int32')
+    >>> type(x.dtype)
+    <type 'numpy.dtype'>
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('imag',
+    """
+    The imaginary part of the array.
+
+    Examples
+    --------
+    >>> x = np.sqrt([1+0j, 0+1j])
+    >>> x.imag
+    array([ 0.        ,  0.70710678])
+    >>> x.imag.dtype
+    dtype('float64')
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemsize',
+    """
+    Length of one array element in bytes.
+
+    Examples
+    --------
+    >>> x = np.array([1,2,3], dtype=np.float64)
+    >>> x.itemsize
+    8
+    >>> x = np.array([1,2,3], dtype=np.complex128)
+    >>> x.itemsize
+    16
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flags',
+    """
+    Information about the memory layout of the array.
+
+    Attributes
+    ----------
+    C_CONTIGUOUS (C)
+        The data is in a single, C-style contiguous segment.
+    F_CONTIGUOUS (F)
+        The data is in a single, Fortran-style contiguous segment.
+    OWNDATA (O)
+        The array owns the memory it uses or borrows it from another object.
+    WRITEABLE (W)
+        The data area can be written to.  Setting this to False locks
+        the data, making it read-only.  A view (slice, etc.) inherits WRITEABLE
+        from its base array at creation time, but a view of a writeable
+        array may be subsequently locked while the base array remains writeable.
+        (The opposite is not true, in that a view of a locked array may not
+        be made writeable.  However, currently, locking a base object does not
+        lock any views that already reference it, so under that circumstance it
+        is possible to alter the contents of a locked array via a previously
+        created writeable view onto it.)  Attempting to change a non-writeable
+        array raises a RuntimeError exception.
+    ALIGNED (A)
+        The data and all elements are aligned appropriately for the hardware.
+    UPDATEIFCOPY (U)
+        This array is a copy of some other array. When this array is
+        deallocated, the base array will be updated with the contents of
+        this array.
+    FNC
+        F_CONTIGUOUS and not C_CONTIGUOUS.
+    FORC
+        F_CONTIGUOUS or C_CONTIGUOUS (one-segment test).
+    BEHAVED (B)
+        ALIGNED and WRITEABLE.
+    CARRAY (CA)
+        BEHAVED and C_CONTIGUOUS.
+    FARRAY (FA)
+        BEHAVED and F_CONTIGUOUS and not C_CONTIGUOUS.
+
+    Notes
+    -----
+    The `flags` object can be accessed dictionary-like (as in ``a.flags['WRITEABLE']``),
+    or by using lowercased attribute names (as in ``a.flags.writeable``). Short flag
+    names are only supported in dictionary access.
+
+    Only the UPDATEIFCOPY, WRITEABLE, and ALIGNED flags can be changed by
+    the user, via direct assignment to the attribute or dictionary entry,
+    or by calling `ndarray.setflags`.
+
+    The array flags cannot be set arbitrarily:
+
+    - UPDATEIFCOPY can only be set ``False``.
+    - ALIGNED can only be set ``True`` if the data is truly aligned.
+    - WRITEABLE can only be set ``True`` if the array owns its own memory
+      or the ultimate owner of the memory exposes a writeable buffer
+      interface or is a string.
+
+    Arrays can be both C-style and Fortran-style contiguous simultaneously.
+    This is clear for 1-dimensional arrays, but can also be true for higher
+    dimensional arrays.
+
+    Even for contiguous arrays a stride for a given dimension
+    ``arr.strides[dim]`` may be *arbitrary* if ``arr.shape[dim] == 1``
+    or the array has no elements.
+    It does *not* generally hold that ``self.strides[-1] == self.itemsize``
+    for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for
+    Fortran-style contiguous arrays is true.
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flat',
+    """
+    A 1-D iterator over the array.
+
+    This is a `numpy.flatiter` instance, which acts similarly to, but is not
+    a subclass of, Python's built-in iterator object.
+
+    See Also
+    --------
+    flatten : Return a copy of the array collapsed into one dimension.
+
+    flatiter
+
+    Examples
+    --------
+    >>> x = np.arange(1, 7).reshape(2, 3)
+    >>> x
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> x.flat[3]
+    4
+    >>> x.T
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+    >>> x.T.flat[3]
+    5
+    >>> type(x.flat)
+    <type 'numpy.flatiter'>
+
+    An assignment example:
+
+    >>> x.flat = 3; x
+    array([[3, 3, 3],
+           [3, 3, 3]])
+    >>> x.flat[[1,4]] = 1; x
+    array([[3, 1, 3],
+           [3, 1, 3]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nbytes',
+    """
+    Total bytes consumed by the elements of the array.
+
+    Notes
+    -----
+    Does not include memory consumed by non-element attributes of the
+    array object.
+
+    Examples
+    --------
+    >>> x = np.zeros((3,5,2), dtype=np.complex128)
+    >>> x.nbytes
+    480
+    >>> np.prod(x.shape) * x.itemsize
+    480
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ndim',
+    """
+    Number of array dimensions.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> x.ndim
+    1
+    >>> y = np.zeros((2, 3, 4))
+    >>> y.ndim
+    3
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('real',
+    """
+    The real part of the array.
+
+    Examples
+    --------
+    >>> x = np.sqrt([1+0j, 0+1j])
+    >>> x.real
+    array([ 1.        ,  0.70710678])
+    >>> x.real.dtype
+    dtype('float64')
+
+    See Also
+    --------
+    numpy.real : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('shape',
+    """
+    Tuple of array dimensions.
+
+    Notes
+    -----
+    May be used to "reshape" the array, as long as this would not
+    require a change in the total number of elements
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3, 4])
+    >>> x.shape
+    (4,)
+    >>> y = np.zeros((2, 3, 4))
+    >>> y.shape
+    (2, 3, 4)
+    >>> y.shape = (3, 8)
+    >>> y
+    array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])
+    >>> y.shape = (3, 6)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: total size of new array must be unchanged
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('size',
+    """
+    Number of elements in the array.
+
+    Equivalent to ``np.prod(a.shape)``, i.e., the product of the array's
+    dimensions.
+
+    Examples
+    --------
+    >>> x = np.zeros((3, 5, 2), dtype=np.complex128)
+    >>> x.size
+    30
+    >>> np.prod(x.shape)
+    30
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('strides',
+    """
+    Tuple of bytes to step in each dimension when traversing an array.
+
+    The byte offset of element ``(i[0], i[1], ..., i[n])`` in an array `a`
+    is::
+
+        offset = sum(np.array(i) * a.strides)
+
+    A more detailed explanation of strides can be found in the
+    "ndarray.rst" file in the NumPy reference guide.
+
+    Notes
+    -----
+    Imagine an array of 32-bit integers (each 4 bytes)::
+
+      x = np.array([[0, 1, 2, 3, 4],
+                    [5, 6, 7, 8, 9]], dtype=np.int32)
+
+    This array is stored in memory as 40 bytes, one after the other
+    (known as a contiguous block of memory).  The strides of an array tell
+    us how many bytes we have to skip in memory to move to the next position
+    along a certain axis.  For example, we have to skip 4 bytes (1 value) to
+    move to the next column, but 20 bytes (5 values) to get to the same
+    position in the next row.  As such, the strides for the array `x` will be
+    ``(20, 4)``.
+
+    See Also
+    --------
+    numpy.lib.stride_tricks.as_strided
+
+    Examples
+    --------
+    >>> y = np.reshape(np.arange(2*3*4), (2,3,4))
+    >>> y
+    array([[[ 0,  1,  2,  3],
+            [ 4,  5,  6,  7],
+            [ 8,  9, 10, 11]],
+           [[12, 13, 14, 15],
+            [16, 17, 18, 19],
+            [20, 21, 22, 23]]])
+    >>> y.strides
+    (48, 16, 4)
+    >>> y[1,1,1]
+    17
+    >>> offset=sum(y.strides * np.array((1,1,1)))
+    >>> offset/y.itemsize
+    17
+
+    >>> x = np.reshape(np.arange(5*6*7*8), (5,6,7,8)).transpose(2,3,1,0)
+    >>> x.strides
+    (32, 4, 224, 1344)
+    >>> i = np.array([3,5,2,2])
+    >>> offset = sum(i * x.strides)
+    >>> x[3,5,2,2]
+    813
+    >>> offset / x.itemsize
+    813
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('T',
+    """
+    Same as self.transpose(), except that self is returned if
+    self.ndim < 2.
+
+    Examples
+    --------
+    >>> x = np.array([[1.,2.],[3.,4.]])
+    >>> x
+    array([[ 1.,  2.],
+           [ 3.,  4.]])
+    >>> x.T
+    array([[ 1.,  3.],
+           [ 2.,  4.]])
+    >>> x = np.array([1.,2.,3.,4.])
+    >>> x
+    array([ 1.,  2.,  3.,  4.])
+    >>> x.T
+    array([ 1.,  2.,  3.,  4.])
+
+    """))
+
+
+##############################################################################
+#
+# ndarray methods
+#
+##############################################################################
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array__',
+    """ a.__array__(|dtype) -> reference if type unchanged, copy otherwise.
+
+    Returns either a new reference to self if dtype is not given or a new array
+    of provided data type if dtype is different from the current dtype of the
+    array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_prepare__',
+    """a.__array_prepare__(obj) -> Object of same type as ndarray object obj.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_wrap__',
+    """a.__array_wrap__(obj) -> Object of same type as ndarray object a.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__copy__',
+    """a.__copy__([order])
+
+    Return a copy of the array.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A'}, optional
+        If order is 'C' (False) then the result is contiguous (default).
+        If order is 'Fortran' (True) then the result has fortran order.
+        If order is 'Any' (None) then the result has fortran order
+        only if the array already is in fortran order.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__deepcopy__',
+    """a.__deepcopy__() -> Deep copy of array.
+
+    Used if copy.deepcopy is called on an array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__reduce__',
+    """a.__reduce__()
+
+    For pickling.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__setstate__',
+    """a.__setstate__(version, shape, dtype, isfortran, rawdata)
+
+    For unpickling.
+
+    Parameters
+    ----------
+    version : int
+        optional pickle version. If omitted defaults to 0.
+    shape : tuple
+    dtype : data-type
+    isFortran : bool
+    rawdata : string or list
+        a binary string with the data (or a list if 'a' is an object array)
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
+    """
+    a.all(axis=None, out=None, keepdims=False)
+
+    Returns True if all elements evaluate to True.
+
+    Refer to `numpy.all` for full documentation.
+
+    See Also
+    --------
+    numpy.all : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('any',
+    """
+    a.any(axis=None, out=None, keepdims=False)
+
+    Returns True if any of the elements of `a` evaluate to True.
+
+    Refer to `numpy.any` for full documentation.
+
+    See Also
+    --------
+    numpy.any : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmax',
+    """
+    a.argmax(axis=None, out=None)
+
+    Return indices of the maximum values along the given axis.
+
+    Refer to `numpy.argmax` for full documentation.
+
+    See Also
+    --------
+    numpy.argmax : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin',
+    """
+    a.argmin(axis=None, out=None)
+
+    Return indices of the minimum values along the given axis of `a`.
+
+    Refer to `numpy.argmin` for detailed documentation.
+
+    See Also
+    --------
+    numpy.argmin : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort',
+    """
+    a.argsort(axis=-1, kind='quicksort', order=None)
+
+    Returns the indices that would sort this array.
+
+    Refer to `numpy.argsort` for full documentation.
+
+    See Also
+    --------
+    numpy.argsort : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argpartition',
+    """
+    a.argpartition(kth, axis=-1, kind='introselect', order=None)
+
+    Returns the indices that would partition this array.
+
+    Refer to `numpy.argpartition` for full documentation.
+
+    .. versionadded:: 1.8.0
+
+    See Also
+    --------
+    numpy.argpartition : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('astype',
+    """
+    a.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
+
+    Copy of the array, cast to a specified type.
+
+    Parameters
+    ----------
+    dtype : str or dtype
+        Typecode or data-type to which the array is cast.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout order of the result.
+        'C' means C order, 'F' means Fortran order, 'A'
+        means 'F' order if all the arrays are Fortran contiguous,
+        'C' order otherwise, and 'K' means as close to the
+        order the array elements appear in memory as possible.
+        Default is 'K'.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur. Defaults to 'unsafe'
+        for backwards compatibility.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through (default), otherwise
+        the returned array will be forced to be a base-class array.
+    copy : bool, optional
+        By default, astype always returns a newly allocated array. If this
+        is set to false, and the `dtype`, `order`, and `subok`
+        requirements are satisfied, the input array is returned instead
+        of a copy.
+
+    Returns
+    -------
+    arr_t : ndarray
+        Unless `copy` is False and the other conditions for returning the input
+        array are satisfied (see description for `copy` input parameter), `arr_t`
+        is a new array of the same shape as the input array, with dtype, order
+        given by `dtype`, `order`.
+
+    Notes
+    -----
+    Starting in NumPy 1.9, astype method now returns an error if the string
+    dtype to cast to is not long enough in 'safe' casting mode to hold the max
+    value of integer/float array that is being casted. Previously the casting
+    was allowed even if the result was truncated.
+
+    Raises
+    ------
+    ComplexWarning
+        When casting from complex to float or int. To avoid this,
+        one should use ``a.real.astype(t)``.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 2.5])
+    >>> x
+    array([ 1. ,  2. ,  2.5])
+
+    >>> x.astype(int)
+    array([1, 2, 2])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('byteswap',
+    """
+    a.byteswap(inplace)
+
+    Swap the bytes of the array elements
+
+    Toggle between low-endian and big-endian data representation by
+    returning a byteswapped array, optionally swapped in-place.
+
+    Parameters
+    ----------
+    inplace : bool, optional
+        If ``True``, swap bytes in-place, default is ``False``.
+
+    Returns
+    -------
+    out : ndarray
+        The byteswapped array. If `inplace` is ``True``, this is
+        a view to self.
+
+    Examples
+    --------
+    >>> A = np.array([1, 256, 8755], dtype=np.int16)
+    >>> map(hex, A)
+    ['0x1', '0x100', '0x2233']
+    >>> A.byteswap(True)
+    array([  256,     1, 13090], dtype=int16)
+    >>> map(hex, A)
+    ['0x100', '0x1', '0x3322']
+
+    Arrays of strings are not swapped
+
+    >>> A = np.array(['ceg', 'fac'])
+    >>> A.byteswap()
+    array(['ceg', 'fac'],
+          dtype='|S3')
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('choose',
+    """
+    a.choose(choices, out=None, mode='raise')
+
+    Use an index array to construct a new array from a set of choices.
+
+    Refer to `numpy.choose` for full documentation.
+
+    See Also
+    --------
+    numpy.choose : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('clip',
+    """
+    a.clip(min=None, max=None, out=None)
+
+    Return an array whose values are limited to ``[min, max]``.
+    One of max or min must be given.
+
+    Refer to `numpy.clip` for full documentation.
+
+    See Also
+    --------
+    numpy.clip : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('compress',
+    """
+    a.compress(condition, axis=None, out=None)
+
+    Return selected slices of this array along given axis.
+
+    Refer to `numpy.compress` for full documentation.
+
+    See Also
+    --------
+    numpy.compress : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conj',
+    """
+    a.conj()
+
+    Complex-conjugate all elements.
+
+    Refer to `numpy.conjugate` for full documentation.
+
+    See Also
+    --------
+    numpy.conjugate : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conjugate',
+    """
+    a.conjugate()
+
+    Return the complex conjugate, element-wise.
+
+    Refer to `numpy.conjugate` for full documentation.
+
+    See Also
+    --------
+    numpy.conjugate : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('copy',
+    """
+    a.copy(order='C')
+
+    Return a copy of the array.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the copy. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible. (Note that this function and :func:numpy.copy are very
+        similar, but have different default values for their order=
+        arguments.)
+
+    See also
+    --------
+    numpy.copy
+    numpy.copyto
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3],[4,5,6]], order='F')
+
+    >>> y = x.copy()
+
+    >>> x.fill(0)
+
+    >>> x
+    array([[0, 0, 0],
+           [0, 0, 0]])
+
+    >>> y
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    >>> y.flags['C_CONTIGUOUS']
+    True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumprod',
+    """
+    a.cumprod(axis=None, dtype=None, out=None)
+
+    Return the cumulative product of the elements along the given axis.
+
+    Refer to `numpy.cumprod` for full documentation.
+
+    See Also
+    --------
+    numpy.cumprod : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumsum',
+    """
+    a.cumsum(axis=None, dtype=None, out=None)
+
+    Return the cumulative sum of the elements along the given axis.
+
+    Refer to `numpy.cumsum` for full documentation.
+
+    See Also
+    --------
+    numpy.cumsum : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('diagonal',
+    """
+    a.diagonal(offset=0, axis1=0, axis2=1)
+
+    Return specified diagonals. In NumPy 1.9 the returned array is a
+    read-only view instead of a copy as in previous NumPy versions.  In
+    a future version the read-only restriction will be removed.
+
+    Refer to :func:`numpy.diagonal` for full documentation.
+
+    See Also
+    --------
+    numpy.diagonal : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dot',
+    """
+    a.dot(b, out=None)
+
+    Dot product of two arrays.
+
+    Refer to `numpy.dot` for full documentation.
+
+    See Also
+    --------
+    numpy.dot : equivalent function
+
+    Examples
+    --------
+    >>> a = np.eye(2)
+    >>> b = np.ones((2, 2)) * 2
+    >>> a.dot(b)
+    array([[ 2.,  2.],
+           [ 2.,  2.]])
+
+    This array method can be conveniently chained:
+
+    >>> a.dot(b).dot(b)
+    array([[ 8.,  8.],
+           [ 8.,  8.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dump',
+    """a.dump(file)
+
+    Dump a pickle of the array to the specified file.
+    The array can be read back with pickle.load or numpy.load.
+
+    Parameters
+    ----------
+    file : str
+        A string naming the dump file.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dumps',
+    """
+    a.dumps()
+
+    Returns the pickle of the array as a string.
+    pickle.loads or numpy.loads will convert the string back to an array.
+
+    Parameters
+    ----------
+    None
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('fill',
+    """
+    a.fill(value)
+
+    Fill the array with a scalar value.
+
+    Parameters
+    ----------
+    value : scalar
+        All elements of `a` will be assigned this value.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2])
+    >>> a.fill(0)
+    >>> a
+    array([0, 0])
+    >>> a = np.empty(2)
+    >>> a.fill(1)
+    >>> a
+    array([ 1.,  1.])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flatten',
+    """
+    a.flatten(order='C')
+
+    Return a copy of the array collapsed into one dimension.
+
+    Parameters
+    ----------
+    order : {'C', 'F', 'A', 'K'}, optional
+        'C' means to flatten in row-major (C-style) order.
+        'F' means to flatten in column-major (Fortran-
+        style) order. 'A' means to flatten in column-major
+        order if `a` is Fortran *contiguous* in memory,
+        row-major order otherwise. 'K' means to flatten
+        `a` in the order the elements occur in memory.
+        The default is 'C'.
+
+    Returns
+    -------
+    y : ndarray
+        A copy of the input array, flattened to one dimension.
+
+    See Also
+    --------
+    ravel : Return a flattened array.
+    flat : A 1-D flat iterator over the array.
+
+    Examples
+    --------
+    >>> a = np.array([[1,2], [3,4]])
+    >>> a.flatten()
+    array([1, 2, 3, 4])
+    >>> a.flatten('F')
+    array([1, 3, 2, 4])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('getfield',
+    """
+    a.getfield(dtype, offset=0)
+
+    Returns a field of the given array as a certain type.
+
+    A field is a view of the array data with a given data-type. The values in
+    the view are determined by the given type and the offset into the current
+    array in bytes. The offset needs to be such that the view dtype fits in the
+    array dtype; for example an array of dtype complex128 has 16-byte elements.
+    If taking a view with a 32-bit integer (4 bytes), the offset needs to be
+    between 0 and 12 bytes.
+
+    Parameters
+    ----------
+    dtype : str or dtype
+        The data type of the view. The dtype size of the view can not be larger
+        than that of the array itself.
+    offset : int
+        Number of bytes to skip before beginning the element view.
+
+    Examples
+    --------
+    >>> x = np.diag([1.+1.j]*2)
+    >>> x[1, 1] = 2 + 4.j
+    >>> x
+    array([[ 1.+1.j,  0.+0.j],
+           [ 0.+0.j,  2.+4.j]])
+    >>> x.getfield(np.float64)
+    array([[ 1.,  0.],
+           [ 0.,  2.]])
+
+    By choosing an offset of 8 bytes we can select the complex part of the
+    array for our view:
+
+    >>> x.getfield(np.float64, offset=8)
+    array([[ 1.,  0.],
+       [ 0.,  4.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('item',
+    """
+    a.item(*args)
+
+    Copy an element of an array to a standard Python scalar and return it.
+
+    Parameters
+    ----------
+    \\*args : Arguments (variable number and type)
+
+        * none: in this case, the method only works for arrays
+          with one element (`a.size == 1`), which element is
+          copied into a standard Python scalar object and returned.
+
+        * int_type: this argument is interpreted as a flat index into
+          the array, specifying which element to copy and return.
+
+        * tuple of int_types: functions as does a single int_type argument,
+          except that the argument is interpreted as an nd-index into the
+          array.
+
+    Returns
+    -------
+    z : Standard Python scalar object
+        A copy of the specified element of the array as a suitable
+        Python scalar
+
+    Notes
+    -----
+    When the data type of `a` is longdouble or clongdouble, item() returns
+    a scalar array object because there is no available Python scalar that
+    would not lose information. Void arrays return a buffer object for item(),
+    unless fields are defined, in which case a tuple is returned.
+
+    `item` is very similar to a[args], except, instead of an array scalar,
+    a standard Python scalar is returned. This can be useful for speeding up
+    access to elements of the array and doing arithmetic on elements of the
+    array using Python's optimized math.
+
+    Examples
+    --------
+    >>> x = np.random.randint(9, size=(3, 3))
+    >>> x
+    array([[3, 1, 7],
+           [2, 8, 3],
+           [8, 5, 3]])
+    >>> x.item(3)
+    2
+    >>> x.item(7)
+    5
+    >>> x.item((0, 1))
+    1
+    >>> x.item((2, 2))
+    3
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemset',
+    """
+    a.itemset(*args)
+
+    Insert scalar into an array (scalar is cast to array's dtype, if possible)
+
+    There must be at least 1 argument, and define the last argument
+    as *item*.  Then, ``a.itemset(*args)`` is equivalent to but faster
+    than ``a[args] = item``.  The item should be a scalar value and `args`
+    must select a single item in the array `a`.
+
+    Parameters
+    ----------
+    \*args : Arguments
+        If one argument: a scalar, only used in case `a` is of size 1.
+        If two arguments: the last argument is the value to be set
+        and must be a scalar, the first argument specifies a single array
+        element location. It is either an int or a tuple.
+
+    Notes
+    -----
+    Compared to indexing syntax, `itemset` provides some speed increase
+    for placing a scalar into a particular location in an `ndarray`,
+    if you must do this.  However, generally this is discouraged:
+    among other problems, it complicates the appearance of the code.
+    Also, when using `itemset` (and `item`) inside a loop, be sure
+    to assign the methods to a local variable to avoid the attribute
+    look-up at each loop iteration.
+
+    Examples
+    --------
+    >>> x = np.random.randint(9, size=(3, 3))
+    >>> x
+    array([[3, 1, 7],
+           [2, 8, 3],
+           [8, 5, 3]])
+    >>> x.itemset(4, 0)
+    >>> x.itemset((2, 2), 9)
+    >>> x
+    array([[3, 1, 7],
+           [2, 0, 3],
+           [8, 5, 9]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('max',
+    """
+    a.max(axis=None, out=None)
+
+    Return the maximum along a given axis.
+
+    Refer to `numpy.amax` for full documentation.
+
+    See Also
+    --------
+    numpy.amax : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('mean',
+    """
+    a.mean(axis=None, dtype=None, out=None, keepdims=False)
+
+    Returns the average of the array elements along given axis.
+
+    Refer to `numpy.mean` for full documentation.
+
+    See Also
+    --------
+    numpy.mean : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('min',
+    """
+    a.min(axis=None, out=None, keepdims=False)
+
+    Return the minimum along a given axis.
+
+    Refer to `numpy.amin` for full documentation.
+
+    See Also
+    --------
+    numpy.amin : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'shares_memory',
+    """
+    shares_memory(a, b, max_work=None)
+
+    Determine if two arrays share memory
+
+    Parameters
+    ----------
+    a, b : ndarray
+        Input arrays
+    max_work : int, optional
+        Effort to spend on solving the overlap problem (maximum number
+        of candidate solutions to consider). The following special
+        values are recognized:
+
+        max_work=MAY_SHARE_EXACT  (default)
+            The problem is solved exactly. In this case, the function returns
+            True only if there is an element shared between the arrays.
+        max_work=MAY_SHARE_BOUNDS
+            Only the memory bounds of a and b are checked.
+
+    Raises
+    ------
+    numpy.TooHardError
+        Exceeded max_work.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    may_share_memory
+
+    Examples
+    --------
+    >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9]))
+    False
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'may_share_memory',
+    """
+    may_share_memory(a, b, max_work=None)
+
+    Determine if two arrays might share memory
+
+    A return of True does not necessarily mean that the two arrays
+    share any element.  It just means that they *might*.
+
+    Only the memory bounds of a and b are checked by default.
+
+    Parameters
+    ----------
+    a, b : ndarray
+        Input arrays
+    max_work : int, optional
+        Effort to spend on solving the overlap problem.  See
+        `shares_memory` for details.  Default for ``may_share_memory``
+        is to do a bounds check.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    shares_memory
+
+    Examples
+    --------
+    >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9]))
+    False
+    >>> x = np.zeros([3, 4])
+    >>> np.may_share_memory(x[:,0], x[:,1])
+    True
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('newbyteorder',
+    """
+    arr.newbyteorder(new_order='S')
+
+    Return the array with the same data viewed with a different byte order.
+
+    Equivalent to::
+
+        arr.view(arr.dtype.newbytorder(new_order))
+
+    Changes are also made in all fields and sub-arrays of the array data
+    type.
+
+
+
+    Parameters
+    ----------
+    new_order : string, optional
+        Byte order to force; a value from the byte order specifications
+        below. `new_order` codes can be any of:
+
+        * 'S' - swap dtype from current to opposite endian
+        * {'<', 'L'} - little endian
+        * {'>', 'B'} - big endian
+        * {'=', 'N'} - native order
+        * {'|', 'I'} - ignore (no change to byte order)
+
+        The default value ('S') results in swapping the current
+        byte order. The code does a case-insensitive check on the first
+        letter of `new_order` for the alternatives above.  For example,
+        any of 'B' or 'b' or 'biggish' are valid to specify big-endian.
+
+
+    Returns
+    -------
+    new_arr : array
+        New array object with the dtype reflecting given change to the
+        byte order.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nonzero',
+    """
+    a.nonzero()
+
+    Return the indices of the elements that are non-zero.
+
+    Refer to `numpy.nonzero` for full documentation.
+
+    See Also
+    --------
+    numpy.nonzero : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('prod',
+    """
+    a.prod(axis=None, dtype=None, out=None, keepdims=False)
+
+    Return the product of the array elements over the given axis
+
+    Refer to `numpy.prod` for full documentation.
+
+    See Also
+    --------
+    numpy.prod : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ptp',
+    """
+    a.ptp(axis=None, out=None)
+
+    Peak to peak (maximum - minimum) value along a given axis.
+
+    Refer to `numpy.ptp` for full documentation.
+
+    See Also
+    --------
+    numpy.ptp : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('put',
+    """
+    a.put(indices, values, mode='raise')
+
+    Set ``a.flat[n] = values[n]`` for all `n` in indices.
+
+    Refer to `numpy.put` for full documentation.
+
+    See Also
+    --------
+    numpy.put : equivalent function
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'copyto',
+    """
+    copyto(dst, src, casting='same_kind', where=None)
+
+    Copies values from one array to another, broadcasting as necessary.
+
+    Raises a TypeError if the `casting` rule is violated, and if
+    `where` is provided, it selects which elements to copy.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dst : ndarray
+        The array into which values are copied.
+    src : array_like
+        The array from which values are copied.
+    casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+        Controls what kind of data casting may occur when copying.
+
+          * 'no' means the data types should not be cast at all.
+          * 'equiv' means only byte-order changes are allowed.
+          * 'safe' means only casts which can preserve values are allowed.
+          * 'same_kind' means only safe casts or casts within a kind,
+            like float64 to float32, are allowed.
+          * 'unsafe' means any data conversions may be done.
+    where : array_like of bool, optional
+        A boolean array which is broadcasted to match the dimensions
+        of `dst`, and selects elements to copy from `src` to `dst`
+        wherever it contains the value True.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'putmask',
+    """
+    putmask(a, mask, values)
+
+    Changes elements of an array based on conditional and input values.
+
+    Sets ``a.flat[n] = values[n]`` for each n where ``mask.flat[n]==True``.
+
+    If `values` is not the same size as `a` and `mask` then it will repeat.
+    This gives behavior different from ``a[mask] = values``.
+
+    Parameters
+    ----------
+    a : array_like
+        Target array.
+    mask : array_like
+        Boolean mask array. It has to be the same shape as `a`.
+    values : array_like
+        Values to put into `a` where `mask` is True. If `values` is smaller
+        than `a` it will be repeated.
+
+    See Also
+    --------
+    place, put, take, copyto
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2, 3)
+    >>> np.putmask(x, x>2, x**2)
+    >>> x
+    array([[ 0,  1,  2],
+           [ 9, 16, 25]])
+
+    If `values` is smaller than `a` it is repeated:
+
+    >>> x = np.arange(5)
+    >>> np.putmask(x, x>1, [-33, -44])
+    >>> x
+    array([  0,   1, -33, -44, -33])
+
+    """)
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ravel',
+    """
+    a.ravel([order])
+
+    Return a flattened array.
+
+    Refer to `numpy.ravel` for full documentation.
+
+    See Also
+    --------
+    numpy.ravel : equivalent function
+
+    ndarray.flat : a flat iterator on the array.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('repeat',
+    """
+    a.repeat(repeats, axis=None)
+
+    Repeat elements of an array.
+
+    Refer to `numpy.repeat` for full documentation.
+
+    See Also
+    --------
+    numpy.repeat : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('reshape',
+    """
+    a.reshape(shape, order='C')
+
+    Returns an array containing the same data with a new shape.
+
+    Refer to `numpy.reshape` for full documentation.
+
+    See Also
+    --------
+    numpy.reshape : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('resize',
+    """
+    a.resize(new_shape, refcheck=True)
+
+    Change shape and size of array in-place.
+
+    Parameters
+    ----------
+    new_shape : tuple of ints, or `n` ints
+        Shape of resized array.
+    refcheck : bool, optional
+        If False, reference count will not be checked. Default is True.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    ValueError
+        If `a` does not own its own data or references or views to it exist,
+        and the data memory must be changed.
+
+    SystemError
+        If the `order` keyword argument is specified. This behaviour is a
+        bug in NumPy.
+
+    See Also
+    --------
+    resize : Return a new array with the specified shape.
+
+    Notes
+    -----
+    This reallocates space for the data area if necessary.
+
+    Only contiguous arrays (data elements consecutive in memory) can be
+    resized.
+
+    The purpose of the reference count check is to make sure you
+    do not use this array as a buffer for another Python object and then
+    reallocate the memory. However, reference counts can increase in
+    other ways so if you are sure that you have not shared the memory
+    for this array with another Python object, then you may safely set
+    `refcheck` to False.
+
+    Examples
+    --------
+    Shrinking an array: array is flattened (in the order that the data are
+    stored in memory), resized, and reshaped:
+
+    >>> a = np.array([[0, 1], [2, 3]], order='C')
+    >>> a.resize((2, 1))
+    >>> a
+    array([[0],
+           [1]])
+
+    >>> a = np.array([[0, 1], [2, 3]], order='F')
+    >>> a.resize((2, 1))
+    >>> a
+    array([[0],
+           [2]])
+
+    Enlarging an array: as above, but missing entries are filled with zeros:
+
+    >>> b = np.array([[0, 1], [2, 3]])
+    >>> b.resize(2, 3) # new_shape parameter doesn't have to be a tuple
+    >>> b
+    array([[0, 1, 2],
+           [3, 0, 0]])
+
+    Referencing an array prevents resizing...
+
+    >>> c = a
+    >>> a.resize((1, 1))
+    Traceback (most recent call last):
+    ...
+    ValueError: cannot resize an array that has been referenced ...
+
+    Unless `refcheck` is False:
+
+    >>> a.resize((1, 1), refcheck=False)
+    >>> a
+    array([[0]])
+    >>> c
+    array([[0]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('round',
+    """
+    a.round(decimals=0, out=None)
+
+    Return `a` with each element rounded to the given number of decimals.
+
+    Refer to `numpy.around` for full documentation.
+
+    See Also
+    --------
+    numpy.around : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('searchsorted',
+    """
+    a.searchsorted(v, side='left', sorter=None)
+
+    Find indices where elements of v should be inserted in a to maintain order.
+
+    For full documentation, see `numpy.searchsorted`
+
+    See Also
+    --------
+    numpy.searchsorted : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setfield',
+    """
+    a.setfield(val, dtype, offset=0)
+
+    Put a value into a specified place in a field defined by a data-type.
+
+    Place `val` into `a`'s field defined by `dtype` and beginning `offset`
+    bytes into the field.
+
+    Parameters
+    ----------
+    val : object
+        Value to be placed in field.
+    dtype : dtype object
+        Data-type of the field in which to place `val`.
+    offset : int, optional
+        The number of bytes into the field at which to place `val`.
+
+    Returns
+    -------
+    None
+
+    See Also
+    --------
+    getfield
+
+    Examples
+    --------
+    >>> x = np.eye(3)
+    >>> x.getfield(np.float64)
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> x.setfield(3, np.int32)
+    >>> x.getfield(np.int32)
+    array([[3, 3, 3],
+           [3, 3, 3],
+           [3, 3, 3]])
+    >>> x
+    array([[  1.00000000e+000,   1.48219694e-323,   1.48219694e-323],
+           [  1.48219694e-323,   1.00000000e+000,   1.48219694e-323],
+           [  1.48219694e-323,   1.48219694e-323,   1.00000000e+000]])
+    >>> x.setfield(np.eye(3), np.int32)
+    >>> x
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags',
+    """
+    a.setflags(write=None, align=None, uic=None)
+
+    Set array flags WRITEABLE, ALIGNED, and UPDATEIFCOPY, respectively.
+
+    These Boolean-valued flags affect how numpy interprets the memory
+    area used by `a` (see Notes below). The ALIGNED flag can only
+    be set to True if the data is actually aligned according to the type.
+    The UPDATEIFCOPY flag can never be set to True. The flag WRITEABLE
+    can only be set to True if the array owns its own memory, or the
+    ultimate owner of the memory exposes a writeable buffer interface,
+    or is a string. (The exception for string is made so that unpickling
+    can be done without copying memory.)
+
+    Parameters
+    ----------
+    write : bool, optional
+        Describes whether or not `a` can be written to.
+    align : bool, optional
+        Describes whether or not `a` is aligned properly for its type.
+    uic : bool, optional
+        Describes whether or not `a` is a copy of another "base" array.
+
+    Notes
+    -----
+    Array flags provide information about how the memory area used
+    for the array is to be interpreted. There are 6 Boolean flags
+    in use, only three of which can be changed by the user:
+    UPDATEIFCOPY, WRITEABLE, and ALIGNED.
+
+    WRITEABLE (W) the data area can be written to;
+
+    ALIGNED (A) the data and strides are aligned appropriately for the hardware
+    (as determined by the compiler);
+
+    UPDATEIFCOPY (U) this array is a copy of some other array (referenced
+    by .base). When this array is deallocated, the base array will be
+    updated with the contents of this array.
+
+    All flags can be accessed using their first (upper case) letter as well
+    as the full name.
+
+    Examples
+    --------
+    >>> y
+    array([[3, 1, 7],
+           [2, 0, 0],
+           [8, 5, 9]])
+    >>> y.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : True
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+    >>> y.setflags(write=0, align=0)
+    >>> y.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : True
+      WRITEABLE : False
+      ALIGNED : False
+      UPDATEIFCOPY : False
+    >>> y.setflags(uic=1)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: cannot set UPDATEIFCOPY flag to True
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
+    """
+    a.sort(axis=-1, kind='quicksort', order=None)
+
+    Sort an array, in-place.
+
+    Parameters
+    ----------
+    axis : int, optional
+        Axis along which to sort. Default is -1, which means sort along the
+        last axis.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm. Default is 'quicksort'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    See Also
+    --------
+    numpy.sort : Return a sorted copy of an array.
+    argsort : Indirect sort.
+    lexsort : Indirect stable sort on multiple keys.
+    searchsorted : Find elements in sorted array.
+    partition: Partial sort.
+
+    Notes
+    -----
+    See ``sort`` for notes on the different sorting algorithms.
+
+    Examples
+    --------
+    >>> a = np.array([[1,4], [3,1]])
+    >>> a.sort(axis=1)
+    >>> a
+    array([[1, 4],
+           [1, 3]])
+    >>> a.sort(axis=0)
+    >>> a
+    array([[1, 3],
+           [1, 4]])
+
+    Use the `order` keyword to specify a field to use when sorting a
+    structured array:
+
+    >>> a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)])
+    >>> a.sort(order='y')
+    >>> a
+    array([('c', 1), ('a', 2)],
+          dtype=[('x', '|S1'), ('y', '<i4')])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('partition',
+    """
+    a.partition(kth, axis=-1, kind='introselect', order=None)
+
+    Rearranges the elements in the array in such a way that value of the
+    element in kth position is in the position it would be in a sorted array.
+    All elements smaller than the kth element are moved before this element and
+    all equal or greater are moved behind it. The ordering of the elements in
+    the two partitions is undefined.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    kth : int or sequence of ints
+        Element index to partition by. The kth element value will be in its
+        final sorted position and all smaller elements will be moved before it
+        and all equal or greater elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all elements
+        indexed by kth of them into their sorted position at once.
+    axis : int, optional
+        Axis along which to sort. Default is -1, which means sort along the
+        last axis.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    See Also
+    --------
+    numpy.partition : Return a parititioned copy of an array.
+    argpartition : Indirect partition.
+    sort : Full sort.
+
+    Notes
+    -----
+    See ``np.partition`` for notes on the different algorithms.
+
+    Examples
+    --------
+    >>> a = np.array([3, 4, 2, 1])
+    >>> a.partition(a, 3)
+    >>> a
+    array([2, 1, 3, 4])
+
+    >>> a.partition((1, 3))
+    array([1, 2, 3, 4])
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('squeeze',
+    """
+    a.squeeze(axis=None)
+
+    Remove single-dimensional entries from the shape of `a`.
+
+    Refer to `numpy.squeeze` for full documentation.
+
+    See Also
+    --------
+    numpy.squeeze : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('std',
+    """
+    a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+
+    Returns the standard deviation of the array elements along given axis.
+
+    Refer to `numpy.std` for full documentation.
+
+    See Also
+    --------
+    numpy.std : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sum',
+    """
+    a.sum(axis=None, dtype=None, out=None, keepdims=False)
+
+    Return the sum of the array elements over the given axis.
+
+    Refer to `numpy.sum` for full documentation.
+
+    See Also
+    --------
+    numpy.sum : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('swapaxes',
+    """
+    a.swapaxes(axis1, axis2)
+
+    Return a view of the array with `axis1` and `axis2` interchanged.
+
+    Refer to `numpy.swapaxes` for full documentation.
+
+    See Also
+    --------
+    numpy.swapaxes : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('take',
+    """
+    a.take(indices, axis=None, out=None, mode='raise')
+
+    Return an array formed from the elements of `a` at the given indices.
+
+    Refer to `numpy.take` for full documentation.
+
+    See Also
+    --------
+    numpy.take : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile',
+    """
+    a.tofile(fid, sep="", format="%s")
+
+    Write array to a file as text or binary (default).
+
+    Data is always written in 'C' order, independent of the order of `a`.
+    The data produced by this method can be recovered using the function
+    fromfile().
+
+    Parameters
+    ----------
+    fid : file or str
+        An open file object, or a string containing a filename.
+    sep : str
+        Separator between array items for text output.
+        If "" (empty), a binary file is written, equivalent to
+        ``file.write(a.tobytes())``.
+    format : str
+        Format string for text file output.
+        Each entry in the array is formatted to text by first converting
+        it to the closest Python type, and then using "format" % item.
+
+    Notes
+    -----
+    This is a convenience function for quick storage of array data.
+    Information on endianness and precision is lost, so this method is not a
+    good choice for files intended to archive data or transport data between
+    machines with different endianness. Some of these problems can be overcome
+    by outputting the data as text files, at the expense of speed and file
+    size.
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tolist',
+    """
+    a.tolist()
+
+    Return the array as a (possibly nested) list.
+
+    Return a copy of the array data as a (nested) Python list.
+    Data items are converted to the nearest compatible Python type.
+
+    Parameters
+    ----------
+    none
+
+    Returns
+    -------
+    y : list
+        The possibly nested list of array elements.
+
+    Notes
+    -----
+    The array may be recreated, ``a = np.array(a.tolist())``.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2])
+    >>> a.tolist()
+    [1, 2]
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> list(a)
+    [array([1, 2]), array([3, 4])]
+    >>> a.tolist()
+    [[1, 2], [3, 4]]
+
+    """))
+
+
+tobytesdoc = """
+    a.{name}(order='C')
+
+    Construct Python bytes containing the raw data bytes in the array.
+
+    Constructs Python bytes showing a copy of the raw contents of
+    data memory. The bytes object can be produced in either 'C' or 'Fortran',
+    or 'Any' order (the default is 'C'-order). 'Any' order means C-order
+    unless the F_CONTIGUOUS flag in the array is set, in which case it
+    means 'Fortran' order.
+
+    {deprecated}
+
+    Parameters
+    ----------
+    order : {{'C', 'F', None}}, optional
+        Order of the data for multidimensional arrays:
+        C, Fortran, or the same as for the original array.
+
+    Returns
+    -------
+    s : bytes
+        Python bytes exhibiting a copy of `a`'s raw data.
+
+    Examples
+    --------
+    >>> x = np.array([[0, 1], [2, 3]])
+    >>> x.tobytes()
+    b'\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+    >>> x.tobytes('C') == x.tobytes()
+    True
+    >>> x.tobytes('F')
+    b'\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+
+    """
+
+add_newdoc('numpy.core.multiarray', 'ndarray',
+           ('tostring', tobytesdoc.format(name='tostring',
+                                          deprecated=
+                                          'This function is a compatibility '
+                                          'alias for tobytes. Despite its '
+                                          'name it returns bytes not '
+                                          'strings.')))
+add_newdoc('numpy.core.multiarray', 'ndarray',
+           ('tobytes', tobytesdoc.format(name='tobytes',
+                                         deprecated='.. versionadded:: 1.9.0')))
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('trace',
+    """
+    a.trace(offset=0, axis1=0, axis2=1, dtype=None, out=None)
+
+    Return the sum along diagonals of the array.
+
+    Refer to `numpy.trace` for full documentation.
+
+    See Also
+    --------
+    numpy.trace : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose',
+    """
+    a.transpose(*axes)
+
+    Returns a view of the array with axes transposed.
+
+    For a 1-D array, this has no effect. (To change between column and
+    row vectors, first cast the 1-D array into a matrix object.)
+    For a 2-D array, this is the usual matrix transpose.
+    For an n-D array, if axes are given, their order indicates how the
+    axes are permuted (see Examples). If axes are not provided and
+    ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then
+    ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``.
+
+    Parameters
+    ----------
+    axes : None, tuple of ints, or `n` ints
+
+     * None or no argument: reverses the order of the axes.
+
+     * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s
+       `i`-th axis becomes `a.transpose()`'s `j`-th axis.
+
+     * `n` ints: same as an n-tuple of the same ints (this form is
+       intended simply as a "convenience" alternative to the tuple form)
+
+    Returns
+    -------
+    out : ndarray
+        View of `a`, with axes suitably permuted.
+
+    See Also
+    --------
+    ndarray.T : Array property returning the array transposed.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> a
+    array([[1, 2],
+           [3, 4]])
+    >>> a.transpose()
+    array([[1, 3],
+           [2, 4]])
+    >>> a.transpose((1, 0))
+    array([[1, 3],
+           [2, 4]])
+    >>> a.transpose(1, 0)
+    array([[1, 3],
+           [2, 4]])
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('var',
+    """
+    a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+
+    Returns the variance of the array elements, along given axis.
+
+    Refer to `numpy.var` for full documentation.
+
+    See Also
+    --------
+    numpy.var : equivalent function
+
+    """))
+
+
+add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
+    """
+    a.view(dtype=None, type=None)
+
+    New view of array with the same data.
+
+    Parameters
+    ----------
+    dtype : data-type or ndarray sub-class, optional
+        Data-type descriptor of the returned view, e.g., float32 or int16. The
+        default, None, results in the view having the same data-type as `a`.
+        This argument can also be specified as an ndarray sub-class, which
+        then specifies the type of the returned object (this is equivalent to
+        setting the ``type`` parameter).
+    type : Python type, optional
+        Type of the returned view, e.g., ndarray or matrix.  Again, the
+        default None results in type preservation.
+
+    Notes
+    -----
+    ``a.view()`` is used two different ways:
+
+    ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
+    of the array's memory with a different data-type.  This can cause a
+    reinterpretation of the bytes of memory.
+
+    ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
+    returns an instance of `ndarray_subclass` that looks at the same array
+    (same shape, dtype, etc.)  This does not cause a reinterpretation of the
+    memory.
+
+    For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
+    bytes per entry than the previous dtype (for example, converting a
+    regular array to a structured array), then the behavior of the view
+    cannot be predicted just from the superficial appearance of ``a`` (shown
+    by ``print(a)``). It also depends on exactly how ``a`` is stored in
+    memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
+    defined as a slice or transpose, etc., the view may give different
+    results.
+
+
+    Examples
+    --------
+    >>> x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
+
+    Viewing array data using a different type and dtype:
+
+    >>> y = x.view(dtype=np.int16, type=np.matrix)
+    >>> y
+    matrix([[513]], dtype=int16)
+    >>> print(type(y))
+    <class 'numpy.matrixlib.defmatrix.matrix'>
+
+    Creating a view on a structured array so it can be used in calculations
+
+    >>> x = np.array([(1, 2),(3,4)], dtype=[('a', np.int8), ('b', np.int8)])
+    >>> xv = x.view(dtype=np.int8).reshape(-1,2)
+    >>> xv
+    array([[1, 2],
+           [3, 4]], dtype=int8)
+    >>> xv.mean(0)
+    array([ 2.,  3.])
+
+    Making changes to the view changes the underlying array
+
+    >>> xv[0,1] = 20
+    >>> print(x)
+    [(1, 20) (3, 4)]
+
+    Using a view to convert an array to a recarray:
+
+    >>> z = x.view(np.recarray)
+    >>> z.a
+    array([1], dtype=int8)
+
+    Views share data:
+
+    >>> x[0] = (9, 10)
+    >>> z[0]
+    (9, 10)
+
+    Views that change the dtype size (bytes per entry) should normally be
+    avoided on arrays defined by slices, transposes, fortran-ordering, etc.:
+
+    >>> x = np.array([[1,2,3],[4,5,6]], dtype=np.int16)
+    >>> y = x[:, 0:2]
+    >>> y
+    array([[1, 2],
+           [4, 5]], dtype=int16)
+    >>> y.view(dtype=[('width', np.int16), ('length', np.int16)])
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ValueError: new type not compatible with array.
+    >>> z = y.copy()
+    >>> z.view(dtype=[('width', np.int16), ('length', np.int16)])
+    array([[(1, 2)],
+           [(4, 5)]], dtype=[('width', '<i2'), ('length', '<i2')])
+    """))
+
+
+##############################################################################
+#
+# umath functions
+#
+##############################################################################
+
+add_newdoc('numpy.core.umath', 'frompyfunc',
+    """
+    frompyfunc(func, nin, nout)
+
+    Takes an arbitrary Python function and returns a Numpy ufunc.
+
+    Can be used, for example, to add broadcasting to a built-in Python
+    function (see Examples section).
+
+    Parameters
+    ----------
+    func : Python function object
+        An arbitrary Python function.
+    nin : int
+        The number of input arguments.
+    nout : int
+        The number of objects returned by `func`.
+
+    Returns
+    -------
+    out : ufunc
+        Returns a Numpy universal function (``ufunc``) object.
+
+    Notes
+    -----
+    The returned ufunc always returns PyObject arrays.
+
+    Examples
+    --------
+    Use frompyfunc to add broadcasting to the Python function ``oct``:
+
+    >>> oct_array = np.frompyfunc(oct, 1, 1)
+    >>> oct_array(np.array((10, 30, 100)))
+    array([012, 036, 0144], dtype=object)
+    >>> np.array((oct(10), oct(30), oct(100))) # for comparison
+    array(['012', '036', '0144'],
+          dtype='|S4')
+
+    """)
+
+add_newdoc('numpy.core.umath', 'geterrobj',
+    """
+    geterrobj()
+
+    Return the current object that defines floating-point error handling.
+
+    The error object contains all information that defines the error handling
+    behavior in Numpy. `geterrobj` is used internally by the other
+    functions that get and set error handling behavior (`geterr`, `seterr`,
+    `geterrcall`, `seterrcall`).
+
+    Returns
+    -------
+    errobj : list
+        The error object, a list containing three elements:
+        [internal numpy buffer size, error mask, error callback function].
+
+        The error mask is a single integer that holds the treatment information
+        on all four floating point errors. The information for each error type
+        is contained in three bits of the integer. If we print it in base 8, we
+        can see what treatment is set for "invalid", "under", "over", and
+        "divide" (in that order). The printed string can be interpreted with
+
+        * 0 : 'ignore'
+        * 1 : 'warn'
+        * 2 : 'raise'
+        * 3 : 'call'
+        * 4 : 'print'
+        * 5 : 'log'
+
+    See Also
+    --------
+    seterrobj, seterr, geterr, seterrcall, geterrcall
+    getbufsize, setbufsize
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterrobj()  # first get the defaults
+    [10000, 0, None]
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+    >>> old_bufsize = np.setbufsize(20000)
+    >>> old_err = np.seterr(divide='raise')
+    >>> old_handler = np.seterrcall(err_handler)
+    >>> np.geterrobj()
+    [20000, 2, <function err_handler at 0x91dcaac>]
+
+    >>> old_err = np.seterr(all='ignore')
+    >>> np.base_repr(np.geterrobj()[1], 8)
+    '0'
+    >>> old_err = np.seterr(divide='warn', over='log', under='call',
+                            invalid='print')
+    >>> np.base_repr(np.geterrobj()[1], 8)
+    '4351'
+
+    """)
+
+add_newdoc('numpy.core.umath', 'seterrobj',
+    """
+    seterrobj(errobj)
+
+    Set the object that defines floating-point error handling.
+
+    The error object contains all information that defines the error handling
+    behavior in Numpy. `seterrobj` is used internally by the other
+    functions that set error handling behavior (`seterr`, `seterrcall`).
+
+    Parameters
+    ----------
+    errobj : list
+        The error object, a list containing three elements:
+        [internal numpy buffer size, error mask, error callback function].
+
+        The error mask is a single integer that holds the treatment information
+        on all four floating point errors. The information for each error type
+        is contained in three bits of the integer. If we print it in base 8, we
+        can see what treatment is set for "invalid", "under", "over", and
+        "divide" (in that order). The printed string can be interpreted with
+
+        * 0 : 'ignore'
+        * 1 : 'warn'
+        * 2 : 'raise'
+        * 3 : 'call'
+        * 4 : 'print'
+        * 5 : 'log'
+
+    See Also
+    --------
+    geterrobj, seterr, geterr, seterrcall, geterrcall
+    getbufsize, setbufsize
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> old_errobj = np.geterrobj()  # first get the defaults
+    >>> old_errobj
+    [10000, 0, None]
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+    >>> new_errobj = [20000, 12, err_handler]
+    >>> np.seterrobj(new_errobj)
+    >>> np.base_repr(12, 8)  # int for divide=4 ('print') and over=1 ('warn')
+    '14'
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'print', 'invalid': 'ignore', 'under': 'ignore'}
+    >>> np.geterrcall() is err_handler
+    True
+
+    """)
+
+
+##############################################################################
+#
+# compiled_base functions
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'digitize',
+    """
+    digitize(x, bins, right=False)
+
+    Return the indices of the bins to which each value in input array belongs.
+
+    Each index ``i`` returned is such that ``bins[i-1] <= x < bins[i]`` if
+    `bins` is monotonically increasing, or ``bins[i-1] > x >= bins[i]`` if
+    `bins` is monotonically decreasing. If values in `x` are beyond the
+    bounds of `bins`, 0 or ``len(bins)`` is returned as appropriate. If right
+    is True, then the right bin is closed so that the index ``i`` is such
+    that ``bins[i-1] < x <= bins[i]`` or bins[i-1] >= x > bins[i]`` if `bins`
+    is monotonically increasing or decreasing, respectively.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array to be binned. Prior to Numpy 1.10.0, this array had to
+        be 1-dimensional, but can now have any shape.
+    bins : array_like
+        Array of bins. It has to be 1-dimensional and monotonic.
+    right : bool, optional
+        Indicating whether the intervals include the right or the left bin
+        edge. Default behavior is (right==False) indicating that the interval
+        does not include the right edge. The left bin end is open in this
+        case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
+        monotonically increasing bins.
+
+    Returns
+    -------
+    out : ndarray of ints
+        Output array of indices, of same shape as `x`.
+
+    Raises
+    ------
+    ValueError
+        If `bins` is not monotonic.
+    TypeError
+        If the type of the input is complex.
+
+    See Also
+    --------
+    bincount, histogram, unique
+
+    Notes
+    -----
+    If values in `x` are such that they fall outside the bin range,
+    attempting to index `bins` with the indices that `digitize` returns
+    will result in an IndexError.
+
+    .. versionadded:: 1.10.0
+
+    `np.digitize` is  implemented in terms of `np.searchsorted`. This means
+    that a binary search is used to bin the values, which scales much better
+    for larger number of bins than the previous linear search. It also removes
+    the requirement for the input array to be 1-dimensional.
+
+    Examples
+    --------
+    >>> x = np.array([0.2, 6.4, 3.0, 1.6])
+    >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
+    >>> inds = np.digitize(x, bins)
+    >>> inds
+    array([1, 4, 3, 2])
+    >>> for n in range(x.size):
+    ...   print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
+    ...
+    0.0 <= 0.2 < 1.0
+    4.0 <= 6.4 < 10.0
+    2.5 <= 3.0 < 4.0
+    1.0 <= 1.6 < 2.5
+
+    >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
+    >>> bins = np.array([0, 5, 10, 15, 20])
+    >>> np.digitize(x,bins,right=True)
+    array([1, 2, 3, 4, 4])
+    >>> np.digitize(x,bins,right=False)
+    array([1, 3, 3, 4, 5])
+    """)
+
+add_newdoc('numpy.core.multiarray', 'bincount',
+    """
+    bincount(x, weights=None, minlength=None)
+
+    Count number of occurrences of each value in array of non-negative ints.
+
+    The number of bins (of size 1) is one larger than the largest value in
+    `x`. If `minlength` is specified, there will be at least this number
+    of bins in the output array (though it will be longer if necessary,
+    depending on the contents of `x`).
+    Each bin gives the number of occurrences of its index value in `x`.
+    If `weights` is specified the input array is weighted by it, i.e. if a
+    value ``n`` is found at position ``i``, ``out[n] += weight[i]`` instead
+    of ``out[n] += 1``.
+
+    Parameters
+    ----------
+    x : array_like, 1 dimension, nonnegative ints
+        Input array.
+    weights : array_like, optional
+        Weights, array of the same shape as `x`.
+    minlength : int, optional
+        A minimum number of bins for the output array.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    out : ndarray of ints
+        The result of binning the input array.
+        The length of `out` is equal to ``np.amax(x)+1``.
+
+    Raises
+    ------
+    ValueError
+        If the input is not 1-dimensional, or contains elements with negative
+        values, or if `minlength` is non-positive.
+    TypeError
+        If the type of the input is float or complex.
+
+    See Also
+    --------
+    histogram, digitize, unique
+
+    Examples
+    --------
+    >>> np.bincount(np.arange(5))
+    array([1, 1, 1, 1, 1])
+    >>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
+    array([1, 3, 1, 1, 0, 0, 0, 1])
+
+    >>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23])
+    >>> np.bincount(x).size == np.amax(x)+1
+    True
+
+    The input array needs to be of integer dtype, otherwise a
+    TypeError is raised:
+
+    >>> np.bincount(np.arange(5, dtype=np.float))
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    TypeError: array cannot be safely cast to required type
+
+    A possible use of ``bincount`` is to perform sums over
+    variable-size chunks of an array, using the ``weights`` keyword.
+
+    >>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights
+    >>> x = np.array([0, 1, 1, 2, 2, 2])
+    >>> np.bincount(x,  weights=w)
+    array([ 0.3,  0.7,  1.1])
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'ravel_multi_index',
+    """
+    ravel_multi_index(multi_index, dims, mode='raise', order='C')
+
+    Converts a tuple of index arrays into an array of flat
+    indices, applying boundary modes to the multi-index.
+
+    Parameters
+    ----------
+    multi_index : tuple of array_like
+        A tuple of integer arrays, one array for each dimension.
+    dims : tuple of ints
+        The shape of array into which the indices from ``multi_index`` apply.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices are handled.  Can specify
+        either one mode or a tuple of modes, one mode per index.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        In 'clip' mode, a negative index which would normally
+        wrap will clip to 0 instead.
+    order : {'C', 'F'}, optional
+        Determines whether the multi-index should be viewed as
+        indexing in row-major (C-style) or column-major
+        (Fortran-style) order.
+
+    Returns
+    -------
+    raveled_indices : ndarray
+        An array of indices into the flattened version of an array
+        of dimensions ``dims``.
+
+    See Also
+    --------
+    unravel_index
+
+    Notes
+    -----
+    .. versionadded:: 1.6.0
+
+    Examples
+    --------
+    >>> arr = np.array([[3,6,6],[4,5,1]])
+    >>> np.ravel_multi_index(arr, (7,6))
+    array([22, 41, 37])
+    >>> np.ravel_multi_index(arr, (7,6), order='F')
+    array([31, 41, 13])
+    >>> np.ravel_multi_index(arr, (4,6), mode='clip')
+    array([22, 23, 19])
+    >>> np.ravel_multi_index(arr, (4,4), mode=('clip','wrap'))
+    array([12, 13, 13])
+
+    >>> np.ravel_multi_index((3,1,4,1), (6,7,8,9))
+    1621
+    """)
+
+add_newdoc('numpy.core.multiarray', 'unravel_index',
+    """
+    unravel_index(indices, dims, order='C')
+
+    Converts a flat index or array of flat indices into a tuple
+    of coordinate arrays.
+
+    Parameters
+    ----------
+    indices : array_like
+        An integer array whose elements are indices into the flattened
+        version of an array of dimensions ``dims``. Before version 1.6.0,
+        this function accepted just one index value.
+    dims : tuple of ints
+        The shape of the array to use for unraveling ``indices``.
+    order : {'C', 'F'}, optional
+        Determines whether the indices should be viewed as indexing in
+        row-major (C-style) or column-major (Fortran-style) order.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    unraveled_coords : tuple of ndarray
+        Each array in the tuple has the same shape as the ``indices``
+        array.
+
+    See Also
+    --------
+    ravel_multi_index
+
+    Examples
+    --------
+    >>> np.unravel_index([22, 41, 37], (7,6))
+    (array([3, 6, 6]), array([4, 5, 1]))
+    >>> np.unravel_index([31, 41, 13], (7,6), order='F')
+    (array([3, 6, 6]), array([4, 5, 1]))
+
+    >>> np.unravel_index(1621, (6,7,8,9))
+    (3, 1, 4, 1)
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'add_docstring',
+    """
+    add_docstring(obj, docstring)
+
+    Add a docstring to a built-in obj if possible.
+    If the obj already has a docstring raise a RuntimeError
+    If this routine does not know how to add a docstring to the object
+    raise a TypeError
+    """)
+
+add_newdoc('numpy.core.umath', '_add_newdoc_ufunc',
+    """
+    add_ufunc_docstring(ufunc, new_docstring)
+
+    Replace the docstring for a ufunc with new_docstring.
+    This method will only work if the current docstring for
+    the ufunc is NULL. (At the C level, i.e. when ufunc->doc is NULL.)
+
+    Parameters
+    ----------
+    ufunc : numpy.ufunc
+        A ufunc whose current doc is NULL.
+    new_docstring : string
+        The new docstring for the ufunc.
+
+    Notes
+    -----
+    This method allocates memory for new_docstring on
+    the heap. Technically this creates a mempory leak, since this
+    memory will not be reclaimed until the end of the program
+    even if the ufunc itself is removed. However this will only
+    be a problem if the user is repeatedly creating ufuncs with
+    no documentation, adding documentation via add_newdoc_ufunc,
+    and then throwing away the ufunc.
+    """)
+
+add_newdoc('numpy.core.multiarray', 'packbits',
+    """
+    packbits(myarray, axis=None)
+
+    Packs the elements of a binary-valued array into bits in a uint8 array.
+
+    The result is padded to full bytes by inserting zero bits at the end.
+
+    Parameters
+    ----------
+    myarray : array_like
+        An integer type array whose elements should be packed to bits.
+    axis : int, optional
+        The dimension over which bit-packing is done.
+        ``None`` implies packing the flattened array.
+
+    Returns
+    -------
+    packed : ndarray
+        Array of type uint8 whose elements represent bits corresponding to the
+        logical (0 or nonzero) value of the input elements. The shape of
+        `packed` has the same number of dimensions as the input (unless `axis`
+        is None, in which case the output is 1-D).
+
+    See Also
+    --------
+    unpackbits: Unpacks elements of a uint8 array into a binary-valued output
+                array.
+
+    Examples
+    --------
+    >>> a = np.array([[[1,0,1],
+    ...                [0,1,0]],
+    ...               [[1,1,0],
+    ...                [0,0,1]]])
+    >>> b = np.packbits(a, axis=-1)
+    >>> b
+    array([[[160],[64]],[[192],[32]]], dtype=uint8)
+
+    Note that in binary 160 = 1010 0000, 64 = 0100 0000, 192 = 1100 0000,
+    and 32 = 0010 0000.
+
+    """)
+
+add_newdoc('numpy.core.multiarray', 'unpackbits',
+    """
+    unpackbits(myarray, axis=None)
+
+    Unpacks elements of a uint8 array into a binary-valued output array.
+
+    Each element of `myarray` represents a bit-field that should be unpacked
+    into a binary-valued output array. The shape of the output array is either
+    1-D (if `axis` is None) or the same shape as the input array with unpacking
+    done along the axis specified.
+
+    Parameters
+    ----------
+    myarray : ndarray, uint8 type
+       Input array.
+    axis : int, optional
+       Unpacks along this axis.
+
+    Returns
+    -------
+    unpacked : ndarray, uint8 type
+       The elements are binary-valued (0 or 1).
+
+    See Also
+    --------
+    packbits : Packs the elements of a binary-valued array into bits in a uint8
+               array.
+
+    Examples
+    --------
+    >>> a = np.array([[2], [7], [23]], dtype=np.uint8)
+    >>> a
+    array([[ 2],
+           [ 7],
+           [23]], dtype=uint8)
+    >>> b = np.unpackbits(a, axis=1)
+    >>> b
+    array([[0, 0, 0, 0, 0, 0, 1, 0],
+           [0, 0, 0, 0, 0, 1, 1, 1],
+           [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for ufunc attributes and methods
+#
+##############################################################################
+
+
+##############################################################################
+#
+# ufunc object
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc',
+    """
+    Functions that operate element by element on whole arrays.
+
+    To see the documentation for a specific ufunc, use np.info().  For
+    example, np.info(np.sin).  Because ufuncs are written in C
+    (for speed) and linked into Python with NumPy's ufunc facility,
+    Python's help() function finds this page whenever help() is called
+    on a ufunc.
+
+    A detailed explanation of ufuncs can be found in the "ufuncs.rst"
+    file in the NumPy reference guide.
+
+    Unary ufuncs:
+    =============
+
+    op(X, out=None)
+    Apply op to X elementwise
+
+    Parameters
+    ----------
+    X : array_like
+        Input array.
+    out : array_like
+        An array to store the output. Must be the same shape as `X`.
+
+    Returns
+    -------
+    r : array_like
+        `r` will have the same shape as `X`; if out is provided, `r`
+        will be equal to out.
+
+    Binary ufuncs:
+    ==============
+
+    op(X, Y, out=None)
+    Apply `op` to `X` and `Y` elementwise. May "broadcast" to make
+    the shapes of `X` and `Y` congruent.
+
+    The broadcasting rules are:
+
+    * Dimensions of length 1 may be prepended to either array.
+    * Arrays may be repeated along dimensions of length 1.
+
+    Parameters
+    ----------
+    X : array_like
+        First input array.
+    Y : array_like
+        Second input array.
+    out : array_like
+        An array to store the output. Must be the same shape as the
+        output would have.
+
+    Returns
+    -------
+    r : array_like
+        The return value; if out is provided, `r` will be equal to out.
+
+    """)
+
+
+##############################################################################
+#
+# ufunc attributes
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc', ('identity',
+    """
+    The identity value.
+
+    Data attribute containing the identity element for the ufunc, if it has one.
+    If it does not, the attribute value is None.
+
+    Examples
+    --------
+    >>> np.add.identity
+    0
+    >>> np.multiply.identity
+    1
+    >>> np.power.identity
+    1
+    >>> print(np.exp.identity)
+    None
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nargs',
+    """
+    The number of arguments.
+
+    Data attribute containing the number of arguments the ufunc takes, including
+    optional ones.
+
+    Notes
+    -----
+    Typically this value will be one more than what you might expect because all
+    ufuncs take  the optional "out" argument.
+
+    Examples
+    --------
+    >>> np.add.nargs
+    3
+    >>> np.multiply.nargs
+    3
+    >>> np.power.nargs
+    3
+    >>> np.exp.nargs
+    2
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nin',
+    """
+    The number of inputs.
+
+    Data attribute containing the number of arguments the ufunc treats as input.
+
+    Examples
+    --------
+    >>> np.add.nin
+    2
+    >>> np.multiply.nin
+    2
+    >>> np.power.nin
+    2
+    >>> np.exp.nin
+    1
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('nout',
+    """
+    The number of outputs.
+
+    Data attribute containing the number of arguments the ufunc treats as output.
+
+    Notes
+    -----
+    Since all ufuncs can take output arguments, this will always be (at least) 1.
+
+    Examples
+    --------
+    >>> np.add.nout
+    1
+    >>> np.multiply.nout
+    1
+    >>> np.power.nout
+    1
+    >>> np.exp.nout
+    1
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('ntypes',
+    """
+    The number of types.
+
+    The number of numerical NumPy types - of which there are 18 total - on which
+    the ufunc can operate.
+
+    See Also
+    --------
+    numpy.ufunc.types
+
+    Examples
+    --------
+    >>> np.add.ntypes
+    18
+    >>> np.multiply.ntypes
+    18
+    >>> np.power.ntypes
+    17
+    >>> np.exp.ntypes
+    7
+    >>> np.remainder.ntypes
+    14
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('types',
+    """
+    Returns a list with types grouped input->output.
+
+    Data attribute listing the data-type "Domain-Range" groupings the ufunc can
+    deliver. The data-types are given using the character codes.
+
+    See Also
+    --------
+    numpy.ufunc.ntypes
+
+    Examples
+    --------
+    >>> np.add.types
+    ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l',
+    'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D',
+    'GG->G', 'OO->O']
+
+    >>> np.multiply.types
+    ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l',
+    'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D',
+    'GG->G', 'OO->O']
+
+    >>> np.power.types
+    ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
+    'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G',
+    'OO->O']
+
+    >>> np.exp.types
+    ['f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O']
+
+    >>> np.remainder.types
+    ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
+    'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'OO->O']
+
+    """))
+
+
+##############################################################################
+#
+# ufunc methods
+#
+##############################################################################
+
+add_newdoc('numpy.core', 'ufunc', ('reduce',
+    """
+    reduce(a, axis=0, dtype=None, out=None, keepdims=False)
+
+    Reduces `a`'s dimension by one, by applying ufunc along one axis.
+
+    Let :math:`a.shape = (N_0, ..., N_i, ..., N_{M-1})`.  Then
+    :math:`ufunc.reduce(a, axis=i)[k_0, ..,k_{i-1}, k_{i+1}, .., k_{M-1}]` =
+    the result of iterating `j` over :math:`range(N_i)`, cumulatively applying
+    ufunc to each :math:`a[k_0, ..,k_{i-1}, j, k_{i+1}, .., k_{M-1}]`.
+    For a one-dimensional array, reduce produces results equivalent to:
+    ::
+
+     r = op.identity # op = ufunc
+     for i in range(len(A)):
+       r = op(r, A[i])
+     return r
+
+    For example, add.reduce() is equivalent to sum().
+
+    Parameters
+    ----------
+    a : array_like
+        The array to act on.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a reduction is performed.
+        The default (`axis` = 0) is perform a reduction over the first
+        dimension of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is `None`, a reduction is performed over all the axes.
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+
+        For operations which are either not commutative or not associative,
+        doing a reduction over multiple axes is not well-defined. The
+        ufuncs do not currently raise an exception in this case, but will
+        likely do so in the future.
+    dtype : data-type code, optional
+        The type used to represent the intermediate results. Defaults
+        to the data-type of the output array if this is provided, or
+        the data-type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided, a
+        freshly-allocated array is returned.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    r : ndarray
+        The reduced array. If `out` was supplied, `r` is a reference to it.
+
+    Examples
+    --------
+    >>> np.multiply.reduce([2,3,5])
+    30
+
+    A multi-dimensional array example:
+
+    >>> X = np.arange(8).reshape((2,2,2))
+    >>> X
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+    >>> np.add.reduce(X, 0)
+    array([[ 4,  6],
+           [ 8, 10]])
+    >>> np.add.reduce(X) # confirm: default axis value is 0
+    array([[ 4,  6],
+           [ 8, 10]])
+    >>> np.add.reduce(X, 1)
+    array([[ 2,  4],
+           [10, 12]])
+    >>> np.add.reduce(X, 2)
+    array([[ 1,  5],
+           [ 9, 13]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('accumulate',
+    """
+    accumulate(array, axis=0, dtype=None, out=None)
+
+    Accumulate the result of applying the operator to all elements.
+
+    For a one-dimensional array, accumulate produces results equivalent to::
+
+      r = np.empty(len(A))
+      t = op.identity        # op = the ufunc being applied to A's  elements
+      for i in range(len(A)):
+          t = op(t, A[i])
+          r[i] = t
+      return r
+
+    For example, add.accumulate() is equivalent to np.cumsum().
+
+    For a multi-dimensional array, accumulate is applied along only one
+    axis (axis zero by default; see Examples below) so repeated use is
+    necessary if one wants to accumulate over multiple axes.
+
+    Parameters
+    ----------
+    array : array_like
+        The array to act on.
+    axis : int, optional
+        The axis along which to apply the accumulation; default is zero.
+    dtype : data-type code, optional
+        The data-type used to represent the intermediate results. Defaults
+        to the data-type of the output array if such is provided, or the
+        the data-type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided a
+        freshly-allocated array is returned.
+
+    Returns
+    -------
+    r : ndarray
+        The accumulated values. If `out` was supplied, `r` is a reference to
+        `out`.
+
+    Examples
+    --------
+    1-D array examples:
+
+    >>> np.add.accumulate([2, 3, 5])
+    array([ 2,  5, 10])
+    >>> np.multiply.accumulate([2, 3, 5])
+    array([ 2,  6, 30])
+
+    2-D array examples:
+
+    >>> I = np.eye(2)
+    >>> I
+    array([[ 1.,  0.],
+           [ 0.,  1.]])
+
+    Accumulate along axis 0 (rows), down columns:
+
+    >>> np.add.accumulate(I, 0)
+    array([[ 1.,  0.],
+           [ 1.,  1.]])
+    >>> np.add.accumulate(I) # no axis specified = axis zero
+    array([[ 1.,  0.],
+           [ 1.,  1.]])
+
+    Accumulate along axis 1 (columns), through rows:
+
+    >>> np.add.accumulate(I, 1)
+    array([[ 1.,  1.],
+           [ 0.,  1.]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('reduceat',
+    """
+    reduceat(a, indices, axis=0, dtype=None, out=None)
+
+    Performs a (local) reduce with specified slices over a single axis.
+
+    For i in ``range(len(indices))``, `reduceat` computes
+    ``ufunc.reduce(a[indices[i]:indices[i+1]])``, which becomes the i-th
+    generalized "row" parallel to `axis` in the final result (i.e., in a
+    2-D array, for example, if `axis = 0`, it becomes the i-th row, but if
+    `axis = 1`, it becomes the i-th column).  There are three exceptions to this:
+
+    * when ``i = len(indices) - 1`` (so for the last index),
+      ``indices[i+1] = a.shape[axis]``.
+    * if ``indices[i] >= indices[i + 1]``, the i-th generalized "row" is
+      simply ``a[indices[i]]``.
+    * if ``indices[i] >= len(a)`` or ``indices[i] < 0``, an error is raised.
+
+    The shape of the output depends on the size of `indices`, and may be
+    larger than `a` (this happens if ``len(indices) > a.shape[axis]``).
+
+    Parameters
+    ----------
+    a : array_like
+        The array to act on.
+    indices : array_like
+        Paired indices, comma separated (not colon), specifying slices to
+        reduce.
+    axis : int, optional
+        The axis along which to apply the reduceat.
+    dtype : data-type code, optional
+        The type used to represent the intermediate results. Defaults
+        to the data type of the output array if this is provided, or
+        the data type of the input array if no output array is provided.
+    out : ndarray, optional
+        A location into which the result is stored. If not provided a
+        freshly-allocated array is returned.
+
+    Returns
+    -------
+    r : ndarray
+        The reduced values. If `out` was supplied, `r` is a reference to
+        `out`.
+
+    Notes
+    -----
+    A descriptive example:
+
+    If `a` is 1-D, the function `ufunc.accumulate(a)` is the same as
+    ``ufunc.reduceat(a, indices)[::2]`` where `indices` is
+    ``range(len(array) - 1)`` with a zero placed
+    in every other element:
+    ``indices = zeros(2 * len(a) - 1)``, ``indices[1::2] = range(1, len(a))``.
+
+    Don't be fooled by this attribute's name: `reduceat(a)` is not
+    necessarily smaller than `a`.
+
+    Examples
+    --------
+    To take the running sum of four successive values:
+
+    >>> np.add.reduceat(np.arange(8),[0,4, 1,5, 2,6, 3,7])[::2]
+    array([ 6, 10, 14, 18])
+
+    A 2-D example:
+
+    >>> x = np.linspace(0, 15, 16).reshape(4,4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+
+    ::
+
+     # reduce such that the result has the following five rows:
+     # [row1 + row2 + row3]
+     # [row4]
+     # [row2]
+     # [row3]
+     # [row1 + row2 + row3 + row4]
+
+    >>> np.add.reduceat(x, [0, 3, 1, 2, 0])
+    array([[ 12.,  15.,  18.,  21.],
+           [ 12.,  13.,  14.,  15.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 24.,  28.,  32.,  36.]])
+
+    ::
+
+     # reduce such that result has the following two columns:
+     # [col1 * col2 * col3, col4]
+
+    >>> np.multiply.reduceat(x, [0, 3], 1)
+    array([[    0.,     3.],
+           [  120.,     7.],
+           [  720.,    11.],
+           [ 2184.,    15.]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('outer',
+    """
+    outer(A, B)
+
+    Apply the ufunc `op` to all pairs (a, b) with a in `A` and b in `B`.
+
+    Let ``M = A.ndim``, ``N = B.ndim``. Then the result, `C`, of
+    ``op.outer(A, B)`` is an array of dimension M + N such that:
+
+    .. math:: C[i_0, ..., i_{M-1}, j_0, ..., j_{N-1}] =
+       op(A[i_0, ..., i_{M-1}], B[j_0, ..., j_{N-1}])
+
+    For `A` and `B` one-dimensional, this is equivalent to::
+
+      r = empty(len(A),len(B))
+      for i in range(len(A)):
+          for j in range(len(B)):
+              r[i,j] = op(A[i], B[j]) # op = ufunc in question
+
+    Parameters
+    ----------
+    A : array_like
+        First array
+    B : array_like
+        Second array
+
+    Returns
+    -------
+    r : ndarray
+        Output array
+
+    See Also
+    --------
+    numpy.outer
+
+    Examples
+    --------
+    >>> np.multiply.outer([1, 2, 3], [4, 5, 6])
+    array([[ 4,  5,  6],
+           [ 8, 10, 12],
+           [12, 15, 18]])
+
+    A multi-dimensional example:
+
+    >>> A = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> A.shape
+    (2, 3)
+    >>> B = np.array([[1, 2, 3, 4]])
+    >>> B.shape
+    (1, 4)
+    >>> C = np.multiply.outer(A, B)
+    >>> C.shape; C
+    (2, 3, 1, 4)
+    array([[[[ 1,  2,  3,  4]],
+            [[ 2,  4,  6,  8]],
+            [[ 3,  6,  9, 12]]],
+           [[[ 4,  8, 12, 16]],
+            [[ 5, 10, 15, 20]],
+            [[ 6, 12, 18, 24]]]])
+
+    """))
+
+add_newdoc('numpy.core', 'ufunc', ('at',
+    """
+    at(a, indices, b=None)
+
+    Performs unbuffered in place operation on operand 'a' for elements
+    specified by 'indices'. For addition ufunc, this method is equivalent to
+    `a[indices] += b`, except that results are accumulated for elements that
+    are indexed more than once. For example, `a[[0,0]] += 1` will only
+    increment the first element once because of buffering, whereas
+    `add.at(a, [0,0], 1)` will increment the first element twice.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        The array to perform in place operation on.
+    indices : array_like or tuple
+        Array like index object or slice object for indexing into first
+        operand. If first operand has multiple dimensions, indices can be a
+        tuple of array like index objects or slice objects.
+    b : array_like
+        Second operand for ufuncs requiring two operands. Operand must be
+        broadcastable over first operand after indexing or slicing.
+
+    Examples
+    --------
+    Set items 0 and 1 to their negative values:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> np.negative.at(a, [0, 1])
+    >>> print(a)
+    array([-1, -2, 3, 4])
+
+    ::
+
+    Increment items 0 and 1, and increment item 2 twice:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> np.add.at(a, [0, 1, 2, 2], 1)
+    >>> print(a)
+    array([2, 3, 5, 4])
+
+    ::
+
+    Add items 0 and 1 in first array to second array,
+    and store results in first array:
+
+    >>> a = np.array([1, 2, 3, 4])
+    >>> b = np.array([1, 2])
+    >>> np.add.at(a, [0, 1], b)
+    >>> print(a)
+    array([2, 4, 3, 4])
+
+    """))
+
+##############################################################################
+#
+# Documentation for dtype attributes and methods
+#
+##############################################################################
+
+##############################################################################
+#
+# dtype object
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype',
+    """
+    dtype(obj, align=False, copy=False)
+
+    Create a data type object.
+
+    A numpy array is homogeneous, and contains elements described by a
+    dtype object. A dtype object can be constructed from different
+    combinations of fundamental numeric types.
+
+    Parameters
+    ----------
+    obj
+        Object to be converted to a data type object.
+    align : bool, optional
+        Add padding to the fields to match what a C compiler would output
+        for a similar C-struct. Can be ``True`` only if `obj` is a dictionary
+        or a comma-separated string. If a struct dtype is being created,
+        this also sets a sticky alignment flag ``isalignedstruct``.
+    copy : bool, optional
+        Make a new copy of the data-type object. If ``False``, the result
+        may just be a reference to a built-in data-type object.
+
+    See also
+    --------
+    result_type
+
+    Examples
+    --------
+    Using array-scalar type:
+
+    >>> np.dtype(np.int16)
+    dtype('int16')
+
+    Structured type, one field name 'f1', containing int16:
+
+    >>> np.dtype([('f1', np.int16)])
+    dtype([('f1', '<i2')])
+
+    Structured type, one field named 'f1', in itself containing a structured
+    type with one field:
+
+    >>> np.dtype([('f1', [('f1', np.int16)])])
+    dtype([('f1', [('f1', '<i2')])])
+
+    Structured type, two fields: the first field contains an unsigned int, the
+    second an int32:
+
+    >>> np.dtype([('f1', np.uint), ('f2', np.int32)])
+    dtype([('f1', '<u4'), ('f2', '<i4')])
+
+    Using array-protocol type strings:
+
+    >>> np.dtype([('a','f8'),('b','S10')])
+    dtype([('a', '<f8'), ('b', '|S10')])
+
+    Using comma-separated field formats.  The shape is (2,3):
+
+    >>> np.dtype("i4, (2,3)f8")
+    dtype([('f0', '<i4'), ('f1', '<f8', (2, 3))])
+
+    Using tuples.  ``int`` is a fixed type, 3 the field's shape.  ``void``
+    is a flexible type, here of size 10:
+
+    >>> np.dtype([('hello',(np.int,3)),('world',np.void,10)])
+    dtype([('hello', '<i4', 3), ('world', '|V10')])
+
+    Subdivide ``int16`` into 2 ``int8``'s, called x and y.  0 and 1 are
+    the offsets in bytes:
+
+    >>> np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)}))
+    dtype(('<i2', [('x', '|i1'), ('y', '|i1')]))
+
+    Using dictionaries.  Two fields named 'gender' and 'age':
+
+    >>> np.dtype({'names':['gender','age'], 'formats':['S1',np.uint8]})
+    dtype([('gender', '|S1'), ('age', '|u1')])
+
+    Offsets in bytes, here 0 and 25:
+
+    >>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)})
+    dtype([('surname', '|S25'), ('age', '|u1')])
+
+    """)
+
+##############################################################################
+#
+# dtype attributes
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('alignment',
+    """
+    The required alignment (bytes) of this data-type according to the compiler.
+
+    More information is available in the C-API section of the manual.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('byteorder',
+    """
+    A character indicating the byte-order of this data-type object.
+
+    One of:
+
+    ===  ==============
+    '='  native
+    '<'  little-endian
+    '>'  big-endian
+    '|'  not applicable
+    ===  ==============
+
+    All built-in data-type objects have byteorder either '=' or '|'.
+
+    Examples
+    --------
+
+    >>> dt = np.dtype('i2')
+    >>> dt.byteorder
+    '='
+    >>> # endian is not relevant for 8 bit numbers
+    >>> np.dtype('i1').byteorder
+    '|'
+    >>> # or ASCII strings
+    >>> np.dtype('S2').byteorder
+    '|'
+    >>> # Even if specific code is given, and it is native
+    >>> # '=' is the byteorder
+    >>> import sys
+    >>> sys_is_le = sys.byteorder == 'little'
+    >>> native_code = sys_is_le and '<' or '>'
+    >>> swapped_code = sys_is_le and '>' or '<'
+    >>> dt = np.dtype(native_code + 'i2')
+    >>> dt.byteorder
+    '='
+    >>> # Swapped code shows up as itself
+    >>> dt = np.dtype(swapped_code + 'i2')
+    >>> dt.byteorder == swapped_code
+    True
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('char',
+    """A unique character code for each of the 21 different built-in types."""))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('descr',
+    """
+    Array-interface compliant full description of the data-type.
+
+    The format is that required by the 'descr' key in the
+    `__array_interface__` attribute.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('fields',
+    """
+    Dictionary of named fields defined for this data type, or ``None``.
+
+    The dictionary is indexed by keys that are the names of the fields.
+    Each entry in the dictionary is a tuple fully describing the field::
+
+      (dtype, offset[, title])
+
+    If present, the optional title can be any object (if it is a string
+    or unicode then it will also be a key in the fields dictionary,
+    otherwise it's meta-data). Notice also that the first two elements
+    of the tuple can be passed directly as arguments to the ``ndarray.getfield``
+    and ``ndarray.setfield`` methods.
+
+    See Also
+    --------
+    ndarray.getfield, ndarray.setfield
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
+    >>> print(dt.fields)
+    {'grades': (dtype(('float64',(2,))), 16), 'name': (dtype('|S16'), 0)}
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('flags',
+    """
+    Bit-flags describing how this data type is to be interpreted.
+
+    Bit-masks are in `numpy.core.multiarray` as the constants
+    `ITEM_HASOBJECT`, `LIST_PICKLE`, `ITEM_IS_POINTER`, `NEEDS_INIT`,
+    `NEEDS_PYAPI`, `USE_GETITEM`, `USE_SETITEM`. A full explanation
+    of these flags is in C-API documentation; they are largely useful
+    for user-defined data-types.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('hasobject',
+    """
+    Boolean indicating whether this dtype contains any reference-counted
+    objects in any fields or sub-dtypes.
+
+    Recall that what is actually in the ndarray memory representing
+    the Python object is the memory address of that object (a pointer).
+    Special handling may be required, and this attribute is useful for
+    distinguishing data types that may contain arbitrary Python objects
+    and data-types that won't.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isbuiltin',
+    """
+    Integer indicating how this dtype relates to the built-in dtypes.
+
+    Read-only.
+
+    =  ========================================================================
+    0  if this is a structured array type, with fields
+    1  if this is a dtype compiled into numpy (such as ints, floats etc)
+    2  if the dtype is for a user-defined numpy type
+       A user-defined type uses the numpy C-API machinery to extend
+       numpy to handle a new array type. See
+       :ref:`user.user-defined-data-types` in the Numpy manual.
+    =  ========================================================================
+
+    Examples
+    --------
+    >>> dt = np.dtype('i2')
+    >>> dt.isbuiltin
+    1
+    >>> dt = np.dtype('f8')
+    >>> dt.isbuiltin
+    1
+    >>> dt = np.dtype([('field1', 'f8')])
+    >>> dt.isbuiltin
+    0
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isnative',
+    """
+    Boolean indicating whether the byte order of this dtype is native
+    to the platform.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('isalignedstruct',
+    """
+    Boolean indicating whether the dtype is a struct which maintains
+    field alignment. This flag is sticky, so when combining multiple
+    structs together, it is preserved and produces new dtypes which
+    are also aligned.
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('itemsize',
+    """
+    The element size of this data-type object.
+
+    For 18 of the 21 types this number is fixed by the data-type.
+    For the flexible data-types, this number can be anything.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('kind',
+    """
+    A character code (one of 'biufcmMOSUV') identifying the general kind of data.
+
+    =  ======================
+    b  boolean
+    i  signed integer
+    u  unsigned integer
+    f  floating-point
+    c  complex floating-point
+    m  timedelta
+    M  datetime
+    O  object
+    S  (byte-)string
+    U  Unicode
+    V  void
+    =  ======================
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('name',
+    """
+    A bit-width name for this data-type.
+
+    Un-sized flexible data-type objects do not have this attribute.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('names',
+    """
+    Ordered list of field names, or ``None`` if there are no fields.
+
+    The names are ordered according to increasing byte offset. This can be
+    used, for example, to walk through all of the named fields in offset order.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
+    >>> dt.names
+    ('name', 'grades')
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('num',
+    """
+    A unique number for each of the 21 different built-in types.
+
+    These are roughly ordered from least-to-most precision.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('shape',
+    """
+    Shape tuple of the sub-array if this data type describes a sub-array,
+    and ``()`` otherwise.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('str',
+    """The array-protocol typestring of this data-type object."""))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('subdtype',
+    """
+    Tuple ``(item_dtype, shape)`` if this `dtype` describes a sub-array, and
+    None otherwise.
+
+    The *shape* is the fixed shape of the sub-array described by this
+    data type, and *item_dtype* the data type of the array.
+
+    If a field whose dtype object has this attribute is retrieved,
+    then the extra dimensions implied by *shape* are tacked on to
+    the end of the retrieved array.
+
+    """))
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('type',
+    """The type object used to instantiate a scalar of this data-type."""))
+
+##############################################################################
+#
+# dtype methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'dtype', ('newbyteorder',
+    """
+    newbyteorder(new_order='S')
+
+    Return a new dtype with a different byte order.
+
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    Parameters
+    ----------
+    new_order : string, optional
+        Byte order to force; a value from the byte order specifications
+        below.  The default value ('S') results in swapping the current
+        byte order.  `new_order` codes can be any of:
+
+        * 'S' - swap dtype from current to opposite endian
+        * {'<', 'L'} - little endian
+        * {'>', 'B'} - big endian
+        * {'=', 'N'} - native order
+        * {'|', 'I'} - ignore (no change to byte order)
+
+        The code does a case-insensitive check on the first letter of
+        `new_order` for these alternatives.  For example, any of '>'
+        or 'B' or 'b' or 'brian' are valid to specify big-endian.
+
+    Returns
+    -------
+    new_dtype : dtype
+        New dtype object with the given change to the byte order.
+
+    Notes
+    -----
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    Examples
+    --------
+    >>> import sys
+    >>> sys_is_le = sys.byteorder == 'little'
+    >>> native_code = sys_is_le and '<' or '>'
+    >>> swapped_code = sys_is_le and '>' or '<'
+    >>> native_dt = np.dtype(native_code+'i2')
+    >>> swapped_dt = np.dtype(swapped_code+'i2')
+    >>> native_dt.newbyteorder('S') == swapped_dt
+    True
+    >>> native_dt.newbyteorder() == swapped_dt
+    True
+    >>> native_dt == swapped_dt.newbyteorder('S')
+    True
+    >>> native_dt == swapped_dt.newbyteorder('=')
+    True
+    >>> native_dt == swapped_dt.newbyteorder('N')
+    True
+    >>> native_dt == native_dt.newbyteorder('|')
+    True
+    >>> np.dtype('<i2') == native_dt.newbyteorder('<')
+    True
+    >>> np.dtype('<i2') == native_dt.newbyteorder('L')
+    True
+    >>> np.dtype('>i2') == native_dt.newbyteorder('>')
+    True
+    >>> np.dtype('>i2') == native_dt.newbyteorder('B')
+    True
+
+    """))
+
+
+##############################################################################
+#
+# Datetime-related Methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar',
+    """
+    busdaycalendar(weekmask='1111100', holidays=None)
+
+    A business day calendar object that efficiently stores information
+    defining valid days for the busday family of functions.
+
+    The default valid days are Monday through Friday ("business days").
+    A busdaycalendar object can be specified with any set of weekly
+    valid days, plus an optional "holiday" dates that always will be invalid.
+
+    Once a busdaycalendar object is created, the weekmask and holidays
+    cannot be modified.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates, no matter which
+        weekday they fall upon.  Holiday dates may be specified in any
+        order, and NaT (not-a-time) dates are ignored.  This list is
+        saved in a normalized form that is suited for fast calculations
+        of valid days.
+
+    Returns
+    -------
+    out : busdaycalendar
+        A business day calendar object containing the specified
+        weekmask and holidays values.
+
+    See Also
+    --------
+    is_busday : Returns a boolean array indicating valid days.
+    busday_offset : Applies an offset counted in valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Attributes
+    ----------
+    Note: once a busdaycalendar object is created, you cannot modify the
+    weekmask or holidays.  The attributes return copies of internal data.
+    weekmask : (copy) seven-element array of bool
+    holidays : (copy) sorted array of datetime64[D]
+
+    Examples
+    --------
+    >>> # Some important days in July
+    ... bdd = np.busdaycalendar(
+    ...             holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+    >>> # Default is Monday to Friday weekdays
+    ... bdd.weekmask
+    array([ True,  True,  True,  True,  True, False, False], dtype='bool')
+    >>> # Any holidays already on the weekend are removed
+    ... bdd.holidays
+    array(['2011-07-01', '2011-07-04'], dtype='datetime64[D]')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('weekmask',
+    """A copy of the seven-element boolean mask indicating valid days."""))
+
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('holidays',
+    """A copy of the holiday array indicating additional invalid days."""))
+
+add_newdoc('numpy.core.multiarray', 'is_busday',
+    """
+    is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None)
+
+    Calculates which of the given dates are valid days, and which are not.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dates : array_like of datetime64[D]
+        The array of dates to process.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of bool, optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of bool
+        An array with the same shape as ``dates``, containing True for
+        each valid day, and False for each invalid day.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    busday_offset : Applies an offset counted in valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Examples
+    --------
+    >>> # The weekdays are Friday, Saturday, and Monday
+    ... np.is_busday(['2011-07-01', '2011-07-02', '2011-07-18'],
+    ...                 holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+    array([False, False,  True], dtype='bool')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busday_offset',
+    """
+    busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)
+
+    First adjusts the date to fall on a valid day according to
+    the ``roll`` rule, then applies offsets to the given dates
+    counted in valid days.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    dates : array_like of datetime64[D]
+        The array of dates to process.
+    offsets : array_like of int
+        The array of offsets, which is broadcast with ``dates``.
+    roll : {'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}, optional
+        How to treat dates that do not fall on a valid day. The default
+        is 'raise'.
+
+          * 'raise' means to raise an exception for an invalid day.
+          * 'nat' means to return a NaT (not-a-time) for an invalid day.
+          * 'forward' and 'following' mean to take the first valid day
+            later in time.
+          * 'backward' and 'preceding' mean to take the first valid day
+            earlier in time.
+          * 'modifiedfollowing' means to take the first valid day
+            later in time unless it is across a Month boundary, in which
+            case to take the first valid day earlier in time.
+          * 'modifiedpreceding' means to take the first valid day
+            earlier in time unless it is across a Month boundary, in which
+            case to take the first valid day later in time.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of datetime64[D], optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of datetime64[D]
+        An array with a shape from broadcasting ``dates`` and ``offsets``
+        together, containing the dates with offsets applied.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    is_busday : Returns a boolean array indicating valid days.
+    busday_count : Counts how many valid days are in a half-open date range.
+
+    Examples
+    --------
+    >>> # First business day in October 2011 (not accounting for holidays)
+    ... np.busday_offset('2011-10', 0, roll='forward')
+    numpy.datetime64('2011-10-03','D')
+    >>> # Last business day in February 2012 (not accounting for holidays)
+    ... np.busday_offset('2012-03', -1, roll='forward')
+    numpy.datetime64('2012-02-29','D')
+    >>> # Third Wednesday in January 2011
+    ... np.busday_offset('2011-01', 2, roll='forward', weekmask='Wed')
+    numpy.datetime64('2011-01-19','D')
+    >>> # 2012 Mother's Day in Canada and the U.S.
+    ... np.busday_offset('2012-05', 1, roll='forward', weekmask='Sun')
+    numpy.datetime64('2012-05-13','D')
+
+    >>> # First business day on or after a date
+    ... np.busday_offset('2011-03-20', 0, roll='forward')
+    numpy.datetime64('2011-03-21','D')
+    >>> np.busday_offset('2011-03-22', 0, roll='forward')
+    numpy.datetime64('2011-03-22','D')
+    >>> # First business day after a date
+    ... np.busday_offset('2011-03-20', 1, roll='backward')
+    numpy.datetime64('2011-03-21','D')
+    >>> np.busday_offset('2011-03-22', 1, roll='backward')
+    numpy.datetime64('2011-03-23','D')
+    """)
+
+add_newdoc('numpy.core.multiarray', 'busday_count',
+    """
+    busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)
+
+    Counts the number of valid days between `begindates` and
+    `enddates`, not including the day of `enddates`.
+
+    If ``enddates`` specifies a date value that is earlier than the
+    corresponding ``begindates`` date value, the count will be negative.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    begindates : array_like of datetime64[D]
+        The array of the first dates for counting.
+    enddates : array_like of datetime64[D]
+        The array of the end dates for counting, which are excluded
+        from the count themselves.
+    weekmask : str or array_like of bool, optional
+        A seven-element array indicating which of Monday through Sunday are
+        valid days. May be specified as a length-seven list or array, like
+        [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+        like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+        weekdays, optionally separated by white space. Valid abbreviations
+        are: Mon Tue Wed Thu Fri Sat Sun
+    holidays : array_like of datetime64[D], optional
+        An array of dates to consider as invalid dates.  They may be
+        specified in any order, and NaT (not-a-time) dates are ignored.
+        This list is saved in a normalized form that is suited for
+        fast calculations of valid days.
+    busdaycal : busdaycalendar, optional
+        A `busdaycalendar` object which specifies the valid days. If this
+        parameter is provided, neither weekmask nor holidays may be
+        provided.
+    out : array of int, optional
+        If provided, this array is filled with the result.
+
+    Returns
+    -------
+    out : array of int
+        An array with a shape from broadcasting ``begindates`` and ``enddates``
+        together, containing the number of valid days between
+        the begin and end dates.
+
+    See Also
+    --------
+    busdaycalendar: An object that specifies a custom set of valid days.
+    is_busday : Returns a boolean array indicating valid days.
+    busday_offset : Applies an offset counted in valid days.
+
+    Examples
+    --------
+    >>> # Number of weekdays in January 2011
+    ... np.busday_count('2011-01', '2011-02')
+    21
+    >>> # Number of weekdays in 2011
+    ...  np.busday_count('2011', '2012')
+    260
+    >>> # Number of Saturdays in 2011
+    ... np.busday_count('2011', '2012', weekmask='Sat')
+    53
+    """)
+
+##############################################################################
+#
+# nd_grid instances
+#
+##############################################################################
+
+add_newdoc('numpy.lib.index_tricks', 'mgrid',
+    """
+    `nd_grid` instance which returns a dense multi-dimensional "meshgrid".
+
+    An instance of `numpy.lib.index_tricks.nd_grid` which returns an dense
+    (or fleshed out) mesh-grid when indexed, so that each returned argument
+    has the same shape.  The dimensions and number of the output arrays are
+    equal to the number of indexing dimensions.  If the step length is not a
+    complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then
+    the integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    Returns
+    ----------
+    mesh-grid `ndarrays` all of the same dimensions
+
+    See Also
+    --------
+    numpy.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects
+    ogrid : like mgrid but returns open (not fleshed out) mesh grids
+    r_ : array concatenator
+
+    Examples
+    --------
+    >>> np.mgrid[0:5,0:5]
+    array([[[0, 0, 0, 0, 0],
+            [1, 1, 1, 1, 1],
+            [2, 2, 2, 2, 2],
+            [3, 3, 3, 3, 3],
+            [4, 4, 4, 4, 4]],
+           [[0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4]]])
+    >>> np.mgrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+
+    """)
+
+add_newdoc('numpy.lib.index_tricks', 'ogrid',
+    """
+    `nd_grid` instance which returns an open multi-dimensional "meshgrid".
+
+    An instance of `numpy.lib.index_tricks.nd_grid` which returns an open
+    (i.e. not fleshed out) mesh-grid when indexed, so that only one dimension
+    of each returned array is greater than 1.  The dimension and number of the
+    output arrays are equal to the number of indexing dimensions.  If the step
+    length is not a complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then
+    the integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    Returns
+    ----------
+    mesh-grid `ndarrays` with only one dimension :math:`\\neq 1`
+
+    See Also
+    --------
+    np.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects
+    mgrid : like `ogrid` but returns dense (or fleshed out) mesh grids
+    r_ : array concatenator
+
+    Examples
+    --------
+    >>> from numpy import ogrid
+    >>> ogrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+    >>> ogrid[0:5,0:5]
+    [array([[0],
+            [1],
+            [2],
+            [3],
+            [4]]), array([[0, 1, 2, 3, 4]])]
+
+    """)
+
+
+##############################################################################
+#
+# Documentation for `generic` attributes and methods
+#
+##############################################################################
+
+add_newdoc('numpy.core.numerictypes', 'generic',
+    """
+    Base class for numpy scalar types.
+
+    Class from which most (all?) numpy scalar types are derived.  For
+    consistency, exposes the same API as `ndarray`, despite many
+    consequent attributes being either "get-only," or completely irrelevant.
+    This is the class from which it is strongly suggested users should derive
+    custom scalar types.
+
+    """)
+
+# Attributes
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('T',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('base',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('data',
+    """Pointer to start of data."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dtype',
+    """Get array data-descriptor."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flags',
+    """The integer value of flags."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flat',
+    """A 1-D view of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('imag',
+    """The imaginary part of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('itemsize',
+    """The length of one element in bytes."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('nbytes',
+    """The length of the scalar in bytes."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ndim',
+    """The number of array dimensions."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('real',
+    """The real part of the scalar."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('shape',
+    """Tuple of array dimensions."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('size',
+    """The number of elements in the gentype."""))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('strides',
+    """Tuple of bytes steps in each dimension."""))
+
+# Methods
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('all',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('any',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argmax',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argmin',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('argsort',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('astype',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('byteswap',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('choose',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('clip',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('compress',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('conjugate',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('copy',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('cumprod',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('cumsum',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('diagonal',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dump',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('dumps',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('fill',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('flatten',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('getfield',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('item',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('itemset',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('max',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('mean',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('min',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('newbyteorder',
+    """
+    newbyteorder(new_order='S')
+
+    Return a new `dtype` with a different byte order.
+
+    Changes are also made in all fields and sub-arrays of the data type.
+
+    The `new_order` code can be any from the following:
+
+    * 'S' - swap dtype from current to opposite endian
+    * {'<', 'L'} - little endian
+    * {'>', 'B'} - big endian
+    * {'=', 'N'} - native order
+    * {'|', 'I'} - ignore (no change to byte order)
+
+    Parameters
+    ----------
+    new_order : str, optional
+        Byte order to force; a value from the byte order specifications
+        above.  The default value ('S') results in swapping the current
+        byte order. The code does a case-insensitive check on the first
+        letter of `new_order` for the alternatives above.  For example,
+        any of 'B' or 'b' or 'biggish' are valid to specify big-endian.
+
+
+    Returns
+    -------
+    new_dtype : dtype
+        New `dtype` object with the given change to the byte order.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('nonzero',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('prod',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ptp',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('put',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('ravel',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('repeat',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('reshape',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('resize',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('round',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('searchsorted',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('setfield',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('setflags',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class so as to
+    provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('sort',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('squeeze',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('std',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('sum',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('swapaxes',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('take',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tofile',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tolist',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('tostring',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('trace',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('transpose',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('var',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+add_newdoc('numpy.core.numerictypes', 'generic', ('view',
+    """
+    Not implemented (virtual attribute)
+
+    Class generic exists solely to derive numpy scalars from, and possesses,
+    albeit unimplemented, all the attributes of the ndarray class
+    so as to provide a uniform API.
+
+    See Also
+    --------
+    The corresponding attribute of the derived class of interest.
+
+    """))
+
+
+##############################################################################
+#
+# Documentation for other scalar classes
+#
+##############################################################################
+
+add_newdoc('numpy.core.numerictypes', 'bool_',
+    """Numpy's Boolean type.  Character code: ``?``.  Alias: bool8""")
+
+add_newdoc('numpy.core.numerictypes', 'complex64',
+    """
+    Complex number type composed of two 32 bit floats. Character code: 'F'.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'complex128',
+    """
+    Complex number type composed of two 64 bit floats. Character code: 'D'.
+    Python complex compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'complex256',
+    """
+    Complex number type composed of two 128-bit floats. Character code: 'G'.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float32',
+    """
+    32-bit floating-point number. Character code 'f'. C float compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float64',
+    """
+    64-bit floating-point number. Character code 'd'. Python float compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float96',
+    """
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'float128',
+    """
+    128-bit floating-point number. Character code: 'g'. C long float
+    compatible.
+
+    """)
+
+add_newdoc('numpy.core.numerictypes', 'int8',
+    """8-bit integer. Character code ``b``. C char compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int16',
+    """16-bit integer. Character code ``h``. C short compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int32',
+    """32-bit integer. Character code 'i'. C int compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'int64',
+    """64-bit integer. Character code 'l'. Python int compatible.""")
+
+add_newdoc('numpy.core.numerictypes', 'object_',
+    """Any Python object.  Character code: 'O'.""")
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/__init__.py
new file mode 100644
index 0000000000..5b371f5c06
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/__init__.py
@@ -0,0 +1,20 @@
+"""
+Compatibility module.
+
+This module contains duplicated code from Python itself or 3rd party
+extensions, which may be included for the following reasons:
+
+  * compatibility
+  * we may only need a small subset of the copied library/module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import _inspect
+from . import py3k
+from ._inspect import getargspec, formatargspec
+from .py3k import *
+
+__all__ = []
+__all__.extend(_inspect.__all__)
+__all__.extend(py3k.__all__)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.py
new file mode 100644
index 0000000000..c1aa22ec44
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.py
@@ -0,0 +1,194 @@
+"""Subset of inspect module from upstream python
+
+We use this instead of upstream because upstream inspect is slow to import, and
+significanly contributes to numpy import times. Importing this copy has almost
+no overhead.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types
+
+__all__ = ['getargspec', 'formatargspec']
+
+# ----------------------------------------------------------- type-checking
+def ismethod(object):
+    """Return true if the object is an instance method.
+
+    Instance method objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this method was defined
+        im_class        class object in which this method belongs
+        im_func         function object containing implementation of method
+        im_self         instance to which this method is bound, or None
+
+    """
+    return isinstance(object, types.MethodType)
+
+def isfunction(object):
+    """Return true if the object is a user-defined function.
+
+    Function objects provide these attributes:
+        __doc__         documentation string
+        __name__        name with which this function was defined
+        func_code       code object containing compiled function bytecode
+        func_defaults   tuple of any default values for arguments
+        func_doc        (same as __doc__)
+        func_globals    global namespace in which this function was defined
+        func_name       (same as __name__)
+
+    """
+    return isinstance(object, types.FunctionType)
+
+def iscode(object):
+    """Return true if the object is a code object.
+
+    Code objects provide these attributes:
+        co_argcount     number of arguments (not including * or ** args)
+        co_code         string of raw compiled bytecode
+        co_consts       tuple of constants used in the bytecode
+        co_filename     name of file in which this code object was created
+        co_firstlineno  number of first line in Python source code
+        co_flags        bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
+        co_lnotab       encoded mapping of line numbers to bytecode indices
+        co_name         name with which this code object was defined
+        co_names        tuple of names of local variables
+        co_nlocals      number of local variables
+        co_stacksize    virtual machine stack space required
+        co_varnames     tuple of names of arguments and local variables
+        
+    """
+    return isinstance(object, types.CodeType)
+
+# ------------------------------------------------ argument list extraction
+# These constants are from Python's compile.h.
+CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+
+def getargs(co):
+    """Get information about the arguments accepted by a code object.
+
+    Three things are returned: (args, varargs, varkw), where 'args' is
+    a list of argument names (possibly containing nested lists), and
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+
+    """
+
+    if not iscode(co):
+        raise TypeError('arg is not a code object')
+
+    nargs = co.co_argcount
+    names = co.co_varnames
+    args = list(names[:nargs])
+
+    # The following acrobatics are for anonymous (tuple) arguments.
+    # Which we do not need to support, so remove to avoid importing
+    # the dis module.
+    for i in range(nargs):
+        if args[i][:1] in ['', '.']:
+            raise TypeError("tuple function arguments are not supported")
+    varargs = None
+    if co.co_flags & CO_VARARGS:
+        varargs = co.co_varnames[nargs]
+        nargs = nargs + 1
+    varkw = None
+    if co.co_flags & CO_VARKEYWORDS:
+        varkw = co.co_varnames[nargs]
+    return args, varargs, varkw
+
+def getargspec(func):
+    """Get the names and default values of a function's arguments.
+
+    A tuple of four things is returned: (args, varargs, varkw, defaults).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'defaults' is an n-tuple of the default values of the last n arguments.
+
+    """
+
+    if ismethod(func):
+        func = func.__func__
+    if not isfunction(func):
+        raise TypeError('arg is not a Python function')
+    args, varargs, varkw = getargs(func.__code__)
+    return args, varargs, varkw, func.__defaults__
+
+def getargvalues(frame):
+    """Get information about arguments passed into a particular frame.
+
+    A tuple of four things is returned: (args, varargs, varkw, locals).
+    'args' is a list of the argument names (it may contain nested lists).
+    'varargs' and 'varkw' are the names of the * and ** arguments or None.
+    'locals' is the locals dictionary of the given frame.
+    
+    """
+    args, varargs, varkw = getargs(frame.f_code)
+    return args, varargs, varkw, frame.f_locals
+
+def joinseq(seq):
+    if len(seq) == 1:
+        return '(' + seq[0] + ',)'
+    else:
+        return '(' + ', '.join(seq) + ')'
+
+def strseq(object, convert, join=joinseq):
+    """Recursively walk a sequence, stringifying each element.
+
+    """
+    if type(object) in [list, tuple]:
+        return join([strseq(_o, convert, join) for _o in object])
+    else:
+        return convert(object)
+
+def formatargspec(args, varargs=None, varkw=None, defaults=None,
+                  formatarg=str,
+                  formatvarargs=lambda name: '*' + name,
+                  formatvarkw=lambda name: '**' + name,
+                  formatvalue=lambda value: '=' + repr(value),
+                  join=joinseq):
+    """Format an argument spec from the 4 values returned by getargspec.
+
+    The first four arguments are (args, varargs, varkw, defaults).  The
+    other four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments.
+
+    """
+    specs = []
+    if defaults:
+        firstdefault = len(args) - len(defaults)
+    for i in range(len(args)):
+        spec = strseq(args[i], formatarg, join)
+        if defaults and i >= firstdefault:
+            spec = spec + formatvalue(defaults[i - firstdefault])
+        specs.append(spec)
+    if varargs is not None:
+        specs.append(formatvarargs(varargs))
+    if varkw is not None:
+        specs.append(formatvarkw(varkw))
+    return '(' + ', '.join(specs) + ')'
+
+def formatargvalues(args, varargs, varkw, locals,
+                    formatarg=str,
+                    formatvarargs=lambda name: '*' + name,
+                    formatvarkw=lambda name: '**' + name,
+                    formatvalue=lambda value: '=' + repr(value),
+                    join=joinseq):
+    """Format an argument spec from the 4 values returned by getargvalues.
+
+    The first four arguments are (args, varargs, varkw, locals).  The
+    next four arguments are the corresponding optional formatting functions
+    that are called to turn names and values into strings.  The ninth
+    argument is an optional function to format the sequence of arguments.
+
+    """
+    def convert(name, locals=locals,
+                formatarg=formatarg, formatvalue=formatvalue):
+        return formatarg(name) + formatvalue(locals[name])
+    specs = []
+    for i in range(len(args)):
+        specs.append(strseq(args[i], convert, join))
+    if varargs:
+        specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
+    if varkw:
+        specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
+    return '(' + ', '.join(specs) + ')'
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/py3k.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/py3k.py
new file mode 100644
index 0000000000..d95a362ca6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/py3k.py
@@ -0,0 +1,88 @@
+"""
+Python 3 compatibility tools.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar',
+           'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested',
+           'asstr', 'open_latin1', 'long', 'basestring', 'sixu',
+           'integer_types']
+
+import sys
+
+if sys.version_info[0] >= 3:
+    import io
+
+    long = int
+    integer_types = (int,)
+    basestring = str
+    unicode = str
+    bytes = bytes
+
+    def asunicode(s):
+        if isinstance(s, bytes):
+            return s.decode('latin1')
+        return str(s)
+
+    def asbytes(s):
+        if isinstance(s, bytes):
+            return s
+        return str(s).encode('latin1')
+
+    def asstr(s):
+        if isinstance(s, bytes):
+            return s.decode('latin1')
+        return str(s)
+
+    def isfileobj(f):
+        return isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter))
+
+    def open_latin1(filename, mode='r'):
+        return open(filename, mode=mode, encoding='iso-8859-1')
+
+    def sixu(s):
+        return s
+
+    strchar = 'U'
+
+
+else:
+    bytes = str
+    long = long
+    basestring = basestring
+    unicode = unicode
+    integer_types = (int, long)
+    asbytes = str
+    asstr = str
+    strchar = 'S'
+
+    def isfileobj(f):
+        return isinstance(f, file)
+
+    def asunicode(s):
+        if isinstance(s, unicode):
+            return s
+        return str(s).decode('ascii')
+
+    def open_latin1(filename, mode='r'):
+        return open(filename, mode=mode)
+
+    def sixu(s):
+        return unicode(s, 'unicode_escape')
+
+
+def getexception():
+    return sys.exc_info()[1]
+
+def asbytes_nested(x):
+    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
+        return [asbytes_nested(y) for y in x]
+    else:
+        return asbytes(x)
+
+def asunicode_nested(x):
+    if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
+        return [asunicode_nested(y) for y in x]
+    else:
+        return asunicode(x)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/setup.py
new file mode 100644
index 0000000000..ad1e50c699
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/compat/setup.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('compat', parent_package, top_path)
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/__init__.py
new file mode 100644
index 0000000000..e8719ca75f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/__init__.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+from .info import __doc__
+from numpy.version import version as __version__
+
+# disables OpenBLAS affinity setting of the main thread that limits
+# python threads or processes to one core
+import os
+env_added = []
+for envkey in ['OPENBLAS_MAIN_FREE', 'GOTOBLAS_MAIN_FREE']:
+    if envkey not in os.environ:
+        os.environ[envkey] = '1'
+        env_added.append(envkey)
+from . import multiarray
+for envkey in env_added:
+    del os.environ[envkey]
+del envkey
+del env_added
+del os
+
+from . import umath
+from . import _internal  # for freeze programs
+from . import numerictypes as nt
+multiarray.set_typeDict(nt.sctypeDict)
+from . import numeric
+from .numeric import *
+from . import fromnumeric
+from .fromnumeric import *
+from . import defchararray as char
+from . import records as rec
+from .records import *
+from .memmap import *
+from .defchararray import chararray
+from . import function_base
+from .function_base import *
+from . import machar
+from .machar import *
+from . import getlimits
+from .getlimits import *
+from . import shape_base
+from .shape_base import *
+del nt
+
+from .fromnumeric import amax as max, amin as min, round_ as round
+from .numeric import absolute as abs
+
+__all__ = ['char', 'rec', 'memmap']
+__all__ += numeric.__all__
+__all__ += fromnumeric.__all__
+__all__ += rec.__all__
+__all__ += ['chararray']
+__all__ += function_base.__all__
+__all__ += machar.__all__
+__all__ += getlimits.__all__
+__all__ += shape_base.__all__
+
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
+
+# Make it possible so that ufuncs can be pickled
+#  Here are the loading and unloading functions
+# The name numpy.core._ufunc_reconstruct must be
+#   available for unpickling to work.
+def _ufunc_reconstruct(module, name):
+    # The `fromlist` kwarg is required to ensure that `mod` points to the
+    # inner-most module rather than the parent package when module name is
+    # nested. This makes it possible to pickle non-toplevel ufuncs such as
+    # scipy.special.expit for instance.
+    mod = __import__(module, fromlist=[name])
+    return getattr(mod, name)
+
+def _ufunc_reduce(func):
+    from pickle import whichmodule
+    name = func.__name__
+    return _ufunc_reconstruct, (whichmodule(func, name), name)
+
+
+import sys
+if sys.version_info[0] >= 3:
+    import copyreg
+else:
+    import copy_reg as copyreg
+
+copyreg.pickle(ufunc, _ufunc_reduce, _ufunc_reconstruct)
+# Unclutter namespace (must keep _ufunc_reconstruct for unpickling)
+del copyreg
+del sys
+del _ufunc_reduce
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_dummy.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_dummy.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..abe5312f1a403f7a1173bb1d978beacbe569ff70
GIT binary patch
literal 16384
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
HA)f*Obpaz?

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_internal.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_internal.py
new file mode 100644
index 0000000000..47c9334111
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_internal.py
@@ -0,0 +1,632 @@
+"""
+A place for code to be called from core C-code.
+
+Some things are more easily handled Python.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import re
+import sys
+
+from numpy.compat import asbytes, basestring
+from .multiarray import dtype, array, ndarray
+import ctypes
+from .numerictypes import object_
+
+if (sys.byteorder == 'little'):
+    _nbo = asbytes('<')
+else:
+    _nbo = asbytes('>')
+
+def _makenames_list(adict, align):
+    allfields = []
+    fnames = list(adict.keys())
+    for fname in fnames:
+        obj = adict[fname]
+        n = len(obj)
+        if not isinstance(obj, tuple) or n not in [2, 3]:
+            raise ValueError("entry not a 2- or 3- tuple")
+        if (n > 2) and (obj[2] == fname):
+            continue
+        num = int(obj[1])
+        if (num < 0):
+            raise ValueError("invalid offset.")
+        format = dtype(obj[0], align=align)
+        if (format.itemsize == 0):
+            raise ValueError("all itemsizes must be fixed.")
+        if (n > 2):
+            title = obj[2]
+        else:
+            title = None
+        allfields.append((fname, format, num, title))
+    # sort by offsets
+    allfields.sort(key=lambda x: x[2])
+    names = [x[0] for x in allfields]
+    formats = [x[1] for x in allfields]
+    offsets = [x[2] for x in allfields]
+    titles = [x[3] for x in allfields]
+
+    return names, formats, offsets, titles
+
+# Called in PyArray_DescrConverter function when
+#  a dictionary without "names" and "formats"
+#  fields is used as a data-type descriptor.
+def _usefields(adict, align):
+    try:
+        names = adict[-1]
+    except KeyError:
+        names = None
+    if names is None:
+        names, formats, offsets, titles = _makenames_list(adict, align)
+    else:
+        formats = []
+        offsets = []
+        titles = []
+        for name in names:
+            res = adict[name]
+            formats.append(res[0])
+            offsets.append(res[1])
+            if (len(res) > 2):
+                titles.append(res[2])
+            else:
+                titles.append(None)
+
+    return dtype({"names": names,
+                  "formats": formats,
+                  "offsets": offsets,
+                  "titles": titles}, align)
+
+
+# construct an array_protocol descriptor list
+#  from the fields attribute of a descriptor
+# This calls itself recursively but should eventually hit
+#  a descriptor that has no fields and then return
+#  a simple typestring
+
+def _array_descr(descriptor):
+    fields = descriptor.fields
+    if fields is None:
+        subdtype = descriptor.subdtype
+        if subdtype is None:
+            if descriptor.metadata is None:
+                return descriptor.str
+            else:
+                new = descriptor.metadata.copy()
+                if new:
+                    return (descriptor.str, new)
+                else:
+                    return descriptor.str
+        else:
+            return (_array_descr(subdtype[0]), subdtype[1])
+
+    names = descriptor.names
+    ordered_fields = [fields[x] + (x,) for x in names]
+    result = []
+    offset = 0
+    for field in ordered_fields:
+        if field[1] > offset:
+            num = field[1] - offset
+            result.append(('', '|V%d' % num))
+            offset += num
+        if len(field) > 3:
+            name = (field[2], field[3])
+        else:
+            name = field[2]
+        if field[0].subdtype:
+            tup = (name, _array_descr(field[0].subdtype[0]),
+                   field[0].subdtype[1])
+        else:
+            tup = (name, _array_descr(field[0]))
+        offset += field[0].itemsize
+        result.append(tup)
+
+    if descriptor.itemsize > offset:
+        num = descriptor.itemsize - offset
+        result.append(('', '|V%d' % num))
+
+    return result
+
+# Build a new array from the information in a pickle.
+# Note that the name numpy.core._internal._reconstruct is embedded in
+# pickles of ndarrays made with NumPy before release 1.0
+# so don't remove the name here, or you'll
+# break backward compatibilty.
+def _reconstruct(subtype, shape, dtype):
+    return ndarray.__new__(subtype, shape, dtype)
+
+
+# format_re was originally from numarray by J. Todd Miller
+
+format_re = re.compile(asbytes(
+                           r'(?P<order1>[<>|=]?)'
+                           r'(?P<repeats> *[(]?[ ,0-9L]*[)]? *)'
+                           r'(?P<order2>[<>|=]?)'
+                           r'(?P<dtype>[A-Za-z0-9.?]*(?:\[[a-zA-Z0-9,.]+\])?)'))
+sep_re = re.compile(asbytes(r'\s*,\s*'))
+space_re = re.compile(asbytes(r'\s+$'))
+
+# astr is a string (perhaps comma separated)
+
+_convorder = {asbytes('='): _nbo}
+
+def _commastring(astr):
+    startindex = 0
+    result = []
+    while startindex < len(astr):
+        mo = format_re.match(astr, pos=startindex)
+        try:
+            (order1, repeats, order2, dtype) = mo.groups()
+        except (TypeError, AttributeError):
+            raise ValueError('format number %d of "%s" is not recognized' %
+                                            (len(result)+1, astr))
+        startindex = mo.end()
+        # Separator or ending padding
+        if startindex < len(astr):
+            if space_re.match(astr, pos=startindex):
+                startindex = len(astr)
+            else:
+                mo = sep_re.match(astr, pos=startindex)
+                if not mo:
+                    raise ValueError(
+                        'format number %d of "%s" is not recognized' %
+                        (len(result)+1, astr))
+                startindex = mo.end()
+
+        if order2 == asbytes(''):
+            order = order1
+        elif order1 == asbytes(''):
+            order = order2
+        else:
+            order1 = _convorder.get(order1, order1)
+            order2 = _convorder.get(order2, order2)
+            if (order1 != order2):
+                raise ValueError(
+                    'inconsistent byte-order specification %s and %s' %
+                    (order1, order2))
+            order = order1
+
+        if order in [asbytes('|'), asbytes('='), _nbo]:
+            order = asbytes('')
+        dtype = order + dtype
+        if (repeats == asbytes('')):
+            newitem = dtype
+        else:
+            newitem = (dtype, eval(repeats))
+        result.append(newitem)
+
+    return result
+
+def _getintp_ctype():
+    val = _getintp_ctype.cache
+    if val is not None:
+        return val
+    char = dtype('p').char
+    if (char == 'i'):
+        val = ctypes.c_int
+    elif char == 'l':
+        val = ctypes.c_long
+    elif char == 'q':
+        val = ctypes.c_longlong
+    else:
+        val = ctypes.c_long
+    _getintp_ctype.cache = val
+    return val
+_getintp_ctype.cache = None
+
+# Used for .ctypes attribute of ndarray
+
+class _missing_ctypes(object):
+    def cast(self, num, obj):
+        return num
+
+    def c_void_p(self, num):
+        return num
+
+class _ctypes(object):
+    def __init__(self, array, ptr=None):
+        try:
+            self._ctypes = ctypes
+        except ImportError:
+            self._ctypes = _missing_ctypes()
+        self._arr = array
+        self._data = ptr
+        if self._arr.ndim == 0:
+            self._zerod = True
+        else:
+            self._zerod = False
+
+    def data_as(self, obj):
+        return self._ctypes.cast(self._data, obj)
+
+    def shape_as(self, obj):
+        if self._zerod:
+            return None
+        return (obj*self._arr.ndim)(*self._arr.shape)
+
+    def strides_as(self, obj):
+        if self._zerod:
+            return None
+        return (obj*self._arr.ndim)(*self._arr.strides)
+
+    def get_data(self):
+        return self._data
+
+    def get_shape(self):
+        if self._zerod:
+            return None
+        return (_getintp_ctype()*self._arr.ndim)(*self._arr.shape)
+
+    def get_strides(self):
+        if self._zerod:
+            return None
+        return (_getintp_ctype()*self._arr.ndim)(*self._arr.strides)
+
+    def get_as_parameter(self):
+        return self._ctypes.c_void_p(self._data)
+
+    data = property(get_data, None, doc="c-types data")
+    shape = property(get_shape, None, doc="c-types shape")
+    strides = property(get_strides, None, doc="c-types strides")
+    _as_parameter_ = property(get_as_parameter, None, doc="_as parameter_")
+
+
+# Given a datatype and an order object
+#  return a new names tuple
+#  with the order indicated
+def _newnames(datatype, order):
+    oldnames = datatype.names
+    nameslist = list(oldnames)
+    if isinstance(order, str):
+        order = [order]
+    if isinstance(order, (list, tuple)):
+        for name in order:
+            try:
+                nameslist.remove(name)
+            except ValueError:
+                raise ValueError("unknown field name: %s" % (name,))
+        return tuple(list(order) + nameslist)
+    raise ValueError("unsupported order value: %s" % (order,))
+
+def _copy_fields(ary):
+    """Return copy of structured array with padding between fields removed.
+
+    Parameters
+    ----------
+    ary : ndarray
+       Structured array from which to remove padding bytes
+
+    Returns
+    -------
+    ary_copy : ndarray
+       Copy of ary with padding bytes removed
+    """
+    dt = ary.dtype
+    copy_dtype = {'names': dt.names,
+                  'formats': [dt.fields[name][0] for name in dt.names]}
+    return array(ary, dtype=copy_dtype, copy=True)
+
+def _getfield_is_safe(oldtype, newtype, offset):
+    """ Checks safety of getfield for object arrays.
+
+    As in _view_is_safe, we need to check that memory containing objects is not
+    reinterpreted as a non-object datatype and vice versa.
+
+    Parameters
+    ----------
+    oldtype : data-type
+        Data type of the original ndarray.
+    newtype : data-type
+        Data type of the field being accessed by ndarray.getfield
+    offset : int
+        Offset of the field being accessed by ndarray.getfield
+
+    Raises
+    ------
+    TypeError
+        If the field access is invalid
+
+    """
+    if newtype.hasobject or oldtype.hasobject:
+        if offset == 0 and newtype == oldtype:
+            return
+        if oldtype.names:
+            for name in oldtype.names:
+                if (oldtype.fields[name][1] == offset and
+                        oldtype.fields[name][0] == newtype):
+                    return
+        raise TypeError("Cannot get/set field of an object array")
+    return
+
+def _view_is_safe(oldtype, newtype):
+    """ Checks safety of a view involving object arrays, for example when
+    doing::
+
+        np.zeros(10, dtype=oldtype).view(newtype)
+
+    Parameters
+    ----------
+    oldtype : data-type
+        Data type of original ndarray
+    newtype : data-type
+        Data type of the view
+
+    Raises
+    ------
+    TypeError
+        If the new type is incompatible with the old type.
+
+    """
+
+    # if the types are equivalent, there is no problem.
+    # for example: dtype((np.record, 'i4,i4')) == dtype((np.void, 'i4,i4'))
+    if oldtype == newtype:
+        return
+
+    if newtype.hasobject or oldtype.hasobject:
+        raise TypeError("Cannot change data-type for object array.")
+    return
+
+# Given a string containing a PEP 3118 format specifier,
+# construct a Numpy dtype
+
+_pep3118_native_map = {
+    '?': '?',
+    'b': 'b',
+    'B': 'B',
+    'h': 'h',
+    'H': 'H',
+    'i': 'i',
+    'I': 'I',
+    'l': 'l',
+    'L': 'L',
+    'q': 'q',
+    'Q': 'Q',
+    'e': 'e',
+    'f': 'f',
+    'd': 'd',
+    'g': 'g',
+    'Zf': 'F',
+    'Zd': 'D',
+    'Zg': 'G',
+    's': 'S',
+    'w': 'U',
+    'O': 'O',
+    'x': 'V',  # padding
+}
+_pep3118_native_typechars = ''.join(_pep3118_native_map.keys())
+
+_pep3118_standard_map = {
+    '?': '?',
+    'b': 'b',
+    'B': 'B',
+    'h': 'i2',
+    'H': 'u2',
+    'i': 'i4',
+    'I': 'u4',
+    'l': 'i4',
+    'L': 'u4',
+    'q': 'i8',
+    'Q': 'u8',
+    'e': 'f2',
+    'f': 'f',
+    'd': 'd',
+    'Zf': 'F',
+    'Zd': 'D',
+    's': 'S',
+    'w': 'U',
+    'O': 'O',
+    'x': 'V',  # padding
+}
+_pep3118_standard_typechars = ''.join(_pep3118_standard_map.keys())
+
+def _dtype_from_pep3118(spec, byteorder='@', is_subdtype=False):
+    fields = {}
+    offset = 0
+    explicit_name = False
+    this_explicit_name = False
+    common_alignment = 1
+    is_padding = False
+
+    dummy_name_index = [0]
+
+    def next_dummy_name():
+        dummy_name_index[0] += 1
+
+    def get_dummy_name():
+        while True:
+            name = 'f%d' % dummy_name_index[0]
+            if name not in fields:
+                return name
+            next_dummy_name()
+
+    # Parse spec
+    while spec:
+        value = None
+
+        # End of structure, bail out to upper level
+        if spec[0] == '}':
+            spec = spec[1:]
+            break
+
+        # Sub-arrays (1)
+        shape = None
+        if spec[0] == '(':
+            j = spec.index(')')
+            shape = tuple(map(int, spec[1:j].split(',')))
+            spec = spec[j+1:]
+
+        # Byte order
+        if spec[0] in ('@', '=', '<', '>', '^', '!'):
+            byteorder = spec[0]
+            if byteorder == '!':
+                byteorder = '>'
+            spec = spec[1:]
+
+        # Byte order characters also control native vs. standard type sizes
+        if byteorder in ('@', '^'):
+            type_map = _pep3118_native_map
+            type_map_chars = _pep3118_native_typechars
+        else:
+            type_map = _pep3118_standard_map
+            type_map_chars = _pep3118_standard_typechars
+
+        # Item sizes
+        itemsize = 1
+        if spec[0].isdigit():
+            j = 1
+            for j in range(1, len(spec)):
+                if not spec[j].isdigit():
+                    break
+            itemsize = int(spec[:j])
+            spec = spec[j:]
+
+        # Data types
+        is_padding = False
+
+        if spec[:2] == 'T{':
+            value, spec, align, next_byteorder = _dtype_from_pep3118(
+                spec[2:], byteorder=byteorder, is_subdtype=True)
+        elif spec[0] in type_map_chars:
+            next_byteorder = byteorder
+            if spec[0] == 'Z':
+                j = 2
+            else:
+                j = 1
+            typechar = spec[:j]
+            spec = spec[j:]
+            is_padding = (typechar == 'x')
+            dtypechar = type_map[typechar]
+            if dtypechar in 'USV':
+                dtypechar += '%d' % itemsize
+                itemsize = 1
+            numpy_byteorder = {'@': '=', '^': '='}.get(byteorder, byteorder)
+            value = dtype(numpy_byteorder + dtypechar)
+            align = value.alignment
+        else:
+            raise ValueError("Unknown PEP 3118 data type specifier %r" % spec)
+
+        #
+        # Native alignment may require padding
+        #
+        # Here we assume that the presence of a '@' character implicitly implies
+        # that the start of the array is *already* aligned.
+        #
+        extra_offset = 0
+        if byteorder == '@':
+            start_padding = (-offset) % align
+            intra_padding = (-value.itemsize) % align
+
+            offset += start_padding
+
+            if intra_padding != 0:
+                if itemsize > 1 or (shape is not None and _prod(shape) > 1):
+                    # Inject internal padding to the end of the sub-item
+                    value = _add_trailing_padding(value, intra_padding)
+                else:
+                    # We can postpone the injection of internal padding,
+                    # as the item appears at most once
+                    extra_offset += intra_padding
+
+            # Update common alignment
+            common_alignment = (align*common_alignment
+                                / _gcd(align, common_alignment))
+
+        # Convert itemsize to sub-array
+        if itemsize != 1:
+            value = dtype((value, (itemsize,)))
+
+        # Sub-arrays (2)
+        if shape is not None:
+            value = dtype((value, shape))
+
+        # Field name
+        this_explicit_name = False
+        if spec and spec.startswith(':'):
+            i = spec[1:].index(':') + 1
+            name = spec[1:i]
+            spec = spec[i+1:]
+            explicit_name = True
+            this_explicit_name = True
+        else:
+            name = get_dummy_name()
+
+        if not is_padding or this_explicit_name:
+            if name in fields:
+                raise RuntimeError("Duplicate field name '%s' in PEP3118 format"
+                                   % name)
+            fields[name] = (value, offset)
+            if not this_explicit_name:
+                next_dummy_name()
+
+        byteorder = next_byteorder
+
+        offset += value.itemsize
+        offset += extra_offset
+
+    # Check if this was a simple 1-item type
+    if (len(fields) == 1 and not explicit_name and
+            fields['f0'][1] == 0 and not is_subdtype):
+        ret = fields['f0'][0]
+    else:
+        ret = dtype(fields)
+
+    # Trailing padding must be explicitly added
+    padding = offset - ret.itemsize
+    if byteorder == '@':
+        padding += (-offset) % common_alignment
+    if is_padding and not this_explicit_name:
+        ret = _add_trailing_padding(ret, padding)
+
+    # Finished
+    if is_subdtype:
+        return ret, spec, common_alignment, byteorder
+    else:
+        return ret
+
+def _add_trailing_padding(value, padding):
+    """Inject the specified number of padding bytes at the end of a dtype"""
+    if value.fields is None:
+        vfields = {'f0': (value, 0)}
+    else:
+        vfields = dict(value.fields)
+
+    if (value.names and value.names[-1] == '' and
+           value[''].char == 'V'):
+        # A trailing padding field is already present
+        vfields[''] = ('V%d' % (vfields[''][0].itemsize + padding),
+                       vfields[''][1])
+        value = dtype(vfields)
+    else:
+        # Get a free name for the padding field
+        j = 0
+        while True:
+            name = 'pad%d' % j
+            if name not in vfields:
+                vfields[name] = ('V%d' % padding, value.itemsize)
+                break
+            j += 1
+
+        value = dtype(vfields)
+        if '' not in vfields:
+            # Strip out the name of the padding field
+            names = list(value.names)
+            names[-1] = ''
+            value.names = tuple(names)
+    return value
+
+def _prod(a):
+    p = 1
+    for x in a:
+        p *= x
+    return p
+
+def _gcd(a, b):
+    """Calculate the greatest common divisor of a and b"""
+    while b:
+        a, b = b, a % b
+    return a
+
+# Exception used in shares_memory()
+class TooHardError(RuntimeError):
+    pass
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_methods.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_methods.py
new file mode 100644
index 0000000000..5fc2bc4450
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/_methods.py
@@ -0,0 +1,133 @@
+"""
+Array methods which are called by both the C-code for the method
+and the Python code for the NumPy-namespace function
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+from numpy.core import multiarray as mu
+from numpy.core import umath as um
+from numpy.core.numeric import asanyarray
+from numpy.core import numerictypes as nt
+
+# save those O(100) nanoseconds!
+umr_maximum = um.maximum.reduce
+umr_minimum = um.minimum.reduce
+umr_sum = um.add.reduce
+umr_prod = um.multiply.reduce
+umr_any = um.logical_or.reduce
+umr_all = um.logical_and.reduce
+
+# avoid keyword arguments to speed up parsing, saves about 15%-20% for very
+# small reductions
+def _amax(a, axis=None, out=None, keepdims=False):
+    return umr_maximum(a, axis, None, out, keepdims)
+
+def _amin(a, axis=None, out=None, keepdims=False):
+    return umr_minimum(a, axis, None, out, keepdims)
+
+def _sum(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_sum(a, axis, dtype, out, keepdims)
+
+def _prod(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_prod(a, axis, dtype, out, keepdims)
+
+def _any(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_any(a, axis, dtype, out, keepdims)
+
+def _all(a, axis=None, dtype=None, out=None, keepdims=False):
+    return umr_all(a, axis, dtype, out, keepdims)
+
+def _count_reduce_items(arr, axis):
+    if axis is None:
+        axis = tuple(range(arr.ndim))
+    if not isinstance(axis, tuple):
+        axis = (axis,)
+    items = 1
+    for ax in axis:
+        items *= arr.shape[ax]
+    return items
+
+def _mean(a, axis=None, dtype=None, out=None, keepdims=False):
+    arr = asanyarray(a)
+
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up first
+    if rcount == 0:
+        warnings.warn("Mean of empty slice.", RuntimeWarning)
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    ret = umr_sum(arr, axis, dtype, out, keepdims)
+    if isinstance(ret, mu.ndarray):
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(ret / rcount)
+    else:
+        ret = ret / rcount
+
+    return ret
+
+def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    arr = asanyarray(a)
+
+    rcount = _count_reduce_items(arr, axis)
+    # Make this warning show up on top.
+    if ddof >= rcount:
+        warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
+
+    # Cast bool, unsigned int, and int to float64 by default
+    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+        dtype = mu.dtype('f8')
+
+    # Compute the mean.
+    # Note that if dtype is not of inexact type then arraymean will
+    # not be either.
+    arrmean = umr_sum(arr, axis, dtype, keepdims=True)
+    if isinstance(arrmean, mu.ndarray):
+        arrmean = um.true_divide(
+                arrmean, rcount, out=arrmean, casting='unsafe', subok=False)
+    else:
+        arrmean = arrmean.dtype.type(arrmean / rcount)
+
+    # Compute sum of squared deviations from mean
+    # Note that x may not be inexact and that we need it to be an array,
+    # not a scalar.
+    x = asanyarray(arr - arrmean)
+    if issubclass(arr.dtype.type, nt.complexfloating):
+        x = um.multiply(x, um.conjugate(x), out=x).real
+    else:
+        x = um.multiply(x, x, out=x)
+    ret = umr_sum(x, axis, dtype, out, keepdims)
+
+    # Compute degrees of freedom and make sure it is not negative.
+    rcount = max([rcount - ddof, 0])
+
+    # divide by degrees of freedom
+    if isinstance(ret, mu.ndarray):
+        ret = um.true_divide(
+                ret, rcount, out=ret, casting='unsafe', subok=False)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(ret / rcount)
+    else:
+        ret = ret / rcount
+
+    return ret
+
+def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+               keepdims=keepdims)
+
+    if isinstance(ret, mu.ndarray):
+        ret = um.sqrt(ret, out=ret)
+    elif hasattr(ret, 'dtype'):
+        ret = ret.dtype.type(um.sqrt(ret))
+    else:
+        ret = um.sqrt(ret)
+
+    return ret
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.py
new file mode 100644
index 0000000000..282fbd1cfb
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.py
@@ -0,0 +1,754 @@
+"""Array printing function
+
+$Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ["array2string", "set_printoptions", "get_printoptions"]
+__docformat__ = 'restructuredtext'
+
+#
+# Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
+# last revision: 1996-3-13
+# modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details)
+# and by Perry Greenfield 2000-4-1 for numarray
+# and by Travis Oliphant  2005-8-22 for numpy
+
+import sys
+from functools import reduce
+from . import numerictypes as _nt
+from .umath import maximum, minimum, absolute, not_equal, isnan, isinf
+from .multiarray import (array, format_longfloat, datetime_as_string,
+                         datetime_data)
+from .fromnumeric import ravel
+from .numeric import asarray
+
+if sys.version_info[0] >= 3:
+    _MAXINT = sys.maxsize
+    _MININT = -sys.maxsize - 1
+else:
+    _MAXINT = sys.maxint
+    _MININT = -sys.maxint - 1
+
+def product(x, y):
+    return x*y
+
+_summaryEdgeItems = 3     # repr N leading and trailing items of each dimension
+_summaryThreshold = 1000  # total items > triggers array summarization
+
+_float_output_precision = 8
+_float_output_suppress_small = False
+_line_width = 75
+_nan_str = 'nan'
+_inf_str = 'inf'
+_formatter = None  # formatting function for array elements
+
+
+def set_printoptions(precision=None, threshold=None, edgeitems=None,
+                     linewidth=None, suppress=None,
+                     nanstr=None, infstr=None,
+                     formatter=None):
+    """
+    Set printing options.
+
+    These options determine the way floating point numbers, arrays and
+    other NumPy objects are displayed.
+
+    Parameters
+    ----------
+    precision : int, optional
+        Number of digits of precision for floating point output (default 8).
+    threshold : int, optional
+        Total number of array elements which trigger summarization
+        rather than full repr (default 1000).
+    edgeitems : int, optional
+        Number of array items in summary at beginning and end of
+        each dimension (default 3).
+    linewidth : int, optional
+        The number of characters per line for the purpose of inserting
+        line breaks (default 75).
+    suppress : bool, optional
+        Whether or not suppress printing of small floating point values
+        using scientific notation (default False).
+    nanstr : str, optional
+        String representation of floating point not-a-number (default nan).
+    infstr : str, optional
+        String representation of floating point infinity (default inf).
+    formatter : dict of callables, optional
+        If not None, the keys should indicate the type(s) that the respective
+        formatting function applies to.  Callables should return a string.
+        Types that are not specified (by their corresponding keys) are handled
+        by the default formatters.  Individual types for which a formatter
+        can be set are::
+
+            - 'bool'
+            - 'int'
+            - 'timedelta' : a `numpy.timedelta64`
+            - 'datetime' : a `numpy.datetime64`
+            - 'float'
+            - 'longfloat' : 128-bit floats
+            - 'complexfloat'
+            - 'longcomplexfloat' : composed of two 128-bit floats
+            - 'numpy_str' : 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'
+
+    See Also
+    --------
+    get_printoptions, set_string_function, array2string
+
+    Notes
+    -----
+    `formatter` is always reset with a call to `set_printoptions`.
+
+    Examples
+    --------
+    Floating point precision can be set:
+
+    >>> np.set_printoptions(precision=4)
+    >>> print(np.array([1.123456789]))
+    [ 1.1235]
+
+    Long arrays can be summarised:
+
+    >>> np.set_printoptions(threshold=5)
+    >>> print(np.arange(10))
+    [0 1 2 ..., 7 8 9]
+
+    Small results can be suppressed:
+
+    >>> eps = np.finfo(float).eps
+    >>> x = np.arange(4.)
+    >>> x**2 - (x + eps)**2
+    array([ -4.9304e-32,  -4.4409e-16,   0.0000e+00,   0.0000e+00])
+    >>> np.set_printoptions(suppress=True)
+    >>> x**2 - (x + eps)**2
+    array([-0., -0.,  0.,  0.])
+
+    A custom formatter can be used to display array elements as desired:
+
+    >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)})
+    >>> x = np.arange(3)
+    >>> x
+    array([int: 0, int: -1, int: -2])
+    >>> np.set_printoptions()  # formatter gets reset
+    >>> x
+    array([0, 1, 2])
+
+    To put back the default options, you can use:
+
+    >>> np.set_printoptions(edgeitems=3,infstr='inf',
+    ... linewidth=75, nanstr='nan', precision=8,
+    ... suppress=False, threshold=1000, formatter=None)
+    """
+
+    global _summaryThreshold, _summaryEdgeItems, _float_output_precision
+    global _line_width, _float_output_suppress_small, _nan_str, _inf_str
+    global _formatter
+
+    if linewidth is not None:
+        _line_width = linewidth
+    if threshold is not None:
+        _summaryThreshold = threshold
+    if edgeitems is not None:
+        _summaryEdgeItems = edgeitems
+    if precision is not None:
+        _float_output_precision = precision
+    if suppress is not None:
+        _float_output_suppress_small = not not suppress
+    if nanstr is not None:
+        _nan_str = nanstr
+    if infstr is not None:
+        _inf_str = infstr
+    _formatter = formatter
+
+def get_printoptions():
+    """
+    Return the current print options.
+
+    Returns
+    -------
+    print_opts : dict
+        Dictionary of current print options with keys
+
+          - precision : int
+          - threshold : int
+          - edgeitems : int
+          - linewidth : int
+          - suppress : bool
+          - nanstr : str
+          - infstr : str
+          - formatter : dict of callables
+
+        For a full description of these options, see `set_printoptions`.
+
+    See Also
+    --------
+    set_printoptions, set_string_function
+
+    """
+    d = dict(precision=_float_output_precision,
+             threshold=_summaryThreshold,
+             edgeitems=_summaryEdgeItems,
+             linewidth=_line_width,
+             suppress=_float_output_suppress_small,
+             nanstr=_nan_str,
+             infstr=_inf_str,
+             formatter=_formatter)
+    return d
+
+def _leading_trailing(a):
+    from . import numeric as _nc
+    if a.ndim == 1:
+        if len(a) > 2*_summaryEdgeItems:
+            b = _nc.concatenate((a[:_summaryEdgeItems],
+                                     a[-_summaryEdgeItems:]))
+        else:
+            b = a
+    else:
+        if len(a) > 2*_summaryEdgeItems:
+            l = [_leading_trailing(a[i]) for i in range(
+                min(len(a), _summaryEdgeItems))]
+            l.extend([_leading_trailing(a[-i]) for i in range(
+                min(len(a), _summaryEdgeItems), 0, -1)])
+        else:
+            l = [_leading_trailing(a[i]) for i in range(0, len(a))]
+        b = _nc.concatenate(tuple(l))
+    return b
+
+def _boolFormatter(x):
+    if x:
+        return ' True'
+    else:
+        return 'False'
+
+
+def repr_format(x):
+    return repr(x)
+
+def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
+                  prefix="", formatter=None):
+
+    if max_line_width is None:
+        max_line_width = _line_width
+
+    if precision is None:
+        precision = _float_output_precision
+
+    if suppress_small is None:
+        suppress_small = _float_output_suppress_small
+
+    if formatter is None:
+        formatter = _formatter
+
+    if a.size > _summaryThreshold:
+        summary_insert = "..., "
+        data = _leading_trailing(a)
+    else:
+        summary_insert = ""
+        data = ravel(asarray(a))
+
+    formatdict = {'bool': _boolFormatter,
+                  'int': IntegerFormat(data),
+                  'float': FloatFormat(data, precision, suppress_small),
+                  'longfloat': LongFloatFormat(precision),
+                  'complexfloat': ComplexFormat(data, precision,
+                                                 suppress_small),
+                  'longcomplexfloat': LongComplexFormat(precision),
+                  'datetime': DatetimeFormat(data),
+                  'timedelta': TimedeltaFormat(data),
+                  'numpystr': repr_format,
+                  'str': str}
+
+    if formatter is not None:
+        fkeys = [k for k in formatter.keys() if formatter[k] is not None]
+        if 'all' in fkeys:
+            for key in formatdict.keys():
+                formatdict[key] = formatter['all']
+        if 'int_kind' in fkeys:
+            for key in ['int']:
+                formatdict[key] = formatter['int_kind']
+        if 'float_kind' in fkeys:
+            for key in ['float', 'longfloat']:
+                formatdict[key] = formatter['float_kind']
+        if 'complex_kind' in fkeys:
+            for key in ['complexfloat', 'longcomplexfloat']:
+                formatdict[key] = formatter['complex_kind']
+        if 'str_kind' in fkeys:
+            for key in ['numpystr', 'str']:
+                formatdict[key] = formatter['str_kind']
+        for key in formatdict.keys():
+            if key in fkeys:
+                formatdict[key] = formatter[key]
+
+    # find the right formatting function for the array
+    dtypeobj = a.dtype.type
+    if issubclass(dtypeobj, _nt.bool_):
+        format_function = formatdict['bool']
+    elif issubclass(dtypeobj, _nt.integer):
+        if issubclass(dtypeobj, _nt.timedelta64):
+            format_function = formatdict['timedelta']
+        else:
+            format_function = formatdict['int']
+    elif issubclass(dtypeobj, _nt.floating):
+        if issubclass(dtypeobj, _nt.longfloat):
+            format_function = formatdict['longfloat']
+        else:
+            format_function = formatdict['float']
+    elif issubclass(dtypeobj, _nt.complexfloating):
+        if issubclass(dtypeobj, _nt.clongfloat):
+            format_function = formatdict['longcomplexfloat']
+        else:
+            format_function = formatdict['complexfloat']
+    elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
+        format_function = formatdict['numpystr']
+    elif issubclass(dtypeobj, _nt.datetime64):
+        format_function = formatdict['datetime']
+    else:
+        format_function = formatdict['numpystr']
+
+    # skip over "["
+    next_line_prefix = " "
+    # skip over array(
+    next_line_prefix += " "*len(prefix)
+
+    lst = _formatArray(a, format_function, len(a.shape), max_line_width,
+                       next_line_prefix, separator,
+                       _summaryEdgeItems, summary_insert)[:-1]
+    return lst
+
+def _convert_arrays(obj):
+    from . import numeric as _nc
+    newtup = []
+    for k in obj:
+        if isinstance(k, _nc.ndarray):
+            k = k.tolist()
+        elif isinstance(k, tuple):
+            k = _convert_arrays(k)
+        newtup.append(k)
+    return tuple(newtup)
+
+
+def array2string(a, max_line_width=None, precision=None,
+                 suppress_small=None, separator=' ', prefix="",
+                 style=repr, formatter=None):
+    """
+    Return a string representation of an array.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    max_line_width : int, optional
+        The maximum number of columns the string should span. Newline
+        characters splits the string appropriately after array elements.
+    precision : int, optional
+        Floating point precision. Default is the current printing
+        precision (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent very small numbers as zero. A number is "very small" if it
+        is smaller than the current printing precision.
+    separator : str, optional
+        Inserted between elements.
+    prefix : str, optional
+        An array is typically printed as::
+
+          'prefix(' + array2string(a) + ')'
+
+        The length of the prefix string is used to align the
+        output correctly.
+    style : function, optional
+        A function that accepts an ndarray and returns a string.  Used only
+        when the shape of `a` is equal to ``()``, i.e. for 0-D arrays.
+    formatter : dict of callables, optional
+        If not None, the keys should indicate the type(s) that the respective
+        formatting function applies to.  Callables should return a string.
+        Types that are not specified (by their corresponding keys) are handled
+        by the default formatters.  Individual types for which a formatter
+        can be set are::
+
+            - 'bool'
+            - 'int'
+            - 'timedelta' : a `numpy.timedelta64`
+            - 'datetime' : a `numpy.datetime64`
+            - 'float'
+            - 'longfloat' : 128-bit floats
+            - 'complexfloat'
+            - 'longcomplexfloat' : composed of two 128-bit floats
+            - 'numpy_str' : 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'
+
+    Returns
+    -------
+    array_str : str
+        String representation of the array.
+
+    Raises
+    ------
+    TypeError
+        if a callable in `formatter` does not return a string.
+
+    See Also
+    --------
+    array_str, array_repr, set_printoptions, get_printoptions
+
+    Notes
+    -----
+    If a formatter is specified for a certain type, the `precision` keyword is
+    ignored for that type.
+
+    This is a very flexible function; `array_repr` and `array_str` are using
+    `array2string` internally so keywords with the same name should work
+    identically in all three functions.
+
+    Examples
+    --------
+    >>> x = np.array([1e-16,1,2,3])
+    >>> print(np.array2string(x, precision=2, separator=',',
+    ...                       suppress_small=True))
+    [ 0., 1., 2., 3.]
+
+    >>> x  = np.arange(3.)
+    >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x})
+    '[0.00 1.00 2.00]'
+
+    >>> x  = np.arange(3)
+    >>> np.array2string(x, formatter={'int':lambda x: hex(x)})
+    '[0x0L 0x1L 0x2L]'
+
+    """
+
+    if a.shape == ():
+        x = a.item()
+        if isinstance(x, tuple):
+            x = _convert_arrays(x)
+        lst = style(x)
+    elif reduce(product, a.shape) == 0:
+        # treat as a null array if any of shape elements == 0
+        lst = "[]"
+    else:
+        lst = _array2string(a, max_line_width, precision, suppress_small,
+                            separator, prefix, formatter=formatter)
+    return lst
+
+def _extendLine(s, line, word, max_line_len, next_line_prefix):
+    if len(line.rstrip()) + len(word.rstrip()) >= max_line_len:
+        s += line.rstrip() + "\n"
+        line = next_line_prefix
+    line += word
+    return s, line
+
+
+def _formatArray(a, format_function, rank, max_line_len,
+                 next_line_prefix, separator, edge_items, summary_insert):
+    """formatArray is designed for two modes of operation:
+
+    1. Full output
+
+    2. Summarized output
+
+    """
+    if rank == 0:
+        obj = a.item()
+        if isinstance(obj, tuple):
+            obj = _convert_arrays(obj)
+        return str(obj)
+
+    if summary_insert and 2*edge_items < len(a):
+        leading_items = edge_items
+        trailing_items = edge_items
+        summary_insert1 = summary_insert
+    else:
+        leading_items = 0
+        trailing_items = len(a)
+        summary_insert1 = ""
+
+    if rank == 1:
+        s = ""
+        line = next_line_prefix
+        for i in range(leading_items):
+            word = format_function(a[i]) + separator
+            s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+
+        if summary_insert1:
+            s, line = _extendLine(s, line, summary_insert1, max_line_len, next_line_prefix)
+
+        for i in range(trailing_items, 1, -1):
+            word = format_function(a[-i]) + separator
+            s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+
+        word = format_function(a[-1])
+        s, line = _extendLine(s, line, word, max_line_len, next_line_prefix)
+        s += line + "]\n"
+        s = '[' + s[len(next_line_prefix):]
+    else:
+        s = '['
+        sep = separator.rstrip()
+        for i in range(leading_items):
+            if i > 0:
+                s += next_line_prefix
+            s += _formatArray(a[i], format_function, rank-1, max_line_len,
+                              " " + next_line_prefix, separator, edge_items,
+                              summary_insert)
+            s = s.rstrip() + sep.rstrip() + '\n'*max(rank-1, 1)
+
+        if summary_insert1:
+            s += next_line_prefix + summary_insert1 + "\n"
+
+        for i in range(trailing_items, 1, -1):
+            if leading_items or i != trailing_items:
+                s += next_line_prefix
+            s += _formatArray(a[-i], format_function, rank-1, max_line_len,
+                              " " + next_line_prefix, separator, edge_items,
+                              summary_insert)
+            s = s.rstrip() + sep.rstrip() + '\n'*max(rank-1, 1)
+        if leading_items or trailing_items > 1:
+            s += next_line_prefix
+        s += _formatArray(a[-1], format_function, rank-1, max_line_len,
+                          " " + next_line_prefix, separator, edge_items,
+                          summary_insert).rstrip()+']\n'
+    return s
+
+class FloatFormat(object):
+    def __init__(self, data, precision, suppress_small, sign=False):
+        self.precision = precision
+        self.suppress_small = suppress_small
+        self.sign = sign
+        self.exp_format = False
+        self.large_exponent = False
+        self.max_str_len = 0
+        try:
+            self.fillFormat(data)
+        except (TypeError, NotImplementedError):
+            # if reduce(data) fails, this instance will not be called, just
+            # instantiated in formatdict.
+            pass
+
+    def fillFormat(self, data):
+        from . import numeric as _nc
+
+        with _nc.errstate(all='ignore'):
+            special = isnan(data) | isinf(data)
+            valid = not_equal(data, 0) & ~special
+            non_zero = absolute(data.compress(valid))
+            if len(non_zero) == 0:
+                max_val = 0.
+                min_val = 0.
+            else:
+                max_val = maximum.reduce(non_zero)
+                min_val = minimum.reduce(non_zero)
+                if max_val >= 1.e8:
+                    self.exp_format = True
+                if not self.suppress_small and (min_val < 0.0001
+                                           or max_val/min_val > 1000.):
+                    self.exp_format = True
+
+        if self.exp_format:
+            self.large_exponent = 0 < min_val < 1e-99 or max_val >= 1e100
+            self.max_str_len = 8 + self.precision
+            if self.large_exponent:
+                self.max_str_len += 1
+            if self.sign:
+                format = '%+'
+            else:
+                format = '%'
+            format = format + '%d.%de' % (self.max_str_len, self.precision)
+        else:
+            format = '%%.%df' % (self.precision,)
+            if len(non_zero):
+                precision = max([_digits(x, self.precision, format)
+                                 for x in non_zero])
+            else:
+                precision = 0
+            precision = min(self.precision, precision)
+            self.max_str_len = len(str(int(max_val))) + precision + 2
+            if _nc.any(special):
+                self.max_str_len = max(self.max_str_len,
+                                       len(_nan_str),
+                                       len(_inf_str)+1)
+            if self.sign:
+                format = '%#+'
+            else:
+                format = '%#'
+            format = format + '%d.%df' % (self.max_str_len, precision)
+
+        self.special_fmt = '%%%ds' % (self.max_str_len,)
+        self.format = format
+
+    def __call__(self, x, strip_zeros=True):
+        from . import numeric as _nc
+
+        with _nc.errstate(invalid='ignore'):
+            if isnan(x):
+                if self.sign:
+                    return self.special_fmt % ('+' + _nan_str,)
+                else:
+                    return self.special_fmt % (_nan_str,)
+            elif isinf(x):
+                if x > 0:
+                    if self.sign:
+                        return self.special_fmt % ('+' + _inf_str,)
+                    else:
+                        return self.special_fmt % (_inf_str,)
+                else:
+                    return self.special_fmt % ('-' + _inf_str,)
+
+        s = self.format % x
+        if self.large_exponent:
+            # 3-digit exponent
+            expsign = s[-3]
+            if expsign == '+' or expsign == '-':
+                s = s[1:-2] + '0' + s[-2:]
+        elif self.exp_format:
+            # 2-digit exponent
+            if s[-3] == '0':
+                s = ' ' + s[:-3] + s[-2:]
+        elif strip_zeros:
+            z = s.rstrip('0')
+            s = z + ' '*(len(s)-len(z))
+        return s
+
+
+def _digits(x, precision, format):
+    s = format % x
+    z = s.rstrip('0')
+    return precision - len(s) + len(z)
+
+
+class IntegerFormat(object):
+    def __init__(self, data):
+        try:
+            max_str_len = max(len(str(maximum.reduce(data))),
+                              len(str(minimum.reduce(data))))
+            self.format = '%' + str(max_str_len) + 'd'
+        except (TypeError, NotImplementedError):
+            # if reduce(data) fails, this instance will not be called, just
+            # instantiated in formatdict.
+            pass
+        except ValueError:
+            # this occurs when everything is NA
+            pass
+
+    def __call__(self, x):
+        if _MININT < x < _MAXINT:
+            return self.format % x
+        else:
+            return "%s" % x
+
+class LongFloatFormat(object):
+    # XXX Have to add something to determine the width to use a la FloatFormat
+    # Right now, things won't line up properly
+    def __init__(self, precision, sign=False):
+        self.precision = precision
+        self.sign = sign
+
+    def __call__(self, x):
+        if isnan(x):
+            if self.sign:
+                return '+' + _nan_str
+            else:
+                return ' ' + _nan_str
+        elif isinf(x):
+            if x > 0:
+                if self.sign:
+                    return '+' + _inf_str
+                else:
+                    return ' ' + _inf_str
+            else:
+                return '-' + _inf_str
+        elif x >= 0:
+            if self.sign:
+                return '+' + format_longfloat(x, self.precision)
+            else:
+                return ' ' + format_longfloat(x, self.precision)
+        else:
+            return format_longfloat(x, self.precision)
+
+
+class LongComplexFormat(object):
+    def __init__(self, precision):
+        self.real_format = LongFloatFormat(precision)
+        self.imag_format = LongFloatFormat(precision, sign=True)
+
+    def __call__(self, x):
+        r = self.real_format(x.real)
+        i = self.imag_format(x.imag)
+        return r + i + 'j'
+
+
+class ComplexFormat(object):
+    def __init__(self, x, precision, suppress_small):
+        self.real_format = FloatFormat(x.real, precision, suppress_small)
+        self.imag_format = FloatFormat(x.imag, precision, suppress_small,
+                                       sign=True)
+
+    def __call__(self, x):
+        r = self.real_format(x.real, strip_zeros=False)
+        i = self.imag_format(x.imag, strip_zeros=False)
+        if not self.imag_format.exp_format:
+            z = i.rstrip('0')
+            i = z + 'j' + ' '*(len(i)-len(z))
+        else:
+            i = i + 'j'
+        return r + i
+
+
+class DatetimeFormat(object):
+    def __init__(self, x, unit=None, timezone=None, casting='same_kind'):
+        # Get the unit from the dtype
+        if unit is None:
+            if x.dtype.kind == 'M':
+                unit = datetime_data(x.dtype)[0]
+            else:
+                unit = 's'
+
+        if timezone is None:
+            timezone = 'naive'
+        self.timezone = timezone
+        self.unit = unit
+        self.casting = casting
+
+    def __call__(self, x):
+        return "'%s'" % datetime_as_string(x,
+                                    unit=self.unit,
+                                    timezone=self.timezone,
+                                    casting=self.casting)
+
+class TimedeltaFormat(object):
+    def __init__(self, data):
+        if data.dtype.kind == 'm':
+            nat_value = array(['NaT'], dtype=data.dtype)[0]
+            v = data[not_equal(data, nat_value)].view('i8')
+            if len(v) > 0:
+                # Max str length of non-NaT elements
+                max_str_len = max(len(str(maximum.reduce(v))),
+                                  len(str(minimum.reduce(v))))
+            else:
+                max_str_len = 0
+            if len(v) < len(data):
+                # data contains a NaT
+                max_str_len = max(max_str_len, 5)
+            self.format = '%' + str(max_str_len) + 'd'
+            self._nat = "'NaT'".rjust(max_str_len)
+
+    def __call__(self, x):
+        if x + 1 == x:
+            return self._nat
+        else:
+            return self.format % x.astype('i8')
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/cversions.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/cversions.py
new file mode 100644
index 0000000000..7995dd9931
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/cversions.py
@@ -0,0 +1,15 @@
+"""Simple script to compute the api hash of the current API.
+
+The API has is defined by numpy_api_order and ufunc_api_order.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from os.path import dirname
+
+from code_generators.genapi import fullapi_hash
+from code_generators.numpy_api import full_api
+
+if __name__ == '__main__':
+    curdir = dirname(__file__)
+    print(fullapi_hash(full_api))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/defchararray.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/defchararray.py
new file mode 100644
index 0000000000..e18f912d60
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/defchararray.py
@@ -0,0 +1,2689 @@
+"""
+This module contains a set of functions for vectorized string
+operations and methods.
+
+.. note::
+   The `chararray` class exists for backwards compatibility with
+   Numarray, it is not recommended for new development. Starting from numpy
+   1.4, if one needs arrays of strings, it is recommended to use arrays of
+   `dtype` `object_`, `string_` or `unicode_`, and use the free functions
+   in the `numpy.char` module for fast vectorized string operations.
+
+Some methods will only be available if the corresponding string method is
+available in your version of Python.
+
+The preferred alias for `defchararray` is `numpy.char`.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+from .numerictypes import string_, unicode_, integer, object_, bool_, character
+from .numeric import ndarray, compare_chararrays
+from .numeric import array as narray
+from numpy.core.multiarray import _vec_string
+from numpy.compat import asbytes, long
+import numpy
+
+__all__ = [
+    'chararray', 'equal', 'not_equal', 'greater_equal', 'less_equal',
+    'greater', 'less', 'str_len', 'add', 'multiply', 'mod', 'capitalize',
+    'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+    'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
+    'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
+    'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit',
+    'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
+    'title', 'translate', 'upper', 'zfill', 'isnumeric', 'isdecimal',
+    'array', 'asarray'
+    ]
+
+
+_globalvar = 0
+if sys.version_info[0] >= 3:
+    _unicode = str
+    _bytes = bytes
+else:
+    _unicode = unicode
+    _bytes = str
+_len = len
+
+def _use_unicode(*args):
+    """
+    Helper function for determining the output type of some string
+    operations.
+
+    For an operation on two ndarrays, if at least one is unicode, the
+    result should be unicode.
+    """
+    for x in args:
+        if (isinstance(x, _unicode) or
+                issubclass(numpy.asarray(x).dtype.type, unicode_)):
+            return unicode_
+    return string_
+
+def _to_string_or_unicode_array(result):
+    """
+    Helper function to cast a result back into a string or unicode array
+    if an object array must be used as an intermediary.
+    """
+    return numpy.asarray(result.tolist())
+
+def _clean_args(*args):
+    """
+    Helper function for delegating arguments to Python string
+    functions.
+
+    Many of the Python string operations that have optional arguments
+    do not use 'None' to indicate a default value.  In these cases,
+    we need to remove all `None` arguments, and those following them.
+    """
+    newargs = []
+    for chk in args:
+        if chk is None:
+            break
+        newargs.append(chk)
+    return newargs
+
+def _get_num_chars(a):
+    """
+    Helper function that returns the number of characters per field in
+    a string or unicode array.  This is to abstract out the fact that
+    for a unicode array this is itemsize / 4.
+    """
+    if issubclass(a.dtype.type, unicode_):
+        return a.itemsize // 4
+    return a.itemsize
+
+
+def equal(x1, x2):
+    """
+    Return (x1 == x2) element-wise.
+
+    Unlike `numpy.equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    not_equal, greater_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '==', True)
+
+def not_equal(x1, x2):
+    """
+    Return (x1 != x2) element-wise.
+
+    Unlike `numpy.not_equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, greater_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '!=', True)
+
+def greater_equal(x1, x2):
+    """
+    Return (x1 >= x2) element-wise.
+
+    Unlike `numpy.greater_equal`, this comparison is performed by
+    first stripping whitespace characters from the end of the string.
+    This behavior is provided for backward-compatibility with
+    numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, less_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '>=', True)
+
+def less_equal(x1, x2):
+    """
+    Return (x1 <= x2) element-wise.
+
+    Unlike `numpy.less_equal`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, greater, less
+    """
+    return compare_chararrays(x1, x2, '<=', True)
+
+def greater(x1, x2):
+    """
+    Return (x1 > x2) element-wise.
+
+    Unlike `numpy.greater`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, less_equal, less
+    """
+    return compare_chararrays(x1, x2, '>', True)
+
+def less(x1, x2):
+    """
+    Return (x1 < x2) element-wise.
+
+    Unlike `numpy.greater`, this comparison is performed by first
+    stripping whitespace characters from the end of the string.  This
+    behavior is provided for backward-compatibility with numarray.
+
+    Parameters
+    ----------
+    x1, x2 : array_like of str or unicode
+        Input arrays of the same shape.
+
+    Returns
+    -------
+    out : ndarray or bool
+        Output array of bools, or a single bool if x1 and x2 are scalars.
+
+    See Also
+    --------
+    equal, not_equal, greater_equal, less_equal, greater
+    """
+    return compare_chararrays(x1, x2, '<', True)
+
+def str_len(a):
+    """
+    Return len(a) element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of integers
+
+    See also
+    --------
+    __builtin__.len
+    """
+    return _vec_string(a, integer, '__len__')
+
+def add(x1, x2):
+    """
+    Return element-wise string concatenation for two arrays of str or unicode.
+
+    Arrays `x1` and `x2` must have the same shape.
+
+    Parameters
+    ----------
+    x1 : array_like of str or unicode
+        Input array.
+    x2 : array_like of str or unicode
+        Input array.
+
+    Returns
+    -------
+    add : ndarray
+        Output array of `string_` or `unicode_`, depending on input types
+        of the same shape as `x1` and `x2`.
+
+    """
+    arr1 = numpy.asarray(x1)
+    arr2 = numpy.asarray(x2)
+    out_size = _get_num_chars(arr1) + _get_num_chars(arr2)
+    dtype = _use_unicode(arr1, arr2)
+    return _vec_string(arr1, (dtype, out_size), '__add__', (arr2,))
+
+def multiply(a, i):
+    """
+    Return (a * i), that is string multiple concatenation,
+    element-wise.
+
+    Values in `i` of less than 0 are treated as 0 (which yields an
+    empty string).
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    i : array_like of ints
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    """
+    a_arr = numpy.asarray(a)
+    i_arr = numpy.asarray(i)
+    if not issubclass(i_arr.dtype.type, integer):
+        raise ValueError("Can only multiply by integers")
+    out_size = _get_num_chars(a_arr) * max(long(i_arr.max()), 0)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, out_size), '__mul__', (i_arr,))
+
+def mod(a, values):
+    """
+    Return (a % i), that is pre-Python 2.6 string formatting
+    (iterpolation), element-wise for a pair of array_likes of str
+    or unicode.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    values : array_like of values
+       These values will be element-wise interpolated into the string.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    See also
+    --------
+    str.__mod__
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, '__mod__', (values,)))
+
+def capitalize(a):
+    """
+    Return a copy of `a` with only the first character of each element
+    capitalized.
+
+    Calls `str.capitalize` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array of strings to capitalize.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input
+        types
+
+    See also
+    --------
+    str.capitalize
+
+    Examples
+    --------
+    >>> c = np.array(['a1b2','1b2a','b2a1','2a1b'],'S4'); c
+    array(['a1b2', '1b2a', 'b2a1', '2a1b'],
+        dtype='|S4')
+    >>> np.char.capitalize(c)
+    array(['A1b2', '1b2a', 'B2a1', '2a1b'],
+        dtype='|S4')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'capitalize')
+
+
+def center(a, width, fillchar=' '):
+    """
+    Return a copy of `a` with its elements centered in a string of
+    length `width`.
+
+    Calls `str.center` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The padding character to use (default is space).
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input
+        types
+
+    See also
+    --------
+    str.center
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'center', (width_arr, fillchar))
+
+
+def count(a, sub, start=0, end=None):
+    """
+    Returns an array with the number of non-overlapping occurrences of
+    substring `sub` in the range [`start`, `end`].
+
+    Calls `str.count` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+       The substring to search for.
+
+    start, end : int, optional
+       Optional arguments `start` and `end` are interpreted as slice
+       notation to specify the range in which to count.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of ints.
+
+    See also
+    --------
+    str.count
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.count(c, 'A')
+    array([3, 1, 1])
+    >>> np.char.count(c, 'aA')
+    array([3, 1, 0])
+    >>> np.char.count(c, 'A', start=1, end=4)
+    array([2, 1, 1])
+    >>> np.char.count(c, 'A', start=1, end=3)
+    array([1, 0, 0])
+
+    """
+    return _vec_string(a, integer, 'count', [sub, start] + _clean_args(end))
+
+
+def decode(a, encoding=None, errors=None):
+    """
+    Calls `str.decode` element-wise.
+
+    The set of available codecs comes from the Python standard library,
+    and may be extended at runtime.  For more information, see the
+    :mod:`codecs` module.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    encoding : str, optional
+       The name of an encoding
+
+    errors : str, optional
+       Specifies how to handle encoding errors
+
+    Returns
+    -------
+    out : ndarray
+
+    See also
+    --------
+    str.decode
+
+    Notes
+    -----
+    The type of the result will depend on the encoding specified.
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.encode(c, encoding='cp037')
+    array(['\\x81\\xc1\\x81\\xc1\\x81\\xc1', '@@\\x81\\xc1@@',
+        '\\x81\\x82\\xc2\\xc1\\xc2\\x82\\x81'],
+        dtype='|S7')
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'decode', _clean_args(encoding, errors)))
+
+
+def encode(a, encoding=None, errors=None):
+    """
+    Calls `str.encode` element-wise.
+
+    The set of available codecs comes from the Python standard library,
+    and may be extended at runtime. For more information, see the codecs
+    module.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    encoding : str, optional
+       The name of an encoding
+
+    errors : str, optional
+       Specifies how to handle encoding errors
+
+    Returns
+    -------
+    out : ndarray
+
+    See also
+    --------
+    str.encode
+
+    Notes
+    -----
+    The type of the result will depend on the encoding specified.
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'encode', _clean_args(encoding, errors)))
+
+
+def endswith(a, suffix, start=0, end=None):
+    """
+    Returns a boolean array which is `True` where the string element
+    in `a` ends with `suffix`, otherwise `False`.
+
+    Calls `str.endswith` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    suffix : str
+
+    start, end : int, optional
+        With optional `start`, test beginning at that position. With
+        optional `end`, stop comparing at that position.
+
+    Returns
+    -------
+    out : ndarray
+        Outputs an array of bools.
+
+    See also
+    --------
+    str.endswith
+
+    Examples
+    --------
+    >>> s = np.array(['foo', 'bar'])
+    >>> s[0] = 'foo'
+    >>> s[1] = 'bar'
+    >>> s
+    array(['foo', 'bar'],
+        dtype='|S3')
+    >>> np.char.endswith(s, 'ar')
+    array([False,  True], dtype=bool)
+    >>> np.char.endswith(s, 'a', start=1, end=2)
+    array([False,  True], dtype=bool)
+
+    """
+    return _vec_string(
+        a, bool_, 'endswith', [suffix, start] + _clean_args(end))
+
+
+def expandtabs(a, tabsize=8):
+    """
+    Return a copy of each string element where all tab characters are
+    replaced by one or more spaces.
+
+    Calls `str.expandtabs` element-wise.
+
+    Return a copy of each string element where all tab characters are
+    replaced by one or more spaces, depending on the current column
+    and the given `tabsize`. The column number is reset to zero after
+    each newline occurring in the string. This doesn't understand other
+    non-printing characters or escape sequences.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array
+    tabsize : int, optional
+        Replace tabs with `tabsize` number of spaces.  If not given defaults
+        to 8 spaces.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.expandtabs
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'expandtabs', (tabsize,)))
+
+
+def find(a, sub, start=0, end=None):
+    """
+    For each element, return the lowest index in the string where
+    substring `sub` is found.
+
+    Calls `str.find` element-wise.
+
+    For each element, return the lowest index in the string where
+    substring `sub` is found, such that `sub` is contained in the
+    range [`start`, `end`].
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+        Optional arguments `start` and `end` are interpreted as in
+        slice notation.
+
+    Returns
+    -------
+    out : ndarray or int
+        Output array of ints.  Returns -1 if `sub` is not found.
+
+    See also
+    --------
+    str.find
+
+    """
+    return _vec_string(
+        a, integer, 'find', [sub, start] + _clean_args(end))
+
+
+def index(a, sub, start=0, end=None):
+    """
+    Like `find`, but raises `ValueError` when the substring is not found.
+
+    Calls `str.index` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+
+    Returns
+    -------
+    out : ndarray
+        Output array of ints.  Returns -1 if `sub` is not found.
+
+    See also
+    --------
+    find, str.find
+
+    """
+    return _vec_string(
+        a, integer, 'index', [sub, start] + _clean_args(end))
+
+def isalnum(a):
+    """
+    Returns true for each element if all characters in the string are
+    alphanumeric and there is at least one character, false otherwise.
+
+    Calls `str.isalnum` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.isalnum
+    """
+    return _vec_string(a, bool_, 'isalnum')
+
+def isalpha(a):
+    """
+    Returns true for each element if all characters in the string are
+    alphabetic and there is at least one character, false otherwise.
+
+    Calls `str.isalpha` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isalpha
+    """
+    return _vec_string(a, bool_, 'isalpha')
+
+def isdigit(a):
+    """
+    Returns true for each element if all characters in the string are
+    digits and there is at least one character, false otherwise.
+
+    Calls `str.isdigit` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isdigit
+    """
+    return _vec_string(a, bool_, 'isdigit')
+
+def islower(a):
+    """
+    Returns true for each element if all cased characters in the
+    string are lowercase and there is at least one cased character,
+    false otherwise.
+
+    Calls `str.islower` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.islower
+    """
+    return _vec_string(a, bool_, 'islower')
+
+def isspace(a):
+    """
+    Returns true for each element if there are only whitespace
+    characters in the string and there is at least one character,
+    false otherwise.
+
+    Calls `str.isspace` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isspace
+    """
+    return _vec_string(a, bool_, 'isspace')
+
+def istitle(a):
+    """
+    Returns true for each element if the element is a titlecased
+    string and there is at least one character, false otherwise.
+
+    Call `str.istitle` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.istitle
+    """
+    return _vec_string(a, bool_, 'istitle')
+
+def isupper(a):
+    """
+    Returns true for each element if all cased characters in the
+    string are uppercase and there is at least one character, false
+    otherwise.
+
+    Call `str.isupper` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of bools
+
+    See also
+    --------
+    str.isupper
+    """
+    return _vec_string(a, bool_, 'isupper')
+
+def join(sep, seq):
+    """
+    Return a string which is the concatenation of the strings in the
+    sequence `seq`.
+
+    Calls `str.join` element-wise.
+
+    Parameters
+    ----------
+    sep : array_like of str or unicode
+    seq : array_like of str or unicode
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input types
+
+    See also
+    --------
+    str.join
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(sep, object_, 'join', (seq,)))
+
+
+def ljust(a, width, fillchar=' '):
+    """
+    Return an array with the elements of `a` left-justified in a
+    string of length `width`.
+
+    Calls `str.ljust` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The character to use for padding
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.ljust
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'ljust', (width_arr, fillchar))
+
+
+def lower(a):
+    """
+    Return an array with the elements converted to lowercase.
+
+    Call `str.lower` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.lower
+
+    Examples
+    --------
+    >>> c = np.array(['A1B C', '1BCA', 'BCA1']); c
+    array(['A1B C', '1BCA', 'BCA1'],
+          dtype='|S5')
+    >>> np.char.lower(c)
+    array(['a1b c', '1bca', 'bca1'],
+          dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'lower')
+
+
+def lstrip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the leading characters
+    removed.
+
+    Calls `str.lstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like, {str, unicode}
+        Input array.
+
+    chars : {str, unicode}, optional
+        The `chars` argument is a string specifying the set of
+        characters to be removed. If omitted or None, the `chars`
+        argument defaults to removing whitespace. The `chars` argument
+        is not a prefix; rather, all combinations of its values are
+        stripped.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.lstrip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+
+    The 'a' variable is unstripped from c[1] because whitespace leading.
+
+    >>> np.char.lstrip(c, 'a')
+    array(['AaAaA', '  aA  ', 'bBABba'],
+        dtype='|S7')
+
+
+    >>> np.char.lstrip(c, 'A') # leaves c unchanged
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, '')).all()
+    ... # XXX: is this a regression? this line now returns False
+    ... # np.char.lstrip(c,'') does not modify c at all.
+    True
+    >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, None)).all()
+    True
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'lstrip', (chars,))
+
+
+def partition(a, sep):
+    """
+    Partition each element in `a` around `sep`.
+
+    Calls `str.partition` element-wise.
+
+    For each element in `a`, split the element as the first
+    occurrence of `sep`, and return 3 strings containing the part
+    before the separator, the separator itself, and the part after
+    the separator. If the separator is not found, return 3 strings
+    containing the string itself, followed by two empty strings.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array
+    sep : {str, unicode}
+        Separator to split each string element in `a`.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type.
+        The output array will have an extra dimension with 3
+        elements per input element.
+
+    See also
+    --------
+    str.partition
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'partition', (sep,)))
+
+
+def replace(a, old, new, count=None):
+    """
+    For each element in `a`, return a copy of the string with all
+    occurrences of substring `old` replaced by `new`.
+
+    Calls `str.replace` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    old, new : str or unicode
+
+    count : int, optional
+        If the optional argument `count` is given, only the first
+        `count` occurrences are replaced.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.replace
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(
+            a, object_, 'replace', [old, new] + _clean_args(count)))
+
+
+def rfind(a, sub, start=0, end=None):
+    """
+    For each element in `a`, return the highest index in the string
+    where substring `sub` is found, such that `sub` is contained
+    within [`start`, `end`].
+
+    Calls `str.rfind` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+        Optional arguments `start` and `end` are interpreted as in
+        slice notation.
+
+    Returns
+    -------
+    out : ndarray
+       Output array of ints.  Return -1 on failure.
+
+    See also
+    --------
+    str.rfind
+
+    """
+    return _vec_string(
+        a, integer, 'rfind', [sub, start] + _clean_args(end))
+
+
+def rindex(a, sub, start=0, end=None):
+    """
+    Like `rfind`, but raises `ValueError` when the substring `sub` is
+    not found.
+
+    Calls `str.rindex` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    sub : str or unicode
+
+    start, end : int, optional
+
+    Returns
+    -------
+    out : ndarray
+       Output array of ints.
+
+    See also
+    --------
+    rfind, str.rindex
+
+    """
+    return _vec_string(
+        a, integer, 'rindex', [sub, start] + _clean_args(end))
+
+
+def rjust(a, width, fillchar=' '):
+    """
+    Return an array with the elements of `a` right-justified in a
+    string of length `width`.
+
+    Calls `str.rjust` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    width : int
+        The length of the resulting strings
+    fillchar : str or unicode, optional
+        The character to use for padding
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.rjust
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    if numpy.issubdtype(a_arr.dtype, numpy.string_):
+        fillchar = asbytes(fillchar)
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'rjust', (width_arr, fillchar))
+
+
+def rpartition(a, sep):
+    """
+    Partition (split) each element around the right-most separator.
+
+    Calls `str.rpartition` element-wise.
+
+    For each element in `a`, split the element as the last
+    occurrence of `sep`, and return 3 strings containing the part
+    before the separator, the separator itself, and the part after
+    the separator. If the separator is not found, return 3 strings
+    containing the string itself, followed by two empty strings.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+        Input array
+    sep : str or unicode
+        Right-most separator to split each element in array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of string or unicode, depending on input
+        type.  The output array will have an extra dimension with
+        3 elements per input element.
+
+    See also
+    --------
+    str.rpartition
+
+    """
+    return _to_string_or_unicode_array(
+        _vec_string(a, object_, 'rpartition', (sep,)))
+
+
+def rsplit(a, sep=None, maxsplit=None):
+    """
+    For each element in `a`, return a list of the words in the
+    string, using `sep` as the delimiter string.
+
+    Calls `str.rsplit` element-wise.
+
+    Except for splitting from the right, `rsplit`
+    behaves like `split`.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sep : str or unicode, optional
+        If `sep` is not specified or `None`, any whitespace string
+        is a separator.
+    maxsplit : int, optional
+        If `maxsplit` is given, at most `maxsplit` splits are done,
+        the rightmost ones.
+
+    Returns
+    -------
+    out : ndarray
+       Array of list objects
+
+    See also
+    --------
+    str.rsplit, split
+
+    """
+    # This will return an array of lists of different sizes, so we
+    # leave it as an object array
+    return _vec_string(
+        a, object_, 'rsplit', [sep] + _clean_args(maxsplit))
+
+
+def rstrip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the trailing
+    characters removed.
+
+    Calls `str.rstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    chars : str or unicode, optional
+       The `chars` argument is a string specifying the set of
+       characters to be removed. If omitted or None, the `chars`
+       argument defaults to removing whitespace. The `chars` argument
+       is not a suffix; rather, all combinations of its values are
+       stripped.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.rstrip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', 'abBABba'], dtype='S7'); c
+    array(['aAaAaA', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.rstrip(c, 'a')
+    array(['aAaAaA', 'abBABb'],
+        dtype='|S7')
+    >>> np.char.rstrip(c, 'A')
+    array(['aAaAa', 'abBABba'],
+        dtype='|S7')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'rstrip', (chars,))
+
+
+def split(a, sep=None, maxsplit=None):
+    """
+    For each element in `a`, return a list of the words in the
+    string, using `sep` as the delimiter string.
+
+    Calls `str.rsplit` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    sep : str or unicode, optional
+       If `sep` is not specified or `None`, any whitespace string is a
+       separator.
+
+    maxsplit : int, optional
+        If `maxsplit` is given, at most `maxsplit` splits are done.
+
+    Returns
+    -------
+    out : ndarray
+        Array of list objects
+
+    See also
+    --------
+    str.split, rsplit
+
+    """
+    # This will return an array of lists of different sizes, so we
+    # leave it as an object array
+    return _vec_string(
+        a, object_, 'split', [sep] + _clean_args(maxsplit))
+
+
+def splitlines(a, keepends=None):
+    """
+    For each element in `a`, return a list of the lines in the
+    element, breaking at line boundaries.
+
+    Calls `str.splitlines` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    keepends : bool, optional
+        Line breaks are not included in the resulting list unless
+        keepends is given and true.
+
+    Returns
+    -------
+    out : ndarray
+        Array of list objects
+
+    See also
+    --------
+    str.splitlines
+
+    """
+    return _vec_string(
+        a, object_, 'splitlines', _clean_args(keepends))
+
+
+def startswith(a, prefix, start=0, end=None):
+    """
+    Returns a boolean array which is `True` where the string element
+    in `a` starts with `prefix`, otherwise `False`.
+
+    Calls `str.startswith` element-wise.
+
+    Parameters
+    ----------
+    a : array_like of str or unicode
+
+    prefix : str
+
+    start, end : int, optional
+        With optional `start`, test beginning at that position. With
+        optional `end`, stop comparing at that position.
+
+    Returns
+    -------
+    out : ndarray
+        Array of booleans
+
+    See also
+    --------
+    str.startswith
+
+    """
+    return _vec_string(
+        a, bool_, 'startswith', [prefix, start] + _clean_args(end))
+
+
+def strip(a, chars=None):
+    """
+    For each element in `a`, return a copy with the leading and
+    trailing characters removed.
+
+    Calls `str.rstrip` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    chars : str or unicode, optional
+       The `chars` argument is a string specifying the set of
+       characters to be removed. If omitted or None, the `chars`
+       argument defaults to removing whitespace. The `chars` argument
+       is not a prefix or suffix; rather, all combinations of its
+       values are stripped.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.strip
+
+    Examples
+    --------
+    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
+    >>> c
+    array(['aAaAaA', '  aA  ', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.strip(c)
+    array(['aAaAaA', 'aA', 'abBABba'],
+        dtype='|S7')
+    >>> np.char.strip(c, 'a') # 'a' unstripped from c[1] because whitespace leads
+    array(['AaAaA', '  aA  ', 'bBABb'],
+        dtype='|S7')
+    >>> np.char.strip(c, 'A') # 'A' unstripped from c[1] because (unprinted) ws trails
+    array(['aAaAa', '  aA  ', 'abBABba'],
+        dtype='|S7')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'strip', _clean_args(chars))
+
+
+def swapcase(a):
+    """
+    Return element-wise a copy of the string with
+    uppercase characters converted to lowercase and vice versa.
+
+    Calls `str.swapcase` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.swapcase
+
+    Examples
+    --------
+    >>> c=np.array(['a1B c','1b Ca','b Ca1','cA1b'],'S5'); c
+    array(['a1B c', '1b Ca', 'b Ca1', 'cA1b'],
+        dtype='|S5')
+    >>> np.char.swapcase(c)
+    array(['A1b C', '1B cA', 'B cA1', 'Ca1B'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'swapcase')
+
+
+def title(a):
+    """
+    Return element-wise title cased version of string or unicode.
+
+    Title case words start with uppercase characters, all remaining cased
+    characters are lowercase.
+
+    Calls `str.title` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.title
+
+    Examples
+    --------
+    >>> c=np.array(['a1b c','1b ca','b ca1','ca1b'],'S5'); c
+    array(['a1b c', '1b ca', 'b ca1', 'ca1b'],
+        dtype='|S5')
+    >>> np.char.title(c)
+    array(['A1B C', '1B Ca', 'B Ca1', 'Ca1B'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'title')
+
+
+def translate(a, table, deletechars=None):
+    """
+    For each element in `a`, return a copy of the string where all
+    characters occurring in the optional argument `deletechars` are
+    removed, and the remaining characters have been mapped through the
+    given translation table.
+
+    Calls `str.translate` element-wise.
+
+    Parameters
+    ----------
+    a : array-like of str or unicode
+
+    table : str of length 256
+
+    deletechars : str
+
+    Returns
+    -------
+    out : ndarray
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.translate
+
+    """
+    a_arr = numpy.asarray(a)
+    if issubclass(a_arr.dtype.type, unicode_):
+        return _vec_string(
+            a_arr, a_arr.dtype, 'translate', (table,))
+    else:
+        return _vec_string(
+            a_arr, a_arr.dtype, 'translate', [table] + _clean_args(deletechars))
+
+
+def upper(a):
+    """
+    Return an array with the elements converted to uppercase.
+
+    Calls `str.upper` element-wise.
+
+    For 8-bit strings, this method is locale-dependent.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.upper
+
+    Examples
+    --------
+    >>> c = np.array(['a1b c', '1bca', 'bca1']); c
+    array(['a1b c', '1bca', 'bca1'],
+        dtype='|S5')
+    >>> np.char.upper(c)
+    array(['A1B C', '1BCA', 'BCA1'],
+        dtype='|S5')
+
+    """
+    a_arr = numpy.asarray(a)
+    return _vec_string(a_arr, a_arr.dtype, 'upper')
+
+
+def zfill(a, width):
+    """
+    Return the numeric string left-filled with zeros
+
+    Calls `str.zfill` element-wise.
+
+    Parameters
+    ----------
+    a : array_like, {str, unicode}
+        Input array.
+    width : int
+        Width of string to left-fill elements in `a`.
+
+    Returns
+    -------
+    out : ndarray, {str, unicode}
+        Output array of str or unicode, depending on input type
+
+    See also
+    --------
+    str.zfill
+
+    """
+    a_arr = numpy.asarray(a)
+    width_arr = numpy.asarray(width)
+    size = long(numpy.max(width_arr.flat))
+    return _vec_string(
+        a_arr, (a_arr.dtype.type, size), 'zfill', (width_arr,))
+
+
+def isnumeric(a):
+    """
+    For each element, return True if there are only numeric
+    characters in the element.
+
+    Calls `unicode.isnumeric` element-wise.
+
+    Numeric characters include digit characters, and all characters
+    that have the Unicode numeric value property, e.g. ``U+2155,
+    VULGAR FRACTION ONE FIFTH``.
+
+    Parameters
+    ----------
+    a : array_like, unicode
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Array of booleans of same shape as `a`.
+
+    See also
+    --------
+    unicode.isnumeric
+
+    """
+    if _use_unicode(a) != unicode_:
+        raise TypeError("isnumeric is only available for Unicode strings and arrays")
+    return _vec_string(a, bool_, 'isnumeric')
+
+
+def isdecimal(a):
+    """
+    For each element, return True if there are only decimal
+    characters in the element.
+
+    Calls `unicode.isdecimal` element-wise.
+
+    Decimal characters include digit characters, and all characters
+    that that can be used to form decimal-radix numbers,
+    e.g. ``U+0660, ARABIC-INDIC DIGIT ZERO``.
+
+    Parameters
+    ----------
+    a : array_like, unicode
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Array of booleans identical in shape to `a`.
+
+    See also
+    --------
+    unicode.isdecimal
+
+    """
+    if _use_unicode(a) != unicode_:
+        raise TypeError("isnumeric is only available for Unicode strings and arrays")
+    return _vec_string(a, bool_, 'isdecimal')
+
+
+class chararray(ndarray):
+    """
+    chararray(shape, itemsize=1, unicode=False, buffer=None, offset=0,
+              strides=None, order=None)
+
+    Provides a convenient view on arrays of string and unicode values.
+
+    .. note::
+       The `chararray` class exists for backwards compatibility with
+       Numarray, it is not recommended for new development. Starting from numpy
+       1.4, if one needs arrays of strings, it is recommended to use arrays of
+       `dtype` `object_`, `string_` or `unicode_`, and use the free functions
+       in the `numpy.char` module for fast vectorized string operations.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `.endswith`) and infix operators (e.g. ``"+", "*", "%"``)
+
+    chararrays should be created using `numpy.char.array` or
+    `numpy.char.asarray`, rather than this constructor directly.
+
+    This constructor creates the array, using `buffer` (with `offset`
+    and `strides`) if it is not ``None``. If `buffer` is ``None``, then
+    constructs a new array with `strides` in "C order", unless both
+    ``len(shape) >= 2`` and ``order='Fortran'``, in which case `strides`
+    is in "Fortran order".
+
+    Methods
+    -------
+    astype
+    argsort
+    copy
+    count
+    decode
+    dump
+    dumps
+    encode
+    endswith
+    expandtabs
+    fill
+    find
+    flatten
+    getfield
+    index
+    isalnum
+    isalpha
+    isdecimal
+    isdigit
+    islower
+    isnumeric
+    isspace
+    istitle
+    isupper
+    item
+    join
+    ljust
+    lower
+    lstrip
+    nonzero
+    put
+    ravel
+    repeat
+    replace
+    reshape
+    resize
+    rfind
+    rindex
+    rjust
+    rsplit
+    rstrip
+    searchsorted
+    setfield
+    setflags
+    sort
+    split
+    splitlines
+    squeeze
+    startswith
+    strip
+    swapaxes
+    swapcase
+    take
+    title
+    tofile
+    tolist
+    tostring
+    translate
+    transpose
+    upper
+    view
+    zfill
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of the array.
+    itemsize : int, optional
+        Length of each array element, in number of characters. Default is 1.
+    unicode : bool, optional
+        Are the array elements of type unicode (True) or string (False).
+        Default is False.
+    buffer : int, optional
+        Memory address of the start of the array data.  Default is None,
+        in which case a new array is created.
+    offset : int, optional
+        Fixed stride displacement from the beginning of an axis?
+        Default is 0. Needs to be >=0.
+    strides : array_like of ints, optional
+        Strides for the array (see `ndarray.strides` for full description).
+        Default is None.
+    order : {'C', 'F'}, optional
+        The order in which the array data is stored in memory: 'C' ->
+        "row major" order (the default), 'F' -> "column major"
+        (Fortran) order.
+
+    Examples
+    --------
+    >>> charar = np.chararray((3, 3))
+    >>> charar[:] = 'a'
+    >>> charar
+    chararray([['a', 'a', 'a'],
+           ['a', 'a', 'a'],
+           ['a', 'a', 'a']],
+          dtype='|S1')
+
+    >>> charar = np.chararray(charar.shape, itemsize=5)
+    >>> charar[:] = 'abc'
+    >>> charar
+    chararray([['abc', 'abc', 'abc'],
+           ['abc', 'abc', 'abc'],
+           ['abc', 'abc', 'abc']],
+          dtype='|S5')
+
+    """
+    def __new__(subtype, shape, itemsize=1, unicode=False, buffer=None,
+                offset=0, strides=None, order='C'):
+        global _globalvar
+
+        if unicode:
+            dtype = unicode_
+        else:
+            dtype = string_
+
+        # force itemsize to be a Python long, since using Numpy integer
+        # types results in itemsize.itemsize being used as the size of
+        # strings in the new array.
+        itemsize = long(itemsize)
+
+        if sys.version_info[0] >= 3 and isinstance(buffer, _unicode):
+            # On Py3, unicode objects do not have the buffer interface
+            filler = buffer
+            buffer = None
+        else:
+            filler = None
+
+        _globalvar = 1
+        if buffer is None:
+            self = ndarray.__new__(subtype, shape, (dtype, itemsize),
+                                   order=order)
+        else:
+            self = ndarray.__new__(subtype, shape, (dtype, itemsize),
+                                   buffer=buffer,
+                                   offset=offset, strides=strides,
+                                   order=order)
+        if filler is not None:
+            self[...] = filler
+        _globalvar = 0
+        return self
+
+    def __array_finalize__(self, obj):
+        # The b is a special case because it is used for reconstructing.
+        if not _globalvar and self.dtype.char not in 'SUbc':
+            raise ValueError("Can only create a chararray from string data.")
+
+    def __getitem__(self, obj):
+        val = ndarray.__getitem__(self, obj)
+
+        if isinstance(val, character):
+            temp = val.rstrip()
+            if _len(temp) == 0:
+                val = ''
+            else:
+                val = temp
+
+        return val
+
+    # IMPLEMENTATION NOTE: Most of the methods of this class are
+    # direct delegations to the free functions in this module.
+    # However, those that return an array of strings should instead
+    # return a chararray, so some extra wrapping is required.
+
+    def __eq__(self, other):
+        """
+        Return (self == other) element-wise.
+
+        See also
+        --------
+        equal
+        """
+        return equal(self, other)
+
+    def __ne__(self, other):
+        """
+        Return (self != other) element-wise.
+
+        See also
+        --------
+        not_equal
+        """
+        return not_equal(self, other)
+
+    def __ge__(self, other):
+        """
+        Return (self >= other) element-wise.
+
+        See also
+        --------
+        greater_equal
+        """
+        return greater_equal(self, other)
+
+    def __le__(self, other):
+        """
+        Return (self <= other) element-wise.
+
+        See also
+        --------
+        less_equal
+        """
+        return less_equal(self, other)
+
+    def __gt__(self, other):
+        """
+        Return (self > other) element-wise.
+
+        See also
+        --------
+        greater
+        """
+        return greater(self, other)
+
+    def __lt__(self, other):
+        """
+        Return (self < other) element-wise.
+
+        See also
+        --------
+        less
+        """
+        return less(self, other)
+
+    def __add__(self, other):
+        """
+        Return (self + other), that is string concatenation,
+        element-wise for a pair of array_likes of str or unicode.
+
+        See also
+        --------
+        add
+        """
+        return asarray(add(self, other))
+
+    def __radd__(self, other):
+        """
+        Return (other + self), that is string concatenation,
+        element-wise for a pair of array_likes of `string_` or `unicode_`.
+
+        See also
+        --------
+        add
+        """
+        return asarray(add(numpy.asarray(other), self))
+
+    def __mul__(self, i):
+        """
+        Return (self * i), that is string multiple concatenation,
+        element-wise.
+
+        See also
+        --------
+        multiply
+        """
+        return asarray(multiply(self, i))
+
+    def __rmul__(self, i):
+        """
+        Return (self * i), that is string multiple concatenation,
+        element-wise.
+
+        See also
+        --------
+        multiply
+        """
+        return asarray(multiply(self, i))
+
+    def __mod__(self, i):
+        """
+        Return (self % i), that is pre-Python 2.6 string formatting
+        (iterpolation), element-wise for a pair of array_likes of `string_`
+        or `unicode_`.
+
+        See also
+        --------
+        mod
+        """
+        return asarray(mod(self, i))
+
+    def __rmod__(self, other):
+        return NotImplemented
+
+    def argsort(self, axis=-1, kind='quicksort', order=None):
+        """
+        Return the indices that sort the array lexicographically.
+
+        For full documentation see `numpy.argsort`, for which this method is
+        in fact merely a "thin wrapper."
+
+        Examples
+        --------
+        >>> c = np.array(['a1b c', '1b ca', 'b ca1', 'Ca1b'], 'S5')
+        >>> c = c.view(np.chararray); c
+        chararray(['a1b c', '1b ca', 'b ca1', 'Ca1b'],
+              dtype='|S5')
+        >>> c[c.argsort()]
+        chararray(['1b ca', 'Ca1b', 'a1b c', 'b ca1'],
+              dtype='|S5')
+
+        """
+        return self.__array__().argsort(axis, kind, order)
+    argsort.__doc__ = ndarray.argsort.__doc__
+
+    def capitalize(self):
+        """
+        Return a copy of `self` with only the first character of each element
+        capitalized.
+
+        See also
+        --------
+        char.capitalize
+
+        """
+        return asarray(capitalize(self))
+
+    def center(self, width, fillchar=' '):
+        """
+        Return a copy of `self` with its elements centered in a
+        string of length `width`.
+
+        See also
+        --------
+        center
+        """
+        return asarray(center(self, width, fillchar))
+
+    def count(self, sub, start=0, end=None):
+        """
+        Returns an array with the number of non-overlapping occurrences of
+        substring `sub` in the range [`start`, `end`].
+
+        See also
+        --------
+        char.count
+
+        """
+        return count(self, sub, start, end)
+
+    def decode(self, encoding=None, errors=None):
+        """
+        Calls `str.decode` element-wise.
+
+        See also
+        --------
+        char.decode
+
+        """
+        return decode(self, encoding, errors)
+
+    def encode(self, encoding=None, errors=None):
+        """
+        Calls `str.encode` element-wise.
+
+        See also
+        --------
+        char.encode
+
+        """
+        return encode(self, encoding, errors)
+
+    def endswith(self, suffix, start=0, end=None):
+        """
+        Returns a boolean array which is `True` where the string element
+        in `self` ends with `suffix`, otherwise `False`.
+
+        See also
+        --------
+        char.endswith
+
+        """
+        return endswith(self, suffix, start, end)
+
+    def expandtabs(self, tabsize=8):
+        """
+        Return a copy of each string element where all tab characters are
+        replaced by one or more spaces.
+
+        See also
+        --------
+        char.expandtabs
+
+        """
+        return asarray(expandtabs(self, tabsize))
+
+    def find(self, sub, start=0, end=None):
+        """
+        For each element, return the lowest index in the string where
+        substring `sub` is found.
+
+        See also
+        --------
+        char.find
+
+        """
+        return find(self, sub, start, end)
+
+    def index(self, sub, start=0, end=None):
+        """
+        Like `find`, but raises `ValueError` when the substring is not found.
+
+        See also
+        --------
+        char.index
+
+        """
+        return index(self, sub, start, end)
+
+    def isalnum(self):
+        """
+        Returns true for each element if all characters in the string
+        are alphanumeric and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isalnum
+
+        """
+        return isalnum(self)
+
+    def isalpha(self):
+        """
+        Returns true for each element if all characters in the string
+        are alphabetic and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isalpha
+
+        """
+        return isalpha(self)
+
+    def isdigit(self):
+        """
+        Returns true for each element if all characters in the string are
+        digits and there is at least one character, false otherwise.
+
+        See also
+        --------
+        char.isdigit
+
+        """
+        return isdigit(self)
+
+    def islower(self):
+        """
+        Returns true for each element if all cased characters in the
+        string are lowercase and there is at least one cased character,
+        false otherwise.
+
+        See also
+        --------
+        char.islower
+
+        """
+        return islower(self)
+
+    def isspace(self):
+        """
+        Returns true for each element if there are only whitespace
+        characters in the string and there is at least one character,
+        false otherwise.
+
+        See also
+        --------
+        char.isspace
+
+        """
+        return isspace(self)
+
+    def istitle(self):
+        """
+        Returns true for each element if the element is a titlecased
+        string and there is at least one character, false otherwise.
+
+        See also
+        --------
+        char.istitle
+
+        """
+        return istitle(self)
+
+    def isupper(self):
+        """
+        Returns true for each element if all cased characters in the
+        string are uppercase and there is at least one character, false
+        otherwise.
+
+        See also
+        --------
+        char.isupper
+
+        """
+        return isupper(self)
+
+    def join(self, seq):
+        """
+        Return a string which is the concatenation of the strings in the
+        sequence `seq`.
+
+        See also
+        --------
+        char.join
+
+        """
+        return join(self, seq)
+
+    def ljust(self, width, fillchar=' '):
+        """
+        Return an array with the elements of `self` left-justified in a
+        string of length `width`.
+
+        See also
+        --------
+        char.ljust
+
+        """
+        return asarray(ljust(self, width, fillchar))
+
+    def lower(self):
+        """
+        Return an array with the elements of `self` converted to
+        lowercase.
+
+        See also
+        --------
+        char.lower
+
+        """
+        return asarray(lower(self))
+
+    def lstrip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the leading characters
+        removed.
+
+        See also
+        --------
+        char.lstrip
+
+        """
+        return asarray(lstrip(self, chars))
+
+    def partition(self, sep):
+        """
+        Partition each element in `self` around `sep`.
+
+        See also
+        --------
+        partition
+        """
+        return asarray(partition(self, sep))
+
+    def replace(self, old, new, count=None):
+        """
+        For each element in `self`, return a copy of the string with all
+        occurrences of substring `old` replaced by `new`.
+
+        See also
+        --------
+        char.replace
+
+        """
+        return asarray(replace(self, old, new, count))
+
+    def rfind(self, sub, start=0, end=None):
+        """
+        For each element in `self`, return the highest index in the string
+        where substring `sub` is found, such that `sub` is contained
+        within [`start`, `end`].
+
+        See also
+        --------
+        char.rfind
+
+        """
+        return rfind(self, sub, start, end)
+
+    def rindex(self, sub, start=0, end=None):
+        """
+        Like `rfind`, but raises `ValueError` when the substring `sub` is
+        not found.
+
+        See also
+        --------
+        char.rindex
+
+        """
+        return rindex(self, sub, start, end)
+
+    def rjust(self, width, fillchar=' '):
+        """
+        Return an array with the elements of `self`
+        right-justified in a string of length `width`.
+
+        See also
+        --------
+        char.rjust
+
+        """
+        return asarray(rjust(self, width, fillchar))
+
+    def rpartition(self, sep):
+        """
+        Partition each element in `self` around `sep`.
+
+        See also
+        --------
+        rpartition
+        """
+        return asarray(rpartition(self, sep))
+
+    def rsplit(self, sep=None, maxsplit=None):
+        """
+        For each element in `self`, return a list of the words in
+        the string, using `sep` as the delimiter string.
+
+        See also
+        --------
+        char.rsplit
+
+        """
+        return rsplit(self, sep, maxsplit)
+
+    def rstrip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the trailing
+        characters removed.
+
+        See also
+        --------
+        char.rstrip
+
+        """
+        return asarray(rstrip(self, chars))
+
+    def split(self, sep=None, maxsplit=None):
+        """
+        For each element in `self`, return a list of the words in the
+        string, using `sep` as the delimiter string.
+
+        See also
+        --------
+        char.split
+
+        """
+        return split(self, sep, maxsplit)
+
+    def splitlines(self, keepends=None):
+        """
+        For each element in `self`, return a list of the lines in the
+        element, breaking at line boundaries.
+
+        See also
+        --------
+        char.splitlines
+
+        """
+        return splitlines(self, keepends)
+
+    def startswith(self, prefix, start=0, end=None):
+        """
+        Returns a boolean array which is `True` where the string element
+        in `self` starts with `prefix`, otherwise `False`.
+
+        See also
+        --------
+        char.startswith
+
+        """
+        return startswith(self, prefix, start, end)
+
+    def strip(self, chars=None):
+        """
+        For each element in `self`, return a copy with the leading and
+        trailing characters removed.
+
+        See also
+        --------
+        char.strip
+
+        """
+        return asarray(strip(self, chars))
+
+    def swapcase(self):
+        """
+        For each element in `self`, return a copy of the string with
+        uppercase characters converted to lowercase and vice versa.
+
+        See also
+        --------
+        char.swapcase
+
+        """
+        return asarray(swapcase(self))
+
+    def title(self):
+        """
+        For each element in `self`, return a titlecased version of the
+        string: words start with uppercase characters, all remaining cased
+        characters are lowercase.
+
+        See also
+        --------
+        char.title
+
+        """
+        return asarray(title(self))
+
+    def translate(self, table, deletechars=None):
+        """
+        For each element in `self`, return a copy of the string where
+        all characters occurring in the optional argument
+        `deletechars` are removed, and the remaining characters have
+        been mapped through the given translation table.
+
+        See also
+        --------
+        char.translate
+
+        """
+        return asarray(translate(self, table, deletechars))
+
+    def upper(self):
+        """
+        Return an array with the elements of `self` converted to
+        uppercase.
+
+        See also
+        --------
+        char.upper
+
+        """
+        return asarray(upper(self))
+
+    def zfill(self, width):
+        """
+        Return the numeric string left-filled with zeros in a string of
+        length `width`.
+
+        See also
+        --------
+        char.zfill
+
+        """
+        return asarray(zfill(self, width))
+
+    def isnumeric(self):
+        """
+        For each element in `self`, return True if there are only
+        numeric characters in the element.
+
+        See also
+        --------
+        char.isnumeric
+
+        """
+        return isnumeric(self)
+
+    def isdecimal(self):
+        """
+        For each element in `self`, return True if there are only
+        decimal characters in the element.
+
+        See also
+        --------
+        char.isdecimal
+
+        """
+        return isdecimal(self)
+
+
+def array(obj, itemsize=None, copy=True, unicode=None, order=None):
+    """
+    Create a `chararray`.
+
+    .. note::
+       This class is provided for numarray backward-compatibility.
+       New code (not concerned with numarray compatibility) should use
+       arrays of type `string_` or `unicode_` and use the free functions
+       in :mod:`numpy.char <numpy.core.defchararray>` for fast
+       vectorized string operations instead.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `str.endswith`) and infix operators (e.g. ``+, *, %``)
+
+    Parameters
+    ----------
+    obj : array of str or unicode-like
+
+    itemsize : int, optional
+        `itemsize` is the number of characters per scalar in the
+        resulting array.  If `itemsize` is None, and `obj` is an
+        object array or a Python list, the `itemsize` will be
+        automatically determined.  If `itemsize` is provided and `obj`
+        is of type str or unicode, then the `obj` string will be
+        chunked into `itemsize` pieces.
+
+    copy : bool, optional
+        If true (default), then the object is copied.  Otherwise, a copy
+        will only be made if __array__ returns a copy, if obj is a
+        nested sequence, or if a copy is needed to satisfy any of the other
+        requirements (`itemsize`, unicode, `order`, etc.).
+
+    unicode : bool, optional
+        When true, the resulting `chararray` can contain Unicode
+        characters, when false only 8-bit characters.  If unicode is
+        `None` and `obj` is one of the following:
+
+          - a `chararray`,
+          - an ndarray of type `str` or `unicode`
+          - a Python str or unicode object,
+
+        then the unicode setting of the output array will be
+        automatically determined.
+
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C' (default), then the
+        array will be in C-contiguous order (last-index varies the
+        fastest).  If order is 'F', then the returned array
+        will be in Fortran-contiguous order (first-index varies the
+        fastest).  If order is 'A', then the returned array may
+        be in any order (either C-, Fortran-contiguous, or even
+        discontiguous).
+    """
+    if isinstance(obj, (_bytes, _unicode)):
+        if unicode is None:
+            if isinstance(obj, _unicode):
+                unicode = True
+            else:
+                unicode = False
+
+        if itemsize is None:
+            itemsize = _len(obj)
+        shape = _len(obj) // itemsize
+
+        if unicode:
+            if sys.maxunicode == 0xffff:
+                # On a narrow Python build, the buffer for Unicode
+                # strings is UCS2, which doesn't match the buffer for
+                # Numpy Unicode types, which is ALWAYS UCS4.
+                # Therefore, we need to convert the buffer.  On Python
+                # 2.6 and later, we can use the utf_32 codec.  Earlier
+                # versions don't have that codec, so we convert to a
+                # numerical array that matches the input buffer, and
+                # then use Numpy to convert it to UCS4.  All of this
+                # should happen in native endianness.
+                if sys.hexversion >= 0x2060000:
+                    obj = obj.encode('utf_32')
+                else:
+                    if isinstance(obj, str):
+                        ascii = numpy.frombuffer(obj, 'u1')
+                        ucs4 = numpy.array(ascii, 'u4')
+                        obj = ucs4.data
+                    else:
+                        ucs2 = numpy.frombuffer(obj, 'u2')
+                        ucs4 = numpy.array(ucs2, 'u4')
+                        obj = ucs4.data
+            else:
+                obj = _unicode(obj)
+        else:
+            # Let the default Unicode -> string encoding (if any) take
+            # precedence.
+            obj = _bytes(obj)
+
+        return chararray(shape, itemsize=itemsize, unicode=unicode,
+                         buffer=obj, order=order)
+
+    if isinstance(obj, (list, tuple)):
+        obj = numpy.asarray(obj)
+
+    if isinstance(obj, ndarray) and issubclass(obj.dtype.type, character):
+        # If we just have a vanilla chararray, create a chararray
+        # view around it.
+        if not isinstance(obj, chararray):
+            obj = obj.view(chararray)
+
+        if itemsize is None:
+            itemsize = obj.itemsize
+            # itemsize is in 8-bit chars, so for Unicode, we need
+            # to divide by the size of a single Unicode character,
+            # which for Numpy is always 4
+            if issubclass(obj.dtype.type, unicode_):
+                itemsize //= 4
+
+        if unicode is None:
+            if issubclass(obj.dtype.type, unicode_):
+                unicode = True
+            else:
+                unicode = False
+
+        if unicode:
+            dtype = unicode_
+        else:
+            dtype = string_
+
+        if order is not None:
+            obj = numpy.asarray(obj, order=order)
+        if (copy or
+                (itemsize != obj.itemsize) or
+                (not unicode and isinstance(obj, unicode_)) or
+                (unicode and isinstance(obj, string_))):
+            obj = obj.astype((dtype, long(itemsize)))
+        return obj
+
+    if isinstance(obj, ndarray) and issubclass(obj.dtype.type, object):
+        if itemsize is None:
+            # Since no itemsize was specified, convert the input array to
+            # a list so the ndarray constructor will automatically
+            # determine the itemsize for us.
+            obj = obj.tolist()
+            # Fall through to the default case
+
+    if unicode:
+        dtype = unicode_
+    else:
+        dtype = string_
+
+    if itemsize is None:
+        val = narray(obj, dtype=dtype, order=order, subok=True)
+    else:
+        val = narray(obj, dtype=(dtype, itemsize), order=order, subok=True)
+    return val.view(chararray)
+
+
+def asarray(obj, itemsize=None, unicode=None, order=None):
+    """
+    Convert the input to a `chararray`, copying the data only if
+    necessary.
+
+    Versus a regular Numpy array of type `str` or `unicode`, this
+    class adds the following functionality:
+
+      1) values automatically have whitespace removed from the end
+         when indexed
+
+      2) comparison operators automatically remove whitespace from the
+         end when comparing values
+
+      3) vectorized string operations are provided as methods
+         (e.g. `str.endswith`) and infix operators (e.g. ``+``, ``*``,``%``)
+
+    Parameters
+    ----------
+    obj : array of str or unicode-like
+
+    itemsize : int, optional
+        `itemsize` is the number of characters per scalar in the
+        resulting array.  If `itemsize` is None, and `obj` is an
+        object array or a Python list, the `itemsize` will be
+        automatically determined.  If `itemsize` is provided and `obj`
+        is of type str or unicode, then the `obj` string will be
+        chunked into `itemsize` pieces.
+
+    unicode : bool, optional
+        When true, the resulting `chararray` can contain Unicode
+        characters, when false only 8-bit characters.  If unicode is
+        `None` and `obj` is one of the following:
+
+          - a `chararray`,
+          - an ndarray of type `str` or 'unicode`
+          - a Python str or unicode object,
+
+        then the unicode setting of the output array will be
+        automatically determined.
+
+    order : {'C', 'F'}, optional
+        Specify the order of the array.  If order is 'C' (default), then the
+        array will be in C-contiguous order (last-index varies the
+        fastest).  If order is 'F', then the returned array
+        will be in Fortran-contiguous order (first-index varies the
+        fastest).
+    """
+    return array(obj, itemsize, copy=False,
+                 unicode=unicode, order=order)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.py
new file mode 100644
index 0000000000..4faeb557a6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.py
@@ -0,0 +1,3100 @@
+"""Module containing non-deprecated functions borrowed from Numeric.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types
+import warnings
+
+import numpy as np
+from .. import VisibleDeprecationWarning
+from . import multiarray as mu
+from . import umath as um
+from . import numerictypes as nt
+from .numeric import asarray, array, asanyarray, concatenate
+from . import _methods
+
+
+_dt_ = nt.sctype2char
+
+
+# functions that are methods
+__all__ = [
+    'alen', 'all', 'alltrue', 'amax', 'amin', 'any', 'argmax',
+    'argmin', 'argpartition', 'argsort', 'around', 'choose', 'clip',
+    'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean',
+    'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put',
+    'rank', 'ravel', 'repeat', 'reshape', 'resize', 'round_',
+    'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze',
+    'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var',
+    ]
+
+
+try:
+    _gentype = types.GeneratorType
+except AttributeError:
+    _gentype = type(None)
+
+# save away Python sum
+_sum_ = sum
+
+
+# functions that are now methods
+def _wrapit(obj, method, *args, **kwds):
+    try:
+        wrap = obj.__array_wrap__
+    except AttributeError:
+        wrap = None
+    result = getattr(asarray(obj), method)(*args, **kwds)
+    if wrap:
+        if not isinstance(result, mu.ndarray):
+            result = asarray(result)
+        result = wrap(result)
+    return result
+
+
+def take(a, indices, axis=None, out=None, mode='raise'):
+    """
+    Take elements from an array along an axis.
+
+    This function does the same thing as "fancy" indexing (indexing arrays
+    using arrays); however, it can be easier to use if you need elements
+    along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        The source array.
+    indices : array_like
+        The indices of the values to extract.
+
+        .. versionadded:: 1.8.0
+
+        Also allow scalars for indices.
+    axis : int, optional
+        The axis over which to select values. By default, the flattened
+        input array is used.
+    out : ndarray, optional
+        If provided, the result will be placed in this array. It should
+        be of the appropriate shape and dtype.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        'clip' mode means that all indices that are too large are replaced
+        by the index that addresses the last element along that axis. Note
+        that this disables indexing with negative numbers.
+
+    Returns
+    -------
+    subarray : ndarray
+        The returned array has the same type as `a`.
+
+    See Also
+    --------
+    compress : Take elements using a boolean mask
+    ndarray.take : equivalent method
+
+    Examples
+    --------
+    >>> a = [4, 3, 5, 7, 6, 8]
+    >>> indices = [0, 1, 4]
+    >>> np.take(a, indices)
+    array([4, 3, 6])
+
+    In this example if `a` is an ndarray, "fancy" indexing can be used.
+
+    >>> a = np.array(a)
+    >>> a[indices]
+    array([4, 3, 6])
+
+    If `indices` is not one dimensional, the output also has these dimensions.
+
+    >>> np.take(a, [[0, 1], [2, 3]])
+    array([[4, 3],
+           [5, 7]])
+    """
+    try:
+        take = a.take
+    except AttributeError:
+        return _wrapit(a, 'take', indices, axis, out, mode)
+    return take(indices, axis, out, mode)
+
+
+# not deprecated --- copy if necessary, view otherwise
+def reshape(a, newshape, order='C'):
+    """
+    Gives a new shape to an array without changing its data.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be reshaped.
+    newshape : int or tuple of ints
+        The new shape should be compatible with the original shape. If
+        an integer, then the result will be a 1-D array of that length.
+        One shape dimension can be -1. In this case, the value is inferred
+        from the length of the array and remaining dimensions.
+    order : {'C', 'F', 'A'}, optional
+        Read the elements of `a` using this index order, and place the elements
+        into the reshaped array using this index order.  'C' means to
+        read / write the elements using C-like index order, with the last axis
+        index changing fastest, back to the first axis index changing slowest.
+        'F' means to read / write the elements using Fortran-like index order,
+        with the first index changing fastest, and the last index changing
+        slowest.
+        Note that the 'C' and 'F' options take no account of the memory layout
+        of the underlying array, and only refer to the order of indexing.  'A'
+        means to read / write the elements in Fortran-like index order if `a`
+        is Fortran *contiguous* in memory, C-like order otherwise.
+
+    Returns
+    -------
+    reshaped_array : ndarray
+        This will be a new view object if possible; otherwise, it will
+        be a copy.  Note there is no guarantee of the *memory layout* (C- or
+        Fortran- contiguous) of the returned array.
+
+    See Also
+    --------
+    ndarray.reshape : Equivalent method.
+
+    Notes
+    -----
+    It is not always possible to change the shape of an array without
+    copying the data. If you want an error to be raise if the data is copied,
+    you should assign the new shape to the shape attribute of the array::
+
+     >>> a = np.zeros((10, 2))
+     # A transpose make the array non-contiguous
+     >>> b = a.T
+     # Taking a view makes it possible to modify the shape without modifying
+     # the initial object.
+     >>> c = b.view()
+     >>> c.shape = (20)
+     AttributeError: incompatible shape for a non-contiguous array
+
+    The `order` keyword gives the index ordering both for *fetching* the values
+    from `a`, and then *placing* the values into the output array.
+    For example, let's say you have an array:
+
+    >>> a = np.arange(6).reshape((3, 2))
+    >>> a
+    array([[0, 1],
+           [2, 3],
+           [4, 5]])
+
+    You can think of reshaping as first raveling the array (using the given
+    index order), then inserting the elements from the raveled array into the
+    new array using the same kind of index ordering as was used for the
+    raveling.
+
+    >>> np.reshape(a, (2, 3)) # C-like index ordering
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshape
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.reshape(a, (2, 3), order='F') # Fortran-like index ordering
+    array([[0, 4, 3],
+           [2, 1, 5]])
+    >>> np.reshape(np.ravel(a, order='F'), (2, 3), order='F')
+    array([[0, 4, 3],
+           [2, 1, 5]])
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3], [4,5,6]])
+    >>> np.reshape(a, 6)
+    array([1, 2, 3, 4, 5, 6])
+    >>> np.reshape(a, 6, order='F')
+    array([1, 4, 2, 5, 3, 6])
+
+    >>> np.reshape(a, (3,-1))       # the unspecified value is inferred to be 2
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    """
+    try:
+        reshape = a.reshape
+    except AttributeError:
+        return _wrapit(a, 'reshape', newshape, order=order)
+    return reshape(newshape, order=order)
+
+
+def choose(a, choices, out=None, mode='raise'):
+    """
+    Construct an array from an index array and a set of arrays to choose from.
+
+    First of all, if confused or uncertain, definitely look at the Examples -
+    in its full generality, this function is less simple than it might
+    seem from the following code description (below ndi =
+    `numpy.lib.index_tricks`):
+
+    ``np.choose(a,c) == np.array([c[a[I]][I] for I in ndi.ndindex(a.shape)])``.
+
+    But this omits some subtleties.  Here is a fully general summary:
+
+    Given an "index" array (`a`) of integers and a sequence of `n` arrays
+    (`choices`), `a` and each choice array are first broadcast, as necessary,
+    to arrays of a common shape; calling these *Ba* and *Bchoices[i], i =
+    0,...,n-1* we have that, necessarily, ``Ba.shape == Bchoices[i].shape``
+    for each `i`.  Then, a new array with shape ``Ba.shape`` is created as
+    follows:
+
+    * if ``mode=raise`` (the default), then, first of all, each element of
+      `a` (and thus `Ba`) must be in the range `[0, n-1]`; now, suppose that
+      `i` (in that range) is the value at the `(j0, j1, ..., jm)` position
+      in `Ba` - then the value at the same position in the new array is the
+      value in `Bchoices[i]` at that same position;
+
+    * if ``mode=wrap``, values in `a` (and thus `Ba`) may be any (signed)
+      integer; modular arithmetic is used to map integers outside the range
+      `[0, n-1]` back into that range; and then the new array is constructed
+      as above;
+
+    * if ``mode=clip``, values in `a` (and thus `Ba`) may be any (signed)
+      integer; negative integers are mapped to 0; values greater than `n-1`
+      are mapped to `n-1`; and then the new array is constructed as above.
+
+    Parameters
+    ----------
+    a : int array
+        This array must contain integers in `[0, n-1]`, where `n` is the number
+        of choices, unless ``mode=wrap`` or ``mode=clip``, in which cases any
+        integers are permissible.
+    choices : sequence of arrays
+        Choice arrays. `a` and all of the choices must be broadcastable to the
+        same shape.  If `choices` is itself an array (not recommended), then
+        its outermost dimension (i.e., the one corresponding to
+        ``choices.shape[0]``) is taken as defining the "sequence".
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+    mode : {'raise' (default), 'wrap', 'clip'}, optional
+        Specifies how indices outside `[0, n-1]` will be treated:
+
+          * 'raise' : an exception is raised
+          * 'wrap' : value becomes value mod `n`
+          * 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1
+
+    Returns
+    -------
+    merged_array : array
+        The merged result.
+
+    Raises
+    ------
+    ValueError: shape mismatch
+        If `a` and each choice array are not all broadcastable to the same
+        shape.
+
+    See Also
+    --------
+    ndarray.choose : equivalent method
+
+    Notes
+    -----
+    To reduce the chance of misinterpretation, even though the following
+    "abuse" is nominally supported, `choices` should neither be, nor be
+    thought of as, a single array, i.e., the outermost sequence-like container
+    should be either a list or a tuple.
+
+    Examples
+    --------
+
+    >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+    ...   [20, 21, 22, 23], [30, 31, 32, 33]]
+    >>> np.choose([2, 3, 1, 0], choices
+    ... # the first element of the result will be the first element of the
+    ... # third (2+1) "array" in choices, namely, 20; the second element
+    ... # will be the second element of the fourth (3+1) choice array, i.e.,
+    ... # 31, etc.
+    ... )
+    array([20, 31, 12,  3])
+    >>> np.choose([2, 4, 1, 0], choices, mode='clip') # 4 goes to 3 (4-1)
+    array([20, 31, 12,  3])
+    >>> # because there are 4 choice arrays
+    >>> np.choose([2, 4, 1, 0], choices, mode='wrap') # 4 goes to (4 mod 4)
+    array([20,  1, 12,  3])
+    >>> # i.e., 0
+
+    A couple examples illustrating how choose broadcasts:
+
+    >>> a = [[1, 0, 1], [0, 1, 0], [1, 0, 1]]
+    >>> choices = [-10, 10]
+    >>> np.choose(a, choices)
+    array([[ 10, -10,  10],
+           [-10,  10, -10],
+           [ 10, -10,  10]])
+
+    >>> # With thanks to Anne Archibald
+    >>> a = np.array([0, 1]).reshape((2,1,1))
+    >>> c1 = np.array([1, 2, 3]).reshape((1,3,1))
+    >>> c2 = np.array([-1, -2, -3, -4, -5]).reshape((1,1,5))
+    >>> np.choose(a, (c1, c2)) # result is 2x3x5, res[0,:,:]=c1, res[1,:,:]=c2
+    array([[[ 1,  1,  1,  1,  1],
+            [ 2,  2,  2,  2,  2],
+            [ 3,  3,  3,  3,  3]],
+           [[-1, -2, -3, -4, -5],
+            [-1, -2, -3, -4, -5],
+            [-1, -2, -3, -4, -5]]])
+
+    """
+    try:
+        choose = a.choose
+    except AttributeError:
+        return _wrapit(a, 'choose', choices, out=out, mode=mode)
+    return choose(choices, out=out, mode=mode)
+
+
+def repeat(a, repeats, axis=None):
+    """
+    Repeat elements of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    repeats : int or array of ints
+        The number of repetitions for each element.  `repeats` is broadcasted
+        to fit the shape of the given axis.
+    axis : int, optional
+        The axis along which to repeat values.  By default, use the
+        flattened input array, and return a flat output array.
+
+    Returns
+    -------
+    repeated_array : ndarray
+        Output array which has the same shape as `a`, except along
+        the given axis.
+
+    See Also
+    --------
+    tile : Tile an array.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2],[3,4]])
+    >>> np.repeat(x, 2)
+    array([1, 1, 2, 2, 3, 3, 4, 4])
+    >>> np.repeat(x, 3, axis=1)
+    array([[1, 1, 1, 2, 2, 2],
+           [3, 3, 3, 4, 4, 4]])
+    >>> np.repeat(x, [1, 2], axis=0)
+    array([[1, 2],
+           [3, 4],
+           [3, 4]])
+
+    """
+    try:
+        repeat = a.repeat
+    except AttributeError:
+        return _wrapit(a, 'repeat', repeats, axis)
+    return repeat(repeats, axis)
+
+
+def put(a, ind, v, mode='raise'):
+    """
+    Replaces specified elements of an array with given values.
+
+    The indexing works on the flattened target array. `put` is roughly
+    equivalent to:
+
+    ::
+
+        a.flat[ind] = v
+
+    Parameters
+    ----------
+    a : ndarray
+        Target array.
+    ind : array_like
+        Target indices, interpreted as integers.
+    v : array_like
+        Values to place in `a` at target indices. If `v` is shorter than
+        `ind` it will be repeated as necessary.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' -- raise an error (default)
+        * 'wrap' -- wrap around
+        * 'clip' -- clip to the range
+
+        'clip' mode means that all indices that are too large are replaced
+        by the index that addresses the last element along that axis. Note
+        that this disables indexing with negative numbers.
+
+    See Also
+    --------
+    putmask, place
+
+    Examples
+    --------
+    >>> a = np.arange(5)
+    >>> np.put(a, [0, 2], [-44, -55])
+    >>> a
+    array([-44,   1, -55,   3,   4])
+
+    >>> a = np.arange(5)
+    >>> np.put(a, 22, -5, mode='clip')
+    >>> a
+    array([ 0,  1,  2,  3, -5])
+
+    """
+    try:
+        put = a.put
+    except AttributeError:
+        raise TypeError("argument 1 must be numpy.ndarray, "
+                        "not {name}".format(name=type(a).__name__))
+
+    return put(ind, v, mode)
+
+
+def swapaxes(a, axis1, axis2):
+    """
+    Interchange two axes of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis1 : int
+        First axis.
+    axis2 : int
+        Second axis.
+
+    Returns
+    -------
+    a_swapped : ndarray
+        For Numpy >= 1.10, if `a` is an ndarray, then a view of `a` is
+        returned; otherwise a new array is created. For earlier Numpy
+        versions a view of `a` is returned only if the order of the
+        axes is changed, otherwise the input array is returned.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3]])
+    >>> np.swapaxes(x,0,1)
+    array([[1],
+           [2],
+           [3]])
+
+    >>> x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]])
+    >>> x
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+
+    >>> np.swapaxes(x,0,2)
+    array([[[0, 4],
+            [2, 6]],
+           [[1, 5],
+            [3, 7]]])
+
+    """
+    try:
+        swapaxes = a.swapaxes
+    except AttributeError:
+        return _wrapit(a, 'swapaxes', axis1, axis2)
+    return swapaxes(axis1, axis2)
+
+
+def transpose(a, axes=None):
+    """
+    Permute the dimensions of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axes : list of ints, optional
+        By default, reverse the dimensions, otherwise permute the axes
+        according to the values given.
+
+    Returns
+    -------
+    p : ndarray
+        `a` with its axes permuted.  A view is returned whenever
+        possible.
+
+    See Also
+    --------
+    moveaxis
+    argsort
+
+    Notes
+    -----
+    Use `transpose(a, argsort(axes))` to invert the transposition of tensors
+    when using the `axes` keyword argument.
+
+    Transposing a 1-D array returns an unchanged view of the original array.
+
+    Examples
+    --------
+    >>> x = np.arange(4).reshape((2,2))
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+
+    >>> np.transpose(x)
+    array([[0, 2],
+           [1, 3]])
+
+    >>> x = np.ones((1, 2, 3))
+    >>> np.transpose(x, (1, 0, 2)).shape
+    (2, 1, 3)
+
+    """
+    try:
+        transpose = a.transpose
+    except AttributeError:
+        return _wrapit(a, 'transpose', axes)
+    return transpose(axes)
+
+
+def partition(a, kth, axis=-1, kind='introselect', order=None):
+    """
+    Return a partitioned copy of an array.
+
+    Creates a copy of the array with its elements rearranged in such a way that
+    the value of the element in kth position is in the position it would be in
+    a sorted array. All elements smaller than the kth element are moved before
+    this element and all equal or greater are moved behind it. The ordering of
+    the elements in the two partitions is undefined.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+    kth : int or sequence of ints
+        Element index to partition by. The kth value of the element will be in
+        its final sorted position and all smaller elements will be moved before
+        it and all equal or greater elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all elements
+        indexed by kth  of them into their sorted position at once.
+    axis : int or None, optional
+        Axis along which to sort. If None, the array is flattened before
+        sorting. The default is -1, which sorts along the last axis.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string.  Not all fields need be specified, but
+        unspecified fields will still be used, in the order in which they
+        come up in the dtype, to break ties.
+
+    Returns
+    -------
+    partitioned_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    ndarray.partition : Method to sort an array in-place.
+    argpartition : Indirect partition.
+    sort : Full sorting
+
+    Notes
+    -----
+    The various selection algorithms are characterized by their average speed,
+    worst case performance, work space size, and whether they are stable. A
+    stable sort keeps items with the same key in the same relative order. The
+    available algorithms have the following properties:
+
+    ================= ======= ============= ============ =======
+       kind            speed   worst case    work space  stable
+    ================= ======= ============= ============ =======
+    'introselect'        1        O(n)           0         no
+    ================= ======= ============= ============ =======
+
+    All the partition algorithms make temporary copies of the data when
+    partitioning along any but the last axis.  Consequently, partitioning
+    along the last axis is faster and uses less space than partitioning
+    along any other axis.
+
+    The sort order for complex numbers is lexicographic. If both the real
+    and imaginary parts are non-nan then the order is determined by the
+    real parts except when they are equal, in which case the order is
+    determined by the imaginary parts.
+
+    Examples
+    --------
+    >>> a = np.array([3, 4, 2, 1])
+    >>> np.partition(a, 3)
+    array([2, 1, 3, 4])
+
+    >>> np.partition(a, (1, 3))
+    array([1, 2, 3, 4])
+
+    """
+    if axis is None:
+        a = asanyarray(a).flatten()
+        axis = 0
+    else:
+        a = asanyarray(a).copy(order="K")
+    a.partition(kth, axis=axis, kind=kind, order=order)
+    return a
+
+
+def argpartition(a, kth, axis=-1, kind='introselect', order=None):
+    """
+    Perform an indirect partition along the given axis using the algorithm
+    specified by the `kind` keyword. It returns an array of indices of the
+    same shape as `a` that index data along the given axis in partitioned
+    order.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array to sort.
+    kth : int or sequence of ints
+        Element index to partition by. The kth element will be in its final
+        sorted position and all smaller elements will be moved before it and
+        all larger elements behind it.
+        The order all elements in the partitions is undefined.
+        If provided with a sequence of kth it will partition all of them into
+        their sorted position at once.
+    axis : int or None, optional
+        Axis along which to sort.  The default is -1 (the last axis). If None,
+        the flattened array is used.
+    kind : {'introselect'}, optional
+        Selection algorithm. Default is 'introselect'
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    index_array : ndarray, int
+        Array of indices that partition `a` along the specified axis.
+        In other words, ``a[index_array]`` yields a sorted `a`.
+
+    See Also
+    --------
+    partition : Describes partition algorithms used.
+    ndarray.partition : Inplace partition.
+    argsort : Full indirect sort
+
+    Notes
+    -----
+    See `partition` for notes on the different selection algorithms.
+
+    Examples
+    --------
+    One dimensional array:
+
+    >>> x = np.array([3, 4, 2, 1])
+    >>> x[np.argpartition(x, 3)]
+    array([2, 1, 3, 4])
+    >>> x[np.argpartition(x, (1, 3))]
+    array([1, 2, 3, 4])
+
+    >>> x = [3, 4, 2, 1]
+    >>> np.array(x)[np.argpartition(x, 3)]
+    array([2, 1, 3, 4])
+
+    """
+    try:
+        argpartition = a.argpartition
+    except AttributeError:
+        return _wrapit(a, 'argpartition',kth, axis, kind, order)
+    return argpartition(kth, axis, kind=kind, order=order)
+
+
+def sort(a, axis=-1, kind='quicksort', order=None):
+    """
+    Return a sorted copy of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+    axis : int or None, optional
+        Axis along which to sort. If None, the array is flattened before
+        sorting. The default is -1, which sorts along the last axis.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm. Default is 'quicksort'.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    sorted_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    ndarray.sort : Method to sort an array in-place.
+    argsort : Indirect sort.
+    lexsort : Indirect stable sort on multiple keys.
+    searchsorted : Find elements in a sorted array.
+    partition : Partial sort.
+
+    Notes
+    -----
+    The various sorting algorithms are characterized by their average speed,
+    worst case performance, work space size, and whether they are stable. A
+    stable sort keeps items with the same key in the same relative
+    order. The three available algorithms have the following
+    properties:
+
+    =========== ======= ============= ============ =======
+       kind      speed   worst case    work space  stable
+    =========== ======= ============= ============ =======
+    'quicksort'    1     O(n^2)            0          no
+    'mergesort'    2     O(n*log(n))      ~n/2        yes
+    'heapsort'     3     O(n*log(n))       0          no
+    =========== ======= ============= ============ =======
+
+    All the sort algorithms make temporary copies of the data when
+    sorting along any but the last axis.  Consequently, sorting along
+    the last axis is faster and uses less space than sorting along
+    any other axis.
+
+    The sort order for complex numbers is lexicographic. If both the real
+    and imaginary parts are non-nan then the order is determined by the
+    real parts except when they are equal, in which case the order is
+    determined by the imaginary parts.
+
+    Previous to numpy 1.4.0 sorting real and complex arrays containing nan
+    values led to undefined behaviour. In numpy versions >= 1.4.0 nan
+    values are sorted to the end. The extended sort order is:
+
+      * Real: [R, nan]
+      * Complex: [R + Rj, R + nanj, nan + Rj, nan + nanj]
+
+    where R is a non-nan real value. Complex values with the same nan
+    placements are sorted according to the non-nan part if it exists.
+    Non-nan values are sorted as before.
+
+    Examples
+    --------
+    >>> a = np.array([[1,4],[3,1]])
+    >>> np.sort(a)                # sort along the last axis
+    array([[1, 4],
+           [1, 3]])
+    >>> np.sort(a, axis=None)     # sort the flattened array
+    array([1, 1, 3, 4])
+    >>> np.sort(a, axis=0)        # sort along the first axis
+    array([[1, 1],
+           [3, 4]])
+
+    Use the `order` keyword to specify a field to use when sorting a
+    structured array:
+
+    >>> dtype = [('name', 'S10'), ('height', float), ('age', int)]
+    >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38),
+    ...           ('Galahad', 1.7, 38)]
+    >>> a = np.array(values, dtype=dtype)       # create a structured array
+    >>> np.sort(a, order='height')                        # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+           ('Lancelot', 1.8999999999999999, 38)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+    Sort by age, then height if ages are equal:
+
+    >>> np.sort(a, order=['age', 'height'])               # doctest: +SKIP
+    array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38),
+           ('Arthur', 1.8, 41)],
+          dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+    """
+    if axis is None:
+        a = asanyarray(a).flatten()
+        axis = 0
+    else:
+        a = asanyarray(a).copy(order="K")
+    a.sort(axis, kind, order)
+    return a
+
+
+def argsort(a, axis=-1, kind='quicksort', order=None):
+    """
+    Returns the indices that would sort an array.
+
+    Perform an indirect sort along the given axis using the algorithm specified
+    by the `kind` keyword. It returns an array of indices of the same shape as
+    `a` that index data along the given axis in sorted order.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to sort.
+    axis : int or None, optional
+        Axis along which to sort.  The default is -1 (the last axis). If None,
+        the flattened array is used.
+    kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+        Sorting algorithm.
+    order : str or list of str, optional
+        When `a` is an array with fields defined, this argument specifies
+        which fields to compare first, second, etc.  A single field can
+        be specified as a string, and not all fields need be specified,
+        but unspecified fields will still be used, in the order in which
+        they come up in the dtype, to break ties.
+
+    Returns
+    -------
+    index_array : ndarray, int
+        Array of indices that sort `a` along the specified axis.
+        If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`.
+
+    See Also
+    --------
+    sort : Describes sorting algorithms used.
+    lexsort : Indirect stable sort with multiple keys.
+    ndarray.sort : Inplace sort.
+    argpartition : Indirect partial sort.
+
+    Notes
+    -----
+    See `sort` for notes on the different sorting algorithms.
+
+    As of NumPy 1.4.0 `argsort` works with real/complex arrays containing
+    nan values. The enhanced sort order is documented in `sort`.
+
+    Examples
+    --------
+    One dimensional array:
+
+    >>> x = np.array([3, 1, 2])
+    >>> np.argsort(x)
+    array([1, 2, 0])
+
+    Two-dimensional array:
+
+    >>> x = np.array([[0, 3], [2, 2]])
+    >>> x
+    array([[0, 3],
+           [2, 2]])
+
+    >>> np.argsort(x, axis=0)
+    array([[0, 1],
+           [1, 0]])
+
+    >>> np.argsort(x, axis=1)
+    array([[0, 1],
+           [0, 1]])
+
+    Sorting with keys:
+
+    >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
+    >>> x
+    array([(1, 0), (0, 1)],
+          dtype=[('x', '<i4'), ('y', '<i4')])
+
+    >>> np.argsort(x, order=('x','y'))
+    array([1, 0])
+
+    >>> np.argsort(x, order=('y','x'))
+    array([0, 1])
+
+    """
+    try:
+        argsort = a.argsort
+    except AttributeError:
+        return _wrapit(a, 'argsort', axis, kind, order)
+    return argsort(axis, kind, order)
+
+
+def argmax(a, axis=None, out=None):
+    """
+    Returns the indices of the maximum values along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        By default, the index is into the flattened array, otherwise
+        along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+
+    Returns
+    -------
+    index_array : ndarray of ints
+        Array of indices into the array. It has the same shape as `a.shape`
+        with the dimension along `axis` removed.
+
+    See Also
+    --------
+    ndarray.argmax, argmin
+    amax : The maximum value along a given axis.
+    unravel_index : Convert a flat index into an index tuple.
+
+    Notes
+    -----
+    In case of multiple occurrences of the maximum values, the indices
+    corresponding to the first occurrence are returned.
+
+    Examples
+    --------
+    >>> a = np.arange(6).reshape(2,3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argmax(a)
+    5
+    >>> np.argmax(a, axis=0)
+    array([1, 1, 1])
+    >>> np.argmax(a, axis=1)
+    array([2, 2])
+
+    >>> b = np.arange(6)
+    >>> b[1] = 5
+    >>> b
+    array([0, 5, 2, 3, 4, 5])
+    >>> np.argmax(b) # Only the first occurrence is returned.
+    1
+
+    """
+    try:
+        argmax = a.argmax
+    except AttributeError:
+        return _wrapit(a, 'argmax', axis, out)
+    return argmax(axis, out)
+
+
+def argmin(a, axis=None, out=None):
+    """
+    Returns the indices of the minimum values along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        By default, the index is into the flattened array, otherwise
+        along the specified axis.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and dtype.
+
+    Returns
+    -------
+    index_array : ndarray of ints
+        Array of indices into the array. It has the same shape as `a.shape`
+        with the dimension along `axis` removed.
+
+    See Also
+    --------
+    ndarray.argmin, argmax
+    amin : The minimum value along a given axis.
+    unravel_index : Convert a flat index into an index tuple.
+
+    Notes
+    -----
+    In case of multiple occurrences of the minimum values, the indices
+    corresponding to the first occurrence are returned.
+
+    Examples
+    --------
+    >>> a = np.arange(6).reshape(2,3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argmin(a)
+    0
+    >>> np.argmin(a, axis=0)
+    array([0, 0, 0])
+    >>> np.argmin(a, axis=1)
+    array([0, 0])
+
+    >>> b = np.arange(6)
+    >>> b[4] = 0
+    >>> b
+    array([0, 1, 2, 3, 0, 5])
+    >>> np.argmin(b) # Only the first occurrence is returned.
+    0
+
+    """
+    try:
+        argmin = a.argmin
+    except AttributeError:
+        return _wrapit(a, 'argmin', axis, out)
+    return argmin(axis, out)
+
+
+def searchsorted(a, v, side='left', sorter=None):
+    """
+    Find indices where elements should be inserted to maintain order.
+
+    Find the indices into a sorted array `a` such that, if the
+    corresponding elements in `v` were inserted before the indices, the
+    order of `a` would be preserved.
+
+    Parameters
+    ----------
+    a : 1-D array_like
+        Input array. If `sorter` is None, then it must be sorted in
+        ascending order, otherwise `sorter` must be an array of indices
+        that sort it.
+    v : array_like
+        Values to insert into `a`.
+    side : {'left', 'right'}, optional
+        If 'left', the index of the first suitable location found is given.
+        If 'right', return the last such index.  If there is no suitable
+        index, return either 0 or N (where N is the length of `a`).
+    sorter : 1-D array_like, optional
+        Optional array of integer indices that sort array a into ascending
+        order. They are typically the result of argsort.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    indices : array of ints
+        Array of insertion points with the same shape as `v`.
+
+    See Also
+    --------
+    sort : Return a sorted copy of an array.
+    histogram : Produce histogram from 1-D data.
+
+    Notes
+    -----
+    Binary search is used to find the required insertion points.
+
+    As of Numpy 1.4.0 `searchsorted` works with real/complex arrays containing
+    `nan` values. The enhanced sort order is documented in `sort`.
+
+    Examples
+    --------
+    >>> np.searchsorted([1,2,3,4,5], 3)
+    2
+    >>> np.searchsorted([1,2,3,4,5], 3, side='right')
+    3
+    >>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
+    array([0, 5, 1, 2])
+
+    """
+    try:
+        searchsorted = a.searchsorted
+    except AttributeError:
+        return _wrapit(a, 'searchsorted', v, side, sorter)
+    return searchsorted(v, side, sorter)
+
+
+def resize(a, new_shape):
+    """
+    Return a new array with the specified shape.
+
+    If the new array is larger than the original array, then the new
+    array is filled with repeated copies of `a`.  Note that this behavior
+    is different from a.resize(new_shape) which fills with zeros instead
+    of repeated copies of `a`.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be resized.
+
+    new_shape : int or tuple of int
+        Shape of resized array.
+
+    Returns
+    -------
+    reshaped_array : ndarray
+        The new array is formed from the data in the old array, repeated
+        if necessary to fill out the required number of elements.  The
+        data are repeated in the order that they are stored in memory.
+
+    See Also
+    --------
+    ndarray.resize : resize an array in-place.
+
+    Examples
+    --------
+    >>> a=np.array([[0,1],[2,3]])
+    >>> np.resize(a,(2,3))
+    array([[0, 1, 2],
+           [3, 0, 1]])
+    >>> np.resize(a,(1,4))
+    array([[0, 1, 2, 3]])
+    >>> np.resize(a,(2,4))
+    array([[0, 1, 2, 3],
+           [0, 1, 2, 3]])
+
+    """
+    if isinstance(new_shape, (int, nt.integer)):
+        new_shape = (new_shape,)
+    a = ravel(a)
+    Na = len(a)
+    if not Na:
+        return mu.zeros(new_shape, a.dtype)
+    total_size = um.multiply.reduce(new_shape)
+    n_copies = int(total_size / Na)
+    extra = total_size % Na
+
+    if total_size == 0:
+        return a[:0]
+
+    if extra != 0:
+        n_copies = n_copies+1
+        extra = Na-extra
+
+    a = concatenate((a,)*n_copies)
+    if extra > 0:
+        a = a[:-extra]
+
+    return reshape(a, new_shape)
+
+
+def squeeze(a, axis=None):
+    """
+    Remove single-dimensional entries from the shape of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        .. versionadded:: 1.7.0
+
+        Selects a subset of the single-dimensional entries in the
+        shape. If an axis is selected with shape entry greater than
+        one, an error is raised.
+
+    Returns
+    -------
+    squeezed : ndarray
+        The input array, but with all or a subset of the
+        dimensions of length 1 removed. This is always `a` itself
+        or a view into `a`.
+
+    Examples
+    --------
+    >>> x = np.array([[[0], [1], [2]]])
+    >>> x.shape
+    (1, 3, 1)
+    >>> np.squeeze(x).shape
+    (3,)
+    >>> np.squeeze(x, axis=(2,)).shape
+    (1, 3)
+
+    """
+    try:
+        squeeze = a.squeeze
+    except AttributeError:
+        return _wrapit(a, 'squeeze')
+    try:
+        # First try to use the new axis= parameter
+        return squeeze(axis=axis)
+    except TypeError:
+        # For backwards compatibility
+        return squeeze()
+
+
+def diagonal(a, offset=0, axis1=0, axis2=1):
+    """
+    Return specified diagonals.
+
+    If `a` is 2-D, returns the diagonal of `a` with the given offset,
+    i.e., the collection of elements of the form ``a[i, i+offset]``.  If
+    `a` has more than two dimensions, then the axes specified by `axis1`
+    and `axis2` are used to determine the 2-D sub-array whose diagonal is
+    returned.  The shape of the resulting array can be determined by
+    removing `axis1` and `axis2` and appending an index to the right equal
+    to the size of the resulting diagonals.
+
+    In versions of NumPy prior to 1.7, this function always returned a new,
+    independent array containing a copy of the values in the diagonal.
+
+    In NumPy 1.7 and 1.8, it continues to return a copy of the diagonal,
+    but depending on this fact is deprecated. Writing to the resulting
+    array continues to work as it used to, but a FutureWarning is issued.
+
+    Starting in NumPy 1.9 it returns a read-only view on the original array.
+    Attempting to write to the resulting array will produce an error.
+
+    In some future release, it will return a read/write view and writing to
+    the returned array will alter your original array.  The returned array
+    will have the same type as the input array.
+
+    If you don't write to the array returned by this function, then you can
+    just ignore all of the above.
+
+    If you depend on the current behavior, then we suggest copying the
+    returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead
+    of just ``np.diagonal(a)``. This will work with both past and future
+    versions of NumPy.
+
+    Parameters
+    ----------
+    a : array_like
+        Array from which the diagonals are taken.
+    offset : int, optional
+        Offset of the diagonal from the main diagonal.  Can be positive or
+        negative.  Defaults to main diagonal (0).
+    axis1 : int, optional
+        Axis to be used as the first axis of the 2-D sub-arrays from which
+        the diagonals should be taken.  Defaults to first axis (0).
+    axis2 : int, optional
+        Axis to be used as the second axis of the 2-D sub-arrays from
+        which the diagonals should be taken. Defaults to second axis (1).
+
+    Returns
+    -------
+    array_of_diagonals : ndarray
+        If `a` is 2-D and not a matrix, a 1-D array of the same type as `a`
+        containing the diagonal is returned. If `a` is a matrix, a 1-D
+        array containing the diagonal is returned in order to maintain
+        backward compatibility.  If the dimension of `a` is greater than
+        two, then an array of diagonals is returned, "packed" from
+        left-most dimension to right-most (e.g., if `a` is 3-D, then the
+        diagonals are "packed" along rows).
+
+    Raises
+    ------
+    ValueError
+        If the dimension of `a` is less than 2.
+
+    See Also
+    --------
+    diag : MATLAB work-a-like for 1-D and 2-D arrays.
+    diagflat : Create diagonal arrays.
+    trace : Sum along diagonals.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape(2,2)
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> a.diagonal()
+    array([0, 3])
+    >>> a.diagonal(1)
+    array([1])
+
+    A 3-D example:
+
+    >>> a = np.arange(8).reshape(2,2,2); a
+    array([[[0, 1],
+            [2, 3]],
+           [[4, 5],
+            [6, 7]]])
+    >>> a.diagonal(0, # Main diagonals of two arrays created by skipping
+    ...            0, # across the outer(left)-most axis last and
+    ...            1) # the "middle" (row) axis first.
+    array([[0, 6],
+           [1, 7]])
+
+    The sub-arrays whose main diagonals we just obtained; note that each
+    corresponds to fixing the right-most (column) axis, and that the
+    diagonals are "packed" in rows.
+
+    >>> a[:,:,0] # main diagonal is [0 6]
+    array([[0, 2],
+           [4, 6]])
+    >>> a[:,:,1] # main diagonal is [1 7]
+    array([[1, 3],
+           [5, 7]])
+
+    """
+    if isinstance(a, np.matrix):
+        # Make diagonal of matrix 1-D to preserve backward compatibility.
+        return asarray(a).diagonal(offset, axis1, axis2)
+    else:
+        return asanyarray(a).diagonal(offset, axis1, axis2)
+
+
+def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):
+    """
+    Return the sum along diagonals of the array.
+
+    If `a` is 2-D, the sum along its diagonal with the given offset
+    is returned, i.e., the sum of elements ``a[i,i+offset]`` for all i.
+
+    If `a` has more than two dimensions, then the axes specified by axis1 and
+    axis2 are used to determine the 2-D sub-arrays whose traces are returned.
+    The shape of the resulting array is the same as that of `a` with `axis1`
+    and `axis2` removed.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, from which the diagonals are taken.
+    offset : int, optional
+        Offset of the diagonal from the main diagonal. Can be both positive
+        and negative. Defaults to 0.
+    axis1, axis2 : int, optional
+        Axes to be used as the first and second axis of the 2-D sub-arrays
+        from which the diagonals should be taken. Defaults are the first two
+        axes of `a`.
+    dtype : dtype, optional
+        Determines the data-type of the returned array and of the accumulator
+        where the elements are summed. If dtype has the value None and `a` is
+        of integer type of precision less than the default integer
+        precision, then the default integer precision is used. Otherwise,
+        the precision is the same as that of `a`.
+    out : ndarray, optional
+        Array into which the output is placed. Its type is preserved and
+        it must be of the right shape to hold the output.
+
+    Returns
+    -------
+    sum_along_diagonals : ndarray
+        If `a` is 2-D, the sum along the diagonal is returned.  If `a` has
+        larger dimensions, then an array of sums along diagonals is returned.
+
+    See Also
+    --------
+    diag, diagonal, diagflat
+
+    Examples
+    --------
+    >>> np.trace(np.eye(3))
+    3.0
+    >>> a = np.arange(8).reshape((2,2,2))
+    >>> np.trace(a)
+    array([6, 8])
+
+    >>> a = np.arange(24).reshape((2,2,2,3))
+    >>> np.trace(a).shape
+    (2, 3)
+
+    """
+    if isinstance(a, np.matrix):
+        # Get trace of matrix via an array to preserve backward compatibility.
+        return asarray(a).trace(offset, axis1, axis2, dtype, out)
+    else:
+        return asanyarray(a).trace(offset, axis1, axis2, dtype, out)
+
+
+def ravel(a, order='C'):
+    """Return a contiguous flattened array.
+
+    A 1-D array, containing the elements of the input, is returned.  A copy is
+    made only if needed.
+
+    As of NumPy 1.10, the returned array will have the same type as the input
+    array. (for example, a masked array will be returned for a masked array
+    input)
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.  The elements in `a` are read in the order specified by
+        `order`, and packed as a 1-D array.
+    order : {'C','F', 'A', 'K'}, optional
+
+        The elements of `a` are read using this index order. 'C' means
+        to index the elements in row-major, C-style order,
+        with the last axis index changing fastest, back to the first
+        axis index changing slowest.  'F' means to index the elements
+        in column-major, Fortran-style order, with the
+        first index changing fastest, and the last index changing
+        slowest. Note that the 'C' and 'F' options take no account of
+        the memory layout of the underlying array, and only refer to
+        the order of axis indexing.  'A' means to read the elements in
+        Fortran-like index order if `a` is Fortran *contiguous* in
+        memory, C-like order otherwise.  'K' means to read the
+        elements in the order they occur in memory, except for
+        reversing the data when strides are negative.  By default, 'C'
+        index order is used.
+
+    Returns
+    -------
+    y : array_like
+        If `a` is a matrix, y is a 1-D ndarray, otherwise y is an array of
+        the same subtype as `a`. The shape of the returned array is
+        ``(a.size,)``. Matrices are special cased for backward
+        compatibility.
+
+    See Also
+    --------
+    ndarray.flat : 1-D iterator over an array.
+    ndarray.flatten : 1-D array copy of the elements of an array
+                      in row-major order.
+    ndarray.reshape : Change the shape of an array without changing its data.
+
+    Notes
+    -----
+    In row-major, C-style order, in two dimensions, the row index
+    varies the slowest, and the column index the quickest.  This can
+    be generalized to multiple dimensions, where row-major order
+    implies that the index along the first axis varies slowest, and
+    the index along the last quickest.  The opposite holds for
+    column-major, Fortran-style index ordering.
+
+    When a view is desired in as many cases as possible, ``arr.reshape(-1)``
+    may be preferable.
+
+    Examples
+    --------
+    It is equivalent to ``reshape(-1, order=order)``.
+
+    >>> x = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> print(np.ravel(x))
+    [1 2 3 4 5 6]
+
+    >>> print(x.reshape(-1))
+    [1 2 3 4 5 6]
+
+    >>> print(np.ravel(x, order='F'))
+    [1 4 2 5 3 6]
+
+    When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering:
+
+    >>> print(np.ravel(x.T))
+    [1 4 2 5 3 6]
+    >>> print(np.ravel(x.T, order='A'))
+    [1 2 3 4 5 6]
+
+    When ``order`` is 'K', it will preserve orderings that are neither 'C'
+    nor 'F', but won't reverse axes:
+
+    >>> a = np.arange(3)[::-1]; a
+    array([2, 1, 0])
+    >>> a.ravel(order='C')
+    array([2, 1, 0])
+    >>> a.ravel(order='K')
+    array([2, 1, 0])
+
+    >>> a = np.arange(12).reshape(2,3,2).swapaxes(1,2); a
+    array([[[ 0,  2,  4],
+            [ 1,  3,  5]],
+           [[ 6,  8, 10],
+            [ 7,  9, 11]]])
+    >>> a.ravel(order='C')
+    array([ 0,  2,  4,  1,  3,  5,  6,  8, 10,  7,  9, 11])
+    >>> a.ravel(order='K')
+    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
+
+    """
+    if isinstance(a, np.matrix):
+        return asarray(a).ravel(order)
+    else:
+        return asanyarray(a).ravel(order)
+
+
+def nonzero(a):
+    """
+    Return the indices of the elements that are non-zero.
+
+    Returns a tuple of arrays, one for each dimension of `a`,
+    containing the indices of the non-zero elements in that
+    dimension. The values in `a` are always tested and returned in
+    row-major, C-style order. The corresponding non-zero
+    values can be obtained with::
+
+        a[nonzero(a)]
+
+    To group the indices by element, rather than dimension, use::
+
+        transpose(nonzero(a))
+
+    The result of this is always a 2-D array, with a row for
+    each non-zero element.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+
+    Returns
+    -------
+    tuple_of_arrays : tuple
+        Indices of elements that are non-zero.
+
+    See Also
+    --------
+    flatnonzero :
+        Return indices that are non-zero in the flattened version of the input
+        array.
+    ndarray.nonzero :
+        Equivalent ndarray method.
+    count_nonzero :
+        Counts the number of non-zero elements in the input array.
+
+    Examples
+    --------
+    >>> x = np.eye(3)
+    >>> x
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> np.nonzero(x)
+    (array([0, 1, 2]), array([0, 1, 2]))
+
+    >>> x[np.nonzero(x)]
+    array([ 1.,  1.,  1.])
+    >>> np.transpose(np.nonzero(x))
+    array([[0, 0],
+           [1, 1],
+           [2, 2]])
+
+    A common use for ``nonzero`` is to find the indices of an array, where
+    a condition is True.  Given an array `a`, the condition `a` > 3 is a
+    boolean array and since False is interpreted as 0, np.nonzero(a > 3)
+    yields the indices of the `a` where the condition is true.
+
+    >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
+    >>> a > 3
+    array([[False, False, False],
+           [ True,  True,  True],
+           [ True,  True,  True]], dtype=bool)
+    >>> np.nonzero(a > 3)
+    (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+    The ``nonzero`` method of the boolean array can also be called.
+
+    >>> (a > 3).nonzero()
+    (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+    """
+    try:
+        nonzero = a.nonzero
+    except AttributeError:
+        res = _wrapit(a, 'nonzero')
+    else:
+        res = nonzero()
+    return res
+
+
+def shape(a):
+    """
+    Return the shape of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+
+    Returns
+    -------
+    shape : tuple of ints
+        The elements of the shape tuple give the lengths of the
+        corresponding array dimensions.
+
+    See Also
+    --------
+    alen
+    ndarray.shape : Equivalent array method.
+
+    Examples
+    --------
+    >>> np.shape(np.eye(3))
+    (3, 3)
+    >>> np.shape([[1, 2]])
+    (1, 2)
+    >>> np.shape([0])
+    (1,)
+    >>> np.shape(0)
+    ()
+
+    >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+    >>> np.shape(a)
+    (2,)
+    >>> a.shape
+    (2,)
+
+    """
+    try:
+        result = a.shape
+    except AttributeError:
+        result = asarray(a).shape
+    return result
+
+
+def compress(condition, a, axis=None, out=None):
+    """
+    Return selected slices of an array along given axis.
+
+    When working along a given axis, a slice along that axis is returned in
+    `output` for each index where `condition` evaluates to True. When
+    working on a 1-D array, `compress` is equivalent to `extract`.
+
+    Parameters
+    ----------
+    condition : 1-D array of bools
+        Array that selects which entries to return. If len(condition)
+        is less than the size of `a` along the given axis, then output is
+        truncated to the length of the condition array.
+    a : array_like
+        Array from which to extract a part.
+    axis : int, optional
+        Axis along which to take slices. If None (default), work on the
+        flattened array.
+    out : ndarray, optional
+        Output array.  Its type is preserved and it must be of the right
+        shape to hold the output.
+
+    Returns
+    -------
+    compressed_array : ndarray
+        A copy of `a` without the slices along axis for which `condition`
+        is false.
+
+    See Also
+    --------
+    take, choose, diag, diagonal, select
+    ndarray.compress : Equivalent method in ndarray
+    np.extract: Equivalent method when working on 1-D arrays
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4], [5, 6]])
+    >>> a
+    array([[1, 2],
+           [3, 4],
+           [5, 6]])
+    >>> np.compress([0, 1], a, axis=0)
+    array([[3, 4]])
+    >>> np.compress([False, True, True], a, axis=0)
+    array([[3, 4],
+           [5, 6]])
+    >>> np.compress([False, True], a, axis=1)
+    array([[2],
+           [4],
+           [6]])
+
+    Working on the flattened array does not return slices along an axis but
+    selects elements.
+
+    >>> np.compress([False, True], a)
+    array([2])
+
+    """
+    try:
+        compress = a.compress
+    except AttributeError:
+        return _wrapit(a, 'compress', condition, axis, out)
+    return compress(condition, axis, out)
+
+
+def clip(a, a_min, a_max, out=None):
+    """
+    Clip (limit) the values in an array.
+
+    Given an interval, values outside the interval are clipped to
+    the interval edges.  For example, if an interval of ``[0, 1]``
+    is specified, values smaller than 0 become 0, and values larger
+    than 1 become 1.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing elements to clip.
+    a_min : scalar or array_like
+        Minimum value.
+    a_max : scalar or array_like
+        Maximum value.  If `a_min` or `a_max` are array_like, then they will
+        be broadcasted to the shape of `a`.
+    out : ndarray, optional
+        The results will be placed in this array. It may be the input
+        array for in-place clipping.  `out` must be of the right shape
+        to hold the output.  Its type is preserved.
+
+    Returns
+    -------
+    clipped_array : ndarray
+        An array with the elements of `a`, but where values
+        < `a_min` are replaced with `a_min`, and those > `a_max`
+        with `a_max`.
+
+    See Also
+    --------
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Examples
+    --------
+    >>> a = np.arange(10)
+    >>> np.clip(a, 1, 8)
+    array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> np.clip(a, 3, 6, out=a)
+    array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
+    >>> a = np.arange(10)
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8)
+    array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])
+
+    """
+    try:
+        clip = a.clip
+    except AttributeError:
+        return _wrapit(a, 'clip', a_min, a_max, out)
+    return clip(a_min, a_max, out)
+
+
+def sum(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Sum of array elements over a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Elements to sum.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a sum is performed.  The default,
+        axis=None, will sum all of the elements of the input array.  If
+        axis is negative it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If axis is a tuple of ints, a sum is performed on all of the axes
+        specified in the tuple instead of a single axis or all the axes as
+        before.
+    dtype : dtype, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  The dtype of `a` is used by default unless `a`
+        has an integer dtype of less precision than the default platform
+        integer.  In that case, if `a` is signed then the platform integer
+        is used while if `a` is unsigned then an unsigned integer of the
+        same precision as the platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the input array.
+
+    Returns
+    -------
+    sum_along_axis : ndarray
+        An array with the same shape as `a`, with the specified
+        axis removed.   If `a` is a 0-d array, or if `axis` is None, a scalar
+        is returned.  If an output array is specified, a reference to
+        `out` is returned.
+
+    See Also
+    --------
+    ndarray.sum : Equivalent method.
+
+    cumsum : Cumulative sum of array elements.
+
+    trapz : Integration of array values using the composite trapezoidal rule.
+
+    mean, average
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    The sum of an empty array is the neutral element 0:
+
+    >>> np.sum([])
+    0.0
+
+    Examples
+    --------
+    >>> np.sum([0.5, 1.5])
+    2.0
+    >>> np.sum([0.5, 0.7, 0.2, 1.5], dtype=np.int32)
+    1
+    >>> np.sum([[0, 1], [0, 5]])
+    6
+    >>> np.sum([[0, 1], [0, 5]], axis=0)
+    array([0, 6])
+    >>> np.sum([[0, 1], [0, 5]], axis=1)
+    array([1, 5])
+
+    If the accumulator is too small, overflow occurs:
+
+    >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8)
+    -128
+
+    """
+    if isinstance(a, _gentype):
+        res = _sum_(a)
+        if out is not None:
+            out[...] = res
+            return out
+        return res
+    elif type(a) is not mu.ndarray:
+        try:
+            sum = a.sum
+        except AttributeError:
+            return _methods._sum(a, axis=axis, dtype=dtype,
+                                 out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameters here...
+        return sum(axis=axis, dtype=dtype, out=out)
+    else:
+        return _methods._sum(a, axis=axis, dtype=dtype,
+                             out=out, keepdims=keepdims)
+
+
+def product(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Return the product of array elements over a given axis.
+
+    See Also
+    --------
+    prod : equivalent function; see for details.
+
+    """
+    return um.multiply.reduce(a, axis=axis, dtype=dtype,
+                              out=out, keepdims=keepdims)
+
+
+def sometrue(a, axis=None, out=None, keepdims=False):
+    """
+    Check whether some values are true.
+
+    Refer to `any` for full documentation.
+
+    See Also
+    --------
+    any : equivalent function
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.any(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.any(axis=axis, out=out)
+
+
+def alltrue(a, axis=None, out=None, keepdims=False):
+    """
+    Check if all elements of input array are true.
+
+    See Also
+    --------
+    numpy.all : Equivalent function; see for details.
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.all(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.all(axis=axis, out=out)
+
+
+def any(a, axis=None, out=None, keepdims=False):
+    """
+    Test whether any array element along a given axis evaluates to True.
+
+    Returns single boolean unless `axis` is not ``None``
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a logical OR reduction is performed.
+        The default (`axis` = `None`) is to perform a logical OR over all
+        the dimensions of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output and its type is preserved
+        (e.g., if it is of type float, then it will remain so, returning
+        1.0 for True and 0.0 for False, regardless of the type of `a`).
+        See `doc.ufuncs` (Section "Output arguments") for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    any : bool or ndarray
+        A new boolean or `ndarray` is returned unless `out` is specified,
+        in which case a reference to `out` is returned.
+
+    See Also
+    --------
+    ndarray.any : equivalent method
+
+    all : Test whether all elements along a given axis evaluate to True.
+
+    Notes
+    -----
+    Not a Number (NaN), positive infinity and negative infinity evaluate
+    to `True` because these are not equal to zero.
+
+    Examples
+    --------
+    >>> np.any([[True, False], [True, True]])
+    True
+
+    >>> np.any([[True, False], [False, False]], axis=0)
+    array([ True, False], dtype=bool)
+
+    >>> np.any([-1, 0, 5])
+    True
+
+    >>> np.any(np.nan)
+    True
+
+    >>> o=np.array([False])
+    >>> z=np.any([-1, 4, 5], out=o)
+    >>> z, o
+    (array([ True], dtype=bool), array([ True], dtype=bool))
+    >>> # Check now that z is a reference to o
+    >>> z is o
+    True
+    >>> id(z), id(o) # identity of z and o              # doctest: +SKIP
+    (191614240, 191614240)
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.any(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.any(axis=axis, out=out)
+
+
+def all(a, axis=None, out=None, keepdims=False):
+    """
+    Test whether all array elements along a given axis evaluate to True.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a logical AND reduction is performed.
+        The default (`axis` = `None`) is to perform a logical AND over all
+        the dimensions of the input array. `axis` may be negative, in
+        which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.7.0
+
+        If this is a tuple of ints, a reduction is performed on multiple
+        axes, instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternate output array in which to place the result.
+        It must have the same shape as the expected output and its
+        type is preserved (e.g., if ``dtype(out)`` is float, the result
+        will consist of 0.0's and 1.0's).  See `doc.ufuncs` (Section
+        "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    all : ndarray, bool
+        A new boolean or array is returned unless `out` is specified,
+        in which case a reference to `out` is returned.
+
+    See Also
+    --------
+    ndarray.all : equivalent method
+
+    any : Test whether any element along a given axis evaluates to True.
+
+    Notes
+    -----
+    Not a Number (NaN), positive infinity and negative infinity
+    evaluate to `True` because these are not equal to zero.
+
+    Examples
+    --------
+    >>> np.all([[True,False],[True,True]])
+    False
+
+    >>> np.all([[True,False],[True,True]], axis=0)
+    array([ True, False], dtype=bool)
+
+    >>> np.all([-1, 4, 5])
+    True
+
+    >>> np.all([1.0, np.nan])
+    True
+
+    >>> o=np.array([False])
+    >>> z=np.all([-1, 4, 5], out=o)
+    >>> id(z), id(o), z                             # doctest: +SKIP
+    (28293632, 28293632, array([ True], dtype=bool))
+
+    """
+    arr = asanyarray(a)
+
+    try:
+        return arr.all(axis=axis, out=out, keepdims=keepdims)
+    except TypeError:
+        return arr.all(axis=axis, out=out)
+
+
+def cumsum(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative sum of the elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        Axis along which the cumulative sum is computed. The default
+        (None) is to compute the cumsum over the flattened array.
+    dtype : dtype, optional
+        Type of the returned array and of the accumulator in which the
+        elements are summed.  If `dtype` is not specified, it defaults
+        to the dtype of `a`, unless `a` has an integer dtype with a
+        precision less than that of the default platform integer.  In
+        that case, the default platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type will be cast if necessary. See `doc.ufuncs`
+        (Section "Output arguments") for more details.
+
+    Returns
+    -------
+    cumsum_along_axis : ndarray.
+        A new array holding the result is returned unless `out` is
+        specified, in which case a reference to `out` is returned. The
+        result has the same size as `a`, and the same shape as `a` if
+        `axis` is not None or `a` is a 1-d array.
+
+
+    See Also
+    --------
+    sum : Sum array elements.
+
+    trapz : Integration of array values using the composite trapezoidal rule.
+
+    diff :  Calculate the n-th discrete difference along given axis.
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3], [4,5,6]])
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.cumsum(a)
+    array([ 1,  3,  6, 10, 15, 21])
+    >>> np.cumsum(a, dtype=float)     # specifies type of output value(s)
+    array([  1.,   3.,   6.,  10.,  15.,  21.])
+
+    >>> np.cumsum(a,axis=0)      # sum over rows for each of the 3 columns
+    array([[1, 2, 3],
+           [5, 7, 9]])
+    >>> np.cumsum(a,axis=1)      # sum over columns for each of the 2 rows
+    array([[ 1,  3,  6],
+           [ 4,  9, 15]])
+
+    """
+    try:
+        cumsum = a.cumsum
+    except AttributeError:
+        return _wrapit(a, 'cumsum', axis, dtype, out)
+    return cumsum(axis, dtype, out)
+
+
+def cumproduct(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative product over the given axis.
+
+
+    See Also
+    --------
+    cumprod : equivalent function; see for details.
+
+    """
+    try:
+        cumprod = a.cumprod
+    except AttributeError:
+        return _wrapit(a, 'cumprod', axis, dtype, out)
+    return cumprod(axis, dtype, out)
+
+
+def ptp(a, axis=None, out=None):
+    """
+    Range of values (maximum - minimum) along an axis.
+
+    The name of the function comes from the acronym for 'peak to peak'.
+
+    Parameters
+    ----------
+    a : array_like
+        Input values.
+    axis : int, optional
+        Axis along which to find the peaks.  By default, flatten the
+        array.
+    out : array_like
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type of the output values will be cast if necessary.
+
+    Returns
+    -------
+    ptp : ndarray
+        A new array holding the result, unless `out` was
+        specified, in which case a reference to `out` is returned.
+
+    Examples
+    --------
+    >>> x = np.arange(4).reshape((2,2))
+    >>> x
+    array([[0, 1],
+           [2, 3]])
+
+    >>> np.ptp(x, axis=0)
+    array([2, 2])
+
+    >>> np.ptp(x, axis=1)
+    array([1, 1])
+
+    """
+    try:
+        ptp = a.ptp
+    except AttributeError:
+        return _wrapit(a, 'ptp', axis, out)
+    return ptp(axis, out)
+
+
+def amax(a, axis=None, out=None, keepdims=False):
+    """
+    Return the maximum of an array or maximum along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which to operate.  By default, flattened input is
+        used.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, the maximum is selected over multiple axes,
+        instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternative output array in which to place the result.  Must
+        be of the same shape and buffer length as the expected output.
+        See `doc.ufuncs` (Section "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    amax : ndarray or scalar
+        Maximum of `a`. If `axis` is None, the result is a scalar value.
+        If `axis` is given, the result is an array of dimension
+        ``a.ndim - 1``.
+
+    See Also
+    --------
+    amin :
+        The minimum value of an array along a given axis, propagating any NaNs.
+    nanmax :
+        The maximum value of an array along a given axis, ignoring any NaNs.
+    maximum :
+        Element-wise maximum of two arrays, propagating any NaNs.
+    fmax :
+        Element-wise maximum of two arrays, ignoring any NaNs.
+    argmax :
+        Return the indices of the maximum values.
+
+    nanmin, minimum, fmin
+
+    Notes
+    -----
+    NaN values are propagated, that is if at least one item is NaN, the
+    corresponding max value will be NaN as well. To ignore NaN values
+    (MATLAB behavior), please use nanmax.
+
+    Don't use `amax` for element-wise comparison of 2 arrays; when
+    ``a.shape[0]`` is 2, ``maximum(a[0], a[1])`` is faster than
+    ``amax(a, axis=0)``.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape((2,2))
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> np.amax(a)           # Maximum of the flattened array
+    3
+    >>> np.amax(a, axis=0)   # Maxima along the first axis
+    array([2, 3])
+    >>> np.amax(a, axis=1)   # Maxima along the second axis
+    array([1, 3])
+
+    >>> b = np.arange(5, dtype=np.float)
+    >>> b[2] = np.NaN
+    >>> np.amax(b)
+    nan
+    >>> np.nanmax(b)
+    4.0
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            amax = a.max
+        except AttributeError:
+            return _methods._amax(a, axis=axis,
+                                  out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameter
+        return amax(axis=axis, out=out)
+    else:
+        return _methods._amax(a, axis=axis,
+                              out=out, keepdims=keepdims)
+
+
+def amin(a, axis=None, out=None, keepdims=False):
+    """
+    Return the minimum of an array or minimum along an axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which to operate.  By default, flattened input is
+        used.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, the minimum is selected over multiple axes,
+        instead of a single axis or all the axes as before.
+    out : ndarray, optional
+        Alternative output array in which to place the result.  Must
+        be of the same shape and buffer length as the expected output.
+        See `doc.ufuncs` (Section "Output arguments") for more details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    amin : ndarray or scalar
+        Minimum of `a`. If `axis` is None, the result is a scalar value.
+        If `axis` is given, the result is an array of dimension
+        ``a.ndim - 1``.
+
+    See Also
+    --------
+    amax :
+        The maximum value of an array along a given axis, propagating any NaNs.
+    nanmin :
+        The minimum value of an array along a given axis, ignoring any NaNs.
+    minimum :
+        Element-wise minimum of two arrays, propagating any NaNs.
+    fmin :
+        Element-wise minimum of two arrays, ignoring any NaNs.
+    argmin :
+        Return the indices of the minimum values.
+
+    nanmax, maximum, fmax
+
+    Notes
+    -----
+    NaN values are propagated, that is if at least one item is NaN, the
+    corresponding min value will be NaN as well. To ignore NaN values
+    (MATLAB behavior), please use nanmin.
+
+    Don't use `amin` for element-wise comparison of 2 arrays; when
+    ``a.shape[0]`` is 2, ``minimum(a[0], a[1])`` is faster than
+    ``amin(a, axis=0)``.
+
+    Examples
+    --------
+    >>> a = np.arange(4).reshape((2,2))
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> np.amin(a)           # Minimum of the flattened array
+    0
+    >>> np.amin(a, axis=0)   # Minima along the first axis
+    array([0, 1])
+    >>> np.amin(a, axis=1)   # Minima along the second axis
+    array([0, 2])
+
+    >>> b = np.arange(5, dtype=np.float)
+    >>> b[2] = np.NaN
+    >>> np.amin(b)
+    nan
+    >>> np.nanmin(b)
+    0.0
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            amin = a.min
+        except AttributeError:
+            return _methods._amin(a, axis=axis,
+                                  out=out, keepdims=keepdims)
+        # NOTE: Dropping the keepdims parameter
+        return amin(axis=axis, out=out)
+    else:
+        return _methods._amin(a, axis=axis,
+                              out=out, keepdims=keepdims)
+
+
+def alen(a):
+    """
+    Return the length of the first dimension of the input array.
+
+    Parameters
+    ----------
+    a : array_like
+       Input array.
+
+    Returns
+    -------
+    alen : int
+       Length of the first dimension of `a`.
+
+    See Also
+    --------
+    shape, size
+
+    Examples
+    --------
+    >>> a = np.zeros((7,4,5))
+    >>> a.shape[0]
+    7
+    >>> np.alen(a)
+    7
+
+    """
+    try:
+        return len(a)
+    except TypeError:
+        return len(array(a, ndmin=1))
+
+
+def prod(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Return the product of array elements over a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which a product is performed.  The default,
+        axis=None, will calculate the product of all the elements in the
+        input array. If axis is negative it counts from the last to the
+        first axis.
+
+        .. versionadded:: 1.7.0
+
+        If axis is a tuple of ints, a product is performed on all of the
+        axes specified in the tuple instead of a single axis or all the
+        axes as before.
+    dtype : dtype, optional
+        The type of the returned array, as well as of the accumulator in
+        which the elements are multiplied.  The dtype of `a` is used by
+        default unless `a` has an integer dtype of less precision than the
+        default platform integer.  In that case, if `a` is signed then the
+        platform integer is used while if `a` is unsigned then an unsigned
+        integer of the same precision as the platform integer is used.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the input array.
+
+    Returns
+    -------
+    product_along_axis : ndarray, see `dtype` parameter above.
+        An array shaped as `a` but with the specified axis removed.
+        Returns a reference to `out` if specified.
+
+    See Also
+    --------
+    ndarray.prod : equivalent method
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.  That means that, on a 32-bit platform:
+
+    >>> x = np.array([536870910, 536870910, 536870910, 536870910])
+    >>> np.prod(x) #random
+    16
+
+    The product of an empty array is the neutral element 1:
+
+    >>> np.prod([])
+    1.0
+
+    Examples
+    --------
+    By default, calculate the product of all elements:
+
+    >>> np.prod([1.,2.])
+    2.0
+
+    Even when the input array is two-dimensional:
+
+    >>> np.prod([[1.,2.],[3.,4.]])
+    24.0
+
+    But we can also specify the axis over which to multiply:
+
+    >>> np.prod([[1.,2.],[3.,4.]], axis=1)
+    array([  2.,  12.])
+
+    If the type of `x` is unsigned, then the output type is
+    the unsigned platform integer:
+
+    >>> x = np.array([1, 2, 3], dtype=np.uint8)
+    >>> np.prod(x).dtype == np.uint
+    True
+
+    If `x` is of a signed integer type, then the output type
+    is the default platform integer:
+
+    >>> x = np.array([1, 2, 3], dtype=np.int8)
+    >>> np.prod(x).dtype == np.int
+    True
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            prod = a.prod
+        except AttributeError:
+            return _methods._prod(a, axis=axis, dtype=dtype,
+                                  out=out, keepdims=keepdims)
+        return prod(axis=axis, dtype=dtype, out=out)
+    else:
+        return _methods._prod(a, axis=axis, dtype=dtype,
+                              out=out, keepdims=keepdims)
+
+
+def cumprod(a, axis=None, dtype=None, out=None):
+    """
+    Return the cumulative product of elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int, optional
+        Axis along which the cumulative product is computed.  By default
+        the input is flattened.
+    dtype : dtype, optional
+        Type of the returned array, as well as of the accumulator in which
+        the elements are multiplied.  If *dtype* is not specified, it
+        defaults to the dtype of `a`, unless `a` has an integer dtype with
+        a precision less than that of the default platform integer.  In
+        that case, the default platform integer is used instead.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type of the resulting values will be cast if necessary.
+
+    Returns
+    -------
+    cumprod : ndarray
+        A new array holding the result is returned unless `out` is
+        specified, in which case a reference to out is returned.
+
+    See Also
+    --------
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    Arithmetic is modular when using integer types, and no error is
+    raised on overflow.
+
+    Examples
+    --------
+    >>> a = np.array([1,2,3])
+    >>> np.cumprod(a) # intermediate results 1, 1*2
+    ...               # total product 1*2*3 = 6
+    array([1, 2, 6])
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]])
+    >>> np.cumprod(a, dtype=float) # specify type of output
+    array([   1.,    2.,    6.,   24.,  120.,  720.])
+
+    The cumulative product for each column (i.e., over the rows) of `a`:
+
+    >>> np.cumprod(a, axis=0)
+    array([[ 1,  2,  3],
+           [ 4, 10, 18]])
+
+    The cumulative product for each row (i.e. over the columns) of `a`:
+
+    >>> np.cumprod(a,axis=1)
+    array([[  1,   2,   6],
+           [  4,  20, 120]])
+
+    """
+    try:
+        cumprod = a.cumprod
+    except AttributeError:
+        return _wrapit(a, 'cumprod', axis, dtype, out)
+    return cumprod(axis, dtype, out)
+
+
+def ndim(a):
+    """
+    Return the number of dimensions of an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.  If it is not already an ndarray, a conversion is
+        attempted.
+
+    Returns
+    -------
+    number_of_dimensions : int
+        The number of dimensions in `a`.  Scalars are zero-dimensional.
+
+    See Also
+    --------
+    ndarray.ndim : equivalent method
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+
+    Examples
+    --------
+    >>> np.ndim([[1,2,3],[4,5,6]])
+    2
+    >>> np.ndim(np.array([[1,2,3],[4,5,6]]))
+    2
+    >>> np.ndim(1)
+    0
+
+    """
+    try:
+        return a.ndim
+    except AttributeError:
+        return asarray(a).ndim
+
+
+def rank(a):
+    """
+    Return the number of dimensions of an array.
+
+    If `a` is not already an array, a conversion is attempted.
+    Scalars are zero dimensional.
+
+    .. note::
+        This function is deprecated in NumPy 1.9 to avoid confusion with
+        `numpy.linalg.matrix_rank`. The ``ndim`` attribute or function
+        should be used instead.
+
+    Parameters
+    ----------
+    a : array_like
+        Array whose number of dimensions is desired. If `a` is not an array,
+        a conversion is attempted.
+
+    Returns
+    -------
+    number_of_dimensions : int
+        The number of dimensions in the array.
+
+    See Also
+    --------
+    ndim : equivalent function
+    ndarray.ndim : equivalent property
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+
+    Notes
+    -----
+    In the old Numeric package, `rank` was the term used for the number of
+    dimensions, but in Numpy `ndim` is used instead.
+
+    Examples
+    --------
+    >>> np.rank([1,2,3])
+    1
+    >>> np.rank(np.array([[1,2,3],[4,5,6]]))
+    2
+    >>> np.rank(1)
+    0
+
+    """
+    # 2014-04-12, 1.9
+    warnings.warn(
+        "`rank` is deprecated; use the `ndim` attribute or function instead. "
+        "To find the rank of a matrix see `numpy.linalg.matrix_rank`.",
+        VisibleDeprecationWarning)
+    try:
+        return a.ndim
+    except AttributeError:
+        return asarray(a).ndim
+
+
+def size(a, axis=None):
+    """
+    Return the number of elements along a given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which the elements are counted.  By default, give
+        the total number of elements.
+
+    Returns
+    -------
+    element_count : int
+        Number of elements along the specified axis.
+
+    See Also
+    --------
+    shape : dimensions of array
+    ndarray.shape : dimensions of array
+    ndarray.size : number of elements in array
+
+    Examples
+    --------
+    >>> a = np.array([[1,2,3],[4,5,6]])
+    >>> np.size(a)
+    6
+    >>> np.size(a,1)
+    3
+    >>> np.size(a,0)
+    2
+
+    """
+    if axis is None:
+        try:
+            return a.size
+        except AttributeError:
+            return asarray(a).size
+    else:
+        try:
+            return a.shape[axis]
+        except AttributeError:
+            return asarray(a).shape[axis]
+
+
+def around(a, decimals=0, out=None):
+    """
+    Evenly round to the given number of decimals.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    decimals : int, optional
+        Number of decimal places to round to (default: 0).  If
+        decimals is negative, it specifies the number of positions to
+        the left of the decimal point.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output, but the type of the output
+        values will be cast if necessary. See `doc.ufuncs` (Section
+        "Output arguments") for details.
+
+    Returns
+    -------
+    rounded_array : ndarray
+        An array of the same type as `a`, containing the rounded values.
+        Unless `out` was specified, a new array is created.  A reference to
+        the result is returned.
+
+        The real and imaginary parts of complex numbers are rounded
+        separately.  The result of rounding a float is a float.
+
+    See Also
+    --------
+    ndarray.round : equivalent method
+
+    ceil, fix, floor, rint, trunc
+
+
+    Notes
+    -----
+    For values exactly halfway between rounded decimal values, Numpy
+    rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
+    -0.5 and 0.5 round to 0.0, etc. Results may also be surprising due
+    to the inexact representation of decimal fractions in the IEEE
+    floating point standard [1]_ and errors introduced when scaling
+    by powers of ten.
+
+    References
+    ----------
+    .. [1] "Lecture Notes on the Status of  IEEE 754", William Kahan,
+           http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
+    .. [2] "How Futile are Mindless Assessments of
+           Roundoff in Floating-Point Computation?", William Kahan,
+           http://www.cs.berkeley.edu/~wkahan/Mindless.pdf
+
+    Examples
+    --------
+    >>> np.around([0.37, 1.64])
+    array([ 0.,  2.])
+    >>> np.around([0.37, 1.64], decimals=1)
+    array([ 0.4,  1.6])
+    >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
+    array([ 0.,  2.,  2.,  4.,  4.])
+    >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
+    array([ 1,  2,  3, 11])
+    >>> np.around([1,2,3,11], decimals=-1)
+    array([ 0,  0,  0, 10])
+
+    """
+    try:
+        round = a.round
+    except AttributeError:
+        return _wrapit(a, 'round', decimals, out)
+    return round(decimals, out)
+
+
+def round_(a, decimals=0, out=None):
+    """
+    Round an array to the given number of decimals.
+
+    Refer to `around` for full documentation.
+
+    See Also
+    --------
+    around : equivalent function
+
+    """
+    try:
+        round = a.round
+    except AttributeError:
+        return _wrapit(a, 'round', decimals, out)
+    return round(decimals, out)
+
+
+def mean(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Compute the arithmetic mean along the specified axis.
+
+    Returns the average of the array elements.  The average is taken over
+    the flattened array by default, otherwise over the specified axis.
+    `float64` intermediate and return values are used for integer inputs.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose mean is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the means are computed. The default is to
+        compute the mean of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a mean is performed over multiple axes,
+        instead of a single axis or all the axes as before.
+    dtype : data-type, optional
+        Type to use in computing the mean.  For integer inputs, the default
+        is `float64`; for floating point inputs, it is the same as the
+        input dtype.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.
+        See `doc.ufuncs` for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    m : ndarray, see dtype parameter above
+        If `out=None`, returns a new array containing the mean values,
+        otherwise a reference to the output array is returned.
+
+    See Also
+    --------
+    average : Weighted average
+    std, var, nanmean, nanstd, nanvar
+
+    Notes
+    -----
+    The arithmetic mean is the sum of the elements along the axis divided
+    by the number of elements.
+
+    Note that for floating-point input, the mean is computed using the
+    same precision the input has.  Depending on the input data, this can
+    cause the results to be inaccurate, especially for `float32` (see
+    example below).  Specifying a higher-precision accumulator using the
+    `dtype` keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.mean(a)
+    2.5
+    >>> np.mean(a, axis=0)
+    array([ 2.,  3.])
+    >>> np.mean(a, axis=1)
+    array([ 1.5,  3.5])
+
+    In single precision, `mean` can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.mean(a)
+    0.546875
+
+    Computing the mean in float64 is more accurate:
+
+    >>> np.mean(a, dtype=np.float64)
+    0.55000000074505806
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            mean = a.mean
+            return mean(axis=axis, dtype=dtype, out=out)
+        except AttributeError:
+            pass
+
+    return _methods._mean(a, axis=axis, dtype=dtype,
+                          out=out, keepdims=keepdims)
+
+
+def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the standard deviation along the specified axis.
+
+    Returns the standard deviation, a measure of the spread of a distribution,
+    of the array elements. The standard deviation is computed for the
+    flattened array by default, otherwise over the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Calculate the standard deviation of these values.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the standard deviation is computed. The
+        default is to compute the standard deviation of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a standard deviation is performed over
+        multiple axes, instead of a single axis or all the axes as before.
+    dtype : dtype, optional
+        Type to use in computing the standard deviation. For arrays of
+        integer type the default is float64, for arrays of float types it is
+        the same as the array type.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output but the type (of the calculated
+        values) will be cast if necessary.
+    ddof : int, optional
+        Means Delta Degrees of Freedom.  The divisor used in calculations
+        is ``N - ddof``, where ``N`` represents the number of elements.
+        By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    standard_deviation : ndarray, see dtype parameter above.
+        If `out` is None, return a new array containing the standard deviation,
+        otherwise return a reference to the output array.
+
+    See Also
+    --------
+    var, mean, nanmean, nanstd, nanvar
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The standard deviation is the square root of the average of the squared
+    deviations from the mean, i.e., ``std = sqrt(mean(abs(x - x.mean())**2))``.
+
+    The average squared deviation is normally calculated as
+    ``x.sum() / N``, where ``N = len(x)``.  If, however, `ddof` is specified,
+    the divisor ``N - ddof`` is used instead. In standard statistical
+    practice, ``ddof=1`` provides an unbiased estimator of the variance
+    of the infinite population. ``ddof=0`` provides a maximum likelihood
+    estimate of the variance for normally distributed variables. The
+    standard deviation computed in this function is the square root of
+    the estimated variance, so even with ``ddof=1``, it will not be an
+    unbiased estimate of the standard deviation per se.
+
+    Note that, for complex numbers, `std` takes the absolute
+    value before squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the *std* is computed using the same
+    precision the input has. Depending on the input data, this can cause
+    the results to be inaccurate, especially for float32 (see example below).
+    Specifying a higher-accuracy accumulator using the `dtype` keyword can
+    alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.std(a)
+    1.1180339887498949
+    >>> np.std(a, axis=0)
+    array([ 1.,  1.])
+    >>> np.std(a, axis=1)
+    array([ 0.5,  0.5])
+
+    In single precision, std() can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.std(a)
+    0.45000005
+
+    Computing the standard deviation in float64 is more accurate:
+
+    >>> np.std(a, dtype=np.float64)
+    0.44999999925494177
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            std = a.std
+            return std(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        except AttributeError:
+            pass
+
+    return _methods._std(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                         keepdims=keepdims)
+
+
+def var(a, axis=None, dtype=None, out=None, ddof=0,
+        keepdims=False):
+    """
+    Compute the variance along the specified axis.
+
+    Returns the variance of the array elements, a measure of the spread of a
+    distribution.  The variance is computed for the flattened array by
+    default, otherwise over the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose variance is desired.  If `a` is not an
+        array, a conversion is attempted.
+    axis : None or int or tuple of ints, optional
+        Axis or axes along which the variance is computed.  The default is to
+        compute the variance of the flattened array.
+
+        .. versionadded: 1.7.0
+
+        If this is a tuple of ints, a variance is performed over multiple axes,
+        instead of a single axis or all the axes as before.
+    dtype : data-type, optional
+        Type to use in computing the variance.  For arrays of integer type
+        the default is `float32`; for arrays of float types it is the same as
+        the array type.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output, but the type is cast if
+        necessary.
+    ddof : int, optional
+        "Delta Degrees of Freedom": the divisor used in the calculation is
+        ``N - ddof``, where ``N`` represents the number of elements. By
+        default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    variance : ndarray, see dtype parameter above
+        If ``out=None``, returns a new array containing the variance;
+        otherwise, a reference to the output array is returned.
+
+    See Also
+    --------
+    std , mean, nanmean, nanstd, nanvar
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The variance is the average of the squared deviations from the mean,
+    i.e.,  ``var = mean(abs(x - x.mean())**2)``.
+
+    The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``.
+    If, however, `ddof` is specified, the divisor ``N - ddof`` is used
+    instead.  In standard statistical practice, ``ddof=1`` provides an
+    unbiased estimator of the variance of a hypothetical infinite population.
+    ``ddof=0`` provides a maximum likelihood estimate of the variance for
+    normally distributed variables.
+
+    Note that for complex numbers, the absolute value is taken before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the variance is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32` (see example
+    below).  Specifying a higher-accuracy accumulator using the ``dtype``
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.var(a)
+    1.25
+    >>> np.var(a, axis=0)
+    array([ 1.,  1.])
+    >>> np.var(a, axis=1)
+    array([ 0.25,  0.25])
+
+    In single precision, var() can be inaccurate:
+
+    >>> a = np.zeros((2, 512*512), dtype=np.float32)
+    >>> a[0, :] = 1.0
+    >>> a[1, :] = 0.1
+    >>> np.var(a)
+    0.20250003
+
+    Computing the variance in float64 is more accurate:
+
+    >>> np.var(a, dtype=np.float64)
+    0.20249999932944759
+    >>> ((1-0.55)**2 + (0.1-0.55)**2)/2
+    0.2025
+
+    """
+    if type(a) is not mu.ndarray:
+        try:
+            var = a.var
+            return var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        except AttributeError:
+            pass
+
+    return _methods._var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                         keepdims=keepdims)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/function_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/function_base.py
new file mode 100644
index 0000000000..21ca1af01a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/function_base.py
@@ -0,0 +1,208 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['logspace', 'linspace']
+
+from . import numeric as _nx
+from .numeric import result_type, NaN, shares_memory, MAY_SHARE_BOUNDS, TooHardError
+
+
+def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
+    """
+    Return evenly spaced numbers over a specified interval.
+
+    Returns `num` evenly spaced samples, calculated over the
+    interval [`start`, `stop`].
+
+    The endpoint of the interval can optionally be excluded.
+
+    Parameters
+    ----------
+    start : scalar
+        The starting value of the sequence.
+    stop : scalar
+        The end value of the sequence, unless `endpoint` is set to False.
+        In that case, the sequence consists of all but the last of ``num + 1``
+        evenly spaced samples, so that `stop` is excluded.  Note that the step
+        size changes when `endpoint` is False.
+    num : int, optional
+        Number of samples to generate. Default is 50. Must be non-negative.
+    endpoint : bool, optional
+        If True, `stop` is the last sample. Otherwise, it is not included.
+        Default is True.
+    retstep : bool, optional
+        If True, return (`samples`, `step`), where `step` is the spacing
+        between samples.
+    dtype : dtype, optional
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    samples : ndarray
+        There are `num` equally spaced samples in the closed interval
+        ``[start, stop]`` or the half-open interval ``[start, stop)``
+        (depending on whether `endpoint` is True or False).
+    step : float
+        Only returned if `retstep` is True
+
+        Size of spacing between samples.
+
+
+    See Also
+    --------
+    arange : Similar to `linspace`, but uses a step size (instead of the
+             number of samples).
+    logspace : Samples uniformly distributed in log space.
+
+    Examples
+    --------
+    >>> np.linspace(2.0, 3.0, num=5)
+        array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])
+    >>> np.linspace(2.0, 3.0, num=5, endpoint=False)
+        array([ 2. ,  2.2,  2.4,  2.6,  2.8])
+    >>> np.linspace(2.0, 3.0, num=5, retstep=True)
+        (array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)
+
+    Graphical illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> N = 8
+    >>> y = np.zeros(N)
+    >>> x1 = np.linspace(0, 10, N, endpoint=True)
+    >>> x2 = np.linspace(0, 10, N, endpoint=False)
+    >>> plt.plot(x1, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(x2, y + 0.5, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.ylim([-0.5, 1])
+    (-0.5, 1)
+    >>> plt.show()
+
+    """
+    num = int(num)
+    if num < 0:
+        raise ValueError("Number of samples, %s, must be non-negative." % num)
+    div = (num - 1) if endpoint else num
+
+    # Convert float/complex array scalars to float, gh-3504
+    start = start * 1.
+    stop = stop * 1.
+
+    dt = result_type(start, stop, float(num))
+    if dtype is None:
+        dtype = dt
+
+    y = _nx.arange(0, num, dtype=dt)
+
+    delta = stop - start
+    if num > 1:
+        step = delta / div
+        if step == 0:
+            # Special handling for denormal numbers, gh-5437
+            y /= div
+            y = y * delta
+        else:
+            # One might be tempted to use faster, in-place multiplication here,
+            # but this prevents step from overriding what class is produced,
+            # and thus prevents, e.g., use of Quantities; see gh-7142.
+            y = y * step
+    else:
+        # 0 and 1 item long sequences have an undefined step
+        step = NaN
+        # Multiply with delta to allow possible override of output class.
+        y = y * delta
+
+    y += start
+
+    if endpoint and num > 1:
+        y[-1] = stop
+
+    if retstep:
+        return y.astype(dtype, copy=False), step
+    else:
+        return y.astype(dtype, copy=False)
+
+
+def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None):
+    """
+    Return numbers spaced evenly on a log scale.
+
+    In linear space, the sequence starts at ``base ** start``
+    (`base` to the power of `start`) and ends with ``base ** stop``
+    (see `endpoint` below).
+
+    Parameters
+    ----------
+    start : float
+        ``base ** start`` is the starting value of the sequence.
+    stop : float
+        ``base ** stop`` is the final value of the sequence, unless `endpoint`
+        is False.  In that case, ``num + 1`` values are spaced over the
+        interval in log-space, of which all but the last (a sequence of
+        length ``num``) are returned.
+    num : integer, optional
+        Number of samples to generate.  Default is 50.
+    endpoint : boolean, optional
+        If true, `stop` is the last sample. Otherwise, it is not included.
+        Default is True.
+    base : float, optional
+        The base of the log space. The step size between the elements in
+        ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform.
+        Default is 10.0.
+    dtype : dtype
+        The type of the output array.  If `dtype` is not given, infer the data
+        type from the other input arguments.
+
+    Returns
+    -------
+    samples : ndarray
+        `num` samples, equally spaced on a log scale.
+
+    See Also
+    --------
+    arange : Similar to linspace, with the step size specified instead of the
+             number of samples. Note that, when used with a float endpoint, the
+             endpoint may or may not be included.
+    linspace : Similar to logspace, but with the samples uniformly distributed
+               in linear space, instead of log space.
+
+    Notes
+    -----
+    Logspace is equivalent to the code
+
+    >>> y = np.linspace(start, stop, num=num, endpoint=endpoint)
+    ... # doctest: +SKIP
+    >>> power(base, y).astype(dtype)
+    ... # doctest: +SKIP
+
+    Examples
+    --------
+    >>> np.logspace(2.0, 3.0, num=4)
+        array([  100.        ,   215.443469  ,   464.15888336,  1000.        ])
+    >>> np.logspace(2.0, 3.0, num=4, endpoint=False)
+        array([ 100.        ,  177.827941  ,  316.22776602,  562.34132519])
+    >>> np.logspace(2.0, 3.0, num=4, base=2.0)
+        array([ 4.        ,  5.0396842 ,  6.34960421,  8.        ])
+
+    Graphical illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> N = 10
+    >>> x1 = np.logspace(0.1, 1, N, endpoint=True)
+    >>> x2 = np.logspace(0.1, 1, N, endpoint=False)
+    >>> y = np.zeros(N)
+    >>> plt.plot(x1, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(x2, y + 0.5, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.ylim([-0.5, 1])
+    (-0.5, 1)
+    >>> plt.show()
+
+    """
+    y = linspace(start, stop, num=num, endpoint=endpoint)
+    if dtype is None:
+        return _nx.power(base, y)
+    return _nx.power(base, y).astype(dtype)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
new file mode 100644
index 0000000000..d376ffd292
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
@@ -0,0 +1,253 @@
+from __future__ import division, print_function
+
+import os
+import genapi
+
+from genapi import \
+        TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi
+
+import numpy_api
+
+# use annotated api when running under cpychecker
+h_template = r"""
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+%s
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+%s
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%%x but this version of numpy is 0x%%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%%x but this version of numpy is 0x%%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
+"""
+
+
+c_template = r"""
+/* These pointers will be stored in the C-object for use in other
+    extension modules
+*/
+
+void *PyArray_API[] = {
+%s
+};
+"""
+
+c_api_header = """
+===========
+Numpy C-API
+===========
+"""
+
+def generate_api(output_dir, force=False):
+    basename = 'multiarray_api'
+
+    h_file = os.path.join(output_dir, '__%s.h' % basename)
+    c_file = os.path.join(output_dir, '__%s.c' % basename)
+    d_file = os.path.join(output_dir, '%s.txt' % basename)
+    targets = (h_file, c_file, d_file)
+
+    sources = numpy_api.multiarray_api
+
+    if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):
+        return targets
+    else:
+        do_generate_api(targets, sources)
+
+    return targets
+
+def do_generate_api(targets, sources):
+    header_file = targets[0]
+    c_file = targets[1]
+    doc_file = targets[2]
+
+    global_vars = sources[0]
+    scalar_bool_values = sources[1]
+    types_api = sources[2]
+    multiarray_funcs = sources[3]
+
+    multiarray_api = sources[:]
+
+    module_list = []
+    extension_list = []
+    init_list = []
+
+    # Check multiarray api indexes
+    multiarray_api_index = genapi.merge_api_dicts(multiarray_api)
+    genapi.check_api_dict(multiarray_api_index)
+
+    numpyapi_list = genapi.get_api_functions('NUMPY_API',
+                                              multiarray_funcs)
+    ordered_funcs_api = genapi.order_dict(multiarray_funcs)
+
+    # Create dict name -> *Api instance
+    api_name = 'PyArray_API'
+    multiarray_api_dict = {}
+    for f in numpyapi_list:
+        name = f.name
+        index = multiarray_funcs[name][0]
+        annotations = multiarray_funcs[name][1:]
+        multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,
+                                                  f.return_type,
+                                                  f.args, api_name)
+
+    for name, val in global_vars.items():
+        index, type = val
+        multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)
+
+    for name, val in scalar_bool_values.items():
+        index = val[0]
+        multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)
+
+    for name, val in types_api.items():
+        index = val[0]
+        multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)
+
+    if len(multiarray_api_dict) != len(multiarray_api_index):
+        raise AssertionError("Multiarray API size mismatch %d %d" %
+                        (len(multiarray_api_dict), len(multiarray_api_index)))
+
+    extension_list = []
+    for name, index in genapi.order_dict(multiarray_api_index):
+        api_item = multiarray_api_dict[name]
+        extension_list.append(api_item.define_from_array_api_string())
+        init_list.append(api_item.array_api_define())
+        module_list.append(api_item.internal_define())
+
+    # Write to header
+    fid = open(header_file, 'w')
+    s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
+    fid.write(s)
+    fid.close()
+
+    # Write to c-code
+    fid = open(c_file, 'w')
+    s = c_template % ',\n'.join(init_list)
+    fid.write(s)
+    fid.close()
+
+    # write to documentation
+    fid = open(doc_file, 'w')
+    fid.write(c_api_header)
+    for func in numpyapi_list:
+        fid.write(func.to_ReST())
+        fid.write('\n\n')
+    fid.close()
+
+    return targets
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/getlimits.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/getlimits.py
new file mode 100644
index 0000000000..2ea9c0e11a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/getlimits.py
@@ -0,0 +1,308 @@
+"""Machine limits for Float32 and Float64 and (long double) if available...
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['finfo', 'iinfo']
+
+from .machar import MachAr
+from . import numeric
+from . import numerictypes as ntypes
+from .numeric import array
+
+def _frz(a):
+    """fix rank-0 --> rank-1"""
+    if a.ndim == 0:
+        a.shape = (1,)
+    return a
+
+_convert_to_float = {
+    ntypes.csingle: ntypes.single,
+    ntypes.complex_: ntypes.float_,
+    ntypes.clongfloat: ntypes.longfloat
+    }
+
+class finfo(object):
+    """
+    finfo(dtype)
+
+    Machine limits for floating point types.
+
+    Attributes
+    ----------
+    eps : float
+        The smallest representable positive number such that
+        ``1.0 + eps != 1.0``.  Type of `eps` is an appropriate floating
+        point type.
+    epsneg : floating point number of the appropriate type
+        The smallest representable positive number such that
+        ``1.0 - epsneg != 1.0``.
+    iexp : int
+        The number of bits in the exponent portion of the floating point
+        representation.
+    machar : MachAr
+        The object which calculated these parameters and holds more
+        detailed information.
+    machep : int
+        The exponent that yields `eps`.
+    max : floating point number of the appropriate type
+        The largest representable number.
+    maxexp : int
+        The smallest positive power of the base (2) that causes overflow.
+    min : floating point number of the appropriate type
+        The smallest representable number, typically ``-max``.
+    minexp : int
+        The most negative power of the base (2) consistent with there
+        being no leading 0's in the mantissa.
+    negep : int
+        The exponent that yields `epsneg`.
+    nexp : int
+        The number of bits in the exponent including its sign and bias.
+    nmant : int
+        The number of bits in the mantissa.
+    precision : int
+        The approximate number of decimal digits to which this kind of
+        float is precise.
+    resolution : floating point number of the appropriate type
+        The approximate decimal resolution of this type, i.e.,
+        ``10**-precision``.
+    tiny : float
+        The smallest positive usable number.  Type of `tiny` is an
+        appropriate floating point type.
+
+    Parameters
+    ----------
+    dtype : float, dtype, or instance
+        Kind of floating point data-type about which to get information.
+
+    See Also
+    --------
+    MachAr : The implementation of the tests that produce this information.
+    iinfo : The equivalent for integer data types.
+
+    Notes
+    -----
+    For developers of NumPy: do not instantiate this at the module level.
+    The initial calculation of these parameters is expensive and negatively
+    impacts import times.  These objects are cached, so calling ``finfo()``
+    repeatedly inside your functions is not a problem.
+
+    """
+
+    _finfo_cache = {}
+
+    def __new__(cls, dtype):
+        try:
+            dtype = numeric.dtype(dtype)
+        except TypeError:
+            # In case a float instance was given
+            dtype = numeric.dtype(type(dtype))
+
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        dtypes = [dtype]
+        newdtype = numeric.obj2sctype(dtype)
+        if newdtype is not dtype:
+            dtypes.append(newdtype)
+            dtype = newdtype
+        if not issubclass(dtype, numeric.inexact):
+            raise ValueError("data type %r not inexact" % (dtype))
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        if not issubclass(dtype, numeric.floating):
+            newdtype = _convert_to_float[dtype]
+            if newdtype is not dtype:
+                dtypes.append(newdtype)
+                dtype = newdtype
+        obj = cls._finfo_cache.get(dtype, None)
+        if obj is not None:
+            return obj
+        obj = object.__new__(cls)._init(dtype)
+        for dt in dtypes:
+            cls._finfo_cache[dt] = obj
+        return obj
+
+    def _init(self, dtype):
+        self.dtype = numeric.dtype(dtype)
+        if dtype is ntypes.double:
+            itype = ntypes.int64
+            fmt = '%24.16e'
+            precname = 'double'
+        elif dtype is ntypes.single:
+            itype = ntypes.int32
+            fmt = '%15.7e'
+            precname = 'single'
+        elif dtype is ntypes.longdouble:
+            itype = ntypes.longlong
+            fmt = '%s'
+            precname = 'long double'
+        elif dtype is ntypes.half:
+            itype = ntypes.int16
+            fmt = '%12.5e'
+            precname = 'half'
+        else:
+            raise ValueError(repr(dtype))
+
+        machar = MachAr(lambda v:array([v], dtype),
+                        lambda v:_frz(v.astype(itype))[0],
+                        lambda v:array(_frz(v)[0], dtype),
+                        lambda v: fmt % array(_frz(v)[0], dtype),
+                        'numpy %s precision floating point number' % precname)
+
+        for word in ['precision', 'iexp',
+                     'maxexp', 'minexp', 'negep',
+                     'machep']:
+            setattr(self, word, getattr(machar, word))
+        for word in ['tiny', 'resolution', 'epsneg']:
+            setattr(self, word, getattr(machar, word).flat[0])
+        self.max = machar.huge.flat[0]
+        self.min = -self.max
+        self.eps = machar.eps.flat[0]
+        self.nexp = machar.iexp
+        self.nmant = machar.it
+        self.machar = machar
+        self._str_tiny = machar._str_xmin.strip()
+        self._str_max = machar._str_xmax.strip()
+        self._str_epsneg = machar._str_epsneg.strip()
+        self._str_eps = machar._str_eps.strip()
+        self._str_resolution = machar._str_resolution.strip()
+        return self
+
+    def __str__(self):
+        fmt = (
+            'Machine parameters for %(dtype)s\n'
+            '---------------------------------------------------------------\n'
+            'precision=%(precision)3s   resolution= %(_str_resolution)s\n'
+            'machep=%(machep)6s   eps=        %(_str_eps)s\n'
+            'negep =%(negep)6s   epsneg=     %(_str_epsneg)s\n'
+            'minexp=%(minexp)6s   tiny=       %(_str_tiny)s\n'
+            'maxexp=%(maxexp)6s   max=        %(_str_max)s\n'
+            'nexp  =%(nexp)6s   min=        -max\n'
+            '---------------------------------------------------------------\n'
+            )
+        return fmt % self.__dict__
+
+    def __repr__(self):
+        c = self.__class__.__name__
+        d = self.__dict__.copy()
+        d['klass'] = c
+        return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s,"
+                 " max=%(_str_max)s, dtype=%(dtype)s)") % d)
+
+
+class iinfo(object):
+    """
+    iinfo(type)
+
+    Machine limits for integer types.
+
+    Attributes
+    ----------
+    min : int
+        The smallest integer expressible by the type.
+    max : int
+        The largest integer expressible by the type.
+
+    Parameters
+    ----------
+    int_type : integer type, dtype, or instance
+        The kind of integer data type to get information about.
+
+    See Also
+    --------
+    finfo : The equivalent for floating point data types.
+
+    Examples
+    --------
+    With types:
+
+    >>> ii16 = np.iinfo(np.int16)
+    >>> ii16.min
+    -32768
+    >>> ii16.max
+    32767
+    >>> ii32 = np.iinfo(np.int32)
+    >>> ii32.min
+    -2147483648
+    >>> ii32.max
+    2147483647
+
+    With instances:
+
+    >>> ii32 = np.iinfo(np.int32(10))
+    >>> ii32.min
+    -2147483648
+    >>> ii32.max
+    2147483647
+
+    """
+
+    _min_vals = {}
+    _max_vals = {}
+
+    def __init__(self, int_type):
+        try:
+            self.dtype = numeric.dtype(int_type)
+        except TypeError:
+            self.dtype = numeric.dtype(type(int_type))
+        self.kind = self.dtype.kind
+        self.bits = self.dtype.itemsize * 8
+        self.key = "%s%d" % (self.kind, self.bits)
+        if self.kind not in 'iu':
+            raise ValueError("Invalid integer data type.")
+
+    def min(self):
+        """Minimum value of given dtype."""
+        if self.kind == 'u':
+            return 0
+        else:
+            try:
+                val = iinfo._min_vals[self.key]
+            except KeyError:
+                val = int(-(1 << (self.bits-1)))
+                iinfo._min_vals[self.key] = val
+            return val
+
+    min = property(min)
+
+    def max(self):
+        """Maximum value of given dtype."""
+        try:
+            val = iinfo._max_vals[self.key]
+        except KeyError:
+            if self.kind == 'u':
+                val = int((1 << self.bits) - 1)
+            else:
+                val = int((1 << (self.bits-1)) - 1)
+            iinfo._max_vals[self.key] = val
+        return val
+
+    max = property(max)
+
+    def __str__(self):
+        """String representation."""
+        fmt = (
+            'Machine parameters for %(dtype)s\n'
+            '---------------------------------------------------------------\n'
+            'min = %(min)s\n'
+            'max = %(max)s\n'
+            '---------------------------------------------------------------\n'
+            )
+        return fmt % {'dtype': self.dtype, 'min': self.min, 'max': self.max}
+
+    def __repr__(self):
+        return "%s(min=%s, max=%s, dtype=%s)" % (self.__class__.__name__,
+                                    self.min, self.max, self.dtype)
+
+if __name__ == '__main__':
+    f = finfo(ntypes.single)
+    print('single epsilon:', f.eps)
+    print('single tiny:', f.tiny)
+    f = finfo(ntypes.float)
+    print('float epsilon:', f.eps)
+    print('float tiny:', f.tiny)
+    f = finfo(ntypes.longfloat)
+    print('longfloat epsilon:', f.eps)
+    print('longfloat tiny:', f.tiny)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
new file mode 100644
index 0000000000..aefb9de029
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
@@ -0,0 +1,1540 @@
+
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCVersion \
+       (void);
+extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArray_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type;
+
+extern NPY_NO_EXPORT int NPY_NUMUSERTYPES;
+
+extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type;
+
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type;
+
+NPY_NO_EXPORT  int PyArray_SetNumericOps \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_GetNumericOps \
+       (void);
+NPY_NO_EXPORT  int PyArray_INCREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_XDECREF \
+       (PyArrayObject *);
+NPY_NO_EXPORT  void PyArray_SetStringFunction \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromType \
+       (int);
+NPY_NO_EXPORT  PyObject * PyArray_TypeObjectFromType \
+       (int);
+NPY_NO_EXPORT  char * PyArray_Zero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  char * PyArray_One \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_CastTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CastAnyTo \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CanCastSafely \
+       (int, int);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTo \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_ObjectType \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromObject \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArrayObject ** PyArray_ConvertToCommonType \
+       (PyObject *, int *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromScalar \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrFromTypeObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_Size \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Scalar \
+       (void *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \
+       (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_ScalarAsCtype \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_CastScalarToCtype \
+       (PyObject *, void *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_CastScalarDirect \
+       (PyObject *, PyArray_Descr *, void *, int);
+NPY_NO_EXPORT  PyObject * PyArray_ScalarFromObject \
+       (PyObject *);
+NPY_NO_EXPORT  PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+       (PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromDims \
+       (int, int *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \
+       (int, int *, PyArray_Descr *, char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \
+       (PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromFile \
+       (FILE *, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromString \
+       (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT  PyObject * PyArray_FromBuffer \
+       (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \
+       (PyObject *, PyArray_Descr *, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \
+       (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Byteswap \
+       (PyArrayObject *, npy_bool);
+NPY_NO_EXPORT  PyObject * PyArray_Resize \
+       (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_MoveInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyAnyInto \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_CopyObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_ToList \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ToString \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  int PyArray_ToFile \
+       (PyArrayObject *, FILE *, char *, char *);
+NPY_NO_EXPORT  int PyArray_Dump \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Dumps \
+       (PyObject *, int);
+NPY_NO_EXPORT  int PyArray_ValidType \
+       (int);
+NPY_NO_EXPORT  void PyArray_UpdateFlags \
+       (PyArrayObject *, int);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \
+       (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \
+       (PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNew \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewFromType \
+       (int);
+NPY_NO_EXPORT  double PyArray_GetPriority \
+       (PyObject *, double);
+NPY_NO_EXPORT  PyObject * PyArray_IterNew \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterNew \
+       (int, ...);
+NPY_NO_EXPORT  int PyArray_PyIntAsInt \
+       (PyObject *);
+NPY_NO_EXPORT  npy_intp PyArray_PyIntAsIntp \
+       (PyObject *);
+NPY_NO_EXPORT  int PyArray_Broadcast \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  void PyArray_FillObjectArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  int PyArray_FillWithScalar \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CheckStrides \
+       (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_DescrNewByteorder \
+       (PyArray_Descr *, char);
+NPY_NO_EXPORT  PyObject * PyArray_IterAllButAxis \
+       (PyObject *, int *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \
+       (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_FromInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromStructInterface \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_FromArrayAttr \
+       (PyObject *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT  NPY_SCALARKIND PyArray_ScalarKind \
+       (int, PyArrayObject **);
+NPY_NO_EXPORT  int PyArray_CanCoerceScalar \
+       (int, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  PyObject * PyArray_NewFlagsObject \
+       (PyObject *);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastScalar \
+       (PyTypeObject *, PyTypeObject *);
+NPY_NO_EXPORT  int PyArray_CompareUCS4 \
+       (npy_ucs4 *, npy_ucs4 *, size_t);
+NPY_NO_EXPORT  int PyArray_RemoveSmallest \
+       (PyArrayMultiIterObject *);
+NPY_NO_EXPORT  int PyArray_ElementStrides \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_Item_INCREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  void PyArray_Item_XDECREF \
+       (char *, PyArray_Descr *);
+NPY_NO_EXPORT  PyObject * PyArray_FieldNames \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Transpose \
+       (PyArrayObject *, PyArray_Dims *);
+NPY_NO_EXPORT  PyObject * PyArray_TakeFrom \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutTo \
+       (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  PyObject * PyArray_PutMask \
+       (PyArrayObject *, PyObject*, PyObject*);
+NPY_NO_EXPORT  PyObject * PyArray_Repeat \
+       (PyArrayObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Choose \
+       (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT  int PyArray_Sort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgSort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_SearchSorted \
+       (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMax \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_ArgMin \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Reshape \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Newshape \
+       (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Squeeze \
+       (PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \
+       (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+NPY_NO_EXPORT  PyObject * PyArray_SwapAxes \
+       (PyArrayObject *, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Max \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Min \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Ptp \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Mean \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Trace \
+       (PyArrayObject *, int, int, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Diagonal \
+       (PyArrayObject *, int, int, int);
+NPY_NO_EXPORT  PyObject * PyArray_Clip \
+       (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Conjugate \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Nonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Std \
+       (PyArrayObject *, int, int, PyArrayObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Sum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumSum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Prod \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CumProd \
+       (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_All \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Any \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Compress \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Flatten \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  PyObject * PyArray_Ravel \
+       (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT  npy_intp PyArray_MultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_MultiplyIntList \
+       (int *, int);
+NPY_NO_EXPORT  void * PyArray_GetPtr \
+       (PyArrayObject *, npy_intp*);
+NPY_NO_EXPORT  int PyArray_CompareLists \
+       (npy_intp *, npy_intp *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \
+       (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+NPY_NO_EXPORT  int PyArray_As1D \
+       (PyObject **, char **, int *, int);
+NPY_NO_EXPORT  int PyArray_As2D \
+       (PyObject **, char ***, int *, int *, int);
+NPY_NO_EXPORT  int PyArray_Free \
+       (PyObject *, void *);
+NPY_NO_EXPORT  int PyArray_Converter \
+       (PyObject *, PyObject **);
+NPY_NO_EXPORT  int PyArray_IntpFromSequence \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Concatenate \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_InnerProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct \
+       (PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_CopyAndTranspose \
+       (PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  int PyArray_TypestrConvert \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_DescrConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_IntpConverter \
+       (PyObject *, PyArray_Dims *);
+NPY_NO_EXPORT  int PyArray_BufferConverter \
+       (PyObject *, PyArray_Chunk *);
+NPY_NO_EXPORT  int PyArray_AxisConverter \
+       (PyObject *, int *);
+NPY_NO_EXPORT  int PyArray_BoolConverter \
+       (PyObject *, npy_bool *);
+NPY_NO_EXPORT  int PyArray_ByteorderConverter \
+       (PyObject *, char *);
+NPY_NO_EXPORT  int PyArray_OrderConverter \
+       (PyObject *, NPY_ORDER *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \
+       (int, npy_intp *, PyArray_Descr *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Where \
+       (PyObject *, PyObject *, PyObject *);
+NPY_NO_EXPORT  PyObject * PyArray_Arange \
+       (double, double, double, int);
+NPY_NO_EXPORT  PyObject * PyArray_ArangeObj \
+       (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_SortkindConverter \
+       (PyObject *, NPY_SORTKIND *);
+NPY_NO_EXPORT  PyObject * PyArray_LexSort \
+       (PyObject *, int);
+NPY_NO_EXPORT  PyObject * PyArray_Round \
+       (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT  unsigned char PyArray_EquivTypenums \
+       (int, int);
+NPY_NO_EXPORT  int PyArray_RegisterDataType \
+       (PyArray_Descr *);
+NPY_NO_EXPORT  int PyArray_RegisterCastFunc \
+       (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+NPY_NO_EXPORT  int PyArray_RegisterCanCast \
+       (PyArray_Descr *, int, NPY_SCALARKIND);
+NPY_NO_EXPORT  void PyArray_InitArrFuncs \
+       (PyArray_ArrFuncs *);
+NPY_NO_EXPORT  PyObject * PyArray_IntTupleFromIntp \
+       (int, npy_intp *);
+NPY_NO_EXPORT  int PyArray_TypeNumFromName \
+       (char *);
+NPY_NO_EXPORT  int PyArray_ClipmodeConverter \
+       (PyObject *, NPY_CLIPMODE *);
+NPY_NO_EXPORT  int PyArray_OutputConverter \
+       (PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  PyObject * PyArray_BroadcastToShape \
+       (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT  void _PyArray_SigintHandler \
+       (int);
+NPY_NO_EXPORT  void* _PyArray_GetSigintBuf \
+       (void);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_DescrAlignConverter2 \
+       (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyArray_SearchsideConverter \
+       (PyObject *, void *);
+NPY_NO_EXPORT  PyObject * PyArray_CheckAxis \
+       (PyArrayObject *, int *, int);
+NPY_NO_EXPORT  npy_intp PyArray_OverflowMultiplyList \
+       (npy_intp *, int);
+NPY_NO_EXPORT  int PyArray_CompareString \
+       (char *, char *, size_t);
+NPY_NO_EXPORT  PyObject * PyArray_MultiIterFromObjects \
+       (PyObject **, int, int, ...);
+NPY_NO_EXPORT  int PyArray_GetEndianness \
+       (void);
+NPY_NO_EXPORT  unsigned int PyArray_GetNDArrayCFeatureVersion \
+       (void);
+NPY_NO_EXPORT  PyObject * PyArray_Correlate2 \
+       (PyObject *, PyObject *, int);
+NPY_NO_EXPORT  PyObject* PyArray_NeighborhoodIterNew \
+       (PyArrayIterObject *, npy_intp *, int, PyArrayObject*);
+extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type;
+
+extern NPY_NO_EXPORT PyTypeObject NpyIter_Type;
+
+NPY_NO_EXPORT  void PyArray_SetDatetimeParseFunction \
+       (PyObject *);
+NPY_NO_EXPORT  void PyArray_DatetimeToDatetimeStruct \
+       (npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  void PyArray_TimedeltaToTimedeltaStruct \
+       (npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_DatetimeStructToDatetime \
+       (NPY_DATETIMEUNIT, npy_datetimestruct *);
+NPY_NO_EXPORT  npy_datetime PyArray_TimedeltaStructToTimedelta \
+       (NPY_DATETIMEUNIT, npy_timedeltastruct *);
+NPY_NO_EXPORT  NpyIter * NpyIter_New \
+       (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*);
+NPY_NO_EXPORT  NpyIter * NpyIter_MultiNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **);
+NPY_NO_EXPORT  NpyIter * NpyIter_AdvancedNew \
+       (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp);
+NPY_NO_EXPORT  NpyIter * NpyIter_Copy \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Deallocate \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasDelayedBufAlloc \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_EnableExternalLoop \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerStrideArray \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetInnerLoopSizePtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_Reset \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_ResetBasePointers \
+       (NpyIter *, char **, char **);
+NPY_NO_EXPORT  int NpyIter_ResetToIterIndexRange \
+       (NpyIter *, npy_intp, npy_intp, char **);
+NPY_NO_EXPORT  int NpyIter_GetNDim \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetNOp \
+       (NpyIter *);
+NPY_NO_EXPORT  NpyIter_IterNextFunc * NpyIter_GetIterNext \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterSize \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetIterIndexRange \
+       (NpyIter *, npy_intp *, npy_intp *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetIterIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIterIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  npy_bool NpyIter_HasMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GetShape \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \
+       (NpyIter *, char **);
+NPY_NO_EXPORT  int NpyIter_GotoMultiIndex \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveMultiIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_HasIndex \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsBuffered \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IsGrowInner \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp NpyIter_GetBufferSize \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetIndexPtr \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_GotoIndex \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  char ** NpyIter_GetDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArray_Descr ** NpyIter_GetDescrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject ** NpyIter_GetOperandArray \
+       (NpyIter *);
+NPY_NO_EXPORT  PyArrayObject * NpyIter_GetIterView \
+       (NpyIter *, npy_intp);
+NPY_NO_EXPORT  void NpyIter_GetReadFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_GetWriteFlags \
+       (NpyIter *, char *);
+NPY_NO_EXPORT  void NpyIter_DebugPrint \
+       (NpyIter *);
+NPY_NO_EXPORT  npy_bool NpyIter_IterationNeedsAPI \
+       (NpyIter *);
+NPY_NO_EXPORT  void NpyIter_GetInnerFixedStrideArray \
+       (NpyIter *, npy_intp *);
+NPY_NO_EXPORT  int NpyIter_RemoveAxis \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_intp * NpyIter_GetAxisStrideArray \
+       (NpyIter *, int);
+NPY_NO_EXPORT  npy_bool NpyIter_RequiresBuffering \
+       (NpyIter *);
+NPY_NO_EXPORT  char ** NpyIter_GetInitialDataPtrArray \
+       (NpyIter *);
+NPY_NO_EXPORT  int NpyIter_CreateCompatibleStrides \
+       (NpyIter *, npy_intp, npy_intp *);
+NPY_NO_EXPORT  int PyArray_CastingConverter \
+       (PyObject *, NPY_CASTING *);
+NPY_NO_EXPORT  npy_intp PyArray_CountNonzero \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_PromoteTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_MinScalarType \
+       (PyArrayObject *);
+NPY_NO_EXPORT  PyArray_Descr * PyArray_ResultType \
+       (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastArrayTo \
+       (PyArrayObject *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  npy_bool PyArray_CanCastTypeTo \
+       (PyArray_Descr *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT  PyArrayObject * PyArray_EinsteinSum \
+       (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \
+       (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int);
+NPY_NO_EXPORT  int PyArray_GetArrayParamsFromObject \
+       (PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *);
+NPY_NO_EXPORT  int PyArray_ConvertClipmodeSequence \
+       (PyObject *, NPY_CLIPMODE *, int);
+NPY_NO_EXPORT  PyObject * PyArray_MatrixProduct2 \
+       (PyObject *, PyObject *, PyArrayObject*);
+NPY_NO_EXPORT  npy_bool NpyIter_IsFirstVisit \
+       (NpyIter *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_CreateSortedStridePerm \
+       (int, npy_intp *, npy_stride_sort_item *);
+NPY_NO_EXPORT  void PyArray_RemoveAxesInPlace \
+       (PyArrayObject *, npy_bool *);
+NPY_NO_EXPORT  void PyArray_DebugPrint \
+       (PyArrayObject *);
+NPY_NO_EXPORT  int PyArray_FailUnlessWriteable \
+       (PyArrayObject *, const char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \
+       (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT  void * PyDataMem_NEW \
+       (size_t);
+NPY_NO_EXPORT  void PyDataMem_FREE \
+       (void *);
+NPY_NO_EXPORT  void * PyDataMem_RENEW \
+       (void *, size_t);
+NPY_NO_EXPORT  PyDataMem_EventHookFunc * PyDataMem_SetEventHook \
+       (PyDataMem_EventHookFunc *, void *, void **);
+extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING;
+
+NPY_NO_EXPORT  void PyArray_MapIterSwapAxes \
+       (PyArrayMapIterObject *, PyArrayObject **, int);
+NPY_NO_EXPORT  PyObject * PyArray_MapIterArray \
+       (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT  void PyArray_MapIterNext \
+       (PyArrayMapIterObject *);
+NPY_NO_EXPORT  int PyArray_Partition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  PyObject * PyArray_ArgPartition \
+       (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT  int PyArray_SelectkindConverter \
+       (PyObject *, NPY_SELECTKIND *);
+NPY_NO_EXPORT  void * PyDataMem_NEW_ZEROED \
+       (size_t, size_t);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \
+       (PyObject *);
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+#define PyArray_GetNDArrayCVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[40])
+#define PyArray_GetNumericOps \
+        (*(PyObject * (*)(void)) \
+         PyArray_API[41])
+#define PyArray_INCREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[42])
+#define PyArray_XDECREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[43])
+#define PyArray_SetStringFunction \
+        (*(void (*)(PyObject *, int)) \
+         PyArray_API[44])
+#define PyArray_DescrFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+        (*(PyObject * (*)(int)) \
+         PyArray_API[46])
+#define PyArray_Zero \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[47])
+#define PyArray_One \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[48])
+#define PyArray_CastToType \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[49])
+#define PyArray_CastTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[50])
+#define PyArray_CastAnyTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[51])
+#define PyArray_CanCastSafely \
+        (*(int (*)(int, int)) \
+         PyArray_API[52])
+#define PyArray_CanCastTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[53])
+#define PyArray_ObjectType \
+        (*(int (*)(PyObject *, int)) \
+         PyArray_API[54])
+#define PyArray_DescrFromObject \
+        (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+        (*(PyArrayObject ** (*)(PyObject *, int *)) \
+         PyArray_API[56])
+#define PyArray_DescrFromScalar \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[58])
+#define PyArray_Size \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[59])
+#define PyArray_Scalar \
+        (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[60])
+#define PyArray_FromScalar \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+        (*(void (*)(PyObject *, void *)) \
+         PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+        (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+         PyArray_API[63])
+#define PyArray_CastScalarDirect \
+        (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+         PyArray_API[64])
+#define PyArray_ScalarFromObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[65])
+#define PyArray_GetCastFunc \
+        (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+         PyArray_API[66])
+#define PyArray_FromDims \
+        (*(PyObject * (*)(int, int *, int)) \
+         PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+        (*(PyObject * (*)(int, int *, PyArray_Descr *, char *)) \
+         PyArray_API[68])
+#define PyArray_FromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[69])
+#define PyArray_EnsureArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[71])
+#define PyArray_FromFile \
+        (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[72])
+#define PyArray_FromString \
+        (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[73])
+#define PyArray_FromBuffer \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+         PyArray_API[74])
+#define PyArray_FromIter \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+         PyArray_API[75])
+#define PyArray_Return \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[76])
+#define PyArray_GetField \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[77])
+#define PyArray_SetField \
+        (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+         PyArray_API[78])
+#define PyArray_Byteswap \
+        (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+         PyArray_API[79])
+#define PyArray_Resize \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER)) \
+         PyArray_API[80])
+#define PyArray_MoveInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[81])
+#define PyArray_CopyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[82])
+#define PyArray_CopyAnyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[83])
+#define PyArray_CopyObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[84])
+#define PyArray_NewCopy \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[85])
+#define PyArray_ToList \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[86])
+#define PyArray_ToString \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[87])
+#define PyArray_ToFile \
+        (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+         PyArray_API[88])
+#define PyArray_Dump \
+        (*(int (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[89])
+#define PyArray_Dumps \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[90])
+#define PyArray_ValidType \
+        (*(int (*)(int)) \
+         PyArray_API[91])
+#define PyArray_UpdateFlags \
+        (*(void (*)(PyArrayObject *, int)) \
+         PyArray_API[92])
+#define PyArray_New \
+        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
+         PyArray_API[93])
+#define PyArray_NewFromDescr \
+        (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *)) \
+         PyArray_API[94])
+#define PyArray_DescrNew \
+        (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+         PyArray_API[95])
+#define PyArray_DescrNewFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[96])
+#define PyArray_GetPriority \
+        (*(double (*)(PyObject *, double)) \
+         PyArray_API[97])
+#define PyArray_IterNew \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[98])
+#define PyArray_MultiIterNew \
+        (*(PyObject * (*)(int, ...)) \
+         PyArray_API[99])
+#define PyArray_PyIntAsInt \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[101])
+#define PyArray_Broadcast \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[102])
+#define PyArray_FillObjectArray \
+        (*(void (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[103])
+#define PyArray_FillWithScalar \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[104])
+#define PyArray_CheckStrides \
+        (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)) \
+         PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+         PyArray_API[106])
+#define PyArray_IterAllButAxis \
+        (*(PyObject * (*)(PyObject *, int *)) \
+         PyArray_API[107])
+#define PyArray_CheckFromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[108])
+#define PyArray_FromArray \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[109])
+#define PyArray_FromInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[110])
+#define PyArray_FromStructInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[111])
+#define PyArray_FromArrayAttr \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[112])
+#define PyArray_ScalarKind \
+        (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+         PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+        (*(int (*)(int, int, NPY_SCALARKIND)) \
+         PyArray_API[114])
+#define PyArray_NewFlagsObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[115])
+#define PyArray_CanCastScalar \
+        (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+         PyArray_API[116])
+#define PyArray_CompareUCS4 \
+        (*(int (*)(npy_ucs4 *, npy_ucs4 *, size_t)) \
+         PyArray_API[117])
+#define PyArray_RemoveSmallest \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[118])
+#define PyArray_ElementStrides \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[119])
+#define PyArray_Item_INCREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[120])
+#define PyArray_Item_XDECREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[121])
+#define PyArray_FieldNames \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[122])
+#define PyArray_Transpose \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+         PyArray_API[123])
+#define PyArray_TakeFrom \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[124])
+#define PyArray_PutTo \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+         PyArray_API[125])
+#define PyArray_PutMask \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+         PyArray_API[126])
+#define PyArray_Repeat \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+         PyArray_API[127])
+#define PyArray_Choose \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[128])
+#define PyArray_Sort \
+        (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[129])
+#define PyArray_ArgSort \
+        (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[130])
+#define PyArray_SearchSorted \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \
+         PyArray_API[131])
+#define PyArray_ArgMax \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[132])
+#define PyArray_ArgMin \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[133])
+#define PyArray_Reshape \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[134])
+#define PyArray_Newshape \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+         PyArray_API[135])
+#define PyArray_Squeeze \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[136])
+#define PyArray_View \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+         PyArray_API[137])
+#define PyArray_SwapAxes \
+        (*(PyObject * (*)(PyArrayObject *, int, int)) \
+         PyArray_API[138])
+#define PyArray_Max \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[139])
+#define PyArray_Min \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[140])
+#define PyArray_Ptp \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[141])
+#define PyArray_Mean \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[142])
+#define PyArray_Trace \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+         PyArray_API[143])
+#define PyArray_Diagonal \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+         PyArray_API[144])
+#define PyArray_Clip \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+         PyArray_API[145])
+#define PyArray_Conjugate \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[146])
+#define PyArray_Nonzero \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[147])
+#define PyArray_Std \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+         PyArray_API[148])
+#define PyArray_Sum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[149])
+#define PyArray_CumSum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[150])
+#define PyArray_Prod \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[151])
+#define PyArray_CumProd \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[152])
+#define PyArray_All \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[153])
+#define PyArray_Any \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[154])
+#define PyArray_Compress \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+         PyArray_API[155])
+#define PyArray_Flatten \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[156])
+#define PyArray_Ravel \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[157])
+#define PyArray_MultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[158])
+#define PyArray_MultiplyIntList \
+        (*(int (*)(int *, int)) \
+         PyArray_API[159])
+#define PyArray_GetPtr \
+        (*(void * (*)(PyArrayObject *, npy_intp*)) \
+         PyArray_API[160])
+#define PyArray_CompareLists \
+        (*(int (*)(npy_intp *, npy_intp *, int)) \
+         PyArray_API[161])
+#define PyArray_AsCArray \
+        (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+         PyArray_API[162])
+#define PyArray_As1D \
+        (*(int (*)(PyObject **, char **, int *, int)) \
+         PyArray_API[163])
+#define PyArray_As2D \
+        (*(int (*)(PyObject **, char ***, int *, int *, int)) \
+         PyArray_API[164])
+#define PyArray_Free \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[165])
+#define PyArray_Converter \
+        (*(int (*)(PyObject *, PyObject **)) \
+         PyArray_API[166])
+#define PyArray_IntpFromSequence \
+        (*(int (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[167])
+#define PyArray_Concatenate \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[168])
+#define PyArray_InnerProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[169])
+#define PyArray_MatrixProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[171])
+#define PyArray_Correlate \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[172])
+#define PyArray_TypestrConvert \
+        (*(int (*)(int, int)) \
+         PyArray_API[173])
+#define PyArray_DescrConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[174])
+#define PyArray_DescrConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[175])
+#define PyArray_IntpConverter \
+        (*(int (*)(PyObject *, PyArray_Dims *)) \
+         PyArray_API[176])
+#define PyArray_BufferConverter \
+        (*(int (*)(PyObject *, PyArray_Chunk *)) \
+         PyArray_API[177])
+#define PyArray_AxisConverter \
+        (*(int (*)(PyObject *, int *)) \
+         PyArray_API[178])
+#define PyArray_BoolConverter \
+        (*(int (*)(PyObject *, npy_bool *)) \
+         PyArray_API[179])
+#define PyArray_ByteorderConverter \
+        (*(int (*)(PyObject *, char *)) \
+         PyArray_API[180])
+#define PyArray_OrderConverter \
+        (*(int (*)(PyObject *, NPY_ORDER *)) \
+         PyArray_API[181])
+#define PyArray_EquivTypes \
+        (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[182])
+#define PyArray_Zeros \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[183])
+#define PyArray_Empty \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[184])
+#define PyArray_Where \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+         PyArray_API[185])
+#define PyArray_Arange \
+        (*(PyObject * (*)(double, double, double, int)) \
+         PyArray_API[186])
+#define PyArray_ArangeObj \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+         PyArray_API[187])
+#define PyArray_SortkindConverter \
+        (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+         PyArray_API[188])
+#define PyArray_LexSort \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[189])
+#define PyArray_Round \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[190])
+#define PyArray_EquivTypenums \
+        (*(unsigned char (*)(int, int)) \
+         PyArray_API[191])
+#define PyArray_RegisterDataType \
+        (*(int (*)(PyArray_Descr *)) \
+         PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+        (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+         PyArray_API[193])
+#define PyArray_RegisterCanCast \
+        (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+         PyArray_API[194])
+#define PyArray_InitArrFuncs \
+        (*(void (*)(PyArray_ArrFuncs *)) \
+         PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+        (*(PyObject * (*)(int, npy_intp *)) \
+         PyArray_API[196])
+#define PyArray_TypeNumFromName \
+        (*(int (*)(char *)) \
+         PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+         PyArray_API[198])
+#define PyArray_OutputConverter \
+        (*(int (*)(PyObject *, PyArrayObject **)) \
+         PyArray_API[199])
+#define PyArray_BroadcastToShape \
+        (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[200])
+#define _PyArray_SigintHandler \
+        (*(void (*)(int)) \
+         PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+        (*(void* (*)(void)) \
+         PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[204])
+#define PyArray_SearchsideConverter \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[205])
+#define PyArray_CheckAxis \
+        (*(PyObject * (*)(PyArrayObject *, int *, int)) \
+         PyArray_API[206])
+#define PyArray_OverflowMultiplyList \
+        (*(npy_intp (*)(npy_intp *, int)) \
+         PyArray_API[207])
+#define PyArray_CompareString \
+        (*(int (*)(char *, char *, size_t)) \
+         PyArray_API[208])
+#define PyArray_MultiIterFromObjects \
+        (*(PyObject * (*)(PyObject **, int, int, ...)) \
+         PyArray_API[209])
+#define PyArray_GetEndianness \
+        (*(int (*)(void)) \
+         PyArray_API[210])
+#define PyArray_GetNDArrayCFeatureVersion \
+        (*(unsigned int (*)(void)) \
+         PyArray_API[211])
+#define PyArray_Correlate2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[212])
+#define PyArray_NeighborhoodIterNew \
+        (*(PyObject* (*)(PyArrayIterObject *, npy_intp *, int, PyArrayObject*)) \
+         PyArray_API[213])
+#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214])
+#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215])
+#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216])
+#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217])
+#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218])
+#define PyArray_SetDatetimeParseFunction \
+        (*(void (*)(PyObject *)) \
+         PyArray_API[219])
+#define PyArray_DatetimeToDatetimeStruct \
+        (*(void (*)(npy_datetime, NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[220])
+#define PyArray_TimedeltaToTimedeltaStruct \
+        (*(void (*)(npy_timedelta, NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[221])
+#define PyArray_DatetimeStructToDatetime \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_datetimestruct *)) \
+         PyArray_API[222])
+#define PyArray_TimedeltaStructToTimedelta \
+        (*(npy_datetime (*)(NPY_DATETIMEUNIT, npy_timedeltastruct *)) \
+         PyArray_API[223])
+#define NpyIter_New \
+        (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \
+         PyArray_API[224])
+#define NpyIter_MultiNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \
+         PyArray_API[225])
+#define NpyIter_AdvancedNew \
+        (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \
+         PyArray_API[226])
+#define NpyIter_Copy \
+        (*(NpyIter * (*)(NpyIter *)) \
+         PyArray_API[227])
+#define NpyIter_Deallocate \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[228])
+#define NpyIter_HasDelayedBufAlloc \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[229])
+#define NpyIter_HasExternalLoop \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[230])
+#define NpyIter_EnableExternalLoop \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[231])
+#define NpyIter_GetInnerStrideArray \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[232])
+#define NpyIter_GetInnerLoopSizePtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[233])
+#define NpyIter_Reset \
+        (*(int (*)(NpyIter *, char **)) \
+         PyArray_API[234])
+#define NpyIter_ResetBasePointers \
+        (*(int (*)(NpyIter *, char **, char **)) \
+         PyArray_API[235])
+#define NpyIter_ResetToIterIndexRange \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \
+         PyArray_API[236])
+#define NpyIter_GetNDim \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[237])
+#define NpyIter_GetNOp \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[238])
+#define NpyIter_GetIterNext \
+        (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[239])
+#define NpyIter_GetIterSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[240])
+#define NpyIter_GetIterIndexRange \
+        (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \
+         PyArray_API[241])
+#define NpyIter_GetIterIndex \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[242])
+#define NpyIter_GotoIterIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[243])
+#define NpyIter_HasMultiIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[244])
+#define NpyIter_GetShape \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[245])
+#define NpyIter_GetGetMultiIndex \
+        (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \
+         PyArray_API[246])
+#define NpyIter_GotoMultiIndex \
+        (*(int (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[247])
+#define NpyIter_RemoveMultiIndex \
+        (*(int (*)(NpyIter *)) \
+         PyArray_API[248])
+#define NpyIter_HasIndex \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[249])
+#define NpyIter_IsBuffered \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[250])
+#define NpyIter_IsGrowInner \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[251])
+#define NpyIter_GetBufferSize \
+        (*(npy_intp (*)(NpyIter *)) \
+         PyArray_API[252])
+#define NpyIter_GetIndexPtr \
+        (*(npy_intp * (*)(NpyIter *)) \
+         PyArray_API[253])
+#define NpyIter_GotoIndex \
+        (*(int (*)(NpyIter *, npy_intp)) \
+         PyArray_API[254])
+#define NpyIter_GetDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[255])
+#define NpyIter_GetDescrArray \
+        (*(PyArray_Descr ** (*)(NpyIter *)) \
+         PyArray_API[256])
+#define NpyIter_GetOperandArray \
+        (*(PyArrayObject ** (*)(NpyIter *)) \
+         PyArray_API[257])
+#define NpyIter_GetIterView \
+        (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \
+         PyArray_API[258])
+#define NpyIter_GetReadFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[259])
+#define NpyIter_GetWriteFlags \
+        (*(void (*)(NpyIter *, char *)) \
+         PyArray_API[260])
+#define NpyIter_DebugPrint \
+        (*(void (*)(NpyIter *)) \
+         PyArray_API[261])
+#define NpyIter_IterationNeedsAPI \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[262])
+#define NpyIter_GetInnerFixedStrideArray \
+        (*(void (*)(NpyIter *, npy_intp *)) \
+         PyArray_API[263])
+#define NpyIter_RemoveAxis \
+        (*(int (*)(NpyIter *, int)) \
+         PyArray_API[264])
+#define NpyIter_GetAxisStrideArray \
+        (*(npy_intp * (*)(NpyIter *, int)) \
+         PyArray_API[265])
+#define NpyIter_RequiresBuffering \
+        (*(npy_bool (*)(NpyIter *)) \
+         PyArray_API[266])
+#define NpyIter_GetInitialDataPtrArray \
+        (*(char ** (*)(NpyIter *)) \
+         PyArray_API[267])
+#define NpyIter_CreateCompatibleStrides \
+        (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \
+         PyArray_API[268])
+#define PyArray_CastingConverter \
+        (*(int (*)(PyObject *, NPY_CASTING *)) \
+         PyArray_API[269])
+#define PyArray_CountNonzero \
+        (*(npy_intp (*)(PyArrayObject *)) \
+         PyArray_API[270])
+#define PyArray_PromoteTypes \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[271])
+#define PyArray_MinScalarType \
+        (*(PyArray_Descr * (*)(PyArrayObject *)) \
+         PyArray_API[272])
+#define PyArray_ResultType \
+        (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \
+         PyArray_API[273])
+#define PyArray_CanCastArrayTo \
+        (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[274])
+#define PyArray_CanCastTypeTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \
+         PyArray_API[275])
+#define PyArray_EinsteinSum \
+        (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \
+         PyArray_API[276])
+#define PyArray_NewLikeArray \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \
+         PyArray_API[277])
+#define PyArray_GetArrayParamsFromObject \
+        (*(int (*)(PyObject *, PyArray_Descr *, npy_bool, PyArray_Descr **, int *, npy_intp *, PyArrayObject **, PyObject *)) \
+         PyArray_API[278])
+#define PyArray_ConvertClipmodeSequence \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \
+         PyArray_API[279])
+#define PyArray_MatrixProduct2 \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \
+         PyArray_API[280])
+#define NpyIter_IsFirstVisit \
+        (*(npy_bool (*)(NpyIter *, int)) \
+         PyArray_API[281])
+#define PyArray_SetBaseObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[282])
+#define PyArray_CreateSortedStridePerm \
+        (*(void (*)(int, npy_intp *, npy_stride_sort_item *)) \
+         PyArray_API[283])
+#define PyArray_RemoveAxesInPlace \
+        (*(void (*)(PyArrayObject *, npy_bool *)) \
+         PyArray_API[284])
+#define PyArray_DebugPrint \
+        (*(void (*)(PyArrayObject *)) \
+         PyArray_API[285])
+#define PyArray_FailUnlessWriteable \
+        (*(int (*)(PyArrayObject *, const char *)) \
+         PyArray_API[286])
+#define PyArray_SetUpdateIfCopyBase \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[287])
+#define PyDataMem_NEW \
+        (*(void * (*)(size_t)) \
+         PyArray_API[288])
+#define PyDataMem_FREE \
+        (*(void (*)(void *)) \
+         PyArray_API[289])
+#define PyDataMem_RENEW \
+        (*(void * (*)(void *, size_t)) \
+         PyArray_API[290])
+#define PyDataMem_SetEventHook \
+        (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \
+         PyArray_API[291])
+#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292])
+#define PyArray_MapIterSwapAxes \
+        (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \
+         PyArray_API[293])
+#define PyArray_MapIterArray \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[294])
+#define PyArray_MapIterNext \
+        (*(void (*)(PyArrayMapIterObject *)) \
+         PyArray_API[295])
+#define PyArray_Partition \
+        (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[296])
+#define PyArray_ArgPartition \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+         PyArray_API[297])
+#define PyArray_SelectkindConverter \
+        (*(int (*)(PyObject *, NPY_SELECTKIND *)) \
+         PyArray_API[298])
+#define PyDataMem_NEW_ZEROED \
+        (*(void * (*)(size_t, size_t)) \
+         PyArray_API[299])
+#define PyArray_CheckAnyScalarExact \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[300])
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  int st;
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyArray_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+      return -1;
+  }
+
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "ABI version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+      return -1;
+  }
+  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+             "API version 0x%x but this version of numpy is 0x%x", \
+             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+      return -1;
+  }
+
+  /*
+   * Perform runtime check of endianness and check it matches the one set by
+   * the headers (npy_endian.h) as a safeguard
+   */
+  st = PyArray_GetEndianness();
+  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+      return -1;
+  }
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+  if (st != NPY_CPU_BIG) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "big endian, but detected different endianness at runtime");
+      return -1;
+  }
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+  if (st != NPY_CPU_LITTLE) {
+      PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+             "little endian, but detected different endianness at runtime");
+      return -1;
+  }
+#endif
+
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_ARRAY_RETVAL NULL
+#else
+#define NUMPY_IMPORT_ARRAY_RETVAL
+#endif
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
new file mode 100644
index 0000000000..bad86bda54
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
@@ -0,0 +1,320 @@
+
+#ifdef _UMATHMODULE
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndData \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForType \
+       (PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *);
+NPY_NO_EXPORT  int PyUFunc_GenericFunction \
+       (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+NPY_NO_EXPORT  void PyUFunc_f_f_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_g_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F_As_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_F_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_G_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_gg_g \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F_As_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_FF_F \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_GG_G \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_O_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_OO_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_On_Om \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_GetPyValues \
+       (char *, int *, int *, PyObject **);
+NPY_NO_EXPORT  int PyUFunc_checkfperr \
+       (int, PyObject *, int *);
+NPY_NO_EXPORT  void PyUFunc_clearfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_getfperr \
+       (void);
+NPY_NO_EXPORT  int PyUFunc_handlefperr \
+       (int, PyObject *, int, int *);
+NPY_NO_EXPORT  int PyUFunc_ReplaceLoopBySignature \
+       (PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *);
+NPY_NO_EXPORT  PyObject * PyUFunc_FromFuncAndDataAndSignature \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *);
+NPY_NO_EXPORT  int PyUFunc_SetUsesArraysAsData \
+       (void **, size_t);
+NPY_NO_EXPORT  void PyUFunc_e_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_e_e_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  void PyUFunc_ee_e_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+NPY_NO_EXPORT  int PyUFunc_DefaultTypeResolver \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_ValidateCasting \
+       (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **);
+NPY_NO_EXPORT  int PyUFunc_RegisterLoopForDescr \
+       (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *);
+
+#else
+
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+#else
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+void **PyUFunc_API;
+#else
+static void **PyUFunc_API=NULL;
+#endif
+#endif
+
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+#define PyUFunc_FromFuncAndData \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \
+         PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+        (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *)) \
+         PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+        (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+         PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[4])
+#define PyUFunc_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[5])
+#define PyUFunc_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[6])
+#define PyUFunc_g_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[8])
+#define PyUFunc_F_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[9])
+#define PyUFunc_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[10])
+#define PyUFunc_G_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[11])
+#define PyUFunc_O_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[13])
+#define PyUFunc_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[14])
+#define PyUFunc_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[15])
+#define PyUFunc_gg_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[17])
+#define PyUFunc_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[18])
+#define PyUFunc_FF_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[19])
+#define PyUFunc_GG_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[20])
+#define PyUFunc_OO_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[23])
+#define PyUFunc_On_Om \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+        (*(int (*)(char *, int *, int *, PyObject **)) \
+         PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+        (*(int (*)(int, PyObject *, int *)) \
+         PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+        (*(void (*)(void)) \
+         PyUFunc_API[27])
+#define PyUFunc_getfperr \
+        (*(int (*)(void)) \
+         PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+        (*(int (*)(int, PyObject *, int, int *)) \
+         PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+        (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)) \
+         PyUFunc_API[30])
+#define PyUFunc_FromFuncAndDataAndSignature \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \
+         PyUFunc_API[31])
+#define PyUFunc_SetUsesArraysAsData \
+        (*(int (*)(void **, size_t)) \
+         PyUFunc_API[32])
+#define PyUFunc_e_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[33])
+#define PyUFunc_e_e_As_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[34])
+#define PyUFunc_e_e_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[35])
+#define PyUFunc_ee_e \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[36])
+#define PyUFunc_ee_e_As_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[37])
+#define PyUFunc_ee_e_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[38])
+#define PyUFunc_DefaultTypeResolver \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \
+         PyUFunc_API[39])
+#define PyUFunc_ValidateCasting \
+        (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \
+         PyUFunc_API[40])
+#define PyUFunc_RegisterLoopForDescr \
+        (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \
+         PyUFunc_API[41])
+
+static NPY_INLINE int
+_import_umath(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) {
+      PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import");
+      return -1;
+  }
+  c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+  Py_DECREF(numpy);
+  if (c_api == NULL) {
+      PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
+      return -1;
+  }
+
+#if PY_VERSION_HEX >= 0x03000000
+  if (!PyCapsule_CheckExact(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+#else
+  if (!PyCObject_Check(c_api)) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCObject object");
+      Py_DECREF(c_api);
+      return -1;
+  }
+  PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
+#endif
+  Py_DECREF(c_api);
+  if (PyUFunc_API == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
+      return -1;
+  }
+  return 0;
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#define NUMPY_IMPORT_UMATH_RETVAL NULL
+#else
+#define NUMPY_IMPORT_UMATH_RETVAL
+#endif
+
+#define import_umath() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return NUMPY_IMPORT_UMATH_RETVAL;\
+        }\
+    } while(0)
+
+#define import_umath1(ret) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_umath2(ret, msg) \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError, msg);\
+            return ret;\
+        }\
+    } while(0)
+
+#define import_ufunc() \
+    do {\
+        UFUNC_NOFPE\
+        if (_import_umath() < 0) {\
+            PyErr_Print();\
+            PyErr_SetString(PyExc_ImportError,\
+                    "numpy.core.umath failed to import");\
+        }\
+    } while(0)
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
new file mode 100644
index 0000000000..e8860cbc73
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
@@ -0,0 +1,90 @@
+#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#error You should not include this header directly
+#endif
+/*
+ * Private API (here for inline)
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter);
+
+/*
+ * Update to next item of the iterator
+ *
+ * Note: this simply increment the coordinates vector, last dimension
+ * incremented first , i.e, for dimension 3
+ * ...
+ * -1, -1, -1
+ * -1, -1,  0
+ * -1, -1,  1
+ *  ....
+ * -1,  0, -1
+ * -1,  0,  0
+ *  ....
+ * 0,  -1, -1
+ * 0,  -1,  0
+ *  ....
+ */
+#define _UPDATE_COORD_ITER(c) \
+    wb = iter->coordinates[c] < iter->bounds[c][1]; \
+    if (wb) { \
+        iter->coordinates[c] += 1; \
+        return 0; \
+    } \
+    else { \
+        iter->coordinates[c] = iter->bounds[c][0]; \
+    }
+
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i, wb;
+
+    for (i = iter->nd - 1; i >= 0; --i) {
+        _UPDATE_COORD_ITER(i)
+    }
+
+    return 0;
+}
+
+/*
+ * Version optimized for 2d arrays, manual loop unrolling
+ */
+static NPY_INLINE int
+_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp wb;
+
+    _UPDATE_COORD_ITER(1)
+    _UPDATE_COORD_ITER(0)
+
+    return 0;
+}
+#undef _UPDATE_COORD_ITER
+
+/*
+ * Advance to the next neighbour
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter)
+{
+    _PyArrayNeighborhoodIter_IncrCoord (iter);
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
+
+/*
+ * Reset functions
+ */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter)
+{
+    npy_intp i;
+
+    for (i = 0; i < iter->nd; ++i) {
+        iter->coordinates[i] = iter->bounds[i][0];
+    }
+    iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+
+    return 0;
+}
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
new file mode 100644
index 0000000000..74ea19b4ff
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
@@ -0,0 +1,31 @@
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_FLOAT 4
+#define NPY_SIZEOF_COMPLEX_FLOAT 8
+#define NPY_SIZEOF_DOUBLE 8
+#define NPY_SIZEOF_COMPLEX_DOUBLE 16
+#define NPY_SIZEOF_LONGDOUBLE 16
+#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 32
+#define NPY_SIZEOF_PY_INTPTR_T 8
+#define NPY_SIZEOF_OFF_T 4
+#define NPY_SIZEOF_PY_LONG_LONG 8
+#define NPY_SIZEOF_LONGLONG 8
+#define NPY_NO_SIGNAL 1
+#define NPY_NO_SMP 0
+#define NPY_HAVE_DECL_ISNAN
+#define NPY_HAVE_DECL_ISINF
+#define NPY_HAVE_DECL_ISFINITE
+#define NPY_HAVE_DECL_SIGNBIT
+#define NPY_USE_C99_COMPLEX 1
+#define NPY_HAVE_COMPLEX_DOUBLE 1
+#define NPY_HAVE_COMPLEX_FLOAT 1
+#define NPY_HAVE_COMPLEX_LONG_DOUBLE 1
+#define NPY_USE_C99_FORMATS 1
+#define NPY_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#define NPY_ABI_VERSION 0x01000009
+#define NPY_API_VERSION 0x0000000A
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
new file mode 100644
index 0000000000..4f46d6b1ac
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
@@ -0,0 +1,11 @@
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
new file mode 100644
index 0000000000..64450e7132
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
@@ -0,0 +1,175 @@
+#ifndef _NPY_ARRAYSCALARS_H_
+#define _NPY_ARRAYSCALARS_H_
+
+#ifndef _MULTIARRAYMODULE
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+#endif
+
+
+typedef struct {
+        PyObject_HEAD
+        signed char obval;
+} PyByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        short obval;
+} PyShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        int obval;
+} PyIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        long obval;
+} PyLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longlong obval;
+} PyLongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned char obval;
+} PyUByteScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned short obval;
+} PyUShortScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned int obval;
+} PyUIntScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        unsigned long obval;
+} PyULongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_ulonglong obval;
+} PyULongLongScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_half obval;
+} PyHalfScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        float obval;
+} PyFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        double obval;
+} PyDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_longdouble obval;
+} PyLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cfloat obval;
+} PyCFloatScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_cdouble obval;
+} PyCDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        PyObject * obval;
+} PyObjectScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_datetime obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyDatetimeScalarObject;
+
+typedef struct {
+        PyObject_HEAD
+        npy_timedelta obval;
+        PyArray_DatetimeMetaData obmeta;
+} PyTimedeltaScalarObject;
+
+
+typedef struct {
+        PyObject_HEAD
+        char obval;
+} PyScalarObject;
+
+#define PyStringScalarObject PyStringObject
+#define PyUnicodeScalarObject PyUnicodeObject
+
+typedef struct {
+        PyObject_VAR_HEAD
+        char *obval;
+        PyArray_Descr *descr;
+        int flags;
+        PyObject *base;
+} PyVoidScalarObject;
+
+/* Macros
+     Py<Cls><bitsize>ScalarObject
+     Py<Cls><bitsize>ArrType_Type
+   are defined in ndarrayobject.h
+*/
+
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+        ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i)                  \
+        return Py_INCREF(PyArrayScalar_FromLong(i)), \
+                PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE              \
+        return Py_INCREF(PyArrayScalar_False),  \
+                PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE               \
+        return Py_INCREF(PyArrayScalar_True),   \
+                PyArrayScalar_True
+
+#define PyArrayScalar_New(cls) \
+        Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls)             \
+        ((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+        PyArrayScalar_VAL(obj, cls) = val
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
new file mode 100644
index 0000000000..ab0d221fb4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
@@ -0,0 +1,70 @@
+#ifndef __NPY_HALFFLOAT_H__
+#define __NPY_HALFFLOAT_H__
+
+#include <Python.h>
+#include <numpy/npy_math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Half-precision routines
+ */
+
+/* Conversions */
+float npy_half_to_float(npy_half h);
+double npy_half_to_double(npy_half h);
+npy_half npy_float_to_half(float f);
+npy_half npy_double_to_half(double d);
+/* Comparisons */
+int npy_half_eq(npy_half h1, npy_half h2);
+int npy_half_ne(npy_half h1, npy_half h2);
+int npy_half_le(npy_half h1, npy_half h2);
+int npy_half_lt(npy_half h1, npy_half h2);
+int npy_half_ge(npy_half h1, npy_half h2);
+int npy_half_gt(npy_half h1, npy_half h2);
+/* faster *_nonan variants for when you know h1 and h2 are not NaN */
+int npy_half_eq_nonan(npy_half h1, npy_half h2);
+int npy_half_lt_nonan(npy_half h1, npy_half h2);
+int npy_half_le_nonan(npy_half h1, npy_half h2);
+/* Miscellaneous functions */
+int npy_half_iszero(npy_half h);
+int npy_half_isnan(npy_half h);
+int npy_half_isinf(npy_half h);
+int npy_half_isfinite(npy_half h);
+int npy_half_signbit(npy_half h);
+npy_half npy_half_copysign(npy_half x, npy_half y);
+npy_half npy_half_spacing(npy_half h);
+npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
+
+/*
+ * Half-precision constants
+ */
+
+#define NPY_HALF_ZERO   (0x0000u)
+#define NPY_HALF_PZERO  (0x0000u)
+#define NPY_HALF_NZERO  (0x8000u)
+#define NPY_HALF_ONE    (0x3c00u)
+#define NPY_HALF_NEGONE (0xbc00u)
+#define NPY_HALF_PINF   (0x7c00u)
+#define NPY_HALF_NINF   (0xfc00u)
+#define NPY_HALF_NAN    (0x7e00u)
+
+#define NPY_MAX_HALF    (0x7bffu)
+
+/*
+ * Bit-level conversions
+ */
+
+npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f);
+npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d);
+npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h);
+npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
new file mode 100644
index 0000000000..3a0683da3c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
@@ -0,0 +1,2449 @@
+
+===========
+Numpy C-API
+===========
+::
+
+  unsigned int
+  PyArray_GetNDArrayCVersion(void )
+
+
+Included at the very first so not auto-grabbed and thus not labeled.
+
+::
+
+  int
+  PyArray_SetNumericOps(PyObject *dict)
+
+Set internal structure with number functions that all arrays will use
+
+::
+
+  PyObject *
+  PyArray_GetNumericOps(void )
+
+Get dictionary showing number functions that all arrays will use
+
+::
+
+  int
+  PyArray_INCREF(PyArrayObject *mp)
+
+For object arrays, increment all internal references.
+
+::
+
+  int
+  PyArray_XDECREF(PyArrayObject *mp)
+
+Decrement all internal references for object arrays.
+(or arrays with object fields)
+
+::
+
+  void
+  PyArray_SetStringFunction(PyObject *op, int repr)
+
+Set the array print function to be a Python function.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromType(int type)
+
+Get the PyArray_Descr structure for a type.
+
+::
+
+  PyObject *
+  PyArray_TypeObjectFromType(int type)
+
+Get a typeobject from a type-number -- can return NULL.
+
+New reference
+
+::
+
+  char *
+  PyArray_Zero(PyArrayObject *arr)
+
+Get pointer to zero of correct type for array.
+
+::
+
+  char *
+  PyArray_One(PyArrayObject *arr)
+
+Get pointer to one of correct type for array
+
+::
+
+  PyObject *
+  PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int
+                     is_f_order)
+
+For backward compatibility
+
+Cast an array using typecode structure.
+steals reference to dtype --- cannot be NULL
+
+This function always makes a copy of arr, even if the dtype
+doesn't change.
+
+::
+
+  int
+  PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.
+
+::
+
+  int
+  PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
+
+Cast to an already created array.  Arrays don't have to be "broadcastable"
+Only requirement is they have the same number of elements.
+
+::
+
+  int
+  PyArray_CanCastSafely(int fromtype, int totype)
+
+Check the type coercion rules.
+
+::
+
+  npy_bool
+  PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
+
+leaves reference count alone --- cannot be NULL
+
+PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
+parameter.
+
+::
+
+  int
+  PyArray_ObjectType(PyObject *op, int minimum_type)
+
+Return the typecode of the array a Python object would be converted to
+
+Returns the type number the result should have, or NPY_NOTYPE on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
+
+new reference -- accepts NULL for mintype
+
+::
+
+  PyArrayObject **
+  PyArray_ConvertToCommonType(PyObject *op, int *retn)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromScalar(PyObject *sc)
+
+Return descr object from array scalar.
+
+New reference
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrFromTypeObject(PyObject *type)
+
+
+::
+
+  npy_intp
+  PyArray_Size(PyObject *op)
+
+Compute the size of an array (in number of items)
+
+::
+
+  PyObject *
+  PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
+
+Get scalar-equivalent to a region of memory described by a descriptor.
+
+::
+
+  PyObject *
+  PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
+
+Get 0-dim array from scalar
+
+0-dim array from array-scalar object
+always contains a copy of the data
+unless outcode is NULL, it is of void type and the referrer does
+not own it either.
+
+steals reference to outcode
+
+::
+
+  void
+  PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
+
+Convert to c-type
+
+no error checking is performed -- ctypeptr must be same type as scalar
+in case of flexible type, the data is not copied
+into ctypeptr which is expected to be a pointer to pointer
+
+::
+
+  int
+  PyArray_CastScalarToCtype(PyObject *scalar, void
+                            *ctypeptr, PyArray_Descr *outcode)
+
+Cast Scalar to c-type
+
+The output buffer must be large-enough to receive the value
+Even for flexible types which is different from ScalarAsCtype
+where only a reference for flexible types is returned
+
+This may not work right on narrow builds for NumPy unicode scalars.
+
+::
+
+  int
+  PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr
+                           *indescr, void *ctypeptr, int outtype)
+
+Cast Scalar to c-type
+
+::
+
+  PyObject *
+  PyArray_ScalarFromObject(PyObject *object)
+
+Get an Array Scalar From a Python Object
+
+Returns NULL if unsuccessful but error is only set if another error occurred.
+Currently only Numeric-like object supported.
+
+::
+
+  PyArray_VectorUnaryFunc *
+  PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
+
+Get a cast function to cast from the input descriptor to the
+output type_number (must be a registered data-type).
+Returns NULL if un-successful.
+
+::
+
+  PyObject *
+  PyArray_FromDims(int nd, int *d, int type)
+
+Construct an empty array from dimensions and typenum
+
+::
+
+  PyObject *
+  PyArray_FromDimsAndDataAndDescr(int nd, int *d, PyArray_Descr
+                                  *descr, char *data)
+
+Like FromDimsAndData but uses the Descr structure instead of typecode
+as input.
+
+::
+
+  PyObject *
+  PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int
+                  min_depth, int max_depth, int flags, PyObject
+                  *context)
+
+Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
+Steals a reference to newtype --- which can be NULL
+
+::
+
+  PyObject *
+  PyArray_EnsureArray(PyObject *op)
+
+This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY)
+that special cases Arrays and PyArray_Scalars up front
+It *steals a reference* to the object
+It also guarantees that the result is PyArray_Type
+Because it decrefs op if any conversion needs to take place
+so it can be used like PyArray_EnsureArray(some_function(...))
+
+::
+
+  PyObject *
+  PyArray_EnsureAnyArray(PyObject *op)
+
+
+::
+
+  PyObject *
+  PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char
+                   *sep)
+
+
+Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
+array corresponding to the data encoded in that file.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+For memory-mapped files, use the buffer interface. No more data than
+necessary is read by this routine.
+
+::
+
+  PyObject *
+  PyArray_FromString(char *data, npy_intp slen, PyArray_Descr
+                     *dtype, npy_intp num, char *sep)
+
+
+Given a pointer to a string ``data``, a string length ``slen``, and
+a ``PyArray_Descr``, return an array corresponding to the data
+encoded in that string.
+
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+
+If ``slen`` is < 0, then the end of string is used for text data.
+It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs
+would be the norm).
+
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+
+::
+
+  PyObject *
+  PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp
+                     count, npy_intp offset)
+
+
+::
+
+  PyObject *
+  PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count)
+
+
+steals a reference to dtype (which cannot be NULL)
+
+::
+
+  PyObject *
+  PyArray_Return(PyArrayObject *mp)
+
+
+Return either an array or the appropriate Python object if the array
+is 0d and matches a Python type.
+steals reference to mp
+
+::
+
+  PyObject *
+  PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int
+                   offset)
+
+Get a subset of bytes from each element of the array
+steals reference to typed, must not be NULL
+
+::
+
+  int
+  PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int
+                   offset, PyObject *val)
+
+Set a subset of bytes from each element of the array
+steals reference to dtype, must not be NULL
+
+::
+
+  PyObject *
+  PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)
+
+
+::
+
+  PyObject *
+  PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int
+                 refcheck, NPY_ORDER order)
+
+Resize (reallocate data).  Only works if nothing else is referencing this
+array and it is contiguous.  If refcheck is 0, then the reference count is
+not checked and assumed to be 1.  You still must own this data and have no
+weak-references and no base object.
+
+::
+
+  int
+  PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src)
+
+Move the memory of one array into another, allowing for overlapping data.
+
+Returns 0 on success, negative on failure.
+
+::
+
+  int
+  PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array.
+Broadcast to the destination shape if necessary.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  int
+  PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src)
+
+Copy an Array into another array -- memory must not overlap
+Does not require src and dest to have "broadcastable" shapes
+(only the same number of elements).
+
+TODO: For NumPy 2.0, this could accept an order parameter which
+only allows NPY_CORDER and NPY_FORDER.  Could also rename
+this to CopyAsFlat to make the name more intuitive.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
+
+
+::
+
+  PyObject *
+  PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order)
+
+Copy an array.
+
+::
+
+  PyObject *
+  PyArray_ToList(PyArrayObject *self)
+
+To List
+
+::
+
+  PyObject *
+  PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
+
+
+::
+
+  int
+  PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
+
+To File
+
+::
+
+  int
+  PyArray_Dump(PyObject *self, PyObject *file, int protocol)
+
+
+::
+
+  PyObject *
+  PyArray_Dumps(PyObject *self, int protocol)
+
+
+::
+
+  int
+  PyArray_ValidType(int type)
+
+Is the typenum valid?
+
+::
+
+  void
+  PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
+
+Update Several Flags at once.
+
+::
+
+  PyObject *
+  PyArray_New(PyTypeObject *subtype, int nd, npy_intp *dims, int
+              type_num, npy_intp *strides, void *data, int itemsize, int
+              flags, PyObject *obj)
+
+Generic new array creation routine.
+
+::
+
+  PyObject *
+  PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int
+                       nd, npy_intp *dims, npy_intp *strides, void
+                       *data, int flags, PyObject *obj)
+
+Generic new array creation routine.
+
+steals a reference to descr (even on failure)
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNew(PyArray_Descr *base)
+
+base cannot be NULL
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewFromType(int type_num)
+
+
+::
+
+  double
+  PyArray_GetPriority(PyObject *obj, double default_)
+
+Get Priority from object
+
+::
+
+  PyObject *
+  PyArray_IterNew(PyObject *obj)
+
+Get Iterator.
+
+::
+
+  PyObject *
+  PyArray_MultiIterNew(int n, ... )
+
+Get MultiIterator,
+
+::
+
+  int
+  PyArray_PyIntAsInt(PyObject *o)
+
+
+::
+
+  npy_intp
+  PyArray_PyIntAsIntp(PyObject *o)
+
+
+::
+
+  int
+  PyArray_Broadcast(PyArrayMultiIterObject *mit)
+
+
+::
+
+  void
+  PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
+
+Assumes contiguous
+
+::
+
+  int
+  PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
+
+
+::
+
+  npy_bool
+  PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp
+                       offset, npy_intp *dims, npy_intp *newstrides)
+
+
+::
+
+  PyArray_Descr *
+  PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+
+
+returns a copy of the PyArray_Descr structure with the byteorder
+altered:
+no arguments:  The byteorder is swapped (in all subfields as well)
+single argument:  The byteorder is forced to the given state
+(in all subfields as well)
+
+Valid states:  ('big', '>') or ('little' or '<')
+('native', or '=')
+
+If a descr structure with | is encountered it's own
+byte-order is not changed but any fields are:
+
+
+Deep bytorder change of a data-type descriptor
+Leaves reference count of self unchanged --- does not DECREF self ***
+
+::
+
+  PyObject *
+  PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
+
+Get Iterator that iterates over all but one axis (don't use this with
+PyArray_ITER_GOTO1D).  The axis will be over-written if negative
+with the axis having the smallest stride.
+
+::
+
+  PyObject *
+  PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int
+                       min_depth, int max_depth, int requires, PyObject
+                       *context)
+
+steals a reference to descr -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int
+                    flags)
+
+steals reference to newtype --- acc. NULL
+
+::
+
+  PyObject *
+  PyArray_FromInterface(PyObject *origin)
+
+
+::
+
+  PyObject *
+  PyArray_FromStructInterface(PyObject *input)
+
+
+::
+
+  PyObject *
+  PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject
+                        *context)
+
+
+::
+
+  NPY_SCALARKIND
+  PyArray_ScalarKind(int typenum, PyArrayObject **arr)
+
+ScalarKind
+
+Returns the scalar kind of a type number, with an
+optional tweak based on the scalar value itself.
+If no scalar is provided, it returns INTPOS_SCALAR
+for both signed and unsigned integers, otherwise
+it checks the sign of any signed integer to choose
+INTNEG_SCALAR when appropriate.
+
+::
+
+  int
+  PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND
+                          scalar)
+
+
+Determines whether the data type 'thistype', with
+scalar kind 'scalar', can be coerced into 'neededtype'.
+
+::
+
+  PyObject *
+  PyArray_NewFlagsObject(PyObject *obj)
+
+
+Get New ArrayFlagsObject
+
+::
+
+  npy_bool
+  PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
+
+See if array scalars can be cast.
+
+TODO: For NumPy 2.0, add a NPY_CASTING parameter.
+
+::
+
+  int
+  PyArray_CompareUCS4(npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
+
+
+::
+
+  int
+  PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
+
+Adjusts previously broadcasted iterators so that the axis with
+the smallest sum of iterator strides is not iterated over.
+Returns dimension which is smallest in the range [0,multi->nd).
+A -1 is returned if multi->nd == 0.
+
+don't use with PyArray_ITER_GOTO1D because factors are not adjusted
+
+::
+
+  int
+  PyArray_ElementStrides(PyObject *obj)
+
+
+::
+
+  void
+  PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  void
+  PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
+
+
+::
+
+  PyObject *
+  PyArray_FieldNames(PyObject *fields)
+
+Return the tuple of ordered field names from a dictionary.
+
+::
+
+  PyObject *
+  PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
+
+Return Transpose.
+
+::
+
+  PyObject *
+  PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int
+                   axis, PyArrayObject *out, NPY_CLIPMODE clipmode)
+
+Take
+
+::
+
+  PyObject *
+  PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject
+                *indices0, NPY_CLIPMODE clipmode)
+
+Put values into an array
+
+::
+
+  PyObject *
+  PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0)
+
+Put values into an array according to a mask.
+
+::
+
+  PyObject *
+  PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis)
+
+Repeat the array.
+
+::
+
+  PyObject *
+  PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject
+                 *out, NPY_CLIPMODE clipmode)
+
+
+::
+
+  int
+  PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+Sort an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+
+ArgSort an array
+
+::
+
+  PyObject *
+  PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE
+                       side, PyObject *perm)
+
+
+Search the sorted array op1 for the location of the items in op2. The
+result is an array of indexes, one for each element in op2, such that if
+the item were to be inserted in op1 just before that index the array
+would still be in sorted order.
+
+Parameters
+----------
+op1 : PyArrayObject *
+Array to be searched, must be 1-D.
+op2 : PyObject *
+Array of items whose insertion indexes in op1 are wanted
+side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT}
+If NPY_SEARCHLEFT, return first valid insertion indexes
+If NPY_SEARCHRIGHT, return last valid insertion indexes
+perm : PyObject *
+Permutation array that sorts op1 (optional)
+
+Returns
+-------
+ret : PyObject *
+New reference to npy_intp array containing indexes where items in op2
+could be validly inserted into op1. NULL on error.
+
+Notes
+-----
+Binary search is used to find the indexes.
+
+::
+
+  PyObject *
+  PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMax
+
+::
+
+  PyObject *
+  PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+
+ArgMin
+
+::
+
+  PyObject *
+  PyArray_Reshape(PyArrayObject *self, PyObject *shape)
+
+Reshape
+
+::
+
+  PyObject *
+  PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER
+                   order)
+
+New shape for an array
+
+::
+
+  PyObject *
+  PyArray_Squeeze(PyArrayObject *self)
+
+
+return a new view of the array object with all of its unit-length
+dimensions squeezed out if needed, otherwise
+return the same array.
+
+::
+
+  PyObject *
+  PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject
+               *pytype)
+
+View
+steals a reference to type -- accepts NULL
+
+::
+
+  PyObject *
+  PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2)
+
+SwapAxes
+
+::
+
+  PyObject *
+  PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Max
+
+::
+
+  PyObject *
+  PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Min
+
+::
+
+  PyObject *
+  PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out)
+
+Ptp
+
+::
+
+  PyObject *
+  PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Mean
+
+::
+
+  PyObject *
+  PyArray_Trace(PyArrayObject *self, int offset, int axis1, int
+                axis2, int rtype, PyArrayObject *out)
+
+Trace
+
+::
+
+  PyObject *
+  PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int
+                   axis2)
+
+Diagonal
+
+In NumPy versions prior to 1.7,  this function always returned a copy of
+the diagonal array. In 1.7, the code has been updated to compute a view
+onto 'self', but it still copies this array before returning, as well as
+setting the internal WARN_ON_WRITE flag. In a future version, it will
+simply return a view onto self.
+
+::
+
+  PyObject *
+  PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject
+               *max, PyArrayObject *out)
+
+Clip
+
+::
+
+  PyObject *
+  PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
+
+Conjugate
+
+::
+
+  PyObject *
+  PyArray_Nonzero(PyArrayObject *self)
+
+Nonzero
+
+TODO: In NumPy 2.0, should make the iteration order a parameter.
+
+::
+
+  PyObject *
+  PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out, int variance)
+
+Set variance to 1 to by-pass square-root calculation and return variance
+Std
+
+::
+
+  PyObject *
+  PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+              *out)
+
+Sum
+
+::
+
+  PyObject *
+  PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+                 *out)
+
+CumSum
+
+::
+
+  PyObject *
+  PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject
+               *out)
+
+Prod
+
+::
+
+  PyObject *
+  PyArray_CumProd(PyArrayObject *self, int axis, int
+                  rtype, PyArrayObject *out)
+
+CumProd
+
+::
+
+  PyObject *
+  PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)
+
+All
+
+::
+
+  PyObject *
+  PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)
+
+Any
+
+::
+
+  PyObject *
+  PyArray_Compress(PyArrayObject *self, PyObject *condition, int
+                   axis, PyArrayObject *out)
+
+Compress
+
+::
+
+  PyObject *
+  PyArray_Flatten(PyArrayObject *a, NPY_ORDER order)
+
+Flatten
+
+::
+
+  PyObject *
+  PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order)
+
+Ravel
+Returns a contiguous array
+
+::
+
+  npy_intp
+  PyArray_MultiplyList(npy_intp *l1, int n)
+
+Multiply a List
+
+::
+
+  int
+  PyArray_MultiplyIntList(int *l1, int n)
+
+Multiply a List of ints
+
+::
+
+  void *
+  PyArray_GetPtr(PyArrayObject *obj, npy_intp*ind)
+
+Produce a pointer into array
+
+::
+
+  int
+  PyArray_CompareLists(npy_intp *l1, npy_intp *l2, int n)
+
+Compare Lists
+
+::
+
+  int
+  PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int
+                   nd, PyArray_Descr*typedescr)
+
+Simulate a C-array
+steals a reference to typedescr -- can be NULL
+
+::
+
+  int
+  PyArray_As1D(PyObject **op, char **ptr, int *d1, int typecode)
+
+Convert to a 1D C-array
+
+::
+
+  int
+  PyArray_As2D(PyObject **op, char ***ptr, int *d1, int *d2, int
+               typecode)
+
+Convert to a 2D C-array
+
+::
+
+  int
+  PyArray_Free(PyObject *op, void *ptr)
+
+Free pointers created if As2D is called
+
+::
+
+  int
+  PyArray_Converter(PyObject *object, PyObject **address)
+
+
+Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
+
+This conversion function can be used with the "O&" argument for
+PyArg_ParseTuple.  It will immediately return an object of array type
+or will convert to a NPY_ARRAY_CARRAY any other object.
+
+If you use PyArray_Converter, you must DECREF the array when finished
+as you get a new reference to it.
+
+::
+
+  int
+  PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
+
+PyArray_IntpFromSequence
+Returns the number of integers converted or -1 if an error occurred.
+vals must be large enough to hold maxvals
+
+::
+
+  PyObject *
+  PyArray_Concatenate(PyObject *op, int axis)
+
+Concatenate
+
+Concatenate an arbitrary Python sequence into an array.
+op is a python object supporting the sequence interface.
+Its elements will be concatenated together to form a single
+multidimensional array. If axis is NPY_MAXDIMS or bigger, then
+each sequence object will be flattened before concatenation
+
+::
+
+  PyObject *
+  PyArray_InnerProduct(PyObject *op1, PyObject *op2)
+
+Numeric.innerproduct(a,v)
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct(PyObject *op1, PyObject *op2)
+
+Numeric.matrixproduct(a,v)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  PyObject *
+  PyArray_CopyAndTranspose(PyObject *op)
+
+Copy and Transpose
+
+Could deprecate this function, as there isn't a speed benefit over
+calling Transpose and then Copy.
+
+::
+
+  PyObject *
+  PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
+
+Numeric.correlate(a1,a2,mode)
+
+::
+
+  int
+  PyArray_TypestrConvert(int itemsize, int gentype)
+
+Typestr converter
+
+::
+
+  int
+  PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
+This function takes a Python object representing a type and converts it
+to a the correct PyArray_Descr * structure to describe the type.
+
+Many objects can be used to represent a data-type which in NumPy is
+quite a flexible concept.
+
+This is the central code that converts Python objects to
+Type-descriptor objects that are used throughout numpy.
+
+Returns a new reference in *at, but the returned should not be
+modified as it may be one of the canonical immutable objects or
+a reference to the input obj.
+
+::
+
+  int
+  PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at)
+
+Get typenum from an object -- None goes to NULL
+
+::
+
+  int
+  PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)
+
+Get intp chunk from sequence
+
+This function takes a Python sequence object and allocates and
+fills in an intp array with the converted values.
+
+Remember to free the pointer seq.ptr when done using
+PyDimMem_FREE(seq.ptr)**
+
+::
+
+  int
+  PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
+
+Get buffer chunk from object
+
+this function takes a Python object which exposes the (single-segment)
+buffer interface and returns a pointer to the data segment
+
+You should increment the reference count by one of buf->base
+if you will hang on to a reference
+
+You only get a borrowed reference to the object. Do not free the
+memory...
+
+::
+
+  int
+  PyArray_AxisConverter(PyObject *obj, int *axis)
+
+Get axis from an object (possibly None) -- a converter function,
+
+See also PyArray_ConvertMultiAxis, which also handles a tuple of axes.
+
+::
+
+  int
+  PyArray_BoolConverter(PyObject *object, npy_bool *val)
+
+Convert an object to true / false
+
+::
+
+  int
+  PyArray_ByteorderConverter(PyObject *obj, char *endian)
+
+Convert object to endian
+
+::
+
+  int
+  PyArray_OrderConverter(PyObject *object, NPY_ORDER *val)
+
+Convert an object to FORTRAN / C / ANY / KEEP
+
+::
+
+  unsigned char
+  PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+
+This function returns true if the two typecodes are
+equivalent (same basic kind and same itemsize).
+
+::
+
+  PyObject *
+  PyArray_Zeros(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Zeros
+
+steal a reference
+accepts NULL type
+
+::
+
+  PyObject *
+  PyArray_Empty(int nd, npy_intp *dims, PyArray_Descr *type, int
+                is_f_order)
+
+Empty
+
+accepts NULL type
+steals referenct to type
+
+::
+
+  PyObject *
+  PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)
+
+Where
+
+::
+
+  PyObject *
+  PyArray_Arange(double start, double stop, double step, int type_num)
+
+Arange,
+
+::
+
+  PyObject *
+  PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject
+                    *step, PyArray_Descr *dtype)
+
+
+ArangeObj,
+
+this doesn't change the references
+
+::
+
+  int
+  PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
+
+Convert object to sort kind
+
+::
+
+  PyObject *
+  PyArray_LexSort(PyObject *sort_keys, int axis)
+
+LexSort an array providing indices that will sort a collection of arrays
+lexicographically.  The first key is sorted on first, followed by the second key
+-- requires that arg"merge"sort is available for each sort_key
+
+Returns an index array that shows the indexes for the lexicographic sort along
+the given axis.
+
+::
+
+  PyObject *
+  PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out)
+
+Round
+
+::
+
+  unsigned char
+  PyArray_EquivTypenums(int typenum1, int typenum2)
+
+
+::
+
+  int
+  PyArray_RegisterDataType(PyArray_Descr *descr)
+
+Register Data type
+Does not change the reference count of descr
+
+::
+
+  int
+  PyArray_RegisterCastFunc(PyArray_Descr *descr, int
+                           totype, PyArray_VectorUnaryFunc *castfunc)
+
+Register Casting Function
+Replaces any function currently stored.
+
+::
+
+  int
+  PyArray_RegisterCanCast(PyArray_Descr *descr, int
+                          totype, NPY_SCALARKIND scalar)
+
+Register a type number indicating that a descriptor can be cast
+to it safely
+
+::
+
+  void
+  PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
+
+Initialize arrfuncs to NULL
+
+::
+
+  PyObject *
+  PyArray_IntTupleFromIntp(int len, npy_intp *vals)
+
+PyArray_IntTupleFromIntp
+
+::
+
+  int
+  PyArray_TypeNumFromName(char *str)
+
+
+::
+
+  int
+  PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)
+
+Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP
+
+::
+
+  int
+  PyArray_OutputConverter(PyObject *object, PyArrayObject **address)
+
+Useful to pass as converter function for O& processing in
+PyArgs_ParseTuple for output arrays
+
+::
+
+  PyObject *
+  PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd)
+
+Get Iterator broadcast to a particular shape
+
+::
+
+  void
+  _PyArray_SigintHandler(int signum)
+
+
+::
+
+  void*
+  _PyArray_GetSigintBuf(void )
+
+
+::
+
+  int
+  PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to DEFAULT type.
+
+any object with the .fields attribute and/or .itemsize attribute (if the
+.fields attribute does not give the total size -- i.e. a partial record
+naming).  If itemsize is given it must be >= size computed from fields
+
+The .fields attribute must return a convertible dictionary if present.
+Result inherits from NPY_VOID.
+
+::
+
+  int
+  PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at)
+
+
+Get type-descriptor from an object forcing alignment if possible
+None goes to NULL.
+
+::
+
+  int
+  PyArray_SearchsideConverter(PyObject *obj, void *addr)
+
+Convert object to searchsorted side
+
+::
+
+  PyObject *
+  PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
+
+PyArray_CheckAxis
+
+check that axis is valid
+convert 0-d arrays to 1-d arrays
+
+::
+
+  npy_intp
+  PyArray_OverflowMultiplyList(npy_intp *l1, int n)
+
+Multiply a List of Non-negative numbers with over-flow detection.
+
+::
+
+  int
+  PyArray_CompareString(char *s1, char *s2, size_t len)
+
+
+::
+
+  PyObject *
+  PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... )
+
+Get MultiIterator from array of Python objects and any additional
+
+PyObject **mps -- array of PyObjects
+int n - number of PyObjects in the array
+int nadd - number of additional arrays to include in the iterator.
+
+Returns a multi-iterator object.
+
+::
+
+  int
+  PyArray_GetEndianness(void )
+
+
+::
+
+  unsigned int
+  PyArray_GetNDArrayCFeatureVersion(void )
+
+Returns the built-in (at compilation time) C API version
+
+::
+
+  PyObject *
+  PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)
+
+correlate(a1,a2,mode)
+
+This function computes the usual correlation (correlate(a1, a2) !=
+correlate(a2, a1), and conjugate the second argument for complex inputs
+
+::
+
+  PyObject*
+  PyArray_NeighborhoodIterNew(PyArrayIterObject *x, npy_intp
+                              *bounds, int mode, PyArrayObject*fill)
+
+A Neighborhood Iterator object.
+
+::
+
+  void
+  PyArray_SetDatetimeParseFunction(PyObject *op)
+
+This function is scheduled to be removed
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_DatetimeToDatetimeStruct(npy_datetime val, NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *result)
+
+Fill the datetime struct from the value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  void
+  PyArray_TimedeltaToTimedeltaStruct(npy_timedelta val, NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *result)
+
+Fill the timedelta struct from the timedelta value and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT
+                                   fr, npy_datetimestruct *d)
+
+Create a datetime value from a filled datetime struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  npy_datetime
+  PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT
+                                     fr, npy_timedeltastruct *d)
+
+Create a timdelta value from a filled timedelta struct and resolution unit.
+
+TO BE REMOVED - NOT USED INTERNALLY.
+
+::
+
+  NpyIter *
+  NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER
+              order, NPY_CASTING casting, PyArray_Descr*dtype)
+
+Allocate a new iterator for one array object.
+
+::
+
+  NpyIter *
+  NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32
+                   flags, NPY_ORDER order, NPY_CASTING
+                   casting, npy_uint32 *op_flags, PyArray_Descr
+                   **op_request_dtypes)
+
+Allocate a new iterator for more than one array object, using
+standard NumPy broadcasting rules and the default buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32
+                      flags, NPY_ORDER order, NPY_CASTING
+                      casting, npy_uint32 *op_flags, PyArray_Descr
+                      **op_request_dtypes, int oa_ndim, int
+                      **op_axes, npy_intp *itershape, npy_intp
+                      buffersize)
+
+Allocate a new iterator for multiple array objects, and advanced
+options for controlling the broadcasting, shape, and buffer size.
+
+::
+
+  NpyIter *
+  NpyIter_Copy(NpyIter *iter)
+
+Makes a copy of the iterator
+
+::
+
+  int
+  NpyIter_Deallocate(NpyIter *iter)
+
+Deallocate an iterator
+
+::
+
+  npy_bool
+  NpyIter_HasDelayedBufAlloc(NpyIter *iter)
+
+Whether the buffer allocation is being delayed
+
+::
+
+  npy_bool
+  NpyIter_HasExternalLoop(NpyIter *iter)
+
+Whether the iterator handles the inner loop
+
+::
+
+  int
+  NpyIter_EnableExternalLoop(NpyIter *iter)
+
+Removes the inner loop handling (so HasExternalLoop returns true)
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerStrideArray(NpyIter *iter)
+
+Get the array of strides for the inner loop (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetInnerLoopSizePtr(NpyIter *iter)
+
+Get a pointer to the size of the inner loop  (when HasExternalLoop is true)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_Reset(NpyIter *iter, char **errmsg)
+
+Resets the iterator to its initial state
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char
+                            **errmsg)
+
+Resets the iterator to its initial state, with new base data pointers.
+This function requires great caution.
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp
+                                iend, char **errmsg)
+
+Resets the iterator to a new iterator index range
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GetNDim(NpyIter *iter)
+
+Gets the number of dimensions being iterated
+
+::
+
+  int
+  NpyIter_GetNOp(NpyIter *iter)
+
+Gets the number of operands being iterated
+
+::
+
+  NpyIter_IterNextFunc *
+  NpyIter_GetIterNext(NpyIter *iter, char **errmsg)
+
+Compute the specialized iteration function for an iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  npy_intp
+  NpyIter_GetIterSize(NpyIter *iter)
+
+Gets the number of elements being iterated
+
+::
+
+  void
+  NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp
+                            *iend)
+
+Gets the range of iteration indices being iterated
+
+::
+
+  npy_intp
+  NpyIter_GetIterIndex(NpyIter *iter)
+
+Gets the current iteration index
+
+::
+
+  int
+  NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex)
+
+Sets the iterator position to the specified iterindex,
+which matches the iteration order of the iterator.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  npy_bool
+  NpyIter_HasMultiIndex(NpyIter *iter)
+
+Whether the iterator is tracking a multi-index
+
+::
+
+  int
+  NpyIter_GetShape(NpyIter *iter, npy_intp *outshape)
+
+Gets the broadcast shape if a multi-index is being tracked by the iterator,
+otherwise gets the shape of the iteration as Fortran-order
+(fastest-changing index first).
+
+The reason Fortran-order is returned when a multi-index
+is not enabled is that this is providing a direct view into how
+the iterator traverses the n-dimensional space. The iterator organizes
+its memory from fastest index to slowest index, and when
+a multi-index is enabled, it uses a permutation to recover the original
+order.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  NpyIter_GetMultiIndexFunc *
+  NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg)
+
+Compute a specialized get_multi_index function for the iterator
+
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL.
+
+::
+
+  int
+  NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp *multi_index)
+
+Sets the iterator to the specified multi-index, which must have the
+correct number of entries for 'ndim'.  It is only valid
+when NPY_ITER_MULTI_INDEX was passed to the constructor.  This operation
+fails if the multi-index is out of bounds.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  int
+  NpyIter_RemoveMultiIndex(NpyIter *iter)
+
+Removes multi-index support from an iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_bool
+  NpyIter_HasIndex(NpyIter *iter)
+
+Whether the iterator is tracking an index
+
+::
+
+  npy_bool
+  NpyIter_IsBuffered(NpyIter *iter)
+
+Whether the iterator is buffered
+
+::
+
+  npy_bool
+  NpyIter_IsGrowInner(NpyIter *iter)
+
+Whether the inner loop can grow if buffering is unneeded
+
+::
+
+  npy_intp
+  NpyIter_GetBufferSize(NpyIter *iter)
+
+Gets the size of the buffer, or 0 if buffering is not enabled
+
+::
+
+  npy_intp *
+  NpyIter_GetIndexPtr(NpyIter *iter)
+
+Get a pointer to the index, if it is being tracked
+
+::
+
+  int
+  NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index)
+
+If the iterator is tracking an index, sets the iterator
+to the specified index.
+
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+
+::
+
+  char **
+  NpyIter_GetDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated)
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  PyArray_Descr **
+  NpyIter_GetDescrArray(NpyIter *iter)
+
+Get the array of data type pointers (1 per object being iterated)
+
+::
+
+  PyArrayObject **
+  NpyIter_GetOperandArray(NpyIter *iter)
+
+Get the array of objects being iterated
+
+::
+
+  PyArrayObject *
+  NpyIter_GetIterView(NpyIter *iter, npy_intp i)
+
+Returns a view to the i-th object with the iterator's internal axes
+
+::
+
+  void
+  NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags)
+
+Gets an array of read flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags)
+
+Gets an array of write flags (1 per object being iterated)
+
+::
+
+  void
+  NpyIter_DebugPrint(NpyIter *iter)
+
+For debugging
+
+::
+
+  npy_bool
+  NpyIter_IterationNeedsAPI(NpyIter *iter)
+
+Whether the iteration loop, and in particular the iternext()
+function, needs API access.  If this is true, the GIL must
+be retained while iterating.
+
+::
+
+  void
+  NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides)
+
+Get an array of strides which are fixed.  Any strides which may
+change during iteration receive the value NPY_MAX_INTP.  Once
+the iterator is ready to iterate, call this to get the strides
+which will always be fixed in the inner loop, then choose optimized
+inner loop functions which take advantage of those fixed strides.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_RemoveAxis(NpyIter *iter, int axis)
+
+Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX
+was set for iterator creation, and does not work if buffering is
+enabled. This function also resets the iterator to its initial state.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  npy_intp *
+  NpyIter_GetAxisStrideArray(NpyIter *iter, int axis)
+
+Gets the array of strides for the specified axis.
+If the iterator is tracking a multi-index, gets the strides
+for the axis specified, otherwise gets the strides for
+the iteration axis as Fortran order (fastest-changing axis first).
+
+Returns NULL if an error occurs.
+
+::
+
+  npy_bool
+  NpyIter_RequiresBuffering(NpyIter *iter)
+
+Whether the iteration could be done with no buffering.
+
+::
+
+  char **
+  NpyIter_GetInitialDataPtrArray(NpyIter *iter)
+
+Get the array of data pointers (1 per object being iterated),
+directly into the arrays (never pointing to a buffer), for starting
+unbuffered iteration. This always returns the addresses for the
+iterator position as reset to iterator index 0.
+
+These pointers are different from the pointers accepted by
+NpyIter_ResetBasePointers, because the direction along some
+axes may have been reversed, requiring base offsets.
+
+This function may be safely called without holding the Python GIL.
+
+::
+
+  int
+  NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp
+                                  itemsize, npy_intp *outstrides)
+
+Builds a set of strides which are the same as the strides of an
+output array created using the NPY_ITER_ALLOCATE flag, where NULL
+was passed for op_axes.  This is for data packed contiguously,
+but not necessarily in C or Fortran order. This should be used
+together with NpyIter_GetShape and NpyIter_GetNDim.
+
+A use case for this function is to match the shape and layout of
+the iterator and tack on one or more dimensions.  For example,
+in order to generate a vector per input value for a numerical gradient,
+you pass in ndim*itemsize for itemsize, then add another dimension to
+the end with size ndim and stride itemsize.  To do the Hessian matrix,
+you do the same thing but add two dimensions, or take advantage of
+the symmetry and pack it into 1 dimension with a particular encoding.
+
+This function may only be called if the iterator is tracking a multi-index
+and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from
+being iterated in reverse order.
+
+If an array is created with this method, simply adding 'itemsize'
+for each iteration will traverse the new array matching the
+iterator.
+
+Returns NPY_SUCCEED or NPY_FAIL.
+
+::
+
+  int
+  PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)
+
+Convert any Python object, *obj*, to an NPY_CASTING enum.
+
+::
+
+  npy_intp
+  PyArray_CountNonzero(PyArrayObject *self)
+
+Counts the number of non-zero elements in the array.
+
+Returns -1 on error.
+
+::
+
+  PyArray_Descr *
+  PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+
+Produces the smallest size and lowest kind type to which both
+input types can be cast.
+
+::
+
+  PyArray_Descr *
+  PyArray_MinScalarType(PyArrayObject *arr)
+
+If arr is a scalar (has 0 dimensions) with a built-in number data type,
+finds the smallest type size/kind which can still represent its data.
+Otherwise, returns the array's data type.
+
+
+::
+
+  PyArray_Descr *
+  PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp
+                     ndtypes, PyArray_Descr **dtypes)
+
+Produces the result type of a bunch of inputs, using the UFunc
+type promotion rules. Use this function when you have a set of
+input arrays, and need to determine an output array dtype.
+
+If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
+of the scalars is greater than the maximum "kind" of the arrays, does
+a regular type promotion.
+
+Otherwise, does a type promotion on the MinScalarType
+of all the inputs.  Data types passed directly are treated as array
+types.
+
+
+::
+
+  npy_bool
+  PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr
+                         *to, NPY_CASTING casting)
+
+Returns 1 if the array object may be cast to the given data type using
+the casting rule, 0 otherwise.  This differs from PyArray_CanCastTo in
+that it handles scalar arrays (0 dimensions) specially, by checking
+their value.
+
+::
+
+  npy_bool
+  PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr
+                        *to, NPY_CASTING casting)
+
+Returns true if data of type 'from' may be cast to data of type
+'to' according to the rule 'casting'.
+
+::
+
+  PyArrayObject *
+  PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject
+                      **op_in, PyArray_Descr *dtype, NPY_ORDER
+                      order, NPY_CASTING casting, PyArrayObject *out)
+
+This function provides summation of array elements according to
+the Einstein summation convention.  For example:
+- trace(a)        -> einsum("ii", a)
+- transpose(a)    -> einsum("ji", a)
+- multiply(a,b)   -> einsum(",", a, b)
+- inner(a,b)      -> einsum("i,i", a, b)
+- outer(a,b)      -> einsum("i,j", a, b)
+- matvec(a,b)     -> einsum("ij,j", a, b)
+- matmat(a,b)     -> einsum("ij,jk", a, b)
+
+subscripts: The string of subscripts for einstein summation.
+nop:        The number of operands
+op_in:      The array of operands
+dtype:      Either NULL, or the data type to force the calculation as.
+order:      The order for the calculation/the output axes.
+casting:    What kind of casts should be permitted.
+out:        Either NULL, or an array into which the output should be placed.
+
+By default, the labels get placed in alphabetical order
+at the end of the output. So, if c = einsum("i,j", a, b)
+then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b)
+then c[i,j] = a[j]*b[i].
+
+Alternatively, you can control the output order or prevent
+an axis from being summed/force an axis to be summed by providing
+indices for the output. This allows us to turn 'trace' into
+'diag', for example.
+- diag(a)         -> einsum("ii->i", a)
+- sum(a, axis=0)  -> einsum("i...->", a)
+
+Subscripts at the beginning and end may be specified by
+putting an ellipsis "..." in the middle.  For example,
+the function einsum("i...i", a) takes the diagonal of
+the first and last dimensions of the operand, and
+einsum("ij...,jk...->ik...") takes the matrix product using
+the first two indices of each operand instead of the last two.
+
+When there is only one operand, no axes being summed, and
+no output parameter, this function returns a view
+into the operand instead of making a copy.
+
+::
+
+  PyObject *
+  PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER
+                       order, PyArray_Descr *dtype, int subok)
+
+Creates a new array with the same shape as the provided one,
+with possible memory layout order and data type changes.
+
+prototype - The array the new one should be like.
+order     - NPY_CORDER - C-contiguous result.
+NPY_FORTRANORDER - Fortran-contiguous result.
+NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise.
+NPY_KEEPORDER - Keeps the axis ordering of prototype.
+dtype     - If not NULL, overrides the data type of the result.
+subok     - If 1, use the prototype's array subtype, otherwise
+always create a base-class array.
+
+NOTE: If dtype is not NULL, steals the dtype reference.
+
+::
+
+  int
+  PyArray_GetArrayParamsFromObject(PyObject *op, PyArray_Descr
+                                   *requested_dtype, npy_bool
+                                   writeable, PyArray_Descr
+                                   **out_dtype, int *out_ndim, npy_intp
+                                   *out_dims, PyArrayObject
+                                   **out_arr, PyObject *context)
+
+Retrieves the array parameters for viewing/converting an arbitrary
+PyObject* to a NumPy array. This allows the "innate type and shape"
+of Python list-of-lists to be discovered without
+actually converting to an array.
+
+In some cases, such as structured arrays and the __array__ interface,
+a data type needs to be used to make sense of the object.  When
+this is needed, provide a Descr for 'requested_dtype', otherwise
+provide NULL. This reference is not stolen. Also, if the requested
+dtype doesn't modify the interpretation of the input, out_dtype will
+still get the "innate" dtype of the object, not the dtype passed
+in 'requested_dtype'.
+
+If writing to the value in 'op' is desired, set the boolean
+'writeable' to 1.  This raises an error when 'op' is a scalar, list
+of lists, or other non-writeable 'op'.
+
+Result: When success (0 return value) is returned, either out_arr
+is filled with a non-NULL PyArrayObject and
+the rest of the parameters are untouched, or out_arr is
+filled with NULL, and the rest of the parameters are
+filled.
+
+Typical usage:
+
+PyArrayObject *arr = NULL;
+PyArray_Descr *dtype = NULL;
+int ndim = 0;
+npy_intp dims[NPY_MAXDIMS];
+
+if (PyArray_GetArrayParamsFromObject(op, NULL, 1, &dtype,
+&ndim, dims, &arr, NULL) < 0) {
+return NULL;
+}
+if (arr == NULL) {
+... validate/change dtype, validate flags, ndim, etc ...
+// Could make custom strides here too
+arr = PyArray_NewFromDescr(&PyArray_Type, dtype, ndim,
+dims, NULL,
+is_f_order ? NPY_ARRAY_F_CONTIGUOUS : 0,
+NULL);
+if (arr == NULL) {
+return NULL;
+}
+if (PyArray_CopyObject(arr, op) < 0) {
+Py_DECREF(arr);
+return NULL;
+}
+}
+else {
+... in this case the other parameters weren't filled, just
+validate and possibly copy arr itself ...
+}
+... use arr ...
+
+::
+
+  int
+  PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE
+                                  *modes, int n)
+
+Convert an object to an array of n NPY_CLIPMODE values.
+This is intended to be used in functions where a different mode
+could be applied to each axis, like in ravel_multi_index.
+
+::
+
+  PyObject *
+  PyArray_MatrixProduct2(PyObject *op1, PyObject
+                         *op2, PyArrayObject*out)
+
+Numeric.matrixproduct2(a,v,out)
+just like inner product but does the swapaxes stuff on the fly
+
+::
+
+  npy_bool
+  NpyIter_IsFirstVisit(NpyIter *iter, int iop)
+
+Checks to see whether this is the first time the elements
+of the specified reduction operand which the iterator points at are
+being seen for the first time. The function returns
+a reasonable answer for reduction operands and when buffering is
+disabled. The answer may be incorrect for buffered non-reduction
+operands.
+
+This function is intended to be used in EXTERNAL_LOOP mode only,
+and will produce some wrong answers when that mode is not enabled.
+
+If this function returns true, the caller should also
+check the inner loop stride of the operand, because if
+that stride is 0, then only the first element of the innermost
+external loop is being visited for the first time.
+
+WARNING: For performance reasons, 'iop' is not bounds-checked,
+it is not confirmed that 'iop' is actually a reduction
+operand, and it is not confirmed that EXTERNAL_LOOP
+mode is enabled. These checks are the responsibility of
+the caller, and should be done outside of any inner loops.
+
+::
+
+  int
+  PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)
+
+Sets the 'base' attribute of the array. This steals a reference
+to 'obj'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void
+  PyArray_CreateSortedStridePerm(int ndim, npy_intp
+                                 *strides, npy_stride_sort_item
+                                 *out_strideperm)
+
+
+This function populates the first ndim elements
+of strideperm with sorted descending by their absolute values.
+For example, the stride array (4, -2, 12) becomes
+[(2, 12), (0, 4), (1, -2)].
+
+::
+
+  void
+  PyArray_RemoveAxesInPlace(PyArrayObject *arr, npy_bool *flags)
+
+
+Removes the axes flagged as True from the array,
+modifying it in place. If an axis flagged for removal
+has a shape entry bigger than one, this effectively selects
+index zero for that axis.
+
+WARNING: If an axis flagged for removal has a shape equal to zero,
+the array will point to invalid memory. The caller must
+validate this!
+If an axis flagged for removal has a shape larger then one,
+the aligned flag (and in the future the contiguous flags),
+may need explicite update.
+(check also NPY_RELAXED_STRIDES_CHECKING)
+
+For example, this can be used to remove the reduction axes
+from a reduction result once its computation is complete.
+
+::
+
+  void
+  PyArray_DebugPrint(PyArrayObject *obj)
+
+Prints the raw data of the ndarray in a form useful for debugging
+low-level C issues.
+
+::
+
+  int
+  PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)
+
+
+This function does nothing if obj is writeable, and raises an exception
+(and returns -1) if obj is not writeable. It may also do other
+house-keeping, such as issuing warnings on arrays which are transitioning
+to become views. Always call this function at some point before writing to
+an array.
+
+'name' is a name for the array, used to give better error
+messages. Something like "assignment destination", "output array", or even
+just "array".
+
+::
+
+  int
+  PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base)
+
+
+Precondition: 'arr' is a copy of 'base' (though possibly with different
+strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the
+->base pointer on 'arr', so that when 'arr' is destructed, it will copy any
+changes back to 'base'.
+
+Steals a reference to 'base'.
+
+Returns 0 on success, -1 on failure.
+
+::
+
+  void *
+  PyDataMem_NEW(size_t size)
+
+Allocates memory for array data.
+
+::
+
+  void
+  PyDataMem_FREE(void *ptr)
+
+Free memory for array data.
+
+::
+
+  void *
+  PyDataMem_RENEW(void *ptr, size_t size)
+
+Reallocate/resize memory for array data.
+
+::
+
+  PyDataMem_EventHookFunc *
+  PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void
+                         *user_data, void **old_data)
+
+Sets the allocation event hook for numpy array data.
+Takes a PyDataMem_EventHookFunc *, which has the signature:
+void hook(void *old, void *new, size_t size, void *user_data).
+Also takes a void *user_data, and void **old_data.
+
+Returns a pointer to the previous hook or NULL.  If old_data is
+non-NULL, the previous user_data pointer will be copied to it.
+
+If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW:
+result = PyDataMem_NEW(size)        -> (*hook)(NULL, result, size, user_data)
+PyDataMem_FREE(ptr)                 -> (*hook)(ptr, NULL, 0, user_data)
+result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data)
+
+When the hook is called, the GIL will be held by the calling
+thread.  The hook should be written to be reentrant, if it performs
+operations that might cause new allocation events (such as the
+creation/descruction numpy objects, or creating/destroying Python
+objects which might cause a gc)
+
+::
+
+  void
+  PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject
+                          **ret, int getmap)
+
+
+::
+
+  PyObject *
+  PyArray_MapIterArray(PyArrayObject *a, PyObject *index)
+
+
+Use advanced indexing to iterate an array. Please note
+that most of this public API is currently not guaranteed
+to stay the same between versions. If you plan on using
+it, please consider adding more utility functions here
+to accommodate new features.
+
+::
+
+  void
+  PyArray_MapIterNext(PyArrayMapIterObject *mit)
+
+This function needs to update the state of the map iterator
+and point mit->dataptr to the memory-location of the next object
+
+Note that this function never handles an extra operand but provides
+compatibility for an old (exposed) API.
+
+::
+
+  int
+  PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int
+                    axis, NPY_SELECTKIND which)
+
+Partition an array in-place
+
+::
+
+  PyObject *
+  PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int
+                       axis, NPY_SELECTKIND which)
+
+ArgPartition an array
+
+::
+
+  int
+  PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind)
+
+Convert object to select kind
+
+::
+
+  void *
+  PyDataMem_NEW_ZEROED(size_t size, size_t elsize)
+
+Allocates zeroed memory for array data.
+
+::
+
+  int
+  PyArray_CheckAnyScalarExact(PyObject *obj)
+
+return true an object is exactly a numpy scalar
+
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
new file mode 100644
index 0000000000..c97a3a797a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
@@ -0,0 +1,246 @@
+/*
+ * DON'T INCLUDE THIS DIRECTLY.
+ */
+
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#ifdef __cplusplus
+#define CONFUSE_EMACS {
+#define CONFUSE_EMACS2 }
+extern "C" CONFUSE_EMACS
+#undef CONFUSE_EMACS
+#undef CONFUSE_EMACS2
+/* ... otherwise a semi-smart identer (like emacs) tries to indent
+       everything when you're typing */
+#endif
+
+#include <Python.h>
+#include "ndarraytypes.h"
+
+/* Includes the "function" C-API -- these are all stored in a
+   list of pointers --- one for each file
+   The two lists are concatenated into one in multiarray.
+
+   They are available as import_array()
+*/
+
+#include "__multiarray_api.h"
+
+
+/* C-API that requries previous API to be defined */
+
+#define PyArray_DescrCheck(op) (((PyObject*)(op))->ob_type==&PyArrayDescr_Type)
+
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
+
+#define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
+        ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
+         (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
+         (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
+          Py_NotImplemented))
+
+#define PyArray_HasArrayInterface(op, out)                                    \
+        PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
+                               (PyArray_NDIM((PyArrayObject *)op) == 0))
+
+#define PyArray_IsScalar(obj, cls)                                            \
+        (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
+                                PyArray_IsZeroDim(m))
+#if PY_MAJOR_VERSION >= 3
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyFloat_Check(obj) || PyComplex_Check(obj) ||                        \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj)                       \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) ||                 \
+         PyUnicode_Check(obj))
+#else
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyInt_Check(obj) || PyFloat_Check(obj) || PyComplex_Check(obj) ||    \
+         PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyInt_Check(obj)                        \
+              || PyLong_Check(obj)                                            \
+              || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyString_Check(obj) ||                \
+         PyUnicode_Check(obj))
+#endif
+
+#define PyArray_IsAnyScalar(obj)                                              \
+        (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
+                                     PyArray_CheckScalar(obj))
+
+
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
+                                  Py_INCREF(m), (m) :                         \
+                                  (PyArrayObject *)(PyArray_Copy(m)))
+
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
+                                  PyArray_CompareLists(PyArray_DIMS(a1),      \
+                                                       PyArray_DIMS(a2),      \
+                                                       PyArray_NDIM(a1)))
+
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
+                                                      NULL)
+
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
+                                PyArray_DescrFromType(type), 0, 0, 0, NULL)
+
+#define PyArray_FROM_OTF(m, type, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
+
+#define PyArray_FROMANY(m, type, min, max, flags) \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
+                        (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+                         (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
+
+#define PyArray_ZEROS(m, dims, type, is_f_order) \
+        PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_EMPTY(m, dims, type, is_f_order) \
+        PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
+
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
+                                           PyArray_NBYTES(obj))
+
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
+
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT, NULL)
+
+#define PyArray_EquivArrTypes(a1, a2) \
+        PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+
+#define PyArray_EquivByteorders(b1, b2) \
+        (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+
+#define PyArray_SimpleNew(nd, dims, typenum) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
+                    data, 0, NPY_ARRAY_CARRAY, NULL)
+
+#define PyArray_SimpleNewFromDescr(nd, dims, descr) \
+        PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
+                             NULL, NULL, 0, NULL)
+
+#define PyArray_ToScalar(data, arr) \
+        PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+
+
+/* These might be faster without the dereferencing of obj
+   going on inside -- of course an optimizing compiler should
+   inline the constants inside a for loop making it a moot point
+*/
+
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
+                                         (i)*PyArray_STRIDES(obj)[0]))
+
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1]))
+
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2]))
+
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
+                                            (i)*PyArray_STRIDES(obj)[0] + \
+                                            (j)*PyArray_STRIDES(obj)[1] + \
+                                            (k)*PyArray_STRIDES(obj)[2] + \
+                                            (l)*PyArray_STRIDES(obj)[3]))
+
+static NPY_INLINE void
+PyArray_XDECREF_ERR(PyArrayObject *arr)
+{
+    if (arr != NULL) {
+        if (PyArray_FLAGS(arr) & NPY_ARRAY_UPDATEIFCOPY) {
+            PyArrayObject *base = (PyArrayObject *)PyArray_BASE(arr);
+            PyArray_ENABLEFLAGS(base, NPY_ARRAY_WRITEABLE);
+            PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
+        }
+        Py_DECREF(arr);
+    }
+}
+
+#define PyArray_DESCR_REPLACE(descr) do { \
+                PyArray_Descr *_new_; \
+                _new_ = PyArray_DescrNew(descr); \
+                Py_XDECREF(descr); \
+                descr = _new_; \
+        } while(0)
+
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+
+#define PyArray_FromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_BEHAVED | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                              max_depth, NPY_ARRAY_DEFAULT | \
+                                         NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+                        max_depth, NPY_ARRAY_ENSURECOPY | \
+                                   NPY_ARRAY_DEFAULT | \
+                                   NPY_ARRAY_ENSUREARRAY, NULL)
+
+#define PyArray_Cast(mp, type_num)                                            \
+        PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+
+#define PyArray_Take(ap, items, axis)                                         \
+        PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+
+#define PyArray_Put(ap, items, values)                                        \
+        PyArray_PutTo(ap, items, values, NPY_RAISE)
+
+/* Compatibility with old Numeric stuff -- don't use in new code */
+
+#define PyArray_FromDimsAndData(nd, d, type, data)                            \
+        PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
+                                        data)
+
+
+/*
+   Check to see if this key in the dictionary is the "title"
+   entry of the tuple (i.e. a duplicate dictionary entry in the fields
+   dict.
+*/
+
+#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \
+                                   (PyTuple_GET_ITEM((value), 2) == (key)))
+
+
+#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
+#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* NPY_NDARRAYOBJECT_H */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
new file mode 100644
index 0000000000..f1fe89f1a1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
@@ -0,0 +1,1793 @@
+#ifndef NDARRAYTYPES_H
+#define NDARRAYTYPES_H
+
+#include "npy_common.h"
+#include "npy_endian.h"
+#include "npy_cpu.h"
+#include "utils.h"
+
+#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN
+
+/* Only use thread if configured in config and python supports it */
+#if defined WITH_THREAD && !NPY_NO_SMP
+        #define NPY_ALLOW_THREADS 1
+#else
+        #define NPY_ALLOW_THREADS 0
+#endif
+
+
+
+/*
+ * There are several places in the code where an array of dimensions
+ * is allocated statically.  This is the size of that static
+ * allocation.
+ *
+ * The array creation itself could have arbitrary dimensions but all
+ * the places where static allocation is used would need to be changed
+ * to dynamic (including inside of several structures)
+ */
+
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+
+/*
+ * Binary compatibility version number.  This number is increased
+ * whenever the C-API is changed such that binary compatibility is
+ * broken, i.e. whenever a recompile of extension modules is needed.
+ */
+#define NPY_VERSION NPY_ABI_VERSION
+
+/*
+ * Minor API version.  This number is increased whenever a change is
+ * made to the C-API -- whether it breaks binary compatibility or not.
+ * Some changes, such as adding a function pointer to the end of the
+ * function table, can be made without breaking binary compatibility.
+ * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION)
+ * would be increased.  Whenever binary compatibility is broken, both
+ * NPY_VERSION and NPY_FEATURE_VERSION should be increased.
+ */
+#define NPY_FEATURE_VERSION NPY_API_VERSION
+
+enum NPY_TYPES {    NPY_BOOL=0,
+                    NPY_BYTE, NPY_UBYTE,
+                    NPY_SHORT, NPY_USHORT,
+                    NPY_INT, NPY_UINT,
+                    NPY_LONG, NPY_ULONG,
+                    NPY_LONGLONG, NPY_ULONGLONG,
+                    NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+                    NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+                    NPY_OBJECT=17,
+                    NPY_STRING, NPY_UNICODE,
+                    NPY_VOID,
+                    /*
+                     * New 1.6 types appended, may be integrated
+                     * into the above in 2.0.
+                     */
+                    NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF,
+
+                    NPY_NTYPES,
+                    NPY_NOTYPE,
+                    NPY_CHAR,      /* special flag */
+                    NPY_USERDEF=256,  /* leave room for characters */
+
+                    /* The number of types not including the new 1.6 types */
+                    NPY_NTYPES_ABI_COMPATIBLE=21
+};
+
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+
+/* How many floating point types are there (excluding half) */
+#define NPY_NUM_FLOATTYPE 3
+
+/*
+ * These characters correspond to the array type and the struct
+ * module
+ */
+
+enum NPY_TYPECHAR {
+        NPY_BOOLLTR = '?',
+        NPY_BYTELTR = 'b',
+        NPY_UBYTELTR = 'B',
+        NPY_SHORTLTR = 'h',
+        NPY_USHORTLTR = 'H',
+        NPY_INTLTR = 'i',
+        NPY_UINTLTR = 'I',
+        NPY_LONGLTR = 'l',
+        NPY_ULONGLTR = 'L',
+        NPY_LONGLONGLTR = 'q',
+        NPY_ULONGLONGLTR = 'Q',
+        NPY_HALFLTR = 'e',
+        NPY_FLOATLTR = 'f',
+        NPY_DOUBLELTR = 'd',
+        NPY_LONGDOUBLELTR = 'g',
+        NPY_CFLOATLTR = 'F',
+        NPY_CDOUBLELTR = 'D',
+        NPY_CLONGDOUBLELTR = 'G',
+        NPY_OBJECTLTR = 'O',
+        NPY_STRINGLTR = 'S',
+        NPY_STRINGLTR2 = 'a',
+        NPY_UNICODELTR = 'U',
+        NPY_VOIDLTR = 'V',
+        NPY_DATETIMELTR = 'M',
+        NPY_TIMEDELTALTR = 'm',
+        NPY_CHARLTR = 'c',
+
+        /*
+         * No Descriptor, just a define -- this let's
+         * Python users specify an array of integers
+         * large enough to hold a pointer on the
+         * platform
+         */
+        NPY_INTPLTR = 'p',
+        NPY_UINTPLTR = 'P',
+
+        /*
+         * These are for dtype 'kinds', not dtype 'typecodes'
+         * as the above are for.
+         */
+        NPY_GENBOOLLTR ='b',
+        NPY_SIGNEDLTR = 'i',
+        NPY_UNSIGNEDLTR = 'u',
+        NPY_FLOATINGLTR = 'f',
+        NPY_COMPLEXLTR = 'c'
+};
+
+typedef enum {
+        NPY_QUICKSORT=0,
+        NPY_HEAPSORT=1,
+        NPY_MERGESORT=2
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_MERGESORT + 1)
+
+
+typedef enum {
+        NPY_INTROSELECT=0
+} NPY_SELECTKIND;
+#define NPY_NSELECTS (NPY_INTROSELECT + 1)
+
+
+typedef enum {
+        NPY_SEARCHLEFT=0,
+        NPY_SEARCHRIGHT=1
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+
+
+typedef enum {
+        NPY_NOSCALAR=-1,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+
+/* For specifying array memory layout or iteration order */
+typedef enum {
+        /* Fortran order if inputs are all Fortran, C otherwise */
+        NPY_ANYORDER=-1,
+        /* C order */
+        NPY_CORDER=0,
+        /* Fortran order */
+        NPY_FORTRANORDER=1,
+        /* An order as close to the inputs as possible */
+        NPY_KEEPORDER=2
+} NPY_ORDER;
+
+/* For specifying allowed casting in operations which support it */
+typedef enum {
+        /* Only allow identical types */
+        NPY_NO_CASTING=0,
+        /* Allow identical and byte swapped types */
+        NPY_EQUIV_CASTING=1,
+        /* Only allow safe casts */
+        NPY_SAFE_CASTING=2,
+        /* Allow safe casts or casts within the same kind */
+        NPY_SAME_KIND_CASTING=3,
+        /* Allow any casts */
+        NPY_UNSAFE_CASTING=4
+} NPY_CASTING;
+
+typedef enum {
+        NPY_CLIP=0,
+        NPY_WRAP=1,
+        NPY_RAISE=2
+} NPY_CLIPMODE;
+
+/* The special not-a-time (NaT) value */
+#define NPY_DATETIME_NAT NPY_MIN_INT64
+
+/*
+ * Upper bound on the length of a DATETIME ISO 8601 string
+ *   YEAR: 21 (64-bit year)
+ *   MONTH: 3
+ *   DAY: 3
+ *   HOURS: 3
+ *   MINUTES: 3
+ *   SECONDS: 3
+ *   ATTOSECONDS: 1 + 3*6
+ *   TIMEZONE: 5
+ *   NULL TERMINATOR: 1
+ */
+#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1)
+
+typedef enum {
+        NPY_FR_Y = 0,  /* Years */
+        NPY_FR_M = 1,  /* Months */
+        NPY_FR_W = 2,  /* Weeks */
+        /* Gap where 1.6 NPY_FR_B (value 3) was */
+        NPY_FR_D = 4,  /* Days */
+        NPY_FR_h = 5,  /* hours */
+        NPY_FR_m = 6,  /* minutes */
+        NPY_FR_s = 7,  /* seconds */
+        NPY_FR_ms = 8, /* milliseconds */
+        NPY_FR_us = 9, /* microseconds */
+        NPY_FR_ns = 10,/* nanoseconds */
+        NPY_FR_ps = 11,/* picoseconds */
+        NPY_FR_fs = 12,/* femtoseconds */
+        NPY_FR_as = 13,/* attoseconds */
+        NPY_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */
+} NPY_DATETIMEUNIT;
+
+/*
+ * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS
+ *       is technically one more than the actual number of units.
+ */
+#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1)
+#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC
+
+/*
+ * Business day conventions for mapping invalid business
+ * days to valid business days.
+ */
+typedef enum {
+    /* Go forward in time to the following business day. */
+    NPY_BUSDAY_FORWARD,
+    NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD,
+    /* Go backward in time to the preceding business day. */
+    NPY_BUSDAY_BACKWARD,
+    NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD,
+    /*
+     * Go forward in time to the following business day, unless it
+     * crosses a month boundary, in which case go backward
+     */
+    NPY_BUSDAY_MODIFIEDFOLLOWING,
+    /*
+     * Go backward in time to the preceding business day, unless it
+     * crosses a month boundary, in which case go forward.
+     */
+    NPY_BUSDAY_MODIFIEDPRECEDING,
+    /* Produce a NaT for non-business days. */
+    NPY_BUSDAY_NAT,
+    /* Raise an exception for non-business days. */
+    NPY_BUSDAY_RAISE
+} NPY_BUSDAY_ROLL;
+
+/************************************************************
+ * NumPy Auxiliary Data for inner loops, sort functions, etc.
+ ************************************************************/
+
+/*
+ * When creating an auxiliary data struct, this should always appear
+ * as the first member, like this:
+ *
+ * typedef struct {
+ *     NpyAuxData base;
+ *     double constant;
+ * } constant_multiplier_aux_data;
+ */
+typedef struct NpyAuxData_tag NpyAuxData;
+
+/* Function pointers for freeing or cloning auxiliary data */
+typedef void (NpyAuxData_FreeFunc) (NpyAuxData *);
+typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *);
+
+struct NpyAuxData_tag {
+    NpyAuxData_FreeFunc *free;
+    NpyAuxData_CloneFunc *clone;
+    /* To allow for a bit of expansion without breaking the ABI */
+    void *reserved[2];
+};
+
+/* Macros to use for freeing and cloning auxiliary data */
+#define NPY_AUXDATA_FREE(auxdata) \
+    do { \
+        if ((auxdata) != NULL) { \
+            (auxdata)->free(auxdata); \
+        } \
+    } while(0)
+#define NPY_AUXDATA_CLONE(auxdata) \
+    ((auxdata)->clone(auxdata))
+
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+
+  /*
+   * Macros to define how array, and dimension/strides data is
+   * allocated.
+   */
+
+  /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */
+
+#define NPY_USE_PYMEM 1
+
+#if NPY_USE_PYMEM == 1
+#define PyArray_malloc PyMem_Malloc
+#define PyArray_free PyMem_Free
+#define PyArray_realloc PyMem_Realloc
+#else
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+#endif
+
+/* Dimensions and strides */
+#define PyDimMem_NEW(size)                                         \
+    ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+
+#define PyDimMem_RENEW(ptr,size)                                   \
+        ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+
+/* forward declaration */
+struct _PyArray_Descr;
+
+/* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+                                     npy_intp, int, void *);
+
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+
+
+/*
+ * These assume aligned and notswapped data -- a buffer will be used
+ * before or contiguous data will be obtained
+ */
+
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+                               npy_intp, void *);
+
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+                                       void *);
+
+/*
+ * XXX the ignore argument should be removed next time the API version
+ * is bumped. It used to be the separator.
+ */
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+                               char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+                                  struct _PyArray_Descr *);
+
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
+                                    npy_intp *, npy_intp *,
+                                    void *);
+typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
+                                       npy_intp *, npy_intp *,
+                                       void *);
+
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+
+typedef int (PyArray_ScalarKindFunc)(void *);
+
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in,
+                                       void *values, npy_intp nv);
+typedef int  (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray,
+                                       npy_intp nindarray, npy_intp n_outer,
+                                       npy_intp m_middle, npy_intp nelem,
+                                       NPY_CLIPMODE clipmode);
+
+typedef struct {
+        npy_intp *ptr;
+        int len;
+} PyArray_Dims;
+
+typedef struct {
+        /*
+         * Functions to cast to most other standard types
+         * Can have some NULL entries. The types
+         * DATETIME, TIMEDELTA, and HALF go into the castdict
+         * even though they are built-in.
+         */
+        PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
+
+        /* The next four functions *cannot* be NULL */
+
+        /*
+         * Functions to get and set items with standard Python types
+         * -- not array scalars
+         */
+        PyArray_GetItemFunc *getitem;
+        PyArray_SetItemFunc *setitem;
+
+        /*
+         * Copy and/or swap data.  Memory areas may not overlap
+         * Use memmove first if they might
+         */
+        PyArray_CopySwapNFunc *copyswapn;
+        PyArray_CopySwapFunc *copyswap;
+
+        /*
+         * Function to compare items
+         * Can be NULL
+         */
+        PyArray_CompareFunc *compare;
+
+        /*
+         * Function to select largest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmax;
+
+        /*
+         * Function to compute dot product
+         * Can be NULL
+         */
+        PyArray_DotFunc *dotfunc;
+
+        /*
+         * Function to scan an ASCII file and
+         * place a single value plus possible separator
+         * Can be NULL
+         */
+        PyArray_ScanFunc *scanfunc;
+
+        /*
+         * Function to read a single value from a string
+         * and adjust the pointer; Can be NULL
+         */
+        PyArray_FromStrFunc *fromstr;
+
+        /*
+         * Function to determine if data is zero or not
+         * If NULL a default version is
+         * used at Registration time.
+         */
+        PyArray_NonzeroFunc *nonzero;
+
+        /*
+         * Used for arange.
+         * Can be NULL.
+         */
+        PyArray_FillFunc *fill;
+
+        /*
+         * Function to fill arrays with scalar values
+         * Can be NULL
+         */
+        PyArray_FillWithScalarFunc *fillwithscalar;
+
+        /*
+         * Sorting functions
+         * Can be NULL
+         */
+        PyArray_SortFunc *sort[NPY_NSORTS];
+        PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+
+        /*
+         * Dictionary of additional casting functions
+         * PyArray_VectorUnaryFuncs
+         * which can be populated to support casting
+         * to other registered types. Can be NULL
+         */
+        PyObject *castdict;
+
+        /*
+         * Functions useful for generalizing
+         * the casting rules.
+         * Can be NULL;
+         */
+        PyArray_ScalarKindFunc *scalarkind;
+        int **cancastscalarkindto;
+        int *cancastto;
+
+        PyArray_FastClipFunc *fastclip;
+        PyArray_FastPutmaskFunc *fastputmask;
+        PyArray_FastTakeFunc *fasttake;
+
+        /*
+         * Function to select smallest
+         * Can be NULL
+         */
+        PyArray_ArgFunc *argmin;
+
+} PyArray_ArrFuncs;
+
+/* The item must be reference counted when it is inserted or extracted. */
+#define NPY_ITEM_REFCOUNT   0x01
+/* Same as needing REFCOUNT */
+#define NPY_ITEM_HASOBJECT  0x01
+/* Convert to list for pickling */
+#define NPY_LIST_PICKLE     0x02
+/* The item is a POINTER  */
+#define NPY_ITEM_IS_POINTER 0x04
+/* memory needs to be initialized for this data-type */
+#define NPY_NEEDS_INIT      0x08
+/* operations need Python C-API so don't give-up thread. */
+#define NPY_NEEDS_PYAPI     0x10
+/* Use f.getitem when extracting elements of this data-type */
+#define NPY_USE_GETITEM     0x20
+/* Use f.setitem when setting creating 0-d array from this data-type.*/
+#define NPY_USE_SETITEM     0x40
+/* A sticky flag specifically for structured arrays */
+#define NPY_ALIGNED_STRUCT  0x80
+
+/*
+ *These are inherited for global data-type if any data-types in the
+ * field have them
+ */
+#define NPY_FROM_FIELDS    (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \
+                            NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \
+                                NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+                                NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+
+#define PyDataType_FLAGCHK(dtype, flag) \
+        (((dtype)->flags & (flag)) == (flag))
+
+#define PyDataType_REFCHK(dtype) \
+        PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+
+typedef struct _PyArray_Descr {
+        PyObject_HEAD
+        /*
+         * the type object representing an
+         * instance of this type -- should not
+         * be two type_numbers with the same type
+         * object.
+         */
+        PyTypeObject *typeobj;
+        /* kind for this type */
+        char kind;
+        /* unique-character representing this type */
+        char type;
+        /*
+         * '>' (big), '<' (little), '|'
+         * (not-applicable), or '=' (native).
+         */
+        char byteorder;
+        /* flags describing data type */
+        char flags;
+        /* number representing this type */
+        int type_num;
+        /* element size (itemsize) for this type */
+        int elsize;
+        /* alignment needed for this type */
+        int alignment;
+        /*
+         * Non-NULL if this type is
+         * is an array (C-contiguous)
+         * of some other type
+         */
+        struct _arr_descr *subarray;
+        /*
+         * The fields dictionary for this type
+         * For statically defined descr this
+         * is always Py_None
+         */
+        PyObject *fields;
+        /*
+         * An ordered tuple of field names or NULL
+         * if no fields are defined
+         */
+        PyObject *names;
+        /*
+         * a table of functions specific for each
+         * basic data descriptor
+         */
+        PyArray_ArrFuncs *f;
+        /* Metadata about this dtype */
+        PyObject *metadata;
+        /*
+         * Metadata specific to the C implementation
+         * of the particular dtype. This was added
+         * for NumPy 1.7.0.
+         */
+        NpyAuxData *c_metadata;
+        /* Cached hash value (-1 if not yet computed).
+         * This was added for NumPy 2.0.0.
+         */
+        npy_hash_t hash;
+} PyArray_Descr;
+
+typedef struct _arr_descr {
+        PyArray_Descr *base;
+        PyObject *shape;       /* a tuple */
+} PyArray_ArrayDescr;
+
+/*
+ * The main array object structure.
+ *
+ * It has been recommended to use the inline functions defined below
+ * (PyArray_DATA and friends) to access fields here for a number of
+ * releases. Direct access to the members themselves is deprecated.
+ * To ensure that your code does not use deprecated access,
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
+ */
+/* This struct will be moved to a private header in a future release */
+typedef struct tagPyArrayObject_fields {
+    PyObject_HEAD
+    /* Pointer to the raw data buffer */
+    char *data;
+    /* The number of dimensions, also called 'ndim' */
+    int nd;
+    /* The size in each dimension, also called 'shape' */
+    npy_intp *dimensions;
+    /*
+     * Number of bytes to jump to get to the
+     * next element in each dimension
+     */
+    npy_intp *strides;
+    /*
+     * This object is decref'd upon
+     * deletion of array. Except in the
+     * case of UPDATEIFCOPY which has
+     * special handling.
+     *
+     * For views it points to the original
+     * array, collapsed so no chains of
+     * views occur.
+     *
+     * For creation from buffer object it
+     * points to an object that shold be
+     * decref'd on deletion
+     *
+     * For UPDATEIFCOPY flag this is an
+     * array to-be-updated upon deletion
+     * of this one
+     */
+    PyObject *base;
+    /* Pointer to type structure */
+    PyArray_Descr *descr;
+    /* Flags describing array -- see below */
+    int flags;
+    /* For weak references */
+    PyObject *weakreflist;
+} PyArrayObject_fields;
+
+/*
+ * To hide the implementation details, we only expose
+ * the Python struct HEAD.
+ */
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+/*
+ * Can't put this in npy_deprecated_api.h like the others.
+ * PyArrayObject field access is deprecated as of NumPy 1.7.
+ */
+typedef PyArrayObject_fields PyArrayObject;
+#else
+typedef struct tagPyArrayObject {
+        PyObject_HEAD
+} PyArrayObject;
+#endif
+
+#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
+
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+        PyObject_HEAD
+        PyObject *arr;
+        int flags;
+} PyArrayFlagsObject;
+
+/* Mirrors buffer object to ptr */
+
+typedef struct {
+        PyObject_HEAD
+        PyObject *base;
+        void *ptr;
+        npy_intp len;
+        int flags;
+} PyArray_Chunk;
+
+typedef struct {
+    NPY_DATETIMEUNIT base;
+    int num;
+} PyArray_DatetimeMetaData;
+
+typedef struct {
+    NpyAuxData base;
+    PyArray_DatetimeMetaData meta;
+} PyArray_DatetimeDTypeMetaData;
+
+/*
+ * This structure contains an exploded view of a date-time value.
+ * NaT is represented by year == NPY_DATETIME_NAT.
+ */
+typedef struct {
+        npy_int64 year;
+        npy_int32 month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+
+/* This is not used internally. */
+typedef struct {
+        npy_int64 day;
+        npy_int32 sec, us, ps, as;
+} npy_timedeltastruct;
+
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+
+/*
+ * Means c-style contiguous (last index varies the fastest). The data
+ * elements right after each other.
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_C_CONTIGUOUS    0x0001
+
+/*
+ * Set if array is a contiguous Fortran array: the first index varies
+ * the fastest in memory (strides array is reverse of C-contiguous
+ * array)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_F_CONTIGUOUS    0x0002
+
+/*
+ * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a
+ * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
+ * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
+ * at the same time if they have either zero or one element.
+ * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
+ * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
+ * and the array is contiguous if ndarray.squeeze() is contiguous.
+ * I.e. dimensions for which `ndarray.shape[dimension] == 1` are
+ * ignored.
+ */
+
+/*
+ * If set, the array owns the data: it will be free'd when the array
+ * is deleted.
+ *
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_OWNDATA         0x0004
+
+/*
+ * An array never has the next four set; they're only used as parameter
+ * flags to the the various FromAny functions
+ *
+ * This flag may be requested in constructor functions.
+ */
+
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_ARRAY_FORCECAST       0x0010
+
+/*
+ * Always copy the array. Returned arrays are always CONTIGUOUS,
+ * ALIGNED, and WRITEABLE.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSURECOPY      0x0020
+
+/*
+ * Make sure the returned array is a base-class ndarray
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ENSUREARRAY     0x0040
+
+/*
+ * Make sure that the strides are in units of the element size Needed
+ * for some operations with record-arrays.
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_ELEMENTSTRIDES  0x0080
+
+/*
+ * Array data is aligned on the appropiate memory address for the type
+ * stored according to how the compiler would align things (e.g., an
+ * array of integers (4 bytes each) starts on a memory address that's
+ * a multiple of 4)
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_ALIGNED         0x0100
+
+/*
+ * Array data has the native endianness
+ *
+ * This flag may be requested in constructor functions.
+ */
+#define NPY_ARRAY_NOTSWAPPED      0x0200
+
+/*
+ * Array data is writeable
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_WRITEABLE       0x0400
+
+/*
+ * If this flag is set, then base contains a pointer to an array of
+ * the same size that should be updated with the current contents of
+ * this array when this array is deallocated
+ *
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+ */
+#define NPY_ARRAY_UPDATEIFCOPY    0x1000
+
+/*
+ * NOTE: there are also internal flags defined in multiarray/arrayobject.h,
+ * which start at bit 31 and work down.
+ */
+
+#define NPY_ARRAY_BEHAVED      (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE)
+#define NPY_ARRAY_BEHAVED_NS   (NPY_ARRAY_ALIGNED | \
+                                NPY_ARRAY_WRITEABLE | \
+                                NPY_ARRAY_NOTSWAPPED)
+#define NPY_ARRAY_CARRAY       (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_CARRAY_RO    (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_FARRAY       (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_FARRAY_RO    (NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_DEFAULT      (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_IN_ARRAY     (NPY_ARRAY_CARRAY_RO)
+#define NPY_ARRAY_OUT_ARRAY    (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_INOUT_ARRAY  (NPY_ARRAY_CARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+#define NPY_ARRAY_IN_FARRAY    (NPY_ARRAY_FARRAY_RO)
+#define NPY_ARRAY_OUT_FARRAY   (NPY_ARRAY_FARRAY)
+#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \
+                                NPY_ARRAY_UPDATEIFCOPY)
+
+#define NPY_ARRAY_UPDATE_ALL   (NPY_ARRAY_C_CONTIGUOUS | \
+                                NPY_ARRAY_F_CONTIGUOUS | \
+                                NPY_ARRAY_ALIGNED)
+
+/* This flag is for the array interface, not PyArrayObject */
+#define NPY_ARR_HAS_DESCR  0x0800
+
+
+
+
+/*
+ * Size of internal buffers used for alignment Make BUFSIZE a multiple
+ * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned
+ */
+#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000)
+#define NPY_BUFSIZE 8192
+/* buffer stress test size: */
+/*#define NPY_BUFSIZE 17*/
+
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+
+/*
+ * C API: consists of Macros and functions.  The MACROS are defined
+ * here.
+ */
+
+
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED)
+
+#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS)
+
+/* the variable is used in some places, so always define it */
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+#define NPY_END_THREADS   do { if (_save) \
+                { PyEval_RestoreThread(_save); _save = NULL;} } while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+                { _save = PyEval_SaveThread();} } while (0);
+
+#define NPY_BEGIN_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_BEGIN_THREADS;} while (0);
+
+#define NPY_END_THREADS_DESCR(dtype) \
+        do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
+                NPY_END_THREADS; } while (0);
+
+#define NPY_ALLOW_C_API_DEF  PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API      do {__save__ = PyGILState_Ensure();} while (0);
+#define NPY_DISABLE_C_API    do {PyGILState_Release(__save__);} while (0);
+#else
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size)
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+#endif
+
+/**********************************
+ * The nditer object, added in 1.6
+ **********************************/
+
+/* The actual structure of the iterator is an internal detail */
+typedef struct NpyIter_InternalOnly NpyIter;
+
+/* Iterator function pointers that may be specialized */
+typedef int (NpyIter_IterNextFunc)(NpyIter *iter);
+typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter,
+                                      npy_intp *outcoords);
+
+/*** Global flags that may be passed to the iterator constructors ***/
+
+/* Track an index representing C order */
+#define NPY_ITER_C_INDEX                    0x00000001
+/* Track an index representing Fortran order */
+#define NPY_ITER_F_INDEX                    0x00000002
+/* Track a multi-index */
+#define NPY_ITER_MULTI_INDEX                0x00000004
+/* User code external to the iterator does the 1-dimensional innermost loop */
+#define NPY_ITER_EXTERNAL_LOOP              0x00000008
+/* Convert all the operands to a common data type */
+#define NPY_ITER_COMMON_DTYPE               0x00000010
+/* Operands may hold references, requiring API access during iteration */
+#define NPY_ITER_REFS_OK                    0x00000020
+/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */
+#define NPY_ITER_ZEROSIZE_OK                0x00000040
+/* Permits reductions (size-0 stride with dimension size > 1) */
+#define NPY_ITER_REDUCE_OK                  0x00000080
+/* Enables sub-range iteration */
+#define NPY_ITER_RANGED                     0x00000100
+/* Enables buffering */
+#define NPY_ITER_BUFFERED                   0x00000200
+/* When buffering is enabled, grows the inner loop if possible */
+#define NPY_ITER_GROWINNER                  0x00000400
+/* Delay allocation of buffers until first Reset* call */
+#define NPY_ITER_DELAY_BUFALLOC             0x00000800
+/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */
+#define NPY_ITER_DONT_NEGATE_STRIDES        0x00001000
+
+/*** Per-operand flags that may be passed to the iterator constructors ***/
+
+/* The operand will be read from and written to */
+#define NPY_ITER_READWRITE                  0x00010000
+/* The operand will only be read from */
+#define NPY_ITER_READONLY                   0x00020000
+/* The operand will only be written to */
+#define NPY_ITER_WRITEONLY                  0x00040000
+/* The operand's data must be in native byte order */
+#define NPY_ITER_NBO                        0x00080000
+/* The operand's data must be aligned */
+#define NPY_ITER_ALIGNED                    0x00100000
+/* The operand's data must be contiguous (within the inner loop) */
+#define NPY_ITER_CONTIG                     0x00200000
+/* The operand may be copied to satisfy requirements */
+#define NPY_ITER_COPY                       0x00400000
+/* The operand may be copied with UPDATEIFCOPY to satisfy requirements */
+#define NPY_ITER_UPDATEIFCOPY               0x00800000
+/* Allocate the operand if it is NULL */
+#define NPY_ITER_ALLOCATE                   0x01000000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE                 0x02000000
+/* This is a virtual array slot, operand is NULL but temporary data is there */
+#define NPY_ITER_VIRTUAL                    0x04000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST               0x08000000
+/* A mask is being used on this array, affects buffer -> array copy */
+#define NPY_ITER_WRITEMASKED                0x10000000
+/* This array is the mask for all WRITEMASKED operands */
+#define NPY_ITER_ARRAYMASK                  0x20000000
+
+#define NPY_ITER_GLOBAL_FLAGS               0x0000ffff
+#define NPY_ITER_PER_OP_FLAGS               0xffff0000
+
+
+/*****************************
+ * Basic iterator object
+ *****************************/
+
+/* FWD declaration */
+typedef struct PyArrayIterObject_tag PyArrayIterObject;
+
+/*
+ * type of the function which translates a set of coordinates to a
+ * pointer to the data
+ */
+typedef char* (*npy_iter_get_dataptr_t)(PyArrayIterObject* iter, npy_intp*);
+
+struct PyArrayIterObject_tag {
+        PyObject_HEAD
+        int               nd_m1;            /* number of dimensions - 1 */
+        npy_intp          index, size;
+        npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+        npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+        npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+        npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+        npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+        PyArrayObject     *ao;
+        char              *dataptr;        /* pointer to current item*/
+        npy_bool          contiguous;
+
+        npy_intp          bounds[NPY_MAXDIMS][2];
+        npy_intp          limits[NPY_MAXDIMS][2];
+        npy_intp          limits_sizes[NPY_MAXDIMS];
+        npy_iter_get_dataptr_t translate;
+} ;
+
+
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) do { \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        memset(_PyAIT(it)->coordinates, 0, \
+               (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \
+} while (0)
+
+#define _PyArray_ITER_NEXT1(it) do { \
+        (it)->dataptr += _PyAIT(it)->strides[0]; \
+        (it)->coordinates[0]++; \
+} while (0)
+
+#define _PyArray_ITER_NEXT2(it) do { \
+        if ((it)->coordinates[1] < (it)->dims_m1[1]) { \
+                (it)->coordinates[1]++; \
+                (it)->dataptr += (it)->strides[1]; \
+        } \
+        else { \
+                (it)->coordinates[1] = 0; \
+                (it)->coordinates[0]++; \
+                (it)->dataptr += (it)->strides[0] - \
+                        (it)->backstrides[1]; \
+        } \
+} while (0)
+
+#define PyArray_ITER_NEXT(it) do { \
+        _PyAIT(it)->index++; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyArray_ITER_NEXT1(_PyAIT(it)); \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else if (_PyAIT(it)->nd_m1 == 1) { \
+                _PyArray_ITER_NEXT2(_PyAIT(it)); \
+        } \
+        else { \
+                int __npy_i; \
+                for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+                        if (_PyAIT(it)->coordinates[__npy_i] < \
+                            _PyAIT(it)->dims_m1[__npy_i]) { \
+                                _PyAIT(it)->coordinates[__npy_i]++; \
+                                _PyAIT(it)->dataptr += \
+                                        _PyAIT(it)->strides[__npy_i]; \
+                                break; \
+                        } \
+                        else { \
+                                _PyAIT(it)->coordinates[__npy_i] = 0; \
+                                _PyAIT(it)->dataptr -= \
+                                        _PyAIT(it)->backstrides[__npy_i]; \
+                        } \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO(it, destination) do { \
+        int __npy_i; \
+        _PyAIT(it)->index = 0; \
+        _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+        for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \
+                if (destination[__npy_i] < 0) { \
+                        destination[__npy_i] += \
+                                _PyAIT(it)->dims_m1[__npy_i]+1; \
+                } \
+                _PyAIT(it)->dataptr += destination[__npy_i] * \
+                        _PyAIT(it)->strides[__npy_i]; \
+                _PyAIT(it)->coordinates[__npy_i] = \
+                        destination[__npy_i]; \
+                _PyAIT(it)->index += destination[__npy_i] * \
+                        ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \
+                          _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \
+        } \
+} while (0)
+
+#define PyArray_ITER_GOTO1D(it, ind) do { \
+        int __npy_i; \
+        npy_intp __npy_ind = (npy_intp) (ind); \
+        if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \
+        _PyAIT(it)->index = __npy_ind; \
+        if (_PyAIT(it)->nd_m1 == 0) { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * _PyAIT(it)->strides[0]; \
+        } \
+        else if (_PyAIT(it)->contiguous) \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+                        __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+        else { \
+                _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+                for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
+                     __npy_i++) { \
+                        _PyAIT(it)->dataptr += \
+                                (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+                                * _PyAIT(it)->strides[__npy_i]; \
+                        __npy_ind %= _PyAIT(it)->factors[__npy_i]; \
+                } \
+        } \
+} while (0)
+
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+
+
+/*
+ * Any object passed to PyArray_Broadcast must be binary compatible
+ * with this structure.
+ */
+
+typedef struct {
+        PyObject_HEAD
+        int                  numiter;                 /* number of iters */
+        npy_intp             size;                    /* broadcasted size */
+        npy_intp             index;                   /* current index */
+        int                  nd;                      /* number of dims */
+        npy_intp             dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject    *iters[NPY_MAXARGS];     /* iterators */
+} PyArrayMultiIterObject;
+
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) do {                                   \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index = 0;                                             \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;  __npy_mi++) {    \
+                PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]);           \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_NEXT(multi) do {                                    \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index++;                                               \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;   __npy_mi++) {   \
+                PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]);            \
+        }                                                                     \
+} while (0)
+
+#define PyArray_MultiIter_GOTO(multi, dest) do {                            \
+        int __npy_mi;                                                       \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {   \
+                PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest);    \
+        }                                                                   \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;              \
+} while (0)
+
+#define PyArray_MultiIter_GOTO1D(multi, ind) do {                          \
+        int __npy_mi;                                                      \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {  \
+                PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind);  \
+        }                                                                  \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;             \
+} while (0)
+
+#define PyArray_MultiIter_DATA(multi, i)                \
+        ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+
+#define PyArray_MultiIter_NEXTi(multi, i)               \
+        PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+
+#define PyArray_MultiIter_NOTDONE(multi)                \
+        (_PyMIT(multi)->index < _PyMIT(multi)->size)
+
+
+/*
+ * Store the information needed for fancy-indexing over an array. The
+ * fields are slightly unordered to keep consec, dataptr and subspace
+ * where they were originally.
+ */
+typedef struct {
+        PyObject_HEAD
+        /*
+         * Multi-iterator portion --- needs to be present in this
+         * order to work with PyArray_Broadcast
+         */
+
+        int                   numiter;                 /* number of index-array
+                                                          iterators */
+        npy_intp              size;                    /* size of broadcasted
+                                                          result */
+        npy_intp              index;                   /* current index */
+        int                   nd;                      /* number of dims */
+        npy_intp              dimensions[NPY_MAXDIMS]; /* dimensions */
+        NpyIter               *outer;                  /* index objects
+                                                          iterator */
+        void                  *unused[NPY_MAXDIMS - 2];
+        PyArrayObject         *array;
+        /* Flat iterator for the indexed array. For compatibility solely. */
+        PyArrayIterObject     *ait;
+
+        /*
+         * Subspace array. For binary compatibility (was an iterator,
+         * but only the check for NULL should be used).
+         */
+        PyArrayObject         *subspace;
+
+        /*
+         * if subspace iteration, then this is the array of axes in
+         * the underlying array represented by the index objects
+         */
+        int                   iteraxes[NPY_MAXDIMS];
+        npy_intp              fancy_strides[NPY_MAXDIMS];
+
+        /* pointer when all fancy indices are 0 */
+        char                  *baseoffset;
+
+        /*
+         * after binding consec denotes at which axis the fancy axes
+         * are inserted.
+         */
+        int                   consec;
+        char                  *dataptr;
+
+        int                   nd_fancy;
+        npy_intp              fancy_dims[NPY_MAXDIMS];
+
+        /* Whether the iterator (any of the iterators) requires API */
+        int                   needs_api;
+
+        /*
+         * Extra op information.
+         */
+        PyArrayObject         *extra_op;
+        PyArray_Descr         *extra_op_dtype;         /* desired dtype */
+        npy_uint32            *extra_op_flags;         /* Iterator flags */
+
+        NpyIter               *extra_op_iter;
+        NpyIter_IterNextFunc  *extra_op_next;
+        char                  **extra_op_ptrs;
+
+        /*
+         * Information about the iteration state.
+         */
+        NpyIter_IterNextFunc  *outer_next;
+        char                  **outer_ptrs;
+        npy_intp              *outer_strides;
+
+        /*
+         * Information about the subspace iterator.
+         */
+        NpyIter               *subspace_iter;
+        NpyIter_IterNextFunc  *subspace_next;
+        char                  **subspace_ptrs;
+        npy_intp              *subspace_strides;
+
+        /* Count for the external loop (which ever it is) for API iteration */
+        npy_intp              iter_count;
+
+} PyArrayMapIterObject;
+
+enum {
+    NPY_NEIGHBORHOOD_ITER_ZERO_PADDING,
+    NPY_NEIGHBORHOOD_ITER_ONE_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING,
+    NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING,
+    NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING
+};
+
+typedef struct {
+    PyObject_HEAD
+
+    /*
+     * PyArrayIterObject part: keep this in this exact order
+     */
+    int               nd_m1;            /* number of dimensions - 1 */
+    npy_intp          index, size;
+    npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+    npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+    npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+    npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+    npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+    PyArrayObject     *ao;
+    char              *dataptr;        /* pointer to current item*/
+    npy_bool          contiguous;
+
+    npy_intp          bounds[NPY_MAXDIMS][2];
+    npy_intp          limits[NPY_MAXDIMS][2];
+    npy_intp          limits_sizes[NPY_MAXDIMS];
+    npy_iter_get_dataptr_t translate;
+
+    /*
+     * New members
+     */
+    npy_intp nd;
+
+    /* Dimensions is the dimension of the array */
+    npy_intp dimensions[NPY_MAXDIMS];
+
+    /*
+     * Neighborhood points coordinates are computed relatively to the
+     * point pointed by _internal_iter
+     */
+    PyArrayIterObject* _internal_iter;
+    /*
+     * To keep a reference to the representation of the constant value
+     * for constant padding
+     */
+    char* constant;
+
+    int mode;
+} PyArrayNeighborhoodIterObject;
+
+/*
+ * Neighborhood iterator API
+ */
+
+/* General: those work for any mode */
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter);
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter);
+#if 0
+static NPY_INLINE int
+PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
+#endif
+
+/*
+ * Include inline implementations - functions defined there are not
+ * considered public API
+ */
+#define _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#include "_neighborhood_iterator_imp.h"
+#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+
+/* The default array type */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+
+/*
+ * All sorts of useful ways to look into a PyArrayObject. It is recommended
+ * to use PyArrayObject * objects instead of always casting from PyObject *,
+ * for improved type checking.
+ *
+ * In many cases here the macro versions of the accessors are deprecated,
+ * but can't be immediately changed to inline functions because the
+ * preexisting macros accept PyObject * and do automatic casts. Inline
+ * functions accepting PyArrayObject * provides for some compile-time
+ * checking of correctness when working with these objects in C.
+ */
+
+#define PyArray_ISONESEGMENT(m) (PyArray_NDIM(m) == 0 || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \
+                             PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS))
+
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \
+                             (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)))
+
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
+                               NPY_ARRAY_F_CONTIGUOUS : 0))
+
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
+/*
+ * Changing access macros into functions, to allow for future hiding
+ * of the internal memory layout. This later hiding will allow the 2.x series
+ * to change the internal representation of arrays without affecting
+ * ABI compatibility.
+ */
+
+static NPY_INLINE int
+PyArray_NDIM(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->nd;
+}
+
+static NPY_INLINE void *
+PyArray_DATA(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE char *
+PyArray_BYTES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->data;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_DIMS(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_STRIDES(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->strides;
+}
+
+static NPY_INLINE npy_intp
+PyArray_DIM(const PyArrayObject *arr, int idim)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions[idim];
+}
+
+static NPY_INLINE npy_intp
+PyArray_STRIDE(const PyArrayObject *arr, int istride)
+{
+    return ((PyArrayObject_fields *)arr)->strides[istride];
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject *
+PyArray_BASE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->base;
+}
+
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr *
+PyArray_DESCR(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE int
+PyArray_FLAGS(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->flags;
+}
+
+static NPY_INLINE npy_intp
+PyArray_ITEMSIZE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->elsize;
+}
+
+static NPY_INLINE int
+PyArray_TYPE(const PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->type_num;
+}
+
+static NPY_INLINE int
+PyArray_CHKFLAGS(const PyArrayObject *arr, int flags)
+{
+    return (PyArray_FLAGS(arr) & flags) == flags;
+}
+
+static NPY_INLINE PyObject *
+PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->getitem(
+                                        (void *)itemptr, (PyArrayObject *)arr);
+}
+
+static NPY_INLINE int
+PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v)
+{
+    return ((PyArrayObject_fields *)arr)->descr->f->setitem(
+                                                        v, itemptr, arr);
+}
+
+#else
+
+/* These macros are deprecated as of NumPy 1.7. */
+#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd)
+#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags)
+#define PyArray_CHKFLAGS(m, FLAGS) \
+        ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS))
+#define PyArray_ITEMSIZE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) \
+                    (((PyArrayObject_fields *)(obj))->descr->type_num)
+#define PyArray_GETITEM(obj,itemptr) \
+        PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+
+#define PyArray_SETITEM(obj,itemptr,v) \
+        PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \
+                                     (char *)(itemptr), \
+                                     (PyArrayObject *)(obj))
+#endif
+
+static NPY_INLINE PyArray_Descr *
+PyArray_DTYPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->descr;
+}
+
+static NPY_INLINE npy_intp *
+PyArray_SHAPE(PyArrayObject *arr)
+{
+    return ((PyArrayObject_fields *)arr)->dimensions;
+}
+
+/*
+ * Enables the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags |= flags;
+}
+
+/*
+ * Clears the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+ */
+static NPY_INLINE void
+PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)
+{
+    ((PyArrayObject_fields *)arr)->flags &= ~flags;
+}
+
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) ||   \
+                                 ((type) == NPY_USHORT) ||     \
+                                 ((type) == NPY_UINT) ||       \
+                                 ((type) == NPY_ULONG) ||      \
+                                 ((type) == NPY_ULONGLONG))
+
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) ||      \
+                               ((type) == NPY_SHORT) ||        \
+                               ((type) == NPY_INT) ||          \
+                               ((type) == NPY_LONG) ||         \
+                               ((type) == NPY_LONGLONG))
+
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) &&     \
+                                ((type) <= NPY_ULONGLONG))
+
+#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \
+                              ((type) <= NPY_LONGDOUBLE)) || \
+                              ((type) == NPY_HALF))
+
+#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \
+                                  ((type) == NPY_HALF))
+
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) ||    \
+                                  ((type) == NPY_UNICODE))
+
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) &&   \
+                                ((type) <= NPY_CLONGDOUBLE))
+
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) ||      \
+                                  ((type) == NPY_DOUBLE) ||    \
+                                  ((type) == NPY_CDOUBLE) ||   \
+                                  ((type) == NPY_BOOL) ||      \
+                                  ((type) == NPY_OBJECT ))
+
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) &&  \
+                                    ((type) <=NPY_VOID))
+
+#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) &&  \
+                                    ((type) <=NPY_TIMEDELTA))
+
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+                                   ((type) < NPY_USERDEF+     \
+                                    NPY_NUMUSERTYPES))
+
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) ||  \
+                                    PyTypeNum_ISUSERDEF(type))
+
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+
+
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(_PyADt(obj))
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL)
+
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+
+    /*
+     * FIXME: This should check for a flag on the data-type that
+     * states whether or not it is variable length.  Because the
+     * ISFLEXIBLE check is hard-coded to the built-in data-types.
+     */
+#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+
+#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj))
+
+
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#else
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#endif
+
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) &&       \
+                                    PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED)
+
+
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+
+/************************************************************
+ * A struct used by PyArray_CreateSortedStridePerm, new in 1.7.
+ ************************************************************/
+
+typedef struct {
+    npy_intp perm, stride;
+} npy_stride_sort_item;
+
+/************************************************************
+ * This is the form of the struct that's returned pointed by the
+ * PyCObject attribute of an array __array_struct__. See
+ * http://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full
+ * documentation.
+ ************************************************************/
+typedef struct {
+    int two;              /*
+                           * contains the integer 2 as a sanity
+                           * check
+                           */
+
+    int nd;               /* number of dimensions */
+
+    char typekind;        /*
+                           * kind in array --- character code of
+                           * typestr
+                           */
+
+    int itemsize;         /* size of each element */
+
+    int flags;            /*
+                           * how should be data interpreted. Valid
+                           * flags are CONTIGUOUS (1), F_CONTIGUOUS (2),
+                           * ALIGNED (0x100), NOTSWAPPED (0x200), and
+                           * WRITEABLE (0x400).  ARR_HAS_DESCR (0x800)
+                           * states that arrdescr field is present in
+                           * structure
+                           */
+
+    npy_intp *shape;       /*
+                            * A length-nd array of shape
+                            * information
+                            */
+
+    npy_intp *strides;    /* A length-nd array of stride information */
+
+    void *data;           /* A pointer to the first element of the array */
+
+    PyObject *descr;      /*
+                           * A list of fields or NULL (ignored if flags
+                           * does not have ARR_HAS_DESCR flag set)
+                           */
+} PyArrayInterface;
+
+/*
+ * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions.
+ * See the documentation for PyDataMem_SetEventHook.
+ */
+typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
+                                       void *user_data);
+
+/*
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+ */
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
+#endif
+#define NPY_DEPRECATED_INCLUDES
+#if !defined(NPY_NO_DEPRECATED_API) || \
+    (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+#include "npy_1_7_deprecated_api.h"
+#endif
+/*
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ *
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ *
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ *     (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+ */
+#undef NPY_DEPRECATED_INCLUDES
+
+#endif /* NPY_ARRAYTYPES_H */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
new file mode 100644
index 0000000000..8306170876
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
@@ -0,0 +1,209 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+
+/*
+ * You can directly include noprefix.h as a backward
+ * compatibility measure
+ */
+#ifndef NPY_NO_PREFIX
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+#endif
+
+#define SIGSETJMP   NPY_SIGSETJMP
+#define SIGLONGJMP  NPY_SIGLONGJMP
+#define SIGJMP_BUF  NPY_SIGJMP_BUF
+
+#define MAX_DIMS NPY_MAXDIMS
+
+#define longlong    npy_longlong
+#define ulonglong   npy_ulonglong
+#define Bool        npy_bool
+#define longdouble  npy_longdouble
+#define byte        npy_byte
+
+#ifndef _BSD_SOURCE
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#endif
+
+#define ubyte       npy_ubyte
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#define cfloat      npy_cfloat
+#define cdouble     npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8        npy_int8
+#define UInt8       npy_uint8
+#define Int16       npy_int16
+#define UInt16      npy_uint16
+#define Int32       npy_int32
+#define UInt32      npy_uint32
+#define Int64       npy_int64
+#define UInt64      npy_uint64
+#define Int128      npy_int128
+#define UInt128     npy_uint128
+#define Int256      npy_int256
+#define UInt256     npy_uint256
+#define Float16     npy_float16
+#define Complex32   npy_complex32
+#define Float32     npy_float32
+#define Complex64   npy_complex64
+#define Float64     npy_float64
+#define Complex128  npy_complex128
+#define Float80     npy_float80
+#define Complex160  npy_complex160
+#define Float96     npy_float96
+#define Complex192  npy_complex192
+#define Float128    npy_float128
+#define Complex256  npy_complex256
+#define intp        npy_intp
+#define uintp       npy_uintp
+#define datetime    npy_datetime
+#define timedelta   npy_timedelta
+
+#define SIZEOF_LONGLONG         NPY_SIZEOF_LONGLONG
+#define SIZEOF_INTP             NPY_SIZEOF_INTP
+#define SIZEOF_UINTP            NPY_SIZEOF_UINTP
+#define SIZEOF_HALF             NPY_SIZEOF_HALF
+#define SIZEOF_LONGDOUBLE       NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_DATETIME         NPY_SIZEOF_DATETIME
+#define SIZEOF_TIMEDELTA        NPY_SIZEOF_TIMEDELTA
+
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX
+
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT   NPY_MAX_INT
+#define MIN_INT   NPY_MIN_INT
+#define MAX_UINT  NPY_MAX_UINT
+#define MAX_LONG  NPY_MAX_LONG
+#define MIN_LONG  NPY_MIN_LONG
+#define MAX_ULONG  NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+#define MIN_DATETIME NPY_MIN_DATETIME
+#define MAX_DATETIME NPY_MAX_DATETIME
+#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA
+#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA
+
+#define BITSOF_BOOL       NPY_BITSOF_BOOL
+#define BITSOF_CHAR       NPY_BITSOF_CHAR
+#define BITSOF_SHORT      NPY_BITSOF_SHORT
+#define BITSOF_INT        NPY_BITSOF_INT
+#define BITSOF_LONG       NPY_BITSOF_LONG
+#define BITSOF_LONGLONG   NPY_BITSOF_LONGLONG
+#define BITSOF_HALF       NPY_BITSOF_HALF
+#define BITSOF_FLOAT      NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE     NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+#define BITSOF_DATETIME   NPY_BITSOF_DATETIME
+#define BITSOF_TIMEDELTA   NPY_BITSOF_TIMEDELTA
+
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS     NPY_BEGIN_THREADS
+#define END_THREADS       NPY_END_THREADS
+#define ALLOW_C_API_DEF   NPY_ALLOW_C_API_DEF
+#define ALLOW_C_API       NPY_ALLOW_C_API
+#define DISABLE_C_API     NPY_DISABLE_C_API
+
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#endif
+
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#endif
+
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+
+#define CONTIGUOUS         NPY_CONTIGUOUS
+#define C_CONTIGUOUS       NPY_C_CONTIGUOUS
+#define FORTRAN            NPY_FORTRAN
+#define F_CONTIGUOUS       NPY_F_CONTIGUOUS
+#define OWNDATA            NPY_OWNDATA
+#define FORCECAST          NPY_FORCECAST
+#define ENSURECOPY         NPY_ENSURECOPY
+#define ENSUREARRAY        NPY_ENSUREARRAY
+#define ELEMENTSTRIDES     NPY_ELEMENTSTRIDES
+#define ALIGNED            NPY_ALIGNED
+#define NOTSWAPPED         NPY_NOTSWAPPED
+#define WRITEABLE          NPY_WRITEABLE
+#define UPDATEIFCOPY       NPY_UPDATEIFCOPY
+#define ARR_HAS_DESCR      NPY_ARR_HAS_DESCR
+#define BEHAVED            NPY_BEHAVED
+#define BEHAVED_NS         NPY_BEHAVED_NS
+#define CARRAY             NPY_CARRAY
+#define CARRAY_RO          NPY_CARRAY_RO
+#define FARRAY             NPY_FARRAY
+#define FARRAY_RO          NPY_FARRAY_RO
+#define DEFAULT            NPY_DEFAULT
+#define IN_ARRAY           NPY_IN_ARRAY
+#define OUT_ARRAY          NPY_OUT_ARRAY
+#define INOUT_ARRAY        NPY_INOUT_ARRAY
+#define IN_FARRAY          NPY_IN_FARRAY
+#define OUT_FARRAY         NPY_OUT_FARRAY
+#define INOUT_FARRAY       NPY_INOUT_FARRAY
+#define UPDATE_ALL         NPY_UPDATE_ALL
+
+#define OWN_DATA          NPY_OWNDATA
+#define BEHAVED_FLAGS     NPY_BEHAVED
+#define BEHAVED_FLAGS_NS  NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO   NPY_CARRAY_RO
+#define CARRAY_FLAGS      NPY_CARRAY
+#define FARRAY_FLAGS      NPY_FARRAY
+#define FARRAY_FLAGS_RO   NPY_FARRAY_RO
+#define DEFAULT_FLAGS     NPY_DEFAULT
+#define UPDATE_ALL_FLAGS  NPY_UPDATE_ALL_FLAGS
+
+#ifndef MIN
+#define MIN PyArray_MIN
+#endif
+#ifndef MAX
+#define MAX PyArray_MAX
+#endif
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
new file mode 100644
index 0000000000..4c318bc478
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
@@ -0,0 +1,130 @@
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+#endif
+
+#if defined(_WIN32)
+#define _WARN___STR2__(x) #x
+#define _WARN___STR1__(x) _WARN___STR2__(x)
+#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: "
+#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
+                         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+#elif defined(__GNUC__)
+#warning "Using deprecated NumPy API, disable it by " \
+         "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+#endif
+/* TODO: How to do this warning message for other compilers? */
+
+/*
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
+ *
+ * This is an attempt to remove bad API, the proliferation of macros,
+ * and namespace pollution currently produced by the NumPy headers.
+ */
+
+/* These array flags are deprecated as of NumPy 1.7 */
+#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
+
+/*
+ * The consistent NPY_ARRAY_* names which don't pollute the NPY_*
+ * namespace were added in NumPy 1.7.
+ *
+ * These versions of the carray flags are deprecated, but
+ * probably should only be removed after two releases instead of one.
+ */
+#define NPY_C_CONTIGUOUS   NPY_ARRAY_C_CONTIGUOUS
+#define NPY_F_CONTIGUOUS   NPY_ARRAY_F_CONTIGUOUS
+#define NPY_OWNDATA        NPY_ARRAY_OWNDATA
+#define NPY_FORCECAST      NPY_ARRAY_FORCECAST
+#define NPY_ENSURECOPY     NPY_ARRAY_ENSURECOPY
+#define NPY_ENSUREARRAY    NPY_ARRAY_ENSUREARRAY
+#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES
+#define NPY_ALIGNED        NPY_ARRAY_ALIGNED
+#define NPY_NOTSWAPPED     NPY_ARRAY_NOTSWAPPED
+#define NPY_WRITEABLE      NPY_ARRAY_WRITEABLE
+#define NPY_UPDATEIFCOPY   NPY_ARRAY_UPDATEIFCOPY
+#define NPY_BEHAVED        NPY_ARRAY_BEHAVED
+#define NPY_BEHAVED_NS     NPY_ARRAY_BEHAVED_NS
+#define NPY_CARRAY         NPY_ARRAY_CARRAY
+#define NPY_CARRAY_RO      NPY_ARRAY_CARRAY_RO
+#define NPY_FARRAY         NPY_ARRAY_FARRAY
+#define NPY_FARRAY_RO      NPY_ARRAY_FARRAY_RO
+#define NPY_DEFAULT        NPY_ARRAY_DEFAULT
+#define NPY_IN_ARRAY       NPY_ARRAY_IN_ARRAY
+#define NPY_OUT_ARRAY      NPY_ARRAY_OUT_ARRAY
+#define NPY_INOUT_ARRAY    NPY_ARRAY_INOUT_ARRAY
+#define NPY_IN_FARRAY      NPY_ARRAY_IN_FARRAY
+#define NPY_OUT_FARRAY     NPY_ARRAY_OUT_FARRAY
+#define NPY_INOUT_FARRAY   NPY_ARRAY_INOUT_FARRAY
+#define NPY_UPDATE_ALL     NPY_ARRAY_UPDATE_ALL
+
+/* This way of accessing the default type is deprecated as of NumPy 1.7 */
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+
+/* These DATETIME bits aren't used internally */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer(                   \
+                PyDict_GetItemString(                                         \
+                    descr->metadata, NPY_METADATA_DTSTR), NULL))))
+#else
+#define PyDataType_GetDatetimeMetaData(descr)                                 \
+    ((descr->metadata == NULL) ? NULL :                                       \
+        ((PyArray_DatetimeMetaData *)(PyCObject_AsVoidPtr(                    \
+                PyDict_GetItemString(descr->metadata, NPY_METADATA_DTSTR)))))
+#endif
+
+/*
+ * Deprecated as of NumPy 1.7, this kind of shortcut doesn't
+ * belong in the public API.
+ */
+#define NPY_AO PyArrayObject
+
+/*
+ * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't
+ * belong in the public API.
+ */
+#define fortran fortran_
+
+/*
+ * Deprecated as of NumPy 1.7, as it is a namespace-polluting
+ * macro.
+ */
+#define FORTRAN_IF PyArray_FORTRAN_IF
+
+/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */
+#define NPY_METADATA_DTSTR "__timeunit__"
+
+/*
+ * Deprecated as of NumPy 1.7.
+ * The reasoning:
+ *  - These are for datetime, but there's no datetime "namespace".
+ *  - They just turn NPY_STR_<x> into "<x>", which is just
+ *    making something simple be indirected.
+ */
+#define NPY_STR_Y "Y"
+#define NPY_STR_M "M"
+#define NPY_STR_W "W"
+#define NPY_STR_D "D"
+#define NPY_STR_h "h"
+#define NPY_STR_m "m"
+#define NPY_STR_s "s"
+#define NPY_STR_ms "ms"
+#define NPY_STR_us "us"
+#define NPY_STR_ns "ns"
+#define NPY_STR_ps "ps"
+#define NPY_STR_fs "fs"
+#define NPY_STR_as "as"
+
+/*
+ * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be
+ * removed in the next major release.
+ */
+#include "old_defines.h"
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
new file mode 100644
index 0000000000..db60a312c3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
@@ -0,0 +1,496 @@
+/*
+ * This is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ *
+ * If you want to use this for your own projects, it's recommended to make a
+ * copy of it. Although the stuff below is unlikely to change, we don't provide
+ * strong backwards compatibility guarantees at the moment.
+ */
+
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+
+#include <Python.h>
+#include <stdio.h>
+
+#if PY_VERSION_HEX >= 0x03000000
+#ifndef NPY_PY3K
+#define NPY_PY3K 1
+#endif
+#endif
+
+#include "numpy/npy_common.h"
+#include "numpy/ndarrayobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * PyInt -> PyLong
+ */
+
+#if defined(NPY_PY3K)
+/* Return True only if the long fits in a C long */
+static NPY_INLINE int PyInt_Check(PyObject *op) {
+    int overflow = 0;
+    if (!PyLong_Check(op)) {
+        return 0;
+    }
+    PyLong_AsLongAndOverflow(op, &overflow);
+    return (overflow == 0);
+}
+
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+
+/* NOTE:
+ *
+ * Since the PyLong type is very different from the fixed-range PyInt,
+ * we don't define PyInt_Type -> PyLong_Type.
+ */
+#endif /* NPY_PY3K */
+
+/*
+ * PyString -> PyBytes
+ */
+
+#if defined(NPY_PY3K)
+
+#define PyString_Type PyBytes_Type
+#define PyString_Check PyBytes_Check
+#define PyStringObject PyBytesObject
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define PyString_FromFormat PyBytes_FromFormat
+#define PyString_Concat PyBytes_Concat
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_Size PyBytes_Size
+
+#define PyUString_Type PyUnicode_Type
+#define PyUString_Check PyUnicode_Check
+#define PyUStringObject PyUnicodeObject
+#define PyUString_FromString PyUnicode_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyUString_FromFormat PyUnicode_FromFormat
+#define PyUString_Concat PyUnicode_Concat2
+#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_Size PyUnicode_Size
+#define PyUString_InternFromString PyUnicode_InternFromString
+#define PyUString_Format PyUnicode_Format
+
+#else
+
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytesObject PyStringObject
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_Size PyString_Size
+
+#define PyUString_Type PyString_Type
+#define PyUString_Check PyString_Check
+#define PyUStringObject PyStringObject
+#define PyUString_FromString PyString_FromString
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#define PyUString_FromFormat PyString_FromFormat
+#define PyUString_Concat PyString_Concat
+#define PyUString_ConcatAndDel PyString_ConcatAndDel
+#define PyUString_GET_SIZE PyString_GET_SIZE
+#define PyUString_Size PyString_Size
+#define PyUString_InternFromString PyString_InternFromString
+#define PyUString_Format PyString_Format
+
+#endif /* NPY_PY3K */
+
+
+static NPY_INLINE void
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    Py_DECREF(right);
+    *left = newobj;
+}
+
+static NPY_INLINE void
+PyUnicode_Concat2(PyObject **left, PyObject *right)
+{
+    PyObject *newobj;
+    newobj = PyUnicode_Concat(*left, right);
+    Py_DECREF(*left);
+    *left = newobj;
+}
+
+/*
+ * PyFile_* compatibility
+ */
+#if defined(NPY_PY3K)
+/*
+ * Get a FILE* handle to the file represented by the Python object
+ */
+static NPY_INLINE FILE*
+npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
+{
+    int fd, fd2, unbuf;
+    PyObject *ret, *os, *io, *io_raw;
+    npy_off_t pos;
+    FILE *handle;
+
+    /* Flush first to ensure things end up in the file in the correct order */
+    ret = PyObject_CallMethod(file, "flush", "");
+    if (ret == NULL) {
+        return NULL;
+    }
+    Py_DECREF(ret);
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return NULL;
+    }
+
+    /*
+     * The handle needs to be dup'd because we have to call fclose
+     * at the end
+     */
+    os = PyImport_ImportModule("os");
+    if (os == NULL) {
+        return NULL;
+    }
+    ret = PyObject_CallMethod(os, "dup", "i", fd);
+    Py_DECREF(os);
+    if (ret == NULL) {
+        return NULL;
+    }
+    fd2 = PyNumber_AsSsize_t(ret, NULL);
+    Py_DECREF(ret);
+
+    /* Convert to FILE* handle */
+#ifdef _WIN32
+    handle = _fdopen(fd2, mode);
+#else
+    handle = fdopen(fd2, mode);
+#endif
+    if (handle == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "Getting a FILE* from a Python file object failed");
+    }
+
+    /* Record the original raw file handle position */
+    *orig_pos = npy_ftell(handle);
+    if (*orig_pos == -1) {
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            fclose(handle);
+            return NULL;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return handle;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+            fclose(handle);
+            return NULL;
+        }
+    }
+
+    /* Seek raw handle to the Python-side position */
+    ret = PyObject_CallMethod(file, "tell", "");
+    if (ret == NULL) {
+        fclose(handle);
+        return NULL;
+    }
+    pos = PyLong_AsLongLong(ret);
+    Py_DECREF(ret);
+    if (PyErr_Occurred()) {
+        fclose(handle);
+        return NULL;
+    }
+    if (npy_fseek(handle, pos, SEEK_SET) == -1) {
+        PyErr_SetString(PyExc_IOError, "seeking file failed");
+        fclose(handle);
+        return NULL;
+    }
+    return handle;
+}
+
+/*
+ * Close the dup-ed file handle, and seek the Python one to the current position
+ */
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
+{
+    int fd, unbuf;
+    PyObject *ret, *io, *io_raw;
+    npy_off_t position;
+
+    position = npy_ftell(handle);
+
+    /* Close the FILE* handle */
+    fclose(handle);
+
+    /*
+     * Restore original file handle position, in order to not confuse
+     * Python-side data structures
+     */
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        return -1;
+    }
+
+    if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
+
+        /* The io module is needed to determine if buffering is used */
+        io = PyImport_ImportModule("io");
+        if (io == NULL) {
+            return -1;
+        }
+        /* File object instances of RawIOBase are unbuffered */
+        io_raw = PyObject_GetAttrString(io, "RawIOBase");
+        Py_DECREF(io);
+        if (io_raw == NULL) {
+            return -1;
+        }
+        unbuf = PyObject_IsInstance(file, io_raw);
+        Py_DECREF(io_raw);
+        if (unbuf == 1) {
+            /* Succeed if the IO is unbuffered */
+            return 0;
+        }
+        else {
+            PyErr_SetString(PyExc_IOError, "seeking file failed");
+            return -1;
+        }
+    }
+
+    if (position == -1) {
+        PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+        return -1;
+    }
+
+    /* Seek Python-side handle to the FILE* handle position */
+    ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+static NPY_INLINE int
+npy_PyFile_Check(PyObject *file)
+{
+    int fd;
+    fd = PyObject_AsFileDescriptor(file);
+    if (fd == -1) {
+        PyErr_Clear();
+        return 0;
+    }
+    return 1;
+}
+
+#else
+
+static NPY_INLINE FILE *
+npy_PyFile_Dup2(PyObject *file,
+                const char *NPY_UNUSED(mode), npy_off_t *NPY_UNUSED(orig_pos))
+{
+    FILE * fp = PyFile_AsFile(file);
+    if (fp == NULL) {
+        PyErr_SetString(PyExc_IOError,
+                        "first argument must be an open file");
+        return NULL;
+    }
+    return fp;
+}
+
+static NPY_INLINE int
+npy_PyFile_DupClose2(PyObject *NPY_UNUSED(file), FILE* NPY_UNUSED(handle),
+                     npy_off_t NPY_UNUSED(orig_pos))
+{
+    return 0;
+}
+
+#define npy_PyFile_Check PyFile_Check
+
+#endif
+
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+{
+    PyObject *open;
+    open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+    if (open == NULL) {
+        return NULL;
+    }
+    return PyObject_CallFunction(open, "Os", filename, mode);
+}
+
+static NPY_INLINE int
+npy_PyFile_CloseFile(PyObject *file)
+{
+    PyObject *ret;
+
+    ret = PyObject_CallMethod(file, "close", NULL);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+
+/*
+ * PyObject_Cmp
+ */
+#if defined(NPY_PY3K)
+static NPY_INLINE int
+PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp)
+{
+    int v;
+    v = PyObject_RichCompareBool(i1, i2, Py_LT);
+    if (v == 1) {
+        *cmp = -1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_GT);
+    if (v == 1) {
+        *cmp = 1;
+        return 1;
+    }
+    else if (v == -1) {
+        return -1;
+    }
+
+    v = PyObject_RichCompareBool(i1, i2, Py_EQ);
+    if (v == 1) {
+        *cmp = 0;
+        return 1;
+    }
+    else {
+        *cmp = 0;
+        return -1;
+    }
+}
+#endif
+
+/*
+ * PyCObject functions adapted to PyCapsules.
+ *
+ * The main job here is to get rid of the improved error handling
+ * of PyCapsules. It's a shame...
+ */
+#if PY_VERSION_HEX >= 0x03000000
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *))
+{
+    PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor);
+    if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) {
+        PyErr_Clear();
+        Py_DECREF(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCapsule_GetContext(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+static NPY_INLINE PyObject *
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context,
+        void (*dtor)(void *, void *))
+{
+    return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor);
+}
+
+static NPY_INLINE void *
+NpyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+static NPY_INLINE void *
+NpyCapsule_GetDesc(PyObject *obj)
+{
+    return PyCObject_GetDesc(obj);
+}
+
+static NPY_INLINE int
+NpyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NPY_3KCOMPAT_H_ */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
new file mode 100644
index 0000000000..baf5549d97
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
@@ -0,0 +1,1069 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+
+/* numpconfig.h is auto-generated */
+#include "numpyconfig.h"
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+
+/* need Python.h for npy_intp, npy_uintp */
+#include <Python.h>
+
+/*
+ * gcc does not unroll even with -O3
+ * use with care, unrolling on modern cpus rarely speeds things up
+ */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS
+#define NPY_GCC_UNROLL_LOOPS \
+    __attribute__((optimize("unroll-loops")))
+#else
+#define NPY_GCC_UNROLL_LOOPS
+#endif
+
+/* highest gcc optimization level, enabled autovectorizer */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3
+#define NPY_GCC_OPT_3 __attribute__((optimize("O3")))
+#else
+#define NPY_GCC_OPT_3
+#endif
+
+/*
+ * mark an argument (starting from 1) that must not be NULL and is not checked
+ * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check
+ */
+#ifdef HAVE_ATTRIBUTE_NONNULL
+#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n)))
+#else
+#define NPY_GCC_NONNULL(n)
+#endif
+
+#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS
+#define NPY_HAVE_SSE_INTRINSICS
+#endif
+
+#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD
+#define NPY_HAVE_SSE2_INTRINSICS
+#endif
+
+/*
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ *
+ * if (NPY_UNLIKELY(failure == 0))
+ *    return NULL;
+ *
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+ */
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#endif
+
+#ifdef HAVE___BUILTIN_PREFETCH
+/* unlike _mm_prefetch also works on non-x86 */
+#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc))
+#else
+#ifdef HAVE__MM_PREFETCH
+/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */
+#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \
+                                             (loc == 1 ? _MM_HINT_T2 : \
+                                              (loc == 2 ? _MM_HINT_T1 : \
+                                               (loc == 3 ? _MM_HINT_T0 : -1))))
+#else
+#define NPY_PREFETCH(x, rw,loc)
+#endif
+#endif
+
+#if defined(_MSC_VER)
+        #define NPY_INLINE __inline
+#elif defined(__GNUC__)
+	#if defined(__STRICT_ANSI__)
+		#define NPY_INLINE __inline__
+	#else
+		#define NPY_INLINE inline
+	#endif
+#else
+        #define NPY_INLINE
+#endif
+
+#ifdef HAVE___THREAD
+    #define NPY_TLS __thread
+#else
+    #ifdef HAVE___DECLSPEC_THREAD_
+        #define NPY_TLS __declspec(thread)
+    #else
+        #define NPY_TLS
+    #endif
+#endif
+
+#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE
+  #define NPY_RETURNS_BORROWED_REF \
+    __attribute__((cpychecker_returns_borrowed_ref))
+#else
+  #define NPY_RETURNS_BORROWED_REF
+#endif
+
+#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE
+  #define NPY_STEALS_REF_TO_ARG(n) \
+   __attribute__((cpychecker_steals_reference_to_arg(n)))
+#else
+ #define NPY_STEALS_REF_TO_ARG(n)
+#endif
+
+/* 64 bit file position support, also on win-amd64. Ticket #1660 */
+#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \
+    defined(__MINGW32__) || defined(__MINGW64__)
+    #include <io.h>
+
+/* mingw based on 3.4.5 has lseek but not ftell/fseek */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+extern int __cdecl _fseeki64(FILE *, long long, int);
+extern long long __cdecl _ftelli64(FILE *);
+#endif
+
+    #define npy_fseek _fseeki64
+    #define npy_ftell _ftelli64
+    #define npy_lseek _lseeki64
+    #define npy_off_t npy_int64
+
+    #if NPY_SIZEOF_INT == 8
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_LONG == 8
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_LONGLONG == 8
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#else
+#ifdef HAVE_FSEEKO
+    #define npy_fseek fseeko
+#else
+    #define npy_fseek fseek
+#endif
+#ifdef HAVE_FTELLO
+    #define npy_ftell ftello
+#else
+    #define npy_ftell ftell
+#endif
+    #include <sys/types.h>
+    #define npy_lseek lseek
+    #define npy_off_t off_t
+
+    #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT
+        #define NPY_OFF_T_PYFMT "h"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT
+        #define NPY_OFF_T_PYFMT "i"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG
+        #define NPY_OFF_T_PYFMT "l"
+    #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG
+        #define NPY_OFF_T_PYFMT "L"
+    #else
+        #error Unsupported size for type off_t
+    #endif
+#endif
+
+/* enums for detected endianness */
+enum {
+        NPY_CPU_UNKNOWN_ENDIAN,
+        NPY_CPU_LITTLE,
+        NPY_CPU_BIG
+};
+
+/*
+ * This is to typedef npy_intp to the appropriate pointer size for this
+ * platform.  Py_intptr_t, Py_uintptr_t are defined in pyport.h.
+ */
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+
+/*
+ * Define sizes that were not defined in numpyconfig.h.
+ */
+#define NPY_SIZEOF_CHAR 1
+#define NPY_SIZEOF_BYTE 1
+#define NPY_SIZEOF_DATETIME 8
+#define NPY_SIZEOF_TIMEDELTA 8
+#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_HALF 2
+#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT
+#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE
+#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE
+
+#ifdef constchar
+#undef constchar
+#endif
+
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+
+/* NPY_INTP_FMT Note:
+ *      Unlike the other NPY_*_FMT macros which are used with
+ *      PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and
+ *      PyString_Format. These functions use different formatting
+ *      codes which are portably specified according to the Python
+ *      documentation. See ticket #1795.
+ *
+ *      On Windows x64, the LONGLONG formatter should be used, but
+ *      in Python 2.6 the %lld formatter is not supported. In this
+ *      case we work around the problem by using the %zd formatter.
+ */
+#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT
+        #define NPY_INTP NPY_INT
+        #define NPY_UINTP NPY_UINT
+        #define PyIntpArrType_Type PyIntArrType_Type
+        #define PyUIntpArrType_Type PyUIntArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_INT
+        #define NPY_MIN_INTP NPY_MIN_INT
+        #define NPY_MAX_UINTP NPY_MAX_UINT
+        #define NPY_INTP_FMT "d"
+#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG
+        #define NPY_INTP NPY_LONG
+        #define NPY_UINTP NPY_ULONG
+        #define PyIntpArrType_Type PyLongArrType_Type
+        #define PyUIntpArrType_Type PyULongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONG
+        #define NPY_MIN_INTP NPY_MIN_LONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONG
+        #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG)
+        #define NPY_INTP NPY_LONGLONG
+        #define NPY_UINTP NPY_ULONGLONG
+        #define PyIntpArrType_Type PyLongLongArrType_Type
+        #define PyUIntpArrType_Type PyULongLongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONGLONG
+        #define NPY_MIN_INTP NPY_MIN_LONGLONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+    #if (PY_VERSION_HEX >= 0x02070000)
+        #define NPY_INTP_FMT "lld"
+    #else
+        #define NPY_INTP_FMT "zd"
+    #endif
+#endif
+
+/*
+ * We can only use C99 formats for npy_int_p if it is the same as
+ * intp_t, hence the condition on HAVE_UNITPTR_T
+ */
+#if (NPY_USE_C99_FORMATS) == 1 \
+        && (defined HAVE_UINTPTR_T) \
+        && (defined HAVE_INTTYPES_H)
+        #include <inttypes.h>
+        #undef NPY_INTP_FMT
+        #define NPY_INTP_FMT PRIdPTR
+#endif
+
+
+/*
+ * Some platforms don't define bool, long long, or long double.
+ * Handle that here.
+ */
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_HALF_FMT "g"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_FMT         "I64d"
+#    define NPY_ULONGLONG_FMT        "I64u"
+#  else
+#    define NPY_LONGLONG_FMT         "lld"
+#    define NPY_ULONGLONG_FMT        "llu"
+#  endif
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_SUFFIX(x)   (x##i64)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##Ui64)
+#  else
+#    define NPY_LONGLONG_SUFFIX(x)   (x##LL)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##ULL)
+#  endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+#  define NPY_LONGLONG_SUFFIX(x)  (x##L)
+#  define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+        typedef double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "g"
+#else
+        typedef long double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+/* These are for completeness */
+typedef char npy_char;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+typedef float npy_float;
+typedef double npy_double;
+
+/*
+ * Hash value compatibility.
+ * As of Python 3.2 hash values are of type Py_hash_t.
+ * Previous versions use C long.
+ */
+#if PY_VERSION_HEX < 0x03020000
+typedef long npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_LONG
+#else
+typedef Py_hash_t npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP
+#endif
+
+/*
+ * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being
+ * able to do .real/.imag. Will have to convert code first.
+ */
+#if 0
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE)
+typedef complex npy_cdouble;
+#else
+typedef struct { double real, imag; } npy_cdouble;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT)
+typedef complex float npy_cfloat;
+#else
+typedef struct { float real, imag; } npy_cfloat;
+#endif
+
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE)
+typedef complex long double npy_clongdouble;
+#else
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+#endif
+#endif
+#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE
+#error npy_cdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { double real, imag; } npy_cdouble;
+
+#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT
+#error npy_cfloat definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { float real, imag; } npy_cfloat;
+
+#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE
+#error npy_clongdouble definition is not compatible with C99 complex definition ! \
+        Please contact Numpy maintainers and give detailed information about your \
+        compiler and platform
+#endif
+typedef struct { npy_longdouble real, imag; } npy_clongdouble;
+
+/*
+ * numarray-style bit-width typedefs
+ */
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define NPY_MIN_DATETIME NPY_MIN_INT64
+#define NPY_MAX_DATETIME NPY_MAX_INT64
+#define NPY_MIN_TIMEDELTA NPY_MIN_INT64
+#define NPY_MAX_TIMEDELTA NPY_MAX_INT64
+
+        /* Need to find the number of bits for each type and
+           make definitions accordingly.
+
+           C states that sizeof(char) == 1 by definition
+
+           So, just using the sizeof keyword won't help.
+
+           It also looks like Python itself uses sizeof(char) quite a
+           bit, which by definition should be 1 all the time.
+
+           Idea: Make Use of CHAR_BIT which should tell us how many
+           BITS per CHARACTER
+        */
+
+        /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT   INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif
+#define NPY_MIN_INT   INT_MIN
+#define NPY_MAX_UINT  UINT_MAX
+#define NPY_MAX_LONG  LONG_MAX
+#define NPY_MIN_LONG  LONG_MIN
+#define NPY_MAX_ULONG  ULONG_MAX
+
+#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT)
+#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT)
+#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT)
+#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT)
+#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT)
+#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT)
+#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT)
+#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT)
+#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT)
+
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+        typedef long npy_int8;
+        typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+        typedef long npy_int16;
+        typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+        typedef long npy_int32;
+        typedef unsigned long npy_uint32;
+        typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+        typedef long npy_int64;
+        typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#define MyPyLong_FromInt64 PyLong_FromLong
+#define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+        typedef long npy_int128;
+        typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#endif
+
+#if NPY_BITSOF_LONGLONG == 8
+#  ifndef NPY_INT8
+#    define NPY_INT8 NPY_LONGLONG
+#    define NPY_UINT8 NPY_ULONGLONG
+        typedef npy_longlong npy_int8;
+        typedef npy_ulonglong npy_uint8;
+#    define PyInt8ScalarObject PyLongLongScalarObject
+#    define PyInt8ArrType_Type PyLongLongArrType_Type
+#    define PyUInt8ScalarObject PyULongLongScalarObject
+#    define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT8
+#  define NPY_MIN_LONGLONG NPY_MIN_INT8
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+#  ifndef NPY_INT16
+#    define NPY_INT16 NPY_LONGLONG
+#    define NPY_UINT16 NPY_ULONGLONG
+        typedef npy_longlong npy_int16;
+        typedef npy_ulonglong npy_uint16;
+#    define PyInt16ScalarObject PyLongLongScalarObject
+#    define PyInt16ArrType_Type PyLongLongArrType_Type
+#    define PyUInt16ScalarObject PyULongLongScalarObject
+#    define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT16
+#  define NPY_MIN_LONGLONG NPY_MIN_INT16
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+#  ifndef NPY_INT32
+#    define NPY_INT32 NPY_LONGLONG
+#    define NPY_UINT32 NPY_ULONGLONG
+        typedef npy_longlong npy_int32;
+        typedef npy_ulonglong npy_uint32;
+        typedef npy_ulonglong npy_ucs4;
+#    define PyInt32ScalarObject PyLongLongScalarObject
+#    define PyInt32ArrType_Type PyLongLongArrType_Type
+#    define PyUInt32ScalarObject PyULongLongScalarObject
+#    define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT32
+#  define NPY_MIN_LONGLONG NPY_MIN_INT32
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+#  ifndef NPY_INT64
+#    define NPY_INT64 NPY_LONGLONG
+#    define NPY_UINT64 NPY_ULONGLONG
+        typedef npy_longlong npy_int64;
+        typedef npy_ulonglong npy_uint64;
+#    define PyInt64ScalarObject PyLongLongScalarObject
+#    define PyInt64ArrType_Type PyLongLongArrType_Type
+#    define PyUInt64ScalarObject PyULongLongScalarObject
+#    define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLongLong
+#    define MyPyLong_AsInt64 PyLong_AsLongLong
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT64
+#  define NPY_MIN_LONGLONG NPY_MIN_INT64
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+#  ifndef NPY_INT128
+#    define NPY_INT128 NPY_LONGLONG
+#    define NPY_UINT128 NPY_ULONGLONG
+        typedef npy_longlong npy_int128;
+        typedef npy_ulonglong npy_uint128;
+#    define PyInt128ScalarObject PyLongLongScalarObject
+#    define PyInt128ArrType_Type PyLongLongArrType_Type
+#    define PyUInt128ScalarObject PyULongLongScalarObject
+#    define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT128
+#  define NPY_MIN_LONGLONG NPY_MIN_INT128
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+#  define NPY_INT256 NPY_LONGLONG
+#  define NPY_UINT256 NPY_ULONGLONG
+        typedef npy_longlong npy_int256;
+        typedef npy_ulonglong npy_uint256;
+#  define PyInt256ScalarObject PyLongLongScalarObject
+#  define PyInt256ArrType_Type PyLongLongArrType_Type
+#  define PyUInt256ScalarObject PyULongLongScalarObject
+#  define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+#  define NPY_MAX_LONGLONG NPY_MAX_INT256
+#  define NPY_MIN_LONGLONG NPY_MIN_INT256
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#endif
+
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+        typedef int npy_int8;
+        typedef unsigned int npy_uint8;
+#    define PyInt8ScalarObject PyIntScalarObject
+#    define PyInt8ArrType_Type PyIntArrType_Type
+#    define PyUInt8ScalarObject PyUIntScalarObject
+#    define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+        typedef int npy_int16;
+        typedef unsigned int npy_uint16;
+#    define PyInt16ScalarObject PyIntScalarObject
+#    define PyInt16ArrType_Type PyIntArrType_Type
+#    define PyUInt16ScalarObject PyIntUScalarObject
+#    define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+        typedef int npy_int32;
+        typedef unsigned int npy_uint32;
+        typedef unsigned int npy_ucs4;
+#    define PyInt32ScalarObject PyIntScalarObject
+#    define PyInt32ArrType_Type PyIntArrType_Type
+#    define PyUInt32ScalarObject PyUIntScalarObject
+#    define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+        typedef int npy_int64;
+        typedef unsigned int npy_uint64;
+#    define PyInt64ScalarObject PyIntScalarObject
+#    define PyInt64ArrType_Type PyIntArrType_Type
+#    define PyUInt64ScalarObject PyUIntScalarObject
+#    define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+        typedef int npy_int128;
+        typedef unsigned int npy_uint128;
+#    define PyInt128ScalarObject PyIntScalarObject
+#    define PyInt128ArrType_Type PyIntArrType_Type
+#    define PyUInt128ScalarObject PyUIntScalarObject
+#    define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#endif
+#endif
+
+#if NPY_BITSOF_SHORT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+        typedef short npy_int8;
+        typedef unsigned short npy_uint8;
+#    define PyInt8ScalarObject PyShortScalarObject
+#    define PyInt8ArrType_Type PyShortArrType_Type
+#    define PyUInt8ScalarObject PyUShortScalarObject
+#    define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+        typedef short npy_int16;
+        typedef unsigned short npy_uint16;
+#    define PyInt16ScalarObject PyShortScalarObject
+#    define PyInt16ArrType_Type PyShortArrType_Type
+#    define PyUInt16ScalarObject PyUShortScalarObject
+#    define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+        typedef short npy_int32;
+        typedef unsigned short npy_uint32;
+        typedef unsigned short npy_ucs4;
+#    define PyInt32ScalarObject PyShortScalarObject
+#    define PyInt32ArrType_Type PyShortArrType_Type
+#    define PyUInt32ScalarObject PyUShortScalarObject
+#    define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+        typedef short npy_int64;
+        typedef unsigned short npy_uint64;
+#    define PyInt64ScalarObject PyShortScalarObject
+#    define PyInt64ArrType_Type PyShortArrType_Type
+#    define PyUInt64ScalarObject PyUShortScalarObject
+#    define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_SHORT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+        typedef short npy_int128;
+        typedef unsigned short npy_uint128;
+#    define PyInt128ScalarObject PyShortScalarObject
+#    define PyInt128ArrType_Type PyShortArrType_Type
+#    define PyUInt128ScalarObject PyUShortScalarObject
+#    define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_CHAR == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+        typedef signed char npy_int8;
+        typedef unsigned char npy_uint8;
+#    define PyInt8ScalarObject PyByteScalarObject
+#    define PyInt8ArrType_Type PyByteArrType_Type
+#    define PyUInt8ScalarObject PyUByteScalarObject
+#    define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+        typedef signed char npy_int16;
+        typedef unsigned char npy_uint16;
+#    define PyInt16ScalarObject PyByteScalarObject
+#    define PyInt16ArrType_Type PyByteArrType_Type
+#    define PyUInt16ScalarObject PyUByteScalarObject
+#    define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+        typedef signed char npy_int32;
+        typedef unsigned char npy_uint32;
+        typedef unsigned char npy_ucs4;
+#    define PyInt32ScalarObject PyByteScalarObject
+#    define PyInt32ArrType_Type PyByteArrType_Type
+#    define PyUInt32ScalarObject PyUByteScalarObject
+#    define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+        typedef signed char npy_int64;
+        typedef unsigned char npy_uint64;
+#    define PyInt64ScalarObject PyByteScalarObject
+#    define PyInt64ArrType_Type PyByteArrType_Type
+#    define PyUInt64ScalarObject PyUByteScalarObject
+#    define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#    define MyPyLong_FromInt64 PyLong_FromLong
+#    define MyPyLong_AsInt64 PyLong_AsLong
+#endif
+#elif NPY_BITSOF_CHAR == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+        typedef signed char npy_int128;
+        typedef unsigned char npy_uint128;
+#    define PyInt128ScalarObject PyByteScalarObject
+#    define PyInt128ArrType_Type PyByteArrType_Type
+#    define PyUInt128ScalarObject PyUByteScalarObject
+#    define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+        typedef double npy_float32;
+        typedef npy_cdouble npy_complex64;
+#    define PyFloat32ScalarObject PyDoubleScalarObject
+#    define PyComplex64ScalarObject PyCDoubleScalarObject
+#    define PyFloat32ArrType_Type PyDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+        typedef double npy_float64;
+        typedef npy_cdouble npy_complex128;
+#    define PyFloat64ScalarObject PyDoubleScalarObject
+#    define PyComplex128ScalarObject PyCDoubleScalarObject
+#    define PyFloat64ArrType_Type PyDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+        typedef double npy_float80;
+        typedef npy_cdouble npy_complex160;
+#    define PyFloat80ScalarObject PyDoubleScalarObject
+#    define PyComplex160ScalarObject PyCDoubleScalarObject
+#    define PyFloat80ArrType_Type PyDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+        typedef double npy_float96;
+        typedef npy_cdouble npy_complex192;
+#    define PyFloat96ScalarObject PyDoubleScalarObject
+#    define PyComplex192ScalarObject PyCDoubleScalarObject
+#    define PyFloat96ArrType_Type PyDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+        typedef double npy_float128;
+        typedef npy_cdouble npy_complex256;
+#    define PyFloat128ScalarObject PyDoubleScalarObject
+#    define PyComplex256ScalarObject PyCDoubleScalarObject
+#    define PyFloat128ArrType_Type PyDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_FLOAT == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+        typedef float npy_float32;
+        typedef npy_cfloat npy_complex64;
+#    define PyFloat32ScalarObject PyFloatScalarObject
+#    define PyComplex64ScalarObject PyCFloatScalarObject
+#    define PyFloat32ArrType_Type PyFloatArrType_Type
+#    define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+        typedef float npy_float64;
+        typedef npy_cfloat npy_complex128;
+#    define PyFloat64ScalarObject PyFloatScalarObject
+#    define PyComplex128ScalarObject PyCFloatScalarObject
+#    define PyFloat64ArrType_Type PyFloatArrType_Type
+#    define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+        typedef float npy_float80;
+        typedef npy_cfloat npy_complex160;
+#    define PyFloat80ScalarObject PyFloatScalarObject
+#    define PyComplex160ScalarObject PyCFloatScalarObject
+#    define PyFloat80ArrType_Type PyFloatArrType_Type
+#    define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+        typedef float npy_float96;
+        typedef npy_cfloat npy_complex192;
+#    define PyFloat96ScalarObject PyFloatScalarObject
+#    define PyComplex192ScalarObject PyCFloatScalarObject
+#    define PyFloat96ArrType_Type PyFloatArrType_Type
+#    define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+        typedef float npy_float128;
+        typedef npy_cfloat npy_complex256;
+#    define PyFloat128ScalarObject PyFloatScalarObject
+#    define PyComplex256ScalarObject PyCFloatScalarObject
+#    define PyFloat128ArrType_Type PyFloatArrType_Type
+#    define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+#endif
+#endif
+
+/* half/float16 isn't a floating-point type in C */
+#define NPY_FLOAT16 NPY_HALF
+typedef npy_uint16 npy_half;
+typedef npy_half npy_float16;
+
+#if NPY_BITSOF_LONGDOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float32;
+        typedef npy_clongdouble npy_complex64;
+#    define PyFloat32ScalarObject PyLongDoubleScalarObject
+#    define PyComplex64ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float64;
+        typedef npy_clongdouble npy_complex128;
+#    define PyFloat64ScalarObject PyLongDoubleScalarObject
+#    define PyComplex128ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float80;
+        typedef npy_clongdouble npy_complex160;
+#    define PyFloat80ScalarObject PyLongDoubleScalarObject
+#    define PyComplex160ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float96;
+        typedef npy_clongdouble npy_complex192;
+#    define PyFloat96ScalarObject PyLongDoubleScalarObject
+#    define PyComplex192ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float128;
+        typedef npy_clongdouble npy_complex256;
+#    define PyFloat128ScalarObject PyLongDoubleScalarObject
+#    define PyComplex256ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float256;
+        typedef npy_clongdouble npy_complex512;
+#    define PyFloat256ScalarObject PyLongDoubleScalarObject
+#    define PyComplex512ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+#endif
+
+/* datetime typedefs */
+typedef npy_int64 npy_timedelta;
+typedef npy_int64 npy_datetime;
+#define NPY_DATETIME_FMT NPY_INT64_FMT
+#define NPY_TIMEDELTA_FMT NPY_INT64_FMT
+
+/* End of typedefs for numarray style bit-width names */
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
new file mode 100644
index 0000000000..60abae4e0b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
@@ -0,0 +1,92 @@
+/*
+ * This set (target) cpu specific macros:
+ *      - Possible values:
+ *              NPY_CPU_X86
+ *              NPY_CPU_AMD64
+ *              NPY_CPU_PPC
+ *              NPY_CPU_PPC64
+ *              NPY_CPU_PPC64LE
+ *              NPY_CPU_SPARC
+ *              NPY_CPU_S390
+ *              NPY_CPU_IA64
+ *              NPY_CPU_HPPA
+ *              NPY_CPU_ALPHA
+ *              NPY_CPU_ARMEL
+ *              NPY_CPU_ARMEB
+ *              NPY_CPU_SH_LE
+ *              NPY_CPU_SH_BE
+ */
+#ifndef _NPY_CPUARCH_H_
+#define _NPY_CPUARCH_H_
+
+#include "numpyconfig.h"
+#include <string.h> /* for memcpy */
+
+#if defined( __i386__ ) || defined(i386) || defined(_M_IX86)
+    /*
+     * __i386__ is defined by gcc and Intel compiler on Linux,
+     * _M_IX86 by VS compiler,
+     * i386 by Sun compilers on opensolaris at least
+     */
+    #define NPY_CPU_X86
+#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64)
+    /*
+     * both __x86_64__ and __amd64__ are defined by gcc
+     * __x86_64 defined by sun compiler on opensolaris at least
+     * _M_AMD64 defined by MS compiler
+     */
+    #define NPY_CPU_AMD64
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC)
+    /*
+     * __ppc__ is defined by gcc, I remember having seen __powerpc__ once,
+     * but can't find it ATM
+     * _ARCH_PPC is used by at least gcc on AIX
+     */
+    #define NPY_CPU_PPC
+#elif defined(__ppc64le__)
+    #define NPY_CPU_PPC64LE
+#elif defined(__ppc64__)
+    #define NPY_CPU_PPC64
+#elif defined(__sparc__) || defined(__sparc)
+    /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */
+    #define NPY_CPU_SPARC
+#elif defined(__s390__)
+    #define NPY_CPU_S390
+#elif defined(__ia64)
+    #define NPY_CPU_IA64
+#elif defined(__hppa)
+    #define NPY_CPU_HPPA
+#elif defined(__alpha__)
+    #define NPY_CPU_ALPHA
+#elif defined(__arm__) && defined(__ARMEL__)
+    #define NPY_CPU_ARMEL
+#elif defined(__arm__) && defined(__ARMEB__)
+    #define NPY_CPU_ARMEB
+#elif defined(__sh__) && defined(__LITTLE_ENDIAN__)
+    #define NPY_CPU_SH_LE
+#elif defined(__sh__) && defined(__BIG_ENDIAN__)
+    #define NPY_CPU_SH_BE
+#elif defined(__MIPSEL__)
+    #define NPY_CPU_MIPSEL
+#elif defined(__MIPSEB__)
+    #define NPY_CPU_MIPSEB
+#elif defined(__or1k__)
+    #define NPY_CPU_OR1K
+#elif defined(__aarch64__)
+    #define NPY_CPU_AARCH64
+#elif defined(__mc68000__)
+    #define NPY_CPU_M68K
+#else
+    #error Unknown CPU, please report this to numpy maintainers with \
+    information about your platform (OS, CPU and compiler)
+#endif
+
+#define NPY_COPY_PYOBJECT_PTR(dst, src) memcpy(dst, src, sizeof(PyObject *))
+
+#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
+#else
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
new file mode 100644
index 0000000000..a8ec572458
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
@@ -0,0 +1,61 @@
+#ifndef _NPY_ENDIAN_H_
+#define _NPY_ENDIAN_H_
+
+/*
+ * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in
+ * endian.h
+ */
+
+#ifdef NPY_HAVE_ENDIAN_H
+    /* Use endian.h if available */
+    #include <endian.h>
+
+    #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    BIG_ENDIAN
+    #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    _BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    _BIG_ENDIAN
+    #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+        #define NPY_BYTE_ORDER    __BYTE_ORDER
+        #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+        #define NPY_BIG_ENDIAN    __BIG_ENDIAN
+    #endif
+#endif
+
+#ifndef NPY_BYTE_ORDER
+    /* Set endianness info using target CPU */
+    #include "npy_cpu.h"
+
+    #define NPY_LITTLE_ENDIAN 1234
+    #define NPY_BIG_ENDIAN 4321
+
+    #if defined(NPY_CPU_X86)            \
+            || defined(NPY_CPU_AMD64)   \
+            || defined(NPY_CPU_IA64)    \
+            || defined(NPY_CPU_ALPHA)   \
+            || defined(NPY_CPU_ARMEL)   \
+            || defined(NPY_CPU_AARCH64) \
+            || defined(NPY_CPU_SH_LE)   \
+            || defined(NPY_CPU_MIPSEL)  \
+            || defined(NPY_CPU_PPC64LE)
+        #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
+    #elif defined(NPY_CPU_PPC)          \
+            || defined(NPY_CPU_SPARC)   \
+            || defined(NPY_CPU_S390)    \
+            || defined(NPY_CPU_HPPA)    \
+            || defined(NPY_CPU_PPC64)   \
+            || defined(NPY_CPU_ARMEB)   \
+            || defined(NPY_CPU_SH_BE)   \
+            || defined(NPY_CPU_MIPSEB)  \
+            || defined(NPY_CPU_OR1K)    \
+            || defined(NPY_CPU_M68K)
+        #define NPY_BYTE_ORDER NPY_BIG_ENDIAN
+    #else
+        #error Unknown CPU: can not set endianness
+    #endif
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
new file mode 100644
index 0000000000..f71fd689eb
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
@@ -0,0 +1,117 @@
+
+/* Signal handling:
+
+This header file defines macros that allow your code to handle
+interrupts received during processing.  Interrupts that
+could reasonably be handled:
+
+SIGINT, SIGABRT, SIGALRM, SIGSEGV
+
+****Warning***************
+
+Do not allow code that creates temporary memory or increases reference
+counts of Python objects to be interrupted unless you handle it
+differently.
+
+**************************
+
+The mechanism for handling interrupts is conceptually simple:
+
+  - replace the signal handler with our own home-grown version
+     and store the old one.
+  - run the code to be interrupted -- if an interrupt occurs
+     the handler should basically just cause a return to the
+     calling function for finish work.
+  - restore the old signal handler
+
+Of course, every code that allows interrupts must account for
+returning via the interrupt and handle clean-up correctly.  But,
+even still, the simple paradigm is complicated by at least three
+factors.
+
+ 1) platform portability (i.e. Microsoft says not to use longjmp
+     to return from signal handling.  They have a __try  and __except
+     extension to C instead but what about mingw?).
+
+ 2) how to handle threads: apparently whether signals are delivered to
+    every thread of the process or the "invoking" thread is platform
+    dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance.  For now, assume the
+    code will not call-back into itself.
+
+Ideas:
+
+ 1) Start by implementing an approach that works on platforms that
+    can use setjmp and longjmp functionality and does nothing
+    on other platforms.
+
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
+
+ 3) Add a default signal_handler function to the C-API but have the rest
+    use macros.
+
+
+Simple Interface:
+
+
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
+[code]
+NPY_SIGINT_OFF
+
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects.  In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
+
+Interrupt handling does not work well with threads.
+
+*/
+
+/* Add signal handling macros
+   Make the global variable and signal handler part of the C-API
+*/
+
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef sigsetjmp
+
+#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF jmp_buf
+
+#else
+
+#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF sigjmp_buf
+
+#endif
+
+#    define NPY_SIGINT_ON {                                             \
+                   PyOS_sighandler_t _npy_sig_save;                     \
+                   _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+                   if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+                                 1) == 0) {                             \
+
+#    define NPY_SIGINT_OFF }                                      \
+        PyOS_setsig(SIGINT, _npy_sig_save);                       \
+        }
+
+#else /* NPY_NO_SIGNAL  */
+
+#define NPY_SIGINT_ON
+#define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
+#endif /* NPY_INTERRUPT_H */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
new file mode 100644
index 0000000000..e76508de04
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
@@ -0,0 +1,529 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#ifdef __SUNPRO_CC
+#include <sunmath.h>
+#endif
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+#endif
+#include <numpy/npy_common.h>
+
+
+/*
+ * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
+ * for INFINITY)
+ *
+ * XXX: I should test whether INFINITY and NAN are available on the platform
+ */
+NPY_INLINE static float __npy_inff(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nanf(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_pzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL};
+    return __bint.__f;
+}
+
+NPY_INLINE static float __npy_nzerof(void)
+{
+    const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL};
+    return __bint.__f;
+}
+
+#define NPY_INFINITYF __npy_inff()
+#define NPY_NANF __npy_nanf()
+#define NPY_PZEROF __npy_pzerof()
+#define NPY_NZEROF __npy_nzerof()
+
+#define NPY_INFINITY ((npy_double)NPY_INFINITYF)
+#define NPY_NAN ((npy_double)NPY_NANF)
+#define NPY_PZERO ((npy_double)NPY_PZEROF)
+#define NPY_NZERO ((npy_double)NPY_NZEROF)
+
+#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF)
+#define NPY_NANL ((npy_longdouble)NPY_NANF)
+#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF)
+#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF)
+
+/*
+ * Useful constants
+ */
+#define NPY_E         2.718281828459045235360287471352662498  /* e */
+#define NPY_LOG2E     1.442695040888963407359924681001892137  /* log_2 e */
+#define NPY_LOG10E    0.434294481903251827651128918916605082  /* log_10 e */
+#define NPY_LOGE2     0.693147180559945309417232121458176568  /* log_e 2 */
+#define NPY_LOGE10    2.302585092994045684017991454684364208  /* log_e 10 */
+#define NPY_PI        3.141592653589793238462643383279502884  /* pi */
+#define NPY_PI_2      1.570796326794896619231321691639751442  /* pi/2 */
+#define NPY_PI_4      0.785398163397448309615660845819875721  /* pi/4 */
+#define NPY_1_PI      0.318309886183790671537767526745028724  /* 1/pi */
+#define NPY_2_PI      0.636619772367581343075535053490057448  /* 2/pi */
+#define NPY_EULER     0.577215664901532860606512090082402431  /* Euler constant */
+#define NPY_SQRT2     1.414213562373095048801688724209698079  /* sqrt(2) */
+#define NPY_SQRT1_2   0.707106781186547524400844362104849039  /* 1/sqrt(2) */
+
+#define NPY_Ef        2.718281828459045235360287471352662498F /* e */
+#define NPY_LOG2Ef    1.442695040888963407359924681001892137F /* log_2 e */
+#define NPY_LOG10Ef   0.434294481903251827651128918916605082F /* log_10 e */
+#define NPY_LOGE2f    0.693147180559945309417232121458176568F /* log_e 2 */
+#define NPY_LOGE10f   2.302585092994045684017991454684364208F /* log_e 10 */
+#define NPY_PIf       3.141592653589793238462643383279502884F /* pi */
+#define NPY_PI_2f     1.570796326794896619231321691639751442F /* pi/2 */
+#define NPY_PI_4f     0.785398163397448309615660845819875721F /* pi/4 */
+#define NPY_1_PIf     0.318309886183790671537767526745028724F /* 1/pi */
+#define NPY_2_PIf     0.636619772367581343075535053490057448F /* 2/pi */
+#define NPY_EULERf    0.577215664901532860606512090082402431F /* Euler constant */
+#define NPY_SQRT2f    1.414213562373095048801688724209698079F /* sqrt(2) */
+#define NPY_SQRT1_2f  0.707106781186547524400844362104849039F /* 1/sqrt(2) */
+
+#define NPY_El        2.718281828459045235360287471352662498L /* e */
+#define NPY_LOG2El    1.442695040888963407359924681001892137L /* log_2 e */
+#define NPY_LOG10El   0.434294481903251827651128918916605082L /* log_10 e */
+#define NPY_LOGE2l    0.693147180559945309417232121458176568L /* log_e 2 */
+#define NPY_LOGE10l   2.302585092994045684017991454684364208L /* log_e 10 */
+#define NPY_PIl       3.141592653589793238462643383279502884L /* pi */
+#define NPY_PI_2l     1.570796326794896619231321691639751442L /* pi/2 */
+#define NPY_PI_4l     0.785398163397448309615660845819875721L /* pi/4 */
+#define NPY_1_PIl     0.318309886183790671537767526745028724L /* 1/pi */
+#define NPY_2_PIl     0.636619772367581343075535053490057448L /* 2/pi */
+#define NPY_EULERl    0.577215664901532860606512090082402431L /* Euler constant */
+#define NPY_SQRT2l    1.414213562373095048801688724209698079L /* sqrt(2) */
+#define NPY_SQRT1_2l  0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+
+/*
+ * C99 double math funcs
+ */
+double npy_sin(double x);
+double npy_cos(double x);
+double npy_tan(double x);
+double npy_sinh(double x);
+double npy_cosh(double x);
+double npy_tanh(double x);
+
+double npy_asin(double x);
+double npy_acos(double x);
+double npy_atan(double x);
+
+double npy_log(double x);
+double npy_log10(double x);
+double npy_exp(double x);
+double npy_sqrt(double x);
+double npy_cbrt(double x);
+
+double npy_fabs(double x);
+double npy_ceil(double x);
+double npy_fmod(double x, double y);
+double npy_floor(double x);
+
+double npy_expm1(double x);
+double npy_log1p(double x);
+double npy_hypot(double x, double y);
+double npy_acosh(double x);
+double npy_asinh(double xx);
+double npy_atanh(double x);
+double npy_rint(double x);
+double npy_trunc(double x);
+double npy_exp2(double x);
+double npy_log2(double x);
+
+double npy_atan2(double x, double y);
+double npy_pow(double x, double y);
+double npy_modf(double x, double* y);
+double npy_frexp(double x, int* y);
+double npy_ldexp(double n, int y);
+
+double npy_copysign(double x, double y);
+double npy_nextafter(double x, double y);
+double npy_spacing(double x);
+
+/*
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+ */
+
+/* use builtins to avoid function calls in tight loops
+ * only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISNAN
+    #define npy_isnan(x) __builtin_isnan(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISNAN
+        #define npy_isnan(x) ((x) != (x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isnan(x) _isnan((x))
+        #else
+            #define npy_isnan(x) isnan(x)
+        #endif
+    #endif
+#endif
+
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISFINITE
+    #define npy_isfinite(x) __builtin_isfinite(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISFINITE
+        #ifdef _MSC_VER
+            #define npy_isfinite(x) _finite((x))
+        #else
+            #define npy_isfinite(x) !npy_isnan((x) + (-x))
+        #endif
+    #else
+        #define npy_isfinite(x) isfinite((x))
+    #endif
+#endif
+
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISINF
+    #define npy_isinf(x) __builtin_isinf(x)
+#else
+    #ifndef NPY_HAVE_DECL_ISINF
+        #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+    #else
+        #if defined(_MSC_VER) && (_MSC_VER < 1900)
+            #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+        #else
+            #define npy_isinf(x) isinf((x))
+        #endif
+    #endif
+#endif
+
+#ifndef NPY_HAVE_DECL_SIGNBIT
+    int _npy_signbit_f(float x);
+    int _npy_signbit_d(double x);
+    int _npy_signbit_ld(long double x);
+    #define npy_signbit(x) \
+        (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+         : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+         : _npy_signbit_f (x))
+#else
+    #define npy_signbit(x) signbit((x))
+#endif
+
+/*
+ * float C99 math functions
+ */
+
+float npy_sinf(float x);
+float npy_cosf(float x);
+float npy_tanf(float x);
+float npy_sinhf(float x);
+float npy_coshf(float x);
+float npy_tanhf(float x);
+float npy_fabsf(float x);
+float npy_floorf(float x);
+float npy_ceilf(float x);
+float npy_rintf(float x);
+float npy_truncf(float x);
+float npy_sqrtf(float x);
+float npy_cbrtf(float x);
+float npy_log10f(float x);
+float npy_logf(float x);
+float npy_expf(float x);
+float npy_expm1f(float x);
+float npy_asinf(float x);
+float npy_acosf(float x);
+float npy_atanf(float x);
+float npy_asinhf(float x);
+float npy_acoshf(float x);
+float npy_atanhf(float x);
+float npy_log1pf(float x);
+float npy_exp2f(float x);
+float npy_log2f(float x);
+
+float npy_atan2f(float x, float y);
+float npy_hypotf(float x, float y);
+float npy_powf(float x, float y);
+float npy_fmodf(float x, float y);
+
+float npy_modff(float x, float* y);
+float npy_frexpf(float x, int* y);
+float npy_ldexpf(float x, int y);
+
+float npy_copysignf(float x, float y);
+float npy_nextafterf(float x, float y);
+float npy_spacingf(float x);
+
+/*
+ * long double C99 math functions
+ */
+
+npy_longdouble npy_sinl(npy_longdouble x);
+npy_longdouble npy_cosl(npy_longdouble x);
+npy_longdouble npy_tanl(npy_longdouble x);
+npy_longdouble npy_sinhl(npy_longdouble x);
+npy_longdouble npy_coshl(npy_longdouble x);
+npy_longdouble npy_tanhl(npy_longdouble x);
+npy_longdouble npy_fabsl(npy_longdouble x);
+npy_longdouble npy_floorl(npy_longdouble x);
+npy_longdouble npy_ceill(npy_longdouble x);
+npy_longdouble npy_rintl(npy_longdouble x);
+npy_longdouble npy_truncl(npy_longdouble x);
+npy_longdouble npy_sqrtl(npy_longdouble x);
+npy_longdouble npy_cbrtl(npy_longdouble x);
+npy_longdouble npy_log10l(npy_longdouble x);
+npy_longdouble npy_logl(npy_longdouble x);
+npy_longdouble npy_expl(npy_longdouble x);
+npy_longdouble npy_expm1l(npy_longdouble x);
+npy_longdouble npy_asinl(npy_longdouble x);
+npy_longdouble npy_acosl(npy_longdouble x);
+npy_longdouble npy_atanl(npy_longdouble x);
+npy_longdouble npy_asinhl(npy_longdouble x);
+npy_longdouble npy_acoshl(npy_longdouble x);
+npy_longdouble npy_atanhl(npy_longdouble x);
+npy_longdouble npy_log1pl(npy_longdouble x);
+npy_longdouble npy_exp2l(npy_longdouble x);
+npy_longdouble npy_log2l(npy_longdouble x);
+
+npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+
+npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_spacingl(npy_longdouble x);
+
+/*
+ * Non standard functions
+ */
+double npy_deg2rad(double x);
+double npy_rad2deg(double x);
+double npy_logaddexp(double x, double y);
+double npy_logaddexp2(double x, double y);
+double npy_divmod(double x, double y, double *modulus);
+
+float npy_deg2radf(float x);
+float npy_rad2degf(float x);
+float npy_logaddexpf(float x, float y);
+float npy_logaddexp2f(float x, float y);
+float npy_divmodf(float x, float y, float *modulus);
+
+npy_longdouble npy_deg2radl(npy_longdouble x);
+npy_longdouble npy_rad2degl(npy_longdouble x);
+npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+                           npy_longdouble *modulus);
+
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+
+/*
+ * Complex declarations
+ */
+
+/*
+ * C99 specifies that complex numbers have the same representation as
+ * an array of two elements, where the first element is the real part
+ * and the second element is the imaginary part.
+ */
+#define __NPY_CPACK_IMP(x, y, type, ctype)   \
+    union {                                  \
+        ctype z;                             \
+        type a[2];                           \
+    } z1;;                                   \
+                                             \
+    z1.a[0] = (x);                           \
+    z1.a[1] = (y);                           \
+                                             \
+    return z1.z;
+
+static NPY_INLINE npy_cdouble npy_cpack(double x, double y)
+{
+    __NPY_CPACK_IMP(x, y, double, npy_cdouble);
+}
+
+static NPY_INLINE npy_cfloat npy_cpackf(float x, float y)
+{
+    __NPY_CPACK_IMP(x, y, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y)
+{
+    __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CPACK_IMP
+
+/*
+ * Same remark as above, but in the other direction: extract first/second
+ * member of complex number, assuming a C99-compatible representation
+ *
+ * Those are defineds as static inline, and such as a reasonable compiler would
+ * most likely compile this to one or two instructions (on CISC at least)
+ */
+#define __NPY_CEXTRACT_IMP(z, index, type, ctype)   \
+    union {                                         \
+        ctype z;                                    \
+        type a[2];                                  \
+    } __z_repr;                                     \
+    __z_repr.z = z;                                 \
+                                                    \
+    return __z_repr.a[index];
+
+static NPY_INLINE double npy_creal(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble);
+}
+
+static NPY_INLINE double npy_cimag(npy_cdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble);
+}
+
+static NPY_INLINE float npy_crealf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat);
+}
+
+static NPY_INLINE float npy_cimagf(npy_cfloat z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat);
+}
+
+static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble);
+}
+
+static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z)
+{
+    __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble);
+}
+#undef __NPY_CEXTRACT_IMP
+
+/*
+ * Double precision complex functions
+ */
+double npy_cabs(npy_cdouble z);
+double npy_carg(npy_cdouble z);
+
+npy_cdouble npy_cexp(npy_cdouble z);
+npy_cdouble npy_clog(npy_cdouble z);
+npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y);
+
+npy_cdouble npy_csqrt(npy_cdouble z);
+
+npy_cdouble npy_ccos(npy_cdouble z);
+npy_cdouble npy_csin(npy_cdouble z);
+npy_cdouble npy_ctan(npy_cdouble z);
+
+npy_cdouble npy_ccosh(npy_cdouble z);
+npy_cdouble npy_csinh(npy_cdouble z);
+npy_cdouble npy_ctanh(npy_cdouble z);
+
+npy_cdouble npy_cacos(npy_cdouble z);
+npy_cdouble npy_casin(npy_cdouble z);
+npy_cdouble npy_catan(npy_cdouble z);
+
+npy_cdouble npy_cacosh(npy_cdouble z);
+npy_cdouble npy_casinh(npy_cdouble z);
+npy_cdouble npy_catanh(npy_cdouble z);
+
+/*
+ * Single precision complex functions
+ */
+float npy_cabsf(npy_cfloat z);
+float npy_cargf(npy_cfloat z);
+
+npy_cfloat npy_cexpf(npy_cfloat z);
+npy_cfloat npy_clogf(npy_cfloat z);
+npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y);
+
+npy_cfloat npy_csqrtf(npy_cfloat z);
+
+npy_cfloat npy_ccosf(npy_cfloat z);
+npy_cfloat npy_csinf(npy_cfloat z);
+npy_cfloat npy_ctanf(npy_cfloat z);
+
+npy_cfloat npy_ccoshf(npy_cfloat z);
+npy_cfloat npy_csinhf(npy_cfloat z);
+npy_cfloat npy_ctanhf(npy_cfloat z);
+
+npy_cfloat npy_cacosf(npy_cfloat z);
+npy_cfloat npy_casinf(npy_cfloat z);
+npy_cfloat npy_catanf(npy_cfloat z);
+
+npy_cfloat npy_cacoshf(npy_cfloat z);
+npy_cfloat npy_casinhf(npy_cfloat z);
+npy_cfloat npy_catanhf(npy_cfloat z);
+
+
+/*
+ * Extended precision complex functions
+ */
+npy_longdouble npy_cabsl(npy_clongdouble z);
+npy_longdouble npy_cargl(npy_clongdouble z);
+
+npy_clongdouble npy_cexpl(npy_clongdouble z);
+npy_clongdouble npy_clogl(npy_clongdouble z);
+npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y);
+
+npy_clongdouble npy_csqrtl(npy_clongdouble z);
+
+npy_clongdouble npy_ccosl(npy_clongdouble z);
+npy_clongdouble npy_csinl(npy_clongdouble z);
+npy_clongdouble npy_ctanl(npy_clongdouble z);
+
+npy_clongdouble npy_ccoshl(npy_clongdouble z);
+npy_clongdouble npy_csinhl(npy_clongdouble z);
+npy_clongdouble npy_ctanhl(npy_clongdouble z);
+
+npy_clongdouble npy_cacosl(npy_clongdouble z);
+npy_clongdouble npy_casinl(npy_clongdouble z);
+npy_clongdouble npy_catanl(npy_clongdouble z);
+
+npy_clongdouble npy_cacoshl(npy_clongdouble z);
+npy_clongdouble npy_casinhl(npy_clongdouble z);
+npy_clongdouble npy_catanhl(npy_clongdouble z);
+
+
+/*
+ * Functions that set the floating point error
+ * status word.
+ */
+
+/*
+ * platform-dependent code translates floating point
+ * status to an integer sum of these values
+ */
+#define NPY_FPE_DIVIDEBYZERO  1
+#define NPY_FPE_OVERFLOW      2
+#define NPY_FPE_UNDERFLOW     4
+#define NPY_FPE_INVALID       8
+
+int npy_get_floatstatus(void);
+int npy_clear_floatstatus(void);
+void npy_set_floatstatus_divbyzero(void);
+void npy_set_floatstatus_overflow(void);
+void npy_set_floatstatus_underflow(void);
+void npy_set_floatstatus_invalid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
new file mode 100644
index 0000000000..6183dc2784
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
@@ -0,0 +1,19 @@
+/*
+ * This include file is provided for inclusion in Cython *.pyd files where
+ * one would like to define the NPY_NO_DEPRECATED_API macro. It can be
+ * included by
+ *
+ * cdef extern from "npy_no_deprecated_api.h": pass
+ *
+ */
+#ifndef NPY_NO_DEPRECATED_API
+
+/* put this check here since there may be multiple includes in C extensions. */
+#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \
+    defined(OLD_DEFINES_H)
+#error "npy_no_deprecated_api.h" must be first among numpy includes.
+#else
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
new file mode 100644
index 0000000000..9228c3916e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
@@ -0,0 +1,30 @@
+#ifndef _NPY_OS_H_
+#define _NPY_OS_H_
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+    #define NPY_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
+            defined(__OpenBSD__) || defined(__DragonFly__)
+    #define NPY_OS_BSD
+    #ifdef __FreeBSD__
+        #define NPY_OS_FREEBSD
+    #elif defined(__NetBSD__)
+        #define NPY_OS_NETBSD
+    #elif defined(__OpenBSD__)
+        #define NPY_OS_OPENBSD
+    #elif defined(__DragonFly__)
+        #define NPY_OS_DRAGONFLY
+    #endif
+#elif defined(sun) || defined(__sun)
+    #define NPY_OS_SOLARIS
+#elif defined(__CYGWIN__)
+    #define NPY_OS_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+    #define NPY_OS_WIN32
+#elif defined(__APPLE__)
+    #define NPY_OS_DARWIN
+#else
+    #define NPY_OS_UNKNOWN
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
new file mode 100644
index 0000000000..cbf4a62b9f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
@@ -0,0 +1,37 @@
+#ifndef _NPY_NUMPYCONFIG_H_
+#define _NPY_NUMPYCONFIG_H_
+
+#include "_numpyconfig.h"
+
+/*
+ * On Mac OS X, because there is only one configuration stage for all the archs
+ * in universal builds, any macro which depends on the arch needs to be
+ * harcoded
+ */
+#ifdef __APPLE__
+    #undef NPY_SIZEOF_LONG
+    #undef NPY_SIZEOF_PY_INTPTR_T
+
+    #ifdef __LP64__
+        #define NPY_SIZEOF_LONG         8
+        #define NPY_SIZEOF_PY_INTPTR_T  8
+    #else
+        #define NPY_SIZEOF_LONG         4
+        #define NPY_SIZEOF_PY_INTPTR_T  4
+    #endif
+#endif
+
+/**
+ * To help with the NPY_NO_DEPRECATED_API macro, we include API version
+ * numbers for specific versions of NumPy. To exclude all API that was
+ * deprecated as of 1.7, add the following before #including any NumPy
+ * headers:
+ *   #define NPY_NO_DEPRECATED_API  NPY_1_7_API_VERSION
+ */
+#define NPY_1_7_API_VERSION 0x00000007
+#define NPY_1_8_API_VERSION 0x00000008
+#define NPY_1_9_API_VERSION 0x00000008
+#define NPY_1_10_API_VERSION 0x00000008
+#define NPY_1_11_API_VERSION 0x00000008
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
new file mode 100644
index 0000000000..abf81595ae
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
@@ -0,0 +1,187 @@
+/* This header is deprecated as of NumPy 1.7 */
+#ifndef OLD_DEFINES_H
+#define OLD_DEFINES_H
+
+#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION
+#error The header "old_defines.h" is deprecated as of NumPy 1.7.
+#endif
+
+#define NDARRAY_VERSION NPY_VERSION
+
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+
+#define PyArray_TYPES       NPY_TYPES
+#define PyArray_BOOL        NPY_BOOL
+#define PyArray_BYTE        NPY_BYTE
+#define PyArray_UBYTE       NPY_UBYTE
+#define PyArray_SHORT       NPY_SHORT
+#define PyArray_USHORT      NPY_USHORT
+#define PyArray_INT         NPY_INT
+#define PyArray_UINT        NPY_UINT
+#define PyArray_LONG        NPY_LONG
+#define PyArray_ULONG       NPY_ULONG
+#define PyArray_LONGLONG    NPY_LONGLONG
+#define PyArray_ULONGLONG   NPY_ULONGLONG
+#define PyArray_HALF        NPY_HALF
+#define PyArray_FLOAT       NPY_FLOAT
+#define PyArray_DOUBLE      NPY_DOUBLE
+#define PyArray_LONGDOUBLE  NPY_LONGDOUBLE
+#define PyArray_CFLOAT      NPY_CFLOAT
+#define PyArray_CDOUBLE     NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT      NPY_OBJECT
+#define PyArray_STRING      NPY_STRING
+#define PyArray_UNICODE     NPY_UNICODE
+#define PyArray_VOID        NPY_VOID
+#define PyArray_DATETIME    NPY_DATETIME
+#define PyArray_TIMEDELTA   NPY_TIMEDELTA
+#define PyArray_NTYPES      NPY_NTYPES
+#define PyArray_NOTYPE      NPY_NOTYPE
+#define PyArray_CHAR        NPY_CHAR
+#define PyArray_USERDEF     NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+
+#define PyArray_INTP        NPY_INTP
+#define PyArray_UINTP       NPY_UINTP
+
+#define PyArray_INT8    NPY_INT8
+#define PyArray_UINT8   NPY_UINT8
+#define PyArray_INT16   NPY_INT16
+#define PyArray_UINT16  NPY_UINT16
+#define PyArray_INT32   NPY_INT32
+#define PyArray_UINT32  NPY_UINT32
+
+#ifdef NPY_INT64
+#define PyArray_INT64   NPY_INT64
+#define PyArray_UINT64  NPY_UINT64
+#endif
+
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#endif
+
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16  NPY_FLOAT16
+#define PyArray_COMPLEX32  NPY_COMPLEX32
+#endif
+
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80  NPY_FLOAT80
+#define PyArray_COMPLEX160  NPY_COMPLEX160
+#endif
+
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96  NPY_FLOAT96
+#define PyArray_COMPLEX192  NPY_COMPLEX192
+#endif
+
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128  NPY_FLOAT128
+#define PyArray_COMPLEX256  NPY_COMPLEX256
+#endif
+
+#define PyArray_FLOAT32    NPY_FLOAT32
+#define PyArray_COMPLEX64  NPY_COMPLEX64
+#define PyArray_FLOAT64    NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+
+
+#define PyArray_TYPECHAR        NPY_TYPECHAR
+#define PyArray_BOOLLTR         NPY_BOOLLTR
+#define PyArray_BYTELTR         NPY_BYTELTR
+#define PyArray_UBYTELTR        NPY_UBYTELTR
+#define PyArray_SHORTLTR        NPY_SHORTLTR
+#define PyArray_USHORTLTR       NPY_USHORTLTR
+#define PyArray_INTLTR          NPY_INTLTR
+#define PyArray_UINTLTR         NPY_UINTLTR
+#define PyArray_LONGLTR         NPY_LONGLTR
+#define PyArray_ULONGLTR        NPY_ULONGLTR
+#define PyArray_LONGLONGLTR     NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR    NPY_ULONGLONGLTR
+#define PyArray_HALFLTR         NPY_HALFLTR
+#define PyArray_FLOATLTR        NPY_FLOATLTR
+#define PyArray_DOUBLELTR       NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR   NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR       NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR      NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR  NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR       NPY_OBJECTLTR
+#define PyArray_STRINGLTR       NPY_STRINGLTR
+#define PyArray_STRINGLTR2      NPY_STRINGLTR2
+#define PyArray_UNICODELTR      NPY_UNICODELTR
+#define PyArray_VOIDLTR         NPY_VOIDLTR
+#define PyArray_DATETIMELTR     NPY_DATETIMELTR
+#define PyArray_TIMEDELTALTR    NPY_TIMEDELTALTR
+#define PyArray_CHARLTR         NPY_CHARLTR
+#define PyArray_INTPLTR         NPY_INTPLTR
+#define PyArray_UINTPLTR        NPY_UINTPLTR
+#define PyArray_GENBOOLLTR      NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR       NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR     NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR     NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR      NPY_COMPLEXLTR
+
+#define PyArray_QUICKSORT   NPY_QUICKSORT
+#define PyArray_HEAPSORT    NPY_HEAPSORT
+#define PyArray_MERGESORT   NPY_MERGESORT
+#define PyArray_SORTKIND    NPY_SORTKIND
+#define PyArray_NSORTS      NPY_NSORTS
+
+#define PyArray_NOSCALAR       NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR    NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR  NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR  NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR   NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR  NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND     NPY_SCALARKIND
+#define PyArray_NSCALARKINDS   NPY_NSCALARKINDS
+
+#define PyArray_ANYORDER     NPY_ANYORDER
+#define PyArray_CORDER       NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER        NPY_ORDER
+
+#define PyDescr_ISBOOL      PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED  PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED    PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER   PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT     PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER    PyDataType_ISNUMBER
+#define PyDescr_ISSTRING    PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX   PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON    PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE  PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF   PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED  PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT    PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS   PyDataType_HASFIELDS
+
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+
+#define PyArray_RemoveLargest PyArray_RemoveSmallest
+
+#define PyArray_UCS4 npy_ucs4
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
new file mode 100644
index 0000000000..748f06da31
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
@@ -0,0 +1,23 @@
+#include "arrayobject.h"
+
+#ifndef REFCOUNT
+#  define REFCOUNT NPY_REFCOUNT
+#  define MAX_ELSIZE 16
+#endif
+
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE NPY_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define OWN_DATA NPY_OWNDATA
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
new file mode 100644
index 0000000000..172749633f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
@@ -0,0 +1,321 @@
+
+=================
+Numpy Ufunc C-API
+=================
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void
+                          **data, char *types, int ntypes, int nin, int
+                          nout, int identity, const char *name, const
+                          char *doc, int unused)
+
+
+::
+
+  int
+  PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int
+                              usertype, PyUFuncGenericFunction
+                              function, int *arg_types, void *data)
+
+
+::
+
+  int
+  PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject
+                          *kwds, PyArrayObject **op)
+
+
+This generic function is called with the ufunc object, the arguments to it,
+and an array of (pointers to) PyArrayObjects which are NULL.
+
+'op' is an array of at least NPY_MAXARGS PyArrayObject *.
+
+::
+
+  void
+  PyUFunc_f_f_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_g_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_F_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_G_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_O_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_gg_g(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_FF_F(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_GG_G(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_O_O_method(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_OO_O_method(char **args, npy_intp *dimensions, npy_intp
+                      *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_On_Om(char **args, npy_intp *dimensions, npy_intp *steps, void
+                *func)
+
+
+::
+
+  int
+  PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject
+                      **errobj)
+
+
+On return, if errobj is populated with a non-NULL value, the caller
+owns a new reference to errobj.
+
+::
+
+  int
+  PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first)
+
+
+::
+
+  void
+  PyUFunc_clearfperr()
+
+
+::
+
+  int
+  PyUFunc_getfperr(void )
+
+
+::
+
+  int
+  PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int
+                      *first)
+
+
+::
+
+  int
+  PyUFunc_ReplaceLoopBySignature(PyUFuncObject
+                                 *func, PyUFuncGenericFunction
+                                 newfunc, int
+                                 *signature, PyUFuncGenericFunction
+                                 *oldfunc)
+
+
+::
+
+  PyObject *
+  PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void
+                                      **data, char *types, int
+                                      ntypes, int nin, int nout, int
+                                      identity, const char *name, const
+                                      char *doc, int unused, const char
+                                      *signature)
+
+
+::
+
+  int
+  PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+
+
+::
+
+  void
+  PyUFunc_e_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+              *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_f_f(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_e_e_As_d_d(char **args, npy_intp *dimensions, npy_intp
+                     *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e(char **args, npy_intp *dimensions, npy_intp *steps, void
+               *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_ff_f(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  void
+  PyUFunc_ee_e_As_dd_d(char **args, npy_intp *dimensions, npy_intp
+                       *steps, void *func)
+
+
+::
+
+  int
+  PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING
+                              casting, PyArrayObject
+                              **operands, PyObject
+                              *type_tup, PyArray_Descr **out_dtypes)
+
+
+This function applies the default type resolution rules
+for the provided ufunc.
+
+Returns 0 on success, -1 on error.
+
+::
+
+  int
+  PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING
+                          casting, PyArrayObject
+                          **operands, PyArray_Descr **dtypes)
+
+
+Validates that the input operands can be cast to
+the input types, and the output types can be cast to
+the output operands where provided.
+
+Returns 0 on success, -1 (with exception raised) on validation failure.
+
+::
+
+  int
+  PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr
+                               *user_dtype, PyUFuncGenericFunction
+                               function, PyArray_Descr
+                               **arg_dtypes, void *data)
+
+
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
new file mode 100644
index 0000000000..1cca64b75b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
@@ -0,0 +1,357 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+
+#include <numpy/npy_math.h>
+#include <numpy/npy_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The legacy generic inner loop for a standard element-wise or
+ * generalized ufunc.
+ */
+typedef void (*PyUFuncGenericFunction)
+            (char **args,
+             npy_intp *dimensions,
+             npy_intp *strides,
+             void *innerloopdata);
+
+/*
+ * The most generic one-dimensional inner loop for
+ * a masked standard element-wise ufunc. "Masked" here means that it skips
+ * doing calculations on any items for which the maskptr array has a true
+ * value.
+ */
+typedef void (PyUFunc_MaskedStridedInnerLoopFunc)(
+                char **dataptrs, npy_intp *strides,
+                char *maskptr, npy_intp mask_stride,
+                npy_intp count,
+                NpyAuxData *innerloopdata);
+
+/* Forward declaration for the type resolver and loop selector typedefs */
+struct _tagPyUFuncObject;
+
+/*
+ * Given the operands for calling a ufunc, should determine the
+ * calculation input and output data types and return an inner loop function.
+ * This function should validate that the casting rule is being followed,
+ * and fail if it is not.
+ *
+ * For backwards compatibility, the regular type resolution function does not
+ * support auxiliary data with object semantics. The type resolution call
+ * which returns a masked generic function returns a standard NpyAuxData
+ * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros
+ * work.
+ *
+ * ufunc:             The ufunc object.
+ * casting:           The 'casting' parameter provided to the ufunc.
+ * operands:          An array of length (ufunc->nin + ufunc->nout),
+ *                    with the output parameters possibly NULL.
+ * type_tup:          Either NULL, or the type_tup passed to the ufunc.
+ * out_dtypes:        An array which should be populated with new
+ *                    references to (ufunc->nin + ufunc->nout) new
+ *                    dtypes, one for each input and output. These
+ *                    dtypes should all be in native-endian format.
+ *
+ * Should return 0 on success, -1 on failure (with exception set),
+ * or -2 if Py_NotImplemented should be returned.
+ */
+typedef int (PyUFunc_TypeResolutionFunc)(
+                                struct _tagPyUFuncObject *ufunc,
+                                NPY_CASTING casting,
+                                PyArrayObject **operands,
+                                PyObject *type_tup,
+                                PyArray_Descr **out_dtypes);
+
+/*
+ * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc,
+ * and an array of fixed strides (the array will contain NPY_MAX_INTP for
+ * strides which are not necessarily fixed), returns an inner loop
+ * with associated auxiliary data.
+ *
+ * For backwards compatibility, there is a variant of the inner loop
+ * selection which returns an inner loop irrespective of the strides,
+ * and with a void* static auxiliary data instead of an NpyAuxData *
+ * dynamically allocatable auxiliary data.
+ *
+ * ufunc:             The ufunc object.
+ * dtypes:            An array which has been populated with dtypes,
+ *                    in most cases by the type resolution funciton
+ *                    for the same ufunc.
+ * fixed_strides:     For each input/output, either the stride that
+ *                    will be used every time the function is called
+ *                    or NPY_MAX_INTP if the stride might change or
+ *                    is not known ahead of time. The loop selection
+ *                    function may use this stride to pick inner loops
+ *                    which are optimized for contiguous or 0-stride
+ *                    cases.
+ * out_innerloop:     Should be populated with the correct ufunc inner
+ *                    loop for the given type.
+ * out_innerloopdata: Should be populated with the void* data to
+ *                    be passed into the out_innerloop function.
+ * out_needs_api:     If the inner loop needs to use the Python API,
+ *                    should set the to 1, otherwise should leave
+ *                    this untouched.
+ */
+typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyUFuncGenericFunction *out_innerloop,
+                            void **out_innerloopdata,
+                            int *out_needs_api);
+typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
+                            struct _tagPyUFuncObject *ufunc,
+                            PyArray_Descr **dtypes,
+                            PyArray_Descr *mask_dtype,
+                            npy_intp *fixed_strides,
+                            npy_intp fixed_mask_stride,
+                            PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
+                            NpyAuxData **out_innerloopdata,
+                            int *out_needs_api);
+
+typedef struct _tagPyUFuncObject {
+        PyObject_HEAD
+        /*
+         * nin: Number of inputs
+         * nout: Number of outputs
+         * nargs: Always nin + nout (Why is it stored?)
+         */
+        int nin, nout, nargs;
+
+        /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */
+        int identity;
+
+        /* Array of one-dimensional core loops */
+        PyUFuncGenericFunction *functions;
+        /* Array of funcdata that gets passed into the functions */
+        void **data;
+        /* The number of elements in 'functions' and 'data' */
+        int ntypes;
+
+        /* Used to be unused field 'check_return' */
+        int reserved1;
+
+        /* The name of the ufunc */
+        const char *name;
+
+        /* Array of type numbers, of size ('nargs' * 'ntypes') */
+        char *types;
+
+        /* Documentation string */
+        const char *doc;
+
+        void *ptr;
+        PyObject *obj;
+        PyObject *userloops;
+
+        /* generalized ufunc parameters */
+
+        /* 0 for scalar ufunc; 1 for generalized ufunc */
+        int core_enabled;
+        /* number of distinct dimension names in signature */
+        int core_num_dim_ix;
+
+        /*
+         * dimension indices of input/output argument k are stored in
+         * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1]
+         */
+
+        /* numbers of core dimensions of each argument */
+        int *core_num_dims;
+        /*
+         * dimension indices in a flatted form; indices
+         * are in the range of [0,core_num_dim_ix)
+         */
+        int *core_dim_ixs;
+        /*
+         * positions of 1st core dimensions of each
+         * argument in core_dim_ixs
+         */
+        int *core_offsets;
+        /* signature string for printing purpose */
+        char *core_signature;
+
+        /*
+         * A function which resolves the types and fills an array
+         * with the dtypes for the inputs and outputs.
+         */
+        PyUFunc_TypeResolutionFunc *type_resolver;
+        /*
+         * A function which returns an inner loop written for
+         * NumPy 1.6 and earlier ufuncs. This is for backwards
+         * compatibility, and may be NULL if inner_loop_selector
+         * is specified.
+         */
+        PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
+        /*
+         * This was blocked off to be the "new" inner loop selector in 1.7,
+         * but this was never implemented. (This is also why the above
+         * selector is called the "legacy" selector.)
+         */
+        void *reserved2;
+        /*
+         * A function which returns a masked inner loop for the ufunc.
+         */
+        PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+
+        /*
+         * List of flags for each operand when ufunc is called by nditer object.
+         * These flags will be used in addition to the default flags for each
+         * operand set by nditer object.
+         */
+        npy_uint32 *op_flags;
+
+        /*
+         * List of global flags used when ufunc is called by nditer object.
+         * These flags will be used in addition to the default global flags
+         * set by nditer object.
+         */
+        npy_uint32 iter_flags;
+} PyUFuncObject;
+
+#include "arrayobject.h"
+
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN   1
+#define UFUNC_ERR_RAISE  2
+#define UFUNC_ERR_CALL   3
+#define UFUNC_ERR_PRINT  4
+#define UFUNC_ERR_LOG    5
+
+        /* Python side integer mask */
+
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW     3
+#define UFUNC_SHIFT_UNDERFLOW    6
+#define UFUNC_SHIFT_INVALID      9
+
+
+#define UFUNC_OBJ_ISOBJECT      1
+#define UFUNC_OBJ_NEEDS_API     2
+
+   /* Default user error mode */
+#define UFUNC_ERR_DEFAULT                               \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) +  \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) +      \
+        (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
+
+#if NPY_ALLOW_THREADS
+#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0);
+#define NPY_LOOP_END_THREADS   do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0);
+#else
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+#endif
+
+/*
+ * UFunc has unit of 1, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_One 1
+/*
+ * UFunc has unit of 0, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_Zero 0
+/*
+ * UFunc has no unit, and the order of operations cannot be reordered.
+ * This case does not allow reduction with multiple axes at once.
+ */
+#define PyUFunc_None -1
+/*
+ * UFunc has no unit, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+ */
+#define PyUFunc_ReorderableNone -2
+
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+
+
+typedef struct {
+        int nin;
+        int nout;
+        PyObject *callable;
+} PyUFunc_PyFuncData;
+
+/* A linked-list of function information for
+   user-defined 1-d loops.
+ */
+typedef struct _loop1d_info {
+        PyUFuncGenericFunction func;
+        void *data;
+        int *arg_types;
+        struct _loop1d_info *next;
+        int nargs;
+        PyArray_Descr **arg_dtypes;
+} PyUFunc_Loop1d;
+
+
+#include "__ufunc_api.h"
+
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+
+#define UFUNC_CHECK_ERROR(arg) \
+        do {if ((((arg)->obj & UFUNC_OBJ_NEEDS_API) && PyErr_Occurred()) || \
+            ((arg)->errormask && \
+             PyUFunc_checkfperr((arg)->errormask, \
+                                (arg)->errobj, \
+                                &(arg)->first))) \
+                goto fail;} while (0)
+
+
+/* keep in sync with ieee754.c.src */
+#if defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version < 502114)) || \
+      defined(__NetBSD__) || \
+      defined(__GLIBC__) || defined(__APPLE__) || \
+      defined(__CYGWIN__) || defined(__MINGW32__) || \
+      (defined(__FreeBSD__) && (__FreeBSD_version >= 502114)) || \
+      defined(_AIX) || \
+      defined(_MSC_VER) || \
+      defined(__osf__) && defined(__alpha)
+#else
+#define NO_FLOATING_POINT_SUPPORT
+#endif
+
+
+/*
+ * THESE MACROS ARE DEPRECATED.
+ * Use npy_set_floatstatus_* in the npymath library.
+ */
+#define UFUNC_FPE_DIVIDEBYZERO  NPY_FPE_DIVIDEBYZERO
+#define UFUNC_FPE_OVERFLOW      NPY_FPE_OVERFLOW
+#define UFUNC_FPE_UNDERFLOW     NPY_FPE_UNDERFLOW
+#define UFUNC_FPE_INVALID       NPY_FPE_INVALID
+
+#define UFUNC_CHECK_STATUS(ret) \
+    { \
+       ret = npy_clear_floatstatus(); \
+    }
+#define generate_divbyzero_error() npy_set_floatstatus_divbyzero()
+#define generate_overflow_error() npy_set_floatstatus_overflow()
+
+  /* Make sure it gets defined if it isn't already */
+#ifndef UFUNC_NOFPE
+/* Clear the floating point exception default of Borland C++ */
+#if defined(__BORLANDC__)
+#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM);
+#else
+#define UFUNC_NOFPE
+#endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UFUNCOBJECT_H */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
new file mode 100644
index 0000000000..cc968a3544
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
@@ -0,0 +1,19 @@
+#ifndef __NUMPY_UTILS_HEADER__
+#define __NUMPY_UTILS_HEADER__
+
+#ifndef __COMP_NPY_UNUSED
+        #if defined(__GNUC__)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        # elif defined(__ICC)
+                #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+        #else
+                #define __COMP_NPY_UNUSED
+        #endif
+#endif
+
+/* Use this to tag a variable as not used. It will remove unused variable
+ * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable
+ * to avoid accidental use */
+#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/info.py
new file mode 100644
index 0000000000..241f209b55
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/info.py
@@ -0,0 +1,87 @@
+"""Defines a multi-dimensional array and useful procedures for Numerical computation.
+
+Functions
+
+-   array                      - NumPy Array construction
+-   zeros                      - Return an array of all zeros
+-   empty                      - Return an unitialized array
+-   shape                      - Return shape of sequence or array
+-   rank                       - Return number of dimensions
+-   size                       - Return number of elements in entire array or a
+                                 certain dimension
+-   fromstring                 - Construct array from (byte) string
+-   take                       - Select sub-arrays using sequence of indices
+-   put                        - Set sub-arrays using sequence of 1-D indices
+-   putmask                    - Set portion of arrays using a mask
+-   reshape                    - Return array with new shape
+-   repeat                     - Repeat elements of array
+-   choose                     - Construct new array from indexed array tuple
+-   correlate                  - Correlate two 1-d arrays
+-   searchsorted               - Search for element in 1-d array
+-   sum                        - Total sum over a specified dimension
+-   average                    - Average, possibly weighted, over axis or array.
+-   cumsum                     - Cumulative sum over a specified dimension
+-   product                    - Total product over a specified dimension
+-   cumproduct                 - Cumulative product over a specified dimension
+-   alltrue                    - Logical and over an entire axis
+-   sometrue                   - Logical or over an entire axis
+-   allclose                   - Tests if sequences are essentially equal
+
+More Functions:
+
+-   arange                     - Return regularly spaced array
+-   asarray                    - Guarantee NumPy array
+-   convolve                   - Convolve two 1-d arrays
+-   swapaxes                   - Exchange axes
+-   concatenate                - Join arrays together
+-   transpose                  - Permute axes
+-   sort                       - Sort elements of array
+-   argsort                    - Indices of sorted array
+-   argmax                     - Index of largest value
+-   argmin                     - Index of smallest value
+-   inner                      - Innerproduct of two arrays
+-   dot                        - Dot product (matrix multiplication)
+-   outer                      - Outerproduct of two arrays
+-   resize                     - Return array with arbitrary new shape
+-   indices                    - Tuple of indices
+-   fromfunction               - Construct array from universal function
+-   diagonal                   - Return diagonal array
+-   trace                      - Trace of array
+-   dump                       - Dump array to file object (pickle)
+-   dumps                      - Return pickled string representing data
+-   load                       - Return array stored in file object
+-   loads                      - Return array from pickled string
+-   ravel                      - Return array as 1-D
+-   nonzero                    - Indices of nonzero elements for 1-D array
+-   shape                      - Shape of array
+-   where                      - Construct array from binary result
+-   compress                   - Elements of array where condition is true
+-   clip                       - Clip array between two values
+-   ones                       - Array of all ones
+-   identity                   - 2-D identity array (matrix)
+
+(Universal) Math Functions
+
+       add                    logical_or             exp
+       subtract               logical_xor            log
+       multiply               logical_not            log10
+       divide                 maximum                sin
+       divide_safe            minimum                sinh
+       conjugate              bitwise_and            sqrt
+       power                  bitwise_or             tan
+       absolute               bitwise_xor            tanh
+       negative               invert                 ceil
+       greater                left_shift             fabs
+       greater_equal          right_shift            floor
+       less                   arccos                 arctan2
+       less_equal             arcsin                 fmod
+       equal                  arctan                 hypot
+       not_equal              cos                    around
+       logical_and            cosh                   sign
+       arccosh                arcsinh                arctanh
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['testing']
+global_symbols = ['*']
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
new file mode 100644
index 0000000000..290c51994e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
@@ -0,0 +1,12 @@
+[meta]
+Name = mlib
+Description = Math library used with this version of numpy
+Version = 1.0
+
+[default]
+Libs=
+Cflags=
+
+[msvc]
+Libs=
+Cflags=
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
new file mode 100644
index 0000000000..c8b897f3f0
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
@@ -0,0 +1,20 @@
+[meta]
+Name=npymath
+Description=Portable, core math library implementing C99 standard
+Version=0.1
+
+[variables]
+pkgname=numpy.core
+prefix=${pkgdir}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+[default]
+Libs=-L${libdir} -lnpymath
+Cflags=-I${includedir}
+Requires=mlib
+
+[msvc]
+Libs=/LIBPATH:${libdir} npymath.lib
+Cflags=/INCLUDE:${includedir}
+Requires=mlib
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/machar.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/machar.py
new file mode 100644
index 0000000000..6f2735d325
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/machar.py
@@ -0,0 +1,342 @@
+"""
+Machine arithmetics - determine the parameters of the
+floating-point arithmetic system
+
+Author: Pearu Peterson, September 2003
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['MachAr']
+
+from numpy.core.fromnumeric import any
+from numpy.core.numeric import errstate
+
+# Need to speed this up...especially for longfloat
+
+class MachAr(object):
+    """
+    Diagnosing machine parameters.
+
+    Attributes
+    ----------
+    ibeta : int
+        Radix in which numbers are represented.
+    it : int
+        Number of base-`ibeta` digits in the floating point mantissa M.
+    machep : int
+        Exponent of the smallest (most negative) power of `ibeta` that,
+        added to 1.0, gives something different from 1.0
+    eps : float
+        Floating-point number ``beta**machep`` (floating point precision)
+    negep : int
+        Exponent of the smallest power of `ibeta` that, substracted
+        from 1.0, gives something different from 1.0.
+    epsneg : float
+        Floating-point number ``beta**negep``.
+    iexp : int
+        Number of bits in the exponent (including its sign and bias).
+    minexp : int
+        Smallest (most negative) power of `ibeta` consistent with there
+        being no leading zeros in the mantissa.
+    xmin : float
+        Floating point number ``beta**minexp`` (the smallest [in
+        magnitude] usable floating value).
+    maxexp : int
+        Smallest (positive) power of `ibeta` that causes overflow.
+    xmax : float
+        ``(1-epsneg) * beta**maxexp`` (the largest [in magnitude]
+        usable floating value).
+    irnd : int
+        In ``range(6)``, information on what kind of rounding is done
+        in addition, and on how underflow is handled.
+    ngrd : int
+        Number of 'guard digits' used when truncating the product
+        of two mantissas to fit the representation.
+    epsilon : float
+        Same as `eps`.
+    tiny : float
+        Same as `xmin`.
+    huge : float
+        Same as `xmax`.
+    precision : float
+        ``- int(-log10(eps))``
+    resolution : float
+        ``- 10**(-precision)``
+
+    Parameters
+    ----------
+    float_conv : function, optional
+        Function that converts an integer or integer array to a float
+        or float array. Default is `float`.
+    int_conv : function, optional
+        Function that converts a float or float array to an integer or
+        integer array. Default is `int`.
+    float_to_float : function, optional
+        Function that converts a float array to float. Default is `float`.
+        Note that this does not seem to do anything useful in the current
+        implementation.
+    float_to_str : function, optional
+        Function that converts a single float to a string. Default is
+        ``lambda v:'%24.16e' %v``.
+    title : str, optional
+        Title that is printed in the string representation of `MachAr`.
+
+    See Also
+    --------
+    finfo : Machine limits for floating point types.
+    iinfo : Machine limits for integer types.
+
+    References
+    ----------
+    .. [1] Press, Teukolsky, Vetterling and Flannery,
+           "Numerical Recipes in C++," 2nd ed,
+           Cambridge University Press, 2002, p. 31.
+
+    """
+
+    def __init__(self, float_conv=float,int_conv=int,
+                 float_to_float=float,
+                 float_to_str=lambda v:'%24.16e' % v,
+                 title='Python floating point number'):
+        """
+
+        float_conv - convert integer to float (array)
+        int_conv   - convert float (array) to integer
+        float_to_float - convert float array to float
+        float_to_str - convert array float to str
+        title        - description of used floating point numbers
+
+        """
+        # We ignore all errors here because we are purposely triggering
+        # underflow to detect the properties of the runninng arch.
+        with errstate(under='ignore'):
+            self._do_init(float_conv, int_conv, float_to_float, float_to_str, title)
+
+    def _do_init(self, float_conv, int_conv, float_to_float, float_to_str, title):
+        max_iterN = 10000
+        msg = "Did not converge after %d tries with %s"
+        one = float_conv(1)
+        two = one + one
+        zero = one - one
+
+        # Do we really need to do this?  Aren't they 2 and 2.0?
+        # Determine ibeta and beta
+        a = one
+        for _ in range(max_iterN):
+            a = a + a
+            temp = a + one
+            temp1 = temp - a
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        b = one
+        for _ in range(max_iterN):
+            b = b + b
+            temp = a + b
+            itemp = int_conv(temp-a)
+            if any(itemp != 0):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        ibeta = itemp
+        beta = float_conv(ibeta)
+
+        # Determine it and irnd
+        it = -1
+        b = one
+        for _ in range(max_iterN):
+            it = it + 1
+            b = b * beta
+            temp = b + one
+            temp1 = temp - b
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+
+        betah = beta / two
+        a = one
+        for _ in range(max_iterN):
+            a = a + a
+            temp = a + one
+            temp1 = temp - a
+            if any(temp1 - one != zero):
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        temp = a + betah
+        irnd = 0
+        if any(temp-a != zero):
+            irnd = 1
+        tempa = a + beta
+        temp = tempa + betah
+        if irnd == 0 and any(temp-tempa != zero):
+            irnd = 2
+
+        # Determine negep and epsneg
+        negep = it + 3
+        betain = one / beta
+        a = one
+        for i in range(negep):
+            a = a * betain
+        b = a
+        for _ in range(max_iterN):
+            temp = one - a
+            if any(temp-one != zero):
+                break
+            a = a * beta
+            negep = negep - 1
+            # Prevent infinite loop on PPC with gcc 4.0:
+            if negep < 0:
+                raise RuntimeError("could not determine machine tolerance "
+                                   "for 'negep', locals() -> %s" % (locals()))
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        negep = -negep
+        epsneg = a
+
+        # Determine machep and eps
+        machep = - it - 3
+        a = b
+
+        for _ in range(max_iterN):
+            temp = one + a
+            if any(temp-one != zero):
+                break
+            a = a * beta
+            machep = machep + 1
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        eps = a
+
+        # Determine ngrd
+        ngrd = 0
+        temp = one + eps
+        if irnd == 0 and any(temp*one - one != zero):
+            ngrd = 1
+
+        # Determine iexp
+        i = 0
+        k = 1
+        z = betain
+        t = one + eps
+        nxres = 0
+        for _ in range(max_iterN):
+            y = z
+            z = y*y
+            a = z*one  # Check here for underflow
+            temp = z*t
+            if any(a+a == zero) or any(abs(z) >= y):
+                break
+            temp1 = temp * betain
+            if any(temp1*beta == z):
+                break
+            i = i + 1
+            k = k + k
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        if ibeta != 10:
+            iexp = i + 1
+            mx = k + k
+        else:
+            iexp = 2
+            iz = ibeta
+            while k >= iz:
+                iz = iz * ibeta
+                iexp = iexp + 1
+            mx = iz + iz - 1
+
+        # Determine minexp and xmin
+        for _ in range(max_iterN):
+            xmin = y
+            y = y * betain
+            a = y * one
+            temp = y * t
+            if any((a + a) != zero) and any(abs(y) < xmin):
+                k = k + 1
+                temp1 = temp * betain
+                if any(temp1*beta == y) and any(temp != y):
+                    nxres = 3
+                    xmin = y
+                    break
+            else:
+                break
+        else:
+            raise RuntimeError(msg % (_, one.dtype))
+        minexp = -k
+
+        # Determine maxexp, xmax
+        if mx <= k + k - 3 and ibeta != 10:
+            mx = mx + mx
+            iexp = iexp + 1
+        maxexp = mx + minexp
+        irnd = irnd + nxres
+        if irnd >= 2:
+            maxexp = maxexp - 2
+        i = maxexp + minexp
+        if ibeta == 2 and not i:
+            maxexp = maxexp - 1
+        if i > 20:
+            maxexp = maxexp - 1
+        if any(a != y):
+            maxexp = maxexp - 2
+        xmax = one - epsneg
+        if any(xmax*one != xmax):
+            xmax = one - beta*epsneg
+        xmax = xmax / (xmin*beta*beta*beta)
+        i = maxexp + minexp + 3
+        for j in range(i):
+            if ibeta == 2:
+                xmax = xmax + xmax
+            else:
+                xmax = xmax * beta
+
+        self.ibeta = ibeta
+        self.it = it
+        self.negep = negep
+        self.epsneg = float_to_float(epsneg)
+        self._str_epsneg = float_to_str(epsneg)
+        self.machep = machep
+        self.eps = float_to_float(eps)
+        self._str_eps = float_to_str(eps)
+        self.ngrd = ngrd
+        self.iexp = iexp
+        self.minexp = minexp
+        self.xmin = float_to_float(xmin)
+        self._str_xmin = float_to_str(xmin)
+        self.maxexp = maxexp
+        self.xmax = float_to_float(xmax)
+        self._str_xmax = float_to_str(xmax)
+        self.irnd = irnd
+
+        self.title = title
+        # Commonly used parameters
+        self.epsilon = self.eps
+        self.tiny = self.xmin
+        self.huge = self.xmax
+
+        import math
+        self.precision = int(-math.log10(float_to_float(self.eps)))
+        ten = two + two + two + two + two
+        resolution = ten ** (-self.precision)
+        self.resolution = float_to_float(resolution)
+        self._str_resolution = float_to_str(resolution)
+
+    def __str__(self):
+        fmt = (
+           'Machine parameters for %(title)s\n'
+           '---------------------------------------------------------------------\n'
+           'ibeta=%(ibeta)s it=%(it)s iexp=%(iexp)s ngrd=%(ngrd)s irnd=%(irnd)s\n'
+           'machep=%(machep)s     eps=%(_str_eps)s (beta**machep == epsilon)\n'
+           'negep =%(negep)s  epsneg=%(_str_epsneg)s (beta**epsneg)\n'
+           'minexp=%(minexp)s   xmin=%(_str_xmin)s (beta**minexp == tiny)\n'
+           'maxexp=%(maxexp)s    xmax=%(_str_xmax)s ((1-epsneg)*beta**maxexp == huge)\n'
+           '---------------------------------------------------------------------\n'
+           )
+        return fmt % self.__dict__
+
+
+if __name__ == '__main__':
+    print(MachAr())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/memmap.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/memmap.py
new file mode 100644
index 0000000000..70d7b72b47
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/memmap.py
@@ -0,0 +1,311 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from .numeric import uint8, ndarray, dtype
+from numpy.compat import long, basestring
+
+__all__ = ['memmap']
+
+dtypedescr = dtype
+valid_filemodes = ["r", "c", "r+", "w+"]
+writeable_filemodes = ["r+", "w+"]
+
+mode_equivalents = {
+    "readonly":"r",
+    "copyonwrite":"c",
+    "readwrite":"r+",
+    "write":"w+"
+    }
+
+class memmap(ndarray):
+    """Create a memory-map to an array stored in a *binary* file on disk.
+
+    Memory-mapped files are used for accessing small segments of large files
+    on disk, without reading the entire file into memory.  Numpy's
+    memmap's are array-like objects.  This differs from Python's ``mmap``
+    module, which uses file-like objects.
+
+    This subclass of ndarray has some unpleasant interactions with
+    some operations, because it doesn't quite fit properly as a subclass.
+    An alternative to using this subclass is to create the ``mmap``
+    object yourself, then create an ndarray with ndarray.__new__ directly,
+    passing the object created in its 'buffer=' parameter.
+
+    This class may at some point be turned into a factory function
+    which returns a view into an mmap buffer.
+
+    Delete the memmap instance to close.
+
+
+    Parameters
+    ----------
+    filename : str or file-like object
+        The file name or file object to be used as the array data buffer.
+    dtype : data-type, optional
+        The data-type used to interpret the file contents.
+        Default is `uint8`.
+    mode : {'r+', 'r', 'w+', 'c'}, optional
+        The file is opened in this mode:
+
+        +------+-------------------------------------------------------------+
+        | 'r'  | Open existing file for reading only.                        |
+        +------+-------------------------------------------------------------+
+        | 'r+' | Open existing file for reading and writing.                 |
+        +------+-------------------------------------------------------------+
+        | 'w+' | Create or overwrite existing file for reading and writing.  |
+        +------+-------------------------------------------------------------+
+        | 'c'  | Copy-on-write: assignments affect data in memory, but       |
+        |      | changes are not saved to disk.  The file on disk is         |
+        |      | read-only.                                                  |
+        +------+-------------------------------------------------------------+
+
+        Default is 'r+'.
+    offset : int, optional
+        In the file, array data starts at this offset. Since `offset` is
+        measured in bytes, it should normally be a multiple of the byte-size
+        of `dtype`. When ``mode != 'r'``, even positive offsets beyond end of
+        file are valid; The file will be extended to accommodate the
+        additional data. By default, ``memmap`` will start at the beginning of
+        the file, even if ``filename`` is a file pointer ``fp`` and
+        ``fp.tell() != 0``.
+    shape : tuple, optional
+        The desired shape of the array. If ``mode == 'r'`` and the number
+        of remaining bytes after `offset` is not a multiple of the byte-size
+        of `dtype`, you must specify `shape`. By default, the returned array
+        will be 1-D with the number of elements determined by file size
+        and data-type.
+    order : {'C', 'F'}, optional
+        Specify the order of the ndarray memory layout:
+        :term:`row-major`, C-style or :term:`column-major`,
+        Fortran-style.  This only has an effect if the shape is
+        greater than 1-D.  The default order is 'C'.
+
+    Attributes
+    ----------
+    filename : str
+        Path to the mapped file.
+    offset : int
+        Offset position in the file.
+    mode : str
+        File mode.
+
+    Methods
+    -------
+    flush
+        Flush any changes in memory to file on disk.
+        When you delete a memmap object, flush is called first to write
+        changes to disk before removing the object.
+
+
+    Notes
+    -----
+    The memmap object can be used anywhere an ndarray is accepted.
+    Given a memmap ``fp``, ``isinstance(fp, numpy.ndarray)`` returns
+    ``True``.
+
+    Memory-mapped arrays use the Python memory-map object which
+    (prior to Python 2.5) does not allow files to be larger than a
+    certain size depending on the platform. This size is always < 2GB
+    even on 64-bit systems.
+
+    When a memmap causes a file to be created or extended beyond its
+    current size in the filesystem, the contents of the new part are
+    unspecified. On systems with POSIX filesystem semantics, the extended
+    part will be filled with zero bytes.
+
+    Examples
+    --------
+    >>> data = np.arange(12, dtype='float32')
+    >>> data.resize((3,4))
+
+    This example uses a temporary file so that doctest doesn't write
+    files to your directory. You would use a 'normal' filename.
+
+    >>> from tempfile import mkdtemp
+    >>> import os.path as path
+    >>> filename = path.join(mkdtemp(), 'newfile.dat')
+
+    Create a memmap with dtype and shape that matches our data:
+
+    >>> fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4))
+    >>> fp
+    memmap([[ 0.,  0.,  0.,  0.],
+            [ 0.,  0.,  0.,  0.],
+            [ 0.,  0.,  0.,  0.]], dtype=float32)
+
+    Write data to memmap array:
+
+    >>> fp[:] = data[:]
+    >>> fp
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    >>> fp.filename == path.abspath(filename)
+    True
+
+    Deletion flushes memory changes to disk before removing the object:
+
+    >>> del fp
+
+    Load the memmap and verify data was stored:
+
+    >>> newfp = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+    >>> newfp
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    Read-only memmap:
+
+    >>> fpr = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+    >>> fpr.flags.writeable
+    False
+
+    Copy-on-write memmap:
+
+    >>> fpc = np.memmap(filename, dtype='float32', mode='c', shape=(3,4))
+    >>> fpc.flags.writeable
+    True
+
+    It's possible to assign to copy-on-write array, but values are only
+    written into the memory copy of the array, and not written to disk:
+
+    >>> fpc
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+    >>> fpc[0,:] = 0
+    >>> fpc
+    memmap([[  0.,   0.,   0.,   0.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    File on disk is unchanged:
+
+    >>> fpr
+    memmap([[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.],
+            [  8.,   9.,  10.,  11.]], dtype=float32)
+
+    Offset into a memmap:
+
+    >>> fpo = np.memmap(filename, dtype='float32', mode='r', offset=16)
+    >>> fpo
+    memmap([  4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.], dtype=float32)
+
+    """
+
+    __array_priority__ = -100.0
+
+    def __new__(subtype, filename, dtype=uint8, mode='r+', offset=0,
+                shape=None, order='C'):
+        # Import here to minimize 'import numpy' overhead
+        import mmap
+        import os.path
+        try:
+            mode = mode_equivalents[mode]
+        except KeyError:
+            if mode not in valid_filemodes:
+                raise ValueError("mode must be one of %s" %
+                                 (valid_filemodes + list(mode_equivalents.keys())))
+
+        if hasattr(filename, 'read'):
+            fid = filename
+            own_file = False
+        else:
+            fid = open(filename, (mode == 'c' and 'r' or mode)+'b')
+            own_file = True
+
+        if (mode == 'w+') and shape is None:
+            raise ValueError("shape must be given")
+
+        fid.seek(0, 2)
+        flen = fid.tell()
+        descr = dtypedescr(dtype)
+        _dbytes = descr.itemsize
+
+        if shape is None:
+            bytes = flen - offset
+            if (bytes % _dbytes):
+                fid.close()
+                raise ValueError("Size of available data is not a "
+                        "multiple of the data-type size.")
+            size = bytes // _dbytes
+            shape = (size,)
+        else:
+            if not isinstance(shape, tuple):
+                shape = (shape,)
+            size = 1
+            for k in shape:
+                size *= k
+
+        bytes = long(offset + size*_dbytes)
+
+        if mode == 'w+' or (mode == 'r+' and flen < bytes):
+            fid.seek(bytes - 1, 0)
+            fid.write(np.compat.asbytes('\0'))
+            fid.flush()
+
+        if mode == 'c':
+            acc = mmap.ACCESS_COPY
+        elif mode == 'r':
+            acc = mmap.ACCESS_READ
+        else:
+            acc = mmap.ACCESS_WRITE
+
+        start = offset - offset % mmap.ALLOCATIONGRANULARITY
+        bytes -= start
+        offset -= start
+        mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
+
+        self = ndarray.__new__(subtype, shape, dtype=descr, buffer=mm,
+            offset=offset, order=order)
+        self._mmap = mm
+        self.offset = offset
+        self.mode = mode
+
+        if isinstance(filename, basestring):
+            self.filename = os.path.abspath(filename)
+        # py3 returns int for TemporaryFile().name
+        elif (hasattr(filename, "name") and
+              isinstance(filename.name, basestring)):
+            self.filename = os.path.abspath(filename.name)
+        # same as memmap copies (e.g. memmap + 1)
+        else:
+            self.filename = None
+
+        if own_file:
+            fid.close()
+
+        return self
+
+    def __array_finalize__(self, obj):
+        if hasattr(obj, '_mmap') and np.may_share_memory(self, obj):
+            self._mmap = obj._mmap
+            self.filename = obj.filename
+            self.offset = obj.offset
+            self.mode = obj.mode
+        else:
+            self._mmap = None
+            self.filename = None
+            self.offset = None
+            self.mode = None
+
+    def flush(self):
+        """
+        Write any changes in the array to the file on disk.
+
+        For further information, see `memmap`.
+
+        Parameters
+        ----------
+        None
+
+        See Also
+        --------
+        memmap
+
+        """
+        if self.base is not None and hasattr(self.base, 'flush'):
+            self.base.flush()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..68b3089acd3dd176cafdddd52cbe294159c132aa
GIT binary patch
literal 1437696
zcmeZ`n!v!!z`(%5z`*eTKLf)K1_*F~P<Y7(1_lN``CWVrTR6`u?qKves~D1zS*%b{
zl%HOdn5&SSn3tDdqL7rTP*j?ykeR38;vcM#o1c=Z$IHv50yR0nm4P9pjT_2?P#+ld
zl(?CgBpDcl7#QA&GBB7iGF%X5U|<jc$zMnZkzh6x#N8l1D+3dVVqjPx4i-$iB?k5v
z1A_uY9IO|_gfgHMTtq;eAppct5NC)m1u>x5K!m~N8k7y98pIinNPrmFu|k13g9a9<
z7;SNeA6!@@ph9{jsTCy*3=9$f1fl*E0{a6h4W<$p0uuC65=#;p7#MaO0)>YV1H%ze
z<OzZ0VT1!i!U4S^h{6eOj0_A9gcuk+7#SE&V5oD@D}bm2`_Vvzf#C+oToIU2VA_Gf
zz(KD9qRwCgNM4kIVG{!b!wW3xl8TE#niiNaGB8{a1u-#j1IT@;5c9xcE+EbTj=ou_
z>cRGALezodL_wT^!Hj`{VGf461A5LuAs~w)Ktux6yi4fn91iG}<bd6m0a8~0Rd)ql
z9Vq-#bMliJAaUIw&cGnWz`$?~U7djw$e5vwgFTwxDC}flWMFu4@v9(%N9RG0&ciR<
zE(<Vtbc^zT6=v{gz3tJ-<k2lE1mbiumGB!L@Hh@CG8jCXk0?YR-oePg0A=#aGdPAi
zhJ=QPfsEB?z2w<>#<%lmX;nAtl>MR%tq1t~<QW+lnqM$_bjwcqBFtd;zmv6UzbL~#
zuo>ODMbhF7ui1CLU}j+Wf7PS&#|IDojm93W2TI>~blVnw5oYLSZ~no=-|~!sfnldS
zC<W$x6J&t7KqERXKGreDG4^np9>07GI9i&2F@mK_@27fnv#1(?+}bTG_C=V%qq~5^
z@V`g5?q4Z!hS%c!@}T03!Nc+xe+xS!0|OREJU0C1(QW(cGsGE;{4KJK3=G}utq1s9
zzA}JV%|96VTf`X|7+Syaw_E~S#cKT-WEF!)>wywp-_94iK*f|#=fnROnpx}ji84T3
z=h1uw;dsLXFZKWb|DVP$@4~>~)2-V1S(w4In@8ovf{Owmb38hambm+L>o$VLeHmVK
zfW$kGc{IP{@UZ+^F6`0G2D0uwNZ|hk56iD*Z#_C+zDWEc$l!V06&x&{$63H7u;GE@
z>>vS;c4lxep*VzJ-T@LbFInO4F+AYW&iqmZ&iCjRjRgCU*Xgq`!*Ni^F}zs+MUdg;
z+kgN6L*nQJh<oqf|NkD{qC61AUq1;myy*BM$Z(t;6d*58|NH+R>|c25QSj(CjsGOf
z(0a+E^L*!JpU$J5Vx@`QtloP;38}>XMbjk#2G7nHhL=1#f4+G7K!Cxq^GNIM64vJ5
z%%v)xoi93Xfh6`k0ILFX96OJ^i23{ff9ru#W>>=}E}ajKv;F`7|35e#gOkqT2`{uS
z2{80J|A!gS{DZN4;R`jeu98zQ(HE%?1Q=QmICdT>m23XZSh^AJkUxL^|9`y{DgFIs
zEcJO|b{6c4UEpNi`SXPtOgn#T+5i6_%OKv6gSZyLVMOLE`Sbt(OIe6oa2f)6?)`nR
zuffp+OTW!;JUqHtTR#aiH2-2e4vJfb5-yMCBOWgo{`>!bf={Q5ibZFLiit<3kBY{N
zy=Md%Ufj4Uz~IyEqGHhv67Tj=(EzJ21gQ`8=zNNtpFn(2k>Sy7Td+@vfuY2}qnCI4
zX(5LHqPF7VpyXMi@6ju|`LqzIEcq{L0Ttx*=;d|TC&cjof=4f}I4Em0A5n;X8GBlQ
z!K0UT+W-ImU*83#H<0<UhbO>+NApj{GAobfpZw*L9-XH=4nAV@=w(gYEz01*c)_Dv
zz@zn2DYwVLhs-Y@9T#9oo8Zy>iqWG}z@yvc0>@!~d4^q}T)h*N#$F!>neWm33uIpF
z$r4$Q=3o5f;!qPsz$PB@=w|Y0{=rtp@pATY0S10~2A^IBMxRb5k4~RMVDmg$PlAms
zJ^lI)$UInC=hJ!Eqw}ms=k*sxCqTLMwnw+=iN|6L9-X=eAB%yapj&hUm@f<}Vr`c^
z7Grqv|F{5yN9PAvrUSVbQgkYKbe?<R_(71tquI9cu^0n`N9W-Zofp@SgCa__;ISA(
z=W*ZGOC>@+-Mmqc#TYz0KX`QBGCb+{|5E4A7c0QV-hd`+kg16D=+XG|KQjXZBrtnf
zW%r3PfI|Qtn0zlQA(<Oeexipb%)cI;=RG>Fz3_#&@$Mt28x39<L)>`gkr+egQIH$O
zJowlD^XcZ@^avChw+v5ucK!gl^W_T$xI4jx-(gUA!u$_$rbp-La$iui_p%o6MR%#{
zi}Ro|rSq6a>$ehK&(0g5Z1eHOqj#Wc3>2se(Q)yI;T|Zt!14O(gcqBS2{1tO;c<`7
zn=iCM1wiY6kIrKyCqa2?_AywTfVD$vGLO#FFO=ScqvO*<F$RVbix=L<z;W^9p%_Ew
zF_1q&adGaU7=x?f0gyv(g8cXq616YIjtMY8%5#Xo;WSwN<k9#G93L_sttU&wJ$hNY
z_rUxKPmJ6zL4^cFKYDsZ#K$>M;=B45>_}gbBSC3K_r>C)V0YSp+zE~kVV`bZwTGZI
z^TPvFEPezz^yQ1<qac5S5)C9WpgGVn+%as2hX4b-Vt=7^TY$ks^N3IPDg#Ca29NGl
z7K{uGKE0}&)EO9jI(t-B2!KQ*1w6WgBs{xYHCRDh2aE0k1rH=%g@Q*f>wQ&F%63r!
zv4zzb7(6Wx^0%DgVqkD={=v%M{+NpaR5&a=F2vy4dB7`~r@@2qM0bzM1_1_!)|3Aq
zfYJ+p>s^p4P*dZIPxltE?WJBXRaqGr!1W2p1xySKp3SZrjGm0G2CNJW-L3*2&8`xR
ztp`f0Ku%%;HD6pc7(F1;9?gdtJ)7S!^0z!-VPJ6V{OQ>F!J~UBNT+9aFNkvdf35WZ
z|9oc0ZdU<Mh)E^W9UJyqure?(@VBgFWnchV3-!21vV#JK%_VJc<y{=00D^}TNIBFc
zFAM+w|IgpL5)`1Q9`t<a!UFQ31K1*R{Risw;qc$V7xEpr{AWp;|D*`{FN>Rj!2{iY
zDa^$9uLf`YDKO)VzwZ|?d^i;mgXYBeumv829?UpnFdrO)+j%g2=>D>aiGd+)0w|%7
z8-ET=IQ`dpfPV_E`1{F5Qu?d{r(-<n(-K?yT*639{Nc}k35@vsHxHNpUNV#9zgwXE
zk0_Zi^IxYRM(laM1a-SX<qswC2Wpz&$bYQ|_^0CXUnMF2E3pG*5pWbbSRnhY6qGXM
z84M42G#&w!@36j;W1M3=a{md`rMWK20P4JTID+cR<O?3XK35rhx*auqEE_ezbpW_n
ztdo5CLlo3waZ>QHZc+dxfS$Xe3=AG19U)i2-9GIu4Q2+0<{$q(jyr*eNlGtxbb@ui
zeDd%A|Fj9<F4T9ZeTIMj{|D=a*=LPxU#;ZJ2z2{wiMQ{{Z@7KxQ2QSJ1l#8c_aDSQ
zXt7@_`O*X3K3#}?p1rvJ=Lz*+>rc3S<xu;Aei5)wLIf>5{|bY{lNkHHBJ4|t+P9EU
zcxs^gj~C)U4?O;Z#h=R`xc^|`Nzi{9=>FpsA;*8$#USZ((Qg9bX(5Cbp0c2kvE&QH
zgr_S~dJ%`%Cj<#k-07tQ-M(Dn?c0j5PaJ9=BP6}x&VM@u(fl_TRCW=U|CS)q%XU$S
z|2}>LhbO{5NPh5uG=pj-UrM0c_ZL(b5NF?%Z}9Xo9U6a$-wD_kfgYZ=knkiXeX@Lq
z+qWHR-=rU4`*6n}uJ9x#y_o(0+2_&ADk;staPS|~!T(I4X01=Js)j7I*~{N1`xP`Q
z!upC=oWY}4bp9S829Iuz7v{SJ7<Pb0CSJyaV!YQ!#lZtK4ichb0q(YY^!BJYfSOgE
zJ}L(MEfyd}oi}_sUwd}G_2@kMIt{76*WIka1Zv<qgBrNa;N~l$*~;H~mH|>(qP0PM
zIzM)P^64&7QSfL!%INt2TIVmH&YzC|uX!}*s8}%aw;TZ#mEGN7^FZz65ETu_|5rR(
z4|sMS<8QGC4OBo<iDTyvkM0l^1DNb_{+0|xz214qr}N|gDd1*1s7>w4(CsYX(d-Or
zokNUi*bQ!0mxOtAH^cf8ka`TmGcCsd|Nlp{;wD19hE(}M+u`7W6i9yxT;G@rLDKsp
zP=6AXdU-CRRBvE!)=9pc$%~e~>UhD$l}E40Wze7|X6<&-qZ6$8WjlC)%YgxG-*-WX
zebXTJ;ZA=M=oZ>SEF>oVS%T}+&QCs_A3eHVR22SSc)8;5|NkC@QqwC?ChUCS)A`o3
z^XTgsQ1bztfLuWd2;6}}>i6)so`Z%mo&<ClTLNkZSp!QVA3#Y2IRX9q^Z!4z+QpK9
z)IsqK>6jrWAZVi=(ZAzwvHSo3KeU}*5(4rHQeuGivXFh#Vgxc7s)4_yAL=(GO|TRs
z18zP+<8wMcBt9QQ;uBF`qPLGUxX}_2FR1SWN^!W`53u^R4IH1~^pnm9v2QxWKHTZ&
z2Pc|+cR9fcmYDQo1-6f1a@h?k!H7>TXP`k!YH|qyS%WjVod1O{x%~L^|39>yjhtM-
zeI(?>;((M`!ih*MCMbzz64Yl{5{n!-v4EQUko<4X3yD8?d4sEcdx8Tk{?>v@ed5wf
zD>(kZ>18?(#6E)M%?x%l`)b*VPA`!1hG2T>{`~*H2kp~~3dkCq>1F;8eCg%HFRbYW
zJYp~)>18<=B>o7dmkc(v`1550#~(56Bc$}=&Iz%PV0r;n%|6{o{XJPw>L;!}O=NnB
z{z#Yf^5p}lAqMV=g2($%+cWv!@THd-Kd`2k)&u<Wm<J@im_y?aBfX&4M;t6@>E$hG
zD2wFs#hsnV^m2m<&Az>$rUg~gi}rg^dbxpU499>Pjv#BAsoVrU_zsk0z|A`>Nyg?2
zz9f_S4Ofzxin|FM4DtymgLT7(atJkn`*7Dupt(eTc}RWqoD~v(Pa*9Ik6vi|7uMYa
z`>|H?<x2*%=mRzWzymY{+rM4N?O%7OeKR5U;cCAKzxJMhRJzm{d*DqeS3IF3Elyy&
zAoEvHF|baTs|=pa2N*q=J3w6`pH2r2sO(DtP+bY0FMzh!!JcBdjHVna`Eu`H&}=oh
zK8Kn>!2DWJUmk2eaq4A3eQ^@h?*;XxNl+j61-8Bb+PVb$7c+dIvM*=;B2B#|sP7AQ
z57Yz#=HL8En)y|q5$eH-6Kp=t_~QCVVtoDm05hMs_|kj{Q%{_KXFMfMJ;w`}dg9#k
z6K+0n>ODzy|1+3-i1RN8+<fBP6Zr&YK5^<_lIY)=B)b0u+&#qk*Wx+c{oSqxp4P3P
zsZ##ldQfYu`2eG5r>lWycdG%Y69k!be5w5vlte-Ec}VKz@u>ffMg4wI<$&FMy`K>E
z9^K9c9@fne_rychdvrP*cyu>|+~dIru2Wv#`T<eziR}LWETEAjtnTOe08#JJ?P}lw
z^Y479dXG+50}qIQp`GrR;$I-@QOvi8s>c#Ox4~K1fdR$*`=Hhes6@v!za5+Udfe(Y
z-b37jV!k|X_3hC3LJ80POpx%w5}xgEAm*d^Hy)}Ui+`)JsmGIkmOp`*kLrGC`oR+Z
zVh^#Xhov7Z>fN3~)T6o|ntrgjfBFL~>hYwX<JjDfC;f;$f|!ruUs(FV;{Ib$^(gL#
zr5`Nr-wt&@iurib&oXT4@uVNI#}N0UxCfSgu(*dE8eb^t@uZ*aaP_UA#*U|Us{v@*
z@VF~z1tiLHh?fGdz=aj0y##7vf>Nb+Gf2J1ac8i452Uv9%RP|79Ht&@z6Zp752*Pb
zpyd{@tRC|T#e9P5=e{OQ{hYT*>S6P-5chaO-Qx*z4{Yde0<wD0Fb~+j;PAof{+#!u
zna_yoe#rPcp76|vG-e>-Nrd~8NmS49ku>)&ct@IgpZlb#x4DO;o`~>&jch&<>ZR`@
znNLJ`p1Fgho(S`+NpycUiSF5h>|Y|>uXCG3_amE6gnwV(LNcES_sAfJPvb8J4hDvL
zj?bVaZ!QcBFK-_gWSD?7Kb3sR<KQDE4~V*Qrq738?mR9CS}X_24~}6-E6NqV9c1?G
zJmb-M)ie2rD`>gpIsVrB3=9ko-;OeSbiU?qUCY40;9~jSGx@9szu$So1Fr?UMcO=?
z4=`GXH2>jmZ3ZnowLDn*%Ej`1iE&MmXYx@O&G(Lw<>$R3Z6)&ET&*WdWqRE~^CV3y
zui3hpS`U=+cr+hk@vuBq`q9<!n~&wQ5)O~fk1qs|3o>|Ez6Nn_zF;{n$lwBA$_ZLF
z2wsKm7<V{rf=BXkN6o*E`#`gK9=#&XE}idR&vupk=Gc6W@%5Ip3BJi+Jr6!(^6C8e
zBJh|XgD+?y=PT$ce2rs*3@`P-YcB449DK|KTCS*bOpw77G}reCtmxPaW{{#ki2iHy
z8w-!l5ET!P-VhZJ&}!cRpH3f@2#}b@i+4Pr<$*^mK#>6nU+DTl3zyDg9-XH>I<GhW
z14Wo`@_{-jpU#6I12kT2KPm`X+3V4H9JEYWqa+x-aPa4g_M?Ify<z`bFV&fPBwy-v
z`{&WE8~#>|!J}73+yk@_SM!iZuZcMSKJM0&C2aq%wjL<qImXQ3(fpdx!}4?KbC1p+
z9?eHAKub>!zbKk3z+iab^*hk28btblx=+J1`388&=~a);d*HBW{0(wvnE)tI#9{6`
zS`y~jdBdag7ihiv%Oipey>9<o57e3VhW+!H;n8io>kY_pF|vO=G%tAcmbCtv&<%0g
z_0|I={IFdOuUSB@d+O2o0<u~&KKAg7D{~;OdpUWQ0CM_;tq(ot(e0`5;@?crBFax5
zpvAxkUkJ<s@t{j8K|$`qzyMj_YT((;;L&-`qni^Pz&^bmA3Qowds<$sSM%t#VKBVy
zVfmw0+N1N=3zpfS)x-x%_`o6W(aGk~dDyel!lM&ptO00&D{6Rw)@vf=n27E<DhEJ`
zzI%<z2@u_R&a?BHPv>#p&a<tz`CIRT#JXElK)ZfCx~G6?pU#sWpb@5S2Z#R?R)7?=
z9`NWq%HIN-Q1$3M_~OS5u$w^ZOAA1J3lP8arf27o7f+{yynM)$S<JKZhezi}&(5R!
zK}p}UQ|tvJC?&TZC=v7Q=JN&306a4M@1yzBgPHGz*<nz+%w=HYZ%GF)C}Q^L4fqe9
z^A;{u^5}Nv@aVkxKfvI%m`8Ii17j(dN4G17N9W7`0R~{>!RaUhl#W2#Kfp_vVC&(#
zg<f=khM8Iqlw9%X7W3?8JI2Bk?b*%d(Hp?%*(v7HT+6_~-v?SL@6p|&asf2N)tk!U
z(_6vO>-^vFcBhMq&+B0LdR@<MsLx&)K}_XusRH?{+m!+AWXsF7vT$p3K-P4N9dlt~
zRPbzOWAXs0YCg>9VR^VV%%i&pY@0{t4bRRWKAoRD_}4Rn1VM4((^;cp;M19+q5+!l
zx9Ij!@$v2TVP)v_QBeSuJ)-~q|8G6O-<kXW|Noaik;l8>?wbUf>;>&jxdn14*yo1-
zkFhYtdN#8$zB~mMgazVD$nYFIeI|HxJ6d>jp6<Nf9Vh`x*&fGTRKQ!cJdz6(UR;0A
z#o)oe{)0y^&sNa(5s(`rUL=B&0Vt`ssCe+VTn8nb&KMO7k8WoTP+=4Rni}%(>2(1W
zMlLD_9^K9g9-S^K8r{wkoh~X0KHc5|FKodZE%-Z@F)%Q+{^xJ01)0+AY|$Mc)BH=Y
z-q3}ApMxZ5ve?6;mv_@_A%+)|r-D-4VUKPf6^|Fsz{wAkH4-3MgQ5ACNS$=!um21T
z40VS*x_Nna3o~?cHXZ~CSe~k14>r)H+e5*lmp5QGX!%8mipL8(h@r1nP5{{z05Mz=
zDmdlEaga}&kAUrf$mLE46%Q|)!4rKB42bdzRz945k(9{9;L%*|!2qc+qNjnjSa}<O
z)_n_nb9NNqZ=C@0Y_ld~N!2%J2bL03kLGFth7vuGZfA>c4$_SLt)Tg6Py}=bOL%m9
zE4=W32abnh9^Kvo9-W6?tiSmGf44JOu2+P?Bl*$`-t(X_YHtgVW=+OYc8_jHj{gCm
zkO$=_kM0HsP-X+~J@No8r*;9YV+AXD2};zUlBLnp0kllmqnVk}qx05_zxK=wtp_UP
zJi5INUIu^?K3L-B3zcI$3?PTTjQRin|BGqU1sGnOoG!rd`Wko?5D^}T^8BL<sFXbK
zVtLFr`G7~~RUdx8V=rv?3o^7GD7Cb_S7K^;uinuk`5I(j65}t;&m{^CRt%-Gz22b8
znTzo?2fsW6NQB#?`4A(hdj4d10A6Cl@_+JW&3oXrG#-qvIzPYOi{>7W<~JJMjuNd0
zN;pAUUtXCEiWb(wSD=bQG+`zvMR2@WHVqWLAO(lf^n*6K8F)0?-tGZy3kU@7Rp51*
zDa7zXYZAyL-org&pxqm;h6g|~<O_~<ZjatTSm`F>(H+bI&Ih0(F3141Rs*#E#vmHJ
zAHwjGNAnSb=$9#fApJ#{eaXo7U6~=o@M70QuzlVr_T2@g*=`c-+XddD1h(?y@BjZN
zfb3K7=oJ+?0oqk@+N0Z(!^84o3FnL56G1zmN(7;45xm*t<-XTkpcSRyeSwhmHL&;w
zm*wX@Ixq9LFoF|Zr2zvp#dmvgc=YOSJ}$`cnq`7V=VuSgmn9+|y`l?`3o^V20b9f0
zvILYjEPwO2ECB7ab9QJwP+{8qfTj5dONqTlcd-Fz4~UsZw;zXxwLeFxjz=>aqertg
zW9fQC<pGj?J-^W(w6(dR+t~r4z4V|*XS@MY!trR<0#`6j93Gt)!MTMs`vo{PoR|(t
z4Kt=dmuG<z1gO$MS}*Hi`MY!-$mSATk8V~Yh{p3!jqxyzuP1tRvx-6_m7tPNFiG&T
ze}uDNZ%;#NFGKgoHNGhThawZBN9Sda?m!DrYvQ<z3V2)VaTk>s1_lO(hAPQq{+4&3
zkn43(N$}{cQ7Q20^-;+HCC1|}Di$C`9-TKqsn5Wp*F`19qq7E7<G83Oyhx4&<#hfI
zUXVTAAu0(Tt(Qt1L3IzO4Ko9%)JyQ_w)E%?ha_Y{XuNh?!-a%P!aN#}fZPcRBgYtU
zdUok{QHgN{RZC2apr*Q;1b=@A*a{z&4AfEzygB8CcQ(j2V~^f2h(*Gst3WvhR4qd?
zOt*`Q52`&L$)F6)-v`><=h5xW@vU(+0|NsGf6G^Jr5C0E@^g31p&u{I`azY)Q4h=G
z{QXT}SA<!-1nnw<*Y_ZgqPeSC8?^onv<Dm1vO%?af=72C2gq&zK{?qP>^4{s3G=tU
z`S<_-OIwuvRo&hk9^Im>+l3iG`HJ^NavvyP@wbG5ofD#x0czk*d%^>1fb+M2>U&U?
zl;P3&(be$eaTgT@(9V6&&I2zNSuug5CBviJ5FT2B{H^=Jo`$;$<fNCY|AD)7;PM{U
zwtA`i|Ns99h6ld6IWTpHIh3YC?CIr|JR-;ds{g^sr4v+hA9qm!FW&a-{0Wi(@34PS
z<ireeBPcN?@V8t8*$RrmgD*NWAt@=55mdc|s3g4HhL}I=ywLoBvH1hz>xq!^0<;Co
zV<)(~;n{hFza<u=sW(``v-1V0sVTZskioN;N5`}C$1aeyo|-RSeB1#lntu6oK73Ku
zE5P8>`Ou^D_={qYA>gR`49WoAVHO^pzh8d-^Z$Q$n1n~SpTY~l=UfaP%|94RZQzm2
z-*OeC7*ud@dB9tp9^Gyh9^GLA;9Yh%J;3c^&^Gv&vY;kbHz<yJc|RW#WN<Y+iJY~L
zyQn}$&tTz&2rO4e<iJ`9Hpj!lqdP#rv-5yYx2J<g=S|1|6G66snt4Y-q1mj>SmFwD
zY62*q@VC~2b%Cqv<`e&4P5`gJ2Ft(n21~(X_8&+)r0#zy5301`UVFVBR91o7(=f#^
zUiAwwfXs6Mn+GqyyIC)86lU<~Jm1aGdZ5n3qg(Xg4q*n+s>g0AkKUZa9Itsn?FEnK
z!yKSavARdMF{mHb?Iz&S?IH0(WjnZHf6(nF11~i}>UT(j101sb`Ec3<xP6_cJ$iZ1
zO%h^wp$S?6(#y*<8MLMJ)(a^RxAiuEizyQW1E}`t<&~N&#9;W}@Y{=jpj8~byb_az
z7+!q(@c(~zute*nIt6f3vzOOkvJgY_F-DJW5etvz;~Xz8eE9$0vRI=2fk!Xz`$<qE
zc0-JK2(o!Sh~2Gga#swr9lhJz!lO69z}4`;3$`B6wpHF;AVpnZMZp4~eXt;Y6^P%<
zyA#CD1G&LjqV+(XI;=ecZVmG;orLNXS0tyTfOMLGOz92=?XIl_@l`<lUfy~TTLNsV
z!wN?JR?rUg6-@lCKN%PpR<J<&bKj0I^0)3}U|{%mgoVF#4wxap-`WHU=w4nnkO|j7
zizGlZL9GW$Bt5!4I6QhqjShf@GcK0szIf0HDuPN?JbHP3CkipVSn>Y<|NmD#dOZwa
zQTNhyn;>L=okuTkB*?@Tkcqv##UOSCh~4dN@IoJy?s|DEK!VBd|Nnozc7jJQuONsU
z^8Ww-m*CQ@m-i#c66g1zwyOiAQQ6CT0VJjm6$7p7g@s=)?+TEV2vmw6l$?8cn?Pa=
zP_fTQ{UMKD-Vl)7lXno~L4~_VFYoOMLJTi1fEIA{@@9hAN8bJa|6kPWwiv@pVdU}|
z-2MTry*^!{;nB_ewn>Zu)M94?Wx<jlkJj5IEFRz{u<Rv}6u9N%(an1n!~qR@fYnJM
ztJ?&U0;>b1e^`^e^>*p~*ALSsAn}*KUYRxly}fC8;5ENXH%}vIOv}aEr|C~AuczgK
z(l>?&ASxvfG@oEZYLED~9w;$(;orvT!oN+()#6mCp5cMll8E-W3;#AAMi>5VB22Cp
z7fS^}#)8ay0W;6l;*{ip<_Ap8FBrk~H>5w)?dagqdAjvLg#fJKbQl&t-K<aVfm=(f
zCI~S&LK^Sg94}(JL20VOA2eUqm<(EJS?|$$pyYr@uj$UcNaKCr#Ax}kM8Kn0birOh
zh8Mx@AdMx{J-VYo9Tx+H=F-cr8^JAm@Q!7e{mpMQzBxLwl!(0u{Qv*|!5{LVGz%Jh
zfsA)~bhFOA2ip94!J}8SWFn+N$KDNX(7nC{_MZi~wR#TRTAdEcHqDg=450PHtcei6
zl|eQ3bqO$dbb|*gz%Bvn69(_Mw}_4d?YxGzRdnEO6&=Wk7d*UrMPosRb>4gd+FjLp
zpkjSDsCC=z=1|GX3u?qQoDuNoj5FwTa{zh$_y7OkAO{)m(an1CE;y|BO@MghUnkTf
zFJb*RXnV2wO@K$|IhW3(9^IZ6KHW|h9-Wt6JI{1G$~blh$XFiYZz%>H%<)5rzr_l~
z_$9>O3TFHe=5I9woeq-h&cfi)9c%%q<GQ^RJUR~@e8|-40d7sfYB*4XgaLFeM@uNQ
zf;$X3P6N~+2M^7C0&m8DvE%|9gGaL-qetg){uXmkB@eEvLFJhTsN;Vb)Xb09Fg*EU
z)p<q+pI(1ZN!Y&|sU_mrc>{L^3+ih<v_v>zD<~Gb-7K0bWQ1KhQ&bcn=X3b<@@9Vo
zt;Bi(s;fG0zTiC!8ds^P^yp>>59f5=07t2Ksfb5+IEP1PjEaXx=TC6s&PBz;qxnbx
zylo3fU(LUS`CGtgrkhpg4mffq_Cq2ku>;zPMCfr~0EG*v0C{;ITxc<%SI368Ult&j
zM;`F1`{fnT`3xT2ZlJ;F{{aRscY*jmy}T!1Ap6Mr(EtB0H6ccT&J*c8_+o}DC@RCS
zM&(CP8wK3BgGc4gU}!iV<8KA!DZ>LV&Ee)j>uV3lfDvd9x=ZKbZU>p>7eb(=$8DhT
zwC3Ne{Oy}TG0@Ap29(&7MP_&~UI2|aFnCzoF1;@XD=2zJ=ky6N@VAJ976L$`ON75=
z1v6-aIjhh_Ay5ko98(`(6u0m&v>qst@aPWX@aT5u@aS#;4{%yGfv8e<k8aip>p=~c
zUml$weYzV!O{o{_CV<<~r6w<Q+CeqA=uxCXidE*87<l{5hBi=<!{5;lni%Y6<-IS)
z;L*&$2s#u46x)Y)g4!%Egw8U8oC9s}!Gp{JG$-D92-J>k2!aOOQT~<^&{BeK2MeU2
z`3O$+ph3@8$PgWTG!Aka3V3~)PcLis1Z00#H-r5xgWcc!t=^ytv72?uI$;K%?gr3t
zUN0YjwxvVQ!|~~5RYEaOn}B)0L3MaHs|&<D&{*<I&^Q(B`~sg|)|)-Z?z`QD-+iF2
zhetQ-m$hK`&0t_)c<t=d%Q_pykZA-ANrO0QJ;V^ukN_lAz@q5o(LNq%`^4JT^{yBL
zf6HG`Xv34#QSdM?Yk4oS(-jEV`T^XkX0=?4l&nDG<1fPdz{!fg_2%FI|6g2e5kRD8
znO-4=mkSX69aqDX9-XfoL6a08Ux0Uab=NY$yUd{s{H;^LwuFMmge*W~+@PMMi;Bg|
zn!lj3|7Gdl|Njy7H>5Z=yo8Z$K?(4`KQsXz=5Hwi`#-?Kqub8{QZ2twc+AAma)7_}
z3n*)Xi(h?^qF&MK-H582RqQ$>SIlaL<O<O7ARgVU?4ZJ}nSt@;Q&2wve%=yZ_v9nF
z2h?Kq=tgnRghvqfEQGsf9f;K{+TVlZp0;Zc_i#bo^AeI4@^3?O>B~?Q_q=d!7GQW;
z_51&Sh^IYzMJ>C87+xxa_HOI|oeKk=%lh~NJT-_sQpVrP4cgub9i6j)RNx+<V{%@8
z0viW91MBrcqyqU6*d?%z)Jy08|Np-@(u9;4#6dPs{{8>|i?ztY9^FC=FKd2-2KX3I
z=5HF`tN?A5>vj0&0h+hD;?j8(RH(L32Nx!R79P!277Y9?OF`vhvZI7&a*c|FM>p$?
zRl*D&$6Hi77$CsW@`p!v2dEVA<oEy4{Fljt-?alY%iz(=@)xAU@HVK|9^uj3q5>*(
zK*RYSAQ1=9pil*fWdV`{nFrz+c=Wn6f*1iHQAq9sk1w^TfQkl?OvdXlXn!6wF7MGR
z`ny|*!51_ibmN6)tpI~(=TXqy2xOASvr~+}<ufShL7GzFDp#1l<pLuEgKz6w{+5|w
zxiAZ#&etB@UIsqhJ}M5N`7jI65QV{uhDLD8Y!LvL*HAxnhp1F|G*<{PmvVVn259iN
z90D2A`SC?p6BlTl!V@&31!~!V%%}hj9u&ePj`O#$f{#{s;Q`t&^zw!H&;S2DK@(5l
z&5fFjpz}oZ8Tng4Q_sGjv%WwJqdh@`kG-O=H$l2lyf0?fK%BJ{v<N%dO#(E^)C(%`
zJgi+*0{B}LK@RHnQAzOZ4pZoLX9W2uqO(N>tfaFC9F{LsRtPeHT$teqZeW5o^Br&b
z0}6A{;M0rTJ>ZfD?3pWIcj+<mw>$@Bo9+-54^U|XtH&KdlT0sPbhkrw9OG}P0qX$O
zKrNuwiw9^%(EH#2|Gu4HU-m%SBc9#v96p^t{|6X=JlZM_s$E)dgIc(tQ83W@a_|WP
zpmYkV8<D2pKqi9rmb!BIfG6r+o&dE^K<!~jR(h!j;(K<7ae%gf1{u8k_xJz*37*|>
z^`PG21dvk<!Luq*^E&Uo{0J^iq5N()u>Jspmt3InD-T5bC>hLez3tI?gTFNblo{FU
z!4sGKtsWq6bn{NW1a6=ub%I6~Km%LdoG*6QftvI#Dh4lAq56G0-<7a|+GQn~p3QoU
z{H-91JmK~l9(W0=BVqlIZdO}}skb^H&AzNUP_ysl^?(2WyBePK>3sAe<IDg5FOUC&
zrYZhbP?d<}?>Q*N$m?#1rJ(J92uoj<gQLfR0o*?Yb!9ey2EmZV=cTJasjno+1vEs`
z?QG%G?XBV3ddVl*L7~pbvzyUlrsww`pwqJq9DAMqd-i&A`1bl7<ajOU(aq@5e2@b!
zFW_T&vh)?CBM0ubg8Lr|py>%01_oIB&$snJ=lRa7KAq=E0zjpPg-_>UpY9%TV)p5V
z6bzlOI)8!+2Mv${0}sv5AdbQd&&9l;NdxN`6^j~fkMH+9tV>i3_~(J9ay&q3>M&?h
z6jZRhh`-Fm;FEmZhkyNn*Rvqy3)ud~H$TAjIj`P&P$-=9=)CCDdB~?1nwNT8RC+);
z;yA<^3{W;G6M@*rTU0=`IEV?FjSm3n1GRHNt}F29X0==ZDNaExNSGoIpKjL1`N9mx
zTU0<zERZm$#06ztFuT)5B?DAAg7h4RSPv2hnePBHALJd722d#sk^tG2;L**xcfK$K
zNRfq4H*4X1P&)%UU8(>QH2`S^IUB^$@abjU*(SvB;%7N1rukbM!Q~0WkKKD9UIq=c
zOM;5U<Ol`Om>Dmqs_34g0&*AV(5jg3DPRv+PXUJkf9n~LA<cWh3jrATTh@ZkcIs|X
z0aYHb=mbrZLmUyJq5+vbP<Zj>@BjZT2l!jgfOq&nEb!@`12)GOWb<awaDO)>s6i%y
zOmGC%W-XH7V*V0n`2i^W_**~@ZvM~M-J<dW)N*YB)jK|nw?IuC#29pEh>8YC3pgY@
zKl*frs3^R6r;TXvK+5}ryO=?}*RTIs89=H*-4W2}e=`%~i^QkkzMd^8d4XK>Vnrn=
z>-T^I=f!Lgr}KtK;}KBW0;faJcun&OrcQ{vUS@*J2aK^|NWqO5B+`YO?*TFrbbb}6
zgKS+1Di%<U2am^t2XtSbf|e(q&6fZ9TknF41V}V^XhW0rOpousJv$je-U5Z&%afq;
z6w>~B838UHz~-^8Jqs@7PPIVFqg#~%3@<~$MXCz}!%iNMW84lfGI(@ClFrKupav$a
zeQ$UG7Fo^z8C{_92eJ|r?)*~@phXIz`v{4USS?tDl$e6j4M-PwF1rO(o_TbOuDA%A
z9=-X3WepF*i*!%`fs$+{VtxWC)4tsF@Be=nP?dbrqk9cFO}_9s&jnhFa0BEdP$+mX
zUiPrOTaye+dp^*_4)X=f3omDbD-i~dZr0v2;P9zxhJ??q3IT?frbywJ3z0trm7fKY
z2d%&G=w|hTNPUM&)q|vdfvT|yFkpB9Gy*3LpHG5}w{`F^fkxVVEDw~v`+PVJX?~A#
z_1k$IT}UyX81+&J_jmI&A{+nyGia0x(I0`hfAFgJ>E<~|*!?na|9*Di*Fp91+s}tF
z;tQev6G%OZ4XElpn%_wHwjS{7<zXr@zgeTg$G_c0g|FcZPg<vo3J>V~%7X%+<qWqo
zKX_VRyqTlIb3aCf>t+r_Ay<df|I#}i%||3)<A><sO~`+*&w)xYM0~y8hsuYThwu;B
z|9JcZ^NTdJyaKuX6Tc3q2_fKVc@gB^H=mKlqmlh@hQ<H4H9;nLG#^yJ<^8)*??c*u
z5ciJeFIaIh(D{*2`h&z5TKYmMQBd;>y86-lb%>Gv`AZgF9;UhQ@8e-ibLr%9f+abW
z{EZ%8;Q9_lIhOeK@8w}AkpQo(a^c_30y3TjR6#QNSe_`QmU?lB`Q0pzX)c`z<FVDh
zVD}78^*-G!jl{WM66{}4`Hkjd%=iNP7or}NztC(zQ4cD=!Ep@MqYEm*UBFdXnq%V$
z2A(t*P&Ia2=ODP|l3@Z>TprB_z!CWpT5!8CAgzx?m<0)MLjEJF{sOxV;vca8Q9}&H
zKM4CF>cRd$h!Vmm>OubZZ9U-C%i>gGfW!BoDvSwKg?U(B0Ea`=KTtT7K7$4T^7>G)
z{UxLM3!dEvI6o3ff8h8+PhY4d3QBrGR}W5Kc+w*%eIfK%;7DPR{B=7<g#(nZT)JIU
zI8c)8J$On(m^GyGmtQZBQwh%YAvkkE+lR0~0Ea=R)4x(e?ZbUMj4qu#O|aSvTY4)&
zZ%-0X4^9t|@O9ze&%)@^$pWe!!KEHH^HJ1qC#=2%tv`k29HQELgGfENeMrzf80|wO
z9a!1}B?$GP{Kaz+If7BugYuVe>jBSRhyRfDg;{%fG=sWeFBn0azHVoJ@M!+=A5@Cp
zj`{=2Y^4vNc?-G!fruYM{v)dXLh=u&{=(-Um|v9O{jV2{pfCWt9^#W9|6Mwr{**oi
z_tcU7Z;GRI(ewZ<>jQ0hYd)xe?)`^g@59@J;PM3}zl`QDdGz)T9rG`t^aqJAM1J|~
z10LTXK7WDK6V6}0y&nHdtU&1t+&DxX-|%dH2~M7%F^=Y+;LLU3Mg^3)Ji1v_Kxy?R
zIFW%yCLr#mVg4fEAFTPy2Ry)Why{240{h<*i~nzH!h8>EAbMi={w=8YT^JZ3{ztBl
zM)TK@%3q-Iz((Bl5hQ*Q`4Loh<16ox%WrV|Xte$U4WOd*K1b^>MDupow+}((H!1lG
zq<*yi0u9g)Nd4sl8b0*t<T*r2|BH}%r2do-sQ=~D$pY%%5#9eHq#mjL=9A3Ri0m9<
z@)s%UX>NWu&q4g|`OGiCtCb_f0BZT{0<BE|EkZAqd~FXIPxRr}Ie}zAiN<Gs0hUI7
zJ=Sm8LJUO@KJ&*M1hpx_YJ3bu;PHF|)ctT^Fg);yUx4>qHm3PDVDmqro3HwbUx4Lc
z8o%DbqQ{^3V-CU<ARB%gWH@N)8Uu3uSPE)?x$tlIQQ^DE8lEl0;0ar+(U9iYcoIBX
z>7&B)S`^gZ0d?{2SN#CDLYsg5FEN8O?hbL>&iruuWzn4*57AWl7&`p`b&g7}-M#Ue
z3pQVV7qt0Y0<qr!Qop0NUy*{Z6g~YA?jM5Urz;CH{P4xkL4G~fuq<NY2NXL7Swak+
z@Tm7~JpgLWmdd<#=a*;r<iW3V0Mdj#C;)1{dUQJdDAE1IF92%NbAaRNHYlE8YQP#m
zihK-%et<NTUdA#X2=0%g#Mkmnobe?IiV0Bj89mO7z_W)Ow_g_Bg+v#cB6yTtzkA~~
zJ2<^zk1tht{}wXc!T<iiXGeamgP-{Y!6geLXy*P2XyzUgzsTyh@i3+lP!BGz6v6g`
z$BSU<4}i>vj~pS)M^O)&AAy>WOMQs~-2Gsq`L$RYK}LfLMX=Lf!t)En{VH(vpuI(4
zJ)Y>^g^V9S)YHy<SHqLOtp`dKUi(AVcY)pF!LN1TvlG7{OP6Q!K}KK8gC&Mu-7F_P
zS`Sp-_v}0bQsa5?Rr3QzPtHT1J^8f`eddoq)lhmK<YRb$3enyMmtH7ggF0S>&A*@c
zqgYUr0wO$-%O7cec?L)+f;yNK^`{hcvJ7YrAKJfDgoi)KFP}a5wa_eh0Xsj5aQOgQ
zZ-VMSRJWq~4^+y7#=>Cx6G8SvvKORz@QFXl5j+I;nP1T9Pw4|tFe1-iAp2K}U!DP!
z10lWz<vmdOcr)rxDQxNoRQ`k9hn!zP(~11=4}1dUuTT7fEbtlwk^W1N)kE_aKJ_U1
zWj_lzKZ4XB0GSWU1mKnd!h96<(ENo@JzD<y1j=6^qv1|Rqz6d)!OUNuK=}(r5AOU$
zP4ltkuTP--^$C=}P7%&uAcr6N#2;}0MFU#?LN6bpSQ=6MiXJ|Q^a`%+QPiTQSLF1D
zmcKwXH7LQ|jrxH<e}VkVauCH567v_P|4@xX_z#x9VB@opiV~bdI3Q)ikN=<e1)Y9i
z8J|VTPaxIc!B~*@5cvrj9)7(%j3tVY@`f>uf1l%jkLE)Ho|Y#;%Zm8!yQuKpuKG~=
z2s*BWG(L%}UjeG0e;an~kD=O;^FKI!gY%CFxIVkj!g$*Tln=mJ>?5eSK$-6a*@w_0
zJpnx551BM}QQ<+-3YjdO01H2P`1tlg7HIh-aNF?@D84~HgU27pd|yb5r9=hdAC_*%
zKakeQA!v)mMTO&jjtU1z<9)E75bL1^$i7mM*XH2xgZS;o|Jzj`N>st?u$vDFcr;i3
zV7Q<8qY~T(1^M{~>*NF>29O7CgIXc@-G37lPT(Xb0MZN61rIMQ{^hvq_ygh$kj-GH
zl;Tq_08<Q|EFow<O#S^#a041eJ)!yy=3Y5ydbr65GYt}05a(j%KbZQv$m-$2fm=Pi
zJ`;e|XCUVy)PvJ9()<UZ{w*Q@p_>O@KZD$1K$}k_$~<uXgv?J8>K~J89ytHv=|2-?
z9tr(xQq2RkXOV-C^!^s8y@J$#BhddJaQ6}D-xKFPM12hE%cG8Xpw`Evng{B>qmDq3
zW*)SB2lp2VkAK6O1V|l4wE5fD>p-(ii1PFGJXAg;KO)6Hh2cxczSn)I_P?wK?J_{P
z?`1X`KN^(}aW7i@p^W&D7T&P(7S?_NmA0Tb1o!q~4H%zJc>9G=dO(gpLi5k?CJ%D-
zq0K)N3QtIQAmXpVhLM4PDtP%HBj}(D^zwjI_2~YE=ts=gr8V0)qF9Jlev_vjv0e;R
zzPYxZMD`Nq`Xi+EWrIUKB78iWZ4TlOA5f3fxAlM{_++{gNq#++Mo0cx2VMDHPr(-Q
zgCg=dsHq9+U!tm)O5@jKIfzZeGmr+*C?|L=zS_-q&<(=i)gOl#Z)bkE|B`>!0Y`q<
z1JH%+Pws*TF;UvH=<!F$Kj`TNef>Si^$@Q@SJs!xzBcFAb7X-y<q&jrJV%Gqe;><J
zB{KYaj8#k}_n_PJ4uRI)L*+`r{aZ})<X&5*@#{Hqpc*IuHBdGUV&WZS6QPo&k3S!V
zx~jwz7GAGqZf6R>Lkj9V1*mC?w>9s-tYRubF%2qN`uOgR*G!-w#oYfwyZj1?FD3YR
zi>u*DP?6xsKNYm-6SAloo}A$0MWm`njOQSk51RxA84qtyL)<eY)We!lDDH=hCzL3|
z#=o5!Y&aPu4}8CnrpjQG=G4jJ1szg=_HQBnRZHW4e+e{@eKA;w0TllH8V5_6`85uq
zjKn?re0Tyxy#`1<XlQyVRDBvq14|me#vzn${1Z@~M#-O$wYrQY);HhXeDRul!p(yo
zmM1`+D>aYigP=-GprP_VL&=Mq2O#35FYeyBd*d|^%s(LBXQcfr5cgn>FRbB1D8EDU
z6Jv=Ev_AuK6}0=#0m{3dK|`OQ@c~cElgFL@faYULL0vwW`>^VV^xuink6!*j%yUF`
z4-@}>$A2Ephlnx{tN!i8>xYD|20VX4!+@pnxXU5XNrw!e6apGw0FPro#E5T*ejT`e
zP<;n71Fqc@I<5^j<1Uu{Tmxr6BtMmEzV=2N|8_d=ataavC<ApWUeJN?Yd8nOUmpPv
z9wV<;RDp*Nc>Eh4ILO1V$m5Zy;Q=21#;ON1K9JjcN|5mw*mwcQ?aU81qrgJ|u#^pL
z++pmm(}cSh6qk_kajXu&7@tN@-{|c{NP1-~(Z$Sv0wB9S@oRxbjh#MtTAuVc?gZKk
z%usp@l<XkkiB&%&{}H7h-F*=A9Fg4v%YQ_fhgCl${}HPn+_%z)h6gANJem<>ZlCzI
z9RGj@EWwik@DRBHPGT;g^E$w@g(XH%{UE*2@i&N3hXg>wuh1}U{`ntn#8ptBg4$yP
zZ9jOnQ|omocsvf|Xt0ApBZ!~)1)0F(sz~lG(FG4Ybvyn5O-Ehu>^uO{;(74}csl9;
zXt?|UXt*2{(Jl-OAWtHXpThcAxWfB0e-xqc28Wk6BD^_1@e3eE@G#@*&S#|h3^{))
zqvlV6+nFEkMxn+tWbrdn{)D;T0BS$T^WXr1EFlI*w&M>>M_dO5gbM=$C|Hog13iC2
z-3J=qzWJ_1a{{P-gpF@2APsIm@U%R6yXwR3tPiDkAni)<!0rT8{Tg8X(D7{?+V3K1
zPn&@5K1h4Q@#eb{C2;!iXg&x^5(@Vn|J|;70BJ*j9Pu1t3e=Z~{yV}wAT!iK?qTAG
z<WB|g)+x{^comXw?m-L!`-Wd0mOpO3D^Z8p4;v3xxb64{<c4PO7%0dQk05%n#5X97
z-+Wi11F|1!d>nirKXh#T0cf%w8l*QN20<Nx9AD7*AAIg9mA-r9wef`8R-h3JkLE+*
zxf6(YN~9nu6gsGW=LV~rrx3&IE1;1V^!^Ao{~^ZH6$pkm7X3)$>tyMN)t?HWl_^yZ
zphNmN;v1X&un@VQ`GcVQ(bGSA{xm$`%LqQ=KoZhk0k<bWZ8Xp{E4Yn@I^G0V4;sP%
zwbVgVzl7$~!8U-4ISI&+6L>O%1v=jVnqWqrPY0_84|zb%|ICkf{t==c>VBf;AHg~>
z+yiRQfFc7lK?ipaBy_-PWkBf*R39SJ4}1aw-XFxG9x1&Lr5=_(K;<{cJ)j8-xcQ({
z+*$dzF?BG4iY5mJ$58kQp&Fn=H9(7~d_k9Zobv>o=5yG$^Gr#!N9PG2&I2phOA-zL
zd$hi-mw)X6>wkbwKW#qF=)?Hfqm#{t@tud|-x6(*VCw<U$+!%R9^HJPvrw*s4#F+H
z2tD5R^$ECs@a+@v;0u!ugX*8o3qG7DR<M^&^*s2N+4JBVW{=jlbvM0wZJvVqKAs1k
zGP@c+c`XIg@7a8W5p*jK<8L3vcRrR+OV(kr{1({qD^SZlx|tF7H&`<8Pd$KGuZ7M>
zzmF)b8KMDZKRUmgvGoARK$twKd=E79(fR1^d3_I*s!;0}k8UT6ZU=?d19gebFBn0G
zPW6T`GD7kv|2DyvOC?sWEhkI0cX0E74%T#0VLQ&EqQJ?;3#w09j=89?F?e)7uo5Vd
zge}ti3>^(RB5~MpC*+2RgN#0w7fUyQ4}(Hl@77?+P|9t1puq|htlw`OhA^jqPA3K>
zEe8H=OuIlQmsv3KPd&iD?Et^eA(Zn^Fyx)k<hMigr&%HyfYcu0$B=hAgnV8{H<KkJ
z*Z~OZ`H}Y%pvyZQ0;Nhs_@c}E5RgaL@6pZVf$9QO_hHKWpt%1tzX0cFegP(ay@Tbd
z{CWqfr1|wufMcgznqTiE|EvRsm-zJ#@XtP^c;PU=-pQ&5;B(_ZnH?PdQ2kQ;dN)7w
z3k0%!<`-~cDdXYSyHw=>Q>k~lj2mQhDA?S?Ro11J{CbDVAArPs`SmV<h0Cw;>s>;(
z?m*RUup}Zsft;XVcmU$GUKfV{he1{?16%caGQZxX>dx0|`1NjA-+nzCl#)O33vhno
z7hnP{BrG>d16e7T2KS;`8pI&OOCTADCqY70cVPJqY%sVp0_mSY&6E1XFAxY?op|#T
zzkm}*8E+cM83AzBdZ)`oK}J?3qq)DzuGA(C<ohdN>A*C&|4)F700#g_2JV&vRjc4e
zfa@Q<lT})V2SBdmpLGBn0w9f5)4_JXZUS-myNmz-|NnY1C?$fz;==15n160--qyPP
zvRv!-iz=y`CvU$5n_aGX{{`6Q`!68&-aL8xMb#tFSk-G55D77xonM{-#6xcX-PXLF
zDR5isc9y`+leb@&Io!Q*_tyOv{9T~Laree+0g(FFTp$usUO-IZh4;TfGRWrLJbn9h
znH0#Bn<wwTsLHu}1MI@XF!zJP4<dW}W%;7pFRCICzSxZBi~BFCCO~u}^4skfRW^5T
z-Mw-5Cd6lk2f&)Z;duW=)g-X{US|FO{~r_v{M}BVfSiZWfAjSH7uCn^-nw}bGLz=n
z?O@@P?4jV=da^>v^WaM+$bsrC&;!+7n*NmXxptm#)I8wYdZ7N9;eo@D6V+k<0lUwI
zf1993^DjnE(5+z%40Xx~`@r+{t`-;T*gQKKTsu#JN>C5WL#5Bb2dX<T5Ualozy9qg
z_NyS<zn#Z1&D9da0U)pN%fsv^tRLM0DEhlmtd{@{vSG0jbcj5}zu48ITR})YdYBSY
zkJEe~H1~iuP5N411grN&#2LtZP<aWBW>8V42a5JO4Y04k{V#BPmtXHhF{s4!>}06o
z;nz3;i}Xj}NC%Yy@bhs&<q_08P?1n&05(tyYM=uHxcvz#@QOi2)B%u*ylF^A-Zwme
zQeWQIgqn8yMU@lSEC;Arkn#`IUcRjf%5%jccW>N&0WwhgH8&zZ--J2#>fIZ!h40>Y
z&42d>viuFh1IYE~XMO=ee!WYd`2{>#pf*=!f<h(*Y<V2m^4D5$^FQ+oM6!S?B#qM`
ztL^ypZdY0IYg~ZZ3K>25%rC$QDq}BI@sx5wb=)jJ2`c<STt|=r)n`3B8L)<@;3s|o
zPY$SKK*ecQ0XS&0z%ELGxCl1B{)t~85>yWyNaKgN$R!QrB)c>uHyMHg4YW`XT=1W*
z;w|NdX}ei|7*yI<fdm}E=2V}AxeHW;GJwn1n<t^Jx&5N522?Ip)qven196MR-J5rB
z-p&+w&6YOd?ybAGJUba~9=Lhx_KT`Sa3PwE6#h3)!a^z(#5|~QTl4m-@_kj@rJSIG
z{8jnByEpE?sNw}p!o8@z2r8Z-1*K;v!)rA#R{>0d%IF)fML=xO{04{y+kfLOD2Czj
z1$H5h`~l8?X!(QC{07)OBFf8J{N)|N^0pYie!}G)x&u(kJAT6Y(H(%IAFaHBmY3*O
zg3236cwtwMZUrIrR5Kq(dH|b`mL9<F$DtnVel+z&mahk?UA`V9qkJ_7XJS*Z7h&xI
zP*HJP^Y+VP?z=Z3rK>DxQX86SOCQ|5@tO~`Kj`j_*KDBnEjYI!^;bat=hr(4Zi_<;
zjjC)=+cXVqSpwLy*Lv{$$**^?ildZ`UoVga(*Ae+%r5{gAgj!wmX>IPhPNPP>WQ**
z{CWo<rgt(_fr{=b9*{avm123Q^s3>3!zkq!sD1*sm7$ISm!w7DQZ)zcqBMw$5aYdi
z2dg+s+0*#-0y)Yxz=fkXXaE{qI954;?DDWYRH6?GC}^2_qU<C{9mJYWhALsO@w_0V
z;Hu8@Q0YZjNe^)xqJ4v2zVdfXW?*0dm9hL?;OjA)e=+j+b%Sna1NBp1+kgr>P+7|b
zY0rY%qKNV~2VCCfVJ&Y{Vdd@3Q@3B0?*NgYn&5V(0Ek(>4b*O~5`dJuCqcHnhPAgr
zMXxqkL={ZRgGoscdH2R^K@k0#8#-PN;()4jSb758Kl6*Bt{il7_dd{w2Wa=*YaV#~
zdv+f5>lQib+3U#YVR?vu{$WqcPmcUk4!gA6E`1CNXhYvljyiSE-7vk7w$05FZePob
z=o$90;eqJ5!-fZ-aUC6Zxa5=PaRyNT{Phz^c%iR1^XU#zG4KUls%3Zpl%5+b8A{k3
z8!Q+~!Gi@Jj2C?wPk34$Dt!hzDqq9!Qis4{FblkVr$Yd8OA#VI!-74!OH>>@TEErl
zx*A?`HN4HgPtuWpAA=|8PEW9D{Ob=pG9LD^yjJ=IWRitTheUMTVOPW3uRo+sz@mSf
zq$B?}GW6>~?cXoy$iE+t{xp|Pm;>G;+Yi&fUDA<%JF)tMJ-R`6<hI_f(|}mt%?S0m
zBma5^U&a$)uU{^G0rI*5$Y!w5Kf=<>@X@ac@xKQ=06ZZ9;0cQR%cal30pQaq5e*9f
zaC-}$9@TEXGdz$s0kmHG0HX)vMaSD3kd%1u<h_HC;M2HmaroxD*I$s=8zI7vJo^ca
zkAvOk(;cIt0m?M?AV=Oj0CD8)OaX{H9dBm{K-_xs@QqU-eDCGGWA{#jTz>Ch>BXBT
z9dBDZ-mVrneDmGScdtJoyWfR>8|eBjPexbGgC5PlnCfKRds#d@dL5ZO7*FxbGq`jx
zfXY=@#uFZv7fLbrV^FStJEIH#c26dl{c=$ISv-100@Eg>xpaaYzyx)`2hczi^8Aqt
zKV|y68C|+PSsbCBS8xM+USy(2uOkPze+IFh1!_H}|A)GMk8VbvZch$RXaLCjK?2~S
zN3Wv*sC@PT2S0}|uJ{LEfdcB(ff5h6SNEAe<`n3<LP-A+G@lDvZ*kx=f8@c>{1M<4
zTHwJF(5MFHdJnL9pZEnp0|ZRqj@c&+^T6}zpZFsWe&UY+uirWdN}|}!1I?F$%>?C{
zgP<udkV9`gtOG3x0iAE&>7v2`*4}(j0JN#+#>pFpZdZN)nf4e|xk7qF@R>_W!;4UU
z2fOt%zknvlnV<Ou5<w%ZksP2F7|&<^n7g0(W3JR$A?iO+`0{I<h6VA7&-{^~-K%Fm
z^G6){%rD3T+PmojT7Gc=RNt3gK+iv5`#yo~JE-u9Um)=XsH^$`)VBHoa>6J6n7f}K
zc7pQ*$Uacl7u*~J?fV0T-6#IY6QB4aLEHMye&UZf@`+#2^TQ{8LB}7UU_667-iI0=
z4!1Ke+|GP(;}Li&?ibUIM|B3Es|;W<q5z7Kn}=?kym9n)<%1h1Zybh3%`H&WfbeS$
z5DCKID4GDi&!PE^hT(0`ZUgW|Fy}owuhxscwuiJwJUUJ8do&+r^su~Jq6510nZ*Ni
z)pIw`eb6k^L-0h;ZP-K)LT%|4&^3VYQ~VL(@5;ZO0c1@tOJJP<X#CZs6SRhw$;0ws
z>F3XfC%AS)r6+=<9T*_eEFkGGpq*E=miL9(e-UE857>De2>S`RA7g%~_0nfYe$d@#
zEEDVa(<Xf87X<ki>>-eUJz6h)g34b6$$x^#gDnKhcV6%~_<+TO@q|a~CCA$ubwZ$&
zbn^f>UJsUjf-DpOrBX=w;Q_Ia17xWKi$^cZ#X6zS{DPd2E{dSzACOPpA*t`Y0J5J0
zWC@7jzyYzUP687DpCEb#psDj9`uX{ew>3P#PGp7X1J$i{>Niim=78vjH0nX_eQ@(6
zi249>z)Mg9gp?E@ry%W*BozMW;fp>V0;>Ntd|OYJxcRmoaOK}7S(0mbz@zn&EB`i*
zdZCw~t1Voir}cwc?{Y5u+gKP~Ee_VdbhS9_%I|a7wF9zQ0hALTeLf6XA6UWy(hoMM
zP8z1gmEZp$vg+rb4}U%kQS%+%e}F2+FdD3wU!H+n_m)H4>qL@!-AQpTs?jj_z69NO
zht!{jyWa~O-rFThYQaI^%D<hXUijrK1_p*SSLor@pa53{ZD0cpn4hS5p5|%^4wp1n
z$oZY%68AoGm~ZC*8&;==6rS5zK-v$2LLWurQ&8|vfT;h5p&rvBh<ftfUj%i((_s{6
z5bu8XgD4sy?!n`JG>ahW;qC{g_io9OJg^C_-JsOo$-uzi+6g(F3KaOVF5N7Ru9hci
zUO_|N6>@M7IN%?Hb0RdoGrM*}gI)@v2OQqW%3pwjI}IA%UlHLAwgDX47^=bTqwWw;
z(;S*ViF9uf#Jx_3k&PtiUiX8@$_cp_)o`$CvfVoxzL@EOnDF(5rw3nn`t^mLT?J0R
zKHV$_eJxKEz4Em@?91<T*tZjMd<CemMokaC@bnAObI_OH{UEY(a13LnUx;c9!@;UC
z(gU&Xt%11Lhcx&4ljL4h!{P2lFRx!(qwZhyZ9U1~0-9F!Z3P{<BOnNBI3%+0w<v=y
zrb22=M6mGpm4n2(T~suDdRZ=j)&x0#wg+&0<`;}$@n}8(+CRwQV|k#&2{IUZu*$L2
zo?kDLg@5{?mP@5q`1LMS`Iq`a2T+fIMN9NP^9u^VG=Jt7O!xyj>t`Q$Nr4Lk1Hax0
z{^^HaAApU&cytSTbPBwl2;=kX9RkU3gYiMThq*z10JnewSUg%U)%k*kGC*#=_*x9w
z4gxipLGBLt<70WSL<{C#)ly~9NH5rBrB^_9fo^64`K&YGhmYmK(rchn59+2np!5JT
z|1GBZU>`w!a}eZ5(1hECD#KEJ6yKL#z+%TG<n}+*e^+4PfgE3;_L?AwNaWyeF$TpA
zq%p|>5{uyA@0$S<1I3re!AC3}jE7!}Px!<y$nl9^Fai_+pe^<S9+nqMyr2Wc2dkV)
z9n$#qA~_uSryp=_IZ%25wEm*XtJDKF#C!xQQ=;|>5^rEbKJg1C`~VGjYy-Jd?*vHE
z>;0hc@#*ID=?>)Z>E!U~4B&X(37X;q%kGA>55e&Taxd7?0UV(4i~&0r>~6+W;3xw%
zKfx~k#4i}|!^84oi5c9<2Bmu7!ElhNU?)SZ1htbrnhyy0bb5U7=>+R4Jq3zB&}=VA
z@#~AA^>3}0>fV6t1KkFx;nB+?_!_+C@slIJpnzxd0Ra#L<hO$*7EmiMR9TgR*x>m{
zNGdKpgJda4mv5)X2VbzI2TM;N$0x}DpagpwRNJ~RFx+I-k`rRM$*Lj;I$`W2e~TU?
z19%aM<84jQF3j7R0{ku4LGcJ~{)3v={C!EF8|J{_bMO%>C|-5p<?Y=Y;AXZ3n5+OL
zLj~|b3YHg2N<j0EH&5L>37XQZDkv?14z1t41quyN&>gyY=Jp%@u8E*q;94g!FfiP`
zbMxfQQ#Vh8M%~{)Rh9VMJaF6M=4p@S17M?X9=Kic0TlO3K#h73el3LP?}7Lr{Q2<B
zQ?FUlCV<BBZ=M1f^|}|7K5m`{xyYxR(WjHar`wUkr_+JMr`u7$r_({er`u7&r_({=
zr5R|s$(h%z{PGMp&)k0laTCalmpT9c{|6-@UXUG*w>3cF^P2nSNqBgG(o>BGD44+E
z#dzwq6gX%sARQBsC!ij<SmFl`n5fd2yEi~VbMp4fyEj3$fP&_f5BQo!1&{`xPKO6R
z-HtDOIvrm4bUS|V>2&zu)9v`fr_%wHHcNMa90Tj!AhU0tdd&n107!_xUJgxvk3jB2
zq(8Zv2OMuh-RIeSKmo)Bh48_WfY(f**aI0+<y9I2T4e)@nOBhV>I9@LQ2^=j><oC|
z(H;20voqj@M|a={&(44k9^HXIJfUe4#fdjhA<omgdFuYFn<qgjbS=o`AdIs90p-5j
z<~JVvnk6a*u7*!QeR|NHxz~L<kNb9>^XQ%fzUQ!x^V=b2{+4G9pq(n;>ew8=9b+!>
z1~pM{r}4i(SttFOUw{oXB;v#P?=ycSyAR`c56i=!`6Eu0J_X%h2f8=$Gru4Qzeb6Q
zfk*QZ@CB7fm!2~CbbjzS_=CyA_W%F?_4UhKTc0>~9xa*IdZ1*MM=QvVZ*`Gr{O`ZP
z>IaX;-wX^44tqg_XXj53e!tfqou6Dfb5s;uJ0Enu^w50$qJUL^!Kd@bXa1-I9{lT%
ze&Ub#;K6tdWE21TqaKXMJz8(qZ~w#}^$p2|1}`H)ceGCccZOl^apCuS@R9{24quN#
zM)<Mww_HOCKX#Px`-BL;Pw?>jgc5$BBA-C`G2;tAS7O2}g#{dD;IIOR5?XlehK1E9
zenEqmpsQvf<v%36p!S2qO9WqdRe;i40KaC9N`m2A)HHV%l;%JeSc1|VJLCdx-`2Nv
zT#nz4vh#y4wM^rG{}y!VuEy8801(^o0Kdl9&-?;vpcMF-Um%W!U*ihD#&2+96kz|%
zFW}GenLqM^599mK{E<JwDKqlSXa2~;pZR01f98(>jnIDj%pdWhbSKDvpj$gX^9ve$
z<`>Lh0R?#gzebHpf=Ba_3eZp(Jl*<qzVJBs1L|r1{?z~f|F^z%>^#EX5(Q!&;BN^6
zU6|W?o4@ZMr~}Ra{u}5DR|n8gpG6wK#y>>)3Tk>-KqJVb^OI-i&(52UpovTem(COw
z1;@@8KKy>*i(fT-G(W$1$^?q0U!YM*PyY4SKJ!Pps5p2qUi0aE1&TV57)TB*?&86C
z-J|vPC;o^Z^)o=p{S$xGe>87au)IW#FO>M?_j~cO5`4Af`~UnJ-(Md}n}C-7iH%Qw
z{+1x{wWW~w<mYbzO+$m?5S+_3zSaeUIG}Z(8ecy_WAqchKpck;<G)Y*0_<u08dpB?
z3;1*RFuqUY*ZBR3Kk~vS{>Z}~mWMy_NB;c8A9>~zf6Vny{1Kp0@=u>Yak?GmSx}n&
z#4nfuE{1T#DRh1r616Ol{KVf6j!#I``a`4E9hAO7F$yZ4H2&44BBB;lAAl}ACq6!>
zGJxar6MsaBiUTP2KJiD?sCYnP6vT(bVf_j;uT*fnGyu5+T3*52>-Xa2Owg^Si1Y=T
zAAh6a(|OFZ^Mc_ekIvICgmeW#_j#9ydT8G8=wt&gNY{vt11&)Y@89=0&IXzbhm8Lo
z22U+_Ug$jZa+i)EL)rxJR56&p3e1Pxr`&njr}NMY26Y|=P^|!-x&|#s=AU(d-}O)j
zGuRIB4am^@mm%ses6o_&&bW;_@tI$c+XH-IGV**KviS?tco;xx1(_l0K<y8Zyn#pO
zWslwv6^$2pT3{0ofY;oo@$0#$Xz<TE#P52sL)fGFh(Yw>38?Drpz1$?@{z`8ez3^~
z(MbFKP}TEk@qktwx~OP;f~y6&0ukPxofkbjFL@sPY43UPrL|Wt3s>_4c^}Oao|=b1
zTdgnE*?_j@zZQhoXUzu`d@L{2s($9r=VAQJpYOsbkj7tfDviJ7P#XWOgJ~}O*H1V$
z{`~)+fuZD*hvlJq?$^?w;ttfG76KgwQ1TJF<^w!m0bQB^St8-WzyOJV-`10!ou^zn
zkCjAwb~{>lv|j3tP$=Q{Nk07Ivz8!(XXl~TZzT=~e>1h-uCwfQ{_olA)5HQc&yjx{
zlOzAOAZE|zLoALRL4O=Ooc@CZ{yFk*bNcJp5%kxw!|5MrZv%A70CoMpPv-$h%c%80
ziLqz%PsUO{(6X3P4v)@5FUz$A!M8VScy=B*?xJD<T7mMCYXK9|crvJ&jXeK}zMtwf
z+WAA_U=JIBvI}Uw+oQWgrNE=}v`^<jkJbYvr5@c57QU?qJdzz0_#t<=C;#xUyk5%c
zV|l(L*`u>WMZvT4M5l|2h6n%p?;f2uUsTU$V(4~Jsc1b=V(xM99}{Thg`P(*&t^#d
z$G?r4e_JrKNAqEpj^IBX&j0zh1^?sU=KQxK_-}{vKM%{(;QL1nqT}KZgHj5_*i#;z
zH$6K)yeQKYWO%*MgMa;p*Rvt!LDSo5k8UoHW@bjvBn=yAlBPt`qf_cd86)IEcJNk^
z@1UcT4WbW&W^X(|*E|0YFz^5k&%M5aNRN>4aPa6n=h1oHquZ0iqg#|i6?AF#VNf@W
z^M&$XeumZqCFT6v+ypvYRMcMxLF_0k^=Q3a;@a)(pvu6?z+ej^Ji47N__qZ}m1uf&
zJ2<!+9%%Sw=LovgxHm*a-4k@R_0RtkKv#i-GrR-H&keuqN-ptlb5T+6U`L1|+~?8x
z@dd*_eg=@$uba~*fby|{N3RcPjKW35;>8jM0S1to6o@kgJi6UDzBfScAD1Xm03|L9
zkgp9qx_wkMUbrv_FhJJ0S3%0hZq~cO;QNXnaYODa<^q`rQVR}NO^`MNL@+CX_!c1k
zPLO=*W>Dz<4={MW3dT4GV_XHrCww=Uf={=qa)cOzM|X}&0Vs)qLj1B<uMJbZ>}xwj
ze+D!c*L;lQMKb7$YRmg2${yW(o}Di|I&XQjo-BRf)A<lQT?bO)08s+Ip-TbM06C0a
z|9W;uSa@`T=KOp+k9%|%TX?j7<8S!}y0X37k>gv#Y6b=d7XB8{W-yO#Hvy023m%q%
z0{pF;m>3vZ54d(0IPmwmGBPlLH$FY_>CI6|@aSbZ$^kN<(?!JtRJlcf+AR*RZNUC*
zOn3MXa#!am&u#|?uWlc83E$2i|0jT2`mG0CJIfvTJH9h8FnBf};qb9cQSsn!0X6Ep
zx<k|?Ji5INUMT(NX8=W*gD=R}2VZE}F)_3r;O`Iu--Pa>65-hGpyJ!<ZUMUNyl)QJ
zAum0ceN+;Bl5co)p75CI`Te&?>m~ly0#GBX^OR$wzXJm!0|R*Jl}ER;h6m_MZ18x>
zaTk>YaAnr*!2wEH3CCSjGC<3<UbOUrY%NUyMR&rBdw)P~V%;1l#^BK_D!~OwDG&bg
zL(&pP0}wg=zVcuWQAv1N_W%EX!vhmMJL4^0pGT7KcGmFe_EAXyT{@TH(aoE!D9qr|
zE#TPg?%>hP#E5nuc#et&NJIhT=obO&m>9tB^XNSM!W!g6(8ch#z=6xo=+pTNR6d<f
z2i?lf-?5p2fdPDXJ4n#1iIu?vBL6$%|9_8eYmeUW|KRqvFn_BqDBQY(IXXdY$IhGo
zgABS|R2*K4fkqa;IZLzhw{8K2dT)qIgio)FN`gn{Pmknig%=#Z`5Bsj{O50Z14;nh
zB`OJ^c#QDqeCc8N*|YP555M2x7mHN{89XdM*RvZQczFb*uGhzu!9(-2;U&+`8!t*#
z1Q`quyj%@#RLX<aBcR;}56QdTaCuO8Ld42JhIO;@2Y}<qg#!{tHh-XT^fDYG|K1-g
zUjvnwfy<kN%$(pDhO~oI0k(tF@U~C4X=;cVc)NJ#S&z<ZKA_y>YT=WdpinP^mVbR1
zpS>vg^Z&nx<^2*B&u*W)4B!m>36z2F`*eN;Wnhq+0EilJ1pv*zj<Jq$sQqyi_kb(s
z&eI;9*L*vVfV$zy844bqFJGAb;s>|cD!>-q^5{J1(fQtSFQ~qJVWcd`;L-g2k4N)A
zM$gVep2t~KK&hwB1zdl7cDq@4F#h&P_E2a&S)uL$*})?YFOM9%MVdg(3G0yNKcz;U
zr!)_>UaEiP*?g4I$MRk2L7&cxFAo0XX8;%7$bNveUy82yfLc7D^6SM4B|!$?P8}7H
zZqLp`AOjj+?*)|_i2Q&W{<!?>_7k^%os=l?Z?{M@$h(f#Ax*gad+`U6{@tNS*uS9q
zT*0IB^iB;128I`TKOp{6^XL}#=oIki4(9Oa4B+tS4i@m}3;^*ZJURm;Ji3DwJURmu
zV9i{l_7GC)wE$H_9-!26)u;0~qEam7d|~ztRH>IHy>NvFB<qW85Uca%3+-=UCwO!o
zE|K);E|37N3E_Gn3zBU;P?F%$tj$;=1<r9E%||RCwT@#fe1Dopw=;)F=S@(JcncJ>
zpwgz}E7-`oi5}go1wP>HXUYo6o^yXdv*+uLkoL_tcSpu<X91U96$bv+{h(r|+uZ_`
zI$s2R2b<#Ad6d89JXFH9^MOa_N5_jld^%sbbbBZ`9{kDl;^t=_29PnmCanw%3=E}W
z9-S|Jl8^axzIvgi0BTUae8C4YtJ~eerQ1Ql#qwB<WkZFOT}d)%t8;I_f6(yNC67*F
z{#HpuNvH$z6}TkSdCBzu|9@zI&{6Y)NAfwtOCF3beUlHo*eWl`;L+`F0cwVV+LsKT
zoo`=)I{UEv&>f)QxC3<VkVogsgTI(Ok}tiOIfIGebqgq9OSwGY!S`a*cYcQE6aQaM
z{rCSruKa;gJ{|QZp?tdXmvH&C0ip(f`4j?OVPpW>CGFXH2Gop9_E6|Nd+;w4I8?d5
zIXN=&w=M&v@4m1642Iu4K>Ohjmz0A7%A@n9Pv;|_WCw*8opO+{^XR+@(#YRZ%fP_U
z`nE2+*Y!VS({(e;gl^&1OC?^Q?bdqm?bd3?T~ric`>j<#EfR%eE-GpaRstp9ksr_j
zYoGUl3q#Sb{0yBRz<s?q&?b5K_UpqeK9-kD7aD$hecPw=vEj*=&7i1Hz6yz~7hk6_
zF?e*|d<h!Z0<CJoHQuM;)4fDx0s{ksA!yhd+^W9p+j-Qt^PDHR<DZ-XsxER6@#)cg
zoYABCn1Bc4YfsC+B|)CuVHU222S82QgMmDtLfy0Tc!`fMD52l->HPUZ`WvV|_v~gb
zbqAk2(R#qMlf86@XSX{C$Sj}EpHSoe2N-x-{w-Yx>8OJ|3#wck;}3guv(EArWAJEZ
zVD#)f{(1?LF_%HcfQ;yN0FB0Kz_PbvoMXJl{|Ef?3~233YWnwL05<<>|E7X}SAj|$
z^8AZ*o&z*aLDfIF`aN4O{MsHA=pM~S1w5LMad=w(Dbe%jmh<cmg+$`Z7k~Ugp1SSP
z$yRa|oW;*0viR%6X%moR2h=n6=nevDeR;&6hXGW6qMuJdrSMn4lHLNrPCbB@-d2Am
zBK$$d;Y)8?-UFQ8Kn_IDUx|L8s6qGd?jKa}uay_s{v|TKDd0$NJ-#4M5ue_mrMCy9
zod6vGcrF4O05}dA08n}hYAcj*cRNdf`c1dNRj)I0C%X<*$^U)}uAV(Q5A(My1gYr_
zQ855@4=g-7559;68^Yi55hMeu(Ys4jEI=It(DoNl>F;Uz!H3`X*ozhkNF@Lg^RYa}
z-vhCa*#o&=Zh`Dfg3J~j2HBnpF~6k<RBCtLd?5;P4S!1_NT8ebr!%<O@$L`EbdDEl
zAE3<+*pw4e`z6@IquW~m)ERN`0fprOP*doVXXg)(&Q~C>oC5bFP&!P7U`xOqCZuKp
z+-z{ZpMc2s;MUVi8_4(rsQcro`N8ngi%M}phL?h1QAGVfrTmVqeo6EOdk-zYzy3=^
z`Ue?@FTY#4lb!y<QF;L6)-Txdd!ZLL|Nj0%gnvQC;q$MT8`=Iv>EEHW=f1j<(4I4a
z^d<53Hw7SS@V4im{SnZ3z2gopP@B!^H9rGlh#pg3=`}w?S|`#NKFa=lO!c2$@iQQl
zW6EDbk@skRW8u^3q7ncqN&<X3eN-YqT#XlxqXZa0JrMAyDI&js%ma=0gOuxd^onZy
z6l8d@{r~^}-61ME@KJu;>VN+bWO&hzTfJxJ1&?0Q8$SdYUV@622@w7n5I+z!J_6xy
z0`VOY{G}kiA%edE#8*V{r-1mNtPeG>1H@-U$k&4SA3-xW;NfeH7jIv}O4|}$P@%N;
z6=;CU*rPY>f9EmCI1Z>Y5e)8&1sQ;wyr4;(3Hv~!Td&{4`}g5s15w9+CHO(bKWzN>
zIk@;o8vlI_wwjLPza0Pn|HnE03-Wm9#}_FOXA&O&eFZJ~Un0hTZNYWJqpy&<feU0J
zjmCeSXg>Z+Fg}ByqQ$2ZBq`A`J}v&@j?XJE_`&1(Qy|VH7@s9CFyfQf1{|M4Um)>m
z1u~H~@fqweAo2Nw2PuCxKZeHVb~gdgd1GoX3ZFwVXbEW(G-~)JXtukksHJrx&CtNc
zGe8~HjNkwNgROquj4?mM0&+~}#}`K+&LkM0OP;~v6Le8W+60eoR$D7@d^&xC#Ants
zP*LZjq5+zJ0nIe|s8DNurr8cld^(}e&oF_S-uUNdAWE>!&tS`+JGhbJbMr&=_+0pu
z&ha_pC+_$(0Xe4g<BKm4XA+FhD^D=uGuHwfpG6-a@j2@W&Ej)2s3bt2Z=*weav;U$
z<NM(F%;|O$=yXw0d2#tMBsMcaxzi2%^r;r+^r;H=+&KX>e|oXoMMVWUbAmGE<?sLh
zgDiaA3!2zMo-!>2xuEmo3&RIsm!U_YEc%qG;A3bMzU~C)$F*kQ_}laj5`VWI5f^`Z
zK>4+F8)#4(G&;N%#z31dMehIJ292hHhEaXGb)Q>-Tf-i(*_V3p*H)nQG?4jHmKVjK
zZkgr%5>*e-gbR4Q3_Rg-&!_VxXu`##`54O!KZv5z+bF{>$m>b4<xdWFr1%uR2M#rO
zd@_T)-+G{w*73>w4Oe_Fd<dyB6Co}m7@v+0QRDNj2{=9<y@A9h7sxmw>PrgaQ{0j+
z@d@e=D0qO^6G8hkS@-bwXT0u_)}N8Ohrd7b>n^f9biBpFqkE4EC}nrAQ335)1TP4<
z?9qA7r}I#WsAuy}rczap=HE=E@;<#R_Am0-1sPi3mKuUOJfJaI&|)meeo)WO3&&kl
zG?+l+DxEbd3ZQiYogZI3tzlwleOq$gaVJOyJa}=-12pppnX-B5TF1lyp8o?+iX-j!
zdx>`c6*2CW^lbjg0(LJ8*u9{|w+t_Kv4P#J3wJZvKB#*kGav}}nnK)r*>NXG2GhM$
zYl(F4OSJuq==))a@sEUO^G^Y=e*{Y9Jv)DR9(=&^;x#MSJ9=>MK<2BU{t-Y6|I})5
z_+N6|36jC|&(RvFe~57pD114<?%@E3?_UN`zdQ=!Anf4_S)YLj->X$%_gr?|36jBd
z4=DV>@k1y*5DH&#chcg8?`=?-ba)4-w+X7~OhAKlA8zwAbRK(g@ea5KEa89g9mMLq
z`QklT0y_KF`2o^@En$ZQ^<mH~XlIEE>d2Z!bR4+nkFC76U_vUdlW(Aw*TEn==}=yO
z{)el){s<16k1sYtTt=|Go_HIzyw=qRm)AzmA?0-x$T-@U*XhP|DX+1`X9WXNd``ZG
z8lTO#z^RGm^{?_@T=A(0azW?E7Y`vWBN(3tZ=%L$tS&e{lb%B2v+E{Z+EddF=@Orq
z_3tk((26}=<Aw0`a;QU6OaBTn_;iAYq<CLUxB^N7{4JpR6TE1x(?vz$Mb!;(Lf~&*
z3o46SZ<lytZ(QqQHm()0Hm+kGV-ADc*XKZs@D)6eTG${dNcj(HYA0L++w1{anQ#JR
zdFR0wBG*B&=*!^QdBmeP5VEu?lmRp*=gQ&H`SO2&fe&c?{!3TT)B$L!1Zhp<1(4p(
zk5GS>peHCf^agstb!dWm2|BIUqnnjm8=Rs99z#-;1;{*j31JFaGKSP+)&uduD;jr$
zTj*P14f8dg$B%%@Z}9pBnBXB81GELpg#qQfd(bMWCE!+#Pq(hQKECwD@j@8V6vx+I
z=XmiBx&i@rdmS@<adDH8zEuApr7wd^*wU92B$oMGcY>mrj_C^;4KIFPh9$ES9nhHX
z%q#q$<n^NQDp<Tk;KgzftMlcH=@1!@=3EBGl2}MW15G!9`b%hOEd{LQ;|mqApE1&!
z0eV_vxe7~bpiO(A{va$pzn;!7@4(>E&DyI0PJNReKvLhXE1;a<LvXxiB{=mhhNZ7r
zFb0wR!{a*m(;G7}>FplD^ad}V6!^CrdUT$LuBZ3tyz1L|r1Rs8H5$AOtp`diJevP9
z)*0;vEjoG43GRPd-Yrq$-!2m0`SFFh4p`9({_Q65o}Dr(ogZJ6fc2GJMP5h;S`R?T
zJ{zz;-1hOrcYb<tTpPna7O*}{`{3tIWP&zXgU+|)?}BzvAoIE)VGhu#@!*3Z!Aqs;
zC0|>@#sfb)@(Uskq)>nz=Uo1rU*pzi{@5EJc^UAELeQT62cZ4BzOA4uo=%o(f(@&C
z$FFhlGk-iwBS<L=Tq*d9a0k!=%n~k`8>-Lx^s-C^wT3-9Px*9Sd};R!wEq24-73&w
zilFL&0elByELOw7@^JrVgElD(f=<rl?`j8c$2$P=Fi0G9_~uFeF3^@)up{fmL6?4l
z)~ABD5A%TUz5{KzP=X&fUH&YMU*py%{@5EJ6*4dtrT371tPVD;?j7j%#ZUb4EC)eq
z5hotJ_<VQ*X!9#K+zHj^e0o`~B6-;NC&a_6K|7;B?txt47>mUyNPPwOZ@J@b&D$^d
zyFd%TeL)lZ#~2tG9B*rY#6Tq+Xg|;aP|wGs^-?|Luwy6C`S&+L+f{9tz&o!k50og~
z)?oylhF$*b=E>WyZeMb|4VNo@0@_`Q*e44*#}$0xX{qDQcgV)qJx0vOL5;h4^7ciT
zQK02pFYexeoOF5j1}H>0!49q7b@ztH!AC5hIX7th{}5ofdjqs5cnV0u@W6!II*hkp
zBFqBqV}5h@2BQCrKELkKy#>5}%eVEUN9SqJPSAc={uVbz1_oFD?TRj)4_!N-y*RD{
z%1<Tc9<BfRTdWuv82GpIcb<K*0W8els=)|Z|MlO6fBVz=I^?k?&_b%i9<BdN1o^k?
zcfNG&eEXsbtgEETxAlMB6~q6p1^KtLRHt>a)PYtOd0PH2+0Vb7r}{-OSXt>K{_P^w
zE}aiwY*qui;ZmAQr%B!G%dq^1uDJ=USq!e3r`o0S(Tg&e=1!fu*H?U7|9kb?RM%^~
z1WjS`Z|ClO^&$kKLNU#yQ_rLMFla!V$;0wKe~TVy?c;Xt7l)O>_Fv@R&i!ILgw4Uf
zojI+O?e%&7?ZO}@3P8+wndZ`I_Iej2{ehBN>)C(*{~Nx2dE?*z|Ngx!_K-0P^k8~f
z_)UOe0;E3xDs1_;OLcyH;iJsU(0Q}-_zP!cUIvGj|0TkPms$?+PdW7cR_6uqdf2%5
z!z~BETg*z|cHZjz_@Yx4<Wle@C8f7JKXu-GQLf6%V0a01vCJWaCW!kW_8EZ3W6p!u
zc^@uO@n}BI#J}DDA82LWi&<K{pi?niRCGL=Uo+lxQPH_w_W?Yo4&B6qGXD)PzYRb;
zTNMm%d+q^cU(hMEU^_sI$$UDGf94l3WxXfJP%84;{<8<a&H;~3mV1zD<9CTJ|8}2P
zh8K!jybSz$toQB;G8EnZ%pY?MuF%I&1*W+4GH72aXk{?SHK2AXs8&YgFX(uKhT(0P
z_1Aqmk0I`xg;=#sla~Q(dMC?#h$}vqK7~aP%KCI1<|!f4BgpA#AoKWj4j>u#3~n6C
zdP*GT!SBO`xK9jZ9w?ZQ45Y+;$2353N<H_LLCs6+WQiv${LuWXMyYvd@o`NZ;@=Jy
zd6@G^iw`vO+9)+o1vR~xfy@KNuSX{f^mxM0rBC1~25Gz!w9p!5{~y-<eh%Qw2ijI{
zup2ZW3SO9doqs#$i!*Ax4E)>unD{k*yf^@2Ykcr%{?GK8KjwR#8YpG*zdryvO!Dw&
z{>WpW`6G_Muu|b=Nb6*Yg9P0D(!1ac2igb@S~BYZ+SG>RKBV>d9tcN(PAmXdFIRjz
zkAW8bfHti8cAoWUeOqS^k~D;^FX!LR4XOux7$3h-1UYXzAHT*AAI5htgw;S%7<t^o
z^6zK<h!3UL_%)8bn5WFk;L$xrWdUecc_$N!%iu>V5R-pZVetXpE$+du<#Lzdg@ZEK
z=kOH$7#<;r@`bqgz${-u>t~s6=YO~vqoVVfU%*90=fy=OUItJRo7U;}4`=y`y}T$@
ze(eS+&tdLA@S;fx#r2?$r^{W?0_)1#9-W6k>O3yKYJR}z!FdQ2;h<AP54=7J_abz?
zKX&^{)M4S(?J^g%#~GYv4!qz)wX^ggl5vpndmQG$^8?6TpZT?1<}$oEsEFbL?D+wQ
zc{tpchh`*2?o&iF3~PQR<UaoGF0qgR<kvdz;+z7imx*>C+`s($k<F{4+`MfrvIzI-
zQEuKoWb^LHlj&bYSo(w3k5Zr}5C0TI@%|hs<sp}sNaH6j5}tE2ywC>6B7ArbGM?|z
zc?~p+tnotkH8*sFd*|U73}B^fouGZjsN?ad`CIw6zDM&hCXeRh26tmXTjK>>R5V^3
zQb5YyccEJ{4ujkSX)1YG^WK&bV<?GzA#oTyzyVr^8vq*kFgOAlQD9Ev2bI+?7{S{~
zm`g;{_%)7!OFXbype8<O{~&xr4VpAGKY!vEFkNv)kO55=@A|kMFW`ekoG+LUfCh_7
z%K72zZ$3ht%ijv>V1gz;h~Fel>KYse@LH)8|Nj4fQ4CHxE-Gr^d%5852Spq5<bMgs
zah)Gum_VG3KDMZUKHej87&hLM4_=w<(apM63_QNG=^SKy=hh)mY!DvbA!EPvXDQ;>
z;{-#;cd+i426bOJUKl`>pzN0p2PbgU!R8gu;PK1*LU|u3e)(IP85kHo^9#5MeC8Jf
zt>fSZdAs!he`^<XIM56GaI+rfa5Ijz9N_sk(0Y!u;0jR1@W5w&LC_?a1E@^_O|PKw
z<{N+h{|B9;@rfUNDu$1W3Upr*D7~YN@3kBRO~ieC;R5ys#`qpae5)LU#W(2G8qoM2
z>s}FXd>=XkiSJhjs2bn6)_Z)Hz&D=9^1>MsnV@Ri=Pm<|^&WB%MWwf4r61^s9+dV^
zIF|VDcmj`q&KJsiK=EHv{s|QKpFnZ1@PZ!{1g!^3i%84e*ryo|gQEP>Cs3P50epH1
zQj|mT_lsZu|3hqk-GZK<m+XhcZwkbj1oN}YerWu@ZUCn@k8akxLg4s)bP5u`Tp$zS
zvjr5Ne}F4~#l`W(FXH?IJnMNlUf2;Czwr9#GN`kwiRjNCR(SDCnwJ3_x*B&~R5Wf^
zKk#UN$9VJI?dlJu*TFSOTs+cwFOc-20PZ}W2d^tRR-%k#p1_M=QoIZvoz5RX#&{fe
z{sHRl!;755INCq*sP*?Yuo;N1&r4YPJ&etMMI`$<UQ|i)GITos09k+B`48Ck`>=tL
zG^F$3!CpA)0UF^tRw9RLzZu93MA!cn+<MsgI43~URiJe>9-W6?ta!-Ha63mu!SKLs
zYjB7mg%`L!hn~Nq@WSpfL?v9^1o-$!0(b`!><E&j4?$V*7-$C)?~4UHKv|H#1+=g7
zcDBIn8kK+-J$t}y0{&Kg@Y#vqN}{{nP);Iov*6$6Ayr}z+Tv??py8(-^c<1^`1uK-
zQ(U08?{@xtVI0c@*~Oj!T43WC18qMv{Io0Cb2~>R!0^CrdynQLFj-i5y<mnp1hm1`
zquUvJriK82>qbz;06L?k^DbzQe$o!Gi#<WdfIS0Ab;|~Gi81`Y3<^pI(0+x0;|w6+
z)A{H{=mTyB(5z#??Hm;cAIk?NybTr%{4I5$GaGM!?h}RC@6pXF%MZ@KNhd(N%^!Gl
zbG&HZ&CdXt{87324jf#uAQ8|g@5O)r|3g+~ApGLd4WGlg09vOZu^sGE(0pbqXh!k%
zE=2$Cc8!X`|I6JBtp{%Bs2G$wgRLo@4K)HR8(;vEdf5VQFT4;2*$keDat4_#^9@>-
z8QgVIF?bpO|NsBHH~wGl=6K=sNPxk!^PopJs}CR8LpzVdJ+y5XKf_Bc&{QeHsT;xN
zmm{w7WxEi*@<rf9Gi0g<U;QEQA`YU6VEs`5>e@q&tpg`x$ng;1!*pKX6=DD-W6l>h
zw}O&!Nufu#vw#QqYz@#xxZW5Q2hhr_&Rd`@Z!cON3V=6|^KWyIva#cDdBecKU}FbP
zv!Inxko8>rQw~7(C3|$<;@<|^EDTD^FAAbSNf^`whM!?p0BSmTbbEu2^$~=+q~L`=
z*d?Xu;1h(bWlIFb82DQjfzo6zXfbu?trvH9@`Kv>H7W+5_ys^)^_sOA`CC9!EiZ(2
zf@+*YkVMpask9%|MTIs;j(_5hItOkbIeg|9^igqnDFNC_1KK%QItg?-5NK;1Xt=lA
z!QuY|(4dD$=i!%?pdn>>NPigOuU(KqnvXAPBSA-;xLbgN<K-7nY2U2P2x_x`IRS37
z|Ko4X1}6*HsRJ)#K)YrT=@n=Cm@a@XeQ>-`23dxGJt@bFf0U<>-M3-sW9MdY`ltn`
zkM3XzNE+!3QSkt8lt)V_(f3gk$`wRH0WI-DN+=*MYC>_3z@AV*^TUv|^7IzORS7SY
z!LBL|ho%(|eo$HgO^|_#Ed!6vTQ4?l$4o0FRWDv`Lro{3qls%&96s?2mZ*5V)C9-5
z0|R(hY3U+dY2$T|;|`Gf;Rzxq94SHYfTA9nARZrsB#6>B4|tdFWjWLqBGN-UAHMV;
z@WPmIdJuTQ2T?@0ynvJv9+304ZrlV_cHr%{ye~Fy1f>E<e*>HnK%3t@x}CwvA;P2E
zSpk$T62Rveb-Jizz|uwlQXyi07d35w_RvBL5zul(q_hFzqNWY)Fi_g?Xg&fiIwnBN
zj;l8y>7n3-FxY+YvcrNGlpa9WK!DPN11LQ#+zL()E}*y;@KNyqZGQzfuq-}-$^--c
z7SO!~FHUViO&>jXT~sVUl@+LBxLu=?@Dj8^4w63bmmQ8fK;D2S5zkPhB*KbFBBBS5
z2!dLAA)rD{Fhs?IzZH}|kdh1N=qGTkLPUBA=fRg=6o^^hqCmv@7Uc5FqxF(!=ULCr
zD?Xh^q3aInR6&OVw_Yl(G`#&9bl;9=cgRuD4LhaM9-W6hdYu_PEsvDG0<S87pXP8F
zJfYWl&C~LZN2e=8-9yjr8qi4S{}O3e(9sj0JUV~A2;KlnhZRRl*gZO989X}wfyTQ%
zE$@_GLN~1Q8hDw5;eprd(k2k=-Wsa7R}NBLcyxlDykI@p$%inUd>*%xSEI)_(s?G5
zplJe77VW$WO4peipv|J={4GtO%Chqis6{giBJA0Dq$Ja$`7cvl40wv+wGh~3#5~^J
z5@+y{TL)icKy;KCdvx>M105xI3%vB@ibr=K2PkuE{0}k!HU2b^G?zl#qn^z=DvTwT
z9?klUC6F^K<3LAyAnjjw=K!6@)eSzt13Cu?KDq-^zk-e-;qd8v2s#U}S)Z|V&+D_G
zSq@z1nRtM9VC(>Sw!1|Ibc7oyNI+)^`g9%#ZN@e5ZG8fAvIT$NInZS!hHnjTdvxns
zaf&g#RtL>I`nLY(ZvhXHfHrC{m#AoXFxRLUcv{}!Zvo9x_;&vF=;i|jLZwHyxJT=y
zlEN1p>%jr-*?Ek=1-h7zzXi0Y+^6%CPv^@Q8teHPd|TgwHm(bLcDpiw&ISPIjZlUX
zd(Un*IA5%^!LvJz!>9A({~!a9OIksvu)+4_gT?|N^YP8DprcUUy`Gjf!LvJ*!>9A*
z{~&|cTU`zRPXNV(g-17sPbYYZ++lD`?FFq(@_+;}d|Cx$l*j)EzO8Rd=6Zq}yrt7T
zyInzsfmFV};@kQC<@bM}gM*OAU!na$&>4N6-5wSmomWB296?L^89<A?Wj8Q^rYK4(
zJbFu1G#qy@gQ5a-aN9x8&W|t7KL;IBR}qbU<OzHTW5X{y&(52Upw15{le~20-*y1$
z3`Xz)PLL4@kWV#0<pDUeKqS&8fSY-*ufoR@k@GjodOvq|eB~j>3t><}OsGBej>!7c
z0Cc2bx0i)S=j9i_K&Rk=P82#;67<d4krC9C03AYEYJwPf1Jz9$pg;gG^!x=00MNQe
z4Uf)GFC-o@fwq!^G7C5;j(c?TdvyA!XuN(n!SKNAC&>GQ(ASHA@&~A23OyU<oJS{?
z^L{cA^$BP)543*}dj5)^4=7eXzEA~)4(KSK<0Zb}u`KXeKl<xnXA^iJ9n!N0bVv`#
z9MC~M&Br)A7+*urCfEe)r^AyrX#eC|R>a{1i;>K^1TqI?1|%WFs|RR8hRmPQ$iJqb
zh{o`*{bp+TcQ4D}^RFwYqk!Sx`d!rU?^$L_{EOUwhMZXiT9V=mI$jX@d?OA}qJ^Dr
z<O4bh<>iY4(0LM_Y@k8Vo1jKs>17Xi)BE*tNcurek)ZXA1j;+z)%eQ0|8E9Qc^A$!
zK;<3RDsT{abdp`(Y1|v6<(>UXYUGE#43y*ta?YP2T)ty3@BFD!zMuUs3O~$ku$1rE
z%e(%q)QI1^|0wY<oy$A4`ZL3$JIeyxhQ934Tnie~1zlItUF85ewJ^Y^w?xGObjGrU
zPj8Bfhfi;f3ixbg1<?4P2Ll5GL+6i%C;vKKRCEyIzrF^(ogaNWUx0><k1YlDfI!EX
z`=~g0G*=2RmvV#Jbrv3$jv6JGLC5hb_;&tyaqS5sL+gQxBGAdh0iD$jpr%lSZ?dC`
zPp7wqWAhKjIxml27CysEp5H%!+T=FfE-E^m&JLd4jt(A-A3Zv6{h#oGfq|jr0DlYU
z9F-l6;C5-Y1<0)CBN>n(bm)15oj)4RFm^gSygtY;&+vkIDL=zYH_+HHxPR2`s?d6%
zPQCdBV}m7wN3RPbV~OBv8AN-j!H%Jn*Q5Cuqle|O(ocp5UM~RK^?D|BJ`^Q<8{a^d
zs-N@(op^oCwey%y=V|^HP`|~qyVAm=xgHeapw-Qw;4T1#Y6d7&K|!7X3i1e#-W-(-
zP=^K_Ar&B&$LmN?@FXAwX9PGnoj`Nt4xljgc+vV89H6eCz^*X7<k9*Kq^H26)7b*l
z3iar203CZ?0=mST&xi4+XXj1V&JX`Dcy#+4_;$YZ1)c8r>IKIVQ0$dX^ysX%@Mt^&
z@(W5pg8Eagtp`fHJ-XdNhgg?5d2}=QbpG^74p8vybhPm4j&J~X%3MIh!QJi(o}C|j
zJ1@?3{Qk?Q^ODC5kZ%+m|4#<>=U&f(*3YfqN+$axyDNBr`c^-&So`whDFFsV`yaV{
zY<vSA!tI`;qQJ<&;M2WFMF2D#13IJ$bl|*$4=4h_XIpPkkpRhn&Zm9^N-Eveu-JGF
z;`X+H7hQWCZvpRyhQ!Gl$X24>6qO2(UdT3SkPkdOdRtUxfOLUI#$H!=boYQ2BE?Sy
zIDX<l@#6uCpMV!nAA;j26?E=DNH1ud0~AL+5PK2P1PYrH7N1@gKG2ck5gwf}Dh4i{
zB`O*|pxxD=`~p7I+5tW8d=`P?j=wbz)R2e7A1G|F#NRjm7LW^|ame4&%>W8Ig>H8R
zSHriS$vG+tGkrRfEx!NtZT%04GmpBp9-TER86YPF_;$Yc=&n(T@afJ`Nl2UE+YOpO
z=yp-@@a+5mKB4X>!p)wYFF_#&i*v7D5j{}v+X0k3`CUJGHXmp7v8+)E0Nrj=qmuE`
z8RU4-`S5oC|NjRkif$iJ3G~UAfBkWf#v|xHdU@@H0Qi(jM1J*Xexu>p?O*|(%-DZI
zfT8&Z19&lZJqQ2PL;Tw=LDy+(K*uxC@-N5+-|hkn@Hp3X-|jRE-_|GmEz_7l2gcW^
z2r%&XZ2={uUKbS)!~Y=9S%9)K_~sk~5Gw#ArtuPVx;wah@kw@6@#v0G@$l>|k!A2<
z{0%DI`1?RZ51zda|2;t~I6$|7c(fiXaq&p@RCu9v<KKVqlA>e$Egm4dK!=}$TD;7l
zk@(J!V4vMR4jN(gQE>p74>zb0q`dVo|C9s#+YYoID76I}c=I~cz{C74pFt`h2L1w_
z3-19s{}y!kZO?H528V{fcKj_-U?rgPyW7zLl!P@v6DFM>|4%ppssN6HiWrCH3KhmW
zI}p>uvp0m5!Nc-ei5Q3ro=Zv&P<Zhf<PA`|@L~MnVR^Vj5Gs4q10;L(#=rlqZ~0qw
zL6$WiXY{nJQ4y$%@kl=I+3jcG*&T93;>FDQ{0t!bq1PvL9(*zX9yk|)cMv*&Mhbht
z*_D4=rWDxiQx1Sm9N}+m2lehiVR`Qw)a%De#S9N%NkNCfu0jvp`eUHb1)o0u5tQXL
zTtFwB7+wMurHH<}!^^p#eFT?0IzK?FDgIV#sK5=+?;pT>Yxt)ecnLZg1YUlD?E~Gx
zpka6kY^q1+O^~skoiAY~yQnyLg03C_AD951sDcFi%U;ly?iVjjA(a<oJk2-RP2t7$
zqXG<_hrkt6^DhSee$ZG4KlBccmu#TC#GIqz;bZxZzvUY!Xg~=7G+Ymg3GeIw{=a<i
z5455Ow0{TX^g{*c`RAUX-DSsoJI{DP&wF>910Ess=saE$3v=ti7am6i7(AQ*GI~O8
z=mDR2TxSXz@w4z?d<_~EgibQ59~EF|Jy0hI)B5uTFGy>r8K|Q5wES9n8Z-j@ayFK8
z&WUs1vf0?&x8ewX_kr#!0OzjuBk1nS1!+ZdpC?xLA=gjMZz?>xi!3}qgXY&gy5lTB
zmxHx%g6pbe0ng+!FLGz_Gq{3=Fps--mpkzHfrc9$dtFrigPH^ppnLDoFS|$p6)+C3
z4PfmL=zSNU%PxF6e?cZSy*gdgB|KplT!8MpC<*uK4pEly==L*s;RuSn?hqB&1s9&T
z!MQ3Fl-CkKXQDFupj>iMCxCjfMQJzeMvK>-6FfW1Ej&7Zdw>^VR-jckp!Hy&L0&Eo
z(CN^fKS9Gpo#hsWw_l$}v>)9-O$q*%%b*$+_k9>8TA;2se@i1sS+^VNofX^nflhOW
z-&xW8;4i3YWdW+jJ6%)^JUUUXt(fTznxF9j-5YW2MaxW3O8Lg$V)g(3f6r#<wG|&<
zh_HgX3Kj9tD=R*Fbbfx(AkWJ1QV3K>fiBE=;R({(%_{d!l)<A{w0Rk1`I7f6eukHC
z;rZ#Cn>1^w|2HQ`mhLizQcaKKYcC=}iL>+Y%M+li*sRCM-?|UP>UQJs==}IUz~JS2
z5V!N<iv&K98~8isgZRnUK#MqdXY(_>KIGBOy5cR^R@dbaTd&UKXLt#^fdZvIYkp$^
z%E3O}Tfi&wp<{%Q>l=>ycAf>@9s$09A=v>utEW*f{5k<Vvd8$?12k3++WzGaDjhp-
zzEFY;A$fEjEwS+h)%Bk|IuE|!nFVsAN4G0OsU&o44>X1gs?p(#I@Tgdln6pj)c{Qz
zK-=fgwHu&OYIHg9!~yDlCe-{zMgKX0Mw40(p!rW{{&4YM((nI}b_GiO)hwg4|H6<)
z@WJ&9bSD_(il8IlR9T=<FZ|ja+<pSh`uQ+^_q4oIV&>6Za+d*|8h^f+^6NjS`30Ib
z{8n<yqgjs;bf2;t2S~j~=SLsL@1VlQ@=oa~=-RVb$e1)_7bl{<h?ZY8K>5Y+EvPF2
z8dV3cQ3Ksf<=c4-?6L%fdZE{G9-!+-7@v7GA6M|Sd{^QJcGJff3?MgwQqbWNYhTcL
z&A&i7r0W4Bgqcgt;rW2MbdLvUsIvJeBd7reF$(P9ccqwv=t$ZggSCO144~aU7-QxW
zDD;m2vVRPILQ@Qie^%Wk&OZW!!9N_x{z>?O%|E+t5$7L{!Qda1_?hq>n}4*f6X&17
z7e5ESVe`+eOT_tSP{a=la(esl6`Oy!E)eG*mcfwTQ1XugR{v=2CeA;DB7RW(6YvFF
z{QTNJg#3e&-Won*^N$vI(A%S%Q2jF~(i@6@HhjY7pId8)i=V;gp9deY`DfS0q3Rz2
ztp3RYPomK+y<xN`eYzn7x8SxL=m-Vh&NF_!CQhKSi+aA-Vc@NRjPHFczm<6TbUp%&
zG`N3&M~pf6)<<yH<|4Fd%v@@P)B-yIZh?We6L#M8V0;fcNXznD={B@hCSts&8MZ;N
z^bS}jyzPc`TOGKY0~yc39N!?rKjrVS`NwbxETIiX|1crN52FX;drzeJS^f^2e<m)(
z=O0kR8WKOA0}?;@{B!*+HvfE_H&p$@j@3Vk9RuMX)bRmQ`*SGm1A{m4XhQ1G?IN=O
zGx*v&39qsF=NFOv1uFT68s+u$S8$IYm)D2zr8g$fKs)uzYgfaQp!)?umk)v_HXQk<
z90Xk+2wLk0TI%@Hriq6E&-y(oj$eVVo&t?Npp5V2v_S%8=#S4$0*!)V_^+pXxcF}q
z*74Ollj!U}jQmO7_}mlFXlf_;fD>wt&sl&b&_R=@hW|afb&aozf)3<^Y-WKB(Sc@1
zz{83j@G<Rxm!SD>=zIxyIv2FE0W{m80A6(P@Wt~ppg{KQW>Mj91x<%Tn|q#}EGi`h
zpz&}I<`~fVk;fD~E&rAHf`|KVzF-7-vGqWStw%5KmwrJ8&{kB|I?$Pz$3fHkpw;;=
z|4+4G1Wg_5GkSI&DQ$wTc>Ny$TDQ*MS^=6%K)S^iwDR>ZXub@(LLPLV38ei9a!TnH
zm=w;TatHMLF;T;d`3iNyYxzkc!%F};ye>k9N5SEBqz@8aS8E1ycwN3ko$v}jMr3$#
zAcxmN$nYyTyr%R*!fR>uU=A<i%hU<4bZ|{hM1Dj`Uxkq2U2u4%^gzO^v}!Pi7c-U8
z*Y>^Sq%TLv@G&^NOu8ZA<ytwI!|U<|>ZGrB=(=};<vj~>eiVcZPlLmYr3(^Xq7{QV
zyt=6rUhYfDNnZ~k!>i!%y3zp&ucu{$IlQ9JQzw0G2aik;QGTJ6_ZuO@x8U$v(hdo)
zt)+uGyt>a)C%oFhBOgSB7fOC?gbWXZ!>gnX5?-w(gE_pS&rm14u1_U0Kca+JAY`}}
z99}N1knjpE9?apTeVRJq6%JmcLTdU_gp3M<!%L(E5?-oBgE_o@pQKKBEuTnE`uYeN
zr3HuAlO{-beJvPd;RRaX0b37+G(&LKuh+)Oqg!|92~h?_&(ZcJ=+rgP{<1pQil>_|
zcJ+Y*$D^B>zZG%~IBbBwq!>K4z+9uE;bZx)#2egA{Q2S*WN@^^+M}2EY$GIC?&X7m
z<p@SMQAdT*qw{cSFRY^n+9ln3yR->?T@+~XGGx90I;Q}-(XJ7+J|Eh3_2^_SJq4A+
z(OZP9zeigyf-)Y3C46QcCm24bpd&KGhR-g@C@VO8);2)GXJ6hB3?C+sZr#db1jFYR
zY*-v?`e6hukk|0E{0>h)vmm3k;PC0KhlJ0(+#wo1kw*!J&#P8^`3p0Asvv{G;PA<<
zgM?3A&JYbB%OeEC=TshP;S==|JXj76AKzL?_{3!o*6=|Y-#dMnI`tX*5m1m3QU9Z~
z#}!{d0uD63CsG3mIMpmrzzx>%z1fGT6JF2B8c+E63=v*WsvzO@HDi#47lHb}@BqR5
zm$d?vm`JGqpF)BKT>n=>g5_R1C|CwV{STYCYQ5yqdBLaGNAQ20f@6avgKw|n|57oZ
z&O@)cJeprIHdHY(lnOV$U@ZM;c<JT+bbbctc)CaOg_jq=Tu6HaUweYG_2)sL!E(&`
zpKM5M4E_17BCPXUYYK*o|0ZFb-}+NdXa7-Ye(MNm@`u**Tfw`iQ=YSL0tGS=^&iUo
z)<ejK0dRj#q!dzcsV0L8uEARWDet6CcpZnHi$HLE7-jxpBhviVlVV7CeN7z9;q`et
zb;7HBHIeBHrG3?iG{3c_2ohdL69#j51@E9vc(pGlGQ3dIS0K{-R!boyyr#wv=I~Oc
zQu?~Sh{*6lNneUc^IIVWknl>48_ePLc`J3&*K+WtH6qG;l=0z@kmdd0@?Iq$5?-dU
zgE_obQz^XCyU0mj2a)EtzT`r}i#292hgbC$>ZGsh;6-Ibq%V~GI1y=n>qrhHyskzK
z=I~m*i8|r6yqU=Kg_0i=k><CiWJAJhY2;uIuj-A|39s)}<b;<Y()?CR79_k%BL;JL
zd2gUjc$L?a6JCr+^IImFknnO1AI#w;y`DPZb-aw6@VbaJzr~UP2`|yGK^9&F#<y;+
zB{;rys~8kG#E)<7LYm)tn+6G%e<7e?84TlF_{O8K%x~>nLoj?^K}TeWo!^>;G{1E=
z6%s!8f`?%EfabSmt|k~hzjE=VA1w1XNb_53Qy}59FKCE{Pvt6t;ll+TvBaK!FvBMb
zX@09W84^D80*7e$M6M(lKCgmFOFvdf^IN$|knpJs7_8xgGQahD1$F8(b?}x;QrqK<
zNb_4JiI9ME^#=vqU>)Dvy_`DX#l9Gn#7GUVi%9cZED4bC67?Ho;YFbSpSYA@{_E-m
z1r7=IKhpfx+c-$D{PO_?%V4Pg(e5j|=F@q&L<)4iI%o%P^KpR}zgO`fZutdWLJiuN
zi&$R+Jue#lzH<0|X&&7^cNt!6Tg3yqlNo+9G2*^79Qxt+oq@HpuSC_3bl(|a{c{;!
z9AAM`zehLde$o;Sk7fqO!{GaMSXoy<&aXWTUN6*osf3MxJ5yRGBj{*P9{z2N{M!N<
zI~*B11V0~6oACM`NEPC|oY&`2`JmHTS-P1Zx}_kxnL8YrI|TW+If9I0>TqQ02xR;W
z3Q`va26X+e_o13c=>BGqeS99>Odj1q93GvF9-V<4Ab00MZ07H9<cHhL*Wt+55y;5D
z&5?<JTOe<TBX36_6aO|xX8vt~JROca9f8dJ+Z<W=w*_){IC6IcvhZ(nWaZx$$kpM<
z)e*?bzs-@2e_J4Dha+c4ARGTSM|S>gfgBx<936q|pAq+6fWi;t9!Ln7LEORK;m8hm
z2U~|D8^Rr|9geIBcd&FgvUCJ8Bg`Y@|JQw};RU{J73scjQ24N6xCdK|K>ZGOD%|f7
zx3VJK12PYHc!M>=Vj7|s7T#F>$-m8!gMV8fIGO@E__sN7@^1@-#1kj~Hb*XaJaO@F
zbL57{6F0&=ko){Vv(=|dv^+XbcyL}=!S2z`RHEk5dZ2^_l*~Q4xk2}Nuz{}1DA5Op
z1vBJYKv4QeQ}x)Vn-etG?b~|5rxSdJlp_b|>{t!Z(!1^u6%9}VWk95VkLEWP;JZFf
zm3YH8eu6IgD+Qmk>k7W<548Eyv-2Y8(gz)%&P$MU9YMF0fe#|(*8?4&JnI0z>mksx
zzQdp!{tm-s9r^W`_z{v5knHn8vCk58Y9xkz8kqK_fh^QOG81GW_`Y$lbJEak1fRNv
z)xS9H_w2j~@-oQ33UK>D7czn^xcTn>%eyzw?RUJb_4)xQJ|N*)5&-j@3+Sq~QfrX!
z92<Vv`SgaUD1b}{1!(6f(4JbK&Wng31$j=PimAjLeEKCgKtb9{_Jcx{UyrfsdFfMr
zJx3O>Q;-}1JAV+QUj<zfIX^+&7l`UU8)DrD4t<aV&CndU59Gi!kPDxcK1t)(bL2pG
z1tcaw4%9%GLWv&_P#%p%b)N?@?z{O86iN4AR<V_M+y&q2_?qqRjn_<fZ@}E@aTpw!
zn{I2~e0THY{g+h_N*~?M6aYI1C00ESL)U|Vu3p404Ot%&3_1+gz@zy$V~LBa;U&WZ
zzO4u9HD5==;={M|vS;%l#s(WEh7wM9{%tanE*&zA9?b_BJuMHEnD|&;uD|05w!qc!
z_UjuHd|MB=@^9m;lQKL24ll4q7MBhln4Z$N(T9=ZbD-@<FR!t>N9%PAw(#I`=ie?9
zndZ_d<A@R<w-Ety9ULCpIqRg6!-F-=rIQDyr}RxU%KfO_F)HZsp@BU<INZBsX1a9B
zG{S5*1x3eQgzY!e!12)ywjQ#+7#bg)JTOhf#K)-pSo6bxhrfTf%uSz8nS=P_-xo9f
zeL8tynuv*iI;MX-`Oy_#K51jmkKCV~`2|>Je&!csfu-&eV^Eg3g~$@ud|MBEcH|de
ztdj)gNCt3zU`5t~Gd~ix{}agmo1gdvSzw`y)&5Ty_9JUSwcn>ZMn%IDR6K|JwjQXf
z^klqXc;K}T{5&Ji&O@NsZ?Ix0;qpBAh{gG~j^J%ekLE*+9?b^@d@K)@2zpu`u7}hh
zu7;OhU%h+dGg5iu+j_w9wr1TcPsR(7^4f}_gyrS|6eCJs-Mw)b)Z}wvV8B{FYP?Rt
zRz7l|r%yXjWMGs};OGDmo-B1Th6lhg!VQX%gP=QO53+##=V^JM^jY-bv<ax;!QWTI
zz`y_r6K$~jk-~!)6ds?Q`SW=M`2{(VgM=RxBv-+eDkw-UfjdKx`p~!a062O;geOPc
zQ%}YVps?lq#4pJBiC@r@1Ie7yr=P*W;(*j14F);T032Z{zO4uN`=&q~2(rhKU!K9I
z^8&a&wPGky^*H!|)rawfN4JDWr=&-B1cygwB!@?Lgn&n9q<}}agM>$?qXg7G1yEFa
z`&wSE-wR31h6i5n;+JP|ysZh2!c2iWO;5%P6F`pTy?GK8gJ7~!0Lg&Thj(w>z44j_
zL`FkSUd0ig*vmWg_{3h{kW}8F=l7SO>wA&f2cWi;9JtTG=+W)O;nC^H;nD3R;L+(Q
z;L+^_4k1_2J=XUa7#JXZJ#c3R)(3+0Wng_Es`fegw>b*%Zwr*~aFp)|6yV?HD9FDp
zP_DyKt|Jg+yAc1jK-msQ*^WRV{%wxJ{M!O$Iviy>0)_dvIg0Ra3zY6~l<o)=;os&c
z%D*j8s>4yLBT$roo1+;2wm``aN6C&rG5&3i;{4kJB|01>Is(N(8PEZAm1l{xZ|lht
zG4RMzvV+3Q#B`+lI3TJJ?NOiZ5ETob&I6$1H9!Y@m+1MnUMkV_?GCc=O^#CVwY=%u
zd8?Gw$MRN*m=EZh5YNs7E}bDN1}`_=VPr^~@cFPW|N6roorhljN)up61NDD2Ji0kS
zhv}azVSQ0*1G-uKhz6qn4QZcycAhHnLTv(@!kWNH-4lJE&P$*!1f>7Kzs*NQ|HUnP
zu#py!^a*b79(Cm3#`WSLOakTn9@zby3gFqJ(;l7IeLK&1_3ALz3%+&&x%V)mNAqzG
z56iot`!&tMC(PY^5eizo+{y0I`mN+H_^{&Z9-#BSn-4RB&f#x94mw=P!}4zFS;RSV
zQ1_snX9c_O&!^iqbQ*Lt6mmfES-)NrM$pDF3-C#5La(DhBL$!n^%1A3z4GY%_~ImN
zq4D98K=92kpmXnEINL#o{Yrh1_K?9&yTd$94dv)z(BKZFJcAse{`>VZXnz37EVTV-
zC<b`^e*kGOqRrQ7Ao(|SDtZ3B30ruK;@@EB!S3JEDdhS0C1`0fXrVlce<ynl3jZRF
zXONy>_kr?jl@+%9x{vEcB1{4$zv9k6qLaxBUrSJ4#t2_#>p>B|c=C_xB=Y?0iM6~C
zb{OpbHJwPFe<QJ%7w&_@zvR_Ft)Mc2ocf2N{0gpLPnluMuiLm@Y=lV=nO{@;$%{|y
z`8C*laKtC>@~O0sJpW?PugNxp-M_89<oOqSeqB6B>i0pNU-eMi!~1<y^j=6AW6Q7m
zxn3~BB#6wfTe~sh(-B+yl*t2r8Z)?kiaozBHpZ8JF;DkIX<pK$eR{NuJpW?PubV9f
zyMM2ClILIS`Sr8?;P5Z5{OSnr-!Vb@cdwEAcR1@;CglFzYs~%~Y4s~we%%hruUY!o
z^6Pf47lAMdBJ(S22YK;{J->d|9~|+CyM7gIC(pmw^DDFIVE3<T8+rc4o?o5uwkPOU
z9uMmL3Yz{$j5l@rsOY@dtqskt(D9CjA9f{29lN<+EP_e!%Oj2N;_A;q_tKy9=)COP
zdDOS_9HM5Gd7Xh6j{~1x+kA}0gYmVe<zLWMRi8j(K%hG$Jz5WVb{;SB1&;yU^6C8f
z!d?fIhCRF4OFf|DHlCgArF%f9)`HCO>HO&dF$#P&&0j26RZZ~dX5HHiSzqMYdHnT2
z-3N~DUsp&U7R|r@hSc!y*`~qg-%v;&7R|r?;5G%N@q4$C68{o;|2d0C^Dz!j%ReQ0
z9^G=_leAvGXaIL&*+A!U-SlYIW-Pr7J>d#;`qgnre)4EO0&n?&*SnE4K8z*5a%<qo
zub<SR5(AfC`!%SMet8=xiBBB$D~06~_WU|umm2<+tsi{;#hzd9n^42Qx^<NJm(KYW
zy57~oqk9kdR`qVk#p~e7mTMlJr+qpPl}LIv|KuoD^=SUbQ7Z4#%kr0jfq~)0DIWob
z*0-g)pfzBiduSo^C!U=bj=QL6aDc9j1>K<T(fP@v^X3cJLyQcqZ%ZzFg05)<i8$_L
z0U5IPFe8IUuQv;X3zdbQ(Ef75VMYdG+$Z7L{8IqzK7mqs&(0s72OqG!(1tiq5AHlj
zc?ET!0Gj)j9t6AZ64V8qHyw9^yzqh-;yw-t7b**L--koQyH5e^J_VTjSYLE|gM$x;
z`xMaJ$BOAbkQZL$9s-A-fa6XO7tMVEAW2Hg<IjrFViyvA(D}M<t{1mp5(8Hr|5u_$
zeyy#dB)`(LJm#lL{nJ}H`235#JoX3oX(??#&8?uszjQ8-NgJQQ(tdK5!;xRLU=jnD
zU;X8&kzdc2Q4*i@%&+k()bQ`!(!u9n?D=)RHZ}bFwuBP@4(j|0+Ae??pYZ7RQPFs@
zND7)^!Ry-~^{Zz$*NZNMIQ7RTIEWgbm@iF4e1eR^J3b*>Oi6rFC%=Lmi98;Iy}z?w
zfg1kREgF3O#hzc^t5d_jwuO}Vm&p9eF(Bg;*z)TwG3@#E5JG&Q^6PtXYQ$%5J|*!<
z&;0sdh8q5@%^Q6F#hzd7iD^%OiaNaIac?dq{vFi$72AB>uM8fB)&u-g4uD1iAp5J1
zI`VJldhrlN0=|9{zTc3*dO4rYOQ0QidWia*A3Q%etB{A`MX4~fkbu<ZVEY<D5-~6d
zsC|w&@{3Qm?bB@X=8v$?4_+1q<rUC1(b(3T(r^9<w|~E8k>_9R^Mj8i2D^V*$@DMw
z`9WoH+hyS6cL>c7f_8*{=8tkw(Rp!{A0@wnWgPjVm|m=bNf5}d6pp`RpC6PL0HtAy
z$3N03DerOQR|@@$z5T5(N)7+6O&fgv#a^H16VrYHO|9as&-bQM;$I@`^MRQkL~Vb6
z;ummH(Rd-r1I??T{T7h=6||d+=>-E!0%?B{uKJb4^b2ZKA@?7#=hu85BGNC&D7^9c
zHkp$6q)vVXITG2w*z;?>AT|8^H)-(s7khr)4{lQsD33uwhc|wCDe^Co`ITDz<uK3z
zAfOWuJUUPFx3n`bFu-<wfzOR7HT-5{2WkdeIPgz7=Fxe}<G70oX!44ovqVM1aVH}K
z1B2rZ@KoQSm7uArU>1;S8)O-fO1QQcvsW@QfU4g#{`V)rm9xcX{wN<6n-@l$;B4;^
z9e3EquB07F4fALIC~uY*f(QkO^*A)j|4*^5Z^`GNMt*o3Klt*)SFGz>>UpW*-@kE#
z&%dl#{kva;8vf;_$iEcie*-es^PuMcCiMJY0L%Xd`0_t^D*ez>aQ^22<$nuU{s+mR
z<^QFO44?P~d{ivJ)xE(BD^_^E=a*-&u`B8M#4q5@@rhr6`Gp*^TmxuX0+sT+0NVKY
zSFHKHo`s0?05S@1eegGW;L|_Ik;wHuD^~yZb5g^<yo1ocqFD3$d1CrsprFGWzp_!3
z#4nNgT>#7YxC6QQUBjdEv`06mN9Q%r!Cp2V-9kG+6**|HzPhX7ffwrk_!ydhFqRm3
zbc=a(b3-e5L5L{-lmq<RK!a@>(Q$_-Ks16E34+hR+wuSZ|NpNa!q2xr%dZwL-Ahz<
zFfcHH?hIW4UIcU6qw}h7=W(CTbD%X!8$hdu^cnaW9Gm|z^0!Q9VqoBJs%B&W@tOEr
z<rx_mJev2YEC7`S{Cxr-Zs#Y@&R?FLpFQ~3U-vxth}G5bt>^dK9tR(>f({;2@NNCZ
z-*<t5fx)+1-N*77e;;Uhldt7t{{Alv3=D=RUk7>~e8TF{d|1Jg@r`G<h>AyN@B`28
z5ETxO&fpgyhJZ(B@COh>!lN_zhez{4Mo-Ig{4JoPD}1|E&ih*4;qL+Y1#J3!(0LKP
zA|}4APki`29(gqXXDpfL(fYscxDWsO=dOkaK(=}HhNv=t=L7w^d6@h<d6@mWeV91>
zI(?WqKr8_eO8~@@0I?)In-3`XS{^FB2(sLV@v^7oxzZL7<{T9T&*r0yK9+010m9!Z
z@c;jR!`q;f+c-Qr559Q+kB_1A254Lqw1CSo#xd40&N2QlT>kt&J_e6&)|4Po29I9R
zP98x9&(4p&oey?{Q$sh$3%>t+46paX1H5jrN9Qk}?m1xF{Cictd+@Kn=F^+^AAIqu
zi;9Lv=S7dsUmgb^vVwvi)PM7B{pQ>GtKQ?~X3zl-@(do9$2|G{j)H=v)ERVu1}NY?
z7+?5wbNF<6Kk(`H0MRdex;+GZI=w$YPSJ4w;n{qM!`JdkNr7iKlSk`;${mIWKt`18
z1%>P*5B~MXT@6oqbo!_$fX!rl0XxsctDA?ztCNS@tJ{Zz!>iMWn*+oW0I>u>EC~=x
z!n66Hf~V!h(u*K_JQy#7W^NUHEw7YL@N7Q7=)ri_*YYrbs{v@Ea<_|$#>*L?;uDb!
zJOBOv@7ej+r@IFnGM=5keE8SD^Y4}U4oQzsJP$r)g{-dvhsTe)NSOOPy9GR2FI95C
zj)2H}XnyjryjJ%E<h#-!P$)tI=#@t|mq(}f1CMSm4v$Xn7arYS0v_N13IeA}&*lRh
zzLtke*LyY}Vf0~q>udS2bn?p&pkj~lQ{_ev#!nUBUav}<01B_mpqv5<E*DU6J!17>
zd<D<19^EWl9-S=Q9^Ecn93Gu6+#Dd50Ei_3Vo88l5+302I#qhnquWJA!H4nk%bNfH
z|AXS&qxDh=EB`j84o1jH78v|)CJ#%-U7%8ee=4XT;rBU&e4ZHSs1SVej{MsgJUcIR
z9(pOI0y@tE)O}I#=)COHdB|}G7Xt&si!42U29Hi=Py#uk06irI(O<w+Z-rOABYeEm
z@U};{u4D*!4BNBwj7R4+pU&g;+^;P?K&MVv-Y+rm>}I*+(am!Yl)ucuCnvU^^yp-{
z2Rfocld<%=N4FyfNHORrM9cf77m&`TK!ks@D+8lP=Zn{%Ep{#p47kfrNFnIac@A8D
z9`oru?bE$R1yl~f%hBh*_(0_*qetgK{uWSQjlYQ#UX+3|q;Kng{=QY9607sJXXi~<
z!%IH=>+gGhzv<ihmcOqNTxhEKSU%?OTLNNRKIHG84JtG*z1D_~mpbupb5Uggor=-n
z_8)Xqji=?+5^vvbm21A1XKD(4EFah9c=oc$K#Ic$pk!Tg8k`70#i8K=PsTT{{M%Sq
zTsm0TKnDeRSROBZ2QtTl@t>#V)zYn=&4(C$81MR8UgvL3gBEX~lS_nu;V9cclHY!U
z3$|`waKW~L9aOO0L@wA&fAKNAKH%H>ziz!p=MVp0nRh<D$^Sk0*B^ET9ijKuxASAY
z+Ut_E2_BZ0J^B5vfZScG%D*iHRMj72><Ihs*?f@0*YajbfM>TLC<k9NyaZBIavS71
zP>FQi19BY8CBsXejIUt%-I0GAi%<uP7}$%J*Gu1n%<*9S2g*nqzLqyjH$Y09qrR5M
z`CE(r|NsAz>;M1%;D}=U4=QGU`}gv^gT&Nr(D`t0eLFwYS;Nft>}CL!kKC`VVCBgT
z56i>Q^2CULn+q!}vLGeKiPE!(5H8*LaxSQ3W4uv$-h=T*#kbcdK)$&ODqjsR`Shl+
zGJxDKg6w_|#(%H3Ao3SQ>DBzl@J+AD-|?hZx9{NedfN+}UKv<1(rfGY(ew(g;i#Qn
zUwZ%j{~z~wGE#e$i1N1lD^mKs&j@O|O2f<Bqo5KLRNn4^m$yE>EcT!R*VXV6sLW-&
z4K8+jKnlAd#qN3#8&vErgA}`(PW;<lQbAdmDXr7(AE*=o6}U0b0++w14%D``d|X$F
zUg#bJ<>d2_LKoaF_UlbaWtiZ|zg@&7ty9DeQTTR;fU5LkP_s*yAj${+)@Y;>c;Xj4
zDZ1nfI7M@MfK#*{6Gn>O`~^8hd-RIfgGymg2@EQU!3|0u6%EhMOCF2|d|Ti8Kni4(
z@>q?3dq^lWEW-YIG#}*f0Tsv|kOKKCv_QTE@;JOeR`BWd31u+61S>Bc`M0wKrggG}
zfxPQsc^y>w9OUp}yap<e6?`nQ6v&{)p~lN^|DdJvTX5qKTq^tYs(|A2wyWVKU&h<u
z_C46?pXzL2_JP_rtp_T(Ut41-pN;vqySPF<1ddz|P^0t=A_7V`ysU#3(B~ip^l^~y
zzy&loQhj<|Tp0`xAeG1b+eI9(#qYD%^Fi%3ipuNuPe|$gEjYbP!qfX<P|^jZ_g%>8
zeJ`lvhDh_C2Ol$m6MZX4H8jzK+AzMLL=Wmq8D4s=?9}bD6cj8hoo;_X@dQfp;m{;s
zQwwTiRG=sKGoWy}jGEk+GNes#>=tS16lsH{_75ItseL6Pu=!h)kW%~Nk9bmh+edI}
zmv#lGc8C8044$1R?Tw=!(Na4&9B`%hgAbTs=>?pAKGti#E{CQUr1pqPcgR#ou!Q|V
zPyN@Sss9cr98gmKR0hLKNa>@SWnw4GG*GC5QvV0AIk-}PKDYzqqoVQh87%eRMM?c&
zU-|H_2ju`z)Pmb5KAoTHtYH3ur+-VRe>9QXC*3Zs5D$Ul8JzmhAtI!7)5|<)>c0R<
z{U^cwnJb|72`u@yG8i6k>=tRj63NeAubMzndY}G&<fQk_@9?DeY45=4UE2wq-UI$%
zr1z`uM$<c}q+=M;>3#Vdr1bs{T)s=e%l9Lo5*t*$??x`)L4#`yDCIjdxO{H|sfL#C
zD?w~f`3@SzGraU##jD%pDJb7_cyzk`02M_<6!6HMNO0cw>rHveFu}81<cLS7$T3&}
z{~m7vpNLezA9{@^!7qIcPViRt-~=E46C=Std5xCf!2yB0fM<sGpP}Wu_Uj60d5BcL
zt9f*XT!n^97--xP+`jQA*uJ@n)V}fTX1VCm$#M-8s-Ob?J$eDZ5xKvaN2q`Y`wCIO
zGfx1!pXm0DN4LvSsE5E24KCqP+c&w;5*}y!<|s=0#<N@G0Jivk_Id%h{q^$qAC&g}
z%h#xUit2;*mq__zxVL{^;K?3sFTmMD+6J6G9KK;>kE1WpvIn@OfIEAPwtqaD4}o*X
zplbg-8#(EH^HV(OecDrSde^oDr}u!*80r1$)6w)k4B9`Bk<$CHZ~r{Pli-&=0w;JY
zGjM{B|A3L;pFBcK@ZgpL?gD<a{R3*~f=hUswtpyU-z<NCl>UePc;><Tcrw6}```><
zX$;N)ac?m)z~lR98DMlgvvdH)GhcF3aXf$dU8MB?5ZwQjfcJk7fqJo^{_jrY{x7&)
zi_-svjBkQY^Y?}Jf0u)Fg8IMnK!f@RUaNn0;unC9aDL_&1dV-xuID;h66D*hatt(&
zS^*m4EcWabfzG2smX&}f=OAO8m;8EDmNM|mGl1@4VVUxoUl1{-_XgA#_F+8cX?e7C
z9bz<%zcm@D_j}|Hp2WZW4mk1K7=ROh;wy~A|LhK0;s*x<?$VzLKHm-QKYpy&eVvWj
z|JC@+FW>?h;e-YYWQ5-V+5^4}9pk(KALI1t^#KiUf&*b9dLV#@^+6;02avnG)$lIw
zN7$I=3-FlcFaKVacRsx`V6XV_ufObSc+&IWBT#gLMl@}p?uD#J;ePD~<s*-0I)OX@
z8PSA#0Mw?xP<qO<`5>bY<5geF^Q9YJR{s0{A08eaj5jI|Lk2hZfX3%RUONFA-}LEC
z0S#?}z19Nq8hi}<jSu6!*Gr(|2^5w0+i#Ja-oe#8N_vNk_ux(MpFrsyGUD@zUl24B
zKu&sp3QF&wogpk&K=&`fhd78z?^kZ(N$=Zlg44T?E;zjxKF3J!-)^F%cW^M^PVda{
z_{E#vK`UY*13u7TAtJql27ADPa1lKa$V~5GuOQMpC_0Hw?;sCA26&(zpeVhAMtZ<r
zI|A|=d`ORa>HYY1r1U=A+xL&I;YsmFuYps1lomL}*FV8X@hsO#O!3h22%6qU$2Y-C
zm`XRir1JPC?(%*MWGxtUeb{jy(30OhD&Y0C=dVE0J%0;3czvxNyis!rv?Ld?un{ze
z>(O}&yuS7}Xw@L-N;dfVS{BdFi{RC@plw6o)wPfL`!<0aH;?)IL8JVJCtquO9()4Y
zTqxjlJ4cn_b{%Mj5ww1`Bow}OwjR1>p$ff$a|BfTf!8cR*3Ghj*UdWJ)?sqGZNui-
zd_VxSC>AuN&FI5;4YVkBwGZQ2)FrX76$=MSz)NE9T*i?Lpz?bzgEK;)IyfVgJ;cZe
zzb_M95_{RFHyd+FEQ`m%M=TS->py?h>%K07wihf9!`H)VcpQ8H4yxNZte}trEk*?`
zdi91bdc6!<)A*mU1m4~OFM0*(L9BOmx~;?EblZl{v-zL^Xz{>%kRcw7*FcL|cks(I
zK$<>~^{fTprVnU6>uu1WJ0jZ8fEz%6e7akp>sf#L@UMUD-z)On^WZ}kSHs(&IEA?1
zxAmJ(=g&Gj#QZLJH5^iV=$41&W$5}dCr}W0G#?YVog)hJAZRYa)AAIkJ#?7Shw-Ve
z<&DyHFa1#4L$^Tfp<5N-UZb>!uDcq(1)IkB%IUU_meXw;J<sN&0=||nOW*r2o+F|?
zgeQNjzX;18>frq01<xPvQ1i!q5Epm;0L@EjfO80FB?BynoPp&KQ0_83`Pv8+nxIhm
z?8Kk%qsqW9=m*avS@29U4U$Rt`+7m$4YZyBcp3C*&}s+djN;pQWdeA8d3OkCZ8;B{
zUuOs#2PE4ZDSZlAOa9Ea^ARZLOam<^*FeoXj?fMQG;b`pfIsgvTma`CQ5A6BvATzm
zclKYPB=3OdbD;Uh09*dihUK5n{P{kt;BW+`eoz+jfM%f!&@6NnRI-4UMWAFM7X}7U
z9Pn^B@eA_6v(OumA+RijJ^x%s%|9nd&OeT%<sXm-MZq3~WufDq&G0O=`lUN03%M{b
zcraq-pVOd{9Fc#(Ue*G68J>mSK(mko18n{Ckp_NE6BT~V8WjN-eoYq@1s8rz9~A=^
ze$5aS2N!<L7?l7Qe$5n>1Q&kI9F+o}?kOq{Knb<^7k7QGi*=963kC*;(qzZxpWG$Z
zj?F)LO2a|R<!^v8P<M;U4-kFu6|?8Tm&_gqUod+%|Kct;_34#WxFf*epDZ%jm+`XW
z|Hq*FLwi)vG%<M|e97c-@C6e{Q<<IN0e%e=6@Cq{OEthQ)d0Ix1ME@_uuC<-F4f3U
zDe!21(*W5WaTwI!^68bmdmGtGzh0TMppk6QqH6FilFnP6jK4nd3y6c7rc%C)w?MQK
zl-7dMMo`)cM7#0}FhOZ9C@tj6cnfq@sVl#L)F*d-0hLqyeS)CPEWI*ULALqy$^`lJ
zs!Rff(FX<w(2m)Y9-UV`I<JG)o%f1JdK`Sf>~ZiZi^sv|teyuSvv?eQ#s(@!3@?4+
z7hnX<_I`5Z7ts2|A9?7L3xDM6Py7)FKRNP89R1|NFQB6d5_<#TyYdU@Xo2`|A$*X$
zC5ZnH!UxG)f%xwsd^dgp9m!9w{E;spe0P2U9Vrn1C4>*sZwTVQg7885jXW7|frMT|
zgg{0pdNAGu2|-=q$S=s~$#~Gy@&bRW6?iWJs0Ycw0N!8pQVX7*5z(<l1s)xrKJg2P
zfuez&=zvCp5GWdCPSy2!K%>B;R|m9YlL55f1r!Ayy(~eXP0O%2;F0t=_#71Otl(nj
z;3GCy!%GuDp${5k0foLIEc744LjMRT^i{y2`vepeM?lIT{HGAU3%`JhAt<z;LHMpP
z{&NT)B+m#6w+9eDNFL082;qa|1))Lv2qFYhBIpST?Z*%yM}9$OPsZ22pwRXLtudea
z543&5g@FMPzIzbiOIC7+hAS5+Tt!at_Zfl8NJ_#MT>c}6uOuvdZ^Od(FerRwz~Orb
z<kQ2T@P+X2LijHH0y5z6y$9jD!ua<ge2_diJa0hwAbCb;;N64>ft0|47?k-V4u3)p
z&nQrMy8guoPjb^MG#r^g;mC7}zwZ@j*B>+-!No-P6cteVL{FQb@&S@QLFI$tB}jV>
z6n?PMK@b*xmto-tDk}s;z~OfV<k>@@@PqKLLijHH0wUn>y9VLA!uZ!Ad^dgp5lLwJ
zy8sb#2MIxg@FGOWkzbI>lkpHZw`YOEOY{#$c#)d^K;h)bFJJ`<CzezEeTRPk{|^cu
zk6xKcpy~(_MpwaQs0z5C_3E{`3o39C<>@n4kAshyL1E@<coLeQ4>E!h7SBakfSrZ~
z*g>#3xHvrn@*0E>4#2YrJ~+V6A^4J@41ONMcjFh}k@R7F2+GqZAVSd4@wGfr+VJxC
zumArMnG!7#$$<(zY;_NMU~K*M|Gx*gPC*Y0P=(^rs{;-UNFaa`&0}VdgU>(}3$v@?
zNl=;rjaYu-7Z3pj!QoH*kypSWz#nl4Bxw1GKl17)C<l})ufaHmpZFuMgE>y1RN%n~
zsw5&WfJKnJIrpW=FHiz-VDRe|L91>rdouq1#4jKZ@~W~g<7H^g>Bujj4H7Z}UD|GQ
ziofsDPe^>j;@YG08YD|x_UN@i^4>ER&x0WEJ!VCTUtE3z`2gZKun#`*N5VZP>B0CD
z?mr~otbXbC6Fj5~YJYV@q73FQ-_FaPjGsU83&<h-p$zhe7RVnar}+E0F#K^D?2ld(
zBu_jBdxDs_0YwLr`#l&x!o7gx<Q*?3{{Te*g9p^TzO4uRdPUBG913!s63BHrr}+DF
ze*FIr3t^D6JUcJLE6jrrVA%$-z8HVn0S76lw1A}_Bqtqx$?)U<e<b&S-QvVApmL7C
z@9B3`XZS!1L{JKLH9U#Kejmo0pZFtDlP{8umtXdM2iXWMd0G#ET6z3^m1uT(9DKwK
zvj<*2crb!;#vyR7Kr-^dOY868{0r)}Ap#fFhWzxIUqB2roDXWWfM`%Y2GO84B!~vJ
zAwe{#4fz?`h6K@|HYA9Kwjn`Gsn4J`WEX$m*>B){J{4S~^_m318ZV%z^60$k)2kxv
z(Rtmc7u0xpzyxVPK4XS7BA+n38eaO$FTe<DzkKG8JOnaX^E0UR_?bWA;Ac?l@iVA(
zcM&A^2Eqrm?!f%F5I#sAtmhqs50VG--$VEydBe}3)+2-uk_Yo&LiiwgOOX642p=R5
z=D+r2ya^Ekw;n-C-gv--AocHIaC-*SdVG2GD=0NX+B49ghsG)>=zo3Y7Z3*pEjdB&
z+j;;LFhZapm+9i~i~0%*auaBf%b*82B)APd4#I*PRQ5b)bp>rf0rfZ0!dnp(wvS=q
zeFPNVD&X*a0`mM3kj)VOQwSf_-UEm4GYB8l*aP#QL--(hNl;)tfbc=`VE#i0A0!VB
z-$x#dA0a{@C19b)o-iTg@CCOQQ@>z@FQlCF1%)qJNgEojT%d3j>EiEW`hqW9uY*%F
z4>Vk1Rn}8bxS}UvNl=j9h6U+iP>{-igY*u_zlT9V3gO>{@Ll)?WGq2??tOOTkATR7
z`S&4w7k&X5a1h@343`J<Z$iThVudCs)NesU_3&rpAOtrNl|KLfpEkj-SBAp$2@N+U
zP`L4Q@%Nqjgg4xLdQk%nOP&`5dHymizz%@|OavTYS3n*H7Yh*nRR|x{CIko2H3%Qn
zCIs`ZL--(hZ~$F^h6cn4u+T+lm>oh1AaI+I@zekR6od~bTtMwXP`I#k@%L@|hzJ)@
zyAZh+1NG^8WyHLCb>@OgPH<*@&H`#EfX)>-_!zz(6_U6PGJ?xT7k&YriJ-tb4GXM;
zpupk*2i6&o=OKJ>hCGYlg9GOrf)7ri=OKJ>dk~a#PCx?-RPcgZ%aHcq>kr8F30k2h
z4=U8K)g$PEvGfBXFu?6X)J}v?uZ$R^#CpsG>g9r`zCnS&faL$fpZNtuCVu9RyaM(;
zf5ah>z{St}kyk%MIg+3GBd@_YmY?|}uY)<@YX7q%e<V0TfYc&YnR8!qd;k?Lkp914
zuLxTH0JR4{^9z8zif9jlJgyBQj6OT_3)pn=_Z@nV-X4Utqaa1~!3RvBElM5-AG5d`
zo`j9Rk>EdwFOWP4^6hm{tfBd6^-Ht&i1r{P%3%Hiw+DZN`~ztZg1n#%BD6sMFzMp&
z`}GdZAH6bQ4}hz5s3*W40H2RUj{8B?D4LUZylj34iUbDuuot*J*bj0j$aP8}*XeZe
z_r-u*hm?4HpsoX@9#H$5IQRH4-UKHMq-1dHCF8sQ|0f{X54IcB{_E%Od-@im{Ra*d
zsI`dpA6EMz)*VE*^76~Rw<zsDP&0wQuM*8JkAshxVD?NvGXIbV<3(^zK=Q?dm)39p
zBkwQvXnv#7{8PMM#-o>2;iLeANAgLJZk7`stp`fdz(+<jAJI76{8N&@1vHV?{8OqV
zxA|vsNk-$({|pQa^#;v9>+5YjdRdpO7Xj<#-^aqy{6oB6)1z1P!U+Kek8YMjuQww6
z@6pX_d0UX7n}HRi-|}Fcy+=3eZXWOmy~=TrdX5(_cJMJ69(dgX8vpd@<<%4uV0ba5
zj0tp*K#Bfw2L;e+FvlDulR<X@9`@*FeeqBbY<D+<M|aB!P%HhV4S2}Tg@M8Fz)R5i
z)bRBV;PW<iYJd*rNZif`GSZ{-a7ish#2+G3QtHtyy7;ajgGVp#o_+uRdmMKL-FC&`
zaokw~TpS;Ffbtz6{7zwyPSEKm93Gt>9LJp%_!t-%jytP>+<Dvq!gB!gJUUsk-++z-
zk#%{;&j1?x2OS9lIiu(^=-#rc+xQqD+$WIn5!iV5n*fh)+4+J33?7~5J(_o0fXwD^
znP<wtuu~l585fAtJvtBbx6CkM06AT-<lle8OD`tvfO_*7e@h=orkgcf5HuC?0d#y~
zcL&I*7f-kIF|;1==w{~ckTL}wY4n28qxFDCCo_Lb6-ZCB9wUEC3y9S%D+zK1+zE9i
z3=BI(K~6Zh4QkP0{uWV?(q7(m5GU{>IYAm^d^hVA0dyxMA)K(s7}W{oAk)B3hy}5_
zWv2-UFd#yq0u%~jASc)%IbjmWkY3*3#o$orfrZa8{+1sgnQqoV3@6;*1`mZVAd8w2
zp-=*HHrNSKAXc}mF(0xMmV%rBj)>h`5uv~jvZ$9g;se+ToJdai3NpT%^&KyID8wL~
zpa`-E$q7LqJzytTf>_<M8+ehOFahKQa70)jIibf0oEA*e!A@v{h0ihmmTMr#b+cw;
zIN|12cqs6pIiUc|2c?Bl5UX2O7sUx{Ku!Qh#MUi{P~e0(p(zdQ1ZE^BFoO+YeZhks
z3SkH*Xo1uqg~DtwALN845UX4E6c=(R90NH491%uHPG~a(heG{3uoD_!;d6|?MILMj
zYbzJJ6E1Iohk_eO4U!W&z<iJsdO@siS$7mC+yglQ91-g`BSL{0;)Fk`U?=>AIqn#L
zOE}mNRwfK51R$Ic2U3INgbQFk$O+p)tZvyOoXDZ@8{`CVMCc$np}_zg3Z4)rR3SMb
z3~UH%Jtul7oZSo$g=&x*Bq!_z^FdAkdDx>{Hjy3K3BqQuqG{zOL@4~#2RmWe8*nIm
zhdJ&Te@iXMxNcS%c629rA)L?xQiJ3K1~X7O0dm4~kW9DiJvL+~7=oMtjtDg*CsaY4
za5x3*gc2ktw1Ev_oymsogyWmwp|BdH2FVGZ!F-St<Uo$;mW@Vn!ee+uEZ&F+h3|Uc
zP!NDP;Umm($M{>U!G^GkVK~7B;e_{KD`7=bDVImLGlxg#P0%S$&3cR=z8i-}=SL8~
zTlNhza)?Yahee7Al5;X3&N=uB93n|b&dC5-)y=w`89hX{ZiI)(3Ug2-z?{S1(h25+
zLZkr1>Xyw!ae^tx3E)VXxB(F&Pj$f|QkM*N!hM+Ij`6poS}=glgj2zAf)T<A{2(<*
zk@5j#F}S3>4q|o7K4U@-g*hN6fO7{Qk`t03PB@(ec0vr269T}7ur6dm4~6v`;Gysf
z6mf7TfFc1;q?9utJ7*>+nSzU~`t^tqxvT>YkvlKI&N&Nn=rR75Vt;Um7%`wbM*-m+
zS&$lHo%7;9=)_Z4n_`b2tU~{=4&fXZh;wuyp<{>SoB}_va~A*SXYlMqZc|KL4-XwF
zkQ!p06N%!SoxThVJHe5ah~%8D+ThU1O9Y3`dRVv}<8R6J1v^Is!#PX{=ZJ&U5bK;*
ze~?3Gn-44pU0RC>9W{t^?mq)NM*+z>Sw3LrEd7HXI>qbYp(6rPL#%V6QJk~c8x~p4
zNY0tA1rD7H31H_;goWEN{+4uauye#PobzNY+&O|EHN-mS%x~n-+293>tSxI0p~C@j
zjv&N2Oi0d2@d7)i{Wp5(gd&{72U0_<b7FrYJ7=vYEV5LQoKvX@4xL9&z@bwN3%6tZ
zEs36B=SciSch0dj@X+A~sUg-m=YAkNXO#ymvZk#@gw87suycyz!OnRCbLcVtmN*Zv
zb2@*ZJI5U191f5gVx41;;+*B~u*hOZa!xeFIa}hu&Iv_wPP9ANIlsQ6J7>jec<8W#
z)DY{O3ty2#XNemuvMN>~Lg$P+ICP#q0z2mz%%R8lTO!=R&guS&?i@*kbC^JCh;@!5
zigOma!XoSCN`!N4A<hwlgpN6qb3$Fg&iV5N-8o&W;Gy#$GyzAfb2fcJ4xM=}u*ix+
za?Uz6aOi}`f<tEoEZmOqw*-N#>SoQwaL(_QaOeDSMy|OD)LG7-kexHz85UWmS0F-1
z9^#yg2Vmz&B00w&WK}oozmMpllY?;1PbU(bv*jbQb7nZfBFhHJITKXDp%V#-tS(r%
z9pi8D0a?|}nvda}yDQ+K^UaY2=cuAMXR0GCveqs~gbpLbIkO;<^&95UWBe_iAgj7r
zAACR$9Y2I~K0A=$oNe!rLuZl$EVAT~oKvI%4jt+H;K<5Ba*i9ws&3Z8cj(U9zZ@Pq
zAM8nRjyj5S`t4zn)xQi8I**mX&f$p$JLfLUp~v`JoIzG~vp#x@?i>SzbKcsK;G7w6
zkwd4)4i;GqNX`j?IL9{%>>NKN=Qx0@>ShhbaL&SI@X&c>OM-JWUn4uG(-sz4g-a2k
zb5sc&I&~&s=j?|$^ca7OEy${F)+evfLq`bVoaZ(qIA_)?WaqTmz#{9>5`=TiAkMje
z3+x;NB<EOxtm<YB#c)pZQh4Y*u_nPe+$hdzwuVJkFp_hYD}qCZ0pgs6uy8xZ-(n83
zs+;xLOZ3qBvIOp&hgKvwXU=ov&}p!OMb?qUh|rOMI7cz$KWO|-2+27nAgj7r!=Ix&
zCl%qGdzK_PhZn^;wU)5RGDUJurvf;1m?FTD)eH-_WBe_KAgj7rPdr0+&b7tx(7BD$
zw<1tU)ICEEohl1hWG!2S2%TT@VCOi8gPrpQ=FnsOEqWlUx>+qToa2sg&J9psjMyra
z{|T~l%0b;ea6d~N$vN2&=X?nSM^-A5bF@KLb+ev&j2=2W7QsX3Dk<H*hR4XxDFJo+
zz#ZX^g^19(BL@zhrD5RExdwCSG5!_}kX7BR))>ywL^$UXsJ~8Z=zM&H?3_aQNX5?u
z2<P}hobxOc>>PI_=ct0L>SkT@2t9OWErf^8dC)i|vCe6Ffb5(+(6BN%va*nzvriTr
zI^s9L&e;JAw`2S*N+7GcS#2MnJBJ(LoHL*iPhy?(`9899vW;Om>-Ky^=;%Y7lK}}G
zO(f^YgRJUiU3VYdIW-I5p>q;6E=sI(Qc#?eVFb%rK1j}4AOjAa&Jb|u%z}m6G5!`A
zkX7BR@)*u}J0I?xW1s;_Vx9B#4sz(E8p4Xfz4H*EBM5QMEkAJ1;zn|gB*?06)(v;i
zLnjX5oWr2ON@AUphT@zg16X9~Avvc>8XP*iA)!+P3%6tZEn*<6x>*%5oO6C2Jai6#
zMh%H|&h^{Kp%bqUi>&!`5ux*03hbOe!QjYx3v=i({uW`7Ro$$UZli~e1Hw6bK|^-L
zIw#{MvU6heV38$&<eU_UbJqHRBP$NcIRYT7x>=QPqC02fTzKg00*##!>ztc6kew5$
z3yZAAIf&4?DhUpqI7sN6hdJ~Ze+w_js&3XPH_)A<gmBJw&|np@&hbKVPM8iXvOdj5
zIL8g*ocTfE$Z|k(4j0I(ZdO(d=S-dh51lQb(IH};bNecC=mcxSA}blmIol<`q4VJy
z*f|?v;dYF_g&ky7H|w;k=%K@caLz{1a161|@j-D;fEFyWuFOJ&jt0azijdGzLUIlZ
z$f|Bub`0l~&W4B1I?!+ovCi3h1vzwlHDQtEisYP`;^5G63IvDFWLUTz<8NUES=G&2
zaRohep3Q<gXEkX2gIMSIT|#z_mj*1dw#`I@4j05Z&DX)sVL@`vKhR)8H!J5QbmxR4
zoU;O?hFIt9zliJ{cXe1~sUtb3S_~XIQy_!=rLb^2#^3TA)O+t{t-6TroD(zQp|cdE
zhFIqqpg6}x4Hj85W*|c6jVRbTUm-Jd&tMJ(&C-Ip%iXN6FQ7Ze65*UhAT`7~NAVkS
z=s2pvB8wBrIk6Duw7G$c!Ehw!d<AuvyIJpG3^%Qs0S}$|AT`7~XA;VAlbs4IvZ|&d
zLg$<aICPG?fSq#!=FnsOEuTRB({5H@4ChEAoHGZchFIq?qd3P}85UWury-nU4{;8M
zGuSznNX~f=>JWCb?!y>v>X{A?otYpt#5!jR%5al~5-hS}kestY7#uo3HNnnV1q-)h
z{4H-lJ+N+8|4-;?=kGMQbEbjR5bGRP6z7;K!XoSJR7B_~LY!lz0d|fwl5<{ydSKnG
z2QY@4@(|9M3{pd^bIMSLn~W4-k!6SEoJm69(5Y4fJEsR0ZpZjro`JeN-K>Tf&bdDo
z9y$|1YKV2ta+IM;eR)`9t)GGj9cGAg?(l-0^B3mOWBe_TL4AyF)+CIy6M%3|FGvls
z&XGWIj*c8GvJ{Y<Qz8fsomw8SbMla!^8nPS?`FOH89nVBoB|J>E|3~xozwXlx!lo|
zg+<oH$%xQ-Dgbtl95>iG_hAk_#@})m)QawAb-{3s5yCm`AT`7~XV*z&=cviRB8v&h
zIbjgz^q&IPSpi7Sxdm!Pce9qBL=T<Cli{J$0#ZY)bF@*Mqbv=Jtl~+C&^gWz4xI)M
zuyYQ=9D0nu<vOU@+Rggx1iEuX5YA}?sUg-mb50<Kj)D{{vYt#tIL89woP+LQ=NKV5
z=L)Eu*v%S_;hfe<@X+Z4wFiiGj_xsJ=je*VA}bWhIV<_Vp)=_O*g1<~;dYF_<sqo9
z?`C~*6g_mlO@uqA8>EI<=gd2b>>MpISY#cWfCwEah;t6Rft@3Q<eYn;%C(y{62m#^
z2<LQw)DY_&eiY}Zi^3wy9LYJ|yx`Dz;tF<7D=gfO@wa4xeBRA^>Ii!1+?W6l9bu3f
zqMY+$(RI*emHZu2U<*Yjw}~(q9yrFrBmp|^%)=J68n*O<M>lKQ3lWB6tee_I7#NPR
zo@*0fU_8dUyiJ6G=@{#=HW3EqW32PrL>O2+I$0OI1T7V0-3c1w>twz36wG`5n4jSo
z>)bXG2G(P&Wo;r1Y{yuqwTUor9%IdK6Jg*w#@f;*!oYrvHMUKJf#Vo!HAF51BA3`E
z!XSQ(HM&iNf%_P1P@4z?&oNfNHW3EiW2|azA`E=TSY_Kp82FE|O16nG2pnUTY7=1)
zJjN>CCc+?ej8&*jghBWiD^HsUgUB(~KdmARqQ_W8+e8?|j<GU<lz4QqW<3PEvl%pC
z(aAdJE||9!)FbX>JqPNEcCtRd4i;p%2BsuIZTe1DBT!qqlhykISTN-rn5sPkrly?&
zQ|m#Qvy=4%C{uK@I)YbHvPOXhh&x$@L30e9tY?mZRX#n$&+tN_ACW3sxWUtNy_>+R
zI<L(UU~n}&;J6cXAM7rB&~i-|6$1tctpQqF3BDj2%;<Dcv3SAT#Rs~QaM>Kt0?cEc
zod-aRHCOcUF?e7sxnZ@0*ike`fB|BGBY4yJt|W-@1`YrJ|3B`cq5(Q)2F;pfonUKR
zP^@vpZq1_2V6Si^S;NG@z_7~+Y7NXcpmnxr*4RU=c{Cf@H@AAR`sOvnH%n%Nd;?nc
z>bQd$WK9Olng)n({?{`wfUN;J!UG&=H#)$+X+*K67`rth5Z~A$S;GRd#sg*zgx2`~
zAH$kLh&2i**6?7rrgkGZ(5}q_`37`vxZ@61kTsbQ<3UNF0Teg?|NpNC`v&9)h;O(c
z)*P6H9B4~>Faxdm<o_4C-JqjKMEM|rHv!2yHiS(KAcHlKtO-%E*yRaY$2zYa9C8UL
zc3EPv%L8=SBPgaDUYr6Y(Vd`+48e}?JoaKo7axO9x9Z6aU_VQM4J%PGaNOwtz9pR#
z<naOq1|(;IvV%`&ii*Vx8HfvB&qVg^c95^o6FkVfW+1z}b?qUcyKp8bbRm|2u0Y%s
zfYr|+%RD-BR4iVsZv%U`8O1U$Y?gJi-d+#(O)S_BNDQ)rJd%U316K@sK&;V1vF0(z
z>1ciec_|x|N4iC0Ac1#o2FObg>p<>44lORQ#h?!;2Jf_jy>xg6a`=^Fu?r~%IY3sT
z#Nan@n&XWHn}Qy7g`g97K#_%T1juPG5+PRmfi=O(sy`sJ(Y)ya@@F-~inr529z=?>
zKybpyQL(`ED%h6aEnp9RoQ~|lY1nM(W_`XE9B1djc0kGy(9r&_RFECVT~ricWroI!
zB@km*p%@D;uh1Re&6)r)wgPM{ByPAtNg)kpEG+YCyzqq>8-Zf%3y{|_jeWTW>{>;z
zv5*kq0U4VDGZy53aG1aN)(j2=b`)bLVmH<Z;@VTwKmiSE4LI)L1sR);Y3zK6vD>F1
zhpiQMV_&ZZyS5l?EX1{-?FYNuFpc$q7@Lh^>|;<y#|(rPh_NzYV<E2P2f5Y-)7Xzq
z;6RW@F}4T0vAz&vk4^;z0t4t6s~w>9u*)6O*jW%`&rC%Q1XJwBib0|*4{R(X5ClQ4
z^~W^U8DeZBim~@VB?D$4@I#Chp9*R%oOIkF1Tr%iW+tq4pz-2;BRB+1P|WPYZl*QF
z%)?WlW(tGM427AANU^gaW<H;S?0qxrX0k)f%!ipN0x~lUW+uX&?hrF)qnP;!R9v9@
z9Z{_mgK`c^p_B*`=@#9z5}fc3P6jy;scZsGX@YYHxMG9k6;Q?I3n~_mHh@D)4#fot
z_+9W3lx$I4a33VnE!waO>;ijq7l2laVsk+*$OX<27c2#9f|ZW<Kwd%%1D|eId9W8n
zo55;tdNwmKzSz<Ns#95~LSzb&WM)BRv>`HaNHPr&nU5<#&K31Rl1YQeOo!;PLXz=;
z$jE}dD5{4fV+4^YhM1;;BqITl;e^NtBgy=02D@4wBEyL!^8_MubUD~<KPG`96XMfT
zpg`^weLo4b%=m^!=g${AKqB4D9=!qo4G(y<Uh?P^E;aG!4(8}|QSkw-Ko2tLc2V(p
zt>6LgG4Z!}Gl7;ffR=*?GBPks0B>&cXg(4EJ>$xwS(~x+l?QwYJ6QhpJ@|etgbb*q
z&EHyc8nh!0w!r;m?&<&kUs!<L)!7W%$mG$@S_Pg9+yUY-@V6$O{{R1V7t;Q-W^G3P
z)-v!(gRm9aU^`!?{|D`V_UMM2J>@ibzaLE1%PKG*?zNH<h>NtqX2Enp%#sF~1wJ3>
z#cWV{19#kAP(P>{<~YYw|Np;y1v*Pg54PVE6dwGo*Fa|zp@zxJ;~;et5aIE<0lYsB
z?p}z^3qd-;ew+kip_$PP7K6F<<qmLQ!aX=2#D)8hzXeo2L;UE5q7Pz|IoLffc7w_k
zxc~m%0u2zr{Fe^$9~Vd+n*Y9m?g2-0+w;F@;XnNpYWUZp@t1*4R!2^1pc8c<?wtlU
zALdVpd)vY0zu-o3Z!UQ959VGgkb9#*>JaXQyYeOIJnjj|_Q^9slXj~b7W>5i{{R1C
zE~vDDht7XczZV|+{vg}lfKE>W$JZke3vL_4&6iQcUN)XWN&GcnE<E}eK?xBl`aoB`
zLV}|mYz%5}RQ&n>|HZ$0J_ZlC^Ab>;XAE+lFGwfYdCnjfn)6J+VlZ=G=A*hN43&Ec
zl!lO;Cj$??7r&9c)qLXr%iF*I|9_E);<(44Q380_NrD`=0jv-1|4gubaMz@OxL~Ju
zpr`|xUyUO25}e(ToaO;{nlD%(%uJA02awZ_)ggzQ2a3}eK~59>4ce^?T7wIA0UOvD
zm`g#%`~)3<1kbxKK`9TBwO=ZN+zt=ymsin(P8{yOwJ64b3|{c-|Nj?iDDGQv897rv
zIr;zp%TlmDn1f!Lfb0XiGzLWiWS~D-1QrA@g~3V@+kMR7Zc#*02+|5VL<z}PEC2of
z|DwAVIp}o3Q-rYmcLwCNTR;E*hm?XBK&)<<BS8ip28+Pm!Ub{*T*1qaCqd~5rvBwE
zlu$!oxyIjGh+-JX_>`aj|G#)ugY3W_&~Owy*{uUP&=RZ<Zq2`w|Np<(ilQkTMbjUU
zCKj+JxXUl2I(0YLsi2za4)}~AnBgEtod=1)6K9D9Buj4riNezlNZoRf2sjRBfLQQg
z0m*fvh`iqOf)&NR$JZk#kR7l7|9=?*(gC*>Gw@76@+kJJgG9jgOMqA?_H+OE|Nq6r
zYUF?oMzM42%m4phJ^-C|gvZVUAbAu!H-kjLb}j+2Q0$!k{r~?LvM6@mUx)0^O)vic
zf0+Z)hsRDIkUWZ=_8<{FI;24IC^~pSB4Ahk109Ei;>wTT{{MebUWFVomY^|Dc#`uy
z@&EtJV<1(5D5``}RILK3S^zd3p2iwapk#*(5EqZTlTdVnQcWnx*4vfHZrcl<t%2oN
zH&Dvf0_nqJE*D51B|QFuPACG0$2$-UB|IK}{r~?(I*Of|r;%gL8RXM#V100(N`brv
zH|8ZHh>OQX6)3tvKFtP+fL#;=V!@39$@zmsz;X^C7K)rP$hA8wkV7aMC5`QW`v3n+
z4v;=P?s)+^SqLSBZi7U?cAf#TQ0(0Q<^TT|t|)dsUyB?<d!GFN|8fdQA09hPK=LSd
zrh`Plc1D0$D0X^-?7Ucx?9XBpJ9j?*|No@|NFN?M89?$Vc7Fa0E9;+tSSWU0|NQ^|
zi&zvp?LiX;&9KzB?a}}LFV}$d;jyy^B#&ZeJxB!X&jJt&#m;1qoiEFf{dpR^019U3
z=7<0PzqA19!(*oeNFK#bZjcDr&Oe~jkWlP=|LOn#7o{k6hNIZI;lcm^FOPuq;jwcG
zNFK$`=^zoXogE++ik;OUI~h^zR7R<Z*WUmC|78G3A09gmK=LSdDuYD8c8Y*lD0Z@g
z?CdQ?4%_u8_2jC1|Np<d13DE6kDYr!@+fw$2Z?~~TmWLB*g5&*|Nk!}QS7uvv2*#|
z|NmcRfb`+9(*q=rVy87o1Z<}ch=pROJjl+aCCL6<juN&@?)?A%@(bv|BRqCq0m-A-
zc^o7HwsQxFg<|LG5C8waFhsG_7{$(oxBvft*#Odq$Ib+hJc^ycAQ7;gE+7_)o#r4r
z_ZB1jb3aPh&b#&h|4SZ_K0J25c@L_jU?n-IyuA++0o!>2#6q$2@caM&UwER}d3qIc
z**E*<|Nk#%fb`+9vjQZK;?Hc52-waT5DUdle~_J5i;(>pj$-GG8~^{mQ~~M3V<!tp
z9>vb@?_g!$3lIy%&fD)m{T~!NAFo9A=hW-}|G(S-(uc>+2_ShCJ3)siLE6?OU^(P=
zW;)2uw}r_5^k0o^=cH@@|G%^W>BD2E3`icuPJWOGIBXd}EEIo!e*6Fbi%JwbZ=-~5
z|JDEhU!DM+f`rG;6(D&OJ7<GLz;^b4SSWVZgY0BQu`?aT&Ymlv_Af{u9y?7y@+fwy
zgG9h~N`P1>c5;L4oLGPywwF=Dw(~Nm{rd)#B4AxB%r^G{kUWZ=n?WLAJC}f1D0WVN
z18V=G*cp#vXWJ!E`xm4Sk3W4t@+fxNgG9h~8h}_Rb}EDHT$zvT&(|nn+kEl=|Cc{r
z<M-zckUWZ=r$HiMJNJNCD0Z%Y{r~?9QxrSH*C40ch714yzia{N!{g5skUWZ=;UE#P
zogN?-ik;RVI}hd|`|~kM*w&u^|No@`NFN?MKfFRO`yPWtz;<2%u~6(h{_6k#7rrQV
z=A+nIb?*QFmvcb+@Yq=cl1K4pK1c*?X99?YVrMYO&YQW&{=AJ6w&iF4|9`0g(uc=R
z4v;*Goxfj#QUIvG`v$~9vGe}R|Nmd4qS%>^VrR*j|NmcZ0qMhI=M<1Uik<Bs5wJfi
zKr9qHvq5%#%t7|&XOyrlJpKRwO9zlXJa#I8<WcMt28n>}WC5{I?EL=X|Nj@YD0ar9
zw5jtz14(CIfI<p)nXm>Vk7DP1kO<h$2_P1Voy{OSIZ^C<jS{xmpdMWWNFN@5T7cwH
z?9>K{fbEn4u~6*f2iZ9_8#!#tQS1bDOkX~Ej^Ce0K=LSdZU>2g?OXw3q1ZY5`Tzef
z6jAJaj1sn~$N&F-Spd?9$DaWpc@#UHK_Xx~O+YLZJJmsUuFXRBXFiIZNyq;GfBEMb
zet+Hp$)nhL9wY*`^8kp2V&~>(|Np<RM6vTXO4!C9{r~@E2S^_te`bK>QS6KciGc0&
z0kKf*v<KOFG!xmM=_q~Pm?QuHzZ3!K!(-={r|4zhbC3ww&Kn>Wik+vQ{{R0X5XH{V
zC}A6U`2YWx3qbnt*x3M*NAYJdNCa$W3W$YbXE?~tyBWy-tVgjk?9l)JFLglr@Yu-%
zl1H)g{}WIO0F`|oKr9qHA3yp3|3xN>ov%^CHu&KG|1Wod^x?5{21p*o&Tfzh*q=2Z
z7K)wuAUnUNBm1))#m;~O|Np;q0qMhIrwT|O#ZGaM2-r>z5DUf5-;e+Qf6<6yCo_tj
zzWe|Ge|h0CD5P+geH%dXD0VIeiGb~#0%D=q*$%Rk7sbwelrc!JegFTzi~;Gx<4+rq
zJc^zAAQ7;g3LqAWox&hHXQm;C?Qax+y6^q}|K*EE`2BeTB#&a}ZjcDr&NUzwik<Tx
z{r~?$6~)eW6gyq^{Qv*51f&m-KSMzBD0aGoM8I}hfLJJYYJ=?Dn2PMr&nRK*xcmSA
zmkc0%c<g-e5WP&e3=#p`c?85lv2**w|NmduqS#rFVyE4%|Nme1fb`+9GY2G(;?H=H
z2-wa55DUdlXONvIQ;_}1jbf+u&j0^kN`Um?vGd0Rbbr1EiGc0A17e}rdH%uw|1UyO
z>@44a+`hHg@&EtJB_Mrx>}&zaqxiENBm%ZG1H?kHGa6*)!(?QCGNagOy8ZwEmj)nx
zc<dAa$)niG3=#p``Q<(+43PVu&+q^L{~{N~&VH1zHQM(7|I0lfeR%Ag1CmFvvmYb^
zwzC1mLh)xY$j+Zh$o~9|;!pjp|Np=A0O`YHrv^wK#ZGCE2-r>@5DUf5|M&j?f6<C!
zXFH0WI$Qq#e|hB|{xV?;NFK$`<scEToijiz6g#^?b_$}{DU4#L=H~zZUnYR`;qj*f
zNFK#bV~_~gP8ARf#ZGaMopTeB!?u1Sa=KO9^#A|MH+S*-^9)EH#m@a85wM*bKr9qH
z7vKH=|Ai)so!lsPDsTM%|78V8A0B^3faFo^^ahE5?X&^0Q0&yd`~Uw0IB*PwpV;dG
zI?)|;ziH?B&eI;9*IYD@^LKzQUUcb={O@9UzdpmI^QK4gao^<Ipo85#zTeRN>D#Mw
z*yH;}|6Ua-kAn}HJsB?>9`Nqf(ez<n1HSt5wS=d&2y<zSXLkrIgJ-7*i%0Vd4iC!{
zB{Ci$5s&6yjHP!ykF$W*kugB!N}sg;FOlvI|L@az!Lv8y5{Jie1`zOQKEUB&d7<<J
z_#9#n$buZl*ux&(Qy^Eh_VV%-2r#&Gx~Qo5bo!`hc=Xn&SiHCt4O&YC;wJm3sCa-@
zdi!*qdhvKA7lTLVPmj(+FAhY57J2c0$roUFF$ctk2(JV&lTUkeetNMDp?ES#w3~Iu
zCJ_dY?hq9Vk8X|^@8dwLr+ri`JeoBbON78{Av~IoAUn~K<9~p`>!%YOn}0Ia>9wA$
z6X|vQ@7e2efWwnpz_a-Pho|L%(l5TrCp|&ptp`g5JX#O&PdUK9?Z9F1a{R*{ofix*
zd4B&0UdqHj<-lR^dL7Vt*sg{LUVLfcW@tUYKNX|_e9km9hEeXfZG2O~4BA$(M&$*V
zo}==CnSsHlvq$9yGXsNX=XKxCV?LdyT)RC~e7ajy9xyX7boQtm0I5ChqLKiPgySwM
zpr!N-$6Zunzyis&3NO?^OF5E#RUA8ydh|N}_h>!H-<k$mNY#26;)m7)J3xwkdY7ma
zFfuT>@VmV5=xqU8>(N^Ry6><DY#qp2kXw8@e}Q7kpc`s^ZwuHN;I-Z!oh2$7AX$YM
zaa)-{zV7%8n$+)gQHcTR2U%cv3A8F6Y-MMOih^h7OOOT!k6ss*3>OH;0>nuG2^+j%
z>t<qT{=vxKx{8s3q1#0zru6`Siwz?KgHJNVV#BvSy<1cYm>3v54?bWvyyV$@gu|!v
zqi=5>hiCIKffr|6_!&I9A>ruJ?V^$ay7r)Z3fQwAoi!>No}D+qR)Hi7KrDs-Au0*o
zQ^4M8{>8}O*9uzy*xjO10SY&$QIMS&;0-y}E-Dosoe*jM)>jM+3@*K1{~!tsFZuL_
zad;kl$oyKyuUE#%qxlerXE!rQpQkm8kY^_|e=8{bL5qPLn-4I09(Mt)dSqbm<X_Js
z;-PsEbkprI4`@2@XnhO1>-Xi058$NkqLKkRU7gjV^Wc90NZ6DJypV|j?^S^$xbHVS
z8jpaI7A#LX#yQ3xhJ~GL>w&sLuU?*G9-SX{ffsl3uNQ!1=7Xi54c~e+{`$hmz`)-(
z6SUr<7?fS1q3+Rn^kvJx|NniH4|p;6905fv%#kmr{rmqPoY7u48(#A0yy1b!887?(
z{{L_I_NC{)|Nqg_{|pue2A}RFDjck!e6UAF07Q3AQF#Fp@9a_e0j5v+b{>Oe0tQxa
zCV0RC+Q-qN0$N%ON>(1nTU0tg49GJ68W7VnIY&j|h18$_|2;uPjbrC=cxEsM<)PN&
zD4D^dcZ<pdCU9o>0m=*tAh-0+QJDZrcfD&=CV<w<clW4(TmVYfAh&^1P5?+Tn9~h$
zcz2Hq*m<2LDiI(B4j=^(kr)*ZAJCQskg$PAcZ-S!$dXPM6%7yvY-6X3io%Q1Es%`V
z3QByvE-E#ki!(uv16d4m5I93wfPCo#%YI;YfWiQjD-~Qog{F&&2gq(vAc1Uj09hgd
zwb9^(!#Zd#lV<|wvKmk>YXkW<xdq|_Sm6RHCnkW3ByeW)>3sMir;(ol<R-9_yCD$;
zSx*Rw2T*~p;Mw^Dn(shP2Jh8?I|CG&APzVbKt2O;H2zNk$0+EwRTc&Ya6ViL&4)8U
zQ3kciaX%>C!tHN9!02J!qA~-dva>}6q>{f?2~@82M*Z{cbx{#8y!2WPTt0htGx&Cw
zTm={LpnC(sd9u^thmYk4{?_*(1DanjdLDNGUEs>#(p$yk*?G)^f4$2!4j=yYC6_ro
zH4pk|e)P1wT)GvM^g+=MDzCx8&|IUE!BE2G(e0y>@xnO*R0lx<10}!Kv>qrCc##8=
zhE)*Y{0hnn82J^HYFt|n@b}GTU|{g>^*PGm)A<6NX`%Pgd%*MViPF!|oC{hw4XzXT
z`<y{pctbcJxZngC1`6ejmpY&|mEiF3P5$r2-17$%KYkz@l-}U^u15vrua_FIto<?+
zbb<0EkIo;+xqB~Y6(206yu1inRf$+H3vbUfzUcr}3Z2(IdPUVUK+A+r`*a@l={)zs
z^331=tq1r!96@;xly^WWu-n<fqw^JL)v(tt28Nac{4J#*?cLrM9-Y5lux;P~i-E6q
zPxe=V=j*v3_qQH}<!k;HQ2PmVHE`=U{+6#G6M9*Hqzf>B5;QnhbO$SRdrN?Fi~%TU
zG(5W9Aa$8fx1WMbx0}R^tZ$Hgna@DZ>P%7b@aT3E@agsz@Bz6Iq93Hy!K2&F0+hxL
zz!eNg$ik!B8DiQCmfsLl7BGVDlyGf*%ij_Pa!%*VP8XG!7qX#z;Ck+*BdEd)mhkBI
zR(O%HhJ(QaR1Nll?f~=XcDDHDAkE0%sspawJrtUMD)6_(F)}c`xE2B~{XIL6@V9IM
z8Qbk_;c9sDxQhz7h=4c<v{43BVEA@E@aTNC6O@A-_ku`}Qw?4St$~&Xd5oa4xZ1*}
z^XbbYpoL|<yuE1x44~o>6l5<rgFtQapP<SQ%)bfde+0GM*g(u)-tsg7h8K?lLCV0w
z??KFNZ;Kb}K=PenvD<-s4A97aQNDr$bm4?6$d=ASFE)UbLsV@AF}qnWtpK&|AY}un
zfyWmL%3M9*vI5k`E9LO$2Dj*->%$w5fD#)lHys8=14fMHs30Or;YA80mOB&v{r~UU
z`nF`dN9W5I?ZJEuuh;tYrl=&iB8R36T<a@PUIT3%V({&J01na@r&dA3vGD)@|E`8_
zUv7Y8Hpu-ypt|t|a_$NL`~SaB=hN5yFA_tbcXxnqAHm*U>;P4J-D|-0qO0LsP|*Xb
zDm^=|`F0*bYASwU0oRfjK+2E1sDO6qfp=F{fD*uQ7ZuQMHwF(-Q}Oo~aKdcu2IZXI
z7I5tbj%qM}j!FY4+4t@N2Q{d`1(^)0gh1AU5)Qc50dcx}RKV6jYCUj8_X(r`T>F7!
zd^&4XEI=aQA|G7i!zw;dl?swkcu}(!Qt{O?F)%dm0h`Fk-y*{VY9_RR9RuoKG=LrF
zqLPDXRi=PjmC&{%xM5iVG7;RW1UK*uUTkQ9#tdk`ShtHxj;rAlP?g65GCjEkY?(*z
z8kGiS1_n?(y#%!_Uo=&LYC34ZboYRpCW!J4)PAf0JBbmr5wb=_0~APL_jQ7jNjId4
z0&)tdg;~%&1#AttW&`!*Ks9m)v}OZ^A|ywG0vH@7(3%ZYtAp|zNF}7{=+YbY&!^WH
zRIw>~b~E~Rhg=u%Y(B_=sM8#O_<*iM?uOTCj?g+Si^;R|5WG$c0o7>-d^9h@>okxv
zd^#Z>_HBJq!U3x9OTZZs)aGqHPy%mz=78(61t2+;x(t*|VYv_7_Jr@p@J)W}#oY4-
zl&bugTi!qd3KFO=J72E&_y503w=cNQ14<^K^1FKqIAuZ;*$dZCpj7L~KlSKKcTfiE
zhBy}#_8{l`TAtu<J`G+}4-NnBDJl@V4tnsfKjqsi!{KXrvj}Vj$Sp6|fmYkM2k<d?
zb{={8{x7sG`_ceZ)M{P?HPk)6-|}HR2#Ohy29Hjdfsh8FC;$2bp5JeP`~Z^nVLSnf
zFOXYa27@*P!1iaLwSPgohe7RM4K@Y_SHo|h{4Bu+?fM->%FhZQ!Q>bfh0Y!o1~y33
zcL69bgJSo13%I`x;vR2NnFFFh!ku%#E#eoFA3<To-|7iUX1y&c9w7a_b5u5f`Fm70
zfHTt;l?|X2+`C2vRAqt!5@aVR-4=kFkOpj!90+n9s0|D<qccXO0@^W50I31VfvTDe
zP>(PIR26!F^n*(Xu%kO&RKQKp0I+TsP-h+L99UklfXaZI!yr3B1}MB}TLUQ-M47>*
z0?05%{+8vSeB0dv_6R6mz#izH0`(9iBw$q_sMW0js^%43KsAet3fNUEz~KaKC4<5f
zWF6Rv4p4^}ypUQ9Ej4C<TFDSoLA?!7-3JP4PzjO^a!GOvIBGymiw!KG62zzTA-Du_
zC<B!sbHD))awphd-90Lx@bc+i1CAwF`T&&&U{`_s0V;Yyy#=4n7!?Ijlz^iO7K)&F
z0=XAloPr}0RGj{wq5|>=D8H~lThMzzzU*#M*#W8zp!ULA&@Cz;*MP271t$w=c?0g8
zc0zRUx84AEZiD{$_WFQZ(x3vz2hxZ}FK|Bax2^)&25v;d3LJ1F8q|Eg#sO+OLmJeV
z!42x`9G;qoeKkLLT3#w$32IP-!=w}Hs!m9lc{D?+ABGZMP@f(Y@GqYDfLZ{Mgpbs`
zhC~mzRO0dlw~3H?#GuTEQY!JwGeFzFprqr+-0}w$z<$hg{y>5g8bxT%c^Ls}BXs+y
zfJ+Zhigh*o2C4!;AqmYJFP6LoWjaUxsmES+`~ltV2K5p&_`wB~1GInwM<gh|K^d_V
zT0n_#_*z~pG6csuXi%uT1)M=&DuW8Dd)}b76{Ki;*$gkOB(RlMAg_T+E0EVfAq;Y*
zN9RFL{`DuI1r|t!C*w(2;RCbMlYjj|&+j)q7$JESBn=9dmka-ZFaLwIXOP<W8KC^(
zB;nC{&ZG0PPv>!$&a<Gr@d{L|bO#D}SOyF5xAcH`y`rr#pdP@-7q$l=ZGUiExI4_k
zqublUvGc`?(p8W~|0Ix^eiF?;8TnfrnHd=B#5_7bfzHmD@&**X{H+^7?PWg+mu_bX
zP%F>X@QI7%LH^z!psdsFtuVo}*^;qT&=Hg#!L{Q74oAxqr7wMYMFT-j=nhlx=*>|9
z4?8J<N-P7P&JY!i7p1Sj#&<jbIk)vce~SpXuw>PMYU=ir@abKnk^r{GU%{o@T>_L9
zH9WfAH9$oTxHF;fLJw-pOpr0%?gAjG0FX5nKHYu-KA;W*$OWCC5~$nVqT3H_ii1bD
zvjE6A15leE#6WaQUhMt}ahV$<1A}YplM*iQdc2lsCQ!fPwU|e9E(7=uA6E{K&X@lK
z48UVD9*svpu>(u|hmqSaffgQ?!4~|jY2aGdQNq#k0Do&FsNLTkr~vMVtXRMS8r5rY
z0Sks{cyxPffCBtQKU6~d-~a!H2VT$QmuK+lb`tRD4zh6R^Z_-<e!ln(THuOiy{q9#
zSHlClAiMTIzNq-c0J%u-D1VDDxY2yTaVKa58g#*2=fM{<{zAO0@c;k+ZctpiN_cd>
z_ULxiaNGmxzr5u92ih$KDi;`B4WIaQdn@?#$`(d}ZUaP)Ur;fs0SbMC7gJw=jqFqa
zW#!f<{4J0zQlMG&(_ml1W|pu9pGPn6?MMNJ7yn&Ag^;&}NADbPQUF!?pd|6)m@6oM
z-UM}tK7-Ws@*V-HKM!Jef`#vZnB9IBFJ>c@o^at~=zRGib2hj)G(8fOMGn1K1X2mn
zv>e3jW<4?+(i;L<1?mkkcz~SI193vLCL@0<JJ=849?{F+pymgBKO!jJz!?QJsBj*v
z%umBJ`GQAx$b}ys{ObihS}*Z;O#k!$Ke#vJYWU>kYEb_kK4oEe0NhrB*H@tW36x%u
z6Erj(V@tj|pCJM7`1k++mrehWr#`?v9`OB&9-XH>x;Z^sPnNL0n4J$A$@P|i@OnYK
z&YK?1M--x8Hstd&goi<NfOZpuCP_-9J-Qt&x&tLVx;+&<k}DKmNX_M7@Zev6+@q7N
zJ6K`|D8aN|Dv|3BcKCLPu~e-25mWOorV>7n)^8<39>+n)tH3T+jEg@!!SKNA&uJ47
z`2}Q~fk*45(v0pviPlRc{N0WYD;P^TnjbJV|6nRr^5}LH@a$v&IRfH>2!$6j=73#r
z*rWM~K{V*XN$y!9pwoavBLo<HKy@}K5{=zJ(;}dOz~cu%hp>1;CRtve^5|y0Jrk_{
zKsYExbG+bi<74oEsCvB`Jc@&G-^=L#DED*1!l(0^N3ZB1kO7^ieL9c7II;^=@K%U=
zcK+}Hm#E+%jf;N?+IkE%94d4e+5a%}x*a(>uX})s_0H2CmWPVPJ-QhkI&1_ynw<q0
z!4pCX(V+12=oJCw?R}tA8bEQ%@A?Tefg_vC4-zin_2^{w=q%>&=nfWmz2Bpob;k^_
zS9L%x?dEtP>k91?zg`Qy&obOG45`j}0d8#UQ3(J=D`*12--F+^1<dvBJn!3j5?tef
zN?%Zw)S}|R$iQ&SMaAC%)NcnJE5iWFvmo6d%>h3AE<ZfF9W^{a6&Gk^#iu)g!?W8(
zh2vYpY6b=d7XB7PMg|7YW)>C3U7$-qK~>SqfB*k`HrJ>KF!1-WfU5}?l?3p>3Zye<
z_zhHqTR`0Jk$lYXl4rNi5s4Q+oj@^OqGI9G%bFS{z_1HcfH`&^^yob9)A{j5l@lKW
z|Gp5FgqBOCqOawl<9(jZ#~2;?_ldP!D&YZHp7RfspGsc%@UMU0e2mf4GDk(AzG{~y
zC|o*kzVHRRO-F^XlpE{~pU#Kid)-=83_yX>4GB4q&Rd?{=Afo2D13Z7e|mH~Xn<Ps
z3ZRtP2{NOb-y`{&hvr2e{`D_?7+-mIihDF30fj!SPJwjuChXFI*zD1Kl<~#+zyJTg
z<N`HHdU@+ZL5cm*3ub#rA8RkT?18$Yxx#{hzvUjNO6%75=rwf<6=2vA!oa}rn%krK
z7$g5Sww41W{QUbafV^A@t`16`fttz?UpQEJG*^Iv-y7tq-V&7vpWYIc1jDzWj);Xv
z@>P%SnhO#L^&SSGLBvRBK5#exm`CTq7b5nc68j@~Xw|dx$O{%Q|KJN7Cq4$p-V#;@
zkK}KjmgfBZuFMP!wW{#`>@LuV3dmKDLDLM~?4a>v56feoo$U2bKo)|M7IMIL-ty^u
z2ucqMFAPD=KTz8O>}t^5r7!6Iv!5?6*n!TE<L@wLWMJ531qsg=&7e}axke>{q0SLB
z=n%obPoUwKRVnxDT>gDQj19l6N>V`Xhz6<a4pE8l=yhTQSrh?ModE8^f^KAWQAwyj
z2Qw8MOPXLE(3t3Uu<)?V5a91W_V54yUA0il+5UhkcyK-I(X7u{qV3Vm>NXXeQ=LN~
zg;KF2G^f6N{P+KVNXma%0`g+FJBLT-&;J1iuTO$P1Qca1-4Qa5&A)kFI&V7gPdVn;
z{9Ay3$^p(}FnOQk00p1U>%Pq5zMbMO{M#I)92<Vvmbg0hIvlZK;%@_OO>h1w&fh){
zoZnd6K#oWj>F{8@@c+RJ2S-qS$hve2*nvI45C>jz;A40Rx~bkL*+T_n5h$&DbUO%m
z%=G;J6I7&^`gC4^b22)A%yj(zv-MJG987Vyg9ND7d;kiR?mghLr1=G-tKlV&?tBH0
zUYnz!!%ANBdV*&AEPwI0Y-eC#@M^9RWnip(4Ko9jv%I=l;FgwLbZGfjVhNH4C6xw?
zIQ|wTP>$)mxhoEI-bgoiS2UzZJH`NZ3n&D;J!D?~f@UFzM%z+Rm(H6npCSpmSTU3+
zIYP6I6VxD(ZqO~%AYGu4?O=Ck`3ABdBvEP)ikjEkKzxvb1`7xN7Vt?Boi}%Z4#s)$
z8@v%2<{ofg8Ke>9o-9xcl7F9vlnehp2T6}!(fA-x(6h=+7GVGtBopjmN#p={KRfH=
zN#GbN2m~qPcwu1A$MAB;-~az12Rn7%e9;GK?1E>}zu$P-3DyQpsh}M0)5{ti1T8r|
zIzPH}dnmkcvgKpo-{zu{&~l(e4(fL|h&ip%p!5hUP)Z*e9(ZYn#Yh%3BOQAknO$2?
zy6}6Pa6I^v>BR#ZgbjP3Haz(ODu?-7e}Xa-!iLv#Kp_bVAkegWf=@5&;y^U_PC}T*
z-;xEocN$X6O@f-Z9M!~^?*IS)-vv6D2(m%F*HkG$fMG`z0|NupDUnc(d1xB>K*_4t
z^n*XDaxJKGdo<<uK?$kXbRU}X-`^n~6+lxC8s**vI*aNhXwC_ICgMv=kP+Rm_!8X_
zAiw}g8r`fM6Cr7$#uk<)*8Kece;4SuzL!j(q6ajA_3{TOF@O#veEAN<0-b>P@(G9q
zI!o*2Ef5QISl7!7AQtGvv6sg{EYQhjFZY00ptICoZUV7DBi=7pfLNdt@?OpZu|TKx
zy_|y5K1LazYkrgA0y?S@)Ua%RVBykvwE2exe+y`4z4Jx$gNWuI5&SK)K&vudsDdUR
zZ9xQo3+RAD$IiEo%}*s9oBv9baD8)jVB~M{W@cb;_;!?$zx6sZ1H(6GM;89pccAhM
zG&l7LG&a+0D`PCez`)<~jhTUACumv$)Jy?oJMiE=C~&|GaKq(=U<$Ym<<WVZzeOH2
zPu^Ps8ea1T&HRA$f%G$YcHZ#m{Pf}|czVOJ^9X<IEAZ$xsD)wh4K&VLECH$@99&z!
zd33V7be41Qx1Ir2qsQGLmy;iN2esW8Ky^#I6?jO+6J(<RXt1K2H^)eX!Kd@r3mzM&
z)G_`R(1H<<?f?Ps{qL=p`1?RZk{->k7(o^7W{?@32VWF}=x%<GZg5Z6;>G7AeumZq
zKHV-V7NuF;?i`NR4jiS4pz<~n6h__t629FY5}w_H9+rZop1lG8eY)cXd_lJKvRnm?
z!-48L3&R7iB|R)%R4n*glt9`*3wgRl7(FaS7)wPwyG58hEk&41?jqXDK9<Kzj6u_k
zt1Y1(IKbcH0vd4XJmk~)5!5`lc)@Q4YN@%XSa>#TF!Hy&04+NKUk_UcX6ZBXx1@lB
z!&#skGI!^39CQg9Xhwhy)Q9&;E>JK$0E%*t<8Bck*YZy};L}+q(dnk}qH+QUgAf1u
z4-VgsviNkC3GlaE2iGv{%}+TzI^8t*TR;PFpde}fE79qu;sG9Pa5La<xd~Et+zmR%
z7suhz%*^Q0`M{(3NCrx?%s2U;Pv=jMgAZ9enh!F*xRD4=IPMbsEl(L482ox!ez>-N
z^XYUK;O`Uu2O6#lR`BWe)&MnCc`kW$@?7xj=DFzE$#VfTzu;(jt^PSEJ(OEO!|XVJ
z>jzNL+WGT^^{4;;eOv#RaCtU^!X*cEM%x}xhvsDxsAmH5({VRY)0u(4RpbBv|DYUl
z+)V`(CLYJ#KnG|t@VBaiimGmR0gp~Mi<hA45Z>PU=IFr4-&zMMe7ac=_kin<7d`?E
zj$k`LwahCEK8Bayz#{@Kpls&A#NQeNQ9l`?{sxNrT_E+K)(*HQ)$I(b<6CV1{QuwW
z4C>j5L3(!lt%ZyX44_;u(fmWAv<aHO!TGtx;17KK!J}6+#tYPOzxg6@EvSpd-|_d~
z|No$<=Wh`LIivIDi{)#;GM!9+{{Me@4>Uap@1MU|4GB|^PF6vE5eEL&ufPBQf4K{!
z2JAl1Zg&nJaBJ#iFKDLSv)c`{@acbm!OLO@A1>ee4}AWSkBY;KumsSlwm%_(^ui;7
zpW)?|zaTe*mfS(oc=HEPw7aNS_;enBDF-SOq4qg&_;elwna>F_-|*y%muApdKgQnz
zI-JR)n>S5Qgu%1(0H`3iZ4Pd{wyXgA_2&!i51`(W9wUG2>%ag1BRTgDD8Y2I{_g_E
zVS_hv9IBb~F}yT_D7Xhv;EJMv6{J8A)X)qGg>*?BJUUOm5HklmjlTs{B6#$Ms2F(k
z`lx95^tz~6K*ow*2!oU~+iunc7qmT~9MpO9#adHPlaY6xt_Xui=OK^Iqc5yM>Oc+V
z<0a09x5533eV|Teof<g*b@NDgG#}=8u?D2E^WX~?(Ei-c51`(Phqb#v%`J~^-T<&^
zuU`BB1sG^tu0+ta^+~C;NAnQ}Nd7!L!J`{CPzM^!dkQZ9K<gL{K&wbJUYMHkF-$;F
z-)#FsM}&c)WEW^?#u3z9kau7}lxOhOqXr(J&hKgd7SM7*{%wX1E#LTCo`DLsUeV{?
zpcN3TFTe@)ROg5NwhRmm(D9y=u7<apUnttx^0!|AtpeM2z%!Yp!H4m{{|DgpJ)IZ!
z+kuXM1uIXRz`xCb5mY9$94I~M+IpM6bvCFV?7aDcJC>ipqt}D+MHYzBdH}pO;SX5y
zxZ&H^s?h!{Xd%Q7CI$xnZOk6c#~C}^|9dnaX5`;y3~Cn3I5hmTD!l_0ImT|){FM=;
z%Aw_3>62sZ3_hKYy16`>53%$%{{Q#y-}j4(CsZ368X8Job{;(VQeb660|NuU%R!G`
zFQ(4J9{esB84iPbU(L6eeKa4vurvfG7I6Iu8b0;t<rVZ4V0aN|0u?{T-(n1!*y&~E
z^8~Gb5asj)on`kERE_x<fDZ1}XY}Yi%->Q7@)o#4C<C!tZ}Ydz0x`N-&xQ#ycvw1f
z@VD}TOzM32;&cosE8YN)1;xe3I>sCZ1s^yx!QpoRRB~-&YJOpFW5nOS3CsgUL6Z-t
zZ!^K8^8z@w9KkwX)`D7CP$5^tlP`0jd>eQay^I2t9q{tS@Z{?mJ3#}l(D3)@yx_PS
zl&)VIfz(ad2|CsH^-FkpYk2bYot>aVcwb)ymj~bzuV0^p%Y)X>N}g<f_^<gO$LmdL
z6TsuPuUEq5cY+SreLWM-M^exJx+!hKPG$xMhL@o8^dRFSuB|8eTR}~?=AVopbN@CU
z6nGg9PUfKD5e9@X-%E%8|Nrj<9R&N*41Qi7LZ1I6XuKE_Ok!~P7v7cs|2s7Nw*^OB
z*}wn)9r*WM2gT?lX(k4bZex$$u>X*=3He*YL7~|l%mHdzXh04q1hthkUfTTwPl32F
zFgWn<JNKeJfD1f8ZVnpnumKfY&HCU$cv#ODG=qLAiXSqtXaLRo9^I^uTET_ie>VZp
z`Vmm=m16`-SK5rFXFT9TuCEV(eSt_aFU>wOGI+rI)h`=BR(8V<L3mmH7j#ZmBsBlM
z0x=*3Sp#Tt`v|CD?q+R=SnY$b`lBHq1IVG8V28d0ontp)LO6JQ)xfv)fKTUn{+7E8
z3=F=V2R%D4cyylf=;bZ&5MX#=pbO0~hxuDT1?r3Eu$*<QB;TW#*B_+lGDuOcsFw#Q
z3mx$2{P<#}A*iOP$OVt`|Mcwq@FH9vR0>;r^oGNt0BoK|w;fzatW@8lI}8>hAO8m#
zfMWz2HisvGW<!v7zJrG%K_Pw^lD<IlB~hR=uu7jG&T2F~@cITs-m~+fN3ZBKcaSSj
zfYzgf#%$x_U#95rF@VcIY{>yM<_gPCh*+BiQjZ8fkIrizpt09OKAq=FDm=PbA4Ui=
zcy|8q>Fxj>l=uSN%Lc{M;gWjLV04^EH|su#637UxPj?4s1;>j_P^xS_P~z#)Eevi|
zgT}svOGQ8@X`-i8Sh&FRpGPwzqettv(nTKNgE$#II&Zw*1qu}Gfi?l9KLlCB*EvPy
z2B?G33!!~FkAfDwD>E{JMs&g13N)bA?I6(&QQ*?+@ZZt$0)NY5P!ZS*S+&)AsnZ3t
zdca4epiZLK>pv)-4l<@q@a$wc2pK~=So+x~`IMvO1<<YoPsTbKaQWkrd;v5^-Pv;m
zR2+bsvo4kgN?(HN`U2l%(6Rb{ojpfDaxWB%xEMe_^XLR!P6evyK^?92AV#;FMYo5{
z3;R;g3ayi%&Jwsq3R)q@$jZO~S;Y-*2z-383N$;_tOqISdqKKeZ<pkNCMrF;9UVNn
zcU%CA{pW8v4Vn#122Df;D|mI69QxtYc>olXSstx#UAi+B_*+0Vs!O-4MDq(qN6Q1?
zRPetMTm-bZLdHOJ^q~2l3z7c~4|t$1XoHNkLc#-)?Nh*wX4Z8O1DT-)-qr=JVM7=O
zZW?=Z`zpM+*aDf>D+d*$pkn`pe#!s;jyo7ZS7?A5K`&p_J%G;4xu`_&w?Hg#wm1gb
zdjJYFP#>M)n}f6fe+%evR%qYn#foMQ29KFO-PHmf-~WLcGZ8-BNdg|N2kP8?lfQa&
zu2BI^tAduV@vr~p)A`r4^Ef<xdNv<r1TRp0=?R+i`UG0o|NpuV<5yqH_oa_Kx*>W&
zeJYT>rGgEh5mDHh+w(e*z=QUTKy3?1bl0dvcv!yYZ&?V6s%~~rE<uclvX>ZmG`lh|
zdUU>cIT@6<I`4sp7CgFHqZ+`GGuIgsIsH0(3@_tAO5kPh>mwfB-W;ImWl)hAqv8Nt
zaN-EAN#Tc|!xpM_9s&g%xNH96z$2v4ZC&*5|NobaV8dNhBEVy<FTQC*OI8<^4F0Ju
zDhV%VfEB=ICtreQ{Q2dP+kdF@BcNrF*z;@gU#R7W`CA4@el5%+lwbP`iO8?NzClh^
z1(!tF@+)}T0%+Wwto-U<2Tl?;PLL!~qXkKFXvHT9`So8d*udS65CgTfaOGFUM)dqz
zUx1ch&)tDWDoOeENBschS9wiH;888VuBrit<y(75Sl-v5YJL^Cj}*FC^Q)T%sreP$
zyz=M_QON*RVHrN1$3T_owVzO%4wnRZbURqMfVMDsbl!C7_K@-DW?dd2$l%dE0n{1*
z&2TBaSf<Z~+IB^>1}qTmRtv};xWk4AUVnwn-($Bw48Q&A5c@&R7Kr_7WZMtzy@Nua
z0u%xjKAp!wA#mjfECl#lwlOd;bcd)^faj_YzBmag0znO>WBe^^p;E4fpsN3c9;gcJ
zJPK;tfcIy<_2^_SNd(X4P6rkJpj;2B16Y&&!6%llw*|HIUV@D7_TT`|dA_Jn0yRUC
z+MN6?kWDD14DjATC<EyH?jztWg@?fwfOcqr+m&3%?Mg_H$HyLqwGTn(mA^n#$A$-9
z-$C#^TL1I6#)Cca3e-fNrozYY610vSUO#$thk_fw7NFHVkj5`GTETWOz#7LE9-Xkp
zvBgU#kcsey>B}&1cM7t83(`JyfG0o~a02w{JpUr-J1hoDyga&Djr{}}z`^4Pnr8uR
zLhHQg(Jk;oTbJ0R=Kxv|V0hs57tHkp*zCUqD#t<5e7MBhqnmZJuOI_B8#sd2Z{7rt
zFL&0cD7;vuL$U*q)^mh|GXOUGgAn$E{qKw2|JF3~|5teUgZ=M=!~eS|@;^%ZzWI%Z
zFDS&%bzb-BJj~xB&&<H!*c~9@37S{CRLQ~69VX$??WX`5A3I#h!Qf$el)u#qH1*K!
zX5rW!Ak*vgsrd&}nOEz7{*FhWwYskun}2cgw}Y4WfrdqDLDL-FtZA--p!>5R{Ti2U
zju%_6gJ+dGrh|q}nwde}l9#<q44|<uW=4-*QDJM)nCizDPZhugEOflR^Wcj)zd;M9
z4|sGQ1?^Bh_yW8)1~k?N9&dWb%)sCaTHa*}GPhUsj1|b3o4%b7UN9^0F?e?KsCe`S
zf;yX?ogymyEg<!+2lzYKAj%hkm4AGZ53}_hsNd6h@P!)8)?*M`w}FZza3A3~e~Sdj
zkD!v~07!MOXp9x8i1`5;Fz=J+W9U5Q(arAB8vwG^qf?x}<vTM218DN)27l))kPg%_
zh*q#rFbAX<H$3pNjFADUy$7-fwAj(3TX&+DAcIHiZJ+K`0iW)zpk4`o%U_U3nwc40
z4c|8Z=iu*?1#PSN&)Mt#{}aCe>vSsthEMzgydb(n5Zs?=e!=*OKk{Jn5026=FX9!!
zp$(qz`3ovPdqwLlKp_|dTHANfv-1OJyuecytO`7i_7LpaUJek|E9!3n^7%o}&I2!0
zAd2`~)`O(FIiSJr(J8>+A^~z_uc!*x=o%FT-_D<)esSl=7w=@iM)S8+V(Mao&%LYw
zNrHCQxAcKlkhH$_===eyH^VGk4G(m?Ie0WPF@AFc%>#f&a6ywj%W6PdoXp{+xp=9v
zM|U`^VEqXlRj_!?3m#A4Z@I<*T3rb%%N=7JW5Hc8@Ono_q?FI!_L`A_q4ht1Clh!`
zM)$9WAVc#j#_#u=e{uSBF9k)4Pj{&Re|rie1H(?xwLp-S5-+x-{r~UTdBD~1B*>-R
zZVvpd2SMKI4pZp%lXzkJ8&(+bw;F>w3VGl%+=0QPn{}oKINm+FJ3ztC-{J|<*DHF-
z3>5e`Jwb!gka`N{?w8Z0L4z5fPBH_c?g6j-n&8pPY6*&mWKaTO`2n7R1ugjiwQpgg
zS%&{#f-Zsprx%ZIT}cl?hVS>0eD|^oJhy;uello20%`sNv>kYYM>p%=B5<Qk+8oko
z(~{?7Fg)<GA2jkQ&*0G=zyaFn9AxnFCTRYl`2nM2=K;s&4~#EC;V=P79<*x%X*~TU
z^Pm6!Cx9+p0d2xs3^vYz!K0at(WCRjO9Lq1vpYlubpMD2Xk`@m{t=6pzrcs@L+VG5
zUeSf%fc$_S`!55fAnS)dzBrzXh#h~>d<|$m8Zw>)cJD#Q=8ueED-lhDmp8#H4`5*m
zwUhxqeh;dWAT1(Tm3;Qa{`YWuTCRY1BdgAF164~oDhkkQxdODbyIVx%#bi}329M+r
z&?fcc9^K9gY5eaGeDdJeV!8051C$q=wHd(!Bj9FB>;IB;&`3p+2dK|{f`Ng-v)e~S
z!lPHT-vpH3b3pn1qi5%f7cr8cwvoI?Z!om{D#=A1o^!<30zsO=@M!&C!UjrFB_SXi
z1+X@m9H2v_X-M~#fSWB7uw~PiRp873O>eLeeZ2rQ{syjMe!i%c=3{v2^8f#TaCHxA
zZKAZd)84@Xw#3h)o7LSFTGxVhFN2yn6F@VtkfyG+3bD-%kLWn?`cahj4tD#Wy+yJA
zxC^@d;5A2}lM`O-R;I{)wE8~6qnlN<M1%pf;<odePv>#p&NCjChxl8rfcC$%UgDo}
z$kXxwf6GfS_doxX11*<II9d+yw_fG|6`{@+9^DQOKHV!K7(q4dTmBXf(6oE&w-Pmv
zZa<E1jiB8i4W*JE-J)jsA`Bju7fX0w6o`Wce)(IbKq^X*QhyYs+;F9?P^GM(P3zsx
z77Z0rcKj_%m_U|2Dd7jLX@rV_w~&Jd_;kQ~Z$Pc*1N)$%dX&FK2UN#^D$DI4cSCj-
zF969y+6u?`TZGs^hJNF3VPpcedi-PzFTIdE%fSHZPB>c_UIGmm@}1>iusq7&584at
z(VcAp9yjs?&-@g#GB7mMf?RhJ8dfdf!wf(pORnJc?x4|R*f0=mq|u}E)eFyOP-h<J
zZ#l~jVt?ar5dj&}?QGHQAk+MVi@y!LuoP5wA(@B8Fp#%@K7|Z`c!I_~6<MLaTF=hF
z&>bw%?d;Hcsq+wjOEV(_!wN?J)@nuu2FMy{{?>lb6!#&=9ZakY42_RK-MhwLAQGYq
zTHXg+G*p4S83L+iEU)snf<})(D-Xa8tsGWR*}<X$8pHLpyyMx)qQc+e%?=7t7Zr)t
z1CHG;Dh?p~nOPwA{{}S^!E3PjTlCpLW3Pgs@kfw1Jvv{3+7~}hgTmwhsI+R;2U!Y=
zGX9q3pd<lWXy5@}Xs`|9QP8>r&}C5|u1D)_*!GA{u;One8sFR;1xkcGy4?&KJscQV
z7#JGU9R7pmZkzSMGd8eE6vG2AYe4r+d2|O`fY!=fsf9Y?D1VCtD2byc`_}KE`X1yk
zP(=xw()I0p2<lkE)>lVBN;OF1;pL;}p!<qYg1KehzyJR`4?&}&1$5$q;||b(G&r4k
zfCfZgy?AvB>XO6!Esw#Te!|}hTBGaH&EU~_4;1jAMb)5VMLNHDbh3dqvAbA1OYpZo
z0ObMDeiP8<^2>RU(WKMhy!4H~Wf2PlgKxK+0H_bz(gtqS`wRGV*TI&wfR+h(fR1%=
zcyT<JgTVv51Kvl)!2`5VrUtY>%|*q-@&8ru4ix?tXK>T|8!SFlKw*Z6Emja0++@2A
zb`%?^LG07{06g<1#^16EB-(rgCBzPc%JW?zpqS)ee2BmKEof2d$roK>e2~7xA&<_F
zo}I^DSc>p5H2?U|-!cJogv1X<{+4!dQxUWVVJCQ%E_}(vD$raQsL$=e%)rpiqACMg
zMaK;)xjec>zh;07EdG`V(3L&Ag}{YYt2emX_T%Vo1Z~q>$-uzC$lnTHMQF{doFT%%
z-=g{Z|9_CU1b?d>Sh1+MHE0(2B7X}X$fQE3NsM4gKMs#>Q86p9f)d^rArQ%ygMUG5
zv)m*=hd;Dj|Mma>%k`i&852CZ{XrTcVQza4x~@kaqN(*3c!{S!s@sl&1g&}7(?M?A
z@eA%Y@YO%oywz5M4E!yiTYo&dMf0o#8D3lzg!r@vq!D6WnI+79TOg7xihuwA@Aj8y
zJ;~pa0&*Q_Ee0rlz=dJ!K9pcKJOFO{fXffV|1V{JgC|cR?W@j%jSoRZOyf@w$=~9`
z#K6#b0k-Dm{qO((n;$Vc?hq0MEsJ{wYFmNsc0#OoKw3~z_Y1t<g>@|`Y<fkdbRq4@
zTOxc6FHeA*bS?}Go}h^+aV7=^@JesPZ!gur>sevh{^f;V|Nrj*&4(NQe<=u-f@S8H
z_kaHXKf%@TzzRl3{wW6>8xMeT=F3D-66y})0PQVxKn%J#ytIYJ7ksQ<4Ag%0>HPN6
z;umP?4aEOQv$$`-?N!8jp0gl6VtvTVbs)a0;kTEjNcuYug3AWOOU)0Nntw9!w}8rX
z(3C_cXz@#D3~0wa_>cnd1Q&en0klWTrQ2EJ#hN3~(&QL_%VKbZGrR<?&V`K+?gA|h
z0iA_V{0B7U?8^Y}xP>zCx4Z*&3PF1%&Vsad9(@VArU<lk{^twl?VxSU$6l@kU*-c3
zL@$s+#86ZQm<wyNy|n&?vP1~P1+8i*1IHe?edlU;;AIq;3kko@Ly*LQQjWIn{RvKD
zp!n|gQL*Se)KCekvKE61>CRU#j%S094{7ZOt&->tQE_<L3GT6g?%V2S%}oRMM>c6e
z($6d*aDOBZY$*e5{LKL|{^s!VC%7{Kc3<-Y#^w)<orhjlfW;ULZySCC#hLq0P@Fq3
zfbvJ_D`={PN`e+wsl(*ESyX&FpS`sC_5VLe`X%4b|NjlYy=4Ch>K`6^nGCuMsPo=S
z8E_hKU<meTexu;g?P%fAc^TAJc){2FgSlK5RE~DD)>{cOl=%8|Hwb{MP0*gHInrDV
z9<7&3G(Eam9~eVNVNQXEmN{PN9|MiTROo<ebI=h^pj}pnJvvXneup&vI00eUekCpj
z!vn9cBaNq_wJ$9?r+~LNd-OtRSMX%9XXiQJ&hsxmz~;Y>K??kCs2anQuAMJHOEN%L
zn}F!;FTsfvJfu?%su_|&8zs-a@aF{&4}eD=+?g2|3~#r-ty8yz?0W~VnJ8iR=yp@+
z=DG1ASpc-b!{t6`*%qVa-TIpzoxeb>i`Btg44%z8DvTbTNBLWlK&FG+6V4zOs5is~
zVt^WqA78NZgUmSiLLKBDP-PFEW7-E&02<ty17bkiY@m2x;%{3E4tUUb)?J@&)%O;l
z&e|)F&YQm7E-C^q_@zK+-W_~#{RODS2I`O<=WhYq2Qr+$<vmC@sL={Kl*t3MLDWH}
z8EP{4h_z;RMvu<l@LcWE4LNVfwezKCw}=X8#HmLdHmP=$zoiT0K(Oz?E0#dM(*aqL
z3<-EpP<eFATmW^+_*>eT7#OtYfKL_xjTKdE2r!iJr18H$`H5fa^e6tfgD)IF!2udC
zJj~x>2QnHmY5WotD<BVmT5K(`API0y?*iJ(+XCL54k|K&K@y+_J7|j5vm0Cw@)<+w
z8JibA+>lDB8|1#uk1t$cY2`3~OC4wtO1B#asGvFcVpSY0@Q(4f<b%5*|2;ZCm&AH>
zv;H%HrtnWboj*b2jJ}6KDV)CpJRk{fw=;m-2JDPJoxfjerA+{tdGp0GP@xX;*-`#h
z(5_cReFF-c5-G#mknCZB+@b@wPY@ma*SA3RA)<T-b*)=B|NZ~}^=?qN1$3$gXe$;d
zI$9@#gs(u<!;4DLGI-?vFX)2H2_C(o>}sGc`Og<Ox%n6zoB#5I6CvozLC5C50+8V!
z$L7C$J3x0?gAeutEz7$BD*8YkZUwEHLb&p!F?enOZmBV7ktQfR@V5&72NlLHDo~fc
zWCW{p<M6a}<KS;i2aQ5a1dV$lN^{VDPEY{xx84RzfNNF5+o1C83|IhO&_h-%!K=n}
zu<LR`O)2mNr0_+NFQ<U@feiu~lMPacuy8Gy3wJzdDL<$O)czFI2?<g0@aQ}YDnG>K
zV42_;e`^O=58P_dZZf3c_y}54x|avEC=GP>k>g&_9osK={)5#g9?fqox?NNfV0|y}
zX>IJFmR$1@i^FLXK;^N+i)H_qp^ITk0zm7NDqOmKR0=#gZ#qKu6N7YlbhF+!0nOtH
zym&4Q>eF+>t5&4NJZRH*4$+|5yKmsFvS0$ey!Gt70y@MHR4;d)^XY7XoLbk}13nxL
zv=;v>XvVBX1vC=rk-P_-y$#<Q-gfB?`0vsi@y{c<1$+RAZ}KJ2@0UFfK4SLkH36;q
zV({&}>cc!m<pyZniFu6*WJJP6MZ*`g4|EFHd~j#y<BJSq&{F=AYS8&Tp!RX+4gNmR
znG}#-@C?uvs~TPgNB;F9{2t9OIb0YId0L)x?7UF=7<9Y?*n(~s6%GFNjEon2Iv;r?
zpYUMr0ej>Ht1&+V=p+jU28PxHB^;jJpq?fJWAjl)>oqE%ajRNAALbMl4G+eD&4(E+
z=cpV2wdh+x3$#3%kDzB)7tom|OTZ<P;oH}z4KKZ{29G2mjjyAGZ{wQ^&;T>oADvTF
zPJqfLSV90F$Ol>1QE?4iU3qjKD^UQ=-ZodraFywMbhC2Dfm;?9%8-_Y0~a3yq$FuP
z0x}q-Fahl;2U!4~+5G6ydF#c&+n|C@j}crAnm~GfCHoz_LsTR{qjd@|3=%j%sgA!T
z96WCmq9W1!i-Eso1!#F~-(^+?hF+)tzTF`z3O>CqDg{2hJm3v$h6g;md6+yqc^E)v
zK>ApoD1Gmd+yn7kx67FV@Xo=5KftF~I(~CeabWW3bU9N1?#T1E7P5jy#zFRTID*%e
zf+{2Mjup_st{BT-K(dfPI=mkoNZ>&VK~SF#yfgB}88;RN&~{YF9@u?uEDXM_|2;uf
z^K$TL(E<LJc_2nIB=|kM-4sA(f_KDtG}>GMpIq5L2|NnnuK+q5F~YMuT*AZh6n`&x
zprRYJ7AUy|>_13gbh~SKcAFgV>2_Dx58A=!*{yQ`R6lEYc7F5h-f92}>28?=p4}{m
zK*AQDorgRR{<8N?_E7NcZU;$w9(-l%!+4?j0lSap1%8*~9<6UXT~reI`x-$Pse{b)
z=&k(^>LFxk9x}Y`+xew4L?y+;@;84AXhy<uA4rL-;U&XM6BsY~ww|n$F+2dBFLrFO
zVPN2&3SJY(dCJrBVCh@O=0l9Wj5k~@Kh<0Wn*ln!&!hP;V~3az<1-J-yQNEgx>Hm#
zK>qgZ_E&K1b{7DxG4|{X2kmWWoyrI*9osd)6`#8XqbDQS6OP@k0-nvT5{#_}_*;Fz
zYQiNvyIUdZTtVtuL7oK#WzSY{vFxG};L{B{<Pww@K?SWJJ0AmN-^WkTX_25t0DsGU
z5EI<2{R~b^ptayED*Ua?psEJ6w;D9`9$@hDGq}^}qr%~8c);)yC|1Gg2(h3Fv}_qq
ziYnZTNKyMijf-v%0Z>gVaEy@wG|X?&9i#v%0So^B|KI$IvB84Dqc=o=u|)J`G&2JO
zG`t%u82DR3JGH>$D3%vW-+`AI!`r`xmq3liYoQDb9-W6@I)Ju`xTqu;UTQty*m;b<
zA9Shp%K}i-f18g=3je-Kmmj@M1RZ<Yu-Af>fq|jK1r(y7<PO?so9v+A$p{YAm!M<d
z92@q774f%B0*}DAgAWIVD+I^V%g}%S|AWp1Y{>@AG#%jYkOiH8m3+dxH{>kn^bHLk
z%O(wQ>`ev5R-MvI&_S4R_xpA`D)?GADu9;u_xuBu<;f@fdwtF_G{0c<)SjpT8jbt$
z-}AU5xW8C>!Lt)=%**Y6pw@!U6Kg%d-*FaZt;l(wZYPAT)4{e%ymp7oe<0acqvZp#
zi|0IctFC%>g7t#;u|U~AAb+u(_XI8ZWS#&@i9VeU8c@lXUf=}eZs2L%4%%VK-wW~;
zDBe6f-3>gu+YLY|9Fn-fJ6a&^D|lOCFQ~H#@gCS7m$M8Q7C}6}>o=$+<Z9q)-3qY?
ze0V8%gw55!v%3{y5hNn}exvMvx(sTow!SUl_Jm}HEufeMx35}ef|;OEsqdi99i-zA
zX)V0~34m3#-Ucy|a>?nR|NlcenJ?RZ{r?Xx%3peeyaLUt+N}nl40qfWyqC(e8If~e
zegZ3l<b3URh%$GmGDJb}@)Ov*h=w0%`MqbiD~AvGK$(}e;C3N=n~@xt3zr4$aYCBp
z`|<n#|6`1dFMoqZzSNmP{U;ZdfS2*$?yCy}13C4p#CdQ=N3LI)N_0HBSyzXNfX>wr
zkb%^%512qbchFJDj0_BDmFpgG1pupDf4xY#0;ycVjp-!N=w$2dl0&c+t=A%;HETT!
zcoZG9nYW<z5`PQm=%m(5by~en|3O14KD{i^Iu$m4;@Qo^=+Vi;2C7><Ef0X|R!H6B
zaWLgb0rNL!2c~Xk2mV&jaFpQz(7+9zY7{h=3u|wH%11~|TDb!p9N=a_DahrZH3>Ig
zG}(h{(qA5+Bg7xRC;{<6s|=3ww>$zBj-W2sO%MZGlY&nAaW(w!(XDgQ1Gb~G@$VN<
zIni$os&Tu6HGI0=6nwf(m_VhehEKN)lV7h6xNV5kKk9aq@Uc9=->VBUyY;P4_cTy}
z;L+U=qUtOS4|sN-bld@|@OCwTw*R#VIr2|s^kuwx;T7nVrqXwy4D7@B(wFg*hvkdX
ziyj~YLA5-n4Cr)|=ynqTRZu%YE!^%lP?6x#?54r!!Po|}09@6%gX*x-GLLR>O801X
z2T4Op&sb0&26X5+IOahoNga1l0kyrr`)V^l1AiW!E-D2tSZqP#B%pOA{4Jp4B0)>a
zU~4vn`CFtw<Hez%V~Ae<{R_{Kw*UVBhnC?b&LHcN3VIJ{K?Ld<HSB|y^PNy%pr`|T
z<fRd)mI4i4OEZDmy8IoW^}!y=7d(1-uKRR*YWP@of{J-qz)HW22CWO3;M47;;A7nd
zDhc^}>_81vkQR~a%`X@|w7a0iyT@@SNb!ErqZ1r2FI{1^3TSl+sCeHDs^CFdd9HzN
zvxeH%2MXm{*_WV+7*KhNVjp;92&75m8czGb2D}Ub8IM@H-v0+uXo9vjzTo`N%K+|0
zwtNS<AJjnx9}NPH0w3rsfiQooBB-0*9Sk0OjesnW0rj>bUUGmWTEBs2e?XH#u^@90
zlMnVFE_g^{DX5}^l(Uyn3q8XFFAsxyb&&7@hdax4&*p=S9?Tt}MCa4#p#cj#4p5I0
zWL_(%@JCuvQ4cl&>|=-t*Dy=~OTKgknb7TK;9=bcs$gm>L7Bj#)6Kx6yA4#iKvVZi
zP+bohp$PG1V0ftrGQZp1zyneN)=ERPxf^&uDnD47O9ur9G&exXeUIaiavvpgfLb#i
z&^)Ex2C5!lJ93e;*vlDU)8Jis&=xhM4m7004)0!H|MUO<3;n;m3?4}3jA!R@<Z|Za
z0*F7L$Ar8D?LbB{@fSF7;3oQj`r`2YY)Gd8H6Lm4=$3U46=Cq{<^2)|+WrJyrg+h(
z^N>$3tFD*;IFp07UxPBa0qDq|1dq-b(D83EDj6U#4Uic4&~}9vAOG?)v>qrG1Z_=u
z(}1Wy4ue<rzhH6(-9Y1`5&<fS!PyD2Cl5BY3*SWYBI5+OfCkl9o4W%fJV2}IT7ozj
zz~*>#9)Gdj31U=+N9R!w%bWZyYM?`%9lM~~TvRIf`#^`mfT!lNK)X!3(*!&^fBAx2
z)en6;55n7bpbbGKvL4L`IXt=<K~wkrpsNWyEf4ze`<wttmOl0c<!^OR+X$4LEn`$N
zK(l%UC48W~Q{icOkiQ2!JZ2fAlEB{rDt^EVm0k!!U70}8!{x`JE<eoQ0$N`J^|ViS
zhQN#NK+w9u<NPg5pj_C^`ri*+XTK4F)Y&?}VVPeFRDpnVRW-P<fF}UZkw*ysg350O
z&~Odtyb93%p#v{}fZE^kkokcZ%pe0>50r{|bhA!|*rfrr>%cFlU9FN}8{jQN(5_}^
ze*nBD+12o*XXgv>fbxrK$Wo1xV<^jB_*=mPY|x!)9*B7$kC*%Z{{N3uKZ0tPmkU5?
z7(5>a3EFKA|Nnz*DgfIA+3xp35MmQ}TpD!7luvhoz>6n8c^M2Zd9?noQwQt!?Pj^+
z-^+6BlOw+X!zV}n2$!o2pw6C$<@HaF{DKUn_dxx!Z9kztZP^O0ahO5Vtsb2(K+^=B
z!u+k$;4Bu*0XiJd15uEAyo4-cV~z3!M-sm<B$C>H@-n<U^ba(Djc_$Ie4^hV;(k6j
zSTh7(=z;8S{qNh$@~2MNvs*+3w5`XZ+2tw&qp#(I(zhTt3W3yggC~MPgR7uTZDRbb
zji4>^OTgy9qsInRi6bhH>!1LJwYQMY1_K?M?9<D8Dhg5(#CUW<OM;C;kdgrP0u@m9
z2Nww$@T*k7XS4OXfXWBZr3?>#f(iuw7HiPy9H1e>7ys-a85eXsIH*MdYn*}008skw
zJoF+9Hp6z9zl9O5^9WRD2DZ!uIx_)02?;ttPz$F27=O!d&=5Mb1aa~Mw@Ja1A0TrL
zPkPuwnrol|A0N;m^~vWwn}0HblLmj^WhMrOG)I0t2M+!&ka|#ylc7ZN<yVk6ygUV|
zV7XAmUCIecMLw3NYTo)-o+=3i86t84-ZE@H#F)mfccCo6$MRII1xV6|fg_Dy?_!zK
z%XOfJ2rNE8QY;tJ`1MZkw}S>A()cw_z)XJZ0h&IZ!^pq@J}vDf_~2wz^G=m1y#$@Z
z2G8$s^A7U2yMir3HE%EIs0sd7Q&8Z8W`6t}9Kl%(bj}F)X#WtE0?<N<=2wiJJ}MR-
z-Mq7;1i|$JY_I{`AM*GPz8<E+gMa-Ya6ox#9`NV|?^tw!oF@Q2Q(WQ2pEcm*4sLvd
z&tn8F_Bi<BYXbO$hYmB)@uVRtF^-`2Drk4DPv<jG%Dx4fLU!ffcHo8dL+DWPQT~?A
zps`s<^m>3Yd%O<^10+&GBVhfZj0_BhCp}sZfO2mMB>#JM{_xRe0~PEZ&Br)=I^BMF
zH2?Zv`T}xX;=ZrE3?ALgKAq2?BQGAE%%x!-@BwttPEhyPp@wh4F#+nUzUcnS%K(}f
zI>x}j(ERs*NnW=L%=zGrx*uB)z}+7IfSCbQWi@LvmaGCb*+7e5VA&K@yfhvGWkOih
zdDsJ_(B1Iu>&Ni;d?5^SV&}n^-ryNn22i?v=>$4)4%93w1rOjrCm_J(9oPsK!?&*|
z7`_G1U4UcfWdyhYW8LHdE~l>ZLCUH7Uw9c_pY`ZwodprU4;4QS65k5Z2|iD^?+Y)3
zXK(0#kIsWHSAohkcz!_ZpMnRcdwIjcKxIk`cyt+FtZW6De!N8mba*lYsF*ztQ2=Ix
zMngeoWP>C<j<<lvs$miaAPLamHK+*E@aSd@7YEG~f{L76P;4CFZ-MMT=>eM!Sxp8R
zAp^HNz@-f<1H%h`SW$7fq#Qc%EXd!Y3EFnsJqK)Mx3`32cd&%zMgEpepa=$?tJ?{x
zXuDbS+`(b@n^ypI5;^EZV~!W|KJzkwRzE${`THL<HV<}W>&X&l(4`9{hM>qOwe^4}
zr`LuP3{Sq;iKf^Pq_|WYG@A{*r2(`siw&f?<S?!^pp8dBK@Cee(ACy13=FL&>nwb_
zgB5(cy%h`(fTPgW@BpHI_3XAe=xJ$l$dTXm0;n}?d9eNssG|-#*3uI+H|rtu!ow0&
zYWIL+553fO0B!#T*Yu#WcO7VjAZQ-&7-S7Nv?252m<I<q;detK(xdaHPj|L}OLu|<
z_&~W%$jQv0U8<lXNI@5dfTFenbVG<scZI@>X(`ZB;~0O-9MB1lZ~0q{z(p3sK-bnM
zp!n-{km-cX=<>HN1~vPVkNb3f^67l}f>jDM#lqhT-ropnB()TSw1X!2S|ULzJ3qcK
z)JBT5W=+OYc3ALtvnqOtFo2F{dI{R_3R<5a25vJsK-#1))GR<7Ef0WqK;L{(;R|+c
zNw`Nh%HI4BAS*i$znl-wx{&r3XuEF(D5-!}L--~ie-SLn&(ORFya+&$zcm0{b%U-E
z=!V#D4?gero8dReIb0JwL2J{}-8n#O6+uH19-YTtM7V>RjK@HSl!Fo=f2-f$|Nmd=
zf$}M6e$)awO5>57q3}Wnq?UjEQP18SRt8VYx1~}q?|>A->LX9azdn|4`CE>IikQwH
z(BRxA0SeBNM;_g*`7YpWpu-I*LgswnWq1iX)D6}iM6^3VTX8}5gSTb`7`&_lt#3EH
z1oJG&_54!~bxu*40xH&nC0<N$<A4VRC}?4+r`torr`th+zhyV5)aZoVo(Gz{15KKN
z4lo5BEB4~mdtL_6Ns?f}Zpeh5Z|6tQ!Q-HnXrOaUL4|F13)nuF&J>jZ(2~6bk4_(z
z2%pZEojEF?b<Yl<lE|gAM#TVh4Vp)Hm;lI7P;7x@6~OWLV%cL*4uK>+P}{8RJud?|
zf+oNY8K^+C5-UI>;j@4L{|~hqY%9oRAd5RgR2+OdUxJ+jc7cnE1(NNcn{;5A1-w=r
zROo3u{{R1_8aPp*j}L;jJo0O90Z&o#YwiJOVHbW)$b6;?zh)13Uec$Rw<G{kLPLTE
z+VHF51U391OAr`9VSOBOfIOHDK32aMA_>Z^7NAlY6rvywxQGUi`a;@-u*;@E&OP}a
z(kygggl_40@!SLyd_CYqkF9+NDr0s)#+nYj0Nrl{s?$4<^S3a<jaULT0&FL&S&6HI
z$-WDmLBZ=SeuIwk0XI$)p+<mG4`?Af%oJF4f#{$f-wD-!l)vRQD6vAedA+#r3~pkA
z8#kbi185?x+h5_uac2$&Ps=0xEuaYmk8W0LM{u6;;1B@KXLfVENP7$FZ-CDKIs*!3
zaIv%q!~%_kLl=lb__s?0KotR~;Q;I486M!*fX1)}EQU2;F{}ZJVUNZmprn9VKY$hk
zm+nQZx_G_OqnmZM1K52X>@fEod&A2BIVsuj_RC<%;V`iB3)X&l=?^-u3~Buxln)>H
zPzA~Rbh|2ahf2U2nY=y%sI5ux*=%?wt@bQ}2K{0FmQ(-!|L+c!03Xhf;sjb^+XJ4P
z_Ut_F)9o$*$*ZLTpsL2Fn>P+rP=OlIo}jh5mM8gJ96*dtA5eEC1eE1nR03WsdCkj^
z#;?cvghPNKjbGyf=zysJP$rM?>Gn}csAA)9;RBC8_JEfH_<+n|0uA?qOa@Kjfl7r4
zP?ipO5dk%82E?o%2(v)Oykr3#jQod@zeN|clGySONM{0nKj{1^-`)_F{~$vmyn1;+
zXLB)tj@b`*A@_<GG-K`49Riw3bWw=_xh#Rd<p5}MsT0&x2W?CRX#}6pAMoPoD^MW_
zmT*ytFgyVAL;%Pg2_T&rzO9$)v_V}2p9379_ys}^aeQ**kKsA+i9bf<&?o-5Q=mRE
z4|p=w$MQnyRo~YC{C&KjLBL)YmH&RdA&-85#)Aq#8(lL%J861Z4uH2txTqv}_qzOL
z@a?Tp`3JhlC;-Iz?%8?R@BoNg0jpm?mh+|Y>z(B90u}q9?i3e)yBH$_Xrmod8o%B_
z{`RXN3!DG2@b}9>Sd9FA7nvDA@#Mt;E*FZ0UV?%Rbg~1#9?z*F9*@owpu@C0Ezgv`
z1?Rkrpxk767&1QN3yQ2JCI-*|fPl(DkQ-zUeBu{iIh4k)aq$y>%!N<<kyq0AHBNov
zk2nnq178Nu=A)piGC6!L@A9|0fve>jl?;#W7?lE#<{Fg<h7u9b5o8gdv7vw$r7uC@
z?gOe)PQEC30n6P-Kut$*?p_UIb-OZvx+bvhdnf~ct08!>5VU7GMkN5TW-{QV#2?Ut
zNCwa5KmUC?AMm$;7HWW8R?F}*5xfWknjbA)R08<>ML_}8>!R}4r`P5vq_{r#$%$Wp
z#R?pxZBrQ-7(jd%s~->n(Cnz;Nss0q93H(D|LY_`ciE;n@$30m9q{0HJ^}B4cv$|d
zwesxz@2Pp-^WuL`#`7RWJim$*UxE%-Oq<}-`NKo=gvZ4n9*if_`1N=W@i(6Y&D(Vz
z_p$t0^ALRT9B8pQ`1%Bp`%7U*v%j1LY7c-;r~$>qDW6`Ovml3qo!4&h@Be>@dqKVC
zgZ%BFr5+yOJ4Jgvn0z{)^Y?;|ON1z~08Ji&^m+2T9r5Tq4n6`F)*fj+z~BEIG{X#D
zy8v#vf|Jn8yP#&z1P{<+rBD2z6=OF*&U0k|AFt}u`NOmGKfgTqh&G?j|1ZBl+kc?6
zWAO6r@BjZlIr9tDJoxca19W{!C#WpRc+SfJsz^FrR3bom4qT2TfTxB*-OHEBpiWq?
z2crknt01#fPJH4Q5CP>off$P)pZEn_tbTmrk9iD9lyQ&1$4q%P{s)a*d~)FzVEW|B
zFTlay4{GQcp7d?~U*}_Z31kq@wKRT>V`(n@dI!tp(;WFVUZnABT>r#>=p|zszsAut
z{*bF_j{Knq)A+*<fjkNw2lKSNUVi}68Q%B|?EIIOAZH?)ac*EPyj0f(9iDaW8MIsi
z-4g^lOdC|rB=EOt{QUnPyhQxP8gv!>t=u5VU!Voe%?B7?hJkh`9C+yu9{&a@?mP&d
z(*gHl5&aeP{w1jB?PXPA6o8)p+Pg>P0%)kV^O8?5q&5IG^uTSvURF*<(3$FoK&4fL
zPcJJMBcyo)YRrL>8b~F${nN|(gaIN2YR`bBjzd<4f!N0(jTsOVq+<i9Wa(wy&L9A~
zQy6@aDyYK>%Aa5*$6Hh`fDUZ~DFa;*1l}6^*<&?mc%;Us^CGCZ<l)iH`iTS5i3Q*P
z267Te0^Fzqw`n@Tx1+J{fvVE*=!G>mL2atiXT0DO)x?+?7(lC9L2Vev<{$F>{r^C<
zRqq<e0=90*VN#%7RKf)eU>#3DLu4*0;JZwxf>$#z^0#Jyrt9{A*QmAruXE^i|L@a1
z1-zonr?*7~bSe|LCy7`Rg(x4APl1+3fflPVfwCcJebj5vja{IS1T6*Weh6`C7c1!I
z=7%q=AA;sOu6uy)UMmAFj=J6YAG}DWp67LX+62%#9n1T5u^y1+PP!n~&<<u7GXp4l
z!B@Y)`}W{q?>zWIVFS3W;MvJ?kH19-G}8;(w6qpHRnmNz5j5x=U|@N_elckM7AV9(
zYsf&Sc(<OclLBpX@4VsB8#0;YI0FNN5NNd*3+VdpkH=ejK#CX`L>R#{5-&8gKzmOh
zsREQDK+z3KeIOcid9bo$ug8DS-arn|UZ0Z!uQ@<RT!Z91I+;K>9eY?_EPVs2jw2j<
zJs3gthXJTk)d00SK?w&k!R@%igNcFR#hWfpPzwN*HUjut)ImMU?ix@{@$<z&4zLt|
z3+S?5(5%<b7yJH$8>ArB8PFMo&Yv$%aB+gpG4<#?{NgV!m<c+;|B?WR2^zcw6@ebz
zd%*GCy#<^Ke7ZGW%zVVl;L&-|7c|-h8d&v7{^oh`8M9xnjj=D|Ggrd{u7<Z;ztso6
z>;NsGgU%=LH(7zU(Eng6mGJ1i;BoMUJ!mte8ED0Y<t6?;U1kObFaGsYj)2mXKQqq}
zzfPXRpj9QFjF(+3kMZ}}FflMVb-T1O_;vFf_Ujfo-u#2nvs<uqIr!cc(4uZn%S-ip
zd^9hC=q(^SW_o`A^%`?{?YN5yWYrt!PCQUzXgvv<@6=@EZvjpDbVK6L@U};HiAqH4
zfqK!`7X0!IpmfrFjKgvcI2h_wJ-YcorQ-|m7|kP(ZbuHNivIxyP(}5(LH&79rhQTN
z05qQHqZ07KB!&}onqlLS8!YH+E4o>=O~LK$6MsNgw{X0O03~vmb6@&^Zt;QS#m*ni
zFBthd)`Hsz(EONuz^j)BGUoc4HEn`V@`2_Tj6TVyKr2Q0*9USm|M(9&;SChNrH@_~
zfwe*|x&d7@(d+ylR2#RP1J4-vs6>GFDbMiewK?dadBLMM=HQRlA|A&<XHqhFG{5Hn
zFP{TXtatN+L*Owe1VC36+=7_|na`|&n`CkvV$$&+uf;+2C*;N$kLGtA9+sc^TT;Om
z^Pw4rDDOR5FI5<L_B#Fdw7lfO?|0$lIZ#uV@e+UMQBXYuxq#r8C*viL)=QrJu9v`<
z?HFEqxg6Xbc3|-AX7}lo@MLE5Y<|n=*~!k|3c6nK#nt=Jhym628UHVUmPoLG4D1F)
zmN_UVB}0Y`Ji2X8fX;4&r5ex{0??g7;5BE4w_7iP(@VYhYb$U~1x*dmq(EwVak~d~
z)(e&>P;UJB;*BF0!%L7?q3xF!(qNaf{xAY3nYX_nNk;WPFT+bEum`}A+YMP@4DPde
zbhDm<s5XbH{tmJRp1@v%(*)}>(8=VztT%sx1_DG=e(^Inf-W}Uc)<xW8+2(gX#E0O
z{R`f`+{@YtGPv_1sL%tgbM^skY-j-wEqL^@PX5Wy;M2>R3sQqTk_)OBK}9vRVgy}|
z;?c{R|C68Lcnf&hG)VGzi^>rY4N`QxMFrG}1#v;e><5roFGL<x!Z~<!v#w=?RHEQ|
z6TD^{T5q;MCBXG2sIdgnq42`?KBP7R6`7#p7eVW!FF~$O17%{62`@NJK!caZL8UfW
zW4GvZkYS+Xk3i$XpsklL&fbKWvll#eyahaV?Ago)tsvM{{{IILSsdnXxe99dgVwV<
zf{$`_1Rdtfu**eA2t06{+X^nj!6%4_f%jFrN%(aB1g(yB>^uUh^FiDGK!ahOM?pS_
zcwx=V$pBj4*!mn)7bH&sha6ZTs2P;}#Rqga$N^7?@(hp8DPO=Q9DKz5;sQ+T8t@3{
zPmkj*UqIVCK#PrDe71#}+Yga^5o8Ayr~_Hl%{z%fkioUrMTHS`NgH@ku>~k*V10Mb
z&X@3^9MEd);$CQFe3ZZC3TT!G5^<nqRoh|B4$z(?pU$5zzB7VDfxq=S$g1QXu%BK`
zya8@xf>)e@PJHi%q!Ppbps{ydW(Gk}d#29^+^#55DRAj7QAq&xH4}WgYg95`JA(74
zCupOz4`_SR!50l~kVz+Bu$G4&&Br-j)YyTJfw<OujL~un*jkTHm&+3TeXl_c&EqaA
z4p2XW{p!*A1MXdBR{_WohM<;y1jt?m7tq|+OHedvykMCG_5Kn5){6h2qr*#73P27^
zKp)NlFMKRjLM$KzZ-JA5Zh-@pwLBm#C9WXxk{9q~%5@7g_we(@sZeN51In9d13nH6
zo}I_Q{SH|F+XFEfu^yDaLB@enIo3%N1_lO(7pIm%eR7Py6|}y_)$spI(2<y~hW~v*
z+mo{Y|Ns9o0o*}m4blUbQtjXP8C*eY<v3o{+~Q?;=>b^+DF9j={1Y@{E%qJSPJxVV
z^0$2d_y0dACCD;yGJuZahYst%@MVSb!4<452Z+B0JQf2g6F{vv&(5ztom;>oL7-@;
z0A*Z|xJUOKa4WbQ60ttr3LqJfF+SbkJ3&EBRF7_r7aMN!f=)pKMO*=Y3#b?B)9uRO
z+j^iP-^cQJT~@E#f8X91mH)n-FI^2UfqK}W90OUu+xo4}!0;rZ{sJ9oI@9C3&1s*`
z1D>5CCq2L%P%qc=oM-2O`uo0&Kf$MUUM@)o+2RRWtloN{g4M_Jc>N}yZm2)HAzlO}
zm<rG^L%|E-o1m(K^@9#Lgx$YF>H*oCybLdQf$IU*s}QN8FAymvkQ8X@0iyphC^scT
zvJgn5!iRtT15ki~x*nhk(Z4t6DFc7&K2S_xbH>YLa7Xv&3(tSx$m4Gb0xw8+g+(i9
zS)lD#upB6AKz%U&7SKugpon#007V@5Qgl$4>qQAOoDb?yy>MXz@wb56pdj6#c|f1e
zHQ-j5PbcJlQ;=)H;@!~hO)?~AJ-R{39Ha{pqmUgsKHU}|4ItY*x+PwmzRt_w3tHd_
zS}oMF2DGxfn;E>+2ee(z)AC1cWpCbppI#Nv1|SAdC12p%TlU}8@U}<tQLo+-wI9B{
zIY${<-+F>)m>fG_R_K7vH|jj#*!+^wv-uSVD5@>N(H;b0gPLTH%|Ais7L{K2Vf^iD
z`MJc*r<>Wc`7omo<1<hK14sL6P_#qRCDg;+Fc15vR6x%>^--yK!G9gpcY?)XiAsS7
z|9WVz5Z2S{WjO{;#~`nRVgMAg{H>t1D7Y+n3A#ZE)B}SQPvGLHBnVX4lyV^oAy7F1
zt{o>|g%mr%fuIJ<jhD@!b%CI{XoL~`tr8$Xq(#{rV7@DKh4kx1i2MRM?*%lc3o1G~
zFE?8-)=7JGvn~K}n;94(rwV}%r-qJqHQQR86$Txx!aDH>XbNfr<WQ$0pqiuERs<x+
z-vT~=q}lf08DY@2c+f!=px(EIPd9IZE@=51sBhgXYWoRv)cj3QcqzQlz7DC;wLu1T
z`=}UzdT17)=B|e|>n3%OE++;47Vurc)~toPA`JX34?!&wYt{v4gc+c{Eo;`<XM`C_
zDm|=On?Q^Lk6zLLANd(x_*@28W+e(9)~rWBnp>N|78$_L*b?Axi3e4^pc`I58Pvd|
zSM&%-Yvm=d%Q~Ndo6fAyG{7am?vIdcE`603bR5(b==hXJx1)kbbA<#$se(_Zg9PYk
zua|4Va?tSWb`${1mpt(41}y}%0h_~G0WsAL%;R{$3NaNlW#`en6O=<4_*=h#GEHYA
zi1&IKw0&xL;3eoTRK$1y#C`>a(gi-94hrB6V;;StM?Zjq`s0hgSHQu*-vU~s=F#oI
z;nB$&d0Lp^WenJj4xr`f9Z<CwVQN*t9tW$n1*sJQtA+ZfS2P}~ej!XfXk#eUY*vu^
zPvE`*R6XLnEYN}Cp!2nA!I8^q3^JxyG!jI0bG%@_0uI-jzo0z?ykZ|fS5!Mnyu1h=
zHAJLekLEWKKE1rGrl3}|i;4?;wS&_Ke$e=k3up~GD1{k#bhFxj1C29+?y&3y-DnGH
z6~0(~g_oi8kl}&WOC@~WAu2AQsP}lW^u+)F9?eH04nxgvH9<H3(R)nu?|;QK-y6I6
z=b`3@gEOFkM|UKLhqdf4H4z4n&U5@z4tiM2ma2#_fNq^T;bASSsRd#m<OH!x)e-DQ
zH3a)9SUp6|Lp2cw&@vbo&I2CSvdUV>JY7{}Uc4qU&k{wSF^WE4O|V@YC-_^Zfis?I
zHON&hkVWFo4xnqUg+PNm7eFj0*wOAD&AUNmD?>?&N9V;CG3USu(4+HsNeH-E{qg@~
zkhDiP(rI@kk{+!GO80@HP2+{oB~ZodqN4G7EvP>WJqAz1qZ4)vp2q8oi1Ywj40{CW
zJblo9R|Su5(Fj#g$e#A-_T&H^@|5+W`z$C|mnMR?G<bB2u22>MpZ?_Zq6i{k37Sdn
zZUR+bD;XFX7)sqhXQnXnw{(I0-g)yy(FM>f!;k+ZKHyO)@MWYgd&U3%-^mYB0Xm!D
zWgUpi1Lx+8|Nrk{EjmX@grOu1eDefESGYK6t^w2#V0iHvWNhn!l2tDxFM`H@Zoc?<
z9%_+3_@WDl78S4-2hbP?$fm=v_9bXe0d$T6i}?TlFP1~iI{xD91zv`of^dgC6NBv+
z28E9SyyNiV>=|hE94=7=EuGZx=sfsBVj3f;%j40_Tp|J*NcR8@2r`$bK*Rbll9&Rh
zf3E?K`orM%zXzhddjZnkg-xTr2Ja_F>)(PF)%bMlF8d71NasMY<p?_V>!@qz86V4+
zklRgtI$ymwdm0pbj-AK(TS0SF9@eJsLAj#kE~vK$*{kpLMF1S5ye}4j74x?&0Bw#1
zowf;DqU_lGM~J`W9cU?I^B-aUR`7WWogZIhLqdSR#TPVCTOrVEvX=oAZrv6hz2X1C
z3sMF6Tb6?>4_DC8U<sFtb%G3kixCq8gG=Yb7gl|Uiv~c(dvu2~bQUOp#?K(<yLaAv
zp=JWwpLYzpV*qTZFn<fEz2E_A(qDo&v{ba)O{V#WFn<dh=n$+QLi{b@^)%hS3?AK#
z;F&DYT0Oy%D38ukP=nv4^M?nPg-IUWaTeesGrB_=K+b5b1TAW5eNrmg?JUy_G8S}x
z1K1*vUp+cwL598F2#GK7_{QtG(E7#$9-l7*LG#NV-M$RXl`=y7Et#M$2zagy)Pi^1
z4_ZI)5_Df6Xvh0e&<=M{vN;SrOB?2tcc5+hrQiuQaQX)+_5cl#Kox^VTtPPvoqOpG
zF8QJM3G=sr4mAO-=_~PZ1ns6|c=-=9pQX)M`VQgB*N>1+VDti2WSt*h^q&H!@{-){
z0)dxGAamjC>A-{4ogX1af_C(;0O^6u#z6c85(KSE0(A;Y1rRnt`XeCsfd(wOKqGAY
zE$cu@=eR2a2srKst^Irny0isRURf6?@b`npn_k+3+yOby6Wj^#K!o&qaD@vFA8;mq
zp(YF);3(+>FOyOPyE2ReUSKhBlsI~T<~zH~KsOtda5YzeB1w;lfnlc*s9QO?8<9-i
z|NsBrS*-B#Hn<}Lj_{YDDOXU5Cs1PO0Wzc8mEqtsCQ!)^GD?`gMF?b+FvutmxKX7$
zU;YNWWD+DTUn;3y$-tlhK8w0afuSVVqqjz-!0^CM(A9m8J3z--fhLD6z-_(Ht3i=J
z`y?o5gRaRAQL%8`0l8-V<BJxsFn?<VGXukm|EED!0%W}K#j2^G#Vnw;vYm%tOa<rO
z+x)EpAg}a_&V2!C_e=$y@&igz$3Z4LK(9+y;BU<YWn}Oc9?%?vN3Uo*R7Wz34%Pr!
zQ2pS}!QbKo8p{Ujr~>KjX5|G-xpDBfw1WhCMWdlcC_s!TN%BA~JV19*c=U>zya4sm
z!B@@9I|fdWpjuJgquYZ6T-JfAMNnDy@E9mW_*+5o4_ZFL-?9!gGjR%%i1}MVX9Kym
zek&0G1>c<G5XGQ#Q(jyLDFKxhttU%Fnk!`l`CGuJdV<GOD?srFsuEt@5CE;Fy96%Q
zT|v!;Lyq5XxprQEx#su(|KJ3A^6&ruFX#OR1#~>5C;<gP>uRtFd}?wIO!-rg@_bZD
z@VObiq6*JJ5%Tjz3CL-n!Kiw0dI{k0==D(e)&#o5nuEUubW`h#M9}e8&Cn~XL_h^Q
z=%5gD&>36PKqUnHj*FM&Ff%$2{tq$$?_Ss`0!o?dIuMCG39JXadd8#MA>+S5r?bL~
zttWXIUOoZMiFST`p#X^m{*J>S^Lj-WJOjD);|l|bICvmT25d?&2WTCoPj9va#K}yZ
z$4gjzy0bz1*ZX=vYXQJn&w<0U*Oy}#s3d$X;M2_r+V<iJx;N6T`4FS!ubMZY>}2KI
z`lQs<!<zN447h#eVa>W4%sRw*%EOv9UkWVBaf-iH6O_EHS^t7WT4X?rt-m=ozhiu@
z?%D10mBF?1p=aj{m(EWwRzPk{?Esxa1-kGJG}sPW31#`c{wk={;%~hS3R+0{;%fLG
zRH7XOi-5BnC~tz2k{~$Ul}LayCukjN=f@X+k3y0cXzj?0iW9sHkZ^WuX9Vpx2X%TO
zLjXQ17NFo|0|jp@*l2hvaR%kgZb%^mYTbj*JHB>;m!a8$iNAI6pa1_|`1g5mbUW~P
z^v0+-`1G=}J>_SBU1kn$vNM3<qw^;85)`<>cR@4bPmc34fKS$i)IYcWfiH$G1x0AL
zwPWXTcqJ~(-+C65KOvz23W9w<{{No<X^$&_ml2!>H9d~Mi2M%TT3#a3{DY}P9o+ni
zi-(<;?+7kUJv)DZ#vX6J&;_eyD!u8r6I3+9#G#sA@_h$2^pNkv1E1I8DA9VLq!iqB
z1P!Ge@ce$m)AB;Sv4`b_Iz11@3!nx9zXyl{EqZa(@ZeuB0GfGY2K6P6SRD2McPhc>
zyMWrv3Lf383{s#Q4=;H1iYh$;6*DJ6mv^l{2I^CR4jO^C7d^UJuS$YDwAUX)I<#KM
ziWtD%6HqtY!lU!_HwS6Pl32r&FSZ>8H%&b{kAYSp-}u4F;L#1)83SsNh?Qi%&;i9!
z>w%JDXd4G|t_(<4xYQohwC;3K(SfYd>;|#Gho2lyo8XaLpwJyC;nD4>@Pa{xgTaG;
z{V~u{j)s>&r*uzy3*IpeQ4DQgf^+o$0D~7hL5^xYP}*yF;Po9?d)T8p(4yN(#wXcH
zrTK+W^ADzS1&`z)g&m+g=>wYPYQ0bz<k9?#1G4AWhu`mzXY&un5=)nEPYF=Cy0)Gy
zk@V;e)Nt(e{O{50bBe=*8#;}As`QIzZ@_=g)(fSA9<7J?ryStlcHl7B=+B1@FL{3d
zV0Zx3-kNd%F@6FI&qxE%BJ;R!jt(rP5gy&9TV4n-yk-NPCmd}6?vhx3EaCC!{Pg1S
z0Z@)BQUB)bz|!sPP;yTdbSkJVh~S@c02G(eafcD@2~exyTLZWlEfEGg1*!zre(Qyv
zuc84ueXH*fFT?i>2Vcm)z6q6w?@wxeW8u;K6Vw~^0G+mfl)q04RQz-cfqc|y2r7MU
zgU%oC7CG+GdZ|(abd*uAGoy#)vC`Kby}XYfg38WUFIo<OIxmQmZ4P@hA7=9C<vsC`
zpW#J1ND@>lyQpZCWO-QLt1I#8O;OQ!ZHXAq=;d7lQfdQHT4D)4&hw#f=hGLKAfe_O
z6%B?GJ<zfR56gQc4j$bi_d)JC?$OJe1=9F?Ke%cwJr3&FYk*p1CBEQ}3;eL1!#=$^
zDjFW0_rUGl=6{SHov%uaJbHQUK>81Z^n;ENefi=9hzUCR2NI;9%Ml%8L79&OG)u6`
zqnDQ*q+{ZKUWV6a_*+1Cyn1vCL2fVP{Qv(yg!LcP&V#o%QTjj4Zz4Q8&wKRpo_oO0
z;M#f4Bl(qY=kXU7AbXSjB|N&r6?}SGUp)W??co=Jpe5qT{t})L;mcs*V=t^gXSBWq
ztuR<{ke9)w^P@{=iHe73=g}7v4)THrYP;PPJi2*ayeK#b8qTZ%9Yb~06C(KIMKnmT
z^)`6h)_G9t71SXCZMN|R^_)Qc1Mq?b&^ZyH>4zzYK<9={Ilys<zZKHv`_JD3y2}J~
zw2c9%ai`(g`4T*31->@x(@r)}#jLvz94jRS;4uL35TM741c)GbIjM_^2Y(Cb&@hmK
zZq`as5%3l5TR~pvW(UprctATqo}fDlSV47evj$_Syk|G;LRe5$S1JX{5TJ4<z~D6>
zX#Ak{Ht2Y7ZN`#kzM#dv;Nez&@U}x=(1vW#xGR4PczmPv8%U)dV@b7d>yr|8PtYK1
zNxVnv+Y)y065$eO#984Ipur-v$sbUA4R#BnN4J9kx)P874?y`Hb~+fOzvYP-wS7GW
z<X%YE15`hOE}@)&7!d}~HBUfHTfGErJDdPH+QLP}19AzkPq&MT$ID0H>W|e#1YFRs
zzQ@l1TC(Z^suE%jfEG@I6zv72OYr$%3Leds0*pSLhwGd@x*a7z%VxSgL5DbUbT=Tz
zL&QP71I7}C7m1+c*~tvfR0`3DUo1rBgG>I`kD=v@N4KMfN9%zSW{++TkLF4X25=cw
z!tohYM7l6A@NaXJZhpXc7<_oxgb5Rn_fNl3aIpqC=e$SfHJ8q#wZ$IYfeN0<2Yk9!
z4uMK&pU#Iq-8zR}ynv;nV<on}txxKzn~yRY-hM3s%HN*dVG=%!?>stLZh^`SAIrxj
zF^-_q96y2DA$_1eZ0mv2o1kP+5(@Pa_!?BusmP%E34E00DG$)b1_uWZNPs}A_gKgU
z2B3I_=WieI^#%%vq;VJ#gRkd<;y+LTbY`dsxC`unx}Tu=jRoYs6L1j>SrO+0Ju9t5
z#HaJ%3)g4R6DE(s?qhJX_~szZ#NP@!dKr2h%8TtH91P#w92ogqdqLBxogZJQUI*=r
zJN&{F6ja^b5+0pLq5W4&Z-u%b&_*DS?rzXo3Z9)mp$qYo0~B6Nh1kd6as|{2>UNg!
z==EUib{6pH^p<EnQ0nZ_-3&T?z@yn2bf!f!$N&#ZZ-x4GplrhdI;ZvYUQmUg&B)&}
z19T8Nv<8EerQmH;4ZFdIPn4*F%mOW@gB~#C!3Z|)WfW*RJUo0sQ}HdJ@&>eN9JE=-
zBl&_)FUw`$ZVwG#>kiNn6h7TxjkO}LebOc%od;243_kQg<T7Xhk9HIK*%McNI>Gv0
zz650qSbG902-eAR8FXBN4|4;^%b)`nppq}QBl_ze-OdIc*3F<(6Zm`UL4gK7C&byn
zqr2Gv)Te>^ss*gYfdSO;?zqa#;L!|Of&^+-^S5w-q7AyI=0)HWJ_b-TPs0NgahBc+
z{C%sz8QjeR8fTzO1-cy^{!akqRu9m5R>%2UK7p!laCOPw3M$V*BYXRH@`BI90-tgQ
zx*G*lq_=?9`o56f!^_~?ohIPf>!;w^dEB$}C%7L2x|(Lf6VOGhKS5Q>-`%_nzLszJ
z`;9?f>vmQEj|EyfOOz;rW~@M6SWnP`h!<eZFTy}hw>-+<o(fu!1|BRr4XR_%6B2(b
zWKbDvV&d-yo&5N6J7`<=1n`357tgkXs}s;J)D|v~KcQje(^(<$;wMb<IArVzx*Flr
zb|k-pCLJMFK`Urn38_?l1v)bYnk0>IBuP;J6I#9@a`#I$(D)cQeIAD%h2;;5CZzOf
ziJU&`BwvD7ZX+d7{vPn~5%|Co9EtQIEXjQVoiznI!l{%O;doH}0ou|U4laXVP6W>v
z!w*Ih0F9SH>WiPC`sELZ56`E{yFg<stQ&Ym7<|CdBl_|Nq=S$Nk^x;4wi2msg^dqF
z-Ge`WxPvEz!1W`nh!PP1E&4h9V#!WW&*CVg0P+(6C!QM~prS|W5h&Te1T9}^2Pv}r
z%-^>cJjTGv%?qyBRBnLQP<?dlyaB4&4(;S+fcSeR_-JI<{1YTiX*Wa84{?TUr$#ET
zUj76P2OzqIk)Y$i;pGideuf=qf{~Xqz+(gi?QsMvWA)>Khj9CKNC>lovnA-{EzpTQ
zNJ$E`rw~3^|MCyS_q;q{-+#IW(cHBI=I@1IkFdVw2FnLQ4PUi`m*Mq7Sa}A$-%g|X
z*ME=BbDfv@TYiD_kD~>&7Y5oO`l5^v+!H$vY8M{uc5^7@0A0<%1X^kOfT{Th6Mstx
zi2a+9zoi*esDUnm===_<QTJQ`S2So>N`dExK}Qm2Gl92^cfNYzy#<_w!R^jq&^&B!
zfC3~HWGjF=g|DIa>td;3n%^>l8lf$qiBXU4$)HNdr}HA{!sfF3d<@;e0-l|RJer*)
z7(E$3wO%UO1FK;quxIDj>zaQt^0$EYf3;q!Sm=>_2wH=9^zs}=I&7#`_;u_ApKebD
zAL~xgc}6v^9?6G5YMNg$`e-+T>yuyqJzz)G!Rr&y0#ii)29!SwJUV}PG#}9bwGs})
zbI>7=UY5f+Y8Vc1a{+uFI8yyGA5@lNuV1c%iXPBL+*Z(%K19Yvwi(nu`sV1s)a~fN
z-`WQ<3v>@LWUrk^a)iQ*d>(KzI1Fk_fRFuvoP^^i;L-UC=KhyWn|P7VCq?XZd&vzh
zU!d`aC;#an*SF2T8Tnh+fQ}!Y4oY(1`Gjty#2KOR;wCrTRZJjPwSp9Z)?<Hsu@5vd
z0qS5L=WosX`~Sb;e{}zb1$#8U0j*Zz*DO&<;Mc5CDFE-+1Qkx8A(qZ_9-ULb+uA`R
z3C&fYF;ok14)Flpb8z=2WRgknh4n^oKfN9_1_oLr1FBxnvqBH)I?Uhl7pw`gLmo6}
z63h;k^Xxpp-*S<W0W?>w02=HDk38K1H3Jf3LF28)@C6FO{4IQ-<IXfd4%GlVR0Fbp
z%cJoK$P1wRd_c7>*!pfq4i9TqLpIPliRDZT4Bx>`cLs(A=$$Ga-J&iWpfT+WB@!UF
zR&M~gpT7lCA4A;vf^7>gXxA5O*=2t4?z}32Qoa{~ketfj3K|dqA71f^U$8{Q;l+es
z|KQ6mK`sTI{pavf8Ku1j8r}Bj7Cm|$7H-U7drO32;np1>0oo4_+I0?@>##yH734F}
zjtCI_60{u=yx+IeMa2fx#S1d%c2Ti;2|B?Hk-wm)@q+AR1@$34K=Z%+E&D;e(DwCU
zKevJ|0rKb$vw#I2WHBCS?FPKC1#J#s0O_%=2QSC-=saAa+wBY*xQqAbX1&P<E@Q<m
zLCRpZ&5%ZJDbg+3kh;k3-~azF%r}9gfBXlJDDMJohy`754cdg@@WT5iJP=!V|NH;{
z^>N6t7B7sV85mx^0S}%+&Ts(5TI^<C(8fK}s~5o$1lnA7tcs~566TW^E}OwI2-=vW
zaR3~BlR%b(hJ-;22f=gIpZEo9R2)9J@C&-Ac)U3E1K|MBSi(zZPz1v2ix<HV?Im+x
zYJ=K0FPtHK{uYb>|Np;81@XF}smEd?+?yrdkh$y57!`*X8AvvOjwO2e5Zw3$WjO{9
zYhF_>(1^E-ii6?F7q&=BL5FF-1l?r#;ylRU)&nK0UoHphL@I9}<F^hTo#zZsdURfY
z@#j0tHzls1^l0zd`4cpx(D@M*qo5O8kGZJWGraf`3Ce8NoyQOZ#GuFv25+7ZG647D
z96%R@?gLHYy?zf1k8tpS9>TsJqU>XQ(L$zuVCyto4G%!}T6=V!dvP-no+6FF!}JFo
zcY;b1(CFdc6wrC{9-TKUxI8*fK+0(FF(;tI7MwxjR-j;lN$|@vK>Y*mcAoYC4S*ly
zZ@B~7bM5Q^x@!oWDL~hDK-PJKdVZkwG~Lb`pe~65=#WVl(7hdB5}=McUJ?VId+xji
zO0Tt2pe4W+mL8y$fWJ#*JbFb1&+{{Y4vy^n`GS8fC_h$IgQs;vLEAK&k2rt=9cg^C
zSs#245^U5TbUp_gSiLCZsA{MVSo}cebHT@!zP=CYZ^Oomk&FioxPq@21nqy)XDnTh
zsI^`%hK)o(=;mMI{O#(X&Q33D!8uTS^P*oePlpfViT@8k^{3&1!wr@U{2f!685kUo
zgO+|XfLENu<_j7uA^gfmknxDSH(m?ez44mo?v2+RApLi5+`aJ`X*`#IJ7XHCYr7e=
z|JL?D1Ajm09FDZ+AN6GmAO?Tp7hwFvFTksH2~-5=ohai6?Wb0`#LuupoPmL%d?QFw
z6~_I<FCeM`Rv7}?FM6?P5=gb&C4L6}Hc;~cq*wwhuXlpK4Yb?<d`>@nzTmdzP1YqB
z`5A7Wy#4a-%`)MetdlN6ZMy%Gzg_qL|Nl1+fGxiH@V4%~i~J1tU*5gJ-vqh{{x0h_
zB%OCzH-L14ZUF%41kD@YW!(!`z~7d}#K3Tubu-L}wg@H$h8>{AG>1L91wo_G9hsoE
zX5+8_pfl9lKnIX`H2(VkpMinD9egrl<FEhqAdWa_kq0y`KpEpOG{{8t!KJ1itNcZN
zP$}xk!9V>F=-4R!=?4@+XF~C^UF2urpMI$20^~k2&;e5XZJ@h8cknSVFdXKWXSl6-
zJ5%5;>)i|d3^z~Res!1i_64w(+b?gP0vmJt_1)WGBT7VWp1l7GtdYN66jZXa^2;;a
zy?K}Q1V}R|JXw#yG~c}m)Bf`AO^9~kn<qg*xdXJih`$|FZoXy#rIsB65T`);H{G1A
zC;2--hw<$K4YW4?1O-l6P2*2UxPX>sH2wq!OB-lh13bTe_%pu%<7a*W-s9)_8Tj>1
zlnL?cvF<+)jaL5loWKA7gQPcrq(csZm|H<iy%UlLnji2qAK(TJ-a+gKM?F&d?YwZf
z`DYz}+lN2@|AWs^@@W25&)@bC#I*t4(Zu;O0@Rk>E|><2$j%G=ZStUwed{Iu4$wu@
zFP%XR*KWa=kVS_KVDBTD-+Hq10)NM;KmY$jbK7BXJ?mk4s9Xx18vfVs00jhpJLt}g
z*SEmKjfXv2FYVxBU|^^`^|JrZ|NnPy>;PS(aJczr16ZEFxAM>b|BXKx8vg&^0ooGC
z?{ny|NAoY3Y&59n*7yq{-RlY7P3zJ4i-Ccmfq%|{UY1tSaoUH|nty<}{M!!nx-c*v
zPMfd`bYIcSW0M&fAmeS&{ugM5&7t|1h)3u7&TIAB9?6$L7oBvw!>>~j0W}{%JtoM7
zBR61E5QjawXMo$It+z`AJ-VF{D;q#(bR!IC2lc6%|B3UrdV!~IJbHNrPw_LnU|9w2
zb{*qy0c|Dn=oMu-1)5(t_(F08sQT7p1b4|m6FwfjqJK~FGeCy}JAb|q2W$QhYP|8o
zFNYB4Zvib-Zau)?>HQx(`wBW#2UZ?;UVKrx64b@N2|Ado^U#Z8kQtyg3ccWajy*a<
z8A__a7nXxZ^SXJj{T62Mu=L>IZ-v~Re(=Q#ke1HF;2q?>ZlD{T`P&|V4v76Hz(4O0
z$dlmth?X;;lZ(Fbw}39nc*zY)WuX1!qLy$!7@m9)vXYnKCB%V{_6PL-at*{;02(iI
zLBqn`;h=k1q3aGovp_E;!NRO}{|JMY&B~sHwEehNf+ksCMuXEWtg?A|0NhY<fZd<k
z_@)39p`B+vyE(vvyN5w7P1FPb;K%%dPEP=>{q1&C=q{9LJy0Um>-HKnu+#?bq%|G^
znFZ=QI>sD+;hhG$2a6lD28j(k+hq@4*TGzJy*pgS@>+>=^FNUiyI#L{%|99W+d$=k
zM>new#0$qyK)m1%iuvQ9gwODLfk$^B_~Ky?=&i#Zuh(^lD|7}Zc%WDe9shc<dIh-R
z=WlTZjR;uq@q;h704GFIu$w`<Rl(hLP`lEjn;Yav{+1Zfy=tF81H`|6fY!z_zf=J=
zJ14w&yd0cB`CCOGq3sV!4!xphjzgR}XF2HnBXHn?;}2XvgU$r?=;f6Gc_&$9q6g!}
z{}1<r76PYDX#OX}58k@fS)uUq;J^R>_d75!FuZ;N8msuQ9P0Eg(0(Za!;>%eu`)7v
zB>(W}W`2FFyI!F;oVoQszsIkG|Cv0J|G(bMzb#y%;a3uW%TrKfCi^Qi|K#9rpUcR=
z(D192zr}$G#K;66d{Elv(JN}t339Z}DUaskj4zA8{@X7KIvX?%<hSH{g_q#-pFtab
zQ$Zr#zMwv4<!NwViN9qL=+xEAi$HB8e()^`9$*Ew6{kQ7e)2=^R_pxrVm(+*30HHi
z1Oq?#Abzk)%b)x$dq6Jj{Pm&-tc1T6v=t2`3A+h3*rQui=NBl)T`X~bkp@;(Y6nu`
z(Jk8i10tdK!WSZ;>d_sFwC0SlRK&wtbnkazh7xYj?2rV1%SNz$FJH(k21lbu=g|^<
zP(x4z#P2)~o=D?wnE_JO&HOSBlxe`Dm|Td1ZD47nH51(Vfvg;f1=Sr63gCwB%<n(J
z=6EFk;BWDT7zHbD4nAjkDF`wZy5eNU-~a!?5%LnWDjgK-zm|eyy<`T+o^DH@UibgL
ztp|KM8B1h5IuCVzd=Uv!(8>IA@}K|z_k&7x@X#}6wzvoi?$S6=8diG-U7vT9zXf!C
z6v)R?i@+fOKCB4T8Ul&&Edq@}gD>|w&foeTG@*-_|9c5KG1jA3l#?BjYF;{k{NMTV
z#fhi?|AR_T@X4Ru!alt|DjA@LKkOz7P)pnZwBe$_qZ6_n4#bH82`jvi&H|l7P-+2M
zsG9+riPLNTC(Pfn0Tf2b6$&pwORqe-nZeoO<vCDAhq&wrw9^100lIVwy#4~*AMpSk
zrIP^~AaUtD2I^&HcyykAAqXCx3{lAd-RG79YGcEC2c0D<1|FbJ1gOvhA0q%_fHEk<
zi`^mM=l~r?Y~ay(5VV!i!UyDJkIs)3f{;#(M|2#lJq>F5gZeUV$bA_k`Io=F85of6
ze|vcvl@D5f<CA>QvH6F1xpMO_@p3tjZeI7(0u0{0EDoS*xR>Q1|27r@P<;z(?>Smt
zD5-XA{vlYB!rx!dz`)?zdH~#JD7oAGORQW1%<jDCarwbYMur52QoEH53_=X09xj~+
zJ3~}-UgW&|_aAg6ad(J{jz@O`c+p|&fl`6jqLB80NAm#|%Tpy1-5kw7B}+eoXCN(*
z+B;zL!H$8bckFd|0~&yBuLIY$uP=aO1<_xEwl6fgBW1daWI(G6I<I!#?ELhC`Tzg_
zEe9ayA2<INf{b@I{{}6r1s%NjTeOt3`JX6%3uq}x^KUT_PmI6iEdv8XZ`ix$UySAH
z9?8B6hL=F8XUZY4vwA~<7+X)4__^?JbC+;z_>sil!U<}6H~c8&Z{YzoI}SKD{KzcT
z^+|SDaBTj;QLgOK%c{k~&)|`K$*Y^?0O&wO5B~KRJS;Er&pq%O)IJ6WfCi{?gRCcS
z{wGwD(ELxh^hLM3!odej)~*Wt^A3RSGJ~`~K{;9j>C7t7`5>SiDFP8I$%kwJ1`h$;
zg!G5wV_&kZ1f6aq@4~<UGP<|hRl(97Y;F_Cyc-LlN%C-s0m!Tq5Ppd=R<o=?X2ItR
zUIZ@$HwVoA|Nr01GRg8F|J(yFHUIzr4+;ar1E5ggZwEIddRY~iAtAxPUgQ8I2ws8~
zi-1m9f}4l5KF7nc`3DR5^r!1CokvR~x;<sOgJhb23e@XZUM$t%-{vl5;Ve}u3%bIG
z0X%@=0SZUQ7{^#dd%g423(Zi_ZIhkHN`kwcWo$wH1^zzJ8AhP{Ru2g<bPF{e0ts4P
z;O_^`N435!5oxHFvg2<7^==#LL9B0}!D7g@4%|Q48Thw-c-;p{pS`aCntw2sH+Vo~
zbN_-<U26vD_JF_4{H-aVX4$r2iJhQfmF8Fe4ZqaNMLc?0MGo^b@Nc`szmG?t`R9NB
zsRuxHts}T?4^_qQ)64qq5LlHf|2`H0N6Qlq{Bw^f9(ySOG81|phDUR?1_OU9Xoa&!
zbF~Ene@h7?14FOte{iO;23Hp41|Hqf1|F98_**W3iow>~C9<G#1qsj+soC>Et<{g9
zW6&pnn3l&&G7Z1ITmx=$faYs&f}8X&K7*G){`BZP4B<Zp@j>$?$4fXt&DmDad;)0A
z7Z+$<3V+KbP>{9$2OTe`k20e1LUBGXgW<QA;Kk~&Gx0!6lq^7NqYOYRs5M@z!s<7V
zZqRwWE-DtFMGV~@5-&h&xIy_E)T{FCeCgZy02=hK=7AdyEpI`!NOuUR1pfHq>pXC!
zRJz0P+sm7v`(Gg$<Av*Yb_TFJw|ywF0xvplh3s;Ljk~;D4KfB2sS@AW89I->oCy*^
z%$v!BTQKn59=n=<h?ZnF{}AJE-2?J^=gk)l^T7EETqCl9RCoS-kpmI)0A0cT3Dkan
z%ip>W)TsicxG4w0$!+QZ!*3P``CBypg4Qh`@acSL`0d5vr3?%$2ORjP9(xI1``vl-
zg#yGZu=&eC5!?Cm1rJ0FY(8iMTI<`=5^!opGyBXRB(t9{ft$SrbkERV#u7RHCeVI^
z=D$q*t+PS5EV(OKIx9Hv&pQU5X6=S@ryP6P1nQf1z5t!YBfpdZ6i@{Sk=`X>k+?sw
z{W#F_I>X2EphxFvpU&eho#&3bsMs)o#yG(D**Z4=WZ`dl0veKYlxhAUz(4<B^AB<U
zsRvpP^0%%9-53jQ*)ImwO@;?Re)H&dcJS!U0bPat60|AI)$rv12?sz11j~SGYa39Z
zru_E*|LzbKo7PJu+TGzY&A+(#+m?W8f*)MvQXajc`g{2qIuCjz^K^MIp8Ef22k49v
zetCw@gD+-2`uE?X^RVFoQ0kWT==|l_`2m!30>Sk^(uu4kpgmz3pfU(i{(#l~0x4Gl
zDQ`Z4CJ(MyJmA9M@%|1M6@AEfKmRrt75&#McS0}SzR2H{^Z);U@P2o&MsRz22WW5|
ze2U@@aO=(UKeSi>64b*)t1m$fjBZa0mu?RU*VdDz?BF#@C7dr?z!w5JFo4#5yLKM*
z?7ZO7dFZ7dv=l(px8U}WhDYZ$!%Hs;`nVVjFM+Oj{P-fJkBg!Cw`7TY^AE`qsm?>4
zH(xY@uF3_^`XSZtu=)<xzCkYUy9;Hyt7O0>{?+Dx;`JHL|HbQ*J-T_X9}-~jNIvF~
zeBA@oY5_G__VEa`o~$%!{wK!Y4yqYFdRg!8=4a^q<dG~g!GrO_{|Aurx$_q2{D*I#
zQDXiU&`DmMH(#81@DH^45m8%!XCPj_*zg@(c(<HkWMBZLEB+Qv&;VRB==xaDfCNGV
zB0PHCAwAV+%nS_8|AqKlq(M_yebYdl!~epNW<m3Ru~P3|xBtyQc*^*j|B08{A@n!Y
zO4;$Zf)5YweEDMEyZ`^e$M3=CcY595HUD7bZ~Fo=@V!X$f5!4NumK9tMYb<a{{TC>
z6*Ly%(aoyy7Tj6iwF}gy=6Df1lNYpmmk-nz1E+*$kfWZ1wp)Q5D*$E)@b{^LjQ=mr
z-y#EM2$zI6{}<zL0aYul|4aK`z6B=)Q2PO-4YWI~`M+@Kk#1*D8^zL9fxj1Yk12Rf
z_zTGh@TLU*7JJaCU%?6oA2D?XD7@_Y2fDAI`JX@?Cuj(x71Uw?Wz4EDMg~wWwE(r>
zEeuZ{cK|n(K@H>e??ICmJ}MTV28*Kte_s%&#|geldKoBYx*0t>&w?9Oos8gxIiRUf
zMo@DZ+==q&d;uO-1I^xc-h6TKD=4H&e8EB9(hDjuL5FvM&Pi`Rf{5F0SFoR)75IA;
zLDqo^=GO0^vcL1@3)#2-|GxyCjtQ%u__sMrG`~o)5$10{2rBk_MXPp!>g)sEB2E0;
zTw!uc!E(HD5V_`G|GQZl`CIzI<<EcqmNo_k2FpV}-MV-83o!U}t8Uvbz`*Z&$YX{_
z=TT4oeKD*IuVvur`Qr=qFW~gt3K~iD<liSF(|Wt|S@TiG=D)1<b{@$vEtmP_89*WD
ztiay~x|;Q+!T<mNTmSR7?gm|%^iHJt9}|BY=vw=ie4rsoaQg7*W_|h!oP@k~K$4Ku
zbZ`<n{RgzPp8-^ooe04ZW3OKPeG7{*X9Y`8jDhMx$mQRl1~O<{U*~Cz7=u(XpuO;*
zbvmFCOL+Qk{x7^6RI2R&?RVjKxnUWrz~6fu)NSj0`NBSgk)feN%Fd(n7=H^m_`5*|
zU^04uT7$0`J0n255<NP__*;2FI-s|MXn^+c1{r`lh#D`y{QmzRlpsn%J-~^foAKo)
zNML|U6-YTy5(u8*>1KQhDq5kb$$2dU!^>^I|Nn<1dX-RcqA&654uvIn(6Ss*0)P1m
z8YZAVZ8zh~AZS{;h!8*Q(ares4Jbu+9(=JAEH3ua65Qi?8HBPv#}%~N?G%3t$aNmc
zUNYcnp!uh`BmcYu%|E%yg?5C3))ZcT(fokXqxl14^8-fLmIEceEeA?G9lM=mntyQd
zw=V!~wC`o**bbWCIq09v)8Wf_!VxsV0~`G8W%2ar=8fMgz~GyFz@wMtpcDT-9){MF
z{GFgHHGMiSzH|mx7!08810Ot+J<%OfrUtV1TFZfwOD^3`GLFqZxXM?0^s*k<23q-j
z5I(1b>D<@Hz<%<W;nU4}Z;t>2sL1#1WjVmVkB6i6B!5Res0L)c{qH|Gy@H3YUtfZ!
z7jPB$`VfK-s>fe%LhwPA<?BUoz9ZNG=;$fvK0L4i;9Y)T^ButrftRmg<)0&@wgt_>
zgXKZ{ixa?0i5x9jFVzWvb}M=`A4!M?H33{07`g*wntut@u{Qq_FMaH4cmR}KeYyi2
zz?*+Ox&sA3r5@;LK5z>NbVD)!lmo7YCmsJ!0<~bki4;^if))UD2gtmLdGh~%=fM}O
zx4>0cLNuh;h^SA{*4tNj^|CNRdd0q-M|?r0<qt;w7SOSd9<3+&`*>MFXC7Yi=)3?L
z6Y6C-wF}fwapa$O$g%U{YrV7y%`cN2cY{Vs8-5Cx^ZE43{@w~I-cGu9%XGV1-gM>n
z0cB?nAIk$J&K}(yF5Qt59^IZ6uC2HEw|PpG902Lxg`{6}H%z}smy6{kM}D76pkp0D
z=iXQzDBTNMgx@!piGjhtH|8mWPv=XIZbnEH@o#g06s90ou$F>NIpEsO(%@ow$dTXY
z0%-4<kLAtMb1s&r_<K^BKqD8I_*-K@^+d0WN`T=v!`rTg-$20)9y{^@u`FK4xpcdz
z_&9cgZukYABQpn7P=NOBO$M#t?1l~dgBRh0hW){vhL&ZZ#$||#k4NX>)=T_T54C;+
zHOxJmk1;y%Z~LZr&ByXPe+%fGWv_0Rub`zbKA`q(w}*sJcZEgk$x<;#a1&I3zYnyJ
z5j3XTq6}W)&(7!pngjvW2cDMq`CH>aSM)W2`=Fp>vOT-mLAwG#hvK$g0=cObv}oS5
zI~;Uz8|ZK%4d@`Y2DoJiS|8aR3?AJEZHIx&If6To;PGUTUQkGAfY#H)3Po`w`Q~Gc
z-6bkMKApcoo@xaxiU3E_WzcxX|JNp<sd{kefr`2~P#YH%dVQc^2Q9|}-(LmVJJWoe
z(bMt|f6Hu;Kf81OGI&_t<!_M%U9R`7bQiP*_U<d_*a*<#=_jC`Yv*CmISEG$54^5{
z)whnI!0_k}5P;n1;@R!)0NVIs0B-m5Z#w{K_=AEMv^Bs2EcZhFAvn`qxCUM;0Xht=
zbt<T^1?{&44d5Cccr6Vb-}eA@E?TyO9VrPe_B%mMzY0*R9yGE5Uc&8Yd6B<wE~uKA
z0J>G<wG|@&ftoEEAYXJNT_?^D-hTn=CAWa8U~q68WAw26UIMCxzA|{U-uCGBuz+r-
zwme<B6V&`H*$mp;=wbQ2^cKQ=(0c!9!*8#RVeaj`^<u{tPz8hB5vc^*1)3Lv+U05a
zrB218^)`4XWl5EX<;~KgU_17M?C`YwQvV3jzVPV0@sbA|{h%5KbPf)d^aHvZ5oUig
zBcn&>Y4Bnh(EL7V>l-*dK{_zt^6O<D*g$Z4^MI;P2MdAv8<^&MbRK@m3@&gTAnowh
zeSiP|e|ZJee+S)e4BDiq&B)*S1XPj2JLHB3UIv3AwVTPKJHq0n19-3*wix*JS?~yY
zi3d3Uwyr|g3A%s`T%H@=2A$c|4>~*Aqnq{CLvT~bd;_E@#NP*Q3PBbr!S}VSNkbZc
z1=R-%hPPj&Tmh#w&<Jlg1OL>+pll1;=GZ9+Z=Qk^mI9~*M_S(l?H^lsfcIgX^JuQH
zVBp^tAYH=Q{D_gi6|{uGBiTdYh0D=D@U>{5^VJMbzF_PHjpQ5$Eh=rUkP$3#>CSTi
z4aGthpLD)zILF!<=HStJ>;DAMO43e{Eb^fw>7aEOlRynsu*<;v#}0dRTEo`1cHRJc
zK)m#k2l$YZ7|^CN_#q{rF<Ve3IqcERy7&P&*eupVg6&2RDA<q`V9Yc&!TTp3-K?e{
z-Q657HiEUiECi37+<fuq=%4?F2VR1X<wgo`0^tQ7lmdm9$Pq+%-2kmfV+1XBJJ(HF
zkQIW03>+tv23f&<aFDUCg9O>qZj>NH<bP1mgRj5<9}febrUf1U2XD`KbhCcFCk)<8
zRtPrZC1?Z^)M{UJ1RQ>$pjB-M^FZm<q4}32sMigfUnvo7y;LFCdGW>ki_k>uqGD0v
z4r+#2>;iSpK*nu84C;ea7=lVz3(#z=DX4MZ8}Pr|Q3jk&1VMY#0y#kYVE=<xF6wxI
z)-E01Aqh%iU?#sjWWmep4{-ORw_iLuFN6Acogpe7FA~~8BYdFJ#i8?fCo_M`XHXn2
z>H-h(f%en5sCa<RR%U>l8iQJ9!^*2<9~B3WgAbWsFdagq2w_m0xto=L9q7a_Uk(q@
z;FOC>K#34&Z+O59`!<lp{4JoE?)Fh}F#Ohfvd$b_UVyfubiRDyn#s=K(aG`|RGM0T
zuYcL?>R|Xym64T!!4^c6ntF7*T7cSqCEB187F4Z6%UkH|vjwzrwm_Itch#et=d<CZ
z7cXvr%6Fd6pqb>-`>)S<bhCQi1t*sut0Bpytdp1FC1^NtLU)LYgW&<tHS4Qb7#Pwf
zcpPUr3~GCT`dpUB>py@!<kPLY;Gr;N_kgS66VPd(hTlL_RN%Wg9XpSM?jf{*PI~#M
zSom~4dcoWV+Arb3;n{f%I+x1d%E-t7TF`js4(NO`&<wsux9Ish!VE9?TEPL<3R-dD
z2|BLEnpgccND+9)Ww)r*ZDEENFIymrK)3FI6m>U(w)24IRT=qPK`kr~Yu><HAYGuF
zx<TR+&}G}!ysm2n82DR2eG!jtQH!+#3@>JbO)D(~ndD*ZqY_XO2l8viizbK!_^|v4
z&}CYhI-qJTL?r^$A8Wl-BH_`^1WHs1@F4^y{+6?#C2*~8`CC8-zjgb{7+!iY(F(MM
zBS$3y6kf009lPB?Tf$a&bbbPvdRZGZ*!vAM0n7!OwBv6{1ceUBh(^$KJIDx+&UY`o
ztvDF`I&~g<g1VcIoyS2t@%URnSLt~+A7ON{e9qtB0jkEpcR;vw{_^O~QL*4}nFwl7
zwSFtf@4V0*qLN^Fp(GXLy@+l<8OP28-9a)hf~+|}2bQ*gZ<p?NQE~9>yaU?#)thse
z<FzEL{p5L^MFo@|Ko>yzT0Sk2_w43T0cGE3;MDa1+6jMs9hzT2_eI|Y&t<wAKJn?c
z&A2bj;MjQ#bWcTuM`wwO!)qyUTO%3NVro9Z2)fn+<cU6z?|nKSfm($pn!z~~H07D^
z+WKt=I7e{#TGlc^mR^FIS<ofPu=xPcISAl3;l~%Nf*2S)J6*w75|>Vfu6O(&VBp#9
z%J8}w!GAdcwEiAxGYM!41LRH%&|!-X&`ULB!J!6?aSP-a2iJV?J+b8;pq-_L-yr45
zYXMmJK{9xq1So5Qg6%yx*j~bd?E$E0wAc?WX)AyK|33lRV&5SMDq)~)c2N5Y)b0jd
z>HukWcZ2R^{|a(Hl7Ff|CACMl6Ng9VMbNkiXt@}|Kj6#vJi2Q@cecc+K>gUw4ob)f
zZ?W^Y90HZLpgqnlptd>m6a#2gF2>(_1-yqQi~}6Sh=CD{m%G6d@DkOd`3OpR`qH=+
zw0eq-(be$DYiUG%;&q(mF*JRF5_6q|S2qvnp2-sQ^aV;h5j#M&@XJ}?)|iMYNFQj`
zYU?HbR-0e{LFe!ucToYCNuXLL0vgCKL5na!CznQmv)<1aJ6`_(@7XQx*?9z1WLbDL
zzhVTP-rXr)BI(naq7w1)EvQq62uKw$7j$zlWYGjf(TP9*|4)FPk73}^Z0lJKItH@y
zv`6Q4{+3p7UcSxW(g4bb-QFA?*1TJ<g36}TAQ@|3g&QCa=;}=mYu?RZ4l`J(=&j|T
z)hicETwnaC2NigwpsxIjm?l`B;BNsHd!W@444{0{E$0C`GaYo2gjk8ANAr*WprI+q
zk#FGs9Ph>|aM{0UIc%xgi~MGg!IjHBjvoMZ-#waP%0caGP~3u+Fn4~0RxuhNLrYh`
z$OKu}dZ6Uwi+B*LTlUR0VbFp69^Jw(V!<YstOKnX>HPIVtQoSW%7NiUGFYuM=zy36
zaL&&I1wi)%&{jy$qE+zW_n^i<<h-3@{4L<cKb;?6D1yA)3|en@n7;+IA<?7x_kaEt
z(2_!rZr<CKU|;DVd^NKP<SYIT&^|*@r3pH3V1h?4@62WV3@>y*hJl8AkMXx8gUZWZ
z(e`DKb$yNvphg{Q7sx=+7R*-25=;0}HIskf$tY<5CfOOZ_5pmN9;E-m8wk?aD;l&6
z9=`lgmw+~HfYy0{xB9^9?*`D;6wpGG43MuuX9I$UBU?eI;lIoVxvUd34-c~7rF<i(
z4uv}ev?1}uV~|+u0sdCViIu#UE5PBPg0OvJBRCv7K?j7r1a(wAx>+5sf}-jdXdhq|
z$N)&hzq}0Ic!+lXipC4|zyJS(wqZ1YXQ4e94|!OgDrW_)4gj^*|6T#x$OQ_%ZjKjP
zjnMsdukZ28!_G$mWrJ&=<LW%RMPDv~BxueT>a`%3l}LMZ%7MyoaBhY)^Wp2MA>}%j
z%Q8U)<#``aoq52clMOrp4&5t#7`Z<Mo^JxRFF_5|&TA#{9@e~1ZU{4!gh5>s4R_7V
z8nA2lA<h6f33M#SVUKQJVTcdim+~`!nxh`woG)A&cp1P4v%u~T0IN-#0MU#hh_XHb
z-run1jlBVigL9x3>TxH~p+XGDoirFg<@|9c(3)k25_6B<Dhbfcq=rZ5FVD^wFaCi8
ztilUaxoCKFI)hHKS$7e%=**3yM8yNN(Y*CQ2_M7};8S4YV-I_D77M(71FerCcUd|M
zyuJoWe=jcA^D;ChYyAKH|Gy__pZ_n=)~b16dn#ub9(cV2l&TTsGpN0<;9<?X;5x|h
zmrE2pdPO~!@H4ysC7sSgoy=gnn}7W;5eM)3haC5EoC)0Q2cN|F!mu7(bU}`Tfha<l
zk2IfW;bF~dd0m*nv-51{b)U|o{4M^Vq5`zq(+$MvcI5C$J_Opx_7ZZU3k&4@zZVmh
zf%ad&d~u@+6rqltNBBEH#RaIH$WZF|64ZHx_ZM0ZRD^aOI`~Sy<r04@XepZI5B}ce
zpgM1c2jhzd3kLpH(2abcvk;CkFgjY^sVnj9_PHzJ(JNZHn4jUr9ngIDkN=&=O1Hj<
zsDpT{wH>qyh{gQ%va|^=n3wT^R==t&1|2H#^2Hjc`osJ!pew*Y{Xft}RjvO^QsK@3
z^)Err0FM{WIOf92zz7aiNY;QH1pu4>?5t5yaP0gEnkMdMEe0ipUQvm~kXHSJTI5b3
zX!Pmugx&x~(Bh=Yuh&B2-zWL_E>I;3YG*|(<%1kIfnt$IH>)(n+}DdB=6Yb73lGm1
z!L{H(C~bq7-^(KZ6136**8YLJ_r^=mj3e|sjn2z2s=<-PKb84~AjAah=>wdfH9$4F
zN9Q$2v<vXJg2p?KF%`dvs{~tKlF7eKpyg7DONSW$Hi2HRBMm>9%Crq{H~gw8QE7g3
zzu}h?f9oX%28Ls7cA!alj4KRb!L1P;2P)yDFMvxp4w(OIco|^+L7$I);atJXaEz@O
zG;q^-_{G@@h=U@)4&rYGox}jT|KdE@!0ihm0s6ffr0RCbCeY|o=^78DF)2_X8y$Dp
zv-5yQH|u1Gwhd5i3^ibFr6&y!yabKof^urZFP{?LhF^ZAV#nBQ!6AQ)&E_R&Ko$}o
z4Zl1~IgYW_ykz<R|9``;;L@eX*ot3*j<-h&EB>};pk4jHYWQ107qPs&0Uk^PkH29H
z{}P`UzU3gN902Y5GlLd>od;i>hlrNQ@^9m4Ia%uD(an0{9N6ckP%r$g0<{9Q8B5CH
z0ePH>0n{y@4AuJ_te3xKG6MsH;qB&!_Zxl&mTE%nXvK2<By!xPO=$S(QNr8s(-))#
zWbo_L$3cgMGQ5V)uXx}JYjuc2Qx-s?XbQ-opz&Tm$gCRZGD%Q)dvvq@Jqz|y5>%yD
z6)4xe1TDtrmuG;M_s|r36`Ep8B3?+B!9&avdH^P<4L1iOTp|xHdcf<~yIE&LY%qY@
zZ~~OdLHnYUV1X7N3o8$xp%)4<#<TN4$!(BHEuiy=JbG=V7VtBGx1@S>9{aouQeJv=
zvsytc;D=hUyposU^<v2Q1U!6RPXhb5*Y?_cWHU-tVXg-qd4Rm16I`r-*KfqfLKE<%
zGvJ_FJ|7aO_LaO0FF}LBi1Ht5*z1Gv`igZfM3WIz)2Rw@_=47F!rB+m(1n!;rBN?J
zOTnQFDP*B3=olge`IM>?nSvUA29@SPlguT4d4?CsC7{;fLC|GYA3)63110QW3rd%I
zbhCau4ff!>c@PiEfwMpCL?vNZbRn&0!I}P+Lrl5?HAw_wQt39s1Fv^^bhCCqq+6lV
zTgyR#@_NApaQ;NJclcXuK~<$S?}ziC{srim6;Rm;IhF@BBqG4y3OZE-#N;R`0v&9`
zP?zn|>#6X9Yd#-?2k59b6_0M#ji<o=x;78irUkVeEy_XlD}RRsXvxYpXNBem_idc{
zTXr%qFxa?3g5Jgvvc}cMo4*xQ-yLTIWkPTkeeD5GPu;Ac5VNIF%)V0wF&i}h4{GYg
zlz{o5b&dx**<QSbq;Gf~VF6z8?83nC;&2ftem;TbEjkar0IfUm=tkNjUU~^M!vJo@
zb>4)IE56=`NPl3bLDL4f0R?HmctF@`6Cg<etm<_;xIe}E^&~iK<e^caRR)TRmyihx
z$Qap6@R>Z|{B#_&kncZO|4Wzu|Nled%bM38RNi!6E-?g+3h1Cl5=V(H|29Wh_<|Oh
z+Jr+6;j#%TEj|wFC?Z$fhe5F^P~!4pdm$(+j)7L5eJgnk9S`XOjfW%m5=&2dbccb*
zSt0#*P_y>+R#^V)6)m32&+y{QXV4*!|4ZVVe=wDKd33Y>KLPf&-CRgYHz@`A8X8Q;
znLv3T;z`i4$6ywuWP+-Iw-=xd#+Ode`J5NRrMwKU=fmY4L!c$7f=BB~@JQ}um(F7)
z0-ykbZP{mFD~$kq?&S;6RRW+i%L~qG&|{?zH~(X-Q|S%+=h5rT;?e6fnFA5u-NK+1
z<(&b4JS<O?egZob+$05`X>~Yl!V7Is7$#o>-L#k7`mOG+OK;kL!~dYMw$}on_-{VW
z=+S(b#mDk_$wBZ+(w8qJKw6-E%Mws%L-zK9wpld)VD#u_EA@g89I=5eJBIb>UT>TL
zYKQG8;AL<GSNMyLg9Dj=4rrmpM^K*QDS?JF%x?&j_*>aQmUY8Sd->zv|Nqd?^8kgH
zN9R@0AT8uX7uaAutVXhU(U}h}Gr^ngyFo2r$gM=68GW>i<H7A?=$fa)pkvStz+?L_
zuIKYIv>vDk1dWwhFxDA^2F?ulx4ALd<np&{W?*2bcLXiH1s#EElU6F?(Q8{Wo1bAP
zXnhW-GI|QKw3~J9F|enLW<yfets<z8!Aq<T+Z032&$B5lz3kCzs|zv!w1M&SveLuH
zT|rB(Az1-@{2ORLb1*b%!*V<1#tv|e>B7L^(QEsB7C!^{?yJwsN*kc{4>%#b1aCv>
zwY>sT0NM`uc^PE4)^S$`(2@j*qR*h=0QmZIk6zpLAmyNCBOv8E|Ns9#?g~1M66!3_
zr0Q{3(6v@jfz4?8MVV*uGrVm109q~uzHj35On!!!OWs2GNc|%X&(1U8y>UlhwB>=C
zQ9u5J4|oFgCp;`)c<}qZFud*2`nF#FCFs09Nc+#D+2;QLl3)+ey>OPV`CB0C|8Id-
z-zI_#0Vms%V2@tWnwgN{5G~M>tWK8uC?}YfZbu9>f{iR)`yvvO>`NAVbc-H50_q+f
z^yn6P5mX3D6s2m2!6oo^1#ou+bU*J4ND~*@t?}q)T?^9NE4mA0e>caATLrufuMff6
z+b=#BfKzD+>kCPceZ8VrW`KHD4_`FB0nPn`4vk<h5dudIioq{-K{WEW#{U2RA2c=r
zZqJ5;3t&)>_8h1{>ja&h=K(3Ijyr*_QDP{md7+*Q30`p403U_{>bHRxj5YsIs4oDG
z-lTc-@_=>)FudS|<s&xmDr(TcNoO2~XXg#jUI`n}KFlBgOV~YTcv#*jQSj*Id+`7i
z@Q^wOUTneIb1;v9vio6BdDAThz7oCTFgTO^odK$l!JX@Fju-Fqp;-m08kD{}f4=a@
z1I0jz$WD-dAct&*gNs{`d^f8p#HgYfko=YfHsmF!-~zRGx*=T9emih|-TX$wH~GMe
z6401y^AQd7^+O)bZ#0@;`8NO3C^zxwWqk`W6t<$)qnkDJ5ZKveU}u9W2~e5#0ph-J
zkomCLJq>94y!j^+<lJ!nJ{8bn)1NFmK)xus)BKYIyhXX>((BV8wkQJwL+QcSN19)<
zG(Y@Zy1kqAV5%@f>w(hF9iT(JU$2Iw{~e&i-Cxgx*DpIj#}I=zW3(`U0C=6?%WC+1
zGH5wRE2u6vJn#|}2F*VOz+0^OTR=hB{8ItEy_~-Vw6d@HC&w<(<RoMdyX&EsCZJs$
zpw;NtK&#XHKwTJ+Q$c(5`CCAJGLUJYoz?s;od5s-2k&M9dl=N8tqW=X$pT(I#@_;3
zJ_gbWT71Ue0=gOc<z;Z6i~%Gn1~R=BbcfPQ5YhaT5q$Cif6Ero<pHZu$`_C%DBSs5
zrh_Cwt5}<VGJ$uc^S6Kw*?U=qq8_rm4Kxl34L{HU0pQKMP(J8<0?6G1;Pwr)zR~bV
zJ_)LBI#0jI$^>Uv(Cm$A>+L$@-s=B`w?R8RUkifLbEnHa2}o)5yF}ch+vhIB3x*u9
zj?%}Vd9V^b(4wmku)KU2TJ9Kr1Dz@R4BFoH>~?Sf4e)hy`gET2?K}vojx;<veN;65
zPXOQJ*d3yx;bAFUA_6{GL%4+1!}3!(JG3zZ-Zk_36WINr^b0nvo71=RpsV45{}Vuy
zkf1fxQ$fcUe+RAR0VhsKdO?|QZhQke8W1!ac-FJ?icjZZ*Uq!82TFXPLyaH$Ap@WM
zFZ41%IkNLuNq}QFi%NH>gyn_$43Fd!9<3+q<b1ka6$}qR+h3mDA_qJ=MGk}JUqMZj
z_lDm(KX^1A0a*lEE&(b=!E1`3>Y+PPQzt;I;(T#99b{FBxFdAp?)3r3P7#&P3$G_Y
z{M-5RMF-e5{4L-MEIVJmu*d+1KYz!4aE0v3(G5N*@jGZLh=afNE=bgx)od@QM*$k6
z0!s++w}LLl?Cw#q0IkV7S;7GpW+`p+=xzWl7zGdZgBpg7k3d%*@V9_BMKxC_Fz~m$
z1}`WrQAsd70PdYS?f{L4`gDHx>HPHBV>PHzv>4*ZR?zh_p2;FA-7PAh7_huh%kJ38
zqT-Q!0o2UB<kJl~2DDDlvzzCDM<)+7<PMd-_v!p-`0d5yY+i<!J3(n2?0;CW7=C+k
zGK-ht<@|q;yOTj@Pr8DJ)j{>ON9Rk!Z!Z+nL9J<KkPc7|dRg-C|9|MI*r3DBU%p^~
zII#s(!MGY8@PUZF0!IL7g>f3_ZieJ6UeI`8%M?)U`tpU$bm&glW1tfuSvmJW26Opa
zSV6Ntp!=b@peg=;0O-c8Sg5`y)8P6HKzB(&nsEyJt!7Ytj^KlMN`(=+U0c8LckTt1
z+r6T?P-9Bdz)=l47OVwy^R`EKg@8xve~(UU{+9coy@}l{DxkFA0=jag`2}OAi%JY=
z=P|@OCVr?UR|(K@wcRZ$pe@}#y(KC!KE2KyuAMKzVc?=-(A@$~7NC_U-7PAhzy;0F
zzS#E%v<QU1LmYIMjEhPP=xny;|BRpr<?lNOP83sAK<ik+d-QyJt2j_BhpYwwS<dqT
zbUqfyc304zt_wb(N%auW$<4Se2c0hns>f$BGBAKvamM&`hp2dfF38sQ0F8QBwt%fJ
zEi*h|c<D92XEzT!XsM}(wGT5#X>#)+Mn}sFr7uAfx*nF_`CCB?i@G6xaI|JosTBfU
zSq*a0aduF00r?5MhK#?}5<GthUjGFy#$Iau0X6Qx?GcY|pRW=x^+AJ7mpVgKVqVV&
zjmKZhfS&*V>hJ&m-2p7Em-svG|NZ~p(ON{MmIaidJ(GD<3@?FhQE-s(?Pj^))5&t#
zqxle{hvli7*PwEgzx5D!0vFyp*!&xGCI}0tR%Lhza=b^csP!aJs{HukTRJ#dfL1!T
zfEM^8QWy(=%RJCgn%(XKAYVFm9s}9WqGI^pvDrq2p`QPBiDxp43aEVdu>4V%?%D10
zU*g3&STbYzUHQPHn|0MLa5LcgL`ak4J4hNWtv8?h|56C-;#vlzQ>Q{f1M=XhWpMa`
z=C$8|xZsI8slWgKzvKp`@NO5C0w2(_Qh0WKF)N*y;pG94+HO`Zkp0~pFV3Zb3&+VX
z&VpP3O~0TF&Hx%K`gR=Lod91z=+W&f@e*V{xYR)OA5qGG(3$X^ryV=5Knwi;odOI#
zoyS}{&w}pM;(lSC1hTI4c!{P*cd$h_o28Qizps;m;r~uH@BxS5C38q6x(jF#@{<yE
zk8Wp_GPqRK!<u#5c43AR9#CP*AOKm<-}=_0^JYmbNHx4`EK%y){8xy-1+=>6#rh;r
z33eE~MEEkO6z{zGVl_w%d9i7!B4~sJv<?7y&F^b&NPYjJ8l)b4NB2aK3CUs}mWMp}
zeJ*s0y#$?b=Fxf6)$pxrZ;i_T7atO#spwd}6!`ck(Ea5<{+CpHHXmj5wS33l0vZef
zA2)mR#bcP_BPG$GWh<Qr9Xnrw&Zq<}r35cBfgFJ1*(st@y3?~eL<Q8Z)9~qh2pPrE
zc)bMFetf~4%FFO_9lU&haTsK7=i!&2zA?W%1LTgOKDaz$e8Hz%)q4x5*8=VWbYAu7
z=6}J~%g50C<A3Mj5@r5<Vl9_SQW}0KlxSOCD6R1T-8g=X@x|jFsFKpV$O8wk{z~UT
z$NyJa50r>|^t%1`uzcsi@ABgH5=8p(=oSaf?;d0HXg<pL!mpc;;dL8G?BENhZtz_W
zmhbqdf)2;|hh#cLfnqlw!;XKTE<b2q4KiSXb{@D-x28|GYRP8MB-%MhU(u0&TPcH2
z=WB<SZzbBG(`;EiEMFHZ@^52rIZ)zcqfnyjVDX{U1C)XJw-tlNHW(dRzLj1DH<CO%
z<q*yQpZM*-zwaE_hou)mT3)X(Jm6#b8tUZN=O=(2`1&}!y$xz#feuag?7ZmFEns-S
zr`w6c5mKA5fX<Dt5@0If1~vAe?SGGMFA1M+N0=IplE>gN%F;U?-9ZW--Ci8u8bLeo
zIZ94LHk<o&o_z5m9+b@>Q^Kz|gHi=jc!Tn2uV_;*KlqII08mRYz^BtkB?5HhyT%J0
z(4}(CM=W6dFXaBVNB0&LP$BKpdDx{Ja<8dp=P7Woo^@>gA;8}*2pVkdWmWIxXK?8}
z1m8*sYMFeiQv|uhr(4>mJDCIAoMU|L+bQMSnZ)7A_{+oc7^uAqIpY*m1VH@{(fSM?
ze*D`&16GV4jISL#grNFfgTf2e7zFP#{Z_XH+8zXtZ-JF}!j!+kqP&$KwjUg>!4s|l
zi~0P0kTZc8__xE{ljaE506**$>=9SPCmyZee3M`B_eq0NYv(PW&WpaCFJAoU;9~#{
zq=Al~Wqj?)_{+!gS?L25*MZj4ID)%GpuwTKB+%yG5`D+!pB$wLpslE!7gn(Iw}OuI
z@@+j(=Ls6`Vf5fX;nB(H!FbWL`2}O?yVu50h0Oe|pw=o#p#nTSyBYaUAQXRm&F0wr
zld+T~IxhaOOXs<R@8n$=&t3cn((}eQ`DAb1e~;v2p1qO(Jv0x2(tGPSk6sqZIvcoo
zKD{!QF8td#UHG>NfNoU=4bS;l-gM~*{O{7?!C3kj<S5Tx9^sNX5WV$hJv&ds1WRAP
zZiTv*k-v2#0|V%mXa2rCaBm%y^cd0(GIGGY_W31fF)nDmc^~M^TyV|Azm3s_f14+B
zha<B~2PgkFM=+PE!;#6Q!xJ7TH^Id*Sf>!kY=|cI4o7w*O>7;GY#>ei+Z>rdX0moT
zvbuD5GVyP7WCrnBIviPCIy{+S&e{3$*uVdvvtjuAz;`7eyN9vEk<q1t6Q=a#%h}-W
zs{?~)@&UwlVSccn3j@-6cC`9c!>4-*_zq^5?mghUmpz+*GJ1BN_2|6p+Ih^U^Q>p`
zkCGhFU~IbKHxJNd$S3O*JU}V#q-W=k7j12zIgMkCo}CAM7$18w{`9c?TKd4X^?xa7
zwE}!x3f!TB)OW6(A0f*kKzoUxlUblt4N~$l9@G-*`~f!qr4Rr5qc2q3_!wTVM_OMF
z8h3>hZ%m-#tx|xogvSu+zMGe?fBpZDq#iOJW#G|y&7)UTxf4`M9e?q?3)<K}%-`Y-
zDq>py^S40P8+vyB<ZpQfs)~C>|99{+fLH4ud{Gh!u6y}gbV2I7kv4bmw={uNcZ1L8
zjco*7BzYLrJmGvXBN9|@g09s8b#g%~jt+zFpOxJRZmg~9fHc;;VnKsp+KeSBumdH*
zDxu{K_<qLgAPag$^I*=o`Qm8=Xyp>}Jd6moRtBh#*qR7x{N6^Le}tS*IRSJ(0jug(
zuzQ3+?&&=Eq6=g+sHY|dDqOl*(>6esuYZaG`KC11qnjC&38ANabsF9VU)_f&?_}?S
zYkjzvJ-S(yp+>9+8&R_N#kv??hL>8P^^~CHCI?@LMes7b1P$%Jm=Xi-&ULhd8qPOg
z{0--2cqt6ZQn2zARNu5-0xc}mC}9De4hpJqG{DQ?U#y=3>i$$nLzeTj9w-5=sj@f>
z?gGC^TJ-P#>-UBSUcW|O&xDd68sC7nZh#gL^@>`7U2x8&^SH-x$OYpJpjbE#ISUuW
zelg*~pZ}l^Pd|9C`Ty=Pi4wl%|4b#E*1;0|EgYZ~%iVqoFIH}3XXp-=@aXnd@aR1H
zV%A1>1`o@l{H@B&;Dzz6Z%d^>0}u=h46r%}lo_D)m8;=N&>RD3M3TX=^T#d?0T%F`
z4Jyo>pvyo(&B_S=7G7r1wn222OyJ$YznI`E6Zl(Hz^<xMi2w!s&lk1jpf%J#JwZ#%
zAvN%et|qV$$mEO{ds`u#ZjBd{Iye|W>su2*I$cx>K%=jAFzv@cx3Pnk9KP^IXs>ut
z2hr}+t?(ikq`eb*ess69g>UPB@FG&5<O~J=7F#Az(fp0S#RPQK;PQIV2{F4s-8}x5
zRiKS+C%-v6GImZ;0o~&c+EC-u?QOx|dKr`#dm*B*mC7J@D}alb5ETcH-YJl?v^zso
zEI=I4S|w20F#s*0-_Q=eXO_S9BWOW*3&il_E#Ptx6v3d4b8#Rmz`dVt15lS3RB3>3
zns-sj@Bj(9s8o1#TfA0=<=4&^o|^YO_}3ryU_9n&dA}sjQ}ezj|N1)~jQ2tMK_^N3
zTK@Ct{O!r_cMo(=k%n*QL(pnp1y4}P_X^~G1JK0b6cvzTJuUB*t_BAbNH=Jv2Xw=G
zi3cc&7kFCU_kp+p<d)K@pz*(MAC&}<Qcz@omCAy6NX`a17rcoFT%Uj>VGAZXKno^j
zgR*}&B$b24;aNR85B?VbyWoZYWl$3EQAv2=dYOaa#SW0t)&r1+;rAOa&A>fHko2=!
z4hF+ZEeH6g9s+Ota_qd|(e0<;(H*StB5OT6Xc#%YJ51swXtmc1MUXL_E#P1WFB&&I
z`OVFdk$>vJm-3(?A@I!Ii`C#lYHu@W=I$kElshN_x-Rl1Xw>7y=1VZQt-QnmohDui
zI`{;9WE<$XGSIBy#~0B&|Np=20go8?s6@P|fom&*Ys-Vn#=*s+z(WcS44}JnP9WXy
z06F>?B+A4CI#1#CJ5Z|>(LN3j3kI$I2hH4hG(TVlUFlcj+IiTq`88vOtxM-^-{jk_
zhL=1KK4$j#e%Y(nM$+TpV`fjr%dqm)uaigIyPHKA6csE!{OeD6HoxNVvAkUR%(3|g
zW1X6B@&T`ImxDh%EE!9LyV;r_{AoVH*vaP8c>>hr0-Y~x#aREmnU5JN0ve9_Xm|k8
zzUt&T=+iB7$hY-U35zfP`ct5mw4>#LdWiYQe3K7&9(=&;)$PIvwnGqV2NT>5ujU%2
zAB^?SU(W*h9IZSBUHa+MU8UjC*`soR3AAzGic9BF-_BFMpelDhXp=(n4bWjj1wNgp
zKwdZe@7a07r}O0t?K)7?VvouL&;o}NDbL=$puq!=?kQjq=<E+$9Up^dw?Bt(x4CC;
zi7W%6b-=>k0&4DoZq#Eu3d&O%pj{%(e-%1&R3iBMLFYfT9;h>O>8<#0`1Z9JJUl!>
zTev`dNASV%$wxi9eGW>za0}&S@Ui?0I{$&?UFmJmJzQzsE-D$G$$kpWFBmH#L3=<v
zW<bx#KKOvygAtVf4G*~VI{o)x{O$Su0w@$g`LmOU*`r&84YVMh-{qo5^9v3S{`IFk
zEf17Fc`cMSq1TnM`G-QMi%JB4-%(J2HM22-Zvrdj204ub)ISdZ4gY~=OhKb;5x$^J
z*^tl$U4N$F)A^~>Ma2P>v44QZE<0UREV^4%K7bCqbWs5pVlSZL8ZUgo3!)E$R{1v`
z0Yw%{6~r&k;Mn{_fxjJeG_p@}mIC-HwwIvWW#00)n6ZKnw({w`1fB!)?DaXsF#)ub
zqxC?EEPqE3xK26%DheI>CxDi+f!fEdexM4d`4H$-{L)LHW8*=|!lyF?R3rVL2wqSF
zI#S^nXz(zCzhxn){B7Q&0&+4#XNH6a>^PF+4&XJt{4IT;Q%xZLYk2bBvD3|=^{sDb
znuX_aH}K57=W#a=P-)KJ`T;xu>*nBj+zosPVDkwk517#)ef%xypql)_Zx9C*ejrPC
zF@r7#>HO%^`PsA6P2k1q8%zuy-K-_$pb3E%aH8gK*#ip3Zr1!7(D>9xk8Xh%A%Wob
zB53J(%RI2G?Osq3X8D7^<uEAtyIFIW!p5fCnHd-$7Yp_JgBpW-R6sEYx{Ar8^P>m9
zD}?XSc?(pGHM28%bXH4vbV5X57=di+JPvA>^#=S0Z}k)AZ}|ka1L=-T{+4$jAyBph
zT_5Gq&F<6r8NLfvoWJ!4xb%jfxAhXdbe*BwNd|n6B_n?u=$uiHZq~46;F5TL9i;i%
z9Rxj6vV`66_RGzn7CiJwNpKtU<-))J|G!`h0)@tZQ2t?qoTCNGIfe(0yQn09YWbIY
zz{M+M{`4;>TzW-?>X4^mQ-XLIUQciS%gEpNjERBaxPt=|D+7a1XM%;taR+cbdmMKF
z$MbPWS^yOr{PGOFKDrFx)a8+U^2PcN@D@YQPB#T;@&YZj@<_hw(Obdc(|OI~;3H;_
zULFBZb=Ca*hi9jshG#dIM<<7Ow-3_~uTCF^A0C=NJT#9nUO4!Ix%1#>kENgl1TLcZ
zTYi9&YB!|B^6Ylg@Zn$o8Z@fa$pIR<1}XCD_F?}4vdg3SIn=oBE#UGDo3WtO$H3nL
zT2AKJ?dI?@8MNQpqgT|j78LTV*Omw~fF~C{dPTiz`59in_UOC_9(j4OosW^hv)e`m
z>`CYa1E6s}{+6GhHY})J6Y%f<f5;Wxpmik29l&>icy=Cf+{*$wAQp7(@QVilpr{31
z3k15e9J-SW604^{BgxGgjQp(!L9A{E4p5UNz~JSk-~a!2PXU)Uplw5-Jrc(q92i*{
z7+$9S0rh6zma_UL=cp)jx2S-MFrUtstp`eZ9KX4!NOSPFya6p${Q-)m&K7W<2Zb**
zAV5cLIX3$_u)Iw8^Z);G2hbfj3}7dNlTaquA+Yn`Uj7GH;_%UVW^lp`QQ-h3h6Eo_
zlgmXV;(w3<D2x(7t*MBYk3spg^W%#h0gz!`=;ka?Z$qpk9aQyzvZYVw$N!f>2ey9Z
z?>zGB|NoaaK|9-f-5fl-{WN?#UpjWa@aen+s&X_C#je7O&)-2C0*->Oe+QSBFaQ7g
z|Nli!`=9@ywlm0&FZsbeE|{BN_a1j}U}j}tKuXas6+oxYAoXuOKzDd{LmE%VT~r)E
zB^}6aP>~O60z$4$fHdtv;u@fG4b&P0aTH$og03WPJ`w@n9|E3lZhVsgDpWHiAlEYZ
zbROq#0iWmn>py=BXp*S;7ZZQ$L(pkSe;K=-9r*h|`z1m5<$zX4Hbbvyas=mxU=5$%
z7H}@_eCg8Z1DftCR(KIQg_EK4g-5c#f=joLN(`tDRfDuglP@&CVDvcnh{dCOiU_E1
z@aXiplHkF=p66QgkN>6jU0YA`x84FJ<8I#fg#rwQw?T)^CLsJCqhfK~MFm<UxTt_j
zdQZ^Qg$rn9{|k@KUoXPH|NrmNcm(80P<?mU@X|MD2PV*Mw*t)%7&{L&e`18Szd+~d
zc!SQ71?@BH3{f$FS>y=X+!3Q<0qUKB?Eo!S1Ksffih&njzoFUyZ(l%+;xz@k{PnsC
z9^I7|9?k5GFBgEvY8VVJz3u^71-{LVU!GwXIBkPgqeI3|;N$BKKHZ5H;L`rQM<-|v
zALRV!Zf6Bh_6EfV=v2I09-Tj%9|$!6V3d5@{PbV*Q5MI}7cbg3f==FoXmI#;Oo6|(
zm4Si5;oC9BZg+>0oE40v8HSe}z8zyKVFlaoYIxG&+c5{v&Kr*WQx1YUepf-21!!&4
zVg43NMo{PT0Hh@h3Wd&tFTOH>dgA;YA&d+Rjn5ba7#R3l!AH7-_vJf)LftV2wEpJ%
zF;KIvME2Ve#!?A>d5|NRO1nBgG(TVjIr>ubBc|64Ag4gm+xKIjrC%ki-;S`9Tmg?0
zJ$%8rl%1jFK*`bOXAb<}Ysx`)Oy`5DXLk<%7H&`~Yz7@+0vgry=ytaN9SP*q&AKUH
zfC1E%{rRF|Ht2j~a3ct`4L%OEbP6_J4O%Ok!3jCy95P|z(J9Q|G8L2nTMv{tICh7q
zD0p-p2A!zZ4Jtp7r+)Zb&Vp?3=71koFHp+o(H#KlX#Ec|0JWE4V?MATS;55L3R=nX
zvKf*dKxqRUrZ-<C9smzFbb_V;z#AJ5dw`}@J8y!E<k#CF`3KwiGC|-06i}`QAF^3u
z4>9#OsM&|?WAOagfs%)w%`7U6KAn$Wt^-9g#1hbSdAGa8%Y9%^!iw3~TVFi#0*%=4
z-Yny1c=68-G%V#0IXcb*w6h3wh}Mha?x5=b0OWu*kKPg$3-Ga@A74BJsqf|81=4#6
z#0KTlLod#QnKxhbL-dtILzQoL<7Mc4`66O2JA+3rZ)X{3jOfsdiD1<qL6=-j12MZ<
zH_rtPS%JFz-5f7Id4k;JqhbNt8O#q})&uG$fMz;Dm-~Q1vP2ftzlAD*97yfR0S;Bj
z3E}V%czqoj<lxY7QLzB`P;rhYHNUX{jjw`MYxs1pQGx6$J?GMS61@Madk(mV@6x>m
zJVxQuy$3u${$gi8_>>1v(2=B@KnEK+D6}3Z)o;CBSMCF<;X_n3UR-5kWB}D%;Pwe5
zU3zv3@wd!nU|{HsQ1I+L<O!;Yet>JDkH;Z1?+l;?0G)flwz+g}0o(4=32~QC=Moi=
zJ0VMWKsf+39pxDRQu`C=umjeNIp9{GX(?y~6}0%Lo8!d<4_>Gvnza~9xjeg_IDEic
zqrt20&?jF(t4kOdJiCJ+=O2Mo!p=AHLZr`d@C9k0nhSJ6S^>Z29`F>=C;pfdY5W==
z()cxgxpbcX#2<GmjbG#7i@AMVpqo^9ed{2X(UkLnu9tDI16?mu2+n(~ZL`5HKU@N8
zHF3PS4N6m>z8h$4v=3atbn`CD766}lnBmxY6I7sst5MjBUT_hJQKf*Cfk)+DaDs9K
zv@E<0Di^vPEYkQjj(K!fIK0pSSqIvmA1vSjI>z(H|LLG%9gl84c$px^-=YobQXSy$
z0FOa8*QjJLdUW1^WS39;5#K?ky?6vl+aQyiEx^6skDyyBJ(z<9u$l<EzoYd)g$rnV
zeTE09zHa#hc3V66K0Z(#0jZz8ExtKQ3-Gsqx;dbW?>#$j{J-$xF32*FBG3igpezD8
zuiNkdzeb5l0lx+$Ry-PyfMN<X(g3S3KY8%$8~~3EyQpOF_k(IRk8WPKENJ+GLJcKw
zVc`l5ct}lp+(iW(wBV2jX~_U3-4_e~{QnPLN(fzF9|LN0f{!wZ0T)Z4^3(&KR}Bxm
z1Z^q;?NkOGn+Y4AgDlNQ)_N5(c@0UQFDAQ!8h^*2K>-fF|I;C1_Km*<)<i6I<z;wz
z4HWU+tiChB3CyVolEA7!QYXQsH|YF2$a?$6HvypDSLgK?+AiR-5WMu&9wgT7;Q-pA
z5d9*MA37^>jK2kRgR4ifgMx>(vq4FSM>p$*8DL9%i}*o9P@wTIE|5b(%QRXnKnWdO
z#mO-;K!(0N8jpZ1gx0e=L5nnB2(mCTcz_d-0k{Jc?cvhxY~u?$-wd>c%dz=~eEB-i
z8m$&{P)E7f;Xml4{{YZ7{$8G=pjD!V2PSxSi!gh3iZFs#?pPiyeecno9bkCCr+119
z<ZSu3{9yOM(t}5L2rGkUrw9{F!@K5c3r1KY3UpcvESq_B^U7xkFi0Ly1y%8^pk@K2
z@#-uAYO^bV8mt;G=73gDgEHGO{ua=sl;C{|2VYEG2d*1CKnpv;J$BG4ABK~l5pZ+E
z1K{IQA?+tb`T(!^oPb!)1zyB90W_*sqEKhy(ajn=9USCVh43Js?##>Z5_}p6=>D;8
zZv&5+pn)y0$G`ssIWPbmWU$ZxpA7EN9qi!I%bQ)m&+y`zJtT2~?;2(OGffy4nYJL4
z!MCk;J8Ss$syqb;_sO&gp4~d!kW~dUJ-+|->}25r9jxbRd8YK~%T1uW{gRzw!=N0X
z^D3b2!^StDjOo!Unv)BvB+r2|5%}PS7r*nNsq8R+3kxXWbhAF00vd>L<|qMeD6F3b
z_VxS%NNQf=1R9XgW-Jkd++_*R@v)Hh8zMYGOTfYBlfS5N2CuI2=saG!uG>LiFX$-6
zZ%3F)xf`DR-D?M`q1*+&9pT__1-r2ubn*-63P#X=GM{dL372kn7I*@IrH*cQ0grCp
zf2jftkVN4QzW+_bquU*vFce-izXmN=XJZ5<DbO_z$6qwA0i}tGa8U6Dx?2y{W`U-U
zpD!L9V`6xz4(@Z=YRnR508iq2bo(2CwqQiOn8?luI>4nBwAly|exDtA8D4@46v!#%
zppBg#-QZCZ!~dW*1?b|_Zg(Eg+35*By{rNG{0zH5rJ4)>zOz1^4?!#T`1iSk*4ik%
zSZ>eD0NN?=yZ{;}hd^m4g1;4X^vKIraD0X%-ALc~CIeJr^olOe22D(!1-UAK0n}wy
z&4Ze740=d%w*v=cnpA<m1+=!+qgPZqACwe6zQ}Y$lt5CT?eTE69Q-ZsL6t<Wx5A5H
zh?~HNnS&OxHdn}q@V7hyjo$T&CTBy8l7kopUe{ItzB3$VEen6kBL+})?=H}Kz_IgK
zomcY<Mo?d^MkT?cR|j02yygatPao#+uzX#j?b+=kFYzMw94Hn+n+{myOCP@oa{xP)
zzZE?1(+pNxdex&>bVnY<0dpY=z*j~c1-T9G7Z&~&&}qsZ&GiCI{4GmC;nvMMYce=-
zZwKk_=6G@5o|oY@sB~?Di0ebew}Y~2HydbK^$SLDWyV%g25Kxf9sxxFq*R5pk3id*
zT_C!>p}H&Wc^Q0LpOozNY}Qd>EZv4QZu@$rNADVNXV|0LTf?uH1$4g!gGcA97dGj9
z4A6vm^M(5nCdlzR-N@xrHE6yRwDho)4OH<37<hEEUYrE>5MM4os3Y9X@#2piFT=|~
zM0?7kTh@2FFvCkbu#f`-XwhoRDo|)x+v-dgX7K3+omkTwqY|(ebX0;bXb$R@C%?;I
zP%rPk4QR@jzXMzw^@>i)12z6$zR&;#52$gl6jXk69(-}#7F0-pV(l=0O9dzzI&XL|
zyQl<!l5+s4{!aqc|2`^+ZaOSqcjl-VxPp4Bpd(RW^*(5FZu4_!iayNW0$P3s+5;89
zz~ABoGQJgj90F({6nvEX^cA3-&fft#56q)iGz1h8ogZH`*zq!WShKoL6J`LX&^e&`
z8szTDAO><u0WB-_O@8NVoiD)OdI8j*ZT-gI2O1-D>~#a(;tP#6pI#G4$`yszZ_UR!
zKnHQQXoE(9x_#^=Ud%iVOT#X<45jy8Oaz5a>w%Ih;Pwfqo^HL1(yw}X4m{Qh>7RA`
zOMtp3h#jRI{H=Q!85mZAuhMPt1Kr8wZUd@DK;hf%uK<oWpU(F$I;}vl1sci<;BRUF
z_y0e5#^hx!*t4Jmjfz3_g|RI!10<F~G0bWW(!<~3^B1NZbnl%<uV^4Nhuc6L?*W+x
z2Q`;L<qdz!ckpN%EVqN#nAHm~^0$Bj51z(BSD(Imu~Hg3&3YKDX9^_!gGzkRU?Dh@
z@VDFqO$Bvcc{v}f#s!)j!AE<0bhEzd2PgCUAV+m`yb!nHWq3IgG{Dy@x-JV+5=;h#
z3252EX;29U8dwH7)Yb6Y%d=o3S(ib~h|YmjY?rNh8D8dr!-lmPB4q$Ieg{a(3S>Om
z8d{HT)&z*syP2>I*9}tq0AhtTMDh;QoC1&(=oac1VivsM{zZUCuV{E0$iW9+9J&D>
zBI&n)xZ!^v*o!3~?{ss#FahZW9cK;B@LY&yibpr=9f;DMa5u1n6vzDj|Nn)mHKf37
zsRB8_n{_2b=`*OQ_pEpsUM7HsXhFAlcqqK!od~*j;|F7%xkoo^3q<itsN#(v#h`=%
zZe#s?G4VRs!L5IO{{R0{0^Gm_ooD21;Q_w#95ibOI^Oa>_%ut<b$p?q_BuCs;MD~*
z@cQt7fB~pK3`#{WxBUdI(PluIF9eNccAoZxulMDT6JT)ZJnjQo@0;<$-3*jkJCA`D
zp?HI?Dmxbk8s@oJBJe^7EaeC~)uawImeul~zZJC59W;KkqYJtM!j*x)WgaMbbVEAC
zki*14Bch;%Y#tEqYcYqG|E211(Pm~w(2f}i&>7}OB2dbH(0pF6s39o4K=&(v+n|-l
zUfY2z{hSUhzg!tgq8wU4hsuLn8m#|%z!A*|($&rJ!rKxwJmJd#9-U~}&cMI`-e~Z8
z0<68tdKRMLLMA^%3e@-)wd7@Z3A%UOquZGSX>qa{Xp|c4na-Op8a{&}tW*hPdn;&U
z0OlvdZywDS3=aHLj(xxP5_In!$ias|r{sdC-uPQ8K^F#f+X_z<X7B;cSb+}42Zf3b
z!USK?8OtC8d^!zYJ^-g-M-H&lL9L+kAc0;{=S)zI@$p64T2KL9dC(KoUugxcT7=Ff
zG@k=Enjqc878S6|dqw|bK=P<QSQ~#QXk$0bW{+-;mlr^$ciwz)A2iAebuwtJ9LTM$
zA^-pXcWC)vBJI)5I;k5R*4Lrt-8biDcscjq|No#}Eud3jzz5>pd~yBe|NlOgA3$36
zfZYIE>vjMVJ|3OyFBzfstv3OsKmL|GjG)yjPfGM1yIoXddILcBQ}MTb1MR2#Ap$AO
z92;s>B$N4D9)bl0`CD#)>PqNtSkKNE-~~&dU<b9wL5qmmKy`9+Edv98%PtVJJCwoI
z@Ff2}FG<jO?ae=v9r>q%t_>4%<ez$|`DZZylmmt*T{tf|HvbUe-*$k%1$4wVXrc+6
z>U%>}JV2fVt!Fy!q5_#1V+VDr!K+_9I)8ySbAk4ZfZWi23Y1XzJEB0BP1LA(FqCL`
zfUd}F)<j(10J$7pwiY}#<<SYsO0Pg(>JDXSr~>&Ee2HO^LhCpFR?zIaOShMdW3S^o
z(7i`(nxGCP<Zf90KG11C9^I@>5dsX|46LB5o*XR?)|VW2Q30RI4O;O8&7Yv9T|OS2
zH@gL1JUI_?BFI(z9kW3b50x^)rK|^2RD75~2ZmcZDwG(#*#8-HlB6$q;<WW-iI_(>
zBYcJvan3JDy+>y(1NgWnXqtm$eV5L6FGc_S{}1u2VGY8sttWr~|Nk=S&;S3P%{3|(
z45d6ET7!YVMHp1?L&i%}8D6@AQVMdgy_jqYE|E)YJi1w5cYwwvC0^8n#6X>tTQ6En
zK}o7auKC=5$Ih=WL1zrY0)oHg<G=s^UxIGwdr@o3%K&lJ>}t^MH?9nz`~Zq-h|57d
zaOQz<UvCBpfTX)YU6{TUkh8k?sDP4#NAd}e=9=?A82MYlv;WXxN6=;@_LtURg{)3s
zhjP652TkyxtqG3JXaB#v1(I*BvVcri^S5^Y{r}(aq(^g=1_NllPR-x{{~@dGzEmLv
zp8nte|6lJ1MINY>gCDs3qTB==Hl<4-UORx$Q!)|e0f>h{JS6|U3<5P}GE88B(uUB<
z-+B;K?SPJz0kyZF^H~+(q}rka=?c}T6u5Mr1$EUkTsjYfCe=I7ftsoo;Hf0gDhdsc
z&M7J@K$>7J36Q)2NInMC>jDo*9d}WQVE|PppnUYg=qD(J@^{Pvi8Sv4>t-mC1CJni
zfLc4C+e<)mVPIoBKfXu=twIGa*8&ZcgQj6yZ<ladM@sPbgZ8VozAfRj%#`5oKM8V1
zH^e!hb@B&5O~5apI~l>6I}dwwTS6y!Jvs&XTR@v*A)OVFuR#?S%K0cgV3&c0oFMnL
z3PPqJ8jrwLgW8|q(eKyKK<ia=+rWkBr({T>Jj)1FVfm;eygtA$&+xrP1>_#c439o&
zr{e8y7nK<PR%g(V=3D+&(EY)!2TG$nK*!E@i^_yUYHZFIReIo*?+B`~U_o-PgOdR?
z6rTY)Zlv4Lqc;q)ph1wo6|`Cu<S@|4d*=-g6z4+11{}zb!GYzYk^xF-{4Gt8m3<&5
zf)>lfcy|8u=;qxXDge3!06Y*0icJe}EW%b0Ha}nj34#hs@L<CWjoZ+w{4jqDsA2<o
zu=N0cA83dQJlt^e#Zpetm680NpdG)U@do}@@C9Iy!ANjezRUy-GlIfXwiO(nmy#gi
z>17BF&zHHN%+>7zTE7=y@$w@0JbTN-{C!)&;&49+fxU=`MqZFt;hD;#n{`hM*aF8S
zSR3`Z0WZT#(1MP%36@9sdm;9~%>(TV^ytQ8UJk@OMYws>LFR$3UjywAfVclZYgM`(
z91!ila?tj%cVNdu?*D-%V(^`x@bOqY7Qb!=dn6zc<`FrN#R}lgQ;13iERVjFLfG;0
z5fU48QYCm+3}ro@NAnwp?m6IT1&_{i-;Oht$b*v(sF35|<|Wne(+;w~tKnx&3Cl4j
zDO*tK16q3N(fP461~lF0qN4F)5va`%9f?!}O>;g5b>KjQUfdqw-DeJ<adFU+%7~4i
z)=%k6(8(YFK?9S^>p*iVa-dEX{A|(EQ;0VH>wWO~V(88{)?i4skp)emTeyJ6z+PBt
zgE9~(SsQ>R(Je|$Ji7fXK$rWJY9T3G^@f1~p$N2&kcWSphZN{KF;GLy@X||J@Yn!k
z{M)1RB1o?d$O`a@(*`dx-+*e>5ETQEDHb5BY&^QHJbL~AgO8BmDqZaZozyY#=)CCo
zKM3p`8?b6nZ`9y*7b5%(|G&Hk$_TLjGq`+ie&gZMdEKM)ba$Xcw|?_q1%B}PTCJB#
z3_$l2fX1X-L7SyJU$h>mh_}2@n|bhseCHvL&KoV4N@I}@AaMZC=-vc5-sZ){GHA2^
z7|1C$kjq4y?G^Z2K<nvUTMv|$bhCqo13&{+tp~cpBs@AlS1x3{V0odFy=E@F{hiwg
zPK7S<prxlTK&|iVx}fn6ZN`#9@JtuvAQg!E=3k8bt>yngBLIwyuB``-gAOiX@aR0j
z-vVlwdUW0cIZgrN7*0^KNB|{l$bqaS>Y#J<7Ip_qbhAUZ+Ck$7Ql$J3Ffcsux;YJL
zeCYLAP<_`8x|M~oll`R(=%5s^<%S2qOH@2MKfJsM?X@A|1AJVE2RI^6^SA5+)m`15
z93I`KlLJ60?qf-wN9U&(=QKb`t;F2$k|$`a=H?668c+%rh92$f(J5RC-+y2MI(8K@
zvu6Q`n!}(44IbU13V|RaFP3n=sDqfN1e$-p`Qk+rsMHsJy%E%(>Sp%n4FFAly<P<J
z586qkpduR*cA$2vJZSYwxA4nSZ~_KpKgdb*NcZug^)Eeqx>a}j3o!V$p7a6L`R6_O
zT|R=gy@7TTKsUWuJ}lAj>3sC!raH*eokvTeeJqnXN<=_5o&}XIpiF<5zvUz3#zWY;
zhg+a1{Coc&cuN3ysuwiW(*io}((r93=u{SPI)QC=fv)d&u`ZY3@81Rr_s*Ly_%y%`
zB2ZgHp(5R*J6ypt`It|)&LL1fQt+{SQKAn%LQE5KoYCbvaLVL}1>NEF(h<BD6O=y9
zwRss{>w!x?(6E^TBY(>lP^Hl;+8PQPe7O1ItUA~t&(1@oxiEdqE}ef7J3IJWJwT}#
zp4`CKUxCsaiz=wL<cIEG_2_2xg}A~ghMxgu6vvA#TD%OeSA*2UhTUI+&kF`^UTdyV
zQDAWFbz_7m?{rbIfgCyc@*ZdusM|@xuUqCpx4VRk<_FMb`94th6Wmq%2$~5p@ac?E
z(Rh)>$qw29;n{iAr#nVP12h|Mz~2IzTm@%$&(4EBpcUUgL0U9kd;twZfNuJB>^u%q
zs!>wv+WMcr1C(e$d**yBQ&bfATVf#&fR3Fr@wbAuigmk7_;<%Vf;p!jd;<n(fnVn%
zu;HGaAACA*dho9o@aT540F8loFoy|1>Ortwj-AI}PlS{Yp53k-KAkVYBOxIw8ZSXb
zg=e!CBY$f(s3QTNLVpQ5ewbe#Ql7mKQv*jAC|zjqw}2Mafr8J~@QH8hTX-NE)Ca!=
ztrviV)C(sLaQN`IfEMq8g2VvS6xHwq^*g|GRSGZe{{eM{LqO}Ij)NRg5(o~HDWHM-
z<|B-t^XOCH(NMqK1L9{;5zy_UqJiDRAiwTJlrM-y0iX>?4h&#xk~~0JqxC7Mp$<80
zyhcR>bgc=fA?*QL{{_lo?4>tAZ9(v1grLJoPJwoxU{S{33cjcuG6@43d@uyXH9RC=
zPeNXw0WR+}JV1H>qDSZD7k5-ZnY_dce0e~LBCKoyWoF36$(Or8EA9~IQFXJ%R)cfh
z$4E%~txFv`0S8eJnh>ytsMrKmk)h7Z@cIrU{)0W5-$0IDJ6$3Pt=u)dA?2dji!^1B
zYf5=NKzo>vC`7-E1?{f~ubBd0OydAK|FZE7_yYSK0hNwLMTwR1pmY)7vBRw>Ki4HQ
zw;1F(7nKN)9gcY^E{P?Hj-VY)pylr#JMvOoQj3#|tUxnd;L-UEj~xo7#i<Gbm5x53
zO+cWHJv+dL`lXh`F17^iae<hgTAU0Tjf3vv*-@m&z;LWZ1$2f8Lt1Bx3b>Kf&3YMh
zVs|&ki*z-RclbL%`4@Cg6y$g;(9k;Qrifm*|31Av;N6Ely)3Pub*F|0Jd(ll%Z{K^
z<a{g-l)m?9{>$jm&CBA2XtGNl0JYB{jrPtQ6^-u~Kzwj}-Ldln_?8dQ0Edf;!HeAU
z;B|PQ-~xAqj=4+Of|n2&9(es6X8Y^ei1Zo`P9OmuC}FFB6t<^9fvw@O!wMQ~pq+)F
z=9tG0NL&PGg2EO&DQV%cBex(Y)i1SN544R8vMQf-TZJ(6R=;DQff-PFZLbOnr;4!7
zpD*@g|NHN1coK9zZRe-Xn=g1E6;6qjM|XgQN9W<@DjC5NC6DAH1&?kIh3)`}7hcuu
z3?BUJ!7CO(_49!j4}AC-Kpnv5BLSc$D5QS}<$%4H;oEwk^Ry4>43#;cnx~t0sRwAJ
z)knp^vGay!=S7U^S5N?hW-%E+3~)$;ng#rz**Z{GJzQe;%}tuIR1jiq2Ke+yP|?cZ
z(Jgwk26PI*!550*oD45oRKO)!$u&?BPy+3Hg0I_!oP6a0sc^turq_?tCV)p1KrPZ3
z(7;u|i#b{U{)3vJG2oR9Au0jjnJq;8q15+{Z$R6vP!<xo@M}U2v~l6r>;bQM@&%uR
z=m|Ps=(tbkIsTTH%nS^U-HtNNFGNALPaBBu+04iYS`6DQ`@I@;OphsO-qi9we~S)?
z(ag^1X?cgg1+*j`bQxRAPtaT_=t2>X&R0I24_&&;WM14-1p6Gk@WTx>i3PgM`rwP*
zAmL_hM(|N{d@P`W#kc$|)l3Wwj?M4*9Gm|!l`DF7`+`QhOG-iW^cVSCo`XgJtmHw7
zhQIX|cz?pn7pIg!tF?0(7(wf#_*<5OuAAZ4Gj)#SXQ&b=<$J-U47Q)YRh|iS`Mk!l
z7YUh=#Zv;2ki}E{?e7>tQhKaxk^Bt&?GG3k7(V&%>pTGYsZSc@Cy<+8z6b}o865A>
zL+CvDU5|kBMaGLIN>E#_f*Ks4rA!R`eLq-0D@4CF)Pb%B{lwo=4hpnxUIRDCtY8L4
za)Yl5+5uYr3QBXRiSNZ!&>S0R<o5`F3n+7YbURpp&ae>h1>HaX(x*Ga!SVl8P-6fz
zwps>r3u8$>Xg1aYtm-Cc0hK3nh>8G`Qt)=*Zcyj4`4>}(qi1(3WbMxZ{+4a5p!sYc
z73hMgC@2?X<^KyWRzt#szm*ddhVc3VG~e2~4-|Bu#s`1P5-?Mrk-z00m<75w?H@P~
z!rMupDR_AQ5408Pg(5F#k(+HrI4GV#i{SK*SF!Q8fcCS1mxfJG2S=o-J6M6<hjNim
zF8l(#4j`^0zurN}*t93e1*Lq576_<)?a|GeS^}=m7WqQzvt0_jpt)qo4F-@%J+A<X
zRPZDx+R`=9{mP)WJ;;zw@BxJz6(9*y5gh8d42;krsb-L`!RODm-Y$XON`DsIhJFHG
zRp!(A0JgBqg<k`fOEn<5)T8kTC@+Hwad-<F<bF_eLR)Jr{4Jn~f){}x*LJh6D+YTj
zISAsd$MU=k(9{ZDTMaIsUU=t#?po(>X<=kw;Fo9c>3rk~+M@mgbVgQx4rs^P5$N5G
zVD-?o9-wB1DR@4<8-8vMs5d<UT7H4#K@%$zKugs?ffxarvWN7FB3_;Wcf+9OvGPJ3
z`XLbFP*A>p2|6VU(td}OhamGFgYK_+;SBNzsMpE_YA=GK6f%wrjaG2M3G=5NXsV<0
zB{&biSS1fDA6)n~4)C{tmS(59@ar81mkw{_AW_^3n(Ih&<kvXx!ZDSLA&p<}1AqH<
z&`=aOA+?|R`~N?9jh~O@10Q}raM95J^!NY&KAjH?Z@&adgKDogFPK3Fb{>8C>laAw
z9jw0(+2-_27Bqo<{N=G<|NlcB4)UQ7*qnziwr7Fkq%|K@`E~w$u^h^e|M&m@PEeor
z#ncqgDELdzFk$DR7tarZ`rF!!;N4bSpkxQSU}wo+(0-FA9^JCeWuP(}lpevwG<efb
z=O@t0o3&t_dXUmL8a%D@mcJzn)DZ{mlyU}jfk4H)6=*^Xbbjm47gYyAlK{C45Zlb4
zwzYo$`Tze*NXrw}!hZ>xYVzpj^>8G&oCA$69(Pdzk2b$pcnsuAeMaz-98kuA9)GnT
zJk<+Nh8zC;|Bt8-k<#OH(0Za>pv71oogW>+CxE?J%L-Z(c<5yw`1W8IP;&qJk`d%<
zM7s9<{r^9BB_=4q_T;dGF0+F#UKN0>QuXYHF0d}C@a!y6v3SV~8XZG4$%VmO*v^)h
z(?Dq#-V=Jc8x+q7#h{Gyf?I|cv}yxnFsOtD^<6R?|4#*##^Al9-QaZf^TlgvUWS)-
zpk^}U@}QSBVAlsg*Vsc&;_7Bykq<5n=6XOf*;Q#!X3$Y#<Zq1x-P8fyvIa_oo+#~o
zwDtt3U%vx1*zME3MMVP~_m{xO#$NT{_dMj$dCH@kH_~2!!51{W&;#Dm?9+J|qke-l
ztYNhrX8i`*5d_+m{bKDA=+Lu^N&$2sSLe+a`<*~{V0bXUkaOk(^?^M)T~s3YTc$EG
zFu3q<vj+8(B0M_(xq@b$A@jbh2eO129QpU12PsVe?F%nu_vkHWJjSlz(YZzi6sjJe
zBWydr8vY0ERZe)V0qL)Rt|tdgnjCXwP}mQyjGK=#f-Px2%;?(kzeEva>i=u42THHF
zbksuZZ$8Rs_#b4RYs>%A`yQR|JS<B<_hLaTD&cLY`>#;SevC~4blBT5Hij2+QlRnx
z(tq$wc2QCA;9n2f(*$yF1!(l6z@s}tz@zhp$H5o&9-x!CTvQTDYCtj-KD~QXKx@4W
zK{r%EyC$&m#<%k$xU#<my4Y)q3MlJ?S_G`1em=+|@U?HClV?CXc3a<8)cbaV@8pYs
zs0Zya1E~ky9Sm};hvnD$H4QZ?2@Iu6L1X5i4$q4WNyrF(#EXB9d<-uZg1Dd(8ssKW
zx-9^0iUmaxylcx;l4W?nqwxqRIiXZ(6FjUT=dkd%7K76<s6W<S13F^>I%3`JApkl`
zp!3%Y#$fPnM*bG?ikI#X(2)$#b=i!EL8~>L1YUw}O+Z{(_PT2VI1a(ne31ABpJ>eA
zY49IZsMRtsfI}ag+dcVRLm5D6p}?ctPr!qJ{e>6(L0}t8Ts%Ru!`)#D9-UmUQ1Iw<
z6L=9P0Sk#Q4txyFzZv;kK_|w)m?pu?0N!3V0Tf{c&=RHx++Td53D>mWfsf%eWH<3k
z(7+35|8XdEMQih$jBifTj6R*mAg7l5cAfy`8}RZ+{#MX_r*0?k)~6_NDSnc_1vH7~
z*kH*3>2-Q^J2`kX?*JV>%D~@Z3Yuc?W%b+qAF{|9bhfDi$UJDT@)M{B4(`_VvRbYN
zZ4Uws`M(F1VxV^KamZmp(D6#xfCV#u%U{qrcemlap!ir&W92aTkkk^D2>y<D;HDn0
znKh(Fh`=ZrU}XZNgaEk+wdL#4dF#cD1JFX@IDZSMw0m)1jF-V9IatA?+h4%5^N3Hk
zi%NuN=gSx6_MnS<9)j{vz>7m5MWBoAJUV}SSRUi=2kqZOcPVIosx}K;RMvSyipo`D
zybLcz!6U4Y{kgFa`5LHv7f2qoU=_K&0&a%9`~oW1LGJM5WiY%1IZ(`_^QA}U@fTYH
zz>UNX(1uUX&OaWVFFg;wv47#~2Wf_M+yMoY<`3}P>@SdP=g}7p0lW+cU&yx{;BN&b
zdDoUF{NQN;k7REJpUxK^Gd;e82eu+!&V)=cfZZEz;n8{k-0bk+cR2_OB9G)CPyut{
z#eRQCdiL_@1T8NPQ3-&oCl){t7UcSrH8v9*KAWIbNtY-u!^^MW6?`E3n)Mk$i;cl6
zg8v5?yqGNtD%uXeoCI$3F@Tzt8NR&Wb>EQA)GE-H?{3!Z8DLW#pr)FDv>~6g!{0gu
z)GC2D2R*u(UpB#PMYs=XwQ%#B0#J?tk9A%4={)Mwd7i&j1~efG$ta*}FhMh_9^DP#
zoj;%=3v|)8M{@-S1AogRQ0>;t#t1roG{L7g2XsH@M@P_7L<V2bfaj|h2ZVS*r}^=>
zEC(rV{SQia3H%+PJ;pwk$NBp~%Z5EVe|j+cs6=>b{s5QSIVu?*$<7L({1(CA0ot$N
z!N2~6r{xR&9`IIw(6SVdZeCFfNCwI9=)8qBk1&F|kg)Zlkj(O;VJ|da9OiFH0Wacw
zQp(<#;P4-mZ9#{}-h7c;2bzkj(BB1_yS@41&I~4o*BXfM^XO)+O$WyWmpe553qvP+
zL|_9c1&AUWwgnF~KKTIDAMxmBwT0+cLea0sSh@>of^QwHe)8yM<%Ouf<OZ?NN|=}7
zbst<l`GrsC0Z`KZ>(P3tGzFBGGhRZstbo%S=t`{+P)6%!{cjCAeF}X3z!d>-Mgp~n
zTdhFLNG!oQnBj%7Flhbf2k<G8A78Kvf|BAB(D{=PWuUEs9=)P#!H!`qN&_ue;drr3
zh?n7|Ik>;mD|*n4pW*c**!(ScMHgh!72do9IS(oi8BZ(l={)SwdETe92eJvS^)_g6
z5~zF5-vX*^zBx;?^0$Hye@OOL04;|A^-g?S50un9Hdru}RC;tfJAev9a7!3bjDt2(
zd-Sr1d$e8x9ShF@UeW<tzo7sszxh25ffpBmiW1N%7#_W>y6Yfixq(M7tKd=yTjPZ|
zXdM}-VgVhC4T@dR<P2=Stp)1j1N<GJp1BAA`V$_Or}%q7_g#5(^JbfZQYyq>SW_wk
z0|Rut599&N()`peXsSKN-vV0x;{(bbpjy83mk+2F1ZpF^khKI2=^>m4A7Ak36^(QS
zB^=gcDUi7O1&VplZAL1fWs7hv(D?A^6%BReXLx-M#)lLr;B#|dUr3wa(JR^rl3xdt
z@4Ns?d_O^n&jr*h1vv+N*%hSy03M(70XJ?sLsSA@{0W1u`#B71`2>K9gb4mtnSY?$
zLto~Cnl!zlA6)nuUV`@gdGw0fxbnjmr-S>$DDCa$HyIwC*L*vVzIe(DPR`)24``v8
zM{*wMFcQ#^0D~vLC-{Vy2oKQZzSc|(44|<{{#MBTHr`Xlpa}9&A*ZhW^g?GRG<FX2
zw@d&v8k_(AcjTXP-0<6Lc5r_0{O4o&u7(rb*5+pd9ZB)<#dkiaYmY&;_IX&Bs6^BR
zdUSp;yyS85hez{2X8w7HJbHZsm^{Gefd2pgzaA9Ke?1sKf{R8E%Y*#=4xnNc)TQtS
zHNURD5b*p1x?`TdMI9{REa1`Ytl-gG2ify-)1%Ykg{%kIx%@3sASK<wpsj*FogaO=
zgB(0M4>|sy1j=)u+zvho0<s(vR5C!9V}klWpoKOl<za3Tq&##1B{Pl}v-n_Lrxt$D
z(OkDZTEBsYbM!!CTA;ls3n9MeZvmea-wL~}NfbO+o`EPk9peup&kw%74+_s0$q?P8
zYCe|l_<KS1JZSxQBG?J%oFPsS=L20B2Tm{G<>RH@hTp&gL6FmNzzbtx>9?D;6r#BV
zs`(Z#$o+bZrAH8+e!T-;-gdLrLexKUf>^eSmzUusH@Nf!mABonQtri0NSfqt1z&5@
zc>}zT!tnOXBFJS2kn-cjWSA;&$qKq{8B`o~gQC>sg9rcmub_c+Gk0*zmT-D>It#qi
z0A-VI*1ZW}Pw#=cLkZ*#Ua&im&T|CKCnZ3K^AGU1)PfD?y=H(hoDc51!FF9>D~S%h
zaM%V;JSDo&xdu?{p_C8O7D|YQj?Z@<d=cRWTIp8#3_OHy2&)yrDj=7kA&u9+34)E+
zcY_A&6Tn^r4|Rf@h_4~0BGMbkKMFp*tWD;i9ZnZLdPUzj@-w`6%MQ*_C5|55;Bywg
z>Vs-J=sAl99H6!&DDXgs4k|>0rr>78g9GoVBP0@^aziU|ewcHi^JyN?^6xgN27fwX
zf=4%_XXhc$##d*x7#R3Fc)^3~7d&>oP5N<S4_mgS$M;u0ofkX~{;>Br_=_KOYH2Ua
zB#+EX8?Bfae0q5rJP$r(@zlHo+IQXfD;G4T*azA|>jOFmYS+mqK89b7Yo3B?bdWg*
zK<4-`9zr#0O&{nQ9hL^)UY<rz%?qB5KXSmXI8;~W+v~vSvFl`p)5Ph`xtp;V!{woQ
z$hVhgqDSVXt)TH~uy&9$d^!)+nfvxS{P)=P-1r<*j@@G&6zv`df3ZP)bIFtOqDL>w
zA)n4e9=$9LAi+*S&)&uh><kQtC;0SsG|&3`-*X2nKzuq+cz%E3(|H2q7bK5>0>h{C
z0$2_lUZ9YH$wR`+Q}dE%ZxcA=IxqRQUh?4gxbX5QXp{<(9>C`tclxLpc=Y<H7<hJG
zeh~#~>wvaWGaDZGc96N$3Ut8hF7E4#3v9WrFZS#_>GA!Q=fR)$9*n0vz%j+<qj>`4
z6Q5p|2Jn1>=fMX|K9&bdoPBy(7(msOfhXeuk6zY-Ts{WRgAZ6d84n=ti%8~aaO^zj
zVR^CM1avf-hvq4d<{vzz&q1@jpz`bBFAg8gQy!pH01B;x4_H8D_Y~0G7O&^0O>k^J
z$k=>{(Y4c?!?81%2dWF<KX7{Y=oa0g3rf(Z!85{^7fXs>M6-etb!jGa?F<V@-tuCJ
z{|hIGgque<t33m#$_MR)5CEMxYWqSBB4+|Ra}zEX06J@{MBxP|SdxG00q~L2pe7Eu
zJae{au8<Ke-2e_6h!oQKGBEe0=%KhT=*4apu=_lr?n}{u%wg-lSOk$!^XO)s|6hm!
zA|D_Da-htMR<I<(4WRLIko{t%7qHt8j{k1fhtc5d+-C>L&SD(Ui+Ql#mjk+!+K!*W
z@Y0KO9J~x3ovh*@cYrR}Nt*ykGhyVWnNk@KJQ4o+@C2W3NzdM9KhVOYUXcSHy(||%
zNe^_^KnLhBYv0~({~!PVd+vaz*WN&8&|)Nhk5irpe=_;@iZJ^2c2E8R8Z-xIEJlzx
zsIX!4)V%1+c+t0a^8TM7*$beo#dyi{;4hFYhmR&G;~E}t{C1eR)XJyxh6g-P_;%g`
z=ZRnTK8&~Ec>?S(lsw^UdAP*iqgRB%r<XM)i;uyB@ldxT2k0ywAI3wV(*_lrUoiRf
zx-_vM(yvD{lSlI*7Ei{5K9+|{KXyCvfJQ@R_%NP;l<bh;x`doRJS`7H?iqYNIc<V(
zZ?n&j|Nnh^yA43$(i_0++j_u<-{TO%`JM-VFnKZ_02MLcU->}8qw|6<=)k~V93BUM
zu=!}7^3*)!%Xq=Bmxt*k=$bb8{24g?zDNU=8JQOrure@YI||r%%<y2m;E^0C0-`{N
zy@N6Xq`n5HH+XsT;_XjRAK@S*)sSD(*!lGGfEP9!7+&&ZJm}HO%905xYaW6E&NrE5
zV&?@<%M<mcpc^K9G!J?-|Kcfq0m~2?harK8qmWtBe1H*LtboT~!1MbS9^i&C0|P??
zsQ2H^<zacS#IReg`8OYb%Lir#hSuAqW*&_%H?cD?bi1*DqE^_W^<+hoPx1*+&Y0;5
z8b~?l*~tNJvq3I{goID?Z^jaT@Ihms4V#@IDhe++|Nj5q{F~RK^B{k_FKA-Bmvx;r
zD4&L?D1h4k8a~N9pak*%0cd_L`Gk+=NsnGfMh~bhuV-{Sad`Chc)oh^|35hKc=Ymg
zyi9?#bUc!s1U!0qJUx0@PI&b4fX*pm@HqH@%|r8qN3xfQ2O}0y36N;AmyAc|0S8dy
ziSeLEvXg>G=1CYY^B|a&?4{ztc<|*f$Y2q~f1pEaI+lY*2Rl!A>{9idqyj=7p!($d
zt8O<IkBh%NG*5x99qhcw-w&F|gLTHC`r+>7IRQS?i8>y5844aga$tZN=hE$^Kw+3<
zo_xW~z~It(V%KHgBmu{RKjpu_I{1stMe~$L@*z;bJOm9m!Tm!~_`^e70c3Coc-#uy
zen;|;3Wfebi(|0wz-@Av9Ui?rpoTy%1E`UF@FAOrCMaQucz`k_3!10|$ej;BGi%TQ
zaOw7vA<=;cJs?5+at1i^Q2dMAEibb`6L?7dk+&h>x=+gjl&3geNHId!o4rf~Ij{L8
z8&Wz2HN$?|dwhQdNv9s27hg()RCTj1hnO<Q9Ae592AC-zd8G2Z`HhB0H)|wBwH(yW
zWeo7ib8u0Ep<WZB-VCa~45xZ<dF;{6`Xd<ZDPIeI2GH10H^&PnBt4zX9-Yn{pw5s-
zr?Z3yXr~sWn1<eO-p#rLqCXU&p9#Buh(7pu3E2K#$JZX6mz#eumMgsYy^jGjg;rwb
z(H#)r(ar7A>7@W^1%b;`(E3)0RYp+1&HB#+S!JvceHhf9czqFheW6G58w*gW2wnts
z+(iX^9ngz5P`3wk3&sTax}tJUk8Z~RkLCjkhhK_+2knIgrw?%Xt<ib8Td?^TAAbwz
zXpvqPA)j8}%ZYppKFK#gh5ZcAgO6D}4nAP<WjyW4co2NJ&k_a(hUQ-^`#|?-mPa{u
zGaFv|{u#9E2z0cIXY*keSHnx7{<UK>=$@rdwftZuAPJDN(ie`FpGu1P*E_QKCSP*y
z7Ma*7*y+duF8x7wwj<)Z`4?N6Uh^TwPEn&IK89|_<^xQftlALf51x{Q<{!L1y}V*c
zd<;Ilvi}qL7)oUKfsW#QnF%S+K}%s6UdBMW$S$DOP6tYyJ-S&rg23sa)tsNf7j#w4
z4bZx{{C_;q<7~h;1%S?r^XcW?2?~i`*+q$b4B$!Zmwcem?Pfh12sYxE8EBn8Sie3@
z|4Y!#fv$#^UP?if&VneNZwAQ>$Nxg@dC3EDCBnbR_my-r`g9)l={(o`gO9%@88q42
zE#wG}rZN!6@&bPws1$MSyzJO{2t3i|YI&Kz1+?GMwe>cCE2shJ2-+afvJJE!5*%+O
z;DuhlSUh@JT^&IOo`NoFgDffc1g(_;l~w=CWnMNiftIH@Fm!8xS4Q%$KkD21fWK82
zto<OPtL3TkC%%~nK%FVaouGlLm!BCJ7}6#<b{;nT4{}B;XiqQXfMUpSdF%gDPM^*b
zzM!tu0iWbZ7LVj0&<W5tefZZO^0hq7-wqlh_W>=VzTshcg1-f{(9EOtWGVkk&?bM_
z_)6zR!%H6DKZ2SKmZv~_Q$1QQfwro;wwx+`<kNWrEDKua&kXKwe)Q;M0~H~#VW7i~
zpjpBe&;oc@%Uk?y;KNpWbyXes8GMr;yL8_01a+Umq2Si-vXtSqpilA%w{D+a24DX5
z2Yp*#lu9)pV05%RRQ?>|Iq)IF3jhEA_f3B6(JT5Vo{zyZ`H)XH&moU))+&Et2ET5W
zM;^VRhfN`I&;5so!Q(h6+c0=Q?hHk7o=@jZpUwj>e}hYK(0NYanIy*@pgSjD?)>-v
zzauyrFM<Ynn}4zR^zzo(!=iBqXh|zlEK0sS15(zl>Dhdc1$4ayI0`{m14F%lh`|Fw
z3=A&~L6fqOJF`5GGlB<j!1(|=s|YKf&iaAV{VWrRhkpG+_s~nw!GzHGay5MN@+rvK
zJ3nxN#-%|C=H*9FMc;YwC1^jWBY1}A<w39-hi15%v!LtIz$wdd2Uyb{umH%RP=VE;
z^J#-!x;Y)2fAaCSIDxN$gJuxWg@mq_7a_?kilrpNwe@7FvVX5kwCBOcOpr_g3PaFV
zpD72T5$$o;)=MSPAo-Ffpqpe$?zviCERW!C0+n~*sPN%me-nI$6=*6RbpP#55Aaj~
z0|Uc<!vh|iH$7S}mac;)#Lu9OUMS{!^vXngfSvG@v9!^rmvyx*KPbT<3~}t{X?QIG
ztB*aC4>@+TG=OITS}&H0fyz^mlb(C<ufOR5%H^Ojd_#yATo^!IsYtMi2hmIf9XSqK
zZ<Blw*}P+*@d8k0e*RJ!R7Oq!cLI>Y!?F1XbBUE>^A8rVObNH;MgA!V9GibIm9Tt1
zoHn8PC!Zt#lmpGb_)54eFY-@2;M#Ja<e5t+_=*%41_n^nOgRXW=4?3$G2%q$2}F2<
z&G*7<KGgV+EeA^98XmB`SpK~ECnNu~gP@Xa`T>iB{8Pb}LE6J$`@qgQ*m9tBFS1I*
z6QJ>v<~JH3J3Tv3d3Ihb2|(D)2lf=d;el=;OTiK^P_8_jHlbUnn-emT`~tK)8ss_f
z)sUxrIxoJc{|i3X6g<KK9T|YA2W4-N0WU!p={R;fvRFE@@J~7LdesC_e~(Q2L7S;S
z_CtzOpH8q7{`^690?fT|`#~$hFzoke{>50L4LYQ+#0fO#mEh6M`oRmFsh1i;GIi>A
zXblDO#bN$!jLk1xZ1l@P<D;7l`5E}P9q>qIY4Tt^^#4&qC1Y{v4zQ9$8<FyL9=)Re
zMyN_Wx>+Z9feytv;n6E91+{_+)e7i+D~1PN_khc>*RA042ApJGBF>`)-;Db*4U|?P
z@}RrJUxp$0pyhht8)6{yMLSqQ$4i_2|NkF+?=bk%7x2BqFO@)I;9?atp1uQgjW4)n
z-vPR$7d+#%1AI3wxVr{#&q3;EP^-?tr#A(3u;_K4&ZCZCBRx7#gVtenJ^~GQgBNzZ
zNR{OS_ron5J6%~kEKl>dtOs=lI!}0L-te$I&ff>x8rWc|&))*x72E5`_?ine?AK87
zU%y1mv-1FW`;3c<g{S5XkIqA$mOpA9_*kAS(eltd<=Oe-g)Zn=?H~UgJ6#z{Y<xhA
z;y}X|V6*Ei92+e4OX@(Uxp{eXv+{X@W0>2JpTSY{CFsVIZjKkVUlH-_5DhKpOV5BC
zVsO6WaaYjEZ456#%UwOXS&w*tP5Nm78Zrkre9W*J<Jo!gb(3fFK}Mg>N00#W={yNK
zFkIt>p9~)Z$h8`s;GJd`o|XssTY~@p|KDH{%iju`ssm;2mQqlK)cL}v^W}?>umAra
z{2}iFIzATaOmO@|=6e-DiP@v`v`6RlI@<>8Xpde`#*!2d%hM(L9^I@W9>NTcohLnd
zMfnUsp1%n?&$652MZ*__=b<-lGkA2fK6M9sPYU6^aCC);_F6+VV{FMZkIr+ixxnse
zu!}8`_GmuF=+XHB636v#O1V5bKY|w+rA_d#{K(&u3~Cj2egZdzZg^;(da>*;XojOg
z+@sfz5!A8)M<9QzHRvX#1Ft*5b9S$rK<#Od)=MSaFG2S%LejV6aRxq6C4bxj97To)
z4ue!7+y@CC15lRt>^#BW2U`Eazm3r*m%jyc|GAAXf6GizifsPHRTu2hYn!3Z&#)7e
z?tMCseO^}T<k{=N?a};-8{E7EP09v&^v0+tfL20)?1l9>n*TF;bl#FY*?ds!1?Okb
zy3r%xTcswH)_L^W%7YB$0-pv8GBn$x`4yMpf6rbIE|7QDflc)6yzxT+A1D|qHyIvy
zy${-cXsBegfL!_R(d)_N(fo?Z@IUl!^9E2W4I*y~3Q(v#*rm`T$w21?v5LBZ<Fh~y
zQnYn_g7&At4utf7JUY+q1oawT)V|{Z_0Bvx50@x)i+S|2>V$zZFwcb-li%?$bo;S@
z`iC#3f8=2RcM`!nrNA8)SbYuMUmO8m=mOdpbsb(9fEb|tqzsUQ@>uv=j(|eGJ5#`;
z*Y%$V=-`reUeHKTccg>|Xqu>*nGvE?phO+C8Fa;4(4ZbSd@Zan^mZ`NLK@K3^`O<s
zy&)<VpkquNKpNQJ@qmuw=m4Ga1Dbbm0PSzHa5X&e;_J`<|3MdHvh%lqS}&lPHU1V*
z`x|s^&Wqz8ct8tnI^9{I^U2MBS@>H_KudYtSwJTdfZF=tG6H-)(P58XULRe4h8OuD
z2ZD}Nc2V(o;RFiGULVjMzK34qf@Hc`yIepM2%vj?yE$H*`~dO}NCENzCg8O0(F{5H
z=<o!P%SvB^gQN52{{RD2Y0!Kw($#3ChdjE2IY37qLiPlAyQpYD>IQiE4N?GF(}H|A
z>dRf=);2gjA#8dHs_$R8fE)=r<_k1F=+Vu3!Wo>HzUn{{)8F?z3@<@<$HU_Pg)me@
z%W=>u7|41^KaCe9?;$~YsANsIKTGS$y3MTz>ehqy`?PHS_y0e5-Pz9<c^_b<93)^t
z{$mY=SZM^cvg<vx)OuO-@Be>r`t^XMw$q@!VXy^#pwtGggAgaXvGBL9WdNV-#vo9d
zwvvH?frG#0B`6IxGctk(5DY*m2ehC1#o5=Olv9xiN;MXsRAb=LdZ~`J!7{p}*46NU
zXXnQkpMHQct4B98f5&u?8NC6Z_Alu20^yPZ=tk_c2`@gsg5{{vIk3n>+Aj@`-{*)>
z2P=7vxG(6%YS3^}^AU&^2hjC+FF3%fuaPgKn*fT|P8Ss&c)aUCT>xJK%Us&{dWJ_g
zE4vdo0&BD(5oq&{hXFeF3yJ^cHyWVn?F&Aj?Q<n=(C$Tvd$%VGe>?QRKk*<whUTA)
ze%&mmN|IX-be<~l@#y89rp?drq6Fk!&`hR}io=WYS3C@$5orfdR}?ZI)OxAplSePF
zF-WZgNNul=3TUas3vZa(*OxqcdHq518X)=3L$5c1ZhtsbBI41@s|6AlfQruotq1Mp
zl>~|Xc?l|#4uLM8W#w@Md-0|g#EX${c|gnmUV^s%PJq=1otHt2$9s9-YJsjgJ?GPT
z{Kd|fJPhCseW0~W;7rsD+V}hlG?&rK`v_zjNc2S~*s7c0^Uq&GJg5QcaQ}R<|KI=r
zknFGVLfL^GbZGhpu(m@lVi1}VLCkK}ItNHupaB|r+4}}k7HELZ7AfHcrvi^=NF4%7
z+(<beTx`SVTcG8whDYaR$WmR`&J&<r44pS!I?uo0`vPhmmvDp2D)9A?haEeAf;JR`
zwralwHEuxz123OJhU8rsAp2dL-{3IMj!5%B`wgJ=Gvqwx<~If|-Gbm2$~DLk&SKD&
z=|bSqoYkN~70XK=$&M@@$$l*SEuf>qTw5=d7J*wqo=l)?q)+m<9s!NwSYC4NyvX0Y
z7F1F6+UDwm#w{))I{j|lGSgqnBI<w7<d@w#>wWmw-}P;M%-;%HjtuJZIa*#Udg2MX
zH4apHoC38VIxoLYOPc_?L<MxdGpGy9-(m$CXM&zx0v=KVt#LBE<k4&UMUS7sC;5~I
z(r5`!|7*bsKFPP-x@G43@~=Pb+4{1y7(D!Usr-c}|N4_2ttU&8Tstp&Se_{31Rt?~
z!lUydc&rD!u&(uFDaXr=poK(u2YFggx^_x9c6zYXiFza-^sqcp$_tKPP{IJ66712-
zdryO(;l;yeXzBTdJg6+`<*m{H9ZCRNV7>1d4+ChTUjvkwPd-CR%pYHT`VE?j1J62v
zhH}>1f|4u83t>>^18+xf)@0;w;enli{Swp<2hG3#V&rdG#sE44r3ZZG3+Muo7SJhx
zpvY_mU*yosyH%Z^;e`Xb13?WTjTe<5i+g#msKZ<-0di$0IK!!;y3r4!bUj?@+ozyn
z0Ic*Eh}jK3I-ga@7J4M>1dm=82hfRU2OluK1dXVGT-TcY|NnnS%S-(2%Ah(6e9#W8
zKJ(~i^6Z3+Kf}Wpv}6TMsPo{<R8St80L`o~Uw}&u9#4;h51GKbv>ZWE%<vL46@xr}
z4e3vTYcY%NOc|H%BpJ{YV(0bdzoL-C6CIoXi0%|)03B2Z+SmPJ*K+UxI(T0zXt`Fm
zgN$SIA2CP%DMy<BiaGF4IqJ&4?Md?sQ3w8QZ<~KGmgT%qe*nG<r`sL6$F?lzg~$U?
z>>lrSLkKZ~g$}xOrhpD8c<BqeaOKwv>p$RXuJdL^2&iS=d<1^a0Jx>SQxw#{Oo#VB
zJ-VF(e0nn!;C7Wy>2{Ox=&lcFej)17d|UxE3oyl_+b_VQ`Jlq<N#OdA9aR5;j#xQ~
zZp8%nZUhH#uv`T%*yt8b<%TSO;C!+8F{q|4(e&sJv*>n`>GgOG8uMrat!HiiA;{kX
zI`bNwJsdzKony>l=)qXbykHafTYiDo(8YpH;co?<4-8W9y%DtTl7WFi0@S8rb-M>z
zSOHm7!TG`fthmGy+++Z?H$Xk+<1Q+o1|sO3EAW18@TT$?pylU3f593xa3^$rd~q3U
z2!9KBg;wXs7tN1(7(AMPfG$|#@A(Fb?mkyg_vim>UeI<KPs>02Euc|#@Z}^QUzC89
zgSJK-E~x?SE@)|HU;rI#?9qAf#R+gX0^BkIjgKQW0k(ny8q`JzFnGNZ++XwP4U+(M
zW<aBzkO5s#&$#pD3ug>hL)3Q%1$Z<cQs8d|-4dHN0bEmoH{L<Yd(iQz{H>q?P{itM
za6=8+pFwiW5hTaJ*8{$|49d2kLfQS_|NpNS1TzPUbUO;T^g8@+z0?^f!r!?aWxsFp
zAsd&@1FpRe|0}+9Itp|Kihxc+1+8)Jj^ybL{@;8+!m;y0Z_xjWubqwpE}f1%pdrsb
z(4ldT%|B%L`}#oLvTjb$LXLyXrFNj<1Ehr<r@;$3e%t#XEpEC2T4CbTD*{{G^oYsV
z@*?E;?e0JhpI#XTAI2Lly+QwdlP~%9iZprjvbK5fF*tRzOmMM0P^$o{5;PAq|Kb6;
zrZbSEjt?|QaNLmt6bC+?oY9B7137w~{<j|JbmZXg16>dA(=F)I>-7)h$V1GfVW1Up
za7X%dUIxuS9t1h^5_Gi*sOR0w(%{o819RkKCSS{2kkvFEnzvAwha7?|5AjUC2wFDb
z1DfIoyZVAVAA<`s%LI@+!9${;^-JL8IA{hOgc$JhFR0M#W<2i50UB3wg!H3(1OEGT
z3chss|NnpUFKhn3n1BEOyYxCRLefj~D`@;NHvh7&|M(JgI&bq2ahGmK9{#>S(4cs4
z0AuqDNF*{g{}8YL^wJpIU4e{uG6#aBDl9;{SvmtH4!d+7*wxw5(eeG2OXq=uKjd8)
z4;}o)s(C2;kd33}0hdlkiI*$D)8P>P_?1_HQjEk)(7|fZ^xOQ3(Xsh}&Fkk-KBVME
zTK{2r$P;>1qUUi3(Bu+>C-e$M&*KcB1t5;c9l$Z|c-#S0c{1>~oZw^t&Fq0@xvugt
zFnECGhWOXtYW~5?-`>LsTAV2QP?4VjKH})HYvF3=OBZ8{ggiQLfaCs`1!yR|BcBVj
zq4X9=bmwi8ZP%ObNjrnqEBR<%a_kI{@YrRnbS0X}SYH{UN!3RalwdqNFM51`2}<~o
zRhB}aC5V}a9Gv(WJT(u34Ez4lwbKK%5=#h82k1<vgFozjp-VkFFM1sODdeGf&`0yM
z2V@C?V`qelhvqTE1CE^q3a@!5cr+dc1p=rGCE)?COb&ycp27txzHWHzTD=Mkv_MYm
zya8V12wDPi$fLIjq|vjJ!K0TY$m8GxCJ)WSh6kDtGdgxgaJ=3OjSr7rp1Ta7EZup?
zL-Xbf-RuAV8y<K)72aM3t+MRA`9c&d4sNr6trz7+vmVs_(Li#;!Cy=so!3CRHIIP~
zp1N}F|9_8OmNHQHM#BSi1F7a=$Ib`=!vil>A(bH{eSuAPhk349_eK*4VVcf?Y`RD0
zw*{;W3@`GpfzAs8HNiALgW>_4usb?BI*=U3c+2D9FIG^Lb%K_WPIl}J5byvmwm9L~
z=^$cw;N?_M!vx-*X}!(g!4C6nxMtwF1t(l3Fx|t8=AMQ?Mur#nucEn!wdQlyqsWUM
zp70fKo;yLA59~%z?ET_`q&)%8?=L-id89lJ{$%yhyyyX1#QG9c*@KcC<0+^YKq;}8
zWuiytDNm3O4n6`cB?bAyqnD-IL-T@Tr-OvyftN>+@-H}ikApHv=M9ft?RSj-mafQ7
z#`KRQntvE#)L38eqx&cI>9g91eG|M8{_*I%f#juwzeJ$^@z}**&hf2i({oo)Tpawx
z2U??r(_<dJEE7FDFMI4d|2_Ee(%DB8JP$r*^U=Hk_8Tk@vlC&&MGwdl7f|^4Xo6x`
z!tj8H=IPAaFF>cLbVkU$Tn1Xsf*9`s$2TnfP2aIFY^VKmBh2toLJpr7-!A|E@3D&^
z;kv8{C@+D=kv#a<fAWAP!=su{nRWJWoq;Quz-dw*9#WdumpNM|YxRRd3X%pSai;-z
zP$3F1%%Bn?GN{01*ujU;WCRH+M^GR&{syf80o7-q@JZ)@=KjYXKRxpQ+h<^gk1k61
zT)PAg9|r%4Q~VgfLmZ&fx!~aw`nL3~+W+`DDB<IQ$Qj`9(S(POtnJ^7f5xhepzt~P
zO9ris1r>py<_9E~d%{xE<|)_IUU2IPVoOO<Sd8%M<>3P5KF}hp&QqSfES(+)AF+98
zUO*&D$4&<cP%-oUmB+zfpw#HG3l<5G_yRS-zrTWI+k?N5Y6@@}4^5noodq(;X;R^(
z(69ghA@w~tzwTy%hIi<Te7m})16i2iZH^M&X%`{kJ!4Mz7b8YUnTwPjclz(HYIk&C
z#1-BLf9b#j`}*pi1|O~+7J>w}7M76064<bM6I)<ot3{Cl8ywP|r##^mGBntsfek7b
zK>^u$5gx=KA<()q@RkSEAcn4~1O+fS+dFnfD7@VI101+W^-Vi?4B>{yF2w+Wt|i`o
z0zEr#f*Z0w?LqO2NQei2+4yLl0#_Nk<h}D9U$x!wfdq^hXpw#A1<%e);I;vHM}ZIH
zC0Ie-%Q6XEp5=x`%&p$X=YcI?46qpC)ypFUO@*GlEM1_I9-hXa0pqa?mb9Tk1aXj*
z2PlY6f@=;ONf2JTg3~ytW#kBHwt&(yXca7|)&cA7Jm&!lbVykW%3z@S6Vl{?CtPrf
z2DMs1O_-Mf;3Z?=`INOf;Ne9f3CQr`uN$!OXr1q%#)fC70JLEPnu!91HzH_vGBC8w
zTc>%I0pur8{Roa@Gm!0_7d-gaAN0^XT*>aicp7xjCwM6kXq4s$=t@9P^#%)VNCx=+
z3Y6YEZ-82O$jR%M0VJ_YAVLyk-N9dwAVjNtLE)fz$OGzm0znAX`x0~|CNw{H-tgGT
zz>u<h^R@@Pu#m*#7oRVnafcg-rYOuW;6c|LpoPCEeo^%Rr%xGBrT{w?yvd~VB8U$f
z={yIv6Waa+D}eh&^E4>t;L-T9_v`=v6F{eAAT=@}buTm~VC~F}?4V{eayzrvna8oy
zfy3~?OOLPr|9kFaWXMQf!F~3h$3B!2%#-mZXnPKL@$x%RdhI;qaqy?PkLJl2OU{7W
zi{6YLyBQdeOR>%q9^c;~N>p=DQs7^I%R}>~$L|0Cr-REo5606kMZgu71A|X*cOq!`
ze;-Oy5{s=IAY1jIwn73K#jeiF9tVGOcxWE>$h-||Y=Ug;JnhkVcs}Uv=)SMe`q8J?
z`=!S|Sfd<VPGhl*31rzp&>3O9-q7M1(=t$l-J_Q!8Z-(FX)t><9~OUk><jYwIX=DJ
zj7x6*^4N#cl*3}BB*;oX0#-^w{0D06!Tt9?T8;H3-#57bx*OO1`|q(2r74WXK3<T0
z_fA1#5m$KfLhJ)Imf`l*2Qo6eJog1^A1Li?%*)>R|G&pRl-36Jw4)2MH3MoZDD5D(
zI8cK4;4fX&wBrYEn}E_z2Dt2k)DNCJ85d|gdJUQ{-iOi}#BRS5$o>~6A-?w5joKna
zvtJ3t{&+~+5oG@f&`l@ZtW(v&<>n+INV$3FGOXPE@(~m`5ceUEhk6_b%}FzO9Cs1`
zb?HE-Y94n2cd0#&JAnt;JUY)Ecj5qzn;drnccwjhMc)a5mN*}E?L6~B{32*<uv8kn
zhz3$9L)T8g`-2|6qK7~Z>iqcP<pq%Hl1m=FqFbRt*C0asJ$gl_Lxmn+0MF-vj}HXz
zjP5-6V)`W>29FsY&7d2(j(c=6^S7unGcbV9f8%cfUD55)D;fjUzZgls7r352_#*rg
zWODR)r!xnC3+RM5s9s}`f?iQIsNQrWy?h|4&Vw(c5qf#}TMjV6?FB7FcIo!!@ablD
z?DhQL{F9r%{R|TW185NG0C*7T0AkONZ|7lf0|7LMbO<_#<fDmgr0W7?5XlF95a|G9
z45&Mpr}YwlUm9p<cCQG7NAgJ@#tR<3JdGZ`tPQ4o4AvqY{QVx_$s5sNLC^^Q#}@_X
zK>=Ty4&G0$#KgdG+!b^sC4=FCm!LsFqyx*gfUcp~co7@}{4JoX|DXYN8$Jyoih9%)
z==x+N13>pxdi09k6M)$K?HtHv{+1?Ce&`iF2Nk{#6$Z@<c=U?yg9@L33WE<8?-iW_
z6~1^5>>lu)coiUnIuE{Ry}-lJ=`7HEfRVqY2NY9i$CP;Vibg@TPl9L%Cn(U?aL@>@
z+XZ-n5P{t93HB%G&R^JJXCA$x@=y~3kWBav8iMOQ_<{vtf&_odOGL6b4+;BM{E!e3
zLDIV$s`tcsxa~6hE!_ych2ZHhX936NAL9J&#-Q74szt2%+cm)~32Xj#&{>y_)iU-@
zpz|z+z!P^*_*=Jt#->}}mUtd_WdMzp8y<L>_Xm{c9T;9bJ`WB({#GN<+{=kS|Np<Z
z027i23F(4Q7lwJe^T$i$KcHsTOPxRe|91!TcyzPcC<`+{_5g@31$nER<HgeRJPa>i
z|NZ~}MKjE>OMn0We+jzU0i51II|N(6+tfhEB(@#^t;mI+h}L}KKjap(UeR-WkZ?M4
z29i=hhY))7if)GrUp)hMJvi<`m$7(Qv%0B+4!;8(O!UGWWOp~Ki4wTro5%-Rs0=Es
zKr_C(A&IHO?Jwv^B-Ya)1A9e}@qyNqeFR+<mvss>m37Rco81F+x*lwe0r(1fapWU!
ze0o`DLUd0CQJo)O=!3L^CI^o5w>$&Q`E?$A@%bzyQjdXFKBAtP)A?a1=#;vdpiO8u
zzu)LQ^rG#>|Nk$&K$*=2l0HgKL$2SP0Wu99PMsfKE(0}2nxVHgvh%l=gU*-+U6kt4
ztij0N$_7eO-3}Zcoj*Zm9en@$|9`i$j7zt-h)1ue1s^{HXhyx;S)vnk23a?2ks@T0
z@fpamC;q?mKs~Rp0TiK|&VqxSzm*YWRT4_-c&P+ZF#)FH{_p?)U$TG>Q-qI)go6fb
zk2H96vlbl@V({oZ@6ma!JBY)j+fTry+l>db-5oTe1FCP1yQn};59tIgQRwE)RTX9c
z9Ts8H?I+UdqoUBw2f7;t6wHVD!K;XTdRbX``58QVMQ4L3&_w&e7mH7T=5;`4B_8K*
zSqRPu|M^=$i_k%{odK`|uz!LMn)(l2Qo>#l0iP#fFR249WfD31|9^IjN`j3?<^gbX
zt@EQt@@)^s!!Ldv`TsvVOaLyCd<nFV)I}wQ@rJgWh~@>4<~I$XV~L^db$DDMCn4}G
z4osm3XzdkvvC+!_P;my2?w6n=(!jGoi23!fV2{Q(przo*L*NHNO}x%)C8ga=%|G}`
z@|u5emWPAZ)&zhSU37kYaqI<XQjxy{bbLB!bxnXruj79YTRwFLhH^d7W#P>~Y)Vv{
z?O4kFJ-S&>91>!10bK$Ey1Le<o8y0ghDYNOkfqUahe3hU4@&O{k#5#Q%EAmD%?ykP
zWw7y2pKj4guyH;r31Blp7o>v|p^Hii=*VLSk8aUsP=NwUk)0tb7TqB#Ih`RY1|Z8p
zmu<YBYIxxFM3{M?{YNNX=Wp=?t!!X&>2>($*!+XNT-GN!2(<g)A}ACTJbFbtxsk{6
zn~zw$Jb#jh0Xlx|YIwla@HQfRJ$sw}pPXgwVf$~gX?giYk8ajo2Zb0QGj%SV7d^TI
zBtWiKaOu4DKfnRh#yRZO%K|z+547gR)$q2D<^|8rL$9|(%?D2%!J6}+Rac;M5x~8B
z56}>|Cb;tN6$$b<_=wq4^O9@kEdf4IZ|D%@n2iZw{jk0Vx_%B&3$XKoN9H9^5(R0`
zzGdUtdFUl*{V^o{f%U`M+Mu-%VEaJ^fkuK4{^A80k$DKzg7)mZ<fwTVvRxFOf5G};
zqo}^1nG5jY1HPb>2Y#`G$0T5;`)Z!{%sdPl7xmOU-~;aIfyjeD>|HYtfP_6D)`5)7
zyack*QS&ll3>ngAmh|kr<g0n=WeIrB$$<f+7(QZwu-_GIzYrGtK|_#^X!c{b7}gwz
zSgZuK_&2y_V*Q{1P0`?8ZHV;Y(fmfE+fl})*WtAxXj=kf882v6&tX{l1Z|^q?R9(&
zx@WumsYkbGfJgJs2PGCB;Cb9%4@&f0x*Zi9LD^Kq#o9@s^kBD>ilw6pXtn+}etCxG
zDg{0edlfYOyhuI)T0Z)E7L*SzPu~Q9mmi(?={(fUY{^)n>(N`HqTt#2;l<r2pp0Ij
z?b-PQvMTAt=|f-<N${LJ_`LLPXVCV5($hYj?1l$kzeLJSo$TO(>Gf5Ff8qUu#y6k?
zJ3%9o-Ci8vn?#QIbe`=7&)b8R_DS%!fbL`a)(DzE6#%UU1YgPrVt~&uJno_bTF(8S
zzjY<JeZ~Y{0q6lOrEb1BeHdKfcT|I9dtFpqKu5AAxOB6DmIMZX3M~)U&W9l53>ZMA
zI;afs>C914crjB7d^c4GXsuAQ-GBa;8K4#vXc_k_(9F@PgP;Ha&(8aU%m&@l3_51W
zqZ4$t2E6Qr-X{XShPK4An+<%3&{I%D3p7u72h@t|ylD9U#p$D<W`Zk2=MRs@BcLFG
zEOT&-g`Nk{Eqd}5KZ6Hoh8na&`bF^}kiR;Q^S6ElIlCKlnuVwsObMv7@*)7N1adwY
z*w>&y@qm;$9-TKq_Z$9)oX`8h_Y-&>Eq{v(=qj=U{4Jmzf{x99SW3h_tYxj`gc<l-
zqe08Nn*T8Kw+4coZ}-2H_c$AP@w6MrMGVLh?#l4e7&Ltb&+nl1AthGen^s;*f@-7A
zi!T-&1h)V{D_~kd9fa2p5a|P6Z!(vj0*}8z0u*cjs09K#Dh(Vd#h^1@x}61(Z11g>
z@U%QoqUh1f+sFpG;^iTDrQEL<(;-*Kc7WF7`+)R-s`i(lgM|M6`TxK3_{)086q^eJ
zL$|X8XtgZpR27eI$Wb5st=qw^po#!cYDoa47SGPVp3O%U_*+1mj$927G*n30f$uTt
z4i*5d$4c<*yb0P?^nU^<4TIfl3U)8(vNHHt10csLdGzvLVTC!?r}Nc|SJy%5i@yW3
z3IsGxk>CkB0rC@Q6M;X(wV<2MVC6%%i;Bx}NIZ11y$k~#EnxS*+eO8LzXg<-nt!l#
zg6=);<^9b9YT2-IvVy1(l>paHQ0N?YQ30*AVesI0J@KLdYO^1x3kFZ`xAuX9C<Z)f
z$KcWJECD(zmCXYjj;;(Zol)9noyT7qK}x(dad4}7GYdZhIQBq|=Dx!`3@?TL{{P>}
z26go7X&&9I))1vHkd-Ebls<<vR~4W(f<mv;mEq+DaOVTO-WBEiGsyh~pfaWNGIXKQ
zpJ(9AQ^NVeYCkCBlsLc_8odKAG@8fAzyMox1j^6NphZWZHRXo?!C4X%Td*wY80Q!d
zTYqHy9Aa?Zi--F_26rAWO-5aL#NTQUI^Ch0^~6pg29It5a2^JYa=cg%*1_Kjy35m}
zn{@?P-jBnh8*=mv=ZikDf)caiE#M`1pgz}2(6l({ygA5vA5ba;FHyPyYCwfu120kP
zJpK}V2~p?A7bale^0$C$ZcwT9WFM#*3tgVHotc4wzYlc&y5U>U@}#4To|bR;Te!ga
z6I{q$1t|wLjgOc3f|n;<1s7PiK%Lu8=<+0X{*HSfQACS$E8?{G*DE3I1xP&wT5seA
zDi<bzlfuhI@cah#A!z64@fH=(7!tUH)jI|3@t1=C|NjSFG}i5>VEF$<zc}=Yo+Qx0
z=0c!_Uwhc0=jR<SSpr%YuK?K#4B7Iwi-U=Y0pxqNOb!N62MDCXgTLhz$l0Jw0`5hE
zc3Okh{~mlX|1Q{kkg5#+mP}CT-dzIP0Pyj}k{9eClR#1dFRs6ab0S`>dI#quy!Z=J
z*3ICPoS@*?>!ZTxk$mz+<$iE+2fk809%OTGj!J<~?;5ZVJ-{c-b{l}`2p<TY;L#1)
z#Bsc|<Rxfi#6$A~sOW)KR5>c3<(}ZW3g%f*aqiLi@wkgh0f_nHnlJ-+;{<5grmNve
z&;l_~f&uLt0v*Z@ssc(t;rv4O3aGHDsPtj{=F$9~k-sGebVS`H@Db1-Up#*fK1Gbb
zwHmZP7<5y_C!fxrFAhBCWpF;mqRs%Z9@S|OcY*7DpUy`<oj>7@a)dal6ErFVAHM^c
zmjFs^-99QFFXXH^7+&546)3Rs%>xoxkfo@OJ3#3K)DVFt8<3}9=6iI$Jno_b@z%8O
zU~i?tJPyk#uRxha^D->6fR1v2EO_Gw7c{V=>RvK{=HS6SC3t<rj&f}hI2nWLqZ^=G
z#P5SV09x}V2Pyipg+Se4i5JH~;++RUUBffr9L?VX+VA)Rr2geR(7EXozzq>l<Y#~m
z8Ru_(0~$`~{MmW@h1Xull5&q19F`mmFZ00@2n;WZL1u#N0^MK!axK{1u)}j-s)M@E
zksuYI;A}qs|HT;#4u+S;V7=h-64ZTuW6{lI3Ei6yiaf|rEUdd+VgouAR0GszP<WvW
zIy$*KL`4C#(J9=c^>&3GXhw{G{UMK;9^XN?P<66_TY``?ZyXr9oxqL3Jw70D@O`MD
zo3A==c!0F@2L1<4SVPVoM(6`4me;$$;f-=0Zvdz$$Jsmt-6scXDS{h^ki2o+MFqTP
zgunF*BLf5Ej=JmMWu74KSb&CQHtz(L*8Clyqy!3g&}ql~eX5{*+5Cgqr#nZ*fWPG$
zNOy0Dii1z*OUTwgP&he&lAEjH+ZX;%ctPXEouFHVT~r)Av|UsTJgi+*EFAf#90ip#
z{4KM<V`p#qTR|7BLK;+#;5JkoXztuv_JIhfX%)!AzyNL?yaZVYs%k)1G=Q#)28SxB
zeGNVm+c6Hb<=6$h`K5ueL=&tDeByBD%@-ZJAx%gOEuj4s-J&-if@>=NmIa_|aEy0=
z{ogtnWFw^Yc;h};K?&~*F^FUf7pMyiX$k!Yw_Cg|9Gfd;#Q0l5cc^%FSAv^D;P8Mq
zg{Fb8COO~;x=_=%JJ12Vodwz+a)7pn9RE*(Hi)`iRCM@T+L<A%FB}l9I8dWV&ZC!i
z{~taENE-#zC{jHS&d{cy29X1zL8SNh|9|jxkMQ!uqx0emhwb137c{8X`v33$|KRim
zzH>cof+PPvUk0CU(;eKx437V=HUG%tZxsS9Q{><0%Lo=o<OkpB0aC~W7AWCw{QxPF
zK<iCVA_)@Lpryv(2-y!h%^Y-G9CEy&w3T1_{QLhORfH8(7sA`iU~@qCii6v!2+NS#
zwo8A*LdK)>*9-1*ppfD35C^sByPX9ffdfkEf}pYia*Y){4NY*|3o7>!^|UMK3|LUx
z?j`8Tj<g9VZZkaaQXkYN=oPK_4LVQv=8M+t;MCKi1uE!zMbn_dc~D_th;TSmI2<Yr
zD)c;hMUA1t35fV<NdPsiI}g4%vIE>c`R@t3WD9g&1|(=9y*JT+zaZADA?Z|u>b$iB
zJTU6md6d5ee8W2CQ2lYJ_UGH63F9z-%X5%ZI}g5?4bk3toWG?RlqH(A!RL`Xb3m3^
zd+dbInRR~fOuh=9<j=eW8Wr$hJk)IW-y`|BN3RSMe+x56cjpbq9pIsfnV#Q&fDTV+
z0bL;uI_DVFhV$sHQE~9-<#qW5i$PE?791g+zg{?=fyAUQXh^j4CAhNw<N>Zg9YDHY
zIQ;tm|D_~2R`nVATU9|mfDi6L68Ue?hKg?1SKQ#X_xGQm&7T}E#CO1^>TZMOK}Q6^
z8}Nn)ULFODhAVh<ih+8^4j!GM3@<l;1>sdo892CaIPL&@9qzqF3=9k)?{R>(5y*h<
zP-O$T723KtJOH{l{$(ntlH3J}JIMWt;Mi?V2Kfc<1DDPZFRei;C%{yK@3UzJUHN1Q
zRtbxg&L1y@Knl}g3OPWI15X49fEB`A?b7+;<qOaVHz-~h+9xxE4p9TeO9?N?(cr!I
z=^(ve`6ZLDp~{2z=7V~upgIp+Yqeg2=mfPxUV=8SgJgCxEO>mO2h<yfs^M<|6)7Ma
zKog)ZK{*`Oo<ZraG{5oi>0YA(%H^GBJvy)Zb{=u<Jm=V4%kZDS1+=ND^<-UM^IJxb
z?ky^ygNO}pdo&+qd~N91%`&I?hiFMy^A9op)=mb{0N+Pf&>{0LU+e~tL05!>7fLiA
z<M6P2U83dDEpi{U`S}>4oQ2DGy8ZC5d|e8?Z_)6;Yemmam|=eJKuNN4GopVEPG*q3
ziIAySaGwYv@6pYg%Lz_=tG+`L->j`X46jdkB%ky+_>lQU&K77EbWyS3Z+Q*5^t=yr
z`B|^)e~<1M6$_YWT|rl(9AE^sxD8(0!@|$Gn`IBk>ycougSLA>TnlR09e}j@0z8|K
zGkP>1=J04f#^GaGqhe4J=+!Oq|2Q+KZG7ArGHB6ysdO_^Xmqk2X9kUFygr05FW@cM
z_ZvWMG>aFzHp4OzWSP8=iUnv7c#H}Q<Zd93ZbpyZLJrSPR|dys8x_z_p5x7b8A}yj
zml*zUwg&SZK^yCv53_(==3@DkzwbEc7%FQq-_94EH7W{_L*^a%ryO+U-*)mv!wHc6
z6%DQbOZI|yg}>epItPIR9K7D&Ai--53Q*9&2`?n!4g@XHhXo_(avKZ7+pnb|{jugB
zVkOq_xNknrVR^UC6Plh%ANh2%d3JsTJLBhzhp$1_S6+Jg2RwEP>YIUTYa|uxzk*e4
zczFxdC45`o4GF0Un?OU1FRy{iCl^qRGJrzm^}`qY;7;5L9!_vz0G&jkV0Z~~p>he|
z3z=1*9gm>>9}FcNofjY{i-96{F<63s>LHjQ#6PVkOL$%`M~nx64-h~)?-{(mvhfY5
ziuUMc%>tE+omYK24}&^<=Y2ZQd0HOu;CHzNp1M{5H3BV<^0$bC83#T1U4DVCl@<Wm
z-@Fp!F#guvpguilLT?MGjpQcN8}J%5!UEbH*Zv-)uRAQjqxshZ{uXg&2FUPhOE_3O
zNC7m`@6h~1l)n{};5|S$W@&?r16^0x3B8J@bBzjUX2hd&4)~_e@8AJZ28IU4Qb~_)
zQQzyZrdswoNKMSm1TKI>Ks(HiyQoBfXpdgdNC~8}fpnxn&EEjWouG47zy#>be+^L9
zQh1T|8x)EB9T^};w%+D%kpy|nM<oDsz(qpyPf`Asa8T6-8WRDxPCY?mk)ZKHQ1dy%
z!}0=uiy3ISK(~uZfhUNk0U9rD{=vZC2U`CCIvb;BDX4Tj4!XY+!~g|fFvz-QHqc$A
z5m))aHxYP%8rk6X`*9Z)c!M51hX*+`1|$#ZtaN^QVUz?ueVe~!J;-&<H7Xtqb^1Qt
z4g#PmEWz+3Bz<^xik$FhKFA0XEbw3sQAzNy1Z~;x3{gp_e}r_U5VU>mqj|!!*M;Ff
zq$22aQSo@`3mUk9l|SG}y8^P&@;HCXX%M6Hui^ifSD@+H14lf92HHST1B;@U5#UV4
z&|ISuBF5i3@8AFbK8!vp884@R#9KheA%Fs|53~y(>L&0Bpg%y7<^euQ3*27<RWhJr
z&G6gH#h~+~Ji4K`1Qjobq}K<3|NjSB4&LW?8<Ztm|CjK9+J_sLfmD<VfcCg81+)2E
zKsVDKcToudsonu1VCKJc1$z*DpJ@T8#RBQ3gYUm#1{X+GpCAR&s`cR9zYydPdC++z
zu@HH-&k*@8h<qbl-WDRi393H}BA*CqD7&ZxfC6m?h<FLPMw*omqTCv)+!~@BwE6%%
zUflWXg~xhu$^hTxG50Tcv4JqyHc<P$oAoRc*uAqpLfrFf9oW6#GrhW5H$Wsqp^|qY
zlAzdyq$f~$WzhUf6g08`sxM#%h?KZD{}L-z0nG_3fcpC^$3eNOLer!37I^dLi_M^$
zG(bDT4|{a8dO>XAhx(x$Y>Nj(7IZub$OI*D@muj6WCAEAUKGMjn1BE--Hs}bJ3$AM
zx^y0J{QeTMY3krFHqAreBY`q6ftsU^mKRD`KZDK#bZtEVK8vmNBWT_TQxE9q6u6$!
zGa%)lgHK8ixqxP=FsuNz^$^PEf|P?=f~AwY10{BVnpdrtO52+&MHqH~+EV<jp!GG)
zl>!XlV~zM*GeMimDtQ<|opA>KR?uN~h6kD}IT%4_Vu8~)XoGqCcTl0x%X;7=AA@7(
z1;1pL1|P-)pyP2J7{EFYBibL}MBDs}rHs2bfVKGmW9vzN*F((*7!O0|yLN!qpS`{Z
z?=S9<W?*1=eGb8w1M&AE_=+I@Is{(@#Gi-YgNmoueF(lbs38m*FN36)9eN->bjZtv
zfnkRsh#w6pQb2rj5Z@cYHv#cM2j@Wa8y<KGI)ejlK1%x$I&<GWM+J0skWcp>74Q)#
zpffDadUjrQ1ve+*hxIu_R^c6Y1_c3w$8l$HQF`1Nvi{B)G&0S=-<J)#D5&`tGk=RA
zE9g$$KYaWx3n5~x{4Ki7pd%>%m#{b<1Kn$AI`g*>gJ<V^MEE=M@8j=054zuuzr}zB
zw3zKUqi6G5#?ohw4feYHt)Rm#!R<515rPf147&U+;%p2Ih9^CbAN~LT|Nj@Ai;>pD
zLv(e3Ym~oCzP<j8{C#3<44}LD{27~H8Z`gp<ZowXV_<OQ-{;Qc*!;r4vH1rlfBPp^
z28LdqPRCvzk4|rn=9i4%^>ayVAQ$~*=5P7J!oc9zP|vK(-+CT&@PG4PR^Q%u7XH2~
ztPrzUTzfq(ID(Bo2odsUb?ptj;Mn|&lfQi(D+7ajZ%c!~|NsBpdtDqaxV9c}>2&7d
z?^9x90F4bLp9Jkx2QQrKW^KR3&){Os(!t-)0&xHve~UXPbosZrv)P1{aM&pDw`xPA
zIDC8E+4=kafu;Akvp2sm0DI^yM8KZ|=IJ{iAF?#`vVc}|bvg_1w<oeOF!*-9^lW~~
z3AtO@v7w&Riob;u?7`!l`$1=k`E>fISiFc`1sYsrjruDDTJGZife&`&PB+JkhbzG?
zi;lVAVBW?LY6n;}{EXsnDFj*Rcy+~J{#MZ8OP<Z31K8ae`TGJOj&o;(xz-*c5YE*6
z$^aZ-dLXT!I~pAS_Odv6_J%Wq)}ZxEfSe2(&3p*b&`{58#ouxg<lN5do}j~Jz}tHr
z`S*##%&7y7GV$;8XLM|SX#k3z^88+rNuJHenH+mX0)2Zu{(&~B_JbBdH~iEsW%+*N
z`>pH)M?5-jf<3Nzq4Us-jKiR9a6T#)p3OfQ>ZM=$u!7DCg|u%$Y16a$B_n^!dC+MU
z{QLO9`alU991f-TJi1xC{|GU-cK-C}6@B}j59u_r_bXss1kh0z;PQ)qAE!sRsn<^-
z2GC$r34iN8P+N7MFC&PX&)>Qp!es(+Q}|mKK)B2xZX$o{L<pA!#I59SZ31;}drMTn
zS37}6-$1wIiu!y9t%UmcUz8if0EOl&&>&-Ph)RG*=dqojGTNi_`sbzHE-ERkIqcx{
z*~#4PqLKhQ9k+Q8_&Q65PG=6#8l6sOo)SKf?iR4%aqv1$-&RP5XLM}-^Pj)v87K-m
zKe%*0+6n3gznHo1|9{XObD$I8TtMq^f3bnCF>g8#S_=2Vubbx)sLcXeIkW!_sLEw^
z`3;&6<9KmkIV`w9r%FJ|JBNn<y8JEvAooK`2uJ>X?7bcrntyWc1hqcP1YXyJgj{+Z
zE`V}+d13Pl1CL&wPEf>o%m5WN9=$vs9-Z8!Hz0+}VbF}m{};ydL8p2_{aV5W^I@k2
z$WtYvu3!&!{(NzIE!a0LMxf36pgSi)t#OnIK!~xRiINxh=KcTw5_BOdynKelchq-C
zeCL(M^Y5!=?EDFez(oF5kXiiue8I6@Qd$cdpM?cKa$l4gIR-$j4Db!Epc@_?kFhhp
zOa&jh3rVkz&42j#TQfmp9Nny+e}c2~jaQ&x=6Ip73>LniRgaMH1@|Lgeg=(rHvi!(
zIR$ZAK7Xqk=tf(p)5`f<#X%;5T7sZJ2Tf@Q{1<)lMTo%z=3Y?45LCg#MzD~b3=&64
zG$j&{@ZAZLd6BUO62#|0tx?c5Hz4yJKnJMh9s2+OWd~?L6xQB`R|_8BZ-QolxnE?>
z1zl78mcK<0w7T@p&;S4TgOcG(&|*{H&hsy0{(!FLJkI<w_|O0U;3DrO%fJ8seLL^J
zbOcNN<@W7$=i=|14LUW3f1f)Stk42AejWMu`Ex^x*z($5Xz^;@=`6zE54!9fRJ``O
z^LRGD<l%1t&B!`7)bm)CRC{(F-w$fxyqpUPw{F(VAK;i^d&S4#+4%xA^?i8>EHXgb
z*FCyf-5^SY5lS||m9&DcV(vWtasueCUC=ajiz8@Iuo+aBzGQsq0v0~b_ObxX_{-<p
z>&{zu&XIqgJ1@jD<p)6?;e&c)3zA19_}f7PAP|r6dp5u1FHv%AsOQ(?Z_xwY*VTD^
zKPZx3UI7Ix*h|Mi;RqJn11f*IS$jamOs{C?OStF0ErxmSG^oUCnG9OmdHL7>{}Vi$
zkF)spI{ta73t9@=dEM3Uq~WEP;4LuStj-XFG7v$qb}<hFX!ULj#3m((0(OLg9;gD)
z&>=`+G(_RaZ$hA>W946fF8UQ!2T|P|FXEw!&A{;v3cR<B{H=>Yt4hrv@pSMTIG*GX
zUeSi?VS*UE0HWaR3%Fmopb8%T23^D9`@ysMxPT+Ld24v7+gYZUrGfE)Z|liUXPG(~
zP-_Sp2Lg;IKt&X&Zs~NE0i7Yy{DQIcoG<9|zCDnX2(RnGDHCGkf$U%fE|77-3TVci
zf*TjC06GsDWZWgNaiC*n5OrpG5!7`jvz=AIMmej1je^#x<pPWs;6^#CG#_Mi1RG`e
zzxgMN1OMFP&BuAb#_j_RKko(Yk^A5Li`jvH{_*DH952_P3rzp@|G(k?<{wZMTrayI
zDi8vtprQtPUTX8N|0Ucn#Xx(A!1d)0I|c>@r1m^odlxj0)4c_JEit0NbnQIj)6MD8
zdD^q{s!QilPs@Xj{8J7!{{t<2bL2S0-+Bu)%C<)ZbUE>V&)!DRZ8MJiQx1FB#>z7=
zlySPY+~#i;=44=K{`a51#f}qnT-6hB$HI|+>M>Wv&&~gsTsv=h@Vk6)ZMnqXdK#jF
zzts=KFnnV8zj=>}1|tIlONlIKs3-%ps0t#&T*6`bfxn%T2Q+fV?ZLnAs!uQL#}}Y$
zW?%jn?S3x=o~GZ<#lYaezwfH$1^)ikpuOJ7CmcIp`Y^t9)I8Ywt<>AK<zyZ6F-Fjt
zMOf}Y2A%uM-&YJep1S!5^D!pBV@`~T$DEi#O3oj1VrDQr@cJa8eeT+FlD`jho`GY-
zPsU@6y8JCxT%fa_f;k*_q^G5&xpZD|JoroA@%xK|znEM!FEt-BaBTR=)Dg(Y-y#52
z2~zX@g-hp!gFoaC{$kQR)XOr7@qnY|A;;!J2F?E%T{;4pTzdom^0(Y$XJ7yYS<6*U
zP;>hi<1t5OUH%r(et(zlXdai&8;%Em!!5f7w(J*EM<5G-%VJKDvz&PxcR`$Wz!7#L
z2(pz29GedqH2-69>2PFq?REUc-|`+5CoKo~`;x#`{$M=j$QHui5&||ZS^#e4E3p3{
zR{mh>2xRAPF#xM^76A8(p~sJ4v5eKF!;!<a*YP`l%Q~24UpYYj16c-Ya6jh&xjkA0
zr)6CHEr-EsoJDY220j+Y@eA00Y#ol={4EbSK%senzpou`8;=!#OC{K(XbD(ILBka4
zLC1z4OubG99ge*GE&gDY&JqOd{0O#_y~B}@zl8_pLt(g`psIouY*Mt$uFkDLVBY-x
z3X~#vT|mbo90teM4YUMu*roGE^8o{plR6v)_*+0VjZ1g5%&xWFw=<xD1-es($3^p2
z=LN^k%h*kEY(5M!gW07cQjou;iX9Z#&N91TgCGZgz%FJv1Ty3T*bvZBGFal0!==Mf
z$hFt;Eq{v*EOa%&21d*5l5c$-h~z3(Y_4(yEpk5O49x+Dp-y9T>4+5OZ@JF~a$2^G
z<8DYAe&KlVue{^;*Pw7>a?yO@*m=nD`)e#2$))oGJe)-MTc(4}ah3tc+iTbm4<h3o
zfTWdI;CSQga1`Zlc@NHc2l)G<!Fq!gpfLr`-Jme$b<w;83Z6^YUEtX8gV7P3Zp0w{
zbC>R51!z3M&EO$u1{1^#asHOete~)PR=^WY*nHOfkIS*w!N9fG@p*@%1b>SH%wNr5
z^MVziu>^M$D?v9w{UyoY0_vr@bZ0BLbdnV_Qv5A{Ss=b55HnA}F~i;AD9zuJ4jQZg
z6;KDkdV^KKF#}5?aDO1jPv-@f&PxY>Fdh6QuXzF7zyKAt@EDTeZz+YD1<6TpQ;=f_
zmnqOVlI3sF2b<!of-jChrW`_Z%Yo*9JkVHr*x@M0-_ipbF#-AUF6hRj?qC&su>>*^
zkMHF9Tc$HJFmxBIbbdJa51xHAKR|L1R^7<?M}fa39PA2b6_4hFN|2ZW>B8^@)C>1I
z9RI`nbFQsV_*=@Ep#?7==q|AT{2gp83=GE@wOu<8IX1jv<Zt=L#K6$`W7pP3Kk3fj
z-(P|1G;o#&jl+UVvWwtcb^@(DJm}bb(7>_b7o$suCnJB$28b!319-l_a_Qx<ay<Bx
z)lu`NOXmrf&U08y&^*@p0bEY}V(M^Y;%~_ZEjr3RY2%`KzVipDocRH>(6QkcGdMRh
z^S6M`;{;v5*nE)HvH1ln;{na%&BqNKIx7FWwjAK^pYr|x|Cf`%TaH2ZAAp)f*Fo#P
z|1p7^M4(pCOZM;JAvzaOuw3GAN%{W&|1n2UQ{!dychLC&;K3G+7x6Fu|95SD(s>Lt
zbfUpO^+5AKR!9D6$2t!=Djef)0WFPchBnLgfw~$cB_7?(KD{+61>IA?tu>!c@CEe+
z9^Ig+e;1Vs$f{$=s#wrcWY7)EpiZ?1=w{!}7VwnWi;j)||93;og*D9hTRt;_+IKAF
zoUSe3_*)~GKsOKne(4Lk$r@@WXm$xa`$V3tM*aW)X9f#^w%d4Q9sq4e0d;FFJV5)o
zE@TIb*g#mIu@H;@q6trhKx;htTR=N5LA%y`x*0sW0|b1!JtVpv6hQmbJUSt(9z71e
z1kW4>bo!{&bb@B~K-0awPK+K0Unzig^gDPSe4)^I2sE<O>7r5r8nB80Sq4frkTtcS
ziN^vDl;fvBhc^8L-Gs>Mp?M1I;}8{#7rA}^|7SyHA`u(X{(CU~@JQYRUY+Z~cwD<i
z#p2~+@PrEZJdN0w;69YnJ<#YpxUc(sDy%!`^Y#CKN5#X<|5#l+Z}GQ)4mN52$L!d7
zjlX^4m;e7Ew;L@7Z?1=oXLvLp<ayZ+>O{(e*DH3ns0e@-2^`>WiTnE>ltSxzjxk1o
zx+tJ&y_cR4LH@o6UqES)4YcX_I+A&ylvm)>`TJ!9SdhV^`5@;@b%goQfkBNIo1gvv
z4^61e|5*83LD!Xo6Xi=ONaqCZKK_@_e}gu^g57tFQTO}(m!CmvWttBPLw22ZvnIU&
z2MPNf$Uw~WDX{Rc0Ue*wEt<B6pP};r^pYLZ7eWj^-7KFxdPVJ^8kWH|aDz3lzI+bu
z-`d{<_ix=nR5!<qdbqMD;4|wFioNuKxJ2@$GlU`Y(h9<me`)yp|9`_vpbKp(LBl_t
z#~|L*{EU2l16qIU2k7{yUf#4HybPd8<r2uD7(TtM9Uzw;cTuTe0L{%HEyo3=ZwHTV
z*3H}a89a`+fG4v-YCvmqLDSD5u>~Ljs6J4S4#WlNv+(GJXaFe!EqDP-9B%=ykO8wh
zK`SkLq4^)QWe4P{3Xoof7mEEnpx#sq=<XcQ@E*8aXgyHE0^Uj3?W0lw*{o@J36#@8
z^ERNBOW;Y67p(EnDZ>^OkmLAUo`C1&JuI3lWkmVG*DZm@eV>7&b;WHy2E*H+L7jb*
zK*Q*e8CTHhz+9l?pZQzZ!J2!(Mj;7508M#!_o#rpj3f*?xgRub3-U0M@Fb{e(CQ#0
z;cSp_>+KTI`m`7CcsL-PLQp)R3{t|z&tB}F1ohcb{uTzXyXHU^o`a_P|AEF?t!0B>
z2{G`ud<1chL&{KaV1o+X<1H$n6`LSF^elh=)*B#Wnwc3rdZ&O3T%TTuB2eEqqz@bk
z9alhVx*>*n^xDq6#mBG{H2vTKx|V^z^($!Nyqno^4`{{*zQ&rFza<B(4<4fYE!iMf
zbvtr&PXGnm_d^T}3<CVEQ<)hU8Xqw*FmQk-)IqKT4{Y+c?gt&C*8Jzc<37+pLJ6-+
z=cCS_FSb4Y|KG9m*iP`40m}gB0lbiO#oq#2eCyI#pa4pJ;7I750**S+94}~S(Ge6w
z430Y-KtT^nfuM6~!Q$``6Jj{tqA~^K76umZvL%fdeij^{QXaI^39`Dd^WY1uZQxA?
z{H+T?VbFQ=#mya{sWhmUy9+oxK&v8JPlE1<2c6Iix}px0JV5CZDIJ`K1{5e%kc1CF
zg~9$n7}5$AMoUapAmPrNFP3p}fOa>$==;RM@N(^6aODmy@46j1K<nH)!PEbs@*ctm
z?b`;=w?pNv(d0$Y_;0~QE=d0raDoEu80|dxLU#rzVvcxpGlLQVXeb_h{01AyU7(4K
zx!{(Yi%LniFM~_xqZhi<z(dEapgjWJJ}M<IY96sMbo+wl8-%v=gYPQy>E<~FE)YC=
zMfGlg3SidDk028c{{1`*hPPjOf!zZ0A0*%nZ-Z_!ZM6XnTt*<tgVqV%e9^WV9A_Y7
z6Zl)WKtqF_H$huCKzZXu2Pj56k9j5^11ZROT@8vZNa=GDvQ-?kgxTpJc&nWwXr<{1
zP?_BA#{pW-oMCwBMcg)ChHe*?5|8dM4#&=)E}b<h2B34CH6V-nI$cyOx?NNvK)dW;
zym|v#S-{`X0y3lXCTI~(0(kF0%X;v5Ive=l=a(Mc0x#rOLzIGMC|dvXw}S3~a0G8%
zc-;t{5BC6Na>!=!)<2;0l{#;}VCaIb(L2oFDgipI;r2^$aE%9AKLK8j3E2<_YLndr
zUrYb;J9tRXg@NJ4;ZCq-{+7w0b(PT7C?4IG9=+lJ!Dk-`^0%0SQa)(2Qzx{z?>yK&
z36zjuYJh?ktylrOr}Y4Tha+f_45Ccgca4u>C#c!z11eKWL*b#`49YgDAUja&p9ls9
z1_p3B@$x3jKQ7&=3@^LEJaByuD^3jmzufv86dt{{F(7+D<p9_o{#MZNDym(e)jFUm
z3l!%dJ3xkj*2ozC2anLh&J+g?L&MnlAdf=xP8AYc6NzmCVuNzQ#DD+)8{U3733Rz~
zcOVBSl|}pyg6tW33A%p6qt|xVRg}<hM0R0G0J`fyt~C7r@)CFy9Fn8YgX0Ur2Cw?=
zW?g(AT;F9}h1GX_Jv<CAxxvl=D}24&1Cf40K<Nj(-mdwL2gsiupldlgPkVG;g;pIU
z3NMzlgOf)|tw%S~1sMD-DWK@;JdC_o<K_$Y4p3!M5eUjA29EsO7@A)s*$9+td-RH~
zxXOoeix;fE^JuP7v0&ow2c6{&DW6#Hf)4-g74^CbDhoJXcy)tTnrkzbh=BJ?cz~)+
z(Bdyxc>qq;{{swOKLG0ona5GL!;ycR1BXo-e+xe&1A|RL>2i-=+p|~r7{FBuIAN4d
zIqnLoU>RQ9dGy*I2FW2Mni9~`XvncRujM>?ZI^@OK`U#(dih&JAo8G811b!A1OD#-
zvq5V)g!x-RcS}L<2!Y=G0y@+4r44v>zHJJ~FnCVjZ)JxV2C8pgZ-mVM_S$~B%*XJ0
zBFGR>`hl7PDm^qjIuE~WhPLNH{$#SrDG9eJ;%^1rhvCs{d+;(J!%on$9;jPafR<*t
zGJwEKe~1e<fRuo0SE!O!h!XJfXC27m7D)K+1o_#c*R~Yon)PWD(At|4pgVfzsC0lg
zo$OI*0H+Gj(rBN~W8h)_Eh?bPIzg+ZXMnl|w?PT}0>~xM<|OFq2@n?~4!SG?#s)2r
zfw4i2B^VpDU<SnIZ%G3ks@ppSywDnaD*o{nFdGz!$6HiDXW)Qh<i)EFXoIRn1!OUQ
z%O4g725=z1&_DkdvJ<>T1>_F?mUwXE1)>ntS^~KO)|&8OVqk!-#cWXlIThSY?S&`?
zH9bIq=h3+Zyr#$S8z|BYKrIwdmE+O52E614-Z}#<005mc+zFZBKHj1Nx|@lC0o*15
zZ9!mQ5Mg|=Umw~WaZxGYZ&?PaWIGSOn7I~Qx$*Zkg9N&3R0=?q-p>~kmw?4VU2IU%
z$lp>5lJETaV#a#Vj>n%M2~dgm;>0F6AJi&(F=H!;-=YHAfb5Zc*cG&K5Zrf%miFBh
z96sF~9-yU~oi!>Ro}EWP&2^Agk8TUl%G3al?h3ek1jy$JAQfQqz*{5vTed;lVi`W2
zXI(mv!^dlUx?Pbrq<dN(;BPq#I?Joq<B!J<`1R!9U&4;;gPs`(IdKEDIZg8*C{K8}
z^m?*`7A1ExxbS<P1UbRMGx?xngAF?ae@g;r6;$VIpUw|HmN$x{eL8P}PQ5tzi`fHo
zg7!;$55`j-7k~Nmid^vQ=JK>WQDgk_2ODUO3F!QZOW4$U^om^Y0ITKiy$o6i)OpFr
z@<P!?pU%TBo#zl!T^^Q)`CC{)@z7kO;=sV)x0?+#knzE{^OcX~1<;l9&23;2m@S^2
z7d#KXu=im+1a=Y61<!6l56fHihA(Z{K=<AHbe@8`2Tdi*1y9hH<y-uHlAtv@od<m^
zPZVAB>^uMp9tYpfSC9>W6&}4Zhe5|?Xdd>pyigqP(|N&1^MJ>}AIzW&QVzbd_h7u>
zaq)+5FV6wbZblEw!!_nFmm{sW@##E)O}%HY$N`UTCXjb~>%i-QF8YG(2VF#@c>-j-
zC*xtzHKu)Spt-$cp!NQY&Hvavl8^DXfJ#nqOqDzXg-holAInR{;h>X0G(jh&Fne?!
z^f(BLr4t?(e|Yrr9P;Vr^t8NLum3UzT;7}jrGtY%m_0iWdLDdf4?0jEq>kl~PdA5;
z<!Sz2Yp}9|9+szyE_yb<X5?=LU7q6EDWl@SoTC!p(Osev;lrGwlHkDz+CJQzqmseM
z-<k-z0Jigo3+Q4d&_ekFP?`qiEKutWbe4?+f9nlUmEY~7Qt;yN8c?sGKmgnu=<WfR
zHK2CBE~txHst&4OL6wvosGbLvLx$f#z1jj$Sq4%j2~t*a6C?{Nia<haV4-x75V*K$
zJy`+~@&-j|fk)?OkJbYvQXZWLUrhVQ&d~gWv4q#7^&3c$9%G4x;cd`fm&PNYA{ta@
zI>tE0f;WF4+5Ea6=B_m`#srUU*tXi&dptT%_;g+bg<+ousJYP_z~R|>>LqBu0<=A9
zc);-6OMB3*kpEfv+jBsR>3Uh)&+##I{_;o`nc%^A;s1l?|E&BiCLk$LcLwC+2G33w
z74RtzE}iFmI+5m&o8K{dG{0tS{`Vi8G-N^DLr^9LC5_iUou7OxZxu)Rbl!kQIhLd$
z=wo@g#^@#J;!e<d9njU6;8f(<dC2qND|;Vs`u6Arr49if%gg+|Gr>g@By}|ZXXbCU
z{qz67Pv=3G&K{LDpz)MW$RNXu12y2W(#{s}h`@`DHUIxxLfHH*oPYlRcj<;|=!R$j
zU3}yTp6dU}?wNd$zl9IHXwHV6q2!4#s5tuQV|kOm8PvG|`v{y*P_m&<ugF2qZXr+0
z3pEBWx3VxWfX@ShWGEDc9=$9FJ-P)z%lUgJgO+iEGSS7Ni!ZZ(|NjpSWAJ=EWJ3!)
z>uq8L&4Yqm^bG7G;=|XJ5mZ1jfXZb^F2xzXl1RC)`9BkX>xW<1!#ANCC42*`k-~S+
zFKpralF_sI1*2p0&;Q`?-2qQ6$l;p-w(f=pmS95(Un^$f!dC)RKf%J68{8si)w}|3
zd8eJ`V=(*%8fgk?fQ&SOvO2h@`W3W_MHW<Cfb!H$So;^00{g&Q+Q511^vh~cK7%R&
z-LGtUnZFNwtOiv6H>iUL%5<)vWmglxt4<&TgIB=G_7v!lB+J7-y-pnbeYL+p3#m@M
z6a>>Jz*3j_`#?<@&t3-(-_BFeTBxb&C+Nze125101jWrI-_Bc}mM8f8)IbjIb>i^t
zy!`UO50GImeL6q#w;TY4spUz}&eO#)KA<dyE$y-#gj7lOCNDu-HNoi*Q6XSUzaEyi
z`1@kP%bE`OSRO382rB6ud^<lPRbHU6aR(30!=9EWeLGJT$AZczEK%#*3$mU8RD+qm
zln32m1GC=;i)znak%O@M3)I~7?7ZL$vfrokhEI2lih~a{jcXp}?>qv!%M!VmDyf6i
zUavsm2`Zv46$j(3y%>Eg57%hF4nr%S4nS)D1K?T?R6a5ISRSr51C?=>r;4t6HXml>
zZ*fDny|f7_4S-IJ0|f}E&_2xH7Yc6eLkexsDny^o1HPRnJS;DJ^m=gc_kkK{zMThO
zf;MCLbRO~qNgd|z+XyQ3dc8P&IuE`C-7M$P&FXm(oW9jgz<QP?wLA<jXM+>V!Iv|?
zgA&aJaH6@u-<JYTG#=nY1L`aLbi$=xg0f35MCw0i;n4wC!;|1GpI}cog2xA5T7cGn
zb)J6t4?IA^dgcPy^0&ufnd^HE55voOpb{5cd%T?g4U~8<d3IiW=?%^mi1jmQ{T0yK
z`R+L?pdB$D;4Pd!oyUAT&w_d%pmsW_ZUV6(EpP^gR*e1%s3wM~dI4fU`!S%N0*K4s
zVhUP(4;_(&^-DlwfzW;l=wf$pza$7$n}CjNfegm-x9EU6ADt~KAj?603rHWO`w+a3
z0xC=RTfnV;*a&X#6mVAr*8RZJSAh<|gU1&;*FaQ5I!d74259>e$Qz&rvj()+1QFi?
z>##uTY!Sv6hRX2XNCkh(A4skFf_ovj*TLT>26BFPjY@^#B~b6@=L^OeU>Q)i1C-GC
zTdsh${CvT&7}VbY_eVg@sTUT@;CyiZgkvR$4;_n6J`8djyzS)yI&uZn*~kz8HOD~e
zJ-Q`4I%7c1xCm$`Bt`|%34wG|K%=_+EivHZ3;00iI)mbhp~0tH+|%+Ve~Tz+zk=m0
z{uUmP6PsT!x*9$KwVzy6GQf9Di7|sW?fHNru3pfm^TKf#6(5ihzMyN}4|;S@QK<lT
zf#-m`z&@6@JUg%RH-qM3!8JR$0Rqa$@Mf$}FUuj%ZVpe&Q#EEULE9yu?J02ih^ZXZ
zUhx36W-s#hWr7^rdBDf=P|-z?&I>->TcDPH@a#NX9P88h3ED$I>)n8R2%eS~YfNAM
zKq?OpVN>nV%X7h_ThPby6o21MaCv;f$MOKEe{&MiEdven6!>Uf^ws?B@%<(EDEWiG
znLR*Vv{OF(>koPM@?7!&N#F3aJXx3G(;JA?r}O;&3gq}s&=m*vpb}5>f=90iXk?DT
zL-UZQ<|Uub3$DFE>>jNL9Qi#C!Rkwo<O_}sHKGiRp3OJ@gO|e}WNiMy&hG-M4@w_)
zhp6~~g7Eu|)=NJ8t_OTTXMQl3s04U0*Qi8*TKfq;)+s6({4D|C_~Ju!)jXSzFoM&=
z!4ghS%R~IFOrV;$o7L|Oxb!)F7*_gJR`4*q=7zMQA=7EyJ>W5N4|of`3e;!^=VQ1~
zF-QoMgAuC0?f44hcKo?d80~l$P&&Nf(Rc(@bYW@7gI$2xj)z>e1R1b=-GbDn-{8}E
z(6{pgEId6eFV>ZL^g43*b{=~P+T;taB5uI@=bo0Q>f$_l12}v;4?~l6lP0KG?!54_
z2}B=<4lF?`3LnsvKV&2U)Jx)Tbph1{pt-yki{>LbNH0%<k1RX=at&yibm#Gx<{+cG
zSs$GOhxPu0uxf_4oQDBrKQmf+4l0~Hy61pbbGo*k1efX8d^(SV3UN@*2jx)^8&m+n
z*r37~#s&>ygV_8nhM-P*Z-`0(q|A0vDF7GPuoH@wl)*=lK<4td%wq!WfqL;~54?B=
z*#X&&3mWzTsR9ilfo#KCJVS<ypv5z&90ZLWf!qTcECTC-Oq+s=V^D$Wq5>+QA)|64
zj4u|;!b@Wh$V5G;BUn2dT;}rkfyQTjx@%NC3@?F>Y$}}u76%oj0sJkIptRrl(_=4e
zfCYY^Yr~7|x$F$!<pnM(5ijN~fO8UF6oQLw7nKZ9qb$OwTfzr4B>>u%;?u3+0h$N{
zog@o63(Ke1<3E23=(<ebZe~x=U=HZ;`nRCo!oeT*;3DFX2lU)jP*+a#V6P*1{HF61
zzsCiS<V*b9Sj1Znl$3%BdC)pw&(8ZkmOnt_6~AzmS3cc_zLp<q%wIZ#yC#s30v&*>
zdC247FJ{lqYn}(++50el0$JZHa>1wD$k*}%f3Fm{e*(G}w&<d-<pchy2SAIy9XptO
z8DD!ce)4So`Jcbl6x5Oe9nu8yd;lbEe*qT|pmVT}%>k!v$W&l=j|w>QTThl?>-@vy
zybQmAI{2Vb0Psnfkj_6S5g|&5RFG{R;8V}Q=T&qbe6ji+q==|TboD(9LHk}nSplVd
z02Mee<L-h_JAmJqEm(REQhtGLhIRcXA&LpZ1FzS3bb{8I_*#Cb<MHTq;_&P|{}Qwi
z!SKM#J0OpDet6yK(aoxV9Gqo&_CZGLV~WAMb92C3UR)R$kj{r{d;?k;;?c``5Tv$u
z4y4TN-2w@%<1H$n5)PCZK`jPwN!iOf2c+~kq&p3kIu7Y@!`Pr^4Vc||5u^(|bkfV3
zw~r4rw+jj~(3tu$NK=C8Sc}R;1_lO3(5-Tv&@tRzR=0h8498kjCV^y*wWv&n(x8c9
zMxS2jKu%|i3b>in%c=lT4%z_)(gr$33A}Cs6#O8U`1G=hfE?Y~0&YNg^s;{6%Li70
zt$_(@xI}<l4(fDx^s-(BsqHKQonhAk9!LfiB_L0Na&7^L1F{Fi$pD4@6wqPm;1x!!
z!BZjZ0FQ3g<50E(NCPMoKpHGOdRh6NfqK}`G6z!DfJUKvAps0hrSPIF7c_}eVgt%~
zV9Qz$lteb{0ml+kDL-gK5!fe?^Qk<#S#^(sQ-Br7>D?SJq6#5BUyvg3ENuzv3%vp!
z2FPd>C<!1^>EQ|d+aQr+!^GbLnXmuk(d)-<`2RHrxWC4~jme|=5F_Jp56g?CpFl^+
zb>4)WiS**35Celp_ZsljzfZU6Ay8m+`*QeLek_sj>HPHKXAa0C{4L<~W})glnq3(f
zAq{Jz?SKD+vIr;`APY@E#WW}iK|Rw>9~F%k^KGDo{$c)>t)McqdkJ`o!56g15On5+
zXSa_E!om)yg|9&UC#X_TD1sUSps^uPOn^`7D^XGCtO1=0c*~>nB`DM_K*~S?2I3gJ
zm=21j=3E9w(3bcXkT&qKtmUq)Z%c$gZU!rDJz2u~;z}M5gKz5-kIv8ht+T+{^5ct&
zOQ6*OhhKL6`~SZ?K*gimL%`MWtw(o+M0bTkCu9u>|Mmb4{%sCgphat7(>mvXJ05AB
zQ^0E?I$BgfN&Dq&keP@%L(sUXN4G17N9Rk>Dg#iT(xaPI`!F~K%-9Vn10wQ4Gj_QQ
zjQlNgLEWQfZN?ID(7{!$Pe8l-Z@&cX-G{b!J>X`)z6+Ya1J}MUrfmh+swJmDo(0u~
zI3nnu6*Pj5^0$J{mwG)Dn%5aYW6BIK*MXW9pnxoGKyo$cU;@yxD)3oW2+x3~^d=yk
zcMQ#v-*$n{vbyNeI|q`|IuC*JD>zT~vOWPxf)+r6N(zvePcQ3Dkl1lZ`N9D5e<x(&
zibpT&t(}mf094(BrI04PLCq9U-2fKvgmel$dRaH@<YPGIqEf(g%tfV;@tBKB5hKWc
zP@3}SWt|O?Ee1)HfQV8CkSw(HY=_8}fr}qdRRA^{xj5~F%zS~$36R|&H-Pd3SY2lf
zs2HkIu>d8?1dtMt5g<+kXuViJqP)320m25YBlDgJVT0$sz}+**vM)$u2Bcfzg?c6^
zXO>ukQa#wr)&nJB4K*qS(DDTo;|%;QhM>+^H|yC0;M6q>6n5PlFMj1f$`_C#Sov};
z8&<x6A`Mo)fX+|g-{zuH04iLXL56ky^62$vcQt(SnhTo#pyi7r;}K8+^AUX8^G)!X
zYcCo>cf*1@SK#cdn*{PCXbp(vOHldp>cz|qkT3XKK>Z`o={=xGg^d2s0k5L-09^(H
zQ=9`;3_1Y`)L;dN3}{UjY<&c1-2flRjols`K9(=}TZ%vhPUou^Mo^tiU}vlWm&2fd
z1I3dkXzfXgiUN2E$t{o0kD%~10Lg+v2gK2M@#`IEBds1I=y<)BxuCWVXh{foc@wNS
z0V@U<C#_ka;^eJI=WqVj)u623`SXS5IY@B=Dhfd7huH21$H%JekldaH3j1a~#*!3p
zAywS^mcJD=L11|MWhUs@S5eThuSYjRGPFJ@LxcQ|BSY(&Lo@VY{?>;e`<wL`OV=9S
zhWAGhO%%{cKa)XLmiBre3Xw)=fd?t?T)Gn!Izv<nkV`wTXFKPB$MDlSLsUvSTvW<l
zLJk~pVDRib`Vw@w3#@+xDUaA7&gXBD2R8#D>wIx|A<GQvg=74!pn~ot=nfpX`$1V5
zS~%rF&VPZeUwE1K543&-KKt@A<lq1Qu7+=4@`Hx7VD5q5&))b3Txj>QmTm>DFfCC@
z0Co0z=RlSULKjwh^s;7d1#MkB1S*|C`P-+Lb@et-aaN*Y04gWInXi}C2V@BHvd!Zz
zDj5u*q6>6bE0_VD1M%o()z}IykP<)zQX;6xNdgy0pycS$%PInqO$JG%fQVFZfdncV
zK}$aij=89$fe)nt_gg{b4Jg|{tZ-3@0I8_}iGtDyL^MXl0hEwI?Hc=TNZI1y(aoCN
z17TZubhBQEvNb^3GeD{pUK~yV<<1f_Pz$;OG*K4XP@|FnEnvWQ^0)MZazi(3&K_`r
zUI_|?ZVqt11|?IFB2ZJD^+kR<s8Q?Dcmx#akkSQqJ_)FNNdT2E&p~E&!Wu8!u=s+O
zFDUI7Nb#Zs+Bn!9qmtp%t;z=S0Jyk#SR(4v`RIi$*!BD^z93UUiafw&MTklP_>jU*
zu&@`0kL5%D7EW+M@#qC7SWii<Pj`w6c)Sc0hMt`td^#UFg4X5V1O<!+sBi%L47@mP
z?FUeU@ECLn3wXVkFn<f^lrvb_09Few8#2>CWy2GX&JX;pA3%At^WzKNQydI0AO8a_
zuZH%wx>;p+gM+hcGo*a*N(Z$DK<jrvM^}O_1cGKTkjbF)$w4b)K~tmP^*bop7t~w{
zQAt3~y&z4Xv$jBf1LfY74i}ZQm!Ny9(!lLS&(13^8Ni(nn0tc3<_8(P)cXJb{{%>W
zHd_lWj`&+Z2ikz<b~A8f=D9}D%zT)?wf5it|1T~6|Nno?MI`~6hq=Ic^vTO!P~HWd
z@&lekVB7^-Cd)td0ROfF{62>cPe6=EgYJ(oy!3yf0VoDr50n^t9Cv`8^8&fO{J4Vx
zxX<FC!g$O<mGPK^8sjksb;e^38jQyrG#QRLXfZ%9oB#y{1Il;^(mF0sZ@2Rd>LOf_
zosdPi{4Jp6CWysbKAjI=cqM@{41Wh`l`iO5T?^0VzwG=iaiDRIOTMjd9gl-nEHR`x
zc80My9&=-3;P0ykd7`^U#lWLm*M6%IgW)&BOP-zAUkf1o+kA}Cv-7+Y|2`i3&eQ*|
zwjS{8^=B-7>5+WQ6LfML=>CIVHzto6AYR{o(7u(|ZVkT$`P(;x>cU=Dm(8GcW4Aqe
zMXf;TDVb#kcuE;wo`PKdBN6QK7EpkI_$v}YDeeb5f6HC416jLwfKz0^CP<3hk;22^
z*{q|&SR#yAQU;$M_w062;qd8v2u_j{UMx<4EPy)))&aSA0d(-YXXg><8pxIZP}bk_
z%0g@l+QbLGZONmX^MxD8#%>lBkKTa)9<7%=J4IAVTRgi%AQlA~fER}qfzqc_LybLS
zDu3%1Mg|5Dn<<6Abp;~>gX1wbCPsdFhUR0;9?91{EwA$TPXeVmPpGNj_Ab<D{#Nz>
z|Nn!UU9V?5@o#gnXS6AWgoRB8e`^%X<Wl}tKZwc9jIWnN+e1+GiTo{~Q5Tz1{#GrR
z`aJ$tIf!~T#+RV=aiI1($c>Eo{H>rf3P5b8JpNWt8_e+-8zXqJ8Ay<^h`;qQ1JpyA
z{H@nP`{$3ju`s^W1=puFDh7rJ__v9$H~cavQEm8T$lnSY3vfKf!p7(U9^?f@rXVO=
zLll+X2FWqJegy7-d31{&Z3CaP$KL`v()Y#xIB<e!-2^({_uFe($73vJ44|e0Klpf8
z5AY=TKX(3>ec)p36DZM4jt9pxc<J|jP`9D;;0ygE@KLq=Ee9DG7+MdMYzG~2)4C7r
zdKNRr*K0tYV=Ccq0bLdbDSte=S!K6@Q`@HXpd$!=fF^_6lb{KXzqR}C|Nk#%f<`?-
zu@5ehL1_)LI8@{1qQC$DJ2uy-NHFrZI)jwjf{!(U<~?w>OLOdWV|m#H9#@689W?*{
z{||OdDt~L`|Ns9TkGU~2z62fE;dsoAmGR|K&_UxbK>4EeK&hBVH*3XKup>*?L$btD
zkQAt0*!mdNV9=y;8dCWMZGSX_uAn*X(Rm$uZG&qoIQ&a^Uo^*p!@dPHjsmK*c7cXb
zA*JqtL}+1pjK2l6JkO)s+X8a%zenex7expD{ckzI-vU~4(OfOT2)R$jqnq{Y7O+!K
zL7n;wlp#S*ZHWWrZcxjU7o3fuhd3WbG!apRA@KuoiP>^+`CoDzH2$IiDf>OZH?4rT
zmw=qJSO@CZ!~CtFLjUz_aQy;GMWquw5Dm^2Q2!U=!UyXhff<p&!|*Z^lv+XO={YO-
zbSrrE>O5rtHK;mYzL12ZG|<wlPWF;I55}V&pkueYoi#i<^FjL~z?<4UIzer;Zf^_F
z0HFeCH796~nFeS{Q|H4Mq1zZh3x4=pKY>zkw>5mVws48LN4FiEE5_gY2&^KEqtivj
z2Xy=pxU}(kc^X`4GrYJR&%^L?4OmSuRL#x*5H+v2dcghp60|&=UmkM)C+NDdZchPF
z<4E*HP#h0~$8og7${_kYx*Ht8adbo>+5>X_8~8l?2#;<@2@h>Y0dV5*=sX9G70@a%
zP=@e$F&(nIr=-ZEoA-4S>4!}odU2E=9D5}OpgAfJkIuustq1A^K_ej^-C+Wr2OluM
zSk=Z09+PT55)mB-zrV@w_Ul*3=^b=_V1ldRNziBy1K8iZkzf~r8mpi)br>KADud$;
z;}}eE+<{bp7!jZ|SzhcGfw)Y@rQ2Brw1d#4lgWjDyR$}`OQ#bH|2A)}4lg#3<|7Hw
zhe72ld_1E0jfO|Jp+|Qlhfgmr=)MH-T*r0C9pI#)`5Dyt1I@m5-g>d46?6^6ZT`MF
zpp%AogY0KuU}!Kr>1z1IxAT@KeAxdr*96d}JP*s$B{4qTEa!YJFO<CVwY*XC(zn;+
z59m_f?{7h?JFpGeLlz?TI<bQqq~Ia@1{-n4()Az%{W@8mfu_?uEKmD(9xh$tdGHCd
z592eB&QcCg+Xd2sc8om?>WDuF`4Z7yfR`^0;K242@aVki+j#_%)SgFUNou{U8K9jN
zz10F9y~Qd%y}T<A@`BEmxwx8-;kYxnF$GFh1|Gev=fC~`f6Q5h@tCtJ<1uG7MxV|{
z$DGv}k2z~FdUU=#=B&wZ%vp;8w4&7ll>MLwu2x2XO0*J7pI&EekIoN<m-x4FfNCYi
zQ$CglN<Vc5D|mpK*PmVlfX3UL6<QBKm#RBJJbHKss5SWdokuq-(*|%+=Dr$IQ0T`%
z_Zhyv2x>cmut&F}2B^2f0h&i?W?(!FS(JYQ*57ETlxC;^UBa0TDs#XJx><u^?6e6U
z-HxCe5=z)X%XJT@O+Y_i*Q1+N6r|eH(V#m}hJVU|#$TXYZTPnxsFU>Q<~>`>&(O`;
zcn~CJd1@DEj*8#!Q0KvyBGEhypqTP#eq-?>Jqlb`mMD94b9jI*i2$v77bq10wTnQr
z+@PihbiacJ_=-G4{Dy-I00sVij#9fomteZ^?{k#!=sfMx?Wtg6%kO%j+fk<Zhj2-G
z^AEuiBadF*39I-RUi5|YFnDwx>vop$==|RNLbUk@W0{dh=MV64!*TIQ>jyo0c_TqO
zVlZ`-p95`pi;jlmKQ&KKRDxXFd_*BSF8*av&j0^u6C4lzWP06!aIZ%<8|Yl?7mOaD
zr5bFdU5MJ{Wi_ax4MWPI2_DUr7NAmszXd#U4nIH_w7~?F4MDe~IDk%-w*cMP7U9!d
zqGAHN@hiZmH$}zcwG$}*K$l-OR|+tfa)Y|A79N(48YP+@y`p_9L0x(9V9!V2&KECk
zg@Ti%9jN;f@B-8xYdugR?a}RR;Mw`ovlDdx+Y7fSkebp}J3tE;z=cX2>=ba&77EaL
zmY}qWCS!O2bSDJ=RM5=`36L}lS~?0Yk3jvG7ohzL%|HH^D77B&=oY=YQHa5V-vvT9
zGckg$Gj2Yj0l5#&@WAU&$mJ<oe<g!|Tcor{=ed^KB@(;s85kHkZ+J8x$v{}@7=O6A
zQbw@kQA4GKf5{zi0GHeX6{nD?D_F>a0?+{zycVF~jR0**Hvt8204R7pUW>u{<B-rQ
z`w!ZdRvPBf?PuT%x>)N4=xPRuNKk0;w}1{k1*voJK#zy>9=)P$D?ss(0~&Pu>D&3?
zMNkMxSLw1BJ0o})UV?XcfbIwa`{tN~wEas^+YH`cf$g{Hc9ikx4ixa{JZ%fgYjxos
z-Mj%+NSW_My^BY8k;E?0d8D8#ktWxJ3iSiv_9^&$RnR@yAhBL=Mo_onMN|l=*K-78
ze@vEyN3U%%sPhDxYk2n}sh$_Q4J-M;=Vknp4)RYwq<M;e-=*eXj2@CFn;)_@|6-K9
z)clCesiB7Te>~`3G|dYhj4xgJw;gcNJm8Uh;l;aPP=0h#u>c*Q74WY47gL!SG+Ww1
zQf)KTA>F|Wt(Qt3d-U>NUdG38@DcNiLm<7qKA>UcLobd7^DuNf%e+Rc@94bwVn;Y6
ziz<UEZwt`ohJ!DzWc>gCdS%)KP*79^^Dw-g3u(`R;>iMia<kC`y6Z{<RtmiYo#+ZG
zztGa31-Q#}#-sBp<Q`FI@yXw!2<m=z7YKmvCz%lpis8=h{4MuDt(nf3FP4G)kbDhv
zmUinY(0PToTffzdz6=I!arsu_4?3^i@;-lGJ-EdOn&ffpy!*m1n1{g!bT@A|hhz5!
z$aq=ce~(UqM$ie39H8_54}r=fQ0eLTKfs{%8z?9>N;i6dH1&!~E(6^{@d9+>fJZm$
z_LY!5lG<TB4B!d|RM4X28%TS#^Q9vwkASkd;q4c#K|BneoyR<T%OqYHhJn~eU(5P}
z3X4}hoiCdYGlEXKf59Hc!(e%zzhyqC{m>0M5kC1csHbJ%(H(L@;)OsMXaru*2UN@)
z_vn1}LOcu<KqcGxJ3!0hJi1w>K#uDbowgKG&$)+!`agP%{4Jo>|DK>NAD|6WAUA=-
zKa_#L71Yu3><$GrK{b3jUqYIo8ZXsA9YiEQyf_>Pa`mwn#UL{~kAj?K0h&iIQ3Wv#
zd^<~2AbcL*&Kyv`5<ENwo8o>AV_fp=cH{8r{0N%Gf}{=DcoA#t3UDQzwFGoN!Us_Q
z?RW?@j9*R%-O+p@gooj!7|3DWtOgLpic26qjfJbs1vjZ#7c2)Gc6TvE-WD$J3u%9U
zbChN*1=Z)%*MJUd1XcLmtj#cX+5~8QX?Pn{7BP5q+y1TqjeDM}vxKJq<ij4_F2^K5
zM^Yf2Jum2C`4e<%_^%hA{lRg=4@#3BmT?00XJM5AsMb3Suf3pm@pa37TMgQrbndu|
zN&+~7Ixl)y#u*%UQ335n{SO)$2KDGr#%Pa2=5RqZ+;JC`91zXl0zP!Txk`YMzx6mP
zXr|Ul0@ObE)&#mBl!d=#6D#P9H3tFD-hkg8&A(Xq+YLZl1bSH+m+>*c_YQy#KA#Z?
zZf<~YY_9>WGVJAj01EHULob&4fl?NDrt~;}ixDSir}%&VmN3v3FVL{si!~6v9-VF)
zkfY*22g_G@bO%XzbP7N&oC57`f{f^c*8+m4TcP`4eYzb5Ks^TwaEGPafdjHJl7qix
z8t4e*1Fu2%uN;){=nmq5_=|(Tr3U1S<^znN#^FOy1p{ikLJt}^2a@adv+(KkGw=lM
zwrquO8($2Tg6z0*1x@I>SwK!g=my<c04`#sAXSB;N4KbI2|q)(P~#y`-C=p5p07JZ
zC80A+p*ut+r87(gbcHhizEhT`_*>_&Gl0&l&tU2ZljiT^16u-_0S2wLZjl8^gWFU5
zZLT26)=M7UejXm3VICmcnHWKi=LO}jQg&$80d?vjbNQe)4y?q1wNF7K@HwCh$qIaW
zK}&^tMV~GNO*puycz~o*KuvK65Gw)1vH;C0f`;ut9P}AO&=xfCAoT|yP!i^EX<z~!
z-sGZ^;n@6xg}+@AbR=~1560te5uk+XxChk8;cu%2E#v}i$pN{yy8%?rf^Hp?;BWcB
z3cinvL4d#ID-#35ixWPGbfp3+?|UJO2|&xXz%wJDtKdMFBy_%bq2mj7Lq`)R{Wb3a
zPX#mbx5k3F-H-)u{M#%%L37QJ^NZl)?3Oq9TR`Uzffk8^My<i&&I;BCOEoO~EnC1@
z1eU-Q_*)LMGB7wa{I4nDacKB&x5Ji!fq~!khex-chC@f46ewD>Jh}xz*Sv9gG;1;P
zw?K{z2n5w5prZ&tLh;ND3@<kMfl6!8!o1^d;6pS#Kr3E3K|@^Kj?e_nQlk3emN%&V
z@PnyT3RLY>c=U=s*v8A?(d{AOVHwE5-*OxjLfx$Pi@^n&4JcN-IbN*shfa;4BnG7R
zb1$T90H+3Uy71@~JvJYbBmzJQAqN!q<R^~HUZ98pZO6*sZ+#3J<}w63>18zNScC~6
z8&W{_R)Abk;L$5uJf9DAjtFFa3vxOHXax<Z)<sT@3NI?bCiAy~j#7ZP-!PV19fsQg
zPw^a3?^%GP!08;Ev|;I710)PR14R^S2k34n!vn7uBisu&ZNofBV3C?@c6ovVhQIX`
zc*Dp`SLk>YS{nE4eDNXx;)o6fP?d&A+n>Q137)oJg6<HT;L*$ba4sLit~yQzh8OOh
z*dpJ<5;6@5nP1xp%9}5)g0fmSq?83OuQ~qWlrK2<@wb4+&q3?m;d5@Czd&=7puFO0
z_~gYZUmk{++TbG|To@QUyInaz&4U1gm$N|o*FBqmu=4kNGBSYU6l9kpq&3vdI&}d!
zrB0d)sd|}wL5_V1I*Zq%y8_f_e-ZBu38LxX9rEt5%)sCJ4Ajo+W(|gzPyvd8ZjKiR
ze846!fi8kX^e3D+JUTD_4=?~_&6j=P(Nh$m4A9+_@cZIGfdldxe~Uaw95kQ)c0Smh
zK~Q%_L2Q`=KA{10AIDjU{3fU?etAQyJpR^v@HjFoKnxGOOaSL<*4Ypp0Z<(r5EDV;
z$rE66XD@F;&F}p90(AaqhnsY_o6O7mppfW1_`=ki2Q+z+;n;cLW#2E9`3>+v0xtu9
zg68}{=YxRxKG3**DF-s3^%8%}c~IN8+X)_~Ek>X)?Y#J+$Q@G7@VA0y7(m4&XlB}@
z^OZ-phr$b;NXQWwQ@{ZUDLcS5Qa9v`7mscS36D-U507rQ0FTZ91&?kw$oj}&kj2dm
zj4!=@BA<`s(aqXB4;;R`W<%1!E-!E_+JHU40B&D=1KZgGn#}WPW@mhP5PX^%D8GVN
z&VbwpYSVz-aoi2u@qGFC2PgnQ@uLed{}j~xSrGH@z~y-%^0%P!RS@|-aQU}$!R~XK
z194vzM1BrbzLz(04j;pd7B^5S4qaIaos56s4+=_9ukO%`8n8U;LXcVTpyGIO)f1u(
zyyyXR&PFTf#x_vR_&>k^bX_3mKx#ym+7CWnjWrr%O0TE`)I}ZOZ2poNbcNd*PacMs
z3}ClG!UsBDr4H_-bO%7&K`fwMs0@sULFI)B$m5-dUjB69VVGce@@1zh4+FeBg|=@!
zx+5(-I?sdFbmV&U@(P2zywd|*K!Df4EeEBhUQwYre4wE{&N-l|m7kym&s$tT9<=iS
z9Yp~>utcmx5Y#?_4C@>Q-4|P$jTp5-k^=Py!AAnU_y#fsG{AGL1a#lu<k@@-FN9oq
zK&iu{(@o-q+uQ&DcY>N19-VFqFK&Q>z4buJ5|8cx36Ra5H#|CxU}I5+w_nzR%UW3Y
zK*!@iV|AeM9Z0zZ;(_c3ji-6^iu%q54Jx>(1b}L(0Pu-$pp)V>UYuzL<(4BBu=W)^
zyjcA}g_EVDfk)?Q{uWVC=7J8%L))65d0fy83#h386#`9;fd+_>gg`^Y9^Kv=AR$?B
zx4HEaDDJcvOF}^Hi)JmxlB5@T;MC>q0a67u3p~Hm?Hm9atYr1*JosP013Kt`+&O>&
z6kSMz|8eo);eXJ1G~I~8(OUy*L+LyZ6k(+MS)fVvC8&u94ll@-hL@oA*vNb#aFD~x
zqnC+LKL5T-$?ig#|Dyg=!MW_oOwf86j|9ig500HbUx4QHJ(`)BV39Y$quUegOZJyu
z?mP_O_<9P;zliv%v|uRV^yv09c&PzO2i>ekQRJcdK^)T47x3uiJvx(*;pHDk9?1A<
zH|tbn^+@ZZo8N%q5`4tOi&Q5>+V=xByn1;XXYw(;SPDv%poDsyzeNo!E?N)rQRl%I
zyPQEefge5|E6(4d4^jbISoRx~JUZPZx}9YpeFzPYZqbM7$bAU@ej|`-&`eY_6XR<W
z=zMVV4-x(rc5uVnS;3|A(7|6!%|C=)_+1Y1?+cdj=;dVtIqRJxD6bsy=;i%0gO9=0
z@PH#Yx4d8ji@PcCZ_Ae20UGXgX!vW(@A9JCSq3s(#NT!YlvJ9lJs9{~3_vGrfNsBd
zk><$50KTlkqx1NSnV`(s=`P{X?d$<=Cv>_;c=Ynln861=g!@Gy*pizbo$d;d`0RAo
z@aT31Wjo0I*dE=%24Icg!AW-mkIrzUfh)zmpjHDoSUO*V2Ej#7q#*}PJzKZ8LU*>x
z3qcni22f$^?(l*Q;v^6LecsY9eu4tN(>=hW^Mglc9caMY0M;vVj5`cjY&_Kg$wMcc
zc^JUujz_1v#EU8ia8!GC9w~7Ldl3|2p`ZwBW?=N}bWxE24O=g90gs7!b{;Dc1Bc8D
zCz!sY{H@DC12v!(4g4+KV4eElOHpChYJ$r^E<_m!o)<-SBvO05I~;sok%mX-Px#>3
z4)Eb%(DE!;z{6VfXeK`cf9s{cpiSA%3NMlF+wErEIvX^A019Sz3y)?7rk4}ILmiOu
z6~}JS?6X)lKZ8d%&xIFj?Rgj+yZu-^J6$DSY;fXX0H+(zPFIB&i;#F4FQzzwhJ9QO
zK!Z98KAq_iFMopD_uzAGUYObQz|Lkl{vs2UcRJlAUS0<`kKn60UOoj4-dH<>402JC
zc)1j`ega(nc3$-91+Rk_T|bqN;YEWTs99Lz0-6u81ReVcJ9t3})HBimC#6o-O(3am
z*5k7v<2In-x5J?F0^A;YeHEI2z(H*R8f=I7A3Xh`0lFu<m$zXhFT;!1w&3UokL$XC
z;;!3Iz@yVcz@ytw!lTne!lT<y!K2ed0o1(o==9J4k0^9{fSQ{Y9-ST*9^HNp9-STz
z;KoU(hlfYEUw}uaM}S9nScFGsKm@p<)Ow&q7*s|FaDb;VoCEk<4ukStx3htVH7m<3
z&~bvG^`)S~9D4jBIRAjg02mlOnyWP!N-Q7)D$$T+=h5k`QIh1*9j4*a&E?Y_#NpG)
z;nNww;Q^Y)2JZ`kT<6`)!06HKEP!k<sJ#X;__#BuSpN^Hk~N~^K;d`X8GMr<c>fw`
ze>CWRUv3Xb)$%{UU;<<U@udp1JbfVz%KackTnI&m2VSp(hCgWj*5HL(```cIiu&LS
z@cw#`dJ(KgD}nEHLt5_ujxP(3&dZ>>vAYR2nxIf>=3y;*d6E!Ai7se#fuqzNL<y88
zfGDOCZ}5Ea3(!&#aCe9KwHRc)4kGR*%)kH<_h`KY9*-*t2PL5BxWf<yrSdQZukU(v
z-h#-zywA$O@IuIjhXJg}qw^T31>^-*$_&cm9-W6u*CDdGN4N0n`7b`%gUe>a1E2xs
zSsvZIwUfa$VbWwiP!nGVv_5H>JrC$SJDr#1;A#`;K2Egp@(hpeNCD5z^NyWYJd#hp
z*k=t*ye=vl{4HFd;fCAxJfLmUok#im*g*%ubh}IVbZdaRZIH1u7XB8{w4!HotpFo`
z-+CqnhF<6YzMZcOzrikpKjxxhFJSl|G%Vl%>MBS0cK!u%3|@kckOGA-3x7))XcKI6
zod6SmYc`149Vg-2U8VpU)rHu@!QT=DmSFR2t`lJJ==EUq?Bpwz@n}8Z*~!M=5)A6y
zw%+D%Ne3~SnHfDh?}4+oPiM&o3D0gP0gvV%OwcPMn}0C#w=y#^Kmy*U^P(f@s0oG_
z$E<i5Tw9-bb{+=}D;j{#^JxKXCwl=}Z{rEN;26vWmFP#ot294(biRCX!44d1{H@8L
z8W-dS@cD_|&K%#t!&M9n3=;gUkm}e)C1NM&7*_sm4${pJq&Zwv>|c0Tfr_x>AlF8K
zZFiU8Z@mnfJp1_~$Cih|xATW*r@I1ZBXH--7giwKK=}vk$9N57JLEtP0G(9GT%iDR
zZs%|Q7SQ@I59<;Y2go6Bp53kzpaoMt-69`6k^6IBz;zC2e7El<0|SF^cael+=XX#9
zAO_ty_*+01s2kpXSpu#D92j0mgHF!?g-q)+&>qn4aL|aqhYz^6=>}cj2|CvfQ6F_X
zsDKt-^_>SLln{&moyWi5SG?XGqGHkc)AA6%?;+4xi!aJ-(0%O!E>>^zw=(|!|No@~
z<VZ6Y@J%6}-Chblogpe7;5dU^YWzY3ba+O0hze-0T`OqiwQuLu|DsaeLJXeWz6u__
z0ST^#2VT6h1hvM&J6k~E4LUeT!=szc13Zk>44Wk8Z&?nS6FPt~lgTg7;MwiY0rG5s
z0VIrD=YSRsxTsh(|6r`+>O9`-BJuzGeZ}KDML^5u?LaFVK&fXPxMnC((Etw(XBc#X
z1~3XN_*+3+()qWQsMtGn6iC1Bod7B<I$yrXwSgqDmR)~AM>BkUQDOl~GY34nS?l`2
z*}uCV(%pOw%EI7b%T~x@Jox4wIna7UsClwb^IE@wqPp`3RQR4X55vpdpo$na9s-Jg
zaNt7bRy<m7`+!1~zjY?4L*L6Q(9g%<()kOl<i&P#(2Q6J=t!|+FYBS>A)pk`1RCu`
zO7UUlAlIX$_!3EI(&&Hs_y2#;Mbwsu`F#(Al0)au7pYe03BnlUQ~}WV;7ssFiVzi#
zmjd898rX41FTMW#|L?-TEl0(^yGF&LvqHtO`D}wrM}{=`fDDgrR_8u&&{gz7g029R
z55Y<K1-PXFi&^khs~(_z5EuUb{|~-b8C<5p3OK|6FJ(co?xSL1d63`tAjr)x9l#@8
z4Dj_Y0Up-8*^@vmsnZ^vS3N+ZuM7<QEq}n{#GV`;y{wK4c^Nz`5AwHgurM%mH-f4r
z(5aih7-6H_t)N~%sJ!IhZ@t0*5oO_TJ;?-NGV!<0gQ`{FZv`I!Y|YEi18NI^u5$CR
z=FN}gXW(z?1Qn3oqDis*3@?_Nf|^GBEnC6PaOQwybyWri1`bd%jRPxX748L{e(emp
zLhcbXtXe=h2f9}r+$Msr*6Y0a!rl~|T0J@smpldy1a%&K0ohxNw63l6G^oA?kJ5HR
z7pQ5x-aY}bhS{U@CTLjzxb*;HfLCO_D1kV*qX9Iw2`V-~%avLj|ATH63{f#~<=>{{
z*z2Nl!G@E+?FXnd1YHc>_W?Au(D0{*f676}hCjCaQx0&RaOr&5{P1tXPaFOz2RTkS
z@^ABE<Zs>11Uf(Ij|P7WF9!pINAoY{Iu6j?dY$YH44%DCOuoH5Lav4fUTeYfN5jup
z{uXr>28M>8I{YmHEDQ`jmM8dIL_x>RL6#LY{ERNW>DYXL@%2-Fc?Qtz_sth&KftYj
zk4{$x{ua>S<PPv)MDr0?D8k26Ji0|^#(-uBZ@&0x434YTm!L?omVMU^irF=wNgiw2
zMsPHrhj4npGG`#1_njbRoS>kvmURMi9zkTj_JL%iLH7|_%VzY0IBF11G+5b2kh0F3
zFJ_8>X5kKi9Sc4PbEhCEJ44Qgf3dq3yz~+x3+lzcXfy|PTzQl9z)fxbmL;G;%+6ac
zR)WMqscJG<;1#H`a~E{p?>=yM1k#@NXs!me0ZxHiv)&S*<Y4h)`ya@F9%zxNPj|9{
zN4MyaXi$%%M8yI$OU&T`x)R%wk%8gG6(dL>fzBTVul$Cz9$5HWg+N7aZ-|NmXmxNZ
z)I?s8VCTmdrl4cqK`n_RC5GLgQAigRht^Bo9t!*|`78_!mZ$hz(!o<ato&WzGNYvn
zQfAngfjkRd;{!VN7Ch$$x*h;^iVd1kUYLPYw;tecJqhx6H>e2hX5HEeHgQ=u#Kc#o
zJPa=vf=dt3_)4b~G;J_5zMKjg`oHASdGp0pQ0fGY8@Mv?x9<P@|Nra7F1?Ny92-D)
zuY%5khNQE9NKpsgz3?*V&;S2B`9XKwI)RqCPXGl*#zRQ(-UIcg4ukS8XpKO3fC6aT
z7j%&;cx5|eLR5jjbswm#uohj`4oWc_K^$nPf^sSNR!q=3DNrZ;#k?c`{)1v1WC*A+
z(ELMzzyB#K14Hu*M*fx(Ht<}g2Sce4YE)IRF)%<XOkPO5fX56$`&U7A4`_*qL+hnF
zPtY<EPzhNEN~oaq2KD^?aiHsVdY%4*j==Ei^*PA#TGpqV!55^=AEd1L0EcJekN^Mw
z*Yo!qfew1KJXm_~#j`Fp(1|i0od+vqLCr7=mu?3I(7Z$aOvmp(JZ6B3<vw+g{$9~Z
zouGJPW$%Ej*RVE$CV&@`#t@bT_<XS6fB*k~$qd>~0*Y_YjRh|={(%;QzhH!(ehlt^
z@8kis3(BfM{TWw=9iU?1<vQ?CJ~Tgc-hA<+5qdO)D+6Q?%F7<e5I#74+<fsv04alR
z0-Z|+%3+QTe{A@BK<AM=HvF;U?*pA@?+7XbTi1Y_Y=;;<nqM(G?g7n2f~s!=&_P_F
z^)sLf-hjX5EqDO_7bAb46!;jnDn<+bmUW<Vr1=+Tory=UZF)N&1Nb~ypU!Kam+`kO
zfJkzch<o(fhJqwPw^>6a!TU8q3B|M5i_vih_!wH)dfWZVpg^dM0!>ebs2Fq}1I2*@
z=o|@a7ZnTs7Ep8g#V;dprNZAD0y;74zcPQzq~HJlcm8}~SqUwH4uT7zmTJ%udEE{Q
zuB``3by~lbXuJpq?TP}OQr>#9L>TQX>{}p5ce*lk7ASzjskIPvq*b>s1OGNhDVrMp
z7SLUZHg^0ik-z@`f5D4nk^*S`Zg1Fs@GdLCQbACU64Y{pFH!<I=a_?(-Ag%ego5K6
z6e~3%V4M0tXWxQjqy@B95E2vMb=e-x6&4JRojxiGC2^qg%>Xn`D~w_tf6GZw(bXMb
z-~rly5~5-N>Vh*df|P?2AjqGF9&p$3w?MX-1%M*hvok~mycmIr(W5)S12pHX2GZvN
zv&N^_?Z0p90iRAr*rk-9)^#%zBmcGlX~&Kb6=~41O)$d+O1VG_K|tdXpluJJm0+Nm
ziI&&kJ6=+uiTWmZ4u)YTXwme`W1u-5@OmcCW=J|jq`;Sz$n8(?aNEmiKmY#+=aiQ{
zKmY%4_^H9)n)l=Xf5(O@CQbg<<RAb4zvKp=Ar2`vUZ(y0|KITB%lM!F|2y(;V`_eI
z-^LfR0mG;B;tLI1XzhCl6hr(iHs3);{jme*KK@pH&}}+SQg$!ZzW@IZK41E!7}!=#
z{?=FD|Nnov;Mf2EJB2}I=s(cJNh@fw*O7mpmEpISVW6rFGNcVj!;tU=g}4WQ%ie$g
z|AY6oK}W&CN?xXcTdm+>CWruN=Q~uz%k>~Hfb-}}(2?c*+n8)Z`CIOTD&RiQE*6`x
z{h*!&f6JXe|Nq-0^0$KO$o-&`pkIO}iZRmUOHh;9quay7)$jmlV<L+I4@2_-=s9#C
z>n&bx1a(rny%k;*?EUw@`N#jxV<q*VGS}h-|J(on!7Pu?<Dj$xojPa-9RXV}BMe?>
z&EEprtln9!@OmRisly8<Jy5a8dc6r;%PnaJm7W|gSoC=qUY`5)|G!Nze~Zum|NmRR
zmHHWe1D6CZ1^)d1fAAU8esCBw|M~y_#b1yipqd1HAYM0XC&V;8sA=2uco<$bfHN*Q
z9AD;wHcWlw-*>_A+l$QoAa6)^9_Me}{`>#`*E2!hbns}lVB~KFB`i=CsHzKYHnik|
z3cYS06^9qzx*%t}s93yQ_zUcs&T@s9w?R?WE9&0N$MEt8NNKO=?<PKmmv2C9NVLBM
zt;BHTUw@+0PoeoBBYz8M3KlZd_CW_+f<e|UL0UK=Di-|Pyret)q`SRTI{j2Yi<n^D
z3h>Ba>&X(d<vQJd;QWmyn(PDW|JG@E9Cw4ZnB5=^=GU5_;Uaeqk8U>&(8}iu4u(>5
z@T96wcLE0_D7txmykG|TH~G3p^KnLx=0i-Loi10vdO!=&Jeq4Raxj#bSl6g{)SQ4s
zt2W3ppv8GFkAc!WXkRzdi1dpPT^@#)??BC5<f{ijYoNgq1aghXaR<;|2Zon>LAeNe
zA1TWC6m$(+=Q+pDD=&gT4g@uM4)eDh1GhRvdzwH?DL%e1zxe;ZN3Upe6KERoIA}?!
z>P65c#s5LW>#QEF2TF55`+WFYHiJgA9)eun%UfU1$M8ZG#D*IB5Y(>j74>KW&q>-f
zfjYJ+Dhi&UUHAuINNa%715yWuzoi7Eq45avN*VBhyr2V`LO{XZE6N6Op-1QOP8XGc
z7kwAN4*k&xa`#ct77tKg@kKdExb-cl^6=nqnF%r$l-4JJ7|HK_IzPT(1sP{~l)v8x
zBnCPYp8-_DgRYW)1#%cj3Vh;KbB&4zRLbMUd6*RFygQFx(c55qKfYiG+XuSR3Dl&q
zW_{cYYRa7kHE^w2?}0e2TbLLaTL1I+Ed#0Og&fiY8pDGehko2eC4_;20d$Z>xd7-a
z63De!te@(H7&`yKHktc$)~IBFc4RsDbe4dQ@I#y#Q2|>K^0EfhYEOIh|G#Im9%JWW
z{uTz1&A0hm+(FLihS&@qC2^JDZ|P-XVCW7}Dd=`ku{^}@a{+wa00a0)fR=-xpaHkN
zJAb{%0eKzNpg+dn@&Y8$dGLjS77v5v2gl9>kb>UVMJ2?w^@&essRC%J3aG!`>7o)+
zBJ9%bsp8UkV5Z~upRJepTS5J07iLEV7t3Rg{5~I=Yg7!FA(LC6oR9%pY5q?goU=VU
zkMXyF?{oo;BD4sA+F9Lh$fJNQcbGs+Cw)M@kWVkBYk{?uh=H;pXoZ$qBkZ8GC!h!i
z6-1t$FF=RixM+b^iGY^e>VP)YLfl{mG7LP{1D?_YjXZ*nafF6iw}%4gcH@^!3=E**
zM#tu(jF2J6au>@Sl>q)0UeN6>oiAUogDeA$d4g8;fl^)?sBHmSwsY`>GR$ko`CC9o
z|9e=oE@>2E*bN%Q1nrLk(flo5pjhkx8*}qTg(@hk_<&;kmq+K(7Z23H-UNqE4Csoy
z)+eB$x&+YhYAXY%({b$`JpRD~kWnY_VqVaZ3m%~1PRJ!GcHll!FnCVOzymyT017;V
zm&M>76KMTLZVkAm`Bew0X=Z8gAdP<;9(d^q8kmCh-#xlnZ6WHjpz5<gDF-y6a0Owl
z;enUJ5c6Lw*5F}ynFcWe)cywNMgG?2zyJStetfYP6k46G3ZP{$pajKSpa4lPt)QVJ
zpUzs1m&ZZP8~FO6-Jqc{P&k5USHu4=cY~^!ZdQi|Q1?RC5==3GN(KYa4L#uL9%fL3
z3$|4h#ekO;VBPQ`zgOUKEZD+ms7p?P1>I4S<u*_m4oYr5oxff%fI^`4K#3&C7of#W
z9=)O=)v%Q51@a<DDL7^Rda+8Khv8)zxC;*ok8Wrt?-jMGgJ}^5DPaTodxA$dY!dV3
zL(qD!7uq1XZSejKcyJhWrAluJ+yC!36py`J_78piPZc<Rt7>7!|4`#$cnRv!gXWh&
zr~AIN0rj-N>qlRjgIY77JmLY8;cqDgC2dglY!wHG72G)-pu<f-Z7I+(dl`<M-@qC`
z2f={a=`Wg}LK}_8`CIP({r?|S3N`;?tmAR)brJjj{g&b($Iff6txrnWyIoWYI^9)3
zBf~D8<qEI?h!!r;xtq=GjG!YX%DY2ULVP;wEj&8o4O%aCxJ#FCtYGAC&0+)(X_v4x
z_)9l<^omy0f@+G7FG5d&ZRc;91IqH92VbP9g10g|b{^z!0rl)$y4^v;bD_0-46c?3
z`FlXkK#*&MUAo;>Tslw8bo~AURG5LzIdkds2dRArHT&mDsM%>Cv%CF4-2li*PvA?U
z4!wAw%EJIUCFw`=umAk5T;R5jJ$y^50DtRpaHb64fOG*254?Q#1H8lxbRSW%Di6cU
zO<+CnWLX2cNT~DYi{pymVc?gqKrzuP`k@AtV_DZ$fRaAP3q?>d0*)znu=%i<GCc6I
z4b-scbcZe<`0)}no(35(xbqn78Svpap!<GcH5IH*ay9&R%tfVK;AJ3qw!$4WlgZ!L
z3Fd@Lc(h(B>G9}=EX(rgg&Zp5)4K(7l?LQis3qWY?ZA~DsH@Wpy=JcSIOx1bP*U;j
zyaU?W>i{wbbm|;<W9Q8mt5m?HAb$(!>=e+oh!&vjFb*EQqAkUs#X==23ZN0O%kq$x
zXcu?{404d$HwS4({ua=LuHm=Wsi5(nScqXI=^nkJt}yMMoiBYscYPdu(FZo9#1mGp
zbwdsTgPu*~(jBPa$au-o@=zT=NCjwEnb}dn@=#3)XlBU6@_UJ-r{&j@PoCW&-$7wg
z+T+n(qhbI)(Z;j+D5H<%`;tuW?vVE&N&Z&Q#KP;lkonLT&B~y&oI$0bi;BSuS7orL
zUAlc#4ES61K>eQ}(3pKJNWAmM%e{~VYMaWyS=zq}lmNizPjI|=qy#!D6kINWMIbE?
zmu^V-zq|%1kHPb~5gxsw9%Z1Mat<^G1!?$JDS#TjhhKbB0y*J!i5_??5fpeCFF@TG
zZurU?Vg8n@43PcTEqg#C5&J<}dPT2+oYVR7g#py06(C_yB@5oK1scl$nI?s4+IEO(
zr7<48qBEd|yq1SJCmCkQXK)0EsDKuz)l`96t~XvRljUImITN(Q8I&0IJqNiI<)S9g
z8JwW2A>3X_DuEV0dNiZ#cLr647H~1p`YG@(a2-fh+3ljD^HKydc?KO{0u9UIRSznW
zTa5qz|NpudRKE6#UaACz^v4&HP#;ZHgamK~$mI^8AesIE&DkZO=`j9QPw=3<i;4r>
zLI&t00J8f)$q8xv8{Pe{w-_FH$p)U+2Guv#yrPvt3?=L@Cp`o0_k>QYfLnN=^TJU2
z6U}cxJJmTnKpl$fkaC%WzvU;WM(E|uFXm%-Aqt9WSbqRC!`sW6Qw&;RCi=7j6h$9F
zu_7P?nl;pB^yoaw-*OwI8*~!RCJ>|Bl>=ff6Mst~L;zC4fX;9A00(6isFVebkTQT1
zfUkr{@&$1BK*6Is<l+yHZZD2+ji5a>9Q>_)j0~W8d<9UOj0x2Atx-|%NIw5U4CDfk
zGr{xpFF=hiV+9_DR`4Xd0e@d3$c|nY6%WI2u7=+X|2yslZJq(OA}n6lz4&ntGTsZ?
z-Udo99-v_zk4|R^&<xxoX-Ceh;K|Eg`1Gu!<uMn2pAVfsU)+_0H0=yLI-M0fJ8yu7
z5LSZH0r&t1NRoC@(eUX^`5*x{8dRV#S14GPs3`FF&1Ym_056n!5h@Kz=)9MT_!v4r
zd2}9rQ6mki3XXVmyGppW{s%P=Ej+q;KJd5t{r~^}#kMC97cT?{S%``U|28LSkIrC;
z<_FS_oJU_KL6S5mJ#@4B7J&;Br*cqX!tr7j$jP7vK&dd|%s_bhf}F+-&O@-Bw2mnI
zj}c8zG0^%V(4=s4l>h_3E2u}O@G=fmbs^OJ198D&0Xno6dc=$dI3a)zi0ozu#eo96
zCCAR+q79Wa@W7BP6+*O@VC_}I10WMTJU|{QQ3EwmJUm)&^S7FTg6TS__yDC9(AgAV
zxtE~Kgz)z3bD#hQ<x>yPKDhYDpkOWC1S&MatDs*mht#6e?tn6IiHd<^^FKz=jHyRw
zfdOQ8ytBZfj>oAt#QeWY=XcQDy=&|L5+3l(YG;88NNs0@!prdg|Nn!Hf}}iG!*4H~
zz-HE{7#wqu7Vzk-FaXsl8Xlb$7KZ;{?}GUcJP`moK_$T8<q1$=BEohZDEtv2^70s1
znzgO~9NlfDkmz15!^7}W1Jq^&k1vAj2hdTekDEcWtDwcI=Uh4ugHBgF?xF(TKT~1=
z3J{GKfsa6;!QY|@x~cj%E2wj)!QT!(v8$KW24sA)2;{UP&_1)~->jeka}EA>P@V75
z%W8zI0-nA+IzPRbQ3*N;1#Di4g-5q+NeOsn4795UG-m{w(S>coYCd8S9d{UX$Z_Y#
z7Y|C<7+MZM^quhNmUSr+Vt9QFDtQ<z$=}ik&JsQ<8Xn!U${+<xp$e3cY(4b41G;_+
zD%lFw4KaG@%M5U73Lc+^%BMo*LsT?M7rx$rSib=qm-Gf}aR6QS><%u~Wv3MjF@VqH
z0-Fl*_ks$zzxi808>wIZ2S=G~Hc06&P#jGFujc{}VPB|l23g+At6IXx@M4Y_s8RuK
zk1p{6M-QmrT@R{PK&Ov_x6(saW*+u{r;yh#LF@HcbMwFnVi%~~?&f%LOA1t4A2EQO
zzhQXb^@%j3^<cpsjc-8v0epIS8yi8FEJM35ofmyN4}n$@mVtIgf`bM!-cbhbjDb$C
zW6c#}@Byt9@#$qPDFz>+R}Pj0Z+<EV<x|iBn!jv7)3=~ax8TX{Uidb+kD{QKUP*34
zjY=5<Xpb7Ws|7k+z0~u?k^7*;SQ5}sqf*XL5(#RiL8MvLK*gJ-qX9qoL?@4C$Zg>a
zr5>QexEqgvJQIyrpZJ3NCdi=D?a=rK?{|Wz0p}06ewYm<J6>p92jzaqy{w>BcHq(c
z#h`T72|o!F)JZ5Q0=081UObS5R0<UyouC!Hnv9@^CuHZNNB0!)5r&|iM7M{>i>Z<z
zKf~<eZ}9-79gz90$siVF2-WZaxcq>)4<ZC#{|C|vij5c9U`t_+boO}p7o478=`#?T
zK3_y%L-I_wq(^Tsbi$@Y8sT^7J*Xwp9-W7wMJD8$&kX3A*^JkhJUS1)oC#g^gvbxj
z@&$7}p{0klXmgejLx}+>e{+<2fhd8}d=SON-wN&+So1~}2r-m+gI3>wbN<V-cmMz2
z1)2nW@%a_#B)>x*oy_nhg{6>XgU}^~O5b4$Uf)Hy#{;y~g8?$<^7?$*gcqBIQI{9K
z2DP|5nLV08Cx{*@U4**4a5BX5YoHVW>hdwaZhX-w4r;j`0xvk^Z-pGDz{`;h&SY=1
z5Q`2C#i5H1LATVv%5${#SB6LDX~)j19U&?@FAiP--STpTf187pO-+fYW5eHK{uWTD
z-Lc_sO$n=OM~;e=CuDe~1$;3aXx}>nC>i#GE_v&%QSo?TD-LQl9OvKXqM`#mg2VJ@
zEiZT>BsBdXpP#`d4oZIfEud9Tpyo*csG;HE)9oPO30e}^at>sAH*6axN6A6Z#1>@Y
zo26unBdA%l&ZFBy!pE|ZqjX7kh>8xl0C)l3Jl=W$)S)xrZvmZ&?U{T6ECnhBEMBAu
zffh!A&glj%S@G;V2%2LJaP0N?=g}D;0a`zEkTDJHUeE53Lkgh!#j`Wypn?bJur$kq
zr7ywm^zA(1)A`e<(?`YNg^3u*L?0CcPjK!L{r~^JXSXAVPv=R{4tP-W7-F7>Wq<~M
ztH%HT|6hIt)t{hwJ_D4+3BI6it!H<MiU#Ne`XG;PK9F>YI%wsuBmcgupoW4OsNC*k
z^XYtmu?7yB;lKvGK0U$4j(_TbUKa)%#|{@2DeypyPv?WzCqSzaOQgUJq7oLv1FyFu
zRrH1jUatU+mO$3gy}pH7J~zKH@abh`nep$xN9SqK&QE<%<=rdFl?N_z^^0FD5CDx&
z7#?W7RKm-@FGNKj)CU0#$a#QQ|MJTtjsHROD`<OC>+KSu7oaO-KxJI#4QS@_Xs*;?
zD3S1JKB)1cpBuDl_b_BVGpJ%to4~&<P^#fqF@K9NBLhRjuNwZAU!b#?e%XSzL-4yE
z>Tpp}=ysGj=Axp=(0ZU$-WAjy109p#(aT$u%g6AdO8}Ie4!`aJ$9MA&fx7zUAL1od
z;2jJ6eW3oGN4Kbm8S<V5{(jJSjz_nn0Ob6T?g9zWEQh}}FJ#%mVg45I{CelX7r`Jg
z*cl>X5W8N=BHG8jydQG-7+$bIWtji}{|}ld7i#!r%MU(*4eTk<eg*JRKA>}aK=rSJ
zM=$R_kjBgWVCTO)1uhCfGXM$<FS+67A9GPruzUF%R2D=0_d>Aw2P=Pj2B?|aE2^3c
zItzfM$%FCG|3@$83quEMK*Q#sB-R_E0<vf)$f7KM9tP0ylLw&FBpNRksDNfqco*h?
z`kyW;8ZYcYZs`TJeL4@l@B(qVV^lO=>i_%yzdI1LdIfyIp+_%o9LPXHkb=&`;8lX%
zj-WnOD<~3SzS9Az`N{|J-5bydAH)bTu*-RwLDJ`-(q}=#61}{yv-uca?1GAcE?aqV
zRtVvv6<|dWAHC1!V*no<0}fQjh97AqwRQTA4L>qVavU3elzQ}v+GX=Glxn(kJAy)>
zE1QqO5p=3q3e<Ga?q|n_AIToQqAJ;Z3?<h+x>-|F!DX;vHl*eIQILn>r7_6TZdOl-
zR2@`m8c0e4B-JZ=JByFu^$d?*(Q6<^zeg{x3&<P4c_BXk1iFT+*MYh904!i6v-ucY
z_&pCe9{j=d;tEvRY0!{dFYm`JK86<upkkn9TA*aP0?G#s3!;_(6`+%)Ah+vuPEi3J
zdS1c>Is%Ko<1uKGrn?1li9~mSg->^efk$_pfCp$6>K$lZT6Y+DxT)n0I|BpgKBu=H
zy)h~gpp$_zKqmtwybgklPnae^htoVeZ-S3PIryTE2U70O16h*nq7va_`Jfbhe|LsQ
z^HD~RWCsOL(23#i`CDd#lyrx@1KCx=>(lx2#Ya$9X+2Q71T-9e09-?WoCoT_)PeSc
zm4U)w3lFHh`X5x>NAUOQg6@FrP5%!%wc6*M#EUX;h};C9L&(F!;A!~=v_^*49i+1g
zq_Yz&*A8NW+++E-^q5C4@A53r=Bu}cZ^8b15de~gsEh?MdtFpQKo(knR@H-#Np^S%
zx*Q#4a8W%T8XBOZXh4U6fNIbex!jNd0iWj&y7I-tn)PhD5JL%%M=NA{%!S|e1*j#T
zVR*@L2e?IY5H!CIvHl)6!V^uId<-wPa)VM2*b|39Oo%7=TR;brdVoR`G$*<OlmS7j
zp`t;DVBYrV-UEs4&Ku43G9o1^9?eH85Ie0L<3Zy$FO2zl7+zmO^ryN_B~3wRQ<e*q
zocHMEbpY9J4zd!oY6zNqIzNF<27J)~3M6nl=Qw|hFlail^*?{h0}!K^*9N5V9~a2k
z$KVkQ)#wh_c$B}z5|aO$GeE;YB`O&&PJ%Q+W@|G_l)&p-KfX8v671#un8C;JVg-l|
znl(Q3Vk?;W3zREXftbC#wjdR4AT~tBWH1wS*87VN5VMz838W$g#D=IS1TjHZ@j#a!
z@XpWRV=#RC!Vx46i4Q+69tM}r92F1HLB9^KixBNWa9Z%_6;+6ZCIjEj7oe_G4ksi5
zfS0R>sDya*@-oHpF}(P~2?`N#ME>MNMDpBpK86<;5OQ}xOlTzcg4Qy_Bl$2Wska^|
zZF?yND$%>)tFd>0>VygKpa$h#4{$z*WTcmyKyzvnUO0pFqm%<s`AJ}TxPBz9a51o%
z$qouWmJj$_lOQEjVmc@fJ$WGvaxr9pEP}rew8sRLYeK*|%cJuyT0ZjVbqD8VkC(Eb
z=(lFwkOG<_2j7R@%Uhnt$ME712PmXog7Wlv5VPAyCE-Oc$QID1!b2~1fdqSbeL-rc
zf!Gk?#T+~gpi(6np>hI9wwG58q%sG@hN!FrF}r<K;5iU_mLPu%WI&1I1!$!b_{Nb#
zFML3XdwK7t@-e*70I?xvn1Yy~wByn3paELS@nSPb1R^N`V)pWG0_pj}4)+Zs$c2_E
zDjwi6suv`C4I%rO9W)VrgwfOT4}XgaBLjn9cg`~jaJ%%?i({aS2x{=ifwy1ysKDnq
z7DPeQA4)Owj17_s#UODdp9-qkU%yC4SXTmKf(s~6!BGsJIC}X)4dil&CxSr=dU>Cv
z@G-p52eBc-HtakMFG0rvzu@`?>L-EYNgX7}1!}9n=U)-spO^Q*>jraFJiu3*Tw`Eh
z=!RV0*m?kTOADlIX{eB9;O_wSKoO~qcV!A6LwA6}i|uTnKm=!=Js@Uxj7r2yQP2cr
zFRvfSfqfuRNS2)qVuBTX0hO!0yt_aOazUaH1yvwsFYhLha2SXU5l&{~VR#AZEQ6LQ
z_ww?9r0o&XE^IsuuiHGjS>0p7jRTz&NaNrNCup+Z<xGfOIVs>0<UcFiy*zB7{zQ(7
z!|ObcZqY-DLJZ)N!xyyr05UTL8tqB|H5(%M7+&bILLx2}WF9!>Pe!=m04t*4NJ-{n
zcrhJe&k_(5R&am{A9%sh1<DYu2TB`WKKu!~nD#yBN*BdHU?#Yxe>vgD|NqeTd*?Zi
zUfvH$pdvX&MdO7T$W-v~N;ey%wlcf~>bLNLmJdV1O&g@7mv>(hAHxfF5E~*a0%CTv
zfwRU85E~-=mjygNJsqU_CWs9Yeg<NK4)=z37Sbj_4lv}}1*#!m@`JkM;Qj+AsQ&;y
zFB^3J<qM(aA53K;pi>x2_+Fk|51t%_%)h+cz2^Uar17Xw$bkSFkOLIXdURg%XuVw;
z{1SAEGH8GNN(P1ohLT!Po4C7L;KkXg|NeI#dvOnx@Imtdhf6DZS?pTB@p~TYJaq7t
ze9I;NR*+W9AN;+bn@T;pV=X*pcyyN>mH?%E$aW9Vkc33ZQjcz51JJM?DF1`DO|^i}
zOzMu1KnzZ5fU4)i9^I^*(csiI4HN_2952k+c^F_L=@2z9K$i%B@_Og77bloOopjJ%
zrAbj>ZT}M?iP9eAY|zRvq%)ph@AT+qO@gQsNrE5QCIV6l?xaD?2f5y(^CM)kMW9sm
zMKatHU5Mu0iLmtnH$Yh?9yCBcjR}<C4}vBfjN$74MuHvH4RzEiP(rr+%-^C78j%8x
z<+mz=Sdd{x!`q<#HRyB#NdFp^9#4Dp^6mne&|Gc7P!joK2@|OI0@}j@N|rCaf)XOA
zU<5@5XrMv^yj}F;iz!Sz3=P%N3>9S_y}TL;d<-wLz;65qs#nTEOr+$-FVFD88zk0w
z6O<z~Tn!I^6CSAY(s-fx5meBDOCLLsqF&w`@q7#~q(E#)@>K^hQO)z{<>g8Q)%%Q~
zkOAAu$i&0&G7ma_W_aLbJ!sz;=qy_hhMzA7KED_;_UO@h&a?BXPv>FZ&NCjZ|LYZB
zgATKUq;HQ-J?M~>592!@#>XDb?-@&^K!Xh3+Mp$*_d$aVr8l9Y2(K?dwgbn<f{yP8
zwg2GzrxZZb4+S2br#(Bb_;eok={)Pv`mLVtwT%bkd$76h7)!u&DBawUMKUFjjnAzo
zOYVa0xDK)dq8N0#PxCv*Qjl$+Q}bdSV_@fTp!8Ru>kqqIRKQ2ubi$_kLsSZUptr_@
zMq?^GK|^JbgOxzF0=RnagbpNkx2S;bX#gKl)E%MW(OqER(_P`<)18pu(VdY2S~Kh6
z(OqEyS|=9(I;A+mqdOwPqq`sgB$eRNUEu+`d%F2R1Bjo&-v^qW@a;V9aqtnlZ|7gn
zgOAxgpm%`zc3$&=jnH<U_w76m>JLHJ<M?*|02SyJ9-W_jIv@Igj#328`Y3>EGSB8?
z4d5gM9uoV10YoKuc76meCIFpw338SOTscT7xbNfvQJMihE;&X8p~AECrf261(3n*L
zTyezz3qH(yAQveyLvEk*Z2SkZp1&V7TLkJ2fC?Pn&i5X@(?My@<KQcH@Y%D67(Kq<
z@HqH@-J{oqy#cgx5Tp<k(%>O+{`H4E_}4=Z!DECh81!I-9WS&8x^@HPZIBj_jo^^*
zfv%DRtx_}qIa31^zzQJG2S7ZAB@8-26R@B$e~>b`|GPs}3OqY+g2tvnYbii}?}Xf8
z3c8OOl6GLp0Cdhc=9*ED{|_ML3CLUvpY8wy(1Lgim+k-!m(CCs1CRd+3gGb+l=RvB
z#sYNr6v$4H*FXzPJUY*Nc3ubHf_)CWSu;byr#nHzqdUW(P7RbEK&$#bdUWQ1&bxgG
zsVjXL|2zJ_>cjZWqxm&s>0L<O2FZfp^{mL_afIzZ=h=D9xAV9!D1+Yi=}u7a=+4ma
z=&mrR=YQ=w!H4miFXMZVMI{#CYe{QBD{Nmv9OBXW$?^Xc&u)HD$#4~%YtMsnEkqMI
z*S=;fJ%Qmsr1}#ae&Cxf4}wNxHGH}~G+@E00S`q){|H>)f_6-UMr1t@H%WVRUi0aW
z(C`JFpID*b*_-{pUIu)gGynSI9y2|^|Muu)^kqEZ!T8a$`4wY{hG#c}2k4-6kJbZ~
zw>|jR9|uWlzJMu(sw=$#u0WC8JJ9x{#b*R4J%PqJe7e_whi5!NS3*ot0j=rx>^$ew
zdCaG?M+LOv*`xKgN4JxOPj`}nM|YNnM|TxC6M57bx*DDY-%<olWd@+4M#Go!A2f4?
zsCYR3zv98X1!4#&!JUV!20==2Na2I&zAcbJgYG?G_kqej&_YYlL=(u79-U`>Iu9cp
z`OTx-$-t+(O2MbQ$ib&OOT(u-$pe(z9YC%JF+A#`L5aoz?Ccw$?i6T~8OYfNAUA7(
z)F?RqzYdW%ykvONr!z$bDhIk^64dl_{C~}Zc@D%+%xl1Rk$He>n57tg1LtBy`or`e
z<Q`S@a6gXl5-8k3UQzJrPSWt`&NA@mE&|`_=TT=g!L##+Pv=Ld3qfQ0pqvg`!VdD3
zFXKPQ|5rVj_dpzqJ@7%TOoaPDK?5p}KpDxxqdUL>TrPoXJp)jV(eUA44=Jm_nJaAq
zntw7t=?Hv?aAyzrs!b12Ljls2^6fn1*&VCk*?d&Pqj3*7iGd1d{yxxsGd`fXj^m(n
zRSrI22So<>2KWF_eE_NmIzcOyyIa7TJUfpe-0N!iA6)F^s6^B`gZJmVDu549|LDu?
z%HYZD%i-C4oYA-QA$Z)zMa96g+f@LiYSVE1A1VQIl#k`_(gWbSk+}wR;dqIP2eihj
zp9v~%!O5)~;&9NoON57RBLf42$H5oupvE0&>gM|`P&Mt*8zSBSN~jPWAu0hL{Od1x
z@UI7Xf^iBYJu|j|!^iNON9*mnP*80MD$aenA<5kbYR?4EZdV0g(7{AMVg3QFutD<=
zs7g}+rCYdPJS;z#9>JKq;g?6hZ>j=h@duDEy631s;tjO*t9uIg@><W%bH3oFmrwT+
z$o;vk|3MK9iZG9EC$N<X9^FphJd**+c_2pwz;apye;;TUn&CIk=0A+3qA$VA$(xTc
zf|_rZ|M*)#<xYb&L&<AUqKokD`~k^qIiQ<WOTg8Hhvs*XiQv`;w37Dl;9q~tlku2G
z=L-nyIC#Vu)Xr|OW`L~sHT?Ek06PB-76Yx%0|gt{;_szk`!akw*FgN#xd-ZV=#9Ui
zoC9)E0(gBTD0`s~RDusfgSK};bqT1wqyTDhb>^sOcy_)7`2(xFJ^0su^<+He$@m>)
z0m2Drw~c}#1bjmiXnli=N(R{IkDy$k0k+Ds6EZ;v%8?1MFmn8V31let@aZoH4bEX1
zZ}sT><<b1;j|bx|(7Cp4pi{41x|u<fSgna5EuA-BvvqT{o-F0`Xg<K=VR@+hBk0^3
z&3m9pG|TV&{nns0o*)8bc?Q^xAm@P!O3=tNXh0qmpgy3nP4I*$=v?XxFQ0=KkUL;W
zk1Z;Y<h2KU|1z{(1g*L8>^$S!c@$J(ffH&sEc!sl6oZzKLDFLcEIlUh_ks3Y`F8&E
z?K}@3Pd2>d(fpUORN|#N_>yr3(B;G)jITW`fANDC>VnfF$g!H&J^0t3@?<;%YPEn_
zXTb>#bmN)fx7R#~^i{&+0lJV1WXQjo_dcB;JT$+9MqT;WAM*i~J0+l|*H7?iE-oq_
zKAk^6=@yhc0zg3qJzo|)W(Vpzg2cdW=M)tWA7;?Rck6%tepgVB6f^o97<@W^_;!Bx
z>HO*0c?{%WP)Xy-c*c|QD#)M&Ur?+5g%9Y!j)$OyEufGCMGL4=4N7GoMHwIt_;ze?
zT1K<Q<NpItd%yYN9}mWxpreP|Zi0^4fToeN;52gYH6LvLzniV~04S{-WAU*32udrT
zJTz~4SYEFa^XU8xzBmx#V$aTFFQY)GICOsWz#i0f*Ba~?N;p8;dO)^-2L%zy>L+-p
z3f#)?{0s_Ba3KMn7103sD&qeI@XecO^)E;YbU{m<5TyNmjFHiU@git}Ug?+5hvDb7
zdvuq8uH*#Ykk$IFUh=gKG`^voTMx$Hp!&W<)dST1JX!Jr+<1KiYP^D)t&l|-P(`J;
zVW$)F%QHZ3)j-r=kl`N%(Bi!WA5d!xbcSZV&}%)IeT@IWjb}Mf7rOOi$$PLxFF_W0
zF#ZGC1*+8_!EBg-avq@qD6@d-SWqbs>N|OMp4$mp_y_J&9|bkpyCK)Nzi|1&4Vqf!
zZ|MeA2AvTW9=*JvOy|)n3OcUNgMa-!pUwgWpUwmgk4_E`&`DvSC4!w54jz`TK{o+I
z`(3@JQlLSxPIFKL4ct-bWCBkoL0t&$=sP0rYx3Y<|J}#(UFkkhXA0cS>$R-_n_&5R
z4`}@3_ZMyk!vn7mK*IyHeoO&;%R}dB(4l1TqbnUyc;GY2pmLoz!FIpQ{LIY&UVo+l
zxta)dSp;b426W`;OQ+A=Nb3h+_Gy6hv>qryGgI_4Hv`Ig191BuJXTVv02(1X>(N{2
z;nDiPP63kMK&K5MjDcL(py6S8zw{ZXCE9!hJlgeg-zRPch<Y6MgN{-}7z6WR`zMfV
zTo?$uzuP$iCA>0_creo}KcR+~1}N#3$bk<aZPsK&94HUd!10Nj0hBQR2N=A*i4tF(
zr#-qo9bP>D$jtx`=UX4S8PcHf0XlROEj~fVKca{B@{bt)Lmn@Rfn1vkO7NbYr@(3a
z7<k<1HfS`aP7&171&@bZ^z8icB1?*w0W^@q_|BK{5h#z9J_e_gI8es~exDe0ystYj
zz@ytS0^B}*#10vo@L?)=!3**ccp#R)<svBObhCk0aDivRoI(3(1w1;P1w6XlBtYw}
zJ-Xc#KntnCyJ0(>H9WfAKntr4Ji6U1JUX2%Ji6T+JUX2nz=tA(*4BX!Np^;u1qf~i
z2S<4H1{ZiRUhn{oJ9=~mCwO!^XMnbbf=oF0A9g^XMM;%MbF~9_XDG-_gp5N;jR)ws
zPLIwTpnZsL9-vJ;Fl`>7V+LU>W56Y+;epp5Ji3EH#|V`0gNj)V&}rF1kYcnu*a5VI
z216V)`UqOD@%=q0LAa=Byj}yVAE0KHo&lv07Y6u!bUQ(tI9}`nX=puAV&%~-4B8sq
z9SkXIK&P5^1_*d`2TOn!P<eC*D?kp94%YDK4A1}{5ZW1F09r={jzh$HNND^)%e@z|
z5DP#j6_tXrVka|XV429c0v)92(dmpCVbH+TKn_fe5;4R|BAEXT54?U0$^xLO{>Alo
zu<*GFlSdkFweaZ9Q~;&8UYE5D9=$S013(F^^X7{gAZ?(%u1EO6H(Ppw&M*E1n&q7)
z4q71e*0(oDMWfEz6SQQ`qxqNz%Kh7Hpsdb^<WTk!E%4<c&Bru6nvZLESl%tY30e7N
z0UEskkIcf`PaeG@vq71~v$y0bLxuVTkM6J^SkplBYetXecN!kezyFus0=I)eDdOo{
zsE?7ybPgLHcs&uVyx0j^s{LXeNO|i4(8713(gUafKa5fygBFrHAeD!R^Z*LY7rqb+
zz^8Xk1O+d(^Dn5a0m?Xt45$G*CN|6ilr&l|l?Z{dQxNo6PmdB2kT7^@C@2ZLFo3GQ
z_a5EB8d$>^me2a%KtuKQVMu$zz@s~|0CXPr!N)8fjfX*1KWL3yJV+g=v^rLj4o)<`
zK#3+%6m$-YJBCZ$G)hW6y4}GQ1wT@Haf>La^ym)H0G*eM<^#73kcU2i*Wty1*K-&i
zc>NJ{$|zR%gN`_Dy#xv#(CMw67ym=c6-Zw}<Hh#ZFn_Iu<qxP?ILePYkcQR+B~GN4
zAKnHYpfg!P2MmLbSOL-Cv;?i6I#2J60BsbLgPLDWrum?Pv@^iM15|K!1~_<h2YYxl
zS2!?ubOv~MbO#53I#rzk0VP79TNqz#cm-~gfog;jUP!`Fh(2t1`}Jp!&YOm}U(9&L
z&F~uS{zXLk2A$0GA{S=F;gWJv%eycG@We{6fk$_kg-2(w1t_AB)3G<WFz>tpid&R)
zY*8WsaV}^LrQw0sUlHwHf@%5iOIV!m2i4c;?OE830$ae#%ssl-KxP;~(?r*Nz@yNh
zA!tv{Hy*9u>a@}(fcm%K*@+ibLZIdTJlckrd^;cbfF_YXzX$_~fyV7XbsltP2z*r@
zyu3ph-@-jVlz}`yQ~+vLbfV7>f%XBwCx;3YJi041Jh~%5lS3Zh$)U~?6$j7)8PFi4
z2V{1ryCMKQIRrjUp}W8V)cH^F=q|{B&JgkUd4u*Ccisk#Iw4ICf$}?aatO5aA2fT^
zc@{Kt1Rl+S-tHj}Y9}#(D)I!-{73<)rw;8Wx~QPc6M=hH;0sT{Ju8p@7eI3<Ad^9-
zj(vO~AP6czTvQ@FJAe9uHl%`9H-Wr?m>~kS9Kgmn{J-GQ`4TitU;y$XLIrpZ=>upE
zDFfuD0Lb(a$c-M%kVu9O#_{)ifI7q7J>ZER@bu9{oYO~)DAPw^)A*s&N1#CRz?eP)
zUnTR)r}H6bBo5Rc0f!C9zu-}4*i=vj=!6UK_!lfld?D9Se)QpAfB3~eeq12}*9Q-c
z?hus>Q0E8KSprWgxu^ty$J6&fCK91DOFo@jAhVLVCX*oJQQ%1s@FeleN`79335fm(
zQtKGhsOY>39?`E*s1pOnBB)914stf*J5c>z`U*BPi&~$8;s(6PN5k-v5C3`xg_lD7
zyh!ycT7ChAAZY9qv_u}fFM0}i%ng)VK*JB9L2k%sPlSR;cY%gS^MMMV?u;Kk-3cc=
zx+^Y#k_adZ+yJF~&?M;tkVt_?cf<?O?rU&-b{BjA2_|@SN9+LY@BsB%89?g6V*wSg
z3sd;}lo%NpCK!G*yzSfi7PRNTqTco8T5z2YI=Z6yFe7LbT>~6JzMT(!7{7To9~S`a
zcrgG)57@cAEP~)Q4!=Ob5b*zkr{&#}T#wElp55ZU-Q^tMfgQ#d9?if0m#zd4&iS@p
zD$xcfYVdW@paI~{8Wo5oo}E7pPl8t27#LoH4c>Wz20=YK5Bl=2KL%=)L0$1;EiW&F
zr{&$!$smghKrJ`}MBjc3xC{ijxidvY1C&-lj)e?D#(-unN>mg;Gn~+oHD>6*86$MO
zvw018u$Pg)^*(5vrSS+T(qJt=@Pr`l`I!t*<bnp3JUh>TM!Z2YMZTb6j2_5rO*g2Z
z%Wwe2D<nQkK*tspYyibifJb-14^WJOhRMMjsUkqa4*Y!}2SD3{u7>{&zkyDD0c~xL
zQHiLxd>sc0&j8<E7B<kdrUs}iQ2-4&f_FB9Cr>+n{l5U7bv(xC(R^6I!?Hxhp+p@t
zjMdHT)1A%X$-n-*5933R<{$q{H-UrPmw)}y7alyk46l#-FmD07-G_MzblPMMc-n!H
zzcn9J@StCB3aX_L^&3ik<<LC`e9@Rk_ZILJkz=ppr_S?`8<9bWQ@77!03DzG3B+!j
z#K6D++H4L!2%wkO*#UGO5$M35!pGodfM@4X(6)LD{ua<OYL8w~9S6|rxq~knA96E*
zFD~=!JO)((*|07u@4&|ZnQ8Uu{OHmNGOXk=H-m5MH?X=AVb5+p=&pFrPBF-Rk)V?k
zK~8{%e`gG6^zwm6=c~@2FUrMO89X}KKyeP5tnfGv8cJmFXtrZ05r+-(I3Q9EsN?|M
z|853eZ*$2WvIywcBk+LE70CF8N3Uq5J<OGcCn1hJ|A?Cb>_YIe6vG3rm&5C0&+ae|
zkRltO&X1t8l>P@9fK=LmPOyCG0Nxb?yH5!uZt?OfXcr7p{Dh;#Pz9)%2jvz}ZUUua
z&>~R_$O0Ger1lxmb+itiy?Gv<&Bp>jMJA}{R&Ve+8RC9$dFuhHH$T2mxC=V{vO*h_
zM=g9ApL=w&`9Mn35>wA^aZk{(%P&D0-r~jAe;}om2R%R;1{8`7DC$AgrA6s!^m&KF
zX!C82Z@`sU_ZIL_IcSmwRQQ3{%s?7L=RI1#`F7{1Sn&6ORC<E8h=bM*`*?u2RCT(j
zIK1`+75_IuHxher@`7&RvH;x=2|A(%bfl-N;YmkO#sXc?=Ht<M3pM}?s>B&T`!N0o
z1;>kH_W%FG#zVzHtH>Qd_mT-fJUJiXNszw+UiW!49sxNAky5~Gzd@xr>U==s8&IVS
znsEZJsp#IK0;xwJOCG?pz8s)U``t@aBtXk{dvjC@JiA>TJX*hjY>EIyCb$;x@a%OB
z00{-uhrI+Xs6nJB&=LRO2=K8iQOPKg0!63?$O{3Wn^AplgW`$519U<<C|WZ>v%VlZ
zJv!Na7{Pw#Z@B@gM0S8e3v|vXxP1xj;%B@N;Q;l>50rR=<{Y6XwL$kGduZMO6<`Xk
z-5|Fea@+|zS_#xm>o5jw;pFcG-QS5Cb{XIU{(ZVjR3ab^EzntE3)y)YoR6`nF~F^W
z8U@?%47SCm^AX4*kOmE?`3#`q44wc%!ISY)96TmpqLT5F7qo76f=A;KP#mB{70UXM
z5NHb{z@zgVco4@Cv|j6|Pv?1%b38zk<u9J!1(#spUN)%N=+Vns0^07_&3l%Kp8>ST
z%L7tOd4LWFVD{)`eF{2xuoFBg<KWTV0CJ>DXR-!(@T{4Q5oELlDAqv96hwmrKqCg=
zFi-%AylCqG_aEGWaW*LN^yp=s1lo_@>B`{IDGw{FV5cv?n060TCV4=Q?e#bgI<%6(
z1L=5X#QNdRn=cgZf>giW2P*j;!;#99#y6mv%Mo;Z3#iBkr4vU`y$D(>=hJz<q{y+k
zLPn6k1ynqHf);3lRtSRb8vrHP<B$bpAh#cfY^DXJs1mm0Y@jd%Em#HZ83tvN7v{O3
zRN3jG5>XoH(aoD<2rgjfT7e2!&KEQ9a)S<$h<L3CTL06_+W8!`?~)NzYJ-ahNU048
z11yz&_Y`n*0@UUKTh?XF#sK4Zb{>79bO+QybJhSwTY(Fxq09ivXBD2w0Sch{8$21T
z0A3FYKL27B_$>X`Qy}FfXwM<cOTDcBo`IGyvSV}FOHk@hn}DR=r#suiw>wq9xtC>0
zFAroiEcxV%uG`SW<)V_o-(n0p2?IQt)+<^7I;o{oz@t}m*&9&#bO1D1_yByioQp~V
zf1fbu@b6w1mH(ifPX)fcr4pd!TcGx+tKkz5==88>ugg&dkIw6$d&t3kpa|G4lb)T&
zUxGpi)ZhZq;CL@dLUJ*vp_1U4e8ljiM=whQByf6l4uPgd!1Hart_nWAz7n9Er|@Fa
z-~azX0oE!5D$0^wR0<rMk1%>1cLg7s2s*jcBiUKOqtjKuv-uc@k9CPk1b@q3P|*Xr
zGQL~vg(WCrdPUb-fL7k;facGC`hu#QgD>*0b2EUJ(+7bvJZOgjDCxY2yah=oFTa83
zVj=wpcvN)Os93my*1qJZ7{GHEXr)_sh)M;hd;~A`a{%oc_2^~*?Wlryqxvbt8!Zb!
z+t0c|y<Si%{{`ZKZW#le=7eJ39`JmxZ}JmJ`Pyr`@-FDgg9HT+&?M3xaNE?QlO3F1
zUwZ!q9jW|=(Xsi@{}M~j<Rh+~PeA8NBzW|SH27#f0EcsL%yk8i-jd@#K<U4m8Pr;a
zPTMrU)&Q-Hcm;BQ#*2uXpnUxDJLtgCDYwAv*MI*12dzUd056AiVZc@&f#Vs}UI5iO
zo#(*Kx#PZ_XZTw{_k}~VI1BhJKnKvE8h^`lP>i<T22H?%ia%%;2bC4jEY6Ia#X(A5
zgk*xUIDaeTHe=RKU2qoPWd_RP951$kU5>46hK!q*-2mqa{uW#C?l#e5|3E9}ZRdju
z-CkacPoP{^!2y~TgjA>kp2^{m5p~N~9=)Q+K`V>-T`qcdim1SX9yCJh!obiy1>Efh
z6$oH==IBF82M`Bz*%!+VZqOYW8a};{%R)Op`gAjZatx@#_XHOapp~QGdx01HgCvz!
zLvXrm0oU%JPM8Jg_yEv0Wl&B5YXmKLfEWl$We%R*?i#REhiH+22AKamf|%I??#pyT
z3R3Xu_A{W)4JZY^JOtj#3Q6yt-31mNt>5@t<Us{T>+KS@<Iu>c6Yxkr-dUrP0<y87
zm!$!z%n`c|4quQ=27k*9Q1n8}oIjxR$a;BAp+!%p2Zu-V0S(ALqze8%Rk+g5IgmC>
z^DzmZPRJQohW~wfAwwNLy#)@SK!b!TXbEXAq;~M>{0wTbf>NGm=aJV@6FhpIIY0#v
zNF^w@mVg$Z+=MQ6Qg~qtD^#9<3W{WiAs)w_LB$UP=;+tu&Y<#+0d#G=NAqD&1$)A>
zMkS@B+_T%?z@uC2#pCPT44^g<=*+Dk6KK)m3tHE3@P+tgNVx*KbqJiLz~u_#HE6jK
z1IqJALE6hY?*XVPVo?E=GT@YlR2RL}{rms_1W+RuRBu8GgYFuY0*}rL1&?0a$u~h-
zZB!767Fr~H1ML%o*U!!G87oXd5%(W7g<k<G7Cbb6K#PTIpkm?J4-Y(Lg3DEI*lGNr
zGM(W?^)+z8FyYVt|Bxc64aGjh{G;J*@Qfp<<?~|OHE7%8ScxBG<oL-IaEdAM_vjT}
z@e;JJS@z*0P&N$U@Jt5fG6|344xk}hhTY(@06a=8=Fw})4cbWn8XoQ}W$@@^2XBdh
zj#PsBS1)c~<z_%@xV*lF)ZYn(yHLaMn`h@)kIsv}okx5+&%O|ZIr4Z(48)Q45J!S$
z$09wGeHlD@S#7|M1U1P%fs-_7pxl`QJUlH3Q|;_f;^EQFz7OJX=KzmhR?z(lo}DZz
z9-XlaouK&u@Vqv7D(QvhRc;2)<18wmVi4x?*SDbk%@^Dt|8(AbvHLO>Ra+*6g9o@F
z>m@)1e}+%zIZw-*CE<{Qul6z|m~%b4MKAsY6?(kCKnFQm-t*{;0NumJ;nB+r4u5dF
zVBf?4|2_D9E_!r|gA6Nx6?WiB#JKpwX%k*_{bvD%J19LCKs&sk^Be3zNAts!y$HJk
zN+h6@X5gU>US!aD0XzxwfZgLDXxaWXk6s_<0%-7Gx&(GAe+y_k4ydJ2;L*z~dmmi)
zX?S#IICykc1c26B^zxR2oY`3bx)06(q_V;TRIc>$#)A?PC~b5@PF;b_i9*|NpcK>_
zP~g!Skl?|1xf{A(zB3}D^^!-gD9d?}&s{Hq3UW|I<k2YzDr`Z6kRBK-HVz}w(~IoO
zV6Q%c#+OGg>q=0=y7?!gM=x*PYmlif2R%BOJdv_Cl78rVh8UFqpUxA$$({<$6*A)W
znV!u*8B5q2Dx~a6bYF=70|hxVD99s_g4`M&<VfZ<R7fP3M7=O#0F6xG(*koZWND7!
zC6Ha9vE2ypMA$+8DTiJdeE$C*6t_qgO?bh}OxR@H<Da0y71V!CU}Ru`uGDW)31DPk
z@a;V33pzy(bZd)m>q-8W2yO-j$L>fO&*V%6-{e#U$L>;@=HCMReY;o~7@B{J^S5jS
zU25~q4Rkc57c=PInWy|MzThj`+#t;i@cGflA&X=onX5$wG^PP&_d*tRgZdH2TU0<@
zR#4mHcnf$u7Q}q<Fagx$03FGE7<3`g6tE&t`T&j3fiw4uI(0S%kIti>-EJD-F=n4`
z(0W?1?X5werbhE$M*fybaF!T11A|ZU60k|#5UW5{grnsV{+2q>ncmPPy&j-u0(2SX
z!G|m!jR!%sKDc^)vFbcHpMW?4{4HNVM|5<@s04tj5YYDA&Y!-?t_q&XVG6#TA7MRS
z@R%S-hXZ&X3e@liAINmWqxk@M)ZXAlFr@L(c^Fi21@O0?1aA`;Jp)S2otXxn$*v0B
zYgE9;SacRzfU-xg=zMTt7{~##4YVQL(Zi!N(4mCe5gaS64j?1CT~q=*jyr&6ml-^c
zJAkGQ863a4N;C4euHpop1r3o;07uGk2go({U`@>j!2OE^&?-Df%OgI?Cw%#R&wv^y
zebabB;h3Wm;o0l>A2gi<YQ+0$J_Hq72_Bt?Tn#UE#(?HuuJ~%c_UXLg@%@Hpug-Cw
z&J!NrZ}{};9E6W|__jXb?|90=z~Iw)!Kd?~;cZCA8!m5n$<y+5J-f$DkMA{S89Xgd
z*30{LgILY~8B0VwEwA(U{RK5``PX0Y1#OLByzJ5ZlF_62=YP<8<KO@JTke5kzf&G^
z(Zg{8AIoc{T^`N<7(shq`TNfBK*L}^sJ4Ju?$Mp2lHk$X0g7|O1Fx-ox;;PmbW3_R
zA7u2kJk8%S18iayhgWZir~v4Q9I#%WPAN~&n(O9+0zQ_<_*?dYoYi^A^WY;EkU|EJ
zW~=|DTYS1XJ)3|2hu#<1iD?Me>z&Z(Sq<95-1!PLLK3D9I*E<HWd>+FYO<dKsD%Z}
zwLYD{3{Qe9=odvlSr|Z_`~pym4l*WM0b)Xmy_eI#%S#<V_uYfDM+^8U3Z%@5lnM8O
zf&$bzfMr&sTnWmrpng9{>V<tQEQgAK4vK`#rGRoMSoWbZD03e3>~_@vg*X3{L!hOu
zKHZ?pGyeSl-*Sn+1$2%zNIfV=zlb~o>d5zii-;FKU`~q)C`-Y7>kHagkfWmD)A_6O
zCnPs@x2S-92^x9@<v@t<T~rLZTflh*JR11p*Z=>WhhKtjn4Zx5PoR#o`JXs{tK)Cb
zts8YxcKj`7U}i0dsr~!^|ISaHH(zXSgammXD+2?}0iK|l!e5;~U$FiF1@;~lkaeI{
zb>I;LutOlh?a>UXj}O0AhI_8&G{|$TfePS$Q<Em7-&A*oo1ycDN8=Gtxr{QV1zTU>
z$iK~1!qLJ_g1>diFVG?7bruZ#t)Okxp3Su&W*<nj8&cx7LO8DA7;csO_y2#d^J`Ea
zzHI~eOhIw}ek~CO29Wpr6+w*Og8VIqg&7$5d&C7mrMd`zKc4^tgJ<W<movegVg^v4
zg5#jqGr*(stS@NkKX`G(iO!!M%?H4{A{1V<y@mF27J)XKgCZQU7_i$%CBX3Zi|SLL
z0O$cvUA)MHa=_^%@f0`1%Wt6GQ1=vY<ii5Zwe!J?93?jJP{9l~@OF4mKLJ*NgG%m~
zUcdhT_c+cDsxV$kf_CvYA7^}70zR7;++KF+-UChuuC4$1TRp%9VhcFhJbG;zuKxcI
z&O9ES79f8jMIhu-6i{~Vtl|KbY5|^|2RsixVDVuF&&awLyp{*ANAv6s_yC$;E8+1>
z_EYfSUw_fFGvI?~^9upc8eZ^>&K*$0A;6=#B7lLvWh>}DgKn4;Ok+XavrYrJ?cJcA
z9-S61FM$t)&a(jB`q#3U4HRdB{4L8tNAH8;Y##U~QdiKLM9^YskWcwr61hM{8Kg_q
z-2?WuN4JAO>q(FjP+8X5q5?Yh4PHMi;Du-a$)WZqkDUP5ah{z=_*<&@89)v1%~wJF
z9TpXjUe*`ju8)ff2Wb2rJiJx`@&L$~)&u-~%Y_&~=bt5jMrk0`4tUh17qaUI)VTzW
z;DU~(0acrwu!XvNz)8cSw?G2a(*&gq(C8PW0qCMq01^ak&;aH83=ju2>*U#a<RwTY
zqCMyXorecyS+L$-Q5`i<FEIsjy!DqO;4WfI9=P6yl`oKFX?PN(3skOxhQ<thKwA|-
zhXwb7&Jb}?u|O(QK>h_;404Uai|OAW$-i|U$kgN($UI%^ZI4d37aqxw-9{drZXZCp
zKt&y7bjs~ViI7h>>oZW10J7@li~FEp2OUn(d`!b~4LGv+`#?8}fi!|5*|Xc%pfg7$
z!lS$9g#_s0hpQ(*y<s1f3{aQ2z@t~xUKPo+>`>2c1>GLl?Pmbeu^40rXz&e`#K7i)
zXDlEsGsBahMmHz~KwGvzg{KG9^9nDTpn1GC98_h(e0AInlqDHFj=O=1Fb0q>Ut0eE
z{~xr0y%*HS2krlb+5j?_+%mjGfPta&@XPa{><%sTVUgw7d9$+wsa62zCQ!)?iX4p>
zzaD{0|Ea(J|8IUR)cl)?zdao~z5~kezM$%~^B2r8&<wbX3aSyHwin1Og%^CEz-D<u
zT>&Z>J(B}L8=^qz4sItXSV3k(G-bX3YZCeO|G(kwmxZ9k<j_FzOb%55Z5!zBffPyL
z0EhYxqL=p#Snmz+`Sp<03TmAM_;$VkX@*pT8Xlc5e0qHoJem)HXO|RSe0vT_kS#`_
z!$;7{V^D*y+X1wUj=vRjsn|;p0V{J~Ts{IRr$MRv#W64kVlSv!Yj_EzMeE!7vGXUW
zp#Yi>fixf?CzgQOpxHc7Mup{C3lIl9PYYVL@*?Ro*o~csOV|x>zx?(CboKiZaH$2l
zHvra#mEvGv*a<2{Jd<-3K!Y)$Y!4c90a*#^$$(4;4MBkne!&NFFKBp|6VycO74-vM
z%mdmJ0NNYS`ro6Mx92G6IL<B5@CJ>=SAh@c+yib$K(-WQfX3xHJbFd{9|iY*Jv=%y
zEIjyKE_!r|d33VB^!oAt|BKH@xETy@ztjZB45a*cG5s)7*mZ$9h_LhR{0M5NgAP#4
z0hLAIk_8f6ptuHy4#+bg4odUI@)J0q_*<`n>quCOCr8Bqv=6Jh2i$)H<y%P5Ku$LU
znc@IShp<Fx0ZYXip2?t9-!3W&FXGREO$K$b%Am;-Yz8O<L6-%3bRIOk{a@f^BuKKk
zB7uRw)dB2Zc>Ps-4>V?E@Y4F{|Noxdp`c~i{4ETB{{L?VRa4)8|Nr0oPmsUm9k^ML
zB><Xij_7q|?95RK=yXx3K&^EG4uNYO(0;D&5YTMGf6y(Hy{s1J|Nn1&>(iU20h;XZ
zWzDz@veb=(zi%(72h-~$;c9rvqqok%rSme#-wB|E21>sm4)%%zBopzn5laCDDgbI!
z3}ERTTweVGDR=Pb1>FDv>bG@6N=uNa!i!lSz=6o$8VfD_!I5~}9b7JgH&nQ&ByfON
zGIzS4fCRq#1<M%F1vq~}9t3S90u}5Y-2yLI!HFhBB?2@Qkl_J3s1sE8b%Iav6HSum
zV|Zb-4_t$_I)e(a&X1jkUnm^pW_Y>v>;M1Y`GpXb1n|HhxKr{Hbhq3KcTm8>&a?tW
zt`I0CfybUfw~m0a6{t$?o&wH(pj$U}85tNLy~q~OG9^#YhJfw>f!0g>ee9s7<SRx{
zMGYDr2IWJKUY83B9=(utDIUGBozX5T5zqneP8XGg*TSIrN$|ifWUlBWIP~Sf{augF
zTQ4|4u53L}ddCx7Ro!~=;~+PKN3Up(9B5rh4QSoROVET*=fM|xd%<DQvJKR6g!b9N
z(;y}DJ(58UwC)&{3efQLFUUx%%wbSg02S9hz24yYEe(%e(Bu^;7o3C+(YH#2Vgp)x
zH@m1LFnSz!hE8@dgY+Y+ZfAj)pc@I0d<R+*6u?j-3vMeyk5Z2SHvvKGo7wqWnm|bv
z?6zLh@WarCrzdFM0c12Jmx8MuP{rZXsqpg2XHd}(>U_iEr}+hA^N;@}rl13KYE&R&
z$-O1l6?#MegYK#XP3iU49RC4YSBq$VgVwxTelL9mx@GSBK5hnxL-|`ez;##&Xy5{T
z-#EgtZ2Ya+U`bH32Yd%o<Y!RY0yRJwT%d`>qq|mMX9WZ3wwOyLqTr-b!q@AvpA~6V
zq5)(b$ot3mTTDQsE4{3_r$NPUs028Qd!ZZFJJ~#XSto-A06X0{UN9X1#X59!s28$s
z3$zZg6Wm%1QAzOZyx`F*8YTlu6`+-JpnEDo>&7K_gAxU(Far%yId;d&fDWcV4r=o^
z?*SK*j4rTtaj$4H=!oH7)|wNb{(~E66B?)y1D&%+y~ECf-{p`is2T0%z~90GZOniY
zgCpp)U<Po)<8S3c42NZa8tnfW`TOG87#Mtd!!&x`|9SMrDtPqP9M$mcy!u)UKEC16
ze3-+-@;85r3FtCdP{QvPe(@g^aG)X(R0;$@OMwJX;R(7oCq|l&;f2mFkZ1W@4*me$
zJPjFR13RQ-EqH<#)OhV>Y4GgLIf~SWgUsz}c=Wo0N1YU2oV^b%y!1f91Wo%G^Ssa;
z25Gjs3cLiJxb6rZf%EAs1K%|TPQSgjbqAmc8@Wf-Y4B3wBlfh+-;xTNlbHd^HKe5H
zf2FTpYJ+q_8&aUzJy1d9+xY=LIG_Ql1;EuAD3iT-d=KK&mUW=Y45=_|6$4$?dHZF_
z2hjZ;1oK-AYJMvL<u_*ZDcyUJ{MNo3k>4c1*5b%-zroEkaDIav@bvsWD93^3Hz6~I
z%&r2UGW5mSJ<uxB1yp?;`S$-msP;guMma&YLbv0Xfrfy3S-%~JciyzmfS4$qH)t`|
zdVs$_@YDbQ;LOb5Vg$O#ml;$LfCo{3yn_vwOgZG(02(Wqdcfikf9r#HpmsH%XXi^;
z6T0~~6F3t1+unlqD5$>#jg>%JT%fTM@Nzv+AqO2w2QAm*pL+P^mv>;#L|`lJN?@g3
z%r%tKt_0WQ8K|`5+=U4JSzkfr4ybe84ZZ>cQQEQdx7LCsL6!SYNa$z2`~Uxi5GWYI
z{c$W>yuez(BOA~ihA&M(n(|+>FuZ&OS}X)lnSL3NiU{1e?{xz&Q&4yjatE3muY%@z
zyWLPWh<<$GyOSGY&Wr9{;CALUWHY-V?M*~~6+FHS%JPslH)s<bsGZUa+G>Y381@>{
zH7G3ubxc8d#s%7~h27lg3M#SPG(fcysEmVTdN&LH7Op@4|3gZ=mm<Ia|99;zQTgwg
ze9X1;8)#P3NAm-yuJ!DVxvJpVTXPiKtmg01S00@o4R625+riE7lKCyD$v+3&=5TGj
zUBV7dc%^)x8a%+G(@o(ecr+>bsNqT9PO#xVoxePLWsZQHhNCY3dkY+_CHk#z>!$R&
z{`csO^ME+3=7<N{JnLZ%56j=BuU=+?R%wFT#E_{NM5XU602;UeU7QKNp`trPC87Bh
zcsln`=OyTLE>8oz>Ww*vZ#ow|xc#DZJ2%5it~cQ8+Y&ktH@{-!???h&CYB5~5?rez
z8Ch~3RA+#S81ODR*s76t8Xll3{iVi_|NniHzq~91=h8jk!BU12K3Mo12Q9B+aDh!5
zKu4WGr%OU^?dY{#w+Tym4H?3GnerOki*L310L}QIE-onFg3fn=n#DgAUKSW0;@@`Z
zMePkxLH|+%H17thP4<AU7W6po2A+EG=yU^5l^`XpgqKG_A<%0&0pS{WO9)y>yu9}6
z|9{8MTaMrm+y3|ef6wGYuASE*DGxlK?%5l21(foR;7EBd8^IL@IGcmc(8~uEo{-WN
zK2ilLV_$y#f^<G2+Il+BJe6m%qXKBTjRSbv?5u0Ir;JDEb<oiyM|`^XsDP%{Kz(9x
za|zVMg|421^@$U@on;)Ge+u{{7b}3&fmTX@2HZOj@%J4DHM^UCiu1SZ1hINOUpN0`
z<ZlBVaNFwvVXtOpU}*gY9-`-OwF9jfYkn!{*!+{3zx@NqL7*ds&Dj|k9FKz<>I~h^
zGR>eP(3$z$o`H<~<|-|~-|`lw@*PMFsxnx{r}O0tZf@vO0r2v*X3&jEpp}g;Hg5sf
zJf5IyIzvD!+mb+MV)wFU9|F}U;R>Fe>>j<We@}pT?i`RBqNN|ysA+a(VD#yH1-i}-
z<X4Yw-t?P%44^Ov84OzCi@FXKG700`c@v}rymr#3Ge#xjg<~4nWuBex8a~}IASWoZ
zF)%b#gNE&&f|{4j%#5I$EV_Bwk<It*yos?Y6JiD2{1?wsVMZJ9x9njB4>g09ih{<;
zq(B9<WsOP#|CB?%me2U79B4Vj-wNv8wZ7$V1$Q%hS)XnKbxB=R3SQm@-@OK!WcVS@
z-)afE2ohXdwtQk`U@&|Oa;^jal%t>}eifjGiErlv(Dp*m8Ed^Epw%TIpyOtKy>Pw&
zF3I>?KqqR0Z%qNEJ+wIj2Zmmc_u#l!{s+Ern7_rH6(0AXc_ab;R+)eQ|9^9q7T|B?
z{P+KVx3f&=p_iZzAb9*58d0Deg>alBG)a{&e7OdcX?j^zH$(jgI@+fK<Z)-v2unAp
zbJ`7QT!SW`B0$ZJPIl0McZEkM+YV5=e(4BWxC@`pX#Oe6-})WYhx{SR-vVI>@wYr-
zVPI(fA<W;Z@E3aNIVf*{Rsw+Y&2h*@gfKR!w+dpv*!%O(f1h5+C<>_OehW0#4Qlkg
zFy{LA-=i7Q6=mRW*#+wH_Cibnjb!<DzVzt)1qyl4Y(_71$QBeKFJ401#4X?{*ltJ<
z#G_f0k-xPBWD4X)n3tddlC%kq&9yRu{H?bk!4$U<8cZ**fY)?6Ff{)V<!|)?)tt>g
zh4@=Q*VZ~V{}kqLwfIAdKd=5k_NPzhE4V+sIsg3!75E@egV&XTE_wyc(1Aw3eUcp%
zd_j{|H7X9U5e<-^LsTq4N<h^=cn|~BwE&L}!}|j)pwR{B`NN>rH7F)P0Sy{v17)&a
z4}}*7ur^E_sPljvP%V(DXGm~^T-9pG#K7><6ukONjK9?yX~K;eIa~O2z68ZPXb1%q
zzaTcqV<7g6j~k(x^f-SDXk8>|Y5HA=7=Ozx&}1pJw+M14$OMnhL!iTQI$cyUUZiY>
zBnOZ<1Ahx>ZWXe|==OSWxdts!K=(U?hSEUFJbHQ0?FB9Gtd$Y<=mag)sXqdW-T(!V
z3XrqF%U+<%q(J-r`CHOKg+(v#vJIdWRig46K=;af@Vj0F1u(efSMhQ`%6ctOCk0ef
zfX43=FcKx$8Q?@2au;MGq`LCy`~<#Q09<fDlP|<Mpy3QHkjiez<pv(0u^iCCLQvZr
zWSDR30no-<AC&@+Zpgw9P^}Jf0LX{kEh>;43?3qe$b-^{2mdx_Y3R-~AJ928A)w**
zPX}HwH$PwmH#tEKC6G$+JQ`>s2*lBNQFj|!h}nV%03nNSOQ6jdPzxDUKO)8|pdArV
zf@$Fd=>QK={fAu63-Sg7!!BEpmd=}yDnV`r^ty{fkoar;4<3i~2OkXrKM=&H^XH2{
zYe8dVzyALR8{pIV^2MX+FunY(2|xe;e|>{r9#NiN{_+1mwEP5JCfj-F<$aI{q^g9J
zl%Bo53ZO;j6`*Un3OqV*fy(t4(l`JAf9VWyvI_$PxT1c^2j@epWy81Ng4d%r7|95q
z&X-^#EN=Y&|B~Sss0YaKqI(@T!^=NE!A%mlc~`*&ialc)mt(UvBY%4*s6o^%?$OJ;
z1~kCZ8Q|dwI<Nv1&7A=OFTr=w;K<CN9M>D5@Z#`wNK~~NgK`oqGed7)2Uk*{nGR62
z!bhq>bpgCs0m*>3&?>y>0LA(XM#yz8pos-=;sh0-Euc0NDCL0)C!|huH*|9{sJ><Y
z_y7M(ZtyU(BL}FVwgr?Dpbqg!4pzWO`=EpkvR>hZ9;o^Mg0Zv<WCz&R<X{C*3J2K-
z$^+mMFWEx@yh8w_Cji6(=S*-SM^4gEH^G(`KuSL7+z_Y&0%-?#lMwdz-2innAvFf*
zrp9hY{+8dM1PkJT`c+7$)FAwflp#RwL=6|PO`vdj|L6bzm!H9-2+(i=S4NP!50nHe
zJd=Ilp7lr$Pyk&36#$Yc0I@tkcd*04fI@#R10|LhjF4*|QDV6D1(FNzfY@-a^S7S)
z{{R2$M=0lEz}F`xfT9c(lHe8Wpr#pU)(6~71a};|9b}px{Ovqk8VgbgYIcF*6&5KD
zplAdyMgU(%0^VB%nnVGm0dU8=8@YymegmA=OU%KmR}&zOD#%G#9^I@<{|SPIoqw^z
z&+lFZUZv4|1g3H)XkqM&g)6}|2Y8Ykbbqf$Zw2TEYLDX%;C3x&<=*oj9-2R!4>}xt
z$^6-4wMQ@O-0h(DF?bgJ(LNB<MTG;@S_*)U1cNuNyQpYDGi&PsNN*10P0%hL(48@m
zu|AJp+dyz*16<;Qnug$&44{Eyb>#LIBCsImJNowefOg=%0<{8MR5U;{_~5fU6<!=V
z4G9!2pU#Jl|3y?@f>x|gc)`62G^Yhx@(r3eI1Ng3;8OV@hy@!M?6oyn2dWw^z#Ak{
z_G7`;`@;4HLXUOqhHm-=9o>D!w-dBV85HLQpqd`U01YiOc(mR=?xK<d5-a8M0Ck1>
zKZ0@-Xnp);(ESLmDn6Z$3{QG+{sN`486K?{N|iu92JN8q>3ju}xz+8U(&?fS15?01
z<sc}n<al)c^6Y#GUTg`Ti38P5;H=&YYSV&dD7zv1lVQmRWF{!fE4)~7?f?JILxu;M
ze=(K_pzR$z42sPP_`w69(iLQuM>1%{6?~C_i;Bj7P(vSFWy0&eZWooD)&r#u;3hMs
znXD3jz=`rKD`er2>k81SS9Eot^T~o&fKw&^lmq<R4!n%}53WTJ>m#7~t?`WksHM`q
zMWq8w&rzAd#K6#c60{!sx-V$i2k2@lP>8pH4lM)~A_hL4r$FbfYP>k{mYt#XEq~u1
zMh1pn*Z-hFYS2MLKD{DGLDMCM2RxE5f)?Q&e8l3B93o=i)6H_-r;~-vvs>h%N2dt0
zNAm#=AIl4+Hw+KF76cu&YyetBXL*#r?;a?2yG0Irbn_hZXuVYV$fwuwzYpkygzvXJ
zIz<lqG9K}0Jz07I6vqur3=EJF4iIkw6KDycg5d#=<7}Yx0y`J4@d(JH@Ep$I+0E$D
zEd-iC2I==`JpifEJvznsJGeo;m+n0(5VP1lI+?-!E+hj$=U=v{fOMkU%mB6-)Zf8s
zGkm<ixAvdm0awG@9?i!YUt6S2@aYaY#^DJ{NlHGQM?Lu0>s<D*&N<9cQsL7X!pGs!
z9dek%5j2a~8Nv<Py20pSdA!8PGx@SdFAu2DVeskY;q&cg^lbjYSh~rh+vgaEXD6pe
zx6fgiYL8By%cbYQW`OQrhlCR-$Uxq3=>*;WhZ0D>{Ob?-b~3)6<k9?!5fo6M-~b)t
z2wKF+c*Unv-J_HF<s(qX7F^`KUV)O|QTHEOfUN7@qp|=@FHu<mPGyduWOmgTbYs#M
zl^xIocmhoCQMtjyz`)-Ey003X{6N(wYVz}Z&CUQC#Oj*`8vQ^?fGp4ih)C}kNipOq
zgHNXjn{T(sMW0R)X3uVsD;}L9?2t5hp!B@qf!9KyH0cIPla8Q7DG5#%h(!6&r<>)t
zPp{{H&(2F8-*5TyuLq^-!@m6MPk4U6;nT@-+?Vm1FXMSoO5Ftt=nW_-^#CX+AWOb3
zfSDF(Nfxr(^R+v;f9}~W=+W)U;L|-v1!Rn8H;;-(>m^6%rl3wX{tj@99W<W-HVi!3
z12eZ%*rSsloQ6U10LcWP<7B|wn<4FKT<$|L2fF1GHa-g8jrw{y*nO_OssDU>-8n#s
z`jTh!5ysbU9^E;|I6zB1OZ0p@&-(DM*E#J2O49r-;NhRn95D`X`gCkQ#OTrKBh2C1
z&Ee7MBMwfmp5U_KL5ZDb@+psAk+Yz@?9(eF=G)B;T9XgDFBF_%4sdvO3WIY8D4skz
zMNWHm2mJ7{eBjY3a=!Es*lc*9fJYNyfzsUq4oR0zftL^efo^vJJMp})wFZA{JZQHu
z|N67Oo!sD>3^aiYnr;N0f(!~?{`ChuzTfiTUw_c!`%Pca!MVpl0SGbL%%{`B103Wp
zJ3zSuydwQ&8R+&3M0!LUPXxsaXwVRpFMPVEfHOnuNypB!o}feQkATKhAo*erIA4IW
z;|p*;S)=j;oKNn6MpAw<^0$C4Q%B^J5YU+(J}L??WL`is%O++921jUSQ2?C<0x7a#
zIR-X9gO*=>yJfEVbjq;#cFSD!>6Bsi?UuRj(<#I5*)4L(qcen+0hVu$8y*0qQAj@D
z0uJHVqM-E%ttU%jK~V(GN}&7XJ&?-xhoJHubYDQX$Z?-;pQ8+r{PY7-*8lPCyzU9k
zU_X31MUMOOuRrMd{iaW+&rt?n#^1h-$3Qu3F(?8cd1?-%nCXOAk0_xb(F2~Rd;p5Y
zP6?2n4`8MN*31Xr29)I4E$G?J23lYQvct2R-?y6yoB<)bpg|e%8@POEQ2|*4iZE~(
zbi%FkfaG<Mbs$+#E(QsK6N*o#E2!dVJOWAwIP)jSW>6y=WH7p~!1)y9D`@{6VoeV?
z0zg98vM$_rEol=RdtLv5F6{uB4LZ^X<UCM*_UZNIa5a1jiaF4VO;8=+*?HXXz-vFB
z?i5gs^@p*<2y~_s|9X?tKGr3NIZ8@=I#b|T`zUJG_Uz{L==2eVXK~NwgB+fg$4d%4
zlh2}Nb74?rSUSrCTra}1I5>L?fU-8IJnRfP%kX+DWdAnQ3Fm#S4ftED|AX@LH6Q-<
zC1)9Ytqu8GL32C4{Ohmyb_&042KDbjvx^|lID(d0f|{@3+yt$lkRuJ;u7-r>9%yKS
zg+P(v(y8&%71aK1e!=M3c@Y$?pvd>(Uw;CWfEmwtcAoV3eiOv^=~M$rgJQ^sxd)s;
zJ^9xk@ce$mgBel~`E>GuRDiAOWP=nSpmg!_F=%fwWc&cMQ5tmn&4dXa-CQ2sP8`0i
zCw;pme7gfUJbMHGmw*m)g_P$m{M#5o6}J!LO&10RAJD;^zy6oL{0zHaCKzgfXY)_?
za%YcT(bd0s8T^u2x_m%4qJr<2Wn&0n<KGs@$`HWHzb%l3A%KN{TOcz-05ku#KqiI&
zCjM=Kj0^#c{M!T>1fmbuZS`z^$pOCc;<U%X*UUb>GIv3(K)+rQ34VD77yfNb9?ge1
zTo^!1r=Kni4va4R+nj#6FgP%Q7{6T@9GF3jKQ0UoEFi{T7X}Ab5aXW<g996g@!y5P
z0a`;}C|&FE{k9L|P2XOgn=j44&0FO26g|4R3=e=kXX?|-`tBDmgMTtlhcDv^$NvvN
z@z3PQ#^lJ#<jBJ0$js!(#N^1x#OTo-#KFJ>>HpOo26@M~^R(x|*UWysAvZZ(__sMS
zdNd#8aA9)%;lg-;$?+GH<8LO%KTM8)nH>KyIsW&tyjXhE^ZRZ8UY?tfRE8+;J-WGk
zy9In(Pl9&Jlqk9yo^<Uz;ljiSs#$zM2R;Az@7j5=^c5&lT^JY+yBZ#N{Tb<eqp)C~
zZYj@h1K-w@KHWhap4|}~9^F9#zMw0kdp-Y`$T;$EV+L(`@nrn$_)W=^@fHJ<591;5
z2AC(&afidf27t7Jw1ERA$D^0^>rY+=uVkJM55^P!A2{-Fb7ph=mc+*3#0FxsI(|!H
zWpH8zu~{6yC9yC#v4Ggjj^C1)8Jw6wY$nHVNlXk*OdvL+<F_P61}8?4Qyjl3F)&4g
z&sqeHDl*jdK*IBa4`|HpoX5d;%pScqUqLCvqgTdi0{=EfP?Zk~U&n6=KNy(!w>kcF
z{Fd;O!HJQ7o8vFXZwbE`oIs+#9ls^~W^iKW-{$zo@ms<l1}7H&ZH|8(za{)-aAM`(
z=J?O?Tf#pECpP|Vj{hCMCH!Y_Vh5!>56fGnGd;fF^JM(($@t5+m**q+3?AtIyRcx7
zZYGazFAksXAORQtZ4BTb%Jk@E{qzGAL?Rs?j2FO{<3RIQ=YemDY>o_0Y%U-ct0RLG
zE11RN$l$~RW-&W5I5C4+OpXjrOkftHBZCtoh^6QV3Lem5nh^8qYCz%R(|O6K6B;-&
z;K1?em5~IcSC`HMps@Lt_=5pr5-4Cm1|@=m1<U{i3YY;35-<Z4AYcY4IKT{8VE9<x
zEL{T*j9Z|P0PXba2VF?`G6R~EK;hxU;REU-1qtwP;{XRolt(Ws^AB)2(c!~*;Qs?e
z`tCddO*mi%DAj-&pd<rkfYJ+?0ZJ@j1}LR~7~phrxNaWE|GuEjU+Dgq0{Or51Sokx
zk_Jc@IAMSpApe6IApe6IApe6IApe6IApe6I2>;(g_CNSyYLxLP@aZw#Tt3}V9InuU
z1e9M?zk__w)8PZkFZ|ma*&M$mvpF&z;NRxR>i8|06~bh3{FclDVKO^@OJ;^JnH;|*
zGeMY)j^C0Q!AwTSZ_1902Ryo+1Y8&xKvh4q{DJ0|Tk!M%&n%Xp@BkO@2RS^O4{<nt
zOZw4y6p~+(elorQn+wV@NxvY>-;UpsenXgl9KR*~fiV9%eoOibVg7Ucmh=z8{O|ZJ
z=|9LpmN!dhgA>SaPy%`R>mO)U6e7Ms*#%UZ7@maX6<eQPR<&=)<*Xx<7n>uK7po(a
z7mFj47qcUi7n38C7o#H+7pM^8Uw@E+DH@aoTo@SYc7x*I2Xvp<Yi8fxm|GmK{M(!u
zLH=`Pa{A%Ic+io_>z5;w*KbEAuRo4VUVj~#y#6^ddHwgbyj6PH<NIxJMNkAzzToql
zyFtkpRJ8~|<Il#Umv`w`aQt=pFrNJX(2>c3&5_B0)se}8#gWN@*^$YC$&tx{(UFM(
z<UU9K^@l(X1ov<1_Mp1&28Sd6HV<%_<;djm1LQo9Uye*3za5!8{x~vu{B>mV_}6*D
zk;&n|ujP%>OQ;TXU;q`zLZ00c;PO0*!?U}9!xL1F>$(~q0L8B(xW0VJ=*f7?@td+I
z<7XGf1E9j(vGYLbW032>#RsU8fV6)g=~c?JTLW%l1-LBp>@E-hne5RWB;nibAW@<Q
z_7AkS@L+rmHvTub&iI6=Gwy?vA|k$_<3*rWM-{j*@aQfQ@aT?`;P1-<o%IQ>`)_%6
zegfU5)A_^m;2UPIULDYeP6nS|8BI|64l2K3nHUtWpmd8U=N-Q#fr>O(S?~BQ36!z<
zw>g5#dr%5SD)T|97^&O`rDUYCAC#Jr%70LbhSmW-mN)rZ3qk9AzTfd+eDA^d&cB!E
zp$Fq@PyyI7i-CawRCj$-|E9*k4C-d`x3odToEg8RGk!~BWN>EmZ2rkqQUt2+n7*Ym
zeM@6vaAxvs{>fYt2NGlcmd^YwjhVq2q@Sh43na$!EuH0C8ViFni)Zss))F(280)um
z)^BO749={c%|F>nlt5x^-_qH>rLi$Mvw=$65<ZX^`?qxVZ)xld&g`HFaf~_a*?Ib<
zA1sw4;s+G}KHWmF76K?mfeuoM67cNK0LOocm8;<agnC5!`UFV;-;_NVUn3>5d!PgZ
zN@Ve|pmVT4f>RAbe|T8%K5*roe9)yg@Sn%Q2h8BD_BKo&{C>y0dSfmLc=Vbuc{aZU
z1=#-*PmgXU&^XREhB_yo-XIR&ZYf9_Q1-OERr=AVTh6Cj+>wddv4aVe0T_I{MGp8d
ziW~xUJS-2^et;QNx*gQ0fGcl3>Da+kG4u6l6!$n{anB*Jdpb|}^u`?GfSFd}5AW~7
zo#)`w>%=j^w_5;`R+T(0Z-Cq<=F`m%YA1FucywL>-M7lX2<h|QDE$mGu5>5FaZt4&
z$1zk)etnK#o*^vQ@LR9rKabv+Ljo}6CGLpuL<EmLD0n8Ig%9H~!vm;6QjZ9d!yd^e
zJ-S&=IWQPR#~o%o)_SsT&g=7_QUuw2Z2bjA_;{oX|8`h^A<c!60oGx7@flh^qx2Vo
zJbFc|KY&V7M1Ns>AWs@&01yB6K&~{#051ORfgEX!0UZ3>1KH9T1K9Yt2ePCw2C(pN
z4`fPX3}E8lE||tB5DmZ2pl%tcd`0d)L^FCGe9QvrJ~%MA@NWn89|S;-bK&3a^eN4S
z5!7+m?(_x3VgZSL1F_gZtREm22Z;3x#Nq<6{(x9KAl5$+i_fF^fB<Opc_~sqLJl%z
z0_rh!GeN5jSC3xab?-r*<$+WikeuMi?7)-e$n3xcA~-+<8;D>55lm^0%%CcSBaM*>
z8h&+~LH>jGCwzN@8A1EOeHjnI(w`&$b`K`c<^uw0j?5k(7*BwV`2r%ofruX<;unbc
z10w$UT3#qU3+-vV3<HfUq4qD7A^nRq7iRPh#!FBK0~Cnh9>ynl{D%d5g3e5c0QD$+
zx}`u>JE%?K3+rFVJMwQAhW0Pg9QoG^c{1KgV-)a#)Jmlfqd`}vAe}dX+~05#0F`Iu
zH6Fd9t?xjMX`U_*##8?vIr480<^dTN1Wr02E*F>!PC+0p2bc>^NFXj7m<vu%ATA4-
z3r<!bE)$pwPF*0!f_OrpG!_RsFNMFa0#xibzvS@gyy(+;3v>?P!S~D_z2%G^2cNNc
z^vW1OlGs53kLE)HX)gTh9Y27=36x+yfw?G2j(@!)O2Xq`?}(E8_}4q4Btri6jwnfy
zf4w70g5+QCh)9+mmN)oYb3rR_zTfv`{Orm2$+ws1=gV#2wM3Bq0;qis?yrE_0xta9
zA^nwHk6u=%x8Sr2X`;g8*QN778vlAno-{@$9w?hDjnRn<%H~L8bmD-r+0q!ny&8~u
zmNZ6iZwAC>N@H|l0)+%)nhPTnD8l<d)6}4J?Sa&8k7M*W_?QLMZ*lEB<k5T(9F~Eg
zuoQ6ZJOt7o2nxvnCKwMCjsYw%9w-z8*kC+R7zS{_c%Tpr;DYf$;TOOI<AFji0Gg?9
zmbQ3&zvsb-=-b=_Ehg{;SDT3N12+))w{w6JIyi;qdi07azX1ndmk%g~BFfLsQ=s$|
z08Xe-HaL|++2AA!WrNcvlnqXtP&PPaf=uB^W8{dAJ6zWd3OXOq;v{I72Oe}16C68F
z!O~$6IP4rdPl3WN2oiQM9wh8wJV@BVc#yDz@gQLb<3Yj>#zPLf8{n|>WV``x_CEzD
zITr>7Q2WB8n+en(GCT<mtXiL5R<YN}?R^*i?G8L?uKeqrd0ZF|f_PkD9v76y0p@W)
zd2C=F8<fWa=CMF|Okf_93*$ll?F^tGV`e-EiY0Ks#m62_o50@(I@}8sfWDnKuxDn_
zksP2(TmWQPzz3Jkt1kT813rOypBx!q@o&%g0x~<}iwomL#<Tp}J-&gs9^V{0PdWAa
zh=S^zfFEGxKU^3uf;9gE^L{xpp5ou`@dvE>4}|j%%=zcSc+tc1Mror5IOBqI?Rjv|
z3DRG30@X>d{)oLtFYniv;M4}GSU^QP!8%0%)GbM4WQsmqw-e-jXqU;S7gAsPGD7-~
zq}C@lO3%W&D4@xY3BjOx!l#?bg?~G;ds7FidvW!r4B-7KQ2PPgp8~}cGis0OA*d7u
z1!^3qt^0{z9-7{X=}&2c+XMXD!J}^;jIW`_{|3=ao{XQ;7~unPw?J)pX#7CVrv>$=
zvN%Bb$)mdp+MhZP?@!(E1l^){#-sBUs6XY|TcQH4tbBT93|;uQ3xWz)L?HogJh<|&
z4*(YzF8td;#Vr5&AZUV5b72es#b)3aa53@)oRT5M2T1KVu;@3iD5MwxiT(hKLh}H~
z1W@`7`~?<;<^_-_sC^aq2Q2yrYyzZs0h#a*Ecy>Did@Xx<ZlHX58w&vhkf;6{0`}d
zeFpc#KpPJn`L{Et@vnDfNaJ76p2i63O)>JffR4p?<lpYh1d;*~?o4Tn;O-X_WL6O*
z$pVrD5$-H$jNm>Ob4fW!f(;}ABHY>17{Q$^7Eq^cyE6w!0z|lTq%k^!qJy=>6{Ld;
zBmpAaxzZS&xxigD9gqYMNCHH-^Q194^ME3-L>MH&2a*60?tE#C&U~N<hj!W&L2XO;
zd4Qnu6n}rs9<9FyOTV8$35(g2@pl^kdS=u<+bvL^4V;W2owg5%`U|ChL_~kh8`2>G
zW&b*7k6ut!DFN#5fFe>DRK&ga>6Y{8W>0fv7EW{N6hQBuAobX`LOMk-)vYH%>MN$c
zK7+ho0L6X8_um3x?Ps`i8R{G%&IJ|!;2MVs>Rd61bD7dyIzfFnk7foYkdJ&Uk$Z5^
z?j=ku*s%;1{h&Ua3-bMSSo?D!i13EHN1)Cd;vTf%b78!O+#ko;x!VTq+@&#sI(IIN
z*IG~3^}Rj<oxVYv|B;8c_ds($F5Qfv=^sRI?iFbI2h#rWfsA&85^lMxM=$G|$DoEe
zbd;N4p5gOh$8HA+Mn?(9ZU+%YM-j(v2LVP$0mp6!9!5tV$8HA>Mn?|EZU+`dM;6C!
z21dri9-SwAIuH4Fo~l~~n(yhBa$%J4Y<|Vz(jCR(!WhBg(R@h3r90|{3u6RG?2QX!
z1dmI1)CU*F2mzPws4p&z5h5<#Q9oQ5BP3k9qyD%sM#zAUMe}U_#a_PwQq`SsY<|e@
zaqtCb=@6sG!3V6Kj0Zdz556=7x9pJTe|+HmH*=3(-gl3Xs#$P(?a1sP;mGVD;>heE
z0P4y)GCOcMGCQz9J8q0jhkZH^f;_VuGQP&l2=a?Z^Fak>$0y8=FPI(QFgt!=cKpKZ
z_=DN;57?2nA&xu=apX&8&}oz&2OqL}GM;z|8gxQV@4npvpu=RlxnNU5;B$gpm>Hpy
zL8Tu+6|f5<1GN80sDCEo*bVERL3?M2&KYR_2h?AX0=3?Jx}n`MP+#HOL!?;mc9wAD
zU+*m8$mk%^?JNRfi#Remh;%!H+8oXTj*Jch-OfB9aUMrT2cB+c4iKBek<o#p+nEK#
zW^rV6VCiOd<X_M1$jA^K2XZ_lz14O5bRO{Oyy*ezdYwy~;L<JR(fp1BoGAF$gQ_wG
z7e)b>?w}_w{ObdsxG)B=xO4}-0C8TpFa~hAbO*fwao)Hv2JpCa2Ymo>KDaOjfb@I;
zalW`P28g(H2mJtXez-6ONVs$d{Q+_QxG)BQlafdCKlb`oNGxF_B@f2Ko*;DK<=ub(
z|3lhqK^&mq>IT&a?By|_^WPsJ1(;*ElLY_zgP`zo>~<1?Fhv}@odh6E0mp799te}i
zvD=9Q!sKx5c4C1rL1D(_$jA|Wcmg<dF8OwzuB!s4Ptfq#YjE)JufNGC(H->!L`Sf6
zN4)?uIJ%?WfEhg9Q6Inzf$pd;V1`I{)DJL2qC4sjm;v^@XY+6N`V}}l@5y+`lkotk
z_U#w=|NnpVVQBkL2+jYjwD<qyf%E@M5l|fswjVa$t>w{O#Q_}&iuUN`Rk;r;Nmx34
z7!Uq`*zGI9zusSh@kF<;2>*J25fDRwf4#o|h{40Z-k%4=;NV~H&jDhv@UQo00Wlc(
z*Yh);0JS+m{b=yLo*te5JUU<dcAlx50=B=K+oe02#k2Vh2mg9L7yk8eEH2%_94_6?
zpi7+<T=>_Af%1mi8;|D03XBIGds(=<y+81;_xs@5E5p?7{DptL+ZXp<5ec_m7D1<8
z9)@n`AN=dxelVWs_Wr}a-tQ0N3D4#~?DaDs=>en2@?bpc!Fc{9D?B`4`N5@I0vZ~&
z9=*I~_mD!vk=aSYk=aSak=aSWk=cpIk=cpEk=cpGk(mkPRY(5yhe6#INO=mL={sGw
z6;^*cGBY@Kd$4#kzvl34J^=C(v&Rd^ZihdP%pPw*Lt>819$y@pJ$^8r@Bk&`^Ee#t
z$$08z?0<0n1+`g(P~E%i?qGE<sC<_I%>ua^g0i7cw-BhX22I?Q$bm+39lMzzqi?rB
zg{vpyXV4rS=yc0xpnkCnq_9O=F92#^dVp385S$NEhom=H_XT47Z%6+1pw0`T?{W{+
zltq;15c9#g1Js5<%mzIKE#2+B;R!k*@TW)TE8ou3Aosg;3wbs}3N#n~^@5-{234k@
z{>lU7f*&M+TKa=TP^$ot2x>h55<#sDKq9C$0!Re4S^$Z_>jqHq$lo6dA0)(5KOFU7
zJnq4G%!BbTsGw|_4PJT9z`vfIe?1$lhXR@}>UL$}U+>Pszut`n(*Iy8De89R;9u{~
z!N1;(1Jc7_E{W@Q<>6oN&cnanjR(?)U@7tHb`{`X?=HZ<-c5kf88mLnT4L7iD#E|s
zU4(zVn+T(`2)GlX)a@$4zusMff4!Roqq77k3QG98U1j*!yUXyecavdsmcfiK@Ca`O
z2WUnJBb9k{M+uZ@A=<C-^!5pwARwI$SgL#A(d{GwPId9Ihe7d+(tanRe*v8ja_JVR
zb3$q#yYjCG_bxs_dKa$D!r;C|+62`0F;edW+F%FuE?k*~TTi-l3RKK|eFnun#P=uA
z=7U_i8R{HB&YR%V4en34@~;PXCqDRegSrT=%uJBZ!~~CK1{TcT1Z+OYqnq88nF-`L
z(0tH&T=PMmi13H@AG!tL_JjKm@bCe5A5a4YX-4QEw9|mpXPEW+JaYS!+Wm)|8%PbK
zVb_0HcO6u3AkY7d_8&m~hi%u8Vtus#K)C;~^eR$-jlllH(JM6f|KRRFJh==iNk;n*
z?B$^T!?#OFp)myd4{3wey`%jH$iNY(O+VUy80|ld_8&mY?LgftSpS9o{RbcL{DTj{
z`G;VSURIs6NDTvU|G~4{!N7yj(ExlQC8MK;XSaib2cx5cXSaid2cx5eXSaiZ2cx5a
zXSV}~2csj0XE%cfBWU&;yx#yZ8!-nwz5!a(1euQjjjQ-DMu5gv9elc@F8DA;2>5hI
z-SA<Iknrh_df>wtq2SXU^}>fSLc^y!>Vpqsgn>_Y)DIuV2n&zq0}kM!ejM`=Y|!}#
zRXp<%79PF4ac4mF9&&%eli9(*li5MTli5MRli5MSli5MQli7j86S9!Z12G}73+x{c
z_=JRm2eab|4`#;;9?Xt6JeVCHcrZJ@@L+cQ;KA(p1MJw#*vHD)K=TryjZvWfJNEeq
zAGG-hAEM_YWI+dyfEIr;e)fc{7V|(%NIV8D9+F3!PxAn+I*S4ixPyi>%0c~$u+vDX
z!lT>Sz>|Nyvw<h0g8}G%M-WHDlhHxLquW^l#8L2MbWrf<c9sBfBs>`%Bs{vE1wb4D
zPeum;k8Wqs72D1no{SD09^K5I{Og%Lp(AH?X!8@Goez-t2?rm@{DgxKqkvC$&<P*@
z^?@gR7z047t1o~!7kn54Kr%N#oEtuj0TMplK@UKj2R@7e3O?OIFF>3ZK8yhxKHWhd
zK%5Ugi~$Bd-9bM<oF6`n0pO&CZ+?Oe_xywhbb=z=qnFj?6mp1lp77*f?*s`j2pbY!
z5H=*ZAZ$ozLD-PMg0R71<;lOE%M&zBff%2F&sXsGfet2{0J_{6GQQ{F!M{H0fCr<5
zN9Sn}^MnT|vq9JwJQyPcpyD??7$ab69(XW<Zb1X9f8oIxp#fF%!Gkfv0LuR10ndQH
z+3WiuX&QZ$jtyxd<HbMFL<V$!5Au8la(J1Xq;q)HwLtQ3=V|D8=wJx1mv6x9ypYy!
zVw?Y{2F-t*0F_+O{)<PquYm{udVd2C&}@dU28gWzVS}zf@mGMbB|zd55Vin_EdXJ2
zfY=-mHiHNMdVVl7NWcR=D}qRG@c9w`KF}Sg6Fj=PeY&GLKocY${OkFA_}9mA_;d#g
z_;fo<cr+gaW!f-M?sU81(R|p!gYlqeFAKLvxAy}N{`Gzje0yb>Ji47<c<`@xd*R<J
zBH`D|BIwo2!{E{F`~f8R0qhj-A0X8~JfM>$(Di!glO=4>$&wqOg<i1v4A^{$56XNA
z+i|4O^JI21@MLz<@MLyU@MLz9@MLxp@ML!4@Py2lc=E453<?RzdLi`r5>UMWnJaPd
z=sf7j>~X@A+2evIv&RijW{(G+%pNa1nLR#ube`~JcK89FF*ys#F&M4~&6q@E)K`f7
zf;``oc5JA)pHP3u6F#2;sRcfRYHs*^iVw6_K%_s&d<QY>!89THyBjv40x|!$CuBm!
z12Lm=2RuR#EuSFf6F;8<S~~<SZ$b5wXY&CEkLH68zWnP04j@-lAOY0c3M7JBWr0Lc
z>n)H7YUKqIL9M|+BB<3ENCaM&5t>h7^I$}qPuUNeIqG%=l?3b_{Oj2~U~?+VAQGVB
z!W~4oad<F-S7|Zvw{$_|K*fqXh;S3|fXtgPmlSz)yMl@ycM#zw;Q^T^VJV67=ynAa
zPwpVXO~HfFSpmE+$H@b9K??tRcThRzrs2WptO1^D(emha1r>AdAi~YSgVEUl)Icc_
z^5}N8@ZewX4kFwvJQ$rVpfL(vFH3N~MH`X6;OX%bG`)C0CR||2@;+$71)MCw6D|xW
z^Bcs^xA>sVxA>yYxA-y(`+(MR5jWrB3z~27q2_#x5BhwIFY0`YFEf)5c<~l!z6ErM
z00-*oEu{GtU(kGuPbX>fEui25FCUxW(+%z~A;Jf=T#Mj*iwAhZ#Rt4dYv${7Nb|AS
z=UXV)umAf1xF{Y*`}JY_Y|TA-S#80-gYC1GcVKW~a%6L1a%6R3a%6E~a%6U4a%6I0
za%2Q;q3?DA9V>9S?jWd!gKn__Z`p_K*k^M5fw^1Xk?{a%!~SjPHX6`|eWdme_WqCy
z6WaPL2E_U-n(WUH-4AM>j_%KA0IgpG?{~r2pC7aj6hzRKi}3Z2;N9*caesdDUU0cE
zLiXo-fcNKL0@cUm2_C(yt$UDs589s(-kyI5v^^iZJ0HYi0dLL+v6#Vo^Fb^o@YZ|~
zixIpt{}BH+M$pFmL*Ugl3<BVay$-xu$`fh7i4N%ECI*jQ6HWMj`~w`ILkb)_4?{NO
zC;W6|1Tnz}SU{MN4b5Ot@BtPOQSbp45GMEl3kVZ@fQ1X=4M)a99+n?L=U3bZ?N$cu
z2IBy&&4RBdhx9i<`%AXL_G^IlyHDK>3J>T&6BYNnJ2GMJc6Vg*_|JF(wA=j(Y%56#
z$c^CkFtk5`z8_z7u(*#<e*v*y8oD1Jwh{)i{t9$-!(rt06_EBkG5v+n{rI3YSD<|$
z!)-r4!S=r<qWzCZU&#CMVTtS^sP&I>J_woZfBw<^_rqlW{qL=yl6~0jzxU|og7pVn
zJbGDm!M;W652U#;JMw@CE)c;1BG^C#3y5F>Z+!1|;s9;nhK!%pZ9(cB!1mvJGM<8s
z*YR(6WCHD{OJjEYkjCuzC5_qfTN<<Dk2Ge-Uun#af6|y8K_}#ZdJI>fJqGBZx{&=1
z82tr7(8*pPcfdAuya#RQfI7&50aV`@fKKrOAJ;;&{q~|;K#k+k{q`=j+i!nq6DT7>
zlO}Ti1GHy;bichkB!7VVZ=ePFOz8XVH*W+7-{^jO)cy9b`4=Wg4+nCTA!q_-@dj{s
zL3fP9+yDIAJwV%0y?GoNPw;Q|0PR`z=7O+68(Y0OAZ*a?S8p~58?;5%n+3uK?WOf*
z0<%FoZka(1k8UUMX)B<vk7LYX{=Q03I}Lo!(@mewvmOWEGJEvaGI|_*&f?K)V&THS
z9W-Jl04_vb_}52%aP7R~!oNKNe0WCWC)dtf?!7W1pk4If9ms)STp2Hec;KDKf!|yi
zZ-G>UcN|ClfbzgQjU#_SRf2aI2mXQbz&ncr|G6^Wa%H^WVflf-734sV?{_^IK}VLo
ze0dUmJ_dBWpR3^k(4JOshta{Km$hU)I5?rFWe`)T2)OdEKLjerqYu~Z097hJkVDIS
zpgZtA8Bg=eGZ0;$+$@FnmO$5$!|Ee&e+g0vqPX|Ty20sQP<@7D|B3==eSstR{2rA3
z_n<TensIpo>SKcg6luR8@%^XK{r3T*`|q27vXj35o?!n>7rB3iYyUkg8Q%r<(ICk<
zJ{EM|DoN*~jqbMx9VNgtV)onHtOPa8p`+H|^=?Cbzr7HwzXqDWsa*l`9(3LURQ|g%
zJ4v`QJBhe5I|;ZlJMp+OJ8`%&JF&Qe7CSg`fHu1ObY2AQf8GrqFYI<?0j+R*&B5%*
z0oo{tw%^{7@c?Lox&8*E0!Cj3#Old-=w&`+@DbAf#OR+5$bS2_<)C1J#`@@f8N&Nz
zN|zx8*a+M&Gj%D={XaPN%Rt(DM##M#(0tC;B_RJp%aLw33CQ^r2fE!v_}4p&I5HmS
zb`#)V4?3ITK(`wY=;Sf57zh7)XAUrng@3&>=qToHHt?Agkb{;%t9#;O4|{-)qxj&{
zdA_cHf=joAOLqW=NAr6Q7yk8<pkpII>kAY>WsgheU6<|%(EftRCvLqlvJ9XeNOu6_
zJPJ@xr8@$297W^@2pe=7MI^X)(;e^wWY7<YddOK6(EdvEfA)IldNPc{3$n-f<#+V{
z3+PZrQ2(VHyx+In#-o>Y>tdwv!C%IL`Yne+TXw<wb-||~p03*l>u-R|ThQ)%oaHTe
z5gESn7Sw%#kAHysFFxI%O2Gxmy{d!Ny?FXBqx<gzM)%*3?!PB+9y550`{@3A@M+hj
z^xuE~W-h2AfVM1$Uw=Xu>^*2ZV6;Ec{F5ELKgMhhQml{mCkXc^RA(av*a+-TxXz-v
z{|9w{B6TLn|Il(|v_BC9y4(i2eV#f4DSU=Nf8y%&LF(So{sgGM9Qb5(KmO=>UY0jX
zN6+&D-!C(C_T$f)1S(jO`xC=$KR#$^3cL&eG+%LcBFMYYb^)k=;mhn~;LGf!;mho#
z;LGeJ;mhnK;LGg9;R~6s0BwXvnXmBZcH{u>$$!n^!R!cH1p(TZkGUToI&X0S`@98c
z`|?ZBI2!2wAy>l#pj%y_S4M*8D+YQ${;>(5V1lNK(f#;1`Wwjm%eV9+hZtl}{pfyt
z1_s#pFz9??<nUV3N9XVwBKz^N%#Y-G^s-Lv1qBzh-16vl18q?S9guOrquWixgMYoV
z2519mw;O1ytFr=x4cZRtECFGIw#+&UK-i$IwV<;x4tR94fp(vQMV$m-n@$n4C5`;@
z3_jfwKHUKVp!pIX{`HbR{Obcj2V{abA^UXR_34fP9h4Dy!VffG;>&p1r#k?0K87#j
zEuZcP(D4|N4<KyN=@^kOAZj3oV?fxDvoU-bZ~205FUCDz!Uml$d5&Yg#0P2qp|uAo
zyzrOt0>1p~4}(09b-n~z-h*aL2$c8Wc@uo)J@S1kph^kZy<fWrse1|aZ{YixZ$b7m
zkM6HWJ{JbGQ+{-R{pkLBJoj6AbhD4{uLm6<1zI8sn@{n;x4#~8zdC4_g>Sb5hi7l#
z{}NUBeDr620S3^WD4+QwKwG#!^9wS7?=JlHzx2uH!)X(c?nB{k2c011(aSoc4OI9-
zTf3hRf94l(l=$q(AK@VJnP1RR0>l>q^F=^>5fEPh%ohOh1wecrFrNp+=K=9Kz<dr6
zp992a0rOcve3sAr0*oLo!)Ja$r0Z1p`#>E6kozGwkQ`F@%pc+O0CY9VXMRD42cP)`
z9G-xLo`ASdK-?D~?h6q21&I3w#C-$ez5#JRfVdw(+z%k`7ZCRgi2DV^{Q=_s0C9hS
zxPL(0KOipnjuZa=V(2PxpH7T*3!nxA<H46Z{{8<yA&vh%wD;oM%>cgh9=st268r}}
znt%K+1#gJ?%pU>rF9T$k4r0A!FzA32@b$<Z-Ci8N;Op+4px508{x4Da?8q;`1d32k
z##^8HBS9D4z>I>$>z(Ms2=mhT-=Fk_n#ToNNC8PBj{i%P!0XLGfe+fT^VyL<lF5hh
zrZ3|mkRw0yN1OoNx9lYFnLh#)Z5*H@@Ld={=Wl>F{9Azc?*xG_aQ5i-67cMf5CAO%
z1zoiaPJ%{|`wl?vWrn!-H`oqO#!n!3dobQaclQ<0eM#Y<4HH%#-9_NLM?j~u`+zT7
zR%T>i@BtmKf5W5mqetg2-_BDo_cI~VM<nQCYVg_>a58b^j|8QY2oM2DF-}iD^G7;9
z0l5U6ctC_8h!Ajk0g`zEmI0+B2Y5PidIOSq1C{|LDF=9xa{2(0`2dyyr7j0}>T>!5
zlKBFb0VOmCctUgf0h0LvmI0+X2Y8xu`U8^r1C{|LKL_OG2fCpHd*7KAemcJ=^niX&
zMh1q@`~vKto18!MN3wn9k7NdAFc2Zg%-`~o0W9y%0=m-qGk>HT%V+*bXK<DTlY-7H
z{4GbIia_ze3{u1aQUuP&&LC3InS;M&K2#CtA~294Zag4G;LPs~A_bj!O6orI3%G+%
z^aq(D08#)hEu2B5ptC?pEJy+Pcz=)r5s(6K@!||31)W7oY(NUYYkxorBtQzl<&iUp
z6m*s-kp?M{0ZD=gXBm)Z!K5JgI)KAS=aGa3gK`Aq0&>u`6CR+u?m^exL<xX$t8cf1
zK#3|WQ-BgFC|`imtRsIUvoGUec;>hbO6{=B0Y29cRC+Rm1@FdoJ+ukvdg#M`kn5pk
z5Z6QdK+d}dm2$A_#z5T((D5#ybih>l-ltpGqni!nBPLMcZHRUqGSZCzTcYC*LsYk(
zgsZQZf_mQ=vip#(2Y|Z|bX~Lz6X?3=5Txs(gW>fFl6%1i#`ttIK#%_ixt9UtUS_C!
z!R4Dr=LN(S0T+<2jNS%zEl4fIwP4j1y`T%nknghs#a6H5KhW*fi2I{4?i&M#pC9PL
z0_c4OK9)B??qMo@4=TwF55V1z^C%nGePggFJ=}T{q_wW=^}#fx^aC21>K5>AJ&B{f
z{RFLVKSAo-PsG%>9`z{o?I(T#M}tqG`qtnRzo4T5h_3<WYk>F~Aie^auK?mJfcO$%
zz66Lb0pbgQ`2rxm0Eo{4=5v7f9H00F7(rZyPgv?(ko%$KsRQWL&rkdjP6s~m3pyP5
z#4q4*0>nK5;+_C;FMzlgK->!;?hO$428eqD#C-tbJ^*nafVeL}+!rA33lR4Mi2DJ=
z{Q%<r0C9hSxZtxp@zuAm!$$Gdw~*jRs&7B>M}YiGa((*=slNRLsc&IMVXbe2K?kmO
zg9;SLbz}VPr$8rl^|ChCB1JNyeg>KE42tbYClDFo03rp!q<}Lh)+3!jWP}5V6a<q3
z&Y;+jbOMnP4j@txObR%IQbD8>h>UOmk%C}Sz!{VpBAq~Fgae2a1d{^Jpi~j*1R^6G
zK%^j;6kz@YD)b;p#F1Z+0l7WF->3Hf|9|i)n2_tFPk#b8NWfRzfJZ?fsV36#z$g9)
zP^y6>9j6nY_#+)b=?9dE1VMy=(*=+iC=ofp6Oq#mkQgW>Ilxnr(*uwgC^<R6latd6
zkQgXUIl$AD(+7|kC}BCk6PD8tkQgX+IY3euXjp>3-yLUbjtxAx3Az>RrOm(p|3TRt
z(nbd5Bk*n0{O!vjQF@^oDN3Q|*?m3?ict@PPyCS}&w7HguqP-^1w1rhVxVm735rhv
z4+WSQC@Xt{;!?mv0wxB^&Yqxn6z~v$iGi}TCnydDJUC!tplt04ioZw(P`U?aYuNf$
z_<6wmeGZ`e(m(MFaG~aJusc0Kc^pItc!44c<a7^EJ_iv3UZ8ja3xT4^1C-ajK+yyi
z0>zRCD8GAwVhJn+iX;zEp7#Pp5?BZnM;@Sj?*)n@un;JUJV1Hh3lv3QAy5o?K=Xev
zz8C^uepmo%Z+k%Qa|AWJKk*B2fG0M*J$hL~szCb%Ss=#&ed3P*6{8W38X%Seh>!pg
z0w96|5@wO$i<V(|`!G`Y`F5VDTMpxc6nHkj0IiXB03~pcyFsZp0+d`MK<P6AlprG<
zz{&83XY&vC`qS7OZfu|%9KAuCHBjmoCk~HpE)4%HsT`XA0oC95`X8Xm2-N@ZVY~@0
zb)fx^Pw@W7C;kXf`X;yk0m_ZA{s-6sPsUH6a@>RQCMYVA>u0?E4;38!4^Zic$WI3y
zAO}(&Z~&D$2S65ria;#oAgF5sPCKAnhEf`WWU!ZsAQ|i>BS;2&`3RE1UP^*wz=;%;
z5kbjS09IClWROZs&{^92{ld8OBi0VcCuj%c6MrPzC;muKoe}{eU>%T8`~vQv?8@|s
zKhh0Ul!0rb2rvomTYx$sAVr|A12aews0;*GWf5Rf&{+V|0Rbrj^$u7-ia>=YxE_oE
zlc3%~9Y_KAs7sInP>Bn!KqJ7UptC|rEJy+P%uA30P%#azc_YB2ptDAa4M+j_@Jo;a
zP}vTyvLnExptC`VG)RF3ND@RiTY&0LFewN=8xyHNPE`K`mMK7q6jT+1(kxQ{1DrX)
z{SR2?ptS!1YW1P_KR}5W-v0o3hzXQgi0psB)zhZ`0d_B1{{!S+c>e=rKe)XI>3@KV
zYYrbvT>THYYI6G@VE3T)KS1tbDt!-%EK>R(uqZv;dJ?3Sxc-MCynl0B12oujThoW}
z;=O~nEnscb7oVZyH;}drDC4o0r+f6W<`ko}VHiFizMYxicsnEE-oe|I3AZx?9B*d?
zfY<@IGaVdnXE=b^4!1K69B*eBfY=7NGZh?fXDEQ!3b!)_9B*d`fY<`JH63qj+&g&N
z66uEIjtRFlAf@H229M?!4Y#uz?j5{c(QrFs!tJaHAm)VI84GS_EdVhW+|Jl=J8J`o
zx#4!kf!kRJK+FTTGcMfDx&UHcxSjFfcGd$B^TF+m54W>EfS4aZ<yHN3>~$_Xbgb?V
z_}p(71_qCAuAA?`tp?C-&~-&fwJdmi>2@Y4Br-ukkO}g8Cdkv7Am3(!ys3E))NJ4Y
zd(`4EzdVCS=Lt}IVJ)n^0P-)WweSMu(F~9mGeDlp0C_6|<e?0ZS294J$oK$iE!;bZ
ztG&PuYA*z0v=_L1yBVODDc^ioB6wR9Qk{bPKKBknMjH|CBQU<G;CNdLlz==LZ-LU#
z&3h*yT4CwvK{R+)5Yd0Z?C-3CG>(G{krEa{z2oid1jpN13HMGy5}D)eiUh~o*#VBX
zvjV_k0rw6%-mVC6yq)dfcst7hEam_fb8x(!ZQyu2%K$8902VWFyq&G!csol0ET#Y!
zQ*gYUE#P=NO8_h;02UK)yshncTMHzj0TQr?hUN$UJ~y=f3@89Vy%|sneF;gWnGN?&
z-p&BUU`502tO>U>CxG~%$gG%fJ8Qx1%mpAmC|)ZT+|Jr?J97hw4~pW74Y#un+|E1z
z;)7zl;=t{!3%4^bfcT(@uefkK>%r~J2OvHu4OBe1o%P{%<_8cTlA0m?70^&P&J=wZ
za`^wt8gPGw$)_9Cg!B>sCB2{Q<pLhPtk3e1A_J*QFpYtM;kFiXj=X{FQ4k02OArU{
zMGyz>KM)7*IS>c#GY|*vEf5FdCvXmJ$LSwX>mGE|Xur+>|Nrmac+GV82IvBJ@c0@i
z)!aA<$(5C$f+_&S17*)jP*LRo;(_vMC8)460P#Q>wh~laDS&vOoLdPhumnInP!_Hf
z0F_fGZ)-xzs&4RUJ)j|NX!zB7^s*kyLkhpUH<0Rcn!BeHdb>P-UmmFcHaKJJ<t12o
z3ckSCi33`u7JBruuF3_49dxP21W?`wh1tE6plp~0in9PH8x&&>P&O#O44`aKY$-t5
zkm?1jR|_0%;PO`hQb>WyU!Tr{KAjgpm+$sffx}A!a^1v>29M^K4Yxr#`QAZLbpy)7
zAQmL|f>@Az3t~ZXEQkfks~{F6mx5TJ{0Z8G4{}ode4MEmJcRHK94<)bD?|IMw>6+4
zWbe_-x*`Xu)`28#d=<_;(AXo)%h38}Gp*{IaE$r}RJd@VxSwMPx!<>20yKo%dJ=gq
z?B=@?1?cz<topp^cv}nF7X`(0>2uIwJ<w!^JRTe#2C4x)y9v&R=|Seh9B*qw>et_n
zx3xSOKixZdThoIPqn^D1nhOK1$HX-s#)6|iid;UtZ18LbrTZ6<bnghN!jOx1a6RUD
zI|EB?=6E{;OP%I;I|ED2=6E{;Oa10}I|EBC=Xg5<OI_!9I|Hf41Jw@v{l+-^o9r0<
zP0)naZGF&m*KNIfCvR(ms(Ect`C`rAa+ZMsG-}6mJ73^-p1{46x3j_Rf^2ZRpjv>x
zWer3D^X+_v+j$Bg1>nX+Hn=fSt-#;X4N<^yJKx}To&iV!xCN38Zh=%Al;nYKQMjG&
za68WdBnfV^WP_V5)ea?rpsN&a=Lg)*3jj%i+c??aHcoXwi3zCTc{@Mhc3uKV65J@t
zP5?Q)I-x}Tc7DO_yaJF!0mwty1z?E+P|85Gr{L?6z*7?78D5|6DCmT-<NurQN)#bU
z+Jh04q`@i9@wPT}CJUUj!B;Fmk~X*>iFQ8~N%L7=kolq88j#*3Xng@}J`3FZ0?iMB
z=CeSYgSRd4^d=$mLm;)SC!wk<X1qQ}-uzV{ynh6DAGr4javyB|3S6Cl+y|PI0&x!B
zwt(~=p*}$FJ?@AG&9#A4f?Nmc=2%ore0?EpLa*b$o9|F(tK8srdZErxfxLCH^!>eq
z#Pkn$L9e!kMAYHdllKnR&3SzkRG4ATN14F=3z``N6*!;;2%z~x(Aox;&-@XNEIy1E
zLCYIhU`_k0pf(l*QvZ;@{R5;a?~w+o!BN(O7=R`i9SlJ0Hw-}QIZVKO6A<47#Mc1x
zH9&j~5MKw(*8%Z$Kzs!-Ujf8d0P#WV8X_E2KztPtA2hRzyxs&nrRyLAl9vI=gXWGS
z91!bGKvTsL4v6(Apc(222hhR=NAP+R&}4Lk1AILSV!a8-F!0Q`17tA@qO;21_x<1h
z|Df=Lw2u!tfR=<D08MXz!tDSkB#(fEj)1sFK-?1`?g<e01c-YE#61Jzo&j+$fVdYx
z+zTM?6%h9dh<gRZy#eCh0C8`CxOYI@J0R{I5cdIy`vAnH_qvzg|Nj5S-o}B=!(I6M
z|35svfd;NUy1Do@PJqg`@&b=uR?QTo=FMmR2u}l0`ZEEsG(apJ5DT=p$592uk^qUx
zfLNflCypW@76(X-=QDo<Cy2oUnv{Xe(?)=!4HVA~Ea09gv^~@WYY%~x!N%)9^G7&<
zV$1^+PY$5i@c_k%11KguK;iEI3Uv=qSc8^?M0kMLfq<5Lcz{=TfEIFifY)sN0rk}D
z7vl&QP(S@2xZ&r(00|E!-`11h^+2Bg`87_IC?LvjkLH(*AUA^C2FZ#)|CheP=|Kih
z=+dx~5=eW(qnqh7zW^wYC4hs4U*jq$$$sV+h+yH@IPsZ3@-?XC@|i#K!e{=-GoSe*
zAM<M*{mdV6@H2l5$m5^@i~waM5JM1jhJH5>g9jrI6KGoBqxpwK={uO6rIQX%c%2As
z!GdfBDFLmO_{=X5$-=L36>8yUet`tgS{AU4pq><_t&X5FND!2rLD^2wquGgr!=u?r
zfWxB`zBr<E>fy8rVZk2FZ#4KdO;q?bYg9lJ@4mf(|M^>1GcbU{_M1mH`0O0e6hpTI
z2fxNY@baJ=@bm}@4A16QjGy@hG{Mdj2ml2$zsA$g{E@G~4)*~qMT&gj+5GGOXa303
zpZOziA%f`fXZ{FK<o_w%>dU|WrZ4~c6P}Ep{d!rreLAIlIzf$L@ER$L&-@VuAir3A
z<`*nr;ny%x;n%295%6d}q7e-`-|_u7evN;xFT%o-zhyDV2NNLi7XexX#{i0TevKFW
z8jnBo3j~0KKx=LuLF4b`Xa2}T5C_J9*0Uvmg7DyHegO`Cjf<egDEu0CKl4X|7At`Q
z{^n=?$Rqq3XFu~tochck11eM)KJ!O-fOH-H%r6LH2r?KR@I;Mn1w?f7w}Mt^gL4%k
zy@K5D(dz{oPXEu}G8a@qfK%Xr`2bQyg9ms$EDs_UnDDnI|NsC0FiPr4<A47a<N?p-
zpa1zazVf$#u5iSRfd~8=zma3$7c>SQB4R)Q<lmU*kbDG=0mB3Q8lXh~_%naxPiS^K
z%&!3|WkBH%DmGqz=8yP}7T!qNi@&w-KX}3!R04v^$P7?=0@bk@sObrLJyWnp@<ESY
znM3GnWcXV^!zF2;^ws<ml=?x{paV-?K57#Lv^-A=L<F($YrN*yc=VY+5|q#$eCCfl
z^_f5N@MnHdVv9J)uW`2Yghw|sysY}nF9<1i@wDNZq7Qp?GlLh>fJ$(12?No@-vOH6
zeSLTWy8F>q9`U!dL6R7XC(1#dfRuke$m@>;K+Oh$0J6P;l$Ja#4<V-|&{zT<&-niT
z|Nr$tP=5_Qy?yI-{Kv0>x_*hjr3sYx!Q;!2wjn4NgQ|HJ{=Pnte|w!cp#4#wZfNTh
zw4O<T_^A5KAMqDdbfL#i{RdbEC~bkZC_nQ@;48f#3!#334CC*!1bK8d%6v5!mi5Po
z_9tj&1l0b7OtK3yfY$neX51Y)d>Ai+miurJZhvybptL_h>zNWjQ#K9>p!G}%Abtjz
zp8?`$fcODmegKFc0OCi0`4J#~1c>hd<~xA+4j{e<nC}7Ndw}?$6&s+nII#6s;2Av!
z3y{18NFKCO1GM&rU(gY}{tC331GGkmUl6p$K)?~SLIbqchF{PTv~I)^w2A|?CI_^B
z8Z^5HvJNyq#RxJCv~&Zs0Eb`DkpsQ`2?{?*`x7)C{h|T1OsWACZVjN2>;Q2)K->-x
zcLInz0mPjE;?4kZXMngfK->i&?g9{Z0f@T-#9aa6t^jd2fVdk#+zlY^4iI+-h`R&C
z1uf<om~~*d+n=zx9Bl2+G*|;P-=mlHMI=%K^b>!CX98&5M+S%$0AfXeSPmeT2Z&_=
zVp)J#;FThvH6xzjl_H=uBb*>f4p2=EnW%%r8)$`s0|#jQ5!(K2hP6LIsvzx8aNIe7
zV$1^+PY$5i@c_k%11KguK;iEI3U$yboCwg0fC$h^8_2p6&}tgUx)KlYls#l!36AzB
zc%JA#uJ$J=WJ=`W?ITe86XZtFS{6uFgtb56qM!H$5&naf9wp_F^4FuA=@Y*IXiZ`Q
zI8@U3HLilv>?eMK2#|mP$i7efk)S0+uRrlep83Qd`8bVV<LD>;m@A+7BMyGzj{pU(
z1IP-{;wA?Uj5Y~U9a-9s)*gAC0&S0iT;b7t0F>K6nJSV4>XL*XpcW|96(ARYT!Q2Z
zkPE;raRe1hf}k7@atgRfDgbJd3LrO0C!w#`$JIVv2QJ~?qqR@d;0;tn`Ve3MwNF3s
z3uu1g7YG138??4E5)>I}{2EU`@khS;#2<Ouhw&z;h5Cs<612|h79<G4j(_}#KLV60
z{*-RQ-9-Jw9|20z1t7nHim?I?Y)w><`#_@@sO>#)bE#zo$VZ^|1UPCzaSX}@Y5W?X
z=mah83IMGv1;_a({>Vq4_#<C_;*UH8a{DL#m^YvJ1rk6Zd=Ruu3)Eaq<JY*G#;<Yl
z6My6zXac$Ui9hm48o$QbPy7+5KJmwZmX(2)w1JkoMI8Rb52`){JunjpN~1Lj)a-+&
zZ%}$gv{x5_Dpzod1uZHP0JpdY!UvFs2DoNNYqZ9JT#sD8BKLlf+plTh2J95<9{Qce
zuK`+shY}^fKJiCBL_~=IC<tPnL-L>i2WSjR;}0}K9)IGG{0WVe!)g2)XP^-RS{3y2
z6M<H24zv~fi9Z5VlxBdE9B3J225ORn<RtX=A1J;c>1_fmy*2*?WoS_1a^R?|2Q~c=
zjUv$UE-4TZ1j;zC)A%)D2@jM@PJQB!JPb*E5eGr(s`RKwH#26z2J$=fz7Ev&;fU4s
z{H;a*LD#B-+q0M^@OL<aT1MLlw`V&cF^1x)Dv+lj<td^)3-T4H*#IdM$n_dhN<(YX
zmgD!27sx*cCtz#Of=UULAx{1l&|%X^?O9MB2Q?cw`1>Y;{EMwU3-TXHQTK^I;xDME
z!_%Z~gf?jjly;D{H9tXy@%Nd7Jh~cI9%CO*)q$5Mu=O>d#WlAx1a4;vKvvpR2*BF0
zcRwTd&rrrw--E+~wIUFuJ$rlQ0R{#J$J;AF)V+hZcY^5KD=$C<K@><3MBiSy03ryY
zK!PCp_R0+qK@bHJ1ktxwg1Uc>w^x8DkRXV@y%LnC9B;1xQ6NDOjk?^Y!0~oQ0ciP7
z0qSxe$UN=A+m!*R%Y7j8v<Gij8o-zPAg=*BJOOF3!4J@S-P;=A)@<V;21W)34^|L)
zdlkd~|NrkDyuAZN-(Df`|NsBnt3V`33`E~vp#T;GksvV;eS3ugSPVph#6a}z6`(cF
zw^xBkkQj)*y&?dt4n%^)K=kbu31Bf02@(U*w^tN^#XuxT3`F0~pxp{3{{D|RM^-tY
ztCWuY{r?}Fs}S`uc)ik1@U=Mn?e&oK<l&FhzJ;Wwdxszi=-xp{ngQ`a=>o(DB?S;4
z6#MrMg65kK-OdC>dZxp@L$@I_&k7(GXyt?^h#>%;We2TtI&|~oZ41Z>uL=P~dzZg2
z`#;F34h*39eZc{V*n5W{k$LYRBmzNvP&9$~pr`@yLD2!?gQ5V$2L(H5lD*;HA<)F+
zLC`$pA<(qrLC`GYA<(4aLC_rHq1*7~Qa#v*VL3p<uvfs%VAT0{*m^0?|0Vi2-`zX_
z%F-_xLH0rN@X!DE4nl@tZ)@B`^)N{J>!--`zp(nMBob17dvr71*0`Mk+6&2XTjS;-
z(4rTCo2Nh{NH<R3JbmNTy_b*~oO`E0-UKZ`slY$zx)$Yr&DWsWB+%ASkgE?UfR?>!
zf^EqJ+u|hvw*|bO1#Am=rCKGZG0UL<YSAhnw`ezjViA$P!h%6V)u27Zr8nQ94zAuj
z02y1otqE$df=j-eNM7^-9r5$)Kg|AnM?rSqJ6L)FccT<Ne52zIgG2Z+!aeZtEyEMO
zpwPW}_{Pb5uWp{YclzdO(6r`ljhhE<oW7j_4i+Z~n6rooe5BT7=>$kC1=T&U_GC#O
zczg{rzA17Kq{dbNjjf}!4NIqhVhXfu<R$p9-J1tWQpmI4@Bl0{V3CA-P_lF$sI873
zQJ}?hpei49o(=Z#$C3hgd^P`M1P4)FJgAw2XuCPy)&fNlXr<oG12@jxJbmxXJrH^5
z-mB7^9^K67mKq-5muJA$J}aFD9iBti#ov($s^AYn$J5Z;n`q;WC25cWIf#R!Ar3~G
zA%-|OLx3m;dvsoy;L*$gj!KlqSLrOAjs<Nqe|-#*-fq4F%_tuLH@99h-8>1;4@sEe
zn+|d=ND=NZK6CH%y)!pY-aCBnVd?dIhe1=%s3D3pKDY$hm_iTH!#7XgJ9zVC>&bhE
z`1`W{|NnpU<m(+s?I%#T5LAeCOZavNK+YooEq;Ndmj+7)#~q9e3=F004HgWJ{8JBr
zMh9Iw7<?FS`hd>6`Sri_Hh8fzL_O$!XHanmnoZ<y2lwB4Maw<F6<(JQ<DvhL8Y<Wr
zc0o<7WMkl;dZ;6it)YSyA;=05WNoNmK?t%y1X&s?m=S`^5JBdK3MPag6GV`yp@I=1
z$OsW+Y_Nceu{BtNg#@Dy^Y{5d7q579o`T<!CUY0GG1#wHL;~b-SQuD=!@#8jY&tY#
zI2x)Lp~6m#Ag3V2nPB2fAa^6gnPKA0AWtI1SzzKUpb$Zbv%<t#LBWR*XM>5eHB_*}
zVv3`oiXAKtDwA9~oY*~@4}n(G^S2s-x_aMl`!L@0?d7@oG8|mnqO2eB=w^b94}11{
z{x8vXH9X+jdC-N60}}Hu8NqS>^MC0}*OrqW-9a2BeBhAjU^)!qrA^@9#?*44^mPXl
zsK{|)U;rHt0AA$+Uhm>00KUsA0(4M<0QlGey#`B$5+26}E12Wal9>nNM^DCEK8!a!
znt%N-y#!wHg1p}tyxt0I0qBG-NUD1UX=W+9AvN1!>Aj(n4QyW(8w1$kr5ui+5apkG
zz_G)Dt)Y??BFl;-3rdb4S=NS17Kkhhk}N1)f@E15Dw!d&%t*4J1PYR6Zm48}$TA_x
zf>J6-mZ_nV5hBZoBnwKiAX!FG5OITo2;yRP#|8@qu!9*uYm4~%*r2Hwyvy^FPv?1$
zgYTI=dQJX<60k?Fj3L+nP!R8i<~wjsKJ3yV0kIgIej#!kpj_j~KlQLnM+76p(G68h
z432PFaEb=WGC@4tP{oWS3r^P{S!PIJHB_-6$%0ciNR|Z>&<$0rNV4EG4w7YsL{dW)
z8<H$IrGsSI8Y<ZtN_fC&9PTP`dOz&Ze2~MXBLbY>L22K^@+N;PXk^vn`+ZNwPo9h)
zd_gzTUjsMO;pG(<XfhhIzz}rNE$CQ*5(`(u1CBdEp#=&%4p88`^1B{{EY-j1$#@HN
zu0ZKy*Omhw-9Z8+yx^GWU;<SWK?0CG@CL-4067m0oIt@Ra72Mxni8Jf8lK%1;Ih`U
zy8v_;heU}hxaR<}P8wugiKt_PH7rvI!27eHvItQKdoaHAWc=mH_}K%RK@Na!!9?!Q
z!tUqf^68G^@aQfQ@aPT#ZN6gXZx;pi=z3YDoWX@NWas4saL{u*HdM1Q@VE9eF))B)
zfq&|O4kt+F5OQp&W@RYhZm5H05q3~4f>l5=2uKABSOqMbu!B+oSOp}LfQ)Bm;BN(W
zY(U8eECtCS?2Zl9Obn%wpfm>-hGY$pFe5{$5h$U8g~5437!*P!ybX5HOvA}9&(L56
z${HO^pm1=EIXt1E4wj`(fhPPI8tPyfaPjL|AoX?7?8@I-@&Et-m!QEg{=VDLuAWEd
z1<%e;zMW@$J8yU%e8cS3tMe3+scbYM^*J=YEEquXWyJtVkOGMI06422hGsNjM^Nqp
z6?avPP^Ii35&o%%VYv;Y1YS}=Ok)RCDPSd#EGOd#s!KrjRWU<NK}sJLpd#mRM+77T
zf{cR~T5#h)W!B-22uLoJbp%y4C1Q@Cc!VesL~?%xsQ5eF5dq1RAoJh_C`2(kr2IVG
z5dq1WAoJK6z~-?-orhu`I|Khza8B)rVE1f3z~R|^2)Y{JCx7c&P{4n`<H`8igYlhz
zFV8~{##b+Wk@9Op9kk%)Z_WJs|NqNa&|)T}@z-zy3oJ`KTn$g|2W4zT{PBVF8wV&g
zx$wK52W4^(#+#mupP;KQOK(9cJBbp(9Uz_H)CH>VBw+R33y2WEJm|a~kK}``Cp~&i
z4#DR5!J7E}4|>e-=(RZnZxQB!=bs_x?ecFEsFMXX2VGk(m2mrX3xJ&D$UpTEs2KCH
zyixkxwdImWw;b50QcjO<P&En43CxBET2EH2hL;bhtwY3kXz4UiU6D2cRA1tEU*`#*
zUgWbxKod62KN(&4w=uw+cmU)?22eEwX%-v+oqqyy;sGp9Y(3e*?9q9lVjZ}A^Jr#Z
zg!l=0dFC9D<G}L4hPPqC1`nuENE_b;6iCT<1IdNsGXK=Wh6fPo7iV~^_DDY2a@(Vu
z<<u@voR+eIbLycEf#|~!Q(8~*cYto{eZ2vB{Gj=lIDdaTBLhS8Pe%ThPYfUiQ%R;r
z@<GpLn}ZDeEx#EU7(iOnK&5N)C0}bs{?-&m(3<9h9EJy8b9pu&<nXn2{87r@e1OsN
zVC{RCUPnep%LDu^f?!jbcQ7z8F!1}I@aSc=cjILMHR^jsCVF(UTmbbaJ-ZoQ4R3q2
z9w-rVHN5R<c>q*byY<S<Wno}o@a+!dFg)PfdZ|Rn*Yd&+P)X&uiwQK^$nSE<h4F@O
zccg%;;U(YJ+a<!jmNy*1K6eB!7<T1%z3kZQ!t}5C2TOUBNAe|)89u!tlYAI2`1Fcy
z_v2;o>}ELxvX<-fVP8u|kK{`w?r=}Hiv9opzw^Xv-n0pZ2bzB}dn8}t_X8()kqI8X
ztQFq83^4bDmcJxlf`nD;{eS=ezdr8ST*<*uy2+!Ll|Klg5M<9H(DGIXhUTBh0ix%D
z8XzG14jUfuNWS!P>%ag14G+9r2Rd96sXTBDcMNk3h1P=2Z!B6bd3K(4>1<H}ji&i@
z_NdGNg?1lk`mfjNzen;XpWZ@7kLGubhHrhkRihLI89H55bUb=%7@1z%^2;-Lc7AZ_
z{N>a6@kP~7ZU&Fm1N^NIK{4Ikq5?9>slmpAfxqP=C@POKdNv;eo8@WwuOz~ke_!2y
z*Vg}aTrQnI9sgfxJy5#IvH8DV$xX-R{|Y6SJ-S&Rs|Yf9^omB<@G`h|{_yDLc;S1I
zi($uqP^-Q9hy|ohbBuM2bBsUS>-697Ey!)%5WjSXsOT`hXuagp8}OgMLk+auAo<X1
z!{(m~C04Gjm-ssxz|P#G0vdz%Og`n<{EE?~gNMKQ6{BbK3&!SO|M^=$>xZ5B_xZ3g
zH2>6d>^xa|u=%H6>D}gEjQo9xj0_CU4K=L)_4r#uq3nNp{H>mh3=EFVhZviGG4Z$5
zfH?g7d>NX5DmZqY<Zsai1;kH1{uU)h1_qEb`Yb^rub5m74;Y?&tv$h=e_sqMqhs@L
zJ=e~gklf?g{9A#)<s*0%{{cov%TxR<pxqN5-4M4oA7r#V<<`N&UV7Nk@)CdFqksSZ
zgFNGte8^Grl27MB59S`QC%t<^1Q<P-r+_)0o!7zT%P~d<kLH7no|flJzr0)y)(Z0Z
zT<}&r)+A+c1e~`9r9+Mv{pYzD3=h0)fJnMRB(tpGv9ta>G<IIbLX;>$lsvbDE9rqN
zv4SZ1uLQQ@j1|O+9Jss`ME*WR{tHx|2QL5XFKDqD>wbv*7N`?-;PSWr{{L@y>E#R1
zs6C?mLrec2{F)^y2B4N`=Q+=A2MM2UCEsofkM1lE-|hkqkM1e~-)_)gXq1FUr;Cb4
ziJv3?b{-X9#y>BNwK*90xBD{iYkcrw{Q5!#%;o>gANj$D@%;-?Fqa#|eZi^C0b03u
z?8O2N4u-T&W)J2V6%A09D&54dQKDkt(R{=MB`G79uPC|I0OVQ)h-*E%wS2n`Ji4nm
ze7iF^KnKnFb|(mwScBXIa?oTgko)+-&U^o&70iRUr&0^*9s!7Zd>9{tU2_!V8U>H$
zBL)c99EO(^sCHZVb}NAHeDv(j;3(1N-_GyD`22+e#1eju4=+SvcC1l{_?huF*p91c
zb{s~F4-2pleUe}LcAoL<yzbNa&hy|?X5ZE)y>9<}I*<DGnrM0S)*KQjDT9uOd3Lk&
zZ|8WiRFi|D`5z;{#)rBh&)#?rc>V9u&Fs;9m;<DyQImtg!}2#MPD)>RceChwcFTdp
zGc}>%!2oe9==k=KqYR#mBF8;Ib<(lg_nysf7=2rxlum>>AGPf9>~`mX8YTlXY_l2%
zL+iJ+PUgz>Al<J)M|im~FrfK20_0x@P&XYk&eCn<(_O{k(_JLs)14*3-?y2C0dxlA
z51-E0KAm5EI{$+bp@ql67tA1r2FP_D2OqHb^s2Cd1Ps9U*YmxYp#h8f7rkJnF9XQa
zFB-rcNFpfFfO?u+4IDxI+x?hc#Df+1Gl60-7|ix%0_$`GbG#uOOPJORsvxb-O#IvZ
zSY9ZDmH4xO^ooPozMvEJKD^)pbG#v(zv@tHr$F?w@Nf5Hd+}Ty<Y0d`klx#1wlC<=
zzYj0YfjQm~&Ow;o2#8)b{_TDoFIIz<_;Y~t&Ihx7L932GyqE;$ctbd?FugJmy&U}8
z{kUG_gO&Jmf%GPW*}hz0|Av7%-Vlx_Oz#5~uz$JuxBKzDFa|5}=K<+e2eW-ahX;Om
zAqD1mgE=0}#{@i@j|+G-9~JOuJ}mI!uNut%5VQX9Z}<E6;<*~w|NlT{-3GIL|AF0c
z4$Sd}a1O%sMnLrb^Rax!-^vXxCS6oCJi0?vEIhv70IjC==yp*t@MJvh$#~3@@u)}Z
z?NV`2%60H)J`#b*+>Y^wCxFYd7inr7437NUL8ZluC<vPm>;PW~2bzHFVJ^6)%)#K%
z{F^b&vD1~IWQimHb{`d{7YY!?kn|%A;rKz)3@d~OO-|ocp`p+RF^36c4ikS%#Q*>Q
z!Dg|%xS|Sn5hOhwhj9ELX=o>e2Tfk9VP-i&%wh(a#lqjh12c>5MF&I!Bz;vwIDU{c
zl?&lPlUqE@tZzzS|FM9~V&iW)0IC;3e&l#z1JM9UZ~739A0&+_LU_>RCk!)d6~ru7
zkXao3EhR9sxL$lvf%p-e{vJa(evmYG6~coi$Kxu{@QQ<&#Rf8qi@!w!W){zjB@hje
z^f(>D@dKy97o89uG<jCT%o2i_#SSuyhri{{Uuf9#y#S>zNB-^pe4zB`4bklfNe{LV
zo-c%_4>RkSA_oJ=9KM%R|Nj5)+4<#V2e^;wfL`7~>RX>~B~TR$s<c2wAAfrrs4dpZ
zYHflvLJ8@Qf|CQ!i=)b*9O4VkZ9BniNCtbcMj0A3&LAgrI`e=vaJ`rUR^$r~+72)q
znwzU(8iXJkxWF1XUL=DR`GU)la4;KMba=ruJX8Q@e-5w)wiiZVMZVxdOAXA1mQ#{2
z4I3aD*uWZCUNC|c`GQNxuSy{QKnukeN>D%4Lo~2}H88!n09ND+E{>0Y+0YVrJ4}Ng
zL<18f7cT&-0XIorOaZeYWqk)sxja}oGpH!Q(&_-W2l@N5Ktm3_jz2s)-}`hv^Xxnh
zs#-KW558yi?JZ~YJot>ouUE$yHh#>%o$rMP*e-D4Aq!?gtQCY=yFwlmaLnK;=8q!C
z<B%fa1DFl<(_=+wAXI@>Lu-|@U?q@J;2@X{4YMsU<=znGkcwm;SP3MfPXe={ancG?
zE(1{xsXOw)N+5YT8O(;pc^FLjTRD)^ogvkQ16T>9x-bE=p=nATrhFenIi!XV1S^5$
zNLDZ#nr43}K)u=zQO?7^-H-3ZBL#5CfHU1SFxwlF%TB_SC&+<HrDFnVoz8rq+5}Xy
z_*lN?Z!L$_0iNIQ`!as<Vf^aX%k$&qf<OQNV`)EnbX$R&Zp}a0`P=y+Iq#tXQqJSw
z?$7fg7~%wQj&p~(;GQfvIC%KC`*Xc8gs1>#F;$p~JrEUK{M-FGUhqRyfb$eHOvNmS
z3J(75{%kMa%7Z-Z4bDUl<)Oh+0a3xmzulkZ#c7BNaIV=8QxOJH!NR}YpXtR)hzf8v
znF~{40#U)lzn%X@2Ur0&s5GmE$%}yH!C3*l$;;pO5S#@ve|U8M^8~d(-!c34<}rF6
ze9Ge2tD?=n9UA(_1YYQZjrRTkGFuU5_6`|vD1G4H?)T{hH$=rJkc$6uP#;c%sQARc
z-S5kbmvZ1R_ySUK7p9^FqT&nxcE4{gjzd&@1F6^zQxODF@r{4G-;WndAu4`=RLq2_
zFo3A|!N1+_*NbL|ieDfV<uDa|5EZ}pxBLBhkqA-o2c#ktrs9n>*e{TFiakUHxSe7Q
zQ*jES;-8P@WB%3$ppg51&xi57U$4(shL_X9)d14^6}0v*yuI(!dDf%zx^L$jP<!8_
z^{r#Ci^@MpbHC(}fJ^5CkKUL=93^EQkoNvoSq=ur=0D&De}zwPJqN5j^6X~!Y(5Td
z?@yHFVDPm34r<4gzVPa1(f94P1GV=nWudVk0CKrwC%Z@I4@7^VnE|qM(DHEUXOHH$
zj2^9TOS?cNCMcPpHv2ug-8rCUs>00NBgMhs+WI8Tv6H=WIY|HOef;vc{SU4W6+l}9
z4bu4E|MzV@>DhVRquU7Fy@GY^vIKm)3j|8+Kq`DXPxEi*^I?4UVv`Ig*?>x2P=|8~
zm<MU6fx3TFWI&#bJm%5-8ni$2N9jq=?sy6Q?c6V_z%miXUkFNpq85?`Kzsc#s|0>|
z2BfhfRJVQuyY;F^w~=SJ2BaIBz)@nJ#{d4CPv>cPc!Dwu<GUBEVCV7kYy1Fp6u(P@
z9d{h+xDTZ_J-cHCK#sc$mWep_qC^sp<B-m;0naBjzk#G9kmaCx)lP`BEK1ZsA|U7J
z!O{oVJ^x;mN`s10aL{}xeeKa5%K@@I9%lPD354w)(2*v{N*bKu@!uo)r!OcGU+Z=M
z=iB<$xATZcZ_Xisk}!{MHc+x-lICD&{tr&EMIOCzpe`!-{4RL^^q~}}fBG7dUO)3k
z{4+d|Ho>!7<cJ5O$T3h~&+<5Eb;Dam-`2OKt30}8{(;=QS_%}F5yxLRA-NeNIuE!0
z|I8opqkfHN^IOK(`*4hhG`{Hojs9tts6djW3%{m|ih~QkrjJU13%_QFN`ec&W{gS!
zC{#T_fh+}zct{ftbilnwFY691<cdU|fq%O<&kJ@b4hB%A!msh;#cxTFdn1p7_hW7M
z=6dl;5-iCDlDvm1$?@VWM3Ms}c@R~S?ZpO&BpXO_392N^i^&j47La5+swC5kGKeG-
zNHPmWlKVvzSPqm_U-%<SX&ifTUyOsnqdQa}jgbjlB7lS0g<k_4NE+Zk(f|jNMvO{<
zN8=GtXrgqt(kAfto&ER!zi)3MsB-b`e2&qs+RhEB+K&mmxF7)v8NUxM{2Di29G2i<
z038W_n18$Xr_cNm$H1a%Axglt%R(^Q8+3C2F;E#k5zP1d;=-?S0d!o!=NI)*GY;`@
z_x=Vo<HCzfh`Mhs{2C`-#6XoC<lpWMI^;j%5Lnn1qUMJSzs7+V7Em<@__uri0-1ae
zEUXAo^9vNHqF}Z+XhZ375T6yy_XE`}APqlWd=Urv4cxN@JN5~f@AnVnE6_I67njAM
z{`IkZ4Nfbq;9B|neILf}{=GbZUbcc~x=`9T4xrH#NYeG_yzJ9?4z!fVquUCU{hGx=
zaThJXukpd7`5!xfyAh=2qpkrOLKoTK!Fb{SgR}{tWcnf;<QR<~ptSp$Kl0xTcaU57
zBaXkgCju%LoT2R>xGGSe?cWPUn5rERRgg9iH(V8{m-z3+Z!u8%k2wBf5=0fG9rRR;
zgMlAxBdA~c@5NP^svL+aNLy$>TotG%{O`qjm?}4jDoA^1CR`P$@BQyZCrp(BL>0JA
zR02}89nw(GfG9Zj;=eG+d#E*n10n%~=3Dst_JJCky?LPYOQ3Ni0I~z@DbPI=|6VXa
z>^c5oI@lg(NCWAWD9r1ii#7hexFre=phAc$NF(V8ToovN|9i0orpg<l3er%T2UqnC
z9C3XxRjLqGkj7F4Tovdpi+?XNV5<HLf&A|bX)p!BRs8~+<pfi86QT;zXwreJ0;TnT
zFJxe<HbYcF8cu9*RiL4qe=oj?K>gSYQ3Yu{frc48!Hp-c-jc5jFGK$R{|_I3MM~R{
z;`bV8VGH=EJSkB6UMvC*MvvzI?ELMZsTYr4)@)U9+TH<4+mQYps5~x*SpR_^RQ_fm
zI2<ox5gfJ`0SFGu3ugp}>4h1b!~H@F%KpqB`JG?m*o$3)po|uVT1a{{AAu&M!~A`q
zVII&0be^4mK#K@GdvjD6Jq|u)@nF0=fge)-y|^L_E+0T8-G>*)Aso>86(3&gf^fcp
z3WXPIAso=|^bao<Ksdj^GLs=3&_yI4UbI0t|G+Yp!q9p);zQ{K&+m7<dTpM+JOW<&
z<-mZqJUQ#p%>)W-bC3z$#T*{p)sXV!FQPmVR{@9l3P_kw0FM>2gRBQ-1b@(o%)b}k
zg`m;jCjd%t?w}4J*NcZj;1~q;t-uNHB1}~VL=~u4$?;-0Tot4|Sq)R=1W^U*s<OS9
z3ReXwPg-HBWFV?Q{a=<B`EXT`@+2On>Ki}UU7$`i(+f|yDoA-^2~%|eqKXML2A~2`
zv>iPE@j?Qk;Mj}xU<K@mx)PBLK(ls`@+1{h4mZE$@aX)FS)S;D+H2rJ)WZTV4hTX6
z$Qx3gY!HM7qdV9hXn8UVt_o6~biq_9LR3M@lM=WpNO_V1Q}vq<<aK9AdEy6G1u0ML
zV5+V{R6)uU4Y(>uc_IN*wH~4hQl2ouRYA&=PXbWacS2M_%9A?+Fh4@dlQS??$q-eL
z@?;xa6{I{_22*7VQ3V+qMlMfszA|{UzUA)^`1}9=%WQCB2Q4>ZAXL79)4RI>C`-qI
zT45;Vi?<>;tz(og;t=OR$`>vKhvUUxez2!OGHfqCAUG^99wRtRFRsBk+%HZ+*|72@
ziWlS<O3RlLex&jx9m0W>FHsN<q<ry(a3JN21B3%9UyLCfNco}$;Xuk4Nq&6gO9-^b
z0+~;P6y?`Fx}_kk=t&F=3?99#LJG*OXi$-TgbyBYTrajGI2<olAvkO=<{~&OFD4*3
zOfQ<@9PSt8P_{>RJh<PJ4&fhr@sAsn_#q7d#6;j>{yxyQPS4)LAD*3G(2HzXiLJzk
z6r!RK4kSc5ARI`D{^kWMgM{ci2nQ0P4<Q^#h+ctkAR&4j6y=a+Ah^W#>*aa&@-%p5
zLojrM8feP`BnUw#>v;5vzLx_n<KyY_VLbK!5u(5I*^yrWbPrr4=pH!830)50Q#U||
zZ$*MnYXY$Z9Y7~?34l)MigW~>;{;*}I)IMt5&#{;73l~%%?ZR3bO4>rCEx%mjX`I1
zK~C**03F~Z06H)v5`0t;h$ZL%I;cwkG#3Zzl7lY{iarclV$FG|`4K;VYbyf-!wP=>
z)>`mX|4(-QJ}uBnht5Nuou_>}4}toz6CC+9m_e79dNv<Y@N7P;;L&_Y!I3}G=>dO)
z(*u4@rw5Mw8qOa;A|Lo8oIdbtI(-10z*~PDHecHOlEbI-lw<Qlc8`Ovm_3>gF?t+)
z#Old-!GrOl2jhj8+d(5ZprOG&(AqN(B+J3=2S<JZAx!%PoFDK<9^x19dcYrXkYB*-
z1HT~1B?2Iq2n2lq$weIG7lgWH_scTSshnW*pu68e#~gv8kYD2l|FPSk0}t8DMLc>%
zJ!L_$$O2g@4_+VEdB}tF6ezf$D<XcfgWY(-xARn8SlR?f@Fg0rI6RvVfWwAA@-)9d
z&;$O6Q~V%@2zotm<QMSx01}Qk#V_auIc*!XEdg7wK*9ukmM>@*#^=KmKJyEBf^P5v
z9l_-Rx=#>92zY{S{Q?Vtj&Sn;T`A}Zx+x4S1Uj6`19YpPC#d!Z3xN)D^8j5e=m|<T
zU?I@CG9I8qZahJCF<1z6d=BWCqeysiIXnTB#_J;BUIwKH4$zK7WdBBZJ>b^_c~k@H
zQLhjDnoysfhio>(NB~Gat^fD`KjQuna0`<QOZ@P+L$=0>9+gIlBk*;L0~tadumn<4
z0tzd5Nb&c9?#!V{`gr*kQJ;eB<nOx!>LY=&4k%eV@@tS5MXx6!$}7nEYoPm7PJ)as
z2c5TDA_Wd`$O>i9c^;r`>Y#I5B0z_^L^y)Z`2Zc;5&=FEf)UgShTRo%_}fALl4_7i
z(1SjL()a}=KnHyAOLQ;@Fo3oSIi&GNoKE8x2)K~OFW~SXjX&a48h^wI5C?q1JBU+%
z0+No<?~(-F36sXJaWIYl*g-~+LJ;Sr6L@naxV-_gy6&z=ZzISu-_8?h{1F`tA3#U+
zz2M-N04;n4S>JKtJ?Konh>izP`onvWk{|5#=U=y>jHh}uzmWi)t_HfN1r%1$^P54|
z@V8Hf)TSwtpxP9Af-`8_Hu$QlNC!}`odEMe$KOOcfKEz*@IlApL^>#dE-(PggZ8mU
zI)K6zA`dzqC(;3Q?gxYqIsqpVbOcBQn9l^dI{|d?!wFEC2H9;d2tGZ)qxp!$VbHz=
z&I>E}`CCBC>_ARMI`tW}3_p!uKoWH9Gc->4B|1T&1v<IWqxqmi8oxlnfi(WedujXv
zfuK0bxRAylaX5`X@@g8tfailWeu0DsY5b9A()c3|f#UH)8b9dx00GYrpktrY_#;8_
zd9Z#ajwpnj#tu4hB#r;r2~aE^1aV%j0Ij3~xwh`HXKxqCMV`G4Aj%hMyf=+s0~(*N
zIrt?w!BKk90p#>F{>aV);ONwt0EyPfi4Yp(I1Ol&M|MJ^9&BeCzeWQn>LF<`vJu3F
z_#xt8{gjv1;B@7}fHc1D(G5L6J_vM@3IoXDY5XFPydw-+dnt~T7Qpu%T=3yM0E!FH
zco4{U9-S9_IuC;G=j;QW-Ic~KAP6d8K_L(I#>F&#frtZX{1KNyj0^mN0SBN_5qS|N
z`hZ^$oPPpAF##9-z%Lj8il4v_Y5Wki{DJ|HDhS7g50FDD4}q&7&`$r)sP}Vufexnd
z0-g4RxSz`lbU&9DC`lvk=kfyG&*cS5)`<JLyg>JJd4ZBP;(jhK&=EFXpyZ9XpUVq$
z0EQPhiG$KK=o%F!c>MqhG5$XAMs8TRrSWTE39*QP1N@qxfYJb^S+M5=F7RuD0!afN
zNC6M{H9-NS0S};n5B!?Y5L%8iy&mvjgoKbNr0POS51=vuavv2W4S>qeDWXW_C+I*<
z(1CT}rXRSe2X5Mdn{wc$8@T+0-SrACKeIuehL)c;{Gju1KxJ140|&VHRN#*|!7tzd
zE-LvWPSoGS?rc^M#)JGC2l<a3+z8SDX8A!_FN4788c|+e2bGr`3=F=VCqTvJ4^UYM
zvJzBWD)2{ieE1F$`N3ZQ@bx5cs|vOLfHsjqMI^}O{OzC<p*?z8*NA|^fv3ZV@x=cJ
z(DosyeGF>SM1tz@h=X7*sBr^o;Xt{dh7G871LcAmHK3LalnZLmfLb+BE~qgBYSBQr
zAW6^>sGv(nK&@(U8yI|K7$gsZ4vzyl(G#@q@PKdU>AGls0RdQ1$icwi$S=_a3ujOh
z*pXkr3DWco_`n}=0>lLua^M!{iF(lH0uG!v9^(rB>)`4fR1h<OTcUN>e0wK=ZS8FY
zQOM;TzeWQCI6hu;IPyzy@k@aAZ-92pf?DNG55E8Z5029YP!u`xM>c_IPzeS~8HZoS
zf+HGv{~okG3`(}3`1%a?{!jLDFOObU8DUU-LGOfv#TS1BxF>@<`GO981XV*QNjMf1
z%FrZi3QfYGD~CajMM}F*Nl&|wt)oBL>+V5}=a1k3H7_8Bdw_FA{p;7uVe@gI#t9^U
z9>DOgkI?Y*FKGUIM}`ywd}8&*sqI`09-2oynt#cAbe{9*oT9Qr3UpU=i^>5o-J^0s
zih+T@KVAq_yzBwXGVu2qgSfqWR1z2&7z_{W6aY1Kj=QK7fObo`8a{E{3n`OpR5Ct$
ztoG<`0qX;A<>_ou0TnGCy)7yUYzzz@oh>S$v#~(Sd=e&jbc3d@dPS22c^N!9KX%Rm
zFXMmVdy<<0q@cp1^M*(F9EbsyH~3q485tOA`8|?dR4N*5*mU??8@NH25<wgfHq52F
zMy0}|o8?BggG6VG3h2bA<`;~P&F>kZyAJp}K*zB9CV%fd{Mx4VHh+gD7sv=7l?0FE
z!;Y4JUHJXqJ6is6;rDso{F>3B!-f&GyfLGJ#R6=KXY)Ho$L9b4OH#b}_t}`W{;!kn
z{P|yW{RaVt)&r&MoB!+aw}9@60c|QcKf$A$wfBnvXjcIf4=;lwWLLrW1zZf!{A75*
zqwxqReh||hj`4@P=YaP|@XIqa|NhV4vKbWE-K;JUgFHb&)y?r@;{q;**ZYxz;wz{Z
z(9J3fQ6?n-S>f)r0JMny^$h6xw&wqgbv#ZDHD(}pCUJs%&ieW@*o6!{5FHW=xENl7
zPJ`{d>CwGKWrGw0L-!o;Dt^lz70?`GovKH74Jf!SYM%D!{NcfP!J{`siqV7d*MwuB
zM00@A!}3t+7nklHus2*=Pu5j-&jCk;OXm`>5gy5hdxQUhA}qnDx8T1=ua7XJSFet-
zXXknTebzp`$&9W4>kNE5KXm@`>3sO2_c(a7M~R$A=Pi$34@S?<7ap32JT(t=2z35>
zkq?nAeFTadU&}u}osUa*x^%;Aasj0WP%`W8fg~ixV;+{L`R5$)Xm(LaP~hKoz=QD^
zD4{hUVDzwtrrb^!l>+`&(DpW1V)p6o0cR0c!vj9uQy^)$SLP@v19*1c_GLT`8ZYqd
zX6$y5Xg$E+_ke?eq4@=);U&*rA0|eh&I{n0vcZDUqxll3+r#K#d7|`#XYv6L%L^|2
zK8HXXlR#CBujS3so&4L_S`P5H9N=JJu+imj&EsQWXsBbf<8Mvj0|oFgCYMeZl?0E@
zk1vFeaWi=I_NajNj`(!@sARZwyQm~|9`b<ht?}seQBeRXEIRZ5KQsqGx2&`t;P0pb
z?P_S=qw+wCfq|h!6cpberc1Y*gp1_?{#JE<&;VhJN&*uDg9qbbP@c>H5d|KdF)9_H
z*f<Uf0FZ|`JS;Die(-396d8=rH0-z!w7m;tE-2H3q91fzlS}6s70`u+{8J8rG=QvR
z;Gc59)$qUKq0Sr4FBm(ffRl?yFUwKTHY!k|0os`5k$f1$1nr@Lq-Rj%fXXe`*8eV@
zH7W^S-7-JAvn5LT8uow<VBl}{=VD-JeOss7>-yjDl1Hx(8>2_(2Uva30NRS}aSgQG
z0d#uEht^B{tuNR?xxz&y!=ss*(W_JDhiCI~MvvxW3O<$)zm;}^5*OGX-4K6(oB=9E
zLH-1J#?|tTN9UF!pitxQc@2uQWJs0<DFDrub>4r?3ra7J%|{tsEuYpqcqSih*uw%U
zT^Z_Ld3N4#>3ju>wJAry3BUAu^M85%{%~Ff29M<9&BqyCI@Yj&q8zHf?m*`raN33@
zai88TDhVtM3_jg^zzNl-vqUAK^F;Ft#?E8VLJ?dZgG#<maFBvSxAQ36BL^R_dvqQL
zZ5QihY5fBl7i7Hek$lgi6H*d@meP21?t$dx&K4EWVM(1I4F7v*9`;~{6yl&#Gr^~O
z4Y)-2VO|3+L7E}a^53IV#{#4v!=szU!Y4UF0%S4B5T9NX4aeRRmH#Di;PBz!7s>#N
z6j5#lhSqNtrXI=192;!d8Teb2xIw!WT-g7=mPmuIw*l2S;4Qr^%-jqN&F>hS|NSq0
z<#-&lNB=))F^XsNI~GsNyQRxKn%_2fG#}^iY(B2wVZ8?I6aH4vpbaQRg6cp9pY9Ts
z1pXFfP^iOdv~EcK=mV<Fm_d0XfYI=PXD1Knq60=y4*2ZR4XIK=J_4l)XesD%@DV#`
zHxwkGryK!A4`}mfi9jby6Da*zLN=1sf9T!<j!Mfd;L@|!1Xhkh#XXZxI)1<C$oSEt
zm!-?A*N2nQqgSNsIOs62{~pZ;SU`^W2uf!l%YAx#R33mfqjjF}>=oGv%B)hL%nDW2
zya!y{Gs4}v1zc};Pf@uc#lUd9r3IvyfkBefr_)D8L-IhcA0yNi%?|`RLsS$%Zo41_
z$}b@*89tpZDh4jS4KMf@7&=Q-EIf|8s04tD2N1&p!~ms3hZoyL*+5(OJUWl@x9EYY
zpw5FYm=CcsfNFY>qYW>4bj#cT<vx$jn=gJo|MMS|6(;UuWoS9T-+CX^@9F&b;^RJ6
z22fOibTIO_Xn|r0TKF*Wx9$WLzdxAxTlzui;0H5*>vE93-YF`eli@%oGxhFK5nyCs
zcwxDpmBH{5$cFqQAU6nrBs-^oB|W+WI6zG#3DBfrw}ZegaADTjqM`uOX%AM<0p8*X
zDsMHwsysM6I{g(qx*Z?}xof--ho}Q7aX=`sKqzr|@#Fx=Y7UT+1XfURLhQ`|vq2{H
zs8oR1ojocO!1PCuvl_t6DJnC-bc;#>l<t7i3s@N#Ud#j=4QgF^BxfkR=z?%PJAdv3
zZB6y;e9;{s^J2-7|NlK&4|sMS;cpS(0u>x<R30!eF!;8<<?lNSilg2&Dj=8nbZ=3)
z0hahyR|BdNLBZ+S`NO0071%t-|5reX2^<v6El@`zXpj*gc>_>5Ft?~ce1M=K9&S;w
zfXah>0;<(Pr9OxaqCvhaZ2_4A4o&73XpkUiNKmza9Sl<E0W}R4PB0o~JIvMqs5(%%
zfeH(dZ6G#?Mz)>571Y*xxfPV6x>?t}5@2wFZb0?u6^&$vG@}Hkb1}S>`S$-msI>*!
zsyXS~|Np(tjD{y2oBuO)wm?dpmKERr|99cvXXe`ajlZuKv{|^<{V%MP?SwSHTspsk
zT3i`Ey*6xy2RaYG4u#cUmUAG+^p*Vo|KHW}s}KLaqaNKpDhaOq{_k8Zzj!1ccIEeZ
z=G4H#&e(jI(V;_!(bMufe~Ti-)-q7N#^~Dm&872eov=&i$N!@Do`M^)%N(2kL3YKS
zeF<(IIx+GxxORR3?TR&@#>Mc`=_`1@qxE<2w#XF_MSoc#e!n^u)aZPv@D=2!H^*93
z61W%`^p3TtBtq#V5Y6B7mW_eIrSruuW(Ed^*W94??g2&@%Lnz^9?2&f_V9qJL&nnA
z&A;UM`x`)ghvZYuhZs9rctFNAgO%1@g;iwW){jT$K@cBQHG-Nc3ZR$+)weH-55t>3
zFaLZ49li(ZlrVH>OMp_iBqIYuuj_wMX$dmgr*{q{?evO(n;)Q~w4nX-<Dk8;3=E#f
zSwL<E6{Q@Y#_n@h!%Kz-Tn!Jrw(;l=R`5(d;ni&;1S(ecoB^5W(Os?K)omm0!MNuP
zC=WFMVsvc20MgC~I)K6QD1RTQeZ;>{gst^bg^i=-ff6>)<R2X(cCD9OI$K&mwMFSt
zk8W=TuWlPb&*T#xooEJw_^b>Jub1}nFnJ`Obm8Bp!spuhq~x?mH&kWo|58zp?rH^(
z<enaoc_8<^jQ;=szfX6zf`508D1(pXd;Zp|plS`O<R$1zN%T;0H9XMm?BLNIY~j)E
z&7sP`0&0>nF@joz7N8oyquW`)r!xlB>~vAlc(K#vFQ{no=saFh=+W)L;bF}?Z96YR
ziGWA9XzzAjh8Gw5xfogxl<4hZ24%m_pD&h6fJ|g&1T`-^f4-3T_w#@2fr<)nd%>&I
z=EuwIZ~y;$H0v{#a)H)FdvyN%A7J3o&C2{7oKgkYAc-(wG8Y4=dz1j`W)ygIm#9>D
z9B%<P%0P9|YXQ)BZ1Z6b56jQ|EybTe>6qK2^<>Fwk7iBA(x)EXjvW633|`*>+q4Z~
z)9Y2B+z#5n?%H~w#0*^DGcYiq2NNjKfYJ%5$^g;m>E$FS;hkdw^}Y9~oB$cn4QV*J
z8lH6N-UF`uJJ*1l0<MN{Jv#3i{`UZt2MnMra~j%zbm8Bp=Gyv%zhen_gZGnCKS#^|
z{C(g>F3HzDds&1VEEr0~UdA#qFo4=qpoT^RXp6ijXdn1-Mn}v4p!LYCFP?&fE|vun
zbfS~E7+xlP1SO3YaJ$W=^N~;IO`lFkar5HuPH?jnveVwD8zSnXdBbCdNB5K?-~``#
ziN8f16rtU|3SQkjnjV&?_*-*9-H7f`4Uf(quqv-^5iJkKDM!Fr;xM={@@ziJVF~H+
z^S8=^8lIi6p~(#v!k}aaivsM)50v*cKm`HFU=T;)g^?3986M+rY5M?*Y!42PZc*;7
zybK<e7x`OyKsCB+FDNPUx7LFk-mJ&S-{J_$4c)9Oo`Az=D>Ec~zE0p`c<J!r|9}3L
z{h(fV@^z1HSB2)|j9%R=8Xlc3SHMBg?WzIivobKelmhJ$>}8Sh=<WeGm_25Iaw+3W
z7myL%p`c*WdU+RgkOH_l;_#N0q4@_Rf6FVdYqS~pTaJTR;2{%GYJTbc_y2$2&Idl7
zKVM|;fX0Zx*Z=>0G=DgDvc2T_`v1RUr&;qm#+Qs=K|W?>d?LW$(wU>8;n6EPlZlt1
zvj)_Jb5Tif?R*F-*<(TeI`Idr_UdD>mlrWYyv#HKT%`NH2bl>O7yu1RbiM}lF+j<;
z8<JLCEYI?{_I&#P|D_w)TdchhbG-iZFo3Ms)ekm@^*z{<0*K_-e-O#J5Xl$s{{M%T
z1|MI{6hSHtKEB}k_47ZddkgBSb?$!$DhTu#`CB)GSlw<M9-SZm2N=9u@(xtQJ1}^3
zv+_O`U;s5$J$gl#G4e8i8nUjP4_!gqt~p-h^m8%1EC=gleewwG;U7>B3-)s{AWDvx
z_kV*OydR>-hXE2QZ~DN#F^8D2=n<$T02%f0=oQ@#Rm2YQl@Qoh3=9k}J%57Ca^~>p
zya_J3z=IPdDitrQK$d_;*}x6Bj~<=BUi{j{3TnH(xU>z_LIg3v&A7u5Zg&s3!S31l
z6Vj0D^ifH8aeWuKG3U{FoWG?LR62KleDQcQE2z!Q-}(-epgTVretYqNgN@-ep9koW
z3`<D6zs?w3#(H$~d;ph$k6~rtEst*2y$`{`^BwA`PrY0WFVjH72c0)wn!o-3-_`KI
zONP(?|3gO?pu>JIvp$0S3Xhl#pu~lx6~1{htQG!p2gsw4#xpUk@SR}w;HERU)d{L%
z&>G-vTR}#Gm4FKbXsaI5>_cu{BekkgThlLs!A8J?-vz=&YemQH1P8ol=TZKaQ{dFU
z2HaQ%ErsiA|M&mDPwx_N!vd+{?9=%O+Hk%KYN~?0K&6H=Xg?6B0fgLiEp2)E@9+Qr
z&7iK)872mXW>D9t2b}CMyGC-GV388C9Tb8A93I`^An2T;0_qaMyF=iPlmUhskY}L1
zBWRb22SW|GrQg}20_qXGxC=_9pxA+11CFE4DbS9@6cw0X!136Lh@=KkS7#kqJJ^Mw
zuFiZ27ZgdLN*IzuUhLcsjie*|EvkP(RUA@R=Mgx0Vs>?6kYWtf)d86Y?dpKKf*#BW
zmw>t_pil?9u)9SC6bK-BP^Sdel>xCqYCyg#T>^@CkoQ5VK>h&9z-V;Sz`@1b0uBdQ
z7X=n3$fokQ+W!Cl|E16$P%9nOx&5>ZTmX1<9`)$_$lr2|fq~)0zm4Fs#k2G13u91%
z?)>Q4dF%xTC_{mm$6wU02lcs2s$C7A_;&OAc7E{bd<E)V{J#z=XRo#%D1G7E`lN&d
zG)8-{lM58`FFe6|_*<s`{{R2Q7m#4<fl}$09iTMU&02mJT#9V`11a#=faIIC8B5p=
zZ@)|hD*+dahPOebcnC<K^WzJ(^{fmYwqHPPm_E>@UoU(+xfnb<kGurk^Zr7Dg^l6m
zoge@IdtfP7qSwQc@Wd^IlW;DE8gT5vI{bE^@WPWkp*>D$vV0*ARt^djaFHzl;i4r+
zt*y}Hc$B|o+AmO9iBx6;|H4^jKvE#M%pfHN!pa2Xv{Jg{<*T3n|4*1OVFKv-Kn0J^
z(;nTP0-&}qFSs6Hht>lg-QdXa=xzY_yqk|GM0@;ykcM>L(>F&6#!?=SZdUgP0t}$T
z#twUQvl_$LX%oIVN-%-t)nQ^D-K@eeHb`Dl04&cA6Z7b1{d^y47D!%#1uXv@Cg#!2
zdKtzB$xA})KMoV~=w{svV}s=(`j^ARJi1vY!`NvPx*a7{8CV$@Y(Yecphq`r9ZV8D
ze(%xEnu-u`U;wFS1gQrRVD)|oY4CnKR#Sw41H(5*31+bS)nTF_|HIf|`<ovyH~(M)
zjm5Jv!6jh*eUEO|r}v<t0cy{82TFK!v);NV!0`PL6DtEl33u}&Mh|`$*8Rw;5aXlW
zP7;=m5+&UHa}V%uJJ9RG@c*#k0i^wn-JTLJSG0nrry%`Z_<C&v(9Ef4=b7#XP(O7g
z0|SFVX)1`~D6#I267cBFQfU6oQ?BpP%PIgG07({^0p60}(QV+-8}{F$^^!-YK&b#^
zK<(iFAOqO=J*)0baEWjl+H0HD3Tjaytp@h!y!c{nBNw>!(jp6Ly>tf%`1Cp`H2)Il
zyj(xeqqjsw!6O-b^i=aN4$sby#Zj(?2fiI*DdBPHW_0ajbld?to$cEprV>6k{_P@+
zY3`jOjGoO0n3^9kmT)@pZxdm3?hs-0=(h0a{OZvg4s|VmD|kIDD8F}tT>MfRbkJ+(
zMZ=Sx%@2S0c8hTMbc*nKG#}*fu{>Gy-lvy`&xi5g>t_CKt_;mD9Bst-+rj;pUQr`9
zUIx%KQ!-1F2jd~+^}!y!wvnv74B!@kN9ViG%OI>?TQ^o-2L6^XP<tOF%-?$H-~a!P
z-61NV_<nT<9^aPG_&$F}fZ?^y1dm=@evo;f&L-GA{??gbjV>w@(1c~<(apN@4kQgB
z1v4~0dTlSW@G|TK1sGI+BuM`^7ZnNSlB1yc%v6v~u=Bw^dTp<P)N_LS0`ERA<8Rf3
zs+VLbnfm&?N3ZREkOD4*0uHDG2}b@F(ESCkS0U1;N3ZQ{ka8Zla`27h9=)~`QG`qO
zdGy+LqX_Z0t_N*k`sSh{!NlJp4yye?ivv7*ZP`HT*x)9%_JBs&x?NNxR6)7c7DVv3
zKKu9o|4T@G**<3GW!T9M(@?V7qu2HZs!+N|ukBe>p%RZ?+e0Wq{H?N37fCYmx3q#R
z*aP*uqyXe-mY1vl{r|rc?6zLpRAyd=m%N~L=J5FpN3b(Ng%P+!;%~JFnNkK)11^so
zLEdG79L@4F9@KR_@bbVPP~QiVe?jGW0jQAZW#wbxW$@``Wde2aI}dw;(4o$Yo}C99
zAA(lZHU0#Vofkd%U2Zf!1YI=J_!C5SUIY#7B=|yvLA{Ay*&j^242?fQ13#S?K_fi@
zzWgp1njf-&R7N!aWa+%<(JQ-+iI>5b-{nN}Lnfcj5EX~!pG=_9xy~3B4^NQrBSvT^
z)T39niHVm1G{s;5ovsW~vGD2TUCqP`nmL~irg$Skeecc~6%8MLmjf?;*K#p<G#@F5
z2JPxWq@VCGkdGA{dma9Hbe{L<yynt*xcLWTc{b=!bdO%qH}AMX-Te~I7g4pKu6~JL
zx0{5ey98($hqe2r07LU{CQ$L&0V<ThXJsByfE<nq2~Ur1*4Uc@46h$U$6ug)s4g#%
z)CrGn)`?fZW!f{4%ey&V9BY7<X<)OE>r0Sp4ZwxtY5o?_S_O~hN&$wFOi-aGQOCvL
z)6M(!253Omqnq{44FLupeiz<1H$XRWc?<aTvVtPQqgV7R$R5yvagd=7`5JI(>Ct(x
z#MYym!SJ?6ZvdoB6D);Q<()Ucc^_0gzqt%{Y$p>h!*1|dhus`6L>jmlUf%|DUtjU)
zW{rTTu|-z%p`MH3^>$D#gb06p{_y}sS+}Sv#6SElqRJo-b@Q?y{G$Q(NQjDpN3W;?
zG)-u{@UJGxKQa)v?qo#rj|<4HNdD=#1orb$WHkyPH6-|_0u;>MqM_Hp@x$*T8hl*<
z6k#UU;qemz8cXO50gtx?FhbI}!i)MUlKkTXaqCM4B>$Aup~laSi(voABKs!*qz27D
z(A_{DpxWG{^DI(r&ff}JW&)|v^}scHkwWut&XU^Z-;5=oJste5$)MV(*Y@r|9!Tl<
zc^Q9;4M?n;H3MQl8+4H8YAy6+M%ZD4hoSj}e;b=kc!{NrBYz7MBLjm?Xz3vz&}hy}
zn8KG`pt22K{(1D;mVvAT)i0lyl}<%dycg761C>Fbf#!-z(11;VfKRuJiUy={P~g#9
zqhbJR9Q1l9cz|06zkE7R@;8GPAGjKx{C0?izm=Pjf#KUBCjQp<pyOm8G4i)w0~P(y
zhD+x^aP}17Z+!>u(FbsVra3jhMcKdqK?Y#kUV>_8P)-0fce*_kJh~$^z|Edc9~A>o
zsb~Q+<ifxI|968|Pk~(adOezl_Wb$(zxg*0e=BJ9vq!IO-(MbvouJAPRI^S2mHnXo
z{D}PK*?9@n9C`G^w_AqOr&ER>(j2)6YL1BT`!Jq-2|61Vp&r!O;dJg0;d&|a|NsBA
z32yw`WjNE^J7quz<1)PjUBm9u&FR|7<p^#9ynF(R4W#xxxOmm@Xg%rCdAh{SquUcS
zhI)KHcnr0K^95@KxKQ;pywqLn;L*!l`;wdCzv%K;;IYXPA;^?&gg|G31oWbB!vn9s
zf>vel27^`BLRG%l$Ii&W@cJ^Sz2SQvoV1IeLxfe;ptAJ!erS88`Hctstay)J7ZnQ+
zP~{_908)M2Ma6;v6qTJWDhe+;Yrt-E1PyUnfR4D8^Z*SNb&GO9oiFvmtsJDJl*jPo
z3t`a6bMq08!w}`22VXG4L<|pr66;||{R`h;_w5j~N9XC%#BawKORXE8v6PB{3)r~$
zSjQO9Wem{zqx0sA6I=iM2Tf#yy8MmF4*x-&T=*%NhdnxPc7~|vyb#*@=YQ(~(6O@o
zE#DXz7#h7DK-KZ<B`)2`5+2=-7OtI-J(4{X9GhP=Rup)2XKVN-p9W3uc=fWJ1^L>`
z+UG2TUpLEn{#M9@?ST?cm(F`0jK@6~k9vH+=h=DE@PNm`XUwnF5b49G+lTdsPqz#E
z4`0iR{H^mrq1XI^!?*Q736F2*Az%LW7d<SGmEP#Cc4$7&*jer1+WMr<&!f9o!>2n~
z!NZ!*x0|W7%C+;h;Q`NskC}a250t9B)<c-@(e1;=;oI%P1Zp#v27->FhMIlQhkyM^
z&{5lWn$I(JRy(}h3|jvW3Lj9a2Q`yG`3n>Zpf(61yg)8_{tu)9G&0cq{4a<JI-v^G
zot*#*C~!9vTK;%+vrYvSRm}{H;G0n)>G_+ZBa27pIsR5zMh1qRpfvO1b2+q(KFr?&
zim2lZpxN?nH;GPX7LRT>3;t~m5*^MQ9^HNx-Hr;K&OF_24ywQ3|Nr0VEYMIXWmm%1
zaE7VVS)khuyc!H#wI`qOIQWp|#SECy&Jz4Br$G}x$!-!Jod-P+K4A9h6=Cq`3|8>y
z4pVs1zJQy-2PD_+4HD1*DR@z|fSUnit4Ft+fJbws1%pSYvqnkS3nTr1kZCq&1OApy
zP=ZMo0IeSOXl7&d>17SR&&J@<`N^a6CM4&*RI21+NSgpL0c6y1X9-ZM@i^|R0H!;g
zHA+``9CtPV@m}wQhTn_mH=xNl{?2RQwkE_Zr2Zpl!N!3yE`|vZnU{acxfou^S8y@B
z1Wizb?q71W==M-}=~52rV>&Q^`kNMDHZ*^92Wo)CQn>#92gSEXcc21@9|Gk=+II#X
zo#$SBgazYa{+3cuE!6q(#opIo*L8qSNdD&L$im;64U*}$-2f^?y8Q%R7?*J|c=Yl<
z`NhKkUbS%O#ls?yi0IW{JPaP4$2~g_fc#JcGQ3%zk-w!1R6DpiF!Hy8l7UBem`1ms
z#ET=GfB$=Q9{1=KT?8}f<_mYYCXoH0NP00x7aA+a`CGuN3wlMX5E{hb8oq!sTDPCY
zi)iV8|2=v|qfuP*4&-RCYxaQEg(-mC-~e(%uc!rB=`pCo4}+D0X0A3eFfi-{^#fmA
zF9rKh6h+}Ikiu>@aMQ5!2Do|>D;4qR4&wmTR~n%4y&wZn;imyD$H4i;qgfj~>k1wR
z`X68bE(<{i_=1W!@OX!<?>Pa6mlMEi+ClR#wyNhqeNA@8m*>Itr#lB^zV@Z*|Ns9d
zAZArx{srZC55yD>=*l}}d2pUaQa=Zz{>9-^E=ceB#l}Ktjy+!D?a|9C^pl6-#aWP8
zx1WVar@O=p2C0Al!FP&ybh<0Nm{bB*Uc&Fu9U$S+Y30#*{AC=-h3NCjy`m?6@GyYp
zi#l(<NC5?9H;XDLQ}A=AO)$LlQga6z1N{6caCzbZT3Fr7yY>eU!;4~wH6ERZOM*Q>
z32;*}I5JlJ-~si<=KTPr!;c=I8VZ!|QVKwA7-MkT0W@SH42qIq4v@SBXtoFvB^ICx
zC_3&i==}B9pOO0$FQt1K7?A2~(E4wrGo&ERkn<j$m-$;JgO)k=iu!<DsrnL<Z%RO7
z-QgC7piJP=%*6Q3-GK?TdP@WB;i(5)4Ntlng2s&mKrVjq*B&~ldX&G#0;IR|pyM7;
zAL7O29tO~ejYsFP5<QR3pD&tW{KF+89?f+M45cohw8Y;M1)8`veBuF~ZM6mE*5+IW
za2j*v@aTN`KfnNV8XNRbEXNqoK@N`b@clp@-Jup9-R>3*RZ@12{8NuLR7lzJPd(&l
zc<q~mG^0m%fP*Xlwr4)ws}6upnritADs6k~G+qZl%QKJeW)0AsbhEPtqX%QN0chS0
zwDz?-OaQdb*cB89eiHnxWgv%jw?Wjpfz-Bv)mr;0@V9`E6YX|Z@UV22;O|uhwG+C-
zEj+rrK}udk&S3+c;$-2`-3Q^%2JxqX*dE<r8(mwzd2|bTbPDjdUSMQk=yn$HXm*xh
zY(2o=67&E6|AyTbtYFvsgIwC(tO0hUgM~-3g96meFG1@TA>}1}rfmx-e|SJfY(azR
z(?NWn-ZG8X!N~P7asIy!E_ZPF|2bF^?tf4w>W2Cc90Z=7KV3T?IR3wi@L5S4+*dEb
zL5tN_pc=hlAJq33!M3!a`W_JrtyN%q!Sb%XPK+MM-M|%^;U%BWpT5ZlK&$OQ6{tri
zSkDWoncNKEDQdU{ps@Go1{>hf4GUhdVh>O>w@QK|7A%i$!AC3>?3}^P@bW3xQAnX+
zc**hq)t8ds;t_N{H|TKxmS;?m)A>8rfR3|GKIGF4w$`Qdl1DGgF`sS^4Ik?c&`d<F
z!b?Ub<o$;}-5v@))*YZ30REo)ppZ;H)clGOtWCQ?gPDP$`PYAs;|}2bTYAw4;`x^@
z;ByjPK+}JW{4LX&7#Ki{!I?m_xyctidU-DUbUSMJST=&}gr?&<$(NwQ)2G`>!N<A@
zV&Ocng%><}MJ_kLVD!-L0$cdwzsGSWsD&P#V86dy4jz+ofUIW#tzrP#H;I6KFG0B#
z*}ik2Bmi<CLHo?X9&})E1cxu^ItI|~2OU0y!k7QG3sR8Q7<k|d&a1HC{Q3v9eOTTF
zw3Y`Pa~_~OHV%TK;hGO~1E|#S>GaTmDL)1d4Dk9hX!v-5JjHU^6SM<?xdWo!K?5rJ
zG7F&|Y6O1s(|&^n0EsuB3rT&qn}LUQ8>p$n-^&k*UXYVI-3&as+YCU(4<p!rFPXtk
z0@d%%1|HVU5cS|KKw$OG2B4x1tR7s#y<85q0;C?ve1v)o^B4aDc>$yz$^7-8=*Mop
zJ6t`aJkxGA0L>IYo39>7#rsQ{-{8oCwKpMUnsysRy&Jf>>(PuT;$KSqB2E1ZRP_Yi
z)ARHHe@LbIQV6^*g!T1)aF2Jw2Ob891Zdq%Qw|ry%a1=m!Gg5k6gr+00q*B?p6<Nr
z((NGQ*!+W^zvUokl)L$d0DlW;P{*<P2VaSzM>p#~h~d#6AQQ0JIiT(|?4b6;JGnvg
z!qYbW{%`oL^(|=49*akEfr3Z3vjw<nZJEsgs-PS^n2QBGI)8yyV)=A?E4Xw!OMse<
zu=Rf$9-SpB8lYB-!i$|U&^E%cl0e7+z%7r?gD;$}ftnl@dd+DLe>^%rAY8x;S|J0v
z`3F>=fyX{xf^JKO_4oC_Z39>>2X23Y&zOhw$3aaE3C(~1L8}w_w*^Uc1W19F@0D<X
zns+YX0z4etn(_d(LLsdw50IP&cxxo+zQpD?9^lsSHU1V>PzLCBwCHw_X@0@i{DY}H
ze-~)p^#y1w-=p;as8v@CX%c~!dVYkrl#aWofO}Cd?wG+n9|k%qqVwhpP2s=)J-WF)
zdISH1?GY}i^5~ZH=naN&#Y()PtvitaJ-S(4_kmLb(|bsSRb`<JtsMrnqDtQ(>Ur>W
zHLv%;+c#kxoh~Xikmh_hh}8_b{sT51=g}PumB0BP6dH11C2+U!w}K~Vc6xNPhV2DA
zBlsP}8J{zu&Ugu$WI=ELf|^aIJvy)Pw?NtkNI}TowicX?85!{g++tIBz~w;$?t>tD
zz!`dU^TESWtb`pJaG*{MR!@WapQ!%jgZLL36=J1(UmpSmXo)&F7@_7FUV1SFG|&i+
zaQ;?MGJ1U<njYcptJh~ex>*hPfCH)FEhLc6WxxU{37otf7(nCW4j$cs79O1^x}#)z
zy+1YoWGbr!HMLz0FMV@xVCwd8D2)WwK`z}665tW4P8Ssmm(CCs19<WRF(BzHMiLrK
zhfCZ*xk_dcXw;~}3N&s48dm}j^E-ehNg(B2^Fu~Q&~ZGU7+=o@r7v)D290Hc4$OPG
z?l<TXr`Kl??L&}z6+ndxXb!2{Q^6xSLg9t^J{E>upjN&I|N6rood-c%S{ghUPk2~f
zDChG4tqORVk`C$LLwNVnxIkSbQ2(&`jRw@H7a#VrFzjMrU})G0HjD9)hvlhqzRrW7
zp@WyoU;`K+PSbcfCk<jA(tI=`jWvQcxb&ugM%i;ftByZ{FPQV~eBjaf>P1y5XiSg4
z19Vqdcd$h3r4r$8XNMJxr990Km_W;*T7Q7jW4AMCHM0VEp+@*#76uRg^+!FdT~svq
z`$6*GoE=#BTfxU=b$c6tRz`??b9NLc^#`qwD2auQlYj<WAfqfVk}iVEH~x-WVAEYx
z6k7j#bUF)^+8%dy0L`3%OD<5)8D)I1(Gx5QiayW+Nzg*%#n8nU;QJB{4;*)P08Lmz
zJLMqFpnfCER8XhFTj0g&`9J@^1f6&YNuQ8F0ImP2N&$sKMTO!2m!QoH@bZDRb|*N^
zI=zOZS*bKwng#VeK=WG=`Dm#8uT+>kXl*z+o4f?yYun9g3{kn@6~v?qaFs&ff|peo
zRenP%7en)j|1ZCQ8^e(F2^rr>02hqsLCGAlf2i}~aTk>c22fBQcTs`V(Xi27{+7+4
zV!Ag(CE&%~FQDYl-vUYz9?dl>0Su6_A(w7<2^UKjl?eV;$eLt#1CP$%9^IxqoxGrK
zYKbm9JUlo&EI*bAcyxYxVV(#IGX54&BK7EwHt^_nHt=XYP<rcyZz`yp?rh=H?XBU{
z?X1upECCwzhm1diE=TEg0gd~EhMiA!u`_^%Q4D;#{lQZc7NFvcIat6`^MI%3MNsFp
zI~=UL+eIY+RAp*-bh|5n7z!``KKlt8DsGtxY6&O1s6=>l`-5*@2>^9vUZnMKGeFnL
z{(MpR60~^8M<w8eeKNF8PXJ9_dO#8^e~TL^7J5TeJbZdxR2*JpCV_p|p%2~x;4k2#
z?W5x1+j+u=*+s?SWeP}fH|vG%;KZ@?B_v91Q$YR(*>O7wnhah~2dyW7C|d_rb}gBU
z;q`ToZq`nScqmkSUouqF%Xo<Kj1YNAsQf&*ygjtMgro-raC$fgx$y5r#xm&kvBUf=
zjG(9o4PRP13-Gss_Jw+M`zgGzO#&_bua;>2-&rS7m(|Nt?~#1c<KRQ)7t$aZP(kjd
zzz<nkaPT=ZsFdjyu>cPUhG~E{aJ=B|1`o4>I2xXvKVJOq;${HX494KiDxe(2@B&m?
zf=jr#c-Z*YaW`<m>~Y);+yeq>DLw0fs3i`9MYs?m9^I_Jw}J!tzzawq&wvFj%xI5p
z)*BEdwNNFcFeNW*|Ns9F$%LS*(6JbP4Wg6z8N_gFxK3x#_}feEXaD~rjTd=zJA#rp
zs48V(JPfKYSyOj`#_yox<)DKiUT#kW6~>VM1#;`COwgm5k<p{`1Sl{d`PuN&%gC=t
z?Pu`#7`O)LJl%S!gumMnR1|YSisDj3P&*T}$pzHrd~snr3wUGRO%ML{$G$l`vUqkL
zDAfbi4$*NhXD5N&09xO@cMCZ5Ha&-UFe(w6_%)*A4#S3_W5KE+_hC1`$p9y()1cx7
zQl@lX<Zt;3>M!($s6@Q@q4w`TXzV2gB+^`?62ZXV5&>d&dt1EVUI-~+K$E2&-Mlst
z0t_ClC;3}CKpQ!_eN-ZRKs8CP=z`}w3@_%zK*kvJLDPcpRZ#pbkoiTB;$%k!SCCzx
zZS_9g-WHz8jtZcS*DaSp?QC#$CF9Z^?BMwA5F>x<LD2nv&5xKI!MFVtgZfw9thx~Y
z3qg}cR01T6Mu2OkIB?qVXg-nwzPg(Mv^Ol`h1&wKCt5)V8i7T8pzZ))!rNRa13C-u
zAvndb9@{Lyz~2JiP}0ru;!ix1>7|QcRnttw`ZUnS#e?9sB$EGH75@MK|9V;4gm2Cc
zj3wsX!4kb*|3SBI_IfihFwAuP{sXkf7gQ2?Bwqw4fEgaWJQqFq*E4!_GJ147Yxs1s
zT<~nxWaMvo3(oQ(DiI#dRT>QZEuc!d+t~r$4e91JZ{}qHMJ{L}2XucVsNfa=6{s2@
zlRylG7s>+AhSM?rmK)$f8gGRcY;hppxq&8IEIc}$6}mz5G9fAvoz4;--EJBloz5Dd
zmKtcR5<0r%0nP8F{D_fj(9Kv89-YCU0b6kC{Nmc<|Np`DJt!7Dnkzxh{tdFUS2P+D
z${Cvk7+%```~Uw%lnki%;-eA)YGep|bQ{9Qf(7|oKr?{geg~*3Yf%8LDDU>R@aR0~
z3raVg4hk=KgT_>Pc?}=&FueF43r>EZF<3{BUeW(gKr<W%UkHFwWhZN6C@5d+F@lzf
zNPyCCtIgm4|6iU4opX+ue}|99dvx>qhYB#fz6x=FYZJ(#ZdUh=;M{lR2@mwLY>#e^
z7w2LjRZIQf|NlWT&fmHnRCRZ|fU<|Th2cq`WCsOMQh)gaVoD;!6i1K?yE$G=i-pw_
zPM`ssZbuHE&Xb@qOcqd}bq7LvaNtDdqT=!L6}SNbE|2*8u7gbsR`5tZ>C-E6%9DRR
zlgCWY?>{_1DeUYY&~;Hvpk(0F$#UZ5DzIYKstsUItauD5Ld4<L9|kr1Vb1OjmVmq4
z_Ag|;EZX?GhfjB=fk$_thG*wF(ETE<Z~0p^K_!E=uH05oK9T`(x)UutyIoW`zBPaj
z4`tzR*}=@f;Mwg86;R-BDFg{L*Qf|E@b~G0PF#8G({1~qj+f!Jed_`KR?vJfXoe89
zisM_uDo`7mzeNyKM0NgraWNXSGOA91iNAjyDAb#eGJ0C)s0i@)-Ul7@*&Xvn!l(14
zN9U~<$3Y1JR2LrOZwUt%CeBbNaPYSzfd$;40xbM3g&=|EIswMIXz0egbdXKmaS}e3
z)g1h-5P8t9y<eafDd=8MP<6!L>IJUrk^5bsPS;CgQ2hg%PXqPYWumzlUIu~{vihtC
z#|Gz9NNjXQgF6q9`UF;-q1|8!Pp_WcWf~r>-}qa!z@>yAhv98d8HHHq!cv;Jl7XRt
zfxiVb%I48|3S|4dC{VuV0}W_2GcvwV2d6T=&chzvjNth(P*(%7bjt8R>uvt22fp8U
z39fQGe}Wox&4(FZgoBOo<9NXr&c)zidAN49N4FmbD5O<E0<8y1FL`vc=B@*K?-n$z
zuZrSgcnO*_0Iw$ixgFfWbmiaYCgs@h!?q;HvD;0>m4Ba~v_~)Rn@2nhj{N(=Bn)qZ
z)_Xa2yD5MtVr0TVi|>!UmIp`8#}`{b{MG{{{vfw?{`3GjZ$~6Z&Bqr7AUVs!HCI68
z7=H_B>e283_%hbC2`^@EWC6`}HUD68<ezfDz1M}o=4CawF$T_G9^I^K*Mi-j^#~F@
zuRx}PCU063z`+I^nE}Vt%RsOgYb8X_GN_(ykz5Qf4MFn}p#B9!ZWmN;7Dx_suo@&h
zx>;=@@~5EkRUrAV;Ne|Rf3llZ79!6D&Ad?{`Kw6sf7gKBs|A&}0?BU$=X;n_4G+9r
z2^L_z2vK|QA;fQdAhn$kscjIcWT-KpBe)n|=0T)pL!>&Ox^94^g266efR4{;fW`)@
zL91jOIY6sKJh}@bn*aST5daT-X++1x$3n)h3{SrJ2}vuUvA2id*t_{++VB7WTMv{N
zfrhe5&miVNUmx)3X4Qq*4)Xs#a7VhE<3(r$7sKntp#80#KVR$s8Q84P=+Sw!M9HJ|
zZAq6$=gSw5Lb(_^og+Lzvu!03%|HJ0yMB0?3(kSCDcaYUCU|tiX5qS>BVON}fKuKy
zzOew63EgW{7BDd|cy^xi0Ua;{7V=c^>~^#8?RL}f={(;#MFrG6@<_e}IuHUhfacL{
zauGC?;Mpy5!J{)o1vGXT0wNsvw?#-b{I=_uqtXSM^O|zl@td0?BY&$3$k^t8jCIN`
z{M!<wJ-Qtn9J|9LJh~e|qYt1uz2L?CwJe~{T&WcJR3(txKmm(1XXwBH+9CpS3+M*v
z3sb;Tl%Ak%aw3p9H3d+!p@IQaY<9Y+M1cJ8%|Tj#zvT!c1A_~wg9d7?wH^Z%F2`L|
z5<n{Xw;gtDe!}Q#c&W2R1+=snwC@zu6Y=SVoPFZbu|x%Y1RiutoJ;2gP~Q~PtYl+h
zVCeQy3GnQm51J2bJz3)2um`Ld)NaY(Z?R!wVCZ&H3GwW_0ose00NUj40cv14fJRtB
zd0zum*s^~4^S@yaILPd}T~spoTY5mXLF<417Ap{=d5_8p(E1gR<B)r@!S3!eflR&n
zbk?Y3_;x<`>0ScfZTwmWG5!NO`UZ6D4M;bC%Rf*z6g0By)0v~9;M@7ouiND>bXm#&
z>#YYWFZguVsAM>H9s;#06F`Gj0WT!`fBpvrq)T^*N&q-CTWi3PS))?Hz~52;Vt4zf
zR6tZ$hjKB1Rf6Yhf<fu3n;ldLgF+2-d$>4%t32q;=<aY1unwQjpZ|jlKvDCO9o!y@
zQE~9Gyv0BD5a%uaZI?PjR03We2DNFx<;e@-P*5T0qEhiv7gGNCs5p4=uRr(VQP0o+
z(56)ae=Dd8a0HKWy)*<Zl!LWz!Ttkzr1esX4=k$qTXGl~7+~Sg-;&P60FFLz#C7+B
zVipu{4nClxnLv>TO0M7`a)lS(pZ@#@#h7DvxPWJ~y98tFrBXT1?&+Y~$+OvAgVB?5
zI>-Qz<{Xs>MzBvD8}@^zL`#xD>c9y%$igEzNCB$!^<_l-bwiRQ$a)XY&KscfR}2s-
zr#nU^!K2$nr2yn82hjS03m~_EZGns*HUDBPNo&1S(cqDM%D0#0yl=OMhA(6;(zm-E
z<S@{bBxqxnJh*=F>Go9cvF?OS4}#ho9?7RXdwI?`zhd;!ZUj#cg61O~!JXsMi@u#;
zGhWJpc2;zU8+ckzhfF1b_N#*q3-{~{H}LG94w`y``tIeYfB*k?x~OD8z2=D=z@4D`
ztvgFpz!?J?+)(d%{D=5$^1uK8!3pO@L@>B{3{GwQt)QDkU-$+?Q{T%rNcrvC`2jMX
z_kW7Y1jsaL=U>pG{?0=$CBVC{!5#qnQslg6^Fc-*<|a_w`E+_|z<lTM54<ZDR5pMk
zz}4_1I1XG54}dE1m!LaZ!5OC0MJ3?H%WjPP@)OhyZ3gF;)(e0B|9|=74`?391)9tt
zaqMb%5^OrmXh@ubcI$yG0Y@`52ok`JYDf~(o(`J$@;vSi9#lh4aW6p?-wsfX@^T$y
zN((e!9qt$gUr*BbrUIOK9W6jb#{*Da?K}^v11^ADxsD1R-JTkqQ&diXR3%^H-&P?7
zD)fCi&w6&7TsZEc0?IZF4h{e996I)>Y-3<x=$r%I81KM8<+$TFcSrD<5)~fZG8aMT
zPJt2_e`^;r1A`0ywgPEz6|fVuFxas>T*9;4p95MMfXXum*ytega3MI+fl7GD5DoMQ
zmKQ77p<Thl{4H(ZQ%0ap?sm}dX#NM9#l27`<<ZRmwFf*lSMb7cIi$9+1r1ts2TOpv
zt;q!nFC;(`-QEI*mp}s-o}C9?tg8SWXL!S-@dzluP%0%*B>@T_pU$5?ov&Wl^nvD(
zUxAkCflhdPq0<MdSdW5YFTn#eP_UW_awt#BB2b`qJ1BsPbkO1!P>~MWI0~wHJiFa3
zz$I<V99D1zlLJx(+PDQ$)q0Y@)e}@~G}ovUaPYVKfNBV&iot<@+i}p5a-j2nJbL$l
zcQ89PKV$4{fgDrOxdwbTg-gd46;QVhv{q=23aA$L?EDMr_cZST9~r^G-;xLlP0&$+
z-61MD9?&}O5~wcgi~)^h!p=mS4Jt@VVjA{<4P@wSQ8@#u{9A-T)g$C^F%Q^DX3!JP
zK&iU|oYcXoyYuG@#<$=)5R{DUJUVMsBD!J5?1FpNgWnZ$#)jb~NcrZ`DRLQ9&Ujc}
zEBy@GrrpvFUS7IK<pr$11TCHg1si`~5vV8j-=}kl3M8%n@#wq{I<pGIdo9inn*aA~
zKEmi@xdg16zr_wTG0|D0VgRZyH9SGvXF+?_I)C|f^E?LS_=x{kTMty80-cfuI!^>-
z7$_h?2Sk8k3)BXAakKsBe~<w97@ITgpu!>C0@Nq{<|Hk^-wIL(k_M##(2xNySd)n#
z7pUD30a|7OI#wEV`bmOEHyfzti2xmv2CnMZ_*+05IYEa!wX}e`oZYSrpt{xrydcoC
zGn9e9)g4?|go0NEM)-8Tg!Z~4Uh09mz#f({Dixr*_80%QTb(f~IWH4HYa!tMF~gHD
zB-?-fH$3@5sQu^v7f*e`MJ|8Keo*Rd1|4a^$HD;Gq0(HVlEA><8uI`D|Cc$4{)T7g
z9Z*}TfTP3$6gZ$j0`0^Gg@xfIpY9M))dgN*0v*5i?Pj?Micg<TMjytDpjdqiZZ~xY
zL)TPY;&0Ukwca3A-(*lx4P6~D8I%Y?$qZykcesEDv^I|MfYinwpxW4j5n3BVj<aKY
z$@dpD>JIBkyxa)t@AUF~1tpjl{VmWY1*Fl%-@51zY_L`eJY)e{->?UqnV?lVe=Dd+
zZ2rZ_-!c(Y+gz%c3iGx{@+qHQmeWWTFn`ZVP|k%OwCDp_OXk^m>$M!B{zs{gSwVpg
zu8&XQsE=Wm`E)jeLgS?fxIYl1k^oz+)%qH=M*`$NRj~W`J0RyAfR6(OIS{#pz~3VR
zc3_N30+Q=QP}~H{BH-GS2e+GiR1$nT8^I2WfmEfS^F~1F08}M_s`&^|nUCDC*#kcI
z5VWx#G_ndUEPnpKfLt)Vd;yvv?Vb)<Q3h#3LF4zOG(3JLqe_EQ$xBfG@`Zvo7sE@?
zLL*R4t^hY8=QhD(9F#BlTW9=&#yF?|2Blh1!gwhI$|K<N;zhF;s6E=E0?NKGgFySg
zJ8!(a{1Y@@`0~t8(D5!mJwa`dTOdm!{!dW>)vc`u_&cA1+5v~bK7a;3q%8$HC@cZg
z5b@|0IgivB@qtLclmaJMNU8&+DTpvE;-MN(qiBSr1rD%A=;0>afd(Gd6CrIi&;SA`
z&v|qP8hCV11hv&X7$<_G>k6ph0&0SIAZwTo>R&Y<V#K1M2CM<Ly7=Ye-{6)LIJ!aQ
zD0<6D7?j<*d%%$mD)-O}(id|;5z^fQK7;Z_e-nD)`SjQS|1bA}*A79(mq4MM;L$x1
zTrOx&1htJkjyr<eMjp+Mpmm>6kAVXoR)0Z?5$(wk<<3y$;3cJy^m67m=$r{iI8Frj
zQozl|m;T^nhP0jst$)1(R8)0d2K8D6m_X+~wWxq-#~q+4V4uz&6$vH=h8N;e;0BB*
z=sZQx`4Hen(Tj_HzyCv)Sb&;5;I<EFSqexebXdV&1gh^Sf6Fh>d_#eRYqy((BjX3h
z<`;~<$v=Es|MT~`GBYsvB=>+V_DKHc*DLcEl!!gP-#0w47u=Z#&7d83Q30K@$KbdN
zBm~;h18K_ncAjxzJm>lSjz{u0&x22xU(0%S`zd&I^Dz2=_L6k+FoX7hfRc}o<&6?k
zAInoU_dG1G@%OcY5=rMlPi9}x#X5{$-8_mOFxC9)eN;SrEN_5zi+Yrv25m2`@Mzux
z4h;tWmi3@=uDb=y^+<M*@U%P*y2+W9c{X??NaGS@bjQG*i@_5-{9)<YtjAd53?4QB
z1vyF!&7<?DCo{;&J{%li7x1rt314pu8np#giU9^7BTDyrcDr%-bb^i`dc6^}z5-MN
zf#L`hgP`M0J-R&<UL2px0$Oj`0=na;d5?+$69WU2XLp#z4n<K0&?ven=m1Da+`90)
z8~{x@yh#4}2i83e;BRpSmCMOfz;WW)4Vtj1Q3>$rR=EJ0P6inTnn3gHb`$VzeZs#j
zN*Yq_ce{gUK@uRxc6oF=Ie2t8WPp+wsAc&ZwDfoj*fqZ0t^&TD4?Q|_R1836X9PG~
zfRFU-E>ZCSHM=xGEec2j?EeLjcF>{Ppk`{oHwQ<75^+#56yVYAZqVofS<#U0@E^3I
zp}R&Uz@wWT<RA}tJA|FTwHTa}VIxm3Q$SN8>8@N1(C}e|HEsD@mas7}@Hdr!mbOB}
zu9OGVMyO!m@9zV72G;&8;RUseK<(ids;<ze=5M(R8UzQ8SGN2HB@;xd0nNC9Jpeib
z8Wd;zEucafbdoBF2VU9%+Y<;11kj+c04#p_TMvSY$4(a&4~QA?Qv*O;kC%)8{{Iij
zEU=6M%9ItLyz&w<#}Q`X+3m*xI^qnRPMSeyMwh5q;O@V?Ncf7BBwFA8{r~@^F1WGg
z$^l7|(CXVoCE%s<-~a!+!zDbr{S{tR%mQ~@_**$aJ+|&Ji<ck4ZvW8ym=Uz><(reV
zKu3&9IVg@Y_*+W<{r?Y(1^$-R%%IQ*ok#{1W8!aJ1d2Ow_Y_pifdU*<K=Aj0wsL~J
zp8*nvReqr6GpO43<X?XT6se$k(xdYQsH+6xf*M~woew;|-vIHzm3MQEiU$LK-!HIh
zT?IV4B|NMlC(iNr>;;t)u;b$TKnp}&4gZ581!RQ>;|-72+aCNLH$3>)$Eaj@FvqAw
zG}Ne+GeD+bT@9ajw7vzU)Py<@NPhsFcRFu^n(;3-WV10q_&;Av$pLMjx&<l=IzPO4
zmc`BB!T8;S@w2Dpn^MpTi{M6_2V;#&0(ivCx<<u=zr_RUV$h+~9#BWt@xdM63u^3w
z+zJXYP!Ag9=I$-vObyzf$N^f=mF>jE(E5$P<2EQ|ceDPOD!|~=nF8J*ec~(+gCppi
zo*SS!w?$4|3@@wyfa;kPl?<?_JUVZI*Z=%{VG43^=MNvo2cSqzco_~JZ-Et6FTa6n
zUDnxC!R4dFSxEUP05VY%By}8e2p}j{p*gK@8b};8*asRBOF)g_98h}=dir|j59EmU
z>~&H3?*Te-8WiF8A(0L_><<*(pvVVB3N*$+YfVAvCjm5x;~?PG&GNvb^+1KRhb83j
zR8XS@6lQgt9{lS;=XG};Mvh{TX&$X_>pXlq|GOH#1-G{#@p;p;`6%Oy3z>-c-I9eI
zzigR^_<dV?+J_m^Tmq#EAL|qq5B}CvPyyTwY1cD?It}1t3_Aptu|_2Vw0Nw7zf~8!
zx+X^@;bqEi@P4Nn&^gIJJvwiBcK+~W{QqKB1~<d&r5@d^vQxmJuXTop!MF1vsFU2y
z@#2gF7sJb?pk^U4mR$t33I9L_YoP5JEZOoi$T-kAA1Ky9fdq<IALvn&u-F1+SEOtS
z%7~!)40IADG<Fs-FfdF2C0|e!fOc1Sb<4c)XuVy@_Y!ot6eK_SXg>C|yi@lBGXrh~
z<=ob{b^hR_>T38OHGYmWzA(r@#E(cOa{Q#FBjV>hB>#aN2+e;-8GWpCK#>GqWYi2f
zRvR2iU{68MrvoX5MUomgk|5_7zTEQ@X}yXM<756#&|)MX#>W+(z<bs}2_7kb{QylM
zUQGiH@ci&$`~k^d<>2H29<b{NwfA18{{#)#IWVBK??5Y2I!}9aUWe|Zu1^A;5OCDB
z^PGp}#S-2Z+pWOU=q=Mh!zjI?si#2m_cvcuY=*2X<YQuBfXuG9foihuU<=3Qe@w`Y
zh|Zhv_Ji_A&?(x-3=e=#JDmy|cXR<ypZF=f$e6;y0LqiyZUW$zBghLDpgpeL4xn*V
zj~DGN_*;@MUwj2^MFbrmeVo4qwBxcn0JL;f;RP?q=<YBJXgjp?r)TF8P;&-U`N3PH
zf}o?@Hp5If3OVHxX2R*o;L6IQ^C*8`8n_Jfv+zi+QStcZD9y;<3fl7G+4$!RXau?+
zbPAng^FK!Zmai<JTB?DCfdLdG{H;2Spi#3YAZr6ashz)1iV-yB?k?cj9V*}hI&JO-
zxXN)+@$j@fP!sKAdAKgj)$rSEb{}gO6^|M(&t4V@-_`>@{2m8DMUsVQ^D$5h_PAFs
zXanDm7nf7G8GJ3j@V9{KAfL_;9y2|@|Ml#47x3$5`QX97{<<e~sDO{<;rjI;?E#?j
zUC5*JAm}Usix+J+pp!m8o7cNp#U=<afM&u#M_@cV4%&El5>&h&wgI(ZKpRp)E04g<
zR>&c4-7YFFpfv%HK!a1Do#`1Ut=AVyHe8@UU<Ac#0DsF{aQ$7u3=Nr<AJDoxfT4s7
z)XEEZ@zWY)Q!WD|f6F~kAc6Otg66-vLsVQ^FO_gXri~YaBZJi)RBAOdFurU8O_NOU
z=)8B_Ma2aa#xLi98Y3Xxt)TU&p55*opt+g=1MqMYs09o0MXMFKGJ-W)p#Etw`2YX^
zOVD*MkQfD>J;C4f7rX%K9}|CT)c^ngL5<r!(4qlP(Bw(CtAJ0p5orGV`z_F%VuYvV
zHU1t@9pYp8nZFOTOvu&n<ZE6q4^%pWHt2fxipcr4egmC7173US;luCo3A`!*v>*NZ
zi#5q?3_i@Dv+TRWEI^Zn-6^1jwxDFv`NOC4qethV7dMi)89);(0ie#aujLv3mc5`Z
zUgrsL8UV$;N9P5w6PaBF{JKp}`B;~zMDX{5R}XZvs`eow{OeJ0g!@9y**<T@#Q>hv
zLX78pb8{3Z5%TDEgSV^GAnj^Ui?;O-s2$f0AB+Mu2@%VZUiyKj&0w(rng2rcUtWUx
z(i2<_Pl7}BH+cHPfx!p2FMM0SRkFU0^VGcOWBIx62Q<(+eN+N`_}702B{z>3xk+fj
z=aY;Pd@~c#gRc(k4L^(5jT1Z>?^Q1KWV~1L?e#oR{R4Jf97w*`8PvP=;9q|nWL3m#
zPH_DJic^@ILAehU`k<WW*?G;YTjYe{0gu*86@ng?mqEEOqK@68^8&<(Q$C#^5vkzC
zmPDvKJ($7SG7PlH3S^PTi_RpdlqV<!d;&Gnt|g#(p%t{-{pGel;53R<>MQ}Z&w7jh
zgF?usvqZ(i)$p57=Lf@+;G_a_uoqHs0cz|BdRQI?<x7t`c8Eg{dNBK_fR?I)N}v}p
z3E*O<bk|FB(3sK$-&W*8&h!uHSXPh?NapjvizAQLla;Kmbv!h0dRU$Y*U{%ejS|p-
zupm2L{EvqizW?Pd@b)dxdJD#zmDfEOZ&rMJeE}379^I@<yTR?2MTa4+##`o~^_MS;
z!8*|Ey9kfYv!3w!u0I-7-yMcjcBhOXl^riL1H(60(0+SJ?<>^8aR(!)N8I_+)$kjr
z@^}&c>d${@{orAF)T8qlXy@;Xg}p2co}e2{+&~M=y3+(ak}DKmoUVn}U7a^UF@aL;
zfU>V8Gk6pPw3o*eI*s!pw3mg!$MOY#%N<ZFrJMC+7ub(#P(OY%11+%vjb4NHvbeT>
zD=jw!6}{k%NGR(Kx<e&Ax_uR1u)rMW3U*v7#Bq8A9XE#w?zp)go$p)?zrhywgGw+4
z2K?m#=y*(|0svGDd%%|>zXa`L@#qe-@aWDKfK<>vptVe(mFvw+j3{9R8Z>$#0C5X=
zy#(l>7-$r{(C7hI(Vm?LK?Cvz{C%J$_Mo&3$}a|>h6Mk%0BP_7R?t<`u7+=$9|`cc
zTm@Gk4xljz&^iC$*)3o2gozJmZNUXlk!s-4`O2sB;r|Q1t#3i6jJ|vkZ3?QLK=q&?
zNI!TA;X4Cp`|LN+`7(Oo(;s0aAb9=q(q7OyM+U~1(f>f%@on7!zupjC23NzkucapV
zbiM-h1sZA@7)s?mKuhHq|9D!yDw*SJdA8<};U$oSBe>&U@(@&(fQk(R(0G#vsIYJV
zU3~=#!OnvqzgoPgjRlnrpqk?0i^Mn(+Xb9geL#aLhhD6U0hJS=75LpgDh{vv(<XR=
z>c<w)!9$R>az3DjBO;1GXSjNFvpRKvlVAA(NERzM0cWvpP%(&5`wO(50a44od;sG6
zwqD}z107NB*Bc|s;A(j3wX9F)CC}zVj3A$tD!{$`n!jZRD11QUZ?G}E*S9Bt{0uJV
z9(pi`fabA418<<y+<ZD?R4iWHjRtuLB-S0G;^5OAqhj%T4LD>#VPx@QsWGTw<D=r>
z*?AO{IKa)ymu#pN5fga22a=vq+Q*G=z^(euYaX4a!7Wpl&K4EWtmKQYm7rXG03(e$
zg0?6#fQL6fzDW2FA0LU}Z((I-VCW8z0IdQQ1vi&nR3bp5av<{{<Eb8<H+{Mb1YVqA
zf#x|E(Ct5;p^6h6!Mln;JF`5JA<ppZWjW~4%>f#PbO4pn4xaq$`M}*7k4_Gc?r;mx
zwi6G~#55>Bb=Ke=&6)K0&wn4N!5-b=3Lc$5K}I=vbRGkxtqKoNE9HP!r_CY$mY<-c
z-(4xte1OphRM2&T2Gu&xdvtqRcqB(EcqIEvSe~dA@R;Gjzh34L=*)l6Wn-UwLHCkr
zF@Z1e1C2a+@UQ0q%lcRzDE$OJ)X7IBgTD{7+XR%*9YEm=zPAUm(aS}p!0;_-001;^
zRihG67dyeV<v*mo?%8eT(fX~<*theMtKnPten21434=F0I)A;`70Jy2%4(jShddc?
z`B=UyeeA)%{<A0J7Z1k!pk(M_oulGVx(*bO1s;q(DgmJD**w6P?|Fba(;56db>Q3q
zTKe711PT-f_y{5s=qd;&4v)@@&;!*gK+B@;MT4?n2xyTDx_a0mT9}@f&%q_Vhk{4v
z@fTt3EZ~)5ptRx9{DTpmJ{<X{9QWuv=F?p+@M0mPI0U&PfxiVbVGRni1kj2B%tRu=
z-x2|iG#8Z!Sh@M3jfKGjG>Gk@;=tbm8Uz9v5aH1)`fd-XQ*pzi+d;vno5Q1<)w2b3
zq#VbKy#}C#s#pVnzvUFz2UvZJ96E-#LDRd9M?iTCrK<p{&po?M-n}#i^$EH|R3ct)
z1*HJc2r<LU*Pzm-^*~*PXSW!r5#?fd5_A!si;BZ*VMP1Xvs>gCNLCG;=ol}0S{?x1
zFW~~30rXHn&NweGgGZ29^P0hBo9!M***06Bi{T~Yqy^9#c*q?b;PtVfz)3JXi5|8u
zyFuo3#;7>FtbnbGLAVE{Jc0GMFM9NbsKoem9(V0L^P*}AxRd~&+5Qz2Mady5F&?d#
z>NGu?K^J9gWCrDz*FtIF_N8ZY%~1vh{+8LGiA~T}bju5+ufb*0i^Nh;nFKl>1r%uT
zW(ET&RzOGG-F$KW7uYKBy;p^xr41n}F`k_V9e02-qfh6{7w?LpD-w_Kx141GvH$b8
zM6rOD9y(~aSi4K`w^oBJ?)F#k=nXJ<QP&EYNJs;B=l(G5Fa%E^2#SK1$haKv1Wo6I
zije>daJxzVA!rQXut)3dl3LIPX`gOy0r2cWa+U&g{@l~jO@hDA7-R`396Y;Qu7M``
zK!>VzH-M(}KnK8s78NW86^oV^_<LS~x0(N8<Zl7p1jXM3nxAxR{=>xI3gUzAzib3Y
z@T6Uk2;QX&s=z@96oE!9x_wk)T2IzF82*1P1WJFP`&wc=K=<ug{-{&+?DqK!+Fn!g
z0<@W>^bu$&H%Jnc$CF)DVmvH=)Zg}K{RZokx`Ngnb-sMDEDbabd%Hvfv_})vU2=wZ
zmy)5~B`n7np>~`h@$I2`!Nc-U-4EFMKhN%#W1s->={yO#gR*-9C`?{l3*lyP><$y~
z>^ukxPfx~|pyUr)t>~t}-v>I%uh;3nZ|^*iPT$@=$3T;GuNA=l?VbRhYHW7UVDw-F
zo95Ykn8VldcZs=YH*<G@fJd_fXi;Fv)rK9ARew4j-4j4_(javn-LPqEuvTBo-=!x(
zE_i7Io>+8X052r~&9}B*s#pe^?(Jnc;oBXc;cGnsbhd{NBvNZ7UI#$@>(d>m;A1@z
zw0^I~*dzIrM=#F_>}v(C`gDR5#7j_<1*yCT3xaiuoB*{m;4{fV8ZaH8dr+Y1&7(WO
zz{7e1C}3)pL9>7!odE_O-4h^_$Y4*sd=2&sq<sMLJ1FI8Pk_v|IzZ=I5yAHobi}UV
zZNqObSAf>(HUD8O;pK16`U{>>2ko%&V7$QJ2?`$%#tRjnUTT3GBk-Z{Y>>j+NR8$-
zfB*mQb^Px!<0S*QSY+K=2Tsqkw)242t#os|c%j9`@KO_0Ja*oEksZp$0GbNq2cI?M
z((R%WWBAs!^+3JwYc0@vY;dw|KFa7}`JztJv)kt_din-kIdl^;#Igpw-1g;*>&c+x
z{GY#NGN>%E{LSA2S{v=r%+Bc1%?w$u1KQr=(J9Q|Y65acH|WHu8qh=?WLH0ElZ-TI
z1}H=&2Gk&IW&o|ZdD#xy4b$z);M(n`;oIwH0N$<84Jj-@bA0$FpB~==mnARPgC@c|
zZ@dH@T!|EF;NczkTqt;pFDNKl57f6q{03@lf{MJ~Nk9L;tOfO5!R0Gtzo$XBqXcMr
z?Yv9pv0fP_e$QK-HxIs)Z#l`|3L4L`Jj~w<4vJpUqHR13paIyFd5|$t(D`W1|CspO
z!Sdbi7N8@bIzRYyw;bXCj{zPi(SaAwAO?6TpsV4@PSD)W3)zeR|3i0HL)PPaH17f}
zK42&*X#NK}MsLnK4u+C_KE15Mzt|Z(dRb$FIT)J%F@cUG23;}@+K)K5Mu5Sw^MXgO
z=-#c6B9C1Yx}E9uVvlat+8S{BISiFtr2&&{<CkaH0bXxe32x`GdP7uhfU0cJfb5qB
zUD*XIkC0YlHopOH)c5Hw0w3Vtd2JVHZKQAVgKiI*7f)KiJN{Zg1EI~;5{&%)p!s!3
z#kC?2RB;^ux0-Lh_|*)qq&z#1mQ+JqDxm3?3IYFKm1i$(>cD+HkItj@Ca;UqCcws!
zRUqOeVm{q0_kFv0R6uRb4p2JtwLDQ<=h1wa(Zlj?iGxSC$bFC2OO?kxnMG7QIz{fk
z-s{oLnpF)B5_hOaud9RlH_+X$v5@{WXiF(*{b_fogeRy&y}6c!0n{|B6L2*=0A8pK
zN=<t~_jz=_K-22c&B_6>fdgtosXC|<0-ZB99Weq1?!tpkXogt{%CFt5sa0Ud1#Lmz
z;r2!iJX+DY0dzQJ0JsAKng(Hj?)UKMc9d`h?X0@&(Rtpb^Q>d934<fQ=ZDTu2Vcpz
zT;gv9Exorq#@`Ey5075azAZcqFBZ&(q~ZSzpbKmHTOWe5f49GdYqz5eXxjm#o7gKl
zV;2ttxSs=VH@s%+=JIGhB;jazg1-ecn**wPJeq$9l|J|Ec69J)-T_X){4MuDnf|Ru
z=S@e@dZJ%1z!TOWHy-A1=>e_&fR5Qm)_|r1K%3Y>_qg@4YJO*D0396p)3fuX2Y9p5
z_p_iiZ`SaW@`X!<P|pzo?eBt|oe>{<*rQj(!K0UT(@s!k$hp7)T4mW<`v3p`moboJ
zo>K`9;8~kN3OHWORE1@TJ!um>dUa18;$V0QDo-HwC95q&dBP@$@>Ou<y&m1H5)jE+
zsH87U61=m8UmkkCi(~T-rp^$R4E}adc>y}!!UeQt0W=n|<pQYg1GOpAL9N6LSHlA@
zwtoX>36IXh{4JnZ?haAOa5X#$T9<X)MFrf_gBK;B;lS&cK;c8|A%3tJD)Dt}{=w+c
zYkFc02SZ7dN3ZF8NEx%jpMwG9Vh?_o58xY53=h0UoZrH#TLBKf;*F5-h*AM%p4W>!
zx>>m)G6hf>2Z&5Z8q$7mNO|kv3OdmD8t78#0{&J|d*7!!(89IbOU4znx7i)kEbbLm
z*a6D{kc7v@FVEo8%>+t(u9gR(n^Qq;Vo>6H<_TI}0#AH~pxKH4pb#wpg=i{l>B3=t
z@Yx2Sda?j~@9Lo!nxGm5lrE2z6haH27e_1MY0^!=r<b+$Cp!aZ@uw$f!0IL>RVISU
z?ruAHsuU{;^5{lRq#~e13Q`N&m<wIT3OY&AAvz9ppdct_!CU-6oh8@`G;o;!Rsd-q
zfsU4e8u1Zk#OoP|{suI$9|cuQ-8B~kJX-(rx3Yo~`<s8D^Oik&Z8eW^Fn~8PK+|(>
z894rCZ-B(#EG1C<!OmasfJm-g50R{eNP<rLgSZE!f7AE|Gz;z7d9HJc3h2<17jg37
zQmSPdxLy451)n^4`7P*Tu)ZcxGpg4Fe1AFUGy^6@sN7-x7DiCtqx0j7cM71ziJ(bC
z(3Z-_pkBdomc!s4&2bjcBro^^OApKArOyrDx*9$KEoKK<{Mr;&Kk;wNkajrmmZkYA
zBWQVhY&@t_bHJ;U<r$>E0G?8}e9qq@40hrp&=gCD9M~n`aYj%R$nX+mbP{w*11!IR
zR<eQI@uK?epZ}iS;$EFBk3sUFv+qFdZt;=`&|>HU-_|E3S{~iZF5Qk2F4hhb{H<A_
z#M~VK+MA&8!nOj^fdZY^>IGht?PvjNF?clZ0yRk)O6oy7c+LMq7w^2Z08drHrcl5-
zT2GeFLd5?IW<@Rr&=Q8$1EqW~{wZ)VfMzUOL0uukx3489cy#l;138Qh)S&^LhXra0
zzAuUJ=;nD162A`;FTDxs=zto67hvrV{#NL0k$DL?wLDn|S|#wnqnqQ!N(C;4*X{83
zv?B*-Fa^{@vV32<0yGL@0E+d_k1sUjK`G0l@dzlDp!EC=PrfLQ1g$dnQ7Hhqg7w80
zc`k+*=Ah_rJ;2{m%)$U!DObvcs4hL5byOJnTR~e_!MmA3<Fo+=FGWG~fbjL-p#EPm
z*u`AyAW3+aJQu^utKcR*Xg;BvH5DSiYb`{67TA?9L&0?_132muBwSmc@VC@}W6ndt
zrSs8?Ev1m^pT8v@yfd!_oZvyVWQR7WzubA?;0t-sA=|+$3=FQ8NBH}^Kxw+0*`u3R
z!kL%B5#03g>2^>66*0$MR2)F5iSVY87u8q6bpiOIWPb28-z!j&-x32(*x*rwI~<_;
z8&o3{fDGktc?DToui()w3_eB{v{WS-;$n|(F9n}&lY^e!J}MeMy*!ZY*v)bfl$fFW
z1wFc*EIgWjayar&J>ZcXpkR35wJt1wd35s}hKwIT2LC)2EKhmx`&<M!0xXa7_c?*~
z__ZD=z2?)+a@e!m!vb_THGhi?Xd?BSgCnCyvZn%nD`>qs#F*FnK}qJX3>U)-2RSZ=
zmuJEK31*k>1PM@Rd35vMbmV1l>3jt8p99E$ut0+ZDW3Ie4p$IC2U!^GAOKoVavWp|
z186uNG+vLKKNLYp*~9XEi3ZO60U02AeGQuaLGuLc;CbZ|36MujWI!d@#}_&>Tns*)
z4_^L*ba|i)<X+za^@V+s5BgiOaDjr?m4DlTm%Bjyykt)WNPvKEXaOaxRwK~1z8ui<
z#T=CkP%Eb8J}YQ!$hY;IXZKXlKtLU@M<)w-MAg&sSm|e1!~d_fVLetz=iaNE<(~(r
zvkzV-X8E7L57YvLYWM5r`R&!s^Ut^QgJ(CWAnF7e3fkx7(cJ(lk3gF?_+41dU3nS6
zi!M97{`~(BGP2tPI!<u1q#rg;AOW%&wDSdZjNo-^^H0W-n%0y29TlMVSMo)lUY-lS
z-HsZ**5LC#YaBfeK4NZu$>`I|BH#%<I@Grte3+<@Cb)aw{1ddX^gqOI55_}2h(kI(
zk}uZo_vjV506NRkr_)Kpqk9r~gahLLmn<MVyAhrKNF1I1JD>%i`=p`GbpDo>-~a!=
z?EDS71Ibmuv)L7NJZ@>QXLl>eaL;B}&_>BtaBwxhWrQ5$3>{j*GgJUNQreaA0cctQ
zRBgRH3NpW8FL<1Vza<r%ZCgQOEwJ-oJsH7vyq@LJ&AK%YT&~?%4k@>kq`4Sg{{8v?
z|BDS$pfu;AQt*-;l-l^$UjyCd(i8;h#2)}P9xC`-CjR>W->Vn8Pb3{76~Nz;4_cnp
z%L7{3$nav06KG)(cy=km@Bk=(h#UqD`hd<m=AUv1w82%R5t`ZSAAxo^B!CuJg8KoT
z-#gc+%mED<G}owPfYwEWw%Q!<ZT$vX(;H9+zW*3Gz4~;n0pBKW_|~)YFL-_LYjsc}
z0<{z%(dXIi@|FRdejzzCM<s#3Zv(ho7J2QF+ygF!!R1wVkcLlkf`U&s&nZy5uG_)E
zvpeK1gHQJkP(t?UZUV)XPv;|-&J-05&{VjBZ|i>_eiz#)CtijZrrZDg2aWeebhE5z
zJy06#)6Mf5yeJ|BbVSxiN6=<t{*FJOrMw^)A(B6Ti#O=RWav<t9?12WS>PpTL6>Xi
zLtoH_tVf{6kL!*<|6k7nWsG`I#*hakQlyMw3C<YxE@=~p%NqB=V@jZ)!pIx@@Z=59
zKq1nA7=JIgcLLrhfiWmn11h9I+onMaM?ul;)A<fGUz7ma0s$J@f3YwSQlkgFm=0w{
zyx8l&&G1t6$N&F6o$p}^LHlO{Ji4cV_kKI><Nyb1FDQCIjV%xt96c`<ZvFG$u^XQG
z_*+4)!<qqeR5BP}wu37U$mk}XEVu=H87U)wO9&(65Mmq9aDMUy&t9La4B%6UA*GUM
zH`qzFN-sgzwIIeD5hV|Q4|oa(q&4I!1NQTXFL-u>jd^(uDW{h>fqVf@CXiE~p}8D<
ztX(&_zz6Li1~r7jfByg9`j)@dA9PS_=fM|e#kd$=I{gIQr^?9R0y<_GG&T;JiS<c7
z;N2T?l)<ChOT)vm3pCgYE#>Q^U(RA+fS!lw+3lg=2|2&Hrq(C<fPb&cQIOj`wI_f#
zOaJ%}D}hU|cy@v-nU}LcsSDx{50GzNt}=iMTMxv+!7yKb`1Sw4XSb_?r#1NUg4#q-
zN#WV)YT()33L0UBdGrKG9mI67yIqblcr+hm^k9ZWU#Eu#%x=)u`xo+J;08K>i}ct3
z|6hLjinLx56p~B~44&Gppz&GH<F4TGS>*EhWi-e#Bu9nea1<zIOaRRWR=|?DN9Vt8
zXo&{eRQh7SA1sA$g|Z@E+_vRrc<BuaA!yZr$0b4FMNTfr=V_z$r$8AAygoC~!n5;?
zN9RwM&SO5Er(ay%0dC5GRwcH8wr_Z}-sW#%0BuS5$H?FQ9JGp|SM<RW9tM|g51E}J
z3=9lAxIl{(Kzn6R`Dh;UxcJM5@sNw<iDK=S-x$G(0Xn|jdBI2XfXBrjK8y!EdU+gN
zEqPAyH{Ar4u$_l|EDzP+^KAYh%-;uE@aWO)iZr|f+MMdq%No6ehry@Y<ikGDoRV+r
zH~uLHTn*nkC>-N&1>Zl>?8*Q=coj6k49el4))%Nd#R%%&b-sFG`2^~><NPhgpgkeb
zaUsVn76$MIgrK&nf@kOP7y4N&44#(9L5mw;2Jz270GWe_G@d}09(KNB1%(WF<mm2W
zu-V|&^DHJ%lleA(OB|?Lx&&%Zf`?K-ZUJdPHV4#{TL{q$y1=$q)MOD4Lx~iqS_YrZ
z%h>#blfMmoUUjdi#UfCR%*vZCz+iYA)WGcKc;O-pYDws*F!Hwqg6st^y8xZc<k9-J
zgd2Pa3V(|`WN&o|H@E@G-vZwD(R#bY5wtd=)Y=2S*23_>Ykf%n8?^o@4crcBS_rb0
z<Hao@(Apr-&>|P&@D%XQB2Z#N>2`q@pLL${>2+ZAw7kIIs{|_2J1=;2UPMX)EDny{
zEQekm1t(R|`6aBKi+C8kdqo^vEO{>Qw|)l|vy7j>(e2Y+a)ARL=irrt;BL-~V-dgq
zJMI7lDtM6h<qOfH(0Dk?-=YkfiG;>+YzA^1dvqRt;hh1Rq(02wVhKuv-K_gl!M^>r
z05<#aN|1};<w9704z&8V{W+*#)GPX6F%jus`gN8EmNZ`!<pD|Wk3i|YUeu$Pb>d<q
zf4A_0Vi6?+6oP`Um(^=AC<Ewx0FP1mw!U@XpK=VeYzlma0w{FB0q$dYsBS4Z{ILW!
zc%2j|g|xbWZn=5uYWNm31P<SvbON-nwc8ciiFkPv%ym%#-GU4{q-;JYO5o?_fX^87
z>2_D>4wry*kvzJ2r<(9GfEsH=98>Uu^Ef!Jz@v|rV58kFK$!)6Obuk0e;#O^Zg;4L
zPcmp+!(Rc^AJ_2dmg)|d0IkEx@aeVyt=B1dQJaPuzb+~XFEZ0u7(gp`3Ou^Q1wd26
zpxs}fJT3rQv6BJP2wvHf0CI2u$Yu{nqX2YCBWP15NCo7qZ^!@FK+9f08;DB99a=yu
zvOrCgPLMT=_`y5U6F?Q@Sx{O6?Y!d$k7+}*+f`7@qZyn>At$ba&wT+cRshWfiSxJa
z05uJ|LFada&Mg6-`vPhtCcK;vl3@Jg)17mH13lgu!CNm;gI~;;_~7q?WEGFj!=<61
zgz)y|7SP4kr};pQeCW~~&^%M?HwXTy$6kVVOM!wPmKe;yBS!GF0=jh#Q7pU!EqwxQ
z*)x0#ipWyo7bRe0kAlQJKxudCF;JX>&$j@N$ongRA~eCL+v3H>6y&%BUEDoC1r(DZ
zptTmxpt)#Jgn}ay6m#IkJQlE+GXQOvhP1mK|6c`J2XX*^E2vrN(DIGH1-u`x^W}@z
zyj%<~(?D6PoAq!aIPdS61IzpGK$76yDc!8gAd<i5K#IZ3AgM0!&RPfL{jJEShd6+?
zw1Q59?mP{?r=jmXBLjnTFN=U{>j4*jj|0xVEP}4BCtdhGPPl?*H$dn7y1++vnn5EQ
zpmGy*Lz7GA3Fv?iXal{g<wgEp(28-7?m`8R?rIIs<QJaF2b+H}_;e==_;ky>^Xb-k
z@6pY3%%fZ9IDa2#^Q%YlCD8g(%ZvQ|pwwr0!0-~kJcFa<ff5Br%Y!A-KHW0MJd#f}
zA7b?Bj5*`r(=Bt{r*qC3(D@0V28^TSq54aXy-xpp7~g`{R)9~&@AXk}aP4*a?=i!t
zv*d__N9UR&AobnO4xsfIpjG}Bpv_zwouD<By)7yrNl*t-;YG{dKalO7$4X+54$bE+
z2Tc)GST?3Xu8r&b;L&&l6pV;^<uGX1j^;%V{`H4E8IO2cp7!MTJMGzd?j`6l;|ZY2
zSJ3!2Y=xxZf!BLW`H@tC`sd$ofkGnrkf-Hg{=Uzk!o2g9r{-Y~{`D7pJMVciUh%QK
z>BH~$@#S?$x>y}AzyLZ@2ef6OdNw5fg?T`OjW1(CJ*jTi&UkRjF@s8O;|5EDZg}$O
zX3c>}KAZ*7ITIqO3>rs7KX0sqnSr76L}!o61#n|!ipmWzeGzm_Ndu_W)p^LH7qXws
zr?&+n+q(s-x<<vq2OQF!F)A9KohLw3+zOosUq~c_&wK5d0Wzx_vI_`2yrT#zrW*f(
z+git6RKNu;f4?Kh9*{B+o!kO8+_U*FBlNhB-X$sxpms#(F~dusLz+QrmXCu<1CQpz
z950p_fsPgK0lUn#*YBTC_Z)DS+qXAFg~PM?h=Aw8hs>Ux=i%dft#9j;d^&#_9)Pqr
z3{N&#G4M}42ugB3jITTx&v{tBD18aqBT<(C+KdG{+|2M2r1b?-<Y{>rw6hK*Tq5<l
zz^j)>$)ouY2k2x&&{T~zi?By0V=4GZ5Xa^NjGo6?gcv|W2K?(;#62~S`&ga=?XTVg
zb}*>0t?=ml3fjB^-kf-j6I2Mk@Mt^&iWo#11Yghuo=@>jKH$f^=LjTjAf~+3`2YX^
zi*ArsP$+^d>ja(01?v6!Kts=^^B8C{Dg+XQKE1`D0QBvxQQ`1tKF;wX&JZ*z^1@@+
z>QxW`3OSGOk3bui6F{~4!56F^y(|tM2OqF_XubetsR(f3KrPGY{9yR4`2~~5!3WGB
z$pVlhBq>2R@Opqw4T%7?HJL%X8GCbN89XhI^0$F!4?1g99A1ln*DH81Uh}oQ>(hCI
zzilGO@NNm8?g$Q#{ftoH1G=lc+XFgw>Y?G)D<bX5dD~<6KPd2FyyVMy%cnQOz=!da
zFXu%c#zVfGCp;KW`EVWtExz?Q_{zeg^=8R5Q0Lyk@RH%l1`AjM0I9OPQThhr2yh_}
za!Gp`c<dY;{$O1mmPgB^py}rlSUY%((u47uhvm`IH_bIFA&mTea^TF|0zRtG@Dg}}
z8MFl31JnvA03{_4OVGeI=+q=828I&Z*Dn0>41T>V;Pm9#4W0_}v}O_W>|`j_1TD;L
zJ_t%q;z-Hqpr_@f(lelQ3qXPW6121ibWAIA&lyMpf#eI&`eBckpgXQX3C`mscoFpR
zqu`YheV~)vkmfH@`fJT^p!cAh?+%b@y~N)FI{y?@zjQk|H2-4s=w9)Gfq|h;8*=Eh
z3gpn~5*d$fPlXrBvEYRb{H=YUY4QWFgCOAr+A!^E`1XZMEDHmuHPxLi(0Zvv5WK7k
zawc-Pg->#pg5fvN*lg$Fk|UtrQ0K4zS8W(Qn(zJhWqjk&{F<@!CDIiqkOd9kJi_47
z9Vp<_?GL*15Y$G5-GTyB@)ER}6LjbWxKjjLX}1G(EYU6v1}5;bm)do#pc4<l(+;5J
zpP*Yv4!&SlhKe5Z>3qrG@`izd;l*ZcR)&@X{4JnC8*m#A6fHiTFAcxF_@T?n06r1c
zMaAHSwjrEj@#3E`D+4HhIKanSKrv$A(`^BwEquBaK(qsBM|SJ&5-EOp2Jj97B;P-W
z_}-`UrQ`o=tp`f?gEV-+3y@w`(6Ic=7oiQT3@=WwLWdPVcjS5;KLC#K<KR>ouHn<I
z^%8W08EBP<xHc<;hb^dB=I;Y-6MJC?(%A`G<piqaUa&W?GQ8dg&Yvjhqwx)71E`}#
zcccX9j=pZtj6XP0yx0tCS%YSsT~rGAJ4~1u7+P<G3QkZi;%~76_cnO%X@IU!Zvl^#
z`6NFEg(ERjAiF?u22u=OYy_(DBS3?+p#I<s?cLyt9z59z>clnwX5{ai#>~I~o%4i6
z{H_#mlz)8DwFVrypgG)@U{H<KdGH0B7FdkG1++I1lm>pjU{(YRfm4PGXbI~j&@!o5
zRj?>1P7^#jfAY8Vu`n>an63#)8=#Ij$e9_Sv;o@ce((wNi(A^P44$3GVEZ`&Ji6U1
zx;<n-hlpKbW?*>D<<a@m5p;}IiMnSuTZ08d$ve={aR4ZyL3Vg_egYl4^8vc|JmB?t
z&<gSl=yt=57hTMtI^^ezpgLCQ>Eti|bAl2zcyI-DsIW_~3h2-VhSuA@$xrzEI6=Po
z=F?lEQsC2@qf+r&#j}~6(WmnlXddoOF1Udd<I!33Rl=kB7$a!w-*qO?UQd4xP@C5Q
z(g$<wb_eynz@t;Xoga3AMoT~uQvtec1>{#B&<U3wy(}L<VWsh+WhXeAJUWk;PK4~)
zPy&TLs1E~bPQeaI1^4qoi43JK^yubYqJ~I0pddy`Hn2G}h|@sQ;DHbj1Ds-@=?Aju
z9pus%Um@d9o}I@_dO&*?K!IK0)14;(-bEt>YPWQUS#$@1O2Jl3(2a5Y?+>^dK7s7)
z_{1;3dwDt!_>6S$0r;Oh__YqC@#~%7Z&GFgCB56Q_J>dB4d2cShL=Fw!hJPw_%Ock
zZ2rSoYUJB_(6jmBA5X@EK9(nnmAfrk|Ch>obRK-o)@|7Ot(4QF`5=p@<;n7oplyMg
zhdeq@_*fpQ;d?Czn(pyoeBfz$p@ajJSl)YfUhrkS;cI!J*2S~=7>93f1fy@K+YiWo
zQvUZRK{pP3^5oY#1#+Z|O2H@oxPu@M2u<f<06V$a7rYhp5`TX>*xxRoqtg$7ZhSiU
zLYI+?q4hR@>qgMMzTlAS{tHW7B@&K%K;5C;AaQUn9h5^(SF<vJBe>N7JctOJ>o+{`
zQV~=XfzHfh00lWHwE0`SK*a{=Xn5HDB;Yd9O~I#Iz_alesEDc)0rl7dUd&<uZG{2P
zUw~W)%0&(`pfP1}sPp?A|NsAQ_#dp=qw|wb=ga?BTMmF~-+&T!&rUl~=ztbK`!YWD
zvAkY${iPtdYYFWnzwiJrd*E-a29HL7I>|XI0iX@Hplh8#M}Q=O&uasnUFy;K6V%~P
zaQuJShcN{-qXNmn{4I%~j&$cI&u%`D-6hXnpNA(JP-+Ax7Vri%SbNkFw2cVlJT{2)
z4lsh9ccJvz%OcSJBTx9Q-<RjXX8(K<2`Yo2rFS2wE8PIf@0~6x8816PT+b?2hL@F~
zuueV<%6t(opMv)if=Xfr`29Z)9-W|TOg*~2KsS)PDud>vkNS3=fovwM{mltJVF$da
zqM4ZywB)fg88nLc8Z>g>tj*{FIxJ})sL9s)tt8(Aw2ra!C#bLmmDRqT4;?#SyvW}M
zTE~U7qNvmZ+xj05(A`Opd%h=tM+#AI_vj4*_kCvfLAp1){&6zER~3P-?=d|2Le2Fz
zsJB=099rn3?No#m$A@0@pMn-bhxuDU72WIY6FlH!lHilWO+eQyEJSJ_LDwT%bXQ7v
zbVmw6`oozTpmUwT2QYNA`E)aZmaTuk>1%nAzaO;c(#P@ue;?>%M_2I5o7b#9mIvyL
zeHafw_rE(fA7u37U+*Hy;KO*>#qxYfo@etR4zF$&F~4pWA<xdkp5Jf#THdHV;o5q#
zLJt&$3Lf38c7fnv5blHo!{@)yV6XrcmGJvqJv$G2bh8RU)XGEE9!FIRTCWExRyuD&
zr^Z3+Sv;DLfKBrF{{XbhyA!$|0G?h9JUY+%bRO)kmGJ0}74YaTRq*Lf1&6~)P$EDN
z2ha^2;BYt#9<~RqKzhvqYTsBMs53(i3V;6fEFzGQ;BTn`k6~d8jiaE@Fo1=IK>#>3
zSUVu0@$?TTWa%$-@i8b}fZH#S@L+<d=7*}@j#V`{e|U7eT7Whtbl!r74dgJPBhZVc
zAffXT)Ik7Wk3PYtyAd?M?VB7R;o0pV;M;nsPSq8hxgqlre%(BW{P@@R9E41>A7J!h
zJmG73q4fD@==$hxM}@;k=?!|ni=zN&m(jV_1NB_5b(;?}TE+>~sd^+I_UP^bZ=V1y
zGD6zZ(R`Tke}I8yoIpKn<-JFD19&i``G`hzoX7tMu=*%0*rV|cXfn;Cd!`2$1A|ZZ
z%m8l4JVIY1DD1nPH9VM^Jgu7@*cljV5<IP&J=hr->cf3|y8}QM6gR(S1g*j8Em2W;
zt&}#wyW8ckffuvOAr9ZpQ=Zn0HF}__G|%RP0-n}R9Q6u5mWRDMS&o%n2bah<9sf^u
z;9_9#XgmUPLv-9>kM70@ko^b&u*nx;?hOY!7`&tu=HQ872X|ig0IBq7y<L|IVI6$T
z>}q(xyW53H!;6`P-M@Q|6UYz#-91bWoD86w(0nv+dUT%fIQYZf!|))8HPiF^PoK_H
zpn(|=&5J7-OSn9nUov`Xp7iNF>BD%_tCNS#v-tprkLBUg<zNq7bo@UF>H(0OAPXOn
z$LGM#1^LaVdm<!!J0Z@!?9&^gq5w)C?qHVZ!ADT%GJ>4T?A^V^5#(I&?jA<4b2Y(7
zVEpu8ya>8&hu`C(2jeI2P7!91gM2Lyl^*r!yyeq*(((U9sDnVZf-k8-b`Sil;pR6Q
z-Bl7EotHg2&w*QOpu)Va4syRpZ~lLu<oEnj+dwNfK*MFwecT?M^FXQlMVmhh1L*oS
zHwBO6qn&vI9>-gbX|OPWZc}04?*rWo=h5w~-~+m5Ci%T1XruXUk8Tc-OTBtyUi|Ru
zRXO3&{F2e5vk&A*&+dR99-Y%bIl=>UhFxzT*u$OEKr^-;z0*L!@H!RRe*^`8H-|^_
zApwu(gJ2^)nqPDH_6Gj<>74lD`~UyG-5x)DIy+zd`2XLRfBh-P&R?#Yw|tW?fy93P
z|L@m5<r>JTj-4-k_}2$>xN6??O+M+@IprKk)Z=&)XjcjYc%`_2BWRWVaZm-u;A8o~
zx7X{xPiGegX#B1lYGV+GPbVjTYZ_=&u9x*cXr*nhpN3yA%Uh5Uh%1vlI@`dp0>2Ge
z0CsKiV|mcf3+TE|@T~=)jw*8g2j3THc)+7OP{G48P{O10bZr^5jPd9OFK6=X4zPIf
zHJFV7=}6X=PS6!5&}*(+LG5R72YWwgA^fEZQ^>w0<fBi0AcvjS8hG@IoCY1c0pDfh
zr2##=)B|)6;bEk+Mr)G6yOMZL<J`{#KA-XRF^_J@d5+D90~{fSf%gMoI}a2l4LUCa
zY=}qlsh5e6`%QukJgg^!*1W*>Hw7DbbWaA&zI!lE2CcGq83Z1#ft0r}yYZYQ2_6`Q
zl`kHU^4p{HRKqS%;%DggkSK|2J?YWyBvBXS(;KDX((C!(xATTyZ^$Ww*P<RXL8;pF
z`%lkKhabL{7d$#Il*ssYcYtmr^ld#^dfyYW8V{rjRL(!~>AdywddHvt(E1c)B1q^6
zSO_#98EDY$squ0Pln;)75741T7d?7K>$-UuUTpjbYKxVKdUSV#GNa)oaA>_eWXr|?
zy1yRGgV+Dy`Xd7Ft8<{$nV=&Rk9b2CfO~krl4O8Iw+DC_{o6tC*)|rXWuW`GBtiWw
z9~Dq*72LT4F~Gek=#VI=i3dvSFO-(S8&fTd!A*c^Am@QPk>zv2n`Jsc>CdAZEd0&M
zkp(g~)R+t%dcOe~tU28213DzpLBOZi2Xy!!?@kHG?Ni{c8`M_N8PzW~EQQ%vVhS}D
zw92!YiSdPL{LlZOJ)$>SFIBEUxhxFSyM$e-1#UJ*M8_RQtT%?tBiwwkBol4`e`hkN
z6}S`JegL;ek9)vdiG~NjTPfh<IiUKf`Hg``=QYDiE}h3;faZUoBUzRnou3>#e}Dp{
zEC;mE0_%nb(Df70h432C#>-*D1Fye8(+fO3ba#S7xAkNRFL;SFJ9LRN=%jN{PJP++
ziIX910yzFPKnW<>Q^2G1+>6`q!Tq%ogVt|#I=x~4eR^50f_iPB*%=q`Ihn$s%mul4
z&PPB3G`Q_!d8qUm<eoT4D+Li=@b;jBN9S1&upOsgltb+B09^!f8k`hd6+En6CHQ+m
z$9uHi=I`reU|{HV{%`orr&r}D$okhx(DJ<-a=$aAtbpYG=3^Y5mR~??y62dJ+~(5_
zz1$vrP&K6d^MjOsoi64Q9?j0+4W3(|XDpXQdq6cbAL9V6aPUZWQ1D;`o9$`&rF4Zy
zx2pnpJhszS!K3pBI0HetA88Z7H^gvxbi?MV!AS<Xr|B@iJo0`}{ti&V11(!UyB#z<
zEgL}98?<b#6M5~EHo>FYQNhEy5!6_yf$j$-P=3Dr1KQ{SE1zJ6F=!{L$Z3$Pp(V9P
zrxUECehE548k%0fS8PJ=69<)-2N*p%G42uvt$%`<4+<*K*c_hwzH^Y><I(LY;nDc>
z-~a#hb*wMlK5#O;-1&hMv=|Fg{({qM^Uefr1_maN&eJ9S9^Kub2HuNcEl?Kd1~-P9
zH5p6Ppv4)eC5t0P?*Jt$==$V~aQ`)ejp%LwXNPVFi{=U$!P1!?-JKw7Jh}xvnza~9
zCxCADf*fY>vI;a22J<g0f1CsD$nF)DZR25h5%30Fz~*$jfm+?r3+Y-9)OmvHtK`Fm
zmq5(|Si>7yUmSOoU;w4`=7Sobqx(EM8#zEX1vtKN>2+ZAO+Emcxq9(koSVTqPM~I&
zM>lJ{2jmnLXtn~UE6@##;8F&WzdRZ%B|w4e(e0^F$NKW=J5Gj|5$`z}(A^I@(&NSX
z+CTq2nt%NF=wvGq1JBz-O-GpbVlyZZTMv{xcySZN0u^MvqI#{MH6Ebrky)QRK~6?k
z{2tn$1UU+!A9a7EPq*%LcaVC>Bp+x=7wAso&TBrM$9+4``B=W>Z_x)0B6Yrc0m>Yp
z;Tce4)1$c-wCTSebjn-@Xm%Jps}5E!23GzVbi#$gf6y&W{4E_Ip>B52P+SLSoxO+U
zv3d~?@Lv2+9tU68dw|BnE_igZgG`YCn*zEd*r)T;i@X0IM!13(bg+Sq_z8+9%MW#I
zo}Ff(S%hw129IuWkJghFNhPcvmWOH+K%3M->m6r;4#WhFDtmnY3Ce07oy_2Pg64n6
zSjV`-AUg#-jvodMu7j*@bpp2q-Tp(xz#ESc;pbs_sNNeiI|eou(l)?lrYpET4K@^X
zBcDg-XTt+8LEAw*JLNn&Z@dKCq<I14vX_u8lMW0Xj32<&4Lg4)Xio?@ltBHPPWG2a
zLE}drj2|jpJ&&`2oC}*0cn@A|1j(<U`>!0qU1{HDNLM=QEho}?1IT__&>?r8oop|+
zf^{PIFQDTi9v;@bwXUFZ*sl73R`{KVTr25e%^U72z`)-ETCnNS%_`+0z~Eu&$id&T
z1T?3@UkyvY;DIUw{+5HFeUy+>K|PMM{RIW>aaT}AV`x24Dhyi60=|76eA^eKzux%+
zbnc+#Vg4S_*u974ef~bseSV-bQNTyn-bdDyHo@?==WzybV1RG-2491B7%cb?WEqkm
zq<#WTcx!-KCKf)BD~Uru7i9l>@#GIUp>-SqC9Y;WhPpD)gr~vFNYLD@{Tpzd%imH5
z@?|23*UegI4-RJGCP*-Ue$C17Qv3h^|J_r-XWzD7s)+UIW{m);>Z}2uPixTxTK@$(
zFdllG>EG9!46uau4jjM7*+9W#c-!MRB>8~X6d<L)?idw=mn%V|f!(aX?Z8fuXab#%
z@)K(0s@I$huUEh52ASM?pmd=}H|u4Hy3j_5Q$0W`Iw9eKHXj5|)!nR3&H@acomas_
zM3AF>Ky#EYKw)Ef2sC7q!9V4YkF~Csvj7AClmi@x_*-p2!~fl^98LlZo|dj0{4Ls`
zW70cczIgQ<R2uWQ#6$VB!2C|o883a=%nS^$;}KmAzjeE)IQVvc2Tl7R#^PNKpBUcu
z?R?kiqGICF3tD&#n%DxdDnKp?==M=@0d2}mVq{?Go&sKQ-|Y%M*2o#O#}YJBWqG5H
z8+7WJNAh8xZk~gkAu1Z6Mcy8u$vM#YZ)c2(!V4zwII%r+yQF8QIJD>k-2~Sn3ogPy
zw`(;2`p@5D2I4mV`p4fA!^ps387slxmjJ4DyL~l$k`Ff@X7u7;&vMX%5j3#f{OfOt
zCaA;!9iHQxd<JwlE+`}&n~yMhb&8zu0&Q*r9oJjo)yZ<c^FwoviU}ilrUn#5{j&f6
z|99yQm2lL&<=T3w&f6pTuy67i!%Lv4ddS*{!=S+p=2!&}<{t22P#(;#8a~WDDj-WH
z_;#~g_UUA~=+n(|!M77~7l@<frTXWtj8{O80!;verl%r2It^SpAAnXaFfcHHh9E&b
zS;siX_``;mEN}47KlE}lIDLYeoSh$Ee0d7a5};|i*0z7pI~`shnBWOsj^+YdSpvF-
z3^Wg8@p1>am}vkdY>@9k0pXc^1QY-s$61bprW-)QAoqg!AZ48&z(*vcO|UFcap)`o
z?WzE6Na=P_F>y6~+Zm&h0-6|j?b2KE&$HK^5qt!#XXnw^oF2`G89goUmN<FzipYUB
zPkMtK+Rb5j$;a{s|CB?F*FAaz|AR(gIt4(tPX=&+bbz`Ypoy;kK?a_dcfpP>-PawX
zlH%EU9AsyAsD$Q^UKi&7nujW?O1yoN4|^t`F$6aXJPtl&_U%0E*?H23IaUD_?jY~^
zFuQ7i;sfL--)@n^zMUcmeY-^t_;iYZm#SDEs(<0gc!lvY=mxZxoS>N%&_ZP2&Uc{f
z016S%7CaFB^7$XoEXYgH26527eQR)*udjn-<=W@aanhGgkRsuQ6<FRBDjy4%2QQ|D
zP0E1t)XSxR|Nn=!pSnebxj{<+&w)?gwY*ru`NHclDBqSi?F0>bLE^ht^lk!ZwBxWx
z=fM|?o`6!o?GjnYePAz=-v0j&DVsqp4p{rf@WAW09=*IzYk3%UH8C<Uyjc7Q)Gm2_
z1KR#WDSw*ZRCrj6eg&0QpdRye{uTr9CPgRMrK=@59^Fm?%|96H!e6X<#>rs#-|#Ky
z0(w)AZq|2}V4n*>eV+Ub<UGV$W@k|O)cPNEG7jjlJWWv906L<u0wt|a0JU&dfRus;
z*C5>vpWb2(!%H5=oxv?c&>5%Q4gwyK3t_sQ1&|wv*LXpzncO)%tXZd<gX+l)b_Ry;
z4WRLO28ISk{#H<Z=wZ$J$Oa_2g@J(qvL4w?=l6f`xoF*@tGPh&a1=CcBlY6gLr@%)
z3WDUmHG(e3W#Vr+2yz}MwZJAvetN)Gn}a&@0-#d5^VN%@jnLlp@e&=6ZV%9`kUl5q
z#?6cTEpDJ&GBUx2^Mj{Dp$opdnHd;f1cGu5=mgzE|Nj4f2|mjn-hFy`0+h^pOH?vI
z*Gqf!hNvWf>;@%NklmoH3z{eI{P1G)chJcpKmLQ4wu7$q0PS4J@aT190-aL9-{!*(
zK7rV$^8tT{11Of0g9SV~oxue+XuX&R|9Wsw653hxWQK>iNAu6WpiU!y%SzBW(9KMY
zp4}cCo}C{(lB*Oz^*iW*Oa^epf;!>>3MTL%#0#^j(6Bki-vV0b;M1KU0Pa~r7C?X|
zeL#gk2KX!)&?1Nsm5fr$m;Rt)AMUQ%pdO1SvokC$fOU8>{zcZr-vYW^2{gdo4IbO_
z?EDCx$Mj)NQAzM^ed5#kpu)zb8{&1>)=MP|pq*ZyZm{ts`kvjv;JXaL>lYE0y`BiE
zzde|p6<+T{v=4l{odrCTFS)i}^62dbjfnd6_FOh#0bQa7?lALrfHo2%)Pv4JwFHgC
zdhoAr1YJJu$#}rW@}x)Sh0-U`zUoWR02?enBdyh4_vior380m--H>_PW+n#EP95;h
zgFsML=Xeatf(Q6p;y^Q<plw10p!3*4XY#|xTR?t?`W4)B^6YjNaP4(sgk?8qKJ!gJ
zV0g)=^CP$$R=@=+gg(5q0~y=B5flyJ%P2ZOywnCC@Ol8WEbN8keNG0@XbR}Oz(X%4
zgT{7|Peb5u{Rb8bgIu2N(Fr@hzymzL3XccySVd`sZ+Cz|>m{E~a5VCFl!FddfraoK
za0r9l54u|0(i1eY4G+&lzLqzk;R)9K(i${J-ptPUGV>2;J5m5r{K6CYOEHil#G?5$
zu*WbCQv;pw?a}!PG*REQ7M!NR3tSpOxfHZuzvVGIXif<12ghz#3E%Dji`E0a$w><Q
zt&>5U*ujTHdn<T!Gl1qzzTffy9bpDq&+cP+g1^_E12mO%ppw^z@q{PiL66o0p8OsM
zJ&>~Mde9saG)qA8=s{?d`E*`-A!p0R06MP`QjofIJA>{3L@h``i!7o2YpBK-6F9)}
z>)Bn(0KMxSa`T!Wc%u~P<~0`;4^TFO%;bB#GzIMtWp-A0x&8P5|IPIh;Imr6i+1>1
zKZ44LZg&OHxs=x43jF<@AQyMLYk-b-1l?-ZZQ#-C_`gIBlAju^7)sbc2Q6kWf|l%g
zFn$7c$V*><##LAu7(hLT4CokUcYsB=mjY<O5p>2gxQGR{Az+JFK&1_MpcTY`6g&GT
zfTIZ1Y>nV=Ne4#_cnla+bVT@c*9&-b?ok09PvhC`X#pve0v$ZMCxHqi&(6yp-2oP$
zjjo`b+2C#KQxCZq9^&722y{NCPv?7Z!#LSRCBU=ut54@WpKc|PRROORk@7p{_?&0+
z8%EHf3@xDTf{qRL45eD#&H}!S?;!(m2TD#u^FoOcco#Ne^zHSL37}0=kfIHAWQoWB
zYaYztn|Hw8dcA!@^AAS;mTK@;#)@ek$rn6&c`hUEV)W<+j{(-oyactdLG#JT`xik6
z|A6&~Tn2ULwYxwQN}%zP<4)j^ExqW`3DyrjhXRxdzTO5^nEWlE<5i$F2h<8sjq#$-
zijCnV`wviy+F8J}+YvoELINL@B%x^$nlfMfWd&92B`T2Xq4`@tS37}j?dc8p4;q4i
z?#EaQs`J1NV9<Ryov;S5$IB^T39wUNa9N?}33yr8?I3_;_e*wA`2_JGI22eegXUt9
zwl%_hZw1Qk-K=j6z%8JKC6KmZ;$2RLmsh`mmTWj1ctFPxvq7T`SjG^++omAd6qH`U
znFlSggHt&8;8qvB2e;nr{qz6jBCx&S8r%cVSY!igDF^D;dO|C7pUz9Z-M-KYz4HK`
zY?aXq%~r?wTlBzH-AkYD3V|02U;l$vk${J>1wc)VZZ`{$?tBH%_FWIqdbR-H&ZnT$
zO*}zcg~6E&G>X^_nbGPz3*T2h^-x2FlpX)n1BMs)w;gcoJn}je);#fms%CZ)0Cyt5
zm8?hSDR4#q)3x(~FXQ|FS3ws|fp1Sdz~2fwe9)u29XwkKxj_+p^_ge$J4Vn}wU$P3
zM-nUsZeyXA%%C;);F1~C6luj%GPi&(1b}5+FPJmCy(~ZnTzK%WKj?wt<d+`*|Nn<x
zx>!;Kav#$EUk^sGb6$e?fk9@iS}%EYgC-=vX_~)-3v^*fZ!>a(15%!X>O%|A<e4Y`
z`UX(@!h`XkujL7FeF#gwXF(S#fyxOka5=%>@d1>c!DYpDa9IJ_ZtelO*tkyNCFsN*
zX#c?nxx82iYWjloiCo87Ui5>f82dmyuFeA<-K^Vn!I|bt0cZrZM8(4gvcZ|-Mba%!
z2GHyQf6Gx&SU2l2f~KBe`$VAi0kKuuUPf*P!vilhL5r<A!A^kW=<66c8Z7zp9XMaO
z8+cf^gJw+ldqJzPAz9bmz@xhzGF=LZl|vA<93GuNLA&kvet>d3t2)GAdkT0M48MVn
z#R<B}$?($l_y7OUM8V$zItl@_juExqe(4M{pjn^M2XwU=I5_xQtw3UkUVt{33rWM;
z?Vz2_9>?7wjcueP{Za!oqyi4*Kpk)>=jB6+CN_{;c7kHLo3#!iWe<1g${U;vFQ<U(
zdJh3m$qG$ltH1yM?}OUp0;MjL))qK*L0Vg|)K&8R|9``8FP%Yc1cVQCK$e3pxnnmx
z@NyEkc!ou-;enTp-@#kBT^P{M>(B57^#;y)bYAuWO^)s40nNBUX7YMPFXZzuym;*c
zT5!wXp$uv|S<7k|fO>jm;L^t#){TWM#BZ(^VC3%uoit~7+i@Rg3=`BX|8MyA#rf;d
zhO-?jxRV6hfD7IRm<Q_mwcZAGVnK)PJAk?HJ}rd%mcOMPBn}#1?+y6x()j^A+7Zf7
zD(ul6%HaaJ5*&1GZ8vC_Rr3+lV_rSFqa{2*vkKO%S2RFV1K{aiP&>Li%Ywg!2h>9p
zzXGmhTOkWYSVi<eqrlD_{4Jmp`atVY*is<_!Qjr{PViz3KLwx8lOEr1dRU&|?@<Gl
z(x75Y78Ee82lzXdfJO(C{RDhE(<DG=thHW-o___M-sWEqUSHzL93bG?dC8-58Ymls
zHhlYlcs~u_8vg%30kpQuvGW*gO1#$(+;4XS_uC<}I&C0r-EJtIcEx{O46dLn#TwWc
z7+wTl<79Zb95O}b!ocvt`5H7Xf<Qh`1@Vyk-mgHlCAcvH>i<Ie-alV_TL`U@j`Fui
zff}Hl2VYEjhp3INfxO*Zp}@f3vKmylKt0(VY60qnf+`zF{;5YnO+Egp2OJHLdUUg{
z2W1mWXAW2XZEyKozOurG4t`66h7P<rJUfrTMhIHJgN<iq^yn6~`N_io8cX1PQFRd<
zX)RUY`o-A-+H3m;>9s);AgJ%wUJJ^#%`7UgZSkNEJ_DpbtsnquvvxiL#jz4-_8z=&
z)J4UBzhyBWC@X}h7<hm-nt*Q7^Xcvbb<IFcSr5>`i`_Fo%~+4l3*ABBUOp#iofv2+
zr8^AN|M2X*;Q9RqXpLcym;eI<s3X$L3u1t3InccVjE6uoBm5qRJd(o%JUZRLhWrFs
z%fG%2RGoS<J3=a9a4dUtgKs8w?R@e7GI%WiMa30P23Nyxptf%7YEVyf8@K}rJKFB$
zMlcsPQw-)#K;F9A1nz@<dwB!A_Z%|c@}e0MtgT1DTNJ*5Mx<VD2P*)Nce-?bcsb(_
z=&mb>`i6brRVhA@80T*Vt+)ksEnQnr`alvje}^ilK=17XRi=KuJ?9|3_Xn{0)Z;r^
zfBg`mzYfk7FF`lq!usp3pnaQ$CtvVf0Ck2xg08jdJmlH=<ApM)aoLTugn_^H16U}S
zqZ3pvbb?OG1(gslZ~g`sh7kArGM@2eeCXTy#FyXW;Y-kQOP<{h7N9-3plcNP*Iz-+
zp)VsrqnEc4{SQbwdnpNC!R!L+n}Q046QI6Ug)r!%nu9OwTMm@WfVtnJn^jZ|Tz42{
zf=_reybUcSL3P@`OPmZZ7G479P>9L=t!IAy|BtZGqnq`rDp>#bOi111bqSQgfBpa8
z3_A9;wVxN1Zb6IP41BE16!`m-Ap#oRVFEtg)dD`<0?_ir1w1SPDNPJ7`6eF#6)B(r
z3D6342k3e*k6t$oa6`~V#p1>BpP(h~;9LM&w(j833B4D-+tI=Y)SUxuw`qXn3Q(B$
zx@&+sY#y%_;Nv48yFnSY*$s3aHaKC!TZ(O<>%2hyHQjDE0Z-7S0dAmEph`|d6B%T_
z3ejf+>wbN}qq`4O3WEBa2Ckhip!wuK=&Do+m+p80k6sT(SI}l3e+ho@F)5(dAlMD=
zAUA*;9Uj*H3j8gMY@i4P`|l;_h+ckq2BfO&r3vgD7$a85Q8wTSPf+`e=Nh<O2RX?G
z>YiH3m*8pvxk1MbD#$<@M6Tg%(1AVk5_H4@`25Ib#Bm;|*V{nK=0lKV@*-pow1fs7
z_6lyzcyPP~B^^+m;?WJxNZ@S&ZJ;s?UbVb10p%mm;HWaFFlhb8-zf!7;m}0+vga?n
z8O`4UDic6~hovdK8$2cA09oYxvg`*qi-Fhgu;wa*)9b8s9`JD;Pe2KM>UmCvmruaW
z6ekDJ%w+^<>@@&<L&pM80zxjNL4~zXx1Yib{YS7d*kk-H4?$ts?E|{x12zU5#tCX(
zfUZO0?@$CScR-Y@F(B2@auv2V3*2D<CnC@gEI;@ZO^@Dqjo0x=`3<+8Zg&Y6(0~g#
zd0q181SK!XCApA>BvQ)}lDyQx%@~M_|AU5WKsQ?Rw-|%cBBXGKCLPbtm#&>J9RFVd
z-Aon$zP{{3MP@hLH!W$P&JCpG^?=k${4JM2orUf|_~4rdxb^^h4?G(WDQ{t2B6S?`
z2wD~4!R)308;=F=+iw9~_~Y7oiNC`bv?V3^kWV)_*SK_E^5|tb?$hm|;bYwaT3b}B
z@Dj8q6A^x(+Z=o#=O6L+fELetBp(8u;R({F4L)+N`PY9B=pl5a7h#u}p9Uu<aCzz|
z;FEl+^^ymA1p@XNe@7{(;X4zf5;@=rAM^z)eCZ2XCJVg_J^2!7NvTIK%XJ^-22f4w
z)9IlBvpV1(XgI|UHk{J!qhbMDHw#*Ru>-V86ST9s6KpPQKxNGrE{2y`;EadV%jpC)
zhQNw3dO0sam0~A2vqQR0*D$(HV9A$v!43UT0ra%t0jY95di^wD?gMS-_y#J)p@lbE
z!;k~y#@Ao}|91p!LTtIr2)b42Hh;%|P~QYJl?;v4Tj-H0{jwFbGDaR8A07(u_yip!
zOk8}<0eiyDz{9!?(*OGdO0D3KaWnAfZiDpyz#;nb4X9Ju-3}_JAS37Q;07;f+v827
zTFL_wnJ<h!gKkg-H+5Kl$$^WS?@5rVQU5e-Hu33aP$v?SFY$EnLcqpAt#)PvP4Rem
z9EaJD#qzD6xENlZ{Q3Vsw2FeYgIYjyTc9C2kK`Z)$W#YtC>-KJ(55I*?1A#Vb{nL(
z=?3j>BC5rgPk#LWZwP7~yxjc>bf6nJc0BN=T~lz-Atk^pP_YLNW{d>L2~x}KrttFG
zFYqFD0iWbct(Say+aT?<Dc2zFG;kv1@3;j$=>yb5MH&C_1dV?j0*`<AK$7#zb>PVM
zQ89Rt2P&|k*M=Sdb%44H6g;4<0*jaJpfmt2Utx`FaG`Y&ntq{GIk?H|*zGRh2^(_)
z9cStZ8FTUk6|<g@0UZx)MKX901)|miq!v2(11XYCK|4obBULHj^B}>&461HW=MX?w
zWrF7rz}K3A+VE&|2#C@dbp8Q6J%C#iB?X?~lGzKC77n7e>tBk23iJKoW;B1x6i}Ez
z5<jTx1X&sicG63)|Ns9xLd$Q+Y44yQK&p$Oq44r6XfUYT6Fk-cjlNBw(hm}~KE05r
zh13Ta@d+Mr04*CYec}O)Pf!sHsRvGii;PSB9s595;Hw8DUW$W`J)3}1{{IDej;QiK
z4mN}anr;O3r@?zOL5Jb-AP=E=LWj^~UxLmS0=1V=#?Q8a?YrRFi*x+U6Eb-95;W%I
z2_D%gmjV|dQ(_@Sh|Y0N$ac||YEX6suU3ls0x3*b85qC?6r_s4Q%dx|<6?L@6*R*J
zDYNirV$eQLsJp<&|FNJCszD`R@`9=m(9lNbP0&D@-$&5wo4bK0Y>e$9$orr(KRVqF
zJRxIjuq1K`T+ksE6yWQvuon~%wXAWH;D8a11vTR!txnK6*xej2P8{WAcqtAV4uEDe
zJSFVpFaQ5Tw%=MnoD01(_NC@Wcp+Mn2^-Tz%PBuUfP4rp#XTW*ctVHikV}D=U%~x8
zurd#bGOVL{zkY*EL&+vHK7fYgrh!U8pWZp(5)hO@tU&u8J^9x+!3TVAfeSoX21)z?
zN)W6q65tTJ83Rc=8;@`@ywv*ymdb=k{fmZ3O#?{@fBOF)lIEBtK+DrW8!BX@c^Dj<
z&;19rkwN;w9sQTP-+){S+o}Ar4BQ=u^k0$JyPxm&l<@4l;?j8xbXP>rLeRn4okum#
zww|oh1Rp+;eAK6x=aAt6&u)<e9?ic%+sUj&4)V8_Lz^j<2kW0emd9K@1nz@^&m;pM
z%iSxw$rdz=dGkfpK~4tHnpyDq6n8!T|NrLhz}Wf8r}H8I)MijA2EMnZb2q5|e(_e4
zg~6rQ?SJbxk4|R=&*Td(oz4O-od-OQw_FB=GH9U%e;;VYZRabG<YS;Yentj{@3%aA
zS&n!lU-IeY0cC6kkMFm9dsVI&UV0sS3~UF3D`*8vBX~h7XgH34y&z~Zdm;l914Esf
zW9Mhr&O?rxmmM`P`6l1?O}^yUJ?A#aJ|F(|5`LX?z;=VqU2Q(d;nDnp12n;Hd9B3A
zzgvdK@|ACI@PD69!HOw9-Qfx#A%9C5uF^K2?r;tNZV@h@&WRv<Uw47Zn{H<T=v)LS
z^YnUa_#_{I&3}RV(jMJG0v?b_cEd|A+FpUqLI7<nfiBrS?9t8YD+W$Br=lQfqv{Z7
zK@rlTf5QW>&%yi8ko_DApu;Ud9d1w1G8m0#uraZ;eULFR(4AeNV{hNx0*}#ob{^z!
z`OE;iW-Lqsv?{~YBbmGPWQCh&x1)mNu|`m=flg#7RrTy;Iq7j6yiEYq>jE*EK@8A(
zixW^c9roysQvj{AusQA7>8SAfG^l6LHyc#gbo*)ebW8fS-Y(U4><#+w(d)?J)9Z4P
z1JNJwv^-G4@6j#b(R_fzqxDkBd(Y0xpt_|l4zy^)@Blbv`E)b-wjQVx^tHU<z(41>
zFTc+XhnD~Ru7{ve=3;rN^mZq+NAii6pu43#x>-3z!C|;95)y`H2SH)@5_D9s;Q{bH
zsGvXu#TR%zaN`@$T|wQIpnWLK{~7pOltF7P3kCT5Kqo@==Kt??`|oOa+oyNRLC{TJ
z;G>W`AA;9I7+z}q=5?IqCMZxmdYeIwS>NQ-bqcWY9iMK{IXN8O%u`N)I~JA~O5b>O
zirn;U2Cd_JUAn*dKci1Kiwb`qxN_=s<Zv~-4fZs&KJMo5u{>DI=Gl3|vGX$6zXv!h
zua`bIJn5PIy7ik+Z#T$Jk6s(_j=nlS-)=_FZU+U&V-2uaED`nW-tq#}8}pdy(;LR<
z`Tdt?r-Ong;}6h*J)or=hzRyP4(@}2d}HY?P`}Be8|)>IZU+U>;w6{P8y<~EK!F8X
zRdyJ>*!uNbSHs)T>sA~X9K+xxkVZFXxbi&c4oXn7%BOcG$feCM7!5D^^!9*5(x>wV
zXx##2uTZzAgykv7QT803mIq6pwqEKC*C;9LE&6YG8?<25vGbP4ahLlbQy6?YZ@v}<
z&8J%);BQR?msbZlJS|U_*m-m_`gDVLTR3(*NVqUw(7aIb$QR^+8J^uN2SBT{N-p_y
zyWBVMZ2rMmx(}4jJUT&K%af&tz^f%K@0CvW=q)z@WtnVI@Hs)ClCJ|?@^!jPbh`@}
zz6JTq4`gxjQI~Fi4Ug`g;~<wg_B#Ft-LBF-5mexLbVe%pBp>K>6maQ|lJGj-au8JN
zKuS5#87H2dpFDaeg5t*2@WAWXv<cA6XLta#(-Wi)l#Te;Gl5RX1KHBq1TNB)Tslv<
zXddvG;nS;f(6@Vw3dmR={`Dot4SYMds3?F&&OkLi=;W{FLmaM_Cu-AuyOlh9T~z*i
zbTT>jvPigSo~W4U0||PM8NS_x3cl7V$M{=8+fRJEJvBVLL6;IVfr>WpmK2X}*3E+8
zTs0vKlB*u<g?6VPyEx)O*C>H@NP~S2iu~>%(2b=Y(7h+1lCb%p2I$UR@G)EyK|4?k
zFTH4d%Ee%rFTmdqYLprtKr!sNBY5t?@X|}rt{#tWRs)C=e4$Q=g*o9R=xlq?`F)7<
z2Akg)fM>I=^S7FT?m)e5`1UooN3xrM2jfw2G<W`d5xSF;!Nc-!t%gT;$$bfrUeP(m
zpjz$Yiz&N6C1>dcP+ot15m8=w^tyt!u*mbbgT_~Og8Hd1cI<{$j>q_0euGj(uV^UP
zn1i76BX7Tm*aezttruYE1noq2Qvl^I{yxwW4zKQ<_aIx<z{+2~kOSMw-?9v}tsqnY
zbaflJW88Vev-6I}_ZvRFB}W-v%R^k>au1YlJd#}nJUVarXg>0=JjCA%I=;ZOyX77z
zDSC8wfYRWLA6LMoe(4F&VSxNCo}i_n-$2VcnvXz_32+4M6aklKFO2uVJX3nhqnq^r
zKRC)|LqS&ofm{x1iKy@4WPqNx1X-gA>WjZbnJEJK@x}Re=pf|Lk`~aC+I)yZ_*;s>
zdlz7?bY%d02s8o;ntgO-08K>0PS^omA?pK99_K+LJDne2%=``6%Ag0@jNm5V0p9?{
z-=_{bQRTJ=C3~PgKjLBl9Zaz6<t^}f@NU+<eBdDX6%3ncezA*_0etHqXunlAY+Cgt
z=sY{<jz~~Wh;@v6`ED0zClvDj6Qup^5l+1_OrD)*I<JB@AAr`-y7XrMcWnME&)+^B
zbbbvuaYchtC@5Ht@wcpjB(5I@pfq~$1;Y+b29I9w0E$=dly{)2X@Uo2%MQ3YwLDb%
z!K1fD1!Qz*96X>vA!_&^G7ul;+0F9@9*5|ItS|W5pb>Z&I-b~h@Wm?7Wmg~vwfqAm
zGX56O{3mGJX^ArEv>H##za_esf9scl#@{_WdILB>C46UyipT5e;P7(h04ehT_fb48
z|CU|`m9j@c=d2&7DC|bt(&k1{T&h2W#w8@N!*6RpjFg|d*+A=A4G(}Pk;O`H;5hIF
zq1U6Ebu|w-MQ{WmX9}U6pf(0%k1)6>j6M9~-40HM*R9C+Z^3KFfZoXepc8GTfRBUp
z>1+Y-ssW`0@OJp$^8D>B@I(-{9hNEiTR=&}qgV8^9yk$r^sWQN!iz6kL1|&iJy0U>
z=zIZhAEKm(3#A`A>jXe&XM*>^Kr@a{Z_0g+*Zk1-M)Oe)Ps=|gsi1QgJ-YpW;7lB#
z;|D!nyn);v2&x{zd!#_wyyF76yz%ICW#Dh=2UTFr+Ki=3Js@3EkLIHs{{sv>E&r6x
z21Wg;@1X2lk%b=h-r(|xviQG`68{09MvG(2VGp!8e}W^<5$aiYa)D!9EC4yi6}CfT
z9H#KazipfhucxBKH*$Rh+Jn3^gPVZ?(kt`nJpZBw6mOv1beO;87idJGSF}<a9J4PJ
zw{S9ebWa5p;h_2GM|(g$$6hcOG(+#vxf-;y)F(Mm!WY!nnGD*;z~6TcJgnxa;MdCn
z?ka(McZ?pLQ<wul2bqA5rvP2i?Ad%M#HY900W@6H+YFNOJot#k2XxJkGidWKgI}+V
zF#IeiM1Jw<*7EJt^yx0*@a_EI+gZrrtN8*nQ0)skE4KBmFTejApUz+f-_Dhwc8X6o
zgJ<&#MqkShzWhGNK&PyL4#x29Z2ZB<z~HO-0#r<abo+ERyZ~QDf3tL6^FJ2;_C9b)
z$NJ8XhruIRWP=Ceh5rvcdRhH;|Nnoy8MIj!)C=)A-VEA9%K%DYoz0;0D~`278ok}%
zz<^|GXqT~08j_y6r#OQ>-5J8H0kYo1@?hyJkKSMnP>BRN>;<y*0kYQv+AjlFkRH9P
zvb$goU;){R;Q(+;>4msD=&n?-<2-s<EqB87Ai4BqAZX*AoCdN&0k}d?!_NcaCGhE~
z;1iINJrrK(zWD)J@^_5Cg%h+^t{Z$^4QP%Uw6B=I1$453Yj=VJ_%tBU^#zX_&apan
z1~`C@<pVDufhMWe11_CO4*VUUfoYFk)+swcyIVGc!V?m}pi@O)PFM=6dAnJ+u!A#!
zy)UHs_i!^PeIj;9yCUt7hFo`M14_4xHbHX<N>GAU40bbkbh3FgGcdla2G!dKUiN_P
zaRe0)uQx%@3wXWT<2WQmzI+54-|GDMVh1P?5JCU49MqcVX1&V>TF%4qB62e)!|VHy
z<BleP=A|`!K@BNY&<$Ap+Za5XUorYJp6~_rGas{eFnTav1j&Pg(-(BD!!*#bLe0M!
zOX@tEe>0V2csBoLE(!8%{>@Ti<JtV1wM5Oc`8QjMfFr^%uqm|Q`!b#Yn+<YwNe0LU
zun33&ayLkpT5J!-i=NG|I7(-IJ`94O>RZE=e;a5VppM4{><Z8-hSD#e4};}AS`Ya2
ziZJr`f!64Q9npCTbcu+M<|SXo6CU3$H9unSaQyFSd5XW~BPg?g*3EQ-7@(1+B9G=@
zOeJw1&A*sSygZtJv6Ps3H2-2PQSxa1#a6-xHm~_0D55$X|I>o!X?dz78e}lYvCRiL
zIvjsMc^!^F;jCY9)^9lL51jQE&iV&ufjnHg92A0xaPsXHVc_orb(_J;IuC-%JYUU=
zp5HGzHa~=>LCZt@EiV~B6V@mBTR?+(o}lZAay*-VGL=MnHveQUar12c$x>qM+5D5W
zM8UK9CtC?G$UKl?;OL<)$Jg>uNfgvbjt)jg{%sDR!<`_kUmlDXA*|nU)*m?QFP!xc
z&iW5#ffB9dq0$wo;ZrB#%D-K}m+?fJOQ#^{0IB8|jHPcrA4X(e&}9^k{M*qoZ(1ij
z_k#A_gL5xvddCwyp9u-W-%KUB;2azV&cXKJ9IOG(!GcI8LX4uB0LX7($AU9*0mvSR
z5Qqf|6vh*2os87wz%ukCq`-FN-ww{uylF0A=YVtcXGBV^lZVEHYv*N`jzGpV$Ahmq
zTskCSk@64`DRtr?=Yo83@BjxS_&}a3efjw?*p_Y=6^%5<gP>u(19iCU^XL_EtP=ql
z<k5VP31nEO<3A6}Q=r&KDrFq``&7Wi_jU%*vU$c69-5%ChRLJ(6_dxsS81J&|C%4M
zgNqu_cm;Tg-XvI2Qvoh&lEFodAGoNo1Q#_b;G%{f&2rjtK_yNy$aqMJBaqhV_yNjI
z>va5tV17X`zaf}E5X@f)<{t#}pQq)i()p0c1|4f6017|{NB-^LLt^_t;o;Nk@B?&S
z<G~l8W7!xznt!nSLGPffGwTdd;c+#*l*XUuqQaBLpLigRzu*9aPv>P%(6Hmd$1J{<
z7x)EPB+K9UXrA!3JnhxX<5^-48c$2>6a*FDKbX=w1DQ&6Jeq$nr*#IhfC}>;ENPvA
zY$XyN%|BSvIs-XM_&l0_u%&eda+QE&cs!bq2t*@SD2{b9ATL3aL+7Cm$Ny;uUvYE<
zg1z?ykyOD+M*>N08aN$-lF!A`7oQJ<g8=M%(6;-ugNHakr)vy}VDRnbai|jpdCjx=
z023r{`C1+<eT(qDZ?A|0e;=sS11a<Eyy&Y5s#Tagn_n_{UVI6vR$%%L@wb5XmivMZ
z5dhV{;CiJ9T(87|>lH6>y<!HgSCqi@3LnT&gx$2@fvT4zsKEk|vd`g@2jfL3^9zFc
z4Z-|@V1jBOs9I3P17(8h8@Rtq7eF!tC?9Bev>pJ3S)ClzPA13B!yS&u1sv#*!biv<
z%;Nwl<G=v{PF&#X#_}MjjDs2K)63&nCkrwZlw?6lQPb?n(#Ie(LsT@t-4UN&9-%rh
zNB-?144@>L)+xg1(R_f($MQt!E08+Sr7x`q>V#aoLG>Y0b@&cZ^78kIf(k=W-wL@Y
z3og*XO<B<OCg92t)cFQgh9wo?rff2}BJ=}SgqGlnPz78O@;k!K0vkeIt}o*Wu&JQh
zp(Mevn*l7~*v$Z`_c|FVXTqwwMMx3u+6}Jhc#tZ(FNiR#(}Oq!oC=s755AUg>5z2n
zJbdtl0JzTUaAb7ph-88o%vgE}hfa9<0c(|TJos9m!;#6QBa#_OXE1oy7IgBb6{vQF
zSe)i~@DPV9|MpvsorhEz7#RLLHa=ot_|I_g1&8CoM;xx4w_G?cfWr-ZqW-by!>-*R
z^$g&I2d-FM`L|zi?L6Vw2-=qL-?8xlNWbI3mmH1<A8@#GUU20+;n8}a4lM-0`a$Bt
zj-Y9`gDjxv2>b(X34jZj5ETtj1=<JNvFHezzIw&z0Xp5g6V$GEY<|Sv>G%hvpaoRb
zg3}wM&Gm~B)^7a;Zgc%&E(!Alwe0OZK`na?Pf*KV5NsmYQjg|WjGc~uXe<D7Z1XF|
zk`PF+do&+Z=yZGl;dDAafiYgd7;j*V4=~0T7~=<w@y7$yQCbH{Y~XqZ6sQi+6j$ic
z8}P@o^RUOkS4<wDs<ZhAi%+k}R8a4~&KPvf36HDc$u#~vA5b-0aFD^L6MUql$HB)e
zK9;9oRqO>{%gbK9JQGV4K~=0vCnLBLWpe3sWC2&A%r2dd93?C+osRHI6cTfF28bX9
zC-47|<Q@43oJe8m`>#t!<UddxlwJT8JUI0J1?L8r4ya~m3jgQQ5&0jc7j(3^hHvZb
zI&)BMi?AD1zPa#kzXVO+@Z^2)5r+%sCC&?-j(<EsS7n?;)YS}*-2$LHNE|?QxeNdH
z1DzK@+8F+;f|B;ZR~!c)aJX<D;Jo15da^FZvp4XMZ|7-PID=|2csLt%x`0|U2T+3f
zFsQ2p3FbqPVD{C#=xcck9L%zyda;wSL=;prf&!TbR5^mem>DUEq2;r%EBLrr7MD&=
zSkw3|sEF`U(E!!6kUlY}P<_eh*?fS-xAPP@<ACcAP(Azw+|j$l-vSwI_yrzp_yrzp
z_yrzp_yrzp_yrzp_yrnlKo|xt6u?C^#Bl2I53qpE0-Y&b5)8KCfC8v^c6j2!coEEa
z0b{&@F+RW;pc)&j22@Fd8K8O@W*|rDdPsHwMK36f>hvKNuz-^&ffD#7W9dai@S<uZ
zPz1xY#(-kxcAd2=|8@?j&1sGY4}yx+i;kTKp+)dRa5@7O!4ElHIWM|!!m6&<jHO4B
zvWX!ynS&zNvGWkv5C0txzLEfEmxC_^Tsi{(bT}gN*m(k)LHX<z2dMry_(B4r8Ij4(
zgZv(&qG5Oml+8eu2+st^Zk7qed4Odis1)+Cyj6M(<OpaA7V-tRFnkalZj=@VXtc}|
zl;)6I7#`r*1Q+?B!AEct1CoFVkCq_}gP1}CKB!*>b|JW>k>Lq$X?S!pg6=9}ya<t{
z78_E%qmGvOc0*bmK43?HE7UKa4+n!rF$_QlX@|pHbhyKj-Q(bEiw?=o!)XU!b2xV1
z25nqA_}ajwBa*EnlCksf!Pf$CQ4N=lNY;)>CQy~~LgC<Ri4I5Rjz|`W6BtWZMq}Cm
zYTGh{R3dBun+a;ubVM>jY*X-r*=ym_5y=iR5^RNm$HCVc9geIWk!(nIz-KPIV^ktM
zLDvc~fX^=g-&+o1dVr441+`=tJV3j?K-JxUP@~7+vzx)STf&#|glFd=NB+~kijQ17
zZ+jkmB;nh6)wA=Er{XKmgO50TIbZp5-U8K|iXS``e|sE!A>n!OH3#UjEY1s%Gy`r4
zZG_C?IL00h_Ux7bmBYJ1R)JjL30jN~Vla4umXLvj|AT5~15d>po{G0U6>oVSe9Yl_
z@PUNq!B-N#oHslnS{eQ`IP#zLRJ`rlc@kph4PVX+pli86%_rpOM08c_L_ERGCk}AB
z3j6_%?l+(e2B}H;`*gu)Ix>K&NzfV-Pk8&uqto#RxB&&azZRUEKr^(S&7cNU7kKdb
z7gI@*CunFi3fzEl0ym(vzzrxNPzr872(}iqaiY`l2VF!!ZU(iZVxWn*`JjVGr{e)A
zuha1aoOJ=tx&dcBfU{n}Ss&o6AK>=XGDrmhiZBgO*tQ<1<Mrqi1ce<qaKXb=kie}=
zK=|1cl-B=y9()Z-#6KK652t~~tXw-mNy()n@SkJnA<u)a4IB@?5^(8={OQ?w*rg-z
zFGN%WRAhS`e4*gd5&5gb@i(a81;rPr=jhRmX&1Ph{|#+UA=~8$HuV=MfggM=;Cb*B
z$V8}J|3PW|;A;!dgRe9^4!!{8aY)q=2x)#T_<R^LD-3E#1$cn-6F6r<^3#6?cz*iN
z-~mmr4F5qjK_ED1fe)Gor@}*y{HHt=U%7T(@;LYiwDc2n`>*0JkAsgmd^jKZa9;B4
zJmdk&3ZP?2L3x0~hx3vLD0eyj05`?fL-N*P-);#Ha1H{w1DcoqGcbTM8#s%BaydAj
zd=zi_g3t|64hCC#@P!1(BCu{yW$MU((ifEPUV-fL;XLHpdBTSiw9^$!<U*?^VPA0L
zio*v-;|eqs2(CWB?H|xZ4xq*rq=*2uzFOEpvx}hV22wgENG3vzqMg724yX;yFBwas
z!S)<*09RBFCqT_fP?hCy0nWMsXFY(kKn*d74p0LO!U8qC;0ANRCL!Pru6T$=9N-MY
z4#_Z}E-z|+VT0rhSbkxI<QG<mC~|&b>TqOs=?H{WLoXRi7lIlokoIpK%qnnxL2BE<
ztb$}0Ce-W#wTc}xyRdXPvbuBxLTV$3Rb=Lv07#AjAK1}((2@U?r{YW3&P$#LA4>Rk
zo&nv9qxjSF;6n~y&WFC77csI6=)OkI6R<FT%~-ktnqlCDMI5wXg4l2v<ipN`ps@Bl
z_{yNe@xMz)B&ghQ=?MG@4h)cjgD)jOeKE(*!=NGp)CPnUNrAsyIwJpqizQD`my@w{
z5u$#nL$=AW^DroaIuC-1CQwNS)`Ve`=fRhtw!|;+5b!Gt&x5ZOAO%w3A5e!5++OvB
z6iSOw3MJ6$Y7)vNfA4OV3+~-K7d$`}{z-6=bP`-TbY4L#l1_mxya5$SA0ZX~OAa5-
zQy!cbygFGfg2tVFEpL@VYkc@9ah=F#NB(?J4ahGD?|y-+UT6U#<=ZXb(<$iN9RO0~
z(;3JC$~T}%rDvc3bWzdp?dI_9b^whC*9rJ^a{6>S!j*ggbw@!P!@<MFpy_enZUN8k
z2#8UF9-WaKpve*bZGrqQ9g+Ml{M#b=Tsj0@__qauhKv|N0=zCAfqWnl&`=N)NQB3w
zBajy)!VDT50*P?DbOiE%L|9xpB3VEpTrM4f+#nHFP=gO7!s*fx$ORH%12qg?Is!RC
z9CnZthf7Bw2dLQw^%{RG=-|8P!@;0(*#NuSq3&h}X#<(T2J#HL+rc>vWDVTyEG`{^
ztRNA%+xbBmA0z^D0SCw^K9`O_P*?<Vx^zT>Tp0-u11^`2NRZdS-Us<F5)>FbE*+8F
zXl@5N9W+o|CkBpSkLH7*K~R1{&kx`R0P+B-45)?Bd{DrnGw_2aB%VDwp{+33Bmt-z
z=?(x#vLL7~0i^?w7EnTX4^0T*fC6n%_3Re#1>NKdu@hvhPbVk?UE<#s_}`@?@IT1A
z|2hIc@NWzJ=+Y7R5yb!75%`aPTi_>`j=)bK{-2J(zx>+*Kf81Ueg^S>cLe_7-xm1A
zr6ceQi2ti2@HhXqz^^VHfnP!VpB;g}__qaqbLj~D))DxVe_P;pknoR=z#lFhf!{&C
z=5I~<|NlQ>*E)8BT>2fP4P?YOkn7Q0`?VwR8?tM^bOe4ycJ2R;z%TsUz*heNnene9
z@IU{yz@MPP3dD!{_LoaX;4g?re}jbobbyMFz~9(hTPF?9X#t>%a3C2Ckr$sLJOx(f
z*?a(`1ad!)Cp<qQDdX>30~$90<=qH`iJ<&=%7uTMCn!~d(;%Nq2Pg@8GJ>WsK~Cg#
z>F@;QM^7e~jzCa;4CHa?@B}4DPf#7k3{u1G(%}ipkDj394$6;#TrM4+p!Dhq$`arV
z!0FQA3CfS2Y@q7MrNa|!4Jbc?@}egwPqM?)bO>6!VY=P56YOqwmySTN8EihCksRo5
zXLafDWCM8*?sgWJ4o{GC5N_vp>F@+O8SDa3ehlPu>F@-Fg(s*80l6{|9tNPi2=W@(
z`yl^;0|S&N5&03_?ejt15>O5SohN)y02Eb_EE4#`vGXD%i+F;vh$kY8c!IKsCp6J~
za_R5{Wf4zA7V!jS5l=)G@dRZNPec~+1Z5FVL>BQx$|9bSEaC~xBA}~x5UGj34~KIh
zPW|rE;R(uSp5J^r1AoBt2*kOFJOXhpB9B0vi^wCMpgaQdE;NsL{scu5)Vsf2IzT=F
z6$YR@0`m1Amkv*89zk`kPjA5g5*fn-j^LY`4}b<Qz!Tx1!9vgGU;j&C<r#Rz4Pmvx
zpvH&+XgzDM(|`V!+n{A)y*z=wmM46Bc?2B!CxZ@Dapa$T(3Rs9e+%d^a*yU;{QPZO
zzzV%ScpiMo0@@D`x*+Y~BNmV5AADtDY2ceV^F`+v@-Vm>-Zs4b*_l6|MFO;NJB`2O
zU>g7ZLuvf^H`4es4yN%Z+;rj>bcqyj;un;O^lUyX;A45Z=$tR(1s}}|K9-lfdU*o*
zTbx15&@Vwe4eAf1bqeyg=s^W57#aAd9s&(~gQk@ETR^ui7+!L0s9=JMgQl8U_*?#g
zE^h{jGegBe6VGh?Eze-$EKqUKWHSeU%Q=`hD^wgbDb2;-0@{27HlGbD4w|Coft+In
z7H5Zwv!`_i^6|H{!OY=+igToO1`3oEfz@(C#W>SC1BFWBz+zlbF|M@EK#>wJuoyQ~
zj61C}P^`oZEXD&B<4NlblqgXGi}6Cmc+)xqrAqifDW!ssfq&|Ov`$Bv=);BwTn$e;
zHrOyQIPy<DnC8;S;|M-U4Rk3ExIF+lw8(=7si9AQG&KyV)BqZb1TBa3>~;EIBIgQ9
zUKXHaa|l#<`!b$@O*sGfU-}5tp9=wvnqMMLbr`tdv49smKf&b*&qN#r&t1?GUvR;5
z8LSX%!NcFy%)r2q#{d4dPj94v;caL!q$;Y*!{E_*4^;ekHXnBIIQWbO)MR8aNaHU#
zoW_6uNE(0sg*5(*!)g2pm(%$3U#0P9UQFXpeCfz97<>RCnRzgcKk=d?zhL$Tkmv<R
zenIC4ppt4Ca!ECjzXi0w9uiWZGO6_dsGtI^ya0(I3aZXP7XB7iMg|73Fua`V4CLT%
zc?T;l;KfvDAP;}bb(k=`l<Eu=;BNt)cLO#AUPyHYitx9rgsFy?QJsMjkb6tOs^LXc
zXP`_;Jy-}{I&}srl;nVg;Du9Xph`(3SO{J=bp~pbxPgV>MN?;>PKhyC2wpOE1{#zo
zfQ8@%Q)i$_2`{2t>U6Y-jzcS#TsnCgVa3w(=(xl5OfAo~MpMfVwxOI_hD*5>t1+4q
zhjvP&XSt=XHkw+7c4{G1Zo#JCiED46styCKJhI@|G*RK#tWgng;n#FgQ2_P*3gAt!
zSkPv$UY?6MnqVQI4QJpcm={<faue*d=fTI|z8`<v6-X28n@?{bqzMLVhS~NhBPGyR
z4Jgg9V`=>Nk3(8o8OPH26RxH4=Rbfp#V)7uCq7Q&Pkf!mpLsaVg+Kpj8h_TyG#CD)
zgO2=ySq%_nSr^mzlU};=3pN$}|Nq~SUodDv8h`$kH2$oIY5Yl`mRr^Ykmv@8Em;Sl
zqDcopqM-Ji6R17M-vqkk%$M<okLC>@@M52vn7vOAP@@jB_vry{zG3!0J-`h$%-*L5
zxRS-}eR^~TDq!n<dUOVAVC#K)bOst=>wS8323lb2eR^~TI-vJHJvswD(0iXAoq+-9
zy-$zMzzFo-r$=XC0($S$qcboAx%cVO=~%$8VWPsX0Zx4ypw!oV1heJm)5!zA6UxK#
zQ0ep6X9q#Dy{<5tY*7YHMw2bUWQ$Ugi$jL3pjW7Xmlieu_zzkZ4(<aZ2H#4-U0Y89
zZ~^RrG58h%?*oHQ67lIpE`U#gHspc_-<+YnUQu~DoWm_np!JNPp*By;o8=FDK+Bz=
zqiy^xpgZtj4hG%-1-ih^u>st3bp-7JVdQTC9UB21T>~GU%EaFSn!$H$r~vg?9hpH}
zI`~_bgU-5ar~vg=9YJ*i3*>w{$A$`42L7pzte{OE{4I?TRiIv~BO7S9M@f-mLj|aJ
z>c|e-aZ-}(*iZrLnL2WKH2>fz32|(w0QE{8IX#+xaF)0_HdKImq>fx3%|EzG%p4mk
zK)q2%Zja_4+$HLc4HclCC}`2^51tYU$A$_}FVvCOqxlDK38!NNcx23x4>T+W9uwoA
z$^u$p&j>1g-XWIn45>j^bs3!TK04@%UhNJ0L03ts(bO=E2VLpe!8|99)DRjSMg<RQ
zf+{M|%oF>N7)C{DmJHzmeHYQulsL49I_Oz$i3yLUmZ6<m2$fr?LtUh)9t0x{r2<F^
zbaY_s2lMC%1Hlo7L6B_s@s1|j(Sb42#&c21W*yK_)n|SI(H3qV2Jo1Z#=#P1ehu*Y
zlF$5tpaY%23nYL1FMWVmu?HTFk#}scV3dTdfBSwxm4Ttb9=w$fybA6iNIC2ng%Wj`
zMbco4Y#12$p*DTy7i591G`LXu6tsxN2eNbWWQmkxgN*>A<N=u3u$_^oN}qw$AuV>%
z0~!B`UqJK-7sMZFAmdrmpg#G8>XUo0U4E{Hw_!VUKG^%VLKn_}!oj!mmJh${W#}>+
z<k}51CI$DFCd^(Ru)Q{*wJ#b6OTZR?;umCr4y0cI9V!9d*a2GnbqThO4P@uZ5=rp5
z7x=m|*UKKAB49nB116rMc~a@-i<|F2j=Oo__9>{#Zd<~l=h@vGcW;1p0e~VHw0{x2
z3dq<Md<6+eSBU`3UWNw8J^$?)7(izDbV~YkCW02r!wfnLK5`MVG`~do<_jOj0|;xu
zJF=S(3f!*z;A459^aaFH*g|mMULJ-LUC<S8U<>&@V7reRc7f~zYwlzOP11nZid!Bm
zy^Q8ZV^DyC669wNNJN6-5jjB~cLbf}2Rf4i=H8p2ga&agI9(dTjM#u?L>hk`EVXtX
zfNcu-^}qBs$N<RZG0$EWff56l0r_YKfZPwt6i_#ScDjKA;SR_T@I(vGQifpNHUjXJ
z4zeF)G0R2B2H#VlECq@!_zEvGkj<cE{Ffc#d(33)aomvuv{4eYfsFAY_%iToAon8$
z0Nj-A7^Z+0tETZ^V?;FtoL|AFAcX=rCO~c}#A3<;Mo^Z5nF5MTP(UEXglDe^LkZjn
zJ*-9`I|O3Hq0*b6utdt(MmOKxd~x&OYo?p0KuHQE<=;GYyHenGrT{D<+yNy<P#%CK
z#}eb4??9;+%>Ym|g3gt=UHJfH#E09N;Iw=XrX3|p259Qw2`kP)!_lb&;-(HzqtTUr
zn*gZ111*~DfE-$fbp{ADvE$q8A>d<q(x=xGJOkuwc>=!t8gvRcWcfAdPBmOJK>BD)
zu2G`w1?p@M=vaA2kmFhpbO=J`oE`bM1%M}dIszH_TR>a4K_W~Z%|Dnr0-5+*R)J=0
z__qasr+GR8nfY5lXApzbfM<C+Kr0(TE1p3j;7Oj2K-Q895Dz@R(-Fv4k_F;{r*}F6
z*-K(TJn-yJM<7RuABYE@-02A9EO7wwxIl9|9f4dWMj#$|YNsQRyF>-V<MC+z!P61Q
zQz8c9fhTr40(na~KqnCLbvS~jc3k<l@i4e_@E}j^pu~>^QvASA75wqP^aWaZfJYtL
zR9*#mDvt-(I{Ik%R9+xhA@->}H&B6$7MYOM3*dG07vbyXMd0h^uOY8S4TR3-LE;y@
zWF9=52a90HYI*Q%9{;uga14V^VuQ}+!J-&+BpY-#kAGVLIF3PQvq5L`__qasBN=o^
z8+100e_H@JrqenDc}j{v(E^TY&|3JCWDpk|*We}aAs{X|vcVHEt{^Trw!sVE%|Kjm
zbc5HttAn`U_y#X`mjH3W5e{DI&Iyij_#$^ul%uR}e~YoYeKd~1XX_2FI6}#n;z;=t
zX|efBv}}o68Tv5eByeuSxyrl@o-K303bAL)V$>Dp9@tlwqpT=@1YJ@75VUq2eMNaP
z+KTdZ$a#1oe+yC>4O({u+LZ!I`rtAeyp9~Dj0UekLMfxctH)8wXz+R@lrkE$&je9M
zgLac3%4pEk2BM4xEe=PN(V%tVh%y?qBpgvjgI0qh%4pC+a6}mmS_2L#qv6ZHK{*zA
z-S;~z>%K?h4_y8ZnfM#c%|)ZR8M>MVa~H>GZXPDN8EJ$HU)_wV3_OCZ0bh{}T8o?j
zUyBU7^1%o9TI83IidvAr?LJ0DjkFf|5Z1NG@CqAsss&tO<6nEspZ^!U^q4>CC&tQS
zM}EOw6s|l@{{R0!+R9__YCK5$9lYomrTq>X%7U)OgSFowOO3&+@nG$D$Yct5H6E<}
z4q0Ffx-AyekN~&eA#01ltMOp%chIt8r1m>#H8E2A9lVGb(S8T7A4as_!Apk`?RW61
zVMO~KykHp7eh04=hP2;NmI*^H_X2GV1GNp1R|da>FC~Vm8BI*+%h*Q~6Cb&W33sc7
z(AW)V&<4lq-O;fd{%rx^&iv@u4S&Mu*v+<p(Xkuw5bE$5U&CE)LeGtbjCqd^$~6CA
z9>Rk%L`E}_%0^Se&`u4b@i(;N4`((-?X453Y_uOX+7E*?>_$8F=zG&gM~FO125y81
zwk!v{N=pHBRbd+cd)SJs&-_{kKx?bOC)oeOTy2O=eHwoq{LsAzpD~UoiU1#yfOD$R
z27a1?5m+JCsYd=b(49<a{O_N@545`N(RnY8KmRr8^aR*}R<OgY@=v7kXB<i6PdJmt
zpZYS5KOc06)zviq%(MK_mq0U*ptBDy^GBa_<QMclkj9^SA&noTC-YDmf8r_rXi(AR
z`~WI{0d%<4B($l>X3$kq{M!UTLFdtW;4{D0AyBaKw`4&i0vN$E%|95SQjRSAEucj$
zpm9bfs2meaj)T9&2&#`6D#r|y<AEIG2hzs^m1BX)3GlaoF0BH|u|nloVR9n;E%%@c
zRM?<$Y%n<q{ua=PFi0OeRE`}cC&S;e462U<D#rnnQ{Zm_owN_q#|f3=gvqHuMo77!
z;#@Fs4e)iC0o+h=ZkV`Ei4({i9;i4EOx&PE3nb1973YPCo0JGa7B=v|2L(4MmBP-;
z0u73Slz(>Q*E)!_ko8dM6D(7w!#zDdfuzSrY5aAHsOj-G=w!&x{93ot`0FCk(&H1*
zvZl}cS|DwSXzB41XdnA$eyvMs{B@uM*gyw+fZ_<09zkY;(j(YRwDbrv6O<moW}>A>
zkeQ(L2sRT}dQ9W5b3{vzCqbLvKl5vyO5?BdL`#n#w}8?k*eyuu5#$a~dIY-zDLsPR
z07{QwH(*PTAp4Qh<6F>f`Oo}XuhRJIGLh2b?a%yLH$Y(u-K+pjk8eTg@nsr+oep$i
zH6%UaEq_1pYaIZu=>%OXjHUbqEh7LO><25aLF&^y`0J1t(%u1=!Od?ZKvPPf*`xsY
zY*IJ4h{bubO*y<Q&IKz(E{ic|litElwt0eUCJ9syA5G&=I15>=m47phKl4l)f8v!i
z{=_?J{Fz5S^FRBX#$Ryzog=^CCeW<WXZ~lm9r*>L8b0$syP3vca1taFHQ_V=Gf-je
zwcs=Vvr}pO1(!g=UK>91KRW@sZxhVB@R|SFrO*7&K&5vOh=87B6OTEYgjRfi;@3I^
z3U$=%asZTFpi+(;Sc-3$oB)>M8zv`#rTB))DPSqSVR9N+if@>l0hZz$CTD@A_=d?j
zU@5*~avo^KH%vSLt@wtCN1zqoF!2Pm;u|KOfmD2h6745`LC85c9?eH2Ajcj;v(14|
zpkf?p+5Vx@C!kp_s6ueZ3QN*H4NkE*llFFa(q0QzIBb*lVMs#))G`6p1fM`fx(9#V
zBk-*0GKeI&bpk5Q7(anZGY|f{SCA>xHmE$Pg#s!anLdF^eGmS+OOW~0G^jkNl>#bN
znURbKovP^um50|1pFp*Z2Y=ly$V{smR36k?0ol)rY`+G73ma4()M5eI&xUNj0px&U
zP|X8swSeqrN4DRBzvUQG%LP;$a3I_7fXEu~)(a?kg38ZBplMsk5m6xXL9G~&`?!$Z
z7XVqV3u?)L+{TUUwg|{_T~KQVR73H60@Y9+{B@_mGrZuXV4xPwH&6}oiC^mz$j(pT
zo*`%{m;+xL|NFO}__bbu#9zRs>!2y#@Bnz-ZW{mlZ=kI4G0l^|?j!Of@B^gm;nDm?
z0#w5|z>d9^2et4)8xFvyW4oyE-FH#p1MgP>?>Be|vgEKw^BWD2t^k-WP#X+(ZFpKI
zOjnJHKpKC(kBR`~1_`hM*FY1`AOqmmf;Sz=LaaRix&%`IVFGBs%AwN77?y&!tQcU|
zQ=<aDlUV>%l}UJXI(`6MS>S7VqVxj9YS5M0Fn5Ed*5UOdbc2X5;|cU`4bm0~a5qR5
zWHYD<2@NQade}Y@c;DtWv|h!vRD*+=fx)L&<Ra+2a9_&{j{K7k`&ga?ogD7Uahbp6
zC%goDkFNx}guYbcZ5sdkOOVdaT~KEyjX(b{q@x4r_Phd}`v$6LK}$ByrSYf!NaIhv
znZ}?05OQ2x=4r@jH<`!zqo1VlC*J4R_`@&yh(G!yfAj%<kzf4Lpb9ssfnVbxzvwA`
zkw-|~bFT&b8mIY1Z}E$qa^x3G0-YP@wSiyb1i$DZh)@)$p7laHG%gskvi$(b)SwdS
zfJf^AXskfn^^E*27a;QBLJ3^w9(Uvc?X7{T09Czfp-MpI5=aTtaYqqkB?9~{T~H;U
zq6wsg`M9GDvJwgYmUO5RQ0W9x!gAbE1zCv#e~SxL38;VqDPcYCsDrFTgTF-)ssvO<
zft0WvcQip(VgNZ`9aM~fiYbs1_T!E=$Vx2uTW%wjR3IfB#~odel{oOXfOc(xOo10x
z#~po;m3Z*CfNn<xDFKyNAXB)GJBA=D2`DK8NrQ?kkTmyk#~5Vkh>~!SG^o@9N%I_c
zOhJ}TD6s%Zg9<K?H1Bc89AxQ?5=nTE?6_kIR0`ZNL!592%A(P6hY|Vf03$R3fc9;H
z^4Vv8LB}7Ud%ADGJ_*^JcgeT)WC>`bfd!mqK#E|Q5wdB^)AAx{(-x@20$qFp&cYf9
zD_$XQtb#T+;JNq)+BPj6Jo-STF>=fL3bX{s0JW@<j*oQV*Yr^_aN*YsQE_nL*NjmK
z@aUeRvVehs0p9XvVPRkZ-DTIyBLF&~%#-mHmLh_k1+*LRmneVRUvOCx^uhDsD;DsD
zKAo2lCrfrSf;Kq5{{~uQ0Y2OtR7Akr;Ee}CHw=SH3P>pd8QK6JCV39r40qwrKL{EN
zN#jqvn&!fvc=R*>v!CFm_GkWQx4@0-&#s_`wJU$Yfp=-H{2Dhw&F?fv{^FY)uKa?X
z44^AI_@7-$<Ig+_Qh5NR<^)Lo21ve9;s5{tX)gR4$J6+W?{j>1;eQ4yAa*){g!wgo
zrh&|H<QMErfC!vU<1fC=0dB^p@r#^EbKw`c18T;D7-vB0K>dO=evMOU{KdC8K%z&$
z>i9+exbh3m{O}Ka%BAOoG)I1oQy}*VfXx*-<H|4CXz(8*yCKbyKOa<x?F<0R7T@G>
z<QMcjkjAfZB8|WJ28b8g05aE+Uodb1NDky^#|J)^m-(9({QLjkxAP`sO`7Myhb%sf
zCw(k$@wezQf$k50j|0KB;(?kKkPZb8L;<33^EmD(0m>>+C5{68Eia%Y3cPglIPR!{
ztVV&q<p@*_ym<3C?r4Fm#(=+N0aOjVeDgT&=z*-pfxo2&ss>)bc^r3)KvomL-vT;c
z50vrYC7j1`#|&gO3H&W4P;=l#oX2s;3S>0}{4D}dHSlpHkK>IUAT<mO3{dYkHZU+S
zAlh~CqR!)ZBWR&MNHI+11h7ij5`TD!=W)CdbPpu5N>IjwobV3v1-$U{INk^<Qjt||
zU|?V<$pNW?mw_I~8&80gAi41XNR=B%6}%|)INo>zP1OaEDp08fZp|I=INtaIp#s#Y
z2i-Kz0BWis9sTLTuK_MOG{7Z?2B_p{K9Ye}V8T)rXm=*GICJ~}Dlu=p-T*5D!Hq6(
zs}0hOIRGyMVY;A&nd1i^%R{B0ZKkl6;>~xk){`cvEQB_J5N$R~`2J3CgYWj;8?Tw}
z-hegXAk99o8DKYnTVSxgod`oJAKb2lZ1Fr)dKbwAl<72yG{<HO2L7q&Cq%vgUoM7x
zA;${PU4^|o0pR_CJc6J`7V`c;PzedyAJ~YoEEaJ>WICv2mByd1Dtm?-ay?5Lf4;23
z8Eytp%L;r|O9Y7Yi4aKRFFlmTUwR61Ny7azY5cbjr}5uDoyMPj5WcMtG*Eohhw&oh
zz83#pmH_@1&{dFdUxAL11YK&7=GY9rk_C2-<SkH}&#@VDL?n3o8Kf%%QU^W|61+Z!
zzhx6t9rzeX@RDiBX}2JC;KLumD_9}De2^IU$Vc!Nw2~?iA9Vc*^fbvV5MKav{v>!4
zT1ga$F9hO)ccGPdf%qaIK6o2ii4}-12I7O4u9awk_!1yKcq3Yg6o@Yc;)7Q+m2iRh
zG9W&9=V6*-vyB4-@~M(<qYtCRy|^p?cA~b1f=1YVaYwx`WJNSTe;eqk99&yNz0>&f
zMa@n@qa90h-#(PafBO_h^j<}aUdWcD?E)Ui+eWv8w-7QSZ5!PV-Y$r|ZFD<$Yalby
zw$bgNOQL?TAZ;7n9smk^R_M0T?E#>WW`k}U-5$UPIu#VUZFGBp0BBqkx@~lOfDq_R
zQ0TVN?ExZ4+eWtsh=EQ7g)TkZ9w33VZFGBp6sUg+-8Q=2K?c5UbUTj&zHOr@afh<R
z33n8uC<_KP{0w|sPkQz`{^tkZE9BW5_`~DiD`wCpeb8~JKD{DWLFH)~_*_@4n?WI0
zlb~$|^{~8Ee$7Yog0JO8(1rD&Tv-z72uf?9D@j1zc4%~U2C{&5*+QeLGmrzc%N80<
zpbeZVj{MLl0^M082I7IE2ef01!;ycx15c-;1bA<yiwfu_L66>m|NJeF8Ni*wMxS0D
z24Bky{=Fg`kdEO+P?-hp7=or^K(WW)2CANXdOd!49(>6Rx=YHV`4^jCuMB8oDg(^l
zm!OwO34jtUxIM>@@OL2S@+gr&&*nqm%cHLOXx{R%yy4Z$Gt<A9B?9bkP?NNi5$taV
zCXeP{jGc}Ue><>vH2-4ibcFcZfz6}&7jvg04`_Gsb_WiR=3gwGjsl?F#oHaYJeq&8
zb~=iHb{E6^ZFs<uf4c}nrwHg8B_>bHgQf5B<#3efA5A5rsRVZJ3vyY4f8`Clx<FMH
z1};o2;DyO6&?S5rg^3KLFe!j+VTGR1e-b{AaR}vdB+!nS%)@E?iJ(i79;NYvkJtxo
zVGTL}$$^MN^g&x#gFrn8rw5>tXPuAc4PVQfUcEdw!8tGiTJm^w3YLU`iV#q34?c<o
zv?2gn_JGD(OUyvBpt>7;2v~_ahzqK!SwJJHB@!SmxcC9>S1I8Hmp>kzjt0;PPZt#n
zkJbZ_B1i(<1QI!jrwIB1>Z&&X;N@=vHBZosATL-ER0s<#S8%uUl27M7&*sC7p3P{%
zbs`OPK>>dvXyoZ(8h_TQH2x&eu#y)jxK5<;XB|r8PXcwul0d-)9X|54JYBTTL-Ur0
z<qeNso}0d)0t*yepaRRIlMx(TkP^!SR7kmkybLa~JV50VD7YYHmPe<f1UR@Lg_cLB
zqXIa%Af=W^r=tdHa6t<$k4_QLG#$9)0`0iPT_)k%`#`<M$;^YJjT5RgP9%^TmS|^M
zz;FG9WR%O`QW)p4^Pt-fL2WMnHqf1<I5UZXtKlVASS1b09-#h#AgD_AwY*vW!l#!<
z+C%e}593MD*+G^!N?>U`4JD1IbviPEiv&ouoCd0;5otWF(~%7+ji-S!1gJ=Wr17*)
zM=od@PwRB#i9YPnE5ZPpMcB^606Gc+bo>XChvkJ*ylrrl8ajCRG|+HoY!n|8scaYp
z3|ej&ZMnh^1RHIWFpaiJ20@zyHrNNA@KA8%-wvPZ#4^W;eo!Pf^=L~s(F!vzMg|6)
z-Ed#f;2CB&9MtrKt)hhV#QCF7I`IqgfKO%uHHkqNtRQv9`CAr)r^2=ifCerhYuBJ_
zDIseOw+Fz+#Sv>ML5o$k2f)U;5$h;Hi&eG<z{af+YbZgBRkjDf#-Ty$)j(D_3V;@?
zY!85qC4<(gfyG5Yi&eHefX9SEvrnKYD$K6EIiy{UuWJulDF<mX@PHNL=-NZW61{7W
z9+rUu(6EGe@Gqct@Zn(zN*8ZES}%PDEh*ry(}WBOf?CX=uzUjQ_J8KrdXUCnm&gJR
zO9xO`z6A{cK(%CYfWy)O6qc7jLjj-pwJw0y|AE8O0Th-Xb3kDUHU|=x4xq3EnF9*T
z7oc@=NMZQ|W~T)Bo*B?^0jNU(U6CjQA2@glI@}ZKBt`U;3mpT8PwAnjbkIl*C<F*D
zk^?nr5FJH*tjQhPQ7i%_cgTV_T%AOCbfGL=1Fca5FI_u;u~-c>cMj<$u0ic4!s8K^
zC!lj6jPQ6w<O!&hBL_Gh5qSb8E&z^4M4o_&OMv4Mktbl{3TSx(Ca!^$C!i64wYOOd
zPUv`ho3Y>_+8-SJZNXs0sJQ~(+XNjibqN&Yu7<bq^)$i74QXKx>T9k+?Q8P49EOxb
zpp*m3J4nlM7-1`iwmX3G&uvit`2<??>A_!j1JoOZtsL48&PSm90$MqB0W{@u0o*;!
z0_8nWUIOI}(5fl;N*@WxP#h>ffy`w=Hdg^W1PRVlATvR$rQl|2K!)N#WfaQFA<zf_
zv`Y(GFORf93emrP7#)YQVh3EG$bsq;&*oR4!-hLuRCsQKFz8%c@T|`x*nAJ_Iw4JL
zny@Vsx(-?h0JStk#li4^N9!e@ULGOP8UoO;VF=Vh8_>DC;7<5+BpX9i0-!o%gi3TF
z1C1~pH7Ww2d@KNJuuFiJMfr4w9OUq5KEUK@dARg4#9p*DLWqhJx)=dV{fT9b5JDSN
zJ#1M5yeI;%5dt{}QLKR0%wg7|&|;+oQ~-j~IAlNtU(o^@e>x3XvJ-t0d8v-q0p#^K
z$O9^%$`)<>iN6IjYY7^If>yRr??ac`Fv1p{Al12;i*X=}PLQf!^u;)!MJGtLF#19q
z(4rHh${2kS4rtK{Qk{&x00*34AXPJB;SG4v2`J@*TS$hNz!RE044_3M+p#Pnnds4c
zhzZ9c5=0!srd@p*Pe2Picr;^KM1oTvs1U%mhy=Wb6_jWLphKVhEhoS=P!QU@2PCQR
zx19#f{_($m3t#pDS``MG1@LTsiE@c3cq_}%H2%c1pZTBN057cg%>V2mc!@_Ezs8p|
z{^C2J^$v-kMb-z>_(eW}*LU!1JcKRH@LZ6_uK`<^A@V2<ve;`QXdwn@WyA*LRTGI5
zpwf|``pgqF_UQ;3`{Zwr{r~^JPv<Qk%^RSxPmhC-SUean`hu2C+=mpku<8vK($Knw
zk-udhL;<3j!?J8*7E}$W=>l4x#DuYIqNEBmObRM?LGsKPOC}&yBdF*F$+KWAmng9U
z=?67wK=P~@OC?IAK*c(!2tI(cL;^I|@0b9Z=m(WxprW=Lc2YUG#M1zmU*HUQ+~pwn
z7-^8lLFwcW^x$!D0SHQDm~-?X-LRFJh+-ObivAAL1Uq~|C~S(}p+pT*Xdhq#9ls1W
z19^u29+Cl|Bns~dOS*OoxVB!xoT7gYT^a>W)u5G{h)oAVObiUZy*v|e%+>z`w+4Rk
z^S6Bgw+4_`X2a*|`P+^{QvYq=-U#q@y7{W@Yq%NG`15u1*Kjky3(mt1pjA)K8({07
zK-;^@4yW;#okmREgNE}HK}(=6Le@ql9!lfSJO$Dh{2-0L40O%zK@iXTLK^@5D?XN|
zA=+;rP2&g6{O5lJ?Gj7l&-?`4S#~asKl2(y?DkpElrg^`iy?ng1}OO>tp=FD-@?ww
zz~I^~;o5o|6oR1T0ACqEA^|MmK!vRb03B}S+U>#N+Io_ID(q%SQ1*B14&VWWKJ04A
z?Vv2sT_Di<jejcaZb@)=syjjiWC!eWNzm>&*X{_2#n9^|>s-47WFXdpkEJcib?x?0
zfLIBdXy7P`aqJFI0b2)I6X4_6U7!KB3N-V;Rbu1V9iaoZ2C^nV$F)1c0PHvDJ(JR|
z-2o;LE1;_a9J?bdz&iMl@`vF8*KVE$u+4~DC*L3`KuLmPuH9JH3A_TQzwQvwyvHSv
zUZ?;3ElVJ4L~y0M4tTn&!<X(rhl7FA9B9D+>nd&r!`q;wAq`D%pk(IR3`=y-<a8LM
zBKbiYKWynOII-OXiF$)}6Q=Pe9!}#2ZH7ralg6KU2eMWdwBjHWbiMQGG=7jcWc2|k
zDHZi1uR55(-*O5Z?XX1$;3ZMr;1vdtH3zG~(%|I;kR=D;lCm4TegLxKpcA43v}gdd
z;Gm?&u^YTf0KC>9-?1CKEC9UJAjz>iKnB!>1+6p)b?gpM08LeQ1ag#kfKmr+oq@Gu
zcYp?LnSq{TcYqFTm4TvTcYpzGk%5R~cYq0OjRCu3w}S;}i9sCbWV3Fb2IM6M@1x_;
z*N4EP9eEW0CHN8v9~H#n0Z=m@v%LjfJP-gMu?UF(&!B_W_pn4jBMw{+KxXv7Q3l#J
zdI&UpFA2IM7Sx_P3SUVO=-<mSp(N6=8x##`oq{EPj?g#&ohDu4;Mfg`0MJ3wB}Sl(
z3))2oI^(89#jzW_UV{a6d~}HzEbKuiN0)Fob~{KwM(uH?dc-*OE2M={KD|Nz`CEFx
zvz-nC9+n3^dL2OrryumRJitHsfFsAjk`j;RU)*JR9=%R~JPy8K@@PK5=-K>>$)i`M
z6}+^<#MSU5Z0dpoHg&=2*?dsI$MQz`3y)rwxgd3(nzuX{4|*~l@UXm9BInr6;M;ns
zld(j^vD<;g6S|@R6uBIojvSz#J}7r1A83odFaSA6qxuchl7_@=;Qx|r&t6BkyFo)0
zKD{CkcZ06ifX=u`fEq+dQFf#Jg;y^NsL9IUqj?G9Y+uWZU}t+EoDJ&Hfu>jx&PES?
z3Fxu)KAn=Vn+`yskK)2QoG!$@XazEL3>hkO;unORVD4dg1GH%65@ek0A~>ljI(EaR
zLd8HK4RSK5?+H#a9H3q%+IkD*VC{gPwNICV^3Iacf^xK=grwd<Tu_2aNKeZHp1ls>
zg3`nCAW}ieK3Y%?-+~f6P5>Sy2>4&3;Mffs^n(o-fA%1F2nMEl+%qYG|M^?CfNNzO
zwO2G~)$ytM(B&Td8lvasbAviIr$JR2xP2m##((=n8h_CR0nqqQ<RQ@Btq8=rV^D2z
z9&0UU5A_*nDgfrI5-m{e0q%Y_|6+uB){&(|$gvwdtbYJ5#u0rOJ|*Pa3-ZWKut(s{
z3;xN6Agv3IL;NlKL2}JMS^3+xf>=nEHA*8R3gq3}^SBwn%Ov<UMDNdoco)>*0JV`p
z12$N^%P+_x=mB2Xc%%FRMpMMo@@5Itw{Lx0FM+%OntsrP`}Pv3Wdafg&tf2a`xYby
zQkn^Ft2lOxG=RoUL86b+`0G?ai-H(I%Na3eB~VhqCs6o;_I%(vIz<H<7oLzIR<L?d
zpC5T_=nhJ278Kye(Sj1C-IE8Jlt|;(kX<tuntC9~1)OmBpFK$9*Ej<n{z>CMbczwY
zr-nb|bQ*ue8Sso8WEAJnDaJI2C@4j_L<&IKx;M%<`)HyxK%l`38o32K9^_eg@E!m)
zM_|H^9EijO7ZU)ljfE`YhqP6Hf>xdNvRnig!7LL%xBI}0V90F`9?iel`P(4ta=iX{
z9(>6JS{4gRPF}q-y`Z*eSq^9fHH}|Gb;TTR&>|N||BQtJoSOKbU4U#H0&QgCKXe)v
z24~XvBTn%P@;E|+;4~-*K!OMP1zj8kJem&(fTjqxf?B$kx1h_>W|VkCqVS1t>m`u4
z9)P0n0cdTS5j0DI6B$SfK1|O6YTtvi)oqaY4UiVllz{-OVGQ2+>&dV6611)NC20H_
z)GYU~JXHEH8aiI?q5|K|3u<jc6Oc!ziwej692E}4W?r0w^xd!#BZMYGgY*zfK?|cw
zz%9?_SKzI@p3MhX5QbEK@M!+^zw|z6pbO+!_~Zasp9!eNid7%ln7!u*pU%J^V581p
z8?Q%XH0XFWX!sqJ-#};X!1CKojJ$IVU*5@p<ehxgfLYMI!>=J5G7DT39RX(`Xa0O1
zP|15Rjlbw3XzG<e5<LDMaS%S@4sW)@rnhgDA3)1BA&@i!$~92OgNhc=fHh-@1vJ@!
zGY@Q_9qKPfjuJ^&feag9he-*bO^|9p?Es|=*jOrP)EcB7luKbjbOSU<;?o_YV&U6*
z+p{<LKYxoPcyP`ep0_-je{sU{7JnOPClx4vff`D#hL=Fu%yA|+gHPu*(56I><^xE}
zWItnMwlw|_P@Xykl{u8gf9NnMqa8`(k2sXZuW=DP+{`cN0UCq849SYcH#qnO12&}b
zi=5^cba=oo=mA=}U*7A{dBa2VmTxc143C2kSU~+a%iH`dpzEWceh2NegkH)A%4ncL
zSVsO9E6^6SZt$!eIFRAP$k3nxZNCFe(!)X;RJ_86kzr~S_**`K2TUN-4xrg^_)s!T
zjREw|ux<wdXw}LBA5Mm;ae&?#*6knyRf8B(hN%gFP9=gy0r=m8+{^|aT861fC`ohd
zc94OZ!4BVf2a_)-adYf;P=LyFAn&?^Dgkf11GRe`RKTi`cH6;JfVSI##;&oAKw~LR
z&^C$T9)Sjz4BCj2K>@8qf$kFn7X~-U8HPsbxDTfB>g!X%g^TX~siWi7!+X3M*BLdm
znhB|$3`tq3lSfn5@J?AMh1&oQ@co`JI>0wNz&FSS_)x~;2X?jqK0}E*p8=W}Hvq4E
z8p3lm*k?k}OD629;KNCty@CHr27JB*epxMKKmyd=@xVDC(E=K-08OCP`Sju#jBo^9
zR13OX9z0158H9k$Cqkxqz@rQNg5W)};1Px!Xd?`uuC{OMCD51xc#;P+XoWt>V|c)^
zTc*LIQwFqD4t%E^z6mut&-^^<8m$;cD~8dEq1yp6`;A^K5?wKXhFrh{qeEwI3VV@{
z9s<}^jaCef0yL=@2Hi~8gBJLBtLT#!aL08x&vbokM$B}5ZH9OkJU8LUpFcX&1zopA
z{7l!OCTQvz!82X^8b@ckFlL;<dss9bu?$TQ$C)maQe71~1p=D>fz6Cz+nIt=$MUxj
zH$7%p56y7=8nUMK;PPt-Opk$v0yGSv2Z?sGOaRStfal#{;eziVQN(m3fyp$KSkOU=
z1$2F&SzqLNe(*t}6i&qLs2!b%`-Rxk0iCyU9JUj2&@F7>`7?cJTJr$Su0v-%!SiU%
z2L-^hpU?#72$`S1_!%@gk91NaxUdAx8bgZ=#Ed?D=kdfno3Wku_!4wRFKo|DiI8Wr
z%>k6N1K)i{T^lau3tt=Vf_J>*GGt4@1sq#Zw!^msfDW8SJv$KT{tM6wbKl+o&{^oR
zpDJPF9b70|0$w$MmNGSgc1(d7K@0eg9qa(Hye9A;JJkUi6aw**9;ETZmYRdMZ6$)2
zpo3&UM@uDwx1o4#0O<gWT>zas>0^1C|JW6f5ug*kPo?o^K7wvU0qrILU9E8nb~Ghu
z_W*xW9C#zjO&`r0K9;xqds%Kkb`W@im#%jR^0$C?5O_k?t0Q(0ctRGbBX$sYLbe4U
zb`W?%b^}0m5O_j106=ySctY0vLv|2&b_ZC%cMy1X2ROiY5O{V6c))iMcy<Q_z;_UM
zb_YbjcMy1X2PD9E5O{V6WWaY2cy>D!z;+P$cJmy-zk>jgO3-!?pdT4_2fT0u{ro}5
zKD@F_P}D<K8KFk`A@J5Crw!nkdH|2_3m%rYKoJOva%_<e5(C9k`C9lU@JLW3l|(`!
z2)wrd7CVr=1+b`r>@9%B3uJErEK(qQ3t+JV*<0Y*?O*`jTY$E=0y+Pn4p@WgQTPJ<
z0-Vd+E#TWKSR!C+XM7?AKw*Hg7XL1Mam+;jUX}|ba-QHd?V!yAp55T{y1>T~vU_$r
z2!J;apbj1&BG6@MI1}k)x>ukw%ST1S@Brv^b3xB;kps}pe&E%G??KWbD)5bV$WcP)
zB2B(@v`Fg+WGShEWggH0tofrw+GvqBTBI?aKrhlDWmZWk(s(uh<U^2kyc~y0ygZwK
z375I}_Imv@JYaaq^Wsa;3SR$S8BS0&$->~#e29@>5WMYEz|-<#`Ae@}7SN%}44@@`
zj0b!zZ<R=aDv3_U!-fY?3(Z5N??LTE#6dBo@~<7>9X)8v7HNfOi89Eb)&rHdJv$GB
z)OlWf-TZ*jlk@OrPkyb#pZOyWygrF$qT*{$(3Bpi>v$rKzwQLc)K1U|8PFw_C0bB3
zZ$ixk8F=wE%uIfb3!nKTKr7BKygmXd;XxGus8?Dl`Pv=i1dzd?wV*7ZBMBHiEiaZB
zcy_Z~@Mt|y`M|UD5J-vV#aAFhIS+wcc?jf6&=rR;^`#e3jFo=vhvME&gu$jTgYQ8N
z2AO*Cl_%6-B&Q-Ym7Ycm4`>L3`xv0G0Ie<sonr{Ot`2tye*%T@Cu||C{2Fxn(Mgbr
zCqTUxa1eW-gs~1ZjIX1IG1$~JevJ#CK!NPRUw7g4L6qQthBC--(1K8Sryox!gUmbx
zaw+HrvWuYP2|6eOHI!vv2ZKTxWGuwZ9-RoIEnwk%2R)p@Mx!_vNnhy+kjo*t$+Oq#
zf2qi8W$2be@B(j-<{$q{1VQ~J$NL(UPj9fE$mM2ueHYTR12vNzpvOp*%D&dQZKDF!
zo5r8dqXN0E3Dtx<H(1+1CR~Axq=Ako04<>f*)0BA4Wt`%ae!y@0gl_CRo=*!Kf1x{
z4bplGVmWA0g9A*j#%pt^<uL6&-8?EF_i^}i!q#~s8+P#q>%SashSw*d?m)`UYDjqm
zl-Qu_r$Iwp{DQEvIN)jS3N&?K$<>F@QnAWwS5VFZXFia@psTU?>kf1x4bi}jy@uOZ
z)Euq&8nnq1vU%pX%S9H@?gUUyg{7eq6<ET!0ZkZ~Is5f7P$GaA5^_l88OFdB!o1tK
z%|kEG)L(mmd=5&v;O$PJ{EIYL1uNBHCFNyw&x4ZiVNmV>Wi;gBuTpfA)A+B!ub{wE
zLJ(&%Xt1MH^R*Y;&7c7fWH*D-Cn%wLH2?Y!kFtxNod-cWJTJZkm2sR0L9RXscJ+Ql
zO2BG1va8838<fs9ZoY%%M47ucUTfdB1Z5^)#uM-}I#4s>{Tr-*Gr1XFU%v}F@B@?&
zK__*9&oC&JyL;ocF2n%PSsfr3L9Wq2HRA3K)?FYYu7ZpJy8-Hg5^=`{90M#wDub_(
z@c^HxPzpXO0p}69pqpbL_iljhIz}BpfuH38ImsS$o<eH|bZi+hnUls}axjhmK4RCs
zr{&G^2R@7!;TJITw|oFC#)tX~bcP1#xD3aJ3P#Xv6O5osJNa8cN9H>=KrYz;9kI>C
z-?9s=tAZJ%3VNT$a)=NMNC<kJ2I#m4$A$`4kP!4XjYfzn@I@S;1G(8siX0m%*g+~F
z2WKQZHdKJG<bWKT5#rcT!3mOuoSNb4*iZq!oP!HAx=~{0*igX@l7*a^q3+mF0luaK
zbh!ghiG*WA1usYza$W|fV?zb_(hl$?8jcM%45;H^NL#9C5kF7UM&pOV_(9EPuKe5J
z3qTOPde9jbph^_9G7u7tklcean;F8#Db>OG5$lmTW%`Ig8Prn|Kw0VqYL)^uxg9}{
zL%zpkTL3sWA>CuL4Scf+WJquoC|mGv3jpUOq<c)Zflnd<4GKcHvhZ&U0OzERK-Q89
z&@D>fOa#5hWLp3@4}ne>i2=!hvk>Tb5kC+QoP#<7IYAe5Yy;nh!qpMT1v(XPTL3u!
zK<_cx20q(_rz4ODbSmDq0C4Vs-ea=Ofe$o92s&c~bi*w25aBzt6B8uUT>1CGA_#em
z@HwbjMzqaJ@F_$qG5f(W#1rUic>;7XB<R);$gPkET{%wiw-mvnG6Sp-dsKoN^`Jw=
zkq@~@<Ig_@x!E!0L>hm>%{2ZD&<0MKNXVu%&@N8Ug+%Az1*capPay0<B9J#*52SSp
z^0$Ca{7-Y_-v^0o&;TQU3*<r~{(X?>1`RX9E+pdL2Z?adU?c28BL01lC<hHW!Y(A@
z-v^0w(7+?))Jm`&;HXanU8hn7=7S?Ytuv6XBn!+3M}HdVf|V#RADjTvIs=737ZUOB
zgCv18(3LAzV0myNNb3v~16@eOzYmfO(mDerKo=76?}H?Sw9Y^&(1k?&`yBYvIvr&|
zTQ5N|4LJ=RbnGa273CX@(sVTLxQ0&Lp_jDqjEpo^{1Po6izDTCRAph{Y-|DT*6_Ei
z1Lsbji8!+HBzQIk9V>;S;ltn74LQW@iBE4N_z*ML#jbZi=SYDD&S7Usu^6QBr`&)X
zOO$XrjXwi)VAL(>#jY<QCrc&124#OoenHR~XW+XHvp1yir=CdTPXyhwe$bI$FdB3k
zpYsDyIWP^m9GD2%UhN1e20*32IdEwXEd)9PSs;@_pke{seCiD3fNoxd6#$)qJp3)7
zJNiIsz>TNQKmk~Z56%3bd|CmL2WNXwuFL}Qz?r@?P^KgX!~<vf&OimwIjH*rz!|<X
zPz6-tL$iBlpa!VK-v=r2I|Fq<R}w+9dS{>ksKke6^v*yN(3M2{9QZmNEufc*@8e-W
zK6?mswZ~}Of+qYxVL$xhcC-`_94!S#O97sdUBaW50=}SXuK5LM*dA&20;4T}QyF+W
zuLatj&!7%l0lax&1isRp=OT{gfhOeccR~I(d9Xs{RzA|gl0T5<!8iDU(6Ec0)A;kR
zftm=|?tV|X0Bt6mO5@Ksl*XTb6>_#@>P5(1@QJrTr<+1nA7ma+<4?Sv#-INu&4oYz
za2kKw?==3b`)MxxNypRp^M5+>3r2yilfUE2F9=?{lE$BQGmSs%bQ*us?==4WTaNsK
zUJKIr^FjAAS4~LcPdf#@4GnbRJV+3<Y$fdk$TpB!8`AibE~fEkf!ZR_ThTzPSDG}j
z+!7C3a{-E|)&m}(1_@|T#}n2o@c_3!K!Z9UA#kk)x{w4ir~?uLcS1cn110!dK!Z9U
zA#j@nbXgjI3usUWBn0k;f-X$sZvhSJfP}y;6Aw@`q6owVH%&Y`11(CDL0oX##G^CN
zp(F&v1vgGSIs-jQTtQs$fR0CJU_gl(hzstEcytCvl&FKa-~k<v&cK8c2@n_DCH3eG
z%qZdX1a(9_Ivo+Wq`UBIxTq+2G#`PqT73EU@h~7C1@rFp6{;md{?SATY7p~}CPD{3
zQWGI+xr%c%i%4bQE*9#bmv66!0C;hpC+I}JL&$eJj}ChAQ)|#`G~n4mea~&+6M8vD
zM;n_DGWvER=4VDn8%IYQM@NeBj})U<aX3aBM~9k5hnhfB`tbSq(E(?V)&rpa-ROYx
z=wt$D2pZgTAHtIfs1*UuF(e|DQLUFhI@IJe+RGmuY8oByWF4a8oydzzLHGFWLph?K
z;0gWw80yhZ=tpmvCx8d$an{K$kP&=-{x&PHLgW#Ac+Z)?Z8~HG|1Eri|F%cxJ<ymu
zboBl)c-MmgY^pzvAAR&b^&xaG=an@6%rpGammK*8gEyq{=U?WJ23;cyn(I%6j`(MS
zZ$9OZ2Hm^o`~WHsx?rlP3vIH$8FUOX|31jk#H|Mq*F9!IBmx*g>t#VpC!tb~Ec`8?
zMQETJ8g%6;=>9vzHOu@hMo@jsP<_lWeLVav;PaG0Yl5J1peusG*D4F}xBP-GGhl_v
zfvyP#%Zc!}+=I%&?(1WNnJK~FatJEN4%NpFlaqm6&AJbMl`RKMP64ub1>^@#s6I}Z
zoC@f=+<ow?pSfV-8lXD?_XTi6)pNtdbwJnU?hAn2_1FA^2PSS%q6IRa7pk5YCT;?{
zE*G@ki2pq(xIue7ke4KYlz(>Q*E$GVAr8J`0CeK}ljyj^BQ;&#_5i2LTWS1tlKd^m
z>GBCQU4pJ-NJLAQw>_GFfYK#MTO<c+x&-M1rAx3rv~+pNqxlCYU0woRX^oaHL1u!|
zCD=?{=`xMK&JitLo&;@j{>-m+DviI+6D?hW+yY9MV7H*9OORVY=@RS~q;v^#2Pj>F
z-GP)Y--0$qf9BVE1-f1vTe<|f4JloM+yzRPV0R&<OZau%kVz+3(4-USHUdz(e3`~y
zr-PC%@s`Kv_oF^QEVBn6HK5{%S{{ScgEsphZMZ1C13H`@bXz58qSd22L<Mn!<YI7<
zi*t6hA6_=Mf)yf{%}BGW;6;t#`%?oUi?5!bmd#&~%jQ=Nm}PVR6{MNf4{7`;Gpona
z_!F;v=707%jlbabJ4b%OP2j!%{LgNKCPG0st=<G*zzX6`0Nu9=o=W}9|Ljy6f59b?
z1~1T6;U~cNb%5k9eCB_433O+NBfnq}sECI)Xx%aAPSJ{Y&~2iiO%kZt2vmeKLZuuz
zuoUkwIRVsc1kwk(vHH*_enC)@$0*)m`V_Df?=U$HEX6xa&HzjC4wJLMQoO_D9IzDc
zFgXvj;vFU)fL6T2#3Rs(cbIqrTJa7O&p;~PL5Ud@HsI-8&@Lv#$}><g{|QvggEo`F
zkL!GbbhRb8!-wV4)W_hIj5EofhbQ@?V1*+t$sdL^KtL^;Zyv1&KJjaP0u?Bqz-tGV
zK_tPg8c@j#O7@RH(vKhu3EH6Ypq9-yPz{2l9khrMbY(ZFRtL3iK&3D!`QHNRzXe%h
z;0DzXx_KC6KIqbRxcLhFEoxACP%8&yKIr0hnDYWP_*>YZ@}QOu$b7a>{917H4ftE0
zA+>fuwFCPneyvL&`!9i(CP0>AgWLzYxfo<W2huI?fewf)18VhvY75R!pxVNNzwQ-i
z@d9FzChTToE>N-tnSThpngP5>6Vw6%)g0WPKsA~Nf88nY(gr_}y`WYQ$X`6j;g$ed
zqzP&Xf&9da?57OyB25QA(9KGp__bgc=Rj6KU}TxMpe%!VAI<}$Yy+w%Ks6HlVjKm~
za&Xu!H))+NDtz}{RQSL<Cp|$|)I0#$0y+f;enkzqV$#O04cn1nS0Ojk!0yBFXg%QB
zE5cAB2Q}dU_<9_K&6OW~EDx1p-pJ$I%fnD&h(lA2iU7!00-)+o!lTpigGXoJ4`0g@
zrRO1*L(c#LJ6#>QPDS1tsRe3m!nQ}2V!6g1Th|C>^J6La8helCHyWV2m|qj@tPqt1
z_;M!!W(EeIUXhES9Sy#g7aaK~ABJpdIONK4nZJdRnSlYa4eUD+rPDW*<xZeW&C~ev
z??F3Ee=#a$^i|P!A=l@o-h?i9dJI_|oqr>ZKl3<$^piCH#QXdjfA~cofv!!9KEN;X
zi$5AvDJM1XYdqu^J;g8b$dO-g7pS@h)w>J$HBR%3-hy0to-_d@v;ltM52*GA)x}<*
zh1Jjs*&DM${s76~pwj7pN9zG->_GbljQlMZAoAb>3RJ%`!Y=>e*8=y3IQUyYClG=1
z8mNo{DPe+L0t8hez~9mZH3d{mfs`;Gca(wbI)#`b!QYY&RRSuhKuTDSJE|ZnQQ&WJ
zfhqwNRv;y;#~pQ$m1yv{C_<Hh$}5l(w&RW_$Vv?OTmB&xSs*3s#~p2um00k%+=eOv
zm0BPr9LF79kd-*_x9or_0To;zC7j0{eUO!S@V9`jas`D8yzDye7=o-Mpri~W4Jy7s
zCU75jj6s%;C<zBigGw-vG|zFz6lCdy5(|(ts1O55^B#B1L6*)ak#qzt-U8L@#~n+c
zQlR_>Da!aYKv|{vh(>hWVMO*kzz9tM9?b_qodB@<AHJ3cOK-nE2|8g1eo`I(KG2b%
zkRBt(hTl^3R<#DgidV>cZJ`Ykco6{JSBltIU7~|WAE*{UZk2;is`F@mlL0RYT=+Fz
zR1{qJHGNbJT=+FZR2*FRHDgo)Ji4c-fDce_1@B$uZ;@ePVDRj`1S%su4?be?WITnX
zsE}s?7ZsxXZK5ooG9~DP=fPJjpxdQ<J1=`4d<<H}$H(8cn2`ZA{`1YJ*Avoq$Fef=
zE~u#BfsCy*9%KOPNC92(elU$c;ZPcX257s~RnWr618MxAF_hGsX)gTW6SqLiCNF}@
zjnA(9&p;a}E~mNjYux<I|LjMaD?jM+I7j~Cn;hV_`DYjYXBR*7KfC41FWAZO|NnoG
zo&zBDC(<1Gi*Im%+U&0Uf{hCQ|Nl>O;nz5x#$SA&!;xQbrvpfYU*ks_NSPzQU}FMA
z;BXp$@okXlm)@oEiyQ&>6F{y1G#7r6J0NwSvMG&U;}EFdkj7tpivuKc2CUWvtU=_D
zBfp^IgfvHfjYF>df-^t-`~M##4RWKv|Ns9%vK!JI`SU@tjRs(Ai*JA&<#-^CU*jP7
zCN7W@1He)uM;!SDBO4s~1p^m=w1P@I&j&u1m-(AI{{8>&+j-NM@rIA)4bOuQS$r5z
z`dHrLZ_#C9U;u3>0p$&k)&sCz<)Eeoq%*<;QGh7);FodnYk@l#0{ks6pd}5w)PrBf
z1y!TK-*N=1243vJFXMu$G2m}m096Ao_u!XtLDe|$x70w@zzaT)<Bk!aEDd$CV*q~(
zXhSooK!BHg@XNTM<|Od9m_W^ek4?cZ<btXx;BOIts)3h%$d__Kl!5Q$LbUzhMW6@L
z<y=sepu4#c8+70$p~vyY6(ILBFfc&9&<M(q{4JB9#VWi|^f=xKDr!NBVJbH;Fff$l
zfcy$C8$FIUo&YI9GVcILl^aMEyomHT-gpB|)di3$1$as6alG*bLIvm`jz-YxUQlxm
zTwp?0zq;^ifJ+n&aEYP;Dp8t`WS|wKuv7)w^A9cN96x|c(p#@LfLcx(ux6PSqKrEL
zFB@UHpoN^{2T#ijrPpAmSh%P-fOg&=0JpBRpe?jlpjG3DRvp^$h_{d~D1$di!G?g_
zh8j>qz->bXgejHKOU^(oMC6;&P$mf_(j2iKj`#v?4;vnJXzTn|Ku$jl057oQ5d>{T
zMP6Xp4d27o2;S_5+^2*OahIjT?oE850o@!9y3h5s1~&s}P#e6FKLSMhL<pqummW&v
zFFlpUfB#4t|NS$d!wX?26T**$1MN*a>ce=^NArS@<t6`KmH^luRjBVlJNzMgRGT6D
z`N5l#VS7}YE5N(=!Ars+9iueI<_hp$eeldOY>#R)WQRVeI$?qBQEi6o%LlIthm0kF
z^n!QegO`PuRDt;5{rBK?;h;UL%@qQm?fKw^;U!TZc_9!VyfPfLYOJ|J1jGj~4KJ|*
z$%}#b;I-kPJ*v$W5+FW!aX4s?YIB7Yh!0*J4%(yITp<JEgZKNVIX2rkpltYmi?KzO
zx^XI^jufZj>Z5VWNtZZ9$@k)}{M%uB(2-6v#n`TbQyE&W2MwkB_VVD$^}g_2?~Etc
zdxMVaU{i&r4lFtS_MtTX+o#g_(?NUCStMb*&#$88Y{)qS+XXz3&l%Vb-ewLtc@(l-
zY&&>EIr2FJ+XFyZ5_0w^WY_6-@akRUa|X79w}*pIAgyrZ-wxgk4nBf33&i6C4bMZ*
z8Q2~m06T=#4<si9JB8E%#1jD>)B!zbV0(ZVXt*7E&cOBn3D`lTVjz`Lu#-qR9Qn69
z$iUAT*v{jCcFq9JBBfAyG*ZZo6qI}?fs~<;&whCE`EW3(X<-0r)b<Aa=Wl`BM~(Az
zj&0z3qJFURx2<6Sb!j|)cpiMo3_AACqxlz`SFa3c9}`2Ffh+g|bWmN%0=jdX5mY4#
zdNv;t@U^^I{=%o1N7_U4mJj1e(CJB*H%by5`L{E8v|dW<WGo2*B{wF}mD_2Zj!Y%4
zATA5&?%K3YN0t&Z5SI;fO>J7IBU_0&h|A&8{EH>6(~+Y@0>tI=X#T~T*6GMq!U^K?
zfKP=z?9nU2V0gfle>>!41V)eM156&47fRovos%K%%D*38L?KRM#ZpA!P!<g8^+L{-
zb^OoYvJbTPt2gk6$H7<3pcB_Tnt!nQ^om>sH5$vjK@ASHqf8KIUm&)-JMjx5pMBwB
zd8_=Kk0$8$V6R>t&~dW?C6SIGcZ1d+f;OA)hZH-Vfh?fS=KCQ<PG=woXdH7tq__bc
zRH5R?zaLW6fR3dQ1Mxt$J1b~&JBK6xeg~dTM+tDf?4p85Bd@_xFVg7K%fsMndBML|
zgaa~4b`jL<0*{iNf~ONutJ<d*HJ$ju(h11_w_Ob{LC^jW02RJz{Q0Lrd+eaw{Xtz<
zP`N7-2s-;CPym#OK<%n?KAN|DEN^)A^33$_Wr+a$AC!bT8NvQ{0H+{Oig5t>1Dt?B
zDZ~iG1E-%(M;_2-`~Bdfd09Fg1wiAt`yIfkr_)gcwAmi!f5QWg{QE^1I>C3FF?m`Z
zEJeSSY&6w0{}@d*B&Ql*P@W}b_b$AwLEYqwez-Si^2HOQuz?)z&EM7mS-|rIJ|+zv
zk48G719Hwc=!A|`=vZ{(=`{XK=m{O5{j&Klp?hXwCv<on0F_vd{DN5<()dB!W0OF;
zYC*eVqd-F|P7gq()in6|-#5XzHNg|)bMSUp(DqYkaRr*e0&PEqmRF!{u%PXy&;koI
zKLy%;3N5if+h0N3PxnJwMxdo&pf!Q}9e6xC9SxwXO<Ytg;8h!FEW@W)<RG46O9b3t
z{K3KB#szLLq83}Q>W#mx6B3edK_TgCcpG$$yboe66zB>h&t{~cgsy2y1f6FO8jic1
z#-9cnynC3&pLHsYKM8ckJt(ZeL3!GdUoZ(4lxQ1_eJxKHP4m#a<zaclqnGEVFR0)H
z1tqB91Kq0_;>o`sQu2W>R&)h%!9|}3sC+X6alvJuN2j9%I4B{7pGT*o0yrokrJqNq
zqXueF8XoWj6@VU{BA|5>;1UpY*a%7+WAL`^wIoNIk>oZbY1X!%Dn1%1<VFfgz9X$|
zk7pAyv~ABd65IB}u+ff^NJiVIqwP~x(t9<d?bA-d(e~+(ZJ&aMwm`FH;8`yPNB;ew
zd3NyG;NWxCQ5O@TuRy@29&MimTCE|($iRTv`+^Sjgn~K=m_t36AqO0RrtBfz1ODif
zPW*yAk^IpIKm#6;py4wCP#5Y1>VOY_%VO}%=YH5i9K;HoE{H?`Y@(SFD&@!mS~<Eu
z05)+9T3ilUk^@>fx<3Fm5e!;b4i@JDtsLDC-+TaCR1Ovw0IeL|58q$_T2Kxa7Xhst
z-R}UNWc>`;#)4(|$R6Ca!aIB<2kD2g^S6O|WH^V9pkazWe1t1Z1EFDx7(_aOI*0@h
zQ&2j2>(P4YGr!i0H2ykG$P5~2=m-?1w?TuGpZT?Jr1959Lc-Jm6sB)Mqm)oBnH=CS
zbpVAaNIfV_!RjGl>HwN72dM{zDaeXUNSHc+CcHuFL17A3j})eFVP;E!PI(0nNr4s}
ze&*MDl*V7D0y^v!+%<a|eHd@bhfXfT*U+G+e9)*MC<I_R1*9H2tqj)#UeOL3>9p`|
zJ?YsC8tF90n*1Sy4`o%L<PYjD8$x#tT?Q?J1C96L?kRufe|8bPUIesC9JGKOv`NV8
zz-RC>mVyJ|b>*Oy<e)`skYR=;sKX5K_=M#V=z;)7czh!A2vo|E11*oh#09|diO3@`
zaS60M0uxt2%Ofyx4Wv8*3RuwUYHXtwt&m)TZ?qy6o=c*^im{JYlvTrm-qr9nWRwCN
z_V`CBNDF(=xWp3FaS8qw&{cxaG8dGWK7sO*2Y=lQk4{F|GT!|T@ci@%l%G8K>u!KX
zE?~=e_apKZl6FUdk}ObOgy$_}y%Lb&UwHmP)~5g-{zl|6WPKWt;a^bM^%hwVC~lzR
zzo5*9v>F*P7V<C}?b10>$NLPhn-MHM7%zgZG$?%yS&RW{m&5KeDUm}`XrqF5p$T+_
zEhv{ku2%Ez72zxqaJ<jLaN7p7;+_e#vFZcNSRWM!@C9sORZ0+5Do8h!@Er8%3^~XF
znfN$VdJnQ{7;V`tqKbsB>%&r0Vp(>J&<0hXhIZ!&WZ5mqD~JLk4_|>%0}5?OfdQH%
zfox|XVx$tZ5LV+RXz43xIqWUa64wJLOI$aAgg~QhkRoFldXWKI@B^Alfv)v}1_QJT
zWrVHc+>a<ZFxR(2)^Q?LwCL+wLF+h?>Ra@+t)O+BNYyU-x>nFSPNdoweN8K99VfIB
zMyzE8uge6bWpK@4c*&#n0B9T(wEJ{FmUWq+E0~x-mjj{K4I0oK4XzttE0%m2Pe6+@
zc>RE7T_z%ppy@-eTVU%l!COZ_*(Csa#0X?@v1e}(+H4x6j^S?uO<sa_dBImwLI=3-
zBI=r#;JZsP2e?1;KYIwSYd-ToyOGAP@g<GF_zq|dVIpXI)5$b`jfb#xgq{o1_%%+$
zmNgy#Eo(fL#xL>-v^Fvgvf$ctLmI!v3D{D|jgTddBBvbr1rtGwt|LJ;mM16;I)X;W
z`P)N5x0rU`^3l8j8XfmI_=v@W@uDwi<>7ruTMkx%!9osNn=nG=7eVuOpn?>%tQWK(
zOae5y2vy=Jz~3?pVhEz)hq3aoqzYsPs6Yjofw*}XvMA5d08;sZ3RRFi3&x7W5-X5?
zP~!z8&x*0yutW+}V1o)*(BjDqsQW<6<s1`0Yvn*?QFPp4(B1$I!vh|zmwbA8gi1h(
zO$6K$@i^{skOQjg5GcJIf?hBQZt&cIE*pd2PE#U}RIVb{wSkM_r;v4Rpj~_+DjJ{#
zZI?WISprIA9q%)Ef+mHV4=UV7tYSM*`W&VKloa8YSW3Ef3%Isk;-AV0D(FGc#drd2
z{&U=W{e+kp7<_wqCg514_77a2|KjIw`vR`du`W{MZ#xQ^e7Nn~8v$M~oUa<m1irgm
z*O7^v!K3pYq*Zkod}XWi22k1utsVyLt}Z*A#$R?Cv1Tp*0_cX;H2zG`Yy@a+F#L+%
z;0I~^WtTy+V7(X8`0rowu{;gYe)}k7$y@%%G=6Ze<r8#c_qjCw%xe&_+h;)wW<Zy}
z@;7CGk~h*axC#6%?2HTyuH6!@t+zoT2wDgCl>sCYzyc0bN9aO0&{|5@ZVwLE)|32G
z9ic1XPJ@zjcK{D4^c|rq;kJXt3Itle@lSPxu7m@3kh&v8Kz2AnSHks!ZHa(b><C(S
z!&Xw~+8rPRu@<rxF4wi&LjhtXWHDTfV|RcG*gD8!I3LIE0u8WLpy_h15*x?v2pzCB
zki~F1uH6v^V81y+R>MiVb_bY1tbi_ubL@_=0PEmGO8<rjT)TN1z&3-g4TRj?fTRE=
z35vNAc{TJB$l^#`=?-+PKV(Zw9lmr2I%yV^=0MA(uK(v^fZP)-4NY*MWClCo-x;*2
zAC#O9gAz~j1JLSo(0Tr#<dnvrc@re+4cg3~#-9k9TD+OYp9s3&`3_{e3uwJn=HoPe
z(9|PH9J2Nbl$45kk=I;JfZX-$h;rAnV>fuQ17yY3YH+FmuW*1YxB{1i-Qd+zko8ue
znLJ0xZP1|QRwXr#-2tFAQs9+V`Hqllp}`BSk{r7OWMJ#8LLDLZLxT@k^Z=y}*eWY)
zN62N-;LBX}9J>Q_U~8-t9U(VIgRgQCaqJE-fvvD&ckFhs04=bJ1Ks4(&C`Iq!0J7E
z<5C<E?Z|6+UVc7|HXZ?Lfa4sG2!M}8ghYVXU4R$sL_mfkz#9iZTMCfMhr~mmMLgiu
zZ=m6bqwwK~K>uEr2_=z`XaL{n42uKMg)1cvj*#28nLt;qlo&ZeLmza>N{I?A=t0-3
zl!(E?9(1uv35R31g9K#l4$f4MSfBF>ypkydv`XcYPjAqF{+1rl5|my?0Z+>Vp1lsB
zBUcYXZtisCI9O8R(fo_OEYG9Y>5s?37fc?_2N*q@e=&LV%Cv%NnKBbs!;`MiRVf^x
zo)XCKoSw}G1$-=Tl)v!kWtj_7=c#!Ma+jxv<*gDq$8HASR`7+-j@=F{p3T1?7d|_7
zJ8*z6e1_z1<Qp5%mysanXjH#}TF#I~MS=fIvT<HkZ48f97Swx@JV4I&>SX~nO&NSN
zFF~B`Yk3juY!8I9L1P=BWiy~O32`=R==&zaR!1Q%MF3v_jdX{Q7%o*vDKzjuq?d=&
zFQCOixGx4mtTez_9CZV<IO>wG<wdVvo{Qkbspy#un<5wUOm+ZGi8F%wnI#;a$qpQ#
z$#L)^C*<S<THof;%W@H%d{`zp@=r!2AO055E(K5$;%{pMFNX5^<9YBU6KEYAC>eS6
z%JhPgM;YjX)!T*#Kq<+QKc9sGl#&qZo4{TG&+zjLia7EMx;P4WG#?NEb*3+XQkLZ{
z=p_G)5|9UcTQ7m;_`x0kB`$Oi7#{FV=4n7aS{q;TLR``H3fy4n4goEdfNpQ1euc5@
z=V*nY09%(kT44;<3IkMAcvv3v=ye2F7@n2~_$MELRT$i(6~<_VF`_CAS@0lO^9x4M
zxj78rp*`^B#NdwZV`#4%Iyh5;p%^+_22)H*-EW50j)BbFK=xjMnlewZHf7Af&TYK}
zb}i_3^b!@YNb@hS2OL;F^9wq%l<<QDL24X0Kmr^Xb^m(snr#OGY$XAI%Vbc)viTPa
zWEmjNCZsuf6B6nNcq{TL)>b6Q54U|Gevkki7zOsj6HtW@a&iJo8h>3P#1CM9f@bIH
z0y#i4LZExQL27s!()jCmKr8jY{l^z*E8OAn1UiZW6se#stgu09^hi|%g%xOo1FSgB
zlfUkeFXIWMrr&*(ZU?AQ2WlJPY}7fRMJ#+W2R!Ks8bU*!^}JDj)khPhB?k%~(D)G8
zIUt9FgXaLK)d~`FU;)jia6qCMEWiO05Wt9H(4lL%n|I3~QOwHUHV0qx&JL|<2louW
zAde%+FDPxg>u7B{C(sDDZ|fzHGZjE%S`R?YI~~vfCMdQ+!Wk?e@fYBho-k+{2P7E5
z0TKkwlL$a#9c+Y111NSbBDepZpvAnX<85N6B@ha6O-q2s>Y%4)lt@5L2JJ%iY(BsO
zy;r^T1!Qspq!xCKdWj~wS{vk93dB9?rPo2Df`?JMAJF^^Es&sN^JwML9njDo(vbj4
zpd{?s{0dwKfYLk0+{8VMGz{8nj57^`?m`Fk4x#-+a7T+j`T)Pi1%A<k{2~`2DcFf$
zP$UwxR}55MT|-O8puP<#8H2Jb1JoPf0?P>GSWs#P$vCjU=N1GVIZDJpa$s=|_=JL>
zqW~z9LD#Au@NGQ_DTG04SU`oqq0URtaZ*Omt_AeWtqL*_p1BcY%YvYd!LSnHHd-;S
ziJ}RV<_^JhqLvKTLH!D!?idvd-`3lny}|$aTTX%pqP*dqC6DG`obb+48F-$j*HOUL
z@RCpGHPAT;9?b_FKm$vl0V5Uzc=k%;*SHBDjprBi08Iyjw)sOw+tc_(Zl&>yoZ=UB
zc)%|hv4LOE1GGz~e7#5K4G+y*zP&6nJPtl!0rh?@Z}YcUf)7%74~hv;&SHRh1XQr_
zw@AZen}0Eaq#algyZQw|<LbX4Be9^;hY75J12M2J=%~QoaucC|8LWT@v7cYi(Eu`;
z1PRYyEMNr!h@o{sM+g2E=%Je+D_Fq_L=a=^f{p<tpm}wWBpX;#0<nc(&@rJT7HTv*
zSW*VDcVE!4pu_<x$pMyBK-sh}2;Q&{NlajAl~4SFji7=ZX~#ZnydG8t=t2y90X{4U
zR0x1|{s9$MpcL{0)Fbxj4Ez9Y4_t<(D&!%1M43Z)$ljyZ>3@k5q9joOSqLAt2V3!o
z<Z*kHqGm7+@K?OzVo2l9*G+iEH9EjQtOxjUota0gsUx`;kd(#tVl-uqP8~rDWmu06
zc{rNR<Ar5UN5>24I9`Z;GBfoDfR{cVjZiv9C`wZX_lzNt%8-U`Kr20m&BP+w;RhcW
zK<hI^8bB+fd@L{e^@?zUHnu~Kb~^;#*nS>7G632k3R;GNb7gV>d{cV}=s1qUjNsYT
z07A2?;3E=1yW5Y#7bZvg_p;0Y&8~tbut4V{_<<%DK|Mt9@dyr}*+tO0WANz+MvmPM
zJn+L2R2;h<1mI^Qh&gsUh`^6VK$=}OJmA<Z;*i!U0zMM~)KA1WZ!}1!B@uJtE~qX9
z4LyMF;T*z~!nh_=Q8Mr7l<Ux%az%|iq~uHIh8FLg(R!JV^)l@nS~j;vBb1I2ijt2<
z8(PrSbLcC$MjKi@pt+in)zBJpiz!AMS{w(5>e@E=tTt%!3pC3InofhwVWCfaVJIG5
zssLJ}=**wb0$%Mpx>SLIp=@-i0(|-D=u(A)0^kY8(WMG3plMuC*;+EXRAF?ff(Ixy
zfL2(IE>(bR^2V~eknE)j;-1iB;+tQ9_SJ&U%5DDfzZByrTAa#2W1o=ilqEu*%{B*6
z&Rc&6S|$~uf=?c$Z!6}DW49S`s?Y~ME`yf>@m#>M7jip%FC^%)AfI03y^u)v9)e~f
ze0u`~K<D&3pM(v3aG~r;dj;O|+XUK#3tC4Mw1EHE!4441YXbkVQyrkQW<k892hi<l
z7<(au4uE7pYP>dpbbwev7eFWe`&gdlKXwIV#6!rg$4t;sju)ZZ*{(puZl6Z%gp334
zguLmadBex@mVYnH4agQYPn0ceo{$Ywh%IcMkPT{xEo`2UeQAg-Y@U$qXpk*zo{$}A
zkS%PUkWFWhEo`3M0T%ErY@Xc#4j#=vAY0fxy8}GnTi86i0|H>@gzI^B2SmWPuz7X|
zB*0Dy7xC;4$bfHQ^XzsgfNf#(?dCavzJ-kr@qc_Y{yPF$N@@mW{G*f-;)t>YZ3`oj
z%FqwKy#rpcjeg2D<XnKVOi&2{*{zCNGC+=Kb=m;V&=26n!UYe@TcCUnDj7gIAANr`
zNDQ<awR|o7><G{--Hnn+NInMdfrMpZ$R0>o4u<T3gk@jI9!OZ;h3tWZMIK}X&9mFV
z0K5kha(OcHakiinYJGb}z{fb?n5=vSnXKgEZv*Y4MxU&N9cNpX1qvTf|Id*>pUbE7
z9%z>uXw{`B^bA|f0P+Qudyt|N6d1SysAw(xOqfXDUKVfw!KX1jyTOOgGD4;?Jt0$-
zOps|z&u#|^#5AU7w}S#=8q>4eK?5<3i4;JF2Ryq)8c^pk(avQ-uES8K2~m<APE|<L
z;DP^33UDqEwm>X$j{t4P2TlI^L<oQq7-%0UbPw%~^1JX=!JsqTFO<l6c7uYald(hu
z7CPXqn4rJ`?;wSr#tNCu1Z`&b=w+D**`o-$st~b9v7{WdxVEg&rx(ZGM03RAbq7$4
zgEE1S1K5%Lg5cff;GKx~;H%bWf};@RM(8eAkQ+fO)luDOcmQ1dcOo_*U`!_?azE;1
z?Px53)~M&xJr<C*b0F>HEhz<Ug9E262Lb-chde9~@=rd%aj3-0v-y{BnTv0)*FVDp
zhL=1qz65Q2_3xG81f?Ms29M@LjIbo+X?d~yrB^Qt=yDVW(6VdB1HP8GN~Az3y_4}U
zIL{tHtWiHy`W}4^8d73GnHt5JSWr~azS(hR-)OUA@HRW>5dV8d<A3nRKT0Vv+Ux|K
zIL<uU>}>uuIGUXU-k?Ou9yr^*#Hku^&kVcPF?zcUzROS0vs(nI)pQV})r6Sf^yJqf
zel`@U7;QEbX&6xgw8!hSC%+a8=s-ah#2#Z%s}1fvBvonrbr4mcb*1Rnd%|7$32HHD
z-yN<wTf|OekYez@L)86-_fZBk!EOMV%K|!Ojs<jFCS*4>ic4ic{(-21>{II$0jmVL
z_6bNO(xEn@j`uY{n<af2PuwPSs3%+@k-KLhCPR16a^T-Ri>8*WDJf78Lbsg~y?Yj<
z$CvR0w%xNxDMSGjqL37F+~pu_wg?ga4?v*`PbuIO08yRBUq|$IRghDV_iBQM#-XRI
z;@++b(gaR6FrBE$=Q=d`z_v5O_qoDi1(Zx2es~;r1n*=7O?p7KGNNll-v`M7(FjRj
zP~CX<K|&%JoXl=l3f#^VfMp5XlM4_n9?b_q`ye@p*$0W|+7OiD9*;V-MO~oNH%Hp_
zBBMb7Icgk~=^b}7g2o#`2g?ThFOhZR*JI$Hb-<C|^)P7jy)Wa54$v%?XY;TBrH?^*
z%|%56bYcanHpS15`~nR8dIxc7y${+|4!Vz;U(-YdRPF>oGc12gEB@m(3z--gAjcf0
zGlA}|M4nQD-vQ0vb`Y{>8|iq>U+W-yBp<Cq*(2%5F911R(~)1m`vCu;!z}!VPP3%(
z-#(JYfBOus!DB~$f#3)Hhc2^#22MdbLFXVsHC{>M2OX^m)=cElnmOPJCBzNW6Zl&|
zhd6@bV;3koK(XM+KkJ|izw0TF)&njboct}Z;0xRJ99ZBI%|94jIy@QqTb!U$97s}3
zE*+js{4MHGDIO##W|t06X8sl)sFVPb6pKrTCkubeN6-n3{CW-|NK&jW9iFWGE!Ut@
z5=c^PE*+k1{4KkoQZh(V>@FRi?EEdDTi+e|^&AwCq&QqUJURGVKu7n1q*Opsj{Gj5
z8ClMbK+ckUkf;VUJfLCG{DaG-!;`Bd7$m0y(g6;l<{#WH9iH4JHXvaGBw-$x4o{vE
zRgka=k}$7JhbM0dA4u4Of7SthmkS+%$R~P&BEs;1Bh+p^mIjbsSAN%1$n#^*kWTo-
zwE_4f{=~f%p14=zOWdGMOQ3T^K<9XZ?ybvLm0bf#+^lO*5;tfh50bh;EaH<lNHrpT
zgLvSBKFLquSk8{!2R)YoR8(+)LzZ9f1Snj=F$hiMGZ`5eKngrqkR{;>y$UAHfhrA6
z?4Sen!Mb@+rJ)Jl2Bup8RT`S;Wnt1HsM64c|BnIcGznB`XyOMQ`3$yO22~oG0YDe3
zf~6HurJ<Q%A<S?Us5DYW;BRS$$wG1iR0%lTU>PDAY`6}p6eLr4fTavjr63tY7c6Ch
zDh0_LLSQKie!UZfG6+Z^PXp8p^i1*yDU+bKP(Y3H&#wGB0=|qVkZu)!0j?=f&NaLa
zS#*HwAY4!d2B{%7;yVZz6vUtm1X^@(ZUt!c4^$O=Kv{Hf*a1|wANb544Z0rl!e{>I
zlb`}0eWnat8+_)Ez66p4=>XLR5XJdOOA2m-PRYf&te~g??NnUQK1Pq$1D_rFbp$#D
z`CCA<e;&<0K$8nP0W2MXjQlO2dzw9(e=vd61aNc&GV!<U0@dElKbXNnJRO0|{4L8N
zLM&h*fsQ~H{ua<Fz#h#%SiwRf9f7R;EsYRWY+xaYjzG4OBG4iOFjoe2D|s?#nE{xq
z&=JT{5&~Li0OqQIN@rKlQUfqo19UOD8ECNqn5zT2nOq&T+yKlq=m_K~0S#dBg1IIg
zfxIQ483!H2*}0%pfO>lFTj)ig$fsN0$Daxg!<U}y#Fq+If;WpsfR~<}SO!W3pwiA6
zJsE%my$PlRkgDJZu!I2Ofs0L2Qv!ce1!j9-G&O)Wwt_qVpwxg;c1R+Z9mq=&o}(NI
z1={p{9qSSU=<QBn;2B?MegPKngs(HdfKP+~q0A4;^GNf-x61dUovEA-%fz4+1yP6`
z3|>><g~-0(RRvZa@VpBi;MMYI{sGOn;FSeZh+GR^Tfha%MX(c=(fTo<dxU*^@ot2E
z3d!{B{B5_vN2H-%J_EnuI|9BDnk4`}6&^rz(7-oD??u}XoesL4$&p`&0kkDL3bY*>
z>>bcG@JuCMpbgPrJ_mR`ffZ;i0hkZE44$n-3$&U5%ohM(8!rV~PXOkNfbWe*2^vFi
zIf}YL8vW9E32-v<g;qg`l?5+QQW5BIJW%n8bKO7~zlP}DMO+Nv#Kf<02ozw>`~o}@
z{D%%Q@oU^j<1hLk&mVG&Kjt)~WOxs{869yd;u)-`BC3Fb%9CG*p_36*eEwqm?8&d=
zzyg}J=L9n$$2_Bro<i=e$8`qcB5>^gV&!j}0b=1gMmvIELzD;XA<%hg{2GVA3k{t4
z^LaS%dkKC>;%N_TM{TQs4oHM~3A6+O><<ht86NoT%df-JfPCaO4WmwJ;V_H3zy%-=
z4W_6Ab^Jj$*f@OV7vMcKpNqj0)Kvs6LT&)xXcO?iRO+?wXAgcI@C7xXalua5s6&aV
zV>d&miwe(YegPL19)3O6#`#<fMVCJF#~g%?P=GahbTaxFN_sF}1P@i5h8{u)9<uZV
zwUNNKf$Vph&&A-|da_jHwKYiN1;jFjgC&}vwk%5nzaFa$$ddaYOW=xp3=yNupwYwT
zHxi)p-5m@Mpjz;79?Sw~xL)v4^_B-q3>~{g8ahLee6x8T7emo?oEDvjdIV`i8&Yfy
zP|JDBTu_^7wB_v4{9^>Socm^jQUR#JJKAy{?ER?Gmb1uc%ena%xKrUk)s{1?3c}rT
zE-As;YKEK@4(fY>PvQmjx{!KRH_EY}6%K9{gE|oKR<R?ZRSaTcZ52-gcLK4uic9K1
z-HNgboF{@?pq~g1b1J;G`viAu7v@xOYZv4`Xlob5ggDjk0Ce~RY3VKY*6wI<L+<gR
zQ*cB3g-EM8zzZS3ElSXt&BCDGi%0`f^Re_T$}Bl91xQUf<f9r9xd`)CB+z-nIL~FM
z_h|mbT~>)R0UJXSFes~mw~2$Y89eR2#F}=sK<!}AwMgJCqcR{K<Z2|)$@?rN++YFN
zG5p}Jwg5}RXMRD*q7l&jrf)FLZU^1$gwqe8o1F&XMIG?fE1w<tqd*ICz$+1uk_6^C
z`rY8N#u0u&6=+byr&k0t%f(P;4IU!^4-SAv3HXH$@<(0dk2(Q9b=-+x&<A#L_>J;g
z@LdLw%aA}v=sy9C2{`gcDSYA=R0JQP54wyRG(a4c0XjlI6LN(9ZIEjtKu73DVjiIn
z8X>@agg$hHfDJN2fO8ju6?_*05BPQ@xJMvYBKaV$M7j;%h;S2hjCToWPx@QXIDjL6
zlm=*V1?Xbo643GaPoQOFR08<;{0H#k^PhmclK?(GA0!AnJ|FB$8SwG>H_?vI2lY2W
z%^su+dvC&z&?j<j4@3iW6$ycp@zK<hu(n45l#{?tgRbiVWjIj(7rHJ6yzT~jfq|3?
zF$)Z$VwsmfEZc%6`oS^n$S(l71`B>#KKPCVP;A5QzPf`J(e_}U`L<p{@>mJDT!EA%
zC}-q@Cz~A5&c}z9D_9pKfiFpbm&JmhZZ&dAjJ_WMer7%>Ex`|r2j75;xEclLA|!N8
z=%oN?G@v^~MFYB~p#*&q5~%GJ<?x5}MM!8GLHXqn-bF}|lt|JdB#0L1A|w_Zi;zI0
zH=uPN2T<32$fbc+D&Si5@d)R75v5O{^&)9_7L42jPXji;0pBK!x?torWKJE|9^~ur
zIrXy`bLvQYkR>3~(U(BG=)iO8vX;G&IrWV_NOS718qys31;E>oL7VG99Iu8n{zHdY
zK+L2CY5a#yfmV+k262lXr12km1md1f<3IEX#CQzaJ_eHWnvlkS`!h`WY5rqpKpT)@
zyO$qA&lo+D#-Dixq&(>W)TqRRAg<R2n9j%0)g}-V9Qg&3K$DM9#kU{xAA1He7qkuq
zbT{W0$laWYpetUVK{hxeU-2pmo_9jo*xU;VmjmD#dT{ij&(UXtRDhOFATKw8u0-*N
z$ssQ)fzHkw!{m^cjzFj8#bI*D3q+vv^1ne#dqDPSz+KY(13D=Wnso;`(gAtV2Xsar
zw96bUXMv;-Ivo$1A_dDiAjv`J;z2bySk40^hcppiQUVqZ00#|74rK;D94r}uB+d<9
zlVT4RPe2lf%)P6F#WRq^ArtTXVDSP%v+f{OEC)ck(Wl&>B2BsDT9=~D3_3Fx=RSUM
zX4s-DUS{+~S9tT#*G@<t%I!qSL!gl&cpd_Apm_+yM9M=TF0MQTk|QAxfs`ZVArKcw
z9s)^GIS-u$rDp#3kURt`>NwJ%%Ok)k2D;W|IU@rDNYVpU7QWb}9VRb;qPzJAG(V-o
z<R#GLp?S(3Ca-`d56xGgrD0(EHPGatc?)#eGg#gLO&*%Ro-;t*Z-FKc&11)5@(yV7
z(0m5UgJAPLVDd<LjlZP>rX7;sU~0f22wU}%4%Q!mCI`uP-e9=|G&xA#(+A6Cpvgh<
zpD<Xi03=5!4}w(k8~~}rmJc5y<wH<w6n+UgcmV$stUHg`_=sici#Yze?l*kV!$*uo
z4@mj+A$ZXP<h+f`t)QV>P@Uq0y66E?(}6PPvjb`T&rX7r1T9G8e|8DP0-dvw1F4E8
zfMxlgJxSxwLAz}@A9Q^*_%?Eo9?%IK&%kSBKs-?Pdv+3Z{svf|Bfmfpq~-!C$+-fp
zs7|Hv6FQB<0khJAE|&O&zH|m809q%5v~&h6B!IGX1}r3jvUCP4q=2$?1}vn3vUCP4
zWB^|}1Lj)5m(GB>4)CQjV6F#z=?s_~0AD%-=0?Dm&VacI@TD_gZU%Vi42X$1vjdch
zP*3duEtWvvK1uyl)Y}Y7MWCV+BNc%J5vd5ogQOx53zCXJEKpGnN)7l^5lAH>6@hrD
zsR$%8nu=(Yicrcd@RA!)Y6C6TLtAo#eyj(m!G?K*IrLbMDrke-kzW8U=^SzZ7Zaeu
z2ZSL7&;xJ*#1AccKxceFN*_EW4}ao8@HroI(9Zb)t;+%B9s&5e91t&n1F<d#%ojkc
z%K`Hx5bJWld<De1957!4GP?j`<2?046TEf}@2MZ0;G+Bo2Y=gtEGu*1r+!p}f)9G?
zhtmfv$9{N$!VZK_f-?s^{6IXf3%-`8i4DJ^IcUd#fEMq7e2G}R1L8S=7VAJ4?|}KB
zDF&7j@ZudXA9Nc$bny<DuYg#*1LkW$7Vm)Buv1eE4}iF+$AW+gHk2d@sYap0v`9x%
zfR^ugG`|r5Z8ZQ-(EGNY^y~#K<GF-qY>vMTbWvIwzlN$~J!t*JZBVCB;|yq+E)6tv
z8j;3-=mZmp83S59sPQt5KmTGHzs8v~{*X6m{D)36rSTVil27B0Ihw|=@iC1*|799~
z$d@$!qObD&$F6py@jp9}#vgMpjX(cT8vnD~Y5X~-)A-Sr0`<ZN{UAq+fTlY>!B)(G
zmP>&+pnK_AN;ttxflfybXfp#m)Ccu8sKX4pxe;>U$WQQMAM6K?@V7vgg#Cgq3B!Ky
z2!9*s*pf7U4PB)=E(Y+RP#V9+S@6mr&?V^(;NSrzvKR+}G=2?GhZYn(XVdsYo}vWL
z5oqu{Oydvvn#N!BMILe(7xv(Rok#(?UcC=K!~{9i1hk$A6bj%aQlQa85C?bY7#{cp
zT32)cWnB>>@aU4Zp4N<}Ehf;pBc9E_m|%BEBGT5e>fxETKm*dCAvA|i`~timtFSMC
z^8SQ<0hBTL)D;&Mj!&Q!P@vA@!J;dl5X+yy+EAB2orSI%0uPWPRwsdMFRp^EPO<=L
zL|Oi%2I|nTfI2h>iynb&fU7`W`*aI(J1n?pMPB;^GF=pIx+7dKZ0(aiWczanibrnZ
zwB{nz4@jfmkP?4@I!?1HKuumy69ui^GTL!M+H(M^w*y8yPQINuy5AvXpi~5^CoxhH
zNN}{{!~j|VKeSU3N=st2<J9~EbV;&K0Bt)??4up0=(xiqbev$-C}Q0SsN)2x)eWE>
zrjk0GtG6Jh?1OqkEa0s(AeIlPUj!XH<j+Cf<8T#Q#|E}I3f!@Qu80D4Y(Pv<#|C2w
z31|x+u9FiX8;L<%LdxoWaGjoL5AL{t3R)KA(-YJ95za>La9qRI;efds+~EK@l>@vd
z15{)=KwNEj05nj-gWAym-S>{ODKi=e0s|HY&;bOb<rHY^yg<E5)N^~#)_LJjfE3%{
z15-e|jXuHF5%Jf7HaLK9Jb#R_-3Zjx#+mi(!E1;>84fM$MIA`vk2=XOhMM!Pq2)Z#
zI-=Vit(QP9k@(CnC<$Ii^aPp*qY^-?x)NDR_|y2`gVlg`eF+9~VC2PZcn1|`fn=LO
zJB>i2Dme3_9j^Qc_X~1%ypEO~L0);{3-O9V8h;&hNfb0=MrClM@z-TSymA}lT~PT{
z7s&y-(h24}kppS`bs~rZk<fA}(%D)_>Ejh>T?70Kb`eOY=@Y*o;<%hQC<_6xo%;mp
z5rWzYNK2INg4Y3o)@~5FL<yn+x<rY<@k3~8Nm!z!0y+!<o_3K|^B^r#x&sOk7tjKj
z13tY0|4WoWdOVw7F@l1f0d)3|FXM^M10L{QJ*D?B68&DRgL5*Fg>w<02m^0Q1Sfm}
z*sz?BfIu2QBC%+k;1@l_FLKI>U(iKRz=>aw2ecJY!Nc-K`El5BraqdtU?-a1Eb&g`
ze-Bz!2XdzZ!f%S;Ycjx#>p(IY9EjCQnH(izptBf2;-Jl<f{_Bp9YsL9i$G}y+~EeT
z4h83UkQx?H3L|htk|HPxfny)(kR#+%weEw`6H<912R&XDNjXyb1h2b6T8^ZGVZ3Ma
z0S-{QK^%t!jzJ_nil9TWK{ps2cjN$h4yFUX`UvKvo9|%vj>|hj5*a83TM~N&5=0Ah
z^%1TkkU&Ex8ql3$B^o#1K^7r7-qyJP66e~ZyEo9%BpLcVdPNvZ)Na0W1Z^p2K(g<k
zNAp2O&*lRH9ghD!EH9QmLAH%VUCnPKK>l-p`Oo}jjS3(Cb{7@ChBG{Apq+1yw>3a{
z$(QlO%^Ve;`!On9H*+9LxDbc)+yW1mfQl8EX<&DlVlxfqdQ9U$-Z@ozhiYbB#9|h>
zgdpV0+c7E}AYXR7sBokqiVb96hNw6g9`I<r<kQO|RAL12XNU@4!#SQb&<;Dt+d2n8
z9)z0|0x}74UGjY-Pg2n+7ZrF+Vhwxbn6yy=dC{YrMFrtQY+)bpzr+IKKh#v=(fo?h
zqxm2UC?$ftdLPL^$3GsRGn;NA`4ZwZ4^RP3J>$T!Ijnt(QcdT9;=zS~dyER-P1f%z
zTnvcO)ilS((+oUmE}bzdJg=odH6}PtEJ1OMs4Gjf9B*sfepz(?#zT-2Sf&Q6@-Y;I
z9U6D*?v2+>cW)rYUI-{*T>@WA69;vK56BTkDO?O5@Exvcj*Tb5j_^_8c`bu*0LU(n
z=7SudqylPnmPkOHareeUBt?dTudfkh>EC1;S_(<0;Dkk}m>9B!Axfe$hQ?=z3SXLI
z<0)|bg{bg2-i94W363I3P(p&GkH_$o0qU_k7#{F#J?Y&m!dapRHOmKV7CbG$O2hjy
zj9_D$4={nYX}qAmF(E4OHZ4*9x{bqMusKX{iZ=xLihnyw@eU3g<l^sk<R6INe*7<e
z0QVTR%ppC-hOf`=gNrN7v`BPVgUcass;>M&Nt_Wh2dONPMQTUIsPJ^VsPG`FT||CD
z@dK!ogchBUS~l_zsPrsF<Qqh5E8u^L0yxVeRmw1XptUh_szh>`Ji=vnV^lamMsgta
zl^$YG%Sdhm2gBXSANbs+gm4=~Il?B#AK<paJ+M8XbdFf62pTKn0EK`r;|YF2PFR$`
z05z_Wx(i5d0bRK$aJv$6$||}#Mc-}?U+_g)FF-99uv(u^&ksJGfe^=ojspfCtbkOE
z$ben`f)Uz3167%zgC4-1eFAnfa<dm)Z-62K*3yE-0dn^fIU<lMR!~HMJPWl6Qdu74
zxCsqe<cNSoAGk5440azl*1;ir6Ujzs(B6eR6BNAg0uq!YLG~f_<L<(}hMXiJwt>B-
z4oxh`dJs_w8dU<HfPvibL-HXgV32KudQsqRBqYL+0|sI#*o&Y>3%Iq3=ne{iI*>@o
z)$s#35nTiO6y!?{<gOvSD!WZ|*ASuw+BFowu`va-)X_!70yN$LI$)5&qxFDCZ^Zu+
zL(ql+7SIA-*JGePDvq6p9r<S+a_PLl?|RIm`86Zx)H%)@;Qo_G^Y8zq=cD5e!;=wc
z;}fKl3GJ1Y>b!RFIQT*V)E$EzM1p+SX$QzW=;0$JV&JV$p534WQLC6rj_&{+>G>Mc
zmIE)yuK+Dg;@7NE5pdzxbWu@o;n(z0F>vA63{i1#;n$2&32@=pOi@Yj=x$Nj02)aH
zc`D#Pe~T9jc-j5|pI#Y8AIp=D{F4v)THbKvpM21j;}m~OBnxQS{ttfsHh&h-vVD&a
zo(EsDfR<ap=Ocgd@wYiZmZ#qaEhPi3a>~~|7YSarZ@MiKW!b(fzd+Ok(6$#>eu1O~
zj{F*r9r*>iKv(iP@*jJ07qo=8fnVbw|Dne${KpR6b>$a;T(!rqaRsCpbhs)=VTUWf
zK+pluVUmvg0#z44%G3B?A9UpxaC+baT9Eeo5p+|_Q<QBm{P`C^hi!pQ-*e>GIO)iL
z?9|;f{=`H48W%zQH2&MiKu5BI#5+Kyr}4i&#jkPQk^k6_4oCiD7w)F<-#*K)@rYmJ
zI>=6t+BE*x(3QrwuR`wm!@An|9OCZ3xBveC_hGyVImilf_ummF1_n@q1IH^kaq-VO
z=-PSOh2QlCIN5<y8o%oW*UpQsoHspMFM$tm?PX$M07-+l%^)cU9nE^k1);q87j!dC
z3{(U76jme+puIJy8lXD@w4oZn2e2Y(0ByKI)d1Zh@C$kbEconIBn_ZlIH($+dj?KI
zHGq#^MbZG;nuDqVx`|*0R0H_*RU{3d{W_=`pt}k{yBa{DWCLDOj|f!ICLUA`&}{~0
zP#av(G=O&YplX2bJ79%s@PS1W$U4|wpMx%(7eH5VbvSbJw}8$_14)KJV;Uuv17O;r
zvE2L%d^9b8%TnkuxG`uB0&NXKbr58uLIuc*6g0)4{X(dUAv+hmL5g$G6oWPqp(=)K
zWsn0YE&(Za;dea&;uP@DI>hgC$c6Jnha>pFTYe32DWm}|g*3pWkOsIE(g2r28lY0B
z`A9`{++k3Pho6Y+04iD?`CSizlYi$y{#l1QFM#;ap(PHm4gWnYPnTYNJsni8Lc1vt
z6F}uF=nN*c*KQsMUnziwYmiFSLyr8empZ^BHH<!%CrXq+<tYp3p11@2dIzhRN=}1!
zU?EhLVr#j8YB|u+3ZMncsOO7<D<{~fC3sB{c6Fe-1#$wVPp{X1{uUKR1_sYwmJ1%1
z2R(XO1VN>*r{w|u$p;)c4)M1@7V!S!hs;BJ^g6xwIQW7Ey!ff}u;;<YES}9j`T5&G
zyJA2EFX$Lj_Ylxx5J!Fi)C&$@HNdtUf=XEM#ix$^0+4%8L5EL(4yguh`~#gliR*k)
z(5m^wgCK3-%TGZDf$u)`u)G0UZV5SvF8?9)>`KDBF51H&yDoe+Z$j@tEs+3KEZ|ML
zIwA*<BI6x+9vT#+m^%|dsXznVSuFwW`9)|1UES~wZIm0lbOK}!C<@WmoTJ1cK80c6
z3r;M2L2H0P2SRp%BQfy1$H7<3pexTnXP)}>LKmkOf?~$-Hb#sb0-X!%v;h=~;0q@~
z;R;%d4!Um=79)@#O*{yyuAtQzWG4)4J^D)2_2~R9poQK@XGQY2yaUzsuoGXw>(cpK
zZb8H#N4|pBrt`NPgNQ-Se3byLPv>vh1Q7%67=|vj;BT1+5rdri3SOtq-_ivUgB)IE
zkk%Q<Q&I&A1JFT=0TyYUfqW%d@Pl6+(mDeLN<e2=f{$zs@JQ<n6apR8_yc^{Vn9Gz
zXP^jZt@jVmkq|lo5ow))VxWT>fAE0KOGxVslqdn6VF@|?H6yJvP^tv1*P$S-(@_T0
z=mPDWMhxT%gES&me*0LSfE=rVH2VR`ve0>3)P>(D$pVi$aH4>$a{wiZE8w}Oz~3GR
zUok-w1+!1D$W+kGM_ClVhUnh_=(=6d#1rJ4Q1GH~(C%J-jZ>hd;rtpm)A)-%LQZ--
z3`rFz%e!xtAA+A03R&Kr0E&H2ejR~MLGbaq;4>ZrI64DaN<hc!GJ#GQ2@vQE<R}3h
zugeVPN`PVvbi6JLn5zJaAkgu;tYEGNC_W(PLmG5CN}x<h34v6I9O#5hcVf$Mcmj-8
z0lUP1m<BAU6R!a}Z}5^I_T|2=pu+*NoOcL5lbeBGk9DRW7emo4(8++F&96ZH3$O;%
zg}#>|YjHuAfe%+q#bFuIhbyXpEG7SN#izco)y23DS3JP4$GYE_i=pT~$Y&rgftMg7
zFE9ojrvM%U@Bz*6AO_e$q1ghr0Q=#J2awwmtYILFsCBp^mMj2ULxp1xCykm70zRY7
z255T&TPcRGHGmR__!N#d8=!~954UCmEX$%SxkE`7kXjI{I<#iP7JSVHEAToka4P}P
zXaKbrKurVC8C=i{rEitr#?~wVZDocx3mo}%kedY{E>g1q#6@ZrfVfD_0uUG4EC8)m
z#L_Hq<kumhS%5V_MgxxM_7u_r9q<A}Tn$=ub?_xckn`kFE)YaphzM!mA)kW;R)A!a
zB&aJ5UTK7Of!uSnz8BKUH>4Ie@<CIec{%=;7vRmRJQIB_Px$uofG#sX1R0owj7Xja
z_cnfsKrU$V=?(hrdGHmJXY(OO(7E?sy)uv{wmIU6IuFp6LQo6a1AM7DD5HQ6tMj$I
zTy)<<^M;4zEstIv$OgbXh;Ld!w;D2*B!GCJ+v$HWLXN5P2MY**Pu%AhbmS<p0}Fs!
z%gi7ZJSE_^7U-J#A1ojNffC43cN*YB_xS}KMW9FB8GvLZKnn*!CZOG-_y(nwEdbi(
zgw)3VfEKXeg<;^a3FuN#<aJ(;(G-(-{v4<)^BHTI1Py0@@De&_et{4H@De&u=_J5^
z>`({4&<Xyi3;a=_wWA_}kmYlp&4&~`EN_)x@ah!-Uj*)>c>^@W&3M7r@+PDs30XY{
zI%*$!CS64u|NFNdkS=Ug2IvU7OpcOd&~Ohp799DbJOn=R3wjEa_<<JDff51eaIFZ5
zPyB+B5+#;k10gpcL?wWZxl2?4uTKS;3F^j1WoUfj7tGWEuTKS^02g5Z(rSPb2jKf5
zLFTd?fF7BJIJq11en`jxSm0G_u<5PWkY+Wgbc4^;$T=bu61hMVq5(8d0$M(YJSPTT
z^o2AnqX{(}u9lPqnxHfZo}&XX99SSZn-i2|SzsOlFYiNIpsDEC?ZD#NEdlLWcpQA7
z;KO+XY0eS0ybn4|#@_<EF~GAoK*7WEqDOC_0%*>`)A9oU<U@`e7fZrDn}4yE1!B2d
z9(-~fs7no7$m?Tys^}GLEhcOs=B*MNklQ&xgabG$f(XvTAU=}MKnqwt^9y?Z00k$=
ze~`)8o6uYX8dthhBJ0>4a)8CPo9BSX!AA-{oTm`w;UUl!cA!Xw&u@Yb9y|cbji4k7
zN-++g0hA~X$jNYypacw`^SlDJ1{x$KCZG{fWWAu9tD-zW;SV|>?l6cr<<lwY(;3JC
zi-$9adDD^tk6x#L9v5GLh6q8+uYG!X7)tD24KKMG-Ub~JDF7-7;U_DCj))8d9T6EQ
z;Msggz{e7FL}cd)|6Z089tR(=fI`ypVhK3qgK`$aFQBXi_J}0HZcy1>0-iJjxgV71
zK>i1Zsw01t!w-;dk3S#}90X;cQ=lnY57-p#3AAvKalGlk0y4+(Cg_Mv@B|;szfaKY
zRDh|4PU~?v-gNi@nc4$S=RN=*`__$ZM$Z^@;*|pjWJ(XjW*|7HcNR3f1nx<Os5pRp
z2$|D^MqsJVYiFNMl<laXA$?bV*UKQ^xO502t=f_Vub~A^U4u@ot70lS3K_|MeFZ$<
z85Zo(_y$xL@@tl;IDn@1KvQ@wDhc4Jy#g10%_%Ak3=9k|{F-xAKuh9X_%)ZPfNsTe
z;n!RPp5$}k*W984x+ctpUvrPj1yIG=-J+rZIu-&p{db0yfx)x$pii#|qvyegEWV5f
zA$9FxUrSKUd(f5RG=IxqR@fxqXI9W8V892@gRfXXRjzO6WzaaZM>A*=umCcN^#pYH
zCwLOj)Y1+-38=f#7BLCfc#r`!S?J0y(D~ut|No%5K+q0Y#|3Gw`~o`}{{R0En!prD
zbL7`JnC8kaaz4$GU-URgvQgmw|Nm(&{D;o4fVdkKKwSPqN5JRi?KA-K9Qj{^G-;dw
z={yEfwGwo;Pns*g=sA#1h}xL}AhrCrkAZ|BhAm702|4l$Oa#qErn&OJK9T0auW>xh
zkzeF5Nc&NcVUZ1KF8sI8rSTv71Gdz20?33TERLW?I7mU@hBO!c*T>WNHGYG1-r?8e
zQ31LCPa6NBJ1ij0$G~&43J@dsU;j?y&%Xh(DMdvfjsNyPP*8XtaN$38yaPOgo94)$
zcp%M@KNGAdM@1oxKmSJ>f8t?~o)Q&<H2%!rY5W?uK(<{5YrX)o?{*shp(`N!G-OoL
z_!Eyqtak)C%avas@PUsdNU`XjH2&8hhQ@91Y^fu^$Q`J|ZeN3F;eUM}6cc~b_;23>
z8T^m`*yRq8$X$p+M}Coe2$lRAKS2&T1ycDd4IEJ*ec<5Ye|<iUKOf}ZTWS2a&+#Ao
z*^$Pdcs-3j^L`qCK4`k&avFc)X~+~R@`-|n|Nj5)+j$c*V+u*6Cwwe#@V5vsBTbq@
zvM*xR6vTG`&5I(>VnL@(LFYMw<w4V)uxVDX0OqtNbmDXgC~bqLyFk;DC|WQlHlb6e
zple3KhJxl9QM6#rR6-|D?O?Wm=MJHBn_x3Aryilxr`#|tpt(R4TQFx6p%bV#K=}{k
z7tkahiWbZ%Lg*CgQka$s(9|EY!wNtJ9LiKPbP}})s-*#R>KdA^22jC;p%FTnY6;T_
zY9GK9fdZicRLX%&a^!bGnN$TGD+gAvf`NenePR_X0V)<@Mxjrxo`fC-*{}mV%L<>7
z1#1MYmB7#lo@C{30XYY(=mZvxpkfz8BV@ug8m#FC7EPcc8bcFg;#Cc-2~;0|LI5=R
z3Kjs}=!ZH13#u$MYC!8fG{BXGhL1{t3%>@eve1B478<b1LIYM=Xuv894QOT2cm!l0
zY@!ytV*z9-xW;tkcLkl@rpM5E2(n=UzJY=BLWkpjPs>xKmtW@n|NkE}QwttU2G^Eg
zL%=I)L>NmoUi)}-qMSm3W)yfY#HkYSArcIp-45WBDyo=DPJ$yDIx!5{F>$ICvXCF8
zEe0NU0qvXwP4^L+vBj<qG-K<cVgX&W!{4$PG}+gA5VR8lQWn7~Odrcbj{MUg6=ox-
zif#TO%->cHK19#sJ=&@n&t}l9t}V!{UdSPOeP*B$*fi9MTaU&=;L4I;pb1o0rtu3*
zf>e4U2h;cky1?}zzsM=XMn{23;OdTFU=g@J;}^(!kOn&GieI1$Tt9*p3rvF4e<D{P
z2RDIE%M$>dnThWNEP<c~$jTYWYMnHQNkO0^Xb-3HqZ)Mpd>kLYK+pz=j6l)_Ps^KW
z{31^wM{j{oXoD`ANd%Srk02)>C4$bEy#lQPPQw?>v_AtanCZOb!+6tI^OncKM=YL<
z7kn&llt_8?h6sW-gy}GV(gG;iH6IWF?VfoZ9d{VCeHK;xRO##2&p>GrwDSiPgC(L^
z6`{38!GpT6)Io647>7d8=x>OM1+<~a-|_++_d!@EjrrR^Q?Jlwlq0_YC(4bYFTv*r
zH-g(Kj{E|F3)1*SKv_}1a{?q*pgWI2a-gPzKqMp$IPwd4f+7S|I|~GY=9<&^MJ^+f
z0KV9VoPWmO4$9Czows~6Z+P|cL_(v&*YXyB3+V7;k5=#@TLNjFg8VI@LK)O;2Ze9|
zXqK6YzXdds0P3}a#Xy_)S@>H(=k0<z?O-v`>@gdE3uKH3y2&3jW6Z(dvK`cXZT`Uu
zRtK6T=HhQz3=v}ki-Bf_dH7pEJ6%Du&tS0v@a%IvX!aSzp8%?Nz!T6ppsPp0Lf}#y
zGzT3Cx_%Ta1gb5-)6j09D@egYpn3p26KxE-h7>FWD&fJC(Fz{TKX}1Hpz<3$9}VU<
zfC^_EQ_>*iA_vks!Anw@a85~oB63O^yE^d7K=5(bphXe^zOV%grr@-PJ~s^+(BW?b
z1vF^U0_fnf4kK`>gk|*tsIBR=0YnBpfF(dLXrelm#;<WDjsMUErZj$yS84qDw;%%G
zQ_U`dPBr@sJJsw{8h`#Pq*KlAcBJvgoJ-@^xClAj3{*DdABL1C@4<)g@wexK){Vdt
z;Y@fUyjcR8{08luhEINjH~|9i$!{=M0Y3Q+<{H2!zrkDw_~bX38vvgC1~DBHIvpjT
zM|(+tI)R`y2C&oF!CP}csz57PSvmv%K-R$i_+R=Att^4mNCO<Jn+!%{6?)no*|7?)
zMnLCNmFi=kjCTT^R)u9UUJKmq2X*<2?t)IL@`TL9gH@x>#9xC98G>vApYp|x!zQYq
z@&&R{1LU`vdRz>iJ3&iU7#J8p7b}8RZkNiuHiNkqynwqIwg>Fj{}LI5?{0&92UF-{
z$ocvbnt!Zum~Ic#gkicWmUGK4p<8njJbW@#+ktI5;Ji874jgR<GK{tZA?-WJVNWBv
z9Z2L<Ijr-6G{Fi!0v^=<Lo8UmiElzL9@O?TybWsEp{^l@9Hxw?%?Isw@aKTrY2|z2
z9R-Xw8uCg6P)iuOjRsm=fYe3<ago|+ATClH4a9}E(LgH^K(#scwi(Dq(8f-}ZL`sk
z1}_B#M+<F38rlj*U!8!owg9EIjH(W_rxJcUk~C;`1=jxN08J~w8{kjTri<_^MQJs_
z=hZ=nu7KvDKsRZ@rlHX1)iD&Op`OPC>i_$I`u`_AdqI=xY<T)$Wl3b`LBzo|f-HvR
z`><s}lzDcL*Aza3?tX*Mvx9^(1U~Z%X0m|i*)KtR>`?(Ag@GK1d3KP>2+%@?NFKyI
zJ4i6W;WNKrq5xu^9VD0$05VeqGS3bYh)DPhnxaR~u<#WMp!^DoN03^F4{7{$pe?UI
z{+FUnB$q%Y(m+W7GRF$qun3;|!?OYfDKWv$UV?SzAWc}1aiGazumku7L7Ogr{4YhH
ze3XQpX#;Bm!)7$mtrkT-$p)5&u&)V#oL>W4JV4}{0Eh<Alq<-w_}2uWsU=}e0Lr{J
zI7&D`B<OH2N6-ZIXQaKnS3VyO26Z9~z$3j8|4VE@gTJ6XlAsB0kT%c_HFYOIEQT~k
z{<_1yj3+!h4|yJZq~Owd!-w+%WZeLG8|9Jc!?4U=Qi5%Q+Zi&!4L-&x05ro5V)=lE
zRpGe-wB`qNZWDNt`<hSZ39nwBlb}g%PsRhDNR!;)^T`~*9s}h7N6?x9K~M>Tw9o-O
z?F;I)fszNvKcG+t`NZQ#8b8EO4j(|CI_S}P2()0prSpUb$VZMpz}sjKd_Ig)%z)2Q
z0xwAb^_?7`3k5hq2PwfP`R}0Vk@M}A0L>hOQmHTF3A7~v=%+QQgA4}S07@hvjstjC
zF=*M$2ar9GjnX$k9!1)L4cb}liDhRssC)(IFZ7Hk<9HXeSn36%<6Tg3NnqL@suntJ
zFW`9B;RDubdw3eU`3}4v*YS3S!2Oqww>2R1_Kuy0@4p03n&8}sd-m=Pa3KSWL>a~s
z>znT&v+c;Hfp(iYb{+&B0foBvOu+@TyY0V^<;~Lb;B%S4i)|pAnZY}#>367z0{Dmn
zlmnY^ov=id%iw1j;XV}!;!lrW5yuj&r}B6-A7t`uJ^*$Zs&S70JS?%D{RDOyR<l6)
z3bY#^bSf3n(L<mj9h`Z{Jj)2|Hlofl8iY;*l@{<dV<@Kuos<~_rv<slka%zpXuSMC
zk*5Vg(jGWc22~zIi4&p@rMXY=P#TuN5*_S^(jfBJ{m6gd!%Zwtls*NIbAhH;Np}oY
z&XECUD(olZ3<noc<wP2A7~RKuA`MCyiGmOOcmdjzbrXJE$7^^DgBn1f+gHG=?2t}I
z0i7VDa1-MM8C*sqP68opG^mB3fO-H7$XNI~M<f^DwnT2xB2SDUITds;ivn8X6l5U0
zWRn3^#h?a_<82L46(D&t6290J`Ain1HLeOUEuf|ts0wnto$=si<PTVgAdVivXVYED
zyOHpg77;dqeFC!SZsZ4806}a5*#ZwBIcSuE+<5aOs67ulrvw&K=xsDbsA_0)2;{R5
zH%}rpi0*$r>=+Un4xZCf@aT?FDe&m7QK|6kJmuMW#i#R_Pv=>W*4uTm9-W_jIxl*5
z{&?X%i-W<l^N<JQJ72~}pvHG8==>Lj=(zY;$C$%Doriq7T~rKw_}9CrXuOo0#lheh
z3b#SSqk9f`d7(%578TG69*8}@okt<|c=Xo&uXFL~d<C}a!;AYfA$Ik$Som~a^0B;7
zCe6Q%%Y}a%g9mtJ{tHHz4yXSe9*iEAhl-y1GCuNTd<%Bc9*^cD8W1Nr#vXPIcML;y
z#TpgRG9Zv^Kohl|omYK3kNI|<@#uW#aqykJ2je@Bi~l@&ZOnXnZ45m$zk4*lX9NX9
zo^R(*&(0S<ou524Kl*f@d|?N6;6cw`_y3-j2aBa0`L_x3Z{q-MI0vV>4$uD`0gRrO
z2aBG1^|ILebpG<RJYJ076VH4Z--A6d3E2~lagOn*Eqv;y1W>6D>R>?*hK%@MVgO2I
zp3ScrA(;nshz=+*a)1~hg&d#`Z>J+DnR|lHrn!Jrw7}|EkN+hm5My4#PErCT!v_#E
zLR1ijd2|MT@aP2fXMX-KJp(o>7<4}t$R?1Jz~|*yfXo5~55!5JBaB?SV^nxR4A4ng
zo}GtWI&Xlwe5n1s6CTY+1fmfq=RlX<l-PjG1GNuPGJA{)k4v`?!c-5CsV6|)F62Jf
z5wIIUAp*~y5=5Ru1?mOCx>}&_6R4O0EnY@HUkc`Ta9ag*>J!MRzKkazq35E4>-a55
z=z}KKO3=>JQb5uQ8h`lpA9^YUYU~I6F999;1hozpy4cSlL$VBVY!mp1DM&2>J7Nkn
z%JK{OxI0j=!Aoi4+B(!Y%#GNplPDLBHh5I{T)?Ltl71W{qVYje3-usU3l$}E40uBx
z`3PZ@#EsIq%HbabovY`3^yyrUcE%4vN<p-N2WVl4eDocp3<VeSgi<o<Xb5}|1F}*T
zxfG}R;0hs^QSX#nNHL8uAO*`~p!@}|bM0UUt-n?TRpyX!JM6n-1i@#cS22}bgN)O?
zz5^b3>xPWsffsLj!;VpZEekOXb@i|UboDT(R=xkSimBw*4$!H2pp~MaIvgTf`Ur9=
zGTQhml}9pB0)fh#o4{t%<6J}xiy(6eu#U~`OaWNm<|!;pK{bcQ&3CYw6(#5-2(*ub
z>ui1uiy)gGNwNr{1!@rsq#JcR6LKIWYLp`f-F@%@z$94&(E_!IXdm5X0ChS@vIwFD
zY7x;sg6N`yMfXYYk!LSUK#8p5eFo3w156+v!Q;o%@<8cxc<O<TvV&3(<Q5REG)Mk@
z4A7=7=q3Zc`z|Vc;E4uE`U4LVW1e*GqT&EH#Isj~p+o~}$N^9<M*(3<<%8RmA8u!U
z@U*;8dI#bNM7IH+OiE?$-gvEj+Y%Oml>!i(K{FyHf}YJ54376TD(~N5<zeSyczqpG
zYK5pEvO%fb-5alUAqIdv585LMu^82eyEj-*vT-rIz6v%1Gb}V5yI~;#-bHagM}-4D
zB#^xUuW!I10q$^UJ9aZb7uhLzHXmR?m;(z75AccqNP&TB3b+>3aOB?(a|!4))7vg8
zJj6T1vsc8SL=9pDBsIXzfH?vbA@}gRLDP|c8_W%e7zGWuKw<}+E^gyA1Dr0@A!gu9
z7I%?M02fox_53A9H{acSar5A7rkkf68!Q-Z9=Lr9mOw0Tp1O^kNI+@p?hSCHLTj@U
z<D2h%7!RNu;Moju%I(SrAR|CY)5r2a={=BUkakD@eFC5%9F3Qe9UKfW=hP{HHp+PL
zpYZ5p^y~)B!-3h*uKz2>(g%pTu1*w51*CcMim~)HNP&-vhHvZ1Iwg={pb1W}A&j2g
z4j;fQsBteDLD%kpRu_R)i+O^Q<N*$_5{P*(8B4(v>@F%AzTF-izTKenbUpb`dh(yB
z6Y%Ne^nnaYfC8)Z184#gtPrB;L>-S0xE~9a{Q{DOOix0b<<Wdl0Bn=v2PAKRddjcB
z&H~py9<7(^#6inOn-79!Rw3$tfD(P_OC$qTK>h?72=^<<P?%>S>cNw+u(LDjL_nu9
zc<{sbf`iuZzX6#D_J9WmXk|d_0Z;yu9{i{31bsR=JwThbK~8Rd!C3kpsuH3Kq=eU_
zQxG(=0ru->P!vEG!hqtF0qks0=p+098OnjhCp5YgArSxx7LfWMV4aBA0v(18N_F5v
zvmH1*z%IlY7l_aXZKQ#i3Jw>9Gax~859A%FYGp`hgGNb_bU+;fQGOSs92`y@;0b21
zD?ovOEu7#9Ti6ktocT|H(*&pzfSlt8^}7hTJUqYxmw(Av3X2d|aI$mcKT*fy0@e)<
zW#kkk3N8u{f>tu{pXdZN`;l@2=oo;LbwZBaA`SefpeJ#F;`<$FokQ~*0dV)$v0K2S
z^#K2=x*VTghd-X66FOgj=0!p0lCb#oih!@3sxtzeCgy5*GL1jaM};Sizu+K)Pv>dy
zFyz6<EWVZ}_yt)c%in;{@44*N%QLY=7PO0|Q?Nu7v<?Tfmw^YgU8XaTqlCFLkOwkY
z1|PRI0F9J_cDZ<To<|-RE>XCx=fU{yW{ips_*hh(7ron97}7e~eHfpE#^}Je8yG;w
zVG-lZ#G7W1+ce0KwE<+vy7RnG=P{4g+a=1k^*ox7GkG*0Q$TXmkF6j_x&H$@33S3a
z$VrDuF<~246UYdkT(Ch{!-tT21dx2B1~!INA0eCYWDB-1f%^zL7l0Ps;N@taJ@~cQ
zJQ&}-SO_)(?ib`~0Fum!#BC0AW<tZGyF{hH@U}<iS)b119<AR>;4Wdg|3VV1-zAm-
zbbOVE<-JmnOTeT5hl$dEb2BI?u<9q^5AZ1#pP|7q32Y2JI6zZAuvrmOjPb^83{Ky`
z+`%&c1rJy|l4n5fAP^Wx+Rtu63k!sHQasTHHiqJ`u*Yo-F=4>~)=qX<9Nb85SjhA5
zX9KO_@?d=TnP2O`i*m3@@ZbPl&p>3-KsQMjw@EldM4o>?OFYOqV7I*9faWWZYX~F|
zR1;R>Hi1AIk>}rs5-#yzlgJAfRFgz;n}jD^_OZyr!{zdNa>51Kgo(IKz#lH9@~<7h
z?(hI57O(Xz3?7W{5VdHDvPU<YN9%#g+a8^VK<Yd$zG{BJ=)rjiR1_cj%pY;!HE4Sh
zaY+i*vb*ajv<z41mdYXfscao;;FhR(bhF$i!cX`UCaNWZlv#p5j!NXa;Yk-9O^erp
zyhK*oMKdW9w@J7{w?w|1Wj-h=fKtGL7vf+OkP13t@-&JGSJ!}igVh8Q!=)Q+64r1b
z(l?%96UcH4|8{sJfwI#7)gWJCbqgV1p_#N5w@J8t#lIb?+${#1fYnz-nqY|A1cJWV
zh7vB%SCJnss3y(DZ4w?|Z9^(|qroPS8ZO8tNa8kuK)8r|bn}5)vd>qdgvU#d<|D)v
zrX?^Fmf|)6(yj+Ls1rQkJryaC)sU`=z>9RSZfJA<8Ps-Y2L-Q2J**mu^!3LTIDL&X
z?!-O1dG5d14%P{ev(KfV5W`<ogF=eu{)<}NItjR13=&mmmZ3QM6*RCwYmbOCpc}UV
zIDIV!@^lbbBa){<b`$V4SfeCvjl?<m#!{Sq#^>buFXn?alI-O9FVb*pgge;)w1^8b
zC~z7)C~zFSi0fO4D*twV561T|9<E?v_{=ZpqM~!tMMdYf_04y;s|9=*AA2;vV=TSx
z(R>8d4M&MMf=2ccYa}Go8G!qZ9-XJ5y+#d?%bE`>fW`=3IH8(V{Q%^?4`9dLfI1GE
z1@Rj5dpU|Pu^IypGY8N>3TVk0`ap^?|8{Umv=-I08WjW3D3AeY(9y!9lii~;oC7wt
za@M2yhy(FsD^Lr3P%W^BnFd;F2#b$!@Nz(~TOsia8(uL38Pa@Qz@zyX(+eh4lhB;%
z{=uU&{0Df%<rLJRh|mNrGlZ9f%E*SUU4{~x^&h|{z{hOh0SPV@3(!MR24ocDyBFyo
zQ#|-}4tOAjqCg#4A`5kxF$x5X!I}AF__y=Kzj(Nmg#mPLzyXg=7tpNcVMfs41jro(
zN)3qiMFg}H2n#7_SVV)2;nz8U2nkpPgOc^I2Pn)CF}#N03<oK2INV$Uic_5foi20X
zLo^^a5C{c`<~evZ6B!2KFhk%?L6H4KrUqCT2;nt^Kp0$IOhFjTz^j=+7)V3YK`_)1
zM86Wel8VScfSJOJ-xQpoAPr6l=NCajA*~Z$C*1?Pf<RJ$=$?pQH-T_~MWZ*=lnzSL
z0vldKaE1aTNuOK@355<9S<>@E4_?iVh_%)hpc7sdJom!SS?Pq<(x7S^R0a8Tp8d=(
zV0!xnCxb`pw^Fg!4v@l%@x4bUGqjp6(c$0D|3YFR3+SGgjW0MEif(`Ak2&VS_#UFR
zli9~m8>+VS3cp5)ih@V;5erDI1X_7bx_i6{yQgCT*gcA5xCge@-2faqhPOTUAj0RI
zPv=pO?mgfI>Y$K0_#6~6|4T()+e3ZJat|`Ze7{7Of4fgC!;63O!7iEp92PQgg+7KV
zFvX>pVF3fHVBtxX7-v`!c1AhG83N=w1AE~Q%kz@+q4gM|3IXjBBC+JSJP)raIP(l7
z?@xv6Myf<Wt{|%92*<A*9v%3@K@e^VyyyVAfW&Y(J(rSj=!NShCmj6o>n1WBI6<cH
z>l~o0COJF@QVQZQg+O{}h3h7#CUM8Fn?N|gY7$1MDHPQtduBs|0lOhMLjh8g)WbBB
zQ<FI1)r=elB`O6Tu-XIK$CC&3q!{17sGZHi;BnlU15}D4s*O_6_#?J_fyX3c!X`ob
zB?_QUT>_$0rv!3J^I-vSr|#`6uzP+$+~W-C&Vg>-1i1#<0l{m)8oUM|hYF+<1Mc}k
zw@H<VL)%*EAVUzPC1`X6WIquNZkP$GxJ|&BCd9#Qtk*MH7*IMKAlnI)k`SF6aqA@D
zZ%L@X^JlOybRu`Up5qvv!IBPSLD9(g{)P4o7KY=_ET9O4H$%WPy08$$>3>Ox|EELT
zfYjvzxdIXb*i(=K$m-_99N-kRdOFDdKVbWve}IPrKz(D7?T94|*eeP#XfR}eoB*#Q
zK*K~J-9*Gb%m8(q2H^C(7})dgrm-*}ce6ltLwrs^<5rv+iHQ0a;{7ZPtq1t0fc?z)
z4%}x41v-)51|^>tm;3OWfztz!XrBVrj#LtYTtL9{5WNxj^!k8yp28O75q&6(xGVoQ
z0nl<F(Dm(zTlZdqmiBaqs2D&OFY~wfF@kPN_Ym;0Jn7TxDFC{w*Vpm{=++Wf&`s%v
zjG#*rK*u_(gU@{SLb@sal;^=mEFR52_{#LbS9pDP=Fex50JTs-2a|wr?ees|S^mP8
z@q!QIMIX%zK9-mGTR=DDID#D4dZ0s)zvUeG!0>GWp!GzI9f6GeEua>$BmcGlCeX^D
zjzA{<mQ_$S%%CMg9f8b{OIAQ?K-RN#1hVkAv_aLdg03X$2xKj(0Lim?H2+}h2xKeC
z0`b^EC+KzrvX{hwcpRYfb2~sM|A2U$prdm;0y#?@Ks+wcskt42TqQ;z9yjQ~+>Su*
z5)}{+v`~qsBao*=48-FF9h2J;$XmkU$iK~jufvfKbo-Gj|27^5mku6A@SP==hf3dp
z?%jbbee>*f`d=~{KSL;f5Le*6gj~A<x$GLWZJobm5;$MLF7^UvAjoASkc+*_;29_f
ztPpz!Dh6Fe<I@`{0J>r1{YmJ_*q+UY9Y8mUfcA8<7=UiGPUFuwoW`GUIgLO65#;{l
z#D|Xjg24wMl9>n7_!BQW@(U(!0Eu33<QH^);A45ZXdNgIf-@j!@f}Jg1f6P)k_kIO
z*$E{Rb_Q~wWx~!t9<)r@87P332|<SpBO)1ezcC^cb_U8IWx~!tg%UqdW&&rz&OjBU
zOxPKyfs_e519gxxVP~KLQYP#SG=XNqPDcyy)!L9;*vZp~$c1sJdzi&t`L`2QOlE<L
zNuB_3G06kI(j2*%^o7T=GoD!XPUFuPt-j9504^>;1tqx1i~x~75ulq=4yEzmJ_R}=
z9$tciV(%)v`1J2(34q1kcF@91L=n0jTwo#>q1yvM#Um3^5xPA9R3I`V6`|V$K*b<(
z5xPA9RQRz%i_q->pyCczgl-SuLn=bI2Y{}O<A4^S+XIA<iqP!=B1lE(_5d-YB6NEI
z=w>-s5xPA9eC;)~2;J@=1200i^EluuLM4#m4*C3gj7tM?t3x`@E8stW%Vh?<b>TM1
zxt(16ZEL`n`FZ^CJou6syvVir7n@hF%vn&Qt;_&&a2F_2S-@9Qf#MQ;OqVaHHuUM`
zk@nEM1v=k~@uY|4jgkb=E&-3$OKF{qB_WRd+Z~udmt3WFIx>~Gg19Um&A*t^IvrU`
z%s^Z=kLF*@X`PO2CF&q9hez`-mb6YsjuHtFm&>F17i(IlBUcG0h|81K>Btj(*rQj3
z!SH}9|8^dRG?z|rt;FPEd7<=eH1dgNBQ*$6T37>6B4l13EfHv4B8=vAJQW{G`vxtf
z9)pWIkw(y^d%l(z{Ch<>9Qh|7_OZMO>MFQ$T;^{%1SuCe_}f5t4f*t<mWzI{a?u%d
zS|a#fO-RuQs{fFiEuhOZ0|mg>_dzc1J6&|mNAs4C<qiK{mI$w2o|z?)(4w-F5!7CQ
zmXx59(E(K0feT7dNoWM(fy>EGM;=gnVLRvmzh5k!jsl?e!gdF6DcR{L0%|X8ci`!C
z1YcR|$iH2Lp;N@sqxk?6=)UatXl-^e*KRCrg;$tO!X=Q#!UP<Rg${UQp$>Orfxm4E
zxHbYc3-U$X&T}#tg0At*mxi_tLG40N`w-MNbl#B0pML^$e;SCF{2+}#^ECJdHvYte
zY5bWtL89Ild@MoNkR49r&%c?*55AP<P8xsy!!-Wehtl{nA49JxI|FNh@C&jS7WE>x
zJSOnBoC5W-z&k=f4G(Z5u^ZgVfV4YSgQdYu3P`hK7DNElhJds>Iw1m}h6AY4QBvdB
z4Q?rb+Z*|g-QcDHxVe$!*c~7PYi)!&b_akCSOYgUJRG|NRA6llYsc;Y&^5GNpx&CE
zV|RcKtfiso*d1U1y4M8MR}*pU4lsdr)z}@o9V|f2jJU&w2VA>(8jzbA@1rr=i127f
zZe~Eb(k`H`^a0SeL;jWz;0P0G0A&>)%Zq-!BAlSC0=aYW5IC!xhi8?e;CzK6s|3Ka
zNeHNob(j&HV*;SD42rH(kemaK--~JdiHG2g3{ZpdC_LZH0NrR)5((M{1ZiRTfi5(K
zH!vI=yTMrl(!MZq>~`RRH!oBiyB!4JtqU>7ZU+%~<ATGn+d%@-wlF;4*e&7!yYq!m
zzCjc<$X6u$^alOsZ|MOa;O!vbVR_J_*Adi{I_PP6fPeA<M~;IfB_7ScxXbc9dY%4w
z9DKn9YSDW(|6=m!l>zTSDl>uHj0_Ga4$yI_pa211hzz;`^o2(+%Un?F%v1B0C*uJR
z#)BS~w@TzdTd!I#buyNSfI`Ky`4=OoFaaeGj!s7oa7P}LI*@u0_{xM~=r{0D)u5(o
zC;a#}%y<J`EacJ4a?#WBfM+ku1kl)#hvh*?yz#fRfRp?$?y@?cUavo%2VXLQTFjuh
z^Xir91;t63BdBIDJm3l`;aC_z(FaN2SqIbjlP>ZLx;P5(3xZ2#0bk40MK?S(Z+TeW
z^6h1r;nB-;vqTXRksh6lC7^W50*XlwP)z_zryL%gjsl>#bnKRC@aU8|2ueF1mWN95
z#U*0Mj4tJS+R4%KeYAWZE#F7Wcly>{qvbnjA3x|eOynV5>bKw94v&`aqviW(`94~{
z)3<ydsPT$v`$o&V(eiGzyc;d==vm(R!UyV*Zbiq^f4>YFpS^%%e0Dp0e0D9y`0Q!V
zgO5S8s(k!yhrz>rpbL5OWtZ)Qm3OGO%e`s<jlDL3ZnXw6f)?-}JJ<nYc}?IycB%t3
z$N}OdJ%HRoo_P^D%YbBp4uE7pEUyh99UxZFg*5)#hkYzh^B=ncGU8zxKN0thH^qT2
z7-qcbqj|%}@|J%u%MHkIF668x*l;fR;G*Uqh~Zq%ZqNwi55#b;CuEEkF`VlO8JdL*
z=Xyd$V<E%2o{#}p$Z)P_cYp<aIM=f~zyY@W#>2Bazym&<>)9O;0Gm11^Xv|YfDh+-
zb_XQDhjTr<12W*lxt`q)1+d{<-)^1*_=j^5sRV5}7t{@KQLzBu%mbPW<pL)Ykpp<f
zb6<f6w|;Q(w}EcOMxXkCPYGv%Za#w!Z*lo_-UAJAK?d*-Ie=o+X#<E1dH_!y7kojn
z3rQfL1OQp<0UqOrj{ZXKE-zZ^0U8Or;oHk{!=slcvLq68Ocivb7jpR5FGlcGvV$jN
zG#5J3>)Gufff(ua>~>H<jP!bTJ7^$AdOf=x48SA3puuv_ZjlDmp<cAXaxp~cBHh-A
zIc5mH&%BpqB4o_)0?L?SNx4V!FV3<;oa2S&h_ONkP*8#b&&NRk6ngxEETA=4;8DVR
z@KHig*vu@E1D&S^8SVuI4QP-MJlqQk8R&2?IQ8Hg?j14S1D&kTcoB4VBdCWAJ_`?g
zURa4B_=LDl5%4f7c(@;NsvCG|8*&oBJB&*GVpx95XffOo$Wl@>S`1@bnKN1pgO>Y1
zR{uh#+(wJxL0-#{Uks0~Fh(ps9i%J3_rZr}5L3rkRv51X_d;;4Fa|9^_Gktz(FZLo
z@#)37!kE9Un}LBLjsN`<_$uQ|9-a5n`19|88ls@JIIz_upq0icHy|C6gwv1}$N9I?
z_)~AD@#nvUtSw1=4O(B~$S>#(T6uiRkzX)-LmGc7XbsBEH2%zkj{Jhrh}Fl_u&zGd
z2U@?1Sbe+?vIPKX_3=LNidH71)yMk+z*_*2Rv+&JuRdWxT7A4P0K5eNy83t@c*QFl
zboKGR0Pq$7=<4Hr;Dst2(ACHL0+3f9?*p%b<?4j2KHe7q-U0w!eY_96CYA@f`gmUe
zcnbh@_3=IjKE&$deLM^<NR7#N=qpR`tYAf3g*6garlKs%91SXbi+E9jO5BxyKlXwJ
zEm6G&FG0e)v=6l23)E@nZ#w{1jAOl$H)#6;e9aPz0H`=g<Ig`08sC5x3l~Af0(fyB
zWSt*uiQhT+QYH8jzx@mz;9i=aBmaKLVrWn|%>l$iUgEdk0eOkve(*Xb*b=|}C`<hI
zBQ5dUKUkOeB`=5dT}GGqm5eU&<Ifyj;&*@%v`lPtiC;NgmM`KRtD*jqh~h<~<=yBM
zA*7p;2p!bUzknF*9$nHrx}=$5bh&o7!{}1<|0T#<ZxCZ8nA1w5TL=c(_6Wp$8Tlib
z$P-HVB7f))W|JRAlAj&<1z?xeedZSgT~h^~ynBu|I|shF1avUSXGi`h&^=n8kQ6`0
zrT7z6F|x_%iot7%Ke_Vj2%w%hg1#SH5@b6}9r6@Bx>F$r`a%sv#5}rz#Hteq-C@Q*
zl@VmW2jfLw#uMNWf^6i1%!)vcbSMQ6xOxisTAuLj^#E-|I)r?rLj-(%2<Y$>90RUp
z;O&l}4gXQoq1$`Gdy~NDqonbd98BZC58ku|KPTk@Xp|IjP6}u@8O*`02l!h+3k)0^
zDi|5~r#gZUOW|(;?KgL9s9*vKflo`}Z`lRfU)NB<3=#s5mGZYNhX}ENgg{GISom8&
zTMHc<Dp)~6;L%e4mPUvwHjohLkN~!lBFBabb`TdlW?GW$*igX%;(`tg;3x@kY^dM_
zalxaeC9aMQ6<i=L=<oop5;Mn!3T_Y=JZ@T|?$}Vl1LA@<0`indI5t%9g1F$3(-Ka{
zh6+9q7kqSzV}lI?1OHU;G(IC}n-2QXDWcH(Ho@0F!Y=0o-|mKVzKTSeW3vSVW@Nv>
zH~?n_c$EjvlO4L@k=+PR6<9~t%hJ>M-(O1O&sXi83XSYE{(RX9Q#rv0Y=R>mamqvK
zp)~%|Q)&G7kEHS62ko~!oW_6qG{&h9N0Ikl2JpB12MyrEd<9Ao?;rw@_=hHmTTn4@
zY(vw;F{l_gZlQ@{6I2WwqtH|_4=M(ZM`*I>f{KA-50Wmb(j1#1@dZg3Ss=auDE=TR
zBMQV90`Vb9!wbY00r4Se!wSR~1Mwk=Lkq;00P!KILkh%~0`VcqgA2r$0rA1<Bh9hd
z#sMXPyhYomE9wZjCl!AJ0hI!<QV40O3f{s6seFC`z3lB1zW}et6ix=u-Jq>(3=9kn
z9<AV8JxirtJADG30S&s+4OG^EZ)o#u{`J2^>l3K3PUF`*SakOjf6PIs3b1OAPDUR?
z&}KW3%F=6S1u~?lqk0(&GZ1$fE9u%T;M#f#GebQGZ+~unBf+m}q5?W5JOF;Qln@i>
zI1L_L+o1o!bJiE!Ig7syv{4o`yzJW>0X`ikU)6IGCqo*4zOLaUP6p_1XxQA9^9Imt
z7HB;XXkx1Da2kKvX+%at?p`9+Qh`(lKS<**yA0}lf_UB+()jOR0q>UvX}^6Gl27wL
zLKoV7O5@K5ZMr>|#-Di&B6j;MDF1@?O!GHofEU_954`g4WtqU=!p_LR;My(W+Ikxl
zf}qU%l>sCYzyc0bSb+{I<6XNwI9yv#@=tYyX5Z7GlDRv82Ne2_(CoV%ELI@U`i+08
zBQ*Oi28%_Afb4LDW?xW~$hA8HVzDD6|JJ#72gpFIg=FAd*KQ95h?S5W90S^54Ym%F
zgMA#k3pBu1L2|H-V|RoO*cwO<)^Y8QFaZ0_5t4<aUAqHJAXY&0uw!?G1y~0kzlMnl
z=mJ{E2|e9B4PcuQ#r+#31t{|xgDD9f>xU%4b^W7Ba0DemaPj*YR$3wkOwlV1a1$4%
z4qp>j9CWiXs7Ppj0cx>>s)^<w|KWGI8XoXyy;LIP*=%zFrN(=Qty=g@WJ?*lI?y!_
z8lU+Ec)feES7xr@qotu$l?S3S(*^fD`1M$YdN~=2Zhc17XJ8Ge_1R^t4yR&(qQ(&J
z`iwMn(2zx|{+r)OfC?xF*x`(#j<;bqt=|OI;NafHYfxEt7<9ihF12^j)PmG$z|6$m
zXCYEqFsM#O9QR1wu1$Rxw6zOv;f{7~$mrV8G=A=PjK&W&yPktPH-2mzjcp2Jo2I!j
zuyr(kD2$)MQ0a9wk47UkqfyS)@DgaC(~*DbA<&=<X!ID-aC-zEU+6|Yp5Z5WxB%yR
z*t_s?1<(c)9K*BxZOx#OE&lhn;p<^fg2wOGHllRsV5143HL)d!AtMQ(Q3UuYysscT
zvl3r|&f5j8g}ne;=LS86HyiB~-esT>UZhia4Hy|1AbtmVz4ZWSF{}(!3_Q?#$fNlO
zBX~tDD@+(P*b5SdEQ<vV0fI~b5BP$FnZavguQNalt^f@Kf`lOpWI=2Az^Xw5zaU}O
z&Oj0VmX$EopaDXVFlf0ff6FA8FlZ1MB+L$4H(L)j05og}5&|!t%>fI627^IDoS^f2
zBf&zTfkcoHcp0r5SO_#I3=-l7t)(>v3xS3fK|<gKwF+P%(BLpgh!?b~me=qAbb$B(
zd}*!WN$@bSBmdNc$SZ80N5^3{wT*AqsPMV)Zx2!7OLJ^I#lVy1(ix({gVb2hQQ^67
zc{4|a4>p<%y1-omY!awj<NzJfD=`O|#J}A|g|FcZPg<u7*br!s=qAXJ7!@v%F(4&e
z9iR>!co6RvybC~*X}4okI6$U#yQpxa!TVdKI7~Ao<Te`>kYOI(EGh`I?qGKrg=T>Y
zX?Uk759BTv{_Qa;d^cI&*Ksm<f~F`yW2Fsgj*X|mu@R%f^I8g&^}&G%jtNjt7_$AW
zM9cBE#_g9y_isD|De+}Ifl%dRC<u$PTX%1~X1WWyIFS|+hvFsT5|ku3xFLQ3-yZ>S
z7wIP5rm0CF_rQCbNIlrwmave0{h8ps6OgM>HyYx+CX~P>4zOEn?;D|*0J=GZ$SWM=
z`BCo$ZbdZ-*L^Tp?odHD$r`swIIo0|=SRLD_$N4AknRZrxrV^S5U3_>$87?rNYQ{5
zP^ymIpgkT3pk)&Ha_%(#x&xp)QQ*bVZO|BukBWxjCEwPQB?^w+EEC{2dBYU5T=Zx@
z#OP^xvGf5_>>Ge?4~5>yiE{6Z!fibd#&<VkRCGS`3%IE0ykG-67<?T^^J~UZ&;=$K
zcaLGe!vy`B^F0PANdgpfuq1&y_))GFuL7HZHTY2iPX{URJdQhpuN3lSJn;#1+j^P@
zf87DZpjYV?=<E-4uXu?*RIf+#D@K@J&*lRx9?b^@kPUGB;L-f+f9b`~pvuJpWPQTT
zcd*#=ckE_>#+*l|iwej692Jh+H7WuiWdgTrR1|LKs3?FO(e0ul0Xp6gB%uI0-4Mjk
z@aS}u@L;?Mu5z}*OG67Zn?OgEmIQ&$0|hy?`Je*WnRu*od;l^XWZw%A17zO^5Cdf2
z53p}GAz9XXvc%Q5^(21_=!QRE%Y*!_?Vv64t(W*)4uX#Nw7lri%Nm~a|381rOc1~M
zrvQIDXm^W8FKc5SCxchANQVdGh5rvghD<%+Yk9C#tK~q6nkQJJT+;vlB`Ka@O`zFI
zk6zXZ$eKV2wz%a$Nj^wPdA&z3>sDlG&|s>Dr{zWdmP|$l2C$lFk6zZRC~A6HcPjk-
z|M@Uj+Qy@o^%t@<SX9lUmsKMl$+2Kj0gqnRFl14WURH&~|Njqr^s??&{0pYJ9U$~_
zGYFla3!(3-Lg?K}5IP^K{(TWdzl9w{{ImvyR)DH+b%gLYT0&?a0|*^!0-+ykL+HEq
z5PE_+gtpLw&_~rE^dwsdea;9%r)WWFZ)FHw3f0dKb@y={h`1-z9Ys+6YoPj_p!&5z
z`az+?-~R63|NkDntQE+i>Cwyj3K}AOP#>(+hnUO)@@ebI5<gHvXt@G9YXg*;K$Bq}
zt(W*)*&s2<;?c|MU;6)li3)$82opF`IXrq<%ZmU1FA)S;?9t0=U;O_+e`^;b1H<RT
zAk!ep%Aw^zi47<*wEl)9M37NDhJXK;+~n`O0Wlq9l#un`|0TzuM%{M&`=7tn9&8j?
zuMHyuL(2jF788gDkQv+tfB%<E<?q`C5dxW!Y5DhmNfXozc?XagAWJ_V273iG7w_5p
z6QozQ1e7yE|NsBb-)Dx<zo!r+Z1?~Ff2bKvAc0oUEa2zEAa}H^f+z-=@gL;f7D2EX
zpwqiOn}34ba0H~K<<~#B8Lfr?|Cg476FNxSI-S4&`CD%N16lnB5+WdNRi+@}!w7BL
zZ2$f*b%0t6x~2;1bZxM;v;O`6UzZ5AGP?le>~@4+J+MF-BqgN8{r?ZjWgyGLG(on+
zf-RqluzaH-NZ1WwK(O`S|D}h)Zf5f6WldE2`@eJxoO?;-@Bh-JaBdn%b{d>}2PE4L
z=jy0~qM_vfe@I>j8JDI45=ulC+NcH+@<SFns0b3Wh6#b3?^gu!=)AxG|JOxB{k|_B
zB-H&E9^CaHfmRk|ZDn9>=^$<9P;G_a5DGzPGXM#+p8bd9OmDE8b|DM(fQ6QWg<4OR
zgn*KH%QIM}0bRKSPHAG0R04`uE^xd)f(U?$E=O?sxCrVz_lkPOf-`HV_FqtnWAWg3
zJ%p5X+*%HlIDwK~D`;LD>hcf^P+Uz!7#L>{5@>)J_%jA<;7eU31HmSM`oN$Jqyf<g
za@sO8kVbci0LW=8Z9xK{{NT|mx*lTE105ujz@FQHNH>=aKpH@OW@vu72MYX_FQBTZ
zS2P!5!d!JE6F_bO&(cGE6KxDK0d&L<)P$p86F^zjqgPZLV!~%lWD_9SY?~2CBWT$S
zRHF%~{HXQl75x?s4uU2WO_mo+lA%`i=>Pp+5(3qACGY?L5_gYY(E|`&E7dTq`mXo)
ze~B_w!&i&H|4YO?dPVyo8tjlXfYUrEWVf6C{a^ACs$(w5iYFeuqOlMiCy^r?>ZX@w
zfB%;pfNJ;v(y-a1S5yb0Ard(XT)IP4G#s0Miu1QiF)=WB^s-*c;AC*^Jn5Ir)8WH-
z;{OB3=3nCc?N3a>lA@U)$%|-`$03ptSS43MBxh%0)7cA=yoXh?03xZFg-vHLL^1`d
zq!~nVIaWzYh~z7*l7CFV{?yIJX6Jo~WC2#mLlDW$SS6Q2B)?&m?0`sG=3uik8zNbQ
zRniY4xgV>fAw-fX7n`vn5J}fuP6oeZo(V`X{mU2}0^MlZ3=bUkX#S<Z-}=ZLR9*jI
z;%~iS4pJ$)G7p?Vp5*=i-+I!6-{lZg;Ynk#LIwWT{a_<S7e|5>P6|g>D8S$9U<OlY
zW(GD<D;caX(hpgo0)Ojq6R<)K{?@%<=ZmIBffW{pAuAN%Zw-dHk&(aE6XHe|Gq6Ha
zePo3S{H<ppZWQ2eJq&SUImC^f=q9>A+{nV;Y6Wp)ydBuYKQ?G4o`$%Qg}?P6#Eq;8
zV1?KGkri_Ax6U(#d1eYYL5jYR2P<rmM^>o7-+I*urtq{8IC#S2zzRPHAS)E$Z~X!{
z@fF0xd!As0t38nwD)6^nhWMJ1zZDcm9=)P7AZ}zp32+Yn)(a5NaPYStgLtMy8*Ji1
zEi@Bv!rgct;>NX*aMTDvRw%&Vss?c*6Mw4=#Ek`(U=y><krgWNw_b<1kqHt<9=)Pb
z@nD7De32D$@V7QV+{nV;S_X0BOKGsepHj#Q75H0|4Z-2a!rvNc2oA>!klOM(imwIu
zTdzS(<lt{T12M773v42@7n+HQ5MML$w}wM}{R-knc^_nj9Q>`t5YH&^w`M|;*%C;A
zAJ9ftsKDQv4soLZe`_qnjsL>IR+|JPD-?i4oM-b77I^0R2?@t(7RU+}_*+vUZe-za
zjfS{U6_RIWqof`V{#Ip(8(H{UB_VG71qnwkX*3h_4Zz{Z!QYx{01n6X5nwmw1|lmI
z;BT#jn8?B3nh!Ct+Xk#q3q8-|LVV2#i6f6*(IpT!UO|Z&4*u3qh-WzXTfHHkd9DUF
z@rEk0)e8Kr#Sk~L@V90{+}H&PM_Y6^u7;S%$ltmUVq%sF*u+UjXeJgy+{grpBadFu
zd`JpEhVDjIh>1-6t-m2r_*)!oVz3yRiTm`x;mE?@x<wBhjz1x8oQzUZ2tXpvv-yVr
ze`_GbjgLLRCNA|rHc^1Tb&o#SL?-^$P5NLHca(w^zA8ml$id(G8e%mQf9pet)t2R8
zh1uoE3I+IEh2Y`H0SU($PGE%#9g!7s@VB}`OyuBiwT77Jq6AhbqlBzbfWI{d;zkz!
z)+C4<dtJZ^Go6tYa`3m#hL|Y8-#QUu;&N56!U~kQ7T|9^1Tm3`zjX)1L{)pRLU~&>
z6U%kM!NbDenyU*Ao@<a2mkp)F72t232e*0(#A*juu!(}MXeOS8m<XyqASPC;gBAWz
zLskeXnjt2#@VCB#nD`9h#`ku}3OV>&)gdOb@VClBOw3jQn>ZWYjeZalIrv*$ASNz$
z1S>2=kC|GyiNz2T^&v4MtcYy20DtQeh>48+t+OB|rdxwe?6*W#$id&r1xXZ4{H+X-
zL=hkhR=5JCq~PFhO|$|BIH-KI0tfhAA+W+`L1YtI_*;KKN?b<%)_0H+x4ZTqXw*Tg
z`X5r8f`h-+-yUotD8bo-O_bUQHc|M)UnGT0{H<(|T*$)T`UjE=Sv(*nx}%vGYXdfs
zg}*h}25jQ==U|01pCKz`;cxu{X#p_tx4we30A}n5TP>T8rqJ6FY$6ALtD_^>#D~xR
zf;{v7DY6?G;hBqrzZIIf5_Q2=r)wdbD8S#E2?<9g{?>R%II8^vE4=a-Ss@F5D+8o<
zW#n)D1_?*WsbDt-??SekgTFN#9*(|{aI9MoHZgELvWblRt$dJh<lt{*fs{SG`C!lN
z%t1Dhg}*fw9*)tFaQu51Y@+XBWD}YATmL}9k%hnY6C@mM=73GinvG^+FeDrm_**?8
z;aCRgzgWyfGf@eWa5?x}B_Ih`um$XEw-)4N2C9%OU@?<#0gjpNtYC$WtjG#k_*(_w
zH5VJC<~le7tgwDBvKu-0Thnd9CNlE3#@d2S^jHa2`1J*{LMHxJIY^#i<Zl&$<e6pG
z;NUrJiR>8`{?<}RTr2RmW<%n79i*O7xr(fiiNBQx64xC3txS-XRM94IIKJC}Y&8pi
zYceFRLG2z$T>n`JcB9=DWQC0Uty++9Wa4jCfP`Z_1K5po{vj*m;BRe&hhsS;93OuN
zE9Cl)>_!&;Rtb1G@<GCprx2_#p#WJSsDS_pM<)K(R7f~3nG069Y7VkOM*dbccsR;H
z!tn_tuJvM(-N?e<S_=tBM*h}fNH|(<1)CVU3E4y@{#Fr4I4bbBazVoJAtb<y<B%1y
z@V92e!!Z#Oj?qWJ;i%t)tdNPn)lM6nC|LMgO|-#@BEAN!a9Ry=G85o$oeH<Q8)Ef`
zFtEal=;=`h;%g56Rwan9KRpF2tUZS8YYzU_W{9s@_**L>zP4EfR=D&fvO*^QRx3!Y
zz{KBb0I3z6wt^Kl+aY^~gTHkmyeriX=}Oh#0f(c}Eo6l({H+?0l7f-HRSr^8$X@`P
z*cywbupUxUaPYU5LQ0Akm%#})=rXb!8Tnh?;NfTk3CG>6V5@I1Bbz9|-#Ql(j*R@R
zlOf?42uY73=;_e}5{?S|ty++9?1417tV)ng<lt}ZhKFM#Bpm0>16wUN4_P52f2$KD
z99j5VEg<1|BoXYHzwyYPVc~C`2?<9g{?>j-ILhw^o2au3*+fu$z{61u5{{bf;BZWz
zf@WenJREBw;TY8iHgR1qnu%eW;PlAB-|C|YPLH~f*4|q5*4|o3c4gsjT@1;teLuk_
zTKq&dkp<G^fb>4BASK1iiC{NA+=lE%P$LdfQYi4ZPK1;co}plc7gr;j$jILs1c_@7
z{#Fl2Tqk#f!|_i$vWYDGtt%mM&B5O~9}?GpPJ`VTdK%e8CjM3jNL+L9x0*rXI&2o$
zM8BD6CQgUMH6wp(FC?y)%mlkp;|#JwM*h|~NH{X`w}wE%@#9ypiC$lj6>{*mZiR#+
z2Y>5oNI0%}40faUV`Mk7@VELvN?aEHRwqa}ChP=Ty*L3`AqRi!Vn{eL^0&@}gyZ!|
zU=ue?LRQGg-x>u8M+N@Y07y7?LIV7P5wb!K{??7~a9j=v$8R6No|%K*lJbCuqa7q1
zUj%}!o*aN|A`5@(d`LJl@wZNegri9{SYc=tvO*^Q)-S5y^vKBH`brg?9(^mpzHY8W
zE+0XiJc!kd{H=}<t0%L86;5YFR>;EN`bZ0Gq5^;G4K1*V`yYW7em;U0GnNovv+%d-
zLwx;vDOjNnO52Qyzx9JU*hCio)@SNq6Z;_b^%g5+&v5X!x<j%n6Mw5MB)dMi1@`sv
zo5%`T_*?JkfK6oNZ@r=eHZfr{*y^WIXbMdsB?Sk6t2U&hP`n9_8M_<Eo?+x~{R0U{
z4*u3pkZ|;Zl#lzEkWB;)hrz?q6B3S$pTTZi_X$}csB;1dM@IhE2as^QaUAT%$!n3V
z2DNM<;mE<?Y7Pm<$B@Qw*eqld8Tng(z{Bw!Bpizpz@AwhhioDXf2%(v99j5VT_NGf
zv;*wMpzX*eGV!-QgM=d!f9oAcIDUk*0G>CaB??=3I2uF3QLG1IVmF$JJSyOr;oxs&
zQUS-z#R{;mSy0lW0Do&TB)f9(w?;y;>-Mi;6Rp1@o5;f7`bz_BA`5@(2Mw@^OMAg4
z&fSFUYYzU_KuAf!$lvM?DJk}x1}n_Jhpdp1zm-D`Y@z~x>pw_bp9}^oeAA7rkcGcB
z9un7}!4gPZZ#@Zi<L(p4Ze-$b{RW9^4*u3Rkhos57#uU<i_lE;g~T-zf2%Vju4|@&
zt!6lhtPs?)g@hv`e=8Rx9K9fo;fbG+6>{*mX2ZiV5fYB;UxVG)_8QrZEc~rZkP?@J
zzx4+s9N)%(6?(@YD+I*{JRJQY;ix<TtWc&8Ss^2Ts{kY%8Tnh;)W9*b1Cnsn1JT@=
z4hcsE{?=GXI35WA`})jVWQ9!pt^eTR_yrP<29WY`i9fQ{Ec~sZkZ@$-Z}o<Rqdlas
z_bo?O$i&~Op$Lv^P_ID|>_+usu+?$J$SGWazqKAx*n?V9kiy>a7ueS<zmQF2;cpd#
z_?m;il?USMCp*D$&A1cUGaUS_xe#A7@wX;Jd_8|2*lHh?^vJ~Ds-g^bBO`ySlrq?j
zy+&ZGKN=ug&B5PV4QU`T^0yX38c3dJzzYANr$-@3o>Aa$<$%O>5+uOau0VDpXhaWQ
zQp7__3Jyqm6gYvbkdeRD01}QY{H<z`a4h`}_VuK%$O<|5TiYSwsKDP^3kk=I-e6zr
zy+QU23xBH|JRC(J;V6*~_Do0`vO-XNK*AB!Yk-8~4M=?*fL>qgK*EuUzf}nmj+cVL
zZd4CKb|VXaYco6?D<R>yXD!(3^(ZYVCjM3_NH~JhIwTwq?*n^ArvuHzLP$7*da;mj
zWG)Arm{^AF8Bj|~9vs&!{H<p4;J9vw%=qj>neh?eZ=DXwt}Ohmy^sb{$~&-$eD9D=
zWZ`esgOn7YbOb3WGTXpzT)Z0DjU4=~t?-hf8d6e(EdZOSxB%HiM*dbCNL+L9w;Dm>
z+N}~CjwxlxCbICiPKLxa2Y+iPB(6mu{lX1fkWFObZ`FdtH4A^M0wk_?^@2@&(Sv4U
zBP6aF`CH2&ah<;(tdI|7uz-ob)dLca3jD2hkZ|mS%yXSfM$XrumMuISr$WLp{yNy#
ziPw<b2#OC#II{4!>OjKLWgR#i+e6V5_Cmr@fxopG5{@-KV1=`;BYTFCztsgEj#iLx
zJf{S<I$j>xL{Q5f9*z?s;pq1S?CTGYkxgXcZ#9C1BL{!01|%GRnSo8bW{PYg3x8`T
zJRIvG;rKTftWY%vSs@dD>wIZ&dSv8pohl7Zj}j$d&-j+0h2u9!1BsEp^$n!boC0Y-
zTA}x^dlkSYGV!-ID}YUmxDGb4DH_ehC-B1l7NoFOTm)8__5jV-vt_|1vhcS~lm(lp
zVh8q&mo2hqKutGz1L*~%f%M`&SYgn8WQCyMQ39LD#NS%41U8Xl1K8?w5oih@KpIG(
zi7ZG1Y5xUq%rsm;b|WKy>vBjqvhcUgg@ofLA+XiK0>~x`K$;w$&7dh?P}AL`S9CQb
zU&o^7>#2}%WaMw{hJ<4!Bwznog={sn$pPs=f|~9gy`mwrz*eiHw;vZn!jXf&btWVn
zld`~`;mbfa5!B>@ha;%z?$Imiz6)&P?w!b<Vd8I{2nk0P{?>L#I3B74hhz5yG!tLI
z!x7YU_vjV%ZvmT_fj-`|T@oBK0{pFOCBZTCIRR{<OCoaW5#Vp-gJ)M3NOqn50c>LG
z2V^(0@V73N1DgoSW^!N?6}!MDYOF(cBL{!$A9!K^2~ybm&jKs-xQVQgk-v2_B(9nG
zTUSEjdMad!?Lri?8(H{Uxggn9fWMUil3lG2fZh0eKe8K{_*)l3;u=)!L*n}IY;eqU
zp^xMKfaDn#{?>PpJd-mC?8fUy(cHKn5{^v#ty>}C=nENt>_Q)Z6oZ7L0Dmi}>F&`h
z`uZW*je8y<yOD*zbuA<uK?53)a9kM$R>+Rh=K>9GLrPpGesI&>qgQnHWU#`8==Jq(
zNH{X`w{C=lBTEt3Gg(o{p5fqc6@r8#6Qt?x(JRUY>4;~9A_q7qKH%Xv9}<qeo?xr{
zQD!PYgZq#Ymj%*v_vjU!44M0oKyN=@76Ydq7XH?gV&K#>JrV52v*_tj3sTq%@V6>J
z3i~IJ^tcQ?JsyPkT7bWGJH*#b8^Lkyyb;aU5)far@VD|oQjha&u+=|M(jyap>v;*V
z8=3f9k4k{u_!crKeIKP(;NWjngEWvB`CDZm4J3=J;NW?E2|2Er_*?fvN(v_a*3FQT
zVm4$j^%}}j4i^4a5lEf^O=LmxOyg0oXI`TW7BKR+-iC+cMMyX<V+LD&m=W1(Xp;j{
zK7yL=9=)PpAT#3Xk;rikiVt`=?uUe9U_98wER-=)4oH&&Qa*y3?jF6O+aT#tZ!)sg
zjQp+FA>qiv-+C4jjv|HN02e|Z57&c)BdEy*3CEio!B#)pfNUZtJ|N-9$ltmf5{|pe
zz$Uh!w;yF7;mE?@3TnE0^oo9mv>!v!)8lIqa9nfnw>}gB$MtW>Iy~c8<lqtDZ*_t+
zkU)c}kOtDXmtZ$8e~Iiy7XH?okdlIhzx6z%r0{G8yRmCIT6#2qmlSG{68FV4u!$?C
zA)Cm^-})R9*8=>lcOh|op$MEPrWPTa$im-h2gx&_!F@=c`3h-2YHdX}k%_<cDkQEs
z_*+jy;ySAjY+_O`nu$7)Jj2M}sszb1B9OxVAbR`pGb9|D_*-8>!ck-f*fU(yk*((7
zZ}ozNBL{!010)>vAY)Q&=wtQ|;o*245{?%jJ@$|wWD`O00SQMYNYmY;S9De&IKZ!>
ztfye)Z+#CB$ET2RydevAqoyRXi5&c`Zjf*kfHd7bdPS9QgM;VEE#%-~;%~hR2}c(G
z*2|D^bhZMUD2hIFW&#OEXw%)JS5&qDtk5nW*=i>K)=oiidSv8ptrrBR$7aZas-1CY
z>G1)?Y9{{HYY?j^Ko(w{Mp<~l!rxjB_jNAB*VE2|gNFgVzCH&j>{<9*k3b50rs-gX
z^;gk+-6{-rBMX0PwJ_L?-{*oAzBEMk3<rPf9Y}U%;%~hK$*wamgMHnAQa-Zqw-!T6
z3P%3cOh`#_VKLamX+Fp%vhcT_f;W&3KpIFPhrlt@auC^#jQp(=A>jz>KtsaO6jDB}
zWI#4ifWP$xBpey}Tkk=_u@5pHZjC-3UJnUJCjQn^NI3dJR$jHDti0mjZ@mTyN6->2
zNI15y0edE|AK7ZqkUl&dn<3$NJR0m729)}mg}?O)Bpg}zTW>+aamG4uIP$DRHj#<H
zwHgwRO#H2dkZ_EEjLs;wA_or(f9oYkI12E$o`8g-aT(Y|7WDr0LVj3WPv-~6wO<<8
zGYx5I>G207yK?ZizJp}f4Nt))CO$=WBMX0PKcu8!;csn)loYJ>U=!UIBfF7<zx5fU
zfdm>%g*1>3xq%h_c0;zBk-v2=B(4ScTPH)}`fC|D9OKZ-$1jk$7T|Av1&Ql5o560Z
z-Hhx;CjQoLNL;h<w>CoJn!g8Z;>#{%H-ZNDA#u&b-+BWQ*KZ)5ikT>j8W{OoS3<&(
zk-v35Bplm5flXxlh-@MUe=CC&EWp1(!ja(`*o~nmbL=eqt<xdl$id&*3kk=0eqe=v
ze33l^iVsLQGV-@RfrO(}8(5)m3$j8+{??_CaAe|doec@csgO0A7f{w{f?D?QaQp-b
z$89&jo(V>o1z_TDoeT*_0shubNI14Y%ExGwnF`S0J|rAj_*)-9!m)fAIIhjm``3GU
zz`+A*N%4TwV=SaOGbI8!Q3&w2iim?13h=jbiGvk>cmnqI!6(SRX5nvL4e>P#f9pbs
zuf-u_&F&~;&7c8z8L){={H;GAzFyW3cH{hW$Wh3|-@20ztdNnvbv+;0>X({et9>=l
ztQLUe8PJj-NL({QYA$1xnv03QbvdM@08J-DN{a21!2y17BC^#i{H_1sCB+v=Nl^hw
zk1J6IQyKYNk3zzcg}-$-Bph!|274wFef&`d9*#nga14Zu_lR9b^UP*QI12E$u7rf6
zDP*jfEf85DsAUTYM^LXp1{^#ckhoUtKvu}e-+B-dj!gWm+ack|7YO!svOk)yB_QDl
zS`q{a$Fe2h0MA^6Y$6kX>v~8yGV!-Ag@og5$l|$cD2wM<_*>Z^c?Oi$A>sHY8*HLi
zHkyf7xxjJF!rywD3+$Q0khzba!D#7GM--+|NffN`&ONY+z4wq!WZ`c;3@Ir<=?GF%
zoP^AX`^-W1H3xsI6r`jO;BOU>0-MOx4L0#|7qW?r{H+(^aeW*T*Wcs7;g}GEY$9lx
z1SGCG_*>;5alL94*u<t)$R;xJx9*3;H4A_1R!Cf*YXqD4rvc4GF-Tm4mIOiKng_B*
z)5Qrnct9;FNH_}cw_b*X<6}rWTo$Dr&cWYm0uM(mNI2d&2X>>=Ib=72;sX+npvCTx
zaNGi!F0erFyDGuMQ34W<^C4}Dj04D?VdQVU2?<95{?_x5a5UlqTm6j_*=i2{Rs%>l
zf(G{?;h1p_96Vg;CB<<_ID$3}K*CW9vdZq8HnNE<{H-j^;MBv&-}(!@6Grq|64+|K
zL}Z1G{H^kk09W8|6@>)&K?`uct~EpR%o#`-&cWY$2vVAzH37S^%>+&1BZxu){?;21
zg=<a03X@II6#77{2KAL7R#zE=6}lLsDLfA`k%PbWD8$4vBd|gXBQ%A65EGgBTU{U~
z7W04=#&Mx342GD<!r$r%F>#hCSYfI#n!-yEg-radCm;&X9RLSU>jC8S$jILs3Q-7}
z=!YomlmeT0S{%*9D-eZ@{H>=T3VF7HO-$W_X5tY@GGpOy-33Wzb^>4%Ir-2`l!Tke
z4>3_^6WGMo4QM9Lftxr9Vq&NP*hEPKG!vyECNlB23PMa=pa53bEr+JC1a4v$#KdfM
zutGCcG==ja3PHo%5QTRkzIK#BQ+NuZkb}SV07PMw4%oywnrI3GA!RrVf2%vB43FFa
z_O+oBTp?(iPp|0LSa8Zefix`9E4ob;tazz1B8YlLe`|mRrz#)|YU_XnjbxDpD?WnF
z^!$j(O}(P*ko_c!QB)p)tWKEt8CfL*#G-vD7R7!7o2iGij-gjH7vj#zNGs2KMX$Mo
zog{$NbL$nYgzO&JgtQX6SM<jZu$fzbAltqIqEZ({<<4(lmA&7PRlbF&T!G@wMu?9B
zQG65*ac3innN5(&axYS4*(>U*3wC^^ByxEAi-84|k+v1|iZ((*{w0dahr(c$YlV@u
ze};soGD^tvKvaU3X~VX1^@{$`0&72sw4bI|v_cRp=!vwFyH~UUvikiSikVON!78`%
zBin8diTB$m?sVk^s}$u$R=E#irYMS;SGd3`mvSMiJOT0hcX4Dven`-1qr~P#$g+)T
zNXs^QMUx?Mq>mCu^^gH5exw1YUeODX72*q@BgcEvGjL)sMp`!BD{2O553?b)hkHdA
zLMEY#*pS`1jRowZb{1qo9VW2gAEf0@y`mTXgDqP4AKCUrkccZniDDlPu=e}x$Yy>N
z0Sm4ZK^D}7q@_=y$bzPjJ##f?$b!9)m6hg5D=T|NLF+a^rzjvT-{=+n4Ov=gfz)Z}
z6}=e*wp|>l<<=`&1(}Q7fwXI?S9CsP_WvHzHl<!s7szlx6Vh-%uV^i#LB9v7LEkGX
z2bsZ-^+tAlE@TLP719uVujq70kM|=|kGEIUI|S^`Hl*!qy`rX&0p)z80p(uNgAm7i
zA#F?R743nPHfP+CZ9nP<Hj@Qudrz-u9%Mvm4NAFW^b1^m|NaRtmOXk!d%u7M!;lsm
z_KL2#0~V~igRGM2Jy`I{J7mEcNcYhXsr%R~dg&Ed<&sy(Dt)ei1?7;Ihxdy9fb?<7
zk=C{Mibg>u7PXKj7JEfEL*{{-pCFql*$Vc10#f6wSJeF>*dob?$SSX$0t>D<g)GR>
z1Wxl88<EreDrc~n-;g#A^@`R&62pF!#K0#C*8V^QS^G?RuwXXQ#CEUfI>-!YgAlUH
zP{??!yBxCME6A!`Z9!x~hEA}PKFJ^pZs!GC)X9r1SSJY<3_uzd?G>HI2^LI8YU}oj
zMnE>2&PLiP)GOK!Db`k{B8Sp6$kMv-1Z2Us7;t!cAoW9fMe87gV2;tqDp^CpD$j)=
z3l{i;1uc=fgT10tt-ylmR>&$ty}*L%UdV!T&A@{BNG;=D(O5UIpuQWj%B7I@X*p8+
zv{zICGVmbhf~@k19$5QUJ!HXd2e4p_1G3;kNG^V@gDj{6$;FfGkOjLTOMZW8Aq%FN
zgJW|g($>^o(Jz`{L2Gv8*yLvdN8AOZiJ@N6?|;Eg+W8mR%r}3)g6sYu3re|xwZC#j
zHnSVj+S_V{T!z$c2itxFX$^C)=v#=&=;_F2&W5b#SDA(^7(5khyZBUO!4s3ff)ghp
z3)W5m3%Vgqiua06O$FN?j5I>mE1HlE7EJF)*50227HscC7L3XQ3(oFC7VLzqfoVjV
zUFsDL$povMiZoTyD+)SA$fK7v0%=8fujtEku*w{yMLE5qf8)V|=13#5y`m=|j`v1!
z{P{Uxm0eB9PVzE_2pS`YygsBIa@QF-jw&6&5oha&EGX&#7QAJTEU0e}7Gy>d)UX8$
zez8GTX$M(o%w>%%XkrXj$!?4+7+?t&R7RQz=@tC}DXgrGkX2rWjG~2GAPati6jr84
zGYY+;XZyf@4>U(s+1>#b<Uv~7*DIO?S<<RuhO9CTQcb+pMHY1I25V<GK^D9Lna{98
z>V@};hCn*f(~&kY_lk-`TB=D%;~u@D?`y&7b3-k1#O<pF3pP|E3+}1{3)WR33)+=~
z1=-7y1?@|~f*d8tf<H3Af~SzyoAip77lH*n3z1c>NCOL2r6CKdL$=HP%tIE8NCB(V
zN<kJBfegmn%|#Y`1u3j{qcl18LzZrIAZ@|x6}<x~>!gy9wcmu4pNq1P1-l{3CBGo;
zQ0Wy-G6cubQbXi4zeEKrXr_rAal6&Psjfy1S+Ge3Ea;+wEVx7&ELfq8EU2LX7W{}(
z?Mgx>2_K=<n|=IXl?nXF+9jpHg0E5PO>W3==^doyalN9tkabl5kjDOcMSooYYhQK&
z*~}bB$Kec8-@jMXND=IJVHB1A=fT=V&LeA&hYXIXA`Oo9icUKVRvEeuIXoXjmcA~V
zk1S{c5llr9OgRSDp1KBEr2%B8%cWJwf&oXtD&Mb07SuTf7VKS%ENF8CELe%6QUkI&
zToOg49%Sn#BZ^A36JYI2QJf@q2rSr%;v})-U_o6Jl>rCAf`SK;gRTow!%ju9T@kY5
zx$Xe6%Del)+Lt1&Lh2RG*asHW-G{8QX)jo?VKTDc*&u@HC|wLo$PTQ76OdIJLN>x)
zpNcHF6tb3V7K-5NHDHT0CL*i+4%xNffud3sGQ@ig#Ujt`VC|~YkhNzl2Mac%sO;GS
z7QBRFX4fLHpdpINbr8olps0+P4OS^R8#$DAK|=l(N)!t~_QSU!EyC*+JvkGsy%%ZM
zZLg?1WaWXt3}iD?r-N0hPeJxk&s4CWem}C{b;xR#kA293+d9B1wPqs=Izv>-&p{Tv
z2$@{FF$-C6)kLuNvnbl%K$h&ap{Nvu><y?!QCSV?V!WA&Z03Squ$dYtDn;wSg0oOm
zT6Ka2uc2794zeJo0BJ!?uc(F|xM1niL$*i_lIHc0mVESz^6ddv6Ki)Pm)=WvfdyTW
zCO>;cvmnd)^^j(udPUiHfK{&Bj;wvcHn5;M(nh^r(e;ouLo1MW4)=;GLZ(F0wjyg^
zRseSV_4UYt5|9N#Q@0=s&dmp_WJ6KO4>^zG$Yx}fqL9_(hmiId^@_GbCe<5|Hq7*j
z9)&bDi;z}{_llZB9B+W)ct6N~ZAKK8VUQ-=bamvAZ<PVNleZW-B?lCNV^gFES+E+i
zciEv3S#T<3jY%fbhUQ+;Tlrw^%a9hH^oq(u1YhSNYj1<J)_$fS3r>Z!mugT{mL-GD
z^h`!p`7;MBcm`<(w^#I7B3N)H(zHddXcEMt-$-+7y`rj+)o0)1kj-q*1Z$7XL>62J
zSvT2;v~IFjR3H_s@-d3zzej=vPevkZzX7RXrFD@*ejDV}h$~3@J9<T>mx0sgou$Yr
zq+tnI&}j*>U?F4**%WC>L$Bzw1z?ry7a*&gJr69HG7njB-!!n`M3nx~A;?h#Q<0_t
zdqtZeJ(O;gPE%Y4IN9_gEq3h{txW<8?nm0G+bbFY>7g8+g>1VJWJTt*$;g6lAw85?
zD4n~HkhMvrNVCwrqGupZszmAWl|t4}xT180iXel`n~)Ao=@tDY33lh6aO60O2n9!+
z4ARztUePbXV8NZi$SV0Df{%ib1=%4p(U*~Sh4zZd`h&H<^g~v8+Ziml4y7lh?+X@W
zLRwhSD|!X8vu}kHvi5RF7vqmNvfw$$`oB9U9kD{lppyZL$_0>)SP@D`?28B3_G2E%
zX0}5*Vo@j^u`UU4vT=|=j<_d~S<gKj$bwmrf<;XVS<pukto=WV_OIXnfX)Xw@cj?`
z43l0_jn81g&!3P5?Zm*^e~KcT84sC<lR*)T`~%jm@&{S_QZBIe0;H+EUeUu4GrPo)
z%?yK_8=`^Ikf>S$PBxlLkaMvjqzB!~h^+nVTd?hi-Xhx`$_%z$i5XdCHKd^Soq=rT
zRz9%G2E?qLW4L3OV<_}E^2RqSm>C#6x?5BfSQr?5y4R>UurM%qboQux08Qa`Uh(NX
z?$deNqkD}?09b(qNUZ@#O}7DvDF9|Ncy@mC)%@pc`3`h!vj<2b0wmGtq5@Xs0p)1$
z_x3V_?D0|Y@aZg3QSj`%;nDfar}N?etG=BteKkLNH17dh&B))<0(F@N$YTEWH7XuH
z{OiAa9DKkGvZTO+8RBS<&VwGEEh^wcxw~6bEI?L4)l`7gfF0Y}qS666`m&qBqw^3*
zdj`mj5+IX%bwKxPGWc}90I3H1r?W)`ba=A|NVSVffRE-6|6Ust&(3Q;+J+vChdrDB
zG4l6;4r%qVJjdT#2AbmT{NSni(Wi5b$_$V-{OgZ<cHZ^vJmb^(+oyYv3M?=pJbT^#
zyBdB2xgg;+r>Eu@{=TUo?cFUZpfK|3_EGWh?R??UdDEw}M#aDb6h<DMzdW0dF@p4H
z{J-kMoTC!p!5pI!;oJGp$GSu%p>&65=Y5~f*Pz$~+YSvvCjJ&ju-Q|<Aqw&^#8*Aw
z!1C#ah6%HeN`Vivi%Nx0Z_z&=#uvV=-|9kqx}myyr>HDo07Y4fN`+6Sk4l7puS^i=
z$ovAo-k4h#e7ZS3nh!~UF6!;{dg0s6;mi2Ir_<|$PdA4T;|rfouOB{^w@Pn<JQe{u
zGdsh#^N$DrdKZ-dkMB1?UP|!j{NcgB{uqcI;nCXywhhE70C_UOxAhx;Upwdo)ozHC
zPxl-Z&^f2Bh6g;lr>Lv|o$%WE$)neU5oCOU594i6>IFI3qxpb@hvmgu)z>Z_-5fsM
z5dvV5=7Wr2MIJ9ax&uCVSYG7skp~^L%D?`yXY&C@kK+z6KzB2EXkPZUJXU(t*YX;F
z%TG|GHrJ?RF!1-Kg3che{K(%25_C0u>)UxAl$0xcI$!v9KJ)Cn>#6zOr+W!B&JVw4
z_0;@c=MM^f<QVqp{OHq}f{0;{=EEp4?896Fis7FgmN6<BrF(okzkp-7M5W^8lYjsJ
z`*gnc?fech6qK|;@dC<9piuSz=ck{b5HtYEgDeGcH2z;TJmArI1eD*S<Kkl-V;o~0
z;~e7;`*h~0D1db$Wk$mTuP;MV)$3V4ohM!&^X)wJ^5eh%|6L6)y?pua|9{`k=dT;^
z79~qiiV}~`%RZfFL3sh}pzb};@<apVMsODGHt_5Ql_Ma>diZL-^R;}&-@6%F20(lX
zN;RD~eY$&8z&W?GMnwY@^a`M)49U3Q@+L&Z<NtNv&WEVQ$x^6M;Nqk^L?yt7fBhDS
zLA@%_BH#h22mqIa%v)3-CgLnyzy%Q4<yZ=rUY56@MC8c`E^I11yP14Cr$7poP8XE`
z&(1@j@&=R-JbXL9LP{1-%|kwnmm!7AEKrsM6)pv!91Ja7mcR;^7O=BDJMZ{(o&^OL
ztXT2s{OsHL4pa_+!V4sm@S4*@^DBSf0wz!vhJ>4M=Let8hoERT02MMCkfc|lq5!%l
z(c}MhALbO50C4*A?0o5A9ix&^y4$DoF(^%giWlF`udqUziND1k<UUwg(T!HJbVJHf
zP~lSGfhb`fVl81jx^wWCFb{oTCCmkA3FCpIgn5Hr!hG=HUk?d1P@v!{W+u?Mm;oQ~
zjIWqs0yzM^m;nhIz6IAVB`OuZoo78e-}!Vt1w{uamO<sq*E&yFrtpMT9w{o2$n^x*
z9EivT6{-Oq%sHUK<)x2hiAqN4e$UP~KHZ>_1(d-(JKut`B*<uRvEtkL0-Q=<7I<{t
z1g8^FKpOnNj=fAlm{6ml0j|taKxGUh{lRl<cZiAy+?dzfeL5fec7A=`2r6$@fy$c~
z(DLR1xV(A#GUfmO|Bk4wmmSbd4QjQ3LL>oH`*-%JFo5aHzMaRQr4FcB;L{B*Z9okf
zk8TT3XzdPiYXw;OKOfC^K9<iwPI3T=W`IRqR4n*=%|OiV78Ou_2ZaQv5CMfmX9+Z%
zL7oB?9H6iX0GXihe~L;03j>31=R;3Ovj*fQM*bF%5g^k+<)CNhCm;UxIpDHriVE0J
zaMK0aoMCPOm!Uq)Q^3tLPf+s*(%OMk<Smd&hItFbU8uzv*qfa#kTL`0S4dIh0WX@4
zftpRAR*`2nn@{H!aK-D}c@5<F2p`QCo}E{Hv^BxaoxhCyeTTp$(s};gOQ0Oz`NLE5
zr%&e+aQzF;Tp-7T!+MJfBs5)AKvlaZ|N7$~6Ei$}UH^k?%Qv2#Uwt6f6o5*nzx;hd
z&{zZoIH+7w@a+766w077-oXRZ9s;LC&*mfGs?q`+*3e)ErRxX}<`R_z&(4>iHd2O<
zb&5(s>3mSC05uXkJHPpKz5|t9pm<>7Z&?BINB0zPQUS#tsBH7-?tv82(8h)bGo(ZV
zRSTey^6Aa`=gauOxAkpZ6sUy+GRmWO3b;W6Y9oWybo!_yKpII?zzr=z?IiS4ECJMz
zsQ?#Y5zt0b0i==C0!bpBE-DE=;8qhPXhE$eP?HE0pWtRNbBs!XZ|htBKJZ!g-7R4E
zff`Pr>(8JKrybyi(<?~B36kEx&7vN#VsJ~z@>Ct+wo@9ew$lqx+vzHQivzS!t6<>o
zO9Ho@e)9MAf=;RjrJyz7b~&gO^%c}y?uMiuP@(px4%|iur3r8|7*r5-_drA7CR&>C
zXg-P~O@Puuf^X+TP}<1wu*^}ZC|wM#BtfzD@;tb3c?ZgopmYl=^9;Z>B)H@P6`YV3
z2Pl1m6C5ZtqZSX)BnU1FK?M>@^9p1zD9b}zd*F7x1}t%d(jC@P!|=fCO^_7(5)@{j
zB5@I@NL&Ri5*PhLD+-(6WPEdUWc28ERPgLP<Jo!fxQj{*s0rfHEy3S95p*v|w~LB}
zV|Sp0XSb&U$eRH^oh~XKzTGt{0{q)5q&>PF96Y)kKuM(eIio{Ijfw@>tDfC1DjGiB
z1}{{OfZ7l)DjuGlM;*HZBs{x46khNjVPNpIJnGZ!qT&H+L<aEp*Dx|L__n_F>^#KZ
zQUJQN@0(}yUq;XFOaagC3V{+~$L2~2M*bEVu$uxcJd%qPTn*oPH2+`($yI>lzJL-{
zw}XXGa)v@fjfw>We+%dq1y{q{zMy+_T0mt{w=083=Pi%#w>&K`)TsMd9<EdJ?DhI@
zc;GcFNJP|w@vDdB!IEenkizBzj6Rl!>!10y-YyaH0rjq2R4iV6%3)&wx!l5|o3-fx
z4}(W%jEaIsuc(y(CxhcoMo^=_o8yH}E*ry+|NsC0_h>$nffBcf(2P;>0D15Q!(j#n
zu!DWNV^lm!Yq~>JVp=bilz4WBs91CdDK!6L;&0JoWMJU$TfoS`(EN*qza<9D;3)Nn
zU8SVu0djILj|517-{YW1H@`>oD@IRHFNyK15952#okO0TJnW^{K>p$I>Ad+uJ%^3K
z@W9K+|DdM%tCt<13r1QGl-vhp9Sfh%7*I|7&ZG0LN9SRWZaz?c=yp+Y@aPrM^Z+eS
z^f(177CL`<@~=PV!}#8Z@#p^wpd4f20lK{EEZ8@%Cn5X`YCd=RsCc~KKg7V`VGD{c
zQ0#kvI)(xKeZk-^ijPWwPiKgV$BU+HP&oU5+P#NCDm-4A{`>#m@POkt2S-N!sRue;
zRAOGnfNuQgcF^$Y)_BPQy6>brP{X6!=;edI|NnymqBr0_e+v&N8c;)re>;}YNpl1R
z&()WAAmISI@`=9%l-1FK7F)=IwO)U@@ZbOc&A%A=Tel#a(GB9DIba(W2RL?sqUU7{
zdOmG@bApM1p}X+`3j>2occOqt=XsCrnF_3+L70site_mWQiF+sp|eE=l*&E28xJru
zFu1lp0p-PjItRyI7nT1$y)7!BeCpBLqjCUp73fjWWnJJdG5Z7X$c+etNB0!=15BXN
z91%v3<^vp_mIq7kyBdCT{O0P&$luBUs&t#{B^dZyYC%PGcfSG16`-4|xIt3g?Jq!$
z9(e7x-2o)sz1{;v9fyn^fD4%8E#Nv6%m(M#3WXOM(-;{%ASQsyxD5;p3@)7?K^=Bb
zz2npEVF9YNKt4R~qM`xT+6hjN5VJs@1*-rR(IAe2XSXZ3I8u0FJN?)H<{ymwt)Tw5
z2gKDcET%Iucy=Cxj@U$abhlf8f;m9K15`+5?Pp+cZ2kkTArkmoBA6K%x~D+G_qdBn
z1;~0(vBJv4zyJ+j9dLMp+z4(Kbh@ZyfH>e`g-#ch0#Jl>`=|ue)frv_#|9$<!)rlL
z{`D*Z9?ge1JQxppT3#(l^yp?02Dz#AK;>f(<`xl9q`kfgs^1GdS`U<Pcyu0ok(&X^
zxgL#2KnVk-czH1^gN*^C&J|RNfSY`+2TE8yIuHIA02fHFPl9Ts1P{v)l?eXUHK6jU
zlh32OT>unCpeCOiM>ixLwH_$l2s6Z|+n2+q+l>R<n1Ti_8;Dl$=niG@=;r%B1zagZ
z!}kAl3swe()&r&cJ-YiDSQ!}pPv-!e-w(RD=KpjFuq=NoXjA~?vkH)l!9JUu&ITS@
zgu0x+MHG~KL9Tzv4PrqZ+SvncdU_m(v{gZ|0ks-bHfMmmSO5yd&K7WM^TnJ~j0~*@
z_*)ghX1J&zEK~wp$ohX54=C|NTfQ7Gw86sAlm*fWx;W@1h=3+hSHo|hlE{&N>amwE
z|NQ^|;$j*b11Ll)UcLdBO0E_l7lCsLypjaTN4(fSg%LSvxv-!ltpbo|KuOC3mb5%N
z_oxVfhCq95z)8$A`3Pu4v-J|lxD4OUfBdb>K=IfOYCd;sc(lGP$u;~BPi_vN<TeGI
z>0e8NlADkZGmDr{CyOvV*<C9U^XX<026b;*4^-avfF-+&9^Ex689u!>)~<#Jd^=x)
z;wr+kTm1h8k8Tk=PeyT%=C_QclR>Ej<Uo(^4siTVfW~i&+u#5Hp}7X+qp1J?|G)T|
z3QnN>Ek6JM|9_eB_y2zvXo7P!eB#=AfWPGvs3?Js>iP6SheyHLshb%TsjUb2JLEtC
z3+kYQ$}&)NCx8YE0-(tn)Oh#kWJ62VJ>cxyda|?<<X}(=qfxRB0oACjPxxDm{(^?x
z9=_O{!p87Y_3!`xFMg*$eP0RkeZ-&t|3NKqa2Wwf+MtnK%v25XVFt+WumpYjI3z)<
z!>qD^S``GcN*h%FF+&RcmskJ&|KAy+lJP<xWH+cJf`&IJS*x&vYKm|CEz;}^44?wD
z+d%<z)KH598v{dkh)M>3Um7a|Lo?{Ai<1nnvaY*EB>>d@Pw-8C<IxK#_&g6jW%lf5
zgI&v*W_Zc9^@(rik2*WU13u772b}&y7(JMI*gQIUn87s+;{^}Pqa|V<-8{@5-GUyi
zmq6)n3JbW{yXe#T%A=P@7<9j*M>nHOH-`r^i<oEgum7%{93GvFrL&-U3|^$PT>b@0
zP>_<^6_n^QK#8s;85-=MB>3|4umAs>e{k@(&i(WMKcw`gwvS#A=OdqP4&P3=r?C5o
z5$q#K;&la8wO}7@N<#LLB3R85a02%@?xK<bDnwjCNf31R7AUF$e7b8?B3xUal$L;U
zae@b=pz!hN4(0&$cR~5+wWbF%A0(%H@~=PQ(aG)E%fsgQ|GGza7>5UQFb62RdvpeK
zl!$tCb9;0%dbA#>JOk?Jf@A9tT4a<+x^zRF^t$~86U4nGO)pD-{{IhhLWTz@0qXwz
z|No`I&;S2lOh{y7@a#PDk`YvzHYY+#(+s4vdYTEERu6%@0j?IXw7LY`IOb)7q|=rM
z3?K&RSRrs}4;m`zPEkql>}F8`r%s3eC7uv(&jFW;9^KrajycE=9^H(7y*vUQtp_~$
zJr4SGb9pwu05zfydoc6)bo#I|crb@?csBp|UwYM}lN%HiXny8z0aY<@N0)TH-~{=k
z^*~9(%bFkm|NHQ-zv|H)qY~l6zy7Q*<8@!gb3UEcKApuJ7zW+=_y0e_Aifs|5+E_&
zYVrdTfY3Pf>2>{Ia?q!{n8T;r+Nax(!>4-<*k3-~V&Iqs^?X262fsjll?ab+CXfRH
z{CZ^+ApSh;(k%(~=TRTVlRk`>Kt6QolwmHt^wRr3Nsd-Vb2K;1(e>Y{?P&h(SX`Y3
zcJ_srp8r8v9Moh56@}f{(f~B+Luy7)?;4T-K<V1ASB3)`HXh7;(6Bk=(aFufO{gP;
zl>wF?K;Z;R1f?f1VowTG^}!laCG9Vm;vuou0xtLqzy1I3*m(qzF<&PAfjXG;2d&B^
z{G}`lw3OxG-^S_K!Qs&@BIdy;04i&-l(M;Bk<uoAOBSe%RfvQ7Fa}h$^?xP78yU2y
zEcmy>3)VDfbuj}YnwES4RTp!>1*dE4ZT^-tkXJ%up<amqdF9BL|NlD=y(|F58S+pv
z%J|7C&(4d!oyU*4s8}#~bX)MZ?g1B4P8P5Zuy1#f0H|vl02)VeaN*zPfINKS*!+Oe
zrNc!f9@M5Y@a%Td@adKS_rYI0*u=o#*c~q6+3m03*?IKEg-y`m6CV`^a3>qoJq~c;
z-{ztc&)*Na@6osQtw-lk{uV7p1_oEdCy=3(NCD68a>P&ysITMM9cbZ`oP<1-QV$wR
z5db^g9Xyoc3c6-;9%xAB0EpRoj{!Pb!QTS9fY`G;2tGy;%>){wI0!0+L1Pr4TQZw}
zflgruHBMXK^0$C)fc5FN_U!!O`Td5k<&S!2AItxBcA#3t@X~8m5XaE7m&e|>^}i3l
z$4?)|$G-gQe|vZH*m-pF`7plou)NCO@(Wa)bz6gO+V-_PUV94Ob%=-tbsbpWt^*Cq
z)PM(Nmj2^_4$Am;{@4v3kLl)k(I3sm&<VQp9(82Kr}OR0bD*v|$f;AHwsijV_<qv^
zG;9HK-DDrjpY?qny}thq-}-d^0>xE;XXkrRJUMuD{spPC@aeq%n$^SdYMs4DFOQZ-
z>m|?5pP=f_z=Pl8B6!5)qX+-`5ETa>#>YO4?|c|P{lDO2U87=ABInU9?Ad&r(Zf1K
z#iMo)NK=4E=X=l2>o3K@HJOV_fZ=UWt=VD=;&&c=krKtm@X`P@#{nOt3sDIGB_t29
zqh2iDfEa6uQ2`}8@St0WN&tVK*1!M%Ur0r<F(49<2Pi=~yc7ZrL4dk9{8L?2EMA&|
zJ2dX#VHQZ|CQ!qtTj}KyP}vF!El{RGj#&QwG|*^{<$wM@(CxI)2<G&)JkH<a0~)8n
zh-Bw(9y>%Fi-9T~NF4iE{;xm&QXCd9e?aEKl8_I`f<J%%{|6iV8RVMgw~U6DUPEkp
z1adZ}P5j$=?9vc+frdwY5Oy7Xx%w}35C?1^$a|o>cu~FA4r*<KY_CJNG#7`Z+j#6c
z;Az+l;tNn32Kn#UOY^^IW3#AZKA8fZo#%YIcOs4Xcy!OiHs<pdoF=;)9YEtjE-D#y
z_Kv--cm{twyQi?h27f?ojKLqnx8IyWLqD9L5u)Zg(9jP*xOnJ;5B&&(`fJ_J7O+_j
z&+cuYaUaj_efY+Ge3BCsUYN8nGJpn2K%+W7-QE_kksZ(g5NOl~H2SlFfq|j(CCFb6
zAf=#w8;FBG*3$+adg^w74*7VsLWg_~g2#oyu6^O!%E;i+c@*4{a#4x!>}~@UgWb>}
zpYpY!A)mjnA)i9fkPoB=2Q{f7Lp}%iTSUSAa@YSJy)xkLILJ}BMtt6ah9d&%j14cr
z#@${EdhoAj5d?L;JsA&pSl%iT^Xz632RR9S#K%V^!NbxAG)%(+8nEkR^XzVe4AXFU
zboz0;X7}l4^XT^Dfc0iQy2Cj@QwAEK;4uJ?T6VgC=1}>eqcfh};9zk4KMguOv(K};
z4>UaE_<tH`d<G=X$iU$Ee;Tv{-)aRaXS$KcOFo5yN?G{8NC{+U2|SO1F&G6JJ&5pV
z{a+&F(fQK{w20xw=1@>^<DwD(y7@K()IsYg0G);cT2SKA&1$fchry-W2Q+df`r-!%
zgGV>ViwB|5vGmuop#k9230c>JJp2Q4J9sD*H0;(LqJlE~Gj|81w|p8@jG%Z&8SEWa
zhLxzpKRRGxxG(uzszCt(9)>Ce%|~^EQ=8#iP#NjKKlSL#hoDZ&xe!RFrQ+osP_fYM
zYyol=Xrux$PXdaYgcp07Ktn)(89h6X@V9Ja1&!-MI(VRz2JO6^gv>XB^KWO0N&#rT
z6+FrU>u@I@1q}m%42<yXd;_X33Ou?kK;d2Q)A_)&^NUC4F~hg6t#3i22LW{sX#H>=
zMqg$Y7T-=5c2GaugYlGy<%be6-)<Im&u$Kn){~%qcn`E64q9jt;oEDX?`n9!6EvIe
z0_sok{lDPZEu!PeDCW`p9yAUFS|#$#v-1cjMS`7*HXzg*4hqI@P!xd%dX9lYsq^5A
zdBLFJ%$GYsO=d_i7~TeTbiF`9hh-qBz_Xhj)?oMPX7K4e;qm>3r{w|u9#zmhlI02h
zUKtRB@t|+(0grAUl>}c<Zw@wG1X^1X0L@wbpn85Fa+W11BtQ+$_24m}n=fVtu`#?{
z^ymM7v_y_JAOuQL;GtBsB))4aB#Ar0%vA#i?#&mDAaf-_V^8`)pyYY@<w{U4XuVw`
z172m}qY?qhni4_KtO=Txi2#lLv|i%x;0F!pce74k%EJI^xPqp-{J(NQGif)+3n!5A
z7eT52LLeIhY$y+uC^JBVd9Aj8|NjTop`bQ|N4GP)&z=YFvxCZb(AZK7JE+wN8j|4!
z)r7sS|3N7(z%%);$HC{!u#y(ugAe#$0v=y_>)H7N$M_Oxt_zf|JwfA3H$a6f4?E`g
z5@?-dFORryHv@Et$)}S6HpB!TjR6HWYLQqD>JorP+rSeFao`ao!p=<x^>C=;To!Rx
z{%uhAa=3IbBKOp0V!F2s<lYV<oeA!UQOB7);;#JLq0VGXb3qN)8JO-Y1-bLVZ&0t1
zaBxyJ_FdtzkLJo*n63oJzSVDd@7M4@s32nn6;z!yDiI!?_kFu{R6q+US{8xUD|Cy4
z)_8zM7JRyyJUU-^e81sid6d8JA!sbf@&JGT4e($NWFX43+n>X;`7I-8oTk9=_G=l>
zZgJ2`JD+YQu%<OIO^bj0|L@z&qX8=3IzhEFXy_kQ#(6M{d3OHv>=gIuJOt`%fI1ol
z9?T&s0iYp!KMqf3e-2N}yP&$F!n4z#qjWB&7p*}h2xzd-qxC<3ixS9voj+gv@&%XC
zq9ATJYsW$!29I9R+K-Sb+SZSa;pLeh|Np-@?F%Xd)`0ud9-YTsTi^1xKKchK0&aoI
z9i$@QGPnrn2j_ei{?_B*@Dfq+0FByC26NaEfydz4`O@?IO<&7{{QWDx|NjpTkOkmD
zB|gwhw{Leihev0KN`yyu9Eag0@X8fXtT3Jc^~w@ni}`djfZE%jX@Ue_%M&&Jo|Z3a
zy?lFhz@Z45nDgcLIO^GX)R%w#VYhA;M%PXzPsUrI&R9h0A<s^B-_CFj%+T@zCEH8j
z1tIz%6)$<dg9dUq_*-9tdIH@%DjuyTOKLs4#lgdJpz5ZZ$+z>h=l9#bpoGu_T2o_r
zqo&rg+nvLs8<G$_nqM-y8lHSD1X_sT*?f@E*YZY9h_B_*I)DFO5s-s@`8^JSyKNrK
zVm|!q4|{Z8_3vh30vBIy96pvOJv$GT9`x)K_w01X;%d;cxR)}Zo>(W?)u2WLqLIeu
z1FZ>Mx?@x_K*J&(*T5~%92JF^Vc-7$#}yhaC&7LO$6?7s&u+~414rA-ub?j5LH_;+
zUqOR{M8%&Ra{Pf!0ZprelS30I^l`)^|8^F}G~}4v@zNfgzFCjX11I5K?>In73)Ijo
z_hw^wIq54X`WX3JbwKqpXyDKj8iyrd|I7i;qWgfB9pCZ<EhM>7Tjpzdp{CHM*Ym$8
zs09v<L&KA=ML;@0Ysb48JS}h3`hnDW`u6Hb__iJZB{mOcHc(>o>|}T1-{!)~(7^;6
zSoCBLheTjFM=7X*4w_O!YLe%I5?mt4aVQPzC@*N7b(g4Qw0^7L0u>?(FIRj4g)r-l
zxnR$peGBsJO^|21yx16CE``YMg2=9a%fSGi<l}ge1Cnk3^8fz?2nhCQexu+4+SJhr
z>UDyWG?z!SCL@2#B+%eaceep((Ln3T5~%1Nh$yIcg`{>GMDzuyNzr<;gbiduNr^{y
z_XiY_Adl{Dkf%X9SziPm0WAyYhW0i~SYJ3m1VH^3hzfm>K<7=5<|7KxFQYuz7}6$q
zbUSkV4=?~PgyNTXV1V*pFXfj9t#*U+n^E~M<Np8ukEH&k1&rVPMx)zNqV)i1=EG3|
z)LUylqH#ElUmnzR1uev2-8u&x#7%D@MdB+DHU^L52S8&^uP;vs4}*r_b)U{-FUml2
ztp_|h50{8|fQFF{zL@L=YMZfnG;1@K2!VYP7k@ZS4`IGD2WahRw}Syx(&PVw2?%+R
z=>~?EATb0AyBAVR!NCR#B{9QGFWA9C&5$l6c&=Kb+gZS;yBV}xr1b!(6{t|>>d`$J
zG|bTag3+V58#FZF)9Z7H<F%{@|N2JIs#;Lb)uZ_!hbQ9!Ps@v7O(g>0Nd?flgUTBo
z%#5!ugJKZW8|!So02&-<Jz1jZ(Ho+o;A(i_g}`dC%RmwOVoNEA&EV158~|$6HXkvF
zJ`B>!$iVPo1{OJ3ctFC_z@s}-z_s<HPv-%b&hs9fQv7|OF-f0pM+M(*37>8U4&Tn3
z;7a2Jf6rl1;%h#@;c9rv)$k;!K=paKo`HdZU)}|@f`-ATJ5s~3`5>b||9Tc-AI8Hj
zmS7WG8o@=jqk<=BjYjhU3IA>x0dS||p2zolo|YeKgnca!*YWwb9;n>u%Xq`5li~H2
z39hXtE3`ejSrcY~n$3_EVhyh$DMP>=+Mo3Rc{eWpFuy#5M>nhKEO7dn^cs{2!CCaV
z8ymyxt6=vT9)KwZRSU}|pe$)_ev{$Zd1fak0|Ud0&pqG&dvqRt;S5esM;*IeR0LWN
z@b_tfhHrXXR6yfGpgyJtXo3*7-p{A=IjF(z0398F(U%8`6(1E3k8TqVP+P&lr+W!M
zC@pk{Nw{<yfR;G*Wim1_bh|mM0Nu<9T8;LA2|RBc1gdmf--6buynJ!g6_lz!f{P-@
zoy?&5;~h*43=F$C*rXU<Tz|_5N-`du$M{>mGchoL((l0+iAhjV7nK11mRq1$>-_kF
zJDZUKG!nfSr0%Up=SSbpr!T^CLBly8L2ftj{C@XETLFmg0$POl@kL}Y$P=KBEPu;W
zkfXZ68$B3&x-EPy|MK@&F)=XsTK?hhD+Co?ptW|OTGywW%kYv9<B8X-zLxK6q&+N8
zd3GM=Z<zzC{<<wd4G15`6TX&z>K}l@#lWTWyKm<+pH2zTq6-d>&X+GPxv(*`{^#!i
zE!gwuW{sZ#N&uiGp}nH@FF6<-JAe9i{s0xgoS?92)@I~y(FD1!^W%&3{fsyk4Nmar
zcC%=%P~hNiUGVS!|Aq>QO#aqs|Nj5~=H|%A-_ipXld|J)0ab+_pzhXnkeS_n3NIGT
zVqoYFlW;XW*?Or&5EOGQ>%nqi7Cy;dpcz2^miM4Q?hX_1?R@O{{kBgxldt8GIt^dT
z!}ZD@%`X@YPkLA$<Zn3%$_R|7Jirwi6DR|*`dS{Tf9%ov77`4gVV;+u0>R+L8D~gs
zWB>|^Xs~^(A=42-QSt&D6rgZmbYWw7`48*@R>SGwJka+7lm|XS1L}b@8w03Z<ZrzW
zX+VNXLQvs;;vcB6hL-0cpnXwH9-swdE}+&fXm0r{s0$2Bi<Tf`IzJk|eer)UBSW)`
zN(`e%vx|xcN4JYg42b2xV(l)#-}4<@wL%jx3rJHpGiWWK;Q<fOiW^~m(2dIfLG#C*
zpaj)<^M8;5C~3WP13L#=A9Q|v(UHLjUFOK&=Lzb6uXh6FhNCa-Kx<yW3FqZekPAU&
zJ{Nd#)=MT7A40_5fz)(|Y4~(=z4QeQ*{3_Pfuhu-^XN-SuzJ>?Q^DaD_8c5;pio`y
z#K!P?HN1X8DK8q|bbz<^RD#M*572g?DJnO>b2nVfpcNjD|2=ynI1IlT{`cw4QK|6g
zWpVKBEjggz(F+>50WAOqu@XSpE&#+T0I?!on}RyTElHrV;0IHwt4H#2&|JpxmLuR8
z0!1*0&B(w2UL@OmSi;ltUWrz>GY5D8AfJ(ep>8i|RYnV_RJH{T^OoH7Xg(~_e2mf4
z@?PmRkM2;5?iQ5~pzPYr#0ctl2{VC4&RiWlx_P5gIT;KOfLsC|7zWu1T6F?i0_*~c
zD96qp@WpEiFKj;j`0vrZ1?+7PP)*EMqVLh{%E0K+`3khaZqMqk{|zs-9^mhs1x~yz
z5S85=pe74{%N0fjhFzel{be<%4<pau(=F}WdYivb6*O^?e9Wy^M85Nv=fMZepk-4B
zeVAPpe3*ST5cRchw+f?2@~P%Sj6R)9&VU^2+pWR?8n1A%yaX0vWMC-0>Dm06(W$pa
zp3$kdM2_+0@qhpSr-ADOk8W25kK}7U-OL`{EEhoAS-;=(v^>Gza{`n}Ef4Vb?FaQM
zS`SpRc`_dG>16ikcGYM;#^}Spp5=ls<MEd@;DqC<;FJ8!qucujXvoLIr`ts(z^hvX
zT(m{_bmoBe;kc+Myf_!|2h`2&*aC{gZXeL<xs!F)pixEezJmfEh~fU-EDt>S*I)4D
zUw^=p@w!Lybx;E6Y`FsRpGRlU6;NbAk~nM$C8#O_t@mayJPBeZfNG^3p!8vQ>Geub
zWGZ-cvr10}r*4NQpfcklD0QE;XM==)=LL_(BcRlbvIx?p8<Zq`IXpUFynF@9d9C)4
z`P^1_u(w%HP6C@4@B~sL+u5@*ywm|pft!ussC~WI@c+w>zn~(<fdOgrvj?~;(DLX!
z+wH00)9a(+;L&;6weyH$cdZ0ygv_ARN5#VOCx1%?BLhS0|2lKuZdZj~_x~Qr*FC;p
z@a>hk;E{Y0G;r(ND{|5B5+pu-yIq8T_;$Jo{qSgh#o=LjsPt{;3Bya8KUxpe3G>S{
zcphf~?aKi7U@b4yfAHunQ891?mk&OjFFiUxy|`7y#NgRo%iz%){vSN)7|Ouk!U{^f
zpybWW-*Sn8fuXxr!=v+{OLy-L(A-Ar3CJ>G*UnQe{4N(984tQzp5pI)$-uzi+8YTT
zfip0?<e7ZPRr9iE^I=AxUKRnLPM51-S9n@pE`8_PdBRomf@|xgIyq2kFz`%1;L*!+
z$ncU!r^p3RW$9>nss6Jo;{`{{pS8L!ohQJme3K7+zu=pElJSRMugD>f<^zm|mwbC!
z1bsVME`c<8SY9Z75AxHq1||m3LL<;3T}DtD3@(8MOWC2#d5=zGkH#aQ2!TcaVQ70E
z6eyq|dMN;Iz%zJuhjM_DlZH>{%l|<Jpt@V*C1_m2)$qVe8?YJ|1_ng_L@O_MfchuR
zwyh?hL(xH7#XybK&M7LONfXdy1gJ^v)7hf}nl|BYnZpa}5VU}0J-TIkrhw)aJUBco
zZ}PWjfpl8){+PhSz~3SZ;&huzgGz795Bx2>peA#->gmZm3_g|*`CI;itnId~PvB(m
z0Hvt6Ab#hs7uzh@K&x3>rh%N(4YSCD<5-KzY)}sJu)OKhy#;LlaTk>wP=4ZXxdNJI
zfhs=kq7nfTHN1ViMP&{H0|TfmJMN+aUVD1nMWqB}3OtWCACNfiqEZ7A1BGFNM>p%6
zcuoe;!bQ+pYfyiw^)`QN3~1+C>o@+EV9*wMYg3acAU{S!IObrECo5=?p&y5bHSe=Y
zAldEgke~u}Q@RTzK)TyNp0wt@)(?^gPat+f7LI#Z9`xuuR-)<AdFaI!b4Un)R=<0K
zrob#emI#27%xtK{Y|wJXW;RA2(2i$!i*5%QP=f%pC9k<gC5N#)T%uH_yGI4o328l9
zA_$tW0J*_3K!U&JEf)hr>m~k{5KaaL!;>!-G=Bf@YIqVfoCceoJno{RzzB*w(7^yd
zU+}U21Z_6}Pv(H?F^Et4e7P7He0ukQH%A#B@I1}}8sP#J@{E?p>OXjP`=}^%elmOu
zTH*>?u=?Wr1kl2J$kY~S2aSMFFK_X7b_UR5anK4;$nFx5m5_<47vJ>$fR~SgboaXb
z@BG*~2fTaC2h=3}?a|8uo}Y9C?d>`K+Sa3!Mcbp>LBQj9i_Qj6?1M`4&K8{wpdMPc
zn}SC-iw3B<=K&G}SF%SrJT2ezx9kVSNH_0~SWX5|A?*N42#(<H#&OVU7X}7~<1Q)&
zAW`sK1#EFXD3CycyFhlmi2CpY6h{25pmAOo(Dc-O&(1I15C?<isa|t{He^}8tCREW
z=6Mh5*}n%>wxusYnH?ncKfu89UHv1^W*rsAQf^QHaexki2r%$y)@S5z?PO+P*au3-
z9><S@DbRRY=g<EE2Cd)tJF-EZOg`+<E281i{L7xdzmAQ8q1i{JK)|E*ZC$!gx4(i%
z_Z}5cMh3Nae4slXVbSN&8**I0@Bq9$<=M@{c$`T96oSo%Bs@C39(Z>1K<3dpy+Bh@
zrFXksR7yY#A9`c78GBtc7&~25O1f)QD!|oS>wkXN<J~nXIhHjl5ug!V{+@rJvbwuP
z1(XcCOH@j_9V9G|@%QGlGca`5s1!JSJI=x163E5Cp!osRasj!t`MHBf@(GV*NFHYN
zQK<pB-J{dz7)R&N){`Z|-7YExD+Ksk%(xjCnqN48*Z!8M)G(K*RD5$$DG=gsF=J<7
zX#S_b->=NgzyO+#Qe|gg=nei4$`BwcV1eRlcoH<E3UZuBuSgK6rQ*@+b6w%J5x6}9
zTIbWUj0?0oiK#@W@fWD|R%(qXPa%5)5AwGh11&2K;As9OP<q;<Tfn3BQk{rzcd&wQ
z@<IP@mP0<4hxl8?xk2;r2N_?VgcWEnwSI$!u|RtmyA6D-O>cq<ht{RP|NjSh19XK6
zD2XN?hPk$L4!BeUg$5{&IY0*`^s*d3?jQi#^5Ox`hYTLa9Y8#W*Of0)%^~fB7SIm-
z7wzV34B$eg+mt1mli}t3-~azNzhG?s!O7p=0g4WH32@^RZ0BWoWPlS>uSig{i%JQj
zN3X~=k4`I4gdcYj04J2=P8^_gX?dLA_jvPRP<p6<r2zh3P{Y63MI{2<CrRLF{_Viu
zxBM5#)2uRG;Ks_u+mOb}L^C#qm!RUn1L0qgCz-&$by2BdMEDle*M|D`^<<yUk1tA&
z{P^$D{Nq2k&&>*2Bk7}3zz7RAkL1G;y$&9|EXSc5Jvs|Gjyni|GBMa^FWn*Ir>&h}
zXIVj=^~;nEss3!eU1AP1)$rSEZqSbM=Hn8U_i7bDJJVWEmb?XL?&qM)4V47t?|U^5
z8umacu@dmcYfudf8Wo4o;6bYha3KY4)g&-8K>N&%M?keStRVnCrUH@vTsj{>iyF_)
zFQDcGWM2q)E!785E{1L11#e5^@0SJ@?yUzv3k*PwS5Ps=-v>%Iy>9<OYg0h!+tu*4
zPp=5Li1q9|?vwn&xxq$)p~SfLTb({=wFkId?Ome+Dr-TztV9@ndc8P&I(Zm<x<M<6
zn-6gKSYGhy<SKpa+WNo3)vLSb4M?q*b<dj(ObiS)RW6`D%d6MoX%jq>FL-qKTmeaY
zSod53OUHqR=#IC51wjr3txCQQZl_t#0q>6C?*XmL1m$FqAK>fc3{2P<z=bG(iy^p}
z*Jt!de#hT>_1FLZFOU5KHFz07>+YKmG9sG>YQTf+=kF2u|NsB%6==zi1(f_eo7osa
zNyn$t;J5?mEDTUTyM(bBnkrxNfSc1UpjC;W`qc0es6GL2<$_ffphUX=Ke(#!=seEf
zvia}-|FHEr*E<<N<3;=}$B~Lkm+lA&&<sTjWM&Fh)wh857(+5`nVw6xzl0;W+y$+l
zZw2ky_2}l^p#@IBGjDP*yf85aw<kI_F*7iLYql4wD!>1C+yTzGpc?n*i=R)yuHtWz
zWdpTY%sqO;Kn-n=PI3O0kD%J6^Z3h&p!ulIpD%b1g0h)DBRHFZCb&GB|NZB0dBY5;
za~xlGfd(16SsmNJPWW~mlC`%Pfr_EG{C#^t(!E>2EeDTYn|H5yJ(`bkcvybtZvm|k
z@aX0P=bl%f-19%c;Ppd~Zr+!gV6#qL=U{;N^+mi9#8deo(_ocb@?lUzrkBOR@RH$4
zP`Sb4(Q9)2xEnaOUcAu*x!{0DCmVmO<G=s^UmAn;f(M^LLoO4+>l0j5pf&Hy{ot_)
z*34G0-Rt0XgF0ys3?bH+fII2o5}?ICt@A;>tX|P8*Etwo`Y^!)+qMENuzQ|>%P5a-
zc6hU2oWJE6D7k{#h;u>JLFf0EilDiuZZ`ps<{u9H{nwa43F}+yfle2d9R7ZO@Z=J-
zLUjNY+5I^z;I<05DGO`v8s0{4@LIa4l<@aUf+l%gRB}M=#&e*JfzXN*qz_aWg7Oup
zy$>s|Iwe3NprP~b7?p}n@IgAD=4qz{s21jLi3Yj3dk(l&?$Isn0jgv>V?gtjP%-G}
zk}+6aFh{2gXgV1>x)kwJ1}yBM(D~`b`8LdUqW4;M-0j43Du{OCOAfF>?i?QAw$aNZ
za18n@yr=}5dJN<VP%RJ3bV(p#%VYd4lR@LX;Sw(&efj_Y#S?wdnA{$4F$3-hfJzwt
z{(GPzq#JBO57?tGKI?!I0mx8L3C`aV`WaNGIdFVySk1t|z{1~h9-Nn<s%v$i$q&+}
z;co%$Yk_HoHU=0yx;;2vN`C(T-_!CRe+y_Yh)1ue_BBuzV*Str>T7Yl$N{?#)GRCl
z?>2#ZHyOn3<xRQ5!SLceEU_QvZ}IsAI$TXO=n4k|X#9so7c^AII#rDaI`pUmlJAD+
z16eQ^G~*081_2b9pl&6Mcl>4B=l}m-@PeEHN<eRZ{QnQ$*y7R6>i{yeSM=jm4u%(d
z^gzMG-`N2QvtH4=S2-A7nu6<BxQn^L5yUD6@>#Fw>B}I0a=hr)V`F%E5i}VOY6WZo
zH(a50Hz<KBfa<hfmSe{q1i;Kr@EL62cy*8fwKuzcR0^6OI=s9FTF76cQs9w%*`?bB
z)PNKT0yR#4HlOG4IQWRU`JqE+jY@$ws4>et1#FE^@(CBl10KggjSGh3PT(e$Pp20s
z!PdNN17|vDbZ*lErIH`=o}EYe+k-!X_hj?8czyi;-|($x=ReQR`>%x|;~${*y{F|{
z{+207$-$%Z)r-j>BS3ZiVg8m+AWwCJI?_K&Tzxt}y;!FS3cXTGkItJfy0pM-UC_X+
zkL9Bh6%T9KO|3i(CDI<2pG(9*1IVQ_J;0;2uP3@NbG*#_3fi0Z!?W|gXEUgzKFr@*
z0-n8g=kS4Kja1M=;2M<zNB-7hU;h7p`3n?D-K;$g;KJ_Y74UGB;|_2DcXPb3&}CzI
z$^8BQ{}*l`Rx8MxCwGI23RlAehL=Fm0%~ufmo_g!Bl@8EABeF=pcL56@nV$@8^cRW
z&@$uB-!Hy`I6@ylNpz12s9oU$Uf9{oIt8S<GekvW*E&$(bpCvC3KU@7yqA@E7(jg}
zX-Hk*(fR8|05~i1cRK(6|NmwDH;`exF&8-)e0o`zf>ig4hFs)ecoFy*ltXzZfrLPd
z@Jzq`|NnZYPv`HK6W@c{2B4hIfHpqD0gAQG%b-)#0zk~}Ac1ag37>9n4VTViKHbg=
z$6HiDTa7`@lot*PkkSaW_6wA^!8&?-R6u-~YkO2cD{4JEPkMCoHu!Tgc!1XRHiL#|
z4}qEt79fLQolcMdxD5effFc82Ac00EUWDEO*V&*^ivs?ZI#4a$ya#L%1ApH%P;CMm
zTj-slasf0w)%nqJ2gtCUpwta&{(+Y6fNTS?L4&Ix_HoGRC=3it93IIP3ZT)Xg5xbJ
zpy5#l1||ld?gRn2$6&66HE=vS=cwEO$5jj1M$qbE&<bae8#P{}T!K%2W$?FvkK=)?
zhMl4U+ST@gB^)%V)uI9lGsBah)zKhf&(0s9g{UB-K%op9r2rWTUNQ}GH;4ls83%cY
zf9gRHA6!R)0t&=Y@a#PJLL>sZYI-F&aC}rU3@^Pn?*?~N1%JyQa0L6PWV|T%hs?<}
zg2EMLM}LV*hDYbe7vDla^Kl<R^O36q85w-Kt2sQnwL#-XphV=;`NOmGzeneB&<f3r
z7c0X-D!`3?kgRX(Tc2(NkM0N#{=Vf5;K{+}|BR(#FB6#<7$$&+2^oL;Sia(K0X0e+
ztQksPdum?w;9q~$lkpm8{Z-$5(597duQ@^EQy_UB4^T$~r0HGFd(cv>?kOsuknz;~
z3OY;>e1OYC=o|s~n8}x*^+X2HeI5~z({ql2f-2$v6v!$N(1ClPqt6mR7WRV<(g6Df
zlprepUjP;S3gE&VGF}63fv?j5t)T`5VaZ}he1hBol7_6Nh9{ox7|=Rq572m7l@BLF
zNe-y935t7A-wGUY-N6DL-Od`I)v%x(<I&8{2tK~UrQ6K`<a`bA`T`df1;``_xDouq
z?j|%_9OG|!2TqH(KvM{vpI;oA^c6hP4@sdnJQ|OHvNlSm3gp8A(B4mQ0|nFv0Ts`T
zh(TFUf_*W25jKw*-hRCjJYE2eCr|<gdEK+~C35g1@=6HksH|Vm;0D>8ffTl&?I$n6
z4N6dLhUp~!mWv?If!)Ksh>^kY_Dc;=bbuyZTS3dXJs=gj;cZaUmiIq+as@Jf2O2+a
ze)z|O@g`{0wrwtG#;%(gyr6X=s6Otz_nNJnt@S`Dr$_TK77xph<sUsdKY3{0^0d5K
z$KlcW`DGTUE<sI@eE<LdZ?IzkO^ttsw!0uH5S-{h2j{^&4ham8&d;DI1f@V|2)z6T
zZjOT|DZrue!gwJg!%Jn5ufX0E@j=WvW`Y*wTC0H?GLZE5G8wGf2b8A3n;Z~5X-59m
z1W?Po+mQnj8vp<P|Btl31g*UP0S;Fu3s2DGA!td9Yv(!WNHPOxnju04G$8z(g@M7f
z+d;w+G%?se4|L3dmxQCWuLOUqCur=XJ4nE%+h4<{+g;&>w$z{h-Qf}*pmDg)qc7f6
zgS&d3ok!}#9J@m$JiC1rUR(zW&h-2aIt=uMOShi{s5jSV1}c5J-4sAevOpHKsDh44
zusq7&+77nFO#`%A2b@?z$6Gal3pO|KW))CT=+T`g;EGb}`*f}W=Wfuk3!ud5(w(3H
zDq6u~E*Ql*ye<H>$z4=5K=lNuCIf}TamZLM0|N`k@fMXOARz`Oh8Oi`;N@unf6HoS
zaN*W@@I|^KT)cw6WiHrXpr%>p&lhX_K_%%=&~YW8=GcoEP&|WEJ+$J26{?=ycD~(p
z94~GMFfxD-Z2|4+_v!Yt0F7FJYB>JZ{h$!&odO;q>%56vStx*#n*(SY56A}~4mg+~
z)e~rfy*orD;>CwRa2)|ke+B%l&zTq)UgUa0YJy21qmj;e0i9F<Ik>?`rQpSJa2<eJ
z!Yd$`@SdO&Ui4)VsD=Seje^SRSNtviL0b+H1^jhS#w(!mwhvTv8Gd`s!7tAMFW-GY
zdcfuT51;N5Q15CAxV{IK@Sd7qJwYcEJ_MDJ;Nwd{yRg53{AmC!Cc*QW89t0(LB+hr
zf5<6qm?eAxQYi#0;laf*?0}XtN}v+H1!6V)02XkNy=a)r$j}WLvTZ$3BJkn`NNwu@
z{;3D}w;lKnDsw^E3#H7R;K9Eh<ZV#J0E!yWbZrFq*hbJf$VlxT7tq<s&{=wz^TD<v
zIXEBGuLmt#1?h_bCCZnN{(#!TFFlZoJkaV&7if`J4=Nfu@4e=SkALGY`}{!*OTlFy
z$kE`q0&Poxmwk{~SZKt6c7uSt0xSE#e)H*k2rK=-G2zh(ssum@@#WRO|Nk4_1}}V>
zdibR=s5I_obtnb5$+w<@^p0{Bp-Ze@t^+w8lu=&%1hrxy!+U)ZfB*k~p`ZvU8bJ~F
zG6-VMhZ3+ktWa}O;pTw$Grl-B8@fQ}WjNf}O|uypUcd6_X59+W+H?})gjWhMCuoD!
zvd)Fdp8|CoUV;Wl*x{yw&aUE@M;br%Xns@C4PI}U>d|_sA^?;|!NZ=tAu1L=y`W={
zX21f>5!_Zi?gDNUf=5UbKqo+e`Wi1-?*0GYdZ5Aq6#W(+%||LgOBTWF-5eD>wFO=;
zht8LR++Pg#de%{h`?VB6>%Cu}hV;)254=8@hEyMb)*A+Z&SdlGJY6F6!WUElH6ICx
zhRwf%9PJHqG}y5QptXM*(9_YtMGokIKZX}(H$WS!4G*+lsyOJ;9c%$gsT!W0H(tE0
zW@7L_F|XTE!9!c%^%|&qQR*Ym`Zv(nENEEHi34;xR_9gU&ST#jK=Wb@3=9(dE%U(@
zmZOD7w}-)t=knlD2L6^~pn|3sbS_yhc(CQ*izjhEK;e}Dnx_u%==SIEXl7yr9V2Pc
z?GBng0nZ#qcrd#QK$2y*J9x950%-oorQ2QN#pCnfrj=(WTZuHJG4=~Io{-ZCX;+zm
zmy0-nR;n}~LEV1r(RuO3QE5;omcQjM*txFoQIgg-Ac4-8FH)r07{J5#haEwqqoBG2
zG!=0cwDj+X9N1f)okvO*cqE^Gu|o>VKg!<%nga%{PicX)iPJo~9XOD~M;}yhce`7F
zPR9cU(Gi$g2cUz*ows~CAHHan1G}%|E@*W==ot1-KAkUL*h@h~uY(-fe2mf2@;iT@
z6ew&vKY^CSorgHYqw{cS`wJ~O_~>&uXdh{FE(2q!fM>TW2WV<OzyOloz$+VGf=<AI
z@I4_Tp8PGwAU(&~z@^r9@PaE)XMw?^mv`QA4u%(BB-t1|dVN46XRkmp6!C%yWO+BM
zd?9FH2)sRj<3*S(sB{LY0xe-~1r><Uk<^#TU^BskKBZh9koMvK00U3Zq$7XJRM1{h
zkc;_Stw3cQ+|`B$UV^eYynKYHZxsbAf)AG(9(c(LF@L8BD8|0s{t22BEm`Q%9d6O>
zrQp+<Vd2x6V9@EIz`rd>x+6duoCG^-R4lr~9Xi1^aJT>{TWNT7hiiZs;FRalc?g{N
z($2yXAAid%P=N;S4S*Bi>o!ON1g|yh=3OHU9v*-!{qyZ+^XL_wbc}=H1&ahY&G5G{
zf_&P|=h1BmT~OlDDahXf+Fs|`$@UVosmr6=8ZITw->LyB<vMSITGFy0W-l)<$iQTf
zfshEf1&NSMkVrRcUp`WVfYLoE^GAS&wfS2>XVySMuw^<Zr9ndc1bFNjmQG&o{Dah9
zN16?O8I2m~FK2>60=gdjAc)<|JMk!Z*khRxxX3Fz%E9m=>JoU^V=_pn^(24mbFe9p
zady~x6HiFOGd%Fp4(t|q#J+@d{lM+=m!PW7qdO41-oyjC*u>-IQP9dgU1`wC11}l=
zfCf?=kji_=dgcP~exB1Fo!5Lox!VVng?dFLK+c=p4~f6WpystRXfV44)JpIG&28TY
zpLYZ9_kpT(Q2&sjq!!dO!&zH^){=vcgoRfWx37aL3jU5}P#*5~0WG2Z^@6SK>wi$R
zSb%m>GV*tTPZ<N53-0liaDi7P7evR!ABJY1*KeWaGpN7^7yS<KQvZd=C6E;rDxh6}
zpkw2~OKw4DBRDwxp8%@bTMtyOh3W_A|JMuQ`N^X@SiwWv=q2bhI8cAyqnnjA7aV!J
z_Ce~aDoI#<3pySNTvvi!S-J)0w$&cptP&7SD-J_6xxzIW|NoEN-wB08NQ6h{Igifk
zKAlHjIDtwQ@Cel57il1N=f@Yv4F7=gFL;*c6eyvB4$=l^w=)i)6>}999?g1;{4IT;
zKn1Pxtnlb&)y)CBJL)iOo(9wu*doEkaPWt`NAr;gP{Z#qXhide1h`mjxdPS=GG{l4
z1zC*>4j}MyDB;qRpfS%*7Zn}I@MbrN1v3a5o`{m{WhKa`9^Gyn9-SZmgBDL{GxE2B
z_5;1Xg_th|*<S&+zqAh&mkyvp6&#@+FCrirxHKD!Ki-H#*8O^bDo_V-+IjIqoQ>h7
zE2xD4xAdhMh}#<iI!)9E(xCBp!2mH=7Gf?FO888{V(tQvxsM^`sYi3A1Vbt3XIT5=
z<?C}O@d;|L7(jPNfTni4q5BP9FoKRU?F92mtU%MjeFwpT+zdLwz@vLIWC4<p2cv*T
zH&hI?TLHYQ0knJ{+MWXIbOFtfI16}mPljx$0F}=gbt#|>)7=f481jLx$T2+dTE>Ha
z{S;>KX$#E<I6yn}G<+-%fOV7@d2~+(%^Z1ji!gaGiZFUWbbEAzm_ncv(hhkrPhkeF
z$A7&8Qa^fhPDVJ1U!LLrWXKMG{#Hna2Jff&KN&P%1!^xi{{R0Ued~utojZ=LAM$CS
z{s)fD9~w9}e}K}B257^Fd?jcs2)u*m#bIX<8x(}#4Ik)X`f@p_?tpCnK{$63LhwZs
z!~p2773jthkY74oR5V%-kh6aUix+$#8&_URfRmR412laZ9)QO8%WBm0h0-2vd;?k~
z0_v+Na4;|!eghrC^#ioft#^+~1E^Qu*`soSoq=H|Xt28Tsw-#^1+<B?^8=`*S@79o
z_09-Z28I{y!r;o-1GE9b9jw0sbVep@UB>YSP!KYJl56J&k6zJ?iR=s>&Ch>$X#Q+G
z2r}T{OXklWt3g@$uOO(=#iGLK(Y!~60n{__>0Auj$i?5H16@N167^_iV1&;5d2}{|
zHgCO1&SGEy9kUGSoq{G-K})dN85mqTvo%@|bT)%llGZ7A?@{>xcA>KYX#Ht#$Yl$U
z<IsiP2f*uDKeWC*-V9oB3UV-i-*!GwYrO>=4xqtIP<Xf+eseYa@3<GVN~Uv-$_<c#
z%?AWLLG$mRqb)m+^@2{_U~%y1tvRk?c;Iyiynb+O{`;T5#f=TLaOf{1e@hH#b=NO}
z5^u;-B>t8Ote~|?9Q-XJU>PR<7EKW20Hb5`aYj$jZ8VnG`CCB4J&xT%-wp|uu61pF
z3tn*N!te4Dv|MQ`=sac(pX39*8H|42Jcm4!uQ`GSlzVwD`*e1Ka<VUIMW25+%R!&c
zMo{MT?DqQ5*)kcl<)+(FqVrJmE5?c_k8V!|m+m=`;7Y#aliUJf_KI9|)I1E^-{jHF
z<k;)+9~AN>(tf=>hkd&pK?Ot!pC@RHt92r1A!VndhEMWA(1KxC%fqE-K)&dF;bVE7
zzt!SDs4)YM!ER_kwjL<)a_RN}jhWRsdUOXUK;zMo@gP5F{W_CJ@(IvYHqD1P94!y}
zbh?~204=?P#!&MC0nnLJE-DH9eWJV!4Ben&u0$ol@c(OmP<;$q=-qrw!t!sO+c!3W
zk`F$~FFd;4K7f}}K;^tTTi$>cfWHWc`2HWv0rfeOodqoa9&c#@x8fP37<wHTJDmmU
zcR}`5PX#Zv=urXXBM;DI6gy~1WjAZCDJO%Er6UJ_%Q8?7yYxaQ5!~_xje>#H^0%;q
z#{N1Fb_avD?O7h;@9F0NZ58MSr9jZIVe2z6KSU)5bbdcbk7M&EM#ttyh%Cb2Qp(1_
z;M#JDza<Ckjuvp%ap`uD=ysHFv^?O#?|;Cx^+27cM|YqCsFa`K)5`<C6~?34<`5%)
z>unYW2Cv=_E)MXp`)f(0`W3XwySWN<B=I&D28QMXjE<HEYF~m5Mah9V#HBl0!=>9(
z!lm<ui{=T?Ca!~^yxQBM(!dH@=y2dTc-byQ$t_24<Q-sf(LCj1d8qy|=)8fGbu!TU
z-?5iPz+*<|lopWI=0l8@ffDtvyIWKwI6%kr@=rbFlUyv|2)d)H#h8PEq2-d}js!ji
z2L2X*4rma#ae(sHKY9NCCh$VyEh-uu3=F&s3=GV!y>*OUojqR~7#SFxI$O4Y;?e`O
z5~%g0SLc>54WO+hEnVCU;FEqp4gjrq1u6FE-J$}L_2^v#UbhMv$#CiX>DAft1zb}0
zIvaqNB7p`sK;;Ig2jSrXT2BFDIdp?dAJAx?fd^=}0%$~p1$0^v=%Dt@ZqSfvGiWoU
zYwQ0y1IJ$X|DfaXduxtyyyo<5KE~l|`L9G0+OsTu2WlpQME?gE_*(ueeGcAT3%Z>K
z)Cvdn6I;x{9tT&Y;KVo=ys*VZB?mMw&@vsgTKLk7McU9o+-6W^%imG~O68CW?Zq-P
zu#-Sd0oW!-V-xVmX{#k@g~=31d|cvhF$E=G&<$%G;Bj#N76nl7bvA>y&NeeJf|e%>
zf(Fz>RB}LUR*-sV%JAr|HURenz#-N<1)O_a4Np4mfZTM_0;z;Rp$IPEK$Q;oP8C>q
z9*3^x1qCO_j84#wx?V_P0foE93*Ii6CqYXJAZtTFi~bM3SgZw;fvoqa1chFAH%Qrw
z<)&cogO-)P1f8diRDyaOZv>T~Alp2Sg9}g4y!mlR;R&h_UPk=-{~sy;bhEN1f;x~>
zz?s3Lo8v_zFQ`-B1K~GoB27p&YcnGE<-unafof<_OB;Trm1lR*55^0QjMrbj`}zOB
zOXqHINn!Z*<<_77|4#tb5-+d*1a;d$sha^&l{xMO%@n`vhpa1U*}=i^BA*jlZ$ok_
ze@hjpI0mJ0RtARGf}rx!qxqNwcsUoS-_dL*07`ytAAEXQC+y&0@JRNM0F}@$!aTsG
z8h?u=$N*3^`0|Ao$nfSpU~e*%ZhtBF|NsBv&7h;<K_T{HHV@ct{+9Kio^Cf%(fRcs
z=%hnOiEd{N7jRv~-vK%q*r(f5!6W&SC#e4EJm{)<@U;MFKWg(U4j0Q4{4JY6C)&SY
z^yy}*cnzw0N}l>8U+}YZxol8!+oP9v3&_9q9AG;^g>M53sL(hJYLkGDS@P*+-M^g!
zv}n(R-=zhd5aFJybccElbSWOVBmkvhkS9OBa0QtN@+2rXmy~<-@)m<E5(5c$egtg*
zPzEvKDndPyy)`^~gAIIoS!+QmWgv!^*nqF@`}pDuJ1B8XQ31KnqxDjWibppqPdq3A
zalG*02Fdk6<WLe0Qt-8|{QLj^%Z-0QDZmA`Y^^O2yfXl_lFqa9z>DX9!9D_q10w@N
zi95LZ+YgSH=)mv)k3&`mF)&DhS15o>zT?fHmI6r0acA%v+m}3`lmr@q`1AAse{ix#
z8)>lt$80cod?5kS<pULo3E%^!!I>Y{$m4H`Myj~LYyUgJo4vb(H9R_hzSx!kE?qo2
zohA4?96>9yA?w{*gu%HMQs04YP6L%fAlHMEIw)>IY|w6A5F2!lBB<ljq9OpQOiqIM
zpl#Ky!k~^;GPsBamou)0Cp~&Y4ucmRfLfc~4icaP!U{lV262FF0NwilFSvX<UxCXV
z&}~VMjVCfdRbOWfXtPz0iUz1;0ws+XEuaJ4K>hq?&`u8i7B0}_z$MU#tCSk7AOiJ-
z_**`J=RP5w5II9oCj`v)=mhubUU-{8gg_qeYzFoEUd+$~70o4F$KkmP)>QBSHAQSd
z-s^^JOX|D<?urZYw=M*)5dsbV#Hb`d2Y(V?f|kT}J4%3py_u2G@(_P-;rIXlH7|5d
zQR#rx<)9{n#|+TsDbVyAsFDOHBTzSh!IcS=gZNu|z+Ql6>25>#0#rf%7BTSE5a8Ag
zNFS&@18U{8NP!ll!mEG-puT|NNl@DmY6{3Bcfe;yhp50C9`H^Ae@n&p|NlWPpw@ri
z{{MfO1v2e8xLFA*sX=>-K=jL(pZ|kbMT6>e$DIjspq4^~1S6yk;mYrFu;o$-C)k)H
zpp#obB_SxB(Q1EKq`DfO1l{`pig<9X?$i0|h0l6M2G`E-9-ZL&{H68}@BuuK){7(m
z)B|uQyMS(xsRk_s1??6u0@bSC0-y~vpw39^$vUat!2dp-2RwU2CV;o&faVzvuz+@)
zeFSybKy4au1c1(b0?(^}`a~X`&7c!1K#Q(4KnWDQ*Tr#1iU4>uDd;jDh8L^WLDSnY
z{+1T-!hLA=fgUa>6$|M|!EH&-Pyn&PIRT=EzXi0n^~Hx61_lrQ^)Dc;o8}jc6;hz}
z-=GF&=b9_v5{!R+&SeA8dhh4prWCl~{P;q>5tN1@)`GkYPDR}T8r>ceFQR=wTj^TB
zjW&;D54hE!<<l;mx0+uu@^?H2H&vkele<AZJCE)H1>eq76FibZy%&#z4_G|9TUbB_
z`}MMLc+BwX>^TB;5zn#aU;jb7bfK1X^B&jaWbo<rHgN9+T{S>p@fK*isltmT+u%hg
zC=K(s*#7|4TA*fn=RsJ*7`z14qnnjE5<CJmV<QIxcm`h{R2+44yjaf)DbPVCykz+K
z|No1(X`qk+x7-Xbz4)&PjVfpp?J8&)CA5jgtP5A^(b)`Ysl6~T05@AeBQh^tLCfa4
z!8ri5T!$ChqvG#h^$9$p^3vrq)V*-WF8Tt>Z;+wkeW2Bm$&(==3#ktwZQk!KDxe~e
z0d#67<ODoO;sae13C=1lQ$T_4(HnBv0F=QyK-(TbdC!C26&l_krAQIj?I7`TE;t>6
z3L_V!!syEH|Np_s25c~D3mldQA+B=i{E28>gR<dK(9s>xJh=P|=%_ju6#)-Oo$_)y
zsN(8o-5L&#m8=brA=XFCNRd$tDozX!yo?8}0`9!=viRHo|1TJ#KuafHft>_N$sYXc
zFZg!8c+sW>Inz!aT;s7uLrgAM4>7p|*<?vj(FBdd^PnbpGH78G%Y|-8o7w}?bbfgN
zeB3iQ0>D$gu>N)^XuP-a%?@yN>1Y8ODeSxs%Ie@#KS66cz|B5T0_)uZzPiSvxx#{>
z#N4y<!;AdKpn>gDZBTZe08#=PVq*sl^fXr(Fz~m4&aL-oJOVNt)Z_%8_tER3QUcmM
zoa52?3)J2QwE#Rp13)*yEo}I<dW9E-M?t1{9_R1a0zN5=k-z0Hc#pjTe@iV`goD3j
z0Vv@dZGI}Sf}g(?v@5>#ZE2ndc&m0N^g6m`Mn=f&%4Se)4X)_x%nfft+M}SQ!=V0q
zj7m<O5@>rt>&cSWAmyb`LH#1AG-!uTj7m=ZJ&;d90fOwS=KliSAu2hgoXx)&`CH7u
zNzvH?beLy>W9JW0SO$O+>~R+r4+aJn29M5<$6Zt$K<g!8y9hx(2VeMG0Xi@QJh5s3
z+C>Li>-u8W8}RaB575NOP0)l#g#cq6w?}h@1OtC7$V<?}OAIf)kdFf=n-0(cY@lY&
z;uW9}<nMqSRRq4GsCzo7c@N4-U~fQrRIT7!nY+C~%k8*TIT=dgLC24Q6?BJM_;mX!
zxOBTpKxTwvR4lrk9Y6;QcyznMCWBqUZdQ14ZzH@E1L@{(0S%>jKu#7&%7#qj*n<M7
z^?!)~X!jzhdjebV4T&{S#SC6#0P1<Rf{uLv#RF(|4YVx-6skF(dJ4350g`N9yxalu
zWyJx=M0yYSIv&r?8!r~dFfqKW1utOpQON-f%2ssdfNs(L0BQ|9-V4^%<?!ve1Ahzn
zKu%Dq*#&Cpy(sesost0B?+<O%fv?kS^Z@MuZFs2(&XuqmYHxx@dY@hfm37D(K>ZuT
z126yn`Trlh3L0c*z5kE@FJFTiGo1%t80`c(fWHIOJ$Y#X9_U>I&S0Rh2CW>c6Yh3(
zSixAz(+oLbrgbUUURMjqc_`EW!p=kK{rmqv=$fi-UkCn{2Cy*bNR%?L@?eY36QG!D
ze!#@v`Ute1^Z+PAJ-T@nl_A?&!E1`a5qcbb2kQ&o4d4j%>^uNVGW;zeAh&|z^rqqe
z7f%*~ebKoOY#A)aA$LMSO=eK~2bB+?5Pk_dx&uCb35rWlQh}|1{`sP7|Ns9l^FhWz
zW<M{0nBA_RGiE@k06dWi8l3={*R07{qKI5by<7xZy8e)HC&)&A*Ml!X+u)%I==C*l
z|L%>(3wBUjwez4y^AU}gx3B#`p8s-0zV7`18|Z+fObf{Dq$l`-caUwM#0Rnf#0Hgn
zAU1!?LeQ{nuV~T=4u%&`iy(=;2UOL7Pl$$G844*pt3X$Fc0K|n2_5h{mC_9GJTCIW
z1RJnU=xtA+OyLL;==}8}D-$#~36W?$;L**<-;o8%QoRBHp(nKn^0!KY6n6)LwkG62
zj%mqx2|5#D0%$!SXr(8p2(CdYe|^Bt0To0VASIwE0dW*wyxtFr;LfA`9iT;npfOnR
zy5r^_3j8ggoyXvVOCB*ZFsumRZvia?cldUcpTCs{RG}a(h;!_G<JkN}0DLnGCn%u0
z{W(0kMdvDjcKBc9Zvh?C^y2ytR?znTR$0(#EZ<zE86j(&K}Fe;pJ1sL@I`=sL0h@O
zc?A;kD?mNC5S1Fk13N*7th_u5_C2dg0JuWVTnVW*1OKqXcT9p}7E~ocMnMkybejq*
zfJRn}Irv*Z$3Q}Y<HfU|te_qUDD8vdoWI2$RJnC~aQIk$<Zl73sRixEP=GpH0yJ3B
z&D!e^wpMB-2j~t0&<M@-->eMK@kmfl3S<;$ivsk>xci{kgWaWyI7#jk=$NL~Cnem_
z1p%NdSi3`1YFaPx_kniG7~Xy@oHhYkL0QJA)bRI#hD4xs*mH0l_7IlzZ-5HU8c=2f
zEtZBBoEtWSRw02WR6z&cJ_Y4#(9zAEH$cmiK?*&PXQ>bVkbij)qz2R=2X#Fe`CHe3
z_>d(AU~|BGIy^z=$zVA+0JNtNG^pA6^TpL;;Bo~Nu%HaY-*OnVL-4NvKlnUckT-XN
zDo9Wg3;@-+pdfSXeBlDk_@HYEJUTyun$8iB$`n+ux~Ld*Lyj#+RID*78sJ(q<SDoo
z1)o%)14<svdmssjza<c~vIcY{0%(cQr5CrtAeCqkXdOgzjS8rm&1Ys{04)QG>jz~9
z{tnPF_Rwhg1&uwB3y~uA1IP}{NIeT_g4DDgs53FV{hALs{s^`|YU=NSR$ze2L-6_*
zhz~qEf4n>djs|d!@|FeXs1n{6onIkY<|N34NE$pr$8b#n?_dLsOmyCSA$}R`txglr
zAwJN1$Q_$Omy7m)1)Ygv_~fMv$X3hW&>_8MW=7C<4zQm)Z+dk8dT}KMT;O$n{P+L=
z>vQ1J401-nOAnAvND_G|3TF3!LmoVq0KTsaT+=K51yz(!pb7RR6KMNuh)NB(O$A!m
zfh9eFH>r}JBpgBeeOeEIl0@rUP_<E`Qp3pK3R<j=6hxpx`Z>6e=I;~%Eg*gO4|O~i
z(!o&&#{h)Q0!lgEJu09vYuD};6-bK<>g#4kM%UH@rS70Wo1Y8`G|*iN&3^^>TknB3
z+(Vpk8B|AgL!t@foX(ps5}?ii)%Pzq{|1f7F@Ul(C<pm;K7>@EFT8eunj%o!T2Gcv
zLn?CkTRTB}pjLs+4zTd(_O<}c(SjCuzc315U}!l2%4{I>Ae+uWQ$DViE-DiIEs3Bj
zRY2|gkD!G(Au2U5v%ua&ECqrr(eDAbzrc~}_Zu9gFGWFT8+X2e7eSz81F8%l#gI#9
zii*OEkS&lTcpEhK*A3qN_3#D%2C!hqanSC{8ql(*37|$Ev}o!432N7X+Sj0cOQ54T
z6hI}+i^@Z2WlK8f;QG!3FWJDUkCoR8Tt3fT0I3$NzCo*nmrp?bxYh%p(ucpb=kNdj
zklLgjw4njCW~aFdbPgQ@Xfs0<=p4Fl;LAc>R6r-uy#k#?R|RTzfsTsw>^uOiL0a0u
zUg*3D3ir)_{{IJ=4y&hh!486i*voC8c42pb0{D287h8Nl^HZ?cC=qn*4pDJX4sd9G
z#LVBC_aD^Pc93|P4V|S&%nv}ia|=MVFQ}&l9$p5WjMeL-k^`#lK@}#blLtTJ2DEwr
z-01?x2I$bMpW8uB2KBr2!QCx^5>-&tL0ZtDelnuV_G0cPkXrtZQgCtSqEZ1;3F`KM
zdPJb80WY%#9Zm<E$%1r)KpkIDaqXf~0x7>4LGcG}iGsU8;4*u`eQ=o#?)iv-Ea<%X
z!iN{S@~9nj@G5`HN^mm}bTMlyc(D<vg$XK#MM3o+e+xfI8~EPV*4L19o6~x!&Iw$1
zg7@Pf>d%}yZD`&38nmOPHvqE9U9j{HXiXbb-Txp1OHfDfD(H^!#v`C`2CV`^gg<zW
z1ttt?xOlGxhfwE4kV9dvgVy|@j0WljmBe>Lx}^sVZ@=b+S_QJFZUfv&pz(QdmlU+^
z{SKo23^Q^s$it=Eq2=f6bs)R%uloQ0CFtx85BQNVucty)yo6Nupe_q&%>68=Xak+*
z43h>ejG8cE0%-k^gHJCnOEEhGD4E!R5>MwvpUy)*y{!2QI6%>614&e%Js{nz)ncFn
zl0fO`;yYG`&O@L@&LuqEAu2YYl2q0SbUwfl2l#qvkof^Vy}VOOA?7<En=cH?qKLX2
zWI-=zN)D1_7{G_}fY0*;wG$LxB)o%Ec(9<h0GC4D;DC4J=$-&t6%A_WfXW{q(2dT%
ztp`f9J-Zz^y1^@^TMtw^dvuF(ig7adbRK-+2{x|80Msu98CAju>O*?Gc)9)O|JDN~
zdSD|!%e_26K3nVv_E`Yv7+2O+uHYi3em<m#x&DzAvhX<|`Y>3RZ|i~5_SfL?kZ#eL
zqMQsb?z{!Ly+pyIxkkl-p;Q~B%mS2wz<B~R0PFDjBzV1oi;9CUXoH>0|NsAACP12;
zRuKE1&x6>P4z}+l=)h!9c>q4a_`F9iulRfph8LecK-;v(N|HhI1xz4*CwTGR{*O?p
z!zJqA;ooLG@B|`!$y_Js@+bvRiieFKc{J-WmdJZ_vrcybd-=>f&_T;TK&@WIkE{%@
z_ZZ%OeFCxQ4tlC9BEKN@x0>H5_;e=;fVWm%_U%08(|Ojh*GGlXrSrK*^2ryE-as99
ztfT<k!u09PkT5&|y6v?$SfWk=x*n{X3%nlS5Qk6l1rN}i!*Q=ppKB7O&pbLm`GUro
zUcM-J2fD~k4ssB|VekZo7-%3O47@Th$iM^c%~)vv!0`6#R}k|->D9oeoA=CfZU&Fe
z)4r`IOL#$RN<mBFUh0ElqnDR=9tQ&`#vtpIUsQsc2B3DvL61(>DIk5_A)w1?TvRkl
zkAPQ_8i29`s8`0o05d-Yqz>JD@SWVfyqo5tm=EetgYN9>1evb`(no~(f1Y7+KX^TO
zFK;-i`JmfL;N~9z=_A7YDIj&|?&k-EL@)23IVkRr1l5AD@QDHGBf@+gkUDhp!BfAz
zyo*rH{|TyCVdj5%%FO`EvkIULh9~@wfYhOz?+<cmFRurx`7@Et?*Zu}!u>HIb?D~5
z2bt8%`))Q$_*jBOVeVG}=_A7YH&3v{Z$HSSUfwCF=7X9h@c7*V(no~(Eg*I1?$?Ky
zZ;5JtC8)ItbH5KrA0G3;$Ax=<S07*W=)C;m$_sF==kEip|MuvPmhb?b)di{Qok1fA
z(E_0U&IQnU;s;+$djTp%`CB08t%KzKI6N#5mgIt(jXvGp3NGEw&~eNX6~s8EGi)5w
z89I(BHW%82JXWIS0q*P^^ys|xVtyE?z3$QZv4YD3G^%#QBRcLdxCE3nJc%sA%m^wI
z5K6k;K!>s$o&*(ztgZIolG11vq_E!gnw7!u<ZI9oYc8Orfvl+z`5!YO^0OfFeUS18
zJ$$x2M-QKFQ4fAj1`p5<4ohgT)IWy=3uH48B3MdD43_`1;lZMd6f7N~uwW5H1OjZl
z15`f{8#=c@=hw5Q+JVDI2<HD+;P6=r@xMnmt1CqQ#tcaKR6*ohA@X6t9*u9n6?`wR
zKrW<BQGwj1cr*jtW=UZHH48djR02G@S+DbQg4!_|poT4MZWmPdf=`76F(8v6umga>
z$NoBabhG;NLfSeOpq5bvs1afSVx@ps8X#5<h^6r2_)}2$gW3@VrE;LwDdYlxaByQ0
z<k;vq*!pddtT(7B*Ig)65(HY_0B%xecy!)$>2^^`0kx|;OH>p<25Y?Fy9+w>{NM{Q
z&?IN$5vWnnCfw@<{PGO@BpDbOUT;TgFM|81@cRHj^$qxbgU*W{y`tx)b1=LR1iQ9G
z6g(6TO2^>q1(Gd({O6a4G-DJ{>nnu*K9K&4Pe8sc5ru30p$XCoso%i$9h!bn`_d#E
z5?3hgOa5u#xI$@PO7lR%T;WCG6U_D{uK~CfhSI(~(%{p}yCe%@ehzY4cmOd!1GF3&
z6riBA;LQyg6$eK-C^3L01VEA=pa`u1u|QG31f&eSP6Ku}w1G!A>pm`s<G_&*P9_R3
zPCbS@QytXI2W|7LfJSEqs46M|cXov5|NigMdGLj|7iebwO#>*1U7+m&kIvJe@md{^
z&WoTekQyGnqI%Of7+$0!j1~l?4xR20(8<L&Uo6uB83MXf09;;V`1JBNXF>u1GQ|gN
zz`vf#0d7Qt8<`-lDZG$=430f3P-+FYdTl+dd5i3M7)ne)XYV?62TOpa{zNi<{BQoj
zSSkeC{oi@>g^CH-#*FB=!{8_eF~IA+I&Z$PFow%ba0~&@I5xjY@ag3}p8;`G1ahQA
zO$A4K0BG?W$VuSL6>{7~B?O#hK_|F^8Q>X<ZdPyPAP)d(P<Rpk2;>L;79mjYuN$<(
zvD<b%sMN6h!QUbc5(EuoxPuto*%lt%t`;630YQ*JFR#c{4u%(Jo`TC&@D7*LprQg~
zj888s4=BWXMLDK|nz=7Q9b0hh?S06~0ICQ;dk|}ULD!FitDw%8FJ>?P`QM}4!@>i3
z-AYM@PiKOKM<-~S&_yMrJ47V_)Q8~T^ZP%j0}#PbA_E$m0Tl-Ps2cq}I<qZW4^&t|
z_E`S#Xg-nv8OS~i?$08c+Am8X`&}Tj;PCxeuUo<K1JeZR+k(n9$RvTs>jj|V4%}%s
zeETvU)Sm6;y<-6`kWWqq9TDXMx*UP?1q&#Ax?NN}UV_&68NPjK3_eSk0n*<{@aUGc
zv*ls%>E%7029M)&p!5swI9{I2!O&gj0E#Vei5URu^m~8^Fe?Hi0nS6<<(UdE+8#h6
zbRRe-d{hEFEN_+wy!ieQBwUi+nC9>w)U@md?QFEXS)%>oEm(%XbuL(gp8-h4d(dbC
z?DCa#kK=CO)hwWN?g24w2Ut_7AxJT(%>u6YK|LN&U_tjkfKGSmkOS?NElF(ja{w)_
zdEE{YWS0N&zvVzlCP<Klf#LN*NPPq=izh(qLwMlB%<E>YH3tVT(_{{Y&N>HB&uRH%
zP=E1tt4B9$0z`7{BuHh~3zm5a-s#oN>I{+mFbS?R7b5TRAG}2nT7H1C8cQlX8cxHb
z;rS$RR`Y@7CvaBtfu{gaEPzV26KqJOS^!8?;l-DG;GlN^m1Yq>*1Q4MJPajDphCz8
zRHlKG^MSLFBCP_njti7d52sCl8xFe8<3id5Xn4Ta|AXqI0H0o7l@y43J&=nAFNk|x
zVD1GuP8#Gm<Uu8Hx^aQH((fL;?3DyH_(4u{0p+yTeUOUtt_!$mLhRp$mQJAkZ=fa}
zXa^kVd~48T$cuz~&@$n0i7#l93?%5$`3ZDCSLY8<Z3ij}Ko)zvIC>Y<#WaSmR1+>0
zg6>rV4TC^3n+;;qTQ_TjDL4`2PK3ns(ubfF09SzMFC*M{795SoL5<|~cUc)g6@-mX
zFYE0jP{4^gf(!z!VmWr)MFljM$nZk(KX@dnr4^JXTECU}c{KlHEQte`>R{J@da<qm
zoU&s;@n{2{902cQR+j>;p#mTHe)z?w`=C&`UE=5g*^meBKMR+*d33XSTY^rFV_-zM
zdjh!0-py(VlCeBoI_dTO7at#h3^-7t0*-sgwm+oy3GAr3*XzLbM>lV%2{>qqCP0cG
z4UcZl7p)*Ox?NN>UQY(8!W}-xJUTCfLI9LxUbNp~WdI$!)a#;R<I~GKA>+q?pI+9P
ziQo`h)C)2ne5Z=S3(y4`tp`eqJevPA*4ZKlQFlH#h|0l11g`vEz6h5=3ZF}$R01AB
zfOyTLo7EUpfLc0Blo*0d^66!D&HwS=qgQlIKgiCTo}C|G%)SlEP^Bx70tMtV=-Ppo
zFP!y%{C~Y_!i&w|;6G5p2P(K6UZmUuC6w2vLHjF>!QtcuGP9fGMbdp%hS#@X`Dsc5
z$dfKAF39=GpdXz7U104WP=5N&h?Lo(#V`A9cs7y(`P&7QkHDi|v8y3je5xZNAEBHl
z53(QBzGH#fkJ7%=?*ZG7(!R51g4nO{V&W~ht?==~Ty?NLDD69NQ=%mv;y)i`|AqE}
z&G&&d;VeA5S+k-31J^r<iUwM&$s+6&2MuNWfJzNeVFvPX#0x)ABMn@V!N$Kp{sWa)
zSK=V{qm);-d%^a@!xwHpa(M-I2)Mk`@aSf(VSssm(oMMc1wpO=xd2>td2ajuA9h9r
z1FSs-Zsf{C9Z`TB2r&>xfU1oDpu))k)Q$zs1>}J81gJcQbaTLs*>2X?PzQjW1@6;;
z3si8!SK-Cq8=zFm-(n7GDuFgqcy!x_f{HFs%L=p#7Tl0p1C~W<S(SkVdU<zsb1=Lp
z0%bzb^zkwN7RU+2E-D2+y{wzMIY2inuIol^StZ|qx2*VE&Vldtc*5VZ9aM&OzI<Uj
z3rp*YzvUQc$^+WM0_BqmNH&74ZvjtYure?}wrIcbSOM?WCV?V72b9J$zzgVazOdf<
z`@bXTVqZ4+fvjRBk)T#u0ctA^vLG6CmZ@M#Ca9I>+WMqI2;NM4(*SLzfigIp1G?Xc
z1F|3ar81<w1{-XBJsXt&LG3e8tVKYVR7bp20oCnD_oG4jbA8bE1w1|t-@asmG~Z<P
z!Q}#17pSZOH-<T1xZVcUPcAAE;EUo6-@d#Cok;?vXGDK)Und8{3&!i9I7jNw?YR2;
zKP>%&d~*b?KL^^3AQA^U#}?de(f0uNEuA_z7>>E9=oi1(a1CsrI{&^96@5@U_r<is
zkn<o!Ku7d~c0$~I5v&F7$r(gL`V-(GQfPYyRGxf^g5)=p^5lLyIKQEkC$IlPyshxU
z@ftis!OIh0B`oEM0l2>fnr#3(T&atL;l-b;U^gp)a-jyO1+iEKR1Z`LdUUgf7{RMO
zB<Diff3Ws&FYDb-P}MH04pQ8C4pdz`fC8oybfir$>%mUYm>+0TWj9D&XN(GX^dG!(
z5ETF5-Y58mcW`zz0EsEQ$OF5IzXf#XjYqTXzYE-;T_~X4@}PE^1*q6C@aX&mzJTn-
z%&Xvfm%jxvKVktt#6qCN3#8J*)AB}12xv}3&a>MCG`9Bt4+n#X<;4=d7q(!FN?gF|
zKw)42YV*#|0nOtbd@<b`9E#v(vPX9SXs_=7AOo;kPs<ynYe0z-+{JVS9jD{b&Dx{`
zPLl6BKtaOsV*3qHB?j%v9QNqt-QB^#@WK<6^Ff2!$6v%<X9blFyFltY555q;2`Upn
z>#A9KE^sq|rqK9XxxlF%wwUncZ*YPJkEesm=Oq!4^ny}8w|0Qj3sQTs*G0tzR5(LN
zg5WJ<aG?7@0{!P@csh~;6&D_$;sR7McZaC>ywE-csS%s4z+nPzSt6Zx5$w?nE~>wT
zL)?QhHuVdVesf^;v4=-DtMzY47adYaBTw6c3v%!v1E^j({0oxK!R0o1+zC{j=t4ym
zUN~O{C16ltSWqej>R3X?pzJ{z7&6)bTJr@yI@KC9{^Zi_C{yAHN=6l+F(*)x57-2%
zctDB~?JZdUW(TzVaohnOa5@evA3*Xhoh~Xd{{sv_;S>Wp$p}k$90|h`9<SQK@q-c`
z+8`f+j+BMfUf_WmP|To)$L62d!b27+s_?@262;+hU?WY!;|-|%WC?|rpBkWIqF0ou
z8IlmdiydC%T!be=UQm7nmr41DK@I{9`@q}Npz^!`)Sn84gl`6N(_m67IDBJZ=?yfn
zb@~UynhbFGf*S?BpnKw=!!38dLxL5YA;34GDZF@b0qz!gP=d(-M>MEQ(H)|a@FMam
zBu5mQgL6bd^kJm)v|!~U=oU-RfWJ@YF;Hm%9)URSq5^KZy*PgXl;3|a))hjA2zp&q
ze0+L&9|VKj?>~b<UK7o00l5s^eh0N<n~@y~Zs#eykpBeg0hPFeaxJ)J7Xe=27NQdH
z;>i+-BhQ$D9SJVVK=m(Zye+_^S5y{k`pp+#&V!N-e{046|DffTptfKf@_nVq<Ie_Q
zhk*{I>jfQW3OZ2*I_?$>HVsr4_qwR$fIJ1>UIWhK$6ZuF+f~8mnSpPa108CX0&2p7
z&a8nJOrT?}z$!pRM8`Lf&%yPGiwbz~8B`#Af{KCyV;YpL@WKY{{!$HaK>#WSpi2=z
zXRV+PM?=PIyF*kmS}&DqfX1Gie=tFsV9h`NL(VD!%|mlBGBA8|b716e-OK>mX%0HD
zpgTmR08~NrnS%yJ_*;I1nrq!*7NFB_IzPU+uKD9XsCEDy`%}^hijAD^5Rl71zIX#V
z<O|d~Jj~yc11ix$CutpgAzJ<8Kd4=BqxBMhXBbGl8>w^6-wHa{1JuEW><TnI@X`o8
z90kAs_9f`BLQs5yFYZJvsRo_j1{#!YJx~g&$@xIxWa-Ai-wIj^2XZkuoL-1&gVsjz
zw?GzHg3b{IEysYJj^qK_^4<C2<v!4sQP9rz@8An69hmrA-h!6H&GYEx&29p<Zevs`
zUU;1YHNE`6b$P`Lne(77=}pkiPEU|TFK=WM2g3_h5F50z?$8S(5EFcm-v<y2A}D)~
zm7%#tC4t4GSM*OK2Sd3uD64t&vf6;`Nfw#l!Fb{S1CL(OZH*v%c{xFb-Z%@l>n@1d
z&H76Pv=cN$r2;hSWO)(fFwlY!(6VYXu+LxK15bI1_BV1cyx#87D_R9&tn=s<%>pr&
zdi07$f*5m<%X`oYm4ndw06Jb#;nT~@7y!zrpzP3z7=l{R2rhy^>lhHdla%8wDv${p
zP?AR!MBS{hUm!^xT+4xrA5bml{uv^w@FMmMID0~lhyoq3=wZ#eRReUP)@M)>1dZ~_
zfchfc)fOJ0Q{O-WFF`WByt4Hi3@@&Nq63utjzJbPgC<}ye0o_$>p{UNDp(Kdocx3j
z`yM+DDwy;bJvxt;q=K&>tp^#_`SZn+-k<+HIy2y7yr792(4N&7-K!vDycwvy2SfN!
zkzk3oM`yJKXfD9s2wWIdfO-z_@j`h2pdXZ;G5QCu4}og*BTzly@iuT#ZutLY2{_;I
z@`4UH?-l)33kkFc(0Ga|$lstL?$`Z>|6h88GY_~u0FFQSjM_h6NED)UFrU<eqY&P~
z1UFT&cQ8Q}OxGufz2Lz{a0e4qLbZH^h=S`CXlHZ6DM(~mfMd)>rNG0Q^@SQJGTlHT
zptu8{n2H>kprJ00UfzIO4u%&Tp!@=j%rBsL0d-h?dRaX{KJOKEsYQ*<pC{pw$=?D#
z@e6dHET}OJT1$1g8xf(PtbxBv`E@3|OIZsp-#}F&tV=m#C8(}B>H#`^4!X)rti+u_
zm(mTAC|<tMGGJl=-TlbGzyMAcNF)BBctdbsuZ7Il!R7_yV?pDukd?TvH$w9#sImoD
zJBI&Xg6{D2=;nQ^0B)S$s)ob}IDLqM%L`C{u@O}9{eSrr+`M*xx37<QLsAAx`}%eb
zIAx%Ye|&(nFW~F8z*!kF{_!4StHO&(C*Z9L)Un%{3m{{+iu&N(5rER30JV2O?R^n!
z?(xRrp4%V`K}~*GF@x%!H}7EXVZ!B}$T<-AOw_~T9`y5(Knb_own&+W!KYhQ{~hQw
zz8aMbpWYIc5TD*0l?0F89MBn#mtpOW{u+?|=RgN#JNR^#s91p3yc>9S{`Bcg0nPR0
zfTn^$XBmUmNQ39{z`6Z}&v8iJIRibaBLK9ch`$|tB~P~>cw!G)^S=Tu5AO!m+MrXK
zz}dt{B?5Z8187~Cn+0es*o#Bapbl^6Vg8N;(4M<PpiE(>2<iYH1zpnI?Vte4kZ(Yn
z!&~3-cPs|&XiPrgu>&-Z_y7O@dXJeN-+y{o9_8=v07-#t{N^Cd#NW~l4iiwl&<(pD
zg^9oAA1k<7!NT8a30CfBfYe&CfCwpoW@<pwI<UDM&}ys~fuMYR+zr&IWoW&9+|2=W
zVPR*SL`h07Pqat!NsogMnO~@Y6oJYHHwFF{&<<Ch<ij4F2SGR2di9Dhcyxw=4v>E#
z`iTux&xSC1fC8;I%)znqhEKAmf=9QXh9u<FGLOz*%?Fr3L;o-8i$L4PTvQT39s>mm
ze=F$zZ2oN(QlN?i)FkrgbQ5^t&hq2GL&JZ&5)sfj$e`wXMz<5_p2n6_V2`<3bcacJ
zbo(iIBu6N`xGB#7+7^8S)CKcp{0cdE?;yw^{uUn=1_qEx{4JZoJ5xeb3P4-m;y!}*
zp8BX{H2XQQz-PKZ>+D;qnHd;%F@u7<^WzIYzu*5ox>+YHLIyBif))^f3bzbUw+*y<
z4su%!=(r(}j@}T^NS%vH#f!B^LCLE^7vxEgWCsP%wrvmV9F+?G7RVXLtjlG<rAST{
zq>F#$1f+410qR?pDuT@aA7Eg3;I)KDH)}OS?T$)_+7~Cl!vT#)Iv62k9Ap)qWBlQ?
z2`?Ul4C)natOSjh)PV9s3FxT&92E^vj!=M4#=zDazi>JNaw>l-XnFeU6;O*`a)A%D
za9{w1Ff_1V6v%-C8k7!RJo*0x63}h}{4M?9uywQe<{-_%-^vNvdkPBIZU+ZYO8}Pm
zx@%N2Ji1qa4s?96^uce4_QU)whTv+~Ljp2CYw4{}=j_q#E&)o3-IGD5H-J`Nck`V1
zf7JuDI;q!#5p>8@r?*7wfl^nG?q<+&WggAW8jK!{%^>9-mfi~WdqMZQ@V6R)r#)d)
zCNGsi++NWe6`+7*m67IQcnLbfx?wlyC<ulUC6H;L3<|nb1Qcr!17Cs`$V2M`@CGl?
z*`uuo_&fYTE>FJT)5~(%x7$O**Rn$cd<QVt8FeDBebOfQfKG3<?owc6V5l($UDnns
za=G~hqmOoz253jmkN+OWoxnZT(yKn5V13}K1KvM{3W9aAT=oQAvCiB8^07~+hXzy<
zeEl=jeIDJ;1|HVn!w_nNK{x1nbUGV&bT@-mgG0mT<qUA$1nIwcbo&XsSpNUZ|K>D@
z-!HfR2JMXikC?vP^ZWn*v<WY=kAV`~%RX3ofQGkrvjHg5k2^yqiIIZ;r6p(s2)w<U
z9H9V9KL#?;^waGpV0a01Fv_vFpnT|N@$wAVc<}lzi0zesK-)J!{S!CvFkOL9a)5$Q
zcZ36I@##$P=5x?!HK@Di`TdtKXvOs<&>)9`<NwK^gU~@4uiHbW`KMr=dh<^a{=TIQ
z3=EAwK_|x7iFtIhPI=D3(9OUK;#(f%?`sF0x_f~eR8hHsPn%8v<wO3~>qr4|8qD@n
zIPN9^staFm9zo8su+Gj4tD~$8FXO?^2m6P0uLL-!Yn6c#9mk7TN5BDU3t9`<`SC@z
zK4@_m<f5mSY9PUGAC-g`Elr^2l$!<rwg9PyUv?#-4Zm#oTa*6(|9{Lu$_{$0ENc|R
z=;x&nqx&I7KLR_{%>wFB(5VhDO#XcN4=yo5<*WZ;R)&|s5VLGvqTFu*zt6h)jfF?&
zdC16U`vLICD0s0)A-JI9wJhOacyatNRQxc1OE6em^bp7?od;jsIS6VjYBTb;bb+>w
zo%HB*lXy`NQs2wF8m#8fiy8Yt0T|BV(aSrh6x7x{;J7mh6cP3NSs8Y+f~wk1H-#6R
zFx!vvgRkKPpBeMQ7;KhkI@qkA9-XcdFET)OcDgEndM@4m4j$d2pQIrL_cwP3CXY^6
z4gOXgP;CxAx;xYWR15KgFO~NI7gaxfx)*@fz`tO>gD9O8KpMI|6kbd^1okZG%Bq&%
z;B4+Jkv74{(pjO-!=t+!T=I1Oa{PbAr`uV=6Ld92@(EASTI)`hQ{BM=KAp}It(W*)
z!R=*eCPK<JAam+>fC{ZrD-Y1xMDU5puk}ESW=gWaT^0*aa~4$89|m7T4sKs?ft%4_
zH<g1Tp!0)IXRd`uXP$;f^AUsw<nhR0@cBTX@i6F=iN?!VaDf2s&mfw|Xm&!&7g$j#
zjiac11M1_0_W4g{0N<6|aT`?RCZF=?WjXEB?V;fVDI-B85-S5kozQC!&^c2+)}7!I
z($E8>lIL{uD@G6PMsNxF>%YfwM`#HNI^~6xf#GF4l6xVACRm@yX;As-!Q2EXAH6hS
z>OuSEq3%a6A2V>2kDwE)VdYozLq`7A)1Xd%x9A*69tOz8hG++efg{P$1F|1G0OVoB
zer(XLd{9_{k`bOla|_rCc;9t1%zl*iar2uB$8QeOjGmom!JDlQ`*xn=Zvmw!Ptc(g
z{4L-kYC&W4pl%Czj1a^Cw|GGf=Kzo18Wj)F96PjM*$cWjx3>n=qIOZScpV2?UkX}1
z)LbdRT*?h<lX-YpI%<@-f`%<26BZu5qCX2EZ3~4LY<oa$hY}l)WFHk5&}OU$pb5y%
zkD$RT@aThrXRip4597-hkntjK16cdx(~GDBAibr1pvwnfDcdp55p-m<q(`@rN9*m9
zIM5<m(ETJJW5LTUZh@`=J+T)wPIDY}eT9@q>$ehq)IOt-XQz$I>v>4|=@ue=zkY;d
zvf(9=!TAt_UvEL=7ufvqn*fi_v!G6g2V}HaH=l#y1^aH07x-HaFfuSeSA)KM5yb~;
z<c3;!bRPfaB+XdL3!aOPi;s1T0rf9?dG{A^Fuds52QE#(N4PeEa&E8angUQ)=HQEk
zdmu$8xVU`-k^|jr83ST;zI>5=9Z@!cI{rT0=>i_zpw<&4|AN|2;gFbv6iPmwk32y~
zqq%_gRJdBaSOrdLt`?wXsVCzR%r;dFEV&{TPvADyN>DoIZ-MNcX9iFAcK(1YZ{cqh
z1GR;^L4`{V=#222(89&y<==nE`#}knA2y(?hkr2gw}6g{1GTZVLFOX0v8<8XShYg0
zGmu+Yf#7x$!4}qaP!>hoy8|xn0w4+TFe3h;O)RjvINM*y<q_g2YtSVH6OhXrV;tp;
z2e>$cwa4I%Rn~w1|4)F$1)idV6BNL(@&de`Rl_4WQUY{iL-S!)kAsg{zBxLultR}V
zYedJrEZ>c^-yU@L1?Z%|0)-d-Lf{742M@;2pxKG$BOt|IyIGOuqrm1z`1G<egBvK|
z32bPVXv{<!xp?t<J1B3IDuB969!OnN&^ANE+n`n)_$2bf9-w1Yx=pv-2Ti4Zgp_6;
zou9z^LCf!5x}6<7y1l`dnZfq6g6B#-I(<|$KvQR+sa9~)54M5fMR^XmTJ-2VRx$-t
zgn)vg^WX~xwXgp{ok<VS4Kkp^G0Q+{tJ}}wMVJV9{JJ$2ED)mN0iI|7_(Dz`l$XUk
zIuCm^zhVR@bus={d$1~4S^d)BKX@@AH2%PgBJaJP4zF(@?O9Inkf8%~{igx=E)vju
z&I{q~pxpk0vCh@QT2@P#hoQs{R6r|$BB1lr3mdN={|zs-9w?Cpuci9=;`Lw9IaEHN
zVU5Et+IE6U!do7l7d${4tm5Jim&k#R+x+?B2uK-dMgT4YnQsTJH+wx5k-kCWL7@3B
z7Awg36w3UUat<U$AvFnjuB)5%)Ln>R0t2XlhCBdm09rW%F80Brl+a0~S6e{|p(G7b
zCv>~0M1ZEy)j>51Xw^PwWS@N=sNsF^MLuYqSo4vBXwYCTG(1}mlwR@Z=B?lbH=^fe
zgUU$g8ruaR--FiJzCH!-FM+dh0cdeJL_gC0xyCo3Hb!@pKzE^pN9TFZ&MVEY8TmUx
zK{a!)=;Uk;h8KQ%pvHJbmPhj8=HHB--8n}j_*-^?S~9mwA}#Onw{kNvFtmQ-?~7w(
zVCZ%G54z}E2Yk`@Ye{JMc9zH}cr+j80PTfT@UeVd66D$KBO~!b7<BL?X!54>Sm~`7
zydbBy9w@nBc;K}+^m?-w0{oDZ;P_iOL4|!cYcmhn(*ht*cXPbhumd#99|Ag}=LM+s
z7qI&`=uVnF9^I@T1t1MwkH#Y)PeO_@$5_X>!=R%EK!=8Md~1SStlN5zfq`KcsN)1a
z)mQER|No$qj6qX3KHcRC-Qg0Ts<4HRfdRDBTEesQ=!<YS&{`AFgzI5Q2KDKD;qm>3
zhvi}Z9?+5_Ps_XfeW3G=L7R^{K(|h~^t%1`O+Mk;dceDv=UgSvYXfM0@J&A9(RsrW
zbVSBXkMEWqoj1HXL(V9G2EQylnqP7_f`jOA>2+}Uy%Yki$@~Up^Y^j-|Np<&?>{KD
z_xhaTfQ%PF@Am<nm2Y{X^utTg_HvKz0D;y^otODr7DAe%pfe1n9D2$9|Ns9NlRz1+
z^#Ffs<3G^dRxdy|LR4^re01=IeanFoWsh#wLtNm1KcC6L;M@5UG%MH5@uF}$xZ^ex
zq>b_QOG$7kz<M8|^a`l(>*jdD15s20s$t;f@IxivZv&eEX^ukDCv1MVm$fJrG}y@-
zZOP66+1}*?%D$itIN&SldR<gN#qK1KQQ*1eUZ@l}uR#|g)@=giHU5@apsd*)qvGMw
z?Tmb#PirqoqM4b|@IPp@On)1=5mMp?%8U`93>pAl)%Ed3>G$uTq~+ZDpT8Bng}mEG
z#RJqOM!L<BwT2Ix=%BN_9^I^soZx`_mjUUJ{@V)b;h}2<=TYzsa@vF!he1kuMfZbr
zbRK*W19j4EpI+V#AhBN2H5s73;SJD)Pu)hagF)pnXi<L2R`40B;1U>`z97|2ujqmd
z(CIP<UbsMX@VAtLqYG(K4}YsVSO~Tp=OyTPnhEg!Z{r)#SdK@x6QsDf>d|?=`3EED
z5XqCE^58&8y5%*<@Fl1`$U~F|DtOC-$DqA-KC%)on4MvH3RE8a-2(O)s66m!JOZ*A
zmW2;{bo+zu_WleyV;VI2)H;a~R0e_bM4bYm`~WH^G`9Wzk8Ucgz2E^lxUAcQ<69%N
zbO2o!4DMlrO9xPxw4CH`0UZ<N)19x-3BK1U9psj7UkT67BQLC-VE#DF-?9q4uJ8e@
zY}m`dz~E_lhrbVW?h&|b0F@TVWrNRIhD!d|#)$fe#PUHF9EBbNttUHA@wZ$A<@TST
z*+%{;2Va8DDe~xMwPOb-N#is~lFZ%=&V$oHx9+rW28TL-Ya1v}cRqj>1rIzBMZtD9
zu=XRVprYU*v?xe}7y`PJ!iVwkOD(V~Sg$~oCZ<AcVuUDa0yWR{VBrm(FKm7To(Agn
zwD9P>?wS1I#j{VK>{iMHimh8<c8QfoH*fzcZqR}w=z2}?F<GMbQ#lww8{9lQf4<0H
z2XTK(8#r5QF!HzbfKG96cJN>>769E`*zL^$YZZZ3QCKuT_zNyPx}7yZV`$LrobJi+
z_L4nPd+CA<xHgo54~N^EgC^!acr=4HcE-no_vd44Mtgt~FKoXJJb!^2R}(yXd9NgZ
z`ah6-37Qx-^XL`*o&u`Z558Es9@L;=owgFRYAqMEg6&`l59pYJR!}$M^}-1r@Se3t
zH*fw*Zid$nQSQeBwP!%{TP#M9_6*8;?&Tm`Fy^vAU1azYH_&u>2l(!6&=C!KYeD5{
zsTQPEX@zZ$f!uEt5Dn_jLFWr$_ZxxcF%iqZ`9ReG^tw7oc@J(sYxs1Yd+`a>4+G7x
z94^rZx9twTST6%=pn?}}bRGk@Hib*M5X&|?K_RaZ9d~#iXwK;M2hjXB$iJZdD=AR_
zqO9-UlMHF9!B<Iw=ad6L>xLLWDF%`hSZ9E)j)$Fd0&TUKtO5HRe7HjZsQC_A4krLD
zyW#s$pz{T<pF_)Ea7_XV1RqcX7PN8e1*qxUdZ6N{M>ne%2U3l3803CL|GMRp2WT_{
zG$QNK?P%fAE6NOVK4@gFdk1Jp_r(SkP<rI=0PRDCjVa$@WnkzI1C6Y;fVQV~hdF#Z
z#K_;u3ObqP5mWOoCjOS6Ag}g@sQ5rmmh=Gy-V2tuprm}*BiTj8$D=z;!vlORxym7r
z?l1+9Zk<E0{0i#$)<r<a_rSe^5)}j3$TR2^Vg=9R2SFzKbUylj9iubN-wIxOiaFi~
zGPiyOXuOZVwF%@v#F$?hczExH(7*4HDUxF)Rp90tr~(8XL*mhmREvSq2P}tqfD;J3
z4-07@b%$Ai#`vMG1o<F2NCA}hk$mBzqVWGZbd?U$Xay*K48Ofz0qe6XgF2&Frbj>>
zU08U5YN!_2{K$S#@<-~sL&pAmy20}tWY3Ref(lfaeMI%o&A}aP$oL4-{D?A+{y5~)
zO-OzPc^T9}z|;S}`4_4G2g;A&^@*U3wvcV9(DmI(QIPfB3@<LMfY03X@^1sJ@$S6&
z;xlOIAJmBhm8yvP5VT||mV=@BCri1sM=vX90tZ9qNsnZa4)6k|v<V))te;~z7~uC?
zdGxX}$8s<r@@FsWjTlt^1vLI~WInWhve*GyQ0LKk)}xnqWjqIiYwH1*PS9Q|evcn7
zF02MuJK*st(Cua(D2>e098eYF)5~fa4_*^g6wkrXSp%Ajj{)^uKzl-8tXmE?p+p!Z
zE%Uc51m%Qg(5wM?rWLd|zWBvMh;@*QhQ5RL8-fS6A@$3PW{_;JXnh={0+Cq*F<I58
zm$v{U)+?G52X8;xLF@&My0u1uDs8md3p^SBdM;v+@MRrH6+Cag%mi~`8SW)$6D}y1
zAmR%g|ETNZnW7=3FnAFA#pPw7g0(~gG!UWT2o2_&FIxVAmR^FF%d0ZO3rVEq^3d`X
z(qC|Z>H{5G!xhKD(0Zx!8o$Sf7iO!#zW3-nT;k!;EBZec)TLnk8Vd@5pP*I)s0=Y&
z25OXB!<V-Umx@5@7|_u{o$!G>kLDu|pp$G254`?@>OZ9Y4-ugK4-g-r?S}_VFG1GV
zfVRgUo&W`{mr7)Mo&J0DhBUJ50Chq=nh&z@uXp_8VR^Ci^XJ20F{JUg)=MR_5cLNk
zm*sdgALQ`hU+?$>q~Q}>1FSq~y;K+A)6EDPV({yA`tQ^0$pI-mdwmXaycV9|X?e0l
z+q3x~hi|vz50EM`AO7`+_$M6j={&^0?LgsukK+eG#rbE@5CrHx+|C0~HyIuP<xH1u
zM+u+qKn;&>M*-K?10^c1y&nG!Pl6^Mz~!xPH_Is>{`D-UJU~;mj0Zd|PnNz08wM#)
zK-U84dvr5-STdFxgY_QpJou3LwHP#heY#y3IXs#VaQIlWFqH~=S{^KY0}T_f`4Cqi
z;$sIV0|O&cc<ta~U|>MzgTfez56LwM{pjX-G`|5gfnNUR25l(t1LdG@ju&PtK#gY5
zd9djE!RvV=7(v$#oy6Qk!~mMj<1B%;E)PRSbwP*bfmhprZ`AWlJ^|Y65da#=^YG|(
z{0|-*Xnx7$(|O8A^Pop36R1`0(R_%*1Ju6<b$c8<I&b=P`lvX(xc7<?a{lPCk{Hmq
z*TENezJ34i(ar7A8~7j6fGW}T=!P6+1loEe21@IobBw@g{UdCU+N1FZ$Pb{?O29+d
zU|D!hcnw}m0IF$WW3%9uz)&4vdp$buy-57_{r~Gp;8;S0FQmN(+9cv>c%ZvT!Lm@H
zgc}r);3F*@7#b?2>>T;09&D%r(+6BF4wgRf=#B(k@Fe5X?IZ)52k~;XJXj(MZhC>5
zf8g{0HN&I3NW;VObIEJa^v7L~?l2C}fGVV1d2xO*D?{@S#uA$sXP1E@@b$h49?ex6
z45eEfn}3RwxHvZd5Gk>9Z2l?A558y1vH6EsNfrM#CkYEj3H~Vuz;nbe5<%rf>w(f;
z9^GOd-P|uUK_f<>TghL7CUp!CxLO|MZv_c@bO#xDbbA_jSf1i<2?v#wpmTY_7d(PS
zTR}tn5QiDweqjP~+6%@K%@;<?SQ$ERynONR|9_}icR_tK=eyvg(NjTppT9f}lDz%m
z`ciQ5#y{oo>l4uYf-*nW_(lSf62TXx9yYuLYVLp<YoK%p+SCT3UsM)?)1znSu@XDb
zHK|h$fx4zs4zye<acMcg-wHZJ+!I_ecy_yS_;h{*U544s`t1ieOGJZ8^KOn8%1c2Z
z>d|-vWF@G-1Dcry&tJ71C_Ml<f)SK7K7zUz;G!SyfFA`v{<|8U^z1y2J;#8CX08<c
z`0v~L-?Q^*39CozfzoP_i}+iFSQr?5TmP4Ec{b}a!nkkwTZ%wOI6~$hL5o!ow<a4N
zco~5_J`Eb%lbHYezh}1{v;y$#6oV}1_5>v!&~_`3mq9V<qT=vU8WfGaTU0K9&p8EU
zamf7x$6LTcpaAvh+@f*=RB`u)3HWsGQ2|ZXfex;H!N9<9yhR0cEHVQF3-j?7l_MbK
z3``(V(1m&o5at=E=!*n_AOAs{$`6BdgSI}tuzU6GzenqB5FdQ0ZRZ>n(1`+|vsF1j
z7iPEY1+51It*a9Utw!l>Q2}Y&3AzCW6xtvfa$$kvjto#M4zyU_Ma2NLIUVFI(5!*R
z3r=s)h<c9-#0Jo&1MosHCXmtKw#W;R+1;R7($@d{EybWlZRgJylTLuv_WkTU{G#GC
z=v*QO&|V49)wwS!PJm|<S{8vvaeY)GUQ7e2Z9M=w4;!>89^_&EmUCd~8kGo8GWq$U
zX+PLJkY7QKpBI}h!1<ta5MMN%Vqj>w4GQc9;8B)6DxkFr{8L&~K#Ny=I@hRxR#tg-
z{`2fSjwpY8IzJlze{t*-$b}ICpxEC9W(P>{Z*!LN==OH-=$;7*3!l!9Hg*pDQ;r*c
z1C>P{-9ZkZ5rd4*8kHIc{wc>ix@UouS$^-_0=|-sf65^nJJ1CyoiQo}iieb@fSm!F
z0|vR)r(2-|v~9!}Y#D=3=SR?VBPhHbUi>@*IxP63Pj?2#i?<+lcL2y?KA>BEUfekY
z8UwFUaS-t6c98Jw*7xj==kV+<7x3(^m+<KhQSkt^m;?A*w=#lmqvLN`3tC=s$+z`M
zz52_1Mh1q@{P}$Rg1!tM&4(C0nvV+jFkbUuJnqBz+SBq1e~T|814Dx~L+Q=W{Q3MK
zWv{P;`t}hoz8qs<@UZ;?N>qKI`M4L-3qh?U(1979Eh?Z$dvOt@1T=6AS-}Sp1zq+5
z+Ryjm^8%21&@$0x21ZC`1%($RpMq9PdxEoP3*@*(P@<S9%?K);L36bU{4JZni*_JA
zJIHlLpuRR}#mEeh3@BfMRU-Beg18PZtA79gk0_^J-UoBtIea>Qf=+`6aUq>d&~h#h
zL_>Bh_;_3g21H5mGVTBW{}VjB;d()<r6(X64O*w?(_Nwx;M2WF1=Jx2wR}M_+uZ^_
z)As)bP~d>irtOBD<_=N_N~AvBki_}&7%1<6PH^NXb!)j);^f=<q;9X_rPs>v`5VxA
zo}E5d!O@2tbtTh4(e}`zo8JQ@{rWz%{0FTHcVH>aXt`990y<ZwFB`P}`qFD<sC+kH
zr_WRj)A(CJr$d5Fyx+|aQt<jNR6SA<asC0%ze48kK0(6^Y#&o;Ma!j<60m)seUx6k
zA*l?n6+z*_znw3w6O{UnGQpkiVfl)`<ud31Tx*8Xd;Ht^K`LI~0k;&u`@t2!*Req2
z9@I(^;BVyx3&A@Y|G+oQf!33OLXWZ3vE@>UE!h6*fB*k`GQN4O1et&0-zL@(%HYv_
zlo4*dr{x>Sr37IA@^2IG2xWME*VXVgSid!R=o1vHosd}d1zj?pqT=D%dEB@2&TD<p
zU``Eqfa)bE#bx}z;K7`u;^4#h&4=+nC|@-nVf3*~QSsn!0d0n9ux0>_0VR|k2VLI<
z>T`p}Av?i(3;thteFzjvi1G<K{?qsdd>Lw{gJUyj{PtXl=r>0PCjM4l(0Sl)pj*vb
zLDhsucb$b#a=3y^=RwVjtta{W*g@m&j{iX|NC%JJIVujIGPPF(JOpoefM1@$^EeA5
zs0r-TDZ&hDR(n_;Dt+x}d7@6wr#npnH1cD3z_(k5#V7e<^Fc<x&X_9>KHV}*Af=9$
zC;U3+TmczbdI!8uz1s~ksOrZ7DjLC~C>EVLD&Wn=8ZQ|A!0if9=gZXtv@iG5i#~SH
zh?Pg@%?eG>$#0EEK)!@D77l}!NPBd<DS-XdE$G9)UI4sz9h6;5)D2I*J_}lIQTh$h
z88tlldZ)v;qm2A5UqGkPJ^^K>ZfEGpdGk@i06aSd3TaS(GyrrGN-t>Av{&?85Tr8-
z-d^y+Z3ehAnguEYJ>YE?j24r72Ha=%pdO?;2WVOxxslBQ9yS7xhX#Y!msvn|nt61C
zn$qAAP)Pa&H)6q?ej)uKkLEWKKHaRU`$1y`ASZ&3@B*Er(krS8bt>pm5%9`=u$w`3
zh=vb%IeEu)u<LU`u6F>9QKo@9)gGX0{9;}lW&pVnWD<PXRt=;OycR(mJe4H~+Z<#8
z?*}v=i8zcQ`WmS|H9YWorAIgG!*}4uU|%3)s9$V0s4@7uKW%~sc-<uY7_#_44u%&G
zroqR1gg{Qvcya90fAC>ub)Z@L<|7uM&L$!}K-1`;H5Jep74-=Ob>l$+iG0?t0;pk$
z8a6M=5H^YUfM&))0Rp{k{SxT9DUknA#>>OO9TWp-3eoZC6@454-jt%l0P4G`P6G#V
zWVefoPV0eErq};oFwJ6R04?A+zVEVclE7=`=EIDgH@?5?ym9b{{J~#rnujtkff`Jf
zmrI|%NQ0!WJD_=uOEXy+I&Z$Ho(Wp-aKr#Kv;Z3)0COPe17*Ix0JO}qmvx2&=r9=2
z1_(&v0PQz*2!Nzx$j~<Op=aPR?gUWaK-Rs12f0DBr{I+1(apMY4``?eG`#OV73@0$
zP$~`Z=ytH^c93cQAynek{6m<(B@x{0WBv999M!k|AyKUja(_2yksN3<1vnkSmi~f!
zg&;RWayWSU9TWix9^JedAGjG_oSz1o-8cs7s_g+KgbdKkM$1l6KtF*vMHnpnV%k(l
zN2djHK9`S5#*4#X1^g|qLG4)3QhJ~66qN{%?ikR~Xg^=1Oa&crlmVLi@&sRb4Z5?<
zv-z(AfB#L84p1x2@V003U&eaLmkU`K7-01s=rnE1*ZeJ$LCxLHTcDV-fZ1*W*6DJm
z!lPM(5wr)Vp!7VV{qY(!9s;_kF~Fl6yea4Bi*p+gi_^Y?BCp$D!3DIIzw?zxH}8er
zkT?S`-+>>t4l8XyF$Ug~@?wVvw75CW-?9fZ-rRZcMG4I0qx>y`93baI^Gmn0f`_HE
z1b;7Rhpta|Gia|0bhzHLJHX<_?$6*M0?-No@a_>%mk>0u{_#cQR8|JhW*rqq@bXz@
z@O2_@`CFEP0s^%6v3sfk_%iJuKA_sm!QuY|Py@U5fM>TW1Al8cNEv7u1L)*dR|fu;
zPoS#GS-_*&S%MMN5LynZiZBQML6<@`yF!#CfR(g@maBR+yMi__w1TYkfcdFM2h{rl
z_d&ARLG9vP21fptKoAq00>S+h@Z~n$kkeP7%kjkcTZ=%mOW+P2XvJqIY^1~ECHOR9
zn7i5dTdF`8Y<9B>yaK0kSzkyhcLk+Xu*KdS43JRbZxH}_x%Dk*`~vI{2>(C!o2o#Q
zM*OYcL2hl<W8`nW4;tU@hA*1B0A3&uTHha{0?HpJ-f}a%SU(w@KVIGjOM==C3?ALA
zr7yuwyW|6L+N!Cn46o<H#``?FSz{sc(|tG?9CyI3`a3d}l>xk=vtch}Z%3L(cPk`q
zIDnTvdN6{+`sHrWeNd47AN(z#$!`x>8iJ_<&sMy20nZ^YfR@v6KyU6i3%>ZkmBXj=
zC8(|a|L_0*6TtHyJ)l)W2lzYUL6MMr!K2sbDuWOBp7uu2)V@b|FDRPpBwvEMoIc%7
z3O?3Npk+J!J$FI<XpoMOs|=t>((VE;f=1dVa>1h$tQ&j-NE*aG52$?$VD|A`MzIdO
zIK58fbqr`f3f#6DXYi^<@M=j9OpC61bb|H0^g^EBfX?^5>;iAtaA1Hc0-FR{A9;Y$
zgSi8gpnW<WG@z0%Ilzh`@d<G~SiQ?t2JixTWDO9%f%ZXw%bN+Vh6h|aUxE6qOg9l_
z%WUwiWeyr1-MrP?L6xJ2flqRV0O(E$SQUw<e2H*DlrLvMS+Miq3z0Qo)4|0AXnf75
z^W}>P{oqpAqw^?#3;5`1(DoxsX9fP=lPsVC&u_l1Z|l`wg1Y(e{)-Q2h~cGY^D)L3
zj{U3*zLsD4TR`i3y}DaIgKix6>283e!VXXp0GCjb@1Z5sfzpF7+d<g`6!WlRr4dpK
z6@bq3?iH=|gk*xHlR&j7>h;yo_2>B@6X3JtFB2eK0}ty~kp29<pi>AS6JM?d9^I{w
zjX{vSupZp$Kx`mNfvCgSKxFY7v^fVHpUC;)0jQ&ju=(L{Q2z;3h_t>2%fLoYJwU69
zPJk}_fL!7N*};WphV2B{U6688yA`tW$Q8Qr2vKal`~bS21Z-a#ihVD`L0r&{Y#(3L
zK;qQ1^B8}NG)TDH-NLhbiV8S3I)8w>v&cm~8-MFLknON2VdHQ42QTOqKm~mtXdD={
zrK@)`D1d!>=NtyD%YLm2>ECrv0ObacW(QF5J^^e^^C1pj%Uk>{@{FK0c1+y?0v^o{
z5{#{vN-j3+fRt7e9^Dfl=_JU)12kdF2-f=gF!;Wo>7W%zmnyb-B%ku>WjTSe_pAYA
zMV-X!07!cZd3S{|c$WmviRM>~K3H~F_;iBxzKlT~F9ZvMb&8w-O>_7l_E*4kfY!gj
z+7sOY1|HTEKp{~p4IYE(3^4HMo&ZT^U{8RL9s>Cf)Vk1~0EtcqXmlci>E#vB^)cNp
zDgvI(E-Ii3v((75yF~>QoFEYmMo-2TaJ;=t2BmRO#J7Mh{d<`U?kq#v2aXMUR3Jeb
z3Dyj1PC$3}!L_S^v?J2(0`RS`u*CYZ?FVRp1zyS*`~h)c<H9dL|NRd-=a;{w6BH*0
z_&dNm#*#01_VQc-m%-NHBEQDh6Lf<X=$dx{qyoQ2+XJLj<O(QxVJU(=J9{8LYy=JK
zKsjJ7ELT89C%BO92JZ)i`z8#ewA)3+z|*=#1so5apls|3Y6pXY02C8&#hRcjfVP_j
z+$Q30?fVY$DB}8}Ixrs^{@N`npm_6ym9l6NatWMeG#U9@|AVhzg^Zzm2D9M-y9{g~
zJS5A%gZ3MGG`|6zg;6Ta4!%w$0n{-8ABp?R1=4s#H26W&bf7jp_*|n1Q1cOUNiw)I
z0Nw1;&AJ|R^(<_m3-m-o?@mx3pi~^(@CJ1vAq!o!z#Y|!!=Uzi2B=4=1|HP_b*dsj
zN&{XfRe%=09RVo;d++sGP=9+T52!WYcKO?X@JdP-m5kTN(vZ&c@o0VnI&E513gSO-
z*BtCWMVSA<-ooh6fS2Wf4uW_My5tt-2k5fT_71QgltB)QK=^?j?1zlQ&^jBmV2A<a
zfdG)Fz`pQ!AyWhPMF#wQb@*8pMv@RGX27GM#TgO>ki$rjSAK(!v;g<HP*0lzA5>xC
z(amZKbv1a2cmXKZz{^&_zEXH`ydCU*W03nR5bhTScc?&v;Yj^s=z6Os@bbn*B?BHc
z6(FA#fQ*5f%v<>bwDb{d2BbWOgukf-#B+%7U+)Cz6@pU?I9$PQ1)Bq!5fz5|K;eaC
zJG?uO=wt_gEq!4d3_88!2q-uq<&Q`68xNme-l^gc`%K`0>Ei_MW`m~Czz4g4!vlQi
zjlzrVZEzdJK;~L>hp3pmaLfQLSvvT_^DQF-XbB#8{S>(S9^uo=D-5;4!J`+n?iaKn
z7Ia$POGikYA;wNX=lQPz`85VIaHa6VqYV`NB`Ki5bNJ>Y%~EOu>JfW@#<t@<;EO{!
zAnjwHWG4lWUJnHyO9uh|o;~1sp#v{Mo`D?|0h&T>u2Jz|@aVi*`pl!7HT)6iq74@n
zkJmRq`2(CJL8@T!m+Ym`da}gx#pVuZV+(XmI;a&4x_}5YGxE_V*+JpOoQ<HJ!XYXS
z;Qrgk7f+rtf^G`-=sf(Q5u_7#pzPt}PN0@F19%DR>y;BgY40w$|M1EI(sat|1dY|a
z1nu1h-FMo}DhrYS1eN!K$b;^xd6C!2%J33&><7Gk=h65EG#TL2%UdK0iP9Q)lwJmz
zfP9@R(*2&GBo98VsseOG9cXdQaTk>u(8wf626ReQ5;#)8r&K}4(?JrTyu%5V08d+i
z8eJd>P?Ef`8WfG7fsD2mPz;tjfv&OxtALMr<%5Jk$sduec)-~T<O}e49i;Gj4U3O%
z$Q`wyLs@D-8{|NGyF*keUKCk^2Gk(3;9-wluz|7+=<r#_>*W(*WlaavJka<fXn%={
z2qd&Z;Gwn79+EO4n@d2adVxlqKz;*-M#yS#_5csz9EY8451s^p4dsA>=H4nu2!OLH
zbmvJoD+fGW@|r>6Qli}Lq7u@2pri;i8E)&*&8l@9oFvRaPUz-%5#A1(y8+Ghz{AZ4
zl<yK=sJ4L;iwAg53b_1$9El1lMI%7jC7~NMHe;Ry3K}1k1W<DP)C%gvf|e<PPI3bs
z<9!hpD67-J_l1GN<BJe_c+9iI7alIFhzXB#psQR#6+LJO5gr~tprQ&d;+n9Bhtw@_
zc&LM%(9Q9}y$x4*h_(_F9^XM#BWN2tC_Emu;0q7LZ6u2XAt6!$Pa(T)At8cUt%J@<
z`m_Qf3qG9(RQtoL9&iy3u4KUJ0$lxri&t=nD7=Vh1cgGW2`Gw@sv8k-z5u0nr1dhe
zsCx`e&mcVsp!%i)lm-ewX&~c;cp@bJ!G`SyXO69~%mF``7J4QTxYS0>f56VWOc8+i
z9#PvKv4QvxoCQGsgLo8tB}*^p96L}!0?IO=!@!t9B_?P~ghw~)%;k_w0d5z;Yv9FD
zQE-re0|!)u*n$EPJecm>016cTmVS^)%{3|+4E!zULDylQe6iycXcqoJNjb>#8IWlL
zkb_WGHGuYU$p=6?)`v^HL23&?rAP{R%{-_CDX;*oatBFN@OOarha<|Q3eYkaHt^Jk
zuSYkl(jCzHZ_q*MZyG=s#(@r9Ydu*a1rAyf!`skUL1^Lt)hiISu=eHaH=z2)13u;X
zdO3)1cpH48FQPn$v?pHHK=<c?oU{UL&7#*cLG?rP8x5ac-r8zVEe1WE(Ab)T;e~KL
zD7;GecY+pRffnPuT-e0Q06DK;1JPaqjjuPp0Z)nd^2$RqeLg&izqEqH6{yJDxD>*6
z04+}dB|}hIXaVAYi*#7F2FEBkIfG+S;YDX1$R+$O(V(FW=v*v#b1tZ_*bcg*(xdqY
z6KG~0WDb8TXmeRZ1*0v0t1xJ~dmDp|Eq}`lMg|5OMgA7hc|0~Y{4FXVzTJM%Aq@QB
zt06(rRse~6!%G;k|3U>m`NiLI36z9D_b%dA{?!+nQjYPrSc2W{3?6)cAp{ygYXhB6
z4LbMcD!5p>V9CK?_#box-?~On!35cQ44Nnv=5M(GwhVRnvosXE5ULZjWCK3*8R5}*
z1QZXTi3ddf<KM<$V^iX3W49l)ScJbt6g1-6&B_U}Sr3#eLF?Zd!Nneu0kH8$$OfeQ
z|G-OtT^JY)|Gxy?5{Z<)+>kuh4%%|$YIw4tMkSxY5p*fSCy&mXp!Hub9)J7t-=p*R
zOURCvU=GOq*-Ox+1p7hFg_od--n0q(K{@>;=ps5u{~nZO_*+3OazsiuJn%9QoSa=4
z7*N(nf!d<r8w9WVwmvB}^XO((yaEp4J_}F?8-4?Yu~!4Ay#Dw?s~$vyE>Hn)=WvVx
z&1X2qANJ{d=yC8N%L^uuJZS&IG5!|Nwawu9WWQdU2cX0O9^&WkdkBsk+v|%#o3Xxu
z@}GBi&Q}SKZeI=$%b)x$cA%*5{Pp5rH8=^k>VfzmNo(HbB^(STi5}geRZBP+UfcyM
zC=CSZ{MNXNfq|i+)WyS^xA8JJLy5IVw`j#>ZiW}zA*!@NsywWDuUzD2D3SB%7Cn8D
zo8iSQuq1!W9R>!Z{mk$r+W8XXZqy>JSLfafZ*OQy1&#58woZC9A7%uN@A+DO;cwLi
z-w5rZV&MzAO9B*`FJ`?4ZDu_VDx1^|-@fJq&Bc3IzAlmS=;nC`E?M4!iZ75bXknS<
z>(XbSMFkcN{4K5EWp1zeK~{KJ#;92Ew-kY<_q%!SgEc+}X#|}fc@L4kKzE6Ibn4s#
z>3Ipdl+>f!l>>4t6(fHuI5k<bYF*%FfNbIdHS8@sI$wJBiX4Ao?*hK5liQ=&Ma6>g
zC1@+C;s2LTpez90;scBImnn6iE#u(x?2dr$iwfa^)K@9+qO8aaSA7MltyvaAWWkj*
zsKx@NX=nlGq5>|{K)qX8kTO{B7F=;FyjWQYP8=<t!HEN;7_{K)Ja~G^2Xv&AX!$}8
z2G4F!4iC$V{4Jo93}38;=xGIyr-RSA>=rd#1nK~IKvbzSGBCVo2de@FNd|wbDA;(=
zPB?J#;%{XE3y8{H<OUt`4K+9fS<54E@&+FTo^c+k3be!Rg&wjhP!|a_YX;eX%gEmf
z+G*!uEjslaC{pHu%m5u62AWvsivdLl<Zfwjf$ITULHPuFZY;QiR`KHJ?eG6Vi%meK
zIRnV?6`=MA_)y^#kIq9rohM(IJ^cP3bXT?PM^OIeca?nzqCs2JK?kLR>Nx1(cC{ee
zK}9u4j2E29V6&OvE&8A;6`n<4Gj*V)bqpYlod;j&ctEqq;gT@WN)d<~L4Miv0Cd>0
zHY0y4XmKKFg?WdIN<5@k<KO0@68{ps0v}rcmV**qH)|&-7<)zaOh8e^@nT;!Xs-FC
z8@MzB`xo5b&G6_pWnRL;;M2{TaT!#Ap)MTI1nGvIZw4DlInD;_Y=JrsOF=imV(bJ9
z03}FJv*;K|8r&>WDTgG!E|7n_MR~zD)`FHEdxIrP;z3~_0P;DwKi~n1H3v{h0xkhz
z!($);aM1!{KqfgaYeU+M0iZVWzDiaGkIoy%*}%ctd<1km7_@xvW-UDj@}g*zF(gb@
zRe|b29~BR%YIv7L1Y~!>i=s+!T?H`&-XDXvUqS0FdU;hjA=%djo_)<g#=~+Rc>F`*
zg?<^x^CdZ;MCReqE$R>UJvaxI@V)Sa$i{+YK`lL(+Zh6m%|G4BwLN-yi;K7!K<A|x
z>;j!sd%H%(;DtdX6N5)DZ)6cS!;6$M&;-Vjh{MNSR9xH`KzB`m$k#_f4Y?x`i2W<w
ztfgnc{-0q4^*`8uuMa`OC)A_!sRz7)CC35smg{?%uUy|9bA88f%=JAZC}u&8ET1``
zvuj*bEPQ%d!$2m2`;?HjmFo|XDh-cb*AF0u!VCRUkpKBxKx^1Mx_v*qh^v4OQn=pW
zZ<z$Dg=*h3lxjEBzGLv{4*lWL?R%q??}Y{^h9GT)*uyWhka-h4dPQe4Ffi=o1}%<t
z1<hGAys#(-?d#`toC0cNzVhgFJ@Mk~LN<oh10{~fU9W(XZFlGiu$C7*<*W?du2)(Q
zlyrG?vnHJZ2hDUtNYM0GfTJE}HK@J?Ij!`7N4G23aUQ)cjQ{z!34m5IcDw%Q2x0vH
zdNIm+5YYPn&Ql(}yqhO;GrZWcl9gcsx;$unb}Abvph2r0JE4tYYmggYnGTf9L2VN7
z$QHQA0nJ+ARY>5Bb-5Tm#-#&FxE>z8Au1W56ch2{J2>1cltEpr1W*?XJi6xb;y5Vy
zn~zi=_0L{>E@uS~Y9gy!4_Al09tX6zWtIU4!;1if)m)&Hi*#P3K{Qw#2CMh!WmUBW
z9lv%Fv;qfon_wzPn`AL4HI&GLT&wZoa5=c(E8zo`b=O+Jqo@{#A?<&p^*m_pFAI;(
z%O1U=Y6ct(E}chTTq_2rC(q8~{4Lg?>ZbGHi&+pc(C(@}&;kKh!*8yJZ(R+acy!zT
zI>*iMI^46{UBauI=YxmkPf!cV5x&E}fswz38&t8Wm4O!ioA9@T*3UKnkn~Kx%HI##
zT;<q&l(G4Mqod{94i;hlUXT!|E#qVPtpsE&wBf*1I>)=)=evZ5<<HXjuB}h_TS2v&
zV{a(4<<+_Z&*Y;ZJ&t=oDf1W$vz}wGE2CrcQ6}Hyw?3BNJZ6BzoQ|<*>p6B_EnVr^
z%?|2~xOBeoXuagwDP9`o*&WW|(wU>816rgSWB^)Q^x75LzlJz45$eDm@C|#tqG|e|
z1kPG~5_CB+$BX5qpp_f?jHO(N<*MMVTgZo=f!E@L@>``o2g7UFdD|YnqLv{3Mvq?6
z2YMU~uUEJlzJ)E3hu)t89ux+r)Lzkf+8hio<O{(u9|nqfJj>)1Kv$fDTEvGzM^qnt
zF(DUpdMNTTIYp1=AO9gqCc6Y&00uzsZviif1Fi4Gw*TZLqQ8RZPlApn0Pk}+e#}Ls
z40Lr&IU{UH0Nmk28hr$fHG&#k{QWxMH5>;(sW?i)qnp<TbW5zIHwS1*J*a}^Z;=8`
zIQN2@S-l}DH9oz(o&VVwe0o_Y=z+SY;QIqIK*LLA9-W|T8M{SSP6tVV%7Sjzx6?rE
z5YQoGAu8pdQWQLZ4(`Q5y0jrG4&Vi$pk?^oth!LW8pz#Tg%{iMK>=Q>f;@N$ZL!=2
zjY%9p>dQ6Ps8lHM_k&u84K*rd4E(L2y#*fKwuvCKp~IOTmX#d*E%%uj7#eC+${D*|
zRB9x@eZSWH40I@O>kZIu;d6|gA3VCJfR{2ipKySf<?^BVoB(M0hXr)@5O@b2tQ7=l
z7QL_ro#W8G1*{EpE=B9N5-!lfP5u@`P=*HG#tc40KUf0PNT>iEeqwonzYlac0jSQb
z0d4m9e&zrFm!KUqp!3(j<FWAdn;zYBz{~ADx@{+d!WMK|lI71536IWSFHYovLW#cx
zy!isI4&nn3(2kpU&<tyLu?6U=f#TEu|F<0AZ`lT_wQ5w#8M;GMYD!g_fBolgc@8?U
z6|`0Q9%v!SCH~fZObiU)oI!UMfX+t-IkDv+s8@3sG>QO@N6Qb;{shQ_U%>WwTY$F^
zcUwX?mUwgu^0yoXNp%)OE)WHs`;WTgvlYCEweuLFKZ95zbO3bz6(ky3Ou%bhA%oB0
z14d!}Z_xUmqu@%ANe8t42h_L%^<s|{vNF8f3z?iPu>|#-JS=~J4pBM?3c0>qP{@H&
z7bMLyfi5I)bYSXsbl`9K`uG3;6^#6?Z$Y}xF}-|>vi=2p$wL?;XdBJ}{+3)&9CwTI
zWpXq4bRK-MtPotDm+*R6v&Nm|X5eq#1fE+K{h9%)+kd`j1u3v*jRMO}1Ix95<M)`0
zN;yMwg#=?g+cyUXM$iesq9>r50w9`rPjWMqaDo<$x5j{ViuOYl=z|or9w<=&)kTl;
zSs6NAR4SSeF!HxlgHkpmgJ}Hu{~wg@K_!rQ^ADyHA<!x{kO#mq-NFGf6Wm3BOh3Hz
z1ckpxH|yWS;PB1T0+qoWFSH6kjf|I7;5Ay{?1Y?@K&!ODyY9i~w_W0IUBUoMN*h5<
z=+2ujEcb)9=)rT$%aeb=gD24WvTjz@6QHh?lLCKh>F@vleL=3=^$)BBR6cgz+yyGh
zUVH}KP>INQFPkCm@#sAL^2eY5|3PD4t<Hb{|NrI;x@W=?yaEZNzZ(+Xpd-6siTNdH
zofcR_?0=XB$o5qS2GCySm-e8bfpk>hdelK{tw0^oe9#nnH_GDu7|_}lwZH%WzfjEw
zCkXylBajfNGvEAzk-v4$FPJ@(e*ORd64dX9)_<V+5(j?G5*33q{`UtwI!~wZYkc(R
zW}Pw#bUvCRM~UEzoqHG=S`U2U7hv6Q&cRT^%db(QVgTN)3!2aA6}8a>mBBY(ESwEJ
zK;Up1zs9kW8=%Btng^<Nv>8iJd2~B-eBu`b-{N)ie}KU!egV*Rk(<D?9Ekb`x<0@8
zO#;YKphFNnI<Nb59`@+=;_$Hc<#6ph<I%kZy!D8`C7zLiA&vk2NsrEpFF^O*Lf9|U
z_%%Mf0Nvh}#;^B*za4y@Q0r~bAPs*D=%N-6OK%ST)=!{bu642me=BI?80hG?ZYLSb
z7RXMMR!~d1+u1=CbXK`7h~RGp9d-%Ys>Bbz?asCJNu8BXx3hw0H-m>I8-MF#P^Y5T
zN9DiaB@fUJTj=@H-7aDrpxvaN)+_@2t>6oDEiab70L8OM=M7L;20$;`0v*^m0kr$9
z+n<BK6||qxrMn0091qY29na1W=xfbfIv;^rzGywYO64E_(al9F?^x#^0Ozk+>X7_(
zDhJf&)+kX40C$Bz=Olq#0!<&jp!UUk{?-$q9RT19V7ggjAO`G&8qkT|07!oc6a^mq
zZhxU?CZUcGHolnwT9VXx1#}$dF^|skFaAFG{@<tbVdtS2pC5ex-+8d}@QYQOz_S71
zRdHG1<(&+Skh&1G0S;C>g2xCzg=6QT7aSJgrm_d9l`99?pb4JEeFYCJm};NShc9lK
zLscK;Z}DSdVCW8)X#T}ipVnL<!NlM92ei!QQfY)o=MRr=2M!O=s;-|N-3|%=0|Y#}
z%{_X<Ap3sB`CC4MtnV&mfQyAP@VD#*2{s-9`4h29+cEwytUmEc&Xw@!eBs*qwq(9f
zcf5j6@-NSW&zT*Y|1$b_r&#~s?{i{fU~ujA{pXwf(WSFT1$5w!=fP*p9^JkQe%306
z{4JoV=jK<8o}HjW+6=$FkX!*82mx)^)M0}!;uQih5p4y~f&GRDz*7_8WqhTdK*M+*
zouGxKh6i4HL6&5>FfjBwe`@~0SjN-q{1r4(-u?kJKG^vYY}v2Qn=kfEV`2br+JvST
z$8I+P&t^B!@+tn-^DLkRXKj!bRBoUJRBfQuV(=BOJ}McYv3+Oo`PLrY4g#QE)(Oy4
zbi17eTzVZCeUlG>E&+JKJ&BFM@T6zAn}VmMn*?YSB!Rz&71Va@b_E>-FHkB7YHBf*
zaDiIQ6)!Glg4*nQjQlN}Ag_a0Ykgp4V0gil1uY^$$B1}<x3wCARCK#Cfcg!fLrp+K
z{h<u}t<K<9Kqz>Fi3ccfAiGpOUTPughwgBg^iSxtw8zVD;L;yd)kE*Xn+P@tb{C%E
zftN4ADqKJ@>m&NlvH7P0fB#m{)eyZw{|yiL^tPygrVd<NFL@?k;_vHX1uZ}ao9Ejt
za@e<1<N#=im51ep()W(NuK!vO_#|Jb)Aj9@xnKys1i=F-zl$97>=Zc+Qtty&59;1}
zcrYFUrLa0)uWpx@KRh~Hu7Irb=yunDByg{87Yp#<goj7BtA<xMivf5CjA!SE&KS_i
z8ZIgUFM>d8u0W;3G5(g`zyJSthf8>LyDNa&fuK4Vbbe*8&jrY72#E3>w9(0fe|^9Y
z(C+$A9<7&3tGYuaJi1*KS}&F4qi6!x44CS@z(?`8S+rgPEz|(*XyR|FXJKGK(Tngu
z=%7BheLno_4}ngnF}(C*cRy%>2k7wi00*D$RiHMlFX(=mSIi6y-3|&Kz0h`T=TD#R
zIswp;c-`(2%`X@`A+41c#!I0Kc#rY7^nvQ@-YMX`>CyS}g*Zgcqw_F-%T}Z$%HLwg
z%)sE;?Iz)A>81c~f`N)8@EA3JpC71(?{$VA4dkr=>dj<;4h#Z!X(C=rgT_}tc?Z<Q
zMLH`Nbl{ec<w^eD2JlkBK2R2eo_PbxCIO(kO2B)^3_v$BfDZ!kaD-fL;KK}>vO>P$
zpkyBG^c^>lRY=Php{M!3M!F)^@W4w2aBGCsa~HTyd8f$10GZV(Nn>SrS@s*cSaBMt
z6g|M-0h%WAKsulY^>AI`*WTpZU+@Q#86oXCqR!_z1zuYZ&QHka<$8cJ36}c{W`mVO
z%y(?q2U*_f=Gol_SuqP)x9`aaF56zpg9D@)ROWf$Sz-*@(+i4EP@&oaIspK5_V8m+
zmI5u%<hh2lmeaEv9Hq6QFF_-K$g4T4!AmnmuHjtG3D)?s=hy%L$6LUulL5SZ>YJ<K
z$(Or9tCtb0Q164eup;W^Q81S^a|bwHzsW<|3iDFHZE@|N|Nnb-f(-||faMx!aVXM4
ze5mA0p<kdioo)u6)@|UGq0*ob_Uv>s@a%4btP6z%+AENO-H?hxyA86^(+#{r*RvT>
zZ@fJG^Z)-BpOV4lHz;>hfT{!jsV*wzpgMuSXCEjZg8JtSV8NFU!JdFk(7$AaxCVN}
z!pj$6S=PSoU@t~Py|_CW)R6<N!3A$4*$iUAk7and<j4R2hL>KpgCeRM9#{u{{{Ig?
z_2uPk@Je;0`9ARZMvZSkYqmiP<pMl9uYwktokz?C#HcvDV7me8?Y`_h^y1HTP_yU7
z)|Jpk&oSscdo!U%kFY+p8FQS!1++^Q)<pUQDq+AaL|CH-R6;$~gQ`Bp-!c=lzT88i
z+g+mdK&Ow22Y(;vHs|J_jQoA;KyBL26OPR<m`cQY1OI|rh=&+GI$6N=321NY=jNA;
zp2-J5gQ*Un8&o=dj(~<<&jf(R0M;)B?=%3HgP{A~z^yRwmang0|3eNNJIW7E{T`4(
zJMa-I;{4!21C*oH`CGv2H=sA%gNOD!I)zIT;RmUJPX`3`x4?J*eSSR!+8zN7jg;_#
zSK5H$0MrIMjI_h`!0Tro-K@=9!AU?s7Lv+$B!W`;>ocJI37SU&9lK@$nMeZ7Jy;-H
z3Yqu^ZFhPZ2ini>0d5a~ngZbSASZwt7$u=#SEzuF{b(r!O+0~GBdwr=Gd$qSMW6>~
zAl&x)0@!{~1EtjlqzRth3=g~n%>#SD1zyibs_#JeXn+Tj6+C)Hm&$;4tGK9Wyf_^L
zAO98ywUEH|fWnIyP^Hs(@I}gD@OnxM^z(LH4G+BZ_yXE~0V)4L<AKdb8a#SgePuWp
zJeqB9MR0@8jkt__Q79;HCV2F+>VTBM#|S$?J1TowB|(CnE-D55kgG62>+3+{-U&Xv
ztkPgP(6lzl2=G8Ycxni|`~;M)R1{ut#el|AAm=+r_*k>1?cio8@c<pIqy)Vt`3C4_
zR?CYeLNCO?YWZ70^$%!pAG`<|yd2r%MbT%-p4hBIAfJP800;GFVe@yOtC26JfydXO
za**~&FK>)A2g3`Sc+d>mL66SkF9PF0(<!3S(x7he!53T!pe`@yC`s1+;h<$j`i!vC
z>fr?jJG_1E(ap-b8Jzl5K>E8mURcG0QXlx_FMfIS{t{%U(NV#pvqwb$)V1iGq5?V)
z#-p17yagO|DPOmf0+@RU6owU`IqF`>Y~md7@_f*U0z@nLQcxe2isQ_nk#*3>AK0kQ
z7Ko9Zb0AiLZs~(;lZSSWTc$HJFgP~<Wa4k}WoBS-Z9Q3H<I&CPx(V!$Vkt;2DvAU7
z!=v#C$jzX92b<dm59)!c1ISUzujhGagGPUkL)yFypivv-MXlf~O&~Ud25mtHL4bx$
z!A|XlgaYU+Ck@C-NpKMZTB5ocbPpM5Q_~UtmS#|k3A78N8`Rd@1ZnGi<8KLJW?=Z{
zAT4mLMFq4BjRACC3TW;P<Ocp0MsUjwVgu+j5uffFl?u=95)}cDZqR{TJ<wnRor~Pv
z0u3uIm>j5e;n5u-;M1)IcW&niPtEh5{OgZ;Fgpo&w4U??Z43n+0MmJbzYnzP#;5b8
z591G?&i@|YZ-Qbk19UnIXyq*E@c9Ja&g&kXkdrPD`5ki9U5Sc<FK9PWii&}6=Sy%S
z{-#IsaYo1g*FbH&1P|sCl>iUR8kLOFv#?=EP+67$8cYG5@8Z$D2Yl*?2mktm9*ht-
zdGN0X`Hk@yNM!*emb#}vJ?f(p;L{rbp65*P=ytMzdD6G@0_bFw43};X8IY?zKxaQX
zfK`At<@%^ZbUVm^1~d#nvI?N<^FVjQfDU_qk>C66f9nCzsVf=$tyjTKmH(i%DhUh~
zR<QCMJSN_G6V#M702!m<+xZfbwL4#VFuwMLcpB_qAIln*gxa&91P|)ocy|8x)I9Fd
zdZ5l4xjzD$t1ST?Z;#VV$N$&B=6PEFFFg<1fClMriZ|?mB%2amP>_NW&WqS+R)!Y~
zqQNZ`{ua<e3dru37EmM_9(ef{)I#Ze;mN=LkPrWQ(0m5tVIRh8;0Yl}`2t=X0lBaD
zga@c$*9ktJ2%MaHUAX>(CQd-U0i_I3UU>N&G@J=P?-x|GSAfobIQYWegYksN#UG$a
zf==ilWakMF%^MI?A-V14N^qY6zUv0m_eU}BMROFWpaZ)B<U_FcK^56lNS=9l>ksHu
z^9L`5!Sw%^7eEzCH><@uaAD9Y1}O|uqgWYUegti>3P;*;-~1-Sqw_kbJ#@~s^T-Q^
z^PpDH&(1?HzMTWLf;x}BSi9icfAG+0C+fLYpb<GphIiZnF1$cF>F^6aHAJ&!IjA7%
zyoJ*I!PNHi#Vu8+p2Pet;Keb}efcl=Ktu0s^FhXdZrpb5eCP-oVz~vnV-7r}oB(PC
zf{K`9B@x{&Dlwpu<Fz2=pq67x5U6;DG+2B(KY&{{!u&0YAW`sI3D5;C&?Ro5MRg^q
zh6i3h1s&v5%8fV#X97qH`6M_{OQQ5DqLpBH;PnPj0N#AT<PIKwEjjDajda!`e~UlJ
z#?Hep%|Uez=zb9JQa{jLe=mzcr+9U{Dfo8h33zl{cy_y4bO*?IBxfiz{}SNu1C<NS
zzr^`lKnzf;u|6D}u)&*FgFsD^=J$-Ao$o#P*Z=kWe&2`jy{F~hVpE^aSDu|OKtpTk
z4Qvb^oxglKUwU@FcoEsa#^A~L)}!+$So)C<<Np_~ATi6oMW;c^HNsgLUV_hX?GEMu
zU9RbYXmoji&+-AySHZV*&j-yHH2>n|?*~o&gRa!_>3rqWJpq&}K*M$X>yLW&y0HHD
zv^-j@3>$Cb-^S&_zYTmq4>%uK9&+h$`rqNfSo9Q>Qowx<(3m19QGss&s!>q@*D0@j
zI$t{ezw}ZbJd_g*8}xx4+UMcXdHCfO*r*P2`2ya5_4NrGcz>A>Y^4b6RAKM}dmm6;
z11jpljU8|kN5ccuBm#*kypRosx7tKN^Laj?;T!Pkgoqa#L1jtvk&MI0`@P`f=K;t$
zYuRa7&YE)?nzMrEl9aQyC_!_{F@A7a2D;(|6iy)LgE|)2a#jOO&*744ke_@ovyd!k
zi(c!25?c@W`EVYcVkKE9X}Ht~(h3KiNP==+DD3EAP^KvHhm@bq+KeUgpnl2`WZBZU
zh%EE^p$ELx{rW1T0S`7B)QSgHbrvscL5UkaGx&NHMtrh9Mvu><g2cq9Zy@gY1mE0+
z5ueEAC1fuU_(CY~MOr>86+XS7CSR}U9s$UDM^IMy52_nL6$W%h9+Z|}oDKjro1x1-
zK&$c$FTLnL37Q%6QK{%W^rHDBC}B8u9(iFo8=5jes-WFS<fvu<6>*^Q_V|l=3eZ$>
zn7@Syv_P_V4S04DoMR69biR6VW&*SecodYN3m`Y@feJPL7E@5c1gh?E+VSg!EzE*r
zkZtX*h6j8=L+}S*6vGS#wH-TO^S6NSpaz$`pa!Q$=P{4&U<J_dAgD2H$ppPIu$y(>
za&XNgEx^HG_!cyEdomc*VAp0W$pojP3Xj&eB@&QPaY4kWIJEr%?n#0wbCeb>a{AC`
zEWL%)H9H6D0rIyz0eKd*@pYf!ThIs@Y)}GpHcKDK-qH?43Vm4#Dyt#s8J-F~x=U0l
zUV;{Md%%+~xVFa~e4x`>3SRt_gGSOZe(-s8h%nUehenQzN(Fx_xa4iU4O&hBIuZFE
z*u|iuG&n#<oV^9_)1Khb`5GL1t)D>?LZGXNAlAEpuRjKr1PtKh0qVoO(0_vH<<A0_
zo6ZW3&42hky1fN_y4?hPx@!e|x-~pNw*zzwcyzmI_;hpdw}3k8b?J`He+2kjK=+3`
zHvbXy=`}qV%*0R{>)H4hwDh8m>zli@0DsFGkZrJKkKo26c(@bPWCL}wTWUb^;KMZ$
z!3(O&O13aEyfg$gNSgof`ShB$_%kt-EcWPjckt=n0PP@@PWI?#&0h*mE_-+(4VgKC
ztPC&Dfy;SN4r2f{g<4;M!r~EV+I|8e=3nxH>L(9)T)hO{2r>b*h$R9v%@F`<{(69h
z)g4~Q2eN_>oC4QAo}EV!{(ubNg0?1t3Vv|+)x+`sHL%}XrT&AatDo?<2!d9HcRqY^
zKY*3tB?~C+z}tg9y{4K$ObjoNg2yl&7<_t7GXt0yUTy^~{eJth80-_I@hY_SV;-Ph
zA?O$y&*Yb$oo75culKtC_vt*={DY~?#iN@wa0xhc-tj;}r!D~0K!7J9P}2jpP6~BV
zKcfGFT(W>F5m3d_&FR?r(y{Z!3p*KT(mh<Vz4<Q_Klsf3=D*DRty4kq+U=kKI@Qsq
z+rYEem(i1d{W;Lg>x&zHAXgmVZ!rTeoA_3j=GDvdmVtqR!LL{31GsGRQL%u`Px`jL
z_3gaq*C}$K&dBiOYZkw5o&z4;!5W^Or+qt*`|z)i;_%^LZ{^c@%ZKro2XnB1XQ#+X
z&{@l#mS;;ZfrdSOm_t-7d@YZaZt>`3f6We>#`5T72cM~P@F}xLw}3~d7`W#n@WZ3i
zN9>13Zy1M1^P?Xgn%6uuKQO*)e)gmJA4idR^Rpj@CmlOaG#}*f>*isw{OH%o!&LOn
zvr|UJ@W4yZiUja@5IjAB1NP-2aJB-4g9gl#FK+mP{a<2bcnLJ6(Fa<k4{QH;bbD)f
zc3$)0UvCIHdxF_pz@wAr0_flbPs^*N4?Q~BUpj&-KUTX%;Hb6bhD7aRKURj9`p{H_
zDDS}Io1ptex>@fo1g$wa?a_J7qgS*=1hnq;D5Q1n(s>?K&_?)ys-Oy+&Yv%?PWkp9
zRCPf%AVXU6;4}YjzNi8%gZc5lL=;>Vce*lwD|2x2Ih-~D?CaO>;OPg+{#a!Dj|d~#
z?*p+P6fUg?Dtx+oz_V*F0-%lnpQoqb2svmLbe_u17hge3I)3~wQ2;r@pwkt+?%kpj
zvcnzf7I66tanCEbd%)vkZxot;ihFckFIV*FX6*vq7@K^Of1eCT^KYh-Jn+t81<<Y_
zP<%qJ2<GntRVm%9b*|hDyFnZBp%(?$UwW~6GH7f6F;Mf?qq_lgI3Q@7G>=E?|B_^n
zZvOulKzGIIF_x}Cly3+d(k6h`l0|!T3xPY}-9ZAN%X#^?IY>4CWUOOveqm$7Sf<lp
z#Q^R^@q6AtXob~xCtuG2yXYn81WVBQ{~=ueU!R5hcQ>eU@lpd+=77Tkw4TJE+fl-!
z^R!E^!+*!-A57)eplz@mphX&P-mDDJYcvfHK)OVwLZHT7r;CaXq_GcLoe92N4l)u6
z3138fgU-7H-Py(8a+!gFq4}41xus+C4_5vb&{@Ae-Mlg-91I@GhaCC$u`oJX9^mhr
zg1Cn{rJGgOg&TGWbA2di*hr@{L`CC;+oW&*J-R&{Ji0qQK-FIB$r25pWET~k?hq9X
zziyU;zO4sJd0&g9P4H|!z~W+gszlwjo5QjBr)23nk8TbR*y-N_B}U-X3K~X*jF+Ow
zf;w`rBR0Vy4q88Y7_?Wzqx0bZAkg*ehd@FvuPy)nA5uPn_a9h*6<c2Hyj)`aV%EfO
z|2uDbbRK&#VInALd;}l-aQFq&63|`Rd~mmjl^A<;gYR~M1at{I$Y{`h`R-tj4i^=D
zNO*&`M(9IjK>H87!=RFo*03=|9=6OuxOCU+{mA_du=_N8I*+|@@`W}g4wra&w0`sG
zJX9h8ngrNo4LWxAzene-5+Tr4YT#QQ;p-njjS0}6DOUD*;Ns>E8>F}~@nU5#y!85<
z;icE$r9&Xc1{l1)2Jhb_fO-@WKAp#0I?wy`vOZ)54RrJR-e3dQr10Yhpxr9uh2oG6
z;AmS9wzz`ICjJ)4PCyqG51($;3ArG*cyRbwKICsn1~qRxAH6sXRS1d_&^dG-9^f5O
z;B)anw;x$PED`nTeDq>AR2}H*W>7mU0KDR-8?@=$ns?JeZiW(F&>k4j!TucG4WOYF
z&^jeX{#MXL(n<z~1_u5X(A_jI4tanEV2*h-|NB?#=+Vu3Zw@%1KCpru$MJ&O6V!SI
zpO5wtR40O4J)o^b;DiWU%>&P`FE)FyGI(}=@a#MSs%bl4zKF_aV(@K!(s`@|bk5j|
z*&yp+YayTuAzGG!G6iHT1Cp5dTbjYQg7LS2?$-og-31!&X#V$)zoiqj2Jqj1{?>&c
zCI9(bK*tk#bn_l`fZi^(1Y}yT=tNcyh8I2_piyGP{y~q<qc2y1YZ+MnVSPIr?BT~O
z5D!a%90)$!xRoDVQ@L`0mSzMPfSO`0Y#<>}7_@?>g+1W4B}!<3n$39DRi6-swmOdT
zw<?30b{oMCg0%O#S$P+LM)g6Pg^$347vA1_ao7zUT`zsWdKf@f1wfj}prtM@Du}5#
z(7`RSFslypx84VhoPj;o0&3;I1f7%%I!|Kid_49ceE2dC(%ysx$4hSzzx96!=)T6r
zS>Q0d#taF=Yi{6BzYVgnn>7a_DGUwZoo=iQFZY3@dU;PXgZ3|gywrLCbkMAoN3ZA^
zkRhE1Uu3#~e9HRD4&*#-Mvu;eC4wHH{bNmk|Nnm}4f8*|r_;^5-;SFBbPh36dlNjy
z0@~8yYIxwKJa|o|3-W$RSknNc#1nE=#>*ezNmfYu0M$1RKE1pq7a<*T#DORAAZH@2
zm@@&@RG>~MczgxY@OZJ;5tQvqJVDW9;n6KC2`YswZ<c6+@+RMlX>MR?E3h>9P?R@2
zzWfL0WN=OC5PcXlY6RYUWq9)SUC4aV5eLM5pdQ_<sx!f1f0+pq_ED~&uz!6JQof_K
zw;SKA0MArp33zs1^X)tWnmPk5K7}o(_duQ(X?@Gz=g9^-XWdHzwB8s|h)D3aw1V>B
zTSkzYU2F^t&41<j`z_fR7(iu=0Dp@(3j@Q8mk!`&A}B}#_*+0{sDiv1@FLR@E}p^P
zVh^&ScaF*e(7ERaCU_iY0j;!U08Qju9<Bdi_|3E1=bHl76b?Ep_C>V-G&8Y$=5N^p
zno?;##%TGq{sibW=$0R#?E$@z(P^LFJ>YhkPcLMxu21h8$dtr!$kFEvpyKVgiwekC
z29T@4rvTM}Sm4T_0>p~&?fmHrx|RNwPv^rIX)d7n<8LVd+1uR%UNrxr6XI|FmfaxH
zUfYiU><r)|{5?94eO|`jS_vwix*_A^pwnnPta;ngIT-j`62OroTA9wl@M4cW#N>Y<
zGhm84K{pswgW5vy@&MH8Szr$;a*ui*d~5H?c+~UaU;dU9CeSIDpjcVV!oXm7z_;}+
z=s0OmAoKTqV+Jkvf~0Tc@b<JkTKe9zw@$<Gn@{Hw6$bEHB0mYkx1f*%jnR5`{^|Vw
zn#HsEhyd;gc?G&J9F&_`UYA6Ju3Y`$k$l~82k4#yAI4vfnm=CbI1RoV$PTn+nDK|F
z<y-!i4NMFSy%mfeGd#O_RF1W<fNaxg{12+2>Of_b=QMB{*ZafH0BY%%Ik7SretRvR
z21+lWnSTb4=3|VWmS6e%8o;5;^BI)E9)UN2-T|dv&@SW4p!P?vtu-SD!%oo7L`Zx<
z?^CnY0ts_~(f~M`z~fCGy|&UIVT9_|4saxac7(v1`I?I0O|Gq=4*CSc|GlpNJ$g$H
zbG+sSwZFkv=URR)Q3qY((t5JwJ=jSvK~4fmfp<)QE`0>AKS47+po#$GeCQ4l@S0xG
z&2yl(wjAiL9Z)&|k1m6PnF-YDa{@JgL56ky@Mt^&%H_Dmk3f1~nuEp?!0l;hw;$SL
z$vX);(SpBK98|&@Le?9A&ohO}$DM`9fB*CU|4Y!QfJZm$I?y)1UeW0Pkf^y0O8v0r
zkm3KA;QP)YYt3Jpf$po#vPES7lB=NN4SWRJ%kRJc|2O>hTEOEt3p_?Gzt-*X=!Qh*
zb8yH#1ce+ZGH-w;?i?5(S2?(-IDmRx;DAfM3MytYK&Nzown2in2!PsR-7YE>;8~Sd
zbALgWh8*W_3HbN_zeCG6{ua=3DbP{Ddl!L@VLJX2bi>+<43Jm4S&vQzr@h_(ARhc>
z&&u#p6nx73M^Iq;bVIVr3rQPR2Jc=UT?U`d|J@-f4nDn(j6RkJpu3-wFS)k9b?JP2
ztVINrxWTPRu*doPu7Ud4y)7yraab+|l{FbJK?hTMbhA1`To3?tK?TSKlR<~Ib{+tg
z{}9<KsO&6|Z0X<s|M!6_Bv^s=5@ZYL+|eRys53o!0~tLm5A6b#d;G1@poR_95uoid
z3?7}wJ(3T3cKe)@faG3iw$$x)V)RJ9<^jsfA3SD2MeSZZIu6d&F})%NFZn<>8y7J(
z{sU!T{(kE}|Np<<<k8LAGzlD(?tj>!2VktVV`X^h4r&W@v!+5Mf5Rmw*g=M^z`^wL
z(I3!g)LZ_(c_8J`8sp_R@N&2sl>pERA5e6_^94J9YY9jtWEG3ye^Bm#rOTI7VJ!iV
zZq~OG!H%+m+be-$Z`Pmx{}JO6;QOJ#JBE5$e}83X@ag5fc^Whe1!_R}^s-9*1zmRx
zUWo!C;Kx86cTp(-b-Y389lRbB6v5yVZNR6VSb%yP;0gwGYQXgb4sZnoZb?87`6;#p
zRS2cv`{%*u@<2<6Ik5d>AV-0FUooHqh*7UehTNyh%xL%xwD*YvmIDv-w}4LU1(g96
z;0;!wRTH2g!3@xhcL7N49hD#dL7lC`{H>tXfuO9F;L*(pS;>3@+*lVZZNzmr5ZFDC
z4Pc;Kd-&xUUM#i&uV(rA8x&3lU)Vt0!rx*68e{C`eFhTm6@B!ZodKMK559=9fR-1B
zK|z+l-vUZp;I#b`bfy`^MZKcef3q{V8XkC|3{hU<<k4;50qa%@@VA0bf#`<yj$eYd
zb9i*KF6;-#eHqBsZjKjnAjg3YdU^?({DT<XtjSnn1nNfew@v|NRHP<9c%uvCgv694
zP+u9cB<AH#usX26Umpe40*Lej8oz;T@Al|r&HBy`TH^HI82b{Z0*_u+PmmJmJPRnJ
zg2JG}qnFhfBo3W+=Wlris+2&pdZ2|)1wOs3Mqp{sAUQ|_w37-d20`fzyyQvYg`znq
zMe(;l+9RMP8P=?olR;-VfQ~u`jRMJnn<w3(&q3FwSzavReW41~(+X~u_^5aoUV3rz
z9%PmWbl3KaJs=LKS~|?%G6%HOxk9G-zaW1LWDksw3bb1U$_9v@3aHBNJoI7%8?-5R
z46?KV+ztjE3=U~*fclfjqq(3K#fuu4p2Petp!;c{cc-d?*1C6lNVtOf3lfm+fc0{q
zHAVFjz3!kb2mEcI?rg6+c-ukSQ}AF9BY!Js=>upn5`QZ=&!A25yaTTpIqBJX12iZ8
z@daNwXe)#sW2q8ibnLa5M>p%lUP!w738^!VS%Nyz+Ki<F9`NJ?X`h4Vdq9>#2J9HX
zQ#G#;rWqc1eGjyit7QwQ#r=vA?6#I`puqyrsp{Qs3XaV$nS7Hkf=;yUW;x+)$#MZQ
zR|U>KA75mbeg6+${sFNMl)EFqQlC11zKBa@VnEt@3Thw0)~CIc{Rck3w3oN}2gnmH
zpzGRQR1#bbPl7kBfnoyMcTfP)pk+7-pld|Hr<@qPXrA^9bp8+8D$Dzz_7!SJA9SfU
z=mg~!(DDsXr5?fH(fNZPx|8zf3$59V3@@*PdwZbum%Y3;U)UL5$Uw5WN9Xa9GLK$S
zCXgFD556!p0}TN3dvvm{HUPx{^wvD_5_ix(!<If!Z~HQ+Ku3&Mv%c*HsTBPM$}-&?
zFQhC${im0yU>iZ_JIwsf&Hz5+7nG9`^DiFVtnLQf46m1g#uq`uM?nTJL8o6rCVWAo
zTQ7zFgNDo?vxJ~%@=QJno-AZJRgw-*L#Il<|9`n1JWm3;pAj0X(CGBEWGL|g->r57
zG}bi_q!x4|5mI}RRTbiXm(QSR;&>5d4tD=iu!$h|pZLbk0PgIA-QUZ55X9F87g4Mq
zyTE=g`vlP|2hp1e)(dJ)p|218!NkD8uen9#0+`;T@&L5K_M~IyIgie({C#ZTQh}+v
zLIQNL*cv7V2FG3*3)j{Ij-a96TL)jsw_Jj3hqL_6-wVE14SE%uM|XgNPx5ilP8^Uw
z`{LLb9KoYLps6y@Bx!emgyk<t9pu>S_s^%-Rluj$=d6H7w}*n^f!6}?_-sDFXnCkE
z!tyYG%VH)52A^)3gFcor$4Wr!aG4>#Wq`)Cff*>I_%)#3(SUfzqwxsHmpIzbzLp0|
z+&#NN2fcGx2T1U@fVyKI-K;A*!2y~24HA%7O+iM#UhL7$>IRX~`o_-S*!dIGd-(y8
zY)j*R|IM-2?Y~dAZEGaxO4Bz!y*WoYJUU;b@oW5p<X4Yw4j;=(juMqLevR{>vfSgv
z%449-qk7;~a~@^f9^C?<4T(P8RUDwrETB%@DM*3onS9Qp^VN%+3&9I__*+2BFhLbW
zfJf&mm(Gvi^SWGAJYHl}gD#A7Q33CBPWDjnNj}v4iqS9Gr6s_tv**YKMg|5i{`Eaa
zKu41`|N38gAGCP|B<cxSH3c4?fX$J@OLnmFAu0+!pp&Eyz1aK|><W+0V<mMy-K<k0
zI2b@>=)o6JEl`Q$CGj4~w?Pr=aquzoYh`Hv#9sllZ^*Ox2!}^Ei-ZUNdKO6!Mt1>U
z%cmt-p4}oUu7(F3cY;n4^8hbQWs&gcWRV25<uASft@f+j3z;AXT`C7ETuayu54;53
zh>TpuzWfeuDY8Cl2gjoS7f3Afn}A~R<t?xz_|ym3?k#ct)+1n1(C(}f6%UV2(2{J>
zWRAzn)nEzMX%Mq+L$l>!W3X9$U`hBw-7HY6r(5Kp52MJjmkxjb|3_ZEcBBEcM>T<8
zvqq($^`s+cdi1JG=P^(SgU6Wp`zk=)X2<^?o!31(FM=i>dt(l9cy=>(2S|8yJAn5}
zf#L~e>k=rDKzB$TEdAukc)_>z0BD*xg1-YaGz_{+*3<H4=}u7U^yxNz9R^C7Z$T*%
zRDO7N`!e`g7IKtGgA(Km*(3k|r}66@E8_v(A_7T=1stBuM>#w#@0MPIrNc9zbQm}v
z9MSwO6F~KSa)1ITErQRv#*u(_fI2XsSw!%`485S$jGZB%m6V5Gq&^0l1>Usj2(AoS
zox)%#ilYfE30_79Iug*MTimzXM@69<G?3+_0BRBlf@;&3j6S_CCpbX+8yS$w572eI
z9zT3650rlL?BsL=4fZ^IVR8-J^X&j_`u6O0QPJ?}X7K1{@AiNM^hy2}(5ev7JPmwP
z8YKOq><{zgUw^@)`8bCsV~C1?hvj{K@JV-`-7G4Q1~ueJ5fK&s7SQMnXp?OMzebHp
zfk*S321J2$7!*$o$T8RH1}V;!TEXeJ99o?F8-mi@>+Rq*qM&7e@O7Aw<tJRAk`*$z
zZFu1I1aLsS1g*vZTkz5kynHW2g#)xf!2@(j2yB0161ZYx-P{7U?#Bm6c6nd`vhF45
zf>e0@gfjlv{Kmqw^NeHX^%qBVA#G34?Lt1C4_}mm`JSD}I*;;qRDjdR3GiHdjy|;Y
zf1JN19W+FE+qLyusnko*bQ~x>f|{ubptIsE@ACJp2emFbZ~1^$Qr>;xs0-D4ti%qI
z5DhU8dIW7ExA+5Ey~c7MR6LZfLzD|1-7NP(ca<&x?Vh#hb^h<s`Ol*_<~YY|A-MlM
znvZdKSl%m<^yuaT4^X@V4N!nYLH$k3d!^4oMbSDvP{=@L!I0Kvg4W+R|Cg_ias?fo
z_{*j9<BJ~9Vf~%Q48h*ydaVWVTAh+dH_v@ozY8>LB3SwqV$os7{{aS;ckAzg>~Yfr
z4Viy<Jr(XgP@&KXHhB@Kr`&n$^%9S6)=y2~h--&NoVq^9dEf;&h6i4Tf<|dvAVQwt
zlgg0B)4}(f_42yzfeeQu&fCiVz|H_V`-%Y^2awZH=7X*iL+f>{)`G84<LeGlaRGI*
zJYHM{6^o$DywK81gh#Jv<#CW*y!;<P9lVpSh6g~afW9&_FuX|Dg2wP+{+0-S28I`L
zp!K<(H($uXqW&m<i#<PR3|mw=2sAv-x+WOZwZ7=l=~VF|Knt7*JJdm1llhq#Ud$6`
zV({qZJzdYu@WKcx`=1Zgicr;W0v(C*@P#x~_yr%xSk?=TphXD>K{d0%i~pJs1J6L@
zR2txN7B3z{<u-tg)75AN8TazV8L03~u(0Vwu<*whTcN^DV3T;=f;bpnEQE^XfyHDG
zK|G`lqCoSt&5-^ORM7&kB3oau>`#x*`C!>NsO&PZZMOVDphXNnJ)yD=P}%ihy|Np@
zdT)Ak?gr~sg39gy%bFU41M;Is=RUA33sm+XSk|@`9P>YYI`@NRpJ_k><`h_#RU9mP
z(5DkTD*WOERQ57NRud%KEgA%(K-UgV02{Fws^}_M5$_SueQDjSe?e4dBUnWvRK+cb
ziXf0wH!C;T7>J5^sEYd#72rG9I%k44yFjI0L!_31bwQ*wp;F%=f%XbyZZEI$J9Y-&
z&IcZyw;UV$LDQ?CDOFfV_NlWn_<+_Sw+ApXFuZuK4)OjSKG5!5(1OBV-p6lY`aL_{
zD}1_bHwADoU@^)W)u=g8qd>6$s)s5(x_M^=fU0Qs3J<7XDxhk1L;SMSADr@;K<<VH
zRTxyo0f>s{U@3@it)WtoG|c-3EVU6FMhZ}=8xUQB;4p$nu|lPuK%|Z#>3XFG@%#sf
z)NUlH^H8Zj5UCAFQd^)>9N^r`8w&D6=T5LQW<sT`AyQmOQgu+NpI`%J&-;PSR0Nep
zy}ZS5Km$&{V5#|yDyXEq>CxE?jv-g5Mpw{C4Ct~Ek8WN=kip#!6&?_KJvyB$UdTe#
zJp)_7E9VCeT6Yiy4cgzT5br_~5~~hKs$2Fc=pM3O-gmFr!H2t9fY($&a%>W+OLjx`
zUjo|zS~uLydmN-2>=Ne+k8ai*ATHFp9;k9i&XVQz2l<$F8AwGhZ#~F5&}~zz!2$O}
z1>|S2hdsL?r%Hhf4p7U*v)eVmqtiLSv)i=->{DZ?!85?_kTroA><cki4Q%iypU%x-
zgXbd~+y*kv1Ib`FsKIU!gKw!o0w@h^Fz;`00I`~Y42Jq?2UJBiM8!*xR5z;=h=Qt^
z2364jR>ArlB-L&D!3z`{vYg%^%61Wm*VzW{Kz4rg=xm3un!!{zYcWVqXESKQ(+hW~
zadMoXGM#sa7YD-&W2hJxNUZbb3uP$(7x;cT-Ys6BfL7h>3o1buf>t2BV1%l;0aDTV
z^TkJHh(}LwfGQAOBanN#S*5)}I$nBqx>me64^^=Yq@$Zx0c7uPsMsX1F4HrfAmtx@
zJC}j&m<yFH0qN-Fy|;~x!SK=xP`T#OE2{qrG-!Inv-1FG1?nz!&;b=XDvbOsp1ceU
zFS69Zl_h_x9$2rBipL9mJJ88H{2gjwyIfSjyBzsFdPP6H1Z9?&FUmlAx>>WUz|Do%
z5K*6Qh8M9QiC*6OFWDJhWGaJ4bgx5X!M1~Xl~y1n-99QF;ARm!sI>xW5_R*=^aC~2
zU#tSj_lmAT)5Z)E#?S_Cn!eyy1KZS&rsV=i7*h*_0t3T~JD}XvE1HC+WiD1Nh9_UF
zfvC4aQ=f}fJ;YU&5G_1tTCA{Z0gaWtaD!-h@d6yo@E~Kyt_5_G_X}Z&mV;<ou7HFw
z{SKPPeDMI3Eqg`hp=nu&U5fx{y~tXKmNGOgdDyjp4kvq21<~S<ro|e&7SQB6IKO%H
zifW)~;lQp19AY96TNu%_Tm=bZdLPtreDM&HF0VXC4dg}GwSfJy4x(ilnwEU5S`1IV
zsDr4lLsM^$Rekfx|1W$Y8sgA2@L|>9(aoCc4!TEJ)DEH^v{TKq^T3PyAX7ja(R)R8
zo`drI2T+DT2^M8$^yy|@<_gv(0nzqiJy?dF(W6(C2dw@ENc~J@Pyyk}01`HR1Zs`E
z00}oKgAO2NoeVMJ*)vG!H8U{2$N+0#1F66945S`xZICi6!;4g9R@fSc!!I(Fz}fUL
zSnDxx>c06x8|(%>M$l|EY>O3mRm2NRh;o*jAe&&y|9}LW(UgNz0vAZ8S2P#J^s^vA
ztjcdIf*s?AqI@1U<={lK2BKUNMR`6><+TvyU!Nko-2t0&a7F0{QGNnNxgbvE@(|?<
zQItOd38H(IL4bkb#RmnjS4&WoZ^o(oAVhf(it-k$%0bI{CP9>|q9_l=sXQ5?oB>6-
z8aCzNa5sS{zx)I_AiskI(Y*>z1gs#LUeS#x%1?j<(UgPECw>CTBH$#y46Fj}n#o??
z#wY9yFDA)=LXWo|Y$U6X1UJKrdWcXRM92^%lmii}f(VI$gd$Odev5N6yl{gE6+u)z
z00|jGg!bJ7d64xeNJs%96a!JU3M9k}5n2XO)ejQ-B@K3$HAGbjNa#68sM&V8IH<MS
z$r>RJnzRcCb-bHxyFh{^z8=lC6=0ULN3(4jm}TkFZ0iGN>3cNWT7g-r9?iBIV3xE;
zv#l7IB?uZ*;Q<u|`stt%)Do^2dh+15Ly4eA^N|R|K$K(rVUKRs-Xd`8V9{g9D9|lA
zR)*KtUwoDW&BU-a6oHP-X7zapI$v2d?g2#2H;|f@FU~{M#6Z+of+TxItw2;a$BRoK
zHLWjJL)2J6)Hs7Adqu@SR5!<qb#kl>FG1&Gyl8<a6ND&J0m=7@zP}H#t{tQdv_JJl
zEJWF>La?h?A<9lbl_h|b34lgF%pl4RLzKM%$@hvb1X0}_FDyaIUjF<4{{=rp*&K+n
zt04Ja(JBzt&GAAAr0ft#*$Y{4P?SQHZ3oHsiUxzIZjKkPWmy?sf=&Q>aS)=+529=V
zNWNE82Sjyqyf^|<Rsu3@7DSmkL|GF^zE_kLM0In#m<v+o3sP1LQN{pKmI{*Z6}<;a
zSKS;h%0SB0K+1d|%5D~b1H>7kY&%q$KS&wq8sHbI5M`Sn$`m2WCP0;GfRx<;9S`{r
zlzh8cyCKTJj_MW7geqeMDccBAb{(QD1)}T`NWNFp2}E^sytpO9%J8xaq-+C3nJq-w
z0g!yJs5FS`=6JCgq%0YvtP`S445DliNWNF}%Uwv+_kfhyfRrUcl)cXf`?Lk3>?~AS
zDoB|qNSQT6*$IfUbcnKLP-S)?W$*s{|NlY+qHG~VnHxk|Jye-ENZE0avbUg|+Ra)8
zQKkk_76DcEL7J7}<pPkhV-RJ*5M?Y7Wrk2?Cqc?8LCWSsl<7c}JqF45igJOdZjKj=
zK+1wZ$|@krSRu+zgXDWfAK!rlNHs{AHb_|@MA^MOaDdE*DBA;776MYn0#c?0QMMhT
ztP7%SDpZ*+NZH-r|Np;WhA5i=QI-c$mIqbF22!>Sr0k9qI4@*El=(rFxkHuRmttjj
z*$+~-6{5@uqD&v6OaZEF2S`~4NLe35nKVS12t?V>+Yp~l1SxX_DNBba`;rUx=@*bO
zy`q<(%CbPpq(I6XAj-}{lwE}=TMbp_3{v(Pe8Lla6#eD$PyheF;Dl(K2GO<{qOAm~
zjR&M{&#(XgCqRHlcOz(_jz{-I(4@Zy<3#YHFVGnz){USESC3AxJpY^n{M!zI&Wq`8
z1Pv~EbWhv>D&H9=f_vB96TzF%87G3K<UmVhJ**qS26ci}Lv@43$AkH|IkI|o9_Wo=
z>}6>Mtz$g+fY~GYf_JYA1G`7_gC8D{383B>Mh(wyXAaPr8@`>v93|?$z1{*I$+ry;
zc=n3igpVhCcJmzcVB|RjveeV^K<RtK1HRV6{BsU~mL$6{FocJJZS?3o<kB0!gs|1|
z;3JlU514&GM>)9&fo=9-1Z~mrf!XZQTfpeqS<C^shyclUo}0eiEC+oUSq_3M1sw|Y
z-qYH+Ce1hbl6S9(FlfBqr#DQ%vzO<VM{flq=!C*L4%mE-Z#T;!B(3%DJ*@3&13(ju
zp2wX*y(9+11D=exJQ+b=bO8;|@f`B(<bhdL{~kOE1zMZ|vh$N?@*y9_8y?*i93H*l
zj2_kk9-RRkHEf0lz$&07zCMju?}IhIUHG>-vVc8<8tFZYKylpN2#(zDiJ<i?9?Zyb
z3{C@`5cy89M6I01ad3)(jJt!A6WGazVe`k0FF=NZj#BAv`~YGyg9k%BtS5pe;5#RR
z<skzrwFbzh9S2(kF&LJ-KnV`ne8=V=%yk7G-4ns*<@7d!PX6)f^<wnso(Q_P(t~*-
zcukpQCs?Ah6RfNgELiXC*c<T2r<W(l^WZ}kPsW3<mD478G#@YkZCLW@bz<}Y-6YK%
zpx|T8;M3{A;n5kOP{Z$Od9d`B;Q`qFuAtsU^UH?U+|d1GpoIjU%`Xf*k2`>4*RwM~
z!PD|Y>2vU<E1>foz&Qk8esba8<_U`(<V@8AI;!2H8yucK(6H>D2wFhr!`#RLnzLe_
z2=XN~Vj-amQQZlV?*z-&%6l9KI|3B4KAnxA91RXq4@i_A_UH!RvFy{`2nsuo?unqG
zA0OsM@YXTriJ$>Xs2$)S?u4lBgvfV-<!ddF?C>}ab_J4kK5z$t;?o1-F0dO8JMwQk
z*!+W;zYkm*bx+Iy&#rcYC+d0|K^HjqFn4x<1t)?g>U<a{g6DIa4>5XJP6Ww&bV4+B
zf|b>mxbz16@jUp5&6n}eYfaBy2M2Kcc6$i;FnVbCfM!se4>9^MdKiH6lBacmLk+iQ
z=K){K3#FF~4;=RG_Q(L;0@Mpmfv;J7x;->JnqN8ibb4ucbbA>1SRV2??gWl&k4`Ux
z()-{=I6j>RUY`V&f5`Jm{M!my`L|WF^s;OP6@<NUOdg$|Tzb<O4?bW%_?QJ!Hkl#H
zrf)vIA)r#xiNmKig3-4#ii5wU9<=4R*Gs@R`HA5H?_QpV7-f^MrBpp=A%kD93}{su
zgKw{nlxMdqhi7lDfLE`NEQ3#P0i)po-_BAFetFPn@KFZj0_vTwWhq0Qg(uWczKk~w
z5BPv~2zJ8DKSZGv3qSJ;Uf%V_$TD~ye8LPW%zb-{1-yHC)O^6jqHkw4#{}PQmSafP
zmA?12wyr5_{?A;O<<YBi6?9T=uN$K$<88;ipfweqy*%1Jy(ULNX$L%?4K}v(4!C#*
z`vZIlMlnZ;IHbJ62o6xOSq-`c!;|s02jfi_%lD<b4G+Au2hA<R{rJ%HxGOjceHfo2
zybJQSPp8XK@MaKDx&Q1XGiXb?wG@BPFVKW{@@>yv9x2esA|yXBdUQH+)P}>t?&Z~g
z|Nr~<`WOp%e7_AXA3PcFfOm$1Zu$n>=-bPpQzC^@zj=1@K+nHDRQlf6@=@ujm))TC
z-n}xCAn$|h^0Z|3>~!Yf?*ldPVfKMDkjHUHu(>Z|A?xR`*7w~LLHlt%7$<`3c3ibT
zDE)d6QU6103Xn036T!pV*jfXS_yIKsK*t_?bRP2P4H07ZO+Mk)>*Bxy+A;3JcmUKm
znBl>A0iN=Gdz}QldqqxwasVjNMsaw8cCf=+00-;AEdVM0IiMohfgvo|g@0Qlt7ES-
zqjztJG`mmo0moh!XR!Hxy*%KA<idCZW{(G`_V)m{JAy&>aDiF@pc=fG1L9uKZk|I(
z?F~@<ZCn%U+8fLSYEk$mUjkL$-A)|7y-}c~&JEG;*;xeD@7v9D*oP5PpL<#!0J+xF
z+Nf5+16o&uQX9`fpH6s-2A;VNgVQ_K`r88~{*dbnaG?op!olhbP;Kth-3YGDyTR=@
zALd4IxyuZREl|W+HzL*TKAjNxPOv<<z5q2E85kHCd^*A9AS9`Eg3}MEz5vzX7<Ce8
z$jO6wBDiXT*nwInf#o~F^5FUcW`_r&;)hy?a1c1bLfi#*1ERiY2DL39?Es(dPEgI{
z18oj4cY^9MpYDkoplX8=T%CbV1n{r~*M}aR;KqYbCs<j1dGiYvpI#9M&x4OxU{waB
zNdT!b6p*S64QQ2NfL>*Q)*}1#f?L$!Dnr4e`IUiBr<a09w}%F5m7!63|D_>l85XF@
zm=KIF!};`ff@2BV?#7kxAk8~yQ@p1U94_D**rR(Qs0HTJI}=2CFoJ{L1JZ`@V1xul
z_e5~CfZ~f094;Q#jY!c}Yv<7oX-pv65FU^=ghw~H_2mIgJl&0uwpJskL;%NCG^9TP
ziUp7Encz6-1-HaJ7-xdp7Tq&JEe#LGncyZy_e{{_m<Ook$T$;pW{QV3q)pe`2#Q^g
zPH=qk_jG~|aRoOS_Jfv3_j>&CY(B{7dGH|{s7=S|X?c*pWhp2Snh!v$eg^>`Mh6X_
zZU+e;Mh63*ZU+TWa`0hvuz<FxYft$=>U&Tz1+DO5wLB>Hpmjf}!uRO*u<+>gvM9a&
zQXI4@2`N|*%^t%8p4}mbBs@Dq4objShb2G-xkvL4=F&&t;CXrH-~a!H2SA~OXul)3
zA6)pi1+wyQ%Vcrvbz=1IbrE9s>Adcde8I8T#file)R*d&0i7zy;KFzTT)_D-9)Ndm
zKsBakFOMXwfGXwymoI4bWj(lS6XV!?2wc8-CV%qnRWSxl^mF+3hNuYm_OeL%^k#tD
z4>>9vX%l?Ac@Ft9!t1O0_rBITDz&<Z&W&$3&jBB79U4U2!M9h$#1mYGW(oKrw@`{e
z?S-1748Dvu@D9;CUu&b9EEoQ5ZylTeGS@|V^y>TtwHiDbKRND$HW{=K;Ri9-OTee|
zx=(Kc*xgAS7@qdER;qD#1a0AC{N%y-(be*6=`q6tFT=o%1b8>?xQhz7YV`#znCuie
z2%-^Z)gP*V{!#&y0>0n#WV{J$4|y<t2c37%qVI9s9jqDDfkmp|>)(4?{w}@w@)>x!
zH>m!C)R2(AGN=y=?#f0mIv#w$45@NX_<;J(psJ_&!4F@?6JDS?%#-mJs3p|x!~u$6
zQ2kSq=?iWr-Uhc5Z$jH2XkIUU52}r<JP$r*M$|}ty)M!Mz92t1Fkm<roK&OZVErFZ
z&+{<IjBhagpk2a<@b|#hn}iflpdtpP+JW{zYNe4oft^TQO3?lQNdE_1DnR={c>0t4
zJ)rZEz<tC#f_+45EPce9eDpq|BB36lEux1A+Ajd9FQJ7ZIPj2thp6eG{bi#2lVGC`
zPavW{h}=FvD#;OjFi@wlRt>4chOJWwO+QrV8}j#n8lUif9;nv$puC^Q-w$f%Aoulj
zLG4$f`g>mB{@x*Qe-9}bkov9Q(1r#JBH+M{C`jiOmLEv&E`m)y4C*hQ0J#^j{u<Pb
zb>ZKZ$kNL)7u;PeX7cE~)mshjEk1+x7NyxelD~n5(ZGXQw;`o{uZ}TjVJ&DV&8IVz
zgTG}FXmB9;zfZ5P0H`q1`OCn-z~J4>qX{a%(T28stV0=Ut^9j^v;`1_I3hoT`b55n
zu3#yAd<t5eANJ`DF=g;L_?#J1@@5Hm_WIbu`<z7_zTGY;9nR8szLrLHroO!))^H0w
z8Gm{}J7l2tG0Q>UPL@OHHa~ye;>y464Y(G_gZCYs89@~RXdga<XD^QytnY}_zjEU6
z>AVgq8a;X=K!bIlOBAE<^&h2bWE`81fXoF~4NpP+N5mY|VgFtqF#(V7pev+7`5jc=
zgSI6?i+i757X1=wMEIeVr={TH|J2KEp#Gh8C_{}2IQ&3i2WlO7S~7WdI&tv#fp+r1
zq63^_VBzz!5p-b<v@-#|#~hT35cUOobUP}5%3D@Yk!g6q!#YsHqcc#UHr|nc8|kC6
zilAl$d{mZS9$Y^l^^dTP$AVk{YPo<s<Y5guI>}LizZZ185&t%{QCesn2N?+=FiHz5
zM37v=a}!&822{Tp*F@tTs>M1)YmRM*7UEwV<Fk<dBB(x$KMWdlc!qVXw)P$@8X-F~
zp@9P(?}G$R4Hsg35!(Or>23s#*ZVMndtZ={1otjr<Mll}pgaz#Y@wY!ST7Hwo`v?N
z_<JC`;lN!3Xy?rbTA4!hpw<?kegS{aY4A=(X8u0VhFTw3f2$GPB8T<2z~hF#y<Uty
zDC4d^onVQ2i{@7>NW-q+209n0<pdjh1>Kay3~7`@8{|Hn4hpr`K&^4mU@IRYeM1`W
zuMFU=^G+uP56e@f&%wFm@C2mF7TTADNWj}?NTb(?${4B?8c?q{BkTjk7gB`^i7@_N
z(CJC|dTt)jE*m6VQATxRArXhQ2Mz8z6E~{M-vd5+new4q{vObU%8t!Hnfd!bmvMP?
zH$ui>C!&nOP6Um?dUS)wU_D@Cum>1DEWu;69-R<PonU4B{h&UeYi}TY9M%vP{zTQ!
zS>XB^G9HV)e#Tcd!y+6sHo}0U9jXT`4Q+ZJp5WUZfHvG403GfP!am&ldI6~JJ_GX)
za(@k!RzTyun1vtcVn6<Ew-7bEOK&nty^dP;VT=MVM;`@-*KZi@d(d!jwny?eq~TyA
zoWsEmIL3qd`#}3$VB?J7F=1$X5Uo~*k6t0|G64<l7NS(ppRo<@f_5B%=D(add|~6e
z@cKC#U;Ql2-vb)fgN*Th_F()78sps#E{LIx5~Ta+e0yU|Ngbc&@3jPX1R<mRzKleV
z7K1L6^979-KL?K%fAj3+F+v|Lj)aBkOVCg*bhH@Mn1F@{;}=8FG^HoJ^GVcraT%yR
z(JNz!F<zVxZZ1H40!jI>@nR3~croZ4F-HYP`1y5Vum*%DE2P$em3W~0YCvsx|6U(X
z_TB(S&*q0ee3B3Kh6J#9K?m#^4;_5O?2&xQhw+q4uLqMyZ;YUZ<H3h4zR4#&8E<-a
zJ97B;1`2rgiWtF0cOyZgyQt%>zSfepT0Y=GbZ9Hb@PJ1*Vv-a*s0#K;blhRk`Bc$y
zhbIs$ubm-<E~v`@tt~ys8X8r=QNMUVhemPs&p?$akz=FS`%9p~HA==gA^jz^u}-ZC
zp1lr)2RqUFOQ0Scs7HY`ZVQeO)LIl8Bp#5#TcrLHX=9~elM($TNEsW5(thIaO@l-)
zQl0A43mN)k1P@;NbT@+MO&P%>mOkB(8R_N&j6RHzQA^Y@PiykWJP*S=%+LW(@F24f
zWWdu0GT`Y08SwOh40!tVIxzY`20VSNVeKkV^U4P@(aPV`4QqncgRXe(^+Fl%Wc9Q>
z2s-JT__5A&h_O!4{4`{G6W*S(Jmi6Ov=b5!6ATX=MygVgdd#4MB@Ti{t3A6z4oY}H
zM?MdN#y}6Dk9;0R<X1%h7ZS6XEd1Ll(TW}?Mg|54{%yxW^GLk~OrFUXz*9&EpRs^C
z!|*ZC13tYj_Uzz+P|)BgY%mmQK+{JBv}!{V)KLb_ErqCn#v4)k!=Uj@5tUji-(DYS
zc=y!s0K&b5>c7LNgPSgh>DM9-P*2Ub+Xpnhi5Nfyk8c*xV0<$eV|){-6YJX>g6uzd
zZ37zLJ>c8PbI2EM829;0VNi=5Jl09<80SOq`1WCbd8GZEpyfJ|te}x?7LVqG8ZNy&
zb3ub0jt3tydnO<B>GhFjZ$8X)@G%Rhe(^}Y?a6o$v|#3>YwM*FHGX*p7tletzTJ@=
zE}hpv6_h9AO&85$j+Tdfl8^ay#vJ-le-~6Qz|X6D-3JPFMErrf#$fB65bKkCl23rw
zCpk7BU~)Y8fCVzZa>BLcl1Hx(qlP2@wnHAhE{A@UXgc-={rBuV?3;YR<KQD^PtD7|
zz1}~-rx7*3;P7EQ2$~=Au{=@w<}-AB58Zy~d?nZgpuMuq2Q}PK!@wUD29C{#nH-^^
z;0q1~PexD}l*+$$^Mv>wbXK?KF<-`;u9k;9l8<?SJYT2j1PY&)1C_TtyCprfBRO0c
zFMt$!%<yHr>Cya}5u~_N=1~20@Q|(p!^`ad|NkS^pJ?&Z%W@kWC%r63L5I16BV~ps
z<3VUk77|sUESG%S10)WQD=lbyk<|El2|C{b$vv?6iez!`<v9S3CAVIYvmnQSV#zo8
zl3y>604y$H5eRb83?If5t}VA=F?bjfgT{`%!T&uw55Z&bl5elq4@COF5ts1vgc)Ao
z`DbW+f=*J`aPDQf?ceJn%?=N=2R}f8bHE82YOu&X_<-3L5^e`P8Be&jUV_AK1SoBT
zrnEq@d&AZ86l&~pLSk3KQ#%3@y9XITv3mm&yQe&0u?rcWcnLaZ4JkY!=Np4V)uZ#Y
zQ?E!XDEooiZKu3@LqKcv9{uoOJoSxP!K1fCSfez+quW~nd~}<2n1DxTutKeyNAocQ
z*VY4Gy&|A?I73OUW3R`5k6sork6xcs93J0qc`%-X^^ZKdc?3Kd!6$`ySbiw|@Y(^i
ze$Io@Spjs~7oRz316;6zhjp+-jfmj^kK=CONfQs)p~?&(RTYK|;Ilh!zKFA7fE?`&
zRgg9z*rV|csIu%9^yobO?T|vLJ*XZ5l?)!RxdumtT2qg1$P70lWNxz?JW1)n2p$Rn
z*K8h*M?l6zgX(YaoHL`Nf=72VsKE#^tQkC?-U$||iEMlX>Rozt-faHG=plJP#lfR{
z3Nv_JQg;h8xTg#{ha0p@Tj7PK8ImXKL7r>|*#K@q!EA;1=RCTb!E?3D&EOVeXES6>
z2EyxZ2DM^5n47`l1f9*G_Krs<gx3u=)Pormu+5-)7}Z<w_~^X(Lc@T80d&D7I10F}
zVL=LW3rcy75x#Xu;R_m~^5}F_;O_xVLwa;KgU0Bf!37!f0E^Vrq6L>n^MekL?iOZH
zn-&sAtfoj|r0sFM8P>)GH7lSo10L^#j*odTIx2vQR&e@=&`0u*wH3O5Jh~xq$J`8B
z`Q`zMLXS=euN!O=G}u7?0SDXbE_ir#Ll#Ofg4ZU3C0~LLQGv-r&+mpLLKko<<lpAW
z>eK73(aX{c&ReimsGP8sUXI@mDR}nkF#7by8u<3IoG!KX=q^_9=nZ4^unvXfF=N96
zttU%_(k6IziyZc3gxrs9d9eNi*afh}8VBliANJ@D<?vtxo%&QO0a+y)s^HNXDp8x<
z%fjiCe1Y+VNAd-bdA_|om;HN1E|(}F$~(_)kwc!$BA`394|sNpfTvw857xf`O(;M@
z#Z>@{o$&N(c*zkGxuu~Vj28|*WcKMzQBm;hbzv0nNj}*8lf$#Ogn^@o^WaNnpU&r>
zJ(hwpw74-+Z0mw@1Y|W9s=vVT-79jkSL7<VxKF<Hdd>up_6%Lnx|ByCrmqDwwqL#g
zPpC40&r1ZYH~>e5M=!Yf4JsGhz&BWc$KxP5tkYSc*2bgpFlaUm)WsBG_FxoY1fN#Z
z{6nGi9n9At!@!j#D91B+bVG6-r~rdzM~Iow><Y@DHC2!x0c}d|Em2W`lo1}P8$hE1
zy;GP$HwAn2g02`0vH;zmq5xW;2x4e}SD<z~fSS)L;9DFlUc5F$3adg;Sb-e?Ej^%)
zL&T>~Z#QT$g->rYX!H)W4nc&`lUanpqf>;@vr`1Lw2i|9<iBSypFm0sP@#k2W6=CY
z=gk*Cv_Utbf)4k4an}qM-j8sEH>hYr4{yl488o~>HerOf1fK8)=UPa3gN7BM<qNc2
z1c}sSVGr*g(C|J1>K*nv8F+LD8GwQr65ibo0w9hCr~oo}(E=(HL8tG5YN9M~FoWzx
z4Q9~#$=+^IJ>k>a3|hK^GkhgVLE#HB0g{QDK|z2kd}nCE!?)HH7QUY#;R`G8K&xUP
za{?aFIf3p*aB0g3UfK&W+Ik`=je2xW1eKmOsnEH2pYBdj-R08_Uis_8+zE1v4>P0+
z><s|TiCIHd`*(tu`TKN2RCIz>pe*?I>FflR>tNe_APbH@qqgs1gW?ePg6bg;MzFn5
z$9OP8Dq`sRG)Ax;VDmhz!88BRVFUgi<aJCC(?BW51Ja@QfOP0RART%SXonusnFmdJ
zA+I&BwIaVe5Aq$#`R!0|KnIavQ!ZFT5$w@gaU3H?P?O>F`JEu&!Nw_=J3-mVhZ#Iv
z0h`D}_LEO1L`5f91vrjiZ3>^xPEfi7hbeSI1Kb&bj4y&~Z>V#jGlROYG)B}O5s<r)
z`g2&!1C5@59D{GoJ0ufBCbuBz2(pI+WIC<G8<aT+?T4vl2Z!I`3F!S1O#jyKd`242
zfQ2O_#ey0Xu>1<ioM2;NIrP{|S&Z|JAnRRxy6Ki4z~u*NaaF_lG6d{!2S{ri#s7{9
zkjRA$9M}56N(7R26xFc51Qmd36TsnxWIlMN6g~ZcYhb8-d8j#*ykTBV9GMncIFaBU
ze&}7*;GPC_JtlbzF<r?o#qhWnJv<5XJ(`i{3()5eK=&DWG*@ykRHVCrj%{ZB{r3NV
z$L|Lim>3vJ{T;s@XaIGUSxeF#8y_$TfZFY>nIHfEFEMd!_{9XeV*S(q|0U}DZ7GZl
z42})Im_2$~XMX?xzeL2b;TMZXFRRSA|Nl$aJ$hN2zx@9XI^gUu_#o-4;3}T=-)hiq
zXC{!Nj)3kga$s<5evks5zjbW>p}^k)y3V%T-?jAse@ha`hUOnE{H>rigk!@`M*bE%
z&=H~yKbiPjS-`Acj2^wLl|TOfFPY-eD>~ug|NkDntdc+f{|CF4-}MmqW<$s39}fI2
zmmtehUHDr;1q{SIKd>nv^F+Wbuz8-K(@t9)K*MRhqCL;RW*!9{#Rv)kkeRCByag$*
zA?Bokb%V^&0kgp76#o4GpT7mt$PwLg9c<28WVhV~wSQVK@waRSAJ@zp0Sld%he2~c
z;P$m+1K2FlPaw0_fR3wO0Fr}`cR=iS1KSF+p9jnW>-qQ#q^AO8Nv|l&J+S?Me<Otr
zXh#A>Kj>^@$A+Iwr2$a;O2K+<AbKrMfb|w4>s16de;gP*x>@&{fcJYVt%7W`eD#2Z
z!SKLK2CxE98Ue)->q(GX-hfVZ>lLjy12(Vm6p~vmf&yLM0jB=xF_8K_5cM9%!Ri^0
zBdK4Asy_7sNPQ1PeZ&>8ddEvh>I+fTm!1QukAbNFaSp70;W;Grj;QKgpMuouK-9l@
z0ah>g97(+(s`^sUdGalP{(uyUT7a&l>}4(dgQWf;NCCpXsn<Z}pMj|FxCzq6y74-a
zdeG&&ppjB&{CovnNz*b1qW%WxB)?wPkI3=Uh-$v-U6A=X5cMw}fXzR656S#MRQ09b
zLF#QF>OF3Q)o=Wcq+Ssu)y;a)h?~I$d<bW+sO1Vs0?@n<P5}RZgU^d@eq-U%&FIp3
zK$U}qfuZ>aM~RJN^8=0&DR8;q3n>@)Rw9=RU>Wd1oxQA6K!$e0N{qA#j*SmMC$~B_
z|6t>9(Pv~}DD!n}{LutjPTtG9{>}gYC42bWR)ey7<BwK|Xyohv|4WuRHvRyma*tlt
zmmvN$$HpI^9PH7{y7JZk|E1QiTOj$Z`3I<&YkdXsf8PK9|I2M%TMu~jvIf5diNyT>
z54vLxl%x-V1-wDU1Sk)K&zkII<$?JGyoVrdf@AX!P_el51xU9XL^rEPFRKVxH}C)d
z|6d<)Z2ST47xc2u16%tYbWLdE4{!s!msRUENbBQ&|Np<92AU6I^)&?Nx2olk;I6t0
z4sOtFHF!NPt1d)-7gRn9A`iN_5hUNsD*5vN|Cf_N*>jsCXr$kh#iLjB%W`%G&~+G~
z`wu`TWp{JDNQ7w21YPR{*{nQa!US;r(FwZlq&Gwbe4S_j=yuTva98ccKhS-9%||Ri
zgX^HsWnc*I7W{VT0DtQe(9{_Jwm=rc1FoRp0<B~Lt*C@dGI%q&^vZxI8hk(lv!F?7
z$AgcVLDNK#uA^`AN#Eq#rG=pJeUIczp8V@C`Y;}H?REO+!+6Vs@q!2ALC`IICGno$
zZ+di|GCTkq|M6gU;&5z!!RW(y%7cGB6G&0%YscQ8f8ZSk{OeEoFrM^acI1c#IT_TS
z?sim&Myii{S#I}=fXCK7k`KLZFg)=3BFgw%H{-z<T+I(a6ZD`sWB~D5(fG`0d?qA5
zcz-l(!lk!R0~QW0z22Y+24+xDcqSkA>5Y+Q_iTRr!;|rFH=`=Zs?OsjK_J&bM*cl!
zfc7CXegMtGg!m*M0-c=g)m+0Mz);HW(Okj7P%7`6eA4h_^Fc-*#uJW~r|MLp(r>}i
zCC|VMG!DDAUh?W?kt^K;ZrHtk)A}FGD0%G3_!-RdY_67ID7n(hBJGiU$pf@E%(J=X
zumJ=ARPdf>!vo(K8%q2j1K7<6HIPQILHQ{8Qi+iV<Hc``ETyWTXfZtSnvZ{bh$9oI
zP1^j3rIa7EiTo|Nl>_o5r2UH2KLUj>H&Xb4c1|O&F95C9N9Kc;cOdgY`q`26gZLas
ze2Dv1K*o4<9)eCmfp^9oe8B861GFv9gYlq8w+ojBs4v9e(d{VU(aGe|?I_{d$#8fA
zXuF#ut4p^aXxafhh33}F10KWo2JI36&7(o)MNWce&K$oTYAE4#?qxXuos0m*;|b6-
zi3j5e&{UUW^CON@EyI(pt+#!X50nV|baQ|vPCI!{fi8u0v^-t^791_G^y}JsyX2j3
z@&#AJldly(^KqTGT{I8-Bp>$Zmhb{iL4hVNd>AjdTAr>u=ElE|h10d=K;=!3ZV6Y$
z8@|a0ygFqLy}peYuY$}+bQ|(-i(~<LiPhoTF%JHgtqcqdu;~(i@V>rYPmO~Qm_0!k
z&CURsZ+NNk87KxzV?7xUfo4>E8Bc*`%vx`k*zxak)Mz<S5#rN%(xun?KX?M|<ZFIV
z{RZ+C|31c+0~KbS_cV`rBp>ta3_0+_lYhOCFXJsw%af&d!TyC#Fiddo6}jyO9f9;s
zzVv#MM>i{v4!D4{TmmT|BX58TNT>!-`KAq)KC~DjZG|j70kk&k8)Jh<=Y>)emtH5v
zUXiJwL1GV3<bh^kK)ZU9FM&#&-VjC$PtfrNEQgTG3yAuIkC=UuK|3lT6E;4KAhuwH
zM=#4E)bSW_LhE%o=m9H#dL2EG(<?~6*TsPilKOgG7&TD!!^gKBz&BiQf-)Y9N9!eU
zT=93rfEv+_4?z*Z-wL__-L*FuoGLwfO+a%33?98Af!?4p*S*&#ipi%}#n2JzP2c28
zPQ5Z`K_hIgj5k3s2ui%5DD+J}>5+WfH~F>`|8^TL&u$qRPsW2@y)2yG-6A63xu))H
zi{|HyuB``3lzqAde3DN#zhw053_0WA(;Z?U;KO*M`R9MX&M9X=8_G)Wf^W1u_*~wj
zw?zdca`3;rM>lWNFLnmdiQo>6&ly0swt**XVE5~F)_}%eUxCI36<%btgU|N{9VKrL
zz9Xdb7U&q~j}Bk{w;rgF+XXu39(0R9LNw?KiVq%*M?irEnQcD|I^?-T06dL>EZPk_
zlg#kI>nETyHZ{SCX6_<LqG7!TN>i`5cyzOtL1et4GOw?KWoAL=S3%`LAZxcIsLKN`
z4Z+FDxATH)Zxkaqm7MYh?YjjPEIy2<z8!`X2bbW*0Vt_4o@jo|QX=A;eA}1thF7o4
z0RhnI8lXsJK;NGR>PxY@8iM9BVY3^qttUNZfTvkYBquoWZ)b5#yZEB{0i#m~3lnJW
z*%dUO04`!(7#Kk5ht==^tk42QxohhI-{g~iy*`{8C8Cb}+j$&2c$gYgm_TFkpgV8t
zUxPJ6>U&WB@#wsOGuwP)Y$)aS=yhQPb^k#1ZLbSs1XBJ1-LD8*AMeTP(k%%pbbNXp
zHQahdz@G8$b>U=3N}ryLhYSxm!out%Jj{F;FF1Bya%?`x<aqFvybt36P%Y}(a*4kc
zbfAXiW&XZdpcZ2DV~&z~m)_|AuAR3WH7~W^uCwLe7pUQAd8s7Ar}N<VORk+aJVBM^
zCEw(erIN3m`Q;h-_XRS76qtX%1S+aPOdTJ_6F!y)OF_wGqB=O4yjuWCCigCb5`#zc
z5m1`~+`jZ^J|KX?PX-z8!@vHNSFZ~PRLY~9H3MQ$F4Ul@V1r(7o!}S>$?@QL2F+*n
zR%*EQ${+{NV`fMVbK8gU2B>~1^#;YF2jdUN=AWS5Xaf9AY@lX0Xn?&JbV<bXA0C}d
zE}bVlx_#I{cZM_l@X-9_p?S@P@zlXr%$*lMdn|=y7RT7b&b=}xU3(pwJbFvm4Lo`?
zJ$hyCf@Xg}brtBg2F4qp<ksuLE>LpXvGEaT2mus}o{YaeIuE*bUNJo2oBX2rH=|EC
z%dt8qSN`oH&W_&>@syf_ZafZhZGBSW>)8BAp;Xed^AxB)@NBkXD6MjAKEUY9_{zod
zaOpdb<4mA3={01(q)#Wf>EO|Ph{L1#Acv#n!TN=8$AabqK-*h9x-ET^9Ta>lkC$+H
z><3-D_5c6>dXG-4*N4Fu0)g7){M#G^I+&2OLeewH$}_LK;qz%kr*BX>4Ncz$Na-78
zJ#yn4(1{tKW^lKmXXiN=(BkBd7!{2daTi%YH?<s}2X2&yyl4Xrru6dOp2yDM)A{K|
zIfVOU9y`N}>@WZSJA6CF$luDw$-v<7?HCh(>uU}MhR(0ePg(d|&vSqUIrv+*Kv)9&
ztusN=ADSO1bh@bI@V8b%Bpmo#<G>P-)}@Pz0e`Cv2Lr?RW1y)s{#JPi8+6f2D-(px
z!oa}a`jj24h6BVt!Op<Y`9T#F>zytt8T_rw*cliapMg$Z<!|j|2Ms6jUIDp!>t|4x
zlK0d+b_SQuUoVzHxM2U@dNJek|NoBs+uYb%4pi`a^z!bW$IigN@4|})ka%|(het2(
zHju{NY?c=}5HSIdUfxY0gJU3k36Eah%^<!Hgs%XTxB2}4f3Gv6OLvTlfn#q8E2z`s
z!1$rFL?xorMI`}z5<%y&P8SsmP^H-X;0LHleVe}}jg5h!SLAlD33#rvH<*d>!@)-^
zuC4z;onQXeuRIJ4-8Cv8YZ@1@GxUa77`(Xn3G7E7P$YhOaro1J&@F%<6~Q2fZHCCk
zf!Ls9qda<fLqY7>pZ@=M1znfZ&Begr*;}Sz_@95Dh@D3-ul+pG?O?|lUsQbh|KHK_
zfBkchUf#C3><ll`A!aFo^hbaC|G)J%e@hf61B2oJ2_D@c|3G#M!Zcfd`v2eZH(0ON
zT+ktWbqX)kA^IPI%#!{D3ZVZkoi!>cKD{Z&G(5Ul7t4YUu6I%K@a#PPTHW#gb&qa-
zkKO<S(EV!JXTV8y56G<M;~Xz;fBgU7$MSiJh)1(ML+NFYUfx+CV~>3N|Nr%Mr(T=4
zpv>#h%X@YXJA+GijY^8E;S-PK|1TDU^!4h1JQ_Bio#DmgkN^Mk%QJX)hdc#kg}}M&
z44%zL7++L>{Quv@@^Sq$k6zx+IiM>5p1er^2o7m|kiO`T|NnQps6>DpOg_CjY|c;<
zWMC#(BAMVmhn?Yt#>fBvTi^1x&H^8V%*z3CuL#KcZ7wR{=|_!j7nKCV|4<`U*gU&M
z{&@8A?wtdTkmn!3Vfw<Om-pLj&{c*nu6_W!Xe}s4PJ-B=1m@G7qvG*e&GG+LXyAbw
zCEBOK;a3AQYc|-dIu*}umOmb#anRe~OOy&MJX*h%9`Weq^#(b)^uz!EuTOyDe>SM5
zDN%`VHGJ|S9%NH5uNTPH;1B=*`y}V6Sa|i?=)I1F^@mq5mX@tx;co?vjjZ6{Zv|af
zze0e&buj}2!wLod)=ePVfxq=2h;HC-1<gfz^zzEjW@i9xy7Op0&h+BPdvFx+_eq1Q
zkzU?+vq8D|(TfM~|NrOT&c1@FWTr<i?~B>&3@^??g&0e^JbHO=gM@ZLg;=0>CH3;2
z1_>{Q3Ulzc<bcLhdU<z&gnOXE0{ktp5aG2T;Zmru0)GqWRuYe1-o#n#3@_rK!Vdf`
zpaW$*dU-oQs@<W&4g4(z5JRd!!UpgE|9>eD8q5VpbT2O-C@?|yQ@jv;54x#~b(It}
z;d}J*%785R`wkqhS3z;`5yEBxi9dy~FMz~vzJrFmM=x(ZNb&?o5_Ct5OLvHhfk$r*
zs8jI#2c)a54{F02@V7=XgYM<^V0KY40B8TNpuwx;8c>l^!Y1I6?4sfT+LQu1%EzM<
zB-~vCNt_O#&7B}23&a0u6Fho(_snKz==}8}=-vPS-C-Y~0xz7w+#fKm3CK;oyxgF0
z(0B(aGF%uL7+ekCI(3V@^XTQhFcXyHjxxUBd<Tl|*We;Ud?q`?iyv<x`2{?C*2{Yp
z<i{s(|Nr;v)lqXb{N~*q@)eY2=Yb74#`xmITaW>t!CCg&40eVW+o1+*0WF+9&gj8h
zqN3nv`Jcbl4iY=pK_*Um3yK046_5WHJbFD0UO0VbW$5-%33*|8iiKf<N8=Gt-3hC&
z9pk`zN<ib$pd<2od3S@NvYUks9J-)jf8hi&ua{RHWVYGc|Nme5f-LKXDDS~gE(}rr
z1LR?L2wMu|_TO(H&T;@nm4-(zZ_O-F4iq`|;^CYB|6l5Y4DIE8Kb@W7#f3MZa4Mbc
z(aXCLWXu7O)?VJrAh|6d#S9R|OF-r>1_^xr{r`V&FcVVE(qh8`uUSA&@BHV;zy5n~
zh=IY2LWps1rn55`UV4!X;eDSDj{Hyvj{#(|Cxi`>d0`8(W!X<~A~pxPLkA>~2D)UX
zmsbuXAPo}mga|N$1h_x~>JWh!)7Tka{CxfY|4S~2z)6t63y{Fu?_fjMf&{LE1TH`X
zrho*Ffdn=~1ZqG6TR{R7Ap*%Dfh8b;GKhdHNMJHZAPgd)3KD1n30Ok}xIhAhAOQu4
zz=x^q3@;Ku0xS@LD<A=Xkig4t|Nn#P0gqnZi6H-2z5f5-u{#u$LMMRupz&2l&=Rd)
z-YFoy6ht1>qL>8YbG`om-=*6}B?Ht{Y|RCg#?UzY@CuS|R9F}oe0x(3K>5!RQZ-DT
z2CW*-yn<H^w?R(Y^XmWqZXcDL)|33Lo50gPyi-B8EO`Y<RvNB`-#mM5j=;)muWpg=
z9=*Il(?FT=7~_kYSCG5}s{6Y@24;f{bWzD@J;2|}3UOQ$$iU!N|Nr;0%mvl9u7+<t
zX887+90Av-;LObgHt#6o3mvd|kj!m06;z$ReIWsIOE0e~DDm)sjhT(E|Ik#BdyX=`
zc=HnE9*F*5Qy}_pyaXqOKOkqEc?ohxG~)q?2@|{_g-a7m{~9FyyP*1KK=fY%>F)vS
zzYFq)<_(A$P$TSNMr0xxQ9gy8;Y9>Q|0<AvAB298Zk;2phEHH^ioa7po;bqzLLF=Z
zq)lN8GC>St!a)$53v9w|c<1tE#4oV-ctDbG!BauJD?sdr5cZeJ><lliLfAc^bb1oP
zz5^293t_i{#5Y3NM?m7B`GMBA{4GVGtl7<KB*M)AZ!0DL2Nhx-{Lo4&VhU)k1k^I=
zWjW^2En@K^17c7B$PqCwz-hA8>-+!zFWr9r|KD8#szP{QPX)C~4GdmbLlkeD3@$Zv
zA-sc=*%>-Ny^x3SPJvt`3}J(0Ua-IT{~y#8ecAmLl$TOe3OsswKY>!;+vorP`*c3?
z>HO&1`RqmfM{wKGw>RYo2Xy?yv0Kcem$zjyD5Q^Zyx9Bv|9@Z0XQiN~(&<U;3@_F^
z2M6XvklPnL2fH172Qer=y?hOtG3yQmHRh#33hF^KZr!1v_N+XJpAX@KN?}b9KmPgu
z|1aY}GgH01Uf{&^?S=PqPy&<&MLx?BpU&e>kPP){64*tIFSMV767Xkm?Pdvbkrc#5
zsvraTz?!2$noS@nM+DUFJOb8ygz?3@XCTdw!J7X}WM_DB7d&0e%K*}R@fpZFCH`Qq
zfF}PudU>yd6zzBh?h53zUgB@P399CMc_)H`d;vuBW{{dGAd|aYK&8%s(n613-nAeV
zbr2O3K`M$M?0S$@X%KcLNIVL{t^<ktLD-2PaVH471|)6<VS9qawIFP;xZJb<|6hVG
zbNA@w<pf#C3z1X+DP)AOc|hV{pZ@><lKnr}AE4;ynas}M$iM!2Z-{`wiyI(GCP<g=
z3`q6yr=Um<Q7Q20{P@BO)av>Ro-TD^K)p}2`Hh4}=LwHaAC-h|PX28UEFRr4DhZCA
zryM&^I39e(<k<Y+TZfAZf2WHIhhy_2M$r9=3H;jvK>Lw2TsoOOI$2bDS->M~F1<-i
zj*ORllP`hKFnGe^lYGMibVL(qY{ZB0hO6Oi$gpS$U$4j|mtGlgzYaVSeb|RtMy0t%
zg@cj5ub7d6!8iHIUPjP(5t#Jul~H!>d<H9@eOoVic60l5TZ4~2=&csuZ&79hwd4#h
zz19YuPtg1yG}gghV&>6#&Xa$=38RnYu~KW$>=S4ytEc59{uan0_MeQUmpq$o7#T_)
zc|tXno}S>_dZ6SIlGc)=zKoB3EN_<>d2};-_EvLvbl&r5e*VL=li91=#rTJJr;G6q
zpUxW|nm-(Sd00F&k9D3n_=36f;AfAep3O%YeHb4%A7!-8QQ_ck1uby^l`8x$ov%DC
zkJd_gbn~bf9_U~JkL>waz9{_y4&jaf7LVp55@>BL$oPmS|N8TW2Ru7r=dF4++Z<#l
z<?!ehISyN{>}h$Z^aZlLC;t8a|GEvN6CnyRp>;iIeFJ#)_BIz4e(<G(j^IG|X#T;-
z-w)~lyevZ94}&tE()>mPG={=z_|3EP3TWWaqqow-saIw%Xb9iCH^iRZsh0<Q*b3-;
zCD2p_Xe9fv2jd~nUKs|^gktM|kKUY920q<do}KSX#a<gXA7k`rKFs6^y4J7xIESO<
z_Y(PU%p9f9J-XRFl06hW`PZL)aeW^P1L%-^CC^T_*JpQt5({Ly0kr<xF&5f51&`PI
zwmvCw@aSbVoCvyvfJMb4`J3TwkJfJ`>S>Vi!ET?s3?8i~OZZ-Nf=oT`0<QZQJem(P
zdRTrgy>EEn_2L)X_Omd&J^~sagN+AvGrAgr2mM(*I<JEVsd^(dI*+<Qvx85sj}W^{
zZxRdW*ecL2A>ZT!zKjPOpMo4!!tc_{a>)%k&k4#hFPM6Zm^?Zw6`CI~y7aOL9DK$C
z_LXbvZ5Mu*8y>CyeUlHA#yIt|K#nwJyy%hq&DHRd#|+P2AI2XZy%jHfdU=>V7;k!f
zzi)WJxAlO>aTiO_+G~aqLC<cHgC5YO?4a4c_m0hn7{N!mTrRx~OJs))54655;pt^T
zjD&lFwr~CLNdD%@c++F1XE&$E_n#j8>rZ%g9`evU@7VmC(WCR1XJ;ixiGyoz_J5zw
z^M-FHcrbqV>AcW<lo2#!G1KGwPoK_9a80LNEZ=%`hI5qObnJEh2bzNP;9q~tlkuQa
zuMXH_p3MgZ4F7v1zx7~z?a};J0<@pmxAlN;uZU)e93;LvFM9H?=Q-%X%yZZiacX4g
z^XB7>o|+#WEr0X3Xn=OBcL)CP>Ad`UKUf!He$6o~6m$iA^BaY3#uXg=EuhuzD;oG)
zr!YeL<2sBC44@sCpg~lR-b~PjJaB3T4e3HQ<k_<~A7?uF9K0dVlkuP@<4e%+PZ#Lu
zJ;MWzyFrQ3@S8{S|JTOg^wN3HQS+E*GU&G8Lq9xP4^%k#SYD{L_T*oG7&IB+$@tTk
zfBh{F#$zs)hwB2J`1iT6GWd22wj8KD!g#~C^P0yDA8nIEKAj&tnqM$_v>vED;L*)m
zBmf@vj_(I`g*aY3-vb}^25o_eJ8bw3R$h8o77EnWf>)sNcl3iQziw6&i0(?L?v?1e
zJ-S&VAxilAAQrTtD}j&CdUUhuLew@v)kdMK^{_0I;P0yh^}RYjz1aQdKV*vgr4OiN
z0nHEcgFSN@s$UAM|D_&ioIoD5-svnv{!uT)Ex&f7c@|}T04#rcG{4d4X7uR1zJi6n
zMI98m4g9U3!-GMCE;gWXl-5i99gjf)VjalA-wSFNfX*j|o;U?QpxC4HD`*HR`GQBU
ziy3?KF(%LsThN3g;|15&CqBI{j2b059tWQ?dnA8@M*MA8!%MGKJUV}P%=G;J7exH@
z<X?XolH)FWGJf#oUw_lp@=A%hZ+DJ{fZ-+IZVunpw<Y%~PkVI!@ce!kqy?hSr}Kn|
z<^_+=Lmthq7(s@--f4Jyf`?_KKs}d-WuyduKWOQ>M>lIKA2|G!pwW427c_h{;Cb7l
zo7DlL=qNOhw_+-Sm4~dc5T(1I;oXI))T5i#0-{J4YF;X)BB*(tw_cq11&#98eG@#o
zS^x5a-3v2c3sWo7{ydcWrtuAElL2Uo)}>q0@U~BHphm9=c(NaSBw%j<<H2XlphYY`
z$>)3-Pk?5synAh!JUaKNfVPH}@b=0afX<(IB;WS#HDU7TuH*1%{SQ(B+C9MEQqRP|
z;K_Kyr?<?&vGFlzVBNb{hRLPZfyt+HiwbxIrgM%8XdOR)YXPV~dAvmhT+V`0((x7*
z(5iJ%=gH%EiwdZ00kJ`&it3<o{B4yipyMFA_ka!Z=}q+T;NR!T=G|+;<;r-#r*nx4
zc&TLPZ-<UOD$hYCcJBe(<<Wdxz@t~>x<}__kIpG7pzRCL&4xb7r!)`w_nMsdO+EoK
zyR%0HwA$ULm&Xruf3FAQX^+kx70`-KpUxf?(CDIXFApDRe`4nx70{x3k6xLxpgo4Y
zJPwZh+YW0(yZ}-RnuhS`oTCD&vV1y!GoJM6)w%4EeA4i?Z?DaHj~O1FEh?ZLYd)PX
zd^^8-b{>1Jnl|Cv5k~&j<)Hl4e3-+d`4|)Ex@8Ybh$;LnpuHl#-6Hay-6C?H-8r%h
zzO9!^uJCVX>pYm&_>hq?t??%#W9crB?jCRutx)jk=8@!Y*$QeFww?qDg94ksbtdQ}
z+io67Ur@iE1Jn)g?g5AQiUv@~gSG*ILf)shMFqqLiGgwpsBre_jpXp@oTCC-lJD7h
z8hnQwf9q6Gxi1eI&uRe&FZizW&JdLhpUx1K1fT9HDj@wJFN0f;-7Vm#^5~wT0^zer
zcz|ZSI%8BEe7YfqgVt$jfV2mI?r&BAbt)q~x?3Re(-{MrP<K)B00~=ob{>4;WB>2}
z%VVGwpp8dB$sCq@!L1p1dFujdICa-)c<`^UQ}9i`?cZy1&$aWgPv;(R(t|7)xD86H
zpn&q_Uw<E#wmlhdgS-t&lrOXXg02mh2hEp3ed5!-L<N)sJUd?)o&<T`C)q;*w8+fB
z@RCnw3g{Yn9~BM9|Cc~M0HspU<?$~e3LO-D`PUzL;dzgh;Uz1`1I;#)4E!ykpj6P^
z15UsQ<9~pX7AQ_2@vsCOt{{g&<AZ-&4>;+sXy9)F9o7P}50q^Aw=;Y@!kE_C0uFHg
zmgV5=(V_xQrQHl53qaYzw_8O96y^n>C<D0@<cA7S)&j+oXSawHNCF&}$w3M}oiQo_
zi1>oWG$;dsv}J&#K|5I?`KNmhI8A~~j{p%Kp4}qC;7IoEya<X$186*ls95-PK6>%a
z@!$WKUqQX&?iNT^>t+D&696S+P<aFk3D3?S9^IZCpo|K37%a?C6Dmj-sC4m3e(2G9
z5}a&3`CZSvyo|Cw8Ker?Y>#eF1!RLk(GL#!UKdFLq+kc>17+ryEuiIxNbRL?q!TG1
z^QYa6kVOl(K}8X0FPUTKq0SZ+&<Vz%)nTr^5sd!5J`C(Worgdz-_8~lP_Fmrb=2_a
zJPyi1pi<Pi*Cm3*vDbv*;4@J5>B;yJx^L2>vqYuBtJj7flx{)(E#Y%UDYktWPkS&!
zq5@Pq&+zCi^zi70B!7_Upi~UnM&7vvTylBzItzeGF;Jj*bl&sn%{TCbI0F>cj=c^{
zorf6@9DK~;(Y!|m<QoRiDGQzVKzcw4%Ck4-DuYumWNSA_5R^{6du8r}mg7OI0<ap8
z94L+Px7-6I&Ey+C-H8$&-Qpl|P=5C4j#Ti}yaVEb7Tx$*KJw{&?7{DM>pLXuK$Es0
zNl>EYZ@B^*s(-=a)A`w_J6yqIhR1Pt&?&zRp1nRt8Jv4r96)0vK1Ufmy4^u#!3~hl
zK_^Okbh~qSb{+<CLDA{K_}QbI*+biz17tKf+wrfz;bVD=zb6`0YIeFSfD!@7PEX52
zpu7fhn@9H+6;ROg&uviwpOME5Dd{~r-2`6F2l;LW*mIpNDiEJJDtL4r1KA1D4XHys
zHNSXtGx%6O@Z|SD0+IyT0`sf@0|S5SC(zxl-Fu)#DP%E{E2#K^SnqMXMFr$1P)Tlh
z62t>}3B)@FaTkLJ;}4K9$X_5~kIp&{kQ+hC0UY1m>>k?g96pv0eE9tyxVD0;SWvmh
z-y#CGdJedDaO`#X57GjPJ)iD9kYv+cqEg{%_ykm1fMVREdkwfC^JqRS0Gj-%@acRH
z3Q|zz=+P^46jX(RPF(;w!?W|OXXk4VW@vjM`GO1M0gzg-IWs(Zd9M3(ZvmHk9=$Th
zL4gj+5gyDf;1U>=TR|@A?g3{hkVa5*!|*mJ2tm6%yCE5>@gb;nq74b6&K?yNP?ZQO
zh|c<Up6YB-@d5LH_;$Yc>^%AsH2(<dkEDUOeH>$9U`T8Jp~2q@>h61XGkbKpGI)ZP
zRr)e`9%l!60yGj);bF<a-}0J)fdO9sc)+W57nKSQ&*q~X9?eHNJev=5z`E?7;H4og
z;85i7Y(CBbs{KJ;=WqGX3fj91DZyR%x3l?l^GJZa5Aq+VDgpTrlzm+~4>Ui}No)QA
zwVl7;_5c6>X`mr@UPcCnG|>JT#!_i`jx7-YnF7kZ9>-b0*#uOafg;+&vIm^H`1>ET
zfDTvV_UvX$b8LL@|DQ*vFM~%XJJ_3PE}d*3ueO2~rg(O{GJJE82K5a=r_v`oD1d6f
zIpDbQ;a?A__<cI3fGdL+A=g2-bwXvkA%ZWjgDOF2#R|$xpkxb5V4ytZG1KGwKM(%(
zA3QqU6+Ak(fSvcU{tsyO-Gzany9FGPp55H72S85bZz+Zv1~!C$J-cToyJshtN4GD-
z%ZPvf|GRV^XgI^@*!(~tt&<Jx8~#==(E7b@fo@2maNGlG_IPxLGJw3+dJ@!7@#thP
z5%B=|24pPQNFi`f8PuR^u?F31*xjN6N^RfR6u?o_?O@UEpwQU@PPhCmM;I6wJe%zp
zd^^AJx3Ys9!r)}%+071`MQ^<V66$UN=P!6Xf$}P7H#RtZ^?GoC;u})g_JA8*{4Fa$
zO9DV`Bt~#-`SdPP0ckki0&cp3{c*en9P(hcC65IEltT@Bz@-#Ji6AT)cy@DpSn^1e
z6oPyVip<jTmP`CC+d-p>;Lvz!0v-?rwfES4JHLP&0<s6BA5?G{Uh+V49yG&&GA5`-
z=!7^1q!v`7f%Jm%@5@q9e->t8$#h8n$0ylA0Tfq;m%wQUq!3i#f~(=qDd1)Ss2Koi
z#k}CS3Q9{o;3f^I+yOPuL5&lTVvud1tO06qf`cr%2OK1z_D2Gwf!5su4l7VgB*P;a
z5>cRL47ddYayTf_f-C~50JlUzt^uhq067W5aZw2XSp_cEJ7LXJkOmFkZf=k6P=*(g
z2LJwpTn91<<T{YPm&-ug8$j(z&t`iD{#I>p(+^S&cyxoVj)FuQXb`Ux>dfvIaHkA8
zpuuBauwVvdVNmJs(Rz~K^`PM;Xt2NJLuv02Q5JZ1^MTB0T?VSSx_iLgHCVae0V(YG
z`%OUozHVkn*#N48Km{U15>z^Pb~3#LZ6TTfauqlmL%m^m2^3tQ3JBB!1=j}P78j(M
z5Aq8rd_bP;ZUGm`AR$m>z`SD*+T+yC4oXF!6!@|d%%1{v<rHx7z~9db&JU>0^XTM<
zmen8^zKjGFkrSZh2dK-r5#-<IJ>V*ok-w!FT==@ERCsg?zzPFsQGiwuq&YU8U|<9r
z`u6w#|DbH{(aiv=BKTX^fMd1?T)IO8&!gFrfxo30?7~n6kK`Z)&rWgAP9{jX^Kunv
zUlM%(oNMb7{+8(=L$EF=U;vk3P}@Lx3F^X^8Q|d{2L@1C0!kGOb*`X*2WP;U9^dzX
zd!nE~1P3>);OQ3d&<^16u!NM$^+M2^&ZCq6bsZ#sLhXZk2;xgm&}?;bkb+02IM{Ek
zmLR`D69Xb_Ui|(4e*(fip>X$f_dtq0guA*0J+uQkJS;EN>%*MTJp~+why>Ry<k=|>
z4)lI-*#sHy2jzE2sshDavlRn0Z1`J12UWpb>e(s&G6@|2&=m2q2Am;5_ZNgRfYL13
z41}Lbu6yvWp8^gvkX}Dfo&uNu-H^tpDuW;cgDohF^S1_pE1*5l6bWgq@%MuFDni?d
zAfJP4+fFwQP%{SH3Iw$k#X(w;E!z9<|NrJa;0^&Je~UG!3EB)Xk%7NO2fQQ)v|Xw7
zK1ik;(tz^pm0|Sk{OrN_*@rnsr2@3ArMFn1#Mrer;J;6A54g}XJmA@Uh>>5O!SIsf
zHx_4w5)O}Mn_~?8Qw}+HfDbWY1kH*(^60kq=yvAV2d+Gr=YT66$NeClXXigp&0`*|
z2ORjP9`&(?RLlHx4#6Ee|A4|FNYmb@a}Bf)zXVbQcSCZiOZO76$9%fifDH!cbkGu?
z)&oAh-U20_h6h0P3dF&$B_Zh#GJm508j){4!02dsp+u>{hLNH4IYi<)#5WHdTHf-v
zMldrlI9gsPwF3FUqg&Vm)I_-G$nW~zL-QbL;-vG04`|%{1)~T5`r{t_>wkGN9&@z(
zQpf3Qd5yoP<p2NwmRsOX1l1y-G7HqX2BnY#pb?NMhv0snf1vp(qXWka{?-&G1_sb#
z?ieNp2A}R~4rm(j1+AK7V`gAzcyhm!5tIf%xzVRLSO7GL`41FNokziEbwS#wC5Dc@
z9!N0;TF*TJ9$%i#HiwYo%fs?uDJZ@`my&e;^40w1V|kUo&y$IP0qO_-J{xEo15})X
zj0PF#(Hp`n0N&61oRNV6blN{Oyg^rtfyO&P)|4uN=N>Fi@V6WUZP);Z_)`zC)Kf@^
z-}C5(BoEL~3dmo+{OhlI@UNc(E>2%gX8;|+h14v8wNyY&98eJiN>eYBL2F~+?Lge6
z0)Kxp_+nFN`3@>+Jv*5^yV*c32XG@5(wz3_X7KD}2bU4CU;cw@VUW`dZ-Z<Fmx`bw
zAKsyY_M*C{fZYrllxBwXvA`pqbsQeY-5`zS&M*y7x2YuFxtE0j)L;df3hHEo+Cs2~
zE2#AV76<od;5{(V4AfNyP(v2flJxEMIm+PEc>&aG0ac2S)^4Y}!pjWMn%CoQ3JeSk
z3@`ux{Qn<i6V^+9=r{@32BdzUkL3p+e!maUBxeX7*#fEY?fe8zb}vC&I(@pmJ~SU=
z1dW($JN@urhK!JcCrtR)ANS;6|I?H45H#7;ae@+3|INRkWwTd(`2DWF6#V!9Khy$P
zM)2+Y1j@$9c?4lMa%e*w(edy9|AsRPos7`&9$$u+dq6wL<r#uKz*9{gou@$qT6GKz
z4Bw8h@VA2QYyxj(vvgD_(FUE|Bn(;t(;X}TVo!hk|37Ga?dFTxchI48=pKd%puumC
z&V$g6a-aba@bm=aEG^L9mEI6$4UcYT2@gvrf%;`0%~c$bJ$?0iU(W#TN9_(2cwzn+
z#ncz-kN*E}Jy0^cQ5m#}7~GJB%^#tRzc;_J=w<}Xj)5CU=Nvl^I5s{2*DResL6e$1
z|J{0dz-JNqCZ7b&uDt_Iys+@MnlUjjfHGw(FL)R{j-~U$!58u^2RiTax6T4(>C60m
zlRz7)dc#>fKnE(j^g93d=}psc>~*PP@@Rhe!>u<)oRRSd$ip){7*BxbCS6oCdfl0P
z86O^ez|!fWqT<qdK=VTD?ao7WUi|yqG%PQa#D2eEd5FK|EU4g0E>ThO>CMwLJn&i(
zX?%-+pD%;usS@+=7eUkYmZ$hzRx&a$fcHOqv^-pT-=mvV=PMV3N3UpS9%KTlav=-D
zOD%Bek~YB;-1t!g`Ool@W9N0yAVYGFii&UNW5@5;>vdj&q#XITakreT&~@S8_tC}j
zlOz9}V~)*-7(JU0GrDMgbnNi{?`nCW&cwy?Lj4s-{%zijEhj54gA}`3{zFmB2vb~t
z8MfX>^MH4+h^9~HNze>4|N5gZPMu(70G%5MDuFyZ5Be~tsAzzv_Q9>|*Idnq7=0Pv
zSl%j8GCb+Yzn(>ff5JfzP{rMPvg9#HBWS;d$MFLos`)J=c$(Ku!l5INg};Rl<m*cw
zogYCbO&||YzZ3ztSwQ_M*1w;@!S$#F5?o#jpz~1{$QoehAA5AOo`tCQDut+*TEN2a
z`W!6%d33X`g~-Fq`!%11;q^M0eCvPT-bw-AZbSZ-LeMtugO5SCL@|3dzheY#-%7q@
zc+$UDN5;QbMg-ix@$LNN%fDXayf0(OSq5K5k<*|`!}5InbIZg0t@@z#5Zs`)5WKzW
z(aq`$vHum+KUMQt7+z|Fo1-qE8m9HXC+HOK<BXsHFA?xK&T<G;#(`=W%j5MQ8u>s+
zeSin{LE|r=`L9pl@HquFPYYz;ZIIhBqVoSSl&Azp;L8l~DY6KEw{rad|NmtPH2gv3
zjRC0aIQ^pW_y7ORKNw4RKzrei7=X60IWTk!e>=oc^4_DlnuDQ2srk`&kItK&E-E^m
z!Y>})2CwAT@o0u924!r}{Hrg-y~c%*_^Fx)iqF?;Ang~(JnIUc(&)}ZjgLSB2F<?`
zO0ridl-hS50*@0npHf)S&?#7|@5sOHf<I_qCv>wKXrd0Z_Yt(c^OR?Ih=7KNWgtf>
zJFfy014AdH;U&<Tj+eVZtN*%LPkaOi+Sy`=BficBIRd2MutzuRYKSBUG(>OAWnp;z
z5aGUWj1Hwz;DHVB9f`fH?j@kbAfSW3nvZCJ4om^<TCQOAu{=;K51OL4@@+j?QtHvm
zdJaV)DE@pb57p^_q{}^eS>;QS&4Hw^){`Z*9=)ur1z@SyvpqTk1$;VB`E)u;fSmjC
zHDtx%j}Kt~?1lPAbuJ6TOYl1UZq~aWxENeJ4?1>U@aPrgf%?e>qyT*QK{x9jWCh7k
z1<D`=TA)exZr0fl!yEG<fpuaI3&Tr(aEfI>8qIHhqu|kbwwu$V^BVuQSXQ6jQjN~@
zz0NEyy*l7?OnY6JL3c7VJ_jWP-{iMG$qz~r8bF(zzylGTFJHui>W$kaN&dYodZ2r5
z4G&E404+9Q7CGkG2|c6naQz#PZqO-?FJBzE^Z!3|e|xDFxIzQ1R)_&D*nyw7-+H@r
zBTW5-JJ4$C^(B~4?Hx$X`0_>abEqVmK|Y;_JUU;#2)PZe(q=ZMGJxx}P_XwM!1b{K
zXkox<&_aNV3=9k&mVp9wn&1q<-vJ)F?`9Qx500Jv(Aa684NYwZ(T7172-RK$Rpy`!
z4?eud4Yuf~^CD=uk8kn`@a2S{^zF-d;@c4czg{0^4c~4@0shuGpgTk@5ApYc?ho+Q
zcI5D}JjCAvIw`}m`Je%4%GR^<vX6GO0_b1?b=O{}|DL@poPND72RS^x-}GfX=-YY2
zhkrc_hYut8>_YJ2%AjLtA%z3zQW}qL)>-es?q6R7NdU)ZA-TVswFV-alnaqvi6jd;
zPZBgDr17E|bZAL;2x!m4%@=I9A;Et0#ha(lV1M}*R8CHK@%k1_0Cauh1hn>o2B^IP
z>SchE3@ETzJbEiNTzWGYU3x26JbH5&*qwV#^gWuN{%{4|Own1Q!s5ty7<3qgFX))(
z*M@IF=Ns_$@*L>Z0k<qXlHc}vF!?av^+-PC!T1+6G{xZox<L9Ni*M@_5Ldt>`6Pdf
z2)O5UiN9qsXt1F-hLyqalB?l2&=j4-Yj5~?woB(V$gcNfmzF=R2P#xuEKk%bcy<>k
zcyyZ_^JxCZSR&-vouT2{a@zy6wXs6aqtjUcyqu8nw4>#vI(rxXZ8GAnEw>%{_Z_a>
z;KF#pV}@rkOUvs`;PSwu`5hx@J_gjm<6r;5^ZRX|&S(J-#?zjR-yAJ3)gSce&QX!@
z>HN?gqQU~oWXw4#;65~{6XC&JqaxsV@Hw+@@_*3r+Tf)om%KVz?0q^-#CL%z9Is9n
zT>($Vvp$S(9h-kK*71WZ>U0(GU_9$+d8rgsQN!1PfM=4yq2Stj$pf?*uhjN+xl8A1
z&BL8HnqM%s9;i_C?2Z7<Hg(G!_GtdiSR&}#odEK?XE)1{3T03y0pj&@Ag`OCczwGI
z<B8XMK&LJv{CflJ-#7se#&e#G_dxzV<J0-!rNICH{|yhg8h(4p2F{j9=a<3O?|}E)
zc5AxuZ_8xy=q=Q6>SY1%xpnW2;bb`oIVd{$0(gTmXoaZ<;|0S@4&RP8fMyGkk4SZF
ze#_{=c*v*ohG+6!55`Yky*A(lejcFpSDk-6zu)ocWjW+yd8k+$9ABXO)_4y2c8eVF
z=@dES3%!Zj)ADfra}UN}zKjoiEDsgka%}$lzeEgFA9TopeCz@0eK-I9U;3e2v-#=2
zPEA--=P*isXneDSiGcw;f11b&>Sq}+gI1eGvUql$0u2T;gU)enQ4wHfVCZyF0o9&t
z&b>7$Y@iWh36Ny>8Wjy@28NCp6$h7&6cy0jpP;rzXN^ikhl@%Dc#ajcc<!i2>o-tV
z2;gs#VgWZ&ZhQ1XX5t;e1qFYL8fY^qXnmE)G0?@C{2muzYXmJ1*S`c0)2#!qY5VWh
z?edqwwG*^>jlTtSpQLZ=Tc2(Z1()su3I3MbpsVz{YyL8LfQAFkg8Ib=T5p%iy$%J3
zr-$Xm5-yMCUyS^%LZFP;e1OsNaGj+`vPgUDrHT(OmY?{0Pk@@|y^vKkp4}oBJ-c}h
zdo=%KEIs7eDRLOxkUCs{7E+&kHXmnnwfw{1p9ZSxTEFqPq%kuvfL7qefk%&C^FY+|
z_xXW_keY3dF_ymdXx?)KG{?kP^2oRKEq_ZZXyBlix1fNX;f3}j76w;P!O;R<5yIaB
zS_$&H7S_IWvHZ;6^A5C6_m)rR2^Y;zuC3qdRiIrY7X}6&%Y!9sp3OfPOLajxulWFn
z<t_de(8Z}f$)|j}8N9lC&VZ~2`{$BhXA7A3`ZCxZe?cMA%ljgqo#Dmei7X7D@k{Vb
z*)|sy2an!8U>AY9)}VCaYWUxy^POksF|Tfxf1o**7EoY&cjx?N@JRNM@abhu02k;1
z3Ld?z;UH$~TOWSc11~BseESbp4;hv_<k9)_g)hjqW{3q0{4HuAhqS&esWUv#dfTIS
zipmB?28L4c*ESP;yB!ofyLnD{K-XGY9<EdONcL$3t(mRh_3LK&=L@pj@?_0bP|Fw8
zX@EpP{Y{@<)^j=R44^gW-_ApwuoqO}f@<iWFHTKh0gvW_Jj}q~0@@G>k6cMm<aTdS
z0r}el6v?)1;JwUC^4J+(RDv|N9w>?P=!Gn_0j-hiya^G9`Kcs~f18hrgHJDOE2!Jn
z`RPRw#0@3tP~~1AW4fn6!npNPiK<68YtnNr29Iuz7xN~A#zA@@a?P5Ipas^B9RC9h
zCV&sF0Oev>4hI*ii2kG|s68tEoQnapPuZojM8&`bw80T{?21RPC|?ew$}O7=s*qoA
z@#y89oy*SfVp%_UK{G7=OJ*A02Bk@83Me&v`5io*3mU(I1YR#l1I(}dE#S=1e3;SE
z@(zFBY0#i+w+m=l^MR6=ptRx99iZUT%j%E~+P{7d92KS8UP}K5@0U;j9RmVNqP@ZY
zJ$gefaCjUCjr)RI7ao=uN<V<gg4Qp;|NjTAUH33N=>a+xzuQG60(6Fk3*!T5pZvl%
z7Zn#s`TL}o2fV!BBl)BU;|b8ly#P=SZDj!+Vj}`x=?gxWp)*INpfg6L22?L6|8ndN
zQDO4vE$0BuuX`MP!~$9hlF)e#lmS3PJ|3ONKrV3b===&Q+cG>3K41cc7^tT7>8<$F
z>-@jdMa7}>2S_#mG!6|aGeMk)&L7PWSUMr|>zzON_tmIWG(TYKY*7I<$3UxdKqYRC
zN(E#q{^4#=_B-wh8q#KP(fr^s!>4-=xB&40ZA|uHe9>H^;=$q58T*018MKVTr5j>2
zc!*;cD+6fXBxp^!3~1~O<Ou$4;vE9rQ^3}NcA@NG1&xP1;cuA=Dv7#FR0==?PoQ$&
zqw|&F0gui#;K_m49uqv9e>3v8fR4}b1<mP91WmhkXDE0z*PLZw<Zn>|EsX1S(D3hO
zIRQVK;TQ+>cm^g%%Om`KnoJA~zO8RPdTqeXdY^8#l1Rw4E3GF>{QZ-8EL~eqR!#%i
z1U>7aWV;Lhc1Fi<2N+A%f+8*qH1PcG026<UK8V$PLcy_-3$*$m&83s^br)3E%ew#n
z|AY2VyayTO+U+61-%<-|g;{>AlXBJk=-Hj2;Mn|<(Kq=d)cLKBpc(e=9u);pS$!OQ
z&V*|>Pov{^&~|8!(sY<J_*;~~iIu<QH0ZoVuv3<R#*JK5D)?JLGa(+`tV<t*8@;PC
zA$jalKPZpA^!@YyzYk6;_*+0Xi#j$wWME)o;BQd^xuchNeHJ^z3!xrFfebD_8UKK`
z46^z3vKnQvgUeh{zIq{b8l0i{TONXs1w<*5o^_*?ar=LR0_ZJ&izPE?dfUYow2Ohi
zMVpy{p*sXp;)4oaP|^h@YLCvJKD|EIIbO>^N@0-;9-V@qQ#U-CU$A&up5$-o1|^^5
zfIl9smnwLCy4ie_10;MbFV&p)IL-(vieF!JwfqQ;9{&D&pfOKqP#^^}e+%feO>hwd
zI`0mW^gx&8crdR4Pd|D#zh`l=EK#Z9Z+-OV|Nrh7l^W2cZJ_3-;U#c$0@k<y)xL)q
zK?lCP1CNLu@Zew1a?z200%%J@$z#x6uH7ywE~=o@=s>GGS}%a6U5`6~hA{p^$DCe*
z&borP&tW+TypT%3qq{~W!lOI<2Z#~i(HUX^+WWu(YD$5!8E9jUhvp9t&11|iDjo-+
z+i+e^0!JLAq<<;)>;HepgHM=!dL0CyC7oyT702d393ICVI6$o_&)yIL4u0^R5uo!?
zcwtW9-^Sm;1yWd?1`=mE<{-cT3kPs0cy>BTcpi5W02u-nczFTR+2?);PMJH>ASu(L
z7o0LTLnPll080i#C8Z&f(|&@s09J7LbRP6L?f^E@rSk#EgPzA-7{Dcy;Q<fLpDv6K
z558pn?6LY~A-K-mqXG_yZhjBY8W9N3rSqXrw-5gh59sMLKAk>XKj2{oJ$mL*=S8qV
zOJ71NU)C^)yM$9Aj&AM&JNh4FAM)08c7_)pIuJSJ<xNl^_ws%KNn8g>fQqYgAl0B6
z>*kBwATdOZwFM;8?W2<6)604~9kj#p*NY3sp*d+fND`uL397bQkW4Rc8pxJHkQB(4
z43Hp1c_~N?VT&I~24oAkO#|wB_p+9zu`|3#g<9469<*;0wA&gwo(hZXZt+e?YU>XF
z15Rw6Ar^mLdVmL`YE&Zlw}<}&3#WC4Sp0iw0Ght(bmDmV6Fhs*Ds>+mr;DLs=iUtt
zyF=gq{|E0rX?&vr%DCNgR6t9}ySJ!RFflN+p5*U)1a3aN8eTH|4?0Z_RNpt-9A+rd
z_3NB-1+<D1G|LHYUmdJ7_3f59=-Ya`<bCV65_ZRLEDlU1Pdr+0m!9$H);ZK%E5T5D
z5~S3lGv|+jNAqz;%Y*f2CU~^|FOBvD-M|1{)xzHgI-|+M8nRTUG!5LVd@TlR|AHo1
z!4_MyTr3R)b^bgpFO|M*sF1QNiS=k^VDxA_0`d%~IRrW>4SbIZOp`BYBIxIf8{fYD
zM^@%)cnPKgtlYQrg5k**o6uD4vIVyl559O=^yB~Q86}fmpW>HC-M`rQ1~erKnt8my
z%)kJee?0*0P=S`Ft^gP2nHr#!egfKix&fk-BNRYwnr(rs9Wg5IE}bzdKKw2BnHU(L
z<2bH{piPV($v+_XT!BuHc<{r6@y9pD2L4uVP|Wr20na*nG9GF^#N^5N>fj?5pWf}D
zW)o-^$9_=J3qJ9v`2dGcXT=Xs%VVW4eL+1BLuhAZDQG1UWbVZ9fD8Y&8jw3&R6Kl=
z54|>V1nn8R=9zrWGdW}`xNNudX#M8XIp+#!g$RF31ZZU+|9Tnlg<rmmhb#}*Mey$n
zVP$B!RC$>37U;ar<dCTh9<7%ukAqGzx#8Jt#aMEwJ4D3;bQGu>s1E1fF8J*b6Mu^t
zD3F>DFg9|6>htDP3Sjfn96JT;*MR!B;MTV_s0ERH#JBZ8oe^k30>~L2JK??rO`3q#
zDj6Pl&E;XqbDY2B7bxmL*9lr4D18fyA5aqq6epgYA6-F383QAzC4SsR#R61d9(Pdz
zoomJ5aoj~k10(=y1uDGwV*x#D?r@2ZN9RHC*>W$~d4K))=w`hDI=|VnMFnIie@i_h
z1A~iYvIKui9H=+b&02aJoC%{+AO+Z=c2Hfc&B)&Zx^WoXjt8Y4P{MTtk3l-dA5NR#
z+im2_zy6+&<u9Mkk}CoHJu|?qX;u%2VXDax!%EvhIr{bP2`;@Npq+f+=B{t@rI!yu
z2Uqv{sQmXyj#2ReEw(!dUaDQ;;t3D1*CL4i0(g?L`N#hf6(38U<E0;bJ8${$ufOQQ
zzn<rqPv?{)0ifgt+WFP|<A3QL!vjdB$b#bsq_|V$I4Gz4SRUYS=>xl0<hYOJsnSOt
z-B1%cMUKC|gB}sCh9_M?a|47T;<$?nc-r<wzWMk6FOPsN2vz{aVduve)p!5>2NlBI
zAmPp%FPDPoZqRz;oBsn0UQPjZT(*U%xI1><0jIus;35u@dR_~;SU%=&oe9zgI=9~P
zP)Qvq5tY7hv3%^p@ABaF3&WGGw>^?Cl^VZ}nBdy^&{6ZCOXmqtn9T5KJy0P8$s0#N
ziLyk&hkw1yG0>cjC*vi{({<|n`&@V#S`JhmcVT?sG2`_)-)<(TtS|ri8<wYiI$e$g
z)ZYXp^Hxbv+;!gZ=q*tRc<BZy$pdbJ6H#j-B;IRVLGk|b07TLlBDn%8nE;Vo{1?2r
z0<wMwW&Ef4jfO|-NzcwRkbQ@s{brye-8_0dHF{mj*q{w`kL3RzjOQJ{v8Xigx7=X>
zorA^Z1KNQG8Uk#7@T2t`D2Mm52>A5oFdFo-fKIMq0PO^gIm*D_0y-DD*X_SguL*cf
zvR|)_u}3#IXxZ+I70oORo|gAZ-}ka?gR1vrya!qz-g=;f)uZ#^e*us>AIs0Bub{>n
z-UfAle0y__f|dZgfLpDQjwM_@qvgH&mxi}r%Rt6^x_Rz{x;|_k&6<oQ&Y*3ymiOvp
zJz(2x?}NlkZ-ORV{s$PmzR>!u^srCo!xu75ERcC>&?E^;o`fmg0yZBdJR$oL_%*kH
zOJjb`Jt_&Hx!a!#ojod`<t(6D0JJLD1+>@>R6KyTLV*g;?lmeOK>Y40DnCHWUiuZa
zKpnD6{H<%i<>4L`(4-v$f9qTjx106RHE=3;pTN!l89xIJ5@a^BFti@v?}+4JU~t^^
zAJqJ6hHH%HVgQeBaDX~B{H+083=H2}R4#zp%nbkk^S4&1fY<th1ezZ(^S7+v1Rd7R
zypNTEfq}n;O$&6cTk{EyZxB5!{H`CMOpX$P&JWG!6q+CKfYw7Nt0D|$WMC+f=!WQM
zKIfncvK!ROZh5PTP{hQ*P@>)Wq48V;BLf3Z1I$sN(Lk3EogW&`u)u^sC(OBm4mjrT
z*r~|C;L>^71-kbPw7L`&zOIG`TzU%_U3*j5Se$!x)H>fY9*3OV`W$>FA~+@g0QJ#9
z4c5*NknVMh${q#=h7!^47H}l>vK(-M9`@mzd;lug4OtKjZj3Y^U^@7K1+)tEBB%-h
z8Fla}GynQS9?5S#dwn<zK&K)fe34Yo!q92JzikWHRHt4Z@Hj(91j{i8HqdH{;|}0L
z%%jsqrNATkq(esmt5dHDIP*Ame(&4@-sA(?#?X8~!#DXj=+t4zJ_=A*>_yH>RtAsG
z4<4QOJQ(kLG#~Kr={3;?ZBYR&5%KH<?{5H&WVv+yXg(m}F~b9*7reNt^MeN?c!LIL
z5(MhO)&u-~VI1Hz018Qu&cD8$-+ekuR5Cm}-+?w8ykKNtF#Klt{}^QH&wo&P2Pz*s
zTfluXSTsLyfG)`fjpBeBYM{^tjpo4Hvn}9VEudXB9^EV-JX#NUcCweSfSPXIF<Tit
zkF%(NYTLBd+x)GQSr{0;ABJ>=LDME6HY)>vt2i4218B?(EXg2{=Ge)`-!ci3HT185
zvj$5tJA+SmiAn}2XM{JfFhK3^c2TJS`E?g)82UD-DFzCq&f~9DA>+9o-8}a|<pme0
zT;OkM0IghaKFnx&pTDmiykZ|BeFG$2dI?q*oP_reL8}EjT0rNPH2+fI?+;OgWIIUq
zZMmri4`GlaszAM0NU8(1^FfMS4R7~G{CDhi`tQ+e0vezK@BH`bX1VX$c>{FDKoMxJ
z1ZhDMXz>qdbu=i@Ky1*UDvS-<0tI51*n0Hx7=X(wk7NPR@OtOP3I&hmU-JC@+-wXC
z4SPgDtF;*UTV&Z77>>0-cpl9MSUfCGl%4^t3-PqP&EE=IQU3BM%KBMQlrS>zw}AFM
zg4iq!{H+x%3=EyOb}%zAFf=}5U^u`4iXaI07XyO>1AhxAGbCae1o&HSF+$l2{H>o@
zz-7Q;1_lNekS6}tBcK7L*0<m_k^C*3pzb;Nc(KkY;Dv+G<^3&eOi)8u_*>tCnkd~K
z93IxZc8k~<O2j?7MNJp6GrXv%0vC`iAg6eCvparcW8`mzjF&;SQ-UI|r4*cw90Wjl
z8<asjI$1t~tm$^J04G)!75)}YIZ(7RFha{fg;E92ZgG$9Ad7EK(yaWg(?Ld9UMS)E
z<^bY$fVj}^4JZn&J-hiq>D{Nh1+s^yJJ90A;Va+%gW9s-JOgSLF9MIr@Th=N8h^_X
z5U*221r){{3?+P?-8?D{l~Q*6E$uQ442_Q&7zDtg?B5(58B1By9Gm%AK(j!g4KJR}
z$Cx~uk8pUvmXWrWfd`>LnY-DJfxqRZGAIpzhxiyOc^$qTXY}Y5os`VZP%78_oRPoP
zodqH9(JT5OnVo^Z!w8f$x>@&MfDBQ8u3-Uf76BC=oh~XBFDHX{kU(-MONk)J-Jo=G
zhY7S_rkT$HB*36hqTB%4-}Ilq^)@I_yIoWY96BId<s3Q+*g$0hSSjR|Lw?sEpngm1
z_rH({V3btQ`s?ri|6s+e{4JkhDT0x|1+>}Ok$*ee3P%1GdpQP%?jCT>*Z7cui-Do>
zCn(?Xw>*|*0CiFLTYiF?>&;A{>-bbaO;m6qIL-oEWzX<(1*l!v&3f`YxRg<gMJi=J
zR<kg?obwyv1QrJV78lUEkz0_R_~7vuXl`)rlxu`!gjVobJKd~R5aYfh8@C8#oG)k$
zuiKFW)Nc77U|@NlzrPYJ<fBsXqM{Pi_<Nn_(amZJF`z5~$vuf619-ry#eF&t`hXf8
z;C>Jj<BQf0pZ~WW03|?BjlkdelpC~tMuV}G-?Q5RG|2Nm09syjgKRqX_5XiJ`Dl26
zUjy2_(SS5>u${z*)Su`THB0~vryP87@jb{+{*IHNt015om_57ML7A?#8&nboNO*L6
zD7<)i;U8pv2-Jf1>}G$N2Tn?m_A6-p(>ZY1pF;L)X%!2@O9k*~2&*nc{!uhiScHP)
z86fhk5P2<R{iY!K2S5M+2jwIN1z0V_-|`!j&`!RXdf+R_O`e@BD*Ua_!E2i!?g7^^
zFF_~jLBhwQn|1A3u=}KtBlBt{3&YC>@BkZl-UgP_UuuAcsk&J!A$sP;Ah~%VNRJO#
z4{Ibuz6{w<jUaiQpa1`Zmyf@U`3AmkrJGe3q87#eP>@;%h*`W4`BQO7cA0|YAAm=v
zSl^xjyWc4S(#41ZNrAReL+X!i*0T`#CaAm>Nd76L1F{Jsbw3QERURaD>Mvx=27k*I
zdC;Ip54gDn%2=SJ2dei#84P@CbjAaZ<1Xx=MOzH~t<%I97(l8(twzv*IY<>K!Gan%
z-BZ9B*aMU}K@BJakU~&425~e%98hxw#8G&`^$@i3hQGxK?8F+C0{(6OtRBtv9E{!i
z9-SxnTWTa27@!3?BWMh*z=eNXI17IZqbO(u20Y8pzwKggA(Kn5BWMBA!DlQ!$tREw
zlRDvQcoH(#-^+8-1+n53bisA&rIK)vA3=>a&*U2($=^H}FN1oypp|9^A2WkH;~t>%
zvJL-(`p-Vy9v?hAe|t9nWc1;8y$L$_+NV<nw2BY1G@9{)C;$4Bu9k;Nuev}RrG^Jw
zTThl~fRYr*7N{t+z0<)0J|EliVEtFnWKlu42555V2B?Sw6}6xlqHPW={4G-@7#N!O
zsDLCG`CDudy#M?yd&L<TI@f@s4P-bYWNdJXBxoYv6|`>R|8W<U3Q$7>+&+e?dCddz
z4`>{~@?f2%CusXa=|@mdfT9MZ0o3>S=F-m01QG<b!d&=W4tX@&9A|Lhclia;Sbw}5
z(mV%snLz8lKxfsy5Cppww9KB7zpn~hySk_p7+(4YQQN@3tpapeMFguu2V^scPv=e0
zLJXw4TrTl%gEU;Bd%!`d3u=`|^M6MEK4oUm<RA<9QX23QV2~?8;R{-T4@$YmA(c1C
z+n^c8=7&FAI`@DB$zuj+OU4IK7&D%5?Db~yV7%bd%L3lpS#a<n3uqd$`G6)Ud1ip?
z1<%f7pvcMa?M?gd+xgvte;-2!biW+``h%XmF$~}hr6AkA`1i3Wc<`@3=-PVQv$uvp
zprq0foQ6Q_Xx@T$&oaE0Y<*k80XaC!@Ga<~4=>RCn`84qMvrb5VNeU?l~1>bIOwR0
zhd!OxJP!V|_cZ+Esrd=i+c@~o-ox;Nhvo-Q%R}|sK)Tgj4c{8ReZ3o;|6AXda=5m>
zEfMtXeD2x&hS9V6&wu{bIM7U+<@XZs9w?AAeJ#KH_3~JNeN`*Kzb)WDXke)$fDyDl
z>;wO{J>YGdpo|Jq4Gl_Af^h1vvG4@1UU5;$U<7Uc0L2V{D`+uSGvx3QMwf0#ID>XA
zgJJ@-G9DD#{H^Jr&NDP(Jv&eObRP0N_>;NwcqiyMssE0hzxZ3$ih);CdmMKH4G}VU
zFrIR>JXHGDtCt0|e1QQJhaek$I*%K^1$7TV?gK?RXm>uSF9VwSb?m$ki{aM-9-zae
z7|%OezUS|=0F_ywqNVe7>2nYMeIk06uRJ<0@V9{G4?)fa>GtgW<J<Yjw_8WWQ}dT6
z<3Gz=B`NU!gJ<V&&_H7bY`hyZB*_oH?8vW|N653=(!0|}*n@u`3!7)>W&V8^EN_+G
z0k`eCYg96PJ2ibRzm%wg<n<7CK$I=@?R*GQ>1+ALw^Ot9HpF?CJvuLxs3FzYorgU5
z*I)EJ?jiu5d;%H81~K4?$8mSC*h@~(*aE2d=myObR&+wLUF)S%30PlUfPn!j%HOg;
z9Ng&v<zCPT!95XBxz4&6bV6z;WKS<BTtP>|fDS%xH5Gyv#{&E<8$pvK-H??Ju+rbB
z^Aog;fsM`jbmpiiyf6Tr+}L^mG%w%c^8Nq+?mghHck6%tKG3{0w5JQo$Dq;%)Pe2%
z?a^CvoCCc12~wYXG_x^!bQ*)kojfe>m&ky|sw_X2ya)9OAA_3WrFUVSzAGNxVxY5-
zJX$Y#bc&Tqdcf}t0d3U*m6Esl`#?hrKAoRIJ!nwH1+(1n8+djAJm#}T<pCoD!)q0A
z{#wCU8rgh;C9Tty0h|j!ht?bgA6nyR`K7K9Iym;kquay6qg(t%?WuqNTMm?7;ot7c
zu!5=NAZS{$o7=VX#S7tU-~P88;BT=MVPF8uGL|d{>F(xt?R??U9boZd;suC`k5Cn_
z+d+4s@VA(NHtxaGA80WE|F$qz{%v_I-DdpT4uQr5AXoczLWTlB*VBNy^N8U>{?_X}
z3=E*&C}_hDsD$i>wCF)gXI_Dq&V&fDGkyT&2vAfUe83FK!_bN$1Ec}8mIHJ$e6I{>
z2MTEW4rmYov<V87Aw7D1xCKD_*+99nm**R_&h=nC1rh}1U(ns&jE8#Nm^>KIdobPt
zX#|D8;kSbiSU|&Ypw_%&=W&l-Cjn6E1C<3H-K>05KuuN1Auf>i9RGIi&J$^>3mDRD
z7eEFC`CVO9GC;Q*fHn_<Mw(B8y1S>EAF-!3|6=2BS<TGA@a-TA=!jwd77tKI_YkNL
z%->=Js;FQia@`&hozSBIT6n<Q+k3!cd>-8*hM)zn7M|T=o}D*Al{IKg4%*TI9UtBe
z+Q2QEG8yDj7ZnZYb}rD}Z7=el{)e<u5Ae4*e*qoF&b)$&zg2>jfnfzBf9n^}k({8e
zrzRtRi!o^XEzC7Oo$UNAULcX~7N|2=!1tSLcy>DofEpU0f(uk(DS%z#()sAcqAMT^
zxIzAGe)zljq(E9HH>iW7z`);923l4K8EI+B2K8J)TgM>l{XCKb6kz4P2jd6O+5&KV
zS%)wR@VD54_Ty~lZa&G9*2(?tAPax%ZqUIae;N7vzJY?To4wmX0yK02x=#*d3@9EA
zFCoe=pKb=w>Noz@&&&)A&4(C$7=Kt^Eqw_}iy$w6k`_#qzwae814A107%EVAAEW|w
z!4~L}B2WvgM8vc6G-zDj*YXyB>t<#K24DX52Vwd_xvmGi<FffA2gog;#Gcm44KvB3
z)5pNTvH1x207;MLW8f1hJe!ZQfR3PYv0MV~Z}Yd#`U^T=+C?P;bjjBN{+3f<f99wZ
zfR-tP6MOd-@cvHdNg$v#4F?%5&-3>!08K7#XYqq2&(dcu{M%ev`M1Tg`0($GWdoi6
z0Xq2-)I0&NO@+-IUNF4$&6NSNHtGQM@+^<!ORl{Epr(pvuLz6d!AC5uw@apa9(>H~
z)2jon8oiopqy!jBIJ}x`v;-JR9DS27dH1@AGJw~*!pe(g@N$b5(B^N?&I7)hFT9&;
zBm@{7`KKQAXs!S;rX28Lyx`h$u;hwIH*4boa9=|$6w+Z>mjhbo2I_H!fR6I*2i?>F
z8nFZ2BxMa6+2C)P`S<_-=92=Dl$O@X&EGotFSv6GDZfD{byt8+>TYQQ&Gc;Nez^_Y
z?q}tP*c1~2vB@Qeh2f<<*!&0ySI}Ui$DjZIJ-fv~u?Lzsg-u2=F@k0QEkFqeb4n0C
z6ZKREJT1uIat3q-1L%;QgP>vsl%QTjihPImwLx6|)+t~m{GiH&zomu)w8oYlWCwVb
z(be!ID9gce892+mFuw@SYM|=_D!_S7!nO4h*zarE7#JMCyD~5^fU+HEqc(V#W)Gx!
z1v=}&n#GX6r3?}V-21s0(wezJ_dV7?!@(w-h2f?62heFBpb8pl7y}ciHv#I1dGNbT
zfs91M$_oA#3(!R_(1HS1KzVlF1iRUz8&YssfZPGAo<X%U$R`Fb&Vp9)gNA$$@V6`k
z-LU{V@dQhe<JkEUq(R|jFL?X{a$Z&QNe*cC0_8NQO@;<9XCRFaKrR^TgzSKRDF~9;
z4#}jJSNU5(BMC44{vf3nk8b3#kr!))U~vU%Sn{{Ncn1o3=9hax_u+!hlkn(v<baK&
z{0}eyZMO&YI~hQ26Oa~AN!q&Y7ic{>c&kwJ9`N34#yUP|=Y)g5Wg$1H9}H<UK{qV&
zx9G6Jn>`98f!$LeO_xh`ZrzXx1X#<#2h`{74g2rW`NIRW7|Wwu;G2`QXbHPxBPRps
zw36ln9H3F#=b-)0pf(zRi`P5QLa`c^0#`%uh&QNE;os)Y>eB1u0Gi2TV0Y>j;Q(z9
z0d-1~FL^Rv_{QGg)yu;M+C(XGzzuOaGOR`H%Xq`BR|H%vc!2ha9EU8|0Ob-;Q41PP
z2C;pUFCA}DkpVUA85kJ6dTZDOTzXkRXa6vGGJf(+KH<oC05oX<N_xJ@2mE?%K>cS2
zuU?yjpg9<j5w46U9W}v<K>a;m&^@3BS`Ya3>YN0r0%-;{4ES5L*%%l=O}g$i;8n7Q
zw>^4Uz%!19pt(meP-@Bm%}Ib91IwBqKFFycJ}6K?eDE$|=+exWpnI|)S1LULAGyFH
z4{{Rtx}_E)Mh4JzOAY)j(cl4R&@@gr<lF|()?`r2#DjmI1Dj{J$RVF@CkxP7Z@$SM
z3O?OY7Cx3d2R(LxrszP+GJN=5Poy1u$KuiL%Fy`{6vUu{qWK{ssIK(sbWt(z?R)@Q
zd>R0f13475NC6b6pabE+H`FMAq&+~=;L5bKM8)C7!`(kX`|UtyqktU4->L|9CnTmo
zN<jhV+36w+9%g}r1B)DJWe&LY3pz^4GDanXzhwst1A`;~c9Xi!8kGvqJuqiGd^@I4
z$^)wSK+)&Zts()r8xpkM*Yh|es63Cm$by25;q`Jzd&;NVm%;Iyqcmg56Oc}jM?I4R
z6+qta{OD?U090gvd<OD8taOD3Culh>NEavwKoM#I;y^s?qGIqOU<%m7{H>t*5Reo&
zF1xpY2ial4fZ^enT*&QRP%J^>A?@Hx7MRV=4;g*By(~b5BFM#{Lv%n61^Eo*4)DQ*
z;A3qdE(=isD}}f$M8yDf`rhWrV8_9n!QTqnaD{LrWPZ`JlSLjR28|5KmlMHDBz?g#
z1hN?tPQINFkX!}|KaeXNKsrGV067g5h9E)IAoA>Hk@5gdWPqEC3TRGhxeu}}IR|tk
z3#8aG{05p`WQJ^o01dpifbM&MG<-{VAT#ukb4Wm4i`D~hG0@x(18Dxi$MRk2`Ip;X
zf{R?xdGFB53glLBDSq6=0KCqIzxDdp|Nmcdd;<;azx)Ymy@JYHXpU+<$=`DPBY0ap
zXoew;|NS>`uL{yKYJS0(#;@_uv$y6LhetQ7M+c~FjM}w)Ee=V4kfeQ#$pdsSa}Vg=
zsBUgh-|qQ0Hl~tCY5W@JUqpWW_dkta?^xMok8b8PevJ>X6N5lq)Ytp?x1ECaW+1~t
z%@2QgcAn_vVLSMc*(3R+592`(X2@xwpuPymk1zj$_uhkY33xdXxG~|`&4$sw2Spqx
zO(E*bxuC1Sq4j0q3(#E)?1l$kUj6a^KeReg01dGe@VD@T8}EA{hoW@XSZH`yR&emQ
zFtZ|R75>&cphW<nI^m@`=ss#t_`>QlP~!R@U;wJdK+KmJpbNm|9bf~aO#CgqumArC
z4}wBAK6&(paI(7^o^<JrWIXr`e6BdC&juO?^+^5(x~rBCbu`qm*XuuM<coj(IS<BD
zK8%Mv883py{##65gQ_RU8ML0sw?TuWjEBKvTA+P&9tR&Yd-aC!3&6%ly|9drGI<<l
zkphLBhvp|w*!bwn+n~Emy61rFAJDzH+~BZk<N#HZ-yzj6=w?y=))(MO9UssT;)~S_
zA;ZPYpuvRh8ju)hgG$TV|DY=O<v-9R2+#v_J(wZkZFs4B4y29LTW-+&n!^J+P6E0Q
zv6ttbXXlL<dplVfJbHQb3@?Fr>pNLtb7f$GUX}*X4V^s4UQ9)kIrxBC8#+Ne!=sny
z*ozX7L7*K1pgl_6J&;r2KnIjDFffoZD*ojp#G5i8|1|GW5df_V*#SQDk>9@s%mvko
zAYpK*f%AYRRD$0R%77jM>Cwsla^Z{r|G`TnU!3&(@gFoj>Cp`8XD$YH|2kPzz%!CB
zgCB!BJCMc=DDwOMvNJG1$7w)C0%&!NtKrGs@c$mYJ{LIBCV&oyYQ0p#)g2_^XnE0v
z-{%zQ+62&HEKglJPrHB?)_@N1_;vUH|L!^9NdeG~In?nY=wOjg=O^$uQS)N~{wW7Q
zyI@}Yy8`YogGY>no`SZY@V6d&`~N@a#2nB7&RhOIPzw+`o&#%wd2|c(dV^AfN3YL$
zj@P^p7oFg5c?Y^Ds@Z}8w8QHVqerKhN2kH-hoJqho59_jc2}e+mqYO^3@>x<|Nrms
z?I;U>i{6X>|6QP)3VlFFPV@#cf_CqMjw}TorND@5mI34{P^k|(|C8~8M=#59AI1Zo
z$6Xk~i?m-}gQer<vjU)76t;!4cIxx@>Ad*=zt<%Qdap2Z3-}DX)=MQ?&94~2K@Xij
zfQA1zCkH0}mTw@#zzxiUrBA_gC7`@<<JkZI-R#iuzLz&aYCstWVj*<m0A%NWkWA;#
z7b{TIuLOy9vzBiH2T_k5q<^*~j)mc6|6@?e;G$B{d{zKvj>gLhhz2)^hTAsm46dCQ
z9e03M(|{IxtODr_1?g<A;9%r${rl_x|3(f_BmL#4U;qEFVB&8PeFQR>l?7tLN++aP
z(E;hceitNPqf!9!UDRx3-?@OU-t1;Qxe@GIK4h&QV?p!3cR>k!3AptRTGZR`_4EJ#
zmptGij&(9bmxm*gg}Xtz(!jd*Kyx$XEKbmf7-&=*9L(M9pb@9$2md<RUv`47XX<8k
zgBbSO77}2^Aamj#!7By<{?_fF#b=O;oRPnODd-|GNU3+c1w8fuDllCQ|G#tx8yLs|
zYA;m$4>AB{_==bApqa^D-eech)j%G-Yru#0yqFRRSz`}wp>#8Y#vxxsM1jO!dUPIo
z(F&68<xOy5XLykaVuSi|hhF4?nBDv@^bjheBUwNbPN1PrP=EBeB|Ag8T=x|4Sg1!Y
ztAiV8ON+<^55^1sA9(bNHd})3s^sMX87u%YtrNVhUKGUaW;NOXT7&>SSE!rgMP3YO
z9H9s7WN<OmYVr^irQo^Oml_~;FYiNVkdaV-ZHWN+0dg>uM>qeA7LdUZ$8Q8l_44*O
zvopNt1+gK*vp`H}2!tV2H%B1+<<rah-U8KMHLghh^66z=Z2@uwZ?7{blwX)durRz-
z1dpz>Hq~RcVqQK5wE=orL0$0ICwzKY(=FH;UhntmWvv4-w)yn3CV?1hJ$gkWE!Y`e
zo&?owy`l~v_Ff1(1jOD5VcUS%kQK5uDg~hPa}K^>a%_IU2$~~x;op|d(p$&^DUB+b
z92rmahWIgo3Z#S2S$vZZbe5=Oxb%h?GBTcmbsR4mURu#m!rP0y<r&n~02NT6i<^BI
zPx*q**ZAbg_zAS5uroxZg1^NAw27+MMdiOwua|&F@_$h0Er*Q}G=JE7vZTnT^OURM
zZNmev`O_wpDuEWAH6P-zJXj*`(QL&~`4%bwS!ZE+u=J(n!BRU=eQ)X6?fAi`H{w6|
z29gqGka?iXM|?VOdw}k^_<qZiQ3kZ9_aJDp5p)&F!*62X3o}41S5L;D9+vO;TdSZu
zy+G>|K^HQCHhZ@o@JPM@s;@x)^62FeD3LHc03N^h?dCb;!^i_S@jW;*fzBuD4H5VO
zy+5Qx3O?WC(=Bokw6h!Lg7@HQI>ukFmS;*Yqh$R*%_o>T;ic?qP`%yF>bRDR!LjqC
zN3ZB)GtgR4SRuGH60|hrWxze~@phmlGh>~FXLB6~1AnW~o&W!#g9@I#ZUVhw|2%s`
zt_i#r289o}E^Ds%!NA}8>h}Nt9+rnn-+1(j$~v(#yyUwB%0sMY*Kjd-^okmRa%4Bh
zi(jBL`xIPavTlM%EjNdhN%D~_3@=YXq^3ipra*Na0qI(Q_y2#x+s7d%+=EJ^mqyqA
z|3@vIKr_W)DG6|)?V?i94Vzkex$Nox|FCLj)>C-z05m=<3hGQ81dZN+TDgevVUOlF
z8K8&*^@u@(ZUG>(K@1NV!vVwqb+AGGTu_k+UR(g_%R$E5L6HvbK>fe`|G!7`kqo5!
zojsc0RCHc&>GV-iaP2&p2HH%q{Sauk52*DIx^EdY#sIdw6Eao+vK!SAkftxF+walq
zqLKqrfZ-;M7tIj6D-MHV4dFkO^~lX{EI^k_^KT1eaRpt{bk?!El%Y2#n$4%TM4G*q
zN87Xc*^h${nIY3T9?2&?du{ki_<C7xgGOIK-7??g1HH~nzP%+D2B0;smpTuEC#?Bh
z4}q7w9t2&DGsBbd7-&;<VF(L@Z|4V}&Q~6t2R%EFytq-v%Fue-x3@$^!?(9a#e=_v
z6Eup_%c5s^2{vBr(am$gqnVM>vzzBSXg3dtZF#x=1!$%SGz{y>_|MhwEvU298wQz?
z=w*Q%n2>xz^9HEZY;ww@SLaYK%WM$G=8)lm*RCGNLBrk*9?kX)CG7B1L2E%PnZYNl
z90v`UGC-ztK&Nbh2IoP?MneYXU-S2E1Fw?;EsX=kb?brBwcgz<?>#_Q5b&?}QPFtu
zGz7Xqnyq9eXwI$mQVE|&=f(d)9N<F`*-IvX&ZY%#FsKKag^+S(;Gc4Uf7^lAZJvz(
zTECUZfpcY@xMz0==u(4+FSMqCdcdGH=mHBt9li(XXImYHT4>UGprrey?0?vKCr1DO
z|DVu$pky6LugHb}|6lZnf=Yqc`wS1f6a^n_;lKcQ77M6YJHX$P`2YX^m#;vF>`wpz
z(D_M*m;O%#*YB+dN(5lL{XC9C*DE(4(LhS?p!1y+JUUM!;?r5dqxC?Eg-3U=g-5rC
z0O*cr@g3lkpGuuPx}z05y1fNnq*j3&-lYm2-OdWfoFy2KIZJ|W6DmCcPG8_NbigV5
zn6m`KF=t7J*UKRNchLTjBMP9iqafq`VIT*1fO@eWo!3BF1(a$Lz3guds~H#=1WGJk
zWCuWF>~KkpN9QMx&Vw&NM~ZoL8+(98Q$cgM!X+gh%||?<<B<FZ+7M>o)9a#Q@nUBH
zX!&S`oJVtwiUlKhfBvE6;G*z2v<>z?7!=+xGr;u$sQ5SF-^O6$ToO@dWaC!iWaC|W
z^f+j}DkS~A?(ygj=IC@$(edcK`9H{@8^nUR0+h3D980Gk2c1d+y`(7m|NsBTLBo;|
z-7i5$FhNo~IN)Adg9fv3-B;86CIY<Q<1A<f6g2S)3NUcl0%CwmK>ilcf>;l0-ul&C
z4E!zNLo2!+Ilec5lru0eu<^H4GBGf`xZ)2Aj7}F76aGG9(2P~D3+Qx%8Wj(pUe)Wi
z><ost4c~%FPYsXGTRxpHUmW%ahreg%G5(fj@Ia&k2P}5fLB+=@Kd=J+mU!?YUo&X5
zcy@~Mw}gR&K#OETR5W}$e}I&0gB`%%VF>OByQqL}i(zPfkz^ym-wrzen}6E@(6Ki@
zj1NHVM_Vpic7~lipv458$38FPZv~C#?f`k6^QdRD9%D%*XoaO^jEV_=KPX5&x*^AJ
zaB4t;buMUO38*IV=(SyD!_Kf1bhx+=*r=A9poKoYw$nhup!E?@;YSeRc91X^!s2X3
z28JD=$^c?<X}f2)8;4KlN6_Y^3Q)_h*VYoG1<9?T;Y`pNEW=BGhyrGi0&bX@CE^~v
zw!f{}8FnIB!veAfG`aykRsm5zc=X!t1t~>16nq6Gcs2dY58zgzZ68PhAIy0ER?zAH
zJ3ty<o`)!i11aD~C;**4x&t(-@^T$WL353Y2P=PHBWO<{|279!n^gXmCkzY>HhHB5
z9=*20Al<w$-KDWRKpoYWC7|g#c?OSO+ecRH3_CgD^0qs`eYX&(d^fA_5^$z#vVt@+
zssf;yE&^qn4!r-$Dhp9BWeri^6~Mv(j&c*j1Fuhbc87ucJr<xSfOLH<JUfqp2VOz>
zZwIIndU+i(#R%SS1dA=h1FyT%CV;!0FSo<xJ$h}mLGA|y7bGFHR>Di@34dW_wJ+$z
zp|>xmf>)9{AfGoB20L*GbWkU#T=VQa<I#E9r}HQx50>!02=QTI@UVR0*?A09oZSKy
z`5X1XBg`d&&@vKnn3+fOU&cDQUEnd{Zf0-|#c~<4=K@^kT3#)E4o>Ibau=Zwbbc{p
zLBZX6;n#OT;Q^W+0Nt|SY5A|@j7R4$ki{>&!8zBX^H_-zr1pQI3UN!RD`-hc=_$n0
znAiI}TL0IJy#yT$1~Km#qle``{uXyo((dN@3>u7m1?sbvJ^}e2v?=R0=mO)`|Mfht
zl_r3yYfsC+B@$lUJg-4&-+|S>fT_I?vap2f#U4KvhL?{)sS&;^=k+Uoc?NKOq2bY8
zC;&c`(4+I?i<ep8y2zu`S%bd?v|a}!=u-3_w6LbY<G3@VM(O<c;z22B4Dh2zr?bV2
zkTMwC;Y9?T?eXGIAy{98$8l$9tIjzB)S&d}4Nd@=8&d(g3UxB50041&D?l@akUeJL
z`VJ(x0%ArB$b}zY?8*b#<ZSQ~l#V8V<Y$1)=mfbV;6+X~ST^GIJV^Zro>Y3h4&J{2
z)#o1Fo&tskK!L^n;!e^3{~j|y79IxIPvHIEpn9S6G)S38=XDRzSi31B14Bc#Bm+PA
z==>LAU>EVX+Jnk8Q2jj>VhrfIOcQnwe$VfqD)rzid(g4Wpwr1cERXT`g4+<?&K95=
z-=kaSgGaZsgGaZ`hZoliK!L>H3cmmExQhyS&kDQ>0u2B+vom^h^VS!zGx+rSs5mt2
zF$RSg=z>R(GVlO8=;SmF$phansDg?)SaTVCf0e?E(7)iV`=BJ5=+Vr~=+Su#RO8><
z23mq%VYiDJ<dM#gFMKcl{14hj)qDh8dK{kM(d`@o+fv5>s=pjOx}5_&Ks%K{*AIYC
zH3ucJQZ7WA2In`pe%7_~!R3<~v=em88@YS}9mmrHQD6vFuoJA{C8+QRjd!xDLZq|I
z*%=%`H!*R%xDHVPI>pH`1R7%s9-ZeQF?QLf^B6eNKog`5^`J-twO?N(=0igHB?D-|
zoxi|~2L+&ne%oUPe+TH~6_4J4{~ne%Kv({FSbnZg_pton!SDA0begK>%@@V);7sk=
zd8EX_!}4=&m`CRgkMB1;dv%VymO!dcI$iEcfa*>U%g-f7;9&mwVmWBJLF<9iN1n|(
zDvTw5-~dv96wikZPreX`m|gPx^>ZK4&g&yEIk5k8=YhlTn<=Ecp5+A%KbRuVZWk2}
zpU#J%qG74w?U(kTCJ&<h$*K#{e+jBT3atMns2k5O&j1ZQ4Uf*V;LvM5S(4LGE6Grr
z_Tpgv|NkDzA3$g9@wb3lm!Q0s;|2}}kIv&Ix*o0H>WmF<zvlDkbh!`p^t}>Au%}<X
z*aR9c19{q`S)Z}Q0_<n-QFn(yQ}xY9pzLne-nn4^i9y}B%M<E9m;!eWkItVU&+P$~
zzn45ZUxKnLDD=Qf7eJ*ZBK+a$ApvyBYUgQ>&g(v%NBLW>gA#bRrvNx%n8S0kE+YfO
z3y)k#!T@DEP~LoT98|>20G-0!i;<f_?G<otP68PM$%hR5Euh<dJfL~or&|S)w}0nA
z3<sT`1<I?SO&s9%IHVW^W$a$iSxw!%3qgl*_4=p;fRur=G<bmx3ur-13h10i7Zn9)
zR_y%sqWLE@M<3>IIR#45u+8^fXF*x`73iF5|1F>YgO1b(O&@?8^rb@3#<dT;aqZ*L
zd?W!Bn2s^v^C7yOBfwV}fG-+B<n)M_fuLjsx*ziHY;b&~8AH+|mj??2q?FwXKEIlE
zFGM~GD*wtICO;J-Ukj0cWem^H>@Xu<=7ZV>pn-;$so)M8gGV>3Dnxx2Lj84^k>IrM
z(aq`vQBn@IvK%fi4>1KPeT2eOh=wnCuQxb_9QNrv%ijXIJOi3YK=JF?P@@7WKf*xC
zL@^r@lWCw%d$*5@z>E1gpaSGSr~vr}iUM!}^23AQ@0W+=eb3In{C#sl!ksT)e02tO
z5BOU^U3Jj$r%Rn#7(h(}&0ijt7x-I`fm(N#?>##I)o{NK29LH`el76=RU(})Jv4v4
znCcA8c85!9Jv$G0fTnI9zTp4+|9|TNk8b7)572UQa6^W<^neFwdp~HkY$s@ozo+Hb
z(rt*`2RcguxjzRk@NRf^-UVNMHv!2U5wJO6GZ5hij%ir_1Dj>||0N$dltDETD8Ba2
z1g8%pBS`vq<qC~|6kSN=Q!hllm?1>{E|~h)Gd#Lk3m}rBP|3M4NpST5n%joR*FxoM
z;qs6M6|8)VfRzT<d^(Tww;V$*4Jtty8C<vLgQD3g6B5l$U^Q+W-4j4vz3+z@7#bM)
zTfyz2ZjS^|>p=~)=#Gh@M9!mmC#Y^`C=me_k(^GDxCWgC2CfvXS()Z=G4Qv7)|Y_F
z7kK^#F+hDTaCrdkZocpVHNL<{#)Eo}KA=9Ni;9Iu=f{1ZTmh<p6<$O*f-I;|0(HDS
z82MYkV{zTAt~0>l{>T6ljzumk44_+yp*1<I{oncVMa89W|2>+2{P*ZQTH+77+z>QE
zb@Ro+U;qDi9z)Rr8XsYOIvs58Ap>>>h$Ff=UWmG&7>-CEFO*%tDYf%m$<o&iX%l?F
zXSH>Qs91P*{sfgt)qg;?fZGkAlG~%3wHIQ(m_CyETb)@LUfO}1z^u6tc_CzZP=0s`
zx(&>uo7EK}Uxh4R3ex}Y-~a#M_HBd*tTlHHT>gXZ8-}#zWI-|Rkq(LRP^>WyI%U%X
ze~gPefFgvyr5TjlLG5d6R)JZd7zZ7uK`6$fGC<WV=niAF7>7i5wmrz~id<M^gHFWr
z=w^+W29A_ieMn@tIzcPVi0HV(phP$Ybf_daj*pc@gUgYdFBHClhi5@b5bfb^R#u2n
zkMtl$Ss@z*D(~M;1zT073z3&Xk$++A1ez#11Zq!TDw+0rJ|e<Fu^s#E|NqzB9^I@f
zAcput4Y}$Fa_`GLaKVAx-vhTt8sC6dDnTO+)c&5$0Be7Pb5(P-0YgcYM{kab!V9i+
zQ26}-2Xp7E|G@^JNy?+P;8X~n$Of0et^ez!4R5DS0G)I3;<*FJ%`W$#ZI=6`FF|eI
z#v>qGK~>@57on-3BvFzHGWCT9gk$H?&H8W(I4s(9AYs7=_QvZY9^I_RAu<6_nJ*3?
z4}wlrVq{<do9WTbx)`E{0UFX5z-nH%86J4u<k8LA3X$Cf4Wdn8S#UjwG=2pd-ZKF2
zus97WJwWpt3?7{qL2U4PS^k!*phVbQEx^FvvKCaW^!li1fClUoJbFcM>asJuaI^uX
zsFGBW-$1dY0h)~gjkdnXUj!MK^a732X?R$=s3_Fvfkq-hBa$BAK(`0Qs`zWLI{vAk
zf!pslAP3Sz`dgr}NzfSO>kAM*tiAvrZx1>z3)EZso(vA%Eg%;dUV8B&0o-RZc)i%8
zo3(y2IE1C4p|HjtT6?^n>Cw&lX%blSJ~WW~VUpm!AU|k43Y_09paIl*jlTs_=tAps
z&^g{OIw7{Zg0jh5I~E4e)K&AZ|0Q7{=e&q+2K%kl2ILEnZ$KVadj%Fm@~}m89Hf8R
z&3YE%s6|jm{j!6)7&1<M*rPK<MdJmJJtRSbPV6q3_WGVjH|tc0K0~O!Loj`>7kG5D
zazG@tp^{5sk}n%TquPk_7U{hB#y8Nt@}8aNJUg%Ow}1{?fi~*-TZ};^U0o6=;Q7I~
zmwI;l3A{L)3>s2@=#l*5MUXWpS@5^K1tpr!hcB3{K_e<h`CIpcP6Ybq(fZa0l;7&P
zUweZZC?1wyOPrwXkndKY{B+Qx^Z1K7pp2J%!=w54f6vaCuMDM^UkHN2xb;BENsre5
zC2Zi{fG0Rvyf#Ri0CI&-=c^Yi4d4(iedc(~O@hJkn42W{VA{1Wz{2o=Z#)9>BPc&P
zg3p9H47yJh(mm+B@%n*BH>>?ba1treg5=N~TNZ}b6Fs_F)gj_J+7R&&TWBo3UhUD%
z$_0^Bhf12mCHp+OS>H|oo7f38Q3@srF1<XuSz{schoJJmY@jB;^!pF3e>6OrD+L%l
zI?qAQX9nFe#rya!E5m<L-utW!;AY$5k}&wpLbo4imI0i#U)Vsluz(IVFHr#{Melc@
zHeZDV|28*?4rdT0+2Je+>WqTBREIs9wHZO3ao7n@u$JFpNPhI_W|f7wcc&&KB)n`u
zCDrSj5P4Af0-C>orkfI#7q_;7W;wkTJdQhq1|~rV3xi@&ld(kE<G3@}mC%NwM|T6b
z3)Or?A==~r18{zXjYD05wLd^1Q6kw;DalYG47#TtROmG`Fe2SIqKgoM+y{W{9)6E*
zXARJV3LB^bFA)XZ*D;w3G$q0aIzj?GV0ZZch1LTlPeGxT`|SV!&O?R=ntw5tKKAHl
zJqapZni&{hUxT^_ZGJEU<X+FtvmTvS5yOl8Eue$QUVJnMWspu66%*)u8GoM`sKtOh
z($A>{8tDhs+!~PZgpBrsif6Qj-eGfafdC%=F9#XZjXwTw23Ek|;t%d`pp5^6?&|?>
zl0_Q-2fL2HBL{SX9;ngf$iI!D`9-3Q7=QbB2GB9)NaO#|5oyrf!H)c(5$Rn179%DG
z2Ah2TR&Zys*Y>*x>Hzv?1_p*53=Av`oUY*E;!;0w{6a_TK_ecZ^BBMr2B6bI!NaF7
z!4tc^wu?b#!AF2gvq1ysERgVlnpUzMWCCQq0klTr^?q3VG*mDalv;Z9+6ICQK@5|t
z?O<SNV0gVB+%96N69@T&#U`J>rJIp~!KR$Q<uT|cT2T8%w-=m$oirfneU>F;yqmuT
zw3rW^J-}mCkOIXq{xHZSMw=x57SIX@oBYx}9=*0J)!7+#!e<!xTR`jbJbG>Cf`k!n
zngsF~$4d=xs|GY;0y-4iHU*>zbZ!)6{JUi)sDkdby$%vaOq;X@fx5n+eJd|P%P-;m
zBT!T^@%Mo?A%YynWRt_+0@~JVQ^en*2=Zzsf2%mCq1<cxK#iSYCp?(>TNxlG3NXB!
z2D%FZ8ed^p$M-ivN8UYpZS7DUHvItqq(hn)`1c)X{=q1DK$U^v0qCA!2ZomppyA|R
z+v^}}k)~%l|NZ|D3J8Ih@(=|rAO-LV4E|Qo4LLhNrx?Bb2O1dbX6^0<$IuH^NDS>T
z2bD-KlR=ZP9=*1jAnh#RS_wQ=r3o>ggW=_VkoI0%U62B#xgHLP0!D_H^B@XtsG_E2
z(18^o7b?801<gP(FfcH^ECvSv12jE@W}iSu1y1njwVepkjpY25P(6$<L3e|`NHT|{
zrxIz8Zq|ccV4uiAee%wXh2bS=hZe%v*Ejj)k>@v%?{9B@1D?6{>^$$;dCjL2G$?^o
z3blf!UO?*sz=!{MfHu}aw%q%+e(SX0Z%JfiVDPavz19bss0;xY8g3{Pl}w<i!Q}s-
z*+Nxg&{1>8`CGtu^mV=hiGBP9scTz7tL&QpGuDZMGjVq)LuW`U=(ur4Ps`(_A3)oO
z&A^9Wy%tKF;L*wQ8PpuG{LbG8s+v8ZQx>ngUABU|wcu8%Dgy&61339Wwvm0mV0cLt
zbf6`8*~kq>=w`A1pqv3R0Cc4LQjhLHNK%C^!LxWhDQ&`wY$I?fe4M{Ul?iktn*x8o
zB@^f<F3|BUx;J~d80w{8*CP5iNbWlWN{*eMd^&%=a5aJ!uAm_wAIle|*TI*W_6Gb1
zcVs*}Lm5hscy_yT_;kMfA7Eg3;Pp00c?G)l$mTL6A22bpf>Lp(%Txx?w2|fY`o}My
z{rmsl$J#UyROWO~0q?ZvWGdnGZT-gIngdFg;7KR&e0F>+yvRYc=UzNE0lN%zN|R}J
z2WS}|-;3`iAV2fB=0bv<0}|kM%HY5Th1EMywFMFdmBHWZpCilzP27T-z{eRt!0^E9
zW{+-GX^^?Sq7_Pz{N@2N{(s$-UibeVy(Nb^UJE1XZ$8Wc8p_@d+W6gi5_B__CS&PK
zkbR&b*$1FYCi`B3jx_0fYxwQ8AjlD*J)NGG-}zfEg0dedz(2mYVgU9QX!v{z=rG5Y
zYv2t13N&9<@dKRjJiA#`_*=ofwdNO~#Sfs<WlGl}4{tA=;L-Zcqu1thsmMzM$ao~!
zefRlWAgctydlz1Vr@)@V+<3>Mn^m(NoG*_-eH>;CE@41(tRCI0JP^s#P)SROWH>0b
zbn|)iik?tnXLzA(%);=p9wdfv9DnQ4f1pj0@bUMTTR{rC1311nfd-8j7#Jk@Tf{)6
zbF&5`e=Fz=D9|R6AcL13pq+T~4&d{0cgzrBV1P|?zVPy3VersA0veD%4%xE-iaAgp
zuenx$0d#%RamdZgVBzDCOPpbB(BXR^_VE^#Ga#CQfdP66CWv>uMdb>pu!D$#wr_w|
zxq~*Sfr=KW3eeVXC=+zJC5Xx23Yt;^t<(aE`1JCoU1DVbU047LG3c&$kSxd)P}`@%
zqnouDw1pLXmS1lRWETc##V$w{$X<}D1dndkyP$2CouKjWUWnU35&<5)tR|pUa-bO|
zkPgtMW{`vfhy&U|0^(SJIG`<tAdZ1YFRS7`P&d*=MFS)O-m3{NU7~csnWyCv=zOl;
zIVuxCrNx1rpoXhQ?-rE_;I`Kk$X(Z+_dk2A25A=ni}rwTSoiGw;MsW)wE7<uryyBS
z(1L7Lcwq}IGh3#Bi!R9B;D-MV-@dr54?h13q_p)wz544|NcrK>&0`H3JA|CSX$U$i
zqxm?8<r;8w)meCS^Vor;ah|6KO4LwIpu7&zSAPQBpYmut0!m4U-jQScVbJznaPW1r
z?gi!g){`KQfL3vp$az>EERpm{h9nh_&RZ|~AAmC=e=BI|6sY6?B`46)(;)RAeV~$r
zzhyqiub`d&)4(TJLG-(V4j%^J^4i;?G65XcQ&c8^R>FYJSvmNS-GlKUX#BsE$)ov2
z1Ly!2(58hCAX`ADg7#A&>bepYkh?+Rp2-KGC(?i_>=(H@pib#={+6}i2x1Lv2Ip%r
z1xQI&r_aLhvJ`S%C@3Ab9)R8<!Qamaa#A-Wf{wR<Z+ZZasDeh9oIrhJEj<?S5e=Y3
z3`+E%oxGsIHp7#k<1|4Dzk3fjmRws8@OQpoW?%q~n{>LU1aw1;19ygfR2)DWLFp27
zOaLgmd35@ycy#{k1dZc%LzdBabjGMaR_}GUfOpD(Q|f_Lpy`AI9-XcN{4MLjW#`Km
z(GNiVJ^qgQAbz*6zzeGouqysmL1qSqW3Cd6$6O^DLBR!bI5_Dg=(2$JzJQb7rFw&x
zOF@SS$V1zsDCsW|nv|gFkH4=9yb=kL2CsmN(Q}{_2P*21dUUfsY6J(jx*R09`Sn;J
zQ$H^oL9R<~Q9%l(mv_PKw{Gwn^VicrJA*+{$iUxs5`6c-TjW^ih8%_f8VOjX1*<9e
zTULSQ5UnAbG5A|_!H#o4Y16C&H3IfPqLaVn5U2^%`S69C77OT5J5cm_Bwqwiv4F<*
z4ga^EtdD#N>h{3e*FL>_z^T-y^CM_Uqff8M4%k-07Y@6>{fF&ObnIjT$v4~V_+JtU
zUM}MfTKZuLv6{cH8<Zy?%RgRfLOpPdzl9%^Orahqo$S@!@&=S8j<bOCE6AAAok&f?
zwJ)B6(s%2DlDXiSV*ZvsP&2MskCDH1KIo=*#L}n<p!;6rLF4m~B>f^=8x|K|K`KEL
z&HUg!xu6vyK9*}#K!MNSItg;YHz;KO^S6N3FMu{rF*1No%I))JWMHs{BxZ1H_H#Wr
zx+`QM(XF5Z+8h5He2@$%alyh4mOo&L(6{sF%g3OY>lNh%Yh_&pGN_y5#XW6MTUkei
zk-zmk=tzFV%=OFtkUioSzrh1iFIqHM7@B`5z_M?j8n|L*O#~U#D>_XE;-Wrn7KWFt
zzrdR*A?f>=s|3R_S4oDKum1f1?{yp!-k|LK@(ZYC1}*GhE;qd7)A`e<^SI~12h1-t
zgIO8CtqP<T$IE>nUC=c0Qu#k>ZJz{j)R{VPFgZ#?9Q9L+h2iA~@Y!;ZxB<;Mw1N&o
ze7OR&d%st7zBD_-%cr0|*#z|Q7H8P_h81Xhqtv9KT7scO7(Ac>9{!ng6<kD@N_%wP
zgpA4_QHXwN_5d6NE)3v-5OALsye1SfeqsO~%z^D528~648|9#SCIGaaQvozQtntDz
z;Q#-fpa#K<b~SJc_UJrZqTKDHqVQsyCJX4!91V|7XNeapLFv2GSphQUWDtGW@WAVD
zu>9oF&APW192}A2kl=Ww32JM-z5=QLK>me}U-P$sGYxn^DBYv;;)?{3!O0gqK!dU7
z;KA5;y%68pA`iySyaE=4j|oDrLxsdYWVCf2$fVW-9^lc|t>DZC8Km~;W|f0DZ<iRv
zdET1PeDivnM>p%l8nD}+NkJs_;F2?;;}PKXL!BqUA=-MfM4_QVlA%=Ug{sg0|D6Xx
zGn_BGG+2=OcOKoWYawQui9pP}r2z^LkW$cmJ19Jm$G7ys(XRR8i4SO`w!{G(499~&
zLvS46!L65C=;r%E%)cfKF~16CzC!e2@cI#5h&&V2!%-S646pCO;tT71OGzcz6~!K)
z0bh^KS1-)`z(HOb=m8qOpWzFcaq0Z|B31>OQjV3FdbIwplQg^yo?&TK2aO2hnPGw1
z4?gD~KJNl{Z*4U=4%ndnS)~pRFQnO-G^F_uaC~&LdP4L(g@$n%L=R|bHh9zn(VsyN
zZ~GUwIzY|Fn=d}y00pwQz>Awc;0m@x5}xR~SsOv+4(K)w(Aef-P{spIi@bh10TL%=
zpuPy$CUAIy&XGr~r^$R#4l*(M2WVnSM;RVqdY}L^fv%r{&qb9ed35^<fLddQ{$O{M
zJ_N0=DiH_gYUr96@FXpi-R;KV0bVZq`YtF@fm(myUMM8LLBa<-{ZV54;+!`qRh3GC
z=Bq%37Q{!$>(@c|G$G4?jC?sAyw(&lzYp>oWF1Y3@e4aIxOwHsx)9;*(ajo)ECV*r
z9lLqLFYLVG*~nQHbVfA;SiLwd^>PUH!bs{t<2%Ut73yB$7yrEA=08?Jm=9X63RMrD
zKhp5%JO|6+wl8*ifs*?TkM1%L(2#PLA~*(1^gUW{*GU*&^62Kd1{#&|==8ZD0U8JJ
zu)JLQ3gm9kR4jN<{$&{G)YJp7U!_gJVtypl{LY&%_@HJRd$iv6>2`AfnePeR5rWVB
zZ+}3`CPC(-#&@0vJbtc&N&&3#y%kvo<nEWt!JSiV@r^LA9a$Gje5WGIfXxd>n1`AF
zUbR5-U(r=){)_Ykr+bwA$A~afAsRFPeFL4r4bFcc^9?*YPak(t(E(Na;C^$p07FR`
zsFKt1=oQrzWoLL{D-Y@vg3f337U&L9(Rr~2I{#!0isI*2KyB^{b#Q5S$^-12QdL;4
z_vmIV0u?uqzy#NSkje$Lo&i>7z~)mx<$oEtJo6NQl+U-6K;_x%Gm!iVaxYT(52+Ik
zFTF^qhm^SXU^loy+)&~OGafP->jZLa*I9^4&{W8+DlP`ZGziE&;8FwJ7J$@`Fi*VR
z3$Y(;e7YMbnUrh<aSSiLh;RnQh_k`#1>o}dZ7JCOo%|5@OF`Vf0;<3HjfF=qFSzpQ
z3{mj_wI@74XS4+Pbo!`7K&s>KpsO64k63`}Bc$>}^u<3=5!cPCjBvKbVUJ$k4q<kN
z7mNP?|Nr_C%KS{@8_=?QpI%<KL!jdWT2$VETiq9ZIuH5uvL=Hn3>@Pj9<Y%J@aVyD
z$cc8~^l=<=mJ*149MXRQF+u7xJi1wJUD!bbD4@{<knr&q70|+cP$LOC2m@t;90F1R
z(w6`lA^<4^aUwi=Su@Un!V|Qht`}k%NWuf83e;r-aliu`AWJ|T3y)sb(6bON1|U`7
zUN~rfK8OSE%!9j&jWVD#%-^ye)W_)Vfef;s?M)E{?M<<e1+}FaJv)zfwy3ND%?0&I
zfo@ZB_zxQT0S$G4oqoJUMFKQB2@2EWE#TwiVd9_)8pH;jK-heM(be#qPv;u&;3jBP
z0KERFw?)MO)IWpXe*o$WfZPo_>g9$ExWoi6#$W<F7PSxe1f;KbkIDuR-TCoF2S|M<
z<VaMfPL}14y*6yk{}nnRM`G~z9{{OK{s9^~0G-X@oBYo3wnyuKuU?%M^>!~o^H+%S
z$g}yse0hme!yX&3Klxi<GcYi8y37S%Bj9wb1uV=6KK%r|vIMj)`r`{VkPBK5fOZr3
zd2}9paZHYd!LyssC;5j*Z{UCMg#luvOF(-iprc=q-4Y<nx*>bX%X&O|MH>V`S%!5@
z5oj2f<HZ9x&<#g=j3rXwRu3pGgKBH|C@?6$f)|W|t8>ExuWy0!AM{w>W<5sGjk6or
zK<7rWtnlh&d0wLD*?ff2$9f5PpL|K0OZOJ=u?65^N@#uN(JLw`$j<Px6f_8lXeu1@
z=w=lKIjdLH3R*5X$$`qHm&ss-tUn6DncfvDsS1&F14;HmvI*#RSJ0|ApWZDh8$jbc
z-BVP+>AAZ{1)fMfJ8$}SegJLV2My-D;Cl`(tN2@ggL+QMTfpN5pw8F^(Df6b&X`B9
z4*1Fs&(0SwX1GFf`36=72GF@6FFYW_aA2dVL6Y4)DxhH=PzS38w8q=Rn)iAsX!>I%
z=pIhc-pgMvc0tNV{+6krBS9c;H@t254RlTf$fVW-^)@fF!7U8%eij~iP{#-|K4<OG
zjm$L#Evjrj%wY*}IDelBc=(q`4y5BKc(`OgY`A0_jIjsCIONeQs>{#L@Dem!?$Imi
z2V&m^4V@>SeIX(V%_ETH!`}j$4(x`Uo6~x-P8}Mxpb`Ld=`LuCUT??*mI=o}lYIXn
zS5sUl{n*_D4pPuvb)X$m-CMvTn7xkwK?kmad<(kRZ3AeOq*tUBG^b{Gz_IhQW8-7c
zo+42C>lR@KEp=pIED`W*wsB)9;cR^L|NsAgog&PRofjM%AN>Ds|IfAcwreK~V~G+-
z=>f)4DUh1u|2svPJ-bERJ&&`vg9;0e&Jb77v=NJs<%QDaogaL9mw+z}_JL;P<_GT^
zpMftfc-z?mInfbPJo$D$2c7i@nmq1=cmR5M^Ec4J!=NnR{DKjBBpE0`K>h)hL!c3k
z){}MaAn$^1(`IL2@abiNdh@j`xP8$2Z5POGp8T%YJvv1kK>_D!d7wo2I}7NDCdShH
z9^E4OAeq-sz{@mj_JEdYr0oSS(*RG_gVMO=7I2n>uh@X@1?BJa2W14P-Jp&(bkB>6
z3V3xVXhaZHF@Q!0A*H>Kii2Y}iw^7{Eok(Ch6goZ<Asp1R~Hq7Zpg4dxa^-g?f-wz
zPB#JY#it;DgC_6{&VZUN{2icSYS6lx7yJ&8ri%+`Q4J$#Q4J$#AMrKNF}s#)z*PaL
z5Ct{#d^$@qB>4M4w^KnK(R_^25j;G2l;!2JfB*l3%z!M+dA$pCgaKGr_ZIMNH$Jcv
zfV$a05dn%K_(Ebf{?<0oU=Z}=DrjzaSp;qqGLUGJ4cH`DkLRT>=$eEn;3N;q(xCHm
zL3SgY134kP^-{g*>sWC7d!l4$bJYB8h?>9av^={ZdHW<dZy$!b9prz=sOABf$T83u
z7`PsUorTr;*`wFw*lSIX?qCUzZf6BoP)qDEhexNA0=R|N9R%JE{DQj%TqKqXd02i1
zU7!QW|1a-=$B!VV1bbi))$L#<@UU0`x{(yLrt7A||Nq^PK=JH6+<K|=B7YyKZUdc6
ze+g7CgM!Gno5k6qo5vA!KYA>v`0@aI(Fru^3c5xLJigaC2Ygr~C`uPFFff4UVIk+R
z`+$xB0+pu_dtADwfQQB*rb5o~_331B^lWBebZkDv*r>w%|Gz!Bm~ycMIjFw`RFgpK
z%H}2DQtCZ84Zdvo`yX^111NvIJPsN!ONO@dkg^p<ZUUWU3>s$#A36u}A2bnz+EW3b
z90toxpfV672tLFBlyN{D(4oPgh9Nj>Sxtsyt(Ob_{Qo~89Nb}3X#OeLdCsHrdMP`o
zsd1^q`^98&7KY}3lAtj%_0EqkT4KQ$Vt_VSNqF>%igL3vfY<5Yd=VrLt@TwrTK|^_
zdGw0@;{r+k05#rCL6V)I6_lXeJfQY5qK>`*Dvv?^1B32B3CId&g%@{n{(;tRGxE0{
z0=3h+p}WaCZ+Ub(IQ$1MRfnu6gDng9;PB{nOaQHzO7&>o0V+%wJbFdHa<Ma%M0<3L
z>VS5QT3#&Se32ytYEG8$fp)QcbC71_Zw2LW571r$&{?Jq3I8X6bc5HIiGa3|fI|+l
zj|8$_6g&{;(JPw31#b4N&4e_2UW$SO0L!X0gJ{tHGS*g*x?a&woFH8sFLsH7+98l0
zRoVoPUeQV}c81sMq3s#;@HmrAQFwro11LOfVc{VII*$V!9#Mh>!vmz7i0}vi`;2vN
z1|&Rgir^2AQjoe{(MKGR@K_~+79N?Lc*0{(7DeF!syaa75z7fpA3UJ*c);P|B|tDd
zK)Q(t4+pT%SbNhU;c-$Je|V&V)b)y9VuyssEMc_ph~&T%9&0iw3J*}R2MUk99MJIi
zW5&+l0S*r<euCiv(oIBoC_uuaHVqOUJB9FvM<_^LujnB*NO*J!p@oMhJD%{ElR;5<
zfT}o9csyl?hQ}Mwu03#gXz>vY50GwR!UOCx*4$J`c&rq}A0DnCb-kjSSRvt2C5RRt
zmTXAj0U94Oy!2ve!ngmR-bC{ejh8Qr89<k3LdHix<%@zxH>(KPUydB0qdZzpGcYi`
zFp39HlC|ywmAlrm`I(@82Ix8la1m+Es+Y>ez(3`nhc)Y(BoONm=P3_s)`ScY`yiOT
z2BHGY-jRY3mq|vjC6Ls_AnDCOQZpwVp}qpioDzt7j#H(w9@eaV>0F=<Nxh<(py2Gh
z2^pyt;e&<_cudHF!K3+&g>UNtpUwj%DxRGuJv%RenysM45ey!kr$BvQFFsK4AF+V!
zkM`(htp$}&kijpD!{G2js-JAqAnB__%%k-{sUfJ*13I1ru^tP(#sYN}LC3#bhmI$8
zv(_eqyPk)j@wtj0HbJumv0uH}_7Ddb0|PjAIzbWA?QGHQAk+MUvH1sQc@((K<*o2y
zT`I&ir5@eR60HYHWIeihyEwqcYqPOK?+Sh40M5x3R-l>>Gz13Pz}oHL;L!~}<O4K<
z86AgM&&+x?32eY3sQbA1p&_af9d~$wM=x(GD?7uBIiOI3-n|hIYU}ih27@$o9(=Kp
zhlRnTla&eN4)D}2Xu~d|-w&RGgohWn`Jv&_D|#NR`}7NKerQMWScxGhdWyl0=Wp50
z$-v;z&D*2H#Q?suqxED7^v=eWAem0nB9Kh4XgAoLn=c;29SAW8WG-k;M?Oe(H?I#!
zHR$dSggJ#EnNCw9kW8<r57eC5Xy$;-1(~A`Qr*qV15%A@jwMK@)AW-zI2d`M<^-de
z12Pw6&VA4s-rc-sK&nyAVT72o2_(}idWHpbJlxF}+-T;2%mtY<9b!%oNHwZCCqXiu
zrbQr`UeP|NIfr>s!x>~Q$Q*x=>TX^ikZM$OCW2%-O^rY@y`nx)bE?tI0htRjhaIH4
zo0kWq8r2-oeYGB)rk}LH;lm9z#~95Vkhvgp_Ja?f=RE^bjcSe}$c9eSO(2<G(R0j@
z@OceNec*%%iFc5>Aalwg=JbG6qnh&)B-3eH1d{0$od`8&F`79bb3x|lgH(6(`hZlU
znzIok(`jl1lIa!ogPIeKW)8?)kU7sm*P?Xu@_<yMno|ie=aVKRe4yqCqnQIT7i7+S
zh&g9Ks!`2xgqX7lB-1N;h6xfrr@2w%9b_)ZoN$OaJs{Pn=5RvHDFVs#iuOXyX+|>#
zWG=`Yeuz0fAl0bmTm;E<ni_#*dPRMp=2)Yd12Pw6&T;So$Gkis)u`sogqZV50~|j5
zP;)+Wq52DCF36mEh&g9Ks!`2>x@QwerdRYbBP4uQqnQIT7i5k(#GD?GYE*Ne?kNJv
z^omZ0nv;xX4#-@PIq$*iw0J{6s!`2Jg!sz}B-1Mz1vN(+%^Z-qAaj;O%wYkkMm0wh
zV$LgdaQMhU&AH5p8a^O%LFU9m%sB&6jcU$EkdHe}H-Th&MQ<}e!lxU}9FVynbHpL$
z^ng^OnzIvPP7z3^S9BiK9A`9hK<0wXIS(3P>gM$UsYW%Y5n_%JNTydb25Qc44pe`E
z%mta#4l#!Zq#D&6Pl!36)F9ylHD@!LIUsXE=Ga5bIRjFSYK|bpoJ}B^UeSC1*%&}Q
z-fT2;K<0wX`3@S?@8<0RsYW&DCMe`OO^ZM>y`oE?<|w0?12Pw6&U%PBJ|NYo<}8Gm
zV+4}v70ra2bDJGCd_d-c%t?os!vj){YECA^oKLFY@X>{uGa1bskhvgp<RRvq0jWkc
zhY=KVou->WGQFZ7{z1aW8_gV$xgc{O2Uzg-fK;QJ16oe!(P>%)lIa!Q0yT#j%^Z-q
zAanY`6EM6!Al0bmOa!^K)6@tg(<@p8HD@;)YWRT61)1XxF^31F8r7Ugh&i8Bz~Q40
zHK!QO9FVynb0BN}dC!1UqnZQ0o}trp6G*04^!;B*_-Lb<12Pw6&USDskhce<8r7Va
zAeVNU7J+1XMb|^kdCUs;moBIs1v0nwKuNJjH*Ww)C8`-)A!e9?WO_vlpk~YmnE|>>
z&!hEri5)0)KV=1Xf^<E)d4)h~K}YSho-E-753aF8M+*%Pcy!8sRt7cHK&PM_hOJKm
zH6Wo%UV486T|om{-v=IPeA$e~-;KuqjK<f7o>vbuFBy$L8;yS%jnDl9)qZC*el;3@
zGaCOj8ejP*s(I09{LkRwV1$3Q|Dvi-M&r*$<6lPObAu;z5a!vV@d>$SGMf8Nqw$%+
z7vLbww?^X^qw!ax@gJk{rQz#2A@LoI#_xvm!TkXb@c!m=9-Wu@TdF}R6SRoA2*l|2
z;_$Ha;{ctvY6F^uH{frH0*kXctAPeC4uS{m_*+~V85q7bt^)0<hg}aMsv5=x8rtA*
z0nPTli2lb6S`*qT4c6|>;n6Kx5&~7g4q7j51y%41obkLlzBPi5mSp5_1)r~E&ATiZ
z)IkO<2>#v(8W>^#ZH8zCjVpU}i%tc*<|5>Lu@~?ELhJ&~K6rF{b9h*T_N;fis2G5*
zud)Fxi3(BCKzQoKKClMR=5?qFc1ZuO5OnjapGUVJ#E23J@Crb1K)mQe=qd5^=)4IM
z)p)`40W@a<GD)Mv7__;f^X7{W5T8v2?QVaq-~l=juiKjgq~73#3z8|*LFW-2fF5rN
z9iIfpkA_b#YuHaV2FOjMprPB&YcHJsfov)f^5|x@js)d>21ZEN@~}@g>r#0x2FNK5
z5V4mj;47#cpy#vs^s)-0oA(KP_zT#)*AeLE`J$UAf^Oc$A877dgfMS5hIvQj(A;<A
zJtTj^{o9FdUJ$}OZw&Kt(akGCH_r*(JSK#Bzr)e}D~fKO3c7i}zoYpVbUsz<0dV-O
z#xQTMESi6>fR9c_ijVE+<|X}s$8R)-d8z2;wV<0<jBcI~!aQya^Nz}(xz7aMJRNlN
z4*iC^Z#O8XLq>2wb&gLrYc9HZPu`-%@6&H+;a7w(FB`)=QFQaBpqn=j-8?0PdD0l>
z?UhFJuM4_);ppaF`UUsz=}`3al8SELmp2gqg2%I7Z2QX$-ImYaau{>~S2wG%G#7(!
z>wyx`?2hvnP+R2Si}JtB49!3O^S8`|s1Zj}qYPGa^F=UBO({gpZz+U198fj-Fg1Y?
zHTRL!y!{Na>*fn?m>OM(n!`wHE<n{h{{wXoCq&J1BsJThY7WEHJOytQXYEE(GXtt-
zK1|I)h?;yPHPuix)i5=4A!>q=)FeUGgu~QSLe!WesquuWF@~uLg{V<RQlk%5!w*wq
z2vNh1q(%g)=Jju=-+3WwUP~gv`R6A{7#@eIc?sGH+s%3&NzEOon#C|RM<Hr9BdIwI
zRZ|aBvk;<YI+B{zP&LsoHMI~m%}8n{L)DnW)PS1IKHaS0NNTE}YJ_2GOd;ktBdJM(
zs(Jql>UTki8g(Q!&QLX{VQSujR)2J}awDnHf~r{#Q*#oc=Dh?W40)hxnqg{|LeyMF
zQuFB}B%I@6Y8oMGwj-&z232DXQxgkOGaE_G0jL^rm>SR#nm*mE^+;+~Le+f!3H7@u
z#GGU#H4~v~&coDvWME+M>1K6DQd0p{vl^xbbcvr&H>)<1ngpntc9<H_@*<yZR(>Qk
zPEa+;Fg2iC{d~GvKZ`@cP{gBGR2izq9-^is)u)^FHj+FyR9+q=e}J*X)u)^FFp~V|
z50LQv|AU#K`2b^ys!uoTY9#p^Q2F~%c~+0k8?QM)GcF|@u#tH1Yz6pGx7TkF=RZPD
z%(?6WI-+DJs6p3x%A=Q;=OY`#i$|ZC89?h(K(oQ1LspNzc<}&qW~(UFHK0>p?tO)p
zm&Zy3K%J?3KOhadCeYC_w>_G385m1KJwWG5J9@PK=WhX>!vnfC4Rl~$=M8XcR=k80
za$rt;>|u}Ya1QVq7|_WskVA+ykR)MC9$s$-t&el%@Br`8emx&FUk=(+>JKmNEkNt*
z4#SQ(`}m>_<j&5+pc8KYL+2YhZ@g?lI<En`ejj^y{CUsD@Z!=Z^zgWG9~>U9-h*QY
z6dvckpoYh}?*kYfXZ>)7M;XYSc*6s-{=tA>vqVJ!e1_h6@ZrnHN^(3veT{C>*OH)q
z1!w_*<|mLROJw;qN>mhF4NrP@-tg%B1v)+zv@jqp{v`w0wwo_zJOS0rrPn|43-I1~
z2MV;GFTS+>`w!xu0rPKyu9<uBpbdKQ+**%rR(7Z_z@~#&2gJo6hOMXf>1BQPmJPBY
z^R!3jwHH@EfvhNT1gG|H2k`m_Sx8GhD8ZxkQi*^^cNb{2tA}L=hyrc5XI<h84=7Nx
z2)tg%r<;{i1g-6Xd_D)f{acJ;e<(5bgI1(^SayIYu>C67?QaxDvmbPR25kQf+<rzB
z`>%c^!vCNg?P1vgqQLeq@xki<lR{|rzX12OA@ikh`#awthkq!<elz6o7e@|%E{|@n
z3J*(<3UC8l3)N<yZdM<3OQGj;!0l5)vF|Ck8&`tgz5)+Rj{>lLyS!0+>eJ17MG(!C
z%wSI<`d_<WBm1wE82d6jEIl&7_IY907lUpe=xhM^{H9MYYdDI1ti;%t;9=>J0JiUz
z7rOtR2%z~-89d;E@ZaZG$o`x99-Mygho^#vrH2C8zAOy;RM73)3?9IMoyTe6)604k
zW+P}})eB{ajrQP)P-u=72Ui5$kQ~e9(H*7XVHu$T-kSQu6YfJuArI|;LrR<%si1X&
zpjob?{4L-UCAwvgfpl2jC@BGzNS(i4Fo9-eK}wF5<a$`%C<*oG<+XbSDve%wb{=@~
z`VFX<k7e-a4F)av_UH^{C`t0@mV@)fN}It68oV&S^CNh1oQsMEq;AoJ<xfc6=Ly*>
z32`Y{2y{djtmZO2@X{1q1%c1U3k4r~q5-PZpjF@N4#awPk8YSQkIoM-K_^^-YCVKJ
zJb&oCM2^p+Z;6Oc2@gvT32=PQ@_>gfs3ZjCM?SRl^B6oJhDbk0Um)8TN{oF19+n;g
zVEeQ%?7PB?W?wOyeQ_xEJ$*xj|2RA>JvhMj?Q%!=Ukti^%xLy~e~#?GQiy#f$mN?T
zI5|L5D~Crnmxm?9HXjVzp7EghZYp@V6cqoUbDA%dNO*wm_&VUxdGO__H_WK}N&mV*
z91lK!5Pq7mfk(G(ybx#(3UqKihezi%m(HUemOnuavR^NHUxDgo==sClejM<zKhS9y
z9^ImvPT--v65bcdP?gP~alg)wFFwCzX4nN<8x2|=0a{}5gR9P}`G<H3Yx57@dV@56
zJywP1Yz+Kemp~g!z~g(ZZ~0q9K$8HV(QokLMgveg%rWM0+Js(@Pt8A>%1(gvaXe>Z
zsPZfIX?^R_ZTgrSbYN;9Xgfb-5r=E@FXmDQ@Es*D)J(qqcQril&DnveJJ^B06+G$G
zc@uQQUbZLf9PCnY*mxYwI?#C&U^m?I?EC;4p4a;h+GA$z(HjoQ)583%aiC(LI~bPf
zKv&LyS2MnJ1?}ma0CK0tGd6}QPLFQhbZ#z&5=W4bElel|B%}utGJ**Of`p_&Lh8>z
z0h0-~fmaFa!5GjrLvQ(8j(~y}G;9l+|9~}?Zb92Mv5qk>FTY}D0J$GDmTCEuzXfta
z|F0K^Uw~t>^)slI4wCG)?Eq~vvHV$L?9ut_#bU5LXb7}a*`r%j1}t~6MEpe;Sc1Q0
z8OY{tKMrX77qmFE^W*;s;I(R?EiXs-TegFCXLNpi@%=S31L#y9@X7eCmpnT~RQOx;
zq52`$XMmjc2z2;E=dVxvf-Wi=FO*(@I%JHW_yt^4G$b!IKVoV=#Q1U_xH@%U0NvpL
zT8adXqL(t(-~NNn=W&6g>6hohW_^4S@|u|;jsN`tuq~hXwGO<j`TPHW+JtU5iPi)B
zt)d_ocDsSr{D5vZWBUhMM9s_J59)A$YY@=A;h-g}P;Ys39_Md)05x0THK=H3hx*E+
zQ@o_g17a3<{SX(((f^tcF~8&lZO#CtoLe5?^;0lMAHM|}ECRKgAd94sJ!Jg{<P>rK
z7SN6x!vimKL1uu?Ie-L@5BQvZNZ>$E3v%axNP#*#0R~X1Y;dA+<M8MX0JT^7Ta^F)
z|NpH4G-A)h-y#O`N%Jny_8SKN77h@v^WzJNm*8FpC><Pp!TpMv0dmOmu@W0ZNP6&V
z9eZgAa^oXL(1woY4~#ECBcU&{LFz#hX}kXX{|_!N3=h2A0AdG1WJ-3ueu3297JG~~
z9+>nTTm*y0x1&L&31WN^c4+-4P!{wCE$MDOQ2N-Xo0T231PXNb6es{SqT^oX-2??J
z@_E4U`fS-F<ns6HGq7d&+b0GdmL3M+^8S<~BzZvw*AIi%;)AVyvG*5bhr~0VZq`b6
zv_hHTGpMu>UC7SG@G=EHUnANH;)fvkg&@AmumAr+_k|fA@Hh_MM0Xg(n=m05G-epj
zzmKuyKuNU=|2{6)mXjq>KD~jAK8y!nD^2jRyy(*##aLqF$iI)N<v@wQEB`)j&*npn
zAazDQows@;_Pg{(C^Y|;bnK1X@5t|V*tItj#C7F&JME%*qGT`V00z(nVBqv<cuDg@
zG}8I*{QH6!H7~q=!@p0+@POup*N?%y8bo^m(!W#K4?YX0^Yn`+{HzQO)~fv5N|^tb
zs(bW$GkWxjraxq3c(IEgya%RKsQKA_!~f0iTpb$zF*)#0KmPrG=MV7W!npXu6OhiM
zZGNKw+DF}a)ur?Jf6?paTns+l8jcOM40`-6PeFq<pnF3<zbN8oW$^4g!oQ8JH{fdH
zqrVIc45bSE+uRsEdgB<IUl@QE^hv<i!-0;8<ln{&5ik1)zWE(|*MTxWD+6f7p=a|S
z#$(KSWg0%c*^K_ZC92@_?s)lG8GJfFd3GN0>^uOve#?cQmBHzli!vi<HS2^2pl094
z7uWf~UgU299c;wE&4aNw5b7fSR?ykr{M!PUJbELTdYvxVaPqf1fJ(y78-^!c4KG2a
zdR~iw?ycnCCeVD4(WTevf@8xE&T<*hq||d)!;=la3`*~VwnIP_U*?x*X#UAmqRrn2
znvd%|;i7o~bR}`$bp{3omtF@(-{b?D2SEqebl&t}y!B!NA1g!a|56#yVb!2>2oM(&
zA>xyN8=FVxXGBPf!$Pt*;6lSM&T@We07AHBA8qvZgSN2x^s08;XJg=R0nOKe4o1Gi
z3)*`Z!p`Vnd9|z$G&R-BW9^}N%cs|c33PkR3udrmI)C!F<bv*QI?#Ctv@w)_8;gkL
z36~BQ;i7lo3k4h-Y8e^$TLu38|Njzn_Kf2WP+J0Wy_N##d`b}4aSzB1h9^CGMf5xv
zZ-CD0X%_wuy8qdc(W{q7*`xE8Z}Nc`6L?t}Tw9;GbUxy50iEVzc%buO^8rT73&&Wv
z4T?U$d;r>|1UAYe`Jkib8Q<h5p1m$CjIWm?hmSKfQSrBJ0aYT+hZ(`=Df;xPw%lW5
zc=;c6Y7s&`B!580KftN^@{5a4m>Iw&$Sse~kDbR~L_P*pRT>{&Xgr0Kzr3L30L&hp
z#xLBSGBb4kd@=nASj92au?uicgqZID8ecK^%rC&IbB~RIU*j`m&hRt80I&8vHqeFO
zpv=u5a*SW^M3IkA=Rwe9q{a(-@Dx#L_GkX6Z{R6RP&{>l22bv#dGgnNd~xg%Gs6Us
ztp=c*bHGKONAnSf=(zZo!I1tRzuxUC>ooql8?6UGyI~kA96g$UF_&>3XUxn?WANxa
z0oD!GbT|!S7<eoZWXj<QAm%UTvYW>l^Ahtw>R+GpX#T}gcH%grZf0KEF-Oo^*AuUI
z!umtu-~t`u-!zCvKk*B&hTa9`z-yopps2fW52x{m97_Xv*%R(%AMh+uX%5)CY5W=x
zk3#(Y;`&3J-c12_KOGp-KpwVD^Wd+$;c@VV0?gMQ_<Rix0+2_+A$J(W`o&y!2jS(5
zi1Y&X{6SRDZ$dh+1nU3pJ>VOs9dBzwV*2KR+chc*Hy_^C&A!9NaR24q8%3c|KO4M=
z0MBHVmfX%!Q2_bd0OH-dF)9||)`CSEzs3zvgdcoy^#L>Zk|dO<&H&d{kntLj8TVgQ
zS%BNPX)y2Gpm`q=-yqLIybWnDg809f%kCjOe;MrMv#4I)2a9j;5uy!06-v09Uve5A
zX!yy(KkdM0&|%aN_rQ)l1g*;l=dY_TB)LFmh5mQ!JWwj|(g(aq>f;L*E>;H6ea!s(
zPP|wFYC|9BJY4$BvDe{h^Mk+qEucNaE}(l+-ZwwE-~7XmzeN~y+4m1m{uV7p1_sC8
zfD1022S5d&w<CDQjuBLL_r_LuSpF`TdkJbxL;MGkeGF<`Ti)ky@dbBdjx%<+{|A+d
zb)2jWy#W^-!A6x`c5MEk$KSFNw4Ji^0N7$z{?_H7IfmZc3Qx<w{B5&9C3y$CN9RYM
z-gL$ncAQ{eKwaJ13A*RG`N#hfPG8HX{OzD6XNI?ZET8&xKINYZU2os{$))q)3sw$R
zhGVV_4B*}r_}~}NuJOZZ6F}}Qx#iN~$^aVH=&faZaf<_NhYQq2e*CRp!E0Y2;qB9#
zTH$H=hrhiSGBj`b*Q4_<|J1{;r$PJ=l`nhZ0(Esh<BJXsP+cHfaFY!b1v~N>7#Lpb
zLC0HsE#L5i@2UeGGv?ai`X5xkfPyL*;tc+M%q<5>gk3BTlyErq1}IowC}jh=x%3#w
zr*C~a-||mA{1S9TCX$8X5DWj@fLNFavd|FXKCpe)LEEmIk1`_L_m~~*ZLod(EsH?m
zj%4Q~u$_lqclp3#2DEP)>cw=%7facZB9_0s4BVgi&)<^!@Be>a%ctei;M0it<rzTc
z@VA6Pg!x;{K_`MWA7OOta8UuLkQiix$}akJK7R@7cEH;&kn6NN|GrcPRaVVEH27OT
zgAIGb-v+vM*72AtgN8@vM^8{x@<aUe+6Wq%FC1+o%M2Wwf5h{*E&=UuxBSE3athS?
zZ$8f05e|01Z8mT?IQBYRaOpf`!&!b9<mA#TFZut0`cIvQU+(z(|G!IzJ0m1fGQC&{
z(*esP{Ox6b|NjSR<8R6N3krZY{LP>RSfJwu;65#4LkTixxE4#WmZzl`UrIv!sL9_t
z3DgU+{KMbY`S<^SP*ym`t_eydx@@crpoH+$vGV}`)WbfVPhWC@`g!p2GkE#X_y)Ac
zlV5WS^w^2h9-UYJi#F<l_6S*kPFB)l1-Bz#vw%_{|32={b1&*4mBl-UhJU*JEmIj8
z7#te@Y4f+tVPs(V#4lhfew~fMv-7S;ujrg>Yz&a538-=C{sq*#D0OyhsAbmh>~&@4
zZ)pLQ7odTSyAZvskFT*Ycyzil@M}O_)OZBsK*&IcV=VkU`(9BO6tiD{2Agf=*&EC3
z(JQJAmIR#+4!T7W)ImB0R^Z9+a@V8vZ3&A<XDq`f{z%j6YitZ@{2Iqz_chq-@weD8
zGBEVIUG?m|yW(#t2miKWMo@dV`JI77!#~b)NqBk#WlKl?ZLSQ>FAQur%RcyaJ^<fR
z`SQglW>ABfzx59&A!**-Q2{QuQdA5)oBvjLbl&sicRT9S`MmiDM-fNo!GkZEKYJ`S
zytIO)gtJ?$Q+yZb@PHLeB|QAwdBoB>dBi=M4>7G^EMe#0#v|6jBMv$TM#HD`;V~B$
z1BMsdzJa<~Z~0r!ftp;*F)A89nvX#~d$|{UzFsyXC^{OhvN62OM-nIp3B-ZYEj&GV
z_PVmX=0mP;4>0m?6X^B2(D0M9>|^J}=7;y2UphAYlq`GF@GHLLe#0+K{was}w_WmJ
zyx`ILmcJFW67aQDLp`Wjx(nnS$n8hM-~Ru9ssHakXcmf<4P>zrs3i!W5A1|Yd>uuk
zuTwANe}d!kUBfS3{ua;y`3=9c`CE1~FfiPF;n8^yRHb|LiaK0@r7cj3e+`})Db;SM
zW7hEKbz|ml*$b*{AW`kgaFcb`6;Q(ZaoZj-<Jl|9fMUjSh#4s!y>Xy4^!zf&0#F(P
zU)<e!^F<q2fd{|KJ$M=dRs0^EKW^~aU14KDGW_NXkKSU&n-4&a1>aZ!5dd?+8<QZx
zQ}PECGJ-BD3Lc$5?z*TbAQ|D&>&Eh$3sOEq`#&Va2k0{Am#nby@33Hx#y6mrs7EjO
zh}3JKlhCez|Np-?fU)@(W0^EKVS)0=qu>8Qhjm-VsAzoR7i8m~dcdRc2uNo%@_p4{
z^FSFBWS#@)PVCNGFWM32DS7nzsDKYZv;f(}`|tmMP)Hdb@UV<gvEZM2;I^FyEN6qd
z^l0Z1fwr1Ef_6)TZl467+0NezKHuM3)X$KMp`_ZQ+ld1*Y|~J}13Kie`UYtHt|SS3
z3uia)nm^!S4N!mLxQmJf1L$aG7Zu1AtH)hbAO|(Vk8bR|^`g5II^KD-L=JR;sAuO3
z$ehRj36Sl`xeSc_E#Uhs8;^jT2P=^r;~e7;Pw;H6uwdYC*$PT?y)G&Rpxu5MAX`BU
zP!YfYy5%Lor#D3<0(AUeg->sdN(gAxsE1E)iAu(6Uyp7dl?2d*Cd{SW9^Ig$n=KtR
zO3XkFQxA_`(bpH*7<@WGv&Ef1UtGHk@+^N#A!sx!*+(S=q^bbad}aLkVk0Q?b$c85
zcD@9cO0Qm+gTtnD?n_6|*ekeygqZJmsq_E;{|TPS0Sbl(JPy8M245yG0W!Gt8|dy{
zHb#$5lj9!A!3v->2v%WvsQl4OQ0oU#UZBKZ^P7xsPST9vcIRdO7SP~YbCrxBKjbW#
z<|<G~fliG9g$?+~0T2UxZzCvt96;e?;n7>85&;S%6HxdBfI`pXwJ*H<1%;LaQfOIt
zfI>^xqgV9M1yDfcs3`b${`Bqq@M6^^P*{~{cqIF%n1I%;26!-jeBlG~AUKd7LSp)b
z&~=cy(q$gaM>0_278+illhaEcfzFtCeJ5?g;PLOJ^QivabrIwb!v0md22zLHznq}c
zD;|Lt*x!M!c7J^t9{%9&riMqiqlHK3IZ#F|$!)HX5iBWxA@uGi=q_iE&cpmI7eT#@
zZV!pH2_BZ-3Uv-1-Q5PD-7DQ;7B9f<t8Qlrk6sVPZf60HPH*rCv@)nc(A}&7?jSg8
zFnTaHgSA+CE7TtVExF-uQ2?Jb4jprZwwJpDC0Z}>w=4yno#E)Pf|0)!)J151z|{PM
ziNB=}w9&ZoE!biFE!N<bYylEJ-4P0~{*<rfty(9a?go%up4|eVr3@S%%}k6SHQfOM
zppiqL&H#`dtq(zCY|IT17dmJ#`dZ%d=>%)6+2_%10KHG%qf>yt6?BuXM|S`R^l*C6
z-P2I_dUX3Kcyz}Jyhzsi_y3!lBO`w+XhFH*CD6$;eUKaYcrJsYfCYRAV)G$J56cUs
zuU;~POLT^Y-4>vV2{dQhtN{*E2Mdp62L)(wz3c(Ev>EwZCNqGyS9er{N`>SLKD{iL
zeY-t0d@Vab%h7$h!J%6x^xDIx+e^X6x(jsKM2#Wn?yg>u%grwseYBf2m_Zjp{P#HS
z1THp9uljU?b-h#vcYr`cC=5^`us)W{p3MgteIP;P)9IlBm3#?0lnCyBX9ExGX3$7`
ztunY^>2x;m=xzp|bq0y@mnXn;8<75$2Q*1&H-nC8g5Q?ij7TBi`#|97(*tt82KbJN
zm*D#nK=T>LK<7nX0?q7tbYl(OrC=*v7#JFMK*Cquqk94*e1j}Jl7kdH881L1`{hYc
zgBq58ntw6!w}8&^XuZVW0X}0q`IJYm%n6@vZw(*IZctd)Nxu$;yU(ZFQ^Ci&6CB#c
z9w4<mCz@X|`e-+TL;Kf%kK>N;&;}>2myyW!K^+0sDRKf5-c6t+>C@?@0hN5I4(h^m
z2N-x*PXGtBv=4IwIDkQ^sWZR;rtbfr|Nnio8z3R;0I4LK9W)q0>-L!^fK2u1oB+xh
zFR%Xj{~x@q=4CDD6c<GK4{gt(lnB}25~1`3!z*yc1D6PQpd|ukd9VsJWk6PW0J>KN
zG=2iw^b-&2A-FIwK+6NrV!>`uc~DvhDGN%<UKGAWIL8-U6gWuubO$K-T3)DK2TFqA
z?8E`edqSY%kH2L;c=@NZgim*{LbtPkXY&C@pH9%mcmCEd*o!M)%L_GIUdDp+DmZ^Y
z@_U}Zi()lMeh1B*wU#k5Fn|ueIZ!Y2(h5{J!`tJa&Xxygqy%&}wg>3!UyyrVdUP|w
zr`H5aZ^6ptixY-Zd0<Rbc>ueJ?Ik0qKS4zK0O}&c^B=gFJq{`kZod`)%?CFhW(0@#
zW^kVIxeLCJ?IkGwK^L5XHxIqOg-Gv&!W&csfaV-pKqtbt9^mf)Uzr5DfR^X7Pq(Lr
zk7XyQOn_F1bwaNrkjr03a5)Mte?7Fjz$L;Dr1ICJ6I_kH^a7Vw(DVg%;>%F5kOKo$
z3D_J+dF;X50m{js@)#-!9un~AMij)-I0F6=Xw?tl0(dvPa3}x|f+Np2!q-!P@00Jm
z3Od@N+f(61it@kzKHcsXo}EWLy5j{L!9|9VN9%z)MZ<5P+2PJtpsR0Q-1+<;q7Gcg
z9rm>R0y@7Lexdt>?r;f@ZhwUrBFg{%gZgHAAS3R1bo(+GLdyG2oy(9zgfEnS_Fy~#
z8e)J>uEjdW90sZ0V0Z};zaGa~E;E1{^Pr;A@<QqR*ApQVk5Cda-mKsVo^g4x?IbgU
zN9Vy8-<Ci-5ujOdP|47F@CDOTL~(NzB-UM^@LC*}UXdy=kLGub;46H<os4dG3sC<9
z)?fl1LIpa~qvZg9D`@T=)M9FOmSAi>P_l(UT710>G#~bZk-r5r|J8b+Vj4JAfYPC(
zhL3e4QaY@acnKQ6<d<jg>2^}^v2Fs_PsL#M1XH68r~rf2hx<U2wI1Ef@X|_{zXjBZ
zgsn~nEyocDE!KkFLJvNA8+=$7q`eJE;$WLW>GuF5JpDRoz|!w2MEe6d8RKeC%mynb
zx;+89RtiyGz}piqEkW~g-(G_5asl7l4DMAy(|6+=(Bx%zA?RE&(2;<w;0SkAFg)qe
zdda7oqk_xF@{~vCMNfYJlRlOQ`TMspFfjO9p77|d7VzcwKL`@*eFaK)-Psx*ou@oC
zPk8XJ4`uLRyzbNKqT=Av>-Hbiv-a@l4d4KGmVA>BfNxp2{E>yhqdVB5+u6af^8;wN
zpKs?wPz%<hGe*Ut(*<-dN)70?d(hp!^Qxff^jJw4xWf!Op7r1hb(7EkTMtwi?}99f
z`S@a*AL!2e4<3z2K;DA%ilF1?-PHmf-Pszhh6i3If%;O-df@9ZVQa|2C$S=F0^KJm
z1Kzl7beN67qnqP})=6dt!vn7ugS^<Ct?^O@lziazAGAGT;S0K0=QQ{(`J+Ca=Sq@1
zdPUU^voXAQZ3}j*w@2qqXa}wm)WQWVJUm=t3hD}X9(=LP<nw=zZlrZdr9z++);e8O
zbUZpiOOm=ltmY$-1%%*+&Fc>y-K;?nr!F`IaccbuX2^XkuP;Nh{{)|IM-I>!gm33T
z&x1eheGO0eYM$_faC{6;_-LL09e>HqKM%CovDby+|6z}ACJ#$S{<&}geD~E=ID-0A
zh{2B*(EaGpF@}qv<k9P*k^t{DgBak!22d|K0F*2|Kz-;8Q1{sdG{#^7>O)7o4n`{9
zx_wjvkowOa;Qq6bPdDf`onFzq2SJ@m=x9U6VNg%8L>ttDb^)nK00l4O&ljNnj0d<A
z4I61VdmN;+bfHJ{kqSt1af}5IkoYD$D1h#GLlu6>`yO;!Jm`E_<nf1+0~5e!?SRG|
znh!8~fW{s`BNLW~%Adbp0xlm=`rnOjJV0|r-GLI_Ssb8Ihi)s^)=MSA-QboV52WSC
z-}(uh89|Gi6hI4dGC^I;<P#p?X#fBJf4#>{kMBQQ-}3jlf@HeoJz8(`w}39e<L~GN
zX|=q;-?IcXJ{<brqt~Cqqc`L_$7@x{_?%BSr*G@Y5*hxEB+%6|{OfOeG#}*f0BI=%
z>pfL^2h;|1>Ad99>7ruuB3tI)e-FzWo}EWa(!RMlu()))sMtX6&U9@(P{P@4$Hd?N
z3>4MPbp{Olt+zqL$lYlkzO7IAThD>SyWK22Kv&u(2Pk;(ufP1_<o{2gjyHb`2NMH>
zr{!IbPB(#Cu5WIREc~rPAU7o6^*H#L**Z_6#HcqUmjUFQ&O8Z^<Vzk0A2GiuIs%?$
z=WkgJRom&N08$THIMC^)0b0ogN?8t$;DIrp&WAq99ts}4ZVsRXrqS)@06yjMNiJyJ
znV$k=lfnzrw=5ugG<-TAd3N4-q4t)A!KYibTb7H#vzbMO@wFnXz5wknkpPzuOb0+C
zcTYe?1p85D2A|Fc9*svp@r#n4Ji1xeLey97hpWGSgqh*>IdJ-T@%sofX!*<Q{T|({
z%@CCW2$gF=DwlY4hgpCIs(g}*6iTXnJHHs7bkTh6%fJ4qtKr)hl1G>se3;V&T5o%H
z9<P)3>2|XK`MUEL==fG&#xE~C{`~*%V)?rCsb{l3BY*20(Ck^aJBLr_PtY}&z5o9I
z2hU2qWC0aS-K>Ab!T#I25AI&|Bg_mhrT_o`@0)zgNAtDeC13vaFMRmdANK0y(RlIk
zH4DQ_(3K7z-K+;8de<TJzCO&%@bW&y<ZOtn1;T%4L9z!Svc3>msr`_`Y!gTdbnq<h
z@~80)=we=vZlmrj4$yR!N9SqJ&MPjUwSHHa89;M&O#CgvYzz$D!4j5N`CC9|{CaeI
zE4-K{`R~7LcZdpyZ?}w!YwIQcJ_XPL)F&Yeb3Bh90WF7uwzm&5`tYwm<!E`TPTsRy
z<g`cYrOH>H&42#$w}SL|cAoKQKFH{3d8+;)ShNMybMytR>;y49W_o`A2^y(vJ;%(z
z;N8jc7<M$7uq5PYGX6eKW(J1V|J}|G{H^nt7#KifLZFTuct<;b-wW_o&R~V+7mS9N
ze0q6~f-ZP9JOE3Np4~h`9?d@)OXPf#4>TWO^y=(65&+5=-QF4=-8_O|KB$;zKE&Z^
zd9n07sN8tR!obk$``@GU6U4(Fy*}qSpydPqdM?Q2Y!^#E`?j8R<ezc~R0zESIit5l
z1!T72rJbNw6FB{P@~`K)0BW#WUa0@<V|kLl6?7heYs)46R?ucU&|roE3j+hlRt?a(
zDZM@_0gmA02C>@kk}IhF?4#o0nS9PC`Il?w8J}*Jb3VN~pnZ4@Ufn%^KvueT-tx3O
zQ7Zge+c)_XXbF`c|9X~lpu=mWd@K*vzw%8!<Jf$J(Tjh5&l!+<AIpQK&s=+BRQ@|!
zUgqxuU2D{Qh_TZ}#pSiGNAgLZ<U=0aEnt-%{OeoJ1TZl$cv-d_0nw#4&4(CWEl>0J
z)iZ%2rq}DgW9P+Eu%6_TUfnI=@b%(f4^i%63DI715*!{Loi{swy>JtNwp$LD)OvIW
zSh#}D-hI;im$BQ~p^m@#KO=t&sDN&M@VEH{Be?O??ako{+Fb{019dwKfErQ?;8F~<
ztafrC)W~CyYtCF-p72A?A_TRGKE4pv2DLNzTMmJWT+p#{ErOs<J7`h_lu1wuC7<N0
zh6g|gVmmN^vV%|Z37>A3W1vozpC!vl{?<F7aTd!9HIG~k4}cf!zPQT&?f+}g`Fmiu
zgXUA3|1yG_as2(Djw3cNfLso0{UatXK;Af0fba(RTs+A7Y|zYDpcdE%t#<$a|A(wN
z@BH{;j|;eE2i+jyz+m|Qo1+6$x1$4pi#li(>jTEl<IUe0UrIrHav(Rk8Xj=m14^MU
zyZ-$Lts95(KqVb?aWG`O4YXhkw5FWDr5|J#)JJ`K|B-YxKls;tg6SpbHc&{4^|3s`
z-(m*tX|i4d?NaI$y`IhrZYuuY$IS2&bp0`M`-OEaMA58WkaF!7NKp#NVW1d{29<ry
z+Kl|Ifgl#V^=^3JCFsD2ZWk4o*8e4yUfomvfD)%;uOFj}<wdW~5S@TpTgM&$Kuy|i
z(7hYUCtWo^xH4YwVLa&78=}SG$@tZ$m*t#Cx7QEw%rYqd^RM^);nC^!!`Jdf=`$D0
ztFFCKjIO;tDvbPnN}yFTmPhz|B|$Be&PT4D*Is7*0hRc-J(Dkab@$u>S?|&5bH&54
zH|W2M<)^xRjyplt`*hc+cz7hAa@G9k)5`+RwXTd8eKb${bpG<~^*R5;hw+dn;|KV7
zDwjv|D-O@*7aX4a>peI;I=Mi_(u<dnRfMf?`TLVVD}=j)EnE#R`6PQOwEi#Q^h`eF
z!@u6=*bf)WtDt*a0{Hu+{{8>o>-!(fGd$p;dC@odl7Fwr1yE`1+sShXl$t#(Pn3Rs
z`2lip#2WZ2&6mbt8(2j^d$4*%FYbUujN@KVL;vOJKmY%GHveSgZ#4k<A5@ZqQrgQ*
z&{7Xjxe;vP)9rJ_1AJ2g<USt@(BvXyvFk<9EMmFOxBrHhS`U=Sd34?aP3?7leBlf}
zt=k7Qe|q@EzTM0Wpi?G0FF+=F5$mDA{fWjm9-tx{)b~6GnJe%}_TunJc9ZY{HO>$6
zw{8R#@x3i7pq`5dr0dZua)Q5aF(~)L?*!lg4aI*jy#3l3(Lc02SZD0fya(J-`p@60
z3Nom34w&oF>2k*bGN5;}B*wFw<%UP=fy%QUj3+8jcyzNq<p;M51fansv<DPipf(Q^
z0|TgdIqZ?_DFJazot#gvkBWm&uj7Bi1EA4a%|o7@A_pOHa<KGmx0?f~P2<>k1GG`W
z2Q<gf%mgZ)4LrKt1Ux!RR4hP!1qJZP255uTizzwKa^om}%QBEBLFY4pR=FK~A*lu~
zH#+J-!mYRKEIqpG6g;|JH6U*2j??hz4pjgRuYlU`-8>h4x>?TqcCuXZ?B+S`(Fv)(
zK$kW>hW004zHoB@l{zm_JlD<o1hfaLS5$jDB)tgk#s~n=MrY7q0c?*JxOWMPOGx;1
zvo3@fv2`27h;zF@M!W>=w}9o3#y1wA9M~Nx(R#_Lmqm)-<AQT9i-c?I0T+Ic1DzKR
zzL0M@P@3psd8;<YrSkxUo8xMEqc+{O*ZaRuZ-|P4;Q`P<JGegb>|_CF1s_mW@JPPo
zn|#2hGekwfr_<$%fmdh95d+YKx`In*jEcsKdeE3+;}MVp4tsR7egW-?>J^QII#v<v
z*w^<wx>;{QWa6PR>=2nF;QcqPCw)5))yYBq<JrmJ(+$aup3MgYd^<gUSRSl@>C?-b
z^bvHe)<wr10-zp4=f#%`AF?o@&sRzq9&l|v&<UDx?hH}MaP2(C-&f0sbY8DxCrcwJ
zSvguBtN-lS{Ev~p4|Je_XRjlRM|X`%2IS@lkK-&VptR)DS)x+l*?FYfMI`}rKT!o}
z;;1*~IEQaCk4m?Rif3<)${&}`92FkV<hQ<^=R6NSWCp8EW(T!oz~>ityQpM<MluX<
zJAyZ-be5=aAeZ+X9^HWoUd=XKj3q%{%{EMoCEgz0o*G`=BAgxvf7yF>UiUM$;q=tJ
z?$s^A2omw=yyj(W0$Pscp?T5M@;rYZ=#Cyx$505|P;x~X?`uB5;bVEDbh>NnrS1|H
zj#Bp4+a*#S$?rgea?S5qn*aUhZ}t2S+C~8$Z?()(;VChz({}82{qNKHUh{>A=5deC
zAE2<Q@aXkv|Krp7pgZ7?NAnAo&HxtBmAoH8llm1dohB<hKwTft<|8biMMN%^IVuJG
z{g*+tRPzxDP=W?6K?HZ2J(>@2cv>DVnPhm|)$r2GA4ua@knzWW=3oCkI!||A=Wm$}
zn)w7>iQuj9f}ii-e^7-D>X~_fa;pbuJP5j7q#3l%JVwRhIL_q|FX}U(g~G8C6OYb=
z;5E*-UaXA%_8&C7^07k5qw|DE^O1n)xOn(_EYSE5JE#=^Y66@@QUGcHBDF6-lcLSA
z_5~zJ9U%Kx8{cGr%IDr36^G_uOdg%*I<FshQHcOGIY7mh1E}}l(V3$XP!ihw>py=>
zIOu-WOQp)-em;LID1jRO2XBpkaR(HhjYmM{fr9jK^DoBIr=TWI$$fDC1?A2FXoz%v
zeDU|w|NpPgL(Ku5cmWwRD7n!cDdEu_r~#@D6FP6cC<V7q+$@@3GlIL%w?Lg>P>T1c
zF!xA4<Z<u;i%+r(OM+iF%R$fPAB-iE9^Ec186MUyDjxi;iU0rq_u*fE0Mr8YXnw`m
z{Of<|$?h--umLY3c|friW&w&d2hYxz;KJOG1L{a{w3R?d^1y{T_(pCQ6%UYlg%_vO
zpmBD%!~)vNyZPdp)zANskrePAA$Nt(|2q$Pblzya#NT-j6hht7@O`%eC8mZ4UY-D_
zF$V@vP=Q;6i~s%qzk-p!<upinZ-`0&wB9}a@&Esqvp|CI`EA1k;6@rae4*o^&2J1m
zntw8Y#$-CL^Y?LsYQ=6LP{*wkG$dho`?U}xeRy<>90zp))jc{7d-OUpdRQJSeeKc9
zTfC8t;YIsK(4MO!&~0Mi{h1!khnYNjdBZ`{86as;%5+iDD9QG)yayWm(x|t2or6?<
z^zzz()Y?GQmRNd#0^+4-=bIOnAfe_O6%B?GJxDEmuf)`&TjV~-J;yzId4FwSV|ej<
z19*6(^f+kci3Vt1sKgvR=?HU`XXhJ_UfwexwbwU*#w{L#wo%>zY3l|>738o6@MHt@
z?&bshEmGiiCZs$9FT??tOfQwd1r752Nm#H;cc6q%ccg+xccg}E>!mtpP~QjMUv02q
zVki~&>^3><n|#8t`2eGLr^#uLZj-}aAiDVgqod`a`di?H;nL|S5gqq(m&H#|8~*ic
zaC||^6Nm0VP|W~3Nb#IUZ;Xn9N4KX!>!o_W*ILI|Kyh$@(ehB8q(`&OLB`Uz$5@yd
z!F2?9F}mfU`sc2#2TDaD3GTB;C+PYO2S^zKIvqyxIvaSK;>Q>FnV@O)c!@8#xpvT_
z^Y;r$a9FT@0xbZwbmJ)52b%xr{P^PFGSHBcIXGd2LH3u5moD_^hRqxxS!8(obq6Fp
zg@YHUDEM?cDtL5W2F*5go@>2Sr)7A+@FZydzrlu?0eltH0qBJs;I22wH<pL$AGMw=
z6+-a_cw)k*n>F+r%n#BCKcpl45DLx^ta>m%9EAGe?@}y&Sc34w>lq&1tan(sK)a?E
zu44mD3U_n7VBZ94&VqswY`@{{mwBMITA(rLm%o=VFd*%J0DD)%qw_Sl?gXvlvswyT
zwIRvh3M$S#tYx{bvoY{bIpkq2JK-9Lb%5g#e=8d(Lt4xFfkaw<f*N|(vLCO4HY|b9
zC$yGr0n6w?l!4au^0z2LIIBSBwWvTiYr%THLkxHT=2$^wn860<f;ioxZP!6-FmJvH
zTMHT{=5GP*2iqwETAbrk@cln{y6@PFz`pOGam*46575$u&M*T=FF3%$qch9`#O@AI
z=nPZv=nl~E=nT{FXx3o#IPL&mEWzIbTD}b)6~#Cm)T1*_zysVX{s3J%1i4r^I_{<X
z_b>m!8=_yogN^@qbT@<Q9gpS;0mix{kM0PCmy19PX8ED_z3=1)EuP;GZ~yNU0`b=)
z`0OD5d;}jfy!5&s&PQ4m<O_<^oq`Mu3@>v)b0FaS2o9B(pk2+7^bC$)572x+XuVYf
z=txKf=y^ZAytmh|F}!G64=$j<t1Lk4ojkf(tvR?De0o_gu3-bEtFvoBtFk|WL)k?|
z;YHzUP>$AS1l_G;;L-XGbZ?EH#EYmkAYnbmQW5aJd+-H6@M9P(pr<lU@PPNIUmpSG
zC(ylj%;4l}1hTE0<Av9HP#YYk-tfTdBgpp)L-VIcw`kE-P?`YU3(Enz03_{&<!Vsk
zD2)YmVLZBJi!QS<cv#*nQ3dq?Wx;YFnG#=+AoxOG4zM793+Sq$ouZ)B^e-2jg!o%P
zw}N?e2LyO@`$>3odMQAsd_ni)xIylVf^7IZ?9nY630fd*d9h^qi|wmGE&$n5I_t%v
zKmY%C2Pk-S9&f!=dI2=cYmoE(zelq^BRHtR?Jj4T<{v`*E%O){7@B_wmsEK4isr8d
zdF$f~X;5&s9w@N~rP^Rnsx|QF3^o9#?bb`61(r;V9^IhC9SlnFpaYU%f)?=o^a3TJ
zFM`&A3xk(lpfoaJrx?heV!7Y{zXa{*GduvEj|BDd4nAOlTq6Dwv=0zb#JmKxyFdz{
zvfy(%;B`0TlqW=e35y?aU)clHz?5QSVCasLY5pzF-);xW&b^|OSFtg8B(u!&U_A8y
zkw>?vIVh?+KfbsR4!_a>k8aTvsL&aRkgZ3zs3KHoCqzigqgzxCDzpqDB<|5IDh(By
z3>M;VnFY4eO#l{y9^IlZE<l2~0Ia0+p+~o<>qUrAEJWy>N4IDYRLBb~#NT2AYGQVa
zMqh%cGzJToCVO;?o`4D|K!jvGx<#)-g?Pb2{4FAk3=H7>>Cx>b@v;D1O@sRbFF*(D
zf{UWg<J}Q5{H<5OHGu;MWcT^Yqabdto5D-bEIGeCgGaY$CDdUXSAtR-e~T8l{u32~
z3eSQH9|skx-J-Lh!p%@&$e^3(m-7&B<UoX5Z-VUU7LA3f4uuLIf(S2zhL{~xcr`?L
zJycj7Dm(=uyaOsM02Qu<2pdAp{<#9|?$$JraI(LONAod(=AVppf*!pteE-3dX&(IR
zPk`HgA6~kERCS9!fx34OSaV5+N4MxlsL)EV5Pz!}MCB@|@Fb}4e^4j7TeKJ|Tn!Zl
z9h&6PE&2y4oB|PU0qygDdFC&?zvj^``tlqks2m|mTGv4gJOmZif(lQE2%m-u3qyp#
zEwz``5V`YE%f2rMhd>MHxR{smpyhcO^Vi^&@n>B?SH67o={)`-<UjO2v%@8j?S?O3
zOa%2Q5Tm&VT@6n{+x(rs{$B>SF;V8H!RZf{Kf$-By;uiYI|mx(J`8GeI)F+nZyA?f
z$9Im+KbXp-8-IdM!>H5t=oWo)nvJ1bsPPa;!17|fghwYkXi;s63M^ki#}|B(ofW`M
z<ex7pFM=+r(PjiqV1gH2d2~A%K$Uy^e*meU;O+eYkIu6mo!4JTgPa6vlpp4Ai39B!
ztdJ4mZviiW0ae1?yj*8N^I#`I-3j7W=)a7Fwi=J|w>UB}Fnn{CcHnP449Xs$q579E
zJbwTG-&`#t4BGV$*<lEsBK7Hf<df{6@M8T17LYDR{?=SjApklt4|F0UxcT<;#Z1P3
z|6305w}6IPyPaiv1Ku_NV&ZSx#K6E{3kt3}P_eY+6jJzI;P0CPvK}<f+@b|CvKw;x
zMdt^|*?XWm6m;ZX38<I$6MB@92ej)9>IxvY2LvG74nBBvzJ%;KXg$E+84fBGz~=t~
z6@ab(OSnK)4}Z&V5EncjaS$>e0qKu}3<cH4-OdV@?h5=Z2_XHQzd)hf`SHaxW>7N}
zX*~pgiyO$CZaa8YBgWqfYIVTseh&|L-H+_<3Ei$5D_Hnj4M2Id^*?_rXeltLk8Z&L
zz6V&vz}4`iN4KklM>ntHX;4HT0EIFlm4oIiBqE>@dYHe(8syGqR|ZB8(7u?1FXjj$
zbydNA&u(M*%4%W$R&J1b@bNOBWgLbFUj6~O1iIb`8vMfitrNkb!5pBWPtYy%uqb$0
z0g?cRD`<f<`0zx~pg%ZlTi1ak;r$E4124V60&W%_-C+Vgoey2QT?IfLf6s$2nO=Na
z$iVP&1Gr!S*#qv7gWLof?(ulJ5Za&i=)C3A`S8WnbN~OpYz8X^XC=@?F=!Ry1klI{
zD5wJr3=h1#jj8~0lnz`yXchGYq<a0^-~az7Ao8D2=W&nDbDo`7Ud;IR|9^M54Cp?t
z&ciQm{eqS}NBLX)Ky^7RiI*vXlQ(}KX!^;cTlC;@lqB8{x{C`mTlMjUIH;ro<>_Pm
zEx$ntznj<PBq(yhxw!KeJOO~lmKa$X7<@WYR5U=M;1TB+>S53bKhEC*TF>Co9UuT|
ztb=FhTvQYw#oqs`pc5_mTfpa?gJ#xS&V%g&uO%})0M1#$@P#}+@P#}+Ncn0)w>vxo
zgNBX3J_Kjr$H!27*9YoqgOX<F#}^!+Q;c9q6kZDZbUp$t-@p2@3e@m|wf{kdCTK(&
z7AxRIBuEYbd7<<bB38ljFQXtvfX<_WCogbkA1VG{a)9~+kn@t;UVQ;~g^a)<g=j8H
zc=USz_vi%e5Af*Z0J#IU#{kk9R){`qc>DEdr2ZkwdYR@o7TsAgo}jwpns4WE(DutW
z3=9n4oTL@_Th+h?f|G+wZ|=M9C<UKxF9FBqzl=WJ3l4xzqT1#p)#0L|&)?<)TIbSS
zslmYCavu~w$(MaPPdfge2wG|G(Rm!4r9OkMLw9}M{DYCdtqL>~*8G==zx^qwnfzCX
zzoi{?D%D?M{+4whJCD0VR-Sj3D|jT|26w-k>ns>Nj=M{M3Kfsec!A^Y8Z4{~4E!yi
z2B<Hn{5A!d+U@S(+04%9(^+re(^)Rj{NQ(|y9Q`97P_(vKA?(d-x?lhuw>w$dcdPs
zgaNdJv0IeuBpZWAGs_`HgcJ`0Xr*W`%c0j>4KJbi?xifa{Bd#sO~Q1;?lS{d(=f|C
z{y#8$+fbvTZwFc})%nwbf6CDpOTU2bpFil^`O~rUg-_=v$NyJ6I)A(j2AP(8xb?P2
zZwTXm{+1>G{{L^VV({p7`d=ymuJ4;)GxE29+kDM07#k`W8A{$Z{}twMtpc5Xf1AIh
z2(;hhHRHkGOuaI5L3>DFCj9&VAK_n*ZnprBZU+UAPIrlyrJ&-h^X7~6o6r?QL7*z+
zt#9jpkTicQD4BY8-td9U167^`oi*{}C8$({*H@06ci<6o+#THcc0Blp>9{+n)A8Ro
z`HxpG&tA~!BQFlkgZ4|0^0$E2ErElCzl9YP<;i|3KAj&RO-0c59Z+Wq6!)DsUr2*&
zg_boLpri(M&&L-pPk`L>(iODh_S1{cvq9I@ee_7a@gf4GrME<y$)oe7N9U&(1`wP1
zTP}e1<X-~$Ev+-e;2$U@fkGX0M>sq`_xdXwcL!~I`+wYB29(}>k`McIetJ<2w(SSF
zgm>+H01lIvFKR)yCf|5H0aRgt@*iw4>P7PcP`CGGBd7>()@KCm<%7vhfJ{op$HJ1x
z%diE^3{d}SgX{tOx5OD1_8(vTJ<h`52)c2c!3Q#~{l($i|CgZlrbp+?7x(9ay6XCj
zrG1F%!0^CJR*>DDFJByhNe4is4Zr;lFnIBBJ~IRO6j_k><{W2XfW%1aihuwAzn%m#
zw;ign<oJs%^Fhm~KuN*y<cs{{EDSFj|NZ~}VlJ|91V|XvyF@B)z~dDf9^InKpyi&O
zu<ku%hvbW}+2DqAE9m|TP&eDdn)mz%P6qy#Fy#9)?t+SyZqcWoI3f3EfKtZ`X{c7n
z5QiV={tT0kPzAR@ed1rUAZCM_aiH?o@b)+Ga0w%S3-}bX&W|ttgZ=m8zendW{uUNc
zLhNQeeHb#bckn-WuMB8^K#Mp?s<S}Aqx0}<Pv{A0pwSx894n;Wf(|9UoC|90cC%hP
zglP!q{Ju~80-)*F!=LyC9Rwgnv_^CsXfDtMi?!hO-C-bGI|EQvi(!}#x+l39w8~@l
zJZ6SZ{DPp3bRS<#1Eu`V8z8=fM>A+&%wZ2}Q<ZO=3?ALAibvQOO7uY+89_s;;89wT
zV_qBtg$ig*(mPNLKc36X@G=llUo|^OFnaVxNW8QKiA^xP{n7-)faM=hePsZdq%IM7
zQ3f%pL<&?*LeI!Hh(7Fr7&LkVnvwG87G*gI8r=aMbL=z|6mKQ$;PqK0{E$#Ghz3pJ
zgX>Gs@QAknXceIWXv)7?o3V5yXfZEn`a=WK2mm#?G+s{zjgNvy%Kk3^&Etd1PmgZa
znFm0V!wv}^-3+i>Cy~oX)=Id%0|!_E^7y+)H)|w9UIClDB|=^Uo4h1KJ^`EjPw)ag
zkoz1mu*u&<$QNLf--(c~z$QNvF5dtevheu-04cwEbhB0><UvO#W5`D$<UvO}W5`>=
z<sBq2><6U}(EYDl_Cj*VX;7OAmeWf3x`Q=5jyr&6tQk53KuH#SjVj9doQ~k}I{18J
zH>>MsP6kjahRz2uGJ15LI1EdV9^I^}DDvH`qNsdF1&?kA3(y7LtRCGC0*4I`97YNc
zh<iIhXMPHRc3z?0GzCq_9^DO~1P1O4gL=Y9`aODC1AAE+JS-3LPXVp?hOC-Lq&NO;
zjsnQ`Veq%3$?tO%*acb^1UhBM<<MdN{iytIRPF?iZbtzRP*$z4;|KNQ5B^ffyyWb}
z&%k)0`Nw~-N&GH{K$#1+AA&UXpzty9==Kx<wL-yb;Tu537AQDHLBR=P@ObowsA&8L
zoxN7V4<5%bh=#{s>+KQ_aDMgZWCqV4fzRkfia#a~OU7OQK_hI_K>^6`bO<@TK=vzm
zG;1+>be=9T0xd$v7E9g|FIG<n4V&Hs$I;7q(?JJ@$%D%iCk~I!i~j=*ULOMWm%-;G
zb+ZP(;bidW6_uL?Dk?Z$w9Noj=AaT3J^rBTH6iMyq3XkMtMB#{co{zpboMAH^D%&e
z?q&Q`RQ`Q5zBwBI`V>_4=h67+^7GN;_ape=@cZVd!Q#<*y3`4@S`id}Y~XoKXI#Mv
z?(Co?dgyqON4KZMi{%$S{eQg~THZQxfC6_5R32oX!R<_eyD=&npTI|$z6hKKZ5SRd
zG4$vLjg;Q>=mwoF3T_pE%6Ac1`L2K{-$6t82B4!EUw=cMPrzdS$Emb6e<CjPA?HPC
zgJ)2J!3W@y<$gmNn}2Z%j_?65$Dus@3u$b=ATIMk+ps|m576iv1>wJOGLG<}lKC%j
znGY^VDG&cnYMKu^OfX_D8^cTE$)GX_az43*N3ZB-CsxpP;U3+d;ORTw7ghbBb{u~T
z==_ClXNl$?eC4Gc-N6DLI~gFL!Nc-YiN8lL?~mD_Qr6_4N3yewM=x*GL^cKw{`D7L
z%;*Od*&o3TyBEzMPOp!O254lv55$44rm#RckH({yS8O61!;27*3UId{)Vj`k1}@I8
zPXJlO@nZWVP;m|_@ImchUx;KARB{$Xaw%jy8{B^Z`A-<#f3x}^{@VlYodgSbfVMS)
zeAeJ$d8nk^qnG#b1U7~jm;0C*nyV%Fz`g(rKLuITTcV=zVtpUfgNI)1>0@T_0sE-e
zTLL_H|Kj1|Z~r}dd3S=8gV$&_Ae8rlm|*1)Kf?Rt9=*IFAZtUAtu5{J=;h4;3EP77
z!9vlakD1~1PLFO@@2BA4dC?CEo*5It!LtNZA41p5f`<fqMc1JR!qi?!Ab`$S_2|u(
z@aQd32>`{iC+Jw`moI$Rf!2!gcYxL&fJXO0BLT-<R184%xkoSLkj8Fj30K3Du<<s>
z9d@7q1^05nzFzenVg#uF)LbpYSP}yY&eAlGUf!D^2lvLPc)UpM1%>2KP#}A}hyZiI
zr<a4pdwEOy*%)3pB82@w%x=&SE$r+e*m(iX)e@|wOAzfd(9$EgE&qFvZ21J{fNcSb
z_wvSqY`KjPe$fMoQx9-_f;!ZEi@yB_yYXc@s6iv|zyMys3JP8D>NL=OJFI&jgJa`V
zA0#%oCV*n&We`{cq`ko356XMs_5--S12rOE`~pR7=V8#qbUVm<pn?PYE=Ndb3fA89
z6nGil3pdZB`HjTwOoh8KDjc8q1$<OEAayl}<D$ah(R@VWrRM~2;|Zc4bn<l?|NE1l
z`J)^KKJ!O;ioDcBmWRww8F=){eo6ur5Rd_Y&g-B_dj-%;esDJ^1%Zla&|%yT;G1Nk
zK+7!{N`gJQ{W(AiRXln{Hz%<&yikKHcIN=K5kRfWScu}V7nYzb-_5#f6KHx5d@l~@
znu~4+&{Q#KaTd5`4m!#1hRnDBkfXZ~mBfSk%=O*i624>)xa}Dik958>NO}d5dVY`r
z{@w8XWuVy9c+m$6`_==XQ-w52?iwC=y$#;~0H@(RWcgmh1FxsS<iYW0c<IHFC!iDD
z4uHDxsEr`ZMg(#v7wq7}h6i4MLvCLgUV2f2%RJ0R6;bA?;4%-hk|N5yE01yb7qihp
zlzA<<%)_jti89XwVV)jxqck7_wMBv5FhuzQu0J#kFTHsD2<~BP6axc1ATwH>$DlJB
zT#(i-XzmES86Gq!125mfJI!A|hx1|Srv+g=s(U?1b1%$16I|vwkZ0bLhj8zsy3c|%
z^T72{^BW6~UfG3lXax#?%Q|q?aqGpuHc+9$-wIlY10GlG7G1m!Jir8*gnn@sssOwv
z7h1}I*AN|nNVI^?a{*0u{d}PXcR7CxXss$J@_f2k&p+aXY%%!=Dv16E7@+Jg=ZD<V
z3!az+E&2p+G6#2aUxEgq5$OY5#P#Z4jRlPn+$<^b=zR6U0qlm-G_YK^=*zWGmxI={
zy-)^A^0$JgD?#^DSiS^ZLGtPa7et~3wB8Qn@{cbH9>Bvq2I^`_u&aN8)_!$6B!KVW
zfT(qO@c%!Ebr@8>nS(Xn1}z9<^=Lg%8U;FVn+p_C{4JmrXP`x5T%egP{+1rlkUHp&
zUhtd;Xg!rbhex+#f=@T=+J~SJf)>P}g#utD9{(SJV&wHLNc+kIJQVoJr<=77tQ^wy
zLkrCkPY>jo>Cy?XS!vKouF$DmjhE%1`7+Q*FJ%7oWh#UZ?yQ35SKT0dNKXJc-@aam
z93QNqcfj@UtaeEK+tmTCe?hBK5%>9NcywL`O$8nI={)y>19U$fXvqFBBs{?LJO^KB
zwt;IEP$*`CXTd;4CG4)egD;{$(w)aa!B|oW3fq!okJkSse$ZI|3|cp42^tVJYyl<a
z5>b!NpP&&4P($J6)K{PtEuirW@ZA956N{naU)tdF7ht{y54XUiLF&QbeG}9rp9pH-
zA%#~3ID8<}?n_%iEuG^pK~v5s`-6RYdDphFF}wtw4-e80S}BP<KI+rUJFSfkbbkBG
zi=gv(e0q5&gVY~^&VT##@^(VyLFW@r@ag5Phw?#F<RE@INIhuj5y*U>Ufu!_zXhQ`
z1;j5w@FPHc(1t&#`T!6=1R?JV;)9kQLFH{gd=rGc0f?`H;H!Z6A_%?&)P3Odg?xH>
z1)%(op!s&6US2LJ{~?tBzm<*Q<rVOfBL@bbUfwSt{t*QKEr`Db!G8?mFG28cfcR4o
z{4*ea3xa<D#4kbcx3ogSI}vLCS|~pd%3lOh?}AW23&b};@F#-!DhPfDRKFlpe=A6y
z1tDJx;(vke2leUYEdueMAo!Ue{uKm20mMIo;D><tTM&FtsC^6n{QnP%e`hEkv>pn?
zw}A2+q4K66{h;$wq4B8$l~07qD?<5!P`(6|?+E1!g7ljp?B{^WD?;TNpnO3n|7!~*
zd>KJ}aD8rZJ5#`;^BmF`mS_X$Ql9^vhf54^=Yd+!u)(cA^<aq-smuf5QP;zu)g}L%
zfB)xqJq(!!JPckE@cI*^JOrDs0curybe{XnALS<SVkg9i&ch`}AaRhO$crTq!4i4w
z=7QP`;PE$z;cwyX1xWiIH2j9#qz|hHH|bqK8^7Kk0Jr5|I)TI{fW|lZw|fe_NPft`
zFacElywn6qptN7X{g0$3P>})df3P=#<|DNk;fpg+Pg%j}f2cRX`yb%;N4KZI3u%OL
zI~oWY2VZXo8eV<S2r>@RKLPPCAn`%wD}e6=xaiR<s@TlN@M2;ew0s4vM*~lTfhQdx
z`oZNV5+9`Bz^9ir!~?WW{WNG(m4-(r$gFEkYz&|!F5o%v7dBu+OAR2qL|RXlK!#KW
zz~+I6zai#>=BGe~@pEYV9o&TgE!*FG<Ntq1>mH^21*Z=SkIsu=n?c)=6g+xG<Dhnf
zm)9U1vAq`LGyWD(Ptov_M=!6RAuGdw(F!B*H7uaMMkd^S86Ld_5}?^~sY#Ij_9ReS
zsyjqQ0klg8yq?~t*INK`h&QNL#B}5vY!guh^lI6|p#Ce;@+{DVIH<Y>HD$pb2aVN$
ze5i2T0X)SHwzKt8>C)rQ5_}8{49A^i7(v!{-tai?44wso<`JaytIb%t8PaM1)nbMR
zUN#`lKQ>oO{4d@AdOa+CVh=C9Mo3(tg;#qGT6paPht~_d;q__)apART2kpWOG4#|4
zn)n6n6afV_Xniqg7=VQE0;O*UaPop20L0M%2`TV;z87iLkO2AyiX`w6L7;hJknJAU
ztXHptX70i5Lu=LpU=HZaZo`u=jvxK<AC%B6TtRpF9DpZK(3lS>mO(>$#@^sHVI}O{
zpwm@L#6ja2>p@L#(0wY%^HZRuVjTS2q&#{9A)9~%O0*0QwA@Bo#M3K!v=DTq0%&V4
z10(pd4fuQ$Vx{{jQ2pW2%sQixm4VTtmvtgY57;)3X4ctI!6|S-Ncjv-#txwAD@gtY
zr!Nnr0J~m?9AKtZpa3h01aIqjvHu8U8J8D0FhCP60eC`0(F+_Rp!TDrN9W;g2Z`1L
zb^eg~aF6IX$V`;sZDaw^c@wgx*Ff{3%#0{!(1P}>!PbVo-i_Se4YPnQVR-T2Cg?sc
zG0<v&=2wj1-l$k<Kca>Bx;bqEwEyMd(RmJ3_<%|xk6zKIwQLM8JS#zd<!=G)pn`a?
z+mYitcuf=oLjz-}qDQaj+Z<3o=K`oPd+<d>CFq_w9~BGG$cZCINiw)6H32*V0B%l~
z2!gsTuw@&qpkfTXALd2bVQ7MaCne|zA}BS1*SH>f@yG)-)^_kk7N~XJe8dCPZU*&F
zL}xAl^`|bB2!fK>l?srfOICm#-0djQdZ2U;=rm){O^lFx5_>^K^h?l|O>lbYy!m27
zHKaZQ9o^Z|4O(l`R|9V9^S6Rd&GTpkjc(TSw}adZ>P~TN0WYue=se2b0y^gn)X)0(
ze;Rm!9N3@yE#OnIJ2NCaIx7SqUUatp{vX^~a8@w9)LEh6(fRVYGkDb-?9kg6Hx`2y
zK!Gwl#B*Tx!Q1yQ(?IR{7s?=~b+aa%2X|^*Yd}ZYgAcjt=6LbG8r-!3?Er<9m*Dgb
zGY-^W=zRI&#+Fb2Uu>>sW_Y;;+A2n*A82}r@aQ}bN)Mo%;L$63sTz_Az=wLjFenFy
zamr3m?7Y}@5S$4>$vViRJ4VF=e7qKD{}}GP0ICp$+~L_l3Z5MlAgMnB9JwI>!}0?}
z1XLd((l^6(P?f632#yG6Mg|7Z0g>lCENeOVTS`FO?r;szfzK=+$)N(E{TkB|Q3M+2
z^MI@ghj`=j0Z0<`0A-iXLoY6$0j=n}1zvJ??8Q+K5Bb13{+37JGE=~#Qw*}_D-3k^
zpnykbn1DyOgM>$?n*{jcTK<-sV1=N70XIe<K7qv#=){<l;PUbsv~z#7BpSA4!sECD
zWQpW)2WZU(*$xNlWAe9x_6H#{^Gg;`wK)M|XDfJHN;m9Sg_odXp&;cQL@S7oq_rKK
z3_!`70ZA0JE^q>5><UzOz=u36ptlb|)x#|TwE!k~biRIR0X7a&o?=f=O_j*$=|KrJ
zJ%RS#y~x^+Ej@uY=-^LJhg>L4PaCcvr6=%t<*jc^py?@uxb(D^fq?<Mh497VeW>ZF
z`4n<`Dh2US(-Zh0B2aDC&EU})#^KS)28qj-lSHMT&zIrp#~UO4fc6u#8iN+2cEb*G
ze5rz*UY>$hjv~^_v48*nBc~S-A1P%l2S+e8{^16K?kd5aUR1$z9Z>b~^r8VO&p_!V
z0&E<<^b%B#oL)8*LDLJUiTT26FShgoTK$JVy-aeVG`%!jLP{^7`?HYB9~a`%%Un=;
z0eho(4{CY|K7pKGTtPh4^a9$y0$TD0PbUYlr4xAha`_^b^Z`y6-l*vUw2=)_A3)L|
z_)09Kt0k_Xr4JAvDSaTH&w@yBplS(w`heW#jh;S0lZxQ-B!gi3Fe*h(9}^0o>4O(k
zmrLy?FMSj_P?|mxE>I_ZfV~mC3pIThA45(bsvsU_`naue+YS<gE#UoB;OZHv7D}4{
zPam7lV@V&d`Ujj&oKe#Wc$p}yz5!htLhtkeI(7_q`si*1ooff)q<9(BssuM(K=X^-
zp!r26$dzZ1CQh&Dry|fC<INXgdEk^&1>Q9N;=vAR$~g|&&j_l(K?jG*F)}dVFIg<?
zpeg4#XfGh7p$|DR47qg!D__C)&!ockpJKLm96$pCpc2%hy8(345a_ng7I0j2-ui#R
z1JvL=%HNU#DsQYyIrv+=K&<XC<dzRg;}qQTDQSmz@$YujRCV_-a;iEH;&pSwduGD?
z;A77}@e6>KBtz;a(1CrRpg~Gi@H7>F7M7+U_f^2_CD87lR>+EL*dqFupkwSn?YnRb
zk8Xbf&(0q&6hPX+`>~Jmw?KLkZ~0q6ci$P_et8vKC@>%;x)N}G0-d6<K&&jYcnK=u
z;Nvmy`UiA#7I>XMe`_1K`hz<KblL+<edp_!ZeXh*^^-?)wE!c3D@etQ83oJ?FL#0#
z<#)riMuKZqMEQxM{ZoKkUOmVLr@EA#+@SI*Ya2Ax9V<a<PlFD0z@O?4fo=u|rG{fA
zWVWX_oTg5B1@^|`t*9xh`5<!2Dh2T{%d5})0t}z|1tBSmzhyt(8jTU;T#$#4mUu$f
z7(-gOpq=zcwGn6wBGPyhD8CIzeFi#M9Cvwz(%(wTLrxzDGNI{19F#u1wqQ#igxfod
zETN?m+391#Nu=}vK1v+XJ~jcDIt2S$6G81Aus51Fqo$AK{mAJf6vRVKAD}BL`L{Eq
z!P`5a{fm$eC$_TZF{s4^NgdXPm(oBxF2J=Iq||{oT0x}_q=sx|1lMoy;^7gfjWYp~
zqMm`v2e_u=-~s{KUV)2(wpU<p-?(CJ|AO`}g3|+N&nm1xh`qcB%0W&K8`7cafeVx#
ztTvIC9wwPnnjRXCBc%rl+P`3L6mLXL55aqp(}OFBhngNpZU2H=NRae^=pTVo1gLgE
zDlUd(`!@?YeN0G&rVr5BG%ut!ke5D+Oeswt2}hCA2YKZMXwqUQ*c-v?QPYR<Zshc#
z3gV%r4^Vm0%>XYgKttCUr3G^P_Xw=5Qeur#n?P=qgXeP4-V11f0lE?wsr~T~G(S$m
z@&Z&;5m{a+Wgw@AhGb}ZU;~vGT<ge74@t(9riTDfbFvvaUPnQC0DHrEEoypD-ie$Z
zL_s`?(!=6I!zeunr6H$>f<$O~0PQD!@oP1C=^@CF()8c}Y6Mc29>DDhus4iB-stuL
z9moMbEJb)ba(Z9|@i5Z^3GIo=2N3CD$hRk$QjpU_LOe7*fL3$Ac(sze^x&jVX?idK
zHToz^5B;F_CD<FvAa5Y02j;EF>EY`Z(A1bU{B#sy$anz%HiiyZ=L6EdK<nBf#!H&_
zA=1M!2LT31!S4@lL&7TyP!kVYS%B_$M5-*FfSZsGP;E46UxIEU#$8{KG(K`E5i&kv
z77I=(RXaIBHOYbH(3FBQJ_4HY$KO+x(1oUyK|MYK_Tt@TsI|=AO~|QeJ&1=nK7uqV
zTT+kF=75imIPQU^An1G{yx9S|bp(=<;NuFQlmwa&^XNv5k1&7?AbxzLh~DEP74amD
zkC2oeo#G+saaj~JJ%UbUd||K@TY4lsUe}>D6w)Kui@r-x)1&SN<n$;H;$fyoq*ib(
z-Vv4cpjH#Oj|3U7LrIW+;GzwlAVH-IXgvy2dMp5GCq6yWeZ1~P46V}RrWi<i6pMhS
zN6;O<FBU8!FFpQH9}4La?8UtcQPbnxwaDqQAH<^|J<5YxZRDrN2irjXPtbXugLC{i
zB8r6ch%!Ft6ouS=TM!CPbtyZULAA2h0%)p389ydGKG>uRO?70C4;Fx$Sd_Kj!0mak
zH<IV0rYz^x$SKPd#G|M^e;CvP1gEW%p+7!o6oH%`CImy%18D8#3#obJrH3MAO4CEa
zW>Eg4sJ{<x&x5@YJQp=R7_UT552_#@mh?b;dww&hEeA~xL#REEI3Lgh)`B_>I-B&k
ziwee!CuqM4Y{ruz3{+!%e323ePAk<rg+XP<yV>xx0$xe%0a<(J(Rz}<#TM_p=L=^=
zcyiGLFZtx}V*t$wARk`|T7T9p55Ji}9AYSVi5lq63D6mr;I&h|qUiITpb>PB&QH+!
z&g1+o;Q0pYcn<y+(D}t4-N71$-#}}<I6b<<1v;;RE<fzN`F}Ee!58SBhL-yO|Nlcg
z$_nx*Qt$BTGEi#z2|h6J=!@&i{{IJGT+Hmz>+v6a`Vn_YYU{UBwr+QUUK0kN<YVB|
z17E%{tpS~(s?S&w4%!Tce3B+?{t$Eobhn3qXXk+z0ifm?xO_ZbVh-9t)C#&A9D2qj
zTs>^3&+C3jdmq-~dOa7yhjlJr?}hL|=a7QeXTi=PwRnlVo~!c*_)JXL{DMbw9ccct
z19TMBjbLVmm#;y)LJ;$n<ff+$!I1PM;tx$vpmWn-%$rGedipFkMA8%3qg!X7mQGWb
zAg8DHCB&wur<Ek6Cx&&f@^x^er;b3(^u)i-Q{d(D0MG^w@O&9)@5#&QNPLidJAx0|
z-%$bPLgw2+{0t;M|9;T^cCY}%ynUVmFWnJ*&|+nVmu3O5{V#?mUur@)5c3RAzP#xJ
zmW1%(>0JSI;8Eu}&|2P`KAlHj9QFY(0S2Er47!=oqw^+YuLOAW|BE>gY4B0;ppy(h
z`aZrm2P#HDmB=yvmdBv3R<EePKPY1yeDT^BY#w-xaXUx~bUNof1_lOC(7mg-Kx>yJ
z{6ITyj)L|M^0#~esR6B%fSjlbnyG@^RoMErB*pOL3t=B-24B!oiHE>TR1d#+<pauj
z6>$*lN5I-abKT&>89lmL-z^6%BL^>^2i-aWDr`ahH}F}xyTGdTz&j0L<qNo2hN(oI
zKL_mtfz6YGtSh~YynzFJBvTydG(^z;5zrCN2VbayeBXH#dUQR^ikJGReM->M4unZB
z|AJ>-VdWuo91S#!jx>&@3^oC#=A}7!rWNUYG0^@81H(%%OqN0iTMn1#fWmr>H)PE>
z=%9jN@L4_@h!rCmu#GyP^Bi7(LOze^^*T_gizqK&8v8IK-`4@1zt!;Qjba2ZKDz3`
zzdlmKgE>;cqxmqqNAu$!pvBLv-pmY!m%x|l9`xuu{^D*aDBss<FqFuF)59mwI`ayU
z8`1ZJg3j*z`63lf3LZZo|0)<>df~F<|Not!O&%VdhhLQYFf()qI~->Kjg0#AvQFRf
z|Nn6Z(6Bk^cKgOhzu*7=-*AozG)LYYY{9=RNTMTv!vl2bc#whzV(l?_Eplf759mA)
zkK+!|Q(Zx~b=(5S`Ac~}P(BCkI)m@u0`I2)?U&!Y7#;!M9=)QgeIeQ6iWf9n94is>
z=oMYz3%bkV1}KKSKuHF)+l32}Bs}07=wbDl;kVbXkmCpBe^7k8Aglw&cStJe#w6sk
zn~00=m)djx|3^Ci4Q&1kvAO^McY7#!bRO<Jaq$P}Y;t~=6E6;cA_e4P`1w|tc7XJQ
zikcUf=YYcFb_uUXa)3f}g^aLAr*MgiN4EsLc_aYJX0SaTu%pxzq7Qpq{N>Rp{Q3%b
zKcMIF1EAdrhL>L60u^f$3{SpXdHx4z@h+r%1BZWvN9So!!w<T<!_$Y2;YGGPsJP&7
z0k4t+Z~f_ZfbZ^Lkl=3#2DRS0y*WI3S&vJCc6l7+Zvo#I(<}Pj3dFxy!uui>YzpYi
z$C6OcHgQlMf^7KcJPh6k04_SaLsUTPv0m_df;NaCZz#hRQW3EIFdn_4oF-t~Alu$v
ze0Br58)Rc?u}80{4`?r!CCDkaz!Ll|;Igdq=8K})pa4Dq+Lw?I^1Op1cwsi^(7eu@
zFH9Ev|KEC`!WDcdipM9=$z={N?7<NT>aZN<Zv{{EB37@0RvUuK%WlU6uqQ!{X^+ms
zFTrIN=#n%p#2Nx{(FyWG+64Y>-U2VeLFRTIe)$Sqps^mA%LzJ+?z|UdL;6oo(5{Ww
zXTb3ZDjWpdLG{4lm%IP{{|`zp2GHn(ZcOw5={xSC0@;|j*cB8WB^sb@cp8p7Ksg*_
zM#$X1ApZ$^bhCb42ru}-2du#gH*oz4G9R&j@}Vai!;3(OiK4rpW<m1y;(34ngYPQ@
zbK&RtLC%A5@aQ}Tx-*#JMU5*oKOg3ANdToF(EW;_;I{znF?0hb7yb@2ung~0kadeZ
zpgNAj)7N89Na3*E4U}H^;p-2@`CI%!IzgM%!1KqwqWi&0KYDaJOT6d+EBE8@=oQ^6
z0Xj?KxQFFM$a&*0_PBt8iNEy@sHOuQv(PKLQ5c-AN_bz)he)<O1WSS%)4e<lFC0P9
z0Ikf$K-NNXiH{2Cf(Ose1D*$8*n2V_@VxlLwe#SM!_Ev0y&|m)AR{_UKx#hj19e=%
zJ&_O<ix*ukV1M$rtOP0P<>m7P6?F$ZI)A-b?+l7?XNA^p9-TKz^gw%;3_LnPH%uM{
zd&xyb<Fy2Ay(pIR031M<aY5vLKv&51@~-m$h2XCjp-__{3s1r7KncYHY=z-B@SY-%
zZb%nG1GGgZ$N<!l(ReunK0l?+Si)s^`z7eY0dV>U*R_VXK_@VPmqvgJJftG}MU*=;
z1N1l~7Y4|AVxar0UK|1)r3((uk|<F59tHMVFo#EXw1CG95B~L08Xn9}3LcDyK~rfZ
zVxTiEz(?G^eBlbJRv_gWB9kHHPaw&IvmRu(G&p^Sg9|_fk6u|OQBaaVKCg%ebY9V7
zCs4uw-RB26n@G>2SM<6FE5nN}utcexM>lJ_6i6%N<O|3dtB~7;Kxbd{iaJ_?($O{k
zDF;0)uk%kiz<Hwi0VC}E@m^6bkaRD6>msN{g>)Vf!hK01AWJaZ#|(A`s{71A?tA43
zayZz1;PM%K!j?z3Lj^d4#>In=Y6X=u3oTIHXNc;)ERZx2?mGm^F3<y?A?H1T!!H@^
z3{>|`7iML6;RTieyH6cdf56;VfbKp<kOM5Q@lQDb4!=YE+b(%1UO)ukNpqCFpO65A
z)&HQa>YxpM9^LSBO8Gpx9W+2Iy_r4!KlltfE-rWmxWHZD3NCP8cDNv=r{*^rSj><B
zpQ+w@poAZ^MIIcKu=K~u3NbARV%iHU7iI?Vu6&Tn!=U~3*v#|k_K@&xJqa?eLV%$J
zbn=#l=l_QjJi1x8P6xYA3u@jgP?m+%>R=O5+nadI=fGipD8&3vE@0ok=pxg6u<-(*
z#q$g$p#9+>=Y!U3vwochcE1zUd@a1@!_qtS1m4bTpv!aaJAjgM1t?I!vHQZ#8FV`N
z5AeY&kRx8>;$QA`U}k{a9}Ox`z=7O(?Zs*baIsp#4hpR3xWg})K=y-L$smmy(Qz+3
z9gzBaAp0BNfDhs76<z-swBZtT7BKjXL(Uh|>_84FsRA8)=KyZz_IgWrc7Avf8V}kO
zUJ=;sEaA~xqf+1sKH$y*R71j!zk?if2igJ+sRKa81^BSAoeRKvLFc`^=(S^J@Mt^&
zvL9S#PXM162jhavSJvLC;PA|HhQ!w`M{x7tB&2+Y)Ysjh+Ye8BbbDBUHXX-+4+U<$
z<kQQ-<jL=G!L#!MsBUs?IZ&$LVR@)l`o%X}Pz3`z+YX%hUVFm(3!wJF6ix=m&I=yB
zqG3=gmxHYYD+OhrD^tJ@5`@ZnIx;i7egGY>0vE3q9xw-i4_<~G2Jg}Bgw&oavGVBU
z<#c9acyY*vnZc)*ml0%I=P~F2BdEQ$1GFSV4&M9~D+z}l7U0o&@x_;OU!iBb9V?NB
zrwfbdIB=s1(I0zp8JZq$dvvo(Lma-y2@;YM9Ka#D65DA*Fsr(GpG^k)RvDxT6n`Gw
zoG-#ahJub~1m9|o+~05va}0%#AsBpf)MWAKJkQ?>+4BiMiW;&{*rPi`z@zmof8TNj
z28Mm0<3n5xzd7!$2s2@D>0P25;l#-BTB`ZS|B^r#!xx^-#~At7A9G=R=4tuPvGZt2
zDENwkpD%uaHXK0C1<VIUYd6yVjM9T1-N784E-FX|bTt3?U%DRL<^%W19b+Bikm{e_
zhTk=e4B&I4Atz9ysoYU~*^~iI%%hu?5fVsYj*yTwvxk;}po8$R^#4EybaZoq#-)2j
ztzNT$j{PqweW76u%59}N9w0A>9(n^2w|yZ15jTN|XT5}obH4at1yWxUvlFx->Np!{
z_c0{Xzcg$80_yU(Fff4kP#k9iZK;FGNrB|x{Za6?m*Z@pou*LvUoBsd?$a;?oqdJT
zesJ*U6@8?NsGq^-IAubd6AL;G+rp#QkK+aZfB2zWA74zG0J^U`SOJv6dwIZzk@?R8
zC2^!xM>t0x96+T5sN@Hotp(bU&kL%<LEW6smY_i3ZvnM5K^y%&dPRTQgBp82Di$x=
ztigq0>E0KAY(bYnywJ5}W&od6-~qbt@daPYm;WBUKA_&%VUW8z553qu6U|K}RiMV9
zg-5p~e07u{e`^MKoFx!4QUX7s3v`Gjs9n$22l6XuQ#<&)vF9b9AbZ`9friBnzWATQ
z0y;qoJi7kzg(t{H(4}UeyP|x`KK+NZI3I&MN0?(VFLOa#YGCy}xV-W3=oJlC0YwMA
z>~?=~%K{WIrFNjMA?SQb9!Q9BzBmY$0PR!q7Vzj5y<o@2@FLa<98e|6(0eQq<zX+V
z#~Y$z^TO#bBr=bIx>HB{{(~;n1s6OAU$oBvg&9&&Rk{O5nF2c3;YEQBXsn5u5z+_;
z2_ecWP<d_uFFqmVc>=sV=K+=H7d<;KdLDdf@7i**R1s93%Yg2g)_9?40XdEobb>CV
zF>Db1+TNp^Riz(RptssW^5->cX#ND}WKfyT&<`%<Y@rHDt(h5K-{qHQK$K-LM}ezo
zkLC&s2L6__j0_CEpx)OLMg|7d0-nDGwExub(u-3Qq5bZ|{4M{$T^&(TkS(1DUp%(}
zhdOw_{$;Qf?>8Gz+WqumjTxwhdg;-5$g}gvi*F!>&AFgk!;bN{cz`Sek5huiA3U3N
zR2cbNAo~rzLCzyKJo$pz9NJ_!<N-=shhN+>2c-wtcqr(sJ&$fSkKTa)(5t4zN{Ydu
z0WKBc{aH|5({Tb(*VKd0YyjP|jZpm39o#tr_b)(w70@^hY)BJ49E#K(+5sA!L1;Y;
zN+*!=`Q!f}gKifUotI_E>DvQw-UDc-%7hopkd(^bQVh<4tnR(wh&yKuiP=4t%nY3$
zUV=tN!Q%&>-7YE|KAjIi-Lt#k90l&Lfw+gk>(ddNyjOyyS-<sw4K#)tm~9D7Dlb9%
zbv?RS<scT$gUWlu<@bTigQZ^qAMjxt9?2&<4|(?bc>JqVO>4Gf@aT2?S0eUW5|O`}
zUofRLS1>V@vNpeBEdAh-e95Qt;ES&&(3Ei)bc6Rnk8alM6F3?EPv`)p5>WL3JsU<C
zXNd{AhNPEQ!4h=Y(-DK{m&&G~Mn0tfY2jfl`hEiF^ulW;eukG^Izc6mQa>!6mSnkr
z>UL=6K4c0SbRcGs3Unk7=px1vDaYm?%%#gbx>;v}Y-wg-gtw18x><W+VrRhPC$Enp
zw;$l+#h?pW&--*9E%kk|qvQYo?g;2LjUJuHUbuIGW|LeQI&WP3(Of4Z%<pmol<rD|
zJd#0&jzNwCgtQM4{o~h<AoT~UZ#OuCe}RIgo8v{7IWvO?q<``H(1dVsf$HGX%UZPS
z>woY-laGoy<OHlM=4=edTvW^%Uf3Cf@)G=>Cvyh=R#5&0kL!Sn_?s_4yMaLk<)3y?
zO#mJmeX#%*smDqpKzAU*uU>-;L3DonKLK?07`P(31*%5$CxiU?5i}rv2c#Ev?cWdZ
z*)_r?s^Fu4P|x#i)@Cfxdhrxgd^8_%09BiyCXh#G4d`TX&_Pw;+6AT&`F>;Yc|qX%
z9;^)(eyqA(;PCon0m)%eX5dz13q(E~5?(Hy$HAWW=)4B<|LGT?^9OxE14N#k2SIj&
z`T^kKAJF{A#}~e!K!>^y<@_&*dEgN^&`Il^*F1VfcQCOs_;i8>uS%3&FdKn_zEl!g
zt^HwuRco&dK@ugR$OROr_w;flsDaqc8rKQ-MljSHlR?QE67ArIeOx^Fd`VFLRRBeI
z=j9hG48fVOF506zTEe4S)FBcS0^ZQRQ5D2KInca-M>qJ!9<V_#D<^^vi-7l!pLT#P
zHiB9#WeN&Euu{-`P&eyQi2P4;km(#Rewi>cyuOE0zgvKV^+iKBC^>urAINg>#U#VO
z|2-f_>q3)*FsPHS4sE$Z`y-IZM?InybmZwxk8WNbh{Xp%7K4faP|LmsoX$Y%AqTH}
zfX|{8-EYpu0IFpJK(QR))9IrU0pe=B;3)vr<wq=F=TCv+uknonBLl;2EsxIAE}iFY
z9=KhjV&HgN<L0}Yr|!SHd$Wp-zvU|f1H<hc6@!}(Z|nZFWn;Mi^6m}(=J_CPIVuMC
zU+{N<uGG8v4x|Pw*Otu0z;L`p1vJc@nU}_J^8iTeKDbs;1$_Gjf7cl%28NsOZk~i_
znheqOfPsNQJ2NlsSc?kiqHG3_-YqI1F^|qq-CQ2chgf<W|Nr~<@B2l?6RHgj4GkqP
zI}aXwDX<bWw#Dyq(4*Ijsq?r8zsp4jhT}W5Kt*u#E#|aNCZFCOu!DShS&y25>g^I0
zg<YpW@|`zdbQv-;Oz>zt0tyRIHiYCCQ0}uxYdyf<0h-MNg$$_woZ!>TT4Kh=u*(6g
z`R5B?Lr|yCM<oE1Zy3O{qCa+l4?gL<2?~?jH7WrwKKO%6Y!IIxe4YU)NLJfGL$fIm
zbor&QNAqEp-X^g3E-7AsdGFA{S1|7#^5_kQc<+`2!|`2NAQv>>W=`uAMs++SJ>RZT
zae%q_kSQC3W9LV>qh}Z}GkCy*1kLdvpMhKocDWhc<qrI<hX4NmzkA~~JGj2Sd*i=o
zO9ME=c$<Q*bN5JiQStZx|CgJ<Z43tF5c5Q~A0DMYUkDgr2|SSf9-SZIPT1@R4m|!=
zbI^5gU9kKHO=7x`)B<WHF}$1rJ{uI`e~->vBqy1jh$O@HGV9;}|HoUv$q#A?I7z<D
z09yh};(3XA3@;`Af&vDrSUWE<50-vkTK@$XF)j=Yko*R^$Le;bfFpRIHAcn3qw~6B
z^AAQ)Ps{+6V-+M1G(X^Q>Gj~bovCp1q(|pXP&nSMQBio|{pbJx7jdAN0}V)m8}}TM
zpkbhoF9Hm}B~{}Qknx}-%rDOn?9uoJ#B~Ip;srV<v=?L_Y*s@7Y;Gp#9vHCcZ-0Y|
zteY>E>M(=Gc|ba&4<pz22=jPAMM9>42VV2$Ld^@sWga9vK$Cd<np;#rE3Wu8_o#sE
zb>Y`+Q2}K}7k<qi70^N`7k<qtDxiz4(p>r9pY-Uw04}hOb%v<ecpQA8@R?trM8&4l
zMa9OEU+?2*et{Yl8&KIL$;iO)*@a(#HNcXMfnVboh%Fjo$;RNwA9BEjU+)5c^D@x!
z6?)(JyUsE(Fo1OPw>d+KB2Xh4RDQYeha7hWtGxwQ`=7sSBSh^_{<a#3T2NyET5N%q
zFMx|JkQg<JEs#5WdRh65(2K3hI?N0c_%)zmrvVE)4OrM|z`{-g5_TSqM?j$sNgfUi
zt(W*a?t>cAy)`NhuAK*cdRb>1A{A^UI?N3G8uzgjYcC8vAvv-IbZFFPegW1G=4=f7
zAwNLOuOO!0asDRIZkldN3N`SO3q*etRF;8Sd*2LD%d#`tkg^OEPW&48klhO^NnW&g
zKpfj@47#jL^kOx*$eLjQEwYaO`2YXqHdr|L^s>%HHotd^3M3wXzDUu=2oI3?pw^!v
z%nBb+2{jv1e;jX70XYd;bb!kw@Rgmg@{8i~X+ETU0=W-r2{`S&tcRCRAp61Plf_?f
zQ3g^9EuA1rL%>SGZiALj9~c-Iz=c!ibx{6R02fZ(fdY~TJUVYSKVWj{bzpk|I=}eE
z6;QatOQO0ENJ(@|8(I>93<4!Jc>f7het-l$x&s9qcYt<AgDn6xy+1<B3QY}g*#lA)
zeHc|eXy+_k{XwYupXx~JDJf4*yL2A&=w|xFFHi*@C$jhiDp4%bKm`J*AORIdpFjnP
zx+xn&8o$Od5JyxC!~qp0X^^sH6(i`>Vo+gnfr)_uteL;f6;eWgq5@Q!q=AZ)G)Q@J
z8>0R{f7b@6`k(x5RS@;ysDe~&;HUyMgg|0cEK&C8qL(O*8f2F!X%j#NF{rh41(uf}
zWs18lQkkNl0h-XjUZ|XLh2&H4EHmhGr`^V&unzeFV($mDLB$H_{vOJT6=}#yD_D85
zOb4|*sR1Rb-X3t~O~Y28C_^0zzH0uzXhS);KylZB7APfO{{Mfu9To^ay{taS79bTU
z!s?iT0V`4VyFdb?6<ngs0`-Tnl_%?v@-M~Z3Fv6W<1OIw4y8N+T^!6W4{Gm#5;3?u
zF~d=wgdw>Hk{?0!x<_}U1ZdI=Uao|wfXfw7nG&O-0m{|}%@0^TI(<|WTzVaNKt+Nc
zsIgNBiVAoUBOL%KVv^ONMGVMnXc6PW0B-MqL_E3!B|yWFjynWF4dmV!(29l-kTswa
zq&shd#*-CZoP!o2+myjY2uLI7C|#8Gca3jA!U*#~?H;gWJvuSWtAm=ChSNNcX4LyY
zA?rQe)If;<bpK<pNAnxdc&dO;ucJci0oZsH$NxH&2JmpyfADY=d_KSfdhIr3IO-#G
zIO?7fxF-xcQQOR;6EqxkqL!24e?SCyN`lC-s3~e}keQR0)0IGDQJ{EdppN_O5bm>t
zxK9J*K9YyaKB~f;_(c)qL<c1IQ8b>Xs)!zd>>vk{7J$KU*M%v<;un-3nvXQ_YnG@K
z`1G>sYk<m&8WjV6jZdISrp{~d-q|luprf>8zyo|YU+lC8mkK3upd6y&!@^*Asli&8
zf65^b%M0b)uSGqY4>5XJUMS<?-^L@{{L-NLCuiAf56cTB!u%Q~Dg_?RZyFH!#iKWX
z*~9W$(Gw5G8@u!j7#Pwz1&%o|F}%L~Uvy0oxJ)Zn2f5KB;l+aY|Np<<4Jw5Y?J<yl
z8sC5}H3H}B-WU}HXlLd#zW}tsuq%aufdSlV@L+rK8?<tN9w>jnv$Tf~Buh_FhGuDy
zaUdr``!67_<4#cB4>k#u`9O{RKmkwytOk{_oi|^6mIr5HklJXZ`9V<o0VL)KK7|E~
z{%olJ&DixL{0Cb34Yt~&^ZJXe^$ZOB8W$XQf_4#lblwCT{6Ze&w?m+`4fk7)H^gsS
zlra1T%}<cfgPZ;$3fX9|xgc+X?&|>2Jjl-EmuGmr4>LZH(${%V66~!}F-XHqU^5j!
zi4t21bGL(}uo#eyhdhZ-VS*?r4CFFc`g(?*zOMck^(g?SFJZ77JrZ6xy#4<lvMYp`
z^z{ineX)Z2%aHVC2g<(iIC$X+i30;gj5q+-7m)M;D%T;w4NAmd(?Q;crLW1d1kx9%
zp24CYmcD|q>qn$7$J-j9#z=rqFRP>qs7(gi2L&q)K;85gFXSNOBo2@vQ&=AdG&+!@
zVgMTHdC_YNiMeo)(>Xj)V~*#w*aVz~1Gh)x5l}#Y@*OPF-k?X??f;_F^T3f7rwlC=
zx?lhQ{~B=~J}AF|#{3+?6V>4GfDSr91~x#B1r1|>PJ0Hq(MARwtROAmnirv8gn@wp
zw|>z5Js|ymq*3)l!V_d1()fx2v`7LEt$@u0H9Bs>hFC!E0o~v8f*q8(;K^pAJ0#is
zl!GQ4kg1^HK^_kQ52ssrbe?wP-+scQ^O{SikBZKVY1Ir2F5NyVI{X?JAf+~Bl=tP|
zpP+k^klGiH;V3IGG(gkgj+_i0J6NG$Cukd-M<?rLTTamBjK^7@*>ZvoZu;-hdHopc
z5nE0MhGVSzY&jX2j<N2r<z!$y#=6OtlR@0G^TILKmA0G=e8*T9+j24p9%HSCD4qc_
z;23KWL{GOZCj;{_)>MerI$KT#mSe0D5V=BIP6pOvtlkj06kARPwqvYz5V>$$P6qa4
ztcDOdFI!Fqj$^DU5II|0P6p0ntl|(k16xi8u4AlR5IJRt?SE~+P8Eaj{@8#WA!^IX
zz<rGM5r_wBT?rUo`s}g#80$wHP6nQ1tf#@^y{s=CI2n$y-nHRm;628=9V7^DML`t&
zKgPP$2JDG_Hk=In$5>}TcpGgv83c~8c7u2?MHxVSG*EjBlpj2s4@fp2Wb|l0AmP#c
zOVsfg10#Qn4I5~NxJE^w`KQD&7IDU742;Jdm>EmYdGy+f+kx@`tD+qzgHNxmC)hcx
zPGAoOI&d;DI_?Ecog8D00CA4727xG7!zagBy+N#Ftojg23qq+vC<O>54WX1E6hDOG
zgiy>7>aRW6s_zi$BZOjs$o+%xenF`F5b7p`x(uPtLa5^q>L7&L4WYI|sPzyE%3B2C
z&4EzUAk+j1)ditiAk=gSH4#GfLa1U0l?S0RAyf*4iic2<5Goi#`9dgn2;~T&LLihM
zgz|z=h7d{{La9P1c?cy5p@bn6FN9);P>c}jw;ebjze1?@5b7m_`U9c9L8wm<>K25$
z3ZX7Qs521i7=$_qp>{*4a}eqTggOGD)<UQi5NZ*GnggMxL#T-mss}=~L8zG!YBGfC
zhfw7Zst7{mLa0m#l?<WcAXEf|%7##>5GoNuc|j;w2xSkUEFqK$gwlghnh;7ELYYA*
z0|=!9p(G%b2!!H;P@E8o8A6FcC;<q?1EGFG%8M@$>K%l7385ZCC^1OH2|y@lr2c|v
z{{o@jL8uoH>Jfyx1EID<OxXyb7D1>v5NaBPngF4?AXE#4nhv2RLa1g4RSTgiAQY%L
zWjw~(3gLl@T1H42%Xo}64<gtIp{gNNK7`7IP{|Og3_=w^C}^P^58**=$bs;ZKon@2
z7(7%Z;c=Wr1vKvjny=z;?R@6aq2So-qVlf!2Md2&4I^kc@2`YQ=gX2L&*U#4MFJkZ
zGG!hIA2a*(@<@0v{(h|hp3m_}K6s3U`M*ami-Sim%kg6@2LGE6GB*E|DADY7eAoPg
zsqC&#@<HbY8%BnbVDDZQ2d54mW{}Db9s`KN((8`RM;JYtSyUK3nq5>lBpsWNf>{z0
zj?I50_*+3o3`5qgf%e#e*7G@n=5it9k02vG4nAP^>=j{eurXpN5%6IA;nrco?9yRk
z@UjrRhD1cgqnCBF87G4q|2`20{(T|>&A<MalsbaQd>6}0ohRzp96K+$bUyG%z5p`N
zr&o4~87G5hug-Bt{(UUMtp_U9J(4dtHrNO<l)P=I5oKT~dFI_K;^5T5!tBv2a=nAa
z2z*II+62euLyV5izgX+VJbFdLL53tB;@`)@^m;#Jd>5n(yha9D>#2YL|3mAGm$QHV
z{|^mv4v$`uGLK%K>&F=WyL7(rNWRc~fbkfM;D3)^k)Y-u5+Iw8u^9a?eF};o36E|Q
zm17Ko9=)vgmYfX7SPTSTE&@-gIUuzkK<lY}dU;c8|AX%4uG`PT;J5>{uy7Y>v)c<h
zI~E3yUe@+Xu<U^sAf9OF(f|LCvrd1-!tk4wiNWJItITWgRyqccPFCJmpf(Thw<jQ#
ztolDe6t9LXXz7V)pd6^y6SV@JirL933{u(4>H}I0*~#mA53F*ZG+5<x84$&408wIj
z6eK7533NbZCvWu~5RW%R3asQVXmMmO>$0~XYen<H+Ie@}0xS6_0k&@ySRbo4#IQYI
zK`ME_-T*7%69t(f`dt!4u}XlIh-S8ee9LMCI^DICSNl3xWr{dhi7rS<rzo2k$Y|F8
zpfgoFc{8qpl!zLFEb8U`1vV4rzZ$R-(NK_EI(g?^2CMuIIta3tH$WI{CL_cTiy$gr
zgN+synFN|h<2`#3q=EODAXp_kNM)y}hX~kq#XBH(irxaPH|ykOz5rHPBLG$@3sHGb
z2&7Up9iqhH99T&v$o5XwU5`N_AzBSGx>xkbTabOMs&_$xylmi@=JkIE7A&|85)`d`
z2+}Tk3nX}))&3DI(s?I<C3rvH`v2eKII9_4LUj3kunvvaEDXn4+1OYi38s^GKUkc%
z04(mu0uvWa2d4tj6E8vPr!m3AdE>$2ya{0Odkipf(fuIT_KJGE0;yN~4^5Dryz{~0
zybM!72{rF8OkC8Q1+<ewbjNOx__p6Lab9^)Q1tRn*a;H<_Y)>A+73=@qA#|A#NB?t
z#Cgv{5|{&M8!4;bBZ&BM)+4uJEU8;CR>2Jj%cE2DCpgWCR&4|YDz7&rUB#>i@mO;~
za-E{nASuZlbZ$^5>yB%naOZspPBgqipd(*8S(!mfIz@FZfrIw#3b1xRkdjW`a!4B3
z0osM#$vP91b~;55fn!~CGI&Qm>yz_fGkMQ~wDZO-0&CX?Dd`lAI1LgM-8mmDSak-h
za`8!!AaBcDu;9^CAVF3+kYK0i^Wz{nQ4i2g!%o)B<Dh7`e-+~4<E*AvV65&-FxJBh
zFqZjw7_0XzjP>|5jAeNW#_B%-V?8|vV_6@Cusk|>kAMn?PF7zK)yvyA1MEus17KIq
z*axOQ?g3L;phVZn+6+n?ove4jX___k5m+woFqk@i5ab_Li*k@DqM0C5dPQGN1@U-y
zgAD8Cy#qRkxsz4*0a&G7IVfeU*$;D$=vR<ky`pKL<9IuH)ge|k+ypCD1R2}Q+XY_a
zC7KO#N3UqlB#;TG_QFhH-3(3_tVhbgwk`!bQ&bM*%wFFApe1{~q9;JBjXPO6LGjzm
zx~dFh!i(K76L<x|o)OJD2#OAYdl2#CtZ8>(tUd75Y4i{#=5Ywdns)%g^5|q`2PKwX
z)(Ws&SR=t{hE=N<<TBRP;KagurU%UX3rY~Ztn(l|{}W&jH$Zp`kAZnX5MD6Ib-k=l
zz-yaWUBRKsS_a{L-vw5=0(2EeC+kZ{uxT}bZHR`1_@7cRFBcM1auAp8-w)Qu@C+P_
zi4Ze4Jq7cGcZ21Y)PwbvLc;9W8!)dOoPJp)AiSI4G{ia!bW?gKYxiETzL<Alm9j^`
zynD~Vyz>w<H-IY5PS%6qbi%r*1}rBGamx~jnV}FH%3g!zmP2gFfY=ZTv0)da<b4eZ
zmopF>=0a@n16{k-$=VOGA)y*<%0r0%7D3Eh3<=#WufTF&A?{>@nCT8NQ{z2YZYCtm
zqChvHcZ&)ef{sjL1(off&Zb8vYb7}CvUWWKt3C~hi=Mk+p6pJD|2e?5OF6`(3G85=
zCPZ!$sFBdg>dgtNa#&R$yuTnNy{u+cU{mZNawi~iA0cvHkPw!Jm<hG-><+Mf?;!rr
zhsYg(xaA>4E~x@+=3|hPdRf1KGFK<-REU{v5Z--=oCJh75h4f5FCLw&yCHHmkQ9^)
zk=qAJUFx7b*v<L?yjY^?2517PTlAAYXiyEpYd)d@8nSX>U~t?4I?dnkl25Ow<2DwC
z*PI@`0gOJDhwAlwIuCegUhwQZ=y~v^y$|CFkBdJ%7$N+JEZ&wpTqOcUmwb91{`*)S
zs=EYk1Aaa{!SIq#cOZvPFYo8AEDSqAW<!khusl_-=h1lrY$SN=tq<b?n2`rO4?bY=
zw-#Y65h%ap0XnkB@>Ja=!vlxYCVane@P$0mc($wI0Y|X0KE1LNwt^h&)9b+KYk30X
z;1fQY2Ru6uc^-Ua@56Y(<Khn=MhO2Ai?=n8a7j}6C7)i8|Gt(d>Mre&WME)uy;S1v
z(Jh*;$Hw5&E#=yJyUxO+TQtIy4Rk|{N4JnqH<L&6Ar4PV4}ntA*WUc{3_jgLU=eFC
zff8fa&V#PKj*PCBH%gy>hTQ+ydZ1#d#|)od*3Vm57(5O>U~%krVc-C5tAVud9eW!Y
z85tN3?*L7z9iA}3qua@%+d;vD@x*IB@OW|aLB@v4{|u!Z9+n47KN=o5yaSZH;p^Km
z#>=|bfS2@nbnj6C4PP4G_Uydw*?HEd^O!GavuCJ<N9%u&?jQ%B?nR)P^EzdZ=EIC0
zou7O<UwU@Fbm?wU0o}~v%lOyv{}ms`ZyuKSOYdUzPEg0Ao8KrjTS|6bFL4IDt@Dsa
zuL)>73xh}V0mkN<#y^s!ubU4sdGyLaM3XOh9DKy|Vx<uaL#K_waTW<s(1RD0#>F4r
z4Qht%0xg6v{Pz0x1drZ{D?sVB^8}=S;c*<)s{@(L;bD29^n=IoMvy#6(BpU`XyYA}
z3A*$Y$^`in$~*z0LFOHAyntX9fPxev3d$TH36JBApcR%-<_i!FQ2<(o0pfWaZ~OtG
zA)=tz1MxhLH*z2h11*q%ih@>fL75r|1ri7*Xh9cL0q9mBC=;~03(5rTnt(Dv3zk64
z!)X&h<Gamo6g;|ZH)(_N^XYE>){}KM9^ImcKn-DQDSq&Mb1uD(|2=x0IJ|m84spDe
zK*XO%^8pSI%ZMM4^O8Y9`nKCyp?4$5L!HGkpuHj2L0;^3cJOH40roufblc_~;2<uk
z@Mzuv4q^TlP=fPl-T{sf{+1??zUCd^I031u7GU6S0d1A*4P^A_=2Zf@51bU3U(7RL
zVF2HJ#L6QGx}<g?NNciquNPw{zelIc1@JK;pvBOKyPaiVDaE5#^xq#)nK=REke8*P
zzHqPTZio=br7t5uLfx!7F`yz`^rjGGfpR1VbVtPNRUX}}{1C}0P)QrOWUogz>!)b2
z&ZAICd6*=450ghX>nw=;4ygQpcBsiOL3=&G;|GxVF=+lJ0$PjTd7Qrww7$0amw260
z<FEe=3=I5zp!IklyENGtx*1qOVwQ*a`@!cSbQe2#H17ka2grV$&WkU!*g-pMj=k6g
zqFWD?7JwG4|9nx+0iB^eUg8H@obS>32{bLz-2u}5;wngSH_{HLl4uX)liN!5L8k^l
zHnRMLZe;OjK4JhG-Un?>DCI(IL;x4<aLH~*2k<02%LVY#dx(ziFzBX5*ru4*6QS$5
zJ3~}-UW9{O)7b`c8OW*KAu2i^%{xF`2L4vb|NsBLo(*3Q*3Ft41&)LiK}ht?VuJ;8
z#sB~Rq2b%@DC5z2-WC*ibuk{@yh}CM7`izd4}t_NPt<!lHvjnV(H-vqI=^`{C?|Qe
ze&cTe6#>4<2fTV^j)Jn22je}DZa(ngc%Xvng#vi>0vp0#{PGNtNUIa_=w@{U*#V2N
zy15?RtcN4PF1;WCap?zEs7qh(gRl4U=<WvPUa%#gobh5e=op30W{@DlB1Hb&2`Uaj
z3oBl1(gn5u*gU%39lAjaEtqG3{n5?s(RuGUBd7>{3A!k0C+HX-(2f`#u&x?i76#C6
z7#*;l&SsDv!vhHOJ-YoJJi0qU!XC##hl(;l%GTx|2BnWdc6oGf07<?CEnwo8XF#||
zNtcBIYADF@9-Rk|Gk{&82|Aa00u;Em9;nN71hoo!Lz-9&54^T?Y<$7Mz{t>ifYGD*
zAd73~!8FIl2mhIy4=_3&e94stl2%D`Y<$U}k>=9r_%F?+)ANsy<)sou&_Z{YZl^zv
zjX(bXXJ9DbmgdsQ2r-7q$MRC?{m+LD4?t>Ng#UsK4}hEy<=T3(F4WcV_G=6N?U785
zjjtGPfW`n1Gddo8#07Rp?-VHp6^Izfrse~ndfcTm=ue%jqvgRm2^aqDf{wkj7&I6d
z(i(sNXD{34(R`5U^?B6wz=-{JhTl9ouex*|@aR16aqumZ3+D;f&LbY3ulZX+2_1B`
zq=8Gf%lbbay*z9G{Qv*owe>)W#7oe1#oZzNe>{2}|FmA>Z|wn<gq;UHnqM=PJ~ur1
zVvRPmq&&*sYQxCD@M1SJXg03(Td6rTOM(spL--$jT*=E9ssEW6py!I+0-JEV<P_v|
zl9L{tKS7IsG+rD8Nq{#_K{7tbAdurgSp%MaUuc6=fsXw+TGHHlo4;>60|P^^^MCLu
zS3g1R#*lWF*A8&?y5P7z#OT?4fW@)%V4CWGW^gp?GQc9)vD4vSnro-WpXNi1KA`hm
zJVB*)^Ffww$3M2<h~Ay%*va78e1PfooeAKrEg>ozFBWS-0s@o-OKdzri=PjI&R!|j
zVqtJ?ed5u19DH00f6JtQ|NlGg0A(YO&R3v=N+K73{r|G&A80q|%Lkwp3KdMCAbhz8
zwEqpQJyii(m=eIRS)-C*_!hiP<(y~db)U}TzMW@1y632X8U}To-wv_!w-kZ*QogO@
za{P9boxcUN(=Cnv{aetfNg7}40zhoT1N<6aKl2Nyff`1i`32%w_%;6UYh3nW{P&q(
zfd4bUfIG`){>Yy`jPF15M_%x-Jp7qI^2lfY$kU(sBd&kuk2(06KjPD8{)iW)J3YD~
zi|{}53mSap7tCM*Ej0+>*QilR@Mu0#0lIM6F$OxA?9=(e<KPcw56}@v_5A&*|NsAQ
zee2kHguf*U#5};?0^axwicZj`&out`-#mI<K+Eu5R4mf?HU1%`C(xcKkH+5&3=9t7
zD&}YBO~-v8o=aznih^V33m<;J&)@{*qxtzo?;j=xpUz)t{O=EV@~^-4nLi3-EaNqw
z&R3uKBR+t{KyqMl7Z1kk9<8@O@kjiqpYe%5>f0y&sQ+l*tYCR50@_}QSnt(&0m*BA
zFJ4yu18psM|DRvu`|Cq#6UdBDe*Tsqr1<2AoSzPgLyy+mY5W>r>w-ZX!vi4pCuod*
z;unbH@L~M-iC=&}jbG!>Cw>8U4j;z%Y5W?OKk-NY{KOx5+QahjC;rF_pZFt>eBzI|
z{)s>4;3xiwPoF?>x*g`(PyB)gpZEncIPk<Nv_6GIEekAa!SM-+TF`|9pyr!9D7-*1
z3U>Ivx>Q8eg3qS_9gjqGeA@m3$LA;hh!PbCQ0#r;kEl`c@Bqgsh!2Uw`W0wiso;1C
zy8bn70%(`Q!5=X9`n`BL6O`)^>C2}(M8&|TJ4QvrxAjt;{mplV2W}p?tqIC7pmh_B
z7aebFINr_>@MS#VX?f`8;Txww_};;L$L^iJck<rLdk0G|-aP4e+uHGVwZP$<?{2<B
zJ?{@KJ$U$ZFHr$CA3^Q~)yJUHx-&#Y!>98YXqT9QFQ_PSQL*6fvjd-(`_}NbN4IWQ
z7$?JPbx{AzxAi~tUPDkfiW#&^k-0?0z|-;$e+#J1@7wv;qnjUG-GlG9Yqo<nf<1ag
z88|`x$^$PR{AL2Remy&nLyhVd1C>*Tf0!6NoAntzJCE_VOkn`+)c(fbG7nTCfbJ~?
zok!^d?zg>g|HH)K+xphC^LUA%XSXW@XjimH>m|?5P=*pePslE5Fkg(n6?8kAXLlHf
zPba8t26BF@Be=jl0=`uqUS>ekmq)WJ1EXi>yVu>2{+DNWD2Gqy%l|<Jua|-R@7e9n
z;nVr^e}I8+>o@+^r2qf_`?kI<+29G<?OnRkv)dJ<+@ssU;I)#g;r|I9;PRuJ!>1E`
z)Jca&vnFF{6Xe7n2Ls6NeZ(}F$NvYuo!?(B0HqN~g96mv1NrO{f8SD2NOYbs{I(y|
zi}IMc8$@}2|K-zp$%B9W1&{AHJUb72XkPSaJy~z?Is@W<(2&DS&+orL8`JsMUjj*Y
z9`fK{f6aq`{b3Ky>z<m2Jz7uJS^0Ec@R;fG{U_*nIsWw*JvA>uSl2zl>aKZc9`<d$
zRKEe_9|zA)4$n?YpH2yIbGh3^#lg2zz_ZiP10v#TcpL1**Ox%&>j-&R3WEE|H5~l&
z5Abh0@cqVT(BKPnJOFz7NOvY^xvqszccO+zccen=TbJ$#1^&MIAU}6Adw?=_BdF%B
z{qJh{*6^FF;U$lQ&zWC~dN3aIvAkZQ?Ad&X!>gMGyrnW4v?$h_e?5zcN9%$5yPk|k
zeJrn+-UTfO2C+M}Jd-bbFkbUuJm%SH;MpmN(mv#0FLD@^`z()ob_&*ifYmFo{gNO<
zJUW>?lP`OAGI(|hzCMHy0S^y>1wn`1K>QaT77Sj9T2csda(AJ^Yb&4bNDa?!nZu6V
z44?=*_<+TO@q$O|?TQeOP6>~089PT%)@pvu=+PO$;o2zynu2t(43sF-^GrVE+IrHX
z*9P2tFWKhNY;%mU?mo;wkJj6zt6-|jFBu*HN6+`$9-R`emqXJxN_o)u2GphZXx^hz
z0ZL1qJ>cC{j-8i$I$Kmgja;A39+e1228IerP<b%{bdEtcgNJ1cSUrDVq$sHU_=}Oh
zMU<I=!LirrA85qKgSiE)$)}saquYVQqZ6_V)Ug*-yFtwJ=)BPxqf!D^-Oa-YG8{A}
z0ZD<amr682B4F#985qGw41pX9iwnm%@PsjV{iI9h1@K}U&(5PDi$G%-o(G?@_%N>l
zdjMQI%mm4RS}x%94cU+b8r_4WcNdimkZqvD{(QP+Zuqv|=I@Z^1}*++Q9*Ll0nkah
z9q+k72i_j^>^uNY(ypENJP*EBaOphn17f{Y0G)Bezy7-?C=2ng{|9Ql9ekv~zy7Gl
z!IughEh^yS`#L{>c1d_Jp780s>B+zTB&ZG%JP2|`1}KCNK2z{u{0GiK9?cgSJUX|4
zhp6C=<KzMrjZgSHK5#NHfSuvec^Bf0W1gKaJrBN6@aeqm%fJ4FZ+9w(2mkte9{lUS
z`gWf8Jor$-^Wb|0{`JRw`PU!ra8aoM9q9p5&-lZK@tlv~0gr=^6+q?kHmFk>KYKP`
zXYlBp10G!aegjmnPiaxP4a%0yd%(LR7&}^2K#f2CZF|7t{PS8=Zh<=b+aR<9$B&K{
zmHQx();vZA2A^)ot_rZrT@7!$8XoYpJW(X(W8DMxXR)5A<%v>FXnOVOJmt}O*q8CP
z$HCY3zKjPv4!*MYWjyK0dE0~WfG6jL%EKO=$9*{O^S5YmFff3YP<O8Z8)Nv*@V_It
zN&MQ~$MSHIn2+UI{^ni=1_mF?!~CtF+zBereL4?$UVQ0s@rB31NA{i<UwCp}^y$3i
zdGR%f@4<P&qw|mt=Pmx08|(}Wjt&19OE!Z}f#H1R!+FYw^HAvl$A*9ZORanu&la<S
z1{NoHFdp|2y!UzqqCejPPKaok;pMwOpoM@AAjgz*mumW0o-I-VxyPgPm5=6OAI(!9
zmaodpK;0mZ&a1Ci!uuCKorfIvfzRa7yyek(85BI4uRJX;dURg(Xui$xvIbPQbzXf5
zx|{}VUiTJoEP+xNXrR;Zk_Z33HQ)&I`2G!)wm@T99-YTQ6$StLSD?X_Ju0AKL$Gv<
z3TSZ4qxEeGU&9`-E=K;AKLQL4{M#V0-qE6R7hF|8*$Z+Ne}^|a1A~J_j!Ff8ix4{~
zq5dy5^RZq6PCsQjKAjIdv|GR&kK@NcIy^0p@HhPhEw*c}QORI*<ezuU@Y_o-c2EX{
z4C(rG{`2Vk;iLJ$!}7RC^F0O+xI*xth7>ykgKNt-{%s&TTY1<)DJ(`M!x5amK*{T*
zr{%{YE>FwD#p<4xA4`>dI&XnaCjcd>_n@={Nm92xIDh+slGMe@^FE!&T@BxQaNY-9
z;LO0^0vdyL+yg2iUt9ZFo-5+=vAj_n=3{xTG|;E>l;_3Qp0M=u(v$NtD1kuIk0<8^
zpUy)bp!5SuZ;lOr7)$np>Q&B9;Pi6~lz#sFFXaYhKE~sof_Go9_pv-z4l=(;6=Xi>
z5Dg#Ab3U54JS;C18+$arWAx~}@cI%`dN>8ThwJ};56w>=prdYXd1xN;w7d*zcQ)T+
zc)bFod@)jclYie)pUyQZkhb3*a9hxafBgYay`JF;>ch9FfQE@2THe+r`?ek^iF0W9
z%gEni!4Ha%IS_r_5Pcq<_dGg(cyRvXZ&}X^8b^7-=wbPTzs(1v79`gKHr}CQjSA?X
zaERl#fQ@*~56$0j$?hrOaeQ!L?g84BYQzdkNRXt;-!cVMGIs9)XKfG5Uq$K-kkW>s
zMAoD8g5ft0%^x0?hxnVpl?Ehby(~r6(|Hc$R?Q0@mdA@lK~CYHa)@gRxTNZs0xq5!
z_JAn{{%uf8Tb;qh)f{jJq9i?ebl!J0eCxw`9GafeLA50`J$YJwEC(gdvPe+k3?Vi>
zsep_CrzcQy<~-%W`N;!P9{u@W$_GkMoi}_SNoox!{j-;<dRiVX$B~|{5}lq_gVNJ7
zM0x_HGiJyfibroDBY$%>4=5!-s|No5y`b$C-H;$OyyWryGpMNH-**(;V(t9k+4<MA
z^8!=?QldDtysh*Er92mhhQI&$TV%j>F{JPTl>?kF_*+v!$?Z5qJ!rTFy5JVl(D?sa
z2;n|Z`dR=kp#Jl>sDQdOE#LTCrNI%4T1r6L%f6Q9%Xvz5d@La~UYU|l=M7LE29*}z
zn#bed3wvM2+a8>k!KKB)%CjDwH+(n`@V9^~H&FLy3b=eTJYe`AT4=Z-+~aBavYgw;
z@>X$~r{&Ai!U;Z|=V0Z>GkedAFFiRwgR&K<{CH;X$@#&j^Oy(cJ&4o6<;OlyF6TVw
z!+Fnx^Btu8;BPGh`G@hAXKyBB5wB0@S%iH)jK@6$Z@iuXtB*V_U-CD*gEB_vH6P8h
zKAQJDEI$=<dNjWUO^Uq+tyX`1+M~M!(kKE=a2Q_l;ok>pDuAks<361~eE8QN0>#+3
zh8mTM|D~Lu1GQQ?co-NU>KgWdb2|fn-y=o_hK4=h`hk(ZbrZNqhn66gbHEh~f71o9
z=oSdCHH;Hd%7A;QmUF=M5P!1+C#X#C0T(8q%n2$?UM>dtp&Jp@(DDT029Oh9#)8IW
zeW2wXsD<L$`4?2wy`1$Ibo?2jnc%^{Zwk0>167isRwbxf1lN0=(5kQ#vLVugfBmbM
z?|=M9I&TjYi<~}|xA>bu8%2CN&%sLLcOIQzeLC-XXkPQQ{0!Oy(0rHSW!}I4|3OtC
zGo%Xi>@8>HZ?*(^8eFIG_dEXl4{Nn}f#*{^zuy5Di7!|D05upuS0;exBRs#~c**+h
z|9{W#xA%jp(U-5jg5^EF-vU>}FAx3#^TE|3=nlsWP?UWJwd6p>J8CZU=!6vL$XO9o
zLA?A1TD;f^Ztj9C@%(=CCFfVLr4UPQeEI*Mzx6kA9Bx|!j&M*b57dfi*aI%s8Tk8(
zSV1kQAB_C1;8t$;97vE`-Y63Cv3$?p49Y$pmN)oYQyCc;99rH&3S9pFVhESNqa4)0
zYyDQL<IwV!zZJBm)dO@^Iw=1)cv@cMZv%};g5)|gK}R&mgJO~a+yeCA-**+%BnMBq
zL86+!^%4uH-Ee@vZxh(u|KRolzXxcH?gyw#1lG>q(ZI&Q0FD9hfWig-j#aGCR<}?0
z8t^t*m(IhWHaGwJqpqEAJP*EA@a=r)+xZ&Q0Qccvf7_FP{T<)VbD+kz52&5~PQe%4
zA9$<a!}!&Q@wBJl3viPR)HU!t_*lV*@wR941qKI;qx>!BSwPLzgXNO^t#d$4Zp%5~
z3Xs3457e9n?_YpUV0(5R^VGcOWBI{H^59F*AUZTZxV9Xq6!++cc-n{al?Uf956(mU
ztv{H-f$YP-4^n9QbiN0reo!{y@9PB>+Lp)o+e<(F|L<w}vy9Wj@)&<h`X|ulqHp}I
z%m0B!Jx=m>%=`EMzu~u+bN+$uhq>pY4e6<PYM$`vJm|r{?}d-$XOHHakQN&Qe}_K{
zH0U4|JPQK@q~Hb(N`X?PW9LPWgRc}E`PUzH>3r;Y@Qs3J=WXB42R{7kZ~5}CKj_21
z{<JSB3?D0i!Wq<#0mYJU=TR`1c@4Ox_T*oG#h3A>kKilMgAWvZ84r3iUt;)v!^#EJ
zCY{5~z~E_l9a6^kfD7s(CD6z=sHpSQyw1PPMWw>0^OtAm4PVU@K9+|)nr|_@7WM5s
z;R9{A`e^?0wLAzC23>*FF`Jcv!4tgygn@yf!ISYPs2>9gMn|xqBftMg4{d1e)q0Y@
z)td<%@ceyoY@pWhH?S&xkB^`rY1L+AU}!nO-<JxOJHX!oz8s2w-wjXx^*0<qH5Vs%
zDL1IgZN$vL0CvHJ51`_#MWq8=BKClfs`1zb%CG<b|F8Gy-UIH&8omWB7Ow!UlK}N<
zeR_3HfFc~+E$;SF$?)uqWdJ3j&NCjJ$9(wLfArW1%2^;!c`)~Yjqv<_$Af?UXCMCc
z4?H>{oi&ech?Gy~7I1d<>E5CO>PdTQe)rJ4=+n6b5+j{oJUWkgH2-4&=>vr{e;*e(
zk1}|GOEZu|L7o49;LB+|EN|3^dVuNxkP8~X5+0U^`R5$+X#HOy>thM&P1Gsx0G;LW
z^4@#U2)I0`g$>FrOTbyA<}su`Z@E-@6XZ`&yAV_+fkrcYx*>hC?huudZpfI2PiKva
z0caFI0Hhccl0Ka!pslPfDj<OdMh1pX&`5qaWatB=(gGv_F3Lb>alKgl?*ISR1N^N4
zpv79vM;Se|V^lJHm?1Im!wd-s4{J~-rC$!L<{twn%=!C&{`>zQT#)g%$bfop&A%D=
z`&dA+ixLFCL3wb_p_e~E1OD*&0C4&CazFfhAqd~%H#kUK7#R3lt(ZV{Dx|IC)A`=j
z@PI?ZUk3g@HfBiq*QxmjR4GAQkRF`B_*?7V{r_+H|E0j6|No)&Hv@mC6lmhMdkVOw
z_TZiZuA4zLsG<PTAjk5zeEA7VjF3h?D7?X<+aMi)m+yc6{|`zbppK{y<3UJ?>-52s
z@g8WP<K@-g|Nr|i{(=<zj{Hs^KoJE>ExwE=KzaCOH)yTH_gjvT%IDbc|B&(343F<O
zKtnvBA_SbAUe1C0-}Czoh>#zoJ_P5Od2j#!_vByy4m1)0&NPtB(|Qs#;^xt*0dZJM
z>)ZeTyCJ9Mv|i$G$p9^8>+Vqj4UBnogN~BD=yC9+y$9nd(2XXRSNU5*KpI-WgJ?e8
zQ@{!hPx^prIz|QtmtK$mo(CT?`&gdjZ;=7Hpxebu!m~Sso5Q2|Actos@~SY)LnYV2
zu6W4+wiPmH1@<@8v!HJK%M4Kc-0RBdWBG!=xfB%9&5(#@^z1weYx=%q_zDX49&n6-
ztFo7AKR`>pTfkj0P#*I*4(Y0ay12($!0k82mzkgb|DWL4@Z&#!OC-qXZivx7o$ukb
z#><U=;YsAbM>nh)_x(F45x|;y_xRgi{RO#T3%CX6W4Q(F68<(jkg1mU_*+du45;px
zLf??vSNts;phySDA*_^u<%D;j^wRn7<?HvLrVb?kdvu<AY5WPn_k@>XSc+z!k1rEI
z$)b1Z_y7MPHKpY-{-*lZ;99R3QtK6h)@g#q`Zs?6|Nmtt*lUnx;W5bA2P3Fs37VI;
z`~gaZpjMAZGbEodynGB=9SQF*{{W3FgZjwLpFq`lGb9EWLE1nW1s?S8KK%a=_VP<c
zknNq2*a1Z-xb1r$RN{j)fa0#f!}2(Pn;XOj;55VU@!_Qz$ejqkTb|=@oAvYme}|U0
zunOm87bvTO3m#A*?`e5~zir~r|NmPK@OLc!_5c6N7D(dy?_>F*Ova=6J#v}?wHQH_
z+{-1P76MXQn*wSh^oBD+@AdJp{N>Sk-J|&e!^<b1L2H*FK7o6b733381_1?!<&AQ1
zQ?P9!sDTb@3U>Vc{~uIZK~3ZD5BdH7KY#DHumAtQ3<Nb&pos=l(tyGpoIzf8fSbaQ
z^nf<r4GOf@lc2GH>pq=_eLK(cw>X1J+GZ;T{ytD0;n5w$0ji2Sk{KBodOiPx;<odw
z$H9jz9*jR<OHTmbAHd%SYNL8I9{^n^z`+2$561FD>BDZwv0I?&in9z14Brkh?)dv3
z)J6tfz~b5Y!`1Ml;cZvLOP;%7^)sZ4=n0xq2FK=WXP?dwpepaDr{!^1exEa*{Oiwq
zH2-F(OY!Nv;h}lM!}0`37&OlB!Fbxm@>*GpXLo>vXY&DpZ-*H9TS4osz~j!KqUoZ?
z#h;#?=RLbQJeq$p@b~QnjemCD0Gsb)`J;9+%ydX=rG8Gya**{<Tl~+wp5fYZ66}T2
zaL^P*K=VIF{?^$H3=G{<z=yN7UMjT#4I<C<_-^mfdI_|yYKsbJ#UHq>%~m1rVeQVr
zKMyqT^I8<NHlXtv=)5C%{RJM}2gOP>_#9*C1U{nw3by<8ZTR>Ef6E(CW3%}`1AkvW
zsMiY$EYI)%JuDA`LgnQ-(CUZIFQ5VqRC9oW)Ti^I=fNk;pg4RH%gMq3;&&bcRpA9M
zd|~|KAb!OQTTT`R-_~!S%QHJ6WiJ1eL!e2+DF-+X@wa|s0JYhk@VC4LrPtmm;HHL0
zZx5tW?1eO?Jwa<TLR1n!Z5>b^0o~{cKGnt(bP@|c$fArFDo;Q~Bt!$K5e2FeoBuI+
zcCvsQ9H8E(XD6R$Cp&*Ds9N*rh4dJGx_wj%Kv(M+_;lu|Sa^2+0Il(GQ2{qwK*0_=
zI~vkv0WHRav{^u%_fF6eq1_NKfn1>Q;?vXr|2q$Z&Pp$Mv5kX;0pto$Yx>1XFvmxw
z;>COp7KY9nFQfkb|GyiQj9*{mZ^;D}<)9RV6zGwE|NjTAqy<^&3QGIJpnk#a?jCRw
z0mb^11BRDcPx4PWq<G;aH#p<6`*gcYfYYI8=OK@7cL4~y`3Hk%=Ry8H3s9~E7lEKs
zA6#a6%=G;J!_)F$JxbdUBE~=GAh^HP?atxZ{DXnN?<}ZFf$N8AJ;dL?8Y~V<7N9~8
zCJre!eNOoDuRjFQ{}`+emPvgy5BOM~;P1%=w-#Jf3Vaz)w4C(mbl~7`jf9E$^n!-h
z_Nags#DbdH;JELc13t{qaX%9{=dDozErIpvO%MRJ9zntF(+j$)4&3Ru3|gG(*?H8n
z+ehUCD5f(&O?Cy)vAhYM-C{33Jj6^hE|z~iI+;O+L6QuQif5-Q1AiOn-ZIcx+R&n;
z^8jdC95mtO3A#KA9Lk6J`#^W%B3j^(G5{1NzdbAu){7xG!9Bl&#2oqO9Q5R0e;O1<
zzTGh@KluAV#T>#2kmetrmWTQKSAlW}C}V@dx&bB*4rmvCpA$Zvpan9AJ(_<o)TtnP
zD;}DMJS<PuYI-mp^z8Ie;Q(DB_Wx!0-~azhL=nAxh^qQqp!FP#2VGlEg4LE@a%?`%
z=-GTsz_a;?fJgIT4$tPJ94?ms_*++jlN>B+AW;J9zJns;<$^!||3kbEzD^44=91-}
z&A%BC0Z``*^1*LUOUS$*$OkVi|AX{_yvN`29ArWBPlh^OgdRwOwmb|9w3o*~J2zX{
zK<#^Ys(ihgzhxarBU}VU%jAFm|AQ0$%hbRB|MRyr|NZ~pv-uaYs}e!3`UP_pzt4%6
zR)7Eh2Uq+2Ew4chCs6qMBD=}+`%h2H1N?IizB~<@f@;wP)wN(hgE9m(q4&4^`~Ux?
z5ZKxmAY<SzeBI06G6_Wl<OG<J6(A$!k@u&f)W6MdG(0*lcME!e*XOrhDlzqFt_Ibg
zZJ^55>p!R>0oSxQUyDJ<FOVwPL{LVvJXrb$G&j@wjlaVZRQ~t!&b$v=@CMrS3OW$P
zo0)~dr8||uvH1@pe;epbU5{RG0hi9_h6f-W3(zUv;9im^c;F0Fyu8+f*DsFE2N_*0
z50>z|be{UmpU>%W@DU5YAdj#ksDamfP{7slNQt*g=P93VNsyEW<1HUcsnU}^-9a2a
z-H{xi_~Gx{1F9xE|N3fP^|gHM$nSp)q}!MAR`Yw%8c>iKKAk}vowW?5TV43~y>R?~
z*VXWVtKrGk{~o>G9Hla^laSnVfDyE`#H0D3fTQJ)5)Thhh3E0T@`p#apoirJ4}Skc
z;Hs9f<O;~$;y&GxKYY3sT{=&IX4ic>Wte?BQ<ynGE&%xrYEJ16&<14i^<;?ECx`jv
z8C(tDzJ9{r0$w!(YAk?~cLU5LKF7cZ^}BRFe+g0mnqLfVy;N7>*$rCHQxfLV8};AS
z@RH#r!`q$*A2YuePn+P$c*xW8a)~l{(?~aq0O-hTJ<$3LPyY2Rg5dQT9*l=QEiZ%C
zXSk>scqE_nWIP342;rh);nOJ)eHb(~WdPd;0bWi6nvY{(h&~Lm>-Ov8$mg**Lf4ac
zG`?8@npEt(?$hg|k^nkc*TJXrDCh*30MNar$6ZuFr|dC!z%Lp<?xGR^@-0Xt0>(&y
zF)~1m7k;1}OuZp09w0+AK!!ztE;=;_33vObIDig@k1#yoVR@0i*&dW!yJJ)WK;^fG
zr{xVt{>cYDEN}8pKH$i4kiXRklzJ@>@waJ$6t=zvXEFX3aP86jiV-yR>(iT~V&kEC
z3N$0!yF{e{R3};9f|OOhoi9B2-9X3A`*c1!?xJD?c3|&a$SA~f&;g#{!o#=o1^BM-
zpDzlba;HHhbGMs?N3w&0NAnNHI<0OW6&p~TcyyiuwUR*RhaGR>0a*v?5PEdB@N_US
zFo4h5?RF<ipC@P*<&jV4%NMVIgIrkZ30jp`0J0c%jFBg3L(UDbTU}H%UO0dG|KFqW
z2q+R^O+!%n1h*Ga1i^zqudhJM3($J0#y1Jf3=H2K9T+`2FY~v8iV2V2E#U4rD9UVH
z!Ixiw1I(lI(~HPEAQ$ns8Zv?gN*paf2lv>(0|&H_92_{Fpux#UEZ|IZyhQ{w3IGiq
z5zwF#=-?k4SI|ZCpsg4logWNO8iLk8HCJ#jlxXvJYzBpTGw2c$Q1NVeu|&it`Os(n
zd=AjwFDHJ@9u|;^&4(BvC(#JFSe`6B)OraN==?2fKue#z{(JPgaeyMoqt}NIcAw%!
z1#l5*d7|`7=Ov$B-fqw??#_>pQvhDr{$pkUg|q`Kq(M&h?7Ru>P=V$pKrO=;S3%vj
z#v`C`i$=Mh036;hVSahYdJ_+XN=WG6h9yA5OD{pY6bvtck7}4O0dn6Nc!3S5ed604
zDbW0r2YfigA&>3|a4QH@`FL~}2zYioD)@9W_;h=4@V9{aOZ<JHUQzQ;zLKcspZukM
z9=)u&4_O(GyMUJ$F?e*As04u8!WKTDyCz*aFM=Ajpr#OLND9>S?S{0kJ3-}2FRSB2
z(2YATDhe<BFEBAo@Mu1g5gm8fqnDL|0z=O{fEikaWGJHl()^RVbZR%GpAU05*rg@l
zv*JOAJ24>qfaGXMwrH>iIsV1D^9Tn+4FjErTK@noG+a6_e&QE&QBeRDVhFR5j0Fc3
z*vv&pW+L3%?I_XwgRw-S`3F;pa`O*H$phanG(TX5@4o}zs?%)22wBQ^cmj-HC+5*y
z!NJHs71Yz~bzxuxE%9>!O$Eb68A1CQQQ8BIZ$Rxq(81peK!qWwQ+C;>^E_xzU}ujC
z=(cAcP#M+jBmin;fNs&?Z|w#RrF92OxVB!Z3-#&t*6{3R1T7Ej0L}g&l%;^i$$Opt
zd-i&A`1bl7<an(No=@|Ds&)Zo_L<;;x9<>xLFKWh<;l{!o}G6*y4@@wR=Xit4ceUM
z(j5l2I?AWp4{o(O*f3A1L7@Fjjwn`ZAi@`BKlpld6#E~6ZViCg|JA4S;ftbwpkdjU
zj-AI|r2hkLm-yz`d5FJ-n~{M5)Wu>3d9d3>MZ&k+MMc50+gG7C;J-(=q)+lGZ)=$o
z{4J9}<GY3@!R7x$pU!taoljrn@q=y#0^h1G4C-Kk?){ZE{Eyh{<k9-Sgv+B@pOL?1
z5(5K+;Q`Re;-JX!XgmUnD_BtsU4rMp0G?+6wY!`ZK}Kscf|kj(ykdd$lUp}~I)eXS
zZUUWb3=V&&`j0P!!RqxugG&4@C&B99^0zYo2eol^R2WNJd^(?k)^NSd0qKR07kG5L
zbAax74KR2a51QX~1&z#QGcho@c3yKeyyVmQ%(3|&lTYVc{+3iG28M1|iPi)BeV#0!
zqCHf@vGce`w-jg+6f`){?I!`6k>OzmO)tADxVHZ1?-K^iQuez4_v!5cPh5f*+4}U#
z90l*tJTSqtTZF;0Qv`Ha7-(tTEg#DprLR4@eK|a={W$nrqd`@4>wk~V7yPaLOrS&H
zpy?PoHUKK29FDuFfNnMi6=a~zOAIcZzd-pFd>=B1p#ZANT{=TlDqhI8fBg?`-W}&}
zaRzl2x*aUK!zDbr{S{ogLsTk!k`ojlDmSbB{qNE3F94dZU;n_j^T7+xAIuECtxxz{
z{(`EW*4tnW{4MVp7#LhZ<Jm@_`M2hO%=}XiI5z)cEahl9z~8D1@;^whH3cmFi<!SA
ziiLrpJ5-|eQi*f7tHTP$Qk&)nOrQe71hiW0<qHpa(9JuCJrFCgJvu`fKwIcsIXpUF
z{tqw!4FR-l139Df?u&)znHai#9YEKjbh|1vKV;-@6#&m5Gk_Z`j=R!83Y&j0@%x?t
zb$~5Ay2C6yJ70QqyJ`3&J1KZ{gNuF*&_TiA4DYxjp8-5SW6%u=ZI{kVFPcH4o1Hgb
zSf6KN@Bp=-`CC?jBBxo8k-udkh}HS?#XZCS|6fW%CQl&ag`muUaP>F-mRF$84oFk$
zgFpZOzq|<QEP_)QC`0kL&IWa#x?MG3D_z0q3Y_R#wRl1CUnk+y?WXW@KBzAx@4(>L
z9V)?i$fdXHpJVfXM*bGiXq{v8e<uDGdnN`3NH#?tyn-jKmZe~4g6=)|2#N8H@qhoP
zfiFUMnZ~d2;l)BQU+)7Xp4%3ILJ_q0*^k4c^8<fNA;_hc{v7-*pqkjDo0U}wynC<e
zCM$zSH^&R3b4&~`@BjY)-?2LeRI0?NDENX(mEixKF`$HY$iJ86uxGb~r?n)13#i0%
zg%vI@#JRuzf4SuM|No#!18*b&FK~x0{KfRtOEvHw4e<Om$c4Tf{H=*#A-xYCpmweM
zv6qLyT}cKP>v{?PRzFa`x!c_W8o!nvGW@Mp|NsB*_IGG}$jHjT(D)NX^0%t~|Np<C
zLduT6MH;-t43s4l>Ks86;Gk7N9+raqtusLj27CQM_u={UE>Qu6254Re)a7(w@a`62
z@oYZ8;bkep$lsa=TES>}qV%OlGdrV8=dYJNpww_2G8PBQr7uAvT^@)#&)7j*D7#^o
zslC+r{r|s9Zw(_jvP)b*5$(}=gTDo|l-;BC0I21|;KA>5<E1D#Z^QK^fZ_^q)0sP{
z=ikln5;Tm_T%%IK#NV<SG>_dK$pI?MKtA*AW_Z2Uvm09qf<^-@N<jX72}(?!-O`}4
z5@CWT2WZF=B=6bHz~34T3iQs?FN6R8{|_z(U*`Y)|Nq6K(@YG_d%(3b52!e+;BQ&M
z%m5SO=WmHb@VNO~?z6(>`1o6TSV09bXl!xuX(oo3$>7}diy6`zYB|8)q6NAH$4#R3
zK#6s?8>p-?ftEEopt9!Ui#t-#vIcw=9(aeE7=H^lcnQaC{+17*f~51_3)|D6{eOqM
z-5i=9F!HxrfVzU+ZVJc+OgDoED7pHc@aPV;00%_3E4X~&Z}|;&B?Gu{0hd6XE-D6|
zprO?q6>zcRxTAo9f#GHE@BjZ_Tsp<X;L#nXVR#Z`2>+CWu)y)`JmLeo&Ai)Pz^9wb
zqdQc?qg&*ZN4Kv4e@i+GXeabLM&z)`K!g;3sRXDZ0M`zn)}aO{pcP*1Km6%GsA-UX
ziizQ+`tSe$u?EpjNo+y%2IMEuKAN+ju;{!8Dap;Cp{oZ9-Ip)wU|QjOYCt79f6FeA
z9+2iwph@7)yD#pZ1bI4C!K2$x0Wz!ta$$u_=V8~*Lq6S69H7(&_BH1&P~q&^{F}*<
z-}g4Czv;s7f8m>}15=5BXY)@+m(IhxK!NGV?|<`~n*$T1FfS4DX#UCQ2wn~V32YaB
z|BIfMr+vCp1$?^m1RVLN9P_a};mAMbuxrb`5>8*sr~EBSY@nJvUIDW1+o!u;z_&Y^
z17x==zt25byzsY71&6*Z3v%esL!?@M{?-WaD0huYLT8MMgHNyR*DIitr)2+KVP)v_
zQPFVe1WoRD)~G~)isFEsso=rg92F0r&J@t)q%kT6ouH1!yTeQjFL}VZSNdh(pa1`%
zZs6u`1zos?EskgJ{q+B(IJh`);BedpG8vjq!7I-^ntwC$w{)|CHeUQ=E~)bAb`|jG
z4io6SdE5m&?*d+552}SgW9ps<U$THAM&U&b$R$mn(hF?BDNySXRLw)Kxa@Wl02zcZ
z1T<#>np6WD)ET0p@QGi5!}H)v<`>N%gDgP?b^9v#fNQ=u0iW(#0iW)80Z{AK(h*!J
zfyTDMorDYg+Yb14>s;{ZcGvLfR=McgZE^t|ubv0rvS=OxE#d*&l6=YY;5!zNW}Ax)
zKD|0u89*zX`Y!y2mOY>n9Au<RH)PR{Z|4tCS4P35vjh|!4}CfzOQT*)J_Jgct{R|e
zchIB?Xf<~8VMae@8x4<ccMU&g84ZtaR|PL?5sjKvFAKosHOM2N5CD0i9Oj8nj{E`!
zAP+)(;oGeO_JT{d&PC5|nF}ub+n{5?ng=`&zG3#50b1<>@(E-{&*R{0W{+l@gW$~*
zAeVbUcir>%{r>g;KXfVv$vbKM8t1@^PFy-)g8Sr>FrRcj@@ziB=)-Iy0rG(lvxx-A
z2OicU5;Z$st^?)BZa)E!?oa_xlz-wEVEn`%$@Ga|km2P-kR<4WZ%}9=6(nVQKK*~W
z3FLQhYUltr_5LyQx1>SZ!uXREGbBl^JjlfGQXgak*pLX&bx7bO1(`<$1*j`hy2MCQ
zo(EqtedZV7c)<ZO=o#c>WRGsvT+nHLy`oMRA?=b`N0}I2x_<_Bh7kGD7bMv$>vxf~
z{CMvG6T{0IP|FZYpiBe>%3P3tK)aSelT9!GgOqlMDM0gKw-;y{l?gP?e*7nLX4d@q
z|3AE3fR+X|DhZ$tKPcqEg#>8A4ip6r;4%VYKe&6Z@Z$S^CWe<!fBgUdiC;i<)de&^
zC4de5#4nhlVgM>Jz=M-mj0BfBS3pM10xj=Av_e?HehO6p)kZ$ur2?RW(W9Hm!_tZ4
zGfE;q;n^*70+LU4PWg7LoZ#Pf0@Ukc&^+OB@HLai3{YDEl*By`zG3ocwmHNAO7oz^
z?bE9Q-jl}PC-(!IV=+?r2XF$fQBi;;aDn}htP0PfCJLYg?#FDS07~Fq)*=cuJ71m!
ztz<w-;Gg*g7(eqzGJOUm@C_hIaO=L+?IU<CqAh6L5aIV{AO(n)lsR|>QmlqgcbSH7
zx3#Zj9S48w$)ErK`*v4z_*&ZWx9$N&?5_e){o>gC14JKowYbOMvIH!i4;2T|5b+*}
zIH;Lmz~9mcDpxyCLffgJNYVfeQz<xh9st*JFKj+AGrauu4K$GlDs_A{AVp_5tkm)7
zb`#*Af5-zm`|QHM?T~-B&Ox7Ue+|EGm4p7>CI>-c-~!Y|^N{Dkx6I(<NY;RtGI}0-
z2P$-sOVGY=(D=Ywf`))%16G1Urn6sM+zW{o&=MxBC8!8;391M7OPGKMxFYfw_{1;Z
z#PNw=fa?>#KmbP?zs8ME{E-}=_#<z9;*UA~iC>WO6Mv-8C;mu=Py7*wKJg1Wa)8$^
zJ9Zv_nGIeIf-vhdzkn0VXMO=LevKQS`6D?#^9uxk4h*>UnLp<AXMRD>&-{@>pZOyh
zKJ!N$`phrr$ntXj*Z=<=;Sm5D7xd`N0qxU2@Z#V*W`>vbU;qDy?5u^5u=6X9G#DQ6
z=sf4yd8NUIjiK`}Wc&lXT&MX5Tj{GEpo<=MgYKYcuwhdul?2^f+v~#i?==@_;Jl%N
zQK6I-bY{iJ7mE%sF?1ev>}F8`9p`W0)64qe3@d{p=*k)Jio&0}Tp+zwjThqJ48U3g
zIuEq-7pN1q7Nq&*i?9Pspu^rFH+6u{rGU=|wH_#$3$hV>{Lh356M{XO-#CD;?gUM7
zD1a_U2i*jq@FF-KbZpKI@coI_;Ok@I_oZT0&kVZcyOVhJ$qA&HfB7Y-MNYi=!VgGO
z&-@;%dQi}uxcTt5C3HLzXLvonfmJ_F^^32OrvC5?($qi3?jMilHyIE=9k}`H_KPac
zyEkuJfQGUUgRY1GEi=&oB?JdhLI}8BqvG&l)f-TDc2Us)C56|Qz@u=8@kpHhyX;O{
z{4Vw)P5osO(;KrBY34r$T?R}-dS=!m&3s|deZ(Y~pKL^$`G-k#&tnqZV@+cG8rzZP
zeq|4w>H|Ot_%tY)8i10i1L&^dlc1S7$Ze#c>o`>5q2+KJRC)zOBjsNr^o!nu<u>y4
zrv|`WPoDm#4mkAR)&lwV>HP<HZ+tt#bn{^e)6ECBEj>C<Ao&k#`JDU^<|6}eh&X_*
zOK||-cZF5GFp2pk817=?%wLSXynJ~&oS9()qI`Kd+XR*G{1BDjjK)uXgeuRCD*uUJ
zfcM5xR)#eGkb|K4;Fr-CnNaMD22E=r+0XqLRo?nC3LkWS`X~Ot6KVW<C#yKq_%#lK
z4u3rS!sICv=!(Y^uit=HIUt#*jOw13-j1m5{cVcM&$dS8&qmWf8I50z#@7bj?}}u<
zHt2RnB)+vis`=ecsQlTMsQlH=sQhj{RQ~FlDB<&Rw;QT_w=D|aqxp?Qng@T~DG+f0
zL>vSkZgB9GLL+EKs{u43ThDpH<KP3(-qX$#;63#&DxfB!iwcKF^AQP@`-NX--$k|G
z+YZIPm&^}P`KvFXs<#e9mFG4_<#(f|Pf+}S=8rn?;`cpfhEM!a2f)#f2w%AT>HGNQ
zld<dn%rC%eahR0>l3X1aUPgnai4o?%>^_U?{^|#)e6;ipaZlh0P;%vfr`BzcnHcyr
zPP~3M;pOYwsQQ1S@*(=84!j69#_FG!tI^U+wI*u#RjZ=%yV25Tw-&1WX*E>-Yh6^n
zvjZwW+8mXijh4SwYoo|R{c{o=hwra3A;lrMrGqN(jO=Hy{L9}~=;leJ@z)(n<F7l>
z_z1K(Ock^)j`KpNiwe(YegPL19&nn4?WcVijU#*~TO-?rn7?d(qXBlS^<Av;FIS_M
zXP@~aSvd}}GQiHC0rCGFK=48Sd-30nnE@p6`~WNH#zqaK^MXObR}Qc;yu57A%m7+1
z+5E->bjF(jzurN9jSp2!CBFO`$I|%UUjiMs#;<p%oS$FsLa{ICBrfprM2A5sc-jG0
z2LAAaV24W?LLC006Kre5F@#cnc~DQxGzFwu14$gD?=!z3=w_@t22kCgeEpeUz(+;r
zGk?Uv*Zt7-J04`Y@7sQ``(DVIGBdpRXbTCAoBLTo&Oveq)O|NVs!`nscH09JW`-A=
zp}J>-bz`^>)Lu>i1)u`IW{rx03%{m|ih~QkrjJShzs5(O&ciPJ8V6o1vjAPK_x_{{
zzs3oEy^o;FgQtR4WbteK;MY6&nLp;oXa2Z<RY|1@F8mrNK^JCwfUI-jKXi`Kg+KHJ
zzuwO(rjlalQE|s#l%0YkY>-ZVJzM$xtPJI)pI!I`xj})i06GQFz=dA}>=X?jl>m?C
zBMFf90l(fk{^^JK^-l0lKVWgFWZ7r_h-07mV{EVNV`Tuj?)8+<{DRD{cfiu~XBYms
zW1k)Q51nA-*Ek4@`*r(R8TdmFzMcTiFQ54%SZC~GWq92P*<bgGKN8G`rB4ul!alV0
z`5l}WB3bMAVWdxx`htC|3@@EcP}64`zurO6v}P4ki9hJBWl$0YogSA4N~4l#phOxB
z@;oGw!u!Xd_JPJeQ2QYK;EQ}cW`-A4V9Sw{=_mdO(?5GbYLF8F%s+xYDjF|LK{_44
zIt6@GG(Lfn=tNLU0G>XP+!u|*eaSf7*8#RW{NRiKhRh5vZdrkHL?mm{URKbM2ugBw
z0Ew7pfYqb86<(fv0%a?W7h6FlO@Nvt0X7Nd?w4iYnN{fiNIdB`4U&M<z$ti%DI^7h
zc%a4+I1PgiWlMA9*Z2YQ{3rgHAD=*}IHoiTr0V1+aPkGMOWMDOl_3q3j?*9sIV+7{
z<M@k>$3clW2Bg_`=^j>w^5Rc~QgGUYG)MwYgQws%pZFt=ed3R?4T4yrapLvNPoN~c
z9h^Qtfzt0MaQX!`=0M585TuYFl7d0u$ttmjmEm<WB)&mikrTIdRrjzm+&g*O@-R9d
z6kb@{*S{^nE&Q9WK;7zlCt+=JZ0c{my?639s8?fe4AukE0aFjYKM>NR2Xzci-hNrd
zR8n>G07(6fhd1BdJbC+Nxzx>*_g@y5z`FX;aiGouWWB=On|E*CeBjX=qY~iJTLL-4
z5;On=I;;}3EGI`7WaTH&wTn3_0pI}vN07_AT~rKigG6#v6z&~_3?W3v9iDLa=FPYF
z4&Jr|4Jm;5H$g5pKs8?hyln6$*f1VU^B-C;Gl16YDnQLQ0Ga>N8MF;bo&l?WYq9#b
zf*k+$=wtXd5b7QSa9jo4J9!(`&v$R$U_H8%l>zQ)LVni3wBxNg)XzwEK>TeDTBU?&
z?}dRbxCD)=f)X0I4_pA+KLj2_?>q-i0-&C70ysnpKw~;!RstwJyy!P#X1ER6<bLzr
z%>y8R+<tlYCMZ3Dsu<AWXEzVrcyi;@&BHg(-hO-cE`Jy3*Z}_4X$%YuckkRhdGplG
z(>D*_Jbn8$f7@pU28P!HP_Z*NPeby<%_BEY-F|iVRuvzA3uqbT-5Ymr-@Wmg145@w
z07d%U5S0j!%RYgcLlG}-9tP!W(5l0`E-Ii%H@NZeCTsN$Rt8YAy$c%hb11L$=)7^;
z?zXi@;}MYWAxYSUf#K%i+pqbjAG-e*TtD%*<oy5t|K^z+hi;y^p=tm&0_^59H&4F=
ztq_@T_XY^wJaF3%WFV4p(DuXKoA-X+e^oy5?#-L;Za%nq@^$;olQ&qOZ3j69yfpRh
zZLpU?lBaK;x_R;?7bt=tgTWIfOfWpq`0zjI2Hq*4qm>;P3=edkN^5+?P?Og9i=n23
z33TRi<HP^V3=I5JLF*X}52S%Kq&5CzsNtV-;4qjEQVrryJ#d(R|G|Tx3mjneE2zDO
zVq#rd<In%q{4LE43=H27f($OTPCNLLzvX0!G00Ax-X?}C|NocEf;cST*_blHw1cm>
zz)b$_r<z|fU48)WwSej;kSdMdCWagT|Chf4aiCi6p=x1-YMJmNnumd52SXibrREWh
z!xLU;gZVWue&-30?;Fxo|JQR~IGi@Yqxp@6W9Ny^6KRf(4;X6F92<Wy)RZJTc3wac
z@JO?~SfcFMdBKtMM4IFG1OMwwL_1G_OeysR8`$f_2rjQX52ZCe`d<%nX-%n0r;Cct
zi<R6A4BalEBhrsp9R7X?6eJ}ZUTo$@xYGhr{-w2^tl&<wyjaiO>&W<e<Ak)<OBJlW
zj{jdTgP3c1sOaPCCy4w9au+Y>MZ*JW-w*z;2gMjT9O3I*L5^goNwa0BDN*UXkfsV{
zTY&T_qv(U=7sCUPNGrJnx&XrgvOXHA{cU&v>Vtg{c~JcGZ@<L9{p5>@kh6%VfL6>R
z;;;2&1s}*0mWBt?EHCm;I&c`olK>^K2L7oB(^@a_Pd&hSf`1z%eL_>;qyO~~_0vH~
z5XpWd|Ck{8M*<XX#)bz#W{W{|P68Ro0C(>_h<oAwI|Si_G)QB245$oaz~UZ$d8GU5
zIxp~VzsSG+#LHwzeE@O?Kg0pkz^;-14Dv8IQYycon>HB~8YlUu8~~-42L36B__tkB
zyl@z4ya^P(NPb3+Lv?7lcS6E_Dm>ibe!K*Z23Qc3K6-t20?fUymqFqiw7;PFjX~$R
z&J&H#Ks`fM28M?EgYN`v|NpOdFLSU3ars-HGB7YSKK%c`o}ssmp@xB>B>Uh?-rhzK
zGp+F;BRGNayBuWv-~l;%9G?Dc85kHW$~=2Ph2)9O6O9l5+cPkzf(+`s<<i^0Ai%(I
z@D*?4PY}bA-}S)37rebP0%?uE8EW`j)`PYQuoxrEbYK7-fo)Wl198j27vkWF!`__?
z3=IrB>p=5Rhcypge$@PmvGrGJ+Rj3d$Pdk%mtS-q?41Cz1L6RPef+M64!+<;cC!P+
z3((;|5I@4K1=;n#9<=1J`2YX^;4J-&9g?NNW%vuwS&FYGL&EdLZgvKSmyk1?LF)n2
z`0Eb7oDSM72RXk78s4xSY#-`9cR)5}zIOm^<LNx*aqyjihvK2eXABLX(?1TC*@4c1
zYgGj;$p$Yr{{NpJ8VMeX7fY%<4!+dF7ZEU<80<YP50wRjPSb<f2wGVNVg2W4@K8MA
zqj=C0ynqk1PTjAUhr#3ED=i<(gP#1Zpdm0VM6`g;Sm{MX3v9P!JlLgeeV}!k2!lH>
zLrrB6VDL~p=yCA12{_KYdTkhYO0zI9Xx{X={Kx~eL#Xu^e`^f`1H;ab%%Gz$e?YfU
zvP0CofF9riTI#BJ$fuWu!^85FC%@|fkAp9?5Rv%8ij4slKG3uXHRnGl5<OZk^0zp_
z;!%zb8jqmEt-<B@3vM<BhL=^4E`|#O!;9Cf3=A*%;C%3i;7c>mnI&NLou?e3RSN(1
zO9vkbKx&N=T}VYzDhR1t4?g7WZQ%lCrNf}wm4Tu0Aj1Jh29Pj|;OE1jVu88yLdjRg
zli!ZAl&UbE1Z{8oc9f;$D|lg^i{^oY55yZE{$plfV7zefAur>J!=R|Lc>Nkwe}M|$
z5~!EJLpnO3+qoe(DS+Fj9*&(C`M00+={)wr2eiqPfBQ*rGPeK!|39d8W&>KE10KB4
zfarhm^!@+;pe;6O{B?(4-1z<ff9K7#PPP~4z)NgECr!ip$BvyR96L{fecj;7za4b*
zlR=te<3om;5|=bbP%ENT1`-Cag!rM}<KROrAI5_oj3*9HfCPsJC_MNXKoVZPER0C!
zDT9N?r}IF`Ye?AWg2Lt?BP47-fL8Z_)^a>Bfdr06=P6Hc%6+8e(aXYh7-lDf{p)*>
z{0R#$7w}?G7f@GN0JN37`H00~P@@S{-hxI6MAn1GI8X5F@k*^{WhmnXjcI&Y2kY)b
z2GkDlYe2`;8h?S}wqCjQQmNi?7Zn-MA{lUa%JA#)?p(*pP!(Pp3K96sA9DgW&dDzi
zx<;e(5NKq%p&nvLiEZOAQ1MtV%&&3cGk@d>@IaFcL^E{I&PRpk^>&DVKyHm#$I9?}
zIfM_^6mbG{KpwdM0{I8jX-ruM8XpJ&b$xj=*0C~_iGez{ZU`Si`_tg`4I&PKPWT14
zj6m0W{QqAMzP96ieVwdpZwCW|Ktme8#tBExizU3D_+w6h`ljH@#*y<vsWrH^11+io
zjf(rIfL2Xh{KOv#+RGE7BJqh|AVftXjbHCn)sfOepZEoQR3u*Sg0^=-ckUiy<aasP
zd9d*z1H*^<#-AXv#Jmx-o{FJf1Z3?e{>T&HfdY_OJ}MHOm%zjEoEMPnd<nWG0o32t
zIPr-;;>61^Nc{{74^UU-#LWXYAKuo@T?=YR-+y`cMw#f{8#h@6*FyVEu=~`&y%mA(
z5EY5ei;%S1_!HcoZUOZ{UNhaj0qN7;y;<c_>eTS8{<w>Z2q^lGyMQ;!gLWB8+|E%E
zxOw2l$=fz6w{=uNUEsSntJq6f@7}nrqjK*dxVNeS$*-WzdII1}$XXA8Zh;Xf6$Y(;
z7jf-%VswQFiIiAD+yFAR#IN;a=^ljPcW=C2=hE$>BI3gB0<sixMa1h_u=aYd7h~fi
zhKB$DA)etp)p@ZqL`4F^d%b+ZjRP;UA%z{JKmOAC80z@@>*FZn%b@WABIYlr9)r#H
zq0K*n;$x>Q0|Ud0MHiSDIuCUobld?tTHxR-rshYC%?~*o`CU&yuK(aX)p@Y_p#VsL
z^HlQ##+{%oEc~tqIWK@y9whyP+@tVf8MsN*dANiNV)n7~Obnejz!y(}SB)Ur&*1xT
zUb0;P&5nWUYp|g&znzEkLHn>@K11+98xCJy15L_-ii-)MpbEY5jRvU3>a7v{@6q|p
zqw}#x=PwV<Qy$H~`0LAkdLtP<dh;25dISIaSl%yk^|8F^%D;`<x7YbUe>3RVFh~Av
z!T%jCF4hRW1l`Nw$iFQB#I5BAouSn0@V_H~$;a|S>2uHK!;G#S9G;f1OLu!%e&%lx
z1~m%0tABWOdw=j~el38owyx9T;xGPfj2?`qT==&!xmX;4-1Oqo!Pvp%!oQ8*#o|OA
zk7MTnmkutM4t9_d{%wqoAZ4I!Egg(5U}gUQJ$l{$yL7n!_v}37(!uqb*|+nQEC04A
zM&Dj9Mpui&HSa--clfsnxL6#j|Ke$Ru$aT8L&C8`@bxwRZSMblK)T}pduX0=>;N4r
z<fD1Q!}3tAlP73XXlFHtNAqC;pHA-&KAqQJo&X)f*LefvNl(kyt{oiwt(U;N_W%F?
z4|1`q#R>j?(7jyXrnW~Xw@+s<hi9)RBgl}KUEp(44uD%;;60w87y<3>LW^&t`10y4
zIrPJ$^QlMYbI>Mq%?lpQKkDm?e0qa8d@QdOd4TJ8-)<=%%S&$j+ju1To2@}tigY{u
z@aeqZX2ru;!}D6)r`zENh+WI;(fon~bb^M5<)NaNpyT^}IwgE8uNCk0uzb(o0y>$&
zqr3cvM|b!KkLLFR2pjAAJP!U~@#z&g<k8LK+s)+DE5it~kI~hFyN=hVlgSf=4uF!3
zM>m^`1rK8_pJykNPbZsiHxpQ)2SgL5dY|sNA0EAKKYTjfe)x7ud3Ig~Mc`%6?r09*
z-e3+F3m!>u1akOvGq_psFxG$ev^-SI;n6AK+sX9$sz*0S+Xau#xF4RH7d#LCVD{`}
z^632FqY1vV#nbXYtpv!U9-ZYJ9?i!Ed^*EF_;lWT2|fd&Q{1OBp2M>@2rTt-7I^pH
z1(0$d%WFQJ68y~zL9u%uw4v^RN8=H~@#R5j{whMvU&YkTUu~e9l#ugR8P@#OMpFJN
zLdsv|w9jAd6z8v(-k`fa5ala1^IH*8ek-O)ek;S8-->bOH#GG`<Tr4H!tz`B;LC65
z@dv5i6u{M6OyECoS@{ffu8HOekLDlp^(8*No=iTLr;EHG^{<cRNmu^ujQq_Zpq0b?
z+XMgkfX3D=FVyhAmg1LZ;NKqbFU`^N0=T?nO6v?@@~}JzDlZQ*rMYx6_*kAU-s55U
zkH5tfT(`yj@aXpY;L-d}0AXickH^6uOdh==j{MshUHG>%rMXxhfE-c+x=}8zlgWjD
zJ9nCk<%v2z$Ib(3E}dLyE}hK$+d<-tX^tSp=NT9n(mEN_T)>LG|9SK}gKnyG{^!|w
z3Z&sR7qmSJuJ5)-G5Pj-F{Qa$9<F)k(fopmf4e}Mi{&9ud3mrHWV%F}W2fNjOZ?lN
z|M`GTi2es^09^c)=Ge&yI#65l1n6>H%R{x=p3MiDJUZhzJerRQ_;mVx@aeq#5_Hxw
z*wL<*C;0n8*8qZ>uO6LzKAmBpN{$Jn`X%TT8=uY-AQOBnPlLjXzquP!ik^bjexPnF
zxb_1@80g>w<n{^n`mO|4-$Bl2hShi5c_R6neGv6snwvF`V-4?X2~dRx=73`mUgNz0
zm+X)lZ#THc18u3qQR9Ik5UIv<;omOf=*GXD$1%;-@^l@KPbZUW=S@hp=h4lU=3>d?
zh*IZm=W+Dt2F0cf79ChJAupml^6i9Ie;{)s!SM;ok7;g}JdX9BkSoB;<W_)lLED|s
zD!@+63UC4_>MmfZ0FlNQsh0nWQ1c(S{G?|7YXcn;gqHuxaOJ-?vh!aNa{dFApVZHP
z?SnS|6(Q$8a17EQ|CM3Qe<*bzTK+@TL0bL;$0t1hl@IRxH}MZz{byfa;M42L0;>Pq
z5cOX-BY(32sQT*;{NvMk!qM_VjlgRuh<tazA5iVb<I((rr89s9RQbK}Y(B^Wt@{pu
z>pn=o4olr<UpE1KTVk(BV>hEqHxszx18tXf>16C=a_Qy<ReIc@Ze1srODA(TlS?-v
zxV{6O(bLHYs_nYH|9JE||8ePb{sZdMbwc}e-BB#Qy<RM!8twzgZQTN(`t2*EN7pF<
zs@-mMJO2T7=sKhSfa<n`znBnp8>m9IJXEU*@(Oz820FshrJEaEwWa+3{~tVUiKyCG
zz*XByaPbJL+CZV{(#gQzyb)A9f=<VD>^$(&<^TWxC^Z|jekQYh+08Q(wL53c(+H~F
zCV;9pH*20o)Y=WRKPL`uo|F^OpL6M!X>{x6X~b5wxmbd1LiFakc^W|#Tel3RYAo4`
zjbEMtsXlYD<e7=+&ROy_f|@5(=+3RjQk%^NM;A(WZV@QDK=-kNqY0@y=fZ%iJ|jCn
z6`|#)Vk+jRHnjXyh9y6>k&vH?5c#Q`+WDz{Fy|*wZ3WLysI?W9@)K&s0~#H%<Y_GC
z#gU&-RTGz=5ZyIPo<>k}V|eDL(fVn$ej2TxK+`rT{jJgZiNf~YX#IpblmTk*jo|v}
z;t#a`6L`AClLOR$@__V@d@N7;g8EOO+qylw1Al;qyDTph3BHzr$a{1L{P48A0BKHm
zbOvyMdQh)Cn-6mMKt>PufqPK$;O04&9#lPKy2Ybc<e*14qfa-JkL3aWw$<SCZWui}
znS8preJoFu@pyI~@ag380Ubro<kQUvI%2x*5NKsfC!-HYmG=*iUgsY^oz6czJ5Tv^
za=qq+xX-uqly7$whi|VJhp**faNCc=qg%ko@(^_R-ltOnbj|X0k8Y6mQ$C&1KOns+
zW>5G?;lUrwplLEtZ;AuGH+2Bi^6uvLwLHP!4!SM=WdV3418krWJgoQ<(mV(Cra)oq
z1L{pJhBePUI}g0HLGMk$_ZyJcpYrSGxrx%B^0VeS2yg#^IFJa#JwHZ#f6Av<=Ad6U
z&p}^HZg7hZGEV5*&F#_6=3~io5Gj9wltCuPFjW(7|M^(*+=RFP{49A64#xH$+WDgv
zpldY2S1tSWmZ%8$^yYvD;7e3Ed^%rvK!)u3`#~$EJ$fUVJT31QyT1gTNsAaCO>+dT
z3+8V*0y?D<bo_4z=;i^?DoFuX!vkrKmKPoQCmnEYJy4qO(R>&*X3ybidAF#>!}2C*
z0NbPUM)7mk&QmU(=UfeMr#V7a8bABb?9zE2bhZ`5c#qB-uKcd|(;A=uuLn&Cpslv$
zZv}7h04+4-Zvm}FaBaO^G7&WH4x2AHg=BYei;s1Q3I~4+=%`EI?z|tK-F_cDo8Ji_
zdAW}llt~W$VDjl@0nHk?@^9w=uha#tZ2kpWY8VSTU9|HQ)Wy(1&|_g>NCO9g6^PY(
zph5)XD;Ll?UDFS{w%+D%bzo*-aOu3{0$K$2i=oDqe|snce@h|Qw2P31P>^L%{4Jox
zZfT&CDm&Dnrm46Zo=kJJJmknf>7Z-t$r6z?*G_>n$4*xUNB->$PzUmFmvrpBiE30a
zGXn!?$!HCKiw}s|dVs&<3z%`cLfF;tQX1%#{^^H6mbI3H&N1q|*m>BIf4l3yG{?@^
ze~z7ZJbOd`d32slb8LL_pE=F3lcDnlXf<<Mr;7^PYg<Hm===a%GtA$z0d&&|=%9Mg
z>3M0bw=0}L3tjK=Pdd<gpu`MP{&{r%h4|N_x0Z>2dnr@t-Za<NCnehv29@4U`+n>{
zbIBFZ`fmR1PXBy*o&Gs?9zqTK$)Fh;@B%XamY*PY>uvrH&>^vDtp_Uj!G65q$Pe~o
zX^oHNasFnoj?SWgX`Spoorhi)ftImMNCTax8U#9O5)_Y}#voSfr3zWFBO4s}ryfmf
zz2pcwGL-X$EC03wFBSiS4qO4R{{CN|=3;r=k$*a9^8LU|_P_uCPe@z&pP9b}wAdGH
zLQM%D$SyOGUEuWsAkXr*f>!;5#N{BX?OgwPbb@ArN@0^iAQ!#>UGaMne9LbyJE*#9
zKF;LZnaAM?y6~a1?t^FN+m~*C{{M%VC<U^i^)`R!U(nLS)&mu3pf$1$j{H*(r?nn%
z<ez%TmGhP>|F%mnUxO6D_fvs`n!j}_NU-%Af2S*$ahtybbSz?8<39$F5eL#*Z}U$*
z;KB)7Li|!6qy)BJ2pTWopa@Z61BW=smR69W?}tHw0Xp&%6fB*$IuG-=g6_}gyzICW
zyfnCzG0m}4;$;&k)WHEa^UwePuBh3p#5~QVlM|E#U+(+^x_6P!vonvwqt~Aa6cR6;
zL5mMRfYYY6iwYb6bg&z{K_)tama3N=1m`(W23+}{c^Al9{+5P6|NpymUIMMmuYu%~
z)`g&;bcB>CQ$c5OV#!w8pg=~Lvh)w=Mj41#UhV_whj<ut>>R|@78Z~Ws4wS$RDj*Y
z-<kmu2d6mDt!`<c{J9pCh(QUu0Ul?E9XW5i@^8ESawF(|H;Cg}c|gX1a&G5MkZ9|H
ziePZ535qCaTpx7h1T7&t`SLhe#qEl+G+S^)9!_h$jhq&K|Avm5g6aj(Y8b~D=#50K
zotGUu4}waS|Mh8(jgSA=gXZ2G`KKRr<==MlWgh6D&(711orj^4U==Qww;lPX9|k-5
z-!D);IqcYZ3zTn>47m(XBekHzSHm5{91(XIfZXBJTcaZ22U>gsx}}f<d_NO-?G1lF
zXvdF7ZxM&5<+oznm!MWznj>T>_)SoK1S$evgBY%@Co2TgTr5w6OHTf6CtX`lmZo_$
zALH=o)bO<YR#fcKtp_?KcDqcbW9RM8`;MJ=Kpp`V_s>D)UE`Dg^`MJ_&w$5!K~s-t
zsj{>!4HA_t;I+U|SAfsiMOx=`5MgC;ua9*Ns2bvBWnl2_F8|@#9sa?y`Mm&=|N0a_
z3vRoaAPatY4mp7)K0Uh)`M0waI(CAp%g5j?DB#8Kpc)C9`@n+WYN`%WbMSY7j<^FA
z!GebW(<~1=@J~P9`k%km6<qIJ?mX<-`N6Z>4ib1S{M$t;`CDdzYby8_5dM|}pb7(&
z&^pe5Sgp4!R16QKxmaH2pAIU}#XUPMeL;(i7{ShjyU(Xv$ccYDOJL`*w8m$k0R0E5
zKbb*BKtpLEhz*LXHDJbp3TcodZ$KOgDlnNGJ3sq&3U(g$?Y!XI9rmO1o@3|Tw8m%u
z>wP=jet7n}{qX3#n$}sO!j|UP`1C)sZ>QjEJ4pTF3Q4r!5CLsTYPk)nlt7m>b$kS|
zT5nhQq&b2vr<epTwOv6cuX=R;_32LKfCPs}Z!L!#|8|zd(#>hEt#3=#q8V9wF%7iA
zhq>e=sD1+9^ZA0qryH!t(-pm%0^MW)F_*tZ0OA11EvIR&tp_RuAx?o*AfQIm2GHep
z&5OX@jkF&=o%}BoKqUnz?(9HC8mNSq12JIbFR1xZp$#kR4}rLj{8JCQa$W@IQx=fg
z*8lu1X@CF!fB73!bU1?6a;CXjo`GlP`=H_uw!RnaH~tn6khPHbYLx)7U0dJsw}95U
zgIw4Y2RgUB+wF&E=MUe`G}!Vl4^X}J0aR~+)`D3c;P3qb>Jl{{=kV<;=kRPkF5uZ&
z|G~5K-Ai?_m7tM-kh!g(dxAi9Oy@IDwE+s5Ok^*C>aPQ?oEN|q@Kul!MEwPEZ)*ui
z6co*!k{}jBzV&uREO@a!sC+yKDgO?*a-IO2^$!$0p!Lh3n%o6keSuTO%L0%gkkWhx
z=*(W!Xf28J=rr=}WPG^;5}*(M*QdFFY9Dx80DRtXr?_WlK8HtdIN0kijX{MmxR(12
z(FV%Kt$ZLSKx|?L#S!TAR8VbMGRL#q&a?9aXovlFk;*iX635+;>MImnOJ0VSSkPF?
z1se*fz!E`6cNZfBTGK&nP+smd0kJ@t?>eNu`30^R4uL`+RKtT#FMTNoQUkJ(zqJ;`
z1f{wVFyjD!M<YmI<8KCN<LH0`|J380?;ZHJ{eNi(QUmf~s{<&>v>xE^tN?ks^>&2;
zs0M;Gr*0$ZNXJ<Lbsp`6bO6#CpZ>2;v-}Gx9>BJM!m;yi=W%fN07G^cs6B84TIZ;O
z>K)5N&_;p#@Bjb9!5dOR%U^tYLqOwqpyjweofjaTAN%@pkKRBQPs>ZiGOxWs`I}$w
z0DsqgaP#XB%V&N;4o}NVMTQ=h7eUALd30VVe*T$Xz~K+S-odgfpn1{H{DKbPS=$#L
z&2SCH=fTTyuYfLn=njT2$3<9M*9n@o1)cQh(JRsjGMZoSAb&e(eGS+FR*Vb`pyLS~
zL1zPkWI)#`fMq~u&V1$<-~{a#ZwKWze!T+@{Iieq>z#DupLN(#;WvLPXg>}}vBn9I
z5a<X@r$3&(PJcW*Pkwgf7xen`nO~6UH3ztT>f3n`q#%&Rx7U${U++};JAS=ORh+IZ
zw@aUZ!o#EU5X74T4E%Zr%Rhk3?b-;w%Hcq<&}V+Zpg$lp8D4LLl*c}uhrr%E<)eAP
z<KQn))y4#}!0C^N<spztsCxchP@(79e1HYCY!|d-*Qe9@gKy`lm+_#@QF<r&yF~y0
z|Nog^kPD;>bdV|tgZ<sc0b08c@i4#M$<O?Pj39NOV0Z~CvG_r{_x=Ox<^=imCFq(4
zhnD~Rt-7H3W=Dv2{w@j7OlI>7P&|Vpk-teEG%8{Qasjk_1g|Uh=J4$GU;#Pu<-xzu
z78EE+fmT$3LlMzGLTcN9raZB(vEuIsZHD#f_2TfcJXb9KIv5<N-xwJfAmdg7K9=W-
z?0mZgeJoG;be{O^#4o@zvG_6ACQ$nXB*4-LN`l9b7a2c6=q^44UUGE}l#a13GUo5A
zh4g?~e0o_R3yndiPqH+E%;xFDni_pNPxy56At`tXI>H!~UqD5RPd67#>I8rLJBXAc
z|LmiXlzGHe;SGN)=yq3-XEjcEb{=%(pLN8iI}Exa+3$yE=Vjkc0hATVpZNt?X7cNu
zD1Xhbcc6;ZwdG0aL(nagpe9#01IRvbIDn=3yOx2I<)LD3&(6pnpcTto(<TsJvc=y!
z8>FxK5C{6YWiL=V0Hq~RGtIY?!=sZ8bOL=h7sy%gkUGKNCIm@PAP@2Do%HBr^6lgR
zdHtm<M1sEylp1|HxjZ`=UV?5Ea&39b-)am>i=h2i;PlD}NsF)rJp4^Uproh?5=C1%
zwi%WLK?w}jh==XJLMiV+<Etp;U44C}M{gjgOe>as?F-7^X`txn`V2}a&4)NXK?^)1
z56g?7Gfu$;-Y0$m2hgDw2g@#jlG`VKK?m?C>vIo;j^cCR67LbN60g3l9n{DL9o`HY
zY6Y1MI%9*sJr2}H0=vNr%+fdrI+vOYBKaRw^?)T`GcYiG;uqiqpOewf1Xc<u_&^7n
zfr>eB$p^X>667P$rXY|Y$SkKHp1n>#JUdT*0+oF~K7q<U9{BjCZztHoKn~wtM-I>)
zr1H0Epc0TBR02Lqn*b^QK>L;$KyE634>F#=YYQmJSRN=A_{1+5^aErv!|N@e@I)^E
zAhvrP{KX6^?L90Hfz&}&!^=Mo^zzRi)D!_H3GV-(6O#qGK-!o-@e6=3Bm~<2K^1{K
z2?~Kv{DO?1_yxJZWgxh91vX*LKd=d$AWy#pjrf8KK@CvCvjf%GU`5QJG}inA6#3wY
z<!|BwB|SNi6%!EUA9!;H_(E*(f)0wxKhRzxSotUMIs_7?Tue9$z)zq8@FJ)HbYK9L
ze;_`~K~Qv*9R;OG*eLR2i~{fzC|%<y0BbM`z)$=FEC)e`^PB`3&fgvnO=tXF-e8u-
zK}Z>htmZ2`jXngm;=8%vk|+4v!2?zNdIvy-0VtY4B?P!21Xa->UxN}V?xK)2Z35DI
z9+2~Hf-*q)E09)5ad;n59D*!{1Pep~e;4SEQqTfcE?9xMk*M+zG!z6{zKdQST7gmo
zILUyjX5<19<TOOco#1a{ho&x&he00qK$M9hP$~W{&?;wWp|~7$0~DxG1Xs}D&Is6|
zH=v6`K&5>rC}|$zZ~6mjGmC%<X2||&546H@8rH%QQ9mQfM-R|7#*aNaAA|3a><wZ3
z;L~{tH1*Q>3smmZCwue;3V>RFW*(LoJvuMk)+!QsEr0W*NAn8-56gqMD+G!KZ)beC
z{j&V+?HBxA_ZS%%?%wcdJ_OQp+oJfCr{!(_mb>5;)4@MHyS+bnHoq1?v7&D7ZB37Z
zzgQs`ZJxTV1=<P7-|olAz;N^A?H5&iAd<h!32gFfrn@&CVM;((aDgOYN_as^Zi03n
z-qyVRlE3{91H_1%CqV_m?H3OGvyM3^{DX|f-Ms-3aJ-%M;pR!tUZ)S9ohNP{aJ*gh
z;pWNPR<8x`-UKao2jx+amwY=<INr_>xOvjI*F)g;%kqa{i^UyUzLh?DEpYe7Yo5C|
z5aA0cF9mLE+<sO57!)o`!6oIvVy>GfZ&!VAylwe<-Q61?uYfG~0nL?N@BrNadBWr1
zFBVW8;bD0Q<P^u-mbDR{%?AZMn-2^4b_W0O?ezZO+j;0^*uVe(Z@&QfY}T>YOgB&7
zw!C@ZwiU=rvyZ<76>T?9f`zRdZ(H5g0uO&eMZgMQZU^13-O26S=?q#(4>tZK(?8JF
z@&EZ-g8u*ifA<EGC-~bzW47RHK|%iJ@BaPw|Npx;!S~{T%6qi3kO5_M3sgqpXaTl^
z3Jd7YvPjS(`_3ESbZB|$whp6D=Y=BCyEk5&q)h-NDfm9JVntB#=i7PE^WZ}kr`tN5
zw_lduyZ?f}i;W2sQ?FS->Onady47qsxE1&lPa#-|S_pa~jP~v3@a;V1dGHa)B0)&X
z%t1?;37}+m1C%l$<sya#DX@n7FRC~|NkItQI^aT51xl+o;c3;8fA+E4FC6)29d%Xs
z3c2VVlvW|-<54V4MfS7_cW-)j-uCTI=J4!|=J4%&0KRSVwhkl6!R3!`p1l8}iqEy>
zZRyR|?BMqE-5a3mxIraKHv?)wJ_Q9N=!6Lm%frQ-zMV-wd^(w5FT8sL)Pw}z?};?-
z!3^H7cLP+fgSNe;gKlGn6_*~J@!)N5y#GKc1>zx47~OsWF9nai)B`89yP&|k0WV3B
zg8$`Zux^k(Xc0LFR82!lJCELA$S%57fB*k?ZTZIEst&5sK}S&Ce!<^;3Y0`|y!;HB
zpFmEZv5?VTl=Db~JsRJDlBrK`2&lCPDi6W^H_&dLdj5XUseV4ajvT(0hl<ic>D|W?
z++P#`_30v5d^!&l$-K4!9oEUpuXnr32vi+=bc4!AkIn#&VkJ;#`3Jw=q0jsR9)HTO
z^XpyUZ|ekgZuM?gv4XUn^K3rA@tI#xz}FIV!hHlw@mz4h*}=@f;M<K{a6-H6_56LH
zDL_z30qsA7PVw^u9iuM<u_%g#zb%}JfdOPZ*j1t)-Aw!%H~BR#cyxk#ilD0%yjVa!
zVB*)i0HVEE_}d<UopqAG>m{fo*3IP63F^2C3W2(xQ6S^Ngb>J5h&`Sx{B1WNnm~TJ
zT?Mh{0>8#hWP5zNnV=0&uuVTeq|+bYPNyHBPU~lWK_`~ig7Eez$kD2vofko>963CD
z135rW<QMQ_DSyJRcZk0YbUz|U5gRDHuTAjmJOB#w&-|eNIXIYE%A!H?&-nFjS3jKK
zVR@)H-lv<(x6=b;AH?gg=fUl(Vk(gV^{x0o&Ft=cP{YpxRJ-b3s(uTKZ+^Yg{B3?9
zVMS2wKY?HGLRkXH>SZ8H8bO;|7kYGqLQ233>NU^K3!a)MJUhYrVnMq^Jv1+Xyb8)J
zVDEw!PxM{}j}#u_@CEJKZ9XjE*%=J({@4Be|G$c<L;~R`OHkSdwHo-rjsiKT8YILB
zI@pR|??M$*i6p4W&d0BJiN6~(-SrZ5tvbKnf$Fyt`1Nk`x19mGAJoJEhhPu5Z+eoy
z%Mk3*+x%U8;IRS$MtHooYk;LL@V9}^9|5&Qx=lf5h(UzQboupe^LOn6-Fc^XlD~T+
zs8KQ<G_W_p6I8Q!b9nT6aeykWm+Sxh{|`F5Y$4dv1N>e6P)2tRNK+En2#^;{L0-@X
zdtoL>rV1n@&%m#DsEVn?78DxB;3!%PlAH{Z)H_gp0pz`Qe=zShe>dn_HLzoCL5e`L
zoS+~(0gA(Rh}>=dt{kxHll<MuAVr>F-X;ES&<qt=;d#(dEy!25|NQ^|a?c;+@s7h2
z97CWhLO_KEj=BxhpN8!s%LUbKmY2MGS#Eyj7ZCW&F90evE)>bVb_bWopi~6Tq!yrL
z?9=JN0ZOsjKHVNa{CZhH<5iG^?Z_|S!BTz^T!3_dGaa-5Ie}E)O$OI@DWJ`XI2!$+
zLm)s!hfgmLWYmMvr&r{lU#|?fRD&dAaLFJHN(+ws0?{n|Z5GId2|vFED2IdhVKahO
z1$B#g^|FA52N@ta)q{n<?HRHQ#e6#j!Mn2=y?R+dg;fNoG!XzVL=l153$+YX3_(jr
z{;pJzt>|{aMoU05B9}qaAiSWw2rfxYeL64ubSHE8^agYI^|Cw!l^|dzL4xi&IPL!h
zr@oU_93XAy_~jWqI}d{cz8j<mEx5~qK(TWdRFK?&%|C#;6aK!P$v=EMxnB3CO+YO_
zK*Q)Sjlr1&x%>ciX<y2~%MX8$<=a4JH+otgD%uFDV0}9;_#h@0(D#+|_kylO2gNk3
zk_GK8_vpO$vIU%eL3sqJ#0Uo!4@%&%7mzdbPM7t*6b5nS86fVxR0Sz4K;7t<N5Jkq
z04wiq^0(ar<@L2-VNiVq2{ZogTCm7%{_a$eJgBTpn*a_~P-701@46tx#%=y?@Hiq1
zSp9`EC6HYAWl(kl6&W6#;vUFb;SWNKh<RXp4)AwD3aA78-3vfkdO+n0e0~E`9>jwR
zi%@WR@B*af3P=q&KS7F4nEz&gBx}Jz1oEHWP5yS!9fzRO3sU~XfaOl|cP|8~>;>}<
zR4)S+1mIEDm*8RuRIY+5U9hk|C~&`{6bo_jv5qm2^GeYASD?`+aJ#lQ2Gqa0h3H@L
z_k+5bkUrMsqH<XJf($$fec~60;_&FaP^9+S3)FwCVoL)h8aq(u%cq;eryIP`&!^Kv
zz^5}nqF4<yM)lznzkmm5pz2Wh8PNH;{B7sKy>`9ZVBIIH4uN`SpZEm@JS{JO;unnI
zD4qx&wfX}(HmExqX`CL}oqZADHu5i4@Zi<KM=YQC1w1)C7*BoT7l61EbYw4o8{`gP
zy^~<eZdb|sbaVN12Z7GIxtYeValxmP)2A~KG{^$Fy3C6MG&sZzBD_JvP8ayw)R-7R
zLrf?6y9}5>Z69vm?qCk^n!_NFVnJchFi<pTBq|C-fUIT&I|X9B1XMew^%v6kHEyC?
z@6*lY+3O7I`GFh>cE<-0=?v{>1%n34xIXa<I&pxOGU}bI((vpA4Ri@O2zd5ZfUZIE
z2Rpp{5yXDb{%mke@q%OO5_CTnv@7+AUjQ_I=K<1ks4NSt@Cis^^*s;E<HaTL_J~h6
zzfX5Khfk;12cOO$kR#YX@eBHMysSgyU-0M$KZxY-1`UwDd<IVbdY7tSgU-`E&ELij
z%AglO?O#wrD9Z!cR5cA`D}PrOC^{{V7fto(X7}h02ZgPGH`MQ*ouD8I{^8Sk1AKN0
z$bNoMnmzb~<rBZ4I|sOvYI%si_X)W90y^U&8ay!O(OLb$xAX8z2}tur8sxevs2f3R
zbzXi36@Q@W_;ngM8)bsB(LIPDsQw4(xCGX5iNE_8$o)MK$ph6O9XI*g=79vuA%cha
z+onSXo=)<2eS&!ZHh<T#zo79x&;@w{p5UP7ZwHkRpg`bn15G-BgP{9AD6?M$=>mn<
zg)%)*`0#gSf<(Y&RXj+6H7NYR<A2Ve<u?N0`40<dVFl_af&9qd1*+}AtZq$^E>?&k
zATL>fM^be_B!9OrNKy?V2`a8#Kzgb`N)GUM=Yb@>Ad&~F&!vHzH9tYKi{PS45F&Gu
zzxyeuO~M4>UaCF>4$5|@^lknwsQD-PyJbKo{(zWpiN70k*DFMEDn#rge|HtgtN^rv
z3{r|A#xqdbJAS<(pc7)?oh0Zg6-Yq_TBY)-sLG?;&ZF}OsLb<VJmF#a=@Y*ID6>R>
zE-5aOe(eW}0caj|0@u9ICXXqo$>ZC30@Q)^WIO@NiwqzFl4Z(42X$TGZ##!tqV0pM
zH?i=v{8Zcq?l;|p_nU&D15Ot_ASc=ILkqGWEFRrfp!SbvH=}3g52$?}oyS17F?bw&
z#sXq^aCk7D`@}B*Iu<Mrl9bvepcXNLpkfVFws?RJq_Onq{NdSc1X^fv@Bs^k4=(Vx
zsX(;DN@F?CPD9XIU63n4$Hc+(M1XUofCp}~4)M2bg@yxv*J`k-8sI_>><~i_&{~(G
zAHLvGe<#q=5zkJ;*P@X5Nl;1$2mi?`7mv=bpk*K)y`>yJoe!W<hFnrzD8B$H+(4)G
zfFn)-tp6AyefV@9_iTQ_;oHsO(|H1m5r@ir!5XiFG*(}n;A45LILxOr{fAE{-%C(8
zri!Tql=TmQv;G18ZY@wQe+*0EpsatIzl{?lcn*{wL0P#h3S?N-7LdXGU7+<yK9<Ld
zR(W=Vra3-<MlPVo^LTW!fjjdbKwU3zuM0GN3`#SIURUu4&(2pbbwM>h=)5bCf6<);
z8jc0GpFlYoTpFF`Zv%}Sy#%$NpsL|z*DH`)L1+1ZGB{ZEP5!q1AVFw>c7eYQbXFSJ
z_1!^`^6WN$w>d}&=ni<06ZqS}t2aS~5u$kO29;$mkAlJm-W~#nhcd)0P($ZsBIq{S
zPGQf^Yz~j!Fi0oNA6jUEm)wC`O<gk~h35hOZVymFVFWT0+<pRCUd2?B3-W4JBFGE;
z-RnR~KusxraQhJyU2xxqg5)6D^<X7+yAs$qz1#fVW*})^aNt75Qz0$|HM?HAK~x>6
zo(V3Q+Q2<mLx|ud{_a@FIQeP*Ht+~!KUzTrX>l=t#&1AtjzOc@y)h~Z9tR(=`t*h{
zKJe_kjTmeObw~PjK*Mjnjtah(hxnVmgBqLi4h*0PP0NEGoh&Mz-3}Zcoh~XIp4|=t
zAclZvw}S+TA;I6=%gVrTTSvvG^8o0Ox!2b4`ugsT`!A|kZojCC@MwOa03Z5M@Bp>Y
zIs-I3x&s6}Is*(mx&tIUIs+_<?QUm0xSjFg=E>Wy%MU?L>iz*5y}W(%BxwBdCTQSW
z0X%L88YjN-S_yO>_G=kf`w-0I1Ce)cyk-N9cY+4!L{vPR4}d)8(JA239iqYk8hrvW
zKz4&gK$c7JH-pxFgUiV$;8l6Z<4drye^6NUT>%ZY9sI@SaqtnV2ji*RTDP+VZfoAo
z6acxKzfGG3GQM6Vbn_HwWD|7N^4%MEZ{0lkTIBBSyEk9+-Mw}9#?6zj*&sCNHquT;
zk8URpk4{Gpk8URck4{Gck8URkk4{Gk(D?PulQ$3Ct`cwr-Jg{uaP#!-m;7xDm>C%E
z-UNpT$IVmsUsRcZ%zMpr_m(Gkc*+xOo)d>B*gPizPq2AT5{|d69B)?%fF1o>?B>bW
zLWuGT6v`lXB6)@ZWX)|*kn?x#1$zuMevaSCx2<kh3A`49#se3Ke$4_RL4E{{cy*ox
zr5vzVeL7iG9B*em011Ho?Az(|zz6Jh7ZnN5UZ)4XolY-&x}5|dGZMa?P9J=_og_d*
zWMF%4>!^TJodmx;C_F$R;Q;c-&68;pZl3h)yy$p4Q^B)0P~kQt<jQY>Mt}L+E`x`s
zZ=QP1hwOiFNXp!PQFY+87|6x11we818srC1{4s${1dXXF+|~e3dw|Z82eq}p@o)|l
z-__?p2dlqk0iE0qI*hk@6L<*wCiuMd*GxB0L&n=4_;h=5_;z}{@agsv@a^>Y;M46T
z0UC$9ZFTe1?J9wnphZ)l98kqnqH+60mFV4@uUYQi1i6pDTLn~bto-x;|IO34UsS)m
zdmBD}4N4i;{(z<_UUov{U-P$tW?62Ydd)uJ=1Gt<Kxq=RWDn$K{w`2Y805~TB<P?s
z*xR5Z@4<)7gX5-~2|8?d@CU1Br_%#aJbHFIy#S?ENVIr%I(-18Sm?kWs8s<{YYCcs
zsS@Dt4FgRxG#^p`4SRv+YhVL<WuO&d@bVhjzo4K3jaP$KM1Y+1viTp>zt3-;zIpOB
zE5AHwBJ34^n;O*NFBAWPhSN$cL9#bb^2;;aeo-X}I>8^59>D4P1%Eeap7JHA3I(O<
z>X$c9zUD<LuWp{a{ffWs3uuh|*3FYQPrlsw7i{Zm{x(pf7F4W&PtZRJa+)+q?&SR!
z{N1m>L4NnfODRwZjquM&P<((^p4`0wj=8Qye?aq7{N1xak#iD!D>}&2{B59BQ=sHi
zB>{;R&~k2Qp&<cIf<jP_fRf@3aCW-&^7U`f5_oRkPVkr_IB;L8`~qDTec&a_Z-~RI
zxcFN@3leUg28AeS8Ur+J4=Oo8(+41L#QgdH|E1QS|Nkd|)Pjx*hE9pS;O_#fy$vp{
zSYRP|?f3uxFQ@+osb?zDx&5L_7?ce8yFvRL?%uk4>!mit>KD~7!7;@R4_|QTwzK_)
zgaK&i7L->&ie6s+_5VM}|NPzQpi2-=-aPf1a{~0b0&tvw_7H$vaP#ELI*|F`a0m61
zZk~M24ed{Y+<E&IfBTPL5E~3Y3QxVf|LgyMaQzMPZ3#&1<V!1%`@!=cpb8RnU62a{
z12OG+&_q6D)%hp>CQzF2fVJsaA#Hka$>7oXp-2{#Y+u*IE5T6Y7JUe!MbGNVc*60v
z24o)f_UrO<kQC7mtN0M<6O{CBzo?P}CEcoxVB;0QB=o!(FdM!81Fv%jbprUC13?RQ
zK{L<l@CpvIBOnjz0v|-`2pB@TEFkYe8t_OC274A#?agO~R(pJ)c&t)^rd~mCmB$SZ
ze^5fcdD5fP$g|VZqx0WuWr)CQX;9jJEeg8d;?`@h`@yv%xXuI}a@lzR)N=7)JOQ!p
z6ew2-f-0t)V5@k*;h_WeJsXI;d&9Sr(X-RYvm4ajN7nnA?e0xb1qRy7iDv3aP+8u^
z#J~VDlfP>QDEPrHc+CY$)sQR)S?cT4dF-_m$jzYY6Y5VyzPtfyYePC1MUV~#<7*v=
z{~`4?7pN?#@&juI)hayj_RB3$=%DpGK;aJY_vza&%lANPugTEb>;8)>soO8APQ4bn
zc@lJ=$!i`^9)X#M-v2-t1@>$&188FS{)?*Xw_j9W1{DWBmdE&;SAv_rp!PnjD*_(=
zmv>;OVk@z^dHOX6?7kFm`Fis;2dG{G%?E*s!VXZ~Bm^oML3PtpSQZB5Q3e<XRK^;B
z%Get>PriHxno@wQ*8nB_vMP|O*K8p3AVnc)SRNF^{9QVr9TAqt_?y5*&5gS^Uh{&Y
z8(zME0^YL|e<w#4ToWBbnp%Q%awI?{^6A^JvDLRvLA?*q$u^*Z4x_#W9Tt7}#>;+C
z?ZZ@}eIHcmfT9&%V1h=3Z=QUq1YVl}u5!2_{Y_YT1sV$ml}!$yD(=+F``|7C=zbXR
zT{WPEI*>Hk2@2MeuQ@>F0JJ9W2K8$|*$CXXfg}!4eGjT|Kt_VP7dKD7yaO88m;er6
zW2jjm|AMQrHc;gSZjrtOEfx1f>mU99_5VMpVz>fo$ABvlPy+%~O@JyCkR9F-18%)k
z0+|U3!;srAs_bD39zqq|Jo$1r$RV)wS;bTmbN@w^FDOsmy$LcZ38eDI-5W2hAx6EZ
z-V3T8pzRw-{gDT)LnnfifLhqyU|qNF-gpVxY<2rZ^=43O2h<+CaT8otfQHvV3FYpM
zmybck|7nm_;06|CHOMRe_C#o<)DDtA1#T#vd}#_>kPe#9f-I&)nIA_Q&+d%@&5%C_
zpXhu8vVNS{{pvO7`_&=GNr8JQmIsSoK^CroPrD>%zj_~NXOs_UyEt^edL6d?>V1bm
zW0oZCSFZt`RRrCy4n5A9iu=|3X|P`%{k+nb*3>wE7VCa?`1xR<{p^qk^?@u?1D#)b
zhy%I^2XfvsS^L?+M_+=*$T|=B!uPY+BF-~H-OrAynz;S!@bkey``PQMbNno*6h&W_
z2RVR%jPt<=#V6W+_X=hP2G4E>3y;q09-U`>dei@VBu6Ot@UMUD(RuTQeFo_Av}2x(
zZ#-HL@V9udfUXs};nC~;-=p(Bc<}D~eGknWpj+lGK)qE5k6ss*01(T=v-2ouj8OB1
zhqa4}1AjZ{-Z7uv5?Kac%P&P);N?M|JUTzVIFioH;A8pKx7WtbxASAMl}GFC5>x(d
ze2)Cv#4RrJx6WZ=U@$!JS`t=1@^9l|bL8J9!VZ$G2i;}Te1Orz@^I-hPtY91C!fxf
zo{aZi<fb!&Y$~4SW1XYo!QYY(9_CH`;n|)0!L#|T0J7WKK!<=CUh??<+2i615B~Ls
zJv)zkGQRg{z0Kc}0@@JBzm1)LTPTC0#RdM>mk{>|Ir4AgVdvi#!pZ=0$TcK~Jay?j
z1d>(p=yp*72aAED#R>k_9EeU~kQ|FENV|*0N&eOdB&|<CS`2)8JsA17`7&6X;%{Yz
zXaZR$!p^_VhZQXP9$aCA{ayYP9G1U4IzRe!`lx95_L|td$WLQt@agtZ(eUj2?bG?e
zm+>bkIQh4M_E|A{G#_B}wLI_G;s3uQ;D6~;u${i0A3Qr>`t(*XdNSSw`+PqG1A`0y
zHZe#3ZGw&#ms~n8^0)dkf+Ir^6akE&m;gBuwD$&NCO8r%_%hyb>AdI&KGFUXe=BIA
zrQrea;f;{-JdiGsc5tx02Nkfe`17?qSRCrndfUHO#1gzJ`~-hXKB#pAx?Ba`p5fod
z0XmQ$Y+>^uMo-H_E*%d4JG}mvK83j4r`ttEgTEEDXT_KChOgzpqSas@dbHm5?R8;f
z^yxfNBF(=|z>$9&AIKEX=3|ULmIpdK{yTPr{V#nAUSj#cL-Umn<gEQX&t4Wu-_BGH
z|6UbI&*q~7o}I2AUMj%aBNi9=o16ZE`j@{zNw4$9i%%)c44{Q+jQ>3ufBIOS<!{me
zwf|zlIzZlTx&dlCfkxK&<w4Qe1UlOG<zdj|w>*O{<7v;%Tn5ix9ZBELSPqbdFE{`B
z|KH*we;a6rgMY6GzendQpUxj>A>m_r0Ui=BK?A?8od-b)tQj<P3l0IF&R?LU<<t4V
zzgL6@k9JUEc?p`xcIiB5amuGRM3%v$^M!BcPyRNLzd<R2e;WrR@D4KiSYB}K@Pwo#
zSN?76E}e&7{`vF&KPY$Sr7$yqdz7GZ2GUx9?w<x<aP%6KS6+h71@P^B=4yD`<G70o
z=m_TjFVn%H1?qo>qpT1G?SJ;{cC_&8tpUv}UG+)!PyiJ=-~m_;(6Fpe=MN9f7oe*M
z`1?W4M9^%7r{(veJfChg574&R$G-gQZ+bGG_OSd~>^s4uyZVP`=PzIW^%s3xPnOtt
zGJ@`BV0Pr+Cgfsqh`*Hwk^!Y*<&P`>HWrYq2otzCcni&mo|XqopMWL`d^(jqEx#8}
z^5`y6;qb6DQQ>cS2g>2yEGj<T6+b+>GeAuQ0W_EPff~%<bvE6(3?98DM;Sc2?R-1m
z`SP#-=-K%j<YM2}ll(0^nHU)SdQ~L7dSwhjxk$x@e;YH{of!~!3cK=e6Jc=yInov6
z{1A}c%?B94?(^+7_v!rX$-n-l2jgiM{%zWh7FS_K49L{i!VrxhBV0j+-3Mgfxpcnr
z=?-P^>AZ|Eff*bK%fZEhC*$eYpu$ar8EgvJRlNuU%Afdji}`k52KmLa+x>@UZ~PD6
z&hQ_epalQcqmvEN{`c)J<?!uI<?!wN1dS8^7Eu4hlkt=z|2AV#yf|1~<8K9R<ug10
zv5*NIDPRjB)67u+g8EAy&96B;x~-v63^7H>!QxtJs^Njxf@u@LT0ubxiqFzuaH6(6
zSo*@#@=kHEPp7eGr;Unl=hK&<Is#-K$ivOTpwVuS!JsQREbsC+Z38d6KgI!xeg5VN
zpd9}bd=kb7kdCHO@G!%jqO~Be`*c3??JWP{q4^55*Tu7wMa8G{hmYn1(5w^a+#*|#
zZWa~K<|7<FofRBDoeCb!2fzu&xAXl=S%jgG!@;Eg|Njq4#2}BpbOUo(R6II0d^$5g
zSyaHYHwQGl&!Y135on{X#RdMhV(?8NmpwXb8GJg$KoRmX3w!|jCD+aupk&hq@}N(r
znP;cHN4Fg`0Xp$-6Onug@zf=ds^&EyUw76r_;!Bw>D2S-e9ym4_$6prA2`c{vMNfJ
z_w4)yUO0|&{~ua=Bm>?aIq%VV&8Ii*zXvFXcb@h*_?pS5S7$EhjJX%f<Cz(J`PV=7
z=sf7j_y^oJiHEgKivRm|z6P~TJip%tw@pe^G(as915h#H0Ag8qK-(riz~|swyQmoO
zx8Gm@<t!6@Q1hhN@Bp|9`~W)nrCX$}Q=}1;E<hFB2OrDt{=F=6{LN25EsD-hp!SM&
zx1nRVfaRysFvA0{d0o0~8eO}28eA>Umj=T0y)rxi>aaO5bc-}Pc8WB?#6S2lzVo&G
zQrzodougvG-vT<A#-}^=hevnq2ao2r0xyF>C!lm*bnN^N$sewk=Zm!s4}iuF!1q%*
zc8fG18~EOr@s=;+4Ij(v{7s;(@tvPux4_yqp8V^NdNBR~`^^n>nnAZkx44VtFPF}L
z{H>t2lq)DtxOMY1xOI!PyINl4Z_NkqF*?BL18QNpc8jQh$~6ra%S#@eB`OO1tqn{J
z3}9XE-8?N$-6jo=mLJh{fpjSN^!hQnbep?ae&TPv#0b^n)-BTD)NRu42ogO6T1DIp
zwyFG?W9KE1sVpEBZk-~Hp5Qji!P58sy*4sn8K-WM2KR1}cDGKE2Io$Zc9@FipsG&6
zxAUhbsJ1I$^ksYn_AjUw1VxjO<u%975B#kx;4<sApkud4lS?;Cql@Js{#KOs2qe6H
z8E-mvesJs-1i2B^CIST!NP{CNCM_@Uw}LAfL?h-@u_ZY9l(h28gX*ttktWw}mPXf3
zmL^ANLh`gcR{9+3uvXC6t}o+FU&~WP$3bm21;Yd2+kIMZmq>yf=i1HE4%OTaN;N)~
zCrY3DbY23tV1I$Hl7Z|R29+F%-n}eZK9I(Wlt=SX0S{1Pg&$m*LfT)BmKXS&z^mUu
zBcEv#K>lvJ4r-8qHf5$wfTiyyP)!d>oczsiK*QltpmF>O-n}eRpn}7@*G3C!!H<{g
zz{kaWbL_n2VtI|f4K%tBj&;w@U!I)@Ub8uN3%GV0c{IOc1Z`mUY(B)|(fsefYiGe9
z$IhTXr4PCVUV^sJfnvS$r>o%sSIbl7d@n%@WhQ{qlvB4zyHlq~gHxvoIG#a?@p-p^
zW9Rjkpd~n+*IYX<x>%koO9fl%YIp#Y+Fo<GcZ;-ul8JMtNDC;Lz>^3>Ywlmr88^RP
zg39U_N28$)6;J_$QfhSz`gVSLY5V8@e@K(%woB))m!K9Mhz3n^fRZGr;R4$9`u`<p
z>?sZD{!z5@%>!J%Ia+vu+Ap4+*FBOQ6g)a@R6KfXR1`cqYg8ma1c%4L7oelIT0y0q
zN4JfNN9Qje&0ikPzv}t>LFbKm_U3c=bgQU%SiT1x)l$pg(fQ7!^S3Ae`WqgMr#&s-
z7Y9Pe|9!gie)x92_65nb9w@Q$WIXNCE$rIO?P__7zm*TvYPj@T8ZqDJ(k(LCwVP)$
zSQ^sLIK=2-d7<=~NApn*k4`&J%QwZnpn#U}uq*+c*YX|I#OSV3;Q(D$;nQ6Yy`Bjq
z&}pKA=K4O+)sdh@VZPn!p1n5LeLA0cbnAQaum9lD`5Nr})&t<%#7k5J_*+0r1U-69
zBz<~i1YNq#T)VYhEx+=&rbApU=+Z4R4enM*KMLm7ZW9%sZZn_GZ(ySt&$)E-xmv#D
zZ)E{%_32fSd=1quGsV^N7Jn<~@Dq<_sCM6Oai7j>aIJE#mZ$k!*MUlmOCF4;K{|OR
zyL8J;bG5w5-#QK4#sTXrf93<y32GqS@aZ;D@nAgd+xgeCJM4!~=QrQZupb`H?>Ia<
z#Sx91&(MhBZ&3!7e~hQQtzAK<(4XgT1uZ=`y!2WS<U??*fXZXgzFxR9LG2N+iQRgh
zkSO+KJPpxanr3+EwE(|716U^{K1)MkI$wEOekl$GSMWOE)(vQ}Dx|yv#e1_LxP9}E
z!v}PnmgRR?`vw;O{LP?I*O%YHO_5)qdZHcDzWD;`Yk}HJ4}CR%dLI1A?9m<m!>6<S
zhi9h<Bn>|Tw|Fcs*1CX_5C^1@qod-{S;yhgTPNVtsRmB};68z4C)n&J&|0*Y;Qb8p
z4h$aMdEiid37RVN03|!0PJ18FF(S>!1$=wKsjfza<K;2X5g?W~`I|v48&I3IQ{Sgk
z9F)RdCV}=&cD{D)JmqS6xh&EHlvX;;Jv#L~y7i%{(50J4^5r+sW}(iPuAQG;El(9&
zdUoo2bjPR&_;fz?=~RCS+H?SJ=YX;_N{Inl9|Sr$#kKS0%S~W2zP`)`7r~(V0JT3e
z16&?BSa^1x^8jt<KkAcQq2ST&;Na1{;{<5STj$RgJHx=EFdn_m|2_HFANOJW;L-XG
z)Q~aYZ|PuRU;s59JAZ?kJRaX~`)K~~=!{W`0Lce{nmh#{Rsx8y@a%Q}4`O71{9ypT
zRp$d}cqV|qA9SgfcQ1>bN9RG13JuV0L6#?qvOy{%Ji2pKG<-XMcyxXQbv=7iWEo!Y
zgfTOCTD~iieqHX<`N*U5B}ks}t|#N27av2xQpNnfoiD(0AOBx(Jy3B2q@weaN9W5I
z=R=tpd>Cs~G(eTLhKHq#ib3%#kW~pDmNB4akScgf0%-W8JK~2=cLB7|1QO_sQ89RF
z4Q}V=sA#-i<uTK@^M&X4|300cJTCqK1(0vA3Y$;o!~fSoCT4)jlNc2b{*HN|t)&nb
zb^E9ofZW92!3$bC3=;eV)&V+a>^NBH2gKzsR6>~<K;}e%oNC~~c*D2#zend?P#`&!
z=z|13K%Ht3!@-yF;RH}uLIph1as)cka>lX4M+MwHehgCO;nSU>;sCD6J0JUYegT=J
zfhd1{8UOfpzVPUTxu@ct2jgq7$VZRPTOdbQyaV-3Oh9I7fE{zow^xM4r}II{VbJ|h
zsN*BZqXMrNgFNEl+xp+9^MP;YW6*jZ2j5;78O9P7wDA=#ko!QTg{S2Kmktle_zK8I
z1E0=YKAN9=G;e^K8@eC^Eqpp}_%Pn}Vf^6%I_=d(#lWL82Sk8Y!8(IG<`yrzKwSmU
zco;}!r-28wbK>7?Vhsua3vfm53p$8tIwJ#ve=m=X4=4y8Ou!hXH~}B!fF>_kWLEfs
z1z-Wk-(e4qa9Bh}2ctzKEEYlD$^gaTOVElsup6#}#-+MlR6Kk-AAw{*N(}sZML5zh
z-Gdl)@d1y&AtxqKdrpJD6SN)<G~@#D5{8cuCir$jT?;nq#fl(gCxZ?1V7viy_e;>U
zB506>GZ@--0Tm`FC6RCI{}OP*1*cK)y&))JRACKjEP=A`#~0RM%Uo0p4Bvuc#Nnks
zG|C`h13K{*)XD*^ZT$ao3ut_&8%Z%}1s}M5^b&NDGVb;dsCfk%zwzii=h=DHr}I2$
zxEWI3tpJsGUcD}$aUIZ&!o4mku<jbDhXy-e1~jbc(RsoLHpT;5j^PVhk!ty|C?;)!
zXE&Q~=XcM}BOp(J2eLgGzxY~yEfRaJ4XQ6ao8NPIcC-6h{`Ks1=O`BU=)C0#3iXGc
z{OiMicrbqYf3@{M#ZAxVV;nw~psr)Li;9A0CwuWSk8U3o3lB>l6$Ad3gP=Me<bRKD
zj~_npF&%K)_fgS!2^-Gw=)C38dD9m(paWVu%)dUA!IOVIp9kY755|umoA^7DLG^yO
z7$}Kpcz|y0`r*O9{;~)EdJbe&;LE_khT$^j69Z@@pAF<n4bRRyKAkx#An!l$038C|
zTlvGI)A5HV;}_3PuvH2Wt3ZVu|9TG&pWXrvsEaDJK|urw7Ek{5;y#@ZVWINO*YaPn
zuxB^BXSbLq=<qH!A5bsw^*V^9AWt~{@aO~`I{nE9Hn_nCjx6wsT2PUp4JvgEK*8$)
z+QDSx(dh*qrT|5k0Vog@KrD@ypd$-FTmz8V3O=109-wvK%?AX0d-K4{E)8CO1g%`{
zc4Yv&CX~UmlMTGS7NkMLvzyJMTM*>gPDb$1s%Lj7gJ(CJXQwNJXQ$Z9Uf8W+pahAM
zXTZ18A_(aEm*zJL9-ZesIxl*3UiHxY=>ysY_EV(3(5E+?(Z}*qnU7De|9?>W^0B<`
z%D;`tv)Ai?v6CbJwxIux78hznUz<VO<NVtKK_a#MpqjSV5p*}LCwRQ6`4FQ^2cwVW
z)zUrSdv+mvgnT+LdNv;d3A=PKmM(hz#N*;mk6sgg&(1R*oj*M~KfM68jyyVFfoDHH
zz5v}n>0$XDv^=HrR<T&x1W-ZFzs=)6s4(}iJO&ylf8*85qwLY^&iI-SB!7$%RHA~^
zd03wI=neQ^EahSOu2__R8)!I?4RkT>Esy5Ij2!|0U*GhwJk8%61KwH!=}&@W__sMj
z&A-{<^uP2ClKUsX&v$BmqXAlT+j-iv^NNS&2_MiH%sCI+<qQlA_1T~;(>|7m%3LOZ
z7KU3McH-aW!^=?Y<k=nY!>99rm5(R`^!`K8`Q;!kWd0B`A$%A#e|Uhyr<23i@<{n!
z&~3)BC_U`cc>uIy+Sl@kPbWwD!q<<$qpZC;M?qaHuU;EXkIr8&K>Oc(Iv;s<e)I&@
zy+2=o$I&c*gIYnIpNd62nh$V*aysY$9}mmp9-Ur4%3pi+is*s1vA^c=Xg<#2(dqpI
z#PhJc20GZhSjorod9kcVH@`<Wn+yN85MBlsix5_Z`pcj}VvkPeAFnTZSYG3A_6N0O
zK<kmZ{eFP0vHaxG>G7ldHHt3~?E|W$$0CgMSUi-{WBFi6kI?%7Vd)WaKKqbMkLA=%
zj~6^TPlL<H6F!~CJeq%K*5~{5Ix>MWwij&v#0PY;_I8e97e~;+<vyJU(kw652)~wt
z$%91GEH8qyH}rbN!=UvZ2bj`2IeaXSmhVF<T_Bm8$;a|&S|>;OlGjf_1G+xFDhyt|
zHj1E(4O-I+E*w92bpCu10Lp9dTrCA2pYv!wz{J1Z<DW<KAtn#Y<7u5<|G-&W4Rk{K
zYu*VS&BvM2I=%maxRAX44^%$BFBawB&c?r;Kh5$){cVrtV@zqC&i_E=<2C+f&@v5}
ze?U_F+x`B5?D4Stl-B9-51h9ZASKjcqRPh{So!D*FCVx2_%akbL(9iBYoAbX0hu-d
zlpeuca0o)y^;;e;dI2f~p#>zUe$jwf?-+|#KrX;uK!VycC<UY|N>Iup$|rCc*6r~F
zdr=7vPmHos8B|uv!OF_*A-)W0E|wv#4E2}bh2;fsVd)IAm0)3sI==wfe-Ey|$xWX{
znCTOo-G@l}EFT={6I5U#rB84O4(;?=PUG|$Tp#b#>&OBsKdoWq38?(+<|sCE><;+j
z(|N%1Vh!hO;qHJxmKSSzKnIV4@5DS@^cFPG4k<9tVicGxK9)y2Im)-ZehQj#^yyUr
zk2Ax{Oz?hRP=gX&W`f#!9`G_#1k|2n>Gt>oI=t1x@_47$pYpd}y&|B}lI1lYzdVCS
z^Kq6=?>`>Rhgl%S<)30P56kz(g57N0{FW!`?|U>KW9fAM^ZG70M}wxQKqB3Ke>|EG
zuy|O0>h$<i{uar};8Ge<z7SPjVzwu{eR>harM1sgh8ls_(xCP_sJsO6QH#r$NX6yg
zXiqAF%19XxP`8HPr8}gT!NoG9m7)F$yo9_24o`3uN3euM?w{i+ABjqTMX>aTbcf{N
zO@HNsCH)nlr9af-aHyoe@_|o(qvanl{pr#2ulWd~%{yBD4S4-KTK+-C&ydG+Q2Qs4
zp|M<8*AITb-(k;gj$&76&(Fj1Vv*=;1w{J@)SmIMyog$zyaF|6JRr?M%>FZ|TkQew
zKePDss=x-vz<p>?Zx+#q2A#i+Xb*~k+Jjh!#y~AX4oLqQqrWEwY7mM-+A<!NC&2v^
z4)B=RO>iRyWFxG-3vS<F85^Ul|LoQ6bC#jl1r~_bK35qa36cREejq+-2oCE0GjiL|
zr#s{<gO6p%Q3i~<8PsQ=fGa!^g(Ij{j7U#-(kEy&czqD)L@E!<t7XvpWjrh|L(cvc
zdaVfBZw@+u%ER(7`su${!Tan$=Sz85UcGHmegdh*?{V-4D|j}$*M<>1k@M>X=sr6{
z8U*dVL!?1r@bbv!Ljt!mK6qFjzg_hK-X#%uEeqN&R|Pst_eGU1cu&=h+tnXDnva1`
z=YjN4J`^j15~SR1z1#Yr-C|{@@7{RLe)k5r=i$+OT;O)~hu4q+2+%kPMDqcG+j$>6
zEI-|@_<+(~0oljj%>>$iee<OZc%U3~iwk`JGw%M&G0<!nB-59|GJQOFyr&a<P>PS`
z;oCZFpc6!;?%sH937t=XoOcTycPv%}C*RJC9tR(?+}7c{{j&T%XnXS?aA<?~hu^&c
zDhr?^L5olZnNdf^bu>LXUxDWnzym)&Jv%>urtZP>fR?YpBjdk{(ewXN_|UjMXfXV>
z>;%v*#VWS@FRI*Lv)sJ_nr}cJE58mND>wDAd|GS(8vlX#^tKM02WVcW6MW2#(`_9#
zaI|az?N@`WLUR7`dY^~ob^c~+@QBcH4v%hs=<xY3EW_uZy=|ataqiv#&k&)k&%)XN
zfkXx2^0x+C`HR|}9NgtEc>Hp}%U?)`98vzFhTsq^e=+*z<dwgO+uxes7<hEgQJDZ*
zoB%qD{Tytp{kU)E8OTf;e?RElRG;2N4j;=$Wof?MpygeUd^=zI@UK4&-j4FD*u}Ry
z>W6RV4IlpXhe4~CO*|QYIP!1f1nt?eI92Lkc;K}JQu)unjfWAmsD;7eVyOybmhf=t
zOVGkC-%c$b%cteDJerRfz=o3@;|^O~EPm+O{EEZ3Gm68<@><aZgj)V~(BRVRbD)w2
zv`R_Ar`H7B*6{1qG4$zt^#XJojYsDzu$*t_L-5S}%NIXDSN2-I^XUBG)A<N>HqO%$
zTIBfmikN`wwqCa%zLr;tlRYip7RUK^%c%HvmooTv-tg`G2=Xx~AV9v>^JM&q>hXBP
z1F!i(>vs_T^+EBkPiNc@kQKg`S3G*%eiY61wY<XL3_8*Y<U`Ny5EXC{<ZJoJqch+~
z`76wD+3DGQl*6a9?8ocvu=Wkg`q1V#7N8hj0EuDHL}}-F56u(4khxOm>UYo_hX;61
z&cR1a9+nsQ!Pgr3^y+B(TE5|L12ro>J70T#zYVUxz-y8DTXuqvF9NMU>kesU=oD##
z`Ru)q<$G_CY5dJ6!0Tl|%cV=KT)NG=xg0Iem3l&!wDYvNbh9+MS{^L5gXw%_c;Geb
z1eb1;HrGxQ_=5KLo{VpOE#H*4do&-hK%@%C_`{B!CtN!}x>_DAK4y5}H5au0>gH*3
z?Bs!K|KQ7b%ZKq6c=>wq|NsA8y3JlshdZ$ebjB0J0{(W;DJ`#O8eRe?7Wn49qdvVR
zjGmpxeL6qASO7{lpfzhTpd}n1!AoBrz32jq{xm$`aquUTN9)NF!ETXu$Ig&e28hoN
zmcI93eDB{IW6J<qYoYnV*Ya+0yszc6;wVtUadGVybM5wJaJ9TxS_%pr$8M1}$8Mii
z2Fp{WSr8)*m%j4o4gPO<05t3Vn$;B~>)OfF0FgaZ`p%Q_tq0?KxbZ~`!ON;Z+d-H-
zS}*apfR6t%JODP;5n12MW&c2nmQT8LUb4JcHrw#PYZljTkv7*(5vbXROW%7kzI(mM
zrQ6K6^VQ2p@TM{c2BiFqy#5e1y?KDvAYKK}%_Em6pwtK}QIdUnWx!i75G9K*qGYk;
zmuK+pF8bly`N0=jxTt~hST`qVd&I?3Gs6R~c^tcW8bO;DEH9R-LBiv3>1$91f)*!B
zF%pjD#p3&r0;LFCpv*z2=5GfjlGkT&7AT-yc9;dqcTf@_vOt0P7?kBf1xp5~U`h7v
zHc|2I25o)$;M@5V<XccUfYOICv|xdF`c!F*;epp;Na2t0z7vY~LB#@c=`sUcy1WNn
zzR-Mx1G98_2|9Ai@?!B}NSRXi<MlyM%N?yeiSX!NqjCVWkhFV=3TT0qXXiC=JWo*p
zox<p;dCmuvS5A92{sXPV@abNoasgCS^h093ki*Av3s@z8TP@g>Jz$=v=6TOv_wODD
zUod<0x*P;A^78<fH<0yL9-W6l%Xl0-_}Aa{VEpZ4`K?F{bl`^r188xPXE(c#<v;NH
zD+!OzSK!r+H=*mVemVZX0$MBzS|Q|PU83RvS_I_a*~wlCN*EC+C5q?4e=MMNP6j@m
zDJmMC2cI#6Rvs$&_1YNvbpCqr5wwcA8{$#0GSAMNV3lB1;JW4K3(!&LK9>JL*Asvi
z%%JpVJz+~dJQ?qSq6V~I%%htb)Ux&HbOYA~K9-+B38UE5#~Knc#oFNH_7dbN{`JD1
z{OkEW7=L*%{sjB0@&IV{6nMFa+mF}#d@MinH>-lqt%LUuz=nhFz-vCh;c0mfT$8+h
z$p}&d4qv3*kj-xlK=B1_55Q{+AJDa+=e&DE)-rg&Y6wtVd-dvQ`gFeY_<qmR@=aMX
z$bq1Jq#s{6YB4i-Sibk@jWK2L?0i{l<lFkTL>II_mVcYD#i>#s!vn8H;q?`0126wJ
z5oU{1rN*EH>}h$l6cmNv#f>L@7~j75s0mvC`=)#@S_KGpzs1GkOCFuKd^%71cD{IV
z45YO4pa<h;PsWcvmgkFFUT-nH1d1#L&+lJ7F1`S7S?bkc1YINA`RWCzvh@Y6(zyXz
zxz_m-tn$SRP$mI&PkwoH-t=L7@4<NQMUEzD(ezIr&6ggQpNsuLJq$09zcgL=x4AO#
zZxeR3xKJ7bs`6d<x4Ez~fV>0}a)kNmg-7QtP>sR(`h|ifXu0xxk4~s@MH@Xd?}1my
zeL(f%%WoRYpl#yChat%t6dI2;m>FIlgs-o~oj<pL^QTAW1@PLg5ETz_NqpG1^Q=d&
z&sqkb?mghF>2dHOlZWLA{(jJXfF7OiJ$qSnJigxtEu!}D=yXwWC@TRit#|MQEku3k
z(fR2`q6R1^K6vz+*m+tW@#s8Ur2IM&7N6kF7B@l5o)~|7F#daCq5+D$JH-N!)!IIt
zFCG71YduhL9c<n!(5V1|AoCb=R2;xr6KrvLk4N(n)XWK58tm};q{mF3&WE6TiVZxz
z{{<}<)Bxu`kBgvXjz>LvZCJoj`|HJHaBdAz@$l_@30}<h6RZoN<;6irG=pRQCMb?O
z)IkaNbFqPkb&ZNgu_oBbw>&z3f}QNy`J%!RoYWqAFur~ft<KB<I>^BCbI}Dz^!b1q
zn4lO$arjFkb!Mdc614LMv;y+|3n_>JuX|C~7r^dj#<#w$%A?nl!^84ax$tXm(9HzF
z9?b_id^#CCEzgu$`E)aa7T!VbE%a$+D1HR$#DC@&aG46aLbB`}=!`6A2fyeELTC9g
zl-@h&c=#2_N_W1#44RKU_=Cj<ZMhq04KKJ;4_oeL4(dh2CwU1hcM}BpAPZC;qOW;V
z1I<w?dUW%7bhCrp-^=isU%;mo?2A*7MRLwRUY`Yz@qvz-0o7MvbFhr>X~0VQ!~A+D
zs}H^Ihqf1SkDna%>4dE(gon4tYhTcjq*Wn^U@NnR2RP^gFrTB)0RO}<;Bpmop!mVE
zGswaC7@@WNC`yQ@fr5M)vfAyhFM(Pj)D3STun#i90fn~6P#qNDN{|2tx&JKa%y6Hh
z5MP{thxi$Ih=ayoj&XS44R4UQst>>JhwKN!J^t7HBe=c{bQ`RP<<)Yj*WM8Ipv2(~
zS{?A2UyuVdE@<pwc^PzJEBI=}v<aXKZos#}UIVRGfZhgsxCnk5EXXkA6$_v+-hiTX
z@9WFhmMwrb$|8mcL49q+5TPQX{RLiS0KR!vz~PUF<#EsjD}Tyg!q+eefjkiRnP1TP
z4`^Ki@;U}t&?uqAXMO>;&-?=XpzB00gH}6y<`?w-^ZFV%jG+sZSU|RX<`;1L<6-#;
z<i|hdFOdc~K`Hv^>)GJ?5O?@O#-Hjz_fLWXMe?;5D8GOc11Nw&C*#8d7<4}*IDjXB
z4)zC~>3^{7Dkx<_FP}VI1iyR|WEOG&gQB}?J&M}huP?#tD@b}qoe=<)ABdo~LMc4N
zK?}gZj)1NJ109L~10KK}uZ6)ri2uYd===kmrkf9QK*nKz6w84^Sn?CU0NW>i0nlOa
z2g@#kQt>B#LGK^0uY!XZbg&0V-zR<nP!sF`2l&izL5CkGK@9R$^^w;zVfU{zzj1)9
zK8B5%9P_Z954td<A9P2TN3W-Xhvg~$Hqat^4`_MpqN3o@?Fe3LuHn(`2yWvVcyv30
zkNCCVZ`NjHV7Q$F+O>J&c8-d{YjbdX!jCqLf}ihu*rPLmg!6sNYQU$xLC-_Gc@lIs
z8T5R^HJ}mD*M!eE><&>;@Mu1$;9+?ddcdy+xB}@80qx5P03Yyc;n5i&!QT!ZacMr{
z04Z({Pr!1X9q61@r1R{m=e$$|oks~e%kCw}sh|TZU-LuDXP5x!JUdVs4?557CAcNt
zdEzDLj5?2lKiI&>4<bhQBS2L@e8myy7Fk5r)%9pTpy1K%@xY_`kOE}w^#hM?j~5=D
zUN1blJwAAJdVK&d%?7Q>z6{OA3a@Qp?HkZhgrFgC(0wSNlaJXwnvW}ZbUHuq=yreM
z(dqocquc$1N2l`#k8bxLpgAay=EDk*^!R|k8Fa-6=#HFb&@PkP`nU51ZtLC769Ap=
zSiTf|bet*30?;5ge-~(s1!M)ANAoeL6>d-~+@Mx~uAy=M@p^U@Q;FLB7gfUG_++_z
z^X|?2FRG8e1PyP1qPzMnDA-<eg3oIMonCnRW!YSiTJXlV`!A|zfiKttl?UKF0Xnk_
z8vbCryZs)3gAKfv{DDWe-wTgUj~5=@ejhwKJwAYof6yB9%N~e`2c1(0x?SNVXn>!n
z`Egs&{10U3AZ!jOH*JCk=&BItJs*(!NZdeq5qyOF?J6tKbP)VLlEd)(NR&V&2Ks#@
zWyauR+d(&(oUA$qnkxd`MdD$36?_*-`BbD56;Zx}?yCWpFdQJV`sC|g(8=W0pJ3?$
zbaZ&xa_}xCEb~m@+yGCB3@9a=5;%W@CYyY^L1z;OfY!JQcvv2X-Mvx%7@GV9UhBZi
zPmt|U&wE1e>HtkC`E+`J@aYT&Z5a@Nq_z*mC7{wTA5`)|OTc)L9}a%v7YO4h-wwLS
zv<z~T`bM8_KA-L|4$w>#%%Im>tC&hez(Ebtb)fn-_->B_)t}P%^)8pUfP?Zl$Tigm
zUxEfrVCe<431Jg>m<W8H1jtNqLg@w#b{-J$0H>i39-R?C${!<zI4nFd+hgz&7CxWF
z-#-a7cF^m{0b0tK0NLW<)yr}Y>4vKVMdGimK>HW<Zdd7oY9sJ|AIrnVs^Hw+D*{r?
z1iJSLe7D;T(7kHPpet^`cR7J?#q)toa4$e<q*XDMfE%prpzF<UzFrEtQREB1-s!T#
zuV+H)Hpo^Gzg`thpUy`wK<8<K>o(AYmrv)z7ohW1d@LVBC%jPF#^Bx*bSnsCzDs-p
z=%OL;{ajw4Q7RvJgAFp%RS4QWpX1Zb?%U0y;?>J?%&V8@9Oy1O$QAXV%dR3pmt6(0
zlyBqLJ5k0DGHxTN3iJVO8QH?GcM#&ClT~03J$*eB<gYKFDDDS^#ubqN&cAMkr$6v4
z*(>DuB{W$EDpe5q30wSL2lq^m`E;Iz%{qYYt@P=Q<nXb)Rqpf>bXqDbeWW=y{$!}(
zZ&|{?z>wzJdWpXSe5pX|$qK$SN6S<ElMeE4JK1`&G~ToMFzBosAItk?IlkS>KAkt*
z__vFsfsS_Qyz1I{HO;Z{Awx}C<J14lX^xFg|JVCi-Yz}`UhmGoohQt(^F*3s;{%48
zG{?pt3^k?gY2Oe2XD(@g*k2M2Nm8I&kPa7}M%Yz81tqnlO-O5f%imf68g2nOwiDE<
zOlv(^p^@g;_=};zk$>uewAPdSQxCduf*k%5beut2>)VnA;BphxGi-eLzdp^;@+|*!
zumVt3i7lNi0oQrIJVBk^51@2589XKlNoTK$Wntk5YEFT3K=UCEr1Tb|%K#cFdTrs@
zc__`X@e$bHzZhytYSTb_m_bL8f}EY2W_gf*`T_oJ2U-u5M4+a~tKhlUL{G~<#W6nJ
zt_+|g>BPUC$IXd<JBy!V=P6`!OQ%D^b3*6AG)O%BWT+`!m$vdhbIA(OoGdtfE(7uT
zTR>M`z{MtcSYG9Co(4{VE({DHagT0a@Jxw^<tr?cwIFv(rrCl6`w%#=54dn%;NN!O
zr3ENjRR7nffy3DH1jJ|H)(AYkV@t1)F>S>BI)A?<<Z1^{dBop#7L+t$;SDOBz_ZY-
z9*iGAQ|_Qc?Lm|7=HU8wB6ueK{);N<*Q__8=c)T4pO+7+xFKoHg9CIisy#UJI!}3k
zFGlzTzGDE~eAo$YJ|x20OZQ(?tq0lg+6YYQz}y4o$szJ1m=8V=8g%eF<UR+_X7J`W
zAIqcs?V#!#B}rE?m1y67Q6&gEkQj8H@%<OoyI+D<*nki2eGhUkxB<rp>A%6;13EJt
zbQBw?IZ`zNbUJhOl$$5PVT~<0gN`CcDK<-xlJl=(Ie7fwNY6Zw@>3Cf-ZiMb1{$lr
z3pv#N25P!J4@$TE&6`2{T`k}6H-paK0i|7^Zg%k5eFwlneeeM*c>nANaERXq#UeP^
z=YxY?8PRG3O=qC4_uv4h<w;d+B}R}F;=y+f+ydRg3|hkgYT;MkcnLbU=jQ4AFRI^y
z8fdS1q4g=m;M*_x+d)MGs9{*O^!|(L6)!<!ETHii%k%ur(cs(wt#3i)aX2(T{Dh46
zqC_C5W%dhnKu;p*{!Zf3H|Xem*cy^Nc#>v;Bx(2!OQ2*e`q~NHG%!O>wEBod%i_TZ
zx{`_M6Tg5Ls9|vke8ta&GIg*nNZafPA_109LUDT<_`X9>ORNf{`9Ss6*VDmm5Y+bA
zX7Fug*wPhr{>Bq@o)fs3{DYFNP}iRzm5<Q$Bni5&>k_p6m54PRfi4g91f?U;bzjh$
z*{Ab>4=Bq%VDUKk2o!3NK;VMjbrc2i3#eTdz)?OQ+%5xMb9AX{CcL7an+B<=#la0S
zZcqSJKYCdMD!)MW^?Oj8jK4hx!oOVwYnOrd@`4fw=+13Oegqi_Iz<JXZ!EE;548Fk
z|9Tewe$dq%(Ba6kcu;%&^k;qn!O#2xkt`maCyHcVTY!dKz)cuEaGK~A@UR4RVL6KB
zK!Z1^w-cA?gIXQnHrOT5KpE&}Vh_u+pZNtNSjrb;X)i*WF9#sam$R?ug4!$K_Sp8<
z6Cnuzb*us29s}=20p09_=o?Ca@)M4&xsdgTQi%4L9q9Tx@XQNn+yOD>5C>{?M}kIl
zKqEW+dZ0E~Jg5y8#!`L=)CLm*wZZm+Rx5(`Re+jd2Oyq+x51Wz;uPEln+*yLXdA2_
z(q90zufHJYckJVDxYsj+j^+jJmj>^s<nLDnS6z`zK9;xm+dwB&?`33QV0di<Eq@^G
z9sZWBpi0dZ)D{4p7nRm}se;$=WE$x7uSo}6PnPC+HXmk6bLnINwYNY`DOdjO%s!nr
zil2jy4edPUYIq6O;Cl9-*|qbCBmWdoL*pkyjZfzd7k*bzd+f>o`U#-@nw=LBZ36yQ
z(EVCz-w*v~h8*AO+Ip#El1K9k_-47YNLKT=H-h?D%}8sr(^|jrw}SR<rh#1F2`WWF
zu9pV4>p%^#qiL;|zzwjM{M$~x1l3Vs`@yZQGtgES=mtU1Itd@}UQiuH&{DQVuof41
z9orNT54w)+6Keg$gxC*y6m37K`2@$#1IX>nlH#=10~M8^HcPy#;ej;EgO2>u54g4-
zC<*XrJ__CxioA2Qz{B!yaW?;UKK|{l4CqbPC6Ff8Tr?|6w}Dz!B^y9HNkKbNUxQm+
zr61B-4^*~;EcSyomJX)1o&+^eT{%y<f|^U<MU$Z9HwT>jKnp`a?XP1@*!H6$#@ih`
z4?<lA3Q}-W%N6P^kg1?!&XC3j!h$_OGatPsg5b@+7d;NXwD(}V=yCDq3r0R>29MSQ
zo}GtFG(p#HgU<fB`C|1x&|$eZUj*}kPb~pQ{b5A=X2<{k|Np;!0dFsagDp_-=sf2G
zI-2M*$b7F}n?pW~2f;@n@PJxx3@@hg!tK%p9li^j4SZ3vA7b4TUZ{1TjD}&~bGUtA
z>oh#D`Nt4p2a<oX4?rwvhFPEy9fx5)!auL)p_bP~`fn=_4*%&Kgjml4vz~zeUiYEe
z5BF~%YWy`n{P)5EX6eBa4MYTT9Rk^S^2H<`Xo!M63~R4K;_oFqJc;z*Rc;*qy92iE
z<_i^=Z3O&>&p!n)OHllC>oCMWhq$TeA6A%Ehf7e?<C-HN+it!Hf!Ri^e<q^FPv;5H
z6lyOIc<bhiX<X3YJ6Ix*h^YlfL3W*d@q!D<XOIYjx4(#tA5)kG=>Ew$2D0Pkix!w2
zRPoO-PHg@OI1aMw<O>OyU7(alo_|td7NGk_<^;%&n=iI-Lc@$I{`tm%%|8q$L3W*d
z;Q_OYeE&>^S%B`JGhjPzzIehxP5-FDtV2m}8%{y|QvtJ!eE%F}hXxqBe`-#H?6~<t
z1ZD@Z@pBP-{sAvPeGvw;4#htSXFztHe6fNZ8g}IS=PMfy|Ja-b*>UrQ3(O7z{(<G!
zUYkG<(0V<1g$pXM`ysY?bRI5I2NwgNYXM%Y{0cgZ{pO2@Y*252t$?-{A=&2@yu1#D
zSfJt2c^+KhUV~J)I_MRy3c@NKaE1E=yzc4ai_@<mwiUx{1Gg*=qt*|I`Vd}T<1OE|
zu|k6nHGUp~!tUe?4kW7%Lp(%k`4$SZ;1F7QEprcK$Hf;*Sdjw{y}g2^{eU;UJ!8S<
zpAS&~SitNeKfSfWEI{|q9;kn=u#n`R&I{n4aOXLXUKv5q(N*AP9=Hj1@FB|!F_?9*
z__+l-nC<{LubzC70keyI|7>N31{k`3)`0Wq#TP6vJHUyX()e+MSqJmaC(y#D1s_0Z
z;pB@M%+RnS-#<^8aQWvM$c~FIOkj2p=N|&`QwFo{FtmLDjvs|5AiHk9IKf1*e?(yx
zpvRBTTaX<WU!=h7Ai+PZpb`#CdSiXDj1d}qu=oM{N8ka-u9Gi*FjDLvSC|Fp{+aU<
zWXHu9Q($%w=bv5^yyd|)1~mVG(^~>G|7gJM!jj(5`xEHxdq{Cku>TYaa{zjMD+A77
zH(xAafQBgn|DxLuzOx&tzlbz`X#u%-2y&_(xMSy$T%Z8yJbLi2KlkFme<n}|(xdZe
zNrXq|N5{ROzTt~i5K+(0BPD7c{Oj+5Yo8b3)9^}E6kHA8di09OzqoP*6i*LdyaB21
zeEH(Ze<lW(&KJmw%MXKkLJ&h=KY`Ux@bx$bp52ZXD7BzpuL`&pOwLe1?s`grYyh1y
zd$`01>=x)5p5S$kFKo_0s>783Obnp?0I;nxhf(TZME!voKIg!v4no7H0uesvUo7|s
z51$Ossz*rpbU{Qx;bY`+@I4dQO)orpMfQS@yaS)%TLTFv{`I#!dPU@3RDjzc4__Pr
z>Fj*@V#hyhVFejKfQHutT;X*V+-kTEYBj*aD*`#ZKo>c@c=i|S@?#}>5ch#sb^ZkJ
z<#-Ws9u#IDUl{zu2r~vq_5K>(UO`z8?Epzp*F7%&^6Wh8+j$Ijx~Nb00?>ql2mkut
z9*p1w$G`sciv*A>I&XS(9(xfAVuDUpK3d}I(R!f71MCve;!^|9&V%4p<KPXDzkE7h
z8s2_kb_L|ZmoNH2+B!eJX#2~=(0K!~oC0*o&0+BP-)>NveSI0HdqG#(=p6C{-IRCU
ztCt7d9QEkD=G%GB1C-9X9UP!;f3fKgG|Uc{Sb@XrhYx6{)JL!*!7hZPxL@GVyZPeN
zA86<~K-Ttv-82CbelOt%T!x1Qdvsp*=ym+>aq&0kri8x7ppip8Sp53*vPgUMR{!VU
zRwDV|$MTR*uZ(4_)N2=*yninXr%Q*3gpcK+8hxM6(|)}&3_g~Jd^-=i@^2Ha6Lzx*
zVPLG|0bOa}*DJ#T5_GY+R&&CqS4P64^}l0>u}A0c(wXq^apB*_$iJ;b@V`rki{O8c
z=2wg!&A%8+{2X^MF)%Rf29I?LP-3ZLhw<xK4jqPu2cqNR4^Kc|j}1yNy-q(oFaGmw
z{l?!H$_Tm=q~_BPkIoR40BC;o?iDff>HO{6t?y}hp{5G5Y~b5#U08T{^vYcD?7ZaD
z&F#j&O@`CeLPn)Fz`IvO$fuL%14xTI=wx}z3w75#daD>cJ1=?k>VQsqXYlA2`QgzU
zqwxc#)x|<aux`IcuZ)Ig=P#Hb$h?{j9=$Rjz#A!=-!b}hYV)_IfksigLsSAL_;hpm
zb=MsF;n(SN=!a+X3r5f8AB_AhZQ$!obSxb~HwZE82M41jsQmNlH96tidD^F2%!z-S
zjG&`MEJJO8e=m=;Pp8NaU&|9U?mnIOeJxMaUGwbCWCW?~Re1|4NPN0YUU>DEDExqF
zb+V8#tlRI^Yog%U`5Gn&G7scllOH~vb}!?>*LhiigFe<V29zQl<3XoZBid_pNsndd
z>9L3o=@EyeXzB6gZ`Au2>5x8)$xokU*wSYajnii_`RTI^TlxgKm+18QG8-*^pzHrZ
z+i!Xu|9M{g<J<a#zfS{PcH|`f^Y3L*@$G!=$iF=oR4&$}`E)*ht%FGKe!VgdzMY3$
z`L}bYxmcd9b@K0J5lVCE<cR>4s1`n*mwhY`)!p>$EnxKRJmk@9W9HKvWAP8Fo~NMh
zq))Gmg=gm{sL0uxeLlT15uVL&nLL}{Fs3<ziidLWIRxPOW*7eLjQrbk0{^ACbh-ro
zgBP&n$OSCz-3M~lOYkzAPEAB{a5xQLc^n1~Q@rJIwHyC-l}w+`Z=lU)VE-bQ$J=E*
z(_Ag@)CMA##~wtL#~`gPmNJ2L`;ZG{kf^KWotpI+1v2P@X3$C30XWLzb_NCpH~#H9
zmB<CM2ERN5a(TR6CNRy>@@{P)a(V1QRCx^2>SQTXSho+kKn96ATHXb@7n0yX^K3qy
z=mj#$`3Tfa-^HY+?=tlCT}0FLO)d8gWcn_qAbpo%OW#GbP2a^7r0+6p=^Nx;^3wMo
zSozHiE^BfY{(+U>-H_rt5>$N4`}N8+fC_EUO+9C89YIC5ODE3^<P!T1qQnMG#WR3P
z?LXkVd3ZJ;%51O!HT!*fWoCFbzhwcH*p8jrrCo^n!KItAJ7?k_mrj?7f8d368ggMx
z6W2I)YQJtlDVm|}Up(!R0C1S$EuTx>x>Z(!if3&s?d5KnPEhIWi(ERpKuhNv_*%=|
zGMz4#G85|#B9+Y$!)i8Tl+2*3j=&`|WPJ^e^0^UIK6mTvL@u7y(b~)1G7~|ivoCV#
z>;f&FZ{TY!cgsw4vXt3acMz#;h8PBNFC^uH?wiC`GQ-9PAngru(rYov=@n51gVSpf
zHPb7VTr+U#wV3SmT85cki)f!-i^)!}Wtiy|<X&2**U|D7Ivz1vzMiNVEni7&4~&+t
zkij!ZdjM2kp$(l;yFD<V<?9bv`;`^k7R!0~1KNJ|L~p+y@a;V0+s*A`c@~mFd^&k<
z;Ap>o1rPW2##sCSYvB0+Zx4X^XTj}(8=lQ?IY8}KPt^7+XtRBH&cz=-oh}!D;BLTD
z-#MMyubVy4TCkw=uaM3^LL2W50*4vi_G`IcugXhM`xU-F12Mkf*DZ6>*HT8M*blh@
z>k4haUdPjb1?lv$l(|@T0MUR2iGfTj+Jw=9&4dm1g4&}v+OMF+?0&sEKatz78X)zE
z@ddALnTwv5u?)q2$PHLmXan{-o(3#Pr<bM7$Fc*61}sPnWE#l5kQPA_*1=xn{)0#J
z8wt<O>z<ugJ-|a}|3R1U_5EgHVDRd#sr={B>7$b1+4;}ASH#}8^MfP*b~{hYtNcBI
zj0_B&e>?yAcK%9hd<xnV_Uu2iPp65BBma~mX`Ll1TxpGe8EW={2Dx4Nw>@#;cYW6R
zFRk&}|9X%t&+8PQUX}ny{_Px&ohPBIoT0na&V%MYK$`hmN|_iK(pvxXcXWXnC;2-r
zGB7Z>8lFtE{OQO){h({>N&Xhl+G@|viyn-Z(wsVZ0>I8&#mvCq+j+{<@@n05pWY}&
zC;sg+5#GHf(muT|2LBv8Z-Q(_wblo8(KxzWl$b#dILY6k3ufHr?+63!7qC3dKm9QO
zw%e_@`CCAz9QgFIfG%YO8H(<mRzr{m&^|cN&Wrpl%K!iWcWr&b-wL`U4A%bwT~q7V
z%M#$({Eo@9`8{aB(1O3U6ST{syF?{nf+PQSF?as$HF^KioI6AE{&_aPW%O+R%gEp2
z54u6T^S^87AH%n4jnBb5(4PEf22asA@J~7F0t)m03^n|&ufbuz3p9b_xC<03Y2Zk5
z=~Pj9orW_mK*62X2r{50h7r7Z@IQaYTo9}EB!5Q;_!4o@iuUu4{F5ND0qSU@$Hr0y
zcx+51GB!9F85q!mvIS%xXfs+zJlF-d`8z^Dfr}g)pu->V#fCme13WfB8v{Xm4gLQA
z{|}0QG}lgxmwo^K|4(bKQQ>0XZv|ab3rc{U^`MKlVetiaLpaC{jsL-0<PN8SSA8FJ
z<-F+%S`eQCQvLlfX!-q0@CCi7Nxbz8SpFbL{@~yL|6kq#@tbW_82DRef^2u|v<Z00
z24aEdFVi4Kz4`b5KYEz7^20pD-@@|$|NocrAU-H^u7k3XBMt`!g3N}`FM`*+^S3?$
z3AUc(?_3CG+~)59?e9u!{K?S3Kh;Hr$Ay1eiV9C!>uvt2hg~=y^KZNT5|l>MCP4Lz
zfqVhdfBDb<{~%=@lR<8P>F0Oh-&Uf+50U`s{|wT<8>DgqDE+_u|L6aI*!Tt{8~(3P
zbFuVM;Q{A#P_XiXl{ml>22`F4E?*74;1?u+Cav)?c;);P5NUY_l3ick0xMu}>^ujP
z2bD*TmiM6YIw0q`cG`g#2}mHOY#rkdqm0KQ)nA~M_n<4VK<fZQR4P0!{_yQQ?$ev}
z!vnM&fklPCPnDH{!2@=sCI_he2c6l(;nOXm0$Lx~&EU~_9CT=ufKTTI55@zYmdE*f
zK-Hil|8||a&i9U;Z#!S7H9iM<q!G07w(&7TO<HG-icFeIXO4>0>$C~Jy(~vOyEz>B
zw~P2Wc3wm+*Y1Ji;5TUh?-wReY4(=Cg8^KcUE=R}29mUV#XtQJ|F%n@Lk~e`LVJP^
z13Tc|$#VtlmSeEod%SL%Pj3XHceltLuU?zGpcaX5uZztONB-?5VIccEKZ2crYQI0Y
zTt#!#U$9Fq@plM<UGj~;15_TSSzdGCpMK1Nf7`d#Z~QHwLrr{pS!{edZ-7k4=DSwV
z0hDQ=jV_*@2l-n-7gVP;g8bSF(hSPQQVjepdjJ3b_wQx7;?bO=!olIutfRsRiUI-8
zP6qzge9$J8ZWomb&|z5>e%(1get2{<cy+q`{sAhBJ)8eC^0!1XGcY*wZ`a8K&wxV;
zP@hg6mCkpa??JHxN=A*(|1+mSBBw-!0~AA2ud~4Um)Q8>02L{%Z}~ew<u_=DO$QT5
z#PTZtBs}qB2fi!$l&2+m@gol|Y0=_m706!DM)9p+1|8zZr&~t_6i2?D8ZUD}<xg{s
z3MlSCg&tV0Q|HRd5b!1%hP3a;Kt<;=aM6nD^48O!LI{)~_*)Kuiq`ueKE$lnA0T$?
zTmDW4Fyj(`2k1&yP(uZ@r|BRl#HSu|;XK8^?b6Hl;Iam?-Ue#lHE{WhW*=y(7@Pq4
zTRwm`h=R*wP{?fuWv#});Q9g8XcLh4z)oy+ggT`22dLyh)Gy!oJ3vQ4rh)dmgUVic
z7yfNID)MQq-yHa-9&_P*2g)NauY=v_zyPtobqdJb)=T`I-eATz{ti$J6mEt9*bD(Q
zGmOEl3>}r1&ET*F&)20jKKfsuW*MTw0Vx<>Hi4W86O@4pp8fs*KV<yYvGXdpbpbgO
zAkES8D=ZtoH2L%Y{{%epTc8&lSNL>lfJ<HQN@e)61c>?Jp!G4=JbE4fcwGGF0a_N4
zzz8Z+Yc~FQZNe|l;MXhC;M;ldvm?I%=yZzme15$H{9TZ#N|6~J&F@(}n%^;gcH|cn
zf~>;u>18qV?ELkaUqBqx-@5DB`583ByWO|fgVC#3rWaJSeRkp(;OX$`4UzZ*HTVR7
z`(e<zoO&nuyFi<J`Sn0cY|18004;_2?8Gm~0-k;7_w79WdV^oDNQZCd38>aXP&cgu
zF98vm0d~u0egVeM`~o2p|9s{bM4DRQZvh?i3F$RBf{FqLAInp9>wJ41L5>4&HUT@X
z0mX6UwxB(u#$ZRCD4Xct%fkS3)2W(%-_FCYcY=cjbgimSuZRTLWiQWyVqNb*)d_?U
zs4?`JUr-P{C43mPH+1t$&}mbM`4E1+OZ?sJpw<RxS6kWy*m$^4=TVPdrym{{|9Z5(
z<?rhP?~+V;_2ad%SFg+o-_BD$-O?bJv&`hzJ5*i+c1{C0CPCu?Z#X=f--4IYw17_f
z@#*!^W$@{I3_j)7@<h!&kWP`69-Z$dfR@6n_3aI0^y;+%Ragvu-7*(EK%HZd8lIU*
z)|}vPKL?95P>uu#&#AH&|6U#;pH7(%pw%@kKAqQIulDMdx!~J*5lQc%@-na!LA%>P
z9YBvxZJ%x~ukIX-l|7*S>!0}rL{>V28`$7pkFVv0y4AkDULZ$;OaM9Z1P(`*`-0-m
z3hcOxWnKQgBAgJ%U8w2u={)y(GuR!VqnyC?iAS%D1>Bu4H$bBhalR$0yfLV&+NlMO
zPVj;saGcJ5sR?Q+g3SZRC+K{VmqnnGV*)(C{ea~+NG#QS`~kW{8I<1+_;w!r1j=t|
zps1_^ZLa3;Dgk%iMQ(UBzvlquxKEHAHw}F73^>PqLdtQ7^aRR#tD$)h98{n~0eMb<
zlJ^goB`5gXK~W9b%gx`lA5^x2L+fB!OBy);eFEh_@aRb+DF3bT>lHcS+j#<}{ZM%o
z#Ep9(Iq(M9ZJ+oB7(ej~gk1dbiC++DY=pn1n}LA=JqNCV=D?$%;sNZ$1E@|c_X0Vu
z$_^AJzMUt^dZF!EP+o+&?^I1IC@-#uxCV3}LD~dR-UB=I<vLLKgHFHOgAlX(|Ns9d
zczy)$++X+75)ygP`UxC?-$2z*EofzoBXqq0T7Cpo>OQ@o{Ah{Dk05`r+yuFpza3;6
z#9gzn<;peSctp#UApIgQJv!fkGUW=anG&Rg=cZ4$G>8GV>jZ!M3rG~6<nIEVbquoK
zxARn4BRD-GWlsJc&_O1k3_2f?UJzLoZX!H>L8jr)te{hsKk*BQyhO{aD}AwLR*(&7
zjxYBIN3%7=(HG0wkn?LhD8FuigrXXF$&UjAG(UojV!8Qp0xXXA!|Hofc~EQB10}zL
z<9yaj&>_X(@B#7pyFty7m*JrJhUeE0u>86KbfJCc2hW2KSiE{`7(YNNyx+I=eJl_0
z_kd1R^X&Ze+8UZZeL<%cAM`x<n8lOvu;Xp*+b_#<UUPwtRsp351_n_5=6UcDi_>iz
z0Z@IJ2r9}g57iw9<yoK3(;f#Ov)tB^@ac___~3Y38+1_!fBSa^1_sbYELA+91337*
zKnoUMv);YQFVArMrEllK@|E!Qrng`4cS$fZFx<TXvc<1gM!=)_y#S~LalCEK-)avo
zz^-}pRw{TLe8%Fzc<y%I2k<ba<-gmSx9dJY#(*I6@sPIpYXdBP@_5Y#@{<FGe{7-t
zIgQ&t<^K0yR5?Q&e&F_tstANz9dBEEG`|x7A4URcuYk{o;R0P=0|`ISI$Ouv+Al%p
z4c&fGwG(!x3QQby0q1Q?Z~=W76lDC}pmB}6H($?zm<JKd`S<_--J36Of{J^2)cb7U
z_fw$dct$1$25^q|=?y`uOfT^F>;`x0K>615;6oOt+d7=Dt>N(j%3nU+(!QNHVUoU`
z7jM5TE5Cc=H7oc$JmeH#=+k))RN0*b<sZLpnG;^UHsDemT-kwAmD6n<Nw9hMJP$qt
zS!M`HA|i~aNra1$fdO<p4k(x}mLt|9gU+If0H+U7&VJ2w_l9RPqP5Tp8u9=S!KPqT
z%%D}hzMT(|ayraMuWeAv6R`Wx{2PhYzk$U1*QfKY$HAv8w{<i@-Yt*3|DwtV;<a`6
zUsRRey#e+O3+VhHpH5|1k?sP@2X}A0MoK@>^1-+B7ASu>-PRF&nfLGi|JyIBHh^3R
zI<E(07N|{ttOnEt_UTjtrz>#9?-+L&bPEq?4D9ZW*NyP_1_^3`QrC@_vk~QqPp>1q
z{=dcqZf}450WN=hdU?z|I)6Z#&!;}~3#7B~_sj>K1=RWZwMp6p?_L&AYY%#+ng<KN
z-l4J_Pz#5ZU++m(sZTeDe<#lka4BzjswUGHw7&9G-APF0!2+u089aMs7(9Dj7(kXt
zgAC%=yYZP{zyowBNHz<9TO=a`13#!CF2uwDI^mevqw@yjU^;J>@+tg!7x>#i?SGJc
z;Db@Ry?a^U?Gn%dDWCZT6Il4cqq7q{y20)6iy+HlF8=XAo+jaMxd`eYgO_YW8so2x
z5dH(ZhXLfjOsM~ESLLDkFNu)<lp+3mfbd^gEWh5{DzL-TKJyEpcy2oA)IC|y87E-*
zNg$6wJru$65;WR8p^A;aWd^v_dw{<SwCWsmHp=yvpye#!_~X|*!rum3{RnmQ+p1Z<
zou^)!f~zYRP{1CB$-m|AdH^mePQ5e(*IS^H2Xww8=s*@eP_wifbf(8k4N$41ccA($
zXnc!b?+kyt7+B;ae|Hn8UBV3JUE=R91X-eYn!gQ{I$vG{nK^-9??Dw)NgOD$LiqKb
z@OS5d`WDQPCJxv=H>#LQBtd@W<JY^*-<=DR2aS({Joa`1zurs!_V1vvJy41OUBAn(
z_m;og9i-|3SolEoa*(1nZjjKbfB*l3Iyj&C1tVF&x#KV>DRplJjTZ?0|NkF(e#E!)
z2&hj3o6~b;2JJ`4dGy1-mq*2?^ELQl8_N^?J$E4O%8x#s&p<t^Bo+`U^x6Xy9-!8i
zPq(yRugFc1s25m{$+z<qzuqDKHqhZmporiEdA$pClK?npKsqP<J)l0kPv<pI^J+UJ
zhv<NF2(-_m@x!av2GqFv%r7ASnO`8E#jn=}Yz;do%Q*52__Of0b-}Vr2{<FmXn>u=
z16Icf$~TVu0-h}V?IqyYxxn963DW>NVhdDG!KM~{I*s{T|APk&xcsnmg%p`U0mSnX
z+y?^rHWBPwK}cg7v}eVE0e^Uah9D5(0qX7|g-1;dG%R+5!osgt1s)b&y)g<HVd2%Q
zbMrI5fGYziEcgX{S;~^(IV;DjS4IJAIFvVl@|YATJ#vClMprec1=1_?!KYLEC1{i#
zl)*sbGobX})d$IG)%RY4YHd(_^XnbvZv&n21o8$e$igY0`~^BV37Y@l@^AUOE<^Lz
zd(a>YSRRtU4pc$%R~;z-yaXrXOGx?aI#}che^=bU|NlX*><$Gf1PywDy91yZN@)8I
zlpotb&B~XcLq^jk@auu{lO-rW>4EbTXbJMmx1hWTwjUy|1Cmz)%Y)9ueR&jY;eqP2
z;QZDGI)morPO#kvs&9gFSNmeHinsjTy5MAVlD~T*C`*CrXK;oT1LeNDzo1QlNZnD#
zIPCjRe0n`U!1hBKF*7iLPX9dkfW@P?1k|1tk@n~W9abymV|nQlzd#xXe-Ef@=h=Dt
zwVQ9}1yIY^yO)L0xAOw@z%UQcfnkTrK;6KTRa|M{%mzwo{=Fg$pZW7SKn)ci%S+Du
zf;^HnCBB`9eJn54ZT0PSV)W@e0J;j%6LeT|uL~o{R(WJYZ+zkx$mig1n+h5$1;s>H
z5EBFF6nJ)z&L5xn1^mG_m$#*XtEGO3swdzB(N0!1_;lU?neM}Q0@RB1XnxHII$`${
zzhD9fe=BG}8@x5FPyy7)_Fy~>N?)J(^En~y-_M`;1%g2iivGbb=>37eg#k3$z8f*i
z_u3V7A5iBFM0kK)>%jqXKdApwRs!zJfX<M+T~+1ZD+3LSM=U;;w?JVbSd-`5dC14|
zR^3kDUT17!p$;<Z6TbjBfFFRvqAWKJl<GmIo~$bW#4msv5<Q@hDAPnby{-*3_i^w6
zix1-okncU3UkiW_7=9@TI&Tk@-DX4jiwF3-Kou9Le^q_@CFmkl(0QNW3ata8;v_g=
z-&S?{cHVd?393Ut=g%GHZv$0?AZPJ+y#nXB3ol=T(yP1!11P_N`cze*<IWH8cV~h!
z(i3oY)H_fOKEwA6fBR*Kz)AjYPmugB2=@|ycRt7xeo&pJ1xnzMbK}5OS{f*sRfT~_
z{%+7ob1y+-#31*8G9c(6;oD$4Z$o8IK+HT){W=Ytp>{y{C;7X;(<9(a1e)P|IUgc%
zpn3@?J%AOrflf*WcP>GL1)ul@BRL>-8z_SLyK_M~5j1AUFVBFde%ppxzrBOkZ;+Ps
zC!fyepf;!{<0;U9MG^;y6ngCoTG8OqE$0bop+aT7z_Orv4wTaP+d!A4fE)wMeajd?
zT}vJzk4_oTE;s(3nV<oN&g-D6ZXKw2_v%Hi>Pj?zfbuBF8phKgd!<1{Hiu{Deb0l>
zSv(ofgZS(q0-WP+@V8xs<h7IhU1z}co{0uXH>6wR$#@c^lo3RDf^#T;JE$B4rA_{}
zop7C?=7dMD$qz&YXvW_PI;9)YfA9hA_rn|&Ob1WQyxa?#Z3lHbpf)Cgg9TP020-_l
zfE@;I-xC>npzDM{6{AO|%nM&o3j~xyd^)efLl3obEK$H7dLEtkJq|u+@nAd;%BHZ=
z>PA^LD64>D>Lh;`s1gP(GXXmi+)0A^1#9S)$%7I+Om76Z?lgJf)2a9JGN`(cX8`4A
zkn=&gn7<2joGXY`ee)&gpg~A}KFr?+8a9L{m$&@jN*Gj)Lh30{6*~oz<KOakfhIXY
za+5*%0&(6YG(X#d^6Mm!6u;gjcz$k#2t48Mk_Fd%dMEk2g+VGaAQG4OyFojMAnrNC
z-=+@A++CplQ5vLz1PuV)uF?k;WBlEql{PPLK>P=lw*bjhsenlSZcx&CSp_lqK=o-z
zmX!q=xfo*mf$D3p@gT5dyDvoXTmEkFBqyk1>9z#rVqr*m^OnDx6Qo}iYlVtDUkw@`
zYJQ{O(Rt0M*Yg2<j0iL@-T47>4?qm#14MfE=w|lm6*2Sdyy0Vc$)l4+#iQF9d<O%E
zN4GQh4h8{_ZfEcv3=;f3PM|v&bW}V#Kitky5qO=RHo>>^f^X+#&w~$GeHl+U-qvuu
zogr}Z<n7mxvl8##0QKPSzo_B>jr-gHmBrlxAXoS>p77}u@a+!Z@aYWT@a+x|@aYTy
z@g;mZ10?)=MWlT!FY)()#`Ar^POF>d+Z)B`3$EQ*y?bpK{d-*)A3!Yx-xL6`m4_MB
zrv{Irbj7oP*x(Tw30Qc8cz18S<^a*4^7OX8XXlUG`4Bg^g9?C~r(g3R!UuGGEq~iL
zCI$x3NxiRGZbI&d5Q7YKff`yMlU~b!Nih(4_Xg_u#CJh;KC5pp3*&1xQ2!rvWdVzd
zNAqh1(5RPZCj)4Hn!~fxfdj-4@a%LD05K#yI~^qWTVp^|)}RgJg$^DEAG3Nep7!Xr
z^y!X%0BRKYbO*oi>306$Vfopk+xdq_XY~V*?n(}yP8k)S&JYz2pH3GQa2!f_bXLFc
z=&ls-=&b(W(On7R|KM-wVrF2tt)l`NGI87iD!jn)nv3wi4>*3IQ3gNOm%nWb_+Vz_
z*gXX*(YpnpNx`>Mz^6Na!?!bl!>2nyz_&91#Fy|zj$P0_d7z6?Eicv00L3n(dBh59
zd_4eLhZMITz;;67mH|9Q1PbrhJRlMlzqj>0km3`R6EWkntO^{L;Pn}(@d-N38Dtv%
z_yl<o)Zm20r%yK|K7BeFe7apg!S28TVhH$jItYLm5<Z;{5-*)W<w+G6e+y{*^XBQ-
zEH_W5O#tPKk05{De9ZznGW!0D>NzjBg3A_Ai<JSA{@6giy?yf}JpBnl*l80$<7J>T
zdSA1FhFcvNZl3h*y!<i>T+V>{?-2c<0a}osK_^dxbbzJ@UW<Uz|IL%HdG6jq#5YK{
z9eA!8GM<U$eiF&MH(w*&Pr~0V@%R7#m&$+s{|6s&{S;==Yi`i^;cZX|-#iJrpX9)w
z|NrmaxOwvB_umk;kWvk&`ULPe)y<PHmx3E_;P3#2ALz7o<nROas_(+XkG~sqe=R5$
zUxK<>P!F)*JPq#e+<s9di|&4edZ@dqAHv<l0b_v<=-v;KKLv`ilmGtzzj^943p7Bx
zkAj_g_r}XLASI_kqimpo4VdQF0<iQ669I*X0aVl78!uhK1-qnAXCQ}9C+O}QM+xv0
zIr#J!aEkBt0-1dBCFm?`<nvvS)+eEjU&yn9y65om3q<=4w7k!^6WYFG^<+Hdcw5Wy
zc9y{FkhBRXtve(+P`Ww=D%MYf66=kdCqcKRfX6Svt^?2P+`S2Hq(GW@pk(a>Y2vNK
z)x={3H8U7bL)vw$o{Z-mZ|ghW&KGdJt?hU_8&WE_tpJt2Hz4->2AA)k*oCBD5DU3H
z_vl4x__2C2o^-se>3BO6Vp2P3z8kYV;BRXK*?^qC#E|nBXl@5&&ud)ed#}ll*IbbC
zdyqPm=3_nX@snz1&{|1&qY=rq&=C}3;sZ3gfA<C`Ho*A<bXq#3wgr{P(D;Bf8XtlR
zXh@?G93R*kjnMdjv=muA7|(-?UzFIm1x)~;Yyj$AfqV=)8y`f2(~kluPQeXtBp-om
zXK<q%GyKb<K)K>I+2yfEugMGK@CP+NJHbV$0|ThMAW+`!c?r6!9y)#kDKGJtx1e!D
z<ns2^%VGlM?PAbu2afXg)XSwLmbV?C@^&KO^48!lw7gA)swGg~Hh{~cn<pW|Kl0%8
z1PVW*%iI5d|NkeYy!D5=3s-q750b}U-tvHykY3(~g3DX<ktuKy)4dT=&?bT6bOLOC
z9kTzEoc$h<{d7Jg?Dv50SBC8O0Pk0(+I|meIS0pnkC&%GtsF#q;^l5sKI(YHG01p3
z<oqAdLRi0EiuZ%mlD!|K4$FR!8k+A1sU>?qNFA2_ARzbR+Yj=x8Z|yJ&R0QdPk1!H
z@qnE0b>6e{I{0j_&YK>Z_g_rk$OJhk?ihcIA2S1kPv;NN>Byi}&@L(#{C)DEAzaXn
z<cvQ+tDOx%`@apqm&|_j=)C&E0i?a#Ma9CW*Mz~>@;iSI=uQ!j&V!)wOUv*4ed0_E
z44%DtjG#Mk`PU!z?L6YCc?Wb@R?9;0l!J`ASFZ@WEB`ia{%uT-7Dqc=R5bWo6PXwo
z3=g~(b_Lxn?83i|hso9A6n|?JXgH|(0HcTH;nF8Qpi71y_;h}C;orvRYVnf4^)@3&
zmnY+o*W#e|Fi0PpEB`hf2Cyt>KnHX~v4`d1@+Thr>rZ?1>hObo^2wv~<%_ZnObi~H
zF)9Y2<;E6_{H>s>!K0T&9^`EcP_Q6EK?B_W^yw~9(EuCp5wzskr}NVbLy#feAu1N2
zPI%|X7m6F07$8fLkAtQo_c1XrFo4FW7(ng=1y|o{P)E8qjnTLBp%4H1)4rW&JvHxw
z!v{2A>eZ{G@6{{9&%e!;!37*Z2Rd9-4ES3?w?-KrcrD_>zb%FpBqhS+YH^vrl^e7I
z2pU3<!8a+t^zHoO!oN+-)#6ZTqTvBg#-Fc6A?+I%{%s<l@L^#D$+^P9<^?Ehz~1`g
z!T9q<+<Hj3XuRb4|Np;l=SPq;LASNv067d~GQ<KVSBpa>^Ia_t74HWb;NNSa0y2d0
z=L?zjOrWIU)A^9UmjiS}{XB^MzMUU@Kw%2njsqGK0wn}cTtcE$3lwQBy5PDW(tiON
z3leMw^}c+1OLQ4L7=L<p-gvQl9oT}JD38vUFWdh9{|^ck6$97KL!dBe0^NKKx~W>l
z;3a6a9DM%Vg@2omiiT_FD`<NGl*F1rtCPViZZ%#m0WEUv{QL3-h~{7a+Jo`$OVAb&
zk8U4u1cNS!c38*606wpE9rVOFkLb8~=&ZeCJoH3e(2>1p`{zLW4?w3R`g9)m>^u)T
zC9T5a;(wpc78Ouc?a^EG!=v@TN3w&0M`w)+2Y(+6C>!?H{Q3dn3xL+Vb9i*us0jG<
zs!01-E`jLk{N>SY4^kk(-?Irkum97t^PUg?`V+p4Khq|_)baNn0<AOZ%~4_W=sfJx
zo%0TKp|s39(3Rc%>koj=@GJK2wPE*R{O!WOO_+Zhzl+61{#JKTp1ky0208p>#6gKj
z7!=H{y5P)th|$CH0w{Anb>-hC=m^TSM?l%~k}u;ANPZS{<ln|40G0vuT|Jt?TFRez
z^@@B0<vjro5Xr#^@}Go9rxkxI=q4L}c?OT}IS_w#*MOG&_dqz!Yrr(4NAn&iqr2w*
z4^RkIcytScLW9GjGvxFS{+7)kUw8g;+zZNuj(b2uBtHD>FZeS4f}}?uONdeYeW1HR
zJbQB?!BYYc9#C=x2Tv|Ec=)&Rcb@9-Q4!$Z#tjOhe+&!^hL>JTLd<jF-v$mJ9${CD
z)BLTVl~hpAg2LymEB`hwM~joC6^7uj5t!i0zl}!-8aO9Q6QOF$Ux56=;ngYg>?P<f
zBSd}d*RAsm5oi1@pz7I~e;W_`%Q|p-$FJMu9VCx|9lZlA_qr7xe~uO>ix>O!=IAoO
zeD2q2^31dI4Sz5A*3s@56^ONvHRcSUC~FP_^?`a*Kzbml&aYGFTTPH>=ew74U^!2~
zu@iK^m#f9;;v^r0Bf$2*Wc?4?4t1Jeo&l6<nnBYuKHWO7#0ODx5R~J3Mc%!917bjS
zdDN(IcywBTd(x<j%|W?Xz^C)=%hh0CBf<x{eS%c~d2~)u0WGueNcK<w9c+H^HIq-T
z31}@a!;8*UObkAn-#uCn@V8{LFfe#@_dwKM{OQqp611z*fWL1#s7m8sf6k}Zh97j%
zx`l7&cTjl_st+tYT5tPye&BEU$P7vfj@>-dI(a5QqVjU-2T;*r;M1$Z3CfEgNAUOX
zurPp!nhe1C6D-yTnuzoT<xk(vSHAq~ulsgh^VR$Zt`$Jj1zx>6=6=0A;@zbTj@_J=
z=Q>MNbog62!8X2@g2!)n$y5f{ZkdTLmiPEuKf!b7<<e)}J}Nq%oiBYmKlye(b?H`c
zv^?X|`INtv8JxvE8GpSN=9g#aHkshsEi(zM{R6mO0p--o<<EWj*B|#}{9$<MHFLMl
z1jkMtga>^zYg8;i`PYDvzx6dJt#tnK?fmD#zaA3kUcEf#pkTD{>9rAucnEAKDEu6|
zd8Q)=7HGK5!tfH@KaSlz6C68vro%$>y+`vJaO{BdJ}BfE`CFDVF)%<fIH<m70L701
zw0!rlged3lD`EsKuuBD1y1xAD&-r$q_XS1zZT=QkCeRLA6MMg27XEI&&QqN}Dmsqc
z9G0i}TTg<EF{JQy>6V%1+AT7{)$%fbE2waRISd-UAACVqZ@qEpmT<AW$=|9B)(@(G
z#USMaIDADWx>#Q0ZxuieU!U$86$78nSDyUquX!;3ay2~gnw?*s!Ks_4!Kss{$+P(Y
zqmSj`()S=oH}8Q20e>rK5wb_;!55}0uvSH&@%=}j!~_m?(3Tuf5`xBmH>XSIQ%B1)
z{4IaMyK_#vbUvE^jb>2%H|K&K|C+_In`fdUQY5|ihm{4O@b~R}!QX58_y2#W)|WTI
zlOghu`Wuwu_}8BU+YicapfGmnmhkL+<Jips3Zj;~;H^5RTsrT8(gP@9npqhc7<~EH
zzcak#$@mv+{{+WQpQ#M6uzu&=tE1v!4T;(MJm1czFGc?S|KDArqT|?k8sv6o9~B)R
ze&@5k{La^W`JLaq<OY>f-7z2qr$BKBRdCFg-}$@`zw^_Vplg)DaR3frh|x%CtQAzy
zy_^V2+@OeZ>AVTD)dw`X-|eG<n!S4!|NQ@tk}0nJ{{R2wGtmATP*d8Xo8zU-zyJTi
zXUo2H2f1A1<>Ej8|ARwm-Jk#eT{@q>oCGqY^A*@l&_n^2kNFRhzX{$TiF*DY5$y|T
z<3hmW;0q>?*8lu{jNmqg3~1Jn!2{CPkWqnDpxrSl0-*Ys17~{!bTujXsyR@5gGa@e
z@h7-E1GQ%O`?i5<UQl@k8eRuCID9$}d+@K9dFRW&{wS!y0jp76x`n&>T`Vv1x7sj)
z3eeZmi1OT}TV}dTx5#8roV6;z%d-om&wM(cx^@dXf^zA0a6$z&HUwR}MJ9sF43PMI
zcm}&r{tVXC0PQNwQ4v6DYCszOHjpsrv{9k7&9MOF^Uj}+d%$fD@aifb{`KhL1Db*H
z#2Y@D&=v<Gd_F<i8o0veJ_G2&Do}xq96qJlkj91}D1RY^PiZhDKV2w)1&(H~PMdEp
zK`RqLZ46MPLF0+P<>0^n|DC&e*k5-1`~M$Jw&XBK=JiBqdFyC-s(7Ohtb72a1W;SS
zv-2H)FC%Dnxw{6`zOecBayqz?&j5<Q=0s4oLf2Ch3~FDjffP;f`T&#;nn8QPLG1^a
zBS9{B3EIu)*m)YP0JM@2L%}&vy8_g}_y%GSYG6RiFSPbV1f)NG*0b}9Z|6~u<O&53
z@R8FSz{h2G{`AoN`@(V&w08~a)wWoI)^&G2K=iL2`1?3O>6m~0aSz599-S^K9-u<O
z1Jq2=@a+8I(RumBy@gERX+;O0ULFQt%QKMm79O3)UfX+g{`T!W@5#UZrU&C|-_92v
zowvX`J^0sucl>{?^+08gN3V}51K6ZnFQzPHV({<fvG=t+QxoCS`Onw#Ox+&e-bzNF
zP9GHuP)oA&w+H|F`#!xPvJ4)YzdaaV`*dCc%|04<bl!CQf6b>mM8&`d)ca{Y;K}cC
z%a`Bt=j(QOe0cQ6m@<Ie4{`d<7s?=~Yu2cEfEol2jQrpw-yXd#whUme`gA_<K=|BY
zf=73WiUZgKo}E8H=b?Z)SoarzydR?C0rtel7v~p%denay`CCBi#vp_1;A}-qaO5Hf
zN9zJaa70ouIP_riLm1&94DyR+jfw+!eH1vPK;8v;?Zx-`Ab<L(XuK$00Ik0xqOo)(
zam*KaG{1=e^(Q?#dsG&HvVP|j70_A@pU&exojod`VP8<E(kD4V0V$P&mdIU%Y<UL{
z_J9u4fbV&C08L$k<HN!Ov_nva)1#Zg!}2~j?)ZByfjXG{>yLPLp7mgEfm-UKqVU=q
z;eVZbo}Kr7Iv@FTw?LfG?W3aL!M{F~!Gn1USPM9r@^^yH4D{%BW$^BmvG=gN@72lj
z4z!r>uZQLRx*a~f!Hgh7Iv>K!@$9_s*DC{FLkdcs8eaVCMXq`E=E(i<=>(17@UQoU
z+u*?r2@$YOpcJg((;cH?z~2d4SMA$*-K$qe?j>lo%LK1pop<1r3hsbffH#|acyzil
z@VA2cLlZo@TfkuosuMtA>(TA<;|J(MmrfTI3xp&nasU3|(fpp#1H1|SIXF5_KvwsG
z8>OE7>yMy@nLDUF_UIjg;RPD|1BKB`(Ap|QAb@%S(B2wqGKQa?KVbss44Y0L6&{a+
zFBL!=YE^hZywCgsJ}Nw&At3QrAn_Ook6-WBXMO<}6`nG2(E8n3hd?W9W*-1wZ|%{1
zMB?xSe!a`(s#Q!S;-JN^vkriky0h|cJMj8p%Yl;b{PGO^dIxuaI{oDrAX*JCK@3v7
z0MQTKRtUPPHWIY5?8GO2fgp}D3D6ot{#l2>3xc2)g73coT~rIUPz<!*iGS7s&~m6M
zkd>bggRBJIR12{XbZPBv{@DjWof*AL{Id=zUO1dKq4PqTDnm`0EkjL-N#_YTTLN@3
zrL*Ay(AAw{pnEY-@lQVhI_cf;0O$l128NP*pTYKn_M$T|lpI0Qs{^+0Fr<G0GC&)8
z4hUo``vJ}q{M$fgfhuDL!vl>E|1&c%@J|5=IWR!(1_$jI2ibZNYAd4sbz2iOx2)lK
zTN5+`Sf&8EulfE9{#l3azu<?33_?9<{;gc5%CgiNqVhEpXhRLyg=NB^DaOMf@z-3i
z@&ddL2NXzPBNZ<khFl?i|HaKy{Id>#Rvv*gfjrQ1pmYm}{rVH~dMV%5110PpmKRGT
zYFR!XPMhG_&FInm!?6CdXD81A&t^u(!w?ap(ifhc9UY7e44_a&xEH;C2aPC!*0nHr
zbe{I@Jm%YZ)}y!TKYvRp3j>2M=m?`;@CZSR3P=&CY-~Ni-&e`Pz~I^KbMS{JXmQ_r
zQ1G^#1eE~2g^Zxl1hCrX7mOaAjGmn*UdwxS`yBn@WBHN4|0q~3sAJ>-lJ6~K1T83P
zJy3ebr}Kk{<_C}FA58rHpp6C|n%_MbKf4+p05`aAdGuB=f-Z^hXgyHj?b{o{=*Yj#
z$k*~Fe_t9i14HLWpUxZL@oLamy2Ytl*3OHd15Ci3$P=ZnJQ;5|@^52s>@e_bKE&wQ
z;q>3r^0#m2jnb_?-92Ehfm;Tjd^$hAnDy`ffA9zlYM%D!yx?*11%FE!cmx96lDzn$
z^t(qdi;z!m9iva@8gS|F*?H8*^1n~#5B@$+P_M4_ZM~>R=T9HapB~LWS-_(L{QcRW
zc6#S8pI#no56w>=oflpCw=sgQMDbue<#F*B_+s)~{M)!(EDqLjx^yr(c5pg&p77~a
zF$RsCsepueTsv4)K;rz{cvK*x<|pd7I=Dc>Ag)(0kF^W`HcpogMvu;)E*)H;Sq2r)
z=C_QXA#l*F0kcQ14zsJpsrq-Xc@gQuqw^wY7@7OOM{nSNpI#YZSBpb6uRJU-)bqG@
zaD!w!Tp3>P1`Xq>cv@a_?cfI4SmMdw59&^UQWK~eW+<uh=-vYkSf6foPf!At011HP
zygEgWgV>Nn!p`Vv3EDpSkH6>0zyJSVyZiK3FnaWYPWL(n4ak1bs%4*UNci%%f;z4q
zjQ2bkfAeo+<KHH1ae==NwEw3=tb_R_Xeiy&@><<0kIrKtlU{<3PyyA279Km&(;xs8
zG=^_II%`xsJiosNo!|o6Ci=r36!MyfJbE1&K||FJKD{b}ueCfFU%B#cWA<!5%m|8{
z=A*10%?DUr__uMnc6k5ywY=lf!NlJJI+ekNe_OzR{%rz|7MJSyT{|yy1pIgD5OD0g
z<kES_g@2m^lMDYg4`x@36Lo?voyT1|JeXWM9GG1@PdIk|bhS8C$L-SL@ZY5)fXTJ<
zf}_R7TF#CDW|s~Qm(Eiljf`L+mky4O07l2oi>?+Yz}xxxdqH=C8(wm;VBnv3$fGwz
zi1DQ-sNd0CqvF5>>gISLJYJs+YKd8Re1GZDdBWr14||V;znDBU4|#N6_3UNQ2c<6$
za7GbP;orvL*ukUHA>h&L&*;(l;pN`H|NnP>@a??ta{HhE{|&!^vTJYUe|VO?`{)1v
zmmZ)le0PkBg~xFh6%7W+d1xTE0*DO>Y&3g2FMyhe4lh!E|Ns9IbR#j?XwWT9u)?4j
zWb(V;piKD^G)7?f?d65vi1V0`=l>etfCgwli4b&L4TEQ|!++1tv!0#TK+VG+paKfi
z``~Zs11&FY-lGCql*ho|askBcZczbgf)#Olz+w<39^E0we|TD6<nKAj!oa}a0$P0o
zO2J_D%`X^zdaJ<29>@kzc>*%lqm$jU^Ve&6&+d?eKRhf?@%K*v>-7S4g`j#oJDEH{
zMIWd|0oJSe16=;~6@!LLI}d=%8_*F=hL=#v8&Kmk!n4<%5yS`pwO|80EJ59>&cpnD
zhe2gabB#&_L%k$O%ELq3MJ2$a`3DO~bq0U`7m$MP8Wj(Z&L6(LGXH!ue|Uh;dh|H>
z%HD(Vg2%-l?)=+aco}>ce|Yw?9P{WF@a**wWpJ@ztmF0R<nZhi_5>FajDEc$pr!W=
z-n}|v9^Ih~j{Mue>JHWk`gHm-cy<aSM18s$oGpA<8S1z^It6?>T^W438N7Q##5h15
zA`g#lE}u>&k4_Fy`xw+bjbL;IPx?*p=nZD{>}9zITQ36&2%l~NP~i?*W$M7;ZWSZS
zQ2)ZC*YCe)FUz^t?4V2GnqM;dbaQ|XuWEh)Qo+km^TNaOR6Vy(r?^MwIp0o>*ULOC
zdsIN74z{wB9pvJYME-uz`3;~H1d2ok{+11(RD+Z@;6)io-lLP}I4JTU34wtTZe*|9
zKTv3U@b`drKzVjvf9d-Vlw?8s?cM%)c3ua|dh|MBi^6`;nsELW&^c5d-BZAB1f?pF
zC7`|m#NvxDK79ve36I7jpfr!ti-I|WzYlbHDaiKo&=G(D&@@YitKk!$&MhjSV-9>e
z_o#q2r+6HEzzlLzg%9HgP_V(~=yt#gO^@%dJvwiAcK!qB-_GCA!m{&+N3Y2wP<dJ4
z(R_fzqq9UM;U(x)E|1RZKApFGIvsxabV~Sk9`*!f^aAjjTF>4PQwIOu8d1=cE|*W|
zUso&sI%&{)YLCtW36IXJuKe5heL8=6c76wKsO$XYV!>I*?a^8A!>2Pszyn+!^1E31
zGSmry)~Wh*3V3wBcj4dW%i!C20knwM8JZ4H)^hoP5}N}DXnK!-8xy$5bhJ28<L|@x
z$fKLvv-t?CXRpXLkLCj!9?ge2e7c!@I-P&`Sf{8Ycyw}=*!pxc_;g47@b2|t1*KM5
z2L5f94i;AY{h-zH9-ukRi{PUVJh}y3tz1MI_~(KS!vYt>ujhbD-wZ_Q>(dPhYM*XM
z(0hD;@6q`K9GswHxbw1y=3$TK8kGX3I%A)17nK4~<b&F<o}D*AWvBtD3<WX31*=cz
zOAs4eu)g^I>;Hcb<`@-lSy18Go5Kdmx%YfJe}gih2Ph}_GI(@?*J*or^cFC_obu=Y
ze^<l*9=%TgLDBB<vf}su{~%jE{Cj!+xf)*b=&b<V=H#pS12hs3nk(wa|NH;HXScCu
zZxo}aC8#~+W6Drx2TB#)A_pD$w}pr@z*=61K#dF^%LAoPyn9(LdUOkTbQ*XzALj7v
z4F2I^`P;MeR_WH4@}NWsTGn~v^#hONEs)X}Txa}$`4Z%#ZWk2~?_QpN9^HbVf(TTE
z@NcVOWpK2p5oO@-yAP^uIvG7W1zuhO4JIFVQHcPB(aVRwz@B@#<QM9GS<v_aC~JdS
z9_a1eGFW@Jj|DU%hT7h(LTT@Q0JmX@YwsQdtEFmtHyulRx0r(V?yAq=a-{hP_V#W$
zecQWb*xS2h*xI{gWVLt83AT5O277zAZJ^t`pnb(i?cFlG?cFl0?cFl8_HHp|d$*Vq
zv%T94YVW#OF?dK`@@Rha&!hPeGx!8BP{~Qv2JaqtgLfO&2JanEv(z0_1d-R^O~%>a
zZ33D67SiAat(rCb_VPUZJiC|LzyJToH9k7p{-tgEw~Wa4ZyE0PZy8P6zvTqmzeU5Z
z{rd)7Zw-(3ZyAC1ZyC1sZyBNXZ!wPcZxN;K-*z1BU!+obgtmVnEirnuf7^&^|GvEa
z6L)>l{3ZgqJq%iz3F_~HMoT~=bw0gC|M^>{!dk|cu(XW#p|p(efLps}pdk+E=pSs9
z7u0bD8{G|^r-KZSC`<qkBl}n$<nLby*8CGRIsqRVMvRYuG{Xj)`szW8IH2RPdMuzN
z6rf=N57>Ats7GS~8kF_5{O8m8pTDmTY-o*&1w*}nPv=)3&A%Sae_8nZH-eT(b$;;c
z<tYZ4-Fe87e>*2)7{r6|gGVomGyishG|N+UoN1jLX^x$OofknT*7^17Fgx;Z4`l#J
z@ufL-`Z9nd!9x7oInpdI)^VqG3V<c}w{v*)hA=aM*Zgj0O6%lGbLnIN4Rcs9y7F(2
zW$@??XY}Z034YBAUS#IkdC;R5G+wwp;Gak5^)y$@%k|GadVT+U^s;z^1~|@oG{0o@
z>^$Pp{DR4af4c)ynycmEn&+Sq4!$(kP7xK4&a-K*os6%SIr49JWdMx_fWj}$v6Dq5
z&9&2&p(KL8A9UmaDE2`y&A{IRIu9K*mI3M<fd;|g105iF*gywZvKcba0W#62xAY%>
z&s5N=pw4UH6W2jwVIWb^9o3M~?*|>S#NPs1?GEbEg0(>h-9f1WV*JGy%Fn^YIYu|c
zvPT7^rLM=L^V&=GfB*k`_p;c#8s7Hk<pGaaAdPQ&e1GfF`2yUd?mQ12py+jE0*y|9
zMsp{<)=!(@!+6Vue>=Np^I=wxUXehL<^x<F&BsBZ2#OT{f4-KF(_A{4_**~+5xVei
z5BLX)en-nob%L&)7t%TdKo_IJM|HP5u(<GV_h3tNwLDQL?Am!W&85?WCC#PNfz7q^
zglp%^G*`<*b-W+}kiGyGkQpwPr$A{VfGy3X6EeKJ-GeF3(eh#~H%KI{Gk^(nQo5_<
zLGXA5f1k(y|NjjyrMXxl#&|*JVIhVVKpsE%7c!jNdEG<vJ)|{Urvx5b1&tGc#|&Hz
zPlDLsF$2%eA1^-q{{J65MCil#AGCeJr#FZBpGPlCwMXZ7ctQrJ>`sA~pe_G~-+X!t
z|G&)n^Z&o6<~N^So?=(SOTL{SK!XL)VFKUI)BGKv#c7~n0!RMs#-5fp>ijxCg3dq#
z?eBHu-!9^qW(l34ftQmnyn9&!K_LwuCtyl*><s<~87SayIR+Yc=#658npVFFGG=fE
zG-d!wJ)l0n;kTEdHD?~ZJjGtUEXDlW1zq^JGo-m#9^&r<EtXGn>10gn6ab%c015*O
zkfxV6K#lBgFXw=VlOgN(Q0B)P-+;%)n)iSQ;n2pDLBnUDlE#6*r5ZF?+`LES1ISeV
zmVF>@cMDh(C@X=c%vOQLAW9J9$s56A!m#mV@Mt7>Y&Z!#o(!@9H1Y>B7IQqg0<0G?
zo}9#pJe~~JtN8#jo*a!do-E9YwY&`Q>~#Sxl?M$YgT`Gz1Ii8_paEsjI(krg3V;qM
zJAek1JzxXM5&Zq1L8WVVjfw+&K=}dYfbw=1Uj`q>2cU5rk8S}+{_Q@Ypy)YR$K%t<
z;n;ZsGOFy?EAkW+hKLbmxH{A(HAvW}n<35F(#IA1n6d-Lm~sH9u#ItLfDb8y)|-MV
z4wUiaG<WNmPzF$Wi*rC3q{Np2Qr;qsC@%+<v!HNC9#M|x@81g=LPn$x&^g<nf)*Ux
z-3;K_Tkzx<B$^>3%3w)oK?^n#I-=~r-xK@q|9{WUD=)z(sZa3e1&t?P0VhP*c(MmL
zQ^RAh-wrhP-0})sEl+_A`*uUdzCi^r#M+B57Ci(Pz>P;hX&z%d8RQ85KG5NIAiH7X
z$sVBb<Oo;8+diEsDixqXWzd-!u)*XE*kCefFcV`W`46O^#vDmb0F5Mjc7A)g9(2%g
z=LHW?e)ss{(P`k*c@A`cOLql$9NCe7dq^z<=<*qGQu^i6`L|B2^QsGI<oG{iIJrUs
zw4uB67pOYs^60Gi;n7(j(0MA&(eedoF2h5@r&GYO^9A^9?EnsEc&e<81r;6O!D9~&
z@cD{0kv@z!eY!ytfuJGdGq53Jk8UoHPVXPSmY;n(nM%Aox(j~zfUmm<DFxli;NuHw
zAn^Bt%4^5Y6P*`df{sjf>^uQB6l6*5a*u9~G)K!2Uk3hp2l=<1^yu~BWPCl*qq{~W
z0#U^Kbb|u8dy5J<fN=~RCot6+fCh0BK;?b`;c;VrPzAso16q*hqLP6$Zu}T?+}Hs;
zZoC0JZu|r`ZtU=K0(9Ki!M~U18S=RC189Z7-_Z^#zmdj`xBHYb)H#DI1P2CB@YwP8
z5O6~ZGHnm96dvOoJl^oq2yO5fl!`$mhpXX}mw%vx#}3}TJkO8^kGI#jGNd_L)`T+f
z_k9En-9Sc<K?{{Zl|lf>fR~@aqsLEPZu|BBKgN1v>b95ff}6Z#wwD)yH51idZWw^}
zavARSav9e4av3$-%jJaI%SA)Gz5Mw$xVRoP?PbszyU6Y3GD7X;GF<KDGR*ceC~aW2
zmy5Btm)k(?<un&-lrdrx(4q*WI_Rwj84c$5pz;#bIwGdQ?DH4AP6E_m&L-4g2A%DN
z++g;FHkch4VC`kJaRpM^%bPnt`E=fRO>BF)ZM3~Sh}+9$M7EdFhM-Z}%UH*tDQho-
z%3A{MWk`8DeA>%J*T4nvkZv!R;chR35(#p988r8Sv%Or5(Oxd1sJ+~dyS-ctX)jxc
z_%e7%p7dyb_|K#HAoIv<FQZiov}`Z8(X73k4;x=zj%9p#GRpY!0dSL-%=U6CSTj-W
z<z%GxGBZ`imp4Plm%A~Bmz%o<EKk+3g9bq$L(8CBN*Tbz%iW<2prJz02%KZ5pksF^
zLpO)z#X1g9pVgP48$77Y0vc5AX6ocZj3{@<G9azzg$ylEMqWP$8DC~`=??hg(Rm#-
zy8IG4y4;O6y3FFz?Z5&WTYd=|TjqfdErUju!Gj&3fmz3HR|e3yGI&@yk-r~w)(6tC
z@*L3MM>k?Q4GF`_^Pt1ZlR#VEVe98{jxSq7hc`fO0u7phhN?ls8=w(FkIsuP4qpHl
z*ErkD&9L!huU;0=hz$cNW6UgwF=kEB2s3ESGkAb`qDS)q5s&8MEH2$#E}i~=d@Ub?
zN0&ikETHi3761(`gO*Qp2K;dWMJ#x^aJK`8OScCPXjECywezS;rw4~irvndUOc^w!
z%<a<Y@W-VyfWx)(0%$y$vonAPI-1<=!2%jf=5*=g=nP;1trdn3BqxFgl99)e{i)F`
z<^Zj}LTeWP@#tmQ4H`!Vr&>@F?i6?#jc5{gz?;OIv5z5x4jTkFiMzo=$gbcPaoPmO
zZjnZe(c@R%y(|;E1;As+ERLPQe>^Pjdv@O9Zvma6jWDEsH>4$e9c|?J52#t+%d^?5
zmt}Lepi4Icc-VM7Xa{vCW2XT4I7iU<0A$dZ8N3|i<#F(!G0J(>9>k6pXMzTU5hH?-
zv0>El;%Oiy-RR@ROTc5k<c$|+gY^<MUhIc7Ui=?>`A6gN;%=8-<l*9OpQ#KkmV^e2
zVX6c`Yk6U-k3oW<m4lW(tt1Q-cgM6c@Pp<n;Dg1`^Aa(}i`}hbrV?0xY#q~!WBoB`
zR26x&7-{`6ct8uW{un$UOvY$&Jan`eb^S3h<Ha|i1uDpmpaK=-0#Jbpau}#UEjkS@
zQ1P~ZA?uH?yrj=~G3eS0M?B-j-64A!+`DT)NeSOzvE@b3B6V2X7spUBC|S8!9;}UY
zu{?w_P8>?iII$~ioVYt=D}!^lPcH*#hXCjjMaUpAXbT5ykl4lYQ0;1uZVpGwkY1D_
z;%W34B9;M_jU){bgO<y=8X^r5&m}xWJOy=#xZ7tdL!G@x=MB*QHj#sl-62yMFbe&r
zI7f%KzI4GeI?M<1QMZc<`si?XO)G<=WzAFu{ytXlX^Y^M#lJvx+i@2a$k;IZ@BjZn
zBh05jW5eL`0cF0BsPz;iw094Jo2+EEciX_4iE8hr(7U}`hP%C6#tmvLAhmbPsNdc#
zC)D088v5<s%SXY*^B`&Ob}}$9z}vgv<-$1HyP#oX%=T^>T6?z)qrF><rM=q*YVV?r
z1A|Uf_Mmhem>pCo5Yym|LNs{W2{m~2K{YjKnFFN3>jG}@LfgA&9erZkyL(7z@3xJ$
zcftGZ22*>Nz+f-54N``)y$c${!`N(xb)c8T_AdVQ#-R2t_Vvb~w&YN4?=~F(7pOzG
zy^CwG*YYALoglS$u?_V?(^@fld$)-E_HH}Q_HHq_y=xuPi!#JJ(%QRdg+A@tyKRG|
zy*oO-J37AGTg8ZV{V<{N-N(DY#q%I(?~ab|5^C;_j_)#n&X53)roqpb7#-gQ&4b}u
z3=D09)ZuLJg2wG=(%!{?z67Yfi~W3wq1@h`v=v;S4&C-HuEoHk<GV;lM~sf|{{Ih}
z+Z!F<?X6=Ze!m=n^$erqy9^%C-5cQb2;gmU)LqZ;c|Evz9whDE(ed5U@m<Jb1qS|>
z(e(@%``@syXBZvdC3*K7?bb6aS_Ljphi-d!bbObHEpLOUy*o_CcR_~%`+`mi-i&4a
z?tGN>yO7h+$Xw6RP5gR>Or-S;{Mgs8k$67DXUO_pPt5hZhe4;?fsTjp03D4f=m9<+
z;wxw;A!rS+XLl%r2WSzmC-^{2K`_6Y!voR>6#$8PKo;_HfDWeUX7cFd@`0TV;oBVx
zI~w9L=K5XGJ>@?<K=&12u7|B>IE}V`m&2#qfy3AGa1CTVgD>Q02;WY|*YNebp53kt
zo}DZzzMx|v25|kZD|ERTxV?<!d<f>H;NqF6_AdBTQc~9Mf^JV!ft(QmTE7cEvlzU7
z_abDU?{N+v&<UmfKYT48`+!b|0A1nj(;e^wbU3Qzr8)s$(6Y0DA3mJ|o}k+#4*7J0
zZc_J<@U=WqC+ORG)Th$}bi2BQZ|4c$&X>NHhw8W?XJdk{n!n&<c?vXi6(Hf$$>Gy^
z%BS0d!_)F2==4eskIn!N&(4d!@HM=#;5EEHNM}KKQ)3M;3zj7fKRkL_etUF&hbCHZ
zV(k=o8IM@h06MA+auUR6?5lXSpo<zn=SEuIsPpguuWA5o`t`6pRm<i9I;I=G-xsv0
z4eMc%{4I|_3&cPNPl6Xm)b9ZA3BU3BD%wikPoTA3y*!`2dRabubPIxx?*yFy0lMVS
z2eQ|9CTL~YaTgWHT3*n_?uOr9?gp>r1)a5tzMdC!wkl{fJLvFLwDTW8>mfng?mhTh
zx<QL|5$6e?0dbMej0K(lumdcHexC4Q@S0rMdR~wvpaXM2YurJ{sDo?(t-OSs_=<j>
za2HrFVm)sa%J~mqy|D9ybCK5bDq=tXfu`pP`**vXMLkaVDua(DBlzqG$iWXj-593{
zdv^PPR2@Va?u7_;Gk9D29L2tz7u#9FzTGiL86fus5M0meZyj?L|9W13>zK1R*7Jfw
z9mo0xP$UlMdBVS-1uV#opi~7)ZJ_nMAcuk0^DdeXE?@`Yd1|1o9Qe-@{t7xz_$q@>
zH<zz9zfb4iIw{Ec58&g3eY;Uk6ZWx0Jx$oBo8QOUmjQHUwFBrp2#?P9KHc!MguNlD
z5OI{SM>oGuH{>K?PfJox5{~!*Ir920gLkjbQ3j80OAkvc{(fap=?ytaSR2Ib7Vx!p
zxjIlM3I7Ehoj}q_!qdPfLLi+aTnAn5i{~WaQc!6QKM}&S+vh7oofG&#2=I9jp4}l=
zL9HhA`T_U;woNaUK;=4Qxf{k|!f!yH0xj1=JxtiUyXGi^r)AAm2L8Ush|?f$fNDbc
zS;9}jr$PLGx#Ab({BF|M`?kRLw}H+|10DPVPR`w+3#s}0R-v?ykAs`IWVVlcz?z9#
z@0*3xK9-_S`?!n~U;DU>8`QY)>_loGgVrQbt9=Y#?~AK_3|;R#nA^tz(Bd0c`}pxp
zaPd7z+Q*;^F%a$JGJNghGOX?6GPL$FC^?|Dk3pwfVziIjK<#56)UzMFK;<f>Ykoo7
zzQE@yA)Wnzqk$ZUXdpMjmqFlYAZwyFkb@u%WW@eWXj8eE_@?r8P~nPbDzC%QRDO=N
zsoVx?A48kUeV`&0-c)`AIV)|$Z_ueY2=}3shs2&gJlbByfBy!K_A+?5m|%MuWjQcP
zdl{66FqTJ9rM--IJutYvjD0;Ys4Y5F+sj2$zy<EGXfK!HZ!e>qJ`8OygAN$M(_RJ@
z&Y%$w4%GHC2`3L@Z!fpwXfF@Y$-{%Hy^LN-(5}7QMs9n#0yLQN05m!ZI%F7hmYrwk
z8Ss!<i^>HC(1qn*|M^?4a)Ivk-2*=Bj)A|$j~8+!2S^`iw6*mTf1edp3}l2yx66ee
zo|Xsrd(3%3_cMI}H<h-ifYmo2VDxBy#puy_5Y*WP+tED-Y_dnEm`CSl&=pNCmw)(J
z9^miy;sR;k2+|JH((A$K(JAcFda3jd=;AgHpH3gp-K`Lp!cM_t;_qYTW?=BK?g4v%
zzeSmefx)K}a#>s(57xsrBft#_&>bnD0VMFPE#MoR96UOY@%LQ<wa$@lZ~`B=3BSR~
zg1?^uJkVYPatr9}KF~EzIyD}eH#|BIL5>rKU*zP$c*CXhrc38--(D6MSN`n+E}fTN
zWcL04-+G{gKh3pM!lm<anrmk$gKOtyu$x>uZ+i6FFnIRr*tmdBH+Jc~<l1@hg&9PP
zU|MG^16Vy+(zWxVBiPJ~j-8iZ2tm~Frnz=<q`7p)GPv?@m+<U$u>oI0<^Vd})umG+
z&9PGeeB^O+j!Fb$=MBfs+m4<0(^UW0r#Uu0W~fPXY<&KoISq8%=*vkA3=Exz(i$Hz
z)TA~3VyNM7`Nzn>kk)#DzXNoma9Zo_3IW4QX_klirypv)#NP@!g3O~g{J(E6ONb-?
zb`HnRvuTcvPr-)%1!;fJz`&5^*!Ua72HjMj)_R-2;}+P=lNG|QhHuj>PdoBYI_lc`
zmcR88=<Zj`i~RjOAO(({44|W!9Xq*vdi@yvdqsR8<4F+Xd^*oL@^5G2Z}t8E|9_fm
z>wo?h=l}ozqdI;e$iU`9OrUEFUmpkGd*##X2D;s<#MknW3;%YBI&EkE?L01y{M#>g
zo_=w#2NX{({4TdW`CUGMj#KotJXCtuvzMg=q}aPx#D{-77wA-Kmrg10jfE8`$997E
zr>23f)8ubq1Gx+A^HN^0`&vPFO7qKuJmuN^f(evGUY-CQw6XF(Gk;6y|NsAAZu|#2
zIUMYn%b-@O<wgF!FQB7D!AD9@0Vnq~$4-W{PG1K87Esvo_d9~lf^CN9Tq6*-y9JUH
z5xdu+r&xB190T=-A=wmks5Hb(k6w51?O6`|J&!<FVf+Tg8tnX!G?4pR#Xv4?J;2}j
z<M03fpmboFX3NmPKlLCeMyDR)JjK85(#w~BLGEuoSz(>l_?w}@k$>v3wAPc3{8Nv*
za(;E?-}d$;=$vA39R06Pvkp<Q;GYh<zUk$Lzo5Q8^gLil8v0+K=3<$nV&TX?{U})L
zO;F>w*Zm);Oz;5ZVh5kj6F72ozuuq!|M^?&IY7l2#E+l>IFP?VWfHgu>%90vvFHE)
zmnNV?Pb?vd`1@XhE(-5F0kH&Bl6AVM1iU;0YPxrWZguM}QL*spTmrsm(Sz}TZ?6sH
zmN(=bj_*7=KNx-k9k%Mz`QNwKodtR_c4vr6f={o>q?e#f<=A-`p8vqv<0dmSr#%KS
zTw5<yXc%5fbF@4J&TA#oE}f@bJ8z~rb~^lV?7ZyKc`41cGvJ?N=b_FEj{Ms_m>l`H
z2e5RWO#^4YMsV(%$Hc(Uc{vT7%OQEt8f13sCH@XKFymx}maE~DG|P*Q{L_!PwmvD5
zcI<r9c{k0mGl0pZ^RZ*+nKZ{v4;KFIr(8N8r8zeK1m)vNpxg<uppc1yA+7Z!e+TGX
z%`}jkML_1cfDD`jGLXNuiIIW9vGXM)*YdaYf;EFZ><`v_iN6Ch2$R-&phC_SRJI&)
z<ezlNwe?a7Kgh2vAh-N;?7R*3r2xbj$IeUqEqY8KgD;~7q6^H-8O#iz^JLO2LB<^h
zna=6jdYiwsjFEw%^8#`SX9;o<)N3C=Y><Cy!NGF?d>nX%W}4**{^<w!w;gDOh?Izf
z0{h>Ki5>s{H~(Ptki69VhzWE~g$Ls&{_Xr8&Bs_hds)Ik$DDgMAK(HN#GT>)d@R4E
zb#m~xs4_8tO6q_=j{Msl{<(HuOml2}2re=~!Q1*6l))T9xA5|}fO?kb38nQjNC7BQ
zwt(`RYv;|Ee?THoElHq^3W}XlZb(VgdIyx7!6gwWGXH>*4Jfgk;%_YmsRf&q31Weh
zNNXF239-KV-~a#6It&qFrDkbht4j1-Ixm0=hnBq{Es!8=eFS2Iia>DK@wZ(1_y7OP
zC;z}jGbq7=%P&v`^Rfn}lD{P!boCE%LTxPpc?sf*Ob`=ddJ7vUenF=1WvBtQ9P0o6
z|L?dH#C|yoqzs~C8Aucq>R?}kQcLS4kSy4%C;tBb|5EEesK5cwKY>FD;@DOjkYj&?
zltK*J2y)kjU10Oi!i8Hu{Q;GMm-st(ff*<HJ9I$qYWxK*^NvEwyd$ohZ(RAeJ$bnV
zqzGhnYY2!1Dnw;L3|CM-+zU!^(2^7+04qwlKx3ky!Uj>W_;f>yo$sIm22{L&Zxe-I
zW0$~GrwTfTI03Y}7R&MTH+(vOzPR@l>EgN!aFyuUo5S+YvzH|X)cgS5qyV~E0djSn
z1L&Ojm;1hhtJq8Y9T_0kHvWWq)3x=IBmY#mKY2l(0yPy*fD#-iFdX=&9!+aK;K)Dq
zkRvDPR@X}}m0^mSV2b#sg0iP0|J1{doVQ*1x7~gj3{wL-6$*OO^dV3qWa<I%z1%NL
zK?=Z$(53S<f2#;6MxTMIhfW_A572xbxO#Yb`0M}wpn}{1G-nAa^Fgg(P~dog7%!K6
z{r|u7GBkVruTN`y46bu-JMvFI40gxq-~a!2UUlp|l;#M!zB;Y(DOkZ(NB-%DTtW3+
z7)ZfEP*Dt#fB3&X&GI6&PV@Nn|9|Hxa61bu3o6J#Wys6zzyJSt1etp#&9U(bxETgA
z*wykWxD*B@nL^M#dYxxoJFnnWG9Ns|UZUawx_sUNbkRU>2BW9uC*NL~63~^)9<2v_
zI&brL{Q2?!zh`eDBmZ`5Ps>mIecM6DgLQuB{Q24q(w=hcypZPD_yAl0{Q#Bk8$mGx
zN}GGYjFS~2uArN{PdV~WI^f!RfZz3$55Ft8=Jm0>P-5fQc>;7~sxz`7rK`ZXs$?;m
z;U&(XlhB$EFm_(_vAj@v#JiWp8<bBwEj*eJGo^vAAb985`H{cH71i1Opz~Qee|dD?
zczp?K=6_~>ms39cE+<|Vf|^?34BMIpVzyr5?{on(PFBc(+OeRP$Pq}cJmAXtz?Fa7
zftN=AL9uYfvGWAT;ow*R#f7Wo5l8;%2f#}BL8F+USq$G^5f@Nn-NBK6yAY^h4{7UO
zbnHC+qPGduX5?>~0?s6zQlQ58%l7Y(HSQ7Mgx2sGo(^49AZbtIGeiM|=LsrWVC^lm
z@x2wG_-fvxA_2N%9@K>c%_4esp7-p$;@j)-pTFf4C#35p08+r;vX>jw=4k<|hjran
zLd8Hzz+E>FOUT{3{5=b~LB*&Pr~}juu>{<t0(Hhf{kJLLD|&sp=cs`7g6?wt4e!5Q
z;P2<;1ZlsGqyH8G%6$Q#7AMHjp#EC~<az{CPDuX^B+TF94(`7}F5msYg|+`y01EyH
z-_B=X*LAw6WPk)RKqu}8cyu1;?|TdK0q8DIhI$#0Q~=1f49J}cEh?abp1)rL+>7%8
zUD_F=65-K#!n0TB9HbYAd<D%7kM39o-(HquzTF(I{M%*X-TAkR_=9_OmtM?k07Z8R
zuV<%(Yv*Oqu~$Bwr$H7*fID&~M?o>}*~?<))6L=8c@$I-B|!CGdXWgxEa=%8%K*~q
z+wBWFO<%;{w_C!c^P)5Vc9HlOHV{R8AVU*;LCaGle7iy2Ix`N?k@Nu`-2y(H5}uF(
zIstU2O#!1vH|W@69rw-`j-9U@JKus!9Y;_t3+j$RdUqZ#K^M-XO#nB);r%;4P{jo*
zv?aidw-thEmPcWY9sX9(l{KJyD*k)+@*MN&mIOPo^IBTtGmr`YK*hx$P$}UE=`AXN
z>W9|1{2kB1j7t@QX_i;{CxP1dpzh*FP=5^6?dJydQaU9)JCFEwO8WG=Gy3=P9OIV<
zMH7Q(w`3aFIG@hrj{MtM;`v)anLiEGMQpLh=;PTkGB9{HALIb_)?Ob5RcH~Oy)0jR
zdczn!x&?eKFMy&jyiU)%o8=0qo9D>CoyWcN^oy%?pooO_^*(`0Okc|jr8hx(J-P+F
zdwI_IbTfh$hII-W9`I;90?LPIojpi@B@JBiwEP6MX29+S_xIlNw+eyV7!2TBgI;og
zs->5^K#IT~xd!gv9pLZ#3hI7z*Qg}G@}x(%xJRd;Pp3S8%PR&32L67K4?%-Cpd84+
z-=YT!J6K-r7WZiWWmpfs%>pFv(aCZhw8;@vT6i?GGr|n@?5$Dx2fBbgfWPMusEhXv
z6l;+FDyV7FvJ=$u5d!x=LHt&BkV`>Ll^3A0sr7Az1*E@sD6RD^Kdc_U^%vaVyHuf{
z*7%p9!2#UgyTm{B5a%aQ^~eb_V*)rWTDz!tKvEU>Y`-)}jTizF1SO7__rOyqE-L?g
zI$c0n(?un~r}F@g%-$~y?%j2>fl4}93DpBG@j$&hNH|=4;avCs|4Ro@@WM*FzPI4s
z-2sRt(B56f%Z<?9T?S|g5GW108lD8*tN|V?2Vc|N0=}{tcDY82$^=lMj5NOmy58NV
zH=hICD7*N}19ZcCh)Tt4T~L3YIYh<7tDEP%XY)}Fk6uvx2zYghoCgg`_*nX=RCs_o
z1)v6~XLsxm?_QQpU(gap(7oy4<nPYEoh7{UU>dlO0O^5UW@KP+LCwcYK^YEIJ9h*?
zx-R@3^B5srAQ#I6;3iG$ZT^-nQ1|B|Xs{>2qw|JuXXp<|S#;U6^N?qEseo^Htb`-~
zcAau(P|oXog=qHkw@d~1<c@$^B;dxvABLJVm(C?BpaVzwTb_U%04hkPK?)N7jyquc
zzol6ob>yFZ%(e9!f6GZm1_u7^Q@~nW__sgx==|#287tt~St{YvdC#-+HK?^$!{4$N
zlsX|rN;u5iL=eNZ^+1InxLbSx+%1L-LAmg6Kfu2|MkT?e^I_+$7r&}NS-XVKw=-12
zw=<T(rSq|G=Pl3fQjX4Bpwgh+rSs;Cs}M!po}Hx(zMY{Qj-9t%I&Zmj9(=JIECY%V
z2L2Y%O)j7Xn=YLPL9HD37jvu7`g|{?LCM_l`vK4}jytH?0djaL7r1NG3OW$Uv$GTw
z%mObXK(bJk{vcg0oh~W~AlJXF2XR3;uSNOa|Nky1@!jeJl7#95CFnGSK6jAR_oE=Y
z6Cj-|aH$V+0)OjFkR;g9eh>?kcwG3mKj?hH-vU~~2yx+lkQ6AV&j&HUN$3+O3gMlS
z1E35I9^dH!sQ{Y?Dk&gFz4Qd-u<kwJIu^OJvITM*6OM~hDxi06SAcFP17#;1cc=UW
zwb#M-XT5m*4Rm=HBrAgM-p=ssbz%Dfx;q_o+qH{If@d$wJ@D1r{Lq`X1Hk9?`Sd0*
zzC8Z})Ma~Hkq0TpT2w%{jit4|b>ZK(1<dB33K4VR-?juS;L7>Tm4Dl}m(Jh<@Bn`Y
zXrV`%W8)84K?myB9CqaV4DKt;`}6-lXvjJORL+BH{eYJ&-$5-*aDD;x8#*DzI(EJR
z<sguVB~%2IJ3uzw1TTpJwNH+>fZJQ3wgkxkkY?l-u>WgRB7C}iR03QL4|r<+^z9Y-
z1M(lJFafvtukm-h0QU^+JbNP;JuPp7>brXWJ`qr@(Rt&w;{?Y}v@w&#pv(qp?}P41
zN^1qT_iv|Jg4+9sL1QN1_CB~Q_OU!s;^5gWa>%jsH1fC$C})J1E`zlB=c8FrV(1Ae
z$w6)Y6Qu{ddsz;F8m6E&|1l1a&afXomXAF<Z}7K*GS5pbaMuUyL|6;|z{`42#sSx}
zttB8PsD&Q{X24qbkgg_ZtnsiT=WB43fDXF>b+f=u1@-Shy(|~YyWqkQ)X$U$weLZl
ziVrXIK<$cykTMmd6s0FO^*1O-9z*IWJ_ASJJ-A5=z(MY!65-nm8ew%&3GnUaf;1r|
zKusop&?s~Ki^MWe!NlL<_VfRL-%cstPL7w>KOr4~0#IDP6od9y0}!#k?+Zi$Bn`|1
z50ttvAe}dj(qCwP;{h5b04-VZ=sfMydDOS_tVgfcf8W+8{4J_%3=H6X148T!44&OA
zDxgc|`&hx8l7l}yEkE%0FtURh^xr|L1$-xD9ivC<0nlo7{uT#Tkgk%WKRhho)!p`J
ze#Z#9`wzC_)fBYc*77BPOD;$+bT+1(4NGhOphvGeqfh4=6;P83G?of-t!L+1&(0%0
zmd|`UAM*FfGJ#zBwqC%q^MkME1JC9kEd2c|K)sC44<4F7JUS1-8tlCyn>{Z6@L>G$
znO}g(qnD-mGrs@_zupP{cF^*6e!Y|YUB*ld4E!1=JbHOR;|UBty(ZkB9r*>=`1KC*
zw=;tz^$zfNePm={fa|>ks;5AD4}d(=8^X=v+4%`%!)Ja$uFw2}3?Ku<Je%J#^6Oo4
z<ezoek$?7aSo^g%kkO}?WwK}IMUW~Ee!Yw3T>N?`tJGXuZkH%}HXmRCi-X1s`SmV(
zc3v!h&98T|`XOAu(|?a%9*{>E`SlL*w|9eDfqDn3Dm*L?@%Mw)`F!RV<n-)3^x2VL
zkl}SdI5<IPKU;!C1Q_bHKl2OlH1q2nEa&G3c}<iR6aWW7B_*iMV|l3bo=-2!ZjdV&
zJbGEWLEZ+L#R2jecv`~)rKRiI^1q}x4c0&P>^$Vr{E`J!&Veg5kTHB7mPbL30-3_b
z-*OY=;{L~=MpE-0a5OXUw_E{nySISvmh|Z6^JxAFZntg$%X@UPob!N5HnTB$SRVE4
zE&9jb^9pn@Xm1iDXf-M%arA=*NPW7Y$)|e>*g*c4P-X@O-_D1=oi98(UwL%CeBn~^
z|Nl!pP#YW+2Il|%{|9*w<U&4>hhM6KCRRXk%m$Kj<QL@o%rD3U@(tTd&=4y)=#Kn_
zYU3B=dbtZ!6HEZP3*?&KB*vGZ8)rN$kMj5VfQyprJ|Mx6|NsAc^|CAl<!IQQnHGqe
z(ewKYP}BC{4|~tflhB!gUPl(s&TBrsGLsB1y*vU6J-ti(T}q(!g&GGx^9w}q@N1mn
z*SPSRU%-KbU+*w~`&qD}1N>c2K?zvnF~7zQe!bKD8b|osL0wRA!rugv(!0Q~ahkvV
zFj)O1{;oEVpvIxk`~m?i;N%5b90~SoC`1OFEkHR1ENBE8We2x~JQ*)}G#_FG9k1@!
zD>4xjP>i0<2f>M%3lyxLe|#)&ff!8uElU`{xhdceD5&}MF7mg5MqEGh3wr$d%r7Va
z_6NjYdWZSjjQ@i}IRcab9e6<gXtRb2fs}i2@atXRZ?lC6F?{A14B&ygzYSE(L(CL(
zU;#P44Kxw>nO}gxaTj<<1eDD|{YJ2VG{F90W?*1=310jQZ^V0kf8lxX2lz%$AI(Fa
z&HtD@JFnL%cy?X@mBrxUR1gE)6an`SKD}symiiXHjL$*+P0!AsKD{N(f4rcXiw)#?
zP=J6^7Q@REpl${zd7c9mVa-37`1?<TOwj!2(aW>j)$jml-B@n~BdA~i7rH0;JGB1(
z|L@xyzz7O$Nq&vPK9-m2VthI;yq1RNN3gd<LFE)Ub6+Tt{LC*P(#WrOsO$-}=Jl|=
zz^`$r^to3rOCu;?KJyDofTGT~^8(0uj(>bDZ<Wq?xfk62IPv;{N9Q?L!?%Y2UrK}A
z*DJEyqnBkfr1%3Bt_RD7K$dp*g1TX#9Mtj$9Dm@F@ntzww7U}2r91$tut14<5hN!G
zeC8K)V0jq=&U^>>y9yz~kVt*01{S`}-{lGsj(|izc!Gmp?>2vz5L6tJQeIvJn|_kN
z>ng+rkks{ZE@(O6$(K`p{{IikH+q*o^B+3J%pY=)KlGFjzxM(Du!Aqpfvq~p-wkRm
zy}S$ZXy-Y@|1ULu{{L_I|D`NQuii=iZqP|>FHeE&k%#p6(dyd_P}dwhxa`q+8gvJ5
z=Xp=?xZEO8_q2JB3TOcYs3XA+>aDh@fRuuoKcFQQT2L{N67aa3r{zKZo>QRWy5$!m
zXl({)Xa}mN`4uB*4il^vwCU;4YZY++-Lu=};twCoAN>7Oz#0#Nlfo-TpWXsS&rTum
zVhYdBvp$_ad^A5mhTrO085n#lfAY7uf-LETjJ%~_tE*j996Wp77=1eTsDMWGJv)#4
zTK@Iz{LSA7s#QUklsYif3;1@v@zwm}+5CrvzyCORFz<z5FUvcSeejyvvs=L9;tx<4
zx|ikHXMO>e$sXMtpo*#+Tw4c%3Lj8fvIj9VPIz=)^y}q;?&?$F^XwK;0c!$f@OIEF
z5GVz9eF6Cu*_bP^iW_u?s#k9aABPWUa{+XdAGpoaoTK8v2(q}DU+<&?|E#0@vt3j?
z5bG;FdxJss_cd63=i4pd*?IZ16UfQ@dM7}2`GKk`hnBY`rJl_PI6%4e^=+?Sk#FFD
z>gMvaJOEP6(_N?Q(Jcb;Do7tcxJ=dr#gWDd&(33@!3|H#1Ese>dVRXNJbFP@AP0Cm
zA_uq@&OoV!VeawhbqBQ%j`?(Rg6v`G237R({CWqfggq<|)hqdQ3VL)N2emChL);BD
zDjp0a&%kv*WDx50G0>n8C^mh&SyX&F8GSo>RQOv!x4`oEgVq#)5;Q24G4Qv5Cd@&D
zB9KJO38}MTsnD~N<s@9PnGrnJ1TxmAH~$}h&lPaR4ca1g4Vq;7K{IGR-H?>T-?EUI
zfdOO`$ZXKC4aiEL&R?KOs?MDM|6hUz)WDH!3hH2jQaq1}M>hwwj5x{P#S9uk>*P`K
z>=b|}kC*R2ITcjl?*PvS33zsLyxa_`xAkD*2XY>`vaMo#sSi?Q*#b`6{C%K02POl$
z(ax)v1-!2jG#XT*65-P;!Upcyc_399Z+to*fJS{l+Y!M7Kc2l#;Ju9=9=$q~UY-Y6
zyC?a(-hs2lEq;v${2B*+J5PgeRSgjE=&q0erNzmhGJ7|_-YNceb665q1&wTW{^QrU
z#jkM@)Z*y;1g@|dzzPoVcfA7{u5pN8?=gS-H4t0x34a&3^`LPFx~UPALU_9Q^=|UF
zgVySR%TQ1Yl3(K{zut}VWPZKdRgvK8-GlLzZ#RcW^Fh#MtCv8VFhQx?r(4RmGvbGb
z<x8JVF8&tKRWm-_9zT4#B_Jk)NS4{49NZ@QA2iDm@x!N+gJ0v}OF2l(t7?%)H>kSj
znGCIrPn1suX9P<o28LardiZrKn4bmK4qjdU5;SN6b}Fc0;L$1I)9E4cQWtFCCH^i>
za9gY5hfimOz{~&OV*C<+*ClW&sSxn!43Oa0xcTxTh!2k_pY9Ts2+!}Z*n&))UiZ*E
z4l2StnCkREm$-U>DtH4>v(2*;Jnn#6>-%(G^60$z;t#0D23iZ^!}#B~^RrKH3L9uu
z`ajR!T1HSh^Z*U~^Qd@q3cTzAA71~>r#It2Qt{j0_zM(LFa3I1zJXd2njb;4tRBq=
zL0v81&O`hiPeE(gyN!H%BN=@xZ-UCb&2_n;8wExA<r%<v0@TI>6(Am#CrV^JyG0Iw
z($8d2o&Nwj!{%Xm0#xUNRwSMP)i<E4S`Kk|b_V_MwEXScd9!rh%Q}!Xoo7L_qoB+O
z^0=$vx0jbd9t3Udx$yd=S1->uuU?jSkgc7NlnN>dn?WU-5GdlhEx`5t0sbz1aPt9t
zhQA6-j1yD}bixw_hzkm22asJa7lG<njZ^&S_45f({R~Y%{M}c6{r~^+<S)<_%x6K)
zGY09>JHX%V1)BEV3Ci#C4rKL*ZDIXkYj77B+8@>fb71{pP!-MJ@&{DUp!bJk@%D#<
zVEy5IkX~qicow!gmfZgEO6>jN&yfD`CrE$z@F#u&jx<mPZ3j)WrGcUh+#^ndbcw+Q
z9H>kD3DhM{;|DdC89~E;;AHlek%0kWz**1;EZBgZAV2knaC3NeegawaiC>WG6Tct>
z$PjS1I1Q;^><Q@*U-s<02$Bc6=3+TF$R$<Epf0f-sGtGMfa=mTXrK5MNI~`ev<aTQ
z;QlbkBaCU_0<a4-U<Io1s=+;CQ2+Q7q(}S-+#~LT_K1IbSRMkI%TTBHiC=){Fvxf1
zf@xr%S+X)Pr15JYcZzTO^s@X0tM}+-ISukQ$T$v=zrfWoW~aD;U*3TM(jSJ*?|=q)
zK_-Cu!yqSt3}EALxdkem`=5Y1z=;0vRS*}}<)waqI2XM?Y?Au_|4UGT3JCz)fB*l3
zyasY2AIP&WwLzo1;OGTS+(5+znLz$wd-)Aihk`@y@L#A#SeF>NL+lN%P>=HWfyS3X
zbrz^Y91Q6YgIX92M0bcez%{W9s6z~DA%GGTf0q+zZi8Rr;3s~82#GX)jZ<m-8W%qC
z3pfa*fqTXGpecjD>pwURYdlWl*SL|!uXj2P+%>)gkw3}bbqp-8cOebjJ3a>yzr^1K
zp1t7LIP{5MAOMt75AnC3gh(FX?@9z~(l`W4Nc`=fnidk47T``L6KHmm@e(M!KwGOX
zLVL>^pxH@~AQvb|J%9LE-U2b0_*>R6fOA*C4^Z%f(mg-868*$4=<(wdzn}ovV^FVx
zy2(oa!66?Z@QGj0K?39}{x;A6$0vTl2#^L3P$*pBZv(aaz){OD7$AZ0NSirCKUh1+
zZwL9?Y`{XWt}?`57NCJua8#Rs{ROI|UxGIQz^hX-I?Jh`9#*%D3R-9RhZi){v4H{s
z6fk@sr@!2U*;!r(G6CFK{*Aq}%nR)-g92O9$MRAdzsBLZFi>w<7!prPpkfQ!OP2n`
zFCcOdRG^eSLUfbUKy~I*uU-~V5@YxT=_hmec3uFv%<%`PpFH>FQgB6w+)ri(IjvXZ
zw?{9_XGnPnE_4r;i-0ZeE(R@F0%xtvKj1h7mzFPMV8Y!MpuRGwE=!vLN$FD|xeO9l
zFa04|^8kNW0z@3-v;c{h@(}Uc{9OhRacDXK4`8K%n^4~&7D5xv%VUsye3HLw3q%5v
z)Lu@2beRi({{IijS9+H|fjZ4;{2>R^pxx#)P`$hdV&zHx?jxXzc?Zbn;EwbEAK;Gj
z7tllt$gABSK=aId3DwUy`_ETV`_DDdzA~sV0JUd8{pSp*7^wAv=s$l0b+KChgSxi8
zB=w&UfHfWiClb8<=hd+OvpdKVX#aT*wz?g6|Je~#dpFmpp!c7zgF6ZY`p=*E1z0Y7
zbaQ~JwbPK=9a1)ddeFX*QVLra8mteJ%Z0$IKs_bUYGhQi?!qg2(1b0XZZyb#P_>HG
zkDh?N|NIHmYP<|`D!A%DP*nlyK^KFneo(Fd`X;CsjOamwl=GafGXV9VVU9iluDeh2
zcO^mUZsbn%b&z(VI?)VB{b!IZETHf^Sgr}msE{7C9-;?r@c;jRXb&1b-iF+j-pw!1
zfVDUM99-jr*1I6}ra}7~;2q{}l6upiYzsQ1#IqCLo8Av<TElzOpo5-p^ro$2|Nnpa
z0g`PG@OSBgI!1`@v>Zg@B!3rZWxr=9ygv;N_Lrc+c2LmpcdZ0f?I3*|kR=@0`qT0t
zHSqql<$qA4{Tj&KFWn$*0C01Yg8uYFNL_rAze^Z2e9(C-jbGyds2zver3R(T%b)`O
zcN(})?FUcLR*+708ovfeE3{h;ss;Glg&>L!@OS+K+XAlVAM>|^+HGn4puRPzoJr${
zcdkLnhX<5=Zt}OU1Zx2eQBDQ3G;XGWI@sx;LbxiL_#QUsE?Q_08)7_&WVsE>IQ(r)
z;65_AH<bqJWAj35>Z<u3-JsS2&t-5Y8>F~=BB=e$-v!#l4(Vn$Km<U2YoAU?KRXhl
z|2BV@8n{ml>1c!YsX!{BAK;_{?P<S<B$P}1U7#w!qZ88AP6PF|!2<Bc0Tuh&7eHN6
z;`-X@*!$X{g!<aYL7iZDUmKL@Ki8Fj`r1;^`8Y`GKLcv5gPRT~O5{NuZcyq1m1l>_
z?jd^I;O4_a?_L({UGC{GBSE%dcDd(+{E4;84N1wM!V^@^o&Yx}PV#pPLRt<7_`5(i
zV?no%gKkxYxE8Wm5Rp)xfL13QcTs`#yR-0A@+ZKRybvT|9N_Ps4XWh(5xwuPkm~&a
zf445E`@Ilcy%U&^-UFVZgUv^ufy_t$=Wm%0>wo`Y1I;Y6gQufEfZ4F__Zv3QbTnwI
z2WY<0qZc|I&CcJl0@C|F0-lY&gFYKQ7uNfp0IJQQz3)D3H8iyMy#zcB2^!~y%toK_
z>^$yc`OmlWCx72W@ND!G=xp>4$ZYgcQ2mWQ8{PQ{)cHR6h{c2PhX>;=kAn|bJQ#1>
z*0`;8^W^Q9{OzFW<l8U!yOuLDFx<WIn(6LMkItVS2OqM4df<+?^+0NB7#SEqYSKVz
zZoX!^3)26Rzuf~WZUPtg=ndf(@a+5qHr?vBg=g~{Mvx&d9HFDy7U2GAuP38N=P3`c
zt8TrPxO?+8&)pk{@otaiLjs_|Cy*(gohNU<EWdm6<n0$#tgbC@ORs@?-@cufJv$G0
z9(=&!$#~<n)ZH7ex$oY9*N2{+hdrBL2!P_p@wSF%=b_uL%I|<Y@C~#i*YY5L|8)ii
zhMOlHZ(H290xz`i==|Z+>&^%b9Usd>w>9b<Z)XUA!l+yvY&jR0<cEZjPv`O1Y<EFH
zaTB!4)1&!-fRE*&(zADOcy#`NnsQqM6pS8>r*CWDwzzGLrNa&~k-zKMzyJSVGu=FS
z+rsg--EEDRJO2Iu50RMyl3_`k0CK6_Z7avydM}&dlEENJcJO=)Nbk)9x2;|}{`>#`
z?#;V59dGM-SRQo*n^+Ra-#-gnRKVxGLBkX9sqJnt*m_O)y!SP@By8Th_#b~y!{7h^
zUq^uA&!@MN(X+SspGW6;XoBp|2Uq>jB-;(iUi>Yw%nS^#x$fS$d*d|=i1h9J>D&1L
zIvZ{l`v3pSXQ1-j@@U;mkXgNzj4!1?26g@b?H&Ln)m|QE&;U1%$?8+^$!Y=6Otoj{
zHE?*`&iHU!0~B@q?Vq4Y^d2Jv11OMhp1hr*a67{QBD)zXI|nX%^E4>IS3|{<K?xh2
zDQ=#;{ffWc87i&=62EoxB*<4cPlC)8xOobsfElU)G-&}&DYqaN?P6eHxDU!@4A5M5
z16==t^xwVVcw5Vd@swxtK~|6E0|B61;R(tBjHhmEIo_`N;A?sFwiSP?I;cK`*J#+f
zyI1kg4Sxgmi$L97q>14V-n}gPpwt2iYf!NON`e+IUH|<556Ul~EugQNCxG%hxEcqA
z4d@^hkXK%V!r%tDB7bT1|NsA+r$9Qm|AQ0rsoNGePu@ImyF%dQUr>q#%UuAaSXO>{
zhMT8u9=L6B^VIDMgO>+E(kDS$r-P)~K<Vq|$=eklK)Mxfo_yH?R}ceI0M-vSS^;8%
z!OhbzJ>Y7jKx&vEG9SQ{#Y?V#;3l&L1ApuF-~a!={Ds+(PX>jJ=0A^v&shvldUk&B
zVEpX^TC4`DUO|hEZt{0HfD&eJAfw}LO<&6kb%mhmjLr);54@I`0CN3iP|V&04}dox
z67aD+P$GXj3tWDbJph#o2a%*opMulI4RHC;%fbyxte(vW1$;U$g0gJo2Vcuu{4M7}
zefr)&MqkSdj<+@I`)?lb={)iJI(R1hiQ)g3kQ(}j$H8YT&=SXk@$+qs+uEQcS1x_~
z1%Ef_Xhuj;0vcF<%?WKkfXa*8)-Ut^Knj{$H}Br`;P*c9(hhX2<jI${;Hn=q^K1i|
zc{cp{|Ns3L{N2Hz`V|zK;9Q0%ukp`6Uk7aw0nNfeCZSb8J!HfrG-N|8bV9jXzys8Y
z)&_5qg>JEj?CU?s-*XFG@q&h!eR?YxL0dS$9dGC)G{^#<ZpfZl4^W@r@N0Egf55Zb
z<<buy%M<+lGr?x0f+|XozTOH(&=ujZ&HWA_L%{~YmXJ*V_4uuOAhU5Tpc!1yLYa#%
z_**L3v8*F=Q3>z_RU@F4(jK5~I-uPkkPZEUpsJ_2MkRouUc{q2N5#QII|sBg>@N#{
zzZIzC&|RY9;M4iRub1V!56XHn&=fUjI_EfeAt|`lysabb37P}G=y~uVi_>i#Zcvo-
zx3e%o>ggBYtO=>hL37sNE{<QX3BPBzm}loD&x4OZnuI~Qc_FmG>IP}K37#lA0jgG=
zZtF0E<P#Yo1s7;q{_YL0-VlBcu<Lzbr__3Ovw=2z1TccqAV?Fus*ixz#~z@a54}9s
zUkgC?cip||(R>g*P3_Yy=+Su%bW*~>2Q0UBm_hz1e{l2UeQ0HW-J{p_zh~zgpI(;Z
zuSH?;dH05A=Mm557vK?Y&=etPQQ>LNgO5SplD_@2{2r))n#IDv03MD1#Q<7|CE(M^
z`LYPy=M(u4KFRe2)XAVI^Rzrr=j72XavW6r-qsNYI|NI`?}@1RK^Yn}TYeH0E?^@;
zEhCR!mh<3<;_~UlHfIiU*;Y^?#fQj0psEp^X8Ay~$)Iu&6axHRxuEJCT6KDM@_}cS
z#XLGMg368CI@~Wo_qju|H)!$m-5akt;Nc6(0UR$Gzy`pE13bI=JUcmjJNZiD`1?U^
zN~D1R(76PlS|6OHkca+39Zc9#IItwRNdTFj_UtVIZQ&?Uap3O(jdZ@wf!Gh)p7YPM
z^E#;JcJSzRVgxZfP%}jTd(ebj%Oy|?f$8oI(3)#-&g<?0uSbDRzk?2?<n@IfL;&*$
ze_s{2AAkL2AE*}r%4misJq|u#_UV;j2iX<j0k0@MzP|;n2|f73-na7xq`BbP>&)TP
zt24>7^BTmxklw9;52Q(YTSwTZ^Ab`z;BR+^W-NUsSS!M(^OA4pDcF>G=QU6%d|SuZ
zqq{)Dv-6AR!6%@ks0>O){OzxxdF&ceE5oz%3pn9F0%fu_Pz9iE?BJT=CZxGh0u_$|
zWlp5#2B_-k_TT_H0GgE{tq&EbdQOmfP_yM0!~vk5A}HN~Hd=zsM{a$f%(7ob%(4sl
zb_V?Lfy}bE-U2n#P{Q=!U+}^-kIrizn(shs)9Q3U)2QINY7hfFQSI6J5yS?sQ1k8l
z;L~{vG+libRKGBnsDM*Mgimh?JE(a3?$i0tvs(;Y1o1&v%R6}VW-z{-`5V$2aRs$4
zK=nT;xd=cb2;MFM4UB<2`5WwcNV`M<-Y)qF&Ivb9zGml_XSjRo=1JIq!yQo50o*)U
z08(=6HA~tAP<;&<c$f;31-DKzK(aSpgWD%}Z{9rV(OK{VbiU|IP&*uw36;Q#Z=Uw(
zECA2>zf=GVfLaG9|AMMoA5e&Pa=ZlX_im_BiD2MwH3l_EK$~`54gZ7sE1=Zt@UjFH
zLg0gDjzele(B!nM;s2M>Ac<}t6$igwmj9qOa&HBrZ|5N&&7YwD5~#P@u?f_lhm0P0
zbbbI8aXyweZ|gAECHQpScr6ZUUx8c%TImcbhYv7<ChV0#;|I_X1*Ms?JD@Ta(q^$d
zQTh;)YH*Gs^uM(E^Z!36*gk>gHtu=#^8EJz73~*5_TScF2IYMRk6xDJKHUtyod=Pt
zt#Tny(*o2c1I6B#-~azZTE);2gvY-@A$R))sFC6WYNUX6-hmPo<g%vTACOHB4xrGn
z{Q+sGXoA`)zrf=FpuJPr&U5D1EKv#I*Q^2Ub<uQDDRAM}>;dl=0j*94t%bP+TC@&Y
z*W%N8)Caa)eK!|)5jcMf=(Hd3(k;-j&fmB|V+AEgA<NZ2fzJ;T1vfEXFv7<NSXB61
zyf~o>u`XA)2g!n#t5<=C@F9l>O+wv#>eFi?<kMTv2<>+Dfp*FIwtlM@_2~QnYBe<f
z0H6I~z~65Ns{POh1A0ZEQ}Lhq1wgC24u9qsh++Y)zvR~gE$R(m;cwFiE%DX6RK?1#
zce_f|qniu7+UJBvCuo5q(`SCcAQq2a9&nSwr&k2LZk-9F+mT-&h=spx323n#OuLj%
zH<NECND~MLffwe2*E0u!ECnr!2d%he;cuG+(Z%28&kPD8A&*W0&@xc)BHkz#(5M0j
zxM27Ua`<O{0VfuZPSDy;keeJ>Je%Kvm!m?Bp5O@@U+5J%4QnreG<kNO1i2FAU;Z}G
zq9K00OI4iU`KT@6-ti&ON+ZVCmpyt#pq_JQ^yp;~_O(3Z(QQzt?b910%;DM1?a}$^
zg|-W5*F-6sXScCW=W);ofM@ez4$#Rw_dv&`d-aN(1~0Vb7jR(l=;nfi9mu^-EQSa8
zH9$#E1Dy0Uz)4R7lJq>V93uyAX@k~Ev|R^{-|O85x%m=*7ie|2Z?7|GRW~RS;XzrZ
z42m{Zkmoc!nqPpHGjjNXheH_o^-h38yZkP{-oY|$kP>hl-|(?KSg-HV&E?y97~#?=
zmY1Mr3fTTCrji=ac7Z|=vC_x#VBJN}ZXqAbqo~nTQo-LZ$Oz3L9H3Ec(1woYABOc@
zzMU>d89bX=R2Y3MkAj8{_<Jltne;ViWO@R>-oYxS5*^U`2_?`hZ#QUK`6cK85PrP_
z)m;<#^=|REfqeW@6TIT;Wc5vcz03S<puLkXoj@BXF$W}`ftwfN?4YI}(h~fGF8}|(
z1Wj#%!xXgrm>;wh*#9qRxv&5{82Q`tK*fjNLH@RWNVxNNmw`nt@ps37T%G~qLD%2%
z>zydm0VgHUSw$cNyFnYLUhW6ELEeGE2ecla8PtF8Jpa=6&;S2bZ2T<{a}V%$)q*WJ
zz~2p;#C_Qf(gO~UC{SnzfWrgS6@0k?JisdN!oX0)R3ZTiEI#n0<~`7)<_WO2lhtoQ
zVbu;g1O()aF3`qWki)unf)p(VD>_iU8XS5c2fd623!UWe2DPZb!Y2R!|9{E)2fSeb
zoDn>_eN+rQI%`xsTn%sg^ooE7WE_xNSfIV8;1!3xP8`0S7a^@Ik6xBZ9-Sd779O3)
zUxEfyKnV_#;pT(W1_Qqacx^rhzs5mOW)EQT>~#3?*_B_w;}2+YdBqP986W{7Jp}mm
zPJtL1G9WTRgue|m{=l#I1e71%@^^uFp4|>0#eyDSGC{_((?I}aoP!8RPk{ix-ar1f
zJkS<UP{^{mf`U-mv)e(y73zWt0e+3|pI!L{Jw!lG0j)f0O93x!ybUT2pH#`gtbkY)
zA>-Kz-gg5gBEZEPXlDS(I|2bb{B4K8Q47nn$H2T}p4|={Apb(h2p-Q)2L86444@Nu
zKy#m<p(4+24*}0^fftAE|3gmmInexo3Dn>4VZ7nle3;d<`GAIJFAI2c4JXKRjx3-h
z9iWRSIs<?BSl<84F9<0b`CCA%mqALvZuIy8Dg_+*1t5+M_`~0x3SO>wkiQMIw-}sg
zB0wS<KVA4WPQ3)Jm<MN--C)Px=I=5DWkHRDpjtui7=JrxhaA7&hq8Kba6;nO_W%F?
zJD5Nl8bFzrU++7A8)*LxNCkh_GVlpLpjqKYkUgN)U30*U6Z~zL!InJX@7e?wxy|3b
z60`~dbp8*&-o>(V@RS!1NKWIU3uyTaXbZ~Im!SQrpezMiOT(}CjlT=Ffuy?(l$h83
zgXB0+Z4SyYkX5Rn^?Km64k>3&R56v*fzm|@NJ;k}ki8M$Jnp~%G8?oq1|-u38cPK+
zx+_3tcYyYr^XvVqVk*hz*ZW_U$glUGzxxoVgaB<Xfb=gw<r^D+%XF~sPV#rPf*A++
zyHA7EtpM4gcc8i*oc*dm7T*Ww$^-n}p!G41{CYR|+vbAApMaHqtDfZwij#KGkd!Of
zErB3|w865M_`5;JAM@)y<!?I!(ga$%2`)uIt5iY7Lz@XmxCpHJ0Dm{APt31(hrb;(
zRSGUFOhBgbfaD?PA3#a~MDrhfaP4<kt_QDN)jR}RwrauT*?GB6AGAZIGepGzbo7q}
zsI3O>41gHmo&actY3IckY2W_;_vwxSDRWVA@MZiB-mDVB3|fD4+ov}UbXWo?;er|g
z0!}QRokH+b{gMmZ?0ezUiP*Su5VRK+v=&DMvKHqfXaEn|D)#KW$lvh=w8as+aRr=d
z5?Ope$Jv1<a6zqBRrq)Xs8|74jhy_TZA>TNi*Zhr#DSK+9s*?|eu0=nEag`~b*VnT
z-jnLP{2G_}^=^OWKXjRyU*i>j$RqH+j*wIQp|ANvFYt#w<qtdcdON87&94VaZ9bsX
z<^&>Ug0i-U<%!ZoUZ70PF952x6Igt^LA#kae86Rlpyv<h-k3zt-WdK?P(FOA09koj
zy%W6R+7Fa9K@+|Z#uNT-P?zZ?C=r2%4%hp1LO0R0f;M&b^8EJcW%=ycE$G?J@gl++
z)TH5WIR`rBrW;&XfCCA%4Gh${5`>glEHBso`2QcY=(QAN26&l``B(5V8=bG9g*u@6
z31vL6@y!lUa@Q<TDd5+H?8$cF*MuBc0B&_J05!irP3~);@dyn@&<UWOJ>atwAjiq1
zLr($)9p%Bm-*N<cbPPx(Y}w5Qs2E5Ic-akTs6YZ#boWSs+v7Q)H7vaejGz%dutv~v
zGTjhcK*NS$ji5o3!><)4fX53#tCjm7fDe<=2RG(H>u(a^<AtE4*9|$-#z*r3WE0C(
z=ovC#i(6KKoAHpHEKJ;3M+-ebBPHO`5eG;Q$?}*7=;#>m+5F9*eG>KJpiZ2&i;9B>
zv~3^2-#-V^w)gE7`3ABZX+w(;ctgtr&t8^eKD{iLeY!!hCIBV^SiE|9K+RG{NIN)^
zg}*Hr+|~zIZkMX~K?xYN%|*bslgp>`lwU6kczvXQuMV4Mw=aVaNV_Ay09d~xzW~U9
zH{f<V)Bp+3&QJ!=PA-sQ4@eW33EaW(=oawl<+%*X%$%UC<H#=%$im<D6{4BHYX@j-
z6m)Y|D1%40fOoGC8;3{dSD$W1@TnsVpu-M8V~if4_Bg1u3)&SMz=9Y*^XT<w^z9Wn
z2W#*9f|}gty?R+d-sOOJHv-f*0VPCuvmbP#gJ(0e*?-2nm*tsnZ-@%0)bX{v;L&Yz
zxlY%+o8=mK3!Kbh&u;D)CKjMP0&e#Ec3y!U&~gi;73^-FbMOONK#lwYP+K3C;x%9?
zUZY0^oZ=ggfbs>_{WPG$z3n^Lv9PuSXu+yaZ|r~XUXgn~-ArD+ETDjZw^z$#;LUzT
zpU%4;&968-n_n}&z5;H)gUTpbQ1c61sNMImyjid51B&CjzMV`j_d%;i(0UP2Wzq$$
zr>eI3Sl+C=?qfLzoEO2d(8&b4B8<NUG<v|_9|D@mZr-B;$~+8^ty}Q?g?!K_NZzMY
z27J&bB=a#a!i@FkE&a#e^AFTK6$a&3Q27C>FPTa#LG3eDaLol;W%4orRPTdo?F4W!
zcZ<JG6I26(R-Aw~D_=vT2XIAt0947zfX1zQ9T`Ekcy^uvkFFr+w0_XdCHyU>pgD=|
zDPVtsmMnoB2^xU}IUF<s*=_Ov|4Yy*{ot7C1INrI{w@_z6{&ZdzgrqqVS@YstM5;g
z1%jJWJHQqBZT{}{AP>$4@#GyCK=F|clJ6FPneZ1R&jjLu`wNgD=kL1)-cWSr<(1!%
zCJbme0~9P};9!XYX>tP@3hpqNgX$7puuK<7CKn_F2~SXcV*--a0>yCmOpr844XA&0
z4%8-ScK|5{`Nbb3rwisCsJ;je%0N&!LwgF<tsv!XpuG?;L8sAyz2OPcV+HS@Kti~?
z26QCENuSOXl?>3}tS@x4QUY?<;XQc1{D-|SXpa(jw~_~F+&Dxf;-w2HIlw!-pdN%z
z=K~jhjl=vJA3Qq)et>r^De!CD^6b0<zH2o@z_U9;!mronwMQ?@Yfx#!|CwI^+;iX;
zNC3Ca^I7=Y_JPfP!ryfm)K~3%@4~NfhF{~CXJ>{0zs6JF&I}39&bL0DfBE%}^S6PL
zI4Em@dJ8A3gj_&tvo(JBc4qwW?Mx8x=sdx%_mRI1G&=%ro2D=^FhClnA3Zw*Bs@Dc
zJUU-_c4u&S^zyv^3@$rAeC8MMWZ`dvY>zt0-*uaTfx)v=!?QDh1Kd;wl@8!mUDrV-
z&|ruFXgZ-=<noKH#%R3(PsYRE-6E$zy#eoDmRla(9NwKgr@#kqbPD)bp671?jjQ-}
zC;ag27Vz(t>GbMldF%lyiTMRUWhf`4Xbc1m#ze62xA%c_*a`l&*N_wr>Ra9B?`j1d
z|H7|vh+pHQN9VzplfkO~@wc%t!ul*WEDQ{g27e|vZyw`sI|Vl4WEB^r)i3@3|9=;L
zP`Ba3OEIvTA7zQ4#%9-IuyG&x+joN*=lI*+!umqphrmKl_`6qtGV>M?50aiQ^0zGq
zTLA0-fts}Z8lXN4Xj>_$=K|VIz^`{4)OLRcR(gQH3$)=MoIl(^=IJBMI|xz+NpL6m
zyFe!vgO!0!On%w+7n1itYbC+G3(%AZh|vw&t_@yu0n!cL`UdKJfDShWOTPkH0y@7F
zBn{r;rgyTc9-INeISRC(0$M(QgmmdoR`G##f;RWQ+yW{M^uATUb>Y`L!r#6W%zeV&
zwe~OQ2vkr(xENII^n%6z^LK;R!#jfa)rCP+oaFC{154iK?+yhiwFC1m@q@cA{CaQr
z+dyId@&_cd^LK-m7`T9Xz3n*=6AtiqgHH1SJ2?_$f+Z-(Ks_8#e7b^^w*3N$gKPwc
z*io>8Tl{UHRn{-PLH9y|#X+ZOy#%cY2ep4eXW#@NN&(Orav2_Ir}Dsd!bL!L!bO0(
z58&Aad^_Qqz-NhqPepf8N$}{+WAyFKVf*3P%ks~s^EuibhD*MKTCz_d!|umk>Vo<s
zo##A`w?Ha1P%1Qh@=^@cuju^f-^=n0)N#>#=mDC2M%o&8_~-xso{#}|AIqDd_4d%Q
zzXTTkK2VPqH0~~g*{6Vwu9swi2j6=|E`#>7gW5-+LCW%TpjyHd)U&t_YM7z-EKcyF
z^(;0b*MFe$-WpWi8-j>lSpQ-gt`U6xR?rfTmp^{|{|~AXPJz1<pf(3Mi$WMr_`5-C
zKVE`1Xn-0;oflqj_wN;X=G)8i4Rp3lw}e->$Z4-`p4%_D^+63K{+1O#;HS#W1@+jD
z!w#Edfpi{R4WGQ+_63}rK`RJBb0J$nN0Ej*hB<~hhJ=QP1$#8U0nH2YYi<D#&x5)U
zptG64T?kM~3GPCGCNq6NM;o37T_e!FM8yDHw4e3qb%LBT6U74>mORPda-9cMq(b-A
zodR=84*u}4{L0^Rj0d#;3S7RlfR3a9rwiEfKG5*}LD)Dy*5UhYAX&>7{4MLi?S9Dc
zeFEy)|DfS}k6sthncMZ?X1@i9R{(C7z=rfeGgsJ$^uI!y{h*^7;7xuHEbIF|fd=;(
zZ+zkxhypFg2W^)FZyY+v-*y<hTS@Oy6&rXJu*7Hnd@j(!V}3yn(C)iW{DMrM_yvPF
z;A;RyxItT2m_S4jbc2p5su?mMGaMni?I4;#ilI8dJ81X?B0ySC@V6;KweokpVP*jJ
zG4r+f1vNk$S-3z%6bEReU%;~yv}1+q6Tg5H$7lY034TGTPyB+QU2hH?V6#Ev{U8R&
zMWFZskM~0+Z#@`qrA+_@fM@4PZ~%a}7PNs1XV3!TDlU+}`MW@4U9eS#uP=CX{_^Sd
zX9UfEK}P&f`E+aebQf^cMS({B1w49lK!r((N`Ys0Fo$P1vq$GgpUxbW1fR|ll?>1z
zX9ajon~O@piv>EMq+iPA+pX=}UCiOr2|iWNv-z-qujQ%I{ov*fcnKzGl?5nxd>BFd
z2pu?ly19M2gE_#rzXpIj%l(O8(3u0&hkz!1jXmH~{#^JqTEJZh7k-T%$U4@>BcMDI
z9Ty+#7~>f080Q!dUYg6_#spbFejDuXOZ;6N|3Qa$IR6K&Vu39A0yzP+p$i;CWon?{
z0Vj@2RXQHcFF;GUVe<!|HQZp8<+nhAT4o6jP)I_$0-8f`g!R8Z^XF^%b{+;rEhJq;
zal8Z%DniH0LG>Z%QdQ9M@2Yw*IT<voaQw3)f4&xIv>YW-K*!4aLA%d=Ti^1x$biR>
zSyaFm$77pY01cJD{12L20N1Y|=T<S5*n(CfR~dpx{_by}%K0Z`>(K%J?sD+*VyOGl
zz)f6PP^%ZT-W=q>>XT{Urto@@Hqh{%59X8uxFz252Yt%HPv`&tm!J~^Kmo|#2HNxv
z3OW8R(BUR1!O!0g8u$abmcI=eKDYV1Ux3@ydYAaSPlKA-pqT}bNo9JVxZ>{$giE`F
zq_se+#z6B8pvCd9MU@Mn-G?RMAOVdsgUV1yK!Db5zXVOYBI*y23#yn(5<niW3V|py
z0vQfc%P$X_e~<==R`G*W@OOhe{t|S*0f<}u8XSD>axiywsY6(|`MW`fjDzPEK)S1!
zL4p+IQ1A)VAl>}k;PaBfVJ!oSfGE&nJ<tq<Pv;NNBt!&gMj2@$0;wJ00Uwg|?R65s
zn27KIO+-9`WQa@P4Dpt~iyhp=X7KC|02M8QU;<QFYP<q%;qdHq0CzP&g-ykWPoSxZ
zA0T#s0f_Wa0Fen6pbZ@$R)hwB8+6YTB*Q)7?*c6~^Xzso@azt-02Of_Af18{7M`6B
z3Z9(-pt4V(Kmla3gGL&7g5n&=g`oC-6?+<}?Odhm+3ld<*$q}JSOHQi=%JAYnzKmb
z*Z2-|A}G%I+jfIA^Xt6@XW`pbYRFbQfUVB3@a$v&^))~)2Jeo}0C`%#LjWWY0NTTO
zkiYF8B%!<o2h%0~E@(Ldn!6D2><*9sdBp*wLlD$k0-ML*23qtAb~1k#=#&(gvq7WB
z4xlQo09;ang4(m20mROL3=o4(oP3d?j@G&HVY~ry5hp0VK@3L@AI1yN$&Ua~wE$W%
z>Buh_`N7BXKD>V5Z>eWu0DB8eczgh9%>Wl}AXdN+{`S9+On;ES4OE~&vf_KNn8wdE
z@T7+%WM9b%{x(pXKaF4SEq@p2(i2dUNaF`34baSoAh^iT`@r8e4HR17xB^u#Z~40z
z;S(Tc5Jlhl+d!+(prHdA$pA4=@^>jftUAcw?h0X@fb@SLc{>>*_Ljdp5>)Q!fg0DK
zlLf%XS9O4F1-H*8LR|k5<od&qy^<PtUV{1wppq8qhj08{&^^Tm_`BmlSt}ZB9B4j~
zjlV?zl5$S+cm08wdw{>22c(J>;)W9-qv{}1C##AedG#d7RiI)FBnjFl1QzZBEhYoA
zz?u2wA4vWO&5`7%fhI|kK_q`S=#24~ph*W%+69>aI-d-zuWKU2q67Thpxvb}O~D@2
zJ5b$`#;<pkzYWwW0WVSpl_UJ!8lXUS<kx$_-&P88Q4>V@x9aJjP(HyAo(}~vPx5zP
z0hME*iBNFFcY{_qr-5ca+BSl8LJQLa{N2AG-hRd32D-}P<$s7D4)AxUf-K|Ld(GcI
zA0qaazk4^xP|$b^Wc&w|;tde}8&G#A0#P_2&6jv!&X<5s{J=V2^6U%Jd`SRwvIMk%
zTOK@Fa_|8QD1~!*K=O?fxas7G+;)1oAKaCB;nR5x)P@8f_vHoZFhLeRgLg20gsyys
zPn_K3@6dxzoPdny1QCfGKAk6gKyxR{z=QRdUaNq1qd^ND?lgYzCifGdX`tpqjG)aC
z9+sy{a!@vppC~^AiuN*7kk0DsY5W?XtxLB*fu>I&c?>*(awv^I<Ww4e=<788&<kn&
zVNcUQvnVS-6<`%pNjxaER0V^{PSB=Js9mK~K&>mUUKVC({hGkx*=^|AUC99|G<-WR
zcyt<gbXI^0K0!}V5h0ie+DOgc3OX_7r5$ubQT6gPa6d=~663e|yL2I}Cy>teOJUGJ
z257vl^BClCvNxbJ^bbB~0j&n~==D)4@a+8I$#}zq@v}!avqyI@hexN23YKE9H$)`?
zB$e<YQ3=$1<ZsypI<6n02NdEUmkKy=z>02uK}h59<z#Rd_S?(l;Pd>C8UBBn`58PJ
z6ZaWB8H43~u*Nr_r5T|96nK_Y6LK6FxIYCtTM68s`T(1fxel6=senz%fbQCWOv#k;
zKu-8C07>z;Sn@G2fJS~nDq&MHs!%bI68Mx1$OQf#4Ia=IDpk;`XXum+SR-^w2BZcw
zB?Hz7nUax5%*eb4-wyB+_lyi!J8VYg3G`MrkRX4{M{v&!G9y#Li*-gO0X`!W;n53e
zW`iQ80>lCJGCevWNB4VlyQoBXK&NXAK^?Q^8kGbF_;d~ERsrx*tOEZ2TF}m~&JVu5
zBHtm?HK6$k`1Nc)ohN-5AApwhdiJs$_h7vFiC=)zryJC33*_(tb@V`cw{AiA@JE5F
zvV;6>JS?Ejs@`pIp1V{f2+2PhCwxE)e3^VZ4<gOpu!ARL;Qb>sljcMEWH6KDd^>&N
zlQ@`qe7ZTH%Va$mL2lyu#4iBqhUuN)Z<`J^iNC896d)j%_%ir(b9ncLu!AOaJi57j
zIzfw}z*7m$IVuU@MdP3Xi(dfbUr@sf)SrXS=bVT2CqUuVc^-7P7G|I2Ab*=Ir0RmS
z>2C9Pse`%)u!)_+-n}f(eS2fT6Fbng)4rBBe7beGeY#7yIr#fPO<|ATJ>V{tM=#_w
zP@hg8&~fi~eL7oI5<p`K-6HQjIzNI|&U^N<NO^PzfU~lPM>hlL*jUg&1n78n(6oq0
z=M)vt%#KIrFHm9uC7KuAa-dvY$`4949-!syknW{N^HD|*%QavdO6Pza3O+{}GM987
zX)b9C_;N2$R}hw4H6Zt?fxCd<+}d~ql&#UafQbIg3H~-QNH9T~rkD7;Zh{w1fv1%2
z`*btm>Jln}nj+9-rhz=SbQ(Ti4lc;GKou%j-R-IypeZIZxIAL63A98uZ33vS2L%zR
z+~)6^4XNu-RxR?eyjgb{G%*CquHZxhn{NW01I^zb3Y~8Pl?)90Ep8xgcZ&+R@Ian#
z0?EVXo4}IIkohK%v7nhC{vOaGte2nzsQE$Z4dnhRwEiLJ(x{i){(?$T&`@hMxa3EK
z=Pmv=aO>#xKd_3Eu>Rp}P%8p-1(XNstP}XQM_7T;fBrY<F1UK|HkT<XAZLMQoj^_n
z%{qac51MrnmHYqy<$s71K-mitPM7$*K<8P4VuimOG{y7M3(^ibQ5Fu00{$*W2>&*J
z_jk~U+C$K7&7i@=3a~U-4@5U;>+j1raEEaY*cJSJSD_PT(8;ohm%`AlBWS4{xV6<)
z4{^r<{_Ytd<C~zyS22}Xfg-dD)Gs~2-+c)rxgI15IzI$7Ac>GZ$=?mSdiv!JkTht(
z5!4pA#oyil;os)(o&wUH4dEWB21#Fr91Zhw2}JNDtj`Ww8^{7`sQ&x~j*3hC-Q6I~
zHJ~tttzQ8Z*4;HK1)ve!&Lt|K&NVoTL+7Q~K{*v%4j>k}z{jIOQ&T>jAu1U@;B7t7
zNvbK}`xiVqufBwKDdG7FbUrOOqr;lxA3!5)puU3-_}DQGpUxM)op(Ju4}(?tbQcKt
zbSFsofX0--^#G{H<H2|nQZ9l<U^qYV3nYLF{!^d$1u{AK+p-}iWjx{U0$q0pYHoUf
zEIX6NukkC5U*oAyXQF^lXCcT;-_B>AouKeL&ff;A|3EPh=~<qvk_0;dq!V-)(GMT+
zlJ*P%kIoBe;AySfkP_nwf0rm|hQ2#Q1#HccG=7bbKAlk#KAlRwosU7CI1i6*FAl_(
zUT78L1#<HT{<Z*!IVbtM!oXQJM8yMqrX;vB`_A76S~Lo2o_D2zEehc9=w<+&O97hi
z1jP-g6a_mLUb=QOfP<+!gqg#mn}r!94laGWLqOM8Kx*z6!jkBn%I+AI4A5x+0UnIU
zJ(^uqJV5K{etUO|e1^=PeFmTH_W?3s4!$cVfWPG-sI}1zy2z^=bPGs#<`184NsnHe
z2A|GXut7u6-Ui5i=1-8y3|=#W&h3fd;BUVH&&i;LXrR0Z?p@#J?>YyPap4D@?f{x%
zJM<EI#Kk}UHqiM%prARx-*q28$p-CI9)tH!PgZe56@hO|08O-|@oRi|30gFk#;^CI
zEC&?r{9Vw#+(-U)&{5NA{Cel0LxiBtD}T2Uq%eEJ-z@+t#z4#JVCCaQ{x)cd{RHgl
zxBOkLAXoE4`pjoNI!}N)o-ZeZ1tHUJ;2tk%_NNOp0S7KTy1`Rc5S@D9NjK1*a!|3s
z-xUN&B?tJsK_`Q}1g%(w?pFlW7oZV^G|=Q&7ihf}nAHtxf5W@EpslxH;V$qv1W0N3
zS&%ni{b10-J%~+hkP_@9e>Z3@<K-Smc?p_>0}X4P1P^O{<L_1m&1|tjJoK&lbsA(I
z?khy~6aFq{kQ5~3KvQThZ$o7M^LGn?Y759*9B8T?6gMaNyOu-bZ}WH01@#x}A>2#+
z-31`!;Q2VvO30Tw5Qzi)-JtFW$l8Pa?Z-fZ5X(S|8o(au-Uu>>7ZPj#`McRc=0IlU
zKwC^+ZU*TAML_owh?-mcZ7m>A#e&LEh+(Thd{EaF)JrWubXq~%A3((<_IbHI;L?w&
z&Ja{zfd(Q7&CY>0{*-{aN6a-U5um;TxVVK((6NIi=>B6)&|UfZ|G%pte1c96)B%P}
z(1EH*$ex%dFWEuY5r8M?o`Z^a&;(rpBeeetKD%-TcuAWT=<G_w@Vk#CsG$v-A4%Zg
z?|TF8$KHCa3QO-#pe-4s&MfHkG)7QIw#>7e<pQ|$0Z+1kTCR`@j`CxmmISm*dlAwk
z*Td-2p2FItT?FmYI)P%g$_zyEcY!XM0C#IGPnCAT=k6>(tCk?gW`6eVyvg4Rx;5hE
zCeUqfpt|%3q}K{MavYND!57bgmM3(BC;33fo`YsQIxoE5?AdGb-MiQ3xkoQ#Cc&rM
z&ZpZPG}H=eX(I~P7VtcSPv-|vISVQXz}`p5PXV7*;n6z<(u(ecmcNsQLG51t7P0T3
z<3;U#I?Y~kgF3dyT~rbnK<k71K7l08f#v}nK7p=u1Wz^p{`vp^OF=~ajkcZ;G}i$-
zv==nV=h1o26SNiYh;QdvpWdkdzMyND3k9LGeG)>T**?fA9z0-n4d_ydAN)NALZJQ=
zv^~e)vH{d#0iULs&j>!~oSnbr7(YmJ&Cwq|me1?%cr?Ff1Rboa`2w=mZ#O>!gRkXd
z{+1|a1_r|eo)=%0h`{<QpxVRp;;Yi{9*hS(dSe+qJCA{S37}O)9+vm{`&d~)?)wHh
zz2m2+=1tG$pDg_S+MqQ^oj*J@UwD8zeXs027(o+L9tR(>f==*Y{N%y-;<lE@!3V4!
zj2~`i3Eb9zoKNwZzpaiHbehHO7ga)#P56^oL8lCWcDcRgxqJKW&DU&qZ{59d^CV;|
z3Z$y`;PB}767cBs5b)^slJMyCkN}+^0p2lRCE(Hd(&OMmR-axLKF8Y{(1S2u^S1?n
z48DEy<jqqzLFaLB+&p#vMU@H2_}5H#Z~1_>kZ|~PdvW-7dVpvF-%bw!pKdP+-%byS
z+g7)$1fZt9mc4oMwIsZMaP#DA9*}Ec;fLh45*7xAySE|RVSj<W2|C3AbaFT7h-FYO
zEP%taI{>ub4m>aoI%^kv?nQ;bYYEW4+PgPi3xH_IF%;18x!w>y1@L~NzqhqKI=MW$
zJvcl%y*NC&Jp{m;_B}ei1U$MuBs@C3ByL;Wt`GptI6~ddFVEluI*+^af=}mVSag8n
z;`Hs8WiFt-fuN&7K!J4oMHM87;z0g;&2jT2)c)oJ3ZT`4w>5k^FN0$7)a{q$XKtQ+
zEe4SX>AiXS<|%l1yyS2D!32uan<rnhrA+_@|NR$LJm5%J^;+oW$=7^0Prl}YslR#B
zw>S2`Pv<Rg;$i%BTMO)~+po)9Z=QV3JOQka2b5N-LO?0wwGcRjc<$Z+#R6peok#O4
z1yC!s`86Y4d-<`Or$PH8Z=SyWn!jxtBLl<DQ(*U;1e+xQHh0%+ftx2mu1EM6beusy
z=<Y9w$0m4mbNF`NMGJV0Fn<Z!d<ojS+gl47CjcdTPs?B6v;kdL(F<8z>C?LfJTdCi
zy9QkR`1C?<;PB`??9&;eQsL7HS=k3lIp7mWKKOLL^67kdJ6qv)wgEWFLk=vtU89n4
z^T2J$P{8dPl>n$5sH(bMqv8OT12su+*Qgl0xW*4E+&uVQ-rvqqF}R(h5^($E-J7>_
zR2**Ss3d^c9?i!YJ(>?Icv$WMFD>M6t^N<%CJEXo`2w``y#giuoCG=0^WbAvAI5tg
z-D2Q9uwme1u{^rNz$x6LJ4^zU!f)H%t`h*?0SGD!Q9Avg^)*#o{4LU;*g5^0<>u)$
z@c9&=tvs*UZk`6ogZ6(){QLhO6fb@GppC7!?%sOM2}%k#Px8w%cy@F6THXPLodKxh
z<KO{W(+kNWpq(k8nDT_?4rpHEZvky}@$LNS)A`7!^CqZO04nWX1o8j>?_-^!V!+?G
z95iIuc^6b3f(pU@-=Jf#y4R?H)bY2R<_2xl`sv&G0&K#=7ZUvc|G$(353n+TcBED@
zm1x|4Q6&m;B<N%V(D4@FTXsP!D?#N$_3N9bKqp+dFfiP`dGplmm;7y@v3^i~1aGRk
zc^ahUH+V}fD4=h@;%@_8qy<UzH&4Fg0$=!7`|o8KXxA_}iGvUIxbd0|oNhtefV)?M
zx1)k~td{+TMCHqMAfeN@UzbJPJoTCdr1bWSDhW_t;O}br1y%&wyDbEEIjB6oaT9!S
z%-tI=r~LZ=AC#HO3P8m(X#XoCWUq5Ks55)><ja+yKJ5fhe7*pkSakX|6WAMFCmFyS
z(NEugQN8W%t-H5gDuNWk^Z)7FudA3!B5uE^vIEJ!W&wo)$orpu{r~@RAJo<=wvyDF
zU?cCpsB!}-fdy<fNSQ8J+5H#Qhd_S1dGfUY%zRLR3@U>_LHH1yd_afbyi5aWICc9)
z^)8Tx*Mji!9Z7xr)t}(a+}%82#V_~#1c$&2{%(CxsGocd+TRV{{oV%J0|W}Qn<rm7
zLp51~G@X3;7qkny^M<S8B~T|m0i20?c`#4He+eEk1l?+L0=6g3QNgqGD(I}Bm*Cas
zknsUf>BZl*oefmN-o5pj4OAL}YD-X_d*IO>zyUt4=A=hwzzYvZUGu@CI{;K+f=`_L
zaXaGy=*XdrgxeVfw=*1WX9V0l2`V9vFoQ}+P;NWL3^iK};-lAmP#SJmK!QhSfP+VO
zKnCdGn*`7X^8gQz?tlW1&VT@q?tluAFo+WYwc!-FL;{fp;6sbrzA-^;s}j3;`ZdSR
z)1XMW396=@K>m5nclS2vga}an2eCZ50~|a$13=#M02%E7wh`pN0FTZ9kpCh;!XVC%
z*LvVoqydlr8{otu0TvYk?Ux7f5$gv)<>AdUx8K~o!{0Um?5fv1AlJb3-+ocW11cx)
zzo>G$dHS`$&C{TE%FR=t+66><bb~@e02COvD-v#=^5_H&2!MkEBv^5~0u&Gu;Hu!Y
z5xBNF`C1E<B0;`>4LTU;^v#p6CBQPLUJKm44U>b^ueTvbK!J{WY6GqH1jT=q03>ID
z&NKsu7Z)g$UbBGOPafR?3gFT>Km!ye3gDpP@aPUO@aP0xm=ItA5;gz}OMoI?8GHr-
z=s1x3FRC~|3BVF`Gy}Mm08SaNz_mH3w!QzNiVKwSe}RvdxO-z4Xh!8VFUSe-{Ns3A
z!-w&bC+Mmp)&-!cnS+l&TL2Y27*B!QTpka6AdRjUKHXjdj<+*D+&t;q>G1*D^!njz
zc^TaL;&1uH%)kH+Hb{~MC)0M&+H+7T#NP(GdJL3g_`6=PF)+O50|zGuDC$5gaB!Y{
z2`Y6#B{F{-=*&1+oZWs=B?byd{;pG?5&?AN7pTO$1#0=+y#dZsH$kPu?brP6PeFw+
zxZnW=)<#fZ-3FD3AdA4}oCJjksPhgAhSwrsk`F|JOaiAj$O#rNL8G*w^U*-1{Weeu
zc?uNR41d9;?hT}L*k1D&bdCTt{&Q3e?!V!018w|<q(lC$eIR*|?rt#a^viP4Vp(YU
z04m+BLB6X}xp@-Qt^uV|5TCyb)L93$U%@RNa7B?e0h}{Wf*J`oPrpor?)NPRrGOXw
zT~XkQ`Sy$Iv!Lwrk_mDM(@Rhp4;qlZ32p^|eDMk7A8@7913FycHmHgKPkK*4_zN^L
z0=gLvBmxREQ0f7v<8DwGKwSB9Eyx92{4E_Io8iXiKu;q9RSWT;D1%r4+K~V<)dK2V
zNsuOR)d^Z70e14^U;qDuoD13=1gSqj&fNz-01I5zoC4L4;h?b>(CrFo6CjC87@Fo`
zDIRoj5-44OvI%I>BLggDz2NT#Exf*Y3U;2&%~POM;|8f`U+{Oez*ya&!DmoD1*NQ)
znsDKH-~<La?ZXA!H+se2-t`Mo^MF>Of#a^b0bHGc$_DV2p^$(B4GF<2tk=BY@c<YX
zRNsO2go0xNwB8A#<37wbr1Q02@waUS#TvNZ^>QPqmV-nkNbRZDOkgjy9fl~mb@Sv)
z&{#UeIMDsBH&27oB{<yLA3@!12KF8(Xm5breF~Z#^+Cd5vqM0pfn)LJ$(MGZoq^E)
zEofE=Y1f74_m`dre}a#1@zFfx+5DHuv-47&7HGO2yleBgiwc$n2(Mn0egG{%0PpJr
z4TJXPGy3$pus!hVWfAu1eC-H2?-1NM1#d$J71SJ{bw;2X6Vik9gcOz%pq&xmUe(K`
zpTM<0sIj7Z`$d&3s8YOp6Vd@OymbEs|Lj8^y&*!3FMol2eER;2>ZhPG6O?K|^zE0R
z^v=NFehwrJE;Kg&g&YC08Z@j0Iu0CE-}!Vt@aen{>RE%=Jh*=N|KCINy~n|)tf0f*
zet0mx1ML+B9peD*`+wx`DE#{WzvFF9AJ9D!ohQI2uw@GH_kngs`E*`-?F33cRXm{h
zsuBm~iPxaM(@jtr1}ddIIxj-HRG>~7sC@~pMs9#da+(h)_*fn)u}0KE<(ojIX<0Q=
zNqQP={uYqQNSaDdgA9j+4yb$X(aXXIF3cfi252K^^Fall&Wj$PzH#6SP_^mV9ryuM
zNqKe${s8qH9B)@XaJ&sUVXjr`|Ns9l+rEIdH<V~Y47vTHN*vree!<@jx^U<&xT=2%
z8Z!b_4AoC>!V_=6e@H2N^W;m=seeA5_gxL&8oqsb?H%Zh<yRgDpR>XSggg&EVucSe
z^+Ha&@a&Z_@?iYu(+k-ccU${*w!m$@+t8j^o&dBPhPMkA%mnI!@wXfT4J>xEf%1$;
zC$mSl8;3`yGlxgFn}A2Bvw%mpn}kQFv&3yXP%(MCPT=Jv@N$X!hHqbLzJs1z*v<Y8
z#Cj?I6WU|(=zQ(jTl>$0-#13Z;ic2(|Njl&zWny~|NpcJXyZ|!ra5SxL<Fen_5kf<
zy$U*$r?W=|)R^$?jrh;s62uQ#FaeqhVc>7c5QHq40BM0Om<WN2fs}w3On|Rm<K+jf
zmFNSnm4KXj2i5~!D*>_q)Y$^-0j-rd_*yXyw14%&5AgogOMD>Rp!>Hy;OE^5g707R
z?YsjTg#{Y`JMHcW9|MDr^&GIX`C9})OCvA7;%{jX0F7{=3~GUv?17I>>pbRb`NgO6
z8-HIIcnA%=2tpK;;lMY$!InT=WMg3P?+tm%0G9ayp3sL~nCb(%bMgl$LHmG?sJ-dg
z>vELgwx$ngYW)yo1mo82Oab^P1b>?jcpwNd-sJ)smV%632!YybkTwT6H{QB?3wcQd
zs29xO-J8S8;L+{N0GY62^<caOGyD~Q+kDW7(=AXF6+F6S3eI!FAQE)SETlfT0pj{V
z7D`|-=(X6*laNsvNP7d~lA9;tizkq+e9hm+2C@?D{`)Vg*zUim5(3qU9-SN@D}1^+
zKs@i>5LOPK&gbw&6dv8K44_@H;6)UykTZQV1i<d|==Edt?F~800G&Sp2lqK}X9!e4
zgHG?w05x}C^0x&tLb}VK#zPY5EH+{2`B<;HZk~j-*FodWpaJ#Q+q`>S{xW#>mNSC(
zq=8q5fV|>q2^nJI?*nbH0u9H2TB-11nBFzu<qM!S7ND(DKAm&Gvj?DI83$-1#IxJw
zD}!(6N7(7GKRv+XoKTm7j{Afxe7IesQUD%>0j*sE57$8CK=Xs(0UM;z8;2Jr|Ni}N
zJ>bLd@()xpz(!@jBQ-fH1&|S%V~ie_TU0>q;BPH~mS|vK`gB8_>Cw#rDRRAgL+&zw
z7fLXAbaH`5UqCq@W%LCW-=Owr87OFPfJ#mNF3`!5pc?Bn52!wZr-$D7{|HkLp!)gt
z>oW1XH}1cvV!8dIN*`2z!8Y|?1hoswtU#@j*BlV@!1V<OXc(mGDyS0=T7TgI?>~Uo
zU)%@n^?d}IvI37MfX<Wy*ErDeAy9h{T=m`rC;NWTT8!hMWDfB>XjKNNtN^FFP9~pD
zSI`BLpq-TcH$ii{&3jZpWe@{@%PA1IyF~?DOd+qz0LjBvWq>82t1>{w`t+v%<L}w{
z`~QER-a<yt&hyYxrGFJ@7NDgDyuE)4xL^XUlmKZ*6nht6y#Dj=|H~}!92aOk2dF-+
zVk)t?{h~@4(mDi{2#E9yYVv~40J?edr6Q==fAao|>iaiOzUGGJ7f^2&beiuM$T7Ix
zp!K>p!Sx=f^#wY){N~A*_W%C>hpGp)1Ngf^n-xKE0%}jb=76z4ZAQ?+wcs|R**{1V
z6m(DE%VnU27rp8KJUh>WJpFPrs1XAmb^@)R1vMK$@yXxK0Gi|jEti1DC-}6#Hc)@(
z?hR0E@pnytHv&QJNKmxB1kLdw-1nLvtR8cO>JnmviU-vEdd&t2v70Afo&k-}SwgFW
zzCiF+WQbGaK&@ENAQKmV%Y9Hc1>Bhfl_8+hYe3e6`T=)uf`ZE#v>3wxG~o!p?-1nv
zDz=geSeRBN-@Wyk1(ZKPF#~GMfsA+wI_Mo-o`DXB0*(EF!?{ZX;^G@OPl9h|2MJa`
z2lY=uqko{$S<ralEB-bSP;Q2_zkfp8-_^6h<KK60fnwJT+OAFlh5M<O0$>W{04I<}
z&>$TzH2ffO0m{=kppMdwyEk6O{{kP71e%p*0MDHIbnXE!D{(cv<l7s=$^crm02((&
z%%~z}Qhhq_LB^v%CsBIz+Drn?s)1%vJv;xu<NyztfO=F<Ss56>oz2srBn6(bbNJ!W
zX#qNNtn&h>xbp#x!ggl}fT~c?QiO-B9-x*MXzj?Y+nT7A=6ATc^T5?7cvKVA&;$)^
zpY;HZh<gZlbY@8SfbKoN2uin^pkps{R06<r4QFq^sL}y72VaZby?gg2cvj^OXru|;
zAHNG8`3?XbewgtCbQ8mCox68$p1gVH=IPf;pqRaR`n43SJ^|$gunY%`1qxeTumize
zqZd_tpc4E3iz)-KjZ$C|KEDP^9pJL+2G~{ypH2q}a4mo0wFuZ{pz&5NP%Z|gs=K!!
z^E;rEb3wHgq^<`K{y4%qw_V=g!usxw*N8z2$Uq=?&;nc)J8*zTD~^M@xzJMmI*5G}
z)P4hpI=mI}n!oKPytB*SWeaYe>;kn8p@k{qC68`C(0Gn#uL$_aO^@bd9N?<O?T4@B
zFAvbgmh3E`%SahKx<Qv+90aW<JcuWH+rcMHf=dt3iT;pU=OdOu98j{kdGaM_3lpds
z;cv4C`5bxpMFi3l0Oe-Ty&Iswek}+h@7@6AFwpq=jl0nC7tp<4pwgDV?KHR;xc#C^
z3e;~0C0J0F1SR9u&^+@RJofoo0GwVxeI@AF=gpHZ7lX<Z&;jaghM*WZ3(|J{@Bjax
zsv6`D&;|!cA_5(kdK+A3gL^42`P)Eynn2Ybe>Z4#3up-G=E;|!F&xBrB*dej^^cHn
z0bOT&^Au!w3p9fT9wz~f*ErlfdGqW`M(Bp`tI#2kEg(06d)S~kb$Idk6jYZ&$|pAd
z7SNf?U}uAZ^CqZdgA{+DL(gB{1iSb)c#sFQTnrMzAmyOi66~mMU&x@<&6l7Hwn4)y
zpaTLB!z-W`4s`UtTMHaqFJFP`MsR(1>h>#;4$zJ2Ae+I#(FHo>5X|ZZk00Fy<p;1&
z!Nti-U(l{^$oLjWFKAL9VcQh=`~rXXHLz_rPrd}L=mYx~5}toSK83bg`MWZ~ZCFrC
z6*8710rE0<+z8Z-1dWg(#Rupx{kABO3h+$fO9fE%1s;6!{SS%t+wb_>m;Q$I<w1wG
z-#q&gw4e`E*z<R%K&A?i<~u>9l@iFEVDoOCe5nR95gcbO5aCm=xsmJ7*Zl30(Aphz
zt{=o)UibjY%XE<Az|IHl+yfU=r*59aG9CoFtOX?f@+;g%&^8@V@dXa1c7N!MPBBRS
zG^j>&1<f4Yym|6v3OE8CK=suN{%+7|9yd?E6am#kV3((Y#xP<*C)0zLE+Q%t(Ao!V
zOLMMyXdd%u#<w&Fd>Sw6*bZoxxbx-<&5!^8gZhJ@D$9rQn`dv03ZrLl4(kukUYD;7
zKArzOx<QBYaCmfrx=jKv>pnwAZrDl;A<5?ciz;bQDFLbZQATfgKwbw;3_S&f6vpVy
z%U_UqJ_sGV0o{BKUV00wFF=8|3=|lktKD1;|NHbN{C{cp5wy4b4rseRsAUOSP69du
zR{bMrMae^dP)7y49O$P9=*qQb#8tMNzk>GbBP|C4b)G<H<bsCh`TJPFn*?sX_C`vt
zr@-C8)3;w#NrJ{?UW3M>VI|njn<qUxFTUmn`5iLi$N*9U9=EYPRgwoPr=SalKo&s;
zY);>PS-uifaF!{9vS{^LPy)Pl`|fQYe(zJaZ-TPw>%H*wTE$ip11mDBTtEiieo@r|
zDTtu<l+FU#52;>oFBD?^|NsBX&0jzx;kRE@?*Ns3;Qj+>e6_6<-0T6x&`Z$479jJ$
zZH^1CxBB;%{AKX&EqTfS8pQ#3;(8&+7=eawKt+>px1C3~9cbZD=Pz&@1k!)=V7v?(
z0|NKfv~NTEaM_@-9k7rFY`7-_Bn0X-zG(OW>a+2;@O}Y}BH8(L+P!1~E%1Ub8ESnG
zNiA!B{Qv(F-0lSz9Qxn?|9=Ud9|UucK}K`<KwFnO?|>2p-~0dnCqMxFY=Q0^l?eWA
zOs<BvL2bAMpY9x$4ByUEpaUriJX+s&9^>x=HOm|<KKOK=uHo^uyjWN4*&D?O+J9<!
z+q3glou#klEsxG0o)>@lGT!p!Uw_EK!i2F_?zOp3=LH|l8{p%(Zg_Ma_TXQC-@(E}
zvPQ+T^N_FQ<(m7xof1BbuY4IFcr?FdEK%wFz`xDt^;DnE3!a^~K*NzfotIzFg7hbS
zI#0VA-hSN!>uMebm%@nji8w6*>;sSP5|sp>?i7^*kM1>)Qxmo^fi_O}-DO~4=sfP(
z`PuNcgT)We&QCQWK9=|R`#^^~`t}Ah8r}w*>}h$+xASsctf%H}&(3$A7k_&)-uC5R
z|Jl2n#lWNWKt+m&<*~YWPyY2s94u@YYYko}`*hy$0Q=U1@djwM6aV_J{@o%5zO9!k
z%zZ4c)fxHnufO7CVIx@M?AdwP$MSZ~S<g;M59Sb+3LoYk@Nj@9C>ZQJfADX!dI{Q|
zxa0r-|Nmh=c8ojh(|N<U^D@|d9=#EazMZ#ThJcp`fbP5fWO(}}=sq{Y1Fz4dO`vuB
z*5i)fy5SeU^`yja-QbPiBBJweG4A*+qDB0I%i9Um$j?Po$j`;3#CH)r;`=3Nmko0G
zz|Mvtsr)8B{>yR4f7$Sl|8i2|zii;+e>=hYJI#{#`a8`MXZ@XKiNF5dPP_VhJEZ;w
zos0&pztb#{>Tgiz8?*k7!&QIhgX-@rQ2m`|X~S4+_&N_y{p|#*zimPFcbb!>jbKd>
zv;seawF39+{K3E7>SY{gCjxxD4|`RPDDPnPIcT9es6Fc0398RQyIc$pygrUzpHn}+
zan$Fa_{LYC57GFpCn>(`hD>}DSH6StH;(!p6yNyj_W_7+Xnjsm{w^jdzKe!oeB-Fk
zLGg{RJ|Cj-T~1Pbmko4$cjK+TI~f=lCLmScC8*tRbM)>vsP>k9ZHlG$4XV7=pq=jr
zsGV>1&JW#2uV+H~-r)Tm5scvOH+237+W+o`^+rkVe|JNw?|X>uH>CC!1NXl7g6^k-
z_P)XMSJ3`<46gb+2~>Z_dh)M70;;|ZUMJzHzRf_@w;`zd2G`y$(Apb&_uHZKN4M2W
z(D};Pt88d^!0KzP{qIv~^)=Pww;pHw)(yw_ttTaZ>jrQ9LaJvX@^3ND_$?Y_@moZV
z{98;){1y#^_$|j7zh%QQe#=RT-?G6QzmVZ?BJyu7&iJhvWbs==jr?0nO8nLggZLe-
ze|?aqH&EMGqxJ7CI<}uj>)$>^|A^@J)oA^TJO2(q{p*3dgX964fNlqE_yhNVAu(Kp
z+5^UzfcCI7VJwz=ZGoi=>|tplS)>Z>1EWnqD}(Nt>Na{k1=0(K%|OotjmJX!zrAGl
ze?6cbV9@xr2Xp}21Kb5J5(amHPa$=I9T=efU!3#Li1BL=OB=>w10u(-y)116i-PfX
zfc-%S#B@U@pb_KK*gL}rd02m#sPSuB#CJLF_%0iE@m)?ze3uPKd?Vdo0Xl3f!-apl
z5_pkGj!J<~=Lz4|Z?2t>`1|ZYw*_@RPiuV6P?Og9pP`1og_V(kVS-EN<+R4fAhF*d
zv9q9qv0Pg(@ppih+NZg;KB*8%bG5wU$Ups%EC04juC14RI!~7hfc6XZO#m&w?~MR0
zQE}~j?%Me@&9U+M|N1n?#;5<8eJpR+Wu;B<=)3`6o8sAd$cKOZRj~DL{M$tY`CHC1
zFfh1uUQ26y26DnbkQ2aXXMvpnI&2c;1pbampi{J5Egw1ZPl7pvzXf!eEx7Ekyj?%T
zqw@xMy@qe61azqf<nUC`X)63Jpgk9^osU3a<AM?ht)R;{(;UAa`OnPX0y+x}Ej+$~
z4{JL85_CR1*!(od?}tEYqyGQ@?`e71qw_F-j|Awl_%_J;nKakdxBM-j+rm)2)fxnv
zrh;k)Egyktz75*D3KD?pe^Mcr=Ggd)p}~QF>M@Z29r>poa^(C33jdd&>&em_8z23z
zPjj{W1&bE&tTotukn-~-Xz@6h4|Q*=H)zKKC{#PuA*?4A)(~6xryfRFatmyU7)S}!
zt^Yvo1D*Q?E0MuhKDcx~hPtBhF(}3@Z^4}cT7ZfuuTb`{HNTO7EgEF-=!RT1;n{f|
zbh1JP=nyc_ia^jhBGBqA7yj*9{C&mXWc$Li^P{WbC6~_ki1b_H+Ic9g@ewH5`~oE#
z(0=l?)&u+<N}vM^U0dH)2&TDMzTls9fPdS8)&m}$pGysVEYI=xfeyX*?2Tk}HN5m%
zZbF*l_oM%rOE#k#23jiX(fQe>^Mz~YJI~IWX{sPkHa-I->&t1KE-HNdeNCWxMDwCY
z=L^q^KYbZ5dh)M7=-Dm8;9+@<zt0quH99YN9DHHla)7^84RlN_|N1N7q|d*dMUcM*
zbeamkJOi@5B}HHl+yp1~*0&Xz$Q~$(_U#R1^z6LpV|ls09ll-<bW&l34>M##fKR6Y
zXkjJza6(2Gl?spMHQ@D5jQlNHjG&D6!j*r!{!7T^R*>_W(^mdxF6r>KJXO0DbkKI^
zX&=oC;FV+-K$RE&`n%rUA`%|0mnzacEU(oidcr*6*?AD`k5+3?x^`{-#@_<EB^22^
z{H>rnd_WfPw>W^Z$V`5D22lQ}uu8LKXyBiE2*lx^dVuo+|F#3*16a}~fa^bx<|7g)
z$qkX7z%gMBih${$h<*7Obckr@XIH~ZFa7@g|33j@-RHmm|NB^;t9$xV2$Ympf^w`5
z=nPuRb9EPA{sXP12Bi>rZ0@-5_y2#x11~{W?z(io0^0}9Zk8ALAy%#jX@{*BMNZ#H
z<?khrZlv<}F@K*PI3c5yzo3g@Cb)FoMlOH%LdxIU{2eDDtS8{|_l_g~^uw<F+ittI
z-bR$a4WL8@E`Kj!D}OK7B|*zy)EIT+-!3ER(s>WL(47iObC7BQ)II_g2>czO9d>E1
zt+y)#(_AedBRQe8#-}%c5tI-Ycz~A531BI5Z9zA-bw0*Y<bv)7h84MgLHE6(2Ek`&
zkqatA(?I$2Fevsw%k;pxr$o@x@({S#1??Dk2|Bh8oQzsQ*TKQ0KzsUMf|hPifXMkm
z66q8EPVfQiAU~<4IX3=*m$A1U`KKOs<opZ@<Cmbl%CPuNa|9P~u9o*<{(lKN*9V^e
zz~$|wmo?xWS}qI>X^!7P?rjBKcmN7J{!VjH3ItW8pz`)NDBZ)#+ry5Wx4{;wfs{Zr
zwlIR$&C32mUXSP)e;88Uf{I$Oa~v&i!=3XIlpNvfACS|d2Woi>Il&5ld7BJQrY}4@
ze}c=~*NC)<UfzBNrB6_KD}<xG{Rb*<&-3?z?m+bHEyP>i?gFLc&VR7-_9HmgIYP?Y
zYXr;N>->G7bGSVa<t^w|Tu6NiDzHEW6>`B;QkB*SZtd&`rFu|>-2pn}D6REC1s}M`
z1?ThD1EukhBKM<@<+b`2h<U`8w^I1Z+Xk@xCB~p)cOAIcJ%_8<4fL?QUgzW4dGIA@
z|4SMuJ%1}X{xTW792Jz_Kt*pWXm$*o(mO#HFoQf|p61y27nIlzf$9`k84J3-0(%Jy
zPw$|b&Jt0+g6=Nz===vNUqL(ZpyexQQ=yOL`MResK|3KJWiIIUL6F$Rmwce)jI(@w
z04ZOqK({nvEnoM85;V*`i1oE4DiNSln7U(B5<r*NfeP3R&{FCGevK0zt>1h)PxJSI
z4hG@ZJHg)$+NlF>|9}p8>;kPC_q4pp-w$d>LUQbDE=YVr3$nU!a6xtl9t}SH>mPh}
z;um01<kve<ev@DCq$B^VqiGXBH=?q-w!AGp1}ST5<=|R8JCFGCuYU~JRd)IH!U?{e
z0v?R7JQ;s@G{0jkQRLS+_?cgT3*^SO#Q&h}1E*g%cr+gd<&Kx2J;AVQ?=a|i&4=KH
z#-Lggk-x)WA%a+c4GM|^k8Vi*1{n`tfGr2wF{^P9yaJnF?}TUPr*boJXmEmd9e|c%
zgHC;cEaiGF0}F58&Rd?HhY|IyXKyqkq>l_az1~yvHh2v>Xq~nv|N6t8-7E|qmdE(}
zKsAVG=Mm3?Z|q%Lp76JVE}r+`Uw;&Ii8&)E47WnU@CY;npOh}~vAkVtk2#<G9k!g?
z6*Qmh0O~S;!&K0>^A;%J+9N=1@6N-ow}Q@(!?v_r4I0cZL5FpN(>p9!9per|R(yeS
zg5iPJ&%sC5f^L|6`4W_BCpbcG0)$*BdkM6>JpvS>pe61Jpm5IM*Es0W`roJX1b-jo
za^4fZou|tc!66GexZKn7V11M?XchgX*W8fwQUFS1zLuBk{L&`)fcitw`WUiS{~joW
zBteI!U-q;-<k@++=C*IAfDhv%PsSIZlR!(fpuTxM89Lqx+V^RBxqb_ZGM~;HrPm<d
zJPf*su^Vbw-|LN_q|^W|GSVg>uipn<mJ3?H5AqjU`gy|N2TC3M$m!=>xjxvJpq2gL
zk(5oK7I1Gdqv7q>qOkM>3eT>^plfEq3Fn?~=jXa;^hD#^Ey4g=ub%>n;CMs?g92e6
zC{<{JSK!}6TIYY%hkyNh|85ZtkUkxdK6TH|!><oxt_*y`SYibYv6rAx63qDjW_bH0
zDD#1?a-R4SbmJr<y&E2QeHrA3ZcvN$CFoFO(5Mtb9+vySDFap>fzBWY1tO$8^65P7
z(fSQ^$02_oxLyG#TF`|<pqva2LeM4%aDg-z(%1p@ML5Cb6)36rSYED+z)~K40+&ai
z!+XnbfDY{imq^g;^tSXUt^x_6t?c6K`KSew4(P0S&>e;#Q~BFKYbkv?Prn2e&XDpE
zRyJiI?T`Rn_;;ZC`b*FezsTt+M<oLkEZ}?sPfsAj!Q~O?f@_d%-~tI`9jHVy0r`W!
z3v{0ZI7xj3Cn?bGkk^vn@W59dfo^U>Pg?Nu2y}i9a(M(E+vHz=^b@}T3nR$-@+}~{
z9r<U04lzDZ#p>Gfq;w%D@!8@jl3YM3&mNRw!J!H&l0athw}Wb6P=efynIPXXmZ*a~
z4ho5v%%JPK(6*aEN+h-apnk{e=a9q8L1PNwA_*J{Na+u=d;*z^D4#$_Z?ygg*~i}p
zx(FELJa7pG@-093wkuE(6%H+;K(~k;sLBH+J5UMbgQa`|g_tDxv}srYbql5BDbWPk
z26DygNfST=GC0ep>(KHE<dmu&XaUvxdLzWkHUIzr2QLUpLtcN6RNrAOuR!+twnED*
zkVBBt*SB)e1raCtyKaH98K}xbDzbzjAq&dvU7*Yfsp-H47HBmTN-YN~u+l)$pNNQl
zaH#A7B^m-HmM%!61}K3X!b~7<7)vZbE(dw#CFn!|>_ry13j`{&`d@<1LxSW_!vn9c
zL4prlV2Oj<g$zjP1-^d)(th#)wV!TlAxbM>aA|e(06%!g7HH2i=&%RK?n3Z+X0T%g
z7lE=Ss1dai!~j=tpcDgI&+XZX+Hi8Zt)mFqaaitf`^8Og!|Am)bUha&(rYb{TTMRv
z>mS3l2!c+csJh|W^0wqM=x}535hJ|;jJ}qa>!+llwWo}4Yk{`&hl92g-h9n`_vQrO
z&eJbJ*QUYhBTs1C3UmuLXqzEu*Dxd%I>sL6muDbYe%;mrmtKb89?EA|!`n9x+<sXu
z19m0oxD*i&P`Y9VNrSDr{hH_QO^?pcQ2+W^-sbNE-5>7JdBd~w4}2^X)V}oZ7E$m8
zjkSVWt3IG%BhZDNpw#7bTSpKafZ?D3^z6Ll(RmnDQoXkHv^-oJ4L1d{{|(+?N(ZH~
zT!aChowp!v_2@i&|3%ed*On(G`#`G=x$oY5%??igcW;7n>`TzybYQ+Ow)T|uZLOD}
z1OM;d0PW5Pofrw)oey3=c=rZ+V)X!x#@q%Mba!ung4^)G>j&`uGM4t$Z7uZD3zQmr
zK%4wePPqLNRCr0kgIf?(cx6EgFP5|kcW;6chVW|(Xn5bf0Zn0ASW2?nI+C|vmfyMm
zqRJ6k;MLy*w=|HOTe7#cUU$OX3kn@j?K~5lc$g>Ly#Yx*hi|{Ap89$x;r0|L{XF6C
z1KkP?E}1~d$FuWWxis8MkZCE<hI(H}V~XkSO;1a3L6nAGy}=5iEKrx!=<bczrFU<D
ziXTv&<=cs~!Q=@_7#@%jy{n+ab^B%cvHLHoQbC2@>q%IPB<I^&FCn?+wE&_#fkY{K
zoFn8tJ3*~0TTq6CMgDcrK_{Rr`g&p-ynS7w5&$ZSA`npzYG!-1e)|l%k(|FT1k!tP
zHN522Yoo-kaoM-?G{4@7vQmD%OI1}M4&*!mU&~vy=BQD9$b*0VWe>(vpk5;6it`|r
zvUGmE+f}R}%{h>$zg2V6w^IPz#(u}h-|_@B_1XCY(s1PPVSEm1v}u5@NsnMD?*=tY
z!8WskjA`_>ya^fqg_SO4pz$Se{sF0!23Z4EImNT{@XJVuBxJm`im5~f)I8?`732?J
zg0ABLHP1i7$}4`oTV)4eT3i?y`1L^78EJxAdGg?<BWQfc*YYN8JOYvvUVa6QKk1#U
zz5}{Wxcx4ecbmT()VAdZU*`)N#dn3b;SR&oH*)z0u3uwR62QG`Q1`L|Hb@T&O5fHe
zpZNv6Sor&PfaB(ZtKn_0UL7rdjhh~zj@bqNHc&MSb|mPC6OYbYo|c#SdqI6}&(2Gp
zo!@*lZ$UOM`|_{<1l{0U>G%@VABDRI6uzvW01ET%jbik)yj&X!x^w}qv-6q{|N3uG
z&HNpp`6Ca@!~A_mK=H@F{<sI@iO>834E%Z*KJyEBu#~Uo*E>{J1u_sEA**~kFL_#C
zu37EdDd_{>4g7|YzvVH=fX)~E8izjf3kdiyzU9}uz^`%oGrvFt3x7MPamKHAsJsAl
zUMc861aPwfGy??+-Y(E3EFPAZ>ry6oG#>)ZhrI+v6R76^iSJ8QT>N^Ms+(S_gX(9!
z1Jy|JeUrZ}7S!?q-SGt-|ArJXpxd><T{%wh&8urbBi)vl>*soO-f}g({StKj4#@Iu
zXk#6czWDWS^0zla;=lR=C^EW>|NZ~}`Y5z~G(7NnAxirS+MdLkABE8K;~{u{JPpc%
zdKbznK|xyw;vn*)HNN}^3SKX8emn`vkGHFGJUb8jTHdNT1<pUnc@lI-qz5QZg7gT0
z^CUb<%G*H^TL`ip5<HdvL5IxWtgD0N$s$m;o4~Jkp-dW{sHTAO{!7sK0V2O0s$wdU
z1m!O-P)5A>G8Y_0mq1Yj&VQ%T^5canrV?0wyac&_7nC16Anh@f{CEkJA8+y_@+0VK
zH*lPs2IWW4s5B(12T^`>K+liRXbOeooZ2va*%5T>FE~3M1?48>><EfN50>%`p!leU
z$H!`DCa+mVul&fb2aj()P#y;7o|g*HIDb2VU+*-3Tg+h0kD%UxN9(sw`~p!N{C%Kf
z=|Fu3Xodt`0OZ?w8r0b<s{r5k1<8{Pp!(4Ydwv9sTEMT=EXxF4-~+yi=u%ZaD4T%t
z<T2#z2s(q=qw@#IR?t<qK8(*nwt}qu#4ixRQ4YE=`CwTd*mh92@-}}LXcEoW@@8En
zEK`Cq7r4_T4pznnwsaz>mIPN-;QQWXz}-V`5Lx~7Wg#dVgL3A3aQOhb@V)HtOK?U4
zoks++9+V+LeV{5?kRJXn&>T4^OLp<gGa%(hkYx2;kOBPdpmUT#cJp_G%3hFL_`AV*
z(hpHbg6$)&egp-jZ|jp!`~qGa{Cy`F85q*|HDDEF8l;9y163$(pmqkxA^csS7=+c4
zpc(~F9clkk6jbFx{d*f6ODC)1pqZyO7GIXU4a$k28uAi|0m+ikYvVjXcjjFvUz5hK
zcZk0YG@lJ}8QApORf{0`y=E~+&U^_nsPjb{zs8|Ykg76`Ujvl%E`ZYke>-Tg1jx+t
zB2aA!Ue5u_YF(fX130L=K;yEY`Z5h(UxFJj@(v83`VyoDd@<T3{%%mq3Viu7D1xhB
zgYI{{$=?PVZFvcrJA}*^LkdxFeF^pfH1&aw=Jv3>Tt6FHV@?E(@PeyMkg1UJIt^T5
zmOx}~SA%XNJjvgk0;)2Pfa-7J>&s940-*X5HGje?Oi&0x^5=!JO0XO2!F47$f8wYw
zL5T{SqCjC;mIc-Y$uI@bD)TtFKaAdnMMMlJgCZiPyd7*%F4!Pw5S2q~%?els&4FaM
z3uR)U>;X;-C#xoa$^&p`02Kb90#pJN9aW$_dZ79dxXJ`YTJ?L7{OPhIDESjyVS?3z
z^5-Q){_MucpO?V-^Cois1Pw`oTnx>h{&dTqpu_Wt%%65I#gX#oNpPs$u8M`^pxQWm
z*%P!+4_sqj1?4Kt?0KksEu`RR2F+E1Do#)mI9atAn)z!MQIJ1NQ1d6W1h~Wx&z~6>
z`4g0cs+dYZmlqxY=g|ZF-Jl}+B|jwLT&jMZ2ChRvLsTz8H``<M6+vw_X!4r_ZPU(#
z=FomfKD@-=4VnuB<v+Cic?psf!1?nSNZ#<k>&5umv&e%B9<ASQX9@842{JJ-K<iE4
z&eJy!+&lz2ZSf-LghkNdgiLpD-+oag067Kg{tNytP?-%GiUQqrar(6~=*%qeF<sDu
zTC4m)HyXVL-6sP&IuMjwKtp5E*y~;Rp^)X<L1R4pZJ_l!ptG=Uzo^;>(*Ift`F<|Y
zeI`i#YseJQQsjymbgHdK=MNvo=eILJceTCdZ?^;;TX*`kAn0I3&;g0?{uRil5c|M~
za)K{c<L?py_1ABLyS1RHiPxMrPeS_(uyO&kZUPkERcs|Tkb5a0<tO-@vfCingU-K%
z94`nug%8{#1r2djzXY9S2e%)j5_BT!70^+6pvxP&<UmdZA3_Ieh21>)ayK{;K<^U(
z9c)*{RN`^_MU_72th3j!`-Qp+z_&`><nITiG`M@A^?fbKc+esK7a^xKzUGJe2l=er
zKcLehK^G!`mc)U_cUUKYC`fez*?Eh+o&q#hQ2-jX$N&wX)~HnYK+nALZG8gjDTB`M
z0w=Kf-~<Nl9eZ@%x_R*CLGbM-ZAGAC454@0p`Y*fqDlmOV(uwWpz(Lrfe(TN9T5sT
z&kz*iknjeLE#7*qiwIBf8Or=!J)qOAg+RBnfm0Ct{x?uD;bVD=zYnym2X_;LzXRMH
z0kspr<sPIULL4AB1C&zBLcy{3g1_qw$RnVWPnm9>^tHTPn+qQg1m%!xKAo3*HSc*|
z{O8Mf&$sit5C8gq-rXz~9-!qS+@O(CkUc`6yUsg5y`Bs@5^^hev=4IJ9Df(6IRrU!
z4xXsGK&yQ~hnda0c@ktir27t9FzDF~>b`^S*74|k;lubAo(C3!(*XD&%h&wvpk+lM
zn?UWMo2Os1-#iU&-+>Os+z!h5pliwCX{!fPF7fyEgWUz|)Nclv2)g^BI}My@UxU&M
z_y(!=HjorJJ--66!08!uW6aBHP$C0eQKJdA50t)M%OUbJn9qmGM=LQM<B{g$LAQ@U
z3ro<wx;G)GJc3r&LC14%fQIm|{r&&{H5(|u-n{|xA?QTIyEj2CuKhPpf{%a#+sgtX
z4G+AY3_jVp8+4H?NE$i+!NzN0;{({rQ_wNOnC0mzP^iKZI}fbCefJjFt}aj+1S)|*
zmpOtPM$r5YDmQ&zBb}dl5?>(-KHPIA$f6sdvkm#XKywqI3;-Dft~m%wj)+0Nd{Ej$
zDkxv^w}aX{h*M<KCV)=&JOefGKInwmlc?n{C^SK<bwOv=gYF{)Sq3gQLF2ce^n3Fp
ztjGkdhn#Tp)a_SgRv=Y3k?$`A<y7$fZJ_!E)TVjO0Xk(EbidHelc4(J<!8_sjyyvZ
z=+MhkuQ_g>g5-bDr5Sf`f>eWwJO_sRFRIVnJoyqdcmxW8>gRWFfr9k*tFoz}%nCLJ
z<c2Dy63g2!s&wyy(mB)JTOfb5z)Db%hd{=G=X;<fC}`9O6jjxiA?ES72SZO32d&=&
z$?$hOgOmD8P&o>ZUr<s<OV1RSr;Blvr~05`2$saq?$1FhPo40Ur{Dr|J*a^-0bdab
zx(OKERs-Fy<bhm7o&?=@2|qzU+7~qLX$~&m@Ro(3^N_&?x`EYxdc6vIe-Y?BT~JL0
zN>JdNJx|_$QMD2@6$UHM`$7F>Xwwf-3W8UJqLzZ7^UQ9ZMwHK>bDP`Q7#SEqg(2w5
z@0+JzbAbv&$oL^BU4ZTk2d5Kwd3XlYA7Z+B(!=sHf8S09&^1S}GVuT?4S>#PXDTti
z{h~_d?#<WSpi2><^)2W;Rd9RY1w`G8>PL5PBjxYApz^9s4AlO(0SdOBlb~g~otGd(
zGV%<d66&=cYWYZd`3btq6qLY0=ifq0PYy`_f|QS-@)A-$UcGtpr97x`2N$fMlnt7~
z0+p$kK*#ig3jeMzkc`j;I@lUirY^mC61)H(>{e)*`Vuso4Vqts&%frVL=e9p2eJd2
znEh9^xcB4K&|p6fxbm2Qh>w?`wNprZ<na>NdJt&4335It?)_Ockclu*Lj|%b4OD+Y
z)}G-$9~5<eRxK&}b!rA;zs^h0eh;MZdI=hJLgFLV7ttua)Z<Psbt5jl)RU54>IP+c
zLE8W2(fmdO)DHnIcXc)V@6o&md{;4pXXhD@&dWZXkR4Gzoju@9A)t*mpoX?b=S7ch
zHw%w$2M3St9iVL~KAk^&JI{M|9_8-?&98Zau42FS|2nAk4q8>^V+lF;o4*gVT*0&X
zIHRlKTVKn+HQcXFCir%K_qBXqr|sMM52DXk^BuS&@Xn|6qX+-`vp$RuK}J<x^X<)J
z^tF6ne-*T41vE71(G9)Yz4N9A;}q~=!akiE9-TKlm?3w(gSNAP>N>^}OOMXO5aU5+
z@pppO{)3Jx2lc?9BgWA7Buv!R@GW@W$D{d(2BbX#8ZLB<hxGCg<r#8+4-%e`8--jA
zzk$LN6krUXrM4h<cy#)x6nJ!A^8sD{3=LFJV7gj(cK!v0r%(3+P<Zn9C4%<<biVND
z{N(um3Md?9!E12e^Y__+WSWmMx*C4-wS33ly9d0u=B2OZN6(8t{d;ZrK<8ZZuWwNS
zMXE<P53@(>N&b#!pur-`^N=+=9-WYQ_UOFt)A`w_8*)SSYin?S!?*LVr{&$cAm7gS
zo|^YPFaGyrypLuiJJ?9b+SPOXeO(~4`PW0v-1Y=J+Jo6gr2y>m%JrVT@r<69ck9>r
zbV4lh?7ZjE`5PW4-7V16HAMw<&c8?JM^I#fBF3lF0JQO!xkUxk_y<KMC^Q*M+&wyv
zLF@rr!QTnm)8pCs7hI=;`$8CzhKMiE&cCjP-(G@RA)uvDsQ0DOJU>8g>7zz|sHbLr
z=pSnNp>L?>hk82Xhki=(!++JfFgAt>6aK5_LFqUs?FXgpptK&8mV?rKQ2JjeME^S|
zeGf{XgVOt;^g1X#4@&nz={hK#2c_env>%kVgVK6XdR`2~zBVXb2Bp)WbQqL&gVJVD
zS`A8zLFs?d5ObbE>1$B>7?j=yrRPEEJ}6xWrPH8v7?gH{(q>Rv4N8ka>3>lW``$t6
zdr<lul->uW*FoudP`VFF*Fot#C>;i+-JrA{l$L|id{FvdB-CCgeGf{XgVOt;^g1X#
z4@&nz={hK#2c_env>%kVgVK6XS`JF{LFs=HQ2U|uJt%z+O7DZx>!9>JDBTC8>!5TV
zl#YYaeo)#DO6x&sIVjBsrT>LP?T6C$p!7K?y$?#SgVOV$bRU$igVK3WIu1(vL1{ZE
ztp}y$pfn$p{s+w`@1XQOD18n}?}O6op!7T_-3O&<l|PR`^V2pcy$niEgVJqKx(rIE
zLFq6k?FOaIptKs47K74kQ2Jd6B>e9|>2pweACz7PrKdsZHYi;NrPH8v7?gH{(q>Rv
z3`(;>>2JXh`|_Z49F+Eh(soc<4@%2HX+9|ZF9@Rl9hANYrO!d>eNcKGl%5Br`=E3k
zl+J_FVNlu)N}EAxH7G3xrP-kLw?K&f&!F@*D18h{Z-dhFpmZCQE`!o(P&y1syFqC)
zC@lx2`JnW_0Em6}p!7K?y$?#SgVOV$bRU$igVJeGIt)s?L1{BE9qiHk#=xWVv`06u
zq6!<s3m)**tUvyHbh@Z0l$7n{U|?W)F<+gL!K0g(0i@tHGw3>6-apE03}7`cZh-`P
zLsS%edR<gBJUVZJgf(952J7)rQSj(I{Nfl$O}7t7nst{l8^epO%nS@*vpqUlH-ZFM
zK*~FBcr+g|h(7Gm&8nix%;3>^^S=N@1U_E^YSX`P|Ns9#Xfk37XbbswkS2}8kn36|
zfaE>8S-*Y&xtPJD^+1X2{|g@7tWQ7!y#X8^-3}ZcouXGk+|~o7k3mh-!$|%2Fi?PK
zcyyaGt1vTobh9=8_}_WBM6>mF2|u_!-g)D{$g$?vjHTZ^dU^Xn?f`d4z?+pp;~j>#
zUo&+c?hR)2Xtue=;L&-Z^yBM8NalC5cCoTCv>qs7`+OLr{y1wHD;sFQj^T9+$P3W%
z`sOzd9^JD0KQc0S>@Zq%Uw5W91B1tL7ZnB2-9;XjhfBmgzF+p}lwAu_(R{=K(j_{a
zHo>FUM@8Yk=u9s*2GFpL!hg{?FE)nG<52q8f6+ECHU^L?gU+M>MHhn98K<Zibbj&x
zH`V|DXJGI#eC}a*-J|oLhv7R9#bX|p_ewNCE&uNqJUUIaK{j@>nt&)Ii(%u(9y`v&
zDqKpt^8dfbK4YlEU!Op<_d~;iJvyIyG`}hE=sf4q%iF`k#_(TM3*@G5*>YAk23Nxa
z9=)MAKyfcB4H9lW06MFn1+*v4qu2ETC=@I}q2Sqh!=pR&hT%z2dNc6ob$tP1Xn6Fp
zTChOV=6}(Lo@@*r-K=t~Yz!cUrgK@?7>=`k=3rysWMMdPob@dSB=9{tSwC@rm3o6x
zMyKlsk8aig2=m8((M2F*dU@}2Ff;rY-RcQ)@_!FDhFu^-JUS2l7oF(I#_+;G1(fJq
zB|JJ=*MgkT>&oHL$?C+y#sEHz02IC8^x6E2xkSA6Qi(8VAua<r1;W$!i)d~J288$o
zSbAg)R%B*qwqPn@JI=twz`)S_i>XAo`4?k}16*-*960`EJ!?S`Z0ZD}EI*gr_vmH@
z<pZYw7d)B|b9h*OE`5uv=fz7d28P!=q2s-V2Vgk~?A!?+ohJ?>&(DMS5E%#wcAteu
zuZv0qs1)f8QHk&Y-S`YT6C?v1AukpxGctJe@*ZMmX7K6tNO0UC&A`C03v|Wdi#8=t
zh?S^lyr=;y@<;%!*y#N5B36-+;l%?bMurLCT!%<M@bR_gHxVAmx*yp=QGMD2)QLad
z`j)>BG)?Hy&3c!ejluAeNAm#=(Cx#Pr;9{<x*a%NyB#=u7!P__p5|`?^~akJF?uu~
zkg$AJdefux=8F%Yt7AdQ?Fe)^ac@p8gU7+A%$}WZeVBDS+1VI8J6#1FkGq1>AHxd+
zUIqro?hq9o#~lWsPB-HP4^TPi+3CvR(ajnKa$2{K2FHKV$?k06qNt?XMa88z;6U@E
z{UtihFIbu%{4P=P?0o6N%&WuB#^AWa0c1>fh>C?rH#i#yxr56Jjb>JMb~Xk^&(0qn
zou5EOZ1a%_NS1eueR)xVk-_jScsJjF(FQkA<nx|oV`k_)^a8Zy+oPNHJR2L>p&TB)
zywz;X3_jg18XPYiL6fAtyk2aelJ?dMBhc|16G9;az~QiLn$RuV$;QUedb>o_qw`I4
zT)blpXy663_XafP!*HB6jSZ58UIc=IZ-z%Ni-Sim%TYOySDGJucyWpsRAHE2mIIZi
zvUfm~=8@y9#%yfhPy{6%1&>ZvZ8lI$egJJ5ZT`VtH_4;<2X~#COSiOZ>uvs4SI~C+
z?qC+s2{^5w`-fe+y*XT4PnJr1G#}=1>1K9qJ;2{8&&a^g?ak79lD}01#0=(W{>8}O
zD#8T1Q2j8EhvjGfX3$j;KHaKQ<Upx0_k!m>kSjnN`ntVYx|#X61#|c?KJa0D*!)Yt
zr<;Ml1$6Hxe;X4cD9b7Ew^V}}4*acgpn)IF13sY3P~ZD>9`Imhbld@|Ej>D2FT4o-
z`~N@4WgeEFi<Wh>dV$KH+lJp-5AgSG1x=82tJb@+G5GYBp7H6{&2eR8cr6K;A8bCx
z=+S&w!rD}vm5qVFw*wSMpb<1yZdNviZh_WIC3itrltNQn=P$?qS3osk3urdpqnq_9
z3mfQeY>)2H7arZd7hJkoBpm-=eZ3N1zJS936xBZ6suN_H89aJxFMxgSxPt{0W1YW1
zg@g~|LuN*hKYIWC{}1xRotL1437UU#lxFg86ZGkP51MCdJjL+;|NoXtp8Ot{JTwn^
z^|CNIf=d>k&R5`2@CRK-3|<+y9Z3(v|Nm*NsG2|}8cdTENE2v0$fK7xjfI)P<G3s6
z7CD9&6Mz5z-wid#m-7>v5g^yYjJOWEM;Nq(#DiJ(GBY?sv@nB`pR<5Zw=+j~0LKfL
z-~a!6^zxo%W@dO{@f&{K8@PP#X0)Biz;K{E*|wK~;XrY<Ee8X`0sa<V&>FFJ(E0;g
zCI*HE{+2%s3=E(PTMzKJUS?omFub&r8`N5olx1Y_X#T;--vZur)_Q=y1++gFEcyR}
z;Q?@g534V2r-01{4Yid!+fD*=mVnHi%)oG<wBGO%xRvzcs0_qRkIq9SB_6Gpz`<Oy
z6)gGx65LD&2HU9&3<pY5ZKr{>I~ZQt2@01NZBXs}EueusP;F2NmH;{DC1?sAo<3}4
zLHdu|_JAlkur*-!g3D{LbuTPs7#UtX;bdTdS_^ZdBGeL(&O`jIpf&nPdRS!`84M4A
zcU3^rS@RK%!w`9}1D{HR<sbh0{~sa>4$1QnQP30%EWF_DBZU_m*%=r-I*)d<3NV36
z$x>C1*0&`J9=*I7Ow0_&S-&wt%cV+I25{*s0`rXmr04{<zdU+nUowGGi0C6mHin&`
za@?m^^&9Ani*FvC_dk2A-U(`Rd30X))O_>VW3@-;_1AjG*g0J~(^)*4k1=)!@PP7p
zXYd#101nWJfSNBnnvZjII{)bm{^8O5Poc!fqx0j7QZ}#~N{@PgPFgDd|NnpICveRM
z8aVCcO=AKzDP$bk7+!)lTI~W^`T7Z{eF$ofDtL4YdUT%dX6iiH`0)S#{|b#iot@nk
z_*>3{5(+4(^0&8un4sj!-#i7x1SQ!LqjCpuQZ3O0C(}|FSQ0Ihf+Q#Y7SOJ4P<qgW
zCQoo9(4+Z?LNsJ#9h@HcTe?AJg44u3k8alK43PTlI;1L6i1zsZ0NQ?lrf1OU5zzEp
zvc?vimXE{I$xlg`<=a6ePV0e^HQ<Ex|HA9W3E!Mp82MX4+ibw|029FJnZE_JB@~>d
z`CCB~v#@l%4r)}12e=Rf9SQ(V*DsC#gYH}hWlB(?{GtV_va}zPzQBU{l8g*5xj+ja
z;pcNeWWi}N5G4BsHAUKj#BRXFz@}(QGBUil!p6YxazD5Vg*1$yWGJX6ZGNNS(aWm{
zj^zDzpk}7*7e-JJ-Yzlr=+=#~2MO68wPRzL(9Qk-sz>KB(6mS?pGWJr5>Ah9XAY0f
zkDy*mw17wJ?b16Qy}VaJ+QB`K_*jqss;BJO7$Efr#5#p;*4d0~44vmaI<K`JDCGi2
zXk7f^v<bT;7#J9Kf*W6npdbOAtaiA>rqjZsvjEgQs9^-9L@BT%S^Yt_^zvqas7_f&
zFy$=pUo_f|4U+jmIq5Js$-JHeu^*gXyIEyHwx4c2P|6Q3B*3W&++OhL<&^|mvE3Hr
zY1TK;q$JfXV0pQe`?YtspyjO+O^?nK9^D=S9<3)!-+A=%K4Sp6>WMAf+QYE&z@s}*
zz@sxj;6<<mxRtpFta6tv8^h}>9^C-~9-Rk0Iz`(U*ce{lf#)YstDpt6udT=c)Q*;J
z{>5A>-OZZ804hgH1Yfv=mP>Gf^XH4-EQt2FLiFKoRwuA3{#MXx+iq491~!J~AB?4U
zJi2)mz<xPdBIwZ_De&TuI3t5c>urzDo2BnPdU=&WlE+zp{AXnVf#a;-psfF*OKjK}
zUeAVvUpMQc|E!??p%}QdI?j6jKP$L<2#&(T6Fho(Z~kXx_%C`Kr0MpA7qkEV{|`QS
z29n@Bk{xY47!MjAXtWG)Wnd^_`h3{%Kw4v^1UD1^lmmw+q%~UlMwM_H9sq4wa$#V2
zeGU{Vi1sy9KmT?|5szLMMhX7yo@}irOEjBbGJ5p#bo%uAoX~LTcHr@}yx`M$u$+V0
zgTuq}R1vpF^8pPX%M+!K4G(-q?oUJ0qetht7dJ)0`JSU(#-m$QM3foS)k|x%@{KBy
z0=1t&WlmiDVOPTgNW2Lioflt#&U$G*P;$#7*~!L(@eu!ZClQa{7$yn+?M`g12TBe#
zzhLy}Wohu}tvRgmn$x5Cu!e`_?~-k><`}5K{31k@k)icK=_Ak18%V~3_Ak8A@abl4
z6#+Ttq(|qeG{;5@->4D}&^ZjCO3J76;EUz|{{L@1Q1Zqz*}=x6^P-RDK~Kg5j{MsL
z*c|z{JBYMi^6YhCkSICR{EE?|S7ee;ug?VyXn6<<D<8{)KAne(I6yUo<;5Zycvyih
z9qv2<u3us4*|YN?%w}-<gN$d0J{4wW0L3FHw0NKzAo;2D;tSAHnAQU&FF@hLzuiTE
z4Xgl?o<RD2x>=VB<MSWr{&blCAU^Ye`s^gcXP2PS?*WSbZw~4TC7d3umr9g8Kt66h
zpy6S8qVxrlZxHDTn}2+|Sw%tqxdaVsZqUhJps)s=kJEYZg~eY`aC`E*UVup;%!B&p
zst_nVkfIChWvKoie?a;PMwcPT@rdXG)u0RvSmH|n9$(<HOyh93gUa^{2VclT?F60T
z1+PCK?vphY0*AL_=ZQ4OMr+jcbn`_x+=1RUK8!cJ8$q+ttp`eO^KTCn@#qZ^gk`%^
z&~W$Z4LPL&P7f~KUOYaQCww|j7I83pad=ps0Hvox8a|enN*^P|04zQEFy1H?e*FyI
zzH<a+mgWN@-5xBhCrjD819)05l^l0%Jy8GDrQ3tYm+>Yn`9aE)+mBJl0|Em)Y#9U?
zz#~W!MUozkFTuQKP6iKMFbgbO{@g?Jphq(&LqsI1_6a*cRS%LFIzP>WzwQ92&_4Ln
zr19Z@b_RyVm;ad=7@B_?^Y??+D}XEdWef}qttTsjJa&P4ZvX%DGk9G7<<WYGzXf#c
zz$g9)){-Ag3~Bs&V7g4&qxC?YfG4Pt&A`AQz~FiLg%9HakMEZ}6fdNC@aKUGLrDCC
z^jbjmg6J|ikJbYoyFf)Y1H%V<52zUo4IccShd}26LA1l;zwsvn3j;$5{J#0mhd=R0
zAdRVj&h$&;uX9o1>2^`!={(qZ=-^NB#)tnwLpm?(n}3Sc`?j8}h;-cX|9?G$<K-WY
ztp`f<Kl4YhZvM{1z^});;X4yUnMmt_I?f#o3=IsIe=r_$={)fLg5rfv7Zr}r`~og2
z9H8Sj4@1kJ=7SBT??3ZLfO;Jghtnp2jLLu*l?pP7r}aRE^ezU5277+jLl{OlFdTPL
z0X1?OkW7Xo3@CY93*@8OH)~Wlb}?`;FmQ*ca5O&p|C@oKQ$*#aj>^qHH*+8^0#)h9
z9YKaM+_r?L08o2D;1j=~iwcKNw~q>kPv<Gu&Ql%-Unz86aO}K%@P~*hC=s~yHZcDA
z|KG9shjE>ZW8)7{AoI6e0kt2Sj|fDADl<s@IX3?guFnFE26P-`U|`q*N*gYn2QR+>
z4HmGpUMM;LiC=)X>>DU`gkSo^A8{g$U+-e^PFKT|t(Pi!9Cw1!hfC){$ICxm7*B!1
z)#Km;1<*hi$0u0eBHP#7@%H!s|GPoS@bYVy*3<kg+5i9l2iYNnW(R*W=ro4bOZ*+6
zKG^rmo(CT*I4a)q<-F|E8KZ(?Iw;9_fc-V$6Tg7yiLYSSp8Uig0ovbok-v@o|NsB3
zmnwundpW_Ibl~~B@zMYP|La{iPw}^amaoIo>xcbFUU+!|ymk^?e>gV(5Gj$|Y0SdF
z;0SK}Y94gF{K%E@6n``5+yj^1C`RyUHPGk=_mBBS4)8}E0FNJ~@rxWt<BtNRE)8&;
zqNE2FczXCwY<d8tCRlO+rHRf%khB0x2)!MkbkO`$xZc#U^MYd|XpebA>&c38a7<tR
z0g5pf&I6c{CIRWsH2*ZNlZIr{QWj`9OCYV!hs3AjPEdq;9DJnUc=@H{_lvHICww>$
zd31&##S_Rt2L{iB4-`NHo{0F90EYuocu7F>dx#28=SB3~u8-miLvXf-`vOaT1m$NI
zr2OoHrUsOs9QZX$R1CnOsFB96@uAyAMW^#n<0A%!5A}_|KqUW^gQ}pM!Fhq(MMcAr
zf69T@OZ-y~xNsh@ILO})Iyo+l|NTkOMqkhlvqzwn)%<!NcZ14q{x<NIx84vHl{9{h
zV=pfAFfxFWyYpuzhHf7fl~4SUCt5*CmDln!69b6%i9d$d6wZ#|HH5Gaf{I$*&rA&b
z9iV<-=ZRfmp`oGQUv-{1_(NXvP%lf6=E3HljQlO2dn=lMGV!+@0FAE9&H``FJ<<Fd
zbV$}ckOiQ<x}W&tZi1Y_0yaG6@+bbti=X&o4ngE1FMQ&U`vhUfT>HcydFm5?%)wF~
zkdCTP;M{ePU!z3Dzyma;arhIz0BiCmCI)b}PU8>%0A8ODu75xAN3u42Vq$m+>cfN9
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..70690c99dbcd21c2bc72500be6e526b89d99a58d
GIT binary patch
literal 52224
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numeric.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numeric.py
new file mode 100644
index 0000000000..0b728f8043
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numeric.py
@@ -0,0 +1,2996 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import operator
+import warnings
+import collections
+from numpy.core import multiarray
+from . import umath
+from .umath import (invert, sin, UFUNC_BUFSIZE_DEFAULT, ERR_IGNORE,
+                    ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG,
+                    ERR_DEFAULT, PINF, NAN)
+from . import numerictypes
+from .numerictypes import longlong, intc, int_, float_, complex_, bool_
+from ._internal import TooHardError
+
+if sys.version_info[0] >= 3:
+    import pickle
+    basestring = str
+    import builtins
+else:
+    import cPickle as pickle
+    import __builtin__ as builtins
+
+loads = pickle.loads
+
+
+__all__ = [
+    'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
+    'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast',
+    'dtype', 'fromstring', 'fromfile', 'frombuffer', 'int_asbuffer',
+    'where', 'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose',
+    'lexsort', 'set_numeric_ops', 'can_cast', 'promote_types',
+    'min_scalar_type', 'result_type', 'asarray', 'asanyarray',
+    'ascontiguousarray', 'asfortranarray', 'isfortran', 'empty_like',
+    'zeros_like', 'ones_like', 'correlate', 'convolve', 'inner', 'dot',
+    'einsum', 'outer', 'vdot', 'alterdot', 'restoredot', 'roll',
+    'rollaxis', 'moveaxis', 'cross', 'tensordot', 'array2string',
+    'get_printoptions', 'set_printoptions', 'array_repr', 'array_str',
+    'set_string_function', 'little_endian', 'require', 'fromiter',
+    'array_equal', 'array_equiv', 'indices', 'fromfunction', 'isclose', 'load',
+    'loads', 'isscalar', 'binary_repr', 'base_repr', 'ones', 'identity',
+    'allclose', 'compare_chararrays', 'putmask', 'seterr', 'geterr',
+    'setbufsize', 'getbufsize', 'seterrcall', 'geterrcall', 'errstate',
+    'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_',
+    'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS', 'BUFSIZE',
+    'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like', 'matmul',
+    'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT',
+    'TooHardError',
+    ]
+
+if sys.version_info[0] < 3:
+    __all__.extend(['getbuffer', 'newbuffer'])
+
+
+class ComplexWarning(RuntimeWarning):
+    """
+    The warning raised when casting a complex dtype to a real dtype.
+
+    As implemented, casting a complex number to a real discards its imaginary
+    part, but this behavior may not be what the user actually wants.
+
+    """
+    pass
+
+bitwise_not = invert
+
+CLIP = multiarray.CLIP
+WRAP = multiarray.WRAP
+RAISE = multiarray.RAISE
+MAXDIMS = multiarray.MAXDIMS
+ALLOW_THREADS = multiarray.ALLOW_THREADS
+BUFSIZE = multiarray.BUFSIZE
+MAY_SHARE_BOUNDS = multiarray.MAY_SHARE_BOUNDS
+MAY_SHARE_EXACT = multiarray.MAY_SHARE_EXACT
+
+ndarray = multiarray.ndarray
+flatiter = multiarray.flatiter
+nditer = multiarray.nditer
+nested_iters = multiarray.nested_iters
+broadcast = multiarray.broadcast
+dtype = multiarray.dtype
+copyto = multiarray.copyto
+ufunc = type(sin)
+
+
+def zeros_like(a, dtype=None, order='K', subok=True):
+    """
+    Return an array of zeros with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of zeros with the same shape and type as `a`.
+
+    See Also
+    --------
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> x = np.arange(6)
+    >>> x = x.reshape((2, 3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.zeros_like(x)
+    array([[0, 0, 0],
+           [0, 0, 0]])
+
+    >>> y = np.arange(3, dtype=np.float)
+    >>> y
+    array([ 0.,  1.,  2.])
+    >>> np.zeros_like(y)
+    array([ 0.,  0.,  0.])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    # needed instead of a 0 to get same result as zeros for for string dtypes
+    z = zeros(1, dtype=res.dtype)
+    multiarray.copyto(res, z, casting='unsafe')
+    return res
+
+def ones(shape, dtype=None, order='C'):
+    """
+    Return a new array of given shape and type, filled with ones.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `numpy.int8`.  Default is
+        `numpy.float64`.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of ones with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros, ones_like
+
+    Examples
+    --------
+    >>> np.ones(5)
+    array([ 1.,  1.,  1.,  1.,  1.])
+
+    >>> np.ones((5,), dtype=np.int)
+    array([1, 1, 1, 1, 1])
+
+    >>> np.ones((2, 1))
+    array([[ 1.],
+           [ 1.]])
+
+    >>> s = (2,2)
+    >>> np.ones(s)
+    array([[ 1.,  1.],
+           [ 1.,  1.]])
+
+    """
+    a = empty(shape, dtype, order)
+    multiarray.copyto(a, 1, casting='unsafe')
+    return a
+
+def ones_like(a, dtype=None, order='K', subok=True):
+    """
+    Return an array of ones with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+
+        .. versionadded:: 1.6.0
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+
+        .. versionadded:: 1.6.0
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of ones with the same shape and type as `a`.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> x = np.arange(6)
+    >>> x = x.reshape((2, 3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.ones_like(x)
+    array([[1, 1, 1],
+           [1, 1, 1]])
+
+    >>> y = np.arange(3, dtype=np.float)
+    >>> y
+    array([ 0.,  1.,  2.])
+    >>> np.ones_like(y)
+    array([ 1.,  1.,  1.])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    multiarray.copyto(res, 1, casting='unsafe')
+    return res
+
+def full(shape, fill_value, dtype=None, order='C'):
+    """
+    Return a new array of given shape and type, filled with `fill_value`.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+    fill_value : scalar
+        Fill value.
+    dtype : data-type, optional
+        The desired data-type for the array, e.g., `np.int8`.  Default
+        is `float`, but will change to `np.array(fill_value).dtype` in a
+        future release.
+    order : {'C', 'F'}, optional
+        Whether to store multidimensional data in C- or Fortran-contiguous
+        (row- or column-wise) order in memory.
+
+    Returns
+    -------
+    out : ndarray
+        Array of `fill_value` with the given shape, dtype, and order.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    full_like : Fill an array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+
+    Examples
+    --------
+    >>> np.full((2, 2), np.inf)
+    array([[ inf,  inf],
+           [ inf,  inf]])
+    >>> np.full((2, 2), 10, dtype=np.int)
+    array([[10, 10],
+           [10, 10]])
+
+    """
+    a = empty(shape, dtype, order)
+    if dtype is None and array(fill_value).dtype != a.dtype:
+        warnings.warn(
+            "in the future, full({0}, {1!r}) will return an array of {2!r}".
+            format(shape, fill_value, array(fill_value).dtype), FutureWarning)
+    multiarray.copyto(a, fill_value, casting='unsafe')
+    return a
+
+def full_like(a, fill_value, dtype=None, order='K', subok=True):
+    """
+    Return a full array with the same shape and type as a given array.
+
+    Parameters
+    ----------
+    a : array_like
+        The shape and data-type of `a` define these same attributes of
+        the returned array.
+    fill_value : scalar
+        Fill value.
+    dtype : data-type, optional
+        Overrides the data type of the result.
+    order : {'C', 'F', 'A', or 'K'}, optional
+        Overrides the memory layout of the result. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible.
+    subok : bool, optional.
+        If True, then the newly created array will use the sub-class
+        type of 'a', otherwise it will be a base-class array. Defaults
+        to True.
+
+    Returns
+    -------
+    out : ndarray
+        Array of `fill_value` with the same shape and type as `a`.
+
+    See Also
+    --------
+    zeros_like : Return an array of zeros with shape and type of input.
+    ones_like : Return an array of ones with shape and type of input.
+    empty_like : Return an empty array with shape and type of input.
+    zeros : Return a new array setting values to zero.
+    ones : Return a new array setting values to one.
+    empty : Return a new uninitialized array.
+    full : Fill a new array.
+
+    Examples
+    --------
+    >>> x = np.arange(6, dtype=np.int)
+    >>> np.full_like(x, 1)
+    array([1, 1, 1, 1, 1, 1])
+    >>> np.full_like(x, 0.1)
+    array([0, 0, 0, 0, 0, 0])
+    >>> np.full_like(x, 0.1, dtype=np.double)
+    array([ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1])
+    >>> np.full_like(x, np.nan, dtype=np.double)
+    array([ nan,  nan,  nan,  nan,  nan,  nan])
+
+    >>> y = np.arange(6, dtype=np.double)
+    >>> np.full_like(y, 0.1)
+    array([ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1])
+
+    """
+    res = empty_like(a, dtype=dtype, order=order, subok=subok)
+    multiarray.copyto(res, fill_value, casting='unsafe')
+    return res
+
+
+def extend_all(module):
+    adict = {}
+    for a in __all__:
+        adict[a] = 1
+    try:
+        mall = getattr(module, '__all__')
+    except AttributeError:
+        mall = [k for k in module.__dict__.keys() if not k.startswith('_')]
+    for a in mall:
+        if a not in adict:
+            __all__.append(a)
+
+newaxis = None
+
+
+arange = multiarray.arange
+array = multiarray.array
+zeros = multiarray.zeros
+count_nonzero = multiarray.count_nonzero
+empty = multiarray.empty
+empty_like = multiarray.empty_like
+fromstring = multiarray.fromstring
+fromiter = multiarray.fromiter
+fromfile = multiarray.fromfile
+frombuffer = multiarray.frombuffer
+shares_memory = multiarray.shares_memory
+may_share_memory = multiarray.may_share_memory
+if sys.version_info[0] < 3:
+    newbuffer = multiarray.newbuffer
+    getbuffer = multiarray.getbuffer
+int_asbuffer = multiarray.int_asbuffer
+where = multiarray.where
+concatenate = multiarray.concatenate
+fastCopyAndTranspose = multiarray._fastCopyAndTranspose
+set_numeric_ops = multiarray.set_numeric_ops
+can_cast = multiarray.can_cast
+promote_types = multiarray.promote_types
+min_scalar_type = multiarray.min_scalar_type
+result_type = multiarray.result_type
+lexsort = multiarray.lexsort
+compare_chararrays = multiarray.compare_chararrays
+putmask = multiarray.putmask
+einsum = multiarray.einsum
+dot = multiarray.dot
+inner = multiarray.inner
+vdot = multiarray.vdot
+matmul = multiarray.matmul
+
+
+def asarray(a, dtype=None, order=None):
+    """Convert the input to an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists and ndarrays.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major (C-style) or
+        column-major (Fortran-style) memory representation.
+        Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray
+        Array interpretation of `a`.  No copy is performed if the input
+        is already an ndarray.  If `a` is a subclass of ndarray, a base
+        class ndarray is returned.
+
+    See Also
+    --------
+    asanyarray : Similar function which passes through subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    asarray_chkfinite : Similar function which checks input for NaNs and Infs.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array:
+
+    >>> a = [1, 2]
+    >>> np.asarray(a)
+    array([1, 2])
+
+    Existing arrays are not copied:
+
+    >>> a = np.array([1, 2])
+    >>> np.asarray(a) is a
+    True
+
+    If `dtype` is set, array is copied only if dtype does not match:
+
+    >>> a = np.array([1, 2], dtype=np.float32)
+    >>> np.asarray(a, dtype=np.float32) is a
+    True
+    >>> np.asarray(a, dtype=np.float64) is a
+    False
+
+    Contrary to `asanyarray`, ndarray subclasses are not passed through:
+
+    >>> issubclass(np.matrix, np.ndarray)
+    True
+    >>> a = np.matrix([[1, 2]])
+    >>> np.asarray(a) is a
+    False
+    >>> np.asanyarray(a) is a
+    True
+
+    """
+    return array(a, dtype, copy=False, order=order)
+
+def asanyarray(a, dtype=None, order=None):
+    """Convert the input to an ndarray, but pass ndarray subclasses through.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes scalars, lists, lists of tuples, tuples, tuples of tuples,
+        tuples of lists, and ndarrays.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major (C-style) or column-major
+        (Fortran-style) memory representation.  Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray or an ndarray subclass
+        Array interpretation of `a`.  If `a` is an ndarray or a subclass
+        of ndarray, it is returned as-is and no copy is performed.
+
+    See Also
+    --------
+    asarray : Similar function which always returns ndarrays.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    asarray_chkfinite : Similar function which checks input for NaNs and
+                        Infs.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array:
+
+    >>> a = [1, 2]
+    >>> np.asanyarray(a)
+    array([1, 2])
+
+    Instances of `ndarray` subclasses are passed through as-is:
+
+    >>> a = np.matrix([1, 2])
+    >>> np.asanyarray(a) is a
+    True
+
+    """
+    return array(a, dtype, copy=False, order=order, subok=True)
+
+def ascontiguousarray(a, dtype=None):
+    """
+    Return a contiguous array in memory (C order).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    dtype : str or dtype object, optional
+        Data-type of returned array.
+
+    Returns
+    -------
+    out : ndarray
+        Contiguous array of same shape and content as `a`, with type `dtype`
+        if specified.
+
+    See Also
+    --------
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    require : Return an ndarray that satisfies requirements.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> np.ascontiguousarray(x, dtype=np.float32)
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4.,  5.]], dtype=float32)
+    >>> x.flags['C_CONTIGUOUS']
+    True
+
+    """
+    return array(a, dtype, copy=False, order='C', ndmin=1)
+
+def asfortranarray(a, dtype=None):
+    """
+    Return an array laid out in Fortran order in memory.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    dtype : str or dtype object, optional
+        By default, the data-type is inferred from the input data.
+
+    Returns
+    -------
+    out : ndarray
+        The input `a` in Fortran, or column-major, order.
+
+    See Also
+    --------
+    ascontiguousarray : Convert input to a contiguous (C order) array.
+    asanyarray : Convert input to an ndarray with either row or
+        column-major memory order.
+    require : Return an ndarray that satisfies requirements.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> y = np.asfortranarray(x)
+    >>> x.flags['F_CONTIGUOUS']
+    False
+    >>> y.flags['F_CONTIGUOUS']
+    True
+
+    """
+    return array(a, dtype, copy=False, order='F', ndmin=1)
+
+def require(a, dtype=None, requirements=None):
+    """
+    Return an ndarray of the provided type that satisfies requirements.
+
+    This function is useful to be sure that an array with the correct flags
+    is returned for passing to compiled code (perhaps through ctypes).
+
+    Parameters
+    ----------
+    a : array_like
+       The object to be converted to a type-and-requirement-satisfying array.
+    dtype : data-type
+       The required data-type. If None preserve the current dtype. If your
+       application requires the data to be in native byteorder, include
+       a byteorder specification as a part of the dtype specification.
+    requirements : str or list of str
+       The requirements list can be any of the following
+
+       * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array
+       * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array
+       * 'ALIGNED' ('A')      - ensure a data-type aligned array
+       * 'WRITEABLE' ('W')    - ensure a writable array
+       * 'OWNDATA' ('O')      - ensure an array that owns its own data
+       * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass
+
+    See Also
+    --------
+    asarray : Convert input to an ndarray.
+    asanyarray : Convert to an ndarray, but pass through ndarray subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    ndarray.flags : Information about the memory layout of the array.
+
+    Notes
+    -----
+    The returned array will be guaranteed to have the listed requirements
+    by making a copy if needed.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> x.flags
+      C_CONTIGUOUS : True
+      F_CONTIGUOUS : False
+      OWNDATA : False
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+
+    >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F'])
+    >>> y.flags
+      C_CONTIGUOUS : False
+      F_CONTIGUOUS : True
+      OWNDATA : True
+      WRITEABLE : True
+      ALIGNED : True
+      UPDATEIFCOPY : False
+
+    """
+    possible_flags = {'C':'C', 'C_CONTIGUOUS':'C', 'CONTIGUOUS':'C',
+                      'F':'F', 'F_CONTIGUOUS':'F', 'FORTRAN':'F',
+                      'A':'A', 'ALIGNED':'A',
+                      'W':'W', 'WRITEABLE':'W',
+                      'O':'O', 'OWNDATA':'O',
+                      'E':'E', 'ENSUREARRAY':'E'}
+    if not requirements:
+        return asanyarray(a, dtype=dtype)
+    else:
+        requirements = set(possible_flags[x.upper()] for x in requirements)
+
+    if 'E' in requirements:
+        requirements.remove('E')
+        subok = False
+    else:
+        subok = True
+
+    order = 'A'
+    if requirements >= set(['C', 'F']):
+        raise ValueError('Cannot specify both "C" and "F" order')
+    elif 'F' in requirements:
+        order = 'F'
+        requirements.remove('F')
+    elif 'C' in requirements:
+        order = 'C'
+        requirements.remove('C')
+
+    arr = array(a, dtype=dtype, order=order, copy=False, subok=subok)
+
+    for prop in requirements:
+        if not arr.flags[prop]:
+            arr = arr.copy(order)
+            break
+    return arr
+
+def isfortran(a):
+    """
+    Returns True if the array is Fortran contiguous but *not* C contiguous.
+
+    This function is obsolete and, because of changes due to relaxed stride
+    checking, its return value for the same array may differ for versions
+    of Numpy >= 1.10 and previous versions. If you only want to check if an
+    array is Fortran contiguous use ``a.flags.f_contiguous`` instead.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+
+
+    Examples
+    --------
+
+    np.array allows to specify whether the array is written in C-contiguous
+    order (last index varies the fastest), or FORTRAN-contiguous order in
+    memory (first index varies the fastest).
+
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(a)
+    False
+
+    >>> b = np.array([[1, 2, 3], [4, 5, 6]], order='FORTRAN')
+    >>> b
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(b)
+    True
+
+
+    The transpose of a C-ordered array is a FORTRAN-ordered array.
+
+    >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
+    >>> a
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> np.isfortran(a)
+    False
+    >>> b = a.T
+    >>> b
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+    >>> np.isfortran(b)
+    True
+
+    C-ordered arrays evaluate as False even if they are also FORTRAN-ordered.
+
+    >>> np.isfortran(np.array([1, 2], order='FORTRAN'))
+    False
+
+    """
+    return a.flags.fnc
+
+def argwhere(a):
+    """
+    Find the indices of array elements that are non-zero, grouped by element.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+
+    Returns
+    -------
+    index_array : ndarray
+        Indices of elements that are non-zero. Indices are grouped by element.
+
+    See Also
+    --------
+    where, nonzero
+
+    Notes
+    -----
+    ``np.argwhere(a)`` is the same as ``np.transpose(np.nonzero(a))``.
+
+    The output of ``argwhere`` is not suitable for indexing arrays.
+    For this purpose use ``where(a)`` instead.
+
+    Examples
+    --------
+    >>> x = np.arange(6).reshape(2,3)
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.argwhere(x>1)
+    array([[0, 2],
+           [1, 0],
+           [1, 1],
+           [1, 2]])
+
+    """
+    return transpose(nonzero(a))
+
+def flatnonzero(a):
+    """
+    Return indices that are non-zero in the flattened version of a.
+
+    This is equivalent to a.ravel().nonzero()[0].
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+
+    Returns
+    -------
+    res : ndarray
+        Output array, containing the indices of the elements of `a.ravel()`
+        that are non-zero.
+
+    See Also
+    --------
+    nonzero : Return the indices of the non-zero elements of the input array.
+    ravel : Return a 1-D array containing the elements of the input array.
+
+    Examples
+    --------
+    >>> x = np.arange(-2, 3)
+    >>> x
+    array([-2, -1,  0,  1,  2])
+    >>> np.flatnonzero(x)
+    array([0, 1, 3, 4])
+
+    Use the indices of the non-zero elements as an index array to extract
+    these elements:
+
+    >>> x.ravel()[np.flatnonzero(x)]
+    array([-2, -1,  1,  2])
+
+    """
+    return a.ravel().nonzero()[0]
+
+_mode_from_name_dict = {'v': 0,
+                        's': 1,
+                        'f': 2}
+
+def _mode_from_name(mode):
+    if isinstance(mode, basestring):
+        return _mode_from_name_dict[mode.lower()[0]]
+    return mode
+
+def correlate(a, v, mode='valid'):
+    """
+    Cross-correlation of two 1-dimensional sequences.
+
+    This function computes the correlation as generally defined in signal
+    processing texts::
+
+        c_{av}[k] = sum_n a[n+k] * conj(v[n])
+
+    with a and v sequences being zero-padded where necessary and conj being
+    the conjugate.
+
+    Parameters
+    ----------
+    a, v : array_like
+        Input sequences.
+    mode : {'valid', 'same', 'full'}, optional
+        Refer to the `convolve` docstring.  Note that the default
+        is 'valid', unlike `convolve`, which uses 'full'.
+    old_behavior : bool
+        `old_behavior` was removed in NumPy 1.10. If you need the old
+        behavior, use `multiarray.correlate`.
+
+    Returns
+    -------
+    out : ndarray
+        Discrete cross-correlation of `a` and `v`.
+
+    See Also
+    --------
+    convolve : Discrete, linear convolution of two one-dimensional sequences.
+    multiarray.correlate : Old, no conjugate, version of correlate.
+
+    Notes
+    -----
+    The definition of correlation above is not unique and sometimes correlation
+    may be defined differently. Another common definition is::
+
+        c'_{av}[k] = sum_n a[n] conj(v[n+k])
+
+    which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``.
+
+    Examples
+    --------
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5])
+    array([ 3.5])
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5], "same")
+    array([ 2. ,  3.5,  3. ])
+    >>> np.correlate([1, 2, 3], [0, 1, 0.5], "full")
+    array([ 0.5,  2. ,  3.5,  3. ,  0. ])
+
+    Using complex sequences:
+
+    >>> np.correlate([1+1j, 2, 3-1j], [0, 1, 0.5j], 'full')
+    array([ 0.5-0.5j,  1.0+0.j ,  1.5-1.5j,  3.0-1.j ,  0.0+0.j ])
+
+    Note that you get the time reversed, complex conjugated result
+    when the two input sequences change places, i.e.,
+    ``c_{va}[k] = c^{*}_{av}[-k]``:
+
+    >>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full')
+    array([ 0.0+0.j ,  3.0+1.j ,  1.5+1.5j,  1.0+0.j ,  0.5+0.5j])
+
+    """
+    mode = _mode_from_name(mode)
+    return multiarray.correlate2(a, v, mode)
+
+def convolve(a,v,mode='full'):
+    """
+    Returns the discrete, linear convolution of two one-dimensional sequences.
+
+    The convolution operator is often seen in signal processing, where it
+    models the effect of a linear time-invariant system on a signal [1]_.  In
+    probability theory, the sum of two independent random variables is
+    distributed according to the convolution of their individual
+    distributions.
+
+    If `v` is longer than `a`, the arrays are swapped before computation.
+
+    Parameters
+    ----------
+    a : (N,) array_like
+        First one-dimensional input array.
+    v : (M,) array_like
+        Second one-dimensional input array.
+    mode : {'full', 'valid', 'same'}, optional
+        'full':
+          By default, mode is 'full'.  This returns the convolution
+          at each point of overlap, with an output shape of (N+M-1,). At
+          the end-points of the convolution, the signals do not overlap
+          completely, and boundary effects may be seen.
+
+        'same':
+          Mode 'same' returns output of length ``max(M, N)``.  Boundary
+          effects are still visible.
+
+        'valid':
+          Mode 'valid' returns output of length
+          ``max(M, N) - min(M, N) + 1``.  The convolution product is only given
+          for points where the signals overlap completely.  Values outside
+          the signal boundary have no effect.
+
+    Returns
+    -------
+    out : ndarray
+        Discrete, linear convolution of `a` and `v`.
+
+    See Also
+    --------
+    scipy.signal.fftconvolve : Convolve two arrays using the Fast Fourier
+                               Transform.
+    scipy.linalg.toeplitz : Used to construct the convolution operator.
+    polymul : Polynomial multiplication. Same output as convolve, but also
+              accepts poly1d objects as input.
+
+    Notes
+    -----
+    The discrete convolution operation is defined as
+
+    .. math:: (a * v)[n] = \\sum_{m = -\\infty}^{\\infty} a[m] v[n - m]
+
+    It can be shown that a convolution :math:`x(t) * y(t)` in time/space
+    is equivalent to the multiplication :math:`X(f) Y(f)` in the Fourier
+    domain, after appropriate padding (padding is necessary to prevent
+    circular convolution).  Since multiplication is more efficient (faster)
+    than convolution, the function `scipy.signal.fftconvolve` exploits the
+    FFT to calculate the convolution of large data-sets.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Convolution", http://en.wikipedia.org/wiki/Convolution.
+
+    Examples
+    --------
+    Note how the convolution operator flips the second array
+    before "sliding" the two across one another:
+
+    >>> np.convolve([1, 2, 3], [0, 1, 0.5])
+    array([ 0. ,  1. ,  2.5,  4. ,  1.5])
+
+    Only return the middle values of the convolution.
+    Contains boundary effects, where zeros are taken
+    into account:
+
+    >>> np.convolve([1,2,3],[0,1,0.5], 'same')
+    array([ 1. ,  2.5,  4. ])
+
+    The two arrays are of the same length, so there
+    is only one position where they completely overlap:
+
+    >>> np.convolve([1,2,3],[0,1,0.5], 'valid')
+    array([ 2.5])
+
+    """
+    a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1)
+    if (len(v) > len(a)):
+        a, v = v, a
+    if len(a) == 0:
+        raise ValueError('a cannot be empty')
+    if len(v) == 0:
+        raise ValueError('v cannot be empty')
+    mode = _mode_from_name(mode)
+    return multiarray.correlate(a, v[::-1], mode)
+
+def outer(a, b, out=None):
+    """
+    Compute the outer product of two vectors.
+
+    Given two vectors, ``a = [a0, a1, ..., aM]`` and
+    ``b = [b0, b1, ..., bN]``,
+    the outer product [1]_ is::
+
+      [[a0*b0  a0*b1 ... a0*bN ]
+       [a1*b0    .
+       [ ...          .
+       [aM*b0            aM*bN ]]
+
+    Parameters
+    ----------
+    a : (M,) array_like
+        First input vector.  Input is flattened if
+        not already 1-dimensional.
+    b : (N,) array_like
+        Second input vector.  Input is flattened if
+        not already 1-dimensional.
+    out : (M, N) ndarray, optional
+        A location where the result is stored
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    out : (M, N) ndarray
+        ``out[i, j] = a[i] * b[j]``
+
+    See also
+    --------
+    inner, einsum
+
+    References
+    ----------
+    .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd
+             ed., Baltimore, MD, Johns Hopkins University Press, 1996,
+             pg. 8.
+
+    Examples
+    --------
+    Make a (*very* coarse) grid for computing a Mandelbrot set:
+
+    >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5))
+    >>> rl
+    array([[-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.],
+           [-2., -1.,  0.,  1.,  2.]])
+    >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
+    >>> im
+    array([[ 0.+2.j,  0.+2.j,  0.+2.j,  0.+2.j,  0.+2.j],
+           [ 0.+1.j,  0.+1.j,  0.+1.j,  0.+1.j,  0.+1.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.-1.j,  0.-1.j,  0.-1.j,  0.-1.j,  0.-1.j],
+           [ 0.-2.j,  0.-2.j,  0.-2.j,  0.-2.j,  0.-2.j]])
+    >>> grid = rl + im
+    >>> grid
+    array([[-2.+2.j, -1.+2.j,  0.+2.j,  1.+2.j,  2.+2.j],
+           [-2.+1.j, -1.+1.j,  0.+1.j,  1.+1.j,  2.+1.j],
+           [-2.+0.j, -1.+0.j,  0.+0.j,  1.+0.j,  2.+0.j],
+           [-2.-1.j, -1.-1.j,  0.-1.j,  1.-1.j,  2.-1.j],
+           [-2.-2.j, -1.-2.j,  0.-2.j,  1.-2.j,  2.-2.j]])
+
+    An example using a "vector" of letters:
+
+    >>> x = np.array(['a', 'b', 'c'], dtype=object)
+    >>> np.outer(x, [1, 2, 3])
+    array([[a, aa, aaa],
+           [b, bb, bbb],
+           [c, cc, ccc]], dtype=object)
+
+    """
+    a = asarray(a)
+    b = asarray(b)
+    return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis,:], out)
+
+
+def alterdot():
+    """
+    Change `dot`, `vdot`, and `inner` to use accelerated BLAS functions.
+
+    Typically, as a user of Numpy, you do not explicitly call this
+    function. If Numpy is built with an accelerated BLAS, this function is
+    automatically called when Numpy is imported.
+
+    When Numpy is built with an accelerated BLAS like ATLAS, these
+    functions are replaced to make use of the faster implementations.  The
+    faster implementations only affect float32, float64, complex64, and
+    complex128 arrays. Furthermore, the BLAS API only includes
+    matrix-matrix, matrix-vector, and vector-vector products. Products of
+    arrays with larger dimensionalities use the built in functions and are
+    not accelerated.
+
+    .. note:: Deprecated in Numpy 1.10
+              The cblas functions have been integrated into the multarray
+              module and alterdot now longer does anything. It will be
+              removed in Numpy 1.11.0.
+
+    See Also
+    --------
+    restoredot : `restoredot` undoes the effects of `alterdot`.
+
+    """
+    # 2014-08-13, 1.10
+    warnings.warn("alterdot no longer does anything.", DeprecationWarning)
+
+
+def restoredot():
+    """
+    Restore `dot`, `vdot`, and `innerproduct` to the default non-BLAS
+    implementations.
+
+    Typically, the user will only need to call this when troubleshooting
+    and installation problem, reproducing the conditions of a build without
+    an accelerated BLAS, or when being very careful about benchmarking
+    linear algebra operations.
+
+    .. note:: Deprecated in Numpy 1.10
+              The cblas functions have been integrated into the multarray
+              module and restoredot now longer does anything. It will be
+              removed in Numpy 1.11.0.
+
+    See Also
+    --------
+    alterdot : `restoredot` undoes the effects of `alterdot`.
+
+    """
+    # 2014-08-13, 1.10
+    warnings.warn("restoredot no longer does anything.", DeprecationWarning)
+
+
+def tensordot(a, b, axes=2):
+    """
+    Compute tensor dot product along specified axes for arrays >= 1-D.
+
+    Given two tensors (arrays of dimension greater than or equal to one),
+    `a` and `b`, and an array_like object containing two array_like
+    objects, ``(a_axes, b_axes)``, sum the products of `a`'s and `b`'s
+    elements (components) over the axes specified by ``a_axes`` and
+    ``b_axes``. The third argument can be a single non-negative
+    integer_like scalar, ``N``; if it is such, then the last ``N``
+    dimensions of `a` and the first ``N`` dimensions of `b` are summed
+    over.
+
+    Parameters
+    ----------
+    a, b : array_like, len(shape) >= 1
+        Tensors to "dot".
+
+    axes : int or (2,) array_like
+        * integer_like
+          If an int N, sum over the last N axes of `a` and the first N axes
+          of `b` in order. The sizes of the corresponding axes must match.
+        * (2,) array_like
+          Or, a list of axes to be summed over, first sequence applying to `a`,
+          second to `b`. Both elements array_like must be of the same length.
+
+    See Also
+    --------
+    dot, einsum
+
+    Notes
+    -----
+    Three common use cases are:
+        ``axes = 0`` : tensor product $a\otimes b$
+        ``axes = 1`` : tensor dot product $a\cdot b$
+        ``axes = 2`` : (default) tensor double contraction $a:b$
+
+    When `axes` is integer_like, the sequence for evaluation will be: first
+    the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and
+    Nth axis in `b` last.
+
+    When there is more than one axis to sum over - and they are not the last
+    (first) axes of `a` (`b`) - the argument `axes` should consist of
+    two sequences of the same length, with the first axis to sum over given
+    first in both sequences, the second axis second, and so forth.
+
+    Examples
+    --------
+    A "traditional" example:
+
+    >>> a = np.arange(60.).reshape(3,4,5)
+    >>> b = np.arange(24.).reshape(4,3,2)
+    >>> c = np.tensordot(a,b, axes=([1,0],[0,1]))
+    >>> c.shape
+    (5, 2)
+    >>> c
+    array([[ 4400.,  4730.],
+           [ 4532.,  4874.],
+           [ 4664.,  5018.],
+           [ 4796.,  5162.],
+           [ 4928.,  5306.]])
+    >>> # A slower but equivalent way of computing the same...
+    >>> d = np.zeros((5,2))
+    >>> for i in range(5):
+    ...   for j in range(2):
+    ...     for k in range(3):
+    ...       for n in range(4):
+    ...         d[i,j] += a[k,n,i] * b[n,k,j]
+    >>> c == d
+    array([[ True,  True],
+           [ True,  True],
+           [ True,  True],
+           [ True,  True],
+           [ True,  True]], dtype=bool)
+
+    An extended example taking advantage of the overloading of + and \\*:
+
+    >>> a = np.array(range(1, 9))
+    >>> a.shape = (2, 2, 2)
+    >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object)
+    >>> A.shape = (2, 2)
+    >>> a; A
+    array([[[1, 2],
+            [3, 4]],
+           [[5, 6],
+            [7, 8]]])
+    array([[a, b],
+           [c, d]], dtype=object)
+
+    >>> np.tensordot(a, A) # third argument default is 2 for double-contraction
+    array([abbcccdddd, aaaaabbbbbbcccccccdddddddd], dtype=object)
+
+    >>> np.tensordot(a, A, 1)
+    array([[[acc, bdd],
+            [aaacccc, bbbdddd]],
+           [[aaaaacccccc, bbbbbdddddd],
+            [aaaaaaacccccccc, bbbbbbbdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, 0) # tensor product (result too long to incl.)
+    array([[[[[a, b],
+              [c, d]],
+              ...
+
+    >>> np.tensordot(a, A, (0, 1))
+    array([[[abbbbb, cddddd],
+            [aabbbbbb, ccdddddd]],
+           [[aaabbbbbbb, cccddddddd],
+            [aaaabbbbbbbb, ccccdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, (2, 1))
+    array([[[abb, cdd],
+            [aaabbbb, cccdddd]],
+           [[aaaaabbbbbb, cccccdddddd],
+            [aaaaaaabbbbbbbb, cccccccdddddddd]]], dtype=object)
+
+    >>> np.tensordot(a, A, ((0, 1), (0, 1)))
+    array([abbbcccccddddddd, aabbbbccccccdddddddd], dtype=object)
+
+    >>> np.tensordot(a, A, ((2, 1), (1, 0)))
+    array([acccbbdddd, aaaaacccccccbbbbbbdddddddd], dtype=object)
+
+    """
+    try:
+        iter(axes)
+    except:
+        axes_a = list(range(-axes, 0))
+        axes_b = list(range(0, axes))
+    else:
+        axes_a, axes_b = axes
+    try:
+        na = len(axes_a)
+        axes_a = list(axes_a)
+    except TypeError:
+        axes_a = [axes_a]
+        na = 1
+    try:
+        nb = len(axes_b)
+        axes_b = list(axes_b)
+    except TypeError:
+        axes_b = [axes_b]
+        nb = 1
+
+    a, b = asarray(a), asarray(b)
+    as_ = a.shape
+    nda = len(a.shape)
+    bs = b.shape
+    ndb = len(b.shape)
+    equal = True
+    if na != nb:
+        equal = False
+    else:
+        for k in range(na):
+            if as_[axes_a[k]] != bs[axes_b[k]]:
+                equal = False
+                break
+            if axes_a[k] < 0:
+                axes_a[k] += nda
+            if axes_b[k] < 0:
+                axes_b[k] += ndb
+    if not equal:
+        raise ValueError("shape-mismatch for sum")
+
+    # Move the axes to sum over to the end of "a"
+    # and to the front of "b"
+    notin = [k for k in range(nda) if k not in axes_a]
+    newaxes_a = notin + axes_a
+    N2 = 1
+    for axis in axes_a:
+        N2 *= as_[axis]
+    newshape_a = (-1, N2)
+    olda = [as_[axis] for axis in notin]
+
+    notin = [k for k in range(ndb) if k not in axes_b]
+    newaxes_b = axes_b + notin
+    N2 = 1
+    for axis in axes_b:
+        N2 *= bs[axis]
+    newshape_b = (N2, -1)
+    oldb = [bs[axis] for axis in notin]
+
+    at = a.transpose(newaxes_a).reshape(newshape_a)
+    bt = b.transpose(newaxes_b).reshape(newshape_b)
+    res = dot(at, bt)
+    return res.reshape(olda + oldb)
+
+def roll(a, shift, axis=None):
+    """
+    Roll array elements along a given axis.
+
+    Elements that roll beyond the last position are re-introduced at
+    the first.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    shift : int
+        The number of places by which elements are shifted.
+    axis : int, optional
+        The axis along which elements are shifted.  By default, the array
+        is flattened before shifting, after which the original
+        shape is restored.
+
+    Returns
+    -------
+    res : ndarray
+        Output array, with the same shape as `a`.
+
+    See Also
+    --------
+    rollaxis : Roll the specified axis backwards, until it lies in a
+               given position.
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> np.roll(x, 2)
+    array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
+
+    >>> x2 = np.reshape(x, (2,5))
+    >>> x2
+    array([[0, 1, 2, 3, 4],
+           [5, 6, 7, 8, 9]])
+    >>> np.roll(x2, 1)
+    array([[9, 0, 1, 2, 3],
+           [4, 5, 6, 7, 8]])
+    >>> np.roll(x2, 1, axis=0)
+    array([[5, 6, 7, 8, 9],
+           [0, 1, 2, 3, 4]])
+    >>> np.roll(x2, 1, axis=1)
+    array([[4, 0, 1, 2, 3],
+           [9, 5, 6, 7, 8]])
+
+    """
+    a = asanyarray(a)
+    if axis is None:
+        n = a.size
+        reshape = True
+    else:
+        try:
+            n = a.shape[axis]
+        except IndexError:
+            raise ValueError('axis must be >= 0 and < %d' % a.ndim)
+        reshape = False
+    if n == 0:
+        return a
+    shift %= n
+    indexes = concatenate((arange(n - shift, n), arange(n - shift)))
+    res = a.take(indexes, axis)
+    if reshape:
+        res = res.reshape(a.shape)
+    return res
+
+
+def rollaxis(a, axis, start=0):
+    """
+    Roll the specified axis backwards, until it lies in a given position.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    axis : int
+        The axis to roll backwards.  The positions of the other axes do not
+        change relative to one another.
+    start : int, optional
+        The axis is rolled until it lies before this position.  The default,
+        0, results in a "complete" roll.
+
+    Returns
+    -------
+    res : ndarray
+        For Numpy >= 1.10 a view of `a` is always returned. For earlier
+        Numpy versions a view of `a` is returned only if the order of the
+        axes is changed, otherwise the input array is returned.
+
+    See Also
+    --------
+    moveaxis : Move array axes to new positions.
+    roll : Roll the elements of an array by a number of positions along a
+        given axis.
+
+    Examples
+    --------
+    >>> a = np.ones((3,4,5,6))
+    >>> np.rollaxis(a, 3, 1).shape
+    (3, 6, 4, 5)
+    >>> np.rollaxis(a, 2).shape
+    (5, 3, 4, 6)
+    >>> np.rollaxis(a, 1, 4).shape
+    (3, 5, 6, 4)
+
+    """
+    n = a.ndim
+    if axis < 0:
+        axis += n
+    if start < 0:
+        start += n
+    msg = 'rollaxis: %s (%d) must be >=0 and < %d'
+    if not (0 <= axis < n):
+        raise ValueError(msg % ('axis', axis, n))
+    if not (0 <= start < n + 1):
+        raise ValueError(msg % ('start', start, n + 1))
+    if (axis < start):
+        # it's been removed
+        start -= 1
+    if axis == start:
+        return a[...]
+    axes = list(range(0, n))
+    axes.remove(axis)
+    axes.insert(start, axis)
+    return a.transpose(axes)
+
+
+def _validate_axis(axis, ndim, argname):
+    try:
+        axis = [operator.index(axis)]
+    except TypeError:
+        axis = list(axis)
+    axis = [a + ndim if a < 0 else a for a in axis]
+    if not builtins.all(0 <= a < ndim for a in axis):
+        raise ValueError('invalid axis for this array in `%s` argument' %
+                         argname)
+    if len(set(axis)) != len(axis):
+        raise ValueError('repeated axis in `%s` argument' % argname)
+    return axis
+
+
+def moveaxis(a, source, destination):
+    """
+    Move axes of an array to new positions.
+
+    Other axes remain in their original order.
+
+    .. versionadded::1.11.0
+
+    Parameters
+    ----------
+    a : np.ndarray
+        The array whose axes should be reordered.
+    source : int or sequence of int
+        Original positions of the axes to move. These must be unique.
+    destination : int or sequence of int
+        Destination positions for each of the original axes. These must also be
+        unique.
+
+    Returns
+    -------
+    result : np.ndarray
+        Array with moved axes. This array is a view of the input array.
+
+    See Also
+    --------
+    transpose: Permute the dimensions of an array.
+    swapaxes: Interchange two axes of an array.
+
+    Examples
+    --------
+
+    >>> x = np.zeros((3, 4, 5))
+    >>> np.moveaxis(x, 0, -1).shape
+    (4, 5, 3)
+    >>> np.moveaxis(x, -1, 0).shape
+    (5, 3, 4)
+
+    These all achieve the same result:
+
+    >>> np.transpose(x).shape
+    (5, 4, 3)
+    >>> np.swapaxis(x, 0, -1).shape
+    (5, 4, 3)
+    >>> np.moveaxis(x, [0, 1], [-1, -2]).shape
+    (5, 4, 3)
+    >>> np.moveaxis(x, [0, 1, 2], [-1, -2, -3]).shape
+    (5, 4, 3)
+
+    """
+    try:
+        # allow duck-array types if they define transpose
+        transpose = a.transpose
+    except AttributeError:
+        a = asarray(a)
+        transpose = a.transpose
+
+    source = _validate_axis(source, a.ndim, 'source')
+    destination = _validate_axis(destination, a.ndim, 'destination')
+    if len(source) != len(destination):
+        raise ValueError('`source` and `destination` arguments must have '
+                         'the same number of elements')
+
+    order = [n for n in range(a.ndim) if n not in source]
+
+    for dest, src in sorted(zip(destination, source)):
+        order.insert(dest, src)
+
+    result = transpose(order)
+    return result
+
+
+# fix hack in scipy which imports this function
+def _move_axis_to_0(a, axis):
+    return rollaxis(a, axis, 0)
+
+def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
+    """
+    Return the cross product of two (arrays of) vectors.
+
+    The cross product of `a` and `b` in :math:`R^3` is a vector perpendicular
+    to both `a` and `b`.  If `a` and `b` are arrays of vectors, the vectors
+    are defined by the last axis of `a` and `b` by default, and these axes
+    can have dimensions 2 or 3.  Where the dimension of either `a` or `b` is
+    2, the third component of the input vector is assumed to be zero and the
+    cross product calculated accordingly.  In cases where both input vectors
+    have dimension 2, the z-component of the cross product is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Components of the first vector(s).
+    b : array_like
+        Components of the second vector(s).
+    axisa : int, optional
+        Axis of `a` that defines the vector(s).  By default, the last axis.
+    axisb : int, optional
+        Axis of `b` that defines the vector(s).  By default, the last axis.
+    axisc : int, optional
+        Axis of `c` containing the cross product vector(s).  Ignored if
+        both input vectors have dimension 2, as the return is scalar.
+        By default, the last axis.
+    axis : int, optional
+        If defined, the axis of `a`, `b` and `c` that defines the vector(s)
+        and cross product(s).  Overrides `axisa`, `axisb` and `axisc`.
+
+    Returns
+    -------
+    c : ndarray
+        Vector cross product(s).
+
+    Raises
+    ------
+    ValueError
+        When the dimension of the vector(s) in `a` and/or `b` does not
+        equal 2 or 3.
+
+    See Also
+    --------
+    inner : Inner product
+    outer : Outer product.
+    ix_ : Construct index arrays.
+
+    Notes
+    -----
+    .. versionadded:: 1.9.0
+
+    Supports full broadcasting of the inputs.
+
+    Examples
+    --------
+    Vector cross-product.
+
+    >>> x = [1, 2, 3]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([-3,  6, -3])
+
+    One vector with dimension 2.
+
+    >>> x = [1, 2]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([12, -6, -3])
+
+    Equivalently:
+
+    >>> x = [1, 2, 0]
+    >>> y = [4, 5, 6]
+    >>> np.cross(x, y)
+    array([12, -6, -3])
+
+    Both vectors with dimension 2.
+
+    >>> x = [1,2]
+    >>> y = [4,5]
+    >>> np.cross(x, y)
+    -3
+
+    Multiple vector cross-products. Note that the direction of the cross
+    product vector is defined by the `right-hand rule`.
+
+    >>> x = np.array([[1,2,3], [4,5,6]])
+    >>> y = np.array([[4,5,6], [1,2,3]])
+    >>> np.cross(x, y)
+    array([[-3,  6, -3],
+           [ 3, -6,  3]])
+
+    The orientation of `c` can be changed using the `axisc` keyword.
+
+    >>> np.cross(x, y, axisc=0)
+    array([[-3,  3],
+           [ 6, -6],
+           [-3,  3]])
+
+    Change the vector definition of `x` and `y` using `axisa` and `axisb`.
+
+    >>> x = np.array([[1,2,3], [4,5,6], [7, 8, 9]])
+    >>> y = np.array([[7, 8, 9], [4,5,6], [1,2,3]])
+    >>> np.cross(x, y)
+    array([[ -6,  12,  -6],
+           [  0,   0,   0],
+           [  6, -12,   6]])
+    >>> np.cross(x, y, axisa=0, axisb=0)
+    array([[-24,  48, -24],
+           [-30,  60, -30],
+           [-36,  72, -36]])
+
+    """
+    if axis is not None:
+        axisa, axisb, axisc = (axis,) * 3
+    a = asarray(a)
+    b = asarray(b)
+    # Check axisa and axisb are within bounds
+    axis_msg = "'axis{0}' out of bounds"
+    if axisa < -a.ndim or axisa >= a.ndim:
+        raise ValueError(axis_msg.format('a'))
+    if axisb < -b.ndim or axisb >= b.ndim:
+        raise ValueError(axis_msg.format('b'))
+    # Move working axis to the end of the shape
+    a = rollaxis(a, axisa, a.ndim)
+    b = rollaxis(b, axisb, b.ndim)
+    msg = ("incompatible dimensions for cross product\n"
+           "(dimension must be 2 or 3)")
+    if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3):
+        raise ValueError(msg)
+
+    # Create the output array
+    shape = broadcast(a[..., 0], b[..., 0]).shape
+    if a.shape[-1] == 3 or b.shape[-1] == 3:
+        shape += (3,)
+        # Check axisc is within bounds
+        if axisc < -len(shape) or axisc >= len(shape):
+            raise ValueError(axis_msg.format('c'))
+    dtype = promote_types(a.dtype, b.dtype)
+    cp = empty(shape, dtype)
+
+    # create local aliases for readability
+    a0 = a[..., 0]
+    a1 = a[..., 1]
+    if a.shape[-1] == 3:
+        a2 = a[..., 2]
+    b0 = b[..., 0]
+    b1 = b[..., 1]
+    if b.shape[-1] == 3:
+        b2 = b[..., 2]
+    if cp.ndim != 0 and cp.shape[-1] == 3:
+        cp0 = cp[..., 0]
+        cp1 = cp[..., 1]
+        cp2 = cp[..., 2]
+
+    if a.shape[-1] == 2:
+        if b.shape[-1] == 2:
+            # a0 * b1 - a1 * b0
+            multiply(a0, b1, out=cp)
+            cp -= a1 * b0
+            return cp
+        else:
+            assert b.shape[-1] == 3
+            # cp0 = a1 * b2 - 0  (a2 = 0)
+            # cp1 = 0 - a0 * b2  (a2 = 0)
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a1, b2, out=cp0)
+            multiply(a0, b2, out=cp1)
+            negative(cp1, out=cp1)
+            multiply(a0, b1, out=cp2)
+            cp2 -= a1 * b0
+    else:
+        assert a.shape[-1] == 3
+        if b.shape[-1] == 3:
+            # cp0 = a1 * b2 - a2 * b1
+            # cp1 = a2 * b0 - a0 * b2
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a1, b2, out=cp0)
+            tmp = array(a2 * b1)
+            cp0 -= tmp
+            multiply(a2, b0, out=cp1)
+            multiply(a0, b2, out=tmp)
+            cp1 -= tmp
+            multiply(a0, b1, out=cp2)
+            multiply(a1, b0, out=tmp)
+            cp2 -= tmp
+        else:
+            assert b.shape[-1] == 2
+            # cp0 = 0 - a2 * b1  (b2 = 0)
+            # cp1 = a2 * b0 - 0  (b2 = 0)
+            # cp2 = a0 * b1 - a1 * b0
+            multiply(a2, b1, out=cp0)
+            negative(cp0, out=cp0)
+            multiply(a2, b0, out=cp1)
+            multiply(a0, b1, out=cp2)
+            cp2 -= a1 * b0
+
+    # This works because we are moving the last axis
+    return rollaxis(cp, -1, axisc)
+
+#Use numarray's printing function
+from .arrayprint import array2string, get_printoptions, set_printoptions
+
+_typelessdata = [int_, float_, complex_]
+if issubclass(intc, int):
+    _typelessdata.append(intc)
+
+if issubclass(longlong, int):
+    _typelessdata.append(longlong)
+
+def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
+    """
+    Return the string representation of an array.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array.
+    max_line_width : int, optional
+        The maximum number of columns the string should span. Newline
+        characters split the string appropriately after array elements.
+    precision : int, optional
+        Floating point precision. Default is the current printing precision
+        (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent very small numbers as zero, default is False. Very small
+        is defined by `precision`, if the precision is 8 then
+        numbers smaller than 5e-9 are represented as zero.
+
+    Returns
+    -------
+    string : str
+      The string representation of an array.
+
+    See Also
+    --------
+    array_str, array2string, set_printoptions
+
+    Examples
+    --------
+    >>> np.array_repr(np.array([1,2]))
+    'array([1, 2])'
+    >>> np.array_repr(np.ma.array([0.]))
+    'MaskedArray([ 0.])'
+    >>> np.array_repr(np.array([], np.int32))
+    'array([], dtype=int32)'
+
+    >>> x = np.array([1e-6, 4e-7, 2, 3])
+    >>> np.array_repr(x, precision=6, suppress_small=True)
+    'array([ 0.000001,  0.      ,  2.      ,  3.      ])'
+
+    """
+    if arr.size > 0 or arr.shape == (0,):
+        lst = array2string(arr, max_line_width, precision, suppress_small,
+                           ', ', "array(")
+    else:  # show zero-length shape unless it is (0,)
+        lst = "[], shape=%s" % (repr(arr.shape),)
+
+    if arr.__class__ is not ndarray:
+        cName = arr.__class__.__name__
+    else:
+        cName = "array"
+
+    skipdtype = (arr.dtype.type in _typelessdata) and arr.size > 0
+
+    if skipdtype:
+        return "%s(%s)" % (cName, lst)
+    else:
+        typename = arr.dtype.name
+        # Quote typename in the output if it is "complex".
+        if typename and not (typename[0].isalpha() and typename.isalnum()):
+            typename = "'%s'" % typename
+
+        lf = ''
+        if issubclass(arr.dtype.type, flexible):
+            if arr.dtype.names:
+                typename = "%s" % str(arr.dtype)
+            else:
+                typename = "'%s'" % str(arr.dtype)
+            lf = '\n'+' '*len("array(")
+        return cName + "(%s, %sdtype=%s)" % (lst, lf, typename)
+
+def array_str(a, max_line_width=None, precision=None, suppress_small=None):
+    """
+    Return a string representation of the data in an array.
+
+    The data in the array is returned as a single string.  This function is
+    similar to `array_repr`, the difference being that `array_repr` also
+    returns information on the kind of array and its data type.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array.
+    max_line_width : int, optional
+        Inserts newlines if text is longer than `max_line_width`.  The
+        default is, indirectly, 75.
+    precision : int, optional
+        Floating point precision.  Default is the current printing precision
+        (usually 8), which can be altered using `set_printoptions`.
+    suppress_small : bool, optional
+        Represent numbers "very close" to zero as zero; default is False.
+        Very close is defined by precision: if the precision is 8, e.g.,
+        numbers smaller (in absolute value) than 5e-9 are represented as
+        zero.
+
+    See Also
+    --------
+    array2string, array_repr, set_printoptions
+
+    Examples
+    --------
+    >>> np.array_str(np.arange(3))
+    '[0 1 2]'
+
+    """
+    return array2string(a, max_line_width, precision, suppress_small, ' ', "", str)
+
+def set_string_function(f, repr=True):
+    """
+    Set a Python function to be used when pretty printing arrays.
+
+    Parameters
+    ----------
+    f : function or None
+        Function to be used to pretty print arrays. The function should expect
+        a single array argument and return a string of the representation of
+        the array. If None, the function is reset to the default NumPy function
+        to print arrays.
+    repr : bool, optional
+        If True (default), the function for pretty printing (``__repr__``)
+        is set, if False the function that returns the default string
+        representation (``__str__``) is set.
+
+    See Also
+    --------
+    set_printoptions, get_printoptions
+
+    Examples
+    --------
+    >>> def pprint(arr):
+    ...     return 'HA! - What are you going to do now?'
+    ...
+    >>> np.set_string_function(pprint)
+    >>> a = np.arange(10)
+    >>> a
+    HA! - What are you going to do now?
+    >>> print(a)
+    [0 1 2 3 4 5 6 7 8 9]
+
+    We can reset the function to the default:
+
+    >>> np.set_string_function(None)
+    >>> a
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    `repr` affects either pretty printing or normal string representation.
+    Note that ``__repr__`` is still affected by setting ``__str__``
+    because the width of each array element in the returned string becomes
+    equal to the length of the result of ``__str__()``.
+
+    >>> x = np.arange(4)
+    >>> np.set_string_function(lambda x:'random', repr=False)
+    >>> x.__str__()
+    'random'
+    >>> x.__repr__()
+    'array([     0,      1,      2,      3])'
+
+    """
+    if f is None:
+        if repr:
+            return multiarray.set_string_function(array_repr, 1)
+        else:
+            return multiarray.set_string_function(array_str, 0)
+    else:
+        return multiarray.set_string_function(f, repr)
+
+set_string_function(array_str, 0)
+set_string_function(array_repr, 1)
+
+little_endian = (sys.byteorder == 'little')
+
+
+def indices(dimensions, dtype=int):
+    """
+    Return an array representing the indices of a grid.
+
+    Compute an array where the subarrays contain index values 0,1,...
+    varying only along the corresponding axis.
+
+    Parameters
+    ----------
+    dimensions : sequence of ints
+        The shape of the grid.
+    dtype : dtype, optional
+        Data type of the result.
+
+    Returns
+    -------
+    grid : ndarray
+        The array of grid indices,
+        ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
+
+    See Also
+    --------
+    mgrid, meshgrid
+
+    Notes
+    -----
+    The output shape is obtained by prepending the number of dimensions
+    in front of the tuple of dimensions, i.e. if `dimensions` is a tuple
+    ``(r0, ..., rN-1)`` of length ``N``, the output shape is
+    ``(N,r0,...,rN-1)``.
+
+    The subarrays ``grid[k]`` contains the N-D array of indices along the
+    ``k-th`` axis. Explicitly::
+
+        grid[k,i0,i1,...,iN-1] = ik
+
+    Examples
+    --------
+    >>> grid = np.indices((2, 3))
+    >>> grid.shape
+    (2, 2, 3)
+    >>> grid[0]        # row indices
+    array([[0, 0, 0],
+           [1, 1, 1]])
+    >>> grid[1]        # column indices
+    array([[0, 1, 2],
+           [0, 1, 2]])
+
+    The indices can be used as an index into an array.
+
+    >>> x = np.arange(20).reshape(5, 4)
+    >>> row, col = np.indices((2, 3))
+    >>> x[row, col]
+    array([[0, 1, 2],
+           [4, 5, 6]])
+
+    Note that it would be more straightforward in the above example to
+    extract the required elements directly with ``x[:2, :3]``.
+
+    """
+    dimensions = tuple(dimensions)
+    N = len(dimensions)
+    if N == 0:
+        return array([], dtype=dtype)
+    res = empty((N,)+dimensions, dtype=dtype)
+    for i, dim in enumerate(dimensions):
+        tmp = arange(dim, dtype=dtype)
+        tmp.shape = (1,)*i + (dim,)+(1,)*(N-i-1)
+        newdim = dimensions[:i] + (1,) + dimensions[i+1:]
+        val = zeros(newdim, dtype)
+        add(tmp, val, res[i])
+    return res
+
+def fromfunction(function, shape, **kwargs):
+    """
+    Construct an array by executing a function over each coordinate.
+
+    The resulting array therefore has a value ``fn(x, y, z)`` at
+    coordinate ``(x, y, z)``.
+
+    Parameters
+    ----------
+    function : callable
+        The function is called with N parameters, where N is the rank of
+        `shape`.  Each parameter represents the coordinates of the array
+        varying along a specific axis.  For example, if `shape`
+        were ``(2, 2)``, then the parameters in turn be (0, 0), (0, 1),
+        (1, 0), (1, 1).
+    shape : (N,) tuple of ints
+        Shape of the output array, which also determines the shape of
+        the coordinate arrays passed to `function`.
+    dtype : data-type, optional
+        Data-type of the coordinate arrays passed to `function`.
+        By default, `dtype` is float.
+
+    Returns
+    -------
+    fromfunction : any
+        The result of the call to `function` is passed back directly.
+        Therefore the shape of `fromfunction` is completely determined by
+        `function`.  If `function` returns a scalar value, the shape of
+        `fromfunction` would match the `shape` parameter.
+
+    See Also
+    --------
+    indices, meshgrid
+
+    Notes
+    -----
+    Keywords other than `dtype` are passed to `function`.
+
+    Examples
+    --------
+    >>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
+    array([[ True, False, False],
+           [False,  True, False],
+           [False, False,  True]], dtype=bool)
+
+    >>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
+    array([[0, 1, 2],
+           [1, 2, 3],
+           [2, 3, 4]])
+
+    """
+    dtype = kwargs.pop('dtype', float)
+    args = indices(shape, dtype=dtype)
+    return function(*args,**kwargs)
+
+def isscalar(num):
+    """
+    Returns True if the type of `num` is a scalar type.
+
+    Parameters
+    ----------
+    num : any
+        Input argument, can be of any type and shape.
+
+    Returns
+    -------
+    val : bool
+        True if `num` is a scalar type, False if it is not.
+
+    Examples
+    --------
+    >>> np.isscalar(3.1)
+    True
+    >>> np.isscalar([3.1])
+    False
+    >>> np.isscalar(False)
+    True
+
+    """
+    if isinstance(num, generic):
+        return True
+    else:
+        return type(num) in ScalarType
+
+_lkup = {
+    '0':'0000',
+    '1':'0001',
+    '2':'0010',
+    '3':'0011',
+    '4':'0100',
+    '5':'0101',
+    '6':'0110',
+    '7':'0111',
+    '8':'1000',
+    '9':'1001',
+    'a':'1010',
+    'b':'1011',
+    'c':'1100',
+    'd':'1101',
+    'e':'1110',
+    'f':'1111',
+    'A':'1010',
+    'B':'1011',
+    'C':'1100',
+    'D':'1101',
+    'E':'1110',
+    'F':'1111',
+    'L':''}
+
+def binary_repr(num, width=None):
+    """
+    Return the binary representation of the input number as a string.
+
+    For negative numbers, if width is not given, a minus sign is added to the
+    front. If width is given, the two's complement of the number is
+    returned, with respect to that width.
+
+    In a two's-complement system negative numbers are represented by the two's
+    complement of the absolute value. This is the most common method of
+    representing signed integers on computers [1]_. A N-bit two's-complement
+    system can represent every integer in the range
+    :math:`-2^{N-1}` to :math:`+2^{N-1}-1`.
+
+    Parameters
+    ----------
+    num : int
+        Only an integer decimal number can be used.
+    width : int, optional
+        The length of the returned string if `num` is positive, the length of
+        the two's complement if `num` is negative.
+
+    Returns
+    -------
+    bin : str
+        Binary representation of `num` or two's complement of `num`.
+
+    See Also
+    --------
+    base_repr: Return a string representation of a number in the given base
+               system.
+
+    Notes
+    -----
+    `binary_repr` is equivalent to using `base_repr` with base 2, but about 25x
+    faster.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Two's complement",
+        http://en.wikipedia.org/wiki/Two's_complement
+
+    Examples
+    --------
+    >>> np.binary_repr(3)
+    '11'
+    >>> np.binary_repr(-3)
+    '-11'
+    >>> np.binary_repr(3, width=4)
+    '0011'
+
+    The two's complement is returned when the input number is negative and
+    width is specified:
+
+    >>> np.binary_repr(-3, width=4)
+    '1101'
+
+    """
+    # ' <-- unbreak Emacs fontification
+    sign = ''
+    if num < 0:
+        if width is None:
+            sign = '-'
+            num = -num
+        else:
+            # replace num with its 2-complement
+            num = 2**width + num
+    elif num == 0:
+        return '0'*(width or 1)
+    ostr = hex(num)
+    bin = ''.join([_lkup[ch] for ch in ostr[2:]])
+    bin = bin.lstrip('0')
+    if width is not None:
+        bin = bin.zfill(width)
+    return sign + bin
+
+def base_repr(number, base=2, padding=0):
+    """
+    Return a string representation of a number in the given base system.
+
+    Parameters
+    ----------
+    number : int
+        The value to convert. Only positive values are handled.
+    base : int, optional
+        Convert `number` to the `base` number system. The valid range is 2-36,
+        the default value is 2.
+    padding : int, optional
+        Number of zeros padded on the left. Default is 0 (no padding).
+
+    Returns
+    -------
+    out : str
+        String representation of `number` in `base` system.
+
+    See Also
+    --------
+    binary_repr : Faster version of `base_repr` for base 2.
+
+    Examples
+    --------
+    >>> np.base_repr(5)
+    '101'
+    >>> np.base_repr(6, 5)
+    '11'
+    >>> np.base_repr(7, base=5, padding=3)
+    '00012'
+
+    >>> np.base_repr(10, base=16)
+    'A'
+    >>> np.base_repr(32, base=16)
+    '20'
+
+    """
+    digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+    if base > len(digits):
+        raise ValueError("Bases greater than 36 not handled in base_repr.")
+
+    num = abs(number)
+    res = []
+    while num:
+        res.append(digits[num % base])
+        num //= base
+    if padding:
+        res.append('0' * padding)
+    if number < 0:
+        res.append('-')
+    return ''.join(reversed(res or '0'))
+
+
+def load(file):
+    """
+    Wrapper around cPickle.load which accepts either a file-like object or
+    a filename.
+
+    Note that the NumPy binary format is not based on pickle/cPickle anymore.
+    For details on the preferred way of loading and saving files, see `load`
+    and `save`.
+
+    See Also
+    --------
+    load, save
+
+    """
+    if isinstance(file, type("")):
+        file = open(file, "rb")
+    return pickle.load(file)
+
+# These are all essentially abbreviations
+# These might wind up in a special abbreviations module
+
+def _maketup(descr, val):
+    dt = dtype(descr)
+    # Place val in all scalar tuples:
+    fields = dt.fields
+    if fields is None:
+        return val
+    else:
+        res = [_maketup(fields[name][0], val) for name in dt.names]
+        return tuple(res)
+
+def identity(n, dtype=None):
+    """
+    Return the identity array.
+
+    The identity array is a square array with ones on
+    the main diagonal.
+
+    Parameters
+    ----------
+    n : int
+        Number of rows (and columns) in `n` x `n` output.
+    dtype : data-type, optional
+        Data-type of the output.  Defaults to ``float``.
+
+    Returns
+    -------
+    out : ndarray
+        `n` x `n` array with its main diagonal set to one,
+        and all other elements 0.
+
+    Examples
+    --------
+    >>> np.identity(3)
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    """
+    from numpy import eye
+    return eye(n, dtype=dtype)
+
+def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+    """
+    Returns True if two arrays are element-wise equal within a tolerance.
+
+    The tolerance values are positive, typically very small numbers.  The
+    relative difference (`rtol` * abs(`b`)) and the absolute difference
+    `atol` are added together to compare against the absolute difference
+    between `a` and `b`.
+
+    If either array contains one or more NaNs, False is returned.
+    Infs are treated as equal if they are in the same place and of the same
+    sign in both arrays.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    rtol : float
+        The relative tolerance parameter (see Notes).
+    atol : float
+        The absolute tolerance parameter (see Notes).
+    equal_nan : bool
+        Whether to compare NaN's as equal.  If True, NaN's in `a` will be
+        considered equal to NaN's in `b` in the output array.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    allclose : bool
+        Returns True if the two arrays are equal within the given
+        tolerance; False otherwise.
+
+    See Also
+    --------
+    isclose, all, any
+
+    Notes
+    -----
+    If the following equation is element-wise True, then allclose returns
+    True.
+
+     absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    The above equation is not symmetric in `a` and `b`, so that
+    `allclose(a, b)` might be different from `allclose(b, a)` in
+    some rare cases.
+
+    Examples
+    --------
+    >>> np.allclose([1e10,1e-7], [1.00001e10,1e-8])
+    False
+    >>> np.allclose([1e10,1e-8], [1.00001e10,1e-9])
+    True
+    >>> np.allclose([1e10,1e-8], [1.0001e10,1e-9])
+    False
+    >>> np.allclose([1.0, np.nan], [1.0, np.nan])
+    False
+    >>> np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+    True
+
+    """
+    res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
+    return bool(res)
+
+def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+    """
+    Returns a boolean array where two arrays are element-wise equal within a
+    tolerance.
+
+    The tolerance values are positive, typically very small numbers.  The
+    relative difference (`rtol` * abs(`b`)) and the absolute difference
+    `atol` are added together to compare against the absolute difference
+    between `a` and `b`.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    rtol : float
+        The relative tolerance parameter (see Notes).
+    atol : float
+        The absolute tolerance parameter (see Notes).
+    equal_nan : bool
+        Whether to compare NaN's as equal.  If True, NaN's in `a` will be
+        considered equal to NaN's in `b` in the output array.
+
+    Returns
+    -------
+    y : array_like
+        Returns a boolean array of where `a` and `b` are equal within the
+        given tolerance. If both `a` and `b` are scalars, returns a single
+        boolean value.
+
+    See Also
+    --------
+    allclose
+
+    Notes
+    -----
+    .. versionadded:: 1.7.0
+
+    For finite values, isclose uses the following equation to test whether
+    two floating point values are equivalent.
+
+     absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    The above equation is not symmetric in `a` and `b`, so that
+    `isclose(a, b)` might be different from `isclose(b, a)` in
+    some rare cases.
+
+    Examples
+    --------
+    >>> np.isclose([1e10,1e-7], [1.00001e10,1e-8])
+    array([True, False])
+    >>> np.isclose([1e10,1e-8], [1.00001e10,1e-9])
+    array([True, True])
+    >>> np.isclose([1e10,1e-8], [1.0001e10,1e-9])
+    array([False, True])
+    >>> np.isclose([1.0, np.nan], [1.0, np.nan])
+    array([True, False])
+    >>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+    array([True, True])
+    """
+    def within_tol(x, y, atol, rtol):
+        with errstate(invalid='ignore'):
+            result = less_equal(abs(x-y), atol + rtol * abs(y))
+        if isscalar(a) and isscalar(b):
+            result = bool(result)
+        return result
+
+    x = array(a, copy=False, subok=True, ndmin=1)
+    y = array(b, copy=False, subok=True, ndmin=1)
+
+    # Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
+    # This will cause casting of x later. Also, make sure to allow subclasses
+    # (e.g., for numpy.ma).
+    dt = multiarray.result_type(y, 1.)
+    y = array(y, dtype=dt, copy=False, subok=True)
+
+    xfin = isfinite(x)
+    yfin = isfinite(y)
+    if all(xfin) and all(yfin):
+        return within_tol(x, y, atol, rtol)
+    else:
+        finite = xfin & yfin
+        cond = zeros_like(finite, subok=True)
+        # Because we're using boolean indexing, x & y must be the same shape.
+        # Ideally, we'd just do x, y = broadcast_arrays(x, y). It's in
+        # lib.stride_tricks, though, so we can't import it here.
+        x = x * ones_like(cond)
+        y = y * ones_like(cond)
+        # Avoid subtraction with infinite/nan values...
+        cond[finite] = within_tol(x[finite], y[finite], atol, rtol)
+        # Check for equality of infinite values...
+        cond[~finite] = (x[~finite] == y[~finite])
+        if equal_nan:
+            # Make NaN == NaN
+            both_nan = isnan(x) & isnan(y)
+            cond[both_nan] = both_nan[both_nan]
+
+        if isscalar(a) and isscalar(b):
+            return bool(cond)
+        else:
+            return cond
+
+def array_equal(a1, a2):
+    """
+    True if two arrays have the same shape and elements, False otherwise.
+
+    Parameters
+    ----------
+    a1, a2 : array_like
+        Input arrays.
+
+    Returns
+    -------
+    b : bool
+        Returns True if the arrays are equal.
+
+    See Also
+    --------
+    allclose: Returns True if two arrays are element-wise equal within a
+              tolerance.
+    array_equiv: Returns True if input arrays are shape consistent and all
+                 elements equal.
+
+    Examples
+    --------
+    >>> np.array_equal([1, 2], [1, 2])
+    True
+    >>> np.array_equal(np.array([1, 2]), np.array([1, 2]))
+    True
+    >>> np.array_equal([1, 2], [1, 2, 3])
+    False
+    >>> np.array_equal([1, 2], [1, 4])
+    False
+
+    """
+    try:
+        a1, a2 = asarray(a1), asarray(a2)
+    except:
+        return False
+    if a1.shape != a2.shape:
+        return False
+    return bool(asarray(a1 == a2).all())
+
+def array_equiv(a1, a2):
+    """
+    Returns True if input arrays are shape consistent and all elements equal.
+
+    Shape consistent means they are either the same shape, or one input array
+    can be broadcasted to create the same shape as the other one.
+
+    Parameters
+    ----------
+    a1, a2 : array_like
+        Input arrays.
+
+    Returns
+    -------
+    out : bool
+        True if equivalent, False otherwise.
+
+    Examples
+    --------
+    >>> np.array_equiv([1, 2], [1, 2])
+    True
+    >>> np.array_equiv([1, 2], [1, 3])
+    False
+
+    Showing the shape equivalence:
+
+    >>> np.array_equiv([1, 2], [[1, 2], [1, 2]])
+    True
+    >>> np.array_equiv([1, 2], [[1, 2, 1, 2], [1, 2, 1, 2]])
+    False
+
+    >>> np.array_equiv([1, 2], [[1, 2], [1, 3]])
+    False
+
+    """
+    try:
+        a1, a2 = asarray(a1), asarray(a2)
+    except:
+        return False
+    try:
+        multiarray.broadcast(a1, a2)
+    except:
+        return False
+
+    return bool(asarray(a1 == a2).all())
+
+
+_errdict = {"ignore":ERR_IGNORE,
+            "warn":ERR_WARN,
+            "raise":ERR_RAISE,
+            "call":ERR_CALL,
+            "print":ERR_PRINT,
+            "log":ERR_LOG}
+
+_errdict_rev = {}
+for key in _errdict.keys():
+    _errdict_rev[_errdict[key]] = key
+del key
+
+def seterr(all=None, divide=None, over=None, under=None, invalid=None):
+    """
+    Set how floating-point errors are handled.
+
+    Note that operations on integer scalar types (such as `int16`) are
+    handled like floating point, and are affected by these settings.
+
+    Parameters
+    ----------
+    all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Set treatment for all types of floating-point errors at once:
+
+        - ignore: Take no action when the exception occurs.
+        - warn: Print a `RuntimeWarning` (via the Python `warnings` module).
+        - raise: Raise a `FloatingPointError`.
+        - call: Call a function specified using the `seterrcall` function.
+        - print: Print a warning directly to ``stdout``.
+        - log: Record error in a Log object specified by `seterrcall`.
+
+        The default is not to change the current behavior.
+    divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for division by zero.
+    over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for floating-point overflow.
+    under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for floating-point underflow.
+    invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+        Treatment for invalid floating-point operation.
+
+    Returns
+    -------
+    old_settings : dict
+        Dictionary containing the old settings.
+
+    See also
+    --------
+    seterrcall : Set a callback function for the 'call' mode.
+    geterr, geterrcall, errstate
+
+    Notes
+    -----
+    The floating-point exceptions are defined in the IEEE 754 standard [1]:
+
+    - Division by zero: infinite result obtained from finite numbers.
+    - Overflow: result too large to be expressed.
+    - Underflow: result so close to zero that some precision
+      was lost.
+    - Invalid operation: result is not an expressible number, typically
+      indicates that a NaN was produced.
+
+    .. [1] http://en.wikipedia.org/wiki/IEEE_754
+
+    Examples
+    --------
+    >>> old_settings = np.seterr(all='ignore')  #seterr to known value
+    >>> np.seterr(over='raise')
+    {'over': 'ignore', 'divide': 'ignore', 'invalid': 'ignore',
+     'under': 'ignore'}
+    >>> np.seterr(**old_settings)  # reset to default
+    {'over': 'raise', 'divide': 'ignore', 'invalid': 'ignore', 'under': 'ignore'}
+
+    >>> np.int16(32000) * np.int16(3)
+    30464
+    >>> old_settings = np.seterr(all='warn', over='raise')
+    >>> np.int16(32000) * np.int16(3)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    FloatingPointError: overflow encountered in short_scalars
+
+    >>> old_settings = np.seterr(all='print')
+    >>> np.geterr()
+    {'over': 'print', 'divide': 'print', 'invalid': 'print', 'under': 'print'}
+    >>> np.int16(32000) * np.int16(3)
+    Warning: overflow encountered in short_scalars
+    30464
+
+    """
+
+    pyvals = umath.geterrobj()
+    old = geterr()
+
+    if divide is None:
+        divide = all or old['divide']
+    if over is None:
+        over = all or old['over']
+    if under is None:
+        under = all or old['under']
+    if invalid is None:
+        invalid = all or old['invalid']
+
+    maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) +
+                 (_errdict[over] << SHIFT_OVERFLOW) +
+                 (_errdict[under] << SHIFT_UNDERFLOW) +
+                 (_errdict[invalid] << SHIFT_INVALID))
+
+    pyvals[1] = maskvalue
+    umath.seterrobj(pyvals)
+    return old
+
+
+def geterr():
+    """
+    Get the current way of handling floating-point errors.
+
+    Returns
+    -------
+    res : dict
+        A dictionary with keys "divide", "over", "under", and "invalid",
+        whose values are from the strings "ignore", "print", "log", "warn",
+        "raise", and "call". The keys represent possible floating-point
+        exceptions, and the values define how these exceptions are handled.
+
+    See Also
+    --------
+    geterrcall, seterr, seterrcall
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'warn', 'invalid': 'warn',
+    'under': 'ignore'}
+    >>> np.arange(3.) / np.arange(3.)
+    array([ NaN,   1.,   1.])
+
+    >>> oldsettings = np.seterr(all='warn', over='raise')
+    >>> np.geterr()
+    {'over': 'raise', 'divide': 'warn', 'invalid': 'warn', 'under': 'warn'}
+    >>> np.arange(3.) / np.arange(3.)
+    __main__:1: RuntimeWarning: invalid value encountered in divide
+    array([ NaN,   1.,   1.])
+
+    """
+    maskvalue = umath.geterrobj()[1]
+    mask = 7
+    res = {}
+    val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask
+    res['divide'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_OVERFLOW) & mask
+    res['over'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_UNDERFLOW) & mask
+    res['under'] = _errdict_rev[val]
+    val = (maskvalue >> SHIFT_INVALID) & mask
+    res['invalid'] = _errdict_rev[val]
+    return res
+
+def setbufsize(size):
+    """
+    Set the size of the buffer used in ufuncs.
+
+    Parameters
+    ----------
+    size : int
+        Size of buffer.
+
+    """
+    if size > 10e6:
+        raise ValueError("Buffer size, %s, is too big." % size)
+    if size < 5:
+        raise ValueError("Buffer size, %s, is too small." % size)
+    if size % 16 != 0:
+        raise ValueError("Buffer size, %s, is not a multiple of 16." % size)
+
+    pyvals = umath.geterrobj()
+    old = getbufsize()
+    pyvals[0] = size
+    umath.seterrobj(pyvals)
+    return old
+
+def getbufsize():
+    """
+    Return the size of the buffer used in ufuncs.
+
+    Returns
+    -------
+    getbufsize : int
+        Size of ufunc buffer in bytes.
+
+    """
+    return umath.geterrobj()[0]
+
+def seterrcall(func):
+    """
+    Set the floating-point error callback function or log object.
+
+    There are two ways to capture floating-point error messages.  The first
+    is to set the error-handler to 'call', using `seterr`.  Then, set
+    the function to call using this function.
+
+    The second is to set the error-handler to 'log', using `seterr`.
+    Floating-point errors then trigger a call to the 'write' method of
+    the provided object.
+
+    Parameters
+    ----------
+    func : callable f(err, flag) or object with write method
+        Function to call upon floating-point errors ('call'-mode) or
+        object whose 'write' method is used to log such message ('log'-mode).
+
+        The call function takes two arguments. The first is a string describing the
+        type of error (such as "divide by zero", "overflow", "underflow", or "invalid value"),
+        and the second is the status flag.  The flag is a byte, whose four
+        least-significant bits indicate the type of error, one of "divide", "over",
+        "under", "invalid"::
+
+          [0 0 0 0 divide over under invalid]
+
+        In other words, ``flags = divide + 2*over + 4*under + 8*invalid``.
+
+        If an object is provided, its write method should take one argument,
+        a string.
+
+    Returns
+    -------
+    h : callable, log instance or None
+        The old error handler.
+
+    See Also
+    --------
+    seterr, geterr, geterrcall
+
+    Examples
+    --------
+    Callback upon error:
+
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    ...
+
+    >>> saved_handler = np.seterrcall(err_handler)
+    >>> save_err = np.seterr(all='call')
+
+    >>> np.array([1, 2, 3]) / 0.0
+    Floating point error (divide by zero), with flag 1
+    array([ Inf,  Inf,  Inf])
+
+    >>> np.seterrcall(saved_handler)
+    <function err_handler at 0x...>
+    >>> np.seterr(**save_err)
+    {'over': 'call', 'divide': 'call', 'invalid': 'call', 'under': 'call'}
+
+    Log error message:
+
+    >>> class Log(object):
+    ...     def write(self, msg):
+    ...         print("LOG: %s" % msg)
+    ...
+
+    >>> log = Log()
+    >>> saved_handler = np.seterrcall(log)
+    >>> save_err = np.seterr(all='log')
+
+    >>> np.array([1, 2, 3]) / 0.0
+    LOG: Warning: divide by zero encountered in divide
+    <BLANKLINE>
+    array([ Inf,  Inf,  Inf])
+
+    >>> np.seterrcall(saved_handler)
+    <__main__.Log object at 0x...>
+    >>> np.seterr(**save_err)
+    {'over': 'log', 'divide': 'log', 'invalid': 'log', 'under': 'log'}
+
+    """
+    if func is not None and not isinstance(func, collections.Callable):
+        if not hasattr(func, 'write') or not isinstance(func.write, collections.Callable):
+            raise ValueError("Only callable can be used as callback")
+    pyvals = umath.geterrobj()
+    old = geterrcall()
+    pyvals[2] = func
+    umath.seterrobj(pyvals)
+    return old
+
+def geterrcall():
+    """
+    Return the current callback function used on floating-point errors.
+
+    When the error handling for a floating-point error (one of "divide",
+    "over", "under", or "invalid") is set to 'call' or 'log', the function
+    that is called or the log instance that is written to is returned by
+    `geterrcall`. This function or log instance has been set with
+    `seterrcall`.
+
+    Returns
+    -------
+    errobj : callable, log instance or None
+        The current error handler. If no handler was set through `seterrcall`,
+        ``None`` is returned.
+
+    See Also
+    --------
+    seterrcall, seterr, geterr
+
+    Notes
+    -----
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> np.geterrcall()  # we did not yet set a handler, returns None
+
+    >>> oldsettings = np.seterr(all='call')
+    >>> def err_handler(type, flag):
+    ...     print("Floating point error (%s), with flag %s" % (type, flag))
+    >>> oldhandler = np.seterrcall(err_handler)
+    >>> np.array([1, 2, 3]) / 0.0
+    Floating point error (divide by zero), with flag 1
+    array([ Inf,  Inf,  Inf])
+
+    >>> cur_handler = np.geterrcall()
+    >>> cur_handler is err_handler
+    True
+
+    """
+    return umath.geterrobj()[2]
+
+class _unspecified(object):
+    pass
+_Unspecified = _unspecified()
+
+class errstate(object):
+    """
+    errstate(**kwargs)
+
+    Context manager for floating-point error handling.
+
+    Using an instance of `errstate` as a context manager allows statements in
+    that context to execute with a known error handling behavior. Upon entering
+    the context the error handling is set with `seterr` and `seterrcall`, and
+    upon exiting it is reset to what it was before.
+
+    Parameters
+    ----------
+    kwargs : {divide, over, under, invalid}
+        Keyword arguments. The valid keywords are the possible floating-point
+        exceptions. Each keyword should have a string value that defines the
+        treatment for the particular error. Possible values are
+        {'ignore', 'warn', 'raise', 'call', 'print', 'log'}.
+
+    See Also
+    --------
+    seterr, geterr, seterrcall, geterrcall
+
+    Notes
+    -----
+    The ``with`` statement was introduced in Python 2.5, and can only be used
+    there by importing it: ``from __future__ import with_statement``. In
+    earlier Python versions the ``with`` statement is not available.
+
+    For complete documentation of the types of floating-point exceptions and
+    treatment options, see `seterr`.
+
+    Examples
+    --------
+    >>> from __future__ import with_statement  # use 'with' in Python 2.5
+    >>> olderr = np.seterr(all='ignore')  # Set error handling to known state.
+
+    >>> np.arange(3) / 0.
+    array([ NaN,  Inf,  Inf])
+    >>> with np.errstate(divide='warn'):
+    ...     np.arange(3) / 0.
+    ...
+    __main__:2: RuntimeWarning: divide by zero encountered in divide
+    array([ NaN,  Inf,  Inf])
+
+    >>> np.sqrt(-1)
+    nan
+    >>> with np.errstate(invalid='raise'):
+    ...     np.sqrt(-1)
+    Traceback (most recent call last):
+      File "<stdin>", line 2, in <module>
+    FloatingPointError: invalid value encountered in sqrt
+
+    Outside the context the error handling behavior has not changed:
+
+    >>> np.geterr()
+    {'over': 'warn', 'divide': 'warn', 'invalid': 'warn',
+    'under': 'ignore'}
+
+    """
+    # Note that we don't want to run the above doctests because they will fail
+    # without a from __future__ import with_statement
+
+    def __init__(self, **kwargs):
+        self.call = kwargs.pop('call', _Unspecified)
+        self.kwargs = kwargs
+
+    def __enter__(self):
+        self.oldstate = seterr(**self.kwargs)
+        if self.call is not _Unspecified:
+            self.oldcall = seterrcall(self.call)
+
+    def __exit__(self, *exc_info):
+        seterr(**self.oldstate)
+        if self.call is not _Unspecified:
+            seterrcall(self.oldcall)
+
+
+def _setdef():
+    defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
+    umath.seterrobj(defval)
+
+# set the default values
+_setdef()
+
+Inf = inf = infty = Infinity = PINF
+nan = NaN = NAN
+False_ = bool_(False)
+True_ = bool_(True)
+
+from .umath import *
+from .numerictypes import *
+from . import fromnumeric
+from .fromnumeric import *
+extend_all(fromnumeric)
+extend_all(umath)
+extend_all(numerictypes)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.py
new file mode 100644
index 0000000000..1b6551e6c8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.py
@@ -0,0 +1,1036 @@
+"""
+numerictypes: Define the numeric type objects
+
+This module is designed so "from numerictypes import \\*" is safe.
+Exported symbols include:
+
+  Dictionary with all registered number types (including aliases):
+    typeDict
+
+  Type objects (not all will be available, depends on platform):
+      see variable sctypes for which ones you have
+
+    Bit-width names
+
+    int8 int16 int32 int64 int128
+    uint8 uint16 uint32 uint64 uint128
+    float16 float32 float64 float96 float128 float256
+    complex32 complex64 complex128 complex192 complex256 complex512
+    datetime64 timedelta64
+
+    c-based names
+
+    bool_
+
+    object_
+
+    void, str_, unicode_
+
+    byte, ubyte,
+    short, ushort
+    intc, uintc,
+    intp, uintp,
+    int_, uint,
+    longlong, ulonglong,
+
+    single, csingle,
+    float_, complex_,
+    longfloat, clongfloat,
+
+   As part of the type-hierarchy:    xx -- is bit-width
+
+   generic
+     +-> bool_                                  (kind=b)
+     +-> number                                 (kind=i)
+     |     integer
+     |     signedinteger   (intxx)
+     |     byte
+     |     short
+     |     intc
+     |     intp           int0
+     |     int_
+     |     longlong
+     +-> unsignedinteger  (uintxx)              (kind=u)
+     |     ubyte
+     |     ushort
+     |     uintc
+     |     uintp          uint0
+     |     uint_
+     |     ulonglong
+     +-> inexact
+     |   +-> floating           (floatxx)       (kind=f)
+     |   |     half
+     |   |     single
+     |   |     float_  (double)
+     |   |     longfloat
+     |   \\-> complexfloating    (complexxx)     (kind=c)
+     |         csingle  (singlecomplex)
+     |         complex_ (cfloat, cdouble)
+     |         clongfloat (longcomplex)
+     +-> flexible
+     |     character
+     |     void                                 (kind=V)
+     |
+     |     str_     (string_, bytes_)           (kind=S)    [Python 2]
+     |     unicode_                             (kind=U)    [Python 2]
+     |
+     |     bytes_   (string_)                   (kind=S)    [Python 3]
+     |     str_     (unicode_)                  (kind=U)    [Python 3]
+     |
+     \\-> object_ (not used much)                (kind=O)
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import types as _types
+import sys
+import numbers
+
+from numpy.compat import bytes, long
+from numpy.core.multiarray import (
+        typeinfo, ndarray, array, empty, dtype, datetime_data,
+        datetime_as_string, busday_offset, busday_count, is_busday,
+        busdaycalendar
+        )
+
+
+# we add more at the bottom
+__all__ = ['sctypeDict', 'sctypeNA', 'typeDict', 'typeNA', 'sctypes',
+           'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
+           'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
+           'issubdtype', 'datetime_data', 'datetime_as_string',
+           'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar',
+           ]
+
+
+# we don't export these for import *, but we do want them accessible
+# as numerictypes.bool, etc.
+if sys.version_info[0] >= 3:
+    from builtins import bool, int, float, complex, object, str
+    unicode = str
+else:
+    from __builtin__ import bool, int, float, complex, object, unicode, str
+
+
+# String-handling utilities to avoid locale-dependence.
+
+# "import string" is costly to import!
+# Construct the translation tables directly
+#   "A" = chr(65), "a" = chr(97)
+_all_chars = [chr(_m) for _m in range(256)]
+_ascii_upper = _all_chars[65:65+26]
+_ascii_lower = _all_chars[97:97+26]
+LOWER_TABLE = "".join(_all_chars[:65] + _ascii_lower + _all_chars[65+26:])
+UPPER_TABLE = "".join(_all_chars[:97] + _ascii_upper + _all_chars[97+26:])
+
+
+def english_lower(s):
+    """ Apply English case rules to convert ASCII strings to all lower case.
+
+    This is an internal utility function to replace calls to str.lower() such
+    that we can avoid changing behavior with changing locales. In particular,
+    Turkish has distinct dotted and dotless variants of the Latin letter "I" in
+    both lowercase and uppercase. Thus, "I".lower() != "i" in a "tr" locale.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    lowered : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_lower
+    >>> english_lower('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+    'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789_'
+    >>> english_lower('')
+    ''
+    """
+    lowered = s.translate(LOWER_TABLE)
+    return lowered
+
+def english_upper(s):
+    """ Apply English case rules to convert ASCII strings to all upper case.
+
+    This is an internal utility function to replace calls to str.upper() such
+    that we can avoid changing behavior with changing locales. In particular,
+    Turkish has distinct dotted and dotless variants of the Latin letter "I" in
+    both lowercase and uppercase. Thus, "i".upper() != "I" in a "tr" locale.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    uppered : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_upper
+    >>> english_upper('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
+    >>> english_upper('')
+    ''
+    """
+    uppered = s.translate(UPPER_TABLE)
+    return uppered
+
+def english_capitalize(s):
+    """ Apply English case rules to convert the first character of an ASCII
+    string to upper case.
+
+    This is an internal utility function to replace calls to str.capitalize()
+    such that we can avoid changing behavior with changing locales.
+
+    Parameters
+    ----------
+    s : str
+
+    Returns
+    -------
+    capitalized : str
+
+    Examples
+    --------
+    >>> from numpy.core.numerictypes import english_capitalize
+    >>> english_capitalize('int8')
+    'Int8'
+    >>> english_capitalize('Int8')
+    'Int8'
+    >>> english_capitalize('')
+    ''
+    """
+    if s:
+        return english_upper(s[0]) + s[1:]
+    else:
+        return s
+
+
+sctypeDict = {}      # Contains all leaf-node scalar types with aliases
+sctypeNA = {}        # Contails all leaf-node types -> numarray type equivalences
+allTypes = {}      # Collect the types we will add to the module here
+
+def _evalname(name):
+    k = 0
+    for ch in name:
+        if ch in '0123456789':
+            break
+        k += 1
+    try:
+        bits = int(name[k:])
+    except ValueError:
+        bits = 0
+    base = name[:k]
+    return base, bits
+
+def bitname(obj):
+    """Return a bit-width name for a given type object"""
+    name = obj.__name__
+    base = ''
+    char = ''
+    try:
+        if name[-1] == '_':
+            newname = name[:-1]
+        else:
+            newname = name
+        info = typeinfo[english_upper(newname)]
+        assert(info[-1] == obj)  # sanity check
+        bits = info[2]
+
+    except KeyError:     # bit-width name
+        base, bits = _evalname(name)
+        char = base[0]
+
+    if name == 'bool_':
+        char = 'b'
+        base = 'bool'
+    elif name == 'void':
+        char = 'V'
+        base = 'void'
+    elif name == 'object_':
+        char = 'O'
+        base = 'object'
+        bits = 0
+    elif name == 'datetime64':
+        char = 'M'
+    elif name == 'timedelta64':
+        char = 'm'
+
+    if sys.version_info[0] >= 3:
+        if name == 'bytes_':
+            char = 'S'
+            base = 'bytes'
+        elif name == 'str_':
+            char = 'U'
+            base = 'str'
+    else:
+        if name == 'string_':
+            char = 'S'
+            base = 'string'
+        elif name == 'unicode_':
+            char = 'U'
+            base = 'unicode'
+
+    bytes = bits // 8
+
+    if char != '' and bytes != 0:
+        char = "%s%d" % (char, bytes)
+
+    return base, bits, char
+
+
+def _add_types():
+    for a in typeinfo.keys():
+        name = english_lower(a)
+        if isinstance(typeinfo[a], tuple):
+            typeobj = typeinfo[a][-1]
+
+            # define C-name and insert typenum and typechar references also
+            allTypes[name] = typeobj
+            sctypeDict[name] = typeobj
+            sctypeDict[typeinfo[a][0]] = typeobj
+            sctypeDict[typeinfo[a][1]] = typeobj
+
+        else:  # generic class
+            allTypes[name] = typeinfo[a]
+_add_types()
+
+def _add_aliases():
+    for a in typeinfo.keys():
+        name = english_lower(a)
+        if not isinstance(typeinfo[a], tuple):
+            continue
+        typeobj = typeinfo[a][-1]
+        # insert bit-width version for this class (if relevant)
+        base, bit, char = bitname(typeobj)
+        if base[-3:] == 'int' or char[0] in 'ui':
+            continue
+        if base != '':
+            myname = "%s%d" % (base, bit)
+            if ((name != 'longdouble' and name != 'clongdouble') or
+                   myname not in allTypes.keys()):
+                allTypes[myname] = typeobj
+                sctypeDict[myname] = typeobj
+                if base == 'complex':
+                    na_name = '%s%d' % (english_capitalize(base), bit//2)
+                elif base == 'bool':
+                    na_name = english_capitalize(base)
+                    sctypeDict[na_name] = typeobj
+                else:
+                    na_name = "%s%d" % (english_capitalize(base), bit)
+                    sctypeDict[na_name] = typeobj
+                sctypeNA[na_name] = typeobj
+                sctypeDict[na_name] = typeobj
+                sctypeNA[typeobj] = na_name
+                sctypeNA[typeinfo[a][0]] = na_name
+        if char != '':
+            sctypeDict[char] = typeobj
+            sctypeNA[char] = na_name
+_add_aliases()
+
+# Integers are handled so that the int32 and int64 types should agree
+# exactly with NPY_INT32, NPY_INT64. We need to enforce the same checking
+# as is done in arrayobject.h where the order of getting a bit-width match
+# is long, longlong, int, short, char.
+def _add_integer_aliases():
+    _ctypes = ['LONG', 'LONGLONG', 'INT', 'SHORT', 'BYTE']
+    for ctype in _ctypes:
+        val = typeinfo[ctype]
+        bits = val[2]
+        charname = 'i%d' % (bits//8,)
+        ucharname = 'u%d' % (bits//8,)
+        intname = 'int%d' % bits
+        UIntname = 'UInt%d' % bits
+        Intname = 'Int%d' % bits
+        uval = typeinfo['U'+ctype]
+        typeobj = val[-1]
+        utypeobj = uval[-1]
+        if intname not in allTypes.keys():
+            uintname = 'uint%d' % bits
+            allTypes[intname] = typeobj
+            allTypes[uintname] = utypeobj
+            sctypeDict[intname] = typeobj
+            sctypeDict[uintname] = utypeobj
+            sctypeDict[Intname] = typeobj
+            sctypeDict[UIntname] = utypeobj
+            sctypeDict[charname] = typeobj
+            sctypeDict[ucharname] = utypeobj
+            sctypeNA[Intname] = typeobj
+            sctypeNA[UIntname] = utypeobj
+            sctypeNA[charname] = typeobj
+            sctypeNA[ucharname] = utypeobj
+        sctypeNA[typeobj] = Intname
+        sctypeNA[utypeobj] = UIntname
+        sctypeNA[val[0]] = Intname
+        sctypeNA[uval[0]] = UIntname
+_add_integer_aliases()
+
+# We use these later
+void = allTypes['void']
+generic = allTypes['generic']
+
+#
+# Rework the Python names (so that float and complex and int are consistent
+#                            with Python usage)
+#
+def _set_up_aliases():
+    type_pairs = [('complex_', 'cdouble'),
+                  ('int0', 'intp'),
+                  ('uint0', 'uintp'),
+                  ('single', 'float'),
+                  ('csingle', 'cfloat'),
+                  ('singlecomplex', 'cfloat'),
+                  ('float_', 'double'),
+                  ('intc', 'int'),
+                  ('uintc', 'uint'),
+                  ('int_', 'long'),
+                  ('uint', 'ulong'),
+                  ('cfloat', 'cdouble'),
+                  ('longfloat', 'longdouble'),
+                  ('clongfloat', 'clongdouble'),
+                  ('longcomplex', 'clongdouble'),
+                  ('bool_', 'bool'),
+                  ('unicode_', 'unicode'),
+                  ('object_', 'object')]
+    if sys.version_info[0] >= 3:
+        type_pairs.extend([('bytes_', 'string'),
+                           ('str_', 'unicode'),
+                           ('string_', 'string')])
+    else:
+        type_pairs.extend([('str_', 'string'),
+                           ('string_', 'string'),
+                           ('bytes_', 'string')])
+    for alias, t in type_pairs:
+        allTypes[alias] = allTypes[t]
+        sctypeDict[alias] = sctypeDict[t]
+    # Remove aliases overriding python types and modules
+    to_remove = ['ulong', 'object', 'unicode', 'int', 'long', 'float',
+                 'complex', 'bool', 'string', 'datetime', 'timedelta']
+    if sys.version_info[0] >= 3:
+        # Py3K
+        to_remove.append('bytes')
+        to_remove.append('str')
+        to_remove.remove('unicode')
+        to_remove.remove('long')
+    for t in to_remove:
+        try:
+            del allTypes[t]
+            del sctypeDict[t]
+        except KeyError:
+            pass
+_set_up_aliases()
+
+# Now, construct dictionary to lookup character codes from types
+_sctype2char_dict = {}
+def _construct_char_code_lookup():
+    for name in typeinfo.keys():
+        tup = typeinfo[name]
+        if isinstance(tup, tuple):
+            if tup[0] not in ['p', 'P']:
+                _sctype2char_dict[tup[-1]] = tup[0]
+_construct_char_code_lookup()
+
+
+sctypes = {'int': [],
+           'uint':[],
+           'float':[],
+           'complex':[],
+           'others':[bool, object, str, unicode, void]}
+
+def _add_array_type(typename, bits):
+    try:
+        t = allTypes['%s%d' % (typename, bits)]
+    except KeyError:
+        pass
+    else:
+        sctypes[typename].append(t)
+
+def _set_array_types():
+    ibytes = [1, 2, 4, 8, 16, 32, 64]
+    fbytes = [2, 4, 8, 10, 12, 16, 32, 64]
+    for bytes in ibytes:
+        bits = 8*bytes
+        _add_array_type('int', bits)
+        _add_array_type('uint', bits)
+    for bytes in fbytes:
+        bits = 8*bytes
+        _add_array_type('float', bits)
+        _add_array_type('complex', 2*bits)
+    _gi = dtype('p')
+    if _gi.type not in sctypes['int']:
+        indx = 0
+        sz = _gi.itemsize
+        _lst = sctypes['int']
+        while (indx < len(_lst) and sz >= _lst[indx](0).itemsize):
+            indx += 1
+        sctypes['int'].insert(indx, _gi.type)
+        sctypes['uint'].insert(indx, dtype('P').type)
+_set_array_types()
+
+
+genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16',
+                   'int32', 'uint32', 'int64', 'uint64', 'int128',
+                   'uint128', 'float16',
+                   'float32', 'float64', 'float80', 'float96', 'float128',
+                   'float256',
+                   'complex32', 'complex64', 'complex128', 'complex160',
+                   'complex192', 'complex256', 'complex512', 'object']
+
+def maximum_sctype(t):
+    """
+    Return the scalar type of highest precision of the same kind as the input.
+
+    Parameters
+    ----------
+    t : dtype or dtype specifier
+        The input data type. This can be a `dtype` object or an object that
+        is convertible to a `dtype`.
+
+    Returns
+    -------
+    out : dtype
+        The highest precision data type of the same kind (`dtype.kind`) as `t`.
+
+    See Also
+    --------
+    obj2sctype, mintypecode, sctype2char
+    dtype
+
+    Examples
+    --------
+    >>> np.maximum_sctype(np.int)
+    <type 'numpy.int64'>
+    >>> np.maximum_sctype(np.uint8)
+    <type 'numpy.uint64'>
+    >>> np.maximum_sctype(np.complex)
+    <type 'numpy.complex192'>
+
+    >>> np.maximum_sctype(str)
+    <type 'numpy.string_'>
+
+    >>> np.maximum_sctype('i2')
+    <type 'numpy.int64'>
+    >>> np.maximum_sctype('f4')
+    <type 'numpy.float96'>
+
+    """
+    g = obj2sctype(t)
+    if g is None:
+        return t
+    t = g
+    name = t.__name__
+    base, bits = _evalname(name)
+    if bits == 0:
+        return t
+    else:
+        return sctypes[base][-1]
+
+try:
+    buffer_type = _types.BufferType
+except AttributeError:
+    # Py3K
+    buffer_type = memoryview
+
+_python_types = {int: 'int_',
+                 float: 'float_',
+                 complex: 'complex_',
+                 bool: 'bool_',
+                 bytes: 'bytes_',
+                 unicode: 'unicode_',
+                 buffer_type: 'void',
+                 }
+
+if sys.version_info[0] >= 3:
+    def _python_type(t):
+        """returns the type corresponding to a certain Python type"""
+        if not isinstance(t, type):
+            t = type(t)
+        return allTypes[_python_types.get(t, 'object_')]
+else:
+    def _python_type(t):
+        """returns the type corresponding to a certain Python type"""
+        if not isinstance(t, _types.TypeType):
+            t = type(t)
+        return allTypes[_python_types.get(t, 'object_')]
+
+def issctype(rep):
+    """
+    Determines whether the given object represents a scalar data-type.
+
+    Parameters
+    ----------
+    rep : any
+        If `rep` is an instance of a scalar dtype, True is returned. If not,
+        False is returned.
+
+    Returns
+    -------
+    out : bool
+        Boolean result of check whether `rep` is a scalar dtype.
+
+    See Also
+    --------
+    issubsctype, issubdtype, obj2sctype, sctype2char
+
+    Examples
+    --------
+    >>> np.issctype(np.int32)
+    True
+    >>> np.issctype(list)
+    False
+    >>> np.issctype(1.1)
+    False
+
+    Strings are also a scalar type:
+
+    >>> np.issctype(np.dtype('str'))
+    True
+
+    """
+    if not isinstance(rep, (type, dtype)):
+        return False
+    try:
+        res = obj2sctype(rep)
+        if res and res != object_:
+            return True
+        return False
+    except:
+        return False
+
+def obj2sctype(rep, default=None):
+    """
+    Return the scalar dtype or NumPy equivalent of Python type of an object.
+
+    Parameters
+    ----------
+    rep : any
+        The object of which the type is returned.
+    default : any, optional
+        If given, this is returned for objects whose types can not be
+        determined. If not given, None is returned for those objects.
+
+    Returns
+    -------
+    dtype : dtype or Python type
+        The data type of `rep`.
+
+    See Also
+    --------
+    sctype2char, issctype, issubsctype, issubdtype, maximum_sctype
+
+    Examples
+    --------
+    >>> np.obj2sctype(np.int32)
+    <type 'numpy.int32'>
+    >>> np.obj2sctype(np.array([1., 2.]))
+    <type 'numpy.float64'>
+    >>> np.obj2sctype(np.array([1.j]))
+    <type 'numpy.complex128'>
+
+    >>> np.obj2sctype(dict)
+    <type 'numpy.object_'>
+    >>> np.obj2sctype('string')
+    <type 'numpy.string_'>
+
+    >>> np.obj2sctype(1, default=list)
+    <type 'list'>
+
+    """
+    try:
+        if issubclass(rep, generic):
+            return rep
+    except TypeError:
+        pass
+    if isinstance(rep, dtype):
+        return rep.type
+    if isinstance(rep, type):
+        return _python_type(rep)
+    if isinstance(rep, ndarray):
+        return rep.dtype.type
+    try:
+        res = dtype(rep)
+    except:
+        return default
+    return res.type
+
+
+def issubclass_(arg1, arg2):
+    """
+    Determine if a class is a subclass of a second class.
+
+    `issubclass_` is equivalent to the Python built-in ``issubclass``,
+    except that it returns False instead of raising a TypeError if one
+    of the arguments is not a class.
+
+    Parameters
+    ----------
+    arg1 : class
+        Input class. True is returned if `arg1` is a subclass of `arg2`.
+    arg2 : class or tuple of classes.
+        Input class. If a tuple of classes, True is returned if `arg1` is a
+        subclass of any of the tuple elements.
+
+    Returns
+    -------
+    out : bool
+        Whether `arg1` is a subclass of `arg2` or not.
+
+    See Also
+    --------
+    issubsctype, issubdtype, issctype
+
+    Examples
+    --------
+    >>> np.issubclass_(np.int32, np.int)
+    True
+    >>> np.issubclass_(np.int32, np.float)
+    False
+
+    """
+    try:
+        return issubclass(arg1, arg2)
+    except TypeError:
+        return False
+
+def issubsctype(arg1, arg2):
+    """
+    Determine if the first argument is a subclass of the second argument.
+
+    Parameters
+    ----------
+    arg1, arg2 : dtype or dtype specifier
+        Data-types.
+
+    Returns
+    -------
+    out : bool
+        The result.
+
+    See Also
+    --------
+    issctype, issubdtype,obj2sctype
+
+    Examples
+    --------
+    >>> np.issubsctype('S8', str)
+    True
+    >>> np.issubsctype(np.array([1]), np.int)
+    True
+    >>> np.issubsctype(np.array([1]), np.float)
+    False
+
+    """
+    return issubclass(obj2sctype(arg1), obj2sctype(arg2))
+
+def issubdtype(arg1, arg2):
+    """
+    Returns True if first argument is a typecode lower/equal in type hierarchy.
+
+    Parameters
+    ----------
+    arg1, arg2 : dtype_like
+        dtype or string representing a typecode.
+
+    Returns
+    -------
+    out : bool
+
+    See Also
+    --------
+    issubsctype, issubclass_
+    numpy.core.numerictypes : Overview of numpy type hierarchy.
+
+    Examples
+    --------
+    >>> np.issubdtype('S1', str)
+    True
+    >>> np.issubdtype(np.float64, np.float32)
+    False
+
+    """
+    if issubclass_(arg2, generic):
+        return issubclass(dtype(arg1).type, arg2)
+    mro = dtype(arg2).type.mro()
+    if len(mro) > 1:
+        val = mro[1]
+    else:
+        val = mro[0]
+    return issubclass(dtype(arg1).type, val)
+
+
+# This dictionary allows look up based on any alias for an array data-type
+class _typedict(dict):
+    """
+    Base object for a dictionary for look-up with any alias for an array dtype.
+
+    Instances of `_typedict` can not be used as dictionaries directly,
+    first they have to be populated.
+
+    """
+
+    def __getitem__(self, obj):
+        return dict.__getitem__(self, obj2sctype(obj))
+
+nbytes = _typedict()
+_alignment = _typedict()
+_maxvals = _typedict()
+_minvals = _typedict()
+def _construct_lookups():
+    for name, val in typeinfo.items():
+        if not isinstance(val, tuple):
+            continue
+        obj = val[-1]
+        nbytes[obj] = val[2] // 8
+        _alignment[obj] = val[3]
+        if (len(val) > 5):
+            _maxvals[obj] = val[4]
+            _minvals[obj] = val[5]
+        else:
+            _maxvals[obj] = None
+            _minvals[obj] = None
+
+_construct_lookups()
+
+def sctype2char(sctype):
+    """
+    Return the string representation of a scalar dtype.
+
+    Parameters
+    ----------
+    sctype : scalar dtype or object
+        If a scalar dtype, the corresponding string character is
+        returned. If an object, `sctype2char` tries to infer its scalar type
+        and then return the corresponding string character.
+
+    Returns
+    -------
+    typechar : str
+        The string character corresponding to the scalar type.
+
+    Raises
+    ------
+    ValueError
+        If `sctype` is an object for which the type can not be inferred.
+
+    See Also
+    --------
+    obj2sctype, issctype, issubsctype, mintypecode
+
+    Examples
+    --------
+    >>> for sctype in [np.int32, np.float, np.complex, np.string_, np.ndarray]:
+    ...     print(np.sctype2char(sctype))
+    l
+    d
+    D
+    S
+    O
+
+    >>> x = np.array([1., 2-1.j])
+    >>> np.sctype2char(x)
+    'D'
+    >>> np.sctype2char(list)
+    'O'
+
+    """
+    sctype = obj2sctype(sctype)
+    if sctype is None:
+        raise ValueError("unrecognized type")
+    return _sctype2char_dict[sctype]
+
+# Create dictionary of casting functions that wrap sequences
+# indexed by type or type character
+
+
+cast = _typedict()
+try:
+    ScalarType = [_types.IntType, _types.FloatType, _types.ComplexType,
+                  _types.LongType, _types.BooleanType,
+                   _types.StringType, _types.UnicodeType, _types.BufferType]
+except AttributeError:
+    # Py3K
+    ScalarType = [int, float, complex, int, bool, bytes, str, memoryview]
+
+ScalarType.extend(_sctype2char_dict.keys())
+ScalarType = tuple(ScalarType)
+for key in _sctype2char_dict.keys():
+    cast[key] = lambda x, k=key: array(x, copy=False).astype(k)
+
+# Create the typestring lookup dictionary
+_typestr = _typedict()
+for key in _sctype2char_dict.keys():
+    if issubclass(key, allTypes['flexible']):
+        _typestr[key] = _sctype2char_dict[key]
+    else:
+        _typestr[key] = empty((1,), key).dtype.str[1:]
+
+# Make sure all typestrings are in sctypeDict
+for key, val in _typestr.items():
+    if val not in sctypeDict:
+        sctypeDict[val] = key
+
+# Add additional strings to the sctypeDict
+
+if sys.version_info[0] >= 3:
+    _toadd = ['int', 'float', 'complex', 'bool', 'object',
+              'str', 'bytes', 'object', ('a', allTypes['bytes_'])]
+else:
+    _toadd = ['int', 'float', 'complex', 'bool', 'object', 'string',
+              ('str', allTypes['string_']),
+              'unicode', 'object', ('a', allTypes['string_'])]
+
+for name in _toadd:
+    if isinstance(name, tuple):
+        sctypeDict[name[0]] = name[1]
+    else:
+        sctypeDict[name] = allTypes['%s_' % name]
+
+del _toadd, name
+
+# Now add the types we've determined to this module
+for key in allTypes:
+    globals()[key] = allTypes[key]
+    __all__.append(key)
+
+del key
+
+typecodes = {'Character':'c',
+             'Integer':'bhilqp',
+             'UnsignedInteger':'BHILQP',
+             'Float':'efdg',
+             'Complex':'FDG',
+             'AllInteger':'bBhHiIlLqQpP',
+             'AllFloat':'efdgFDG',
+             'Datetime': 'Mm',
+             'All':'?bhilqpBHILQPefdgFDGSUVOMm'}
+
+# backwards compatibility --- deprecated name
+typeDict = sctypeDict
+typeNA = sctypeNA
+
+# b -> boolean
+# u -> unsigned integer
+# i -> signed integer
+# f -> floating point
+# c -> complex
+# M -> datetime
+# m -> timedelta
+# S -> string
+# U -> Unicode string
+# V -> record
+# O -> Python object
+_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm']
+
+__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O'
+__len_test_types = len(__test_types)
+
+# Keep incrementing until a common type both can be coerced to
+#  is found.  Otherwise, return None
+def _find_common_coerce(a, b):
+    if a > b:
+        return a
+    try:
+        thisind = __test_types.index(a.char)
+    except ValueError:
+        return None
+    return _can_coerce_all([a, b], start=thisind)
+
+# Find a data-type that all data-types in a list can be coerced to
+def _can_coerce_all(dtypelist, start=0):
+    N = len(dtypelist)
+    if N == 0:
+        return None
+    if N == 1:
+        return dtypelist[0]
+    thisind = start
+    while thisind < __len_test_types:
+        newdtype = dtype(__test_types[thisind])
+        numcoerce = len([x for x in dtypelist if newdtype >= x])
+        if numcoerce == N:
+            return newdtype
+        thisind += 1
+    return None
+
+def _register_types():
+    numbers.Integral.register(integer)
+    numbers.Complex.register(inexact)
+    numbers.Real.register(floating)
+
+_register_types()
+
+def find_common_type(array_types, scalar_types):
+    """
+    Determine common type following standard coercion rules.
+
+    Parameters
+    ----------
+    array_types : sequence
+        A list of dtypes or dtype convertible objects representing arrays.
+    scalar_types : sequence
+        A list of dtypes or dtype convertible objects representing scalars.
+
+    Returns
+    -------
+    datatype : dtype
+        The common data type, which is the maximum of `array_types` ignoring
+        `scalar_types`, unless the maximum of `scalar_types` is of a
+        different kind (`dtype.kind`). If the kind is not understood, then
+        None is returned.
+
+    See Also
+    --------
+    dtype, common_type, can_cast, mintypecode
+
+    Examples
+    --------
+    >>> np.find_common_type([], [np.int64, np.float32, np.complex])
+    dtype('complex128')
+    >>> np.find_common_type([np.int64, np.float32], [])
+    dtype('float64')
+
+    The standard casting rules ensure that a scalar cannot up-cast an
+    array unless the scalar is of a fundamentally different kind of data
+    (i.e. under a different hierarchy in the data type hierarchy) then
+    the array:
+
+    >>> np.find_common_type([np.float32], [np.int64, np.float64])
+    dtype('float32')
+
+    Complex is of a different type, so it up-casts the float in the
+    `array_types` argument:
+
+    >>> np.find_common_type([np.float32], [np.complex])
+    dtype('complex128')
+
+    Type specifier strings are convertible to dtypes and can therefore
+    be used instead of dtypes:
+
+    >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8'])
+    dtype('complex128')
+
+    """
+    array_types = [dtype(x) for x in array_types]
+    scalar_types = [dtype(x) for x in scalar_types]
+
+    maxa = _can_coerce_all(array_types)
+    maxsc = _can_coerce_all(scalar_types)
+
+    if maxa is None:
+        return maxsc
+
+    if maxsc is None:
+        return maxa
+
+    try:
+        index_a = _kind_list.index(maxa.kind)
+        index_sc = _kind_list.index(maxsc.kind)
+    except ValueError:
+        return None
+
+    if index_sc > index_a:
+        return _find_common_coerce(maxsc, maxa)
+    else:
+        return maxa
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..5b1a62fd8a366b7efbb7b16e75fabd08732457c7
GIT binary patch
literal 18432
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
K$P3#c;9~%ckt_!Q

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/records.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/records.py
new file mode 100644
index 0000000000..9f5dcc8110
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/records.py
@@ -0,0 +1,855 @@
+"""
+Record Arrays
+=============
+Record arrays expose the fields of structured arrays as properties.
+
+Most commonly, ndarrays contain elements of a single type, e.g. floats,
+integers, bools etc.  However, it is possible for elements to be combinations
+of these using structured types, such as::
+
+  >>> a = np.array([(1, 2.0), (1, 2.0)], dtype=[('x', int), ('y', float)])
+  >>> a
+  array([(1, 2.0), (1, 2.0)],
+        dtype=[('x', '<i4'), ('y', '<f8')])
+
+Here, each element consists of two fields: x (and int), and y (a float).
+This is known as a structured array.  The different fields are analogous
+to columns in a spread-sheet.  The different fields can be accessed as
+one would a dictionary::
+
+  >>> a['x']
+  array([1, 1])
+
+  >>> a['y']
+  array([ 2.,  2.])
+
+Record arrays allow us to access fields as properties::
+
+  >>> ar = np.rec.array(a)
+
+  >>> ar.x
+  array([1, 1])
+
+  >>> ar.y
+  array([ 2.,  2.])
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+
+from . import numeric as sb
+from . import numerictypes as nt
+from numpy.compat import isfileobj, bytes, long
+
+# All of the functions allow formats to be a dtype
+__all__ = ['record', 'recarray', 'format_parser']
+
+
+ndarray = sb.ndarray
+
+_byteorderconv = {'b':'>',
+                  'l':'<',
+                  'n':'=',
+                  'B':'>',
+                  'L':'<',
+                  'N':'=',
+                  'S':'s',
+                  's':'s',
+                  '>':'>',
+                  '<':'<',
+                  '=':'=',
+                  '|':'|',
+                  'I':'|',
+                  'i':'|'}
+
+# formats regular expression
+# allows multidimension spec with a tuple syntax in front
+# of the letter code '(2,3)f4' and ' (  2 ,  3  )  f4  '
+# are equally allowed
+
+numfmt = nt.typeDict
+
+def find_duplicate(list):
+    """Find duplication in a list, return a list of duplicated elements"""
+    dup = []
+    for i in range(len(list)):
+        if (list[i] in list[i + 1:]):
+            if (list[i] not in dup):
+                dup.append(list[i])
+    return dup
+
+class format_parser:
+    """
+    Class to convert formats, names, titles description to a dtype.
+
+    After constructing the format_parser object, the dtype attribute is
+    the converted data-type:
+    ``dtype = format_parser(formats, names, titles).dtype``
+
+    Attributes
+    ----------
+    dtype : dtype
+        The converted data-type.
+
+    Parameters
+    ----------
+    formats : str or list of str
+        The format description, either specified as a string with
+        comma-separated format descriptions in the form ``'f8, i4, a5'``, or
+        a list of format description strings  in the form
+        ``['f8', 'i4', 'a5']``.
+    names : str or list/tuple of str
+        The field names, either specified as a comma-separated string in the
+        form ``'col1, col2, col3'``, or as a list or tuple of strings in the
+        form ``['col1', 'col2', 'col3']``.
+        An empty list can be used, in that case default field names
+        ('f0', 'f1', ...) are used.
+    titles : sequence
+        Sequence of title strings. An empty list can be used to leave titles
+        out.
+    aligned : bool, optional
+        If True, align the fields by padding as the C-compiler would.
+        Default is False.
+    byteorder : str, optional
+        If specified, all the fields will be changed to the
+        provided byte-order.  Otherwise, the default byte-order is
+        used. For all available string specifiers, see `dtype.newbyteorder`.
+
+    See Also
+    --------
+    dtype, typename, sctype2char
+
+    Examples
+    --------
+    >>> np.format_parser(['f8', 'i4', 'a5'], ['col1', 'col2', 'col3'],
+    ...                  ['T1', 'T2', 'T3']).dtype
+    dtype([(('T1', 'col1'), '<f8'), (('T2', 'col2'), '<i4'),
+           (('T3', 'col3'), '|S5')])
+
+    `names` and/or `titles` can be empty lists. If `titles` is an empty list,
+    titles will simply not appear. If `names` is empty, default field names
+    will be used.
+
+    >>> np.format_parser(['f8', 'i4', 'a5'], ['col1', 'col2', 'col3'],
+    ...                  []).dtype
+    dtype([('col1', '<f8'), ('col2', '<i4'), ('col3', '|S5')])
+    >>> np.format_parser(['f8', 'i4', 'a5'], [], []).dtype
+    dtype([('f0', '<f8'), ('f1', '<i4'), ('f2', '|S5')])
+
+    """
+
+    def __init__(self, formats, names, titles, aligned=False, byteorder=None):
+        self._parseFormats(formats, aligned)
+        self._setfieldnames(names, titles)
+        self._createdescr(byteorder)
+        self.dtype = self._descr
+
+    def _parseFormats(self, formats, aligned=0):
+        """ Parse the field formats """
+
+        if formats is None:
+            raise ValueError("Need formats argument")
+        if isinstance(formats, list):
+            if len(formats) < 2:
+                formats.append('')
+            formats = ','.join(formats)
+        dtype = sb.dtype(formats, aligned)
+        fields = dtype.fields
+        if fields is None:
+            dtype = sb.dtype([('f1', dtype)], aligned)
+            fields = dtype.fields
+        keys = dtype.names
+        self._f_formats = [fields[key][0] for key in keys]
+        self._offsets = [fields[key][1] for key in keys]
+        self._nfields = len(keys)
+
+    def _setfieldnames(self, names, titles):
+        """convert input field names into a list and assign to the _names
+        attribute """
+
+        if (names):
+            if (type(names) in [list, tuple]):
+                pass
+            elif isinstance(names, str):
+                names = names.split(',')
+            else:
+                raise NameError("illegal input names %s" % repr(names))
+
+            self._names = [n.strip() for n in names[:self._nfields]]
+        else:
+            self._names = []
+
+        # if the names are not specified, they will be assigned as
+        #  "f0, f1, f2,..."
+        # if not enough names are specified, they will be assigned as "f[n],
+        # f[n+1],..." etc. where n is the number of specified names..."
+        self._names += ['f%d' % i for i in range(len(self._names),
+                                                 self._nfields)]
+        # check for redundant names
+        _dup = find_duplicate(self._names)
+        if _dup:
+            raise ValueError("Duplicate field names: %s" % _dup)
+
+        if (titles):
+            self._titles = [n.strip() for n in titles[:self._nfields]]
+        else:
+            self._titles = []
+            titles = []
+
+        if (self._nfields > len(titles)):
+            self._titles += [None] * (self._nfields - len(titles))
+
+    def _createdescr(self, byteorder):
+        descr = sb.dtype({'names':self._names,
+                          'formats':self._f_formats,
+                          'offsets':self._offsets,
+                          'titles':self._titles})
+        if (byteorder is not None):
+            byteorder = _byteorderconv[byteorder[0]]
+            descr = descr.newbyteorder(byteorder)
+
+        self._descr = descr
+
+class record(nt.void):
+    """A data-type scalar that allows field access as attribute lookup.
+    """
+
+    # manually set name and module so that this class's type shows up
+    # as numpy.record when printed
+    __name__ = 'record'
+    __module__ = 'numpy'
+
+    def __repr__(self):
+        return self.__str__()
+
+    def __str__(self):
+        return str(self.item())
+
+    def __getattribute__(self, attr):
+        if attr in ['setfield', 'getfield', 'dtype']:
+            return nt.void.__getattribute__(self, attr)
+        try:
+            return nt.void.__getattribute__(self, attr)
+        except AttributeError:
+            pass
+        fielddict = nt.void.__getattribute__(self, 'dtype').fields
+        res = fielddict.get(attr, None)
+        if res:
+            obj = self.getfield(*res[:2])
+            # if it has fields return a record,
+            # otherwise return the object
+            try:
+                dt = obj.dtype
+            except AttributeError:
+                #happens if field is Object type
+                return obj
+            if dt.fields:
+                return obj.view((self.__class__, obj.dtype.fields))
+            return obj
+        else:
+            raise AttributeError("'record' object has no "
+                    "attribute '%s'" % attr)
+
+    def __setattr__(self, attr, val):
+        if attr in ['setfield', 'getfield', 'dtype']:
+            raise AttributeError("Cannot set '%s' attribute" % attr)
+        fielddict = nt.void.__getattribute__(self, 'dtype').fields
+        res = fielddict.get(attr, None)
+        if res:
+            return self.setfield(val, *res[:2])
+        else:
+            if getattr(self, attr, None):
+                return nt.void.__setattr__(self, attr, val)
+            else:
+                raise AttributeError("'record' object has no "
+                        "attribute '%s'" % attr)
+
+    def __getitem__(self, indx):
+        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))
+        else:
+            # return a single element
+            return obj
+
+    def pprint(self):
+        """Pretty-print all fields."""
+        # pretty-print all fields
+        names = self.dtype.names
+        maxlen = max(len(name) for name in names)
+        rows = []
+        fmt = '%% %ds: %%s' % maxlen
+        for name in names:
+            rows.append(fmt % (name, getattr(self, name)))
+        return "\n".join(rows)
+
+# The recarray is almost identical to a standard array (which supports
+#   named fields already)  The biggest difference is that it can use
+#   attribute-lookup to find the fields and it is constructed using
+#   a record.
+
+# If byteorder is given it forces a particular byteorder on all
+#  the fields (and any subfields)
+
+class recarray(ndarray):
+    """Construct an ndarray that allows field access using attributes.
+
+    Arrays may have a data-types containing fields, analogous
+    to columns in a spread sheet.  An example is ``[(x, int), (y, float)]``,
+    where each entry in the array is a pair of ``(int, float)``.  Normally,
+    these attributes are accessed using dictionary lookups such as ``arr['x']``
+    and ``arr['y']``.  Record arrays allow the fields to be accessed as members
+    of the array, using ``arr.x`` and ``arr.y``.
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of output array.
+    dtype : data-type, optional
+        The desired data-type.  By default, the data-type is determined
+        from `formats`, `names`, `titles`, `aligned` and `byteorder`.
+    formats : list of data-types, optional
+        A list containing the data-types for the different columns, e.g.
+        ``['i4', 'f8', 'i4']``.  `formats` does *not* support the new
+        convention of using types directly, i.e. ``(int, float, int)``.
+        Note that `formats` must be a list, not a tuple.
+        Given that `formats` is somewhat limited, we recommend specifying
+        `dtype` instead.
+    names : tuple of str, optional
+        The name of each column, e.g. ``('x', 'y', 'z')``.
+    buf : buffer, optional
+        By default, a new array is created of the given shape and data-type.
+        If `buf` is specified and is an object exposing the buffer interface,
+        the array will use the memory from the existing buffer.  In this case,
+        the `offset` and `strides` keywords are available.
+
+    Other Parameters
+    ----------------
+    titles : tuple of str, optional
+        Aliases for column names.  For example, if `names` were
+        ``('x', 'y', 'z')`` and `titles` is
+        ``('x_coordinate', 'y_coordinate', 'z_coordinate')``, then
+        ``arr['x']`` is equivalent to both ``arr.x`` and ``arr.x_coordinate``.
+    byteorder : {'<', '>', '='}, optional
+        Byte-order for all fields.
+    aligned : bool, optional
+        Align the fields in memory as the C-compiler would.
+    strides : tuple of ints, optional
+        Buffer (`buf`) is interpreted according to these strides (strides
+        define how many bytes each array element, row, column, etc.
+        occupy in memory).
+    offset : int, optional
+        Start reading buffer (`buf`) from this offset onwards.
+    order : {'C', 'F'}, optional
+        Row-major (C-style) or column-major (Fortran-style) order.
+
+    Returns
+    -------
+    rec : recarray
+        Empty array of the given shape and type.
+
+    See Also
+    --------
+    rec.fromrecords : Construct a record array from data.
+    record : fundamental data-type for `recarray`.
+    format_parser : determine a data-type from formats, names, titles.
+
+    Notes
+    -----
+    This constructor can be compared to ``empty``: it creates a new record
+    array but does not fill it with data.  To create a record array from data,
+    use one of the following methods:
+
+    1. Create a standard ndarray and convert it to a record array,
+       using ``arr.view(np.recarray)``
+    2. Use the `buf` keyword.
+    3. Use `np.rec.fromrecords`.
+
+    Examples
+    --------
+    Create an array with two fields, ``x`` and ``y``:
+
+    >>> x = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y', int)])
+    >>> x
+    array([(1.0, 2), (3.0, 4)],
+          dtype=[('x', '<f8'), ('y', '<i4')])
+
+    >>> x['x']
+    array([ 1.,  3.])
+
+    View the array as a record array:
+
+    >>> x = x.view(np.recarray)
+
+    >>> x.x
+    array([ 1.,  3.])
+
+    >>> x.y
+    array([2, 4])
+
+    Create a new, empty record array:
+
+    >>> np.recarray((2,),
+    ... dtype=[('x', int), ('y', float), ('z', int)]) #doctest: +SKIP
+    rec.array([(-1073741821, 1.2249118382103472e-301, 24547520),
+           (3471280, 1.2134086255804012e-316, 0)],
+          dtype=[('x', '<i4'), ('y', '<f8'), ('z', '<i4')])
+
+    """
+
+    # manually set name and module so that this class's type shows
+    # up as "numpy.recarray" when printed
+    __name__ = 'recarray'
+    __module__ = 'numpy'
+
+    def __new__(subtype, shape, dtype=None, buf=None, offset=0, strides=None,
+                formats=None, names=None, titles=None,
+                byteorder=None, aligned=False, order='C'):
+
+        if dtype is not None:
+            descr = sb.dtype(dtype)
+        else:
+            descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+        if buf is None:
+            self = ndarray.__new__(subtype, shape, (record, descr), order=order)
+        else:
+            self = ndarray.__new__(subtype, shape, (record, descr),
+                                      buffer=buf, offset=offset,
+                                      strides=strides, order=order)
+        return self
+
+    def __array_finalize__(self, obj):
+        if self.dtype.type is not record:
+            # 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
+
+    def __getattribute__(self, attr):
+        # See if ndarray has this attr, and return it if so. (note that this
+        # means a field with the same name as an ndarray attr cannot be
+        # accessed by attribute).
+        try:
+            return object.__getattribute__(self, attr)
+        except AttributeError:  # attr must be a fieldname
+            pass
+
+        # look for a field with this name
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("recarray has no attribute %s" % attr)
+        obj = self.getfield(*res)
+
+        # At this point obj will always be a recarray, since (see
+        # PyArray_GetField) the type of obj is inherited. Next, if obj.dtype is
+        # non-structured, convert it to an ndarray. Then if obj is structured
+        # 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 issubclass(obj.dtype.type, nt.void):
+                return obj.view(dtype=(self.dtype.type, obj.dtype))
+            return obj
+        else:
+            return obj.view(ndarray)
+
+    # Save the dictionary.
+    # If the attr is a field name and not in the saved dictionary
+    # Undo any "setting" of the attribute and do a setfield
+    # Thus, you can't create attributes on-the-fly that are field names.
+    def __setattr__(self, attr, val):
+
+        # 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:
+            val = sb.dtype((record, val))
+
+        newattr = attr not in self.__dict__
+        try:
+            ret = object.__setattr__(self, attr, val)
+        except:
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            if attr not in fielddict:
+                exctype, value = sys.exc_info()[:2]
+                raise exctype(value)
+        else:
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            if attr not in fielddict:
+                return ret
+            if newattr:
+                # We just added this one or this setattr worked on an
+                # internal attribute.
+                try:
+                    object.__delattr__(self, attr)
+                except:
+                    return ret
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+        return self.setfield(val, *res)
+
+    def __getitem__(self, indx):
+        obj = super(recarray, self).__getitem__(indx)
+
+        # copy behavior of getattr, except that here
+        # we might also be returning a single element
+        if isinstance(obj, ndarray):
+            if obj.dtype.fields:
+                obj = obj.view(type(self))
+                if issubclass(obj.dtype.type, nt.void):
+                    return obj.view(dtype=(self.dtype.type, obj.dtype))
+                return obj
+            else:
+                return obj.view(type=ndarray)
+        else:
+            # return a single element
+            return obj
+
+    def __repr__(self):
+        # get data/shape string. logic taken from numeric.array_repr
+        if self.size > 0 or self.shape == (0,):
+            lst = sb.array2string(self, separator=', ')
+        else:
+            # show zero-length shape unless it is (0,)
+            lst = "[], shape=%s" % (repr(self.shape),)
+
+        if (self.dtype.type is record
+                or (not issubclass(self.dtype.type, nt.void))):
+            # If this is a full record array (has numpy.record dtype),
+            # or if it has a scalar (non-void) dtype with no records,
+            # represent it using the rec.array function. Since rec.array
+            # converts dtype to a numpy.record for us, convert back
+            # to non-record before printing
+            plain_dtype = self.dtype
+            if plain_dtype.type is record:
+                plain_dtype = sb.dtype((nt.void, plain_dtype))
+            lf = '\n'+' '*len("rec.array(")
+            return ('rec.array(%s, %sdtype=%s)' %
+                          (lst, lf, plain_dtype))
+        else:
+            # otherwise represent it using np.array plus a view
+            # This should only happen if the user is playing
+            # strange games with dtypes.
+            lf = '\n'+' '*len("array(")
+            return ('array(%s, %sdtype=%s).view(numpy.recarray)' %
+                          (lst, lf, str(self.dtype)))
+
+    def field(self, attr, val=None):
+        if isinstance(attr, int):
+            names = ndarray.__getattribute__(self, 'dtype').names
+            attr = names[attr]
+
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+
+        res = fielddict[attr][:2]
+
+        if val is None:
+            obj = self.getfield(*res)
+            if obj.dtype.fields:
+                return obj
+            return obj.view(ndarray)
+        else:
+            return self.setfield(val, *res)
+
+
+def fromarrays(arrayList, dtype=None, shape=None, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None):
+    """ create a record array from a (flat) list of arrays
+
+    >>> x1=np.array([1,2,3,4])
+    >>> x2=np.array(['a','dd','xyz','12'])
+    >>> x3=np.array([1.1,2,3,4])
+    >>> r = np.core.records.fromarrays([x1,x2,x3],names='a,b,c')
+    >>> print(r[1])
+    (2, 'dd', 2.0)
+    >>> x1[1]=34
+    >>> r.a
+    array([1, 2, 3, 4])
+    """
+
+    arrayList = [sb.asarray(x) for x in arrayList]
+
+    if shape is None or shape == 0:
+        shape = arrayList[0].shape
+
+    if isinstance(shape, int):
+        shape = (shape,)
+
+    if formats is None and dtype is None:
+        # go through each object in the list to see if it is an ndarray
+        # and determine the formats.
+        formats = []
+        for obj in arrayList:
+            if not isinstance(obj, ndarray):
+                raise ValueError("item in the array list must be an ndarray.")
+            formats.append(obj.dtype.str)
+        formats = ','.join(formats)
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+        _names = descr.names
+    else:
+        parsed = format_parser(formats, names, titles, aligned, byteorder)
+        _names = parsed._names
+        descr = parsed._descr
+
+    # Determine shape from data-type.
+    if len(descr) != len(arrayList):
+        raise ValueError("mismatch between the number of fields "
+                "and the number of arrays")
+
+    d0 = descr[0].shape
+    nn = len(d0)
+    if nn > 0:
+        shape = shape[:-nn]
+
+    for k, obj in enumerate(arrayList):
+        nn = len(descr[k].shape)
+        testshape = obj.shape[:len(obj.shape) - nn]
+        if testshape != shape:
+            raise ValueError("array-shape mismatch in array %d" % k)
+
+    _array = recarray(shape, descr)
+
+    # populate the record array (makes a copy)
+    for i in range(len(arrayList)):
+        _array[_names[i]] = arrayList[i]
+
+    return _array
+
+# shape must be 1-d if you use list of lists...
+def fromrecords(recList, dtype=None, shape=None, formats=None, names=None,
+                titles=None, aligned=False, byteorder=None):
+    """ create a recarray from a list of records in text form
+
+        The data in the same field can be heterogeneous, they will be promoted
+        to the highest data type.  This method is intended for creating
+        smaller record arrays.  If used to create large array without formats
+        defined
+
+        r=fromrecords([(2,3.,'abc')]*100000)
+
+        it can be slow.
+
+        If formats is None, then this will auto-detect formats. Use list of
+        tuples rather than list of lists for faster processing.
+
+    >>> r=np.core.records.fromrecords([(456,'dbe',1.2),(2,'de',1.3)],
+    ... names='col1,col2,col3')
+    >>> print(r[0])
+    (456, 'dbe', 1.2)
+    >>> r.col1
+    array([456,   2])
+    >>> r.col2
+    array(['dbe', 'de'],
+          dtype='|S3')
+    >>> import pickle
+    >>> print(pickle.loads(pickle.dumps(r)))
+    [(456, 'dbe', 1.2) (2, 'de', 1.3)]
+    """
+
+    nfields = len(recList[0])
+    if formats is None and dtype is None:  # slower
+        obj = sb.array(recList, dtype=object)
+        arrlist = [sb.array(obj[..., i].tolist()) for i in range(nfields)]
+        return fromarrays(arrlist, formats=formats, shape=shape, names=names,
+                          titles=titles, aligned=aligned, byteorder=byteorder)
+
+    if dtype is not None:
+        descr = sb.dtype((record, dtype))
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    try:
+        retval = sb.array(recList, dtype=descr)
+    except TypeError:  # list of lists instead of list of tuples
+        if (shape is None or shape == 0):
+            shape = len(recList)
+        if isinstance(shape, (int, long)):
+            shape = (shape,)
+        if len(shape) > 1:
+            raise ValueError("Can only deal with 1-d array.")
+        _array = recarray(shape, descr)
+        for k in range(_array.size):
+            _array[k] = tuple(recList[k])
+        return _array
+    else:
+        if shape is not None and retval.shape != shape:
+            retval.shape = shape
+
+    res = retval.view(recarray)
+
+    return res
+
+
+def fromstring(datastring, dtype=None, shape=None, offset=0, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None):
+    """ create a (read-only) record array from binary data contained in
+    a string"""
+
+    if dtype is None and formats is None:
+        raise ValueError("Must have dtype= or formats=")
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    itemsize = descr.itemsize
+    if (shape is None or shape == 0 or shape == -1):
+        shape = (len(datastring) - offset) / itemsize
+
+    _array = recarray(shape, descr, buf=datastring, offset=offset)
+    return _array
+
+def get_remaining_size(fd):
+    try:
+        fn = fd.fileno()
+    except AttributeError:
+        return os.path.getsize(fd.name) - fd.tell()
+    st = os.fstat(fn)
+    size = st.st_size - fd.tell()
+    return size
+
+def fromfile(fd, dtype=None, shape=None, offset=0, formats=None,
+             names=None, titles=None, aligned=False, byteorder=None):
+    """Create an array from binary file data
+
+    If file is a string then that file is opened, else it is assumed
+    to be a file object.
+
+    >>> from tempfile import TemporaryFile
+    >>> a = np.empty(10,dtype='f8,i4,a5')
+    >>> a[5] = (0.5,10,'abcde')
+    >>>
+    >>> fd=TemporaryFile()
+    >>> a = a.newbyteorder('<')
+    >>> a.tofile(fd)
+    >>>
+    >>> fd.seek(0)
+    >>> r=np.core.records.fromfile(fd, formats='f8,i4,a5', shape=10,
+    ... byteorder='<')
+    >>> print(r[5])
+    (0.5, 10, 'abcde')
+    >>> r.shape
+    (10,)
+    """
+
+    if (shape is None or shape == 0):
+        shape = (-1,)
+    elif isinstance(shape, (int, long)):
+        shape = (shape,)
+
+    name = 0
+    if isinstance(fd, str):
+        name = 1
+        fd = open(fd, 'rb')
+    if (offset > 0):
+        fd.seek(offset, 1)
+    size = get_remaining_size(fd)
+
+    if dtype is not None:
+        descr = sb.dtype(dtype)
+    else:
+        descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+    itemsize = descr.itemsize
+
+    shapeprod = sb.array(shape).prod()
+    shapesize = shapeprod * itemsize
+    if shapesize < 0:
+        shape = list(shape)
+        shape[shape.index(-1)] = size / -shapesize
+        shape = tuple(shape)
+        shapeprod = sb.array(shape).prod()
+
+    nbytes = shapeprod * itemsize
+
+    if nbytes > size:
+        raise ValueError(
+                "Not enough bytes left in file for specified shape and type")
+
+    # create the array
+    _array = recarray(shape, descr)
+    nbytesread = fd.readinto(_array.data)
+    if nbytesread != nbytes:
+        raise IOError("Didn't read as many bytes as expected")
+    if name:
+        fd.close()
+
+    return _array
+
+def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
+          names=None, titles=None, aligned=False, byteorder=None, copy=True):
+    """Construct a record array from a wide-variety of objects.
+    """
+
+    if ((isinstance(obj, (type(None), str)) or isfileobj(obj)) and
+           (formats is None) and (dtype is None)):
+        raise ValueError("Must define formats (or dtype) if object is "
+                         "None, string, or an open file")
+
+    kwds = {}
+    if dtype is not None:
+        dtype = sb.dtype(dtype)
+    elif formats is not None:
+        dtype = format_parser(formats, names, titles,
+                              aligned, byteorder)._descr
+    else:
+        kwds = {'formats': formats,
+                'names': names,
+                'titles': titles,
+                'aligned': aligned,
+                'byteorder': byteorder
+                }
+
+    if obj is None:
+        if shape is None:
+            raise ValueError("Must define a shape if obj is None")
+        return recarray(shape, dtype, buf=obj, offset=offset, strides=strides)
+
+    elif isinstance(obj, bytes):
+        return fromstring(obj, dtype, shape=shape, offset=offset, **kwds)
+
+    elif isinstance(obj, (list, tuple)):
+        if isinstance(obj[0], (tuple, list)):
+            return fromrecords(obj, dtype=dtype, shape=shape, **kwds)
+        else:
+            return fromarrays(obj, dtype=dtype, shape=shape, **kwds)
+
+    elif isinstance(obj, recarray):
+        if dtype is not None and (obj.dtype != dtype):
+            new = obj.view(dtype)
+        else:
+            new = obj
+        if copy:
+            new = new.copy()
+        return new
+
+    elif isfileobj(obj):
+        return fromfile(obj, dtype=dtype, shape=shape, offset=offset)
+
+    elif isinstance(obj, ndarray):
+        if dtype is not None and (obj.dtype != dtype):
+            new = obj.view(dtype)
+        else:
+            new = obj
+        if copy:
+            new = new.copy()
+        return new.view(recarray)
+
+    else:
+        interface = getattr(obj, "__array_interface__", None)
+        if interface is None or not isinstance(interface, dict):
+            raise ValueError("Unknown input type")
+        obj = sb.array(obj)
+        if dtype is not None and (obj.dtype != dtype):
+            obj = obj.view(dtype)
+        return obj.view(recarray)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup.py
new file mode 100644
index 0000000000..3c3d1602e4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup.py
@@ -0,0 +1,964 @@
+from __future__ import division, print_function
+
+import imp
+import os
+import sys
+import pickle
+import copy
+import warnings
+from os.path import join
+from numpy.distutils import log
+from distutils.dep_util import newer
+from distutils.sysconfig import get_config_var
+from numpy._build_utils.apple_accelerate import (uses_accelerate_framework,
+                                                 get_sgemv_fix)
+
+from setup_common import *
+
+# Set to True to enable relaxed strides checking. This (mostly) means
+# that `strides[dim]` is ignored if `shape[dim] == 1` when setting flags.
+NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "0") != "0")
+
+# XXX: ugly, we use a class to avoid calling twice some expensive functions in
+# config.h/numpyconfig.h. I don't see a better way because distutils force
+# config.h generation inside an Extension class, and as such sharing
+# configuration informations between extensions is not easy.
+# Using a pickled-based memoize does not work because config_cmd is an instance
+# method, which cPickle does not like.
+#
+# Use pickle in all cases, as cPickle is gone in python3 and the difference
+# in time is only in build. -- Charles Harris, 2013-03-30
+
+class CallOnceOnly(object):
+    def __init__(self):
+        self._check_types = None
+        self._check_ieee_macros = None
+        self._check_complex = None
+
+    def check_types(self, *a, **kw):
+        if self._check_types is None:
+            out = check_types(*a, **kw)
+            self._check_types = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_types))
+        return out
+
+    def check_ieee_macros(self, *a, **kw):
+        if self._check_ieee_macros is None:
+            out = check_ieee_macros(*a, **kw)
+            self._check_ieee_macros = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_ieee_macros))
+        return out
+
+    def check_complex(self, *a, **kw):
+        if self._check_complex is None:
+            out = check_complex(*a, **kw)
+            self._check_complex = pickle.dumps(out)
+        else:
+            out = copy.deepcopy(pickle.loads(self._check_complex))
+        return out
+
+PYTHON_HAS_UNICODE_WIDE = True
+
+def pythonlib_dir():
+    """return path where libpython* is."""
+    if sys.platform == 'win32':
+        return os.path.join(sys.prefix, "libs")
+    else:
+        return get_config_var('LIBDIR')
+
+def is_npy_no_signal():
+    """Return True if the NPY_NO_SIGNAL symbol must be defined in configuration
+    header."""
+    return sys.platform == 'win32'
+
+def is_npy_no_smp():
+    """Return True if the NPY_NO_SMP symbol must be defined in public
+    header (when SMP support cannot be reliably enabled)."""
+    # Perhaps a fancier check is in order here.
+    #  so that threads are only enabled if there
+    #  are actually multiple CPUS? -- but
+    #  threaded code can be nice even on a single
+    #  CPU so that long-calculating code doesn't
+    #  block.
+    return 'NPY_NOSMP' in os.environ
+
+def win32_checks(deflist):
+    from numpy.distutils.misc_util import get_build_architecture
+    a = get_build_architecture()
+
+    # Distutils hack on AMD64 on windows
+    print('BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' %
+          (a, os.name, sys.platform))
+    if a == 'AMD64':
+        deflist.append('DISTUTILS_USE_SDK')
+
+    # On win32, force long double format string to be 'g', not
+    # 'Lg', since the MS runtime does not support long double whose
+    # size is > sizeof(double)
+    if a == "Intel" or a == "AMD64":
+        deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
+
+def check_math_capabilities(config, moredefs, mathlibs):
+    def check_func(func_name):
+        return config.check_func(func_name, libraries=mathlibs,
+                                 decl=True, call=True)
+
+    def check_funcs_once(funcs_name):
+        decl = dict([(f, True) for f in funcs_name])
+        st = config.check_funcs_once(funcs_name, libraries=mathlibs,
+                                     decl=decl, call=decl)
+        if st:
+            moredefs.extend([(fname2def(f), 1) for f in funcs_name])
+        return st
+
+    def check_funcs(funcs_name):
+        # Use check_funcs_once first, and if it does not work, test func per
+        # func. Return success only if all the functions are available
+        if not check_funcs_once(funcs_name):
+            # Global check failed, check func per func
+            for f in funcs_name:
+                if check_func(f):
+                    moredefs.append((fname2def(f), 1))
+            return 0
+        else:
+            return 1
+
+    #use_msvc = config.check_decl("_MSC_VER")
+
+    if not check_funcs_once(MANDATORY_FUNCS):
+        raise SystemError("One of the required function to build numpy is not"
+                " available (the list is %s)." % str(MANDATORY_FUNCS))
+
+    # Standard functions which may not be available and for which we have a
+    # replacement implementation. Note that some of these are C99 functions.
+
+    # XXX: hack to circumvent cpp pollution from python: python put its
+    # config.h in the public namespace, so we have a clash for the common
+    # functions we test. We remove every function tested by python's
+    # autoconf, hoping their own test are correct
+    for f in OPTIONAL_STDFUNCS_MAYBE:
+        if config.check_decl(fname2def(f),
+                    headers=["Python.h", "math.h"]):
+            OPTIONAL_STDFUNCS.remove(f)
+
+    check_funcs(OPTIONAL_STDFUNCS)
+
+    for h in OPTIONAL_HEADERS:
+        if config.check_func("", decl=False, call=False, headers=[h]):
+            moredefs.append((fname2def(h).replace(".", "_"), 1))
+
+    for tup in OPTIONAL_INTRINSICS:
+        headers = None
+        if len(tup) == 2:
+            f, args = tup
+        else:
+            f, args, headers = tup[0], tup[1], [tup[2]]
+        if config.check_func(f, decl=False, call=True, call_args=args,
+                             headers=headers):
+            moredefs.append((fname2def(f), 1))
+
+    for dec, fn in OPTIONAL_FUNCTION_ATTRIBUTES:
+        if config.check_gcc_function_attribute(dec, fn):
+            moredefs.append((fname2def(fn), 1))
+
+    for fn in OPTIONAL_VARIABLE_ATTRIBUTES:
+        if config.check_gcc_variable_attribute(fn):
+            m = fn.replace("(", "_").replace(")", "_")
+            moredefs.append((fname2def(m), 1))
+
+    # C99 functions: float and long double versions
+    check_funcs(C99_FUNCS_SINGLE)
+    check_funcs(C99_FUNCS_EXTENDED)
+
+def check_complex(config, mathlibs):
+    priv = []
+    pub = []
+
+    try:
+        if os.uname()[0] == "Interix":
+            warnings.warn("Disabling broken complex support. See #1365")
+            return priv, pub
+    except:
+        # os.uname not available on all platforms. blanket except ugly but safe
+        pass
+
+    # Check for complex support
+    st = config.check_header('complex.h')
+    if st:
+        priv.append(('HAVE_COMPLEX_H', 1))
+        pub.append(('NPY_USE_C99_COMPLEX', 1))
+
+        for t in C99_COMPLEX_TYPES:
+            st = config.check_type(t, headers=["complex.h"])
+            if st:
+                pub.append(('NPY_HAVE_%s' % type2def(t), 1))
+
+        def check_prec(prec):
+            flist = [f + prec for f in C99_COMPLEX_FUNCS]
+            decl = dict([(f, True) for f in flist])
+            if not config.check_funcs_once(flist, call=decl, decl=decl,
+                                           libraries=mathlibs):
+                for f in flist:
+                    if config.check_func(f, call=True, decl=True,
+                                         libraries=mathlibs):
+                        priv.append((fname2def(f), 1))
+            else:
+                priv.extend([(fname2def(f), 1) for f in flist])
+
+        check_prec('')
+        check_prec('f')
+        check_prec('l')
+
+    return priv, pub
+
+def check_ieee_macros(config):
+    priv = []
+    pub = []
+
+    macros = []
+
+    def _add_decl(f):
+        priv.append(fname2def("decl_%s" % f))
+        pub.append('NPY_%s' % fname2def("decl_%s" % f))
+
+    # XXX: hack to circumvent cpp pollution from python: python put its
+    # config.h in the public namespace, so we have a clash for the common
+    # functions we test. We remove every function tested by python's
+    # autoconf, hoping their own test are correct
+    _macros = ["isnan", "isinf", "signbit", "isfinite"]
+    for f in _macros:
+        py_symbol = fname2def("decl_%s" % f)
+        already_declared = config.check_decl(py_symbol,
+                headers=["Python.h", "math.h"])
+        if already_declared:
+            if config.check_macro_true(py_symbol,
+                    headers=["Python.h", "math.h"]):
+                pub.append('NPY_%s' % fname2def("decl_%s" % f))
+        else:
+            macros.append(f)
+    # Normally, isnan and isinf are macro (C99), but some platforms only have
+    # func, or both func and macro version. Check for macro only, and define
+    # replacement ones if not found.
+    # Note: including Python.h is necessary because it modifies some math.h
+    # definitions
+    for f in macros:
+        st = config.check_decl(f, headers=["Python.h", "math.h"])
+        if st:
+            _add_decl(f)
+
+    return priv, pub
+
+def check_types(config_cmd, ext, build_dir):
+    private_defines = []
+    public_defines = []
+
+    # Expected size (in number of bytes) for each type. This is an
+    # optimization: those are only hints, and an exhaustive search for the size
+    # is done if the hints are wrong.
+    expected = {'short': [2], 'int': [4], 'long': [8, 4],
+                'float': [4], 'double': [8], 'long double': [16, 12, 8],
+                'Py_intptr_t': [8, 4], 'PY_LONG_LONG': [8], 'long long': [8],
+                'off_t': [8, 4]}
+
+    # Check we have the python header (-dev* packages on Linux)
+    result = config_cmd.check_header('Python.h')
+    if not result:
+        raise SystemError(
+                "Cannot compile 'Python.h'. Perhaps you need to "
+                "install python-dev|python-devel.")
+    res = config_cmd.check_header("endian.h")
+    if res:
+        private_defines.append(('HAVE_ENDIAN_H', 1))
+        public_defines.append(('NPY_HAVE_ENDIAN_H', 1))
+
+    # Check basic types sizes
+    for type in ('short', 'int', 'long'):
+        res = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), headers=["Python.h"])
+        if res:
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), "SIZEOF_%s" % sym2def(type)))
+        else:
+            res = config_cmd.check_type_size(type, expected=expected[type])
+            if res >= 0:
+                public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+            else:
+                raise SystemError("Checking sizeof (%s) failed !" % type)
+
+    for type in ('float', 'double', 'long double'):
+        already_declared = config_cmd.check_decl("SIZEOF_%s" % sym2def(type),
+                                                 headers=["Python.h"])
+        res = config_cmd.check_type_size(type, expected=expected[type])
+        if res >= 0:
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+            if not already_declared and not type == 'long double':
+                private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % type)
+
+        # Compute size of corresponding complex type: used to check that our
+        # definition is binary compatible with C99 complex type (check done at
+        # build time in npy_common.h)
+        complex_def = "struct {%s __x; %s __y;}" % (type, type)
+        res = config_cmd.check_type_size(complex_def,
+                                         expected=[2 * x for x in expected[type]])
+        if res >= 0:
+            public_defines.append(('NPY_SIZEOF_COMPLEX_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % complex_def)
+
+    for type in ('Py_intptr_t', 'off_t'):
+        res = config_cmd.check_type_size(type, headers=["Python.h"],
+                library_dirs=[pythonlib_dir()],
+                expected=expected[type])
+
+        if res >= 0:
+            private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % type)
+
+    # We check declaration AND type because that's how distutils does it.
+    if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']):
+        res = config_cmd.check_type_size('PY_LONG_LONG',  headers=['Python.h'],
+                library_dirs=[pythonlib_dir()],
+                expected=expected['PY_LONG_LONG'])
+        if res >= 0:
+            private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % 'PY_LONG_LONG')
+
+        res = config_cmd.check_type_size('long long',
+                expected=expected['long long'])
+        if res >= 0:
+            #private_defines.append(('SIZEOF_%s' % sym2def('long long'), '%d' % res))
+            public_defines.append(('NPY_SIZEOF_%s' % sym2def('long long'), '%d' % res))
+        else:
+            raise SystemError("Checking sizeof (%s) failed !" % 'long long')
+
+    if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']):
+        raise RuntimeError(
+            "Config wo CHAR_BIT is not supported"
+            ", please contact the maintainers")
+
+    return private_defines, public_defines
+
+def check_mathlib(config_cmd):
+    # Testing the C math library
+    mathlibs = []
+    mathlibs_choices = [[], ['m'], ['cpml']]
+    mathlib = os.environ.get('MATHLIB')
+    if mathlib:
+        mathlibs_choices.insert(0, mathlib.split(','))
+    for libs in mathlibs_choices:
+        if config_cmd.check_func("exp", libraries=libs, decl=True, call=True):
+            mathlibs = libs
+            break
+    else:
+        raise EnvironmentError("math library missing; rerun "
+                               "setup.py after setting the "
+                               "MATHLIB env variable")
+    return mathlibs
+
+def visibility_define(config):
+    """Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty
+    string)."""
+    if config.check_compiler_gcc4():
+        return '__attribute__((visibility("hidden")))'
+    else:
+        return ''
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration, dot_join
+    from numpy.distutils.system_info import get_info
+
+    config = Configuration('core', parent_package, top_path)
+    local_dir = config.local_path
+    codegen_dir = join(local_dir, 'code_generators')
+
+    if is_released(config):
+        warnings.simplefilter('error', MismatchCAPIWarning)
+
+    # Check whether we have a mismatch between the set C API VERSION and the
+    # actual C API VERSION
+    check_api_version(C_API_VERSION, codegen_dir)
+
+    generate_umath_py = join(codegen_dir, 'generate_umath.py')
+    n = dot_join(config.name, 'generate_umath')
+    generate_umath = imp.load_module('_'.join(n.split('.')),
+                                     open(generate_umath_py, 'U'), generate_umath_py,
+                                     ('.py', 'U', 1))
+
+    header_dir = 'include/numpy'  # this is relative to config.path_in_package
+
+    cocache = CallOnceOnly()
+
+    def generate_config_h(ext, build_dir):
+        target = join(build_dir, header_dir, 'config.h')
+        d = os.path.dirname(target)
+        if not os.path.exists(d):
+            os.makedirs(d)
+
+        if newer(__file__, target):
+            config_cmd = config.get_config_cmd()
+            log.info('Generating %s', target)
+
+            # Check sizeof
+            moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir)
+
+            # Check math library and C99 math funcs availability
+            mathlibs = check_mathlib(config_cmd)
+            moredefs.append(('MATHLIB', ','.join(mathlibs)))
+
+            check_math_capabilities(config_cmd, moredefs, mathlibs)
+            moredefs.extend(cocache.check_ieee_macros(config_cmd)[0])
+            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0])
+
+            # Signal check
+            if is_npy_no_signal():
+                moredefs.append('__NPY_PRIVATE_NO_SIGNAL')
+
+            # Windows checks
+            if sys.platform == 'win32' or os.name == 'nt':
+                win32_checks(moredefs)
+
+            # C99 restrict keyword
+            moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict()))
+
+            # Inline check
+            inline = config_cmd.check_inline()
+
+            # Check whether we need our own wide character support
+            if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']):
+                PYTHON_HAS_UNICODE_WIDE = True
+            else:
+                PYTHON_HAS_UNICODE_WIDE = False
+
+            if NPY_RELAXED_STRIDES_CHECKING:
+                moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
+
+            # Get long double representation
+            if sys.platform != 'darwin':
+                rep = check_long_double_representation(config_cmd)
+                if rep in ['INTEL_EXTENDED_12_BYTES_LE',
+                           'INTEL_EXTENDED_16_BYTES_LE',
+                           'MOTOROLA_EXTENDED_12_BYTES_BE',
+                           'IEEE_QUAD_LE', 'IEEE_QUAD_BE',
+                           'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE',
+                           'DOUBLE_DOUBLE_BE', 'DOUBLE_DOUBLE_LE']:
+                    moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1))
+                else:
+                    raise ValueError("Unrecognized long double format: %s" % rep)
+
+            # Py3K check
+            if sys.version_info[0] == 3:
+                moredefs.append(('NPY_PY3K', 1))
+
+            # Generate the config.h file from moredefs
+            target_f = open(target, 'w')
+            for d in moredefs:
+                if isinstance(d, str):
+                    target_f.write('#define %s\n' % (d))
+                else:
+                    target_f.write('#define %s %s\n' % (d[0], d[1]))
+
+            # define inline to our keyword, or nothing
+            target_f.write('#ifndef __cplusplus\n')
+            if inline == 'inline':
+                target_f.write('/* #undef inline */\n')
+            else:
+                target_f.write('#define inline %s\n' % inline)
+            target_f.write('#endif\n')
+
+            # add the guard to make sure config.h is never included directly,
+            # but always through npy_config.h
+            target_f.write("""
+#ifndef _NPY_NPY_CONFIG_H_
+#error config.h should never be included directly, include npy_config.h instead
+#endif
+""")
+
+            target_f.close()
+            print('File:', target)
+            target_f = open(target)
+            print(target_f.read())
+            target_f.close()
+            print('EOF')
+        else:
+            mathlibs = []
+            target_f = open(target)
+            for line in target_f:
+                s = '#define MATHLIB'
+                if line.startswith(s):
+                    value = line[len(s):].strip()
+                    if value:
+                        mathlibs.extend(value.split(','))
+            target_f.close()
+
+        # Ugly: this can be called within a library and not an extension,
+        # in which case there is no libraries attributes (and none is
+        # needed).
+        if hasattr(ext, 'libraries'):
+            ext.libraries.extend(mathlibs)
+
+        incl_dir = os.path.dirname(target)
+        if incl_dir not in config.numpy_include_dirs:
+            config.numpy_include_dirs.append(incl_dir)
+
+        return target
+
+    def generate_numpyconfig_h(ext, build_dir):
+        """Depends on config.h: generate_config_h has to be called before !"""
+        # put private include directory in build_dir on search path
+        # allows using code generation in headers headers
+        config.add_include_dirs(join(build_dir, "src", "private"))
+
+        target = join(build_dir, header_dir, '_numpyconfig.h')
+        d = os.path.dirname(target)
+        if not os.path.exists(d):
+            os.makedirs(d)
+        if newer(__file__, target):
+            config_cmd = config.get_config_cmd()
+            log.info('Generating %s', target)
+
+            # Check sizeof
+            ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir)
+
+            if is_npy_no_signal():
+                moredefs.append(('NPY_NO_SIGNAL', 1))
+
+            if is_npy_no_smp():
+                moredefs.append(('NPY_NO_SMP', 1))
+            else:
+                moredefs.append(('NPY_NO_SMP', 0))
+
+            mathlibs = check_mathlib(config_cmd)
+            moredefs.extend(cocache.check_ieee_macros(config_cmd)[1])
+            moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1])
+
+            if NPY_RELAXED_STRIDES_CHECKING:
+                moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
+
+            # Check wether we can use inttypes (C99) formats
+            if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']):
+                moredefs.append(('NPY_USE_C99_FORMATS', 1))
+
+            # visibility check
+            hidden_visibility = visibility_define(config_cmd)
+            moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility))
+
+            # Add the C API/ABI versions
+            moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION))
+            moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION))
+
+            # Add moredefs to header
+            target_f = open(target, 'w')
+            for d in moredefs:
+                if isinstance(d, str):
+                    target_f.write('#define %s\n' % (d))
+                else:
+                    target_f.write('#define %s %s\n' % (d[0], d[1]))
+
+            # Define __STDC_FORMAT_MACROS
+            target_f.write("""
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
+#endif
+""")
+            target_f.close()
+
+            # Dump the numpyconfig.h header to stdout
+            print('File: %s' % target)
+            target_f = open(target)
+            print(target_f.read())
+            target_f.close()
+            print('EOF')
+        config.add_data_files((header_dir, target))
+        return target
+
+    def generate_api_func(module_name):
+        def generate_api(ext, build_dir):
+            script = join(codegen_dir, module_name + '.py')
+            sys.path.insert(0, codegen_dir)
+            try:
+                m = __import__(module_name)
+                log.info('executing %s', script)
+                h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir))
+            finally:
+                del sys.path[0]
+            config.add_data_files((header_dir, h_file),
+                                  (header_dir, doc_file))
+            return (h_file,)
+        return generate_api
+
+    generate_numpy_api = generate_api_func('generate_numpy_api')
+    generate_ufunc_api = generate_api_func('generate_ufunc_api')
+
+    config.add_include_dirs(join(local_dir, "src", "private"))
+    config.add_include_dirs(join(local_dir, "src"))
+    config.add_include_dirs(join(local_dir))
+
+    config.add_data_files('include/numpy/*.h')
+    config.add_include_dirs(join('src', 'npymath'))
+    config.add_include_dirs(join('src', 'multiarray'))
+    config.add_include_dirs(join('src', 'umath'))
+    config.add_include_dirs(join('src', 'npysort'))
+
+    config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")])
+    config.add_define_macros([("_FILE_OFFSET_BITS", "64")])
+    config.add_define_macros([('_LARGEFILE_SOURCE', '1')])
+    config.add_define_macros([('_LARGEFILE64_SOURCE', '1')])
+
+    config.numpy_include_dirs.extend(config.paths('include'))
+
+    deps = [join('src', 'npymath', '_signbit.c'),
+            join('include', 'numpy', '*object.h'),
+            join(codegen_dir, 'genapi.py'),
+            ]
+
+    #######################################################################
+    #                            dummy module                             #
+    #######################################################################
+
+    # npymath needs the config.h and numpyconfig.h files to be generated, but
+    # build_clib cannot handle generate_config_h and generate_numpyconfig_h
+    # (don't ask). Because clib are generated before extensions, we have to
+    # explicitly add an extension which has generate_config_h and
+    # generate_numpyconfig_h as sources *before* adding npymath.
+
+    config.add_extension('_dummy',
+                         sources=[join('src', 'dummymodule.c'),
+                                  generate_config_h,
+                                  generate_numpyconfig_h,
+                                  generate_numpy_api]
+                         )
+
+    #######################################################################
+    #                          npymath library                            #
+    #######################################################################
+
+    subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")])
+
+    def get_mathlib_info(*args):
+        # Another ugly hack: the mathlib info is known once build_src is run,
+        # but we cannot use add_installed_pkg_config here either, so we only
+        # update the substition dictionary during npymath build
+        config_cmd = config.get_config_cmd()
+
+        # Check that the toolchain works, to fail early if it doesn't
+        # (avoid late errors with MATHLIB which are confusing if the
+        # compiler does not work).
+        st = config_cmd.try_link('int main(void) { return 0;}')
+        if not st:
+            raise RuntimeError("Broken toolchain: cannot link a simple C program")
+        mlibs = check_mathlib(config_cmd)
+
+        posix_mlib = ' '.join(['-l%s' % l for l in mlibs])
+        msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs])
+        subst_dict["posix_mathlib"] = posix_mlib
+        subst_dict["msvc_mathlib"] = msvc_mlib
+
+    npymath_sources = [join('src', 'npymath', 'npy_math.c.src'),
+                       join('src', 'npymath', 'ieee754.c.src'),
+                       join('src', 'npymath', 'npy_math_complex.c.src'),
+                       join('src', 'npymath', 'halffloat.c')
+                       ]
+    config.add_installed_library('npymath',
+            sources=npymath_sources + [get_mathlib_info],
+            install_dir='lib')
+    config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config",
+            subst_dict)
+    config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config",
+            subst_dict)
+
+    #######################################################################
+    #                         npysort library                             #
+    #######################################################################
+
+    # This library is created for the build but it is not installed
+    npysort_sources = [join('src', 'npysort', 'quicksort.c.src'),
+                       join('src', 'npysort', 'mergesort.c.src'),
+                       join('src', 'npysort', 'heapsort.c.src'),
+                       join('src', 'private', 'npy_partition.h.src'),
+                       join('src', 'npysort', 'selection.c.src'),
+                       join('src', 'private', 'npy_binsearch.h.src'),
+                       join('src', 'npysort', 'binsearch.c.src'),
+                       ]
+    config.add_library('npysort',
+                       sources=npysort_sources,
+                       include_dirs=[])
+
+    #######################################################################
+    #                        multiarray module                            #
+    #######################################################################
+
+    # Multiarray version: this function is needed to build foo.c from foo.c.src
+    # when foo.c is included in another file and as such not in the src
+    # argument of build_ext command
+    def generate_multiarray_templated_sources(ext, build_dir):
+        from numpy.distutils.misc_util import get_cmd
+
+        subpath = join('src', 'multiarray')
+        sources = [join(local_dir, subpath, 'scalartypes.c.src'),
+                   join(local_dir, subpath, 'arraytypes.c.src'),
+                   join(local_dir, subpath, 'nditer_templ.c.src'),
+                   join(local_dir, subpath, 'lowlevel_strided_loops.c.src'),
+                   join(local_dir, subpath, 'einsum.c.src'),
+                   join(local_dir, 'src', 'private', 'templ_common.h.src')
+                   ]
+
+        # numpy.distutils generate .c from .c.src in weird directories, we have
+        # to add them there as they depend on the build_dir
+        config.add_include_dirs(join(build_dir, subpath))
+        cmd = get_cmd('build_src')
+        cmd.ensure_finalized()
+        cmd.template_sources(sources, ext)
+
+    multiarray_deps = [
+            join('src', 'multiarray', 'arrayobject.h'),
+            join('src', 'multiarray', 'arraytypes.h'),
+            join('src', 'multiarray', 'array_assign.h'),
+            join('src', 'multiarray', 'buffer.h'),
+            join('src', 'multiarray', 'calculation.h'),
+            join('src', 'multiarray', 'cblasfuncs.h'),
+            join('src', 'multiarray', 'common.h'),
+            join('src', 'multiarray', 'convert_datatype.h'),
+            join('src', 'multiarray', 'convert.h'),
+            join('src', 'multiarray', 'conversion_utils.h'),
+            join('src', 'multiarray', 'ctors.h'),
+            join('src', 'multiarray', 'descriptor.h'),
+            join('src', 'multiarray', 'getset.h'),
+            join('src', 'multiarray', 'hashdescr.h'),
+            join('src', 'multiarray', 'iterators.h'),
+            join('src', 'multiarray', 'mapping.h'),
+            join('src', 'multiarray', 'methods.h'),
+            join('src', 'multiarray', 'multiarraymodule.h'),
+            join('src', 'multiarray', 'nditer_impl.h'),
+            join('src', 'multiarray', 'numpymemoryview.h'),
+            join('src', 'multiarray', 'number.h'),
+            join('src', 'multiarray', 'numpyos.h'),
+            join('src', 'multiarray', 'refcount.h'),
+            join('src', 'multiarray', 'scalartypes.h'),
+            join('src', 'multiarray', 'sequence.h'),
+            join('src', 'multiarray', 'shape.h'),
+            join('src', 'multiarray', 'ucsnarrow.h'),
+            join('src', 'multiarray', 'usertypes.h'),
+            join('src', 'multiarray', 'vdot.h'),
+            join('src', 'private', 'npy_config.h'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'private', 'lowlevel_strided_loops.h'),
+            join('src', 'private', 'mem_overlap.h'),
+            join('src', 'private', 'npy_extint128.h'),
+            join('include', 'numpy', 'arrayobject.h'),
+            join('include', 'numpy', '_neighborhood_iterator_imp.h'),
+            join('include', 'numpy', 'npy_endian.h'),
+            join('include', 'numpy', 'arrayscalars.h'),
+            join('include', 'numpy', 'noprefix.h'),
+            join('include', 'numpy', 'npy_interrupt.h'),
+            join('include', 'numpy', 'npy_3kcompat.h'),
+            join('include', 'numpy', 'npy_math.h'),
+            join('include', 'numpy', 'halffloat.h'),
+            join('include', 'numpy', 'npy_common.h'),
+            join('include', 'numpy', 'npy_os.h'),
+            join('include', 'numpy', 'utils.h'),
+            join('include', 'numpy', 'ndarrayobject.h'),
+            join('include', 'numpy', 'npy_cpu.h'),
+            join('include', 'numpy', 'numpyconfig.h'),
+            join('include', 'numpy', 'ndarraytypes.h'),
+            join('include', 'numpy', 'npy_1_7_deprecated_api.h'),
+            join('include', 'numpy', '_numpyconfig.h.in'),
+            # add library sources as distuils does not consider libraries
+            # dependencies
+            ] + npysort_sources + npymath_sources
+
+    multiarray_src = [
+            join('src', 'multiarray', 'alloc.c'),
+            join('src', 'multiarray', 'arrayobject.c'),
+            join('src', 'multiarray', 'arraytypes.c.src'),
+            join('src', 'multiarray', 'array_assign.c'),
+            join('src', 'multiarray', 'array_assign_scalar.c'),
+            join('src', 'multiarray', 'array_assign_array.c'),
+            join('src', 'multiarray', 'buffer.c'),
+            join('src', 'multiarray', 'calculation.c'),
+            join('src', 'multiarray', 'compiled_base.c'),
+            join('src', 'multiarray', 'common.c'),
+            join('src', 'multiarray', 'convert.c'),
+            join('src', 'multiarray', 'convert_datatype.c'),
+            join('src', 'multiarray', 'conversion_utils.c'),
+            join('src', 'multiarray', 'ctors.c'),
+            join('src', 'multiarray', 'datetime.c'),
+            join('src', 'multiarray', 'datetime_strings.c'),
+            join('src', 'multiarray', 'datetime_busday.c'),
+            join('src', 'multiarray', 'datetime_busdaycal.c'),
+            join('src', 'multiarray', 'descriptor.c'),
+            join('src', 'multiarray', 'dtype_transfer.c'),
+            join('src', 'multiarray', 'einsum.c.src'),
+            join('src', 'multiarray', 'flagsobject.c'),
+            join('src', 'multiarray', 'getset.c'),
+            join('src', 'multiarray', 'hashdescr.c'),
+            join('src', 'multiarray', 'item_selection.c'),
+            join('src', 'multiarray', 'iterators.c'),
+            join('src', 'multiarray', 'lowlevel_strided_loops.c.src'),
+            join('src', 'multiarray', 'mapping.c'),
+            join('src', 'multiarray', 'methods.c'),
+            join('src', 'multiarray', 'multiarraymodule.c'),
+            join('src', 'multiarray', 'nditer_templ.c.src'),
+            join('src', 'multiarray', 'nditer_api.c'),
+            join('src', 'multiarray', 'nditer_constr.c'),
+            join('src', 'multiarray', 'nditer_pywrap.c'),
+            join('src', 'multiarray', 'number.c'),
+            join('src', 'multiarray', 'numpymemoryview.c'),
+            join('src', 'multiarray', 'numpyos.c'),
+            join('src', 'multiarray', 'refcount.c'),
+            join('src', 'multiarray', 'sequence.c'),
+            join('src', 'multiarray', 'shape.c'),
+            join('src', 'multiarray', 'scalarapi.c'),
+            join('src', 'multiarray', 'scalartypes.c.src'),
+            join('src', 'multiarray', 'usertypes.c'),
+            join('src', 'multiarray', 'ucsnarrow.c'),
+            join('src', 'multiarray', 'vdot.c'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'private', 'mem_overlap.c'),
+            ]
+
+    blas_info = get_info('blas_opt', 0)
+    if blas_info and ('HAVE_CBLAS', None) in blas_info.get('define_macros', []):
+        extra_info = blas_info
+        # These files are also in MANIFEST.in so that they are always in
+        # the source distribution independently of HAVE_CBLAS.
+        multiarray_src.extend([join('src', 'multiarray', 'cblasfuncs.c'),
+                               join('src', 'multiarray', 'python_xerbla.c'),
+                               ])
+        if uses_accelerate_framework(blas_info):
+            multiarray_src.extend(get_sgemv_fix())
+    else:
+        extra_info = {}
+
+    config.add_extension('multiarray',
+                         sources=multiarray_src +
+                                 [generate_config_h,
+                                  generate_numpyconfig_h,
+                                  generate_numpy_api,
+                                  join(codegen_dir, 'generate_numpy_api.py'),
+                                  join('*.py')],
+                         depends=deps + multiarray_deps,
+                         libraries=['npymath', 'npysort'],
+                         extra_info=extra_info)
+
+    #######################################################################
+    #                           umath module                              #
+    #######################################################################
+
+    # umath version: this function is needed to build foo.c from foo.c.src
+    # when foo.c is included in another file and as such not in the src
+    # argument of build_ext command
+    def generate_umath_templated_sources(ext, build_dir):
+        from numpy.distutils.misc_util import get_cmd
+
+        subpath = join('src', 'umath')
+        sources = [
+            join(local_dir, subpath, 'loops.h.src'),
+            join(local_dir, subpath, 'loops.c.src'),
+            join(local_dir, subpath, 'scalarmath.c.src'),
+            join(local_dir, subpath, 'simd.inc.src')]
+
+        # numpy.distutils generate .c from .c.src in weird directories, we have
+        # to add them there as they depend on the build_dir
+        config.add_include_dirs(join(build_dir, subpath))
+        cmd = get_cmd('build_src')
+        cmd.ensure_finalized()
+        cmd.template_sources(sources, ext)
+
+    def generate_umath_c(ext, build_dir):
+        target = join(build_dir, header_dir, '__umath_generated.c')
+        dir = os.path.dirname(target)
+        if not os.path.exists(dir):
+            os.makedirs(dir)
+        script = generate_umath_py
+        if newer(script, target):
+            f = open(target, 'w')
+            f.write(generate_umath.make_code(generate_umath.defdict,
+                                             generate_umath.__file__))
+            f.close()
+        return []
+
+    umath_src = [
+            join('src', 'umath', 'umathmodule.c'),
+            join('src', 'umath', 'reduction.c'),
+            join('src', 'umath', 'funcs.inc.src'),
+            join('src', 'umath', 'simd.inc.src'),
+            join('src', 'umath', 'loops.h.src'),
+            join('src', 'umath', 'loops.c.src'),
+            join('src', 'umath', 'ufunc_object.c'),
+            join('src', 'umath', 'scalarmath.c.src'),
+            join('src', 'umath', 'ufunc_type_resolution.c')]
+
+    umath_deps = [
+            generate_umath_py,
+            join('include', 'numpy', 'npy_math.h'),
+            join('include', 'numpy', 'halffloat.h'),
+            join('src', 'multiarray', 'common.h'),
+            join('src', 'private', 'templ_common.h.src'),
+            join('src', 'umath', 'simd.inc.src'),
+            join(codegen_dir, 'generate_ufunc_api.py'),
+            join('src', 'private', 'ufunc_override.h')] + npymath_sources
+
+    config.add_extension('umath',
+                         sources=umath_src +
+                                 [generate_config_h,
+                                 generate_numpyconfig_h,
+                                 generate_umath_c,
+                                 generate_ufunc_api],
+                         depends=deps + umath_deps,
+                         libraries=['npymath'],
+                         )
+
+    #######################################################################
+    #                        umath_tests module                           #
+    #######################################################################
+
+    config.add_extension('umath_tests',
+                    sources=[join('src', 'umath', 'umath_tests.c.src')])
+
+    #######################################################################
+    #                   custom rational dtype module                      #
+    #######################################################################
+
+    config.add_extension('test_rational',
+                    sources=[join('src', 'umath', 'test_rational.c.src')])
+
+    #######################################################################
+    #                        struct_ufunc_test module                     #
+    #######################################################################
+
+    config.add_extension('struct_ufunc_test',
+                    sources=[join('src', 'umath', 'struct_ufunc_test.c.src')])
+
+    #######################################################################
+    #                     multiarray_tests module                         #
+    #######################################################################
+
+    config.add_extension('multiarray_tests',
+                    sources=[join('src', 'multiarray', 'multiarray_tests.c.src'),
+                             join('src', 'private', 'mem_overlap.c')],
+                    depends=[join('src', 'private', 'mem_overlap.h'),
+                             join('src', 'private', 'npy_extint128.h')])
+
+    #######################################################################
+    #                        operand_flag_tests module                    #
+    #######################################################################
+
+    config.add_extension('operand_flag_tests',
+                    sources=[join('src', 'umath', 'operand_flag_tests.c.src')])
+
+    config.add_data_dir('tests')
+    config.add_data_dir('tests/data')
+
+    config.make_svn_version_py()
+
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup_common.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup_common.py
new file mode 100644
index 0000000000..ba7521e304
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/setup_common.py
@@ -0,0 +1,356 @@
+from __future__ import division, absolute_import, print_function
+
+# Code common to build tools
+import sys
+import warnings
+import copy
+import binascii
+
+from numpy.distutils.misc_util import mingw32
+
+
+#-------------------
+# Versioning support
+#-------------------
+# How to change C_API_VERSION ?
+#   - increase C_API_VERSION value
+#   - record the hash for the new C API with the script cversions.py
+#   and add the hash to cversions.txt
+# The hash values are used to remind developers when the C API number was not
+# updated - generates a MismatchCAPIWarning warning which is turned into an
+# exception for released version.
+
+# Binary compatibility version number. This number is increased whenever the
+# C-API is changed such that binary compatibility is broken, i.e. whenever a
+# recompile of extension modules is needed.
+C_ABI_VERSION = 0x01000009
+
+# Minor API version.  This number is increased whenever a change is made to the
+# C-API -- whether it breaks binary compatibility or not.  Some changes, such
+# as adding a function pointer to the end of the function table, can be made
+# without breaking binary compatibility.  In this case, only the C_API_VERSION
+# (*not* C_ABI_VERSION) would be increased.  Whenever binary compatibility is
+# broken, both C_API_VERSION and C_ABI_VERSION should be increased.
+#
+# 0x00000008 - 1.7.x
+# 0x00000009 - 1.8.x
+# 0x00000009 - 1.9.x
+# 0x0000000a - 1.10.x
+# 0x0000000a - 1.11.x
+C_API_VERSION = 0x0000000a
+
+class MismatchCAPIWarning(Warning):
+    pass
+
+def is_released(config):
+    """Return True if a released version of numpy is detected."""
+    from distutils.version import LooseVersion
+
+    v = config.get_version('../version.py')
+    if v is None:
+        raise ValueError("Could not get version")
+    pv = LooseVersion(vstring=v).version
+    if len(pv) > 3:
+        return False
+    return True
+
+def get_api_versions(apiversion, codegen_dir):
+    """
+    Return current C API checksum and the recorded checksum.
+
+    Return current C API checksum and the recorded checksum for the given
+    version of the C API version.
+
+    """
+    # Compute the hash of the current API as defined in the .txt files in
+    # code_generators
+    sys.path.insert(0, codegen_dir)
+    try:
+        m = __import__('genapi')
+        numpy_api = __import__('numpy_api')
+        curapi_hash = m.fullapi_hash(numpy_api.full_api)
+        apis_hash = m.get_versions_hash()
+    finally:
+        del sys.path[0]
+
+    return curapi_hash, apis_hash[apiversion]
+
+def check_api_version(apiversion, codegen_dir):
+    """Emits a MismacthCAPIWarning if the C API version needs updating."""
+    curapi_hash, api_hash = get_api_versions(apiversion, codegen_dir)
+
+    # If different hash, it means that the api .txt files in
+    # codegen_dir have been updated without the API version being
+    # updated. Any modification in those .txt files should be reflected
+    # in the api and eventually abi versions.
+    # To compute the checksum of the current API, use
+    # code_generators/cversions.py script
+    if not curapi_hash == api_hash:
+        msg = ("API mismatch detected, the C API version "
+               "numbers have to be updated. Current C api version is %d, "
+               "with checksum %s, but recorded checksum for C API version %d in "
+               "codegen_dir/cversions.txt is %s. If functions were added in the "
+               "C API, you have to update C_API_VERSION  in %s."
+               )
+        warnings.warn(msg % (apiversion, curapi_hash, apiversion, api_hash,
+                             __file__),
+                      MismatchCAPIWarning)
+# Mandatory functions: if not found, fail the build
+MANDATORY_FUNCS = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
+        "floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
+        "acos", "atan", "fmod", 'modf', 'frexp', 'ldexp']
+
+# Standard functions which may not be available and for which we have a
+# replacement implementation. Note that some of these are C99 functions.
+OPTIONAL_STDFUNCS = ["expm1", "log1p", "acosh", "asinh", "atanh",
+        "rint", "trunc", "exp2", "log2", "hypot", "atan2", "pow",
+        "copysign", "nextafter", "ftello", "fseeko",
+        "strtoll", "strtoull", "cbrt", "strtold_l", "fallocate"]
+
+
+OPTIONAL_HEADERS = [
+# sse headers only enabled automatically on amd64/x32 builds
+                "xmmintrin.h",  # SSE
+                "emmintrin.h",  # SSE2
+                "features.h",  # for glibc version linux
+]
+
+# optional gcc compiler builtins and their call arguments and optional a
+# required header
+# call arguments are required as the compiler will do strict signature checking
+OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
+                       ("__builtin_isinf", '5.'),
+                       ("__builtin_isfinite", '5.'),
+                       ("__builtin_bswap32", '5u'),
+                       ("__builtin_bswap64", '5u'),
+                       ("__builtin_expect", '5, 0'),
+                       ("__builtin_mul_overflow", '5, 5, (int*)5'),
+                       ("_mm_load_ps", '(float*)0', "xmmintrin.h"),  # SSE
+                       ("_mm_prefetch", '(float*)0, _MM_HINT_NTA',
+                        "xmmintrin.h"),  # SSE
+                       ("_mm_load_pd", '(double*)0', "emmintrin.h"),  # SSE2
+                       ("__builtin_prefetch", "(float*)0, 0, 3"),
+                       ]
+
+# function attributes
+# tested via "int %s %s(void *);" % (attribute, name)
+# function name will be converted to HAVE_<upper-case-name> preprocessor macro
+OPTIONAL_FUNCTION_ATTRIBUTES = [('__attribute__((optimize("unroll-loops")))',
+                                'attribute_optimize_unroll_loops'),
+                                ('__attribute__((optimize("O3")))',
+                                 'attribute_optimize_opt_3'),
+                                ('__attribute__((nonnull (1)))',
+                                 'attribute_nonnull'),
+                                ]
+
+# variable attributes tested via "int %s a" % attribute
+OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"]
+
+# Subset of OPTIONAL_STDFUNCS which may alreay have HAVE_* defined by Python.h
+OPTIONAL_STDFUNCS_MAYBE = [
+    "expm1", "log1p", "acosh", "atanh", "asinh", "hypot", "copysign",
+    "ftello", "fseeko"
+    ]
+
+# C99 functions: float and long double versions
+C99_FUNCS = [
+    "sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor", "ceil",
+    "rint", "trunc", "sqrt", "log10", "log", "log1p", "exp", "expm1",
+    "asin", "acos", "atan", "asinh", "acosh", "atanh", "hypot", "atan2",
+    "pow", "fmod", "modf", 'frexp', 'ldexp', "exp2", "log2", "copysign",
+    "nextafter", "cbrt"
+    ]
+C99_FUNCS_SINGLE = [f + 'f' for f in C99_FUNCS]
+C99_FUNCS_EXTENDED = [f + 'l' for f in C99_FUNCS]
+C99_COMPLEX_TYPES = [
+    'complex double', 'complex float', 'complex long double'
+    ]
+C99_COMPLEX_FUNCS = [
+    "cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
+    "catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
+    "cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
+    ]
+
+def fname2def(name):
+    return "HAVE_%s" % name.upper()
+
+def sym2def(symbol):
+    define = symbol.replace(' ', '')
+    return define.upper()
+
+def type2def(symbol):
+    define = symbol.replace(' ', '_')
+    return define.upper()
+
+# Code to detect long double representation taken from MPFR m4 macro
+def check_long_double_representation(cmd):
+    cmd._check_compiler()
+    body = LONG_DOUBLE_REPRESENTATION_SRC % {'type': 'long double'}
+
+    # Disable whole program optimization (the default on vs2015, with python 3.5+)
+    # which generates intermediary object files and prevents checking the
+    # float representation.
+    if sys.platform == "win32" and not mingw32():
+        try:
+            cmd.compiler.compile_options.remove("/GL")
+        except (AttributeError, ValueError):
+            pass
+
+    # We need to use _compile because we need the object filename
+    src, obj = cmd._compile(body, None, None, 'c')
+    try:
+        ltype = long_double_representation(pyod(obj))
+        return ltype
+    except ValueError:
+        # try linking to support CC="gcc -flto" or icc -ipo
+        # struct needs to be volatile so it isn't optimized away
+        body = body.replace('struct', 'volatile struct')
+        body += "int main(void) { return 0; }\n"
+        src, obj = cmd._compile(body, None, None, 'c')
+        cmd.temp_files.append("_configtest")
+        cmd.compiler.link_executable([obj], "_configtest")
+        ltype = long_double_representation(pyod("_configtest"))
+        return ltype
+    finally:
+        cmd._clean()
+
+LONG_DOUBLE_REPRESENTATION_SRC = r"""
+/* "before" is 16 bytes to ensure there's no padding between it and "x".
+ *    We're not expecting any "long double" bigger than 16 bytes or with
+ *       alignment requirements stricter than 16 bytes.  */
+typedef %(type)s test_type;
+
+struct {
+        char         before[16];
+        test_type    x;
+        char         after[8];
+} foo = {
+        { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+          '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+        -123456789.0,
+        { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
+};
+"""
+
+def pyod(filename):
+    """Python implementation of the od UNIX utility (od -b, more exactly).
+
+    Parameters
+    ----------
+    filename : str
+        name of the file to get the dump from.
+
+    Returns
+    -------
+    out : seq
+        list of lines of od output
+
+    Note
+    ----
+    We only implement enough to get the necessary information for long double
+    representation, this is not intended as a compatible replacement for od.
+    """
+    def _pyod2():
+        out = []
+
+        fid = open(filename, 'rb')
+        try:
+            yo = [int(oct(int(binascii.b2a_hex(o), 16))) for o in fid.read()]
+            for i in range(0, len(yo), 16):
+                line = ['%07d' % int(oct(i))]
+                line.extend(['%03d' % c for c in yo[i:i+16]])
+                out.append(" ".join(line))
+            return out
+        finally:
+            fid.close()
+
+    def _pyod3():
+        out = []
+
+        fid = open(filename, 'rb')
+        try:
+            yo2 = [oct(o)[2:] for o in fid.read()]
+            for i in range(0, len(yo2), 16):
+                line = ['%07d' % int(oct(i)[2:])]
+                line.extend(['%03d' % int(c) for c in yo2[i:i+16]])
+                out.append(" ".join(line))
+            return out
+        finally:
+            fid.close()
+
+    if sys.version_info[0] < 3:
+        return _pyod2()
+    else:
+        return _pyod3()
+
+_BEFORE_SEQ = ['000', '000', '000', '000', '000', '000', '000', '000',
+              '001', '043', '105', '147', '211', '253', '315', '357']
+_AFTER_SEQ = ['376', '334', '272', '230', '166', '124', '062', '020']
+
+_IEEE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000']
+_IEEE_DOUBLE_LE = _IEEE_DOUBLE_BE[::-1]
+_INTEL_EXTENDED_12B = ['000', '000', '000', '000', '240', '242', '171', '353',
+                       '031', '300', '000', '000']
+_INTEL_EXTENDED_16B = ['000', '000', '000', '000', '240', '242', '171', '353',
+                       '031', '300', '000', '000', '000', '000', '000', '000']
+_MOTOROLA_EXTENDED_12B = ['300', '031', '000', '000', '353', '171',
+                          '242', '240', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_BE = ['300', '031', '326', '363', '105', '100', '000', '000',
+                      '000', '000', '000', '000', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_LE = _IEEE_QUAD_PREC_BE[::-1]
+_DOUBLE_DOUBLE_BE = (['301', '235', '157', '064', '124', '000', '000', '000'] +
+                     ['000'] * 8)
+_DOUBLE_DOUBLE_LE = (['000', '000', '000', '124', '064', '157', '235', '301'] +
+                     ['000'] * 8)
+
+def long_double_representation(lines):
+    """Given a binary dump as given by GNU od -b, look for long double
+    representation."""
+
+    # Read contains a list of 32 items, each item is a byte (in octal
+    # representation, as a string). We 'slide' over the output until read is of
+    # the form before_seq + content + after_sequence, where content is the long double
+    # representation:
+    #  - content is 12 bytes: 80 bits Intel representation
+    #  - content is 16 bytes: 80 bits Intel representation (64 bits) or quad precision
+    #  - content is 8 bytes: same as double (not implemented yet)
+    read = [''] * 32
+    saw = None
+    for line in lines:
+        # we skip the first word, as od -b output an index at the beginning of
+        # each line
+        for w in line.split()[1:]:
+            read.pop(0)
+            read.append(w)
+
+            # If the end of read is equal to the after_sequence, read contains
+            # the long double
+            if read[-8:] == _AFTER_SEQ:
+                saw = copy.copy(read)
+                if read[:12] == _BEFORE_SEQ[4:]:
+                    if read[12:-8] == _INTEL_EXTENDED_12B:
+                        return 'INTEL_EXTENDED_12_BYTES_LE'
+                    if read[12:-8] == _MOTOROLA_EXTENDED_12B:
+                        return 'MOTOROLA_EXTENDED_12_BYTES_BE'
+                elif read[:8] == _BEFORE_SEQ[8:]:
+                    if read[8:-8] == _INTEL_EXTENDED_16B:
+                        return 'INTEL_EXTENDED_16_BYTES_LE'
+                    elif read[8:-8] == _IEEE_QUAD_PREC_BE:
+                        return 'IEEE_QUAD_BE'
+                    elif read[8:-8] == _IEEE_QUAD_PREC_LE:
+                        return 'IEEE_QUAD_LE'
+                    elif read[8:-8] == _DOUBLE_DOUBLE_BE:
+                        return 'DOUBLE_DOUBLE_BE'
+                    elif read[8:-8] == _DOUBLE_DOUBLE_LE:
+                        return 'DOUBLE_DOUBLE_LE'
+                elif read[:16] == _BEFORE_SEQ:
+                    if read[16:-8] == _IEEE_DOUBLE_LE:
+                        return 'IEEE_DOUBLE_LE'
+                    elif read[16:-8] == _IEEE_DOUBLE_BE:
+                        return 'IEEE_DOUBLE_BE'
+
+    if saw is not None:
+        raise ValueError("Unrecognized format (%s)" % saw)
+    else:
+        # We never detected the after_sequence
+        raise ValueError("Could not lock sequences (%s)" % saw)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/shape_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/shape_base.py
new file mode 100644
index 0000000000..599b48d82b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/shape_base.py
@@ -0,0 +1,350 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack',
+           'stack']
+
+from . import numeric as _nx
+from .numeric import asanyarray, newaxis
+
+def atleast_1d(*arys):
+    """
+    Convert inputs to arrays with at least one dimension.
+
+    Scalar inputs are converted to 1-dimensional arrays, whilst
+    higher-dimensional inputs are preserved.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more input arrays.
+
+    Returns
+    -------
+    ret : ndarray
+        An array, or sequence of arrays, each with ``a.ndim >= 1``.
+        Copies are made only if necessary.
+
+    See Also
+    --------
+    atleast_2d, atleast_3d
+
+    Examples
+    --------
+    >>> np.atleast_1d(1.0)
+    array([ 1.])
+
+    >>> x = np.arange(9.0).reshape(3,3)
+    >>> np.atleast_1d(x)
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4.,  5.],
+           [ 6.,  7.,  8.]])
+    >>> np.atleast_1d(x) is x
+    True
+
+    >>> np.atleast_1d(1, [3, 4])
+    [array([1]), array([3, 4])]
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1)
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+def atleast_2d(*arys):
+    """
+    View inputs as arrays with at least two dimensions.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more array-like sequences.  Non-array inputs are converted
+        to arrays.  Arrays that already have two or more dimensions are
+        preserved.
+
+    Returns
+    -------
+    res, res2, ... : ndarray
+        An array, or tuple of arrays, each with ``a.ndim >= 2``.
+        Copies are avoided where possible, and views with two or more
+        dimensions are returned.
+
+    See Also
+    --------
+    atleast_1d, atleast_3d
+
+    Examples
+    --------
+    >>> np.atleast_2d(3.0)
+    array([[ 3.]])
+
+    >>> x = np.arange(3.0)
+    >>> np.atleast_2d(x)
+    array([[ 0.,  1.,  2.]])
+    >>> np.atleast_2d(x).base is x
+    True
+
+    >>> np.atleast_2d(1, [1, 2], [[1, 2]])
+    [array([[1]]), array([[1, 2]]), array([[1, 2]])]
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1, 1)
+        elif len(ary.shape) == 1:
+            result = ary[newaxis,:]
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+def atleast_3d(*arys):
+    """
+    View inputs as arrays with at least three dimensions.
+
+    Parameters
+    ----------
+    arys1, arys2, ... : array_like
+        One or more array-like sequences.  Non-array inputs are converted to
+        arrays.  Arrays that already have three or more dimensions are
+        preserved.
+
+    Returns
+    -------
+    res1, res2, ... : ndarray
+        An array, or tuple of arrays, each with ``a.ndim >= 3``.  Copies are
+        avoided where possible, and views with three or more dimensions are
+        returned.  For example, a 1-D array of shape ``(N,)`` becomes a view
+        of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a
+        view of shape ``(M, N, 1)``.
+
+    See Also
+    --------
+    atleast_1d, atleast_2d
+
+    Examples
+    --------
+    >>> np.atleast_3d(3.0)
+    array([[[ 3.]]])
+
+    >>> x = np.arange(3.0)
+    >>> np.atleast_3d(x).shape
+    (1, 3, 1)
+
+    >>> x = np.arange(12.0).reshape(4,3)
+    >>> np.atleast_3d(x).shape
+    (4, 3, 1)
+    >>> np.atleast_3d(x).base is x
+    True
+
+    >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]):
+    ...     print(arr, arr.shape)
+    ...
+    [[[1]
+      [2]]] (1, 2, 1)
+    [[[1]
+      [2]]] (1, 2, 1)
+    [[[1 2]]] (1, 1, 2)
+
+    """
+    res = []
+    for ary in arys:
+        ary = asanyarray(ary)
+        if len(ary.shape) == 0:
+            result = ary.reshape(1, 1, 1)
+        elif len(ary.shape) == 1:
+            result = ary[newaxis,:, newaxis]
+        elif len(ary.shape) == 2:
+            result = ary[:,:, newaxis]
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+
+def vstack(tup):
+    """
+    Stack arrays in sequence vertically (row wise).
+
+    Take a sequence of arrays and stack them vertically to make a single
+    array. Rebuild arrays divided by `vsplit`.
+
+    Parameters
+    ----------
+    tup : sequence of ndarrays
+        Tuple containing arrays to be stacked. The arrays must have the same
+        shape along all but the first axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise).
+    dstack : Stack arrays in sequence depth wise (along third dimension).
+    concatenate : Join a sequence of arrays along an existing axis.
+    vsplit : Split array into a list of multiple sub-arrays vertically.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that
+    are at least 2-dimensional.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3])
+    >>> b = np.array([2, 3, 4])
+    >>> np.vstack((a,b))
+    array([[1, 2, 3],
+           [2, 3, 4]])
+
+    >>> a = np.array([[1], [2], [3]])
+    >>> b = np.array([[2], [3], [4]])
+    >>> np.vstack((a,b))
+    array([[1],
+           [2],
+           [3],
+           [2],
+           [3],
+           [4]])
+
+    """
+    return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
+
+def hstack(tup):
+    """
+    Stack arrays in sequence horizontally (column wise).
+
+    Take a sequence of arrays and stack them horizontally to make
+    a single array. Rebuild arrays divided by `hsplit`.
+
+    Parameters
+    ----------
+    tup : sequence of ndarrays
+        All arrays must have the same shape along all but the second axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    vstack : Stack arrays in sequence vertically (row wise).
+    dstack : Stack arrays in sequence depth wise (along third axis).
+    concatenate : Join a sequence of arrays along an existing axis.
+    hsplit : Split array along second axis.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=1)``
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.hstack((a,b))
+    array([1, 2, 3, 2, 3, 4])
+    >>> a = np.array([[1],[2],[3]])
+    >>> b = np.array([[2],[3],[4]])
+    >>> np.hstack((a,b))
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrs = [atleast_1d(_m) for _m in tup]
+    # As a special case, dimension 0 of 1-dimensional arrays is "horizontal"
+    if arrs[0].ndim == 1:
+        return _nx.concatenate(arrs, 0)
+    else:
+        return _nx.concatenate(arrs, 1)
+
+def stack(arrays, axis=0):
+    """
+    Join a sequence of arrays along a new axis.
+
+    The `axis` parameter specifies the index of the new axis in the dimensions
+    of the result. For example, if ``axis=0`` it will be the first dimension
+    and if ``axis=-1`` it will be the last dimension.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        Each array must have the same shape.
+    axis : int, optional
+        The axis in the result array along which the input arrays are stacked.
+
+    Returns
+    -------
+    stacked : ndarray
+        The stacked array has one more dimension than the input arrays.
+
+    See Also
+    --------
+    concatenate : Join a sequence of arrays along an existing axis.
+    split : Split array into a list of multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> arrays = [np.random.randn(3, 4) for _ in range(10)]
+    >>> np.stack(arrays, axis=0).shape
+    (10, 3, 4)
+
+    >>> np.stack(arrays, axis=1).shape
+    (3, 10, 4)
+
+    >>> np.stack(arrays, axis=2).shape
+    (3, 4, 10)
+
+    >>> a = np.array([1, 2, 3])
+    >>> b = np.array([2, 3, 4])
+    >>> np.stack((a, b))
+    array([[1, 2, 3],
+           [2, 3, 4]])
+
+    >>> np.stack((a, b), axis=-1)
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrays = [asanyarray(arr) for arr in arrays]
+    if not arrays:
+        raise ValueError('need at least one array to stack')
+
+    shapes = set(arr.shape for arr in arrays)
+    if len(shapes) != 1:
+        raise ValueError('all input arrays must have the same shape')
+
+    result_ndim = arrays[0].ndim + 1
+    if not -result_ndim <= axis < result_ndim:
+        msg = 'axis {0} out of bounds [-{1}, {1})'.format(axis, result_ndim)
+        raise IndexError(msg)
+    if axis < 0:
+        axis += result_ndim
+
+    sl = (slice(None),) * axis + (_nx.newaxis,)
+    expanded_arrays = [arr[sl] for arr in arrays]
+    return _nx.concatenate(expanded_arrays, axis=axis)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..e5af4d3112adb4a99e7aef10317c3bf3067de000
GIT binary patch
literal 18944
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
S0O2bv(13}I#Lyk|eg*)$)PLFl

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/test_rational.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/test_rational.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..b36effc9a0651d83c9fc6e463bb579620db488e1
GIT binary patch
literal 79360
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
T1rWZ%0u7i5$fcv0!Vmxe9#gC7

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..7397c978297b3f64c7e6540b23f448f280e30bcc
GIT binary patch
literal 716
zcmZo*O3o|IEvVE>&M!*U%Pq|*$xJLNO049HFG@|$&nqq|DorloDrAJH;>t^b$QCkr
zGqi>>Cbb6@GHZA<dV97)6{M6@7Nl|&vV=0FS$H#eGqwj6vTArUhcepu`T2SM|Ns9#
znDAyON$L#oU}9i!2{M+p-EHo`e0p8g@15ojb5<8@_t|OgAgbvyGkT}F!xi0|Hv4y&
zJ0wgjwvyav?jW%`%=gd&bBEn34?|y0H+Ptk9GEzHrMbhFZ|^b;PntWd(b*d(c*@+N
z-hW2Kgwy5@()xE**v^_e99{7+Klq%vgP{b!xWOrNhdqraV);&+JIq{m?%v{4<_<e6
z?Ce&bFn37M-5lO{*xX_HxqFLW9X5A(vo48s`XO_Ny`T2BZa8G_5W8JE-0YCK!;O#Y
z?zkT`cbNY#K;QU)xr4!*vw0c&%^iGon>H%$Gk3VS^{mA7J?0LJV?Ld5TW9Vd`aZyV
z-E?z@4=Wn(s&<<@xL!SEUq8d#!9(`ZREy>24rg3L6EEyHcd*=<<)41e+#y^>rgPdA
zbBC!$c@LDXm^(z2N_#Pa_zi376Rwy$EL|MlD|pr1fkpDIq~#@Zhxbjh=YPFt?jTW}
zRUiD&+~M#^m8-WNn>%=~(d=LO)Z9TP+^kLbsky_7-#70rcw+9LpBl!T^TgaCk)va^
z{S$MCJyDu{?;o2x7?k|a4t{LzuvhwG#hQoa4h$fVoilfEUbEh(d7rsMW^PT=n?2?Z
zdw$$GXL8Wop{M0;(!+b^4w?@qaf!Y(cQ_f}bn4<qa|iDtGs8dc%^lv(|F-wgQ*(#Y
zMZ#6Z7tI|QSzfs9x@hhot$J<B@oVM|Uo%#Rv)?p#@ZHC-Hs+SO1N%Q#dC%MC4mTD!
zb=ci8chCqkj)=Q!?ogWY?D*At<_<sC&iV1>zPW=>_cKkU$L0<?vpXJq`D*S^lB5R!
Dg`qy%

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
new file mode 100644
index 0000000000000000000000000000000000000000..ca48ee85153645a7510e201d574e9b119c089dce
GIT binary patch
literal 8640
zcmWIc^bPQFRZy^1zyd-P^cB)Fb5a#j@>7cylJoP@@{4j6O7a!lJVSyNic1pnQWA?&
zP&7Juh6H#<U^mauOhI2EuQWF)wMZd9O(7|>q*$RKwMZc)u_RHUAhRMh2gN8b$Imgs
zGgtw;c?t$7=7Eh#tVk^eYs5jgMufQfx!^Dl<X^DYKt>g(mMG*VR)V};l9-vNkXlia
znpd2epNC?;v%jyet6zwM0whc{+;UPYGLv#r6+Ckj(^C~fiW2jR3-XIf6oM;@OHy++
z6+l6lSfY@UnwFWDnxc@Ir{GvzQk0*UpIfPrn3sYu4=h}eQCXasT&xgWT2PRanwy$e
zq7a-~l$lzrP-bGHUtnxztOI448|o;OnH%dD7@JzcSZ1br2=kot^GXtvOB6~nQWg9h
zgB=xulQUEEl2aA@)6z1NQ$aBj42{uZkV_OoQj;_C@^kXjD?yG1>r+rbm<J9h7mznH
zOEUBG6jJh&OTi9QHZ(8*8<1a;ky-=^mrQWdNdzg>Lx~yxAWwHsKTv$A2ZsbFd+G*<
z1iLr}>xVcx`M3tFE9fhPBqrs6{F_<?3Va1aOG`^#14~^4a};x695+uNS3gHzS6c=3
zk|ez}P!dyz$tfs+(o144*stJpjU<DE=?6_PSo4P=$UJy@MoJ)=d60aAX(%}HVG56m
zjE2By2#kinXb6mkz-R~zp%4HyCxbox{cIJ~ojm=(trpbwMp9;8Vo{|+38)o=XhY)k
zA-?vrf`x*<f`x8UW{E;lWeNUvF3bYF?PnteeFY=kl+0X6!!|KT0mZd2GmvSpd4{0&
z8nP&aZD_8buTY+uQj!5`OhSB|nTOx4VDpTyo2Ot5F_#oFz}Y_()Evj!UIX<PiZiRg
z?Z4uJ)a1;>97yLQu_!eWyDjec%mcOm^7B$5W~3M8mlh~!6r~oHW)`KUC}gKrmgg6x
zXrh`M;^yh<;}VR$zeR?BLqZ}0T*2|74)XzO`pZd7O3hJ7%P&$$%S_Dyb=C|~U4+UD
zaq|!Ig_vjP0+B*B57adR8JC+_0*Ym@p;n+&Sy_^*;Nl<Z1nNyfG=fO5`@r$5o&@46
zC@7$shv_~es5-0^*nJT5480&KP|d^cJ`-I~j#2RR3vqRK4T9(clVJB5gVLXRGFX7H
z`|!pR*nJT5OdTNx65~F{U}sNH1?P;!qQvBq)FOyR5E<g)85{tK4|gL|Jwr2e_oZYO
z7vv;@yJ(;&0qMbq!RA52&(jc+642a7qIrIyK0aXc;I`@-8Jd`zSQwj`fXai?JXlw^
zEHS4v6_j)olJj#)bMxRDkQre2LBh|`6e2;9`#d~@L;Qmx6`YGw6H8K46x@n36%5U+
zj7+Tz%oU7`biGRRbd3xQARz&<4=*{|f5RI*qmrW`Fd71*AwYBpIEbWyKso~hgKc6`
za!RU$$Qckg%fP^3mzJK9ndKmA3<4$$3=H<!pb=t*Q7{?;qaiRF0;3@?8UmvsFd71*
LAut*OBQ*p7Ng>cF

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_abc.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
new file mode 100644
index 0000000000..2430866fdf
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
@@ -0,0 +1,47 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import TestCase, assert_, run_module_suite
+
+import numbers
+from numpy.core.numerictypes import sctypes
+
+class ABC(TestCase):
+    def test_floats(self):
+        for t in sctypes['float']:
+            assert_(isinstance(t(), numbers.Real), 
+                    "{0} is not instance of Real".format(t.__name__))
+            assert_(issubclass(t, numbers.Real),
+                    "{0} is not subclass of Real".format(t.__name__))
+            assert_(not isinstance(t(), numbers.Rational), 
+                    "{0} is instance of Rational".format(t.__name__))
+            assert_(not issubclass(t, numbers.Rational),
+                    "{0} is subclass of Rational".format(t.__name__))
+
+    def test_complex(self):
+        for t in sctypes['complex']:
+            assert_(isinstance(t(), numbers.Complex), 
+                    "{0} is not instance of Complex".format(t.__name__))
+            assert_(issubclass(t, numbers.Complex),
+                    "{0} is not subclass of Complex".format(t.__name__))
+            assert_(not isinstance(t(), numbers.Real), 
+                    "{0} is instance of Real".format(t.__name__))
+            assert_(not issubclass(t, numbers.Real),
+                    "{0} is subclass of Real".format(t.__name__))
+
+    def test_int(self):
+        for t in sctypes['int']:
+            assert_(isinstance(t(), numbers.Integral), 
+                    "{0} is not instance of Integral".format(t.__name__))
+            assert_(issubclass(t, numbers.Integral),
+                    "{0} is not subclass of Integral".format(t.__name__))
+
+    def test_uint(self):
+        for t in sctypes['uint']:
+            assert_(isinstance(t(), numbers.Integral), 
+                    "{0} is not instance of Integral".format(t.__name__))
+            assert_(issubclass(t, numbers.Integral),
+                    "{0} is not subclass of Integral".format(t.__name__))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_api.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_api.py
new file mode 100644
index 0000000000..876cab4d7b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_api.py
@@ -0,0 +1,515 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import sixu
+from numpy.testing import (
+     run_module_suite, assert_, assert_equal, assert_array_equal,
+     assert_raises
+)
+
+# Switch between new behaviour when NPY_RELAXED_STRIDES_CHECKING is set.
+NPY_RELAXED_STRIDES_CHECKING = np.ones((10, 1), order='C').flags.f_contiguous
+
+
+def test_array_array():
+    tobj = type(object)
+    ones11 = np.ones((1, 1), np.float64)
+    tndarray = type(ones11)
+    # Test is_ndarray
+    assert_equal(np.array(ones11, dtype=np.float64), ones11)
+    old_refcount = sys.getrefcount(tndarray)
+    np.array(ones11)
+    assert_equal(old_refcount, sys.getrefcount(tndarray))
+
+    # test None
+    assert_equal(np.array(None, dtype=np.float64),
+                 np.array(np.nan, dtype=np.float64))
+    old_refcount = sys.getrefcount(tobj)
+    np.array(None, dtype=np.float64)
+    assert_equal(old_refcount, sys.getrefcount(tobj))
+
+    # test scalar
+    assert_equal(np.array(1.0, dtype=np.float64),
+                 np.ones((), dtype=np.float64))
+    old_refcount = sys.getrefcount(np.float64)
+    np.array(np.array(1.0, dtype=np.float64), dtype=np.float64)
+    assert_equal(old_refcount, sys.getrefcount(np.float64))
+
+    # test string
+    S2 = np.dtype((str, 2))
+    S3 = np.dtype((str, 3))
+    S5 = np.dtype((str, 5))
+    assert_equal(np.array("1.0", dtype=np.float64),
+                 np.ones((), dtype=np.float64))
+    assert_equal(np.array("1.0").dtype, S3)
+    assert_equal(np.array("1.0", dtype=str).dtype, S3)
+    assert_equal(np.array("1.0", dtype=S2), np.array("1."))
+    assert_equal(np.array("1", dtype=S5), np.ones((), dtype=S5))
+
+    # test unicode
+    _unicode = globals().get("unicode")
+    if _unicode:
+        U2 = np.dtype((_unicode, 2))
+        U3 = np.dtype((_unicode, 3))
+        U5 = np.dtype((_unicode, 5))
+        assert_equal(np.array(_unicode("1.0"), dtype=np.float64),
+                     np.ones((), dtype=np.float64))
+        assert_equal(np.array(_unicode("1.0")).dtype, U3)
+        assert_equal(np.array(_unicode("1.0"), dtype=_unicode).dtype, U3)
+        assert_equal(np.array(_unicode("1.0"), dtype=U2),
+                     np.array(_unicode("1.")))
+        assert_equal(np.array(_unicode("1"), dtype=U5),
+                     np.ones((), dtype=U5))
+
+    builtins = getattr(__builtins__, '__dict__', __builtins__)
+    assert_(isinstance(builtins, dict))
+
+    # test buffer
+    _buffer = builtins.get("buffer")
+    if _buffer and sys.version_info[:3] >= (2, 7, 5):
+        # This test fails for earlier versions of Python.
+        # Evidently a bug got fixed in 2.7.5.
+        dat = np.array(_buffer('1.0'), dtype=np.float64)
+        assert_equal(dat, [49.0, 46.0, 48.0])
+        assert_(dat.dtype.type is np.float64)
+
+        dat = np.array(_buffer(b'1.0'))
+        assert_equal(dat, [49, 46, 48])
+        assert_(dat.dtype.type is np.uint8)
+
+    # test memoryview, new version of buffer
+    _memoryview = builtins.get("memoryview")
+    if _memoryview:
+        dat = np.array(_memoryview(b'1.0'), dtype=np.float64)
+        assert_equal(dat, [49.0, 46.0, 48.0])
+        assert_(dat.dtype.type is np.float64)
+
+        dat = np.array(_memoryview(b'1.0'))
+        assert_equal(dat, [49, 46, 48])
+        assert_(dat.dtype.type is np.uint8)
+
+    # test array interface
+    a = np.array(100.0, dtype=np.float64)
+    o = type("o", (object,),
+             dict(__array_interface__=a.__array_interface__))
+    assert_equal(np.array(o, dtype=np.float64), a)
+
+    # test array_struct interface
+    a = np.array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
+                 dtype=[('f0', int), ('f1', float), ('f2', str)])
+    o = type("o", (object,),
+             dict(__array_struct__=a.__array_struct__))
+    ## wasn't what I expected... is np.array(o) supposed to equal a ?
+    ## instead we get a array([...], dtype=">V18")
+    assert_equal(str(np.array(o).data), str(a.data))
+
+    # test array
+    o = type("o", (object,),
+             dict(__array__=lambda *x: np.array(100.0, dtype=np.float64)))()
+    assert_equal(np.array(o, dtype=np.float64), np.array(100.0, np.float64))
+
+    # test recursion
+    nested = 1.5
+    for i in range(np.MAXDIMS):
+        nested = [nested]
+
+    # no error
+    np.array(nested)
+
+    # Exceeds recursion limit
+    assert_raises(ValueError, np.array, [nested], dtype=np.float64)
+
+    # Try with lists...
+    assert_equal(np.array([None] * 10, dtype=np.float64),
+                 np.full((10,), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None]] * 10, dtype=np.float64),
+                 np.full((10, 1), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None] * 10], dtype=np.float64),
+                 np.full((1, 10), np.nan, dtype=np.float64))
+    assert_equal(np.array([[None] * 10] * 10, dtype=np.float64),
+                 np.full((10, 10), np.nan, dtype=np.float64))
+
+    assert_equal(np.array([1.0] * 10, dtype=np.float64),
+                 np.ones((10,), dtype=np.float64))
+    assert_equal(np.array([[1.0]] * 10, dtype=np.float64),
+                 np.ones((10, 1), dtype=np.float64))
+    assert_equal(np.array([[1.0] * 10], dtype=np.float64),
+                 np.ones((1, 10), dtype=np.float64))
+    assert_equal(np.array([[1.0] * 10] * 10, dtype=np.float64),
+                 np.ones((10, 10), dtype=np.float64))
+
+    # Try with tuples
+    assert_equal(np.array((None,) * 10, dtype=np.float64),
+                 np.full((10,), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,)] * 10, dtype=np.float64),
+                 np.full((10, 1), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,) * 10], dtype=np.float64),
+                 np.full((1, 10), np.nan, dtype=np.float64))
+    assert_equal(np.array([(None,) * 10] * 10, dtype=np.float64),
+                 np.full((10, 10), np.nan, dtype=np.float64))
+
+    assert_equal(np.array((1.0,) * 10, dtype=np.float64),
+                 np.ones((10,), dtype=np.float64))
+    assert_equal(np.array([(1.0,)] * 10, dtype=np.float64),
+                 np.ones((10, 1), dtype=np.float64))
+    assert_equal(np.array([(1.0,) * 10], dtype=np.float64),
+                 np.ones((1, 10), dtype=np.float64))
+    assert_equal(np.array([(1.0,) * 10] * 10, dtype=np.float64),
+                 np.ones((10, 10), dtype=np.float64))
+
+
+def test_fastCopyAndTranspose():
+    # 0D array
+    a = np.array(2)
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+    # 1D array
+    a = np.array([3, 2, 7, 0])
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+    # 2D array
+    a = np.arange(6).reshape(2, 3)
+    b = np.fastCopyAndTranspose(a)
+    assert_equal(b, a.T)
+    assert_(b.flags.owndata)
+
+def test_array_astype():
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+    # Default behavior: allows unsafe casts, keeps memory layout,
+    #                   always copies.
+    b = a.astype('i4')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('i4'))
+    assert_equal(a.strides, b.strides)
+    b = a.T.astype('i4')
+    assert_equal(a.T, b)
+    assert_equal(b.dtype, np.dtype('i4'))
+    assert_equal(a.T.strides, b.strides)
+    b = a.astype('f4')
+    assert_equal(a, b)
+    assert_(not (a is b))
+
+    # copy=False parameter can sometimes skip a copy
+    b = a.astype('f4', copy=False)
+    assert_(a is b)
+
+    # order parameter allows overriding of the memory layout,
+    # forcing a copy if the layout is wrong
+    b = a.astype('f4', order='F', copy=False)
+    assert_equal(a, b)
+    assert_(not (a is b))
+    assert_(b.flags.f_contiguous)
+
+    b = a.astype('f4', order='C', copy=False)
+    assert_equal(a, b)
+    assert_(a is b)
+    assert_(b.flags.c_contiguous)
+
+    # casting parameter allows catching bad casts
+    b = a.astype('c8', casting='safe')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('c8'))
+
+    assert_raises(TypeError, a.astype, 'i4', casting='safe')
+
+    # subok=False passes through a non-subclassed array
+    b = a.astype('f4', subok=0, copy=False)
+    assert_(a is b)
+
+    a = np.matrix([[0, 1, 2], [3, 4, 5]], dtype='f4')
+
+    # subok=True passes through a matrix
+    b = a.astype('f4', subok=True, copy=False)
+    assert_(a is b)
+
+    # subok=True is default, and creates a subtype on a cast
+    b = a.astype('i4', copy=False)
+    assert_equal(a, b)
+    assert_equal(type(b), np.matrix)
+
+    # subok=False never returns a matrix
+    b = a.astype('f4', subok=False, copy=False)
+    assert_equal(a, b)
+    assert_(not (a is b))
+    assert_(type(b) is not np.matrix)
+
+    # Make sure converting from string object to fixed length string
+    # does not truncate.
+    a = np.array([b'a'*100], dtype='O')
+    b = a.astype('S')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('S100'))
+    a = np.array([sixu('a')*100], dtype='O')
+    b = a.astype('U')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('U100'))
+
+    # Same test as above but for strings shorter than 64 characters
+    a = np.array([b'a'*10], dtype='O')
+    b = a.astype('S')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('S10'))
+    a = np.array([sixu('a')*10], dtype='O')
+    b = a.astype('U')
+    assert_equal(a, b)
+    assert_equal(b.dtype, np.dtype('U10'))
+
+    a = np.array(123456789012345678901234567890, dtype='O').astype('S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array(123456789012345678901234567890, dtype='O').astype('U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array([123456789012345678901234567890], dtype='O').astype('S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array([123456789012345678901234567890], dtype='O').astype('U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array(123456789012345678901234567890, dtype='S')
+    assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30'))
+    a = np.array(123456789012345678901234567890, dtype='U')
+    assert_array_equal(a, np.array(sixu('1234567890' * 3), dtype='U30'))
+
+    a = np.array(sixu('a\u0140'), dtype='U')
+    b = np.ndarray(buffer=a, dtype='uint32', shape=2)
+    assert_(b.size == 2)
+
+    a = np.array([1000], dtype='i4')
+    assert_raises(TypeError, a.astype, 'S1', casting='safe')
+
+    a = np.array(1000, dtype='i4')
+    assert_raises(TypeError, a.astype, 'U1', casting='safe')
+
+def test_copyto_fromscalar():
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+
+    # Simple copy
+    np.copyto(a, 1.5)
+    assert_equal(a, 1.5)
+    np.copyto(a.T, 2.5)
+    assert_equal(a, 2.5)
+
+    # Where-masked copy
+    mask = np.array([[0, 1, 0], [0, 0, 1]], dtype='?')
+    np.copyto(a, 3.5, where=mask)
+    assert_equal(a, [[2.5, 3.5, 2.5], [2.5, 2.5, 3.5]])
+    mask = np.array([[0, 1], [1, 1], [1, 0]], dtype='?')
+    np.copyto(a.T, 4.5, where=mask)
+    assert_equal(a, [[2.5, 4.5, 4.5], [4.5, 4.5, 3.5]])
+
+def test_copyto():
+    a = np.arange(6, dtype='i4').reshape(2, 3)
+
+    # Simple copy
+    np.copyto(a, [[3, 1, 5], [6, 2, 1]])
+    assert_equal(a, [[3, 1, 5], [6, 2, 1]])
+
+    # Overlapping copy should work
+    np.copyto(a[:, :2], a[::-1, 1::-1])
+    assert_equal(a, [[2, 6, 5], [1, 3, 1]])
+
+    # Defaults to 'same_kind' casting
+    assert_raises(TypeError, np.copyto, a, 1.5)
+
+    # Force a copy with 'unsafe' casting, truncating 1.5 to 1
+    np.copyto(a, 1.5, casting='unsafe')
+    assert_equal(a, 1)
+
+    # Copying with a mask
+    np.copyto(a, 3, where=[True, False, True])
+    assert_equal(a, [[3, 1, 3], [3, 1, 3]])
+
+    # Casting rule still applies with a mask
+    assert_raises(TypeError, np.copyto, a, 3.5, where=[True, False, True])
+
+    # Lists of integer 0's and 1's is ok too
+    np.copyto(a, 4.0, casting='unsafe', where=[[0, 1, 1], [1, 0, 0]])
+    assert_equal(a, [[3, 4, 4], [4, 1, 3]])
+
+    # Overlapping copy with mask should work
+    np.copyto(a[:, :2], a[::-1, 1::-1], where=[[0, 1], [1, 1]])
+    assert_equal(a, [[3, 4, 4], [4, 3, 3]])
+
+    # 'dst' must be an array
+    assert_raises(TypeError, np.copyto, [1, 2, 3], [2, 3, 4])
+
+def test_copyto_permut():
+    # test explicit overflow case
+    pad = 500
+    l = [True] * pad + [True, True, True, True]
+    r = np.zeros(len(l)-pad)
+    d = np.ones(len(l)-pad)
+    mask = np.array(l)[pad:]
+    np.copyto(r, d, where=mask[::-1])
+
+    # test all permutation of possible masks, 9 should be sufficient for
+    # current 4 byte unrolled code
+    power = 9
+    d = np.ones(power)
+    for i in range(2**power):
+        r = np.zeros(power)
+        l = [(i & x) != 0 for x in range(power)]
+        mask = np.array(l)
+        np.copyto(r, d, where=mask)
+        assert_array_equal(r == 1, l)
+        assert_equal(r.sum(), sum(l))
+
+        r = np.zeros(power)
+        np.copyto(r, d, where=mask[::-1])
+        assert_array_equal(r == 1, l[::-1])
+        assert_equal(r.sum(), sum(l))
+
+        r = np.zeros(power)
+        np.copyto(r[::2], d[::2], where=mask[::2])
+        assert_array_equal(r[::2] == 1, l[::2])
+        assert_equal(r[::2].sum(), sum(l[::2]))
+
+        r = np.zeros(power)
+        np.copyto(r[::2], d[::2], where=mask[::-2])
+        assert_array_equal(r[::2] == 1, l[::-2])
+        assert_equal(r[::2].sum(), sum(l[::-2]))
+
+        for c in [0xFF, 0x7F, 0x02, 0x10]:
+            r = np.zeros(power)
+            mask = np.array(l)
+            imask = np.array(l).view(np.uint8)
+            imask[mask != 0] = c
+            np.copyto(r, d, where=mask)
+            assert_array_equal(r == 1, l)
+            assert_equal(r.sum(), sum(l))
+
+    r = np.zeros(power)
+    np.copyto(r, d, where=True)
+    assert_equal(r.sum(), r.size)
+    r = np.ones(power)
+    d = np.zeros(power)
+    np.copyto(r, d, where=False)
+    assert_equal(r.sum(), r.size)
+
+def test_copy_order():
+    a = np.arange(24).reshape(2, 1, 3, 4)
+    b = a.copy(order='F')
+    c = np.arange(24).reshape(2, 1, 4, 3).swapaxes(2, 3)
+
+    def check_copy_result(x, y, ccontig, fcontig, strides=False):
+        assert_(not (x is y))
+        assert_equal(x, y)
+        assert_equal(res.flags.c_contiguous, ccontig)
+        assert_equal(res.flags.f_contiguous, fcontig)
+        # This check is impossible only because
+        # NPY_RELAXED_STRIDES_CHECKING changes the strides actively
+        if not NPY_RELAXED_STRIDES_CHECKING:
+            if strides:
+                assert_equal(x.strides, y.strides)
+            else:
+                assert_(x.strides != y.strides)
+
+    # Validate the initial state of a, b, and c
+    assert_(a.flags.c_contiguous)
+    assert_(not a.flags.f_contiguous)
+    assert_(not b.flags.c_contiguous)
+    assert_(b.flags.f_contiguous)
+    assert_(not c.flags.c_contiguous)
+    assert_(not c.flags.f_contiguous)
+
+    # Copy with order='C'
+    res = a.copy(order='C')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = b.copy(order='C')
+    check_copy_result(res, b, ccontig=True, fcontig=False, strides=False)
+    res = c.copy(order='C')
+    check_copy_result(res, c, ccontig=True, fcontig=False, strides=False)
+    res = np.copy(a, order='C')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = np.copy(b, order='C')
+    check_copy_result(res, b, ccontig=True, fcontig=False, strides=False)
+    res = np.copy(c, order='C')
+    check_copy_result(res, c, ccontig=True, fcontig=False, strides=False)
+
+    # Copy with order='F'
+    res = a.copy(order='F')
+    check_copy_result(res, a, ccontig=False, fcontig=True, strides=False)
+    res = b.copy(order='F')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = c.copy(order='F')
+    check_copy_result(res, c, ccontig=False, fcontig=True, strides=False)
+    res = np.copy(a, order='F')
+    check_copy_result(res, a, ccontig=False, fcontig=True, strides=False)
+    res = np.copy(b, order='F')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = np.copy(c, order='F')
+    check_copy_result(res, c, ccontig=False, fcontig=True, strides=False)
+
+    # Copy with order='K'
+    res = a.copy(order='K')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = b.copy(order='K')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = c.copy(order='K')
+    check_copy_result(res, c, ccontig=False, fcontig=False, strides=True)
+    res = np.copy(a, order='K')
+    check_copy_result(res, a, ccontig=True, fcontig=False, strides=True)
+    res = np.copy(b, order='K')
+    check_copy_result(res, b, ccontig=False, fcontig=True, strides=True)
+    res = np.copy(c, order='K')
+    check_copy_result(res, c, ccontig=False, fcontig=False, strides=True)
+
+def test_contiguous_flags():
+    a = np.ones((4, 4, 1))[::2,:,:]
+    if NPY_RELAXED_STRIDES_CHECKING:
+        a.strides = a.strides[:2] + (-123,)
+    b = np.ones((2, 2, 1, 2, 2)).swapaxes(3, 4)
+
+    def check_contig(a, ccontig, fcontig):
+        assert_(a.flags.c_contiguous == ccontig)
+        assert_(a.flags.f_contiguous == fcontig)
+
+    # Check if new arrays are correct:
+    check_contig(a, False, False)
+    check_contig(b, False, False)
+    if NPY_RELAXED_STRIDES_CHECKING:
+        check_contig(np.empty((2, 2, 0, 2, 2)), True, True)
+        check_contig(np.array([[[1], [2]]], order='F'), True, True)
+    else:
+        check_contig(np.empty((2, 2, 0, 2, 2)), True, False)
+        check_contig(np.array([[[1], [2]]], order='F'), False, True)
+    check_contig(np.empty((2, 2)), True, False)
+    check_contig(np.empty((2, 2), order='F'), False, True)
+
+    # Check that np.array creates correct contiguous flags:
+    check_contig(np.array(a, copy=False), False, False)
+    check_contig(np.array(a, copy=False, order='C'), True, False)
+    check_contig(np.array(a, ndmin=4, copy=False, order='F'), False, True)
+
+    if NPY_RELAXED_STRIDES_CHECKING:
+        # Check slicing update of flags and :
+        check_contig(a[0], True, True)
+        check_contig(a[None, ::4, ..., None], True, True)
+        check_contig(b[0, 0, ...], False, True)
+        check_contig(b[:,:, 0:0,:,:], True, True)
+    else:
+        # Check slicing update of flags:
+        check_contig(a[0], True, False)
+        # Would be nice if this was C-Contiguous:
+        check_contig(a[None, 0, ..., None], False, False)
+        check_contig(b[0, 0, 0, ...], False, True)
+
+    # Test ravel and squeeze.
+    check_contig(a.ravel(), True, True)
+    check_contig(np.ones((1, 3, 1)).squeeze(), True, True)
+
+def test_broadcast_arrays():
+    # Test user defined dtypes
+    a = np.array([(1, 2, 3)], dtype='u4,u4,u4')
+    b = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4')
+    result = np.broadcast_arrays(a, b)
+    assert_equal(result[0], np.array([(1, 2, 3), (1, 2, 3), (1, 2, 3)], dtype='u4,u4,u4'))
+    assert_equal(result[1], np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4'))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
new file mode 100644
index 0000000000..f89f4b291a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import sixu
+from numpy.testing import (
+     TestCase, run_module_suite, assert_, assert_equal
+)
+
+class TestArrayRepr(object):
+    def test_nan_inf(self):
+        x = np.array([np.nan, np.inf])
+        assert_equal(repr(x), 'array([ nan,  inf])')
+
+class TestComplexArray(TestCase):
+    def test_str(self):
+        rvals = [0, 1, -1, np.inf, -np.inf, np.nan]
+        cvals = [complex(rp, ip) for rp in rvals for ip in rvals]
+        dtypes = [np.complex64, np.cdouble, np.clongdouble]
+        actual = [str(np.array([c], dt)) for c in cvals for dt in dtypes]
+        wanted = [
+            '[ 0.+0.j]',    '[ 0.+0.j]',    '[ 0.0+0.0j]',
+            '[ 0.+1.j]',    '[ 0.+1.j]',    '[ 0.0+1.0j]',
+            '[ 0.-1.j]',    '[ 0.-1.j]',    '[ 0.0-1.0j]',
+            '[ 0.+infj]',   '[ 0.+infj]',   '[ 0.0+infj]',
+            '[ 0.-infj]',   '[ 0.-infj]',   '[ 0.0-infj]',
+            '[ 0.+nanj]',   '[ 0.+nanj]',   '[ 0.0+nanj]',
+            '[ 1.+0.j]',    '[ 1.+0.j]',    '[ 1.0+0.0j]',
+            '[ 1.+1.j]',    '[ 1.+1.j]',    '[ 1.0+1.0j]',
+            '[ 1.-1.j]',    '[ 1.-1.j]',    '[ 1.0-1.0j]',
+            '[ 1.+infj]',   '[ 1.+infj]',   '[ 1.0+infj]',
+            '[ 1.-infj]',   '[ 1.-infj]',   '[ 1.0-infj]',
+            '[ 1.+nanj]',   '[ 1.+nanj]',   '[ 1.0+nanj]',
+            '[-1.+0.j]',    '[-1.+0.j]',    '[-1.0+0.0j]',
+            '[-1.+1.j]',    '[-1.+1.j]',    '[-1.0+1.0j]',
+            '[-1.-1.j]',    '[-1.-1.j]',    '[-1.0-1.0j]',
+            '[-1.+infj]',   '[-1.+infj]',   '[-1.0+infj]',
+            '[-1.-infj]',   '[-1.-infj]',   '[-1.0-infj]',
+            '[-1.+nanj]',   '[-1.+nanj]',   '[-1.0+nanj]',
+            '[ inf+0.j]',   '[ inf+0.j]',   '[ inf+0.0j]',
+            '[ inf+1.j]',   '[ inf+1.j]',   '[ inf+1.0j]',
+            '[ inf-1.j]',   '[ inf-1.j]',   '[ inf-1.0j]',
+            '[ inf+infj]',  '[ inf+infj]',  '[ inf+infj]',
+            '[ inf-infj]',  '[ inf-infj]',  '[ inf-infj]',
+            '[ inf+nanj]',  '[ inf+nanj]',  '[ inf+nanj]',
+            '[-inf+0.j]',   '[-inf+0.j]',   '[-inf+0.0j]',
+            '[-inf+1.j]',   '[-inf+1.j]',   '[-inf+1.0j]',
+            '[-inf-1.j]',   '[-inf-1.j]',   '[-inf-1.0j]',
+            '[-inf+infj]',  '[-inf+infj]',  '[-inf+infj]',
+            '[-inf-infj]',  '[-inf-infj]',  '[-inf-infj]',
+            '[-inf+nanj]',  '[-inf+nanj]',  '[-inf+nanj]',
+            '[ nan+0.j]',   '[ nan+0.j]',   '[ nan+0.0j]',
+            '[ nan+1.j]',   '[ nan+1.j]',   '[ nan+1.0j]',
+            '[ nan-1.j]',   '[ nan-1.j]',   '[ nan-1.0j]',
+            '[ nan+infj]',  '[ nan+infj]',  '[ nan+infj]',
+            '[ nan-infj]',  '[ nan-infj]',  '[ nan-infj]',
+            '[ nan+nanj]',  '[ nan+nanj]',  '[ nan+nanj]']
+
+        for res, val in zip(actual, wanted):
+            assert_(res == val)
+
+class TestArray2String(TestCase):
+    def test_basic(self):
+        """Basic test of array2string."""
+        a = np.arange(3)
+        assert_(np.array2string(a) == '[0 1 2]')
+        assert_(np.array2string(a, max_line_width=4) == '[0 1\n 2]')
+
+    def test_style_keyword(self):
+        """This should only apply to 0-D arrays. See #1218."""
+        stylestr = np.array2string(np.array(1.5),
+                                   style=lambda x: "Value in 0-D array: " + str(x))
+        assert_(stylestr == 'Value in 0-D array: 1.5')
+
+    def test_format_function(self):
+        """Test custom format function for each element in array."""
+        def _format_function(x):
+            if np.abs(x) < 1:
+                return '.'
+            elif np.abs(x) < 2:
+                return 'o'
+            else:
+                return 'O'
+
+        x = np.arange(3)
+        if sys.version_info[0] >= 3:
+            x_hex = "[0x0 0x1 0x2]"
+            x_oct = "[0o0 0o1 0o2]"
+        else:
+            x_hex = "[0x0L 0x1L 0x2L]"
+            x_oct = "[0L 01L 02L]"
+        assert_(np.array2string(x, formatter={'all':_format_function}) ==
+                "[. o O]")
+        assert_(np.array2string(x, formatter={'int_kind':_format_function}) ==
+                "[. o O]")
+        assert_(np.array2string(x, formatter={'all':lambda x: "%.4f" % x}) ==
+                "[0.0000 1.0000 2.0000]")
+        assert_equal(np.array2string(x, formatter={'int':lambda x: hex(x)}),
+                x_hex)
+        assert_equal(np.array2string(x, formatter={'int':lambda x: oct(x)}),
+                x_oct)
+
+        x = np.arange(3.)
+        assert_(np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) ==
+                "[0.00 1.00 2.00]")
+        assert_(np.array2string(x, formatter={'float':lambda x: "%.2f" % x}) ==
+                "[0.00 1.00 2.00]")
+
+        s = np.array(['abc', 'def'])
+        assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) ==
+                '[abcabc defdef]')
+
+
+class TestPrintOptions:
+    """Test getting and setting global print options."""
+
+    def setUp(self):
+        self.oldopts = np.get_printoptions()
+
+    def tearDown(self):
+        np.set_printoptions(**self.oldopts)
+
+    def test_basic(self):
+        x = np.array([1.5, 0, 1.234567890])
+        assert_equal(repr(x), "array([ 1.5       ,  0.        ,  1.23456789])")
+        np.set_printoptions(precision=4)
+        assert_equal(repr(x), "array([ 1.5   ,  0.    ,  1.2346])")
+
+    def test_formatter(self):
+        x = np.arange(3)
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+
+    def test_formatter_reset(self):
+        x = np.arange(3)
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'int':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        np.set_printoptions(formatter={'all':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'all':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        np.set_printoptions(formatter={'int':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1, 0, 1])")
+        np.set_printoptions(formatter={'int_kind':None})
+        assert_equal(repr(x), "array([0, 1, 2])")
+
+        x = np.arange(3.)
+        np.set_printoptions(formatter={'float':lambda x: str(x-1)})
+        assert_equal(repr(x), "array([-1.0, 0.0, 1.0])")
+        np.set_printoptions(formatter={'float_kind':None})
+        assert_equal(repr(x), "array([ 0.,  1.,  2.])")
+
+def test_unicode_object_array():
+    import sys
+    if sys.version_info[0] >= 3:
+        expected = "array(['é'], dtype=object)"
+    else:
+        expected = "array([u'\\xe9'], dtype=object)"
+    x = np.array([sixu('\xe9')], dtype=object)
+    assert_equal(repr(x), expected)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
new file mode 100644
index 0000000000..601f09c091
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
@@ -0,0 +1,1909 @@
+from __future__ import division, absolute_import, print_function
+
+import pickle
+import warnings
+
+import numpy
+import numpy as np
+import datetime
+from numpy.compat import asbytes
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_warns, dec
+)
+
+# Use pytz to test out various time zones if available
+try:
+    from pytz import timezone as tz
+    _has_pytz = True
+except ImportError:
+    _has_pytz = False
+
+
+class TestDateTime(TestCase):
+    def test_datetime_dtype_creation(self):
+        for unit in ['Y', 'M', 'W', 'D',
+                     'h', 'm', 's', 'ms', 'us',
+                     'ns', 'ps', 'fs', 'as']:
+            dt1 = np.dtype('M8[750%s]' % unit)
+            assert_(dt1 == np.dtype('datetime64[750%s]' % unit))
+            dt2 = np.dtype('m8[%s]' % unit)
+            assert_(dt2 == np.dtype('timedelta64[%s]' % unit))
+
+        # Generic units shouldn't add [] to the end
+        assert_equal(str(np.dtype("M8")), "datetime64")
+
+        # Should be possible to specify the endianness
+        assert_equal(np.dtype("=M8"), np.dtype("M8"))
+        assert_equal(np.dtype("=M8[s]"), np.dtype("M8[s]"))
+        assert_(np.dtype(">M8") == np.dtype("M8") or
+                np.dtype("<M8") == np.dtype("M8"))
+        assert_(np.dtype(">M8[D]") == np.dtype("M8[D]") or
+                np.dtype("<M8[D]") == np.dtype("M8[D]"))
+        assert_(np.dtype(">M8") != np.dtype("<M8"))
+
+        assert_equal(np.dtype("=m8"), np.dtype("m8"))
+        assert_equal(np.dtype("=m8[s]"), np.dtype("m8[s]"))
+        assert_(np.dtype(">m8") == np.dtype("m8") or
+                np.dtype("<m8") == np.dtype("m8"))
+        assert_(np.dtype(">m8[D]") == np.dtype("m8[D]") or
+                np.dtype("<m8[D]") == np.dtype("m8[D]"))
+        assert_(np.dtype(">m8") != np.dtype("<m8"))
+
+        # Check that the parser rejects bad datetime types
+        assert_raises(TypeError, np.dtype, 'M8[badunit]')
+        assert_raises(TypeError, np.dtype, 'm8[badunit]')
+        assert_raises(TypeError, np.dtype, 'M8[YY]')
+        assert_raises(TypeError, np.dtype, 'm8[YY]')
+        assert_raises(TypeError, np.dtype, 'm4')
+        assert_raises(TypeError, np.dtype, 'M7')
+        assert_raises(TypeError, np.dtype, 'm7')
+        assert_raises(TypeError, np.dtype, 'M16')
+        assert_raises(TypeError, np.dtype, 'm16')
+
+    def test_datetime_casting_rules(self):
+        # Cannot cast safely/same_kind between timedelta and datetime
+        assert_(not np.can_cast('m8', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('M8', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('m8', 'M8', casting='safe'))
+        assert_(not np.can_cast('M8', 'm8', casting='safe'))
+
+        # Can cast safely/same_kind from integer to timedelta
+        assert_(np.can_cast('i8', 'm8', casting='same_kind'))
+        assert_(np.can_cast('i8', 'm8', casting='safe'))
+
+        # Cannot cast safely/same_kind from float to timedelta
+        assert_(not np.can_cast('f4', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('f4', 'm8', casting='safe'))
+
+        # Cannot cast safely/same_kind from integer to datetime
+        assert_(not np.can_cast('i8', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('i8', 'M8', casting='safe'))
+
+        # Cannot cast safely/same_kind from bool to datetime
+        assert_(not np.can_cast('b1', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('b1', 'M8', casting='safe'))
+        # Can cast safely/same_kind from bool to timedelta
+        assert_(np.can_cast('b1', 'm8', casting='same_kind'))
+        assert_(np.can_cast('b1', 'm8', casting='safe'))
+
+        # Can cast datetime safely from months/years to days
+        assert_(np.can_cast('M8[M]', 'M8[D]', casting='safe'))
+        assert_(np.can_cast('M8[Y]', 'M8[D]', casting='safe'))
+        # Cannot cast timedelta safely from months/years to days
+        assert_(not np.can_cast('m8[M]', 'm8[D]', casting='safe'))
+        assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='safe'))
+        # Can cast datetime same_kind from months/years to days
+        assert_(np.can_cast('M8[M]', 'M8[D]', casting='same_kind'))
+        assert_(np.can_cast('M8[Y]', 'M8[D]', casting='same_kind'))
+        # Can't cast timedelta same_kind from months/years to days
+        assert_(not np.can_cast('m8[M]', 'm8[D]', casting='same_kind'))
+        assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='same_kind'))
+        # Can cast datetime same_kind across the date/time boundary
+        assert_(np.can_cast('M8[D]', 'M8[h]', casting='same_kind'))
+        # Can cast timedelta same_kind across the date/time boundary
+        assert_(np.can_cast('m8[D]', 'm8[h]', casting='same_kind'))
+        assert_(np.can_cast('m8[h]', 'm8[D]', casting='same_kind'))
+
+        # Cannot cast safely if the integer multiplier doesn't divide
+        assert_(not np.can_cast('M8[7h]', 'M8[3h]', casting='safe'))
+        assert_(not np.can_cast('M8[3h]', 'M8[6h]', casting='safe'))
+        # But can cast same_kind
+        assert_(np.can_cast('M8[7h]', 'M8[3h]', casting='same_kind'))
+        # Can cast safely if the integer multiplier does divide
+        assert_(np.can_cast('M8[6h]', 'M8[3h]', casting='safe'))
+
+        # We can always cast types with generic units (corresponding to NaT) to
+        # more specific types
+        assert_(np.can_cast('m8', 'm8[h]', casting='same_kind'))
+        assert_(np.can_cast('m8', 'm8[h]', casting='safe'))
+        assert_(np.can_cast('M8', 'M8[h]', casting='same_kind'))
+        assert_(np.can_cast('M8', 'M8[h]', casting='safe'))
+        # but not the other way around
+        assert_(not np.can_cast('m8[h]', 'm8', casting='same_kind'))
+        assert_(not np.can_cast('m8[h]', 'm8', casting='safe'))
+        assert_(not np.can_cast('M8[h]', 'M8', casting='same_kind'))
+        assert_(not np.can_cast('M8[h]', 'M8', casting='safe'))
+
+    def test_compare_generic_nat(self):
+        # regression tests for GH6452
+        assert_equal(np.datetime64('NaT'),
+                     np.datetime64('2000') + np.timedelta64('NaT'))
+        # nb. we may want to make NaT != NaT true in the future; this test
+        # verifies the existing behavior (and that it should not warn)
+        assert_(np.datetime64('NaT') == np.datetime64('NaT', 'us'))
+        assert_(np.datetime64('NaT', 'us') == np.datetime64('NaT'))
+
+    def test_datetime_scalar_construction(self):
+        # Construct with different units
+        assert_equal(np.datetime64('1950-03-12', 'D'),
+                     np.datetime64('1950-03-12'))
+        assert_equal(np.datetime64('1950-03-12T13', 's'),
+                     np.datetime64('1950-03-12T13', 'm'))
+
+        # Default construction means NaT
+        assert_equal(np.datetime64(), np.datetime64('NaT'))
+
+        # Some basic strings and repr
+        assert_equal(str(np.datetime64('NaT')), 'NaT')
+        assert_equal(repr(np.datetime64('NaT')),
+                     "numpy.datetime64('NaT')")
+        assert_equal(str(np.datetime64('2011-02')), '2011-02')
+        assert_equal(repr(np.datetime64('2011-02')),
+                     "numpy.datetime64('2011-02')")
+
+        # None gets constructed as NaT
+        assert_equal(np.datetime64(None), np.datetime64('NaT'))
+
+        # Default construction of NaT is in generic units
+        assert_equal(np.datetime64().dtype, np.dtype('M8'))
+        assert_equal(np.datetime64('NaT').dtype, np.dtype('M8'))
+
+        # Construction from integers requires a specified unit
+        assert_raises(ValueError, np.datetime64, 17)
+
+        # When constructing from a scalar or zero-dimensional array,
+        # it either keeps the units or you can override them.
+        a = np.datetime64('2000-03-18T16', 'h')
+        b = np.array('2000-03-18T16', dtype='M8[h]')
+
+        assert_equal(a.dtype, np.dtype('M8[h]'))
+        assert_equal(b.dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(a), a)
+        assert_equal(np.datetime64(a).dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(b), a)
+        assert_equal(np.datetime64(b).dtype, np.dtype('M8[h]'))
+
+        assert_equal(np.datetime64(a, 's'), a)
+        assert_equal(np.datetime64(a, 's').dtype, np.dtype('M8[s]'))
+
+        assert_equal(np.datetime64(b, 's'), a)
+        assert_equal(np.datetime64(b, 's').dtype, np.dtype('M8[s]'))
+
+        # Construction from datetime.date
+        assert_equal(np.datetime64('1945-03-25'),
+                     np.datetime64(datetime.date(1945, 3, 25)))
+        assert_equal(np.datetime64('2045-03-25', 'D'),
+                     np.datetime64(datetime.date(2045, 3, 25), 'D'))
+        # Construction from datetime.datetime
+        assert_equal(np.datetime64('1980-01-25T14:36:22.5'),
+                     np.datetime64(datetime.datetime(1980, 1, 25,
+                                                14, 36, 22, 500000)))
+
+        # Construction with time units from a date is okay
+        assert_equal(np.datetime64('1920-03-13', 'h'),
+                     np.datetime64('1920-03-13T00'))
+        assert_equal(np.datetime64('1920-03', 'm'),
+                     np.datetime64('1920-03-01T00:00'))
+        assert_equal(np.datetime64('1920', 's'),
+                     np.datetime64('1920-01-01T00:00:00'))
+        assert_equal(np.datetime64(datetime.date(2045, 3, 25), 'ms'),
+                     np.datetime64('2045-03-25T00:00:00.000'))
+
+        # Construction with date units from a datetime is also okay
+        assert_equal(np.datetime64('1920-03-13T18', 'D'),
+                     np.datetime64('1920-03-13'))
+        assert_equal(np.datetime64('1920-03-13T18:33:12', 'M'),
+                     np.datetime64('1920-03'))
+        assert_equal(np.datetime64('1920-03-13T18:33:12.5', 'Y'),
+                     np.datetime64('1920'))
+
+    def test_datetime_scalar_construction_timezone(self):
+        # verify that supplying an explicit timezone works, but is deprecated
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('2000-01-01T00Z'),
+                         np.datetime64('2000-01-01T00'))
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('2000-01-01T00-08'),
+                         np.datetime64('2000-01-01T08'))
+
+    def test_datetime_array_find_type(self):
+        dt = np.datetime64('1970-01-01', 'M')
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('M8[M]'))
+
+        # at the moment, we don't automatically convert these to datetime64
+
+        dt = datetime.date(1970, 1, 1)
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.datetime(1970, 1, 1, 12, 30, 40)
+        arr = np.array([dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        # find "supertype" for non-dates and dates
+
+        b = np.bool_(True)
+        dt = np.datetime64('1970-01-01', 'M')
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.date(1970, 1, 1)
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+        dt = datetime.datetime(1970, 1, 1, 12, 30, 40)
+        arr = np.array([b, dt])
+        assert_equal(arr.dtype, np.dtype('O'))
+
+    def test_timedelta_scalar_construction(self):
+        # Construct with different units
+        assert_equal(np.timedelta64(7, 'D'),
+                     np.timedelta64(1, 'W'))
+        assert_equal(np.timedelta64(120, 's'),
+                     np.timedelta64(2, 'm'))
+
+        # Default construction means 0
+        assert_equal(np.timedelta64(), np.timedelta64(0))
+
+        # None gets constructed as NaT
+        assert_equal(np.timedelta64(None), np.timedelta64('NaT'))
+
+        # Some basic strings and repr
+        assert_equal(str(np.timedelta64('NaT')), 'NaT')
+        assert_equal(repr(np.timedelta64('NaT')),
+                     "numpy.timedelta64('NaT')")
+        assert_equal(str(np.timedelta64(3, 's')), '3 seconds')
+        assert_equal(repr(np.timedelta64(-3, 's')),
+                     "numpy.timedelta64(-3,'s')")
+        assert_equal(repr(np.timedelta64(12)),
+                     "numpy.timedelta64(12)")
+
+        # Construction from an integer produces generic units
+        assert_equal(np.timedelta64(12).dtype, np.dtype('m8'))
+
+        # When constructing from a scalar or zero-dimensional array,
+        # it either keeps the units or you can override them.
+        a = np.timedelta64(2, 'h')
+        b = np.array(2, dtype='m8[h]')
+
+        assert_equal(a.dtype, np.dtype('m8[h]'))
+        assert_equal(b.dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(a), a)
+        assert_equal(np.timedelta64(a).dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(b), a)
+        assert_equal(np.timedelta64(b).dtype, np.dtype('m8[h]'))
+
+        assert_equal(np.timedelta64(a, 's'), a)
+        assert_equal(np.timedelta64(a, 's').dtype, np.dtype('m8[s]'))
+
+        assert_equal(np.timedelta64(b, 's'), a)
+        assert_equal(np.timedelta64(b, 's').dtype, np.dtype('m8[s]'))
+
+        # Construction from datetime.timedelta
+        assert_equal(np.timedelta64(5, 'D'),
+                     np.timedelta64(datetime.timedelta(days=5)))
+        assert_equal(np.timedelta64(102347621, 's'),
+                     np.timedelta64(datetime.timedelta(seconds=102347621)))
+        assert_equal(np.timedelta64(-10234760000, 'us'),
+                     np.timedelta64(datetime.timedelta(
+                                            microseconds=-10234760000)))
+        assert_equal(np.timedelta64(10234760000, 'us'),
+                     np.timedelta64(datetime.timedelta(
+                                            microseconds=10234760000)))
+        assert_equal(np.timedelta64(1023476, 'ms'),
+                     np.timedelta64(datetime.timedelta(milliseconds=1023476)))
+        assert_equal(np.timedelta64(10, 'm'),
+                     np.timedelta64(datetime.timedelta(minutes=10)))
+        assert_equal(np.timedelta64(281, 'h'),
+                     np.timedelta64(datetime.timedelta(hours=281)))
+        assert_equal(np.timedelta64(28, 'W'),
+                     np.timedelta64(datetime.timedelta(weeks=28)))
+
+        # Cannot construct across nonlinear time unit boundaries
+        a = np.timedelta64(3, 's')
+        assert_raises(TypeError, np.timedelta64, a, 'M')
+        assert_raises(TypeError, np.timedelta64, a, 'Y')
+        a = np.timedelta64(6, 'M')
+        assert_raises(TypeError, np.timedelta64, a, 'D')
+        assert_raises(TypeError, np.timedelta64, a, 'h')
+        a = np.timedelta64(1, 'Y')
+        assert_raises(TypeError, np.timedelta64, a, 'D')
+        assert_raises(TypeError, np.timedelta64, a, 'm')
+
+    def test_timedelta_scalar_construction_units(self):
+        # String construction detecting units
+        assert_equal(np.datetime64('2010').dtype,
+                     np.dtype('M8[Y]'))
+        assert_equal(np.datetime64('2010-03').dtype,
+                     np.dtype('M8[M]'))
+        assert_equal(np.datetime64('2010-03-12').dtype,
+                     np.dtype('M8[D]'))
+        assert_equal(np.datetime64('2010-03-12T17').dtype,
+                     np.dtype('M8[h]'))
+        assert_equal(np.datetime64('2010-03-12T17:15').dtype,
+                     np.dtype('M8[m]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08').dtype,
+                     np.dtype('M8[s]'))
+
+        assert_equal(np.datetime64('2010-03-12T17:15:08.1').dtype,
+                     np.dtype('M8[ms]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.12').dtype,
+                     np.dtype('M8[ms]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.123').dtype,
+                     np.dtype('M8[ms]'))
+
+        assert_equal(np.datetime64('2010-03-12T17:15:08.1234').dtype,
+                     np.dtype('M8[us]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.12345').dtype,
+                     np.dtype('M8[us]'))
+        assert_equal(np.datetime64('2010-03-12T17:15:08.123456').dtype,
+                     np.dtype('M8[us]'))
+
+        assert_equal(np.datetime64('1970-01-01T00:00:02.1234567').dtype,
+                     np.dtype('M8[ns]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.12345678').dtype,
+                     np.dtype('M8[ns]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.123456789').dtype,
+                     np.dtype('M8[ns]'))
+
+        assert_equal(np.datetime64('1970-01-01T00:00:02.1234567890').dtype,
+                     np.dtype('M8[ps]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.12345678901').dtype,
+                     np.dtype('M8[ps]'))
+        assert_equal(np.datetime64('1970-01-01T00:00:02.123456789012').dtype,
+                     np.dtype('M8[ps]'))
+
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.1234567890123').dtype,
+                     np.dtype('M8[fs]'))
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.12345678901234').dtype,
+                     np.dtype('M8[fs]'))
+        assert_equal(np.datetime64(
+                     '1970-01-01T00:00:02.123456789012345').dtype,
+                     np.dtype('M8[fs]'))
+
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.1234567890123456').dtype,
+                     np.dtype('M8[as]'))
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.12345678901234567').dtype,
+                     np.dtype('M8[as]'))
+        assert_equal(np.datetime64(
+                    '1970-01-01T00:00:02.123456789012345678').dtype,
+                     np.dtype('M8[as]'))
+
+        # Python date object
+        assert_equal(np.datetime64(datetime.date(2010, 4, 16)).dtype,
+                     np.dtype('M8[D]'))
+
+        # Python datetime object
+        assert_equal(np.datetime64(
+                        datetime.datetime(2010, 4, 16, 13, 45, 18)).dtype,
+                     np.dtype('M8[us]'))
+
+        # 'today' special value
+        assert_equal(np.datetime64('today').dtype,
+                     np.dtype('M8[D]'))
+
+        # 'now' special value
+        assert_equal(np.datetime64('now').dtype,
+                     np.dtype('M8[s]'))
+
+    def test_datetime_nat_casting(self):
+        a = np.array('NaT', dtype='M8[D]')
+        b = np.datetime64('NaT', '[D]')
+
+        # Arrays
+        assert_equal(a.astype('M8[s]'), np.array('NaT', dtype='M8[s]'))
+        assert_equal(a.astype('M8[ms]'), np.array('NaT', dtype='M8[ms]'))
+        assert_equal(a.astype('M8[M]'), np.array('NaT', dtype='M8[M]'))
+        assert_equal(a.astype('M8[Y]'), np.array('NaT', dtype='M8[Y]'))
+        assert_equal(a.astype('M8[W]'), np.array('NaT', dtype='M8[W]'))
+
+        # Scalars -> Scalars
+        assert_equal(np.datetime64(b, '[s]'), np.datetime64('NaT', '[s]'))
+        assert_equal(np.datetime64(b, '[ms]'), np.datetime64('NaT', '[ms]'))
+        assert_equal(np.datetime64(b, '[M]'), np.datetime64('NaT', '[M]'))
+        assert_equal(np.datetime64(b, '[Y]'), np.datetime64('NaT', '[Y]'))
+        assert_equal(np.datetime64(b, '[W]'), np.datetime64('NaT', '[W]'))
+
+        # Arrays -> Scalars
+        assert_equal(np.datetime64(a, '[s]'), np.datetime64('NaT', '[s]'))
+        assert_equal(np.datetime64(a, '[ms]'), np.datetime64('NaT', '[ms]'))
+        assert_equal(np.datetime64(a, '[M]'), np.datetime64('NaT', '[M]'))
+        assert_equal(np.datetime64(a, '[Y]'), np.datetime64('NaT', '[Y]'))
+        assert_equal(np.datetime64(a, '[W]'), np.datetime64('NaT', '[W]'))
+
+    def test_days_creation(self):
+        assert_equal(np.array('1599', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3 - 365)
+        assert_equal(np.array('1600', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3)
+        assert_equal(np.array('1601', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)/4 + 3 + 366)
+        assert_equal(np.array('1900', dtype='M8[D]').astype('i8'),
+                (1900-1970)*365 - (1970-1900)//4)
+        assert_equal(np.array('1901', dtype='M8[D]').astype('i8'),
+                (1900-1970)*365 - (1970-1900)//4 + 365)
+        assert_equal(np.array('1967', dtype='M8[D]').astype('i8'), -3*365 - 1)
+        assert_equal(np.array('1968', dtype='M8[D]').astype('i8'), -2*365 - 1)
+        assert_equal(np.array('1969', dtype='M8[D]').astype('i8'), -1*365)
+        assert_equal(np.array('1970', dtype='M8[D]').astype('i8'), 0*365)
+        assert_equal(np.array('1971', dtype='M8[D]').astype('i8'), 1*365)
+        assert_equal(np.array('1972', dtype='M8[D]').astype('i8'), 2*365)
+        assert_equal(np.array('1973', dtype='M8[D]').astype('i8'), 3*365 + 1)
+        assert_equal(np.array('1974', dtype='M8[D]').astype('i8'), 4*365 + 1)
+        assert_equal(np.array('2000', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4)
+        assert_equal(np.array('2001', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 366)
+        assert_equal(np.array('2400', dtype='M8[D]').astype('i8'),
+                 (2400 - 1970)*365 + (2400 - 1972)//4 - 3)
+        assert_equal(np.array('2401', dtype='M8[D]').astype('i8'),
+                 (2400 - 1970)*365 + (2400 - 1972)//4 - 3 + 366)
+
+        assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 28)
+        assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('i8'),
+                (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 29)
+        assert_equal(np.array('2000-02-29', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 28)
+        assert_equal(np.array('2000-03-01', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 29)
+        assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('i8'),
+                 (2000 - 1970)*365 + (2000 - 1972)//4 + 366 + 31 + 28 + 21)
+
+    def test_days_to_pydate(self):
+        assert_equal(np.array('1599', dtype='M8[D]').astype('O'),
+                    datetime.date(1599, 1, 1))
+        assert_equal(np.array('1600', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 1, 1))
+        assert_equal(np.array('1601', dtype='M8[D]').astype('O'),
+                    datetime.date(1601, 1, 1))
+        assert_equal(np.array('1900', dtype='M8[D]').astype('O'),
+                    datetime.date(1900, 1, 1))
+        assert_equal(np.array('1901', dtype='M8[D]').astype('O'),
+                    datetime.date(1901, 1, 1))
+        assert_equal(np.array('2000', dtype='M8[D]').astype('O'),
+                    datetime.date(2000, 1, 1))
+        assert_equal(np.array('2001', dtype='M8[D]').astype('O'),
+                    datetime.date(2001, 1, 1))
+        assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 2, 29))
+        assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('O'),
+                    datetime.date(1600, 3, 1))
+        assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('O'),
+                    datetime.date(2001, 3, 22))
+
+    def test_dtype_comparison(self):
+        assert_(not (np.dtype('M8[us]') == np.dtype('M8[ms]')))
+        assert_(np.dtype('M8[us]') != np.dtype('M8[ms]'))
+        assert_(np.dtype('M8[2D]') != np.dtype('M8[D]'))
+        assert_(np.dtype('M8[D]') != np.dtype('M8[2D]'))
+
+    def test_pydatetime_creation(self):
+        a = np.array(['1960-03-12', datetime.date(1960, 3, 12)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        a = np.array(['1999-12-31', datetime.date(1999, 12, 31)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        a = np.array(['2000-01-01', datetime.date(2000, 1, 1)], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        # Will fail if the date changes during the exact right moment
+        a = np.array(['today', datetime.date.today()], dtype='M8[D]')
+        assert_equal(a[0], a[1])
+        # datetime.datetime.now() returns local time, not UTC
+        #a = np.array(['now', datetime.datetime.now()], dtype='M8[s]')
+        #assert_equal(a[0], a[1])
+
+        # we can give a datetime.date time units
+        assert_equal(np.array(datetime.date(1960, 3, 12), dtype='M8[s]'),
+                     np.array(np.datetime64('1960-03-12T00:00:00')))
+
+    def test_datetime_string_conversion(self):
+        a = ['2011-03-16', '1920-01-01', '2013-05-19']
+        str_a = np.array(a, dtype='S')
+        dt_a = np.array(a, dtype='M')
+        str_b = np.empty_like(str_a)
+        dt_b = np.empty_like(dt_a)
+
+        # String to datetime
+        assert_equal(dt_a, str_a.astype('M'))
+        assert_equal(dt_a.dtype, str_a.astype('M').dtype)
+        dt_b[...] = str_a
+        assert_equal(dt_a, dt_b)
+        # Datetime to string
+        assert_equal(str_a, dt_a.astype('S0'))
+        str_b[...] = dt_a
+        assert_equal(str_a, str_b)
+
+        # Convert the 'S' to 'U'
+        str_a = str_a.astype('U')
+        str_b = str_b.astype('U')
+
+        # Unicode to datetime
+        assert_equal(dt_a, str_a.astype('M'))
+        assert_equal(dt_a.dtype, str_a.astype('M').dtype)
+        dt_b[...] = str_a
+        assert_equal(dt_a, dt_b)
+        # Datetime to unicode
+        assert_equal(str_a, dt_a.astype('U'))
+        str_b[...] = dt_a
+        assert_equal(str_a, str_b)
+
+    def test_datetime_array_str(self):
+        a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M')
+        assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']")
+
+        a = np.array(['2011-03-16T13:55', '1920-01-01T03:12'], dtype='M')
+        assert_equal(np.array2string(a, separator=', ',
+                    formatter={'datetime': lambda x:
+                            "'%s'" % np.datetime_as_string(x, timezone='UTC')}),
+                     "['2011-03-16T13:55Z', '1920-01-01T03:12Z']")
+
+        # Check that one NaT doesn't corrupt subsequent entries
+        a = np.array(['2010', 'NaT', '2030']).astype('M')
+        assert_equal(str(a), "['2010' 'NaT' '2030']")
+
+    def test_timedelta_array_str(self):
+        a = np.array([-1, 0, 100], dtype='m')
+        assert_equal(str(a), "[ -1   0 100]")
+        a = np.array(['NaT', 'NaT'], dtype='m')
+        assert_equal(str(a), "['NaT' 'NaT']")
+        # Check right-alignment with NaTs
+        a = np.array([-1, 'NaT', 0], dtype='m')
+        assert_equal(str(a), "[   -1 'NaT'     0]")
+        a = np.array([-1, 'NaT', 1234567], dtype='m')
+        assert_equal(str(a), "[     -1   'NaT' 1234567]")
+
+    def test_pickle(self):
+        # Check that pickle roundtripping works
+        dt = np.dtype('M8[7D]')
+        assert_equal(pickle.loads(pickle.dumps(dt)), dt)
+        dt = np.dtype('M8[W]')
+        assert_equal(pickle.loads(pickle.dumps(dt)), dt)
+
+        # Check that loading pickles from 1.6 works
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'D'\np6\n" + \
+              "I7\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('<M8[7D]'))
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'W'\np6\n" + \
+              "I1\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('<M8[W]'))
+        pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \
+              "(I4\nS'>'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'us'\np6\n" + \
+              "I1\nI1\nI1\ntp7\ntp8\ntp9\nb."
+        assert_equal(pickle.loads(asbytes(pkl)), np.dtype('>M8[us]'))
+
+    def test_setstate(self):
+        "Verify that datetime dtype __setstate__ can handle bad arguments"
+        dt = np.dtype('>M8[us]')
+        assert_raises(ValueError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, 1))
+        assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2])
+        assert_raises(TypeError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, ({}, 'xxx')))
+        assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2])
+
+    def test_dtype_promotion(self):
+        # datetime <op> datetime computes the metadata gcd
+        # timedelta <op> timedelta computes the metadata gcd
+        for mM in ['m', 'M']:
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[2Y]'), np.dtype(mM+'8[2Y]')),
+                np.dtype(mM+'8[2Y]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[12Y]'), np.dtype(mM+'8[15Y]')),
+                np.dtype(mM+'8[3Y]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[62M]'), np.dtype(mM+'8[24M]')),
+                np.dtype(mM+'8[2M]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[1W]'), np.dtype(mM+'8[2D]')),
+                np.dtype(mM+'8[1D]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[W]'), np.dtype(mM+'8[13s]')),
+                np.dtype(mM+'8[s]'))
+            assert_equal(
+                np.promote_types(np.dtype(mM+'8[13W]'), np.dtype(mM+'8[49s]')),
+                np.dtype(mM+'8[7s]'))
+        # timedelta <op> timedelta raises when there is no reasonable gcd
+        assert_raises(TypeError, np.promote_types,
+                            np.dtype('m8[Y]'), np.dtype('m8[D]'))
+        assert_raises(TypeError, np.promote_types,
+                            np.dtype('m8[M]'), np.dtype('m8[W]'))
+        # timedelta <op> timedelta may overflow with big unit ranges
+        assert_raises(OverflowError, np.promote_types,
+                            np.dtype('m8[W]'), np.dtype('m8[fs]'))
+        assert_raises(OverflowError, np.promote_types,
+                            np.dtype('m8[s]'), np.dtype('m8[as]'))
+
+    def test_cast_overflow(self):
+        # gh-4486
+        def cast():
+            numpy.datetime64("1971-01-01 00:00:00.000000000000000").astype("<M8[D]")
+        assert_raises(OverflowError, cast)
+
+        def cast2():
+            numpy.datetime64("2014").astype("<M8[fs]")
+        assert_raises(OverflowError, cast2)
+
+    def test_pyobject_roundtrip(self):
+        # All datetime types should be able to roundtrip through object
+        a = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0,
+                      -1020040340, -2942398, -1, 0, 1, 234523453, 1199164176],
+                                                        dtype=np.int64)
+        # With date units
+        for unit in ['M8[D]', 'M8[W]', 'M8[M]', 'M8[Y]']:
+            b = a.copy().view(dtype=unit)
+            b[0] = '-0001-01-01'
+            b[1] = '-0001-12-31'
+            b[2] = '0000-01-01'
+            b[3] = '0001-01-01'
+            b[4] = '1969-12-31'
+            b[5] = '1970-01-01'
+            b[6] = '9999-12-31'
+            b[7] = '10000-01-01'
+            b[8] = 'NaT'
+
+            assert_equal(b.astype(object).astype(unit), b,
+                            "Error roundtripping unit %s" % unit)
+        # With time units
+        for unit in ['M8[as]', 'M8[16fs]', 'M8[ps]', 'M8[us]',
+                     'M8[300as]', 'M8[20us]']:
+            b = a.copy().view(dtype=unit)
+            b[0] = '-0001-01-01T00'
+            b[1] = '-0001-12-31T00'
+            b[2] = '0000-01-01T00'
+            b[3] = '0001-01-01T00'
+            b[4] = '1969-12-31T23:59:59.999999'
+            b[5] = '1970-01-01T00'
+            b[6] = '9999-12-31T23:59:59.999999'
+            b[7] = '10000-01-01T00'
+            b[8] = 'NaT'
+
+            assert_equal(b.astype(object).astype(unit), b,
+                            "Error roundtripping unit %s" % unit)
+
+    def test_month_truncation(self):
+        # Make sure that months are truncating correctly
+        assert_equal(np.array('1945-03-01', dtype='M8[M]'),
+                     np.array('1945-03-31', dtype='M8[M]'))
+        assert_equal(np.array('1969-11-01', dtype='M8[M]'),
+             np.array('1969-11-30T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1969-12-01', dtype='M8[M]'),
+             np.array('1969-12-31T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1970-01-01', dtype='M8[M]'),
+             np.array('1970-01-31T23:59:59.99999', dtype='M').astype('M8[M]'))
+        assert_equal(np.array('1980-02-01', dtype='M8[M]'),
+             np.array('1980-02-29T23:59:59.99999', dtype='M').astype('M8[M]'))
+
+    def test_different_unit_comparison(self):
+        # Check some years with date units
+        for unit1 in ['Y', 'M', 'D']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['Y', 'M', 'D']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_equal(np.array('1945', dtype=dt1),
+                             np.array('1945', dtype=dt2))
+                assert_equal(np.array('1970', dtype=dt1),
+                             np.array('1970', dtype=dt2))
+                assert_equal(np.array('9999', dtype=dt1),
+                             np.array('9999', dtype=dt2))
+                assert_equal(np.array('10000', dtype=dt1),
+                             np.array('10000-01-01', dtype=dt2))
+                assert_equal(np.datetime64('1945', unit1),
+                             np.datetime64('1945', unit2))
+                assert_equal(np.datetime64('1970', unit1),
+                             np.datetime64('1970', unit2))
+                assert_equal(np.datetime64('9999', unit1),
+                             np.datetime64('9999', unit2))
+                assert_equal(np.datetime64('10000', unit1),
+                             np.datetime64('10000-01-01', unit2))
+        # Check some datetimes with time units
+        for unit1 in ['6h', 'h', 'm', 's', '10ms', 'ms', 'us']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['h', 'm', 's', 'ms', 'us']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_equal(np.array('1945-03-12T18', dtype=dt1),
+                             np.array('1945-03-12T18', dtype=dt2))
+                assert_equal(np.array('1970-03-12T18', dtype=dt1),
+                             np.array('1970-03-12T18', dtype=dt2))
+                assert_equal(np.array('9999-03-12T18', dtype=dt1),
+                             np.array('9999-03-12T18', dtype=dt2))
+                assert_equal(np.array('10000-01-01T00', dtype=dt1),
+                             np.array('10000-01-01T00', dtype=dt2))
+                assert_equal(np.datetime64('1945-03-12T18', unit1),
+                             np.datetime64('1945-03-12T18', unit2))
+                assert_equal(np.datetime64('1970-03-12T18', unit1),
+                             np.datetime64('1970-03-12T18', unit2))
+                assert_equal(np.datetime64('9999-03-12T18', unit1),
+                             np.datetime64('9999-03-12T18', unit2))
+                assert_equal(np.datetime64('10000-01-01T00', unit1),
+                             np.datetime64('10000-01-01T00', unit2))
+        # Check some days with units that won't overflow
+        for unit1 in ['D', '12h', 'h', 'm', 's', '4s', 'ms', 'us']:
+            dt1 = np.dtype('M8[%s]' % unit1)
+            for unit2 in ['D', 'h', 'm', 's', 'ms', 'us']:
+                dt2 = np.dtype('M8[%s]' % unit2)
+                assert_(np.equal(np.array('1932-02-17', dtype='M').astype(dt1),
+                     np.array('1932-02-17T00:00:00', dtype='M').astype(dt2),
+                     casting='unsafe'))
+                assert_(np.equal(np.array('10000-04-27', dtype='M').astype(dt1),
+                     np.array('10000-04-27T00:00:00', dtype='M').astype(dt2),
+                     casting='unsafe'))
+
+        # Shouldn't be able to compare datetime and timedelta
+        # TODO: Changing to 'same_kind' or 'safe' casting in the ufuncs by
+        #       default is needed to properly catch this kind of thing...
+        a = np.array('2012-12-21', dtype='M8[D]')
+        b = np.array(3, dtype='m8[D]')
+        #assert_raises(TypeError, np.less, a, b)
+        assert_raises(TypeError, np.less, a, b, casting='same_kind')
+
+    def test_datetime_like(self):
+        a = np.array([3], dtype='m8[4D]')
+        b = np.array(['2012-12-21'], dtype='M8[D]')
+
+        assert_equal(np.ones_like(a).dtype, a.dtype)
+        assert_equal(np.zeros_like(a).dtype, a.dtype)
+        assert_equal(np.empty_like(a).dtype, a.dtype)
+        assert_equal(np.ones_like(b).dtype, b.dtype)
+        assert_equal(np.zeros_like(b).dtype, b.dtype)
+        assert_equal(np.empty_like(b).dtype, b.dtype)
+
+    def test_datetime_unary(self):
+        for tda, tdb, tdzero, tdone, tdmone in \
+                [
+                 # One-dimensional arrays
+                 (np.array([3], dtype='m8[D]'),
+                  np.array([-3], dtype='m8[D]'),
+                  np.array([0], dtype='m8[D]'),
+                  np.array([1], dtype='m8[D]'),
+                  np.array([-1], dtype='m8[D]')),
+                 # NumPy scalars
+                 (np.timedelta64(3, '[D]'),
+                  np.timedelta64(-3, '[D]'),
+                  np.timedelta64(0, '[D]'),
+                  np.timedelta64(1, '[D]'),
+                  np.timedelta64(-1, '[D]'))]:
+            # negative ufunc
+            assert_equal(-tdb, tda)
+            assert_equal((-tdb).dtype, tda.dtype)
+            assert_equal(np.negative(tdb), tda)
+            assert_equal(np.negative(tdb).dtype, tda.dtype)
+
+            # absolute ufunc
+            assert_equal(np.absolute(tdb), tda)
+            assert_equal(np.absolute(tdb).dtype, tda.dtype)
+
+            # sign ufunc
+            assert_equal(np.sign(tda), tdone)
+            assert_equal(np.sign(tdb), tdmone)
+            assert_equal(np.sign(tdzero), tdzero)
+            assert_equal(np.sign(tda).dtype, tda.dtype)
+
+            # The ufuncs always produce native-endian results
+            assert_
+
+    def test_datetime_add(self):
+        for dta, dtb, dtc, dtnat, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array(['2012-12-24'], dtype='M8[D]'),
+                      np.array(['2012-12-21T11'], dtype='M8[h]'),
+                      np.array(['NaT'], dtype='M8[D]'),
+                      np.array([3], dtype='m8[D]'),
+                      np.array([11], dtype='m8[h]'),
+                      np.array([3*24 + 11], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.datetime64('2012-12-24', '[D]'),
+                      np.datetime64('2012-12-21T11', '[h]'),
+                      np.datetime64('NaT', '[D]'),
+                      np.timedelta64(3, '[D]'),
+                      np.timedelta64(11, '[h]'),
+                      np.timedelta64(3*24 + 11, '[h]'))]:
+            # m8 + m8
+            assert_equal(tda + tdb, tdc)
+            assert_equal((tda + tdb).dtype, np.dtype('m8[h]'))
+            # m8 + bool
+            assert_equal(tdb + True, tdb + 1)
+            assert_equal((tdb + True).dtype, np.dtype('m8[h]'))
+            # m8 + int
+            assert_equal(tdb + 3*24, tdc)
+            assert_equal((tdb + 3*24).dtype, np.dtype('m8[h]'))
+            # bool + m8
+            assert_equal(False + tdb, tdb)
+            assert_equal((False + tdb).dtype, np.dtype('m8[h]'))
+            # int + m8
+            assert_equal(3*24 + tdb, tdc)
+            assert_equal((3*24 + tdb).dtype, np.dtype('m8[h]'))
+            # M8 + bool
+            assert_equal(dta + True, dta + 1)
+            assert_equal(dtnat + True, dtnat)
+            assert_equal((dta + True).dtype, np.dtype('M8[D]'))
+            # M8 + int
+            assert_equal(dta + 3, dtb)
+            assert_equal(dtnat + 3, dtnat)
+            assert_equal((dta + 3).dtype, np.dtype('M8[D]'))
+            # bool + M8
+            assert_equal(False + dta, dta)
+            assert_equal(False + dtnat, dtnat)
+            assert_equal((False + dta).dtype, np.dtype('M8[D]'))
+            # int + M8
+            assert_equal(3 + dta, dtb)
+            assert_equal(3 + dtnat, dtnat)
+            assert_equal((3 + dta).dtype, np.dtype('M8[D]'))
+            # M8 + m8
+            assert_equal(dta + tda, dtb)
+            assert_equal(dtnat + tda, dtnat)
+            assert_equal((dta + tda).dtype, np.dtype('M8[D]'))
+            # m8 + M8
+            assert_equal(tda + dta, dtb)
+            assert_equal(tda + dtnat, dtnat)
+            assert_equal((tda + dta).dtype, np.dtype('M8[D]'))
+
+            # In M8 + m8, the result goes to higher precision
+            assert_equal(np.add(dta, tdb, casting='unsafe'), dtc)
+            assert_equal(np.add(dta, tdb, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+            assert_equal(np.add(tdb, dta, casting='unsafe'), dtc)
+            assert_equal(np.add(tdb, dta, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+
+            # M8 + M8
+            assert_raises(TypeError, np.add, dta, dtb)
+
+    def test_datetime_subtract(self):
+        for dta, dtb, dtc, dtd, dte, dtnat, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array(['2012-12-24'], dtype='M8[D]'),
+                      np.array(['1940-12-24'], dtype='M8[D]'),
+                      np.array(['1940-12-24T00'], dtype='M8[h]'),
+                      np.array(['1940-12-23T13'], dtype='M8[h]'),
+                      np.array(['NaT'], dtype='M8[D]'),
+                      np.array([3], dtype='m8[D]'),
+                      np.array([11], dtype='m8[h]'),
+                      np.array([3*24 - 11], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.datetime64('2012-12-24', '[D]'),
+                      np.datetime64('1940-12-24', '[D]'),
+                      np.datetime64('1940-12-24T00', '[h]'),
+                      np.datetime64('1940-12-23T13', '[h]'),
+                      np.datetime64('NaT', '[D]'),
+                      np.timedelta64(3, '[D]'),
+                      np.timedelta64(11, '[h]'),
+                      np.timedelta64(3*24 - 11, '[h]'))]:
+            # m8 - m8
+            assert_equal(tda - tdb, tdc)
+            assert_equal((tda - tdb).dtype, np.dtype('m8[h]'))
+            assert_equal(tdb - tda, -tdc)
+            assert_equal((tdb - tda).dtype, np.dtype('m8[h]'))
+            # m8 - bool
+            assert_equal(tdc - True, tdc - 1)
+            assert_equal((tdc - True).dtype, np.dtype('m8[h]'))
+            # m8 - int
+            assert_equal(tdc - 3*24, -tdb)
+            assert_equal((tdc - 3*24).dtype, np.dtype('m8[h]'))
+            # int - m8
+            assert_equal(False - tdb, -tdb)
+            assert_equal((False - tdb).dtype, np.dtype('m8[h]'))
+            # int - m8
+            assert_equal(3*24 - tdb, tdc)
+            assert_equal((3*24 - tdb).dtype, np.dtype('m8[h]'))
+            # M8 - bool
+            assert_equal(dtb - True, dtb - 1)
+            assert_equal(dtnat - True, dtnat)
+            assert_equal((dtb - True).dtype, np.dtype('M8[D]'))
+            # M8 - int
+            assert_equal(dtb - 3, dta)
+            assert_equal(dtnat - 3, dtnat)
+            assert_equal((dtb - 3).dtype, np.dtype('M8[D]'))
+            # M8 - m8
+            assert_equal(dtb - tda, dta)
+            assert_equal(dtnat - tda, dtnat)
+            assert_equal((dtb - tda).dtype, np.dtype('M8[D]'))
+
+            # In M8 - m8, the result goes to higher precision
+            assert_equal(np.subtract(dtc, tdb, casting='unsafe'), dte)
+            assert_equal(np.subtract(dtc, tdb, casting='unsafe').dtype,
+                         np.dtype('M8[h]'))
+
+            # M8 - M8 with different goes to higher precision
+            assert_equal(np.subtract(dtc, dtd, casting='unsafe'),
+                         np.timedelta64(0, 'h'))
+            assert_equal(np.subtract(dtc, dtd, casting='unsafe').dtype,
+                         np.dtype('m8[h]'))
+            assert_equal(np.subtract(dtd, dtc, casting='unsafe'),
+                         np.timedelta64(0, 'h'))
+            assert_equal(np.subtract(dtd, dtc, casting='unsafe').dtype,
+                         np.dtype('m8[h]'))
+
+            # m8 - M8
+            assert_raises(TypeError, np.subtract, tda, dta)
+            # bool - M8
+            assert_raises(TypeError, np.subtract, False, dta)
+            # int - M8
+            assert_raises(TypeError, np.subtract, 3, dta)
+
+    def test_datetime_multiply(self):
+        for dta, tda, tdb, tdc in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array([6], dtype='m8[h]'),
+                      np.array([9], dtype='m8[h]'),
+                      np.array([12], dtype='m8[h]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.timedelta64(6, '[h]'),
+                      np.timedelta64(9, '[h]'),
+                      np.timedelta64(12, '[h]'))]:
+            # m8 * int
+            assert_equal(tda * 2, tdc)
+            assert_equal((tda * 2).dtype, np.dtype('m8[h]'))
+            # int * m8
+            assert_equal(2 * tda, tdc)
+            assert_equal((2 * tda).dtype, np.dtype('m8[h]'))
+            # m8 * float
+            assert_equal(tda * 1.5, tdb)
+            assert_equal((tda * 1.5).dtype, np.dtype('m8[h]'))
+            # float * m8
+            assert_equal(1.5 * tda, tdb)
+            assert_equal((1.5 * tda).dtype, np.dtype('m8[h]'))
+
+            # m8 * m8
+            assert_raises(TypeError, np.multiply, tda, tdb)
+            # m8 * M8
+            assert_raises(TypeError, np.multiply, dta, tda)
+            # M8 * m8
+            assert_raises(TypeError, np.multiply, tda, dta)
+            # M8 * int
+            assert_raises(TypeError, np.multiply, dta, 2)
+            # int * M8
+            assert_raises(TypeError, np.multiply, 2, dta)
+            # M8 * float
+            assert_raises(TypeError, np.multiply, dta, 1.5)
+            # float * M8
+            assert_raises(TypeError, np.multiply, 1.5, dta)
+
+        # NaTs
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', category=RuntimeWarning)
+            nat = np.timedelta64('NaT')
+            def check(a, b, res):
+                assert_equal(a * b, res)
+                assert_equal(b * a, res)
+            for tp in (int, float):
+                check(nat, tp(2), nat)
+                check(nat, tp(0), nat)
+            for f in (float('inf'), float('nan')):
+                check(np.timedelta64(1), f, nat)
+                check(np.timedelta64(0), f, nat)
+                check(nat, f, nat)
+
+    def test_datetime_divide(self):
+        for dta, tda, tdb, tdc, tdd in \
+                    [
+                     # One-dimensional arrays
+                     (np.array(['2012-12-21'], dtype='M8[D]'),
+                      np.array([6], dtype='m8[h]'),
+                      np.array([9], dtype='m8[h]'),
+                      np.array([12], dtype='m8[h]'),
+                      np.array([6], dtype='m8[m]')),
+                     # NumPy scalars
+                     (np.datetime64('2012-12-21', '[D]'),
+                      np.timedelta64(6, '[h]'),
+                      np.timedelta64(9, '[h]'),
+                      np.timedelta64(12, '[h]'),
+                      np.timedelta64(6, '[m]'))]:
+            # m8 / int
+            assert_equal(tdc / 2, tda)
+            assert_equal((tdc / 2).dtype, np.dtype('m8[h]'))
+            # m8 / float
+            assert_equal(tda / 0.5, tdc)
+            assert_equal((tda / 0.5).dtype, np.dtype('m8[h]'))
+            # m8 / m8
+            assert_equal(tda / tdb, 6.0 / 9.0)
+            assert_equal(np.divide(tda, tdb), 6.0 / 9.0)
+            assert_equal(np.true_divide(tda, tdb), 6.0 / 9.0)
+            assert_equal(tdb / tda, 9.0 / 6.0)
+            assert_equal((tda / tdb).dtype, np.dtype('f8'))
+            assert_equal(tda / tdd, 60.0)
+            assert_equal(tdd / tda, 1.0 / 60.0)
+
+            # m8 // m8
+            assert_raises(TypeError, np.floor_divide, tda, tdb)
+            # int / m8
+            assert_raises(TypeError, np.divide, 2, tdb)
+            # float / m8
+            assert_raises(TypeError, np.divide, 0.5, tdb)
+            # m8 / M8
+            assert_raises(TypeError, np.divide, dta, tda)
+            # M8 / m8
+            assert_raises(TypeError, np.divide, tda, dta)
+            # M8 / int
+            assert_raises(TypeError, np.divide, dta, 2)
+            # int / M8
+            assert_raises(TypeError, np.divide, 2, dta)
+            # M8 / float
+            assert_raises(TypeError, np.divide, dta, 1.5)
+            # float / M8
+            assert_raises(TypeError, np.divide, 1.5, dta)
+
+        # NaTs
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', category=RuntimeWarning)
+            nat = np.timedelta64('NaT')
+            for tp in (int, float):
+                assert_equal(np.timedelta64(1) / tp(0), nat)
+                assert_equal(np.timedelta64(0) / tp(0), nat)
+                assert_equal(nat / tp(0), nat)
+                assert_equal(nat / tp(2), nat)
+            # Division by inf
+            assert_equal(np.timedelta64(1) / float('inf'), np.timedelta64(0))
+            assert_equal(np.timedelta64(0) / float('inf'), np.timedelta64(0))
+            assert_equal(nat / float('inf'), nat)
+            # Division by nan
+            assert_equal(np.timedelta64(1) / float('nan'), nat)
+            assert_equal(np.timedelta64(0) / float('nan'), nat)
+            assert_equal(nat / float('nan'), nat)
+
+    def test_datetime_compare(self):
+        # Test all the comparison operators
+        a = np.datetime64('2000-03-12T18:00:00.000000')
+        b = np.array(['2000-03-12T18:00:00.000000',
+                      '2000-03-12T17:59:59.999999',
+                      '2000-03-12T18:00:00.000001',
+                      '1970-01-11T12:00:00.909090',
+                      '2016-01-11T12:00:00.909090'],
+                      dtype='datetime64[us]')
+        assert_equal(np.equal(a, b), [1, 0, 0, 0, 0])
+        assert_equal(np.not_equal(a, b), [0, 1, 1, 1, 1])
+        assert_equal(np.less(a, b), [0, 0, 1, 0, 1])
+        assert_equal(np.less_equal(a, b), [1, 0, 1, 0, 1])
+        assert_equal(np.greater(a, b), [0, 1, 0, 1, 0])
+        assert_equal(np.greater_equal(a, b), [1, 1, 0, 1, 0])
+
+    def test_datetime_compare_nat(self):
+        dt_nat = np.datetime64('NaT', 'D')
+        dt_other = np.datetime64('2000-01-01')
+        td_nat = np.timedelta64('NaT', 'h')
+        td_other = np.timedelta64(1, 'h')
+
+        for op in [np.equal, np.less, np.less_equal,
+                   np.greater, np.greater_equal]:
+            if op(dt_nat, dt_nat):
+                assert_warns(FutureWarning, op, dt_nat, dt_nat)
+            if op(dt_nat, dt_other):
+                assert_warns(FutureWarning, op, dt_nat, dt_other)
+            if op(dt_other, dt_nat):
+                assert_warns(FutureWarning, op, dt_other, dt_nat)
+            if op(td_nat, td_nat):
+                assert_warns(FutureWarning, op, td_nat, td_nat)
+            if op(td_nat, td_other):
+                assert_warns(FutureWarning, op, td_nat, td_other)
+            if op(td_other, td_nat):
+                assert_warns(FutureWarning, op, td_other, td_nat)
+
+        assert_warns(FutureWarning, np.not_equal, dt_nat, dt_nat)
+        assert_(np.not_equal(dt_nat, dt_other))
+        assert_(np.not_equal(dt_other, dt_nat))
+        assert_warns(FutureWarning, np.not_equal, td_nat, td_nat)
+        assert_(np.not_equal(td_nat, td_other))
+        assert_(np.not_equal(td_other, td_nat))
+
+    def test_datetime_minmax(self):
+        # The metadata of the result should become the GCD
+        # of the operand metadata
+        a = np.array('1999-03-12T13', dtype='M8[2m]')
+        b = np.array('1999-03-12T12', dtype='M8[s]')
+        assert_equal(np.minimum(a, b), b)
+        assert_equal(np.minimum(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.fmin(a, b), b)
+        assert_equal(np.fmin(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.maximum(a, b), a)
+        assert_equal(np.maximum(a, b).dtype, np.dtype('M8[s]'))
+        assert_equal(np.fmax(a, b), a)
+        assert_equal(np.fmax(a, b).dtype, np.dtype('M8[s]'))
+        # Viewed as integers, the comparison is opposite because
+        # of the units chosen
+        assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8'))
+
+        # Interaction with NaT
+        a = np.array('1999-03-12T13', dtype='M8[2m]')
+        dtnat = np.array('NaT', dtype='M8[h]')
+        assert_equal(np.minimum(a, dtnat), a)
+        assert_equal(np.minimum(dtnat, a), a)
+        assert_equal(np.maximum(a, dtnat), a)
+        assert_equal(np.maximum(dtnat, a), a)
+
+        # Also do timedelta
+        a = np.array(3, dtype='m8[h]')
+        b = np.array(3*3600 - 3, dtype='m8[s]')
+        assert_equal(np.minimum(a, b), b)
+        assert_equal(np.minimum(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.fmin(a, b), b)
+        assert_equal(np.fmin(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.maximum(a, b), a)
+        assert_equal(np.maximum(a, b).dtype, np.dtype('m8[s]'))
+        assert_equal(np.fmax(a, b), a)
+        assert_equal(np.fmax(a, b).dtype, np.dtype('m8[s]'))
+        # Viewed as integers, the comparison is opposite because
+        # of the units chosen
+        assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8'))
+
+        # should raise between datetime and timedelta
+        #
+        # TODO: Allowing unsafe casting by
+        #       default in ufuncs strikes again... :(
+        a = np.array(3, dtype='m8[h]')
+        b = np.array('1999-03-12T12', dtype='M8[s]')
+        #assert_raises(TypeError, np.minimum, a, b)
+        #assert_raises(TypeError, np.maximum, a, b)
+        #assert_raises(TypeError, np.fmin, a, b)
+        #assert_raises(TypeError, np.fmax, a, b)
+        assert_raises(TypeError, np.minimum, a, b, casting='same_kind')
+        assert_raises(TypeError, np.maximum, a, b, casting='same_kind')
+        assert_raises(TypeError, np.fmin, a, b, casting='same_kind')
+        assert_raises(TypeError, np.fmax, a, b, casting='same_kind')
+
+    def test_hours(self):
+        t = np.ones(3, dtype='M8[s]')
+        t[0] = 60*60*24 + 60*60*10
+        assert_(t[0].item().hour == 10)
+
+    def test_divisor_conversion_year(self):
+        assert_(np.dtype('M8[Y/4]') == np.dtype('M8[3M]'))
+        assert_(np.dtype('M8[Y/13]') == np.dtype('M8[4W]'))
+        assert_(np.dtype('M8[3Y/73]') == np.dtype('M8[15D]'))
+
+    def test_divisor_conversion_month(self):
+        assert_(np.dtype('M8[M/2]') == np.dtype('M8[2W]'))
+        assert_(np.dtype('M8[M/15]') == np.dtype('M8[2D]'))
+        assert_(np.dtype('M8[3M/40]') == np.dtype('M8[54h]'))
+
+    def test_divisor_conversion_week(self):
+        assert_(np.dtype('m8[W/7]') == np.dtype('m8[D]'))
+        assert_(np.dtype('m8[3W/14]') == np.dtype('m8[36h]'))
+        assert_(np.dtype('m8[5W/140]') == np.dtype('m8[360m]'))
+
+    def test_divisor_conversion_day(self):
+        assert_(np.dtype('M8[D/12]') == np.dtype('M8[2h]'))
+        assert_(np.dtype('M8[D/120]') == np.dtype('M8[12m]'))
+        assert_(np.dtype('M8[3D/960]') == np.dtype('M8[270s]'))
+
+    def test_divisor_conversion_hour(self):
+        assert_(np.dtype('m8[h/30]') == np.dtype('m8[2m]'))
+        assert_(np.dtype('m8[3h/300]') == np.dtype('m8[36s]'))
+
+    def test_divisor_conversion_minute(self):
+        assert_(np.dtype('m8[m/30]') == np.dtype('m8[2s]'))
+        assert_(np.dtype('m8[3m/300]') == np.dtype('m8[600ms]'))
+
+    def test_divisor_conversion_second(self):
+        assert_(np.dtype('m8[s/100]') == np.dtype('m8[10ms]'))
+        assert_(np.dtype('m8[3s/10000]') == np.dtype('m8[300us]'))
+
+    def test_divisor_conversion_fs(self):
+        assert_(np.dtype('M8[fs/100]') == np.dtype('M8[10as]'))
+        self.assertRaises(ValueError, lambda: np.dtype('M8[3fs/10000]'))
+
+    def test_divisor_conversion_as(self):
+        self.assertRaises(ValueError, lambda: np.dtype('M8[as/10]'))
+
+    def test_string_parser_variants(self):
+        # Allow space instead of 'T' between date and time
+        assert_equal(np.array(['1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                     np.array(['1980-02-29 01:02:03'], np.dtype('M8[s]')))
+        # Allow negative years
+        assert_equal(np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                     np.array(['-1980-02-29 01:02:03'], np.dtype('M8[s]')))
+        # UTC specifier
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')),
+                np.array(['-1980-02-29 01:02:03Z'], np.dtype('M8[s]')))
+        # Time zone offset
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-29T02:02:03'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:32:03-0130'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-28T22:32:03'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:02:03+01:30'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(
+                np.array(['1980-02-29T02:32:03.506'], np.dtype('M8[s]')),
+                np.array(['1980-02-29 00:32:03.506-02'], np.dtype('M8[s]')))
+        with assert_warns(DeprecationWarning):
+            assert_equal(np.datetime64('1977-03-02T12:30-0230'),
+                         np.datetime64('1977-03-02T15:00'))
+
+    def test_string_parser_error_check(self):
+        # Arbitrary bad string
+        assert_raises(ValueError, np.array, ['badvalue'], np.dtype('M8[us]'))
+        # Character after year must be '-'
+        assert_raises(ValueError, np.array, ['1980X'], np.dtype('M8[us]'))
+        # Cannot have trailing '-'
+        assert_raises(ValueError, np.array, ['1980-'], np.dtype('M8[us]'))
+        # Month must be in range [1,12]
+        assert_raises(ValueError, np.array, ['1980-00'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-13'], np.dtype('M8[us]'))
+        # Month must have two digits
+        assert_raises(ValueError, np.array, ['1980-1'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-1-02'], np.dtype('M8[us]'))
+        # 'Mor' is not a valid month
+        assert_raises(ValueError, np.array, ['1980-Mor'], np.dtype('M8[us]'))
+        # Cannot have trailing '-'
+        assert_raises(ValueError, np.array, ['1980-01-'], np.dtype('M8[us]'))
+        # Day must be in range [1,len(month)]
+        assert_raises(ValueError, np.array, ['1980-01-0'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-01-00'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-01-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1979-02-29'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-30'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-03-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-04-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-05-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-06-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-07-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-08-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-09-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-10-32'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-11-31'], np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-12-32'], np.dtype('M8[us]'))
+        # Cannot have trailing characters
+        assert_raises(ValueError, np.array, ['1980-02-03%'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 q'],
+                                                        np.dtype('M8[us]'))
+
+        # Hours must be in range [0, 23]
+        assert_raises(ValueError, np.array, ['1980-02-03 25'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03T25'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 24:01'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03T24:01'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 -1'],
+                                                        np.dtype('M8[us]'))
+        # No trailing ':'
+        assert_raises(ValueError, np.array, ['1980-02-03 01:'],
+                                                        np.dtype('M8[us]'))
+        # Minutes must be in range [0, 59]
+        assert_raises(ValueError, np.array, ['1980-02-03 01:-1'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 01:60'],
+                                                        np.dtype('M8[us]'))
+        # No trailing ':'
+        assert_raises(ValueError, np.array, ['1980-02-03 01:60:'],
+                                                        np.dtype('M8[us]'))
+        # Seconds must be in range [0, 59]
+        assert_raises(ValueError, np.array, ['1980-02-03 01:10:-1'],
+                                                        np.dtype('M8[us]'))
+        assert_raises(ValueError, np.array, ['1980-02-03 01:01:60'],
+                                                        np.dtype('M8[us]'))
+        # Timezone offset must within a reasonable range
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+0661'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+2500'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-0070'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-3000'],
+                                                            np.dtype('M8[us]'))
+        with assert_warns(DeprecationWarning):
+            assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-25:00'],
+                                                            np.dtype('M8[us]'))
+
+    def test_creation_overflow(self):
+        date = '1980-03-23 20:00:00'
+        timesteps = np.array([date], dtype='datetime64[s]')[0].astype(np.int64)
+        for unit in ['ms', 'us', 'ns']:
+            timesteps *= 1000
+            x = np.array([date], dtype='datetime64[%s]' % unit)
+
+            assert_equal(timesteps, x[0].astype(np.int64),
+                         err_msg='Datetime conversion error for unit %s' % unit)
+
+        assert_equal(x[0].astype(np.int64), 322689600000000000)
+
+    def test_datetime_as_string(self):
+        # Check all the units with default string conversion
+        date = '1959-10-13'
+        datetime = '1959-10-13T12:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'Y')),
+                     '1959')
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'M')),
+                     '1959-10')
+        assert_equal(np.datetime_as_string(np.datetime64(date, 'D')),
+                     '1959-10-13')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'h')),
+                     '1959-10-13T12')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'm')),
+                     '1959-10-13T12:34')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 's')),
+                     '1959-10-13T12:34:56')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ms')),
+                     '1959-10-13T12:34:56.789')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'us')),
+                     '1959-10-13T12:34:56.789012')
+
+        datetime = '1969-12-31T23:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')),
+                     '1969-12-31T23:34:56.789012345')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')),
+                     '1969-12-31T23:34:56.789012345678')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')),
+                     '1969-12-31T23:34:56.789012345678901')
+
+        datetime = '1969-12-31T23:59:57.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')),
+                     datetime)
+        datetime = '1970-01-01T00:34:56.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')),
+                     '1970-01-01T00:34:56.789012345')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')),
+                     '1970-01-01T00:34:56.789012345678')
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')),
+                     '1970-01-01T00:34:56.789012345678901')
+
+        datetime = '1970-01-01T00:00:05.789012345678901234'
+
+        assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')),
+                     datetime)
+
+        # String conversion with the unit= parameter
+        a = np.datetime64('2032-07-18T12:23:34.123456', 'us')
+        assert_equal(np.datetime_as_string(a, unit='Y', casting='unsafe'),
+                            '2032')
+        assert_equal(np.datetime_as_string(a, unit='M', casting='unsafe'),
+                            '2032-07')
+        assert_equal(np.datetime_as_string(a, unit='W', casting='unsafe'),
+                            '2032-07-18')
+        assert_equal(np.datetime_as_string(a, unit='D', casting='unsafe'),
+                            '2032-07-18')
+        assert_equal(np.datetime_as_string(a, unit='h'), '2032-07-18T12')
+        assert_equal(np.datetime_as_string(a, unit='m'),
+                            '2032-07-18T12:23')
+        assert_equal(np.datetime_as_string(a, unit='s'),
+                            '2032-07-18T12:23:34')
+        assert_equal(np.datetime_as_string(a, unit='ms'),
+                            '2032-07-18T12:23:34.123')
+        assert_equal(np.datetime_as_string(a, unit='us'),
+                            '2032-07-18T12:23:34.123456')
+        assert_equal(np.datetime_as_string(a, unit='ns'),
+                            '2032-07-18T12:23:34.123456000')
+        assert_equal(np.datetime_as_string(a, unit='ps'),
+                            '2032-07-18T12:23:34.123456000000')
+        assert_equal(np.datetime_as_string(a, unit='fs'),
+                            '2032-07-18T12:23:34.123456000000000')
+        assert_equal(np.datetime_as_string(a, unit='as'),
+                            '2032-07-18T12:23:34.123456000000000000')
+
+        # unit='auto' parameter
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34.123456', 'us'), unit='auto'),
+                '2032-07-18T12:23:34.123456')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34.12', 'us'), unit='auto'),
+                '2032-07-18T12:23:34.120')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:34', 'us'), unit='auto'),
+                '2032-07-18T12:23:34')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:23:00', 'us'), unit='auto'),
+                '2032-07-18T12:23')
+        # 'auto' doesn't split up hour and minute
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T12:00:00', 'us'), unit='auto'),
+                '2032-07-18T12:00')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-18T00:00:00', 'us'), unit='auto'),
+                '2032-07-18')
+        # 'auto' doesn't split up the date
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-07-01T00:00:00', 'us'), unit='auto'),
+                '2032-07-01')
+        assert_equal(np.datetime_as_string(
+                np.datetime64('2032-01-01T00:00:00', 'us'), unit='auto'),
+                '2032-01-01')
+
+    @dec.skipif(not _has_pytz, "The pytz module is not available.")
+    def test_datetime_as_string_timezone(self):
+        # timezone='local' vs 'UTC'
+        a = np.datetime64('2010-03-15T06:30', 'm')
+        assert_equal(np.datetime_as_string(a),
+                '2010-03-15T06:30')
+        assert_equal(np.datetime_as_string(a, timezone='naive'),
+                '2010-03-15T06:30')
+        assert_equal(np.datetime_as_string(a, timezone='UTC'),
+                '2010-03-15T06:30Z')
+        assert_(np.datetime_as_string(a, timezone='local') !=
+                '2010-03-15T06:30')
+
+        b = np.datetime64('2010-02-15T06:30', 'm')
+
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Central')),
+                     '2010-03-15T01:30-0500')
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Eastern')),
+                     '2010-03-15T02:30-0400')
+        assert_equal(np.datetime_as_string(a, timezone=tz('US/Pacific')),
+                     '2010-03-14T23:30-0700')
+
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Central')),
+                     '2010-02-15T00:30-0600')
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Eastern')),
+                     '2010-02-15T01:30-0500')
+        assert_equal(np.datetime_as_string(b, timezone=tz('US/Pacific')),
+                     '2010-02-14T22:30-0800')
+
+        # Dates to strings with a timezone attached is disabled by default
+        assert_raises(TypeError, np.datetime_as_string, a, unit='D',
+                           timezone=tz('US/Pacific'))
+        # Check that we can print out the date in the specified time zone
+        assert_equal(np.datetime_as_string(a, unit='D',
+                           timezone=tz('US/Pacific'), casting='unsafe'),
+                     '2010-03-14')
+        assert_equal(np.datetime_as_string(b, unit='D',
+                           timezone=tz('US/Central'), casting='unsafe'),
+                     '2010-02-15')
+
+    def test_datetime_arange(self):
+        # With two datetimes provided as strings
+        a = np.arange('2010-01-05', '2010-01-10', dtype='M8[D]')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.array(['2010-01-05', '2010-01-06', '2010-01-07',
+                      '2010-01-08', '2010-01-09'], dtype='M8[D]'))
+
+        a = np.arange('1950-02-10', '1950-02-06', -1, dtype='M8[D]')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.array(['1950-02-10', '1950-02-09', '1950-02-08',
+                      '1950-02-07'], dtype='M8[D]'))
+
+        # Unit should be detected as months here
+        a = np.arange('1969-05', '1970-05', 2, dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[M]'))
+        assert_equal(a,
+            np.datetime64('1969-05') + np.arange(12, step=2))
+
+        # datetime, integer|timedelta works as well
+        # produces arange (start, start + stop) in this case
+        a = np.arange('1969', 18, 3, dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[Y]'))
+        assert_equal(a,
+            np.datetime64('1969') + np.arange(18, step=3))
+        a = np.arange('1969-12-19', 22, np.timedelta64(2), dtype='M8')
+        assert_equal(a.dtype, np.dtype('M8[D]'))
+        assert_equal(a,
+            np.datetime64('1969-12-19') + np.arange(22, step=2))
+
+        # Step of 0 is disallowed
+        assert_raises(ValueError, np.arange, np.datetime64('today'),
+                                np.datetime64('today') + 3, 0)
+        # Promotion across nonlinear unit boundaries is disallowed
+        assert_raises(TypeError, np.arange, np.datetime64('2011-03-01', 'D'),
+                                np.timedelta64(5, 'M'))
+        assert_raises(TypeError, np.arange,
+                                np.datetime64('2012-02-03T14', 's'),
+                                np.timedelta64(5, 'Y'))
+
+    def test_datetime_arange_no_dtype(self):
+        d = np.array('2010-01-04', dtype="M8[D]")
+        assert_equal(np.arange(d, d + 1), d)
+        assert_raises(ValueError, np.arange, d)
+
+    def test_timedelta_arange(self):
+        a = np.arange(3, 10, dtype='m8')
+        assert_equal(a.dtype, np.dtype('m8'))
+        assert_equal(a, np.timedelta64(0) + np.arange(3, 10))
+
+        a = np.arange(np.timedelta64(3, 's'), 10, 2, dtype='m8')
+        assert_equal(a.dtype, np.dtype('m8[s]'))
+        assert_equal(a, np.timedelta64(0, 's') + np.arange(3, 10, 2))
+
+        # Step of 0 is disallowed
+        assert_raises(ValueError, np.arange, np.timedelta64(0),
+                                np.timedelta64(5), 0)
+        # Promotion across nonlinear unit boundaries is disallowed
+        assert_raises(TypeError, np.arange, np.timedelta64(0, 'D'),
+                                np.timedelta64(5, 'M'))
+        assert_raises(TypeError, np.arange, np.timedelta64(0, 'Y'),
+                                np.timedelta64(5, 'D'))
+
+    def test_timedelta_arange_no_dtype(self):
+        d = np.array(5, dtype="m8[D]")
+        assert_equal(np.arange(d, d + 1), d)
+        assert_raises(ValueError, np.arange, d)
+
+    def test_datetime_maximum_reduce(self):
+        a = np.array(['2010-01-02', '1999-03-14', '1833-03'], dtype='M8[D]')
+        assert_equal(np.maximum.reduce(a).dtype, np.dtype('M8[D]'))
+        assert_equal(np.maximum.reduce(a),
+                     np.datetime64('2010-01-02'))
+
+        a = np.array([1, 4, 0, 7, 2], dtype='m8[s]')
+        assert_equal(np.maximum.reduce(a).dtype, np.dtype('m8[s]'))
+        assert_equal(np.maximum.reduce(a),
+                     np.timedelta64(7, 's'))
+
+    def test_datetime_busday_offset(self):
+        # First Monday in June
+        assert_equal(
+            np.busday_offset('2011-06', 0, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-06'))
+        # Last Monday in June
+        assert_equal(
+            np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-27'))
+        assert_equal(
+            np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'),
+            np.datetime64('2011-06-27'))
+
+        # Default M-F business days, different roll modes
+        assert_equal(np.busday_offset('2010-08', 0, roll='backward'),
+                     np.datetime64('2010-07-30'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='preceding'),
+                     np.datetime64('2010-07-30'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='modifiedpreceding'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='modifiedfollowing'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='forward'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-08', 0, roll='following'),
+                     np.datetime64('2010-08-02'))
+        assert_equal(np.busday_offset('2010-10-30', 0, roll='following'),
+                     np.datetime64('2010-11-01'))
+        assert_equal(
+                np.busday_offset('2010-10-30', 0, roll='modifiedfollowing'),
+                np.datetime64('2010-10-29'))
+        assert_equal(
+                np.busday_offset('2010-10-30', 0, roll='modifiedpreceding'),
+                np.datetime64('2010-10-29'))
+        assert_equal(
+                np.busday_offset('2010-10-16', 0, roll='modifiedfollowing'),
+                np.datetime64('2010-10-18'))
+        assert_equal(
+                np.busday_offset('2010-10-16', 0, roll='modifiedpreceding'),
+                np.datetime64('2010-10-15'))
+        # roll='raise' by default
+        assert_raises(ValueError, np.busday_offset, '2011-06-04', 0)
+
+        # Bigger offset values
+        assert_equal(np.busday_offset('2006-02-01', 25),
+                     np.datetime64('2006-03-08'))
+        assert_equal(np.busday_offset('2006-03-08', -25),
+                     np.datetime64('2006-02-01'))
+        assert_equal(np.busday_offset('2007-02-25', 11, weekmask='SatSun'),
+                     np.datetime64('2007-04-07'))
+        assert_equal(np.busday_offset('2007-04-07', -11, weekmask='SatSun'),
+                     np.datetime64('2007-02-25'))
+
+        # NaT values when roll is not raise
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='nat'),
+                     np.datetime64('NaT'))
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='following'),
+                     np.datetime64('NaT'))
+        assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='preceding'),
+                     np.datetime64('NaT'))
+
+
+    def test_datetime_busdaycalendar(self):
+        # Check that it removes NaT, duplicates, and weekends
+        # and sorts the result.
+        bdd = np.busdaycalendar(
+            holidays=['NaT', '2011-01-17', '2011-03-06', 'NaT',
+                       '2011-12-26', '2011-05-30', '2011-01-17'])
+        assert_equal(bdd.holidays,
+            np.array(['2011-01-17', '2011-05-30', '2011-12-26'], dtype='M8'))
+        # Default M-F weekmask
+        assert_equal(bdd.weekmask, np.array([1, 1, 1, 1, 1, 0, 0], dtype='?'))
+
+        # Check string weekmask with varying whitespace.
+        bdd = np.busdaycalendar(weekmask="Sun TueWed  Thu\tFri")
+        assert_equal(bdd.weekmask, np.array([0, 1, 1, 1, 1, 0, 1], dtype='?'))
+
+        # Check length 7 0/1 string
+        bdd = np.busdaycalendar(weekmask="0011001")
+        assert_equal(bdd.weekmask, np.array([0, 0, 1, 1, 0, 0, 1], dtype='?'))
+
+        # Check length 7 string weekmask.
+        bdd = np.busdaycalendar(weekmask="Mon Tue")
+        assert_equal(bdd.weekmask, np.array([1, 1, 0, 0, 0, 0, 0], dtype='?'))
+
+        # All-zeros weekmask should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask=[0, 0, 0, 0, 0, 0, 0])
+        # weekday names must be correct case
+        assert_raises(ValueError, np.busdaycalendar, weekmask="satsun")
+        # All-zeros weekmask should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask="")
+        # Invalid weekday name codes should raise
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Mon Tue We")
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Max")
+        assert_raises(ValueError, np.busdaycalendar, weekmask="Monday Tue")
+
+    def test_datetime_busday_holidays_offset(self):
+        # With exactly one holiday
+        assert_equal(
+            np.busday_offset('2011-11-10', 1, holidays=['2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-04', 5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-10', 5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-18'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1, holidays=['2011-11-11']),
+            np.datetime64('2011-11-10'))
+        assert_equal(
+            np.busday_offset('2011-11-18', -5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-10'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -5, holidays=['2011-11-11']),
+            np.datetime64('2011-11-04'))
+        # With the holiday appearing twice
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', '2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-11-11', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With a NaT holiday
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', 'NaT']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['NaT', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With another holiday after
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-10'))
+        # With another holiday before
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-10-10', '2011-11-11']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-10-10', '2011-11-11']),
+            np.datetime64('2011-11-10'))
+        # With another holiday before and after
+        assert_equal(
+            np.busday_offset('2011-11-10', 1,
+                holidays=['2011-10-10', '2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-14'))
+        assert_equal(
+            np.busday_offset('2011-11-14', -1,
+                holidays=['2011-10-10', '2011-11-11', '2011-11-24']),
+            np.datetime64('2011-11-10'))
+
+        # A bigger forward jump across more than one week/holiday
+        holidays = ['2011-10-10', '2011-11-11', '2011-11-24',
+                  '2011-12-25', '2011-05-30', '2011-02-21',
+                  '2011-12-26', '2012-01-02']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+        assert_equal(
+            np.busday_offset('2011-10-03', 4, holidays=holidays),
+            np.busday_offset('2011-10-03', 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 5, holidays=holidays),
+            np.busday_offset('2011-10-03', 5 + 1))
+        assert_equal(
+            np.busday_offset('2011-10-03', 27, holidays=holidays),
+            np.busday_offset('2011-10-03', 27 + 1))
+        assert_equal(
+            np.busday_offset('2011-10-03', 28, holidays=holidays),
+            np.busday_offset('2011-10-03', 28 + 2))
+        assert_equal(
+            np.busday_offset('2011-10-03', 35, holidays=holidays),
+            np.busday_offset('2011-10-03', 35 + 2))
+        assert_equal(
+            np.busday_offset('2011-10-03', 36, holidays=holidays),
+            np.busday_offset('2011-10-03', 36 + 3))
+        assert_equal(
+            np.busday_offset('2011-10-03', 56, holidays=holidays),
+            np.busday_offset('2011-10-03', 56 + 3))
+        assert_equal(
+            np.busday_offset('2011-10-03', 57, holidays=holidays),
+            np.busday_offset('2011-10-03', 57 + 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 60, holidays=holidays),
+            np.busday_offset('2011-10-03', 60 + 4))
+        assert_equal(
+            np.busday_offset('2011-10-03', 61, holidays=holidays),
+            np.busday_offset('2011-10-03', 61 + 5))
+        assert_equal(
+            np.busday_offset('2011-10-03', 61, busdaycal=bdd),
+            np.busday_offset('2011-10-03', 61 + 5))
+        # A bigger backward jump across more than one week/holiday
+        assert_equal(
+            np.busday_offset('2012-01-03', -1, holidays=holidays),
+            np.busday_offset('2012-01-03', -1 - 1))
+        assert_equal(
+            np.busday_offset('2012-01-03', -4, holidays=holidays),
+            np.busday_offset('2012-01-03', -4 - 1))
+        assert_equal(
+            np.busday_offset('2012-01-03', -5, holidays=holidays),
+            np.busday_offset('2012-01-03', -5 - 2))
+        assert_equal(
+            np.busday_offset('2012-01-03', -25, holidays=holidays),
+            np.busday_offset('2012-01-03', -25 - 2))
+        assert_equal(
+            np.busday_offset('2012-01-03', -26, holidays=holidays),
+            np.busday_offset('2012-01-03', -26 - 3))
+        assert_equal(
+            np.busday_offset('2012-01-03', -33, holidays=holidays),
+            np.busday_offset('2012-01-03', -33 - 3))
+        assert_equal(
+            np.busday_offset('2012-01-03', -34, holidays=holidays),
+            np.busday_offset('2012-01-03', -34 - 4))
+        assert_equal(
+            np.busday_offset('2012-01-03', -56, holidays=holidays),
+            np.busday_offset('2012-01-03', -56 - 4))
+        assert_equal(
+            np.busday_offset('2012-01-03', -57, holidays=holidays),
+            np.busday_offset('2012-01-03', -57 - 5))
+        assert_equal(
+            np.busday_offset('2012-01-03', -57, busdaycal=bdd),
+            np.busday_offset('2012-01-03', -57 - 5))
+
+        # Can't supply both a weekmask/holidays and busdaycal
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', -15,
+                        weekmask='1111100', busdaycal=bdd)
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', -15,
+                        holidays=holidays, busdaycal=bdd)
+
+        # Roll with the holidays
+        assert_equal(
+            np.busday_offset('2011-12-25', 0,
+                roll='forward', holidays=holidays),
+            np.datetime64('2011-12-27'))
+        assert_equal(
+            np.busday_offset('2011-12-26', 0,
+                roll='forward', holidays=holidays),
+            np.datetime64('2011-12-27'))
+        assert_equal(
+            np.busday_offset('2011-12-26', 0,
+                roll='backward', holidays=holidays),
+            np.datetime64('2011-12-23'))
+        assert_equal(
+            np.busday_offset('2012-02-27', 0,
+                roll='modifiedfollowing',
+                holidays=['2012-02-27', '2012-02-26', '2012-02-28',
+                          '2012-03-01', '2012-02-29']),
+            np.datetime64('2012-02-24'))
+        assert_equal(
+            np.busday_offset('2012-03-06', 0,
+                roll='modifiedpreceding',
+                holidays=['2012-03-02', '2012-03-03', '2012-03-01',
+                          '2012-03-05', '2012-03-07', '2012-03-06']),
+            np.datetime64('2012-03-08'))
+
+    def test_datetime_busday_holidays_count(self):
+        holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24',
+                    '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17',
+                    '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30',
+                    '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+
+        # Validate against busday_offset broadcast against
+        # a range of offsets
+        dates = np.busday_offset('2011-01-01', np.arange(366),
+                        roll='forward', busdaycal=bdd)
+        assert_equal(np.busday_count('2011-01-01', dates, busdaycal=bdd),
+                     np.arange(366))
+        # Returns negative value when reversed
+        assert_equal(np.busday_count(dates, '2011-01-01', busdaycal=bdd),
+                     -np.arange(366))
+
+        dates = np.busday_offset('2011-12-31', -np.arange(366),
+                        roll='forward', busdaycal=bdd)
+        assert_equal(np.busday_count(dates, '2011-12-31', busdaycal=bdd),
+                     np.arange(366))
+        # Returns negative value when reversed
+        assert_equal(np.busday_count('2011-12-31', dates, busdaycal=bdd),
+                     -np.arange(366))
+
+        # Can't supply both a weekmask/holidays and busdaycal
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03',
+                        weekmask='1111100', busdaycal=bdd)
+        assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03',
+                        holidays=holidays, busdaycal=bdd)
+
+        # Number of Mondays in March 2011
+        assert_equal(np.busday_count('2011-03', '2011-04', weekmask='Mon'), 4)
+        # Returns negative value when reversed
+        assert_equal(np.busday_count('2011-04', '2011-03', weekmask='Mon'), -4)
+
+    def test_datetime_is_busday(self):
+        holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24',
+                    '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17',
+                    '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30',
+                    '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10',
+                    'NaT']
+        bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays)
+
+        # Weekend/weekday tests
+        assert_equal(np.is_busday('2011-01-01'), False)
+        assert_equal(np.is_busday('2011-01-02'), False)
+        assert_equal(np.is_busday('2011-01-03'), True)
+
+        # All the holidays are not business days
+        assert_equal(np.is_busday(holidays, busdaycal=bdd),
+                     np.zeros(len(holidays), dtype='?'))
+
+    def test_datetime_y2038(self):
+        # Test parsing on either side of the Y2038 boundary
+        a = np.datetime64('2038-01-19T03:14:07')
+        assert_equal(a.view(np.int64), 2**31 - 1)
+        a = np.datetime64('2038-01-19T03:14:08')
+        assert_equal(a.view(np.int64), 2**31)
+
+        # Test parsing on either side of the Y2038 boundary with
+        # a manually specified timezone offset
+        with assert_warns(DeprecationWarning):
+            a = np.datetime64('2038-01-19T04:14:07+0100')
+            assert_equal(a.view(np.int64), 2**31 - 1)
+        with assert_warns(DeprecationWarning):
+            a = np.datetime64('2038-01-19T04:14:08+0100')
+            assert_equal(a.view(np.int64), 2**31)
+
+        # Test parsing a date after Y2038
+        a = np.datetime64('2038-01-20T13:21:14')
+        assert_equal(str(a), '2038-01-20T13:21:14')
+
+class TestDateTimeData(TestCase):
+
+    def test_basic(self):
+        a = np.array(['1980-03-23'], dtype=np.datetime64)
+        assert_equal(np.datetime_data(a.dtype), ('D', 1))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
new file mode 100644
index 0000000000..e828b879f3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
@@ -0,0 +1,703 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.core.multiarray import _vec_string
+from numpy.compat import asbytes, asbytes_nested, sixu
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal
+)
+
+kw_unicode_true = {'unicode': True}  # make 2to3 work properly
+kw_unicode_false = {'unicode': False}
+
+class TestBasic(TestCase):
+    def test_from_object_array(self):
+        A = np.array([['abc', 2],
+                      ['long   ', '0123456789']], dtype='O')
+        B = np.char.array(A)
+        assert_equal(B.dtype.itemsize, 10)
+        assert_array_equal(B, asbytes_nested([['abc', '2'],
+                                              ['long', '0123456789']]))
+
+    def test_from_object_array_unicode(self):
+        A = np.array([['abc', sixu('Sigma \u03a3')],
+                      ['long   ', '0123456789']], dtype='O')
+        self.assertRaises(ValueError, np.char.array, (A,))
+        B = np.char.array(A, **kw_unicode_true)
+        assert_equal(B.dtype.itemsize, 10 * np.array('a', 'U').dtype.itemsize)
+        assert_array_equal(B, [['abc', sixu('Sigma \u03a3')],
+                               ['long', '0123456789']])
+
+    def test_from_string_array(self):
+        A = np.array(asbytes_nested([['abc', 'foo'],
+                                     ['long   ', '0123456789']]))
+        assert_equal(A.dtype.type, np.string_)
+        B = np.char.array(A)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+        B[0, 0] = 'changed'
+        assert_(B[0, 0] != A[0, 0])
+        C = np.char.asarray(A)
+        assert_array_equal(C, A)
+        assert_equal(C.dtype, A.dtype)
+        C[0, 0] = 'changed again'
+        assert_(C[0, 0] != B[0, 0])
+        assert_(C[0, 0] == A[0, 0])
+
+    def test_from_unicode_array(self):
+        A = np.array([['abc', sixu('Sigma \u03a3')],
+                      ['long   ', '0123456789']])
+        assert_equal(A.dtype.type, np.unicode_)
+        B = np.char.array(A)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+        B = np.char.array(A, **kw_unicode_true)
+        assert_array_equal(B, A)
+        assert_equal(B.dtype, A.dtype)
+        assert_equal(B.shape, A.shape)
+
+        def fail():
+            np.char.array(A, **kw_unicode_false)
+
+        self.assertRaises(UnicodeEncodeError, fail)
+
+    def test_unicode_upconvert(self):
+        A = np.char.array(['abc'])
+        B = np.char.array([sixu('\u03a3')])
+        assert_(issubclass((A + B).dtype.type, np.unicode_))
+
+    def test_from_string(self):
+        A = np.char.array(asbytes('abc'))
+        assert_equal(len(A), 1)
+        assert_equal(len(A[0]), 3)
+        assert_(issubclass(A.dtype.type, np.string_))
+
+    def test_from_unicode(self):
+        A = np.char.array(sixu('\u03a3'))
+        assert_equal(len(A), 1)
+        assert_equal(len(A[0]), 1)
+        assert_equal(A.itemsize, 4)
+        assert_(issubclass(A.dtype.type, np.unicode_))
+
+class TestVecString(TestCase):
+    def test_non_existent_method(self):
+
+        def fail():
+            _vec_string('a', np.string_, 'bogus')
+
+        self.assertRaises(AttributeError, fail)
+
+    def test_non_string_array(self):
+
+        def fail():
+            _vec_string(1, np.string_, 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_args_tuple(self):
+
+        def fail():
+            _vec_string(['a'], np.string_, 'strip', 1)
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_type_descr(self):
+
+        def fail():
+            _vec_string(['a'], 'BOGUS', 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_function_args(self):
+
+        def fail():
+            _vec_string(['a'], np.string_, 'strip', (1,))
+
+        self.assertRaises(TypeError, fail)
+
+    def test_invalid_result_type(self):
+
+        def fail():
+            _vec_string(['a'], np.integer, 'strip')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_broadcast_error(self):
+
+        def fail():
+            _vec_string([['abc', 'def']], np.integer, 'find', (['a', 'd', 'j'],))
+
+        self.assertRaises(ValueError, fail)
+
+
+class TestWhitespace(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc ', '123  '],
+                           ['789 ', 'xyz ']]).view(np.chararray)
+        self.B = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+
+    def test1(self):
+        assert_(np.all(self.A == self.B))
+        assert_(np.all(self.A >= self.B))
+        assert_(np.all(self.A <= self.B))
+        assert_(not np.any(self.A > self.B))
+        assert_(not np.any(self.A < self.B))
+        assert_(not np.any(self.A != self.B))
+
+class TestChar(TestCase):
+    def setUp(self):
+        self.A = np.array('abc1', dtype='c').view(np.chararray)
+
+    def test_it(self):
+        assert_equal(self.A.shape, (4,))
+        assert_equal(self.A.upper()[:2].tobytes(), asbytes('AB'))
+
+class TestComparisons(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+        self.B = np.array([['efg', '123  '],
+                           ['051', 'tuv']]).view(np.chararray)
+
+    def test_not_equal(self):
+        assert_array_equal((self.A != self.B), [[True, False], [True, True]])
+
+    def test_equal(self):
+        assert_array_equal((self.A == self.B), [[False, True], [False, False]])
+
+    def test_greater_equal(self):
+        assert_array_equal((self.A >= self.B), [[False, True], [True, True]])
+
+    def test_less_equal(self):
+        assert_array_equal((self.A <= self.B), [[True, True], [False, False]])
+
+    def test_greater(self):
+        assert_array_equal((self.A > self.B), [[False, False], [True, True]])
+
+    def test_less(self):
+        assert_array_equal((self.A < self.B), [[True, False], [False, False]])
+
+class TestComparisonsMixed1(TestComparisons):
+    """Ticket #1276"""
+
+    def setUp(self):
+        TestComparisons.setUp(self)
+        self.B = np.array([['efg', '123  '],
+                           ['051', 'tuv']], np.unicode_).view(np.chararray)
+
+class TestComparisonsMixed2(TestComparisons):
+    """Ticket #1276"""
+
+    def setUp(self):
+        TestComparisons.setUp(self)
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']], np.unicode_).view(np.chararray)
+
+class TestInformation(TestCase):
+    def setUp(self):
+        self.A = np.array([[' abc ', ''],
+                           ['12345', 'MixedCase'],
+                           ['123 \t 345 \0 ', 'UPPER']]).view(np.chararray)
+        self.B = np.array([[sixu(' \u03a3 '), sixu('')],
+                           [sixu('12345'), sixu('MixedCase')],
+                           [sixu('123 \t 345 \0 '), sixu('UPPER')]]).view(np.chararray)
+
+    def test_len(self):
+        assert_(issubclass(np.char.str_len(self.A).dtype.type, np.integer))
+        assert_array_equal(np.char.str_len(self.A), [[5, 0], [5, 9], [12, 5]])
+        assert_array_equal(np.char.str_len(self.B), [[3, 0], [5, 9], [12, 5]])
+
+    def test_count(self):
+        assert_(issubclass(self.A.count('').dtype.type, np.integer))
+        assert_array_equal(self.A.count('a'), [[1, 0], [0, 1], [0, 0]])
+        assert_array_equal(self.A.count('123'), [[0, 0], [1, 0], [1, 0]])
+        # Python doesn't seem to like counting NULL characters
+        # assert_array_equal(self.A.count('\0'), [[0, 0], [0, 0], [1, 0]])
+        assert_array_equal(self.A.count('a', 0, 2), [[1, 0], [0, 0], [0, 0]])
+        assert_array_equal(self.B.count('a'), [[0, 0], [0, 1], [0, 0]])
+        assert_array_equal(self.B.count('123'), [[0, 0], [1, 0], [1, 0]])
+        # assert_array_equal(self.B.count('\0'), [[0, 0], [0, 0], [1, 0]])
+
+    def test_endswith(self):
+        assert_(issubclass(self.A.endswith('').dtype.type, np.bool_))
+        assert_array_equal(self.A.endswith(' '), [[1, 0], [0, 0], [1, 0]])
+        assert_array_equal(self.A.endswith('3', 0, 3), [[0, 0], [1, 0], [1, 0]])
+
+        def fail():
+            self.A.endswith('3', 'fdjk')
+
+        self.assertRaises(TypeError, fail)
+
+    def test_find(self):
+        assert_(issubclass(self.A.find('a').dtype.type, np.integer))
+        assert_array_equal(self.A.find('a'), [[1, -1], [-1, 6], [-1, -1]])
+        assert_array_equal(self.A.find('3'), [[-1, -1], [2, -1], [2, -1]])
+        assert_array_equal(self.A.find('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
+        assert_array_equal(self.A.find(['1', 'P']), [[-1, -1], [0, -1], [0, 1]])
+
+    def test_index(self):
+
+        def fail():
+            self.A.index('a')
+
+        self.assertRaises(ValueError, fail)
+        assert_(np.char.index('abcba', 'b') == 1)
+        assert_(issubclass(np.char.index('abcba', 'b').dtype.type, np.integer))
+
+    def test_isalnum(self):
+        assert_(issubclass(self.A.isalnum().dtype.type, np.bool_))
+        assert_array_equal(self.A.isalnum(), [[False, False], [True, True], [False, True]])
+
+    def test_isalpha(self):
+        assert_(issubclass(self.A.isalpha().dtype.type, np.bool_))
+        assert_array_equal(self.A.isalpha(), [[False, False], [False, True], [False, True]])
+
+    def test_isdigit(self):
+        assert_(issubclass(self.A.isdigit().dtype.type, np.bool_))
+        assert_array_equal(self.A.isdigit(), [[False, False], [True, False], [False, False]])
+
+    def test_islower(self):
+        assert_(issubclass(self.A.islower().dtype.type, np.bool_))
+        assert_array_equal(self.A.islower(), [[True, False], [False, False], [False, False]])
+
+    def test_isspace(self):
+        assert_(issubclass(self.A.isspace().dtype.type, np.bool_))
+        assert_array_equal(self.A.isspace(), [[False, False], [False, False], [False, False]])
+
+    def test_istitle(self):
+        assert_(issubclass(self.A.istitle().dtype.type, np.bool_))
+        assert_array_equal(self.A.istitle(), [[False, False], [False, False], [False, False]])
+
+    def test_isupper(self):
+        assert_(issubclass(self.A.isupper().dtype.type, np.bool_))
+        assert_array_equal(self.A.isupper(), [[False, False], [False, False], [False, True]])
+
+    def test_rfind(self):
+        assert_(issubclass(self.A.rfind('a').dtype.type, np.integer))
+        assert_array_equal(self.A.rfind('a'), [[1, -1], [-1, 6], [-1, -1]])
+        assert_array_equal(self.A.rfind('3'), [[-1, -1], [2, -1], [6, -1]])
+        assert_array_equal(self.A.rfind('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
+        assert_array_equal(self.A.rfind(['1', 'P']), [[-1, -1], [0, -1], [0, 2]])
+
+    def test_rindex(self):
+
+        def fail():
+            self.A.rindex('a')
+
+        self.assertRaises(ValueError, fail)
+        assert_(np.char.rindex('abcba', 'b') == 3)
+        assert_(issubclass(np.char.rindex('abcba', 'b').dtype.type, np.integer))
+
+    def test_startswith(self):
+        assert_(issubclass(self.A.startswith('').dtype.type, np.bool_))
+        assert_array_equal(self.A.startswith(' '), [[1, 0], [0, 0], [0, 0]])
+        assert_array_equal(self.A.startswith('1', 0, 3), [[0, 0], [1, 0], [1, 0]])
+
+        def fail():
+            self.A.startswith('3', 'fdjk')
+
+        self.assertRaises(TypeError, fail)
+
+
+class TestMethods(TestCase):
+    def setUp(self):
+        self.A = np.array([[' abc ', ''],
+                           ['12345', 'MixedCase'],
+                           ['123 \t 345 \0 ', 'UPPER']],
+                          dtype='S').view(np.chararray)
+        self.B = np.array([[sixu(' \u03a3 '), sixu('')],
+                           [sixu('12345'), sixu('MixedCase')],
+                           [sixu('123 \t 345 \0 '), sixu('UPPER')]]).view(np.chararray)
+
+    def test_capitalize(self):
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12345', 'Mixedcase'],
+                              ['123 \t 345 \0 ', 'Upper']])
+        assert_(issubclass(self.A.capitalize().dtype.type, np.string_))
+        assert_array_equal(self.A.capitalize(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), ''],
+               ['12345', 'Mixedcase'],
+               ['123 \t 345 \0 ', 'Upper']]
+        assert_(issubclass(self.B.capitalize().dtype.type, np.unicode_))
+        assert_array_equal(self.B.capitalize(), tgt)
+
+    def test_center(self):
+        assert_(issubclass(self.A.center(10).dtype.type, np.string_))
+        C = self.A.center([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.center(20, asbytes('#'))
+        assert_(np.all(C.startswith(asbytes('#'))))
+        assert_(np.all(C.endswith(asbytes('#'))))
+
+        C = np.char.center(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['   FOO    ', '        FOO         '],
+                              ['      FOO      ', '  FOO   ']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_decode(self):
+        if sys.version_info[0] >= 3:
+            A = np.char.array([asbytes('\\u03a3')])
+            assert_(A.decode('unicode-escape')[0] == '\u03a3')
+        else:
+            A = np.char.array(['736563726574206d657373616765'])
+            assert_(A.decode('hex_codec')[0] == 'secret message')
+
+    def test_encode(self):
+        B = self.B.encode('unicode_escape')
+        assert_(B[0][0] == str(' \\u03a3 ').encode('latin1'))
+
+    def test_expandtabs(self):
+        T = self.A.expandtabs()
+        assert_(T[2, 0] == asbytes('123      345 \0'))
+
+    def test_join(self):
+        if sys.version_info[0] >= 3:
+            # NOTE: list(b'123') == [49, 50, 51]
+            #       so that b','.join(b'123') results to an error on Py3
+            A0 = self.A.decode('ascii')
+        else:
+            A0 = self.A
+
+        A = np.char.join([',', '#'], A0)
+        if sys.version_info[0] >= 3:
+            assert_(issubclass(A.dtype.type, np.unicode_))
+        else:
+            assert_(issubclass(A.dtype.type, np.string_))
+        tgt = np.array([[' ,a,b,c, ', ''],
+                        ['1,2,3,4,5', 'M#i#x#e#d#C#a#s#e'],
+                        ['1,2,3, ,\t, ,3,4,5, ,\x00, ', 'U#P#P#E#R']])
+        assert_array_equal(np.char.join([',', '#'], A0), tgt)
+
+    def test_ljust(self):
+        assert_(issubclass(self.A.ljust(10).dtype.type, np.string_))
+
+        C = self.A.ljust([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.ljust(20, asbytes('#'))
+        assert_array_equal(C.startswith(asbytes('#')), [
+                [False, True], [False, False], [False, False]])
+        assert_(np.all(C.endswith(asbytes('#'))))
+
+        C = np.char.ljust(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['FOO       ', 'FOO                 '],
+                              ['FOO            ', 'FOO     ']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_lower(self):
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12345', 'mixedcase'],
+                              ['123 \t 345 \0 ', 'upper']])
+        assert_(issubclass(self.A.lower().dtype.type, np.string_))
+        assert_array_equal(self.A.lower(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), sixu('')],
+               [sixu('12345'), sixu('mixedcase')],
+               [sixu('123 \t 345 \0 '), sixu('upper')]]
+        assert_(issubclass(self.B.lower().dtype.type, np.unicode_))
+        assert_array_equal(self.B.lower(), tgt)
+
+    def test_lstrip(self):
+        tgt = asbytes_nested([['abc ', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345 \0 ', 'UPPER']])
+        assert_(issubclass(self.A.lstrip().dtype.type, np.string_))
+        assert_array_equal(self.A.lstrip(), tgt)
+
+        tgt = asbytes_nested([[' abc', ''],
+                              ['2345', 'ixedCase'],
+                              ['23 \t 345 \x00', 'UPPER']])
+        assert_array_equal(self.A.lstrip(asbytes_nested(['1', 'M'])), tgt)
+
+        tgt = [[sixu('\u03a3 '), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345 \0 ', 'UPPER']]
+        assert_(issubclass(self.B.lstrip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.lstrip(), tgt)
+
+    def test_partition(self):
+        P = self.A.partition(asbytes_nested(['3', 'M']))
+        tgt = asbytes_nested([[(' abc ', '', ''), ('', '', '')],
+                             [('12', '3', '45'), ('', 'M', 'ixedCase')],
+                             [('12', '3', ' \t 345 \0 '), ('UPPER', '', '')]])
+        assert_(issubclass(P.dtype.type, np.string_))
+        assert_array_equal(P, tgt)
+
+    def test_replace(self):
+        R = self.A.replace(asbytes_nested(['3', 'a']),
+                           asbytes_nested(['##########', '@']))
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['12##########45', 'MixedC@se'],
+                              ['12########## \t ##########45 \x00', 'UPPER']])
+        assert_(issubclass(R.dtype.type, np.string_))
+        assert_array_equal(R, tgt)
+
+        if sys.version_info[0] < 3:
+            # NOTE: b'abc'.replace(b'a', 'b') is not allowed on Py3
+            R = self.A.replace(asbytes('a'), sixu('\u03a3'))
+            tgt = [[sixu(' \u03a3bc '), ''],
+                   ['12345', sixu('MixedC\u03a3se')],
+                   ['123 \t 345 \x00', 'UPPER']]
+            assert_(issubclass(R.dtype.type, np.unicode_))
+            assert_array_equal(R, tgt)
+
+    def test_rjust(self):
+        assert_(issubclass(self.A.rjust(10).dtype.type, np.string_))
+
+        C = self.A.rjust([10, 20])
+        assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
+
+        C = self.A.rjust(20, asbytes('#'))
+        assert_(np.all(C.startswith(asbytes('#'))))
+        assert_array_equal(C.endswith(asbytes('#')),
+                           [[False, True], [False, False], [False, False]])
+
+        C = np.char.rjust(asbytes('FOO'), [[10, 20], [15, 8]])
+        tgt = asbytes_nested([['       FOO', '                 FOO'],
+                              ['            FOO', '     FOO']])
+        assert_(issubclass(C.dtype.type, np.string_))
+        assert_array_equal(C, tgt)
+
+    def test_rpartition(self):
+        P = self.A.rpartition(asbytes_nested(['3', 'M']))
+        tgt = asbytes_nested([[('', '', ' abc '), ('', '', '')],
+                              [('12', '3', '45'), ('', 'M', 'ixedCase')],
+                              [('123 \t ', '3', '45 \0 '), ('', '', 'UPPER')]])
+        assert_(issubclass(P.dtype.type, np.string_))
+        assert_array_equal(P, tgt)
+
+    def test_rsplit(self):
+        A = self.A.rsplit(asbytes('3'))
+        tgt = asbytes_nested([[[' abc '], ['']],
+                              [['12', '45'], ['MixedCase']],
+                              [['12', ' \t ', '45 \x00 '], ['UPPER']]])
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_equal(A.tolist(), tgt)
+
+    def test_rstrip(self):
+        assert_(issubclass(self.A.rstrip().dtype.type, np.string_))
+
+        tgt = asbytes_nested([[' abc', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345', 'UPPER']])
+        assert_array_equal(self.A.rstrip(), tgt)
+
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['1234', 'MixedCase'],
+                              ['123 \t 345 \x00', 'UPP']
+                              ])
+        assert_array_equal(self.A.rstrip(asbytes_nested(['5', 'ER'])), tgt)
+
+        tgt = [[sixu(' \u03a3'), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345', 'UPPER']]
+        assert_(issubclass(self.B.rstrip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.rstrip(), tgt)
+
+    def test_strip(self):
+        tgt = asbytes_nested([['abc', ''],
+                              ['12345', 'MixedCase'],
+                              ['123 \t 345', 'UPPER']])
+        assert_(issubclass(self.A.strip().dtype.type, np.string_))
+        assert_array_equal(self.A.strip(), tgt)
+
+        tgt = asbytes_nested([[' abc ', ''],
+                              ['234', 'ixedCas'],
+                              ['23 \t 345 \x00', 'UPP']])
+        assert_array_equal(self.A.strip(asbytes_nested(['15', 'EReM'])), tgt)
+
+        tgt = [[sixu('\u03a3'), ''],
+               ['12345', 'MixedCase'],
+               ['123 \t 345', 'UPPER']]
+        assert_(issubclass(self.B.strip().dtype.type, np.unicode_))
+        assert_array_equal(self.B.strip(), tgt)
+
+    def test_split(self):
+        A = self.A.split(asbytes('3'))
+        tgt = asbytes_nested([
+                              [[' abc '], ['']],
+                              [['12', '45'], ['MixedCase']],
+                              [['12', ' \t ', '45 \x00 '], ['UPPER']]])
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_equal(A.tolist(), tgt)
+
+    def test_splitlines(self):
+        A = np.char.array(['abc\nfds\nwer']).splitlines()
+        assert_(issubclass(A.dtype.type, np.object_))
+        assert_(A.shape == (1,))
+        assert_(len(A[0]) == 3)
+
+    def test_swapcase(self):
+        tgt = asbytes_nested([[' ABC ', ''],
+                              ['12345', 'mIXEDcASE'],
+                              ['123 \t 345 \0 ', 'upper']])
+        assert_(issubclass(self.A.swapcase().dtype.type, np.string_))
+        assert_array_equal(self.A.swapcase(), tgt)
+
+        tgt = [[sixu(' \u03c3 '), sixu('')],
+               [sixu('12345'), sixu('mIXEDcASE')],
+               [sixu('123 \t 345 \0 '), sixu('upper')]]
+        assert_(issubclass(self.B.swapcase().dtype.type, np.unicode_))
+        assert_array_equal(self.B.swapcase(), tgt)
+
+    def test_title(self):
+        tgt = asbytes_nested([[' Abc ', ''],
+                              ['12345', 'Mixedcase'],
+                              ['123 \t 345 \0 ', 'Upper']])
+        assert_(issubclass(self.A.title().dtype.type, np.string_))
+        assert_array_equal(self.A.title(), tgt)
+
+        tgt = [[sixu(' \u03a3 '), sixu('')],
+               [sixu('12345'), sixu('Mixedcase')],
+               [sixu('123 \t 345 \0 '), sixu('Upper')]]
+        assert_(issubclass(self.B.title().dtype.type, np.unicode_))
+        assert_array_equal(self.B.title(), tgt)
+
+    def test_upper(self):
+        tgt = asbytes_nested([[' ABC ', ''],
+                              ['12345', 'MIXEDCASE'],
+                              ['123 \t 345 \0 ', 'UPPER']])
+        assert_(issubclass(self.A.upper().dtype.type, np.string_))
+        assert_array_equal(self.A.upper(), tgt)
+
+        tgt = [[sixu(' \u03a3 '), sixu('')],
+               [sixu('12345'), sixu('MIXEDCASE')],
+               [sixu('123 \t 345 \0 '), sixu('UPPER')]]
+        assert_(issubclass(self.B.upper().dtype.type, np.unicode_))
+        assert_array_equal(self.B.upper(), tgt)
+
+    def test_isnumeric(self):
+
+        def fail():
+            self.A.isnumeric()
+
+        self.assertRaises(TypeError, fail)
+        assert_(issubclass(self.B.isnumeric().dtype.type, np.bool_))
+        assert_array_equal(self.B.isnumeric(), [
+                [False, False], [True, False], [False, False]])
+
+    def test_isdecimal(self):
+
+        def fail():
+            self.A.isdecimal()
+
+        self.assertRaises(TypeError, fail)
+        assert_(issubclass(self.B.isdecimal().dtype.type, np.bool_))
+        assert_array_equal(self.B.isdecimal(), [
+                [False, False], [True, False], [False, False]])
+
+
+class TestOperations(TestCase):
+    def setUp(self):
+        self.A = np.array([['abc', '123'],
+                           ['789', 'xyz']]).view(np.chararray)
+        self.B = np.array([['efg', '456'],
+                           ['051', 'tuv']]).view(np.chararray)
+
+    def test_add(self):
+        AB = np.array([['abcefg', '123456'],
+                       ['789051', 'xyztuv']]).view(np.chararray)
+        assert_array_equal(AB, (self.A + self.B))
+        assert_(len((self.A + self.B)[0][0]) == 6)
+
+    def test_radd(self):
+        QA = np.array([['qabc', 'q123'],
+                       ['q789', 'qxyz']]).view(np.chararray)
+        assert_array_equal(QA, ('q' + self.A))
+
+    def test_mul(self):
+        A = self.A
+        for r in (2, 3, 5, 7, 197):
+            Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
+                           [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray)
+
+            assert_array_equal(Ar, (self.A * r))
+
+        for ob in [object(), 'qrs']:
+            try:
+                A * ob
+            except ValueError:
+                pass
+            else:
+                self.fail("chararray can only be multiplied by integers")
+
+    def test_rmul(self):
+        A = self.A
+        for r in (2, 3, 5, 7, 197):
+            Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
+                           [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray)
+            assert_array_equal(Ar, (r * self.A))
+
+        for ob in [object(), 'qrs']:
+            try:
+                ob * A
+            except ValueError:
+                pass
+            else:
+                self.fail("chararray can only be multiplied by integers")
+
+    def test_mod(self):
+        """Ticket #856"""
+        F = np.array([['%d', '%f'], ['%s', '%r']]).view(np.chararray)
+        C = np.array([[3, 7], [19, 1]])
+        FC = np.array([['3', '7.000000'],
+                       ['19', '1']]).view(np.chararray)
+        assert_array_equal(FC, F % C)
+
+        A = np.array([['%.3f', '%d'], ['%s', '%r']]).view(np.chararray)
+        A1 = np.array([['1.000', '1'], ['1', '1']]).view(np.chararray)
+        assert_array_equal(A1, (A % 1))
+
+        A2 = np.array([['1.000', '2'], ['3', '4']]).view(np.chararray)
+        assert_array_equal(A2, (A % [[1, 2], [3, 4]]))
+
+    def test_rmod(self):
+        assert_(("%s" % self.A) == str(self.A))
+        assert_(("%r" % self.A) == repr(self.A))
+
+        for ob in [42, object()]:
+            try:
+                ob % self.A
+            except TypeError:
+                pass
+            else:
+                self.fail("chararray __rmod__ should fail with "
+                          "non-string objects")
+
+    def test_slice(self):
+        """Regression test for https://github.com/numpy/numpy/issues/5982"""
+
+        arr = np.array([['abc ', 'def '], ['geh ', 'ijk ']],
+                       dtype='S4').view(np.chararray)
+        sl1 = arr[:]
+        assert_array_equal(sl1, arr)
+        assert_(sl1.base is arr)
+        assert_(sl1.base.base is arr.base)
+
+        sl2 = arr[:, :]
+        assert_array_equal(sl2, arr)
+        assert_(sl2.base is arr)
+        assert_(sl2.base.base is arr.base)
+
+        assert_(arr[0, 0] == asbytes('abc'))
+
+
+def test_empty_indexing():
+    """Regression test for ticket 1948."""
+    # Check that indexing a chararray with an empty list/array returns an
+    # empty chararray instead of a chararray with a single empty string in it.
+    s = np.chararray((4,))
+    assert_(s[[]].size == 0)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
new file mode 100644
index 0000000000..562e6966fe
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
@@ -0,0 +1,809 @@
+"""
+Tests related to deprecation warnings. Also a convenient place
+to document how deprecations should eventually be turned into errors.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import datetime
+import sys
+import operator
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_raises, assert_warns, assert_no_warnings,
+    assert_array_equal, assert_, dec)
+
+try:
+    import pytz
+    _has_pytz = True
+except ImportError:
+    _has_pytz = False
+
+
+class _VisibleDeprecationTestCase(object):
+    # Just as warning: warnings uses re.match, so the start of this message
+    # must match.
+    message = ''
+
+    def setUp(self):
+        self.warn_ctx = warnings.catch_warnings(record=True)
+        self.log = self.warn_ctx.__enter__()
+
+        # Do *not* ignore other DeprecationWarnings. Ignoring warnings
+        # can give very confusing results because of
+        # http://bugs.python.org/issue4180 and it is probably simplest to
+        # try to keep the tests cleanly giving only the right warning type.
+        # (While checking them set to "error" those are ignored anyway)
+        # We still have them show up, because otherwise they would be raised
+        warnings.filterwarnings("always", category=np.VisibleDeprecationWarning)
+        warnings.filterwarnings("always", message=self.message,
+                                category=np.VisibleDeprecationWarning)
+
+    def tearDown(self):
+        self.warn_ctx.__exit__()
+
+    def assert_deprecated(self, function, num=1, ignore_others=False,
+                          function_fails=False,
+                          exceptions=(np.VisibleDeprecationWarning,),
+                          args=(), kwargs={}):
+        """Test if VisibleDeprecationWarnings are given and raised.
+
+        This first checks if the function when called gives `num`
+        VisibleDeprecationWarnings, after that it tries to raise these
+        VisibleDeprecationWarnings and compares them with `exceptions`.
+        The exceptions can be different for cases where this code path
+        is simply not anticipated and the exception is replaced.
+
+        Parameters
+        ----------
+        f : callable
+            The function to test
+        num : int
+            Number of VisibleDeprecationWarnings to expect. This should
+            normally be 1.
+        ignore_other : bool
+            Whether warnings of the wrong type should be ignored (note that
+            the message is not checked)
+        function_fails : bool
+            If the function would normally fail, setting this will check for
+            warnings inside a try/except block.
+        exceptions : Exception or tuple of Exceptions
+            Exception to expect when turning the warnings into an error.
+            The default checks for DeprecationWarnings. If exceptions is
+            empty the function is expected to run successfull.
+        args : tuple
+            Arguments for `f`
+        kwargs : dict
+            Keyword arguments for `f`
+        """
+        # reset the log
+        self.log[:] = []
+
+        try:
+            function(*args, **kwargs)
+        except (Exception if function_fails else tuple()):
+            pass
+
+        # just in case, clear the registry
+        num_found = 0
+        for warning in self.log:
+            if warning.category is np.VisibleDeprecationWarning:
+                num_found += 1
+            elif not ignore_others:
+                raise AssertionError(
+                        "expected DeprecationWarning but got: %s" %
+                        (warning.category,))
+        if num is not None and num_found != num:
+            msg = "%i warnings found but %i expected." % (len(self.log), num)
+            lst = [w.category for w in self.log]
+            raise AssertionError("\n".join([msg] + lst))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error", message=self.message,
+                                    category=np.VisibleDeprecationWarning)
+            try:
+                function(*args, **kwargs)
+                if exceptions != tuple():
+                    raise AssertionError(
+                            "No error raised during function call")
+            except exceptions:
+                if exceptions == tuple():
+                    raise AssertionError(
+                            "Error raised during function call")
+
+    def assert_not_deprecated(self, function, args=(), kwargs={}):
+        """Test if VisibleDeprecationWarnings are given and raised.
+
+        This is just a shorthand for:
+
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+        """
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+
+
+class _DeprecationTestCase(object):
+    # Just as warning: warnings uses re.match, so the start of this message
+    # must match.
+    message = ''
+
+    def setUp(self):
+        self.warn_ctx = warnings.catch_warnings(record=True)
+        self.log = self.warn_ctx.__enter__()
+
+        # Do *not* ignore other DeprecationWarnings. Ignoring warnings
+        # can give very confusing results because of
+        # http://bugs.python.org/issue4180 and it is probably simplest to
+        # try to keep the tests cleanly giving only the right warning type.
+        # (While checking them set to "error" those are ignored anyway)
+        # We still have them show up, because otherwise they would be raised
+        warnings.filterwarnings("always", category=DeprecationWarning)
+        warnings.filterwarnings("always", message=self.message,
+                                    category=DeprecationWarning)
+
+    def tearDown(self):
+        self.warn_ctx.__exit__()
+
+    def assert_deprecated(self, function, num=1, ignore_others=False,
+                        function_fails=False,
+                        exceptions=(DeprecationWarning,), args=(), kwargs={}):
+        """Test if DeprecationWarnings are given and raised.
+
+        This first checks if the function when called gives `num`
+        DeprecationWarnings, after that it tries to raise these
+        DeprecationWarnings and compares them with `exceptions`.
+        The exceptions can be different for cases where this code path
+        is simply not anticipated and the exception is replaced.
+
+        Parameters
+        ----------
+        f : callable
+            The function to test
+        num : int
+            Number of DeprecationWarnings to expect. This should normally be 1.
+        ignore_other : bool
+            Whether warnings of the wrong type should be ignored (note that
+            the message is not checked)
+        function_fails : bool
+            If the function would normally fail, setting this will check for
+            warnings inside a try/except block.
+        exceptions : Exception or tuple of Exceptions
+            Exception to expect when turning the warnings into an error.
+            The default checks for DeprecationWarnings. If exceptions is
+            empty the function is expected to run successfull.
+        args : tuple
+            Arguments for `f`
+        kwargs : dict
+            Keyword arguments for `f`
+        """
+        # reset the log
+        self.log[:] = []
+
+        try:
+            function(*args, **kwargs)
+        except (Exception if function_fails else tuple()):
+            pass
+
+        # just in case, clear the registry
+        num_found = 0
+        for warning in self.log:
+            if warning.category is DeprecationWarning:
+                num_found += 1
+            elif not ignore_others:
+                raise AssertionError(
+                        "expected DeprecationWarning but got: %s" %
+                        (warning.category,))
+        if num is not None and num_found != num:
+            msg = "%i warnings found but %i expected." % (len(self.log), num)
+            lst = [w.category for w in self.log]
+            raise AssertionError("\n".join([msg] + lst))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error", message=self.message,
+                                    category=DeprecationWarning)
+            try:
+                function(*args, **kwargs)
+                if exceptions != tuple():
+                    raise AssertionError(
+                            "No error raised during function call")
+            except exceptions:
+                if exceptions == tuple():
+                    raise AssertionError(
+                            "Error raised during function call")
+
+    def assert_not_deprecated(self, function, args=(), kwargs={}):
+        """Test if DeprecationWarnings are given and raised.
+
+        This is just a shorthand for:
+
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+        """
+        self.assert_deprecated(function, num=0, ignore_others=True,
+                        exceptions=tuple(), args=args, kwargs=kwargs)
+
+
+class TestFloatNonIntegerArgumentDeprecation(_VisibleDeprecationTestCase):
+    """
+    These test that ``DeprecationWarning`` is given when you try to use
+    non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]``
+    and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``.
+
+    After deprecation, changes need to be done inside conversion_utils.c
+    in PyArray_PyIntAsIntp and possibly PyArray_IntpConverter.
+    In iterators.c the function slice_GetIndices could be removed in favor
+    of its python equivalent and in mapping.c the function _tuple_of_integers
+    can be simplified (if ``np.array([1]).__index__()`` is also deprecated).
+
+    As for the deprecation time-frame: via Ralf Gommers,
+
+    "Hard to put that as a version number, since we don't know if the
+    version after 1.8 will be 6 months or 2 years after. I'd say 2
+    years is reasonable."
+
+    I interpret this to mean 2 years after the 1.8 release. Possibly
+    giving a PendingDeprecationWarning before that (which is visible
+    by default)
+
+    """
+    message = "using a non-integer number instead of an integer " \
+              "will result in an error in the future"
+
+    def test_indexing(self):
+        a = np.array([[[5]]])
+
+        def assert_deprecated(*args, **kwargs):
+            self.assert_deprecated(*args, exceptions=(IndexError,), **kwargs)
+
+        assert_deprecated(lambda: a[0.0])
+        assert_deprecated(lambda: a[0, 0.0])
+        assert_deprecated(lambda: a[0.0, 0])
+        assert_deprecated(lambda: a[0.0,:])
+        assert_deprecated(lambda: a[:, 0.0])
+        assert_deprecated(lambda: a[:, 0.0,:])
+        assert_deprecated(lambda: a[0.0,:,:])
+        assert_deprecated(lambda: a[0, 0, 0.0])
+        assert_deprecated(lambda: a[0.0, 0, 0])
+        assert_deprecated(lambda: a[0, 0.0, 0])
+        assert_deprecated(lambda: a[-1.4])
+        assert_deprecated(lambda: a[0, -1.4])
+        assert_deprecated(lambda: a[-1.4, 0])
+        assert_deprecated(lambda: a[-1.4,:])
+        assert_deprecated(lambda: a[:, -1.4])
+        assert_deprecated(lambda: a[:, -1.4,:])
+        assert_deprecated(lambda: a[-1.4,:,:])
+        assert_deprecated(lambda: a[0, 0, -1.4])
+        assert_deprecated(lambda: a[-1.4, 0, 0])
+        assert_deprecated(lambda: a[0, -1.4, 0])
+
+        # Test that the slice parameter deprecation warning doesn't mask
+        # the scalar index warning.
+        assert_deprecated(lambda: a[0.0:, 0.0], num=2)
+        assert_deprecated(lambda: a[0.0:, 0.0,:], num=2)
+
+    def test_valid_indexing(self):
+        a = np.array([[[5]]])
+        assert_not_deprecated = self.assert_not_deprecated
+
+        assert_not_deprecated(lambda: a[np.array([0])])
+        assert_not_deprecated(lambda: a[[0, 0]])
+        assert_not_deprecated(lambda: a[:, [0, 0]])
+        assert_not_deprecated(lambda: a[:, 0,:])
+        assert_not_deprecated(lambda: a[:,:,:])
+
+    def test_slicing(self):
+        a = np.array([[5]])
+
+        def assert_deprecated(*args, **kwargs):
+            self.assert_deprecated(*args, exceptions=(IndexError,), **kwargs)
+
+        # start as float.
+        assert_deprecated(lambda: a[0.0:])
+        assert_deprecated(lambda: a[0:, 0.0:2])
+        assert_deprecated(lambda: a[0.0::2, :0])
+        assert_deprecated(lambda: a[0.0:1:2,:])
+        assert_deprecated(lambda: a[:, 0.0:])
+        # stop as float.
+        assert_deprecated(lambda: a[:0.0])
+        assert_deprecated(lambda: a[:0, 1:2.0])
+        assert_deprecated(lambda: a[:0.0:2, :0])
+        assert_deprecated(lambda: a[:0.0,:])
+        assert_deprecated(lambda: a[:, 0:4.0:2])
+        # step as float.
+        assert_deprecated(lambda: a[::1.0])
+        assert_deprecated(lambda: a[0:, :2:2.0])
+        assert_deprecated(lambda: a[1::4.0, :0])
+        assert_deprecated(lambda: a[::5.0,:])
+        assert_deprecated(lambda: a[:, 0:4:2.0])
+        # mixed.
+        assert_deprecated(lambda: a[1.0:2:2.0], num=2)
+        assert_deprecated(lambda: a[1.0::2.0], num=2)
+        assert_deprecated(lambda: a[0:, :2.0:2.0], num=2)
+        assert_deprecated(lambda: a[1.0:1:4.0, :0], num=2)
+        assert_deprecated(lambda: a[1.0:5.0:5.0,:], num=3)
+        assert_deprecated(lambda: a[:, 0.4:4.0:2.0], num=3)
+        # should still get the DeprecationWarning if step = 0.
+        assert_deprecated(lambda: a[::0.0], function_fails=True)
+
+    def test_valid_slicing(self):
+        a = np.array([[[5]]])
+        assert_not_deprecated = self.assert_not_deprecated
+
+        assert_not_deprecated(lambda: a[::])
+        assert_not_deprecated(lambda: a[0:])
+        assert_not_deprecated(lambda: a[:2])
+        assert_not_deprecated(lambda: a[0:2])
+        assert_not_deprecated(lambda: a[::2])
+        assert_not_deprecated(lambda: a[1::2])
+        assert_not_deprecated(lambda: a[:2:2])
+        assert_not_deprecated(lambda: a[1:2:2])
+
+    def test_non_integer_argument_deprecations(self):
+        a = np.array([[5]])
+
+        self.assert_deprecated(np.reshape, args=(a, (1., 1., -1)), num=2)
+        self.assert_deprecated(np.reshape, args=(a, (np.array(1.), -1)))
+        self.assert_deprecated(np.take, args=(a, [0], 1.))
+        self.assert_deprecated(np.take, args=(a, [0], np.float64(1.)))
+
+    def test_non_integer_sequence_multiplication(self):
+        # Numpy scalar sequence multiply should not work with non-integers
+        def mult(a, b):
+            return a * b
+
+        self.assert_deprecated(mult, args=([1], np.float_(3)))
+        self.assert_not_deprecated(mult, args=([1], np.int_(3)))
+
+    def test_reduce_axis_float_index(self):
+        d = np.zeros((3,3,3))
+        self.assert_deprecated(np.min, args=(d, 0.5))
+        self.assert_deprecated(np.min, num=1, args=(d, (0.5, 1)))
+        self.assert_deprecated(np.min, num=1, args=(d, (1, 2.2)))
+        self.assert_deprecated(np.min, num=2, args=(d, (.2, 1.2)))
+
+
+class TestBooleanArgumentDeprecation(_VisibleDeprecationTestCase):
+    """This tests that using a boolean as integer argument/indexing is
+    deprecated.
+
+    This should be kept in sync with TestFloatNonIntegerArgumentDeprecation
+    and like it is handled in PyArray_PyIntAsIntp.
+    """
+    message = "using a boolean instead of an integer " \
+              "will result in an error in the future"
+
+    def test_bool_as_int_argument(self):
+        a = np.array([[[1]]])
+
+        self.assert_deprecated(np.reshape, args=(a, (True, -1)))
+        self.assert_deprecated(np.reshape, args=(a, (np.bool_(True), -1)))
+        # Note that operator.index(np.array(True)) does not work, a boolean
+        # array is thus also deprecated, but not with the same message:
+        assert_raises(TypeError, operator.index, np.array(True))
+        self.assert_deprecated(np.take, args=(a, [0], False))
+        self.assert_deprecated(lambda: a[False:True:True], exceptions=IndexError, num=3)
+        self.assert_deprecated(lambda: a[False, 0], exceptions=IndexError)
+        self.assert_deprecated(lambda: a[False, 0, 0], exceptions=IndexError)
+
+
+class TestArrayToIndexDeprecation(_VisibleDeprecationTestCase):
+    """This tests that creating an an index from an array is deprecated
+    if the array is not 0d.
+
+    This can probably be deprecated somewhat faster then the integer
+    deprecations. The deprecation period started with NumPy 1.8.
+    For deprecation this needs changing of array_index in number.c
+    """
+    message = "converting an array with ndim \> 0 to an index will result " \
+              "in an error in the future"
+
+    def test_array_to_index_deprecation(self):
+        # This drops into the non-integer deprecation, which is ignored here,
+        # so no exception is expected. The raising is effectively tested above.
+        a = np.array([[[1]]])
+
+        self.assert_deprecated(operator.index, args=(np.array([1]),))
+        self.assert_deprecated(np.reshape, args=(a, (a, -1)), exceptions=())
+        self.assert_deprecated(np.take, args=(a, [0], a), exceptions=())
+        # Check slicing. Normal indexing checks arrays specifically.
+        self.assert_deprecated(lambda: a[a:a:a], exceptions=(), num=3)
+
+class TestNonIntegerArrayLike(_VisibleDeprecationTestCase):
+    """Tests that array likes, i.e. lists give a deprecation warning
+    when they cannot be safely cast to an integer.
+    """
+    message = "non integer \(and non boolean\) array-likes will not be " \
+              "accepted as indices in the future"
+
+    def test_basic(self):
+        a = np.arange(10)
+        self.assert_deprecated(a.__getitem__, args=([0.5, 1.5],),
+                               exceptions=IndexError)
+        self.assert_deprecated(a.__getitem__, args=((['1', '2'],),),
+                               exceptions=IndexError)
+
+        self.assert_not_deprecated(a.__getitem__, ([],))
+
+    def test_boolean_futurewarning(self):
+        a = np.arange(10)
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always')
+            assert_warns(FutureWarning, a.__getitem__, [True])
+            # Unfortunatly, the deprecation warning takes precedence:
+            #assert_warns(FutureWarning, a.__getitem__, True)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error')
+            assert_raises(FutureWarning, a.__getitem__, [True])
+            #assert_raises(FutureWarning, a.__getitem__, True)
+
+
+class TestMultipleEllipsisDeprecation(_VisibleDeprecationTestCase):
+    message = "an index can only have a single Ellipsis \(`...`\); replace " \
+              "all but one with slices \(`:`\)."
+
+    def test_basic(self):
+        a = np.arange(10)
+        self.assert_deprecated(a.__getitem__, args=((Ellipsis, Ellipsis),))
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', '', np.VisibleDeprecationWarning)
+            # Just check that this works:
+            b = a[...,...]
+            assert_array_equal(a, b)
+            assert_raises(IndexError, a.__getitem__, ((Ellipsis, ) * 3,))
+
+
+class TestBooleanUnaryMinusDeprecation(_DeprecationTestCase):
+    """Test deprecation of unary boolean `-`. While + and * are well
+    defined, unary - is not and even a corrected form seems to have
+    no real uses.
+
+    The deprecation process was started in NumPy 1.9.
+    """
+    message = r"numpy boolean negative, the `-` operator, .*"
+
+    def test_unary_minus_operator_deprecation(self):
+        array = np.array([True])
+        generic = np.bool_(True)
+
+        # Unary minus/negative ufunc:
+        self.assert_deprecated(operator.neg, args=(array,))
+        self.assert_deprecated(operator.neg, args=(generic,))
+
+
+class TestBooleanBinaryMinusDeprecation(_DeprecationTestCase):
+    """Test deprecation of binary boolean `-`. While + and * are well
+    defined, binary  - is not and even a corrected form seems to have
+    no real uses.
+
+    The deprecation process was started in NumPy 1.9.
+    """
+    message = r"numpy boolean subtract, the `-` operator, .*"
+
+    def test_operator_deprecation(self):
+        array = np.array([True])
+        generic = np.bool_(True)
+
+        # Minus operator/subtract ufunc:
+        self.assert_deprecated(operator.sub, args=(array, array))
+        self.assert_deprecated(operator.sub, args=(generic, generic))
+
+
+class TestRankDeprecation(_DeprecationTestCase):
+    """Test that np.rank is deprecated. The function should simply be
+    removed. The VisibleDeprecationWarning may become unnecessary.
+    """
+
+    def test(self):
+        a = np.arange(10)
+        assert_warns(np.VisibleDeprecationWarning, np.rank, a)
+
+
+class TestComparisonDeprecations(_DeprecationTestCase):
+    """This tests the deprecation, for non-element-wise comparison logic.
+    This used to mean that when an error occurred during element-wise comparison
+    (i.e. broadcasting) NotImplemented was returned, but also in the comparison
+    itself, False was given instead of the error.
+
+    Also test FutureWarning for the None comparison.
+    """
+
+    message = "elementwise.* comparison failed; .*"
+
+    def test_normal_types(self):
+        for op in (operator.eq, operator.ne):
+            # Broadcasting errors:
+            self.assert_deprecated(op, args=(np.zeros(3), []))
+            a = np.zeros(3, dtype='i,i')
+            # (warning is issued a couple of times here)
+            self.assert_deprecated(op, args=(a, a[:-1]), num=None)
+
+            # Element comparison error (numpy array can't be compared).
+            a = np.array([1, np.array([1,2,3])], dtype=object)
+            b = np.array([1, np.array([1,2,3])], dtype=object)
+            self.assert_deprecated(op, args=(a, b), num=None)
+
+    def test_string(self):
+        # For two string arrays, strings always raised the broadcasting error:
+        a = np.array(['a', 'b'])
+        b = np.array(['a', 'b', 'c'])
+        assert_raises(ValueError, lambda x, y: x == y, a, b)
+
+        # The empty list is not cast to string, as this is only to document
+        # that fact (it likely should be changed). This means that the
+        # following works (and returns False) due to dtype mismatch:
+        a == []
+
+    def test_none_comparison(self):
+        # Test comparison of None, which should result in element-wise
+        # comparison in the future. [1, 2] == None should be [False, False].
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_warns(FutureWarning, operator.eq, np.arange(3), None)
+            assert_warns(FutureWarning, operator.ne, np.arange(3), None)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', FutureWarning)
+            assert_raises(FutureWarning, operator.eq, np.arange(3), None)
+            assert_raises(FutureWarning, operator.ne, np.arange(3), None)
+
+    def test_scalar_none_comparison(self):
+        # Scalars should still just return False and not give a warnings.
+        # The comparisons are flagged by pep8, ignore that.
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_(not np.float32(1) == None)
+            assert_(not np.str_('test') == None)
+            # This is dubious (see below):
+            assert_(not np.datetime64('NaT') == None)
+
+            assert_(np.float32(1) != None)
+            assert_(np.str_('test') != None)
+            # This is dubious (see below):
+            assert_(np.datetime64('NaT') != None)
+        assert_(len(w) == 0)
+
+        # For documentation purposes, this is why the datetime is dubious.
+        # At the time of deprecation this was no behaviour change, but
+        # it has to be considered when the deprecations are done.
+        assert_(np.equal(np.datetime64('NaT'), None))
+
+    def test_void_dtype_equality_failures(self):
+        class NotArray(object):
+            def __array__(self):
+                raise TypeError
+
+            # Needed so Python 3 does not raise DeprecationWarning twice.
+            def __ne__(self, other):
+                return NotImplemented
+
+        self.assert_deprecated(lambda: np.arange(2) == NotArray())
+        self.assert_deprecated(lambda: np.arange(2) != NotArray())
+
+        struct1 = np.zeros(2, dtype="i4,i4")
+        struct2 = np.zeros(2, dtype="i4,i4,i4")
+
+        assert_warns(FutureWarning, lambda: struct1 == 1)
+        assert_warns(FutureWarning, lambda: struct1 == struct2)
+        assert_warns(FutureWarning, lambda: struct1 != 1)
+        assert_warns(FutureWarning, lambda: struct1 != struct2)
+
+    def test_array_richcompare_legacy_weirdness(self):
+        # It doesn't really work to use assert_deprecated here, b/c part of
+        # the point of assert_deprecated is to check that when warnings are
+        # set to "error" mode then the error is propagated -- which is good!
+        # But here we are testing a bunch of code that is deprecated *because*
+        # it has the habit of swallowing up errors and converting them into
+        # different warnings. So assert_warns will have to be sufficient.
+        assert_warns(FutureWarning, lambda: np.arange(2) == "a")
+        assert_warns(FutureWarning, lambda: np.arange(2) != "a")
+        # No warning for scalar comparisons
+        with warnings.catch_warnings():
+            warnings.filterwarnings("error")
+            assert_(not (np.array(0) == "a"))
+            assert_(np.array(0) != "a")
+            assert_(not (np.int16(0) == "a"))
+            assert_(np.int16(0) != "a")
+
+        for arg1 in [np.asarray(0), np.int16(0)]:
+            struct = np.zeros(2, dtype="i4,i4")
+            for arg2 in [struct, "a"]:
+                for f in [operator.lt, operator.le, operator.gt, operator.ge]:
+                    if sys.version_info[0] >= 3:
+                        # py3
+                        with warnings.catch_warnings() as l:
+                            warnings.filterwarnings("always")
+                            assert_raises(TypeError, f, arg1, arg2)
+                            assert_(not l)
+                    else:
+                        # py2
+                        assert_warns(DeprecationWarning, f, arg1, arg2)
+
+
+class TestIdentityComparisonDeprecations(_DeprecationTestCase):
+    """This tests the equal and not_equal object ufuncs identity check
+    deprecation. This was due to the usage of PyObject_RichCompareBool.
+
+    This tests that for example for `a = np.array([np.nan], dtype=object)`
+    `a == a` it is warned that False and not `np.nan is np.nan` is returned.
+
+    Should be kept in sync with TestComparisonDeprecations and new tests
+    added when the deprecation is over. Requires only removing of @identity@
+    (and blocks) from the ufunc loops.c.src of the OBJECT comparisons.
+    """
+
+    message = "numpy .* will not check object identity in the future."
+
+    def test_identity_equality_mismatch(self):
+        a = np.array([np.nan], dtype=object)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_warns(FutureWarning, np.equal, a, a)
+            assert_warns(FutureWarning, np.not_equal, a, a)
+
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', FutureWarning)
+            assert_raises(FutureWarning, np.equal, a, a)
+            assert_raises(FutureWarning, np.not_equal, a, a)
+            # And the other do not warn:
+            with np.errstate(invalid='ignore'):
+                np.less(a, a)
+                np.greater(a, a)
+                np.less_equal(a, a)
+                np.greater_equal(a, a)
+
+    def test_comparison_error(self):
+        class FunkyType(object):
+            def __eq__(self, other):
+                raise TypeError("I won't compare")
+
+            def __ne__(self, other):
+                raise TypeError("I won't compare")
+
+        a = np.array([FunkyType()])
+        self.assert_deprecated(np.equal, args=(a, a))
+        self.assert_deprecated(np.not_equal, args=(a, a))
+
+    def test_bool_error(self):
+        # The comparison result cannot be interpreted as a bool
+        a = np.array([np.array([1, 2, 3]), None], dtype=object)
+        self.assert_deprecated(np.equal, args=(a, a))
+        self.assert_deprecated(np.not_equal, args=(a, a))
+
+
+class TestAlterdotRestoredotDeprecations(_DeprecationTestCase):
+    """The alterdot/restoredot functions are deprecated.
+
+    These functions no longer do anything in numpy 1.10, so
+    they should not be used.
+
+    """
+
+    def test_alterdot_restoredot_deprecation(self):
+        self.assert_deprecated(np.alterdot)
+        self.assert_deprecated(np.restoredot)
+
+
+class TestBooleanIndexShapeMismatchDeprecation():
+    """Tests deprecation for boolean indexing where the boolean array
+    does not match the input array along the given dimensions.
+    """
+    message = r"boolean index did not match indexed array"
+
+    def test_simple(self):
+        arr = np.ones((5, 4, 3))
+        index = np.array([True])
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+                     arr.__getitem__, index)
+
+        index = np.array([False] * 6)
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, index)
+
+        index = np.zeros((4, 4), dtype=bool)
+        #self.assert_deprecated(arr.__getitem__, args=(index,))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, index)
+        #self.assert_deprecated(arr.__getitem__, args=((slice(None), index),))
+        assert_warns(np.VisibleDeprecationWarning,
+             arr.__getitem__, (slice(None), index))
+
+
+class TestFullDefaultDtype(object):
+    """np.full defaults to float when dtype is not set.  In the future, it will
+    use the fill value's dtype.
+    """
+
+    def test_full_default_dtype(self):
+        assert_warns(FutureWarning, np.full, 1, 1)
+        assert_warns(FutureWarning, np.full, 1, None)
+        assert_no_warnings(np.full, 1, 1, float)
+
+
+class TestDatetime64Timezone(_DeprecationTestCase):
+    """Parsing of datetime64 with timezones deprecated in 1.11.0, because
+    datetime64 is now timezone naive rather than UTC only.
+
+    It will be quite a while before we can remove this, because, at the very
+    least, a lot of existing code uses the 'Z' modifier to avoid conversion
+    from local time to UTC, even if otherwise it handles time in a timezone
+    naive fashion.
+    """
+    def test_string(self):
+        self.assert_deprecated(np.datetime64, args=('2000-01-01T00+01',))
+        self.assert_deprecated(np.datetime64, args=('2000-01-01T00Z',))
+
+    @dec.skipif(not _has_pytz, "The pytz module is not available.")
+    @dec.knownfailureif(sys.version_info[0:2] < (2, 7))
+    def test_datetime(self):
+        tz = pytz.timezone('US/Eastern')
+        dt = datetime.datetime(2000, 1, 1, 0, 0, tzinfo=tz)
+        self.assert_deprecated(np.datetime64, args=(dt,))
+
+
+class TestNonCContiguousViewDeprecation(_DeprecationTestCase):
+    """View of non-C-contiguous arrays deprecated in 1.11.0.
+
+    The deprecation will not be raised for arrays that are both C and F
+    contiguous, as C contiguous is dominant. There are more such arrays
+    with relaxed stride checking than without so the deprecation is not
+    as visible with relaxed stride checking in force.
+    """
+
+    def test_fortran_contiguous(self):
+        self.assert_deprecated(np.ones((2,2)).T.view, args=(np.complex,))
+        self.assert_deprecated(np.ones((2,2)).T.view, args=(np.int8,))
+
+
+class TestInvalidOrderParameterInputForFlattenArrayDeprecation(_DeprecationTestCase):
+    """Invalid arguments to the ORDER parameter in array.flatten() should not be
+    allowed and should raise an error.  However, in the interests of not breaking
+    code that may inadvertently pass invalid arguments to this parameter, a
+    DeprecationWarning will be issued instead for the time being to give developers
+    time to refactor relevant code.
+    """
+
+    def test_flatten_array_non_string_arg(self):
+        x = np.zeros((3, 5))
+        self.message = ("Non-string object detected for "
+                        "the array ordering. Please pass "
+                        "in 'C', 'F', 'A', or 'K' instead")
+        self.assert_deprecated(x.flatten, args=(np.pi,))
+
+    def test_flatten_array_invalid_string_arg(self):
+        # Tests that a DeprecationWarning is raised
+        # when a string of length greater than one
+        # starting with "C", "F", "A", or "K" (case-
+        # and unicode-insensitive) is passed in for
+        # the ORDER parameter. Otherwise, a TypeError
+        # will be raised!
+
+        x = np.zeros((3, 5))
+        self.message = ("Non length-one string passed "
+                        "in for the array ordering. Please "
+                        "pass in 'C', 'F', 'A', or 'K' instead")
+        self.assert_deprecated(x.flatten, args=("FACK",))
+
+
+class TestTestDeprecated(object):
+    def test_assert_deprecated(self):
+        test_case_instance = _DeprecationTestCase()
+        test_case_instance.setUp()
+        assert_raises(AssertionError,
+                      test_case_instance.assert_deprecated,
+                      lambda: None)
+
+        def foo():
+            warnings.warn("foo", category=DeprecationWarning)
+
+        test_case_instance.assert_deprecated(foo)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
new file mode 100644
index 0000000000..a6cb66b7d5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
@@ -0,0 +1,599 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.core.test_rational import rational
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    dec
+)
+
+def assert_dtype_equal(a, b):
+    assert_equal(a, b)
+    assert_equal(hash(a), hash(b),
+                 "two equivalent types do not hash to the same value !")
+
+def assert_dtype_not_equal(a, b):
+    assert_(a != b)
+    assert_(hash(a) != hash(b),
+            "two different types hash to the same value !")
+
+class TestBuiltin(TestCase):
+    def test_run(self):
+        """Only test hash runs at all."""
+        for t in [np.int, np.float, np.complex, np.int32, np.str, np.object,
+                np.unicode]:
+            dt = np.dtype(t)
+            hash(dt)
+
+    def test_dtype(self):
+        # Make sure equivalent byte order char hash the same (e.g. < and = on
+        # little endian)
+        for t in [np.int, np.float]:
+            dt = np.dtype(t)
+            dt2 = dt.newbyteorder("<")
+            dt3 = dt.newbyteorder(">")
+            if dt == dt2:
+                self.assertTrue(dt.byteorder != dt2.byteorder, "bogus test")
+                assert_dtype_equal(dt, dt2)
+            else:
+                self.assertTrue(dt.byteorder != dt3.byteorder, "bogus test")
+                assert_dtype_equal(dt, dt3)
+
+    def test_equivalent_dtype_hashing(self):
+        # Make sure equivalent dtypes with different type num hash equal
+        uintp = np.dtype(np.uintp)
+        if uintp.itemsize == 4:
+            left = uintp
+            right = np.dtype(np.uint32)
+        else:
+            left = uintp
+            right = np.dtype(np.ulonglong)
+        self.assertTrue(left == right)
+        self.assertTrue(hash(left) == hash(right))
+
+    def test_invalid_types(self):
+        # Make sure invalid type strings raise an error
+
+        assert_raises(TypeError, np.dtype, 'O3')
+        assert_raises(TypeError, np.dtype, 'O5')
+        assert_raises(TypeError, np.dtype, 'O7')
+        assert_raises(TypeError, np.dtype, 'b3')
+        assert_raises(TypeError, np.dtype, 'h4')
+        assert_raises(TypeError, np.dtype, 'I5')
+        assert_raises(TypeError, np.dtype, 'e3')
+        assert_raises(TypeError, np.dtype, 'f5')
+
+        if np.dtype('g').itemsize == 8 or np.dtype('g').itemsize == 16:
+            assert_raises(TypeError, np.dtype, 'g12')
+        elif np.dtype('g').itemsize == 12:
+            assert_raises(TypeError, np.dtype, 'g16')
+
+        if np.dtype('l').itemsize == 8:
+            assert_raises(TypeError, np.dtype, 'l4')
+            assert_raises(TypeError, np.dtype, 'L4')
+        else:
+            assert_raises(TypeError, np.dtype, 'l8')
+            assert_raises(TypeError, np.dtype, 'L8')
+
+        if np.dtype('q').itemsize == 8:
+            assert_raises(TypeError, np.dtype, 'q4')
+            assert_raises(TypeError, np.dtype, 'Q4')
+        else:
+            assert_raises(TypeError, np.dtype, 'q8')
+            assert_raises(TypeError, np.dtype, 'Q8')
+
+    def test_bad_param(self):
+        # Can't give a size that's too small
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i4', 'i1'],
+                         'offsets':[0, 4],
+                         'itemsize':4})
+        # If alignment is enabled, the alignment (4) must divide the itemsize
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i4', 'i1'],
+                         'offsets':[0, 4],
+                         'itemsize':9}, align=True)
+        # If alignment is enabled, the individual fields must be aligned
+        assert_raises(ValueError, np.dtype,
+                        {'names':['f0', 'f1'],
+                         'formats':['i1', 'f4'],
+                         'offsets':[0, 2]}, align=True)
+
+class TestRecord(TestCase):
+    def test_equivalent_record(self):
+        """Test whether equivalent record dtypes hash the same."""
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('yo', np.int)])
+        assert_dtype_equal(a, b)
+
+    def test_different_names(self):
+        # In theory, they may hash the same (collision) ?
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('ye', np.int)])
+        assert_dtype_not_equal(a, b)
+
+    def test_different_titles(self):
+        # In theory, they may hash the same (collision) ?
+        a = np.dtype({'names': ['r', 'b'],
+                      'formats': ['u1', 'u1'],
+                      'titles': ['Red pixel', 'Blue pixel']})
+        b = np.dtype({'names': ['r', 'b'],
+                      'formats': ['u1', 'u1'],
+                      'titles': ['RRed pixel', 'Blue pixel']})
+        assert_dtype_not_equal(a, b)
+
+    def test_mutate(self):
+        # Mutating a dtype should reset the cached hash value
+        a = np.dtype([('yo', np.int)])
+        b = np.dtype([('yo', np.int)])
+        c = np.dtype([('ye', np.int)])
+        assert_dtype_equal(a, b)
+        assert_dtype_not_equal(a, c)
+        a.names = ['ye']
+        assert_dtype_equal(a, c)
+        assert_dtype_not_equal(a, b)
+        state = b.__reduce__()[2]
+        a.__setstate__(state)
+        assert_dtype_equal(a, b)
+        assert_dtype_not_equal(a, c)
+
+    def test_not_lists(self):
+        """Test if an appropriate exception is raised when passing bad values to
+        the dtype constructor.
+        """
+        self.assertRaises(TypeError, np.dtype,
+            dict(names=set(['A', 'B']), formats=['f8', 'i4']))
+        self.assertRaises(TypeError, np.dtype,
+            dict(names=['A', 'B'], formats=set(['f8', 'i4'])))
+
+    def test_aligned_size(self):
+        # Check that structured dtypes get padded to an aligned size
+        dt = np.dtype('i4, i1', align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype([('f0', 'i4'), ('f1', 'i1')], align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype({'names':['f0', 'f1'],
+                       'formats':['i4', 'u1'],
+                       'offsets':[0, 4]}, align=True)
+        assert_equal(dt.itemsize, 8)
+        dt = np.dtype({'f0': ('i4', 0), 'f1':('u1', 4)}, align=True)
+        assert_equal(dt.itemsize, 8)
+        # Nesting should preserve that alignment
+        dt1 = np.dtype([('f0', 'i4'),
+                       ('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
+                       ('f2', 'i1')], align=True)
+        assert_equal(dt1.itemsize, 20)
+        dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
+                       'formats':['i4',
+                                  [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
+                                  'i1'],
+                       'offsets':[0, 4, 16]}, align=True)
+        assert_equal(dt2.itemsize, 20)
+        dt3 = np.dtype({'f0': ('i4', 0),
+                       'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
+                       'f2': ('i1', 16)}, align=True)
+        assert_equal(dt3.itemsize, 20)
+        assert_equal(dt1, dt2)
+        assert_equal(dt2, dt3)
+        # Nesting should preserve packing
+        dt1 = np.dtype([('f0', 'i4'),
+                       ('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
+                       ('f2', 'i1')], align=False)
+        assert_equal(dt1.itemsize, 11)
+        dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
+                       'formats':['i4',
+                                  [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
+                                  'i1'],
+                       'offsets':[0, 4, 10]}, align=False)
+        assert_equal(dt2.itemsize, 11)
+        dt3 = np.dtype({'f0': ('i4', 0),
+                       'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
+                       'f2': ('i1', 10)}, align=False)
+        assert_equal(dt3.itemsize, 11)
+        assert_equal(dt1, dt2)
+        assert_equal(dt2, dt3)
+
+    def test_union_struct(self):
+        # Should be able to create union dtypes
+        dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
+                        'offsets':[0, 0, 2]}, align=True)
+        assert_equal(dt.itemsize, 4)
+        a = np.array([3], dtype='<u4').view(dt)
+        a['f1'] = 10
+        a['f2'] = 36
+        assert_equal(a['f0'], 10 + 36*256*256)
+        # Should be able to specify fields out of order
+        dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
+                        'offsets':[4, 0, 2]}, align=True)
+        assert_equal(dt.itemsize, 8)
+        dt2 = np.dtype({'names':['f2', 'f0', 'f1'],
+                        'formats':['<u2', '<u4', '<u2'],
+                        'offsets':[2, 4, 0]}, align=True)
+        vals = [(0, 1, 2), (3, -1, 4)]
+        vals2 = [(2, 0, 1), (4, 3, -1)]
+        a = np.array(vals, dt)
+        b = np.array(vals2, dt2)
+        assert_equal(a.astype(dt2), b)
+        assert_equal(b.astype(dt), a)
+        assert_equal(a.view(dt2), b)
+        assert_equal(b.view(dt), a)
+        # Should not be able to overlap objects with other types
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['O', 'i1'],
+                 'offsets':[0, 2]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['i4', 'O'],
+                 'offsets':[0, 3]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':[[('a', 'O')], 'i1'],
+                 'offsets':[0, 2]})
+        assert_raises(TypeError, np.dtype,
+                {'names':['f0', 'f1'],
+                 'formats':['i4', [('a', 'O')]],
+                 'offsets':[0, 3]})
+        # Out of order should still be ok, however
+        dt = np.dtype({'names':['f0', 'f1'],
+                       'formats':['i1', 'O'],
+                       'offsets':[np.dtype('intp').itemsize, 0]})
+
+    def test_comma_datetime(self):
+        dt = np.dtype('M8[D],datetime64[Y],i8')
+        assert_equal(dt, np.dtype([('f0', 'M8[D]'),
+                                   ('f1', 'datetime64[Y]'),
+                                   ('f2', 'i8')]))
+
+    def test_from_dictproxy(self):
+        # Tests for PR #5920
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'f4']})
+        assert_dtype_equal(dt, np.dtype(dt.fields))
+        dt2 = np.dtype((np.void, dt.fields))
+        assert_equal(dt2.fields, dt.fields)
+
+    def test_bool_commastring(self):
+        d = np.dtype('?,?,?')  # raises?
+        assert_equal(len(d.names), 3)
+        for n in d.names:
+            assert_equal(d.fields[n][0], np.dtype('?'))
+
+
+class TestSubarray(TestCase):
+    def test_single_subarray(self):
+        a = np.dtype((np.int, (2)))
+        b = np.dtype((np.int, (2,)))
+        assert_dtype_equal(a, b)
+
+        assert_equal(type(a.subdtype[1]), tuple)
+        assert_equal(type(b.subdtype[1]), tuple)
+
+    def test_equivalent_record(self):
+        """Test whether equivalent subarray dtypes hash the same."""
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (2, 3)))
+        assert_dtype_equal(a, b)
+
+    def test_nonequivalent_record(self):
+        """Test whether different subarray dtypes hash differently."""
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (3, 2)))
+        assert_dtype_not_equal(a, b)
+
+        a = np.dtype((np.int, (2, 3)))
+        b = np.dtype((np.int, (2, 2)))
+        assert_dtype_not_equal(a, b)
+
+        a = np.dtype((np.int, (1, 2, 3)))
+        b = np.dtype((np.int, (1, 2)))
+        assert_dtype_not_equal(a, b)
+
+    def test_shape_equal(self):
+        """Test some data types that are equal"""
+        assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', tuple())))
+        assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', 1)))
+        assert_dtype_equal(np.dtype((np.int, 2)), np.dtype((np.int, (2,))))
+        assert_dtype_equal(np.dtype(('<f4', (3, 2))), np.dtype(('<f4', (3, 2))))
+        d = ([('a', 'f4', (1, 2)), ('b', 'f8', (3, 1))], (3, 2))
+        assert_dtype_equal(np.dtype(d), np.dtype(d))
+
+    def test_shape_simple(self):
+        """Test some simple cases that shouldn't be equal"""
+        assert_dtype_not_equal(np.dtype('f8'), np.dtype(('f8', (1,))))
+        assert_dtype_not_equal(np.dtype(('f8', (1,))), np.dtype(('f8', (1, 1))))
+        assert_dtype_not_equal(np.dtype(('f4', (3, 2))), np.dtype(('f4', (2, 3))))
+
+    def test_shape_monster(self):
+        """Test some more complicated cases that shouldn't be equal"""
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', 'f4', (1, 2)), ('b', 'f8', (1, 3))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'i8', (1, 3))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('e', 'f8', (1, 3)), ('d', 'f4', (2, 1))], (2, 2))))
+        assert_dtype_not_equal(
+            np.dtype(([('a', [('a', 'i4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
+            np.dtype(([('a', [('a', 'u4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))))
+
+    def test_shape_sequence(self):
+        # Any sequence of integers should work as shape, but the result
+        # should be a tuple (immutable) of base type integers.
+        a = np.array([1, 2, 3], dtype=np.int16)
+        l = [1, 2, 3]
+        # Array gets converted
+        dt = np.dtype([('a', 'f4', a)])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+        # List gets converted
+        dt = np.dtype([('a', 'f4', l)])
+        assert_(isinstance(dt['a'].shape, tuple))
+        #
+
+        class IntLike(object):
+            def __index__(self):
+                return 3
+
+            def __int__(self):
+                # (a PyNumber_Check fails without __int__)
+                return 3
+
+        dt = np.dtype([('a', 'f4', IntLike())])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+        dt = np.dtype([('a', 'f4', (IntLike(),))])
+        assert_(isinstance(dt['a'].shape, tuple))
+        assert_(isinstance(dt['a'].shape[0], int))
+
+    def test_shape_invalid(self):
+        # Check that the shape is valid.
+        max_int = np.iinfo(np.intc).max
+        max_intp = np.iinfo(np.intp).max
+        # Too large values (the datatype is part of this)
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_int // 4 + 1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_int + 1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', (max_int, 2))])
+        # Takes a different code path (fails earlier:
+        assert_raises(ValueError, np.dtype, [('a', 'f4', max_intp + 1)])
+        # Negative values
+        assert_raises(ValueError, np.dtype, [('a', 'f4', -1)])
+        assert_raises(ValueError, np.dtype, [('a', 'f4', (-1, -1))])
+
+    def test_alignment(self):
+        #Check that subarrays are aligned
+        t1 = np.dtype('1i4', align=True)
+        t2 = np.dtype('2i4', align=True)
+        assert_equal(t1.alignment, t2.alignment)
+
+
+class TestMonsterType(TestCase):
+    """Test deeply nested subtypes."""
+
+    def test1(self):
+        simple1 = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+            'titles': ['Red pixel', 'Blue pixel']})
+        a = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((np.int, (3, 2))))])
+        b = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((np.int, (3, 2))))])
+        assert_dtype_equal(a, b)
+
+        c = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((a, (3, 2))))])
+        d = np.dtype([('yo', np.int), ('ye', simple1),
+            ('yi', np.dtype((a, (3, 2))))])
+        assert_dtype_equal(c, d)
+
+class TestMetadata(TestCase):
+    def test_no_metadata(self):
+        d = np.dtype(int)
+        self.assertEqual(d.metadata, None)
+
+    def test_metadata_takes_dict(self):
+        d = np.dtype(int, metadata={'datum': 1})
+        self.assertEqual(d.metadata, {'datum': 1})
+
+    def test_metadata_rejects_nondict(self):
+        self.assertRaises(TypeError, np.dtype, int, metadata='datum')
+        self.assertRaises(TypeError, np.dtype, int, metadata=1)
+        self.assertRaises(TypeError, np.dtype, int, metadata=None)
+
+    def test_nested_metadata(self):
+        d = np.dtype([('a', np.dtype(int, metadata={'datum': 1}))])
+        self.assertEqual(d['a'].metadata, {'datum': 1})
+
+    def base_metadata_copied(self):
+        d = np.dtype((np.void, np.dtype('i4,i4', metadata={'datum': 1})))
+        assert_equal(d.metadata, {'datum': 1})
+
+class TestString(TestCase):
+    def test_complex_dtype_str(self):
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))], (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])])
+        assert_equal(str(dt),
+                     "[('top', [('tiles', ('>f4', (64, 64)), (1,)), "
+                     "('rtile', '>f4', (64, 36))], (3,)), "
+                     "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
+                     "('bright', '>f4', (8, 36))])]")
+
+        # If the sticky aligned flag is set to True, it makes the
+        # str() function use a dict representation with an 'aligned' flag
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))],
+                                (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])],
+                       align=True)
+        assert_equal(str(dt),
+                    "{'names':['top','bottom'], "
+                     "'formats':[([('tiles', ('>f4', (64, 64)), (1,)), "
+                                  "('rtile', '>f4', (64, 36))], (3,)),"
+                                 "[('bleft', ('>f4', (8, 64)), (1,)), "
+                                  "('bright', '>f4', (8, 36))]], "
+                     "'offsets':[0,76800], "
+                     "'itemsize':80000, "
+                     "'aligned':True}")
+        assert_equal(np.dtype(eval(str(dt))), dt)
+
+        dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
+                        'offsets': [0, 1, 2],
+                        'titles': ['Red pixel', 'Green pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "[(('Red pixel', 'r'), 'u1'), "
+                    "(('Green pixel', 'g'), 'u1'), "
+                    "(('Blue pixel', 'b'), 'u1')]")
+
+        dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
+                       'formats': ['<u4', 'u1', 'u1', 'u1'],
+                       'offsets': [0, 0, 1, 2],
+                       'titles': ['Color', 'Red pixel',
+                                  'Green pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "{'names':['rgba','r','g','b'],"
+                    " 'formats':['<u4','u1','u1','u1'],"
+                    " 'offsets':[0,0,1,2],"
+                    " 'titles':['Color','Red pixel',"
+                              "'Green pixel','Blue pixel'],"
+                    " 'itemsize':4}")
+
+        dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+                        'offsets': [0, 2],
+                        'titles': ['Red pixel', 'Blue pixel']})
+        assert_equal(str(dt),
+                    "{'names':['r','b'],"
+                    " 'formats':['u1','u1'],"
+                    " 'offsets':[0,2],"
+                    " 'titles':['Red pixel','Blue pixel'],"
+                    " 'itemsize':3}")
+
+        dt = np.dtype([('a', '<m8[D]'), ('b', '<M8[us]')])
+        assert_equal(str(dt),
+                    "[('a', '<m8[D]'), ('b', '<M8[us]')]")
+
+    def test_complex_dtype_repr(self):
+        dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
+                                ('rtile', '>f4', (64, 36))], (3,)),
+                       ('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
+                                   ('bright', '>f4', (8, 36))])])
+        assert_equal(repr(dt),
+                     "dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), "
+                     "('rtile', '>f4', (64, 36))], (3,)), "
+                     "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
+                     "('bright', '>f4', (8, 36))])])")
+
+        dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
+                        'offsets': [0, 1, 2],
+                        'titles': ['Red pixel', 'Green pixel', 'Blue pixel']},
+                        align=True)
+        assert_equal(repr(dt),
+                    "dtype([(('Red pixel', 'r'), 'u1'), "
+                    "(('Green pixel', 'g'), 'u1'), "
+                    "(('Blue pixel', 'b'), 'u1')], align=True)")
+
+        dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
+                       'formats': ['<u4', 'u1', 'u1', 'u1'],
+                       'offsets': [0, 0, 1, 2],
+                       'titles': ['Color', 'Red pixel',
+                                  'Green pixel', 'Blue pixel']}, align=True)
+        assert_equal(repr(dt),
+                    "dtype({'names':['rgba','r','g','b'],"
+                    " 'formats':['<u4','u1','u1','u1'],"
+                    " 'offsets':[0,0,1,2],"
+                    " 'titles':['Color','Red pixel',"
+                              "'Green pixel','Blue pixel'],"
+                    " 'itemsize':4}, align=True)")
+
+        dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
+                        'offsets': [0, 2],
+                        'titles': ['Red pixel', 'Blue pixel'],
+                        'itemsize': 4})
+        assert_equal(repr(dt),
+                    "dtype({'names':['r','b'], "
+                    "'formats':['u1','u1'], "
+                    "'offsets':[0,2], "
+                    "'titles':['Red pixel','Blue pixel'], "
+                    "'itemsize':4})")
+
+        dt = np.dtype([('a', '<M8[D]'), ('b', '<m8[us]')])
+        assert_equal(repr(dt),
+                    "dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_dtype_str_with_long_in_shape(self):
+        # Pull request #376, should not error
+        np.dtype('(1L,)i4')
+
+    def test_base_dtype_with_object_type(self):
+        # Issue gh-2798, should not error.
+        np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
+
+    def test_empty_string_to_object(self):
+        # Pull request #4722
+        np.array(["", ""]).astype(object)
+
+class TestDtypeAttributeDeletion(TestCase):
+
+    def test_dtype_non_writable_attributes_deletion(self):
+        dt = np.dtype(np.double)
+        attr = ["subdtype", "descr", "str", "name", "base", "shape",
+                "isbuiltin", "isnative", "isalignedstruct", "fields",
+                "metadata", "hasobject"]
+
+        for s in attr:
+            assert_raises(AttributeError, delattr, dt, s)
+
+    def test_dtype_writable_attributes_deletion(self):
+        dt = np.dtype(np.double)
+        attr = ["names"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, dt, s)
+
+
+class TestDtypeAttributes(TestCase):
+    def test_descr_has_trailing_void(self):
+        # see gh-6359
+        dtype = np.dtype({
+            'names': ['A', 'B'],
+            'formats': ['f4', 'f4'],
+            'offsets': [0, 8],
+            'itemsize': 16})
+        new_dtype = np.dtype(dtype.descr)
+        assert_equal(new_dtype.itemsize, 16)
+
+
+class TestDtypeAttributes(TestCase):
+
+    def test_name_builtin(self):
+        for t in np.typeDict.values():
+            name = t.__name__
+            if name.endswith('_'):
+                name = name[:-1]
+            assert_equal(np.dtype(t).name, name)
+
+    def test_name_dtype_subclass(self):
+        # Ticket #4357
+        class user_def_subcls(np.void):
+            pass
+        assert_equal(np.dtype(user_def_subcls).name, 'user_def_subcls')
+
+
+def test_rational_dtype():
+    # test for bug gh-5719
+    a = np.array([1111], dtype=rational).astype
+    assert_raises(OverflowError, a, 'int8')
+
+    # test that dtype detection finds user-defined types
+    x = rational(1)
+    assert_equal(np.array([x,x]).dtype, np.dtype(rational))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
new file mode 100644
index 0000000000..1f863a7db9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
@@ -0,0 +1,627 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_raises
+    )
+
+class TestEinSum(TestCase):
+    def test_einsum_errors(self):
+        # Need enough arguments
+        assert_raises(ValueError, np.einsum)
+        assert_raises(ValueError, np.einsum, "")
+
+        # subscripts must be a string
+        assert_raises(TypeError, np.einsum, 0, 0)
+
+        # out parameter must be an array
+        assert_raises(TypeError, np.einsum, "", 0, out='test')
+
+        # order parameter must be a valid order
+        assert_raises(TypeError, np.einsum, "", 0, order='W')
+
+        # casting parameter must be a valid casting
+        assert_raises(ValueError, np.einsum, "", 0, casting='blah')
+
+        # dtype parameter must be a valid dtype
+        assert_raises(TypeError, np.einsum, "", 0, dtype='bad_data_type')
+
+        # other keyword arguments are rejected
+        assert_raises(TypeError, np.einsum, "", 0, bad_arg=0)
+
+        # issue 4528 revealed a segfault with this call
+        assert_raises(TypeError, np.einsum, *(None,)*63)
+
+        # number of operands must match count in subscripts string
+        assert_raises(ValueError, np.einsum, "", 0, 0)
+        assert_raises(ValueError, np.einsum, ",", 0, [0], [0])
+        assert_raises(ValueError, np.einsum, ",", [0])
+
+        # can't have more subscripts than dimensions in the operand
+        assert_raises(ValueError, np.einsum, "i", 0)
+        assert_raises(ValueError, np.einsum, "ij", [0, 0])
+        assert_raises(ValueError, np.einsum, "...i", 0)
+        assert_raises(ValueError, np.einsum, "i...j", [0, 0])
+        assert_raises(ValueError, np.einsum, "i...", 0)
+        assert_raises(ValueError, np.einsum, "ij...", [0, 0])
+
+        # invalid ellipsis
+        assert_raises(ValueError, np.einsum, "i..", [0, 0])
+        assert_raises(ValueError, np.einsum, ".i...", [0, 0])
+        assert_raises(ValueError, np.einsum, "j->..j", [0, 0])
+        assert_raises(ValueError, np.einsum, "j->.j...", [0, 0])
+
+        # invalid subscript character
+        assert_raises(ValueError, np.einsum, "i%...", [0, 0])
+        assert_raises(ValueError, np.einsum, "...j$", [0, 0])
+        assert_raises(ValueError, np.einsum, "i->&", [0, 0])
+
+        # output subscripts must appear in input
+        assert_raises(ValueError, np.einsum, "i->ij", [0, 0])
+
+        # output subscripts may only be specified once
+        assert_raises(ValueError, np.einsum, "ij->jij", [[0, 0], [0, 0]])
+
+        # dimensions much match when being collapsed
+        assert_raises(ValueError, np.einsum, "ii", np.arange(6).reshape(2, 3))
+        assert_raises(ValueError, np.einsum, "ii->i", np.arange(6).reshape(2, 3))
+
+        # broadcasting to new dimensions must be enabled explicitly
+        assert_raises(ValueError, np.einsum, "i", np.arange(6).reshape(2, 3))
+        assert_raises(ValueError, np.einsum, "i->i", [[0, 1], [0, 1]],
+                                            out=np.arange(4).reshape(2, 2))
+
+    def test_einsum_views(self):
+        # pass-through
+        a = np.arange(6)
+        a.shape = (2, 3)
+
+        b = np.einsum("...", a)
+        assert_(b.base is a)
+
+        b = np.einsum(a, [Ellipsis])
+        assert_(b.base is a)
+
+        b = np.einsum("ij", a)
+        assert_(b.base is a)
+        assert_equal(b, a)
+
+        b = np.einsum(a, [0, 1])
+        assert_(b.base is a)
+        assert_equal(b, a)
+
+        # output is writeable whenever input is writeable
+        b = np.einsum("...", a)
+        assert_(b.flags['WRITEABLE'])
+        a.flags['WRITEABLE'] = False
+        b = np.einsum("...", a)
+        assert_(not b.flags['WRITEABLE'])
+
+        # transpose
+        a = np.arange(6)
+        a.shape = (2, 3)
+
+        b = np.einsum("ji", a)
+        assert_(b.base is a)
+        assert_equal(b, a.T)
+
+        b = np.einsum(a, [1, 0])
+        assert_(b.base is a)
+        assert_equal(b, a.T)
+
+        # diagonal
+        a = np.arange(9)
+        a.shape = (3, 3)
+
+        b = np.einsum("ii->i", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0], [0])
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i] for i in range(3)])
+
+        # diagonal with various ways of broadcasting an additional dimension
+        a = np.arange(27)
+        a.shape = (3, 3, 3)
+
+        b = np.einsum("...ii->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)] for x in a])
+
+        b = np.einsum(a, [Ellipsis, 0, 0], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)] for x in a])
+
+        b = np.einsum("ii...->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(2, 0, 1)])
+
+        b = np.einsum(a, [0, 0, Ellipsis], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(2, 0, 1)])
+
+        b = np.einsum("...ii->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [Ellipsis, 0, 0], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum("jii->ij", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [1, 0, 0], [0, 1])
+        assert_(b.base is a)
+        assert_equal(b, [a[:, i, i] for i in range(3)])
+
+        b = np.einsum("ii...->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0, Ellipsis], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)])
+
+        b = np.einsum("i...i->i...", a)
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, Ellipsis, 0], [0, Ellipsis])
+        assert_(b.base is a)
+        assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)])
+
+        b = np.einsum("i...i->...i", a)
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(1, 0, 2)])
+
+        b = np.einsum(a, [0, Ellipsis, 0], [Ellipsis, 0])
+        assert_(b.base is a)
+        assert_equal(b, [[x[i, i] for i in range(3)]
+                         for x in a.transpose(1, 0, 2)])
+
+        # triple diagonal
+        a = np.arange(27)
+        a.shape = (3, 3, 3)
+
+        b = np.einsum("iii->i", a)
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i, i] for i in range(3)])
+
+        b = np.einsum(a, [0, 0, 0], [0])
+        assert_(b.base is a)
+        assert_equal(b, [a[i, i, i] for i in range(3)])
+
+        # swap axes
+        a = np.arange(24)
+        a.shape = (2, 3, 4)
+
+        b = np.einsum("ijk->jik", a)
+        assert_(b.base is a)
+        assert_equal(b, a.swapaxes(0, 1))
+
+        b = np.einsum(a, [0, 1, 2], [1, 0, 2])
+        assert_(b.base is a)
+        assert_equal(b, a.swapaxes(0, 1))
+
+    def check_einsum_sums(self, dtype):
+        # Check various sums.  Does many sizes to exercise unrolled loops.
+
+        # sum(a, axis=-1)
+        for n in range(1, 17):
+            a = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("i->", a), np.sum(a, axis=-1).astype(dtype))
+            assert_equal(np.einsum(a, [0], []),
+                         np.sum(a, axis=-1).astype(dtype))
+
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("...i->...", a),
+                         np.sum(a, axis=-1).astype(dtype))
+            assert_equal(np.einsum(a, [Ellipsis, 0], [Ellipsis]),
+                         np.sum(a, axis=-1).astype(dtype))
+
+        # sum(a, axis=0)
+        for n in range(1, 17):
+            a = np.arange(2*n, dtype=dtype).reshape(2, n)
+            assert_equal(np.einsum("i...->...", a),
+                         np.sum(a, axis=0).astype(dtype))
+            assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis]),
+                         np.sum(a, axis=0).astype(dtype))
+
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("i...->...", a),
+                         np.sum(a, axis=0).astype(dtype))
+            assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis]),
+                         np.sum(a, axis=0).astype(dtype))
+
+        # trace(a)
+        for n in range(1, 17):
+            a = np.arange(n*n, dtype=dtype).reshape(n, n)
+            assert_equal(np.einsum("ii", a), np.trace(a).astype(dtype))
+            assert_equal(np.einsum(a, [0, 0]), np.trace(a).astype(dtype))
+
+        # multiply(a, b)
+        assert_equal(np.einsum("..., ...", 3, 4), 12)  # scalar case
+        for n in range(1, 17):
+            a = np.arange(3*n, dtype=dtype).reshape(3, n)
+            b = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            assert_equal(np.einsum("..., ...", a, b), np.multiply(a, b))
+            assert_equal(np.einsum(a, [Ellipsis], b, [Ellipsis]),
+                         np.multiply(a, b))
+
+        # inner(a,b)
+        for n in range(1, 17):
+            a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n)
+            b = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("...i, ...i", a, b), np.inner(a, b))
+            assert_equal(np.einsum(a, [Ellipsis, 0], b, [Ellipsis, 0]),
+                         np.inner(a, b))
+
+        for n in range(1, 11):
+            a = np.arange(n*3*2, dtype=dtype).reshape(n, 3, 2)
+            b = np.arange(n, dtype=dtype)
+            assert_equal(np.einsum("i..., i...", a, b), np.inner(a.T, b.T).T)
+            assert_equal(np.einsum(a, [0, Ellipsis], b, [0, Ellipsis]),
+                         np.inner(a.T, b.T).T)
+
+        # outer(a,b)
+        for n in range(1, 17):
+            a = np.arange(3, dtype=dtype)+1
+            b = np.arange(n, dtype=dtype)+1
+            assert_equal(np.einsum("i,j", a, b), np.outer(a, b))
+            assert_equal(np.einsum(a, [0], b, [1]), np.outer(a, b))
+
+        # Suppress the complex warnings for the 'as f8' tests
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', np.ComplexWarning)
+
+            # matvec(a,b) / a.dot(b) where a is matrix, b is vector
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n, dtype=dtype)
+                assert_equal(np.einsum("ij, j", a, b), np.dot(a, b))
+                assert_equal(np.einsum(a, [0, 1], b, [1]), np.dot(a, b))
+
+                c = np.arange(4, dtype=dtype)
+                np.einsum("ij,j", a, b, out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1], b, [1], out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n, dtype=dtype)
+                assert_equal(np.einsum("ji,j", a.T, b.T), np.dot(b.T, a.T))
+                assert_equal(np.einsum(a.T, [1, 0], b.T, [1]), np.dot(b.T, a.T))
+
+                c = np.arange(4, dtype=dtype)
+                np.einsum("ji,j", a.T, b.T, out=c, dtype='f8', casting='unsafe')
+                assert_equal(c,
+                        np.dot(b.T.astype('f8'),
+                               a.T.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a.T, [1, 0], b.T, [1], out=c,
+                            dtype='f8', casting='unsafe')
+                assert_equal(c,
+                        np.dot(b.T.astype('f8'),
+                               a.T.astype('f8')).astype(dtype))
+
+            # matmat(a,b) / a.dot(b) where a is matrix, b is matrix
+            for n in range(1, 17):
+                if n < 8 or dtype != 'f2':
+                    a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                    b = np.arange(n*6, dtype=dtype).reshape(n, 6)
+                    assert_equal(np.einsum("ij,jk", a, b), np.dot(a, b))
+                    assert_equal(np.einsum(a, [0, 1], b, [1, 2]), np.dot(a, b))
+
+            for n in range(1, 17):
+                a = np.arange(4*n, dtype=dtype).reshape(4, n)
+                b = np.arange(n*6, dtype=dtype).reshape(n, 6)
+                c = np.arange(24, dtype=dtype).reshape(4, 6)
+                np.einsum("ij,jk", a, b, out=c, dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1], b, [1, 2], out=c,
+                                dtype='f8', casting='unsafe')
+                assert_equal(c,
+                            np.dot(a.astype('f8'),
+                                   b.astype('f8')).astype(dtype))
+
+            # matrix triple product (note this is not currently an efficient
+            # way to multiply 3 matrices)
+            a = np.arange(12, dtype=dtype).reshape(3, 4)
+            b = np.arange(20, dtype=dtype).reshape(4, 5)
+            c = np.arange(30, dtype=dtype).reshape(5, 6)
+            if dtype != 'f2':
+                assert_equal(np.einsum("ij,jk,kl", a, b, c),
+                                    a.dot(b).dot(c))
+                assert_equal(np.einsum(a, [0, 1], b, [1, 2], c, [2, 3]),
+                                    a.dot(b).dot(c))
+
+            d = np.arange(18, dtype=dtype).reshape(3, 6)
+            np.einsum("ij,jk,kl", a, b, c, out=d,
+                      dtype='f8', casting='unsafe')
+            tgt = a.astype('f8').dot(b.astype('f8'))
+            tgt = tgt.dot(c.astype('f8')).astype(dtype)
+            assert_equal(d, tgt)
+
+            d[...] = 0
+            np.einsum(a, [0, 1], b, [1, 2], c, [2, 3], out=d,
+                      dtype='f8', casting='unsafe')
+            tgt = a.astype('f8').dot(b.astype('f8'))
+            tgt = tgt.dot(c.astype('f8')).astype(dtype)
+            assert_equal(d, tgt)
+
+            # tensordot(a, b)
+            if np.dtype(dtype) != np.dtype('f2'):
+                a = np.arange(60, dtype=dtype).reshape(3, 4, 5)
+                b = np.arange(24, dtype=dtype).reshape(4, 3, 2)
+                assert_equal(np.einsum("ijk, jil -> kl", a, b),
+                                np.tensordot(a, b, axes=([1, 0], [0, 1])))
+                assert_equal(np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3]),
+                                np.tensordot(a, b, axes=([1, 0], [0, 1])))
+
+                c = np.arange(10, dtype=dtype).reshape(5, 2)
+                np.einsum("ijk,jil->kl", a, b, out=c,
+                                        dtype='f8', casting='unsafe')
+                assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'),
+                                        axes=([1, 0], [0, 1])).astype(dtype))
+                c[...] = 0
+                np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3], out=c,
+                                        dtype='f8', casting='unsafe')
+                assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'),
+                                        axes=([1, 0], [0, 1])).astype(dtype))
+
+        # logical_and(logical_and(a!=0, b!=0), c!=0)
+        a = np.array([1,   3,   -2,   0,   12,  13,   0,   1], dtype=dtype)
+        b = np.array([0,   3.5, 0.,   -2,  0,   1,    3,   12], dtype=dtype)
+        c = np.array([True, True, False, True, True, False, True, True])
+        assert_equal(np.einsum("i,i,i->i", a, b, c,
+                                dtype='?', casting='unsafe'),
+                            np.logical_and(np.logical_and(a != 0, b != 0), c != 0))
+        assert_equal(np.einsum(a, [0], b, [0], c, [0], [0],
+                                dtype='?', casting='unsafe'),
+                            np.logical_and(np.logical_and(a != 0, b != 0), c != 0))
+
+        a = np.arange(9, dtype=dtype)
+        assert_equal(np.einsum(",i->", 3, a), 3*np.sum(a))
+        assert_equal(np.einsum(3, [], a, [0], []), 3*np.sum(a))
+        assert_equal(np.einsum("i,->", a, 3), 3*np.sum(a))
+        assert_equal(np.einsum(a, [0], 3, [], []), 3*np.sum(a))
+
+        # Various stride0, contiguous, and SSE aligned variants
+        for n in range(1, 25):
+            a = np.arange(n, dtype=dtype)
+            if np.dtype(dtype).itemsize > 1:
+                assert_equal(np.einsum("...,...", a, a), np.multiply(a, a))
+                assert_equal(np.einsum("i,i", a, a), np.dot(a, a))
+                assert_equal(np.einsum("i,->i", a, 2), 2*a)
+                assert_equal(np.einsum(",i->i", 2, a), 2*a)
+                assert_equal(np.einsum("i,->", a, 2), 2*np.sum(a))
+                assert_equal(np.einsum(",i->", 2, a), 2*np.sum(a))
+
+                assert_equal(np.einsum("...,...", a[1:], a[:-1]),
+                             np.multiply(a[1:], a[:-1]))
+                assert_equal(np.einsum("i,i", a[1:], a[:-1]),
+                             np.dot(a[1:], a[:-1]))
+                assert_equal(np.einsum("i,->i", a[1:], 2), 2*a[1:])
+                assert_equal(np.einsum(",i->i", 2, a[1:]), 2*a[1:])
+                assert_equal(np.einsum("i,->", a[1:], 2), 2*np.sum(a[1:]))
+                assert_equal(np.einsum(",i->", 2, a[1:]), 2*np.sum(a[1:]))
+
+        # An object array, summed as the data type
+        a = np.arange(9, dtype=object)
+
+        b = np.einsum("i->", a, dtype=dtype, casting='unsafe')
+        assert_equal(b, np.sum(a))
+        assert_equal(b.dtype, np.dtype(dtype))
+
+        b = np.einsum(a, [0], [], dtype=dtype, casting='unsafe')
+        assert_equal(b, np.sum(a))
+        assert_equal(b.dtype, np.dtype(dtype))
+
+        # A case which was failing (ticket #1885)
+        p = np.arange(2) + 1
+        q = np.arange(4).reshape(2, 2) + 3
+        r = np.arange(4).reshape(2, 2) + 7
+        assert_equal(np.einsum('z,mz,zm->', p, q, r), 253)
+
+    def test_einsum_sums_int8(self):
+        self.check_einsum_sums('i1')
+
+    def test_einsum_sums_uint8(self):
+        self.check_einsum_sums('u1')
+
+    def test_einsum_sums_int16(self):
+        self.check_einsum_sums('i2')
+
+    def test_einsum_sums_uint16(self):
+        self.check_einsum_sums('u2')
+
+    def test_einsum_sums_int32(self):
+        self.check_einsum_sums('i4')
+
+    def test_einsum_sums_uint32(self):
+        self.check_einsum_sums('u4')
+
+    def test_einsum_sums_int64(self):
+        self.check_einsum_sums('i8')
+
+    def test_einsum_sums_uint64(self):
+        self.check_einsum_sums('u8')
+
+    def test_einsum_sums_float16(self):
+        self.check_einsum_sums('f2')
+
+    def test_einsum_sums_float32(self):
+        self.check_einsum_sums('f4')
+
+    def test_einsum_sums_float64(self):
+        self.check_einsum_sums('f8')
+
+    def test_einsum_sums_longdouble(self):
+        self.check_einsum_sums(np.longdouble)
+
+    def test_einsum_sums_cfloat64(self):
+        self.check_einsum_sums('c8')
+
+    def test_einsum_sums_cfloat128(self):
+        self.check_einsum_sums('c16')
+
+    def test_einsum_sums_clongdouble(self):
+        self.check_einsum_sums(np.clongdouble)
+
+    def test_einsum_misc(self):
+        # This call used to crash because of a bug in
+        # PyArray_AssignZero
+        a = np.ones((1, 2))
+        b = np.ones((2, 2, 1))
+        assert_equal(np.einsum('ij...,j...->i...', a, b), [[[2], [2]]])
+
+        # The iterator had an issue with buffering this reduction
+        a = np.ones((5, 12, 4, 2, 3), np.int64)
+        b = np.ones((5, 12, 11), np.int64)
+        assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b),
+                        np.einsum('ijklm,ijn->', a, b))
+
+        # Issue #2027, was a problem in the contiguous 3-argument
+        # inner loop implementation
+        a = np.arange(1, 3)
+        b = np.arange(1, 5).reshape(2, 2)
+        c = np.arange(1, 9).reshape(4, 2)
+        assert_equal(np.einsum('x,yx,zx->xzy', a, b, c),
+                    [[[1,  3], [3,  9], [5, 15], [7, 21]],
+                    [[8, 16], [16, 32], [24, 48], [32, 64]]])
+
+    def test_einsum_broadcast(self):
+        # Issue #2455 change in handling ellipsis
+        # remove the 'middle broadcast' error
+        # only use the 'RIGHT' iteration in prepare_op_axes
+        # adds auto broadcast on left where it belongs
+        # broadcast on right has to be explicit
+
+        A = np.arange(2*3*4).reshape(2,3,4)
+        B = np.arange(3)
+        ref = np.einsum('ijk,j->ijk',A, B)
+        assert_equal(np.einsum('ij...,j...->ij...',A, B), ref)
+        assert_equal(np.einsum('ij...,...j->ij...',A, B), ref)
+        assert_equal(np.einsum('ij...,j->ij...',A, B), ref)  # used to raise error
+
+        A = np.arange(12).reshape((4,3))
+        B = np.arange(6).reshape((3,2))
+        ref = np.einsum('ik,kj->ij', A, B)
+        assert_equal(np.einsum('ik...,k...->i...', A, B), ref)
+        assert_equal(np.einsum('ik...,...kj->i...j', A, B), ref)
+        assert_equal(np.einsum('...k,kj', A, B), ref)  # used to raise error
+        assert_equal(np.einsum('ik,k...->i...', A, B), ref)  # used to raise error
+
+        dims = [2,3,4,5]
+        a = np.arange(np.prod(dims)).reshape(dims)
+        v = np.arange(dims[2])
+        ref = np.einsum('ijkl,k->ijl', a, v)
+        assert_equal(np.einsum('ijkl,k', a, v), ref)
+        assert_equal(np.einsum('...kl,k', a, v), ref)  # used to raise error
+        assert_equal(np.einsum('...kl,k...', a, v), ref)
+        # no real diff from 1st
+
+        J,K,M = 160,160,120
+        A = np.arange(J*K*M).reshape(1,1,1,J,K,M)
+        B = np.arange(J*K*M*3).reshape(J,K,M,3)
+        ref = np.einsum('...lmn,...lmno->...o', A, B)
+        assert_equal(np.einsum('...lmn,lmno->...o', A, B), ref)  # used to raise error
+
+    def test_einsum_fixedstridebug(self):
+        # Issue #4485 obscure einsum bug
+        # This case revealed a bug in nditer where it reported a stride
+        # as 'fixed' (0) when it was in fact not fixed during processing
+        # (0 or 4). The reason for the bug was that the check for a fixed
+        # stride was using the information from the 2D inner loop reuse
+        # to restrict the iteration dimensions it had to validate to be
+        # the same, but that 2D inner loop reuse logic is only triggered
+        # during the buffer copying step, and hence it was invalid to
+        # rely on those values. The fix is to check all the dimensions
+        # of the stride in question, which in the test case reveals that
+        # the stride is not fixed.
+        #
+        # NOTE: This test is triggered by the fact that the default buffersize,
+        #       used by einsum, is 8192, and 3*2731 = 8193, is larger than that
+        #       and results in a mismatch between the buffering and the
+        #       striding for operand A.
+        A = np.arange(2*3).reshape(2,3).astype(np.float32)
+        B = np.arange(2*3*2731).reshape(2,3,2731).astype(np.int16)
+        es = np.einsum('cl,cpx->lpx', A, B)
+        tp = np.tensordot(A, B, axes=(0, 0))
+        assert_equal(es, tp)
+        # The following is the original test case from the bug report,
+        # made repeatable by changing random arrays to aranges.
+        A = np.arange(3*3).reshape(3,3).astype(np.float64)
+        B = np.arange(3*3*64*64).reshape(3,3,64,64).astype(np.float32)
+        es = np.einsum('cl,cpxy->lpxy', A,B)
+        tp = np.tensordot(A,B, axes=(0,0))
+        assert_equal(es, tp)
+
+    def test_einsum_fixed_collapsingbug(self):
+        # Issue #5147.
+        # The bug only occured when output argument of einssum was used.
+        x = np.random.normal(0, 1, (5, 5, 5, 5))
+        y1 = np.zeros((5, 5))
+        np.einsum('aabb->ab', x, out=y1)
+        idx = np.arange(5)
+        y2 = x[idx[:, None], idx[:, None], idx, idx]
+        assert_equal(y1, y2)
+
+    def test_einsum_all_contig_non_contig_output(self):
+        # Issue gh-5907, tests that the all contiguous special case
+        # actually checks the contiguity of the output
+        x = np.ones((5, 5))
+        out = np.ones(10)[::2]
+        correct_base = np.ones(10)
+        correct_base[::2] = 5
+        # Always worked (inner iteration is done with 0-stride):
+        np.einsum('mi,mi,mi->m', x, x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+        # Example 1:
+        out = np.ones(10)[::2]
+        np.einsum('im,im,im->m', x, x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+        # Example 2, buffering causes x to be contiguous but
+        # special cases do not catch the operation before:
+        out = np.ones((2, 2, 2))[..., 0]
+        correct_base = np.ones((2, 2, 2))
+        correct_base[..., 0] = 2
+        x = np.ones((2, 2), np.float32)
+        np.einsum('ij,jk->ik', x, x, out=out)
+        assert_array_equal(out.base, correct_base)
+
+    def test_small_boolean_arrays(self):
+        # See gh-5946.
+        # Use array of True embedded in False.
+        a = np.zeros((16, 1, 1), dtype=np.bool_)[:2]
+        a[...] = True
+        out = np.zeros((16, 1, 1), dtype=np.bool_)[:2]
+        tgt = np.ones((2,1,1), dtype=np.bool_)
+        res = np.einsum('...ij,...jk->...ik', a, a, out=out)
+        assert_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
new file mode 100644
index 0000000000..7fc749a7ec
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
@@ -0,0 +1,52 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+import numpy as np
+from numpy.testing import TestCase, assert_, run_module_suite, dec
+
+
+class TestErrstate(TestCase):
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_invalid(self):
+        with np.errstate(all='raise', under='ignore'):
+            a = -np.arange(3)
+            # This should work
+            with np.errstate(invalid='ignore'):
+                np.sqrt(a)
+            # While this should fail!
+            try:
+                np.sqrt(a)
+            except FloatingPointError:
+                pass
+            else:
+                self.fail("Did not raise an invalid error")
+
+    def test_divide(self):
+        with np.errstate(all='raise', under='ignore'):
+            a = -np.arange(3)
+            # This should work
+            with np.errstate(divide='ignore'):
+                a // 0
+            # While this should fail!
+            try:
+                a // 0
+            except FloatingPointError:
+                pass
+            else:
+                self.fail("Did not raise divide by zero error")
+
+    def test_errcall(self):
+        def foo(*args):
+            print(args)
+
+        olderrcall = np.geterrcall()
+        with np.errstate(call=foo):
+            assert_(np.geterrcall() is foo, 'call is not foo')
+            with np.errstate(call=None):
+                assert_(np.geterrcall() is None, 'call is not None')
+        assert_(np.geterrcall() is olderrcall, 'call is not olderrcall')
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
new file mode 100644
index 0000000000..2afae2f6b2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
@@ -0,0 +1,225 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import contextlib
+import operator
+
+import numpy as np
+import numpy.core.multiarray_tests as mt
+from numpy.compat import long
+
+from numpy.testing import assert_raises, assert_equal
+
+
+INT64_MAX = np.iinfo(np.int64).max
+INT64_MIN = np.iinfo(np.int64).min
+INT64_MID = 2**32
+
+# int128 is not two's complement, the sign bit is separate
+INT128_MAX = 2**128 - 1
+INT128_MIN = -INT128_MAX
+INT128_MID = 2**64
+
+INT64_VALUES = (
+    [INT64_MIN + j for j in range(20)] +
+    [INT64_MAX - j for j in range(20)] +
+    [INT64_MID + j for j in range(-20, 20)] +
+    [2*INT64_MID + j for j in range(-20, 20)] +
+    [INT64_MID//2 + j for j in range(-20, 20)] +
+    list(range(-70, 70))
+)
+
+INT128_VALUES = (
+    [INT128_MIN + j for j in range(20)] +
+    [INT128_MAX - j for j in range(20)] +
+    [INT128_MID + j for j in range(-20, 20)] +
+    [2*INT128_MID + j for j in range(-20, 20)] +
+    [INT128_MID//2 + j for j in range(-20, 20)] +
+    list(range(-70, 70)) +
+    [False]  # negative zero
+)
+
+INT64_POS_VALUES = [x for x in INT64_VALUES if x > 0]
+
+
+@contextlib.contextmanager
+def exc_iter(*args):
+    """
+    Iterate over Cartesian product of *args, and if an exception is raised,
+    add information of the current iterate.
+    """
+
+    value = [None]
+
+    def iterate():
+        for v in itertools.product(*args):
+            value[0] = v
+            yield v
+
+    try:
+        yield iterate()
+    except:
+        import traceback
+        msg = "At: %r\n%s" % (repr(value[0]),
+                              traceback.format_exc())
+        raise AssertionError(msg)
+
+
+def test_safe_binop():
+    # Test checked arithmetic routines
+
+    ops = [
+        (operator.add, 1),
+        (operator.sub, 2),
+        (operator.mul, 3)
+    ]
+
+    with exc_iter(ops, INT64_VALUES, INT64_VALUES) as it:
+        for xop, a, b in it:
+            pyop, op = xop
+            c = pyop(a, b)
+
+            if not (INT64_MIN <= c <= INT64_MAX):
+                assert_raises(OverflowError, mt.extint_safe_binop, a, b, op)
+            else:
+                d = mt.extint_safe_binop(a, b, op)
+                if c != d:
+                    # assert_equal is slow
+                    assert_equal(d, c)
+
+
+def test_to_128():
+    with exc_iter(INT64_VALUES) as it:
+        for a, in it:
+            b = mt.extint_to_128(a)
+            if a != b:
+                assert_equal(b, a)
+
+
+def test_to_64():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if not (INT64_MIN <= a <= INT64_MAX):
+                assert_raises(OverflowError, mt.extint_to_64, a)
+            else:
+                b = mt.extint_to_64(a)
+                if a != b:
+                    assert_equal(b, a)
+
+
+def test_mul_64_64():
+    with exc_iter(INT64_VALUES, INT64_VALUES) as it:
+        for a, b in it:
+            c = a * b
+            d = mt.extint_mul_64_64(a, b)
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_add_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a + b
+            if not (INT128_MIN <= c <= INT128_MAX):
+                assert_raises(OverflowError, mt.extint_add_128, a, b)
+            else:
+                d = mt.extint_add_128(a, b)
+                if c != d:
+                    assert_equal(d, c)
+
+
+def test_sub_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a - b
+            if not (INT128_MIN <= c <= INT128_MAX):
+                assert_raises(OverflowError, mt.extint_sub_128, a, b)
+            else:
+                d = mt.extint_sub_128(a, b)
+                if c != d:
+                    assert_equal(d, c)
+
+
+def test_neg_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            b = -a
+            c = mt.extint_neg_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_shl_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if a < 0:
+                b = -(((-a) << 1) & (2**128-1))
+            else:
+                b = (a << 1) & (2**128-1)
+            c = mt.extint_shl_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_shr_128():
+    with exc_iter(INT128_VALUES) as it:
+        for a, in it:
+            if a < 0:
+                b = -((-a) >> 1)
+            else:
+                b = a >> 1
+            c = mt.extint_shr_128(a)
+            if b != c:
+                assert_equal(c, b)
+
+
+def test_gt_128():
+    with exc_iter(INT128_VALUES, INT128_VALUES) as it:
+        for a, b in it:
+            c = a > b
+            d = mt.extint_gt_128(a, b)
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_divmod_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            if a >= 0:
+                c, cr = divmod(a, b)
+            else:
+                c, cr = divmod(-a, b)
+                c = -c
+                cr = -cr
+
+            d, dr = mt.extint_divmod_128_64(a, b)
+
+            if c != d or d != dr or b*d + dr != a:
+                assert_equal(d, c)
+                assert_equal(dr, cr)
+                assert_equal(b*d + dr, a)
+
+
+def test_floordiv_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            c = a // b
+            d = mt.extint_floordiv_128_64(a, b)
+
+            if c != d:
+                assert_equal(d, c)
+
+
+def test_ceildiv_128_64():
+    with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it:
+        for a, b in it:
+            c = (a + b - 1) // b
+            d = mt.extint_ceildiv_128_64(a, b)
+
+            if c != d:
+                assert_equal(d, c)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
new file mode 100644
index 0000000000..6b5430611a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
@@ -0,0 +1,155 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import (logspace, linspace, dtype, array, finfo, typecodes, arange,
+                   isnan, ndarray)
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal
+)
+
+
+class TestLogspace(TestCase):
+
+    def test_basic(self):
+        y = logspace(0, 6)
+        assert_(len(y) == 50)
+        y = logspace(0, 6, num=100)
+        assert_(y[-1] == 10 ** 6)
+        y = logspace(0, 6, endpoint=0)
+        assert_(y[-1] < 10 ** 6)
+        y = logspace(0, 6, num=7)
+        assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6])
+
+    def test_dtype(self):
+        y = logspace(0, 6, dtype='float32')
+        assert_equal(y.dtype, dtype('float32'))
+        y = logspace(0, 6, dtype='float64')
+        assert_equal(y.dtype, dtype('float64'))
+        y = logspace(0, 6, dtype='int32')
+        assert_equal(y.dtype, dtype('int32'))
+
+
+class TestLinspace(TestCase):
+
+    def test_basic(self):
+        y = linspace(0, 10)
+        assert_(len(y) == 50)
+        y = linspace(2, 10, num=100)
+        assert_(y[-1] == 10)
+        y = linspace(2, 10, endpoint=0)
+        assert_(y[-1] < 10)
+        assert_raises(ValueError, linspace, 0, 10, num=-1)
+
+    def test_corner(self):
+        y = list(linspace(0, 1, 1))
+        assert_(y == [0.0], y)
+        y = list(linspace(0, 1, 2.5))
+        assert_(y == [0.0, 1.0])
+
+    def test_type(self):
+        t1 = linspace(0, 1, 0).dtype
+        t2 = linspace(0, 1, 1).dtype
+        t3 = linspace(0, 1, 2).dtype
+        assert_equal(t1, t2)
+        assert_equal(t2, t3)
+
+    def test_dtype(self):
+        y = linspace(0, 6, dtype='float32')
+        assert_equal(y.dtype, dtype('float32'))
+        y = linspace(0, 6, dtype='float64')
+        assert_equal(y.dtype, dtype('float64'))
+        y = linspace(0, 6, dtype='int32')
+        assert_equal(y.dtype, dtype('int32'))
+
+    def test_array_scalar(self):
+        lim1 = array([-120, 100], dtype="int8")
+        lim2 = array([120, -100], dtype="int8")
+        lim3 = array([1200, 1000], dtype="uint16")
+        t1 = linspace(lim1[0], lim1[1], 5)
+        t2 = linspace(lim2[0], lim2[1], 5)
+        t3 = linspace(lim3[0], lim3[1], 5)
+        t4 = linspace(-120.0, 100.0, 5)
+        t5 = linspace(120.0, -100.0, 5)
+        t6 = linspace(1200.0, 1000.0, 5)
+        assert_equal(t1, t4)
+        assert_equal(t2, t5)
+        assert_equal(t3, t6)
+
+    def test_complex(self):
+        lim1 = linspace(1 + 2j, 3 + 4j, 5)
+        t1 = array([ 1.0+2.j,  1.5+2.5j,  2.0+3.j,  2.5+3.5j,  3.0+4.j])
+        lim2 = linspace(1j, 10, 5)
+        t2 = array([  0.0+1.j,   2.5+0.75j,   5.0+0.5j,   7.5+0.25j,  10.0+0.j])
+        assert_equal(lim1, t1)
+        assert_equal(lim2, t2)
+
+    def test_physical_quantities(self):
+        class PhysicalQuantity(float):
+            def __new__(cls, value):
+                return float.__new__(cls, value)
+
+            def __add__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(x) + float(self))
+            __radd__ = __add__
+
+            def __sub__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(self) - float(x))
+
+            def __rsub__(self, x):
+                assert_(isinstance(x, PhysicalQuantity))
+                return PhysicalQuantity(float(x) - float(self))
+
+            def __mul__(self, x):
+                return PhysicalQuantity(float(x) * float(self))
+            __rmul__ = __mul__
+
+            def __div__(self, x):
+                return PhysicalQuantity(float(self) / float(x))
+
+            def __rdiv__(self, x):
+                return PhysicalQuantity(float(x) / float(self))
+
+        a = PhysicalQuantity(0.0)
+        b = PhysicalQuantity(1.0)
+        assert_equal(linspace(a, b), linspace(0.0, 1.0))
+
+    def test_subclass(self):
+        class PhysicalQuantity2(ndarray):
+            __array_priority__ = 10
+
+        a = array(0).view(PhysicalQuantity2)
+        b = array(1).view(PhysicalQuantity2)
+        ls = linspace(a, b)
+        assert type(ls) is PhysicalQuantity2
+        assert_equal(ls, linspace(0.0, 1.0))
+        ls = linspace(a, b, 1)
+        assert type(ls) is PhysicalQuantity2
+        assert_equal(ls, linspace(0.0, 1.0, 1))
+
+    def test_denormal_numbers(self):
+        # Regression test for gh-5437. Will probably fail when compiled
+        # with ICC, which flushes denormals to zero
+        for dt in (dtype(f) for f in typecodes['Float']):
+            stop = finfo(dt).tiny * finfo(dt).resolution
+            assert_(any(linspace(0, stop, 10, endpoint=False, dtype=dt)))
+
+    def test_equivalent_to_arange(self):
+        for j in range(1000):
+            assert_equal(linspace(0, j, j+1, dtype=int),
+                         arange(j+1, dtype=int))
+
+    def test_retstep(self):
+        y = linspace(0, 1, 2, retstep=True)
+        assert_(isinstance(y, tuple) and len(y) == 2)
+        for num in (0, 1):
+            for ept in (False, True):
+                y = linspace(0, 1, num, endpoint=ept, retstep=True)
+                assert_(isinstance(y, tuple) and len(y) == 2 and
+                        len(y[0]) == num and isnan(y[1]),
+                        'num={0}, endpoint={1}'.format(num, ept))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
new file mode 100644
index 0000000000..c36d7c0684
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
@@ -0,0 +1,77 @@
+""" Test functions for limits module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.core import finfo, iinfo
+from numpy import half, single, double, longdouble
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal
+)
+
+##################################################
+
+class TestPythonFloat(TestCase):
+    def test_singleton(self):
+        ftype = finfo(float)
+        ftype2 = finfo(float)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestHalf(TestCase):
+    def test_singleton(self):
+        ftype = finfo(half)
+        ftype2 = finfo(half)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestSingle(TestCase):
+    def test_singleton(self):
+        ftype = finfo(single)
+        ftype2 = finfo(single)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestDouble(TestCase):
+    def test_singleton(self):
+        ftype = finfo(double)
+        ftype2 = finfo(double)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestLongdouble(TestCase):
+    def test_singleton(self,level=2):
+        ftype = finfo(longdouble)
+        ftype2 = finfo(longdouble)
+        assert_equal(id(ftype), id(ftype2))
+
+class TestIinfo(TestCase):
+    def test_basic(self):
+        dts = list(zip(['i1', 'i2', 'i4', 'i8',
+                   'u1', 'u2', 'u4', 'u8'],
+                  [np.int8, np.int16, np.int32, np.int64,
+                   np.uint8, np.uint16, np.uint32, np.uint64]))
+        for dt1, dt2 in dts:
+            assert_equal(iinfo(dt1).min, iinfo(dt2).min)
+            assert_equal(iinfo(dt1).max, iinfo(dt2).max)
+        self.assertRaises(ValueError, iinfo, 'f4')
+
+    def test_unsigned_max(self):
+        types = np.sctypes['uint']
+        for T in types:
+            assert_equal(iinfo(T).max, T(-1))
+
+class TestRepr(TestCase):
+    def test_iinfo_repr(self):
+        expected = "iinfo(min=-32768, max=32767, dtype=int16)"
+        assert_equal(repr(np.iinfo(np.int16)), expected)
+
+    def test_finfo_repr(self):
+        expected = "finfo(resolution=1e-06, min=-3.4028235e+38," + \
+                   " max=3.4028235e+38, dtype=float32)"
+        assert_equal(repr(np.finfo(np.float32)), expected)
+
+
+def test_instances():
+    iinfo(10)
+    finfo(3.0)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_half.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_half.py
new file mode 100644
index 0000000000..56b574ae81
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_half.py
@@ -0,0 +1,436 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+import numpy as np
+from numpy import uint16, float16, float32, float64
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal, \
+    dec
+
+
+def assert_raises_fpe(strmatch, callable, *args, **kwargs):
+    try:
+        callable(*args, **kwargs)
+    except FloatingPointError as exc:
+        assert_(str(exc).find(strmatch) >= 0,
+                "Did not raise floating point %s error" % strmatch)
+    else:
+        assert_(False,
+                "Did not raise floating point %s error" % strmatch)
+
+class TestHalf(TestCase):
+    def setUp(self):
+        # An array of all possible float16 values
+        self.all_f16 = np.arange(0x10000, dtype=uint16)
+        self.all_f16.dtype = float16
+        self.all_f32 = np.array(self.all_f16, dtype=float32)
+        self.all_f64 = np.array(self.all_f16, dtype=float64)
+
+        # An array of all non-NaN float16 values, in sorted order
+        self.nonan_f16 = np.concatenate(
+                                (np.arange(0xfc00, 0x7fff, -1, dtype=uint16),
+                                 np.arange(0x0000, 0x7c01, 1, dtype=uint16)))
+        self.nonan_f16.dtype = float16
+        self.nonan_f32 = np.array(self.nonan_f16, dtype=float32)
+        self.nonan_f64 = np.array(self.nonan_f16, dtype=float64)
+
+        # An array of all finite float16 values, in sorted order
+        self.finite_f16 = self.nonan_f16[1:-1]
+        self.finite_f32 = self.nonan_f32[1:-1]
+        self.finite_f64 = self.nonan_f64[1:-1]
+
+    def test_half_conversions(self):
+        """Checks that all 16-bit values survive conversion
+           to/from 32-bit and 64-bit float"""
+        # Because the underlying routines preserve the NaN bits, every
+        # value is preserved when converting to/from other floats.
+
+        # Convert from float32 back to float16
+        b = np.array(self.all_f32, dtype=float16)
+        assert_equal(self.all_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Convert from float64 back to float16
+        b = np.array(self.all_f64, dtype=float16)
+        assert_equal(self.all_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Convert float16 to longdouble and back
+        # This doesn't necessarily preserve the extra NaN bits,
+        # so exclude NaNs.
+        a_ld = np.array(self.nonan_f16, dtype=np.longdouble)
+        b = np.array(a_ld, dtype=float16)
+        assert_equal(self.nonan_f16.view(dtype=uint16),
+                     b.view(dtype=uint16))
+
+        # Check the range for which all integers can be represented
+        i_int = np.arange(-2048, 2049)
+        i_f16 = np.array(i_int, dtype=float16)
+        j = np.array(i_f16, dtype=np.int)
+        assert_equal(i_int, j)
+
+    def test_nans_infs(self):
+        with np.errstate(all='ignore'):
+            # Check some of the ufuncs
+            assert_equal(np.isnan(self.all_f16), np.isnan(self.all_f32))
+            assert_equal(np.isinf(self.all_f16), np.isinf(self.all_f32))
+            assert_equal(np.isfinite(self.all_f16), np.isfinite(self.all_f32))
+            assert_equal(np.signbit(self.all_f16), np.signbit(self.all_f32))
+            assert_equal(np.spacing(float16(65504)), np.inf)
+
+            # Check comparisons of all values with NaN
+            nan = float16(np.nan)
+
+            assert_(not (self.all_f16 == nan).any())
+            assert_(not (nan == self.all_f16).any())
+
+            assert_((self.all_f16 != nan).all())
+            assert_((nan != self.all_f16).all())
+
+            assert_(not (self.all_f16 < nan).any())
+            assert_(not (nan < self.all_f16).any())
+
+            assert_(not (self.all_f16 <= nan).any())
+            assert_(not (nan <= self.all_f16).any())
+
+            assert_(not (self.all_f16 > nan).any())
+            assert_(not (nan > self.all_f16).any())
+
+            assert_(not (self.all_f16 >= nan).any())
+            assert_(not (nan >= self.all_f16).any())
+
+    def test_half_values(self):
+        """Confirms a small number of known half values"""
+        a = np.array([1.0, -1.0,
+                      2.0, -2.0,
+                      0.0999755859375, 0.333251953125,  # 1/10, 1/3
+                      65504, -65504,           # Maximum magnitude
+                      2.0**(-14), -2.0**(-14),  # Minimum normal
+                      2.0**(-24), -2.0**(-24),  # Minimum subnormal
+                      0, -1/1e1000,            # Signed zeros
+                      np.inf, -np.inf])
+        b = np.array([0x3c00, 0xbc00,
+                      0x4000, 0xc000,
+                      0x2e66, 0x3555,
+                      0x7bff, 0xfbff,
+                      0x0400, 0x8400,
+                      0x0001, 0x8001,
+                      0x0000, 0x8000,
+                      0x7c00, 0xfc00], dtype=uint16)
+        b.dtype = float16
+        assert_equal(a, b)
+
+    def test_half_rounding(self):
+        """Checks that rounding when converting to half is correct"""
+        a = np.array([2.0**-25 + 2.0**-35,  # Rounds to minimum subnormal
+                      2.0**-25,       # Underflows to zero (nearest even mode)
+                      2.0**-26,       # Underflows to zero
+                      1.0+2.0**-11 + 2.0**-16,  # rounds to 1.0+2**(-10)
+                      1.0+2.0**-11,   # rounds to 1.0 (nearest even mode)
+                      1.0+2.0**-12,   # rounds to 1.0
+                      65519,          # rounds to 65504
+                      65520],         # rounds to inf
+                      dtype=float64)
+        rounded = [2.0**-24,
+                   0.0,
+                   0.0,
+                   1.0+2.0**(-10),
+                   1.0,
+                   1.0,
+                   65504,
+                   np.inf]
+
+        # Check float64->float16 rounding
+        b = np.array(a, dtype=float16)
+        assert_equal(b, rounded)
+
+        # Check float32->float16 rounding
+        a = np.array(a, dtype=float32)
+        b = np.array(a, dtype=float16)
+        assert_equal(b, rounded)
+
+    def test_half_correctness(self):
+        """Take every finite float16, and check the casting functions with
+           a manual conversion."""
+
+        # Create an array of all finite float16s
+        a_bits = self.finite_f16.view(dtype=uint16)
+
+        # Convert to 64-bit float manually
+        a_sgn = (-1.0)**((a_bits & 0x8000) >> 15)
+        a_exp = np.array((a_bits & 0x7c00) >> 10, dtype=np.int32) - 15
+        a_man = (a_bits & 0x03ff) * 2.0**(-10)
+        # Implicit bit of normalized floats
+        a_man[a_exp != -15] += 1
+        # Denormalized exponent is -14
+        a_exp[a_exp == -15] = -14
+
+        a_manual = a_sgn * a_man * 2.0**a_exp
+
+        a32_fail = np.nonzero(self.finite_f32 != a_manual)[0]
+        if len(a32_fail) != 0:
+            bad_index = a32_fail[0]
+            assert_equal(self.finite_f32, a_manual,
+                 "First non-equal is half value %x -> %g != %g" %
+                            (self.finite_f16[bad_index],
+                             self.finite_f32[bad_index],
+                             a_manual[bad_index]))
+
+        a64_fail = np.nonzero(self.finite_f64 != a_manual)[0]
+        if len(a64_fail) != 0:
+            bad_index = a64_fail[0]
+            assert_equal(self.finite_f64, a_manual,
+                 "First non-equal is half value %x -> %g != %g" %
+                            (self.finite_f16[bad_index],
+                             self.finite_f64[bad_index],
+                             a_manual[bad_index]))
+
+    def test_half_ordering(self):
+        """Make sure comparisons are working right"""
+
+        # All non-NaN float16 values in reverse order
+        a = self.nonan_f16[::-1].copy()
+
+        # 32-bit float copy
+        b = np.array(a, dtype=float32)
+
+        # Should sort the same
+        a.sort()
+        b.sort()
+        assert_equal(a, b)
+
+        # Comparisons should work
+        assert_((a[:-1] <= a[1:]).all())
+        assert_(not (a[:-1] > a[1:]).any())
+        assert_((a[1:] >= a[:-1]).all())
+        assert_(not (a[1:] < a[:-1]).any())
+        # All != except for +/-0
+        assert_equal(np.nonzero(a[:-1] < a[1:])[0].size, a.size-2)
+        assert_equal(np.nonzero(a[1:] > a[:-1])[0].size, a.size-2)
+
+    def test_half_funcs(self):
+        """Test the various ArrFuncs"""
+
+        # fill
+        assert_equal(np.arange(10, dtype=float16),
+                     np.arange(10, dtype=float32))
+
+        # fillwithscalar
+        a = np.zeros((5,), dtype=float16)
+        a.fill(1)
+        assert_equal(a, np.ones((5,), dtype=float16))
+
+        # nonzero and copyswap
+        a = np.array([0, 0, -1, -1/1e20, 0, 2.0**-24, 7.629e-6], dtype=float16)
+        assert_equal(a.nonzero()[0],
+                     [2, 5, 6])
+        a = a.byteswap().newbyteorder()
+        assert_equal(a.nonzero()[0],
+                     [2, 5, 6])
+
+        # dot
+        a = np.arange(0, 10, 0.5, dtype=float16)
+        b = np.ones((20,), dtype=float16)
+        assert_equal(np.dot(a, b),
+                     95)
+
+        # argmax
+        a = np.array([0, -np.inf, -2, 0.5, 12.55, 7.3, 2.1, 12.4], dtype=float16)
+        assert_equal(a.argmax(),
+                     4)
+        a = np.array([0, -np.inf, -2, np.inf, 12.55, np.nan, 2.1, 12.4], dtype=float16)
+        assert_equal(a.argmax(),
+                     5)
+
+        # getitem
+        a = np.arange(10, dtype=float16)
+        for i in range(10):
+            assert_equal(a.item(i), i)
+
+    def test_spacing_nextafter(self):
+        """Test np.spacing and np.nextafter"""
+        # All non-negative finite #'s
+        a = np.arange(0x7c00, dtype=uint16)
+        hinf = np.array((np.inf,), dtype=float16)
+        a_f16 = a.view(dtype=float16)
+
+        assert_equal(np.spacing(a_f16[:-1]), a_f16[1:]-a_f16[:-1])
+
+        assert_equal(np.nextafter(a_f16[:-1], hinf), a_f16[1:])
+        assert_equal(np.nextafter(a_f16[0], -hinf), -a_f16[1])
+        assert_equal(np.nextafter(a_f16[1:], -hinf), a_f16[:-1])
+
+        # switch to negatives
+        a |= 0x8000
+
+        assert_equal(np.spacing(a_f16[0]), np.spacing(a_f16[1]))
+        assert_equal(np.spacing(a_f16[1:]), a_f16[:-1]-a_f16[1:])
+
+        assert_equal(np.nextafter(a_f16[0], hinf), -a_f16[1])
+        assert_equal(np.nextafter(a_f16[1:], hinf), a_f16[:-1])
+        assert_equal(np.nextafter(a_f16[:-1], -hinf), a_f16[1:])
+
+    def test_half_ufuncs(self):
+        """Test the various ufuncs"""
+
+        a = np.array([0, 1, 2, 4, 2], dtype=float16)
+        b = np.array([-2, 5, 1, 4, 3], dtype=float16)
+        c = np.array([0, -1, -np.inf, np.nan, 6], dtype=float16)
+
+        assert_equal(np.add(a, b), [-2, 6, 3, 8, 5])
+        assert_equal(np.subtract(a, b), [2, -4, 1, 0, -1])
+        assert_equal(np.multiply(a, b), [0, 5, 2, 16, 6])
+        assert_equal(np.divide(a, b), [0, 0.199951171875, 2, 1, 0.66650390625])
+
+        assert_equal(np.equal(a, b), [False, False, False, True, False])
+        assert_equal(np.not_equal(a, b), [True, True, True, False, True])
+        assert_equal(np.less(a, b), [False, True, False, False, True])
+        assert_equal(np.less_equal(a, b), [False, True, False, True, True])
+        assert_equal(np.greater(a, b), [True, False, True, False, False])
+        assert_equal(np.greater_equal(a, b), [True, False, True, True, False])
+        assert_equal(np.logical_and(a, b), [False, True, True, True, True])
+        assert_equal(np.logical_or(a, b), [True, True, True, True, True])
+        assert_equal(np.logical_xor(a, b), [True, False, False, False, False])
+        assert_equal(np.logical_not(a), [True, False, False, False, False])
+
+        assert_equal(np.isnan(c), [False, False, False, True, False])
+        assert_equal(np.isinf(c), [False, False, True, False, False])
+        assert_equal(np.isfinite(c), [True, True, False, False, True])
+        assert_equal(np.signbit(b), [True, False, False, False, False])
+
+        assert_equal(np.copysign(b, a), [2, 5, 1, 4, 3])
+
+        assert_equal(np.maximum(a, b), [0, 5, 2, 4, 3])
+        x = np.maximum(b, c)
+        assert_(np.isnan(x[3]))
+        x[3] = 0
+        assert_equal(x, [0, 5, 1, 0, 6])
+        assert_equal(np.minimum(a, b), [-2, 1, 1, 4, 2])
+        x = np.minimum(b, c)
+        assert_(np.isnan(x[3]))
+        x[3] = 0
+        assert_equal(x, [-2, -1, -np.inf, 0, 3])
+        assert_equal(np.fmax(a, b), [0, 5, 2, 4, 3])
+        assert_equal(np.fmax(b, c), [0, 5, 1, 4, 6])
+        assert_equal(np.fmin(a, b), [-2, 1, 1, 4, 2])
+        assert_equal(np.fmin(b, c), [-2, -1, -np.inf, 4, 3])
+
+        assert_equal(np.floor_divide(a, b), [0, 0, 2, 1, 0])
+        assert_equal(np.remainder(a, b), [0, 1, 0, 0, 2])
+        assert_equal(np.square(b), [4, 25, 1, 16, 9])
+        assert_equal(np.reciprocal(b), [-0.5, 0.199951171875, 1, 0.25, 0.333251953125])
+        assert_equal(np.ones_like(b), [1, 1, 1, 1, 1])
+        assert_equal(np.conjugate(b), b)
+        assert_equal(np.absolute(b), [2, 5, 1, 4, 3])
+        assert_equal(np.negative(b), [2, -5, -1, -4, -3])
+        assert_equal(np.sign(b), [-1, 1, 1, 1, 1])
+        assert_equal(np.modf(b), ([0, 0, 0, 0, 0], b))
+        assert_equal(np.frexp(b), ([-0.5, 0.625, 0.5, 0.5, 0.75], [2, 3, 1, 3, 2]))
+        assert_equal(np.ldexp(b, [0, 1, 2, 4, 2]), [-2, 10, 4, 64, 12])
+
+    def test_half_coercion(self):
+        """Test that half gets coerced properly with the other types"""
+        a16 = np.array((1,), dtype=float16)
+        a32 = np.array((1,), dtype=float32)
+        b16 = float16(1)
+        b32 = float32(1)
+
+        assert_equal(np.power(a16, 2).dtype, float16)
+        assert_equal(np.power(a16, 2.0).dtype, float16)
+        assert_equal(np.power(a16, b16).dtype, float16)
+        assert_equal(np.power(a16, b32).dtype, float16)
+        assert_equal(np.power(a16, a16).dtype, float16)
+        assert_equal(np.power(a16, a32).dtype, float32)
+
+        assert_equal(np.power(b16, 2).dtype, float64)
+        assert_equal(np.power(b16, 2.0).dtype, float64)
+        assert_equal(np.power(b16, b16).dtype, float16)
+        assert_equal(np.power(b16, b32).dtype, float32)
+        assert_equal(np.power(b16, a16).dtype, float16)
+        assert_equal(np.power(b16, a32).dtype, float32)
+
+        assert_equal(np.power(a32, a16).dtype, float32)
+        assert_equal(np.power(a32, b16).dtype, float32)
+        assert_equal(np.power(b32, a16).dtype, float16)
+        assert_equal(np.power(b32, b16).dtype, float32)
+
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_half_fpe(self):
+        with np.errstate(all='raise'):
+            sx16 = np.array((1e-4,), dtype=float16)
+            bx16 = np.array((1e4,), dtype=float16)
+            sy16 = float16(1e-4)
+            by16 = float16(1e4)
+
+            # Underflow errors
+            assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sx16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sy16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sx16)
+            assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sy16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sx16, bx16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sx16, by16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sy16, bx16)
+            assert_raises_fpe('underflow', lambda a, b:a/b, sy16, by16)
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14), float16(2**11))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(-2.**-14), float16(2**11))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14+2**-24), float16(2))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(-2.**-14-2**-24), float16(2))
+            assert_raises_fpe('underflow', lambda a, b:a/b,
+                                             float16(2.**-14+2**-23), float16(4))
+
+            # Overflow errors
+            assert_raises_fpe('overflow', lambda a, b:a*b, bx16, bx16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, bx16, by16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, by16, bx16)
+            assert_raises_fpe('overflow', lambda a, b:a*b, by16, by16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sx16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sy16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, by16, sx16)
+            assert_raises_fpe('overflow', lambda a, b:a/b, by16, sy16)
+            assert_raises_fpe('overflow', lambda a, b:a+b,
+                                             float16(65504), float16(17))
+            assert_raises_fpe('overflow', lambda a, b:a-b,
+                                             float16(-65504), float16(17))
+            assert_raises_fpe('overflow', np.nextafter, float16(65504), float16(np.inf))
+            assert_raises_fpe('overflow', np.nextafter, float16(-65504), float16(-np.inf))
+            assert_raises_fpe('overflow', np.spacing, float16(65504))
+
+            # Invalid value errors
+            assert_raises_fpe('invalid', np.divide, float16(np.inf), float16(np.inf))
+            assert_raises_fpe('invalid', np.spacing, float16(np.inf))
+            assert_raises_fpe('invalid', np.spacing, float16(np.nan))
+            assert_raises_fpe('invalid', np.nextafter, float16(np.inf), float16(0))
+            assert_raises_fpe('invalid', np.nextafter, float16(-np.inf), float16(0))
+            assert_raises_fpe('invalid', np.nextafter, float16(0), float16(np.nan))
+
+            # These should not raise
+            float16(65472)+float16(32)
+            float16(2**-13)/float16(2)
+            float16(2**-14)/float16(2**10)
+            np.spacing(float16(-65504))
+            np.nextafter(float16(65504), float16(-np.inf))
+            np.nextafter(float16(-65504), float16(np.inf))
+            float16(2**-14)/float16(2**10)
+            float16(-2**-14)/float16(2**10)
+            float16(2**-14+2**-23)/float16(2)
+            float16(-2**-14-2**-23)/float16(2)
+
+    def test_half_array_interface(self):
+        """Test that half is compatible with __array_interface__"""
+        class Dummy:
+            pass
+
+        a = np.ones((1,), dtype=float16)
+        b = Dummy()
+        b.__array_interface__ = a.__array_interface__
+        c = np.array(b)
+        assert_(c.dtype == float16)
+        assert_equal(a, c)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
new file mode 100644
index 0000000000..e6b6be3610
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
@@ -0,0 +1,126 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_raises
+
+class TestIndexErrors(TestCase):
+    '''Tests to exercise indexerrors not covered by other tests.'''
+
+    def test_arraytypes_fasttake(self):
+        'take from a 0-length dimension'
+        x = np.empty((2, 3, 0, 4))
+        assert_raises(IndexError, x.take, [0], axis=2)
+        assert_raises(IndexError, x.take, [1], axis=2)
+        assert_raises(IndexError, x.take, [0], axis=2, mode='wrap')
+        assert_raises(IndexError, x.take, [0], axis=2, mode='clip')
+
+    def test_take_from_object(self):
+        # Check exception taking from object array
+        d = np.zeros(5, dtype=object)
+        assert_raises(IndexError, d.take, [6])
+
+        # Check exception taking from 0-d array
+        d = np.zeros((5, 0), dtype=object)
+        assert_raises(IndexError, d.take, [1], axis=1)
+        assert_raises(IndexError, d.take, [0], axis=1)
+        assert_raises(IndexError, d.take, [0])
+        assert_raises(IndexError, d.take, [0], mode='wrap')
+        assert_raises(IndexError, d.take, [0], mode='clip')
+
+    def test_multiindex_exceptions(self):
+        a = np.empty(5, dtype=object)
+        assert_raises(IndexError, a.item, 20)
+        a = np.empty((5, 0), dtype=object)
+        assert_raises(IndexError, a.item, (0, 0))
+
+        a = np.empty(5, dtype=object)
+        assert_raises(IndexError, a.itemset, 20, 0)
+        a = np.empty((5, 0), dtype=object)
+        assert_raises(IndexError, a.itemset, (0, 0), 0)
+
+    def test_put_exceptions(self):
+        a = np.zeros((5, 5))
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5), dtype=object)
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5, 0))
+        assert_raises(IndexError, a.put, 100, 0)
+        a = np.zeros((5, 5, 0), dtype=object)
+        assert_raises(IndexError, a.put, 100, 0)
+
+    def test_iterators_exceptions(self):
+        "cases in iterators.c"
+        def assign(obj, ind, val):
+            obj[ind] = val
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a[0, 5, None, 2])
+        assert_raises(IndexError, lambda: a[0, 5, 0, 2])
+        assert_raises(IndexError, lambda: assign(a, (0, 5, None, 2), 1))
+        assert_raises(IndexError, lambda: assign(a, (0, 5, 0, 2),  1))
+
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a[0, 0, None, 2])
+        assert_raises(IndexError, lambda: assign(a, (0, 0, None, 2), 1))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[10])
+        assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[10])
+        assert_raises(IndexError, lambda: assign(a.flat, 10, 5))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array(10)])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array(10)])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5))
+
+        a = np.zeros([1, 2, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array([10])])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
+        a = np.zeros([1, 0, 3])
+        assert_raises(IndexError, lambda: a.flat[np.array([10])])
+        assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5))
+
+    def test_mapping(self):
+        "cases from mapping.c"
+
+        def assign(obj, ind, val):
+            obj[ind] = val
+
+        a = np.zeros((0, 10))
+        assert_raises(IndexError, lambda: a[12])
+
+        a = np.zeros((3, 5))
+        assert_raises(IndexError, lambda: a[(10, 20)])
+        assert_raises(IndexError, lambda: assign(a, (10, 20), 1))
+        a = np.zeros((3, 0))
+        assert_raises(IndexError, lambda: a[(1, 0)])
+        assert_raises(IndexError, lambda: assign(a, (1, 0), 1))
+
+        a = np.zeros((10,))
+        assert_raises(IndexError, lambda: assign(a, 10, 1))
+        a = np.zeros((0,))
+        assert_raises(IndexError, lambda: assign(a, 10, 1))
+
+        a = np.zeros((3, 5))
+        assert_raises(IndexError, lambda: a[(1, [1, 20])])
+        assert_raises(IndexError, lambda: assign(a, (1, [1, 20]), 1))
+        a = np.zeros((3, 0))
+        assert_raises(IndexError, lambda: a[(1, [0, 1])])
+        assert_raises(IndexError, lambda: assign(a, (1, [0, 1]), 1))
+
+    def test_methods(self):
+        "cases from methods.c"
+
+        a = np.zeros((3, 3))
+        assert_raises(IndexError, lambda: a.item(100))
+        assert_raises(IndexError, lambda: a.itemset(100, 1))
+        a = np.zeros((0, 3))
+        assert_raises(IndexError, lambda: a.item(100))
+        assert_raises(IndexError, lambda: a.itemset(100, 1))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
new file mode 100644
index 0000000000..70029f8048
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
@@ -0,0 +1,1044 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+import functools
+
+import numpy as np
+from numpy.core.multiarray_tests import array_indexing
+from itertools import product
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_warns
+)
+
+
+try:
+    cdll = np.ctypeslib.load_library('multiarray', np.core.multiarray.__file__)
+    _HAS_CTYPE = True
+except ImportError:
+    _HAS_CTYPE = False
+
+
+class TestIndexing(TestCase):
+    def test_none_index(self):
+        # `None` index adds newaxis
+        a = np.array([1, 2, 3])
+        assert_equal(a[None], a[np.newaxis])
+        assert_equal(a[None].ndim, a.ndim + 1)
+
+    def test_empty_tuple_index(self):
+        # Empty tuple index creates a view
+        a = np.array([1, 2, 3])
+        assert_equal(a[()], a)
+        assert_(a[()].base is a)
+        a = np.array(0)
+        assert_(isinstance(a[()], np.int_))
+
+        # Regression, it needs to fall through integer and fancy indexing
+        # cases, so need the with statement to ignore the non-integer error.
+        with warnings.catch_warnings():
+            warnings.filterwarnings('ignore', '', DeprecationWarning)
+            a = np.array([1.])
+            assert_(isinstance(a[0.], np.float_))
+
+            a = np.array([np.array(1)], dtype=object)
+            assert_(isinstance(a[0.], np.ndarray))
+
+    def test_same_kind_index_casting(self):
+        # Indexes should be cast with same-kind and not safe, even if
+        # that is somewhat unsafe. So test various different code paths.
+        index = np.arange(5)
+        u_index = index.astype(np.uintp)
+        arr = np.arange(10)
+
+        assert_array_equal(arr[index], arr[u_index])
+        arr[u_index] = np.arange(5)
+        assert_array_equal(arr, np.arange(10))
+
+        arr = np.arange(10).reshape(5, 2)
+        assert_array_equal(arr[index], arr[u_index])
+
+        arr[u_index] = np.arange(5)[:,None]
+        assert_array_equal(arr, np.arange(5)[:,None].repeat(2, axis=1))
+
+        arr = np.arange(25).reshape(5, 5)
+        assert_array_equal(arr[u_index, u_index], arr[index, index])
+
+    def test_empty_fancy_index(self):
+        # Empty list index creates an empty array
+        # with the same dtype (but with weird shape)
+        a = np.array([1, 2, 3])
+        assert_equal(a[[]], [])
+        assert_equal(a[[]].dtype, a.dtype)
+
+        b = np.array([], dtype=np.intp)
+        assert_equal(a[[]], [])
+        assert_equal(a[[]].dtype, a.dtype)
+
+        b = np.array([])
+        assert_raises(IndexError, a.__getitem__, b)
+
+    def test_ellipsis_index(self):
+        # Ellipsis index does not create a view
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+        assert_equal(a[...], a)
+        assert_(a[...].base is a)  # `a[...]` was `a` in numpy <1.9.)
+
+        # Slicing with ellipsis can skip an
+        # arbitrary number of dimensions
+        assert_equal(a[0, ...], a[0])
+        assert_equal(a[0, ...], a[0,:])
+        assert_equal(a[..., 0], a[:, 0])
+
+        # Slicing with ellipsis always results
+        # in an array, not a scalar
+        assert_equal(a[0, ..., 1], np.array(2))
+
+        # Assignment with `(Ellipsis,)` on 0-d arrays
+        b = np.array(1)
+        b[(Ellipsis,)] = 2
+        assert_equal(b, 2)
+
+    def test_single_int_index(self):
+        # Single integer index selects one row
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+
+        assert_equal(a[0], [1, 2, 3])
+        assert_equal(a[-1], [7, 8, 9])
+
+        # Index out of bounds produces IndexError
+        assert_raises(IndexError, a.__getitem__, 1 << 30)
+        # Index overflow produces IndexError
+        assert_raises(IndexError, a.__getitem__, 1 << 64)
+
+    def test_single_bool_index(self):
+        # Single boolean index
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+
+        # Python boolean converts to integer
+        # These are being deprecated (and test in test_deprecations)
+        #assert_equal(a[True], a[1])
+        #assert_equal(a[False], a[0])
+
+        # Same with NumPy boolean scalar
+        # Before DEPRECATE, this is an error (as always, but telling about
+        # future change):
+        assert_raises(IndexError, a.__getitem__, np.array(True))
+        assert_raises(IndexError, a.__getitem__, np.array(False))
+        # After DEPRECATE, this behaviour can be enabled:
+        #assert_equal(a[np.array(True)], a[None])
+        #assert_equal(a[np.array(False), a[None][0:0]])
+
+    def test_boolean_indexing_onedim(self):
+        # Indexing a 2-dimensional array with
+        # boolean array of length one
+        a = np.array([[ 0.,  0.,  0.]])
+        b = np.array([ True], dtype=bool)
+        assert_equal(a[b], a)
+        # boolean assignment
+        a[b] = 1.
+        assert_equal(a, [[1., 1., 1.]])
+
+    def test_boolean_assignment_value_mismatch(self):
+        # A boolean assignment should fail when the shape of the values
+        # cannot be broadcast to the subscription. (see also gh-3458)
+        a = np.arange(4)
+
+        def f(a, v):
+            a[a > -1] = v
+
+        assert_raises(ValueError, f, a, [])
+        assert_raises(ValueError, f, a, [1, 2, 3])
+        assert_raises(ValueError, f, a[:1], [1, 2, 3])
+
+    def test_boolean_indexing_twodim(self):
+        # Indexing a 2-dimensional array with
+        # 2-dimensional boolean array
+        a = np.array([[1, 2, 3],
+                      [4, 5, 6],
+                      [7, 8, 9]])
+        b = np.array([[ True, False,  True],
+                      [False,  True, False],
+                      [ True, False,  True]])
+        assert_equal(a[b], [1, 3, 5, 7, 9])
+        assert_equal(a[b[1]], [[4, 5, 6]])
+        assert_equal(a[b[0]], a[b[2]])
+
+        # boolean assignment
+        a[b] = 0
+        assert_equal(a, [[0, 2, 0],
+                         [4, 0, 6],
+                         [0, 8, 0]])
+
+    def test_reverse_strides_and_subspace_bufferinit(self):
+        # This tests that the strides are not reversed for simple and
+        # subspace fancy indexing.
+        a = np.ones(5)
+        b = np.zeros(5, dtype=np.intp)[::-1]
+        c = np.arange(5)[::-1]
+
+        a[b] = c
+        # If the strides are not reversed, the 0 in the arange comes last.
+        assert_equal(a[0], 0)
+
+        # This also tests that the subspace buffer is initialized:
+        a = np.ones((5, 2))
+        c = np.arange(10).reshape(5, 2)[::-1]
+        a[b, :] = c
+        assert_equal(a[0], [0, 1])
+
+    def test_reversed_strides_result_allocation(self):
+        # Test a bug when calculating the output strides for a result array
+        # when the subspace size was 1 (and test other cases as well)
+        a = np.arange(10)[:, None]
+        i = np.arange(10)[::-1]
+        assert_array_equal(a[i], a[i.copy('C')])
+
+        a = np.arange(20).reshape(-1, 2)
+
+    def test_uncontiguous_subspace_assignment(self):
+        # During development there was a bug activating a skip logic
+        # based on ndim instead of size.
+        a = np.full((3, 4, 2), -1)
+        b = np.full((3, 4, 2), -1)
+
+        a[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T
+        b[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T.copy()
+
+        assert_equal(a, b)
+
+    def test_too_many_fancy_indices_special_case(self):
+        # Just documents behaviour, this is a small limitation.
+        a = np.ones((1,) * 32)  # 32 is NPY_MAXDIMS
+        assert_raises(IndexError, a.__getitem__, (np.array([0]),) * 32)
+
+    def test_scalar_array_bool(self):
+        # Numpy bools can be used as boolean index (python ones as of yet not)
+        a = np.array(1)
+        assert_equal(a[np.bool_(True)], a[np.array(True)])
+        assert_equal(a[np.bool_(False)], a[np.array(False)])
+
+        # After deprecating bools as integers:
+        #a = np.array([0,1,2])
+        #assert_equal(a[True, :], a[None, :])
+        #assert_equal(a[:, True], a[:, None])
+        #
+        #assert_(not np.may_share_memory(a, a[True, :]))
+
+    def test_everything_returns_views(self):
+        # Before `...` would return a itself.
+        a = np.arange(5)
+
+        assert_(a is not a[()])
+        assert_(a is not a[...])
+        assert_(a is not a[:])
+
+    def test_broaderrors_indexing(self):
+        a = np.zeros((5, 5))
+        assert_raises(IndexError, a.__getitem__, ([0, 1], [0, 1, 2]))
+        assert_raises(IndexError, a.__setitem__, ([0, 1], [0, 1, 2]), 0)
+
+    def test_trivial_fancy_out_of_bounds(self):
+        a = np.zeros(5)
+        ind = np.ones(20, dtype=np.intp)
+        ind[-1] = 10
+        assert_raises(IndexError, a.__getitem__, ind)
+        assert_raises(IndexError, a.__setitem__, ind, 0)
+        ind = np.ones(20, dtype=np.intp)
+        ind[0] = 11
+        assert_raises(IndexError, a.__getitem__, ind)
+        assert_raises(IndexError, a.__setitem__, ind, 0)
+
+    def test_nonbaseclass_values(self):
+        class SubClass(np.ndarray):
+            def __array_finalize__(self, old):
+                # Have array finalize do funny things
+                self.fill(99)
+
+        a = np.zeros((5, 5))
+        s = a.copy().view(type=SubClass)
+        s.fill(1)
+
+        a[[0, 1, 2, 3, 4], :] = s
+        assert_((a == 1).all())
+
+        # Subspace is last, so transposing might want to finalize
+        a[:, [0, 1, 2, 3, 4]] = s
+        assert_((a == 1).all())
+
+        a.fill(0)
+        a[...] = s
+        assert_((a == 1).all())
+
+    def test_subclass_writeable(self):
+        d = np.rec.array([('NGC1001', 11), ('NGC1002', 1.), ('NGC1003', 1.)],
+                         dtype=[('target', 'S20'), ('V_mag', '>f4')])
+        ind = np.array([False,  True,  True], dtype=bool)
+        assert_(d[ind].flags.writeable)
+        ind = np.array([0, 1])
+        assert_(d[ind].flags.writeable)
+        assert_(d[...].flags.writeable)
+        assert_(d[0].flags.writeable)
+
+    def test_memory_order(self):
+        # This is not necessary to preserve. Memory layouts for
+        # more complex indices are not as simple.
+        a = np.arange(10)
+        b = np.arange(10).reshape(5,2).T
+        assert_(a[b].flags.f_contiguous)
+
+        # Takes a different implementation branch:
+        a = a.reshape(-1, 1)
+        assert_(a[b, 0].flags.f_contiguous)
+
+    def test_scalar_return_type(self):
+        # Full scalar indices should return scalars and object
+        # arrays should not call PyArray_Return on their items
+        class Zero(object):
+            # The most basic valid indexing
+            def __index__(self):
+                return 0
+
+        z = Zero()
+
+        class ArrayLike(object):
+            # Simple array, should behave like the array
+            def __array__(self):
+                return np.array(0)
+
+        a = np.zeros(())
+        assert_(isinstance(a[()], np.float_))
+        a = np.zeros(1)
+        assert_(isinstance(a[z], np.float_))
+        a = np.zeros((1, 1))
+        assert_(isinstance(a[z, np.array(0)], np.float_))
+        assert_(isinstance(a[z, ArrayLike()], np.float_))
+
+        # And object arrays do not call it too often:
+        b = np.array(0)
+        a = np.array(0, dtype=object)
+        a[()] = b
+        assert_(isinstance(a[()], np.ndarray))
+        a = np.array([b, None])
+        assert_(isinstance(a[z], np.ndarray))
+        a = np.array([[b, None]])
+        assert_(isinstance(a[z, np.array(0)], np.ndarray))
+        assert_(isinstance(a[z, ArrayLike()], np.ndarray))
+
+    def test_small_regressions(self):
+        # Reference count of intp for index checks
+        a = np.array([0])
+        refcount = sys.getrefcount(np.dtype(np.intp))
+        # item setting always checks indices in separate function:
+        a[np.array([0], dtype=np.intp)] = 1
+        a[np.array([0], dtype=np.uint8)] = 1
+        assert_raises(IndexError, a.__setitem__,
+                      np.array([1], dtype=np.intp), 1)
+        assert_raises(IndexError, a.__setitem__,
+                      np.array([1], dtype=np.uint8), 1)
+
+        assert_equal(sys.getrefcount(np.dtype(np.intp)), refcount)
+
+    def test_unaligned(self):
+        v = (np.zeros(64, dtype=np.int8) + ord('a'))[1:-7]
+        d = v.view(np.dtype("S8"))
+        # unaligned source
+        x = (np.zeros(16, dtype=np.int8) + ord('a'))[1:-7]
+        x = x.view(np.dtype("S8"))
+        x[...] = np.array("b" * 8, dtype="S")
+        b = np.arange(d.size)
+        #trivial
+        assert_equal(d[b], d)
+        d[b] = x
+        # nontrivial
+        # unaligned index array
+        b = np.zeros(d.size + 1).view(np.int8)[1:-(np.intp(0).itemsize - 1)]
+        b = b.view(np.intp)[:d.size]
+        b[...] = np.arange(d.size)
+        assert_equal(d[b.astype(np.int16)], d)
+        d[b.astype(np.int16)] = x
+        # boolean
+        d[b % 2 == 0]
+        d[b % 2 == 0] = x[::2]
+
+    def test_tuple_subclass(self):
+        arr = np.ones((5, 5))
+
+        # A tuple subclass should also be an nd-index
+        class TupleSubclass(tuple):
+            pass
+        index = ([1], [1])
+        index = TupleSubclass(index)
+        assert_(arr[index].shape == (1,))
+        # Unlike the non nd-index:
+        assert_(arr[index,].shape != (1,))
+
+    def test_broken_sequence_not_nd_index(self):
+        # See gh-5063:
+        # If we have an object which claims to be a sequence, but fails
+        # on item getting, this should not be converted to an nd-index (tuple)
+        # If this object happens to be a valid index otherwise, it should work
+        # This object here is very dubious and probably bad though:
+        class SequenceLike(object):
+            def __index__(self):
+                return 0
+
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, item):
+                raise IndexError('Not possible')
+
+        arr = np.arange(10)
+        assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
+
+        # also test that field indexing does not segfault
+        # for a similar reason, by indexing a structured array
+        arr = np.zeros((1,), dtype=[('f1', 'i8'), ('f2', 'i8')])
+        assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),])
+
+    def test_indexing_array_weird_strides(self):
+        # See also gh-6221
+        # the shapes used here come from the issue and create the correct
+        # size for the iterator buffering size.
+        x = np.ones(10)
+        x2 = np.ones((10, 2))
+        ind = np.arange(10)[:, None, None, None]
+        ind = np.broadcast_to(ind, (10, 55, 4, 4))
+
+        # single advanced index case
+        assert_array_equal(x[ind], x[ind.copy()])
+        # higher dimensional advanced index
+        zind = np.zeros(4, dtype=np.intp)
+        assert_array_equal(x2[ind, zind], x2[ind.copy(), zind])
+
+
+class TestFieldIndexing(TestCase):
+    def test_scalar_return_type(self):
+        # Field access on an array should return an array, even if it
+        # is 0-d.
+        a = np.zeros((), [('a','f8')])
+        assert_(isinstance(a['a'], np.ndarray))
+        assert_(isinstance(a[['a']], np.ndarray))
+
+
+class TestBroadcastedAssignments(TestCase):
+    def assign(self, a, ind, val):
+        a[ind] = val
+        return a
+
+    def test_prepending_ones(self):
+        a = np.zeros((3, 2))
+
+        a[...] = np.ones((1, 3, 2))
+        # Fancy with subspace with and without transpose
+        a[[0, 1, 2], :] = np.ones((1, 3, 2))
+        a[:, [0, 1]] = np.ones((1, 3, 2))
+        # Fancy without subspace (with broadcasting)
+        a[[[0], [1], [2]], [0, 1]] = np.ones((1, 3, 2))
+
+    def test_prepend_not_one(self):
+        assign = self.assign
+        s_ = np.s_
+
+        a = np.zeros(5)
+
+        # Too large and not only ones.
+        assert_raises(ValueError, assign, a, s_[...],  np.ones((2, 1)))
+
+        with warnings.catch_warnings():
+            # Will be a ValueError as well.
+            warnings.simplefilter("error", DeprecationWarning)
+            assert_raises(DeprecationWarning, assign, a, s_[[1, 2, 3],],
+                          np.ones((2, 1)))
+            assert_raises(DeprecationWarning, assign, a, s_[[[1], [2]],],
+                          np.ones((2,2,1)))
+
+    def test_simple_broadcasting_errors(self):
+        assign = self.assign
+        s_ = np.s_
+
+        a = np.zeros((5, 1))
+        assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 2)))
+        assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 0)))
+
+        assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 2)))
+        assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 0)))
+
+        assert_raises(ValueError, assign, a, s_[[0], :], np.zeros((2, 1)))
+
+    def test_index_is_larger(self):
+        # Simple case of fancy index broadcasting of the index.
+        a = np.zeros((5, 5))
+        a[[[0], [1], [2]], [0, 1, 2]] = [2, 3, 4]
+
+        assert_((a[:3, :3] == [2, 3, 4]).all())
+
+    def test_broadcast_subspace(self):
+        a = np.zeros((100, 100))
+        v = np.arange(100)[:,None]
+        b = np.arange(100)[::-1]
+        a[b] = v
+        assert_((a[::-1] == v).all())
+
+
+class TestSubclasses(TestCase):
+    def test_basic(self):
+        class SubClass(np.ndarray):
+            pass
+
+        s = np.arange(5).view(SubClass)
+        assert_(isinstance(s[:3], SubClass))
+        assert_(s[:3].base is s)
+
+        assert_(isinstance(s[[0, 1, 2]], SubClass))
+        assert_(isinstance(s[s > 0], SubClass))
+
+    def test_matrix_fancy(self):
+        # The matrix class messes with the shape. While this is always
+        # weird (getitem is not used, it does not have setitem nor knows
+        # about fancy indexing), this tests gh-3110
+        m = np.matrix([[1, 2], [3, 4]])
+
+        assert_(isinstance(m[[0,1,0], :], np.matrix))
+
+        # gh-3110. Note the transpose currently because matrices do *not*
+        # support dimension fixing for fancy indexing correctly.
+        x = np.asmatrix(np.arange(50).reshape(5,10))
+        assert_equal(x[:2, np.array(-1)], x[:2, -1].T)
+
+    def test_finalize_gets_full_info(self):
+        # Array finalize should be called on the filled array.
+        class SubClass(np.ndarray):
+            def __array_finalize__(self, old):
+                self.finalize_status = np.array(self)
+                self.old = old
+
+        s = np.arange(10).view(SubClass)
+        new_s = s[:3]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+        new_s = s[[0,1,2,3]]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+        new_s = s[s > 0]
+        assert_array_equal(new_s.finalize_status, new_s)
+        assert_array_equal(new_s.old, s)
+
+class TestFancingIndexingCast(TestCase):
+    def test_boolean_index_cast_assign(self):
+        # Setup the boolean index and float arrays.
+        shape = (8, 63)
+        bool_index = np.zeros(shape).astype(bool)
+        bool_index[0, 1] = True
+        zero_array = np.zeros(shape)
+
+        # Assigning float is fine.
+        zero_array[bool_index] = np.array([1])
+        assert_equal(zero_array[0, 1], 1)
+
+        # Fancy indexing works, although we get a cast warning.
+        assert_warns(np.ComplexWarning,
+                     zero_array.__setitem__, ([0], [1]), np.array([2 + 1j]))
+        assert_equal(zero_array[0, 1], 2)  # No complex part
+
+        # Cast complex to float, throwing away the imaginary portion.
+        assert_warns(np.ComplexWarning,
+                     zero_array.__setitem__, bool_index, np.array([1j]))
+        assert_equal(zero_array[0, 1], 0)
+
+class TestFancyIndexingEquivalence(TestCase):
+    def test_object_assign(self):
+        # Check that the field and object special case using copyto is active.
+        # The right hand side cannot be converted to an array here.
+        a = np.arange(5, dtype=object)
+        b = a.copy()
+        a[:3] = [1, (1,2), 3]
+        b[[0, 1, 2]] = [1, (1,2), 3]
+        assert_array_equal(a, b)
+
+        # test same for subspace fancy indexing
+        b = np.arange(5, dtype=object)[None, :]
+        b[[0], :3] = [[1, (1,2), 3]]
+        assert_array_equal(a, b[0])
+
+        # Check that swapping of axes works.
+        # There was a bug that made the later assignment throw a ValueError
+        # do to an incorrectly transposed temporary right hand side (gh-5714)
+        b = b.T
+        b[:3, [0]] = [[1], [(1,2)], [3]]
+        assert_array_equal(a, b[:, 0])
+
+        # Another test for the memory order of the subspace
+        arr = np.ones((3, 4, 5), dtype=object)
+        # Equivalent slicing assignment for comparison
+        cmp_arr = arr.copy()
+        cmp_arr[:1, ...] = [[[1], [2], [3], [4]]]
+        arr[[0], ...] = [[[1], [2], [3], [4]]]
+        assert_array_equal(arr, cmp_arr)
+        arr = arr.copy('F')
+        arr[[0], ...] = [[[1], [2], [3], [4]]]
+        assert_array_equal(arr, cmp_arr)
+
+    def test_cast_equivalence(self):
+        # Yes, normal slicing uses unsafe casting.
+        a = np.arange(5)
+        b = a.copy()
+
+        a[:3] = np.array(['2', '-3', '-1'])
+        b[[0, 2, 1]] = np.array(['2', '-1', '-3'])
+        assert_array_equal(a, b)
+
+        # test the same for subspace fancy indexing
+        b = np.arange(5)[None, :]
+        b[[0], :3] = np.array([['2', '-3', '-1']])
+        assert_array_equal(a, b[0])
+
+
+class TestMultiIndexingAutomated(TestCase):
+    """
+     These test use code to mimic the C-Code indexing for selection.
+
+     NOTE: * This still lacks tests for complex item setting.
+           * If you change behavior of indexing, you might want to modify
+             these tests to try more combinations.
+           * Behavior was written to match numpy version 1.8. (though a
+             first version matched 1.7.)
+           * Only tuple indices are supported by the mimicking code.
+             (and tested as of writing this)
+           * Error types should match most of the time as long as there
+             is only one error. For multiple errors, what gets raised
+             will usually not be the same one. They are *not* tested.
+    """
+
+    def setUp(self):
+        self.a = np.arange(np.prod([3, 1, 5, 6])).reshape(3, 1, 5, 6)
+        self.b = np.empty((3, 0, 5, 6))
+        self.complex_indices = ['skip', Ellipsis,
+            0,
+            # Boolean indices, up to 3-d for some special cases of eating up
+            # dimensions, also need to test all False
+            np.array(False),
+            np.array([True, False, False]),
+            np.array([[True, False], [False, True]]),
+            np.array([[[False, False], [False, False]]]),
+            # Some slices:
+            slice(-5, 5, 2),
+            slice(1, 1, 100),
+            slice(4, -1, -2),
+            slice(None, None, -3),
+            # Some Fancy indexes:
+            np.empty((0, 1, 1), dtype=np.intp),  # empty and can be broadcast
+            np.array([0, 1, -2]),
+            np.array([[2], [0], [1]]),
+            np.array([[0, -1], [0, 1]], dtype=np.dtype('intp').newbyteorder()),
+            np.array([2, -1], dtype=np.int8),
+            np.zeros([1]*31, dtype=int),  # trigger too large array.
+            np.array([0., 1.])]  # invalid datatype
+        # Some simpler indices that still cover a bit more
+        self.simple_indices = [Ellipsis, None, -1, [1], np.array([True]), 'skip']
+        # Very simple ones to fill the rest:
+        self.fill_indices = [slice(None, None), 0]
+
+    def _get_multi_index(self, arr, indices):
+        """Mimic multi dimensional indexing.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed.
+        indices : tuple of index objects
+
+        Returns
+        -------
+        out : ndarray
+            An array equivalent to the indexing operation (but always a copy).
+            `arr[indices]` should be identical.
+        no_copy : bool
+            Whether the indexing operation requires a copy. If this is `True`,
+            `np.may_share_memory(arr, arr[indicies])` should be `True` (with
+            some exceptions for scalars and possibly 0-d arrays).
+
+        Notes
+        -----
+        While the function may mostly match the errors of normal indexing this
+        is generally not the case.
+        """
+        in_indices = list(indices)
+        indices = []
+        # if False, this is a fancy or boolean index
+        no_copy = True
+        # number of fancy/scalar indexes that are not consecutive
+        num_fancy = 0
+        # number of dimensions indexed by a "fancy" index
+        fancy_dim = 0
+        # NOTE: This is a funny twist (and probably OK to change).
+        # The boolean array has illegal indexes, but this is
+        # allowed if the broadcast fancy-indices are 0-sized.
+        # This variable is to catch that case.
+        error_unless_broadcast_to_empty = False
+
+        # We need to handle Ellipsis and make arrays from indices, also
+        # check if this is fancy indexing (set no_copy).
+        ndim = 0
+        ellipsis_pos = None  # define here mostly to replace all but first.
+        for i, indx in enumerate(in_indices):
+            if indx is None:
+                continue
+            if isinstance(indx, np.ndarray) and indx.dtype == bool:
+                no_copy = False
+                if indx.ndim == 0:
+                    raise IndexError
+                # boolean indices can have higher dimensions
+                ndim += indx.ndim
+                fancy_dim += indx.ndim
+                continue
+            if indx is Ellipsis:
+                if ellipsis_pos is None:
+                    ellipsis_pos = i
+                    continue  # do not increment ndim counter
+                raise IndexError
+            if isinstance(indx, slice):
+                ndim += 1
+                continue
+            if not isinstance(indx, np.ndarray):
+                # This could be open for changes in numpy.
+                # numpy should maybe raise an error if casting to intp
+                # is not safe. It rejects np.array([1., 2.]) but not
+                # [1., 2.] as index (same for ie. np.take).
+                # (Note the importance of empty lists if changing this here)
+                indx = np.array(indx, dtype=np.intp)
+                in_indices[i] = indx
+            elif indx.dtype.kind != 'b' and indx.dtype.kind != 'i':
+                raise IndexError('arrays used as indices must be of integer (or boolean) type')
+            if indx.ndim != 0:
+                no_copy = False
+            ndim += 1
+            fancy_dim += 1
+
+        if arr.ndim - ndim < 0:
+            # we can't take more dimensions then we have, not even for 0-d arrays.
+            # since a[()] makes sense, but not a[(),]. We will raise an error
+            # later on, unless a broadcasting error occurs first.
+            raise IndexError
+
+        if ndim == 0 and None not in in_indices:
+            # Well we have no indexes or one Ellipsis. This is legal.
+            return arr.copy(), no_copy
+
+        if ellipsis_pos is not None:
+            in_indices[ellipsis_pos:ellipsis_pos+1] = [slice(None, None)] * (arr.ndim - ndim)
+
+        for ax, indx in enumerate(in_indices):
+            if isinstance(indx, slice):
+                # convert to an index array
+                indx = np.arange(*indx.indices(arr.shape[ax]))
+                indices.append(['s', indx])
+                continue
+            elif indx is None:
+                # this is like taking a slice with one element from a new axis:
+                indices.append(['n', np.array([0], dtype=np.intp)])
+                arr = arr.reshape((arr.shape[:ax] + (1,) + arr.shape[ax:]))
+                continue
+            if isinstance(indx, np.ndarray) and indx.dtype == bool:
+                if indx.shape != arr.shape[ax:ax+indx.ndim]:
+                    raise IndexError
+
+                try:
+                    flat_indx = np.ravel_multi_index(np.nonzero(indx),
+                                    arr.shape[ax:ax+indx.ndim], mode='raise')
+                except:
+                    error_unless_broadcast_to_empty = True
+                    # fill with 0s instead, and raise error later
+                    flat_indx = np.array([0]*indx.sum(), dtype=np.intp)
+                # concatenate axis into a single one:
+                if indx.ndim != 0:
+                    arr = arr.reshape((arr.shape[:ax]
+                                  + (np.prod(arr.shape[ax:ax+indx.ndim]),)
+                                  + arr.shape[ax+indx.ndim:]))
+                    indx = flat_indx
+                else:
+                    # This could be changed, a 0-d boolean index can
+                    # make sense (even outside the 0-d indexed array case)
+                    # Note that originally this is could be interpreted as
+                    # integer in the full integer special case.
+                    raise IndexError
+            else:
+                # If the index is a singleton, the bounds check is done
+                # before the broadcasting. This used to be different in <1.9
+                if indx.ndim == 0:
+                    if indx >= arr.shape[ax] or indx < -arr.shape[ax]:
+                        raise IndexError
+            if indx.ndim == 0:
+                # The index is a scalar. This used to be two fold, but if fancy
+                # indexing was active, the check was done later, possibly
+                # after broadcasting it away (1.7. or earlier). Now it is always
+                # done.
+                if indx >= arr.shape[ax] or indx < - arr.shape[ax]:
+                    raise IndexError
+            if len(indices) > 0 and indices[-1][0] == 'f' and ax != ellipsis_pos:
+                # NOTE: There could still have been a 0-sized Ellipsis
+                # between them. Checked that with ellipsis_pos.
+                indices[-1].append(indx)
+            else:
+                # We have a fancy index that is not after an existing one.
+                # NOTE: A 0-d array triggers this as well, while
+                # one may expect it to not trigger it, since a scalar
+                # would not be considered fancy indexing.
+                num_fancy += 1
+                indices.append(['f', indx])
+
+        if num_fancy > 1 and not no_copy:
+            # We have to flush the fancy indexes left
+            new_indices = indices[:]
+            axes = list(range(arr.ndim))
+            fancy_axes = []
+            new_indices.insert(0, ['f'])
+            ni = 0
+            ai = 0
+            for indx in indices:
+                ni += 1
+                if indx[0] == 'f':
+                    new_indices[0].extend(indx[1:])
+                    del new_indices[ni]
+                    ni -= 1
+                    for ax in range(ai, ai + len(indx[1:])):
+                        fancy_axes.append(ax)
+                        axes.remove(ax)
+                ai += len(indx) - 1  # axis we are at
+            indices = new_indices
+            # and now we need to transpose arr:
+            arr = arr.transpose(*(fancy_axes + axes))
+
+        # We only have one 'f' index now and arr is transposed accordingly.
+        # Now handle newaxis by reshaping...
+        ax = 0
+        for indx in indices:
+            if indx[0] == 'f':
+                if len(indx) == 1:
+                    continue
+                # First of all, reshape arr to combine fancy axes into one:
+                orig_shape = arr.shape
+                orig_slice = orig_shape[ax:ax + len(indx[1:])]
+                arr = arr.reshape((arr.shape[:ax]
+                                    + (np.prod(orig_slice).astype(int),)
+                                    + arr.shape[ax + len(indx[1:]):]))
+
+                # Check if broadcasting works
+                res = np.broadcast(*indx[1:])
+                # unfortunately the indices might be out of bounds. So check
+                # that first, and use mode='wrap' then. However only if
+                # there are any indices...
+                if res.size != 0:
+                    if error_unless_broadcast_to_empty:
+                        raise IndexError
+                    for _indx, _size in zip(indx[1:], orig_slice):
+                        if _indx.size == 0:
+                            continue
+                        if np.any(_indx >= _size) or np.any(_indx < -_size):
+                                raise IndexError
+                if len(indx[1:]) == len(orig_slice):
+                    if np.product(orig_slice) == 0:
+                        # Work around for a crash or IndexError with 'wrap'
+                        # in some 0-sized cases.
+                        try:
+                            mi = np.ravel_multi_index(indx[1:], orig_slice, mode='raise')
+                        except:
+                            # This happens with 0-sized orig_slice (sometimes?)
+                            # here it is a ValueError, but indexing gives a:
+                            raise IndexError('invalid index into 0-sized')
+                    else:
+                        mi = np.ravel_multi_index(indx[1:], orig_slice, mode='wrap')
+                else:
+                    # Maybe never happens...
+                    raise ValueError
+                arr = arr.take(mi.ravel(), axis=ax)
+                arr = arr.reshape((arr.shape[:ax]
+                                    + mi.shape
+                                    + arr.shape[ax+1:]))
+                ax += mi.ndim
+                continue
+
+            # If we are here, we have a 1D array for take:
+            arr = arr.take(indx[1], axis=ax)
+            ax += 1
+
+        return arr, no_copy
+
+    def _check_multi_index(self, arr, index):
+        """Check a multi index item getting and simple setting.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed, must be a reshaped arange.
+        index : tuple of indexing objects
+            Index being tested.
+        """
+        # Test item getting
+        try:
+            mimic_get, no_copy = self._get_multi_index(arr, index)
+        except Exception:
+            prev_refcount = sys.getrefcount(arr)
+            assert_raises(Exception, arr.__getitem__, index)
+            assert_raises(Exception, arr.__setitem__, index, 0)
+            assert_equal(prev_refcount, sys.getrefcount(arr))
+            return
+
+        self._compare_index_result(arr, index, mimic_get, no_copy)
+
+    def _check_single_index(self, arr, index):
+        """Check a single index item getting and simple setting.
+
+        Parameters
+        ----------
+        arr : ndarray
+            Array to be indexed, must be an arange.
+        index : indexing object
+            Index being tested. Must be a single index and not a tuple
+            of indexing objects (see also `_check_multi_index`).
+        """
+        try:
+            mimic_get, no_copy = self._get_multi_index(arr, (index,))
+        except Exception:
+            prev_refcount = sys.getrefcount(arr)
+            assert_raises(Exception, arr.__getitem__, index)
+            assert_raises(Exception, arr.__setitem__, index, 0)
+            assert_equal(prev_refcount, sys.getrefcount(arr))
+            return
+
+        self._compare_index_result(arr, index, mimic_get, no_copy)
+
+    def _compare_index_result(self, arr, index, mimic_get, no_copy):
+        """Compare mimicked result to indexing result.
+        """
+        arr = arr.copy()
+        indexed_arr = arr[index]
+        assert_array_equal(indexed_arr, mimic_get)
+        # Check if we got a view, unless its a 0-sized or 0-d array.
+        # (then its not a view, and that does not matter)
+        if indexed_arr.size != 0 and indexed_arr.ndim != 0:
+            assert_(np.may_share_memory(indexed_arr, arr) == no_copy)
+            # Check reference count of the original array
+            if no_copy:
+                # refcount increases by one:
+                assert_equal(sys.getrefcount(arr), 3)
+            else:
+                assert_equal(sys.getrefcount(arr), 2)
+
+        # Test non-broadcast setitem:
+        b = arr.copy()
+        b[index] = mimic_get + 1000
+        if b.size == 0:
+            return  # nothing to compare here...
+        if no_copy and indexed_arr.ndim != 0:
+            # change indexed_arr in-place to manipulate original:
+            indexed_arr += 1000
+            assert_array_equal(arr, b)
+            return
+        # Use the fact that the array is originally an arange:
+        arr.flat[indexed_arr.ravel()] += 1000
+        assert_array_equal(arr, b)
+
+    def test_boolean(self):
+        a = np.array(5)
+        assert_equal(a[np.array(True)], 5)
+        a[np.array(True)] = 1
+        assert_equal(a, 1)
+        # NOTE: This is different from normal broadcasting, as
+        # arr[boolean_array] works like in a multi index. Which means
+        # it is aligned to the left. This is probably correct for
+        # consistency with arr[boolean_array,] also no broadcasting
+        # is done at all
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool),))
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool)[..., 0],))
+        self._check_multi_index(self.a, (np.zeros_like(self.a, dtype=bool)[None, ...],))
+
+    def test_multidim(self):
+        # Automatically test combinations with complex indexes on 2nd (or 1st)
+        # spot and the simple ones in one other spot.
+        with warnings.catch_warnings():
+            # This is so that np.array(True) is not accepted in a full integer
+            # index, when running the file separately.
+            warnings.filterwarnings('error', '', DeprecationWarning)
+            warnings.filterwarnings('error', '', np.VisibleDeprecationWarning)
+
+            def isskip(idx):
+                return isinstance(idx, str) and idx == "skip"
+
+            for simple_pos in [0, 2, 3]:
+                tocheck = [self.fill_indices, self.complex_indices,
+                           self.fill_indices, self.fill_indices]
+                tocheck[simple_pos] = self.simple_indices
+                for index in product(*tocheck):
+                    index = tuple(i for i in index if not isskip(i))
+                    self._check_multi_index(self.a, index)
+                    self._check_multi_index(self.b, index)
+
+        # Check very simple item getting:
+        self._check_multi_index(self.a, (0, 0, 0, 0))
+        self._check_multi_index(self.b, (0, 0, 0, 0))
+        # Also check (simple cases of) too many indices:
+        assert_raises(IndexError, self.a.__getitem__, (0, 0, 0, 0, 0))
+        assert_raises(IndexError, self.a.__setitem__, (0, 0, 0, 0, 0), 0)
+        assert_raises(IndexError, self.a.__getitem__, (0, 0, [1], 0, 0))
+        assert_raises(IndexError, self.a.__setitem__, (0, 0, [1], 0, 0), 0)
+
+    def test_1d(self):
+        a = np.arange(10)
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', '', np.VisibleDeprecationWarning)
+            for index in self.complex_indices:
+                self._check_single_index(a, index)
+
+
+class TestCApiAccess(TestCase):
+    def test_getitem(self):
+        subscript = functools.partial(array_indexing, 0)
+
+        # 0-d arrays don't work:
+        assert_raises(IndexError, subscript, np.ones(()), 0)
+        # Out of bound values:
+        assert_raises(IndexError, subscript, np.ones(10), 11)
+        assert_raises(IndexError, subscript, np.ones(10), -11)
+        assert_raises(IndexError, subscript, np.ones((10, 10)), 11)
+        assert_raises(IndexError, subscript, np.ones((10, 10)), -11)
+
+        a = np.arange(10)
+        assert_array_equal(a[4], subscript(a, 4))
+        a = a.reshape(5, 2)
+        assert_array_equal(a[-4], subscript(a, -4))
+
+    def test_setitem(self):
+        assign = functools.partial(array_indexing, 1)
+
+        # Deletion is impossible:
+        assert_raises(ValueError, assign, np.ones(10), 0)
+        # 0-d arrays don't work:
+        assert_raises(IndexError, assign, np.ones(()), 0, 0)
+        # Out of bound values:
+        assert_raises(IndexError, assign, np.ones(10), 11, 0)
+        assert_raises(IndexError, assign, np.ones(10), -11, 0)
+        assert_raises(IndexError, assign, np.ones((10, 10)), 11, 0)
+        assert_raises(IndexError, assign, np.ones((10, 10)), -11, 0)
+
+        a = np.arange(10)
+        assign(a, 4, 10)
+        assert_(a[4] == 10)
+
+        a = a.reshape(5, 2)
+        assign(a, 4, 10)
+        assert_array_equal(a[-1], [10, 10])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
new file mode 100644
index 0000000000..ddce20fe9a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_array_equal
+)
+
+
+class TestTake(TestCase):
+    def test_simple(self):
+        a = [[1, 2], [3, 4]]
+        a_str = [[b'1', b'2'], [b'3', b'4']]
+        modes = ['raise', 'wrap', 'clip']
+        indices = [-1, 4]
+        index_arrays = [np.empty(0, dtype=np.intp),
+                        np.empty(tuple(), dtype=np.intp),
+                        np.empty((1, 1), dtype=np.intp)]
+        real_indices = {'raise': {-1: 1, 4: IndexError},
+                        'wrap': {-1: 1, 4: 0},
+                        'clip': {-1: 0, 4: 1}}
+        # Currently all types but object, use the same function generation.
+        # So it should not be necessary to test all. However test also a non
+        # refcounted struct on top of object.
+        types = np.int, np.object, np.dtype([('', 'i', 2)])
+        for t in types:
+            # ta works, even if the array may be odd if buffer interface is used
+            ta = np.array(a if np.issubdtype(t, np.number) else a_str, dtype=t)
+            tresult = list(ta.T.copy())
+            for index_array in index_arrays:
+                if index_array.size != 0:
+                    tresult[0].shape = (2,) + index_array.shape
+                    tresult[1].shape = (2,) + index_array.shape
+                for mode in modes:
+                    for index in indices:
+                        real_index = real_indices[mode][index]
+                        if real_index is IndexError and index_array.size != 0:
+                            index_array.put(0, index)
+                            assert_raises(IndexError, ta.take, index_array,
+                                          mode=mode, axis=1)
+                        elif index_array.size != 0:
+                            index_array.put(0, index)
+                            res = ta.take(index_array, mode=mode, axis=1)
+                            assert_array_equal(res, tresult[real_index])
+                        else:
+                            res = ta.take(index_array, mode=mode, axis=1)
+                            assert_(res.shape == (2,) + index_array.shape)
+
+    def test_refcounting(self):
+        objects = [object() for i in range(10)]
+        for mode in ('raise', 'clip', 'wrap'):
+            a = np.array(objects)
+            b = np.array([2, 2, 4, 5, 3, 5])
+            a.take(b, out=a[:6])
+            del a
+            assert_(all(sys.getrefcount(o) == 3 for o in objects))
+            # not contiguous, example:
+            a = np.array(objects * 2)[::2]
+            a.take(b, out=a[:6])
+            del a
+            assert_(all(sys.getrefcount(o) == 3 for o in objects))
+
+    def test_unicode_mode(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.take, 5, mode=k)
+
+    def test_empty_partition(self):
+        # In reference to github issue #6530
+        a_original = np.array([0, 2, 4, 6, 8, 10])
+        a = a_original.copy()
+
+        # An empty partition should be a successful no-op
+        a.partition(np.array([], dtype=np.int16))
+
+        assert_array_equal(a, a_original)
+
+    def test_empty_argpartition(self):
+            # In reference to github issue #6530
+            a = np.array([0, 2, 4, 6, 8, 10])
+            a = a.argpartition(np.array([], dtype=np.int16))
+
+            b = np.array([0, 1, 2, 3, 4, 5])
+            assert_array_equal(a, b)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
new file mode 100644
index 0000000000..1c561a48f5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
@@ -0,0 +1,209 @@
+from __future__ import division, absolute_import, print_function
+
+import locale
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, dec, assert_raises,
+    assert_array_equal, TestCase, temppath,
+)
+from numpy.compat import sixu
+from test_print import in_foreign_locale
+
+longdouble_longer_than_double = (np.finfo(np.longdouble).eps
+                                 < np.finfo(np.double).eps)
+
+
+_o = 1 + np.finfo(np.longdouble).eps
+string_to_longdouble_inaccurate = (_o != np.longdouble(repr(_o)))
+del _o
+
+
+def test_scalar_extraction():
+    """Confirm that extracting a value doesn't convert to python float"""
+    o = 1 + np.finfo(np.longdouble).eps
+    a = np.array([o, o, o])
+    assert_equal(a[1], o)
+
+
+# Conversions string -> long double
+
+
+def test_repr_roundtrip():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_equal(np.longdouble(repr(o)), o,
+                 "repr was %s" % repr(o))
+
+
+def test_unicode():
+    np.longdouble(sixu("1.2"))
+
+
+def test_string():
+    np.longdouble("1.2")
+
+
+def test_bytes():
+    np.longdouble(b"1.2")
+
+
+@in_foreign_locale
+def test_fromstring_foreign():
+    f = 1.234
+    a = np.fromstring(repr(f), dtype=float, sep=" ")
+    assert_equal(a[0], f)
+
+
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_repr_roundtrip_bytes():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_equal(np.longdouble(repr(o).encode("ascii")), o)
+
+
+@in_foreign_locale
+def test_repr_roundtrip_foreign():
+    o = 1.5
+    assert_equal(o, np.longdouble(repr(o)))
+
+
+def test_bogus_string():
+    assert_raises(ValueError, np.longdouble, "spam")
+    assert_raises(ValueError, np.longdouble, "1.0 flub")
+
+
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_fromstring():
+    o = 1 + np.finfo(np.longdouble).eps
+    s = (" " + repr(o))*5
+    a = np.array([o]*5)
+    assert_equal(np.fromstring(s, sep=" ", dtype=np.longdouble), a,
+                 err_msg="reading '%s'" % s)
+
+
+@in_foreign_locale
+def test_fromstring_best_effort_float():
+    assert_equal(np.fromstring("1,234", dtype=float, sep=" "),
+                 np.array([1.]))
+
+
+@in_foreign_locale
+def test_fromstring_best_effort():
+    assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "),
+                 np.array([1.]))
+
+
+def test_fromstring_bogus():
+    assert_equal(np.fromstring("1. 2. 3. flop 4.", dtype=float, sep=" "),
+                 np.array([1., 2., 3.]))
+
+
+def test_fromstring_empty():
+    assert_equal(np.fromstring("xxxxx", sep="x"),
+                 np.array([]))
+
+
+def test_fromstring_missing():
+    assert_equal(np.fromstring("1xx3x4x5x6", sep="x"),
+                 np.array([1]))
+
+
+class FileBased(TestCase):
+
+    ldbl = 1 + np.finfo(np.longdouble).eps
+    tgt = np.array([ldbl]*5)
+    out = ''.join([repr(t) + '\n' for t in tgt])
+
+    def test_fromfile_bogus(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write("1. 2. 3. flop 4.\n")
+            res = np.fromfile(path, dtype=float, sep=" ")
+        assert_equal(res, np.array([1., 2., 3.]))
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_fromfile(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.fromfile(path, dtype=np.longdouble, sep="\n")
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_genfromtxt(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.genfromtxt(path, dtype=np.longdouble)
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_loadtxt(self):
+        with temppath() as path:
+            with open(path, 'wt') as f:
+                f.write(self.out)
+            res = np.loadtxt(path, dtype=np.longdouble)
+        assert_equal(res, self.tgt)
+
+    @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+    def test_tofile_roundtrip(self):
+        with temppath() as path:
+            self.tgt.tofile(path, sep=" ")
+            res = np.fromfile(path, dtype=np.longdouble, sep=" ")
+        assert_equal(res, self.tgt)
+
+
+@in_foreign_locale
+def test_fromstring_foreign():
+    s = "1.234"
+    a = np.fromstring(s, dtype=np.longdouble, sep=" ")
+    assert_equal(a[0], np.longdouble(s))
+
+
+@in_foreign_locale
+def test_fromstring_foreign_sep():
+    a = np.array([1, 2, 3, 4])
+    b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",")
+    assert_array_equal(a, b)
+
+
+@in_foreign_locale
+def test_fromstring_foreign_value():
+    b = np.fromstring("1,234", dtype=np.longdouble, sep=" ")
+    assert_array_equal(b[0], 1)
+
+
+# Conversions long double -> string
+
+
+def test_repr_exact():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_(repr(o) != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "BUG #2376")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_format():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_("{0:.40g}".format(o) != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "BUG #2376")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_percent():
+    o = 1 + np.finfo(np.longdouble).eps
+    assert_("%.40g" % o != '1')
+
+
+@dec.knownfailureif(longdouble_longer_than_double, "array repr problem")
+@dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l")
+def test_array_repr():
+    o = 1 + np.finfo(np.longdouble).eps
+    a = np.array([o])
+    b = np.array([1], dtype=np.longdouble)
+    if not np.all(a != b):
+        raise ValueError("precision loss creating arrays")
+    assert_(repr(a) != repr(b))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_machar.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
new file mode 100644
index 0000000000..d8fc537aa4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
@@ -0,0 +1,29 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.core.machar import MachAr
+import numpy.core.numerictypes as ntypes
+from numpy import errstate, array
+from numpy.testing import TestCase, run_module_suite
+
+class TestMachAr(TestCase):
+    def _run_machar_highprec(self):
+        # Instantiate MachAr instance with high enough precision to cause
+        # underflow
+        try:
+            hiprec = ntypes.float96
+            MachAr(lambda v:array([v], hiprec))
+        except AttributeError:
+            "Skipping test: no ntypes.float96 available on this platform."
+
+    def test_underlow(self):
+        # Regression test for #759:
+        # instanciating MachAr for dtype = np.float96 raises spurious warning.
+        with errstate(all='raise'):
+            try:
+                self._run_machar_highprec()
+            except FloatingPointError as e:
+                self.fail("Caught %s exception, should not have been raised." % e)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
new file mode 100644
index 0000000000..5a1f6ac980
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
@@ -0,0 +1,522 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+
+import numpy as np
+from numpy.testing import run_module_suite, assert_, assert_raises, assert_equal
+
+from numpy.core.multiarray_tests import solve_diophantine, internal_overlap
+from numpy.lib.stride_tricks import as_strided
+from numpy.compat import long
+
+if sys.version_info[0] >= 3:
+    xrange = range
+
+
+ndims = 2
+size = 10
+shape = tuple([size] * ndims)
+
+MAY_SHARE_BOUNDS = 0
+MAY_SHARE_EXACT = -1
+
+
+def _indices_for_nelems(nelems):
+    """Returns slices of length nelems, from start onwards, in direction sign."""
+
+    if nelems == 0:
+        return [size // 2]  # int index
+
+    res = []
+    for step in (1, 2):
+        for sign in (-1, 1):
+            start = size // 2 - nelems * step * sign // 2
+            stop = start + nelems * step * sign
+            res.append(slice(start, stop, step * sign))
+
+    return res
+
+
+def _indices_for_axis():
+    """Returns (src, dst) pairs of indices."""
+
+    res = []
+    for nelems in (0, 2, 3):
+        ind = _indices_for_nelems(nelems)
+
+        # no itertools.product available in Py2.4
+        res.extend([(a, b) for a in ind for b in ind])  # all assignments of size "nelems"
+
+    return res
+
+
+def _indices(ndims):
+    """Returns ((axis0_src, axis0_dst), (axis1_src, axis1_dst), ... ) index pairs."""
+
+    ind = _indices_for_axis()
+
+    # no itertools.product available in Py2.4
+
+    res = [[]]
+    for i in range(ndims):
+        newres = []
+        for elem in ind:
+            for others in res:
+                newres.append([elem] + others)
+        res = newres
+
+    return res
+
+
+def _check_assignment(srcidx, dstidx):
+    """Check assignment arr[dstidx] = arr[srcidx] works."""
+
+    arr = np.arange(np.product(shape)).reshape(shape)
+
+    cpy = arr.copy()
+
+    cpy[dstidx] = arr[srcidx]
+    arr[dstidx] = arr[srcidx]
+
+    assert_(np.all(arr == cpy),
+            'assigning arr[%s] = arr[%s]' % (dstidx, srcidx))
+
+
+def test_overlapping_assignments():
+    """Test automatically generated assignments which overlap in memory."""
+
+    inds = _indices(ndims)
+
+    for ind in inds:
+        srcidx = tuple([a[0] for a in ind])
+        dstidx = tuple([a[1] for a in ind])
+
+        yield _check_assignment, srcidx, dstidx
+
+
+def test_diophantine_fuzz():
+    # Fuzz test the diophantine solver
+    rng = np.random.RandomState(1234)
+
+    max_int = np.iinfo(np.intp).max
+
+    for ndim in range(10):
+        feasible_count = 0
+        infeasible_count = 0
+
+        min_count = 500//(ndim + 1)
+
+        numbers = []
+        while min(feasible_count, infeasible_count) < min_count:
+            # Ensure big and small integer problems
+            A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6
+            U_max = rng.randint(0, 11, dtype=np.intp)**6
+
+            A_max = min(max_int, A_max)
+            U_max = min(max_int-1, U_max)
+
+            A = tuple(int(rng.randint(1, A_max+1, dtype=np.intp))
+                      for j in range(ndim))
+            U = tuple(int(rng.randint(0, U_max+2, dtype=np.intp))
+                      for j in range(ndim))
+
+            b_ub = min(max_int-2, sum(a*ub for a, ub in zip(A, U)))
+            b = rng.randint(-1, b_ub+2, dtype=np.intp)
+
+            if ndim == 0 and feasible_count < min_count:
+                b = 0
+
+            X = solve_diophantine(A, U, b)
+
+            if X is None:
+                # Check the simplified decision problem agrees
+                X_simplified = solve_diophantine(A, U, b, simplify=1)
+                assert_(X_simplified is None, (A, U, b, X_simplified))
+
+                # Check no solution exists (provided the problem is
+                # small enough so that brute force checking doesn't
+                # take too long)
+                try:
+                    ranges = tuple(xrange(0, a*ub+1, a) for a, ub in zip(A, U))
+                except OverflowError:
+                    # xrange on 32-bit Python 2 may overflow
+                    continue
+
+                size = 1
+                for r in ranges:
+                    size *= len(r)
+                if size < 100000:
+                    assert_(not any(sum(w) == b for w in itertools.product(*ranges)))
+                    infeasible_count += 1
+            else:
+                # Check the simplified decision problem agrees
+                X_simplified = solve_diophantine(A, U, b, simplify=1)
+                assert_(X_simplified is not None, (A, U, b, X_simplified))
+
+                # Check validity
+                assert_(sum(a*x for a, x in zip(A, X)) == b)
+                assert_(all(0 <= x <= ub for x, ub in zip(X, U)))
+                feasible_count += 1
+
+
+def test_diophantine_overflow():
+    # Smoke test integer overflow detection
+    max_intp = np.iinfo(np.intp).max
+    max_int64 = np.iinfo(np.int64).max
+
+    if max_int64 <= max_intp:
+        # Check that the algorithm works internally in 128-bit;
+        # solving this problem requires large intermediate numbers
+        A = (max_int64//2, max_int64//2 - 10)
+        U = (max_int64//2, max_int64//2 - 10)
+        b = 2*(max_int64//2) - 10
+
+        assert_equal(solve_diophantine(A, U, b), (1, 1))
+
+
+def check_may_share_memory_exact(a, b):
+    got = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
+
+    assert_equal(np.may_share_memory(a, b),
+                 np.may_share_memory(a, b, max_work=MAY_SHARE_BOUNDS))
+
+    a.fill(0)
+    b.fill(0)
+    a.fill(1)
+    exact = b.any()
+
+    err_msg = ""
+    if got != exact:
+        err_msg = "    " + "\n    ".join([
+            "base_a - base_b = %r" % (a.__array_interface__['data'][0] - b.__array_interface__['data'][0],),
+            "shape_a = %r" % (a.shape,),
+            "shape_b = %r" % (b.shape,),
+            "strides_a = %r" % (a.strides,),
+            "strides_b = %r" % (b.strides,),
+            "size_a = %r" % (a.size,),
+            "size_b = %r" % (b.size,)
+        ])
+
+    assert_equal(got, exact, err_msg=err_msg)
+
+
+def test_may_share_memory_manual():
+    # Manual test cases for may_share_memory
+
+    # Base arrays
+    xs0 = [
+        np.zeros([13, 21, 23, 22], dtype=np.int8),
+        np.zeros([13, 21, 23*2, 22], dtype=np.int8)[:,:,::2,:]
+    ]
+
+    # Generate all negative stride combinations
+    xs = []
+    for x in xs0:
+        for ss in itertools.product(*(([slice(None), slice(None, None, -1)],)*4)):
+            xp = x[ss]
+            xs.append(xp)
+
+    for x in xs:
+        # The default is a simple extent check
+        assert_(np.may_share_memory(x[:,0,:], x[:,1,:]))
+        assert_(np.may_share_memory(x[:,0,:], x[:,1,:], max_work=None))
+
+        # Exact checks
+        check_may_share_memory_exact(x[:,0,:], x[:,1,:])
+        check_may_share_memory_exact(x[:,::7], x[:,3::3])
+
+        try:
+            xp = x.ravel()
+            if xp.flags.owndata:
+                continue
+            xp = xp.view(np.int16)
+        except ValueError:
+            continue
+
+        # 0-size arrays cannot overlap
+        check_may_share_memory_exact(x.ravel()[6:6],
+                                     xp.reshape(13, 21, 23, 11)[:,::7])
+
+        # Test itemsize is dealt with
+        check_may_share_memory_exact(x[:,::7],
+                                     xp.reshape(13, 21, 23, 11))
+        check_may_share_memory_exact(x[:,::7],
+                                     xp.reshape(13, 21, 23, 11)[:,3::3])
+        check_may_share_memory_exact(x.ravel()[6:7],
+                                     xp.reshape(13, 21, 23, 11)[:,::7])
+
+    # Check unit size
+    x = np.zeros([1], dtype=np.int8)
+    check_may_share_memory_exact(x, x)
+    check_may_share_memory_exact(x, x.copy())
+
+
+def check_may_share_memory_easy_fuzz(get_max_work, same_steps, min_count):
+    # Check that overlap problems with common strides are solved with
+    # little work.
+    x = np.zeros([17,34,71,97], dtype=np.int16)
+
+    rng = np.random.RandomState(1234)
+
+    def random_slice(n, step):
+        start = rng.randint(0, n+1, dtype=np.intp)
+        stop = rng.randint(start, n+1, dtype=np.intp)
+        if rng.randint(0, 2, dtype=np.intp) == 0:
+            stop, start = start, stop
+            step *= -1
+        return slice(start, stop, step)
+
+    feasible = 0
+    infeasible = 0
+
+    while min(feasible, infeasible) < min_count:
+        steps = tuple(rng.randint(1, 11, dtype=np.intp)
+                      if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                      for j in range(x.ndim))
+        if same_steps:
+            steps2 = steps
+        else:
+            steps2 = tuple(rng.randint(1, 11, dtype=np.intp)
+                           if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                           for j in range(x.ndim))
+
+        t1 = np.arange(x.ndim)
+        rng.shuffle(t1)
+
+        t2 = np.arange(x.ndim)
+        rng.shuffle(t2)
+
+        s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
+        s2 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps2))
+        a = x[s1].transpose(t1)
+        b = x[s2].transpose(t2)
+
+        bounds_overlap = np.may_share_memory(a, b)
+        may_share_answer = np.may_share_memory(a, b)
+        easy_answer = np.may_share_memory(a, b, max_work=get_max_work(a, b))
+        exact_answer = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT)
+
+        if easy_answer != exact_answer:
+            # assert_equal is slow...
+            assert_equal(easy_answer, exact_answer, err_msg=repr((s1, s2)))
+
+        if may_share_answer != bounds_overlap:
+            assert_equal(may_share_answer, bounds_overlap,
+                         err_msg=repr((s1, s2)))
+
+        if bounds_overlap:
+            if exact_answer:
+                feasible += 1
+            else:
+                infeasible += 1
+
+
+def test_may_share_memory_easy_fuzz():
+    # Check that overlap problems with common strides are always
+    # solved with little work.
+
+    check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: 1,
+                                     same_steps=True,
+                                     min_count=2000)
+
+
+def test_may_share_memory_harder_fuzz():
+    # Overlap problems with not necessarily common strides take more
+    # work.
+    #
+    # The work bound below can't be reduced much. Harder problems can
+    # also exist but not be detected here, as the set of problems
+    # comes from RNG.
+
+    check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: max(a.size, b.size)//2,
+                                     same_steps=False,
+                                     min_count=2000)
+
+
+def test_shares_memory_api():
+    x = np.zeros([4, 5, 6], dtype=np.int8)
+
+    assert_equal(np.shares_memory(x, x), True)
+    assert_equal(np.shares_memory(x, x.copy()), False)
+
+    a = x[:,::2,::3]
+    b = x[:,::3,::2]
+    assert_equal(np.shares_memory(a, b), True)
+    assert_equal(np.shares_memory(a, b, max_work=None), True)
+    assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=1)
+    assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=long(1))
+
+
+def test_internal_overlap_diophantine():
+    def check(A, U, exists=None):
+        X = solve_diophantine(A, U, 0, require_ub_nontrivial=1)
+
+        if exists is None:
+            exists = (X is not None)
+
+        if X is not None:
+            assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U)))
+            assert_(all(0 <= x <= u for x, u in zip(X, U)))
+            assert_(any(x != u//2 for x, u in zip(X, U)))
+
+        if exists:
+            assert_(X is not None, repr(X))
+        else:
+            assert_(X is None, repr(X))
+
+    # Smoke tests
+    check((3, 2), (2*2, 3*2), exists=True)
+    check((3*2, 2), (15*2, (3-1)*2), exists=False)
+
+
+def test_internal_overlap_slices():
+    # Slicing an array never generates internal overlap
+
+    x = np.zeros([17,34,71,97], dtype=np.int16)
+
+    rng = np.random.RandomState(1234)
+
+    def random_slice(n, step):
+        start = rng.randint(0, n+1, dtype=np.intp)
+        stop = rng.randint(start, n+1, dtype=np.intp)
+        if rng.randint(0, 2, dtype=np.intp) == 0:
+            stop, start = start, stop
+            step *= -1
+        return slice(start, stop, step)
+
+    cases = 0
+    min_count = 5000
+
+    while cases < min_count:
+        steps = tuple(rng.randint(1, 11, dtype=np.intp)
+                      if rng.randint(0, 5, dtype=np.intp) == 0 else 1
+                      for j in range(x.ndim))
+        t1 = np.arange(x.ndim)
+        rng.shuffle(t1)
+        s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps))
+        a = x[s1].transpose(t1)
+
+        assert_(not internal_overlap(a))
+        cases += 1
+
+
+def check_internal_overlap(a, manual_expected=None):
+    got = internal_overlap(a)
+
+    # Brute-force check
+    m = set()
+    ranges = tuple(xrange(n) for n in a.shape)
+    for v in itertools.product(*ranges):
+        offset = sum(s*w for s, w in zip(a.strides, v))
+        if offset in m:
+            expected = True
+            break
+        else:
+            m.add(offset)
+    else:
+        expected = False
+
+    # Compare
+    if got != expected:
+        assert_equal(got, expected, err_msg=repr((a.strides, a.shape)))
+    if manual_expected is not None and expected != manual_expected:
+        assert_equal(expected, manual_expected)
+    return got
+
+
+def test_internal_overlap_manual():
+    # Stride tricks can construct arrays with internal overlap
+
+    # We don't care about memory bounds, the array is not
+    # read/write accessed
+    x = np.arange(1).astype(np.int8)
+
+    # Check low-dimensional special cases
+
+    check_internal_overlap(x, False) # 1-dim
+    check_internal_overlap(x.reshape([]), False) # 0-dim
+
+    a = as_strided(x, strides=(3, 4), shape=(4, 4))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(3, 4), shape=(5, 4))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0,), shape=(0,))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0,), shape=(1,))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0,), shape=(2,))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0, -9993), shape=(87, 22))
+    check_internal_overlap(a, True)
+
+    a = as_strided(x, strides=(0, -9993), shape=(1, 22))
+    check_internal_overlap(a, False)
+
+    a = as_strided(x, strides=(0, -9993), shape=(0, 22))
+    check_internal_overlap(a, False)
+
+
+def test_internal_overlap_fuzz():
+    # Fuzz check; the brute-force check is fairly slow
+
+    x = np.arange(1).astype(np.int8)
+
+    overlap = 0
+    no_overlap = 0
+    min_count = 100
+
+    rng = np.random.RandomState(1234)
+
+    while min(overlap, no_overlap) < min_count:
+        ndim = rng.randint(1, 4, dtype=np.intp)
+
+        strides = tuple(rng.randint(-1000, 1000, dtype=np.intp)
+                        for j in range(ndim))
+        shape = tuple(rng.randint(1, 30, dtype=np.intp)
+                      for j in range(ndim))
+
+        a = as_strided(x, strides=strides, shape=shape)
+        result = check_internal_overlap(a)
+
+        if result:
+            overlap += 1
+        else:
+            no_overlap += 1
+
+
+def test_non_ndarray_inputs():
+    # Regression check for gh-5604
+
+    class MyArray(object):
+        def __init__(self, data):
+            self.data = data
+
+        @property
+        def __array_interface__(self):
+            return self.data.__array_interface__
+
+    class MyArray2(object):
+        def __init__(self, data):
+            self.data = data
+
+        def __array__(self):
+            return self.data
+
+    for cls in [MyArray, MyArray2]:
+        x = np.arange(5)
+
+        assert_(np.may_share_memory(cls(x[::2]), x[1::2]))
+        assert_(not np.shares_memory(cls(x[::2]), x[1::2]))
+
+        assert_(np.shares_memory(cls(x[1::3]), x[::2]))
+        assert_(np.may_share_memory(cls(x[1::3]), x[::2]))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
new file mode 100644
index 0000000000..e41758c510
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
@@ -0,0 +1,130 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import shutil
+from tempfile import NamedTemporaryFile, TemporaryFile, mktemp, mkdtemp
+
+from numpy import memmap
+from numpy import arange, allclose, asarray
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    dec
+)
+
+class TestMemmap(TestCase):
+    def setUp(self):
+        self.tmpfp = NamedTemporaryFile(prefix='mmap')
+        self.tempdir = mkdtemp()
+        self.shape = (3, 4)
+        self.dtype = 'float32'
+        self.data = arange(12, dtype=self.dtype)
+        self.data.resize(self.shape)
+
+    def tearDown(self):
+        self.tmpfp.close()
+        shutil.rmtree(self.tempdir)
+
+    def test_roundtrip(self):
+        # Write data to file
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp[:] = self.data[:]
+        del fp  # Test __del__ machinery, which handles cleanup
+
+        # Read data back from file
+        newfp = memmap(self.tmpfp, dtype=self.dtype, mode='r',
+                       shape=self.shape)
+        assert_(allclose(self.data, newfp))
+        assert_array_equal(self.data, newfp)
+
+    def test_open_with_filename(self):
+        tmpname = mktemp('', 'mmap', dir=self.tempdir)
+        fp = memmap(tmpname, dtype=self.dtype, mode='w+',
+                       shape=self.shape)
+        fp[:] = self.data[:]
+        del fp
+
+    def test_unnamed_file(self):
+        with TemporaryFile() as f:
+            fp = memmap(f, dtype=self.dtype, shape=self.shape)
+            del fp
+
+    def test_attributes(self):
+        offset = 1
+        mode = "w+"
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode=mode,
+                    shape=self.shape, offset=offset)
+        self.assertEqual(offset, fp.offset)
+        self.assertEqual(mode, fp.mode)
+        del fp
+
+    def test_filename(self):
+        tmpname = mktemp('', 'mmap', dir=self.tempdir)
+        fp = memmap(tmpname, dtype=self.dtype, mode='w+',
+                       shape=self.shape)
+        abspath = os.path.abspath(tmpname)
+        fp[:] = self.data[:]
+        self.assertEqual(abspath, fp.filename)
+        b = fp[:1]
+        self.assertEqual(abspath, b.filename)
+        del b
+        del fp
+
+    def test_filename_fileobj(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode="w+",
+                    shape=self.shape)
+        self.assertEqual(fp.filename, self.tmpfp.name)
+
+    @dec.knownfailureif(sys.platform == 'gnu0', "This test is known to fail on hurd")
+    def test_flush(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp[:] = self.data[:]
+        assert_equal(fp[0], self.data[0])
+        fp.flush()
+
+    def test_del(self):
+        # Make sure a view does not delete the underlying mmap
+        fp_base = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        fp_base[0] = 5
+        fp_view = fp_base[0:1]
+        assert_equal(fp_view[0], 5)
+        del fp_view
+        # Should still be able to access and assign values after
+        # deleting the view
+        assert_equal(fp_base[0], 5)
+        fp_base[0] = 6
+        assert_equal(fp_base[0], 6)
+
+    def test_arithmetic_drops_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        tmp = (fp + 10)
+        if isinstance(tmp, memmap):
+            assert_(tmp._mmap is not fp._mmap)
+
+    def test_indexing_drops_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        tmp = fp[[(1, 2), (2, 3)]]
+        if isinstance(tmp, memmap):
+            assert_(tmp._mmap is not fp._mmap)
+
+    def test_slicing_keeps_references(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+',
+                    shape=self.shape)
+        assert_(fp[:2, :2]._mmap is fp._mmap)
+
+    def test_view(self):
+        fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape)
+        new1 = fp.view()
+        new2 = new1.view()
+        assert_(new1.base is fp)
+        assert_(new2.base is fp)
+        new_array = asarray(fp)
+        assert_(new_array.base is fp)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
new file mode 100644
index 0000000000..0a68ff6e2e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
@@ -0,0 +1,6386 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+import tempfile
+import sys
+import shutil
+import warnings
+import operator
+import io
+import itertools
+import ctypes
+import os
+if sys.version_info[0] >= 3:
+    import builtins
+else:
+    import __builtin__ as builtins
+from decimal import Decimal
+
+
+import numpy as np
+from numpy.compat import asbytes, getexception, strchar, unicode, sixu
+from test_print import in_foreign_locale
+from numpy.core.multiarray_tests import (
+    test_neighborhood_iterator, test_neighborhood_iterator_oob,
+    test_pydatamem_seteventhook_start, test_pydatamem_seteventhook_end,
+    test_inplace_increment, get_buffer_info, test_as_c_array
+    )
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_equal, assert_almost_equal, assert_array_equal,
+    assert_array_almost_equal, assert_allclose,
+    assert_array_less, runstring, dec, SkipTest
+    )
+
+# Need to test an object that does not fully implement math interface
+from datetime import timedelta
+
+
+if sys.version_info[:2] > (3, 2):
+    # In Python 3.3 the representation of empty shape, strides and sub-offsets
+    # is an empty tuple instead of None.
+    # http://docs.python.org/dev/whatsnew/3.3.html#api-changes
+    EMPTY = ()
+else:
+    EMPTY = None
+
+
+class TestFlags(TestCase):
+    def setUp(self):
+        self.a = np.arange(10)
+
+    def test_writeable(self):
+        mydict = locals()
+        self.a.flags.writeable = False
+        self.assertRaises(ValueError, runstring, 'self.a[0] = 3', mydict)
+        self.assertRaises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict)
+        self.a.flags.writeable = True
+        self.a[0] = 5
+        self.a[0] = 0
+
+    def test_otherflags(self):
+        assert_equal(self.a.flags.carray, True)
+        assert_equal(self.a.flags.farray, False)
+        assert_equal(self.a.flags.behaved, True)
+        assert_equal(self.a.flags.fnc, False)
+        assert_equal(self.a.flags.forc, True)
+        assert_equal(self.a.flags.owndata, True)
+        assert_equal(self.a.flags.writeable, True)
+        assert_equal(self.a.flags.aligned, True)
+        assert_equal(self.a.flags.updateifcopy, False)
+
+    def test_string_align(self):
+        a = np.zeros(4, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+        # not power of two are accessed byte-wise and thus considered aligned
+        a = np.zeros(5, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+
+    def test_void_align(self):
+        a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")]))
+        assert_(a.flags.aligned)
+
+
+class TestHash(TestCase):
+    # see #3793
+    def test_int(self):
+        for st, ut, s in [(np.int8, np.uint8, 8),
+                          (np.int16, np.uint16, 16),
+                          (np.int32, np.uint32, 32),
+                          (np.int64, np.uint64, 64)]:
+            for i in range(1, s):
+                assert_equal(hash(st(-2**i)), hash(-2**i),
+                             err_msg="%r: -2**%d" % (st, i))
+                assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (st, i - 1))
+                assert_equal(hash(st(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (st, i))
+
+                i = max(i - 1, 1)
+                assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (ut, i - 1))
+                assert_equal(hash(ut(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (ut, i))
+
+
+class TestAttributes(TestCase):
+    def setUp(self):
+        self.one = np.arange(10)
+        self.two = np.arange(20).reshape(4, 5)
+        self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6)
+
+    def test_attributes(self):
+        assert_equal(self.one.shape, (10,))
+        assert_equal(self.two.shape, (4, 5))
+        assert_equal(self.three.shape, (2, 5, 6))
+        self.three.shape = (10, 3, 2)
+        assert_equal(self.three.shape, (10, 3, 2))
+        self.three.shape = (2, 5, 6)
+        assert_equal(self.one.strides, (self.one.itemsize,))
+        num = self.two.itemsize
+        assert_equal(self.two.strides, (5*num, num))
+        num = self.three.itemsize
+        assert_equal(self.three.strides, (30*num, 6*num, num))
+        assert_equal(self.one.ndim, 1)
+        assert_equal(self.two.ndim, 2)
+        assert_equal(self.three.ndim, 3)
+        num = self.two.itemsize
+        assert_equal(self.two.size, 20)
+        assert_equal(self.two.nbytes, 20*num)
+        assert_equal(self.two.itemsize, self.two.dtype.itemsize)
+        assert_equal(self.two.base, np.arange(20))
+
+    def test_dtypeattr(self):
+        assert_equal(self.one.dtype, np.dtype(np.int_))
+        assert_equal(self.three.dtype, np.dtype(np.float_))
+        assert_equal(self.one.dtype.char, 'l')
+        assert_equal(self.three.dtype.char, 'd')
+        self.assertTrue(self.three.dtype.str[0] in '<>')
+        assert_equal(self.one.dtype.str[1], 'i')
+        assert_equal(self.three.dtype.str[1], 'f')
+
+    def test_int_subclassing(self):
+        # Regression test for https://github.com/numpy/numpy/pull/3526
+
+        numpy_int = np.int_(0)
+
+        if sys.version_info[0] >= 3:
+            # On Py3k int_ should not inherit from int, because it's not
+            # fixed-width anymore
+            assert_equal(isinstance(numpy_int, int), False)
+        else:
+            # Otherwise, it should inherit from int...
+            assert_equal(isinstance(numpy_int, int), True)
+
+            # ... and fast-path checks on C-API level should also work
+            from numpy.core.multiarray_tests import test_int_subclass
+            assert_equal(test_int_subclass(numpy_int), True)
+
+    def test_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            return np.ndarray(size, buffer=x, dtype=int,
+                              offset=offset*x.itemsize,
+                              strides=strides*x.itemsize)
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(ValueError, make_array, 8, 3, 1)
+        assert_equal(make_array(8, 3, 0), np.array([3]*8))
+        # Check behavior reported in gh-2503:
+        self.assertRaises(ValueError, make_array, (2, 3), 5, np.array([-2, -3]))
+        make_array(0, 0, 10)
+
+    def test_set_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            try:
+                r = np.ndarray([size], dtype=int, buffer=x,
+                               offset=offset*x.itemsize)
+            except:
+                raise RuntimeError(getexception())
+            r.strides = strides = strides*x.itemsize
+            return r
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(RuntimeError, make_array, 8, 3, 1)
+        # Check that the true extent of the array is used.
+        # Test relies on as_strided base not exposing a buffer.
+        x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0))
+
+        def set_strides(arr, strides):
+            arr.strides = strides
+
+        self.assertRaises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize))
+
+        # Test for offset calculations:
+        x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1],
+                                                    shape=(10,), strides=(-1,))
+        self.assertRaises(ValueError, set_strides, x[::-1], -1)
+        a = x[::-1]
+        a.strides = 1
+        a[::2].strides = 2
+
+    def test_fill(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = np.empty((3, 2, 1), t)
+            y = np.empty((3, 2, 1), t)
+            x.fill(1)
+            y[...] = 1
+            assert_equal(x, y)
+
+    def test_fill_max_uint64(self):
+        x = np.empty((3, 2, 1), dtype=np.uint64)
+        y = np.empty((3, 2, 1), dtype=np.uint64)
+        value = 2**64 - 1
+        y[...] = value
+        x.fill(value)
+        assert_array_equal(x, y)
+
+    def test_fill_struct_array(self):
+        # Filling from a scalar
+        x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8')
+        x.fill(x[0])
+        assert_equal(x['f1'][1], x['f1'][0])
+        # Filling from a tuple that can be converted
+        # to a scalar
+        x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')])
+        x.fill((3.5, -2))
+        assert_array_equal(x['a'], [3.5, 3.5])
+        assert_array_equal(x['b'], [-2, -2])
+
+
+class TestArrayConstruction(TestCase):
+    def test_array(self):
+        d = np.ones(6)
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6)))
+
+        d = np.ones(6)
+        tgt = np.ones((2, 6))
+        r = np.array([d, d])
+        assert_equal(r, tgt)
+        tgt[1] = 2
+        r = np.array([d, d + 1])
+        assert_equal(r, tgt)
+
+        d = np.ones(6)
+        r = np.array([[d, d]])
+        assert_equal(r, np.ones((1, 2, 6)))
+
+        d = np.ones(6)
+        r = np.array([[d, d], [d, d]])
+        assert_equal(r, np.ones((2, 2, 6)))
+
+        d = np.ones((6, 6))
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6, 6)))
+
+        d = np.ones((6, ))
+        r = np.array([[d, d + 1], d + 2])
+        assert_equal(len(r), 2)
+        assert_equal(r[0], [d, d + 1])
+        assert_equal(r[1], d + 2)
+
+        tgt = np.ones((2, 3), dtype=np.bool)
+        tgt[0, 2] = False
+        tgt[1, 0:2] = False
+        r = np.array([[True, True, False], [False, False, True]])
+        assert_equal(r, tgt)
+        r = np.array([[True, False], [True, False], [False, True]])
+        assert_equal(r, tgt.T)
+
+    def test_array_empty(self):
+        assert_raises(TypeError, np.array)
+
+    def test_array_copy_false(self):
+        d = np.array([1, 2, 3])
+        e = np.array(d, copy=False)
+        d[1] = 3
+        assert_array_equal(e, [1, 3, 3])
+        e = np.array(d, copy=False, order='F')
+        d[1] = 4
+        assert_array_equal(e, [1, 4, 3])
+        e[2] = 7
+        assert_array_equal(d, [1, 4, 7])
+
+    def test_array_copy_true(self):
+        d = np.array([[1,2,3], [1, 2, 3]])
+        e = np.array(d, copy=True)
+        d[0, 1] = 3
+        e[0, 2] = -7
+        assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
+        e = np.array(d, copy=True, order='F')
+        d[0, 1] = 5
+        e[0, 2] = 7
+        assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 5, 3], [1,2,3]])
+
+    def test_array_cont(self):
+        d = np.ones(10)[::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.ascontiguousarray(d).flags.f_contiguous)
+        assert_(np.asfortranarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+        d = np.ones((10, 10))[::2,::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+
+
+class TestAssignment(TestCase):
+    def test_assignment_broadcasting(self):
+        a = np.arange(6).reshape(2, 3)
+
+        # Broadcasting the input to the output
+        a[...] = np.arange(3)
+        assert_equal(a, [[0, 1, 2], [0, 1, 2]])
+        a[...] = np.arange(2).reshape(2, 1)
+        assert_equal(a, [[0, 0, 0], [1, 1, 1]])
+
+        # For compatibility with <= 1.5, a limited version of broadcasting
+        # the output to the input.
+        #
+        # This behavior is inconsistent with NumPy broadcasting
+        # in general, because it only uses one of the two broadcasting
+        # rules (adding a new "1" dimension to the left of the shape),
+        # applied to the output instead of an input. In NumPy 2.0, this kind
+        # of broadcasting assignment will likely be disallowed.
+        a[...] = np.arange(6)[::-1].reshape(1, 2, 3)
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+        # The other type of broadcasting would require a reduction operation.
+
+        def assign(a, b):
+            a[...] = b
+
+        assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3))
+
+    def test_assignment_errors(self):
+        # Address issue #2276
+        class C:
+            pass
+        a = np.zeros(1)
+
+        def assign(v):
+            a[0] = v
+
+        assert_raises((AttributeError, TypeError), assign, C())
+        assert_raises(ValueError, assign, [1])
+
+
+class TestDtypedescr(TestCase):
+    def test_construction(self):
+        d1 = np.dtype('i4')
+        assert_equal(d1, np.dtype(np.int32))
+        d2 = np.dtype('f8')
+        assert_equal(d2, np.dtype(np.float64))
+
+    def test_byteorders(self):
+        self.assertNotEqual(np.dtype('<i4'), np.dtype('>i4'))
+        self.assertNotEqual(np.dtype([('a', '<i4')]), np.dtype([('a', '>i4')]))
+
+
+class TestZeroRank(TestCase):
+    def setUp(self):
+        self.d = np.array(0), np.array('x', object)
+
+    def test_ellipsis_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(b[...], 'x')
+        self.assertTrue(a[...].base is a)  # `a[...] is a` in numpy <1.9.
+        self.assertTrue(b[...].base is b)  # `b[...] is b` in numpy <1.9.
+
+    def test_empty_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(b[()], 'x')
+        self.assertTrue(type(a[()]) is a.dtype.type)
+        self.assertTrue(type(b[()]) is str)
+
+    def test_invalid_subscript(self):
+        a, b = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[0], b)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], b)
+
+    def test_ellipsis_subscript_assignment(self):
+        a, b = self.d
+        a[...] = 42
+        self.assertEqual(a, 42)
+        b[...] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_empty_subscript_assignment(self):
+        a, b = self.d
+        a[()] = 42
+        self.assertEqual(a, 42)
+        b[()] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_invalid_subscript_assignment(self):
+        a, b = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(IndexError, assign, a, 0, 42)
+        self.assertRaises(IndexError, assign, b, 0, '')
+        self.assertRaises(ValueError, assign, a, (), '')
+
+    def test_newaxis(self):
+        a, b = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a, b = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_constructor(self):
+        x = np.ndarray(())
+        x[()] = 5
+        self.assertEqual(x[()], 5)
+        y = np.ndarray((), buffer=x)
+        y[()] = 6
+        self.assertEqual(x[()], 6)
+
+    def test_output(self):
+        x = np.array(2)
+        self.assertRaises(ValueError, np.add, x, [1], x)
+
+
+class TestScalarIndexing(TestCase):
+    def setUp(self):
+        self.d = np.array([0, 1])[0]
+
+    def test_ellipsis_subscript(self):
+        a = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(a[...].shape, ())
+
+    def test_empty_subscript(self):
+        a = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(a[()].shape, ())
+
+    def test_invalid_subscript(self):
+        a = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+
+    def test_invalid_subscript_assignment(self):
+        a = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(TypeError, assign, a, 0, 42)
+
+    def test_newaxis(self):
+        a = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_overlapping_assignment(self):
+        # With positive strides
+        a = np.arange(4)
+        a[:-1] = a[1:]
+        assert_equal(a, [1, 2, 3, 3])
+
+        a = np.arange(4)
+        a[1:] = a[:-1]
+        assert_equal(a, [0, 0, 1, 2])
+
+        # With positive and negative strides
+        a = np.arange(4)
+        a[:] = a[::-1]
+        assert_equal(a, [3, 2, 1, 0])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1,:] = a[:, ::-1]
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1, ::-1] = a[:, ::-1]
+        assert_equal(a, [[3, 4, 5], [0, 1, 2]])
+
+        # With just one element overlapping
+        a = np.arange(5)
+        a[:3] = a[2:]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[:3]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+        a = np.arange(5)
+        a[2::-1] = a[2:]
+        assert_equal(a, [4, 3, 2, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[2::-1]
+        assert_equal(a, [0, 1, 2, 1, 0])
+
+        a = np.arange(5)
+        a[2::-1] = a[:1:-1]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[:1:-1] = a[2::-1]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+
+class TestCreation(TestCase):
+    def test_from_attribute(self):
+        class x(object):
+            def __array__(self, dtype=None):
+                pass
+
+        self.assertRaises(ValueError, np.array, x())
+
+    def test_from_string(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['Float']
+        nstr = ['123', '123']
+        result = np.array([123, 123], dtype=int)
+        for type in types:
+            msg = 'String conversion for %s' % type
+            assert_equal(np.array(nstr, dtype=type), result, err_msg=msg)
+
+    def test_void(self):
+        arr = np.array([], dtype='V')
+        assert_equal(arr.dtype.kind, 'V')
+
+    def test_zeros(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((13,), dtype=dt)
+            assert_equal(np.count_nonzero(d), 0)
+            # true for ieee floats
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='4i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4, (2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+
+    @dec.slow
+    def test_zeros_big(self):
+        # test big array as they might be allocated different by the system
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((30 * 1024**2,), dtype=dt)
+            assert_(not d.any())
+            # This test can fail on 32-bit systems due to insufficient
+            # contiguous memory. Deallocating the previous array increases the
+            # chance of success.
+            del(d)
+
+    def test_zeros_obj(self):
+        # test initialization from PyLong(0)
+        d = np.zeros((13,), dtype=object)
+        assert_array_equal(d, [0] * 13)
+        assert_equal(np.count_nonzero(d), 0)
+
+    def test_zeros_obj_obj(self):
+        d = np.zeros(10, dtype=[('k', object, 2)])
+        assert_array_equal(d['k'], 0)
+
+    def test_zeros_like_like_zeros(self):
+        # test zeros_like returns the same as zeros
+        for c in np.typecodes['All']:
+            if c == 'V':
+                continue
+            d = np.zeros((3,3), dtype=c)
+            assert_array_equal(np.zeros_like(d), d)
+            assert_equal(np.zeros_like(d).dtype, d.dtype)
+        # explicitly check some special cases
+        d = np.zeros((3,3), dtype='S5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='U5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='f4,f4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+    def test_empty_unicode(self):
+        # don't throw decode errors on garbage memory
+        for i in range(5, 100, 5):
+            d = np.empty(i, dtype='U')
+            str(d)
+
+    def test_sequence_non_homogenous(self):
+        assert_equal(np.array([4, 2**80]).dtype, np.object)
+        assert_equal(np.array([4, 2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80] * 3).dtype, np.object)
+        assert_equal(np.array([[1, 1],[1j, 1j]]).dtype, np.complex)
+        assert_equal(np.array([[1j, 1j],[1, 1]]).dtype, np.complex)
+        assert_equal(np.array([[1, 1, 1],[1, 1j, 1.], [1, 1, 1]]).dtype, np.complex)
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_sequence_long(self):
+        assert_equal(np.array([long(4), long(4)]).dtype, np.long)
+        assert_equal(np.array([long(4), 2**80]).dtype, np.object)
+        assert_equal(np.array([long(4), 2**80, long(4)]).dtype, np.object)
+        assert_equal(np.array([2**80, long(4)]).dtype, np.object)
+
+    def test_non_sequence_sequence(self):
+        """Should not segfault.
+
+        Class Fail breaks the sequence protocol for new style classes, i.e.,
+        those derived from object. Class Map is a mapping type indicated by
+        raising a ValueError. At some point we may raise a warning instead
+        of an error in the Fail case.
+
+        """
+        class Fail(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise ValueError()
+
+        class Map(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise KeyError()
+
+        a = np.array([Map()])
+        assert_(a.shape == (1,))
+        assert_(a.dtype == np.dtype(object))
+        assert_raises(ValueError, np.array, [Fail()])
+
+    def test_no_len_object_type(self):
+        # gh-5100, want object array from iterable object without len()
+        class Point2:
+            def __init__(self):
+                pass
+
+            def __getitem__(self, ind):
+                if ind in [0, 1]:
+                    return ind
+                else:
+                    raise IndexError()
+        d = np.array([Point2(), Point2(), Point2()])
+        assert_equal(d.dtype, np.dtype(object))
+
+    def test_false_len_sequence(self):
+        # gh-7264, segfault for this example
+        class C:
+            def __getitem__(self, i):
+                raise IndexError
+            def __len__(self):
+                return 42
+
+        assert_raises(ValueError, np.array, C()) # segfault?
+
+    def test_failed_len_sequence(self):
+        # gh-7393
+        class A(object):
+            def __init__(self, data):
+                self._data = data
+            def __getitem__(self, item):
+                return type(self)(self._data[item])
+            def __len__(self):
+                return len(self._data)
+
+        # len(d) should give 3, but len(d[0]) will fail
+        d = A([1,2,3])
+        assert_equal(len(np.array(d)), 3)
+
+
+class TestStructured(TestCase):
+    def test_subarray_field_access(self):
+        a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
+        a['a'] = np.arange(60).reshape(3, 5, 2, 2)
+
+        # Since the subarray is always in C-order, a transpose
+        # does not swap the subarray:
+        assert_array_equal(a.T['a'], a['a'].transpose(1, 0, 2, 3))
+
+        # In Fortran order, the subarray gets appended
+        # like in all other cases, not prepended as a special case
+        b = a.copy(order='F')
+        assert_equal(a['a'].shape, b['a'].shape)
+        assert_equal(a.T['a'].shape, a.T.copy()['a'].shape)
+
+    def test_subarray_comparison(self):
+        # Check that comparisons between record arrays with
+        # multi-dimensional field types work properly
+        a = np.rec.fromrecords(
+            [([1, 2, 3], 'a', [[1, 2], [3, 4]]), ([3, 3, 3], 'b', [[0, 0], [0, 0]])],
+            dtype=[('a', ('f4', 3)), ('b', np.object), ('c', ('i4', (2, 2)))])
+        b = a.copy()
+        assert_equal(a == b, [True, True])
+        assert_equal(a != b, [False, False])
+        b[1].b = 'c'
+        assert_equal(a == b, [True, False])
+        assert_equal(a != b, [False, True])
+        for i in range(3):
+            b[0].a = a[0].a
+            b[0].a[i] = 5
+            assert_equal(a == b, [False, False])
+            assert_equal(a != b, [True, True])
+        for i in range(2):
+            for j in range(2):
+                b = a.copy()
+                b[0].c[i, j] = 10
+                assert_equal(a == b, [False, True])
+                assert_equal(a != b, [True, False])
+
+        # Check that broadcasting with a subarray works
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8')])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8')])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8', (1,))])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8', (1,))])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))])
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that broadcasting Fortran-style arrays with a subarray work
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))], order='F')
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that incompatible sub-array shapes don't result to broadcasting
+        x = np.zeros((1,), dtype=[('a', ('f4', (1, 2))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        # Check that structured arrays that are different only in
+        # byte-order work
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i8'), ('b', '<f8')])
+        b = np.array([(5, 43), (10, 1)], dtype=[('a', '<i8'), ('b', '>f8')])
+        assert_equal(a == b, [False, True])
+
+    def test_casting(self):
+        # Check that casting a structured array to change its byte order
+        # works
+        a = np.array([(1,)], dtype=[('a', '<i4')])
+        assert_(np.can_cast(a.dtype, [('a', '>i4')], casting='unsafe'))
+        b = a.astype([('a', '>i4')])
+        assert_equal(b, a.byteswap().newbyteorder())
+        assert_equal(a['a'][0], b['a'][0])
+
+        # Check that equality comparison works on structured arrays if
+        # they are 'equiv'-castable
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', '<f8')])
+        b = np.array([(42, 5), (1, 10)], dtype=[('b', '>f8'), ('a', '<i4')])
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        assert_equal(a == b, [True, True])
+
+        # Check that 'equiv' casting can reorder fields and change byte
+        # order
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        c = a.astype(b.dtype, casting='equiv')
+        assert_equal(a == c, [True, True])
+
+        # Check that 'safe' casting can change byte order and up-cast
+        # fields
+        t = [('a', '<i8'), ('b', '>f8')]
+        assert_(np.can_cast(a.dtype, t, casting='safe'))
+        c = a.astype(t, casting='safe')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that 'same_kind' casting can change byte order and
+        # change field widths within a "kind"
+        t = [('a', '<i4'), ('b', '>f4')]
+        assert_(np.can_cast(a.dtype, t, casting='same_kind'))
+        c = a.astype(t, casting='same_kind')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that casting fails if the casting rule should fail on
+        # any of the fields
+        t = [('a', '>i8'), ('b', '<f4')]
+        assert_(not np.can_cast(a.dtype, t, casting='safe'))
+        assert_raises(TypeError, a.astype, t, casting='safe')
+        t = [('a', '>i2'), ('b', '<f8')]
+        assert_(not np.can_cast(a.dtype, t, casting='equiv'))
+        assert_raises(TypeError, a.astype, t, casting='equiv')
+        t = [('a', '>i8'), ('b', '<i2')]
+        assert_(not np.can_cast(a.dtype, t, casting='same_kind'))
+        assert_raises(TypeError, a.astype, t, casting='same_kind')
+        assert_(not np.can_cast(a.dtype, b.dtype, casting='no'))
+        assert_raises(TypeError, a.astype, b.dtype, casting='no')
+
+        # Check that non-'unsafe' casting can't change the set of field names
+        for casting in ['no', 'safe', 'equiv', 'same_kind']:
+            t = [('a', '>i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+            t = [('a', '>i4'), ('b', '<f8'), ('c', 'i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+
+    def test_objview(self):
+        # https://github.com/numpy/numpy/issues/3286
+        a = np.array([], dtype=[('a', 'f'), ('b', 'f'), ('c', 'O')])
+        a[['a', 'b']]  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3253
+        dat2 = np.zeros(3, [('A', 'i'), ('B', '|O')])
+        dat2[['B', 'A']]  # TypeError?
+
+    def test_setfield(self):
+        # https://github.com/numpy/numpy/issues/3126
+        struct_dt = np.dtype([('elem', 'i4', 5),])
+        dt = np.dtype([('field', 'i4', 10),('struct', struct_dt)])
+        x = np.zeros(1, dt)
+        x[0]['field'] = np.ones(10, dtype='i4')
+        x[0]['struct'] = np.ones(1, dtype=struct_dt)
+        assert_equal(x[0]['field'], np.ones(10, dtype='i4'))
+
+    def test_setfield_object(self):
+        # make sure object field assignment with ndarray value
+        # on void scalar mimics setitem behavior
+        b = np.zeros(1, dtype=[('x', 'O')])
+        # next line should work identically to b['x'][0] = np.arange(3)
+        b[0]['x'] = np.arange(3)
+        assert_equal(b[0]['x'], np.arange(3))
+
+        # check that broadcasting check still works
+        c = np.zeros(1, dtype=[('x', 'O', 5)])
+
+        def testassign():
+            c[0]['x'] = np.arange(3)
+
+        assert_raises(ValueError, testassign)
+
+
+class TestBool(TestCase):
+    def test_test_interning(self):
+        a0 = np.bool_(0)
+        b0 = np.bool_(False)
+        self.assertTrue(a0 is b0)
+        a1 = np.bool_(1)
+        b1 = np.bool_(True)
+        self.assertTrue(a1 is b1)
+        self.assertTrue(np.array([True])[0] is a1)
+        self.assertTrue(np.array(True)[()] is a1)
+
+    def test_sum(self):
+        d = np.ones(101, dtype=np.bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+        d = np.frombuffer(b'\xff\xff' * 100, dtype=bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+    def check_count_nonzero(self, power, length):
+        powers = [2 ** i for i in range(length)]
+        for i in range(2**power):
+            l = [(i & x) != 0 for x in powers]
+            a = np.array(l, dtype=np.bool)
+            c = builtins.sum(l)
+            self.assertEqual(np.count_nonzero(a), c)
+            av = a.view(np.uint8)
+            av *= 3
+            self.assertEqual(np.count_nonzero(a), c)
+            av *= 4
+            self.assertEqual(np.count_nonzero(a), c)
+            av[av != 0] = 0xFF
+            self.assertEqual(np.count_nonzero(a), c)
+
+    def test_count_nonzero(self):
+        # check all 12 bit combinations in a length 17 array
+        # covers most cases of the 16 byte unrolled code
+        self.check_count_nonzero(12, 17)
+
+    @dec.slow
+    def test_count_nonzero_all(self):
+        # check all combinations in a length 17 array
+        # covers all cases of the 16 byte unrolled code
+        self.check_count_nonzero(17, 17)
+
+    def test_count_nonzero_unaligned(self):
+        # prevent mistakes as e.g. gh-4060
+        for o in range(7):
+            a = np.zeros((18,), dtype=np.bool)[o+1:]
+            a[:o] = True
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+            a = np.ones((18,), dtype=np.bool)[o+1:]
+            a[:o] = False
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+
+
+class TestMethods(TestCase):
+    def test_compress(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = arr.compress([0, 1, 0, 1, 0], axis=1)
+        assert_equal(out, tgt)
+
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=1)
+        assert_equal(out, tgt)
+
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1])
+        assert_equal(out, 1)
+
+    def test_choose(self):
+        x = 2*np.ones((3,), dtype=int)
+        y = 3*np.ones((3,), dtype=int)
+        x2 = 2*np.ones((2, 3), dtype=int)
+        y2 = 3*np.ones((2, 3), dtype=int)
+        ind = np.array([0, 0, 1])
+
+        A = ind.choose((x, y))
+        assert_equal(A, [2, 2, 3])
+
+        A = ind.choose((x2, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+        A = ind.choose((x, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_prod(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, a.prod)
+                self.assertRaises(ArithmeticError, a2.prod, axis=1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+    def test_repeat(self):
+        m = np.array([1, 2, 3, 4, 5, 6])
+        m_rect = m.reshape((2, 3))
+
+        A = m.repeat([1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+        A = m.repeat(2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+        A = m_rect.repeat([2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat([1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+        A = m_rect.repeat(2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat(2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+    def test_reshape(self):
+        arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
+
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(arr.reshape(2, 6), tgt)
+
+        tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
+        assert_equal(arr.reshape(3, 4), tgt)
+
+        tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
+        assert_equal(arr.reshape((3, 4), order='F'), tgt)
+
+        tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
+        assert_equal(arr.T.reshape((3, 4), order='C'), tgt)
+
+    def test_round(self):
+        def check_round(arr, expected, *round_args):
+            assert_equal(arr.round(*round_args), expected)
+            # With output array
+            out = np.zeros_like(arr)
+            res = arr.round(*round_args, out=out)
+            assert_equal(out, expected)
+            assert_equal(out, res)
+
+        check_round(np.array([1.2, 1.5]), [1, 2])
+        check_round(np.array(1.5), 2)
+        check_round(np.array([12.2, 15.5]), [10, 20], -1)
+        check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1)
+        # Complex rounding
+        check_round(np.array([4.5 + 1.5j]), [4 + 2j])
+        check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1)
+
+    def test_squeeze(self):
+        a = np.array([[[1], [2], [3]]])
+        assert_equal(a.squeeze(), [1, 2, 3])
+        assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]])
+        assert_raises(ValueError, a.squeeze, axis=(1,))
+        assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]])
+
+    def test_transpose(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(a.transpose(), [[1, 3], [2, 4]])
+        self.assertRaises(ValueError, lambda: a.transpose(0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 1, 2))
+
+    def test_sort(self):
+        # test ordering for floats and complex containing nans. It is only
+        # necessary to check the less-than comparison, so sorts that
+        # only follow the insertion sort path are sufficient. We only
+        # test doubles and complex doubles as the logic is the same.
+
+        # check doubles
+        msg = "Test real sort order with nans"
+        a = np.array([np.nan, 1, 0])
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+        # check complex
+        msg = "Test complex sort order with nans"
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0]
+        a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0]
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+
+        # all c scalar sorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test complex sorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, real part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, imag part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+
+        # test sorting of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                c = arr.copy()
+                c.sort()
+                msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
+                assert_equal(c, arr, msg)
+
+        # test string sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "string sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test unicode sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test object array sorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test record array sorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test datetime64 sorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test timedelta64 sorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific sorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 0], [3, 2]])
+        c = np.array([[2, 3], [0, 1]])
+        d = a.copy()
+        d.sort(axis=0)
+        assert_equal(d, b, "test sort with axis=0")
+        d = a.copy()
+        d.sort(axis=1)
+        assert_equal(d, c, "test sort with axis=1")
+        d = a.copy()
+        d.sort()
+        assert_equal(d, c, "test sort with default axis")
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array sort with axis={0}'.format(axis)
+            assert_equal(np.sort(a, axis=axis), a, msg)
+        msg = 'test empty array sort with axis=None'
+        assert_equal(np.sort(a, axis=None), a.ravel(), msg)
+
+    def test_copy(self):
+        def assert_fortran(arr):
+            assert_(arr.flags.fortran)
+            assert_(arr.flags.f_contiguous)
+            assert_(not arr.flags.c_contiguous)
+
+        def assert_c(arr):
+            assert_(not arr.flags.fortran)
+            assert_(not arr.flags.f_contiguous)
+            assert_(arr.flags.c_contiguous)
+
+        a = np.empty((2, 2), order='F')
+        # Test copying a Fortran array
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_fortran(a.copy('A'))
+
+        # Now test starting with a C array.
+        a = np.empty((2, 2), order='C')
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_c(a.copy('A'))
+
+    def test_sort_order(self):
+        # Test sorting an array with fields
+        x1 = np.array([21, 32, 14])
+        x2 = np.array(['my', 'first', 'name'])
+        x3 = np.array([3.1, 4.5, 6.2])
+        r = np.rec.fromarrays([x1, x2, x3], names='id,word,number')
+
+        r.sort(order=['id'])
+        assert_equal(r.id, np.array([14, 21, 32]))
+        assert_equal(r.word, np.array(['name', 'my', 'first']))
+        assert_equal(r.number, np.array([6.2, 3.1, 4.5]))
+
+        r.sort(order=['word'])
+        assert_equal(r.id, np.array([32, 21, 14]))
+        assert_equal(r.word, np.array(['first', 'my', 'name']))
+        assert_equal(r.number, np.array([4.5, 3.1, 6.2]))
+
+        r.sort(order=['number'])
+        assert_equal(r.id, np.array([21, 32, 14]))
+        assert_equal(r.word, np.array(['my', 'first', 'name']))
+        assert_equal(r.number, np.array([3.1, 4.5, 6.2]))
+
+        if sys.byteorder == 'little':
+            strtype = '>i2'
+        else:
+            strtype = '<i2'
+        mydtype = [('name', strchar + '5'), ('col2', strtype)]
+        r = np.array([('a', 1), ('b', 255), ('c', 3), ('d', 258)],
+                     dtype=mydtype)
+        r.sort(order='col2')
+        assert_equal(r['col2'], [1, 3, 255, 258])
+        assert_equal(r, np.array([('a', 1), ('c', 3), ('b', 255), ('d', 258)],
+                                 dtype=mydtype))
+
+    def test_argsort(self):
+        # all c scalar argsorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), a, msg)
+            assert_equal(b.copy().argsort(kind=kind), b, msg)
+
+        # test complex argsorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+
+        # test argsort of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                msg = 'byte-swapped complex argsort, dtype={0}'.format(dt)
+                assert_equal(arr.argsort(),
+                             np.arange(len(arr), dtype=np.intp), msg)
+
+        # test string argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "string argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test unicode argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test object array argsorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "object argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test structured array argsorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "structured array argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test datetime64 argsorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test timedelta64 argsorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific argsorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 1], [0, 0]])
+        c = np.array([[1, 0], [1, 0]])
+        assert_equal(a.copy().argsort(axis=0), b)
+        assert_equal(a.copy().argsort(axis=1), c)
+        assert_equal(a.copy().argsort(), c)
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argsort with axis={0}'.format(axis)
+            assert_equal(np.argsort(a, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argsort with axis=None'
+        assert_equal(np.argsort(a, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+        # check that stable argsorts are stable
+        r = np.arange(100)
+        # scalars
+        a = np.zeros(100)
+        assert_equal(a.argsort(kind='m'), r)
+        # complex
+        a = np.zeros(100, dtype=np.complex)
+        assert_equal(a.argsort(kind='m'), r)
+        # string
+        a = np.array(['aaaaaaaaa' for i in range(100)])
+        assert_equal(a.argsort(kind='m'), r)
+        # unicode
+        a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode)
+        assert_equal(a.argsort(kind='m'), r)
+
+    def test_sort_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.sort, kind=k)
+        assert_raises(ValueError, d.argsort, kind=k)
+
+    def test_searchsorted(self):
+        # test for floats and complex containing nans. The logic is the
+        # same for all float types so only test double types for now.
+        # The search sorted routines use the compare functions for the
+        # array type, so this checks if that is consistent with the sort
+        # order.
+
+        # check double
+        a = np.array([0, 1, np.nan])
+        msg = "Test real searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(3), msg)
+        msg = "Test real searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 4), msg)
+        # check double complex
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan]
+        a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan]
+        msg = "Test complex searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(9), msg)
+        msg = "Test complex searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 10), msg)
+        msg = "Test searchsorted with little endian, side='l'"
+        a = np.array([0, 128], dtype='<i4')
+        b = a.searchsorted(np.array(128, dtype='<i4'))
+        assert_equal(b, 1, msg)
+        msg = "Test searchsorted with big endian, side='l'"
+        a = np.array([0, 128], dtype='>i4')
+        b = a.searchsorted(np.array(128, dtype='>i4'))
+        assert_equal(b, 1, msg)
+
+        # Check 0 elements
+        a = np.ones(0)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 0])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 0, 0])
+        a = np.ones(1)
+        # Check 1 element
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 1])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 1, 1])
+        # Check all elements equal
+        a = np.ones(2)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 2])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 2, 2])
+
+        # Test searching unaligned array
+        a = np.arange(10)
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        unaligned[:] = a
+        # Test searching unaligned array
+        b = unaligned.searchsorted(a, 'l')
+        assert_equal(b, a)
+        b = unaligned.searchsorted(a, 'r')
+        assert_equal(b, a + 1)
+        # Test searching for unaligned keys
+        b = a.searchsorted(unaligned, 'l')
+        assert_equal(b, a)
+        b = a.searchsorted(unaligned, 'r')
+        assert_equal(b, a + 1)
+
+        # Test smart resetting of binsearch indices
+        a = np.arange(5)
+        b = a.searchsorted([6, 5, 4], 'l')
+        assert_equal(b, [5, 5, 4])
+        b = a.searchsorted([6, 5, 4], 'r')
+        assert_equal(b, [5, 5, 5])
+
+        # Test all type specific binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.arange(2, dtype=dt)
+                out = np.arange(2)
+            else:
+                a = np.arange(0, 5, dtype=dt)
+                out = np.arange(5)
+            b = a.searchsorted(a, 'l')
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r')
+            assert_equal(b, out + 1)
+
+    def test_searchsorted_unicode(self):
+        # Test searchsorted on unicode strings.
+
+        # 1.6.1 contained a string length miscalculation in
+        # arraytypes.c.src:UNICODE_compare() which manifested as
+        # incorrect/inconsistent results from searchsorted.
+        a = np.array(['P:\\20x_dapi_cy3\\20x_dapi_cy3_20100185_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100186_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100187_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100189_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100190_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100191_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100192_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100193_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100194_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100195_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100196_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
+                     dtype=np.unicode)
+        ind = np.arange(len(a))
+        assert_equal([a.searchsorted(v, 'left') for v in a], ind)
+        assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
+        assert_equal([a.searchsorted(a[i], 'left') for i in ind], ind)
+        assert_equal([a.searchsorted(a[i], 'right') for i in ind], ind + 1)
+
+    def test_searchsorted_with_sorter(self):
+        a = np.array([5, 2, 1, 3, 4])
+        s = np.argsort(a)
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=(1, (2, 3)))
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=[1.1])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4, 5, 6])
+
+        # bounds check
+        assert_raises(ValueError, np.searchsorted, a, 4, sorter=[0, 1, 2, 3, 5])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[-1, 0, 1, 2, 3])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[4, 0, -1, 2, 3])
+
+        a = np.random.rand(300)
+        s = a.argsort()
+        b = np.sort(a)
+        k = np.linspace(0, 1, 20)
+        assert_equal(b.searchsorted(k), a.searchsorted(k, sorter=s))
+
+        a = np.array([0, 1, 2, 3, 5]*20)
+        s = a.argsort()
+        k = [0, 1, 2, 3, 5]
+        expected = [0, 20, 40, 60, 80]
+        assert_equal(a.searchsorted(k, side='l', sorter=s), expected)
+        expected = [20, 40, 60, 80, 100]
+        assert_equal(a.searchsorted(k, side='r', sorter=s), expected)
+
+        # Test searching unaligned array
+        keys = np.arange(10)
+        a = keys.copy()
+        np.random.shuffle(s)
+        s = a.argsort()
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        # Test searching unaligned array
+        unaligned[:] = a
+        b = unaligned.searchsorted(keys, 'l', s)
+        assert_equal(b, keys)
+        b = unaligned.searchsorted(keys, 'r', s)
+        assert_equal(b, keys + 1)
+        # Test searching for unaligned keys
+        unaligned[:] = keys
+        b = a.searchsorted(unaligned, 'l', s)
+        assert_equal(b, keys)
+        b = a.searchsorted(unaligned, 'r', s)
+        assert_equal(b, keys + 1)
+
+        # Test all type specific indirect binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.array([1, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([1, 0], dtype=np.int16)
+                out = np.array([1, 0])
+            else:
+                a = np.array([3, 4, 1, 2, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([4, 2, 3, 0, 1], dtype=np.int16)
+                out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+            b = a.searchsorted(a, 'l', s)
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r', s)
+            assert_equal(b, out + 1)
+
+        # Test non-contiguous sorter array
+        a = np.array([3, 4, 1, 2, 0])
+        srt = np.empty((10,), dtype=np.intp)
+        srt[1::2] = -1
+        srt[::2] = [4, 2, 3, 0, 1]
+        s = srt[::2]
+        out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+        b = a.searchsorted(a, 'l', s)
+        assert_equal(b, out)
+        b = a.searchsorted(a, 'r', s)
+        assert_equal(b, out + 1)
+
+    def test_searchsorted_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        s = np.arange(5).view(A)
+        assert_(not isinstance(a.searchsorted(b, 'l'), A))
+        assert_(not isinstance(a.searchsorted(b, 'r'), A))
+        assert_(not isinstance(a.searchsorted(b, 'l', s), A))
+        assert_(not isinstance(a.searchsorted(b, 'r', s), A))
+
+    def test_argpartition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.argpartition, 10)
+        assert_raises(ValueError, d.argpartition, -11)
+        # Test also for generic type argpartition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.argpartition, 10)
+        assert_raises(ValueError, d_obj.argpartition, -11)
+
+    def test_partition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.partition, 10)
+        assert_raises(ValueError, d.partition, -11)
+        # Test also for generic type partition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.partition, 10)
+        assert_raises(ValueError, d_obj.partition, -11)
+
+    def test_partition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array partition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis), a, msg)
+        msg = 'test empty array partition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None), a.ravel(), msg)
+
+    def test_argpartition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argpartition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argpartition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+    def test_partition(self):
+        d = np.arange(10)
+        assert_raises(TypeError, np.partition, d, 2, kind=1)
+        assert_raises(ValueError, np.partition, d, 2, kind="nonsense")
+        assert_raises(ValueError, np.argpartition, d, 2, kind="nonsense")
+        assert_raises(ValueError, d.partition, 2, axis=0, kind="nonsense")
+        assert_raises(ValueError, d.argpartition, 2, axis=0, kind="nonsense")
+        for k in ("introselect",):
+            d = np.array([])
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(np.argpartition(d, 0, kind=k), d)
+            d = np.ones(1)
+            assert_array_equal(np.partition(d, 0, kind=k)[0], d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # kth not modified
+            kth = np.array([30, 15, 5])
+            okth = kth.copy()
+            np.partition(np.arange(40), kth)
+            assert_array_equal(kth, okth)
+
+            for r in ([2, 1], [1, 2], [1, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            for r in ([3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1],
+                      [1, 1, 1], [1, 2, 2], [2, 2, 1], [1, 2, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(np.partition(d, 2, kind=k)[2], tgt[2])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                assert_array_equal(d[np.argpartition(d, 2, kind=k)],
+                                   np.partition(d, 2, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            d = np.ones(50)
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # sorted
+            d = np.arange(49)
+            self.assertEqual(np.partition(d, 5, kind=k)[5], 5)
+            self.assertEqual(np.partition(d, 15, kind=k)[15], 15)
+            assert_array_equal(d[np.argpartition(d, 5, kind=k)],
+                               np.partition(d, 5, kind=k))
+            assert_array_equal(d[np.argpartition(d, 15, kind=k)],
+                               np.partition(d, 15, kind=k))
+
+            # rsorted
+            d = np.arange(47)[::-1]
+            self.assertEqual(np.partition(d, 6, kind=k)[6], 6)
+            self.assertEqual(np.partition(d, 16, kind=k)[16], 16)
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+
+            assert_array_equal(np.partition(d, -6, kind=k),
+                               np.partition(d, 41, kind=k))
+            assert_array_equal(np.partition(d, -16, kind=k),
+                               np.partition(d, 31, kind=k))
+            assert_array_equal(d[np.argpartition(d, -6, kind=k)],
+                               np.partition(d, 41, kind=k))
+
+            # median of 3 killer, O(n^2) on pure median 3 pivot quickselect
+            # exercises the median of median of 5 code used to keep O(n)
+            d = np.arange(1000000)
+            x = np.roll(d, d.size // 2)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+            d = np.arange(1000001)
+            x = np.roll(d, d.size // 2 + 1)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+
+            # max
+            d = np.ones(10)
+            d[1] = 4
+            assert_equal(np.partition(d, (2, -1))[-1], 4)
+            assert_equal(np.partition(d, (2, -1))[2], 1)
+            assert_equal(d[np.argpartition(d, (2, -1))][-1], 4)
+            assert_equal(d[np.argpartition(d, (2, -1))][2], 1)
+            d[1] = np.nan
+            assert_(np.isnan(d[np.argpartition(d, (2, -1))][-1]))
+            assert_(np.isnan(np.partition(d, (2, -1))[-1]))
+
+            # equal elements
+            d = np.arange(47) % 7
+            tgt = np.sort(np.arange(47) % 7)
+            np.random.shuffle(d)
+            for i in range(d.size):
+                self.assertEqual(np.partition(d, i, kind=k)[i], tgt[i])
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+            for i in range(d.size):
+                d[i:].partition(0, kind=k)
+            assert_array_equal(d, tgt)
+
+            d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                          7, 7, 7, 7, 7, 9])
+            kth = [0, 3, 19, 20]
+            assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
+            assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
+
+            d = np.array([2, 1])
+            d.partition(0, kind=k)
+            assert_raises(ValueError, d.partition, 2)
+            assert_raises(ValueError, d.partition, 3, axis=1)
+            assert_raises(ValueError, np.partition, d, 2)
+            assert_raises(ValueError, np.partition, d, 2, axis=1)
+            assert_raises(ValueError, d.argpartition, 2)
+            assert_raises(ValueError, d.argpartition, 3, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 2)
+            assert_raises(ValueError, np.argpartition, d, 2, axis=1)
+            d = np.arange(10).reshape((2, 5))
+            d.partition(1, axis=0, kind=k)
+            d.partition(4, axis=1, kind=k)
+            np.partition(d, 1, axis=0, kind=k)
+            np.partition(d, 4, axis=1, kind=k)
+            np.partition(d, 1, axis=None, kind=k)
+            np.partition(d, 9, axis=None, kind=k)
+            d.argpartition(1, axis=0, kind=k)
+            d.argpartition(4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=0, kind=k)
+            np.argpartition(d, 4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=None, kind=k)
+            np.argpartition(d, 9, axis=None, kind=k)
+            assert_raises(ValueError, d.partition, 2, axis=0)
+            assert_raises(ValueError, d.partition, 11, axis=1)
+            assert_raises(TypeError, d.partition, 2, axis=None)
+            assert_raises(ValueError, np.partition, d, 9, axis=1)
+            assert_raises(ValueError, np.partition, d, 11, axis=None)
+            assert_raises(ValueError, d.argpartition, 2, axis=0)
+            assert_raises(ValueError, d.argpartition, 11, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 9, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 11, axis=None)
+
+            td = [(dt, s) for dt in [np.int32, np.float32, np.complex64]
+                  for s in (9, 16)]
+            for dt, s in td:
+                aae = assert_array_equal
+                at = self.assertTrue
+
+                d = np.arange(s, dtype=dt)
+                np.random.shuffle(d)
+                d1 = np.tile(np.arange(s, dtype=dt), (4, 1))
+                map(np.random.shuffle, d1)
+                d0 = np.transpose(d1)
+                for i in range(d.size):
+                    p = np.partition(d, i, kind=k)
+                    self.assertEqual(p[i], i)
+                    # all before are smaller
+                    assert_array_less(p[:i], p[i])
+                    # all after are larger
+                    assert_array_less(p[i], p[i + 1:])
+                    aae(p, d[np.argpartition(d, i, kind=k)])
+
+                    p = np.partition(d1, i, axis=1, kind=k)
+                    aae(p[:, i], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:, :i].T <= p[:, i]).all(),
+                       msg="%d: %r <= %r" % (i, p[:, i], p[:, :i].T))
+                    at((p[:, i + 1:].T > p[:, i]).all(),
+                       msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T))
+                    aae(p, d1[np.arange(d1.shape[0])[:, None],
+                        np.argpartition(d1, i, axis=1, kind=k)])
+
+                    p = np.partition(d0, i, axis=0, kind=k)
+                    aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:i, :] <= p[i, :]).all(),
+                       msg="%d: %r <= %r" % (i, p[i, :], p[:i, :]))
+                    at((p[i + 1:, :] > p[i, :]).all(),
+                       msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:]))
+                    aae(p, d0[np.argpartition(d0, i, axis=0, kind=k),
+                        np.arange(d0.shape[1])[None, :]])
+
+                    # check inplace
+                    dc = d.copy()
+                    dc.partition(i, kind=k)
+                    assert_equal(dc, np.partition(d, i, kind=k))
+                    dc = d0.copy()
+                    dc.partition(i, axis=0, kind=k)
+                    assert_equal(dc, np.partition(d0, i, axis=0, kind=k))
+                    dc = d1.copy()
+                    dc.partition(i, axis=1, kind=k)
+                    assert_equal(dc, np.partition(d1, i, axis=1, kind=k))
+
+    def assert_partitioned(self, d, kth):
+        prev = 0
+        for k in np.sort(kth):
+            assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k)
+            assert_((d[k:] >= d[k]).all(),
+                    msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k]))
+            prev = k + 1
+
+    def test_partition_iterative(self):
+            d = np.arange(17)
+            kth = (0, 1, 2, 429, 231)
+            assert_raises(ValueError, d.partition, kth)
+            assert_raises(ValueError, d.argpartition, kth)
+            d = np.arange(10).reshape((2, 5))
+            assert_raises(ValueError, d.partition, kth, axis=0)
+            assert_raises(ValueError, d.partition, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=None)
+
+            d = np.array([3, 4, 2, 1])
+            p = np.partition(d, (0, 3))
+            self.assert_partitioned(p, (0, 3))
+            self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3))
+
+            assert_array_equal(p, np.partition(d, (-3, -1)))
+            assert_array_equal(p, d[np.argpartition(d, (-3, -1))])
+
+            d = np.arange(17)
+            np.random.shuffle(d)
+            d.partition(range(d.size))
+            assert_array_equal(np.arange(17), d)
+            np.random.shuffle(d)
+            assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))])
+
+            # test unsorted kth
+            d = np.arange(17)
+            np.random.shuffle(d)
+            keys = np.array([1, 3, 8, -2])
+            np.random.shuffle(d)
+            p = np.partition(d, keys)
+            self.assert_partitioned(p, keys)
+            p = d[np.argpartition(d, keys)]
+            self.assert_partitioned(p, keys)
+            np.random.shuffle(keys)
+            assert_array_equal(np.partition(d, keys), p)
+            assert_array_equal(d[np.argpartition(d, keys)], p)
+
+            # equal kth
+            d = np.arange(20)[::-1]
+            self.assert_partitioned(np.partition(d, [5]*4), [5])
+            self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]),
+                                    [5]*4 + [6, 13])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])],
+                                    [5]*4 + [6, 13])
+
+            d = np.arange(12)
+            np.random.shuffle(d)
+            d1 = np.tile(np.arange(12), (4, 1))
+            map(np.random.shuffle, d1)
+            d0 = np.transpose(d1)
+
+            kth = (1, 6, 7, -1)
+            p = np.partition(d1, kth, axis=1)
+            pa = d1[np.arange(d1.shape[0])[:, None],
+                    d1.argpartition(kth, axis=1)]
+            assert_array_equal(p, pa)
+            for i in range(d1.shape[0]):
+                self.assert_partitioned(p[i,:], kth)
+            p = np.partition(d0, kth, axis=0)
+            pa = d0[np.argpartition(d0, kth, axis=0),
+                    np.arange(d0.shape[1])[None,:]]
+            assert_array_equal(p, pa)
+            for i in range(d0.shape[1]):
+                self.assert_partitioned(p[:, i], kth)
+
+    def test_partition_cdtype(self):
+        d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+                   ('Lancelot', 1.9, 38)],
+                  dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+        tgt = np.sort(d, order=['age', 'height'])
+        assert_array_equal(np.partition(d, range(d.size),
+                                        order=['age', 'height']),
+                           tgt)
+        assert_array_equal(d[np.argpartition(d, range(d.size),
+                                             order=['age', 'height'])],
+                           tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k, order=['age', 'height'])[k],
+                        tgt[k])
+            assert_equal(d[np.argpartition(d, k, order=['age', 'height'])][k],
+                         tgt[k])
+
+        d = np.array(['Galahad', 'Arthur', 'zebra', 'Lancelot'])
+        tgt = np.sort(d)
+        assert_array_equal(np.partition(d, range(d.size)), tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k)[k], tgt[k])
+            assert_equal(d[np.argpartition(d, k)][k], tgt[k])
+
+    def test_partition_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.partition, 2, kind=k)
+        assert_raises(ValueError, d.argpartition, 2, kind=k)
+
+    def test_partition_fuzz(self):
+        # a few rounds of random data testing
+        for j in range(10, 30):
+            for i in range(1, j - 2):
+                d = np.arange(j)
+                np.random.shuffle(d)
+                d = d % np.random.randint(2, 30)
+                idx = np.random.randint(d.size)
+                kth = [0, idx, i, i + 1]
+                tgt = np.sort(d)[kth]
+                assert_array_equal(np.partition(d, kth)[kth], tgt,
+                                   err_msg="data: %r\n kth: %r" % (d, kth))
+
+    def test_argpartition_gh5524(self):
+        #  A test for functionality of argpartition on lists.
+        d = [6,7,3,2,9,0]
+        p = np.argpartition(d,1)
+        self.assert_partitioned(np.array(d)[p],[1])
+
+    def test_flatten(self):
+        x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
+        x1 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], np.int32)
+        y0 = np.array([1, 2, 3, 4, 5, 6], np.int32)
+        y0f = np.array([1, 4, 2, 5, 3, 6], np.int32)
+        y1 = np.array([1, 2, 3, 4, 5, 6, 7, 8], np.int32)
+        y1f = np.array([1, 5, 3, 7, 2, 6, 4, 8], np.int32)
+        assert_equal(x0.flatten(), y0)
+        assert_equal(x0.flatten('F'), y0f)
+        assert_equal(x0.flatten('F'), x0.T.flatten())
+        assert_equal(x1.flatten(), y1)
+        assert_equal(x1.flatten('F'), y1f)
+        assert_equal(x1.flatten('F'), x1.T.flatten())
+
+    def test_dot(self):
+        a = np.array([[1, 0], [0, 1]])
+        b = np.array([[0, 1], [1, 0]])
+        c = np.array([[9, 1], [1, -9]])
+        d = np.arange(24).reshape(4, 6)
+        ddt = np.array(
+            [[  55,  145,  235,  325],
+             [ 145,  451,  757, 1063],
+             [ 235,  757, 1279, 1801],
+             [ 325, 1063, 1801, 2539]]
+        )
+        dtd = np.array(
+            [[504, 540, 576, 612, 648, 684],
+             [540, 580, 620, 660, 700, 740],
+             [576, 620, 664, 708, 752, 796],
+             [612, 660, 708, 756, 804, 852],
+             [648, 700, 752, 804, 856, 908],
+             [684, 740, 796, 852, 908, 964]]
+        )
+
+
+        # gemm vs syrk optimizations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            assert_equal(np.dot(eaf, eaf), eaf)
+            assert_equal(np.dot(eaf.T, eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T.copy()), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf.T.copy()), eaf)
+
+        # syrk validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            ebf = b.astype(et)
+            assert_equal(np.dot(ebf, ebf), eaf)
+            assert_equal(np.dot(ebf.T, ebf), eaf)
+            assert_equal(np.dot(ebf, ebf.T), eaf)
+            assert_equal(np.dot(ebf.T, ebf.T), eaf)
+
+        # syrk - different shape, stride, and view validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            assert_equal(
+                np.dot(edf[::-1, :], edf.T),
+                np.dot(edf[::-1, :].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:, ::-1], edf.T),
+                np.dot(edf[:, ::-1].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[::-1, :].T),
+                np.dot(edf, edf[::-1, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[:, ::-1].T),
+                np.dot(edf, edf[:, ::-1].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:edf.shape[0] // 2, :], edf[::2, :].T),
+                np.dot(edf[:edf.shape[0] // 2, :].copy(), edf[::2, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[::2, :], edf[:edf.shape[0] // 2, :].T),
+                np.dot(edf[::2, :].copy(), edf[:edf.shape[0] // 2, :].T.copy())
+            )
+
+        # syrk - different shape
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            eddtf = ddt.astype(et)
+            edtdf = dtd.astype(et)
+            assert_equal(np.dot(edf, edf.T), eddtf)
+            assert_equal(np.dot(edf.T, edf), edtdf)
+
+        # function versus methods
+        assert_equal(np.dot(a, b), a.dot(b))
+        assert_equal(np.dot(np.dot(a, b), c), a.dot(b).dot(c))
+
+        # test passing in an output array
+        c = np.zeros_like(a)
+        a.dot(b, c)
+        assert_equal(c, np.dot(a, b))
+
+        # test keyword args
+        c = np.zeros_like(a)
+        a.dot(b=b, out=c)
+        assert_equal(c, np.dot(a, b))
+
+    def test_dot_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        b = B()
+        c = np.array([[1]])
+
+        assert_equal(np.dot(a, b), "A")
+        assert_equal(c.dot(a), "A")
+        assert_raises(TypeError, np.dot, b, c)
+        assert_raises(TypeError, c.dot, b)
+
+    def test_dot_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.dot, c, A)
+        assert_raises(TypeError, np.dot, A, c)
+
+    def test_diagonal(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.diagonal(), [0, 5, 10])
+        assert_equal(a.diagonal(0), [0, 5, 10])
+        assert_equal(a.diagonal(1), [1, 6, 11])
+        assert_equal(a.diagonal(-1), [4, 9])
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.diagonal(), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(0), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(1), [[2], [3]])
+        assert_equal(b.diagonal(-1), [[4], [5]])
+        assert_raises(ValueError, b.diagonal, axis1=0, axis2=0)
+        assert_equal(b.diagonal(0, 1, 2), [[0, 3], [4, 7]])
+        assert_equal(b.diagonal(0, 0, 1), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(offset=1, axis1=0, axis2=2), [[1], [3]])
+        # Order of axis argument doesn't matter:
+        assert_equal(b.diagonal(0, 2, 1), [[0, 3], [4, 7]])
+
+    def test_diagonal_view_notwriteable(self):
+        # this test is only for 1.9, the diagonal view will be
+        # writeable in 1.10.
+        a = np.eye(3).diagonal()
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diagonal(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diag(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+    def test_diagonal_memleak(self):
+        # Regression test for a bug that crept in at one point
+        a = np.zeros((100, 100))
+        assert_(sys.getrefcount(a) < 50)
+        for i in range(100):
+            a.diagonal()
+        assert_(sys.getrefcount(a) < 50)
+
+    def test_trace(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.trace(), 15)
+        assert_equal(a.trace(0), 15)
+        assert_equal(a.trace(1), 18)
+        assert_equal(a.trace(-1), 13)
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.trace(), [6, 8])
+        assert_equal(b.trace(0), [6, 8])
+        assert_equal(b.trace(1), [2, 3])
+        assert_equal(b.trace(-1), [4, 5])
+        assert_equal(b.trace(0, 0, 1), [6, 8])
+        assert_equal(b.trace(0, 0, 2), [5, 9])
+        assert_equal(b.trace(0, 1, 2), [3, 11])
+        assert_equal(b.trace(offset=1, axis1=0, axis2=2), [1, 3])
+
+    def test_trace_subclass(self):
+        # The class would need to overwrite trace to ensure single-element
+        # output also has the right subclass.
+        class MyArray(np.ndarray):
+            pass
+
+        b = np.arange(8).reshape((2, 2, 2)).view(MyArray)
+        t = b.trace()
+        assert isinstance(t, MyArray)
+
+    def test_put(self):
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+        for dt in icodes + fcodes + 'O':
+            tgt = np.array([0, 1, 0, 3, 0, 5], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt.reshape(2, 3))
+
+        for dt in '?':
+            tgt = np.array([False, True, False, True, False, True], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt.reshape(2, 3))
+
+        # check must be writeable
+        a = np.zeros(6)
+        a.flags.writeable = False
+        assert_raises(ValueError, a.put, [1, 3, 5], [1, 3, 5])
+
+        # when calling np.put, make sure a
+        # TypeError is raised if the object
+        # isn't an ndarray
+        bad_array = [1, 2, 3]
+        assert_raises(TypeError, np.put, bad_array, [0, 2], 5)
+
+    def test_ravel(self):
+        a = np.array([[0, 1], [2, 3]])
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_(not a.ravel().flags.owndata)
+        assert_equal(a.ravel('F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='C'), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='A'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_equal(a.ravel(order='K'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+
+        a = np.array([[0, 1], [2, 3]], order='F')
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='A'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='K'), [0, 2, 1, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+        assert_equal(a.ravel(order='A'), a.reshape(-1, order='A'))
+
+        a = np.array([[0, 1], [2, 3]])[::-1, :]
+        assert_equal(a.ravel(), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='C'), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='F'), [2, 0, 3, 1])
+        assert_equal(a.ravel(order='A'), [2, 3, 0, 1])
+        # 'K' doesn't reverse the axes of negative strides
+        assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
+        assert_(a.ravel(order='K').flags.owndata)
+
+        # Test simple 1-d copy behaviour:
+        a = np.arange(10)[::2]
+        assert_(a.ravel('K').flags.owndata)
+        assert_(a.ravel('C').flags.owndata)
+        assert_(a.ravel('F').flags.owndata)
+
+        # Not contiguous and 1-sized axis with non matching stride
+        a = np.arange(2**3 * 2)[::2]
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('K'), np.arange(0, 15, 2))
+
+        # contiguous and 1-sized axis with non matching stride works:
+        a = np.arange(2**3)
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(np.may_share_memory(a.ravel(order='K'), a))
+        assert_equal(a.ravel(order='K'), np.arange(2**3))
+
+        # Test negative strides (not very interesting since non-contiguous):
+        a = np.arange(4)[::-1].reshape(2, 2)
+        assert_(a.ravel(order='C').flags.owndata)
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('C'), [3, 2, 1, 0])
+        assert_equal(a.ravel('K'), [3, 2, 1, 0])
+
+        # 1-element tidy strides test (NPY_RELAXED_STRIDES_CHECKING):
+        a = np.array([[1]])
+        a.strides = (123, 432)
+        # If the stride is not 8, NPY_RELAXED_STRIDES_CHECKING is messing
+        # them up on purpose:
+        if np.ones(1).strides == (8,):
+            assert_(np.may_share_memory(a.ravel('K'), a))
+            assert_equal(a.ravel('K').strides, (a.dtype.itemsize,))
+
+        for order in ('C', 'F', 'A', 'K'):
+            # 0-d corner case:
+            a = np.array(0)
+            assert_equal(a.ravel(order), [0])
+            assert_(np.may_share_memory(a.ravel(order), a))
+
+        # Test that certain non-inplace ravels work right (mostly) for 'K':
+        b = np.arange(2**4 * 2)[::2].reshape(2, 2, 2, 2)
+        a = b[..., ::2]
+        assert_equal(a.ravel('K'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('C'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('A'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('F'), [0, 16, 8, 24, 4, 20, 12, 28])
+
+        a = b[::2, ...]
+        assert_equal(a.ravel('K'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('C'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('A'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('F'), [0, 8, 4, 12, 2, 10, 6, 14])
+
+    def test_ravel_subclass(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = np.arange(10).view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+        a = np.arange(10)[::2].view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+    def test_swapaxes(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        idx = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        b = a.copy()
+        # check exceptions
+        assert_raises(ValueError, a.swapaxes, -5, 0)
+        assert_raises(ValueError, a.swapaxes, 4, 0)
+        assert_raises(ValueError, a.swapaxes, 0, -5)
+        assert_raises(ValueError, a.swapaxes, 0, 4)
+
+        for i in range(-4, 4):
+            for j in range(-4, 4):
+                for k, src in enumerate((a, b)):
+                    c = src.swapaxes(i, j)
+                    # check shape
+                    shape = list(src.shape)
+                    shape[i] = src.shape[j]
+                    shape[j] = src.shape[i]
+                    assert_equal(c.shape, shape, str((i, j, k)))
+                    # check array contents
+                    i0, i1, i2, i3 = [dim-1 for dim in c.shape]
+                    j0, j1, j2, j3 = [dim-1 for dim in src.shape]
+                    assert_equal(src[idx[j0], idx[j1], idx[j2], idx[j3]],
+                                 c[idx[i0], idx[i1], idx[i2], idx[i3]],
+                                 str((i, j, k)))
+                    # check a view is always returned, gh-5260
+                    assert_(not c.flags['OWNDATA'], str((i, j, k)))
+                    # check on non-contiguous input array
+                    if k == 1:
+                        b = c
+
+    def test_conjugate(self):
+        a = np.array([1-1j, 1+1j, 23+23.0j])
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1, 2, 3])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1.0, 2.0, 3.0])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 1, 2.0], object)
+        ac = a.conj()
+        assert_equal(ac, [k.conjugate() for k in a])
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1, 2.0, 'f'], object)
+        assert_raises(AttributeError, lambda: a.conj())
+        assert_raises(AttributeError, lambda: a.conjugate())
+
+class TestBinop(object):
+    def test_inplace(self):
+        # test refcount 1 inplace conversion
+        assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
+                                  [0.5, 1.0])
+
+        d = np.array([0.5, 0.5])[::2]
+        assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
+                                  [0.25, 0.5])
+
+        a = np.array([0.5])
+        b = np.array([0.5])
+        c = a + b
+        c = a - b
+        c = a * b
+        c = a / b
+        assert_equal(a, b)
+        assert_almost_equal(c, 1.)
+
+        c = a + b * 2. / b * a - a / b
+        assert_equal(a, b)
+        assert_equal(c, 0.5)
+
+        # true divide
+        a = np.array([5])
+        b = np.array([3])
+        c = (a * a) / b
+
+        assert_almost_equal(c, 25 / 3)
+        assert_equal(a, 5)
+        assert_equal(b, 3)
+
+    def test_extension_incref_elide(self):
+        # test extension (e.g. cython) calling PyNumber_* slots without
+        # increasing the reference counts
+        #
+        # def incref_elide(a):
+        #    d = input.copy() # refcount 1
+        #    return d, d + d # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide
+        d = np.ones(5)
+        orig, res = incref_elide(d)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(orig, d)
+        assert_array_equal(res, d + d)
+
+    def test_extension_incref_elide_stack(self):
+        # scanning if the refcount == 1 object is on the python stack to check
+        # that we are called directly from python is flawed as object may still
+        # be above the stack pointer and we have no access to the top of it
+        #
+        # def incref_elide_l(d):
+        #    return l[4] + l[4] # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide_l
+        # padding with 1 makes sure the object on the stack is not overwriten
+        l = [1, 1, 1, 1, np.ones(5)]
+        res = incref_elide_l(l)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(l[4], np.ones(5))
+        assert_array_equal(res, l[4] + l[4])
+
+    def test_ufunc_override_rop_precedence(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that __rmul__ and other right-hand operations have
+        # precedence over __numpy_ufunc__
+
+        ops = {
+            '__add__':      ('__radd__', np.add, True),
+            '__sub__':      ('__rsub__', np.subtract, True),
+            '__mul__':      ('__rmul__', np.multiply, True),
+            '__truediv__':  ('__rtruediv__', np.true_divide, True),
+            '__floordiv__': ('__rfloordiv__', np.floor_divide, True),
+            '__mod__':      ('__rmod__', np.remainder, True),
+            '__divmod__':   ('__rdivmod__', None, False),
+            '__pow__':      ('__rpow__', np.power, True),
+            '__lshift__':   ('__rlshift__', np.left_shift, True),
+            '__rshift__':   ('__rrshift__', np.right_shift, True),
+            '__and__':      ('__rand__', np.bitwise_and, True),
+            '__xor__':      ('__rxor__', np.bitwise_xor, True),
+            '__or__':       ('__ror__', np.bitwise_or, True),
+            '__ge__':       ('__le__', np.less_equal, False),
+            '__gt__':       ('__lt__', np.less, False),
+            '__le__':       ('__ge__', np.greater_equal, False),
+            '__lt__':       ('__gt__', np.greater, False),
+            '__eq__':       ('__eq__', np.equal, False),
+            '__ne__':       ('__ne__', np.not_equal, False),
+        }
+
+        class OtherNdarraySubclass(np.ndarray):
+            pass
+
+        class OtherNdarraySubclassWithOverride(np.ndarray):
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+        def check(op_name, ndsubclass):
+            rop_name, np_op, has_iop = ops[op_name]
+
+            if has_iop:
+                iop_name = '__i' + op_name[2:]
+                iop = getattr(operator, iop_name)
+
+            if op_name == "__divmod__":
+                op = divmod
+            else:
+                op = getattr(operator, op_name)
+
+            # Dummy class
+            def __init__(self, *a, **kw):
+                pass
+
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+            def __op__(self, *other):
+                return "op"
+
+            def __rop__(self, *other):
+                return "rop"
+
+            if ndsubclass:
+                bases = (np.ndarray,)
+            else:
+                bases = (object,)
+
+            dct = {'__init__': __init__,
+                   '__numpy_ufunc__': __numpy_ufunc__,
+                   op_name: __op__}
+            if op_name != rop_name:
+                dct[rop_name] = __rop__
+
+            cls = type("Rop" + rop_name, bases, dct)
+
+            # Check behavior against both bare ndarray objects and a
+            # ndarray subclasses with and without their own override
+            obj = cls((1,), buffer=np.ones(1,))
+
+            arr_objs = [np.array([1]),
+                        np.array([2]).view(OtherNdarraySubclass),
+                        np.array([3]).view(OtherNdarraySubclassWithOverride),
+                        ]
+
+            for arr in arr_objs:
+                err_msg = "%r %r" % (op_name, arr,)
+
+                # Check that ndarray op gives up if it sees a non-subclass
+                if not isinstance(obj, arr.__class__):
+                    assert_equal(getattr(arr, op_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+
+                # Check that the Python binops have priority
+                assert_equal(op(obj, arr), "op", err_msg=err_msg)
+                if op_name == rop_name:
+                    assert_equal(op(arr, obj), "op", err_msg=err_msg)
+                else:
+                    assert_equal(op(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that Python binops have priority also for in-place ops
+                if has_iop:
+                    assert_equal(getattr(arr, iop_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+                    if op_name != "__pow__":
+                        # inplace pow requires the other object to be
+                        # integer-like?
+                        assert_equal(iop(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that ufunc call __numpy_ufunc__ normally
+                if np_op is not None:
+                    assert_raises(AssertionError, np_op, arr, obj,
+                                  err_msg=err_msg)
+                    assert_raises(AssertionError, np_op, obj, arr,
+                                  err_msg=err_msg)
+
+        # Check all binary operations
+        for op_name in sorted(ops.keys()):
+            yield check, op_name, True
+            yield check, op_name, False
+
+    def test_ufunc_override_rop_simple(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check parts of the binary op overriding behavior in an
+        # explicit test case that is easier to understand.
+        class SomeClass(object):
+            def __numpy_ufunc__(self, *a, **kw):
+                return "ufunc"
+
+            def __mul__(self, other):
+                return 123
+
+            def __rmul__(self, other):
+                return 321
+
+            def __rsub__(self, other):
+                return "no subs for me"
+
+            def __gt__(self, other):
+                return "yep"
+
+            def __lt__(self, other):
+                return "nope"
+
+        class SomeClass2(SomeClass, np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if ufunc is np.multiply or ufunc is np.bitwise_and:
+                    return "ufunc"
+                else:
+                    inputs = list(inputs)
+                    if i < len(inputs):
+                        inputs[i] = np.asarray(self)
+                    func = getattr(ufunc, method)
+                    if ('out' in kw) and (kw['out'] is not None):
+                        kw['out'] = np.asarray(kw['out'])
+                    r = func(*inputs, **kw)
+                    x = self.__class__(r.shape, dtype=r.dtype)
+                    x[...] = r
+                    return x
+
+        class SomeClass3(SomeClass2):
+            def __rsub__(self, other):
+                return "sub for me"
+
+        arr = np.array([0])
+        obj = SomeClass()
+        obj2 = SomeClass2((1,), dtype=np.int_)
+        obj2[0] = 9
+        obj3 = SomeClass3((1,), dtype=np.int_)
+        obj3[0] = 4
+
+        # obj is first, so should get to define outcome.
+        assert_equal(obj * arr, 123)
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        assert_equal(arr * obj, 321)
+        # obj is second, but has __numpy_ufunc__ and defines __rsub__.
+        assert_equal(arr - obj, "no subs for me")
+        # obj is second, but has __numpy_ufunc__ and defines __lt__.
+        assert_equal(arr > obj, "nope")
+        # obj is second, but has __numpy_ufunc__ and defines __gt__.
+        assert_equal(arr < obj, "yep")
+        # Called as a ufunc, obj.__numpy_ufunc__ is used.
+        assert_equal(np.multiply(arr, obj), "ufunc")
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        arr *= obj
+        assert_equal(arr, 321)
+
+        # obj2 is an ndarray subclass, so CPython takes care of the same rules.
+        assert_equal(obj2 * arr, 123)
+        assert_equal(arr * obj2, 321)
+        assert_equal(arr - obj2, "no subs for me")
+        assert_equal(arr > obj2, "nope")
+        assert_equal(arr < obj2, "yep")
+        # Called as a ufunc, obj2.__numpy_ufunc__ is called.
+        assert_equal(np.multiply(arr, obj2), "ufunc")
+        # Also when the method is not overridden.
+        assert_equal(arr & obj2, "ufunc")
+        arr *= obj2
+        assert_equal(arr, 321)
+
+        obj2 += 33
+        assert_equal(obj2[0], 42)
+        assert_equal(obj2.sum(), 42)
+        assert_(isinstance(obj2, SomeClass2))
+
+        # Obj3 is subclass that defines __rsub__.  CPython calls it.
+        assert_equal(arr - obj3, "sub for me")
+        assert_equal(obj2 - obj3, "sub for me")
+        # obj3 is a subclass that defines __rmul__.  CPython calls it.
+        assert_equal(arr * obj3, 321)
+        # But not here, since obj3.__rmul__ is obj2.__rmul__.
+        assert_equal(obj2 * obj3, 123)
+        # And of course, here obj3.__mul__ should be called.
+        assert_equal(obj3 * obj2, 123)
+        # obj3 defines __numpy_ufunc__ but obj3.__radd__ is obj2.__radd__.
+        # (and both are just ndarray.__radd__); see #4815.
+        res = obj2 + obj3
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass2))
+        # Since obj3 is a subclass, it should have precedence, like CPython
+        # would give, even though obj2 has __numpy_ufunc__ and __radd__.
+        # See gh-4815 and gh-5747.
+        res = obj3 + obj2
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass3))
+
+    def test_ufunc_override_normalize_signature(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # gh-5674
+        class SomeClass(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return kw
+
+        a = SomeClass()
+        kw = np.add(a, [1])
+        assert_('sig' not in kw and 'signature' not in kw)
+        kw = np.add(a, [1], sig='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+        kw = np.add(a, [1], signature='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+
+    def test_numpy_ufunc_index(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that index is set appropriately, also if only an output
+        # is passed on (latter is another regression tests for github bug 4753)
+        class CheckIndex(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return i
+
+        a = CheckIndex()
+        dummy = np.arange(2.)
+        # 1 input, 1 output
+        assert_equal(np.sin(a), 0)
+        assert_equal(np.sin(dummy, a), 1)
+        assert_equal(np.sin(dummy, out=a), 1)
+        assert_equal(np.sin(dummy, out=(a,)), 1)
+        assert_equal(np.sin(a, a), 0)
+        assert_equal(np.sin(a, out=a), 0)
+        assert_equal(np.sin(a, out=(a,)), 0)
+        # 1 input, 2 outputs
+        assert_equal(np.modf(dummy, a), 1)
+        assert_equal(np.modf(dummy, None, a), 2)
+        assert_equal(np.modf(dummy, dummy, a), 2)
+        assert_equal(np.modf(dummy, out=a), 1)
+        assert_equal(np.modf(dummy, out=(a,)), 1)
+        assert_equal(np.modf(dummy, out=(a, None)), 1)
+        assert_equal(np.modf(dummy, out=(a, dummy)), 1)
+        assert_equal(np.modf(dummy, out=(None, a)), 2)
+        assert_equal(np.modf(dummy, out=(dummy, a)), 2)
+        assert_equal(np.modf(a, out=(dummy, a)), 0)
+        # 2 inputs, 1 output
+        assert_equal(np.add(a, dummy), 0)
+        assert_equal(np.add(dummy, a), 1)
+        assert_equal(np.add(dummy, dummy, a), 2)
+        assert_equal(np.add(dummy, a, a), 1)
+        assert_equal(np.add(dummy, dummy, out=a), 2)
+        assert_equal(np.add(dummy, dummy, out=(a,)), 2)
+        assert_equal(np.add(a, dummy, out=a), 0)
+
+    def test_out_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # regression test for github bug 4753
+        class OutClass(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if 'out' in kw:
+                    tmp_kw = kw.copy()
+                    tmp_kw.pop('out')
+                    func = getattr(ufunc, method)
+                    kw['out'][...] = func(*inputs, **tmp_kw)
+
+        A = np.array([0]).view(OutClass)
+        B = np.array([5])
+        C = np.array([6])
+        np.multiply(C, B, A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+        A[0] = 0
+        np.multiply(C, B, out=A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+
+
+class TestCAPI(TestCase):
+    def test_IsPythonScalar(self):
+        from numpy.core.multiarray_tests import IsPythonScalar
+        assert_(IsPythonScalar(b'foobar'))
+        assert_(IsPythonScalar(1))
+        assert_(IsPythonScalar(2**80))
+        assert_(IsPythonScalar(2.))
+        assert_(IsPythonScalar("a"))
+
+
+class TestSubscripting(TestCase):
+    def test_test_zero_rank(self):
+        x = np.array([1, 2, 3])
+        self.assertTrue(isinstance(x[0], np.int_))
+        if sys.version_info[0] < 3:
+            self.assertTrue(isinstance(x[0], int))
+        self.assertTrue(type(x[0, ...]) is np.ndarray)
+
+
+class TestPickling(TestCase):
+    def test_roundtrip(self):
+        import pickle
+        carray = np.array([[2, 9], [7, 0], [3, 8]])
+        DATA = [
+            carray,
+            np.transpose(carray),
+            np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int),
+                                               ('c', float)])
+        ]
+
+        for a in DATA:
+            assert_equal(a, pickle.loads(a.dumps()), err_msg="%r" % a)
+
+    def _loads(self, obj):
+        if sys.version_info[0] >= 3:
+            return np.loads(obj, encoding='latin1')
+        else:
+            return np.loads(obj)
+
+    # version 0 pickles, using protocol=2 to pickle
+    # version 0 doesn't have a version field
+    def test_version0_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    # version 1 pickles, using protocol=2 to pickle
+    def test_version1_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(K\x01U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_subarray_int_shape(self):
+        s = "cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'V6'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'a'\np12\ng3\ntp13\n(dp14\ng12\n(g7\n(S'V4'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'|'\np18\n(g7\n(S'i1'\np19\nI0\nI1\ntp20\nRp21\n(I3\nS'|'\np22\nNNNI-1\nI-1\nI0\ntp23\nb(I2\nI2\ntp24\ntp25\nNNI4\nI1\nI0\ntp26\nbI0\ntp27\nsg3\n(g7\n(S'V2'\np28\nI0\nI1\ntp29\nRp30\n(I3\nS'|'\np31\n(g21\nI2\ntp32\nNNI2\nI1\nI0\ntp33\nbI4\ntp34\nsI6\nI1\nI0\ntp35\nbI00\nS'\\x01\\x01\\x01\\x01\\x01\\x02'\np36\ntp37\nb."
+        a = np.array([(1, (1, 2))], dtype=[('a', 'i1', (2, 2)), ('b', 'i1', 2)])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+
+class TestFancyIndexing(TestCase):
+    def test_list(self):
+        x = np.ones((1, 1))
+        x[:, [0]] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+
+        x = np.ones((1, 1, 1))
+        x[:, :, [0]] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_tuple(self):
+        x = np.ones((1, 1))
+        x[:, (0,)] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+        x = np.ones((1, 1, 1))
+        x[:, :, (0,)] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        assert_array_equal(x[m], np.array([2]))
+
+    def test_mask2(self):
+        x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        assert_array_equal(x[m], np.array([[5, 6, 7, 8]]))
+        assert_array_equal(x[m2], np.array([2, 5]))
+        assert_array_equal(x[m3], np.array([2]))
+
+    def test_assign_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        x[m] = 5
+        assert_array_equal(x, np.array([1, 5, 3, 4]))
+
+    def test_assign_mask2(self):
+        xorig = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        x = xorig.copy()
+        x[m] = 10
+        assert_array_equal(x, np.array([[1, 2, 3, 4], [10, 10, 10, 10]]))
+        x = xorig.copy()
+        x[m2] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [10, 6, 7, 8]]))
+        x = xorig.copy()
+        x[m3] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [5, 6, 7, 8]]))
+
+
+class TestStringCompare(TestCase):
+    def test_string(self):
+        g1 = np.array(["This", "is", "example"])
+        g2 = np.array(["This", "was", "example"])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
+
+    def test_mixed(self):
+        g1 = np.array(["spam", "spa", "spammer", "and eggs"])
+        g2 = "spam"
+        assert_array_equal(g1 == g2, [x == g2 for x in g1])
+        assert_array_equal(g1 != g2, [x != g2 for x in g1])
+        assert_array_equal(g1 < g2, [x < g2 for x in g1])
+        assert_array_equal(g1 > g2, [x > g2 for x in g1])
+        assert_array_equal(g1 <= g2, [x <= g2 for x in g1])
+        assert_array_equal(g1 >= g2, [x >= g2 for x in g1])
+
+    def test_unicode(self):
+        g1 = np.array([sixu("This"), sixu("is"), sixu("example")])
+        g2 = np.array([sixu("This"), sixu("was"), sixu("example")])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2,  [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2,  [g1[i] > g2[i] for i in [0, 1, 2]])
+
+
+class TestArgmax(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 5),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2015-11-20T12:20:59'),
+          np.datetime64('1932-09-23T10:10:13'),
+          np.datetime64('2014-10-10T03:50:30')], 3),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 4),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 0),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 3),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 0),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 1),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 2),
+
+        ([False, False, False, False, True], 4),
+        ([False, False, False, True, False], 3),
+        ([True, False, False, False, False], 0),
+        ([True, False, True, False, False], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amax = a.max(i)
+            aargmax = a.argmax(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmax(arr)], np.max(arr), err_msg="%r" % arr)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmax(-1, out=out)
+        assert_equal(out, a.argmax(-1))
+
+    def test_argmax_unicode(self):
+        d = np.zeros(6031, dtype='<U9')
+        d[5942] = "as"
+        assert_equal(d.argmax(), 5942)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmax and numpy.argmax support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.zeros(2, dtype=int)
+        assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.zeros(3, dtype=int)
+        assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmax_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmax(), 0)
+        a[3] = 10
+        assert_equal(a.argmax(), 3)
+        a[1] = 30
+        assert_equal(a.argmax(), 1)
+
+
+class TestArgmin(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 2),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 1),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 0),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2014-11-20T12:20:59'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 4),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 1),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 2),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 0),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 1),
+
+        ([True, True, True, True, False], 4),
+        ([True, True, True, False, True], 3),
+        ([False, True, True, True, True], 0),
+        ([False, True, False, True, True], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amin = a.min(i)
+            aargmin = a.argmin(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmin(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmin(arr)], np.min(arr), err_msg="%r" % arr)
+
+    def test_minimum_signed_integers(self):
+
+        a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
+        assert_equal(np.argmin(a), 1)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmin(-1, out=out)
+        assert_equal(out, a.argmin(-1))
+
+    def test_argmin_unicode(self):
+        d = np.ones(6031, dtype='<U9')
+        d[6001] = "0"
+        assert_equal(d.argmin(), 6001)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmin and numpy.argmin support out/axis args
+        a = np.random.normal(size=(2, 3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.ones(2, dtype=int)
+        assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.ones(3, dtype=int)
+        assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmin_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmin(), 0)
+        a[3] = 30
+        assert_equal(a.argmin(), 3)
+        a[1] = 10
+        assert_equal(a.argmin(), 1)
+
+
+class TestMinMax(TestCase):
+
+    def test_scalar(self):
+        assert_raises(ValueError, np.amax, 1, 1)
+        assert_raises(ValueError, np.amin, 1, 1)
+
+        assert_equal(np.amax(1, axis=0), 1)
+        assert_equal(np.amin(1, axis=0), 1)
+        assert_equal(np.amax(1, axis=None), 1)
+        assert_equal(np.amin(1, axis=None), 1)
+
+    def test_axis(self):
+        assert_raises(ValueError, np.amax, [1, 2, 3], 1000)
+        assert_equal(np.amax([[1, 2, 3]], axis=1), 3)
+
+    def test_datetime(self):
+        # NaTs are ignored
+        for dtype in ('m8[s]', 'm8[Y]'):
+            a = np.arange(10).astype(dtype)
+            a[3] = 'NaT'
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[9])
+            a[0] = 'NaT'
+            assert_equal(np.amin(a), a[1])
+            assert_equal(np.amax(a), a[9])
+            a.fill('NaT')
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[0])
+
+
+class TestNewaxis(TestCase):
+    def test_basic(self):
+        sk = np.array([0, -0.1, 0.1])
+        res = 250*sk[:, np.newaxis]
+        assert_almost_equal(res.ravel(), 250*sk)
+
+
+class TestClip(TestCase):
+    def _check_range(self, x, cmin, cmax):
+        assert_(np.all(x >= cmin))
+        assert_(np.all(x <= cmax))
+
+    def _clip_type(self, type_group, array_max,
+                   clip_min, clip_max, inplace=False,
+                   expected_min=None, expected_max=None):
+        if expected_min is None:
+            expected_min = clip_min
+        if expected_max is None:
+            expected_max = clip_max
+
+        for T in np.sctypes[type_group]:
+            if sys.byteorder == 'little':
+                byte_orders = ['=', '>']
+            else:
+                byte_orders = ['<', '=']
+
+            for byteorder in byte_orders:
+                dtype = np.dtype(T).newbyteorder(byteorder)
+
+                x = (np.random.random(1000) * array_max).astype(dtype)
+                if inplace:
+                    x.clip(clip_min, clip_max, x)
+                else:
+                    x = x.clip(clip_min, clip_max)
+                    byteorder = '='
+
+                if x.dtype.byteorder == '|':
+                    byteorder = '|'
+                assert_equal(x.dtype.byteorder, byteorder)
+                self._check_range(x, expected_min, expected_max)
+        return x
+
+    def test_basic(self):
+        for inplace in [False, True]:
+            self._clip_type(
+                'float', 1024, -12.8, 100.2, inplace=inplace)
+            self._clip_type(
+                'float', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'int', 1024, -120, 100.5, inplace=inplace)
+            self._clip_type(
+                'int', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'uint', 1024, 0, 0, inplace=inplace)
+            self._clip_type(
+                'uint', 1024, -120, 100, inplace=inplace, expected_min=0)
+
+    def test_record_array(self):
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                       dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
+        y = rec['x'].clip(-0.3, 0.5)
+        self._check_range(y, -0.3, 0.5)
+
+    def test_max_or_min(self):
+        val = np.array([0, 1, 2, 3, 4, 5, 6, 7])
+        x = val.clip(3)
+        assert_(np.all(x >= 3))
+        x = val.clip(min=3)
+        assert_(np.all(x >= 3))
+        x = val.clip(max=4)
+        assert_(np.all(x <= 4))
+
+
+class TestCompress(TestCase):
+    def test_axis(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = np.compress([0, 1, 0, 1, 0], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_truncate(self):
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_flatten(self):
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr)
+        assert_equal(out, 1)
+
+
+class TestPutmask(object):
+    def tst_basic(self, x, T, mask, val):
+        np.putmask(x, mask, val)
+        assert_(np.all(x[mask] == T(val)))
+        assert_(x.dtype == T)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(1000)*100
+        mask = x < 40
+
+        for val in [-100, 0, 15]:
+            for types in np.sctypes.values():
+                for T in types:
+                    if T not in unchecked_types:
+                        yield self.tst_basic, x.copy().astype(T), T, mask, val
+
+    def test_mask_size(self):
+        assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5)
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        np.putmask(x, [True, False, True], -1)
+        assert_array_equal(x, [-1, 2, -1])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        np.putmask(rec['x'], [True, False], 10)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [2, 4])
+        assert_array_equal(rec['z'], [3, 3])
+        np.putmask(rec['y'], [True, False], 11)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [11, 4])
+        assert_array_equal(rec['z'], [3, 3])
+
+
+class TestTake(object):
+    def tst_basic(self, x):
+        ind = list(range(x.shape[0]))
+        assert_array_equal(x.take(ind, axis=0), x)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        for types in np.sctypes.values():
+            for T in types:
+                if T not in unchecked_types:
+                    yield self.tst_basic, x.copy().astype(T)
+
+    def test_raise(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_raises(IndexError, x.take, [0, 1, 2], axis=0)
+        assert_raises(IndexError, x.take, [-3], axis=0)
+        assert_array_equal(x.take([-1], axis=0)[0], x[1])
+
+    def test_clip(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='clip')[0], x[0])
+        assert_array_equal(x.take([2], axis=0, mode='clip')[0], x[1])
+
+    def test_wrap(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='wrap')[0], x[1])
+        assert_array_equal(x.take([2], axis=0, mode='wrap')[0], x[0])
+        assert_array_equal(x.take([3], axis=0, mode='wrap')[0], x[1])
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        assert_array_equal(x.take([0, 2, 1]), [1, 3, 2])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        rec1 = rec.take([1])
+        assert_(rec1['x'] == 5.0 and rec1['y'] == 4.0)
+
+
+class TestLexsort(TestCase):
+    def test_basic(self):
+        a = [1, 2, 1, 3, 1, 5]
+        b = [0, 4, 5, 6, 2, 3]
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([0, 4, 2, 1, 3, 5])
+        assert_array_equal(idx, expected_idx)
+
+        x = np.vstack((b, a))
+        idx = np.lexsort(x)
+        assert_array_equal(idx, expected_idx)
+
+        assert_array_equal(x[1][idx], np.sort(x[1]))
+
+    def test_datetime(self):
+        a = np.array([0,0,0], dtype='datetime64[D]')
+        b = np.array([2,1,0], dtype='datetime64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+        a = np.array([0,0,0], dtype='timedelta64[D]')
+        b = np.array([2,1,0], dtype='timedelta64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+    def test_object(self):  # gh-6312
+        a = np.random.choice(10, 1000)
+        b = np.random.choice(['abc', 'xy', 'wz', 'efghi', 'qwst', 'x'], 1000)
+
+        for u in a, b:
+            left = np.lexsort((u.astype('O'),))
+            right = np.argsort(u, kind='mergesort')
+            assert_array_equal(left, right)
+
+        for u, v in (a, b), (b, a):
+            idx = np.lexsort((u, v))
+            assert_array_equal(idx, np.lexsort((u.astype('O'), v)))
+            assert_array_equal(idx, np.lexsort((u, v.astype('O'))))
+            u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
+            assert_array_equal(idx, np.lexsort((u, v)))
+
+
+class TestIO(object):
+    """Test tofile, fromfile, tobytes, and fromstring"""
+
+    def setUp(self):
+        shape = (2, 4, 3)
+        rand = np.random.random
+        self.x = rand(shape) + rand(shape).astype(np.complex)*1j
+        self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
+        self.dtype = self.x.dtype
+        self.tempdir = tempfile.mkdtemp()
+        self.filename = tempfile.mktemp(dir=self.tempdir)
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def test_nofile(self):
+        # this should probably be supported as a file
+        # but for now test for proper errors
+        b = io.BytesIO()
+        assert_raises(IOError, np.fromfile, b, np.uint8, 80)
+        d = np.ones(7);
+        assert_raises(IOError, lambda x: x.tofile(b), d)
+
+    def test_bool_fromstring(self):
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        y = np.fromstring('1 0 -2.3 0.0', sep=' ', dtype=np.bool_)
+        assert_array_equal(v, y)
+
+    def test_uint64_fromstring(self):
+        d = np.fromstring("9923372036854775807 104783749223640",
+                          dtype=np.uint64, sep=' ')
+        e = np.array([9923372036854775807, 104783749223640], dtype=np.uint64)
+        assert_array_equal(d, e)
+
+    def test_int64_fromstring(self):
+        d = np.fromstring("-25041670086757 104783749223640",
+                          dtype=np.int64, sep=' ')
+        e = np.array([-25041670086757, 104783749223640], dtype=np.int64)
+        assert_array_equal(d, e)
+
+    def test_empty_files_binary(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename)
+        assert_(y.size == 0, "Array not empty")
+
+    def test_empty_files_text(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename, sep=" ")
+        assert_(y.size == 0, "Array not empty")
+
+    def test_roundtrip_file(self):
+        f = open(self.filename, 'wb')
+        self.x.tofile(f)
+        f.close()
+        # NB. doesn't work with flush+seek, due to use of C stdio
+        f = open(self.filename, 'rb')
+        y = np.fromfile(f, dtype=self.dtype)
+        f.close()
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_filename(self):
+        self.x.tofile(self.filename)
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_binary_str(self):
+        s = self.x.tobytes()
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+        s = self.x.tobytes('F')
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flatten('F'))
+
+    def test_roundtrip_str(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(str, x))
+        y = np.fromstring(s, sep="@")
+        # NB. str imbues less precision
+        nan_mask = ~np.isfinite(x)
+        assert_array_equal(x[nan_mask], y[nan_mask])
+        assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
+
+    def test_roundtrip_repr(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(repr, x))
+        y = np.fromstring(s, sep="@")
+        assert_array_equal(x, y)
+
+    def test_unbuffered_fromfile(self):
+        # gh-6246
+        self.x.tofile(self.filename)
+
+        def fail(*args, **kwargs):
+            raise io.IOError('Can not tell or seek')
+
+        f = io.open(self.filename, 'rb', buffering=0)
+        f.seek = fail
+        f.tell = fail
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_largish_file(self):
+        # check the fallocate path on files > 16MB
+        d = np.zeros(4 * 1024 ** 2)
+        d.tofile(self.filename)
+        assert_equal(os.path.getsize(self.filename), d.nbytes)
+        assert_array_equal(d, np.fromfile(self.filename));
+        # check offset
+        with open(self.filename, "r+b") as f:
+            f.seek(d.nbytes)
+            d.tofile(f)
+            assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+
+    def test_file_position_after_fromfile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.close()
+
+            for mode in ['rb', 'r+b']:
+                err_msg = "%d %s" % (size, mode)
+
+                f = open(self.filename, mode)
+                f.read(2)
+                np.fromfile(f, dtype=np.float64, count=1)
+                pos = f.tell()
+                f.close()
+                assert_equal(pos, 10, err_msg=err_msg)
+
+    def test_file_position_after_tofile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            err_msg = "%d" % (size,)
+
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.seek(10)
+            f.write(b'12')
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
+
+            f = open(self.filename, 'r+b')
+            f.read(2)
+            f.seek(0, 1)  # seek between read&write required by ANSI C
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10, err_msg=err_msg)
+
+    def _check_from(self, s, value, **kw):
+        y = np.fromstring(asbytes(s), **kw)
+        assert_array_equal(y, value)
+
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, **kw)
+        assert_array_equal(y, value)
+
+    def test_nan(self):
+        self._check_from(
+            "nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
+            [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
+            sep=' ')
+
+    def test_inf(self):
+        self._check_from(
+            "inf +inf -inf infinity -Infinity iNfInItY -inF",
+            [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
+            sep=' ')
+
+    def test_numbers(self):
+        self._check_from("1.234 -1.234 .3 .3e55 -123133.1231e+133",
+                         [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+
+    def test_binary(self):
+        self._check_from('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+                         np.array([1, 2, 3, 4]),
+                         dtype='<f4')
+
+    @dec.slow  # takes > 1 minute on mechanical hard drive
+    def test_big_binary(self):
+        """Test workarounds for 32-bit limited fwrite, fseek, and ftell
+        calls in windows. These normally would hang doing something like this.
+        See http://projects.scipy.org/numpy/ticket/1660"""
+        if sys.platform != 'win32' or "MSYSTEM" in os.environ:
+            return
+        try:
+            # before workarounds, only up to 2**32-1 worked
+            fourgbplus = 2**32 + 2**16
+            testbytes = np.arange(8, dtype=np.int8)
+            n = len(testbytes)
+            flike = tempfile.NamedTemporaryFile()
+            f = flike.file
+            np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
+            flike.seek(0)
+            a = np.fromfile(f, dtype=np.int8)
+            flike.close()
+            assert_(len(a) == fourgbplus)
+            # check only start and end for speed:
+            assert_((a[:n] == testbytes).all())
+            assert_((a[-n:] == testbytes).all())
+        except (MemoryError, ValueError):
+            pass
+
+    def test_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], sep=',')
+
+    def test_counted_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3.], count=3, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+
+    def test_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3, 4], dtype=int, sep=' ')
+
+    def test_counted_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3], count=3, dtype=int,
+                         sep=' ')
+
+    def test_ascii(self):
+        self._check_from('1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
+
+    def test_malformed(self):
+        self._check_from('1.234 1,234', [1.234, 1.], sep=' ')
+
+    def test_long_sep(self):
+        self._check_from('1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
+
+    def test_dtype(self):
+        v = np.array([1, 2, 3, 4], dtype=np.int_)
+        self._check_from('1,2,3,4', v, sep=',', dtype=np.int_)
+
+    def test_dtype_bool(self):
+        # can't use _check_from because fromstring can't handle True/False
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        s = '1,0,-2.3,0'
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
+        assert_(y.dtype == '?')
+        assert_array_equal(y, v)
+
+    def test_tofile_sep(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        #assert_equal(s, '1.51,2.0,3.51,4.0')
+        y = np.array([float(p) for p in s.split(',')])
+        assert_array_equal(x,y)
+
+    def test_tofile_format(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',', format='%.2f')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.00,3.51,4.00')
+
+    def test_locale(self):
+        in_foreign_locale(self.test_numbers)()
+        in_foreign_locale(self.test_nan)()
+        in_foreign_locale(self.test_inf)()
+        in_foreign_locale(self.test_counted_string)()
+        in_foreign_locale(self.test_ascii)()
+        in_foreign_locale(self.test_malformed)()
+        in_foreign_locale(self.test_tofile_sep)()
+        in_foreign_locale(self.test_tofile_format)()
+
+
+class TestFromBuffer(object):
+    def tst_basic(self, buffer, expected, kwargs):
+        assert_array_equal(np.frombuffer(buffer,**kwargs), expected)
+
+    def test_ip_basic(self):
+        for byteorder in ['<', '>']:
+            for dtype in [float, int, np.complex]:
+                dt = np.dtype(dtype).newbyteorder(byteorder)
+                x = (np.random.random((4, 7))*5).astype(dt)
+                buf = x.tobytes()
+                yield self.tst_basic, buf, x.flat, {'dtype':dt}
+
+    def test_empty(self):
+        yield self.tst_basic, asbytes(''), np.array([]), {}
+
+
+class TestFlat(TestCase):
+    def setUp(self):
+        a0 = np.arange(20.0)
+        a = a0.reshape(4, 5)
+        a0.shape = (4, 5)
+        a.flags.writeable = False
+        self.a = a
+        self.b = a[::2, ::2]
+        self.a0 = a0
+        self.b0 = a0[::2, ::2]
+
+    def test_contiguous(self):
+        testpassed = False
+        try:
+            self.a.flat[12] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.a.flat[12] == 12.0)
+
+    def test_discontiguous(self):
+        testpassed = False
+        try:
+            self.b.flat[4] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.b.flat[4] == 12.0)
+
+    def test___array__(self):
+        c = self.a.flat.__array__()
+        d = self.b.flat.__array__()
+        e = self.a0.flat.__array__()
+        f = self.b0.flat.__array__()
+
+        assert_(c.flags.writeable is False)
+        assert_(d.flags.writeable is False)
+        assert_(e.flags.writeable is True)
+        assert_(f.flags.writeable is True)
+
+        assert_(c.flags.updateifcopy is False)
+        assert_(d.flags.updateifcopy is False)
+        assert_(e.flags.updateifcopy is False)
+        assert_(f.flags.updateifcopy is True)
+        assert_(f.base is self.b0)
+
+
+class TestResize(TestCase):
+    def test_basic(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        x.resize((5, 5))
+        assert_array_equal(x.flat[:9],
+                np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat)
+        assert_array_equal(x[9:].flat, 0)
+
+    def test_check_reference(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        y = x
+        self.assertRaises(ValueError, x.resize, (5, 1))
+        del y  # avoid pyflakes unused variable warning.
+
+    def test_int_shape(self):
+        x = np.eye(3)
+        x.resize(3)
+        assert_array_equal(x, np.eye(3)[0,:])
+
+    def test_none_shape(self):
+        x = np.eye(3)
+        x.resize(None)
+        assert_array_equal(x, np.eye(3))
+        x.resize()
+        assert_array_equal(x, np.eye(3))
+
+    def test_invalid_arguements(self):
+        self.assertRaises(TypeError, np.eye(3).resize, 'hi')
+        self.assertRaises(ValueError, np.eye(3).resize, -1)
+        self.assertRaises(TypeError, np.eye(3).resize, order=1)
+        self.assertRaises(TypeError, np.eye(3).resize, refcheck='hi')
+
+    def test_freeform_shape(self):
+        x = np.eye(3)
+        x.resize(3, 2, 1)
+        assert_(x.shape == (3, 2, 1))
+
+    def test_zeros_appended(self):
+        x = np.eye(3)
+        x.resize(2, 3, 3)
+        assert_array_equal(x[0], np.eye(3))
+        assert_array_equal(x[1], np.zeros((3, 3)))
+
+    def test_obj_obj(self):
+        # check memory is initialized on resize, gh-4857
+        a = np.ones(10, dtype=[('k', object, 2)])
+        a.resize(15,)
+        assert_equal(a.shape, (15,))
+        assert_array_equal(a['k'][-5:], 0)
+        assert_array_equal(a['k'][:-5], 1)
+
+
+class TestRecord(TestCase):
+    def test_field_rename(self):
+        dt = np.dtype([('f', float), ('i', int)])
+        dt.names = ['p', 'q']
+        assert_equal(dt.names, ['p', 'q'])
+
+    def test_multiple_field_name_occurrence(self):
+        def test_assign():
+            dtype = np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")])
+
+        # Error raised when multiple fields have the same name
+        assert_raises(ValueError, test_assign)
+
+    if sys.version_info[0] >= 3:
+        def test_bytes_fields(self):
+            # Bytes are not allowed in field names and not recognized in titles
+            # on Py3
+            assert_raises(TypeError, np.dtype, [(asbytes('a'), int)])
+            assert_raises(TypeError, np.dtype, [(('b', asbytes('a')), int)])
+
+            dt = np.dtype([((asbytes('a'), 'b'), int)])
+            assert_raises(ValueError, dt.__getitem__, asbytes('a'))
+
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            assert_raises(IndexError, x.__getitem__, asbytes('a'))
+
+            y = x[0]
+            assert_raises(IndexError, y.__getitem__, asbytes('a'))
+
+        def test_multiple_field_name_unicode(self):
+            def test_assign_unicode():
+                dt = np.dtype([("\u20B9", "f8"),
+                               ("B", "f8"),
+                               ("\u20B9", "f8")])
+
+            # Error raised when multiple fields have the same name(unicode included)
+            assert_raises(ValueError, test_assign_unicode)
+
+    else:
+        def test_unicode_field_titles(self):
+            # Unicode field titles are added to field dict on Py2
+            title = unicode('b')
+            dt = np.dtype([((title, 'a'), int)])
+            dt[title]
+            dt['a']
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            x[title]
+            x['a']
+            y = x[0]
+            y[title]
+            y['a']
+
+        def test_unicode_field_names(self):
+            # Unicode field names are not allowed on Py2
+            title = unicode('b')
+            assert_raises(TypeError, np.dtype, [(title, int)])
+            assert_raises(TypeError, np.dtype, [(('a', title), int)])
+
+    def test_field_names(self):
+        # Test unicode and 8-bit / byte strings can be used
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        is_py3 = sys.version_info[0] >= 3
+        if is_py3:
+            funcs = (str,)
+            # byte string indexing fails gracefully
+            assert_raises(IndexError, a.__setitem__, asbytes('f1'), 1)
+            assert_raises(IndexError, a.__getitem__, asbytes('f1'))
+            assert_raises(IndexError, a['f1'].__setitem__, asbytes('sf1'), 1)
+            assert_raises(IndexError, a['f1'].__getitem__, asbytes('sf1'))
+        else:
+            funcs = (str, unicode)
+        for func in funcs:
+            b = a.copy()
+            fn1 = func('f1')
+            b[fn1] = 1
+            assert_equal(b[fn1], 1)
+            fnn = func('not at all')
+            assert_raises(ValueError, b.__setitem__, fnn, 1)
+            assert_raises(ValueError, b.__getitem__, fnn)
+            b[0][fn1] = 2
+            assert_equal(b[fn1], 2)
+            # Subfield
+            assert_raises(ValueError, b[0].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[0].__getitem__, fnn)
+            # Subfield
+            fn3 = func('f3')
+            sfn1 = func('sf1')
+            b[fn3][sfn1] = 1
+            assert_equal(b[fn3][sfn1], 1)
+            assert_raises(ValueError, b[fn3].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[fn3].__getitem__, fnn)
+            # multiple subfields
+            fn2 = func('f2')
+            b[fn2] = 3
+            assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2))
+            assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,)))
+            # view of subfield view/copy
+            assert_equal(b[['f1', 'f2']][0].view(('i4', 2)).tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].view(('i4', 2)).tolist(), (3, 2))
+            view_dtype = [('f1', 'i4'), ('f3', [('', 'i4')])]
+            assert_equal(b[['f1', 'f3']][0].view(view_dtype).tolist(), (2, (1,)))
+        # non-ascii unicode field indexing is well behaved
+        if not is_py3:
+            raise SkipTest('non ascii unicode field indexing skipped; '
+                           'raises segfault on python 2.x')
+        else:
+            assert_raises(ValueError, a.__setitem__, sixu('\u03e0'), 1)
+            assert_raises(ValueError, a.__getitem__, sixu('\u03e0'))
+
+    def test_field_names_deprecation(self):
+
+        def collect_warnings(f, *args, **kwargs):
+            with warnings.catch_warnings(record=True) as log:
+                warnings.simplefilter("always")
+                f(*args, **kwargs)
+            return [w.category for w in log]
+
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        a['f1'][0] = 1
+        a['f2'][0] = 2
+        a['f3'][0] = (3,)
+        b = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        b['f1'][0] = 1
+        b['f2'][0] = 2
+        b['f3'][0] = (3,)
+
+        # All the different functions raise a warning, but not an error, and
+        # 'a' is not modified:
+        assert_equal(collect_warnings(a[['f1', 'f2']].__setitem__, 0, (10, 20)),
+                     [FutureWarning])
+        assert_equal(a, b)
+        # Views also warn
+        subset = a[['f1', 'f2']]
+        subset_view = subset.view()
+        assert_equal(collect_warnings(subset_view['f1'].__setitem__, 0, 10),
+                     [FutureWarning])
+        # But the write goes through:
+        assert_equal(subset['f1'][0], 10)
+        # Only one warning per multiple field indexing, though (even if there
+        # are multiple views involved):
+        assert_equal(collect_warnings(subset['f1'].__setitem__, 0, 10), [])
+
+    def test_record_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        a.flags.writeable = False
+        b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')])
+        b.flags.writeable = False
+        c = np.array([(1, 2), (3, 4)], dtype='i1,i2')
+        c.flags.writeable = False
+        self.assertTrue(hash(a[0]) == hash(a[1]))
+        self.assertTrue(hash(a[0]) == hash(b[0]))
+        self.assertTrue(hash(a[0]) != hash(b[1]))
+        self.assertTrue(hash(c[0]) == hash(a[0]) and c[0] == a[0])
+
+    def test_record_no_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        self.assertRaises(TypeError, hash, a[0])
+
+    def test_empty_structure_creation(self):
+        # make sure these do not raise errors (gh-5631)
+        np.array([()], dtype={'names': [], 'formats': [],
+                           'offsets': [], 'itemsize': 12})
+        np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [],
+                                           'offsets': [], 'itemsize': 12})
+
+class TestView(TestCase):
+    def test_basic(self):
+        x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)],
+                     dtype=[('r', np.int8), ('g', np.int8),
+                            ('b', np.int8), ('a', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i4')
+        # ... and again without the keyword.
+        z = x.view('<i4')
+        assert_array_equal(y, z)
+        assert_array_equal(y, [67305985, 134678021])
+
+
+def _mean(a, **args):
+    return a.mean(**args)
+
+
+def _var(a, **args):
+    return a.var(**args)
+
+
+def _std(a, **args):
+    return a.std(**args)
+
+
+class TestStats(TestCase):
+
+    funcs = [_mean, _var, _std]
+
+    def setUp(self):
+        np.random.seed(range(3))
+        self.rmat = np.random.random((4, 5))
+        self.cmat = self.rmat + 1j * self.rmat
+        self.omat = np.array([Decimal(repr(r)) for r in self.rmat.flat])
+        self.omat = self.omat.reshape(4, 5)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            for axis in [0, 1]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == mat.ndim)
+                assert_(res.shape[axis] == 1)
+            for axis in [None]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.shape == (1, 1))
+
+    def test_out(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            out = np.zeros(3)
+            tgt = f(mat, axis=1)
+            res = f(mat, axis=1, out=out)
+            assert_almost_equal(res, out)
+            assert_almost_equal(res, tgt)
+        out = np.empty(2)
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+        out = np.empty((2, 2))
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+
+    def test_dtype_from_input(self):
+
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+
+        # object type
+        for f in self.funcs:
+            mat = np.array([[Decimal(1)]*3]*3)
+            tgt = mat.dtype.type
+            res = f(mat, axis=1).dtype.type
+            assert_(res is tgt)
+            # scalar case
+            res = type(f(mat, axis=None))
+            assert_(res is Decimal)
+
+        # integer types
+        for f in self.funcs:
+            for c in icodes:
+                mat = np.eye(3, dtype=c)
+                tgt = np.float64
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # mean for float types
+        for f in [_mean]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                tgt = mat.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # var, std for float types
+        for f in [_var, _std]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                # deal with complex types
+                tgt = mat.real.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+
+        # stats for integer types
+        # FIXME:
+        # this needs definition as there are lots places along the line
+        # where type casting may take place.
+
+        # for f in self.funcs:
+        #    for c in np.typecodes['AllInteger']:
+        #        tgt = np.dtype(c).type
+        #        res = f(mat, axis=1, dtype=c).dtype.type
+        #        assert_(res is tgt)
+        #        # scalar case
+        #        res = f(mat, axis=None, dtype=c).dtype.type
+        #        assert_(res is tgt)
+
+        # stats for float types
+        for f in self.funcs:
+            for c in np.typecodes['AllFloat']:
+                tgt = np.dtype(c).type
+                res = f(mat, axis=1, dtype=c).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None, dtype=c).dtype.type
+                assert_(res is tgt)
+
+    def test_ddof(self):
+        for f in [_var]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * dim
+                res = f(self.rmat, axis=1, ddof=ddof) * (dim - ddof)
+        for f in [_std]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * np.sqrt(dim)
+                res = f(self.rmat, axis=1, ddof=ddof) * np.sqrt(dim - ddof)
+                assert_almost_equal(res, tgt)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        dim = self.rmat.shape[1]
+        for f in [_var, _std]:
+            for ddof in range(dim, dim + 2):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    res = f(self.rmat, axis=1, ddof=ddof)
+                    assert_(not (res < 0).any())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        A = np.zeros((0, 3))
+        for f in self.funcs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(A, axis=axis)).all())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(A, axis=axis), np.zeros([]))
+
+    def test_mean_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * mat.shape[axis]
+                assert_almost_equal(res, tgt)
+            for axis in [None]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * np.prod(mat.shape)
+                assert_almost_equal(res, tgt)
+
+    def test_var_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                msqr = _mean(mat * mat.conj(), axis=axis)
+                mean = _mean(mat, axis=axis)
+                tgt = msqr - mean * mean.conjugate()
+                res = _var(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_std_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                tgt = np.sqrt(_var(mat, axis=axis))
+                res = _std(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_subclass(self):
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, "info", '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        res = dat.mean(1)
+        assert_(res.info == dat.info)
+        res = dat.std(1)
+        assert_(res.info == dat.info)
+        res = dat.var(1)
+        assert_(res.info == dat.info)
+
+class TestVdot(TestCase):
+    def test_basic(self):
+        dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
+        dt_complex = np.typecodes['Complex']
+
+        # test real
+        a = np.eye(3)
+        for dt in dt_numeric + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test complex
+        a = np.eye(3) * 1j
+        for dt in dt_complex + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test boolean
+        b = np.eye(3, dtype=np.bool)
+        res = np.vdot(b, b)
+        assert_(np.isscalar(res))
+        assert_equal(np.vdot(b, b), True)
+
+    def test_vdot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.vdot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.vdot(a, b), res)
+        assert_equal(np.vdot(b, a), res)
+        assert_equal(np.vdot(b, b), res)
+
+    def test_vdot_uncontiguous(self):
+        for size in [2, 1000]:
+            # Different sizes match different branches in vdot.
+            a = np.zeros((size, 2, 2))
+            b = np.zeros((size, 2, 2))
+            a[:, 0, 0] = np.arange(size)
+            b[:, 0, 0] = np.arange(size) + 1
+            # Make a and b uncontiguous:
+            a = a[..., 0]
+            b = b[..., 0]
+
+            assert_equal(np.vdot(a, b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy()),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy(), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy('F'), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy('F')),
+                         np.vdot(a.flatten(), b.flatten()))
+
+
+class TestDot(TestCase):
+    def setUp(self):
+        np.random.seed(128)
+        self.A = np.random.rand(4, 2)
+        self.b1 = np.random.rand(2, 1)
+        self.b2 = np.random.rand(2)
+        self.b3 = np.random.rand(1, 2)
+        self.b4 = np.random.rand(4)
+        self.N = 7
+
+    def test_dotmatmat(self):
+        A = self.A
+        res = np.dot(A.transpose(), A)
+        tgt = np.array([[1.45046013, 0.86323640],
+                        [0.86323640, 0.84934569]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec(self):
+        A, b1 = self.A, self.b1
+        res = np.dot(A, b1)
+        tgt = np.array([[0.32114320], [0.04889721],
+                        [0.15696029], [0.33612621]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec2(self):
+        A, b2 = self.A, self.b2
+        res = np.dot(A, b2)
+        tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(b4, A)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat2(self):
+        b3, A = self.b3, self.A
+        res = np.dot(b3, A.transpose())
+        tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat3(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(A.transpose(), b4)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecouter(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b1, b3)
+        tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecinner(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b3, b1)
+        tgt = np.array([[ 0.23129668]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect1(self):
+        b1 = np.ones((3, 1))
+        b2 = [5.3]
+        res = np.dot(b1, b2)
+        tgt = np.array([5.3, 5.3, 5.3])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect2(self):
+        b1 = np.ones((3, 1)).transpose()
+        b2 = [6.2]
+        res = np.dot(b2, b1)
+        tgt = np.array([6.2, 6.2, 6.2])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar(self):
+        np.random.seed(100)
+        b1 = np.random.rand(1, 1)
+        b2 = np.random.rand(1, 4)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar2(self):
+        np.random.seed(100)
+        b1 = np.random.rand(4, 1)
+        b2 = np.random.rand(1, 1)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_all(self):
+        dims = [(), (1,), (1, 1)]
+        dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)]
+        for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)):
+            b1 = np.zeros(dim1)
+            b2 = np.zeros(dim2)
+            res = np.dot(b1, b2)
+            tgt = np.zeros(dim)
+            assert_(res.shape == tgt.shape)
+            assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_vecobject(self):
+        class Vec(object):
+            def __init__(self, sequence=None):
+                if sequence is None:
+                    sequence = []
+                self.array = np.array(sequence)
+
+            def __add__(self, other):
+                out = Vec()
+                out.array = self.array + other.array
+                return out
+
+            def __sub__(self, other):
+                out = Vec()
+                out.array = self.array - other.array
+                return out
+
+            def __mul__(self, other):  # with scalar
+                out = Vec(self.array.copy())
+                out.array *= other
+                return out
+
+            def __rmul__(self, other):
+                return self*other
+
+        U_non_cont = np.transpose([[1., 1.], [1., 2.]])
+        U_cont = np.ascontiguousarray(U_non_cont)
+        x = np.array([Vec([1., 0.]), Vec([0., 1.])])
+        zeros = np.array([Vec([0., 0.]), Vec([0., 0.])])
+        zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x)
+        assert_equal(zeros[0].array, zeros_test[0].array)
+        assert_equal(zeros[1].array, zeros_test[1].array)
+
+    def test_dot_2args(self):
+        from numpy.core.multiarray import dot
+
+        a = np.array([[1, 2], [3, 4]], dtype=float)
+        b = np.array([[1, 0], [1, 1]], dtype=float)
+        c = np.array([[3, 2], [7, 4]], dtype=float)
+
+        d = dot(a, b)
+        assert_allclose(c, d)
+
+    def test_dot_3args(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 32))
+        for i in range(12):
+            dot(f, v, r)
+        assert_equal(sys.getrefcount(r), 2)
+        r2 = dot(f, v, out=None)
+        assert_array_equal(r2, r)
+        assert_(r is dot(f, v, out=r))
+
+        v = v[:, 0].copy()  # v.shape == (16,)
+        r = r[:, 0].copy()  # r.shape == (1024,)
+        r2 = dot(f, v)
+        assert_(r is dot(f, v, r))
+        assert_array_equal(r2, r)
+
+    def test_dot_3args_errors(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 31))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32, 1024))
+        assert_raises(ValueError, dot, f, v, r)
+        assert_raises(ValueError, dot, f, v, r.T)
+
+        r = np.empty((1024, 64))
+        assert_raises(ValueError, dot, f, v, r[:, ::2])
+        assert_raises(ValueError, dot, f, v, r[:, :32])
+
+        r = np.empty((1024, 32), dtype=np.float32)
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024, 32), dtype=int)
+        assert_raises(ValueError, dot, f, v, r)
+
+    def test_dot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.dot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.dot(a, b), res)
+        assert_equal(np.dot(b, a), res)
+        assert_equal(np.dot(b, b), res)
+
+    def test_dot_scalar_and_matrix_of_objects(self):
+        # Ticket #2469
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.dot(arr, 3), desired)
+        assert_equal(np.dot(3, arr), desired)
+
+    def test_accelerate_framework_sgemv_fix(self):
+
+        def aligned_array(shape, align, dtype, order='C'):
+            d = dtype(0)
+            N = np.prod(shape)
+            tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
+            address = tmp.__array_interface__["data"][0]
+            for offset in range(align):
+                if (address + offset) % align == 0:
+                    break
+            tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
+            return tmp.reshape(shape, order=order)
+
+        def as_aligned(arr, align, dtype, order='C'):
+            aligned = aligned_array(arr.shape, align, dtype, order)
+            aligned[:] = arr[:]
+            return aligned
+
+        def assert_dot_close(A, X, desired):
+            assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
+
+        m = aligned_array(100, 15, np.float32)
+        s = aligned_array((100, 100), 15, np.float32)
+        np.dot(s, m)  # this will always segfault if the bug is present
+
+        testdata = itertools.product((15,32), (10000,), (200,89), ('C','F'))
+        for align, m, n, a_order in testdata:
+            # Calculation in double precision
+            A_d = np.random.rand(m, n)
+            X_d = np.random.rand(n)
+            desired = np.dot(A_d, X_d)
+            # Calculation with aligned single precision
+            A_f = as_aligned(A_d, align, np.float32, order=a_order)
+            X_f = as_aligned(X_d, align, np.float32)
+            assert_dot_close(A_f, X_f, desired)
+            # Strided A rows
+            A_d_2 = A_d[::2]
+            desired = np.dot(A_d_2, X_d)
+            A_f_2 = A_f[::2]
+            assert_dot_close(A_f_2, X_f, desired)
+            # Strided A columns, strided X vector
+            A_d_22 = A_d_2[:, ::2]
+            X_d_2 = X_d[::2]
+            desired = np.dot(A_d_22, X_d_2)
+            A_f_22 = A_f_2[:, ::2]
+            X_f_2 = X_f[::2]
+            assert_dot_close(A_f_22, X_f_2, desired)
+            # Check the strides are as expected
+            if a_order == 'F':
+                assert_equal(A_f_22.strides, (8, 8 * m))
+            else:
+                assert_equal(A_f_22.strides, (8 * n, 8))
+            assert_equal(X_f_2.strides, (8,))
+            # Strides in A rows + cols only
+            X_f_2c = as_aligned(X_f_2, align, np.float32)
+            assert_dot_close(A_f_22, X_f_2c, desired)
+            # Strides just in A cols
+            A_d_12 = A_d[:, ::2]
+            desired = np.dot(A_d_12, X_d_2)
+            A_f_12 = A_f[:, ::2]
+            assert_dot_close(A_f_12, X_f_2c, desired)
+            # Strides in A cols and X
+            assert_dot_close(A_f_12, X_f_2, desired)
+
+
+class MatmulCommon():
+    """Common tests for '@' operator and numpy.matmul.
+
+    Do not derive from TestCase to avoid nose running it.
+
+    """
+    # Should work with these types. Will want to add
+    # "O" at some point
+    types = "?bhilqBHILQefdgFDG"
+
+    def test_exceptions(self):
+        dims = [
+            ((1,), (2,)),            # mismatched vector vector
+            ((2, 1,), (2,)),         # mismatched matrix vector
+            ((2,), (1, 2)),          # mismatched vector matrix
+            ((1, 2), (3, 1)),        # mismatched matrix matrix
+            ((1,), ()),              # vector scalar
+            ((), (1)),               # scalar vector
+            ((1, 1), ()),            # matrix scalar
+            ((), (1, 1)),            # scalar matrix
+            ((2, 2, 1), (3, 1, 2)),  # cannot broadcast
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            assert_raises(ValueError, self.matmul, a, b)
+
+    def test_shapes(self):
+        dims = [
+            ((1, 1), (2, 1, 1)),     # broadcast first argument
+            ((2, 1, 1), (1, 1)),     # broadcast second argument
+            ((2, 1, 1), (2, 1, 1)),  # matrix stack sizes match
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            res = self.matmul(a, b)
+            assert_(res.shape == (2, 1, 1))
+
+        # vector vector returns scalars.
+        for dt in self.types:
+            a = np.ones((2,), dtype=dt)
+            b = np.ones((2,), dtype=dt)
+            c = self.matmul(a, b)
+            assert_(np.array(c).shape == ())
+
+    def test_result_types(self):
+        mat = np.ones((1,1))
+        vec = np.ones((1,))
+        for dt in self.types:
+            m = mat.astype(dt)
+            v = vec.astype(dt)
+            for arg in [(m, v), (v, m), (m, m)]:
+                res = self.matmul(*arg)
+                assert_(res.dtype == dt)
+
+            # vector vector returns scalars
+            res = self.matmul(v, v)
+            assert_(type(res) is np.dtype(dt).type)
+
+    def test_vector_vector_values(self):
+        vec = np.array([1, 2])
+        tgt = 5
+        for dt in self.types[1:]:
+            v1 = vec.astype(dt)
+            res = self.matmul(v1, v1)
+            assert_equal(res, tgt)
+
+        # boolean type
+        vec = np.array([True, True], dtype='?')
+        res = self.matmul(vec, vec)
+        assert_equal(res, True)
+
+    def test_vector_matrix_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([7, 10])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(v, m1)
+            assert_equal(res, tgt1)
+            res = self.matmul(v, m2)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_vector_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([5, 11])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(m1, v)
+            assert_equal(res, tgt1)
+            res = self.matmul(m2, v)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_matrix_values(self):
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.array([[1, 0], [1, 1]])
+        mat12 = np.stack([mat1, mat2], axis=0)
+        mat21 = np.stack([mat2, mat1], axis=0)
+        tgt11 = np.array([[7, 10], [15, 22]])
+        tgt12 = np.array([[3, 2], [7, 4]])
+        tgt21 = np.array([[1, 2], [4, 6]])
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+        for dt in self.types[1:]:
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            m12 = mat12.astype(dt)
+            m21 = mat21.astype(dt)
+
+            # matrix @ matrix
+            res = self.matmul(m1, m2)
+            assert_equal(res, tgt12)
+            res = self.matmul(m2, m1)
+            assert_equal(res, tgt21)
+
+            # stacked @ matrix
+            res = self.matmul(m12, m1)
+            assert_equal(res, tgt11_21)
+
+            # matrix @ stacked
+            res = self.matmul(m1, m12)
+            assert_equal(res, tgt11_12)
+
+            # stacked @ stacked
+            res = self.matmul(m12, m21)
+            assert_equal(res, tgt12_21)
+
+        # boolean type
+        m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_)
+        m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_)
+        m12 = np.stack([m1, m2], axis=0)
+        m21 = np.stack([m2, m1], axis=0)
+        tgt11 = m1
+        tgt12 = m1
+        tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_)
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+
+        # matrix @ matrix
+        res = self.matmul(m1, m2)
+        assert_equal(res, tgt12)
+        res = self.matmul(m2, m1)
+        assert_equal(res, tgt21)
+
+        # stacked @ matrix
+        res = self.matmul(m12, m1)
+        assert_equal(res, tgt11_21)
+
+        # matrix @ stacked
+        res = self.matmul(m1, m12)
+        assert_equal(res, tgt11_12)
+
+        # stacked @ stacked
+        res = self.matmul(m12, m21)
+        assert_equal(res, tgt12_21)
+
+    def test_numpy_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A([1, 2])
+        b = B([1, 2])
+        c = np.ones(2)
+        assert_equal(self.matmul(a, b), "A")
+        assert_equal(self.matmul(b, a), "A")
+        assert_raises(TypeError, self.matmul, b, c)
+
+
+class TestMatmul(MatmulCommon, TestCase):
+    matmul = np.matmul
+
+    def test_out_arg(self):
+        a = np.ones((2, 2), dtype=np.float)
+        b = np.ones((2, 2), dtype=np.float)
+        tgt = np.full((2,2), 2, dtype=np.float)
+
+        # test as positional argument
+        msg = "out positional argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test as keyword argument
+        msg = "out keyword argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out=out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out with not allowed type cast (safe casting)
+        # einsum and cblas raise different error types, so
+        # use Exception.
+        msg = "out argument with illegal cast"
+        out = np.zeros((2, 2), dtype=np.int32)
+        assert_raises(Exception, self.matmul, a, b, out=out)
+
+        # skip following tests for now, cblas does not allow non-contiguous
+        # outputs and consistency with dot would require same type,
+        # dimensions, subtype, and c_contiguous.
+
+        # test out with allowed type cast
+        # msg = "out argument with allowed cast"
+        # out = np.zeros((2, 2), dtype=np.complex128)
+        # self.matmul(a, b, out=out)
+        # assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out non-contiguous
+        # msg = "out argument with non-contiguous layout"
+        # c = np.zeros((2, 2, 2), dtype=np.float)
+        # self.matmul(a, b, out=c[..., 0])
+        # assert_array_equal(c, tgt, err_msg=msg)
+
+
+if sys.version_info[:2] >= (3, 5):
+    class TestMatmulOperator(MatmulCommon, TestCase):
+        import operator
+        matmul = operator.matmul
+
+        def test_array_priority_override(self):
+
+            class A(object):
+                __array_priority__ = 1000
+
+                def __matmul__(self, other):
+                    return "A"
+
+                def __rmatmul__(self, other):
+                    return "A"
+
+            a = A()
+            b = np.ones(2)
+            assert_equal(self.matmul(a, b), "A")
+            assert_equal(self.matmul(b, a), "A")
+
+    def test_matmul_inplace():
+        # It would be nice to support in-place matmul eventually, but for now
+        # we don't have a working implementation, so better just to error out
+        # and nudge people to writing "a = a @ b".
+        a = np.eye(3)
+        b = np.eye(3)
+        assert_raises(TypeError, a.__imatmul__, b)
+        import operator
+        assert_raises(TypeError, operator.imatmul, a, b)
+        # we avoid writing the token `exec` so as not to crash python 2's
+        # parser
+        exec_ = getattr(builtins, "exec")
+        assert_raises(TypeError, exec_, "a @= b", globals(), locals())
+
+
+class TestInner(TestCase):
+
+    def test_inner_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.inner, c, A)
+        assert_raises(TypeError, np.inner, A, c)
+
+    def test_inner_scalar_and_vector(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            vec = np.array([1, 2], dtype=dt)
+            desired = np.array([3, 6], dtype=dt)
+            assert_equal(np.inner(vec, sca), desired)
+            assert_equal(np.inner(sca, vec), desired)
+
+    def test_inner_scalar_and_matrix(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            arr = np.matrix([[1, 2], [3, 4]], dtype=dt)
+            desired = np.matrix([[3, 6], [9, 12]], dtype=dt)
+            assert_equal(np.inner(arr, sca), desired)
+            assert_equal(np.inner(sca, arr), desired)
+
+    def test_inner_scalar_and_matrix_of_objects(self):
+        # Ticket #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.inner(arr, 3), desired)
+        assert_equal(np.inner(3, arr), desired)
+
+    def test_vecself(self):
+        # Ticket 844.
+        # Inner product of a vector with itself segfaults or give
+        # meaningless result
+        a = np.zeros(shape=(1, 80), dtype=np.float64)
+        p = np.inner(a, a)
+        assert_almost_equal(p, 0, decimal=14)
+
+    def test_inner_product_with_various_contiguities(self):
+        # github issue 6532
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            # check an inner product involving a matrix transpose
+            A = np.array([[1, 2], [3, 4]], dtype=dt)
+            B = np.array([[1, 3], [2, 4]], dtype=dt)
+            C = np.array([1, 1], dtype=dt)
+            desired = np.array([4, 6], dtype=dt)
+            assert_equal(np.inner(A.T, C), desired)
+            assert_equal(np.inner(C, A.T), desired)
+            assert_equal(np.inner(B, C), desired)
+            assert_equal(np.inner(C, B), desired)
+            # check a matrix product
+            desired = np.array([[7, 10], [15, 22]], dtype=dt)
+            assert_equal(np.inner(A, B), desired)
+            # check the syrk vs. gemm paths
+            desired = np.array([[5, 11], [11, 25]], dtype=dt)
+            assert_equal(np.inner(A, A), desired)
+            assert_equal(np.inner(A, A.copy()), desired)
+            # check an inner product involving an aliased and reversed view
+            a = np.arange(5).astype(dt)
+            b = a[::-1]
+            desired = np.array(10, dtype=dt).item()
+            assert_equal(np.inner(b, a), desired)
+
+    def test_3d_tensor(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            a = np.arange(24).reshape(2,3,4).astype(dt)
+            b = np.arange(24, 48).reshape(2,3,4).astype(dt)
+            desired = np.array(
+                [[[[ 158,  182,  206],
+                   [ 230,  254,  278]],
+
+                  [[ 566,  654,  742],
+                   [ 830,  918, 1006]],
+
+                  [[ 974, 1126, 1278],
+                   [1430, 1582, 1734]]],
+
+                 [[[1382, 1598, 1814],
+                   [2030, 2246, 2462]],
+
+                  [[1790, 2070, 2350],
+                   [2630, 2910, 3190]],
+
+                  [[2198, 2542, 2886],
+                   [3230, 3574, 3918]]]],
+                dtype=dt
+            )
+            assert_equal(np.inner(a, b), desired)
+            assert_equal(np.inner(b, a).transpose(2,3,0,1), desired)
+
+
+class TestSummarization(TestCase):
+    def test_1d(self):
+        A = np.arange(1001)
+        strA = '[   0    1    2 ...,  998  999 1000]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([   0,    1,    2, ...,  998,  999, 1000])'
+        assert_(repr(A) == reprA)
+
+    def test_2d(self):
+        A = np.arange(1002).reshape(2, 501)
+        strA = '[[   0    1    2 ...,  498  499  500]\n' \
+               ' [ 501  502  503 ...,  999 1000 1001]]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([[   0,    1,    2, ...,  498,  499,  500],\n' \
+                '       [ 501,  502,  503, ...,  999, 1000, 1001]])'
+        assert_(repr(A) == reprA)
+
+
+class TestAlen(TestCase):
+    def test_basic(self):
+        m = np.array([1, 2, 3])
+        self.assertEqual(np.alen(m), 3)
+
+        m = np.array([[1, 2, 3], [4, 5, 7]])
+        self.assertEqual(np.alen(m), 2)
+
+        m = [1, 2, 3]
+        self.assertEqual(np.alen(m), 3)
+
+        m = [[1, 2, 3], [4, 5, 7]]
+        self.assertEqual(np.alen(m), 2)
+
+    def test_singleton(self):
+        self.assertEqual(np.alen(5), 1)
+
+
+class TestChoose(TestCase):
+    def setUp(self):
+        self.x = 2*np.ones((3,), dtype=int)
+        self.y = 3*np.ones((3,), dtype=int)
+        self.x2 = 2*np.ones((2, 3), dtype=int)
+        self.y2 = 3*np.ones((2, 3), dtype=int)
+        self.ind = [0, 0, 1]
+
+    def test_basic(self):
+        A = np.choose(self.ind, (self.x, self.y))
+        assert_equal(A, [2, 2, 3])
+
+    def test_broadcast1(self):
+        A = np.choose(self.ind, (self.x2, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_broadcast2(self):
+        A = np.choose(self.ind, (self.x, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+
+class TestRepeat(TestCase):
+    def setUp(self):
+        self.m = np.array([1, 2, 3, 4, 5, 6])
+        self.m_rect = self.m.reshape((2, 3))
+
+    def test_basic(self):
+        A = np.repeat(self.m, [1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+    def test_broadcast1(self):
+        A = np.repeat(self.m, 2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+    def test_axis_spec(self):
+        A = np.repeat(self.m_rect, [2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, [1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+    def test_broadcast2(self):
+        A = np.repeat(self.m_rect, 2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, 2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+
+# TODO: test for multidimensional
+NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4}
+
+
+class TestNeighborhoodIter(TestCase):
+    # Simple, 2d tests
+    def _test_simple2d(self, dt):
+        # Test zero and one padding for simple data type
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt),
+             np.array([[0, 0, 0], [0, 1, 0]], dtype=dt),
+             np.array([[0, 0, 1], [0, 2, 3]], dtype=dt),
+             np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt),
+             np.array([[1, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[1, 0, 1], [1, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt),
+             np.array([[4, 4, 4], [0, 1, 4]], dtype=dt),
+             np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
+             np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], 4,
+                NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple2d(self):
+        self._test_simple2d(np.float)
+
+    def test_simple2d_object(self):
+        self._test_simple2d(Decimal)
+
+    def _test_mirror2d(self, dt):
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
+             np.array([[0, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[0, 0, 1], [2, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    def test_mirror2d(self):
+        self._test_mirror2d(np.float)
+
+    def test_mirror2d_object(self):
+        self._test_mirror2d(Decimal)
+
+    # Simple, 1d tests
+    def _test_simple(self, dt):
+        # Test padding with constant values
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[4], NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple_float(self):
+        self._test_simple(np.float)
+
+    def test_simple_object(self):
+        self._test_simple(Decimal)
+
+    # Test mirror modes
+    def _test_mirror(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[1], NEIGH_MODE['mirror'])
+        self.assertTrue([i.dtype == dt for i in l])
+        assert_array_equal(l, r)
+
+    def test_mirror(self):
+        self._test_mirror(np.float)
+
+    def test_mirror_object(self):
+        self._test_mirror(Decimal)
+
+    # Circular mode
+    def _test_circular(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    def test_circular(self):
+        self._test_circular(np.float)
+
+    def test_circular_object(self):
+        self._test_circular(Decimal)
+
+# Test stacking neighborhood iterators
+class TestStackedNeighborhoodIter(TestCase):
+    # Simple, 1d test: stacking 2 constant-padded neigh iterators
+    def test_simple_const(self):
+        dt = np.float64
+        # Test zero and one padding for simple data type
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([1], dtype=dt),
+             np.array([2], dtype=dt),
+             np.array([3], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-2, 4], NEIGH_MODE['zero'],
+                [0, 0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([1, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-1, 1], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+    # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # mirror padding
+    def test_simple_mirror(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 1], dtype=dt),
+             np.array([1, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 3], dtype=dt),
+             np.array([3, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['mirror'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # circular padding
+    def test_simple_circular(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 3, 1], dtype=dt),
+             np.array([3, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 1], dtype=dt),
+             np.array([3, 1, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['circular'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator
+    # being strictly within the array
+    def test_simple_strict_within(self):
+        dt = np.float64
+        # Stacking zero on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+class TestWarnings(object):
+
+    def test_complex_warning(self):
+        x = np.array([1, 2])
+        y = np.array([1-2j, 1+2j])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", np.ComplexWarning)
+            assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y)
+            assert_equal(x, [1, 2])
+
+
+class TestMinScalarType(object):
+
+    def test_usigned_shortshort(self):
+        dt = np.min_scalar_type(2**8-1)
+        wanted = np.dtype('uint8')
+        assert_equal(wanted, dt)
+
+    def test_usigned_short(self):
+        dt = np.min_scalar_type(2**16-1)
+        wanted = np.dtype('uint16')
+        assert_equal(wanted, dt)
+
+    def test_usigned_int(self):
+        dt = np.min_scalar_type(2**32-1)
+        wanted = np.dtype('uint32')
+        assert_equal(wanted, dt)
+
+    def test_usigned_longlong(self):
+        dt = np.min_scalar_type(2**63-1)
+        wanted = np.dtype('uint64')
+        assert_equal(wanted, dt)
+
+    def test_object(self):
+        dt = np.min_scalar_type(2**64)
+        wanted = np.dtype('O')
+        assert_equal(wanted, dt)
+
+
+if sys.version_info[:2] == (2, 6):
+    from numpy.core.multiarray import memorysimpleview as memoryview
+
+from numpy.core._internal import _dtype_from_pep3118
+
+
+class TestPEP3118Dtype(object):
+    def _check(self, spec, wanted):
+        dt = np.dtype(wanted)
+        if isinstance(wanted, list) and isinstance(wanted[-1], tuple):
+            if wanted[-1][0] == '':
+                names = list(dt.names)
+                names[-1] = ''
+                dt.names = tuple(names)
+        assert_equal(_dtype_from_pep3118(spec), dt,
+                     err_msg="spec %r != dtype %r" % (spec, wanted))
+
+    def test_native_padding(self):
+        align = np.dtype('i').alignment
+        for j in range(8):
+            if j == 0:
+                s = 'bi'
+            else:
+                s = 'b%dxi' % j
+            self._check('@'+s, {'f0': ('i1', 0),
+                                'f1': ('i', align*(1 + j//align))})
+            self._check('='+s, {'f0': ('i1', 0),
+                                'f1': ('i', 1+j)})
+
+    def test_native_padding_2(self):
+        # Native padding should work also for structs and sub-arrays
+        self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
+        self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
+
+    def test_trailing_padding(self):
+        # Trailing padding should be included, *and*, the item size
+        # should match the alignment if in aligned mode
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('ix', [('f0', 'i'), ('', VV(1))])
+        self._check('ixx', [('f0', 'i'), ('', VV(2))])
+        self._check('ixxx', [('f0', 'i'), ('', VV(3))])
+        self._check('ixxxx', [('f0', 'i'), ('', VV(4))])
+        self._check('i7x', [('f0', 'i'), ('', VV(7))])
+
+        self._check('^ix', [('f0', 'i'), ('', 'V1')])
+        self._check('^ixx', [('f0', 'i'), ('', 'V2')])
+        self._check('^ixxx', [('f0', 'i'), ('', 'V3')])
+        self._check('^ixxxx', [('f0', 'i'), ('', 'V4')])
+        self._check('^i7x', [('f0', 'i'), ('', 'V7')])
+
+    def test_native_padding_3(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'),
+                    ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
+
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
+
+    def test_padding_with_array_inside_struct(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)),
+                    ('d', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
+
+    def test_byteorder_inside_struct(self):
+        # The byte order after @T{=i} should be '=', not '@'.
+        # Check this by noting the absence of native alignment.
+        self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0),
+                                 'f1': ('i', 5)})
+
+    def test_intra_padding(self):
+        # Natively aligned sub-arrays may require some internal padding
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('(3)T{ix}', ({'f0': ('i', 0), '': (VV(1), 4)}, (3,)))
+
+
+class TestNewBufferProtocol(object):
+    def _check_roundtrip(self, obj):
+        obj = np.asarray(obj)
+        x = memoryview(obj)
+        y = np.asarray(x)
+        y2 = np.array(x)
+        assert_(not y.flags.owndata)
+        assert_(y2.flags.owndata)
+
+        assert_equal(y.dtype, obj.dtype)
+        assert_equal(y.shape, obj.shape)
+        assert_array_equal(obj, y)
+
+        assert_equal(y2.dtype, obj.dtype)
+        assert_equal(y2.shape, obj.shape)
+        assert_array_equal(obj, y2)
+
+    def test_roundtrip(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i4')
+        self._check_roundtrip(x)
+
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        self._check_roundtrip(x)
+
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        self._check_roundtrip(x)
+
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('xxx'), True, 1.0)],
+                dtype=dt)
+        self._check_roundtrip(x)
+
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))])
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i4')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i4')
+        self._check_roundtrip(x)
+
+        # check long long can be represented as non-native
+        x = np.array([1, 2, 3], dtype='>q')
+        self._check_roundtrip(x)
+
+        # Native-only data types can be passed through the buffer interface
+        # only in native byte order
+        if sys.byteorder == 'little':
+            x = np.array([1, 2, 3], dtype='>g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+            x = np.array([1, 2, 3], dtype='<g')
+            self._check_roundtrip(x)
+        else:
+            x = np.array([1, 2, 3], dtype='>g')
+            self._check_roundtrip(x)
+            x = np.array([1, 2, 3], dtype='<g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+
+    def test_roundtrip_half(self):
+        half_list = [
+            1.0,
+            -2.0,
+            6.5504 * 10**4,  # (max half precision)
+            2**-14,  # ~= 6.10352 * 10**-5 (minimum positive normal)
+            2**-24,  # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
+            0.0,
+            -0.0,
+            float('+inf'),
+            float('-inf'),
+            0.333251953125,  # ~= 1/3
+        ]
+
+        x = np.array(half_list, dtype='>e')
+        self._check_roundtrip(x)
+        x = np.array(half_list, dtype='<e')
+        self._check_roundtrip(x)
+
+    def test_roundtrip_single_types(self):
+        for typ in np.typeDict.values():
+            dtype = np.dtype(typ)
+
+            if dtype.char in 'Mm':
+                # datetimes cannot be used in buffers
+                continue
+            if dtype.char == 'V':
+                # skip void
+                continue
+
+            x = np.zeros(4, dtype=dtype)
+            self._check_roundtrip(x)
+
+            if dtype.char not in 'qQgG':
+                dt = dtype.newbyteorder('<')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+                dt = dtype.newbyteorder('>')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+    def test_roundtrip_scalar(self):
+        # Issue #4015.
+        self._check_roundtrip(0)
+
+    def test_export_simple_1d(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i')
+        y = memoryview(x)
+        assert_equal(y.format, 'i')
+        assert_equal(y.shape, (5,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.strides, (4,))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_simple_nd(self):
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        y = memoryview(x)
+        assert_equal(y.format, 'd')
+        assert_equal(y.shape, (2, 2))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (16, 8))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 8)
+
+    def test_export_discontiguous(self):
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        y = memoryview(x)
+        assert_equal(y.format, 'f')
+        assert_equal(y.shape, (3, 3))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (36, 4))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_record(self):
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('   '), True, 1.0)],
+                dtype=dt)
+        y = memoryview(x)
+        assert_equal(y.shape, (1,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.suboffsets, EMPTY)
+
+        sz = sum([np.dtype(b).itemsize for a, b in dt])
+        if np.dtype('l').itemsize == 4:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        else:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides
+        if not (np.ones(1).strides[0] == np.iinfo(np.intp).max):
+            assert_equal(y.strides, (sz,))
+        assert_equal(y.itemsize, sz)
+
+    def test_export_subarray(self):
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))])
+        y = memoryview(x)
+        assert_equal(y.format, 'T{(2,2)i:a:}')
+        assert_equal(y.shape, EMPTY)
+        assert_equal(y.ndim, 0)
+        assert_equal(y.strides, EMPTY)
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 16)
+
+    def test_export_endian(self):
+        x = np.array([1, 2, 3], dtype='>i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, '>i')
+        else:
+            assert_equal(y.format, 'i')
+
+        x = np.array([1, 2, 3], dtype='<i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, 'i')
+        else:
+            assert_equal(y.format, '<i')
+
+    def test_export_flags(self):
+        # Check SIMPLE flag, see also gh-3613 (exception should be BufferError)
+        assert_raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
+
+    def test_padding(self):
+        for j in range(8):
+            x = np.array([(1,), (2,)], dtype={'f0': (int, j)})
+            self._check_roundtrip(x)
+
+    def test_reference_leak(self):
+        count_1 = sys.getrefcount(np.core._internal)
+        a = np.zeros(4)
+        b = memoryview(a)
+        c = np.asarray(b)
+        count_2 = sys.getrefcount(np.core._internal)
+        assert_equal(count_1, count_2)
+        del c  # avoid pyflakes unused variable warning.
+
+    def test_padded_struct_array(self):
+        dt1 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        x1 = np.arange(dt1.itemsize, dtype=np.int8).view(dt1)
+        self._check_roundtrip(x1)
+
+        dt2 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')],
+                align=True)
+        x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
+        self._check_roundtrip(x2)
+
+        dt3 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
+        self._check_roundtrip(x3)
+
+    def test_relaxed_strides(self):
+        # Test that relaxed strides are converted to non-relaxed
+        c = np.ones((1, 10, 10), dtype='i8')
+
+        # Check for NPY_RELAXED_STRIDES_CHECKING:
+        if np.ones((10, 1), order="C").flags.f_contiguous:
+            c.strides = (-1, 80, 8)
+
+        assert_(memoryview(c).strides == (800, 80, 8))
+
+        # Writing C-contiguous data to a BytesIO buffer should work
+        fd = io.BytesIO()
+        fd.write(c.data)
+
+        fortran = c.T
+        assert_(memoryview(fortran).strides == (8, 80, 800))
+
+        arr = np.ones((1, 10))
+        if arr.flags.f_contiguous:
+            shape, strides = get_buffer_info(arr, ['F_CONTIGUOUS'])
+            assert_(strides[0] == 8)
+            arr = np.ones((10, 1), order='F')
+            shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
+            assert_(strides[-1] == 8)
+
+
+class TestArrayAttributeDeletion(object):
+
+    def test_multiarray_writable_attributes_deletion(self):
+        """ticket #2046, should not seqfault, raise AttributeError"""
+        a = np.ones(2)
+        attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_not_writable_attributes_deletion(self):
+        a = np.ones(2)
+        attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
+                "ctypes", "T", "__array_interface__", "__array_struct__",
+                "__array_priority__", "__array_finalize__"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ['updateifcopy', 'aligned', 'writeable']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_not_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
+                "owndata", "fnc", "forc", "behaved", "carray", "farray",
+                "num"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+
+def test_array_interface():
+    # Test scalar coercion within the array interface
+    class Foo(object):
+        def __init__(self, value):
+            self.value = value
+            self.iface = {'typestr': '=f8'}
+
+        def __float__(self):
+            return float(self.value)
+
+        @property
+        def __array_interface__(self):
+            return self.iface
+
+    f = Foo(0.5)
+    assert_equal(np.array(f), 0.5)
+    assert_equal(np.array([f]), [0.5])
+    assert_equal(np.array([f, f]), [0.5, 0.5])
+    assert_equal(np.array(f).dtype, np.dtype('=f8'))
+    # Test various shape definitions
+    f.iface['shape'] = ()
+    assert_equal(np.array(f), 0.5)
+    f.iface['shape'] = None
+    assert_raises(TypeError, np.array, f)
+    f.iface['shape'] = (1, 1)
+    assert_equal(np.array(f), [[0.5]])
+    f.iface['shape'] = (2,)
+    assert_raises(ValueError, np.array, f)
+
+    # test scalar with no shape
+    class ArrayLike(object):
+        array = np.array(1)
+        __array_interface__ = array.__array_interface__
+    assert_equal(np.array(ArrayLike()), 1)
+
+
+def test_array_interface_itemsize():
+    # See gh-6361
+    my_dtype = np.dtype({'names': ['A', 'B'], 'formats': ['f4', 'f4'],
+                         'offsets': [0, 8], 'itemsize': 16})
+    a = np.ones(10, dtype=my_dtype)
+    descr_t = np.dtype(a.__array_interface__['descr'])
+    typestr_t = np.dtype(a.__array_interface__['typestr'])
+    assert_equal(descr_t.itemsize, typestr_t.itemsize)
+
+
+def test_flat_element_deletion():
+    it = np.ones(3).flat
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+
+def test_scalar_element_deletion():
+    a = np.zeros(2, dtype=[('x', 'int'), ('y', 'int')])
+    assert_raises(ValueError, a[0].__delitem__, 'x')
+
+
+class TestMemEventHook(TestCase):
+    def test_mem_seteventhook(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+        test_pydatamem_seteventhook_start()
+        # force an allocation and free of a numpy array
+        # needs to be larger then limit of small memory cacher in ctors.c
+        a = np.zeros(1000)
+        del a
+        test_pydatamem_seteventhook_end()
+
+class TestMapIter(TestCase):
+    def test_mapiter(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+
+        a = np.arange(12).reshape((3, 4)).astype(float)
+        index = ([1, 1, 2, 0],
+                 [0, 0, 2, 3])
+        vals = [50, 50, 30, 16]
+
+        test_inplace_increment(a, index, vals)
+        assert_equal(a, [[0.00, 1., 2.0, 19.],
+                         [104., 5., 6.0, 7.0],
+                         [8.00, 9., 40., 11.]])
+
+        b = np.arange(6).astype(float)
+        index = (np.array([1, 2, 0]),)
+        vals = [50, 4, 100.1]
+        test_inplace_increment(b, index, vals)
+        assert_equal(b, [100.1,  51.,   6.,   3.,   4.,   5.])
+
+
+class TestAsCArray(TestCase):
+    def test_1darray(self):
+        array = np.arange(24, dtype=np.double)
+        from_c = test_as_c_array(array, 3)
+        assert_equal(array[3], from_c)
+
+    def test_2darray(self):
+        array = np.arange(24, dtype=np.double).reshape(3, 8)
+        from_c = test_as_c_array(array, 2, 4)
+        assert_equal(array[2, 4], from_c)
+
+    def test_3darray(self):
+        array = np.arange(24, dtype=np.double).reshape(2, 3, 4)
+        from_c = test_as_c_array(array, 1, 2, 3)
+        assert_equal(array[1, 2, 3], from_c)
+
+
+class TestConversion(TestCase):
+    def test_array_scalar_relational_operation(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+
+            # Unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+class TestWhere(TestCase):
+    def test_basic(self):
+        dts = [np.bool, np.int16, np.int32, np.int64, np.double, np.complex128,
+               np.longdouble, np.clongdouble]
+        for dt in dts:
+            c = np.ones(53, dtype=np.bool)
+            assert_equal(np.where( c, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(~c, dt(0), dt(1)), dt(1))
+            assert_equal(np.where(True, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(False, dt(0), dt(1)), dt(1))
+            d = np.ones_like(c).astype(dt)
+            e = np.zeros_like(d)
+            r = d.astype(dt)
+            c[7] = False
+            r[7] = e[7]
+            assert_equal(np.where(c, e, e), e)
+            assert_equal(np.where(c, d, e), r)
+            assert_equal(np.where(c, d, e[0]), r)
+            assert_equal(np.where(c, d[0], e), r)
+            assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2])
+            assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2])
+            assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3])
+            assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3])
+            assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2])
+            assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3])
+            assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3])
+
+    def test_exotic(self):
+        # object
+        assert_array_equal(np.where(True, None, None), np.array(None))
+        # zero sized
+        m = np.array([], dtype=bool).reshape(0, 3)
+        b = np.array([], dtype=np.float64).reshape(0, 3)
+        assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3))
+
+        # object cast
+        d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313,
+                      0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013,
+                      1.267, 0.229, -1.39, 0.487])
+        nan = float('NaN')
+        e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan,
+                     'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'],
+                     dtype=object)
+        m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+                      0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool)
+
+        r = e[:]
+        r[np.where(m)] = d[np.where(m)]
+        assert_array_equal(np.where(m, d, e), r)
+
+        r = e[:]
+        r[np.where(~m)] = d[np.where(~m)]
+        assert_array_equal(np.where(m, e, d), r)
+
+        assert_array_equal(np.where(m, e, e), e)
+
+        # minimal dtype result with NaN scalar (e.g required by pandas)
+        d = np.array([1., 2.], dtype=np.float32)
+        e = float('NaN')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('-Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        # also check upcast
+        e = float(1e150)
+        assert_equal(np.where(True, d, e).dtype, np.float64)
+
+    def test_ndim(self):
+        c = [True, False]
+        a = np.zeros((2, 25))
+        b = np.ones((2, 25))
+        r = np.where(np.array(c)[:,np.newaxis], a, b)
+        assert_array_equal(r[0], a[0])
+        assert_array_equal(r[1], b[0])
+
+        a = a.T
+        b = b.T
+        r = np.where(c, a, b)
+        assert_array_equal(r[:,0], a[:,0])
+        assert_array_equal(r[:,1], b[:,0])
+
+    def test_dtype_mix(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        a = np.uint32(1)
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                      dtype=np.float64)
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype(np.float32)
+        b = b.astype(np.int64)
+        assert_equal(np.where(c, a, b), r)
+
+        # non bool mask
+        c = c.astype(np.int)
+        c[c != 0] = 34242324
+        assert_equal(np.where(c, a, b), r)
+        # invert
+        tmpmask = c != 0
+        c[c == 0] = 41247212
+        c[tmpmask] = 0
+        assert_equal(np.where(c, b, a), r)
+
+    def test_foreign(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        a = np.ones(1, dtype='>i4')
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        b = b.astype('>f8')
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype('<i4')
+        assert_equal(np.where(c, a, b), r)
+
+        c = c.astype('>i4')
+        assert_equal(np.where(c, a, b), r)
+
+    def test_error(self):
+        c = [True, True]
+        a = np.ones((4, 5))
+        b = np.ones((5, 5))
+        assert_raises(ValueError, np.where, c, a, a)
+        assert_raises(ValueError, np.where, c[0], a, b)
+
+    def test_string(self):
+        # gh-4778 check strings are properly filled with nulls
+        a = np.array("abc")
+        b = np.array("x" * 753)
+        assert_equal(np.where(True, a, b), "abc")
+        assert_equal(np.where(False, b, a), "abc")
+
+        # check native datatype sized strings
+        a = np.array("abcd")
+        b = np.array("x" * 8)
+        assert_equal(np.where(True, a, b), "abcd")
+        assert_equal(np.where(False, b, a), "abcd")
+
+
+class TestSizeOf(TestCase):
+
+    def test_empty_array(self):
+        x = np.array([])
+        assert_(sys.getsizeof(x) > 0)
+
+    def check_array(self, dtype):
+        elem_size = dtype(0).itemsize
+
+        for length in [10, 50, 100, 500]:
+            x = np.arange(length, dtype=dtype)
+            assert_(sys.getsizeof(x) > length * elem_size)
+
+    def test_array_int32(self):
+        self.check_array(np.int32)
+
+    def test_array_int64(self):
+        self.check_array(np.int64)
+
+    def test_array_float32(self):
+        self.check_array(np.float32)
+
+    def test_array_float64(self):
+        self.check_array(np.float64)
+
+    def test_view(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d[...]) < sys.getsizeof(d))
+
+    def test_reshape(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy()))
+
+    def test_resize(self):
+        d = np.ones(100)
+        old = sys.getsizeof(d)
+        d.resize(50)
+        assert_(old > sys.getsizeof(d))
+        d.resize(150)
+        assert_(old < sys.getsizeof(d))
+
+    def test_error(self):
+        d = np.ones(100)
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestHashing(TestCase):
+
+    def test_arrays_not_hashable(self):
+        x = np.ones(3)
+        assert_raises(TypeError, hash, x)
+
+    def test_collections_hashable(self):
+        x = np.array([])
+        self.assertFalse(isinstance(x, collections.Hashable))
+
+
+class TestArrayPriority(TestCase):
+    # This will go away when __array_priority__ is settled, meanwhile
+    # it serves to check unintended changes.
+    op = operator
+    binary_ops = [
+        op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod,
+        op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt,
+        op.ge, op.lt, op.le, op.ne, op.eq
+        ]
+
+    if sys.version_info[0] < 3:
+        binary_ops.append(op.div)
+
+    class Foo(np.ndarray):
+        __array_priority__ = 100.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Bar(np.ndarray):
+        __array_priority__ = 101.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Other(object):
+        __array_priority__ = 1000.
+
+        def _all(self, other):
+            return self.__class__()
+
+        __add__ = __radd__ = _all
+        __sub__ = __rsub__ = _all
+        __mul__ = __rmul__ = _all
+        __pow__ = __rpow__ = _all
+        __div__ = __rdiv__ = _all
+        __mod__ = __rmod__ = _all
+        __truediv__ = __rtruediv__ = _all
+        __floordiv__ = __rfloordiv__ = _all
+        __and__ = __rand__ = _all
+        __xor__ = __rxor__ = _all
+        __or__ = __ror__ = _all
+        __lshift__ = __rlshift__ = _all
+        __rshift__ = __rrshift__ = _all
+        __eq__ = _all
+        __ne__ = _all
+        __gt__ = _all
+        __ge__ = _all
+        __lt__ = _all
+        __le__ = _all
+
+    def test_ndarray_subclass(self):
+        a = np.array([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_ndarray_other(self):
+        a = np.array([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+    def test_subclass_subclass(self):
+        a = self.Foo([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_subclass_other(self):
+        a = self.Foo([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+
+class TestBytestringArrayNonzero(TestCase):
+
+    def test_empty_bstring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.str))
+
+    def test_whitespace_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_bstring_array_is_truthy(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+class TestUnicodeArrayNonzero(TestCase):
+
+    def test_empty_ustring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.unicode))
+
+    def test_whitespace_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_ustring_array_is_truthy(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
new file mode 100644
index 0000000000..c73a0f3a66
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
@@ -0,0 +1,6386 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+import tempfile
+import sys
+import shutil
+import warnings
+import operator
+import io
+import itertools
+import ctypes
+import os
+if sys.version_info[0] >= 3:
+    import builtins
+else:
+    import __builtin__ as builtins
+from decimal import Decimal
+
+
+import numpy as np
+from numpy.compat import asbytes, getexception, strchar, unicode, sixu
+from test_print import in_foreign_locale
+from numpy.core.multiarray_tests import (
+    test_neighborhood_iterator, test_neighborhood_iterator_oob,
+    test_pydatamem_seteventhook_start, test_pydatamem_seteventhook_end,
+    test_inplace_increment, get_buffer_info, test_as_c_array
+    )
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_raises,
+    assert_equal, assert_almost_equal, assert_array_equal,
+    assert_array_almost_equal, assert_allclose,
+    assert_array_less, runstring, dec, SkipTest
+    )
+
+# Need to test an object that does not fully implement math interface
+from datetime import timedelta
+
+
+if sys.version_info[:2] > (3, 2):
+    # In Python 3.3 the representation of empty shape, strides and sub-offsets
+    # is an empty tuple instead of None.
+    # http://docs.python.org/dev/whatsnew/3.3.html#api-changes
+    EMPTY = ()
+else:
+    EMPTY = None
+
+
+class TestFlags(TestCase):
+    def setUp(self):
+        self.a = np.arange(10)
+
+    def test_writeable(self):
+        mydict = locals()
+        self.a.flags.writeable = False
+        self.assertRaises(ValueError, runstring, 'self.a[0] = 3', mydict)
+        self.assertRaises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict)
+        self.a.flags.writeable = True
+        self.a[0] = 5
+        self.a[0] = 0
+
+    def test_otherflags(self):
+        assert_equal(self.a.flags.carray, True)
+        assert_equal(self.a.flags.farray, False)
+        assert_equal(self.a.flags.behaved, True)
+        assert_equal(self.a.flags.fnc, False)
+        assert_equal(self.a.flags.forc, True)
+        assert_equal(self.a.flags.owndata, True)
+        assert_equal(self.a.flags.writeable, True)
+        assert_equal(self.a.flags.aligned, True)
+        assert_equal(self.a.flags.updateifcopy, False)
+
+    def test_string_align(self):
+        a = np.zeros(4, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+        # not power of two are accessed byte-wise and thus considered aligned
+        a = np.zeros(5, dtype=np.dtype('|S4'))
+        assert_(a.flags.aligned)
+
+    def test_void_align(self):
+        a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")]))
+        assert_(a.flags.aligned)
+
+
+class TestHash(TestCase):
+    # see #3793
+    def test_int(self):
+        for st, ut, s in [(np.int8, np.uint8, 8),
+                          (np.int16, np.uint16, 16),
+                          (np.int32, np.uint32, 32),
+                          (np.int64, np.uint64, 64)]:
+            for i in range(1, s):
+                assert_equal(hash(st(-2**i)), hash(-2**i),
+                             err_msg="%r: -2**%d" % (st, i))
+                assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (st, i - 1))
+                assert_equal(hash(st(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (st, i))
+
+                i = max(i - 1, 1)
+                assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)),
+                             err_msg="%r: 2**%d" % (ut, i - 1))
+                assert_equal(hash(ut(2**i - 1)), hash(2**i - 1),
+                             err_msg="%r: 2**%d - 1" % (ut, i))
+
+
+class TestAttributes(TestCase):
+    def setUp(self):
+        self.one = np.arange(10)
+        self.two = np.arange(20).reshape(4, 5)
+        self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6)
+
+    def test_attributes(self):
+        assert_equal(self.one.shape, (10,))
+        assert_equal(self.two.shape, (4, 5))
+        assert_equal(self.three.shape, (2, 5, 6))
+        self.three.shape = (10, 3, 2)
+        assert_equal(self.three.shape, (10, 3, 2))
+        self.three.shape = (2, 5, 6)
+        assert_equal(self.one.strides, (self.one.itemsize,))
+        num = self.two.itemsize
+        assert_equal(self.two.strides, (5*num, num))
+        num = self.three.itemsize
+        assert_equal(self.three.strides, (30*num, 6*num, num))
+        assert_equal(self.one.ndim, 1)
+        assert_equal(self.two.ndim, 2)
+        assert_equal(self.three.ndim, 3)
+        num = self.two.itemsize
+        assert_equal(self.two.size, 20)
+        assert_equal(self.two.nbytes, 20*num)
+        assert_equal(self.two.itemsize, self.two.dtype.itemsize)
+        assert_equal(self.two.base, np.arange(20))
+
+    def test_dtypeattr(self):
+        assert_equal(self.one.dtype, np.dtype(np.int_))
+        assert_equal(self.three.dtype, np.dtype(np.float_))
+        assert_equal(self.one.dtype.char, 'l')
+        assert_equal(self.three.dtype.char, 'd')
+        self.assertTrue(self.three.dtype.str[0] in '<>')
+        assert_equal(self.one.dtype.str[1], 'i')
+        assert_equal(self.three.dtype.str[1], 'f')
+
+    def test_int_subclassing(self):
+        # Regression test for https://github.com/numpy/numpy/pull/3526
+
+        numpy_int = np.int_(0)
+
+        if sys.version_info[0] >= 3:
+            # On Py3k int_ should not inherit from int, because it's not
+            # fixed-width anymore
+            assert_equal(isinstance(numpy_int, int), False)
+        else:
+            # Otherwise, it should inherit from int...
+            assert_equal(isinstance(numpy_int, int), True)
+
+            # ... and fast-path checks on C-API level should also work
+            from numpy.core.multiarray_tests import test_int_subclass
+            assert_equal(test_int_subclass(numpy_int), True)
+
+    def test_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            return np.ndarray(size, buffer=x, dtype=int,
+                              offset=offset*x.itemsize,
+                              strides=strides*x.itemsize)
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(ValueError, make_array, 8, 3, 1)
+        assert_equal(make_array(8, 3, 0), np.array([3]*8))
+        # Check behavior reported in gh-2503:
+        self.assertRaises(ValueError, make_array, (2, 3), 5, np.array([-2, -3]))
+        make_array(0, 0, 10)
+
+    def test_set_stridesattr(self):
+        x = self.one
+
+        def make_array(size, offset, strides):
+            try:
+                r = np.ndarray([size], dtype=int, buffer=x,
+                               offset=offset*x.itemsize)
+            except:
+                raise RuntimeError(getexception())
+            r.strides = strides = strides*x.itemsize
+            return r
+
+        assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
+        assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9]))
+        self.assertRaises(ValueError, make_array, 4, 4, -2)
+        self.assertRaises(ValueError, make_array, 4, 2, -1)
+        self.assertRaises(RuntimeError, make_array, 8, 3, 1)
+        # Check that the true extent of the array is used.
+        # Test relies on as_strided base not exposing a buffer.
+        x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0))
+
+        def set_strides(arr, strides):
+            arr.strides = strides
+
+        self.assertRaises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize))
+
+        # Test for offset calculations:
+        x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1],
+                                                    shape=(10,), strides=(-1,))
+        self.assertRaises(ValueError, set_strides, x[::-1], -1)
+        a = x[::-1]
+        a.strides = 1
+        a[::2].strides = 2
+
+    def test_fill(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = np.empty((3, 2, 1), t)
+            y = np.empty((3, 2, 1), t)
+            x.fill(1)
+            y[...] = 1
+            assert_equal(x, y)
+
+    def test_fill_max_uint64(self):
+        x = np.empty((3, 2, 1), dtype=np.uint64)
+        y = np.empty((3, 2, 1), dtype=np.uint64)
+        value = 2**64 - 1
+        y[...] = value
+        x.fill(value)
+        assert_array_equal(x, y)
+
+    def test_fill_struct_array(self):
+        # Filling from a scalar
+        x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8')
+        x.fill(x[0])
+        assert_equal(x['f1'][1], x['f1'][0])
+        # Filling from a tuple that can be converted
+        # to a scalar
+        x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')])
+        x.fill((3.5, -2))
+        assert_array_equal(x['a'], [3.5, 3.5])
+        assert_array_equal(x['b'], [-2, -2])
+
+
+class TestArrayConstruction(TestCase):
+    def test_array(self):
+        d = np.ones(6)
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6)))
+
+        d = np.ones(6)
+        tgt = np.ones((2, 6))
+        r = np.array([d, d])
+        assert_equal(r, tgt)
+        tgt[1] = 2
+        r = np.array([d, d + 1])
+        assert_equal(r, tgt)
+
+        d = np.ones(6)
+        r = np.array([[d, d]])
+        assert_equal(r, np.ones((1, 2, 6)))
+
+        d = np.ones(6)
+        r = np.array([[d, d], [d, d]])
+        assert_equal(r, np.ones((2, 2, 6)))
+
+        d = np.ones((6, 6))
+        r = np.array([d, d])
+        assert_equal(r, np.ones((2, 6, 6)))
+
+        d = np.ones((6, ))
+        r = np.array([[d, d + 1], d + 2])
+        assert_equal(len(r), 2)
+        assert_equal(r[0], [d, d + 1])
+        assert_equal(r[1], d + 2)
+
+        tgt = np.ones((2, 3), dtype=np.bool)
+        tgt[0, 2] = False
+        tgt[1, 0:2] = False
+        r = np.array([[True, True, False], [False, False, True]])
+        assert_equal(r, tgt)
+        r = np.array([[True, False], [True, False], [False, True]])
+        assert_equal(r, tgt.T)
+
+    def test_array_empty(self):
+        assert_raises(TypeError, np.array)
+
+    def test_array_copy_false(self):
+        d = np.array([1, 2, 3])
+        e = np.array(d, copy=False)
+        d[1] = 3
+        assert_array_equal(e, [1, 3, 3])
+        e = np.array(d, copy=False, order='F')
+        d[1] = 4
+        assert_array_equal(e, [1, 4, 3])
+        e[2] = 7
+        assert_array_equal(d, [1, 4, 7])
+
+    def test_array_copy_true(self):
+        d = np.array([[1,2,3], [1, 2, 3]])
+        e = np.array(d, copy=True)
+        d[0, 1] = 3
+        e[0, 2] = -7
+        assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
+        e = np.array(d, copy=True, order='F')
+        d[0, 1] = 5
+        e[0, 2] = 7
+        assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
+        assert_array_equal(d, [[1, 5, 3], [1,2,3]])
+
+    def test_array_cont(self):
+        d = np.ones(10)[::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.ascontiguousarray(d).flags.f_contiguous)
+        assert_(np.asfortranarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+        d = np.ones((10, 10))[::2,::2]
+        assert_(np.ascontiguousarray(d).flags.c_contiguous)
+        assert_(np.asfortranarray(d).flags.f_contiguous)
+
+
+class TestAssignment(TestCase):
+    def test_assignment_broadcasting(self):
+        a = np.arange(6).reshape(2, 3)
+
+        # Broadcasting the input to the output
+        a[...] = np.arange(3)
+        assert_equal(a, [[0, 1, 2], [0, 1, 2]])
+        a[...] = np.arange(2).reshape(2, 1)
+        assert_equal(a, [[0, 0, 0], [1, 1, 1]])
+
+        # For compatibility with <= 1.5, a limited version of broadcasting
+        # the output to the input.
+        #
+        # This behavior is inconsistent with NumPy broadcasting
+        # in general, because it only uses one of the two broadcasting
+        # rules (adding a new "1" dimension to the left of the shape),
+        # applied to the output instead of an input. In NumPy 2.0, this kind
+        # of broadcasting assignment will likely be disallowed.
+        a[...] = np.arange(6)[::-1].reshape(1, 2, 3)
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+        # The other type of broadcasting would require a reduction operation.
+
+        def assign(a, b):
+            a[...] = b
+
+        assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3))
+
+    def test_assignment_errors(self):
+        # Address issue #2276
+        class C:
+            pass
+        a = np.zeros(1)
+
+        def assign(v):
+            a[0] = v
+
+        assert_raises((AttributeError, TypeError), assign, C())
+        assert_raises(ValueError, assign, [1])
+
+
+class TestDtypedescr(TestCase):
+    def test_construction(self):
+        d1 = np.dtype('i4')
+        assert_equal(d1, np.dtype(np.int32))
+        d2 = np.dtype('f8')
+        assert_equal(d2, np.dtype(np.float64))
+
+    def test_byteorders(self):
+        self.assertNotEqual(np.dtype('<i4'), np.dtype('>i4'))
+        self.assertNotEqual(np.dtype([('a', '<i4')]), np.dtype([('a', '>i4')]))
+
+
+class TestZeroRank(TestCase):
+    def setUp(self):
+        self.d = np.array(0), np.array('x', object)
+
+    def test_ellipsis_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(b[...], 'x')
+        self.assertTrue(a[...].base is a)  # `a[...] is a` in numpy <1.9.
+        self.assertTrue(b[...].base is b)  # `b[...] is b` in numpy <1.9.
+
+    def test_empty_subscript(self):
+        a, b = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(b[()], 'x')
+        self.assertTrue(type(a[()]) is a.dtype.type)
+        self.assertTrue(type(b[()]) is str)
+
+    def test_invalid_subscript(self):
+        a, b = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[0], b)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], b)
+
+    def test_ellipsis_subscript_assignment(self):
+        a, b = self.d
+        a[...] = 42
+        self.assertEqual(a, 42)
+        b[...] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_empty_subscript_assignment(self):
+        a, b = self.d
+        a[()] = 42
+        self.assertEqual(a, 42)
+        b[()] = ''
+        self.assertEqual(b.item(), '')
+
+    def test_invalid_subscript_assignment(self):
+        a, b = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(IndexError, assign, a, 0, 42)
+        self.assertRaises(IndexError, assign, b, 0, '')
+        self.assertRaises(ValueError, assign, a, (), '')
+
+    def test_newaxis(self):
+        a, b = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a, b = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_constructor(self):
+        x = np.ndarray(())
+        x[()] = 5
+        self.assertEqual(x[()], 5)
+        y = np.ndarray((), buffer=x)
+        y[()] = 6
+        self.assertEqual(x[()], 6)
+
+    def test_output(self):
+        x = np.array(2)
+        self.assertRaises(ValueError, np.add, x, [1], x)
+
+
+class TestScalarIndexing(TestCase):
+    def setUp(self):
+        self.d = np.array([0, 1])[0]
+
+    def test_ellipsis_subscript(self):
+        a = self.d
+        self.assertEqual(a[...], 0)
+        self.assertEqual(a[...].shape, ())
+
+    def test_empty_subscript(self):
+        a = self.d
+        self.assertEqual(a[()], 0)
+        self.assertEqual(a[()].shape, ())
+
+    def test_invalid_subscript(self):
+        a = self.d
+        self.assertRaises(IndexError, lambda x: x[0], a)
+        self.assertRaises(IndexError, lambda x: x[np.array([], int)], a)
+
+    def test_invalid_subscript_assignment(self):
+        a = self.d
+
+        def assign(x, i, v):
+            x[i] = v
+
+        self.assertRaises(TypeError, assign, a, 0, 42)
+
+    def test_newaxis(self):
+        a = self.d
+        self.assertEqual(a[np.newaxis].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ...].shape, (1,))
+        self.assertEqual(a[..., np.newaxis].shape, (1,))
+        self.assertEqual(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
+        self.assertEqual(a[..., np.newaxis, np.newaxis].shape, (1, 1))
+        self.assertEqual(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
+        self.assertEqual(a[(np.newaxis,)*10].shape, (1,)*10)
+
+    def test_invalid_newaxis(self):
+        a = self.d
+
+        def subscript(x, i):
+            x[i]
+
+        self.assertRaises(IndexError, subscript, a, (np.newaxis, 0))
+        self.assertRaises(IndexError, subscript, a, (np.newaxis,)*50)
+
+    def test_overlapping_assignment(self):
+        # With positive strides
+        a = np.arange(4)
+        a[:-1] = a[1:]
+        assert_equal(a, [1, 2, 3, 3])
+
+        a = np.arange(4)
+        a[1:] = a[:-1]
+        assert_equal(a, [0, 0, 1, 2])
+
+        # With positive and negative strides
+        a = np.arange(4)
+        a[:] = a[::-1]
+        assert_equal(a, [3, 2, 1, 0])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1,:] = a[:, ::-1]
+        assert_equal(a, [[5, 4, 3], [2, 1, 0]])
+
+        a = np.arange(6).reshape(2, 3)
+        a[::-1, ::-1] = a[:, ::-1]
+        assert_equal(a, [[3, 4, 5], [0, 1, 2]])
+
+        # With just one element overlapping
+        a = np.arange(5)
+        a[:3] = a[2:]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[:3]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+        a = np.arange(5)
+        a[2::-1] = a[2:]
+        assert_equal(a, [4, 3, 2, 3, 4])
+
+        a = np.arange(5)
+        a[2:] = a[2::-1]
+        assert_equal(a, [0, 1, 2, 1, 0])
+
+        a = np.arange(5)
+        a[2::-1] = a[:1:-1]
+        assert_equal(a, [2, 3, 4, 3, 4])
+
+        a = np.arange(5)
+        a[:1:-1] = a[2::-1]
+        assert_equal(a, [0, 1, 0, 1, 2])
+
+
+class TestCreation(TestCase):
+    def test_from_attribute(self):
+        class x(object):
+            def __array__(self, dtype=None):
+                pass
+
+        self.assertRaises(ValueError, np.array, x())
+
+    def test_from_string(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['Float']
+        nstr = ['123', '123']
+        result = np.array([123, 123], dtype=int)
+        for type in types:
+            msg = 'String conversion for %s' % type
+            assert_equal(np.array(nstr, dtype=type), result, err_msg=msg)
+
+    def test_void(self):
+        arr = np.array([], dtype='V')
+        assert_equal(arr.dtype.kind, 'V')
+
+    def test_zeros(self):
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((13,), dtype=dt)
+            assert_equal(np.count_nonzero(d), 0)
+            # true for ieee floats
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='4i4')
+            assert_equal(np.count_nonzero(d), 0)
+            assert_equal(d.sum(), 0)
+            assert_(not d.any())
+
+            d = np.zeros(2, dtype='(2,4)i4, (2,4)i4')
+            assert_equal(np.count_nonzero(d), 0)
+
+    @dec.slow
+    def test_zeros_big(self):
+        # test big array as they might be allocated different by the system
+        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        for dt in types:
+            d = np.zeros((30 * 1024**2,), dtype=dt)
+            assert_(not d.any())
+            # This test can fail on 32-bit systems due to insufficient
+            # contiguous memory. Deallocating the previous array increases the
+            # chance of success.
+            del(d)
+
+    def test_zeros_obj(self):
+        # test initialization from PyLong(0)
+        d = np.zeros((13,), dtype=object)
+        assert_array_equal(d, [0] * 13)
+        assert_equal(np.count_nonzero(d), 0)
+
+    def test_zeros_obj_obj(self):
+        d = np.zeros(10, dtype=[('k', object, 2)])
+        assert_array_equal(d['k'], 0)
+
+    def test_zeros_like_like_zeros(self):
+        # test zeros_like returns the same as zeros
+        for c in np.typecodes['All']:
+            if c == 'V':
+                continue
+            d = np.zeros((3,3), dtype=c)
+            assert_array_equal(np.zeros_like(d), d)
+            assert_equal(np.zeros_like(d).dtype, d.dtype)
+        # explicitly check some special cases
+        d = np.zeros((3,3), dtype='S5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='U5')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>i4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='<M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+        d = np.zeros((3,3), dtype='>M8[s]')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+        d = np.zeros((3,3), dtype='f4,f4')
+        assert_array_equal(np.zeros_like(d), d)
+        assert_equal(np.zeros_like(d).dtype, d.dtype)
+
+    def test_empty_unicode(self):
+        # don't throw decode errors on garbage memory
+        for i in range(5, 100, 5):
+            d = np.empty(i, dtype='U')
+            str(d)
+
+    def test_sequence_non_homogenous(self):
+        assert_equal(np.array([4, 2**80]).dtype, np.object)
+        assert_equal(np.array([4, 2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80, 4]).dtype, np.object)
+        assert_equal(np.array([2**80] * 3).dtype, np.object)
+        assert_equal(np.array([[1, 1],[1j, 1j]]).dtype, np.complex)
+        assert_equal(np.array([[1j, 1j],[1, 1]]).dtype, np.complex)
+        assert_equal(np.array([[1, 1, 1],[1, 1j, 1.], [1, 1, 1]]).dtype, np.complex)
+
+    @dec.skipif(sys.version_info[0] >= 3)
+    def test_sequence_long(self):
+        assert_equal(np.array([long(4), long(4)]).dtype, np.long)
+        assert_equal(np.array([long(4), 2**80]).dtype, np.object)
+        assert_equal(np.array([long(4), 2**80, long(4)]).dtype, np.object)
+        assert_equal(np.array([2**80, long(4)]).dtype, np.object)
+
+    def test_non_sequence_sequence(self):
+        """Should not segfault.
+
+        Class Fail breaks the sequence protocol for new style classes, i.e.,
+        those derived from object. Class Map is a mapping type indicated by
+        raising a ValueError. At some point we may raise a warning instead
+        of an error in the Fail case.
+
+        """
+        class Fail(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise ValueError()
+
+        class Map(object):
+            def __len__(self):
+                return 1
+
+            def __getitem__(self, index):
+                raise KeyError()
+
+        a = np.array([Map()])
+        assert_(a.shape == (1,))
+        assert_(a.dtype == np.dtype(object))
+        assert_raises(ValueError, np.array, [Fail()])
+
+    def test_no_len_object_type(self):
+        # gh-5100, want object array from iterable object without len()
+        class Point2:
+            def __init__(self):
+                pass
+
+            def __getitem__(self, ind):
+                if ind in [0, 1]:
+                    return ind
+                else:
+                    raise IndexError()
+        d = np.array([Point2(), Point2(), Point2()])
+        assert_equal(d.dtype, np.dtype(object))
+
+    def test_false_len_sequence(self):
+        # gh-7264, segfault for this example
+        class C:
+            def __getitem__(self, i):
+                raise IndexError
+            def __len__(self):
+                return 42
+
+        assert_raises(ValueError, np.array, C()) # segfault?
+
+    def test_failed_len_sequence(self):
+        # gh-7393
+        class A(object):
+            def __init__(self, data):
+                self._data = data
+            def __getitem__(self, item):
+                return type(self)(self._data[item])
+            def __len__(self):
+                return len(self._data)
+
+        # len(d) should give 3, but len(d[0]) will fail
+        d = A([1,2,3])
+        assert_equal(len(np.array(d)), 3)
+
+
+class TestStructured(TestCase):
+    def test_subarray_field_access(self):
+        a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
+        a['a'] = np.arange(60).reshape(3, 5, 2, 2)
+
+        # Since the subarray is always in C-order, a transpose
+        # does not swap the subarray:
+        assert_array_equal(a.T['a'], a['a'].transpose(1, 0, 2, 3))
+
+        # In Fortran order, the subarray gets appended
+        # like in all other cases, not prepended as a special case
+        b = a.copy(order='F')
+        assert_equal(a['a'].shape, b['a'].shape)
+        assert_equal(a.T['a'].shape, a.T.copy()['a'].shape)
+
+    def test_subarray_comparison(self):
+        # Check that comparisons between record arrays with
+        # multi-dimensional field types work properly
+        a = np.rec.fromrecords(
+            [([1, 2, 3], 'a', [[1, 2], [3, 4]]), ([3, 3, 3], 'b', [[0, 0], [0, 0]])],
+            dtype=[('a', ('f4', 3)), ('b', np.object), ('c', ('i4', (2, 2)))])
+        b = a.copy()
+        assert_equal(a == b, [True, True])
+        assert_equal(a != b, [False, False])
+        b[1].b = 'c'
+        assert_equal(a == b, [True, False])
+        assert_equal(a != b, [False, True])
+        for i in range(3):
+            b[0].a = a[0].a
+            b[0].a[i] = 5
+            assert_equal(a == b, [False, False])
+            assert_equal(a != b, [True, True])
+        for i in range(2):
+            for j in range(2):
+                b = a.copy()
+                b[0].c[i, j] = 10
+                assert_equal(a == b, [False, True])
+                assert_equal(a != b, [True, False])
+
+        # Check that broadcasting with a subarray works
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8')])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8')])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8', (1,))])
+        b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8', (1,))])
+        assert_equal(a == b, [[True, True, False], [False, False, True]])
+        assert_equal(b == a, [[True, True, False], [False, False, True]])
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))])
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that broadcasting Fortran-style arrays with a subarray work
+        a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))], order='F')
+        b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
+        assert_equal(a == b, [[True, False, False], [False, False, True]])
+        assert_equal(b == a, [[True, False, False], [False, False, True]])
+
+        # Check that incompatible sub-array shapes don't result to broadcasting
+        x = np.zeros((1,), dtype=[('a', ('f4', (1, 2))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')])
+        y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
+        # This comparison invokes deprecated behaviour, and will probably
+        # start raising an error eventually. What we really care about in this
+        # test is just that it doesn't return True.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            assert_equal(x == y, False)
+
+        # Check that structured arrays that are different only in
+        # byte-order work
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i8'), ('b', '<f8')])
+        b = np.array([(5, 43), (10, 1)], dtype=[('a', '<i8'), ('b', '>f8')])
+        assert_equal(a == b, [False, True])
+
+    def test_casting(self):
+        # Check that casting a structured array to change its byte order
+        # works
+        a = np.array([(1,)], dtype=[('a', '<i4')])
+        assert_(np.can_cast(a.dtype, [('a', '>i4')], casting='unsafe'))
+        b = a.astype([('a', '>i4')])
+        assert_equal(b, a.byteswap().newbyteorder())
+        assert_equal(a['a'][0], b['a'][0])
+
+        # Check that equality comparison works on structured arrays if
+        # they are 'equiv'-castable
+        a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', '<f8')])
+        b = np.array([(42, 5), (1, 10)], dtype=[('b', '>f8'), ('a', '<i4')])
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        assert_equal(a == b, [True, True])
+
+        # Check that 'equiv' casting can reorder fields and change byte
+        # order
+        assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
+        c = a.astype(b.dtype, casting='equiv')
+        assert_equal(a == c, [True, True])
+
+        # Check that 'safe' casting can change byte order and up-cast
+        # fields
+        t = [('a', '<i8'), ('b', '>f8')]
+        assert_(np.can_cast(a.dtype, t, casting='safe'))
+        c = a.astype(t, casting='safe')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that 'same_kind' casting can change byte order and
+        # change field widths within a "kind"
+        t = [('a', '<i4'), ('b', '>f4')]
+        assert_(np.can_cast(a.dtype, t, casting='same_kind'))
+        c = a.astype(t, casting='same_kind')
+        assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
+                     [True, True])
+
+        # Check that casting fails if the casting rule should fail on
+        # any of the fields
+        t = [('a', '>i8'), ('b', '<f4')]
+        assert_(not np.can_cast(a.dtype, t, casting='safe'))
+        assert_raises(TypeError, a.astype, t, casting='safe')
+        t = [('a', '>i2'), ('b', '<f8')]
+        assert_(not np.can_cast(a.dtype, t, casting='equiv'))
+        assert_raises(TypeError, a.astype, t, casting='equiv')
+        t = [('a', '>i8'), ('b', '<i2')]
+        assert_(not np.can_cast(a.dtype, t, casting='same_kind'))
+        assert_raises(TypeError, a.astype, t, casting='same_kind')
+        assert_(not np.can_cast(a.dtype, b.dtype, casting='no'))
+        assert_raises(TypeError, a.astype, b.dtype, casting='no')
+
+        # Check that non-'unsafe' casting can't change the set of field names
+        for casting in ['no', 'safe', 'equiv', 'same_kind']:
+            t = [('a', '>i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+            t = [('a', '>i4'), ('b', '<f8'), ('c', 'i4')]
+            assert_(not np.can_cast(a.dtype, t, casting=casting))
+
+    def test_objview(self):
+        # https://github.com/numpy/numpy/issues/3286
+        a = np.array([], dtype=[('a', 'f'), ('b', 'f'), ('c', 'O')])
+        a[['a', 'b']]  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3253
+        dat2 = np.zeros(3, [('A', 'i'), ('B', '|O')])
+        dat2[['B', 'A']]  # TypeError?
+
+    def test_setfield(self):
+        # https://github.com/numpy/numpy/issues/3126
+        struct_dt = np.dtype([('elem', 'i4', 5),])
+        dt = np.dtype([('field', 'i4', 10),('struct', struct_dt)])
+        x = np.zeros(1, dt)
+        x[0]['field'] = np.ones(10, dtype='i4')
+        x[0]['struct'] = np.ones(1, dtype=struct_dt)
+        assert_equal(x[0]['field'], np.ones(10, dtype='i4'))
+
+    def test_setfield_object(self):
+        # make sure object field assignment with ndarray value
+        # on void scalar mimics setitem behavior
+        b = np.zeros(1, dtype=[('x', 'O')])
+        # next line should work identically to b['x'][0] = np.arange(3)
+        b[0]['x'] = np.arange(3)
+        assert_equal(b[0]['x'], np.arange(3))
+
+        # check that broadcasting check still works
+        c = np.zeros(1, dtype=[('x', 'O', 5)])
+
+        def testassign():
+            c[0]['x'] = np.arange(3)
+
+        assert_raises(ValueError, testassign)
+
+
+class TestBool(TestCase):
+    def test_test_interning(self):
+        a0 = np.bool_(0)
+        b0 = np.bool_(False)
+        self.assertTrue(a0 is b0)
+        a1 = np.bool_(1)
+        b1 = np.bool_(True)
+        self.assertTrue(a1 is b1)
+        self.assertTrue(np.array([True])[0] is a1)
+        self.assertTrue(np.array(True)[()] is a1)
+
+    def test_sum(self):
+        d = np.ones(101, dtype=np.bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+        d = np.frombuffer(b'\xff\xff' * 100, dtype=bool)
+        assert_equal(d.sum(), d.size)
+        assert_equal(d[::2].sum(), d[::2].size)
+        assert_equal(d[::-2].sum(), d[::-2].size)
+
+    def check_count_nonzero(self, power, length):
+        powers = [2 ** i for i in range(length)]
+        for i in range(2**power):
+            l = [(i & x) != 0 for x in powers]
+            a = np.array(l, dtype=np.bool)
+            c = builtins.sum(l)
+            self.assertEqual(np.count_nonzero(a), c)
+            av = a.view(np.uint8)
+            av *= 3
+            self.assertEqual(np.count_nonzero(a), c)
+            av *= 4
+            self.assertEqual(np.count_nonzero(a), c)
+            av[av != 0] = 0xFF
+            self.assertEqual(np.count_nonzero(a), c)
+
+    def test_count_nonzero(self):
+        # check all 12 bit combinations in a length 17 array
+        # covers most cases of the 16 byte unrolled code
+        self.check_count_nonzero(12, 17)
+
+    @dec.slow
+    def test_count_nonzero_all(self):
+        # check all combinations in a length 17 array
+        # covers all cases of the 16 byte unrolled code
+        self.check_count_nonzero(17, 17)
+
+    def test_count_nonzero_unaligned(self):
+        # prevent mistakes as e.g. gh-4060
+        for o in range(7):
+            a = np.zeros((18,), dtype=np.bool)[o+1:]
+            a[:o] = True
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+            a = np.ones((18,), dtype=np.bool)[o+1:]
+            a[:o] = False
+            self.assertEqual(np.count_nonzero(a), builtins.sum(a.tolist()))
+
+
+class TestMethods(TestCase):
+    def test_compress(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = arr.compress([0, 1, 0, 1, 0], axis=1)
+        assert_equal(out, tgt)
+
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1], axis=1)
+        assert_equal(out, tgt)
+
+        arr = np.arange(10).reshape(2, 5)
+        out = arr.compress([0, 1])
+        assert_equal(out, 1)
+
+    def test_choose(self):
+        x = 2*np.ones((3,), dtype=int)
+        y = 3*np.ones((3,), dtype=int)
+        x2 = 2*np.ones((2, 3), dtype=int)
+        y2 = 3*np.ones((2, 3), dtype=int)
+        ind = np.array([0, 0, 1])
+
+        A = ind.choose((x, y))
+        assert_equal(A, [2, 2, 3])
+
+        A = ind.choose((x2, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+        A = ind.choose((x, y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_prod(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, a.prod)
+                self.assertRaises(ArithmeticError, a2.prod, axis=1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+    def test_repeat(self):
+        m = np.array([1, 2, 3, 4, 5, 6])
+        m_rect = m.reshape((2, 3))
+
+        A = m.repeat([1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+        A = m.repeat(2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+        A = m_rect.repeat([2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat([1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+        A = m_rect.repeat(2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = m_rect.repeat(2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+    def test_reshape(self):
+        arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
+
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(arr.reshape(2, 6), tgt)
+
+        tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
+        assert_equal(arr.reshape(3, 4), tgt)
+
+        tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
+        assert_equal(arr.reshape((3, 4), order='F'), tgt)
+
+        tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
+        assert_equal(arr.T.reshape((3, 4), order='C'), tgt)
+
+    def test_round(self):
+        def check_round(arr, expected, *round_args):
+            assert_equal(arr.round(*round_args), expected)
+            # With output array
+            out = np.zeros_like(arr)
+            res = arr.round(*round_args, out=out)
+            assert_equal(out, expected)
+            assert_equal(out, res)
+
+        check_round(np.array([1.2, 1.5]), [1, 2])
+        check_round(np.array(1.5), 2)
+        check_round(np.array([12.2, 15.5]), [10, 20], -1)
+        check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1)
+        # Complex rounding
+        check_round(np.array([4.5 + 1.5j]), [4 + 2j])
+        check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1)
+
+    def test_squeeze(self):
+        a = np.array([[[1], [2], [3]]])
+        assert_equal(a.squeeze(), [1, 2, 3])
+        assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]])
+        assert_raises(ValueError, a.squeeze, axis=(1,))
+        assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]])
+
+    def test_transpose(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(a.transpose(), [[1, 3], [2, 4]])
+        self.assertRaises(ValueError, lambda: a.transpose(0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 0))
+        self.assertRaises(ValueError, lambda: a.transpose(0, 1, 2))
+
+    def test_sort(self):
+        # test ordering for floats and complex containing nans. It is only
+        # necessary to check the less-than comparison, so sorts that
+        # only follow the insertion sort path are sufficient. We only
+        # test doubles and complex doubles as the logic is the same.
+
+        # check doubles
+        msg = "Test real sort order with nans"
+        a = np.array([np.nan, 1, 0])
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+        # check complex
+        msg = "Test complex sort order with nans"
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0]
+        a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0]
+        b = np.sort(a)
+        assert_equal(b, a[::-1], msg)
+
+        # all c scalar sorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test complex sorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, real part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex sort, imag part == 1, kind=%s" % kind
+            c = ai.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+            c = bi.copy()
+            c.sort(kind=kind)
+            assert_equal(c, ai, msg)
+
+        # test sorting of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                c = arr.copy()
+                c.sort()
+                msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
+                assert_equal(c, arr, msg)
+
+        # test string sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "string sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test unicode sorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test object array sorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test record array sorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "object sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test datetime64 sorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # test timedelta64 sorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 sort, kind=%s" % kind
+            c = a.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+            c = b.copy()
+            c.sort(kind=kind)
+            assert_equal(c, a, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific sorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 0], [3, 2]])
+        c = np.array([[2, 3], [0, 1]])
+        d = a.copy()
+        d.sort(axis=0)
+        assert_equal(d, b, "test sort with axis=0")
+        d = a.copy()
+        d.sort(axis=1)
+        assert_equal(d, c, "test sort with axis=1")
+        d = a.copy()
+        d.sort()
+        assert_equal(d, c, "test sort with default axis")
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array sort with axis={0}'.format(axis)
+            assert_equal(np.sort(a, axis=axis), a, msg)
+        msg = 'test empty array sort with axis=None'
+        assert_equal(np.sort(a, axis=None), a.ravel(), msg)
+
+    def test_copy(self):
+        def assert_fortran(arr):
+            assert_(arr.flags.fortran)
+            assert_(arr.flags.f_contiguous)
+            assert_(not arr.flags.c_contiguous)
+
+        def assert_c(arr):
+            assert_(not arr.flags.fortran)
+            assert_(not arr.flags.f_contiguous)
+            assert_(arr.flags.c_contiguous)
+
+        a = np.empty((2, 2), order='F')
+        # Test copying a Fortran array
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_fortran(a.copy('A'))
+
+        # Now test starting with a C array.
+        a = np.empty((2, 2), order='C')
+        assert_c(a.copy())
+        assert_c(a.copy('C'))
+        assert_fortran(a.copy('F'))
+        assert_c(a.copy('A'))
+
+    def test_sort_order(self):
+        # Test sorting an array with fields
+        x1 = np.array([21, 32, 14])
+        x2 = np.array(['my', 'first', 'name'])
+        x3 = np.array([3.1, 4.5, 6.2])
+        r = np.rec.fromarrays([x1, x2, x3], names='id,word,number')
+
+        r.sort(order=['id'])
+        assert_equal(r.id, np.array([14, 21, 32]))
+        assert_equal(r.word, np.array(['name', 'my', 'first']))
+        assert_equal(r.number, np.array([6.2, 3.1, 4.5]))
+
+        r.sort(order=['word'])
+        assert_equal(r.id, np.array([32, 21, 14]))
+        assert_equal(r.word, np.array(['first', 'my', 'name']))
+        assert_equal(r.number, np.array([4.5, 3.1, 6.2]))
+
+        r.sort(order=['number'])
+        assert_equal(r.id, np.array([21, 32, 14]))
+        assert_equal(r.word, np.array(['my', 'first', 'name']))
+        assert_equal(r.number, np.array([3.1, 4.5, 6.2]))
+
+        if sys.byteorder == 'little':
+            strtype = '>i2'
+        else:
+            strtype = '<i2'
+        mydtype = [('name', strchar + '5'), ('col2', strtype)]
+        r = np.array([('a', 1), ('b', 255), ('c', 3), ('d', 258)],
+                     dtype=mydtype)
+        r.sort(order='col2')
+        assert_equal(r['col2'], [1, 3, 255, 258])
+        assert_equal(r, np.array([('a', 1), ('c', 3), ('b', 255), ('d', 258)],
+                                 dtype=mydtype))
+
+    def test_argsort(self):
+        # all c scalar argsorts use the same code with different types
+        # so it suffices to run a quick check with one type. The number
+        # of sorted items must be greater than ~50 to check the actual
+        # algorithm because quick and merge sort fall over to insertion
+        # sort for small arrays.
+        a = np.arange(101)
+        b = a[::-1].copy()
+        for kind in ['q', 'm', 'h']:
+            msg = "scalar argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), a, msg)
+            assert_equal(b.copy().argsort(kind=kind), b, msg)
+
+        # test complex argsorts. These use the same code as the scalars
+        # but the compare function differs.
+        ai = a*1j + 1
+        bi = b*1j + 1
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+        ai = a + 1j
+        bi = b + 1j
+        for kind in ['q', 'm', 'h']:
+            msg = "complex argsort, kind=%s" % kind
+            assert_equal(ai.copy().argsort(kind=kind), a, msg)
+            assert_equal(bi.copy().argsort(kind=kind), b, msg)
+
+        # test argsort of complex arrays requiring byte-swapping, gh-5441
+        for endianess in '<>':
+            for dt in np.typecodes['Complex']:
+                arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianess + dt)
+                msg = 'byte-swapped complex argsort, dtype={0}'.format(dt)
+                assert_equal(arr.argsort(),
+                             np.arange(len(arr), dtype=np.intp), msg)
+
+        # test string argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)])
+        b = a[::-1].copy()
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "string argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test unicode argsorts.
+        s = 'aaaaaaaa'
+        a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "unicode argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test object array argsorts.
+        a = np.empty((101,), dtype=np.object)
+        a[:] = list(range(101))
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "object argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test structured array argsorts.
+        dt = np.dtype([('f', float), ('i', int)])
+        a = np.array([(i, i) for i in range(101)], dtype=dt)
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'm', 'h']:
+            msg = "structured array argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test datetime64 argsorts.
+        a = np.arange(0, 101, dtype='datetime64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "datetime64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # test timedelta64 argsorts.
+        a = np.arange(0, 101, dtype='timedelta64[D]')
+        b = a[::-1]
+        r = np.arange(101)
+        rr = r[::-1]
+        for kind in ['q', 'h', 'm']:
+            msg = "timedelta64 argsort, kind=%s" % kind
+            assert_equal(a.copy().argsort(kind=kind), r, msg)
+            assert_equal(b.copy().argsort(kind=kind), rr, msg)
+
+        # check axis handling. This should be the same for all type
+        # specific argsorts, so we only check it for one type and one kind
+        a = np.array([[3, 2], [1, 0]])
+        b = np.array([[1, 1], [0, 0]])
+        c = np.array([[1, 0], [1, 0]])
+        assert_equal(a.copy().argsort(axis=0), b)
+        assert_equal(a.copy().argsort(axis=1), c)
+        assert_equal(a.copy().argsort(), c)
+
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argsort with axis={0}'.format(axis)
+            assert_equal(np.argsort(a, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argsort with axis=None'
+        assert_equal(np.argsort(a, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+        # check that stable argsorts are stable
+        r = np.arange(100)
+        # scalars
+        a = np.zeros(100)
+        assert_equal(a.argsort(kind='m'), r)
+        # complex
+        a = np.zeros(100, dtype=np.complex)
+        assert_equal(a.argsort(kind='m'), r)
+        # string
+        a = np.array(['aaaaaaaaa' for i in range(100)])
+        assert_equal(a.argsort(kind='m'), r)
+        # unicode
+        a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode)
+        assert_equal(a.argsort(kind='m'), r)
+
+    def test_sort_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.sort, kind=k)
+        assert_raises(ValueError, d.argsort, kind=k)
+
+    def test_searchsorted(self):
+        # test for floats and complex containing nans. The logic is the
+        # same for all float types so only test double types for now.
+        # The search sorted routines use the compare functions for the
+        # array type, so this checks if that is consistent with the sort
+        # order.
+
+        # check double
+        a = np.array([0, 1, np.nan])
+        msg = "Test real searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(3), msg)
+        msg = "Test real searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 4), msg)
+        # check double complex
+        a = np.zeros(9, dtype=np.complex128)
+        a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan]
+        a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan]
+        msg = "Test complex searchsorted with nans, side='l'"
+        b = a.searchsorted(a, side='l')
+        assert_equal(b, np.arange(9), msg)
+        msg = "Test complex searchsorted with nans, side='r'"
+        b = a.searchsorted(a, side='r')
+        assert_equal(b, np.arange(1, 10), msg)
+        msg = "Test searchsorted with little endian, side='l'"
+        a = np.array([0, 128], dtype='<i4')
+        b = a.searchsorted(np.array(128, dtype='<i4'))
+        assert_equal(b, 1, msg)
+        msg = "Test searchsorted with big endian, side='l'"
+        a = np.array([0, 128], dtype='>i4')
+        b = a.searchsorted(np.array(128, dtype='>i4'))
+        assert_equal(b, 1, msg)
+
+        # Check 0 elements
+        a = np.ones(0)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 0])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 0, 0])
+        a = np.ones(1)
+        # Check 1 element
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 1])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 1, 1])
+        # Check all elements equal
+        a = np.ones(2)
+        b = a.searchsorted([0, 1, 2], 'l')
+        assert_equal(b, [0, 0, 2])
+        b = a.searchsorted([0, 1, 2], 'r')
+        assert_equal(b, [0, 2, 2])
+
+        # Test searching unaligned array
+        a = np.arange(10)
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        unaligned[:] = a
+        # Test searching unaligned array
+        b = unaligned.searchsorted(a, 'l')
+        assert_equal(b, a)
+        b = unaligned.searchsorted(a, 'r')
+        assert_equal(b, a + 1)
+        # Test searching for unaligned keys
+        b = a.searchsorted(unaligned, 'l')
+        assert_equal(b, a)
+        b = a.searchsorted(unaligned, 'r')
+        assert_equal(b, a + 1)
+
+        # Test smart resetting of binsearch indices
+        a = np.arange(5)
+        b = a.searchsorted([6, 5, 4], 'l')
+        assert_equal(b, [5, 5, 4])
+        b = a.searchsorted([6, 5, 4], 'r')
+        assert_equal(b, [5, 5, 5])
+
+        # Test all type specific binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.arange(2, dtype=dt)
+                out = np.arange(2)
+            else:
+                a = np.arange(0, 5, dtype=dt)
+                out = np.arange(5)
+            b = a.searchsorted(a, 'l')
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r')
+            assert_equal(b, out + 1)
+
+    def test_searchsorted_unicode(self):
+        # Test searchsorted on unicode strings.
+
+        # 1.6.1 contained a string length miscalculation in
+        # arraytypes.c.src:UNICODE_compare() which manifested as
+        # incorrect/inconsistent results from searchsorted.
+        a = np.array(['P:\\20x_dapi_cy3\\20x_dapi_cy3_20100185_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100186_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100187_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100189_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100190_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100191_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100192_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100193_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100194_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100195_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100196_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
+                      'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
+                     dtype=np.unicode)
+        ind = np.arange(len(a))
+        assert_equal([a.searchsorted(v, 'left') for v in a], ind)
+        assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
+        assert_equal([a.searchsorted(a[i], 'left') for i in ind], ind)
+        assert_equal([a.searchsorted(a[i], 'right') for i in ind], ind + 1)
+
+    def test_searchsorted_with_sorter(self):
+        a = np.array([5, 2, 1, 3, 4])
+        s = np.argsort(a)
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=(1, (2, 3)))
+        assert_raises(TypeError, np.searchsorted, a, 0, sorter=[1.1])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4, 5, 6])
+
+        # bounds check
+        assert_raises(ValueError, np.searchsorted, a, 4, sorter=[0, 1, 2, 3, 5])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[-1, 0, 1, 2, 3])
+        assert_raises(ValueError, np.searchsorted, a, 0, sorter=[4, 0, -1, 2, 3])
+
+        a = np.random.rand(300)
+        s = a.argsort()
+        b = np.sort(a)
+        k = np.linspace(0, 1, 20)
+        assert_equal(b.searchsorted(k), a.searchsorted(k, sorter=s))
+
+        a = np.array([0, 1, 2, 3, 5]*20)
+        s = a.argsort()
+        k = [0, 1, 2, 3, 5]
+        expected = [0, 20, 40, 60, 80]
+        assert_equal(a.searchsorted(k, side='l', sorter=s), expected)
+        expected = [20, 40, 60, 80, 100]
+        assert_equal(a.searchsorted(k, side='r', sorter=s), expected)
+
+        # Test searching unaligned array
+        keys = np.arange(10)
+        a = keys.copy()
+        np.random.shuffle(s)
+        s = a.argsort()
+        aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
+        unaligned = aligned[1:].view(a.dtype)
+        # Test searching unaligned array
+        unaligned[:] = a
+        b = unaligned.searchsorted(keys, 'l', s)
+        assert_equal(b, keys)
+        b = unaligned.searchsorted(keys, 'r', s)
+        assert_equal(b, keys + 1)
+        # Test searching for unaligned keys
+        unaligned[:] = keys
+        b = a.searchsorted(unaligned, 'l', s)
+        assert_equal(b, keys)
+        b = a.searchsorted(unaligned, 'r', s)
+        assert_equal(b, keys + 1)
+
+        # Test all type specific indirect binary search functions
+        types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
+                         np.typecodes['Datetime'], '?O'))
+        for dt in types:
+            if dt == 'M':
+                dt = 'M8[D]'
+            if dt == '?':
+                a = np.array([1, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([1, 0], dtype=np.int16)
+                out = np.array([1, 0])
+            else:
+                a = np.array([3, 4, 1, 2, 0], dtype=dt)
+                # We want the sorter array to be of a type that is different
+                # from np.intp in all platforms, to check for #4698
+                s = np.array([4, 2, 3, 0, 1], dtype=np.int16)
+                out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+            b = a.searchsorted(a, 'l', s)
+            assert_equal(b, out)
+            b = a.searchsorted(a, 'r', s)
+            assert_equal(b, out + 1)
+
+        # Test non-contiguous sorter array
+        a = np.array([3, 4, 1, 2, 0])
+        srt = np.empty((10,), dtype=np.intp)
+        srt[1::2] = -1
+        srt[::2] = [4, 2, 3, 0, 1]
+        s = srt[::2]
+        out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
+        b = a.searchsorted(a, 'l', s)
+        assert_equal(b, out)
+        b = a.searchsorted(a, 'r', s)
+        assert_equal(b, out + 1)
+
+    def test_searchsorted_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        s = np.arange(5).view(A)
+        assert_(not isinstance(a.searchsorted(b, 'l'), A))
+        assert_(not isinstance(a.searchsorted(b, 'r'), A))
+        assert_(not isinstance(a.searchsorted(b, 'l', s), A))
+        assert_(not isinstance(a.searchsorted(b, 'r', s), A))
+
+    def test_argpartition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.argpartition, 10)
+        assert_raises(ValueError, d.argpartition, -11)
+        # Test also for generic type argpartition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.argpartition, 10)
+        assert_raises(ValueError, d_obj.argpartition, -11)
+
+    def test_partition_out_of_range(self):
+        # Test out of range values in kth raise an error, gh-5469
+        d = np.arange(10)
+        assert_raises(ValueError, d.partition, 10)
+        assert_raises(ValueError, d.partition, -11)
+        # Test also for generic type partition, which uses sorting
+        # and used to not bound check kth
+        d_obj = np.arange(10, dtype=object)
+        assert_raises(ValueError, d_obj.partition, 10)
+        assert_raises(ValueError, d_obj.partition, -11)
+
+    def test_partition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array partition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis), a, msg)
+        msg = 'test empty array partition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None), a.ravel(), msg)
+
+    def test_argpartition_empty_array(self):
+        # check axis handling for multidimensional empty arrays
+        a = np.array([])
+        a.shape = (3, 2, 1, 0)
+        for axis in range(-a.ndim, a.ndim):
+            msg = 'test empty array argpartition with axis={0}'.format(axis)
+            assert_equal(np.partition(a, 0, axis=axis),
+                         np.zeros_like(a, dtype=np.intp), msg)
+        msg = 'test empty array argpartition with axis=None'
+        assert_equal(np.partition(a, 0, axis=None),
+                     np.zeros_like(a.ravel(), dtype=np.intp), msg)
+
+    def test_partition(self):
+        d = np.arange(10)
+        assert_raises(TypeError, np.partition, d, 2, kind=1)
+        assert_raises(ValueError, np.partition, d, 2, kind="nonsense")
+        assert_raises(ValueError, np.argpartition, d, 2, kind="nonsense")
+        assert_raises(ValueError, d.partition, 2, axis=0, kind="nonsense")
+        assert_raises(ValueError, d.argpartition, 2, axis=0, kind="nonsense")
+        for k in ("introselect",):
+            d = np.array([])
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(np.argpartition(d, 0, kind=k), d)
+            d = np.ones(1)
+            assert_array_equal(np.partition(d, 0, kind=k)[0], d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # kth not modified
+            kth = np.array([30, 15, 5])
+            okth = kth.copy()
+            np.partition(np.arange(40), kth)
+            assert_array_equal(kth, okth)
+
+            for r in ([2, 1], [1, 2], [1, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            for r in ([3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1],
+                      [1, 1, 1], [1, 2, 2], [2, 2, 1], [1, 2, 1]):
+                d = np.array(r)
+                tgt = np.sort(d)
+                assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
+                assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
+                assert_array_equal(np.partition(d, 2, kind=k)[2], tgt[2])
+                assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                                   np.partition(d, 0, kind=k))
+                assert_array_equal(d[np.argpartition(d, 1, kind=k)],
+                                   np.partition(d, 1, kind=k))
+                assert_array_equal(d[np.argpartition(d, 2, kind=k)],
+                                   np.partition(d, 2, kind=k))
+                for i in range(d.size):
+                    d[i:].partition(0, kind=k)
+                assert_array_equal(d, tgt)
+
+            d = np.ones(50)
+            assert_array_equal(np.partition(d, 0, kind=k), d)
+            assert_array_equal(d[np.argpartition(d, 0, kind=k)],
+                               np.partition(d, 0, kind=k))
+
+            # sorted
+            d = np.arange(49)
+            self.assertEqual(np.partition(d, 5, kind=k)[5], 5)
+            self.assertEqual(np.partition(d, 15, kind=k)[15], 15)
+            assert_array_equal(d[np.argpartition(d, 5, kind=k)],
+                               np.partition(d, 5, kind=k))
+            assert_array_equal(d[np.argpartition(d, 15, kind=k)],
+                               np.partition(d, 15, kind=k))
+
+            # rsorted
+            d = np.arange(47)[::-1]
+            self.assertEqual(np.partition(d, 6, kind=k)[6], 6)
+            self.assertEqual(np.partition(d, 16, kind=k)[16], 16)
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+
+            assert_array_equal(np.partition(d, -6, kind=k),
+                               np.partition(d, 41, kind=k))
+            assert_array_equal(np.partition(d, -16, kind=k),
+                               np.partition(d, 31, kind=k))
+            assert_array_equal(d[np.argpartition(d, -6, kind=k)],
+                               np.partition(d, 41, kind=k))
+
+            # median of 3 killer, O(n^2) on pure median 3 pivot quickselect
+            # exercises the median of median of 5 code used to keep O(n)
+            d = np.arange(1000000)
+            x = np.roll(d, d.size // 2)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+            d = np.arange(1000001)
+            x = np.roll(d, d.size // 2 + 1)
+            mid = x.size // 2 + 1
+            assert_equal(np.partition(x, mid)[mid], mid)
+
+            # max
+            d = np.ones(10)
+            d[1] = 4
+            assert_equal(np.partition(d, (2, -1))[-1], 4)
+            assert_equal(np.partition(d, (2, -1))[2], 1)
+            assert_equal(d[np.argpartition(d, (2, -1))][-1], 4)
+            assert_equal(d[np.argpartition(d, (2, -1))][2], 1)
+            d[1] = np.nan
+            assert_(np.isnan(d[np.argpartition(d, (2, -1))][-1]))
+            assert_(np.isnan(np.partition(d, (2, -1))[-1]))
+
+            # equal elements
+            d = np.arange(47) % 7
+            tgt = np.sort(np.arange(47) % 7)
+            np.random.shuffle(d)
+            for i in range(d.size):
+                self.assertEqual(np.partition(d, i, kind=k)[i], tgt[i])
+            assert_array_equal(d[np.argpartition(d, 6, kind=k)],
+                               np.partition(d, 6, kind=k))
+            assert_array_equal(d[np.argpartition(d, 16, kind=k)],
+                               np.partition(d, 16, kind=k))
+            for i in range(d.size):
+                d[i:].partition(0, kind=k)
+            assert_array_equal(d, tgt)
+
+            d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+                          7, 7, 7, 7, 7, 9])
+            kth = [0, 3, 19, 20]
+            assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
+            assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
+
+            d = np.array([2, 1])
+            d.partition(0, kind=k)
+            assert_raises(ValueError, d.partition, 2)
+            assert_raises(ValueError, d.partition, 3, axis=1)
+            assert_raises(ValueError, np.partition, d, 2)
+            assert_raises(ValueError, np.partition, d, 2, axis=1)
+            assert_raises(ValueError, d.argpartition, 2)
+            assert_raises(ValueError, d.argpartition, 3, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 2)
+            assert_raises(ValueError, np.argpartition, d, 2, axis=1)
+            d = np.arange(10).reshape((2, 5))
+            d.partition(1, axis=0, kind=k)
+            d.partition(4, axis=1, kind=k)
+            np.partition(d, 1, axis=0, kind=k)
+            np.partition(d, 4, axis=1, kind=k)
+            np.partition(d, 1, axis=None, kind=k)
+            np.partition(d, 9, axis=None, kind=k)
+            d.argpartition(1, axis=0, kind=k)
+            d.argpartition(4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=0, kind=k)
+            np.argpartition(d, 4, axis=1, kind=k)
+            np.argpartition(d, 1, axis=None, kind=k)
+            np.argpartition(d, 9, axis=None, kind=k)
+            assert_raises(ValueError, d.partition, 2, axis=0)
+            assert_raises(ValueError, d.partition, 11, axis=1)
+            assert_raises(TypeError, d.partition, 2, axis=None)
+            assert_raises(ValueError, np.partition, d, 9, axis=1)
+            assert_raises(ValueError, np.partition, d, 11, axis=None)
+            assert_raises(ValueError, d.argpartition, 2, axis=0)
+            assert_raises(ValueError, d.argpartition, 11, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 9, axis=1)
+            assert_raises(ValueError, np.argpartition, d, 11, axis=None)
+
+            td = [(dt, s) for dt in [np.int32, np.float32, np.complex64]
+                  for s in (9, 16)]
+            for dt, s in td:
+                aae = assert_array_equal
+                at = self.assertTrue
+
+                d = np.arange(s, dtype=dt)
+                np.random.shuffle(d)
+                d1 = np.tile(np.arange(s, dtype=dt), (4, 1))
+                map(np.random.shuffle, d1)
+                d0 = np.transpose(d1)
+                for i in range(d.size):
+                    p = np.partition(d, i, kind=k)
+                    self.assertEqual(p[i], i)
+                    # all before are smaller
+                    assert_array_less(p[:i], p[i])
+                    # all after are larger
+                    assert_array_less(p[i], p[i + 1:])
+                    aae(p, d[np.argpartition(d, i, kind=k)])
+
+                    p = np.partition(d1, i, axis=1, kind=k)
+                    aae(p[:, i], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:, :i].T <= p[:, i]).all(),
+                       msg="%d: %r <= %r" % (i, p[:, i], p[:, :i].T))
+                    at((p[:, i + 1:].T > p[:, i]).all(),
+                       msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T))
+                    aae(p, d1[np.arange(d1.shape[0])[:, None],
+                        np.argpartition(d1, i, axis=1, kind=k)])
+
+                    p = np.partition(d0, i, axis=0, kind=k)
+                    aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt))
+                    # array_less does not seem to work right
+                    at((p[:i, :] <= p[i, :]).all(),
+                       msg="%d: %r <= %r" % (i, p[i, :], p[:i, :]))
+                    at((p[i + 1:, :] > p[i, :]).all(),
+                       msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:]))
+                    aae(p, d0[np.argpartition(d0, i, axis=0, kind=k),
+                        np.arange(d0.shape[1])[None, :]])
+
+                    # check inplace
+                    dc = d.copy()
+                    dc.partition(i, kind=k)
+                    assert_equal(dc, np.partition(d, i, kind=k))
+                    dc = d0.copy()
+                    dc.partition(i, axis=0, kind=k)
+                    assert_equal(dc, np.partition(d0, i, axis=0, kind=k))
+                    dc = d1.copy()
+                    dc.partition(i, axis=1, kind=k)
+                    assert_equal(dc, np.partition(d1, i, axis=1, kind=k))
+
+    def assert_partitioned(self, d, kth):
+        prev = 0
+        for k in np.sort(kth):
+            assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k)
+            assert_((d[k:] >= d[k]).all(),
+                    msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k]))
+            prev = k + 1
+
+    def test_partition_iterative(self):
+            d = np.arange(17)
+            kth = (0, 1, 2, 429, 231)
+            assert_raises(ValueError, d.partition, kth)
+            assert_raises(ValueError, d.argpartition, kth)
+            d = np.arange(10).reshape((2, 5))
+            assert_raises(ValueError, d.partition, kth, axis=0)
+            assert_raises(ValueError, d.partition, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=1)
+            assert_raises(ValueError, np.partition, d, kth, axis=None)
+
+            d = np.array([3, 4, 2, 1])
+            p = np.partition(d, (0, 3))
+            self.assert_partitioned(p, (0, 3))
+            self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3))
+
+            assert_array_equal(p, np.partition(d, (-3, -1)))
+            assert_array_equal(p, d[np.argpartition(d, (-3, -1))])
+
+            d = np.arange(17)
+            np.random.shuffle(d)
+            d.partition(range(d.size))
+            assert_array_equal(np.arange(17), d)
+            np.random.shuffle(d)
+            assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))])
+
+            # test unsorted kth
+            d = np.arange(17)
+            np.random.shuffle(d)
+            keys = np.array([1, 3, 8, -2])
+            np.random.shuffle(d)
+            p = np.partition(d, keys)
+            self.assert_partitioned(p, keys)
+            p = d[np.argpartition(d, keys)]
+            self.assert_partitioned(p, keys)
+            np.random.shuffle(keys)
+            assert_array_equal(np.partition(d, keys), p)
+            assert_array_equal(d[np.argpartition(d, keys)], p)
+
+            # equal kth
+            d = np.arange(20)[::-1]
+            self.assert_partitioned(np.partition(d, [5]*4), [5])
+            self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]),
+                                    [5]*4 + [6, 13])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5])
+            self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])],
+                                    [5]*4 + [6, 13])
+
+            d = np.arange(12)
+            np.random.shuffle(d)
+            d1 = np.tile(np.arange(12), (4, 1))
+            map(np.random.shuffle, d1)
+            d0 = np.transpose(d1)
+
+            kth = (1, 6, 7, -1)
+            p = np.partition(d1, kth, axis=1)
+            pa = d1[np.arange(d1.shape[0])[:, None],
+                    d1.argpartition(kth, axis=1)]
+            assert_array_equal(p, pa)
+            for i in range(d1.shape[0]):
+                self.assert_partitioned(p[i,:], kth)
+            p = np.partition(d0, kth, axis=0)
+            pa = d0[np.argpartition(d0, kth, axis=0),
+                    np.arange(d0.shape[1])[None,:]]
+            assert_array_equal(p, pa)
+            for i in range(d0.shape[1]):
+                self.assert_partitioned(p[:, i], kth)
+
+    def test_partition_cdtype(self):
+        d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+                   ('Lancelot', 1.9, 38)],
+                  dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+
+        tgt = np.sort(d, order=['age', 'height'])
+        assert_array_equal(np.partition(d, range(d.size),
+                                        order=['age', 'height']),
+                           tgt)
+        assert_array_equal(d[np.argpartition(d, range(d.size),
+                                             order=['age', 'height'])],
+                           tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k, order=['age', 'height'])[k],
+                        tgt[k])
+            assert_equal(d[np.argpartition(d, k, order=['age', 'height'])][k],
+                         tgt[k])
+
+        d = np.array(['Galahad', 'Arthur', 'zebra', 'Lancelot'])
+        tgt = np.sort(d)
+        assert_array_equal(np.partition(d, range(d.size)), tgt)
+        for k in range(d.size):
+            assert_equal(np.partition(d, k)[k], tgt[k])
+            assert_equal(d[np.argpartition(d, k)][k], tgt[k])
+
+    def test_partition_unicode_kind(self):
+        d = np.arange(10)
+        k = b'\xc3\xa4'.decode("UTF8")
+        assert_raises(ValueError, d.partition, 2, kind=k)
+        assert_raises(ValueError, d.argpartition, 2, kind=k)
+
+    def test_partition_fuzz(self):
+        # a few rounds of random data testing
+        for j in range(10, 30):
+            for i in range(1, j - 2):
+                d = np.arange(j)
+                np.random.shuffle(d)
+                d = d % np.random.randint(2, 30)
+                idx = np.random.randint(d.size)
+                kth = [0, idx, i, i + 1]
+                tgt = np.sort(d)[kth]
+                assert_array_equal(np.partition(d, kth)[kth], tgt,
+                                   err_msg="data: %r\n kth: %r" % (d, kth))
+
+    def test_argpartition_gh5524(self):
+        #  A test for functionality of argpartition on lists.
+        d = [6,7,3,2,9,0]
+        p = np.argpartition(d,1)
+        self.assert_partitioned(np.array(d)[p],[1])
+
+    def test_flatten(self):
+        x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
+        x1 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], np.int32)
+        y0 = np.array([1, 2, 3, 4, 5, 6], np.int32)
+        y0f = np.array([1, 4, 2, 5, 3, 6], np.int32)
+        y1 = np.array([1, 2, 3, 4, 5, 6, 7, 8], np.int32)
+        y1f = np.array([1, 5, 3, 7, 2, 6, 4, 8], np.int32)
+        assert_equal(x0.flatten(), y0)
+        assert_equal(x0.flatten('F'), y0f)
+        assert_equal(x0.flatten('F'), x0.T.flatten())
+        assert_equal(x1.flatten(), y1)
+        assert_equal(x1.flatten('F'), y1f)
+        assert_equal(x1.flatten('F'), x1.T.flatten())
+
+    def test_dot(self):
+        a = np.array([[1, 0], [0, 1]])
+        b = np.array([[0, 1], [1, 0]])
+        c = np.array([[9, 1], [1, -9]])
+        d = np.arange(24).reshape(4, 6)
+        ddt = np.array(
+            [[  55,  145,  235,  325],
+             [ 145,  451,  757, 1063],
+             [ 235,  757, 1279, 1801],
+             [ 325, 1063, 1801, 2539]]
+        )
+        dtd = np.array(
+            [[504, 540, 576, 612, 648, 684],
+             [540, 580, 620, 660, 700, 740],
+             [576, 620, 664, 708, 752, 796],
+             [612, 660, 708, 756, 804, 852],
+             [648, 700, 752, 804, 856, 908],
+             [684, 740, 796, 852, 908, 964]]
+        )
+
+
+        # gemm vs syrk optimizations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            assert_equal(np.dot(eaf, eaf), eaf)
+            assert_equal(np.dot(eaf.T, eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T, eaf.T), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf), eaf)
+            assert_equal(np.dot(eaf, eaf.T.copy()), eaf)
+            assert_equal(np.dot(eaf.T.copy(), eaf.T.copy()), eaf)
+
+        # syrk validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            eaf = a.astype(et)
+            ebf = b.astype(et)
+            assert_equal(np.dot(ebf, ebf), eaf)
+            assert_equal(np.dot(ebf.T, ebf), eaf)
+            assert_equal(np.dot(ebf, ebf.T), eaf)
+            assert_equal(np.dot(ebf.T, ebf.T), eaf)
+
+        # syrk - different shape, stride, and view validations
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            assert_equal(
+                np.dot(edf[::-1, :], edf.T),
+                np.dot(edf[::-1, :].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:, ::-1], edf.T),
+                np.dot(edf[:, ::-1].copy(), edf.T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[::-1, :].T),
+                np.dot(edf, edf[::-1, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf, edf[:, ::-1].T),
+                np.dot(edf, edf[:, ::-1].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[:edf.shape[0] // 2, :], edf[::2, :].T),
+                np.dot(edf[:edf.shape[0] // 2, :].copy(), edf[::2, :].T.copy())
+            )
+            assert_equal(
+                np.dot(edf[::2, :], edf[:edf.shape[0] // 2, :].T),
+                np.dot(edf[::2, :].copy(), edf[:edf.shape[0] // 2, :].T.copy())
+            )
+
+        # syrk - different shape
+        for et in [np.float32, np.float64, np.complex64, np.complex128]:
+            edf = d.astype(et)
+            eddtf = ddt.astype(et)
+            edtdf = dtd.astype(et)
+            assert_equal(np.dot(edf, edf.T), eddtf)
+            assert_equal(np.dot(edf.T, edf), edtdf)
+
+        # function versus methods
+        assert_equal(np.dot(a, b), a.dot(b))
+        assert_equal(np.dot(np.dot(a, b), c), a.dot(b).dot(c))
+
+        # test passing in an output array
+        c = np.zeros_like(a)
+        a.dot(b, c)
+        assert_equal(c, np.dot(a, b))
+
+        # test keyword args
+        c = np.zeros_like(a)
+        a.dot(b=b, out=c)
+        assert_equal(c, np.dot(a, b))
+
+    def test_dot_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        b = B()
+        c = np.array([[1]])
+
+        assert_equal(np.dot(a, b), "A")
+        assert_equal(c.dot(a), "A")
+        assert_raises(TypeError, np.dot, b, c)
+        assert_raises(TypeError, c.dot, b)
+
+    def test_dot_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.dot, c, A)
+        assert_raises(TypeError, np.dot, A, c)
+
+    def test_diagonal(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.diagonal(), [0, 5, 10])
+        assert_equal(a.diagonal(0), [0, 5, 10])
+        assert_equal(a.diagonal(1), [1, 6, 11])
+        assert_equal(a.diagonal(-1), [4, 9])
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.diagonal(), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(0), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(1), [[2], [3]])
+        assert_equal(b.diagonal(-1), [[4], [5]])
+        assert_raises(ValueError, b.diagonal, axis1=0, axis2=0)
+        assert_equal(b.diagonal(0, 1, 2), [[0, 3], [4, 7]])
+        assert_equal(b.diagonal(0, 0, 1), [[0, 6], [1, 7]])
+        assert_equal(b.diagonal(offset=1, axis1=0, axis2=2), [[1], [3]])
+        # Order of axis argument doesn't matter:
+        assert_equal(b.diagonal(0, 2, 1), [[0, 3], [4, 7]])
+
+    def test_diagonal_view_notwriteable(self):
+        # this test is only for 1.9, the diagonal view will be
+        # writeable in 1.10.
+        a = np.eye(3).diagonal()
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diagonal(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+        a = np.diag(np.eye(3))
+        assert_(not a.flags.writeable)
+        assert_(not a.flags.owndata)
+
+    def test_diagonal_memleak(self):
+        # Regression test for a bug that crept in at one point
+        a = np.zeros((100, 100))
+        assert_(sys.getrefcount(a) < 50)
+        for i in range(100):
+            a.diagonal()
+        assert_(sys.getrefcount(a) < 50)
+
+    def test_trace(self):
+        a = np.arange(12).reshape((3, 4))
+        assert_equal(a.trace(), 15)
+        assert_equal(a.trace(0), 15)
+        assert_equal(a.trace(1), 18)
+        assert_equal(a.trace(-1), 13)
+
+        b = np.arange(8).reshape((2, 2, 2))
+        assert_equal(b.trace(), [6, 8])
+        assert_equal(b.trace(0), [6, 8])
+        assert_equal(b.trace(1), [2, 3])
+        assert_equal(b.trace(-1), [4, 5])
+        assert_equal(b.trace(0, 0, 1), [6, 8])
+        assert_equal(b.trace(0, 0, 2), [5, 9])
+        assert_equal(b.trace(0, 1, 2), [3, 11])
+        assert_equal(b.trace(offset=1, axis1=0, axis2=2), [1, 3])
+
+    def test_trace_subclass(self):
+        # The class would need to overwrite trace to ensure single-element
+        # output also has the right subclass.
+        class MyArray(np.ndarray):
+            pass
+
+        b = np.arange(8).reshape((2, 2, 2)).view(MyArray)
+        t = b.trace()
+        assert isinstance(t, MyArray)
+
+    def test_put(self):
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+        for dt in icodes + fcodes + 'O':
+            tgt = np.array([0, 1, 0, 3, 0, 5], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [1, 3, 5])
+            assert_equal(a, tgt.reshape(2, 3))
+
+        for dt in '?':
+            tgt = np.array([False, True, False, True, False, True], dtype=dt)
+
+            # test 1-d
+            a = np.zeros(6, dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt)
+
+            # test 2-d
+            a = np.zeros((2, 3), dtype=dt)
+            a.put([1, 3, 5], [True]*3)
+            assert_equal(a, tgt.reshape(2, 3))
+
+        # check must be writeable
+        a = np.zeros(6)
+        a.flags.writeable = False
+        assert_raises(ValueError, a.put, [1, 3, 5], [1, 3, 5])
+
+        # when calling np.put, make sure a
+        # TypeError is raised if the object
+        # isn't an ndarray
+        bad_array = [1, 2, 3]
+        assert_raises(TypeError, np.put, bad_array, [0, 2], 5)
+
+    def test_ravel(self):
+        a = np.array([[0, 1], [2, 3]])
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_(not a.ravel().flags.owndata)
+        assert_equal(a.ravel('F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='C'), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='F'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='A'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_equal(a.ravel(order='K'), [0, 1, 2, 3])
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+
+        a = np.array([[0, 1], [2, 3]], order='F')
+        assert_equal(a.ravel(), [0, 1, 2, 3])
+        assert_equal(a.ravel(order='A'), [0, 2, 1, 3])
+        assert_equal(a.ravel(order='K'), [0, 2, 1, 3])
+        assert_(not a.ravel(order='A').flags.owndata)
+        assert_(not a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel(), a.reshape(-1))
+        assert_equal(a.ravel(order='A'), a.reshape(-1, order='A'))
+
+        a = np.array([[0, 1], [2, 3]])[::-1, :]
+        assert_equal(a.ravel(), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='C'), [2, 3, 0, 1])
+        assert_equal(a.ravel(order='F'), [2, 0, 3, 1])
+        assert_equal(a.ravel(order='A'), [2, 3, 0, 1])
+        # 'K' doesn't reverse the axes of negative strides
+        assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
+        assert_(a.ravel(order='K').flags.owndata)
+
+        # Test simple 1-d copy behaviour:
+        a = np.arange(10)[::2]
+        assert_(a.ravel('K').flags.owndata)
+        assert_(a.ravel('C').flags.owndata)
+        assert_(a.ravel('F').flags.owndata)
+
+        # Not contiguous and 1-sized axis with non matching stride
+        a = np.arange(2**3 * 2)[::2]
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('K'), np.arange(0, 15, 2))
+
+        # contiguous and 1-sized axis with non matching stride works:
+        a = np.arange(2**3)
+        a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
+        strides = list(a.strides)
+        strides[1] = 123
+        a.strides = strides
+        assert_(np.may_share_memory(a.ravel(order='K'), a))
+        assert_equal(a.ravel(order='K'), np.arange(2**3))
+
+        # Test negative strides (not very interesting since non-contiguous):
+        a = np.arange(4)[::-1].reshape(2, 2)
+        assert_(a.ravel(order='C').flags.owndata)
+        assert_(a.ravel(order='K').flags.owndata)
+        assert_equal(a.ravel('C'), [3, 2, 1, 0])
+        assert_equal(a.ravel('K'), [3, 2, 1, 0])
+
+        # 1-element tidy strides test (NPY_RELAXED_STRIDES_CHECKING):
+        a = np.array([[1]])
+        a.strides = (123, 432)
+        # If the stride is not 8, NPY_RELAXED_STRIDES_CHECKING is messing
+        # them up on purpose:
+        if np.ones(1).strides == (8,):
+            assert_(np.may_share_memory(a.ravel('K'), a))
+            assert_equal(a.ravel('K').strides, (a.dtype.itemsize,))
+
+        for order in ('C', 'F', 'A', 'K'):
+            # 0-d corner case:
+            a = np.array(0)
+            assert_equal(a.ravel(order), [0])
+            assert_(np.may_share_memory(a.ravel(order), a))
+
+        # Test that certain non-inplace ravels work right (mostly) for 'K':
+        b = np.arange(2**4 * 2)[::2].reshape(2, 2, 2, 2)
+        a = b[..., ::2]
+        assert_equal(a.ravel('K'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('C'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('A'), [0, 4, 8, 12, 16, 20, 24, 28])
+        assert_equal(a.ravel('F'), [0, 16, 8, 24, 4, 20, 12, 28])
+
+        a = b[::2, ...]
+        assert_equal(a.ravel('K'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('C'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('A'), [0, 2, 4, 6, 8, 10, 12, 14])
+        assert_equal(a.ravel('F'), [0, 8, 4, 12, 2, 10, 6, 14])
+
+    def test_ravel_subclass(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = np.arange(10).view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+        a = np.arange(10)[::2].view(ArraySubclass)
+        assert_(isinstance(a.ravel('C'), ArraySubclass))
+        assert_(isinstance(a.ravel('F'), ArraySubclass))
+        assert_(isinstance(a.ravel('A'), ArraySubclass))
+        assert_(isinstance(a.ravel('K'), ArraySubclass))
+
+    def test_swapaxes(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        idx = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        b = a.copy()
+        # check exceptions
+        assert_raises(ValueError, a.swapaxes, -5, 0)
+        assert_raises(ValueError, a.swapaxes, 4, 0)
+        assert_raises(ValueError, a.swapaxes, 0, -5)
+        assert_raises(ValueError, a.swapaxes, 0, 4)
+
+        for i in range(-4, 4):
+            for j in range(-4, 4):
+                for k, src in enumerate((a, b)):
+                    c = src.swapaxes(i, j)
+                    # check shape
+                    shape = list(src.shape)
+                    shape[i] = src.shape[j]
+                    shape[j] = src.shape[i]
+                    assert_equal(c.shape, shape, str((i, j, k)))
+                    # check array contents
+                    i0, i1, i2, i3 = [dim-1 for dim in c.shape]
+                    j0, j1, j2, j3 = [dim-1 for dim in src.shape]
+                    assert_equal(src[idx[j0], idx[j1], idx[j2], idx[j3]],
+                                 c[idx[i0], idx[i1], idx[i2], idx[i3]],
+                                 str((i, j, k)))
+                    # check a view is always returned, gh-5260
+                    assert_(not c.flags['OWNDATA'], str((i, j, k)))
+                    # check on non-contiguous input array
+                    if k == 1:
+                        b = c
+
+    def test_conjugate(self):
+        a = np.array([1-1j, 1+1j, 23+23.0j])
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
+        ac = a.conj()
+        assert_equal(a.real, ac.real)
+        assert_equal(a.imag, -ac.imag)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1, 2, 3])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1.0, 2.0, 3.0])
+        ac = a.conj()
+        assert_equal(a, ac)
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1+1j, 1, 2.0], object)
+        ac = a.conj()
+        assert_equal(ac, [k.conjugate() for k in a])
+        assert_equal(ac, a.conjugate())
+        assert_equal(ac, np.conjugate(a))
+
+        a = np.array([1-1j, 1, 2.0, 'f'], object)
+        assert_raises(AttributeError, lambda: a.conj())
+        assert_raises(AttributeError, lambda: a.conjugate())
+
+class TestBinop(object):
+    def test_inplace(self):
+        # test refcount 1 inplace conversion
+        assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
+                                  [0.5, 1.0])
+
+        d = np.array([0.5, 0.5])[::2]
+        assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
+                                  [0.25, 0.5])
+
+        a = np.array([0.5])
+        b = np.array([0.5])
+        c = a + b
+        c = a - b
+        c = a * b
+        c = a / b
+        assert_equal(a, b)
+        assert_almost_equal(c, 1.)
+
+        c = a + b * 2. / b * a - a / b
+        assert_equal(a, b)
+        assert_equal(c, 0.5)
+
+        # true divide
+        a = np.array([5])
+        b = np.array([3])
+        c = (a * a) / b
+
+        assert_almost_equal(c, 25 / 3)
+        assert_equal(a, 5)
+        assert_equal(b, 3)
+
+    def test_extension_incref_elide(self):
+        # test extension (e.g. cython) calling PyNumber_* slots without
+        # increasing the reference counts
+        #
+        # def incref_elide(a):
+        #    d = input.copy() # refcount 1
+        #    return d, d + d # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide
+        d = np.ones(5)
+        orig, res = incref_elide(d)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(orig, d)
+        assert_array_equal(res, d + d)
+
+    def test_extension_incref_elide_stack(self):
+        # scanning if the refcount == 1 object is on the python stack to check
+        # that we are called directly from python is flawed as object may still
+        # be above the stack pointer and we have no access to the top of it
+        #
+        # def incref_elide_l(d):
+        #    return l[4] + l[4] # PyNumber_Add without increasing refcount
+        from numpy.core.multiarray_tests import incref_elide_l
+        # padding with 1 makes sure the object on the stack is not overwriten
+        l = [1, 1, 1, 1, np.ones(5)]
+        res = incref_elide_l(l)
+        # the return original should not be changed to an inplace operation
+        assert_array_equal(l[4], np.ones(5))
+        assert_array_equal(res, l[4] + l[4])
+
+    def test_ufunc_override_rop_precedence(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that __rmul__ and other right-hand operations have
+        # precedence over __numpy_ufunc__
+
+        ops = {
+            '__add__':      ('__radd__', np.add, True),
+            '__sub__':      ('__rsub__', np.subtract, True),
+            '__mul__':      ('__rmul__', np.multiply, True),
+            '__truediv__':  ('__rtruediv__', np.true_divide, True),
+            '__floordiv__': ('__rfloordiv__', np.floor_divide, True),
+            '__mod__':      ('__rmod__', np.remainder, True),
+            '__divmod__':   ('__rdivmod__', None, False),
+            '__pow__':      ('__rpow__', np.power, True),
+            '__lshift__':   ('__rlshift__', np.left_shift, True),
+            '__rshift__':   ('__rrshift__', np.right_shift, True),
+            '__and__':      ('__rand__', np.bitwise_and, True),
+            '__xor__':      ('__rxor__', np.bitwise_xor, True),
+            '__or__':       ('__ror__', np.bitwise_or, True),
+            '__ge__':       ('__le__', np.less_equal, False),
+            '__gt__':       ('__lt__', np.less, False),
+            '__le__':       ('__ge__', np.greater_equal, False),
+            '__lt__':       ('__gt__', np.greater, False),
+            '__eq__':       ('__eq__', np.equal, False),
+            '__ne__':       ('__ne__', np.not_equal, False),
+        }
+
+        class OtherNdarraySubclass(np.ndarray):
+            pass
+
+        class OtherNdarraySubclassWithOverride(np.ndarray):
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+        def check(op_name, ndsubclass):
+            rop_name, np_op, has_iop = ops[op_name]
+
+            if has_iop:
+                iop_name = '__i' + op_name[2:]
+                iop = getattr(operator, iop_name)
+
+            if op_name == "__divmod__":
+                op = divmod
+            else:
+                op = getattr(operator, op_name)
+
+            # Dummy class
+            def __init__(self, *a, **kw):
+                pass
+
+            def __numpy_ufunc__(self, *a, **kw):
+                raise AssertionError(("__numpy_ufunc__ %r %r shouldn't have "
+                                      "been called!") % (a, kw))
+
+            def __op__(self, *other):
+                return "op"
+
+            def __rop__(self, *other):
+                return "rop"
+
+            if ndsubclass:
+                bases = (np.ndarray,)
+            else:
+                bases = (object,)
+
+            dct = {'__init__': __init__,
+                   '__numpy_ufunc__': __numpy_ufunc__,
+                   op_name: __op__}
+            if op_name != rop_name:
+                dct[rop_name] = __rop__
+
+            cls = type("Rop" + rop_name, bases, dct)
+
+            # Check behavior against both bare ndarray objects and a
+            # ndarray subclasses with and without their own override
+            obj = cls((1,), buffer=np.ones(1,))
+
+            arr_objs = [np.array([1]),
+                        np.array([2]).view(OtherNdarraySubclass),
+                        np.array([3]).view(OtherNdarraySubclassWithOverride),
+                        ]
+
+            for arr in arr_objs:
+                err_msg = "%r %r" % (op_name, arr,)
+
+                # Check that ndarray op gives up if it sees a non-subclass
+                if not isinstance(obj, arr.__class__):
+                    assert_equal(getattr(arr, op_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+
+                # Check that the Python binops have priority
+                assert_equal(op(obj, arr), "op", err_msg=err_msg)
+                if op_name == rop_name:
+                    assert_equal(op(arr, obj), "op", err_msg=err_msg)
+                else:
+                    assert_equal(op(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that Python binops have priority also for in-place ops
+                if has_iop:
+                    assert_equal(getattr(arr, iop_name)(obj),
+                                 NotImplemented, err_msg=err_msg)
+                    if op_name != "__pow__":
+                        # inplace pow requires the other object to be
+                        # integer-like?
+                        assert_equal(iop(arr, obj), "rop", err_msg=err_msg)
+
+                # Check that ufunc call __numpy_ufunc__ normally
+                if np_op is not None:
+                    assert_raises(AssertionError, np_op, arr, obj,
+                                  err_msg=err_msg)
+                    assert_raises(AssertionError, np_op, obj, arr,
+                                  err_msg=err_msg)
+
+        # Check all binary operations
+        for op_name in sorted(ops.keys()):
+            yield check, op_name, True
+            yield check, op_name, False
+
+    def test_ufunc_override_rop_simple(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check parts of the binary op overriding behavior in an
+        # explicit test case that is easier to understand.
+        class SomeClass(object):
+            def __numpy_ufunc__(self, *a, **kw):
+                return "ufunc"
+
+            def __mul__(self, other):
+                return 123
+
+            def __rmul__(self, other):
+                return 321
+
+            def __rsub__(self, other):
+                return "no subs for me"
+
+            def __gt__(self, other):
+                return "yep"
+
+            def __lt__(self, other):
+                return "nope"
+
+        class SomeClass2(SomeClass, np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if ufunc is np.multiply or ufunc is np.bitwise_and:
+                    return "ufunc"
+                else:
+                    inputs = list(inputs)
+                    if i < len(inputs):
+                        inputs[i] = np.asarray(self)
+                    func = getattr(ufunc, method)
+                    if ('out' in kw) and (kw['out'] is not None):
+                        kw['out'] = np.asarray(kw['out'])
+                    r = func(*inputs, **kw)
+                    x = self.__class__(r.shape, dtype=r.dtype)
+                    x[...] = r
+                    return x
+
+        class SomeClass3(SomeClass2):
+            def __rsub__(self, other):
+                return "sub for me"
+
+        arr = np.array([0])
+        obj = SomeClass()
+        obj2 = SomeClass2((1,), dtype=np.int_)
+        obj2[0] = 9
+        obj3 = SomeClass3((1,), dtype=np.int_)
+        obj3[0] = 4
+
+        # obj is first, so should get to define outcome.
+        assert_equal(obj * arr, 123)
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        assert_equal(arr * obj, 321)
+        # obj is second, but has __numpy_ufunc__ and defines __rsub__.
+        assert_equal(arr - obj, "no subs for me")
+        # obj is second, but has __numpy_ufunc__ and defines __lt__.
+        assert_equal(arr > obj, "nope")
+        # obj is second, but has __numpy_ufunc__ and defines __gt__.
+        assert_equal(arr < obj, "yep")
+        # Called as a ufunc, obj.__numpy_ufunc__ is used.
+        assert_equal(np.multiply(arr, obj), "ufunc")
+        # obj is second, but has __numpy_ufunc__ and defines __rmul__.
+        arr *= obj
+        assert_equal(arr, 321)
+
+        # obj2 is an ndarray subclass, so CPython takes care of the same rules.
+        assert_equal(obj2 * arr, 123)
+        assert_equal(arr * obj2, 321)
+        assert_equal(arr - obj2, "no subs for me")
+        assert_equal(arr > obj2, "nope")
+        assert_equal(arr < obj2, "yep")
+        # Called as a ufunc, obj2.__numpy_ufunc__ is called.
+        assert_equal(np.multiply(arr, obj2), "ufunc")
+        # Also when the method is not overridden.
+        assert_equal(arr & obj2, "ufunc")
+        arr *= obj2
+        assert_equal(arr, 321)
+
+        obj2 += 33
+        assert_equal(obj2[0], 42)
+        assert_equal(obj2.sum(), 42)
+        assert_(isinstance(obj2, SomeClass2))
+
+        # Obj3 is subclass that defines __rsub__.  CPython calls it.
+        assert_equal(arr - obj3, "sub for me")
+        assert_equal(obj2 - obj3, "sub for me")
+        # obj3 is a subclass that defines __rmul__.  CPython calls it.
+        assert_equal(arr * obj3, 321)
+        # But not here, since obj3.__rmul__ is obj2.__rmul__.
+        assert_equal(obj2 * obj3, 123)
+        # And of course, here obj3.__mul__ should be called.
+        assert_equal(obj3 * obj2, 123)
+        # obj3 defines __numpy_ufunc__ but obj3.__radd__ is obj2.__radd__.
+        # (and both are just ndarray.__radd__); see #4815.
+        res = obj2 + obj3
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass2))
+        # Since obj3 is a subclass, it should have precedence, like CPython
+        # would give, even though obj2 has __numpy_ufunc__ and __radd__.
+        # See gh-4815 and gh-5747.
+        res = obj3 + obj2
+        assert_equal(res, 46)
+        assert_(isinstance(res, SomeClass3))
+
+    def test_ufunc_override_normalize_signature(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # gh-5674
+        class SomeClass(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return kw
+
+        a = SomeClass()
+        kw = np.add(a, [1])
+        assert_('sig' not in kw and 'signature' not in kw)
+        kw = np.add(a, [1], sig='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+        kw = np.add(a, [1], signature='ii->i')
+        assert_('sig' not in kw and 'signature' in kw)
+        assert_equal(kw['signature'], 'ii->i')
+
+    def test_numpy_ufunc_index(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Check that index is set appropriately, also if only an output
+        # is passed on (latter is another regression tests for github bug 4753)
+        class CheckIndex(object):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                return i
+
+        a = CheckIndex()
+        dummy = np.arange(2.)
+        # 1 input, 1 output
+        assert_equal(np.sin(a), 0)
+        assert_equal(np.sin(dummy, a), 1)
+        assert_equal(np.sin(dummy, out=a), 1)
+        assert_equal(np.sin(dummy, out=(a,)), 1)
+        assert_equal(np.sin(a, a), 0)
+        assert_equal(np.sin(a, out=a), 0)
+        assert_equal(np.sin(a, out=(a,)), 0)
+        # 1 input, 2 outputs
+        assert_equal(np.modf(dummy, a), 1)
+        assert_equal(np.modf(dummy, None, a), 2)
+        assert_equal(np.modf(dummy, dummy, a), 2)
+        assert_equal(np.modf(dummy, out=a), 1)
+        assert_equal(np.modf(dummy, out=(a,)), 1)
+        assert_equal(np.modf(dummy, out=(a, None)), 1)
+        assert_equal(np.modf(dummy, out=(a, dummy)), 1)
+        assert_equal(np.modf(dummy, out=(None, a)), 2)
+        assert_equal(np.modf(dummy, out=(dummy, a)), 2)
+        assert_equal(np.modf(a, out=(dummy, a)), 0)
+        # 2 inputs, 1 output
+        assert_equal(np.add(a, dummy), 0)
+        assert_equal(np.add(dummy, a), 1)
+        assert_equal(np.add(dummy, dummy, a), 2)
+        assert_equal(np.add(dummy, a, a), 1)
+        assert_equal(np.add(dummy, dummy, out=a), 2)
+        assert_equal(np.add(dummy, dummy, out=(a,)), 2)
+        assert_equal(np.add(a, dummy, out=a), 0)
+
+    def test_out_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # regression test for github bug 4753
+        class OutClass(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kw):
+                if 'out' in kw:
+                    tmp_kw = kw.copy()
+                    tmp_kw.pop('out')
+                    func = getattr(ufunc, method)
+                    kw['out'][...] = func(*inputs, **tmp_kw)
+
+        A = np.array([0]).view(OutClass)
+        B = np.array([5])
+        C = np.array([6])
+        np.multiply(C, B, A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+        A[0] = 0
+        np.multiply(C, B, out=A)
+        assert_equal(A[0], 30)
+        assert_(isinstance(A, OutClass))
+
+
+class TestCAPI(TestCase):
+    def test_IsPythonScalar(self):
+        from numpy.core.multiarray_tests import IsPythonScalar
+        assert_(IsPythonScalar(b'foobar'))
+        assert_(IsPythonScalar(1))
+        assert_(IsPythonScalar(2**80))
+        assert_(IsPythonScalar(2.))
+        assert_(IsPythonScalar("a"))
+
+
+class TestSubscripting(TestCase):
+    def test_test_zero_rank(self):
+        x = np.array([1, 2, 3])
+        self.assertTrue(isinstance(x[0], np.int_))
+        if sys.version_info[0] < 3:
+            self.assertTrue(isinstance(x[0], int))
+        self.assertTrue(type(x[0, ...]) is np.ndarray)
+
+
+class TestPickling(TestCase):
+    def test_roundtrip(self):
+        import pickle
+        carray = np.array([[2, 9], [7, 0], [3, 8]])
+        DATA = [
+            carray,
+            np.transpose(carray),
+            np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int),
+                                               ('c', float)])
+        ]
+
+        for a in DATA:
+            assert_equal(a, pickle.loads(a.dumps()), err_msg="%r" % a)
+
+    def _loads(self, obj):
+        if sys.version_info[0] >= 3:
+            return np.loads(obj, encoding='latin1')
+        else:
+            return np.loads(obj)
+
+    # version 0 pickles, using protocol=2 to pickle
+    # version 0 doesn't have a version field
+    def test_version0_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version0_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    # version 1 pickles, using protocol=2 to pickle
+    def test_version1_int8(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
+        a = np.array([1, 2, 3, 4], dtype=np.int8)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_float32(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(K\x01U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
+        a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_version1_object(self):
+        s = '\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
+        a = np.array([{'a': 1}, {'b': 2}])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+    def test_subarray_int_shape(self):
+        s = "cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'V6'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'a'\np12\ng3\ntp13\n(dp14\ng12\n(g7\n(S'V4'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'|'\np18\n(g7\n(S'i1'\np19\nI0\nI1\ntp20\nRp21\n(I3\nS'|'\np22\nNNNI-1\nI-1\nI0\ntp23\nb(I2\nI2\ntp24\ntp25\nNNI4\nI1\nI0\ntp26\nbI0\ntp27\nsg3\n(g7\n(S'V2'\np28\nI0\nI1\ntp29\nRp30\n(I3\nS'|'\np31\n(g21\nI2\ntp32\nNNI2\nI1\nI0\ntp33\nbI4\ntp34\nsI6\nI1\nI0\ntp35\nbI00\nS'\\x01\\x01\\x01\\x01\\x01\\x02'\np36\ntp37\nb."
+        a = np.array([(1, (1, 2))], dtype=[('a', 'i1', (2, 2)), ('b', 'i1', 2)])
+        p = self._loads(asbytes(s))
+        assert_equal(a, p)
+
+
+class TestFancyIndexing(TestCase):
+    def test_list(self):
+        x = np.ones((1, 1))
+        x[:, [0]] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+
+        x = np.ones((1, 1, 1))
+        x[:, :, [0]] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_tuple(self):
+        x = np.ones((1, 1))
+        x[:, (0,)] = 2.0
+        assert_array_equal(x, np.array([[2.0]]))
+        x = np.ones((1, 1, 1))
+        x[:, :, (0,)] = 2.0
+        assert_array_equal(x, np.array([[[2.0]]]))
+
+    def test_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        assert_array_equal(x[m], np.array([2]))
+
+    def test_mask2(self):
+        x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        assert_array_equal(x[m], np.array([[5, 6, 7, 8]]))
+        assert_array_equal(x[m2], np.array([2, 5]))
+        assert_array_equal(x[m3], np.array([2]))
+
+    def test_assign_mask(self):
+        x = np.array([1, 2, 3, 4])
+        m = np.array([0, 1, 0, 0], bool)
+        x[m] = 5
+        assert_array_equal(x, np.array([1, 5, 3, 4]))
+
+    def test_assign_mask2(self):
+        xorig = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        m = np.array([0, 1], bool)
+        m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
+        m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
+        x = xorig.copy()
+        x[m] = 10
+        assert_array_equal(x, np.array([[1, 2, 3, 4], [10, 10, 10, 10]]))
+        x = xorig.copy()
+        x[m2] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [10, 6, 7, 8]]))
+        x = xorig.copy()
+        x[m3] = 10
+        assert_array_equal(x, np.array([[1, 10, 3, 4], [5, 6, 7, 8]]))
+
+
+class TestStringCompare(TestCase):
+    def test_string(self):
+        g1 = np.array(["This", "is", "example"])
+        g2 = np.array(["This", "was", "example"])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
+
+    def test_mixed(self):
+        g1 = np.array(["spam", "spa", "spammer", "and eggs"])
+        g2 = "spam"
+        assert_array_equal(g1 == g2, [x == g2 for x in g1])
+        assert_array_equal(g1 != g2, [x != g2 for x in g1])
+        assert_array_equal(g1 < g2, [x < g2 for x in g1])
+        assert_array_equal(g1 > g2, [x > g2 for x in g1])
+        assert_array_equal(g1 <= g2, [x <= g2 for x in g1])
+        assert_array_equal(g1 >= g2, [x >= g2 for x in g1])
+
+    def test_unicode(self):
+        g1 = np.array([sixu("This"), sixu("is"), sixu("example")])
+        g2 = np.array([sixu("This"), sixu("was"), sixu("example")])
+        assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 < g2,  [g1[i] < g2[i] for i in [0, 1, 2]])
+        assert_array_equal(g1 > g2,  [g1[i] > g2[i] for i in [0, 1, 2]])
+
+
+class TestArgmax(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 5),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2015-11-20T12:20:59'),
+          np.datetime64('1932-09-23T10:10:13'),
+          np.datetime64('2014-10-10T03:50:30')], 3),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 4),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 0),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 3),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 0),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 1),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 2),
+
+        ([False, False, False, False, True], 4),
+        ([False, False, False, True, False], 3),
+        ([True, False, False, False, False], 0),
+        ([True, False, True, False, False], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amax = a.max(i)
+            aargmax = a.argmax(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmax(arr)], np.max(arr), err_msg="%r" % arr)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmax, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmax(-1, out=out)
+        assert_equal(out, a.argmax(-1))
+
+    def test_argmax_unicode(self):
+        d = np.zeros(6031, dtype='<U9')
+        d[5942] = "as"
+        assert_equal(d.argmax(), 5942)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmax and numpy.argmax support out/axis args
+        a = np.random.normal(size=(2,3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.zeros(2, dtype=int)
+        assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.zeros(3, dtype=int)
+        assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmax_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmax(), 0)
+        a[3] = 10
+        assert_equal(a.argmax(), 3)
+        a[1] = 30
+        assert_equal(a.argmax(), 1)
+
+
+class TestArgmin(TestCase):
+
+    nan_arr = [
+        ([0, 1, 2, 3, np.nan], 4),
+        ([0, 1, 2, np.nan, 3], 3),
+        ([np.nan, 0, 1, 2, 3], 0),
+        ([np.nan, 0, np.nan, 2, 3], 0),
+        ([0, 1, 2, 3, complex(0, np.nan)], 4),
+        ([0, 1, 2, 3, complex(np.nan, 0)], 4),
+        ([0, 1, 2, complex(np.nan, 0), 3], 3),
+        ([0, 1, 2, complex(0, np.nan), 3], 3),
+        ([complex(0, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
+        ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
+
+        ([complex(0, 0), complex(0, 2), complex(0, 1)], 0),
+        ([complex(1, 0), complex(0, 2), complex(0, 1)], 2),
+        ([complex(1, 0), complex(0, 2), complex(1, 1)], 1),
+
+        ([np.datetime64('1923-04-14T12:43:12'),
+          np.datetime64('1994-06-21T14:43:15'),
+          np.datetime64('2001-10-15T04:10:32'),
+          np.datetime64('1995-11-25T16:02:16'),
+          np.datetime64('2005-01-04T03:14:12'),
+          np.datetime64('2041-12-03T14:05:03')], 0),
+        ([np.datetime64('1935-09-14T04:40:11'),
+          np.datetime64('1949-10-12T12:32:11'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('2014-11-20T12:20:59'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        # Assorted tests with NaTs
+        ([np.datetime64('NaT'),
+          np.datetime64('NaT'),
+          np.datetime64('2010-01-03T05:14:12'),
+          np.datetime64('NaT'),
+          np.datetime64('2015-09-23T10:10:13'),
+          np.datetime64('1932-10-10T03:50:30')], 5),
+        ([np.datetime64('2059-03-14T12:43:12'),
+          np.datetime64('1996-09-21T14:43:15'),
+          np.datetime64('NaT'),
+          np.datetime64('2022-12-25T16:02:16'),
+          np.datetime64('1963-10-04T03:14:12'),
+          np.datetime64('2013-05-08T18:15:23')], 4),
+        ([np.timedelta64(2, 's'),
+          np.timedelta64(1, 's'),
+          np.timedelta64('NaT', 's'),
+          np.timedelta64(3, 's')], 1),
+        ([np.timedelta64('NaT', 's')] * 3, 0),
+
+        ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
+          timedelta(days=-1, seconds=23)], 2),
+        ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
+          timedelta(days=5, seconds=14)], 0),
+        ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
+          timedelta(days=10, seconds=43)], 1),
+
+        ([True, True, True, True, False], 4),
+        ([True, True, True, False, True], 3),
+        ([False, True, True, True, True], 0),
+        ([False, True, False, True, True], 0),
+    ]
+
+    def test_all(self):
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            amin = a.min(i)
+            aargmin = a.argmin(i)
+            axes = list(range(a.ndim))
+            axes.remove(i)
+            assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
+
+    def test_combinations(self):
+        for arr, pos in self.nan_arr:
+            assert_equal(np.argmin(arr), pos, err_msg="%r" % arr)
+            assert_equal(arr[np.argmin(arr)], np.min(arr), err_msg="%r" % arr)
+
+    def test_minimum_signed_integers(self):
+
+        a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
+        assert_equal(np.argmin(a), 1)
+
+        a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
+        assert_equal(np.argmin(a), 1)
+
+    def test_output_shape(self):
+        # see also gh-616
+        a = np.ones((10, 5))
+        # Check some simple shape mismatches
+        out = np.ones(11, dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones((2, 5), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        # these could be relaxed possibly (used to allow even the previous)
+        out = np.ones((1, 10), dtype=np.int_)
+        assert_raises(ValueError, a.argmin, -1, out)
+
+        out = np.ones(10, dtype=np.int_)
+        a.argmin(-1, out=out)
+        assert_equal(out, a.argmin(-1))
+
+    def test_argmin_unicode(self):
+        d = np.ones(6031, dtype='<U9')
+        d[6001] = "0"
+        assert_equal(d.argmin(), 6001)
+
+    def test_np_vs_ndarray(self):
+        # make sure both ndarray.argmin and numpy.argmin support out/axis args
+        a = np.random.normal(size=(2, 3))
+
+        # check positional args
+        out1 = np.zeros(2, dtype=int)
+        out2 = np.ones(2, dtype=int)
+        assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
+        assert_equal(out1, out2)
+
+        # check keyword args
+        out1 = np.zeros(3, dtype=int)
+        out2 = np.ones(3, dtype=int)
+        assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
+        assert_equal(out1, out2)
+
+    def test_object_argmin_with_NULLs(self):
+        # See gh-6032
+        a = np.empty(4, dtype='O')
+        ctypes.memset(a.ctypes.data, 0, a.nbytes)
+        assert_equal(a.argmin(), 0)
+        a[3] = 30
+        assert_equal(a.argmin(), 3)
+        a[1] = 10
+        assert_equal(a.argmin(), 1)
+
+
+class TestMinMax(TestCase):
+
+    def test_scalar(self):
+        assert_raises(ValueError, np.amax, 1, 1)
+        assert_raises(ValueError, np.amin, 1, 1)
+
+        assert_equal(np.amax(1, axis=0), 1)
+        assert_equal(np.amin(1, axis=0), 1)
+        assert_equal(np.amax(1, axis=None), 1)
+        assert_equal(np.amin(1, axis=None), 1)
+
+    def test_axis(self):
+        assert_raises(ValueError, np.amax, [1, 2, 3], 1000)
+        assert_equal(np.amax([[1, 2, 3]], axis=1), 3)
+
+    def test_datetime(self):
+        # NaTs are ignored
+        for dtype in ('m8[s]', 'm8[Y]'):
+            a = np.arange(10).astype(dtype)
+            a[3] = 'NaT'
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[9])
+            a[0] = 'NaT'
+            assert_equal(np.amin(a), a[1])
+            assert_equal(np.amax(a), a[9])
+            a.fill('NaT')
+            assert_equal(np.amin(a), a[0])
+            assert_equal(np.amax(a), a[0])
+
+
+class TestNewaxis(TestCase):
+    def test_basic(self):
+        sk = np.array([0, -0.1, 0.1])
+        res = 250*sk[:, np.newaxis]
+        assert_almost_equal(res.ravel(), 250*sk)
+
+
+class TestClip(TestCase):
+    def _check_range(self, x, cmin, cmax):
+        assert_(np.all(x >= cmin))
+        assert_(np.all(x <= cmax))
+
+    def _clip_type(self, type_group, array_max,
+                   clip_min, clip_max, inplace=False,
+                   expected_min=None, expected_max=None):
+        if expected_min is None:
+            expected_min = clip_min
+        if expected_max is None:
+            expected_max = clip_max
+
+        for T in np.sctypes[type_group]:
+            if sys.byteorder == 'little':
+                byte_orders = ['=', '>']
+            else:
+                byte_orders = ['<', '=']
+
+            for byteorder in byte_orders:
+                dtype = np.dtype(T).newbyteorder(byteorder)
+
+                x = (np.random.random(1000) * array_max).astype(dtype)
+                if inplace:
+                    x.clip(clip_min, clip_max, x)
+                else:
+                    x = x.clip(clip_min, clip_max)
+                    byteorder = '='
+
+                if x.dtype.byteorder == '|':
+                    byteorder = '|'
+                assert_equal(x.dtype.byteorder, byteorder)
+                self._check_range(x, expected_min, expected_max)
+        return x
+
+    def test_basic(self):
+        for inplace in [False, True]:
+            self._clip_type(
+                'float', 1024, -12.8, 100.2, inplace=inplace)
+            self._clip_type(
+                'float', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'int', 1024, -120, 100.5, inplace=inplace)
+            self._clip_type(
+                'int', 1024, 0, 0, inplace=inplace)
+
+            self._clip_type(
+                'uint', 1024, 0, 0, inplace=inplace)
+            self._clip_type(
+                'uint', 1024, -120, 100, inplace=inplace, expected_min=0)
+
+    def test_record_array(self):
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                       dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
+        y = rec['x'].clip(-0.3, 0.5)
+        self._check_range(y, -0.3, 0.5)
+
+    def test_max_or_min(self):
+        val = np.array([0, 1, 2, 3, 4, 5, 6, 7])
+        x = val.clip(3)
+        assert_(np.all(x >= 3))
+        x = val.clip(min=3)
+        assert_(np.all(x >= 3))
+        x = val.clip(max=4)
+        assert_(np.all(x <= 4))
+
+
+class TestCompress(TestCase):
+    def test_axis(self):
+        tgt = [[5, 6, 7, 8, 9]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+        tgt = [[1, 3], [6, 8]]
+        out = np.compress([0, 1, 0, 1, 0], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_truncate(self):
+        tgt = [[1], [6]]
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr, axis=1)
+        assert_equal(out, tgt)
+
+    def test_flatten(self):
+        arr = np.arange(10).reshape(2, 5)
+        out = np.compress([0, 1], arr)
+        assert_equal(out, 1)
+
+
+class TestPutmask(object):
+    def tst_basic(self, x, T, mask, val):
+        np.putmask(x, mask, val)
+        assert_(np.all(x[mask] == T(val)))
+        assert_(x.dtype == T)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(1000)*100
+        mask = x < 40
+
+        for val in [-100, 0, 15]:
+            for types in np.sctypes.values():
+                for T in types:
+                    if T not in unchecked_types:
+                        yield self.tst_basic, x.copy().astype(T), T, mask, val
+
+    def test_mask_size(self):
+        assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5)
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        np.putmask(x, [True, False, True], -1)
+        assert_array_equal(x, [-1, 2, -1])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        np.putmask(rec['x'], [True, False], 10)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [2, 4])
+        assert_array_equal(rec['z'], [3, 3])
+        np.putmask(rec['y'], [True, False], 11)
+        assert_array_equal(rec['x'], [10, 5])
+        assert_array_equal(rec['y'], [11, 4])
+        assert_array_equal(rec['z'], [3, 3])
+
+
+class TestTake(object):
+    def tst_basic(self, x):
+        ind = list(range(x.shape[0]))
+        assert_array_equal(x.take(ind, axis=0), x)
+
+    def test_ip_types(self):
+        unchecked_types = [str, unicode, np.void, object]
+
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        for types in np.sctypes.values():
+            for T in types:
+                if T not in unchecked_types:
+                    yield self.tst_basic, x.copy().astype(T)
+
+    def test_raise(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_raises(IndexError, x.take, [0, 1, 2], axis=0)
+        assert_raises(IndexError, x.take, [-3], axis=0)
+        assert_array_equal(x.take([-1], axis=0)[0], x[1])
+
+    def test_clip(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='clip')[0], x[0])
+        assert_array_equal(x.take([2], axis=0, mode='clip')[0], x[1])
+
+    def test_wrap(self):
+        x = np.random.random(24)*100
+        x.shape = 2, 3, 4
+        assert_array_equal(x.take([-1], axis=0, mode='wrap')[0], x[1])
+        assert_array_equal(x.take([2], axis=0, mode='wrap')[0], x[0])
+        assert_array_equal(x.take([3], axis=0, mode='wrap')[0], x[1])
+
+    def tst_byteorder(self, dtype):
+        x = np.array([1, 2, 3], dtype)
+        assert_array_equal(x.take([0, 2, 1]), [1, 3, 2])
+
+    def test_ip_byteorder(self):
+        for dtype in ('>i4', '<i4'):
+            yield self.tst_byteorder, dtype
+
+    def test_record_array(self):
+        # Note mixed byteorder.
+        rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
+                      dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
+        rec1 = rec.take([1])
+        assert_(rec1['x'] == 5.0 and rec1['y'] == 4.0)
+
+
+class TestLexsort(TestCase):
+    def test_basic(self):
+        a = [1, 2, 1, 3, 1, 5]
+        b = [0, 4, 5, 6, 2, 3]
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([0, 4, 2, 1, 3, 5])
+        assert_array_equal(idx, expected_idx)
+
+        x = np.vstack((b, a))
+        idx = np.lexsort(x)
+        assert_array_equal(idx, expected_idx)
+
+        assert_array_equal(x[1][idx], np.sort(x[1]))
+
+    def test_datetime(self):
+        a = np.array([0,0,0], dtype='datetime64[D]')
+        b = np.array([2,1,0], dtype='datetime64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+        a = np.array([0,0,0], dtype='timedelta64[D]')
+        b = np.array([2,1,0], dtype='timedelta64[D]')
+        idx = np.lexsort((b, a))
+        expected_idx = np.array([2, 1, 0])
+        assert_array_equal(idx, expected_idx)
+
+    def test_object(self):  # gh-6312
+        a = np.random.choice(10, 1000)
+        b = np.random.choice(['abc', 'xy', 'wz', 'efghi', 'qwst', 'x'], 1000)
+
+        for u in a, b:
+            left = np.lexsort((u.astype('O'),))
+            right = np.argsort(u, kind='mergesort')
+            assert_array_equal(left, right)
+
+        for u, v in (a, b), (b, a):
+            idx = np.lexsort((u, v))
+            assert_array_equal(idx, np.lexsort((u.astype('O'), v)))
+            assert_array_equal(idx, np.lexsort((u, v.astype('O'))))
+            u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
+            assert_array_equal(idx, np.lexsort((u, v)))
+
+
+class TestIO(object):
+    """Test tofile, fromfile, tobytes, and fromstring"""
+
+    def setUp(self):
+        shape = (2, 4, 3)
+        rand = np.random.random
+        self.x = rand(shape) + rand(shape).astype(np.complex)*1j
+        self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
+        self.dtype = self.x.dtype
+        self.tempdir = tempfile.mkdtemp()
+        self.filename = tempfile.mktemp(dir=self.tempdir)
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def test_nofile(self):
+        # this should probably be supported as a file
+        # but for now test for proper errors
+        b = io.BytesIO()
+        assert_raises(IOError, np.fromfile, b, np.uint8, 80)
+        d = np.ones(7);
+        assert_raises(IOError, lambda x: x.tofile(b), d)
+
+    def test_bool_fromstring(self):
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        y = np.fromstring('1 0 -2.3 0.0', sep=' ', dtype=np.bool_)
+        assert_array_equal(v, y)
+
+    def test_uint64_fromstring(self):
+        d = np.fromstring("9923372036854775807 104783749223640",
+                          dtype=np.uint64, sep=' ')
+        e = np.array([9923372036854775807, 104783749223640], dtype=np.uint64)
+        assert_array_equal(d, e)
+
+    def test_int64_fromstring(self):
+        d = np.fromstring("-25041670086757 104783749223640",
+                          dtype=np.int64, sep=' ')
+        e = np.array([-25041670086757, 104783749223640], dtype=np.int64)
+        assert_array_equal(d, e)
+
+    def test_empty_files_binary(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename)
+        assert_(y.size == 0, "Array not empty")
+
+    def test_empty_files_text(self):
+        f = open(self.filename, 'w')
+        f.close()
+        y = np.fromfile(self.filename, sep=" ")
+        assert_(y.size == 0, "Array not empty")
+
+    def test_roundtrip_file(self):
+        f = open(self.filename, 'wb')
+        self.x.tofile(f)
+        f.close()
+        # NB. doesn't work with flush+seek, due to use of C stdio
+        f = open(self.filename, 'rb')
+        y = np.fromfile(f, dtype=self.dtype)
+        f.close()
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_filename(self):
+        self.x.tofile(self.filename)
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_roundtrip_binary_str(self):
+        s = self.x.tobytes()
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+        s = self.x.tobytes('F')
+        y = np.fromstring(s, dtype=self.dtype)
+        assert_array_equal(y, self.x.flatten('F'))
+
+    def test_roundtrip_str(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(str, x))
+        y = np.fromstring(s, sep="@")
+        # NB. str imbues less precision
+        nan_mask = ~np.isfinite(x)
+        assert_array_equal(x[nan_mask], y[nan_mask])
+        assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
+
+    def test_roundtrip_repr(self):
+        x = self.x.real.ravel()
+        s = "@".join(map(repr, x))
+        y = np.fromstring(s, sep="@")
+        assert_array_equal(x, y)
+
+    def test_unbuffered_fromfile(self):
+        # gh-6246
+        self.x.tofile(self.filename)
+
+        def fail(*args, **kwargs):
+            raise io.IOError('Can not tell or seek')
+
+        f = io.open(self.filename, 'rb', buffering=0)
+        f.seek = fail
+        f.tell = fail
+        y = np.fromfile(self.filename, dtype=self.dtype)
+        assert_array_equal(y, self.x.flat)
+
+    def test_largish_file(self):
+        # check the fallocate path on files > 16MB
+        d = np.zeros(4 * 1024 ** 2)
+        d.tofile(self.filename)
+        assert_equal(os.path.getsize(self.filename), d.nbytes)
+        assert_array_equal(d, np.fromfile(self.filename));
+        # check offset
+        with open(self.filename, "r+b") as f:
+            f.seek(d.nbytes)
+            d.tofile(f)
+            assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+
+    def test_file_position_after_fromfile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.close()
+
+            for mode in ['rb', 'r+b']:
+                err_msg = "%d %s" % (size, mode)
+
+                f = open(self.filename, mode)
+                f.read(2)
+                np.fromfile(f, dtype=np.float64, count=1)
+                pos = f.tell()
+                f.close()
+                assert_equal(pos, 10, err_msg=err_msg)
+
+    def test_file_position_after_tofile(self):
+        # gh-4118
+        sizes = [io.DEFAULT_BUFFER_SIZE//8,
+                 io.DEFAULT_BUFFER_SIZE,
+                 io.DEFAULT_BUFFER_SIZE*8]
+
+        for size in sizes:
+            err_msg = "%d" % (size,)
+
+            f = open(self.filename, 'wb')
+            f.seek(size-1)
+            f.write(b'\0')
+            f.seek(10)
+            f.write(b'12')
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
+
+            f = open(self.filename, 'r+b')
+            f.read(2)
+            f.seek(0, 1)  # seek between read&write required by ANSI C
+            np.array([0], dtype=np.float64).tofile(f)
+            pos = f.tell()
+            f.close()
+            assert_equal(pos, 10, err_msg=err_msg)
+
+    def _check_from(self, s, value, **kw):
+        y = np.fromstring(asbytes(s), **kw)
+        assert_array_equal(y, value)
+
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, **kw)
+        assert_array_equal(y, value)
+
+    def test_nan(self):
+        self._check_from(
+            "nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
+            [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
+            sep=' ')
+
+    def test_inf(self):
+        self._check_from(
+            "inf +inf -inf infinity -Infinity iNfInItY -inF",
+            [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
+            sep=' ')
+
+    def test_numbers(self):
+        self._check_from("1.234 -1.234 .3 .3e55 -123133.1231e+133",
+                         [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+
+    def test_binary(self):
+        self._check_from('\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+                         np.array([1, 2, 3, 4]),
+                         dtype='<f4')
+
+    @dec.slow  # takes > 1 minute on mechanical hard drive
+    def test_big_binary(self):
+        """Test workarounds for 32-bit limited fwrite, fseek, and ftell
+        calls in windows. These normally would hang doing something like this.
+        See http://projects.scipy.org/numpy/ticket/1660"""
+        if sys.platform != 'win32':
+            return
+        try:
+            # before workarounds, only up to 2**32-1 worked
+            fourgbplus = 2**32 + 2**16
+            testbytes = np.arange(8, dtype=np.int8)
+            n = len(testbytes)
+            flike = tempfile.NamedTemporaryFile()
+            f = flike.file
+            np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
+            flike.seek(0)
+            a = np.fromfile(f, dtype=np.int8)
+            flike.close()
+            assert_(len(a) == fourgbplus)
+            # check only start and end for speed:
+            assert_((a[:n] == testbytes).all())
+            assert_((a[-n:] == testbytes).all())
+        except (MemoryError, ValueError):
+            pass
+
+    def test_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], sep=',')
+
+    def test_counted_string(self):
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3.], count=3, sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+
+    def test_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3, 4], dtype=int, sep=' ')
+
+    def test_counted_string_with_ws(self):
+        self._check_from('1 2  3     4   ', [1, 2, 3], count=3, dtype=int,
+                         sep=' ')
+
+    def test_ascii(self):
+        self._check_from('1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
+        self._check_from('1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
+
+    def test_malformed(self):
+        self._check_from('1.234 1,234', [1.234, 1.], sep=' ')
+
+    def test_long_sep(self):
+        self._check_from('1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
+
+    def test_dtype(self):
+        v = np.array([1, 2, 3, 4], dtype=np.int_)
+        self._check_from('1,2,3,4', v, sep=',', dtype=np.int_)
+
+    def test_dtype_bool(self):
+        # can't use _check_from because fromstring can't handle True/False
+        v = np.array([True, False, True, False], dtype=np.bool_)
+        s = '1,0,-2.3,0'
+        f = open(self.filename, 'wb')
+        f.write(asbytes(s))
+        f.close()
+        y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
+        assert_(y.dtype == '?')
+        assert_array_equal(y, v)
+
+    def test_tofile_sep(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        #assert_equal(s, '1.51,2.0,3.51,4.0')
+        y = np.array([float(p) for p in s.split(',')])
+        assert_array_equal(x,y)
+
+    def test_tofile_format(self):
+        x = np.array([1.51, 2, 3.51, 4], dtype=float)
+        f = open(self.filename, 'w')
+        x.tofile(f, sep=',', format='%.2f')
+        f.close()
+        f = open(self.filename, 'r')
+        s = f.read()
+        f.close()
+        assert_equal(s, '1.51,2.00,3.51,4.00')
+
+    def test_locale(self):
+        in_foreign_locale(self.test_numbers)()
+        in_foreign_locale(self.test_nan)()
+        in_foreign_locale(self.test_inf)()
+        in_foreign_locale(self.test_counted_string)()
+        in_foreign_locale(self.test_ascii)()
+        in_foreign_locale(self.test_malformed)()
+        in_foreign_locale(self.test_tofile_sep)()
+        in_foreign_locale(self.test_tofile_format)()
+
+
+class TestFromBuffer(object):
+    def tst_basic(self, buffer, expected, kwargs):
+        assert_array_equal(np.frombuffer(buffer,**kwargs), expected)
+
+    def test_ip_basic(self):
+        for byteorder in ['<', '>']:
+            for dtype in [float, int, np.complex]:
+                dt = np.dtype(dtype).newbyteorder(byteorder)
+                x = (np.random.random((4, 7))*5).astype(dt)
+                buf = x.tobytes()
+                yield self.tst_basic, buf, x.flat, {'dtype':dt}
+
+    def test_empty(self):
+        yield self.tst_basic, asbytes(''), np.array([]), {}
+
+
+class TestFlat(TestCase):
+    def setUp(self):
+        a0 = np.arange(20.0)
+        a = a0.reshape(4, 5)
+        a0.shape = (4, 5)
+        a.flags.writeable = False
+        self.a = a
+        self.b = a[::2, ::2]
+        self.a0 = a0
+        self.b0 = a0[::2, ::2]
+
+    def test_contiguous(self):
+        testpassed = False
+        try:
+            self.a.flat[12] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.a.flat[12] == 12.0)
+
+    def test_discontiguous(self):
+        testpassed = False
+        try:
+            self.b.flat[4] = 100.0
+        except ValueError:
+            testpassed = True
+        assert_(testpassed)
+        assert_(self.b.flat[4] == 12.0)
+
+    def test___array__(self):
+        c = self.a.flat.__array__()
+        d = self.b.flat.__array__()
+        e = self.a0.flat.__array__()
+        f = self.b0.flat.__array__()
+
+        assert_(c.flags.writeable is False)
+        assert_(d.flags.writeable is False)
+        assert_(e.flags.writeable is True)
+        assert_(f.flags.writeable is True)
+
+        assert_(c.flags.updateifcopy is False)
+        assert_(d.flags.updateifcopy is False)
+        assert_(e.flags.updateifcopy is False)
+        assert_(f.flags.updateifcopy is True)
+        assert_(f.base is self.b0)
+
+
+class TestResize(TestCase):
+    def test_basic(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        x.resize((5, 5))
+        assert_array_equal(x.flat[:9],
+                np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat)
+        assert_array_equal(x[9:].flat, 0)
+
+    def test_check_reference(self):
+        x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        y = x
+        self.assertRaises(ValueError, x.resize, (5, 1))
+        del y  # avoid pyflakes unused variable warning.
+
+    def test_int_shape(self):
+        x = np.eye(3)
+        x.resize(3)
+        assert_array_equal(x, np.eye(3)[0,:])
+
+    def test_none_shape(self):
+        x = np.eye(3)
+        x.resize(None)
+        assert_array_equal(x, np.eye(3))
+        x.resize()
+        assert_array_equal(x, np.eye(3))
+
+    def test_invalid_arguements(self):
+        self.assertRaises(TypeError, np.eye(3).resize, 'hi')
+        self.assertRaises(ValueError, np.eye(3).resize, -1)
+        self.assertRaises(TypeError, np.eye(3).resize, order=1)
+        self.assertRaises(TypeError, np.eye(3).resize, refcheck='hi')
+
+    def test_freeform_shape(self):
+        x = np.eye(3)
+        x.resize(3, 2, 1)
+        assert_(x.shape == (3, 2, 1))
+
+    def test_zeros_appended(self):
+        x = np.eye(3)
+        x.resize(2, 3, 3)
+        assert_array_equal(x[0], np.eye(3))
+        assert_array_equal(x[1], np.zeros((3, 3)))
+
+    def test_obj_obj(self):
+        # check memory is initialized on resize, gh-4857
+        a = np.ones(10, dtype=[('k', object, 2)])
+        a.resize(15,)
+        assert_equal(a.shape, (15,))
+        assert_array_equal(a['k'][-5:], 0)
+        assert_array_equal(a['k'][:-5], 1)
+
+
+class TestRecord(TestCase):
+    def test_field_rename(self):
+        dt = np.dtype([('f', float), ('i', int)])
+        dt.names = ['p', 'q']
+        assert_equal(dt.names, ['p', 'q'])
+
+    def test_multiple_field_name_occurrence(self):
+        def test_assign():
+            dtype = np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")])
+
+        # Error raised when multiple fields have the same name
+        assert_raises(ValueError, test_assign)
+
+    if sys.version_info[0] >= 3:
+        def test_bytes_fields(self):
+            # Bytes are not allowed in field names and not recognized in titles
+            # on Py3
+            assert_raises(TypeError, np.dtype, [(asbytes('a'), int)])
+            assert_raises(TypeError, np.dtype, [(('b', asbytes('a')), int)])
+
+            dt = np.dtype([((asbytes('a'), 'b'), int)])
+            assert_raises(ValueError, dt.__getitem__, asbytes('a'))
+
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            assert_raises(IndexError, x.__getitem__, asbytes('a'))
+
+            y = x[0]
+            assert_raises(IndexError, y.__getitem__, asbytes('a'))
+
+        def test_multiple_field_name_unicode(self):
+            def test_assign_unicode():
+                dt = np.dtype([("\u20B9", "f8"),
+                               ("B", "f8"),
+                               ("\u20B9", "f8")])
+
+            # Error raised when multiple fields have the same name(unicode included)
+            assert_raises(ValueError, test_assign_unicode)
+
+    else:
+        def test_unicode_field_titles(self):
+            # Unicode field titles are added to field dict on Py2
+            title = unicode('b')
+            dt = np.dtype([((title, 'a'), int)])
+            dt[title]
+            dt['a']
+            x = np.array([(1,), (2,), (3,)], dtype=dt)
+            x[title]
+            x['a']
+            y = x[0]
+            y[title]
+            y['a']
+
+        def test_unicode_field_names(self):
+            # Unicode field names are not allowed on Py2
+            title = unicode('b')
+            assert_raises(TypeError, np.dtype, [(title, int)])
+            assert_raises(TypeError, np.dtype, [(('a', title), int)])
+
+    def test_field_names(self):
+        # Test unicode and 8-bit / byte strings can be used
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        is_py3 = sys.version_info[0] >= 3
+        if is_py3:
+            funcs = (str,)
+            # byte string indexing fails gracefully
+            assert_raises(IndexError, a.__setitem__, asbytes('f1'), 1)
+            assert_raises(IndexError, a.__getitem__, asbytes('f1'))
+            assert_raises(IndexError, a['f1'].__setitem__, asbytes('sf1'), 1)
+            assert_raises(IndexError, a['f1'].__getitem__, asbytes('sf1'))
+        else:
+            funcs = (str, unicode)
+        for func in funcs:
+            b = a.copy()
+            fn1 = func('f1')
+            b[fn1] = 1
+            assert_equal(b[fn1], 1)
+            fnn = func('not at all')
+            assert_raises(ValueError, b.__setitem__, fnn, 1)
+            assert_raises(ValueError, b.__getitem__, fnn)
+            b[0][fn1] = 2
+            assert_equal(b[fn1], 2)
+            # Subfield
+            assert_raises(ValueError, b[0].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[0].__getitem__, fnn)
+            # Subfield
+            fn3 = func('f3')
+            sfn1 = func('sf1')
+            b[fn3][sfn1] = 1
+            assert_equal(b[fn3][sfn1], 1)
+            assert_raises(ValueError, b[fn3].__setitem__, fnn, 1)
+            assert_raises(ValueError, b[fn3].__getitem__, fnn)
+            # multiple subfields
+            fn2 = func('f2')
+            b[fn2] = 3
+            assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2))
+            assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,)))
+            # view of subfield view/copy
+            assert_equal(b[['f1', 'f2']][0].view(('i4', 2)).tolist(), (2, 3))
+            assert_equal(b[['f2', 'f1']][0].view(('i4', 2)).tolist(), (3, 2))
+            view_dtype = [('f1', 'i4'), ('f3', [('', 'i4')])]
+            assert_equal(b[['f1', 'f3']][0].view(view_dtype).tolist(), (2, (1,)))
+        # non-ascii unicode field indexing is well behaved
+        if not is_py3:
+            raise SkipTest('non ascii unicode field indexing skipped; '
+                           'raises segfault on python 2.x')
+        else:
+            assert_raises(ValueError, a.__setitem__, sixu('\u03e0'), 1)
+            assert_raises(ValueError, a.__getitem__, sixu('\u03e0'))
+
+    def test_field_names_deprecation(self):
+
+        def collect_warnings(f, *args, **kwargs):
+            with warnings.catch_warnings(record=True) as log:
+                warnings.simplefilter("always")
+                f(*args, **kwargs)
+            return [w.category for w in log]
+
+        a = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        a['f1'][0] = 1
+        a['f2'][0] = 2
+        a['f3'][0] = (3,)
+        b = np.zeros((1,), dtype=[('f1', 'i4'),
+                                  ('f2', 'i4'),
+                                  ('f3', [('sf1', 'i4')])])
+        b['f1'][0] = 1
+        b['f2'][0] = 2
+        b['f3'][0] = (3,)
+
+        # All the different functions raise a warning, but not an error, and
+        # 'a' is not modified:
+        assert_equal(collect_warnings(a[['f1', 'f2']].__setitem__, 0, (10, 20)),
+                     [FutureWarning])
+        assert_equal(a, b)
+        # Views also warn
+        subset = a[['f1', 'f2']]
+        subset_view = subset.view()
+        assert_equal(collect_warnings(subset_view['f1'].__setitem__, 0, 10),
+                     [FutureWarning])
+        # But the write goes through:
+        assert_equal(subset['f1'][0], 10)
+        # Only one warning per multiple field indexing, though (even if there
+        # are multiple views involved):
+        assert_equal(collect_warnings(subset['f1'].__setitem__, 0, 10), [])
+
+    def test_record_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        a.flags.writeable = False
+        b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')])
+        b.flags.writeable = False
+        c = np.array([(1, 2), (3, 4)], dtype='i1,i2')
+        c.flags.writeable = False
+        self.assertTrue(hash(a[0]) == hash(a[1]))
+        self.assertTrue(hash(a[0]) == hash(b[0]))
+        self.assertTrue(hash(a[0]) != hash(b[1]))
+        self.assertTrue(hash(c[0]) == hash(a[0]) and c[0] == a[0])
+
+    def test_record_no_hash(self):
+        a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
+        self.assertRaises(TypeError, hash, a[0])
+
+    def test_empty_structure_creation(self):
+        # make sure these do not raise errors (gh-5631)
+        np.array([()], dtype={'names': [], 'formats': [],
+                           'offsets': [], 'itemsize': 12})
+        np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [],
+                                           'offsets': [], 'itemsize': 12})
+
+class TestView(TestCase):
+    def test_basic(self):
+        x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)],
+                     dtype=[('r', np.int8), ('g', np.int8),
+                            ('b', np.int8), ('a', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i4')
+        # ... and again without the keyword.
+        z = x.view('<i4')
+        assert_array_equal(y, z)
+        assert_array_equal(y, [67305985, 134678021])
+
+
+def _mean(a, **args):
+    return a.mean(**args)
+
+
+def _var(a, **args):
+    return a.var(**args)
+
+
+def _std(a, **args):
+    return a.std(**args)
+
+
+class TestStats(TestCase):
+
+    funcs = [_mean, _var, _std]
+
+    def setUp(self):
+        np.random.seed(range(3))
+        self.rmat = np.random.random((4, 5))
+        self.cmat = self.rmat + 1j * self.rmat
+        self.omat = np.array([Decimal(repr(r)) for r in self.rmat.flat])
+        self.omat = self.omat.reshape(4, 5)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            for axis in [0, 1]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == mat.ndim)
+                assert_(res.shape[axis] == 1)
+            for axis in [None]:
+                res = f(mat, axis=axis, keepdims=True)
+                assert_(res.shape == (1, 1))
+
+    def test_out(self):
+        mat = np.eye(3)
+        for f in self.funcs:
+            out = np.zeros(3)
+            tgt = f(mat, axis=1)
+            res = f(mat, axis=1, out=out)
+            assert_almost_equal(res, out)
+            assert_almost_equal(res, tgt)
+        out = np.empty(2)
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+        out = np.empty((2, 2))
+        assert_raises(ValueError, f, mat, axis=1, out=out)
+
+    def test_dtype_from_input(self):
+
+        icodes = np.typecodes['AllInteger']
+        fcodes = np.typecodes['AllFloat']
+
+        # object type
+        for f in self.funcs:
+            mat = np.array([[Decimal(1)]*3]*3)
+            tgt = mat.dtype.type
+            res = f(mat, axis=1).dtype.type
+            assert_(res is tgt)
+            # scalar case
+            res = type(f(mat, axis=None))
+            assert_(res is Decimal)
+
+        # integer types
+        for f in self.funcs:
+            for c in icodes:
+                mat = np.eye(3, dtype=c)
+                tgt = np.float64
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # mean for float types
+        for f in [_mean]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                tgt = mat.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+        # var, std for float types
+        for f in [_var, _std]:
+            for c in fcodes:
+                mat = np.eye(3, dtype=c)
+                # deal with complex types
+                tgt = mat.real.dtype.type
+                res = f(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+
+        # stats for integer types
+        # FIXME:
+        # this needs definition as there are lots places along the line
+        # where type casting may take place.
+
+        # for f in self.funcs:
+        #    for c in np.typecodes['AllInteger']:
+        #        tgt = np.dtype(c).type
+        #        res = f(mat, axis=1, dtype=c).dtype.type
+        #        assert_(res is tgt)
+        #        # scalar case
+        #        res = f(mat, axis=None, dtype=c).dtype.type
+        #        assert_(res is tgt)
+
+        # stats for float types
+        for f in self.funcs:
+            for c in np.typecodes['AllFloat']:
+                tgt = np.dtype(c).type
+                res = f(mat, axis=1, dtype=c).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                res = f(mat, axis=None, dtype=c).dtype.type
+                assert_(res is tgt)
+
+    def test_ddof(self):
+        for f in [_var]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * dim
+                res = f(self.rmat, axis=1, ddof=ddof) * (dim - ddof)
+        for f in [_std]:
+            for ddof in range(3):
+                dim = self.rmat.shape[1]
+                tgt = f(self.rmat, axis=1) * np.sqrt(dim)
+                res = f(self.rmat, axis=1, ddof=ddof) * np.sqrt(dim - ddof)
+                assert_almost_equal(res, tgt)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        dim = self.rmat.shape[1]
+        for f in [_var, _std]:
+            for ddof in range(dim, dim + 2):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    res = f(self.rmat, axis=1, ddof=ddof)
+                    assert_(not (res < 0).any())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        A = np.zeros((0, 3))
+        for f in self.funcs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(A, axis=axis)).all())
+                    assert_(len(w) > 0)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(A, axis=axis), np.zeros([]))
+
+    def test_mean_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * mat.shape[axis]
+                assert_almost_equal(res, tgt)
+            for axis in [None]:
+                tgt = mat.sum(axis=axis)
+                res = _mean(mat, axis=axis) * np.prod(mat.shape)
+                assert_almost_equal(res, tgt)
+
+    def test_var_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                msqr = _mean(mat * mat.conj(), axis=axis)
+                mean = _mean(mat, axis=axis)
+                tgt = msqr - mean * mean.conjugate()
+                res = _var(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_std_values(self):
+        for mat in [self.rmat, self.cmat, self.omat]:
+            for axis in [0, 1, None]:
+                tgt = np.sqrt(_var(mat, axis=axis))
+                res = _std(mat, axis=axis)
+                assert_almost_equal(res, tgt)
+
+    def test_subclass(self):
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, "info", '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        res = dat.mean(1)
+        assert_(res.info == dat.info)
+        res = dat.std(1)
+        assert_(res.info == dat.info)
+        res = dat.var(1)
+        assert_(res.info == dat.info)
+
+class TestVdot(TestCase):
+    def test_basic(self):
+        dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
+        dt_complex = np.typecodes['Complex']
+
+        # test real
+        a = np.eye(3)
+        for dt in dt_numeric + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test complex
+        a = np.eye(3) * 1j
+        for dt in dt_complex + 'O':
+            b = a.astype(dt)
+            res = np.vdot(b, b)
+            assert_(np.isscalar(res))
+            assert_equal(np.vdot(b, b), 3)
+
+        # test boolean
+        b = np.eye(3, dtype=np.bool)
+        res = np.vdot(b, b)
+        assert_(np.isscalar(res))
+        assert_equal(np.vdot(b, b), True)
+
+    def test_vdot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.vdot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.vdot(a, b), res)
+        assert_equal(np.vdot(b, a), res)
+        assert_equal(np.vdot(b, b), res)
+
+    def test_vdot_uncontiguous(self):
+        for size in [2, 1000]:
+            # Different sizes match different branches in vdot.
+            a = np.zeros((size, 2, 2))
+            b = np.zeros((size, 2, 2))
+            a[:, 0, 0] = np.arange(size)
+            b[:, 0, 0] = np.arange(size) + 1
+            # Make a and b uncontiguous:
+            a = a[..., 0]
+            b = b[..., 0]
+
+            assert_equal(np.vdot(a, b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy()),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy(), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a.copy('F'), b),
+                         np.vdot(a.flatten(), b.flatten()))
+            assert_equal(np.vdot(a, b.copy('F')),
+                         np.vdot(a.flatten(), b.flatten()))
+
+
+class TestDot(TestCase):
+    def setUp(self):
+        np.random.seed(128)
+        self.A = np.random.rand(4, 2)
+        self.b1 = np.random.rand(2, 1)
+        self.b2 = np.random.rand(2)
+        self.b3 = np.random.rand(1, 2)
+        self.b4 = np.random.rand(4)
+        self.N = 7
+
+    def test_dotmatmat(self):
+        A = self.A
+        res = np.dot(A.transpose(), A)
+        tgt = np.array([[1.45046013, 0.86323640],
+                        [0.86323640, 0.84934569]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec(self):
+        A, b1 = self.A, self.b1
+        res = np.dot(A, b1)
+        tgt = np.array([[0.32114320], [0.04889721],
+                        [0.15696029], [0.33612621]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotmatvec2(self):
+        A, b2 = self.A, self.b2
+        res = np.dot(A, b2)
+        tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(b4, A)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat2(self):
+        b3, A = self.b3, self.A
+        res = np.dot(b3, A.transpose())
+        tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecmat3(self):
+        A, b4 = self.A, self.b4
+        res = np.dot(A.transpose(), b4)
+        tgt = np.array([1.23495091, 1.12222648])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecouter(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b1, b3)
+        tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecvecinner(self):
+        b1, b3 = self.b1, self.b3
+        res = np.dot(b3, b1)
+        tgt = np.array([[ 0.23129668]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect1(self):
+        b1 = np.ones((3, 1))
+        b2 = [5.3]
+        res = np.dot(b1, b2)
+        tgt = np.array([5.3, 5.3, 5.3])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotcolumnvect2(self):
+        b1 = np.ones((3, 1)).transpose()
+        b2 = [6.2]
+        res = np.dot(b2, b1)
+        tgt = np.array([6.2, 6.2, 6.2])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar(self):
+        np.random.seed(100)
+        b1 = np.random.rand(1, 1)
+        b2 = np.random.rand(1, 4)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_dotvecscalar2(self):
+        np.random.seed(100)
+        b1 = np.random.rand(4, 1)
+        b2 = np.random.rand(1, 1)
+        res = np.dot(b1, b2)
+        tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]])
+        assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_all(self):
+        dims = [(), (1,), (1, 1)]
+        dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)]
+        for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)):
+            b1 = np.zeros(dim1)
+            b2 = np.zeros(dim2)
+            res = np.dot(b1, b2)
+            tgt = np.zeros(dim)
+            assert_(res.shape == tgt.shape)
+            assert_almost_equal(res, tgt, decimal=self.N)
+
+    def test_vecobject(self):
+        class Vec(object):
+            def __init__(self, sequence=None):
+                if sequence is None:
+                    sequence = []
+                self.array = np.array(sequence)
+
+            def __add__(self, other):
+                out = Vec()
+                out.array = self.array + other.array
+                return out
+
+            def __sub__(self, other):
+                out = Vec()
+                out.array = self.array - other.array
+                return out
+
+            def __mul__(self, other):  # with scalar
+                out = Vec(self.array.copy())
+                out.array *= other
+                return out
+
+            def __rmul__(self, other):
+                return self*other
+
+        U_non_cont = np.transpose([[1., 1.], [1., 2.]])
+        U_cont = np.ascontiguousarray(U_non_cont)
+        x = np.array([Vec([1., 0.]), Vec([0., 1.])])
+        zeros = np.array([Vec([0., 0.]), Vec([0., 0.])])
+        zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x)
+        assert_equal(zeros[0].array, zeros_test[0].array)
+        assert_equal(zeros[1].array, zeros_test[1].array)
+
+    def test_dot_2args(self):
+        from numpy.core.multiarray import dot
+
+        a = np.array([[1, 2], [3, 4]], dtype=float)
+        b = np.array([[1, 0], [1, 1]], dtype=float)
+        c = np.array([[3, 2], [7, 4]], dtype=float)
+
+        d = dot(a, b)
+        assert_allclose(c, d)
+
+    def test_dot_3args(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 32))
+        for i in range(12):
+            dot(f, v, r)
+        assert_equal(sys.getrefcount(r), 2)
+        r2 = dot(f, v, out=None)
+        assert_array_equal(r2, r)
+        assert_(r is dot(f, v, out=r))
+
+        v = v[:, 0].copy()  # v.shape == (16,)
+        r = r[:, 0].copy()  # r.shape == (1024,)
+        r2 = dot(f, v)
+        assert_(r is dot(f, v, r))
+        assert_array_equal(r2, r)
+
+    def test_dot_3args_errors(self):
+        from numpy.core.multiarray import dot
+
+        np.random.seed(22)
+        f = np.random.random_sample((1024, 16))
+        v = np.random.random_sample((16, 32))
+
+        r = np.empty((1024, 31))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32,))
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((32, 1024))
+        assert_raises(ValueError, dot, f, v, r)
+        assert_raises(ValueError, dot, f, v, r.T)
+
+        r = np.empty((1024, 64))
+        assert_raises(ValueError, dot, f, v, r[:, ::2])
+        assert_raises(ValueError, dot, f, v, r[:, :32])
+
+        r = np.empty((1024, 32), dtype=np.float32)
+        assert_raises(ValueError, dot, f, v, r)
+
+        r = np.empty((1024, 32), dtype=int)
+        assert_raises(ValueError, dot, f, v, r)
+
+    def test_dot_array_order(self):
+        a = np.array([[1, 2], [3, 4]], order='C')
+        b = np.array([[1, 2], [3, 4]], order='F')
+        res = np.dot(a, a)
+
+        # integer arrays are exact
+        assert_equal(np.dot(a, b), res)
+        assert_equal(np.dot(b, a), res)
+        assert_equal(np.dot(b, b), res)
+
+    def test_dot_scalar_and_matrix_of_objects(self):
+        # Ticket #2469
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.dot(arr, 3), desired)
+        assert_equal(np.dot(3, arr), desired)
+
+    def test_accelerate_framework_sgemv_fix(self):
+
+        def aligned_array(shape, align, dtype, order='C'):
+            d = dtype(0)
+            N = np.prod(shape)
+            tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
+            address = tmp.__array_interface__["data"][0]
+            for offset in range(align):
+                if (address + offset) % align == 0:
+                    break
+            tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
+            return tmp.reshape(shape, order=order)
+
+        def as_aligned(arr, align, dtype, order='C'):
+            aligned = aligned_array(arr.shape, align, dtype, order)
+            aligned[:] = arr[:]
+            return aligned
+
+        def assert_dot_close(A, X, desired):
+            assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
+
+        m = aligned_array(100, 15, np.float32)
+        s = aligned_array((100, 100), 15, np.float32)
+        np.dot(s, m)  # this will always segfault if the bug is present
+
+        testdata = itertools.product((15,32), (10000,), (200,89), ('C','F'))
+        for align, m, n, a_order in testdata:
+            # Calculation in double precision
+            A_d = np.random.rand(m, n)
+            X_d = np.random.rand(n)
+            desired = np.dot(A_d, X_d)
+            # Calculation with aligned single precision
+            A_f = as_aligned(A_d, align, np.float32, order=a_order)
+            X_f = as_aligned(X_d, align, np.float32)
+            assert_dot_close(A_f, X_f, desired)
+            # Strided A rows
+            A_d_2 = A_d[::2]
+            desired = np.dot(A_d_2, X_d)
+            A_f_2 = A_f[::2]
+            assert_dot_close(A_f_2, X_f, desired)
+            # Strided A columns, strided X vector
+            A_d_22 = A_d_2[:, ::2]
+            X_d_2 = X_d[::2]
+            desired = np.dot(A_d_22, X_d_2)
+            A_f_22 = A_f_2[:, ::2]
+            X_f_2 = X_f[::2]
+            assert_dot_close(A_f_22, X_f_2, desired)
+            # Check the strides are as expected
+            if a_order == 'F':
+                assert_equal(A_f_22.strides, (8, 8 * m))
+            else:
+                assert_equal(A_f_22.strides, (8 * n, 8))
+            assert_equal(X_f_2.strides, (8,))
+            # Strides in A rows + cols only
+            X_f_2c = as_aligned(X_f_2, align, np.float32)
+            assert_dot_close(A_f_22, X_f_2c, desired)
+            # Strides just in A cols
+            A_d_12 = A_d[:, ::2]
+            desired = np.dot(A_d_12, X_d_2)
+            A_f_12 = A_f[:, ::2]
+            assert_dot_close(A_f_12, X_f_2c, desired)
+            # Strides in A cols and X
+            assert_dot_close(A_f_12, X_f_2, desired)
+
+
+class MatmulCommon():
+    """Common tests for '@' operator and numpy.matmul.
+
+    Do not derive from TestCase to avoid nose running it.
+
+    """
+    # Should work with these types. Will want to add
+    # "O" at some point
+    types = "?bhilqBHILQefdgFDG"
+
+    def test_exceptions(self):
+        dims = [
+            ((1,), (2,)),            # mismatched vector vector
+            ((2, 1,), (2,)),         # mismatched matrix vector
+            ((2,), (1, 2)),          # mismatched vector matrix
+            ((1, 2), (3, 1)),        # mismatched matrix matrix
+            ((1,), ()),              # vector scalar
+            ((), (1)),               # scalar vector
+            ((1, 1), ()),            # matrix scalar
+            ((), (1, 1)),            # scalar matrix
+            ((2, 2, 1), (3, 1, 2)),  # cannot broadcast
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            assert_raises(ValueError, self.matmul, a, b)
+
+    def test_shapes(self):
+        dims = [
+            ((1, 1), (2, 1, 1)),     # broadcast first argument
+            ((2, 1, 1), (1, 1)),     # broadcast second argument
+            ((2, 1, 1), (2, 1, 1)),  # matrix stack sizes match
+            ]
+
+        for dt, (dm1, dm2) in itertools.product(self.types, dims):
+            a = np.ones(dm1, dtype=dt)
+            b = np.ones(dm2, dtype=dt)
+            res = self.matmul(a, b)
+            assert_(res.shape == (2, 1, 1))
+
+        # vector vector returns scalars.
+        for dt in self.types:
+            a = np.ones((2,), dtype=dt)
+            b = np.ones((2,), dtype=dt)
+            c = self.matmul(a, b)
+            assert_(np.array(c).shape == ())
+
+    def test_result_types(self):
+        mat = np.ones((1,1))
+        vec = np.ones((1,))
+        for dt in self.types:
+            m = mat.astype(dt)
+            v = vec.astype(dt)
+            for arg in [(m, v), (v, m), (m, m)]:
+                res = self.matmul(*arg)
+                assert_(res.dtype == dt)
+
+            # vector vector returns scalars
+            res = self.matmul(v, v)
+            assert_(type(res) is np.dtype(dt).type)
+
+    def test_vector_vector_values(self):
+        vec = np.array([1, 2])
+        tgt = 5
+        for dt in self.types[1:]:
+            v1 = vec.astype(dt)
+            res = self.matmul(v1, v1)
+            assert_equal(res, tgt)
+
+        # boolean type
+        vec = np.array([True, True], dtype='?')
+        res = self.matmul(vec, vec)
+        assert_equal(res, True)
+
+    def test_vector_matrix_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([7, 10])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(v, m1)
+            assert_equal(res, tgt1)
+            res = self.matmul(v, m2)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_vector_values(self):
+        vec = np.array([1, 2])
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([5, 11])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+        for dt in self.types[1:]:
+            v = vec.astype(dt)
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            res = self.matmul(m1, v)
+            assert_equal(res, tgt1)
+            res = self.matmul(m2, v)
+            assert_equal(res, tgt2)
+
+        # boolean type
+        vec = np.array([True, False])
+        mat1 = np.array([[True, False], [False, True]])
+        mat2 = np.stack([mat1]*2, axis=0)
+        tgt1 = np.array([True, False])
+        tgt2 = np.stack([tgt1]*2, axis=0)
+
+        res = self.matmul(vec, mat1)
+        assert_equal(res, tgt1)
+        res = self.matmul(vec, mat2)
+        assert_equal(res, tgt2)
+
+    def test_matrix_matrix_values(self):
+        mat1 = np.array([[1, 2], [3, 4]])
+        mat2 = np.array([[1, 0], [1, 1]])
+        mat12 = np.stack([mat1, mat2], axis=0)
+        mat21 = np.stack([mat2, mat1], axis=0)
+        tgt11 = np.array([[7, 10], [15, 22]])
+        tgt12 = np.array([[3, 2], [7, 4]])
+        tgt21 = np.array([[1, 2], [4, 6]])
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+        for dt in self.types[1:]:
+            m1 = mat1.astype(dt)
+            m2 = mat2.astype(dt)
+            m12 = mat12.astype(dt)
+            m21 = mat21.astype(dt)
+
+            # matrix @ matrix
+            res = self.matmul(m1, m2)
+            assert_equal(res, tgt12)
+            res = self.matmul(m2, m1)
+            assert_equal(res, tgt21)
+
+            # stacked @ matrix
+            res = self.matmul(m12, m1)
+            assert_equal(res, tgt11_21)
+
+            # matrix @ stacked
+            res = self.matmul(m1, m12)
+            assert_equal(res, tgt11_12)
+
+            # stacked @ stacked
+            res = self.matmul(m12, m21)
+            assert_equal(res, tgt12_21)
+
+        # boolean type
+        m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_)
+        m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_)
+        m12 = np.stack([m1, m2], axis=0)
+        m21 = np.stack([m2, m1], axis=0)
+        tgt11 = m1
+        tgt12 = m1
+        tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_)
+        tgt12_21 = np.stack([tgt12, tgt21], axis=0)
+        tgt11_12 = np.stack((tgt11, tgt12), axis=0)
+        tgt11_21 = np.stack((tgt11, tgt21), axis=0)
+
+        # matrix @ matrix
+        res = self.matmul(m1, m2)
+        assert_equal(res, tgt12)
+        res = self.matmul(m2, m1)
+        assert_equal(res, tgt21)
+
+        # stacked @ matrix
+        res = self.matmul(m12, m1)
+        assert_equal(res, tgt11_21)
+
+        # matrix @ stacked
+        res = self.matmul(m1, m12)
+        assert_equal(res, tgt11_12)
+
+        # stacked @ stacked
+        res = self.matmul(m12, m21)
+        assert_equal(res, tgt12_21)
+
+    def test_numpy_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return "A"
+
+        class B(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A([1, 2])
+        b = B([1, 2])
+        c = np.ones(2)
+        assert_equal(self.matmul(a, b), "A")
+        assert_equal(self.matmul(b, a), "A")
+        assert_raises(TypeError, self.matmul, b, c)
+
+
+class TestMatmul(MatmulCommon, TestCase):
+    matmul = np.matmul
+
+    def test_out_arg(self):
+        a = np.ones((2, 2), dtype=np.float)
+        b = np.ones((2, 2), dtype=np.float)
+        tgt = np.full((2,2), 2, dtype=np.float)
+
+        # test as positional argument
+        msg = "out positional argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test as keyword argument
+        msg = "out keyword argument"
+        out = np.zeros((2, 2), dtype=np.float)
+        self.matmul(a, b, out=out)
+        assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out with not allowed type cast (safe casting)
+        # einsum and cblas raise different error types, so
+        # use Exception.
+        msg = "out argument with illegal cast"
+        out = np.zeros((2, 2), dtype=np.int32)
+        assert_raises(Exception, self.matmul, a, b, out=out)
+
+        # skip following tests for now, cblas does not allow non-contiguous
+        # outputs and consistency with dot would require same type,
+        # dimensions, subtype, and c_contiguous.
+
+        # test out with allowed type cast
+        # msg = "out argument with allowed cast"
+        # out = np.zeros((2, 2), dtype=np.complex128)
+        # self.matmul(a, b, out=out)
+        # assert_array_equal(out, tgt, err_msg=msg)
+
+        # test out non-contiguous
+        # msg = "out argument with non-contiguous layout"
+        # c = np.zeros((2, 2, 2), dtype=np.float)
+        # self.matmul(a, b, out=c[..., 0])
+        # assert_array_equal(c, tgt, err_msg=msg)
+
+
+if sys.version_info[:2] >= (3, 5):
+    class TestMatmulOperator(MatmulCommon, TestCase):
+        import operator
+        matmul = operator.matmul
+
+        def test_array_priority_override(self):
+
+            class A(object):
+                __array_priority__ = 1000
+
+                def __matmul__(self, other):
+                    return "A"
+
+                def __rmatmul__(self, other):
+                    return "A"
+
+            a = A()
+            b = np.ones(2)
+            assert_equal(self.matmul(a, b), "A")
+            assert_equal(self.matmul(b, a), "A")
+
+    def test_matmul_inplace():
+        # It would be nice to support in-place matmul eventually, but for now
+        # we don't have a working implementation, so better just to error out
+        # and nudge people to writing "a = a @ b".
+        a = np.eye(3)
+        b = np.eye(3)
+        assert_raises(TypeError, a.__imatmul__, b)
+        import operator
+        assert_raises(TypeError, operator.imatmul, a, b)
+        # we avoid writing the token `exec` so as not to crash python 2's
+        # parser
+        exec_ = getattr(builtins, "exec")
+        assert_raises(TypeError, exec_, "a @= b", globals(), locals())
+
+
+class TestInner(TestCase):
+
+    def test_inner_type_mismatch(self):
+        c = 1.
+        A = np.array((1,1), dtype='i,i')
+
+        assert_raises(TypeError, np.inner, c, A)
+        assert_raises(TypeError, np.inner, A, c)
+
+    def test_inner_scalar_and_vector(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            vec = np.array([1, 2], dtype=dt)
+            desired = np.array([3, 6], dtype=dt)
+            assert_equal(np.inner(vec, sca), desired)
+            assert_equal(np.inner(sca, vec), desired)
+
+    def test_inner_scalar_and_matrix(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            sca = np.array(3, dtype=dt)[()]
+            arr = np.matrix([[1, 2], [3, 4]], dtype=dt)
+            desired = np.matrix([[3, 6], [9, 12]], dtype=dt)
+            assert_equal(np.inner(arr, sca), desired)
+            assert_equal(np.inner(sca, arr), desired)
+
+    def test_inner_scalar_and_matrix_of_objects(self):
+        # Ticket #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.inner(arr, 3), desired)
+        assert_equal(np.inner(3, arr), desired)
+
+    def test_vecself(self):
+        # Ticket 844.
+        # Inner product of a vector with itself segfaults or give
+        # meaningless result
+        a = np.zeros(shape=(1, 80), dtype=np.float64)
+        p = np.inner(a, a)
+        assert_almost_equal(p, 0, decimal=14)
+
+    def test_inner_product_with_various_contiguities(self):
+        # github issue 6532
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            # check an inner product involving a matrix transpose
+            A = np.array([[1, 2], [3, 4]], dtype=dt)
+            B = np.array([[1, 3], [2, 4]], dtype=dt)
+            C = np.array([1, 1], dtype=dt)
+            desired = np.array([4, 6], dtype=dt)
+            assert_equal(np.inner(A.T, C), desired)
+            assert_equal(np.inner(C, A.T), desired)
+            assert_equal(np.inner(B, C), desired)
+            assert_equal(np.inner(C, B), desired)
+            # check a matrix product
+            desired = np.array([[7, 10], [15, 22]], dtype=dt)
+            assert_equal(np.inner(A, B), desired)
+            # check the syrk vs. gemm paths
+            desired = np.array([[5, 11], [11, 25]], dtype=dt)
+            assert_equal(np.inner(A, A), desired)
+            assert_equal(np.inner(A, A.copy()), desired)
+            # check an inner product involving an aliased and reversed view
+            a = np.arange(5).astype(dt)
+            b = a[::-1]
+            desired = np.array(10, dtype=dt).item()
+            assert_equal(np.inner(b, a), desired)
+
+    def test_3d_tensor(self):
+        for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
+            a = np.arange(24).reshape(2,3,4).astype(dt)
+            b = np.arange(24, 48).reshape(2,3,4).astype(dt)
+            desired = np.array(
+                [[[[ 158,  182,  206],
+                   [ 230,  254,  278]],
+
+                  [[ 566,  654,  742],
+                   [ 830,  918, 1006]],
+
+                  [[ 974, 1126, 1278],
+                   [1430, 1582, 1734]]],
+
+                 [[[1382, 1598, 1814],
+                   [2030, 2246, 2462]],
+
+                  [[1790, 2070, 2350],
+                   [2630, 2910, 3190]],
+
+                  [[2198, 2542, 2886],
+                   [3230, 3574, 3918]]]],
+                dtype=dt
+            )
+            assert_equal(np.inner(a, b), desired)
+            assert_equal(np.inner(b, a).transpose(2,3,0,1), desired)
+
+
+class TestSummarization(TestCase):
+    def test_1d(self):
+        A = np.arange(1001)
+        strA = '[   0    1    2 ...,  998  999 1000]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([   0,    1,    2, ...,  998,  999, 1000])'
+        assert_(repr(A) == reprA)
+
+    def test_2d(self):
+        A = np.arange(1002).reshape(2, 501)
+        strA = '[[   0    1    2 ...,  498  499  500]\n' \
+               ' [ 501  502  503 ...,  999 1000 1001]]'
+        assert_(str(A) == strA)
+
+        reprA = 'array([[   0,    1,    2, ...,  498,  499,  500],\n' \
+                '       [ 501,  502,  503, ...,  999, 1000, 1001]])'
+        assert_(repr(A) == reprA)
+
+
+class TestAlen(TestCase):
+    def test_basic(self):
+        m = np.array([1, 2, 3])
+        self.assertEqual(np.alen(m), 3)
+
+        m = np.array([[1, 2, 3], [4, 5, 7]])
+        self.assertEqual(np.alen(m), 2)
+
+        m = [1, 2, 3]
+        self.assertEqual(np.alen(m), 3)
+
+        m = [[1, 2, 3], [4, 5, 7]]
+        self.assertEqual(np.alen(m), 2)
+
+    def test_singleton(self):
+        self.assertEqual(np.alen(5), 1)
+
+
+class TestChoose(TestCase):
+    def setUp(self):
+        self.x = 2*np.ones((3,), dtype=int)
+        self.y = 3*np.ones((3,), dtype=int)
+        self.x2 = 2*np.ones((2, 3), dtype=int)
+        self.y2 = 3*np.ones((2, 3), dtype=int)
+        self.ind = [0, 0, 1]
+
+    def test_basic(self):
+        A = np.choose(self.ind, (self.x, self.y))
+        assert_equal(A, [2, 2, 3])
+
+    def test_broadcast1(self):
+        A = np.choose(self.ind, (self.x2, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+    def test_broadcast2(self):
+        A = np.choose(self.ind, (self.x, self.y2))
+        assert_equal(A, [[2, 2, 3], [2, 2, 3]])
+
+
+class TestRepeat(TestCase):
+    def setUp(self):
+        self.m = np.array([1, 2, 3, 4, 5, 6])
+        self.m_rect = self.m.reshape((2, 3))
+
+    def test_basic(self):
+        A = np.repeat(self.m, [1, 3, 2, 1, 1, 2])
+        assert_equal(A, [1, 2, 2, 2, 3,
+                         3, 4, 5, 6, 6])
+
+    def test_broadcast1(self):
+        A = np.repeat(self.m, 2)
+        assert_equal(A, [1, 1, 2, 2, 3, 3,
+                         4, 4, 5, 5, 6, 6])
+
+    def test_axis_spec(self):
+        A = np.repeat(self.m_rect, [2, 1], axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, [1, 3, 2], axis=1)
+        assert_equal(A, [[1, 2, 2, 2, 3, 3],
+                         [4, 5, 5, 5, 6, 6]])
+
+    def test_broadcast2(self):
+        A = np.repeat(self.m_rect, 2, axis=0)
+        assert_equal(A, [[1, 2, 3],
+                         [1, 2, 3],
+                         [4, 5, 6],
+                         [4, 5, 6]])
+
+        A = np.repeat(self.m_rect, 2, axis=1)
+        assert_equal(A, [[1, 1, 2, 2, 3, 3],
+                         [4, 4, 5, 5, 6, 6]])
+
+
+# TODO: test for multidimensional
+NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4}
+
+
+class TestNeighborhoodIter(TestCase):
+    # Simple, 2d tests
+    def _test_simple2d(self, dt):
+        # Test zero and one padding for simple data type
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt),
+             np.array([[0, 0, 0], [0, 1, 0]], dtype=dt),
+             np.array([[0, 0, 1], [0, 2, 3]], dtype=dt),
+             np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt),
+             np.array([[1, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[1, 0, 1], [1, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt),
+             np.array([[4, 4, 4], [0, 1, 4]], dtype=dt),
+             np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
+             np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], 4,
+                NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple2d(self):
+        self._test_simple2d(np.float)
+
+    def test_simple2d_object(self):
+        self._test_simple2d(Decimal)
+
+    def _test_mirror2d(self, dt):
+        x = np.array([[0, 1], [2, 3]], dtype=dt)
+        r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
+             np.array([[0, 1, 1], [0, 1, 1]], dtype=dt),
+             np.array([[0, 0, 1], [2, 2, 3]], dtype=dt),
+             np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)]
+        l = test_neighborhood_iterator(x, [-1, 0, -1, 1], x[0],
+                NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    def test_mirror2d(self):
+        self._test_mirror2d(np.float)
+
+    def test_mirror2d_object(self):
+        self._test_mirror2d(Decimal)
+
+    # Simple, 1d tests
+    def _test_simple(self, dt):
+        # Test padding with constant values
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[0], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+        r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]]
+        l = test_neighborhood_iterator(x, [-1, 1], x[4], NEIGH_MODE['constant'])
+        assert_array_equal(l, r)
+
+    def test_simple_float(self):
+        self._test_simple(np.float)
+
+    def test_simple_object(self):
+        self._test_simple(Decimal)
+
+    # Test mirror modes
+    def _test_mirror(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[1], NEIGH_MODE['mirror'])
+        self.assertTrue([i.dtype == dt for i in l])
+        assert_array_equal(l, r)
+
+    def test_mirror(self):
+        self._test_mirror(np.float)
+
+    def test_mirror_object(self):
+        self._test_mirror(Decimal)
+
+    # Circular mode
+    def _test_circular(self, dt):
+        x = np.linspace(1, 5, 5).astype(dt)
+        r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5],
+                [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt)
+        l = test_neighborhood_iterator(x, [-2, 2], x[0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    def test_circular(self):
+        self._test_circular(np.float)
+
+    def test_circular_object(self):
+        self._test_circular(Decimal)
+
+# Test stacking neighborhood iterators
+class TestStackedNeighborhoodIter(TestCase):
+    # Simple, 1d test: stacking 2 constant-padded neigh iterators
+    def test_simple_const(self):
+        dt = np.float64
+        # Test zero and one padding for simple data type
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([1], dtype=dt),
+             np.array([2], dtype=dt),
+             np.array([3], dtype=dt),
+             np.array([0], dtype=dt),
+             np.array([0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-2, 4], NEIGH_MODE['zero'],
+                [0, 0], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        r = [np.array([1, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-1, 1], NEIGH_MODE['one'])
+        assert_array_equal(l, r)
+
+    # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # mirror padding
+    def test_simple_mirror(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 1], dtype=dt),
+             np.array([1, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 3], dtype=dt),
+             np.array([3, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['mirror'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+    # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
+    # circular padding
+    def test_simple_circular(self):
+        dt = np.float64
+        # Stacking zero on top of mirror
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 3, 1], dtype=dt),
+             np.array([3, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 1], dtype=dt),
+             np.array([3, 1, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['circular'],
+                [-1, 1], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt),
+             np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 0], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 2nd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([0, 1, 2], dtype=dt),
+             np.array([1, 2, 3], dtype=dt),
+             np.array([2, 3, 0], dtype=dt),
+             np.array([3, 0, 0], dtype=dt),
+             np.array([0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [0, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero: 3rd
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([3, 0, 0, 1, 2], dtype=dt),
+             np.array([0, 0, 1, 2, 3], dtype=dt),
+             np.array([0, 1, 2, 3, 0], dtype=dt),
+             np.array([1, 2, 3, 0, 0], dtype=dt),
+             np.array([2, 3, 0, 0, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [-1, 3], NEIGH_MODE['zero'],
+                [-2, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+    # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator
+    # being strictly within the array
+    def test_simple_strict_within(self):
+        dt = np.float64
+        # Stacking zero on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 0], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['zero'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 3], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['mirror'])
+        assert_array_equal(l, r)
+
+        # Stacking mirror on top of zero, first neighborhood strictly inside the
+        # array
+        x = np.array([1, 2, 3], dtype=dt)
+        r = [np.array([1, 2, 3, 1], dtype=dt)]
+        l = test_neighborhood_iterator_oob(x, [1, 1], NEIGH_MODE['zero'],
+                [-1, 2], NEIGH_MODE['circular'])
+        assert_array_equal(l, r)
+
+class TestWarnings(object):
+
+    def test_complex_warning(self):
+        x = np.array([1, 2])
+        y = np.array([1-2j, 1+2j])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", np.ComplexWarning)
+            assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y)
+            assert_equal(x, [1, 2])
+
+
+class TestMinScalarType(object):
+
+    def test_usigned_shortshort(self):
+        dt = np.min_scalar_type(2**8-1)
+        wanted = np.dtype('uint8')
+        assert_equal(wanted, dt)
+
+    def test_usigned_short(self):
+        dt = np.min_scalar_type(2**16-1)
+        wanted = np.dtype('uint16')
+        assert_equal(wanted, dt)
+
+    def test_usigned_int(self):
+        dt = np.min_scalar_type(2**32-1)
+        wanted = np.dtype('uint32')
+        assert_equal(wanted, dt)
+
+    def test_usigned_longlong(self):
+        dt = np.min_scalar_type(2**63-1)
+        wanted = np.dtype('uint64')
+        assert_equal(wanted, dt)
+
+    def test_object(self):
+        dt = np.min_scalar_type(2**64)
+        wanted = np.dtype('O')
+        assert_equal(wanted, dt)
+
+
+if sys.version_info[:2] == (2, 6):
+    from numpy.core.multiarray import memorysimpleview as memoryview
+
+from numpy.core._internal import _dtype_from_pep3118
+
+
+class TestPEP3118Dtype(object):
+    def _check(self, spec, wanted):
+        dt = np.dtype(wanted)
+        if isinstance(wanted, list) and isinstance(wanted[-1], tuple):
+            if wanted[-1][0] == '':
+                names = list(dt.names)
+                names[-1] = ''
+                dt.names = tuple(names)
+        assert_equal(_dtype_from_pep3118(spec), dt,
+                     err_msg="spec %r != dtype %r" % (spec, wanted))
+
+    def test_native_padding(self):
+        align = np.dtype('i').alignment
+        for j in range(8):
+            if j == 0:
+                s = 'bi'
+            else:
+                s = 'b%dxi' % j
+            self._check('@'+s, {'f0': ('i1', 0),
+                                'f1': ('i', align*(1 + j//align))})
+            self._check('='+s, {'f0': ('i1', 0),
+                                'f1': ('i', 1+j)})
+
+    def test_native_padding_2(self):
+        # Native padding should work also for structs and sub-arrays
+        self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
+        self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
+
+    def test_trailing_padding(self):
+        # Trailing padding should be included, *and*, the item size
+        # should match the alignment if in aligned mode
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('ix', [('f0', 'i'), ('', VV(1))])
+        self._check('ixx', [('f0', 'i'), ('', VV(2))])
+        self._check('ixxx', [('f0', 'i'), ('', VV(3))])
+        self._check('ixxxx', [('f0', 'i'), ('', VV(4))])
+        self._check('i7x', [('f0', 'i'), ('', VV(7))])
+
+        self._check('^ix', [('f0', 'i'), ('', 'V1')])
+        self._check('^ixx', [('f0', 'i'), ('', 'V2')])
+        self._check('^ixxx', [('f0', 'i'), ('', 'V3')])
+        self._check('^ixxxx', [('f0', 'i'), ('', 'V4')])
+        self._check('^i7x', [('f0', 'i'), ('', 'V7')])
+
+    def test_native_padding_3(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'),
+                    ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
+
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
+
+    def test_padding_with_array_inside_struct(self):
+        dt = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)),
+                    ('d', 'i')],
+                align=True)
+        self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
+
+    def test_byteorder_inside_struct(self):
+        # The byte order after @T{=i} should be '=', not '@'.
+        # Check this by noting the absence of native alignment.
+        self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0),
+                                 'f1': ('i', 5)})
+
+    def test_intra_padding(self):
+        # Natively aligned sub-arrays may require some internal padding
+        align = np.dtype('i').alignment
+
+        def VV(n):
+            return 'V%d' % (align*(1 + (n-1)//align))
+
+        self._check('(3)T{ix}', ({'f0': ('i', 0), '': (VV(1), 4)}, (3,)))
+
+
+class TestNewBufferProtocol(object):
+    def _check_roundtrip(self, obj):
+        obj = np.asarray(obj)
+        x = memoryview(obj)
+        y = np.asarray(x)
+        y2 = np.array(x)
+        assert_(not y.flags.owndata)
+        assert_(y2.flags.owndata)
+
+        assert_equal(y.dtype, obj.dtype)
+        assert_equal(y.shape, obj.shape)
+        assert_array_equal(obj, y)
+
+        assert_equal(y2.dtype, obj.dtype)
+        assert_equal(y2.shape, obj.shape)
+        assert_array_equal(obj, y2)
+
+    def test_roundtrip(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i4')
+        self._check_roundtrip(x)
+
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        self._check_roundtrip(x)
+
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        self._check_roundtrip(x)
+
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('xxx'), True, 1.0)],
+                dtype=dt)
+        self._check_roundtrip(x)
+
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))])
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i2')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='>i4')
+        self._check_roundtrip(x)
+
+        x = np.array([1, 2, 3], dtype='<i4')
+        self._check_roundtrip(x)
+
+        # check long long can be represented as non-native
+        x = np.array([1, 2, 3], dtype='>q')
+        self._check_roundtrip(x)
+
+        # Native-only data types can be passed through the buffer interface
+        # only in native byte order
+        if sys.byteorder == 'little':
+            x = np.array([1, 2, 3], dtype='>g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+            x = np.array([1, 2, 3], dtype='<g')
+            self._check_roundtrip(x)
+        else:
+            x = np.array([1, 2, 3], dtype='>g')
+            self._check_roundtrip(x)
+            x = np.array([1, 2, 3], dtype='<g')
+            assert_raises(ValueError, self._check_roundtrip, x)
+
+    def test_roundtrip_half(self):
+        half_list = [
+            1.0,
+            -2.0,
+            6.5504 * 10**4,  # (max half precision)
+            2**-14,  # ~= 6.10352 * 10**-5 (minimum positive normal)
+            2**-24,  # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
+            0.0,
+            -0.0,
+            float('+inf'),
+            float('-inf'),
+            0.333251953125,  # ~= 1/3
+        ]
+
+        x = np.array(half_list, dtype='>e')
+        self._check_roundtrip(x)
+        x = np.array(half_list, dtype='<e')
+        self._check_roundtrip(x)
+
+    def test_roundtrip_single_types(self):
+        for typ in np.typeDict.values():
+            dtype = np.dtype(typ)
+
+            if dtype.char in 'Mm':
+                # datetimes cannot be used in buffers
+                continue
+            if dtype.char == 'V':
+                # skip void
+                continue
+
+            x = np.zeros(4, dtype=dtype)
+            self._check_roundtrip(x)
+
+            if dtype.char not in 'qQgG':
+                dt = dtype.newbyteorder('<')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+                dt = dtype.newbyteorder('>')
+                x = np.zeros(4, dtype=dt)
+                self._check_roundtrip(x)
+
+    def test_roundtrip_scalar(self):
+        # Issue #4015.
+        self._check_roundtrip(0)
+
+    def test_export_simple_1d(self):
+        x = np.array([1, 2, 3, 4, 5], dtype='i')
+        y = memoryview(x)
+        assert_equal(y.format, 'i')
+        assert_equal(y.shape, (5,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.strides, (4,))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_simple_nd(self):
+        x = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        y = memoryview(x)
+        assert_equal(y.format, 'd')
+        assert_equal(y.shape, (2, 2))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (16, 8))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 8)
+
+    def test_export_discontiguous(self):
+        x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
+        y = memoryview(x)
+        assert_equal(y.format, 'f')
+        assert_equal(y.shape, (3, 3))
+        assert_equal(y.ndim, 2)
+        assert_equal(y.strides, (36, 4))
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 4)
+
+    def test_export_record(self):
+        dt = [('a', 'b'),
+              ('b', 'h'),
+              ('c', 'i'),
+              ('d', 'l'),
+              ('dx', 'q'),
+              ('e', 'B'),
+              ('f', 'H'),
+              ('g', 'I'),
+              ('h', 'L'),
+              ('hx', 'Q'),
+              ('i', np.single),
+              ('j', np.double),
+              ('k', np.longdouble),
+              ('ix', np.csingle),
+              ('jx', np.cdouble),
+              ('kx', np.clongdouble),
+              ('l', 'S4'),
+              ('m', 'U4'),
+              ('n', 'V3'),
+              ('o', '?'),
+              ('p', np.half),
+              ]
+        x = np.array(
+                [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                    asbytes('aaaa'), 'bbbb', asbytes('   '), True, 1.0)],
+                dtype=dt)
+        y = memoryview(x)
+        assert_equal(y.shape, (1,))
+        assert_equal(y.ndim, 1)
+        assert_equal(y.suboffsets, EMPTY)
+
+        sz = sum([np.dtype(b).itemsize for a, b in dt])
+        if np.dtype('l').itemsize == 4:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        else:
+            assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
+        # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides
+        if not (np.ones(1).strides[0] == np.iinfo(np.intp).max):
+            assert_equal(y.strides, (sz,))
+        assert_equal(y.itemsize, sz)
+
+    def test_export_subarray(self):
+        x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))])
+        y = memoryview(x)
+        assert_equal(y.format, 'T{(2,2)i:a:}')
+        assert_equal(y.shape, EMPTY)
+        assert_equal(y.ndim, 0)
+        assert_equal(y.strides, EMPTY)
+        assert_equal(y.suboffsets, EMPTY)
+        assert_equal(y.itemsize, 16)
+
+    def test_export_endian(self):
+        x = np.array([1, 2, 3], dtype='>i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, '>i')
+        else:
+            assert_equal(y.format, 'i')
+
+        x = np.array([1, 2, 3], dtype='<i')
+        y = memoryview(x)
+        if sys.byteorder == 'little':
+            assert_equal(y.format, 'i')
+        else:
+            assert_equal(y.format, '<i')
+
+    def test_export_flags(self):
+        # Check SIMPLE flag, see also gh-3613 (exception should be BufferError)
+        assert_raises(ValueError, get_buffer_info, np.arange(5)[::2], ('SIMPLE',))
+
+    def test_padding(self):
+        for j in range(8):
+            x = np.array([(1,), (2,)], dtype={'f0': (int, j)})
+            self._check_roundtrip(x)
+
+    def test_reference_leak(self):
+        count_1 = sys.getrefcount(np.core._internal)
+        a = np.zeros(4)
+        b = memoryview(a)
+        c = np.asarray(b)
+        count_2 = sys.getrefcount(np.core._internal)
+        assert_equal(count_1, count_2)
+        del c  # avoid pyflakes unused variable warning.
+
+    def test_padded_struct_array(self):
+        dt1 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
+                align=True)
+        x1 = np.arange(dt1.itemsize, dtype=np.int8).view(dt1)
+        self._check_roundtrip(x1)
+
+        dt2 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')],
+                align=True)
+        x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
+        self._check_roundtrip(x2)
+
+        dt3 = np.dtype(
+                [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
+                    ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+        x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
+        self._check_roundtrip(x3)
+
+    def test_relaxed_strides(self):
+        # Test that relaxed strides are converted to non-relaxed
+        c = np.ones((1, 10, 10), dtype='i8')
+
+        # Check for NPY_RELAXED_STRIDES_CHECKING:
+        if np.ones((10, 1), order="C").flags.f_contiguous:
+            c.strides = (-1, 80, 8)
+
+        assert_(memoryview(c).strides == (800, 80, 8))
+
+        # Writing C-contiguous data to a BytesIO buffer should work
+        fd = io.BytesIO()
+        fd.write(c.data)
+
+        fortran = c.T
+        assert_(memoryview(fortran).strides == (8, 80, 800))
+
+        arr = np.ones((1, 10))
+        if arr.flags.f_contiguous:
+            shape, strides = get_buffer_info(arr, ['F_CONTIGUOUS'])
+            assert_(strides[0] == 8)
+            arr = np.ones((10, 1), order='F')
+            shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
+            assert_(strides[-1] == 8)
+
+
+class TestArrayAttributeDeletion(object):
+
+    def test_multiarray_writable_attributes_deletion(self):
+        """ticket #2046, should not seqfault, raise AttributeError"""
+        a = np.ones(2)
+        attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_not_writable_attributes_deletion(self):
+        a = np.ones(2)
+        attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
+                "ctypes", "T", "__array_interface__", "__array_struct__",
+                "__array_priority__", "__array_finalize__"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ['updateifcopy', 'aligned', 'writeable']
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+    def test_multiarray_flags_not_writable_attribute_deletion(self):
+        a = np.ones(2).flags
+        attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
+                "owndata", "fnc", "forc", "behaved", "carray", "farray",
+                "num"]
+        for s in attr:
+            assert_raises(AttributeError, delattr, a, s)
+
+
+def test_array_interface():
+    # Test scalar coercion within the array interface
+    class Foo(object):
+        def __init__(self, value):
+            self.value = value
+            self.iface = {'typestr': '=f8'}
+
+        def __float__(self):
+            return float(self.value)
+
+        @property
+        def __array_interface__(self):
+            return self.iface
+
+    f = Foo(0.5)
+    assert_equal(np.array(f), 0.5)
+    assert_equal(np.array([f]), [0.5])
+    assert_equal(np.array([f, f]), [0.5, 0.5])
+    assert_equal(np.array(f).dtype, np.dtype('=f8'))
+    # Test various shape definitions
+    f.iface['shape'] = ()
+    assert_equal(np.array(f), 0.5)
+    f.iface['shape'] = None
+    assert_raises(TypeError, np.array, f)
+    f.iface['shape'] = (1, 1)
+    assert_equal(np.array(f), [[0.5]])
+    f.iface['shape'] = (2,)
+    assert_raises(ValueError, np.array, f)
+
+    # test scalar with no shape
+    class ArrayLike(object):
+        array = np.array(1)
+        __array_interface__ = array.__array_interface__
+    assert_equal(np.array(ArrayLike()), 1)
+
+
+def test_array_interface_itemsize():
+    # See gh-6361
+    my_dtype = np.dtype({'names': ['A', 'B'], 'formats': ['f4', 'f4'],
+                         'offsets': [0, 8], 'itemsize': 16})
+    a = np.ones(10, dtype=my_dtype)
+    descr_t = np.dtype(a.__array_interface__['descr'])
+    typestr_t = np.dtype(a.__array_interface__['typestr'])
+    assert_equal(descr_t.itemsize, typestr_t.itemsize)
+
+
+def test_flat_element_deletion():
+    it = np.ones(3).flat
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+
+def test_scalar_element_deletion():
+    a = np.zeros(2, dtype=[('x', 'int'), ('y', 'int')])
+    assert_raises(ValueError, a[0].__delitem__, 'x')
+
+
+class TestMemEventHook(TestCase):
+    def test_mem_seteventhook(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+        test_pydatamem_seteventhook_start()
+        # force an allocation and free of a numpy array
+        # needs to be larger then limit of small memory cacher in ctors.c
+        a = np.zeros(1000)
+        del a
+        test_pydatamem_seteventhook_end()
+
+class TestMapIter(TestCase):
+    def test_mapiter(self):
+        # The actual tests are within the C code in
+        # multiarray/multiarray_tests.c.src
+
+        a = np.arange(12).reshape((3, 4)).astype(float)
+        index = ([1, 1, 2, 0],
+                 [0, 0, 2, 3])
+        vals = [50, 50, 30, 16]
+
+        test_inplace_increment(a, index, vals)
+        assert_equal(a, [[0.00, 1., 2.0, 19.],
+                         [104., 5., 6.0, 7.0],
+                         [8.00, 9., 40., 11.]])
+
+        b = np.arange(6).astype(float)
+        index = (np.array([1, 2, 0]),)
+        vals = [50, 4, 100.1]
+        test_inplace_increment(b, index, vals)
+        assert_equal(b, [100.1,  51.,   6.,   3.,   4.,   5.])
+
+
+class TestAsCArray(TestCase):
+    def test_1darray(self):
+        array = np.arange(24, dtype=np.double)
+        from_c = test_as_c_array(array, 3)
+        assert_equal(array[3], from_c)
+
+    def test_2darray(self):
+        array = np.arange(24, dtype=np.double).reshape(3, 8)
+        from_c = test_as_c_array(array, 2, 4)
+        assert_equal(array[2, 4], from_c)
+
+    def test_3darray(self):
+        array = np.arange(24, dtype=np.double).reshape(2, 3, 4)
+        from_c = test_as_c_array(array, 1, 2, 3)
+        assert_equal(array[1, 2, 3], from_c)
+
+
+class TestConversion(TestCase):
+    def test_array_scalar_relational_operation(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,))
+
+            # Unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+        # Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2),
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+class TestWhere(TestCase):
+    def test_basic(self):
+        dts = [np.bool, np.int16, np.int32, np.int64, np.double, np.complex128,
+               np.longdouble, np.clongdouble]
+        for dt in dts:
+            c = np.ones(53, dtype=np.bool)
+            assert_equal(np.where( c, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(~c, dt(0), dt(1)), dt(1))
+            assert_equal(np.where(True, dt(0), dt(1)), dt(0))
+            assert_equal(np.where(False, dt(0), dt(1)), dt(1))
+            d = np.ones_like(c).astype(dt)
+            e = np.zeros_like(d)
+            r = d.astype(dt)
+            c[7] = False
+            r[7] = e[7]
+            assert_equal(np.where(c, e, e), e)
+            assert_equal(np.where(c, d, e), r)
+            assert_equal(np.where(c, d, e[0]), r)
+            assert_equal(np.where(c, d[0], e), r)
+            assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2])
+            assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2])
+            assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3])
+            assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3])
+            assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2])
+            assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3])
+            assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3])
+
+    def test_exotic(self):
+        # object
+        assert_array_equal(np.where(True, None, None), np.array(None))
+        # zero sized
+        m = np.array([], dtype=bool).reshape(0, 3)
+        b = np.array([], dtype=np.float64).reshape(0, 3)
+        assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3))
+
+        # object cast
+        d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313,
+                      0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013,
+                      1.267, 0.229, -1.39, 0.487])
+        nan = float('NaN')
+        e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan,
+                     'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'],
+                     dtype=object)
+        m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
+                      0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool)
+
+        r = e[:]
+        r[np.where(m)] = d[np.where(m)]
+        assert_array_equal(np.where(m, d, e), r)
+
+        r = e[:]
+        r[np.where(~m)] = d[np.where(~m)]
+        assert_array_equal(np.where(m, e, d), r)
+
+        assert_array_equal(np.where(m, e, e), e)
+
+        # minimal dtype result with NaN scalar (e.g required by pandas)
+        d = np.array([1., 2.], dtype=np.float32)
+        e = float('NaN')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        e = float('-Infinity')
+        assert_equal(np.where(True, d, e).dtype, np.float32)
+        # also check upcast
+        e = float(1e150)
+        assert_equal(np.where(True, d, e).dtype, np.float64)
+
+    def test_ndim(self):
+        c = [True, False]
+        a = np.zeros((2, 25))
+        b = np.ones((2, 25))
+        r = np.where(np.array(c)[:,np.newaxis], a, b)
+        assert_array_equal(r[0], a[0])
+        assert_array_equal(r[1], b[0])
+
+        a = a.T
+        b = b.T
+        r = np.where(c, a, b)
+        assert_array_equal(r[:,0], a[:,0])
+        assert_array_equal(r[:,1], b[:,0])
+
+    def test_dtype_mix(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        a = np.uint32(1)
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                      dtype=np.float64)
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype(np.float32)
+        b = b.astype(np.int64)
+        assert_equal(np.where(c, a, b), r)
+
+        # non bool mask
+        c = c.astype(np.int)
+        c[c != 0] = 34242324
+        assert_equal(np.where(c, a, b), r)
+        # invert
+        tmpmask = c != 0
+        c[c == 0] = 41247212
+        c[tmpmask] = 0
+        assert_equal(np.where(c, b, a), r)
+
+    def test_foreign(self):
+        c = np.array([False, True, False, False, False, False, True, False,
+                     False, False, True, False])
+        r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
+                     dtype=np.float64)
+        a = np.ones(1, dtype='>i4')
+        b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
+                     dtype=np.float64)
+        assert_equal(np.where(c, a, b), r)
+
+        b = b.astype('>f8')
+        assert_equal(np.where(c, a, b), r)
+
+        a = a.astype('<i4')
+        assert_equal(np.where(c, a, b), r)
+
+        c = c.astype('>i4')
+        assert_equal(np.where(c, a, b), r)
+
+    def test_error(self):
+        c = [True, True]
+        a = np.ones((4, 5))
+        b = np.ones((5, 5))
+        assert_raises(ValueError, np.where, c, a, a)
+        assert_raises(ValueError, np.where, c[0], a, b)
+
+    def test_string(self):
+        # gh-4778 check strings are properly filled with nulls
+        a = np.array("abc")
+        b = np.array("x" * 753)
+        assert_equal(np.where(True, a, b), "abc")
+        assert_equal(np.where(False, b, a), "abc")
+
+        # check native datatype sized strings
+        a = np.array("abcd")
+        b = np.array("x" * 8)
+        assert_equal(np.where(True, a, b), "abcd")
+        assert_equal(np.where(False, b, a), "abcd")
+
+
+class TestSizeOf(TestCase):
+
+    def test_empty_array(self):
+        x = np.array([])
+        assert_(sys.getsizeof(x) > 0)
+
+    def check_array(self, dtype):
+        elem_size = dtype(0).itemsize
+
+        for length in [10, 50, 100, 500]:
+            x = np.arange(length, dtype=dtype)
+            assert_(sys.getsizeof(x) > length * elem_size)
+
+    def test_array_int32(self):
+        self.check_array(np.int32)
+
+    def test_array_int64(self):
+        self.check_array(np.int64)
+
+    def test_array_float32(self):
+        self.check_array(np.float32)
+
+    def test_array_float64(self):
+        self.check_array(np.float64)
+
+    def test_view(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d[...]) < sys.getsizeof(d))
+
+    def test_reshape(self):
+        d = np.ones(100)
+        assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy()))
+
+    def test_resize(self):
+        d = np.ones(100)
+        old = sys.getsizeof(d)
+        d.resize(50)
+        assert_(old > sys.getsizeof(d))
+        d.resize(150)
+        assert_(old < sys.getsizeof(d))
+
+    def test_error(self):
+        d = np.ones(100)
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestHashing(TestCase):
+
+    def test_arrays_not_hashable(self):
+        x = np.ones(3)
+        assert_raises(TypeError, hash, x)
+
+    def test_collections_hashable(self):
+        x = np.array([])
+        self.assertFalse(isinstance(x, collections.Hashable))
+
+
+class TestArrayPriority(TestCase):
+    # This will go away when __array_priority__ is settled, meanwhile
+    # it serves to check unintended changes.
+    op = operator
+    binary_ops = [
+        op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod,
+        op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt,
+        op.ge, op.lt, op.le, op.ne, op.eq
+        ]
+
+    if sys.version_info[0] < 3:
+        binary_ops.append(op.div)
+
+    class Foo(np.ndarray):
+        __array_priority__ = 100.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Bar(np.ndarray):
+        __array_priority__ = 101.
+
+        def __new__(cls, *args, **kwargs):
+            return np.array(*args, **kwargs).view(cls)
+
+    class Other(object):
+        __array_priority__ = 1000.
+
+        def _all(self, other):
+            return self.__class__()
+
+        __add__ = __radd__ = _all
+        __sub__ = __rsub__ = _all
+        __mul__ = __rmul__ = _all
+        __pow__ = __rpow__ = _all
+        __div__ = __rdiv__ = _all
+        __mod__ = __rmod__ = _all
+        __truediv__ = __rtruediv__ = _all
+        __floordiv__ = __rfloordiv__ = _all
+        __and__ = __rand__ = _all
+        __xor__ = __rxor__ = _all
+        __or__ = __ror__ = _all
+        __lshift__ = __rlshift__ = _all
+        __rshift__ = __rrshift__ = _all
+        __eq__ = _all
+        __ne__ = _all
+        __gt__ = _all
+        __ge__ = _all
+        __lt__ = _all
+        __le__ = _all
+
+    def test_ndarray_subclass(self):
+        a = np.array([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_ndarray_other(self):
+        a = np.array([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+    def test_subclass_subclass(self):
+        a = self.Foo([1, 2])
+        b = self.Bar([1, 2])
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Bar), msg)
+            assert_(isinstance(f(b, a), self.Bar), msg)
+
+    def test_subclass_other(self):
+        a = self.Foo([1, 2])
+        b = self.Other()
+        for f in self.binary_ops:
+            msg = repr(f)
+            assert_(isinstance(f(a, b), self.Other), msg)
+            assert_(isinstance(f(b, a), self.Other), msg)
+
+
+class TestBytestringArrayNonzero(TestCase):
+
+    def test_empty_bstring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.str))
+
+    def test_whitespace_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_bstring_array_is_falsey(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_bstring_array_is_truthy(self):
+        a = np.array(['spam'], dtype=np.str)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+class TestUnicodeArrayNonzero(TestCase):
+
+    def test_empty_ustring_array_is_falsey(self):
+        self.assertFalse(np.array([''], dtype=np.unicode))
+
+    def test_whitespace_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '  \0\0'
+        self.assertFalse(a)
+
+    def test_all_null_ustring_array_is_falsey(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = '\0\0\0\0'
+        self.assertFalse(a)
+
+    def test_null_inside_ustring_array_is_truthy(self):
+        a = np.array(['eggs'], dtype=np.unicode)
+        a[0] = ' \0 \0'
+        self.assertTrue(a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
new file mode 100644
index 0000000000..ed01979912
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
@@ -0,0 +1,2638 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+
+import numpy as np
+from numpy import array, arange, nditer, all
+from numpy.compat import asbytes, sixu
+from numpy.core.multiarray_tests import test_nditer_too_large
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_raises, dec
+    )
+
+
+def iter_multi_index(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.multi_index)
+        i.iternext()
+    return ret
+
+def iter_indices(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.index)
+        i.iternext()
+    return ret
+
+def iter_iterindices(i):
+    ret = []
+    while not i.finished:
+        ret.append(i.iterindex)
+        i.iternext()
+    return ret
+
+def test_iter_refcount():
+    # Make sure the iterator doesn't leak
+
+    # Basic
+    a = arange(6)
+    dt = np.dtype('f4').newbyteorder()
+    rc_a = sys.getrefcount(a)
+    rc_dt = sys.getrefcount(dt)
+    it = nditer(a, [],
+                [['readwrite', 'updateifcopy']],
+                casting='unsafe',
+                op_dtypes=[dt])
+    assert_(not it.iterationneedsapi)
+    assert_(sys.getrefcount(a) > rc_a)
+    assert_(sys.getrefcount(dt) > rc_dt)
+    it = None
+    assert_equal(sys.getrefcount(a), rc_a)
+    assert_equal(sys.getrefcount(dt), rc_dt)
+
+    # With a copy
+    a = arange(6, dtype='f4')
+    dt = np.dtype('f4')
+    rc_a = sys.getrefcount(a)
+    rc_dt = sys.getrefcount(dt)
+    it = nditer(a, [],
+                [['readwrite']],
+                op_dtypes=[dt])
+    rc2_a = sys.getrefcount(a)
+    rc2_dt = sys.getrefcount(dt)
+    it2 = it.copy()
+    assert_(sys.getrefcount(a) > rc2_a)
+    assert_(sys.getrefcount(dt) > rc2_dt)
+    it = None
+    assert_equal(sys.getrefcount(a), rc2_a)
+    assert_equal(sys.getrefcount(dt), rc2_dt)
+    it2 = None
+    assert_equal(sys.getrefcount(a), rc_a)
+    assert_equal(sys.getrefcount(dt), rc_dt)
+
+    del it2  # avoid pyflakes unused variable warning
+
+def test_iter_best_order():
+    # The iterator should always find the iteration order
+    # with increasing memory addresses
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, [], [['readonly']])
+            assert_equal([x for x in i], a)
+            # Fortran-order
+            i = nditer(aview.T, [], [['readonly']])
+            assert_equal([x for x in i], a)
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), [], [['readonly']])
+                assert_equal([x for x in i], a)
+
+def test_iter_c_order():
+    # Test forcing C order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='C')
+            assert_equal([x for x in i], aview.ravel(order='C'))
+            # Fortran-order
+            i = nditer(aview.T, order='C')
+            assert_equal([x for x in i], aview.T.ravel(order='C'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='C')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='C'))
+
+def test_iter_f_order():
+    # Test forcing F order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='F')
+            assert_equal([x for x in i], aview.ravel(order='F'))
+            # Fortran-order
+            i = nditer(aview.T, order='F')
+            assert_equal([x for x in i], aview.T.ravel(order='F'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='F')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='F'))
+
+def test_iter_c_or_f_order():
+    # Test forcing any contiguous (C or F) order
+
+    # Test the ordering for 1-D to 5-D shapes
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        a = arange(np.prod(shape))
+        # Test each combination of positive and negative strides
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, order='A')
+            assert_equal([x for x in i], aview.ravel(order='A'))
+            # Fortran-order
+            i = nditer(aview.T, order='A')
+            assert_equal([x for x in i], aview.T.ravel(order='A'))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1), order='A')
+                assert_equal([x for x in i],
+                                    aview.swapaxes(0, 1).ravel(order='A'))
+
+def test_iter_best_order_multi_index_1d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0,), (1,), (2,), (3,)])
+    # 1D reversed order
+    i = nditer(a[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(3,), (2,), (1,), (0,)])
+
+def test_iter_best_order_multi_index_2d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 0), (1, 1), (1, 2), (0, 0), (0, 1), (0, 2)])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 2), (0, 1), (0, 0), (1, 2), (1, 1), (1, 0)])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 2), (1, 1), (1, 0), (0, 2), (0, 1), (0, 0)])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 0), (0, 0), (1, 1), (0, 1), (1, 2), (0, 2)])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                                   ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(0, 2), (1, 2), (0, 1), (1, 1), (0, 0), (1, 0)])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                                   ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i), [(1, 2), (0, 2), (1, 1), (0, 1), (1, 0), (0, 0)])
+
+def test_iter_best_order_multi_index_3d():
+    # The multi-indices should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1),
+                             (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1)])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'), ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0),
+                             (0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1)])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1),
+                             (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1)])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 2, 0), (0, 2, 1), (0, 1, 0), (0, 1, 1), (0, 0, 0), (0, 0, 1),
+                             (1, 2, 0), (1, 2, 1), (1, 1, 0), (1, 1, 1), (1, 0, 0), (1, 0, 1)])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 1), (0, 0, 0), (0, 1, 1), (0, 1, 0), (0, 2, 1), (0, 2, 0),
+                             (1, 0, 1), (1, 0, 0), (1, 1, 1), (1, 1, 0), (1, 2, 1), (1, 2, 0)])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0), (1, 2, 0), (0, 2, 0),
+                             (1, 0, 1), (0, 0, 1), (1, 1, 1), (0, 1, 1), (1, 2, 1), (0, 2, 1)])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 2, 0), (1, 2, 0), (0, 1, 0), (1, 1, 0), (0, 0, 0), (1, 0, 0),
+                             (0, 2, 1), (1, 2, 1), (0, 1, 1), (1, 1, 1), (0, 0, 1), (1, 0, 1)])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                                    ['multi_index'], [['readonly']])
+    assert_equal(iter_multi_index(i),
+                            [(0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1),
+                             (0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0)])
+
+def test_iter_best_order_c_index_1d():
+    # The C index should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3])
+    # 1D reversed order
+    i = nditer(a[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 2, 1, 0])
+
+def test_iter_best_order_c_index_2d():
+    # The C index should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'),
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 3, 1, 4, 2, 5])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 4, 5, 0, 1, 2])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [2, 1, 0, 5, 4, 3])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 0, 4, 1, 5, 2])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [2, 5, 1, 4, 0, 3])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 2, 4, 1, 3, 0])
+
+def test_iter_best_order_c_index_3d():
+    # The C index should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                    ['c_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
+
+def test_iter_best_order_f_index_1d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(4)
+    # 1D order
+    i = nditer(a, ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3])
+    # 1D reversed order
+    i = nditer(a[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [3, 2, 1, 0])
+
+def test_iter_best_order_f_index_2d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(6)
+    # 2D C-order
+    i = nditer(a.reshape(2, 3), ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 2, 4, 1, 3, 5])
+    # 2D Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F'),
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5])
+    # 2D reversed C-order
+    i = nditer(a.reshape(2, 3)[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [1, 3, 5, 0, 2, 4])
+    i = nditer(a.reshape(2, 3)[:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [4, 2, 0, 5, 3, 1])
+    i = nditer(a.reshape(2, 3)[::-1, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 3, 1, 4, 2, 0])
+    # 2D reversed Fortran-order
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [1, 0, 3, 2, 5, 4])
+    i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [4, 5, 2, 3, 0, 1])
+    i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0])
+
+def test_iter_best_order_f_index_3d():
+    # The Fortran index should be correct with any reordering
+
+    a = arange(12)
+    # 3D C-order
+    i = nditer(a.reshape(2, 3, 2), ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11])
+    # 3D Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F'),
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+    # 3D reversed C-order
+    i = nditer(a.reshape(2, 3, 2)[::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10])
+    i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7])
+    i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5])
+    # 3D reversed Fortran-order
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7])
+    i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1],
+                                    ['f_index'], [['readonly']])
+    assert_equal(iter_indices(i),
+                            [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5])
+
+def test_iter_no_inner_full_coalesce():
+    # Check no_inner iterators which coalesce into a single inner loop
+
+    for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]:
+        size = np.prod(shape)
+        a = arange(size)
+        # Test each combination of forward and backwards indexing
+        for dirs in range(2**len(shape)):
+            dirs_index = [slice(None)]*len(shape)
+            for bit in range(len(shape)):
+                if ((2**bit) & dirs):
+                    dirs_index[bit] = slice(None, None, -1)
+            dirs_index = tuple(dirs_index)
+
+            aview = a.reshape(shape)[dirs_index]
+            # C-order
+            i = nditer(aview, ['external_loop'], [['readonly']])
+            assert_equal(i.ndim, 1)
+            assert_equal(i[0].shape, (size,))
+            # Fortran-order
+            i = nditer(aview.T, ['external_loop'], [['readonly']])
+            assert_equal(i.ndim, 1)
+            assert_equal(i[0].shape, (size,))
+            # Other order
+            if len(shape) > 2:
+                i = nditer(aview.swapaxes(0, 1),
+                                    ['external_loop'], [['readonly']])
+                assert_equal(i.ndim, 1)
+                assert_equal(i[0].shape, (size,))
+
+def test_iter_no_inner_dim_coalescing():
+    # Check no_inner iterators whose dimensions may not coalesce completely
+
+    # Skipping the last element in a dimension prevents coalescing
+    # with the next-bigger dimension
+    a = arange(24).reshape(2, 3, 4)[:,:, :-1]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 2)
+    assert_equal(i[0].shape, (3,))
+    a = arange(24).reshape(2, 3, 4)[:, :-1,:]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 2)
+    assert_equal(i[0].shape, (8,))
+    a = arange(24).reshape(2, 3, 4)[:-1,:,:]
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    assert_equal(i[0].shape, (12,))
+
+    # Even with lots of 1-sized dimensions, should still coalesce
+    a = arange(24).reshape(1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1)
+    i = nditer(a, ['external_loop'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    assert_equal(i[0].shape, (24,))
+
+def test_iter_dim_coalescing():
+    # Check that the correct number of dimensions are coalesced
+
+    # Tracking a multi-index disables coalescing
+    a = arange(24).reshape(2, 3, 4)
+    i = nditer(a, ['multi_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+
+    # A tracked index can allow coalescing if it's compatible with the array
+    a3d = arange(24).reshape(2, 3, 4)
+    i = nditer(a3d, ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.swapaxes(0, 1), ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, ['c_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, ['f_index'], [['readonly']])
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T.swapaxes(0, 1), ['f_index'], [['readonly']])
+    assert_equal(i.ndim, 3)
+
+    # When C or F order is forced, coalescing may still occur
+    a3d = arange(24).reshape(2, 3, 4)
+    i = nditer(a3d, order='C')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T, order='C')
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d, order='F')
+    assert_equal(i.ndim, 3)
+    i = nditer(a3d.T, order='F')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d, order='A')
+    assert_equal(i.ndim, 1)
+    i = nditer(a3d.T, order='A')
+    assert_equal(i.ndim, 1)
+
+def test_iter_broadcasting():
+    # Standard NumPy broadcasting rules
+
+    # 1D with scalar
+    i = nditer([arange(6), np.int32(2)], ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (6,))
+
+    # 2D with scalar
+    i = nditer([arange(6).reshape(2, 3), np.int32(2)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    # 2D with 1D
+    i = nditer([arange(6).reshape(2, 3), arange(3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    i = nditer([arange(2).reshape(2, 1), arange(3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+    # 2D with 2D
+    i = nditer([arange(2).reshape(2, 1), arange(3).reshape(1, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 6)
+    assert_equal(i.shape, (2, 3))
+
+    # 3D with scalar
+    i = nditer([np.int32(2), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 1D
+    i = nditer([arange(3), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(3), arange(8).reshape(4, 2, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 2D
+    i = nditer([arange(6).reshape(2, 3), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(2).reshape(2, 1), arange(24).reshape(4, 2, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(3).reshape(1, 3), arange(8).reshape(4, 2, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    # 3D with 3D
+    i = nditer([arange(2).reshape(1, 2, 1), arange(3).reshape(1, 1, 3),
+                        arange(4).reshape(4, 1, 1)],
+                        ['multi_index'], [['readonly']]*3)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(6).reshape(1, 2, 3), arange(4).reshape(4, 1, 1)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+    i = nditer([arange(24).reshape(4, 2, 3), arange(12).reshape(4, 1, 3)],
+                        ['multi_index'], [['readonly']]*2)
+    assert_equal(i.itersize, 24)
+    assert_equal(i.shape, (4, 2, 3))
+
+def test_iter_itershape():
+    # Check that allocated outputs work with a specified shape
+    a = np.arange(6, dtype='i2').reshape(2, 3)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (2, 3, 4))
+    assert_equal(i.operands[1].strides, (24, 8, 2))
+
+    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (3, 2, 4))
+    assert_equal(i.operands[1].strides, (8, 24, 2))
+
+    i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']],
+                            order='F',
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, -1, 4))
+    assert_equal(i.operands[1].shape, (3, 2, 4))
+    assert_equal(i.operands[1].strides, (2, 6, 12))
+
+    # If we specify 1 in the itershape, it shouldn't allow broadcasting
+    # of that dimension to a bigger value
+    assert_raises(ValueError, nditer, [a, None], [],
+                            [['readonly'], ['writeonly', 'allocate']],
+                            op_axes=[[0, 1, None], None],
+                            itershape=(-1, 1, 4))
+    # Test bug that for no op_axes but itershape, they are NULLed correctly
+    i = np.nditer([np.ones(2), None, None], itershape=(2,))
+
+def test_iter_broadcasting_errors():
+    # Check that errors are thrown for bad broadcasting shapes
+
+    # 1D with 1D
+    assert_raises(ValueError, nditer, [arange(2), arange(3)],
+                    [], [['readonly']]*2)
+    # 2D with 1D
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(2)],
+                    [], [['readonly']]*2)
+    # 2D with 2D
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(9).reshape(3, 3)],
+                    [], [['readonly']]*2)
+    assert_raises(ValueError, nditer,
+                    [arange(6).reshape(2, 3), arange(4).reshape(2, 2)],
+                    [], [['readonly']]*2)
+    # 3D with 3D
+    assert_raises(ValueError, nditer,
+                    [arange(36).reshape(3, 3, 4), arange(24).reshape(2, 3, 4)],
+                    [], [['readonly']]*2)
+    assert_raises(ValueError, nditer,
+                    [arange(8).reshape(2, 4, 1), arange(24).reshape(2, 3, 4)],
+                    [], [['readonly']]*2)
+
+    # Verify that the error message mentions the right shapes
+    try:
+        nditer([arange(2).reshape(1, 2, 1),
+                arange(3).reshape(1, 3),
+                arange(6).reshape(2, 3)],
+               [],
+               [['readonly'], ['readonly'], ['writeonly', 'no_broadcast']])
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain the shape of the 3rd operand
+        assert_(msg.find('(2,3)') >= 0,
+                'Message "%s" doesn\'t contain operand shape (2,3)' % msg)
+        # The message should contain the broadcast shape
+        assert_(msg.find('(1,2,3)') >= 0,
+                'Message "%s" doesn\'t contain broadcast shape (1,2,3)' % msg)
+
+    try:
+        nditer([arange(6).reshape(2, 3), arange(2)],
+               [],
+               [['readonly'], ['readonly']],
+               op_axes=[[0, 1], [0, np.newaxis]],
+               itershape=(4, 3))
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain "shape->remappedshape" for each operand
+        assert_(msg.find('(2,3)->(2,3)') >= 0,
+            'Message "%s" doesn\'t contain operand shape (2,3)->(2,3)' % msg)
+        assert_(msg.find('(2,)->(2,newaxis)') >= 0,
+                ('Message "%s" doesn\'t contain remapped operand shape' +
+                '(2,)->(2,newaxis)') % msg)
+        # The message should contain the itershape parameter
+        assert_(msg.find('(4,3)') >= 0,
+                'Message "%s" doesn\'t contain itershape parameter (4,3)' % msg)
+
+    try:
+        nditer([np.zeros((2, 1, 1)), np.zeros((2,))],
+               [],
+               [['writeonly', 'no_broadcast'], ['readonly']])
+        raise AssertionError('Should have raised a broadcast error')
+    except ValueError as e:
+        msg = str(e)
+        # The message should contain the shape of the bad operand
+        assert_(msg.find('(2,1,1)') >= 0,
+            'Message "%s" doesn\'t contain operand shape (2,1,1)' % msg)
+        # The message should contain the broadcast shape
+        assert_(msg.find('(2,1,2)') >= 0,
+                'Message "%s" doesn\'t contain the broadcast shape (2,1,2)' % msg)
+
+def test_iter_flags_errors():
+    # Check that bad combinations of flags produce errors
+
+    a = arange(6)
+
+    # Not enough operands
+    assert_raises(ValueError, nditer, [], [], [])
+    # Too many operands
+    assert_raises(ValueError, nditer, [a]*100, [], [['readonly']]*100)
+    # Bad global flag
+    assert_raises(ValueError, nditer, [a], ['bad flag'], [['readonly']])
+    # Bad op flag
+    assert_raises(ValueError, nditer, [a], [], [['readonly', 'bad flag']])
+    # Bad order parameter
+    assert_raises(ValueError, nditer, [a], [], [['readonly']], order='G')
+    # Bad casting parameter
+    assert_raises(ValueError, nditer, [a], [], [['readonly']], casting='noon')
+    # op_flags must match ops
+    assert_raises(ValueError, nditer, [a]*3, [], [['readonly']]*2)
+    # Cannot track both a C and an F index
+    assert_raises(ValueError, nditer, a,
+                ['c_index', 'f_index'], [['readonly']])
+    # Inner iteration and multi-indices/indices are incompatible
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'multi_index'], [['readonly']])
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'c_index'], [['readonly']])
+    assert_raises(ValueError, nditer, a,
+                ['external_loop', 'f_index'], [['readonly']])
+    # Must specify exactly one of readwrite/readonly/writeonly per operand
+    assert_raises(ValueError, nditer, a, [], [[]])
+    assert_raises(ValueError, nditer, a, [], [['readonly', 'writeonly']])
+    assert_raises(ValueError, nditer, a, [], [['readonly', 'readwrite']])
+    assert_raises(ValueError, nditer, a, [], [['writeonly', 'readwrite']])
+    assert_raises(ValueError, nditer, a,
+                [], [['readonly', 'writeonly', 'readwrite']])
+    # Python scalars are always readonly
+    assert_raises(TypeError, nditer, 1.5, [], [['writeonly']])
+    assert_raises(TypeError, nditer, 1.5, [], [['readwrite']])
+    # Array scalars are always readonly
+    assert_raises(TypeError, nditer, np.int32(1), [], [['writeonly']])
+    assert_raises(TypeError, nditer, np.int32(1), [], [['readwrite']])
+    # Check readonly array
+    a.flags.writeable = False
+    assert_raises(ValueError, nditer, a, [], [['writeonly']])
+    assert_raises(ValueError, nditer, a, [], [['readwrite']])
+    a.flags.writeable = True
+    # Multi-indices available only with the multi_index flag
+    i = nditer(arange(6), [], [['readonly']])
+    assert_raises(ValueError, lambda i:i.multi_index, i)
+    # Index available only with an index flag
+    assert_raises(ValueError, lambda i:i.index, i)
+    # GotoCoords and GotoIndex incompatible with buffering or no_inner
+
+    def assign_multi_index(i):
+        i.multi_index = (0,)
+
+    def assign_index(i):
+        i.index = 0
+
+    def assign_iterindex(i):
+        i.iterindex = 0
+
+    def assign_iterrange(i):
+        i.iterrange = (0, 1)
+    i = nditer(arange(6), ['external_loop'])
+    assert_raises(ValueError, assign_multi_index, i)
+    assert_raises(ValueError, assign_index, i)
+    assert_raises(ValueError, assign_iterindex, i)
+    assert_raises(ValueError, assign_iterrange, i)
+    i = nditer(arange(6), ['buffered'])
+    assert_raises(ValueError, assign_multi_index, i)
+    assert_raises(ValueError, assign_index, i)
+    assert_raises(ValueError, assign_iterrange, i)
+    # Can't iterate if size is zero
+    assert_raises(ValueError, nditer, np.array([]))
+
+def test_iter_slice():
+    a, b, c = np.arange(3), np.arange(3), np.arange(3.)
+    i = nditer([a, b, c], [], ['readwrite'])
+    i[0:2] = (3, 3)
+    assert_equal(a, [3, 1, 2])
+    assert_equal(b, [3, 1, 2])
+    assert_equal(c, [0, 1, 2])
+    i[1] = 12
+    assert_equal(i[0:2], [3, 12])
+
+def test_iter_nbo_align_contig():
+    # Check that byte order, alignment, and contig changes work
+
+    # Byte order change by requesting a specific dtype
+    a = np.arange(6, dtype='f4')
+    au = a.byteswap().newbyteorder()
+    assert_(a.dtype.byteorder != au.dtype.byteorder)
+    i = nditer(au, [], [['readwrite', 'updateifcopy']],
+                        casting='equiv',
+                        op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 2
+    i = None
+    assert_equal(au, [2]*6)
+
+    # Byte order change by requesting NBO
+    a = np.arange(6, dtype='f4')
+    au = a.byteswap().newbyteorder()
+    assert_(a.dtype.byteorder != au.dtype.byteorder)
+    i = nditer(au, [], [['readwrite', 'updateifcopy', 'nbo']], casting='equiv')
+    assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 2
+    i = None
+    assert_equal(au, [2]*6)
+
+    # Unaligned input
+    a = np.zeros((6*4+1,), dtype='i1')[1:]
+    a.dtype = 'f4'
+    a[:] = np.arange(6, dtype='f4')
+    assert_(not a.flags.aligned)
+    # Without 'aligned', shouldn't copy
+    i = nditer(a, [], [['readonly']])
+    assert_(not i.operands[0].flags.aligned)
+    assert_equal(i.operands[0], a)
+    # With 'aligned', should make a copy
+    i = nditer(a, [], [['readwrite', 'updateifcopy', 'aligned']])
+    assert_(i.operands[0].flags.aligned)
+    assert_equal(i.operands[0], a)
+    i.operands[0][:] = 3
+    i = None
+    assert_equal(a, [3]*6)
+
+    # Discontiguous input
+    a = arange(12)
+    # If it is contiguous, shouldn't copy
+    i = nditer(a[:6], [], [['readonly']])
+    assert_(i.operands[0].flags.contiguous)
+    assert_equal(i.operands[0], a[:6])
+    # If it isn't contiguous, should buffer
+    i = nditer(a[::2], ['buffered', 'external_loop'],
+                        [['readonly', 'contig']],
+                        buffersize=10)
+    assert_(i[0].flags.contiguous)
+    assert_equal(i[0], a[::2])
+
+def test_iter_array_cast():
+    # Check that arrays are cast as requested
+
+    # No cast 'f4' -> 'f4'
+    a = np.arange(6, dtype='f4').reshape(2, 3)
+    i = nditer(a, [], [['readwrite']], op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+
+    # Byte-order cast '<f4' -> '>f4'
+    a = np.arange(6, dtype='<f4').reshape(2, 3)
+    i = nditer(a, [], [['readwrite', 'updateifcopy']],
+            casting='equiv',
+            op_dtypes=[np.dtype('>f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('>f4'))
+
+    # Safe case 'f4' -> 'f8'
+    a = np.arange(24, dtype='f4').reshape(2, 3, 4).swapaxes(1, 2)
+    i = nditer(a, [], [['readonly', 'copy']],
+            casting='safe',
+            op_dtypes=[np.dtype('f8')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f8'))
+    # The memory layout of the temporary should match a (a is (48,4,16))
+    # except negative strides get flipped to positive strides.
+    assert_equal(i.operands[0].strides, (96, 8, 32))
+    a = a[::-1,:, ::-1]
+    i = nditer(a, [], [['readonly', 'copy']],
+            casting='safe',
+            op_dtypes=[np.dtype('f8')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f8'))
+    assert_equal(i.operands[0].strides, (96, 8, 32))
+
+    # Same-kind cast 'f8' -> 'f4' -> 'f8'
+    a = np.arange(24, dtype='f8').reshape(2, 3, 4).T
+    i = nditer(a, [],
+            [['readwrite', 'updateifcopy']],
+            casting='same_kind',
+            op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0], a)
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+    assert_equal(i.operands[0].strides, (4, 16, 48))
+    # Check that UPDATEIFCOPY is activated
+    i.operands[0][2, 1, 1] = -12.5
+    assert_(a[2, 1, 1] != -12.5)
+    i = None
+    assert_equal(a[2, 1, 1], -12.5)
+
+    a = np.arange(6, dtype='i4')[::-2]
+    i = nditer(a, [],
+            [['writeonly', 'updateifcopy']],
+            casting='unsafe',
+            op_dtypes=[np.dtype('f4')])
+    assert_equal(i.operands[0].dtype, np.dtype('f4'))
+    # Even though the stride was negative in 'a', it
+    # becomes positive in the temporary
+    assert_equal(i.operands[0].strides, (4,))
+    i.operands[0][:] = [1, 2, 3]
+    i = None
+    assert_equal(a, [1, 2, 3])
+
+def test_iter_array_cast_errors():
+    # Check that invalid casts are caught
+
+    # Need to enable copying for casts to occur
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly']], op_dtypes=[np.dtype('f8')])
+    # Also need to allow casting for casts to occur
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']], casting='no',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']], casting='equiv',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='no',
+                op_dtypes=[np.dtype('f4')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='equiv',
+                op_dtypes=[np.dtype('f4')])
+    # '<f4' -> '>f4' should not work with casting='no'
+    assert_raises(TypeError, nditer, arange(2, dtype='<f4'), [],
+                [['readonly', 'copy']], casting='no',
+                op_dtypes=[np.dtype('>f4')])
+    # 'f4' -> 'f8' is a safe cast, but 'f8' -> 'f4' isn't
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readwrite', 'updateifcopy']],
+                casting='safe',
+                op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, arange(2, dtype='f8'), [],
+                [['readwrite', 'updateifcopy']],
+                casting='safe',
+                op_dtypes=[np.dtype('f4')])
+    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
+    assert_raises(TypeError, nditer, arange(2, dtype='f4'), [],
+                [['readonly', 'copy']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('i4')])
+    assert_raises(TypeError, nditer, arange(2, dtype='i4'), [],
+                [['writeonly', 'updateifcopy']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('f4')])
+
+def test_iter_scalar_cast():
+    # Check that scalars are cast as requested
+
+    # No cast 'f4' -> 'f4'
+    i = nditer(np.float32(2.5), [], [['readonly']],
+                    op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.value.dtype, np.dtype('f4'))
+    assert_equal(i.value, 2.5)
+    # Safe cast 'f4' -> 'f8'
+    i = nditer(np.float32(2.5), [],
+                    [['readonly', 'copy']],
+                    casting='safe',
+                    op_dtypes=[np.dtype('f8')])
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.value.dtype, np.dtype('f8'))
+    assert_equal(i.value, 2.5)
+    # Same-kind cast 'f8' -> 'f4'
+    i = nditer(np.float64(2.5), [],
+                    [['readonly', 'copy']],
+                    casting='same_kind',
+                    op_dtypes=[np.dtype('f4')])
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.value.dtype, np.dtype('f4'))
+    assert_equal(i.value, 2.5)
+    # Unsafe cast 'f8' -> 'i4'
+    i = nditer(np.float64(3.0), [],
+                    [['readonly', 'copy']],
+                    casting='unsafe',
+                    op_dtypes=[np.dtype('i4')])
+    assert_equal(i.dtypes[0], np.dtype('i4'))
+    assert_equal(i.value.dtype, np.dtype('i4'))
+    assert_equal(i.value, 3)
+    # Readonly scalars may be cast even without setting COPY or BUFFERED
+    i = nditer(3, [], [['readonly']], op_dtypes=[np.dtype('f8')])
+    assert_equal(i[0].dtype, np.dtype('f8'))
+    assert_equal(i[0], 3.)
+
+def test_iter_scalar_cast_errors():
+    # Check that invalid casts are caught
+
+    # Need to allow copying/buffering for write casts of scalars to occur
+    assert_raises(TypeError, nditer, np.float32(2), [],
+                [['readwrite']], op_dtypes=[np.dtype('f8')])
+    assert_raises(TypeError, nditer, 2.5, [],
+                [['readwrite']], op_dtypes=[np.dtype('f4')])
+    # 'f8' -> 'f4' isn't a safe cast if the value would overflow
+    assert_raises(TypeError, nditer, np.float64(1e60), [],
+                [['readonly']],
+                casting='safe',
+                op_dtypes=[np.dtype('f4')])
+    # 'f4' -> 'i4' is neither a safe nor a same-kind cast
+    assert_raises(TypeError, nditer, np.float32(2), [],
+                [['readonly']],
+                casting='same_kind',
+                op_dtypes=[np.dtype('i4')])
+
+def test_iter_object_arrays_basic():
+    # Check that object arrays work
+
+    obj = {'a':3,'b':'d'}
+    a = np.array([[1, 2, 3], None, obj, None], dtype='O')
+    rc = sys.getrefcount(obj)
+
+    # Need to allow references for object arrays
+    assert_raises(TypeError, nditer, a)
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a, ['refs_ok'], ['readonly'])
+    vals = [x_[()] for x_ in i]
+    assert_equal(np.array(vals, dtype='O'), a)
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
+                        ['readonly'], order='C')
+    assert_(i.iterationneedsapi)
+    vals = [x_[()] for x_ in i]
+    assert_equal(np.array(vals, dtype='O'), a.reshape(2, 2).ravel(order='F'))
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc)
+
+    i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'],
+                        ['readwrite'], order='C')
+    for x in i:
+        x[...] = None
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(obj), rc-1)
+    assert_equal(a, np.array([None]*4, dtype='O'))
+
+def test_iter_object_arrays_conversions():
+    # Conversions to/from objects
+    a = np.arange(6, dtype='O')
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='i4')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    a = np.arange(6, dtype='i4')
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='O')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    # Non-contiguous object array
+    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'O')])
+    a = a['a']
+    a[:] = np.arange(6)
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='i4')
+    for x in i:
+        x[...] += 1
+    assert_equal(a, np.arange(6)+1)
+
+    #Non-contiguous value array
+    a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'i4')])
+    a = a['a']
+    a[:] = np.arange(6) + 98172488
+    i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'],
+                    casting='unsafe', op_dtypes='O')
+    ob = i[0][()]
+    rc = sys.getrefcount(ob)
+    for x in i:
+        x[...] += 1
+    assert_equal(sys.getrefcount(ob), rc-1)
+    assert_equal(a, np.arange(6)+98172489)
+
+def test_iter_common_dtype():
+    # Check that the iterator finds a common data type correctly
+
+    i = nditer([array([3], dtype='f4'), array([0], dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.dtypes[1], np.dtype('f8'))
+    i = nditer([array([3], dtype='i4'), array([0], dtype='f4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('f8'))
+    assert_equal(i.dtypes[1], np.dtype('f8'))
+    i = nditer([array([3], dtype='f4'), array(0, dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='same_kind')
+    assert_equal(i.dtypes[0], np.dtype('f4'))
+    assert_equal(i.dtypes[1], np.dtype('f4'))
+    i = nditer([array([3], dtype='u4'), array(0, dtype='i4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('u4'))
+    assert_equal(i.dtypes[1], np.dtype('u4'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*2,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('i8'))
+    assert_equal(i.dtypes[1], np.dtype('i8'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'),
+                 array([2j], dtype='c8'), array([9], dtype='f8')],
+                    ['common_dtype'],
+                    [['readonly', 'copy']]*4,
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('c16'))
+    assert_equal(i.dtypes[1], np.dtype('c16'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+    assert_equal(i.dtypes[3], np.dtype('c16'))
+    assert_equal(i.value, (3, -12, 2j, 9))
+
+    # When allocating outputs, other outputs aren't factored in
+    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')], [],
+                    [['readonly', 'copy'],
+                     ['writeonly', 'allocate'],
+                     ['writeonly']],
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('i4'))
+    assert_equal(i.dtypes[1], np.dtype('i4'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+    # But, if common data types are requested, they are
+    i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')],
+                    ['common_dtype'],
+                    [['readonly', 'copy'],
+                     ['writeonly', 'allocate'],
+                     ['writeonly']],
+                    casting='safe')
+    assert_equal(i.dtypes[0], np.dtype('c16'))
+    assert_equal(i.dtypes[1], np.dtype('c16'))
+    assert_equal(i.dtypes[2], np.dtype('c16'))
+
+def test_iter_op_axes():
+    # Check that custom axes work
+
+    # Reverse the axes
+    a = arange(6).reshape(2, 3)
+    i = nditer([a, a.T], [], [['readonly']]*2, op_axes=[[0, 1], [1, 0]])
+    assert_(all([x == y for (x, y) in i]))
+    a = arange(24).reshape(2, 3, 4)
+    i = nditer([a.T, a], [], [['readonly']]*2, op_axes=[[2, 1, 0], None])
+    assert_(all([x == y for (x, y) in i]))
+
+    # Broadcast 1D to any dimension
+    a = arange(1, 31).reshape(2, 3, 5)
+    b = arange(1, 3)
+    i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [0, -1, -1]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(2, 1, 1)).ravel())
+    b = arange(1, 4)
+    i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [-1, 0, -1]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 3, 1)).ravel())
+    b = arange(1, 6)
+    i = nditer([a, b], [], [['readonly']]*2,
+                            op_axes=[None, [np.newaxis, np.newaxis, 0]])
+    assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 1, 5)).ravel())
+
+    # Inner product-style broadcasting
+    a = arange(24).reshape(2, 3, 4)
+    b = arange(40).reshape(5, 2, 4)
+    i = nditer([a, b], ['multi_index'], [['readonly']]*2,
+                            op_axes=[[0, 1, -1, -1], [-1, -1, 0, 1]])
+    assert_equal(i.shape, (2, 3, 5, 2))
+
+    # Matrix product-style broadcasting
+    a = arange(12).reshape(3, 4)
+    b = arange(20).reshape(4, 5)
+    i = nditer([a, b], ['multi_index'], [['readonly']]*2,
+                            op_axes=[[0, -1], [-1, 1]])
+    assert_equal(i.shape, (3, 5))
+
+def test_iter_op_axes_errors():
+    # Check that custom axes throws errors for bad inputs
+
+    # Wrong number of items in op_axes
+    a = arange(6).reshape(2, 3)
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0], [1], [0]])
+    # Out of bounds items in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[2, 1], [0, 1]])
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [2, -1]])
+    # Duplicate items in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 0], [0, 1]])
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [1, 1]])
+
+    # Different sized arrays in op_axes
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [0, 1, 0]])
+
+    # Non-broadcastable dimensions in the result
+    assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2,
+                                    op_axes=[[0, 1], [1, 0]])
+
+def test_iter_copy():
+    # Check that copying the iterator works correctly
+    a = arange(24).reshape(2, 3, 4)
+
+    # Simple iterator
+    i = nditer(a)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterindex = 3
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    # Buffered iterator
+    i = nditer(a, ['buffered', 'ranged'], order='F', buffersize=3)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterindex = 3
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterrange = (3, 9)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    i.iterrange = (2, 18)
+    next(i)
+    next(i)
+    j = i.copy()
+    assert_equal([x[()] for x in i], [x[()] for x in j])
+
+    # Casting iterator
+    i = nditer(a, ['buffered'], order='F', casting='unsafe',
+                op_dtypes='f8', buffersize=5)
+    j = i.copy()
+    i = None
+    assert_equal([x[()] for x in j], a.ravel(order='F'))
+
+    a = arange(24, dtype='<i4').reshape(2, 3, 4)
+    i = nditer(a, ['buffered'], order='F', casting='unsafe',
+                op_dtypes='>f8', buffersize=5)
+    j = i.copy()
+    i = None
+    assert_equal([x[()] for x in j], a.ravel(order='F'))
+
+def test_iter_allocate_output_simple():
+    # Check that the iterator will properly allocate outputs
+
+    # Simple case
+    a = arange(6)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+
+def test_iter_allocate_output_buffered_readwrite():
+    # Allocated output with buffering + delay_bufalloc
+
+    a = arange(6)
+    i = nditer([a, None], ['buffered', 'delay_bufalloc'],
+                        [['readonly'], ['allocate', 'readwrite']])
+    i.operands[1][:] = 1
+    i.reset()
+    for x in i:
+        x[1][...] += x[0][...]
+    assert_equal(i.operands[1], a+1)
+
+def test_iter_allocate_output_itorder():
+    # The allocated output should match the iteration order
+
+    # C-order input, best iteration order
+    a = arange(6, dtype='i4').reshape(2, 3)
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, a.strides)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+    # F-order input, best iteration order
+    a = arange(24, dtype='i4').reshape(2, 3, 4).T
+    i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, a.strides)
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+    # Non-contiguous input, C iteration order
+    a = arange(24, dtype='i4').reshape(2, 3, 4).swapaxes(0, 1)
+    i = nditer([a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        order='C',
+                        op_dtypes=[None, np.dtype('f4')])
+    assert_equal(i.operands[1].shape, a.shape)
+    assert_equal(i.operands[1].strides, (32, 16, 4))
+    assert_equal(i.operands[1].dtype, np.dtype('f4'))
+
+def test_iter_allocate_output_opaxes():
+    # Specifing op_axes should work
+
+    a = arange(24, dtype='i4').reshape(2, 3, 4)
+    i = nditer([None, a], [], [['writeonly', 'allocate'], ['readonly']],
+                        op_dtypes=[np.dtype('u4'), None],
+                        op_axes=[[1, 2, 0], None])
+    assert_equal(i.operands[0].shape, (4, 2, 3))
+    assert_equal(i.operands[0].strides, (4, 48, 16))
+    assert_equal(i.operands[0].dtype, np.dtype('u4'))
+
+def test_iter_allocate_output_types_promotion():
+    # Check type promotion of automatic outputs
+
+    i = nditer([array([3], dtype='f4'), array([0], dtype='f8'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f8'))
+    i = nditer([array([3], dtype='i4'), array([0], dtype='f4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f8'))
+    i = nditer([array([3], dtype='f4'), array(0, dtype='f8'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('f4'))
+    i = nditer([array([3], dtype='u4'), array(0, dtype='i4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('u4'))
+    i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'), None], [],
+                    [['readonly']]*2+[['writeonly', 'allocate']])
+    assert_equal(i.dtypes[2], np.dtype('i8'))
+
+def test_iter_allocate_output_types_byte_order():
+    # Verify the rules for byte order changes
+
+    # When there's just one input, the output type exactly matches
+    a = array([3], dtype='u4').newbyteorder()
+    i = nditer([a, None], [],
+                    [['readonly'], ['writeonly', 'allocate']])
+    assert_equal(i.dtypes[0], i.dtypes[1])
+    # With two or more inputs, the output type is in native byte order
+    i = nditer([a, a, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    assert_(i.dtypes[0] != i.dtypes[2])
+    assert_equal(i.dtypes[0].newbyteorder('='), i.dtypes[2])
+
+def test_iter_allocate_output_types_scalar():
+    # If the inputs are all scalars, the output should be a scalar
+
+    i = nditer([None, 1, 2.3, np.float32(12), np.complex128(3)], [],
+                [['writeonly', 'allocate']] + [['readonly']]*4)
+    assert_equal(i.operands[0].dtype, np.dtype('complex128'))
+    assert_equal(i.operands[0].ndim, 0)
+
+def test_iter_allocate_output_subtype():
+    # Make sure that the subtype with priority wins
+
+    # matrix vs ndarray
+    a = np.matrix([[1, 2], [3, 4]])
+    b = np.arange(4).reshape(2, 2).T
+    i = nditer([a, b, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    assert_equal(type(a), type(i.operands[2]))
+    assert_(type(b) != type(i.operands[2]))
+    assert_equal(i.operands[2].shape, (2, 2))
+
+    # matrix always wants things to be 2D
+    b = np.arange(4).reshape(1, 2, 2)
+    assert_raises(RuntimeError, nditer, [a, b, None], [],
+                    [['readonly'], ['readonly'], ['writeonly', 'allocate']])
+    # but if subtypes are disabled, the result can still work
+    i = nditer([a, b, None], [],
+            [['readonly'], ['readonly'], ['writeonly', 'allocate', 'no_subtype']])
+    assert_equal(type(b), type(i.operands[2]))
+    assert_(type(a) != type(i.operands[2]))
+    assert_equal(i.operands[2].shape, (1, 2, 2))
+
+def test_iter_allocate_output_errors():
+    # Check that the iterator will throw errors for bad output allocations
+
+    # Need an input if no output data type is specified
+    a = arange(6)
+    assert_raises(TypeError, nditer, [a, None], [],
+                        [['writeonly'], ['writeonly', 'allocate']])
+    # Allocated output should be flagged for writing
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['allocate', 'readonly']])
+    # Allocated output can't have buffering without delayed bufalloc
+    assert_raises(ValueError, nditer, [a, None], ['buffered'],
+                                            ['allocate', 'readwrite'])
+    # Must specify at least one input
+    assert_raises(ValueError, nditer, [None, None], [],
+                        [['writeonly', 'allocate'],
+                         ['writeonly', 'allocate']],
+                        op_dtypes=[np.dtype('f4'), np.dtype('f4')])
+    # If using op_axes, must specify all the axes
+    a = arange(24, dtype='i4').reshape(2, 3, 4)
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, np.newaxis, 1]])
+    # If using op_axes, the axes must be within bounds
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, 3, 1]])
+    # If using op_axes, there can't be duplicates
+    assert_raises(ValueError, nditer, [a, None], [],
+                        [['readonly'], ['writeonly', 'allocate']],
+                        op_dtypes=[None, np.dtype('f4')],
+                        op_axes=[None, [0, 2, 1, 0]])
+
+def test_iter_remove_axis():
+    a = arange(24).reshape(2, 3, 4)
+
+    i = nditer(a, ['multi_index'])
+    i.remove_axis(1)
+    assert_equal([x for x in i], a[:, 0,:].ravel())
+
+    a = a[::-1,:,:]
+    i = nditer(a, ['multi_index'])
+    i.remove_axis(0)
+    assert_equal([x for x in i], a[0,:,:].ravel())
+
+def test_iter_remove_multi_index_inner_loop():
+    # Check that removing multi-index support works
+
+    a = arange(24).reshape(2, 3, 4)
+
+    i = nditer(a, ['multi_index'])
+    assert_equal(i.ndim, 3)
+    assert_equal(i.shape, (2, 3, 4))
+    assert_equal(i.itviews[0].shape, (2, 3, 4))
+
+    # Removing the multi-index tracking causes all dimensions to coalesce
+    before = [x for x in i]
+    i.remove_multi_index()
+    after = [x for x in i]
+
+    assert_equal(before, after)
+    assert_equal(i.ndim, 1)
+    assert_raises(ValueError, lambda i:i.shape, i)
+    assert_equal(i.itviews[0].shape, (24,))
+
+    # Removing the inner loop means there's just one iteration
+    i.reset()
+    assert_equal(i.itersize, 24)
+    assert_equal(i[0].shape, tuple())
+    i.enable_external_loop()
+    assert_equal(i.itersize, 24)
+    assert_equal(i[0].shape, (24,))
+    assert_equal(i.value, arange(24))
+
+def test_iter_iterindex():
+    # Make sure iterindex works
+
+    buffersize = 5
+    a = arange(24).reshape(4, 3, 2)
+    for flags in ([], ['buffered']):
+        i = nditer(a, flags, buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 2
+        assert_equal(iter_iterindices(i), list(range(2, 24)))
+
+        i = nditer(a, flags, order='F', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 5
+        assert_equal(iter_iterindices(i), list(range(5, 24)))
+
+        i = nditer(a[::-1], flags, order='F', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 9
+        assert_equal(iter_iterindices(i), list(range(9, 24)))
+
+        i = nditer(a[::-1, ::-1], flags, order='C', buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 13
+        assert_equal(iter_iterindices(i), list(range(13, 24)))
+
+        i = nditer(a[::1, ::-1], flags, buffersize=buffersize)
+        assert_equal(iter_iterindices(i), list(range(24)))
+        i.iterindex = 23
+        assert_equal(iter_iterindices(i), list(range(23, 24)))
+        i.reset()
+        i.iterindex = 2
+        assert_equal(iter_iterindices(i), list(range(2, 24)))
+
+def test_iter_iterrange():
+    # Make sure getting and resetting the iterrange works
+
+    buffersize = 5
+    a = arange(24, dtype='i4').reshape(4, 3, 2)
+    a_fort = a.ravel(order='F')
+
+    i = nditer(a, ['ranged'], ['readonly'], order='F',
+                buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal([x[()] for x in i], a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal([x[()] for x in i], a_fort[r[0]:r[1]])
+
+    i = nditer(a, ['ranged', 'buffered'], ['readonly'], order='F',
+                op_dtypes='f8', buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal([x[()] for x in i], a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal([x[()] for x in i], a_fort[r[0]:r[1]])
+
+    def get_array(i):
+        val = np.array([], dtype='f8')
+        for x in i:
+            val = np.concatenate((val, x))
+        return val
+
+    i = nditer(a, ['ranged', 'buffered', 'external_loop'],
+                ['readonly'], order='F',
+                op_dtypes='f8', buffersize=buffersize)
+    assert_equal(i.iterrange, (0, 24))
+    assert_equal(get_array(i), a_fort)
+    for r in [(0, 24), (1, 2), (3, 24), (5, 5), (0, 20), (23, 24)]:
+        i.iterrange = r
+        assert_equal(i.iterrange, r)
+        assert_equal(get_array(i), a_fort[r[0]:r[1]])
+
+def test_iter_buffering():
+    # Test buffering with several buffer sizes and types
+    arrays = []
+    # F-order swapped array
+    arrays.append(np.arange(24,
+                    dtype='c16').reshape(2, 3, 4).T.newbyteorder().byteswap())
+    # Contiguous 1-dimensional array
+    arrays.append(np.arange(10, dtype='f4'))
+    # Unaligned array
+    a = np.zeros((4*16+1,), dtype='i1')[1:]
+    a.dtype = 'i4'
+    a[:] = np.arange(16, dtype='i4')
+    arrays.append(a)
+    # 4-D F-order array
+    arrays.append(np.arange(120, dtype='i4').reshape(5, 3, 2, 4).T)
+    for a in arrays:
+        for buffersize in (1, 2, 3, 5, 8, 11, 16, 1024):
+            vals = []
+            i = nditer(a, ['buffered', 'external_loop'],
+                           [['readonly', 'nbo', 'aligned']],
+                           order='C',
+                           casting='equiv',
+                           buffersize=buffersize)
+            while not i.finished:
+                assert_(i[0].size <= buffersize)
+                vals.append(i[0].copy())
+                i.iternext()
+            assert_equal(np.concatenate(vals), a.ravel(order='C'))
+
+def test_iter_write_buffering():
+    # Test that buffering of writes is working
+
+    # F-order swapped array
+    a = np.arange(24).reshape(2, 3, 4).T.newbyteorder().byteswap()
+    i = nditer(a, ['buffered'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='equiv',
+                   order='C',
+                   buffersize=16)
+    x = 0
+    while not i.finished:
+        i[0] = x
+        x += 1
+        i.iternext()
+    assert_equal(a.ravel(order='C'), np.arange(24))
+
+def test_iter_buffering_delayed_alloc():
+    # Test that delaying buffer allocation works
+
+    a = np.arange(6)
+    b = np.arange(1, dtype='f4')
+    i = nditer([a, b], ['buffered', 'delay_bufalloc', 'multi_index', 'reduce_ok'],
+                    ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes='f4')
+    assert_(i.has_delayed_bufalloc)
+    assert_raises(ValueError, lambda i:i.multi_index, i)
+    assert_raises(ValueError, lambda i:i[0], i)
+    assert_raises(ValueError, lambda i:i[0:2], i)
+
+    def assign_iter(i):
+        i[0] = 0
+    assert_raises(ValueError, assign_iter, i)
+
+    i.reset()
+    assert_(not i.has_delayed_bufalloc)
+    assert_equal(i.multi_index, (0,))
+    assert_equal(i[0], 0)
+    i[1] = 1
+    assert_equal(i[0:2], [0, 1])
+    assert_equal([[x[0][()], x[1][()]] for x in i], list(zip(range(6), [1]*6)))
+
+def test_iter_buffered_cast_simple():
+    # Test that buffering can handle a simple cast
+
+    a = np.arange(10, dtype='f4')
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f8')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+
+    assert_equal(a, 2*np.arange(10, dtype='f4'))
+
+def test_iter_buffered_cast_byteswapped():
+    # Test that buffering can handle a cast which requires swap->cast->swap
+
+    a = np.arange(10, dtype='f4').newbyteorder().byteswap()
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f8').newbyteorder()],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+
+    assert_equal(a, 2*np.arange(10, dtype='f4'))
+
+    try:
+        warnings.simplefilter("ignore", np.ComplexWarning)
+
+        a = np.arange(10, dtype='f8').newbyteorder().byteswap()
+        i = nditer(a, ['buffered', 'external_loop'],
+                       [['readwrite', 'nbo', 'aligned']],
+                       casting='unsafe',
+                       op_dtypes=[np.dtype('c8').newbyteorder()],
+                       buffersize=3)
+        for v in i:
+            v[...] *= 2
+
+        assert_equal(a, 2*np.arange(10, dtype='f8'))
+    finally:
+        warnings.simplefilter("default", np.ComplexWarning)
+
+def test_iter_buffered_cast_byteswapped_complex():
+    # Test that buffering can handle a cast which requires swap->cast->copy
+
+    a = np.arange(10, dtype='c8').newbyteorder().byteswap()
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype='c8') + 4j)
+
+    a = np.arange(10, dtype='c8')
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16').newbyteorder()],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype='c8') + 4j)
+
+    a = np.arange(10, dtype=np.clongdouble).newbyteorder().byteswap()
+    a += 2j
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('c16')],
+                   buffersize=3)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype=np.clongdouble) + 4j)
+
+    a = np.arange(10, dtype=np.longdouble).newbyteorder().byteswap()
+    i = nditer(a, ['buffered', 'external_loop'],
+                   [['readwrite', 'nbo', 'aligned']],
+                   casting='same_kind',
+                   op_dtypes=[np.dtype('f4')],
+                   buffersize=7)
+    for v in i:
+        v[...] *= 2
+    assert_equal(a, 2*np.arange(10, dtype=np.longdouble))
+
+def test_iter_buffered_cast_structured_type():
+    # Tests buffering of structured types
+
+    # simple -> struct type (duplicates the value)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.arange(3, dtype='f4') + 0.5
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt)
+    vals = [np.array(x) for x in i]
+    assert_equal(vals[0]['a'], 0.5)
+    assert_equal(vals[0]['b'], 0)
+    assert_equal(vals[0]['c'], [[(0.5)]*3]*2)
+    assert_equal(vals[0]['d'], 0.5)
+    assert_equal(vals[1]['a'], 1.5)
+    assert_equal(vals[1]['b'], 1)
+    assert_equal(vals[1]['c'], [[(1.5)]*3]*2)
+    assert_equal(vals[1]['d'], 1.5)
+    assert_equal(vals[0].dtype, np.dtype(sdt))
+
+    # object -> struct type
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.zeros((3,), dtype='O')
+    a[0] = (0.5, 0.5, [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5]], 0.5)
+    a[1] = (1.5, 1.5, [[1.5, 1.5, 1.5], [1.5, 1.5, 1.5]], 1.5)
+    a[2] = (2.5, 2.5, [[2.5, 2.5, 2.5], [2.5, 2.5, 2.5]], 2.5)
+    rc = sys.getrefcount(a[0])
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt)
+    vals = [x.copy() for x in i]
+    assert_equal(vals[0]['a'], 0.5)
+    assert_equal(vals[0]['b'], 0)
+    assert_equal(vals[0]['c'], [[(0.5)]*3]*2)
+    assert_equal(vals[0]['d'], 0.5)
+    assert_equal(vals[1]['a'], 1.5)
+    assert_equal(vals[1]['b'], 1)
+    assert_equal(vals[1]['c'], [[(1.5)]*3]*2)
+    assert_equal(vals[1]['d'], 1.5)
+    assert_equal(vals[0].dtype, np.dtype(sdt))
+    vals, i, x = [None]*3
+    assert_equal(sys.getrefcount(a[0]), rc)
+
+    # struct type -> simple (takes the first value)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    a = np.array([(5.5, 7, 'test'), (8, 10, 11)], dtype=sdt)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes='i4')
+    assert_equal([x_[()] for x_ in i], [5, 8])
+
+    # struct type -> struct type (field-wise copy)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    sdt2 = [('d', 'u2'), ('a', 'O'), ('b', 'f8')]
+    a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    assert_equal([np.array(x_) for x_ in i],
+                 [np.array((3, 1, 2), dtype=sdt2),
+                  np.array((6, 4, 5), dtype=sdt2)])
+
+    # struct type -> struct type (field gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, None), (8, 5, None)], dtype=sdt1))
+
+    # struct type -> struct type (structured field gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'i4')])]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, (0, 9)), (4, 5, (20, 21))], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, (0, 0)), (8, 5, (0, 0))], dtype=sdt1))
+
+    # struct type -> struct type (structured field w/ ref gets discarded)
+    sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'O')])]
+    sdt2 = [('b', 'O'), ('a', 'f8')]
+    a = np.array([(1, 2, (0, 9)), (4, 5, (20, 21))], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1), dtype=sdt2),
+                     np.array((5, 4), dtype=sdt2)])
+    assert_equal(a, np.array([(5, 2, (0, None)), (8, 5, (0, None))], dtype=sdt1))
+
+    # struct type -> struct type back (structured field w/ ref gets discarded)
+    sdt1 = [('b', 'O'), ('a', 'f8')]
+    sdt2 = [('a', 'f4'), ('b', 'i8'), ('d', [('a', 'i2'), ('b', 'O')])]
+    a = np.array([(1, 2), (4, 5)], dtype=sdt1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    vals = []
+    for x in i:
+        vals.append(np.array(x))
+        assert_equal(x['d'], np.array((0, None), dtype=[('a', 'i2'), ('b', 'O')]))
+        x['a'] = x['b']+3
+    assert_equal(vals, [np.array((2, 1, (0, None)), dtype=sdt2),
+                     np.array((5, 4, (0, None)), dtype=sdt2)])
+    assert_equal(a, np.array([(1, 4), (4, 7)], dtype=sdt1))
+
+def test_iter_buffered_cast_subarray():
+    # Tests buffering of subarrays
+
+    # one element -> many (copies it to all)
+    sdt1 = [('a', 'f4')]
+    sdt2 = [('a', 'f8', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    for x, count in zip(i, list(range(6))):
+        assert_(np.all(x['a'] == count))
+
+    # one element -> many -> back (copies it to all)
+    sdt1 = [('a', 'O', (1, 1))]
+    sdt2 = [('a', 'O', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_(np.all(x['a'] == count))
+        x['a'][0] += 2
+        count += 1
+    assert_equal(a['a'], np.arange(6).reshape(6, 1, 1)+2)
+
+    # many -> one element -> back (copies just element 0)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'O', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        x['a'] += 2
+        count += 1
+    assert_equal(a['a'], np.arange(6).reshape(6, 1, 1, 1)*np.ones((1, 3, 2, 2))+2)
+
+    # many -> one element -> back (copies just element 0)
+    sdt1 = [('a', 'f8', (3, 2, 2))]
+    sdt2 = [('a', 'O', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        count += 1
+
+    # many -> one element (copies just element 0)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'f4', (1,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'][:, 0, 0, 0] = np.arange(6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], count)
+        count += 1
+
+    # many -> matching shape (straightforward copy)
+    sdt1 = [('a', 'O', (3, 2, 2))]
+    sdt2 = [('a', 'f4', (3, 2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*3*2*2).reshape(6, 3, 2, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], a[count]['a'])
+        count += 1
+
+    # vector -> smaller vector (truncates)
+    sdt1 = [('a', 'f8', (6,))]
+    sdt2 = [('a', 'f4', (2,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*6).reshape(6, 6)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'], a[count]['a'][:2])
+        count += 1
+
+    # vector -> bigger vector (pads with zeros)
+    sdt1 = [('a', 'f8', (2,))]
+    sdt2 = [('a', 'f4', (6,))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2], a[count]['a'])
+        assert_equal(x['a'][2:], [0, 0, 0, 0])
+        count += 1
+
+    # vector -> matrix (broadcasts)
+    sdt1 = [('a', 'f8', (2,))]
+    sdt2 = [('a', 'f4', (2, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][0], a[count]['a'])
+        assert_equal(x['a'][1], a[count]['a'])
+        count += 1
+
+    # vector -> matrix (broadcasts and zero-pads)
+    sdt1 = [('a', 'f8', (2, 1))]
+    sdt2 = [('a', 'f4', (3, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2).reshape(6, 2, 1)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2, 0], a[count]['a'][:, 0])
+        assert_equal(x['a'][:2, 1], a[count]['a'][:, 0])
+        assert_equal(x['a'][2,:], [0, 0])
+        count += 1
+
+    # matrix -> matrix (truncates and zero-pads)
+    sdt1 = [('a', 'f8', (2, 3))]
+    sdt2 = [('a', 'f4', (3, 2))]
+    a = np.zeros((6,), dtype=sdt1)
+    a['a'] = np.arange(6*2*3).reshape(6, 2, 3)
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe',
+                    op_dtypes=sdt2)
+    assert_equal(i[0].dtype, np.dtype(sdt2))
+    count = 0
+    for x in i:
+        assert_equal(x['a'][:2, 0], a[count]['a'][:, 0])
+        assert_equal(x['a'][:2, 1], a[count]['a'][:, 1])
+        assert_equal(x['a'][2,:], [0, 0])
+        count += 1
+
+def test_iter_buffering_badwriteback():
+    # Writing back from a buffer cannot combine elements
+
+    # a needs write buffering, but had a broadcast dimension
+    a = np.arange(6).reshape(2, 3, 1)
+    b = np.arange(12).reshape(2, 3, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+
+    # But if a is readonly, it's fine
+    nditer([a, b], ['buffered', 'external_loop'],
+           [['readonly'], ['writeonly']],
+           order='C')
+
+    # If a has just one element, it's fine too (constant 0 stride, a reduction)
+    a = np.arange(1).reshape(1, 1, 1)
+    nditer([a, b], ['buffered', 'external_loop', 'reduce_ok'],
+           [['readwrite'], ['writeonly']],
+           order='C')
+
+    # check that it fails on other dimensions too
+    a = np.arange(6).reshape(1, 3, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+    a = np.arange(4).reshape(2, 1, 2)
+    assert_raises(ValueError, nditer, [a, b],
+                  ['buffered', 'external_loop'],
+                  [['readwrite'], ['writeonly']],
+                  order='C')
+
+def test_iter_buffering_string():
+    # Safe casting disallows shrinking strings
+    a = np.array(['abc', 'a', 'abcd'], dtype=np.bytes_)
+    assert_equal(a.dtype, np.dtype('S4'))
+    assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'],
+                  op_dtypes='S2')
+    i = nditer(a, ['buffered'], ['readonly'], op_dtypes='S6')
+    assert_equal(i[0], asbytes('abc'))
+    assert_equal(i[0].dtype, np.dtype('S6'))
+
+    a = np.array(['abc', 'a', 'abcd'], dtype=np.unicode)
+    assert_equal(a.dtype, np.dtype('U4'))
+    assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'],
+                    op_dtypes='U2')
+    i = nditer(a, ['buffered'], ['readonly'], op_dtypes='U6')
+    assert_equal(i[0], sixu('abc'))
+    assert_equal(i[0].dtype, np.dtype('U6'))
+
+def test_iter_buffering_growinner():
+    # Test that the inner loop grows when no buffering is needed
+    a = np.arange(30)
+    i = nditer(a, ['buffered', 'growinner', 'external_loop'],
+                           buffersize=5)
+    # Should end up with just one inner loop here
+    assert_equal(i[0].size, a.size)
+
+
+@dec.slow
+def test_iter_buffered_reduce_reuse():
+    # large enough array for all views, including negative strides.
+    a = np.arange(2*3**5)[3**5:3**5+1]
+    flags = ['buffered', 'delay_bufalloc', 'multi_index', 'reduce_ok', 'refs_ok']
+    op_flags = [('readonly',), ('readwrite', 'allocate')]
+    op_axes_list = [[(0, 1, 2), (0, 1, -1)], [(0, 1, 2), (0, -1, -1)]]
+    # wrong dtype to force buffering
+    op_dtypes = [np.float, a.dtype]
+
+    def get_params():
+        for xs in range(-3**2, 3**2 + 1):
+            for ys in range(xs, 3**2 + 1):
+                for op_axes in op_axes_list:
+                    # last stride is reduced and because of that not
+                    # important for this test, as it is the inner stride.
+                    strides = (xs * a.itemsize, ys * a.itemsize, a.itemsize)
+                    arr = np.lib.stride_tricks.as_strided(a, (3, 3, 3), strides)
+
+                    for skip in [0, 1]:
+                        yield arr, op_axes, skip
+
+    for arr, op_axes, skip in get_params():
+        nditer2 = np.nditer([arr.copy(), None],
+                            op_axes=op_axes, flags=flags, op_flags=op_flags,
+                            op_dtypes=op_dtypes)
+        nditer2.operands[-1][...] = 0
+        nditer2.reset()
+        nditer2.iterindex = skip
+
+        for (a2_in, b2_in) in nditer2:
+            b2_in += a2_in.astype(np.int_)
+
+        comp_res = nditer2.operands[-1]
+
+        for bufsize in range(0, 3**3):
+            nditer1 = np.nditer([arr, None],
+                                op_axes=op_axes, flags=flags, op_flags=op_flags,
+                                buffersize=bufsize, op_dtypes=op_dtypes)
+            nditer1.operands[-1][...] = 0
+            nditer1.reset()
+            nditer1.iterindex = skip
+
+            for (a1_in, b1_in) in nditer1:
+                b1_in += a1_in.astype(np.int_)
+
+            res = nditer1.operands[-1]
+            assert_array_equal(res, comp_res)
+
+
+def test_iter_no_broadcast():
+    # Test that the no_broadcast flag works
+    a = np.arange(24).reshape(2, 3, 4)
+    b = np.arange(6).reshape(2, 3, 1)
+    c = np.arange(12).reshape(3, 4)
+
+    nditer([a, b, c], [],
+           [['readonly', 'no_broadcast'],
+            ['readonly'], ['readonly']])
+    assert_raises(ValueError, nditer, [a, b, c], [],
+                  [['readonly'], ['readonly', 'no_broadcast'], ['readonly']])
+    assert_raises(ValueError, nditer, [a, b, c], [],
+                  [['readonly'], ['readonly'], ['readonly', 'no_broadcast']])
+
+def test_iter_nested_iters_basic():
+    # Test nested iteration basic usage
+    a = arange(12).reshape(2, 3, 2)
+
+    i, j = np.nested_iters(a, [[0], [1, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+def test_iter_nested_iters_reorder():
+    # Test nested iteration basic usage
+    a = arange(12).reshape(2, 3, 2)
+
+    # In 'K' order (default), it gets reordered
+    i, j = np.nested_iters(a, [[0], [2, 1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[2, 0], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+    # In 'C' order, it doesn't
+    i, j = np.nested_iters(a, [[0], [2, 1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4, 1, 3, 5], [6, 8, 10, 7, 9, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0], [2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [6, 7], [2, 3], [8, 9], [4, 5], [10, 11]])
+
+    i, j = np.nested_iters(a, [[2, 0], [1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [6, 8, 10], [1, 3, 5], [7, 9, 11]])
+
+def test_iter_nested_iters_flip_axes():
+    # Test nested iteration with negative axes
+    a = arange(12).reshape(2, 3, 2)[::-1, ::-1, ::-1]
+
+    # In 'K' order (default), the axes all get flipped
+    i, j = np.nested_iters(a, [[0], [1, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+    # In 'C' order, flipping axes is disabled
+    i, j = np.nested_iters(a, [[0], [1, 2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 10, 9, 8, 7, 6], [5, 4, 3, 2, 1, 0]])
+
+    i, j = np.nested_iters(a, [[0, 1], [2]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 10], [9, 8], [7, 6], [5, 4], [3, 2], [1, 0]])
+
+    i, j = np.nested_iters(a, [[0, 2], [1]], order='C')
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[11, 9, 7], [10, 8, 6], [5, 3, 1], [4, 2, 0]])
+
+def test_iter_nested_iters_broadcast():
+    # Test nested iteration with broadcasting
+    a = arange(2).reshape(2, 1)
+    b = arange(3).reshape(1, 3)
+
+    i, j = np.nested_iters([a, b], [[0], [1]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]])
+
+    i, j = np.nested_iters([a, b], [[1], [0]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[[0, 0], [1, 0]], [[0, 1], [1, 1]], [[0, 2], [1, 2]]])
+
+def test_iter_nested_iters_dtype_copy():
+    # Test nested iteration with a copy to change dtype
+
+    # copy
+    a = arange(6, dtype='i4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        op_flags=['readonly', 'copy'],
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2], [3, 4, 5]])
+    vals = None
+
+    # updateifcopy
+    a = arange(6, dtype='f4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        op_flags=['readwrite', 'updateifcopy'],
+                        casting='same_kind',
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    for x in i:
+        for y in j:
+            y[...] += 1
+    assert_equal(a, [[0, 1, 2], [3, 4, 5]])
+    i, j, x, y = (None,)*4  # force the updateifcopy
+    assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+def test_iter_nested_iters_dtype_buffered():
+    # Test nested iteration with buffering to change dtype
+
+    a = arange(6, dtype='f4').reshape(2, 3)
+    i, j = np.nested_iters(a, [[0], [1]],
+                        flags=['buffered'],
+                        op_flags=['readwrite'],
+                        casting='same_kind',
+                        op_dtypes='f8')
+    assert_equal(j[0].dtype, np.dtype('f8'))
+    for x in i:
+        for y in j:
+            y[...] += 1
+    assert_equal(a, [[1, 2, 3], [4, 5, 6]])
+
+def test_iter_reduction_error():
+
+    a = np.arange(6)
+    assert_raises(ValueError, nditer, [a, None], [],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0], [-1]])
+
+    a = np.arange(6).reshape(2, 3)
+    assert_raises(ValueError, nditer, [a, None], ['external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0, 1], [-1, -1]])
+
+def test_iter_reduction():
+    # Test doing reductions with the iterator
+
+    a = np.arange(6)
+    i = nditer([a, None], ['reduce_ok'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0], [-1]])
+    # Need to initialize the output operand to the addition unit
+    i.operands[1][...] = 0
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(i.operands[1].ndim, 0)
+    assert_equal(i.operands[1], np.sum(a))
+
+    a = np.arange(6).reshape(2, 3)
+    i = nditer([a, None], ['reduce_ok', 'external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[[0, 1], [-1, -1]])
+    # Need to initialize the output operand to the addition unit
+    i.operands[1][...] = 0
+    # Reduction shape/strides for the output
+    assert_equal(i[1].shape, (6,))
+    assert_equal(i[1].strides, (0,))
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(i.operands[1].ndim, 0)
+    assert_equal(i.operands[1], np.sum(a))
+
+    # This is a tricky reduction case for the buffering double loop
+    # to handle
+    a = np.ones((2, 3, 5))
+    it1 = nditer([a, None], ['reduce_ok', 'external_loop'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[None, [0, -1, 1]])
+    it2 = nditer([a, None], ['reduce_ok', 'external_loop',
+                            'buffered', 'delay_bufalloc'],
+                    [['readonly'], ['readwrite', 'allocate']],
+                    op_axes=[None, [0, -1, 1]], buffersize=10)
+    it1.operands[1].fill(0)
+    it2.operands[1].fill(0)
+    it2.reset()
+    for x in it1:
+        x[1][...] += x[0]
+    for x in it2:
+        x[1][...] += x[0]
+    assert_equal(it1.operands[1], it2.operands[1])
+    assert_equal(it2.operands[1].sum(), a.size)
+
+def test_iter_buffering_reduction():
+    # Test doing buffered reductions with the iterator
+
+    a = np.arange(6)
+    b = np.array(0., dtype='f8').byteswap().newbyteorder()
+    i = nditer([a, b], ['reduce_ok', 'buffered'],
+                    [['readonly'], ['readwrite', 'nbo']],
+                    op_axes=[[0], [-1]])
+    assert_equal(i[1].dtype, np.dtype('f8'))
+    assert_(i[1].dtype != b.dtype)
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    # Since no axes were specified, should have allocated a scalar
+    assert_equal(b, np.sum(a))
+
+    a = np.arange(6).reshape(2, 3)
+    b = np.array([0, 0], dtype='f8').byteswap().newbyteorder()
+    i = nditer([a, b], ['reduce_ok', 'external_loop', 'buffered'],
+                    [['readonly'], ['readwrite', 'nbo']],
+                    op_axes=[[0, 1], [0, -1]])
+    # Reduction shape/strides for the output
+    assert_equal(i[1].shape, (3,))
+    assert_equal(i[1].strides, (0,))
+    # Do the reduction
+    for x, y in i:
+        y[...] += x
+    assert_equal(b, np.sum(a, axis=1))
+
+    # Iterator inner double loop was wrong on this one
+    p = np.arange(2) + 1
+    it = np.nditer([p, None],
+            ['delay_bufalloc', 'reduce_ok', 'buffered', 'external_loop'],
+            [['readonly'], ['readwrite', 'allocate']],
+            op_axes=[[-1, 0], [-1, -1]],
+            itershape=(2, 2))
+    it.operands[1].fill(0)
+    it.reset()
+    assert_equal(it[0], [1, 2, 1, 2])
+
+def test_iter_buffering_reduction_reuse_reduce_loops():
+    # There was a bug triggering reuse of the reduce loop inappropriately,
+    # which caused processing to happen in unnecessarily small chunks
+    # and overran the buffer.
+
+    a = np.zeros((2, 7))
+    b = np.zeros((1, 7))
+    it = np.nditer([a, b], flags=['reduce_ok', 'external_loop', 'buffered'],
+                    op_flags=[['readonly'], ['readwrite']],
+                    buffersize=5)
+
+    bufsizes = []
+    for x, y in it:
+        bufsizes.append(x.shape[0])
+    assert_equal(bufsizes, [5, 2, 5, 2])
+    assert_equal(sum(bufsizes), a.size)
+
+def test_iter_writemasked_badinput():
+    a = np.zeros((2, 3))
+    b = np.zeros((3,))
+    m = np.array([[True, True, False], [False, True, False]])
+    m2 = np.array([True, True, False])
+    m3 = np.array([0, 1, 1], dtype='u1')
+    mbad1 = np.array([0, 1, 1], dtype='i1')
+    mbad2 = np.array([0, 1, 1], dtype='f4')
+
+    # Need an 'arraymask' if any operand is 'writemasked'
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readwrite', 'writemasked'], ['readonly']])
+
+    # A 'writemasked' operand must not be readonly
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readonly', 'writemasked'], ['readonly', 'arraymask']])
+
+    # 'writemasked' and 'arraymask' may not be used together
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readonly'], ['readwrite', 'arraymask', 'writemasked']])
+
+    # 'arraymask' may only be specified once
+    assert_raises(ValueError, nditer, [a, m, m2], [],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask'],
+                     ['readonly', 'arraymask']])
+
+    # An 'arraymask' with nothing 'writemasked' also doesn't make sense
+    assert_raises(ValueError, nditer, [a, m], [],
+                    [['readwrite'], ['readonly', 'arraymask']])
+
+    # A writemasked reduction requires a similarly smaller mask
+    assert_raises(ValueError, nditer, [a, b, m], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']])
+    # But this should work with a smaller/equal mask to the reduction operand
+    np.nditer([a, b, m2], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']])
+    # The arraymask itself cannot be a reduction
+    assert_raises(ValueError, nditer, [a, b, m2], ['reduce_ok'],
+                    [['readonly'],
+                     ['readwrite', 'writemasked'],
+                     ['readwrite', 'arraymask']])
+
+    # A uint8 mask is ok too
+    np.nditer([a, m3], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+    # An int8 mask isn't ok
+    assert_raises(TypeError, np.nditer, [a, mbad1], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+    # A float32 mask isn't ok
+    assert_raises(TypeError, np.nditer, [a, mbad2], ['buffered'],
+                    [['readwrite', 'writemasked'],
+                     ['readonly', 'arraymask']],
+                    op_dtypes=['f4', None],
+                    casting='same_kind')
+
+def test_iter_writemasked():
+    a = np.zeros((3,), dtype='f8')
+    msk = np.array([True, True, False])
+
+    # When buffering is unused, 'writemasked' effectively does nothing.
+    # It's up to the user of the iterator to obey the requested semantics.
+    it = np.nditer([a, msk], [],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']])
+    for x, m in it:
+        x[...] = 1
+    # Because we violated the semantics, all the values became 1
+    assert_equal(a, [1, 1, 1])
+
+    # Even if buffering is enabled, we still may be accessing the array
+    # directly.
+    it = np.nditer([a, msk], ['buffered'],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']])
+    for x, m in it:
+        x[...] = 2.5
+    # Because we violated the semantics, all the values became 2.5
+    assert_equal(a, [2.5, 2.5, 2.5])
+
+    # If buffering will definitely happening, for instance because of
+    # a cast, only the items selected by the mask will be copied back from
+    # the buffer.
+    it = np.nditer([a, msk], ['buffered'],
+                [['readwrite', 'writemasked'],
+                 ['readonly', 'arraymask']],
+                op_dtypes=['i8', None],
+                casting='unsafe')
+    for x, m in it:
+        x[...] = 3
+    # Even though we violated the semantics, only the selected values
+    # were copied back
+    assert_equal(a, [3, 3, 2.5])
+
+def test_iter_non_writable_attribute_deletion():
+    it = np.nditer(np.ones(2))
+    attr = ["value", "shape", "operands", "itviews", "has_delayed_bufalloc",
+            "iterationneedsapi", "has_multi_index", "has_index", "dtypes",
+            "ndim", "nop", "itersize", "finished"]
+
+    for s in attr:
+        assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_writable_attribute_deletion():
+    it = np.nditer(np.ones(2))
+    attr = [ "multi_index", "index", "iterrange", "iterindex"]
+    for s in attr:
+        assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_element_deletion():
+    it = np.nditer(np.ones(3))
+    try:
+        del it[1]
+        del it[1:2]
+    except TypeError:
+        pass
+    except:
+        raise AssertionError
+
+def test_iter_allocated_array_dtypes():
+    # If the dtype of an allocated output has a shape, the shape gets
+    # tacked onto the end of the result.
+    it = np.nditer(([1, 3, 20], None), op_dtypes=[None, ('i4', (2,))])
+    for a, b in it:
+        b[0] = a - 1
+        b[1] = a + 1
+    assert_equal(it.operands[1], [[0, 2], [2, 4], [19, 21]])
+
+    # Make sure this works for scalars too
+    it = np.nditer((10, 2, None), op_dtypes=[None, None, ('i4', (2, 2))])
+    for a, b, c in it:
+        c[0, 0] = a - b
+        c[0, 1] = a + b
+        c[1, 0] = a * b
+        c[1, 1] = a / b
+    assert_equal(it.operands[2], [[8, 12], [20, 5]])
+
+
+def test_0d_iter():
+    # Basic test for iteration of 0-d arrays:
+    i = nditer([2, 3], ['multi_index'], [['readonly']]*2)
+    assert_equal(i.ndim, 0)
+    assert_equal(next(i), (2, 3))
+    assert_equal(i.multi_index, ())
+    assert_equal(i.iterindex, 0)
+    assert_raises(StopIteration, next, i)
+    # test reset:
+    i.reset()
+    assert_equal(next(i), (2, 3))
+    assert_raises(StopIteration, next, i)
+
+    # test forcing to 0-d
+    i = nditer(np.arange(5), ['multi_index'], [['readonly']], op_axes=[()])
+    assert_equal(i.ndim, 0)
+    assert_equal(len(i), 1)
+    # note that itershape=(), still behaves like None due to the conversions
+
+    # Test a more complex buffered casting case (same as another test above)
+    sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')]
+    a = np.array(0.5, dtype='f4')
+    i = nditer(a, ['buffered', 'refs_ok'], ['readonly'],
+                    casting='unsafe', op_dtypes=sdt)
+    vals = next(i)
+    assert_equal(vals['a'], 0.5)
+    assert_equal(vals['b'], 0)
+    assert_equal(vals['c'], [[(0.5)]*3]*2)
+    assert_equal(vals['d'], 0.5)
+
+
+def test_0d_nested_iter():
+    a = np.arange(12).reshape(2, 3, 2)
+    i, j = np.nested_iters(a, [[], [1, 0, 2]])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
+
+    i, j = np.nested_iters(a, [[1, 0, 2], []])
+    vals = []
+    for x in i:
+        vals.append([y for y in j])
+    assert_equal(vals, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]])
+
+    i, j, k = np.nested_iters(a, [[2, 0], [], [1]])
+    vals = []
+    for x in i:
+        for y in j:
+            vals.append([z for z in k])
+    assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]])
+
+
+def test_iter_too_large():
+    # The total size of the iterator must not exceed the maximum intp due
+    # to broadcasting. Dividing by 1024 will keep it small enough to
+    # give a legal array.
+    size = np.iinfo(np.intp).max // 1024
+    arr = np.lib.stride_tricks.as_strided(np.zeros(1), (size,), (0,))
+    assert_raises(ValueError, nditer, (arr, arr[:, None]))
+    # test the same for multiindex. That may get more interesting when
+    # removing 0 dimensional axis is allowed (since an iterator can grow then)
+    assert_raises(ValueError, nditer,
+                  (arr, arr[:, None]), flags=['multi_index'])
+
+
+def test_iter_too_large_with_multiindex():
+    # When a multi index is being tracked, the error is delayed this
+    # checks the delayed error messages and getting below that by
+    # removing an axis.
+    base_size = 2**10
+    num = 1
+    while base_size**num < np.iinfo(np.intp).max:
+        num += 1
+
+    shape_template = [1, 1] * num
+    arrays = []
+    for i in range(num):
+        shape = shape_template[:]
+        shape[i * 2] = 2**10
+        arrays.append(np.empty(shape))
+    arrays = tuple(arrays)
+
+    # arrays are now too large to be broadcast. The different modes test
+    # different nditer functionality with or without GIL.
+    for mode in range(6):
+        assert_raises(ValueError, test_nditer_too_large, arrays, -1, mode)
+    # but if we do nothing with the nditer, it can be constructed:
+    test_nditer_too_large(arrays, -1, 7)
+
+    # When an axis is removed, things should work again (half the time):
+    for i in range(num):
+        for mode in range(6):
+            # an axis with size 1024 is removed:
+            test_nditer_too_large(arrays, i*2, mode)
+            # an axis with size 1 is removed:
+            assert_raises(ValueError, test_nditer_too_large,
+                          arrays, i*2 + 1, mode)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
new file mode 100644
index 0000000000..5dbeec3b4e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
@@ -0,0 +1,2438 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+import itertools
+import platform
+from decimal import Decimal
+
+import numpy as np
+from numpy.core import umath
+from numpy.random import rand, randint, randn
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_raises_regex, assert_array_equal, assert_almost_equal,
+    assert_array_almost_equal, dec
+)
+
+
+class TestResize(TestCase):
+    def test_copies(self):
+        A = np.array([[1, 2], [3, 4]])
+        Ar1 = np.array([[1, 2, 3, 4], [1, 2, 3, 4]])
+        assert_equal(np.resize(A, (2, 4)), Ar1)
+
+        Ar2 = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
+        assert_equal(np.resize(A, (4, 2)), Ar2)
+
+        Ar3 = np.array([[1, 2, 3], [4, 1, 2], [3, 4, 1], [2, 3, 4]])
+        assert_equal(np.resize(A, (4, 3)), Ar3)
+
+    def test_zeroresize(self):
+        A = np.array([[1, 2], [3, 4]])
+        Ar = np.resize(A, (0,))
+        assert_array_equal(Ar, np.array([]))
+        assert_equal(A.dtype, Ar.dtype)
+
+    def test_reshape_from_zero(self):
+        # See also gh-6740
+        A = np.zeros(0, dtype=[('a', np.float32, 1)])
+        Ar = np.resize(A, (2, 1))
+        assert_array_equal(Ar, np.zeros((2, 1), Ar.dtype))
+        assert_equal(A.dtype, Ar.dtype)
+
+
+class TestNonarrayArgs(TestCase):
+    # check that non-array arguments to functions wrap them in arrays
+    def test_choose(self):
+        choices = [[0, 1, 2],
+                   [3, 4, 5],
+                   [5, 6, 7]]
+        tgt = [5, 1, 5]
+        a = [2, 0, 1]
+
+        out = np.choose(a, choices)
+        assert_equal(out, tgt)
+
+    def test_clip(self):
+        arr = [-1, 5, 2, 3, 10, -4, -9]
+        out = np.clip(arr, 2, 7)
+        tgt = [2, 5, 2, 3, 7, 2, 2]
+        assert_equal(out, tgt)
+
+    def test_compress(self):
+        arr = [[0, 1, 2, 3, 4],
+               [5, 6, 7, 8, 9]]
+        tgt = [[5, 6, 7, 8, 9]]
+        out = np.compress([0, 1], arr, axis=0)
+        assert_equal(out, tgt)
+
+    def test_cumproduct(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.all(np.cumproduct(A) == np.array([1, 2, 6, 24, 120, 720])))
+
+    def test_diagonal(self):
+        a = [[0, 1, 2, 3],
+             [4, 5, 6, 7],
+             [8, 9, 10, 11]]
+        out = np.diagonal(a)
+        tgt = [0, 5, 10]
+
+        assert_equal(out, tgt)
+
+    def test_mean(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.mean(A) == 3.5)
+        assert_(np.all(np.mean(A, 0) == np.array([2.5, 3.5, 4.5])))
+        assert_(np.all(np.mean(A, 1) == np.array([2., 5.])))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.mean([])))
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_ptp(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.ptp(a, axis=0), 15.0)
+
+    def test_prod(self):
+        arr = [[1, 2, 3, 4],
+               [5, 6, 7, 9],
+               [10, 3, 4, 5]]
+        tgt = [24, 1890, 600]
+
+        assert_equal(np.prod(arr, axis=-1), tgt)
+
+    def test_ravel(self):
+        a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
+        tgt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+        assert_equal(np.ravel(a), tgt)
+
+    def test_repeat(self):
+        a = [1, 2, 3]
+        tgt = [1, 1, 2, 2, 3, 3]
+
+        out = np.repeat(a, 2)
+        assert_equal(out, tgt)
+
+    def test_reshape(self):
+        arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
+        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
+        assert_equal(np.reshape(arr, (2, 6)), tgt)
+
+    def test_round(self):
+        arr = [1.56, 72.54, 6.35, 3.25]
+        tgt = [1.6, 72.5, 6.4, 3.2]
+        assert_equal(np.around(arr, decimals=1), tgt)
+
+    def test_searchsorted(self):
+        arr = [-8, -5, -1, 3, 6, 10]
+        out = np.searchsorted(arr, 0)
+        assert_equal(out, 3)
+
+    def test_size(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_(np.size(A) == 6)
+        assert_(np.size(A, 0) == 2)
+        assert_(np.size(A, 1) == 3)
+
+    def test_squeeze(self):
+        A = [[[1, 1, 1], [2, 2, 2], [3, 3, 3]]]
+        assert_(np.squeeze(A).shape == (3, 3))
+
+    def test_std(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_almost_equal(np.std(A), 1.707825127659933)
+        assert_almost_equal(np.std(A, 0), np.array([1.5, 1.5, 1.5]))
+        assert_almost_equal(np.std(A, 1), np.array([0.81649658, 0.81649658]))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.std([])))
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_swapaxes(self):
+        tgt = [[[0, 4], [2, 6]], [[1, 5], [3, 7]]]
+        a = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
+        out = np.swapaxes(a, 0, 2)
+        assert_equal(out, tgt)
+
+    def test_sum(self):
+        m = [[1, 2, 3],
+             [4, 5, 6],
+             [7, 8, 9]]
+        tgt = [[6], [15], [24]]
+        out = np.sum(m, axis=1, keepdims=True)
+
+        assert_equal(tgt, out)
+
+    def test_take(self):
+        tgt = [2, 3, 5]
+        indices = [1, 2, 4]
+        a = [1, 2, 3, 4, 5]
+
+        out = np.take(a, indices)
+        assert_equal(out, tgt)
+
+    def test_trace(self):
+        c = [[1, 2], [3, 4], [5, 6]]
+        assert_equal(np.trace(c), 5)
+
+    def test_transpose(self):
+        arr = [[1, 2], [3, 4], [5, 6]]
+        tgt = [[1, 3, 5], [2, 4, 6]]
+        assert_equal(np.transpose(arr, (1, 0)), tgt)
+
+    def test_var(self):
+        A = [[1, 2, 3], [4, 5, 6]]
+        assert_almost_equal(np.var(A), 2.9166666666666665)
+        assert_almost_equal(np.var(A, 0), np.array([2.25, 2.25, 2.25]))
+        assert_almost_equal(np.var(A, 1), np.array([0.66666667, 0.66666667]))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.var([])))
+            assert_(w[0].category is RuntimeWarning)
+
+
+class TestBoolScalar(TestCase):
+    def test_logical(self):
+        f = np.False_
+        t = np.True_
+        s = "xyz"
+        self.assertTrue((t and s) is s)
+        self.assertTrue((f and s) is f)
+
+    def test_bitwise_or(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t | t) is t)
+        self.assertTrue((f | t) is t)
+        self.assertTrue((t | f) is t)
+        self.assertTrue((f | f) is f)
+
+    def test_bitwise_and(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t & t) is t)
+        self.assertTrue((f & t) is f)
+        self.assertTrue((t & f) is f)
+        self.assertTrue((f & f) is f)
+
+    def test_bitwise_xor(self):
+        f = np.False_
+        t = np.True_
+        self.assertTrue((t ^ t) is f)
+        self.assertTrue((f ^ t) is t)
+        self.assertTrue((t ^ f) is t)
+        self.assertTrue((f ^ f) is f)
+
+
+class TestBoolArray(TestCase):
+    def setUp(self):
+        # offset for simd tests
+        self.t = np.array([True] * 41, dtype=np.bool)[1::]
+        self.f = np.array([False] * 41, dtype=np.bool)[1::]
+        self.o = np.array([False] * 42, dtype=np.bool)[2::]
+        self.nm = self.f.copy()
+        self.im = self.t.copy()
+        self.nm[3] = True
+        self.nm[-2] = True
+        self.im[3] = False
+        self.im[-2] = False
+
+    def test_all_any(self):
+        self.assertTrue(self.t.all())
+        self.assertTrue(self.t.any())
+        self.assertFalse(self.f.all())
+        self.assertFalse(self.f.any())
+        self.assertTrue(self.nm.any())
+        self.assertTrue(self.im.any())
+        self.assertFalse(self.nm.all())
+        self.assertFalse(self.im.all())
+        # check bad element in all positions
+        for i in range(256 - 7):
+            d = np.array([False] * 256, dtype=np.bool)[7::]
+            d[i] = True
+            self.assertTrue(np.any(d))
+            e = np.array([True] * 256, dtype=np.bool)[7::]
+            e[i] = False
+            self.assertFalse(np.all(e))
+            assert_array_equal(e, ~d)
+        # big array test for blocked libc loops
+        for i in list(range(9, 6000, 507)) + [7764, 90021, -10]:
+            d = np.array([False] * 100043, dtype=np.bool)
+            d[i] = True
+            self.assertTrue(np.any(d), msg="%r" % i)
+            e = np.array([True] * 100043, dtype=np.bool)
+            e[i] = False
+            self.assertFalse(np.all(e), msg="%r" % i)
+
+    def test_logical_not_abs(self):
+        assert_array_equal(~self.t, self.f)
+        assert_array_equal(np.abs(~self.t), self.f)
+        assert_array_equal(np.abs(~self.f), self.t)
+        assert_array_equal(np.abs(self.f), self.f)
+        assert_array_equal(~np.abs(self.f), self.t)
+        assert_array_equal(~np.abs(self.t), self.f)
+        assert_array_equal(np.abs(~self.nm), self.im)
+        np.logical_not(self.t, out=self.o)
+        assert_array_equal(self.o, self.f)
+        np.abs(self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+
+    def test_logical_and_or_xor(self):
+        assert_array_equal(self.t | self.t, self.t)
+        assert_array_equal(self.f | self.f, self.f)
+        assert_array_equal(self.t | self.f, self.t)
+        assert_array_equal(self.f | self.t, self.t)
+        np.logical_or(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+        assert_array_equal(self.t & self.t, self.t)
+        assert_array_equal(self.f & self.f, self.f)
+        assert_array_equal(self.t & self.f, self.f)
+        assert_array_equal(self.f & self.t, self.f)
+        np.logical_and(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.t)
+        assert_array_equal(self.t ^ self.t, self.f)
+        assert_array_equal(self.f ^ self.f, self.f)
+        assert_array_equal(self.t ^ self.f, self.t)
+        assert_array_equal(self.f ^ self.t, self.t)
+        np.logical_xor(self.t, self.t, out=self.o)
+        assert_array_equal(self.o, self.f)
+
+        assert_array_equal(self.nm & self.t, self.nm)
+        assert_array_equal(self.im & self.f, False)
+        assert_array_equal(self.nm & True, self.nm)
+        assert_array_equal(self.im & False, self.f)
+        assert_array_equal(self.nm | self.t, self.t)
+        assert_array_equal(self.im | self.f, self.im)
+        assert_array_equal(self.nm | True, self.t)
+        assert_array_equal(self.im | False, self.im)
+        assert_array_equal(self.nm ^ self.t, self.im)
+        assert_array_equal(self.im ^ self.f, self.im)
+        assert_array_equal(self.nm ^ True, self.im)
+        assert_array_equal(self.im ^ False, self.im)
+
+
+class TestBoolCmp(TestCase):
+    def setUp(self):
+        self.f = np.ones(256, dtype=np.float32)
+        self.ef = np.ones(self.f.size, dtype=np.bool)
+        self.d = np.ones(128, dtype=np.float64)
+        self.ed = np.ones(self.d.size, dtype=np.bool)
+        # generate values for all permutation of 256bit simd vectors
+        s = 0
+        for i in range(32):
+            self.f[s:s+8] = [i & 2**x for x in range(8)]
+            self.ef[s:s+8] = [(i & 2**x) != 0 for x in range(8)]
+            s += 8
+        s = 0
+        for i in range(16):
+            self.d[s:s+4] = [i & 2**x for x in range(4)]
+            self.ed[s:s+4] = [(i & 2**x) != 0 for x in range(4)]
+            s += 4
+
+        self.nf = self.f.copy()
+        self.nd = self.d.copy()
+        self.nf[self.ef] = np.nan
+        self.nd[self.ed] = np.nan
+
+    def test_float(self):
+        # offset for alignment test
+        for i in range(4):
+            assert_array_equal(self.f[i:] > 0, self.ef[i:])
+            assert_array_equal(self.f[i:] - 1 >= 0, self.ef[i:])
+            assert_array_equal(self.f[i:] == 0, ~self.ef[i:])
+            assert_array_equal(-self.f[i:] < 0, self.ef[i:])
+            assert_array_equal(-self.f[i:] + 1 <= 0, self.ef[i:])
+            r = self.f[i:] != 0
+            assert_array_equal(r, self.ef[i:])
+            r2 = self.f[i:] != np.zeros_like(self.f[i:])
+            r3 = 0 != self.f[i:]
+            assert_array_equal(r, r2)
+            assert_array_equal(r, r3)
+            # check bool == 0x1
+            assert_array_equal(r.view(np.int8), r.astype(np.int8))
+            assert_array_equal(r2.view(np.int8), r2.astype(np.int8))
+            assert_array_equal(r3.view(np.int8), r3.astype(np.int8))
+
+            # isnan on amd64 takes the same code path
+            assert_array_equal(np.isnan(self.nf[i:]), self.ef[i:])
+
+    def test_double(self):
+        # offset for alignment test
+        for i in range(2):
+            assert_array_equal(self.d[i:] > 0, self.ed[i:])
+            assert_array_equal(self.d[i:] - 1 >= 0, self.ed[i:])
+            assert_array_equal(self.d[i:] == 0, ~self.ed[i:])
+            assert_array_equal(-self.d[i:] < 0, self.ed[i:])
+            assert_array_equal(-self.d[i:] + 1 <= 0, self.ed[i:])
+            r = self.d[i:] != 0
+            assert_array_equal(r, self.ed[i:])
+            r2 = self.d[i:] != np.zeros_like(self.d[i:])
+            r3 = 0 != self.d[i:]
+            assert_array_equal(r, r2)
+            assert_array_equal(r, r3)
+            # check bool == 0x1
+            assert_array_equal(r.view(np.int8), r.astype(np.int8))
+            assert_array_equal(r2.view(np.int8), r2.astype(np.int8))
+            assert_array_equal(r3.view(np.int8), r3.astype(np.int8))
+
+            # isnan on amd64 takes the same code path
+            assert_array_equal(np.isnan(self.nd[i:]), self.ed[i:])
+
+
+class TestSeterr(TestCase):
+    def test_default(self):
+        err = np.geterr()
+        self.assertEqual(err, dict(
+            divide='warn',
+            invalid='warn',
+            over='warn',
+            under='ignore',
+        ))
+
+    def test_set(self):
+        with np.errstate():
+            err = np.seterr()
+            old = np.seterr(divide='print')
+            self.assertTrue(err == old)
+            new = np.seterr()
+            self.assertTrue(new['divide'] == 'print')
+            np.seterr(over='raise')
+            self.assertTrue(np.geterr()['over'] == 'raise')
+            self.assertTrue(new['divide'] == 'print')
+            np.seterr(**old)
+            self.assertTrue(np.geterr() == old)
+
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_divide_err(self):
+        with np.errstate(divide='raise'):
+            try:
+                np.array([1.]) / np.array([0.])
+            except FloatingPointError:
+                pass
+            else:
+                self.fail()
+            np.seterr(divide='ignore')
+            np.array([1.]) / np.array([0.])
+
+    def test_errobj(self):
+        olderrobj = np.geterrobj()
+        self.called = 0
+        try:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter("always")
+                with np.errstate(divide='warn'):
+                    np.seterrobj([20000, 1, None])
+                    np.array([1.]) / np.array([0.])
+                    self.assertEqual(len(w), 1)
+
+            def log_err(*args):
+                self.called += 1
+                extobj_err = args
+                assert_(len(extobj_err) == 2)
+                assert_("divide" in extobj_err[0])
+
+            with np.errstate(divide='ignore'):
+                np.seterrobj([20000, 3, log_err])
+                np.array([1.]) / np.array([0.])
+            self.assertEqual(self.called, 1)
+
+            np.seterrobj(olderrobj)
+            with np.errstate(divide='ignore'):
+                np.divide(1., 0., extobj=[20000, 3, log_err])
+            self.assertEqual(self.called, 2)
+        finally:
+            np.seterrobj(olderrobj)
+            del self.called
+
+    def test_errobj_noerrmask(self):
+        # errmask = 0 has a special code path for the default
+        olderrobj = np.geterrobj()
+        try:
+            # set errobj to something non default
+            np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT,
+                         umath.ERR_DEFAULT + 1, None])
+            # call a ufunc
+            np.isnan(np.array([6]))
+            # same with the default, lots of times to get rid of possible
+            # pre-existing stack in the code
+            for i in range(10000):
+                np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, umath.ERR_DEFAULT,
+                             None])
+            np.isnan(np.array([6]))
+        finally:
+            np.seterrobj(olderrobj)
+
+
+class TestFloatExceptions(TestCase):
+    def assert_raises_fpe(self, fpeerr, flop, x, y):
+        ftype = type(x)
+        try:
+            flop(x, y)
+            assert_(False,
+                    "Type %s did not raise fpe error '%s'." % (ftype, fpeerr))
+        except FloatingPointError as exc:
+            assert_(str(exc).find(fpeerr) >= 0,
+                    "Type %s raised wrong fpe error '%s'." % (ftype, exc))
+
+    def assert_op_raises_fpe(self, fpeerr, flop, sc1, sc2):
+        # Check that fpe exception is raised.
+        #
+        # Given a floating operation `flop` and two scalar values, check that
+        # the operation raises the floating point exception specified by
+        # `fpeerr`. Tests all variants with 0-d array scalars as well.
+
+        self.assert_raises_fpe(fpeerr, flop, sc1, sc2)
+        self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2)
+        self.assert_raises_fpe(fpeerr, flop, sc1, sc2[()])
+        self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2[()])
+
+    @dec.knownfailureif(True, "See ticket #2350")
+    def test_floating_exceptions(self):
+        # Test basic arithmetic function errors
+        with np.errstate(all='raise'):
+            # Test for all real and complex float types
+            for typecode in np.typecodes['AllFloat']:
+                ftype = np.obj2sctype(typecode)
+                if np.dtype(ftype).kind == 'f':
+                    # Get some extreme values for the type
+                    fi = np.finfo(ftype)
+                    ft_tiny = fi.tiny
+                    ft_max = fi.max
+                    ft_eps = fi.eps
+                    underflow = 'underflow'
+                    divbyzero = 'divide by zero'
+                else:
+                    # 'c', complex, corresponding real dtype
+                    rtype = type(ftype(0).real)
+                    fi = np.finfo(rtype)
+                    ft_tiny = ftype(fi.tiny)
+                    ft_max = ftype(fi.max)
+                    ft_eps = ftype(fi.eps)
+                    # The complex types raise different exceptions
+                    underflow = ''
+                    divbyzero = ''
+                overflow = 'overflow'
+                invalid = 'invalid'
+
+                self.assert_raises_fpe(underflow,
+                                       lambda a, b: a/b, ft_tiny, ft_max)
+                self.assert_raises_fpe(underflow,
+                                       lambda a, b: a*b, ft_tiny, ft_tiny)
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a*b, ft_max, ftype(2))
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a/b, ft_max, ftype(0.5))
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a+b, ft_max, ft_max*ft_eps)
+                self.assert_raises_fpe(overflow,
+                                       lambda a, b: a-b, -ft_max, ft_max*ft_eps)
+                self.assert_raises_fpe(overflow,
+                                       np.power, ftype(2), ftype(2**fi.nexp))
+                self.assert_raises_fpe(divbyzero,
+                                       lambda a, b: a/b, ftype(1), ftype(0))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a/b, ftype(np.inf), ftype(np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a/b, ftype(0), ftype(0))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a-b, ftype(np.inf), ftype(np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a+b, ftype(np.inf), ftype(-np.inf))
+                self.assert_raises_fpe(invalid,
+                                       lambda a, b: a*b, ftype(0), ftype(np.inf))
+
+    def test_warnings(self):
+        # test warning code path
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter("always")
+            with np.errstate(all="warn"):
+                np.divide(1, 0.)
+                self.assertEqual(len(w), 1)
+                self.assertTrue("divide by zero" in str(w[0].message))
+                np.array(1e300) * np.array(1e300)
+                self.assertEqual(len(w), 2)
+                self.assertTrue("overflow" in str(w[-1].message))
+                np.array(np.inf) - np.array(np.inf)
+                self.assertEqual(len(w), 3)
+                self.assertTrue("invalid value" in str(w[-1].message))
+                np.array(1e-300) * np.array(1e-300)
+                self.assertEqual(len(w), 4)
+                self.assertTrue("underflow" in str(w[-1].message))
+
+
+class TestTypes(TestCase):
+    def check_promotion_cases(self, promote_func):
+        # tests that the scalars get coerced correctly.
+        b = np.bool_(0)
+        i8, i16, i32, i64 = np.int8(0), np.int16(0), np.int32(0), np.int64(0)
+        u8, u16, u32, u64 = np.uint8(0), np.uint16(0), np.uint32(0), np.uint64(0)
+        f32, f64, fld = np.float32(0), np.float64(0), np.longdouble(0)
+        c64, c128, cld = np.complex64(0), np.complex128(0), np.clongdouble(0)
+
+        # coercion within the same kind
+        assert_equal(promote_func(i8, i16), np.dtype(np.int16))
+        assert_equal(promote_func(i32, i8), np.dtype(np.int32))
+        assert_equal(promote_func(i16, i64), np.dtype(np.int64))
+        assert_equal(promote_func(u8, u32), np.dtype(np.uint32))
+        assert_equal(promote_func(f32, f64), np.dtype(np.float64))
+        assert_equal(promote_func(fld, f32), np.dtype(np.longdouble))
+        assert_equal(promote_func(f64, fld), np.dtype(np.longdouble))
+        assert_equal(promote_func(c128, c64), np.dtype(np.complex128))
+        assert_equal(promote_func(cld, c128), np.dtype(np.clongdouble))
+        assert_equal(promote_func(c64, fld), np.dtype(np.clongdouble))
+
+        # coercion between kinds
+        assert_equal(promote_func(b, i32), np.dtype(np.int32))
+        assert_equal(promote_func(b, u8), np.dtype(np.uint8))
+        assert_equal(promote_func(i8, u8), np.dtype(np.int16))
+        assert_equal(promote_func(u8, i32), np.dtype(np.int32))
+        assert_equal(promote_func(i64, u32), np.dtype(np.int64))
+        assert_equal(promote_func(u64, i32), np.dtype(np.float64))
+        assert_equal(promote_func(i32, f32), np.dtype(np.float64))
+        assert_equal(promote_func(i64, f32), np.dtype(np.float64))
+        assert_equal(promote_func(f32, i16), np.dtype(np.float32))
+        assert_equal(promote_func(f32, u32), np.dtype(np.float64))
+        assert_equal(promote_func(f32, c64), np.dtype(np.complex64))
+        assert_equal(promote_func(c128, f32), np.dtype(np.complex128))
+        assert_equal(promote_func(cld, f64), np.dtype(np.clongdouble))
+
+        # coercion between scalars and 1-D arrays
+        assert_equal(promote_func(np.array([b]), i8), np.dtype(np.int8))
+        assert_equal(promote_func(np.array([b]), u8), np.dtype(np.uint8))
+        assert_equal(promote_func(np.array([b]), i32), np.dtype(np.int32))
+        assert_equal(promote_func(np.array([b]), u32), np.dtype(np.uint32))
+        assert_equal(promote_func(np.array([i8]), i64), np.dtype(np.int8))
+        assert_equal(promote_func(u64, np.array([i32])), np.dtype(np.int32))
+        assert_equal(promote_func(i64, np.array([u32])), np.dtype(np.uint32))
+        assert_equal(promote_func(np.int32(-1), np.array([u64])),
+                     np.dtype(np.float64))
+        assert_equal(promote_func(f64, np.array([f32])), np.dtype(np.float32))
+        assert_equal(promote_func(fld, np.array([f32])), np.dtype(np.float32))
+        assert_equal(promote_func(np.array([f64]), fld), np.dtype(np.float64))
+        assert_equal(promote_func(fld, np.array([c64])),
+                     np.dtype(np.complex64))
+        assert_equal(promote_func(c64, np.array([f64])),
+                     np.dtype(np.complex128))
+        assert_equal(promote_func(np.complex64(3j), np.array([f64])),
+                     np.dtype(np.complex128))
+
+        # coercion between scalars and 1-D arrays, where
+        # the scalar has greater kind than the array
+        assert_equal(promote_func(np.array([b]), f64), np.dtype(np.float64))
+        assert_equal(promote_func(np.array([b]), i64), np.dtype(np.int64))
+        assert_equal(promote_func(np.array([b]), u64), np.dtype(np.uint64))
+        assert_equal(promote_func(np.array([i8]), f64), np.dtype(np.float64))
+        assert_equal(promote_func(np.array([u16]), f64), np.dtype(np.float64))
+
+        # uint and int are treated as the same "kind" for
+        # the purposes of array-scalar promotion.
+        assert_equal(promote_func(np.array([u16]), i32), np.dtype(np.uint16))
+
+        # float and complex are treated as the same "kind" for
+        # the purposes of array-scalar promotion, so that you can do
+        # (0j + float32array) to get a complex64 array instead of
+        # a complex128 array.
+        assert_equal(promote_func(np.array([f32]), c128),
+                     np.dtype(np.complex64))
+
+    def test_coercion(self):
+        def res_type(a, b):
+            return np.add(a, b).dtype
+
+        self.check_promotion_cases(res_type)
+
+        # Use-case: float/complex scalar * bool/int8 array
+        #           shouldn't narrow the float/complex type
+        for a in [np.array([True, False]), np.array([-3, 12], dtype=np.int8)]:
+            b = 1.234 * a
+            assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype)
+            b = np.longdouble(1.234) * a
+            assert_equal(b.dtype, np.dtype(np.longdouble),
+                         "array type %s" % a.dtype)
+            b = np.float64(1.234) * a
+            assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype)
+            b = np.float32(1.234) * a
+            assert_equal(b.dtype, np.dtype('f4'), "array type %s" % a.dtype)
+            b = np.float16(1.234) * a
+            assert_equal(b.dtype, np.dtype('f2'), "array type %s" % a.dtype)
+
+            b = 1.234j * a
+            assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype)
+            b = np.clongdouble(1.234j) * a
+            assert_equal(b.dtype, np.dtype(np.clongdouble),
+                         "array type %s" % a.dtype)
+            b = np.complex128(1.234j) * a
+            assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype)
+            b = np.complex64(1.234j) * a
+            assert_equal(b.dtype, np.dtype('c8'), "array type %s" % a.dtype)
+
+        # The following use-case is problematic, and to resolve its
+        # tricky side-effects requires more changes.
+        #
+        # Use-case: (1-t)*a, where 't' is a boolean array and 'a' is
+        #            a float32, shouldn't promote to float64
+        #
+        # a = np.array([1.0, 1.5], dtype=np.float32)
+        # t = np.array([True, False])
+        # b = t*a
+        # assert_equal(b, [1.0, 0.0])
+        # assert_equal(b.dtype, np.dtype('f4'))
+        # b = (1-t)*a
+        # assert_equal(b, [0.0, 1.5])
+        # assert_equal(b.dtype, np.dtype('f4'))
+        #
+        # Probably ~t (bitwise negation) is more proper to use here,
+        # but this is arguably less intuitive to understand at a glance, and
+        # would fail if 't' is actually an integer array instead of boolean:
+        #
+        # b = (~t)*a
+        # assert_equal(b, [0.0, 1.5])
+        # assert_equal(b.dtype, np.dtype('f4'))
+
+    def test_result_type(self):
+        self.check_promotion_cases(np.result_type)
+        assert_(np.result_type(None) == np.dtype(None))
+
+    def test_promote_types_endian(self):
+        # promote_types should always return native-endian types
+        assert_equal(np.promote_types('<i8', '<i8'), np.dtype('i8'))
+        assert_equal(np.promote_types('>i8', '>i8'), np.dtype('i8'))
+
+        assert_equal(np.promote_types('>i8', '>U16'), np.dtype('U21'))
+        assert_equal(np.promote_types('<i8', '<U16'), np.dtype('U21'))
+        assert_equal(np.promote_types('>U16', '>i8'), np.dtype('U21'))
+        assert_equal(np.promote_types('<U16', '<i8'), np.dtype('U21'))
+
+        assert_equal(np.promote_types('<S5', '<U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('>S5', '>U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('<U8', '<S5'), np.dtype('U8'))
+        assert_equal(np.promote_types('>U8', '>S5'), np.dtype('U8'))
+        assert_equal(np.promote_types('<U5', '<U8'), np.dtype('U8'))
+        assert_equal(np.promote_types('>U8', '>U5'), np.dtype('U8'))
+
+        assert_equal(np.promote_types('<M8', '<M8'), np.dtype('M8'))
+        assert_equal(np.promote_types('>M8', '>M8'), np.dtype('M8'))
+        assert_equal(np.promote_types('<m8', '<m8'), np.dtype('m8'))
+        assert_equal(np.promote_types('>m8', '>m8'), np.dtype('m8'))
+
+    def test_promote_types_strings(self):
+        assert_equal(np.promote_types('bool', 'S'), np.dtype('S5'))
+        assert_equal(np.promote_types('b', 'S'), np.dtype('S4'))
+        assert_equal(np.promote_types('u1', 'S'), np.dtype('S3'))
+        assert_equal(np.promote_types('u2', 'S'), np.dtype('S5'))
+        assert_equal(np.promote_types('u4', 'S'), np.dtype('S10'))
+        assert_equal(np.promote_types('u8', 'S'), np.dtype('S20'))
+        assert_equal(np.promote_types('i1', 'S'), np.dtype('S4'))
+        assert_equal(np.promote_types('i2', 'S'), np.dtype('S6'))
+        assert_equal(np.promote_types('i4', 'S'), np.dtype('S11'))
+        assert_equal(np.promote_types('i8', 'S'), np.dtype('S21'))
+        assert_equal(np.promote_types('bool', 'U'), np.dtype('U5'))
+        assert_equal(np.promote_types('b', 'U'), np.dtype('U4'))
+        assert_equal(np.promote_types('u1', 'U'), np.dtype('U3'))
+        assert_equal(np.promote_types('u2', 'U'), np.dtype('U5'))
+        assert_equal(np.promote_types('u4', 'U'), np.dtype('U10'))
+        assert_equal(np.promote_types('u8', 'U'), np.dtype('U20'))
+        assert_equal(np.promote_types('i1', 'U'), np.dtype('U4'))
+        assert_equal(np.promote_types('i2', 'U'), np.dtype('U6'))
+        assert_equal(np.promote_types('i4', 'U'), np.dtype('U11'))
+        assert_equal(np.promote_types('i8', 'U'), np.dtype('U21'))
+        assert_equal(np.promote_types('bool', 'S1'), np.dtype('S5'))
+        assert_equal(np.promote_types('bool', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('b', 'S1'), np.dtype('S4'))
+        assert_equal(np.promote_types('b', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u1', 'S1'), np.dtype('S3'))
+        assert_equal(np.promote_types('u1', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u2', 'S1'), np.dtype('S5'))
+        assert_equal(np.promote_types('u2', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u4', 'S1'), np.dtype('S10'))
+        assert_equal(np.promote_types('u4', 'S30'), np.dtype('S30'))
+        assert_equal(np.promote_types('u8', 'S1'), np.dtype('S20'))
+        assert_equal(np.promote_types('u8', 'S30'), np.dtype('S30'))
+
+    def test_can_cast(self):
+        assert_(np.can_cast(np.int32, np.int64))
+        assert_(np.can_cast(np.float64, np.complex))
+        assert_(not np.can_cast(np.complex, np.float))
+
+        assert_(np.can_cast('i8', 'f8'))
+        assert_(not np.can_cast('i8', 'f4'))
+        assert_(np.can_cast('i4', 'S11'))
+
+        assert_(np.can_cast('i8', 'i8', 'no'))
+        assert_(not np.can_cast('<i8', '>i8', 'no'))
+
+        assert_(np.can_cast('<i8', '>i8', 'equiv'))
+        assert_(not np.can_cast('<i4', '>i8', 'equiv'))
+
+        assert_(np.can_cast('<i4', '>i8', 'safe'))
+        assert_(not np.can_cast('<i8', '>i4', 'safe'))
+
+        assert_(np.can_cast('<i8', '>i4', 'same_kind'))
+        assert_(not np.can_cast('<i8', '>u4', 'same_kind'))
+
+        assert_(np.can_cast('<i8', '>u4', 'unsafe'))
+
+        assert_(np.can_cast('bool', 'S5'))
+        assert_(not np.can_cast('bool', 'S4'))
+
+        assert_(np.can_cast('b', 'S4'))
+        assert_(not np.can_cast('b', 'S3'))
+
+        assert_(np.can_cast('u1', 'S3'))
+        assert_(not np.can_cast('u1', 'S2'))
+        assert_(np.can_cast('u2', 'S5'))
+        assert_(not np.can_cast('u2', 'S4'))
+        assert_(np.can_cast('u4', 'S10'))
+        assert_(not np.can_cast('u4', 'S9'))
+        assert_(np.can_cast('u8', 'S20'))
+        assert_(not np.can_cast('u8', 'S19'))
+
+        assert_(np.can_cast('i1', 'S4'))
+        assert_(not np.can_cast('i1', 'S3'))
+        assert_(np.can_cast('i2', 'S6'))
+        assert_(not np.can_cast('i2', 'S5'))
+        assert_(np.can_cast('i4', 'S11'))
+        assert_(not np.can_cast('i4', 'S10'))
+        assert_(np.can_cast('i8', 'S21'))
+        assert_(not np.can_cast('i8', 'S20'))
+
+        assert_(np.can_cast('bool', 'S5'))
+        assert_(not np.can_cast('bool', 'S4'))
+
+        assert_(np.can_cast('b', 'U4'))
+        assert_(not np.can_cast('b', 'U3'))
+
+        assert_(np.can_cast('u1', 'U3'))
+        assert_(not np.can_cast('u1', 'U2'))
+        assert_(np.can_cast('u2', 'U5'))
+        assert_(not np.can_cast('u2', 'U4'))
+        assert_(np.can_cast('u4', 'U10'))
+        assert_(not np.can_cast('u4', 'U9'))
+        assert_(np.can_cast('u8', 'U20'))
+        assert_(not np.can_cast('u8', 'U19'))
+
+        assert_(np.can_cast('i1', 'U4'))
+        assert_(not np.can_cast('i1', 'U3'))
+        assert_(np.can_cast('i2', 'U6'))
+        assert_(not np.can_cast('i2', 'U5'))
+        assert_(np.can_cast('i4', 'U11'))
+        assert_(not np.can_cast('i4', 'U10'))
+        assert_(np.can_cast('i8', 'U21'))
+        assert_(not np.can_cast('i8', 'U20'))
+
+        assert_raises(TypeError, np.can_cast, 'i4', None)
+        assert_raises(TypeError, np.can_cast, None, 'i4')
+
+
+# Custom exception class to test exception propagation in fromiter
+class NIterError(Exception):
+    pass
+
+
+class TestFromiter(TestCase):
+    def makegen(self):
+        for x in range(24):
+            yield x**2
+
+    def test_types(self):
+        ai32 = np.fromiter(self.makegen(), np.int32)
+        ai64 = np.fromiter(self.makegen(), np.int64)
+        af = np.fromiter(self.makegen(), float)
+        self.assertTrue(ai32.dtype == np.dtype(np.int32))
+        self.assertTrue(ai64.dtype == np.dtype(np.int64))
+        self.assertTrue(af.dtype == np.dtype(float))
+
+    def test_lengths(self):
+        expected = np.array(list(self.makegen()))
+        a = np.fromiter(self.makegen(), int)
+        a20 = np.fromiter(self.makegen(), int, 20)
+        self.assertTrue(len(a) == len(expected))
+        self.assertTrue(len(a20) == 20)
+        self.assertRaises(ValueError, np.fromiter,
+                          self.makegen(), int, len(expected) + 10)
+
+    def test_values(self):
+        expected = np.array(list(self.makegen()))
+        a = np.fromiter(self.makegen(), int)
+        a20 = np.fromiter(self.makegen(), int, 20)
+        self.assertTrue(np.alltrue(a == expected, axis=0))
+        self.assertTrue(np.alltrue(a20 == expected[:20], axis=0))
+
+    def load_data(self, n, eindex):
+        # Utility method for the issue 2592 tests.
+        # Raise an exception at the desired index in the iterator.
+        for e in range(n):
+            if e == eindex:
+                raise NIterError('error at index %s' % eindex)
+            yield e
+
+    def test_2592(self):
+        # Test iteration exceptions are correctly raised.
+        count, eindex = 10, 5
+        self.assertRaises(NIterError, np.fromiter,
+                          self.load_data(count, eindex), dtype=int, count=count)
+
+    def test_2592_edge(self):
+        # Test iter. exceptions, edge case (exception at end of iterator).
+        count = 10
+        eindex = count-1
+        self.assertRaises(NIterError, np.fromiter,
+                          self.load_data(count, eindex), dtype=int, count=count)
+
+
+class TestNonzero(TestCase):
+    def test_nonzero_trivial(self):
+        assert_equal(np.count_nonzero(np.array([])), 0)
+        assert_equal(np.count_nonzero(np.array([], dtype='?')), 0)
+        assert_equal(np.nonzero(np.array([])), ([],))
+
+        assert_equal(np.count_nonzero(np.array(0)), 0)
+        assert_equal(np.count_nonzero(np.array(0, dtype='?')), 0)
+        assert_equal(np.nonzero(np.array(0)), ([],))
+        assert_equal(np.count_nonzero(np.array(1)), 1)
+        assert_equal(np.count_nonzero(np.array(1, dtype='?')), 1)
+        assert_equal(np.nonzero(np.array(1)), ([0],))
+
+    def test_nonzero_onedim(self):
+        x = np.array([1, 0, 2, -1, 0, 0, 8])
+        assert_equal(np.count_nonzero(x), 4)
+        assert_equal(np.count_nonzero(x), 4)
+        assert_equal(np.nonzero(x), ([0, 2, 3, 6],))
+
+        x = np.array([(1, 2), (0, 0), (1, 1), (-1, 3), (0, 7)],
+                     dtype=[('a', 'i4'), ('b', 'i2')])
+        assert_equal(np.count_nonzero(x['a']), 3)
+        assert_equal(np.count_nonzero(x['b']), 4)
+        assert_equal(np.nonzero(x['a']), ([0, 2, 3],))
+        assert_equal(np.nonzero(x['b']), ([0, 2, 3, 4],))
+
+    def test_nonzero_twodim(self):
+        x = np.array([[0, 1, 0], [2, 0, 3]])
+        assert_equal(np.count_nonzero(x), 3)
+        assert_equal(np.nonzero(x), ([0, 1, 1], [1, 0, 2]))
+
+        x = np.eye(3)
+        assert_equal(np.count_nonzero(x), 3)
+        assert_equal(np.nonzero(x), ([0, 1, 2], [0, 1, 2]))
+
+        x = np.array([[(0, 1), (0, 0), (1, 11)],
+                   [(1, 1), (1, 0), (0, 0)],
+                   [(0, 0), (1, 5), (0, 1)]], dtype=[('a', 'f4'), ('b', 'u1')])
+        assert_equal(np.count_nonzero(x['a']), 4)
+        assert_equal(np.count_nonzero(x['b']), 5)
+        assert_equal(np.nonzero(x['a']), ([0, 1, 1, 2], [2, 0, 1, 1]))
+        assert_equal(np.nonzero(x['b']), ([0, 0, 1, 2, 2], [0, 2, 0, 1, 2]))
+
+        assert_(not x['a'].T.flags.aligned)
+        assert_equal(np.count_nonzero(x['a'].T), 4)
+        assert_equal(np.count_nonzero(x['b'].T), 5)
+        assert_equal(np.nonzero(x['a'].T), ([0, 1, 1, 2], [1, 1, 2, 0]))
+        assert_equal(np.nonzero(x['b'].T), ([0, 0, 1, 2, 2], [0, 1, 2, 0, 2]))
+
+    def test_sparse(self):
+        # test special sparse condition boolean code path
+        for i in range(20):
+            c = np.zeros(200, dtype=np.bool)
+            c[i::20] = True
+            assert_equal(np.nonzero(c)[0], np.arange(i, 200 + i, 20))
+
+            c = np.zeros(400, dtype=np.bool)
+            c[10 + i:20 + i] = True
+            c[20 + i*2] = True
+            assert_equal(np.nonzero(c)[0],
+                         np.concatenate((np.arange(10 + i, 20 + i), [20 + i*2])))
+
+    def test_return_type(self):
+        class C(np.ndarray):
+            pass
+
+        for view in (C, np.ndarray):
+            for nd in range(1, 4):
+                shape = tuple(range(2, 2+nd))
+                x = np.arange(np.prod(shape)).reshape(shape).view(view)
+                for nzx in (np.nonzero(x), x.nonzero()):
+                    for nzx_i in nzx:
+                        assert_(type(nzx_i) is np.ndarray)
+                        assert_(nzx_i.flags.writeable)
+
+    # Tests that the array method
+    # call works
+    def test_array_method(self):
+        m = np.array([[1, 0, 0], [4, 0, 6]])
+        tgt = [[0, 1, 1], [0, 0, 2]]
+
+        assert_equal(m.nonzero(), tgt)
+
+
+class TestIndex(TestCase):
+    def test_boolean(self):
+        a = rand(3, 5, 8)
+        V = rand(5, 8)
+        g1 = randint(0, 5, size=15)
+        g2 = randint(0, 8, size=15)
+        V[g1, g2] = -V[g1, g2]
+        assert_((np.array([a[0][V > 0], a[1][V > 0], a[2][V > 0]]) == a[:, V > 0]).all())
+
+    def test_boolean_edgecase(self):
+        a = np.array([], dtype='int32')
+        b = np.array([], dtype='bool')
+        c = a[b]
+        assert_equal(c, [])
+        assert_equal(c.dtype, np.dtype('int32'))
+
+
+class TestBinaryRepr(TestCase):
+    def test_zero(self):
+        assert_equal(np.binary_repr(0), '0')
+
+    def test_large(self):
+        assert_equal(np.binary_repr(10736848), '101000111101010011010000')
+
+    def test_negative(self):
+        assert_equal(np.binary_repr(-1), '-1')
+        assert_equal(np.binary_repr(-1, width=8), '11111111')
+
+
+class TestBaseRepr(TestCase):
+    def test_base3(self):
+        assert_equal(np.base_repr(3**5, 3), '100000')
+
+    def test_positive(self):
+        assert_equal(np.base_repr(12, 10), '12')
+        assert_equal(np.base_repr(12, 10, 4), '000012')
+        assert_equal(np.base_repr(12, 4), '30')
+        assert_equal(np.base_repr(3731624803700888, 36), '10QR0ROFCEW')
+
+    def test_negative(self):
+        assert_equal(np.base_repr(-12, 10), '-12')
+        assert_equal(np.base_repr(-12, 10, 4), '-000012')
+        assert_equal(np.base_repr(-12, 4), '-30')
+
+
+class TestArrayComparisons(TestCase):
+    def test_array_equal(self):
+        res = np.array_equal(np.array([1, 2]), np.array([1, 2]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([1, 2, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([3, 4]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([1, 2]), np.array([1, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array(['a'], dtype='S1'), np.array(['a'], dtype='S1'))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equal(np.array([('a', 1)], dtype='S1,u4'),
+                             np.array([('a', 1)], dtype='S1,u4'))
+        assert_(res)
+        assert_(type(res) is bool)
+
+    def test_array_equiv(self):
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 2]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 2, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([3, 4]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([1, 3]))
+        assert_(not res)
+        assert_(type(res) is bool)
+
+        res = np.array_equiv(np.array([1, 1]), np.array([1]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 1]), np.array([[1], [1]]))
+        assert_(res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([2]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([[1], [2]]))
+        assert_(not res)
+        assert_(type(res) is bool)
+        res = np.array_equiv(np.array([1, 2]), np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
+        assert_(not res)
+        assert_(type(res) is bool)
+
+
+def assert_array_strict_equal(x, y):
+    assert_array_equal(x, y)
+    # Check flags, 32 bit arches typically don't provide 16 byte alignment
+    if ((x.dtype.alignment <= 8 or
+            np.intp().dtype.itemsize != 4) and
+            sys.platform != 'win32'):
+        assert_(x.flags == y.flags)
+    else:
+        assert_(x.flags.owndata == y.flags.owndata)
+        assert_(x.flags.writeable == y.flags.writeable)
+        assert_(x.flags.c_contiguous == y.flags.c_contiguous)
+        assert_(x.flags.f_contiguous == y.flags.f_contiguous)
+        assert_(x.flags.updateifcopy == y.flags.updateifcopy)
+    # check endianness
+    assert_(x.dtype.isnative == y.dtype.isnative)
+
+
+class TestClip(TestCase):
+    def setUp(self):
+        self.nr = 5
+        self.nc = 3
+
+    def fastclip(self, a, m, M, out=None):
+        if out is None:
+            return a.clip(m, M)
+        else:
+            return a.clip(m, M, out)
+
+    def clip(self, a, m, M, out=None):
+        # use slow-clip
+        selector = np.less(a, m) + 2*np.greater(a, M)
+        return selector.choose((a, m, M), out=out)
+
+    # Handy functions
+    def _generate_data(self, n, m):
+        return randn(n, m)
+
+    def _generate_data_complex(self, n, m):
+        return randn(n, m) + 1.j * rand(n, m)
+
+    def _generate_flt_data(self, n, m):
+        return (randn(n, m)).astype(np.float32)
+
+    def _neg_byteorder(self, a):
+        a = np.asarray(a)
+        if sys.byteorder == 'little':
+            a = a.astype(a.dtype.newbyteorder('>'))
+        else:
+            a = a.astype(a.dtype.newbyteorder('<'))
+        return a
+
+    def _generate_non_native_data(self, n, m):
+        data = randn(n, m)
+        data = self._neg_byteorder(data)
+        assert_(not data.dtype.isnative)
+        return data
+
+    def _generate_int_data(self, n, m):
+        return (10 * rand(n, m)).astype(np.int64)
+
+    def _generate_int32_data(self, n, m):
+        return (10 * rand(n, m)).astype(np.int32)
+
+    # Now the real test cases
+    def test_simple_double(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = 0.1
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int(self):
+        # Test native int input with scalar min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        a = a.astype(int)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_array_double(self):
+        # Test native double input with array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = np.zeros(a.shape)
+        M = m + 0.5
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_nonnative(self):
+        # Test non native double input with scalar min/max.
+        # Test native double input with non native double scalar min/max.
+        a = self._generate_non_native_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_equal(ac, act)
+
+        # Test native double input with non native double scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = self._neg_byteorder(0.6)
+        assert_(not M.dtype.isnative)
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_equal(ac, act)
+
+    def test_simple_complex(self):
+        # Test native complex input with native double scalar min/max.
+        # Test native input with complex double scalar min/max.
+        a = 3 * self._generate_data_complex(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+        # Test native input with complex double scalar min/max.
+        a = 3 * self._generate_data(self.nr, self.nc)
+        m = -0.5 + 1.j
+        M = 1. + 2.j
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_complex(self):
+        # Address Issue gh-5354 for clipping complex arrays
+        # Test native complex input without explicit min/max
+        # ie, either min=None or max=None
+        a = np.ones(10, dtype=np.complex)
+        m = a.min()
+        M = a.max()
+        am = self.fastclip(a, m, None)
+        aM = self.fastclip(a, None, M)
+        assert_array_strict_equal(am, a)
+        assert_array_strict_equal(aM, a)
+
+    def test_clip_non_contig(self):
+        # Test clip for non contiguous native input and native scalar min/max.
+        a = self._generate_data(self.nr * 2, self.nc * 3)
+        a = a[::2, ::3]
+        assert_(not a.flags['F_CONTIGUOUS'])
+        assert_(not a.flags['C_CONTIGUOUS'])
+        ac = self.fastclip(a, -1.6, 1.7)
+        act = self.clip(a, -1.6, 1.7)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_out(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = np.zeros(a.shape)
+        act = np.zeros(a.shape)
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int32_inout(self):
+        # Test native int32 input with double min/max and int32 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float64(0)
+        M = np.float64(2)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int64_out(self):
+        # Test native int32 input with int32 scalar min/max and int64 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.int32(-1)
+        M = np.int32(1)
+        ac = np.zeros(a.shape, dtype=np.int64)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int64_inout(self):
+        # Test native int32 input with double array min/max and int32 out.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.zeros(a.shape, np.float64)
+        M = np.float64(1)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_int32_out(self):
+        # Test native double input with scalar min/max and int out.
+        a = self._generate_data(self.nr, self.nc)
+        m = -1.0
+        M = 2.0
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_simple_inplace_01(self):
+        # Test native double input with array min/max in-place.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = np.zeros(a.shape)
+        M = 1.0
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_simple_inplace_02(self):
+        # Test native double input with scalar min/max in-place.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_noncontig_inplace(self):
+        # Test non contiguous double input with double scalar min/max in-place.
+        a = self._generate_data(self.nr * 2, self.nc * 3)
+        a = a[::2, ::3]
+        assert_(not a.flags['F_CONTIGUOUS'])
+        assert_(not a.flags['C_CONTIGUOUS'])
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_equal(a, ac)
+
+    def test_type_cast_01(self):
+        # Test native double input with scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_02(self):
+        # Test native int32 input with int32 scalar min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        a = a.astype(np.int32)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, m, M)
+        act = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_03(self):
+        # Test native int32 input with float64 scalar min/max.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = -2
+        M = 4
+        ac = self.fastclip(a, np.float64(m), np.float64(M))
+        act = self.clip(a, np.float64(m), np.float64(M))
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_04(self):
+        # Test native int32 input with float32 scalar min/max.
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float32(-2)
+        M = np.float32(4)
+        act = self.fastclip(a, m, M)
+        ac = self.clip(a, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_05(self):
+        # Test native int32 with double arrays min/max.
+        a = self._generate_int_data(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        ac = self.fastclip(a, m * np.zeros(a.shape), M)
+        act = self.clip(a, m * np.zeros(a.shape), M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_06(self):
+        # Test native with NON native scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = 0.5
+        m_s = self._neg_byteorder(m)
+        M = 1.
+        act = self.clip(a, m_s, M)
+        ac = self.fastclip(a, m_s, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_07(self):
+        # Test NON native with native array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5 * np.ones(a.shape)
+        M = 1.
+        a_s = self._neg_byteorder(a)
+        assert_(not a_s.dtype.isnative)
+        act = a_s.clip(m, M)
+        ac = self.fastclip(a_s, m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_08(self):
+        # Test NON native with native scalar min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 1.
+        a_s = self._neg_byteorder(a)
+        assert_(not a_s.dtype.isnative)
+        ac = self.fastclip(a_s, m, M)
+        act = a_s.clip(m, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_09(self):
+        # Test native with NON native array min/max.
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5 * np.ones(a.shape)
+        M = 1.
+        m_s = self._neg_byteorder(m)
+        assert_(not m_s.dtype.isnative)
+        ac = self.fastclip(a, m_s, M)
+        act = self.clip(a, m_s, M)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_10(self):
+        # Test native int32 with float min/max and float out for output argument.
+        a = self._generate_int_data(self.nr, self.nc)
+        b = np.zeros(a.shape, dtype=np.float32)
+        m = np.float32(-0.5)
+        M = np.float32(1)
+        act = self.clip(a, m, M, out=b)
+        ac = self.fastclip(a, m, M, out=b)
+        assert_array_strict_equal(ac, act)
+
+    def test_type_cast_11(self):
+        # Test non native with native scalar, min/max, out non native
+        a = self._generate_non_native_data(self.nr, self.nc)
+        b = a.copy()
+        b = b.astype(b.dtype.newbyteorder('>'))
+        bt = b.copy()
+        m = -0.5
+        M = 1.
+        self.fastclip(a, m, M, out=b)
+        self.clip(a, m, M, out=bt)
+        assert_array_strict_equal(b, bt)
+
+    def test_type_cast_12(self):
+        # Test native int32 input and min/max and float out
+        a = self._generate_int_data(self.nr, self.nc)
+        b = np.zeros(a.shape, dtype=np.float32)
+        m = np.int32(0)
+        M = np.int32(1)
+        act = self.clip(a, m, M, out=b)
+        ac = self.fastclip(a, m, M, out=b)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple(self):
+        # Test native double input with scalar min/max
+        a = self._generate_data(self.nr, self.nc)
+        m = -0.5
+        M = 0.6
+        ac = np.zeros(a.shape)
+        act = np.zeros(a.shape)
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple2(self):
+        # Test native int32 input with double min/max and int32 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.float64(0)
+        M = np.float64(2)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_simple_int32(self):
+        # Test native int32 input with int32 scalar min/max and int64 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.int32(-1)
+        M = np.int32(1)
+        ac = np.zeros(a.shape, dtype=np.int64)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_array_int32(self):
+        # Test native int32 input with double array min/max and int32 out
+        a = self._generate_int32_data(self.nr, self.nc)
+        m = np.zeros(a.shape, np.float64)
+        M = np.float64(1)
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_with_out_array_outint32(self):
+        # Test native double input with scalar min/max and int out
+        a = self._generate_data(self.nr, self.nc)
+        m = -1.0
+        M = 2.0
+        ac = np.zeros(a.shape, dtype=np.int32)
+        act = ac.copy()
+        self.fastclip(a, m, M, ac)
+        self.clip(a, m, M, act)
+        assert_array_strict_equal(ac, act)
+
+    def test_clip_inplace_array(self):
+        # Test native double input with array min/max
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = np.zeros(a.shape)
+        M = 1.0
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_clip_inplace_simple(self):
+        # Test native double input with scalar min/max
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        self.fastclip(a, m, M, a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a, ac)
+
+    def test_clip_func_takes_out(self):
+        # Ensure that the clip() function takes an out=argument.
+        a = self._generate_data(self.nr, self.nc)
+        ac = a.copy()
+        m = -0.5
+        M = 0.6
+        a2 = np.clip(a, m, M, out=a)
+        self.clip(a, m, M, ac)
+        assert_array_strict_equal(a2, ac)
+        self.assertTrue(a2 is a)
+
+    def test_clip_nan(self):
+        d = np.arange(7.)
+        assert_equal(d.clip(min=np.nan), d)
+        assert_equal(d.clip(max=np.nan), d)
+        assert_equal(d.clip(min=np.nan, max=np.nan), d)
+        assert_equal(d.clip(min=-2, max=np.nan), d)
+        assert_equal(d.clip(min=np.nan, max=10), d)
+
+
+class TestAllclose(object):
+    rtol = 1e-5
+    atol = 1e-8
+
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def tst_allclose(self, x, y):
+        assert_(np.allclose(x, y), "%s and %s not close" % (x, y))
+
+    def tst_not_allclose(self, x, y):
+        assert_(not np.allclose(x, y), "%s and %s shouldn't be close" % (x, y))
+
+    def test_ip_allclose(self):
+        # Parametric test factory.
+        arr = np.array([100, 1000])
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        atol = self.atol
+        rtol = self.rtol
+
+        data = [([1, 0], [1, 0]),
+                ([atol], [0]),
+                ([1], [1+rtol+atol]),
+                (arr, arr + arr*rtol),
+                (arr, arr + arr*rtol + atol*2),
+                (aran, aran + aran*rtol),
+                (np.inf, np.inf),
+                (np.inf, [np.inf])]
+
+        for (x, y) in data:
+            yield (self.tst_allclose, x, y)
+
+    def test_ip_not_allclose(self):
+        # Parametric test factory.
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        atol = self.atol
+        rtol = self.rtol
+
+        data = [([np.inf, 0], [1, np.inf]),
+                ([np.inf, 0], [1, 0]),
+                ([np.inf, np.inf], [1, np.inf]),
+                ([np.inf, np.inf], [1, 0]),
+                ([-np.inf, 0], [np.inf, 0]),
+                ([np.nan, 0], [np.nan, 0]),
+                ([atol*2], [0]),
+                ([1], [1+rtol+atol*2]),
+                (aran, aran + aran*atol + atol*2),
+                (np.array([np.inf, 1]), np.array([0, np.inf]))]
+
+        for (x, y) in data:
+            yield (self.tst_not_allclose, x, y)
+
+    def test_no_parameter_modification(self):
+        x = np.array([np.inf, 1])
+        y = np.array([0, np.inf])
+        np.allclose(x, y)
+        assert_array_equal(x, np.array([np.inf, 1]))
+        assert_array_equal(y, np.array([0, np.inf]))
+
+    def test_min_int(self):
+        # Could make problems because of abs(min_int) == min_int
+        min_int = np.iinfo(np.int_).min
+        a = np.array([min_int], dtype=np.int_)
+        assert_(np.allclose(a, a))
+
+    def test_equalnan(self):
+        x = np.array([1.0, np.nan])
+        assert_(np.allclose(x, x, equal_nan=True))
+
+    def test_return_class_is_ndarray(self):
+        # Issue gh-6475
+        # Check that allclose does not preserve subtypes
+        class Foo(np.ndarray):
+            def __new__(cls, *args, **kwargs):
+                return np.array(*args, **kwargs).view(cls)
+
+        a = Foo([1])
+        assert_(type(np.allclose(a, a)) is bool)
+
+
+class TestIsclose(object):
+    rtol = 1e-5
+    atol = 1e-8
+
+    def setup(self):
+        atol = self.atol
+        rtol = self.rtol
+        arr = np.array([100, 1000])
+        aran = np.arange(125).reshape((5, 5, 5))
+
+        self.all_close_tests = [
+                ([1, 0], [1, 0]),
+                ([atol], [0]),
+                ([1], [1 + rtol + atol]),
+                (arr, arr + arr*rtol),
+                (arr, arr + arr*rtol + atol),
+                (aran, aran + aran*rtol),
+                (np.inf, np.inf),
+                (np.inf, [np.inf]),
+                ([np.inf, -np.inf], [np.inf, -np.inf]),
+                ]
+        self.none_close_tests = [
+                ([np.inf, 0], [1, np.inf]),
+                ([np.inf, -np.inf], [1, 0]),
+                ([np.inf, np.inf], [1, -np.inf]),
+                ([np.inf, np.inf], [1, 0]),
+                ([np.nan, 0], [np.nan, -np.inf]),
+                ([atol*2], [0]),
+                ([1], [1 + rtol + atol*2]),
+                (aran, aran + rtol*1.1*aran + atol*1.1),
+                (np.array([np.inf, 1]), np.array([0, np.inf])),
+                ]
+        self.some_close_tests = [
+                ([np.inf, 0], [np.inf, atol*2]),
+                ([atol, 1, 1e6*(1 + 2*rtol) + atol], [0, np.nan, 1e6]),
+                (np.arange(3), [0, 1, 2.1]),
+                (np.nan, [np.nan, np.nan, np.nan]),
+                ([0], [atol, np.inf, -np.inf, np.nan]),
+                (0, [atol, np.inf, -np.inf, np.nan]),
+                ]
+        self.some_close_results = [
+                [True, False],
+                [True, False, False],
+                [True, True, False],
+                [False, False, False],
+                [True, False, False, False],
+                [True, False, False, False],
+                ]
+
+    def test_ip_isclose(self):
+        self.setup()
+        tests = self.some_close_tests
+        results = self.some_close_results
+        for (x, y), result in zip(tests, results):
+            yield (assert_array_equal, np.isclose(x, y), result)
+
+    def tst_all_isclose(self, x, y):
+        assert_(np.all(np.isclose(x, y)), "%s and %s not close" % (x, y))
+
+    def tst_none_isclose(self, x, y):
+        msg = "%s and %s shouldn't be close"
+        assert_(not np.any(np.isclose(x, y)), msg % (x, y))
+
+    def tst_isclose_allclose(self, x, y):
+        msg = "isclose.all() and allclose aren't same for %s and %s"
+        msg2 = "isclose and allclose aren't same for %s and %s"
+        if np.isscalar(x) and np.isscalar(y):
+            assert_(np.isclose(x, y) == np.allclose(x, y), msg=msg2 % (x, y))
+        else:
+            assert_array_equal(np.isclose(x, y).all(), np.allclose(x, y), msg % (x, y))
+
+    def test_ip_all_isclose(self):
+        self.setup()
+        for (x, y) in self.all_close_tests:
+            yield (self.tst_all_isclose, x, y)
+
+    def test_ip_none_isclose(self):
+        self.setup()
+        for (x, y) in self.none_close_tests:
+            yield (self.tst_none_isclose, x, y)
+
+    def test_ip_isclose_allclose(self):
+        self.setup()
+        tests = (self.all_close_tests + self.none_close_tests +
+                 self.some_close_tests)
+        for (x, y) in tests:
+            yield (self.tst_isclose_allclose, x, y)
+
+    def test_equal_nan(self):
+        assert_array_equal(np.isclose(np.nan, np.nan, equal_nan=True), [True])
+        arr = np.array([1.0, np.nan])
+        assert_array_equal(np.isclose(arr, arr, equal_nan=True), [True, True])
+
+    def test_masked_arrays(self):
+        # Make sure to test the output type when arguments are interchanged.
+
+        x = np.ma.masked_where([True, True, False], np.arange(3))
+        assert_(type(x) is type(np.isclose(2, x)))
+        assert_(type(x) is type(np.isclose(x, 2)))
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.inf, np.nan])
+        assert_(type(x) is type(np.isclose(np.inf, x)))
+        assert_(type(x) is type(np.isclose(x, np.inf)))
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan])
+        y = np.isclose(np.nan, x, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+        y = np.isclose(x, np.nan, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+
+        x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan])
+        y = np.isclose(x, x, equal_nan=True)
+        assert_(type(x) is type(y))
+        # Ensure that the mask isn't modified...
+        assert_array_equal([True, True, False], y.mask)
+
+    def test_scalar_return(self):
+        assert_(np.isscalar(np.isclose(1, 1)))
+
+    def test_no_parameter_modification(self):
+        x = np.array([np.inf, 1])
+        y = np.array([0, np.inf])
+        np.isclose(x, y)
+        assert_array_equal(x, np.array([np.inf, 1]))
+        assert_array_equal(y, np.array([0, np.inf]))
+
+    def test_non_finite_scalar(self):
+        # GH7014, when two scalars are compared the output should also be a
+        # scalar
+        assert_(np.isclose(np.inf, -np.inf) is False)
+        assert_(np.isclose(0, np.inf) is False)
+        assert_(type(np.isclose(0, np.inf)) is bool)
+
+
+class TestStdVar(TestCase):
+    def setUp(self):
+        self.A = np.array([1, -1, 1, -1])
+        self.real_var = 1
+
+    def test_basic(self):
+        assert_almost_equal(np.var(self.A), self.real_var)
+        assert_almost_equal(np.std(self.A)**2, self.real_var)
+
+    def test_scalars(self):
+        assert_equal(np.var(1), 0)
+        assert_equal(np.std(1), 0)
+
+    def test_ddof1(self):
+        assert_almost_equal(np.var(self.A, ddof=1),
+                            self.real_var*len(self.A)/float(len(self.A)-1))
+        assert_almost_equal(np.std(self.A, ddof=1)**2,
+                            self.real_var*len(self.A)/float(len(self.A)-1))
+
+    def test_ddof2(self):
+        assert_almost_equal(np.var(self.A, ddof=2),
+                            self.real_var*len(self.A)/float(len(self.A)-2))
+        assert_almost_equal(np.std(self.A, ddof=2)**2,
+                            self.real_var*len(self.A)/float(len(self.A)-2))
+
+    def test_out_scalar(self):
+        d = np.arange(10)
+        out = np.array(0.)
+        r = np.std(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+        r = np.var(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+        r = np.mean(d, out=out)
+        assert_(r is out)
+        assert_array_equal(r, out)
+
+
+class TestStdVarComplex(TestCase):
+    def test_basic(self):
+        A = np.array([1, 1.j, -1, -1.j])
+        real_var = 1
+        assert_almost_equal(np.var(A), real_var)
+        assert_almost_equal(np.std(A)**2, real_var)
+
+    def test_scalars(self):
+        assert_equal(np.var(1j), 0)
+        assert_equal(np.std(1j), 0)
+
+
+class TestCreationFuncs(TestCase):
+    # Test ones, zeros, empty and filled
+
+    def setUp(self):
+        self.dtypes = ('b', 'i', 'u', 'f', 'c', 'S', 'a', 'U', 'V')
+        self.orders = {'C': 'c_contiguous', 'F': 'f_contiguous'}
+        self.ndims = 10
+
+    def check_function(self, func, fill_value=None):
+        par = (
+            (0, 1, 2),
+            range(self.ndims),
+            self.orders,
+            self.dtypes,
+            2**np.arange(9)
+        )
+        fill_kwarg = {}
+        if fill_value is not None:
+            fill_kwarg = {'fill_value': fill_value}
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', DeprecationWarning)
+            for size, ndims, order, type, bytes in itertools.product(*par):
+                shape = ndims * [size]
+                try:
+                    dtype = np.dtype('{0}{1}'.format(type, bytes))
+                except TypeError:  # dtype combination does not exist
+                    continue
+                else:
+                    # do not fill void type
+                    if fill_value is not None and type in 'V':
+                        continue
+
+                    arr = func(shape, order=order, dtype=dtype,
+                               **fill_kwarg)
+
+                    assert_(arr.dtype == dtype)
+                    assert_(getattr(arr.flags, self.orders[order]))
+
+                    if fill_value is not None:
+                        if dtype.str.startswith('|S'):
+                            val = str(fill_value)
+                        else:
+                            val = fill_value
+                        assert_equal(arr, dtype.type(val))
+
+    def test_zeros(self):
+        self.check_function(np.zeros)
+
+    def test_ones(self):
+        self.check_function(np.zeros)
+
+    def test_empty(self):
+        self.check_function(np.empty)
+
+    def test_filled(self):
+        self.check_function(np.full, 0)
+        self.check_function(np.full, 1)
+
+    def test_for_reference_leak(self):
+        # Make sure we have an object for reference
+        dim = 1
+        beg = sys.getrefcount(dim)
+        np.zeros([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.ones([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.empty([dim]*10)
+        assert_(sys.getrefcount(dim) == beg)
+        np.full([dim]*10, 0)
+        assert_(sys.getrefcount(dim) == beg)
+
+
+class TestLikeFuncs(TestCase):
+    '''Test ones_like, zeros_like, empty_like and full_like'''
+
+    def setUp(self):
+        self.data = [
+                # Array scalars
+                (np.array(3.), None),
+                (np.array(3), 'f8'),
+                # 1D arrays
+                (np.arange(6, dtype='f4'), None),
+                (np.arange(6), 'c16'),
+                # 2D C-layout arrays
+                (np.arange(6).reshape(2, 3), None),
+                (np.arange(6).reshape(3, 2), 'i1'),
+                # 2D F-layout arrays
+                (np.arange(6).reshape((2, 3), order='F'), None),
+                (np.arange(6).reshape((3, 2), order='F'), 'i1'),
+                # 3D C-layout arrays
+                (np.arange(24).reshape(2, 3, 4), None),
+                (np.arange(24).reshape(4, 3, 2), 'f4'),
+                # 3D F-layout arrays
+                (np.arange(24).reshape((2, 3, 4), order='F'), None),
+                (np.arange(24).reshape((4, 3, 2), order='F'), 'f4'),
+                # 3D non-C/F-layout arrays
+                (np.arange(24).reshape(2, 3, 4).swapaxes(0, 1), None),
+                (np.arange(24).reshape(4, 3, 2).swapaxes(0, 1), '?'),
+                     ]
+
+    def compare_array_value(self, dz, value, fill_value):
+        if value is not None:
+            if fill_value:
+                try:
+                    z = dz.dtype.type(value)
+                except OverflowError:
+                    pass
+                else:
+                    assert_(np.all(dz == z))
+            else:
+                assert_(np.all(dz == value))
+
+    def check_like_function(self, like_function, value, fill_value=False):
+        if fill_value:
+            fill_kwarg = {'fill_value': value}
+        else:
+            fill_kwarg = {}
+        for d, dtype in self.data:
+            # default (K) order, dtype
+            dz = like_function(d, dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_equal(np.array(dz.strides)*d.dtype.itemsize,
+                         np.array(d.strides)*dz.dtype.itemsize)
+            assert_equal(d.flags.c_contiguous, dz.flags.c_contiguous)
+            assert_equal(d.flags.f_contiguous, dz.flags.f_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # C order, default dtype
+            dz = like_function(d, order='C', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_(dz.flags.c_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # F order, default dtype
+            dz = like_function(d, order='F', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            assert_(dz.flags.f_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+            # A order
+            dz = like_function(d, order='A', dtype=dtype, **fill_kwarg)
+            assert_equal(dz.shape, d.shape)
+            if d.flags.f_contiguous:
+                assert_(dz.flags.f_contiguous)
+            else:
+                assert_(dz.flags.c_contiguous)
+            if dtype is None:
+                assert_equal(dz.dtype, d.dtype)
+            else:
+                assert_equal(dz.dtype, np.dtype(dtype))
+            self.compare_array_value(dz, value, fill_value)
+
+        # Test the 'subok' parameter
+        a = np.matrix([[1, 2], [3, 4]])
+
+        b = like_function(a, **fill_kwarg)
+        assert_(type(b) is np.matrix)
+
+        b = like_function(a, subok=False, **fill_kwarg)
+        assert_(type(b) is not np.matrix)
+
+    def test_ones_like(self):
+        self.check_like_function(np.ones_like, 1)
+
+    def test_zeros_like(self):
+        self.check_like_function(np.zeros_like, 0)
+
+    def test_empty_like(self):
+        self.check_like_function(np.empty_like, None)
+
+    def test_filled_like(self):
+        self.check_like_function(np.full_like, 0, True)
+        self.check_like_function(np.full_like, 1, True)
+        self.check_like_function(np.full_like, 1000, True)
+        self.check_like_function(np.full_like, 123.456, True)
+        self.check_like_function(np.full_like, np.inf, True)
+
+
+class TestCorrelate(TestCase):
+    def _setup(self, dt):
+        self.x = np.array([1, 2, 3, 4, 5], dtype=dt)
+        self.xs = np.arange(1, 20)[::3]
+        self.y = np.array([-1, -2, -3], dtype=dt)
+        self.z1 = np.array([ -3.,  -8., -14., -20., -26., -14.,  -5.], dtype=dt)
+        self.z1_4 = np.array([-2., -5., -8., -11., -14., -5.], dtype=dt)
+        self.z1r = np.array([-15., -22., -22., -16., -10.,  -4.,  -1.], dtype=dt)
+        self.z2 = np.array([-5., -14., -26., -20., -14., -8.,  -3.], dtype=dt)
+        self.z2r = np.array([-1., -4., -10., -16., -22., -22., -15.], dtype=dt)
+        self.zs = np.array([-3., -14., -30., -48., -66., -84.,
+                           -102., -54., -19.], dtype=dt)
+
+    def test_float(self):
+        self._setup(np.float)
+        z = np.correlate(self.x, self.y, 'full')
+        assert_array_almost_equal(z, self.z1)
+        z = np.correlate(self.x, self.y[:-1], 'full')
+        assert_array_almost_equal(z, self.z1_4)
+        z = np.correlate(self.y, self.x, 'full')
+        assert_array_almost_equal(z, self.z2)
+        z = np.correlate(self.x[::-1], self.y, 'full')
+        assert_array_almost_equal(z, self.z1r)
+        z = np.correlate(self.y, self.x[::-1], 'full')
+        assert_array_almost_equal(z, self.z2r)
+        z = np.correlate(self.xs, self.y, 'full')
+        assert_array_almost_equal(z, self.zs)
+
+    def test_object(self):
+        self._setup(Decimal)
+        z = np.correlate(self.x, self.y, 'full')
+        assert_array_almost_equal(z, self.z1)
+        z = np.correlate(self.y, self.x, 'full')
+        assert_array_almost_equal(z, self.z2)
+
+    def test_no_overwrite(self):
+        d = np.ones(100)
+        k = np.ones(3)
+        np.correlate(d, k)
+        assert_array_equal(d, np.ones(100))
+        assert_array_equal(k, np.ones(3))
+
+    def test_complex(self):
+        x = np.array([1, 2, 3, 4+1j], dtype=np.complex)
+        y = np.array([-1, -2j, 3+1j], dtype=np.complex)
+        r_z = np.array([3-1j, 6, 8+1j, 11+5j, -5+8j, -4-1j], dtype=np.complex)
+        r_z = r_z[::-1].conjugate()
+        z = np.correlate(y, x, mode='full')
+        assert_array_almost_equal(z, r_z)
+
+
+class TestConvolve(TestCase):
+    def test_object(self):
+        d = [1.] * 100
+        k = [1.] * 3
+        assert_array_almost_equal(np.convolve(d, k)[2:-2], np.full(98, 3))
+
+    def test_no_overwrite(self):
+        d = np.ones(100)
+        k = np.ones(3)
+        np.convolve(d, k)
+        assert_array_equal(d, np.ones(100))
+        assert_array_equal(k, np.ones(3))
+
+
+class TestArgwhere(object):
+    def test_2D(self):
+        x = np.arange(6).reshape((2, 3))
+        assert_array_equal(np.argwhere(x > 1),
+                           [[0, 2],
+                            [1, 0],
+                            [1, 1],
+                            [1, 2]])
+
+    def test_list(self):
+        assert_equal(np.argwhere([4, 0, 2, 1, 3]), [[0], [2], [3], [4]])
+
+
+class TestStringFunction(object):
+
+    def test_set_string_function(self):
+        a = np.array([1])
+        np.set_string_function(lambda x: "FOO", repr=True)
+        assert_equal(repr(a), "FOO")
+        np.set_string_function(None, repr=True)
+        assert_equal(repr(a), "array([1])")
+
+        np.set_string_function(lambda x: "FOO", repr=False)
+        assert_equal(str(a), "FOO")
+        np.set_string_function(None, repr=False)
+        assert_equal(str(a), "[1]")
+
+
+class TestRoll(TestCase):
+    def test_roll1d(self):
+        x = np.arange(10)
+        xr = np.roll(x, 2)
+        assert_equal(xr, np.array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7]))
+
+    def test_roll2d(self):
+        x2 = np.reshape(np.arange(10), (2, 5))
+        x2r = np.roll(x2, 1)
+        assert_equal(x2r, np.array([[9, 0, 1, 2, 3], [4, 5, 6, 7, 8]]))
+
+        x2r = np.roll(x2, 1, axis=0)
+        assert_equal(x2r, np.array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]]))
+
+        x2r = np.roll(x2, 1, axis=1)
+        assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]]))
+
+    def test_roll_empty(self):
+        x = np.array([])
+        assert_equal(np.roll(x, 1), np.array([]))
+
+
+class TestRollaxis(TestCase):
+
+    # expected shape indexed by (axis, start) for array of
+    # shape (1, 2, 3, 4)
+    tgtshape = {(0, 0): (1, 2, 3, 4), (0, 1): (1, 2, 3, 4),
+                (0, 2): (2, 1, 3, 4), (0, 3): (2, 3, 1, 4),
+                (0, 4): (2, 3, 4, 1),
+                (1, 0): (2, 1, 3, 4), (1, 1): (1, 2, 3, 4),
+                (1, 2): (1, 2, 3, 4), (1, 3): (1, 3, 2, 4),
+                (1, 4): (1, 3, 4, 2),
+                (2, 0): (3, 1, 2, 4), (2, 1): (1, 3, 2, 4),
+                (2, 2): (1, 2, 3, 4), (2, 3): (1, 2, 3, 4),
+                (2, 4): (1, 2, 4, 3),
+                (3, 0): (4, 1, 2, 3), (3, 1): (1, 4, 2, 3),
+                (3, 2): (1, 2, 4, 3), (3, 3): (1, 2, 3, 4),
+                (3, 4): (1, 2, 3, 4)}
+
+    def test_exceptions(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4)
+        assert_raises(ValueError, np.rollaxis, a, -5, 0)
+        assert_raises(ValueError, np.rollaxis, a, 0, -5)
+        assert_raises(ValueError, np.rollaxis, a, 4, 0)
+        assert_raises(ValueError, np.rollaxis, a, 0, 5)
+
+    def test_results(self):
+        a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
+        aind = np.indices(a.shape)
+        assert_(a.flags['OWNDATA'])
+        for (i, j) in self.tgtshape:
+            # positive axis, positive start
+            res = np.rollaxis(a, axis=i, start=j)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(i, j)], str((i,j)))
+            assert_(not res.flags['OWNDATA'])
+
+            # negative axis, positive start
+            ip = i + 1
+            res = np.rollaxis(a, axis=-ip, start=j)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(4 - ip, j)])
+            assert_(not res.flags['OWNDATA'])
+
+            # positive axis, negative start
+            jp = j + 1 if j < 4 else j
+            res = np.rollaxis(a, axis=i, start=-jp)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(i, 4 - jp)])
+            assert_(not res.flags['OWNDATA'])
+
+            # negative axis, negative start
+            ip = i + 1
+            jp = j + 1 if j < 4 else j
+            res = np.rollaxis(a, axis=-ip, start=-jp)
+            i0, i1, i2, i3 = aind[np.array(res.shape) - 1]
+            assert_(np.all(res[i0, i1, i2, i3] == a))
+            assert_(res.shape == self.tgtshape[(4 - ip, 4 - jp)])
+            assert_(not res.flags['OWNDATA'])
+
+
+class TestMoveaxis(TestCase):
+    def test_move_to_end(self):
+        x = np.random.randn(5, 6, 7)
+        for source, expected in [(0, (6, 7, 5)),
+                                 (1, (5, 7, 6)),
+                                 (2, (5, 6, 7)),
+                                 (-1, (5, 6, 7))]:
+            actual = np.moveaxis(x, source, -1).shape
+            assert_(actual, expected)
+
+    def test_move_new_position(self):
+        x = np.random.randn(1, 2, 3, 4)
+        for source, destination, expected in [
+                (0, 1, (2, 1, 3, 4)),
+                (1, 2, (1, 3, 2, 4)),
+                (1, -1, (1, 3, 4, 2)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, expected)
+
+    def test_preserve_order(self):
+        x = np.zeros((1, 2, 3, 4))
+        for source, destination in [
+                (0, 0),
+                (3, -1),
+                (-1, 3),
+                ([0, -1], [0, -1]),
+                ([2, 0], [2, 0]),
+                (range(4), range(4)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, (1, 2, 3, 4))
+
+    def test_move_multiples(self):
+        x = np.zeros((0, 1, 2, 3))
+        for source, destination, expected in [
+                ([0, 1], [2, 3], (2, 3, 0, 1)),
+                ([2, 3], [0, 1], (2, 3, 0, 1)),
+                ([0, 1, 2], [2, 3, 0], (2, 3, 0, 1)),
+                ([3, 0], [1, 0], (0, 3, 1, 2)),
+                ([0, 3], [0, 1], (0, 3, 1, 2)),
+                ]:
+            actual = np.moveaxis(x, source, destination).shape
+            assert_(actual, expected)
+
+    def test_errors(self):
+        x = np.random.randn(1, 2, 3)
+        assert_raises_regex(ValueError, 'invalid axis .* `source`',
+                            np.moveaxis, x, 3, 0)
+        assert_raises_regex(ValueError, 'invalid axis .* `source`',
+                            np.moveaxis, x, -4, 0)
+        assert_raises_regex(ValueError, 'invalid axis .* `destination`',
+                            np.moveaxis, x, 0, 5)
+        assert_raises_regex(ValueError, 'repeated axis in `source`',
+                            np.moveaxis, x, [0, 0], [0, 1])
+        assert_raises_regex(ValueError, 'repeated axis in `destination`',
+                            np.moveaxis, x, [0, 1], [1, 1])
+        assert_raises_regex(ValueError, 'must have the same number',
+                            np.moveaxis, x, 0, [0, 1])
+        assert_raises_regex(ValueError, 'must have the same number',
+                            np.moveaxis, x, [0, 1], [0])
+
+    def test_array_likes(self):
+        x = np.ma.zeros((1, 2, 3))
+        result = np.moveaxis(x, 0, 0)
+        assert_(x.shape, result.shape)
+        assert_(isinstance(result, np.ma.MaskedArray))
+
+        x = [1, 2, 3]
+        result = np.moveaxis(x, 0, 0)
+        assert_(x, list(result))
+        assert_(isinstance(result, np.ndarray))
+
+
+class TestCross(TestCase):
+    def test_2x2(self):
+        u = [1, 2]
+        v = [3, 4]
+        z = -2
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_2x3(self):
+        u = [1, 2]
+        v = [3, 4, 5]
+        z = np.array([10, -5, -2])
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_3x3(self):
+        u = [1, 2, 3]
+        v = [4, 5, 6]
+        z = np.array([-3, 6, -3])
+        cp = np.cross(u, v)
+        assert_equal(cp, z)
+        cp = np.cross(v, u)
+        assert_equal(cp, -z)
+
+    def test_broadcasting(self):
+        # Ticket #2624 (Trac #2032)
+        u = np.tile([1, 2], (11, 1))
+        v = np.tile([3, 4], (11, 1))
+        z = -2
+        assert_equal(np.cross(u, v), z)
+        assert_equal(np.cross(v, u), -z)
+        assert_equal(np.cross(u, u), 0)
+
+        u = np.tile([1, 2], (11, 1)).T
+        v = np.tile([3, 4, 5], (11, 1))
+        z = np.tile([10, -5, -2], (11, 1))
+        assert_equal(np.cross(u, v, axisa=0), z)
+        assert_equal(np.cross(v, u.T), -z)
+        assert_equal(np.cross(v, v), 0)
+
+        u = np.tile([1, 2, 3], (11, 1)).T
+        v = np.tile([3, 4], (11, 1)).T
+        z = np.tile([-12, 9, -2], (11, 1))
+        assert_equal(np.cross(u, v, axisa=0, axisb=0), z)
+        assert_equal(np.cross(v.T, u.T), -z)
+        assert_equal(np.cross(u.T, u.T), 0)
+
+        u = np.tile([1, 2, 3], (5, 1))
+        v = np.tile([4, 5, 6], (5, 1)).T
+        z = np.tile([-3, 6, -3], (5, 1))
+        assert_equal(np.cross(u, v, axisb=0), z)
+        assert_equal(np.cross(v.T, u), -z)
+        assert_equal(np.cross(u, u), 0)
+
+    def test_broadcasting_shapes(self):
+        u = np.ones((2, 1, 3))
+        v = np.ones((5, 3))
+        assert_equal(np.cross(u, v).shape, (2, 5, 3))
+        u = np.ones((10, 3, 5))
+        v = np.ones((2, 5))
+        assert_equal(np.cross(u, v, axisa=1, axisb=0).shape, (10, 5, 3))
+        assert_raises(ValueError, np.cross, u, v, axisa=1, axisb=2)
+        assert_raises(ValueError, np.cross, u, v, axisa=3, axisb=0)
+        u = np.ones((10, 3, 5, 7))
+        v = np.ones((5, 7, 2))
+        assert_equal(np.cross(u, v, axisa=1, axisc=2).shape, (10, 5, 3, 7))
+        assert_raises(ValueError, np.cross, u, v, axisa=-5, axisb=2)
+        assert_raises(ValueError, np.cross, u, v, axisa=1, axisb=-4)
+        # gh-5885
+        u = np.ones((3, 4, 2))
+        for axisc in range(-2, 2):
+            assert_equal(np.cross(u, u, axisc=axisc).shape, (3, 4))
+
+
+def test_outer_out_param():
+    arr1 = np.ones((5,))
+    arr2 = np.ones((2,))
+    arr3 = np.linspace(-2, 2, 5)
+    out1 = np.ndarray(shape=(5,5))
+    out2 = np.ndarray(shape=(2, 5))
+    res1 = np.outer(arr1, arr3, out1)
+    assert_equal(res1, out1)
+    assert_equal(np.outer(arr2, arr3, out2), out2)
+
+
+class TestRequire(object):
+    flag_names = ['C', 'C_CONTIGUOUS', 'CONTIGUOUS',
+                  'F', 'F_CONTIGUOUS', 'FORTRAN',
+                  'A', 'ALIGNED',
+                  'W', 'WRITEABLE',
+                  'O', 'OWNDATA']
+
+    def generate_all_false(self, dtype):
+        arr = np.zeros((2, 2), [('junk', 'i1'), ('a', dtype)])
+        arr.setflags(write=False)
+        a = arr['a']
+        assert_(not a.flags['C'])
+        assert_(not a.flags['F'])
+        assert_(not a.flags['O'])
+        assert_(not a.flags['W'])
+        assert_(not a.flags['A'])
+        return a
+
+    def set_and_check_flag(self, flag, dtype, arr):
+        if dtype is None:
+            dtype = arr.dtype
+        b = np.require(arr, dtype, [flag])
+        assert_(b.flags[flag])
+        assert_(b.dtype == dtype)
+
+        # a further call to np.require ought to return the same array
+        # unless OWNDATA is specified.
+        c = np.require(b, None, [flag])
+        if flag[0] != 'O':
+            assert_(c is b)
+        else:
+            assert_(c.flags[flag])
+
+    def test_require_each(self):
+
+        id = ['f8', 'i4']
+        fd = [None, 'f8', 'c16']
+        for idtype, fdtype, flag in itertools.product(id, fd, self.flag_names):
+            a = self.generate_all_false(idtype)
+            yield self.set_and_check_flag, flag, fdtype,  a
+
+    def test_unknown_requirement(self):
+        a = self.generate_all_false('f8')
+        assert_raises(KeyError, np.require, a, None, 'Q')
+
+    def test_non_array_input(self):
+        a = np.require([1, 2, 3, 4], 'i4', ['C', 'A', 'O'])
+        assert_(a.flags['O'])
+        assert_(a.flags['C'])
+        assert_(a.flags['A'])
+        assert_(a.dtype == 'i4')
+        assert_equal(a, [1, 2, 3, 4])
+
+    def test_C_and_F_simul(self):
+        a = self.generate_all_false('f8')
+        assert_raises(ValueError, np.require, a, None, ['C', 'F'])
+
+    def test_ensure_array(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        a = ArraySubclass((2, 2))
+        b = np.require(a, None, ['E'])
+        assert_(type(b) is np.ndarray)
+
+    def test_preserve_subtype(self):
+        class ArraySubclass(np.ndarray):
+            pass
+
+        for flag in self.flag_names:
+            a = ArraySubclass((2, 2))
+            yield self.set_and_check_flag, flag, None, a
+
+
+class TestBroadcast(TestCase):
+    def test_broadcast_in_args(self):
+        # gh-5881
+        arrs = [np.empty((6, 7)), np.empty((5, 6, 1)), np.empty((7,)),
+                np.empty((5, 1, 7))]
+        mits = [np.broadcast(*arrs),
+                np.broadcast(np.broadcast(*arrs[:2]), np.broadcast(*arrs[2:])),
+                np.broadcast(arrs[0], np.broadcast(*arrs[1:-1]), arrs[-1])]
+        for mit in mits:
+            assert_equal(mit.shape, (5, 6, 7))
+            assert_equal(mit.nd, 3)
+            assert_equal(mit.numiter, 4)
+            for a, ia in zip(arrs, mit.iters):
+                assert_(a is ia.base)
+
+    def test_broadcast_single_arg(self):
+        # gh-6899
+        arrs = [np.empty((5, 6, 7))]
+        mit = np.broadcast(*arrs)
+        assert_equal(mit.shape, (5, 6, 7))
+        assert_equal(mit.nd, 3)
+        assert_equal(mit.numiter, 1)
+        assert_(arrs[0] is mit.iters[0].base)
+
+    def test_number_of_arguments(self):
+        arr = np.empty((5,))
+        for j in range(35):
+            arrs = [arr] * j
+            if j < 1 or j > 32:
+                assert_raises(ValueError, np.broadcast, *arrs)
+            else:
+                mit = np.broadcast(*arrs)
+                assert_equal(mit.numiter, j)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
new file mode 100644
index 0000000000..a7bbe01922
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
@@ -0,0 +1,382 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import asbytes, asunicode
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal
+)
+
+# This is the structure of the table used for plain objects:
+#
+# +-+-+-+
+# |x|y|z|
+# +-+-+-+
+
+# Structure of a plain array description:
+Pdescr = [
+    ('x', 'i4', (2,)),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+# A plain list of tuples with values for testing:
+PbufferT = [
+    # x     y                  z
+    ([3, 2], [[6., 4.], [6., 4.]], 8),
+    ([4, 3], [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+# This is the structure of the table used for nested objects (DON'T PANIC!):
+#
+# +-+---------------------------------+-----+----------+-+-+
+# |x|Info                             |color|info      |y|z|
+# | +-----+--+----------------+----+--+     +----+-----+ | |
+# | |value|y2|Info2           |name|z2|     |Name|Value| | |
+# | |     |  +----+-----+--+--+    |  |     |    |     | | |
+# | |     |  |name|value|y3|z3|    |  |     |    |     | | |
+# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+
+#
+
+# The corresponding nested array description:
+Ndescr = [
+    ('x', 'i4', (2,)),
+    ('Info', [
+        ('value', 'c16'),
+        ('y2', 'f8'),
+        ('Info2', [
+            ('name', 'S2'),
+            ('value', 'c16', (2,)),
+            ('y3', 'f8', (2,)),
+            ('z3', 'u4', (2,))]),
+        ('name', 'S2'),
+        ('z2', 'b1')]),
+    ('color', 'S2'),
+    ('info', [
+        ('Name', 'U8'),
+        ('Value', 'c16')]),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+NbufferT = [
+    # x     Info                                                color info        y                  z
+    #       value y2 Info2                            name z2         Name Value
+    #                name   value    y3       z3
+    ([3, 2], (6j, 6., (asbytes('nn'), [6j, 4j], [6., 4.], [1, 2]), asbytes('NN'), True), asbytes('cc'), (asunicode('NN'), 6j), [[6., 4.], [6., 4.]], 8),
+    ([4, 3], (7j, 7., (asbytes('oo'), [7j, 5j], [7., 5.], [2, 1]), asbytes('OO'), False), asbytes('dd'), (asunicode('OO'), 7j), [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+byteorder = {'little':'<', 'big':'>'}[sys.byteorder]
+
+def normalize_descr(descr):
+    "Normalize a description adding the platform byteorder."
+
+    out = []
+    for item in descr:
+        dtype = item[1]
+        if isinstance(dtype, str):
+            if dtype[0] not in ['|', '<', '>']:
+                onebyte = dtype[1:] == "1"
+                if onebyte or dtype[0] in ['S', 'V', 'b']:
+                    dtype = "|" + dtype
+                else:
+                    dtype = byteorder + dtype
+            if len(item) > 2 and np.prod(item[2]) > 1:
+                nitem = (item[0], dtype, item[2])
+            else:
+                nitem = (item[0], dtype)
+            out.append(nitem)
+        elif isinstance(item[1], list):
+            l = []
+            for j in normalize_descr(item[1]):
+                l.append(j)
+            out.append((item[0], l))
+        else:
+            raise ValueError("Expected a str or list and got %s" %
+                             (type(item)))
+    return out
+
+
+############################################################
+#    Creation tests
+############################################################
+
+class create_zeros(object):
+    """Check the creation of heterogeneous arrays zero-valued"""
+
+    def test_zeros0D(self):
+        """Check creation of 0-dimensional objects"""
+        h = np.zeros((), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype.fields['x'][0].name[:4] == 'void')
+        self.assertTrue(h.dtype.fields['x'][0].char == 'V')
+        self.assertTrue(h.dtype.fields['x'][0].type == np.void)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((), dtype='u1'))
+
+    def test_zerosSD(self):
+        """Check creation of single-dimensional objects"""
+        h = np.zeros((2,), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype['y'].name[:4] == 'void')
+        self.assertTrue(h.dtype['y'].char == 'V')
+        self.assertTrue(h.dtype['y'].type == np.void)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((2,), dtype='u1'))
+
+    def test_zerosMD(self):
+        """Check creation of multi-dimensional objects"""
+        h = np.zeros((2, 3), dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        self.assertTrue(h.dtype['z'].name == 'uint8')
+        self.assertTrue(h.dtype['z'].char == 'B')
+        self.assertTrue(h.dtype['z'].type == np.uint8)
+        # A small check that data is ok
+        assert_equal(h['z'], np.zeros((2, 3), dtype='u1'))
+
+
+class test_create_zeros_plain(create_zeros, TestCase):
+    """Check the creation of heterogeneous arrays zero-valued (plain)"""
+    _descr = Pdescr
+
+class test_create_zeros_nested(create_zeros, TestCase):
+    """Check the creation of heterogeneous arrays zero-valued (nested)"""
+    _descr = Ndescr
+
+
+class create_values(object):
+    """Check the creation of heterogeneous arrays with values"""
+
+    def test_tuple(self):
+        """Check creation from tuples"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (2,))
+        else:
+            self.assertTrue(h.shape == ())
+
+    def test_list_of_tuple(self):
+        """Check creation from list of tuples"""
+        h = np.array([self._buffer], dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (1, 2))
+        else:
+            self.assertTrue(h.shape == (1,))
+
+    def test_list_of_list_of_tuple(self):
+        """Check creation from list of list of tuples"""
+        h = np.array([[self._buffer]], dtype=self._descr)
+        self.assertTrue(normalize_descr(self._descr) == h.dtype.descr)
+        if self.multiple_rows:
+            self.assertTrue(h.shape == (1, 1, 2))
+        else:
+            self.assertTrue(h.shape == (1, 1))
+
+
+class test_create_values_plain_single(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (plain, single row)"""
+    _descr = Pdescr
+    multiple_rows = 0
+    _buffer = PbufferT[0]
+
+class test_create_values_plain_multiple(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (plain, multiple rows)"""
+    _descr = Pdescr
+    multiple_rows = 1
+    _buffer = PbufferT
+
+class test_create_values_nested_single(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (nested, single row)"""
+    _descr = Ndescr
+    multiple_rows = 0
+    _buffer = NbufferT[0]
+
+class test_create_values_nested_multiple(create_values, TestCase):
+    """Check the creation of heterogeneous arrays (nested, multiple rows)"""
+    _descr = Ndescr
+    multiple_rows = 1
+    _buffer = NbufferT
+
+
+############################################################
+#    Reading tests
+############################################################
+
+class read_values_plain(object):
+    """Check the reading of values in heterogeneous arrays (plain)"""
+
+    def test_access_fields(self):
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            self.assertTrue(h.shape == ())
+            assert_equal(h['x'], np.array(self._buffer[0], dtype='i4'))
+            assert_equal(h['y'], np.array(self._buffer[1], dtype='f8'))
+            assert_equal(h['z'], np.array(self._buffer[2], dtype='u1'))
+        else:
+            self.assertTrue(len(h) == 2)
+            assert_equal(h['x'], np.array([self._buffer[0][0],
+                                             self._buffer[1][0]], dtype='i4'))
+            assert_equal(h['y'], np.array([self._buffer[0][1],
+                                             self._buffer[1][1]], dtype='f8'))
+            assert_equal(h['z'], np.array([self._buffer[0][2],
+                                             self._buffer[1][2]], dtype='u1'))
+
+
+class test_read_values_plain_single(read_values_plain, TestCase):
+    """Check the creation of heterogeneous arrays (plain, single row)"""
+    _descr = Pdescr
+    multiple_rows = 0
+    _buffer = PbufferT[0]
+
+class test_read_values_plain_multiple(read_values_plain, TestCase):
+    """Check the values of heterogeneous arrays (plain, multiple rows)"""
+    _descr = Pdescr
+    multiple_rows = 1
+    _buffer = PbufferT
+
+class read_values_nested(object):
+    """Check the reading of values in heterogeneous arrays (nested)"""
+
+    def test_access_top_fields(self):
+        """Check reading the top fields of a nested array"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            self.assertTrue(h.shape == ())
+            assert_equal(h['x'], np.array(self._buffer[0], dtype='i4'))
+            assert_equal(h['y'], np.array(self._buffer[4], dtype='f8'))
+            assert_equal(h['z'], np.array(self._buffer[5], dtype='u1'))
+        else:
+            self.assertTrue(len(h) == 2)
+            assert_equal(h['x'], np.array([self._buffer[0][0],
+                                           self._buffer[1][0]], dtype='i4'))
+            assert_equal(h['y'], np.array([self._buffer[0][4],
+                                           self._buffer[1][4]], dtype='f8'))
+            assert_equal(h['z'], np.array([self._buffer[0][5],
+                                           self._buffer[1][5]], dtype='u1'))
+
+    def test_nested1_acessors(self):
+        """Check reading the nested fields of a nested array (1st level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            assert_equal(h['Info']['value'],
+                         np.array(self._buffer[1][0], dtype='c16'))
+            assert_equal(h['Info']['y2'],
+                         np.array(self._buffer[1][1], dtype='f8'))
+            assert_equal(h['info']['Name'],
+                         np.array(self._buffer[3][0], dtype='U2'))
+            assert_equal(h['info']['Value'],
+                         np.array(self._buffer[3][1], dtype='c16'))
+        else:
+            assert_equal(h['Info']['value'],
+                         np.array([self._buffer[0][1][0],
+                                self._buffer[1][1][0]],
+                                dtype='c16'))
+            assert_equal(h['Info']['y2'],
+                         np.array([self._buffer[0][1][1],
+                                self._buffer[1][1][1]],
+                                dtype='f8'))
+            assert_equal(h['info']['Name'],
+                         np.array([self._buffer[0][3][0],
+                                self._buffer[1][3][0]],
+                               dtype='U2'))
+            assert_equal(h['info']['Value'],
+                         np.array([self._buffer[0][3][1],
+                                self._buffer[1][3][1]],
+                               dtype='c16'))
+
+    def test_nested2_acessors(self):
+        """Check reading the nested fields of a nested array (2nd level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        if not self.multiple_rows:
+            assert_equal(h['Info']['Info2']['value'],
+                         np.array(self._buffer[1][2][1], dtype='c16'))
+            assert_equal(h['Info']['Info2']['z3'],
+                         np.array(self._buffer[1][2][3], dtype='u4'))
+        else:
+            assert_equal(h['Info']['Info2']['value'],
+                         np.array([self._buffer[0][1][2][1],
+                                self._buffer[1][1][2][1]],
+                               dtype='c16'))
+            assert_equal(h['Info']['Info2']['z3'],
+                         np.array([self._buffer[0][1][2][3],
+                                self._buffer[1][1][2][3]],
+                               dtype='u4'))
+
+    def test_nested1_descriptor(self):
+        """Check access nested descriptors of a nested array (1st level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(h.dtype['Info']['value'].name == 'complex128')
+        self.assertTrue(h.dtype['Info']['y2'].name == 'float64')
+        if sys.version_info[0] >= 3:
+            self.assertTrue(h.dtype['info']['Name'].name == 'str256')
+        else:
+            self.assertTrue(h.dtype['info']['Name'].name == 'unicode256')
+        self.assertTrue(h.dtype['info']['Value'].name == 'complex128')
+
+    def test_nested2_descriptor(self):
+        """Check access nested descriptors of a nested array (2nd level)"""
+        h = np.array(self._buffer, dtype=self._descr)
+        self.assertTrue(h.dtype['Info']['Info2']['value'].name == 'void256')
+        self.assertTrue(h.dtype['Info']['Info2']['z3'].name == 'void64')
+
+
+class test_read_values_nested_single(read_values_nested, TestCase):
+    """Check the values of heterogeneous arrays (nested, single row)"""
+    _descr = Ndescr
+    multiple_rows = False
+    _buffer = NbufferT[0]
+
+class test_read_values_nested_multiple(read_values_nested, TestCase):
+    """Check the values of heterogeneous arrays (nested, multiple rows)"""
+    _descr = Ndescr
+    multiple_rows = True
+    _buffer = NbufferT
+
+class TestEmptyField(TestCase):
+    def test_assign(self):
+        a = np.arange(10, dtype=np.float32)
+        a.dtype = [("int",   "<0i4"), ("float", "<2f4")]
+        assert_(a['int'].shape == (5, 0))
+        assert_(a['float'].shape == (5, 2))
+
+class TestCommonType(TestCase):
+    def test_scalar_loses1(self):
+        res = np.find_common_type(['f4', 'f4', 'i2'], ['f8'])
+        assert_(res == 'f4')
+
+    def test_scalar_loses2(self):
+        res = np.find_common_type(['f4', 'f4'], ['i8'])
+        assert_(res == 'f4')
+
+    def test_scalar_wins(self):
+        res = np.find_common_type(['f4', 'f4', 'i2'], ['c8'])
+        assert_(res == 'c8')
+
+    def test_scalar_wins2(self):
+        res = np.find_common_type(['u4', 'i4', 'i4'], ['f4'])
+        assert_(res == 'f8')
+
+    def test_scalar_wins3(self):  # doesn't go up to 'f16' on purpose
+        res = np.find_common_type(['u8', 'i8', 'i8'], ['f8'])
+        assert_(res == 'f8')
+
+class TestMultipleFields(TestCase):
+    def setUp(self):
+        self.ary = np.array([(1, 2, 3, 4), (5, 6, 7, 8)], dtype='i4,f4,i2,c8')
+
+    def _bad_call(self):
+        return self.ary['f0', 'f1']
+
+    def test_no_tuple(self):
+        self.assertRaises(IndexError, self._bad_call)
+
+    def test_return(self):
+        res = self.ary[['f0', 'f2']].tolist()
+        assert_(res == [(1, 3), (5, 7)])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_print.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_print.py
new file mode 100644
index 0000000000..6234b641ea
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_print.py
@@ -0,0 +1,248 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import locale
+import nose
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, SkipTest
+)
+
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+_REF = {np.inf: 'inf', -np.inf: '-inf', np.nan: 'nan'}
+
+
+def check_float_type(tp):
+    for x in [0, 1, -1, 1e20]:
+        assert_equal(str(tp(x)), str(float(x)),
+                     err_msg='Failed str formatting for type %s' % tp)
+
+    if tp(1e10).itemsize > 4:
+        assert_equal(str(tp(1e10)), str(float('1e10')),
+                     err_msg='Failed str formatting for type %s' % tp)
+    else:
+        ref = '1e+10'
+        assert_equal(str(tp(1e10)), ref,
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_float_types():
+    """ Check formatting.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_float_type, t
+
+def check_nan_inf_float(tp):
+    for x in [np.inf, -np.inf, np.nan]:
+        assert_equal(str(tp(x)), _REF[x],
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_nan_inf_float():
+    """ Check formatting of nan & inf.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_nan_inf_float, t
+
+def check_complex_type(tp):
+    for x in [0, 1, -1, 1e20]:
+        assert_equal(str(tp(x)), str(complex(x)),
+                     err_msg='Failed str formatting for type %s' % tp)
+        assert_equal(str(tp(x*1j)), str(complex(x*1j)),
+                     err_msg='Failed str formatting for type %s' % tp)
+        assert_equal(str(tp(x + x*1j)), str(complex(x + x*1j)),
+                     err_msg='Failed str formatting for type %s' % tp)
+
+    if tp(1e10).itemsize > 8:
+        assert_equal(str(tp(1e10)), str(complex(1e10)),
+                     err_msg='Failed str formatting for type %s' % tp)
+    else:
+        ref = '(1e+10+0j)'
+        assert_equal(str(tp(1e10)), ref,
+                     err_msg='Failed str formatting for type %s' % tp)
+
+def test_complex_types():
+    """Check formatting of complex types.
+
+        This is only for the str function, and only for simple types.
+        The precision of np.float and np.longdouble aren't the same as the
+        python float precision.
+
+    """
+    for t in [np.complex64, np.cdouble, np.clongdouble]:
+        yield check_complex_type, t
+
+def test_complex_inf_nan():
+    """Check inf/nan formatting of complex types."""
+    TESTS = {
+        complex(np.inf, 0): "(inf+0j)",
+        complex(0, np.inf): "inf*j",
+        complex(-np.inf, 0): "(-inf+0j)",
+        complex(0, -np.inf): "-inf*j",
+        complex(np.inf, 1): "(inf+1j)",
+        complex(1, np.inf): "(1+inf*j)",
+        complex(-np.inf, 1): "(-inf+1j)",
+        complex(1, -np.inf): "(1-inf*j)",
+        complex(np.nan, 0): "(nan+0j)",
+        complex(0, np.nan): "nan*j",
+        complex(-np.nan, 0): "(nan+0j)",
+        complex(0, -np.nan): "nan*j",
+        complex(np.nan, 1): "(nan+1j)",
+        complex(1, np.nan): "(1+nan*j)",
+        complex(-np.nan, 1): "(nan+1j)",
+        complex(1, -np.nan): "(1+nan*j)",
+    }
+    for tp in [np.complex64, np.cdouble, np.clongdouble]:
+        for c, s in TESTS.items():
+            yield _check_complex_inf_nan, c, s, tp
+
+def _check_complex_inf_nan(c, s, dtype):
+    assert_equal(str(dtype(c)), s)
+
+# print tests
+def _test_redirected_print(x, tp, ref=None):
+    file = StringIO()
+    file_tp = StringIO()
+    stdout = sys.stdout
+    try:
+        sys.stdout = file_tp
+        print(tp(x))
+        sys.stdout = file
+        if ref:
+            print(ref)
+        else:
+            print(x)
+    finally:
+        sys.stdout = stdout
+
+    assert_equal(file.getvalue(), file_tp.getvalue(),
+                 err_msg='print failed for type%s' % tp)
+
+def check_float_type_print(tp):
+    for x in [0, 1, -1, 1e20]:
+        _test_redirected_print(float(x), tp)
+
+    for x in [np.inf, -np.inf, np.nan]:
+        _test_redirected_print(float(x), tp, _REF[x])
+
+    if tp(1e10).itemsize > 4:
+        _test_redirected_print(float(1e10), tp)
+    else:
+        ref = '1e+10'
+        _test_redirected_print(float(1e10), tp, ref)
+
+def check_complex_type_print(tp):
+    # We do not create complex with inf/nan directly because the feature is
+    # missing in python < 2.6
+    for x in [0, 1, -1, 1e20]:
+        _test_redirected_print(complex(x), tp)
+
+    if tp(1e10).itemsize > 8:
+        _test_redirected_print(complex(1e10), tp)
+    else:
+        ref = '(1e+10+0j)'
+        _test_redirected_print(complex(1e10), tp, ref)
+
+    _test_redirected_print(complex(np.inf, 1), tp, '(inf+1j)')
+    _test_redirected_print(complex(-np.inf, 1), tp, '(-inf+1j)')
+    _test_redirected_print(complex(-np.nan, 1), tp, '(nan+1j)')
+
+def test_float_type_print():
+    """Check formatting when using print """
+    for t in [np.float32, np.double, np.longdouble]:
+        yield check_float_type_print, t
+
+def test_complex_type_print():
+    """Check formatting when using print """
+    for t in [np.complex64, np.cdouble, np.clongdouble]:
+        yield check_complex_type_print, t
+
+def test_scalar_format():
+    """Test the str.format method with NumPy scalar types"""
+    tests = [('{0}', True, np.bool_),
+            ('{0}', False, np.bool_),
+            ('{0:d}', 130, np.uint8),
+            ('{0:d}', 50000, np.uint16),
+            ('{0:d}', 3000000000, np.uint32),
+            ('{0:d}', 15000000000000000000, np.uint64),
+            ('{0:d}', -120, np.int8),
+            ('{0:d}', -30000, np.int16),
+            ('{0:d}', -2000000000, np.int32),
+            ('{0:d}', -7000000000000000000, np.int64),
+            ('{0:g}', 1.5, np.float16),
+            ('{0:g}', 1.5, np.float32),
+            ('{0:g}', 1.5, np.float64),
+            ('{0:g}', 1.5, np.longdouble)]
+    # Python 2.6 doesn't implement complex.__format__
+    if sys.version_info[:2] > (2, 6):
+        tests += [('{0:g}', 1.5+0.5j, np.complex64),
+                ('{0:g}', 1.5+0.5j, np.complex128),
+                ('{0:g}', 1.5+0.5j, np.clongdouble)]
+
+    for (fmat, val, valtype) in tests:
+        try:
+            assert_equal(fmat.format(val), fmat.format(valtype(val)),
+                    "failed with val %s, type %s" % (val, valtype))
+        except ValueError as e:
+            assert_(False,
+               "format raised exception (fmt='%s', val=%s, type=%s, exc='%s')" %
+                            (fmat, repr(val), repr(valtype), str(e)))
+
+
+# Locale tests: scalar types formatting should be independent of the locale
+def in_foreign_locale(func):
+    """
+    Swap LC_NUMERIC locale to one in which the decimal point is ',' and not '.'
+    If not possible, raise SkipTest
+
+    """
+    if sys.platform == 'win32':
+        locales = ['FRENCH']
+    else:
+        locales = ['fr_FR', 'fr_FR.UTF-8', 'fi_FI', 'fi_FI.UTF-8']
+
+    def wrapper(*args, **kwargs):
+        curloc = locale.getlocale(locale.LC_NUMERIC)
+        try:
+            for loc in locales:
+                try:
+                    locale.setlocale(locale.LC_NUMERIC, loc)
+                    break
+                except locale.Error:
+                    pass
+            else:
+                raise SkipTest("Skipping locale test, because "
+                                "French locale not found")
+            return func(*args, **kwargs)
+        finally:
+            locale.setlocale(locale.LC_NUMERIC, locale=curloc)
+    return nose.tools.make_decorator(func)(wrapper)
+
+@in_foreign_locale
+def test_locale_single():
+    assert_equal(str(np.float32(1.2)), str(float(1.2)))
+
+@in_foreign_locale
+def test_locale_double():
+    assert_equal(str(np.double(1.2)), str(float(1.2)))
+
+@in_foreign_locale
+def test_locale_longdouble():
+    assert_equal(str(np.longdouble(1.2)), str(float(1.2)))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_records.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_records.py
new file mode 100644
index 0000000000..9fbdf51d60
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_records.py
@@ -0,0 +1,337 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import collections
+import pickle
+from os import path
+
+import numpy as np
+from numpy.compat import asbytes
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_raises
+    )
+
+
+class TestFromrecords(TestCase):
+    def test_fromrecords(self):
+        r = np.rec.fromrecords([[456, 'dbe', 1.2], [2, 'de', 1.3]],
+                            names='col1,col2,col3')
+        assert_equal(r[0].item(), (456, 'dbe', 1.2))
+        assert_equal(r['col1'].dtype.kind, 'i')
+        if sys.version_info[0] >= 3:
+            assert_equal(r['col2'].dtype.kind, 'U')
+            assert_equal(r['col2'].dtype.itemsize, 12)
+        else:
+            assert_equal(r['col2'].dtype.kind, 'S')
+            assert_equal(r['col2'].dtype.itemsize, 3)
+        assert_equal(r['col3'].dtype.kind, 'f')
+
+    def test_method_array(self):
+        r = np.rec.array(asbytes('abcdefg') * 100, formats='i2,a3,i4', shape=3, byteorder='big')
+        assert_equal(r[1].item(), (25444, asbytes('efg'), 1633837924))
+
+    def test_method_array2(self):
+        r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'),
+                     (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1')
+        assert_equal(r[1].item(), (2, 22.0, asbytes('b')))
+
+    def test_recarray_slices(self):
+        r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'),
+                     (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1')
+        assert_equal(r[1::2][1].item(), (4, 44.0, asbytes('d')))
+
+    def test_recarray_fromarrays(self):
+        x1 = np.array([1, 2, 3, 4])
+        x2 = np.array(['a', 'dd', 'xyz', '12'])
+        x3 = np.array([1.1, 2, 3, 4])
+        r = np.rec.fromarrays([x1, x2, x3], names='a,b,c')
+        assert_equal(r[1].item(), (2, 'dd', 2.0))
+        x1[1] = 34
+        assert_equal(r.a, np.array([1, 2, 3, 4]))
+
+    def test_recarray_fromfile(self):
+        data_dir = path.join(path.dirname(__file__), 'data')
+        filename = path.join(data_dir, 'recarray_from_file.fits')
+        fd = open(filename, 'rb')
+        fd.seek(2880 * 2)
+        r1 = np.rec.fromfile(fd, formats='f8,i4,a5', shape=3, byteorder='big')
+        fd.seek(2880 * 2)
+        r2 = np.rec.array(fd, formats='f8,i4,a5', shape=3, byteorder='big')
+        fd.close()
+        assert_equal(r1, r2)
+
+    def test_recarray_from_obj(self):
+        count = 10
+        a = np.zeros(count, dtype='O')
+        b = np.zeros(count, dtype='f8')
+        c = np.zeros(count, dtype='f8')
+        for i in range(len(a)):
+            a[i] = list(range(1, 10))
+
+        mine = np.rec.fromarrays([a, b, c], names='date,data1,data2')
+        for i in range(len(a)):
+            assert_((mine.date[i] == list(range(1, 10))))
+            assert_((mine.data1[i] == 0.0))
+            assert_((mine.data2[i] == 0.0))
+
+    def test_recarray_from_repr(self):
+        a = np.array([(1,'ABC'), (2, "DEF")],
+                     dtype=[('foo', int), ('bar', 'S4')])
+        recordarr = np.rec.array(a)
+        recarr = a.view(np.recarray)
+        recordview = a.view(np.dtype((np.record, a.dtype)))
+
+        recordarr_r = eval("numpy." + repr(recordarr), {'numpy': np})
+        recarr_r = eval("numpy." + repr(recarr), {'numpy': np})
+        recordview_r = eval("numpy." + repr(recordview), {'numpy': np})
+
+        assert_equal(type(recordarr_r), np.recarray)
+        assert_equal(recordarr_r.dtype.type, np.record)
+        assert_equal(recordarr, recordarr_r)
+
+        assert_equal(type(recarr_r), np.recarray)
+        assert_equal(recarr_r.dtype.type, np.record)
+        assert_equal(recarr, recarr_r)
+
+        assert_equal(type(recordview_r), np.ndarray)
+        assert_equal(recordview.dtype.type, np.record)
+        assert_equal(recordview, recordview_r)
+
+    def test_recarray_views(self):
+        a = np.array([(1,'ABC'), (2, "DEF")],
+                     dtype=[('foo', int), ('bar', 'S4')])
+        b = np.array([1,2,3,4,5], dtype=np.int64)
+
+        #check that np.rec.array gives right dtypes
+        assert_equal(np.rec.array(a).dtype.type, np.record)
+        assert_equal(type(np.rec.array(a)), np.recarray)
+        assert_equal(np.rec.array(b).dtype.type, np.int64)
+        assert_equal(type(np.rec.array(b)), np.recarray)
+
+        #check that viewing as recarray does the same
+        assert_equal(a.view(np.recarray).dtype.type, np.record)
+        assert_equal(type(a.view(np.recarray)), np.recarray)
+        assert_equal(b.view(np.recarray).dtype.type, np.int64)
+        assert_equal(type(b.view(np.recarray)), np.recarray)
+
+        #check that view to non-structured dtype preserves type=np.recarray
+        r = np.rec.array(np.ones(4, dtype="f4,i4"))
+        rv = r.view('f8').view('f4,i4')
+        assert_equal(type(rv), np.recarray)
+        assert_equal(rv.dtype.type, np.record)
+
+        #check that getitem also preserves np.recarray and np.record
+        r = np.rec.array(np.ones(4, dtype=[('a', 'i4'), ('b', 'i4'),
+                                           ('c', 'i4,i4')]))
+        assert_equal(r['c'].dtype.type, np.record)
+        assert_equal(type(r['c']), np.recarray)
+        assert_equal(r[['a', 'b']].dtype.type, np.record)
+        assert_equal(type(r[['a', 'b']]), np.recarray)
+
+        #and that it preserves subclasses (gh-6949)
+        class C(np.recarray):
+            pass
+
+        c = r.view(C)
+        assert_equal(type(c['c']), C)
+
+        # check that accessing nested structures keep record type, but
+        # not for subarrays, non-void structures, non-structured voids
+        test_dtype = [('a', 'f4,f4'), ('b', 'V8'), ('c', ('f4',2)),
+                      ('d', ('i8', 'i4,i4'))]
+        r = np.rec.array([((1,1), b'11111111', [1,1], 1),
+                          ((1,1), b'11111111', [1,1], 1)], dtype=test_dtype)
+        assert_equal(r.a.dtype.type, np.record)
+        assert_equal(r.b.dtype.type, np.void)
+        assert_equal(r.c.dtype.type, np.float32)
+        assert_equal(r.d.dtype.type, np.int64)
+        # check the same, but for views
+        r = np.rec.array(np.ones(4, dtype='i4,i4'))
+        assert_equal(r.view('f4,f4').dtype.type, np.record)
+        assert_equal(r.view(('i4',2)).dtype.type, np.int32)
+        assert_equal(r.view('V8').dtype.type, np.void)
+        assert_equal(r.view(('i8', 'i4,i4')).dtype.type, np.int64)
+
+        #check that we can undo the view
+        arrs = [np.ones(4, dtype='f4,i4'), np.ones(4, dtype='f8')]
+        for arr in arrs:
+            rec = np.rec.array(arr)
+            # recommended way to view as an ndarray:
+            arr2 = rec.view(rec.dtype.fields or rec.dtype, np.ndarray)
+            assert_equal(arr2.dtype.type, arr.dtype.type)
+            assert_equal(type(arr2), type(arr))
+
+    def test_recarray_repr(self):
+        # make sure non-structured dtypes also show up as rec.array
+        a = np.array(np.ones(4, dtype='f8'))
+        assert_(repr(np.rec.array(a)).startswith('rec.array'))
+
+        # check that the 'np.record' part of the dtype isn't shown
+        a = np.rec.array(np.ones(3, dtype='i4,i4'))
+        assert_equal(repr(a).find('numpy.record'), -1)
+        a = np.rec.array(np.ones(3, dtype='i4'))
+        assert_(repr(a).find('dtype=int32') != -1)
+
+    def test_recarray_from_names(self):
+        ra = np.rec.array([
+            (1, 'abc', 3.7000002861022949, 0),
+            (2, 'xy', 6.6999998092651367, 1),
+            (0, ' ', 0.40000000596046448, 0)],
+                       names='c1, c2, c3, c4')
+        pa = np.rec.fromrecords([
+            (1, 'abc', 3.7000002861022949, 0),
+            (2, 'xy', 6.6999998092651367, 1),
+            (0, ' ', 0.40000000596046448, 0)],
+                       names='c1, c2, c3, c4')
+        assert_(ra.dtype == pa.dtype)
+        assert_(ra.shape == pa.shape)
+        for k in range(len(ra)):
+            assert_(ra[k].item() == pa[k].item())
+
+    def test_recarray_conflict_fields(self):
+        ra = np.rec.array([(1, 'abc', 2.3), (2, 'xyz', 4.2),
+                        (3, 'wrs', 1.3)],
+                       names='field, shape, mean')
+        ra.mean = [1.1, 2.2, 3.3]
+        assert_array_almost_equal(ra['mean'], [1.1, 2.2, 3.3])
+        assert_(type(ra.mean) is type(ra.var))
+        ra.shape = (1, 3)
+        assert_(ra.shape == (1, 3))
+        ra.shape = ['A', 'B', 'C']
+        assert_array_equal(ra['shape'], [['A', 'B', 'C']])
+        ra.field = 5
+        assert_array_equal(ra['field'], [[5, 5, 5]])
+        assert_(isinstance(ra.field, collections.Callable))
+
+    def test_fromrecords_with_explicit_dtype(self):
+        a = np.rec.fromrecords([(1, 'a'), (2, 'bbb')],
+                                dtype=[('a', int), ('b', np.object)])
+        assert_equal(a.a, [1, 2])
+        assert_equal(a[0].a, 1)
+        assert_equal(a.b, ['a', 'bbb'])
+        assert_equal(a[-1].b, 'bbb')
+        #
+        ndtype = np.dtype([('a', int), ('b', np.object)])
+        a = np.rec.fromrecords([(1, 'a'), (2, 'bbb')], dtype=ndtype)
+        assert_equal(a.a, [1, 2])
+        assert_equal(a[0].a, 1)
+        assert_equal(a.b, ['a', 'bbb'])
+        assert_equal(a[-1].b, 'bbb')
+
+    def test_recarray_stringtypes(self):
+        # Issue #3993
+        a = np.array([('abc ', 1), ('abc', 2)],
+                     dtype=[('foo', 'S4'), ('bar', int)])
+        a = a.view(np.recarray)
+        assert_equal(a.foo[0] == a.foo[1], False)
+
+    def test_recarray_returntypes(self):
+        qux_fields = {'C': (np.dtype('S5'), 0), 'D': (np.dtype('S5'), 6)}
+        a = np.rec.array([('abc ', (1,1), 1, ('abcde', 'fgehi')),
+                          ('abc', (2,3), 1, ('abcde', 'jklmn'))],
+                         dtype=[('foo', 'S4'),
+                                ('bar', [('A', int), ('B', int)]),
+                                ('baz', int), ('qux', qux_fields)])
+        assert_equal(type(a.foo), np.ndarray)
+        assert_equal(type(a['foo']), np.ndarray)
+        assert_equal(type(a.bar), np.recarray)
+        assert_equal(type(a['bar']), np.recarray)
+        assert_equal(a.bar.dtype.type, np.record)
+        assert_equal(type(a['qux']), np.recarray)
+        assert_equal(a.qux.dtype.type, np.record)
+        assert_equal(dict(a.qux.dtype.fields), qux_fields)
+        assert_equal(type(a.baz), np.ndarray)
+        assert_equal(type(a['baz']), np.ndarray)
+        assert_equal(type(a[0].bar), np.record)
+        assert_equal(type(a[0]['bar']), np.record)
+        assert_equal(a[0].bar.A, 1)
+        assert_equal(a[0].bar['A'], 1)
+        assert_equal(a[0]['bar'].A, 1)
+        assert_equal(a[0]['bar']['A'], 1)
+        assert_equal(a[0].qux.D, asbytes('fgehi'))
+        assert_equal(a[0].qux['D'], asbytes('fgehi'))
+        assert_equal(a[0]['qux'].D, asbytes('fgehi'))
+        assert_equal(a[0]['qux']['D'], asbytes('fgehi'))
+
+
+class TestRecord(TestCase):
+    def setUp(self):
+        self.data = np.rec.fromrecords([(1, 2, 3), (4, 5, 6)],
+                            dtype=[("col1", "<i4"),
+                                   ("col2", "<i4"),
+                                   ("col3", "<i4")])
+
+    def test_assignment1(self):
+        a = self.data
+        assert_equal(a.col1[0], 1)
+        a[0].col1 = 0
+        assert_equal(a.col1[0], 0)
+
+    def test_assignment2(self):
+        a = self.data
+        assert_equal(a.col1[0], 1)
+        a.col1[0] = 0
+        assert_equal(a.col1[0], 0)
+
+    def test_invalid_assignment(self):
+        a = self.data
+
+        def assign_invalid_column(x):
+            x[0].col5 = 1
+
+        self.assertRaises(AttributeError, assign_invalid_column, a)
+
+    def test_out_of_order_fields(self):
+        """Ticket #1431."""
+        x = self.data[['col1', 'col2']]
+        y = self.data[['col2', 'col1']]
+        assert_equal(x[0][0], y[0][1])
+
+    def test_pickle_1(self):
+        # Issue #1529
+        a = np.array([(1, [])], dtype=[('a', np.int32), ('b', np.int32, 0)])
+        assert_equal(a, pickle.loads(pickle.dumps(a)))
+        assert_equal(a[0], pickle.loads(pickle.dumps(a[0])))
+
+    def test_pickle_2(self):
+        a = self.data
+        assert_equal(a, pickle.loads(pickle.dumps(a)))
+        assert_equal(a[0], pickle.loads(pickle.dumps(a[0])))
+
+    def test_objview_record(self):
+        # https://github.com/numpy/numpy/issues/2599
+        dt = np.dtype([('foo', 'i8'), ('bar', 'O')])
+        r = np.zeros((1,3), dtype=dt).view(np.recarray)
+        r.foo = np.array([1, 2, 3])  # TypeError?
+
+        # https://github.com/numpy/numpy/issues/3256
+        ra = np.recarray((2,), dtype=[('x', object), ('y', float), ('z', int)])
+        ra[['x','y']]  # TypeError?
+
+    def test_record_scalar_setitem(self):
+        # https://github.com/numpy/numpy/issues/3561
+        rec = np.recarray(1, dtype=[('x', float, 5)])
+        rec[0].x = 1
+        assert_equal(rec[0].x, np.ones(5))
+
+    def test_missing_field(self):
+        # https://github.com/numpy/numpy/issues/4806
+        arr = np.zeros((3,), dtype=[('x', int), ('y', int)])
+        assert_raises(ValueError, lambda: arr[['nofield']])
+
+def test_find_duplicate():
+    l1 = [1, 2, 3, 4, 5, 6]
+    assert_(np.rec.find_duplicate(l1) == [])
+
+    l2 = [1, 2, 1, 4, 5, 6]
+    assert_(np.rec.find_duplicate(l2) == [1])
+
+    l3 = [1, 2, 1, 4, 1, 6, 2, 3]
+    assert_(np.rec.find_duplicate(l3) == [1, 2])
+
+    l3 = [2, 2, 1, 4, 1, 6, 2, 3]
+    assert_(np.rec.find_duplicate(l3) == [2, 1])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
new file mode 100644
index 0000000000..a61e64d8de
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
@@ -0,0 +1,2187 @@
+from __future__ import division, absolute_import, print_function
+
+import copy
+import pickle
+import sys
+import platform
+import gc
+import warnings
+import tempfile
+from os import path
+from io import BytesIO
+from itertools import chain
+
+import numpy as np
+from numpy.testing import (
+        run_module_suite, TestCase, assert_, assert_equal,
+        assert_almost_equal, assert_array_equal, assert_array_almost_equal,
+        assert_raises, assert_warns, dec
+        )
+from numpy.testing.utils import _assert_valid_refcount
+from numpy.compat import asbytes, asunicode, asbytes_nested, long, sixu
+
+rlevel = 1
+
+class TestRegression(TestCase):
+    def test_invalid_round(self,level=rlevel):
+        # Ticket #3
+        v = 4.7599999999999998
+        assert_array_equal(np.array([v]), np.array(v))
+
+    def test_mem_empty(self,level=rlevel):
+        # Ticket #7
+        np.empty((1,), dtype=[('x', np.int64)])
+
+    def test_pickle_transposed(self,level=rlevel):
+        # Ticket #16
+        a = np.transpose(np.array([[2, 9], [7, 0], [3, 8]]))
+        f = BytesIO()
+        pickle.dump(a, f)
+        f.seek(0)
+        b = pickle.load(f)
+        f.close()
+        assert_array_equal(a, b)
+
+    def test_typeNA(self,level=rlevel):
+        # Ticket #31
+        assert_equal(np.typeNA[np.int64], 'Int64')
+        assert_equal(np.typeNA[np.uint64], 'UInt64')
+
+    def test_dtype_names(self,level=rlevel):
+        # Ticket #35
+        # Should succeed
+        np.dtype([(('name', 'label'), np.int32, 3)])
+
+    def test_reduce(self,level=rlevel):
+        # Ticket #40
+        assert_almost_equal(np.add.reduce([1., .5], dtype=None), 1.5)
+
+    def test_zeros_order(self,level=rlevel):
+        # Ticket #43
+        np.zeros([3], int, 'C')
+        np.zeros([3], order='C')
+        np.zeros([3], int, order='C')
+
+    def test_asarray_with_order(self,level=rlevel):
+        # Check that nothing is done when order='F' and array C/F-contiguous
+        a = np.ones(2)
+        assert_(a is np.asarray(a, order='F'))
+
+    def test_ravel_with_order(self,level=rlevel):
+        # Check that ravel works when order='F' and array C/F-contiguous
+        a = np.ones(2)
+        assert_(not a.ravel('F').flags.owndata)
+
+    def test_sort_bigendian(self,level=rlevel):
+        # Ticket #47
+        a = np.linspace(0, 10, 11)
+        c = a.astype(np.dtype('<f8'))
+        c.sort()
+        assert_array_almost_equal(c, a)
+
+    def test_negative_nd_indexing(self,level=rlevel):
+        # Ticket #49
+        c = np.arange(125).reshape((5, 5, 5))
+        origidx = np.array([-1, 0, 1])
+        idx = np.array(origidx)
+        c[idx]
+        assert_array_equal(idx, origidx)
+
+    def test_char_dump(self,level=rlevel):
+        # Ticket #50
+        f = BytesIO()
+        ca = np.char.array(np.arange(1000, 1010), itemsize=4)
+        ca.dump(f)
+        f.seek(0)
+        ca = np.load(f)
+        f.close()
+
+    def test_noncontiguous_fill(self,level=rlevel):
+        # Ticket #58.
+        a = np.zeros((5, 3))
+        b = a[:, :2,]
+
+        def rs():
+            b.shape = (10,)
+
+        self.assertRaises(AttributeError, rs)
+
+    def test_bool(self,level=rlevel):
+        # Ticket #60
+        np.bool_(1)  # Should succeed
+
+    def test_indexing1(self,level=rlevel):
+        # Ticket #64
+        descr = [('x', [('y', [('z', 'c16', (2,)),]),]),]
+        buffer = ((([6j, 4j],),),)
+        h = np.array(buffer, dtype=descr)
+        h['x']['y']['z']
+
+    def test_indexing2(self,level=rlevel):
+        # Ticket #65
+        descr = [('x', 'i4', (2,))]
+        buffer = ([3, 2],)
+        h = np.array(buffer, dtype=descr)
+        h['x']
+
+    def test_round(self,level=rlevel):
+        # Ticket #67
+        x = np.array([1+2j])
+        assert_almost_equal(x**(-1), [1/(1+2j)])
+
+    def test_scalar_compare(self,level=rlevel):
+        # Trac Ticket #72
+        # https://github.com/numpy/numpy/issues/565
+        a = np.array(['test', 'auto'])
+        assert_array_equal(a == 'auto', np.array([False, True]))
+        self.assertTrue(a[1] == 'auto')
+        self.assertTrue(a[0] != 'auto')
+        b = np.linspace(0, 10, 11)
+        # This should return true for now, but will eventually raise an error:
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            self.assertTrue(b != 'auto')
+        self.assertTrue(b[0] != 'auto')
+
+    def test_unicode_swapping(self,level=rlevel):
+        # Ticket #79
+        ulen = 1
+        ucs_value = sixu('\U0010FFFF')
+        ua = np.array([[[ucs_value*ulen]*2]*3]*4, dtype='U%s' % ulen)
+        ua.newbyteorder()  # Should succeed.
+
+    def test_object_array_fill(self,level=rlevel):
+        # Ticket #86
+        x = np.zeros(1, 'O')
+        x.fill([])
+
+    def test_mem_dtype_align(self,level=rlevel):
+        # Ticket #93
+        self.assertRaises(TypeError, np.dtype,
+                              {'names':['a'],'formats':['foo']}, align=1)
+
+    @dec.knownfailureif((sys.version_info[0] >= 3) or
+                        (sys.platform == "win32" and
+                         platform.architecture()[0] == "64bit"),
+                        "numpy.intp('0xff', 16) not supported on Py3, "
+                        "as it does not inherit from Python int")
+    def test_intp(self,level=rlevel):
+        # Ticket #99
+        i_width = np.int_(0).nbytes*2 - 1
+        np.intp('0x' + 'f'*i_width, 16)
+        self.assertRaises(OverflowError, np.intp, '0x' + 'f'*(i_width+1), 16)
+        self.assertRaises(ValueError, np.intp, '0x1', 32)
+        assert_equal(255, np.intp('0xFF', 16))
+        assert_equal(1024, np.intp(1024))
+
+    def test_endian_bool_indexing(self,level=rlevel):
+        # Ticket #105
+        a = np.arange(10., dtype='>f8')
+        b = np.arange(10., dtype='<f8')
+        xa = np.where((a > 2) & (a < 6))
+        xb = np.where((b > 2) & (b < 6))
+        ya = ((a > 2) & (a < 6))
+        yb = ((b > 2) & (b < 6))
+        assert_array_almost_equal(xa, ya.nonzero())
+        assert_array_almost_equal(xb, yb.nonzero())
+        assert_(np.all(a[ya] > 0.5))
+        assert_(np.all(b[yb] > 0.5))
+
+    def test_endian_where(self,level=rlevel):
+        # GitHub issue #369
+        net = np.zeros(3, dtype='>f4')
+        net[1] = 0.00458849
+        net[2] = 0.605202
+        max_net = net.max()
+        test = np.where(net <= 0., max_net, net)
+        correct = np.array([ 0.60520202,  0.00458849,  0.60520202])
+        assert_array_almost_equal(test, correct)
+
+    def test_endian_recarray(self,level=rlevel):
+        # Ticket #2185
+        dt = np.dtype([
+               ('head', '>u4'),
+               ('data', '>u4', 2),
+            ])
+        buf = np.recarray(1, dtype=dt)
+        buf[0]['head'] = 1
+        buf[0]['data'][:] = [1, 1]
+
+        h = buf[0]['head']
+        d = buf[0]['data'][0]
+        buf[0]['head'] = h
+        buf[0]['data'][0] = d
+        assert_(buf[0]['head'] == 1)
+
+    def test_mem_dot(self,level=rlevel):
+        # Ticket #106
+        x = np.random.randn(0, 1)
+        y = np.random.randn(10, 1)
+        # Dummy array to detect bad memory access:
+        _z = np.ones(10)
+        _dummy = np.empty((0, 10))
+        z = np.lib.stride_tricks.as_strided(_z, _dummy.shape, _dummy.strides)
+        np.dot(x, np.transpose(y), out=z)
+        assert_equal(_z, np.ones(10))
+        # Do the same for the built-in dot:
+        np.core.multiarray.dot(x, np.transpose(y), out=z)
+        assert_equal(_z, np.ones(10))
+
+    def test_arange_endian(self,level=rlevel):
+        # Ticket #111
+        ref = np.arange(10)
+        x = np.arange(10, dtype='<f8')
+        assert_array_equal(ref, x)
+        x = np.arange(10, dtype='>f8')
+        assert_array_equal(ref, x)
+
+    def test_argmax(self,level=rlevel):
+        # Ticket #119
+        a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+        for i in range(a.ndim):
+            a.argmax(i)  # Should succeed
+
+    def test_mem_divmod(self,level=rlevel):
+        # Ticket #126
+        for i in range(10):
+            divmod(np.array([i])[0], 10)
+
+    def test_hstack_invalid_dims(self,level=rlevel):
+        # Ticket #128
+        x = np.arange(9).reshape((3, 3))
+        y = np.array([0, 0, 0])
+        self.assertRaises(ValueError, np.hstack, (x, y))
+
+    def test_squeeze_type(self,level=rlevel):
+        # Ticket #133
+        a = np.array([3])
+        b = np.array(3)
+        assert_(type(a.squeeze()) is np.ndarray)
+        assert_(type(b.squeeze()) is np.ndarray)
+
+    def test_add_identity(self,level=rlevel):
+        # Ticket #143
+        assert_equal(0, np.add.identity)
+
+    def test_numpy_float_python_long_addition(self):
+        # Check that numpy float and python longs can be added correctly.
+        a = np.float_(23.) + 2**135
+        assert_equal(a, 23. + 2**135)
+
+    def test_binary_repr_0(self,level=rlevel):
+        # Ticket #151
+        assert_equal('0', np.binary_repr(0))
+
+    def test_rec_iterate(self,level=rlevel):
+        # Ticket #160
+        descr = np.dtype([('i', int), ('f', float), ('s', '|S3')])
+        x = np.rec.array([(1, 1.1, '1.0'),
+                         (2, 2.2, '2.0')], dtype=descr)
+        x[0].tolist()
+        [i for i in x[0]]
+
+    def test_unicode_string_comparison(self,level=rlevel):
+        # Ticket #190
+        a = np.array('hello', np.unicode_)
+        b = np.array('world')
+        a == b
+
+    def test_tobytes_FORTRANORDER_discontiguous(self,level=rlevel):
+        # Fix in r2836
+        # Create non-contiguous Fortran ordered array
+        x = np.array(np.random.rand(3, 3), order='F')[:, :2]
+        assert_array_almost_equal(x.ravel(), np.fromstring(x.tobytes()))
+
+    def test_flat_assignment(self,level=rlevel):
+        # Correct behaviour of ticket #194
+        x = np.empty((3, 1))
+        x.flat = np.arange(3)
+        assert_array_almost_equal(x, [[0], [1], [2]])
+        x.flat = np.arange(3, dtype=float)
+        assert_array_almost_equal(x, [[0], [1], [2]])
+
+    def test_broadcast_flat_assignment(self,level=rlevel):
+        # Ticket #194
+        x = np.empty((3, 1))
+
+        def bfa():
+            x[:] = np.arange(3)
+
+        def bfb():
+            x[:] = np.arange(3, dtype=float)
+
+        self.assertRaises(ValueError, bfa)
+        self.assertRaises(ValueError, bfb)
+
+    def test_nonarray_assignment(self):
+        # See also Issue gh-2870, test for non-array assignment
+        # and equivalent unsafe casted array assignment
+        a = np.arange(10)
+        b = np.ones(10, dtype=bool)
+        r = np.arange(10)
+
+        def assign(a, b, c):
+            a[b] = c
+
+        assert_raises(ValueError, assign, a, b, np.nan)
+        a[b] = np.array(np.nan)  # but not this.
+        assert_raises(ValueError, assign, a, r, np.nan)
+        a[r] = np.array(np.nan)
+
+    def test_unpickle_dtype_with_object(self,level=rlevel):
+        # Implemented in r2840
+        dt = np.dtype([('x', int), ('y', np.object_), ('z', 'O')])
+        f = BytesIO()
+        pickle.dump(dt, f)
+        f.seek(0)
+        dt_ = pickle.load(f)
+        f.close()
+        assert_equal(dt, dt_)
+
+    def test_mem_array_creation_invalid_specification(self,level=rlevel):
+        # Ticket #196
+        dt = np.dtype([('x', int), ('y', np.object_)])
+        # Wrong way
+        self.assertRaises(ValueError, np.array, [1, 'object'], dt)
+        # Correct way
+        np.array([(1, 'object')], dt)
+
+    def test_recarray_single_element(self,level=rlevel):
+        # Ticket #202
+        a = np.array([1, 2, 3], dtype=np.int32)
+        b = a.copy()
+        r = np.rec.array(a, shape=1, formats=['3i4'], names=['d'])
+        assert_array_equal(a, b)
+        assert_equal(a, r[0][0])
+
+    def test_zero_sized_array_indexing(self,level=rlevel):
+        # Ticket #205
+        tmp = np.array([])
+
+        def index_tmp():
+            tmp[np.array(10)]
+
+        self.assertRaises(IndexError, index_tmp)
+
+    def test_chararray_rstrip(self,level=rlevel):
+        # Ticket #222
+        x = np.chararray((1,), 5)
+        x[0] = asbytes('a   ')
+        x = x.rstrip()
+        assert_equal(x[0], asbytes('a'))
+
+    def test_object_array_shape(self,level=rlevel):
+        # Ticket #239
+        assert_equal(np.array([[1, 2], 3, 4], dtype=object).shape, (3,))
+        assert_equal(np.array([[1, 2], [3, 4]], dtype=object).shape, (2, 2))
+        assert_equal(np.array([(1, 2), (3, 4)], dtype=object).shape, (2, 2))
+        assert_equal(np.array([], dtype=object).shape, (0,))
+        assert_equal(np.array([[], [], []], dtype=object).shape, (3, 0))
+        assert_equal(np.array([[3, 4], [5, 6], None], dtype=object).shape, (3,))
+
+    def test_mem_around(self,level=rlevel):
+        # Ticket #243
+        x = np.zeros((1,))
+        y = [0]
+        decimal = 6
+        np.around(abs(x-y), decimal) <= 10.0**(-decimal)
+
+    def test_character_array_strip(self,level=rlevel):
+        # Ticket #246
+        x = np.char.array(("x", "x ", "x  "))
+        for c in x:
+            assert_equal(c, "x")
+
+    def test_lexsort(self,level=rlevel):
+        # Lexsort memory error
+        v = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+        assert_equal(np.lexsort(v), 0)
+
+    def test_lexsort_invalid_sequence(self):
+        # Issue gh-4123
+        class BuggySequence(object):
+            def __len__(self):
+                return 4
+
+            def __getitem__(self, key):
+                raise KeyError
+
+        assert_raises(KeyError, np.lexsort, BuggySequence())
+
+    def test_pickle_py2_bytes_encoding(self):
+        # Check that arrays and scalars pickled on Py2 are
+        # unpickleable on Py3 using encoding='bytes'
+
+        test_data = [
+            # (original, py2_pickle)
+            (np.unicode_('\u6f2c'),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+                     "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\n"
+                     "I0\ntp6\nbS',o\\x00\\x00'\np7\ntp8\nRp9\n.")),
+
+            (np.array([9e123], dtype=np.float64),
+             asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\n"
+                     "p1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\n"
+                     "p7\n(S'f8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'<'\np11\nNNNI-1\nI-1\n"
+                     "I0\ntp12\nbI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np13\ntp14\nb.")),
+
+            (np.array([(9e123,)], dtype=[('name', float)]),
+             asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n"
+                     "(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n"
+                     "(S'V8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'name'\np12\ntp13\n"
+                     "(dp14\ng12\n(g7\n(S'f8'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'<'\np18\nNNNI-1\n"
+                     "I-1\nI0\ntp19\nbI0\ntp20\nsI8\nI1\nI0\ntp21\n"
+                     "bI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np22\ntp23\nb.")),
+        ]
+
+        if sys.version_info[:2] >= (3, 4):
+            # encoding='bytes' was added in Py3.4
+            for original, data in test_data:
+                result = pickle.loads(data, encoding='bytes')
+                assert_equal(result, original)
+
+                if isinstance(result, np.ndarray) and result.dtype.names:
+                    for name in result.dtype.names:
+                        assert_(isinstance(name, str))
+
+    def test_pickle_dtype(self,level=rlevel):
+        # Ticket #251
+        pickle.dumps(np.float)
+
+    def test_swap_real(self, level=rlevel):
+        # Ticket #265
+        assert_equal(np.arange(4, dtype='>c8').imag.max(), 0.0)
+        assert_equal(np.arange(4, dtype='<c8').imag.max(), 0.0)
+        assert_equal(np.arange(4, dtype='>c8').real.max(), 3.0)
+        assert_equal(np.arange(4, dtype='<c8').real.max(), 3.0)
+
+    def test_object_array_from_list(self, level=rlevel):
+        # Ticket #270
+        np.array([1, 'A', None])  # Should succeed
+
+    def test_multiple_assign(self, level=rlevel):
+        # Ticket #273
+        a = np.zeros((3, 1), int)
+        a[[1, 2]] = 1
+
+    def test_empty_array_type(self, level=rlevel):
+        assert_equal(np.array([]).dtype, np.zeros(0).dtype)
+
+    def test_void_copyswap(self, level=rlevel):
+        dt = np.dtype([('one', '<i4'), ('two', '<i4')])
+        x = np.array((1, 2), dtype=dt)
+        x = x.byteswap()
+        assert_(x['one'] > 1 and x['two'] > 2)
+
+    def test_method_args(self, level=rlevel):
+        # Make sure methods and functions have same default axis
+        # keyword and arguments
+        funcs1 = ['argmax', 'argmin', 'sum', ('product', 'prod'),
+                 ('sometrue', 'any'),
+                 ('alltrue', 'all'), 'cumsum', ('cumproduct', 'cumprod'),
+                 'ptp', 'cumprod', 'prod', 'std', 'var', 'mean',
+                 'round', 'min', 'max', 'argsort', 'sort']
+        funcs2 = ['compress', 'take', 'repeat']
+
+        for func in funcs1:
+            arr = np.random.rand(8, 7)
+            arr2 = arr.copy()
+            if isinstance(func, tuple):
+                func_meth = func[1]
+                func = func[0]
+            else:
+                func_meth = func
+            res1 = getattr(arr, func_meth)()
+            res2 = getattr(np, func)(arr2)
+            if res1 is None:
+                res1 = arr
+
+            if res1.dtype.kind in 'uib':
+                assert_((res1 == res2).all(), func)
+            else:
+                assert_(abs(res1-res2).max() < 1e-8, func)
+
+        for func in funcs2:
+            arr1 = np.random.rand(8, 7)
+            arr2 = np.random.rand(8, 7)
+            res1 = None
+            if func == 'compress':
+                arr1 = arr1.ravel()
+                res1 = getattr(arr2, func)(arr1)
+            else:
+                arr2 = (15*arr2).astype(int).ravel()
+            if res1 is None:
+                res1 = getattr(arr1, func)(arr2)
+            res2 = getattr(np, func)(arr1, arr2)
+            assert_(abs(res1-res2).max() < 1e-8, func)
+
+    def test_mem_lexsort_strings(self, level=rlevel):
+        # Ticket #298
+        lst = ['abc', 'cde', 'fgh']
+        np.lexsort((lst,))
+
+    def test_fancy_index(self, level=rlevel):
+        # Ticket #302
+        x = np.array([1, 2])[np.array([0])]
+        assert_equal(x.shape, (1,))
+
+    def test_recarray_copy(self, level=rlevel):
+        # Ticket #312
+        dt = [('x', np.int16), ('y', np.float64)]
+        ra = np.array([(1, 2.3)], dtype=dt)
+        rb = np.rec.array(ra, dtype=dt)
+        rb['x'] = 2.
+        assert_(ra['x'] != rb['x'])
+
+    def test_rec_fromarray(self, level=rlevel):
+        # Ticket #322
+        x1 = np.array([[1, 2], [3, 4], [5, 6]])
+        x2 = np.array(['a', 'dd', 'xyz'])
+        x3 = np.array([1.1, 2, 3])
+        np.rec.fromarrays([x1, x2, x3], formats="(2,)i4,a3,f8")
+
+    def test_object_array_assign(self, level=rlevel):
+        x = np.empty((2, 2), object)
+        x.flat[2] = (1, 2, 3)
+        assert_equal(x.flat[2], (1, 2, 3))
+
+    def test_ndmin_float64(self, level=rlevel):
+        # Ticket #324
+        x = np.array([1, 2, 3], dtype=np.float64)
+        assert_equal(np.array(x, dtype=np.float32, ndmin=2).ndim, 2)
+        assert_equal(np.array(x, dtype=np.float64, ndmin=2).ndim, 2)
+
+    def test_ndmin_order(self, level=rlevel):
+        # Issue #465 and related checks
+        assert_(np.array([1, 2], order='C', ndmin=3).flags.c_contiguous)
+        assert_(np.array([1, 2], order='F', ndmin=3).flags.f_contiguous)
+        assert_(np.array(np.ones((2, 2), order='F'), ndmin=3).flags.f_contiguous)
+        assert_(np.array(np.ones((2, 2), order='C'), ndmin=3).flags.c_contiguous)
+
+    def test_mem_axis_minimization(self, level=rlevel):
+        # Ticket #327
+        data = np.arange(5)
+        data = np.add.outer(data, data)
+
+    def test_mem_float_imag(self, level=rlevel):
+        # Ticket #330
+        np.float64(1.0).imag
+
+    def test_dtype_tuple(self, level=rlevel):
+        # Ticket #334
+        assert_(np.dtype('i4') == np.dtype(('i4', ())))
+
+    def test_dtype_posttuple(self, level=rlevel):
+        # Ticket #335
+        np.dtype([('col1', '()i4')])
+
+    def test_numeric_carray_compare(self, level=rlevel):
+        # Ticket #341
+        assert_equal(np.array(['X'], 'c'), asbytes('X'))
+
+    def test_string_array_size(self, level=rlevel):
+        # Ticket #342
+        self.assertRaises(ValueError,
+                              np.array, [['X'], ['X', 'X', 'X']], '|S1')
+
+    def test_dtype_repr(self, level=rlevel):
+        # Ticket #344
+        dt1 = np.dtype(('uint32', 2))
+        dt2 = np.dtype(('uint32', (2,)))
+        assert_equal(dt1.__repr__(), dt2.__repr__())
+
+    def test_reshape_order(self, level=rlevel):
+        # Make sure reshape order works.
+        a = np.arange(6).reshape(2, 3, order='F')
+        assert_equal(a, [[0, 2, 4], [1, 3, 5]])
+        a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
+        b = a[:, 1]
+        assert_equal(b.reshape(2, 2, order='F'), [[2, 6], [4, 8]])
+
+    def test_reshape_zero_strides(self, level=rlevel):
+        # Issue #380, test reshaping of zero strided arrays
+        a = np.ones(1)
+        a = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(0,))
+        assert_(a.reshape(5, 1).strides[0] == 0)
+
+    def test_reshape_zero_size(self, level=rlevel):
+        # GitHub Issue #2700, setting shape failed for 0-sized arrays
+        a = np.ones((0, 2))
+        a.shape = (-1, 2)
+
+    # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides.
+    # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous.
+    @dec.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max)
+    def test_reshape_trailing_ones_strides(self):
+        # GitHub issue gh-2949, bad strides for trailing ones of new shape
+        a = np.zeros(12, dtype=np.int32)[::2]  # not contiguous
+        strides_c = (16, 8, 8, 8)
+        strides_f = (8, 24, 48, 48)
+        assert_equal(a.reshape(3, 2, 1, 1).strides, strides_c)
+        assert_equal(a.reshape(3, 2, 1, 1, order='F').strides, strides_f)
+        assert_equal(np.array(0, dtype=np.int32).reshape(1, 1).strides, (4, 4))
+
+    def test_repeat_discont(self, level=rlevel):
+        # Ticket #352
+        a = np.arange(12).reshape(4, 3)[:, 2]
+        assert_equal(a.repeat(3), [2, 2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11])
+
+    def test_array_index(self, level=rlevel):
+        # Make sure optimization is not called in this case.
+        a = np.array([1, 2, 3])
+        a2 = np.array([[1, 2, 3]])
+        assert_equal(a[np.where(a == 3)], a2[np.where(a2 == 3)])
+
+    def test_object_argmax(self, level=rlevel):
+        a = np.array([1, 2, 3], dtype=object)
+        assert_(a.argmax() == 2)
+
+    def test_recarray_fields(self, level=rlevel):
+        # Ticket #372
+        dt0 = np.dtype([('f0', 'i4'), ('f1', 'i4')])
+        dt1 = np.dtype([('f0', 'i8'), ('f1', 'i8')])
+        for a in [np.array([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.array([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.array([(1, 2), (3, 4)]),
+                  np.rec.fromarrays([(1, 2), (3, 4)], "i4,i4"),
+                  np.rec.fromarrays([(1, 2), (3, 4)])]:
+            assert_(a.dtype in [dt0, dt1])
+
+    def test_random_shuffle(self, level=rlevel):
+        # Ticket #374
+        a = np.arange(5).reshape((5, 1))
+        b = a.copy()
+        np.random.shuffle(b)
+        assert_equal(np.sort(b, axis=0), a)
+
+    def test_refcount_vdot(self, level=rlevel):
+        # Changeset #3443
+        _assert_valid_refcount(np.vdot)
+
+    def test_startswith(self, level=rlevel):
+        ca = np.char.array(['Hi', 'There'])
+        assert_equal(ca.startswith('H'), [True, False])
+
+    def test_noncommutative_reduce_accumulate(self, level=rlevel):
+        # Ticket #413
+        tosubtract = np.arange(5)
+        todivide = np.array([2.0, 0.5, 0.25])
+        assert_equal(np.subtract.reduce(tosubtract), -10)
+        assert_equal(np.divide.reduce(todivide), 16.0)
+        assert_array_equal(np.subtract.accumulate(tosubtract),
+            np.array([0, -1, -3, -6, -10]))
+        assert_array_equal(np.divide.accumulate(todivide),
+            np.array([2., 4., 16.]))
+
+    def test_convolve_empty(self, level=rlevel):
+        # Convolve should raise an error for empty input array.
+        self.assertRaises(ValueError, np.convolve, [], [1])
+        self.assertRaises(ValueError, np.convolve, [1], [])
+
+    def test_multidim_byteswap(self, level=rlevel):
+        # Ticket #449
+        r = np.array([(1, (0, 1, 2))], dtype="i2,3i2")
+        assert_array_equal(r.byteswap(),
+                           np.array([(256, (0, 256, 512))], r.dtype))
+
+    def test_string_NULL(self, level=rlevel):
+        # Changeset 3557
+        assert_equal(np.array("a\x00\x0b\x0c\x00").item(),
+                     'a\x00\x0b\x0c')
+
+    def test_junk_in_string_fields_of_recarray(self, level=rlevel):
+        # Ticket #483
+        r = np.array([[asbytes('abc')]], dtype=[('var1', '|S20')])
+        assert_(asbytes(r['var1'][0][0]) == asbytes('abc'))
+
+    def test_take_output(self, level=rlevel):
+        # Ensure that 'take' honours output parameter.
+        x = np.arange(12).reshape((3, 4))
+        a = np.take(x, [0, 2], axis=1)
+        b = np.zeros_like(a)
+        np.take(x, [0, 2], axis=1, out=b)
+        assert_array_equal(a, b)
+
+    def test_take_object_fail(self):
+        # Issue gh-3001
+        d = 123.
+        a = np.array([d, 1], dtype=object)
+        ref_d = sys.getrefcount(d)
+        try:
+            a.take([0, 100])
+        except IndexError:
+            pass
+        assert_(ref_d == sys.getrefcount(d))
+
+    def test_array_str_64bit(self, level=rlevel):
+        # Ticket #501
+        s = np.array([1, np.nan], dtype=np.float64)
+        with np.errstate(all='raise'):
+            np.array_str(s)  # Should succeed
+
+    def test_frompyfunc_endian(self, level=rlevel):
+        # Ticket #503
+        from math import radians
+        uradians = np.frompyfunc(radians, 1, 1)
+        big_endian = np.array([83.4, 83.5], dtype='>f8')
+        little_endian = np.array([83.4, 83.5], dtype='<f8')
+        assert_almost_equal(uradians(big_endian).astype(float),
+                            uradians(little_endian).astype(float))
+
+    def test_mem_string_arr(self, level=rlevel):
+        # Ticket #514
+        s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        t = []
+        np.hstack((t, s))
+
+    def test_arr_transpose(self, level=rlevel):
+        # Ticket #516
+        x = np.random.rand(*(2,)*16)
+        x.transpose(list(range(16)))  # Should succeed
+
+    def test_string_mergesort(self, level=rlevel):
+        # Ticket #540
+        x = np.array(['a']*32)
+        assert_array_equal(x.argsort(kind='m'), np.arange(32))
+
+    def test_argmax_byteorder(self, level=rlevel):
+        # Ticket #546
+        a = np.arange(3, dtype='>f')
+        assert_(a[a.argmax()] == a.max())
+
+    def test_rand_seed(self, level=rlevel):
+        # Ticket #555
+        for l in np.arange(4):
+            np.random.seed(l)
+
+    def test_mem_deallocation_leak(self, level=rlevel):
+        # Ticket #562
+        a = np.zeros(5, dtype=float)
+        b = np.array(a, dtype=float)
+        del a, b
+
+    def test_mem_on_invalid_dtype(self):
+        "Ticket #583"
+        self.assertRaises(ValueError, np.fromiter, [['12', ''], ['13', '']], str)
+
+    def test_dot_negative_stride(self, level=rlevel):
+        # Ticket #588
+        x = np.array([[1, 5, 25, 125., 625]])
+        y = np.array([[20.], [160.], [640.], [1280.], [1024.]])
+        z = y[::-1].copy()
+        y2 = y[::-1]
+        assert_equal(np.dot(x, z), np.dot(x, y2))
+
+    def test_object_casting(self, level=rlevel):
+        # This used to trigger the object-type version of
+        # the bitwise_or operation, because float64 -> object
+        # casting succeeds
+        def rs():
+            x = np.ones([484, 286])
+            y = np.zeros([484, 286])
+            x |= y
+
+        self.assertRaises(TypeError, rs)
+
+    def test_unicode_scalar(self, level=rlevel):
+        # Ticket #600
+        x = np.array(["DROND", "DROND1"], dtype="U6")
+        el = x[1]
+        new = pickle.loads(pickle.dumps(el))
+        assert_equal(new, el)
+
+    def test_arange_non_native_dtype(self, level=rlevel):
+        # Ticket #616
+        for T in ('>f4', '<f4'):
+            dt = np.dtype(T)
+            assert_equal(np.arange(0, dtype=dt).dtype, dt)
+            assert_equal(np.arange(0.5, dtype=dt).dtype, dt)
+            assert_equal(np.arange(5, dtype=dt).dtype, dt)
+
+    def test_bool_flat_indexing_invalid_nr_elements(self, level=rlevel):
+        s = np.ones(10, dtype=float)
+        x = np.array((15,), dtype=float)
+
+        def ia(x, s, v):
+            x[(s > 0)] = v
+
+        # After removing deprecation, the following are ValueErrors.
+        # This might seem odd as compared to the value error below. This
+        # is due to the fact that the new code always uses "nonzero" logic
+        # and the boolean special case is not taken.
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', DeprecationWarning)
+            warnings.simplefilter('ignore', np.VisibleDeprecationWarning)
+            self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float))
+            self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float))
+        # Old special case (different code path):
+        self.assertRaises(ValueError, ia, x.flat, s, np.zeros(9, dtype=float))
+        self.assertRaises(ValueError, ia, x.flat, s, np.zeros(11, dtype=float))
+
+    def test_mem_scalar_indexing(self, level=rlevel):
+        # Ticket #603
+        x = np.array([0], dtype=float)
+        index = np.array(0, dtype=np.int32)
+        x[index]
+
+    def test_binary_repr_0_width(self, level=rlevel):
+        assert_equal(np.binary_repr(0, width=3), '000')
+
+    def test_fromstring(self, level=rlevel):
+        assert_equal(np.fromstring("12:09:09", dtype=int, sep=":"),
+                     [12, 9, 9])
+
+    def test_searchsorted_variable_length(self, level=rlevel):
+        x = np.array(['a', 'aa', 'b'])
+        y = np.array(['d', 'e'])
+        assert_equal(x.searchsorted(y), [3, 3])
+
+    def test_string_argsort_with_zeros(self, level=rlevel):
+        # Check argsort for strings containing zeros.
+        x = np.fromstring("\x00\x02\x00\x01", dtype="|S2")
+        assert_array_equal(x.argsort(kind='m'), np.array([1, 0]))
+        assert_array_equal(x.argsort(kind='q'), np.array([1, 0]))
+
+    def test_string_sort_with_zeros(self, level=rlevel):
+        # Check sort for strings containing zeros.
+        x = np.fromstring("\x00\x02\x00\x01", dtype="|S2")
+        y = np.fromstring("\x00\x01\x00\x02", dtype="|S2")
+        assert_array_equal(np.sort(x, kind="q"), y)
+
+    def test_copy_detection_zero_dim(self, level=rlevel):
+        # Ticket #658
+        np.indices((0, 3, 4)).T.reshape(-1, 3)
+
+    def test_flat_byteorder(self, level=rlevel):
+        # Ticket #657
+        x = np.arange(10)
+        assert_array_equal(x.astype('>i4'), x.astype('<i4').flat[:])
+        assert_array_equal(x.astype('>i4').flat[:], x.astype('<i4'))
+
+    def test_uint64_from_negative(self, level=rlevel):
+        assert_equal(np.uint64(-2), np.uint64(18446744073709551614))
+
+    def test_sign_bit(self, level=rlevel):
+        x = np.array([0, -0.0, 0])
+        assert_equal(str(np.abs(x)), '[ 0.  0.  0.]')
+
+    def test_flat_index_byteswap(self, level=rlevel):
+        for dt in (np.dtype('<i4'), np.dtype('>i4')):
+            x = np.array([-1, 0, 1], dtype=dt)
+            assert_equal(x.flat[0].dtype, x[0].dtype)
+
+    def test_copy_detection_corner_case(self, level=rlevel):
+        # Ticket #658
+        np.indices((0, 3, 4)).T.reshape(-1, 3)
+
+    # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides.
+    # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous,
+    # 0-sized reshape itself is tested elsewhere.
+    @dec.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max)
+    def test_copy_detection_corner_case2(self, level=rlevel):
+        # Ticket #771: strides are not set correctly when reshaping 0-sized
+        # arrays
+        b = np.indices((0, 3, 4)).T.reshape(-1, 3)
+        assert_equal(b.strides, (3 * b.itemsize, b.itemsize))
+
+    def test_object_array_refcounting(self, level=rlevel):
+        # Ticket #633
+        if not hasattr(sys, 'getrefcount'):
+            return
+
+        # NB. this is probably CPython-specific
+
+        cnt = sys.getrefcount
+
+        a = object()
+        b = object()
+        c = object()
+
+        cnt0_a = cnt(a)
+        cnt0_b = cnt(b)
+        cnt0_c = cnt(c)
+
+        # -- 0d -> 1-d broadcast slice assignment
+
+        arr = np.zeros(5, dtype=np.object_)
+
+        arr[:] = a
+        assert_equal(cnt(a), cnt0_a + 5)
+
+        arr[:] = b
+        assert_equal(cnt(a), cnt0_a)
+        assert_equal(cnt(b), cnt0_b + 5)
+
+        arr[:2] = c
+        assert_equal(cnt(b), cnt0_b + 3)
+        assert_equal(cnt(c), cnt0_c + 2)
+
+        del arr
+
+        # -- 1-d -> 2-d broadcast slice assignment
+
+        arr = np.zeros((5, 2), dtype=np.object_)
+        arr0 = np.zeros(2, dtype=np.object_)
+
+        arr0[0] = a
+        assert_(cnt(a) == cnt0_a + 1)
+        arr0[1] = b
+        assert_(cnt(b) == cnt0_b + 1)
+
+        arr[:,:] = arr0
+        assert_(cnt(a) == cnt0_a + 6)
+        assert_(cnt(b) == cnt0_b + 6)
+
+        arr[:, 0] = None
+        assert_(cnt(a) == cnt0_a + 1)
+
+        del arr, arr0
+
+        # -- 2-d copying + flattening
+
+        arr = np.zeros((5, 2), dtype=np.object_)
+
+        arr[:, 0] = a
+        arr[:, 1] = b
+        assert_(cnt(a) == cnt0_a + 5)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        arr2 = arr.copy()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 10)
+
+        arr2 = arr[:, 0].copy()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        arr2 = arr.flatten()
+        assert_(cnt(a) == cnt0_a + 10)
+        assert_(cnt(b) == cnt0_b + 10)
+
+        del arr, arr2
+
+        # -- concatenate, repeat, take, choose
+
+        arr1 = np.zeros((5, 1), dtype=np.object_)
+        arr2 = np.zeros((5, 1), dtype=np.object_)
+
+        arr1[...] = a
+        arr2[...] = b
+        assert_(cnt(a) == cnt0_a + 5)
+        assert_(cnt(b) == cnt0_b + 5)
+
+        tmp = np.concatenate((arr1, arr2))
+        assert_(cnt(a) == cnt0_a + 5 + 5)
+        assert_(cnt(b) == cnt0_b + 5 + 5)
+
+        tmp = arr1.repeat(3, axis=0)
+        assert_(cnt(a) == cnt0_a + 5 + 3*5)
+
+        tmp = arr1.take([1, 2, 3], axis=0)
+        assert_(cnt(a) == cnt0_a + 5 + 3)
+
+        x = np.array([[0], [1], [0], [1], [1]], int)
+        tmp = x.choose(arr1, arr2)
+        assert_(cnt(a) == cnt0_a + 5 + 2)
+        assert_(cnt(b) == cnt0_b + 5 + 3)
+
+        del tmp  # Avoid pyflakes unused variable warning
+
+    def test_mem_custom_float_to_array(self, level=rlevel):
+        # Ticket 702
+        class MyFloat(object):
+            def __float__(self):
+                return 1.0
+
+        tmp = np.atleast_1d([MyFloat()])
+        tmp.astype(float)  # Should succeed
+
+    def test_object_array_refcount_self_assign(self, level=rlevel):
+        # Ticket #711
+        class VictimObject(object):
+            deleted = False
+
+            def __del__(self):
+                self.deleted = True
+
+        d = VictimObject()
+        arr = np.zeros(5, dtype=np.object_)
+        arr[:] = d
+        del d
+        arr[:] = arr  # refcount of 'd' might hit zero here
+        assert_(not arr[0].deleted)
+        arr[:] = arr  # trying to induce a segfault by doing it again...
+        assert_(not arr[0].deleted)
+
+    def test_mem_fromiter_invalid_dtype_string(self, level=rlevel):
+        x = [1, 2, 3]
+        self.assertRaises(ValueError,
+                              np.fromiter, [xi for xi in x], dtype='S')
+
+    def test_reduce_big_object_array(self, level=rlevel):
+        # Ticket #713
+        oldsize = np.setbufsize(10*16)
+        a = np.array([None]*161, object)
+        assert_(not np.any(a))
+        np.setbufsize(oldsize)
+
+    def test_mem_0d_array_index(self, level=rlevel):
+        # Ticket #714
+        np.zeros(10)[np.array(0)]
+
+    def test_floats_from_string(self, level=rlevel):
+        # Ticket #640, floats from string
+        fsingle = np.single('1.234')
+        fdouble = np.double('1.234')
+        flongdouble = np.longdouble('1.234')
+        assert_almost_equal(fsingle, 1.234)
+        assert_almost_equal(fdouble, 1.234)
+        assert_almost_equal(flongdouble, 1.234)
+
+    def test_nonnative_endian_fill(self, level=rlevel):
+        # Non-native endian arrays were incorrectly filled with scalars
+        # before r5034.
+        if sys.byteorder == 'little':
+            dtype = np.dtype('>i4')
+        else:
+            dtype = np.dtype('<i4')
+        x = np.empty([1], dtype=dtype)
+        x.fill(1)
+        assert_equal(x, np.array([1], dtype=dtype))
+
+    def test_dot_alignment_sse2(self, level=rlevel):
+        # Test for ticket #551, changeset r5140
+        x = np.zeros((30, 40))
+        y = pickle.loads(pickle.dumps(x))
+        # y is now typically not aligned on a 8-byte boundary
+        z = np.ones((1, y.shape[0]))
+        # This shouldn't cause a segmentation fault:
+        np.dot(z, y)
+
+    def test_astype_copy(self, level=rlevel):
+        # Ticket #788, changeset r5155
+        # The test data file was generated by scipy.io.savemat.
+        # The dtype is float64, but the isbuiltin attribute is 0.
+        data_dir = path.join(path.dirname(__file__), 'data')
+        filename = path.join(data_dir, "astype_copy.pkl")
+        if sys.version_info[0] >= 3:
+            f = open(filename, 'rb')
+            xp = pickle.load(f, encoding='latin1')
+            f.close()
+        else:
+            f = open(filename)
+            xp = pickle.load(f)
+            f.close()
+        xpd = xp.astype(np.float64)
+        assert_((xp.__array_interface__['data'][0] !=
+                xpd.__array_interface__['data'][0]))
+
+    def test_compress_small_type(self, level=rlevel):
+        # Ticket #789, changeset 5217.
+        # compress with out argument segfaulted if cannot cast safely
+        import numpy as np
+        a = np.array([[1, 2], [3, 4]])
+        b = np.zeros((2, 1), dtype=np.single)
+        try:
+            a.compress([True, False], axis=1, out=b)
+            raise AssertionError("compress with an out which cannot be "
+                                 "safely casted should not return "
+                                 "successfully")
+        except TypeError:
+            pass
+
+    def test_attributes(self, level=rlevel):
+        # Ticket #791
+        class TestArray(np.ndarray):
+            def __new__(cls, data, info):
+                result = np.array(data)
+                result = result.view(cls)
+                result.info = info
+                return result
+
+            def __array_finalize__(self, obj):
+                self.info = getattr(obj, 'info', '')
+
+        dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
+        assert_(dat.info == 'jubba')
+        dat.resize((4, 2))
+        assert_(dat.info == 'jubba')
+        dat.sort()
+        assert_(dat.info == 'jubba')
+        dat.fill(2)
+        assert_(dat.info == 'jubba')
+        dat.put([2, 3, 4], [6, 3, 4])
+        assert_(dat.info == 'jubba')
+        dat.setfield(4, np.int32, 0)
+        assert_(dat.info == 'jubba')
+        dat.setflags()
+        assert_(dat.info == 'jubba')
+        assert_(dat.all(1).info == 'jubba')
+        assert_(dat.any(1).info == 'jubba')
+        assert_(dat.argmax(1).info == 'jubba')
+        assert_(dat.argmin(1).info == 'jubba')
+        assert_(dat.argsort(1).info == 'jubba')
+        assert_(dat.astype(TestArray).info == 'jubba')
+        assert_(dat.byteswap().info == 'jubba')
+        assert_(dat.clip(2, 7).info == 'jubba')
+        assert_(dat.compress([0, 1, 1]).info == 'jubba')
+        assert_(dat.conj().info == 'jubba')
+        assert_(dat.conjugate().info == 'jubba')
+        assert_(dat.copy().info == 'jubba')
+        dat2 = TestArray([2, 3, 1, 0], 'jubba')
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        assert_(dat2.choose(choices).info == 'jubba')
+        assert_(dat.cumprod(1).info == 'jubba')
+        assert_(dat.cumsum(1).info == 'jubba')
+        assert_(dat.diagonal().info == 'jubba')
+        assert_(dat.flatten().info == 'jubba')
+        assert_(dat.getfield(np.int32, 0).info == 'jubba')
+        assert_(dat.imag.info == 'jubba')
+        assert_(dat.max(1).info == 'jubba')
+        assert_(dat.mean(1).info == 'jubba')
+        assert_(dat.min(1).info == 'jubba')
+        assert_(dat.newbyteorder().info == 'jubba')
+        assert_(dat.prod(1).info == 'jubba')
+        assert_(dat.ptp(1).info == 'jubba')
+        assert_(dat.ravel().info == 'jubba')
+        assert_(dat.real.info == 'jubba')
+        assert_(dat.repeat(2).info == 'jubba')
+        assert_(dat.reshape((2, 4)).info == 'jubba')
+        assert_(dat.round().info == 'jubba')
+        assert_(dat.squeeze().info == 'jubba')
+        assert_(dat.std(1).info == 'jubba')
+        assert_(dat.sum(1).info == 'jubba')
+        assert_(dat.swapaxes(0, 1).info == 'jubba')
+        assert_(dat.take([2, 3, 5]).info == 'jubba')
+        assert_(dat.transpose().info == 'jubba')
+        assert_(dat.T.info == 'jubba')
+        assert_(dat.var(1).info == 'jubba')
+        assert_(dat.view(TestArray).info == 'jubba')
+        # These methods do not preserve subclasses
+        assert_(type(dat.nonzero()[0]) is np.ndarray)
+        assert_(type(dat.nonzero()[1]) is np.ndarray)
+
+    def test_recarray_tolist(self, level=rlevel):
+        # Ticket #793, changeset r5215
+        # Comparisons fail for NaN, so we can't use random memory
+        # for the test.
+        buf = np.zeros(40, dtype=np.int8)
+        a = np.recarray(2, formats="i4,f8,f8", names="id,x,y", buf=buf)
+        b = a.tolist()
+        assert_( a[0].tolist() == b[0])
+        assert_( a[1].tolist() == b[1])
+
+    def test_nonscalar_item_method(self):
+        # Make sure that .item() fails graciously when it should
+        a = np.arange(5)
+        assert_raises(ValueError, a.item)
+
+    def test_char_array_creation(self, level=rlevel):
+        a = np.array('123', dtype='c')
+        b = np.array(asbytes_nested(['1', '2', '3']))
+        assert_equal(a, b)
+
+    def test_unaligned_unicode_access(self, level=rlevel):
+        # Ticket #825
+        for i in range(1, 9):
+            msg = 'unicode offset: %d chars' % i
+            t = np.dtype([('a', 'S%d' % i), ('b', 'U2')])
+            x = np.array([(asbytes('a'), sixu('b'))], dtype=t)
+            if sys.version_info[0] >= 3:
+                assert_equal(str(x), "[(b'a', 'b')]", err_msg=msg)
+            else:
+                assert_equal(str(x), "[('a', u'b')]", err_msg=msg)
+
+    def test_sign_for_complex_nan(self, level=rlevel):
+        # Ticket 794.
+        with np.errstate(invalid='ignore'):
+            C = np.array([-np.inf, -2+1j, 0, 2-1j, np.inf, np.nan])
+            have = np.sign(C)
+            want = np.array([-1+0j, -1+0j, 0+0j, 1+0j, 1+0j, np.nan])
+            assert_equal(have, want)
+
+    def test_for_equal_names(self, level=rlevel):
+        # Ticket #674
+        dt = np.dtype([('foo', float), ('bar', float)])
+        a = np.zeros(10, dt)
+        b = list(a.dtype.names)
+        b[0] = "notfoo"
+        a.dtype.names = b
+        assert_(a.dtype.names[0] == "notfoo")
+        assert_(a.dtype.names[1] == "bar")
+
+    def test_for_object_scalar_creation(self, level=rlevel):
+        # Ticket #816
+        a = np.object_()
+        b = np.object_(3)
+        b2 = np.object_(3.0)
+        c = np.object_([4, 5])
+        d = np.object_([None, {}, []])
+        assert_(a is None)
+        assert_(type(b) is int)
+        assert_(type(b2) is float)
+        assert_(type(c) is np.ndarray)
+        assert_(c.dtype == object)
+        assert_(d.dtype == object)
+
+    def test_array_resize_method_system_error(self):
+        # Ticket #840 - order should be an invalid keyword.
+        x = np.array([[0, 1], [2, 3]])
+        self.assertRaises(TypeError, x.resize, (2, 2), order='C')
+
+    def test_for_zero_length_in_choose(self, level=rlevel):
+        "Ticket #882"
+        a = np.array(1)
+        self.assertRaises(ValueError, lambda x: x.choose([]), a)
+
+    def test_array_ndmin_overflow(self):
+        "Ticket #947."
+        self.assertRaises(ValueError, lambda: np.array([1], ndmin=33))
+
+    def test_errobj_reference_leak(self, level=rlevel):
+        # Ticket #955
+        with np.errstate(all="ignore"):
+            z = int(0)
+            p = np.int32(-1)
+
+            gc.collect()
+            n_before = len(gc.get_objects())
+            z**p  # this shouldn't leak a reference to errobj
+            gc.collect()
+            n_after = len(gc.get_objects())
+            assert_(n_before >= n_after, (n_before, n_after))
+
+    def test_void_scalar_with_titles(self, level=rlevel):
+        # No ticket
+        data = [('john', 4), ('mary', 5)]
+        dtype1 = [(('source:yy', 'name'), 'O'), (('source:xx', 'id'), int)]
+        arr = np.array(data, dtype=dtype1)
+        assert_(arr[0][0] == 'john')
+        assert_(arr[0][1] == 4)
+
+    def test_void_scalar_constructor(self):
+        #Issue #1550
+
+        #Create test string data, construct void scalar from data and assert
+        #that void scalar contains original data.
+        test_string = np.array("test")
+        test_string_void_scalar = np.core.multiarray.scalar(
+            np.dtype(("V", test_string.dtype.itemsize)), test_string.tobytes())
+
+        assert_(test_string_void_scalar.view(test_string.dtype) == test_string)
+
+        #Create record scalar, construct from data and assert that
+        #reconstructed scalar is correct.
+        test_record = np.ones((), "i,i")
+        test_record_void_scalar = np.core.multiarray.scalar(
+            test_record.dtype, test_record.tobytes())
+
+        assert_(test_record_void_scalar == test_record)
+
+        #Test pickle and unpickle of void and record scalars
+        assert_(pickle.loads(pickle.dumps(test_string)) == test_string)
+        assert_(pickle.loads(pickle.dumps(test_record)) == test_record)
+
+    def test_blasdot_uninitialized_memory(self):
+        # Ticket #950
+        for m in [0, 1, 2]:
+            for n in [0, 1, 2]:
+                for k in range(3):
+                    # Try to ensure that x->data contains non-zero floats
+                    x = np.array([123456789e199], dtype=np.float64)
+                    x.resize((m, 0))
+                    y = np.array([123456789e199], dtype=np.float64)
+                    y.resize((0, n))
+
+                    # `dot` should just return zero (m,n) matrix
+                    z = np.dot(x, y)
+                    assert_(np.all(z == 0))
+                    assert_(z.shape == (m, n))
+
+    def test_zeros(self):
+        # Regression test for #1061.
+        # Set a size which cannot fit into a 64 bits signed integer
+        sz = 2 ** 64
+        good = 'Maximum allowed dimension exceeded'
+        try:
+            np.empty(sz)
+        except ValueError as e:
+            if not str(e) == good:
+                self.fail("Got msg '%s', expected '%s'" % (e, good))
+        except Exception as e:
+            self.fail("Got exception of type %s instead of ValueError" % type(e))
+
+    def test_huge_arange(self):
+        # Regression test for #1062.
+        # Set a size which cannot fit into a 64 bits signed integer
+        sz = 2 ** 64
+        good = 'Maximum allowed size exceeded'
+        try:
+            np.arange(sz)
+            self.assertTrue(np.size == sz)
+        except ValueError as e:
+            if not str(e) == good:
+                self.fail("Got msg '%s', expected '%s'" % (e, good))
+        except Exception as e:
+            self.fail("Got exception of type %s instead of ValueError" % type(e))
+
+    def test_fromiter_bytes(self):
+        # Ticket #1058
+        a = np.fromiter(list(range(10)), dtype='b')
+        b = np.fromiter(list(range(10)), dtype='B')
+        assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+        assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+
+    def test_array_from_sequence_scalar_array(self):
+        # Ticket #1078: segfaults when creating an array with a sequence of
+        # 0d arrays.
+        a = np.array((np.ones(2), np.array(2)))
+        assert_equal(a.shape, (2,))
+        assert_equal(a.dtype, np.dtype(object))
+        assert_equal(a[0], np.ones(2))
+        assert_equal(a[1], np.array(2))
+
+        a = np.array(((1,), np.array(1)))
+        assert_equal(a.shape, (2,))
+        assert_equal(a.dtype, np.dtype(object))
+        assert_equal(a[0], (1,))
+        assert_equal(a[1], np.array(1))
+
+    def test_array_from_sequence_scalar_array2(self):
+        # Ticket #1081: weird array with strange input...
+        t = np.array([np.array([]), np.array(0, object)])
+        assert_equal(t.shape, (2,))
+        assert_equal(t.dtype, np.dtype(object))
+
+    def test_array_too_big(self):
+        # Ticket #1080.
+        assert_raises(ValueError, np.zeros, [975]*7, np.int8)
+        assert_raises(ValueError, np.zeros, [26244]*5, np.int8)
+
+    def test_dtype_keyerrors_(self):
+        # Ticket #1106.
+        dt = np.dtype([('f1', np.uint)])
+        assert_raises(KeyError, dt.__getitem__, "f2")
+        assert_raises(IndexError, dt.__getitem__, 1)
+        assert_raises(ValueError, dt.__getitem__, 0.0)
+
+    def test_lexsort_buffer_length(self):
+        # Ticket #1217, don't segfault.
+        a = np.ones(100, dtype=np.int8)
+        b = np.ones(100, dtype=np.int32)
+        i = np.lexsort((a[::-1], b))
+        assert_equal(i, np.arange(100, dtype=np.int))
+
+    def test_object_array_to_fixed_string(self):
+        # Ticket #1235.
+        a = np.array(['abcdefgh', 'ijklmnop'], dtype=np.object_)
+        b = np.array(a, dtype=(np.str_, 8))
+        assert_equal(a, b)
+        c = np.array(a, dtype=(np.str_, 5))
+        assert_equal(c, np.array(['abcde', 'ijklm']))
+        d = np.array(a, dtype=(np.str_, 12))
+        assert_equal(a, d)
+        e = np.empty((2, ), dtype=(np.str_, 8))
+        e[:] = a[:]
+        assert_equal(a, e)
+
+    def test_unicode_to_string_cast(self):
+        # Ticket #1240.
+        a = np.array([[sixu('abc'), sixu('\u03a3')],
+                      [sixu('asdf'), sixu('erw')]],
+                     dtype='U')
+        self.assertRaises(UnicodeEncodeError, np.array, a, 'S4')
+
+    def test_mixed_string_unicode_array_creation(self):
+        a = np.array(['1234', sixu('123')])
+        assert_(a.itemsize == 16)
+        a = np.array([sixu('123'), '1234'])
+        assert_(a.itemsize == 16)
+        a = np.array(['1234', sixu('123'), '12345'])
+        assert_(a.itemsize == 20)
+        a = np.array([sixu('123'), '1234', sixu('12345')])
+        assert_(a.itemsize == 20)
+        a = np.array([sixu('123'), '1234', sixu('1234')])
+        assert_(a.itemsize == 16)
+
+    def test_misaligned_objects_segfault(self):
+        # Ticket #1198 and #1267
+        a1 = np.zeros((10,), dtype='O,c')
+        a2 = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 'S10')
+        a1['f0'] = a2
+        repr(a1)
+        np.argmax(a1['f0'])
+        a1['f0'][1] = "FOO"
+        a1['f0'] = "FOO"
+        np.array(a1['f0'], dtype='S')
+        np.nonzero(a1['f0'])
+        a1.sort()
+        copy.deepcopy(a1)
+
+    def test_misaligned_scalars_segfault(self):
+        # Ticket #1267
+        s1 = np.array(('a', 'Foo'), dtype='c,O')
+        s2 = np.array(('b', 'Bar'), dtype='c,O')
+        s1['f1'] = s2['f1']
+        s1['f1'] = 'Baz'
+
+    def test_misaligned_dot_product_objects(self):
+        # Ticket #1267
+        # This didn't require a fix, but it's worth testing anyway, because
+        # it may fail if .dot stops enforcing the arrays to be BEHAVED
+        a = np.array([[(1, 'a'), (0, 'a')], [(0, 'a'), (1, 'a')]], dtype='O,c')
+        b = np.array([[(4, 'a'), (1, 'a')], [(2, 'a'), (2, 'a')]], dtype='O,c')
+        np.dot(a['f0'], b['f0'])
+
+    def test_byteswap_complex_scalar(self):
+        # Ticket #1259 and gh-441
+        for dtype in [np.dtype('<'+t) for t in np.typecodes['Complex']]:
+            z = np.array([2.2-1.1j], dtype)
+            x = z[0]  # always native-endian
+            y = x.byteswap()
+            if x.dtype.byteorder == z.dtype.byteorder:
+                # little-endian machine
+                assert_equal(x, np.fromstring(y.tobytes(), dtype=dtype.newbyteorder()))
+            else:
+                # big-endian machine
+                assert_equal(x, np.fromstring(y.tobytes(), dtype=dtype))
+            # double check real and imaginary parts:
+            assert_equal(x.real, y.real.byteswap())
+            assert_equal(x.imag, y.imag.byteswap())
+
+    def test_structured_arrays_with_objects1(self):
+        # Ticket #1299
+        stra = 'aaaa'
+        strb = 'bbbb'
+        x = np.array([[(0, stra), (1, strb)]], 'i8,O')
+        x[x.nonzero()] = x.ravel()[:1]
+        assert_(x[0, 1] == x[0, 0])
+
+    def test_structured_arrays_with_objects2(self):
+        # Ticket #1299 second test
+        stra = 'aaaa'
+        strb = 'bbbb'
+        numb = sys.getrefcount(strb)
+        numa = sys.getrefcount(stra)
+        x = np.array([[(0, stra), (1, strb)]], 'i8,O')
+        x[x.nonzero()] = x.ravel()[:1]
+        assert_(sys.getrefcount(strb) == numb)
+        assert_(sys.getrefcount(stra) == numa + 2)
+
+    def test_duplicate_title_and_name(self):
+        # Ticket #1254
+        dtspec = [(('a', 'a'), 'i'), ('b', 'i')]
+        self.assertRaises(ValueError, np.dtype, dtspec)
+
+    def test_signed_integer_division_overflow(self):
+        # Ticket #1317.
+        def test_type(t):
+            min = np.array([np.iinfo(t).min])
+            min //= -1
+
+        with np.errstate(divide="ignore"):
+            for t in (np.int8, np.int16, np.int32, np.int64, np.int, np.long):
+                test_type(t)
+
+    def test_buffer_hashlib(self):
+        try:
+            from hashlib import md5
+        except ImportError:
+            from md5 import new as md5
+
+        x = np.array([1, 2, 3], dtype=np.dtype('<i4'))
+        assert_equal(md5(x).hexdigest(), '2a1dd1e1e59d0a384c26951e316cd7e6')
+
+    def test_0d_string_scalar(self):
+        # Bug #1436; the following should succeed
+        np.asarray('x', '>c')
+
+    def test_log1p_compiler_shenanigans(self):
+        # Check if log1p is behaving on 32 bit intel systems.
+        assert_(np.isfinite(np.log1p(np.exp2(-53))))
+
+    def test_fromiter_comparison(self, level=rlevel):
+        a = np.fromiter(list(range(10)), dtype='b')
+        b = np.fromiter(list(range(10)), dtype='B')
+        assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+        assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])))
+
+    def test_fromstring_crash(self):
+        # Ticket #1345: the following should not cause a crash
+        np.fromstring(asbytes('aa, aa, 1.0'), sep=',')
+
+    def test_ticket_1539(self):
+        dtypes = [x for x in np.typeDict.values()
+                  if (issubclass(x, np.number)
+                      and not issubclass(x, np.timedelta64))]
+        a = np.array([], dtypes[0])
+        failures = []
+        # ignore complex warnings
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', np.ComplexWarning)
+            for x in dtypes:
+                b = a.astype(x)
+                for y in dtypes:
+                    c = a.astype(y)
+                    try:
+                        np.dot(b, c)
+                    except TypeError:
+                        failures.append((x, y))
+        if failures:
+            raise AssertionError("Failures: %r" % failures)
+
+    def test_ticket_1538(self):
+        x = np.finfo(np.float32)
+        for name in 'eps epsneg max min resolution tiny'.split():
+            assert_equal(type(getattr(x, name)), np.float32,
+                         err_msg=name)
+
+    def test_ticket_1434(self):
+        # Check that the out= argument in var and std has an effect
+        data = np.array(((1, 2, 3), (4, 5, 6), (7, 8, 9)))
+        out = np.zeros((3,))
+
+        ret = data.var(axis=1, out=out)
+        assert_(ret is out)
+        assert_array_equal(ret, data.var(axis=1))
+
+        ret = data.std(axis=1, out=out)
+        assert_(ret is out)
+        assert_array_equal(ret, data.std(axis=1))
+
+    def test_complex_nan_maximum(self):
+        cnan = complex(0, np.nan)
+        assert_equal(np.maximum(1, cnan), cnan)
+
+    def test_subclass_int_tuple_assignment(self):
+        # ticket #1563
+        class Subclass(np.ndarray):
+            def __new__(cls, i):
+                return np.ones((i,)).view(cls)
+
+        x = Subclass(5)
+        x[(0,)] = 2  # shouldn't raise an exception
+        assert_equal(x[0], 2)
+
+    def test_ufunc_no_unnecessary_views(self):
+        # ticket #1548
+        class Subclass(np.ndarray):
+            pass
+        x = np.array([1, 2, 3]).view(Subclass)
+        y = np.add(x, x, x)
+        assert_equal(id(x), id(y))
+
+    def test_take_refcount(self):
+        # ticket #939
+        a = np.arange(16, dtype=np.float)
+        a.shape = (4, 4)
+        lut = np.ones((5 + 3, 4), np.float)
+        rgba = np.empty(shape=a.shape + (4,), dtype=lut.dtype)
+        c1 = sys.getrefcount(rgba)
+        try:
+            lut.take(a, axis=0, mode='clip', out=rgba)
+        except TypeError:
+            pass
+        c2 = sys.getrefcount(rgba)
+        assert_equal(c1, c2)
+
+    def test_fromfile_tofile_seeks(self):
+        # On Python 3, tofile/fromfile used to get (#1610) the Python
+        # file handle out of sync
+        f0 = tempfile.NamedTemporaryFile()
+        f = f0.file
+        f.write(np.arange(255, dtype='u1').tobytes())
+
+        f.seek(20)
+        ret = np.fromfile(f, count=4, dtype='u1')
+        assert_equal(ret, np.array([20, 21, 22, 23], dtype='u1'))
+        assert_equal(f.tell(), 24)
+
+        f.seek(40)
+        np.array([1, 2, 3], dtype='u1').tofile(f)
+        assert_equal(f.tell(), 43)
+
+        f.seek(40)
+        data = f.read(3)
+        assert_equal(data, asbytes("\x01\x02\x03"))
+
+        f.seek(80)
+        f.read(4)
+        data = np.fromfile(f, dtype='u1', count=4)
+        assert_equal(data, np.array([84, 85, 86, 87], dtype='u1'))
+
+        f.close()
+
+    def test_complex_scalar_warning(self):
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = tp(1+2j)
+            assert_warns(np.ComplexWarning, float, x)
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                assert_equal(float(x), float(x.real))
+
+    def test_complex_scalar_complex_cast(self):
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = tp(1+2j)
+            assert_equal(complex(x), 1+2j)
+
+    def test_complex_boolean_cast(self):
+        # Ticket #2218
+        for tp in [np.csingle, np.cdouble, np.clongdouble]:
+            x = np.array([0, 0+0.5j, 0.5+0j], dtype=tp)
+            assert_equal(x.astype(bool), np.array([0, 1, 1], dtype=bool))
+            assert_(np.any(x))
+            assert_(np.all(x[1:]))
+
+    def test_uint_int_conversion(self):
+        x = 2**64 - 1
+        assert_equal(int(np.uint64(x)), x)
+
+    def test_duplicate_field_names_assign(self):
+        ra = np.fromiter(((i*3, i*2) for i in range(10)), dtype='i8,f8')
+        ra.dtype.names = ('f1', 'f2')
+        repr(ra)  # should not cause a segmentation fault
+        assert_raises(ValueError, setattr, ra.dtype, 'names', ('f1', 'f1'))
+
+    def test_eq_string_and_object_array(self):
+        # From e-mail thread "__eq__ with str and object" (Keith Goodman)
+        a1 = np.array(['a', 'b'], dtype=object)
+        a2 = np.array(['a', 'c'])
+        assert_array_equal(a1 == a2, [True, False])
+        assert_array_equal(a2 == a1, [True, False])
+
+    def test_nonzero_byteswap(self):
+        a = np.array([0x80000000, 0x00000080, 0], dtype=np.uint32)
+        a.dtype = np.float32
+        assert_equal(a.nonzero()[0], [1])
+        a = a.byteswap().newbyteorder()
+        assert_equal(a.nonzero()[0], [1])  # [0] if nonzero() ignores swap
+
+    def test_find_common_type_boolean(self):
+        # Ticket #1695
+        assert_(np.find_common_type([], ['?', '?']) == '?')
+
+    def test_empty_mul(self):
+        a = np.array([1.])
+        a[1:1] *= 2
+        assert_equal(a, [1.])
+
+    def test_array_side_effect(self):
+        # The second use of itemsize was throwing an exception because in
+        # ctors.c, discover_itemsize was calling PyObject_Length without
+        # checking the return code.  This failed to get the length of the
+        # number 2, and the exception hung around until something checked
+        # PyErr_Occurred() and returned an error.
+        assert_equal(np.dtype('S10').itemsize, 10)
+        np.array([['abc', 2], ['long   ', '0123456789']], dtype=np.string_)
+        assert_equal(np.dtype('S10').itemsize, 10)
+
+    def test_any_float(self):
+        # all and any for floats
+        a = np.array([0.1, 0.9])
+        assert_(np.any(a))
+        assert_(np.all(a))
+
+    def test_large_float_sum(self):
+        a = np.arange(10000, dtype='f')
+        assert_equal(a.sum(dtype='d'), a.astype('d').sum())
+
+    def test_ufunc_casting_out(self):
+        a = np.array(1.0, dtype=np.float32)
+        b = np.array(1.0, dtype=np.float64)
+        c = np.array(1.0, dtype=np.float32)
+        np.add(a, b, out=c)
+        assert_equal(c, 2.0)
+
+    def test_array_scalar_contiguous(self):
+        # Array scalars are both C and Fortran contiguous
+        assert_(np.array(1.0).flags.c_contiguous)
+        assert_(np.array(1.0).flags.f_contiguous)
+        assert_(np.array(np.float32(1.0)).flags.c_contiguous)
+        assert_(np.array(np.float32(1.0)).flags.f_contiguous)
+
+    def test_squeeze_contiguous(self):
+        # Similar to GitHub issue #387
+        a = np.zeros((1, 2)).squeeze()
+        b = np.zeros((2, 2, 2), order='F')[:,:, ::2].squeeze()
+        assert_(a.flags.c_contiguous)
+        assert_(a.flags.f_contiguous)
+        assert_(b.flags.f_contiguous)
+
+    def test_reduce_contiguous(self):
+        # GitHub issue #387
+        a = np.add.reduce(np.zeros((2, 1, 2)), (0, 1))
+        b = np.add.reduce(np.zeros((2, 1, 2)), 1)
+        assert_(a.flags.c_contiguous)
+        assert_(a.flags.f_contiguous)
+        assert_(b.flags.c_contiguous)
+
+    def test_object_array_self_reference(self):
+        # Object arrays with references to themselves can cause problems
+        a = np.array(0, dtype=object)
+        a[()] = a
+        assert_raises(TypeError, int, a)
+        assert_raises(TypeError, long, a)
+        assert_raises(TypeError, float, a)
+        assert_raises(TypeError, oct, a)
+        assert_raises(TypeError, hex, a)
+
+        # Test the same for a circular reference.
+        b = np.array(a, dtype=object)
+        a[()] = b
+        assert_raises(TypeError, int, a)
+        # Numpy has no tp_traverse currently, so circular references
+        # cannot be detected. So resolve it:
+        a[()] = 0
+
+        # This was causing a to become like the above
+        a = np.array(0, dtype=object)
+        a[...] += 1
+        assert_equal(a, 1)
+
+    def test_object_array_self_copy(self):
+        # An object array being copied into itself DECREF'ed before INCREF'ing
+        # causing segmentation faults (gh-3787)
+        a = np.array(object(), dtype=object)
+        np.copyto(a, a)
+        assert_equal(sys.getrefcount(a[()]), 2)
+        a[()].__class__  # will segfault if object was deleted
+
+    def test_zerosize_accumulate(self):
+        "Ticket #1733"
+        x = np.array([[42, 0]], dtype=np.uint32)
+        assert_equal(np.add.accumulate(x[:-1, 0]), [])
+
+    def test_objectarray_setfield(self):
+        # Setfield should not overwrite Object fields with non-Object data
+        x = np.array([1, 2, 3], dtype=object)
+        assert_raises(TypeError, x.setfield, 4, np.int32, 0)
+
+    def test_setting_rank0_string(self):
+        "Ticket #1736"
+        s1 = asbytes("hello1")
+        s2 = asbytes("hello2")
+        a = np.zeros((), dtype="S10")
+        a[()] = s1
+        assert_equal(a, np.array(s1))
+        a[()] = np.array(s2)
+        assert_equal(a, np.array(s2))
+
+        a = np.zeros((), dtype='f4')
+        a[()] = 3
+        assert_equal(a, np.array(3))
+        a[()] = np.array(4)
+        assert_equal(a, np.array(4))
+
+    def test_string_astype(self):
+        "Ticket #1748"
+        s1 = asbytes('black')
+        s2 = asbytes('white')
+        s3 = asbytes('other')
+        a = np.array([[s1], [s2], [s3]])
+        assert_equal(a.dtype, np.dtype('S5'))
+        b = a.astype(np.dtype('S0'))
+        assert_equal(b.dtype, np.dtype('S5'))
+
+    def test_ticket_1756(self):
+        # Ticket #1756
+        s = asbytes('0123456789abcdef')
+        a = np.array([s]*5)
+        for i in range(1, 17):
+            a1 = np.array(a, "|S%d" % i)
+            a2 = np.array([s[:i]]*5)
+            assert_equal(a1, a2)
+
+    def test_fields_strides(self):
+        "Ticket #1760"
+        r = np.fromstring('abcdefghijklmnop'*4*3, dtype='i4,(2,3)u2')
+        assert_equal(r[0:3:2]['f1'], r['f1'][0:3:2])
+        assert_equal(r[0:3:2]['f1'][0], r[0:3:2][0]['f1'])
+        assert_equal(r[0:3:2]['f1'][0][()], r[0:3:2][0]['f1'][()])
+        assert_equal(r[0:3:2]['f1'][0].strides, r[0:3:2][0]['f1'].strides)
+
+    def test_alignment_update(self):
+        # Check that alignment flag is updated on stride setting
+        a = np.arange(10)
+        assert_(a.flags.aligned)
+        a.strides = 3
+        assert_(not a.flags.aligned)
+
+    def test_ticket_1770(self):
+        "Should not segfault on python 3k"
+        import numpy as np
+        try:
+            a = np.zeros((1,), dtype=[('f1', 'f')])
+            a['f1'] = 1
+            a['f2'] = 1
+        except ValueError:
+            pass
+        except:
+            raise AssertionError
+
+    def test_ticket_1608(self):
+        "x.flat shouldn't modify data"
+        x = np.array([[1, 2], [3, 4]]).T
+        np.array(x.flat)
+        assert_equal(x, [[1, 3], [2, 4]])
+
+    def test_pickle_string_overwrite(self):
+        import re
+
+        data = np.array([1], dtype='b')
+        blob = pickle.dumps(data, protocol=1)
+        data = pickle.loads(blob)
+
+        # Check that loads does not clobber interned strings
+        s = re.sub("a(.)", "\x01\\1", "a_")
+        assert_equal(s[0], "\x01")
+        data[0] = 0xbb
+        s = re.sub("a(.)", "\x01\\1", "a_")
+        assert_equal(s[0], "\x01")
+
+    def test_pickle_bytes_overwrite(self):
+        if sys.version_info[0] >= 3:
+            data = np.array([1], dtype='b')
+            data = pickle.loads(pickle.dumps(data))
+            data[0] = 0xdd
+            bytestring = "\x01  ".encode('ascii')
+            assert_equal(bytestring[0:1], '\x01'.encode('ascii'))
+
+    def test_pickle_py2_array_latin1_hack(self):
+        # Check that unpickling hacks in Py3 that support
+        # encoding='latin1' work correctly.
+
+        # Python2 output for pickle.dumps(numpy.array([129], dtype='b'))
+        data = asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\n"
+                       "tp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'i1'\np8\n"
+                       "I0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x81'\n"
+                       "p13\ntp14\nb.")
+        if sys.version_info[0] >= 3:
+            # This should work:
+            result = pickle.loads(data, encoding='latin1')
+            assert_array_equal(result, np.array([129], dtype='b'))
+            # Should not segfault:
+            assert_raises(Exception, pickle.loads, data, encoding='koi8-r')
+
+    def test_pickle_py2_scalar_latin1_hack(self):
+        # Check that scalar unpickling hack in Py3 that supports
+        # encoding='latin1' work correctly.
+
+        # Python2 output for pickle.dumps(...)
+        datas = [
+            # (original, python2_pickle, koi8r_validity)
+            (np.unicode_('\u6bd2'),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+                     "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\nI0\n"
+                     "tp6\nbS'\\xd2k\\x00\\x00'\np7\ntp8\nRp9\n."),
+             'invalid'),
+
+            (np.float64(9e123),
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'f8'\n"
+                     "p2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI-1\nI-1\nI0\ntp6\n"
+                     "bS'O\\x81\\xb7Z\\xaa:\\xabY'\np7\ntp8\nRp9\n."),
+             'invalid'),
+
+            (np.bytes_(asbytes('\x9c')),  # different 8-bit code point in KOI8-R vs latin1
+             asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'S1'\np2\n"
+                     "I0\nI1\ntp3\nRp4\n(I3\nS'|'\np5\nNNNI1\nI1\nI0\ntp6\nbS'\\x9c'\np7\n"
+                     "tp8\nRp9\n."),
+             'different'),
+        ]
+        if sys.version_info[0] >= 3:
+            for original, data, koi8r_validity in datas:
+                result = pickle.loads(data, encoding='latin1')
+                assert_equal(result, original)
+
+                # Decoding under non-latin1 encoding (e.g.) KOI8-R can
+                # produce bad results, but should not segfault.
+                if koi8r_validity == 'different':
+                    # Unicode code points happen to lie within latin1,
+                    # but are different in koi8-r, resulting to silent
+                    # bogus results
+                    result = pickle.loads(data, encoding='koi8-r')
+                    assert_(result != original)
+                elif koi8r_validity == 'invalid':
+                    # Unicode code points outside latin1, so results
+                    # to an encoding exception
+                    assert_raises(ValueError, pickle.loads, data, encoding='koi8-r')
+                else:
+                    raise ValueError(koi8r_validity)
+
+    def test_structured_type_to_object(self):
+        a_rec = np.array([(0, 1), (3, 2)], dtype='i4,i8')
+        a_obj = np.empty((2,), dtype=object)
+        a_obj[0] = (0, 1)
+        a_obj[1] = (3, 2)
+        # astype records -> object
+        assert_equal(a_rec.astype(object), a_obj)
+        # '=' records -> object
+        b = np.empty_like(a_obj)
+        b[...] = a_rec
+        assert_equal(b, a_obj)
+        # '=' object -> records
+        b = np.empty_like(a_rec)
+        b[...] = a_obj
+        assert_equal(b, a_rec)
+
+    def test_assign_obj_listoflists(self):
+        # Ticket # 1870
+        # The inner list should get assigned to the object elements
+        a = np.zeros(4, dtype=object)
+        b = a.copy()
+        a[0] = [1]
+        a[1] = [2]
+        a[2] = [3]
+        a[3] = [4]
+        b[...] = [[1], [2], [3], [4]]
+        assert_equal(a, b)
+        # The first dimension should get broadcast
+        a = np.zeros((2, 2), dtype=object)
+        a[...] = [[1, 2]]
+        assert_equal(a, [[1, 2], [1, 2]])
+
+    def test_memoryleak(self):
+        # Ticket #1917 - ensure that array data doesn't leak
+        for i in range(1000):
+            # 100MB times 1000 would give 100GB of memory usage if it leaks
+            a = np.empty((100000000,), dtype='i1')
+            del a
+
+    def test_ufunc_reduce_memoryleak(self):
+        a = np.arange(6)
+        acnt = sys.getrefcount(a)
+        np.add.reduce(a)
+        assert_equal(sys.getrefcount(a), acnt)
+
+    def test_search_sorted_invalid_arguments(self):
+        # Ticket #2021, should not segfault.
+        x = np.arange(0, 4, dtype='datetime64[D]')
+        assert_raises(TypeError, x.searchsorted, 1)
+
+    def test_string_truncation(self):
+        # Ticket #1990 - Data can be truncated in creation of an array from a
+        # mixed sequence of numeric values and strings
+        for val in [True, 1234, 123.4, complex(1, 234)]:
+            for tostr in [asunicode, asbytes]:
+                b = np.array([val, tostr('xx')])
+                assert_equal(tostr(b[0]), tostr(val))
+                b = np.array([tostr('xx'), val])
+                assert_equal(tostr(b[1]), tostr(val))
+
+                # test also with longer strings
+                b = np.array([val, tostr('xxxxxxxxxx')])
+                assert_equal(tostr(b[0]), tostr(val))
+                b = np.array([tostr('xxxxxxxxxx'), val])
+                assert_equal(tostr(b[1]), tostr(val))
+
+    def test_string_truncation_ucs2(self):
+        # Ticket #2081. Python compiled with two byte unicode
+        # can lead to truncation if itemsize is not properly
+        # adjusted for Numpy's four byte unicode.
+        if sys.version_info[0] >= 3:
+            a = np.array(['abcd'])
+        else:
+            a = np.array([sixu('abcd')])
+        assert_equal(a.dtype.itemsize, 16)
+
+    def test_unique_stable(self):
+        # Ticket #2063 must always choose stable sort for argsort to
+        # get consistent results
+        v = np.array(([0]*5 + [1]*6 + [2]*6)*4)
+        res = np.unique(v, return_index=True)
+        tgt = (np.array([0, 1, 2]), np.array([ 0,  5, 11]))
+        assert_equal(res, tgt)
+
+    def test_unicode_alloc_dealloc_match(self):
+        # Ticket #1578, the mismatch only showed up when running
+        # python-debug for python versions >= 2.7, and then as
+        # a core dump and error message.
+        a = np.array(['abc'], dtype=np.unicode)[0]
+        del a
+
+    def test_refcount_error_in_clip(self):
+        # Ticket #1588
+        a = np.zeros((2,), dtype='>i2').clip(min=0)
+        x = a + a
+        # This used to segfault:
+        y = str(x)
+        # Check the final string:
+        assert_(y == "[0 0]")
+
+    def test_searchsorted_wrong_dtype(self):
+        # Ticket #2189, it used to segfault, so we check that it raises the
+        # proper exception.
+        a = np.array([('a', 1)], dtype='S1, int')
+        assert_raises(TypeError, np.searchsorted, a, 1.2)
+        # Ticket #2066, similar problem:
+        dtype = np.format_parser(['i4', 'i4'], [], [])
+        a = np.recarray((2, ), dtype)
+        assert_raises(TypeError, np.searchsorted, a, 1)
+
+    def test_complex64_alignment(self):
+        # Issue gh-2668 (trac 2076), segfault on sparc due to misalignment
+        dtt = np.complex64
+        arr = np.arange(10, dtype=dtt)
+        # 2D array
+        arr2 = np.reshape(arr, (2, 5))
+        # Fortran write followed by (C or F) read caused bus error
+        data_str = arr2.tobytes('F')
+        data_back = np.ndarray(arr2.shape,
+                              arr2.dtype,
+                              buffer=data_str,
+                              order='F')
+        assert_array_equal(arr2, data_back)
+
+    def test_structured_count_nonzero(self):
+        arr = np.array([0, 1]).astype('i4, (2)i4')[:1]
+        count = np.count_nonzero(arr)
+        assert_equal(count, 0)
+
+    def test_copymodule_preserves_f_contiguity(self):
+        a = np.empty((2, 2), order='F')
+        b = copy.copy(a)
+        c = copy.deepcopy(a)
+        assert_(b.flags.fortran)
+        assert_(b.flags.f_contiguous)
+        assert_(c.flags.fortran)
+        assert_(c.flags.f_contiguous)
+
+    def test_fortran_order_buffer(self):
+        import numpy as np
+        a = np.array([['Hello', 'Foob']], dtype='U5', order='F')
+        arr = np.ndarray(shape=[1, 2, 5], dtype='U1', buffer=a)
+        arr2 = np.array([[[sixu('H'), sixu('e'), sixu('l'), sixu('l'), sixu('o')],
+                          [sixu('F'), sixu('o'), sixu('o'), sixu('b'), sixu('')]]])
+        assert_array_equal(arr, arr2)
+
+    def test_assign_from_sequence_error(self):
+        # Ticket #4024.
+        arr = np.array([1, 2, 3])
+        assert_raises(ValueError, arr.__setitem__, slice(None), [9, 9])
+        arr.__setitem__(slice(None), [9])
+        assert_equal(arr, [9, 9, 9])
+
+    def test_format_on_flex_array_element(self):
+        # Ticket #4369.
+        dt = np.dtype([('date', '<M8[D]'), ('val', '<f8')])
+        arr = np.array([('2000-01-01', 1)], dt)
+        formatted = '{0}'.format(arr[0])
+        assert_equal(formatted, str(arr[0]))
+
+    def test_deepcopy_on_0d_array(self):
+        # Ticket #3311.
+        arr = np.array(3)
+        arr_cp = copy.deepcopy(arr)
+
+        assert_equal(arr, arr_cp)
+        assert_equal(arr.shape, arr_cp.shape)
+        assert_equal(int(arr), int(arr_cp))
+        self.assertTrue(arr is not arr_cp)
+        self.assertTrue(isinstance(arr_cp, type(arr)))
+
+    def test_bool_subscript_crash(self):
+        # gh-4494
+        c = np.rec.array([(1, 2, 3), (4, 5, 6)])
+        masked = c[np.array([True, False])]
+        base = masked.base
+        del masked, c
+        base.dtype
+
+    def test_richcompare_crash(self):
+        # gh-4613
+        import operator as op
+
+        # dummy class where __array__ throws exception
+        class Foo(object):
+            __array_priority__ = 1002
+
+            def __array__(self,*args,**kwargs):
+                raise Exception()
+
+        rhs = Foo()
+        lhs = np.array(1)
+        for f in [op.lt, op.le, op.gt, op.ge]:
+            if sys.version_info[0] >= 3:
+                assert_raises(TypeError, f, lhs, rhs)
+            else:
+                f(lhs, rhs)
+        assert_(not op.eq(lhs, rhs))
+        assert_(op.ne(lhs, rhs))
+
+    def test_richcompare_scalar_and_subclass(self):
+        # gh-4709
+        class Foo(np.ndarray):
+            def __eq__(self, other):
+                return "OK"
+
+        x = np.array([1,2,3]).view(Foo)
+        assert_equal(10 == x, "OK")
+        assert_equal(np.int32(10) == x, "OK")
+        assert_equal(np.array([10]) == x, "OK")
+
+    def test_pickle_empty_string(self):
+        # gh-3926
+
+        import pickle
+        test_string = np.string_('')
+        assert_equal(pickle.loads(pickle.dumps(test_string)), test_string)
+
+    def test_frompyfunc_many_args(self):
+        # gh-5672
+
+        def passer(*args):
+            pass
+
+        assert_raises(ValueError, np.frompyfunc, passer, 32, 1)
+
+    def test_repeat_broadcasting(self):
+        # gh-5743
+        a = np.arange(60).reshape(3, 4, 5)
+        for axis in chain(range(-a.ndim, a.ndim), [None]):
+            assert_equal(a.repeat(2, axis=axis), a.repeat([2], axis=axis))
+
+    def test_frompyfunc_nout_0(self):
+        # gh-2014
+
+        def f(x):
+            x[0], x[-1] = x[-1], x[0]
+
+        uf = np.frompyfunc(f, 1, 0)
+        a = np.array([[1, 2, 3], [4, 5], [6, 7, 8, 9]])
+        assert_equal(uf(a), ())
+        assert_array_equal(a, [[3, 2, 1], [5, 4], [9, 7, 8, 6]])
+
+    def test_leak_in_structured_dtype_comparison(self):
+        # gh-6250
+        recordtype = np.dtype([('a', np.float64),
+                               ('b', np.int32),
+                               ('d', (np.str, 5))])
+
+        # Simple case
+        a = np.zeros(2, dtype=recordtype)
+        for i in range(100):
+            a == a
+        assert_(sys.getrefcount(a) < 10)
+
+        # The case in the bug report.
+        before = sys.getrefcount(a)
+        u, v = a[0], a[1]
+        u == v
+        del u, v
+        gc.collect()
+        after = sys.getrefcount(a)
+        assert_equal(before, after)
+
+    def test_empty_percentile(self):
+        # gh-6530 / gh-6553
+        assert_array_equal(np.percentile(np.arange(10), []), np.array([]))
+
+    def test_void_compare_segfault(self):
+        # gh-6922. The following should not segfault
+        a = np.ones(3, dtype=[('object', 'O'), ('int', '<i2')])
+        a.sort()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
new file mode 100644
index 0000000000..e8cf7fde00
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+""" Test printing of scalar types.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+class A(object):
+    pass
+class B(A, np.float64):
+    pass
+
+class C(B):
+    pass
+class D(C, B):
+    pass
+
+class B0(np.float64, A):
+    pass
+class C0(B0):
+    pass
+
+class TestInherit(TestCase):
+    def test_init(self):
+        x = B(1.0)
+        assert_(str(x) == '1.0')
+        y = C(2.0)
+        assert_(str(y) == '2.0')
+        z = D(3.0)
+        assert_(str(z) == '3.0')
+
+    def test_init2(self):
+        x = B0(1.0)
+        assert_(str(x) == '1.0')
+        y = C0(2.0)
+        assert_(str(y) == '2.0')
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
new file mode 100644
index 0000000000..12b1a0fe33
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
@@ -0,0 +1,473 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import warnings
+import operator
+
+import numpy as np
+from numpy.testing.utils import _gen_alignment_data
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_almost_equal, assert_allclose
+)
+
+types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
+         np.int_, np.uint, np.longlong, np.ulonglong,
+         np.single, np.double, np.longdouble, np.csingle,
+         np.cdouble, np.clongdouble]
+
+floating_types = np.floating.__subclasses__()
+
+
+# This compares scalarmath against ufuncs.
+
+class TestTypes(TestCase):
+    def test_types(self, level=1):
+        for atype in types:
+            a = atype(1)
+            assert_(a == 1, "error with %r: got %r" % (atype, a))
+
+    def test_type_add(self, level=1):
+        # list of types
+        for k, atype in enumerate(types):
+            a_scalar = atype(3)
+            a_array = np.array([3], dtype=atype)
+            for l, btype in enumerate(types):
+                b_scalar = btype(1)
+                b_array = np.array([1], dtype=btype)
+                c_scalar = a_scalar + b_scalar
+                c_array = a_array + b_array
+                # It was comparing the type numbers, but the new ufunc
+                # function-finding mechanism finds the lowest function
+                # to which both inputs can be cast - which produces 'l'
+                # when you do 'q' + 'b'.  The old function finding mechanism
+                # skipped ahead based on the first argument, but that
+                # does not produce properly symmetric results...
+                assert_equal(c_scalar.dtype, c_array.dtype,
+                           "error with types (%d/'%c' + %d/'%c')" %
+                            (k, np.dtype(atype).char, l, np.dtype(btype).char))
+
+    def test_type_create(self, level=1):
+        for k, atype in enumerate(types):
+            a = np.array([1, 2, 3], atype)
+            b = atype([1, 2, 3])
+            assert_equal(a, b)
+
+    def test_leak(self):
+        # test leak of scalar objects
+        # a leak would show up in valgrind as still-reachable of ~2.6MB
+        for i in range(200000):
+            np.add(1, 1)
+
+
+class TestBaseMath(TestCase):
+    def test_blocked(self):
+        # test alignments offsets for simd instructions
+        # alignments for vz + 2 * (vs - 1) + 1
+        for dt, sz in [(np.float32, 11), (np.float64, 7)]:
+            for out, inp1, inp2, msg in _gen_alignment_data(dtype=dt,
+                                                            type='binary',
+                                                            max_size=sz):
+                exp1 = np.ones_like(inp1)
+                inp1[...] = np.ones_like(inp1)
+                inp2[...] = np.zeros_like(inp2)
+                assert_almost_equal(np.add(inp1, inp2), exp1, err_msg=msg)
+                assert_almost_equal(np.add(inp1, 1), exp1 + 1, err_msg=msg)
+                assert_almost_equal(np.add(1, inp2), exp1, err_msg=msg)
+
+                np.add(inp1, inp2, out=out)
+                assert_almost_equal(out, exp1, err_msg=msg)
+
+                inp2[...] += np.arange(inp2.size, dtype=dt) + 1
+                assert_almost_equal(np.square(inp2),
+                                    np.multiply(inp2, inp2),  err_msg=msg)
+                assert_almost_equal(np.reciprocal(inp2),
+                                    np.divide(1, inp2),  err_msg=msg)
+
+                inp1[...] = np.ones_like(inp1)
+                inp2[...] = np.zeros_like(inp2)
+                np.add(inp1, 1, out=out)
+                assert_almost_equal(out, exp1 + 1, err_msg=msg)
+                np.add(1, inp2, out=out)
+                assert_almost_equal(out, exp1, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_almost_equal(d + d, d * 2)
+        np.add(d, d, out=o)
+        np.add(np.ones_like(d), d, out=o)
+        np.add(d, np.ones_like(d), out=o)
+        np.add(np.ones_like(d), d)
+        np.add(d, np.ones_like(d))
+
+
+class TestPower(TestCase):
+    def test_small_types(self):
+        for t in [np.int8, np.int16, np.float16]:
+            a = t(3)
+            b = a ** 4
+            assert_(b == 81, "error with %r: got %r" % (t, b))
+
+    def test_large_types(self):
+        for t in [np.int32, np.int64, np.float32, np.float64, np.longdouble]:
+            a = t(51)
+            b = a ** 4
+            msg = "error with %r: got %r" % (t, b)
+            if np.issubdtype(t, np.integer):
+                assert_(b == 6765201, msg)
+            else:
+                assert_almost_equal(b, 6765201, err_msg=msg)
+
+    def test_mixed_types(self):
+        typelist = [np.int8, np.int16, np.float16,
+                    np.float32, np.float64, np.int8,
+                    np.int16, np.int32, np.int64]
+        for t1 in typelist:
+            for t2 in typelist:
+                a = t1(3)
+                b = t2(2)
+                result = a**b
+                msg = ("error with %r and %r:"
+                       "got %r, expected %r") % (t1, t2, result, 9)
+                if np.issubdtype(np.dtype(result), np.integer):
+                    assert_(result == 9, msg)
+                else:
+                    assert_almost_equal(result, 9, err_msg=msg)
+
+
+class TestModulus(TestCase):
+
+    floordiv = operator.floordiv
+    mod = operator.mod
+
+    def test_modulus_basic(self):
+        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                if sg1 == -1 and dt1 in np.typecodes['UnsignedInteger']:
+                    continue
+                if sg2 == -1 and dt2 in np.typecodes['UnsignedInteger']:
+                    continue
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*71, dtype=dt1)[()]
+                b = np.array(sg2*19, dtype=dt2)[()]
+                div = self.floordiv(a, b)
+                rem = self.mod(a, b)
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_modulus_exact(self):
+        # test that float results are exact for small integers. This also
+        # holds for the same integers scaled by powers of two.
+        nlst = list(range(-127, 0))
+        plst = list(range(1, 128))
+        dividend = nlst + [0] + plst
+        divisor = nlst + plst
+        arg = list(itertools.product(dividend, divisor))
+        tgt = list(divmod(*t) for t in arg)
+
+        a, b = np.array(arg, dtype=int).T
+        # convert exact integer results from Python to float so that
+        # signed zero can be used, it is checked.
+        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
+        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
+        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
+
+        for dt in np.typecodes['Float']:
+            msg = 'dtype: %s' % (dt,)
+            fa = a.astype(dt)
+            fb = b.astype(dt)
+            # use list comprehension so a_ and b_ are scalars
+            div = [self.floordiv(a_, b_) for  a_, b_ in zip(fa, fb)]
+            rem = [self.mod(a_, b_) for a_, b_ in zip(fa, fb)]
+            assert_equal(div, tgtdiv, err_msg=msg)
+            assert_equal(rem, tgtrem, err_msg=msg)
+
+    def test_float_modulus_roundoff(self):
+        # gh-6127
+        dt = np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*78*6e-8, dtype=dt1)[()]
+                b = np.array(sg2*6e-8, dtype=dt2)[()]
+                div = self.floordiv(a, b)
+                rem = self.mod(a, b)
+                # Equal assertion should hold when fmod is used
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_modulus_corner_cases(self):
+        # Check remainder magnitude.
+        for dt in np.typecodes['Float']:
+            b = np.array(1.0, dtype=dt)
+            a = np.nextafter(np.array(0.0, dtype=dt), -b)
+            rem = self.mod(a, b)
+            assert_(rem <= b, 'dt: %s' % dt)
+            rem = self.mod(-a, -b)
+            assert_(rem >= -b, 'dt: %s' % dt)
+
+        # Check nans, inf
+        with warnings.catch_warnings():
+            warnings.simplefilter('always')
+            warnings.simplefilter('ignore', RuntimeWarning)
+            for dt in np.typecodes['Float']:
+                fone = np.array(1.0, dtype=dt)
+                fzer = np.array(0.0, dtype=dt)
+                finf = np.array(np.inf, dtype=dt)
+                fnan = np.array(np.nan, dtype=dt)
+                rem = self.mod(fone, fzer)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+                # MSVC 2008 returns NaN here, so disable the check.
+                #rem = self.mod(fone, finf)
+                #assert_(rem == fone, 'dt: %s' % dt)
+                rem = self.mod(fone, fnan)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+                rem = self.mod(finf, fone)
+                assert_(np.isnan(rem), 'dt: %s' % dt)
+
+
+class TestComplexDivision(TestCase):
+    def test_zero_division(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                a = t(0.0)
+                b = t(1.0)
+                assert_(np.isinf(b/a))
+                b = t(complex(np.inf, np.inf))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.inf, np.nan))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.nan, np.inf))
+                assert_(np.isinf(b/a))
+                b = t(complex(np.nan, np.nan))
+                assert_(np.isnan(b/a))
+                b = t(0.)
+                assert_(np.isnan(b/a))
+
+    def test_signed_zeros(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                # tupled (numerator, denominator, expected)
+                # for testing as expected == numerator/denominator
+                data = (
+                    (( 0.0,-1.0), ( 0.0, 1.0), (-1.0,-0.0)),
+                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    (( 0.0,-1.0), (-0.0,-1.0), ( 1.0, 0.0)),
+                    (( 0.0,-1.0), (-0.0, 1.0), (-1.0, 0.0)),
+                    (( 0.0, 1.0), ( 0.0,-1.0), (-1.0, 0.0)),
+                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    ((-0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
+                    ((-0.0, 1.0), ( 0.0,-1.0), (-1.0,-0.0))
+                )
+                for cases in data:
+                    n = cases[0]
+                    d = cases[1]
+                    ex = cases[2]
+                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
+                    # check real and imag parts separately to avoid comparison
+                    # in array context, which does not account for signed zeros
+                    assert_equal(result.real, ex[0])
+                    assert_equal(result.imag, ex[1])
+
+    def test_branches(self):
+        with np.errstate(all="ignore"):
+            for t in [np.complex64, np.complex128]:
+                # tupled (numerator, denominator, expected)
+                # for testing as expected == numerator/denominator
+                data = list()
+
+                # trigger branch: real(fabs(denom)) > imag(fabs(denom))
+                # followed by else condition as neither are == 0
+                data.append((( 2.0, 1.0), ( 2.0, 1.0), (1.0, 0.0)))
+
+                # trigger branch: real(fabs(denom)) > imag(fabs(denom))
+                # followed by if condition as both are == 0
+                # is performed in test_zero_division(), so this is skipped
+
+                # trigger else if branch: real(fabs(denom)) < imag(fabs(denom))
+                data.append((( 1.0, 2.0), ( 1.0, 2.0), (1.0, 0.0)))
+
+                for cases in data:
+                    n = cases[0]
+                    d = cases[1]
+                    ex = cases[2]
+                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
+                    # check real and imag parts separately to avoid comparison
+                    # in array context, which does not account for signed zeros
+                    assert_equal(result.real, ex[0])
+                    assert_equal(result.imag, ex[1])
+
+
+class TestConversion(TestCase):
+    def test_int_from_long(self):
+        l = [1e6, 1e12, 1e18, -1e6, -1e12, -1e18]
+        li = [10**6, 10**12, 10**18, -10**6, -10**12, -10**18]
+        for T in [None, np.float64, np.int64]:
+            a = np.array(l, dtype=T)
+            assert_equal([int(_m) for _m in a], li)
+
+        a = np.array(l[:3], dtype=np.uint64)
+        assert_equal([int(_m) for _m in a], li[:3])
+
+    def test_iinfo_long_values(self):
+        for code in 'bBhH':
+            res = np.array(np.iinfo(code).max + 1, dtype=code)
+            tgt = np.iinfo(code).min
+            assert_(res == tgt)
+
+        for code in np.typecodes['AllInteger']:
+            res = np.array(np.iinfo(code).max, dtype=code)
+            tgt = np.iinfo(code).max
+            assert_(res == tgt)
+
+        for code in np.typecodes['AllInteger']:
+            res = np.typeDict[code](np.iinfo(code).max)
+            tgt = np.iinfo(code).max
+            assert_(res == tgt)
+
+    def test_int_raise_behaviour(self):
+        def overflow_error_func(dtype):
+            np.typeDict[dtype](np.iinfo(dtype).max + 1)
+
+        for code in 'lLqQ':
+            assert_raises(OverflowError, overflow_error_func, code)
+
+    def test_longdouble_int(self):
+        # gh-627
+        x = np.longdouble(np.inf)
+        assert_raises(OverflowError, x.__int__)
+        x = np.clongdouble(np.inf)
+        assert_raises(OverflowError, x.__int__)
+
+    def test_numpy_scalar_relational_operators(self):
+        # All integer
+        for dt1 in np.typecodes['AllInteger']:
+            assert_(1 > np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            for dt2 in np.typecodes['AllInteger']:
+                assert_(np.array(1, dtype=dt1)[()] > np.array(0, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(0, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+        #Unsigned integers
+        for dt1 in 'BHILQP':
+            assert_(-1 < np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not -1 > np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(-1 != np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            #unsigned vs signed
+            for dt2 in 'bhilqp':
+                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(1, dtype=dt1)[()] != np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+        #Signed integers and floats
+        for dt1 in 'bhlqp' + np.typecodes['Float']:
+            assert_(1 > np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(not 1 < np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+            assert_(-1 == np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
+
+            for dt2 in 'bhlqp' + np.typecodes['Float']:
+                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+                assert_(np.array(-1, dtype=dt1)[()] == np.array(-1, dtype=dt2)[()],
+                        "type %s and %s failed" % (dt1, dt2))
+
+
+#class TestRepr(TestCase):
+#    def test_repr(self):
+#        for t in types:
+#            val = t(1197346475.0137341)
+#            val_repr = repr(val)
+#            val2 = eval(val_repr)
+#            assert_equal( val, val2 )
+
+
+class TestRepr(object):
+    def _test_type_repr(self, t):
+        finfo = np.finfo(t)
+        last_fraction_bit_idx = finfo.nexp + finfo.nmant
+        last_exponent_bit_idx = finfo.nexp
+        storage_bytes = np.dtype(t).itemsize*8
+        # could add some more types to the list below
+        for which in ['small denorm', 'small norm']:
+            # Values from http://en.wikipedia.org/wiki/IEEE_754
+            constr = np.array([0x00]*storage_bytes, dtype=np.uint8)
+            if which == 'small denorm':
+                byte = last_fraction_bit_idx // 8
+                bytebit = 7-(last_fraction_bit_idx % 8)
+                constr[byte] = 1 << bytebit
+            elif which == 'small norm':
+                byte = last_exponent_bit_idx // 8
+                bytebit = 7-(last_exponent_bit_idx % 8)
+                constr[byte] = 1 << bytebit
+            else:
+                raise ValueError('hmm')
+            val = constr.view(t)[0]
+            val_repr = repr(val)
+            val2 = t(eval(val_repr))
+            if not (val2 == 0 and val < 1e-100):
+                assert_equal(val, val2)
+
+    def test_float_repr(self):
+        # long double test cannot work, because eval goes through a python
+        # float
+        for t in [np.float32, np.float64]:
+            yield self._test_type_repr, t
+
+
+class TestSizeOf(TestCase):
+
+    def test_equal_nbytes(self):
+        for type in types:
+            x = type(0)
+            assert_(sys.getsizeof(x) > x.nbytes)
+
+    def test_error(self):
+        d = np.float32()
+        assert_raises(TypeError, d.__sizeof__, "a")
+
+
+class TestAbs(TestCase):
+
+    def _test_abs_func(self, absfunc):
+        for tp in floating_types:
+            x = tp(-1.5)
+            assert_equal(absfunc(x), 1.5)
+            x = tp(0.0)
+            res = absfunc(x)
+            # assert_equal() checks zero signedness
+            assert_equal(res, 0.0)
+            x = tp(-0.0)
+            res = absfunc(x)
+            assert_equal(res, 0.0)
+
+    def test_builtin_abs(self):
+        self._test_abs_func(abs)
+
+    def test_numpy_abs(self):
+        self._test_abs_func(np.abs)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
new file mode 100644
index 0000000000..8d0f27182b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+""" Test printing of scalar types.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, assert_, run_module_suite
+
+
+class TestRealScalars(TestCase):
+    def test_str(self):
+        svals = [0.0, -0.0, 1, -1, np.inf, -np.inf, np.nan]
+        styps = [np.float16, np.float32, np.float64, np.longdouble]
+        actual = [str(f(c)) for c in svals for f in styps]
+        wanted = [
+             '0.0',  '0.0',  '0.0',  '0.0',
+             '-0.0', '-0.0', '-0.0', '-0.0',
+             '1.0',  '1.0',  '1.0',  '1.0',
+             '-1.0', '-1.0', '-1.0', '-1.0',
+             'inf',  'inf',  'inf',  'inf',
+             '-inf', '-inf', '-inf', '-inf',
+             'nan',  'nan',  'nan',  'nan']
+
+        for res, val in zip(actual, wanted):
+            assert_(res == val)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
new file mode 100644
index 0000000000..0d163c1dc9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
@@ -0,0 +1,319 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.compat import long
+from numpy.core import (array, arange, atleast_1d, atleast_2d, atleast_3d,
+                        vstack, hstack, newaxis, concatenate, stack)
+from numpy.testing import (TestCase, assert_, assert_raises, assert_array_equal,
+                           assert_equal, run_module_suite, assert_raises_regex)
+
+class TestAtleast1d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [array([1]), array([2])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [array([1, 2]), array([2, 3])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_1d(a), atleast_1d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_r1array(self):
+        """ Test to make sure equivalent Travis O's r1array function
+        """
+        assert_(atleast_1d(3).shape == (1,))
+        assert_(atleast_1d(3j).shape == (1,))
+        assert_(atleast_1d(long(3)).shape == (1,))
+        assert_(atleast_1d(3.0).shape == (1,))
+        assert_(atleast_1d([[2, 3], [4, 5]]).shape == (2, 2))
+
+
+class TestAtleast2d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [array([[1]]), array([[2]])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [array([[1, 2]]), array([[2, 3]])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_2d(a), atleast_2d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+    def test_r2array(self):
+        """ Test to make sure equivalent Travis O's r2array function
+        """
+        assert_(atleast_2d(3).shape == (1, 1))
+        assert_(atleast_2d([3j, 1]).shape == (1, 2))
+        assert_(atleast_2d([[[3, 1], [4, 5]], [[3, 5], [1, 2]]]).shape == (2, 2, 2))
+
+
+class TestAtleast3d(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [array([[[1]]]), array([[[2]]])]
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1, 2])
+        b = array([2, 3])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [array([[[1], [2]]]), array([[[2], [3]]])]
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [a[:,:, newaxis], b[:,:, newaxis]]
+        assert_array_equal(res, desired)
+
+    def test_3D_array(self):
+        a = array([[1, 2], [1, 2]])
+        b = array([[2, 3], [2, 3]])
+        a = array([a, a])
+        b = array([b, b])
+        res = [atleast_3d(a), atleast_3d(b)]
+        desired = [a, b]
+        assert_array_equal(res, desired)
+
+
+class TestHstack(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = hstack([a, b])
+        desired = array([1, 2])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1])
+        b = array([2])
+        res = hstack([a, b])
+        desired = array([1, 2])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1], [2]])
+        b = array([[1], [2]])
+        res = hstack([a, b])
+        desired = array([[1, 1], [2, 2]])
+        assert_array_equal(res, desired)
+
+
+class TestVstack(TestCase):
+    def test_0D_array(self):
+        a = array(1)
+        b = array(2)
+        res = vstack([a, b])
+        desired = array([[1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = array([1])
+        b = array([2])
+        res = vstack([a, b])
+        desired = array([[1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = array([[1], [2]])
+        b = array([[1], [2]])
+        res = vstack([a, b])
+        desired = array([[1], [2], [1], [2]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array2(self):
+        a = array([1, 2])
+        b = array([1, 2])
+        res = vstack([a, b])
+        desired = array([[1, 2], [1, 2]])
+        assert_array_equal(res, desired)
+
+
+class TestConcatenate(TestCase):
+    def test_exceptions(self):
+        # test axis must be in bounds
+        for ndim in [1, 2, 3]:
+            a = np.ones((1,)*ndim)
+            np.concatenate((a, a), axis=0)  # OK
+            assert_raises(IndexError, np.concatenate, (a, a), axis=ndim)
+            assert_raises(IndexError, np.concatenate, (a, a), axis=-(ndim + 1))
+
+        # Scalars cannot be concatenated
+        assert_raises(ValueError, concatenate, (0,))
+        assert_raises(ValueError, concatenate, (np.array(0),))
+
+        # test shapes must match except for concatenation axis
+        a = np.ones((1, 2, 3))
+        b = np.ones((2, 2, 3))
+        axis = list(range(3))
+        for i in range(3):
+            np.concatenate((a, b), axis=axis[0])  # OK
+            assert_raises(ValueError, np.concatenate, (a, b), axis=axis[1])
+            assert_raises(ValueError, np.concatenate, (a, b), axis=axis[2])
+            a = np.rollaxis(a, -1)
+            b = np.rollaxis(b, -1)
+            axis.append(axis.pop(0))
+
+        # No arrays to concatenate raises ValueError
+        assert_raises(ValueError, concatenate, ())
+
+    def test_concatenate_axis_None(self):
+        a = np.arange(4, dtype=np.float64).reshape((2, 2))
+        b = list(range(3))
+        c = ['x']
+        r = np.concatenate((a, a), axis=None)
+        assert_equal(r.dtype, a.dtype)
+        assert_equal(r.ndim, 1)
+        r = np.concatenate((a, b), axis=None)
+        assert_equal(r.size, a.size + len(b))
+        assert_equal(r.dtype, a.dtype)
+        r = np.concatenate((a, b, c), axis=None)
+        d = array(['0.0', '1.0', '2.0', '3.0',
+                   '0', '1', '2', 'x'])
+        assert_array_equal(r, d)
+
+    def test_large_concatenate_axis_None(self):
+        # When no axis is given, concatenate uses flattened versions.
+        # This also had a bug with many arrays (see gh-5979).
+        x = np.arange(1, 100)
+        r = np.concatenate(x, None)
+        assert_array_equal(x, r)
+
+        # This should probably be deprecated:
+        r = np.concatenate(x, 100)  # axis is >= MAXDIMS
+        assert_array_equal(x, r)
+
+    def test_concatenate(self):
+        # Test concatenate function
+        # One sequence returns unmodified (but as array)
+        r4 = list(range(4))
+        assert_array_equal(concatenate((r4,)), r4)
+        # Any sequence
+        assert_array_equal(concatenate((tuple(r4),)), r4)
+        assert_array_equal(concatenate((array(r4),)), r4)
+        # 1D default concatenation
+        r3 = list(range(3))
+        assert_array_equal(concatenate((r4, r3)), r4 + r3)
+        # Mixed sequence types
+        assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3)
+        assert_array_equal(concatenate((array(r4), r3)), r4 + r3)
+        # Explicit axis specification
+        assert_array_equal(concatenate((r4, r3), 0), r4 + r3)
+        # Including negative
+        assert_array_equal(concatenate((r4, r3), -1), r4 + r3)
+        # 2D
+        a23 = array([[10, 11, 12], [13, 14, 15]])
+        a13 = array([[0, 1, 2]])
+        res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]])
+        assert_array_equal(concatenate((a23, a13)), res)
+        assert_array_equal(concatenate((a23, a13), 0), res)
+        assert_array_equal(concatenate((a23.T, a13.T), 1), res.T)
+        assert_array_equal(concatenate((a23.T, a13.T), -1), res.T)
+        # Arrays much match shape
+        assert_raises(ValueError, concatenate, (a23.T, a13.T), 0)
+        # 3D
+        res = arange(2 * 3 * 7).reshape((2, 3, 7))
+        a0 = res[..., :4]
+        a1 = res[..., 4:6]
+        a2 = res[..., 6:]
+        assert_array_equal(concatenate((a0, a1, a2), 2), res)
+        assert_array_equal(concatenate((a0, a1, a2), -1), res)
+        assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T)
+
+
+def test_stack():
+    # 0d input
+    for input_ in [(1, 2, 3),
+                   [np.int32(1), np.int32(2), np.int32(3)],
+                   [np.array(1), np.array(2), np.array(3)]]:
+        assert_array_equal(stack(input_), [1, 2, 3])
+    # 1d input examples
+    a = np.array([1, 2, 3])
+    b = np.array([4, 5, 6])
+    r1 = array([[1, 2, 3], [4, 5, 6]])
+    assert_array_equal(np.stack((a, b)), r1)
+    assert_array_equal(np.stack((a, b), axis=1), r1.T)
+    # all input types
+    assert_array_equal(np.stack(list([a, b])), r1)
+    assert_array_equal(np.stack(array([a, b])), r1)
+    # all shapes for 1d input
+    arrays = [np.random.randn(3) for _ in range(10)]
+    axes = [0, 1, -1, -2]
+    expected_shapes = [(10, 3), (3, 10), (3, 10), (10, 3)]
+    for axis, expected_shape in zip(axes, expected_shapes):
+        assert_equal(np.stack(arrays, axis).shape, expected_shape)
+    assert_raises_regex(IndexError, 'out of bounds', stack, arrays, axis=2)
+    assert_raises_regex(IndexError, 'out of bounds', stack, arrays, axis=-3)
+    # all shapes for 2d input
+    arrays = [np.random.randn(3, 4) for _ in range(10)]
+    axes = [0, 1, 2, -1, -2, -3]
+    expected_shapes = [(10, 3, 4), (3, 10, 4), (3, 4, 10),
+                        (3, 4, 10), (3, 10, 4), (10, 3, 4)]
+    for axis, expected_shape in zip(axes, expected_shapes):
+        assert_equal(np.stack(arrays, axis).shape, expected_shape)
+    # empty arrays
+    assert_(stack([[], [], []]).shape == (3, 0))
+    assert_(stack([[], [], []], axis=1).shape == (0, 3))
+    # edge cases
+    assert_raises_regex(ValueError, 'need at least one array', stack, [])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [1, np.arange(3)])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(3), 1])
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(3), 1], axis=1)
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.zeros((3, 3)), np.zeros(3)], axis=1)
+    assert_raises_regex(ValueError, 'must have the same shape',
+                        stack, [np.arange(2), np.arange(3)])
+    # np.matrix
+    m = np.matrix([[1, 2], [3, 4]])
+    assert_raises_regex(ValueError, 'shape too large to be a matrix',
+                        stack, [m, m])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
new file mode 100644
index 0000000000..ab8cecff0f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
@@ -0,0 +1,1243 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.core.umath_tests as umt
+import numpy.core.operand_flag_tests as opflag_tests
+from numpy.compat import asbytes
+from numpy.core.test_rational import rational, test_add, test_add_rationals
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_almost_equal, assert_array_almost_equal,
+    assert_no_warnings
+)
+
+
+class TestUfuncKwargs(TestCase):
+    def test_kwarg_exact(self):
+        assert_raises(TypeError, np.add, 1, 2, castingx='safe')
+        assert_raises(TypeError, np.add, 1, 2, dtypex=np.int)
+        assert_raises(TypeError, np.add, 1, 2, extobjx=[4096])
+        assert_raises(TypeError, np.add, 1, 2, outx=None)
+        assert_raises(TypeError, np.add, 1, 2, sigx='ii->i')
+        assert_raises(TypeError, np.add, 1, 2, signaturex='ii->i')
+        assert_raises(TypeError, np.add, 1, 2, subokx=False)
+        assert_raises(TypeError, np.add, 1, 2, wherex=[True])
+
+    def test_sig_signature(self):
+        assert_raises(ValueError, np.add, 1, 2, sig='ii->i',
+                      signature='ii->i')
+
+    def test_sig_dtype(self):
+        assert_raises(RuntimeError, np.add, 1, 2, sig='ii->i',
+                      dtype=np.int)
+        assert_raises(RuntimeError, np.add, 1, 2, signature='ii->i',
+                      dtype=np.int)
+
+
+class TestUfunc(TestCase):
+    def test_pickle(self):
+        import pickle
+        assert_(pickle.loads(pickle.dumps(np.sin)) is np.sin)
+
+        # Check that ufunc not defined in the top level numpy namespace such as
+        # numpy.core.test_rational.test_add can also be pickled
+        assert_(pickle.loads(pickle.dumps(test_add)) is test_add)
+
+    def test_pickle_withstring(self):
+        import pickle
+        astring = asbytes("cnumpy.core\n_ufunc_reconstruct\np0\n"
+                "(S'numpy.core.umath'\np1\nS'cos'\np2\ntp3\nRp4\n.")
+        assert_(pickle.loads(astring) is np.cos)
+
+    def test_reduceat_shifting_sum(self):
+        L = 6
+        x = np.arange(L)
+        idx = np.array(list(zip(np.arange(L - 2), np.arange(L - 2) + 2))).ravel()
+        assert_array_equal(np.add.reduceat(x, idx)[::2], [1, 3, 5, 7])
+
+    def test_generic_loops(self):
+        """Test generic loops.
+
+        The loops to be tested are:
+
+            PyUFunc_ff_f_As_dd_d
+            PyUFunc_ff_f
+            PyUFunc_dd_d
+            PyUFunc_gg_g
+            PyUFunc_FF_F_As_DD_D
+            PyUFunc_DD_D
+            PyUFunc_FF_F
+            PyUFunc_GG_G
+            PyUFunc_OO_O
+            PyUFunc_OO_O_method
+            PyUFunc_f_f_As_d_d
+            PyUFunc_d_d
+            PyUFunc_f_f
+            PyUFunc_g_g
+            PyUFunc_F_F_As_D_D
+            PyUFunc_F_F
+            PyUFunc_D_D
+            PyUFunc_G_G
+            PyUFunc_O_O
+            PyUFunc_O_O_method
+            PyUFunc_On_Om
+
+        Where:
+
+            f -- float
+            d -- double
+            g -- long double
+            F -- complex float
+            D -- complex double
+            G -- complex long double
+            O -- python object
+
+        It is difficult to assure that each of these loops is entered from the
+        Python level as the special cased loops are a moving target and the
+        corresponding types are architecture dependent. We probably need to
+        define C level testing ufuncs to get at them. For the time being, I've
+        just looked at the signatures registered in the build directory to find
+        relevant functions.
+
+        Fixme, currently untested:
+
+            PyUFunc_ff_f_As_dd_d
+            PyUFunc_FF_F_As_DD_D
+            PyUFunc_f_f_As_d_d
+            PyUFunc_F_F_As_D_D
+            PyUFunc_On_Om
+
+        """
+        fone = np.exp
+        ftwo = lambda x, y: x**y
+        fone_val = 1
+        ftwo_val = 1
+        # check unary PyUFunc_f_f.
+        msg = "PyUFunc_f_f"
+        x = np.zeros(10, dtype=np.single)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_d_d.
+        msg = "PyUFunc_d_d"
+        x = np.zeros(10, dtype=np.double)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_g_g.
+        msg = "PyUFunc_g_g"
+        x = np.zeros(10, dtype=np.longdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_F_F.
+        msg = "PyUFunc_F_F"
+        x = np.zeros(10, dtype=np.csingle)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_D_D.
+        msg = "PyUFunc_D_D"
+        x = np.zeros(10, dtype=np.cdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+        # check unary PyUFunc_G_G.
+        msg = "PyUFunc_G_G"
+        x = np.zeros(10, dtype=np.clongdouble)[0::2]
+        assert_almost_equal(fone(x), fone_val, err_msg=msg)
+
+        # check binary PyUFunc_ff_f.
+        msg = "PyUFunc_ff_f"
+        x = np.ones(10, dtype=np.single)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_dd_d.
+        msg = "PyUFunc_dd_d"
+        x = np.ones(10, dtype=np.double)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_gg_g.
+        msg = "PyUFunc_gg_g"
+        x = np.ones(10, dtype=np.longdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_FF_F.
+        msg = "PyUFunc_FF_F"
+        x = np.ones(10, dtype=np.csingle)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_DD_D.
+        msg = "PyUFunc_DD_D"
+        x = np.ones(10, dtype=np.cdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+        # check binary PyUFunc_GG_G.
+        msg = "PyUFunc_GG_G"
+        x = np.ones(10, dtype=np.clongdouble)[0::2]
+        assert_almost_equal(ftwo(x, x), ftwo_val, err_msg=msg)
+
+        # class to use in testing object method loops
+        class foo(object):
+            def conjugate(self):
+                return np.bool_(1)
+
+            def logical_xor(self, obj):
+                return np.bool_(1)
+
+        # check unary PyUFunc_O_O
+        msg = "PyUFunc_O_O"
+        x = np.ones(10, dtype=np.object)[0::2]
+        assert_(np.all(np.abs(x) == 1), msg)
+        # check unary PyUFunc_O_O_method
+        msg = "PyUFunc_O_O_method"
+        x = np.zeros(10, dtype=np.object)[0::2]
+        for i in range(len(x)):
+            x[i] = foo()
+        assert_(np.all(np.conjugate(x) == True), msg)
+
+        # check binary PyUFunc_OO_O
+        msg = "PyUFunc_OO_O"
+        x = np.ones(10, dtype=np.object)[0::2]
+        assert_(np.all(np.add(x, x) == 2), msg)
+        # check binary PyUFunc_OO_O_method
+        msg = "PyUFunc_OO_O_method"
+        x = np.zeros(10, dtype=np.object)[0::2]
+        for i in range(len(x)):
+            x[i] = foo()
+        assert_(np.all(np.logical_xor(x, x)), msg)
+
+        # check PyUFunc_On_Om
+        # fixme -- I don't know how to do this yet
+
+    def test_all_ufunc(self):
+        """Try to check presence and results of all ufuncs.
+
+        The list of ufuncs comes from generate_umath.py and is as follows:
+
+        =====  ====  =============  ===============  ========================
+        done   args   function        types                notes
+        =====  ====  =============  ===============  ========================
+        n      1     conjugate      nums + O
+        n      1     absolute       nums + O         complex -> real
+        n      1     negative       nums + O
+        n      1     sign           nums + O         -> int
+        n      1     invert         bool + ints + O  flts raise an error
+        n      1     degrees        real + M         cmplx raise an error
+        n      1     radians        real + M         cmplx raise an error
+        n      1     arccos         flts + M
+        n      1     arccosh        flts + M
+        n      1     arcsin         flts + M
+        n      1     arcsinh        flts + M
+        n      1     arctan         flts + M
+        n      1     arctanh        flts + M
+        n      1     cos            flts + M
+        n      1     sin            flts + M
+        n      1     tan            flts + M
+        n      1     cosh           flts + M
+        n      1     sinh           flts + M
+        n      1     tanh           flts + M
+        n      1     exp            flts + M
+        n      1     expm1          flts + M
+        n      1     log            flts + M
+        n      1     log10          flts + M
+        n      1     log1p          flts + M
+        n      1     sqrt           flts + M         real x < 0 raises error
+        n      1     ceil           real + M
+        n      1     trunc          real + M
+        n      1     floor          real + M
+        n      1     fabs           real + M
+        n      1     rint           flts + M
+        n      1     isnan          flts             -> bool
+        n      1     isinf          flts             -> bool
+        n      1     isfinite       flts             -> bool
+        n      1     signbit        real             -> bool
+        n      1     modf           real             -> (frac, int)
+        n      1     logical_not    bool + nums + M  -> bool
+        n      2     left_shift     ints + O         flts raise an error
+        n      2     right_shift    ints + O         flts raise an error
+        n      2     add            bool + nums + O  boolean + is ||
+        n      2     subtract       bool + nums + O  boolean - is ^
+        n      2     multiply       bool + nums + O  boolean * is &
+        n      2     divide         nums + O
+        n      2     floor_divide   nums + O
+        n      2     true_divide    nums + O         bBhH -> f, iIlLqQ -> d
+        n      2     fmod           nums + M
+        n      2     power          nums + O
+        n      2     greater        bool + nums + O  -> bool
+        n      2     greater_equal  bool + nums + O  -> bool
+        n      2     less           bool + nums + O  -> bool
+        n      2     less_equal     bool + nums + O  -> bool
+        n      2     equal          bool + nums + O  -> bool
+        n      2     not_equal      bool + nums + O  -> bool
+        n      2     logical_and    bool + nums + M  -> bool
+        n      2     logical_or     bool + nums + M  -> bool
+        n      2     logical_xor    bool + nums + M  -> bool
+        n      2     maximum        bool + nums + O
+        n      2     minimum        bool + nums + O
+        n      2     bitwise_and    bool + ints + O  flts raise an error
+        n      2     bitwise_or     bool + ints + O  flts raise an error
+        n      2     bitwise_xor    bool + ints + O  flts raise an error
+        n      2     arctan2        real + M
+        n      2     remainder      ints + real + O
+        n      2     hypot          real + M
+        =====  ====  =============  ===============  ========================
+
+        Types other than those listed will be accepted, but they are cast to
+        the smallest compatible type for which the function is defined. The
+        casting rules are:
+
+        bool -> int8 -> float32
+        ints -> double
+
+        """
+        pass
+
+    def test_signature(self):
+        # the arguments to test_signature are: nin, nout, core_signature
+        # pass
+        assert_equal(umt.test_signature(2, 1, "(i),(i)->()"), 1)
+
+        # pass. empty core signature; treat as plain ufunc (with trivial core)
+        assert_equal(umt.test_signature(2, 1, "(),()->()"), 0)
+
+        # in the following calls, a ValueError should be raised because
+        # of error in core signature
+        # FIXME These should be using assert_raises
+
+        # error: extra parenthesis
+        msg = "core_sig: extra parenthesis"
+        try:
+            ret = umt.test_signature(2, 1, "((i)),(i)->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: parenthesis matching
+        msg = "core_sig: parenthesis matching"
+        try:
+            ret = umt.test_signature(2, 1, "(i),)i(->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: incomplete signature. letters outside of parenthesis are ignored
+        msg = "core_sig: incomplete signature"
+        try:
+            ret = umt.test_signature(2, 1, "(i),->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # error: incomplete signature. 2 output arguments are specified
+        msg = "core_sig: incomplete signature"
+        try:
+            ret = umt.test_signature(2, 2, "(i),(i)->()")
+            assert_equal(ret, None, err_msg=msg)
+        except ValueError:
+            pass
+
+        # more complicated names for variables
+        assert_equal(umt.test_signature(2, 1, "(i1,i2),(J_1)->(_kAB)"), 1)
+
+    def test_get_signature(self):
+        assert_equal(umt.inner1d.signature, "(i),(i)->()")
+
+    def test_forced_sig(self):
+        a = 0.5*np.arange(3, dtype='f8')
+        assert_equal(np.add(a, 0.5), [0.5, 1, 1.5])
+        assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig='ii->i', casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'), [0, 0, 1])
+        assert_equal(np.add(a, 0.5, sig=('i4', 'i4', 'i4'),
+                                            casting='unsafe'), [0, 0, 1])
+
+        b = np.zeros((3,), dtype='f8')
+        np.add(a, 0.5, out=b)
+        assert_equal(b, [0.5, 1, 1.5])
+        b[:] = 0
+        np.add(a, 0.5, sig='i', out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig='ii->i', out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+        b[:] = 0
+        np.add(a, 0.5, sig=('i4', 'i4', 'i4'), out=b, casting='unsafe')
+        assert_equal(b, [0, 0, 1])
+
+    def test_true_divide(self):
+        # True_divide has a non uniform signature, see #3484.
+        # This also tests type_tuple_type_resolver.
+        a = np.full(5, 12.5)
+        b = np.full(5, 10.0)
+        tgt = np.full(5, 1.25)
+        assert_almost_equal(np.true_divide(a, b, dtype=np.float64), tgt)
+        assert_almost_equal(np.true_divide(a, b, dtype=np.float32), tgt)
+        assert_raises(TypeError, np.true_divide, a, b, dtype=np.int)
+
+    def test_sum_stability(self):
+        a = np.ones(500, dtype=np.float32)
+        assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 4)
+
+        a = np.ones(500, dtype=np.float64)
+        assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 13)
+
+    def test_sum(self):
+        for dt in (np.int, np.float16, np.float32, np.float64, np.longdouble):
+            for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
+                      128, 1024, 1235):
+                tgt = dt(v * (v + 1) / 2)
+                d = np.arange(1, v + 1, dtype=dt)
+                assert_almost_equal(np.sum(d), tgt)
+                assert_almost_equal(np.sum(d[::-1]), tgt)
+
+            d = np.ones(500, dtype=dt)
+            assert_almost_equal(np.sum(d[::2]), 250.)
+            assert_almost_equal(np.sum(d[1::2]), 250.)
+            assert_almost_equal(np.sum(d[::3]), 167.)
+            assert_almost_equal(np.sum(d[1::3]), 167.)
+            assert_almost_equal(np.sum(d[::-2]), 250.)
+            assert_almost_equal(np.sum(d[-1::-2]), 250.)
+            assert_almost_equal(np.sum(d[::-3]), 167.)
+            assert_almost_equal(np.sum(d[-1::-3]), 167.)
+            # sum with first reduction entry != 0
+            d = np.ones((1,), dtype=dt)
+            d += d
+            assert_almost_equal(d, 2.)
+
+    def test_sum_complex(self):
+        for dt in (np.complex64, np.complex128, np.clongdouble):
+            for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
+                      128, 1024, 1235):
+                tgt = dt(v * (v + 1) / 2) - dt((v * (v + 1) / 2) * 1j)
+                d = np.empty(v, dtype=dt)
+                d.real = np.arange(1, v + 1)
+                d.imag = -np.arange(1, v + 1)
+                assert_almost_equal(np.sum(d), tgt)
+                assert_almost_equal(np.sum(d[::-1]), tgt)
+
+            d = np.ones(500, dtype=dt) + 1j
+            assert_almost_equal(np.sum(d[::2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[1::2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[::3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[1::3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[::-2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[-1::-2]), 250. + 250j)
+            assert_almost_equal(np.sum(d[::-3]), 167. + 167j)
+            assert_almost_equal(np.sum(d[-1::-3]), 167. + 167j)
+            # sum with first reduction entry != 0
+            d = np.ones((1,), dtype=dt) + 1j
+            d += d
+            assert_almost_equal(d, 2. + 2j)
+
+    def test_inner1d(self):
+        a = np.arange(6).reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1))
+        a = np.arange(6)
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a))
+
+    def test_broadcast(self):
+        msg = "broadcast"
+        a = np.arange(4).reshape((2, 1, 2))
+        b = np.arange(4).reshape((1, 2, 2))
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        msg = "extend & broadcast loop dimensions"
+        b = np.arange(4).reshape((2, 2))
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        # Broadcast in core dimensions should fail
+        a = np.arange(8).reshape((4, 2))
+        b = np.arange(4).reshape((4, 1))
+        assert_raises(ValueError, umt.inner1d, a, b)
+        # Extend core dimensions should fail
+        a = np.arange(8).reshape((4, 2))
+        b = np.array(7)
+        assert_raises(ValueError, umt.inner1d, a, b)
+        # Broadcast should fail
+        a = np.arange(2).reshape((2, 1, 1))
+        b = np.arange(3).reshape((3, 1, 1))
+        assert_raises(ValueError, umt.inner1d, a, b)
+
+    def test_type_cast(self):
+        msg = "type cast"
+        a = np.arange(6, dtype='short').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+        msg = "type cast on one argument"
+        a = np.arange(6).reshape((2, 3))
+        b = a + 0.1
+        assert_array_almost_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1),
+                                  err_msg=msg)
+
+    def test_endian(self):
+        msg = "big endian"
+        a = np.arange(6, dtype='>i4').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+        msg = "little endian"
+        a = np.arange(6, dtype='<i4').reshape((2, 3))
+        assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
+                           err_msg=msg)
+
+        # Output should always be native-endian
+        Ba = np.arange(1, dtype='>f8')
+        La = np.arange(1, dtype='<f8')
+        assert_equal((Ba+Ba).dtype, np.dtype('f8'))
+        assert_equal((Ba+La).dtype, np.dtype('f8'))
+        assert_equal((La+Ba).dtype, np.dtype('f8'))
+        assert_equal((La+La).dtype, np.dtype('f8'))
+
+        assert_equal(np.absolute(La).dtype, np.dtype('f8'))
+        assert_equal(np.absolute(Ba).dtype, np.dtype('f8'))
+        assert_equal(np.negative(La).dtype, np.dtype('f8'))
+        assert_equal(np.negative(Ba).dtype, np.dtype('f8'))
+
+    def test_incontiguous_array(self):
+        msg = "incontiguous memory layout of array"
+        x = np.arange(64).reshape((2, 2, 2, 2, 2, 2))
+        a = x[:, 0,:, 0,:, 0]
+        b = x[:, 1,:, 1,:, 1]
+        a[0, 0, 0] = -1
+        msg2 = "make sure it references to the original array"
+        assert_equal(x[0, 0, 0, 0, 0, 0], -1, err_msg=msg2)
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+        x = np.arange(24).reshape(2, 3, 4)
+        a = x.T
+        b = x.T
+        a[0, 0, 0] = -1
+        assert_equal(x[0, 0, 0], -1, err_msg=msg2)
+        assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
+
+    def test_output_argument(self):
+        msg = "output argument"
+        a = np.arange(12).reshape((2, 3, 2))
+        b = np.arange(4).reshape((2, 1, 2)) + 1
+        c = np.zeros((2, 3), dtype='int')
+        umt.inner1d(a, b, c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+
+        msg = "output argument with type cast"
+        c = np.zeros((2, 3), dtype='int16')
+        umt.inner1d(a, b, c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c)
+        assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
+
+        msg = "output argument with incontiguous layout"
+        c = np.zeros((2, 3, 4), dtype='int16')
+        umt.inner1d(a, b, c[..., 0])
+        assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
+        c[:] = -1
+        umt.inner1d(a, b, out=c[..., 0])
+        assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
+
+    def test_innerwt(self):
+        a = np.arange(6).reshape((2, 3))
+        b = np.arange(10, 16).reshape((2, 3))
+        w = np.arange(20, 26).reshape((2, 3))
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+        a = np.arange(100, 124).reshape((2, 3, 4))
+        b = np.arange(200, 224).reshape((2, 3, 4))
+        w = np.arange(300, 324).reshape((2, 3, 4))
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+
+    def test_innerwt_empty(self):
+        """Test generalized ufunc with zero-sized operands"""
+        a = np.array([], dtype='f8')
+        b = np.array([], dtype='f8')
+        w = np.array([], dtype='f8')
+        assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
+
+    def test_matrix_multiply(self):
+        self.compare_matrix_multiply_results(np.long)
+        self.compare_matrix_multiply_results(np.double)
+
+    def compare_matrix_multiply_results(self, tp):
+        d1 = np.array(np.random.rand(2, 3, 4), dtype=tp)
+        d2 = np.array(np.random.rand(2, 3, 4), dtype=tp)
+        msg = "matrix multiply on type %s" % d1.dtype.name
+
+        def permute_n(n):
+            if n == 1:
+                return ([0],)
+            ret = ()
+            base = permute_n(n-1)
+            for perm in base:
+                for i in range(n):
+                    new = perm + [n-1]
+                    new[n-1] = new[i]
+                    new[i] = n-1
+                    ret += (new,)
+            return ret
+
+        def slice_n(n):
+            if n == 0:
+                return ((),)
+            ret = ()
+            base = slice_n(n-1)
+            for sl in base:
+                ret += (sl+(slice(None),),)
+                ret += (sl+(slice(0, 1),),)
+            return ret
+
+        def broadcastable(s1, s2):
+            return s1 == s2 or s1 == 1 or s2 == 1
+
+        permute_3 = permute_n(3)
+        slice_3 = slice_n(3) + ((slice(None, None, -1),)*3,)
+
+        ref = True
+        for p1 in permute_3:
+            for p2 in permute_3:
+                for s1 in slice_3:
+                    for s2 in slice_3:
+                        a1 = d1.transpose(p1)[s1]
+                        a2 = d2.transpose(p2)[s2]
+                        ref = ref and a1.base is not None
+                        ref = ref and a2.base is not None
+                        if (a1.shape[-1] == a2.shape[-2] and
+                                broadcastable(a1.shape[0], a2.shape[0])):
+                            assert_array_almost_equal(
+                                umt.matrix_multiply(a1, a2),
+                                np.sum(a2[..., np.newaxis].swapaxes(-3, -1) *
+                                       a1[..., np.newaxis,:], axis=-1),
+                                err_msg=msg + ' %s %s' % (str(a1.shape),
+                                                          str(a2.shape)))
+
+        assert_equal(ref, True, err_msg="reference check")
+
+    def test_euclidean_pdist(self):
+        a = np.arange(12, dtype=np.float).reshape(4, 3)
+        out = np.empty((a.shape[0] * (a.shape[0] - 1) // 2,), dtype=a.dtype)
+        umt.euclidean_pdist(a, out)
+        b = np.sqrt(np.sum((a[:, None] - a)**2, axis=-1))
+        b = b[~np.tri(a.shape[0], dtype=bool)]
+        assert_almost_equal(out, b)
+        # An output array is required to determine p with signature (n,d)->(p)
+        assert_raises(ValueError, umt.euclidean_pdist, a)
+
+    def test_object_logical(self):
+        a = np.array([3, None, True, False, "test", ""], dtype=object)
+        assert_equal(np.logical_or(a, None),
+                        np.array([x or None for x in a], dtype=object))
+        assert_equal(np.logical_or(a, True),
+                        np.array([x or True for x in a], dtype=object))
+        assert_equal(np.logical_or(a, 12),
+                        np.array([x or 12 for x in a], dtype=object))
+        assert_equal(np.logical_or(a, "blah"),
+                        np.array([x or "blah" for x in a], dtype=object))
+
+        assert_equal(np.logical_and(a, None),
+                        np.array([x and None for x in a], dtype=object))
+        assert_equal(np.logical_and(a, True),
+                        np.array([x and True for x in a], dtype=object))
+        assert_equal(np.logical_and(a, 12),
+                        np.array([x and 12 for x in a], dtype=object))
+        assert_equal(np.logical_and(a, "blah"),
+                        np.array([x and "blah" for x in a], dtype=object))
+
+        assert_equal(np.logical_not(a),
+                        np.array([not x for x in a], dtype=object))
+
+        assert_equal(np.logical_or.reduce(a), 3)
+        assert_equal(np.logical_and.reduce(a), None)
+
+    def test_object_array_reduction(self):
+        # Reductions on object arrays
+        a = np.array(['a', 'b', 'c'], dtype=object)
+        assert_equal(np.sum(a), 'abc')
+        assert_equal(np.max(a), 'c')
+        assert_equal(np.min(a), 'a')
+        a = np.array([True, False, True], dtype=object)
+        assert_equal(np.sum(a), 2)
+        assert_equal(np.prod(a), 0)
+        assert_equal(np.any(a), True)
+        assert_equal(np.all(a), False)
+        assert_equal(np.max(a), True)
+        assert_equal(np.min(a), False)
+        assert_equal(np.array([[1]], dtype=object).sum(), 1)
+        assert_equal(np.array([[[1, 2]]], dtype=object).sum((0, 1)), [1, 2])
+
+    def test_object_array_accumulate_inplace(self):
+        # Checks that in-place accumulates work, see also gh-7402
+        arr = np.ones(4, dtype=object)
+        arr[:] = [[1] for i in range(4)]
+        # Twice reproduced also for tuples:
+        np.add.accumulate(arr, out=arr)
+        np.add.accumulate(arr, out=arr)
+        assert_array_equal(arr, np.array([[1]*i for i in [1, 3, 6, 10]]))
+
+        # And the same if the axis argument is used
+        arr = np.ones((2, 4), dtype=object)
+        arr[0, :] = [[2] for i in range(4)]
+        np.add.accumulate(arr, out=arr, axis=-1)
+        np.add.accumulate(arr, out=arr, axis=-1)
+        assert_array_equal(arr[0, :], np.array([[2]*i for i in [1, 3, 6, 10]]))
+
+    def test_object_scalar_multiply(self):
+        # Tickets #2469 and #4482
+        arr = np.matrix([1, 2], dtype=object)
+        desired = np.matrix([[3, 6]], dtype=object)
+        assert_equal(np.multiply(arr, 3), desired)
+        assert_equal(np.multiply(3, arr), desired)
+
+    def test_zerosize_reduction(self):
+        # Test with default dtype and object dtype
+        for a in [[], np.array([], dtype=object)]:
+            assert_equal(np.sum(a), 0)
+            assert_equal(np.prod(a), 1)
+            assert_equal(np.any(a), False)
+            assert_equal(np.all(a), True)
+            assert_raises(ValueError, np.max, a)
+            assert_raises(ValueError, np.min, a)
+
+    def test_axis_out_of_bounds(self):
+        a = np.array([False, False])
+        assert_raises(ValueError, a.all, axis=1)
+        a = np.array([False, False])
+        assert_raises(ValueError, a.all, axis=-2)
+
+        a = np.array([False, False])
+        assert_raises(ValueError, a.any, axis=1)
+        a = np.array([False, False])
+        assert_raises(ValueError, a.any, axis=-2)
+
+    def test_scalar_reduction(self):
+        # The functions 'sum', 'prod', etc allow specifying axis=0
+        # even for scalars
+        assert_equal(np.sum(3, axis=0), 3)
+        assert_equal(np.prod(3.5, axis=0), 3.5)
+        assert_equal(np.any(True, axis=0), True)
+        assert_equal(np.all(False, axis=0), False)
+        assert_equal(np.max(3, axis=0), 3)
+        assert_equal(np.min(2.5, axis=0), 2.5)
+
+        # Check scalar behaviour for ufuncs without an identity
+        assert_equal(np.power.reduce(3), 3)
+
+        # Make sure that scalars are coming out from this operation
+        assert_(type(np.prod(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.sum(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.max(np.float32(2.5), axis=0)) is np.float32)
+        assert_(type(np.min(np.float32(2.5), axis=0)) is np.float32)
+
+        # check if scalars/0-d arrays get cast
+        assert_(type(np.any(0, axis=0)) is np.bool_)
+
+        # assert that 0-d arrays get wrapped
+        class MyArray(np.ndarray):
+            pass
+        a = np.array(1).view(MyArray)
+        assert_(type(np.any(a)) is MyArray)
+
+    def test_casting_out_param(self):
+        # Test that it's possible to do casts on output
+        a = np.ones((200, 100), np.int64)
+        b = np.ones((200, 100), np.int64)
+        c = np.ones((200, 100), np.float64)
+        np.add(a, b, out=c)
+        assert_equal(c, 2)
+
+        a = np.zeros(65536)
+        b = np.zeros(65536, dtype=np.float32)
+        np.subtract(a, 0, out=b)
+        assert_equal(b, 0)
+
+    def test_where_param(self):
+        # Test that the where= ufunc parameter works with regular arrays
+        a = np.arange(7)
+        b = np.ones(7)
+        c = np.zeros(7)
+        np.add(a, b, out=c, where=(a % 2 == 1))
+        assert_equal(c, [0, 2, 0, 4, 0, 6, 0])
+
+        a = np.arange(4).reshape(2, 2) + 2
+        np.power(a, [2, 3], out=a, where=[[0, 1], [1, 0]])
+        assert_equal(a, [[2, 27], [16, 5]])
+        # Broadcasting the where= parameter
+        np.subtract(a, 2, out=a, where=[True, False])
+        assert_equal(a, [[0, 27], [14, 5]])
+
+    def test_where_param_buffer_output(self):
+        # This test is temporarily skipped because it requires
+        # adding masking features to the nditer to work properly
+
+        # With casting on output
+        a = np.ones(10, np.int64)
+        b = np.ones(10, np.int64)
+        c = 1.5 * np.ones(10, np.float64)
+        np.add(a, b, out=c, where=[1, 0, 0, 1, 0, 0, 1, 1, 1, 0])
+        assert_equal(c, [2, 1.5, 1.5, 2, 1.5, 1.5, 2, 2, 2, 1.5])
+
+    def check_identityless_reduction(self, a):
+        # np.minimum.reduce is a identityless reduction
+
+        # Verify that it sees the zero at various positions
+        a[...] = 1
+        a[1, 0, 0] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [1, 0])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[1, 1, 1, 1], [0, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[1, 1, 1], [0, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+        a[...] = 1
+        a[0, 1, 0] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [1, 0, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[1, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[0, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[1, 0, 1], [1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+        a[...] = 1
+        a[0, 0, 1] = 0
+        assert_equal(np.minimum.reduce(a, axis=None), 0)
+        assert_equal(np.minimum.reduce(a, axis=(0, 1)), [1, 0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
+        assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
+        assert_equal(np.minimum.reduce(a, axis=0),
+                                    [[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=1),
+                                    [[1, 0, 1, 1], [1, 1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=2),
+                                    [[0, 1, 1], [1, 1, 1]])
+        assert_equal(np.minimum.reduce(a, axis=()), a)
+
+    def test_identityless_reduction_corder(self):
+        a = np.empty((2, 3, 4), order='C')
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_forder(self):
+        a = np.empty((2, 3, 4), order='F')
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_otherorder(self):
+        a = np.empty((2, 4, 3), order='C').swapaxes(1, 2)
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_noncontig(self):
+        a = np.empty((3, 5, 4), order='C').swapaxes(1, 2)
+        a = a[1:, 1:, 1:]
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_noncontig_unaligned(self):
+        a = np.empty((3*4*5*8 + 1,), dtype='i1')
+        a = a[1:].view(dtype='f8')
+        a.shape = (3, 4, 5)
+        a = a[1:, 1:, 1:]
+        self.check_identityless_reduction(a)
+
+    def test_identityless_reduction_nonreorderable(self):
+        a = np.array([[8.0, 2.0, 2.0], [1.0, 0.5, 0.25]])
+
+        res = np.divide.reduce(a, axis=0)
+        assert_equal(res, [8.0, 4.0, 8.0])
+
+        res = np.divide.reduce(a, axis=1)
+        assert_equal(res, [2.0, 8.0])
+
+        res = np.divide.reduce(a, axis=())
+        assert_equal(res, a)
+
+        assert_raises(ValueError, np.divide.reduce, a, axis=(0, 1))
+
+    def test_reduce_zero_axis(self):
+        # If we have a n x m array and do a reduction with axis=1, then we are
+        # doing n reductions, and each reduction takes an m-element array. For
+        # a reduction operation without an identity, then:
+        #   n > 0, m > 0: fine
+        #   n = 0, m > 0: fine, doing 0 reductions of m-element arrays
+        #   n > 0, m = 0: can't reduce a 0-element array, ValueError
+        #   n = 0, m = 0: can't reduce a 0-element array, ValueError (for
+        #     consistency with the above case)
+        # This test doesn't actually look at return values, it just checks to
+        # make sure that error we get an error in exactly those cases where we
+        # expect one, and assumes the calculations themselves are done
+        # correctly.
+
+        def ok(f, *args, **kwargs):
+            f(*args, **kwargs)
+
+        def err(f, *args, **kwargs):
+            assert_raises(ValueError, f, *args, **kwargs)
+
+        def t(expect, func, n, m):
+            expect(func, np.zeros((n, m)), axis=1)
+            expect(func, np.zeros((m, n)), axis=0)
+            expect(func, np.zeros((n // 2, n // 2, m)), axis=2)
+            expect(func, np.zeros((n // 2, m, n // 2)), axis=1)
+            expect(func, np.zeros((n, m // 2, m // 2)), axis=(1, 2))
+            expect(func, np.zeros((m // 2, n, m // 2)), axis=(0, 2))
+            expect(func, np.zeros((m // 3, m // 3, m // 3,
+                                  n // 2, n // 2)),
+                                 axis=(0, 1, 2))
+            # Check what happens if the inner (resp. outer) dimensions are a
+            # mix of zero and non-zero:
+            expect(func, np.zeros((10, m, n)), axis=(0, 1))
+            expect(func, np.zeros((10, n, m)), axis=(0, 2))
+            expect(func, np.zeros((m, 10, n)), axis=0)
+            expect(func, np.zeros((10, m, n)), axis=1)
+            expect(func, np.zeros((10, n, m)), axis=2)
+
+        # np.maximum is just an arbitrary ufunc with no reduction identity
+        assert_equal(np.maximum.identity, None)
+        t(ok, np.maximum.reduce, 30, 30)
+        t(ok, np.maximum.reduce, 0, 30)
+        t(err, np.maximum.reduce, 30, 0)
+        t(err, np.maximum.reduce, 0, 0)
+        err(np.maximum.reduce, [])
+        np.maximum.reduce(np.zeros((0, 0)), axis=())
+
+        # all of the combinations are fine for a reduction that has an
+        # identity
+        t(ok, np.add.reduce, 30, 30)
+        t(ok, np.add.reduce, 0, 30)
+        t(ok, np.add.reduce, 30, 0)
+        t(ok, np.add.reduce, 0, 0)
+        np.add.reduce([])
+        np.add.reduce(np.zeros((0, 0)), axis=())
+
+        # OTOH, accumulate always makes sense for any combination of n and m,
+        # because it maps an m-element array to an m-element array. These
+        # tests are simpler because accumulate doesn't accept multiple axes.
+        for uf in (np.maximum, np.add):
+            uf.accumulate(np.zeros((30, 0)), axis=0)
+            uf.accumulate(np.zeros((0, 30)), axis=0)
+            uf.accumulate(np.zeros((30, 30)), axis=0)
+            uf.accumulate(np.zeros((0, 0)), axis=0)
+
+    def test_safe_casting(self):
+        # In old versions of numpy, in-place operations used the 'unsafe'
+        # casting rules. In versions >= 1.10, 'same_kind' is the
+        # default and an exception is raised instead of a warning.
+        # when 'same_kind' is not satisfied.
+        a = np.array([1, 2, 3], dtype=int)
+        # Non-in-place addition is fine
+        assert_array_equal(assert_no_warnings(np.add, a, 1.1),
+                           [2.1, 3.1, 4.1])
+        assert_raises(TypeError, np.add, a, 1.1, out=a)
+
+        def add_inplace(a, b):
+            a += b
+
+        assert_raises(TypeError, add_inplace, a, 1.1)
+        # Make sure that explicitly overriding the exception is allowed:
+        assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe")
+        assert_array_equal(a, [2, 3, 4])
+
+    def test_ufunc_custom_out(self):
+        # Test ufunc with built in input types and custom output type
+
+        a = np.array([0, 1, 2], dtype='i8')
+        b = np.array([0, 1, 2], dtype='i8')
+        c = np.empty(3, dtype=rational)
+
+        # Output must be specified so numpy knows what
+        # ufunc signature to look for
+        result = test_add(a, b, c)
+        assert_equal(result, np.array([0, 2, 4], dtype=rational))
+
+        # no output type should raise TypeError
+        assert_raises(TypeError, test_add, a, b)
+
+    def test_operand_flags(self):
+        a = np.arange(16, dtype='l').reshape(4, 4)
+        b = np.arange(9, dtype='l').reshape(3, 3)
+        opflag_tests.inplace_add(a[:-1, :-1], b)
+        assert_equal(a, np.array([[0, 2, 4, 3], [7, 9, 11, 7],
+            [14, 16, 18, 11], [12, 13, 14, 15]], dtype='l'))
+
+        a = np.array(0)
+        opflag_tests.inplace_add(a, 3)
+        assert_equal(a, 3)
+        opflag_tests.inplace_add(a, [3, 4])
+        assert_equal(a, 10)
+
+    def test_struct_ufunc(self):
+        import numpy.core.struct_ufunc_test as struct_ufunc
+
+        a = np.array([(1, 2, 3)], dtype='u8,u8,u8')
+        b = np.array([(1, 2, 3)], dtype='u8,u8,u8')
+
+        result = struct_ufunc.add_triplet(a, b)
+        assert_equal(result, np.array([(2, 4, 6)], dtype='u8,u8,u8'))
+
+    def test_custom_ufunc(self):
+        a = np.array([rational(1, 2), rational(1, 3), rational(1, 4)],
+            dtype=rational)
+        b = np.array([rational(1, 2), rational(1, 3), rational(1, 4)],
+            dtype=rational)
+
+        result = test_add_rationals(a, b)
+        expected = np.array([rational(1), rational(2, 3), rational(1, 2)],
+            dtype=rational)
+        assert_equal(result, expected)
+
+    def test_custom_array_like(self):
+
+        class MyThing(object):
+            __array_priority__ = 1000
+
+            rmul_count = 0
+            getitem_count = 0
+
+            def __init__(self, shape):
+                self.shape = shape
+
+            def __len__(self):
+                return self.shape[0]
+
+            def __getitem__(self, i):
+                MyThing.getitem_count += 1
+                if not isinstance(i, tuple):
+                    i = (i,)
+                if len(i) > len(self.shape):
+                    raise IndexError("boo")
+
+                return MyThing(self.shape[len(i):])
+
+            def __rmul__(self, other):
+                MyThing.rmul_count += 1
+                return self
+
+        np.float64(5)*MyThing((3, 3))
+        assert_(MyThing.rmul_count == 1, MyThing.rmul_count)
+        assert_(MyThing.getitem_count <= 2, MyThing.getitem_count)
+
+    def test_inplace_fancy_indexing(self):
+
+        a = np.arange(10)
+        np.add.at(a, [2, 5, 2], 1)
+        assert_equal(a, [0, 1, 4, 3, 4, 6, 6, 7, 8, 9])
+
+        a = np.arange(10)
+        b = np.array([100, 100, 100])
+        np.add.at(a, [2, 5, 2], b)
+        assert_equal(a, [0, 1, 202, 3, 4, 105, 6, 7, 8, 9])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
+        np.add.at(a, (slice(None), [1, 2, 1]), b)
+        assert_equal(a, [[0, 201, 102], [3, 404, 205], [6, 607, 308]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), slice(None), [1, 2, 1]), b)
+        assert_equal(a,
+            [[[0, 401, 202],
+              [3, 404, 205],
+              [6, 407, 208]],
+
+             [[9, 410, 211],
+              [12, 413, 214],
+              [15, 416, 217]],
+
+             [[18, 419, 220],
+              [21, 422, 223],
+              [24, 425, 226]]])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
+        np.add.at(a, ([1, 2, 1], slice(None)), b)
+        assert_equal(a, [[0, 1, 2], [403, 404, 405], [206, 207, 208]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), [1, 2, 1], slice(None)), b)
+        assert_equal(a,
+            [[[0,  1,  2],
+              [203, 404, 605],
+              [106, 207, 308]],
+
+             [[9,  10, 11],
+              [212, 413, 614],
+              [115, 216, 317]],
+
+             [[18, 19, 20],
+              [221, 422, 623],
+              [124, 225, 326]]])
+
+        a = np.arange(9).reshape(3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (0, [1, 2, 1]), b)
+        assert_equal(a, [[0, 401, 202], [3, 4, 5], [6, 7, 8]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, ([1, 2, 1], 0, slice(None)), b)
+        assert_equal(a,
+            [[[0,  1,  2],
+              [3,  4,  5],
+              [6,  7,  8]],
+
+             [[209, 410, 611],
+              [12,  13, 14],
+              [15,  16, 17]],
+
+             [[118, 219, 320],
+              [21,  22, 23],
+              [24,  25, 26]]])
+
+        a = np.arange(27).reshape(3, 3, 3)
+        b = np.array([100, 200, 300])
+        np.add.at(a, (slice(None), slice(None), slice(None)), b)
+        assert_equal(a,
+            [[[100, 201, 302],
+              [103, 204, 305],
+              [106, 207, 308]],
+
+             [[109, 210, 311],
+              [112, 213, 314],
+              [115, 216, 317]],
+
+             [[118, 219, 320],
+              [121, 222, 323],
+              [124, 225, 326]]])
+
+        a = np.arange(10)
+        np.negative.at(a, [2, 5, 2])
+        assert_equal(a, [0, 1, 2, 3, 4, -5, 6, 7, 8, 9])
+
+        # Test 0-dim array
+        a = np.array(0)
+        np.add.at(a, (), 1)
+        assert_equal(a, 1)
+
+        assert_raises(IndexError, np.add.at, a, 0, 1)
+        assert_raises(IndexError, np.add.at, a, [], 1)
+
+        # Test mixed dtypes
+        a = np.arange(10)
+        np.power.at(a, [1, 2, 3, 2], 3.5)
+        assert_equal(a, np.array([0, 1, 4414, 46, 4, 5, 6, 7, 8, 9]))
+
+        # Test boolean indexing and boolean ufuncs
+        a = np.arange(10)
+        index = a % 2 == 0
+        np.equal.at(a, index, [0, 2, 4, 6, 8])
+        assert_equal(a, [1, 1, 1, 3, 1, 5, 1, 7, 1, 9])
+
+        # Test unary operator
+        a = np.arange(10, dtype='u4')
+        np.invert.at(a, [2, 5, 2])
+        assert_equal(a, [0, 1, 2, 3, 4, 5 ^ 0xffffffff, 6, 7, 8, 9])
+
+        # Test empty subspace
+        orig = np.arange(4)
+        a = orig[:, None][:, 0:0]
+        np.add.at(a, [0, 1], 3)
+        assert_array_equal(orig, np.arange(4))
+
+        # Test with swapped byte order
+        index = np.array([1, 2, 1], np.dtype('i').newbyteorder())
+        values = np.array([1, 2, 3, 4], np.dtype('f').newbyteorder())
+        np.add.at(values, index, 3)
+        assert_array_equal(values, [1, 8, 6, 4])
+
+        # Test exception thrown
+        values = np.array(['a', 1], dtype=np.object)
+        self.assertRaises(TypeError, np.add.at, values, [0, 1], 1)
+        assert_array_equal(values, np.array(['a', 1], dtype=np.object))
+
+        # Test multiple output ufuncs raise error, gh-5665
+        assert_raises(ValueError, np.modf.at, np.arange(10), [1])
+
+    def test_reduce_arguments(self):
+        f = np.add.reduce
+        d = np.ones((5,2), dtype=int)
+        o = np.ones((2,), dtype=d.dtype)
+        r = o * 5
+        assert_equal(f(d), r)
+        # a, axis=0, dtype=None, out=None, keepdims=False
+        assert_equal(f(d, axis=0), r)
+        assert_equal(f(d, 0), r)
+        assert_equal(f(d, 0, dtype=None), r)
+        assert_equal(f(d, 0, dtype='i'), r)
+        assert_equal(f(d, 0, 'i'), r)
+        assert_equal(f(d, 0, None), r)
+        assert_equal(f(d, 0, None, out=None), r)
+        assert_equal(f(d, 0, None, out=o), r)
+        assert_equal(f(d, 0, None, o), r)
+        assert_equal(f(d, 0, None, None), r)
+        assert_equal(f(d, 0, None, None, keepdims=False), r)
+        assert_equal(f(d, 0, None, None, True), r.reshape((1,) + r.shape))
+        # multiple keywords
+        assert_equal(f(d, axis=0, dtype=None, out=None, keepdims=False), r)
+        assert_equal(f(d, 0, dtype=None, out=None, keepdims=False), r)
+        assert_equal(f(d, 0, None, out=None, keepdims=False), r)
+
+        # too little
+        assert_raises(TypeError, f)
+        # too much
+        assert_raises(TypeError, f, d, 0, None, None, False, 1)
+        # invalid axis
+        assert_raises(TypeError, f, d, "invalid")
+        assert_raises(TypeError, f, d, axis="invalid")
+        assert_raises(TypeError, f, d, axis="invalid", dtype=None,
+                      keepdims=True)
+        # invalid dtype
+        assert_raises(TypeError, f, d, 0, "invalid")
+        assert_raises(TypeError, f, d, dtype="invalid")
+        assert_raises(TypeError, f, d, dtype="invalid", out=None)
+        # invalid out
+        assert_raises(TypeError, f, d, 0, None, "invalid")
+        assert_raises(TypeError, f, d, out="invalid")
+        assert_raises(TypeError, f, d, out="invalid", dtype=None)
+        # keepdims boolean, no invalid value
+        # assert_raises(TypeError, f, d, 0, None, None, "invalid")
+        # assert_raises(TypeError, f, d, keepdims="invalid", axis=0, dtype=None)
+        # invalid mix
+        assert_raises(TypeError, f, d, 0, keepdims="invalid", dtype="invalid",
+                     out=None)
+
+        # invalid keyord
+        assert_raises(TypeError, f, d, axis=0, dtype=None, invalid=0)
+        assert_raises(TypeError, f, d, invalid=0)
+        assert_raises(TypeError, f, d, 0, keepdims=True, invalid="invalid",
+                      out=None)
+        assert_raises(TypeError, f, d, axis=0, dtype=None, keepdims=True,
+                      out=None, invalid=0)
+        assert_raises(TypeError, f, d, axis=0, dtype=None,
+                      out=None, invalid=0)
+
+    def test_structured_equal(self):
+        # https://github.com/numpy/numpy/issues/4855
+
+        class MyA(np.ndarray):
+            def __numpy_ufunc__(self, ufunc, method, i, inputs, **kwargs):
+                return getattr(ufunc, method)(*(input.view(np.ndarray)
+                                              for input in inputs), **kwargs)
+        a = np.arange(12.).reshape(4,3)
+        ra = a.view(dtype=('f8,f8,f8')).squeeze()
+        mra = ra.view(MyA)
+
+        target = np.array([ True, False, False, False], dtype=bool)
+        assert_equal(np.all(target == (mra == ra[0])), True)
+
+    def test_NotImplemented_not_returned(self):
+        # See gh-5964 and gh-2091. Some of these functions are not operator
+        # related and were fixed for other reasons in the past.
+        binary_funcs = [
+            np.power, np.add, np.subtract, np.multiply, np.divide,
+            np.true_divide, np.floor_divide, np.bitwise_and, np.bitwise_or,
+            np.bitwise_xor, np.left_shift, np.right_shift, np.fmax,
+            np.fmin, np.fmod, np.hypot, np.logaddexp, np.logaddexp2,
+            np.logical_and, np.logical_or, np.logical_xor, np.maximum,
+            np.minimum, np.mod
+            ]
+
+        # These functions still return NotImplemented. Will be fixed in
+        # future.
+        # bad = [np.greater, np.greater_equal, np.less, np.less_equal, np.not_equal]
+
+        a = np.array('1')
+        b = 1
+        for f in binary_funcs:
+            assert_raises(TypeError, f, a, b)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
new file mode 100644
index 0000000000..da52e0dde3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
@@ -0,0 +1,2062 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import platform
+import warnings
+import itertools
+
+from numpy.testing.utils import _gen_alignment_data
+import numpy.core.umath as ncu
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_raises,
+    assert_array_equal, assert_almost_equal, assert_array_almost_equal,
+    dec, assert_allclose, assert_no_warnings
+)
+
+
+def on_powerpc():
+    """ True if we are running on a Power PC platform."""
+    return platform.processor() == 'powerpc' or \
+           platform.machine().startswith('ppc')
+
+
+class _FilterInvalids(object):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+
+class TestConstants(TestCase):
+    def test_pi(self):
+        assert_allclose(ncu.pi, 3.141592653589793, 1e-15)
+
+    def test_e(self):
+        assert_allclose(ncu.e, 2.718281828459045, 1e-15)
+
+    def test_euler_gamma(self):
+        assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15)
+
+
+class TestOut(TestCase):
+    def test_out_subok(self):
+        for subok in (True, False):
+            a = np.array(0.5)
+            o = np.empty(())
+
+            r = np.add(a, 2, o, subok=subok)
+            assert_(r is o)
+            r = np.add(a, 2, out=o, subok=subok)
+            assert_(r is o)
+            r = np.add(a, 2, out=(o,), subok=subok)
+            assert_(r is o)
+
+            d = np.array(5.7)
+            o1 = np.empty(())
+            o2 = np.empty((), dtype=np.int32)
+
+            r1, r2 = np.frexp(d, o1, None, subok=subok)
+            assert_(r1 is o1)
+            r1, r2 = np.frexp(d, None, o2, subok=subok)
+            assert_(r2 is o2)
+            r1, r2 = np.frexp(d, o1, o2, subok=subok)
+            assert_(r1 is o1)
+            assert_(r2 is o2)
+
+            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
+            assert_(r1 is o1)
+            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
+            assert_(r2 is o2)
+            r1, r2 = np.frexp(d, out=(o1, o2), subok=subok)
+            assert_(r1 is o1)
+            assert_(r2 is o2)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings('always', '', DeprecationWarning)
+                r1, r2 = np.frexp(d, out=o1, subok=subok)
+                assert_(r1 is o1)
+                assert_(w[0].category is DeprecationWarning)
+
+            assert_raises(ValueError, np.add, a, 2, o, o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, o, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, None, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(), subok=subok)
+            assert_raises(TypeError, np.add, a, 2, [], subok=subok)
+            assert_raises(TypeError, np.add, a, 2, out=[], subok=subok)
+            assert_raises(TypeError, np.add, a, 2, out=([],), subok=subok)
+            o.flags.writeable = False
+            assert_raises(ValueError, np.add, a, 2, o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=o, subok=subok)
+            assert_raises(ValueError, np.add, a, 2, out=(o,), subok=subok)
+
+    def test_out_wrap_subok(self):
+        class ArrayWrap(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls, arr):
+                return np.asarray(arr).view(cls).copy()
+
+            def __array_wrap__(self, arr, context):
+                return arr.view(type(self))
+
+        for subok in (True, False):
+            a = ArrayWrap([0.5])
+
+            r = np.add(a, 2, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, None, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, out=None, subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            r = np.add(a, 2, out=(None,), subok=subok)
+            if subok:
+                assert_(isinstance(r, ArrayWrap))
+            else:
+                assert_(type(r) == np.ndarray)
+
+            d = ArrayWrap([5.7])
+            o1 = np.empty((1,))
+            o2 = np.empty((1,), dtype=np.int32)
+
+            r1, r2 = np.frexp(d, o1, subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, o1, None, subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, None, o2, subok=subok)
+            if subok:
+                assert_(isinstance(r1, ArrayWrap))
+            else:
+                assert_(type(r1) == np.ndarray)
+
+            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
+            if subok:
+                assert_(isinstance(r2, ArrayWrap))
+            else:
+                assert_(type(r2) == np.ndarray)
+
+            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
+            if subok:
+                assert_(isinstance(r1, ArrayWrap))
+            else:
+                assert_(type(r1) == np.ndarray)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings('always', '', DeprecationWarning)
+                r1, r2 = np.frexp(d, out=o1, subok=subok)
+                if subok:
+                    assert_(isinstance(r2, ArrayWrap))
+                else:
+                    assert_(type(r2) == np.ndarray)
+                assert_(w[0].category is DeprecationWarning)
+
+
+class TestDivision(TestCase):
+    def test_division_int(self):
+        # int division should follow Python
+        x = np.array([5, 10, 90, 100, -5, -10, -90, -100, -120])
+        if 5 / 10 == 0.5:
+            assert_equal(x / 100, [0.05, 0.1, 0.9, 1,
+                                   -0.05, -0.1, -0.9, -1, -1.2])
+        else:
+            assert_equal(x / 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
+        assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
+        assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80])
+
+    def test_division_complex(self):
+        # check that implementation is correct
+        msg = "Complex division implementation check"
+        x = np.array([1. + 1.*1j, 1. + .5*1j, 1. + 2.*1j], dtype=np.complex128)
+        assert_almost_equal(x**2/x, x, err_msg=msg)
+        # check overflow, underflow
+        msg = "Complex division overflow/underflow check"
+        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
+        y = x**2/x
+        assert_almost_equal(y/x, [1, 1], err_msg=msg)
+
+    def test_zero_division_complex(self):
+        with np.errstate(invalid="ignore", divide="ignore"):
+            x = np.array([0.0], dtype=np.complex128)
+            y = 1.0/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.inf, np.nan)/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.nan, np.inf)/x
+            assert_(np.isinf(y)[0])
+            y = complex(np.inf, np.inf)/x
+            assert_(np.isinf(y)[0])
+            y = 0.0/x
+            assert_(np.isnan(y)[0])
+
+    def test_floor_division_complex(self):
+        # check that implementation is correct
+        msg = "Complex floor division implementation check"
+        x = np.array([.9 + 1j, -.1 + 1j, .9 + .5*1j, .9 + 2.*1j], dtype=np.complex128)
+        y = np.array([0., -1., 0., 0.], dtype=np.complex128)
+        assert_equal(np.floor_divide(x**2, x), y, err_msg=msg)
+        # check overflow, underflow
+        msg = "Complex floor division overflow/underflow check"
+        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
+        y = np.floor_divide(x**2, x)
+        assert_equal(y, [1.e+110, 0], err_msg=msg)
+
+
+class TestRemainder(TestCase):
+
+    def test_remainder_basic(self):
+        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                if sg1 == -1 and dt1 in np.typecodes['UnsignedInteger']:
+                    continue
+                if sg2 == -1 and dt2 in np.typecodes['UnsignedInteger']:
+                    continue
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*71, dtype=dt1)
+                b = np.array(sg2*19, dtype=dt2)
+                div = np.floor_divide(a, b)
+                rem = np.remainder(a, b)
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_remainder_exact(self):
+        # test that float results are exact for small integers. This also
+        # holds for the same integers scaled by powers of two.
+        nlst = list(range(-127, 0))
+        plst = list(range(1, 128))
+        dividend = nlst + [0] + plst
+        divisor = nlst + plst
+        arg = list(itertools.product(dividend, divisor))
+        tgt = list(divmod(*t) for t in arg)
+
+        a, b = np.array(arg, dtype=int).T
+        # convert exact integer results from Python to float so that
+        # signed zero can be used, it is checked.
+        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
+        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
+        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
+
+        for dt in np.typecodes['Float']:
+            msg = 'dtype: %s' % (dt,)
+            fa = a.astype(dt)
+            fb = b.astype(dt)
+            div = np.floor_divide(fa, fb)
+            rem = np.remainder(fa, fb)
+            assert_equal(div, tgtdiv, err_msg=msg)
+            assert_equal(rem, tgtrem, err_msg=msg)
+
+    def test_float_remainder_roundoff(self):
+        # gh-6127
+        dt = np.typecodes['Float']
+        for dt1, dt2 in itertools.product(dt, dt):
+            for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
+                fmt = 'dt1: %s, dt2: %s, sg1: %s, sg2: %s'
+                msg = fmt % (dt1, dt2, sg1, sg2)
+                a = np.array(sg1*78*6e-8, dtype=dt1)
+                b = np.array(sg2*6e-8, dtype=dt2)
+                div = np.floor_divide(a, b)
+                rem = np.remainder(a, b)
+                # Equal assertion should hold when fmod is used
+                assert_equal(div*b + rem, a, err_msg=msg)
+                if sg2 == -1:
+                    assert_(b < rem <= 0, msg)
+                else:
+                    assert_(b > rem >= 0, msg)
+
+    def test_float_remainder_corner_cases(self):
+        # Check remainder magnitude.
+        for dt in np.typecodes['Float']:
+            b = np.array(1.0, dtype=dt)
+            a = np.nextafter(np.array(0.0, dtype=dt), -b)
+            rem = np.remainder(a, b)
+            assert_(rem <= b, 'dt: %s' % dt)
+            rem = np.remainder(-a, -b)
+            assert_(rem >= -b, 'dt: %s' % dt)
+
+        # Check nans, inf
+        with warnings.catch_warnings():
+            warnings.simplefilter('always')
+            warnings.simplefilter('ignore', RuntimeWarning)
+            for dt in np.typecodes['Float']:
+                fone = np.array(1.0, dtype=dt)
+                fzer = np.array(0.0, dtype=dt)
+                finf = np.array(np.inf, dtype=dt)
+                fnan = np.array(np.nan, dtype=dt)
+                rem = np.remainder(fone, fzer)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+                # MSVC 2008 returns NaN here, so disable the check.
+                #rem = np.remainder(fone, finf)
+                #assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem))
+                rem = np.remainder(fone, fnan)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+                rem = np.remainder(finf, fone)
+                assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem))
+
+
+class TestCbrt(TestCase):
+    def test_cbrt_scalar(self):
+        assert_almost_equal((np.cbrt(np.float32(-2.5)**3)), -2.5)
+
+    def test_cbrt(self):
+        x = np.array([1., 2., -3., np.inf, -np.inf])
+        assert_almost_equal(np.cbrt(x**3), x)
+
+        assert_(np.isnan(np.cbrt(np.nan)))
+        assert_equal(np.cbrt(np.inf), np.inf)
+        assert_equal(np.cbrt(-np.inf), -np.inf)
+
+
+class TestPower(TestCase):
+    def test_power_float(self):
+        x = np.array([1., 2., 3.])
+        assert_equal(x**0, [1., 1., 1.])
+        assert_equal(x**1, x)
+        assert_equal(x**2, [1., 4., 9.])
+        y = x.copy()
+        y **= 2
+        assert_equal(y, [1., 4., 9.])
+        assert_almost_equal(x**(-1), [1., 0.5, 1./3])
+        assert_almost_equal(x**(0.5), [1., ncu.sqrt(2), ncu.sqrt(3)])
+
+        for out, inp, msg in _gen_alignment_data(dtype=np.float32,
+                                                 type='unary',
+                                                 max_size=11):
+            exp = [ncu.sqrt(i) for i in inp]
+            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
+            np.sqrt(inp, out=out)
+            assert_equal(out, exp, err_msg=msg)
+
+        for out, inp, msg in _gen_alignment_data(dtype=np.float64,
+                                                 type='unary',
+                                                 max_size=7):
+            exp = [ncu.sqrt(i) for i in inp]
+            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
+            np.sqrt(inp, out=out)
+            assert_equal(out, exp, err_msg=msg)
+
+    def test_power_complex(self):
+        x = np.array([1+2j, 2+3j, 3+4j])
+        assert_equal(x**0, [1., 1., 1.])
+        assert_equal(x**1, x)
+        assert_almost_equal(x**2, [-3+4j, -5+12j, -7+24j])
+        assert_almost_equal(x**3, [(1+2j)**3, (2+3j)**3, (3+4j)**3])
+        assert_almost_equal(x**4, [(1+2j)**4, (2+3j)**4, (3+4j)**4])
+        assert_almost_equal(x**(-1), [1/(1+2j), 1/(2+3j), 1/(3+4j)])
+        assert_almost_equal(x**(-2), [1/(1+2j)**2, 1/(2+3j)**2, 1/(3+4j)**2])
+        assert_almost_equal(x**(-3), [(-11+2j)/125, (-46-9j)/2197,
+                                      (-117-44j)/15625])
+        assert_almost_equal(x**(0.5), [ncu.sqrt(1+2j), ncu.sqrt(2+3j),
+                                       ncu.sqrt(3+4j)])
+        norm = 1./((x**14)[0])
+        assert_almost_equal(x**14 * norm,
+                [i * norm for i in [-76443+16124j, 23161315+58317492j,
+                                    5583548873 + 2465133864j]])
+
+        # Ticket #836
+        def assert_complex_equal(x, y):
+            assert_array_equal(x.real, y.real)
+            assert_array_equal(x.imag, y.imag)
+
+        for z in [complex(0, np.inf), complex(1, np.inf)]:
+            z = np.array([z], dtype=np.complex_)
+            with np.errstate(invalid="ignore"):
+                assert_complex_equal(z**1, z)
+                assert_complex_equal(z**2, z*z)
+                assert_complex_equal(z**3, z*z*z)
+
+    def test_power_zero(self):
+        # ticket #1271
+        zero = np.array([0j])
+        one = np.array([1+0j])
+        cnan = np.array([complex(np.nan, np.nan)])
+        # FIXME cinf not tested.
+        #cinf = np.array([complex(np.inf, 0)])
+
+        def assert_complex_equal(x, y):
+            x, y = np.asarray(x), np.asarray(y)
+            assert_array_equal(x.real, y.real)
+            assert_array_equal(x.imag, y.imag)
+
+        # positive powers
+        for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
+            assert_complex_equal(np.power(zero, p), zero)
+
+        # zero power
+        assert_complex_equal(np.power(zero, 0), one)
+        with np.errstate(invalid="ignore"):
+            assert_complex_equal(np.power(zero, 0+1j), cnan)
+
+            # negative power
+            for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
+                assert_complex_equal(np.power(zero, -p), cnan)
+            assert_complex_equal(np.power(zero, -1+0.2j), cnan)
+
+    def test_fast_power(self):
+        x = np.array([1, 2, 3], np.int16)
+        assert_((x**2.00001).dtype is (x**2.0).dtype)
+
+        # Check that the fast path ignores 1-element not 0-d arrays
+        res = x ** np.array([[[2]]])
+        assert_equal(res.shape, (1, 1, 3))
+
+
+class TestLog2(TestCase):
+    def test_log2_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)
+            assert_almost_equal(np.log2(xf), yf)
+
+    def test_log2_ints(self):
+        # a good log2 implementation should provide this,
+        # might fail on OS with bad libm
+        for i in range(1, 65):
+            v = np.log2(2.**i)
+            assert_equal(v, float(i), err_msg='at exponent %d' % i)
+
+    def test_log2_special(self):
+        assert_equal(np.log2(1.), 0.)
+        assert_equal(np.log2(np.inf), np.inf)
+        assert_(np.isnan(np.log2(np.nan)))
+
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_(np.isnan(np.log2(-1.)))
+            assert_(np.isnan(np.log2(-np.inf)))
+            assert_equal(np.log2(0.), -np.inf)
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+            assert_(w[2].category is RuntimeWarning)
+
+
+class TestExp2(TestCase):
+    def test_exp2_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)
+            assert_almost_equal(np.exp2(yf), xf)
+
+
+class TestLogAddExp2(_FilterInvalids):
+    # Need test for intermediate precisions
+    def test_logaddexp2_values(self):
+        x = [1, 2, 3, 4, 5]
+        y = [5, 4, 3, 2, 1]
+        z = [6, 6, 6, 6, 6]
+        for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]):
+            xf = np.log2(np.array(x, dtype=dt))
+            yf = np.log2(np.array(y, dtype=dt))
+            zf = np.log2(np.array(z, dtype=dt))
+            assert_almost_equal(np.logaddexp2(xf, yf), zf, decimal=dec_)
+
+    def test_logaddexp2_range(self):
+        x = [1000000, -1000000, 1000200, -1000200]
+        y = [1000200, -1000200, 1000000, -1000000]
+        z = [1000200, -1000000, 1000200, -1000000]
+        for dt in ['f', 'd', 'g']:
+            logxf = np.array(x, dtype=dt)
+            logyf = np.array(y, dtype=dt)
+            logzf = np.array(z, dtype=dt)
+            assert_almost_equal(np.logaddexp2(logxf, logyf), logzf)
+
+    def test_inf(self):
+        inf = np.inf
+        x = [inf, -inf,  inf, -inf, inf, 1,  -inf,  1]
+        y = [inf,  inf, -inf, -inf, 1,   inf, 1,   -inf]
+        z = [inf,  inf,  inf, -inf, inf, inf, 1,    1]
+        with np.errstate(invalid='raise'):
+            for dt in ['f', 'd', 'g']:
+                logxf = np.array(x, dtype=dt)
+                logyf = np.array(y, dtype=dt)
+                logzf = np.array(z, dtype=dt)
+                assert_equal(np.logaddexp2(logxf, logyf), logzf)
+
+    def test_nan(self):
+        assert_(np.isnan(np.logaddexp2(np.nan, np.inf)))
+        assert_(np.isnan(np.logaddexp2(np.inf, np.nan)))
+        assert_(np.isnan(np.logaddexp2(np.nan, 0)))
+        assert_(np.isnan(np.logaddexp2(0, np.nan)))
+        assert_(np.isnan(np.logaddexp2(np.nan, np.nan)))
+
+
+class TestLog(TestCase):
+    def test_log_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            log2_ = 0.69314718055994530943
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)*log2_
+            assert_almost_equal(np.log(xf), yf)
+
+
+class TestExp(TestCase):
+    def test_exp_values(self):
+        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
+        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+        for dt in ['f', 'd', 'g']:
+            log2_ = 0.69314718055994530943
+            xf = np.array(x, dtype=dt)
+            yf = np.array(y, dtype=dt)*log2_
+            assert_almost_equal(np.exp(yf), xf)
+
+
+class TestLogAddExp(_FilterInvalids):
+    def test_logaddexp_values(self):
+        x = [1, 2, 3, 4, 5]
+        y = [5, 4, 3, 2, 1]
+        z = [6, 6, 6, 6, 6]
+        for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]):
+            xf = np.log(np.array(x, dtype=dt))
+            yf = np.log(np.array(y, dtype=dt))
+            zf = np.log(np.array(z, dtype=dt))
+            assert_almost_equal(np.logaddexp(xf, yf), zf, decimal=dec_)
+
+    def test_logaddexp_range(self):
+        x = [1000000, -1000000, 1000200, -1000200]
+        y = [1000200, -1000200, 1000000, -1000000]
+        z = [1000200, -1000000, 1000200, -1000000]
+        for dt in ['f', 'd', 'g']:
+            logxf = np.array(x, dtype=dt)
+            logyf = np.array(y, dtype=dt)
+            logzf = np.array(z, dtype=dt)
+            assert_almost_equal(np.logaddexp(logxf, logyf), logzf)
+
+    def test_inf(self):
+        inf = np.inf
+        x = [inf, -inf,  inf, -inf, inf, 1,  -inf,  1]
+        y = [inf,  inf, -inf, -inf, 1,   inf, 1,   -inf]
+        z = [inf,  inf,  inf, -inf, inf, inf, 1,    1]
+        with np.errstate(invalid='raise'):
+            for dt in ['f', 'd', 'g']:
+                logxf = np.array(x, dtype=dt)
+                logyf = np.array(y, dtype=dt)
+                logzf = np.array(z, dtype=dt)
+                assert_equal(np.logaddexp(logxf, logyf), logzf)
+
+    def test_nan(self):
+        assert_(np.isnan(np.logaddexp(np.nan, np.inf)))
+        assert_(np.isnan(np.logaddexp(np.inf, np.nan)))
+        assert_(np.isnan(np.logaddexp(np.nan, 0)))
+        assert_(np.isnan(np.logaddexp(0, np.nan)))
+        assert_(np.isnan(np.logaddexp(np.nan, np.nan)))
+
+
+class TestLog1p(TestCase):
+    def test_log1p(self):
+        assert_almost_equal(ncu.log1p(0.2), ncu.log(1.2))
+        assert_almost_equal(ncu.log1p(1e-6), ncu.log(1+1e-6))
+
+    def test_special(self):
+        with np.errstate(invalid="ignore", divide="ignore"):
+            assert_equal(ncu.log1p(np.nan), np.nan)
+            assert_equal(ncu.log1p(np.inf), np.inf)
+            assert_equal(ncu.log1p(-1.), -np.inf)
+            assert_equal(ncu.log1p(-2.), np.nan)
+            assert_equal(ncu.log1p(-np.inf), np.nan)
+
+
+class TestExpm1(TestCase):
+    def test_expm1(self):
+        assert_almost_equal(ncu.expm1(0.2), ncu.exp(0.2)-1)
+        assert_almost_equal(ncu.expm1(1e-6), ncu.exp(1e-6)-1)
+
+    def test_special(self):
+        assert_equal(ncu.expm1(np.inf), np.inf)
+        assert_equal(ncu.expm1(0.), 0.)
+        assert_equal(ncu.expm1(-0.), -0.)
+        assert_equal(ncu.expm1(np.inf), np.inf)
+        assert_equal(ncu.expm1(-np.inf), -1.)
+
+
+class TestHypot(TestCase, object):
+    def test_simple(self):
+        assert_almost_equal(ncu.hypot(1, 1), ncu.sqrt(2))
+        assert_almost_equal(ncu.hypot(0, 0), 0)
+
+
+def assert_hypot_isnan(x, y):
+    with np.errstate(invalid='ignore'):
+        assert_(np.isnan(ncu.hypot(x, y)),
+                "hypot(%s, %s) is %s, not nan" % (x, y, ncu.hypot(x, y)))
+
+
+def assert_hypot_isinf(x, y):
+    with np.errstate(invalid='ignore'):
+        assert_(np.isinf(ncu.hypot(x, y)),
+                "hypot(%s, %s) is %s, not inf" % (x, y, ncu.hypot(x, y)))
+
+
+class TestHypotSpecialValues(TestCase):
+    def test_nan_outputs(self):
+        assert_hypot_isnan(np.nan, np.nan)
+        assert_hypot_isnan(np.nan, 1)
+
+    def test_nan_outputs2(self):
+        assert_hypot_isinf(np.nan, np.inf)
+        assert_hypot_isinf(np.inf, np.nan)
+        assert_hypot_isinf(np.inf, 0)
+        assert_hypot_isinf(0, np.inf)
+        assert_hypot_isinf(np.inf, np.inf)
+        assert_hypot_isinf(np.inf, 23.0)
+
+    def test_no_fpe(self):
+        assert_no_warnings(ncu.hypot, np.inf, 0)
+
+
+def assert_arctan2_isnan(x, y):
+    assert_(np.isnan(ncu.arctan2(x, y)), "arctan(%s, %s) is %s, not nan" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_ispinf(x, y):
+    assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) > 0), "arctan(%s, %s) is %s, not +inf" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_isninf(x, y):
+    assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) < 0), "arctan(%s, %s) is %s, not -inf" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_ispzero(x, y):
+    assert_((ncu.arctan2(x, y) == 0 and not np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not +0" % (x, y, ncu.arctan2(x, y)))
+
+
+def assert_arctan2_isnzero(x, y):
+    assert_((ncu.arctan2(x, y) == 0 and np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not -0" % (x, y, ncu.arctan2(x, y)))
+
+
+class TestArctan2SpecialValues(TestCase):
+    def test_one_one(self):
+        # atan2(1, 1) returns pi/4.
+        assert_almost_equal(ncu.arctan2(1, 1), 0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(-1, 1), -0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(1, -1), 0.75 * np.pi)
+
+    def test_zero_nzero(self):
+        # atan2(+-0, -0) returns +-pi.
+        assert_almost_equal(ncu.arctan2(np.PZERO, np.NZERO), np.pi)
+        assert_almost_equal(ncu.arctan2(np.NZERO, np.NZERO), -np.pi)
+
+    def test_zero_pzero(self):
+        # atan2(+-0, +0) returns +-0.
+        assert_arctan2_ispzero(np.PZERO, np.PZERO)
+        assert_arctan2_isnzero(np.NZERO, np.PZERO)
+
+    def test_zero_negative(self):
+        # atan2(+-0, x) returns +-pi for x < 0.
+        assert_almost_equal(ncu.arctan2(np.PZERO, -1), np.pi)
+        assert_almost_equal(ncu.arctan2(np.NZERO, -1), -np.pi)
+
+    def test_zero_positive(self):
+        # atan2(+-0, x) returns +-0 for x > 0.
+        assert_arctan2_ispzero(np.PZERO, 1)
+        assert_arctan2_isnzero(np.NZERO, 1)
+
+    def test_positive_zero(self):
+        # atan2(y, +-0) returns +pi/2 for y > 0.
+        assert_almost_equal(ncu.arctan2(1, np.PZERO), 0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(1, np.NZERO), 0.5 * np.pi)
+
+    def test_negative_zero(self):
+        # atan2(y, +-0) returns -pi/2 for y < 0.
+        assert_almost_equal(ncu.arctan2(-1, np.PZERO), -0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(-1, np.NZERO), -0.5 * np.pi)
+
+    def test_any_ninf(self):
+        # atan2(+-y, -infinity) returns +-pi for finite y > 0.
+        assert_almost_equal(ncu.arctan2(1, np.NINF),  np.pi)
+        assert_almost_equal(ncu.arctan2(-1, np.NINF), -np.pi)
+
+    def test_any_pinf(self):
+        # atan2(+-y, +infinity) returns +-0 for finite y > 0.
+        assert_arctan2_ispzero(1, np.inf)
+        assert_arctan2_isnzero(-1, np.inf)
+
+    def test_inf_any(self):
+        # atan2(+-infinity, x) returns +-pi/2 for finite x.
+        assert_almost_equal(ncu.arctan2( np.inf, 1),  0.5 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, 1), -0.5 * np.pi)
+
+    def test_inf_ninf(self):
+        # atan2(+-infinity, -infinity) returns +-3*pi/4.
+        assert_almost_equal(ncu.arctan2( np.inf, -np.inf),  0.75 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, -np.inf), -0.75 * np.pi)
+
+    def test_inf_pinf(self):
+        # atan2(+-infinity, +infinity) returns +-pi/4.
+        assert_almost_equal(ncu.arctan2( np.inf, np.inf),  0.25 * np.pi)
+        assert_almost_equal(ncu.arctan2(-np.inf, np.inf), -0.25 * np.pi)
+
+    def test_nan_any(self):
+        # atan2(nan, x) returns nan for any x, including inf
+        assert_arctan2_isnan(np.nan, np.inf)
+        assert_arctan2_isnan(np.inf, np.nan)
+        assert_arctan2_isnan(np.nan, np.nan)
+
+
+class TestLdexp(TestCase):
+    def _check_ldexp(self, tp):
+        assert_almost_equal(ncu.ldexp(np.array(2., np.float32),
+                                      np.array(3, tp)), 16.)
+        assert_almost_equal(ncu.ldexp(np.array(2., np.float64),
+                                      np.array(3, tp)), 16.)
+        assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble),
+                                      np.array(3, tp)), 16.)
+
+    def test_ldexp(self):
+        # The default Python int type should work
+        assert_almost_equal(ncu.ldexp(2., 3),  16.)
+        # The following int types should all be accepted
+        self._check_ldexp(np.int8)
+        self._check_ldexp(np.int16)
+        self._check_ldexp(np.int32)
+        self._check_ldexp('i')
+        self._check_ldexp('l')
+
+    def test_ldexp_overflow(self):
+        # silence warning emitted on overflow
+        with np.errstate(over="ignore"):
+            imax = np.iinfo(np.dtype('l')).max
+            imin = np.iinfo(np.dtype('l')).min
+            assert_equal(ncu.ldexp(2., imax), np.inf)
+            assert_equal(ncu.ldexp(2., imin), 0)
+
+
+class TestMaximum(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.maximum.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), np.nan)
+            assert_equal(func(tmp2), np.nan)
+
+    def test_reduce_complex(self):
+        assert_equal(np.maximum.reduce([1, 2j]), 1)
+        assert_equal(np.maximum.reduce([1+3j, 2j]), 1+3j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([nan, nan, nan])
+        assert_equal(np.maximum(arg1, arg2), out)
+
+    def test_object_nans(self):
+        # Multiple checks to give this a chance to
+        # fail if cmp is used instead of rich compare.
+        # Failure cannot be guaranteed.
+        for i in range(1):
+            x = np.array(float('nan'), np.object)
+            y = 1.0
+            z = np.array(float('nan'), np.object)
+            assert_(np.maximum(x, y) == 1.0)
+            assert_(np.maximum(z, y) == 1.0)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([nan, nan, nan], dtype=np.complex)
+            assert_equal(np.maximum(arg1, arg2), out)
+
+    def test_object_array(self):
+        arg1 = np.arange(5, dtype=np.object)
+        arg2 = arg1 + 1
+        assert_equal(np.maximum(arg1, arg2), arg2)
+
+
+class TestMinimum(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.minimum.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), np.nan)
+            assert_equal(func(tmp2), np.nan)
+
+    def test_reduce_complex(self):
+        assert_equal(np.minimum.reduce([1, 2j]), 2j)
+        assert_equal(np.minimum.reduce([1+3j, 2j]), 2j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([nan, nan, nan])
+        assert_equal(np.minimum(arg1, arg2), out)
+
+    def test_object_nans(self):
+        # Multiple checks to give this a chance to
+        # fail if cmp is used instead of rich compare.
+        # Failure cannot be guaranteed.
+        for i in range(1):
+            x = np.array(float('nan'), np.object)
+            y = 1.0
+            z = np.array(float('nan'), np.object)
+            assert_(np.minimum(x, y) == 1.0)
+            assert_(np.minimum(z, y) == 1.0)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([nan, nan, nan], dtype=np.complex)
+            assert_equal(np.minimum(arg1, arg2), out)
+
+    def test_object_array(self):
+        arg1 = np.arange(5, dtype=np.object)
+        arg2 = arg1 + 1
+        assert_equal(np.minimum(arg1, arg2), arg1)
+
+
+class TestFmax(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.fmax.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 10)
+            assert_equal(func(tmp2), 10)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), 9)
+            assert_equal(func(tmp2), 9)
+
+    def test_reduce_complex(self):
+        assert_equal(np.fmax.reduce([1, 2j]), 1)
+        assert_equal(np.fmax.reduce([1+3j, 2j]), 1+3j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([0,   0,   nan])
+        assert_equal(np.fmax(arg1, arg2), out)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([0,    0, nan], dtype=np.complex)
+            assert_equal(np.fmax(arg1, arg2), out)
+
+
+class TestFmin(_FilterInvalids):
+    def test_reduce(self):
+        dflt = np.typecodes['AllFloat']
+        dint = np.typecodes['AllInteger']
+        seq1 = np.arange(11)
+        seq2 = seq1[::-1]
+        func = np.fmin.reduce
+        for dt in dint:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+        for dt in dflt:
+            tmp1 = seq1.astype(dt)
+            tmp2 = seq2.astype(dt)
+            assert_equal(func(tmp1), 0)
+            assert_equal(func(tmp2), 0)
+            tmp1[::2] = np.nan
+            tmp2[::2] = np.nan
+            assert_equal(func(tmp1), 1)
+            assert_equal(func(tmp2), 1)
+
+    def test_reduce_complex(self):
+        assert_equal(np.fmin.reduce([1, 2j]), 2j)
+        assert_equal(np.fmin.reduce([1+3j, 2j]), 2j)
+
+    def test_float_nans(self):
+        nan = np.nan
+        arg1 = np.array([0,   nan, nan])
+        arg2 = np.array([nan, 0,   nan])
+        out = np.array([0,   0,   nan])
+        assert_equal(np.fmin(arg1, arg2), out)
+
+    def test_complex_nans(self):
+        nan = np.nan
+        for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]:
+            arg1 = np.array([0, cnan, cnan], dtype=np.complex)
+            arg2 = np.array([cnan, 0, cnan], dtype=np.complex)
+            out = np.array([0,    0, nan], dtype=np.complex)
+            assert_equal(np.fmin(arg1, arg2), out)
+
+
+class TestBool(TestCase):
+    def test_truth_table_logical(self):
+        # 2, 3 and 4 serves as true values
+        input1 = [0, 0, 3, 2]
+        input2 = [0, 4, 0, 2]
+
+        typecodes = (np.typecodes['AllFloat']
+                     + np.typecodes['AllInteger']
+                     + '?')     # boolean
+        for dtype in map(np.dtype, typecodes):
+            arg1 = np.asarray(input1, dtype=dtype)
+            arg2 = np.asarray(input2, dtype=dtype)
+
+            # OR
+            out = [False, True, True, True]
+            for func in (np.logical_or, np.maximum):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+            # AND
+            out = [False, False, False, True]
+            for func in (np.logical_and, np.minimum):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+            # XOR
+            out = [False, True, True, False]
+            for func in (np.logical_xor, np.not_equal):
+                assert_equal(func(arg1, arg2).astype(bool), out)
+
+    def test_truth_table_bitwise(self):
+        arg1 = [False, False, True, True]
+        arg2 = [False, True, False, True]
+
+        out = [False, True, True, True]
+        assert_equal(np.bitwise_or(arg1, arg2), out)
+
+        out = [False, False, False, True]
+        assert_equal(np.bitwise_and(arg1, arg2), out)
+
+        out = [False, True, True, False]
+        assert_equal(np.bitwise_xor(arg1, arg2), out)
+
+
+class TestInt(TestCase):
+    def test_logical_not(self):
+        x = np.ones(10, dtype=np.int16)
+        o = np.ones(10 * 2, dtype=np.bool)
+        tgt = o.copy()
+        tgt[::2] = False
+        os = o[::2]
+        assert_array_equal(np.logical_not(x, out=os), False)
+        assert_array_equal(o, tgt)
+
+
+class TestFloatingPoint(TestCase):
+    def test_floating_point(self):
+        assert_equal(ncu.FLOATING_POINT_SUPPORT, 1)
+
+
+class TestDegrees(TestCase):
+    def test_degrees(self):
+        assert_almost_equal(ncu.degrees(np.pi), 180.0)
+        assert_almost_equal(ncu.degrees(-0.5*np.pi), -90.0)
+
+
+class TestRadians(TestCase):
+    def test_radians(self):
+        assert_almost_equal(ncu.radians(180.0), np.pi)
+        assert_almost_equal(ncu.radians(-90.0), -0.5*np.pi)
+
+
+class TestSign(TestCase):
+    def test_sign(self):
+        a = np.array([np.inf, -np.inf, np.nan, 0.0, 3.0, -3.0])
+        out = np.zeros(a.shape)
+        tgt = np.array([1., -1., np.nan, 0.0, 1.0, -1.0])
+
+        with np.errstate(invalid='ignore'):
+            res = ncu.sign(a)
+            assert_equal(res, tgt)
+            res = ncu.sign(a, out)
+            assert_equal(res, tgt)
+            assert_equal(out, tgt)
+
+    def test_sign_dtype_object(self):
+        # In reference to github issue #6229
+
+        foo = np.array([-.1, 0, .1])
+        a = np.sign(foo.astype(np.object))
+        b = np.sign(foo)
+
+        assert_array_equal(a, b)
+
+    def test_sign_dtype_nan_object(self):
+        # In reference to github issue #6229
+        def test_nan():
+            foo = np.array([np.nan])
+            a = np.sign(foo.astype(np.object))
+
+        assert_raises(TypeError, test_nan)
+
+class TestMinMax(TestCase):
+    def test_minmax_blocked(self):
+        # simd tests on max/min, test all alignments, slow but important
+        # for 2 * vz + 2 * (vs - 1) + 1 (unrolled once)
+        for dt, sz in [(np.float32, 15), (np.float64, 7)]:
+            for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary',
+                                                     max_size=sz):
+                for i in range(inp.size):
+                    inp[:] = np.arange(inp.size, dtype=dt)
+                    inp[i] = np.nan
+                    emsg = lambda: '%r\n%s' % (inp, msg)
+                    assert_(np.isnan(inp.max()), msg=emsg)
+                    assert_(np.isnan(inp.min()), msg=emsg)
+
+                    inp[i] = 1e10
+                    assert_equal(inp.max(), 1e10, err_msg=msg)
+                    inp[i] = -1e10
+                    assert_equal(inp.min(), -1e10, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_equal(d.max(), d[0])
+        assert_equal(d.min(), d[0])
+
+
+class TestAbsoluteNegative(TestCase):
+    def test_abs_neg_blocked(self):
+        # simd tests on abs, test all alignments for vz + 2 * (vs - 1) + 1
+        for dt, sz in [(np.float32, 11), (np.float64, 5)]:
+            for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary',
+                                                     max_size=sz):
+                tgt = [ncu.absolute(i) for i in inp]
+                np.absolute(inp, out=out)
+                assert_equal(out, tgt, err_msg=msg)
+                self.assertTrue((out >= 0).all())
+
+                tgt = [-1*(i) for i in inp]
+                np.negative(inp, out=out)
+                assert_equal(out, tgt, err_msg=msg)
+
+                # will throw invalid flag depending on compiler optimizations
+                with np.errstate(invalid='ignore'):
+                    for v in [np.nan, -np.inf, np.inf]:
+                        for i in range(inp.size):
+                            d = np.arange(inp.size, dtype=dt)
+                            inp[:] = -d
+                            inp[i] = v
+                            d[i] = -v if v == -np.inf else v
+                            assert_array_equal(np.abs(inp), d, err_msg=msg)
+                            np.abs(inp, out=out)
+                            assert_array_equal(out, d, err_msg=msg)
+
+                            assert_array_equal(-inp, -1*inp, err_msg=msg)
+                            np.negative(inp, out=out)
+                            assert_array_equal(out, -1*inp, err_msg=msg)
+
+    def test_lower_align(self):
+        # check data that is not aligned to element size
+        # i.e doubles are aligned to 4 bytes on i386
+        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+        assert_equal(np.abs(d), d)
+        assert_equal(np.negative(d), -d)
+        np.negative(d, out=d)
+        np.negative(np.ones_like(d), out=d)
+        np.abs(d, out=d)
+        np.abs(np.ones_like(d), out=d)
+
+
+class TestSpecialMethods(TestCase):
+    def test_wrap(self):
+
+        class with_wrap(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                r = with_wrap()
+                r.arr = arr
+                r.context = context
+                return r
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x.arr, np.zeros(1))
+        func, args, i = x.context
+        self.assertTrue(func is ncu.minimum)
+        self.assertEqual(len(args), 2)
+        assert_equal(args[0], a)
+        assert_equal(args[1], a)
+        self.assertEqual(i, 0)
+
+    def test_wrap_with_iterable(self):
+        # test fix for bug #1026:
+
+        class with_wrap(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls):
+                return np.asarray(1).view(cls).copy()
+
+            def __array_wrap__(self, arr, context):
+                return arr.view(type(self))
+
+        a = with_wrap()
+        x = ncu.multiply(a, (1, 2, 3))
+        self.assertTrue(isinstance(x, with_wrap))
+        assert_array_equal(x, np.array((1, 2, 3)))
+
+    def test_priority_with_scalar(self):
+        # test fix for bug #826:
+
+        class A(np.ndarray):
+            __array_priority__ = 10
+
+            def __new__(cls):
+                return np.asarray(1.0, 'float64').view(cls).copy()
+
+        a = A()
+        x = np.float64(1)*a
+        self.assertTrue(isinstance(x, A))
+        assert_array_equal(x, np.array(1))
+
+    def test_old_wrap(self):
+
+        class with_wrap(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr):
+                r = with_wrap()
+                r.arr = arr
+                return r
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x.arr, np.zeros(1))
+
+    def test_priority(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                r = type(self)()
+                r.arr = arr
+                r.context = context
+                return r
+
+        class B(A):
+            __array_priority__ = 20.
+
+        class C(A):
+            __array_priority__ = 40.
+
+        x = np.zeros(1)
+        a = A()
+        b = B()
+        c = C()
+        f = ncu.minimum
+        self.assertTrue(type(f(x, x)) is np.ndarray)
+        self.assertTrue(type(f(x, a)) is A)
+        self.assertTrue(type(f(x, b)) is B)
+        self.assertTrue(type(f(x, c)) is C)
+        self.assertTrue(type(f(a, x)) is A)
+        self.assertTrue(type(f(b, x)) is B)
+        self.assertTrue(type(f(c, x)) is C)
+
+        self.assertTrue(type(f(a, a)) is A)
+        self.assertTrue(type(f(a, b)) is B)
+        self.assertTrue(type(f(b, a)) is B)
+        self.assertTrue(type(f(b, b)) is B)
+        self.assertTrue(type(f(b, c)) is C)
+        self.assertTrue(type(f(c, b)) is C)
+        self.assertTrue(type(f(c, c)) is C)
+
+        self.assertTrue(type(ncu.exp(a) is A))
+        self.assertTrue(type(ncu.exp(b) is B))
+        self.assertTrue(type(ncu.exp(c) is C))
+
+    def test_failing_wrap(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                raise RuntimeError
+
+        a = A()
+        self.assertRaises(RuntimeError, ncu.maximum, a, a)
+
+    def test_default_prepare(self):
+
+        class with_wrap(object):
+            __array_priority__ = 10
+
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_wrap__(self, arr, context):
+                return arr
+
+        a = with_wrap()
+        x = ncu.minimum(a, a)
+        assert_equal(x, np.zeros(1))
+        assert_equal(type(x), np.ndarray)
+
+    def test_prepare(self):
+
+        class with_prepare(np.ndarray):
+            __array_priority__ = 10
+
+            def __array_prepare__(self, arr, context):
+                # make sure we can return a new
+                return np.array(arr).view(type=with_prepare)
+
+        a = np.array(1).view(type=with_prepare)
+        x = np.add(a, a)
+        assert_equal(x, np.array(2))
+        assert_equal(type(x), with_prepare)
+
+    def test_failing_prepare(self):
+
+        class A(object):
+            def __array__(self):
+                return np.zeros(1)
+
+            def __array_prepare__(self, arr, context=None):
+                raise RuntimeError
+
+        a = A()
+        self.assertRaises(RuntimeError, ncu.maximum, a, a)
+
+    def test_array_with_context(self):
+
+        class A(object):
+            def __array__(self, dtype=None, context=None):
+                func, args, i = context
+                self.func = func
+                self.args = args
+                self.i = i
+                return np.zeros(1)
+
+        class B(object):
+            def __array__(self, dtype=None):
+                return np.zeros(1, dtype)
+
+        class C(object):
+            def __array__(self):
+                return np.zeros(1)
+
+        a = A()
+        ncu.maximum(np.zeros(1), a)
+        self.assertTrue(a.func is ncu.maximum)
+        assert_equal(a.args[0], 0)
+        self.assertTrue(a.args[1] is a)
+        self.assertTrue(a.i == 1)
+        assert_equal(ncu.maximum(a, B()), 0)
+        assert_equal(ncu.maximum(a, C()), 0)
+
+    def test_ufunc_override_disabled(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        # This test should be removed when __numpy_ufunc__ is re-enabled.
+
+        class MyArray(object):
+            def __numpy_ufunc__(self, *args, **kwargs):
+                self._numpy_ufunc_called = True
+
+        my_array = MyArray()
+        real_array = np.ones(10)
+        assert_raises(TypeError, lambda: real_array + my_array)
+        assert_raises(TypeError, np.add, real_array, my_array)
+        assert not hasattr(my_array, "_numpy_ufunc_called")
+
+
+    def test_ufunc_override(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return self, func, method, pos, inputs, kwargs
+
+        a = A()
+        b = np.matrix([1])
+        res0 = np.multiply(a, b)
+        res1 = np.dot(a, b)
+
+        # self
+        assert_equal(res0[0], a)
+        assert_equal(res1[0], a)
+        assert_equal(res0[1], np.multiply)
+        assert_equal(res1[1], np.dot)
+        assert_equal(res0[2], '__call__')
+        assert_equal(res1[2], '__call__')
+        assert_equal(res0[3], 0)
+        assert_equal(res1[3], 0)
+        assert_equal(res0[4], (a, b))
+        assert_equal(res1[4], (a, b))
+        assert_equal(res0[5], {})
+        assert_equal(res1[5], {})
+
+    def test_ufunc_override_mro(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        # Some multi arg functions for testing.
+        def tres_mul(a, b, c):
+            return a * b * c
+
+        def quatro_mul(a, b, c, d):
+            return a * b * c * d
+
+        # Make these into ufuncs.
+        three_mul_ufunc = np.frompyfunc(tres_mul, 3, 1)
+        four_mul_ufunc = np.frompyfunc(quatro_mul, 4, 1)
+
+        class A(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "A"
+
+        class ASub(A):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "ASub"
+
+        class B(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return "B"
+
+        class C(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        class CSub(object):
+            def __numpy_ufunc__(self, func, method, pos, inputs, **kwargs):
+                return NotImplemented
+
+        a = A()
+        a_sub = ASub()
+        b = B()
+        c = C()
+        c_sub = CSub()
+
+        # Standard
+        res = np.multiply(a, a_sub)
+        assert_equal(res, "ASub")
+        res = np.multiply(a_sub, b)
+        assert_equal(res, "ASub")
+
+        # With 1 NotImplemented
+        res = np.multiply(c, a)
+        assert_equal(res, "A")
+
+        # Both NotImplemented.
+        assert_raises(TypeError, np.multiply, c, c_sub)
+        assert_raises(TypeError, np.multiply, c_sub, c)
+        assert_raises(TypeError, np.multiply, 2, c)
+
+        # Ternary testing.
+        assert_equal(three_mul_ufunc(a, 1, 2), "A")
+        assert_equal(three_mul_ufunc(1, a, 2), "A")
+        assert_equal(three_mul_ufunc(1, 2, a), "A")
+
+        assert_equal(three_mul_ufunc(a, a, 6), "A")
+        assert_equal(three_mul_ufunc(a, 2, a), "A")
+        assert_equal(three_mul_ufunc(a, 2, b), "A")
+        assert_equal(three_mul_ufunc(a, 2, a_sub), "ASub")
+        assert_equal(three_mul_ufunc(a, a_sub, 3), "ASub")
+        assert_equal(three_mul_ufunc(c, a_sub, 3), "ASub")
+        assert_equal(three_mul_ufunc(1, a_sub, c), "ASub")
+
+        assert_equal(three_mul_ufunc(a, b, c), "A")
+        assert_equal(three_mul_ufunc(a, b, c_sub), "A")
+        assert_equal(three_mul_ufunc(1, 2, b), "B")
+
+        assert_raises(TypeError, three_mul_ufunc, 1, 2, c)
+        assert_raises(TypeError, three_mul_ufunc, c_sub, 2, c)
+        assert_raises(TypeError, three_mul_ufunc, c_sub, 2, 3)
+
+        # Quaternary testing.
+        assert_equal(four_mul_ufunc(a, 1, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, a, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, 1, a, 3), "A")
+        assert_equal(four_mul_ufunc(1, 1, 2, a), "A")
+
+        assert_equal(four_mul_ufunc(a, b, 2, 3), "A")
+        assert_equal(four_mul_ufunc(1, a, 2, b), "A")
+        assert_equal(four_mul_ufunc(b, 1, a, 3), "B")
+        assert_equal(four_mul_ufunc(a_sub, 1, 2, a), "ASub")
+        assert_equal(four_mul_ufunc(a, 1, 2, a_sub), "ASub")
+
+        assert_raises(TypeError, four_mul_ufunc, 1, 2, 3, c)
+        assert_raises(TypeError, four_mul_ufunc, 1, 2, c_sub, c)
+        assert_raises(TypeError, four_mul_ufunc, 1, c, c_sub, c)
+
+    def test_ufunc_override_methods(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return self, ufunc, method, pos, inputs, kwargs
+
+        # __call__
+        a = A()
+        res = np.multiply.__call__(1, a, foo='bar', answer=42)
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], '__call__')
+        assert_equal(res[3], 1)
+        assert_equal(res[4], (1, a))
+        assert_equal(res[5], {'foo': 'bar', 'answer': 42})
+
+        # reduce, positional args
+        res = np.multiply.reduce(a, 'axis0', 'dtype0', 'out0', 'keep0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduce')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'keepdims': 'keep0',
+                               'axis': 'axis0'})
+
+        # reduce, kwargs
+        res = np.multiply.reduce(a, axis='axis0', dtype='dtype0', out='out0',
+                                 keepdims='keep0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduce')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'keepdims': 'keep0',
+                               'axis': 'axis0'})
+
+        # accumulate, pos args
+        res = np.multiply.accumulate(a, 'axis0', 'dtype0', 'out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'accumulate')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # accumulate, kwargs
+        res = np.multiply.accumulate(a, axis='axis0', dtype='dtype0',
+                                     out='out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'accumulate')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a,))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # reduceat, pos args
+        res = np.multiply.reduceat(a, [4, 2], 'axis0', 'dtype0', 'out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduceat')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2]))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # reduceat, kwargs
+        res = np.multiply.reduceat(a, [4, 2], axis='axis0', dtype='dtype0',
+                                   out='out0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'reduceat')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2]))
+        assert_equal(res[5], {'dtype':'dtype0',
+                               'out': 'out0',
+                               'axis': 'axis0'})
+
+        # outer
+        res = np.multiply.outer(a, 42)
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'outer')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, 42))
+        assert_equal(res[5], {})
+
+        # at
+        res = np.multiply.at(a, [4, 2], 'b0')
+        assert_equal(res[0], a)
+        assert_equal(res[1], np.multiply)
+        assert_equal(res[2], 'at')
+        assert_equal(res[3], 0)
+        assert_equal(res[4], (a, [4, 2], 'b0'))
+
+    def test_ufunc_override_out(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return kwargs
+
+        class B(object):
+            def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs):
+                return kwargs
+
+        a = A()
+        b = B()
+        res0 = np.multiply(a, b, 'out_arg')
+        res1 = np.multiply(a, b, out='out_arg')
+        res2 = np.multiply(2, b, 'out_arg')
+        res3 = np.multiply(3, b, out='out_arg')
+        res4 = np.multiply(a, 4, 'out_arg')
+        res5 = np.multiply(a, 5, out='out_arg')
+
+        assert_equal(res0['out'], 'out_arg')
+        assert_equal(res1['out'], 'out_arg')
+        assert_equal(res2['out'], 'out_arg')
+        assert_equal(res3['out'], 'out_arg')
+        assert_equal(res4['out'], 'out_arg')
+        assert_equal(res5['out'], 'out_arg')
+
+        # ufuncs with multiple output modf and frexp.
+        res6 = np.modf(a, 'out0', 'out1')
+        res7 = np.frexp(a, 'out0', 'out1')
+        assert_equal(res6['out'][0], 'out0')
+        assert_equal(res6['out'][1], 'out1')
+        assert_equal(res7['out'][0], 'out0')
+        assert_equal(res7['out'][1], 'out1')
+
+    def test_ufunc_override_exception(self):
+        # 2016-01-29: NUMPY_UFUNC_DISABLED
+        return
+
+        class A(object):
+            def __numpy_ufunc__(self, *a, **kwargs):
+                raise ValueError("oops")
+
+        a = A()
+        for func in [np.divide, np.dot]:
+            assert_raises(ValueError, func, a, a)
+
+class TestChoose(TestCase):
+    def test_mixed(self):
+        c = np.array([True, True])
+        a = np.array([True, True])
+        assert_equal(np.choose(c, (a, 1)), np.array([1, 1]))
+
+
+def is_longdouble_finfo_bogus():
+    info = np.finfo(np.longcomplex)
+    return not np.isfinite(np.log10(info.tiny/info.eps))
+
+
+class TestComplexFunctions(object):
+    funcs = [np.arcsin,  np.arccos,  np.arctan, np.arcsinh, np.arccosh,
+             np.arctanh, np.sin,     np.cos,    np.tan,     np.exp,
+             np.exp2,    np.log,     np.sqrt,   np.log10,   np.log2,
+             np.log1p]
+
+    def test_it(self):
+        for f in self.funcs:
+            if f is np.arccosh:
+                x = 1.5
+            else:
+                x = .5
+            fr = f(x)
+            fz = f(np.complex(x))
+            assert_almost_equal(fz.real, fr, err_msg='real part %s' % f)
+            assert_almost_equal(fz.imag, 0., err_msg='imag part %s' % f)
+
+    def test_precisions_consistent(self):
+        z = 1 + 1j
+        for f in self.funcs:
+            fcf = f(np.csingle(z))
+            fcd = f(np.cdouble(z))
+            fcl = f(np.clongdouble(z))
+            assert_almost_equal(fcf, fcd, decimal=6, err_msg='fch-fcd %s' % f)
+            assert_almost_equal(fcl, fcd, decimal=15, err_msg='fch-fcl %s' % f)
+
+    def test_branch_cuts(self):
+        # check branch cuts and continuity on them
+        yield _check_branch_cut, np.log,   -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log2,  -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True
+        yield _check_branch_cut, np.sqrt,  -0.5, 1j, 1, -1, True
+
+        yield _check_branch_cut, np.arcsin, [ -2, 2],   [1j, 1j], 1, -1, True
+        yield _check_branch_cut, np.arccos, [ -2, 2],   [1j, 1j], 1, -1, True
+        yield _check_branch_cut, np.arctan, [0-2j, 2j],  [1,  1], -1, 1, True
+
+        yield _check_branch_cut, np.arcsinh, [0-2j,  2j], [1,   1], -1, 1, True
+        yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j,  1j], 1, -1, True
+        yield _check_branch_cut, np.arctanh, [ -2,   2], [1j, 1j], 1, -1, True
+
+        # check against bogus branch cuts: assert continuity between quadrants
+        yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1,  1], 1, 1
+        yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1,  1], 1, 1
+        yield _check_branch_cut, np.arctan, [ -2,  2], [1j, 1j], 1, 1
+
+        yield _check_branch_cut, np.arcsinh, [ -2,  2, 0], [1j, 1j, 1], 1, 1
+        yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1,  1,  1j], 1, 1
+        yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1,  1,  1j], 1, 1
+
+    def test_branch_cuts_complex64(self):
+        # check branch cuts and continuity on them
+        yield _check_branch_cut, np.log,   -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log2,  -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True, np.complex64
+        yield _check_branch_cut, np.sqrt,  -0.5, 1j, 1, -1, True, np.complex64
+
+        yield _check_branch_cut, np.arcsin, [ -2, 2],   [1j, 1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arccos, [ -2, 2],   [1j, 1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arctan, [0-2j, 2j],  [1,  1], -1, 1, True, np.complex64
+
+        yield _check_branch_cut, np.arcsinh, [0-2j,  2j], [1,   1], -1, 1, True, np.complex64
+        yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j,  1j], 1, -1, True, np.complex64
+        yield _check_branch_cut, np.arctanh, [ -2,   2], [1j, 1j], 1, -1, True, np.complex64
+
+        # check against bogus branch cuts: assert continuity between quadrants
+        yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1,  1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1,  1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arctan, [ -2,  2], [1j, 1j], 1, 1, False, np.complex64
+
+        yield _check_branch_cut, np.arcsinh, [ -2,  2, 0], [1j, 1j, 1], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1,  1,  1j], 1, 1, False, np.complex64
+        yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1,  1,  1j], 1, 1, False, np.complex64
+
+    def test_against_cmath(self):
+        import cmath
+
+        points = [-1-1j, -1+1j, +1-1j, +1+1j]
+        name_map = {'arcsin': 'asin', 'arccos': 'acos', 'arctan': 'atan',
+                    'arcsinh': 'asinh', 'arccosh': 'acosh', 'arctanh': 'atanh'}
+        atol = 4*np.finfo(np.complex).eps
+        for func in self.funcs:
+            fname = func.__name__.split('.')[-1]
+            cname = name_map.get(fname, fname)
+            try:
+                cfunc = getattr(cmath, cname)
+            except AttributeError:
+                continue
+            for p in points:
+                a = complex(func(np.complex_(p)))
+                b = cfunc(p)
+                assert_(abs(a - b) < atol, "%s %s: %s; cmath: %s" % (fname, p, a, b))
+
+    def check_loss_of_precision(self, dtype):
+        """Check loss of precision in complex arc* functions"""
+
+        # Check against known-good functions
+
+        info = np.finfo(dtype)
+        real_dtype = dtype(0.).real.dtype
+        eps = info.eps
+
+        def check(x, rtol):
+            x = x.astype(real_dtype)
+
+            z = x.astype(dtype)
+            d = np.absolute(np.arcsinh(x)/np.arcsinh(z).real - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arcsinh'))
+
+            z = (1j*x).astype(dtype)
+            d = np.absolute(np.arcsinh(x)/np.arcsin(z).imag - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arcsin'))
+
+            z = x.astype(dtype)
+            d = np.absolute(np.arctanh(x)/np.arctanh(z).real - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arctanh'))
+
+            z = (1j*x).astype(dtype)
+            d = np.absolute(np.arctanh(x)/np.arctan(z).imag - 1)
+            assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(),
+                                      'arctan'))
+
+        # The switchover was chosen as 1e-3; hence there can be up to
+        # ~eps/1e-3 of relative cancellation error before it
+
+        x_series = np.logspace(-20, -3.001, 200)
+        x_basic = np.logspace(-2.999, 0, 10, endpoint=False)
+
+        if dtype is np.longcomplex:
+            # It's not guaranteed that the system-provided arc functions
+            # are accurate down to a few epsilons. (Eg. on Linux 64-bit)
+            # So, give more leeway for long complex tests here:
+            check(x_series, 50*eps)
+        else:
+            check(x_series, 2.1*eps)
+        check(x_basic, 2*eps/1e-3)
+
+        # Check a few points
+
+        z = np.array([1e-5*(1+1j)], dtype=dtype)
+        p = 9.999999999333333333e-6 + 1.000000000066666666e-5j
+        d = np.absolute(1-np.arctanh(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 1.0000000000333333333e-5 + 9.999999999666666667e-6j
+        d = np.absolute(1-np.arcsinh(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 9.999999999333333333e-6j + 1.000000000066666666e-5
+        d = np.absolute(1-np.arctan(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        p = 1.0000000000333333333e-5j + 9.999999999666666667e-6
+        d = np.absolute(1-np.arcsin(z)/p)
+        assert_(np.all(d < 1e-15))
+
+        # Check continuity across switchover points
+
+        def check(func, z0, d=1):
+            z0 = np.asarray(z0, dtype=dtype)
+            zp = z0 + abs(z0) * d * eps * 2
+            zm = z0 - abs(z0) * d * eps * 2
+            assert_(np.all(zp != zm), (zp, zm))
+
+            # NB: the cancellation error at the switchover is at least eps
+            good = (abs(func(zp) - func(zm)) < 2*eps)
+            assert_(np.all(good), (func, z0[~good]))
+
+        for func in (np.arcsinh, np.arcsinh, np.arcsin, np.arctanh, np.arctan):
+            pts = [rp+1j*ip for rp in (-1e-3, 0, 1e-3) for ip in(-1e-3, 0, 1e-3)
+                   if rp != 0 or ip != 0]
+            check(func, pts, 1)
+            check(func, pts, 1j)
+            check(func, pts, 1+1j)
+
+    def test_loss_of_precision(self):
+        for dtype in [np.complex64, np.complex_]:
+            yield self.check_loss_of_precision, dtype
+
+    @dec.knownfailureif(is_longdouble_finfo_bogus(), "Bogus long double finfo")
+    def test_loss_of_precision_longcomplex(self):
+        self.check_loss_of_precision(np.longcomplex)
+
+
+class TestAttributes(TestCase):
+    def test_attributes(self):
+        add = ncu.add
+        assert_equal(add.__name__, 'add')
+        assert_(add.__doc__.startswith('add(x1, x2[, out])\n\n'))
+        self.assertTrue(add.ntypes >= 18)  # don't fail if types added
+        self.assertTrue('ii->i' in add.types)
+        assert_equal(add.nin, 2)
+        assert_equal(add.nout, 1)
+        assert_equal(add.identity, 0)
+
+
+class TestSubclass(TestCase):
+
+    def test_subclass_op(self):
+
+        class simple(np.ndarray):
+            def __new__(subtype, shape):
+                self = np.ndarray.__new__(subtype, shape, dtype=object)
+                self.fill(0)
+                return self
+
+        a = simple((3, 4))
+        assert_equal(a+a, a)
+
+def _check_branch_cut(f, x0, dx, re_sign=1, im_sign=-1, sig_zero_ok=False,
+                      dtype=np.complex):
+    """
+    Check for a branch cut in a function.
+
+    Assert that `x0` lies on a branch cut of function `f` and `f` is
+    continuous from the direction `dx`.
+
+    Parameters
+    ----------
+    f : func
+        Function to check
+    x0 : array-like
+        Point on branch cut
+    dx : array-like
+        Direction to check continuity in
+    re_sign, im_sign : {1, -1}
+        Change of sign of the real or imaginary part expected
+    sig_zero_ok : bool
+        Whether to check if the branch cut respects signed zero (if applicable)
+    dtype : dtype
+        Dtype to check (should be complex)
+
+    """
+    x0 = np.atleast_1d(x0).astype(dtype)
+    dx = np.atleast_1d(dx).astype(dtype)
+
+    if np.dtype(dtype).char == 'F':
+        scale = np.finfo(dtype).eps * 1e2
+        atol = np.float32(1e-2)
+    else:
+        scale = np.finfo(dtype).eps * 1e3
+        atol = 1e-4
+
+    y0 = f(x0)
+    yp = f(x0 + dx*scale*np.absolute(x0)/np.absolute(dx))
+    ym = f(x0 - dx*scale*np.absolute(x0)/np.absolute(dx))
+
+    assert_(np.all(np.absolute(y0.real - yp.real) < atol), (y0, yp))
+    assert_(np.all(np.absolute(y0.imag - yp.imag) < atol), (y0, yp))
+    assert_(np.all(np.absolute(y0.real - ym.real*re_sign) < atol), (y0, ym))
+    assert_(np.all(np.absolute(y0.imag - ym.imag*im_sign) < atol), (y0, ym))
+
+    if sig_zero_ok:
+        # check that signed zeros also work as a displacement
+        jr = (x0.real == 0) & (dx.real != 0)
+        ji = (x0.imag == 0) & (dx.imag != 0)
+        if np.any(jr):
+            x = x0[jr]
+            x.real = np.NZERO
+            ym = f(x)
+            assert_(np.all(np.absolute(y0[jr].real - ym.real*re_sign) < atol), (y0[jr], ym))
+            assert_(np.all(np.absolute(y0[jr].imag - ym.imag*im_sign) < atol), (y0[jr], ym))
+
+        if np.any(ji):
+            x = x0[ji]
+            x.imag = np.NZERO
+            ym = f(x)
+            assert_(np.all(np.absolute(y0[ji].real - ym.real*re_sign) < atol), (y0[ji], ym))
+            assert_(np.all(np.absolute(y0[ji].imag - ym.imag*im_sign) < atol), (y0[ji], ym))
+
+def test_copysign():
+    assert_(np.copysign(1, -1) == -1)
+    with np.errstate(divide="ignore"):
+        assert_(1 / np.copysign(0, -1) < 0)
+        assert_(1 / np.copysign(0, 1) > 0)
+    assert_(np.signbit(np.copysign(np.nan, -1)))
+    assert_(not np.signbit(np.copysign(np.nan, 1)))
+
+def _test_nextafter(t):
+    one = t(1)
+    two = t(2)
+    zero = t(0)
+    eps = np.finfo(t).eps
+    assert_(np.nextafter(one, two) - one == eps)
+    assert_(np.nextafter(one, zero) - one < 0)
+    assert_(np.isnan(np.nextafter(np.nan, one)))
+    assert_(np.isnan(np.nextafter(one, np.nan)))
+    assert_(np.nextafter(one, one) == one)
+
+def test_nextafter():
+    return _test_nextafter(np.float64)
+
+def test_nextafterf():
+    return _test_nextafter(np.float32)
+
+@dec.knownfailureif(sys.platform == 'win32' or on_powerpc(),
+            "Long double support buggy on win32 and PPC, ticket 1664.")
+def test_nextafterl():
+    return _test_nextafter(np.longdouble)
+
+def _test_spacing(t):
+    one = t(1)
+    eps = np.finfo(t).eps
+    nan = t(np.nan)
+    inf = t(np.inf)
+    with np.errstate(invalid='ignore'):
+        assert_(np.spacing(one) == eps)
+        assert_(np.isnan(np.spacing(nan)))
+        assert_(np.isnan(np.spacing(inf)))
+        assert_(np.isnan(np.spacing(-inf)))
+        assert_(np.spacing(t(1e30)) != 0)
+
+def test_spacing():
+    return _test_spacing(np.float64)
+
+def test_spacingf():
+    return _test_spacing(np.float32)
+
+@dec.knownfailureif(sys.platform == 'win32' or on_powerpc(),
+            "Long double support buggy on win32 and PPC, ticket 1664.")
+def test_spacingl():
+    return _test_spacing(np.longdouble)
+
+def test_spacing_gfortran():
+    # Reference from this fortran file, built with gfortran 4.3.3 on linux
+    # 32bits:
+    #       PROGRAM test_spacing
+    #        INTEGER, PARAMETER :: SGL = SELECTED_REAL_KIND(p=6, r=37)
+    #        INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(p=13, r=200)
+    #
+    #        WRITE(*,*) spacing(0.00001_DBL)
+    #        WRITE(*,*) spacing(1.0_DBL)
+    #        WRITE(*,*) spacing(1000._DBL)
+    #        WRITE(*,*) spacing(10500._DBL)
+    #
+    #        WRITE(*,*) spacing(0.00001_SGL)
+    #        WRITE(*,*) spacing(1.0_SGL)
+    #        WRITE(*,*) spacing(1000._SGL)
+    #        WRITE(*,*) spacing(10500._SGL)
+    #       END PROGRAM
+    ref = {np.float64: [1.69406589450860068E-021,
+                        2.22044604925031308E-016,
+                        1.13686837721616030E-013,
+                        1.81898940354585648E-012],
+           np.float32: [9.09494702E-13,
+                        1.19209290E-07,
+                        6.10351563E-05,
+                        9.76562500E-04]}
+
+    for dt, dec_ in zip([np.float32, np.float64], (10, 20)):
+        x = np.array([1e-5, 1, 1000, 10500], dtype=dt)
+        assert_array_almost_equal(np.spacing(x), ref[dt], decimal=dec_)
+
+def test_nextafter_vs_spacing():
+    # XXX: spacing does not handle long double yet
+    for t in [np.float32, np.float64]:
+        for _f in [1, 1e-5, 1000]:
+            f = t(_f)
+            f1 = t(_f + 1)
+            assert_(np.nextafter(f, f1) - f == np.spacing(f))
+
+def test_pos_nan():
+    """Check np.nan is a positive nan."""
+    assert_(np.signbit(np.nan) == 0)
+
+def test_reduceat():
+    """Test bug in reduceat when structured arrays are not copied."""
+    db = np.dtype([('name', 'S11'), ('time', np.int64), ('value', np.float32)])
+    a = np.empty([100], dtype=db)
+    a['name'] = 'Simple'
+    a['time'] = 10
+    a['value'] = 100
+    indx = [0, 7, 15, 25]
+
+    h2 = []
+    val1 = indx[0]
+    for val2 in indx[1:]:
+        h2.append(np.add.reduce(a['value'][val1:val2]))
+        val1 = val2
+    h2.append(np.add.reduce(a['value'][val1:]))
+    h2 = np.array(h2)
+
+    # test buffered -- this should work
+    h1 = np.add.reduceat(a['value'], indx)
+    assert_array_almost_equal(h1, h2)
+
+    # This is when the error occurs.
+    # test no buffer
+    np.setbufsize(32)
+    h1 = np.add.reduceat(a['value'], indx)
+    np.setbufsize(np.UFUNC_BUFSIZE_DEFAULT)
+    assert_array_almost_equal(h1, h2)
+
+def test_reduceat_empty():
+    """Reduceat should work with empty arrays"""
+    indices = np.array([], 'i4')
+    x = np.array([], 'f8')
+    result = np.add.reduceat(x, indices)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (0,))
+    # Another case with a slightly different zero-sized shape
+    x = np.ones((5, 2))
+    result = np.add.reduceat(x, [], axis=0)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (0, 2))
+    result = np.add.reduceat(x, [], axis=1)
+    assert_equal(result.dtype, x.dtype)
+    assert_equal(result.shape, (5, 0))
+
+def test_complex_nan_comparisons():
+    nans = [complex(np.nan, 0), complex(0, np.nan), complex(np.nan, np.nan)]
+    fins = [complex(1, 0), complex(-1, 0), complex(0, 1), complex(0, -1),
+            complex(1, 1), complex(-1, -1), complex(0, 0)]
+
+    with np.errstate(invalid='ignore'):
+        for x in nans + fins:
+            x = np.array([x])
+            for y in nans + fins:
+                y = np.array([y])
+
+                if np.isfinite(x) and np.isfinite(y):
+                    continue
+
+                assert_equal(x < y, False, err_msg="%r < %r" % (x, y))
+                assert_equal(x > y, False, err_msg="%r > %r" % (x, y))
+                assert_equal(x <= y, False, err_msg="%r <= %r" % (x, y))
+                assert_equal(x >= y, False, err_msg="%r >= %r" % (x, y))
+                assert_equal(x == y, False, err_msg="%r == %r" % (x, y))
+
+
+def test_rint_big_int():
+    # np.rint bug for large integer values on Windows 32-bit and MKL
+    # https://github.com/numpy/numpy/issues/6685
+    val = 4607998452777363968
+    # This is exactly representable in floating point
+    assert_equal(val, int(float(val)))
+    # Rint should not change the value
+    assert_equal(val, np.rint(val))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
new file mode 100644
index 0000000000..536ad398a7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
@@ -0,0 +1,538 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import platform
+
+import numpy as np
+import numpy.core.umath as ncu
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_almost_equal, dec
+)
+
+# TODO: branch cuts (use Pauli code)
+# TODO: conj 'symmetry'
+# TODO: FPU exceptions
+
+# At least on Windows the results of many complex functions are not conforming
+# to the C99 standard. See ticket 1574.
+# Ditto for Solaris (ticket 1642) and OS X on PowerPC.
+with np.errstate(all='ignore'):
+    functions_seem_flaky = ((np.exp(complex(np.inf, 0)).imag != 0)
+                            or (np.log(complex(np.NZERO, 0)).imag != np.pi))
+# TODO: replace with a check on whether platform-provided C99 funcs are used
+skip_complex_tests = (not sys.platform.startswith('linux') or functions_seem_flaky)
+
+def platform_skip(func):
+    return dec.skipif(skip_complex_tests,
+        "Numpy is using complex functions (e.g. sqrt) provided by your"
+        "platform's C library. However, they do not seem to behave according"
+        "to C99 -- so C99 tests are skipped.")(func)
+
+
+class TestCexp(object):
+    def test_simple(self):
+        check = check_complex_value
+        f = np.exp
+
+        yield check, f, 1, 0, np.exp(1), 0, False
+        yield check, f, 0, 1, np.cos(1), np.sin(1), False
+
+        ref = np.exp(1) * np.complex(np.cos(1), np.sin(1))
+        yield check, f, 1, 1, ref.real, ref.imag, False
+
+    @platform_skip
+    def test_special_values(self):
+        # C99: Section G 6.3.1
+
+        check = check_complex_value
+        f = np.exp
+
+        # cexp(+-0 + 0i) is 1 + 0i
+        yield check, f, np.PZERO, 0, 1, 0, False
+        yield check, f, np.NZERO, 0, 1, 0, False
+
+        # cexp(x + infi) is nan + nani for finite x and raises 'invalid' FPU
+        # exception
+        yield check, f,  1, np.inf, np.nan, np.nan
+        yield check, f, -1, np.inf, np.nan, np.nan
+        yield check, f,  0, np.inf, np.nan, np.nan
+
+        # cexp(inf + 0i) is inf + 0i
+        yield check, f,  np.inf, 0, np.inf, 0
+
+        # cexp(-inf + yi) is +0 * (cos(y) + i sin(y)) for finite y
+        yield check, f,  -np.inf, 1, np.PZERO, np.PZERO
+        yield check, f,  -np.inf, 0.75 * np.pi, np.NZERO, np.PZERO
+
+        # cexp(inf + yi) is +inf * (cos(y) + i sin(y)) for finite y
+        yield check, f,  np.inf, 1, np.inf, np.inf
+        yield check, f,  np.inf, 0.75 * np.pi, -np.inf, np.inf
+
+        # cexp(-inf + inf i) is +-0 +- 0i (signs unspecified)
+        def _check_ninf_inf(dummy):
+            msgform = "cexp(-inf, inf) is (%f, %f), expected (+-0, +-0)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(-np.inf, np.inf)))
+                if z.real != 0 or z.imag != 0:
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_inf, None
+
+        # cexp(inf + inf i) is +-inf + NaNi and raised invalid FPU ex.
+        def _check_inf_inf(dummy):
+            msgform = "cexp(inf, inf) is (%f, %f), expected (+-inf, nan)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(np.inf, np.inf)))
+                if not np.isinf(z.real) or not np.isnan(z.imag):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_inf_inf, None
+
+        # cexp(-inf + nan i) is +-0 +- 0i
+        def _check_ninf_nan(dummy):
+            msgform = "cexp(-inf, nan) is (%f, %f), expected (+-0, +-0)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(-np.inf, np.nan)))
+                if z.real != 0 or z.imag != 0:
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_nan, None
+
+        # cexp(inf + nan i) is +-inf + nan
+        def _check_inf_nan(dummy):
+            msgform = "cexp(-inf, nan) is (%f, %f), expected (+-inf, nan)"
+            with np.errstate(invalid='ignore'):
+                z = f(np.array(np.complex(np.inf, np.nan)))
+                if not np.isinf(z.real) or not np.isnan(z.imag):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_inf_nan, None
+
+        # cexp(nan + yi) is nan + nani for y != 0 (optional: raises invalid FPU
+        # ex)
+        yield check, f, np.nan, 1, np.nan, np.nan
+        yield check, f, np.nan, -1, np.nan, np.nan
+
+        yield check, f, np.nan,  np.inf, np.nan, np.nan
+        yield check, f, np.nan, -np.inf, np.nan, np.nan
+
+        # cexp(nan + nani) is nan + nani
+        yield check, f, np.nan, np.nan, np.nan, np.nan
+
+    @dec.knownfailureif(True, "cexp(nan + 0I) is wrong on most implementations")
+    def test_special_values2(self):
+        # XXX: most implementations get it wrong here (including glibc <= 2.10)
+        # cexp(nan + 0i) is nan + 0i
+        check = check_complex_value
+        f = np.exp
+
+        yield check, f, np.nan, 0, np.nan, 0
+
+class TestClog(TestCase):
+    def test_simple(self):
+        x = np.array([1+0j, 1+2j])
+        y_r = np.log(np.abs(x)) + 1j * np.angle(x)
+        y = np.log(x)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    @platform_skip
+    @dec.skipif(platform.machine() == "armv5tel", "See gh-413.")
+    def test_special_values(self):
+        xl = []
+        yl = []
+
+        # From C99 std (Sec 6.3.2)
+        # XXX: check exceptions raised
+        # --- raise for invalid fails.
+
+        # clog(-0 + i0) returns -inf + i pi and raises the 'divide-by-zero'
+        # floating-point exception.
+        with np.errstate(divide='raise'):
+            x = np.array([np.NZERO], dtype=np.complex)
+            y = np.complex(-np.inf, np.pi)
+            self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(divide='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+0 + i0) returns -inf + i0 and raises the 'divide-by-zero'
+        # floating-point exception.
+        with np.errstate(divide='raise'):
+            x = np.array([0], dtype=np.complex)
+            y = np.complex(-np.inf, 0)
+            self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(divide='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(x + i inf returns +inf + i pi /2, for finite x.
+        x = np.array([complex(1, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.5 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        x = np.array([complex(-1, np.inf)], dtype=np.complex)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(x + iNaN) returns NaN + iNaN and optionally raises the
+        # 'invalid' floating- point exception, for finite x.
+        with np.errstate(invalid='raise'):
+            x = np.array([complex(1., np.nan)], dtype=np.complex)
+            y = np.complex(np.nan, np.nan)
+            #self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(invalid='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        with np.errstate(invalid='raise'):
+            x = np.array([np.inf + 1j * np.nan], dtype=np.complex)
+            #self.assertRaises(FloatingPointError, np.log, x)
+        with np.errstate(invalid='ignore'):
+            assert_almost_equal(np.log(x), y)
+
+        xl.append(x)
+        yl.append(y)
+
+        # clog(- inf + iy) returns +inf + ipi , for finite positive-signed y.
+        x = np.array([-np.inf + 1j], dtype=np.complex)
+        y = np.complex(np.inf, np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+ inf + iy) returns +inf + i0, for finite positive-signed y.
+        x = np.array([np.inf + 1j], dtype=np.complex)
+        y = np.complex(np.inf, 0)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(- inf + i inf) returns +inf + i3pi /4.
+        x = np.array([complex(-np.inf, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.75 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+ inf + i inf) returns +inf + ipi /4.
+        x = np.array([complex(np.inf, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, 0.25 * np.pi)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(+/- inf + iNaN) returns +inf + iNaN.
+        x = np.array([complex(np.inf, np.nan)], dtype=np.complex)
+        y = np.complex(np.inf, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        x = np.array([complex(-np.inf, np.nan)], dtype=np.complex)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + iy) returns NaN + iNaN and optionally raises the
+        # 'invalid' floating-point exception, for finite y.
+        x = np.array([complex(np.nan, 1)], dtype=np.complex)
+        y = np.complex(np.nan, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + i inf) returns +inf + iNaN.
+        x = np.array([complex(np.nan, np.inf)], dtype=np.complex)
+        y = np.complex(np.inf, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(NaN + iNaN) returns NaN + iNaN.
+        x = np.array([complex(np.nan, np.nan)], dtype=np.complex)
+        y = np.complex(np.nan, np.nan)
+        assert_almost_equal(np.log(x), y)
+        xl.append(x)
+        yl.append(y)
+
+        # clog(conj(z)) = conj(clog(z)).
+        xa = np.array(xl, dtype=np.complex)
+        ya = np.array(yl, dtype=np.complex)
+        with np.errstate(divide='ignore'):
+            for i in range(len(xa)):
+                assert_almost_equal(np.log(xa[i].conj()), ya[i].conj())
+
+class TestCsqrt(object):
+
+    def test_simple(self):
+        # sqrt(1)
+        yield check_complex_value, np.sqrt, 1, 0, 1, 0
+
+        # sqrt(1i)
+        yield check_complex_value, np.sqrt, 0, 1, 0.5*np.sqrt(2), 0.5*np.sqrt(2), False
+
+        # sqrt(-1)
+        yield check_complex_value, np.sqrt, -1, 0, 0, 1
+
+    def test_simple_conjugate(self):
+        ref = np.conj(np.sqrt(np.complex(1, 1)))
+
+        def f(z):
+            return np.sqrt(np.conj(z))
+        yield check_complex_value, f, 1, 1, ref.real, ref.imag, False
+
+    #def test_branch_cut(self):
+    #    _check_branch_cut(f, -1, 0, 1, -1)
+
+    @platform_skip
+    def test_special_values(self):
+        # C99: Sec G 6.4.2
+
+        check = check_complex_value
+        f = np.sqrt
+
+        # csqrt(+-0 + 0i) is 0 + 0i
+        yield check, f, np.PZERO, 0, 0, 0
+        yield check, f, np.NZERO, 0, 0, 0
+
+        # csqrt(x + infi) is inf + infi for any x (including NaN)
+        yield check, f,  1, np.inf, np.inf, np.inf
+        yield check, f, -1, np.inf, np.inf, np.inf
+
+        yield check, f, np.PZERO, np.inf, np.inf, np.inf
+        yield check, f, np.NZERO, np.inf, np.inf, np.inf
+        yield check, f,   np.inf, np.inf, np.inf, np.inf
+        yield check, f,  -np.inf, np.inf, np.inf, np.inf
+        yield check, f,  -np.nan, np.inf, np.inf, np.inf
+
+        # csqrt(x + nani) is nan + nani for any finite x
+        yield check, f,  1, np.nan, np.nan, np.nan
+        yield check, f, -1, np.nan, np.nan, np.nan
+        yield check, f,  0, np.nan, np.nan, np.nan
+
+        # csqrt(-inf + yi) is +0 + infi for any finite y > 0
+        yield check, f, -np.inf, 1, np.PZERO, np.inf
+
+        # csqrt(inf + yi) is +inf + 0i for any finite y > 0
+        yield check, f, np.inf, 1, np.inf, np.PZERO
+
+        # csqrt(-inf + nani) is nan +- infi (both +i infi are valid)
+        def _check_ninf_nan(dummy):
+            msgform = "csqrt(-inf, nan) is (%f, %f), expected (nan, +-inf)"
+            z = np.sqrt(np.array(np.complex(-np.inf, np.nan)))
+            #Fixme: ugly workaround for isinf bug.
+            with np.errstate(invalid='ignore'):
+                if not (np.isnan(z.real) and np.isinf(z.imag)):
+                    raise AssertionError(msgform % (z.real, z.imag))
+
+        yield _check_ninf_nan, None
+
+        # csqrt(+inf + nani) is inf + nani
+        yield check, f, np.inf, np.nan, np.inf, np.nan
+
+        # csqrt(nan + yi) is nan + nani for any finite y (infinite handled in x
+        # + nani)
+        yield check, f, np.nan,       0, np.nan, np.nan
+        yield check, f, np.nan,       1, np.nan, np.nan
+        yield check, f, np.nan,  np.nan, np.nan, np.nan
+
+        # XXX: check for conj(csqrt(z)) == csqrt(conj(z)) (need to fix branch
+        # cuts first)
+
+class TestCpow(TestCase):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def test_simple(self):
+        x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan])
+        y_r = x ** 2
+        y = np.power(x, 2)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    def test_scalar(self):
+        x = np.array([1, 1j,         2,  2.5+.37j, np.inf, np.nan])
+        y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j,      2,      3])
+        lx = list(range(len(x)))
+        # Compute the values for complex type in python
+        p_r = [complex(x[i]) ** complex(y[i]) for i in lx]
+        # Substitute a result allowed by C99 standard
+        p_r[4] = complex(np.inf, np.nan)
+        # Do the same with numpy complex scalars
+        n_r = [x[i] ** y[i] for i in lx]
+        for i in lx:
+            assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i)
+
+    def test_array(self):
+        x = np.array([1, 1j,         2,  2.5+.37j, np.inf, np.nan])
+        y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j,      2,      3])
+        lx = list(range(len(x)))
+        # Compute the values for complex type in python
+        p_r = [complex(x[i]) ** complex(y[i]) for i in lx]
+        # Substitute a result allowed by C99 standard
+        p_r[4] = complex(np.inf, np.nan)
+        # Do the same with numpy arrays
+        n_r = x ** y
+        for i in lx:
+            assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i)
+
+class TestCabs(object):
+    def setUp(self):
+        self.olderr = np.seterr(invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.olderr)
+
+    def test_simple(self):
+        x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan])
+        y_r = np.array([np.sqrt(2.), 2, np.sqrt(5), np.inf, np.nan])
+        y = np.abs(x)
+        for i in range(len(x)):
+            assert_almost_equal(y[i], y_r[i])
+
+    def test_fabs(self):
+        # Test that np.abs(x +- 0j) == np.abs(x) (as mandated by C99 for cabs)
+        x = np.array([1+0j], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(1, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(np.inf, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+        x = np.array([complex(np.nan, np.NZERO)], dtype=np.complex)
+        assert_array_equal(np.abs(x), np.real(x))
+
+    def test_cabs_inf_nan(self):
+        x, y = [], []
+
+        # cabs(+-nan + nani) returns nan
+        x.append(np.nan)
+        y.append(np.nan)
+        yield check_real_value, np.abs,  np.nan, np.nan, np.nan
+
+        x.append(np.nan)
+        y.append(-np.nan)
+        yield check_real_value, np.abs, -np.nan, np.nan, np.nan
+
+        # According to C99 standard, if exactly one of the real/part is inf and
+        # the other nan, then cabs should return inf
+        x.append(np.inf)
+        y.append(np.nan)
+        yield check_real_value, np.abs,  np.inf, np.nan, np.inf
+
+        x.append(-np.inf)
+        y.append(np.nan)
+        yield check_real_value, np.abs, -np.inf, np.nan, np.inf
+
+        # cabs(conj(z)) == conj(cabs(z)) (= cabs(z))
+        def f(a):
+            return np.abs(np.conj(a))
+
+        def g(a, b):
+            return np.abs(np.complex(a, b))
+
+        xa = np.array(x, dtype=np.complex)
+        for i in range(len(xa)):
+            ref = g(x[i], y[i])
+            yield check_real_value, f, x[i], y[i], ref
+
+class TestCarg(object):
+    def test_simple(self):
+        check_real_value(ncu._arg, 1, 0, 0, False)
+        check_real_value(ncu._arg, 0, 1, 0.5*np.pi, False)
+
+        check_real_value(ncu._arg, 1, 1, 0.25*np.pi, False)
+        check_real_value(ncu._arg, np.PZERO, np.PZERO, np.PZERO)
+
+    @dec.knownfailureif(True,
+        "Complex arithmetic with signed zero is buggy on most implementation")
+    def test_zero(self):
+        # carg(-0 +- 0i) returns +- pi
+        yield check_real_value, ncu._arg, np.NZERO, np.PZERO,  np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, np.NZERO, -np.pi, False
+
+        # carg(+0 +- 0i) returns +- 0
+        yield check_real_value, ncu._arg, np.PZERO, np.PZERO, np.PZERO
+        yield check_real_value, ncu._arg, np.PZERO, np.NZERO, np.NZERO
+
+        # carg(x +- 0i) returns +- 0 for x > 0
+        yield check_real_value, ncu._arg, 1, np.PZERO, np.PZERO, False
+        yield check_real_value, ncu._arg, 1, np.NZERO, np.NZERO, False
+
+        # carg(x +- 0i) returns +- pi for x < 0
+        yield check_real_value, ncu._arg, -1, np.PZERO,  np.pi, False
+        yield check_real_value, ncu._arg, -1, np.NZERO, -np.pi, False
+
+        # carg(+- 0 + yi) returns pi/2 for y > 0
+        yield check_real_value, ncu._arg, np.PZERO, 1, 0.5 * np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, 1, 0.5 * np.pi, False
+
+        # carg(+- 0 + yi) returns -pi/2 for y < 0
+        yield check_real_value, ncu._arg, np.PZERO, -1, 0.5 * np.pi, False
+        yield check_real_value, ncu._arg, np.NZERO, -1, -0.5 * np.pi, False
+
+    #def test_branch_cuts(self):
+    #    _check_branch_cut(ncu._arg, -1, 1j, -1, 1)
+
+    def test_special_values(self):
+        # carg(-np.inf +- yi) returns +-pi for finite y > 0
+        yield check_real_value, ncu._arg, -np.inf,  1,  np.pi, False
+        yield check_real_value, ncu._arg, -np.inf, -1, -np.pi, False
+
+        # carg(np.inf +- yi) returns +-0 for finite y > 0
+        yield check_real_value, ncu._arg, np.inf,  1, np.PZERO, False
+        yield check_real_value, ncu._arg, np.inf, -1, np.NZERO, False
+
+        # carg(x +- np.infi) returns +-pi/2 for finite x
+        yield check_real_value, ncu._arg, 1,  np.inf,  0.5 * np.pi, False
+        yield check_real_value, ncu._arg, 1, -np.inf, -0.5 * np.pi, False
+
+        # carg(-np.inf +- np.infi) returns +-3pi/4
+        yield check_real_value, ncu._arg, -np.inf,  np.inf,  0.75 * np.pi, False
+        yield check_real_value, ncu._arg, -np.inf, -np.inf, -0.75 * np.pi, False
+
+        # carg(np.inf +- np.infi) returns +-pi/4
+        yield check_real_value, ncu._arg, np.inf,  np.inf,  0.25 * np.pi, False
+        yield check_real_value, ncu._arg, np.inf, -np.inf, -0.25 * np.pi, False
+
+        # carg(x + yi) returns np.nan if x or y is nan
+        yield check_real_value, ncu._arg, np.nan,      0, np.nan, False
+        yield check_real_value, ncu._arg,      0, np.nan, np.nan, False
+
+        yield check_real_value, ncu._arg, np.nan, np.inf, np.nan, False
+        yield check_real_value, ncu._arg, np.inf, np.nan, np.nan, False
+
+def check_real_value(f, x1, y1, x, exact=True):
+    z1 = np.array([complex(x1, y1)])
+    if exact:
+        assert_equal(f(z1), x)
+    else:
+        assert_almost_equal(f(z1), x)
+
+def check_complex_value(f, x1, y1, x2, y2, exact=True):
+    z1 = np.array([complex(x1, y1)])
+    z2 = np.complex(x2, y2)
+    with np.errstate(invalid='ignore'):
+        if exact:
+            assert_equal(f(z1), z2)
+        else:
+            assert_almost_equal(f(z1), z2)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
new file mode 100644
index 0000000000..7a421a5fbc
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
@@ -0,0 +1,360 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.compat import asbytes, unicode, sixu
+from numpy.testing import TestCase, run_module_suite, assert_equal
+
+# Guess the UCS length for this python interpreter
+if sys.version_info[:2] >= (3, 3):
+    # Python 3.3 uses a flexible string representation
+    ucs4 = False
+
+    def buffer_length(arr):
+        if isinstance(arr, unicode):
+            arr = str(arr)
+            return (sys.getsizeof(arr+"a") - sys.getsizeof(arr)) * len(arr)
+        v = memoryview(arr)
+        if v.shape is None:
+            return len(v) * v.itemsize
+        else:
+            return np.prod(v.shape) * v.itemsize
+elif sys.version_info[0] >= 3:
+    import array as _array
+
+    ucs4 = (_array.array('u').itemsize == 4)
+
+    def buffer_length(arr):
+        if isinstance(arr, unicode):
+            return _array.array('u').itemsize * len(arr)
+        v = memoryview(arr)
+        if v.shape is None:
+            return len(v) * v.itemsize
+        else:
+            return np.prod(v.shape) * v.itemsize
+else:
+    if len(buffer(sixu('u'))) == 4:
+        ucs4 = True
+    else:
+        ucs4 = False
+
+    def buffer_length(arr):
+        if isinstance(arr, np.ndarray):
+            return len(arr.data)
+        return len(buffer(arr))
+
+# In both cases below we need to make sure that the byte swapped value (as
+# UCS4) is still a valid unicode:
+# Value that can be represented in UCS2 interpreters
+ucs2_value = sixu('\u0900')
+# Value that cannot be represented in UCS2 interpreters (but can in UCS4)
+ucs4_value = sixu('\U00100900')
+
+
+############################################################
+#    Creation tests
+############################################################
+
+class create_zeros(object):
+    """Check the creation of zero-valued arrays"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == sixu(''))
+        # Encode to ascii and double check
+        self.assertTrue(ua_scalar.encode('ascii') == asbytes(''))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 0)
+        else:
+            self.assertTrue(buffer_length(ua_scalar) == 0)
+
+    def test_zeros0D(self):
+        # Check creation of 0-dimensional objects
+        ua = np.zeros((), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_zerosSD(self):
+        # Check creation of single-dimensional objects
+        ua = np.zeros((2,), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_zerosMD(self):
+        # Check creation of multi-dimensional objects
+        ua = np.zeros((2, 3, 4), dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_create_zeros_1(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 1)"""
+    ulen = 1
+
+
+class test_create_zeros_2(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 2)"""
+    ulen = 2
+
+
+class test_create_zeros_1009(create_zeros, TestCase):
+    """Check the creation of zero-valued arrays (size 1009)"""
+    ulen = 1009
+
+
+class create_values(object):
+    """Check the creation of unicode arrays with values"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == self.ucs_value*self.ulen)
+        # Encode to UTF-8 and double check
+        self.assertTrue(ua_scalar.encode('utf-8') ==
+                        (self.ucs_value*self.ulen).encode('utf-8'))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 4*self.ulen)
+        else:
+            if self.ucs_value == ucs4_value:
+                # In UCS2, the \U0010FFFF will be represented using a
+                # surrogate *pair*
+                self.assertTrue(buffer_length(ua_scalar) == 2*2*self.ulen)
+            else:
+                # In UCS2, the \uFFFF will be represented using a
+                # regular 2-byte word
+                self.assertTrue(buffer_length(ua_scalar) == 2*self.ulen)
+
+    def test_values0D(self):
+        # Check creation of 0-dimensional objects with values
+        ua = np.array(self.ucs_value*self.ulen, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_valuesSD(self):
+        # Check creation of single-dimensional objects with values
+        ua = np.array([self.ucs_value*self.ulen]*2, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_valuesMD(self):
+        # Check creation of multi-dimensional objects with values
+        ua = np.array([[[self.ucs_value*self.ulen]*2]*3]*4, dtype='U%s' % self.ulen)
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_create_values_1_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_create_values_1_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_create_values_2_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_create_values_2_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_create_values_1009_ucs2(create_values, TestCase):
+    """Check the creation of valued arrays (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_create_values_1009_ucs4(create_values, TestCase):
+    """Check the creation of valued arrays (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+############################################################
+#    Assignment tests
+############################################################
+
+class assign_values(object):
+    """Check the assignment of unicode arrays with values"""
+
+    def content_check(self, ua, ua_scalar, nbytes):
+
+        # Check the length of the unicode base type
+        self.assertTrue(int(ua.dtype.str[2:]) == self.ulen)
+        # Check the length of the data buffer
+        self.assertTrue(buffer_length(ua) == nbytes)
+        # Small check that data in array element is ok
+        self.assertTrue(ua_scalar == self.ucs_value*self.ulen)
+        # Encode to UTF-8 and double check
+        self.assertTrue(ua_scalar.encode('utf-8') ==
+                        (self.ucs_value*self.ulen).encode('utf-8'))
+        # Check buffer lengths for scalars
+        if ucs4:
+            self.assertTrue(buffer_length(ua_scalar) == 4*self.ulen)
+        else:
+            if self.ucs_value == ucs4_value:
+                # In UCS2, the \U0010FFFF will be represented using a
+                # surrogate *pair*
+                self.assertTrue(buffer_length(ua_scalar) == 2*2*self.ulen)
+            else:
+                # In UCS2, the \uFFFF will be represented using a
+                # regular 2-byte word
+                self.assertTrue(buffer_length(ua_scalar) == 2*self.ulen)
+
+    def test_values0D(self):
+        # Check assignment of 0-dimensional objects with values
+        ua = np.zeros((), dtype='U%s' % self.ulen)
+        ua[()] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[()], 4*self.ulen)
+
+    def test_valuesSD(self):
+        # Check assignment of single-dimensional objects with values
+        ua = np.zeros((2,), dtype='U%s' % self.ulen)
+        ua[0] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[0], 4*self.ulen*2)
+        ua[1] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[1], 4*self.ulen*2)
+
+    def test_valuesMD(self):
+        # Check assignment of multi-dimensional objects with values
+        ua = np.zeros((2, 3, 4), dtype='U%s' % self.ulen)
+        ua[0, 0, 0] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[0, 0, 0], 4*self.ulen*2*3*4)
+        ua[-1, -1, -1] = self.ucs_value*self.ulen
+        self.content_check(ua, ua[-1, -1, -1], 4*self.ulen*2*3*4)
+
+
+class test_assign_values_1_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_assign_values_1_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_assign_values_2_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_assign_values_2_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_assign_values_1009_ucs2(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_assign_values_1009_ucs4(assign_values, TestCase):
+    """Check the assignment of valued arrays (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+############################################################
+#    Byteorder tests
+############################################################
+
+class byteorder_values:
+    """Check the byteorder of unicode arrays in round-trip conversions"""
+
+    def test_values0D(self):
+        # Check byteorder of 0-dimensional objects
+        ua = np.array(self.ucs_value*self.ulen, dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        # This changes the interpretation of the data region (but not the
+        #  actual data), therefore the returned scalars are not
+        #  the same (they are byte-swapped versions of each other).
+        self.assertTrue(ua[()] != ua2[()])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+    def test_valuesSD(self):
+        # Check byteorder of single-dimensional objects
+        ua = np.array([self.ucs_value*self.ulen]*2, dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        self.assertTrue(ua[0] != ua2[0])
+        self.assertTrue(ua[-1] != ua2[-1])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+    def test_valuesMD(self):
+        # Check byteorder of multi-dimensional objects
+        ua = np.array([[[self.ucs_value*self.ulen]*2]*3]*4,
+                   dtype='U%s' % self.ulen)
+        ua2 = ua.newbyteorder()
+        self.assertTrue(ua[0, 0, 0] != ua2[0, 0, 0])
+        self.assertTrue(ua[-1, -1, -1] != ua2[-1, -1, -1])
+        ua3 = ua2.newbyteorder()
+        # Arrays must be equal after the round-trip
+        assert_equal(ua, ua3)
+
+
+class test_byteorder_1_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1, UCS2 values)"""
+    ulen = 1
+    ucs_value = ucs2_value
+
+
+class test_byteorder_1_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1, UCS4 values)"""
+    ulen = 1
+    ucs_value = ucs4_value
+
+
+class test_byteorder_2_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 2, UCS2 values)"""
+    ulen = 2
+    ucs_value = ucs2_value
+
+
+class test_byteorder_2_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 2, UCS4 values)"""
+    ulen = 2
+    ucs_value = ucs4_value
+
+
+class test_byteorder_1009_ucs2(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1009, UCS2 values)"""
+    ulen = 1009
+    ucs_value = ucs2_value
+
+
+class test_byteorder_1009_ucs4(byteorder_values, TestCase):
+    """Check the byteorder in unicode (size 1009, UCS4 values)"""
+    ulen = 1009
+    ucs_value = ucs4_value
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..f6fd730c0363803f3887491e0f08552ba4a2e17d
GIT binary patch
literal 787968
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
B$D#lL

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath_tests.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..fe652645dd65b59a45a03e589bf8b689ec18969d
GIT binary patch
literal 26112
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ctypeslib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ctypeslib.py
new file mode 100644
index 0000000000..fa1dcad6f1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ctypeslib.py
@@ -0,0 +1,453 @@
+"""
+============================
+``ctypes`` Utility Functions
+============================
+
+See Also
+---------
+load_library : Load a C library.
+ndpointer : Array restype/argtype with verification.
+as_ctypes : Create a ctypes array from an ndarray.
+as_array : Create an ndarray from a ctypes array.
+
+References
+----------
+.. [1] "SciPy Cookbook: ctypes", http://www.scipy.org/Cookbook/Ctypes
+
+Examples
+--------
+Load the C library:
+
+>>> _lib = np.ctypeslib.load_library('libmystuff', '.')     #doctest: +SKIP
+
+Our result type, an ndarray that must be of type double, be 1-dimensional
+and is C-contiguous in memory:
+
+>>> array_1d_double = np.ctypeslib.ndpointer(
+...                          dtype=np.double,
+...                          ndim=1, flags='CONTIGUOUS')    #doctest: +SKIP
+
+Our C-function typically takes an array and updates its values
+in-place.  For example::
+
+    void foo_func(double* x, int length)
+    {
+        int i;
+        for (i = 0; i < length; i++) {
+            x[i] = i*i;
+        }
+    }
+
+We wrap it using:
+
+>>> _lib.foo_func.restype = None                      #doctest: +SKIP
+>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP
+
+Then, we're ready to call ``foo_func``:
+
+>>> out = np.empty(15, dtype=np.double)
+>>> _lib.foo_func(out, len(out))                #doctest: +SKIP
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['load_library', 'ndpointer', 'test', 'ctypes_load_library',
+           'c_intp', 'as_ctypes', 'as_array']
+
+import sys, os
+from numpy import integer, ndarray, dtype as _dtype, deprecate, array
+from numpy.core.multiarray import _flagdict, flagsobj
+
+try:
+    import ctypes
+except ImportError:
+    ctypes = None
+
+if ctypes is None:
+    def _dummy(*args, **kwds):
+        """
+        Dummy object that raises an ImportError if ctypes is not available.
+
+        Raises
+        ------
+        ImportError
+            If ctypes is not available.
+
+        """
+        raise ImportError("ctypes is not available.")
+    ctypes_load_library = _dummy
+    load_library = _dummy
+    as_ctypes = _dummy
+    as_array = _dummy
+    from numpy import intp as c_intp
+    _ndptr_base = object
+else:
+    import numpy.core._internal as nic
+    c_intp = nic._getintp_ctype()
+    del nic
+    _ndptr_base = ctypes.c_void_p
+
+    # Adapted from Albert Strasheim
+    def load_library(libname, loader_path):
+        """
+        It is possible to load a library using 
+        >>> lib = ctypes.cdll[<full_path_name>]
+
+        But there are cross-platform considerations, such as library file extensions,
+        plus the fact Windows will just load the first library it finds with that name.  
+        Numpy supplies the load_library function as a convenience.
+
+        Parameters
+        ----------
+        libname : str
+            Name of the library, which can have 'lib' as a prefix,
+            but without an extension.
+        loader_path : str
+            Where the library can be found.
+
+        Returns
+        -------
+        ctypes.cdll[libpath] : library object
+           A ctypes library object 
+
+        Raises
+        ------
+        OSError
+            If there is no library with the expected extension, or the 
+            library is defective and cannot be loaded.
+        """
+        if ctypes.__version__ < '1.0.1':
+            import warnings
+            warnings.warn("All features of ctypes interface may not work " \
+                          "with ctypes < 1.0.1")
+
+        ext = os.path.splitext(libname)[1]
+        if not ext:
+            # Try to load library with platform-specific name, otherwise
+            # default to libname.[so|pyd].  Sometimes, these files are built
+            # erroneously on non-linux platforms.
+            from numpy.distutils.misc_util import get_shared_lib_extension
+            so_ext = get_shared_lib_extension()
+            libname_ext = [libname + so_ext]
+            # mac, windows and linux >= py3.2 shared library and loadable
+            # module have different extensions so try both
+            so_ext2 = get_shared_lib_extension(is_python_ext=True)
+            if not so_ext2 == so_ext:
+                libname_ext.insert(0, libname + so_ext2)
+        else:
+            libname_ext = [libname]
+
+        loader_path = os.path.abspath(loader_path)
+        if not os.path.isdir(loader_path):
+            libdir = os.path.dirname(loader_path)
+        else:
+            libdir = loader_path
+
+        for ln in libname_ext:
+            libpath = os.path.join(libdir, ln)
+            if os.path.exists(libpath):
+                try:
+                    return ctypes.cdll[libpath]
+                except OSError:
+                    ## defective lib file
+                    raise
+        ## if no successful return in the libname_ext loop:
+        raise OSError("no file with expected extension")
+
+    ctypes_load_library = deprecate(load_library, 'ctypes_load_library',
+                                    'load_library')
+
+def _num_fromflags(flaglist):
+    num = 0
+    for val in flaglist:
+        num += _flagdict[val]
+    return num
+
+_flagnames = ['C_CONTIGUOUS', 'F_CONTIGUOUS', 'ALIGNED', 'WRITEABLE',
+              'OWNDATA', 'UPDATEIFCOPY']
+def _flags_fromnum(num):
+    res = []
+    for key in _flagnames:
+        value = _flagdict[key]
+        if (num & value):
+            res.append(key)
+    return res
+
+
+class _ndptr(_ndptr_base):
+
+    def _check_retval_(self):
+        """This method is called when this class is used as the .restype
+        asttribute for a shared-library function.   It constructs a numpy
+        array from a void pointer."""
+        return array(self)
+
+    @property
+    def __array_interface__(self):
+        return {'descr': self._dtype_.descr,
+                '__ref': self,
+                'strides': None,
+                'shape': self._shape_,
+                'version': 3,
+                'typestr': self._dtype_.descr[0][1],
+                'data': (self.value, False),
+                }
+
+    @classmethod
+    def from_param(cls, obj):
+        if not isinstance(obj, ndarray):
+            raise TypeError("argument must be an ndarray")
+        if cls._dtype_ is not None \
+               and obj.dtype != cls._dtype_:
+            raise TypeError("array must have data type %s" % cls._dtype_)
+        if cls._ndim_ is not None \
+               and obj.ndim != cls._ndim_:
+            raise TypeError("array must have %d dimension(s)" % cls._ndim_)
+        if cls._shape_ is not None \
+               and obj.shape != cls._shape_:
+            raise TypeError("array must have shape %s" % str(cls._shape_))
+        if cls._flags_ is not None \
+               and ((obj.flags.num & cls._flags_) != cls._flags_):
+            raise TypeError("array must have flags %s" %
+                    _flags_fromnum(cls._flags_))
+        return obj.ctypes
+
+
+# Factory for an array-checking class with from_param defined for
+#  use with ctypes argtypes mechanism
+_pointer_type_cache = {}
+def ndpointer(dtype=None, ndim=None, shape=None, flags=None):
+    """
+    Array-checking restype/argtypes.
+
+    An ndpointer instance is used to describe an ndarray in restypes
+    and argtypes specifications.  This approach is more flexible than
+    using, for example, ``POINTER(c_double)``, since several restrictions
+    can be specified, which are verified upon calling the ctypes function.
+    These include data type, number of dimensions, shape and flags.  If a
+    given array does not satisfy the specified restrictions,
+    a ``TypeError`` is raised.
+
+    Parameters
+    ----------
+    dtype : data-type, optional
+        Array data-type.
+    ndim : int, optional
+        Number of array dimensions.
+    shape : tuple of ints, optional
+        Array shape.
+    flags : str or tuple of str
+        Array flags; may be one or more of:
+
+          - C_CONTIGUOUS / C / CONTIGUOUS
+          - F_CONTIGUOUS / F / FORTRAN
+          - OWNDATA / O
+          - WRITEABLE / W
+          - ALIGNED / A
+          - UPDATEIFCOPY / U
+
+    Returns
+    -------
+    klass : ndpointer type object
+        A type object, which is an ``_ndtpr`` instance containing
+        dtype, ndim, shape and flags information.
+
+    Raises
+    ------
+    TypeError
+        If a given array does not satisfy the specified restrictions.
+
+    Examples
+    --------
+    >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,
+    ...                                                  ndim=1,
+    ...                                                  flags='C_CONTIGUOUS')]
+    ... #doctest: +SKIP
+    >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64))
+    ... #doctest: +SKIP
+
+    """
+
+    if dtype is not None:
+        dtype = _dtype(dtype)
+    num = None
+    if flags is not None:
+        if isinstance(flags, str):
+            flags = flags.split(',')
+        elif isinstance(flags, (int, integer)):
+            num = flags
+            flags = _flags_fromnum(num)
+        elif isinstance(flags, flagsobj):
+            num = flags.num
+            flags = _flags_fromnum(num)
+        if num is None:
+            try:
+                flags = [x.strip().upper() for x in flags]
+            except:
+                raise TypeError("invalid flags specification")
+            num = _num_fromflags(flags)
+    try:
+        return _pointer_type_cache[(dtype, ndim, shape, num)]
+    except KeyError:
+        pass
+    if dtype is None:
+        name = 'any'
+    elif dtype.names:
+        name = str(id(dtype))
+    else:
+        name = dtype.str
+    if ndim is not None:
+        name += "_%dd" % ndim
+    if shape is not None:
+        try:
+            strshape = [str(x) for x in shape]
+        except TypeError:
+            strshape = [str(shape)]
+            shape = (shape,)
+        shape = tuple(shape)
+        name += "_"+"x".join(strshape)
+    if flags is not None:
+        name += "_"+"_".join(flags)
+    else:
+        flags = []
+    klass = type("ndpointer_%s"%name, (_ndptr,),
+                 {"_dtype_": dtype,
+                  "_shape_" : shape,
+                  "_ndim_" : ndim,
+                  "_flags_" : num})
+    _pointer_type_cache[dtype] = klass
+    return klass
+
+if ctypes is not None:
+    ct = ctypes
+    ################################################################
+    # simple types
+
+    # maps the numpy typecodes like '<f8' to simple ctypes types like
+    # c_double. Filled in by prep_simple.
+    _typecodes = {}
+
+    def prep_simple(simple_type, dtype):
+        """Given a ctypes simple type, construct and attach an
+        __array_interface__ property to it if it does not yet have one.
+        """
+        try: simple_type.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        typestr = _dtype(dtype).str
+        _typecodes[typestr] = simple_type
+
+        def __array_interface__(self):
+            return {'descr': [('', typestr)],
+                    '__ref': self,
+                    'strides': None,
+                    'shape': (),
+                    'version': 3,
+                    'typestr': typestr,
+                    'data': (ct.addressof(self), False),
+                    }
+
+        simple_type.__array_interface__ = property(__array_interface__)
+
+    simple_types = [
+        ((ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong), "i"),
+        ((ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong), "u"),
+        ((ct.c_float, ct.c_double), "f"),
+    ]
+
+    # Prep that numerical ctypes types:
+    for types, code in simple_types:
+        for tp in types:
+            prep_simple(tp, "%c%d" % (code, ct.sizeof(tp)))
+
+    ################################################################
+    # array types
+
+    _ARRAY_TYPE = type(ct.c_int * 1)
+
+    def prep_array(array_type):
+        """Given a ctypes array type, construct and attach an
+        __array_interface__ property to it if it does not yet have one.
+        """
+        try: array_type.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        shape = []
+        ob = array_type
+        while type(ob) is _ARRAY_TYPE:
+            shape.append(ob._length_)
+            ob = ob._type_
+        shape = tuple(shape)
+        ai = ob().__array_interface__
+        descr = ai['descr']
+        typestr = ai['typestr']
+
+        def __array_interface__(self):
+            return {'descr': descr,
+                    '__ref': self,
+                    'strides': None,
+                    'shape': shape,
+                    'version': 3,
+                    'typestr': typestr,
+                    'data': (ct.addressof(self), False),
+                    }
+
+        array_type.__array_interface__ = property(__array_interface__)
+
+    def prep_pointer(pointer_obj, shape):
+        """Given a ctypes pointer object, construct and
+        attach an __array_interface__ property to it if it does not
+        yet have one.
+        """
+        try: pointer_obj.__array_interface__
+        except AttributeError: pass
+        else: return
+
+        contents = pointer_obj.contents
+        dtype = _dtype(type(contents))
+
+        inter = {'version': 3,
+                 'typestr': dtype.str,
+                 'data': (ct.addressof(contents), False),
+                 'shape': shape}
+
+        pointer_obj.__array_interface__ = inter
+
+    ################################################################
+    # public functions
+
+    def as_array(obj, shape=None):
+        """Create a numpy array from a ctypes array or a ctypes POINTER.
+        The numpy array shares the memory with the ctypes object.
+
+        The size parameter must be given if converting from a ctypes POINTER.
+        The size parameter is ignored if converting from a ctypes array
+        """
+        tp = type(obj)
+        try: tp.__array_interface__
+        except AttributeError:
+            if hasattr(obj, 'contents'):
+                prep_pointer(obj, shape)
+            else:
+                prep_array(tp)
+        return array(obj, copy=False)
+
+    def as_ctypes(obj):
+        """Create and return a ctypes object from a numpy array.  Actually
+        anything that exposes the __array_interface__ is accepted."""
+        ai = obj.__array_interface__
+        if ai["strides"]:
+            raise TypeError("strided arrays not supported")
+        if ai["version"] != 3:
+            raise TypeError("only __array_interface__ version 3 supported")
+        addr, readonly = ai["data"]
+        if readonly:
+            raise TypeError("readonly arrays unsupported")
+        tp = _typecodes[ai["typestr"]]
+        for dim in ai["shape"][::-1]:
+            tp = tp * dim
+        result = tp.from_address(addr)
+        result.__keep = ai
+        return result
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.py
new file mode 100644
index 0000000000..2c2719980e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.py
@@ -0,0 +1,26 @@
+# This file is generated by C:/repo/mingw-w64-python-numpy/src/numpy-py2-x86_64/setup.py
+# It contains system_info results at the time of building this package.
+__all__ = ["get_info","show"]
+
+lapack_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+openblas_lapack_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_mkl_info={}
+openblas_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_opt_info={'libraries': ['openblas', 'openblas'], 'library_dirs': ['C:/building/msys64/mingw64/lib'], 'language': 'c', 'define_macros': [('HAVE_CBLAS', None)]}
+
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    
\ No newline at end of file
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.py
new file mode 100644
index 0000000000..602a3d1170
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from .__version__ import version as __version__
+# Must import local ccompiler ASAP in order to get
+# customized CCompiler.spawn effective.
+from . import ccompiler
+from . import unixccompiler
+
+from .info import __doc__
+from .npy_pkg_config import *
+
+# If numpy is installed, add distutils.test()
+try:
+    from . import __config__
+    # Normally numpy is installed if the above import works, but an interrupted
+    # in-place build could also have left a __config__.py.  In that case the
+    # next import may still fail, so keep it inside the try block.
+    from numpy.testing.nosetester import _numpy_tester
+    test = _numpy_tester().test
+except ImportError:
+    pass
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.py
new file mode 100644
index 0000000000..969decbba2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.py
@@ -0,0 +1,6 @@
+from __future__ import division, absolute_import, print_function
+
+major = 0
+minor = 4
+micro = 0
+version = '%(major)d.%(minor)d.%(micro)d' % (locals())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
new file mode 100644
index 0000000000..2f2d63b599
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
@@ -0,0 +1,689 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import types
+from copy import copy
+from distutils import ccompiler
+from distutils.ccompiler import *
+from distutils.errors import DistutilsExecError, DistutilsModuleError, \
+                             DistutilsPlatformError
+from distutils.sysconfig import customize_compiler
+from distutils.version import LooseVersion
+
+from numpy.distutils import log
+from numpy.distutils.compat import get_exception
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, \
+                                      quote_args, get_num_build_jobs
+
+
+def replace_method(klass, method_name, func):
+    if sys.version_info[0] < 3:
+        m = types.MethodType(func, None, klass)
+    else:
+        # Py3k does not have unbound method anymore, MethodType does not work
+        m = lambda self, *args, **kw: func(self, *args, **kw)
+    setattr(klass, method_name, m)
+
+# Using customized CCompiler.spawn.
+def CCompiler_spawn(self, cmd, display=None):
+    """
+    Execute a command in a sub-process.
+
+    Parameters
+    ----------
+    cmd : str
+        The command to execute.
+    display : str or sequence of str, optional
+        The text to add to the log file kept by `numpy.distutils`.
+        If not given, `display` is equal to `cmd`.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    DistutilsExecError
+        If the command failed, i.e. the exit status was not 0.
+
+    """
+    if display is None:
+        display = cmd
+        if is_sequence(display):
+            display = ' '.join(list(display))
+    log.info(display)
+    s, o = exec_command(cmd)
+    if s:
+        if is_sequence(cmd):
+            cmd = ' '.join(list(cmd))
+        try:
+            print(o)
+        except UnicodeError:
+            # When installing through pip, `o` can contain non-ascii chars
+            pass
+        if re.search('Too many open files', o):
+            msg = '\nTry rerunning setup command until build succeeds.'
+        else:
+            msg = ''
+        raise DistutilsExecError('Command "%s" failed with exit status %d%s' % (cmd, s, msg))
+
+replace_method(CCompiler, 'spawn', CCompiler_spawn)
+
+def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
+    """
+    Return the name of the object files for the given source files.
+
+    Parameters
+    ----------
+    source_filenames : list of str
+        The list of paths to source files. Paths can be either relative or
+        absolute, this is handled transparently.
+    strip_dir : bool, optional
+        Whether to strip the directory from the returned paths. If True,
+        the file name prepended by `output_dir` is returned. Default is False.
+    output_dir : str, optional
+        If given, this path is prepended to the returned paths to the
+        object files.
+
+    Returns
+    -------
+    obj_names : list of str
+        The list of paths to the object files corresponding to the source
+        files in `source_filenames`.
+
+    """
+    if output_dir is None:
+        output_dir = ''
+    obj_names = []
+    for src_name in source_filenames:
+        base, ext = os.path.splitext(os.path.normpath(src_name))
+        base = os.path.splitdrive(base)[1] # Chop off the drive
+        base = base[os.path.isabs(base):]  # If abs, chop off leading /
+        if base.startswith('..'):
+            # Resolve starting relative path components, middle ones
+            # (if any) have been handled by os.path.normpath above.
+            i = base.rfind('..')+2
+            d = base[:i]
+            d = os.path.basename(os.path.abspath(d))
+            base = d + base[i:]
+        if ext not in self.src_extensions:
+            raise UnknownFileError("unknown file type '%s' (from '%s')" % (ext, src_name))
+        if strip_dir:
+            base = os.path.basename(base)
+        obj_name = os.path.join(output_dir, base + self.obj_extension)
+        obj_names.append(obj_name)
+    return obj_names
+
+replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames)
+
+def CCompiler_compile(self, sources, output_dir=None, macros=None,
+                      include_dirs=None, debug=0, extra_preargs=None,
+                      extra_postargs=None, depends=None):
+    """
+    Compile one or more source files.
+
+    Please refer to the Python distutils API reference for more details.
+
+    Parameters
+    ----------
+    sources : list of str
+        A list of filenames
+    output_dir : str, optional
+        Path to the output directory.
+    macros : list of tuples
+        A list of macro definitions.
+    include_dirs : list of str, optional
+        The directories to add to the default include file search path for
+        this compilation only.
+    debug : bool, optional
+        Whether or not to output debug symbols in or alongside the object
+        file(s).
+    extra_preargs, extra_postargs : ?
+        Extra pre- and post-arguments.
+    depends : list of str, optional
+        A list of file names that all targets depend on.
+
+    Returns
+    -------
+    objects : list of str
+        A list of object file names, one per source file `sources`.
+
+    Raises
+    ------
+    CompileError
+        If compilation fails.
+
+    """
+    # This method is effective only with Python >=2.3 distutils.
+    # Any changes here should be applied also to fcompiler.compile
+    # method to support pre Python 2.3 distutils.
+    if not sources:
+        return []
+    # FIXME:RELATIVE_IMPORT
+    if sys.version_info[0] < 3:
+        from .fcompiler import FCompiler, is_f_file, has_f90_header
+    else:
+        from numpy.distutils.fcompiler import (FCompiler, is_f_file,
+                                               has_f90_header)
+    if isinstance(self, FCompiler):
+        display = []
+        for fc in ['f77', 'f90', 'fix']:
+            fcomp = getattr(self, 'compiler_'+fc)
+            if fcomp is None:
+                continue
+            display.append("Fortran %s compiler: %s" % (fc, ' '.join(fcomp)))
+        display = '\n'.join(display)
+    else:
+        ccomp = self.compiler_so
+        display = "C compiler: %s\n" % (' '.join(ccomp),)
+    log.info(display)
+    macros, objects, extra_postargs, pp_opts, build = \
+            self._setup_compile(output_dir, macros, include_dirs, sources,
+                                depends, extra_postargs)
+    cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
+    display = "compile options: '%s'" % (' '.join(cc_args))
+    if extra_postargs:
+        display += "\nextra options: '%s'" % (' '.join(extra_postargs))
+    log.info(display)
+
+    def single_compile(args):
+        obj, (src, ext) = args
+        self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
+
+    if isinstance(self, FCompiler):
+        objects_to_build = list(build.keys())
+        f77_objects, other_objects = [], []
+        for obj in objects:
+            if obj in objects_to_build:
+                src, ext = build[obj]
+                if self.compiler_type=='absoft':
+                    obj = cyg2win32(obj)
+                    src = cyg2win32(src)
+                if is_f_file(src) and not has_f90_header(src):
+                    f77_objects.append((obj, (src, ext)))
+                else:
+                    other_objects.append((obj, (src, ext)))
+
+        # f77 objects can be built in parallel
+        build_items = f77_objects
+        # build f90 modules serial, module files are generated during
+        # compilation and may be used by files later in the list so the
+        # ordering is important
+        for o in other_objects:
+            single_compile(o)
+    else:
+        build_items = build.items()
+
+    jobs = get_num_build_jobs()
+    if len(build) > 1 and jobs > 1:
+        # build parallel
+        import multiprocessing.pool
+        pool = multiprocessing.pool.ThreadPool(jobs)
+        pool.map(single_compile, build_items)
+        pool.close()
+    else:
+        # build serial
+        for o in build_items:
+            single_compile(o)
+
+    # Return *all* object filenames, not just the ones we just built.
+    return objects
+
+replace_method(CCompiler, 'compile', CCompiler_compile)
+
+def CCompiler_customize_cmd(self, cmd, ignore=()):
+    """
+    Customize compiler using distutils command.
+
+    Parameters
+    ----------
+    cmd : class instance
+        An instance inheriting from `distutils.cmd.Command`.
+    ignore : sequence of str, optional
+        List of `CCompiler` commands (without ``'set_'``) that should not be
+        altered. Strings that are checked for are:
+        ``('include_dirs', 'define', 'undef', 'libraries', 'library_dirs',
+        'rpath', 'link_objects')``.
+
+    Returns
+    -------
+    None
+
+    """
+    log.info('customize %s using %s' % (self.__class__.__name__,
+                                        cmd.__class__.__name__))
+    def allow(attr):
+        return getattr(cmd, attr, None) is not None and attr not in ignore
+
+    if allow('include_dirs'):
+        self.set_include_dirs(cmd.include_dirs)
+    if allow('define'):
+        for (name, value) in cmd.define:
+            self.define_macro(name, value)
+    if allow('undef'):
+        for macro in cmd.undef:
+            self.undefine_macro(macro)
+    if allow('libraries'):
+        self.set_libraries(self.libraries + cmd.libraries)
+    if allow('library_dirs'):
+        self.set_library_dirs(self.library_dirs + cmd.library_dirs)
+    if allow('rpath'):
+        self.set_runtime_library_dirs(cmd.rpath)
+    if allow('link_objects'):
+        self.set_link_objects(cmd.link_objects)
+
+replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd)
+
+def _compiler_to_string(compiler):
+    props = []
+    mx = 0
+    keys = list(compiler.executables.keys())
+    for key in ['version', 'libraries', 'library_dirs',
+                'object_switch', 'compile_switch',
+                'include_dirs', 'define', 'undef', 'rpath', 'link_objects']:
+        if key not in keys:
+            keys.append(key)
+    for key in keys:
+        if hasattr(compiler, key):
+            v = getattr(compiler, key)
+            mx = max(mx, len(key))
+            props.append((key, repr(v)))
+    lines = []
+    format = '%-' + repr(mx+1) + 's = %s'
+    for prop in props:
+        lines.append(format % prop)
+    return '\n'.join(lines)
+
+def CCompiler_show_customization(self):
+    """
+    Print the compiler customizations to stdout.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    None
+
+    Notes
+    -----
+    Printing is only done if the distutils log threshold is < 2.
+
+    """
+    if 0:
+        for attrname in ['include_dirs', 'define', 'undef',
+                         'libraries', 'library_dirs',
+                         'rpath', 'link_objects']:
+            attr = getattr(self, attrname, None)
+            if not attr:
+                continue
+            log.info("compiler '%s' is set to %s" % (attrname, attr))
+    try:
+        self.get_version()
+    except:
+        pass
+    if log._global_log.threshold<2:
+        print('*'*80)
+        print(self.__class__)
+        print(_compiler_to_string(self))
+        print('*'*80)
+
+replace_method(CCompiler, 'show_customization', CCompiler_show_customization)
+
+def CCompiler_customize(self, dist, need_cxx=0):
+    """
+    Do any platform-specific customization of a compiler instance.
+
+    This method calls `distutils.sysconfig.customize_compiler` for
+    platform-specific customization, as well as optionally remove a flag
+    to suppress spurious warnings in case C++ code is being compiled.
+
+    Parameters
+    ----------
+    dist : object
+        This parameter is not used for anything.
+    need_cxx : bool, optional
+        Whether or not C++ has to be compiled. If so (True), the
+        ``"-Wstrict-prototypes"`` option is removed to prevent spurious
+        warnings. Default is False.
+
+    Returns
+    -------
+    None
+
+    Notes
+    -----
+    All the default options used by distutils can be extracted with::
+
+      from distutils import sysconfig
+      sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS',
+                                'CCSHARED', 'LDSHARED', 'SO')
+
+    """
+    # See FCompiler.customize for suggested usage.
+    log.info('customize %s' % (self.__class__.__name__))
+    customize_compiler(self)
+    if need_cxx:
+        # In general, distutils uses -Wstrict-prototypes, but this option is
+        # not valid for C++ code, only for C.  Remove it if it's there to
+        # avoid a spurious warning on every compilation.
+        try:
+            self.compiler_so.remove('-Wstrict-prototypes')
+        except (AttributeError, ValueError):
+            pass
+
+        if hasattr(self, 'compiler') and 'cc' in self.compiler[0]:
+            if not self.compiler_cxx:
+                if self.compiler[0].startswith('gcc'):
+                    a, b = 'gcc', 'g++'
+                else:
+                    a, b = 'cc', 'c++'
+                self.compiler_cxx = [self.compiler[0].replace(a, b)]\
+                                    + self.compiler[1:]
+        else:
+            if hasattr(self, 'compiler'):
+                log.warn("#### %s #######" % (self.compiler,))
+            if not hasattr(self, 'compiler_cxx'):
+                log.warn('Missing compiler_cxx fix for ' + self.__class__.__name__)
+    return
+
+replace_method(CCompiler, 'customize', CCompiler_customize)
+
+def simple_version_match(pat=r'[-.\d]+', ignore='', start=''):
+    """
+    Simple matching of version numbers, for use in CCompiler and FCompiler.
+
+    Parameters
+    ----------
+    pat : str, optional
+        A regular expression matching version numbers.
+        Default is ``r'[-.\\d]+'``.
+    ignore : str, optional
+        A regular expression matching patterns to skip.
+        Default is ``''``, in which case nothing is skipped.
+    start : str, optional
+        A regular expression matching the start of where to start looking
+        for version numbers.
+        Default is ``''``, in which case searching is started at the
+        beginning of the version string given to `matcher`.
+
+    Returns
+    -------
+    matcher : callable
+        A function that is appropriate to use as the ``.version_match``
+        attribute of a `CCompiler` class. `matcher` takes a single parameter,
+        a version string.
+
+    """
+    def matcher(self, version_string):
+        # version string may appear in the second line, so getting rid
+        # of new lines:
+        version_string = version_string.replace('\n', ' ')
+        pos = 0
+        if start:
+            m = re.match(start, version_string)
+            if not m:
+                return None
+            pos = m.end()
+        while True:
+            m = re.search(pat, version_string[pos:])
+            if not m:
+                return None
+            if ignore and re.match(ignore, m.group(0)):
+                pos = m.end()
+                continue
+            break
+        return m.group(0)
+    return matcher
+
+def CCompiler_get_version(self, force=False, ok_status=[0]):
+    """
+    Return compiler version, or None if compiler is not available.
+
+    Parameters
+    ----------
+    force : bool, optional
+        If True, force a new determination of the version, even if the
+        compiler already has a version attribute. Default is False.
+    ok_status : list of int, optional
+        The list of status values returned by the version look-up process
+        for which a version string is returned. If the status value is not
+        in `ok_status`, None is returned. Default is ``[0]``.
+
+    Returns
+    -------
+    version : str or None
+        Version string, in the format of `distutils.version.LooseVersion`.
+
+    """
+    if not force and hasattr(self, 'version'):
+        return self.version
+    self.find_executables()
+    try:
+        version_cmd = self.version_cmd
+    except AttributeError:
+        return None
+    if not version_cmd or not version_cmd[0]:
+        return None
+    try:
+        matcher = self.version_match
+    except AttributeError:
+        try:
+            pat = self.version_pattern
+        except AttributeError:
+            return None
+        def matcher(version_string):
+            m = re.match(pat, version_string)
+            if not m:
+                return None
+            version = m.group('version')
+            return version
+
+    status, output = exec_command(version_cmd, use_tee=0)
+
+    version = None
+    if status in ok_status:
+        version = matcher(output)
+        if version:
+            version = LooseVersion(version)
+    self.version = version
+    return version
+
+replace_method(CCompiler, 'get_version', CCompiler_get_version)
+
+def CCompiler_cxx_compiler(self):
+    """
+    Return the C++ compiler.
+
+    Parameters
+    ----------
+    None
+
+    Returns
+    -------
+    cxx : class instance
+        The C++ compiler, as a `CCompiler` instance.
+
+    """
+    if self.compiler_type in ('msvc', 'intelw', 'intelemw'):
+        return self
+
+    cxx = copy(self)
+    cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:]
+    if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]:
+        # AIX needs the ld_so_aix script included with Python
+        cxx.linker_so = [cxx.linker_so[0], cxx.compiler_cxx[0]] \
+                        + cxx.linker_so[2:]
+    else:
+        cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:]
+    return cxx
+
+replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler)
+
+compiler_class['intel'] = ('intelccompiler', 'IntelCCompiler',
+                           "Intel C Compiler for 32-bit applications")
+compiler_class['intele'] = ('intelccompiler', 'IntelItaniumCCompiler',
+                            "Intel C Itanium Compiler for Itanium-based applications")
+compiler_class['intelem'] = ('intelccompiler', 'IntelEM64TCCompiler',
+                             "Intel C Compiler for 64-bit applications")
+compiler_class['intelw'] = ('intelccompiler', 'IntelCCompilerW',
+                            "Intel C Compiler for 32-bit applications on Windows")
+compiler_class['intelemw'] = ('intelccompiler', 'IntelEM64TCCompilerW',
+                              "Intel C Compiler for 64-bit applications on Windows")
+compiler_class['pathcc'] = ('pathccompiler', 'PathScaleCCompiler',
+                            "PathScale Compiler for SiCortex-based applications")
+ccompiler._default_compilers += (('linux.*', 'intel'),
+                                 ('linux.*', 'intele'),
+                                 ('linux.*', 'intelem'),
+                                 ('linux.*', 'pathcc'),
+                                 ('nt', 'intelw'),
+                                 ('nt', 'intelemw'))
+
+if sys.platform == 'win32':
+    compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',
+                                 "Mingw32 port of GNU C Compiler for Win32"\
+                                 "(for MSC built Python)")
+    if mingw32():
+        # On windows platforms, we want to default to mingw32 (gcc)
+        # because msvc can't build blitz stuff.
+        log.info('Setting mingw32 as default compiler for nt.')
+        ccompiler._default_compilers = (('nt', 'mingw32'),) \
+                                       + ccompiler._default_compilers
+
+
+_distutils_new_compiler = new_compiler
+def new_compiler (plat=None,
+                  compiler=None,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+    # Try first C compilers from numpy.distutils.
+    if plat is None:
+        plat = os.name
+    try:
+        if compiler is None:
+            compiler = get_default_compiler(plat)
+        (module_name, class_name, long_description) = compiler_class[compiler]
+    except KeyError:
+        msg = "don't know how to compile C/C++ code on platform '%s'" % plat
+        if compiler is not None:
+            msg = msg + " with '%s' compiler" % compiler
+        raise DistutilsPlatformError(msg)
+    module_name = "numpy.distutils." + module_name
+    try:
+        __import__ (module_name)
+    except ImportError:
+        msg = str(get_exception())
+        log.info('%s in numpy.distutils; trying from distutils',
+                 str(msg))
+        module_name = module_name[6:]
+        try:
+            __import__(module_name)
+        except ImportError:
+            msg = str(get_exception())
+            raise DistutilsModuleError("can't compile C/C++ code: unable to load module '%s'" % \
+                  module_name)
+    try:
+        module = sys.modules[module_name]
+        klass = vars(module)[class_name]
+    except KeyError:
+        raise DistutilsModuleError(("can't compile C/C++ code: unable to find class '%s' " +
+               "in module '%s'") % (class_name, module_name))
+    compiler = klass(None, dry_run, force)
+    log.debug('new_compiler returns %s' % (klass))
+    return compiler
+
+ccompiler.new_compiler = new_compiler
+
+_distutils_gen_lib_options = gen_lib_options
+def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
+    library_dirs = quote_args(library_dirs)
+    runtime_library_dirs = quote_args(runtime_library_dirs)
+    r = _distutils_gen_lib_options(compiler, library_dirs,
+                                   runtime_library_dirs, libraries)
+    lib_opts = []
+    for i in r:
+        if is_sequence(i):
+            lib_opts.extend(list(i))
+        else:
+            lib_opts.append(i)
+    return lib_opts
+ccompiler.gen_lib_options = gen_lib_options
+
+# Also fix up the various compiler modules, which do
+# from distutils.ccompiler import gen_lib_options
+# Don't bother with mwerks, as we don't support Classic Mac.
+for _cc in ['msvc9', 'msvc', 'bcpp', 'cygwinc', 'emxc', 'unixc']:
+    _m = sys.modules.get('distutils.' + _cc + 'compiler')
+    if _m is not None:
+        setattr(_m, 'gen_lib_options', gen_lib_options)
+
+_distutils_gen_preprocess_options = gen_preprocess_options
+def gen_preprocess_options (macros, include_dirs):
+    include_dirs = quote_args(include_dirs)
+    return _distutils_gen_preprocess_options(macros, include_dirs)
+ccompiler.gen_preprocess_options = gen_preprocess_options
+
+##Fix distutils.util.split_quoted:
+# NOTE:  I removed this fix in revision 4481 (see ticket #619), but it appears
+# that removing this fix causes f2py problems on Windows XP (see ticket #723).
+# Specifically, on WinXP when gfortran is installed in a directory path, which
+# contains spaces, then f2py is unable to find it.
+import string
+_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
+_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
+_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
+_has_white_re = re.compile(r'\s')
+def split_quoted(s):
+    s = s.strip()
+    words = []
+    pos = 0
+
+    while s:
+        m = _wordchars_re.match(s, pos)
+        end = m.end()
+        if end == len(s):
+            words.append(s[:end])
+            break
+
+        if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
+            words.append(s[:end])       # we definitely have a word delimiter
+            s = s[end:].lstrip()
+            pos = 0
+
+        elif s[end] == '\\':            # preserve whatever is being escaped;
+                                        # will become part of the current word
+            s = s[:end] + s[end+1:]
+            pos = end+1
+
+        else:
+            if s[end] == "'":           # slurp singly-quoted string
+                m = _squote_re.match(s, end)
+            elif s[end] == '"':         # slurp doubly-quoted string
+                m = _dquote_re.match(s, end)
+            else:
+                raise RuntimeError("this can't happen (bad char '%c')" % s[end])
+
+            if m is None:
+                raise ValueError("bad string (mismatched %s quotes?)" % s[end])
+
+            (beg, end) = m.span()
+            if _has_white_re.search(s[beg+1:end-1]):
+                s = s[:beg] + s[beg+1:end-1] + s[end:]
+                pos = m.end() - 2
+            else:
+                # Keeping quotes when a quoted word does not contain
+                # white-space. XXX: send a patch to distutils
+                pos = m.end()
+
+        if pos >= len(s):
+            words.append(s)
+            break
+
+    return words
+ccompiler.split_quoted = split_quoted
+##Fix distutils.util.split_quoted:
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
new file mode 100644
index 0000000000..76a2600723
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
@@ -0,0 +1,43 @@
+"""distutils.command
+
+Package containing implementation of all the standard Distutils
+commands.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+def test_na_writable_attributes_deletion():
+    a = np.NA(2)
+    attr =  ['payload', 'dtype']
+    for s in attr:
+        assert_raises(AttributeError, delattr, a, s)
+
+
+__revision__ = "$Id: __init__.py,v 1.3 2005/05/16 11:08:49 pearu Exp $"
+
+distutils_all = [  #'build_py',
+                   'clean',
+                   'install_clib',
+                   'install_scripts',
+                   'bdist',
+                   'bdist_dumb',
+                   'bdist_wininst',
+                ]
+
+__import__('distutils.command', globals(), locals(), distutils_all)
+
+__all__ = ['build',
+           'config_compiler',
+           'config',
+           'build_src',
+           'build_py',
+           'build_ext',
+           'build_clib',
+           'build_scripts',
+           'install',
+           'install_data',
+           'install_headers',
+           'install_lib',
+           'bdist_rpm',
+           'sdist',
+          ] + distutils_all
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
new file mode 100644
index 0000000000..d5e78963c1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
@@ -0,0 +1,96 @@
+"""This module implements additional tests ala autoconf which can be useful.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+
+# We put them here since they could be easily reused outside numpy.distutils
+
+def check_inline(cmd):
+    """Return the inline identifier (may be empty)."""
+    cmd._check_compiler()
+    body = """
+#ifndef __cplusplus
+static %(inline)s int static_func (void)
+{
+    return 0;
+}
+%(inline)s int nostatic_func (void)
+{
+    return 0;
+}
+#endif"""
+
+    for kw in ['inline', '__inline__', '__inline']:
+        st = cmd.try_compile(body % {'inline': kw}, None, None)
+        if st:
+            return kw
+
+    return ''
+
+def check_restrict(cmd):
+    """Return the restrict identifier (may be empty)."""
+    cmd._check_compiler()
+    body = """
+static int static_func (char * %(restrict)s a)
+{
+    return 0;
+}
+"""
+
+    for kw in ['restrict', '__restrict__', '__restrict']:
+        st = cmd.try_compile(body % {'restrict': kw}, None, None)
+        if st:
+            return kw
+
+    return ''
+
+def check_compiler_gcc4(cmd):
+    """Return True if the C compiler is GCC 4.x."""
+    cmd._check_compiler()
+    body = """
+int
+main()
+{
+#if (! defined __GNUC__) || (__GNUC__ < 4)
+#error gcc >= 4 required
+#endif
+    return 0;
+}
+"""
+    return cmd.try_compile(body, None, None)
+
+
+def check_gcc_function_attribute(cmd, attribute, name):
+    """Return True if the given function attribute is supported."""
+    cmd._check_compiler()
+    body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s %s(void*);
+
+int
+main()
+{
+    return 0;
+}
+""" % (attribute, name)
+    return cmd.try_compile(body, None, None) != 0
+
+def check_gcc_variable_attribute(cmd, attribute):
+    """Return True if the given variable attribute is supported."""
+    cmd._check_compiler()
+    body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s foo;
+
+int
+main()
+{
+    return 0;
+}
+""" % (attribute, )
+    return cmd.try_compile(body, None, None) != 0
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
new file mode 100644
index 0000000000..3e52a503b1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
@@ -0,0 +1,24 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+if 'setuptools' in sys.modules:
+    from setuptools.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+else:
+    from distutils.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+
+class bdist_rpm(old_bdist_rpm):
+
+    def _make_spec_file(self):
+        spec_file = old_bdist_rpm._make_spec_file(self)
+
+        # Replace hardcoded setup.py script name
+        # with the real setup script name.
+        setup_py = os.path.basename(sys.argv[0])
+        if setup_py == 'setup.py':
+            return spec_file
+        new_spec_file = []
+        for line in spec_file:
+            line = line.replace('setup.py', setup_py)
+            new_spec_file.append(line)
+        return new_spec_file
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.py
new file mode 100644
index 0000000000..3d7101582a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.py
@@ -0,0 +1,47 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from distutils.command.build import build as old_build
+from distutils.util import get_platform
+from numpy.distutils.command.config_compiler import show_fortran_compilers
+
+class build(old_build):
+
+    sub_commands = [('config_cc',     lambda *args: True),
+                    ('config_fc',     lambda *args: True),
+                    ('build_src',     old_build.has_ext_modules),
+                    ] + old_build.sub_commands
+
+    user_options = old_build.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    help_options = old_build.help_options + [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    def initialize_options(self):
+        old_build.initialize_options(self)
+        self.fcompiler = None
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+        build_scripts = self.build_scripts
+        old_build.finalize_options(self)
+        plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+        if build_scripts is None:
+            self.build_scripts = os.path.join(self.build_base,
+                                              'scripts' + plat_specifier)
+
+    def run(self):
+        old_build.run(self)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
new file mode 100644
index 0000000000..1c868cf6c7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
@@ -0,0 +1,295 @@
+""" Modified version of build_clib that handles fortran source files.
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+from glob import glob
+import shutil
+from distutils.command.build_clib import build_clib as old_build_clib
+from distutils.errors import DistutilsSetupError, DistutilsError, \
+     DistutilsFileError
+
+from numpy.distutils import log
+from distutils.dep_util import newer_group
+from numpy.distutils.misc_util import filter_sources, has_f_sources,\
+     has_cxx_sources, all_strings, get_lib_source_files, is_sequence, \
+     get_numpy_include_dirs
+
+# Fix Python distutils bug sf #1718574:
+_l = old_build_clib.user_options
+for _i in range(len(_l)):
+    if _l[_i][0] in ['build-clib', 'build-temp']:
+        _l[_i] = (_l[_i][0]+'=',)+_l[_i][1:]
+#
+
+class build_clib(old_build_clib):
+
+    description = "build C/C++/F libraries used by Python extensions"
+
+    user_options = old_build_clib.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('inplace', 'i', 'Build in-place'),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    boolean_options = old_build_clib.boolean_options + ['inplace']
+
+    def initialize_options(self):
+        old_build_clib.initialize_options(self)
+        self.fcompiler = None
+        self.inplace = 0
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+        old_build_clib.finalize_options(self)
+        self.set_undefined_options('build', ('parallel', 'parallel'))
+
+    def have_f_sources(self):
+        for (lib_name, build_info) in self.libraries:
+            if has_f_sources(build_info.get('sources', [])):
+                return True
+        return False
+
+    def have_cxx_sources(self):
+        for (lib_name, build_info) in self.libraries:
+            if has_cxx_sources(build_info.get('sources', [])):
+                return True
+        return False
+
+    def run(self):
+        if not self.libraries:
+            return
+
+        # Make sure that library sources are complete.
+        languages = []
+
+        # Make sure that extension sources are complete.
+        self.run_command('build_src')
+
+        for (lib_name, build_info) in self.libraries:
+            l = build_info.get('language', None)
+            if l and l not in languages: languages.append(l)
+
+        from distutils.ccompiler import new_compiler
+        self.compiler = new_compiler(compiler=self.compiler,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        self.compiler.customize(self.distribution,
+                                need_cxx=self.have_cxx_sources())
+
+        libraries = self.libraries
+        self.libraries = None
+        self.compiler.customize_cmd(self)
+        self.libraries = libraries
+
+        self.compiler.show_customization()
+
+        if self.have_f_sources():
+            from numpy.distutils.fcompiler import new_fcompiler
+            self._f_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90='f90' in languages,
+                                               c_compiler=self.compiler)
+            if self._f_compiler is not None:
+                self._f_compiler.customize(self.distribution)
+
+                libraries = self.libraries
+                self.libraries = None
+                self._f_compiler.customize_cmd(self)
+                self.libraries = libraries
+
+                self._f_compiler.show_customization()
+        else:
+            self._f_compiler = None
+
+        self.build_libraries(self.libraries)
+
+        if self.inplace:
+            for l in  self.distribution.installed_libraries:
+                libname = self.compiler.library_filename(l.name)
+                source = os.path.join(self.build_clib, libname)
+                target =  os.path.join(l.target_dir, libname)
+                self.mkpath(l.target_dir)
+                shutil.copy(source, target)
+
+    def get_source_files(self):
+        self.check_library_list(self.libraries)
+        filenames = []
+        for lib in self.libraries:
+            filenames.extend(get_lib_source_files(lib))
+        return filenames
+
+    def build_libraries(self, libraries):
+        for (lib_name, build_info) in libraries:
+            self.build_a_library(build_info, lib_name, libraries)
+
+    def build_a_library(self, build_info, lib_name, libraries):
+        # default compilers
+        compiler = self.compiler
+        fcompiler = self._f_compiler
+
+        sources = build_info.get('sources')
+        if sources is None or not is_sequence(sources):
+            raise DistutilsSetupError(("in 'libraries' option (library '%s'), " +
+                   "'sources' must be present and must be " +
+                   "a list of source filenames") % lib_name)
+        sources = list(sources)
+
+        c_sources, cxx_sources, f_sources, fmodule_sources \
+                   = filter_sources(sources)
+        requiref90 = not not fmodule_sources or \
+                     build_info.get('language', 'c')=='f90'
+
+        # save source type information so that build_ext can use it.
+        source_languages = []
+        if c_sources: source_languages.append('c')
+        if cxx_sources: source_languages.append('c++')
+        if requiref90: source_languages.append('f90')
+        elif f_sources: source_languages.append('f77')
+        build_info['source_languages'] = source_languages
+
+        lib_file = compiler.library_filename(lib_name,
+                                             output_dir=self.build_clib)
+        depends = sources + build_info.get('depends', [])
+        if not (self.force or newer_group(depends, lib_file, 'newer')):
+            log.debug("skipping '%s' library (up-to-date)", lib_name)
+            return
+        else:
+            log.info("building '%s' library", lib_name)
+
+        config_fc = build_info.get('config_fc', {})
+        if fcompiler is not None and config_fc:
+            log.info('using additional config_fc from setup script '\
+                     'for fortran compiler: %s' \
+                     % (config_fc,))
+            from numpy.distutils.fcompiler import new_fcompiler
+            fcompiler = new_fcompiler(compiler=fcompiler.compiler_type,
+                                      verbose=self.verbose,
+                                      dry_run=self.dry_run,
+                                      force=self.force,
+                                      requiref90=requiref90,
+                                      c_compiler=self.compiler)
+            if fcompiler is not None:
+                dist = self.distribution
+                base_config_fc = dist.get_option_dict('config_fc').copy()
+                base_config_fc.update(config_fc)
+                fcompiler.customize(base_config_fc)
+
+        # check availability of Fortran compilers
+        if (f_sources or fmodule_sources) and fcompiler is None:
+            raise DistutilsError("library %s has Fortran sources"\
+                  " but no Fortran compiler found" % (lib_name))
+
+        if fcompiler is not None:
+            fcompiler.extra_f77_compile_args = build_info.get('extra_f77_compile_args') or []
+            fcompiler.extra_f90_compile_args = build_info.get('extra_f90_compile_args') or []
+
+        macros = build_info.get('macros')
+        include_dirs = build_info.get('include_dirs')
+        if include_dirs is None:
+            include_dirs = []
+        extra_postargs = build_info.get('extra_compiler_args') or []
+
+        include_dirs.extend(get_numpy_include_dirs())
+        # where compiled F90 module files are:
+        module_dirs = build_info.get('module_dirs') or []
+        module_build_dir = os.path.dirname(lib_file)
+        if requiref90: self.mkpath(module_build_dir)
+
+        if compiler.compiler_type=='msvc':
+            # this hack works around the msvc compiler attributes
+            # problem, msvc uses its own convention :(
+            c_sources += cxx_sources
+            cxx_sources = []
+
+        objects = []
+        if c_sources:
+            log.info("compiling C sources")
+            objects = compiler.compile(c_sources,
+                                       output_dir=self.build_temp,
+                                       macros=macros,
+                                       include_dirs=include_dirs,
+                                       debug=self.debug,
+                                       extra_postargs=extra_postargs)
+
+        if cxx_sources:
+            log.info("compiling C++ sources")
+            cxx_compiler = compiler.cxx_compiler()
+            cxx_objects = cxx_compiler.compile(cxx_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+            objects.extend(cxx_objects)
+
+        if f_sources or fmodule_sources:
+            extra_postargs = []
+            f_objects = []
+
+            if requiref90:
+                if fcompiler.module_dir_switch is None:
+                    existing_modules = glob('*.mod')
+                extra_postargs += fcompiler.module_options(\
+                    module_dirs, module_build_dir)
+
+            if fmodule_sources:
+                log.info("compiling Fortran 90 module sources")
+                f_objects += fcompiler.compile(fmodule_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+
+            if requiref90 and self._f_compiler.module_dir_switch is None:
+                # move new compiled F90 module files to module_build_dir
+                for f in glob('*.mod'):
+                    if f in existing_modules:
+                        continue
+                    t = os.path.join(module_build_dir, f)
+                    if os.path.abspath(f)==os.path.abspath(t):
+                        continue
+                    if os.path.isfile(t):
+                        os.remove(t)
+                    try:
+                        self.move_file(f, module_build_dir)
+                    except DistutilsFileError:
+                        log.warn('failed to move %r to %r' \
+                                 % (f, module_build_dir))
+
+            if f_sources:
+                log.info("compiling Fortran sources")
+                f_objects += fcompiler.compile(f_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+        else:
+            f_objects = []
+
+        objects.extend(f_objects)
+
+        # assume that default linker is suitable for
+        # linking Fortran object files
+        compiler.create_static_lib(objects, lib_name,
+                                   output_dir=self.build_clib,
+                                   debug=self.debug)
+
+        # fix library dependencies
+        clib_libraries = build_info.get('libraries', [])
+        for lname, binfo in libraries:
+            if lname in clib_libraries:
+                clib_libraries.extend(binfo.get('libraries', []))
+        if clib_libraries:
+            build_info['libraries'] = clib_libraries
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
new file mode 100644
index 0000000000..0fa52a2818
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
@@ -0,0 +1,522 @@
+""" Modified version of build_ext that handles fortran source files.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from glob import glob
+
+from distutils.dep_util import newer_group
+from distutils.command.build_ext import build_ext as old_build_ext
+from distutils.errors import DistutilsFileError, DistutilsSetupError,\
+     DistutilsError
+from distutils.file_util import copy_file
+
+from numpy.distutils import log
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.system_info import combine_paths
+from numpy.distutils.misc_util import filter_sources, has_f_sources, \
+     has_cxx_sources, get_ext_source_files, \
+     get_numpy_include_dirs, is_sequence, get_build_architecture, \
+     msvc_version
+from numpy.distutils.command.config_compiler import show_fortran_compilers
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+class build_ext (old_build_ext):
+
+    description = "build C/C++/F extensions (compile/link to build directory)"
+
+    user_options = old_build_ext.user_options + [
+        ('fcompiler=', None,
+         "specify the Fortran compiler type"),
+        ('parallel=', 'j',
+         "number of parallel jobs"),
+        ]
+
+    help_options = old_build_ext.help_options + [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    def initialize_options(self):
+        old_build_ext.initialize_options(self)
+        self.fcompiler = None
+        self.parallel = None
+
+    def finalize_options(self):
+        if self.parallel:
+            try:
+                self.parallel = int(self.parallel)
+            except ValueError:
+                raise ValueError("--parallel/-j argument must be an integer")
+
+        # Ensure that self.include_dirs and self.distribution.include_dirs
+        # refer to the same list object. finalize_options will modify
+        # self.include_dirs, but self.distribution.include_dirs is used
+        # during the actual build.
+        # self.include_dirs is None unless paths are specified with
+        # --include-dirs.
+        # The include paths will be passed to the compiler in the order:
+        # numpy paths, --include-dirs paths, Python include path.
+        if isinstance(self.include_dirs, str):
+            self.include_dirs = self.include_dirs.split(os.pathsep)
+        incl_dirs = self.include_dirs or []
+        if self.distribution.include_dirs is None:
+            self.distribution.include_dirs = []
+        self.include_dirs = self.distribution.include_dirs
+        self.include_dirs.extend(incl_dirs)
+
+        old_build_ext.finalize_options(self)
+        self.set_undefined_options('build', ('parallel', 'parallel'))
+
+    def run(self):
+        if not self.extensions:
+            return
+
+        # Make sure that extension sources are complete.
+        self.run_command('build_src')
+
+        if self.distribution.has_c_libraries():
+            if self.inplace:
+                if self.distribution.have_run.get('build_clib'):
+                    log.warn('build_clib already run, it is too late to ' \
+                            'ensure in-place build of build_clib')
+                    build_clib = self.distribution.get_command_obj('build_clib')
+                else:
+                    build_clib = self.distribution.get_command_obj('build_clib')
+                    build_clib.inplace = 1
+                    build_clib.ensure_finalized()
+                    build_clib.run()
+                    self.distribution.have_run['build_clib'] = 1
+
+            else:
+                self.run_command('build_clib')
+                build_clib = self.get_finalized_command('build_clib')
+            self.library_dirs.append(build_clib.build_clib)
+        else:
+            build_clib = None
+
+        # Not including C libraries to the list of
+        # extension libraries automatically to prevent
+        # bogus linking commands. Extensions must
+        # explicitly specify the C libraries that they use.
+
+        from distutils.ccompiler import new_compiler
+        from numpy.distutils.fcompiler import new_fcompiler
+
+        compiler_type = self.compiler
+        # Initialize C compiler:
+        self.compiler = new_compiler(compiler=compiler_type,
+                                     verbose=self.verbose,
+                                     dry_run=self.dry_run,
+                                     force=self.force)
+        self.compiler.customize(self.distribution)
+        self.compiler.customize_cmd(self)
+        self.compiler.show_customization()
+
+        # Create mapping of libraries built by build_clib:
+        clibs = {}
+        if build_clib is not None:
+            for libname, build_info in build_clib.libraries or []:
+                if libname in clibs and clibs[libname] != build_info:
+                    log.warn('library %r defined more than once,'\
+                             ' overwriting build_info\n%s... \nwith\n%s...' \
+                             % (libname, repr(clibs[libname])[:300], repr(build_info)[:300]))
+                clibs[libname] = build_info
+        # .. and distribution libraries:
+        for libname, build_info in self.distribution.libraries or []:
+            if libname in clibs:
+                # build_clib libraries have a precedence before distribution ones
+                continue
+            clibs[libname] = build_info
+
+        # Determine if C++/Fortran 77/Fortran 90 compilers are needed.
+        # Update extension libraries, library_dirs, and macros.
+        all_languages = set()
+        for ext in self.extensions:
+            ext_languages = set()
+            c_libs = []
+            c_lib_dirs = []
+            macros = []
+            for libname in ext.libraries:
+                if libname in clibs:
+                    binfo = clibs[libname]
+                    c_libs += binfo.get('libraries', [])
+                    c_lib_dirs += binfo.get('library_dirs', [])
+                    for m in binfo.get('macros', []):
+                        if m not in macros:
+                            macros.append(m)
+
+                for l in clibs.get(libname, {}).get('source_languages', []):
+                    ext_languages.add(l)
+            if c_libs:
+                new_c_libs = ext.libraries + c_libs
+                log.info('updating extension %r libraries from %r to %r'
+                         % (ext.name, ext.libraries, new_c_libs))
+                ext.libraries = new_c_libs
+                ext.library_dirs = ext.library_dirs + c_lib_dirs
+            if macros:
+                log.info('extending extension %r defined_macros with %r'
+                         % (ext.name, macros))
+                ext.define_macros = ext.define_macros + macros
+
+            # determine extension languages
+            if has_f_sources(ext.sources):
+                ext_languages.add('f77')
+            if has_cxx_sources(ext.sources):
+                ext_languages.add('c++')
+            l = ext.language or self.compiler.detect_language(ext.sources)
+            if l:
+                ext_languages.add(l)
+            # reset language attribute for choosing proper linker
+            if 'c++' in ext_languages:
+                ext_language = 'c++'
+            elif 'f90' in ext_languages:
+                ext_language = 'f90'
+            elif 'f77' in ext_languages:
+                ext_language = 'f77'
+            else:
+                ext_language = 'c' # default
+            if l and l != ext_language and ext.language:
+                log.warn('resetting extension %r language from %r to %r.' %
+                         (ext.name, l, ext_language))
+            ext.language = ext_language
+            # global language
+            all_languages.update(ext_languages)
+
+        need_f90_compiler = 'f90' in all_languages
+        need_f77_compiler = 'f77' in all_languages
+        need_cxx_compiler = 'c++' in all_languages
+
+        # Initialize C++ compiler:
+        if need_cxx_compiler:
+            self._cxx_compiler = new_compiler(compiler=compiler_type,
+                                             verbose=self.verbose,
+                                             dry_run=self.dry_run,
+                                             force=self.force)
+            compiler = self._cxx_compiler
+            compiler.customize(self.distribution, need_cxx=need_cxx_compiler)
+            compiler.customize_cmd(self)
+            compiler.show_customization()
+            self._cxx_compiler = compiler.cxx_compiler()
+        else:
+            self._cxx_compiler = None
+
+        # Initialize Fortran 77 compiler:
+        if need_f77_compiler:
+            ctype = self.fcompiler
+            self._f77_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90=False,
+                                               c_compiler=self.compiler)
+            fcompiler = self._f77_compiler
+            if fcompiler:
+                ctype = fcompiler.compiler_type
+                fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
+                fcompiler.customize_cmd(self)
+                fcompiler.show_customization()
+            else:
+                self.warn('f77_compiler=%s is not available.' %
+                          (ctype))
+                self._f77_compiler = None
+        else:
+            self._f77_compiler = None
+
+        # Initialize Fortran 90 compiler:
+        if need_f90_compiler:
+            ctype = self.fcompiler
+            self._f90_compiler = new_fcompiler(compiler=self.fcompiler,
+                                               verbose=self.verbose,
+                                               dry_run=self.dry_run,
+                                               force=self.force,
+                                               requiref90=True,
+                                               c_compiler = self.compiler)
+            fcompiler = self._f90_compiler
+            if fcompiler:
+                ctype = fcompiler.compiler_type
+                fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
+                fcompiler.customize_cmd(self)
+                fcompiler.show_customization()
+            else:
+                self.warn('f90_compiler=%s is not available.' %
+                          (ctype))
+                self._f90_compiler = None
+        else:
+            self._f90_compiler = None
+
+        # Build extensions
+        self.build_extensions()
+
+
+    def swig_sources(self, sources):
+        # Do nothing. Swig sources have beed handled in build_src command.
+        return sources
+
+    def build_extension(self, ext):
+        sources = ext.sources
+        if sources is None or not is_sequence(sources):
+            raise DistutilsSetupError(
+                ("in 'ext_modules' option (extension '%s'), " +
+                 "'sources' must be present and must be " +
+                 "a list of source filenames") % ext.name)
+        sources = list(sources)
+
+        if not sources:
+            return
+
+        fullname = self.get_ext_fullname(ext.name)
+        if self.inplace:
+            modpath = fullname.split('.')
+            package = '.'.join(modpath[0:-1])
+            base = modpath[-1]
+            build_py = self.get_finalized_command('build_py')
+            package_dir = build_py.get_package_dir(package)
+            ext_filename = os.path.join(package_dir,
+                                        self.get_ext_filename(base))
+        else:
+            ext_filename = os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname))
+        depends = sources + ext.depends
+
+        if not (self.force or newer_group(depends, ext_filename, 'newer')):
+            log.debug("skipping '%s' extension (up-to-date)", ext.name)
+            return
+        else:
+            log.info("building '%s' extension", ext.name)
+
+        extra_args = ext.extra_compile_args or []
+        macros = ext.define_macros[:]
+        for undef in ext.undef_macros:
+            macros.append((undef,))
+
+        c_sources, cxx_sources, f_sources, fmodule_sources = \
+                   filter_sources(ext.sources)
+
+
+
+        if self.compiler.compiler_type=='msvc':
+            if cxx_sources:
+                # Needed to compile kiva.agg._agg extension.
+                extra_args.append('/Zm1000')
+            # this hack works around the msvc compiler attributes
+            # problem, msvc uses its own convention :(
+            c_sources += cxx_sources
+            cxx_sources = []
+
+        # Set Fortran/C++ compilers for compilation and linking.
+        if ext.language=='f90':
+            fcompiler = self._f90_compiler
+        elif ext.language=='f77':
+            fcompiler = self._f77_compiler
+        else: # in case ext.language is c++, for instance
+            fcompiler = self._f90_compiler or self._f77_compiler
+        if fcompiler is not None:
+            fcompiler.extra_f77_compile_args = (ext.extra_f77_compile_args or []) if hasattr(ext, 'extra_f77_compile_args') else []
+            fcompiler.extra_f90_compile_args = (ext.extra_f90_compile_args or []) if hasattr(ext, 'extra_f90_compile_args') else []
+        cxx_compiler = self._cxx_compiler
+
+        # check for the availability of required compilers
+        if cxx_sources and cxx_compiler is None:
+            raise DistutilsError("extension %r has C++ sources" \
+                  "but no C++ compiler found" % (ext.name))
+        if (f_sources or fmodule_sources) and fcompiler is None:
+            raise DistutilsError("extension %r has Fortran sources " \
+                  "but no Fortran compiler found" % (ext.name))
+        if ext.language in ['f77', 'f90'] and fcompiler is None:
+            self.warn("extension %r has Fortran libraries " \
+                  "but no Fortran linker found, using default linker" % (ext.name))
+        if ext.language=='c++' and cxx_compiler is None:
+            self.warn("extension %r has C++ libraries " \
+                  "but no C++ linker found, using default linker" % (ext.name))
+
+        kws = {'depends':ext.depends}
+        output_dir = self.build_temp
+
+        include_dirs = ext.include_dirs + get_numpy_include_dirs()
+
+        c_objects = []
+        if c_sources:
+            log.info("compiling C sources")
+            c_objects = self.compiler.compile(c_sources,
+                                              output_dir=output_dir,
+                                              macros=macros,
+                                              include_dirs=include_dirs,
+                                              debug=self.debug,
+                                              extra_postargs=extra_args,
+                                              **kws)
+
+        if cxx_sources:
+            log.info("compiling C++ sources")
+            c_objects += cxx_compiler.compile(cxx_sources,
+                                              output_dir=output_dir,
+                                              macros=macros,
+                                              include_dirs=include_dirs,
+                                              debug=self.debug,
+                                              extra_postargs=extra_args,
+                                              **kws)
+
+        extra_postargs = []
+        f_objects = []
+        if fmodule_sources:
+            log.info("compiling Fortran 90 module sources")
+            module_dirs = ext.module_dirs[:]
+            module_build_dir = os.path.join(
+                self.build_temp, os.path.dirname(
+                    self.get_ext_filename(fullname)))
+
+            self.mkpath(module_build_dir)
+            if fcompiler.module_dir_switch is None:
+                existing_modules = glob('*.mod')
+            extra_postargs += fcompiler.module_options(
+                module_dirs, module_build_dir)
+            f_objects += fcompiler.compile(fmodule_sources,
+                                           output_dir=self.build_temp,
+                                           macros=macros,
+                                           include_dirs=include_dirs,
+                                           debug=self.debug,
+                                           extra_postargs=extra_postargs,
+                                           depends=ext.depends)
+
+            if fcompiler.module_dir_switch is None:
+                for f in glob('*.mod'):
+                    if f in existing_modules:
+                        continue
+                    t = os.path.join(module_build_dir, f)
+                    if os.path.abspath(f)==os.path.abspath(t):
+                        continue
+                    if os.path.isfile(t):
+                        os.remove(t)
+                    try:
+                        self.move_file(f, module_build_dir)
+                    except DistutilsFileError:
+                        log.warn('failed to move %r to %r' %
+                                 (f, module_build_dir))
+        if f_sources:
+            log.info("compiling Fortran sources")
+            f_objects += fcompiler.compile(f_sources,
+                                           output_dir=self.build_temp,
+                                           macros=macros,
+                                           include_dirs=include_dirs,
+                                           debug=self.debug,
+                                           extra_postargs=extra_postargs,
+                                           depends=ext.depends)
+
+        objects = c_objects + f_objects
+
+        if ext.extra_objects:
+            objects.extend(ext.extra_objects)
+        extra_args = ext.extra_link_args or []
+        libraries = self.get_libraries(ext)[:]
+        library_dirs = ext.library_dirs[:]
+
+        linker = self.compiler.link_shared_object
+        # Always use system linker when using MSVC compiler.
+        if self.compiler.compiler_type in ('msvc', 'intelw', 'intelemw'):
+            # expand libraries with fcompiler libraries as we are
+            # not using fcompiler linker
+            self._libs_with_msvc_and_fortran(fcompiler, libraries, library_dirs)
+
+        elif ext.language in ['f77', 'f90'] and fcompiler is not None:
+            linker = fcompiler.link_shared_object
+        if ext.language=='c++' and cxx_compiler is not None:
+            linker = cxx_compiler.link_shared_object
+
+        linker(objects, ext_filename,
+               libraries=libraries,
+               library_dirs=library_dirs,
+               runtime_library_dirs=ext.runtime_library_dirs,
+               extra_postargs=extra_args,
+               export_symbols=self.get_export_symbols(ext),
+               debug=self.debug,
+               build_temp=self.build_temp,
+               target_lang=ext.language)
+
+    def _add_dummy_mingwex_sym(self, c_sources):
+        build_src = self.get_finalized_command("build_src").build_src
+        build_clib = self.get_finalized_command("build_clib").build_clib
+        objects = self.compiler.compile([os.path.join(build_src,
+                "gfortran_vs2003_hack.c")],
+                output_dir=self.build_temp)
+        self.compiler.create_static_lib(objects, "_gfortran_workaround", output_dir=build_clib, debug=self.debug)
+
+    def _libs_with_msvc_and_fortran(self, fcompiler, c_libraries,
+                                    c_library_dirs):
+        if fcompiler is None: return
+
+        for libname in c_libraries:
+            if libname.startswith('msvc'): continue
+            fileexists = False
+            for libdir in c_library_dirs or []:
+                libfile = os.path.join(libdir, '%s.lib' % (libname))
+                if os.path.isfile(libfile):
+                    fileexists = True
+                    break
+            if fileexists: continue
+            # make g77-compiled static libs available to MSVC
+            fileexists = False
+            for libdir in c_library_dirs:
+                libfile = os.path.join(libdir, 'lib%s.a' % (libname))
+                if os.path.isfile(libfile):
+                    # copy libname.a file to name.lib so that MSVC linker
+                    # can find it
+                    libfile2 = os.path.join(self.build_temp, libname + '.lib')
+                    copy_file(libfile, libfile2)
+                    if self.build_temp not in c_library_dirs:
+                        c_library_dirs.append(self.build_temp)
+                    fileexists = True
+                    break
+            if fileexists: continue
+            log.warn('could not find library %r in directories %s'
+                     % (libname, c_library_dirs))
+
+        # Always use system linker when using MSVC compiler.
+        f_lib_dirs = []
+        for dir in fcompiler.library_dirs:
+            # correct path when compiling in Cygwin but with normal Win
+            # Python
+            if dir.startswith('/usr/lib'):
+                s, o = exec_command(['cygpath', '-w', dir], use_tee=False)
+                if not s:
+                    dir = o
+            f_lib_dirs.append(dir)
+        c_library_dirs.extend(f_lib_dirs)
+
+        # make g77-compiled static libs available to MSVC
+        for lib in fcompiler.libraries:
+            if not lib.startswith('msvc'):
+                c_libraries.append(lib)
+                p = combine_paths(f_lib_dirs, 'lib' + lib + '.a')
+                if p:
+                    dst_name = os.path.join(self.build_temp, lib + '.lib')
+                    if not os.path.isfile(dst_name):
+                        copy_file(p[0], dst_name)
+                    if self.build_temp not in c_library_dirs:
+                        c_library_dirs.append(self.build_temp)
+
+    def get_source_files (self):
+        self.check_extensions_list(self.extensions)
+        filenames = []
+        for ext in self.extensions:
+            filenames.extend(get_ext_source_files(ext))
+        return filenames
+
+    def get_outputs (self):
+        self.check_extensions_list(self.extensions)
+
+        outputs = []
+        for ext in self.extensions:
+            if not ext.sources:
+                continue
+            fullname = self.get_ext_fullname(ext.name)
+            outputs.append(os.path.join(self.build_lib,
+                                        self.get_ext_filename(fullname)))
+        return outputs
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
new file mode 100644
index 0000000000..54dcde4350
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
@@ -0,0 +1,33 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.command.build_py import build_py as old_build_py
+from numpy.distutils.misc_util import is_string
+
+class build_py(old_build_py):
+
+    def run(self):
+        build_src = self.get_finalized_command('build_src')
+        if build_src.py_modules_dict and self.packages is None:
+            self.packages = list(build_src.py_modules_dict.keys ())
+        old_build_py.run(self)
+
+    def find_package_modules(self, package, package_dir):
+        modules = old_build_py.find_package_modules(self, package, package_dir)
+
+        # Find build_src generated *.py files.
+        build_src = self.get_finalized_command('build_src')
+        modules += build_src.py_modules_dict.get(package, [])
+
+        return modules
+
+    def find_modules(self):
+        old_py_modules = self.py_modules[:]
+        new_py_modules = [_m for _m in self.py_modules if is_string(_m)]
+        self.py_modules[:] = new_py_modules
+        modules = old_build_py.find_modules(self)
+        self.py_modules[:] = old_py_modules
+
+        return modules
+
+    # XXX: Fix find_source_files for item in py_modules such that item is 3-tuple
+    # and item[2] is source file.
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
new file mode 100644
index 0000000000..c8b25fc719
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
@@ -0,0 +1,51 @@
+""" Modified version of build_scripts that handles building scripts from functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from distutils.command.build_scripts import build_scripts as old_build_scripts
+from numpy.distutils import log
+from numpy.distutils.misc_util import is_string
+
+class build_scripts(old_build_scripts):
+
+    def generate_scripts(self, scripts):
+        new_scripts = []
+        func_scripts = []
+        for script in scripts:
+            if is_string(script):
+                new_scripts.append(script)
+            else:
+                func_scripts.append(script)
+        if not func_scripts:
+            return new_scripts
+
+        build_dir = self.build_dir
+        self.mkpath(build_dir)
+        for func in func_scripts:
+            script = func(build_dir)
+            if not script:
+                continue
+            if is_string(script):
+                log.info("  adding '%s' to scripts" % (script,))
+                new_scripts.append(script)
+            else:
+                [log.info("  adding '%s' to scripts" % (s,)) for s in script]
+                new_scripts.extend(list(script))
+        return new_scripts
+
+    def run (self):
+        if not self.scripts:
+            return
+
+        self.scripts = self.generate_scripts(self.scripts)
+        # Now make sure that the distribution object has this list of scripts.
+        # setuptools' develop command requires that this be a list of filenames,
+        # not functions.
+        self.distribution.scripts = self.scripts
+
+        return old_build_scripts.run(self)
+
+    def get_source_files(self):
+        from numpy.distutils.misc_util import get_script_files
+        return get_script_files(self.scripts)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
new file mode 100644
index 0000000000..2efcdea60c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
@@ -0,0 +1,775 @@
+""" Build swig and f2py sources.
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import shlex
+import copy
+
+from distutils.command import build_ext
+from distutils.dep_util import newer_group, newer
+from distutils.util import get_platform
+from distutils.errors import DistutilsError, DistutilsSetupError
+
+
+# this import can't be done here, as it uses numpy stuff only available
+# after it's installed
+#import numpy.f2py
+from numpy.distutils import log
+from numpy.distutils.misc_util import fortran_ext_match, \
+     appendpath, is_string, is_sequence, get_cmd
+from numpy.distutils.from_template import process_file as process_f_file
+from numpy.distutils.conv_template import process_file as process_c_file
+
+def subst_vars(target, source, d):
+    """Substitute any occurence of @foo@ by d['foo'] from source file into
+    target."""
+    var = re.compile('@([a-zA-Z_]+)@')
+    fs = open(source, 'r')
+    try:
+        ft = open(target, 'w')
+        try:
+            for l in fs:
+                m = var.search(l)
+                if m:
+                    ft.write(l.replace('@%s@' % m.group(1), d[m.group(1)]))
+                else:
+                    ft.write(l)
+        finally:
+            ft.close()
+    finally:
+        fs.close()
+
+class build_src(build_ext.build_ext):
+
+    description = "build sources from SWIG, F2PY files or a function"
+
+    user_options = [
+        ('build-src=', 'd', "directory to \"build\" sources to"),
+        ('f2py-opts=', None, "list of f2py command line options"),
+        ('swig=', None, "path to the SWIG executable"),
+        ('swig-opts=', None, "list of SWIG command line options"),
+        ('swig-cpp', None, "make SWIG create C++ files (default is autodetected from sources)"),
+        ('f2pyflags=', None, "additional flags to f2py (use --f2py-opts= instead)"), # obsolete
+        ('swigflags=', None, "additional flags to swig (use --swig-opts= instead)"), # obsolete
+        ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+        ('inplace', 'i',
+         "ignore build-lib and put compiled extensions into the source " +
+         "directory alongside your pure Python modules"),
+        ]
+
+    boolean_options = ['force', 'inplace']
+
+    help_options = []
+
+    def initialize_options(self):
+        self.extensions = None
+        self.package = None
+        self.py_modules = None
+        self.py_modules_dict = None
+        self.build_src = None
+        self.build_lib = None
+        self.build_base = None
+        self.force = None
+        self.inplace = None
+        self.package_dir = None
+        self.f2pyflags = None # obsolete
+        self.f2py_opts = None
+        self.swigflags = None # obsolete
+        self.swig_opts = None
+        self.swig_cpp = None
+        self.swig = None
+
+    def finalize_options(self):
+        self.set_undefined_options('build',
+                                   ('build_base', 'build_base'),
+                                   ('build_lib', 'build_lib'),
+                                   ('force', 'force'))
+        if self.package is None:
+            self.package = self.distribution.ext_package
+        self.extensions = self.distribution.ext_modules
+        self.libraries = self.distribution.libraries or []
+        self.py_modules = self.distribution.py_modules or []
+        self.data_files = self.distribution.data_files or []
+
+        if self.build_src is None:
+            plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+            self.build_src = os.path.join(self.build_base, 'src'+plat_specifier)
+
+        # py_modules_dict is used in build_py.find_package_modules
+        self.py_modules_dict = {}
+
+        if self.f2pyflags:
+            if self.f2py_opts:
+                log.warn('ignoring --f2pyflags as --f2py-opts already used')
+            else:
+                self.f2py_opts = self.f2pyflags
+            self.f2pyflags = None
+        if self.f2py_opts is None:
+            self.f2py_opts = []
+        else:
+            self.f2py_opts = shlex.split(self.f2py_opts)
+
+        if self.swigflags:
+            if self.swig_opts:
+                log.warn('ignoring --swigflags as --swig-opts already used')
+            else:
+                self.swig_opts = self.swigflags
+            self.swigflags = None
+
+        if self.swig_opts is None:
+            self.swig_opts = []
+        else:
+            self.swig_opts = shlex.split(self.swig_opts)
+
+        # use options from build_ext command
+        build_ext = self.get_finalized_command('build_ext')
+        if self.inplace is None:
+            self.inplace = build_ext.inplace
+        if self.swig_cpp is None:
+            self.swig_cpp = build_ext.swig_cpp
+        for c in ['swig', 'swig_opt']:
+            o = '--'+c.replace('_', '-')
+            v = getattr(build_ext, c, None)
+            if v:
+                if getattr(self, c):
+                    log.warn('both build_src and build_ext define %s option' % (o))
+                else:
+                    log.info('using "%s=%s" option from build_ext command' % (o, v))
+                    setattr(self, c, v)
+
+    def run(self):
+        log.info("build_src")
+        if not (self.extensions or self.libraries):
+            return
+        self.build_sources()
+
+    def build_sources(self):
+
+        if self.inplace:
+            self.get_package_dir = \
+                     self.get_finalized_command('build_py').get_package_dir
+
+        self.build_py_modules_sources()
+
+        for libname_info in self.libraries:
+            self.build_library_sources(*libname_info)
+
+        if self.extensions:
+            self.check_extensions_list(self.extensions)
+
+            for ext in self.extensions:
+                self.build_extension_sources(ext)
+
+        self.build_data_files_sources()
+        self.build_npy_pkg_config()
+
+    def build_data_files_sources(self):
+        if not self.data_files:
+            return
+        log.info('building data_files sources')
+        from numpy.distutils.misc_util import get_data_files
+        new_data_files = []
+        for data in self.data_files:
+            if isinstance(data, str):
+                new_data_files.append(data)
+            elif isinstance(data, tuple):
+                d, files = data
+                if self.inplace:
+                    build_dir = self.get_package_dir('.'.join(d.split(os.sep)))
+                else:
+                    build_dir = os.path.join(self.build_src, d)
+                funcs = [f for f in files if hasattr(f, '__call__')]
+                files = [f for f in files if not hasattr(f, '__call__')]
+                for f in funcs:
+                    if f.__code__.co_argcount==1:
+                        s = f(build_dir)
+                    else:
+                        s = f()
+                    if s is not None:
+                        if isinstance(s, list):
+                            files.extend(s)
+                        elif isinstance(s, str):
+                            files.append(s)
+                        else:
+                            raise TypeError(repr(s))
+                filenames = get_data_files((d, files))
+                new_data_files.append((d, filenames))
+            else:
+                raise TypeError(repr(data))
+        self.data_files[:] = new_data_files
+
+
+    def _build_npy_pkg_config(self, info, gd):
+        import shutil
+        template, install_dir, subst_dict = info
+        template_dir = os.path.dirname(template)
+        for k, v in gd.items():
+            subst_dict[k] = v
+
+        if self.inplace == 1:
+            generated_dir = os.path.join(template_dir, install_dir)
+        else:
+            generated_dir = os.path.join(self.build_src, template_dir,
+                    install_dir)
+        generated = os.path.basename(os.path.splitext(template)[0])
+        generated_path = os.path.join(generated_dir, generated)
+        if not os.path.exists(generated_dir):
+            os.makedirs(generated_dir)
+
+        subst_vars(generated_path, template, subst_dict)
+
+        # Where to install relatively to install prefix
+        full_install_dir = os.path.join(template_dir, install_dir)
+        return full_install_dir, generated_path
+
+    def build_npy_pkg_config(self):
+        log.info('build_src: building npy-pkg config files')
+
+        # XXX: another ugly workaround to circumvent distutils brain damage. We
+        # need the install prefix here, but finalizing the options of the
+        # install command when only building sources cause error. Instead, we
+        # copy the install command instance, and finalize the copy so that it
+        # does not disrupt how distutils want to do things when with the
+        # original install command instance.
+        install_cmd = copy.copy(get_cmd('install'))
+        if not install_cmd.finalized == 1:
+            install_cmd.finalize_options()
+        build_npkg = False
+        gd = {}
+        if self.inplace == 1:
+            top_prefix = '.'
+            build_npkg = True
+        elif hasattr(install_cmd, 'install_libbase'):
+            top_prefix = install_cmd.install_libbase
+            build_npkg = True
+
+        if build_npkg:
+            for pkg, infos in self.distribution.installed_pkg_config.items():
+                pkg_path = self.distribution.package_dir[pkg]
+                prefix = os.path.join(os.path.abspath(top_prefix), pkg_path)
+                d = {'prefix': prefix}
+                for info in infos:
+                    install_dir, generated = self._build_npy_pkg_config(info, d)
+                    self.distribution.data_files.append((install_dir,
+                        [generated]))
+
+    def build_py_modules_sources(self):
+        if not self.py_modules:
+            return
+        log.info('building py_modules sources')
+        new_py_modules = []
+        for source in self.py_modules:
+            if is_sequence(source) and len(source)==3:
+                package, module_base, source = source
+                if self.inplace:
+                    build_dir = self.get_package_dir(package)
+                else:
+                    build_dir = os.path.join(self.build_src,
+                                             os.path.join(*package.split('.')))
+                if hasattr(source, '__call__'):
+                    target = os.path.join(build_dir, module_base + '.py')
+                    source = source(target)
+                if source is None:
+                    continue
+                modules = [(package, module_base, source)]
+                if package not in self.py_modules_dict:
+                    self.py_modules_dict[package] = []
+                self.py_modules_dict[package] += modules
+            else:
+                new_py_modules.append(source)
+        self.py_modules[:] = new_py_modules
+
+    def build_library_sources(self, lib_name, build_info):
+        sources = list(build_info.get('sources', []))
+
+        if not sources:
+            return
+
+        log.info('building library "%s" sources' % (lib_name))
+
+        sources = self.generate_sources(sources, (lib_name, build_info))
+
+        sources = self.template_sources(sources, (lib_name, build_info))
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     self.package, h_files)
+
+        #for f in h_files:
+        #    self.distribution.headers.append((lib_name,f))
+
+        build_info['sources'] = sources
+        return
+
+    def build_extension_sources(self, ext):
+
+        sources = list(ext.sources)
+
+        log.info('building extension "%s" sources' % (ext.name))
+
+        fullname = self.get_ext_fullname(ext.name)
+
+        modpath = fullname.split('.')
+        package = '.'.join(modpath[0:-1])
+
+        if self.inplace:
+            self.ext_target_dir = self.get_package_dir(package)
+
+        sources = self.generate_sources(sources, ext)
+        sources = self.template_sources(sources, ext)
+        sources = self.swig_sources(sources, ext)
+        sources = self.f2py_sources(sources, ext)
+        sources = self.pyrex_sources(sources, ext)
+
+        sources, py_files = self.filter_py_files(sources)
+
+        if package not in self.py_modules_dict:
+            self.py_modules_dict[package] = []
+        modules = []
+        for f in py_files:
+            module = os.path.splitext(os.path.basename(f))[0]
+            modules.append((package, module, f))
+        self.py_modules_dict[package] += modules
+
+        sources, h_files = self.filter_h_files(sources)
+
+        if h_files:
+            log.info('%s - nothing done with h_files = %s',
+                     package, h_files)
+        #for f in h_files:
+        #    self.distribution.headers.append((package,f))
+
+        ext.sources = sources
+
+    def generate_sources(self, sources, extension):
+        new_sources = []
+        func_sources = []
+        for source in sources:
+            if is_string(source):
+                new_sources.append(source)
+            else:
+                func_sources.append(source)
+        if not func_sources:
+            return new_sources
+        if self.inplace and not is_sequence(extension):
+            build_dir = self.ext_target_dir
+        else:
+            if is_sequence(extension):
+                name = extension[0]
+            #    if 'include_dirs' not in extension[1]:
+            #        extension[1]['include_dirs'] = []
+            #    incl_dirs = extension[1]['include_dirs']
+            else:
+                name = extension.name
+            #    incl_dirs = extension.include_dirs
+            #if self.build_src not in incl_dirs:
+            #    incl_dirs.append(self.build_src)
+            build_dir = os.path.join(*([self.build_src]\
+                                       +name.split('.')[:-1]))
+        self.mkpath(build_dir)
+        for func in func_sources:
+            source = func(extension, build_dir)
+            if not source:
+                continue
+            if is_sequence(source):
+                [log.info("  adding '%s' to sources." % (s,)) for s in source]
+                new_sources.extend(source)
+            else:
+                log.info("  adding '%s' to sources." % (source,))
+                new_sources.append(source)
+
+        return new_sources
+
+    def filter_py_files(self, sources):
+        return self.filter_files(sources, ['.py'])
+
+    def filter_h_files(self, sources):
+        return self.filter_files(sources, ['.h', '.hpp', '.inc'])
+
+    def filter_files(self, sources, exts = []):
+        new_sources = []
+        files = []
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext in exts:
+                files.append(source)
+            else:
+                new_sources.append(source)
+        return new_sources, files
+
+    def template_sources(self, sources, extension):
+        new_sources = []
+        if is_sequence(extension):
+            depends = extension[1].get('depends')
+            include_dirs = extension[1].get('include_dirs')
+        else:
+            depends = extension.depends
+            include_dirs = extension.include_dirs
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.src':  # Template file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                self.mkpath(target_dir)
+                target_file = os.path.join(target_dir, os.path.basename(base))
+                if (self.force or newer_group([source] + depends, target_file)):
+                    if _f_pyf_ext_match(base):
+                        log.info("from_template:> %s" % (target_file))
+                        outstr = process_f_file(source)
+                    else:
+                        log.info("conv_template:> %s" % (target_file))
+                        outstr = process_c_file(source)
+                    fid = open(target_file, 'w')
+                    fid.write(outstr)
+                    fid.close()
+                if _header_ext_match(target_file):
+                    d = os.path.dirname(target_file)
+                    if d not in include_dirs:
+                        log.info("  adding '%s' to include_dirs." % (d))
+                        include_dirs.append(d)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def pyrex_sources(self, sources, extension):
+        """Pyrex not supported; this remains for Cython support (see below)"""
+        new_sources = []
+        ext_name = extension.name.split('.')[-1]
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyx':
+                target_file = self.generate_a_pyrex_source(base, ext_name,
+                                                           source,
+                                                           extension)
+                new_sources.append(target_file)
+            else:
+                new_sources.append(source)
+        return new_sources
+
+    def generate_a_pyrex_source(self, base, ext_name, source, extension):
+        """Pyrex is not supported, but some projects monkeypatch this method.
+
+        That allows compiling Cython code, see gh-6955.
+        This method will remain here for compatibility reasons.
+        """
+        return []
+
+    def f2py_sources(self, sources, extension):
+        new_sources = []
+        f2py_sources = []
+        f_sources = []
+        f2py_targets = {}
+        target_dirs = []
+        ext_name = extension.name.split('.')[-1]
+        skip_f2py = 0
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.pyf': # F2PY interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                if os.path.isfile(source):
+                    name = get_f2py_modulename(source)
+                    if name != ext_name:
+                        raise DistutilsSetupError('mismatch of extension names: %s '
+                                                  'provides %r but expected %r' % (
+                            source, name, ext_name))
+                    target_file = os.path.join(target_dir, name+'module.c')
+                else:
+                    log.debug('  source %s does not exist: skipping f2py\'ing.' \
+                              % (source))
+                    name = ext_name
+                    skip_f2py = 1
+                    target_file = os.path.join(target_dir, name+'module.c')
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %smodule.c was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = os.path.join(target_dir, name+'module.c')
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.info('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                f2py_sources.append(source)
+                f2py_targets[source] = target_file
+                new_sources.append(target_file)
+            elif fortran_ext_match(ext):
+                f_sources.append(source)
+            else:
+                new_sources.append(source)
+
+        if not (f2py_sources or f_sources):
+            return new_sources
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        f2py_options = extension.f2py_options + self.f2py_opts
+
+        if self.distribution.libraries:
+            for name, build_info in self.distribution.libraries:
+                if name in extension.libraries:
+                    f2py_options.extend(build_info.get('f2py_options', []))
+
+        log.info("f2py options: %s" % (f2py_options))
+
+        if f2py_sources:
+            if len(f2py_sources) != 1:
+                raise DistutilsSetupError(
+                    'only one .pyf file is allowed per extension module but got'\
+                    ' more: %r' % (f2py_sources,))
+            source = f2py_sources[0]
+            target_file = f2py_targets[source]
+            target_dir = os.path.dirname(target_file) or '.'
+            depends = [source] + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py: %s" % (source))
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options
+                                    + ['--build-dir', target_dir, source])
+            else:
+                log.debug("  skipping '%s' f2py interface (up-to-date)" % (source))
+        else:
+            #XXX TODO: --inplace support for sdist command
+            if is_sequence(extension):
+                name = extension[0]
+            else: name = extension.name
+            target_dir = os.path.join(*([self.build_src]\
+                                        +name.split('.')[:-1]))
+            target_file = os.path.join(target_dir, ext_name + 'module.c')
+            new_sources.append(target_file)
+            depends = f_sources + extension.depends
+            if (self.force or newer_group(depends, target_file, 'newer')) \
+                   and not skip_f2py:
+                log.info("f2py:> %s" % (target_file))
+                self.mkpath(target_dir)
+                import numpy.f2py
+                numpy.f2py.run_main(f2py_options + ['--lower',
+                                                '--build-dir', target_dir]+\
+                                ['-m', ext_name]+f_sources)
+            else:
+                log.debug("  skipping f2py fortran files for '%s' (up-to-date)"\
+                          % (target_file))
+
+        if not os.path.isfile(target_file):
+            raise DistutilsError("f2py target file %r not generated" % (target_file,))
+
+        target_c = os.path.join(self.build_src, 'fortranobject.c')
+        target_h = os.path.join(self.build_src, 'fortranobject.h')
+        log.info("  adding '%s' to sources." % (target_c))
+        new_sources.append(target_c)
+        if self.build_src not in extension.include_dirs:
+            log.info("  adding '%s' to include_dirs." \
+                     % (self.build_src))
+            extension.include_dirs.append(self.build_src)
+
+        if not skip_f2py:
+            import numpy.f2py
+            d = os.path.dirname(numpy.f2py.__file__)
+            source_c = os.path.join(d, 'src', 'fortranobject.c')
+            source_h = os.path.join(d, 'src', 'fortranobject.h')
+            if newer(source_c, target_c) or newer(source_h, target_h):
+                self.mkpath(os.path.dirname(target_c))
+                self.copy_file(source_c, target_c)
+                self.copy_file(source_h, target_h)
+        else:
+            if not os.path.isfile(target_c):
+                raise DistutilsSetupError("f2py target_c file %r not found" % (target_c,))
+            if not os.path.isfile(target_h):
+                raise DistutilsSetupError("f2py target_h file %r not found" % (target_h,))
+
+        for name_ext in ['-f2pywrappers.f', '-f2pywrappers2.f90']:
+            filename = os.path.join(target_dir, ext_name + name_ext)
+            if os.path.isfile(filename):
+                log.info("  adding '%s' to sources." % (filename))
+                f_sources.append(filename)
+
+        return new_sources + f_sources
+
+    def swig_sources(self, sources, extension):
+        # Assuming SWIG 1.3.14 or later. See compatibility note in
+        #   http://www.swig.org/Doc1.3/Python.html#Python_nn6
+
+        new_sources = []
+        swig_sources = []
+        swig_targets = {}
+        target_dirs = []
+        py_files = []     # swig generated .py files
+        target_ext = '.c'
+        if '-c++' in extension.swig_opts:
+            typ = 'c++'
+            is_cpp = True
+            extension.swig_opts.remove('-c++')
+        elif self.swig_cpp:
+            typ = 'c++'
+            is_cpp = True
+        else:
+            typ = None
+            is_cpp = False
+        skip_swig = 0
+        ext_name = extension.name.split('.')[-1]
+
+        for source in sources:
+            (base, ext) = os.path.splitext(source)
+            if ext == '.i': # SWIG interface file
+                # the code below assumes that the sources list
+                # contains not more than one .i SWIG interface file
+                if self.inplace:
+                    target_dir = os.path.dirname(base)
+                    py_target_dir = self.ext_target_dir
+                else:
+                    target_dir = appendpath(self.build_src, os.path.dirname(base))
+                    py_target_dir = target_dir
+                if os.path.isfile(source):
+                    name = get_swig_modulename(source)
+                    if name != ext_name[1:]:
+                        raise DistutilsSetupError(
+                            'mismatch of extension names: %s provides %r'
+                            ' but expected %r' % (source, name, ext_name[1:]))
+                    if typ is None:
+                        typ = get_swig_target(source)
+                        is_cpp = typ=='c++'
+                    else:
+                        typ2 = get_swig_target(source)
+                        if typ2 is None:
+                            log.warn('source %r does not define swig target, assuming %s swig target' \
+                                     % (source, typ))
+                        elif typ!=typ2:
+                            log.warn('expected %r but source %r defines %r swig target' \
+                                     % (typ, source, typ2))
+                            if typ2=='c++':
+                                log.warn('resetting swig target to c++ (some targets may have .c extension)')
+                                is_cpp = True
+                            else:
+                                log.warn('assuming that %r has c++ swig target' % (source))
+                    if is_cpp:
+                        target_ext = '.cpp'
+                    target_file = os.path.join(target_dir, '%s_wrap%s' \
+                                               % (name, target_ext))
+                else:
+                    log.warn('  source %s does not exist: skipping swig\'ing.' \
+                             % (source))
+                    name = ext_name[1:]
+                    skip_swig = 1
+                    target_file = _find_swig_target(target_dir, name)
+                    if not os.path.isfile(target_file):
+                        log.warn('  target %s does not exist:\n   '\
+                                 'Assuming %s_wrap.{c,cpp} was generated with '\
+                                 '"build_src --inplace" command.' \
+                                 % (target_file, name))
+                        target_dir = os.path.dirname(base)
+                        target_file = _find_swig_target(target_dir, name)
+                        if not os.path.isfile(target_file):
+                            raise DistutilsSetupError("%r missing" % (target_file,))
+                        log.warn('   Yes! Using %r as up-to-date target.' \
+                                 % (target_file))
+                target_dirs.append(target_dir)
+                new_sources.append(target_file)
+                py_files.append(os.path.join(py_target_dir, name+'.py'))
+                swig_sources.append(source)
+                swig_targets[source] = new_sources[-1]
+            else:
+                new_sources.append(source)
+
+        if not swig_sources:
+            return new_sources
+
+        if skip_swig:
+            return new_sources + py_files
+
+        for d in target_dirs:
+            self.mkpath(d)
+
+        swig = self.swig or self.find_swig()
+        swig_cmd = [swig, "-python"] + extension.swig_opts
+        if is_cpp:
+            swig_cmd.append('-c++')
+        for d in extension.include_dirs:
+            swig_cmd.append('-I'+d)
+        for source in swig_sources:
+            target = swig_targets[source]
+            depends = [source] + extension.depends
+            if self.force or newer_group(depends, target, 'newer'):
+                log.info("%s: %s" % (os.path.basename(swig) \
+                                     + (is_cpp and '++' or ''), source))
+                self.spawn(swig_cmd + self.swig_opts \
+                           + ["-o", target, '-outdir', py_target_dir, source])
+            else:
+                log.debug("  skipping '%s' swig interface (up-to-date)" \
+                         % (source))
+
+        return new_sources + py_files
+
+_f_pyf_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+_header_ext_match = re.compile(r'.*[.](inc|h|hpp)\Z', re.I).match
+
+#### SWIG related auxiliary functions ####
+_swig_module_name_match = re.compile(r'\s*%module\s*(.*\(\s*package\s*=\s*"(?P<package>[\w_]+)".*\)|)\s*(?P<name>[\w_]+)',
+                                     re.I).match
+_has_c_header = re.compile(r'-[*]-\s*c\s*-[*]-', re.I).search
+_has_cpp_header = re.compile(r'-[*]-\s*c[+][+]\s*-[*]-', re.I).search
+
+def get_swig_target(source):
+    f = open(source, 'r')
+    result = None
+    line = f.readline()
+    if _has_cpp_header(line):
+        result = 'c++'
+    if _has_c_header(line):
+        result = 'c'
+    f.close()
+    return result
+
+def get_swig_modulename(source):
+    f = open(source, 'r')
+    name = None
+    for line in f:
+        m = _swig_module_name_match(line)
+        if m:
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+def _find_swig_target(target_dir, name):
+    for ext in ['.cpp', '.c']:
+        target = os.path.join(target_dir, '%s_wrap%s' % (name, ext))
+        if os.path.isfile(target):
+            break
+    return target
+
+#### F2PY related auxiliary functions ####
+
+_f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]+)',
+                                re.I).match
+_f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]*?'\
+                                     '__user__[\w_]*)', re.I).match
+
+def get_f2py_modulename(source):
+    name = None
+    f = open(source)
+    for line in f:
+        m = _f2py_module_name_match(line)
+        if m:
+            if _f2py_user_module_name_match(line): # skip *__user__* names
+                continue
+            name = m.group('name')
+            break
+    f.close()
+    return name
+
+##########################################
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.py
new file mode 100644
index 0000000000..4f20fc0de1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.py
@@ -0,0 +1,437 @@
+# Added Fortran compiler support to config. Currently useful only for
+# try_compile call. try_run works but is untested for most of Fortran
+# compilers (they must define linker_exe first).
+# Pearu Peterson
+from __future__ import division, absolute_import, print_function
+
+import os, signal
+import warnings
+import sys
+
+from distutils.command.config import config as old_config
+from distutils.command.config import LANG_EXT
+from distutils import log
+from distutils.file_util import copy_file
+from distutils.ccompiler import CompileError, LinkError
+import distutils
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.mingw32ccompiler import generate_manifest
+from numpy.distutils.command.autodist import (check_gcc_function_attribute,
+                                              check_gcc_variable_attribute,
+                                              check_inline,
+                                              check_restrict,
+                                              check_compiler_gcc4)
+from numpy.distutils.compat import get_exception
+
+LANG_EXT['f77'] = '.f'
+LANG_EXT['f90'] = '.f90'
+
+class config(old_config):
+    old_config.user_options += [
+        ('fcompiler=', None, "specify the Fortran compiler type"),
+        ]
+
+    def initialize_options(self):
+        self.fcompiler = None
+        old_config.initialize_options(self)
+
+    def _check_compiler (self):
+        old_config._check_compiler(self)
+        from numpy.distutils.fcompiler import FCompiler, new_fcompiler
+
+        if sys.platform == 'win32' and (self.compiler.compiler_type in
+                                        ('msvc', 'intelw', 'intelemw')):
+            # XXX: hack to circumvent a python 2.6 bug with msvc9compiler:
+            # initialize call query_vcvarsall, which throws an IOError, and
+            # causes an error along the way without much information. We try to
+            # catch it here, hoping it is early enough, and print an helpful
+            # message instead of Error: None.
+            if not self.compiler.initialized:
+                try:
+                    self.compiler.initialize()
+                except IOError:
+                    e = get_exception()
+                    msg = """\
+Could not initialize compiler instance: do you have Visual Studio
+installed?  If you are trying to build with MinGW, please use "python setup.py
+build -c mingw32" instead.  If you have Visual Studio installed, check it is
+correctly installed, and the right version (VS 2008 for python 2.6, 2.7 and 3.2,
+VS 2010 for >= 3.3).
+
+Original exception was: %s, and the Compiler class was %s
+============================================================================""" \
+                        % (e, self.compiler.__class__.__name__)
+                    print ("""\
+============================================================================""")
+                    raise distutils.errors.DistutilsPlatformError(msg)
+
+            # After MSVC is initialized, add an explicit /MANIFEST to linker
+            # flags.  See issues gh-4245 and gh-4101 for details.  Also
+            # relevant are issues 4431 and 16296 on the Python bug tracker.
+            from distutils import msvc9compiler
+            if msvc9compiler.get_build_version() >= 10:
+                for ldflags in [self.compiler.ldflags_shared,
+                                self.compiler.ldflags_shared_debug]:
+                    if '/MANIFEST' not in ldflags:
+                        ldflags.append('/MANIFEST')
+
+        if not isinstance(self.fcompiler, FCompiler):
+            self.fcompiler = new_fcompiler(compiler=self.fcompiler,
+                                           dry_run=self.dry_run, force=1,
+                                           c_compiler=self.compiler)
+            if self.fcompiler is not None:
+                self.fcompiler.customize(self.distribution)
+                if self.fcompiler.get_version():
+                    self.fcompiler.customize_cmd(self)
+                    self.fcompiler.show_customization()
+
+    def _wrap_method(self, mth, lang, args):
+        from distutils.ccompiler import CompileError
+        from distutils.errors import DistutilsExecError
+        save_compiler = self.compiler
+        if lang in ['f77', 'f90']:
+            self.compiler = self.fcompiler
+        try:
+            ret = mth(*((self,)+args))
+        except (DistutilsExecError, CompileError):
+            msg = str(get_exception())
+            self.compiler = save_compiler
+            raise CompileError
+        self.compiler = save_compiler
+        return ret
+
+    def _compile (self, body, headers, include_dirs, lang):
+        return self._wrap_method(old_config._compile, lang,
+                                 (body, headers, include_dirs, lang))
+
+    def _link (self, body,
+               headers, include_dirs,
+               libraries, library_dirs, lang):
+        if self.compiler.compiler_type=='msvc':
+            libraries = (libraries or [])[:]
+            library_dirs = (library_dirs or [])[:]
+            if lang in ['f77', 'f90']:
+                lang = 'c' # always use system linker when using MSVC compiler
+                if self.fcompiler:
+                    for d in self.fcompiler.library_dirs or []:
+                        # correct path when compiling in Cygwin but with
+                        # normal Win Python
+                        if d.startswith('/usr/lib'):
+                            s, o = exec_command(['cygpath', '-w', d],
+                                               use_tee=False)
+                            if not s: d = o
+                        library_dirs.append(d)
+                    for libname in self.fcompiler.libraries or []:
+                        if libname not in libraries:
+                            libraries.append(libname)
+            for libname in libraries:
+                if libname.startswith('msvc'): continue
+                fileexists = False
+                for libdir in library_dirs or []:
+                    libfile = os.path.join(libdir, '%s.lib' % (libname))
+                    if os.path.isfile(libfile):
+                        fileexists = True
+                        break
+                if fileexists: continue
+                # make g77-compiled static libs available to MSVC
+                fileexists = False
+                for libdir in library_dirs:
+                    libfile = os.path.join(libdir, 'lib%s.a' % (libname))
+                    if os.path.isfile(libfile):
+                        # copy libname.a file to name.lib so that MSVC linker
+                        # can find it
+                        libfile2 = os.path.join(libdir, '%s.lib' % (libname))
+                        copy_file(libfile, libfile2)
+                        self.temp_files.append(libfile2)
+                        fileexists = True
+                        break
+                if fileexists: continue
+                log.warn('could not find library %r in directories %s' \
+                         % (libname, library_dirs))
+        elif self.compiler.compiler_type == 'mingw32':
+            generate_manifest(self)
+        return self._wrap_method(old_config._link, lang,
+                                 (body, headers, include_dirs,
+                                  libraries, library_dirs, lang))
+
+    def check_header(self, header, include_dirs=None, library_dirs=None, lang='c'):
+        self._check_compiler()
+        return self.try_compile(
+                "/* we need a dummy line to make distutils happy */",
+                [header], include_dirs)
+
+    def check_decl(self, symbol,
+                   headers=None, include_dirs=None):
+        self._check_compiler()
+        body = """
+int main(void)
+{
+#ifndef %s
+    (void) %s;
+#endif
+    ;
+    return 0;
+}""" % (symbol, symbol)
+
+        return self.try_compile(body, headers, include_dirs)
+
+    def check_macro_true(self, symbol,
+                         headers=None, include_dirs=None):
+        self._check_compiler()
+        body = """
+int main(void)
+{
+#if %s
+#else
+#error false or undefined macro
+#endif
+    ;
+    return 0;
+}""" % (symbol,)
+
+        return self.try_compile(body, headers, include_dirs)
+
+    def check_type(self, type_name, headers=None, include_dirs=None,
+            library_dirs=None):
+        """Check type availability. Return True if the type can be compiled,
+        False otherwise"""
+        self._check_compiler()
+
+        # First check the type can be compiled
+        body = r"""
+int main(void) {
+  if ((%(name)s *) 0)
+    return 0;
+  if (sizeof (%(name)s))
+    return 0;
+}
+""" % {'name': type_name}
+
+        st = False
+        try:
+            try:
+                self._compile(body % {'type': type_name},
+                        headers, include_dirs, 'c')
+                st = True
+            except distutils.errors.CompileError:
+                st = False
+        finally:
+            self._clean()
+
+        return st
+
+    def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None, expected=None):
+        """Check size of a given type."""
+        self._check_compiler()
+
+        # First check the type can be compiled
+        body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+        self._compile(body % {'type': type_name},
+                headers, include_dirs, 'c')
+        self._clean()
+
+        if expected:
+            body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) == %(size)s)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+            for size in expected:
+                try:
+                    self._compile(body % {'type': type_name, 'size': size},
+                            headers, include_dirs, 'c')
+                    self._clean()
+                    return size
+                except CompileError:
+                    pass
+
+        # this fails to *compile* if size > sizeof(type)
+        body = r"""
+typedef %(type)s npy_check_sizeof_type;
+int main (void)
+{
+    static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)];
+    test_array [0] = 0
+
+    ;
+    return 0;
+}
+"""
+
+        # The principle is simple: we first find low and high bounds of size
+        # for the type, where low/high are looked up on a log scale. Then, we
+        # do a binary search to find the exact size between low and high
+        low = 0
+        mid = 0
+        while True:
+            try:
+                self._compile(body % {'type': type_name, 'size': mid},
+                        headers, include_dirs, 'c')
+                self._clean()
+                break
+            except CompileError:
+                #log.info("failure to test for bound %d" % mid)
+                low = mid + 1
+                mid = 2 * mid + 1
+
+        high = mid
+        # Binary search:
+        while low != high:
+            mid = (high - low) // 2 + low
+            try:
+                self._compile(body % {'type': type_name, 'size': mid},
+                        headers, include_dirs, 'c')
+                self._clean()
+                high = mid
+            except CompileError:
+                low = mid + 1
+        return low
+
+    def check_func(self, func,
+                   headers=None, include_dirs=None,
+                   libraries=None, library_dirs=None,
+                   decl=False, call=False, call_args=None):
+        # clean up distutils's config a bit: add void to main(), and
+        # return a value.
+        self._check_compiler()
+        body = []
+        if decl:
+            if type(decl) == str:
+                body.append(decl)
+            else:
+                body.append("int %s (void);" % func)
+        # Handle MSVC intrinsics: force MS compiler to make a function call.
+        # Useful to test for some functions when built with optimization on, to
+        # avoid build error because the intrinsic and our 'fake' test
+        # declaration do not match.
+        body.append("#ifdef _MSC_VER")
+        body.append("#pragma function(%s)" % func)
+        body.append("#endif")
+        body.append("int main (void) {")
+        if call:
+            if call_args is None:
+                call_args = ''
+            body.append("  %s(%s);" % (func, call_args))
+        else:
+            body.append("  %s;" % func)
+        body.append("  return 0;")
+        body.append("}")
+        body = '\n'.join(body) + "\n"
+
+        return self.try_link(body, headers, include_dirs,
+                             libraries, library_dirs)
+
+    def check_funcs_once(self, funcs,
+                   headers=None, include_dirs=None,
+                   libraries=None, library_dirs=None,
+                   decl=False, call=False, call_args=None):
+        """Check a list of functions at once.
+
+        This is useful to speed up things, since all the functions in the funcs
+        list will be put in one compilation unit.
+
+        Arguments
+        ---------
+        funcs : seq
+            list of functions to test
+        include_dirs : seq
+            list of header paths
+        libraries : seq
+            list of libraries to link the code snippet to
+        libraru_dirs : seq
+            list of library paths
+        decl : dict
+            for every (key, value), the declaration in the value will be
+            used for function in key. If a function is not in the
+            dictionay, no declaration will be used.
+        call : dict
+            for every item (f, value), if the value is True, a call will be
+            done to the function f.
+        """
+        self._check_compiler()
+        body = []
+        if decl:
+            for f, v in decl.items():
+                if v:
+                    body.append("int %s (void);" % f)
+
+        # Handle MS intrinsics. See check_func for more info.
+        body.append("#ifdef _MSC_VER")
+        for func in funcs:
+            body.append("#pragma function(%s)" % func)
+        body.append("#endif")
+
+        body.append("int main (void) {")
+        if call:
+            for f in funcs:
+                if f in call and call[f]:
+                    if not (call_args and f in call_args and call_args[f]):
+                        args = ''
+                    else:
+                        args = call_args[f]
+                    body.append("  %s(%s);" % (f, args))
+                else:
+                    body.append("  %s;" % f)
+        else:
+            for f in funcs:
+                body.append("  %s;" % f)
+        body.append("  return 0;")
+        body.append("}")
+        body = '\n'.join(body) + "\n"
+
+        return self.try_link(body, headers, include_dirs,
+                             libraries, library_dirs)
+
+    def check_inline(self):
+        """Return the inline keyword recognized by the compiler, empty string
+        otherwise."""
+        return check_inline(self)
+
+    def check_restrict(self):
+        """Return the restrict keyword recognized by the compiler, empty string
+        otherwise."""
+        return check_restrict(self)
+
+    def check_compiler_gcc4(self):
+        """Return True if the C compiler is gcc >= 4."""
+        return check_compiler_gcc4(self)
+
+    def check_gcc_function_attribute(self, attribute, name):
+        return check_gcc_function_attribute(self, attribute, name)
+
+    def check_gcc_variable_attribute(self, attribute):
+        return check_gcc_variable_attribute(self, attribute)
+
+
+class GrabStdout(object):
+
+    def __init__(self):
+        self.sys_stdout = sys.stdout
+        self.data = ''
+        sys.stdout = self
+
+    def write (self, data):
+        self.sys_stdout.write(data)
+        self.data += data
+
+    def flush (self):
+        self.sys_stdout.flush()
+
+    def restore(self):
+        sys.stdout = self.sys_stdout
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
new file mode 100644
index 0000000000..5e638feccc
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
@@ -0,0 +1,125 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.core import Command
+from numpy.distutils import log
+
+#XXX: Linker flags
+
+def show_fortran_compilers(_cache=[]):
+    # Using cache to prevent infinite recursion
+    if _cache: return
+    _cache.append(1)
+    from numpy.distutils.fcompiler import show_fcompilers
+    import distutils.core
+    dist = distutils.core._setup_distribution
+    show_fcompilers(dist)
+
+class config_fc(Command):
+    """ Distutils command to hold user specified options
+    to Fortran compilers.
+
+    config_fc command is used by the FCompiler.customize() method.
+    """
+
+    description = "specify Fortran 77/Fortran 90 compiler information"
+
+    user_options = [
+        ('fcompiler=', None, "specify Fortran compiler type"),
+        ('f77exec=', None, "specify F77 compiler command"),
+        ('f90exec=', None, "specify F90 compiler command"),
+        ('f77flags=', None, "specify F77 compiler flags"),
+        ('f90flags=', None, "specify F90 compiler flags"),
+        ('opt=', None, "specify optimization flags"),
+        ('arch=', None, "specify architecture specific optimization flags"),
+        ('debug', 'g', "compile with debugging information"),
+        ('noopt', None, "compile without optimization"),
+        ('noarch', None, "compile without arch-dependent optimization"),
+        ]
+
+    help_options = [
+        ('help-fcompiler', None, "list available Fortran compilers",
+         show_fortran_compilers),
+        ]
+
+    boolean_options = ['debug', 'noopt', 'noarch']
+
+    def initialize_options(self):
+        self.fcompiler = None
+        self.f77exec = None
+        self.f90exec = None
+        self.f77flags = None
+        self.f90flags = None
+        self.opt = None
+        self.arch = None
+        self.debug = None
+        self.noopt = None
+        self.noarch = None
+
+    def finalize_options(self):
+        log.info('unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options')
+        build_clib = self.get_finalized_command('build_clib')
+        build_ext = self.get_finalized_command('build_ext')
+        config = self.get_finalized_command('config')
+        build = self.get_finalized_command('build')
+        cmd_list = [self, config, build_clib, build_ext, build]
+        for a in ['fcompiler']:
+            l = []
+            for c in cmd_list:
+                v = getattr(c, a)
+                if v is not None:
+                    if not isinstance(v, str): v = v.compiler_type
+                    if v not in l: l.append(v)
+            if not l: v1 = None
+            else: v1 = l[0]
+            if len(l)>1:
+                log.warn('  commands have different --%s options: %s'\
+                         ', using first in list as default' % (a, l))
+            if v1:
+                for c in cmd_list:
+                    if getattr(c, a) is None: setattr(c, a, v1)
+
+    def run(self):
+        # Do nothing.
+        return
+
+class config_cc(Command):
+    """ Distutils command to hold user specified options
+    to C/C++ compilers.
+    """
+
+    description = "specify C/C++ compiler information"
+
+    user_options = [
+        ('compiler=', None, "specify C/C++ compiler type"),
+        ]
+
+    def initialize_options(self):
+        self.compiler = None
+
+    def finalize_options(self):
+        log.info('unifing config_cc, config, build_clib, build_ext, build commands --compiler options')
+        build_clib = self.get_finalized_command('build_clib')
+        build_ext = self.get_finalized_command('build_ext')
+        config = self.get_finalized_command('config')
+        build = self.get_finalized_command('build')
+        cmd_list = [self, config, build_clib, build_ext, build]
+        for a in ['compiler']:
+            l = []
+            for c in cmd_list:
+                v = getattr(c, a)
+                if v is not None:
+                    if not isinstance(v, str): v = v.compiler_type
+                    if v not in l: l.append(v)
+            if not l: v1 = None
+            else: v1 = l[0]
+            if len(l)>1:
+                log.warn('  commands have different --%s options: %s'\
+                         ', using first in list as default' % (a, l))
+            if v1:
+                for c in cmd_list:
+                    if getattr(c, a) is None: setattr(c, a, v1)
+        return
+
+    def run(self):
+        # Do nothing.
+        return
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.py
new file mode 100644
index 0000000000..1410ab2a00
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.py
@@ -0,0 +1,17 @@
+""" Override the develop command from setuptools so we can ensure that our
+generated files (from build_src or build_scripts) are properly converted to real
+files with filenames.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from setuptools.command.develop import develop as old_develop
+
+class develop(old_develop):
+    __doc__ = old_develop.__doc__
+    def install_for_development(self):
+        # Build sources in-place, too.
+        self.reinitialize_command('build_src', inplace=1)
+        # Make sure scripts are built.
+        self.run_command('build_scripts')
+        old_develop.install_for_development(self)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
new file mode 100644
index 0000000000..972a27df38
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
@@ -0,0 +1,19 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from setuptools.command.egg_info import egg_info as _egg_info
+
+class egg_info(_egg_info):
+    def run(self):
+        if 'sdist' in sys.argv:
+            import warnings
+            warnings.warn("`build_src` is being run, this may lead to missing "
+                          "files in your sdist!  See numpy issue gh-7127 for "
+                          "details", UserWarning)
+
+        # We need to ensure that build_src has been executed in order to give
+        # setuptools' egg_info command real filenames instead of functions which
+        # generate files.
+        self.run_command("build_src")
+        _egg_info.run(self)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.py
new file mode 100644
index 0000000000..a1dd47755c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.py
@@ -0,0 +1,82 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+if 'setuptools' in sys.modules:
+    import setuptools.command.install as old_install_mod
+    have_setuptools = True
+else:
+    import distutils.command.install as old_install_mod
+    have_setuptools = False
+from distutils.file_util import write_file
+
+old_install = old_install_mod.install
+
+class install(old_install):
+
+    # Always run install_clib - the command is cheap, so no need to bypass it;
+    # but it's not run by setuptools -- so it's run again in install_data
+    sub_commands = old_install.sub_commands + [
+        ('install_clib', lambda x: True)
+    ]
+
+    def finalize_options (self):
+        old_install.finalize_options(self)
+        self.install_lib = self.install_libbase
+
+    def setuptools_run(self):
+        """ The setuptools version of the .run() method.
+
+        We must pull in the entire code so we can override the level used in the
+        _getframe() call since we wrap this call by one more level.
+        """
+        from distutils.command.install import install as distutils_install
+
+        # Explicit request for old-style install?  Just do it
+        if self.old_and_unmanageable or self.single_version_externally_managed:
+            return distutils_install.run(self)
+
+        # Attempt to detect whether we were called from setup() or by another
+        # command.  If we were called by setup(), our caller will be the
+        # 'run_command' method in 'distutils.dist', and *its* caller will be
+        # the 'run_commands' method.  If we were called any other way, our
+        # immediate caller *might* be 'run_command', but it won't have been
+        # called by 'run_commands'.  This is slightly kludgy, but seems to
+        # work.
+        #
+        caller = sys._getframe(3)
+        caller_module = caller.f_globals.get('__name__', '')
+        caller_name = caller.f_code.co_name
+
+        if caller_module != 'distutils.dist' or caller_name!='run_commands':
+            # We weren't called from the command line or setup(), so we
+            # should run in backward-compatibility mode to support bdist_*
+            # commands.
+            distutils_install.run(self)
+        else:
+            self.do_egg_install()
+
+    def run(self):
+        if not have_setuptools:
+            r = old_install.run(self)
+        else:
+            r = self.setuptools_run()
+        if self.record:
+            # bdist_rpm fails when INSTALLED_FILES contains
+            # paths with spaces. Such paths must be enclosed
+            # with double-quotes.
+            f = open(self.record, 'r')
+            lines = []
+            need_rewrite = False
+            for l in f:
+                l = l.rstrip()
+                if ' ' in l:
+                    need_rewrite = True
+                    l = '"%s"' % (l)
+                lines.append(l)
+            f.close()
+            if need_rewrite:
+                self.execute(write_file,
+                             (self.record, lines),
+                             "re-writing list of installed files to '%s'" %
+                             self.record)
+        return r
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
new file mode 100644
index 0000000000..662aa00bda
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
@@ -0,0 +1,39 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.core import Command
+from distutils.ccompiler import new_compiler
+from numpy.distutils.misc_util import get_cmd
+
+class install_clib(Command):
+    description = "Command to install installable C libraries"
+
+    user_options = []
+
+    def initialize_options(self):
+        self.install_dir = None
+        self.outfiles = []
+
+    def finalize_options(self):
+        self.set_undefined_options('install', ('install_lib', 'install_dir'))
+
+    def run (self):
+        build_clib_cmd = get_cmd("build_clib")
+        build_dir = build_clib_cmd.build_clib
+
+        # We need the compiler to get the library name -> filename association
+        if not build_clib_cmd.compiler:
+            compiler = new_compiler(compiler=None)
+            compiler.customize(self.distribution)
+        else:
+            compiler = build_clib_cmd.compiler
+
+        for l in self.distribution.installed_libraries:
+            target_dir = os.path.join(self.install_dir, l.target_dir)
+            name = compiler.library_filename(l.name)
+            source = os.path.join(build_dir, name)
+            self.mkpath(target_dir)
+            self.outfiles.append(self.copy_file(source, target_dir)[0])
+
+    def get_outputs(self):
+        return self.outfiles
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
new file mode 100644
index 0000000000..996cf7e401
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
@@ -0,0 +1,26 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+have_setuptools = ('setuptools' in sys.modules)
+
+from distutils.command.install_data import install_data as old_install_data
+
+#data installer with improved intelligence over distutils
+#data files are copied into the project directory instead
+#of willy-nilly
+class install_data (old_install_data):
+
+    def run(self):
+        old_install_data.run(self)
+
+        if have_setuptools:
+            # Run install_clib again, since setuptools does not run sub-commands
+            # of install automatically
+            self.run_command('install_clib')
+
+    def finalize_options (self):
+        self.set_undefined_options('install',
+                                   ('install_lib', 'install_dir'),
+                                   ('root', 'root'),
+                                   ('force', 'force'),
+                                  )
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
new file mode 100644
index 0000000000..f3f58aa287
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
@@ -0,0 +1,27 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.command.install_headers import install_headers as old_install_headers
+
+class install_headers (old_install_headers):
+
+    def run (self):
+        headers = self.distribution.headers
+        if not headers:
+            return
+
+        prefix = os.path.dirname(self.install_dir)
+        for header in headers:
+            if isinstance(header, tuple):
+                # Kind of a hack, but I don't know where else to change this...
+                if header[0] == 'numpy.core':
+                    header = ('numpy', header[1])
+                    if os.path.splitext(header[1])[1] == '.inc':
+                        continue
+                d = os.path.join(*([prefix]+header[0].split('.')))
+                header = header[1]
+            else:
+                d = self.install_dir
+            self.mkpath(d)
+            (out, _) = self.copy_file(header, d)
+            self.outfiles.append(out)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
new file mode 100644
index 0000000000..bfaab1c8ff
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
@@ -0,0 +1,29 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+if 'setuptools' in sys.modules:
+    from setuptools.command.sdist import sdist as old_sdist
+else:
+    from distutils.command.sdist import sdist as old_sdist
+
+from numpy.distutils.misc_util import get_data_files
+
+class sdist(old_sdist):
+
+    def add_defaults (self):
+        old_sdist.add_defaults(self)
+
+        dist = self.distribution
+
+        if dist.has_data_files():
+            for data in dist.data_files:
+                self.filelist.extend(get_data_files(data))
+
+        if dist.has_headers():
+            headers = []
+            for h in dist.headers:
+                if isinstance(h, str): headers.append(h)
+                else: headers.append(h[1])
+            self.filelist.extend(headers)
+
+        return
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/compat.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/compat.py
new file mode 100644
index 0000000000..9a81cd392f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/compat.py
@@ -0,0 +1,10 @@
+"""Small modules to cope with python 2 vs 3 incompatibilities inside
+numpy.distutils
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+def get_exception():
+    return sys.exc_info()[1]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.py
new file mode 100644
index 0000000000..43adb16360
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.py
@@ -0,0 +1,337 @@
+#!/usr/bin/python2
+"""
+takes templated file .xxx.src and produces .xxx file  where .xxx is
+.i or .c or .h, using the following template rules
+
+/**begin repeat  -- on a line by itself marks the start of a repeated code
+                    segment
+/**end repeat**/ -- on a line by itself marks it's end
+
+After the /**begin repeat and before the */, all the named templates are placed
+these should all have the same number of replacements
+
+Repeat blocks can be nested, with each nested block labeled with its depth,
+i.e.
+/**begin repeat1
+ *....
+ */
+/**end repeat1**/
+
+When using nested loops, you can optionally exlude particular
+combinations of the variables using (inside the comment portion of the inner loop):
+
+ :exclude: var1=value1, var2=value2, ...
+
+This will exlude the pattern where var1 is value1 and var2 is value2 when
+the result is being generated.
+
+
+In the main body each replace will use one entry from the list of named replacements
+
+ Note that all #..# forms in a block must have the same number of
+   comma-separated entries.
+
+Example:
+
+    An input file containing
+
+        /**begin repeat
+         * #a = 1,2,3#
+         * #b = 1,2,3#
+         */
+
+        /**begin repeat1
+         * #c = ted, jim#
+         */
+        @a@, @b@, @c@
+        /**end repeat1**/
+
+        /**end repeat**/
+
+    produces
+
+        line 1 "template.c.src"
+
+        /*
+         *********************************************************************
+         **       This file was autogenerated from a template  DO NOT EDIT!!**
+         **       Changes should be made to the original source (.src) file **
+         *********************************************************************
+         */
+
+        #line 9
+        1, 1, ted
+
+        #line 9
+        1, 1, jim
+
+        #line 9
+        2, 2, ted
+
+        #line 9
+        2, 2, jim
+
+        #line 9
+        3, 3, ted
+
+        #line 9
+        3, 3, jim
+
+"""
+from __future__ import division, absolute_import, print_function
+
+
+__all__ = ['process_str', 'process_file']
+
+import os
+import sys
+import re
+
+from numpy.distutils.compat import get_exception
+
+# names for replacement that are already global.
+global_names = {}
+
+# header placed at the front of head processed file
+header =\
+"""
+/*
+ *****************************************************************************
+ **       This file was autogenerated from a template  DO NOT EDIT!!!!      **
+ **       Changes should be made to the original source (.src) file         **
+ *****************************************************************************
+ */
+
+"""
+# Parse string for repeat loops
+def parse_structure(astr, level):
+    """
+    The returned line number is from the beginning of the string, starting
+    at zero. Returns an empty list if no loops found.
+
+    """
+    if level == 0 :
+        loopbeg = "/**begin repeat"
+        loopend = "/**end repeat**/"
+    else :
+        loopbeg = "/**begin repeat%d" % level
+        loopend = "/**end repeat%d**/" % level
+
+    ind = 0
+    line = 0
+    spanlist = []
+    while True:
+        start = astr.find(loopbeg, ind)
+        if start == -1:
+            break
+        start2 = astr.find("*/", start)
+        start2 = astr.find("\n", start2)
+        fini1 = astr.find(loopend, start2)
+        fini2 = astr.find("\n", fini1)
+        line += astr.count("\n", ind, start2+1)
+        spanlist.append((start, start2+1, fini1, fini2+1, line))
+        line += astr.count("\n", start2+1, fini2)
+        ind = fini2
+    spanlist.sort()
+    return spanlist
+
+
+def paren_repl(obj):
+    torep = obj.group(1)
+    numrep = obj.group(2)
+    return ','.join([torep]*int(numrep))
+
+parenrep = re.compile(r"[(]([^)]*)[)]\*(\d+)")
+plainrep = re.compile(r"([^*]+)\*(\d+)")
+def parse_values(astr):
+    # replaces all occurrences of '(a,b,c)*4' in astr
+    # with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate
+    # empty values, i.e., ()*4 yields ',,,'. The result is
+    # split at ',' and a list of values returned.
+    astr = parenrep.sub(paren_repl, astr)
+    # replaces occurences of xxx*3 with xxx, xxx, xxx
+    astr = ','.join([plainrep.sub(paren_repl, x.strip())
+                     for x in astr.split(',')])
+    return astr.split(',')
+
+
+stripast = re.compile(r"\n\s*\*?")
+named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#")
+exclude_vars_re = re.compile(r"(\w*)=(\w*)")
+exclude_re = re.compile(":exclude:")
+def parse_loop_header(loophead) :
+    """Find all named replacements in the header
+
+    Returns a list of dictionaries, one for each loop iteration,
+    where each key is a name to be substituted and the corresponding
+    value is the replacement string.
+
+    Also return a list of exclusions.  The exclusions are dictionaries
+     of key value pairs. There can be more than one exclusion.
+     [{'var1':'value1', 'var2', 'value2'[,...]}, ...]
+
+    """
+    # Strip out '\n' and leading '*', if any, in continuation lines.
+    # This should not effect code previous to this change as
+    # continuation lines were not allowed.
+    loophead = stripast.sub("", loophead)
+    # parse out the names and lists of values
+    names = []
+    reps = named_re.findall(loophead)
+    nsub = None
+    for rep in reps:
+        name = rep[0]
+        vals = parse_values(rep[1])
+        size = len(vals)
+        if nsub is None :
+            nsub = size
+        elif nsub != size :
+            msg = "Mismatch in number of values:\n%s = %s" % (name, vals)
+            raise ValueError(msg)
+        names.append((name, vals))
+
+
+    # Find any exclude variables
+    excludes = []
+
+    for obj in exclude_re.finditer(loophead):
+        span = obj.span()
+        # find next newline
+        endline = loophead.find('\n', span[1])
+        substr = loophead[span[1]:endline]
+        ex_names = exclude_vars_re.findall(substr)
+        excludes.append(dict(ex_names))
+
+    # generate list of dictionaries, one for each template iteration
+    dlist = []
+    if nsub is None :
+        raise ValueError("No substitution variables found")
+    for i in range(nsub) :
+        tmp = {}
+        for name, vals in names :
+            tmp[name] = vals[i]
+        dlist.append(tmp)
+    return dlist
+
+replace_re = re.compile(r"@([\w]+)@")
+def parse_string(astr, env, level, line) :
+    lineno = "#line %d\n" % line
+
+    # local function for string replacement, uses env
+    def replace(match):
+        name = match.group(1)
+        try :
+            val = env[name]
+        except KeyError:
+            msg = 'line %d: no definition of key "%s"'%(line, name)
+            raise ValueError(msg)
+        return val
+
+    code = [lineno]
+    struct = parse_structure(astr, level)
+    if struct :
+        # recurse over inner loops
+        oldend = 0
+        newlevel = level + 1
+        for sub in struct:
+            pref = astr[oldend:sub[0]]
+            head = astr[sub[0]:sub[1]]
+            text = astr[sub[1]:sub[2]]
+            oldend = sub[3]
+            newline = line + sub[4]
+            code.append(replace_re.sub(replace, pref))
+            try :
+                envlist = parse_loop_header(head)
+            except ValueError:
+                e = get_exception()
+                msg = "line %d: %s" % (newline, e)
+                raise ValueError(msg)
+            for newenv in envlist :
+                newenv.update(env)
+                newcode = parse_string(text, newenv, newlevel, newline)
+                code.extend(newcode)
+        suff = astr[oldend:]
+        code.append(replace_re.sub(replace, suff))
+    else :
+        # replace keys
+        code.append(replace_re.sub(replace, astr))
+    code.append('\n')
+    return ''.join(code)
+
+def process_str(astr):
+    code = [header]
+    code.extend(parse_string(astr, global_names, 0, 1))
+    return ''.join(code)
+
+
+include_src_re = re.compile(r"(\n|\A)#include\s*['\"]"
+                            r"(?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
+
+def resolve_includes(source):
+    d = os.path.dirname(source)
+    fid = open(source)
+    lines = []
+    for line in fid:
+        m = include_src_re.match(line)
+        if m:
+            fn = m.group('name')
+            if not os.path.isabs(fn):
+                fn = os.path.join(d, fn)
+            if os.path.isfile(fn):
+                print('Including file', fn)
+                lines.extend(resolve_includes(fn))
+            else:
+                lines.append(line)
+        else:
+            lines.append(line)
+    fid.close()
+    return lines
+
+def process_file(source):
+    lines = resolve_includes(source)
+    sourcefile = os.path.normcase(source).replace("\\", "\\\\")
+    try:
+        code = process_str(''.join(lines))
+    except ValueError:
+        e = get_exception()
+        raise ValueError('In "%s" loop at %s' % (sourcefile, e))
+    return '#line 1 "%s"\n%s' % (sourcefile, code)
+
+
+def unique_key(adict):
+    # this obtains a unique key given a dictionary
+    # currently it works by appending together n of the letters of the
+    #   current keys and increasing n until a unique key is found
+    # -- not particularly quick
+    allkeys = list(adict.keys())
+    done = False
+    n = 1
+    while not done:
+        newkey = "".join([x[:n] for x in allkeys])
+        if newkey in allkeys:
+            n += 1
+        else:
+            done = True
+    return newkey
+
+
+if __name__ == "__main__":
+
+    try:
+        file = sys.argv[1]
+    except IndexError:
+        fid = sys.stdin
+        outfile = sys.stdout
+    else:
+        fid = open(file, 'r')
+        (base, ext) = os.path.splitext(file)
+        newname = base
+        outfile = open(newname, 'w')
+
+    allstr = fid.read()
+    try:
+        writestr = process_str(allstr)
+    except ValueError:
+        e = get_exception()
+        raise ValueError("In %s loop at %s" % (file, e))
+    outfile.write(writestr)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/core.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/core.py
new file mode 100644
index 0000000000..3f0fd464a0
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/core.py
@@ -0,0 +1,210 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from distutils.core import *
+
+if 'setuptools' in sys.modules:
+    have_setuptools = True
+    from setuptools import setup as old_setup
+    # easy_install imports math, it may be picked up from cwd
+    from setuptools.command import easy_install
+    try:
+        # very old versions of setuptools don't have this
+        from setuptools.command import bdist_egg
+    except ImportError:
+        have_setuptools = False
+else:
+    from distutils.core import setup as old_setup
+    have_setuptools = False
+
+import warnings
+import distutils.core
+import distutils.dist
+
+from numpy.distutils.extension import Extension
+from numpy.distutils.numpy_distribution import NumpyDistribution
+from numpy.distutils.command import config, config_compiler, \
+     build, build_py, build_ext, build_clib, build_src, build_scripts, \
+     sdist, install_data, install_headers, install, bdist_rpm, \
+     install_clib
+from numpy.distutils.misc_util import get_data_files, is_sequence, is_string
+
+numpy_cmdclass = {'build':            build.build,
+                  'build_src':        build_src.build_src,
+                  'build_scripts':    build_scripts.build_scripts,
+                  'config_cc':        config_compiler.config_cc,
+                  'config_fc':        config_compiler.config_fc,
+                  'config':           config.config,
+                  'build_ext':        build_ext.build_ext,
+                  'build_py':         build_py.build_py,
+                  'build_clib':       build_clib.build_clib,
+                  'sdist':            sdist.sdist,
+                  'install_data':     install_data.install_data,
+                  'install_headers':  install_headers.install_headers,
+                  'install_clib':     install_clib.install_clib,
+                  'install':          install.install,
+                  'bdist_rpm':        bdist_rpm.bdist_rpm,
+                  }
+if have_setuptools:
+    # Use our own versions of develop and egg_info to ensure that build_src is
+    # handled appropriately.
+    from numpy.distutils.command import develop, egg_info
+    numpy_cmdclass['bdist_egg'] = bdist_egg.bdist_egg
+    numpy_cmdclass['develop'] = develop.develop
+    numpy_cmdclass['easy_install'] = easy_install.easy_install
+    numpy_cmdclass['egg_info'] = egg_info.egg_info
+
+def _dict_append(d, **kws):
+    for k, v in kws.items():
+        if k not in d:
+            d[k] = v
+            continue
+        dv = d[k]
+        if isinstance(dv, tuple):
+            d[k] = dv + tuple(v)
+        elif isinstance(dv, list):
+            d[k] = dv + list(v)
+        elif isinstance(dv, dict):
+            _dict_append(dv, **v)
+        elif is_string(dv):
+            d[k] = dv + v
+        else:
+            raise TypeError(repr(type(dv)))
+
+def _command_line_ok(_cache=[]):
+    """ Return True if command line does not contain any
+    help or display requests.
+    """
+    if _cache:
+        return _cache[0]
+    ok = True
+    display_opts = ['--'+n for n in Distribution.display_option_names]
+    for o in Distribution.display_options:
+        if o[1]:
+            display_opts.append('-'+o[1])
+    for arg in sys.argv:
+        if arg.startswith('--help') or arg=='-h' or arg in display_opts:
+            ok = False
+            break
+    _cache.append(ok)
+    return ok
+
+def get_distribution(always=False):
+    dist = distutils.core._setup_distribution
+    # XXX Hack to get numpy installable with easy_install.
+    # The problem is easy_install runs it's own setup(), which
+    # sets up distutils.core._setup_distribution. However,
+    # when our setup() runs, that gets overwritten and lost.
+    # We can't use isinstance, as the DistributionWithoutHelpCommands
+    # class is local to a function in setuptools.command.easy_install
+    if dist is not None and \
+            'DistributionWithoutHelpCommands' in repr(dist):
+        dist = None
+    if always and dist is None:
+        dist = NumpyDistribution()
+    return dist
+
+def setup(**attr):
+
+    cmdclass = numpy_cmdclass.copy()
+
+    new_attr = attr.copy()
+    if 'cmdclass' in new_attr:
+        cmdclass.update(new_attr['cmdclass'])
+    new_attr['cmdclass'] = cmdclass
+
+    if 'configuration' in new_attr:
+        # To avoid calling configuration if there are any errors
+        # or help request in command in the line.
+        configuration = new_attr.pop('configuration')
+
+        old_dist = distutils.core._setup_distribution
+        old_stop = distutils.core._setup_stop_after
+        distutils.core._setup_distribution = None
+        distutils.core._setup_stop_after = "commandline"
+        try:
+            dist = setup(**new_attr)
+        finally:
+            distutils.core._setup_distribution = old_dist
+            distutils.core._setup_stop_after = old_stop
+        if dist.help or not _command_line_ok():
+            # probably displayed help, skip running any commands
+            return dist
+
+        # create setup dictionary and append to new_attr
+        config = configuration()
+        if hasattr(config, 'todict'):
+            config = config.todict()
+        _dict_append(new_attr, **config)
+
+    # Move extension source libraries to libraries
+    libraries = []
+    for ext in new_attr.get('ext_modules', []):
+        new_libraries = []
+        for item in ext.libraries:
+            if is_sequence(item):
+                lib_name, build_info = item
+                _check_append_ext_library(libraries, lib_name, build_info)
+                new_libraries.append(lib_name)
+            elif is_string(item):
+                new_libraries.append(item)
+            else:
+                raise TypeError("invalid description of extension module "
+                                "library %r" % (item,))
+        ext.libraries = new_libraries
+    if libraries:
+        if 'libraries' not in new_attr:
+            new_attr['libraries'] = []
+        for item in libraries:
+            _check_append_library(new_attr['libraries'], item)
+
+    # sources in ext_modules or libraries may contain header files
+    if ('ext_modules' in new_attr or 'libraries' in new_attr) \
+       and 'headers' not in new_attr:
+        new_attr['headers'] = []
+
+    # Use our custom NumpyDistribution class instead of distutils' one
+    new_attr['distclass'] = NumpyDistribution
+
+    return old_setup(**new_attr)
+
+def _check_append_library(libraries, item):
+    for libitem in libraries:
+        if is_sequence(libitem):
+            if is_sequence(item):
+                if item[0]==libitem[0]:
+                    if item[1] is libitem[1]:
+                        return
+                    warnings.warn("[0] libraries list contains %r with"
+                                  " different build_info" % (item[0],))
+                    break
+            else:
+                if item==libitem[0]:
+                    warnings.warn("[1] libraries list contains %r with"
+                                  " no build_info" % (item[0],))
+                    break
+        else:
+            if is_sequence(item):
+                if item[0]==libitem:
+                    warnings.warn("[2] libraries list contains %r with"
+                                  " no build_info" % (item[0],))
+                    break
+            else:
+                if item==libitem:
+                    return
+    libraries.append(item)
+
+def _check_append_ext_library(libraries, lib_name, build_info):
+    for item in libraries:
+        if is_sequence(item):
+            if item[0]==lib_name:
+                if item[1] is build_info:
+                    return
+                warnings.warn("[3] libraries list contains %r with"
+                              " different build_info" % (lib_name,))
+                break
+        elif item==lib_name:
+            warnings.warn("[4] libraries list contains %r with"
+                          " no build_info" % (lib_name,))
+            break
+    libraries.append((lib_name, build_info))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
new file mode 100644
index 0000000000..40f9d77c98
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
@@ -0,0 +1,693 @@
+#!/usr/bin/env python2
+"""
+cpuinfo
+
+Copyright 2002 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) license.  See LICENSE.txt that came with
+this distribution for specifics.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['cpu']
+
+import sys, re, types
+import os
+
+if sys.version_info[0] >= 3:
+    from subprocess import getstatusoutput
+else:
+    from commands import getstatusoutput
+
+import warnings
+import platform
+
+from numpy.distutils.compat import get_exception
+
+def getoutput(cmd, successful_status=(0,), stacklevel=1):
+    try:
+        status, output = getstatusoutput(cmd)
+    except EnvironmentError:
+        e = get_exception()
+        warnings.warn(str(e), UserWarning, stacklevel=stacklevel)
+        return False, output
+    if os.WIFEXITED(status) and os.WEXITSTATUS(status) in successful_status:
+        return True, output
+    return False, output
+
+def command_info(successful_status=(0,), stacklevel=1, **kw):
+    info = {}
+    for key in kw:
+        ok, output = getoutput(kw[key], successful_status=successful_status,
+                               stacklevel=stacklevel+1)
+        if ok:
+            info[key] = output.strip()
+    return info
+
+def command_by_line(cmd, successful_status=(0,), stacklevel=1):
+    ok, output = getoutput(cmd, successful_status=successful_status,
+                           stacklevel=stacklevel+1)
+    if not ok:
+        return
+    for line in output.splitlines():
+        yield line.strip()
+
+def key_value_from_command(cmd, sep, successful_status=(0,),
+                           stacklevel=1):
+    d = {}
+    for line in command_by_line(cmd, successful_status=successful_status,
+                                stacklevel=stacklevel+1):
+        l = [s.strip() for s in line.split(sep, 1)]
+        if len(l) == 2:
+            d[l[0]] = l[1]
+    return d
+
+class CPUInfoBase(object):
+    """Holds CPU information and provides methods for requiring
+    the availability of various CPU features.
+    """
+
+    def _try_call(self, func):
+        try:
+            return func()
+        except:
+            pass
+
+    def __getattr__(self, name):
+        if not name.startswith('_'):
+            if hasattr(self, '_'+name):
+                attr = getattr(self, '_'+name)
+                if isinstance(attr, types.MethodType):
+                    return lambda func=self._try_call,attr=attr : func(attr)
+            else:
+                return lambda : None
+        raise AttributeError(name)
+
+    def _getNCPUs(self):
+        return 1
+
+    def __get_nbits(self):
+        abits = platform.architecture()[0]
+        nbits = re.compile('(\d+)bit').search(abits).group(1)
+        return nbits
+
+    def _is_32bit(self):
+        return self.__get_nbits() == '32'
+
+    def _is_64bit(self):
+        return self.__get_nbits() == '64'
+
+class LinuxCPUInfo(CPUInfoBase):
+
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = [ {} ]
+        ok, output = getoutput('uname -m')
+        if ok:
+            info[0]['uname_m'] = output.strip()
+        try:
+            fo = open('/proc/cpuinfo')
+        except EnvironmentError:
+            e = get_exception()
+            warnings.warn(str(e), UserWarning)
+        else:
+            for line in fo:
+                name_value = [s.strip() for s in line.split(':', 1)]
+                if len(name_value) != 2:
+                    continue
+                name, value = name_value
+                if not info or name in info[-1]: # next processor
+                    info.append({})
+                info[-1][name] = value
+            fo.close()
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    # Athlon
+
+    def _is_AMD(self):
+        return self.info[0]['vendor_id']=='AuthenticAMD'
+
+    def _is_AthlonK6_2(self):
+        return self._is_AMD() and self.info[0]['model'] == '2'
+
+    def _is_AthlonK6_3(self):
+        return self._is_AMD() and self.info[0]['model'] == '3'
+
+    def _is_AthlonK6(self):
+        return re.match(r'.*?AMD-K6', self.info[0]['model name']) is not None
+
+    def _is_AthlonK7(self):
+        return re.match(r'.*?AMD-K7', self.info[0]['model name']) is not None
+
+    def _is_AthlonMP(self):
+        return re.match(r'.*?Athlon\(tm\) MP\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_AMD64(self):
+        return self.is_AMD() and self.info[0]['family'] == '15'
+
+    def _is_Athlon64(self):
+        return re.match(r'.*?Athlon\(tm\) 64\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_AthlonHX(self):
+        return re.match(r'.*?Athlon HX\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Opteron(self):
+        return re.match(r'.*?Opteron\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Hammer(self):
+        return re.match(r'.*?Hammer\b',
+                        self.info[0]['model name']) is not None
+
+    # Alpha
+
+    def _is_Alpha(self):
+        return self.info[0]['cpu']=='Alpha'
+
+    def _is_EV4(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV4'
+
+    def _is_EV5(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV5'
+
+    def _is_EV56(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'EV56'
+
+    def _is_PCA56(self):
+        return self.is_Alpha() and self.info[0]['cpu model'] == 'PCA56'
+
+    # Intel
+
+    #XXX
+    _is_i386 = _not_impl
+
+    def _is_Intel(self):
+        return self.info[0]['vendor_id']=='GenuineIntel'
+
+    def _is_i486(self):
+        return self.info[0]['cpu']=='i486'
+
+    def _is_i586(self):
+        return self.is_Intel() and self.info[0]['cpu family'] == '5'
+
+    def _is_i686(self):
+        return self.is_Intel() and self.info[0]['cpu family'] == '6'
+
+    def _is_Celeron(self):
+        return re.match(r'.*?Celeron',
+                        self.info[0]['model name']) is not None
+
+    def _is_Pentium(self):
+        return re.match(r'.*?Pentium',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumII(self):
+        return re.match(r'.*?Pentium.*?II\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumPro(self):
+        return re.match(r'.*?PentiumPro\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumMMX(self):
+        return re.match(r'.*?Pentium.*?MMX\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumIII(self):
+        return re.match(r'.*?Pentium.*?III\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumIV(self):
+        return re.match(r'.*?Pentium.*?(IV|4)\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_PentiumM(self):
+        return re.match(r'.*?Pentium.*?M\b',
+                        self.info[0]['model name']) is not None
+
+    def _is_Prescott(self):
+        return self.is_PentiumIV() and self.has_sse3()
+
+    def _is_Nocona(self):
+        return self.is_Intel() \
+               and (self.info[0]['cpu family'] == '6' \
+                    or self.info[0]['cpu family'] == '15' ) \
+               and (self.has_sse3() and not self.has_ssse3())\
+               and re.match(r'.*?\blm\b', self.info[0]['flags']) is not None
+
+    def _is_Core2(self):
+        return self.is_64bit() and self.is_Intel() and \
+               re.match(r'.*?Core\(TM\)2\b', \
+                        self.info[0]['model name']) is not None
+
+    def _is_Itanium(self):
+        return re.match(r'.*?Itanium\b',
+                        self.info[0]['family']) is not None
+
+    def _is_XEON(self):
+        return re.match(r'.*?XEON\b',
+                        self.info[0]['model name'], re.IGNORECASE) is not None
+
+    _is_Xeon = _is_XEON
+
+    # Varia
+
+    def _is_singleCPU(self):
+        return len(self.info) == 1
+
+    def _getNCPUs(self):
+        return len(self.info)
+
+    def _has_fdiv_bug(self):
+        return self.info[0]['fdiv_bug']=='yes'
+
+    def _has_f00f_bug(self):
+        return self.info[0]['f00f_bug']=='yes'
+
+    def _has_mmx(self):
+        return re.match(r'.*?\bmmx\b', self.info[0]['flags']) is not None
+
+    def _has_sse(self):
+        return re.match(r'.*?\bsse\b', self.info[0]['flags']) is not None
+
+    def _has_sse2(self):
+        return re.match(r'.*?\bsse2\b', self.info[0]['flags']) is not None
+
+    def _has_sse3(self):
+        return re.match(r'.*?\bpni\b', self.info[0]['flags']) is not None
+
+    def _has_ssse3(self):
+        return re.match(r'.*?\bssse3\b', self.info[0]['flags']) is not None
+
+    def _has_3dnow(self):
+        return re.match(r'.*?\b3dnow\b', self.info[0]['flags']) is not None
+
+    def _has_3dnowext(self):
+        return re.match(r'.*?\b3dnowext\b', self.info[0]['flags']) is not None
+
+class IRIXCPUInfo(CPUInfoBase):
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = key_value_from_command('sysconf', sep=' ',
+                                      successful_status=(0, 1))
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _is_singleCPU(self):
+        return self.info.get('NUM_PROCESSORS') == '1'
+
+    def _getNCPUs(self):
+        return int(self.info.get('NUM_PROCESSORS', 1))
+
+    def __cputype(self, n):
+        return self.info.get('PROCESSORS').split()[0].lower() == 'r%s' % (n)
+    def _is_r2000(self): return self.__cputype(2000)
+    def _is_r3000(self): return self.__cputype(3000)
+    def _is_r3900(self): return self.__cputype(3900)
+    def _is_r4000(self): return self.__cputype(4000)
+    def _is_r4100(self): return self.__cputype(4100)
+    def _is_r4300(self): return self.__cputype(4300)
+    def _is_r4400(self): return self.__cputype(4400)
+    def _is_r4600(self): return self.__cputype(4600)
+    def _is_r4650(self): return self.__cputype(4650)
+    def _is_r5000(self): return self.__cputype(5000)
+    def _is_r6000(self): return self.__cputype(6000)
+    def _is_r8000(self): return self.__cputype(8000)
+    def _is_r10000(self): return self.__cputype(10000)
+    def _is_r12000(self): return self.__cputype(12000)
+    def _is_rorion(self): return self.__cputype('orion')
+
+    def get_ip(self):
+        try: return self.info.get('MACHINE')
+        except: pass
+    def __machine(self, n):
+        return self.info.get('MACHINE').lower() == 'ip%s' % (n)
+    def _is_IP19(self): return self.__machine(19)
+    def _is_IP20(self): return self.__machine(20)
+    def _is_IP21(self): return self.__machine(21)
+    def _is_IP22(self): return self.__machine(22)
+    def _is_IP22_4k(self): return self.__machine(22) and self._is_r4000()
+    def _is_IP22_5k(self): return self.__machine(22)  and self._is_r5000()
+    def _is_IP24(self): return self.__machine(24)
+    def _is_IP25(self): return self.__machine(25)
+    def _is_IP26(self): return self.__machine(26)
+    def _is_IP27(self): return self.__machine(27)
+    def _is_IP28(self): return self.__machine(28)
+    def _is_IP30(self): return self.__machine(30)
+    def _is_IP32(self): return self.__machine(32)
+    def _is_IP32_5k(self): return self.__machine(32) and self._is_r5000()
+    def _is_IP32_10k(self): return self.__machine(32) and self._is_r10000()
+
+
+class DarwinCPUInfo(CPUInfoBase):
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = command_info(arch='arch',
+                            machine='machine')
+        info['sysctl_hw'] = key_value_from_command('sysctl hw', sep='=')
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _getNCPUs(self):
+        return int(self.info['sysctl_hw'].get('hw.ncpu', 1))
+
+    def _is_Power_Macintosh(self):
+        return self.info['sysctl_hw']['hw.machine']=='Power Macintosh'
+
+    def _is_i386(self):
+        return self.info['arch']=='i386'
+    def _is_ppc(self):
+        return self.info['arch']=='ppc'
+
+    def __machine(self, n):
+        return self.info['machine'] == 'ppc%s'%n
+    def _is_ppc601(self): return self.__machine(601)
+    def _is_ppc602(self): return self.__machine(602)
+    def _is_ppc603(self): return self.__machine(603)
+    def _is_ppc603e(self): return self.__machine('603e')
+    def _is_ppc604(self): return self.__machine(604)
+    def _is_ppc604e(self): return self.__machine('604e')
+    def _is_ppc620(self): return self.__machine(620)
+    def _is_ppc630(self): return self.__machine(630)
+    def _is_ppc740(self): return self.__machine(740)
+    def _is_ppc7400(self): return self.__machine(7400)
+    def _is_ppc7450(self): return self.__machine(7450)
+    def _is_ppc750(self): return self.__machine(750)
+    def _is_ppc403(self): return self.__machine(403)
+    def _is_ppc505(self): return self.__machine(505)
+    def _is_ppc801(self): return self.__machine(801)
+    def _is_ppc821(self): return self.__machine(821)
+    def _is_ppc823(self): return self.__machine(823)
+    def _is_ppc860(self): return self.__machine(860)
+
+
+class SunOSCPUInfo(CPUInfoBase):
+
+    info = None
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = command_info(arch='arch',
+                            mach='mach',
+                            uname_i='uname_i',
+                            isainfo_b='isainfo -b',
+                            isainfo_n='isainfo -n',
+                            )
+        info['uname_X'] = key_value_from_command('uname -X', sep='=')
+        for line in command_by_line('psrinfo -v 0'):
+            m = re.match(r'\s*The (?P<p>[\w\d]+) processor operates at', line)
+            if m:
+                info['processor'] = m.group('p')
+                break
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    def _is_i386(self):
+        return self.info['isainfo_n']=='i386'
+    def _is_sparc(self):
+        return self.info['isainfo_n']=='sparc'
+    def _is_sparcv9(self):
+        return self.info['isainfo_n']=='sparcv9'
+
+    def _getNCPUs(self):
+        return int(self.info['uname_X'].get('NumCPU', 1))
+
+    def _is_sun4(self):
+        return self.info['arch']=='sun4'
+
+    def _is_SUNW(self):
+        return re.match(r'SUNW', self.info['uname_i']) is not None
+    def _is_sparcstation5(self):
+        return re.match(r'.*SPARCstation-5', self.info['uname_i']) is not None
+    def _is_ultra1(self):
+        return re.match(r'.*Ultra-1', self.info['uname_i']) is not None
+    def _is_ultra250(self):
+        return re.match(r'.*Ultra-250', self.info['uname_i']) is not None
+    def _is_ultra2(self):
+        return re.match(r'.*Ultra-2', self.info['uname_i']) is not None
+    def _is_ultra30(self):
+        return re.match(r'.*Ultra-30', self.info['uname_i']) is not None
+    def _is_ultra4(self):
+        return re.match(r'.*Ultra-4', self.info['uname_i']) is not None
+    def _is_ultra5_10(self):
+        return re.match(r'.*Ultra-5_10', self.info['uname_i']) is not None
+    def _is_ultra5(self):
+        return re.match(r'.*Ultra-5', self.info['uname_i']) is not None
+    def _is_ultra60(self):
+        return re.match(r'.*Ultra-60', self.info['uname_i']) is not None
+    def _is_ultra80(self):
+        return re.match(r'.*Ultra-80', self.info['uname_i']) is not None
+    def _is_ultraenterprice(self):
+        return re.match(r'.*Ultra-Enterprise', self.info['uname_i']) is not None
+    def _is_ultraenterprice10k(self):
+        return re.match(r'.*Ultra-Enterprise-10000', self.info['uname_i']) is not None
+    def _is_sunfire(self):
+        return re.match(r'.*Sun-Fire', self.info['uname_i']) is not None
+    def _is_ultra(self):
+        return re.match(r'.*Ultra', self.info['uname_i']) is not None
+
+    def _is_cpusparcv7(self):
+        return self.info['processor']=='sparcv7'
+    def _is_cpusparcv8(self):
+        return self.info['processor']=='sparcv8'
+    def _is_cpusparcv9(self):
+        return self.info['processor']=='sparcv9'
+
+class Win32CPUInfo(CPUInfoBase):
+
+    info = None
+    pkey = r"HARDWARE\DESCRIPTION\System\CentralProcessor"
+    # XXX: what does the value of
+    #   HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
+    # mean?
+
+    def __init__(self):
+        if self.info is not None:
+            return
+        info = []
+        try:
+            #XXX: Bad style to use so long `try:...except:...`. Fix it!
+            if sys.version_info[0] >= 3:
+                import winreg
+            else:
+                import _winreg as winreg
+
+            prgx = re.compile(r"family\s+(?P<FML>\d+)\s+model\s+(?P<MDL>\d+)"\
+                              "\s+stepping\s+(?P<STP>\d+)", re.IGNORECASE)
+            chnd=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, self.pkey)
+            pnum=0
+            while True:
+                try:
+                    proc=winreg.EnumKey(chnd, pnum)
+                except winreg.error:
+                    break
+                else:
+                    pnum+=1
+                    info.append({"Processor":proc})
+                    phnd=winreg.OpenKey(chnd, proc)
+                    pidx=0
+                    while True:
+                        try:
+                            name, value, vtpe=winreg.EnumValue(phnd, pidx)
+                        except winreg.error:
+                            break
+                        else:
+                            pidx=pidx+1
+                            info[-1][name]=value
+                            if name=="Identifier":
+                                srch=prgx.search(value)
+                                if srch:
+                                    info[-1]["Family"]=int(srch.group("FML"))
+                                    info[-1]["Model"]=int(srch.group("MDL"))
+                                    info[-1]["Stepping"]=int(srch.group("STP"))
+        except:
+            print(sys.exc_info()[1], '(ignoring)')
+        self.__class__.info = info
+
+    def _not_impl(self): pass
+
+    # Athlon
+
+    def _is_AMD(self):
+        return self.info[0]['VendorIdentifier']=='AuthenticAMD'
+
+    def _is_Am486(self):
+        return self.is_AMD() and self.info[0]['Family']==4
+
+    def _is_Am5x86(self):
+        return self.is_AMD() and self.info[0]['Family']==4
+
+    def _is_AMDK5(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model'] in [0, 1, 2, 3]
+
+    def _is_AMDK6(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model'] in [6, 7]
+
+    def _is_AMDK6_2(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==8
+
+    def _is_AMDK6_3(self):
+        return self.is_AMD() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==9
+
+    def _is_AMDK7(self):
+        return self.is_AMD() and self.info[0]['Family'] == 6
+
+    # To reliably distinguish between the different types of AMD64 chips
+    # (Athlon64, Operton, Athlon64 X2, Semperon, Turion 64, etc.) would
+    # require looking at the 'brand' from cpuid
+
+    def _is_AMD64(self):
+        return self.is_AMD() and self.info[0]['Family'] == 15
+
+    # Intel
+
+    def _is_Intel(self):
+        return self.info[0]['VendorIdentifier']=='GenuineIntel'
+
+    def _is_i386(self):
+        return self.info[0]['Family']==3
+
+    def _is_i486(self):
+        return self.info[0]['Family']==4
+
+    def _is_i586(self):
+        return self.is_Intel() and self.info[0]['Family']==5
+
+    def _is_i686(self):
+        return self.is_Intel() and self.info[0]['Family']==6
+
+    def _is_Pentium(self):
+        return self.is_Intel() and self.info[0]['Family']==5
+
+    def _is_PentiumMMX(self):
+        return self.is_Intel() and self.info[0]['Family']==5 \
+               and self.info[0]['Model']==4
+
+    def _is_PentiumPro(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model']==1
+
+    def _is_PentiumII(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model'] in [3, 5, 6]
+
+    def _is_PentiumIII(self):
+        return self.is_Intel() and self.info[0]['Family']==6 \
+               and self.info[0]['Model'] in [7, 8, 9, 10, 11]
+
+    def _is_PentiumIV(self):
+        return self.is_Intel() and self.info[0]['Family']==15
+
+    def _is_PentiumM(self):
+        return self.is_Intel() and self.info[0]['Family'] == 6 \
+               and self.info[0]['Model'] in [9, 13, 14]
+
+    def _is_Core2(self):
+        return self.is_Intel() and self.info[0]['Family'] == 6 \
+               and self.info[0]['Model'] in [15, 16, 17]
+
+    # Varia
+
+    def _is_singleCPU(self):
+        return len(self.info) == 1
+
+    def _getNCPUs(self):
+        return len(self.info)
+
+    def _has_mmx(self):
+        if self.is_Intel():
+            return (self.info[0]['Family']==5 and self.info[0]['Model']==4) \
+                   or (self.info[0]['Family'] in [6, 15])
+        elif self.is_AMD():
+            return self.info[0]['Family'] in [5, 6, 15]
+        else:
+            return False
+
+    def _has_sse(self):
+        if self.is_Intel():
+            return (self.info[0]['Family']==6 and \
+                    self.info[0]['Model'] in [7, 8, 9, 10, 11]) \
+                    or self.info[0]['Family']==15
+        elif self.is_AMD():
+            return (self.info[0]['Family']==6 and \
+                    self.info[0]['Model'] in [6, 7, 8, 10]) \
+                    or self.info[0]['Family']==15
+        else:
+            return False
+
+    def _has_sse2(self):
+        if self.is_Intel():
+            return self.is_Pentium4() or self.is_PentiumM() \
+                   or self.is_Core2()
+        elif self.is_AMD():
+            return self.is_AMD64()
+        else:
+            return False
+
+    def _has_3dnow(self):
+        return self.is_AMD() and self.info[0]['Family'] in [5, 6, 15]
+
+    def _has_3dnowext(self):
+        return self.is_AMD() and self.info[0]['Family'] in [6, 15]
+
+if sys.platform.startswith('linux'): # variations: linux2,linux-i386 (any others?)
+    cpuinfo = LinuxCPUInfo
+elif sys.platform.startswith('irix'):
+    cpuinfo = IRIXCPUInfo
+elif sys.platform == 'darwin':
+    cpuinfo = DarwinCPUInfo
+elif sys.platform.startswith('sunos'):
+    cpuinfo = SunOSCPUInfo
+elif sys.platform.startswith('win32'):
+    cpuinfo = Win32CPUInfo
+elif sys.platform.startswith('cygwin'):
+    cpuinfo = LinuxCPUInfo
+#XXX: other OS's. Eg. use _winreg on Win32. Or os.uname on unices.
+else:
+    cpuinfo = CPUInfoBase
+
+cpu = cpuinfo()
+
+#if __name__ == "__main__":
+#
+#    cpu.is_blaa()
+#    cpu.is_Intel()
+#    cpu.is_Alpha()
+#
+#    print 'CPU information:',
+#    for name in dir(cpuinfo):
+#        if name[0]=='_' and name[1]!='_':
+#            r = getattr(cpu,name[1:])()
+#            if r:
+#                if r!=1:
+#                    print '%s=%s' %(name[1:],r),
+#                else:
+#                    print name[1:],
+#    print
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/environment.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/environment.py
new file mode 100644
index 0000000000..3798e16f5d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/environment.py
@@ -0,0 +1,72 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+from distutils.dist import Distribution
+
+__metaclass__ = type
+
+class EnvironmentConfig(object):
+    def __init__(self, distutils_section='ALL', **kw):
+        self._distutils_section = distutils_section
+        self._conf_keys = kw
+        self._conf = None
+        self._hook_handler = None
+
+    def dump_variable(self, name):
+        conf_desc = self._conf_keys[name]
+        hook, envvar, confvar, convert = conf_desc
+        if not convert:
+            convert = lambda x : x
+        print('%s.%s:' % (self._distutils_section, name))
+        v = self._hook_handler(name, hook)
+        print('  hook   : %s' % (convert(v),))
+        if envvar:
+            v = os.environ.get(envvar, None)
+            print('  environ: %s' % (convert(v),))
+        if confvar and self._conf:
+            v = self._conf.get(confvar, (None, None))[1]
+            print('  config : %s' % (convert(v),))
+
+    def dump_variables(self):
+        for name in self._conf_keys:
+            self.dump_variable(name)
+
+    def __getattr__(self, name):
+        try:
+            conf_desc = self._conf_keys[name]
+        except KeyError:
+            raise AttributeError(name)
+        return self._get_var(name, conf_desc)
+
+    def get(self, name, default=None):
+        try:
+            conf_desc = self._conf_keys[name]
+        except KeyError:
+            return default
+        var = self._get_var(name, conf_desc)
+        if var is None:
+            var = default
+        return var
+
+    def _get_var(self, name, conf_desc):
+        hook, envvar, confvar, convert = conf_desc
+        var = self._hook_handler(name, hook)
+        if envvar is not None:
+            var = os.environ.get(envvar, var)
+        if confvar is not None and self._conf:
+            var = self._conf.get(confvar, (None, var))[1]
+        if convert is not None:
+            var = convert(var)
+        return var
+
+    def clone(self, hook_handler):
+        ec = self.__class__(distutils_section=self._distutils_section,
+                            **self._conf_keys)
+        ec._hook_handler = hook_handler
+        return ec
+
+    def use_distribution(self, dist):
+        if isinstance(dist, Distribution):
+            self._conf = dist.get_option_dict(self._distutils_section)
+        else:
+            self._conf = dist
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.py
new file mode 100644
index 0000000000..c127dc355b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.py
@@ -0,0 +1,651 @@
+#!/usr/bin/env python2
+"""
+exec_command
+
+Implements exec_command function that is (almost) equivalent to
+commands.getstatusoutput function but on NT, DOS systems the
+returned status is actually correct (though, the returned status
+values may be different by a factor). In addition, exec_command
+takes keyword arguments for (re-)defining environment variables.
+
+Provides functions:
+
+  exec_command  --- execute command in a specified directory and
+                    in the modified environment.
+  find_executable --- locate a command using info from environment
+                    variable PATH. Equivalent to posix `which`
+                    command.
+
+Author: Pearu Peterson <pearu@cens.ioc.ee>
+Created: 11 January 2003
+
+Requires: Python 2.x
+
+Succesfully tested on:
+
+========  ============  =================================================
+os.name   sys.platform  comments
+========  ============  =================================================
+posix     linux2        Debian (sid) Linux, Python 2.1.3+, 2.2.3+, 2.3.3
+                        PyCrust 0.9.3, Idle 1.0.2
+posix     linux2        Red Hat 9 Linux, Python 2.1.3, 2.2.2, 2.3.2
+posix     sunos5        SunOS 5.9, Python 2.2, 2.3.2
+posix     darwin        Darwin 7.2.0, Python 2.3
+nt        win32         Windows Me
+                        Python 2.3(EE), Idle 1.0, PyCrust 0.7.2
+                        Python 2.1.1 Idle 0.8
+nt        win32         Windows 98, Python 2.1.1. Idle 0.8
+nt        win32         Cygwin 98-4.10, Python 2.1.1(MSC) - echo tests
+                        fail i.e. redefining environment variables may
+                        not work. FIXED: don't use cygwin echo!
+                        Comment: also `cmd /c echo` will not work
+                        but redefining environment variables do work.
+posix     cygwin        Cygwin 98-4.10, Python 2.3.3(cygming special)
+nt        win32         Windows XP, Python 2.3.3
+========  ============  =================================================
+
+Known bugs:
+
+* Tests, that send messages to stderr, fail when executed from MSYS prompt
+  because the messages are lost at some point.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['exec_command', 'find_executable']
+
+import os
+import sys
+import shlex
+
+from numpy.distutils.misc_util import is_sequence, make_temp_file
+from numpy.distutils import log
+from numpy.distutils.compat import get_exception
+
+from numpy.compat import open_latin1
+
+def temp_file_name():
+    fo, name = make_temp_file()
+    fo.close()
+    return name
+
+def get_pythonexe():
+    pythonexe = sys.executable
+    if os.name in ['nt', 'dos']:
+        fdir, fn = os.path.split(pythonexe)
+        fn = fn.upper().replace('PYTHONW', 'PYTHON')
+        pythonexe = os.path.join(fdir, fn)
+        assert os.path.isfile(pythonexe), '%r is not a file' % (pythonexe,)
+    return pythonexe
+
+def find_executable(exe, path=None, _cache={}):
+    """Return full path of a executable or None.
+
+    Symbolic links are not followed.
+    """
+    key = exe, path
+    try:
+        return _cache[key]
+    except KeyError:
+        pass
+    log.debug('find_executable(%r)' % exe)
+    orig_exe = exe
+
+    if path is None:
+        path = os.environ.get('PATH', os.defpath)
+    if os.name=='posix':
+        realpath = os.path.realpath
+    else:
+        realpath = lambda a:a
+
+    if exe.startswith('"'):
+        exe = exe[1:-1]
+
+    suffixes = ['']
+    if os.name in ['nt', 'dos', 'os2']:
+        fn, ext = os.path.splitext(exe)
+        extra_suffixes = ['.exe', '.com', '.bat']
+        if ext.lower() not in extra_suffixes:
+            suffixes = extra_suffixes
+
+    if os.path.isabs(exe):
+        paths = ['']
+    else:
+        paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ]
+
+    for path in paths:
+        fn = os.path.join(path, exe)
+        for s in suffixes:
+            f_ext = fn+s
+            if not os.path.islink(f_ext):
+                f_ext = realpath(f_ext)
+            if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK):
+                log.info('Found executable %s' % f_ext)
+                _cache[key] = f_ext
+                return f_ext
+
+    log.warn('Could not locate executable %s' % orig_exe)
+    return None
+
+############################################################
+
+def _preserve_environment( names ):
+    log.debug('_preserve_environment(%r)' % (names))
+    env = {}
+    for name in names:
+        env[name] = os.environ.get(name)
+    return env
+
+def _update_environment( **env ):
+    log.debug('_update_environment(...)')
+    for name, value in env.items():
+        os.environ[name] = value or ''
+
+def _supports_fileno(stream):
+    """
+    Returns True if 'stream' supports the file descriptor and allows fileno().
+    """
+    if hasattr(stream, 'fileno'):
+        try:
+            r = stream.fileno()
+            return True
+        except IOError:
+            return False
+    else:
+        return False
+
+def exec_command(command, execute_in='', use_shell=None, use_tee=None,
+                 _with_python = 1, **env ):
+    """
+    Return (status,output) of executed command.
+
+    Parameters
+    ----------
+    command : str
+        A concatenated string of executable and arguments.
+    execute_in : str
+        Before running command ``cd execute_in`` and after ``cd -``.
+    use_shell : {bool, None}, optional
+        If True, execute ``sh -c command``. Default None (True)
+    use_tee : {bool, None}, optional
+        If True use tee. Default None (True)
+
+
+    Returns
+    -------
+    res : str
+        Both stdout and stderr messages.
+
+    Notes
+    -----
+    On NT, DOS systems the returned status is correct for external commands.
+    Wild cards will not work for non-posix systems or when use_shell=0.
+
+    """
+    log.debug('exec_command(%r,%s)' % (command,\
+         ','.join(['%s=%r'%kv for kv in env.items()])))
+
+    if use_tee is None:
+        use_tee = os.name=='posix'
+    if use_shell is None:
+        use_shell = os.name=='posix'
+    execute_in = os.path.abspath(execute_in)
+    oldcwd = os.path.abspath(os.getcwd())
+
+    if __name__[-12:] == 'exec_command':
+        exec_dir = os.path.dirname(os.path.abspath(__file__))
+    elif os.path.isfile('exec_command.py'):
+        exec_dir = os.path.abspath('.')
+    else:
+        exec_dir = os.path.abspath(sys.argv[0])
+        if os.path.isfile(exec_dir):
+            exec_dir = os.path.dirname(exec_dir)
+
+    if oldcwd!=execute_in:
+        os.chdir(execute_in)
+        log.debug('New cwd: %s' % execute_in)
+    else:
+        log.debug('Retaining cwd: %s' % oldcwd)
+
+    oldenv = _preserve_environment( list(env.keys()) )
+    _update_environment( **env )
+
+    try:
+        # _exec_command is robust but slow, it relies on
+        # usable sys.std*.fileno() descriptors. If they
+        # are bad (like in win32 Idle, PyCrust environments)
+        # then _exec_command_python (even slower)
+        # will be used as a last resort.
+        #
+        # _exec_command_posix uses os.system and is faster
+        # but not on all platforms os.system will return
+        # a correct status.
+        if (_with_python and _supports_fileno(sys.stdout) and
+                            sys.stdout.fileno() == -1):
+            st = _exec_command_python(command,
+                                      exec_command_dir = exec_dir,
+                                      **env)
+        elif os.name=='posix':
+            st = _exec_command_posix(command,
+                                     use_shell=use_shell,
+                                     use_tee=use_tee,
+                                     **env)
+        else:
+            st = _exec_command(command, use_shell=use_shell,
+                               use_tee=use_tee,**env)
+    finally:
+        if oldcwd!=execute_in:
+            os.chdir(oldcwd)
+            log.debug('Restored cwd to %s' % oldcwd)
+        _update_environment(**oldenv)
+
+    return st
+
+def _exec_command_posix( command,
+                         use_shell = None,
+                         use_tee = None,
+                         **env ):
+    log.debug('_exec_command_posix(...)')
+
+    if is_sequence(command):
+        command_str = ' '.join(list(command))
+    else:
+        command_str = command
+
+    tmpfile = temp_file_name()
+    stsfile = None
+    if use_tee:
+        stsfile = temp_file_name()
+        filter = ''
+        if use_tee == 2:
+            filter = r'| tr -cd "\n" | tr "\n" "."; echo'
+        command_posix = '( %s ; echo $? > %s ) 2>&1 | tee %s %s'\
+                      % (command_str, stsfile, tmpfile, filter)
+    else:
+        stsfile = temp_file_name()
+        command_posix = '( %s ; echo $? > %s ) > %s 2>&1'\
+                        % (command_str, stsfile, tmpfile)
+        #command_posix = '( %s ) > %s 2>&1' % (command_str,tmpfile)
+
+    log.debug('Running os.system(%r)' % (command_posix))
+    status = os.system(command_posix)
+
+    if use_tee:
+        if status:
+            # if command_tee fails then fall back to robust exec_command
+            log.warn('_exec_command_posix failed (status=%s)' % status)
+            return _exec_command(command, use_shell=use_shell, **env)
+
+    if stsfile is not None:
+        f = open_latin1(stsfile, 'r')
+        status_text = f.read()
+        status = int(status_text)
+        f.close()
+        os.remove(stsfile)
+
+    f = open_latin1(tmpfile, 'r')
+    text = f.read()
+    f.close()
+    os.remove(tmpfile)
+
+    if text[-1:]=='\n':
+        text = text[:-1]
+
+    return status, text
+
+
+def _exec_command_python(command,
+                         exec_command_dir='', **env):
+    log.debug('_exec_command_python(...)')
+
+    python_exe = get_pythonexe()
+    cmdfile = temp_file_name()
+    stsfile = temp_file_name()
+    outfile = temp_file_name()
+
+    f = open(cmdfile, 'w')
+    f.write('import os\n')
+    f.write('import sys\n')
+    f.write('sys.path.insert(0,%r)\n' % (exec_command_dir))
+    f.write('from exec_command import exec_command\n')
+    f.write('del sys.path[0]\n')
+    f.write('cmd = %r\n' % command)
+    f.write('os.environ = %r\n' % (os.environ))
+    f.write('s,o = exec_command(cmd, _with_python=0, **%r)\n' % (env))
+    f.write('f=open(%r,"w")\nf.write(str(s))\nf.close()\n' % (stsfile))
+    f.write('f=open(%r,"w")\nf.write(o)\nf.close()\n' % (outfile))
+    f.close()
+
+    cmd = '%s %s' % (python_exe, cmdfile)
+    status = os.system(cmd)
+    if status:
+        raise RuntimeError("%r failed" % (cmd,))
+    os.remove(cmdfile)
+
+    f = open_latin1(stsfile, 'r')
+    status = int(f.read())
+    f.close()
+    os.remove(stsfile)
+
+    f = open_latin1(outfile, 'r')
+    text = f.read()
+    f.close()
+    os.remove(outfile)
+
+    return status, text
+
+def quote_arg(arg):
+    if arg[0]!='"' and ' ' in arg:
+        return '"%s"' % arg
+    return arg
+
+def _exec_command( command, use_shell=None, use_tee = None, **env ):
+    log.debug('_exec_command(...)')
+
+    if use_shell is None:
+        use_shell = os.name=='posix'
+    if use_tee is None:
+        use_tee = os.name=='posix'
+    using_command = 0
+    if use_shell:
+        # We use shell (unless use_shell==0) so that wildcards can be
+        # used.
+        sh = os.environ.get('SHELL', '/bin/sh')
+        if is_sequence(command):
+            argv = [sh, '-c', ' '.join(list(command))]
+        else:
+            argv = [sh, '-c', command]
+    else:
+        # On NT, DOS we avoid using command.com as it's exit status is
+        # not related to the exit status of a command.
+        if is_sequence(command):
+            argv = command[:]
+        else:
+            argv = shlex.split(command)
+
+    if hasattr(os, 'spawnvpe'):
+        spawn_command = os.spawnvpe
+    else:
+        spawn_command = os.spawnve
+        argv[0] = find_executable(argv[0]) or argv[0]
+        if not os.path.isfile(argv[0]):
+            log.warn('Executable %s does not exist' % (argv[0]))
+            if os.name in ['nt', 'dos']:
+                # argv[0] might be internal command
+                argv = [os.environ['COMSPEC'], '/C'] + argv
+                using_command = 1
+
+    _so_has_fileno = _supports_fileno(sys.stdout)
+    _se_has_fileno = _supports_fileno(sys.stderr)
+    so_flush = sys.stdout.flush
+    se_flush = sys.stderr.flush
+    if _so_has_fileno:
+        so_fileno = sys.stdout.fileno()
+        so_dup = os.dup(so_fileno)
+    if _se_has_fileno:
+        se_fileno = sys.stderr.fileno()
+        se_dup = os.dup(se_fileno)
+
+    outfile = temp_file_name()
+    fout = open(outfile, 'w')
+    if using_command:
+        errfile = temp_file_name()
+        ferr = open(errfile, 'w')
+
+    log.debug('Running %s(%s,%r,%r,os.environ)' \
+              % (spawn_command.__name__, os.P_WAIT, argv[0], argv))
+
+    if sys.version_info[0] >= 3 and os.name == 'nt':
+        # Pre-encode os.environ, discarding un-encodable entries,
+        # to avoid it failing during encoding as part of spawn. Failure
+        # is possible if the environment contains entries that are not
+        # encoded using the system codepage as windows expects.
+        #
+        # This is not necessary on unix, where os.environ is encoded
+        # using the surrogateescape error handler and decoded using
+        # it as part of spawn.
+        encoded_environ = {}
+        for k, v in os.environ.items():
+            try:
+                encoded_environ[k.encode(sys.getfilesystemencoding())] = v.encode(
+                    sys.getfilesystemencoding())
+            except UnicodeEncodeError:
+                log.debug("ignoring un-encodable env entry %s", k)
+    else:
+        encoded_environ = os.environ
+
+    argv0 = argv[0]
+    if not using_command:
+        argv[0] = quote_arg(argv0)
+
+    so_flush()
+    se_flush()
+    if _so_has_fileno:
+        os.dup2(fout.fileno(), so_fileno)
+
+    if _se_has_fileno:
+        if using_command:
+            #XXX: disabled for now as it does not work from cmd under win32.
+            #     Tests fail on msys
+            os.dup2(ferr.fileno(), se_fileno)
+        else:
+            os.dup2(fout.fileno(), se_fileno)
+    try:
+        status = spawn_command(os.P_WAIT, argv0, argv, encoded_environ)
+    except Exception:
+        errmess = str(get_exception())
+        status = 999
+        sys.stderr.write('%s: %s'%(errmess, argv[0]))
+
+    so_flush()
+    se_flush()
+    if _so_has_fileno:
+        os.dup2(so_dup, so_fileno)
+        os.close(so_dup)
+    if _se_has_fileno:
+        os.dup2(se_dup, se_fileno)
+        os.close(se_dup)
+
+    fout.close()
+    fout = open_latin1(outfile, 'r')
+    text = fout.read()
+    fout.close()
+    os.remove(outfile)
+
+    if using_command:
+        ferr.close()
+        ferr = open_latin1(errfile, 'r')
+        errmess = ferr.read()
+        ferr.close()
+        os.remove(errfile)
+        if errmess and not status:
+            # Not sure how to handle the case where errmess
+            # contains only warning messages and that should
+            # not be treated as errors.
+            #status = 998
+            if text:
+                text = text + '\n'
+            #text = '%sCOMMAND %r FAILED: %s' %(text,command,errmess)
+            text = text + errmess
+            print (errmess)
+    if text[-1:]=='\n':
+        text = text[:-1]
+    if status is None:
+        status = 0
+
+    if use_tee:
+        print (text)
+
+    return status, text
+
+
+def test_nt(**kws):
+    pythonexe = get_pythonexe()
+    echo = find_executable('echo')
+    using_cygwin_echo = echo != 'echo'
+    if using_cygwin_echo:
+        log.warn('Using cygwin echo in win32 environment is not supported')
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'AAA\',\'\')"')
+        assert s==0 and o=='', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'AAA\')"',
+                         AAA='Tere')
+        assert s==0 and o=='Tere', (s, o)
+
+        os.environ['BBB'] = 'Hi'
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
+        assert s==0 and o=='Hi', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"',
+                         BBB='Hey')
+        assert s==0 and o=='Hey', (s, o)
+
+        s, o=exec_command(pythonexe\
+                         +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
+        assert s==0 and o=='Hi', (s, o)
+    elif 0:
+        s, o=exec_command('echo Hello')
+        assert s==0 and o=='Hello', (s, o)
+
+        s, o=exec_command('echo a%AAA%')
+        assert s==0 and o=='a', (s, o)
+
+        s, o=exec_command('echo a%AAA%', AAA='Tere')
+        assert s==0 and o=='aTere', (s, o)
+
+        os.environ['BBB'] = 'Hi'
+        s, o=exec_command('echo a%BBB%')
+        assert s==0 and o=='aHi', (s, o)
+
+        s, o=exec_command('echo a%BBB%', BBB='Hey')
+        assert s==0 and o=='aHey', (s, o)
+        s, o=exec_command('echo a%BBB%')
+        assert s==0 and o=='aHi', (s, o)
+
+        s, o=exec_command('this_is_not_a_command')
+        assert s and o!='', (s, o)
+
+        s, o=exec_command('type not_existing_file')
+        assert s and o!='', (s, o)
+
+    s, o=exec_command('echo path=%path%')
+    assert s==0 and o!='', (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.stderr.write(sys.platform)"' \
+                     % pythonexe)
+    assert s==0 and o=='win32', (s, o)
+
+    s, o=exec_command('%s -c "raise \'Ignore me.\'"' % pythonexe)
+    assert s==1 and o, (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"'\
+                     % pythonexe)
+    assert s==0 and o=='012', (s, o)
+
+    s, o=exec_command('%s -c "import sys;sys.exit(15)"' % pythonexe)
+    assert s==15 and o=='', (s, o)
+
+    s, o=exec_command('%s -c "print \'Heipa\'"' % pythonexe)
+    assert s==0 and o=='Heipa', (s, o)
+
+    print ('ok')
+
+def test_posix(**kws):
+    s, o=exec_command("echo Hello",**kws)
+    assert s==0 and o=='Hello', (s, o)
+
+    s, o=exec_command('echo $AAA',**kws)
+    assert s==0 and o=='', (s, o)
+
+    s, o=exec_command('echo "$AAA"',AAA='Tere',**kws)
+    assert s==0 and o=='Tere', (s, o)
+
+
+    s, o=exec_command('echo "$AAA"',**kws)
+    assert s==0 and o=='', (s, o)
+
+    os.environ['BBB'] = 'Hi'
+    s, o=exec_command('echo "$BBB"',**kws)
+    assert s==0 and o=='Hi', (s, o)
+
+    s, o=exec_command('echo "$BBB"',BBB='Hey',**kws)
+    assert s==0 and o=='Hey', (s, o)
+
+    s, o=exec_command('echo "$BBB"',**kws)
+    assert s==0 and o=='Hi', (s, o)
+
+
+    s, o=exec_command('this_is_not_a_command',**kws)
+    assert s!=0 and o!='', (s, o)
+
+    s, o=exec_command('echo path=$PATH',**kws)
+    assert s==0 and o!='', (s, o)
+
+    s, o=exec_command('python -c "import sys,os;sys.stderr.write(os.name)"',**kws)
+    assert s==0 and o=='posix', (s, o)
+
+    s, o=exec_command('python -c "raise \'Ignore me.\'"',**kws)
+    assert s==1 and o, (s, o)
+
+    s, o=exec_command('python -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"',**kws)
+    assert s==0 and o=='012', (s, o)
+
+    s, o=exec_command('python -c "import sys;sys.exit(15)"',**kws)
+    assert s==15 and o=='', (s, o)
+
+    s, o=exec_command('python -c "print \'Heipa\'"',**kws)
+    assert s==0 and o=='Heipa', (s, o)
+
+    print ('ok')
+
+def test_execute_in(**kws):
+    pythonexe = get_pythonexe()
+    tmpfile = temp_file_name()
+    fn = os.path.basename(tmpfile)
+    tmpdir = os.path.dirname(tmpfile)
+    f = open(tmpfile, 'w')
+    f.write('Hello')
+    f.close()
+
+    s, o = exec_command('%s -c "print \'Ignore the following IOError:\','\
+                       'open(%r,\'r\')"' % (pythonexe, fn),**kws)
+    assert s and o!='', (s, o)
+    s, o = exec_command('%s -c "print open(%r,\'r\').read()"' % (pythonexe, fn),
+                       execute_in = tmpdir,**kws)
+    assert s==0 and o=='Hello', (s, o)
+    os.remove(tmpfile)
+    print ('ok')
+
+def test_svn(**kws):
+    s, o = exec_command(['svn', 'status'],**kws)
+    assert s, (s, o)
+    print ('svn ok')
+
+def test_cl(**kws):
+    if os.name=='nt':
+        s, o = exec_command(['cl', '/V'],**kws)
+        assert s, (s, o)
+        print ('cl ok')
+
+if os.name=='posix':
+    test = test_posix
+elif os.name in ['nt', 'dos']:
+    test = test_nt
+else:
+    raise NotImplementedError('exec_command tests for ', os.name)
+
+############################################################
+
+if __name__ == "__main__":
+
+    test(use_tee=0)
+    test(use_tee=1)
+    test_execute_in(use_tee=0)
+    test_execute_in(use_tee=1)
+    test_svn(use_tee=1)
+    test_cl(use_tee=1)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/extension.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/extension.py
new file mode 100644
index 0000000000..344c66da02
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/extension.py
@@ -0,0 +1,90 @@
+"""distutils.extension
+
+Provides the Extension class, used to describe C/C++ extension
+modules in setup scripts.
+
+Overridden to support f2py.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+from distutils.extension import Extension as old_Extension
+
+if sys.version_info[0] >= 3:
+    basestring = str
+
+
+cxx_ext_re = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
+fortran_pyf_ext_re = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+
+class Extension(old_Extension):
+    def __init__ (self, name, sources,
+                  include_dirs=None,
+                  define_macros=None,
+                  undef_macros=None,
+                  library_dirs=None,
+                  libraries=None,
+                  runtime_library_dirs=None,
+                  extra_objects=None,
+                  extra_compile_args=None,
+                  extra_link_args=None,
+                  export_symbols=None,
+                  swig_opts=None,
+                  depends=None,
+                  language=None,
+                  f2py_options=None,
+                  module_dirs=None,
+                  extra_f77_compile_args=None,
+                  extra_f90_compile_args=None,
+                 ):
+        old_Extension.__init__(self, name, [],
+                               include_dirs,
+                               define_macros,
+                               undef_macros,
+                               library_dirs,
+                               libraries,
+                               runtime_library_dirs,
+                               extra_objects,
+                               extra_compile_args,
+                               extra_link_args,
+                               export_symbols)
+        # Avoid assert statements checking that sources contains strings:
+        self.sources = sources
+
+        # Python 2.4 distutils new features
+        self.swig_opts = swig_opts or []
+        # swig_opts is assumed to be a list. Here we handle the case where it
+        # is specified as a string instead.
+        if isinstance(self.swig_opts, basestring):
+            import warnings
+            msg = "swig_opts is specified as a string instead of a list"
+            warnings.warn(msg, SyntaxWarning)
+            self.swig_opts = self.swig_opts.split()
+
+        # Python 2.3 distutils new features
+        self.depends = depends or []
+        self.language = language
+
+        # numpy_distutils features
+        self.f2py_options = f2py_options or []
+        self.module_dirs = module_dirs or []
+        self.extra_f77_compile_args = extra_f77_compile_args or []
+        self.extra_f90_compile_args = extra_f90_compile_args or []
+
+        return
+
+    def has_cxx_sources(self):
+        for source in self.sources:
+            if cxx_ext_re(str(source)):
+                return True
+        return False
+
+    def has_f2py_sources(self):
+        for source in self.sources:
+            if fortran_pyf_ext_re(source):
+                return True
+        return False
+
+# class Extension
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
new file mode 100644
index 0000000000..0b1b1ee6d9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
@@ -0,0 +1,989 @@
+"""numpy.distutils.fcompiler
+
+Contains FCompiler, an abstract base class that defines the interface
+for the numpy.distutils Fortran compiler abstraction model.
+
+Terminology:
+
+To be consistent, where the term 'executable' is used, it means the single
+file, like 'gcc', that is executed, and should be a string. In contrast,
+'command' means the entire command line, like ['gcc', '-c', 'file.c'], and
+should be a list.
+
+But note that FCompiler.executables is actually a dictionary of commands.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['FCompiler', 'new_fcompiler', 'show_fcompilers',
+           'dummy_fortran_file']
+
+import os
+import sys
+import re
+import types
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from numpy.compat import open_latin1
+
+from distutils.sysconfig import get_python_lib
+from distutils.fancy_getopt import FancyGetopt
+from distutils.errors import DistutilsModuleError, \
+     DistutilsExecError, CompileError, LinkError, DistutilsPlatformError
+from distutils.util import split_quoted, strtobool
+
+from numpy.distutils.ccompiler import CCompiler, gen_lib_options
+from numpy.distutils import log
+from numpy.distutils.misc_util import is_string, all_strings, is_sequence, \
+    make_temp_file, get_shared_lib_extension
+from numpy.distutils.environment import EnvironmentConfig
+from numpy.distutils.exec_command import find_executable
+from numpy.distutils.compat import get_exception
+
+__metaclass__ = type
+
+class CompilerNotFound(Exception):
+    pass
+
+def flaglist(s):
+    if is_string(s):
+        return split_quoted(s)
+    else:
+        return s
+
+def str2bool(s):
+    if is_string(s):
+        return strtobool(s)
+    return bool(s)
+
+def is_sequence_of_strings(seq):
+    return is_sequence(seq) and all_strings(seq)
+
+class FCompiler(CCompiler):
+    """Abstract base class to define the interface that must be implemented
+    by real Fortran compiler classes.
+
+    Methods that subclasses may redefine:
+
+        update_executables(), find_executables(), get_version()
+        get_flags(), get_flags_opt(), get_flags_arch(), get_flags_debug()
+        get_flags_f77(), get_flags_opt_f77(), get_flags_arch_f77(),
+        get_flags_debug_f77(), get_flags_f90(), get_flags_opt_f90(),
+        get_flags_arch_f90(), get_flags_debug_f90(),
+        get_flags_fix(), get_flags_linker_so()
+
+    DON'T call these methods (except get_version) after
+    constructing a compiler instance or inside any other method.
+    All methods, except update_executables() and find_executables(),
+    may call the get_version() method.
+
+    After constructing a compiler instance, always call customize(dist=None)
+    method that finalizes compiler construction and makes the following
+    attributes available:
+      compiler_f77
+      compiler_f90
+      compiler_fix
+      linker_so
+      archiver
+      ranlib
+      libraries
+      library_dirs
+    """
+
+    # These are the environment variables and distutils keys used.
+    # Each configuration descripition is
+    # (<hook name>, <environment variable>, <key in distutils.cfg>, <convert>)
+    # The hook names are handled by the self._environment_hook method.
+    #  - names starting with 'self.' call methods in this class
+    #  - names starting with 'exe.' return the key in the executables dict
+    #  - names like 'flags.YYY' return self.get_flag_YYY()
+    # convert is either None or a function to convert a string to the
+    # appropiate type used.
+
+    distutils_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        noopt = (None, None, 'noopt', str2bool),
+        noarch = (None, None, 'noarch', str2bool),
+        debug = (None, None, 'debug', str2bool),
+        verbose = (None, None, 'verbose', str2bool),
+    )
+
+    command_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec', None),
+        compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec', None),
+        compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec', None),
+        version_cmd = ('exe.version_cmd', None, None, None),
+        linker_so = ('exe.linker_so', 'LDSHARED', 'ldshared', None),
+        linker_exe = ('exe.linker_exe', 'LD', 'ld', None),
+        archiver = (None, 'AR', 'ar', None),
+        ranlib = (None, 'RANLIB', 'ranlib', None),
+    )
+
+    flag_vars = EnvironmentConfig(
+        distutils_section='config_fc',
+        f77 = ('flags.f77', 'F77FLAGS', 'f77flags', flaglist),
+        f90 = ('flags.f90', 'F90FLAGS', 'f90flags', flaglist),
+        free = ('flags.free', 'FREEFLAGS', 'freeflags', flaglist),
+        fix = ('flags.fix', None, None, flaglist),
+        opt = ('flags.opt', 'FOPT', 'opt', flaglist),
+        opt_f77 = ('flags.opt_f77', None, None, flaglist),
+        opt_f90 = ('flags.opt_f90', None, None, flaglist),
+        arch = ('flags.arch', 'FARCH', 'arch', flaglist),
+        arch_f77 = ('flags.arch_f77', None, None, flaglist),
+        arch_f90 = ('flags.arch_f90', None, None, flaglist),
+        debug = ('flags.debug', 'FDEBUG', 'fdebug', flaglist),
+        debug_f77 = ('flags.debug_f77', None, None, flaglist),
+        debug_f90 = ('flags.debug_f90', None, None, flaglist),
+        flags = ('self.get_flags', 'FFLAGS', 'fflags', flaglist),
+        linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags', flaglist),
+        linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags', flaglist),
+        ar = ('flags.ar', 'ARFLAGS', 'arflags', flaglist),
+    )
+
+    language_map = {'.f': 'f77',
+                    '.for': 'f77',
+                    '.F': 'f77',    # XXX: needs preprocessor
+                    '.ftn': 'f77',
+                    '.f77': 'f77',
+                    '.f90': 'f90',
+                    '.F90': 'f90',  # XXX: needs preprocessor
+                    '.f95': 'f90',
+                    }
+    language_order = ['f90', 'f77']
+
+
+    # These will be set by the subclass
+
+    compiler_type = None
+    compiler_aliases = ()
+    version_pattern = None
+
+    possible_executables = []
+    executables = {
+        'version_cmd': ["f77", "-v"],
+        'compiler_f77': ["f77"],
+        'compiler_f90': ["f90"],
+        'compiler_fix': ["f90", "-fixed"],
+        'linker_so': ["f90", "-shared"],
+        'linker_exe': ["f90"],
+        'archiver': ["ar", "-cr"],
+        'ranlib': None,
+        }
+
+    # If compiler does not support compiling Fortran 90 then it can
+    # suggest using another compiler. For example, gnu would suggest
+    # gnu95 compiler type when there are F90 sources.
+    suggested_f90_compiler = None
+
+    compile_switch = "-c"
+    object_switch = "-o "   # Ending space matters! It will be stripped
+                            # but if it is missing then object_switch
+                            # will be prefixed to object file name by
+                            # string concatenation.
+    library_switch = "-o "  # Ditto!
+
+    # Switch to specify where module files are created and searched
+    # for USE statement.  Normally it is a string and also here ending
+    # space matters. See above.
+    module_dir_switch = None
+
+    # Switch to specify where module files are searched for USE statement.
+    module_include_switch = '-I'
+
+    pic_flags = []           # Flags to create position-independent code
+
+    src_extensions = ['.for', '.ftn', '.f77', '.f', '.f90', '.f95', '.F', '.F90', '.FOR']
+    obj_extension = ".o"
+
+    shared_lib_extension = get_shared_lib_extension()
+    static_lib_extension = ".a"  # or .lib
+    static_lib_format = "lib%s%s" # or %s%s
+    shared_lib_format = "%s%s"
+    exe_extension = ""
+
+    _exe_cache = {}
+
+    _executable_keys = ['version_cmd', 'compiler_f77', 'compiler_f90',
+                        'compiler_fix', 'linker_so', 'linker_exe', 'archiver',
+                        'ranlib']
+
+    # This will be set by new_fcompiler when called in
+    # command/{build_ext.py, build_clib.py, config.py} files.
+    c_compiler = None
+
+    # extra_{f77,f90}_compile_args are set by build_ext.build_extension method
+    extra_f77_compile_args = []
+    extra_f90_compile_args = []
+
+    def __init__(self, *args, **kw):
+        CCompiler.__init__(self, *args, **kw)
+        self.distutils_vars = self.distutils_vars.clone(self._environment_hook)
+        self.command_vars = self.command_vars.clone(self._environment_hook)
+        self.flag_vars = self.flag_vars.clone(self._environment_hook)
+        self.executables = self.executables.copy()
+        for e in self._executable_keys:
+            if e not in self.executables:
+                self.executables[e] = None
+
+        # Some methods depend on .customize() being called first, so
+        # this keeps track of whether that's happened yet.
+        self._is_customised = False
+
+    def __copy__(self):
+        obj = self.__new__(self.__class__)
+        obj.__dict__.update(self.__dict__)
+        obj.distutils_vars = obj.distutils_vars.clone(obj._environment_hook)
+        obj.command_vars = obj.command_vars.clone(obj._environment_hook)
+        obj.flag_vars = obj.flag_vars.clone(obj._environment_hook)
+        obj.executables = obj.executables.copy()
+        return obj
+
+    def copy(self):
+        return self.__copy__()
+
+    # Use properties for the attributes used by CCompiler. Setting them
+    # as attributes from the self.executables dictionary is error-prone,
+    # so we get them from there each time.
+    def _command_property(key):
+        def fget(self):
+            assert self._is_customised
+            return self.executables[key]
+        return property(fget=fget)
+    version_cmd = _command_property('version_cmd')
+    compiler_f77 = _command_property('compiler_f77')
+    compiler_f90 = _command_property('compiler_f90')
+    compiler_fix = _command_property('compiler_fix')
+    linker_so = _command_property('linker_so')
+    linker_exe = _command_property('linker_exe')
+    archiver = _command_property('archiver')
+    ranlib = _command_property('ranlib')
+
+    # Make our terminology consistent.
+    def set_executable(self, key, value):
+        self.set_command(key, value)
+
+    def set_commands(self, **kw):
+        for k, v in kw.items():
+            self.set_command(k, v)
+
+    def set_command(self, key, value):
+        if not key in self._executable_keys:
+            raise ValueError(
+                "unknown executable '%s' for class %s" %
+                (key, self.__class__.__name__))
+        if is_string(value):
+            value = split_quoted(value)
+        assert value is None or is_sequence_of_strings(value[1:]), (key, value)
+        self.executables[key] = value
+
+    ######################################################################
+    ## Methods that subclasses may redefine. But don't call these methods!
+    ## They are private to FCompiler class and may return unexpected
+    ## results if used elsewhere. So, you have been warned..
+
+    def find_executables(self):
+        """Go through the self.executables dictionary, and attempt to
+        find and assign appropiate executables.
+
+        Executable names are looked for in the environment (environment
+        variables, the distutils.cfg, and command line), the 0th-element of
+        the command list, and the self.possible_executables list.
+
+        Also, if the 0th element is "<F77>" or "<F90>", the Fortran 77
+        or the Fortran 90 compiler executable is used, unless overridden
+        by an environment setting.
+
+        Subclasses should call this if overriden.
+        """
+        assert self._is_customised
+        exe_cache = self._exe_cache
+        def cached_find_executable(exe):
+            if exe in exe_cache:
+                return exe_cache[exe]
+            fc_exe = find_executable(exe)
+            exe_cache[exe] = exe_cache[fc_exe] = fc_exe
+            return fc_exe
+        def verify_command_form(name, value):
+            if value is not None and not is_sequence_of_strings(value):
+                raise ValueError(
+                    "%s value %r is invalid in class %s" %
+                    (name, value, self.__class__.__name__))
+        def set_exe(exe_key, f77=None, f90=None):
+            cmd = self.executables.get(exe_key, None)
+            if not cmd:
+                return None
+            # Note that we get cmd[0] here if the environment doesn't
+            # have anything set
+            exe_from_environ = getattr(self.command_vars, exe_key)
+            if not exe_from_environ:
+                possibles = [f90, f77] + self.possible_executables
+            else:
+                possibles = [exe_from_environ] + self.possible_executables
+
+            seen = set()
+            unique_possibles = []
+            for e in possibles:
+                if e == '<F77>':
+                    e = f77
+                elif e == '<F90>':
+                    e = f90
+                if not e or e in seen:
+                    continue
+                seen.add(e)
+                unique_possibles.append(e)
+
+            for exe in unique_possibles:
+                fc_exe = cached_find_executable(exe)
+                if fc_exe:
+                    cmd[0] = fc_exe
+                    return fc_exe
+            self.set_command(exe_key, None)
+            return None
+
+        ctype = self.compiler_type
+        f90 = set_exe('compiler_f90')
+        if not f90:
+            f77 = set_exe('compiler_f77')
+            if f77:
+                log.warn('%s: no Fortran 90 compiler found' % ctype)
+            else:
+                raise CompilerNotFound('%s: f90 nor f77' % ctype)
+        else:
+            f77 = set_exe('compiler_f77', f90=f90)
+            if not f77:
+                log.warn('%s: no Fortran 77 compiler found' % ctype)
+            set_exe('compiler_fix', f90=f90)
+
+        set_exe('linker_so', f77=f77, f90=f90)
+        set_exe('linker_exe', f77=f77, f90=f90)
+        set_exe('version_cmd', f77=f77, f90=f90)
+        set_exe('archiver')
+        set_exe('ranlib')
+
+    def update_executables(elf):
+        """Called at the beginning of customisation. Subclasses should
+        override this if they need to set up the executables dictionary.
+
+        Note that self.find_executables() is run afterwards, so the
+        self.executables dictionary values can contain <F77> or <F90> as
+        the command, which will be replaced by the found F77 or F90
+        compiler.
+        """
+        pass
+
+    def get_flags(self):
+        """List of flags common to all compiler types."""
+        return [] + self.pic_flags
+
+    def _get_command_flags(self, key):
+        cmd = self.executables.get(key, None)
+        if cmd is None:
+            return []
+        return cmd[1:]
+
+    def get_flags_f77(self):
+        """List of Fortran 77 specific flags."""
+        return self._get_command_flags('compiler_f77')
+    def get_flags_f90(self):
+        """List of Fortran 90 specific flags."""
+        return self._get_command_flags('compiler_f90')
+    def get_flags_free(self):
+        """List of Fortran 90 free format specific flags."""
+        return []
+    def get_flags_fix(self):
+        """List of Fortran 90 fixed format specific flags."""
+        return self._get_command_flags('compiler_fix')
+    def get_flags_linker_so(self):
+        """List of linker flags to build a shared library."""
+        return self._get_command_flags('linker_so')
+    def get_flags_linker_exe(self):
+        """List of linker flags to build an executable."""
+        return self._get_command_flags('linker_exe')
+    def get_flags_ar(self):
+        """List of archiver flags. """
+        return self._get_command_flags('archiver')
+    def get_flags_opt(self):
+        """List of architecture independent compiler flags."""
+        return []
+    def get_flags_arch(self):
+        """List of architecture dependent compiler flags."""
+        return []
+    def get_flags_debug(self):
+        """List of compiler flags to compile with debugging information."""
+        return []
+
+    get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt
+    get_flags_arch_f77 = get_flags_arch_f90 = get_flags_arch
+    get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug
+
+    def get_libraries(self):
+        """List of compiler libraries."""
+        return self.libraries[:]
+    def get_library_dirs(self):
+        """List of compiler library directories."""
+        return self.library_dirs[:]
+
+    def get_version(self, force=False, ok_status=[0]):
+        assert self._is_customised
+        version = CCompiler.get_version(self, force=force, ok_status=ok_status)
+        if version is None:
+            raise CompilerNotFound()
+        return version
+
+    ############################################################
+
+    ## Public methods:
+
+    def customize(self, dist = None):
+        """Customize Fortran compiler.
+
+        This method gets Fortran compiler specific information from
+        (i) class definition, (ii) environment, (iii) distutils config
+        files, and (iv) command line (later overrides earlier).
+
+        This method should be always called after constructing a
+        compiler instance. But not in __init__ because Distribution
+        instance is needed for (iii) and (iv).
+        """
+        log.info('customize %s' % (self.__class__.__name__))
+
+        self._is_customised = True
+
+        self.distutils_vars.use_distribution(dist)
+        self.command_vars.use_distribution(dist)
+        self.flag_vars.use_distribution(dist)
+
+        self.update_executables()
+
+        # find_executables takes care of setting the compiler commands,
+        # version_cmd, linker_so, linker_exe, ar, and ranlib
+        self.find_executables()
+
+        noopt = self.distutils_vars.get('noopt', False)
+        noarch = self.distutils_vars.get('noarch', noopt)
+        debug = self.distutils_vars.get('debug', False)
+
+        f77 = self.command_vars.compiler_f77
+        f90 = self.command_vars.compiler_f90
+
+        f77flags = []
+        f90flags = []
+        freeflags = []
+        fixflags = []
+
+        if f77:
+            f77flags = self.flag_vars.f77
+        if f90:
+            f90flags = self.flag_vars.f90
+            freeflags = self.flag_vars.free
+        # XXX Assuming that free format is default for f90 compiler.
+        fix = self.command_vars.compiler_fix
+        if fix:
+            fixflags = self.flag_vars.fix + f90flags
+
+        oflags, aflags, dflags = [], [], []
+        # examine get_flags_<tag>_<compiler> for extra flags
+        # only add them if the method is different from get_flags_<tag>
+        def get_flags(tag, flags):
+            # note that self.flag_vars.<tag> calls self.get_flags_<tag>()
+            flags.extend(getattr(self.flag_vars, tag))
+            this_get = getattr(self, 'get_flags_' + tag)
+            for name, c, flagvar in [('f77', f77, f77flags),
+                                     ('f90', f90, f90flags),
+                                     ('f90', fix, fixflags)]:
+                t = '%s_%s' % (tag, name)
+                if c and this_get is not getattr(self, 'get_flags_' + t):
+                    flagvar.extend(getattr(self.flag_vars, t))
+        if not noopt:
+            get_flags('opt', oflags)
+            if not noarch:
+                get_flags('arch', aflags)
+        if debug:
+            get_flags('debug', dflags)
+
+        fflags = self.flag_vars.flags + dflags + oflags + aflags
+
+        if f77:
+            self.set_commands(compiler_f77=[f77]+f77flags+fflags)
+        if f90:
+            self.set_commands(compiler_f90=[f90]+freeflags+f90flags+fflags)
+        if fix:
+            self.set_commands(compiler_fix=[fix]+fixflags+fflags)
+
+
+        #XXX: Do we need LDSHARED->SOSHARED, LDFLAGS->SOFLAGS
+        linker_so = self.linker_so
+        if linker_so:
+            linker_so_flags = self.flag_vars.linker_so
+            if sys.platform.startswith('aix'):
+                python_lib = get_python_lib(standard_lib=1)
+                ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
+                python_exp = os.path.join(python_lib, 'config', 'python.exp')
+                linker_so = [ld_so_aix] + linker_so + ['-bI:'+python_exp]
+            self.set_commands(linker_so=linker_so+linker_so_flags)
+
+        linker_exe = self.linker_exe
+        if linker_exe:
+            linker_exe_flags = self.flag_vars.linker_exe
+            self.set_commands(linker_exe=linker_exe+linker_exe_flags)
+
+        ar = self.command_vars.archiver
+        if ar:
+            arflags = self.flag_vars.ar
+            self.set_commands(archiver=[ar]+arflags)
+
+        self.set_library_dirs(self.get_library_dirs())
+        self.set_libraries(self.get_libraries())
+
+    def dump_properties(self):
+        """Print out the attributes of a compiler instance."""
+        props = []
+        for key in list(self.executables.keys()) + \
+                ['version', 'libraries', 'library_dirs',
+                 'object_switch', 'compile_switch']:
+            if hasattr(self, key):
+                v = getattr(self, key)
+                props.append((key, None, '= '+repr(v)))
+        props.sort()
+
+        pretty_printer = FancyGetopt(props)
+        for l in pretty_printer.generate_help("%s instance properties:" \
+                                              % (self.__class__.__name__)):
+            if l[:4]=='  --':
+                l = '  ' + l[4:]
+            print(l)
+
+    ###################
+
+    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+        """Compile 'src' to product 'obj'."""
+        src_flags = {}
+        if is_f_file(src) and not has_f90_header(src):
+            flavor = ':f77'
+            compiler = self.compiler_f77
+            src_flags = get_f77flags(src)
+            extra_compile_args = self.extra_f77_compile_args or []
+        elif is_free_format(src):
+            flavor = ':f90'
+            compiler = self.compiler_f90
+            if compiler is None:
+                raise DistutilsExecError('f90 not supported by %s needed for %s'\
+                      % (self.__class__.__name__, src))
+            extra_compile_args = self.extra_f90_compile_args or []
+        else:
+            flavor = ':fix'
+            compiler = self.compiler_fix
+            if compiler is None:
+                raise DistutilsExecError('f90 (fixed) not supported by %s needed for %s'\
+                      % (self.__class__.__name__, src))
+            extra_compile_args = self.extra_f90_compile_args or []
+        if self.object_switch[-1]==' ':
+            o_args = [self.object_switch.strip(), obj]
+        else:
+            o_args = [self.object_switch.strip()+obj]
+
+        assert self.compile_switch.strip()
+        s_args = [self.compile_switch, src]
+
+        if extra_compile_args:
+            log.info('extra %s options: %r' \
+                     % (flavor[1:], ' '.join(extra_compile_args)))
+
+        extra_flags = src_flags.get(self.compiler_type, [])
+        if extra_flags:
+            log.info('using compile options from source: %r' \
+                     % ' '.join(extra_flags))
+
+        command = compiler + cc_args + extra_flags + s_args + o_args \
+                  + extra_postargs + extra_compile_args
+
+        display = '%s: %s' % (os.path.basename(compiler[0]) + flavor,
+                              src)
+        try:
+            self.spawn(command, display=display)
+        except DistutilsExecError:
+            msg = str(get_exception())
+            raise CompileError(msg)
+
+    def module_options(self, module_dirs, module_build_dir):
+        options = []
+        if self.module_dir_switch is not None:
+            if self.module_dir_switch[-1]==' ':
+                options.extend([self.module_dir_switch.strip(), module_build_dir])
+            else:
+                options.append(self.module_dir_switch.strip()+module_build_dir)
+        else:
+            print('XXX: module_build_dir=%r option ignored' % (module_build_dir))
+            print('XXX: Fix module_dir_switch for ', self.__class__.__name__)
+        if self.module_include_switch is not None:
+            for d in [module_build_dir]+module_dirs:
+                options.append('%s%s' % (self.module_include_switch, d))
+        else:
+            print('XXX: module_dirs=%r option ignored' % (module_dirs))
+            print('XXX: Fix module_include_switch for ', self.__class__.__name__)
+        return options
+
+    def library_option(self, lib):
+        return "-l" + lib
+    def library_dir_option(self, dir):
+        return "-L" + dir
+
+    def link(self, target_desc, objects,
+             output_filename, output_dir=None, libraries=None,
+             library_dirs=None, runtime_library_dirs=None,
+             export_symbols=None, debug=0, extra_preargs=None,
+             extra_postargs=None, build_temp=None, target_lang=None):
+        objects, output_dir = self._fix_object_args(objects, output_dir)
+        libraries, library_dirs, runtime_library_dirs = \
+            self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
+
+        lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
+                                   libraries)
+        if is_string(output_dir):
+            output_filename = os.path.join(output_dir, output_filename)
+        elif output_dir is not None:
+            raise TypeError("'output_dir' must be a string or None")
+
+        if self._need_link(objects, output_filename):
+            if self.library_switch[-1]==' ':
+                o_args = [self.library_switch.strip(), output_filename]
+            else:
+                o_args = [self.library_switch.strip()+output_filename]
+
+            if is_string(self.objects):
+                ld_args = objects + [self.objects]
+            else:
+                ld_args = objects + self.objects
+            ld_args = ld_args + lib_opts + o_args
+            if debug:
+                ld_args[:0] = ['-g']
+            if extra_preargs:
+                ld_args[:0] = extra_preargs
+            if extra_postargs:
+                ld_args.extend(extra_postargs)
+            self.mkpath(os.path.dirname(output_filename))
+            if target_desc == CCompiler.EXECUTABLE:
+                linker = self.linker_exe[:]
+            else:
+                linker = self.linker_so[:]
+            command = linker + ld_args
+            try:
+                self.spawn(command)
+            except DistutilsExecError:
+                msg = str(get_exception())
+                raise LinkError(msg)
+        else:
+            log.debug("skipping %s (up-to-date)", output_filename)
+
+    def _environment_hook(self, name, hook_name):
+        if hook_name is None:
+            return None
+        if is_string(hook_name):
+            if hook_name.startswith('self.'):
+                hook_name = hook_name[5:]
+                hook = getattr(self, hook_name)
+                return hook()
+            elif hook_name.startswith('exe.'):
+                hook_name = hook_name[4:]
+                var = self.executables[hook_name]
+                if var:
+                    return var[0]
+                else:
+                    return None
+            elif hook_name.startswith('flags.'):
+                hook_name = hook_name[6:]
+                hook = getattr(self, 'get_flags_' + hook_name)
+                return hook()
+        else:
+            return hook_name()
+
+    ## class FCompiler
+
+_default_compilers = (
+    # sys.platform mappings
+    ('win32', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95',
+               'intelvem', 'intelem')),
+    ('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')),
+    ('linux.*', ('gnu95', 'intel', 'lahey', 'pg', 'absoft', 'nag', 'vast', 'compaq',
+                'intele', 'intelem', 'gnu', 'g95', 'pathf95')),
+    ('darwin.*', ('gnu95', 'nag', 'absoft', 'ibm', 'intel', 'gnu', 'g95', 'pg')),
+    ('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')),
+    ('irix.*', ('mips', 'gnu', 'gnu95',)),
+    ('aix.*', ('ibm', 'gnu', 'gnu95',)),
+    # os.name mappings
+    ('posix', ('gnu', 'gnu95',)),
+    ('nt', ('gnu', 'gnu95',)),
+    ('mac', ('gnu95', 'gnu', 'pg')),
+    )
+
+fcompiler_class = None
+fcompiler_aliases = None
+
+def load_all_fcompiler_classes():
+    """Cache all the FCompiler classes found in modules in the
+    numpy.distutils.fcompiler package.
+    """
+    from glob import glob
+    global fcompiler_class, fcompiler_aliases
+    if fcompiler_class is not None:
+        return
+    pys = os.path.join(os.path.dirname(__file__), '*.py')
+    fcompiler_class = {}
+    fcompiler_aliases = {}
+    for fname in glob(pys):
+        module_name, ext = os.path.splitext(os.path.basename(fname))
+        module_name = 'numpy.distutils.fcompiler.' + module_name
+        __import__ (module_name)
+        module = sys.modules[module_name]
+        if hasattr(module, 'compilers'):
+            for cname in module.compilers:
+                klass = getattr(module, cname)
+                desc = (klass.compiler_type, klass, klass.description)
+                fcompiler_class[klass.compiler_type] = desc
+                for alias in klass.compiler_aliases:
+                    if alias in fcompiler_aliases:
+                        raise ValueError("alias %r defined for both %s and %s"
+                                         % (alias, klass.__name__,
+                                            fcompiler_aliases[alias][1].__name__))
+                    fcompiler_aliases[alias] = desc
+
+def _find_existing_fcompiler(compiler_types,
+                             osname=None, platform=None,
+                             requiref90=False,
+                             c_compiler=None):
+    from numpy.distutils.core import get_distribution
+    dist = get_distribution(always=True)
+    for compiler_type in compiler_types:
+        v = None
+        try:
+            c = new_fcompiler(plat=platform, compiler=compiler_type,
+                              c_compiler=c_compiler)
+            c.customize(dist)
+            v = c.get_version()
+            if requiref90 and c.compiler_f90 is None:
+                v = None
+                new_compiler = c.suggested_f90_compiler
+                if new_compiler:
+                    log.warn('Trying %r compiler as suggested by %r '
+                             'compiler for f90 support.' % (compiler_type,
+                                                            new_compiler))
+                    c = new_fcompiler(plat=platform, compiler=new_compiler,
+                                      c_compiler=c_compiler)
+                    c.customize(dist)
+                    v = c.get_version()
+                    if v is not None:
+                        compiler_type = new_compiler
+            if requiref90 and c.compiler_f90 is None:
+                raise ValueError('%s does not support compiling f90 codes, '
+                                 'skipping.' % (c.__class__.__name__))
+        except DistutilsModuleError:
+            log.debug("_find_existing_fcompiler: compiler_type='%s' raised DistutilsModuleError", compiler_type)
+        except CompilerNotFound:
+            log.debug("_find_existing_fcompiler: compiler_type='%s' not found", compiler_type)
+        if v is not None:
+            return compiler_type
+    return None
+
+def available_fcompilers_for_platform(osname=None, platform=None):
+    if osname is None:
+        osname = os.name
+    if platform is None:
+        platform = sys.platform
+    matching_compiler_types = []
+    for pattern, compiler_type in _default_compilers:
+        if re.match(pattern, platform) or re.match(pattern, osname):
+            for ct in compiler_type:
+                if ct not in matching_compiler_types:
+                    matching_compiler_types.append(ct)
+    if not matching_compiler_types:
+        matching_compiler_types.append('gnu')
+    return matching_compiler_types
+
+def get_default_fcompiler(osname=None, platform=None, requiref90=False,
+                          c_compiler=None):
+    """Determine the default Fortran compiler to use for the given
+    platform."""
+    matching_compiler_types = available_fcompilers_for_platform(osname,
+                                                                platform)
+    compiler_type =  _find_existing_fcompiler(matching_compiler_types,
+                                              osname=osname,
+                                              platform=platform,
+                                              requiref90=requiref90,
+                                              c_compiler=c_compiler)
+    return compiler_type
+
+# Flag to avoid rechecking for Fortran compiler every time
+failed_fcompilers = set()
+
+def new_fcompiler(plat=None,
+                  compiler=None,
+                  verbose=0,
+                  dry_run=0,
+                  force=0,
+                  requiref90=False,
+                  c_compiler = None):
+    """Generate an instance of some FCompiler subclass for the supplied
+    platform/compiler combination.
+    """
+    global failed_fcompilers
+    fcompiler_key = (plat, compiler)
+    if fcompiler_key in failed_fcompilers:
+        return None
+
+    load_all_fcompiler_classes()
+    if plat is None:
+        plat = os.name
+    if compiler is None:
+        compiler = get_default_fcompiler(plat, requiref90=requiref90,
+                                         c_compiler=c_compiler)
+    if compiler in fcompiler_class:
+        module_name, klass, long_description = fcompiler_class[compiler]
+    elif compiler in fcompiler_aliases:
+        module_name, klass, long_description = fcompiler_aliases[compiler]
+    else:
+        msg = "don't know how to compile Fortran code on platform '%s'" % plat
+        if compiler is not None:
+            msg = msg + " with '%s' compiler." % compiler
+            msg = msg + " Supported compilers are: %s)" \
+                  % (','.join(fcompiler_class.keys()))
+        log.warn(msg)
+        failed_fcompilers.add(fcompiler_key)
+        return None
+
+    compiler = klass(verbose=verbose, dry_run=dry_run, force=force)
+    compiler.c_compiler = c_compiler
+    return compiler
+
+def show_fcompilers(dist=None):
+    """Print list of available compilers (used by the "--help-fcompiler"
+    option to "config_fc").
+    """
+    if dist is None:
+        from distutils.dist import Distribution
+        from numpy.distutils.command.config_compiler import config_fc
+        dist = Distribution()
+        dist.script_name = os.path.basename(sys.argv[0])
+        dist.script_args = ['config_fc'] + sys.argv[1:]
+        try:
+            dist.script_args.remove('--help-fcompiler')
+        except ValueError:
+            pass
+        dist.cmdclass['config_fc'] = config_fc
+        dist.parse_config_files()
+        dist.parse_command_line()
+    compilers = []
+    compilers_na = []
+    compilers_ni = []
+    if not fcompiler_class:
+        load_all_fcompiler_classes()
+    platform_compilers = available_fcompilers_for_platform()
+    for compiler in platform_compilers:
+        v = None
+        log.set_verbosity(-2)
+        try:
+            c = new_fcompiler(compiler=compiler, verbose=dist.verbose)
+            c.customize(dist)
+            v = c.get_version()
+        except (DistutilsModuleError, CompilerNotFound):
+            e = get_exception()
+            log.debug("show_fcompilers: %s not found" % (compiler,))
+            log.debug(repr(e))
+
+        if v is None:
+            compilers_na.append(("fcompiler="+compiler, None,
+                              fcompiler_class[compiler][2]))
+        else:
+            c.dump_properties()
+            compilers.append(("fcompiler="+compiler, None,
+                              fcompiler_class[compiler][2] + ' (%s)' % v))
+
+    compilers_ni = list(set(fcompiler_class.keys()) - set(platform_compilers))
+    compilers_ni = [("fcompiler="+fc, None, fcompiler_class[fc][2])
+                    for fc in compilers_ni]
+
+    compilers.sort()
+    compilers_na.sort()
+    compilers_ni.sort()
+    pretty_printer = FancyGetopt(compilers)
+    pretty_printer.print_help("Fortran compilers found:")
+    pretty_printer = FancyGetopt(compilers_na)
+    pretty_printer.print_help("Compilers available for this "
+                              "platform, but not found:")
+    if compilers_ni:
+        pretty_printer = FancyGetopt(compilers_ni)
+        pretty_printer.print_help("Compilers not available on this platform:")
+    print("For compiler details, run 'config_fc --verbose' setup command.")
+
+
+def dummy_fortran_file():
+    fo, name = make_temp_file(suffix='.f')
+    fo.write("      subroutine dummy()\n      end\n")
+    fo.close()
+    return name[:-2]
+
+
+is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
+_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
+_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]', re.I).match
+
+def is_free_format(file):
+    """Check if file is in free format Fortran."""
+    # f90 allows both fixed and free format, assuming fixed unless
+    # signs of free format are detected.
+    result = 0
+    f = open_latin1(file, 'r')
+    line = f.readline()
+    n = 10000 # the number of non-comment lines to scan for hints
+    if _has_f_header(line):
+        n = 0
+    elif _has_f90_header(line):
+        n = 0
+        result = 1
+    while n>0 and line:
+        line = line.rstrip()
+        if line and line[0]!='!':
+            n -= 1
+            if (line[0]!='\t' and _free_f90_start(line[:5])) or line[-1:]=='&':
+                result = 1
+                break
+        line = f.readline()
+    f.close()
+    return result
+
+def has_f90_header(src):
+    f = open_latin1(src, 'r')
+    line = f.readline()
+    f.close()
+    return _has_f90_header(line) or _has_fix_header(line)
+
+_f77flags_re = re.compile(r'(c|)f77flags\s*\(\s*(?P<fcname>\w+)\s*\)\s*=\s*(?P<fflags>.*)', re.I)
+def get_f77flags(src):
+    """
+    Search the first 20 lines of fortran 77 code for line pattern
+      `CF77FLAGS(<fcompiler type>)=<f77 flags>`
+    Return a dictionary {<fcompiler type>:<f77 flags>}.
+    """
+    flags = {}
+    f = open_latin1(src, 'r')
+    i = 0
+    for line in f:
+        i += 1
+        if i>20: break
+        m = _f77flags_re.match(line)
+        if not m: continue
+        fcname = m.group('fcname').strip()
+        fflags = m.group('fflags').strip()
+        flags[fcname] = split_quoted(fflags)
+    f.close()
+    return flags
+
+# TODO: implement get_f90flags and use it in _compile similarly to get_f77flags
+
+if __name__ == '__main__':
+    show_fcompilers()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
new file mode 100644
index 0000000000..bde0529bea
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
@@ -0,0 +1,160 @@
+
+# http://www.absoft.com/literature/osxuserguide.pdf
+# http://www.absoft.com/documentation.html
+
+# Notes:
+# - when using -g77 then use -DUNDERSCORE_G77 to compile f2py
+#   generated extension modules (works for f2py v2.45.241_1936 and up)
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.cpuinfo import cpu
+from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
+from numpy.distutils.misc_util import cyg2win32
+
+compilers = ['AbsoftFCompiler']
+
+class AbsoftFCompiler(FCompiler):
+
+    compiler_type = 'absoft'
+    description = 'Absoft Corp Fortran Compiler'
+    #version_pattern = r'FORTRAN 77 Compiler (?P<version>[^\s*,]*).*?Absoft Corp'
+    version_pattern = r'(f90:.*?(Absoft Pro FORTRAN Version|FORTRAN 77 Compiler|Absoft Fortran Compiler Version|Copyright Absoft Corporation.*?Version))'+\
+                       r' (?P<version>[^\s*,]*)(.*?Absoft Corp|)'
+
+    # on windows: f90 -V -c dummy.f
+    # f90: Copyright Absoft Corporation 1994-1998 mV2; Cray Research, Inc. 1994-1996 CF90 (2.x.x.x  f36t87) Version 2.3 Wed Apr 19, 2006  13:05:16
+
+    # samt5735(8)$ f90 -V -c dummy.f
+    # f90: Copyright Absoft Corporation 1994-2002; Absoft Pro FORTRAN Version 8.0
+    # Note that fink installs g77 as f77, so need to use f90 for detection.
+
+    executables = {
+        'version_cmd'  : None,          # set by update_executables
+        'compiler_f77' : ["f77"],
+        'compiler_fix' : ["f90"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    if os.name=='nt':
+        library_switch = '/out:'      #No space after /out:!
+
+    module_dir_switch = None
+    module_include_switch = '-p'
+
+    def update_executables(self):
+        f = cyg2win32(dummy_fortran_file())
+        self.executables['version_cmd'] = ['<F90>', '-V', '-c',
+                                           f+'.f', '-o', f+'.o']
+
+    def get_flags_linker_so(self):
+        if os.name=='nt':
+            opt = ['/dll']
+        # The "-K shared" switches are being left in for pre-9.0 versions
+        # of Absoft though I don't think versions earlier than 9 can
+        # actually be used to build shared libraries.  In fact, version
+        # 8 of Absoft doesn't recognize "-K shared" and will fail.
+        elif self.get_version() >= '9.0':
+            opt = ['-shared']
+        else:
+            opt = ["-K", "shared"]
+        return opt
+
+    def library_dir_option(self, dir):
+        if os.name=='nt':
+            return ['-link', '/PATH:"%s"' % (dir)]
+        return "-L" + dir
+
+    def library_option(self, lib):
+        if os.name=='nt':
+            return '%s.lib' % (lib)
+        return "-l" + lib
+
+    def get_library_dirs(self):
+        opt = FCompiler.get_library_dirs(self)
+        d = os.environ.get('ABSOFT')
+        if d:
+            if self.get_version() >= '10.0':
+                # use shared libraries, the static libraries were not compiled -fPIC
+                prefix = 'sh'
+            else:
+                prefix = ''
+            if cpu.is_64bit():
+                suffix = '64'
+            else:
+                suffix = ''
+            opt.append(os.path.join(d, '%slib%s' % (prefix, suffix)))
+        return opt
+
+    def get_libraries(self):
+        opt = FCompiler.get_libraries(self)
+        if self.get_version() >= '11.0':
+            opt.extend(['af90math', 'afio', 'af77math', 'amisc'])
+        elif self.get_version() >= '10.0':
+            opt.extend(['af90math', 'afio', 'af77math', 'U77'])
+        elif self.get_version() >= '8.0':
+            opt.extend(['f90math', 'fio', 'f77math', 'U77'])
+        else:
+            opt.extend(['fio', 'f90math', 'fmath', 'U77'])
+        if os.name =='nt':
+            opt.append('COMDLG32')
+        return opt
+
+    def get_flags(self):
+        opt = FCompiler.get_flags(self)
+        if os.name != 'nt':
+            opt.extend(['-s'])
+            if self.get_version():
+                if self.get_version()>='8.2':
+                    opt.append('-fpic')
+        return opt
+
+    def get_flags_f77(self):
+        opt = FCompiler.get_flags_f77(self)
+        opt.extend(['-N22', '-N90', '-N110'])
+        v = self.get_version()
+        if os.name == 'nt':
+            if v and v>='8.0':
+                opt.extend(['-f', '-N15'])
+        else:
+            opt.append('-f')
+            if v:
+                if v<='4.6':
+                    opt.append('-B108')
+                else:
+                    # Though -N15 is undocumented, it works with
+                    # Absoft 8.0 on Linux
+                    opt.append('-N15')
+        return opt
+
+    def get_flags_f90(self):
+        opt = FCompiler.get_flags_f90(self)
+        opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX",
+                    "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"])
+        if self.get_version():
+            if self.get_version()>'4.6':
+                opt.extend(["-YDEALLOC=ALL"])
+        return opt
+
+    def get_flags_fix(self):
+        opt = FCompiler.get_flags_fix(self)
+        opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX",
+                    "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"])
+        opt.extend(["-f", "fixed"])
+        return opt
+
+    def get_flags_opt(self):
+        opt = ['-O']
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='absoft')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
new file mode 100644
index 0000000000..e25f244534
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
@@ -0,0 +1,128 @@
+
+#http://www.compaq.com/fortran/docs/
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.compat import get_exception
+from distutils.errors import DistutilsPlatformError
+
+compilers = ['CompaqFCompiler']
+if (os.name != 'posix' or sys.platform[:6] == 'cygwin') and not 'GCC' in sys.version:
+    # Otherwise we'd get a false positive on posix systems with
+    # case-insensitive filesystems (like darwin), because we'll pick
+    # up /bin/df
+    compilers.append('CompaqVisualFCompiler')
+
+class CompaqFCompiler(FCompiler):
+
+    compiler_type = 'compaq'
+    description = 'Compaq Fortran Compiler'
+    version_pattern = r'Compaq Fortran (?P<version>[^\s]*).*'
+
+    if sys.platform[:5]=='linux':
+        fc_exe = 'fort'
+    else:
+        fc_exe = 'f90'
+
+    executables = {
+        'version_cmd'  : ['<F90>', "-version"],
+        'compiler_f77' : [fc_exe, "-f77rtl", "-fixed"],
+        'compiler_fix' : [fc_exe, "-fixed"],
+        'compiler_f90' : [fc_exe],
+        'linker_so'    : ['<F90>'],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    module_dir_switch = '-module ' # not tested
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        return ['-assume no2underscore', '-nomixed_str_len_arg']
+    def get_flags_debug(self):
+        return ['-g', '-check bounds']
+    def get_flags_opt(self):
+        return ['-O4', '-align dcommons', '-assume bigarrays',
+                '-assume nozsize', '-math_library fast']
+    def get_flags_arch(self):
+        return ['-arch host', '-tune host']
+    def get_flags_linker_so(self):
+        if sys.platform[:5]=='linux':
+            return ['-shared']
+        return ['-shared', '-Wl,-expect_unresolved,*']
+
+class CompaqVisualFCompiler(FCompiler):
+
+    compiler_type = 'compaqv'
+    description = 'DIGITAL or Compaq Visual Fortran Compiler'
+    version_pattern = r'(DIGITAL|Compaq) Visual Fortran Optimizing Compiler'\
+                      ' Version (?P<version>[^\s]*).*'
+
+    compile_switch = '/compile_only'
+    object_switch = '/object:'
+    library_switch = '/OUT:'      #No space after /OUT:!
+
+    static_lib_extension = ".lib"
+    static_lib_format = "%s%s"
+    module_dir_switch = '/module:'
+    module_include_switch = '/I'
+
+    ar_exe = 'lib.exe'
+    fc_exe = 'DF'
+
+    if sys.platform=='win32':
+        from numpy.distutils.msvccompiler import MSVCCompiler
+
+        try:
+            m = MSVCCompiler()
+            m.initialize()
+            ar_exe = m.lib
+        except DistutilsPlatformError:
+            pass
+        except AttributeError:
+            msg = get_exception()
+            if '_MSVCCompiler__root' in str(msg):
+                print('Ignoring "%s" (I think it is msvccompiler.py bug)' % (msg))
+            else:
+                raise
+        except IOError:
+            e = get_exception()
+            if not "vcvarsall.bat" in str(e):
+                print("Unexpected IOError in", __file__)
+                raise e
+        except ValueError:
+            e = get_exception()
+            if not "path']" in str(e):
+                print("Unexpected ValueError in", __file__)
+                raise e
+
+    executables = {
+        'version_cmd'  : ['<F90>', "/what"],
+        'compiler_f77' : [fc_exe, "/f77rtl", "/fixed"],
+        'compiler_fix' : [fc_exe, "/fixed"],
+        'compiler_f90' : [fc_exe],
+        'linker_so'    : ['<F90>'],
+        'archiver'     : [ar_exe, "/OUT:"],
+        'ranlib'       : None
+        }
+
+    def get_flags(self):
+        return ['/nologo', '/MD', '/WX', '/iface=(cref,nomixed_str_len_arg)',
+                '/names:lowercase', '/assume:underscore']
+    def get_flags_opt(self):
+        return ['/Ox', '/fast', '/optimize:5', '/unroll:0', '/math_library:fast']
+    def get_flags_arch(self):
+        return ['/threads']
+    def get_flags_debug(self):
+        return ['/debug']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='compaq')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
new file mode 100644
index 0000000000..26f73b530e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
@@ -0,0 +1,45 @@
+# http://g95.sourceforge.net/
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['G95FCompiler']
+
+class G95FCompiler(FCompiler):
+    compiler_type = 'g95'
+    description = 'G95 Fortran Compiler'
+
+#    version_pattern = r'G95 \((GCC (?P<gccversion>[\d.]+)|.*?) \(g95!\) (?P<version>.*)\).*'
+    # $ g95 --version
+    # G95 (GCC 4.0.3 (g95!) May 22 2006)
+
+    version_pattern = r'G95 \((GCC (?P<gccversion>[\d.]+)|.*?) \(g95 (?P<version>.*)!\) (?P<date>.*)\).*'
+    # $ g95 --version
+    # G95 (GCC 4.0.3 (g95 0.90!) Aug 22 2006)
+
+    executables = {
+        'version_cmd'  : ["<F90>", "--version"],
+        'compiler_f77' : ["g95", "-ffixed-form"],
+        'compiler_fix' : ["g95", "-ffixed-form"],
+        'compiler_f90' : ["g95"],
+        'linker_so'    : ["<F90>", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    pic_flags = ['-fpic']
+    module_dir_switch = '-fmod='
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        return ['-fno-second-underscore']
+    def get_flags_opt(self):
+        return ['-O']
+    def get_flags_debug(self):
+        return ['-g']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    compiler = G95FCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
new file mode 100644
index 0000000000..dcca73c9ce
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
@@ -0,0 +1,391 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+import os
+import sys
+import warnings
+import platform
+import tempfile
+from subprocess import Popen, PIPE, STDOUT
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.exec_command import exec_command
+from numpy.distutils.misc_util import msvc_runtime_library
+from numpy.distutils.compat import get_exception
+
+compilers = ['GnuFCompiler', 'Gnu95FCompiler']
+
+TARGET_R = re.compile("Target: ([a-zA-Z0-9_\-]*)")
+
+# XXX: handle cross compilation
+def is_win64():
+    return sys.platform == "win32" and platform.architecture()[0] == "64bit"
+
+if is_win64():
+    #_EXTRAFLAGS = ["-fno-leading-underscore"]
+    _EXTRAFLAGS = []
+else:
+    _EXTRAFLAGS = []
+
+class GnuFCompiler(FCompiler):
+    compiler_type = 'gnu'
+    compiler_aliases = ('g77',)
+    description = 'GNU Fortran 77 compiler'
+
+    def gnu_version_match(self, version_string):
+        """Handle the different versions of GNU fortran compilers"""
+        # Strip warning(s) that may be emitted by gfortran
+        while version_string.startswith('gfortran: warning'):
+            version_string = version_string[version_string.find('\n')+1:]
+
+        # Gfortran versions from after 2010 will output a simple string
+        # (usually "x.y", "x.y.z" or "x.y.z-q") for ``-dumpversion``; older
+        # gfortrans may still return long version strings (``-dumpversion`` was
+        # an alias for ``--version``)
+        if len(version_string) <= 20:
+            # Try to find a valid version string
+            m = re.search(r'([0-9.]+)', version_string)
+            if m:
+                # g77 provides a longer version string that starts with GNU
+                # Fortran
+                if version_string.startswith('GNU Fortran'):
+                    return ('g77', m.group(1))
+
+                # gfortran only outputs a version string such as #.#.#, so check
+                # if the match is at the start of the string
+                elif m.start() == 0:
+                    return ('gfortran', m.group(1))
+        else:
+            # Output probably from --version, try harder:
+            m = re.search(r'GNU Fortran\s+95.*?([0-9-.]+)', version_string)
+            if m:
+                return ('gfortran', m.group(1))
+            m = re.search(r'GNU Fortran.*?\-?(\d*(?:\.\d+)+)', version_string)
+            if m:
+                v = m.group(1)
+                if v.startswith('0') or v.startswith('2') or v.startswith('3'):
+                    # the '0' is for early g77's
+                    return ('g77', v)
+                else:
+                    # at some point in the 4.x series, the ' 95' was dropped
+                    # from the version string
+                    return ('gfortran', v)
+
+        # If still nothing, raise an error to make the problem easy to find.
+        err = 'A valid Fortran version was not found in this string:\n'
+        raise ValueError(err + version_string)
+
+    def version_match(self, version_string):
+        v = self.gnu_version_match(version_string)
+        if not v or v[0] != 'g77':
+            return None
+        return v[1]
+
+    possible_executables = ['g77', 'f77']
+    executables = {
+        'version_cmd'  : [None, "-dumpversion"],
+        'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"],
+        'compiler_f90' : None,  # Use --fcompiler=gnu95 for f90 codes
+        'compiler_fix' : None,
+        'linker_so'    : [None, "-g", "-Wall"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"],
+        'linker_exe'   : [None, "-g", "-Wall"]
+        }
+    module_dir_switch = None
+    module_include_switch = None
+
+    # Cygwin: f771: warning: -fPIC ignored for target (all code is
+    # position independent)
+    if os.name != 'nt' and sys.platform != 'cygwin':
+        pic_flags = ['-fPIC']
+
+    # use -mno-cygwin for g77 when Python is not Cygwin-Python
+    if sys.platform == 'win32' and not 'GCC' in sys.version:
+        for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']:
+            executables[key].append('-mno-cygwin')
+
+    g2c = 'g2c'
+    suggested_f90_compiler = 'gnu95'
+
+    def get_flags_linker_so(self):
+        opt = self.linker_so[1:]
+        if sys.platform == 'darwin':
+            target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
+            # If MACOSX_DEPLOYMENT_TARGET is set, we simply trust the value
+            # and leave it alone.  But, distutils will complain if the
+            # environment's value is different from the one in the Python
+            # Makefile used to build Python.  We let disutils handle this
+            # error checking.
+            if not target:
+                # If MACOSX_DEPLOYMENT_TARGET is not set in the environment,
+                # we try to get it first from the Python Makefile and then we
+                # fall back to setting it to 10.3 to maximize the set of
+                # versions we can work with.  This is a reasonable default
+                # even when using the official Python dist and those derived
+                # from it.
+                import distutils.sysconfig as sc
+                g = {}
+                filename = sc.get_makefile_filename()
+                sc.parse_makefile(filename, g)
+                target = g.get('MACOSX_DEPLOYMENT_TARGET', '10.3')
+                os.environ['MACOSX_DEPLOYMENT_TARGET'] = target
+                if target == '10.3':
+                    s = 'Env. variable MACOSX_DEPLOYMENT_TARGET set to 10.3'
+                    warnings.warn(s)
+
+            opt.extend(['-undefined', 'dynamic_lookup', '-bundle'])
+        else:
+            opt.append("-shared")
+        if sys.platform.startswith('sunos'):
+            # SunOS often has dynamically loaded symbols defined in the
+            # static library libg2c.a  The linker doesn't like this.  To
+            # ignore the problem, use the -mimpure-text flag.  It isn't
+            # the safest thing, but seems to work. 'man gcc' says:
+            # ".. Instead of using -mimpure-text, you should compile all
+            #  source code with -fpic or -fPIC."
+            opt.append('-mimpure-text')
+        return opt
+
+    def get_libgcc_dir(self):
+        status, output = exec_command(self.compiler_f77 +
+                                      ['-print-libgcc-file-name'],
+                                      use_tee=0)
+        if not status:
+            return os.path.dirname(output)
+        return None
+
+    def get_library_dirs(self):
+        opt = []
+        if sys.platform[:5] != 'linux':
+            d = self.get_libgcc_dir()
+            if d:
+                # if windows and not cygwin, libg2c lies in a different folder
+                if sys.platform == 'win32' and not d.startswith('/usr/lib'):
+                    d = os.path.normpath(d)
+                    path = os.path.join(d, "lib%s.a" % self.g2c)
+                    if not os.path.exists(path):
+                        root = os.path.join(d, *((os.pardir,)*4))
+                        d2 = os.path.abspath(os.path.join(root, 'lib'))
+                        path = os.path.join(d2, "lib%s.a" % self.g2c)
+                        if os.path.exists(path):
+                            opt.append(d2)
+                opt.append(d)
+        return opt
+
+    def get_libraries(self):
+        opt = []
+        d = self.get_libgcc_dir()
+        if d is not None:
+            g2c = self.g2c + '-pic'
+            f = self.static_lib_format % (g2c, self.static_lib_extension)
+            if not os.path.isfile(os.path.join(d, f)):
+                g2c = self.g2c
+        else:
+            g2c = self.g2c
+
+        if g2c is not None:
+            opt.append(g2c)
+        c_compiler = self.c_compiler
+        if sys.platform == 'win32' and c_compiler and \
+               c_compiler.compiler_type == 'msvc':
+            # the following code is not needed (read: breaks) when using MinGW
+            # in case want to link F77 compiled code with MSVC
+            opt.append('gcc')
+            runtime_lib = msvc_runtime_library()
+            if runtime_lib:
+                opt.append(runtime_lib)
+        if sys.platform == 'darwin':
+            opt.append('cc_dynamic')
+        return opt
+
+    def get_flags_debug(self):
+        return ['-g']
+
+    def get_flags_opt(self):
+        v = self.get_version()
+        if v and v <= '3.3.3':
+            # With this compiler version building Fortran BLAS/LAPACK
+            # with -O3 caused failures in lib.lapack heevr,syevr tests.
+            opt = ['-O2']
+        else:
+            opt = ['-O3']
+        opt.append('-funroll-loops')
+        return opt
+
+    def _c_arch_flags(self):
+        """ Return detected arch flags from CFLAGS """
+        from distutils import sysconfig
+        try:
+            cflags = sysconfig.get_config_vars()['CFLAGS']
+        except KeyError:
+            return []
+        arch_re = re.compile(r"-arch\s+(\w+)")
+        arch_flags = []
+        for arch in arch_re.findall(cflags):
+            arch_flags += ['-arch', arch]
+        return arch_flags
+
+    def get_flags_arch(self):
+        return []
+
+    def runtime_library_dir_option(self, dir):
+        return '-Wl,-rpath="%s"' % dir
+
+class Gnu95FCompiler(GnuFCompiler):
+    compiler_type = 'gnu95'
+    compiler_aliases = ('gfortran',)
+    description = 'GNU Fortran 95 compiler'
+
+    def version_match(self, version_string):
+        v = self.gnu_version_match(version_string)
+        if not v or v[0] != 'gfortran':
+            return None
+        v = v[1]
+        if v >= '4.':
+            # gcc-4 series releases do not support -mno-cygwin option
+            pass
+        else:
+            # use -mno-cygwin flag for gfortran when Python is not
+            # Cygwin-Python
+            if sys.platform == 'win32':
+                for key in ['version_cmd', 'compiler_f77', 'compiler_f90',
+                            'compiler_fix', 'linker_so', 'linker_exe']:
+                    self.executables[key].append('-mno-cygwin')
+        return v
+
+    possible_executables = ['gfortran', 'f95']
+    executables = {
+        'version_cmd'  : ["<F90>", "-dumpversion"],
+        'compiler_f77' : [None, "-Wall", "-g", "-ffixed-form",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'compiler_f90' : [None, "-Wall", "-g",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'compiler_fix' : [None, "-Wall",  "-g","-ffixed-form",
+                          "-fno-second-underscore"] + _EXTRAFLAGS,
+        'linker_so'    : ["<F90>", "-Wall", "-g"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"],
+        'linker_exe'   : [None, "-Wall"]
+        }
+
+    module_dir_switch = '-J'
+    module_include_switch = '-I'
+
+    g2c = 'gfortran'
+
+    def _universal_flags(self, cmd):
+        """Return a list of -arch flags for every supported architecture."""
+        if not sys.platform == 'darwin':
+            return []
+        arch_flags = []
+        # get arches the C compiler gets.
+        c_archs = self._c_arch_flags()
+        if "i386" in c_archs:
+            c_archs[c_archs.index("i386")] = "i686"
+        # check the arches the Fortran compiler supports, and compare with
+        # arch flags from C compiler
+        for arch in ["ppc", "i686", "x86_64", "ppc64"]:
+            if _can_target(cmd, arch) and arch in c_archs:
+                arch_flags.extend(["-arch", arch])
+        return arch_flags
+
+    def get_flags(self):
+        flags = GnuFCompiler.get_flags(self)
+        arch_flags = self._universal_flags(self.compiler_f90)
+        if arch_flags:
+            flags[:0] = arch_flags
+        return flags
+
+    def get_flags_linker_so(self):
+        flags = GnuFCompiler.get_flags_linker_so(self)
+        arch_flags = self._universal_flags(self.linker_so)
+        if arch_flags:
+            flags[:0] = arch_flags
+        return flags
+
+    def get_library_dirs(self):
+        opt = GnuFCompiler.get_library_dirs(self)
+        if sys.platform == 'win32':
+            c_compiler = self.c_compiler
+            if c_compiler and c_compiler.compiler_type == "msvc":
+                target = self.get_target()
+                if target:
+                    d = os.path.normpath(self.get_libgcc_dir())
+                    root = os.path.join(d, *((os.pardir,)*4))
+                    path = os.path.join(root, "lib")
+                    mingwdir = os.path.normpath(path)
+                    if os.path.exists(os.path.join(mingwdir, "libmingwex.a")):
+                        opt.append(mingwdir)
+        return opt
+
+    def get_libraries(self):
+        opt = GnuFCompiler.get_libraries(self)
+        if sys.platform == 'darwin':
+            opt.remove('cc_dynamic')
+        if sys.platform == 'win32':
+            c_compiler = self.c_compiler
+            if c_compiler and c_compiler.compiler_type == "msvc":
+                if "gcc" in opt:
+                    i = opt.index("gcc")
+                    opt.insert(i+1, "mingwex")
+                    opt.insert(i+1, "mingw32")
+            # XXX: fix this mess, does not work for mingw
+            if is_win64():
+                c_compiler = self.c_compiler
+                if c_compiler and c_compiler.compiler_type == "msvc":
+                    return []
+                else:
+                    pass
+        return opt
+
+    def get_target(self):
+        status, output = exec_command(self.compiler_f77 +
+                                      ['-v'],
+                                      use_tee=0)
+        if not status:
+            m = TARGET_R.search(output)
+            if m:
+                return m.group(1)
+        return ""
+
+    def get_flags_opt(self):
+        if is_win64():
+            return ['-O0']
+        else:
+            return GnuFCompiler.get_flags_opt(self)
+
+def _can_target(cmd, arch):
+    """Return true if the architecture supports the -arch flag"""
+    newcmd = cmd[:]
+    fid, filename = tempfile.mkstemp(suffix=".f")
+    try:
+        d = os.path.dirname(filename)
+        output = os.path.splitext(filename)[0] + ".o"
+        try:
+            newcmd.extend(["-arch", arch, "-c", filename])
+            p = Popen(newcmd, stderr=STDOUT, stdout=PIPE, cwd=d)
+            p.communicate()
+            return p.returncode == 0
+        finally:
+            if os.path.exists(output):
+                os.remove(output)
+    finally:
+        os.remove(filename)
+    return False
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+
+    compiler = GnuFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
+
+    try:
+        compiler = Gnu95FCompiler()
+        compiler.customize()
+        print(compiler.get_version())
+    except Exception:
+        msg = get_exception()
+        print(msg)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
new file mode 100644
index 0000000000..9004961e1d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
@@ -0,0 +1,45 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['HPUXFCompiler']
+
+class HPUXFCompiler(FCompiler):
+
+    compiler_type = 'hpux'
+    description = 'HP Fortran 90 Compiler'
+    version_pattern =  r'HP F90 (?P<version>[^\s*,]*)'
+
+    executables = {
+        'version_cmd'  : ["f90", "+version"],
+        'compiler_f77' : ["f90"],
+        'compiler_fix' : ["f90"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["ld", "-b"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = None #XXX: fix me
+    module_include_switch = None #XXX: fix me
+    pic_flags = ['+Z']
+    def get_flags(self):
+        return self.pic_flags + ['+ppu', '+DD64']
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_libraries(self):
+        return ['m']
+    def get_library_dirs(self):
+        opt = ['/usr/lib/hpux64']
+        return opt
+    def get_version(self, force=0, ok_status=[256, 0, 1]):
+        # XXX status==256 may indicate 'unrecognized option' or
+        #     'no input file'. So, version_cmd needs more work.
+        return FCompiler.get_version(self, force, ok_status)
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(10)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='hpux')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
new file mode 100644
index 0000000000..cc65df9721
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
@@ -0,0 +1,96 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+
+from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.exec_command import exec_command, find_executable
+from numpy.distutils.misc_util import make_temp_file
+from distutils import log
+
+compilers = ['IBMFCompiler']
+
+class IBMFCompiler(FCompiler):
+    compiler_type = 'ibm'
+    description = 'IBM XL Fortran Compiler'
+    version_pattern =  r'(xlf\(1\)\s*|)IBM XL Fortran ((Advanced Edition |)Version |Enterprise Edition V|for AIX, V)(?P<version>[^\s*]*)'
+    #IBM XL Fortran Enterprise Edition V10.1 for AIX \nVersion: 10.01.0000.0004
+
+    executables = {
+        'version_cmd'  : ["<F77>", "-qversion"],
+        'compiler_f77' : ["xlf"],
+        'compiler_fix' : ["xlf90", "-qfixed"],
+        'compiler_f90' : ["xlf90"],
+        'linker_so'    : ["xlf95"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_version(self,*args,**kwds):
+        version = FCompiler.get_version(self,*args,**kwds)
+
+        if version is None and sys.platform.startswith('aix'):
+            # use lslpp to find out xlf version
+            lslpp = find_executable('lslpp')
+            xlf = find_executable('xlf')
+            if os.path.exists(xlf) and os.path.exists(lslpp):
+                s, o = exec_command(lslpp + ' -Lc xlfcmp')
+                m = re.search('xlfcmp:(?P<version>\d+([.]\d+)+)', o)
+                if m: version = m.group('version')
+
+        xlf_dir = '/etc/opt/ibmcmp/xlf'
+        if version is None and os.path.isdir(xlf_dir):
+            # linux:
+            # If the output of xlf does not contain version info
+            # (that's the case with xlf 8.1, for instance) then
+            # let's try another method:
+            l = sorted(os.listdir(xlf_dir))
+            l.reverse()
+            l = [d for d in l if os.path.isfile(os.path.join(xlf_dir, d, 'xlf.cfg'))]
+            if l:
+                from distutils.version import LooseVersion
+                self.version = version = LooseVersion(l[0])
+        return version
+
+    def get_flags(self):
+        return ['-qextname']
+
+    def get_flags_debug(self):
+        return ['-g']
+
+    def get_flags_linker_so(self):
+        opt = []
+        if sys.platform=='darwin':
+            opt.append('-Wl,-bundle,-flat_namespace,-undefined,suppress')
+        else:
+            opt.append('-bshared')
+        version = self.get_version(ok_status=[0, 40])
+        if version is not None:
+            if sys.platform.startswith('aix'):
+                xlf_cfg = '/etc/xlf.cfg'
+            else:
+                xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version
+            fo, new_cfg = make_temp_file(suffix='_xlf.cfg')
+            log.info('Creating '+new_cfg)
+            fi = open(xlf_cfg, 'r')
+            crt1_match = re.compile(r'\s*crt\s*[=]\s*(?P<path>.*)/crt1.o').match
+            for line in fi:
+                m = crt1_match(line)
+                if m:
+                    fo.write('crt = %s/bundle1.o\n' % (m.group('path')))
+                else:
+                    fo.write(line)
+            fi.close()
+            fo.close()
+            opt.append('-F'+new_cfg)
+        return opt
+
+    def get_flags_opt(self):
+        return ['-O3']
+
+if __name__ == '__main__':
+    log.set_verbosity(2)
+    compiler = IBMFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
new file mode 100644
index 0000000000..c4f15a073a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
@@ -0,0 +1,217 @@
+# http://developer.intel.com/software/products/compilers/flin/
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from numpy.distutils.ccompiler import simple_version_match
+from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
+
+compilers = ['IntelFCompiler', 'IntelVisualFCompiler',
+             'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler',
+             'IntelEM64VisualFCompiler', 'IntelEM64TFCompiler']
+
+
+def intel_version_match(type):
+    # Match against the important stuff in the version string
+    return simple_version_match(start=r'Intel.*?Fortran.*?(?:%s).*?Version' % (type,))
+
+
+class BaseIntelFCompiler(FCompiler):
+    def update_executables(self):
+        f = dummy_fortran_file()
+        self.executables['version_cmd'] = ['<F77>', '-FI', '-V', '-c',
+                                           f + '.f', '-o', f + '.o']
+
+    def runtime_library_dir_option(self, dir):
+        return '-Wl,-rpath="%s"' % dir
+
+
+class IntelFCompiler(BaseIntelFCompiler):
+
+    compiler_type = 'intel'
+    compiler_aliases = ('ifort',)
+    description = 'Intel Fortran Compiler for 32-bit apps'
+    version_match = intel_version_match('32-bit|IA-32')
+
+    possible_executables = ['ifort', 'ifc']
+
+    executables = {
+        'version_cmd'  : None,          # set by update_executables
+        'compiler_f77' : [None, "-72", "-w90", "-w95"],
+        'compiler_f90' : [None],
+        'compiler_fix' : [None, "-FI"],
+        'linker_so'    : ["<F90>", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    pic_flags = ['-fPIC']
+    module_dir_switch = '-module '  # Don't remove ending space!
+    module_include_switch = '-I'
+
+    def get_flags_free(self):
+        return ['-FR']
+
+    def get_flags(self):
+        return ['-fPIC']
+
+    def get_flags_opt(self):  # Scipy test failures with -O2
+        return ['-xhost -openmp -fp-model strict -O1']
+
+    def get_flags_arch(self):
+        return []
+
+    def get_flags_linker_so(self):
+        opt = FCompiler.get_flags_linker_so(self)
+        v = self.get_version()
+        if v and v >= '8.0':
+            opt.append('-nofor_main')
+        if sys.platform == 'darwin':
+            # Here, it's -dynamiclib
+            try:
+                idx = opt.index('-shared')
+                opt.remove('-shared')
+            except ValueError:
+                idx = 0
+            opt[idx:idx] = ['-dynamiclib', '-Wl,-undefined,dynamic_lookup']
+        return opt
+
+
+class IntelItaniumFCompiler(IntelFCompiler):
+    compiler_type = 'intele'
+    compiler_aliases = ()
+    description = 'Intel Fortran Compiler for Itanium apps'
+
+    version_match = intel_version_match('Itanium|IA-64')
+
+    possible_executables = ['ifort', 'efort', 'efc']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI", "-w90", "-w95"],
+        'compiler_fix' : [None, "-FI"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+
+class IntelEM64TFCompiler(IntelFCompiler):
+    compiler_type = 'intelem'
+    compiler_aliases = ()
+    description = 'Intel Fortran Compiler for 64-bit apps'
+
+    version_match = intel_version_match('EM64T-based|Intel\\(R\\) 64|64|IA-64|64-bit')
+
+    possible_executables = ['ifort', 'efort', 'efc']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI"],
+        'compiler_fix' : [None, "-FI"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_flags(self):
+        return ['-fPIC']
+
+    def get_flags_opt(self):  # Scipy test failures with -O2
+        return ['-openmp -fp-model strict -O1']
+
+    def get_flags_arch(self):
+        return ['-xSSE4.2']
+
+# Is there no difference in the version string between the above compilers
+# and the Visual compilers?
+
+
+class IntelVisualFCompiler(BaseIntelFCompiler):
+    compiler_type = 'intelv'
+    description = 'Intel Visual Fortran Compiler for 32-bit apps'
+    version_match = intel_version_match('32-bit|IA-32')
+
+    def update_executables(self):
+        f = dummy_fortran_file()
+        self.executables['version_cmd'] = ['<F77>', '/FI', '/c',
+                                           f + '.f', '/o', f + '.o']
+
+    ar_exe = 'lib.exe'
+    possible_executables = ['ifort', 'ifl']
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None],
+        'compiler_fix' : [None],
+        'compiler_f90' : [None],
+        'linker_so'    : [None],
+        'archiver'     : [ar_exe, "/verbose", "/OUT:"],
+        'ranlib'       : None
+        }
+
+    compile_switch = '/c '
+    object_switch = '/Fo'     # No space after /Fo!
+    library_switch = '/OUT:'  # No space after /OUT:!
+    module_dir_switch = '/module:'  # No space after /module:
+    module_include_switch = '/I'
+
+    def get_flags(self):
+        opt = ['/nologo', '/MD', '/nbs', '/names:lowercase', '/assume:underscore']
+        return opt
+
+    def get_flags_free(self):
+        return []
+
+    def get_flags_debug(self):
+        return ['/4Yb', '/d2']
+
+    def get_flags_opt(self):
+        return ['/O1']  # Scipy test failures with /O2
+
+    def get_flags_arch(self):
+        return ["/arch:IA32", "/QaxSSE3"]
+
+    def runtime_library_dir_option(self, dir):
+        raise NotImplementedError
+
+
+class IntelItaniumVisualFCompiler(IntelVisualFCompiler):
+    compiler_type = 'intelev'
+    description = 'Intel Visual Fortran Compiler for Itanium apps'
+
+    version_match = intel_version_match('Itanium')
+
+    possible_executables = ['efl']  # XXX this is a wild guess
+    ar_exe = IntelVisualFCompiler.ar_exe
+
+    executables = {
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI", "-w90", "-w95"],
+        'compiler_fix' : [None, "-FI", "-4L72", "-w"],
+        'compiler_f90' : [None],
+        'linker_so'    : ['<F90>', "-shared"],
+        'archiver'     : [ar_exe, "/verbose", "/OUT:"],
+        'ranlib'       : None
+        }
+
+
+class IntelEM64VisualFCompiler(IntelVisualFCompiler):
+    compiler_type = 'intelvem'
+    description = 'Intel Visual Fortran Compiler for 64-bit apps'
+
+    version_match = simple_version_match(start='Intel\(R\).*?64,')
+
+    def get_flags_arch(self):
+        return ['/QaxSSE4.2']
+
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='intel')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
new file mode 100644
index 0000000000..7a33b4b63c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
@@ -0,0 +1,49 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['LaheyFCompiler']
+
+class LaheyFCompiler(FCompiler):
+
+    compiler_type = 'lahey'
+    description = 'Lahey/Fujitsu Fortran 95 Compiler'
+    version_pattern =  r'Lahey/Fujitsu Fortran 95 Compiler Release (?P<version>[^\s*]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "--version"],
+        'compiler_f77' : ["lf95", "--fix"],
+        'compiler_fix' : ["lf95", "--fix"],
+        'compiler_f90' : ["lf95"],
+        'linker_so'    : ["lf95", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    module_dir_switch = None  #XXX Fix me
+    module_include_switch = None #XXX Fix me
+
+    def get_flags_opt(self):
+        return ['-O']
+    def get_flags_debug(self):
+        return ['-g', '--chk', '--chkglobal']
+    def get_library_dirs(self):
+        opt = []
+        d = os.environ.get('LAHEY')
+        if d:
+            opt.append(os.path.join(d, 'lib'))
+        return opt
+    def get_libraries(self):
+        opt = []
+        opt.extend(['fj9f6', 'fj9i6', 'fj9ipp', 'fj9e6'])
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='lahey')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
new file mode 100644
index 0000000000..6a8d230992
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
@@ -0,0 +1,58 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.cpuinfo import cpu
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['MIPSFCompiler']
+
+class MIPSFCompiler(FCompiler):
+
+    compiler_type = 'mips'
+    description = 'MIPSpro Fortran Compiler'
+    version_pattern =  r'MIPSpro Compilers: Version (?P<version>[^\s*,]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-version"],
+        'compiler_f77' : ["f77", "-f77"],
+        'compiler_fix' : ["f90", "-fixedform"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["f90", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : None
+        }
+    module_dir_switch = None #XXX: fix me
+    module_include_switch = None #XXX: fix me
+    pic_flags = ['-KPIC']
+
+    def get_flags(self):
+        return self.pic_flags + ['-n32']
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_flags_arch(self):
+        opt = []
+        for a in '19 20 21 22_4k 22_5k 24 25 26 27 28 30 32_5k 32_10k'.split():
+            if getattr(cpu, 'is_IP%s'%a)():
+                opt.append('-TARG:platform=IP%s' % a)
+                break
+        return opt
+    def get_flags_arch_f77(self):
+        r = None
+        if cpu.is_r10000(): r = 10000
+        elif cpu.is_r12000(): r = 12000
+        elif cpu.is_r8000(): r = 8000
+        elif cpu.is_r5000(): r = 5000
+        elif cpu.is_r4000(): r = 4000
+        if r is not None:
+            return ['r%s' % (r)]
+        return []
+    def get_flags_arch_f90(self):
+        r = self.get_flags_arch_f77()
+        if r:
+            r[0] = '-' + r[0]
+        return r
+
+if __name__ == '__main__':
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='mips')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
new file mode 100644
index 0000000000..ae1b96faf3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
@@ -0,0 +1,45 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['NAGFCompiler']
+
+class NAGFCompiler(FCompiler):
+
+    compiler_type = 'nag'
+    description = 'NAGWare Fortran 95 Compiler'
+    version_pattern =  r'NAGWare Fortran 95 compiler Release (?P<version>[^\s]*)'
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-V"],
+        'compiler_f77' : ["f95", "-fixed"],
+        'compiler_fix' : ["f95", "-fixed"],
+        'compiler_f90' : ["f95"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+
+    def get_flags_linker_so(self):
+        if sys.platform=='darwin':
+            return ['-unsharedf95', '-Wl,-bundle,-flat_namespace,-undefined,suppress']
+        return ["-Wl,-shared"]
+    def get_flags_opt(self):
+        return ['-O4']
+    def get_flags_arch(self):
+        version = self.get_version()
+        if version and version < '5.1':
+            return ['-target=native']
+        else:
+            return ['']
+    def get_flags_debug(self):
+        return ['-g', '-gline', '-g90', '-nan', '-C']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='nag')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
new file mode 100644
index 0000000000..6f602d734d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
@@ -0,0 +1,31 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['NoneFCompiler']
+
+class NoneFCompiler(FCompiler):
+
+    compiler_type = 'none'
+    description = 'Fake Fortran compiler'
+
+    executables = {'compiler_f77': None,
+                   'compiler_f90': None,
+                   'compiler_fix': None,
+                   'linker_so': None,
+                   'linker_exe': None,
+                   'archiver': None,
+                   'ranlib': None,
+                   'version_cmd': None,
+                   }
+
+    def find_executables(self):
+        pass
+
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    compiler = NoneFCompiler()
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
new file mode 100644
index 0000000000..1902bbc242
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
@@ -0,0 +1,38 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['PathScaleFCompiler']
+
+class PathScaleFCompiler(FCompiler):
+
+    compiler_type = 'pathf95'
+    description = 'PathScale Fortran Compiler'
+    version_pattern =  r'PathScale\(TM\) Compiler Suite: Version (?P<version>[\d.]+)'
+
+    executables = {
+        'version_cmd'  : ["pathf95", "-version"],
+        'compiler_f77' : ["pathf95", "-fixedform"],
+        'compiler_fix' : ["pathf95", "-fixedform"],
+        'compiler_f90' : ["pathf95"],
+        'linker_so'    : ["pathf95", "-shared"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+    }
+    pic_flags = ['-fPIC']
+    module_dir_switch = '-module ' # Don't remove ending space!
+    module_include_switch = '-I'
+
+    def get_flags_opt(self):
+        return ['-O3']
+    def get_flags_debug(self):
+        return ['-g']
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    #compiler = PathScaleFCompiler()
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='pathf95')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
new file mode 100644
index 0000000000..ee357c6d08
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
@@ -0,0 +1,63 @@
+# http://www.pgroup.com
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.fcompiler import FCompiler
+from sys import platform
+
+compilers = ['PGroupFCompiler']
+
+class PGroupFCompiler(FCompiler):
+
+    compiler_type = 'pg'
+    description = 'Portland Group Fortran Compiler'
+    version_pattern =  r'\s*pg(f77|f90|hpf|fortran) (?P<version>[\d.-]+).*'
+
+    if platform == 'darwin':
+        executables = {
+        'version_cmd'  : ["<F77>", "-V"],
+        'compiler_f77' : ["pgfortran", "-dynamiclib"],
+        'compiler_fix' : ["pgfortran", "-Mfixed", "-dynamiclib"],
+        'compiler_f90' : ["pgfortran", "-dynamiclib"],
+        'linker_so'    : ["libtool"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+        pic_flags = ['']
+    else:
+        executables = {
+        'version_cmd'  : ["<F77>", "-V"],
+        'compiler_f77' : ["pgfortran"],
+        'compiler_fix' : ["pgfortran", "-Mfixed"],
+        'compiler_f90' : ["pgfortran"],
+        'linker_so'    : ["pgfortran", "-shared", "-fpic"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+        pic_flags = ['-fpic']
+
+
+    module_dir_switch = '-module '
+    module_include_switch = '-I'
+
+    def get_flags(self):
+        opt = ['-Minform=inform', '-Mnosecond_underscore']
+        return self.pic_flags + opt
+    def get_flags_opt(self):
+        return ['-fast']
+    def get_flags_debug(self):
+        return ['-g']
+
+    if platform == 'darwin':
+        def get_flags_linker_so(self):
+            return ["-dynamic", '-undefined', 'dynamic_lookup']
+
+    def runtime_library_dir_option(self, dir):
+        return '-R"%s"' % dir
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='pg')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
new file mode 100644
index 0000000000..76ce1cabc6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
@@ -0,0 +1,55 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.distutils.ccompiler import simple_version_match
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['SunFCompiler']
+
+class SunFCompiler(FCompiler):
+
+    compiler_type = 'sun'
+    description = 'Sun or Forte Fortran 95 Compiler'
+    # ex:
+    # f90: Sun WorkShop 6 update 2 Fortran 95 6.2 Patch 111690-10 2003/08/28
+    version_match = simple_version_match(
+                      start=r'f9[05]: (Sun|Forte|WorkShop).*Fortran 95')
+
+    executables = {
+        'version_cmd'  : ["<F90>", "-V"],
+        'compiler_f77' : ["f90"],
+        'compiler_fix' : ["f90", "-fixed"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>", "-Bdynamic", "-G"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = '-moddir='
+    module_include_switch = '-M'
+    pic_flags = ['-xcode=pic32']
+
+    def get_flags_f77(self):
+        ret = ["-ftrap=%none"]
+        if (self.get_version() or '') >= '7':
+            ret.append("-f77")
+        else:
+            ret.append("-fixed")
+        return ret
+    def get_opt(self):
+        return ['-fast', '-dalign']
+    def get_arch(self):
+        return ['-xtarget=generic']
+    def get_libraries(self):
+        opt = []
+        opt.extend(['fsu', 'sunmath', 'mvec'])
+        return opt
+
+    def runtime_library_dir_option(self, dir):
+        return '-R"%s"' % dir
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='sun')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
new file mode 100644
index 0000000000..05bbc10bad
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
@@ -0,0 +1,56 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.fcompiler.gnu import GnuFCompiler
+
+compilers = ['VastFCompiler']
+
+class VastFCompiler(GnuFCompiler):
+    compiler_type = 'vast'
+    compiler_aliases = ()
+    description = 'Pacific-Sierra Research Fortran 90 Compiler'
+    version_pattern = r'\s*Pacific-Sierra Research vf90 '\
+                      '(Personal|Professional)\s+(?P<version>[^\s]*)'
+
+    # VAST f90 does not support -o with -c. So, object files are created
+    # to the current directory and then moved to build directory
+    object_switch = ' && function _mvfile { mv -v `basename $1` $1 ; } && _mvfile '
+
+    executables = {
+        'version_cmd'  : ["vf90", "-v"],
+        'compiler_f77' : ["g77"],
+        'compiler_fix' : ["f90", "-Wv,-ya"],
+        'compiler_f90' : ["f90"],
+        'linker_so'    : ["<F90>"],
+        'archiver'     : ["ar", "-cr"],
+        'ranlib'       : ["ranlib"]
+        }
+    module_dir_switch = None  #XXX Fix me
+    module_include_switch = None #XXX Fix me
+
+    def find_executables(self):
+        pass
+
+    def get_version_cmd(self):
+        f90 = self.compiler_f90[0]
+        d, b = os.path.split(f90)
+        vf90 = os.path.join(d, 'v'+b)
+        return vf90
+
+    def get_flags_arch(self):
+        vast_version = self.get_version()
+        gnu = GnuFCompiler()
+        gnu.customize(None)
+        self.version = gnu.get_version()
+        opt = GnuFCompiler.get_flags_arch(self)
+        self.version = vast_version
+        return opt
+
+if __name__ == '__main__':
+    from distutils import log
+    log.set_verbosity(2)
+    from numpy.distutils.fcompiler import new_fcompiler
+    compiler = new_fcompiler(compiler='vast')
+    compiler.customize()
+    print(compiler.get_version())
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.py
new file mode 100644
index 0000000000..b7013ddf46
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.py
@@ -0,0 +1,256 @@
+#!/usr/bin/python2
+"""
+
+process_file(filename)
+
+  takes templated file .xxx.src and produces .xxx file where .xxx
+  is .pyf .f90 or .f using the following template rules:
+
+  '<..>' denotes a template.
+
+  All function and subroutine blocks in a source file with names that
+  contain '<..>' will be replicated according to the rules in '<..>'.
+
+  The number of comma-separeted words in '<..>' will determine the number of
+  replicates.
+
+  '<..>' may have two different forms, named and short. For example,
+
+  named:
+   <p=d,s,z,c> where anywhere inside a block '<p>' will be replaced with
+   'd', 's', 'z', and 'c' for each replicate of the block.
+
+   <_c>  is already defined: <_c=s,d,c,z>
+   <_t>  is already defined: <_t=real,double precision,complex,double complex>
+
+  short:
+   <s,d,c,z>, a short form of the named, useful when no <p> appears inside
+   a block.
+
+  In general, '<..>' contains a comma separated list of arbitrary
+  expressions. If these expression must contain a comma|leftarrow|rightarrow,
+  then prepend the comma|leftarrow|rightarrow with a backslash.
+
+  If an expression matches '\\<index>' then it will be replaced
+  by <index>-th expression.
+
+  Note that all '<..>' forms in a block must have the same number of
+  comma-separated entries.
+
+ Predefined named template rules:
+  <prefix=s,d,c,z>
+  <ftype=real,double precision,complex,double complex>
+  <ftypereal=real,double precision,\\0,\\1>
+  <ctype=float,double,complex_float,complex_double>
+  <ctypereal=float,double,\\0,\\1>
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['process_str', 'process_file']
+
+import os
+import sys
+import re
+
+routine_start_re = re.compile(r'(\n|\A)((     (\$|\*))|)\s*(subroutine|function)\b', re.I)
+routine_end_re = re.compile(r'\n\s*end\s*(subroutine|function)\b.*(\n|\Z)', re.I)
+function_start_re = re.compile(r'\n     (\$|\*)\s*function\b', re.I)
+
+def parse_structure(astr):
+    """ Return a list of tuples for each function or subroutine each
+    tuple is the start and end of a subroutine or function to be
+    expanded.
+    """
+
+    spanlist = []
+    ind = 0
+    while True:
+        m = routine_start_re.search(astr, ind)
+        if m is None:
+            break
+        start = m.start()
+        if function_start_re.match(astr, start, m.end()):
+            while True:
+                i = astr.rfind('\n', ind, start)
+                if i==-1:
+                    break
+                start = i
+                if astr[i:i+7]!='\n     $':
+                    break
+        start += 1
+        m = routine_end_re.search(astr, m.end())
+        ind = end = m and m.end()-1 or len(astr)
+        spanlist.append((start, end))
+    return spanlist
+
+template_re = re.compile(r"<\s*(\w[\w\d]*)\s*>")
+named_re = re.compile(r"<\s*(\w[\w\d]*)\s*=\s*(.*?)\s*>")
+list_re = re.compile(r"<\s*((.*?))\s*>")
+
+def find_repl_patterns(astr):
+    reps = named_re.findall(astr)
+    names = {}
+    for rep in reps:
+        name = rep[0].strip() or unique_key(names)
+        repl = rep[1].replace('\,', '@comma@')
+        thelist = conv(repl)
+        names[name] = thelist
+    return names
+
+item_re = re.compile(r"\A\\(?P<index>\d+)\Z")
+def conv(astr):
+    b = astr.split(',')
+    l = [x.strip() for x in b]
+    for i in range(len(l)):
+        m = item_re.match(l[i])
+        if m:
+            j = int(m.group('index'))
+            l[i] = l[j]
+    return ','.join(l)
+
+def unique_key(adict):
+    """ Obtain a unique key given a dictionary."""
+    allkeys = list(adict.keys())
+    done = False
+    n = 1
+    while not done:
+        newkey = '__l%s' % (n)
+        if newkey in allkeys:
+            n += 1
+        else:
+            done = True
+    return newkey
+
+
+template_name_re = re.compile(r'\A\s*(\w[\w\d]*)\s*\Z')
+def expand_sub(substr, names):
+    substr = substr.replace('\>', '@rightarrow@')
+    substr = substr.replace('\<', '@leftarrow@')
+    lnames = find_repl_patterns(substr)
+    substr = named_re.sub(r"<\1>", substr)  # get rid of definition templates
+
+    def listrepl(mobj):
+        thelist = conv(mobj.group(1).replace('\,', '@comma@'))
+        if template_name_re.match(thelist):
+            return "<%s>" % (thelist)
+        name = None
+        for key in lnames.keys():    # see if list is already in dictionary
+            if lnames[key] == thelist:
+                name = key
+        if name is None:      # this list is not in the dictionary yet
+            name = unique_key(lnames)
+            lnames[name] = thelist
+        return "<%s>" % name
+
+    substr = list_re.sub(listrepl, substr) # convert all lists to named templates
+                                           # newnames are constructed as needed
+
+    numsubs = None
+    base_rule = None
+    rules = {}
+    for r in template_re.findall(substr):
+        if r not in rules:
+            thelist = lnames.get(r, names.get(r, None))
+            if thelist is None:
+                raise ValueError('No replicates found for <%s>' % (r))
+            if r not in names and not thelist.startswith('_'):
+                names[r] = thelist
+            rule = [i.replace('@comma@', ',') for i in thelist.split(',')]
+            num = len(rule)
+
+            if numsubs is None:
+                numsubs = num
+                rules[r] = rule
+                base_rule = r
+            elif num == numsubs:
+                rules[r] = rule
+            else:
+                print("Mismatch in number of replacements (base <%s=%s>)"
+                      " for <%s=%s>. Ignoring." %
+                      (base_rule, ','.join(rules[base_rule]), r, thelist))
+    if not rules:
+        return substr
+
+    def namerepl(mobj):
+        name = mobj.group(1)
+        return rules.get(name, (k+1)*[name])[k]
+
+    newstr = ''
+    for k in range(numsubs):
+        newstr += template_re.sub(namerepl, substr) + '\n\n'
+
+    newstr = newstr.replace('@rightarrow@', '>')
+    newstr = newstr.replace('@leftarrow@', '<')
+    return newstr
+
+def process_str(allstr):
+    newstr = allstr
+    writestr = '' #_head # using _head will break free-format files
+
+    struct = parse_structure(newstr)
+
+    oldend = 0
+    names = {}
+    names.update(_special_names)
+    for sub in struct:
+        writestr += newstr[oldend:sub[0]]
+        names.update(find_repl_patterns(newstr[oldend:sub[0]]))
+        writestr += expand_sub(newstr[sub[0]:sub[1]], names)
+        oldend =  sub[1]
+    writestr += newstr[oldend:]
+
+    return writestr
+
+include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
+
+def resolve_includes(source):
+    d = os.path.dirname(source)
+    fid = open(source)
+    lines = []
+    for line in fid:
+        m = include_src_re.match(line)
+        if m:
+            fn = m.group('name')
+            if not os.path.isabs(fn):
+                fn = os.path.join(d, fn)
+            if os.path.isfile(fn):
+                print('Including file', fn)
+                lines.extend(resolve_includes(fn))
+            else:
+                lines.append(line)
+        else:
+            lines.append(line)
+    fid.close()
+    return lines
+
+def process_file(source):
+    lines = resolve_includes(source)
+    return process_str(''.join(lines))
+
+_special_names = find_repl_patterns('''
+<_c=s,d,c,z>
+<_t=real,double precision,complex,double complex>
+<prefix=s,d,c,z>
+<ftype=real,double precision,complex,double complex>
+<ctype=float,double,complex_float,complex_double>
+<ftypereal=real,double precision,\\0,\\1>
+<ctypereal=float,double,\\0,\\1>
+''')
+
+if __name__ == "__main__":
+
+    try:
+        file = sys.argv[1]
+    except IndexError:
+        fid = sys.stdin
+        outfile = sys.stdout
+    else:
+        fid = open(file, 'r')
+        (base, ext) = os.path.splitext(file)
+        newname = base
+        outfile = open(newname, 'w')
+
+    allstr = fid.read()
+    writestr = process_str(allstr)
+    outfile.write(writestr)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/info.py
new file mode 100644
index 0000000000..2f5310665c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/info.py
@@ -0,0 +1,6 @@
+"""
+Enhanced distutils with Fortran compilers support and more.
+"""
+from __future__ import division, absolute_import, print_function
+
+postpone_import = True
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
new file mode 100644
index 0000000000..20c6d2ba41
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
@@ -0,0 +1,105 @@
+from __future__ import division, absolute_import, print_function
+
+import platform
+
+from distutils.unixccompiler import UnixCCompiler
+from numpy.distutils.exec_command import find_executable
+from numpy.distutils.ccompiler import simple_version_match
+if platform.system() == 'Windows':
+    from numpy.distutils.msvc9compiler import MSVCCompiler
+
+
+class IntelCCompiler(UnixCCompiler):
+    """A modified Intel compiler compatible with a GCC-built Python."""
+    compiler_type = 'intel'
+    cc_exe = 'icc'
+    cc_args = 'fPIC'
+
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__(self, verbose, dry_run, force)
+        self.cc_exe = ('icc -fPIC -fp-model strict -O3 '
+                       '-fomit-frame-pointer -openmp')
+        compiler = self.cc_exe
+        if platform.system() == 'Darwin':
+            shared_flag = '-Wl,-undefined,dynamic_lookup'
+        else:
+            shared_flag = '-shared'
+        self.set_executables(compiler=compiler,
+                             compiler_so=compiler,
+                             compiler_cxx=compiler,
+                             archiver='xiar' + ' cru',
+                             linker_exe=compiler + ' -shared-intel',
+                             linker_so=compiler + ' ' + shared_flag +
+                             ' -shared-intel')
+
+
+class IntelItaniumCCompiler(IntelCCompiler):
+    compiler_type = 'intele'
+
+    # On Itanium, the Intel Compiler used to be called ecc, let's search for
+    # it (now it's also icc, so ecc is last in the search).
+    for cc_exe in map(find_executable, ['icc', 'ecc']):
+        if cc_exe:
+            break
+
+
+class IntelEM64TCCompiler(UnixCCompiler):
+    """
+    A modified Intel x86_64 compiler compatible with a 64bit GCC-built Python.
+    """
+    compiler_type = 'intelem'
+    cc_exe = 'icc -m64'
+    cc_args = '-fPIC'
+
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__(self, verbose, dry_run, force)
+        self.cc_exe = ('icc -m64 -fPIC -fp-model strict -O3 '
+                       '-fomit-frame-pointer -openmp -xSSE4.2')
+        compiler = self.cc_exe
+        if platform.system() == 'Darwin':
+            shared_flag = '-Wl,-undefined,dynamic_lookup'
+        else:
+            shared_flag = '-shared'
+        self.set_executables(compiler=compiler,
+                             compiler_so=compiler,
+                             compiler_cxx=compiler,
+                             archiver='xiar' + ' cru',
+                             linker_exe=compiler + ' -shared-intel',
+                             linker_so=compiler + ' ' + shared_flag +
+                             ' -shared-intel')
+
+
+if platform.system() == 'Windows':
+    class IntelCCompilerW(MSVCCompiler):
+        """
+        A modified Intel compiler compatible with an MSVC-built Python.
+        """
+        compiler_type = 'intelw'
+        compiler_cxx = 'icl'
+
+        def __init__(self, verbose=0, dry_run=0, force=0):
+            MSVCCompiler.__init__(self, verbose, dry_run, force)
+            version_match = simple_version_match(start='Intel\(R\).*?32,')
+            self.__version = version_match
+
+        def initialize(self, plat_name=None):
+            MSVCCompiler.initialize(self, plat_name)
+            self.cc = self.find_exe('icl.exe')
+            self.lib = self.find_exe('xilib')
+            self.linker = self.find_exe('xilink')
+            self.compile_options = ['/nologo', '/O3', '/MD', '/W3',
+                                    '/Qstd=c99', '/QaxSSE4.2']
+            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3',
+                                          '/Qstd=c99', '/Z7', '/D_DEBUG']
+
+    class IntelEM64TCCompilerW(IntelCCompilerW):
+        """
+        A modified Intel x86_64 compiler compatible with
+        a 64bit MSVC-built Python.
+        """
+        compiler_type = 'intelemw'
+
+        def __init__(self, verbose=0, dry_run=0, force=0):
+            MSVCCompiler.__init__(self, verbose, dry_run, force)
+            version_match = simple_version_match(start='Intel\(R\).*?64,')
+            self.__version = version_match
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.py
new file mode 100644
index 0000000000..0a53645664
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.py
@@ -0,0 +1,116 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+import sys
+import os
+import subprocess
+
+__doc__ = """This module generates a DEF file from the symbols in
+an MSVC-compiled DLL import library.  It correctly discriminates between
+data and functions.  The data is collected from the output of the program
+nm(1).
+
+Usage:
+    python lib2def.py [libname.lib] [output.def]
+or
+    python lib2def.py [libname.lib] > output.def
+
+libname.lib defaults to python<py_ver>.lib and output.def defaults to stdout
+
+Author: Robert Kern <kernr@mail.ncifcrf.gov>
+Last Update: April 30, 1999
+"""
+
+__version__ = '0.1a'
+
+py_ver = "%d%d" % tuple(sys.version_info[:2])
+
+DEFAULT_NM = 'nm -Cs'
+
+DEF_HEADER = """LIBRARY         python%s.dll
+;CODE           PRELOAD MOVEABLE DISCARDABLE
+;DATA           PRELOAD SINGLE
+
+EXPORTS
+""" % py_ver
+# the header of the DEF file
+
+FUNC_RE = re.compile(r"^(.*) in python%s\.dll" % py_ver, re.MULTILINE)
+DATA_RE = re.compile(r"^_imp__(.*) in python%s\.dll" % py_ver, re.MULTILINE)
+
+def parse_cmd():
+    """Parses the command-line arguments.
+
+libfile, deffile = parse_cmd()"""
+    if len(sys.argv) == 3:
+        if sys.argv[1][-4:] == '.lib' and sys.argv[2][-4:] == '.def':
+            libfile, deffile = sys.argv[1:]
+        elif sys.argv[1][-4:] == '.def' and sys.argv[2][-4:] == '.lib':
+            deffile, libfile = sys.argv[1:]
+        else:
+            print("I'm assuming that your first argument is the library")
+            print("and the second is the DEF file.")
+    elif len(sys.argv) == 2:
+        if sys.argv[1][-4:] == '.def':
+            deffile = sys.argv[1]
+            libfile = 'python%s.lib' % py_ver
+        elif sys.argv[1][-4:] == '.lib':
+            deffile = None
+            libfile = sys.argv[1]
+    else:
+        libfile = 'python%s.lib' % py_ver
+        deffile = None
+    return libfile, deffile
+
+def getnm(nm_cmd = ['nm', '-Cs', 'python%s.lib' % py_ver]):
+    """Returns the output of nm_cmd via a pipe.
+
+nm_output = getnam(nm_cmd = 'nm -Cs py_lib')"""
+    f = subprocess.Popen(nm_cmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
+    nm_output = f.stdout.read()
+    f.stdout.close()
+    return nm_output
+
+def parse_nm(nm_output):
+    """Returns a tuple of lists: dlist for the list of data
+symbols and flist for the list of function symbols.
+
+dlist, flist = parse_nm(nm_output)"""
+    data = DATA_RE.findall(nm_output)
+    func = FUNC_RE.findall(nm_output)
+
+    flist = []
+    for sym in data:
+        if sym in func and (sym[:2] == 'Py' or sym[:3] == '_Py' or sym[:4] == 'init'):
+            flist.append(sym)
+
+    dlist = []
+    for sym in data:
+        if sym not in flist and (sym[:2] == 'Py' or sym[:3] == '_Py'):
+            dlist.append(sym)
+
+    dlist.sort()
+    flist.sort()
+    return dlist, flist
+
+def output_def(dlist, flist, header, file = sys.stdout):
+    """Outputs the final DEF file to a file defaulting to stdout.
+
+output_def(dlist, flist, header, file = sys.stdout)"""
+    for data_sym in dlist:
+        header = header + '\t%s DATA\n' % data_sym
+    header = header + '\n' # blank line
+    for func_sym in flist:
+        header = header + '\t%s\n' % func_sym
+    file.write(header)
+
+if __name__ == '__main__':
+    libfile, deffile = parse_cmd()
+    if deffile is None:
+        deffile = sys.stdout
+    else:
+        deffile = open(deffile, 'w')
+    nm_cmd = [str(DEFAULT_NM), str(libfile)]
+    nm_output = getnm(nm_cmd)
+    dlist, flist = parse_nm(nm_output)
+    output_def(dlist, flist, DEF_HEADER, deffile)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.py
new file mode 100644
index 0000000000..5ecb104ffd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.py
@@ -0,0 +1,76 @@
+""" Functions for converting from DOS to UNIX line endings
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys, re, os
+
+def dos2unix(file):
+    "Replace CRLF with LF in argument files.  Print names of changed files."
+    if os.path.isdir(file):
+        print(file, "Directory!")
+        return
+
+    data = open(file, "rb").read()
+    if '\0' in data:
+        print(file, "Binary!")
+        return
+
+    newdata = re.sub("\r\n", "\n", data)
+    if newdata != data:
+        print('dos2unix:', file)
+        f = open(file, "wb")
+        f.write(newdata)
+        f.close()
+        return file
+    else:
+        print(file, 'ok')
+
+def dos2unix_one_dir(modified_files, dir_name, file_names):
+    for file in file_names:
+        full_path = os.path.join(dir_name, file)
+        file = dos2unix(full_path)
+        if file is not None:
+            modified_files.append(file)
+
+def dos2unix_dir(dir_name):
+    modified_files = []
+    os.path.walk(dir_name, dos2unix_one_dir, modified_files)
+    return modified_files
+#----------------------------------
+
+def unix2dos(file):
+    "Replace LF with CRLF in argument files.  Print names of changed files."
+    if os.path.isdir(file):
+        print(file, "Directory!")
+        return
+
+    data = open(file, "rb").read()
+    if '\0' in data:
+        print(file, "Binary!")
+        return
+    newdata = re.sub("\r\n", "\n", data)
+    newdata = re.sub("\n", "\r\n", newdata)
+    if newdata != data:
+        print('unix2dos:', file)
+        f = open(file, "wb")
+        f.write(newdata)
+        f.close()
+        return file
+    else:
+        print(file, 'ok')
+
+def unix2dos_one_dir(modified_files, dir_name, file_names):
+    for file in file_names:
+        full_path = os.path.join(dir_name, file)
+        unix2dos(full_path)
+        if file is not None:
+            modified_files.append(file)
+
+def unix2dos_dir(dir_name):
+    modified_files = []
+    os.path.walk(dir_name, unix2dos_one_dir, modified_files)
+    return modified_files
+
+if __name__ == "__main__":
+    dos2unix_dir(sys.argv[1])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/log.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/log.py
new file mode 100644
index 0000000000..37f9fe5dd0
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/log.py
@@ -0,0 +1,93 @@
+# Colored log, requires Python 2.3 or up.
+from __future__ import division, absolute_import, print_function
+
+import sys
+from distutils.log import *
+from distutils.log import Log as old_Log
+from distutils.log import _global_log
+
+if sys.version_info[0] < 3:
+    from .misc_util import (red_text, default_text, cyan_text, green_text,
+            is_sequence, is_string)
+else:
+    from numpy.distutils.misc_util import (red_text, default_text, cyan_text,
+            green_text, is_sequence, is_string)
+
+
+def _fix_args(args,flag=1):
+    if is_string(args):
+        return args.replace('%', '%%')
+    if flag and is_sequence(args):
+        return tuple([_fix_args(a, flag=0) for a in args])
+    return args
+
+
+class Log(old_Log):
+    def _log(self, level, msg, args):
+        if level >= self.threshold:
+            if args:
+                msg = msg % _fix_args(args)
+            if 0:
+                if msg.startswith('copying ') and msg.find(' -> ') != -1:
+                    return
+                if msg.startswith('byte-compiling '):
+                    return
+            print(_global_color_map[level](msg))
+            sys.stdout.flush()
+
+    def good(self, msg, *args):
+        """
+        If we log WARN messages, log this message as a 'nice' anti-warn
+        message.
+
+        """
+        if WARN >= self.threshold:
+            if args:
+                print(green_text(msg % _fix_args(args)))
+            else:
+                print(green_text(msg))
+            sys.stdout.flush()
+
+
+_global_log.__class__ = Log
+
+good = _global_log.good
+
+def set_threshold(level, force=False):
+    prev_level = _global_log.threshold
+    if prev_level > DEBUG or force:
+        # If we're running at DEBUG, don't change the threshold, as there's
+        # likely a good reason why we're running at this level.
+        _global_log.threshold = level
+        if level <= DEBUG:
+            info('set_threshold: setting threshold to DEBUG level,'
+                    ' it can be changed only with force argument')
+    else:
+        info('set_threshold: not changing threshold from DEBUG level'
+                ' %s to %s' % (prev_level, level))
+    return prev_level
+
+
+def set_verbosity(v, force=False):
+    prev_level = _global_log.threshold
+    if v < 0:
+        set_threshold(ERROR, force)
+    elif v == 0:
+        set_threshold(WARN, force)
+    elif v == 1:
+        set_threshold(INFO, force)
+    elif v >= 2:
+        set_threshold(DEBUG, force)
+    return {FATAL:-2,ERROR:-1,WARN:0,INFO:1,DEBUG:2}.get(prev_level, 1)
+
+
+_global_color_map = {
+    DEBUG:cyan_text,
+    INFO:default_text,
+    WARN:red_text,
+    ERROR:red_text,
+    FATAL:red_text
+}
+
+# don't use INFO,.. flags in set_verbosity, these flags are for set_threshold.
+set_verbosity(0, force=True)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
new file mode 100644
index 0000000000..15ed7e6863
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
@@ -0,0 +1,6 @@
+int _get_output_format(void)
+{
+	return 0;
+}
+
+int _imp____lc_codepage = 0;
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
new file mode 100644
index 0000000000..c05cbf492e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
@@ -0,0 +1,584 @@
+"""
+Support code for building Python extensions on Windows.
+
+    # NT stuff
+    # 1. Make sure libpython<version>.a exists for gcc.  If not, build it.
+    # 2. Force windows to use gcc (we're struggling with MSVC and g77 support)
+    # 3. Force windows to use g77
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import subprocess
+import re
+
+# Overwrite certain distutils.ccompiler functions:
+import numpy.distutils.ccompiler
+
+if sys.version_info[0] < 3:
+    from . import log
+else:
+    from numpy.distutils import log
+# NT stuff
+# 1. Make sure libpython<version>.a exists for gcc.  If not, build it.
+# 2. Force windows to use gcc (we're struggling with MSVC and g77 support)
+#    --> this is done in numpy/distutils/ccompiler.py
+# 3. Force windows to use g77
+
+import distutils.cygwinccompiler
+from distutils.version import StrictVersion
+from numpy.distutils.ccompiler import gen_preprocess_options, gen_lib_options
+from distutils.unixccompiler import UnixCCompiler
+from distutils.msvccompiler import get_build_version as get_build_msvc_version
+from distutils.errors import (DistutilsExecError, CompileError,
+                              UnknownFileError)
+from numpy.distutils.misc_util import (msvc_runtime_library,
+                                       get_build_architecture)
+
+# Useful to generate table of symbols from a dll
+_START = re.compile(r'\[Ordinal/Name Pointer\] Table')
+_TABLE = re.compile(r'^\s+\[([\s*[0-9]*)\] ([a-zA-Z0-9_]*)')
+
+# the same as cygwin plus some additional parameters
+class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
+    """ A modified MingW32 compiler compatible with an MSVC built Python.
+
+    """
+
+    compiler_type = 'mingw32'
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0,
+                  force=0):
+
+        distutils.cygwinccompiler.CygwinCCompiler.__init__ (self, verbose,
+                                                            dry_run, force)
+
+        # we need to support 3.2 which doesn't match the standard
+        # get_versions methods regex
+        if self.gcc_version is None:
+            import re
+            p = subprocess.Popen(['gcc', '-dumpversion'], shell=True,
+                                 stdout=subprocess.PIPE)
+            out_string = p.stdout.read()
+            p.stdout.close()
+            result = re.search('(\d+\.\d+)', out_string)
+            if result:
+                self.gcc_version = StrictVersion(result.group(1))
+
+        # A real mingw32 doesn't need to specify a different entry point,
+        # but cygwin 2.91.57 in no-cygwin-mode needs it.
+        if self.gcc_version <= "2.91.57":
+            entry_point = '--entry _DllMain@12'
+        else:
+            entry_point = ''
+
+        if self.linker_dll == 'dllwrap':
+            # Commented out '--driver-name g++' part that fixes weird
+            #   g++.exe: g++: No such file or directory
+            # error (mingw 1.0 in Enthon24 tree, gcc-3.4.5).
+            # If the --driver-name part is required for some environment
+            # then make the inclusion of this part specific to that
+            # environment.
+            self.linker = 'dllwrap' #  --driver-name g++'
+        elif self.linker_dll == 'gcc':
+            self.linker = 'g++'
+
+        if not 'GCC' in sys.version:
+
+            # **changes: eric jones 4/11/01
+            # 1. Check for import library on Windows.  Build if it doesn't exist.
+
+            build_import_library()
+
+            # Check for custom msvc runtime library on Windows. Build if it doesn't exist.
+            msvcr_success = build_msvcr_library()
+            msvcr_dbg_success = build_msvcr_library(debug=True)
+            if msvcr_success or msvcr_dbg_success:
+                # add preprocessor statement for using customized msvcr lib
+                self.define_macro('NPY_MINGW_USE_CUSTOM_MSVCR')
+
+            # Define the MSVC version as hint for MinGW
+            msvcr_version = '0x%03i0' % int(msvc_runtime_library().lstrip('msvcr'))
+            self.define_macro('__MSVCRT_VERSION__', msvcr_version)
+
+        # MS_WIN64 should be defined when building for amd64 on windows,
+        # but python headers define it only for MS compilers, which has all
+        # kind of bad consequences, like using Py_ModuleInit4 instead of
+        # Py_ModuleInit4_64, etc... So we add it here
+        if get_build_architecture() == 'AMD64':
+            if self.gcc_version < "4.0":
+                self.set_executables(
+                    compiler='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall',
+                    compiler_so='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0'
+                                ' -Wall -Wstrict-prototypes',
+                    linker_exe='gcc -g -mno-cygwin',
+                    linker_so='gcc -g -mno-cygwin -shared')
+            else:
+                # gcc-4 series releases do not support -mno-cygwin option
+                self.set_executables(
+                    compiler='gcc -march=x86-64 -mtune=generic -DMS_WIN64'
+                             ' -O2 -msse2 -Wall',
+                    compiler_so='gcc -march=x86-64 -mtune=generic -DMS_WIN64'
+                                ' -O2 -msse2 -Wall -Wstrict-prototypes',
+                    linker_exe='gcc',
+                    linker_so='gcc -shared -Wl,-gc-sections -Wl,-s')
+        else:
+            if self.gcc_version <= "3.0.0":
+                self.set_executables(
+                    compiler='gcc -mno-cygwin -O2 -w',
+                    compiler_so='gcc -mno-cygwin -mdll -O2 -w'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ -mno-cygwin',
+                    linker_so='%s -mno-cygwin -mdll -static %s' %
+                              (self.linker, entry_point))
+            elif self.gcc_version < "4.0":
+                self.set_executables(
+                    compiler='gcc -mno-cygwin -O2 -Wall',
+                    compiler_so='gcc -mno-cygwin -O2 -Wall'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ -mno-cygwin',
+                    linker_so='g++ -mno-cygwin -shared')
+            else:
+                # gcc-4 series releases do not support -mno-cygwin option
+                self.set_executables(
+                    compiler='gcc -O2 -march=core2 -mtune=generic'
+                             ' -mfpmath=sse -msse2'
+                             ' -mincoming-stack-boundary=2 -Wall',
+                    compiler_so='gcc -O2 -march=core2 -mtune=generic'
+                                ' -mfpmath=sse -msse2'
+                                ' -mincoming-stack-boundary=2 -Wall'
+                                ' -Wstrict-prototypes',
+                    linker_exe='g++ ',
+                    linker_so='g++ -shared -Wl,-gc-sections -Wl,-s')
+        # added for python2.3 support
+        # we can't pass it through set_executables because pre 2.2 would fail
+        self.compiler_cxx = ['g++']
+
+        # Maybe we should also append -mthreads, but then the finished dlls
+        # need another dll (mingwm10.dll see Mingw32 docs) (-mthreads: Support
+        # thread-safe exception handling on `Mingw32')
+
+        # no additional libraries needed
+        #self.dll_libraries=[]
+        return
+
+    # __init__ ()
+
+    def link(self,
+             target_desc,
+             objects,
+             output_filename,
+             output_dir,
+             libraries,
+             library_dirs,
+             runtime_library_dirs,
+             export_symbols = None,
+             debug=0,
+             extra_preargs=None,
+             extra_postargs=None,
+             build_temp=None,
+             target_lang=None):
+        # Include the appropiate MSVC runtime library if Python was built
+        # with MSVC >= 7.0 (MinGW standard is msvcrt)
+        runtime_library = msvc_runtime_library()
+        if runtime_library:
+            if not libraries:
+                libraries = []
+            libraries.append(runtime_library)
+        args = (self,
+                target_desc,
+                objects,
+                output_filename,
+                output_dir,
+                libraries,
+                library_dirs,
+                runtime_library_dirs,
+                None, #export_symbols, we do this in our def-file
+                debug,
+                extra_preargs,
+                extra_postargs,
+                build_temp,
+                target_lang)
+        if self.gcc_version < "3.0.0":
+            func = distutils.cygwinccompiler.CygwinCCompiler.link
+        else:
+            func = UnixCCompiler.link
+        func(*args[:func.__code__.co_argcount])
+        return
+
+    def object_filenames (self,
+                          source_filenames,
+                          strip_dir=0,
+                          output_dir=''):
+        if output_dir is None: output_dir = ''
+        obj_names = []
+        for src_name in source_filenames:
+            # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+            (base, ext) = os.path.splitext (os.path.normcase(src_name))
+
+            # added these lines to strip off windows drive letters
+            # without it, .o files are placed next to .c files
+            # instead of the build directory
+            drv, base = os.path.splitdrive(base)
+            if drv:
+                base = base[1:]
+
+            if ext not in (self.src_extensions + ['.rc', '.res']):
+                raise UnknownFileError(
+                      "unknown file type '%s' (from '%s')" % \
+                      (ext, src_name))
+            if strip_dir:
+                base = os.path.basename (base)
+            if ext == '.res' or ext == '.rc':
+                # these need to be compiled to object files
+                obj_names.append (os.path.join (output_dir,
+                                                base + ext + self.obj_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                                base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
+
+
+def find_python_dll():
+    maj, min, micro = [int(i) for i in sys.version_info[:3]]
+    dllname = 'python%d%d.dll' % (maj, min)
+    print("Looking for %s" % dllname)
+
+    # We can't do much here:
+    # - find it in python main dir
+    # - in system32,
+    # - ortherwise (Sxs), I don't know how to get it.
+    lib_dirs = [sys.prefix, os.path.join(sys.prefix, 'lib')]
+    try:
+        lib_dirs.append(os.path.join(os.environ['SYSTEMROOT'], 'system32'))
+    except KeyError:
+        pass
+
+    for d in lib_dirs:
+        dll = os.path.join(d, dllname)
+        if os.path.exists(dll):
+            return dll
+
+    raise ValueError("%s not found in %s" % (dllname, lib_dirs))
+
+def dump_table(dll):
+    st = subprocess.Popen(["objdump.exe", "-p", dll], stdout=subprocess.PIPE)
+    return st.stdout.readlines()
+
+def generate_def(dll, dfile):
+    """Given a dll file location,  get all its exported symbols and dump them
+    into the given def file.
+
+    The .def file will be overwritten"""
+    dump = dump_table(dll)
+    for i in range(len(dump)):
+        if _START.match(dump[i].decode()):
+            break
+    else:
+        raise ValueError("Symbol table not found")
+
+    syms = []
+    for j in range(i+1, len(dump)):
+        m = _TABLE.match(dump[j].decode())
+        if m:
+            syms.append((int(m.group(1).strip()), m.group(2)))
+        else:
+            break
+
+    if len(syms) == 0:
+        log.warn('No symbols found in %s' % dll)
+
+    d = open(dfile, 'w')
+    d.write('LIBRARY        %s\n' % os.path.basename(dll))
+    d.write(';CODE          PRELOAD MOVEABLE DISCARDABLE\n')
+    d.write(';DATA          PRELOAD SINGLE\n')
+    d.write('\nEXPORTS\n')
+    for s in syms:
+        #d.write('@%d    %s\n' % (s[0], s[1]))
+        d.write('%s\n' % s[1])
+    d.close()
+
+def find_dll(dll_name):
+
+    arch = {'AMD64' : 'amd64',
+            'Intel' : 'x86'}[get_build_architecture()]
+
+    def _find_dll_in_winsxs(dll_name):
+        # Walk through the WinSxS directory to find the dll.
+        winsxs_path = os.path.join(os.environ['WINDIR'], 'winsxs')
+        if not os.path.exists(winsxs_path):
+            return None
+        for root, dirs, files in os.walk(winsxs_path):
+            if dll_name in files and arch in root:
+                return os.path.join(root, dll_name)
+        return None
+
+    def _find_dll_in_path(dll_name):
+        # First, look in the Python directory, then scan PATH for
+        # the given dll name.
+        for path in [sys.prefix] + os.environ['PATH'].split(';'):
+            filepath = os.path.join(path, dll_name)
+            if os.path.exists(filepath):
+                return os.path.abspath(filepath)
+
+    return _find_dll_in_winsxs(dll_name) or _find_dll_in_path(dll_name)
+
+def build_msvcr_library(debug=False):
+    if os.name != 'nt':
+        return False
+
+    msvcr_name = msvc_runtime_library()
+
+    # Skip using a custom library for versions < MSVC 8.0
+    if int(msvcr_name.lstrip('msvcr')) < 80:
+        log.debug('Skip building msvcr library:'
+                  ' custom functionality not present')
+        return False
+
+    if debug:
+        msvcr_name += 'd'
+
+    # Skip if custom library already exists
+    out_name = "lib%s.a" % msvcr_name
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if os.path.isfile(out_file):
+        log.debug('Skip building msvcr library: "%s" exists' %
+                  (out_file,))
+        return True
+
+    # Find the msvcr dll
+    msvcr_dll_name = msvcr_name + '.dll'
+    dll_file = find_dll(msvcr_dll_name)
+    if not dll_file:
+        log.warn('Cannot build msvcr library: "%s" not found' %
+                 msvcr_dll_name)
+        return False
+
+    def_name = "lib%s.def" % msvcr_name
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+
+    log.info('Building msvcr library: "%s" (from %s)' \
+             % (out_file, dll_file))
+
+    # Generate a symbol definition file from the msvcr dll
+    generate_def(dll_file, def_file)
+
+    # Create a custom mingw library for the given symbol definitions
+    cmd = ['dlltool', '-d', def_file, '-l', out_file]
+    retcode = subprocess.call(cmd)
+
+    # Clean up symbol definitions
+    os.remove(def_file)
+
+    return (not retcode)
+
+def build_import_library():
+    if os.name != 'nt':
+        return
+
+    arch = get_build_architecture()
+    if arch == 'AMD64':
+        return _build_import_library_amd64()
+    elif arch == 'Intel':
+        return _build_import_library_x86()
+    else:
+        raise ValueError("Unhandled arch %s" % arch)
+
+def _build_import_library_amd64():
+    dll_file = find_python_dll()
+
+    out_name = "libpython%d%d.a" % tuple(sys.version_info[:2])
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if os.path.isfile(out_file):
+        log.debug('Skip building import library: "%s" exists' %
+                  (out_file))
+        return
+
+    def_name = "python%d%d.def" % tuple(sys.version_info[:2])
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+
+    log.info('Building import library (arch=AMD64): "%s" (from %s)' %
+             (out_file, dll_file))
+
+    generate_def(dll_file, def_file)
+
+    cmd = ['dlltool', '-d', def_file, '-l', out_file]
+    subprocess.Popen(cmd)
+
+def _build_import_library_x86():
+    """ Build the import libraries for Mingw32-gcc on Windows
+    """
+    lib_name = "python%d%d.lib" % tuple(sys.version_info[:2])
+    lib_file = os.path.join(sys.prefix, 'libs', lib_name)
+    out_name = "libpython%d%d.a" % tuple(sys.version_info[:2])
+    out_file = os.path.join(sys.prefix, 'libs', out_name)
+    if not os.path.isfile(lib_file):
+        log.warn('Cannot build import library: "%s" not found' % (lib_file))
+        return
+    if os.path.isfile(out_file):
+        log.debug('Skip building import library: "%s" exists' % (out_file))
+        return
+    log.info('Building import library (ARCH=x86): "%s"' % (out_file))
+
+    from numpy.distutils import lib2def
+
+    def_name = "python%d%d.def" % tuple(sys.version_info[:2])
+    def_file = os.path.join(sys.prefix, 'libs', def_name)
+    nm_cmd = '%s %s' % (lib2def.DEFAULT_NM, lib_file)
+    nm_output = lib2def.getnm(nm_cmd)
+    dlist, flist = lib2def.parse_nm(nm_output)
+    lib2def.output_def(dlist, flist, lib2def.DEF_HEADER, open(def_file, 'w'))
+
+    dll_name = "python%d%d.dll" % tuple(sys.version_info[:2])
+    args = (dll_name, def_file, out_file)
+    cmd = 'dlltool --dllname %s --def %s --output-lib %s' % args
+    status = os.system(cmd)
+    # for now, fail silently
+    if status:
+        log.warn('Failed to build import library for gcc. Linking will fail.')
+    return
+
+#=====================================
+# Dealing with Visual Studio MANIFESTS
+#=====================================
+
+# Functions to deal with visual studio manifests. Manifest are a mechanism to
+# enforce strong DLL versioning on windows, and has nothing to do with
+# distutils MANIFEST. manifests are XML files with version info, and used by
+# the OS loader; they are necessary when linking against a DLL not in the
+# system path; in particular, official python 2.6 binary is built against the
+# MS runtime 9 (the one from VS 2008), which is not available on most windows
+# systems; python 2.6 installer does install it in the Win SxS (Side by side)
+# directory, but this requires the manifest for this to work. This is a big
+# mess, thanks MS for a wonderful system.
+
+# XXX: ideally, we should use exactly the same version as used by python. I
+# submitted a patch to get this version, but it was only included for python
+# 2.6.1 and above. So for versions below, we use a "best guess".
+_MSVCRVER_TO_FULLVER = {}
+if sys.platform == 'win32':
+    try:
+        import msvcrt
+        # I took one version in my SxS directory: no idea if it is the good
+        # one, and we can't retrieve it from python
+        _MSVCRVER_TO_FULLVER['80'] = "8.0.50727.42"
+        _MSVCRVER_TO_FULLVER['90'] = "9.0.21022.8"
+        # Value from msvcrt.CRT_ASSEMBLY_VERSION under Python 3.3.0
+        # on Windows XP:
+        _MSVCRVER_TO_FULLVER['100'] = "10.0.30319.460"
+        if hasattr(msvcrt, "CRT_ASSEMBLY_VERSION"):
+            major, minor, rest = msvcrt.CRT_ASSEMBLY_VERSION.split(".", 2)
+            _MSVCRVER_TO_FULLVER[major + minor] = msvcrt.CRT_ASSEMBLY_VERSION
+            del major, minor, rest
+    except ImportError:
+        # If we are here, means python was not built with MSVC. Not sure what
+        # to do in that case: manifest building will fail, but it should not be
+        # used in that case anyway
+        log.warn('Cannot import msvcrt: using manifest will not be possible')
+
+def msvc_manifest_xml(maj, min):
+    """Given a major and minor version of the MSVCR, returns the
+    corresponding XML file."""
+    try:
+        fullver = _MSVCRVER_TO_FULLVER[str(maj * 10 + min)]
+    except KeyError:
+        raise ValueError("Version %d,%d of MSVCRT not supported yet" %
+                         (maj, min))
+    # Don't be fooled, it looks like an XML, but it is not. In particular, it
+    # should not have any space before starting, and its size should be
+    # divisible by 4, most likely for alignement constraints when the xml is
+    # embedded in the binary...
+    # This template was copied directly from the python 2.6 binary (using
+    # strings.exe from mingw on python.exe).
+    template = """\
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC%(maj)d%(min)d.CRT" version="%(fullver)s" processorArchitecture="*" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
+    </dependentAssembly>
+  </dependency>
+</assembly>"""
+
+    return template % {'fullver': fullver, 'maj': maj, 'min': min}
+
+def manifest_rc(name, type='dll'):
+    """Return the rc file used to generate the res file which will be embedded
+    as manifest for given manifest file name, of given type ('dll' or
+    'exe').
+
+    Parameters
+    ----------
+    name : str
+            name of the manifest file to embed
+    type : str {'dll', 'exe'}
+            type of the binary which will embed the manifest
+
+    """
+    if type == 'dll':
+        rctype = 2
+    elif type == 'exe':
+        rctype = 1
+    else:
+        raise ValueError("Type %s not supported" % type)
+
+    return """\
+#include "winuser.h"
+%d RT_MANIFEST %s""" % (rctype, name)
+
+def check_embedded_msvcr_match_linked(msver):
+    """msver is the ms runtime version used for the MANIFEST."""
+    # check msvcr major version are the same for linking and
+    # embedding
+    msvcv = msvc_runtime_library()
+    if msvcv:
+        assert msvcv.startswith("msvcr"), msvcv
+        # Dealing with something like "mscvr90" or "mscvr100", the last
+        # last digit is the minor release, want int("9") or int("10"):
+        maj = int(msvcv[5:-1])
+        if not maj == int(msver):
+            raise ValueError(
+                  "Discrepancy between linked msvcr " \
+                  "(%d) and the one about to be embedded " \
+                  "(%d)" % (int(msver), maj))
+
+def configtest_name(config):
+    base = os.path.basename(config._gen_temp_sourcefile("yo", [], "c"))
+    return os.path.splitext(base)[0]
+
+def manifest_name(config):
+    # Get configest name (including suffix)
+    root = configtest_name(config)
+    exext = config.compiler.exe_extension
+    return root + exext + ".manifest"
+
+def rc_name(config):
+    # Get configtest name (including suffix)
+    root = configtest_name(config)
+    return root + ".rc"
+
+def generate_manifest(config):
+    msver = get_build_msvc_version()
+    if msver is not None:
+        if msver >= 8:
+            check_embedded_msvcr_match_linked(msver)
+            ma = int(msver)
+            mi = int((msver - ma) * 10)
+            # Write the manifest file
+            manxml = msvc_manifest_xml(ma, mi)
+            man = open(manifest_name(config), "w")
+            config.temp_files.append(manifest_name(config))
+            man.write(manxml)
+            man.close()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.py
new file mode 100644
index 0000000000..960e20c366
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.py
@@ -0,0 +1,2312 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import re
+import sys
+import imp
+import copy
+import glob
+import atexit
+import tempfile
+import subprocess
+import shutil
+
+import distutils
+from distutils.errors import DistutilsError
+try:
+    from threading import local as tlocal
+except ImportError:
+    from dummy_threading import local as tlocal
+
+# stores temporary directory of each thread to only create one per thread
+_tdata = tlocal()
+
+# store all created temporary directories so they can be deleted on exit
+_tmpdirs = []
+def clean_up_temporary_directory():
+    for d in _tmpdirs:
+        try:
+            shutil.rmtree(d)
+        except OSError:
+            pass
+
+atexit.register(clean_up_temporary_directory)
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from numpy.distutils.compat import get_exception
+from numpy.compat import basestring
+
+__all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict',
+           'dict_append', 'appendpath', 'generate_config_py',
+           'get_cmd', 'allpath', 'get_mathlibs',
+           'terminal_has_colors', 'red_text', 'green_text', 'yellow_text',
+           'blue_text', 'cyan_text', 'cyg2win32', 'mingw32', 'all_strings',
+           'has_f_sources', 'has_cxx_sources', 'filter_sources',
+           'get_dependencies', 'is_local_src_dir', 'get_ext_source_files',
+           'get_script_files', 'get_lib_source_files', 'get_data_files',
+           'dot_join', 'get_frame', 'minrelpath', 'njoin',
+           'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language',
+           'quote_args', 'get_build_architecture', 'get_info', 'get_pkg_info',
+           'get_num_build_jobs']
+
+class InstallableLib(object):
+    """
+    Container to hold information on an installable library.
+
+    Parameters
+    ----------
+    name : str
+        Name of the installed library.
+    build_info : dict
+        Dictionary holding build information.
+    target_dir : str
+        Absolute path specifying where to install the library.
+
+    See Also
+    --------
+    Configuration.add_installed_library
+
+    Notes
+    -----
+    The three parameters are stored as attributes with the same names.
+
+    """
+    def __init__(self, name, build_info, target_dir):
+        self.name = name
+        self.build_info = build_info
+        self.target_dir = target_dir
+
+
+def get_num_build_jobs():
+    """
+    Get number of parallel build jobs set by the --parallel command line
+    argument of setup.py
+    If the command did not receive a setting the environment variable
+    NPY_NUM_BUILD_JOBS checked and if that is unset it returns 1.
+
+    Returns
+    -------
+    out : int
+        number of parallel jobs that can be run
+
+    """
+    from numpy.distutils.core import get_distribution
+    envjobs = int(os.environ.get("NPY_NUM_BUILD_JOBS", 1))
+    dist = get_distribution()
+    # may be None during configuration
+    if dist is None:
+        return envjobs
+
+    # any of these three may have the job set, take the largest
+    cmdattr = (getattr(dist.get_command_obj('build'), 'parallel', None),
+               getattr(dist.get_command_obj('build_ext'), 'parallel', None),
+               getattr(dist.get_command_obj('build_clib'), 'parallel', None))
+    if all(x is None for x in cmdattr):
+        return envjobs
+    else:
+        return max(x for x in cmdattr if x is not None)
+
+def quote_args(args):
+    # don't used _nt_quote_args as it does not check if
+    # args items already have quotes or not.
+    args = list(args)
+    for i in range(len(args)):
+        a = args[i]
+        if ' ' in a and a[0] not in '"\'':
+            args[i] = '"%s"' % (a)
+    return args
+
+def allpath(name):
+    "Convert a /-separated pathname to one using the OS's path separator."
+    splitted = name.split('/')
+    return os.path.join(*splitted)
+
+def rel_path(path, parent_path):
+    """Return path relative to parent_path.
+    """
+    pd = os.path.abspath(parent_path)
+    apath = os.path.abspath(path)
+    if len(apath)<len(pd):
+        return path
+    if apath==pd:
+        return ''
+    if pd == apath[:len(pd)]:
+        assert apath[len(pd)] in [os.sep], repr((path, apath[len(pd)]))
+        path = apath[len(pd)+1:]
+    return path
+
+def get_path_from_frame(frame, parent_path=None):
+    """Return path of the module given a frame object from the call stack.
+
+    Returned path is relative to parent_path when given,
+    otherwise it is absolute path.
+    """
+
+    # First, try to find if the file name is in the frame.
+    try:
+        caller_file = eval('__file__', frame.f_globals, frame.f_locals)
+        d = os.path.dirname(os.path.abspath(caller_file))
+    except NameError:
+        # __file__ is not defined, so let's try __name__. We try this second
+        # because setuptools spoofs __name__ to be '__main__' even though
+        # sys.modules['__main__'] might be something else, like easy_install(1).
+        caller_name = eval('__name__', frame.f_globals, frame.f_locals)
+        __import__(caller_name)
+        mod = sys.modules[caller_name]
+        if hasattr(mod, '__file__'):
+            d = os.path.dirname(os.path.abspath(mod.__file__))
+        else:
+            # we're probably running setup.py as execfile("setup.py")
+            # (likely we're building an egg)
+            d = os.path.abspath('.')
+            # hmm, should we use sys.argv[0] like in __builtin__ case?
+
+    if parent_path is not None:
+        d = rel_path(d, parent_path)
+
+    return d or '.'
+
+def njoin(*path):
+    """Join two or more pathname components +
+    - convert a /-separated pathname to one using the OS's path separator.
+    - resolve `..` and `.` from path.
+
+    Either passing n arguments as in njoin('a','b'), or a sequence
+    of n names as in njoin(['a','b']) is handled, or a mixture of such arguments.
+    """
+    paths = []
+    for p in path:
+        if is_sequence(p):
+            # njoin(['a', 'b'], 'c')
+            paths.append(njoin(*p))
+        else:
+            assert is_string(p)
+            paths.append(p)
+    path = paths
+    if not path:
+        # njoin()
+        joined = ''
+    else:
+        # njoin('a', 'b')
+        joined = os.path.join(*path)
+    if os.path.sep != '/':
+        joined = joined.replace('/', os.path.sep)
+    return minrelpath(joined)
+
+def get_mathlibs(path=None):
+    """Return the MATHLIB line from numpyconfig.h
+    """
+    if path is not None:
+        config_file = os.path.join(path, '_numpyconfig.h')
+    else:
+        # Look for the file in each of the numpy include directories.
+        dirs = get_numpy_include_dirs()
+        for path in dirs:
+            fn = os.path.join(path, '_numpyconfig.h')
+            if os.path.exists(fn):
+                config_file = fn
+                break
+        else:
+            raise DistutilsError('_numpyconfig.h not found in numpy include '
+                'dirs %r' % (dirs,))
+
+    fid = open(config_file)
+    mathlibs = []
+    s = '#define MATHLIB'
+    for line in fid:
+        if line.startswith(s):
+            value = line[len(s):].strip()
+            if value:
+                mathlibs.extend(value.split(','))
+    fid.close()
+    return mathlibs
+
+def minrelpath(path):
+    """Resolve `..` and '.' from path.
+    """
+    if not is_string(path):
+        return path
+    if '.' not in path:
+        return path
+    l = path.split(os.sep)
+    while l:
+        try:
+            i = l.index('.', 1)
+        except ValueError:
+            break
+        del l[i]
+    j = 1
+    while l:
+        try:
+            i = l.index('..', j)
+        except ValueError:
+            break
+        if l[i-1]=='..':
+            j += 1
+        else:
+            del l[i], l[i-1]
+            j = 1
+    if not l:
+        return ''
+    return os.sep.join(l)
+
+def _fix_paths(paths, local_path, include_non_existing):
+    assert is_sequence(paths), repr(type(paths))
+    new_paths = []
+    assert not is_string(paths), repr(paths)
+    for n in paths:
+        if is_string(n):
+            if '*' in n or '?' in n:
+                p = glob.glob(n)
+                p2 = glob.glob(njoin(local_path, n))
+                if p2:
+                    new_paths.extend(p2)
+                elif p:
+                    new_paths.extend(p)
+                else:
+                    if include_non_existing:
+                        new_paths.append(n)
+                    print('could not resolve pattern in %r: %r' %
+                            (local_path, n))
+            else:
+                n2 = njoin(local_path, n)
+                if os.path.exists(n2):
+                    new_paths.append(n2)
+                else:
+                    if os.path.exists(n):
+                        new_paths.append(n)
+                    elif include_non_existing:
+                        new_paths.append(n)
+                    if not os.path.exists(n):
+                        print('non-existing path in %r: %r' %
+                                (local_path, n))
+
+        elif is_sequence(n):
+            new_paths.extend(_fix_paths(n, local_path, include_non_existing))
+        else:
+            new_paths.append(n)
+    return [minrelpath(p) for p in new_paths]
+
+def gpaths(paths, local_path='', include_non_existing=True):
+    """Apply glob to paths and prepend local_path if needed.
+    """
+    if is_string(paths):
+        paths = (paths,)
+    return _fix_paths(paths, local_path, include_non_existing)
+
+def make_temp_file(suffix='', prefix='', text=True):
+    if not hasattr(_tdata, 'tempdir'):
+        _tdata.tempdir = tempfile.mkdtemp()
+        _tmpdirs.append(_tdata.tempdir)
+    fid, name = tempfile.mkstemp(suffix=suffix,
+                                 prefix=prefix,
+                                 dir=_tdata.tempdir,
+                                 text=text)
+    fo = os.fdopen(fid, 'w')
+    return fo, name
+
+# Hooks for colored terminal output.
+# See also http://www.livinglogic.de/Python/ansistyle
+def terminal_has_colors():
+    if sys.platform=='cygwin' and 'USE_COLOR' not in os.environ:
+        # Avoid importing curses that causes illegal operation
+        # with a message:
+        #  PYTHON2 caused an invalid page fault in
+        #  module CYGNURSES7.DLL as 015f:18bbfc28
+        # Details: Python 2.3.3 [GCC 3.3.1 (cygming special)]
+        #          ssh to Win32 machine from debian
+        #          curses.version is 2.2
+        #          CYGWIN_98-4.10, release 1.5.7(0.109/3/2))
+        return 0
+    if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
+        try:
+            import curses
+            curses.setupterm()
+            if (curses.tigetnum("colors") >= 0
+                and curses.tigetnum("pairs") >= 0
+                and ((curses.tigetstr("setf") is not None
+                      and curses.tigetstr("setb") is not None)
+                     or (curses.tigetstr("setaf") is not None
+                         and curses.tigetstr("setab") is not None)
+                     or curses.tigetstr("scp") is not None)):
+                return 1
+        except Exception:
+            pass
+    return 0
+
+if terminal_has_colors():
+    _colour_codes = dict(black=0, red=1, green=2, yellow=3,
+                         blue=4, magenta=5, cyan=6, white=7, default=9)
+    def colour_text(s, fg=None, bg=None, bold=False):
+        seq = []
+        if bold:
+            seq.append('1')
+        if fg:
+            fgcode = 30 + _colour_codes.get(fg.lower(), 0)
+            seq.append(str(fgcode))
+        if bg:
+            bgcode = 40 + _colour_codes.get(fg.lower(), 7)
+            seq.append(str(bgcode))
+        if seq:
+            return '\x1b[%sm%s\x1b[0m' % (';'.join(seq), s)
+        else:
+            return s
+else:
+    def colour_text(s, fg=None, bg=None):
+        return s
+
+def default_text(s):
+    return colour_text(s, 'default')
+def red_text(s):
+    return colour_text(s, 'red')
+def green_text(s):
+    return colour_text(s, 'green')
+def yellow_text(s):
+    return colour_text(s, 'yellow')
+def cyan_text(s):
+    return colour_text(s, 'cyan')
+def blue_text(s):
+    return colour_text(s, 'blue')
+
+#########################
+
+def cyg2win32(path):
+    if sys.platform=='cygwin' and path.startswith('/cygdrive'):
+        path = path[10] + ':' + os.path.normcase(path[11:])
+    return path
+
+def mingw32():
+    """Return true when using mingw32 environment.
+    """
+    if sys.platform=='win32':
+        if os.environ.get('OSTYPE', '')=='msys':
+            return True
+        if os.environ.get('MSYSTEM', '')=='MINGW32':
+            return True
+        if os.environ.get('MSYSTEM', '')=='MINGW64':
+            return True
+        if 'GCC' in sys.version:
+            return True
+    return False
+
+def msvc_runtime_library():
+    "Return name of MSVC runtime library if Python was built with MSVC >= 7"
+    msc_pos = sys.version.find('MSC v.')
+    if msc_pos != -1:
+        msc_ver = sys.version[msc_pos+6:msc_pos+10]
+        lib = {'1300': 'msvcr70',    # MSVC 7.0
+               '1310': 'msvcr71',    # MSVC 7.1
+               '1400': 'msvcr80',    # MSVC 8
+               '1500': 'msvcr90',    # MSVC 9 (VS 2008)
+               '1600': 'msvcr100',   # MSVC 10 (aka 2010)
+              }.get(msc_ver, None)
+    else:
+        lib = None
+    return lib
+
+
+#########################
+
+#XXX need support for .C that is also C++
+cxx_ext_match = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
+fortran_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f)\Z', re.I).match
+f90_ext_match = re.compile(r'.*[.](f90|f95)\Z', re.I).match
+f90_module_name_match = re.compile(r'\s*module\s*(?P<name>[\w_]+)', re.I).match
+def _get_f90_modules(source):
+    """Return a list of Fortran f90 module names that
+    given source file defines.
+    """
+    if not f90_ext_match(source):
+        return []
+    modules = []
+    f = open(source, 'r')
+    for line in f:
+        m = f90_module_name_match(line)
+        if m:
+            name = m.group('name')
+            modules.append(name)
+            # break  # XXX can we assume that there is one module per file?
+    f.close()
+    return modules
+
+def is_string(s):
+    return isinstance(s, basestring)
+
+def all_strings(lst):
+    """Return True if all items in lst are string objects. """
+    for item in lst:
+        if not is_string(item):
+            return False
+    return True
+
+def is_sequence(seq):
+    if is_string(seq):
+        return False
+    try:
+        len(seq)
+    except:
+        return False
+    return True
+
+def is_glob_pattern(s):
+    return is_string(s) and ('*' in s or '?' is s)
+
+def as_list(seq):
+    if is_sequence(seq):
+        return list(seq)
+    else:
+        return [seq]
+
+def get_language(sources):
+    # not used in numpy/scipy packages, use build_ext.detect_language instead
+    """Determine language value (c,f77,f90) from sources """
+    language = None
+    for source in sources:
+        if isinstance(source, str):
+            if f90_ext_match(source):
+                language = 'f90'
+                break
+            elif fortran_ext_match(source):
+                language = 'f77'
+    return language
+
+def has_f_sources(sources):
+    """Return True if sources contains Fortran files """
+    for source in sources:
+        if fortran_ext_match(source):
+            return True
+    return False
+
+def has_cxx_sources(sources):
+    """Return True if sources contains C++ files """
+    for source in sources:
+        if cxx_ext_match(source):
+            return True
+    return False
+
+def filter_sources(sources):
+    """Return four lists of filenames containing
+    C, C++, Fortran, and Fortran 90 module sources,
+    respectively.
+    """
+    c_sources = []
+    cxx_sources = []
+    f_sources = []
+    fmodule_sources = []
+    for source in sources:
+        if fortran_ext_match(source):
+            modules = _get_f90_modules(source)
+            if modules:
+                fmodule_sources.append(source)
+            else:
+                f_sources.append(source)
+        elif cxx_ext_match(source):
+            cxx_sources.append(source)
+        else:
+            c_sources.append(source)
+    return c_sources, cxx_sources, f_sources, fmodule_sources
+
+
+def _get_headers(directory_list):
+    # get *.h files from list of directories
+    headers = []
+    for d in directory_list:
+        head = glob.glob(os.path.join(d, "*.h")) #XXX: *.hpp files??
+        headers.extend(head)
+    return headers
+
+def _get_directories(list_of_sources):
+    # get unique directories from list of sources.
+    direcs = []
+    for f in list_of_sources:
+        d = os.path.split(f)
+        if d[0] != '' and not d[0] in direcs:
+            direcs.append(d[0])
+    return direcs
+
+def get_dependencies(sources):
+    #XXX scan sources for include statements
+    return _get_headers(_get_directories(sources))
+
+def is_local_src_dir(directory):
+    """Return true if directory is local directory.
+    """
+    if not is_string(directory):
+        return False
+    abs_dir = os.path.abspath(directory)
+    c = os.path.commonprefix([os.getcwd(), abs_dir])
+    new_dir = abs_dir[len(c):].split(os.sep)
+    if new_dir and not new_dir[0]:
+        new_dir = new_dir[1:]
+    if new_dir and new_dir[0]=='build':
+        return False
+    new_dir = os.sep.join(new_dir)
+    return os.path.isdir(new_dir)
+
+def general_source_files(top_path):
+    pruned_directories = {'CVS':1, '.svn':1, 'build':1}
+    prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$')
+    for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
+        pruned = [ d for d in dirnames if d not in pruned_directories ]
+        dirnames[:] = pruned
+        for f in filenames:
+            if not prune_file_pat.search(f):
+                yield os.path.join(dirpath, f)
+
+def general_source_directories_files(top_path):
+    """Return a directory name relative to top_path and
+    files contained.
+    """
+    pruned_directories = ['CVS', '.svn', 'build']
+    prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$')
+    for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
+        pruned = [ d for d in dirnames if d not in pruned_directories ]
+        dirnames[:] = pruned
+        for d in dirnames:
+            dpath = os.path.join(dirpath, d)
+            rpath = rel_path(dpath, top_path)
+            files = []
+            for f in os.listdir(dpath):
+                fn = os.path.join(dpath, f)
+                if os.path.isfile(fn) and not prune_file_pat.search(fn):
+                    files.append(fn)
+            yield rpath, files
+    dpath = top_path
+    rpath = rel_path(dpath, top_path)
+    filenames = [os.path.join(dpath, f) for f in os.listdir(dpath) \
+                 if not prune_file_pat.search(f)]
+    files = [f for f in filenames if os.path.isfile(f)]
+    yield rpath, files
+
+
+def get_ext_source_files(ext):
+    # Get sources and any include files in the same directory.
+    filenames = []
+    sources = [_m for _m in ext.sources if is_string(_m)]
+    filenames.extend(sources)
+    filenames.extend(get_dependencies(sources))
+    for d in ext.depends:
+        if is_local_src_dir(d):
+            filenames.extend(list(general_source_files(d)))
+        elif os.path.isfile(d):
+            filenames.append(d)
+    return filenames
+
+def get_script_files(scripts):
+    scripts = [_m for _m in scripts if is_string(_m)]
+    return scripts
+
+def get_lib_source_files(lib):
+    filenames = []
+    sources = lib[1].get('sources', [])
+    sources = [_m for _m in sources if is_string(_m)]
+    filenames.extend(sources)
+    filenames.extend(get_dependencies(sources))
+    depends = lib[1].get('depends', [])
+    for d in depends:
+        if is_local_src_dir(d):
+            filenames.extend(list(general_source_files(d)))
+        elif os.path.isfile(d):
+            filenames.append(d)
+    return filenames
+
+def get_shared_lib_extension(is_python_ext=False):
+    """Return the correct file extension for shared libraries.
+
+    Parameters
+    ----------
+    is_python_ext : bool, optional
+        Whether the shared library is a Python extension.  Default is False.
+
+    Returns
+    -------
+    so_ext : str
+        The shared library extension.
+
+    Notes
+    -----
+    For Python shared libs, `so_ext` will typically be '.so' on Linux and OS X,
+    and '.pyd' on Windows.  For Python >= 3.2 `so_ext` has a tag prepended on
+    POSIX systems according to PEP 3149.  For Python 3.2 this is implemented on
+    Linux, but not on OS X.
+
+    """
+    confvars = distutils.sysconfig.get_config_vars()
+    # SO is deprecated in 3.3.1, use EXT_SUFFIX instead
+    so_ext = confvars.get('EXT_SUFFIX', None)
+    if so_ext is None:
+        so_ext = confvars.get('SO', '')
+
+    if not is_python_ext:
+        # hardcode known values, config vars (including SHLIB_SUFFIX) are
+        # unreliable (see #3182)
+        # darwin, windows and debug linux are wrong in 3.3.1 and older
+        if (sys.platform.startswith('linux') or
+            sys.platform.startswith('gnukfreebsd')):
+            so_ext = '.so'
+        elif sys.platform.startswith('darwin'):
+            so_ext = '.dylib'
+        elif sys.platform.startswith('win'):
+            so_ext = '.dll'
+        else:
+            # fall back to config vars for unknown platforms
+            # fix long extension for Python >=3.2, see PEP 3149.
+            if 'SOABI' in confvars:
+                # Does nothing unless SOABI config var exists
+                so_ext = so_ext.replace('.' + confvars.get('SOABI'), '', 1)
+
+    return so_ext
+
+def get_data_files(data):
+    if is_string(data):
+        return [data]
+    sources = data[1]
+    filenames = []
+    for s in sources:
+        if hasattr(s, '__call__'):
+            continue
+        if is_local_src_dir(s):
+            filenames.extend(list(general_source_files(s)))
+        elif is_string(s):
+            if os.path.isfile(s):
+                filenames.append(s)
+            else:
+                print('Not existing data file:', s)
+        else:
+            raise TypeError(repr(s))
+    return filenames
+
+def dot_join(*args):
+    return '.'.join([a for a in args if a])
+
+def get_frame(level=0):
+    """Return frame object from call stack with given level.
+    """
+    try:
+        return sys._getframe(level+1)
+    except AttributeError:
+        frame = sys.exc_info()[2].tb_frame
+        for _ in range(level+1):
+            frame = frame.f_back
+        return frame
+
+
+######################
+
+class Configuration(object):
+
+    _list_keys = ['packages', 'ext_modules', 'data_files', 'include_dirs',
+                  'libraries', 'headers', 'scripts', 'py_modules',
+                  'installed_libraries', 'define_macros']
+    _dict_keys = ['package_dir', 'installed_pkg_config']
+    _extra_keys = ['name', 'version']
+
+    numpy_include_dirs = []
+
+    def __init__(self,
+                 package_name=None,
+                 parent_name=None,
+                 top_path=None,
+                 package_path=None,
+                 caller_level=1,
+                 setup_name='setup.py',
+                 **attrs):
+        """Construct configuration instance of a package.
+
+        package_name -- name of the package
+                        Ex.: 'distutils'
+        parent_name  -- name of the parent package
+                        Ex.: 'numpy'
+        top_path     -- directory of the toplevel package
+                        Ex.: the directory where the numpy package source sits
+        package_path -- directory of package. Will be computed by magic from the
+                        directory of the caller module if not specified
+                        Ex.: the directory where numpy.distutils is
+        caller_level -- frame level to caller namespace, internal parameter.
+        """
+        self.name = dot_join(parent_name, package_name)
+        self.version = None
+
+        caller_frame = get_frame(caller_level)
+        self.local_path = get_path_from_frame(caller_frame, top_path)
+        # local_path -- directory of a file (usually setup.py) that
+        #               defines a configuration() function.
+        # local_path -- directory of a file (usually setup.py) that
+        #               defines a configuration() function.
+        if top_path is None:
+            top_path = self.local_path
+            self.local_path = ''
+        if package_path is None:
+            package_path = self.local_path
+        elif os.path.isdir(njoin(self.local_path, package_path)):
+            package_path = njoin(self.local_path, package_path)
+        if not os.path.isdir(package_path or '.'):
+            raise ValueError("%r is not a directory" % (package_path,))
+        self.top_path = top_path
+        self.package_path = package_path
+        # this is the relative path in the installed package
+        self.path_in_package = os.path.join(*self.name.split('.'))
+
+        self.list_keys = self._list_keys[:]
+        self.dict_keys = self._dict_keys[:]
+
+        for n in self.list_keys:
+            v = copy.copy(attrs.get(n, []))
+            setattr(self, n, as_list(v))
+
+        for n in self.dict_keys:
+            v = copy.copy(attrs.get(n, {}))
+            setattr(self, n, v)
+
+        known_keys = self.list_keys + self.dict_keys
+        self.extra_keys = self._extra_keys[:]
+        for n in attrs.keys():
+            if n in known_keys:
+                continue
+            a = attrs[n]
+            setattr(self, n, a)
+            if isinstance(a, list):
+                self.list_keys.append(n)
+            elif isinstance(a, dict):
+                self.dict_keys.append(n)
+            else:
+                self.extra_keys.append(n)
+
+        if os.path.exists(njoin(package_path, '__init__.py')):
+            self.packages.append(self.name)
+            self.package_dir[self.name] = package_path
+
+        self.options = dict(
+            ignore_setup_xxx_py = False,
+            assume_default_configuration = False,
+            delegate_options_to_subpackages = False,
+            quiet = False,
+            )
+
+        caller_instance = None
+        for i in range(1, 3):
+            try:
+                f = get_frame(i)
+            except ValueError:
+                break
+            try:
+                caller_instance = eval('self', f.f_globals, f.f_locals)
+                break
+            except NameError:
+                pass
+        if isinstance(caller_instance, self.__class__):
+            if caller_instance.options['delegate_options_to_subpackages']:
+                self.set_options(**caller_instance.options)
+
+        self.setup_name = setup_name
+
+    def todict(self):
+        """
+        Return a dictionary compatible with the keyword arguments of distutils
+        setup function.
+
+        Examples
+        --------
+        >>> setup(**config.todict())                           #doctest: +SKIP
+        """
+
+        self._optimize_data_files()
+        d = {}
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        for n in known_keys:
+            a = getattr(self, n)
+            if a:
+                d[n] = a
+        return d
+
+    def info(self, message):
+        if not self.options['quiet']:
+            print(message)
+
+    def warn(self, message):
+        sys.stderr.write('Warning: %s' % (message,))
+
+    def set_options(self, **options):
+        """
+        Configure Configuration instance.
+
+        The following options are available:
+         - ignore_setup_xxx_py
+         - assume_default_configuration
+         - delegate_options_to_subpackages
+         - quiet
+
+        """
+        for key, value in options.items():
+            if key in self.options:
+                self.options[key] = value
+            else:
+                raise ValueError('Unknown option: '+key)
+
+    def get_distribution(self):
+        """Return the distutils distribution object for self."""
+        from numpy.distutils.core import get_distribution
+        return get_distribution()
+
+    def _wildcard_get_subpackage(self, subpackage_name,
+                                 parent_name,
+                                 caller_level = 1):
+        l = subpackage_name.split('.')
+        subpackage_path = njoin([self.local_path]+l)
+        dirs = [_m for _m in glob.glob(subpackage_path) if os.path.isdir(_m)]
+        config_list = []
+        for d in dirs:
+            if not os.path.isfile(njoin(d, '__init__.py')):
+                continue
+            if 'build' in d.split(os.sep):
+                continue
+            n = '.'.join(d.split(os.sep)[-len(l):])
+            c = self.get_subpackage(n,
+                                    parent_name = parent_name,
+                                    caller_level = caller_level+1)
+            config_list.extend(c)
+        return config_list
+
+    def _get_configuration_from_setup_py(self, setup_py,
+                                         subpackage_name,
+                                         subpackage_path,
+                                         parent_name,
+                                         caller_level = 1):
+        # In case setup_py imports local modules:
+        sys.path.insert(0, os.path.dirname(setup_py))
+        try:
+            fo_setup_py = open(setup_py, 'U')
+            setup_name = os.path.splitext(os.path.basename(setup_py))[0]
+            n = dot_join(self.name, subpackage_name, setup_name)
+            setup_module = imp.load_module('_'.join(n.split('.')),
+                                           fo_setup_py,
+                                           setup_py,
+                                           ('.py', 'U', 1))
+            fo_setup_py.close()
+            if not hasattr(setup_module, 'configuration'):
+                if not self.options['assume_default_configuration']:
+                    self.warn('Assuming default configuration '\
+                              '(%s does not define configuration())'\
+                              % (setup_module))
+                config = Configuration(subpackage_name, parent_name,
+                                       self.top_path, subpackage_path,
+                                       caller_level = caller_level + 1)
+            else:
+                pn = dot_join(*([parent_name] + subpackage_name.split('.')[:-1]))
+                args = (pn,)
+                def fix_args_py2(args):
+                    if setup_module.configuration.__code__.co_argcount > 1:
+                        args = args + (self.top_path,)
+                    return args
+                def fix_args_py3(args):
+                    if setup_module.configuration.__code__.co_argcount > 1:
+                        args = args + (self.top_path,)
+                    return args
+                if sys.version_info[0] < 3:
+                    args = fix_args_py2(args)
+                else:
+                    args = fix_args_py3(args)
+                config = setup_module.configuration(*args)
+            if config.name!=dot_join(parent_name, subpackage_name):
+                self.warn('Subpackage %r configuration returned as %r' % \
+                          (dot_join(parent_name, subpackage_name), config.name))
+        finally:
+            del sys.path[0]
+        return config
+
+    def get_subpackage(self,subpackage_name,
+                       subpackage_path=None,
+                       parent_name=None,
+                       caller_level = 1):
+        """Return list of subpackage configurations.
+
+        Parameters
+        ----------
+        subpackage_name : str or None
+            Name of the subpackage to get the configuration. '*' in
+            subpackage_name is handled as a wildcard.
+        subpackage_path : str
+            If None, then the path is assumed to be the local path plus the
+            subpackage_name. If a setup.py file is not found in the
+            subpackage_path, then a default configuration is used.
+        parent_name : str
+            Parent name.
+        """
+        if subpackage_name is None:
+            if subpackage_path is None:
+                raise ValueError(
+                    "either subpackage_name or subpackage_path must be specified")
+            subpackage_name = os.path.basename(subpackage_path)
+
+        # handle wildcards
+        l = subpackage_name.split('.')
+        if subpackage_path is None and '*' in subpackage_name:
+            return self._wildcard_get_subpackage(subpackage_name,
+                                                 parent_name,
+                                                 caller_level = caller_level+1)
+        assert '*' not in subpackage_name, repr((subpackage_name, subpackage_path, parent_name))
+        if subpackage_path is None:
+            subpackage_path = njoin([self.local_path] + l)
+        else:
+            subpackage_path = njoin([subpackage_path] + l[:-1])
+            subpackage_path = self.paths([subpackage_path])[0]
+        setup_py = njoin(subpackage_path, self.setup_name)
+        if not self.options['ignore_setup_xxx_py']:
+            if not os.path.isfile(setup_py):
+                setup_py = njoin(subpackage_path,
+                                 'setup_%s.py' % (subpackage_name))
+        if not os.path.isfile(setup_py):
+            if not self.options['assume_default_configuration']:
+                self.warn('Assuming default configuration '\
+                          '(%s/{setup_%s,setup}.py was not found)' \
+                          % (os.path.dirname(setup_py), subpackage_name))
+            config = Configuration(subpackage_name, parent_name,
+                                   self.top_path, subpackage_path,
+                                   caller_level = caller_level+1)
+        else:
+            config = self._get_configuration_from_setup_py(
+                setup_py,
+                subpackage_name,
+                subpackage_path,
+                parent_name,
+                caller_level = caller_level + 1)
+        if config:
+            return [config]
+        else:
+            return []
+
+    def add_subpackage(self,subpackage_name,
+                       subpackage_path=None,
+                       standalone = False):
+        """Add a sub-package to the current Configuration instance.
+
+        This is useful in a setup.py script for adding sub-packages to a
+        package.
+
+        Parameters
+        ----------
+        subpackage_name : str
+            name of the subpackage
+        subpackage_path : str
+            if given, the subpackage path such as the subpackage is in
+            subpackage_path / subpackage_name. If None,the subpackage is
+            assumed to be located in the local path / subpackage_name.
+        standalone : bool
+        """
+
+        if standalone:
+            parent_name = None
+        else:
+            parent_name = self.name
+        config_list = self.get_subpackage(subpackage_name, subpackage_path,
+                                          parent_name = parent_name,
+                                          caller_level = 2)
+        if not config_list:
+            self.warn('No configuration returned, assuming unavailable.')
+        for config in config_list:
+            d = config
+            if isinstance(config, Configuration):
+                d = config.todict()
+            assert isinstance(d, dict), repr(type(d))
+
+            self.info('Appending %s configuration to %s' \
+                      % (d.get('name'), self.name))
+            self.dict_append(**d)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add a subpackage '+ subpackage_name)
+
+    def add_data_dir(self, data_path):
+        """Recursively add files under data_path to data_files list.
+
+        Recursively add files under data_path to the list of data_files to be
+        installed (and distributed). The data_path can be either a relative
+        path-name, or an absolute path-name, or a 2-tuple where the first
+        argument shows where in the install directory the data directory
+        should be installed to.
+
+        Parameters
+        ----------
+        data_path : seq or str
+            Argument can be either
+
+                * 2-sequence (<datadir suffix>, <path to data directory>)
+                * path to data directory where python datadir suffix defaults
+                  to package dir.
+
+        Notes
+        -----
+        Rules for installation paths:
+          foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar
+          (gun, foo/bar) -> parent/gun
+          foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b
+          (gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun
+          (gun/*, foo/*) -> parent/gun/a, parent/gun/b
+          /foo/bar -> (bar, /foo/bar) -> parent/bar
+          (gun, /foo/bar) -> parent/gun
+          (fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar
+
+        Examples
+        --------
+        For example suppose the source directory contains fun/foo.dat and
+        fun/bar/car.dat::
+
+            >>> self.add_data_dir('fun')                       #doctest: +SKIP
+            >>> self.add_data_dir(('sun', 'fun'))              #doctest: +SKIP
+            >>> self.add_data_dir(('gun', '/full/path/to/fun'))#doctest: +SKIP
+
+        Will install data-files to the locations::
+
+            <package install directory>/
+              fun/
+                foo.dat
+                bar/
+                  car.dat
+              sun/
+                foo.dat
+                bar/
+                  car.dat
+              gun/
+                foo.dat
+                car.dat
+        """
+        if is_sequence(data_path):
+            d, data_path = data_path
+        else:
+            d = None
+        if is_sequence(data_path):
+            [self.add_data_dir((d, p)) for p in data_path]
+            return
+        if not is_string(data_path):
+            raise TypeError("not a string: %r" % (data_path,))
+        if d is None:
+            if os.path.isabs(data_path):
+                return self.add_data_dir((os.path.basename(data_path), data_path))
+            return self.add_data_dir((data_path, data_path))
+        paths = self.paths(data_path, include_non_existing=False)
+        if is_glob_pattern(data_path):
+            if is_glob_pattern(d):
+                pattern_list = allpath(d).split(os.sep)
+                pattern_list.reverse()
+                # /a/*//b/ -> /a/*/b
+                rl = list(range(len(pattern_list)-1)); rl.reverse()
+                for i in rl:
+                    if not pattern_list[i]:
+                        del pattern_list[i]
+                #
+                for path in paths:
+                    if not os.path.isdir(path):
+                        print('Not a directory, skipping', path)
+                        continue
+                    rpath = rel_path(path, self.local_path)
+                    path_list = rpath.split(os.sep)
+                    path_list.reverse()
+                    target_list = []
+                    i = 0
+                    for s in pattern_list:
+                        if is_glob_pattern(s):
+                            if i>=len(path_list):
+                                raise ValueError('cannot fill pattern %r with %r' \
+                                      % (d, path))
+                            target_list.append(path_list[i])
+                        else:
+                            assert s==path_list[i], repr((s, path_list[i], data_path, d, path, rpath))
+                            target_list.append(s)
+                        i += 1
+                    if path_list[i:]:
+                        self.warn('mismatch of pattern_list=%s and path_list=%s'\
+                                  % (pattern_list, path_list))
+                    target_list.reverse()
+                    self.add_data_dir((os.sep.join(target_list), path))
+            else:
+                for path in paths:
+                    self.add_data_dir((d, path))
+            return
+        assert not is_glob_pattern(d), repr(d)
+
+        dist = self.get_distribution()
+        if dist is not None and dist.data_files is not None:
+            data_files = dist.data_files
+        else:
+            data_files = self.data_files
+
+        for path in paths:
+            for d1, f in list(general_source_directories_files(path)):
+                target_path = os.path.join(self.path_in_package, d, d1)
+                data_files.append((target_path, f))
+
+    def _optimize_data_files(self):
+        data_dict = {}
+        for p, files in self.data_files:
+            if p not in data_dict:
+                data_dict[p] = set()
+            for f in files:
+                data_dict[p].add(f)
+        self.data_files[:] = [(p, list(files)) for p, files in data_dict.items()]
+
+    def add_data_files(self,*files):
+        """Add data files to configuration data_files.
+
+        Parameters
+        ----------
+        files : sequence
+            Argument(s) can be either
+
+                * 2-sequence (<datadir prefix>,<path to data file(s)>)
+                * paths to data files where python datadir prefix defaults
+                  to package dir.
+
+        Notes
+        -----
+        The form of each element of the files sequence is very flexible
+        allowing many combinations of where to get the files from the package
+        and where they should ultimately be installed on the system. The most
+        basic usage is for an element of the files argument sequence to be a
+        simple filename. This will cause that file from the local path to be
+        installed to the installation path of the self.name package (package
+        path). The file argument can also be a relative path in which case the
+        entire relative path will be installed into the package directory.
+        Finally, the file can be an absolute path name in which case the file
+        will be found at the absolute path name but installed to the package
+        path.
+
+        This basic behavior can be augmented by passing a 2-tuple in as the
+        file argument. The first element of the tuple should specify the
+        relative path (under the package install directory) where the
+        remaining sequence of files should be installed to (it has nothing to
+        do with the file-names in the source distribution). The second element
+        of the tuple is the sequence of files that should be installed. The
+        files in this sequence can be filenames, relative paths, or absolute
+        paths. For absolute paths the file will be installed in the top-level
+        package installation directory (regardless of the first argument).
+        Filenames and relative path names will be installed in the package
+        install directory under the path name given as the first element of
+        the tuple.
+
+        Rules for installation paths:
+
+          #. file.txt -> (., file.txt)-> parent/file.txt
+          #. foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt
+          #. /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt
+          #. *.txt -> parent/a.txt, parent/b.txt
+          #. foo/*.txt -> parent/foo/a.txt, parent/foo/b.txt
+          #. */*.txt -> (*, */*.txt) -> parent/c/a.txt, parent/d/b.txt
+          #. (sun, file.txt) -> parent/sun/file.txt
+          #. (sun, bar/file.txt) -> parent/sun/file.txt
+          #. (sun, /foo/bar/file.txt) -> parent/sun/file.txt
+          #. (sun, *.txt) -> parent/sun/a.txt, parent/sun/b.txt
+          #. (sun, bar/*.txt) -> parent/sun/a.txt, parent/sun/b.txt
+          #. (sun/*, */*.txt) -> parent/sun/c/a.txt, parent/d/b.txt
+
+        An additional feature is that the path to a data-file can actually be
+        a function that takes no arguments and returns the actual path(s) to
+        the data-files. This is useful when the data files are generated while
+        building the package.
+
+        Examples
+        --------
+        Add files to the list of data_files to be included with the package.
+
+            >>> self.add_data_files('foo.dat',
+            ...     ('fun', ['gun.dat', 'nun/pun.dat', '/tmp/sun.dat']),
+            ...     'bar/cat.dat',
+            ...     '/full/path/to/can.dat')                   #doctest: +SKIP
+
+        will install these data files to::
+
+            <package install directory>/
+             foo.dat
+             fun/
+               gun.dat
+               nun/
+                 pun.dat
+             sun.dat
+             bar/
+               car.dat
+             can.dat
+
+        where <package install directory> is the package (or sub-package)
+        directory such as '/usr/lib/python2.4/site-packages/mypackage' ('C:
+        \\Python2.4 \\Lib \\site-packages \\mypackage') or
+        '/usr/lib/python2.4/site- packages/mypackage/mysubpackage' ('C:
+        \\Python2.4 \\Lib \\site-packages \\mypackage \\mysubpackage').
+        """
+
+        if len(files)>1:
+            for f in files:
+                self.add_data_files(f)
+            return
+        assert len(files)==1
+        if is_sequence(files[0]):
+            d, files = files[0]
+        else:
+            d = None
+        if is_string(files):
+            filepat = files
+        elif is_sequence(files):
+            if len(files)==1:
+                filepat = files[0]
+            else:
+                for f in files:
+                    self.add_data_files((d, f))
+                return
+        else:
+            raise TypeError(repr(type(files)))
+
+        if d is None:
+            if hasattr(filepat, '__call__'):
+                d = ''
+            elif os.path.isabs(filepat):
+                d = ''
+            else:
+                d = os.path.dirname(filepat)
+            self.add_data_files((d, files))
+            return
+
+        paths = self.paths(filepat, include_non_existing=False)
+        if is_glob_pattern(filepat):
+            if is_glob_pattern(d):
+                pattern_list = d.split(os.sep)
+                pattern_list.reverse()
+                for path in paths:
+                    path_list = path.split(os.sep)
+                    path_list.reverse()
+                    path_list.pop() # filename
+                    target_list = []
+                    i = 0
+                    for s in pattern_list:
+                        if is_glob_pattern(s):
+                            target_list.append(path_list[i])
+                            i += 1
+                        else:
+                            target_list.append(s)
+                    target_list.reverse()
+                    self.add_data_files((os.sep.join(target_list), path))
+            else:
+                self.add_data_files((d, paths))
+            return
+        assert not is_glob_pattern(d), repr((d, filepat))
+
+        dist = self.get_distribution()
+        if dist is not None and dist.data_files is not None:
+            data_files = dist.data_files
+        else:
+            data_files = self.data_files
+
+        data_files.append((os.path.join(self.path_in_package, d), paths))
+
+    ### XXX Implement add_py_modules
+
+    def add_define_macros(self, macros):
+        """Add define macros to configuration
+
+        Add the given sequence of macro name and value duples to the beginning
+        of the define_macros list This list will be visible to all extension
+        modules of the current package.
+        """
+        dist = self.get_distribution()
+        if dist is not None:
+            if not hasattr(dist, 'define_macros'):
+                dist.define_macros = []
+            dist.define_macros.extend(macros)
+        else:
+            self.define_macros.extend(macros)
+
+
+    def add_include_dirs(self,*paths):
+        """Add paths to configuration include directories.
+
+        Add the given sequence of paths to the beginning of the include_dirs
+        list. This list will be visible to all extension modules of the
+        current package.
+        """
+        include_dirs = self.paths(paths)
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.include_dirs is None:
+                dist.include_dirs = []
+            dist.include_dirs.extend(include_dirs)
+        else:
+            self.include_dirs.extend(include_dirs)
+
+    def add_headers(self,*files):
+        """Add installable headers to configuration.
+
+        Add the given sequence of files to the beginning of the headers list.
+        By default, headers will be installed under <python-
+        include>/<self.name.replace('.','/')>/ directory. If an item of files
+        is a tuple, then its first argument specifies the actual installation
+        location relative to the <python-include> path.
+
+        Parameters
+        ----------
+        files : str or seq
+            Argument(s) can be either:
+
+                * 2-sequence (<includedir suffix>,<path to header file(s)>)
+                * path(s) to header file(s) where python includedir suffix will
+                  default to package name.
+        """
+        headers = []
+        for path in files:
+            if is_string(path):
+                [headers.append((self.name, p)) for p in self.paths(path)]
+            else:
+                if not isinstance(path, (tuple, list)) or len(path) != 2:
+                    raise TypeError(repr(path))
+                [headers.append((path[0], p)) for p in self.paths(path[1])]
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.headers is None:
+                dist.headers = []
+            dist.headers.extend(headers)
+        else:
+            self.headers.extend(headers)
+
+    def paths(self,*paths,**kws):
+        """Apply glob to paths and prepend local_path if needed.
+
+        Applies glob.glob(...) to each path in the sequence (if needed) and
+        pre-pends the local_path if needed. Because this is called on all
+        source lists, this allows wildcard characters to be specified in lists
+        of sources for extension modules and libraries and scripts and allows
+        path-names be relative to the source directory.
+
+        """
+        include_non_existing = kws.get('include_non_existing', True)
+        return gpaths(paths,
+                      local_path = self.local_path,
+                      include_non_existing=include_non_existing)
+
+    def _fix_paths_dict(self, kw):
+        for k in kw.keys():
+            v = kw[k]
+            if k in ['sources', 'depends', 'include_dirs', 'library_dirs',
+                     'module_dirs', 'extra_objects']:
+                new_v = self.paths(v)
+                kw[k] = new_v
+
+    def add_extension(self,name,sources,**kw):
+        """Add extension to configuration.
+
+        Create and add an Extension instance to the ext_modules list. This
+        method also takes the following optional keyword arguments that are
+        passed on to the Extension constructor.
+
+        Parameters
+        ----------
+        name : str
+            name of the extension
+        sources : seq
+            list of the sources. The list of sources may contain functions
+            (called source generators) which must take an extension instance
+            and a build directory as inputs and return a source file or list of
+            source files or None. If None is returned then no sources are
+            generated. If the Extension instance has no sources after
+            processing all source generators, then no extension module is
+            built.
+        include_dirs :
+        define_macros :
+        undef_macros :
+        library_dirs :
+        libraries :
+        runtime_library_dirs :
+        extra_objects :
+        extra_compile_args :
+        extra_link_args :
+        extra_f77_compile_args :
+        extra_f90_compile_args :
+        export_symbols :
+        swig_opts :
+        depends :
+            The depends list contains paths to files or directories that the
+            sources of the extension module depend on. If any path in the
+            depends list is newer than the extension module, then the module
+            will be rebuilt.
+        language :
+        f2py_options :
+        module_dirs :
+        extra_info : dict or list
+            dict or list of dict of keywords to be appended to keywords.
+
+        Notes
+        -----
+        The self.paths(...) method is applied to all lists that may contain
+        paths.
+        """
+        ext_args = copy.copy(kw)
+        ext_args['name'] = dot_join(self.name, name)
+        ext_args['sources'] = sources
+
+        if 'extra_info' in ext_args:
+            extra_info = ext_args['extra_info']
+            del ext_args['extra_info']
+            if isinstance(extra_info, dict):
+                extra_info = [extra_info]
+            for info in extra_info:
+                assert isinstance(info, dict), repr(info)
+                dict_append(ext_args,**info)
+
+        self._fix_paths_dict(ext_args)
+
+        # Resolve out-of-tree dependencies
+        libraries = ext_args.get('libraries', [])
+        libnames = []
+        ext_args['libraries'] = []
+        for libname in libraries:
+            if isinstance(libname, tuple):
+                self._fix_paths_dict(libname[1])
+
+            # Handle library names of the form libname@relative/path/to/library
+            if '@' in libname:
+                lname, lpath = libname.split('@', 1)
+                lpath = os.path.abspath(njoin(self.local_path, lpath))
+                if os.path.isdir(lpath):
+                    c = self.get_subpackage(None, lpath,
+                                            caller_level = 2)
+                    if isinstance(c, Configuration):
+                        c = c.todict()
+                    for l in [l[0] for l in c.get('libraries', [])]:
+                        llname = l.split('__OF__', 1)[0]
+                        if llname == lname:
+                            c.pop('name', None)
+                            dict_append(ext_args,**c)
+                            break
+                    continue
+            libnames.append(libname)
+
+        ext_args['libraries'] = libnames + ext_args['libraries']
+        ext_args['define_macros'] = \
+            self.define_macros + ext_args.get('define_macros', [])
+
+        from numpy.distutils.core import Extension
+        ext = Extension(**ext_args)
+        self.ext_modules.append(ext)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add an extension '+name)
+        return ext
+
+    def add_library(self,name,sources,**build_info):
+        """
+        Add library to configuration.
+
+        Parameters
+        ----------
+        name : str
+            Name of the extension.
+        sources : sequence
+            List of the sources. The list of sources may contain functions
+            (called source generators) which must take an extension instance
+            and a build directory as inputs and return a source file or list of
+            source files or None. If None is returned then no sources are
+            generated. If the Extension instance has no sources after
+            processing all source generators, then no extension module is
+            built.
+        build_info : dict, optional
+            The following keys are allowed:
+
+                * depends
+                * macros
+                * include_dirs
+                * extra_compiler_args
+                * extra_f77_compiler_args
+                * extra_f90_compiler_args
+                * f2py_options
+                * language
+
+        """
+        self._add_library(name, sources, None, build_info)
+
+        dist = self.get_distribution()
+        if dist is not None:
+            self.warn('distutils distribution has been initialized,'\
+                      ' it may be too late to add a library '+ name)
+
+    def _add_library(self, name, sources, install_dir, build_info):
+        """Common implementation for add_library and add_installed_library. Do
+        not use directly"""
+        build_info = copy.copy(build_info)
+        name = name #+ '__OF__' + self.name
+        build_info['sources'] = sources
+
+        # Sometimes, depends is not set up to an empty list by default, and if
+        # depends is not given to add_library, distutils barfs (#1134)
+        if not 'depends' in build_info:
+            build_info['depends'] = []
+
+        self._fix_paths_dict(build_info)
+
+        # Add to libraries list so that it is build with build_clib
+        self.libraries.append((name, build_info))
+
+    def add_installed_library(self, name, sources, install_dir, build_info=None):
+        """
+        Similar to add_library, but the specified library is installed.
+
+        Most C libraries used with `distutils` are only used to build python
+        extensions, but libraries built through this method will be installed
+        so that they can be reused by third-party packages.
+
+        Parameters
+        ----------
+        name : str
+            Name of the installed library.
+        sources : sequence
+            List of the library's source files. See `add_library` for details.
+        install_dir : str
+            Path to install the library, relative to the current sub-package.
+        build_info : dict, optional
+            The following keys are allowed:
+
+                * depends
+                * macros
+                * include_dirs
+                * extra_compiler_args
+                * extra_f77_compiler_args
+                * extra_f90_compiler_args
+                * f2py_options
+                * language
+
+        Returns
+        -------
+        None
+
+        See Also
+        --------
+        add_library, add_npy_pkg_config, get_info
+
+        Notes
+        -----
+        The best way to encode the options required to link against the specified
+        C libraries is to use a "libname.ini" file, and use `get_info` to
+        retrieve the required options (see `add_npy_pkg_config` for more
+        information).
+
+        """
+        if not build_info:
+            build_info = {}
+
+        install_dir = os.path.join(self.package_path, install_dir)
+        self._add_library(name, sources, install_dir, build_info)
+        self.installed_libraries.append(InstallableLib(name, build_info, install_dir))
+
+    def add_npy_pkg_config(self, template, install_dir, subst_dict=None):
+        """
+        Generate and install a npy-pkg config file from a template.
+
+        The config file generated from `template` is installed in the
+        given install directory, using `subst_dict` for variable substitution.
+
+        Parameters
+        ----------
+        template : str
+            The path of the template, relatively to the current package path.
+        install_dir : str
+            Where to install the npy-pkg config file, relatively to the current
+            package path.
+        subst_dict : dict, optional
+            If given, any string of the form ``@key@`` will be replaced by
+            ``subst_dict[key]`` in the template file when installed. The install
+            prefix is always available through the variable ``@prefix@``, since the
+            install prefix is not easy to get reliably from setup.py.
+
+        See also
+        --------
+        add_installed_library, get_info
+
+        Notes
+        -----
+        This works for both standard installs and in-place builds, i.e. the
+        ``@prefix@`` refer to the source directory for in-place builds.
+
+        Examples
+        --------
+        ::
+
+            config.add_npy_pkg_config('foo.ini.in', 'lib', {'foo': bar})
+
+        Assuming the foo.ini.in file has the following content::
+
+            [meta]
+            Name=@foo@
+            Version=1.0
+            Description=dummy description
+
+            [default]
+            Cflags=-I@prefix@/include
+            Libs=
+
+        The generated file will have the following content::
+
+            [meta]
+            Name=bar
+            Version=1.0
+            Description=dummy description
+
+            [default]
+            Cflags=-Iprefix_dir/include
+            Libs=
+
+        and will be installed as foo.ini in the 'lib' subpath.
+
+        """
+        if subst_dict is None:
+            subst_dict = {}
+        basename = os.path.splitext(template)[0]
+        template = os.path.join(self.package_path, template)
+
+        if self.name in self.installed_pkg_config:
+            self.installed_pkg_config[self.name].append((template, install_dir,
+                subst_dict))
+        else:
+            self.installed_pkg_config[self.name] = [(template, install_dir,
+                subst_dict)]
+
+
+    def add_scripts(self,*files):
+        """Add scripts to configuration.
+
+        Add the sequence of files to the beginning of the scripts list.
+        Scripts will be installed under the <prefix>/bin/ directory.
+
+        """
+        scripts = self.paths(files)
+        dist = self.get_distribution()
+        if dist is not None:
+            if dist.scripts is None:
+                dist.scripts = []
+            dist.scripts.extend(scripts)
+        else:
+            self.scripts.extend(scripts)
+
+    def dict_append(self,**dict):
+        for key in self.list_keys:
+            a = getattr(self, key)
+            a.extend(dict.get(key, []))
+        for key in self.dict_keys:
+            a = getattr(self, key)
+            a.update(dict.get(key, {}))
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        for key in dict.keys():
+            if key not in known_keys:
+                a = getattr(self, key, None)
+                if a and a==dict[key]: continue
+                self.warn('Inheriting attribute %r=%r from %r' \
+                          % (key, dict[key], dict.get('name', '?')))
+                setattr(self, key, dict[key])
+                self.extra_keys.append(key)
+            elif key in self.extra_keys:
+                self.info('Ignoring attempt to set %r (from %r to %r)' \
+                          % (key, getattr(self, key), dict[key]))
+            elif key in known_keys:
+                # key is already processed above
+                pass
+            else:
+                raise ValueError("Don't know about key=%r" % (key))
+
+    def __str__(self):
+        from pprint import pformat
+        known_keys = self.list_keys + self.dict_keys + self.extra_keys
+        s = '<'+5*'-' + '\n'
+        s += 'Configuration of '+self.name+':\n'
+        known_keys.sort()
+        for k in known_keys:
+            a = getattr(self, k, None)
+            if a:
+                s += '%s = %s\n' % (k, pformat(a))
+        s += 5*'-' + '>'
+        return s
+
+    def get_config_cmd(self):
+        """
+        Returns the numpy.distutils config command instance.
+        """
+        cmd = get_cmd('config')
+        cmd.ensure_finalized()
+        cmd.dump_source = 0
+        cmd.noisy = 0
+        old_path = os.environ.get('PATH')
+        if old_path:
+            path = os.pathsep.join(['.', old_path])
+            os.environ['PATH'] = path
+        return cmd
+
+    def get_build_temp_dir(self):
+        """
+        Return a path to a temporary directory where temporary files should be
+        placed.
+        """
+        cmd = get_cmd('build')
+        cmd.ensure_finalized()
+        return cmd.build_temp
+
+    def have_f77c(self):
+        """Check for availability of Fortran 77 compiler.
+
+        Use it inside source generating function to ensure that
+        setup distribution instance has been initialized.
+
+        Notes
+        -----
+        True if a Fortran 77 compiler is available (because a simple Fortran 77
+        code was able to be compiled successfully).
+        """
+        simple_fortran_subroutine = '''
+        subroutine simple
+        end
+        '''
+        config_cmd = self.get_config_cmd()
+        flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f77')
+        return flag
+
+    def have_f90c(self):
+        """Check for availability of Fortran 90 compiler.
+
+        Use it inside source generating function to ensure that
+        setup distribution instance has been initialized.
+
+        Notes
+        -----
+        True if a Fortran 90 compiler is available (because a simple Fortran
+        90 code was able to be compiled successfully)
+        """
+        simple_fortran_subroutine = '''
+        subroutine simple
+        end
+        '''
+        config_cmd = self.get_config_cmd()
+        flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f90')
+        return flag
+
+    def append_to(self, extlib):
+        """Append libraries, include_dirs to extension or library item.
+        """
+        if is_sequence(extlib):
+            lib_name, build_info = extlib
+            dict_append(build_info,
+                        libraries=self.libraries,
+                        include_dirs=self.include_dirs)
+        else:
+            from numpy.distutils.core import Extension
+            assert isinstance(extlib, Extension), repr(extlib)
+            extlib.libraries.extend(self.libraries)
+            extlib.include_dirs.extend(self.include_dirs)
+
+    def _get_svn_revision(self, path):
+        """Return path's SVN revision number.
+        """
+        revision = None
+        m = None
+        cwd =  os.getcwd()
+        try:
+            os.chdir(path or '.')
+            p = subprocess.Popen(['svnversion'], shell=True,
+                    stdout=subprocess.PIPE, stderr=None,
+                    close_fds=True)
+            sout = p.stdout
+            m = re.match(r'(?P<revision>\d+)', sout.read())
+        except:
+            pass
+        os.chdir(cwd)
+        if m:
+            revision = int(m.group('revision'))
+            return revision
+        if sys.platform=='win32' and os.environ.get('SVN_ASP_DOT_NET_HACK', None):
+            entries = njoin(path, '_svn', 'entries')
+        else:
+            entries = njoin(path, '.svn', 'entries')
+        if os.path.isfile(entries):
+            f = open(entries)
+            fstr = f.read()
+            f.close()
+            if fstr[:5] == '<?xml':  # pre 1.4
+                m = re.search(r'revision="(?P<revision>\d+)"', fstr)
+                if m:
+                    revision = int(m.group('revision'))
+            else:  # non-xml entries file --- check to be sure that
+                m = re.search(r'dir[\n\r]+(?P<revision>\d+)', fstr)
+                if m:
+                    revision = int(m.group('revision'))
+        return revision
+
+    def _get_hg_revision(self, path):
+        """Return path's Mercurial revision number.
+        """
+        revision = None
+        m = None
+        cwd =  os.getcwd()
+        try:
+            os.chdir(path or '.')
+            p = subprocess.Popen(['hg identify --num'], shell=True,
+                    stdout=subprocess.PIPE, stderr=None,
+                    close_fds=True)
+            sout = p.stdout
+            m = re.match(r'(?P<revision>\d+)', sout.read())
+        except:
+            pass
+        os.chdir(cwd)
+        if m:
+            revision = int(m.group('revision'))
+            return revision
+        branch_fn = njoin(path, '.hg', 'branch')
+        branch_cache_fn = njoin(path, '.hg', 'branch.cache')
+
+        if os.path.isfile(branch_fn):
+            branch0 = None
+            f = open(branch_fn)
+            revision0 = f.read().strip()
+            f.close()
+
+            branch_map = {}
+            for line in file(branch_cache_fn, 'r'):
+                branch1, revision1  = line.split()[:2]
+                if revision1==revision0:
+                    branch0 = branch1
+                try:
+                    revision1 = int(revision1)
+                except ValueError:
+                    continue
+                branch_map[branch1] = revision1
+
+            revision = branch_map.get(branch0)
+        return revision
+
+
+    def get_version(self, version_file=None, version_variable=None):
+        """Try to get version string of a package.
+
+        Return a version string of the current package or None if the version
+        information could not be detected.
+
+        Notes
+        -----
+        This method scans files named
+        __version__.py, <packagename>_version.py, version.py, and
+        __svn_version__.py for string variables version, __version\__, and
+        <packagename>_version, until a version number is found.
+        """
+        version = getattr(self, 'version', None)
+        if version is not None:
+            return version
+
+        # Get version from version file.
+        if version_file is None:
+            files = ['__version__.py',
+                     self.name.split('.')[-1]+'_version.py',
+                     'version.py',
+                     '__svn_version__.py',
+                     '__hg_version__.py']
+        else:
+            files = [version_file]
+        if version_variable is None:
+            version_vars = ['version',
+                            '__version__',
+                            self.name.split('.')[-1]+'_version']
+        else:
+            version_vars = [version_variable]
+        for f in files:
+            fn = njoin(self.local_path, f)
+            if os.path.isfile(fn):
+                info = (open(fn), fn, ('.py', 'U', 1))
+                name = os.path.splitext(os.path.basename(fn))[0]
+                n = dot_join(self.name, name)
+                try:
+                    version_module = imp.load_module('_'.join(n.split('.')),*info)
+                except ImportError:
+                    msg = get_exception()
+                    self.warn(str(msg))
+                    version_module = None
+                if version_module is None:
+                    continue
+
+                for a in version_vars:
+                    version = getattr(version_module, a, None)
+                    if version is not None:
+                        break
+                if version is not None:
+                    break
+
+        if version is not None:
+            self.version = version
+            return version
+
+        # Get version as SVN or Mercurial revision number
+        revision = self._get_svn_revision(self.local_path)
+        if revision is None:
+            revision = self._get_hg_revision(self.local_path)
+
+        if revision is not None:
+            version = str(revision)
+            self.version = version
+
+        return version
+
+    def make_svn_version_py(self, delete=True):
+        """Appends a data function to the data_files list that will generate
+        __svn_version__.py file to the current package directory.
+
+        Generate package __svn_version__.py file from SVN revision number,
+        it will be removed after python exits but will be available
+        when sdist, etc commands are executed.
+
+        Notes
+        -----
+        If __svn_version__.py existed before, nothing is done.
+
+        This is
+        intended for working with source directories that are in an SVN
+        repository.
+        """
+        target = njoin(self.local_path, '__svn_version__.py')
+        revision = self._get_svn_revision(self.local_path)
+        if os.path.isfile(target) or revision is None:
+            return
+        else:
+            def generate_svn_version_py():
+                if not os.path.isfile(target):
+                    version = str(revision)
+                    self.info('Creating %s (version=%r)' % (target, version))
+                    f = open(target, 'w')
+                    f.write('version = %r\n' % (version))
+                    f.close()
+
+                import atexit
+                def rm_file(f=target,p=self.info):
+                    if delete:
+                        try: os.remove(f); p('removed '+f)
+                        except OSError: pass
+                        try: os.remove(f+'c'); p('removed '+f+'c')
+                        except OSError: pass
+
+                atexit.register(rm_file)
+
+                return target
+
+            self.add_data_files(('', generate_svn_version_py()))
+
+    def make_hg_version_py(self, delete=True):
+        """Appends a data function to the data_files list that will generate
+        __hg_version__.py file to the current package directory.
+
+        Generate package __hg_version__.py file from Mercurial revision,
+        it will be removed after python exits but will be available
+        when sdist, etc commands are executed.
+
+        Notes
+        -----
+        If __hg_version__.py existed before, nothing is done.
+
+        This is intended for working with source directories that are
+        in an Mercurial repository.
+        """
+        target = njoin(self.local_path, '__hg_version__.py')
+        revision = self._get_hg_revision(self.local_path)
+        if os.path.isfile(target) or revision is None:
+            return
+        else:
+            def generate_hg_version_py():
+                if not os.path.isfile(target):
+                    version = str(revision)
+                    self.info('Creating %s (version=%r)' % (target, version))
+                    f = open(target, 'w')
+                    f.write('version = %r\n' % (version))
+                    f.close()
+
+                import atexit
+                def rm_file(f=target,p=self.info):
+                    if delete:
+                        try: os.remove(f); p('removed '+f)
+                        except OSError: pass
+                        try: os.remove(f+'c'); p('removed '+f+'c')
+                        except OSError: pass
+
+                atexit.register(rm_file)
+
+                return target
+
+            self.add_data_files(('', generate_hg_version_py()))
+
+    def make_config_py(self,name='__config__'):
+        """Generate package __config__.py file containing system_info
+        information used during building the package.
+
+        This file is installed to the
+        package installation directory.
+
+        """
+        self.py_modules.append((self.name, name, generate_config_py))
+
+
+    def get_info(self,*names):
+        """Get resources information.
+
+        Return information (from system_info.get_info) for all of the names in
+        the argument list in a single dictionary.
+        """
+        from .system_info import get_info, dict_append
+        info_dict = {}
+        for a in names:
+            dict_append(info_dict,**get_info(a))
+        return info_dict
+
+
+def get_cmd(cmdname, _cache={}):
+    if cmdname not in _cache:
+        import distutils.core
+        dist = distutils.core._setup_distribution
+        if dist is None:
+            from distutils.errors import DistutilsInternalError
+            raise DistutilsInternalError(
+                  'setup distribution instance not initialized')
+        cmd = dist.get_command_obj(cmdname)
+        _cache[cmdname] = cmd
+    return _cache[cmdname]
+
+def get_numpy_include_dirs():
+    # numpy_include_dirs are set by numpy/core/setup.py, otherwise []
+    include_dirs = Configuration.numpy_include_dirs[:]
+    if not include_dirs:
+        import numpy
+        include_dirs = [ numpy.get_include() ]
+    # else running numpy/core/setup.py
+    return include_dirs
+
+def get_npy_pkg_dir():
+    """Return the path where to find the npy-pkg-config directory."""
+    # XXX: import here for bootstrapping reasons
+    import numpy
+    d = os.path.join(os.path.dirname(numpy.__file__),
+            'core', 'lib', 'npy-pkg-config')
+    return d
+
+def get_pkg_info(pkgname, dirs=None):
+    """
+    Return library info for the given package.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of additional directories where to look
+        for npy-pkg-config files. Those directories are searched prior to the
+        NumPy directory.
+
+    Returns
+    -------
+    pkginfo : class instance
+        The `LibraryInfo` instance containing the build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    Configuration.add_npy_pkg_config, Configuration.add_installed_library,
+    get_info
+
+    """
+    from numpy.distutils.npy_pkg_config import read_config
+
+    if dirs:
+        dirs.append(get_npy_pkg_dir())
+    else:
+        dirs = [get_npy_pkg_dir()]
+    return read_config(pkgname, dirs)
+
+def get_info(pkgname, dirs=None):
+    """
+    Return an info dict for a given C library.
+
+    The info dict contains the necessary options to use the C library.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of additional directories where to look
+        for npy-pkg-config files. Those directories are searched prior to the
+        NumPy directory.
+
+    Returns
+    -------
+    info : dict
+        The dictionary with build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    Configuration.add_npy_pkg_config, Configuration.add_installed_library,
+    get_pkg_info
+
+    Examples
+    --------
+    To get the necessary information for the npymath library from NumPy:
+
+    >>> npymath_info = np.distutils.misc_util.get_info('npymath')
+    >>> npymath_info                                    #doctest: +SKIP
+    {'define_macros': [], 'libraries': ['npymath'], 'library_dirs':
+    ['.../numpy/core/lib'], 'include_dirs': ['.../numpy/core/include']}
+
+    This info dict can then be used as input to a `Configuration` instance::
+
+      config.add_extension('foo', sources=['foo.c'], extra_info=npymath_info)
+
+    """
+    from numpy.distutils.npy_pkg_config import parse_flags
+    pkg_info = get_pkg_info(pkgname, dirs)
+
+    # Translate LibraryInfo instance into a build_info dict
+    info = parse_flags(pkg_info.cflags())
+    for k, v in parse_flags(pkg_info.libs()).items():
+        info[k].extend(v)
+
+    # add_extension extra_info argument is ANAL
+    info['define_macros'] = info['macros']
+    del info['macros']
+    del info['ignored']
+
+    return info
+
+def is_bootstrapping():
+    if sys.version_info[0] >= 3:
+        import builtins
+    else:
+        import __builtin__ as builtins
+
+    try:
+        builtins.__NUMPY_SETUP__
+        return True
+    except AttributeError:
+        return False
+        __NUMPY_SETUP__ = False
+
+
+#########################
+
+def default_config_dict(name = None, parent_name = None, local_path=None):
+    """Return a configuration dictionary for usage in
+    configuration() function defined in file setup_<name>.py.
+    """
+    import warnings
+    warnings.warn('Use Configuration(%r,%r,top_path=%r) instead of '\
+                  'deprecated default_config_dict(%r,%r,%r)'
+                  % (name, parent_name, local_path,
+                     name, parent_name, local_path,
+                     ))
+    c = Configuration(name, parent_name, local_path)
+    return c.todict()
+
+
+def dict_append(d, **kws):
+    for k, v in kws.items():
+        if k in d:
+            ov = d[k]
+            if isinstance(ov, str):
+                d[k] = v
+            else:
+                d[k].extend(v)
+        else:
+            d[k] = v
+
+def appendpath(prefix, path):
+    if os.path.sep != '/':
+        prefix = prefix.replace('/', os.path.sep)
+        path = path.replace('/', os.path.sep)
+    drive = ''
+    if os.path.isabs(path):
+        drive = os.path.splitdrive(prefix)[0]
+        absprefix = os.path.splitdrive(os.path.abspath(prefix))[1]
+        pathdrive, path = os.path.splitdrive(path)
+        d = os.path.commonprefix([absprefix, path])
+        if os.path.join(absprefix[:len(d)], absprefix[len(d):]) != absprefix \
+           or os.path.join(path[:len(d)], path[len(d):]) != path:
+            # Handle invalid paths
+            d = os.path.dirname(d)
+        subpath = path[len(d):]
+        if os.path.isabs(subpath):
+            subpath = subpath[1:]
+    else:
+        subpath = path
+    return os.path.normpath(njoin(drive + prefix, subpath))
+
+def generate_config_py(target):
+    """Generate config.py file containing system_info information
+    used during building the package.
+
+    Usage:
+        config['py_modules'].append((packagename, '__config__',generate_config_py))
+    """
+    from numpy.distutils.system_info import system_info
+    from distutils.dir_util import mkpath
+    mkpath(os.path.dirname(target))
+    f = open(target, 'w')
+    f.write('# This file is generated by %s\n' % (os.path.abspath(sys.argv[0])))
+    f.write('# It contains system_info results at the time of building this package.\n')
+    f.write('__all__ = ["get_info","show"]\n\n')
+    for k, i in system_info.saved_results.items():
+        f.write('%s=%r\n' % (k, i))
+    f.write(r'''
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
+def show():
+    for name,info_dict in globals().items():
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print(name + ":")
+        if not info_dict:
+            print("  NOT AVAILABLE")
+        for k,v in info_dict.items():
+            v = str(v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print("    %s = %s" % (k,v))
+    ''')
+
+    f.close()
+    return target
+
+def msvc_version(compiler):
+    """Return version major and minor of compiler instance if it is
+    MSVC, raise an exception otherwise."""
+    if not compiler.compiler_type == "msvc":
+        raise ValueError("Compiler instance is not msvc (%s)"\
+                         % compiler.compiler_type)
+    return compiler._MSVCCompiler__version
+
+if sys.version[:3] >= '2.5':
+    def get_build_architecture():
+        from distutils.msvccompiler import get_build_architecture
+        return get_build_architecture()
+else:
+    #copied from python 2.5.1 distutils/msvccompiler.py
+    def get_build_architecture():
+        """Return the processor architecture.
+
+        Possible results are "Intel", "Itanium", or "AMD64".
+        """
+        prefix = " bit ("
+        i = sys.version.find(prefix)
+        if i == -1:
+            return "Intel"
+        j = sys.version.find(")", i)
+        return sys.version[i+len(prefix):j]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
new file mode 100644
index 0000000000..c53f45531c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
@@ -0,0 +1,25 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import distutils.msvc9compiler
+from distutils.msvc9compiler import *
+
+
+class MSVCCompiler(distutils.msvc9compiler.MSVCCompiler):
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        distutils.msvc9compiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
+
+    def initialize(self, plat_name=None):
+        environ_lib = os.getenv('lib')
+        environ_include = os.getenv('include')
+        distutils.msvc9compiler.MSVCCompiler.initialize(self, plat_name)
+        if environ_lib is not None:
+            os.environ['lib'] = environ_lib + os.environ['lib']
+        if environ_include is not None:
+            os.environ['include'] = environ_include + os.environ['include']
+
+    def manifest_setup_ldargs(self, output_filename, build_temp, ld_args):
+        ld_args.append('/MANIFEST')
+        distutils.msvc9compiler.MSVCCompiler.manifest_setup_ldargs(self,
+                                                                   output_filename,
+                                                                   build_temp, ld_args)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
new file mode 100644
index 0000000000..9e0eb8e100
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
@@ -0,0 +1,26 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import distutils.msvccompiler
+from distutils.msvccompiler import *
+
+from .system_info import platform_bits
+
+
+class MSVCCompiler(distutils.msvccompiler.MSVCCompiler):
+    def __init__(self, verbose=0, dry_run=0, force=0):
+        distutils.msvccompiler.MSVCCompiler.__init__(self, verbose, dry_run, force)
+
+    def initialize(self, plat_name=None):
+        environ_lib = os.getenv('lib')
+        environ_include = os.getenv('include')
+        distutils.msvccompiler.MSVCCompiler.initialize(self)
+        if environ_lib is not None:
+            os.environ['lib'] = environ_lib + os.environ['lib']
+        if environ_include is not None:
+            os.environ['include'] = environ_include + os.environ['include']
+        if platform_bits == 32:
+            # msvc9 building for 32 bits requires SSE2 to work around a
+            # compiler bug.
+            self.compile_options += ['/arch:SSE2']
+            self.compile_options_debug += ['/arch:SSE2']
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
new file mode 100644
index 0000000000..fe64709ca2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
@@ -0,0 +1,450 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+import os
+
+if sys.version_info[0] < 3:
+    from ConfigParser import SafeConfigParser, NoOptionError
+else:
+    from configparser import ConfigParser, SafeConfigParser, NoOptionError
+
+__all__ = ['FormatError', 'PkgNotFound', 'LibraryInfo', 'VariableSet',
+        'read_config', 'parse_flags']
+
+_VAR = re.compile('\$\{([a-zA-Z0-9_-]+)\}')
+
+class FormatError(IOError):
+    """
+    Exception thrown when there is a problem parsing a configuration file.
+
+    """
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return self.msg
+
+class PkgNotFound(IOError):
+    """Exception raised when a package can not be located."""
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return self.msg
+
+def parse_flags(line):
+    """
+    Parse a line from a config file containing compile flags.
+
+    Parameters
+    ----------
+    line : str
+        A single line containing one or more compile flags.
+
+    Returns
+    -------
+    d : dict
+        Dictionary of parsed flags, split into relevant categories.
+        These categories are the keys of `d`:
+
+        * 'include_dirs'
+        * 'library_dirs'
+        * 'libraries'
+        * 'macros'
+        * 'ignored'
+
+    """
+    d = {'include_dirs': [], 'library_dirs': [], 'libraries': [],
+         'macros': [], 'ignored': []}
+
+    flags = (' ' + line).split(' -')
+    for flag in flags:
+        flag = '-' + flag
+        if len(flag) > 0:
+            if flag.startswith('-I'):
+                d['include_dirs'].append(flag[2:].strip())
+            elif flag.startswith('-L'):
+                d['library_dirs'].append(flag[2:].strip())
+            elif flag.startswith('-l'):
+                d['libraries'].append(flag[2:].strip())
+            elif flag.startswith('-D'):
+                d['macros'].append(flag[2:].strip())
+            else:
+                d['ignored'].append(flag)
+
+    return d
+
+def _escape_backslash(val):
+    return val.replace('\\', '\\\\')
+
+class LibraryInfo(object):
+    """
+    Object containing build information about a library.
+
+    Parameters
+    ----------
+    name : str
+        The library name.
+    description : str
+        Description of the library.
+    version : str
+        Version string.
+    sections : dict
+        The sections of the configuration file for the library. The keys are
+        the section headers, the values the text under each header.
+    vars : class instance
+        A `VariableSet` instance, which contains ``(name, value)`` pairs for
+        variables defined in the configuration file for the library.
+    requires : sequence, optional
+        The required libraries for the library to be installed.
+
+    Notes
+    -----
+    All input parameters (except "sections" which is a method) are available as
+    attributes of the same name.
+
+    """
+    def __init__(self, name, description, version, sections, vars, requires=None):
+        self.name = name
+        self.description = description
+        if requires:
+            self.requires = requires
+        else:
+            self.requires = []
+        self.version = version
+        self._sections = sections
+        self.vars = vars
+
+    def sections(self):
+        """
+        Return the section headers of the config file.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        keys : list of str
+            The list of section headers.
+
+        """
+        return list(self._sections.keys())
+
+    def cflags(self, section="default"):
+        val = self.vars.interpolate(self._sections[section]['cflags'])
+        return _escape_backslash(val)
+
+    def libs(self, section="default"):
+        val = self.vars.interpolate(self._sections[section]['libs'])
+        return _escape_backslash(val)
+
+    def __str__(self):
+        m = ['Name: %s' % self.name, 'Description: %s' % self.description]
+        if self.requires:
+            m.append('Requires:')
+        else:
+            m.append('Requires: %s' % ",".join(self.requires))
+        m.append('Version: %s' % self.version)
+
+        return "\n".join(m)
+
+class VariableSet(object):
+    """
+    Container object for the variables defined in a config file.
+
+    `VariableSet` can be used as a plain dictionary, with the variable names
+    as keys.
+
+    Parameters
+    ----------
+    d : dict
+        Dict of items in the "variables" section of the configuration file.
+
+    """
+    def __init__(self, d):
+        self._raw_data = dict([(k, v) for k, v in d.items()])
+
+        self._re = {}
+        self._re_sub = {}
+
+        self._init_parse()
+
+    def _init_parse(self):
+        for k, v in self._raw_data.items():
+            self._init_parse_var(k, v)
+
+    def _init_parse_var(self, name, value):
+        self._re[name] = re.compile(r'\$\{%s\}' % name)
+        self._re_sub[name] = value
+
+    def interpolate(self, value):
+        # Brute force: we keep interpolating until there is no '${var}' anymore
+        # or until interpolated string is equal to input string
+        def _interpolate(value):
+            for k in self._re.keys():
+                value = self._re[k].sub(self._re_sub[k], value)
+            return value
+        while _VAR.search(value):
+            nvalue = _interpolate(value)
+            if nvalue == value:
+                break
+            value = nvalue
+
+        return value
+
+    def variables(self):
+        """
+        Return the list of variable names.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        names : list of str
+            The names of all variables in the `VariableSet` instance.
+
+        """
+        return list(self._raw_data.keys())
+
+    # Emulate a dict to set/get variables values
+    def __getitem__(self, name):
+        return self._raw_data[name]
+
+    def __setitem__(self, name, value):
+        self._raw_data[name] = value
+        self._init_parse_var(name, value)
+
+def parse_meta(config):
+    if not config.has_section('meta'):
+        raise FormatError("No meta section found !")
+
+    d = {}
+    for name, value in config.items('meta'):
+        d[name] = value
+
+    for k in ['name', 'description', 'version']:
+        if not k in d:
+            raise FormatError("Option %s (section [meta]) is mandatory, "
+                "but not found" % k)
+
+    if not 'requires' in d:
+        d['requires'] = []
+
+    return d
+
+def parse_variables(config):
+    if not config.has_section('variables'):
+        raise FormatError("No variables section found !")
+
+    d = {}
+
+    for name, value in config.items("variables"):
+        d[name] = value
+
+    return VariableSet(d)
+
+def parse_sections(config):
+    return meta_d, r
+
+def pkg_to_filename(pkg_name):
+    return "%s.ini" % pkg_name
+
+def parse_config(filename, dirs=None):
+    if dirs:
+        filenames = [os.path.join(d, filename) for d in dirs]
+    else:
+        filenames = [filename]
+
+    if sys.version[:3] > '3.1':
+        # SafeConfigParser is deprecated in py-3.2 and renamed to ConfigParser
+        config = ConfigParser()
+    else:
+        config = SafeConfigParser()
+
+    n = config.read(filenames)
+    if not len(n) >= 1:
+        raise PkgNotFound("Could not find file(s) %s" % str(filenames))
+
+    # Parse meta and variables sections
+    meta = parse_meta(config)
+
+    vars = {}
+    if config.has_section('variables'):
+        for name, value in config.items("variables"):
+            vars[name] = _escape_backslash(value)
+
+    # Parse "normal" sections
+    secs = [s for s in config.sections() if not s in ['meta', 'variables']]
+    sections = {}
+
+    requires = {}
+    for s in secs:
+        d = {}
+        if config.has_option(s, "requires"):
+            requires[s] = config.get(s, 'requires')
+
+        for name, value in config.items(s):
+            d[name] = value
+        sections[s] = d
+
+    return meta, vars, sections, requires
+
+def _read_config_imp(filenames, dirs=None):
+    def _read_config(f):
+        meta, vars, sections, reqs = parse_config(f, dirs)
+        # recursively add sections and variables of required libraries
+        for rname, rvalue in reqs.items():
+            nmeta, nvars, nsections, nreqs = _read_config(pkg_to_filename(rvalue))
+
+            # Update var dict for variables not in 'top' config file
+            for k, v in nvars.items():
+                if not k in vars:
+                    vars[k] = v
+
+            # Update sec dict
+            for oname, ovalue in nsections[rname].items():
+                if ovalue:
+                    sections[rname][oname] += ' %s' % ovalue
+
+        return meta, vars, sections, reqs
+
+    meta, vars, sections, reqs = _read_config(filenames)
+
+    # FIXME: document this. If pkgname is defined in the variables section, and
+    # there is no pkgdir variable defined, pkgdir is automatically defined to
+    # the path of pkgname. This requires the package to be imported to work
+    if not 'pkgdir' in vars and "pkgname" in vars:
+        pkgname = vars["pkgname"]
+        if not pkgname in sys.modules:
+            raise ValueError("You should import %s to get information on %s" %
+                             (pkgname, meta["name"]))
+
+        mod = sys.modules[pkgname]
+        vars["pkgdir"] = _escape_backslash(os.path.dirname(mod.__file__))
+
+    return LibraryInfo(name=meta["name"], description=meta["description"],
+            version=meta["version"], sections=sections, vars=VariableSet(vars))
+
+# Trivial cache to cache LibraryInfo instances creation. To be really
+# efficient, the cache should be handled in read_config, since a same file can
+# be parsed many time outside LibraryInfo creation, but I doubt this will be a
+# problem in practice
+_CACHE = {}
+def read_config(pkgname, dirs=None):
+    """
+    Return library info for a package from its configuration file.
+
+    Parameters
+    ----------
+    pkgname : str
+        Name of the package (should match the name of the .ini file, without
+        the extension, e.g. foo for the file foo.ini).
+    dirs : sequence, optional
+        If given, should be a sequence of directories - usually including
+        the NumPy base directory - where to look for npy-pkg-config files.
+
+    Returns
+    -------
+    pkginfo : class instance
+        The `LibraryInfo` instance containing the build information.
+
+    Raises
+    ------
+    PkgNotFound
+        If the package is not found.
+
+    See Also
+    --------
+    misc_util.get_info, misc_util.get_pkg_info
+
+    Examples
+    --------
+    >>> npymath_info = np.distutils.npy_pkg_config.read_config('npymath')
+    >>> type(npymath_info)
+    <class 'numpy.distutils.npy_pkg_config.LibraryInfo'>
+    >>> print(npymath_info)
+    Name: npymath
+    Description: Portable, core math library implementing C99 standard
+    Requires:
+    Version: 0.1  #random
+
+    """
+    try:
+        return _CACHE[pkgname]
+    except KeyError:
+        v = _read_config_imp(pkg_to_filename(pkgname), dirs)
+        _CACHE[pkgname] = v
+        return v
+
+# TODO:
+#   - implements version comparison (modversion + atleast)
+
+# pkg-config simple emulator - useful for debugging, and maybe later to query
+# the system
+if __name__ == '__main__':
+    import sys
+    from optparse import OptionParser
+    import glob
+
+    parser = OptionParser()
+    parser.add_option("--cflags", dest="cflags", action="store_true",
+                      help="output all preprocessor and compiler flags")
+    parser.add_option("--libs", dest="libs", action="store_true",
+                      help="output all linker flags")
+    parser.add_option("--use-section", dest="section",
+                      help="use this section instead of default for options")
+    parser.add_option("--version", dest="version", action="store_true",
+                      help="output version")
+    parser.add_option("--atleast-version", dest="min_version",
+                      help="Minimal version")
+    parser.add_option("--list-all", dest="list_all", action="store_true",
+                      help="Minimal version")
+    parser.add_option("--define-variable", dest="define_variable",
+                      help="Replace variable with the given value")
+
+    (options, args) = parser.parse_args(sys.argv)
+
+    if len(args) < 2:
+        raise ValueError("Expect package name on the command line:")
+
+    if options.list_all:
+        files = glob.glob("*.ini")
+        for f in files:
+            info = read_config(f)
+            print("%s\t%s - %s" % (info.name, info.name, info.description))
+
+    pkg_name = args[1]
+    import os
+    d = os.environ.get('NPY_PKG_CONFIG_PATH')
+    if d:
+        info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.', d])
+    else:
+        info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.'])
+
+    if options.section:
+        section = options.section
+    else:
+        section = "default"
+
+    if options.define_variable:
+        m = re.search('([\S]+)=([\S]+)', options.define_variable)
+        if not m:
+            raise ValueError("--define-variable option should be of " \
+                             "the form --define-variable=foo=bar")
+        else:
+            name = m.group(1)
+            value = m.group(2)
+        info.vars[name] = value
+
+    if options.cflags:
+        print(info.cflags(section))
+    if options.libs:
+        print(info.libs(section))
+    if options.version:
+        print(info.version)
+    if options.min_version:
+        print(info.version >= options.min_version)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
new file mode 100644
index 0000000000..6ae19d16b1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
@@ -0,0 +1,19 @@
+# XXX: Handle setuptools ?
+from __future__ import division, absolute_import, print_function
+
+from distutils.core import Distribution
+
+# This class is used because we add new files (sconscripts, and so on) with the
+# scons command
+class NumpyDistribution(Distribution):
+    def __init__(self, attrs = None):
+        # A list of (sconscripts, pre_hook, post_hook, src, parent_names)
+        self.scons_data = []
+        # A list of installable libraries
+        self.installed_libraries = []
+        # A dict of pkg_config files to generate/install
+        self.installed_pkg_config = {}
+        Distribution.__init__(self, attrs)
+
+    def has_scons_scripts(self):
+        return bool(self.scons_data)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
new file mode 100644
index 0000000000..fc9872db34
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+from distutils.unixccompiler import UnixCCompiler
+
+class PathScaleCCompiler(UnixCCompiler):
+
+    """
+    PathScale compiler compatible with an gcc built Python.
+    """
+
+    compiler_type = 'pathcc'
+    cc_exe = 'pathcc'
+    cxx_exe = 'pathCC'
+
+    def __init__ (self, verbose=0, dry_run=0, force=0):
+        UnixCCompiler.__init__ (self, verbose, dry_run, force)
+        cc_compiler = self.cc_exe
+        cxx_compiler = self.cxx_exe
+        self.set_executables(compiler=cc_compiler,
+                             compiler_so=cc_compiler,
+                             compiler_cxx=cxx_compiler,
+                             linker_exe=cc_compiler,
+                             linker_so=cc_compiler + ' -shared')
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/setup.py
new file mode 100644
index 0000000000..2f12d42d91
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/setup.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('distutils', parent_package, top_path)
+    config.add_subpackage('command')
+    config.add_subpackage('fcompiler')
+    config.add_data_dir('tests')
+    config.add_data_files('site.cfg')
+    config.add_data_files('mingw/gfortran_vs2003_hack.c')
+    config.make_config_py()
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core      import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.py
new file mode 100644
index 0000000000..cd24185d26
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.py
@@ -0,0 +1,2405 @@
+#!/usr/bin/env python2
+"""
+This file defines a set of system_info classes for getting
+information about various resources (libraries, library directories,
+include directories, etc.) in the system. Currently, the following
+classes are available:
+
+  atlas_info
+  atlas_threads_info
+  atlas_blas_info
+  atlas_blas_threads_info
+  lapack_atlas_info
+  lapack_atlas_threads_info
+  atlas_3_10_info
+  atlas_3_10_threads_info
+  atlas_3_10_blas_info,
+  atlas_3_10_blas_threads_info,
+  lapack_atlas_3_10_info
+  lapack_atlas_3_10_threads_info
+  blas_info
+  lapack_info
+  openblas_info
+  blas_opt_info       # usage recommended
+  lapack_opt_info     # usage recommended
+  fftw_info,dfftw_info,sfftw_info
+  fftw_threads_info,dfftw_threads_info,sfftw_threads_info
+  djbfft_info
+  x11_info
+  lapack_src_info
+  blas_src_info
+  numpy_info
+  numarray_info
+  numpy_info
+  boost_python_info
+  agg2_info
+  wx_info
+  gdk_pixbuf_xlib_2_info
+  gdk_pixbuf_2_info
+  gdk_x11_2_info
+  gtkp_x11_2_info
+  gtkp_2_info
+  xft_info
+  freetype2_info
+  umfpack_info
+
+Usage:
+    info_dict = get_info(<name>)
+  where <name> is a string 'atlas','x11','fftw','lapack','blas',
+  'lapack_src', 'blas_src', etc. For a complete list of allowed names,
+  see the definition of get_info() function below.
+
+  Returned info_dict is a dictionary which is compatible with
+  distutils.setup keyword arguments. If info_dict == {}, then the
+  asked resource is not available (system_info could not find it).
+
+  Several *_info classes specify an environment variable to specify
+  the locations of software. When setting the corresponding environment
+  variable to 'None' then the software will be ignored, even when it
+  is available in system.
+
+Global parameters:
+  system_info.search_static_first - search static libraries (.a)
+             in precedence to shared ones (.so, .sl) if enabled.
+  system_info.verbosity - output the results to stdout if enabled.
+
+The file 'site.cfg' is looked for in
+
+1) Directory of main setup.py file being run.
+2) Home directory of user running the setup.py file as ~/.numpy-site.cfg
+3) System wide directory (location of this file...)
+
+The first one found is used to get system configuration options The
+format is that used by ConfigParser (i.e., Windows .INI style). The
+section ALL has options that are the default for each section. The
+available sections are fftw, atlas, and x11. Appropiate defaults are
+used if nothing is specified.
+
+The order of finding the locations of resources is the following:
+ 1. environment variable
+ 2. section in site.cfg
+ 3. ALL section in site.cfg
+Only the first complete match is returned.
+
+Example:
+----------
+[ALL]
+library_dirs = /usr/lib:/usr/local/lib:/opt/lib
+include_dirs = /usr/include:/usr/local/include:/opt/include
+src_dirs = /usr/local/src:/opt/src
+# search static libraries (.a) in preference to shared ones (.so)
+search_static_first = 0
+
+[fftw]
+fftw_libs = rfftw, fftw
+fftw_opt_libs = rfftw_threaded, fftw_threaded
+# if the above aren't found, look for {s,d}fftw_libs and {s,d}fftw_opt_libs
+
+[atlas]
+library_dirs = /usr/lib/3dnow:/usr/lib/3dnow/atlas
+# for overriding the names of the atlas libraries
+atlas_libs = lapack, f77blas, cblas, atlas
+
+[x11]
+library_dirs = /usr/X11R6/lib
+include_dirs = /usr/X11R6/include
+----------
+
+Authors:
+  Pearu Peterson <pearu@cens.ioc.ee>, February 2002
+  David M. Cooke <cookedm@physics.mcmaster.ca>, April 2002
+
+Copyright 2002 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) license.  See LICENSE.txt that came with
+this distribution for specifics.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import re
+import copy
+import warnings
+from glob import glob
+from functools import reduce
+if sys.version_info[0] < 3:
+    from ConfigParser import NoOptionError, ConfigParser
+else:
+    from configparser import NoOptionError, ConfigParser
+
+from distutils.errors import DistutilsError
+from distutils.dist import Distribution
+import distutils.sysconfig
+from distutils import log
+from distutils.util import get_platform
+
+from numpy.distutils.exec_command import \
+    find_executable, exec_command, get_pythonexe
+from numpy.distutils.misc_util import is_sequence, is_string, \
+                                      get_shared_lib_extension
+from numpy.distutils.command.config import config as cmd_config
+from numpy.distutils.compat import get_exception
+import distutils.ccompiler
+import tempfile
+import shutil
+
+
+# Determine number of bits
+import platform
+_bits = {'32bit': 32, '64bit': 64}
+platform_bits = _bits[platform.architecture()[0]]
+
+
+def libpaths(paths, bits):
+    """Return a list of library paths valid on 32 or 64 bit systems.
+
+    Inputs:
+      paths : sequence
+        A sequence of strings (typically paths)
+      bits : int
+        An integer, the only valid values are 32 or 64.  A ValueError exception
+      is raised otherwise.
+
+    Examples:
+
+    Consider a list of directories
+    >>> paths = ['/usr/X11R6/lib','/usr/X11/lib','/usr/lib']
+
+    For a 32-bit platform, this is already valid:
+    >>> np.distutils.system_info.libpaths(paths,32)
+    ['/usr/X11R6/lib', '/usr/X11/lib', '/usr/lib']
+
+    On 64 bits, we prepend the '64' postfix
+    >>> np.distutils.system_info.libpaths(paths,64)
+    ['/usr/X11R6/lib64', '/usr/X11R6/lib', '/usr/X11/lib64', '/usr/X11/lib',
+    '/usr/lib64', '/usr/lib']
+    """
+    if bits not in (32, 64):
+        raise ValueError("Invalid bit size in libpaths: 32 or 64 only")
+
+    # Handle 32bit case
+    if bits == 32:
+        return paths
+
+    # Handle 64bit case
+    out = []
+    for p in paths:
+        out.extend([p + '64', p])
+
+    return out
+
+
+if sys.platform == 'win32':
+    default_lib_dirs = ['C:\\',
+                        os.path.join(distutils.sysconfig.EXEC_PREFIX,
+                                     'libs')]
+    default_runtime_dirs = []
+    default_include_dirs = []
+    default_src_dirs = ['.']
+    default_x11_lib_dirs = []
+    default_x11_include_dirs = []
+else:
+    default_lib_dirs = libpaths(['/usr/local/lib', '/opt/lib', '/usr/lib',
+                                 '/opt/local/lib', '/sw/lib'], platform_bits)
+    default_runtime_dirs = []
+    default_include_dirs = ['/usr/local/include',
+                            '/opt/include', '/usr/include',
+                            # path of umfpack under macports
+                            '/opt/local/include/ufsparse',
+                            '/opt/local/include', '/sw/include',
+                            '/usr/include/suitesparse']
+    default_src_dirs = ['.', '/usr/local/src', '/opt/src', '/sw/src']
+
+    default_x11_lib_dirs = libpaths(['/usr/X11R6/lib', '/usr/X11/lib',
+                                     '/usr/lib'], platform_bits)
+    default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include',
+                                '/usr/include']
+
+    if os.path.exists('/usr/lib/X11'):
+        globbed_x11_dir = glob('/usr/lib/*/libX11.so')
+        if globbed_x11_dir:
+            x11_so_dir = os.path.split(globbed_x11_dir[0])[0]
+            default_x11_lib_dirs.extend([x11_so_dir, '/usr/lib/X11'])
+            default_x11_include_dirs.extend(['/usr/lib/X11/include',
+                                             '/usr/include/X11'])
+
+    import subprocess as sp
+    tmp = None
+    try:
+        # Explicitly open/close file to avoid ResourceWarning when
+        # tests are run in debug mode Python 3.
+        tmp = open(os.devnull, 'w')
+        p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE,
+                stderr=tmp)
+    except (OSError, DistutilsError):
+        # OSError if gcc is not installed, or SandboxViolation (DistutilsError
+        # subclass) if an old setuptools bug is triggered (see gh-3160).
+        pass
+    else:
+        triplet = str(p.communicate()[0].decode().strip())
+        if p.returncode == 0:
+            # gcc supports the "-print-multiarch" option
+            default_x11_lib_dirs += [os.path.join("/usr/lib/", triplet)]
+            default_lib_dirs += [os.path.join("/usr/lib/", triplet)]
+    finally:
+        if tmp is not None:
+            tmp.close()
+
+if os.path.join(sys.prefix, 'lib') not in default_lib_dirs:
+    default_lib_dirs.insert(0, os.path.join(sys.prefix, 'lib'))
+    default_include_dirs.append(os.path.join(sys.prefix, 'include'))
+    default_src_dirs.append(os.path.join(sys.prefix, 'src'))
+
+default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)]
+default_runtime_dirs = [_m for _m in default_runtime_dirs if os.path.isdir(_m)]
+default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)]
+default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)]
+
+so_ext = get_shared_lib_extension()
+
+
+def get_standard_file(fname):
+    """Returns a list of files named 'fname' from
+    1) System-wide directory (directory-location of this module)
+    2) Users HOME directory (os.environ['HOME'])
+    3) Local directory
+    """
+    # System-wide file
+    filenames = []
+    try:
+        f = __file__
+    except NameError:
+        f = sys.argv[0]
+    else:
+        sysfile = os.path.join(os.path.split(os.path.abspath(f))[0],
+                               fname)
+        if os.path.isfile(sysfile):
+            filenames.append(sysfile)
+
+    # Home directory
+    # And look for the user config file
+    try:
+        f = os.path.expanduser('~')
+    except KeyError:
+        pass
+    else:
+        user_file = os.path.join(f, fname)
+        if os.path.isfile(user_file):
+            filenames.append(user_file)
+
+    # Local file
+    if os.path.isfile(fname):
+        filenames.append(os.path.abspath(fname))
+
+    return filenames
+
+
+def get_info(name, notfound_action=0):
+    """
+    notfound_action:
+      0 - do nothing
+      1 - display warning message
+      2 - raise error
+    """
+    cl = {'atlas': atlas_info,  # use lapack_opt or blas_opt instead
+          'atlas_threads': atlas_threads_info,                # ditto
+          'atlas_blas': atlas_blas_info,
+          'atlas_blas_threads': atlas_blas_threads_info,
+          'lapack_atlas': lapack_atlas_info,  # use lapack_opt instead
+          'lapack_atlas_threads': lapack_atlas_threads_info,  # ditto
+          'atlas_3_10': atlas_3_10_info,  # use lapack_opt or blas_opt instead
+          'atlas_3_10_threads': atlas_3_10_threads_info,                # ditto
+          'atlas_3_10_blas': atlas_3_10_blas_info,
+          'atlas_3_10_blas_threads': atlas_3_10_blas_threads_info,
+          'lapack_atlas_3_10': lapack_atlas_3_10_info,  # use lapack_opt instead
+          'lapack_atlas_3_10_threads': lapack_atlas_3_10_threads_info,  # ditto
+          'mkl': mkl_info,
+          # openblas which may or may not have embedded lapack
+          'openblas': openblas_info,          # use blas_opt instead
+          # openblas with embedded lapack
+          'openblas_lapack': openblas_lapack_info, # use blas_opt instead
+          'lapack_mkl': lapack_mkl_info,      # use lapack_opt instead
+          'blas_mkl': blas_mkl_info,          # use blas_opt instead
+          'x11': x11_info,
+          'fft_opt': fft_opt_info,
+          'fftw': fftw_info,
+          'fftw2': fftw2_info,
+          'fftw3': fftw3_info,
+          'dfftw': dfftw_info,
+          'sfftw': sfftw_info,
+          'fftw_threads': fftw_threads_info,
+          'dfftw_threads': dfftw_threads_info,
+          'sfftw_threads': sfftw_threads_info,
+          'djbfft': djbfft_info,
+          'blas': blas_info,                  # use blas_opt instead
+          'lapack': lapack_info,              # use lapack_opt instead
+          'lapack_src': lapack_src_info,
+          'blas_src': blas_src_info,
+          'numpy': numpy_info,
+          'f2py': f2py_info,
+          'Numeric': Numeric_info,
+          'numeric': Numeric_info,
+          'numarray': numarray_info,
+          'numerix': numerix_info,
+          'lapack_opt': lapack_opt_info,
+          'blas_opt': blas_opt_info,
+          'boost_python': boost_python_info,
+          'agg2': agg2_info,
+          'wx': wx_info,
+          'gdk_pixbuf_xlib_2': gdk_pixbuf_xlib_2_info,
+          'gdk-pixbuf-xlib-2.0': gdk_pixbuf_xlib_2_info,
+          'gdk_pixbuf_2': gdk_pixbuf_2_info,
+          'gdk-pixbuf-2.0': gdk_pixbuf_2_info,
+          'gdk': gdk_info,
+          'gdk_2': gdk_2_info,
+          'gdk-2.0': gdk_2_info,
+          'gdk_x11_2': gdk_x11_2_info,
+          'gdk-x11-2.0': gdk_x11_2_info,
+          'gtkp_x11_2': gtkp_x11_2_info,
+          'gtk+-x11-2.0': gtkp_x11_2_info,
+          'gtkp_2': gtkp_2_info,
+          'gtk+-2.0': gtkp_2_info,
+          'xft': xft_info,
+          'freetype2': freetype2_info,
+          'umfpack': umfpack_info,
+          'amd': amd_info,
+          }.get(name.lower(), system_info)
+    return cl().get_info(notfound_action)
+
+
+class NotFoundError(DistutilsError):
+    """Some third-party program or library is not found."""
+
+
+class AtlasNotFoundError(NotFoundError):
+    """
+    Atlas (http://math-atlas.sourceforge.net/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [atlas]) or by setting
+    the ATLAS environment variable."""
+
+
+class LapackNotFoundError(NotFoundError):
+    """
+    Lapack (http://www.netlib.org/lapack/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [lapack]) or by setting
+    the LAPACK environment variable."""
+
+
+class LapackSrcNotFoundError(LapackNotFoundError):
+    """
+    Lapack (http://www.netlib.org/lapack/) sources not found.
+    Directories to search for the sources can be specified in the
+    numpy/distutils/site.cfg file (section [lapack_src]) or by setting
+    the LAPACK_SRC environment variable."""
+
+
+class BlasNotFoundError(NotFoundError):
+    """
+    Blas (http://www.netlib.org/blas/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [blas]) or by setting
+    the BLAS environment variable."""
+
+
+class BlasSrcNotFoundError(BlasNotFoundError):
+    """
+    Blas (http://www.netlib.org/blas/) sources not found.
+    Directories to search for the sources can be specified in the
+    numpy/distutils/site.cfg file (section [blas_src]) or by setting
+    the BLAS_SRC environment variable."""
+
+
+class FFTWNotFoundError(NotFoundError):
+    """
+    FFTW (http://www.fftw.org/) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [fftw]) or by setting
+    the FFTW environment variable."""
+
+
+class DJBFFTNotFoundError(NotFoundError):
+    """
+    DJBFFT (http://cr.yp.to/djbfft.html) libraries not found.
+    Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [djbfft]) or by setting
+    the DJBFFT environment variable."""
+
+
+class NumericNotFoundError(NotFoundError):
+    """
+    Numeric (http://www.numpy.org/) module not found.
+    Get it from above location, install it, and retry setup.py."""
+
+
+class X11NotFoundError(NotFoundError):
+    """X11 libraries not found."""
+
+
+class UmfpackNotFoundError(NotFoundError):
+    """
+    UMFPACK sparse solver (http://www.cise.ufl.edu/research/sparse/umfpack/)
+    not found. Directories to search for the libraries can be specified in the
+    numpy/distutils/site.cfg file (section [umfpack]) or by setting
+    the UMFPACK environment variable."""
+
+
+class system_info(object):
+
+    """ get_info() is the only public method. Don't use others.
+    """
+    section = 'ALL'
+    dir_env_var = None
+    search_static_first = 0  # XXX: disabled by default, may disappear in
+                            # future unless it is proved to be useful.
+    verbosity = 1
+    saved_results = {}
+
+    notfounderror = NotFoundError
+
+    def __init__(self,
+                  default_lib_dirs=default_lib_dirs,
+                  default_include_dirs=default_include_dirs,
+                  verbosity=1,
+                  ):
+        self.__class__.info = {}
+        self.local_prefixes = []
+        defaults = {'library_dirs': os.pathsep.join(default_lib_dirs),
+                    'include_dirs': os.pathsep.join(default_include_dirs),
+                    'runtime_library_dirs': os.pathsep.join(default_runtime_dirs),
+                    'rpath': '',
+                    'src_dirs': os.pathsep.join(default_src_dirs),
+                    'search_static_first': str(self.search_static_first),
+                    'extra_compile_args': '', 'extra_link_args': ''}
+        self.cp = ConfigParser(defaults)
+        self.files = []
+        self.files.extend(get_standard_file('.numpy-site.cfg'))
+        self.files.extend(get_standard_file('site.cfg'))
+        self.parse_config_files()
+        if self.section is not None:
+            self.search_static_first = self.cp.getboolean(
+                self.section, 'search_static_first')
+        assert isinstance(self.search_static_first, int)
+
+    def parse_config_files(self):
+        self.cp.read(self.files)
+        if not self.cp.has_section(self.section):
+            if self.section is not None:
+                self.cp.add_section(self.section)
+
+    def calc_libraries_info(self):
+        libs = self.get_libraries()
+        dirs = self.get_lib_dirs()
+        # The extensions use runtime_library_dirs
+        r_dirs = self.get_runtime_lib_dirs() 
+        # Intrinsic distutils use rpath, we simply append both entries
+        # as though they were one entry
+        r_dirs.extend(self.get_runtime_lib_dirs(key='rpath'))
+        info = {}
+        for lib in libs:
+            i = self.check_libs(dirs, [lib])
+            if i is not None:
+                dict_append(info, **i)
+            else:
+                log.info('Library %s was not found. Ignoring' % (lib))
+            i = self.check_libs(r_dirs, [lib])
+            if i is not None:
+                # Swap library keywords found to runtime_library_dirs
+                # the libraries are insisting on the user having defined
+                # them using the library_dirs, and not necessarily by
+                # runtime_library_dirs
+                del i['libraries']
+                i['runtime_library_dirs'] = i.pop('library_dirs')
+                dict_append(info, **i)
+            else:
+                log.info('Runtime library %s was not found. Ignoring' % (lib))
+        return info
+
+    def set_info(self, **info):
+        if info:
+            lib_info = self.calc_libraries_info()
+            dict_append(info, **lib_info)
+            # Update extra information
+            extra_info = self.calc_extra_info()
+            dict_append(info, **extra_info)
+        self.saved_results[self.__class__.__name__] = info
+
+    def has_info(self):
+        return self.__class__.__name__ in self.saved_results
+
+    def calc_extra_info(self):
+        """ Updates the information in the current information with
+        respect to these flags:
+          extra_compile_args
+          extra_link_args
+        """
+        info = {}
+        for key in ['extra_compile_args', 'extra_link_args']:
+            # Get values
+            opt = self.cp.get(self.section, key)
+            if opt:
+                tmp = {key : [opt]}
+                dict_append(info, **tmp)
+        return info
+
+    def get_info(self, notfound_action=0):
+        """ Return a dictonary with items that are compatible
+            with numpy.distutils.setup keyword arguments.
+        """
+        flag = 0
+        if not self.has_info():
+            flag = 1
+            log.info(self.__class__.__name__ + ':')
+            if hasattr(self, 'calc_info'):
+                self.calc_info()
+            if notfound_action:
+                if not self.has_info():
+                    if notfound_action == 1:
+                        warnings.warn(self.notfounderror.__doc__)
+                    elif notfound_action == 2:
+                        raise self.notfounderror(self.notfounderror.__doc__)
+                    else:
+                        raise ValueError(repr(notfound_action))
+
+            if not self.has_info():
+                log.info('  NOT AVAILABLE')
+                self.set_info()
+            else:
+                log.info('  FOUND:')
+
+        res = self.saved_results.get(self.__class__.__name__)
+        if self.verbosity > 0 and flag:
+            for k, v in res.items():
+                v = str(v)
+                if k in ['sources', 'libraries'] and len(v) > 270:
+                    v = v[:120] + '...\n...\n...' + v[-120:]
+                log.info('    %s = %s', k, v)
+            log.info('')
+
+        return copy.deepcopy(res)
+
+    def get_paths(self, section, key):
+        dirs = self.cp.get(section, key).split(os.pathsep)
+        env_var = self.dir_env_var
+        if env_var:
+            if is_sequence(env_var):
+                e0 = env_var[-1]
+                for e in env_var:
+                    if e in os.environ:
+                        e0 = e
+                        break
+                if not env_var[0] == e0:
+                    log.info('Setting %s=%s' % (env_var[0], e0))
+                env_var = e0
+        if env_var and env_var in os.environ:
+            d = os.environ[env_var]
+            if d == 'None':
+                log.info('Disabled %s: %s',
+                         self.__class__.__name__, '(%s is None)'
+                         % (env_var,))
+                return []
+            if os.path.isfile(d):
+                dirs = [os.path.dirname(d)] + dirs
+                l = getattr(self, '_lib_names', [])
+                if len(l) == 1:
+                    b = os.path.basename(d)
+                    b = os.path.splitext(b)[0]
+                    if b[:3] == 'lib':
+                        log.info('Replacing _lib_names[0]==%r with %r' \
+                              % (self._lib_names[0], b[3:]))
+                        self._lib_names[0] = b[3:]
+            else:
+                ds = d.split(os.pathsep)
+                ds2 = []
+                for d in ds:
+                    if os.path.isdir(d):
+                        ds2.append(d)
+                        for dd in ['include', 'lib']:
+                            d1 = os.path.join(d, dd)
+                            if os.path.isdir(d1):
+                                ds2.append(d1)
+                dirs = ds2 + dirs
+        default_dirs = self.cp.get(self.section, key).split(os.pathsep)
+        dirs.extend(default_dirs)
+        ret = []
+        for d in dirs:
+            if len(d) > 0 and not os.path.isdir(d):
+                warnings.warn('Specified path %s is invalid.' % d)
+                continue
+
+            if d not in ret:
+                ret.append(d)
+
+        log.debug('( %s = %s )', key, ':'.join(ret))
+        return ret
+
+    def get_lib_dirs(self, key='library_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_runtime_lib_dirs(self, key='runtime_library_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_include_dirs(self, key='include_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_src_dirs(self, key='src_dirs'):
+        return self.get_paths(self.section, key)
+
+    def get_libs(self, key, default):
+        try:
+            libs = self.cp.get(self.section, key)
+        except NoOptionError:
+            if not default:
+                return []
+            if is_string(default):
+                return [default]
+            return default
+        return [b for b in [a.strip() for a in libs.split(',')] if b]
+
+    def get_libraries(self, key='libraries'):
+        if hasattr(self, '_lib_names'):
+            return self.get_libs(key, default=self._lib_names)
+        else:
+            return self.get_libs(key, '')
+
+    def library_extensions(self):
+        static_exts = ['.a']
+        if sys.platform == 'win32':
+            static_exts.append('.lib')  # .lib is used by MSVC
+        if self.search_static_first:
+            exts = static_exts + [so_ext]
+        else:
+            exts = [so_ext] + static_exts
+        if sys.platform == 'cygwin':
+            exts.append('.dll.a')
+        if sys.platform == 'darwin':
+            exts.append('.dylib')
+        return exts
+
+    def check_libs(self, lib_dirs, libs, opt_libs=[]):
+        """If static or shared libraries are available then return
+        their info dictionary.
+
+        Checks for all libraries as shared libraries first, then
+        static (or vice versa if self.search_static_first is True).
+        """
+        exts = self.library_extensions()
+        info = None
+        for ext in exts:
+            info = self._check_libs(lib_dirs, libs, opt_libs, [ext])
+            if info is not None:
+                break
+        if not info:
+            log.info('  libraries %s not found in %s', ','.join(libs),
+                     lib_dirs)
+        return info
+
+    def check_libs2(self, lib_dirs, libs, opt_libs=[]):
+        """If static or shared libraries are available then return
+        their info dictionary.
+
+        Checks each library for shared or static.
+        """
+        exts = self.library_extensions()
+        info = self._check_libs(lib_dirs, libs, opt_libs, exts)
+        if not info:
+            log.info('  libraries %s not found in %s', ','.join(libs),
+                     lib_dirs)
+        return info
+
+    def _lib_list(self, lib_dir, libs, exts):
+        assert is_string(lib_dir)
+        liblist = []
+        # under windows first try without 'lib' prefix
+        if sys.platform == 'win32':
+            lib_prefixes = ['', 'lib']
+        else:
+            lib_prefixes = ['lib']
+        # for each library name, see if we can find a file for it.
+        for l in libs:
+            for ext in exts:
+                for prefix in lib_prefixes:
+                    p = self.combine_paths(lib_dir, prefix + l + ext)
+                    if p:
+                        break
+                if p:
+                    assert len(p) == 1
+                    # ??? splitext on p[0] would do this for cygwin
+                    # doesn't seem correct
+                    if ext == '.dll.a':
+                        l += '.dll'
+                    liblist.append(l)
+                    break
+        return liblist
+
+    def _check_libs(self, lib_dirs, libs, opt_libs, exts):
+        """Find mandatory and optional libs in expected paths.
+
+        Missing optional libraries are silently forgotten.
+        """
+        # First, try to find the mandatory libraries
+        if is_sequence(lib_dirs):
+            found_libs, found_dirs = [], []
+            for dir_ in lib_dirs:
+                found_libs1 = self._lib_list(dir_, libs, exts)
+                # It's possible that we'll find the same library in multiple
+                # directories. It's also possible that we'll find some
+                # libraries on in directory, and some in another. So the
+                # obvious thing would be to use a set instead of a list, but I
+                # don't know if preserving order matters (does it?).
+                for found_lib in found_libs1:
+                    if found_lib not in found_libs:
+                        found_libs.append(found_lib)
+                        if dir_ not in found_dirs:
+                            found_dirs.append(dir_)
+        else:
+            found_libs = self._lib_list(lib_dirs, libs, exts)
+            found_dirs = [lib_dirs]
+        if len(found_libs) > 0 and len(found_libs) == len(libs):
+            info = {'libraries': found_libs, 'library_dirs': found_dirs}
+            # Now, check for optional libraries
+            if is_sequence(lib_dirs):
+                for dir_ in lib_dirs:
+                    opt_found_libs = self._lib_list(dir_, opt_libs, exts)
+                    if opt_found_libs:
+                        if dir_ not in found_dirs:
+                            found_dirs.extend(dir_)
+                        found_libs.extend(opt_found_libs)
+            else:
+                opt_found_libs = self._lib_list(lib_dirs, opt_libs, exts)
+                if opt_found_libs:
+                    found_libs.extend(opt_found_libs)
+            return info
+        else:
+            return None
+
+    def combine_paths(self, *args):
+        """Return a list of existing paths composed by all combinations
+        of items from the arguments.
+        """
+        return combine_paths(*args, **{'verbosity': self.verbosity})
+
+
+class fft_opt_info(system_info):
+
+    def calc_info(self):
+        info = {}
+        fftw_info = get_info('fftw3') or get_info('fftw2') or get_info('dfftw')
+        djbfft_info = get_info('djbfft')
+        if fftw_info:
+            dict_append(info, **fftw_info)
+            if djbfft_info:
+                dict_append(info, **djbfft_info)
+            self.set_info(**info)
+            return
+
+
+class fftw_info(system_info):
+    #variables to override
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw3',
+                    'libs':['fftw3'],
+                    'includes':['fftw3.h'],
+                    'macros':[('SCIPY_FFTW3_H', None)]},
+                  {'name':'fftw2',
+                    'libs':['rfftw', 'fftw'],
+                    'includes':['fftw.h', 'rfftw.h'],
+                    'macros':[('SCIPY_FFTW_H', None)]}]
+
+    def calc_ver_info(self, ver_param):
+        """Returns True on successful version detection, else False"""
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        incl_dir = None
+        libs = self.get_libs(self.section + '_libs', ver_param['libs'])
+        info = self.check_libs(lib_dirs, libs)
+        if info is not None:
+            flag = 0
+            for d in incl_dirs:
+                if len(self.combine_paths(d, ver_param['includes'])) \
+                   == len(ver_param['includes']):
+                    dict_append(info, include_dirs=[d])
+                    flag = 1
+                    incl_dirs = [d]
+                    break
+            if flag:
+                dict_append(info, define_macros=ver_param['macros'])
+            else:
+                info = None
+        if info is not None:
+            self.set_info(**info)
+            return True
+        else:
+            log.info('  %s not found' % (ver_param['name']))
+            return False
+
+    def calc_info(self):
+        for i in self.ver_info:
+            if self.calc_ver_info(i):
+                break
+
+
+class fftw2_info(fftw_info):
+    #variables to override
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw2',
+                    'libs':['rfftw', 'fftw'],
+                    'includes':['fftw.h', 'rfftw.h'],
+                    'macros':[('SCIPY_FFTW_H', None)]}
+                  ]
+
+
+class fftw3_info(fftw_info):
+    #variables to override
+    section = 'fftw3'
+    dir_env_var = 'FFTW3'
+    notfounderror = FFTWNotFoundError
+    ver_info = [{'name':'fftw3',
+                    'libs':['fftw3'],
+                    'includes':['fftw3.h'],
+                    'macros':[('SCIPY_FFTW3_H', None)]},
+                  ]
+
+
+class dfftw_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'dfftw',
+                    'libs':['drfftw', 'dfftw'],
+                    'includes':['dfftw.h', 'drfftw.h'],
+                    'macros':[('SCIPY_DFFTW_H', None)]}]
+
+
+class sfftw_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'sfftw',
+                    'libs':['srfftw', 'sfftw'],
+                    'includes':['sfftw.h', 'srfftw.h'],
+                    'macros':[('SCIPY_SFFTW_H', None)]}]
+
+
+class fftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'fftw threads',
+                    'libs':['rfftw_threads', 'fftw_threads'],
+                    'includes':['fftw_threads.h', 'rfftw_threads.h'],
+                    'macros':[('SCIPY_FFTW_THREADS_H', None)]}]
+
+
+class dfftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'dfftw threads',
+                    'libs':['drfftw_threads', 'dfftw_threads'],
+                    'includes':['dfftw_threads.h', 'drfftw_threads.h'],
+                    'macros':[('SCIPY_DFFTW_THREADS_H', None)]}]
+
+
+class sfftw_threads_info(fftw_info):
+    section = 'fftw'
+    dir_env_var = 'FFTW'
+    ver_info = [{'name':'sfftw threads',
+                    'libs':['srfftw_threads', 'sfftw_threads'],
+                    'includes':['sfftw_threads.h', 'srfftw_threads.h'],
+                    'macros':[('SCIPY_SFFTW_THREADS_H', None)]}]
+
+
+class djbfft_info(system_info):
+    section = 'djbfft'
+    dir_env_var = 'DJBFFT'
+    notfounderror = DJBFFTNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend(self.combine_paths(d, ['djbfft']) + [d])
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        info = None
+        for d in lib_dirs:
+            p = self.combine_paths(d, ['djbfft.a'])
+            if p:
+                info = {'extra_objects': p}
+                break
+            p = self.combine_paths(d, ['libdjbfft.a', 'libdjbfft' + so_ext])
+            if p:
+                info = {'libraries': ['djbfft'], 'library_dirs': [d]}
+                break
+        if info is None:
+            return
+        for d in incl_dirs:
+            if len(self.combine_paths(d, ['fftc8.h', 'fftfreq.h'])) == 2:
+                dict_append(info, include_dirs=[d],
+                            define_macros=[('SCIPY_DJBFFT_H', None)])
+                self.set_info(**info)
+                return
+        return
+
+
+class mkl_info(system_info):
+    section = 'mkl'
+    dir_env_var = 'MKL'
+    _lib_mkl = ['mkl', 'vml', 'guide']
+
+    def get_mkl_rootdir(self):
+        mklroot = os.environ.get('MKLROOT', None)
+        if mklroot is not None:
+            return mklroot
+        paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep)
+        ld_so_conf = '/etc/ld.so.conf'
+        if os.path.isfile(ld_so_conf):
+            for d in open(ld_so_conf, 'r'):
+                d = d.strip()
+                if d:
+                    paths.append(d)
+        intel_mkl_dirs = []
+        for path in paths:
+            path_atoms = path.split(os.sep)
+            for m in path_atoms:
+                if m.startswith('mkl'):
+                    d = os.sep.join(path_atoms[:path_atoms.index(m) + 2])
+                    intel_mkl_dirs.append(d)
+                    break
+        for d in paths:
+            dirs = glob(os.path.join(d, 'mkl', '*'))
+            dirs += glob(os.path.join(d, 'mkl*'))
+            for d in dirs:
+                if os.path.isdir(os.path.join(d, 'lib')):
+                    return d
+        return None
+
+    def __init__(self):
+        mklroot = self.get_mkl_rootdir()
+        if mklroot is None:
+            system_info.__init__(self)
+        else:
+            from .cpuinfo import cpu
+            l = 'mkl'  # use shared library
+            if cpu.is_Itanium():
+                plt = '64'
+            elif cpu.is_Xeon():
+                plt = 'intel64'
+            else:
+                plt = '32'
+            if l not in self._lib_mkl:
+                self._lib_mkl.insert(0, l)
+            system_info.__init__(
+                self,
+                default_lib_dirs=[os.path.join(mklroot, 'lib', plt)],
+                default_include_dirs=[os.path.join(mklroot, 'include')])
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        incl_dirs = self.get_include_dirs()
+        mkl_libs = self.get_libs('mkl_libs', self._lib_mkl)
+        info = self.check_libs2(lib_dirs, mkl_libs)
+        if info is None:
+            return
+        dict_append(info,
+                    define_macros=[('SCIPY_MKL_H', None),
+                                   ('HAVE_CBLAS', None)],
+                    include_dirs=incl_dirs)
+        if sys.platform == 'win32':
+            pass  # win32 has no pthread library
+        else:
+            dict_append(info, libraries=['pthread'])
+        self.set_info(**info)
+
+
+class lapack_mkl_info(mkl_info):
+
+    def calc_info(self):
+        mkl = get_info('mkl')
+        if not mkl:
+            return
+        if sys.platform == 'win32':
+            lapack_libs = self.get_libs('lapack_libs', ['mkl_lapack'])
+        else:
+            lapack_libs = self.get_libs('lapack_libs',
+                                        ['mkl_lapack32', 'mkl_lapack64'])
+
+        info = {'libraries': lapack_libs}
+        dict_append(info, **mkl)
+        self.set_info(**info)
+
+
+class blas_mkl_info(mkl_info):
+    pass
+
+
+class atlas_info(system_info):
+    section = 'atlas'
+    dir_env_var = 'ATLAS'
+    _lib_names = ['f77blas', 'cblas']
+    if sys.platform[:7] == 'freebsd':
+        _lib_atlas = ['atlas_r']
+        _lib_lapack = ['alapack_r']
+    else:
+        _lib_atlas = ['atlas']
+        _lib_lapack = ['lapack']
+
+    notfounderror = AtlasNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend(self.combine_paths(d, ['atlas*', 'ATLAS*',
+                                         'sse', '3dnow', 'sse2']) + [d])
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names + self._lib_atlas)
+        lapack_libs = self.get_libs('lapack_libs', self._lib_lapack)
+        atlas = None
+        lapack = None
+        atlas_1 = None
+        for d in lib_dirs:
+            atlas = self.check_libs2(d, atlas_libs, [])
+            lapack_atlas = self.check_libs2(d, ['lapack_atlas'], [])
+            if atlas is not None:
+                lib_dirs2 = [d] + self.combine_paths(d, ['atlas*', 'ATLAS*'])
+                lapack = self.check_libs2(lib_dirs2, lapack_libs, [])
+                if lapack is not None:
+                    break
+            if atlas:
+                atlas_1 = atlas
+        log.info(self.__class__)
+        if atlas is None:
+            atlas = atlas_1
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        if lapack is not None:
+            dict_append(info, **lapack)
+            dict_append(info, **atlas)
+        elif 'lapack_atlas' in atlas['libraries']:
+            dict_append(info, **atlas)
+            dict_append(info,
+                        define_macros=[('ATLAS_WITH_LAPACK_ATLAS', None)])
+            self.set_info(**info)
+            return
+        else:
+            dict_append(info, **atlas)
+            dict_append(info, define_macros=[('ATLAS_WITHOUT_LAPACK', None)])
+            message = """
+*********************************************************************
+    Could not find lapack library within the ATLAS installation.
+*********************************************************************
+"""
+            warnings.warn(message)
+            self.set_info(**info)
+            return
+
+        # Check if lapack library is complete, only warn if it is not.
+        lapack_dir = lapack['library_dirs'][0]
+        lapack_name = lapack['libraries'][0]
+        lapack_lib = None
+        lib_prefixes = ['lib']
+        if sys.platform == 'win32':
+            lib_prefixes.append('')
+        for e in self.library_extensions():
+            for prefix in lib_prefixes:
+                fn = os.path.join(lapack_dir, prefix + lapack_name + e)
+                if os.path.exists(fn):
+                    lapack_lib = fn
+                    break
+            if lapack_lib:
+                break
+        if lapack_lib is not None:
+            sz = os.stat(lapack_lib)[6]
+            if sz <= 4000 * 1024:
+                message = """
+*********************************************************************
+    Lapack library (from ATLAS) is probably incomplete:
+      size of %s is %sk (expected >4000k)
+
+    Follow the instructions in the KNOWN PROBLEMS section of the file
+    numpy/INSTALL.txt.
+*********************************************************************
+""" % (lapack_lib, sz / 1024)
+                warnings.warn(message)
+            else:
+                info['language'] = 'f77'
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(info, **atlas_extra_info)
+
+        self.set_info(**info)
+
+
+class atlas_blas_info(atlas_info):
+    _lib_names = ['f77blas', 'cblas']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names + self._lib_atlas)
+        atlas = self.check_libs2(lib_dirs, atlas_libs, [])
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(atlas, **atlas_extra_info)
+
+        dict_append(info, **atlas)
+
+        self.set_info(**info)
+        return
+
+
+class atlas_threads_info(atlas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['ptf77blas', 'ptcblas']
+
+
+class atlas_blas_threads_info(atlas_blas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['ptf77blas', 'ptcblas']
+
+
+class lapack_atlas_info(atlas_info):
+    _lib_names = ['lapack_atlas'] + atlas_info._lib_names
+
+
+class lapack_atlas_threads_info(atlas_threads_info):
+    _lib_names = ['lapack_atlas'] + atlas_threads_info._lib_names
+
+
+class atlas_3_10_info(atlas_info):
+    _lib_names = ['satlas']
+    _lib_atlas = _lib_names
+    _lib_lapack = _lib_names
+
+
+class atlas_3_10_blas_info(atlas_3_10_info):
+    _lib_names = ['satlas']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        info = {}
+        atlas_libs = self.get_libs('atlas_libs',
+                                   self._lib_names)
+        atlas = self.check_libs2(lib_dirs, atlas_libs, [])
+        if atlas is None:
+            return
+        include_dirs = self.get_include_dirs()
+        h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
+        h = h[0]
+        if h:
+            h = os.path.dirname(h)
+            dict_append(info, include_dirs=[h])
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+
+        atlas_version, atlas_extra_info = get_atlas_version(**atlas)
+        dict_append(atlas, **atlas_extra_info)
+
+        dict_append(info, **atlas)
+
+        self.set_info(**info)
+        return
+
+
+class atlas_3_10_threads_info(atlas_3_10_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['tatlas']
+    _lib_atlas = _lib_names
+    _lib_lapack = _lib_names
+
+
+class atlas_3_10_blas_threads_info(atlas_3_10_blas_info):
+    dir_env_var = ['PTATLAS', 'ATLAS']
+    _lib_names = ['tatlas']
+
+
+class lapack_atlas_3_10_info(atlas_3_10_info):
+    pass
+
+
+class lapack_atlas_3_10_threads_info(atlas_3_10_threads_info):
+    pass
+
+
+class lapack_info(system_info):
+    section = 'lapack'
+    dir_env_var = 'LAPACK'
+    _lib_names = ['lapack']
+    notfounderror = LapackNotFoundError
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        lapack_libs = self.get_libs('lapack_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, lapack_libs, [])
+        if info is None:
+            return
+        info['language'] = 'f77'
+        self.set_info(**info)
+
+
+class lapack_src_info(system_info):
+    section = 'lapack_src'
+    dir_env_var = 'LAPACK_SRC'
+    notfounderror = LapackSrcNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['LAPACK*/SRC', 'SRC']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'dgesv.f')):
+                src_dir = d
+                break
+        if not src_dir:
+            #XXX: Get sources from netlib. May be ask first.
+            return
+        # The following is extracted from LAPACK-3.0/SRC/Makefile.
+        # Added missing names from lapack-lite-3.1.1/SRC/Makefile
+        # while keeping removed names for Lapack-3.0 compatibility.
+        allaux = '''
+        ilaenv ieeeck lsame lsamen xerbla
+        iparmq
+        '''  # *.f
+        laux = '''
+        bdsdc bdsqr disna labad lacpy ladiv lae2 laebz laed0 laed1
+        laed2 laed3 laed4 laed5 laed6 laed7 laed8 laed9 laeda laev2
+        lagtf lagts lamch lamrg lanst lapy2 lapy3 larnv larrb larre
+        larrf lartg laruv las2 lascl lasd0 lasd1 lasd2 lasd3 lasd4
+        lasd5 lasd6 lasd7 lasd8 lasd9 lasda lasdq lasdt laset lasq1
+        lasq2 lasq3 lasq4 lasq5 lasq6 lasr lasrt lassq lasv2 pttrf
+        stebz stedc steqr sterf
+
+        larra larrc larrd larr larrk larrj larrr laneg laisnan isnan
+        lazq3 lazq4
+        '''  # [s|d]*.f
+        lasrc = '''
+        gbbrd gbcon gbequ gbrfs gbsv gbsvx gbtf2 gbtrf gbtrs gebak
+        gebal gebd2 gebrd gecon geequ gees geesx geev geevx gegs gegv
+        gehd2 gehrd gelq2 gelqf gels gelsd gelss gelsx gelsy geql2
+        geqlf geqp3 geqpf geqr2 geqrf gerfs gerq2 gerqf gesc2 gesdd
+        gesv gesvd gesvx getc2 getf2 getrf getri getrs ggbak ggbal
+        gges ggesx ggev ggevx ggglm gghrd gglse ggqrf ggrqf ggsvd
+        ggsvp gtcon gtrfs gtsv gtsvx gttrf gttrs gtts2 hgeqz hsein
+        hseqr labrd lacon laein lags2 lagtm lahqr lahrd laic1 lals0
+        lalsa lalsd langb lange langt lanhs lansb lansp lansy lantb
+        lantp lantr lapll lapmt laqgb laqge laqp2 laqps laqsb laqsp
+        laqsy lar1v lar2v larf larfb larfg larft larfx largv larrv
+        lartv larz larzb larzt laswp lasyf latbs latdf latps latrd
+        latrs latrz latzm lauu2 lauum pbcon pbequ pbrfs pbstf pbsv
+        pbsvx pbtf2 pbtrf pbtrs pocon poequ porfs posv posvx potf2
+        potrf potri potrs ppcon ppequ pprfs ppsv ppsvx pptrf pptri
+        pptrs ptcon pteqr ptrfs ptsv ptsvx pttrs ptts2 spcon sprfs
+        spsv spsvx sptrf sptri sptrs stegr stein sycon syrfs sysv
+        sysvx sytf2 sytrf sytri sytrs tbcon tbrfs tbtrs tgevc tgex2
+        tgexc tgsen tgsja tgsna tgsy2 tgsyl tpcon tprfs tptri tptrs
+        trcon trevc trexc trrfs trsen trsna trsyl trti2 trtri trtrs
+        tzrqf tzrzf
+
+        lacn2 lahr2 stemr laqr0 laqr1 laqr2 laqr3 laqr4 laqr5
+        '''  # [s|c|d|z]*.f
+        sd_lasrc = '''
+        laexc lag2 lagv2 laln2 lanv2 laqtr lasy2 opgtr opmtr org2l
+        org2r orgbr orghr orgl2 orglq orgql orgqr orgr2 orgrq orgtr
+        orm2l orm2r ormbr ormhr orml2 ormlq ormql ormqr ormr2 ormr3
+        ormrq ormrz ormtr rscl sbev sbevd sbevx sbgst sbgv sbgvd sbgvx
+        sbtrd spev spevd spevx spgst spgv spgvd spgvx sptrd stev stevd
+        stevr stevx syev syevd syevr syevx sygs2 sygst sygv sygvd
+        sygvx sytd2 sytrd
+        '''  # [s|d]*.f
+        cz_lasrc = '''
+        bdsqr hbev hbevd hbevx hbgst hbgv hbgvd hbgvx hbtrd hecon heev
+        heevd heevr heevx hegs2 hegst hegv hegvd hegvx herfs hesv
+        hesvx hetd2 hetf2 hetrd hetrf hetri hetrs hpcon hpev hpevd
+        hpevx hpgst hpgv hpgvd hpgvx hprfs hpsv hpsvx hptrd hptrf
+        hptri hptrs lacgv lacp2 lacpy lacrm lacrt ladiv laed0 laed7
+        laed8 laesy laev2 lahef lanhb lanhe lanhp lanht laqhb laqhe
+        laqhp larcm larnv lartg lascl laset lasr lassq pttrf rot spmv
+        spr stedc steqr symv syr ung2l ung2r ungbr unghr ungl2 unglq
+        ungql ungqr ungr2 ungrq ungtr unm2l unm2r unmbr unmhr unml2
+        unmlq unmql unmqr unmr2 unmr3 unmrq unmrz unmtr upgtr upmtr
+        '''  # [c|z]*.f
+        #######
+        sclaux = laux + ' econd '                  # s*.f
+        dzlaux = laux + ' secnd '                  # d*.f
+        slasrc = lasrc + sd_lasrc                  # s*.f
+        dlasrc = lasrc + sd_lasrc                  # d*.f
+        clasrc = lasrc + cz_lasrc + ' srot srscl '  # c*.f
+        zlasrc = lasrc + cz_lasrc + ' drot drscl '  # z*.f
+        oclasrc = ' icmax1 scsum1 '                # *.f
+        ozlasrc = ' izmax1 dzsum1 '                # *.f
+        sources = ['s%s.f' % f for f in (sclaux + slasrc).split()] \
+                  + ['d%s.f' % f for f in (dzlaux + dlasrc).split()] \
+                  + ['c%s.f' % f for f in (clasrc).split()] \
+                  + ['z%s.f' % f for f in (zlasrc).split()] \
+                  + ['%s.f' % f for f in (allaux + oclasrc + ozlasrc).split()]
+        sources = [os.path.join(src_dir, f) for f in sources]
+        # Lapack 3.1:
+        src_dir2 = os.path.join(src_dir, '..', 'INSTALL')
+        sources += [os.path.join(src_dir2, p + 'lamch.f') for p in 'sdcz']
+        # Lapack 3.2.1:
+        sources += [os.path.join(src_dir, p + 'larfp.f') for p in 'sdcz']
+        sources += [os.path.join(src_dir, 'ila' + p + 'lr.f') for p in 'sdcz']
+        sources += [os.path.join(src_dir, 'ila' + p + 'lc.f') for p in 'sdcz']
+        # Should we check here actual existence of source files?
+        # Yes, the file listing is different between 3.0 and 3.1
+        # versions.
+        sources = [f for f in sources if os.path.isfile(f)]
+        info = {'sources': sources, 'language': 'f77'}
+        self.set_info(**info)
+
+atlas_version_c_text = r'''
+/* This file is generated from numpy/distutils/system_info.py */
+void ATL_buildinfo(void);
+int main(void) {
+  ATL_buildinfo();
+  return 0;
+}
+'''
+
+_cached_atlas_version = {}
+
+
+def get_atlas_version(**config):
+    libraries = config.get('libraries', [])
+    library_dirs = config.get('library_dirs', [])
+    key = (tuple(libraries), tuple(library_dirs))
+    if key in _cached_atlas_version:
+        return _cached_atlas_version[key]
+    c = cmd_config(Distribution())
+    atlas_version = None
+    info = {}
+    try:
+        s, o = c.get_output(atlas_version_c_text,
+                            libraries=libraries, library_dirs=library_dirs,
+                            use_tee=(system_info.verbosity > 0))
+        if s and re.search(r'undefined reference to `_gfortran', o, re.M):
+            s, o = c.get_output(atlas_version_c_text,
+                                libraries=libraries + ['gfortran'],
+                                library_dirs=library_dirs,
+                                use_tee=(system_info.verbosity > 0))
+            if not s:
+                warnings.warn("""
+*****************************************************
+Linkage with ATLAS requires gfortran. Use
+
+  python setup.py config_fc --fcompiler=gnu95 ...
+
+when building extension libraries that use ATLAS.
+Make sure that -lgfortran is used for C++ extensions.
+*****************************************************
+""")
+                dict_append(info, language='f90',
+                            define_macros=[('ATLAS_REQUIRES_GFORTRAN', None)])
+    except Exception:  # failed to get version from file -- maybe on Windows
+        # look at directory name
+        for o in library_dirs:
+            m = re.search(r'ATLAS_(?P<version>\d+[.]\d+[.]\d+)_', o)
+            if m:
+                atlas_version = m.group('version')
+            if atlas_version is not None:
+                break
+
+        # final choice --- look at ATLAS_VERSION environment
+        #   variable
+        if atlas_version is None:
+            atlas_version = os.environ.get('ATLAS_VERSION', None)
+        if atlas_version:
+            dict_append(info, define_macros=[(
+                'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
+            ])
+        else:
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', -1)])
+        return atlas_version or '?.?.?', info
+
+    if not s:
+        m = re.search(r'ATLAS version (?P<version>\d+[.]\d+[.]\d+)', o)
+        if m:
+            atlas_version = m.group('version')
+    if atlas_version is None:
+        if re.search(r'undefined symbol: ATL_buildinfo', o, re.M):
+            atlas_version = '3.2.1_pre3.3.6'
+        else:
+            log.info('Status: %d', s)
+            log.info('Output: %s', o)
+
+    if atlas_version == '3.2.1_pre3.3.6':
+        dict_append(info, define_macros=[('NO_ATLAS_INFO', -2)])
+    else:
+        dict_append(info, define_macros=[(
+            'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
+        ])
+    result = _cached_atlas_version[key] = atlas_version, info
+    return result
+
+
+class lapack_opt_info(system_info):
+
+    notfounderror = LapackNotFoundError
+
+    def calc_info(self):
+
+        openblas_info = get_info('openblas_lapack')
+        if openblas_info:
+            self.set_info(**openblas_info)
+            return
+
+        lapack_mkl_info = get_info('lapack_mkl')
+        if lapack_mkl_info:
+            self.set_info(**lapack_mkl_info)
+            return
+
+        atlas_info = get_info('atlas_3_10_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_3_10')
+        if not atlas_info:
+            atlas_info = get_info('atlas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas')
+
+        if sys.platform == 'darwin' and not atlas_info:
+            # Use the system lapack from Accelerate or vecLib under OSX
+            args = []
+            link_args = []
+            if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
+               'x86_64' in get_platform() or \
+               'i386' in platform.platform():
+                intel = 1
+            else:
+                intel = 0
+            if os.path.exists('/System/Library/Frameworks'
+                              '/Accelerate.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
+            elif os.path.exists('/System/Library/Frameworks'
+                                '/vecLib.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
+            if args:
+                self.set_info(extra_compile_args=args,
+                              extra_link_args=link_args,
+                              define_macros=[('NO_ATLAS_INFO', 3),
+                                             ('HAVE_CBLAS', None)])
+                return
+
+        need_lapack = 0
+        need_blas = 0
+        info = {}
+        if atlas_info:
+            l = atlas_info.get('define_macros', [])
+            if ('ATLAS_WITH_LAPACK_ATLAS', None) in l \
+                   or ('ATLAS_WITHOUT_LAPACK', None) in l:
+                need_lapack = 1
+            info = atlas_info
+
+        else:
+            warnings.warn(AtlasNotFoundError.__doc__)
+            need_blas = 1
+            need_lapack = 1
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
+
+        if need_lapack:
+            lapack_info = get_info('lapack')
+            #lapack_info = {} ## uncomment for testing
+            if lapack_info:
+                dict_append(info, **lapack_info)
+            else:
+                warnings.warn(LapackNotFoundError.__doc__)
+                lapack_src_info = get_info('lapack_src')
+                if not lapack_src_info:
+                    warnings.warn(LapackSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('flapack_src', lapack_src_info)])
+
+        if need_blas:
+            blas_info = get_info('blas')
+            if blas_info:
+                dict_append(info, **blas_info)
+            else:
+                warnings.warn(BlasNotFoundError.__doc__)
+                blas_src_info = get_info('blas_src')
+                if not blas_src_info:
+                    warnings.warn(BlasSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('fblas_src', blas_src_info)])
+
+        self.set_info(**info)
+        return
+
+
+class blas_opt_info(system_info):
+
+    notfounderror = BlasNotFoundError
+
+    def calc_info(self):
+
+        blas_mkl_info = get_info('blas_mkl')
+        if blas_mkl_info:
+            self.set_info(**blas_mkl_info)
+            return
+
+        openblas_info = get_info('openblas')
+        if openblas_info:
+            self.set_info(**openblas_info)
+            return
+
+        atlas_info = get_info('atlas_3_10_blas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_3_10_blas')
+        if not atlas_info:
+            atlas_info = get_info('atlas_blas_threads')
+        if not atlas_info:
+            atlas_info = get_info('atlas_blas')
+
+        if sys.platform == 'darwin' and not atlas_info:
+            # Use the system BLAS from Accelerate or vecLib under OSX
+            args = []
+            link_args = []
+            if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
+               'x86_64' in get_platform() or \
+               'i386' in platform.platform():
+                intel = 1
+            else:
+                intel = 0
+            if os.path.exists('/System/Library/Frameworks'
+                              '/Accelerate.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                args.extend([
+                    '-I/System/Library/Frameworks/vecLib.framework/Headers'])
+                link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
+            elif os.path.exists('/System/Library/Frameworks'
+                                '/vecLib.framework/'):
+                if intel:
+                    args.extend(['-msse3'])
+                else:
+                    args.extend(['-faltivec'])
+                args.extend([
+                    '-I/System/Library/Frameworks/vecLib.framework/Headers'])
+                link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
+            if args:
+                self.set_info(extra_compile_args=args,
+                              extra_link_args=link_args,
+                              define_macros=[('NO_ATLAS_INFO', 3),
+                                             ('HAVE_CBLAS', None)])
+                return
+
+        need_blas = 0
+        info = {}
+        if atlas_info:
+            info = atlas_info
+        else:
+            warnings.warn(AtlasNotFoundError.__doc__)
+            need_blas = 1
+            dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
+
+        if need_blas:
+            blas_info = get_info('blas')
+            if blas_info:
+                dict_append(info, **blas_info)
+            else:
+                warnings.warn(BlasNotFoundError.__doc__)
+                blas_src_info = get_info('blas_src')
+                if not blas_src_info:
+                    warnings.warn(BlasSrcNotFoundError.__doc__)
+                    return
+                dict_append(info, libraries=[('fblas_src', blas_src_info)])
+
+        self.set_info(**info)
+        return
+
+
+class blas_info(system_info):
+    section = 'blas'
+    dir_env_var = 'BLAS'
+    _lib_names = ['blas']
+    notfounderror = BlasNotFoundError
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+        blas_libs = self.get_libs('blas_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, blas_libs, [])
+        if info is None:
+            return
+        if platform.system() == 'Windows':
+            # The check for windows is needed because has_cblas uses the
+            # same compiler that was used to compile Python and msvc is
+            # often not installed when mingw is being used. This rough
+            # treatment is not desirable, but windows is tricky.
+            info['language'] = 'f77'  # XXX: is it generally true?
+        else:
+            lib = self.has_cblas(info)
+            if lib is not None:
+                info['language'] = 'c'
+                info['libraries'] = [lib]
+                info['define_macros'] = [('HAVE_CBLAS', None)]
+        self.set_info(**info)
+
+    def has_cblas(self, info):
+        # primitive cblas check by looking for the header and trying to link
+        # cblas or blas
+        res = False
+        c = distutils.ccompiler.new_compiler()
+        tmpdir = tempfile.mkdtemp()
+        s = """#include <cblas.h>
+        int main(int argc, const char *argv[])
+        {
+            double a[4] = {1,2,3,4};
+            double b[4] = {5,6,7,8};
+            return cblas_ddot(4, a, 1, b, 1) > 10;
+        }"""
+        src = os.path.join(tmpdir, 'source.c')
+        try:
+            with open(src, 'wt') as f:
+                f.write(s)
+
+            try:
+                # check we can compile (find headers)
+                obj = c.compile([src], output_dir=tmpdir,
+                                include_dirs=self.get_include_dirs())
+
+                # check we can link (find library)
+                # some systems have separate cblas and blas libs. First
+                # check for cblas lib, and if not present check for blas lib.
+                try:
+                    c.link_executable(obj, os.path.join(tmpdir, "a.out"),
+                                      libraries=["cblas"],
+                                      library_dirs=info['library_dirs'],
+                                      extra_postargs=info.get('extra_link_args', []))
+                    res = "cblas"
+                except distutils.ccompiler.LinkError:
+                    c.link_executable(obj, os.path.join(tmpdir, "a.out"),
+                                      libraries=["blas"],
+                                      library_dirs=info['library_dirs'],
+                                      extra_postargs=info.get('extra_link_args', []))
+                    res = "blas"
+            except distutils.ccompiler.CompileError:
+                res = None
+        finally:
+            shutil.rmtree(tmpdir)
+        return res
+
+
+class openblas_info(blas_info):
+    section = 'openblas'
+    dir_env_var = 'OPENBLAS'
+    _lib_names = ['openblas']
+    notfounderror = BlasNotFoundError
+
+    def check_embedded_lapack(self, info):
+        return True
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        openblas_libs = self.get_libs('libraries', self._lib_names)
+        if openblas_libs == self._lib_names: # backward compat with 1.8.0
+            openblas_libs = self.get_libs('openblas_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, openblas_libs, [])
+        if info is None:
+            return
+
+        # Add extra info for OpenBLAS
+        extra_info = self.calc_extra_info()
+        dict_append(info, **extra_info)
+
+        if not self.check_embedded_lapack(info):
+            return
+
+        info['language'] = 'c'
+        info['define_macros'] = [('HAVE_CBLAS', None)]
+        self.set_info(**info)
+
+
+class openblas_lapack_info(openblas_info):
+    section = 'openblas'
+    dir_env_var = 'OPENBLAS'
+    _lib_names = ['openblas']
+    notfounderror = BlasNotFoundError
+
+    def check_embedded_lapack(self, info):
+        res = False
+        c = distutils.ccompiler.new_compiler()
+        tmpdir = tempfile.mkdtemp()
+        s = """void zungqr();
+        int main(int argc, const char *argv[])
+        {
+            zungqr_();
+            return 0;
+        }"""
+        src = os.path.join(tmpdir, 'source.c')
+        out = os.path.join(tmpdir, 'a.out')
+        # Add the additional "extra" arguments
+        try:
+            extra_args = info['extra_link_args']
+        except:
+            extra_args = []
+        try:
+            with open(src, 'wt') as f:
+                f.write(s)
+            obj = c.compile([src], output_dir=tmpdir)
+            try:
+                c.link_executable(obj, out, libraries=info['libraries'],
+                                  library_dirs=info['library_dirs'],
+                                  extra_postargs=extra_args)
+                res = True
+            except distutils.ccompiler.LinkError:
+                res = False
+        finally:
+            shutil.rmtree(tmpdir)
+        return res
+
+
+class blas_src_info(system_info):
+    section = 'blas_src'
+    dir_env_var = 'BLAS_SRC'
+    notfounderror = BlasSrcNotFoundError
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['blas']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'daxpy.f')):
+                src_dir = d
+                break
+        if not src_dir:
+            #XXX: Get sources from netlib. May be ask first.
+            return
+        blas1 = '''
+        caxpy csscal dnrm2 dzasum saxpy srotg zdotc ccopy cswap drot
+        dznrm2 scasum srotm zdotu cdotc dasum drotg icamax scnrm2
+        srotmg zdrot cdotu daxpy drotm idamax scopy sscal zdscal crotg
+        dcabs1 drotmg isamax sdot sswap zrotg cscal dcopy dscal izamax
+        snrm2 zaxpy zscal csrot ddot dswap sasum srot zcopy zswap
+        scabs1
+        '''
+        blas2 = '''
+        cgbmv chpmv ctrsv dsymv dtrsv sspr2 strmv zhemv ztpmv cgemv
+        chpr dgbmv dsyr lsame ssymv strsv zher ztpsv cgerc chpr2 dgemv
+        dsyr2 sgbmv ssyr xerbla zher2 ztrmv cgeru ctbmv dger dtbmv
+        sgemv ssyr2 zgbmv zhpmv ztrsv chbmv ctbsv dsbmv dtbsv sger
+        stbmv zgemv zhpr chemv ctpmv dspmv dtpmv ssbmv stbsv zgerc
+        zhpr2 cher ctpsv dspr dtpsv sspmv stpmv zgeru ztbmv cher2
+        ctrmv dspr2 dtrmv sspr stpsv zhbmv ztbsv
+        '''
+        blas3 = '''
+        cgemm csymm ctrsm dsyrk sgemm strmm zhemm zsyr2k chemm csyr2k
+        dgemm dtrmm ssymm strsm zher2k zsyrk cher2k csyrk dsymm dtrsm
+        ssyr2k zherk ztrmm cherk ctrmm dsyr2k ssyrk zgemm zsymm ztrsm
+        '''
+        sources = [os.path.join(src_dir, f + '.f') \
+                   for f in (blas1 + blas2 + blas3).split()]
+        #XXX: should we check here actual existence of source files?
+        sources = [f for f in sources if os.path.isfile(f)]
+        info = {'sources': sources, 'language': 'f77'}
+        self.set_info(**info)
+
+
+class x11_info(system_info):
+    section = 'x11'
+    notfounderror = X11NotFoundError
+
+    def __init__(self):
+        system_info.__init__(self,
+                             default_lib_dirs=default_x11_lib_dirs,
+                             default_include_dirs=default_x11_include_dirs)
+
+    def calc_info(self):
+        if sys.platform  in ['win32']:
+            return
+        lib_dirs = self.get_lib_dirs()
+        include_dirs = self.get_include_dirs()
+        x11_libs = self.get_libs('x11_libs', ['X11'])
+        info = self.check_libs(lib_dirs, x11_libs, [])
+        if info is None:
+            return
+        inc_dir = None
+        for d in include_dirs:
+            if self.combine_paths(d, 'X11/X.h'):
+                inc_dir = d
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir])
+        self.set_info(**info)
+
+
+class _numpy_info(system_info):
+    section = 'Numeric'
+    modulename = 'Numeric'
+    notfounderror = NumericNotFoundError
+
+    def __init__(self):
+        include_dirs = []
+        try:
+            module = __import__(self.modulename)
+            prefix = []
+            for name in module.__file__.split(os.sep):
+                if name == 'lib':
+                    break
+                prefix.append(name)
+
+            # Ask numpy for its own include path before attempting
+            # anything else
+            try:
+                include_dirs.append(getattr(module, 'get_include')())
+            except AttributeError:
+                pass
+
+            include_dirs.append(distutils.sysconfig.get_python_inc(
+                                        prefix=os.sep.join(prefix)))
+        except ImportError:
+            pass
+        py_incl_dir = distutils.sysconfig.get_python_inc()
+        include_dirs.append(py_incl_dir)
+        py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
+        if py_pincl_dir not in include_dirs:
+            include_dirs.append(py_pincl_dir)
+        for d in default_include_dirs:
+            d = os.path.join(d, os.path.basename(py_incl_dir))
+            if d not in include_dirs:
+                include_dirs.append(d)
+        system_info.__init__(self,
+                             default_lib_dirs=[],
+                             default_include_dirs=include_dirs)
+
+    def calc_info(self):
+        try:
+            module = __import__(self.modulename)
+        except ImportError:
+            return
+        info = {}
+        macros = []
+        for v in ['__version__', 'version']:
+            vrs = getattr(module, v, None)
+            if vrs is None:
+                continue
+            macros = [(self.modulename.upper() + '_VERSION',
+                      '"\\"%s\\""' % (vrs)),
+                      (self.modulename.upper(), None)]
+            break
+        dict_append(info, define_macros=macros)
+        include_dirs = self.get_include_dirs()
+        inc_dir = None
+        for d in include_dirs:
+            if self.combine_paths(d,
+                                  os.path.join(self.modulename,
+                                               'arrayobject.h')):
+                inc_dir = d
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir])
+        if info:
+            self.set_info(**info)
+        return
+
+
+class numarray_info(_numpy_info):
+    section = 'numarray'
+    modulename = 'numarray'
+
+
+class Numeric_info(_numpy_info):
+    section = 'Numeric'
+    modulename = 'Numeric'
+
+
+class numpy_info(_numpy_info):
+    section = 'numpy'
+    modulename = 'numpy'
+
+
+class numerix_info(system_info):
+    section = 'numerix'
+
+    def calc_info(self):
+        which = None, None
+        if os.getenv("NUMERIX"):
+            which = os.getenv("NUMERIX"), "environment var"
+        # If all the above fail, default to numpy.
+        if which[0] is None:
+            which = "numpy", "defaulted"
+            try:
+                import numpy
+                which = "numpy", "defaulted"
+            except ImportError:
+                msg1 = str(get_exception())
+                try:
+                    import Numeric
+                    which = "numeric", "defaulted"
+                except ImportError:
+                    msg2 = str(get_exception())
+                    try:
+                        import numarray
+                        which = "numarray", "defaulted"
+                    except ImportError:
+                        msg3 = str(get_exception())
+                        log.info(msg1)
+                        log.info(msg2)
+                        log.info(msg3)
+        which = which[0].strip().lower(), which[1]
+        if which[0] not in ["numeric", "numarray", "numpy"]:
+            raise ValueError("numerix selector must be either 'Numeric' "
+                             "or 'numarray' or 'numpy' but the value obtained"
+                             " from the %s was '%s'." % (which[1], which[0]))
+        os.environ['NUMERIX'] = which[0]
+        self.set_info(**get_info(which[0]))
+
+
+class f2py_info(system_info):
+    def calc_info(self):
+        try:
+            import numpy.f2py as f2py
+        except ImportError:
+            return
+        f2py_dir = os.path.join(os.path.dirname(f2py.__file__), 'src')
+        self.set_info(sources=[os.path.join(f2py_dir, 'fortranobject.c')],
+                      include_dirs=[f2py_dir])
+        return
+
+
+class boost_python_info(system_info):
+    section = 'boost_python'
+    dir_env_var = 'BOOST'
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['boost*']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'libs', 'python', 'src',
+                                           'module.cpp')):
+                src_dir = d
+                break
+        if not src_dir:
+            return
+        py_incl_dirs = [distutils.sysconfig.get_python_inc()]
+        py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
+        if py_pincl_dir not in py_incl_dirs:
+            py_incl_dirs.append(py_pincl_dir)
+        srcs_dir = os.path.join(src_dir, 'libs', 'python', 'src')
+        bpl_srcs = glob(os.path.join(srcs_dir, '*.cpp'))
+        bpl_srcs += glob(os.path.join(srcs_dir, '*', '*.cpp'))
+        info = {'libraries': [('boost_python_src',
+                               {'include_dirs': [src_dir] + py_incl_dirs,
+                                'sources':bpl_srcs}
+                              )],
+                'include_dirs': [src_dir],
+                }
+        if info:
+            self.set_info(**info)
+        return
+
+
+class agg2_info(system_info):
+    section = 'agg2'
+    dir_env_var = 'AGG2'
+
+    def get_paths(self, section, key):
+        pre_dirs = system_info.get_paths(self, section, key)
+        dirs = []
+        for d in pre_dirs:
+            dirs.extend([d] + self.combine_paths(d, ['agg2*']))
+        return [d for d in dirs if os.path.isdir(d)]
+
+    def calc_info(self):
+        src_dirs = self.get_src_dirs()
+        src_dir = ''
+        for d in src_dirs:
+            if os.path.isfile(os.path.join(d, 'src', 'agg_affine_matrix.cpp')):
+                src_dir = d
+                break
+        if not src_dir:
+            return
+        if sys.platform == 'win32':
+            agg2_srcs = glob(os.path.join(src_dir, 'src', 'platform',
+                                          'win32', 'agg_win32_bmp.cpp'))
+        else:
+            agg2_srcs = glob(os.path.join(src_dir, 'src', '*.cpp'))
+            agg2_srcs += [os.path.join(src_dir, 'src', 'platform',
+                                       'X11',
+                                       'agg_platform_support.cpp')]
+
+        info = {'libraries':
+                [('agg2_src',
+                  {'sources': agg2_srcs,
+                   'include_dirs': [os.path.join(src_dir, 'include')],
+                  }
+                 )],
+                'include_dirs': [os.path.join(src_dir, 'include')],
+                }
+        if info:
+            self.set_info(**info)
+        return
+
+
+class _pkg_config_info(system_info):
+    section = None
+    config_env_var = 'PKG_CONFIG'
+    default_config_exe = 'pkg-config'
+    append_config_exe = ''
+    version_macro_name = None
+    release_macro_name = None
+    version_flag = '--modversion'
+    cflags_flag = '--cflags'
+
+    def get_config_exe(self):
+        if self.config_env_var in os.environ:
+            return os.environ[self.config_env_var]
+        return self.default_config_exe
+
+    def get_config_output(self, config_exe, option):
+        cmd = config_exe + ' ' + self.append_config_exe + ' ' + option
+        s, o = exec_command(cmd, use_tee=0)
+        if not s:
+            return o
+
+    def calc_info(self):
+        config_exe = find_executable(self.get_config_exe())
+        if not config_exe:
+            log.warn('File not found: %s. Cannot determine %s info.' \
+                  % (config_exe, self.section))
+            return
+        info = {}
+        macros = []
+        libraries = []
+        library_dirs = []
+        include_dirs = []
+        extra_link_args = []
+        extra_compile_args = []
+        version = self.get_config_output(config_exe, self.version_flag)
+        if version:
+            macros.append((self.__class__.__name__.split('.')[-1].upper(),
+                           '"\\"%s\\""' % (version)))
+            if self.version_macro_name:
+                macros.append((self.version_macro_name + '_%s'
+                               % (version.replace('.', '_')), None))
+        if self.release_macro_name:
+            release = self.get_config_output(config_exe, '--release')
+            if release:
+                macros.append((self.release_macro_name + '_%s'
+                               % (release.replace('.', '_')), None))
+        opts = self.get_config_output(config_exe, '--libs')
+        if opts:
+            for opt in opts.split():
+                if opt[:2] == '-l':
+                    libraries.append(opt[2:])
+                elif opt[:2] == '-L':
+                    library_dirs.append(opt[2:])
+                else:
+                    extra_link_args.append(opt)
+        opts = self.get_config_output(config_exe, self.cflags_flag)
+        if opts:
+            for opt in opts.split():
+                if opt[:2] == '-I':
+                    include_dirs.append(opt[2:])
+                elif opt[:2] == '-D':
+                    if '=' in opt:
+                        n, v = opt[2:].split('=')
+                        macros.append((n, v))
+                    else:
+                        macros.append((opt[2:], None))
+                else:
+                    extra_compile_args.append(opt)
+        if macros:
+            dict_append(info, define_macros=macros)
+        if libraries:
+            dict_append(info, libraries=libraries)
+        if library_dirs:
+            dict_append(info, library_dirs=library_dirs)
+        if include_dirs:
+            dict_append(info, include_dirs=include_dirs)
+        if extra_link_args:
+            dict_append(info, extra_link_args=extra_link_args)
+        if extra_compile_args:
+            dict_append(info, extra_compile_args=extra_compile_args)
+        if info:
+            self.set_info(**info)
+        return
+
+
+class wx_info(_pkg_config_info):
+    section = 'wx'
+    config_env_var = 'WX_CONFIG'
+    default_config_exe = 'wx-config'
+    append_config_exe = ''
+    version_macro_name = 'WX_VERSION'
+    release_macro_name = 'WX_RELEASE'
+    version_flag = '--version'
+    cflags_flag = '--cxxflags'
+
+
+class gdk_pixbuf_xlib_2_info(_pkg_config_info):
+    section = 'gdk_pixbuf_xlib_2'
+    append_config_exe = 'gdk-pixbuf-xlib-2.0'
+    version_macro_name = 'GDK_PIXBUF_XLIB_VERSION'
+
+
+class gdk_pixbuf_2_info(_pkg_config_info):
+    section = 'gdk_pixbuf_2'
+    append_config_exe = 'gdk-pixbuf-2.0'
+    version_macro_name = 'GDK_PIXBUF_VERSION'
+
+
+class gdk_x11_2_info(_pkg_config_info):
+    section = 'gdk_x11_2'
+    append_config_exe = 'gdk-x11-2.0'
+    version_macro_name = 'GDK_X11_VERSION'
+
+
+class gdk_2_info(_pkg_config_info):
+    section = 'gdk_2'
+    append_config_exe = 'gdk-2.0'
+    version_macro_name = 'GDK_VERSION'
+
+
+class gdk_info(_pkg_config_info):
+    section = 'gdk'
+    append_config_exe = 'gdk'
+    version_macro_name = 'GDK_VERSION'
+
+
+class gtkp_x11_2_info(_pkg_config_info):
+    section = 'gtkp_x11_2'
+    append_config_exe = 'gtk+-x11-2.0'
+    version_macro_name = 'GTK_X11_VERSION'
+
+
+class gtkp_2_info(_pkg_config_info):
+    section = 'gtkp_2'
+    append_config_exe = 'gtk+-2.0'
+    version_macro_name = 'GTK_VERSION'
+
+
+class xft_info(_pkg_config_info):
+    section = 'xft'
+    append_config_exe = 'xft'
+    version_macro_name = 'XFT_VERSION'
+
+
+class freetype2_info(_pkg_config_info):
+    section = 'freetype2'
+    append_config_exe = 'freetype2'
+    version_macro_name = 'FREETYPE2_VERSION'
+
+
+class amd_info(system_info):
+    section = 'amd'
+    dir_env_var = 'AMD'
+    _lib_names = ['amd']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        amd_libs = self.get_libs('amd_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, amd_libs, [])
+        if info is None:
+            return
+
+        include_dirs = self.get_include_dirs()
+
+        inc_dir = None
+        for d in include_dirs:
+            p = self.combine_paths(d, 'amd.h')
+            if p:
+                inc_dir = os.path.dirname(p[0])
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir],
+                        define_macros=[('SCIPY_AMD_H', None)],
+                        swig_opts=['-I' + inc_dir])
+
+        self.set_info(**info)
+        return
+
+
+class umfpack_info(system_info):
+    section = 'umfpack'
+    dir_env_var = 'UMFPACK'
+    notfounderror = UmfpackNotFoundError
+    _lib_names = ['umfpack']
+
+    def calc_info(self):
+        lib_dirs = self.get_lib_dirs()
+
+        umfpack_libs = self.get_libs('umfpack_libs', self._lib_names)
+        info = self.check_libs(lib_dirs, umfpack_libs, [])
+        if info is None:
+            return
+
+        include_dirs = self.get_include_dirs()
+
+        inc_dir = None
+        for d in include_dirs:
+            p = self.combine_paths(d, ['', 'umfpack'], 'umfpack.h')
+            if p:
+                inc_dir = os.path.dirname(p[0])
+                break
+        if inc_dir is not None:
+            dict_append(info, include_dirs=[inc_dir],
+                        define_macros=[('SCIPY_UMFPACK_H', None)],
+                        swig_opts=['-I' + inc_dir])
+
+        amd = get_info('amd')
+        dict_append(info, **get_info('amd'))
+
+        self.set_info(**info)
+        return
+
+
+def combine_paths(*args, **kws):
+    """ Return a list of existing paths composed by all combinations of
+        items from arguments.
+    """
+    r = []
+    for a in args:
+        if not a:
+            continue
+        if is_string(a):
+            a = [a]
+        r.append(a)
+    args = r
+    if not args:
+        return []
+    if len(args) == 1:
+        result = reduce(lambda a, b: a + b, map(glob, args[0]), [])
+    elif len(args) == 2:
+        result = []
+        for a0 in args[0]:
+            for a1 in args[1]:
+                result.extend(glob(os.path.join(a0, a1)))
+    else:
+        result = combine_paths(*(combine_paths(args[0], args[1]) + args[2:]))
+    verbosity = kws.get('verbosity', 1)
+    log.debug('(paths: %s)', ','.join(result))
+    return result
+
+language_map = {'c': 0, 'c++': 1, 'f77': 2, 'f90': 3}
+inv_language_map = {0: 'c', 1: 'c++', 2: 'f77', 3: 'f90'}
+
+
+def dict_append(d, **kws):
+    languages = []
+    for k, v in kws.items():
+        if k == 'language':
+            languages.append(v)
+            continue
+        if k in d:
+            if k in ['library_dirs', 'include_dirs', 
+                     'extra_compile_args', 'extra_link_args',
+                     'runtime_library_dirs', 'define_macros']:
+                [d[k].append(vv) for vv in v if vv not in d[k]]
+            else:
+                d[k].extend(v)
+        else:
+            d[k] = v
+    if languages:
+        l = inv_language_map[max([language_map.get(l, 0) for l in languages])]
+        d['language'] = l
+    return
+
+
+def parseCmdLine(argv=(None,)):
+    import optparse
+    parser = optparse.OptionParser("usage: %prog [-v] [info objs]")
+    parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
+                      default=False,
+                      help='be verbose and print more messages')
+
+    opts, args = parser.parse_args(args=argv[1:])
+    return opts, args
+
+
+def show_all(argv=None):
+    import inspect
+    if argv is None:
+        argv = sys.argv
+    opts, args = parseCmdLine(argv)
+    if opts.verbose:
+        log.set_threshold(log.DEBUG)
+    else:
+        log.set_threshold(log.INFO)
+    show_only = []
+    for n in args:
+        if n[-5:] != '_info':
+            n = n + '_info'
+        show_only.append(n)
+    show_all = not show_only
+    _gdict_ = globals().copy()
+    for name, c in _gdict_.items():
+        if not inspect.isclass(c):
+            continue
+        if not issubclass(c, system_info) or c is system_info:
+            continue
+        if not show_all:
+            if name not in show_only:
+                continue
+            del show_only[show_only.index(name)]
+        conf = c()
+        conf.verbosity = 2
+        r = conf.get_info()
+    if show_only:
+        log.info('Info classes not defined: %s', ','.join(show_only))
+
+if __name__ == "__main__":
+    show_all()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
new file mode 100644
index 0000000000..0931f749b3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
@@ -0,0 +1,92 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from tempfile import TemporaryFile
+
+from numpy.distutils import exec_command
+
+# In python 3 stdout, stderr are text (unicode compliant) devices, so to
+# emulate them import StringIO from the io module.
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+class redirect_stdout(object):
+    """Context manager to redirect stdout for exec_command test."""
+    def __init__(self, stdout=None):
+        self._stdout = stdout or sys.stdout
+
+    def __enter__(self):
+        self.old_stdout = sys.stdout
+        sys.stdout = self._stdout
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._stdout.flush()
+        sys.stdout = self.old_stdout
+        # note: closing sys.stdout won't close it.
+        self._stdout.close()
+
+class redirect_stderr(object):
+    """Context manager to redirect stderr for exec_command test."""
+    def __init__(self, stderr=None):
+        self._stderr = stderr or sys.stderr
+
+    def __enter__(self):
+        self.old_stderr = sys.stderr
+        sys.stderr = self._stderr
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._stderr.flush()
+        sys.stderr = self.old_stderr
+        # note: closing sys.stderr won't close it.
+        self._stderr.close()
+
+class emulate_nonposix(object):
+    """Context manager to emulate os.name != 'posix' """
+    def __init__(self, osname='non-posix'):
+        self._new_name = osname
+
+    def __enter__(self):
+        self._old_name = os.name
+        os.name = self._new_name
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        os.name = self._old_name
+
+
+def test_exec_command_stdout():
+    # Regression test for gh-2999 and gh-2915.
+    # There are several packages (nose, scipy.weave.inline, Sage inline
+    # Fortran) that replace stdout, in which case it doesn't have a fileno
+    # method.  This is tested here, with a do-nothing command that fails if the
+    # presence of fileno() is assumed in exec_command.
+
+    # The code has a special case for posix systems, so if we are on posix test
+    # both that the special case works and that the generic code works.
+
+    # Test posix version:
+    with redirect_stdout(StringIO()):
+        with redirect_stderr(TemporaryFile()):
+            exec_command.exec_command("cd '.'")
+
+    if os.name == 'posix':
+        # Test general (non-posix) version:
+        with emulate_nonposix():
+            with redirect_stdout(StringIO()):
+                with redirect_stderr(TemporaryFile()):
+                    exec_command.exec_command("cd '.'")
+
+def test_exec_command_stderr():
+    # Test posix version:
+    with redirect_stdout(TemporaryFile(mode='w+')):
+        with redirect_stderr(StringIO()):
+            exec_command.exec_command("cd '.'")
+
+    if os.name == 'posix':
+        # Test general (non-posix) version:
+        with emulate_nonposix():
+            with redirect_stdout(TemporaryFile()):
+                with redirect_stderr(StringIO()):
+                    exec_command.exec_command("cd '.'")
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
new file mode 100644
index 0000000000..7ca99db22a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
@@ -0,0 +1,60 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import TestCase, assert_, run_module_suite
+
+import numpy.distutils.fcompiler
+
+g77_version_strings = [
+    ('GNU Fortran 0.5.25 20010319 (prerelease)', '0.5.25'),
+    ('GNU Fortran (GCC 3.2) 3.2 20020814 (release)', '3.2'),
+    ('GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian)', '3.3.3'),
+    ('GNU Fortran (GCC) 3.3.3 (Debian 20040401)', '3.3.3'),
+    ('GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2'
+       ' 20030222 (Red Hat Linux 3.2.2-5)', '3.2.2'),
+]
+
+gfortran_version_strings = [
+    ('GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3))',
+     '4.0.3'),
+    ('GNU Fortran 95 (GCC) 4.1.0', '4.1.0'),
+    ('GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental)', '4.2.0'),
+    ('GNU Fortran (GCC) 4.3.0 20070316 (experimental)', '4.3.0'),
+    ('GNU Fortran (rubenvb-4.8.0) 4.8.0', '4.8.0'),
+    ('4.8.0', '4.8.0'),
+    ('4.0.3-7', '4.0.3'),
+    ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n4.9.1",
+     '4.9.1'),
+    ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n"
+     "gfortran: warning: yet another warning\n4.9.1",
+     '4.9.1')
+]
+
+class TestG77Versions(TestCase):
+    def test_g77_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
+        for vs, version in g77_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version, (vs, v))
+
+    def test_not_g77(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu')
+        for vs, _ in gfortran_version_strings:
+            v = fc.version_match(vs)
+            assert_(v is None, (vs, v))
+
+class TestGFortranVersions(TestCase):
+    def test_gfortran_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
+        for vs, version in gfortran_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version, (vs, v))
+
+    def test_not_gfortran(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95')
+        for vs, _ in g77_version_strings:
+            v = fc.version_match(vs)
+            assert_(v is None, (vs, v))
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
new file mode 100644
index 0000000000..8e371b92b7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
@@ -0,0 +1,36 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.distutils.fcompiler
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+intel_32bit_version_strings = [
+    ("Intel(R) Fortran Intel(R) 32-bit Compiler Professional for applications"
+     "running on Intel(R) 32, Version 11.1", '11.1'),
+]
+
+intel_64bit_version_strings = [
+    ("Intel(R) Fortran IA-64 Compiler Professional for applications"
+     "running on IA-64, Version 11.0", '11.0'),
+    ("Intel(R) Fortran Intel(R) 64 Compiler Professional for applications"
+     "running on Intel(R) 64, Version 11.1", '11.1')
+]
+
+class TestIntelFCompilerVersions(TestCase):
+    def test_32bit_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intel')
+        for vs, version in intel_32bit_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version)
+
+
+class TestIntelEM64TFCompilerVersions(TestCase):
+    def test_64bit_version(self):
+        fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intelem')
+        for vs, version in intel_64bit_version_strings:
+            v = fc.version_match(vs)
+            assert_(v == version)
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
new file mode 100644
index 0000000000..df845f71b3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python2
+from __future__ import division, absolute_import, print_function
+
+from os.path import join, sep, dirname
+
+from numpy.distutils.misc_util import (
+    appendpath, minrelpath, gpaths, get_shared_lib_extension
+)
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal
+)
+
+ajoin = lambda *paths: join(*((sep,)+paths))
+
+class TestAppendpath(TestCase):
+
+    def test_1(self):
+        assert_equal(appendpath('prefix', 'name'), join('prefix', 'name'))
+        assert_equal(appendpath('/prefix', 'name'), ajoin('prefix', 'name'))
+        assert_equal(appendpath('/prefix', '/name'), ajoin('prefix', 'name'))
+        assert_equal(appendpath('prefix', '/name'), join('prefix', 'name'))
+
+    def test_2(self):
+        assert_equal(appendpath('prefix/sub', 'name'),
+                     join('prefix', 'sub', 'name'))
+        assert_equal(appendpath('prefix/sub', 'sup/name'),
+                     join('prefix', 'sub', 'sup', 'name'))
+        assert_equal(appendpath('/prefix/sub', '/prefix/name'),
+                     ajoin('prefix', 'sub', 'name'))
+
+    def test_3(self):
+        assert_equal(appendpath('/prefix/sub', '/prefix/sup/name'),
+                     ajoin('prefix', 'sub', 'sup', 'name'))
+        assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sup/sup2/name'),
+                     ajoin('prefix', 'sub', 'sub2', 'sup', 'sup2', 'name'))
+        assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sub/sup/name'),
+                     ajoin('prefix', 'sub', 'sub2', 'sup', 'name'))
+
+class TestMinrelpath(TestCase):
+
+    def test_1(self):
+        n = lambda path: path.replace('/', sep)
+        assert_equal(minrelpath(n('aa/bb')), n('aa/bb'))
+        assert_equal(minrelpath('..'), '..')
+        assert_equal(minrelpath(n('aa/..')), '')
+        assert_equal(minrelpath(n('aa/../bb')), 'bb')
+        assert_equal(minrelpath(n('aa/bb/..')), 'aa')
+        assert_equal(minrelpath(n('aa/bb/../..')), '')
+        assert_equal(minrelpath(n('aa/bb/../cc/../dd')), n('aa/dd'))
+        assert_equal(minrelpath(n('.././..')), n('../..'))
+        assert_equal(minrelpath(n('aa/bb/.././../dd')), n('dd'))
+
+class TestGpaths(TestCase):
+
+    def test_gpaths(self):
+        local_path = minrelpath(join(dirname(__file__), '..'))
+        ls = gpaths('command/*.py', local_path)
+        assert_(join(local_path, 'command', 'build_src.py') in ls, repr(ls))
+        f = gpaths('system_info.py', local_path)
+        assert_(join(local_path, 'system_info.py') == f[0], repr(f))
+
+class TestSharedExtension(TestCase):
+
+    def test_get_shared_lib_extension(self):
+        import sys
+        ext = get_shared_lib_extension(is_python_ext=False)
+        if sys.platform.startswith('linux'):
+            assert_equal(ext, '.so')
+        elif sys.platform.startswith('gnukfreebsd'):
+            assert_equal(ext, '.so')
+        elif sys.platform.startswith('darwin'):
+            assert_equal(ext, '.dylib')
+        elif sys.platform.startswith('win'):
+            assert_equal(ext, '.dll')
+        # just check for no crash
+        assert_(get_shared_lib_extension(is_python_ext=True))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
new file mode 100644
index 0000000000..bdef47167b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
@@ -0,0 +1,90 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.distutils.npy_pkg_config import read_config, parse_flags
+from numpy.testing import TestCase, run_module_suite, temppath
+
+simple = """\
+[meta]
+Name = foo
+Description = foo lib
+Version = 0.1
+
+[default]
+cflags = -I/usr/include
+libs = -L/usr/lib
+"""
+simple_d = {'cflags': '-I/usr/include', 'libflags': '-L/usr/lib',
+        'version': '0.1', 'name': 'foo'}
+
+simple_variable = """\
+[meta]
+Name = foo
+Description = foo lib
+Version = 0.1
+
+[variables]
+prefix = /foo/bar
+libdir = ${prefix}/lib
+includedir = ${prefix}/include
+
+[default]
+cflags = -I${includedir}
+libs = -L${libdir}
+"""
+simple_variable_d = {'cflags': '-I/foo/bar/include', 'libflags': '-L/foo/bar/lib',
+        'version': '0.1', 'name': 'foo'}
+
+class TestLibraryInfo(TestCase):
+    def test_simple(self):
+        with temppath('foo.ini') as path:
+            with open(path,  'w') as f:
+                f.write(simple)
+            pkg = os.path.splitext(path)[0]
+            out = read_config(pkg)
+
+        self.assertTrue(out.cflags() == simple_d['cflags'])
+        self.assertTrue(out.libs() == simple_d['libflags'])
+        self.assertTrue(out.name == simple_d['name'])
+        self.assertTrue(out.version == simple_d['version'])
+
+    def test_simple_variable(self):
+        with temppath('foo.ini') as path:
+            with open(path,  'w') as f:
+                f.write(simple_variable)
+            pkg = os.path.splitext(path)[0]
+            out = read_config(pkg)
+
+        self.assertTrue(out.cflags() == simple_variable_d['cflags'])
+        self.assertTrue(out.libs() == simple_variable_d['libflags'])
+        self.assertTrue(out.name == simple_variable_d['name'])
+        self.assertTrue(out.version == simple_variable_d['version'])
+        out.vars['prefix'] = '/Users/david'
+        self.assertTrue(out.cflags() == '-I/Users/david/include')
+
+class TestParseFlags(TestCase):
+    def test_simple_cflags(self):
+        d = parse_flags("-I/usr/include")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+
+        d = parse_flags("-I/usr/include -DFOO")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+        self.assertTrue(d['macros'] == ['FOO'])
+
+        d = parse_flags("-I /usr/include -DFOO")
+        self.assertTrue(d['include_dirs'] == ['/usr/include'])
+        self.assertTrue(d['macros'] == ['FOO'])
+
+    def test_simple_lflags(self):
+        d = parse_flags("-L/usr/lib -lfoo -L/usr/lib -lbar")
+        self.assertTrue(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
+        self.assertTrue(d['libraries'] == ['foo', 'bar'])
+
+        d = parse_flags("-L /usr/lib -lfoo -L/usr/lib -lbar")
+        self.assertTrue(d['library_dirs'] == ['/usr/lib', '/usr/lib'])
+        self.assertTrue(d['libraries'] == ['foo', 'bar'])
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
new file mode 100644
index 0000000000..58ad05a593
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
@@ -0,0 +1,208 @@
+from __future__ import division, print_function
+
+import os
+import shutil
+from tempfile import mkstemp, mkdtemp
+
+from numpy.distutils import ccompiler
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal
+from numpy.testing.decorators import skipif
+from numpy.distutils.system_info import system_info, ConfigParser
+from numpy.distutils.system_info import default_lib_dirs, default_include_dirs
+
+
+def get_class(name, notfound_action=1):
+    """
+    notfound_action:
+      0 - do nothing
+      1 - display warning message
+      2 - raise error
+    """
+    cl = {'temp1': TestTemp1,
+          'temp2': TestTemp2
+          }.get(name.lower(), test_system_info)
+    return cl()
+
+simple_site = """
+[ALL]
+library_dirs = {dir1:s}{pathsep:s}{dir2:s}
+libraries = {lib1:s},{lib2:s}
+extra_compile_args = -I/fake/directory
+runtime_library_dirs = {dir1:s}
+
+[temp1]
+library_dirs = {dir1:s}
+libraries = {lib1:s}
+runtime_library_dirs = {dir1:s}
+
+[temp2]
+library_dirs = {dir2:s}
+libraries = {lib2:s}
+extra_link_args = -Wl,-rpath={lib2:s}
+rpath = {dir2:s}
+"""
+site_cfg = simple_site
+
+fakelib_c_text = """
+/* This file is generated from numpy/distutils/testing/test_system_info.py */
+#include<stdio.h>
+void foo(void) {
+   printf("Hello foo");
+}
+void bar(void) {
+   printf("Hello bar");
+}
+"""
+
+
+class test_system_info(system_info):
+
+    def __init__(self,
+                 default_lib_dirs=default_lib_dirs,
+                 default_include_dirs=default_include_dirs,
+                 verbosity=1,
+                 ):
+        self.__class__.info = {}
+        self.local_prefixes = []
+        defaults = {'library_dirs': '',
+                    'include_dirs': '',
+                    'runtime_library_dirs': '',
+                    'rpath': '',
+                    'src_dirs': '',
+                    'search_static_first': "0",
+                    'extra_compile_args': '',
+                    'extra_link_args': ''}
+        self.cp = ConfigParser(defaults)
+        # We have to parse the config files afterwards
+        # to have a consistent temporary filepath
+
+    def _check_libs(self, lib_dirs, libs, opt_libs, exts):
+        """Override _check_libs to return with all dirs """
+        info = {'libraries': libs, 'library_dirs': lib_dirs}
+        return info
+
+
+class TestTemp1(test_system_info):
+    section = 'temp1'
+
+
+class TestTemp2(test_system_info):
+    section = 'temp2'
+
+
+class TestSystemInfoReading(TestCase):
+
+    def setUp(self):
+        """ Create the libraries """
+        # Create 2 sources and 2 libraries
+        self._dir1 = mkdtemp()
+        self._src1 = os.path.join(self._dir1, 'foo.c')
+        self._lib1 = os.path.join(self._dir1, 'libfoo.so')
+        self._dir2 = mkdtemp()
+        self._src2 = os.path.join(self._dir2, 'bar.c')
+        self._lib2 = os.path.join(self._dir2, 'libbar.so')
+        # Update local site.cfg
+        global simple_site, site_cfg
+        site_cfg = simple_site.format(**{
+            'dir1': self._dir1,
+            'lib1': self._lib1,
+            'dir2': self._dir2,
+            'lib2': self._lib2,
+            'pathsep': os.pathsep
+        })
+        # Write site.cfg
+        fd, self._sitecfg = mkstemp()
+        os.close(fd)
+        with open(self._sitecfg, 'w') as fd:
+            fd.write(site_cfg)
+        # Write the sources
+        with open(self._src1, 'w') as fd:
+            fd.write(fakelib_c_text)
+        with open(self._src2, 'w') as fd:
+            fd.write(fakelib_c_text)
+        # We create all class-instances
+
+        def site_and_parse(c, site_cfg):
+            c.files = [site_cfg]
+            c.parse_config_files()
+            return c
+        self.c_default = site_and_parse(get_class('default'), self._sitecfg)
+        self.c_temp1 = site_and_parse(get_class('temp1'), self._sitecfg)
+        self.c_temp2 = site_and_parse(get_class('temp2'), self._sitecfg)
+
+    def tearDown(self):
+        # Do each removal separately
+        try:
+            shutil.rmtree(self._dir1)
+        except:
+            pass
+        try:
+            shutil.rmtree(self._dir2)
+        except:
+            pass
+        try:
+            os.remove(self._sitecfg)
+        except:
+            pass
+
+    def test_all(self):
+        # Read in all information in the ALL block
+        tsi = self.c_default
+        assert_equal(tsi.get_lib_dirs(), [self._dir1, self._dir2])
+        assert_equal(tsi.get_libraries(), [self._lib1, self._lib2])
+        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
+        extra = tsi.calc_extra_info()
+        assert_equal(extra['extra_compile_args'], ['-I/fake/directory'])
+
+    def test_temp1(self):
+        # Read in all information in the temp1 block
+        tsi = self.c_temp1
+        assert_equal(tsi.get_lib_dirs(), [self._dir1])
+        assert_equal(tsi.get_libraries(), [self._lib1])
+        assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1])
+
+    def test_temp2(self):
+        # Read in all information in the temp2 block
+        tsi = self.c_temp2
+        assert_equal(tsi.get_lib_dirs(), [self._dir2])
+        assert_equal(tsi.get_libraries(), [self._lib2])
+        # Now from rpath and not runtime_library_dirs
+        assert_equal(tsi.get_runtime_lib_dirs(key='rpath'), [self._dir2])
+        extra = tsi.calc_extra_info()
+        assert_equal(extra['extra_link_args'], ['-Wl,-rpath=' + self._lib2])
+
+    def test_compile1(self):
+        # Compile source and link the first source
+        c = ccompiler.new_compiler()
+        try:
+            # Change directory to not screw up directories
+            previousDir = os.getcwd()
+            os.chdir(self._dir1)
+            c.compile([os.path.basename(self._src1)], output_dir=self._dir1)
+            # Ensure that the object exists
+            assert_(os.path.isfile(self._src1.replace('.c', '.o')) or
+                    os.path.isfile(self._src1.replace('.c', '.obj')))
+            os.chdir(previousDir)
+        except OSError:
+            pass
+
+    @skipif('msvc' in repr(ccompiler.new_compiler()))
+    def test_compile2(self):
+        # Compile source and link the second source
+        tsi = self.c_temp2
+        c = ccompiler.new_compiler()
+        extra_link_args = tsi.calc_extra_info()['extra_link_args']
+        try:
+            # Change directory to not screw up directories
+            previousDir = os.getcwd()
+            os.chdir(self._dir2)
+            c.compile([os.path.basename(self._src2)], output_dir=self._dir2,
+                      extra_postargs=extra_link_args)
+            # Ensure that the object exists
+            assert_(os.path.isfile(self._src2.replace('.c', '.o')))
+            os.chdir(previousDir)
+        except OSError:
+            pass
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
new file mode 100644
index 0000000000..a92ccd3e7d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
@@ -0,0 +1,125 @@
+"""
+unixccompiler - can handle very long argument lists for ar.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from distutils.errors import DistutilsExecError, CompileError
+from distutils.unixccompiler import *
+from numpy.distutils.ccompiler import replace_method
+from numpy.distutils.compat import get_exception
+
+if sys.version_info[0] < 3:
+    from . import log
+else:
+    from numpy.distutils import log
+
+# Note that UnixCCompiler._compile appeared in Python 2.3
+def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
+    """Compile a single source files with a Unix-style compiler."""
+    # HP ad-hoc fix, see ticket 1383
+    ccomp = self.compiler_so
+    if ccomp[0] == 'aCC':
+        # remove flags that will trigger ANSI-C mode for aCC
+        if '-Ae' in ccomp:
+            ccomp.remove('-Ae')
+        if '-Aa' in ccomp:
+            ccomp.remove('-Aa')
+        # add flags for (almost) sane C++ handling
+        ccomp += ['-AA']
+        self.compiler_so = ccomp
+    # ensure OPT environment variable is read
+    if 'OPT' in os.environ:
+        from distutils.sysconfig import get_config_vars
+        opt = " ".join(os.environ['OPT'].split())
+        gcv_opt = " ".join(get_config_vars('OPT')[0].split())
+        ccomp_s = " ".join(self.compiler_so)
+        if opt not in ccomp_s:
+            ccomp_s = ccomp_s.replace(gcv_opt, opt)
+            self.compiler_so = ccomp_s.split()
+        llink_s = " ".join(self.linker_so)
+        if opt not in llink_s:
+            self.linker_so = llink_s.split() + opt.split()
+
+    display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
+    try:
+        self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
+                   extra_postargs, display = display)
+    except DistutilsExecError:
+        msg = str(get_exception())
+        raise CompileError(msg)
+
+replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile)
+
+
+def UnixCCompiler_create_static_lib(self, objects, output_libname,
+                                    output_dir=None, debug=0, target_lang=None):
+    """
+    Build a static library in a separate sub-process.
+
+    Parameters
+    ----------
+    objects : list or tuple of str
+        List of paths to object files used to build the static library.
+    output_libname : str
+        The library name as an absolute or relative (if `output_dir` is used)
+        path.
+    output_dir : str, optional
+        The path to the output directory. Default is None, in which case
+        the ``output_dir`` attribute of the UnixCCompiler instance.
+    debug : bool, optional
+        This parameter is not used.
+    target_lang : str, optional
+        This parameter is not used.
+
+    Returns
+    -------
+    None
+
+    """
+    objects, output_dir = self._fix_object_args(objects, output_dir)
+
+    output_filename = \
+                    self.library_filename(output_libname, output_dir=output_dir)
+
+    if self._need_link(objects, output_filename):
+        try:
+            # previous .a may be screwed up; best to remove it first
+            # and recreate.
+            # Also, ar on OS X doesn't handle updating universal archives
+            os.unlink(output_filename)
+        except (IOError, OSError):
+            pass
+        self.mkpath(os.path.dirname(output_filename))
+        tmp_objects = objects + self.objects
+        while tmp_objects:
+            objects = tmp_objects[:50]
+            tmp_objects = tmp_objects[50:]
+            display = '%s: adding %d object files to %s' % (
+                           os.path.basename(self.archiver[0]),
+                           len(objects), output_filename)
+            self.spawn(self.archiver + [output_filename] + objects,
+                       display = display)
+
+        # Not many Unices required ranlib anymore -- SunOS 4.x is, I
+        # think the only major Unix that does.  Maybe we need some
+        # platform intelligence here to skip ranlib if it's not
+        # needed -- or maybe Python's configure script took care of
+        # it for us, hence the check for leading colon.
+        if self.ranlib:
+            display = '%s:@ %s' % (os.path.basename(self.ranlib[0]),
+                                   output_filename)
+            try:
+                self.spawn(self.ranlib + [output_filename],
+                           display = display)
+            except DistutilsExecError:
+                msg = str(get_exception())
+                raise LibError(msg)
+    else:
+        log.debug("skipping %s (up-to-date)", output_filename)
+    return
+
+replace_method(UnixCCompiler, 'create_static_lib',
+               UnixCCompiler_create_static_lib)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/__init__.py
new file mode 100644
index 0000000000..b6f1fa71c5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/__init__.py
@@ -0,0 +1,28 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+ref_dir = os.path.join(os.path.dirname(__file__))
+
+__all__ = sorted(f[:-3] for f in os.listdir(ref_dir) if f.endswith('.py') and
+           not f.startswith('__'))
+
+for f in __all__:
+    __import__(__name__ + '.' + f)
+
+del f, ref_dir
+
+__doc__ = """\
+Topical documentation
+=====================
+
+The following topics are available:
+%s
+
+You can view them by
+
+>>> help(np.doc.TOPIC)                                      #doctest: +SKIP
+
+""" % '\n- '.join([''] + __all__)
+
+__all__.extend(['__doc__'])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/basics.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/basics.py
new file mode 100644
index 0000000000..745bff15a6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/basics.py
@@ -0,0 +1,185 @@
+"""
+============
+Array basics
+============
+
+Array types and conversions between types
+=========================================
+
+Numpy supports a much greater variety of numerical types than Python does.
+This section shows which are available, and how to modify an array's data-type.
+
+==========  ==========================================================
+Data type   Description
+==========  ==========================================================
+bool_       Boolean (True or False) stored as a byte
+int_        Default integer type (same as C ``long``; normally either
+            ``int64`` or ``int32``)
+intc        Identical to C ``int`` (normally ``int32`` or ``int64``)
+intp        Integer used for indexing (same as C ``ssize_t``; normally
+            either ``int32`` or ``int64``)
+int8        Byte (-128 to 127)
+int16       Integer (-32768 to 32767)
+int32       Integer (-2147483648 to 2147483647)
+int64       Integer (-9223372036854775808 to 9223372036854775807)
+uint8       Unsigned integer (0 to 255)
+uint16      Unsigned integer (0 to 65535)
+uint32      Unsigned integer (0 to 4294967295)
+uint64      Unsigned integer (0 to 18446744073709551615)
+float_      Shorthand for ``float64``.
+float16     Half precision float: sign bit, 5 bits exponent,
+            10 bits mantissa
+float32     Single precision float: sign bit, 8 bits exponent,
+            23 bits mantissa
+float64     Double precision float: sign bit, 11 bits exponent,
+            52 bits mantissa
+complex_    Shorthand for ``complex128``.
+complex64   Complex number, represented by two 32-bit floats (real
+            and imaginary components)
+complex128  Complex number, represented by two 64-bit floats (real
+            and imaginary components)
+==========  ==========================================================
+
+Additionally to ``intc`` the platform dependent C integer types ``short``,
+``long``, ``longlong`` and their unsigned versions are defined.
+
+Numpy numerical types are instances of ``dtype`` (data-type) objects, each
+having unique characteristics.  Once you have imported NumPy using
+
+  ::
+
+    >>> import numpy as np
+
+the dtypes are available as ``np.bool_``, ``np.float32``, etc.
+
+Advanced types, not listed in the table above, are explored in
+section :ref:`structured_arrays`.
+
+There are 5 basic numerical types representing booleans (bool), integers (int),
+unsigned integers (uint) floating point (float) and complex. Those with numbers
+in their name indicate the bitsize of the type (i.e. how many bits are needed
+to represent a single value in memory).  Some types, such as ``int`` and
+``intp``, have differing bitsizes, dependent on the platforms (e.g. 32-bit
+vs. 64-bit machines).  This should be taken into account when interfacing
+with low-level code (such as C or Fortran) where the raw memory is addressed.
+
+Data-types can be used as functions to convert python numbers to array scalars
+(see the array scalar section for an explanation), python sequences of numbers
+to arrays of that type, or as arguments to the dtype keyword that many numpy
+functions or methods accept. Some examples::
+
+    >>> import numpy as np
+    >>> x = np.float32(1.0)
+    >>> x
+    1.0
+    >>> y = np.int_([1,2,4])
+    >>> y
+    array([1, 2, 4])
+    >>> z = np.arange(3, dtype=np.uint8)
+    >>> z
+    array([0, 1, 2], dtype=uint8)
+
+Array types can also be referred to by character codes, mostly to retain
+backward compatibility with older packages such as Numeric.  Some
+documentation may still refer to these, for example::
+
+  >>> np.array([1, 2, 3], dtype='f')
+  array([ 1.,  2.,  3.], dtype=float32)
+
+We recommend using dtype objects instead.
+
+To convert the type of an array, use the .astype() method (preferred) or
+the type itself as a function. For example: ::
+
+    >>> z.astype(float)                 #doctest: +NORMALIZE_WHITESPACE
+    array([  0.,  1.,  2.])
+    >>> np.int8(z)
+    array([0, 1, 2], dtype=int8)
+
+Note that, above, we use the *Python* float object as a dtype.  NumPy knows
+that ``int`` refers to ``np.int_``, ``bool`` means ``np.bool_``,
+that ``float`` is ``np.float_`` and ``complex`` is ``np.complex_``.
+The other data-types do not have Python equivalents.
+
+To determine the type of an array, look at the dtype attribute::
+
+    >>> z.dtype
+    dtype('uint8')
+
+dtype objects also contain information about the type, such as its bit-width
+and its byte-order.  The data type can also be used indirectly to query
+properties of the type, such as whether it is an integer::
+
+    >>> d = np.dtype(int)
+    >>> d
+    dtype('int32')
+
+    >>> np.issubdtype(d, int)
+    True
+
+    >>> np.issubdtype(d, float)
+    False
+
+
+Array Scalars
+=============
+
+Numpy generally returns elements of arrays as array scalars (a scalar
+with an associated dtype).  Array scalars differ from Python scalars, but
+for the most part they can be used interchangeably (the primary
+exception is for versions of Python older than v2.x, where integer array
+scalars cannot act as indices for lists and tuples).  There are some
+exceptions, such as when code requires very specific attributes of a scalar
+or when it checks specifically whether a value is a Python scalar. Generally,
+problems are easily fixed by explicitly converting array scalars
+to Python scalars, using the corresponding Python type function
+(e.g., ``int``, ``float``, ``complex``, ``str``, ``unicode``).
+
+The primary advantage of using array scalars is that
+they preserve the array type (Python may not have a matching scalar type
+available, e.g. ``int16``).  Therefore, the use of array scalars ensures
+identical behaviour between arrays and scalars, irrespective of whether the
+value is inside an array or not.  NumPy scalars also have many of the same
+methods arrays do.
+
+Extended Precision
+==================
+
+Python's floating-point numbers are usually 64-bit floating-point numbers,
+nearly equivalent to ``np.float64``. In some unusual situations it may be
+useful to use floating-point numbers with more precision. Whether this
+is possible in numpy depends on the hardware and on the development
+environment: specifically, x86 machines provide hardware floating-point
+with 80-bit precision, and while most C compilers provide this as their
+``long double`` type, MSVC (standard for Windows builds) makes
+``long double`` identical to ``double`` (64 bits). Numpy makes the
+compiler's ``long double`` available as ``np.longdouble`` (and
+``np.clongdouble`` for the complex numbers). You can find out what your
+numpy provides with``np.finfo(np.longdouble)``.
+
+Numpy does not provide a dtype with more precision than C
+``long double``s; in particular, the 128-bit IEEE quad precision
+data type (FORTRAN's ``REAL*16``) is not available.
+
+For efficient memory alignment, ``np.longdouble`` is usually stored
+padded with zero bits, either to 96 or 128 bits. Which is more efficient
+depends on hardware and development environment; typically on 32-bit
+systems they are padded to 96 bits, while on 64-bit systems they are
+typically padded to 128 bits. ``np.longdouble`` is padded to the system
+default; ``np.float96`` and ``np.float128`` are provided for users who
+want specific padding. In spite of the names, ``np.float96`` and
+``np.float128`` provide only as much precision as ``np.longdouble``,
+that is, 80 bits on most x86 machines and 64 bits in standard
+Windows builds.
+
+Be warned that even if ``np.longdouble`` offers more precision than
+python ``float``, it is easy to lose that extra precision, since
+python often forces values to pass through ``float``. For example,
+the ``%`` formatting operator requires its arguments to be converted
+to standard python types, and it is therefore impossible to preserve
+extended precision even if many decimal places are requested. It can
+be useful to test your code with the value
+``1 + np.finfo(np.longdouble).eps``.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.py
new file mode 100644
index 0000000000..717914cda2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.py
@@ -0,0 +1,178 @@
+"""
+========================
+Broadcasting over arrays
+========================
+
+The term broadcasting describes how numpy treats arrays with different
+shapes during arithmetic operations. Subject to certain constraints,
+the smaller array is "broadcast" across the larger array so that they
+have compatible shapes. Broadcasting provides a means of vectorizing
+array operations so that looping occurs in C instead of Python. It does
+this without making needless copies of data and usually leads to
+efficient algorithm implementations. There are, however, cases where
+broadcasting is a bad idea because it leads to inefficient use of memory
+that slows computation.
+
+NumPy operations are usually done on pairs of arrays on an
+element-by-element basis.  In the simplest case, the two arrays must
+have exactly the same shape, as in the following example:
+
+  >>> a = np.array([1.0, 2.0, 3.0])
+  >>> b = np.array([2.0, 2.0, 2.0])
+  >>> a * b
+  array([ 2.,  4.,  6.])
+
+NumPy's broadcasting rule relaxes this constraint when the arrays'
+shapes meet certain constraints. The simplest broadcasting example occurs
+when an array and a scalar value are combined in an operation:
+
+>>> a = np.array([1.0, 2.0, 3.0])
+>>> b = 2.0
+>>> a * b
+array([ 2.,  4.,  6.])
+
+The result is equivalent to the previous example where ``b`` was an array.
+We can think of the scalar ``b`` being *stretched* during the arithmetic
+operation into an array with the same shape as ``a``. The new elements in
+``b`` are simply copies of the original scalar. The stretching analogy is
+only conceptual.  NumPy is smart enough to use the original scalar value
+without actually making copies, so that broadcasting operations are as
+memory and computationally efficient as possible.
+
+The code in the second example is more efficient than that in the first
+because broadcasting moves less memory around during the multiplication
+(``b`` is a scalar rather than an array).
+
+General Broadcasting Rules
+==========================
+When operating on two arrays, NumPy compares their shapes element-wise.
+It starts with the trailing dimensions, and works its way forward.  Two
+dimensions are compatible when
+
+1) they are equal, or
+2) one of them is 1
+
+If these conditions are not met, a
+``ValueError: frames are not aligned`` exception is thrown, indicating that
+the arrays have incompatible shapes. The size of the resulting array
+is the maximum size along each dimension of the input arrays.
+
+Arrays do not need to have the same *number* of dimensions.  For example,
+if you have a ``256x256x3`` array of RGB values, and you want to scale
+each color in the image by a different value, you can multiply the image
+by a one-dimensional array with 3 values. Lining up the sizes of the
+trailing axes of these arrays according to the broadcast rules, shows that
+they are compatible::
+
+  Image  (3d array): 256 x 256 x 3
+  Scale  (1d array):             3
+  Result (3d array): 256 x 256 x 3
+
+When either of the dimensions compared is one, the other is
+used.  In other words, dimensions with size 1 are stretched or "copied"
+to match the other.
+
+In the following example, both the ``A`` and ``B`` arrays have axes with
+length one that are expanded to a larger size during the broadcast
+operation::
+
+  A      (4d array):  8 x 1 x 6 x 1
+  B      (3d array):      7 x 1 x 5
+  Result (4d array):  8 x 7 x 6 x 5
+
+Here are some more examples::
+
+  A      (2d array):  5 x 4
+  B      (1d array):      1
+  Result (2d array):  5 x 4
+
+  A      (2d array):  5 x 4
+  B      (1d array):      4
+  Result (2d array):  5 x 4
+
+  A      (3d array):  15 x 3 x 5
+  B      (3d array):  15 x 1 x 5
+  Result (3d array):  15 x 3 x 5
+
+  A      (3d array):  15 x 3 x 5
+  B      (2d array):       3 x 5
+  Result (3d array):  15 x 3 x 5
+
+  A      (3d array):  15 x 3 x 5
+  B      (2d array):       3 x 1
+  Result (3d array):  15 x 3 x 5
+
+Here are examples of shapes that do not broadcast::
+
+  A      (1d array):  3
+  B      (1d array):  4 # trailing dimensions do not match
+
+  A      (2d array):      2 x 1
+  B      (3d array):  8 x 4 x 3 # second from last dimensions mismatched
+
+An example of broadcasting in practice::
+
+ >>> x = np.arange(4)
+ >>> xx = x.reshape(4,1)
+ >>> y = np.ones(5)
+ >>> z = np.ones((3,4))
+
+ >>> x.shape
+ (4,)
+
+ >>> y.shape
+ (5,)
+
+ >>> x + y
+ <type 'exceptions.ValueError'>: shape mismatch: objects cannot be broadcast to a single shape
+
+ >>> xx.shape
+ (4, 1)
+
+ >>> y.shape
+ (5,)
+
+ >>> (xx + y).shape
+ (4, 5)
+
+ >>> xx + y
+ array([[ 1.,  1.,  1.,  1.,  1.],
+        [ 2.,  2.,  2.,  2.,  2.],
+        [ 3.,  3.,  3.,  3.,  3.],
+        [ 4.,  4.,  4.,  4.,  4.]])
+
+ >>> x.shape
+ (4,)
+
+ >>> z.shape
+ (3, 4)
+
+ >>> (x + z).shape
+ (3, 4)
+
+ >>> x + z
+ array([[ 1.,  2.,  3.,  4.],
+        [ 1.,  2.,  3.,  4.],
+        [ 1.,  2.,  3.,  4.]])
+
+Broadcasting provides a convenient way of taking the outer product (or
+any other outer operation) of two arrays. The following example shows an
+outer addition operation of two 1-d arrays::
+
+  >>> a = np.array([0.0, 10.0, 20.0, 30.0])
+  >>> b = np.array([1.0, 2.0, 3.0])
+  >>> a[:, np.newaxis] + b
+  array([[  1.,   2.,   3.],
+         [ 11.,  12.,  13.],
+         [ 21.,  22.,  23.],
+         [ 31.,  32.,  33.]])
+
+Here the ``newaxis`` index operator inserts a new axis into ``a``,
+making it a two-dimensional ``4x1`` array.  Combining the ``4x1`` array
+with ``b``, which has shape ``(3,)``, yields a ``4x3`` array.
+
+See `this article <http://wiki.scipy.org/EricsBroadcastingDoc>`_
+for illustrations of broadcasting concepts.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.py
new file mode 100644
index 0000000000..59c0498789
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.py
@@ -0,0 +1,156 @@
+"""
+
+=============================
+ Byteswapping and byte order
+=============================
+
+Introduction to byte ordering and ndarrays
+==========================================
+
+The ``ndarray`` is an object that provide a python array interface to data
+in memory.
+
+It often happens that the memory that you want to view with an array is
+not of the same byte ordering as the computer on which you are running
+Python.
+
+For example, I might be working on a computer with a little-endian CPU -
+such as an Intel Pentium, but I have loaded some data from a file
+written by a computer that is big-endian.  Let's say I have loaded 4
+bytes from a file written by a Sun (big-endian) computer.  I know that
+these 4 bytes represent two 16-bit integers.  On a big-endian machine, a
+two-byte integer is stored with the Most Significant Byte (MSB) first,
+and then the Least Significant Byte (LSB). Thus the bytes are, in memory order:
+
+#. MSB integer 1
+#. LSB integer 1
+#. MSB integer 2
+#. LSB integer 2
+
+Let's say the two integers were in fact 1 and 770.  Because 770 = 256 *
+3 + 2, the 4 bytes in memory would contain respectively: 0, 1, 3, 2.
+The bytes I have loaded from the file would have these contents:
+
+>>> big_end_str = chr(0) + chr(1) + chr(3) + chr(2)
+>>> big_end_str
+'\\x00\\x01\\x03\\x02'
+
+We might want to use an ``ndarray`` to access these integers.  In that
+case, we can create an array around this memory, and tell numpy that
+there are two integers, and that they are 16 bit and big-endian:
+
+>>> import numpy as np
+>>> big_end_arr = np.ndarray(shape=(2,),dtype='>i2', buffer=big_end_str)
+>>> big_end_arr[0]
+1
+>>> big_end_arr[1]
+770
+
+Note the array ``dtype`` above of ``>i2``.  The ``>`` means 'big-endian'
+(``<`` is little-endian) and ``i2`` means 'signed 2-byte integer'.  For
+example, if our data represented a single unsigned 4-byte little-endian
+integer, the dtype string would be ``<u4``.
+
+In fact, why don't we try that?
+
+>>> little_end_u4 = np.ndarray(shape=(1,),dtype='<u4', buffer=big_end_str)
+>>> little_end_u4[0] == 1 * 256**1 + 3 * 256**2 + 2 * 256**3
+True
+
+Returning to our ``big_end_arr`` - in this case our underlying data is
+big-endian (data endianness) and we've set the dtype to match (the dtype
+is also big-endian).  However, sometimes you need to flip these around.
+
+.. warning::
+
+    Scalars currently do not include byte order information, so extracting
+    a scalar from an array will return an integer in native byte order.
+    Hence:
+
+    >>> big_end_arr[0].dtype.byteorder == little_end_u4[0].dtype.byteorder
+    True
+
+Changing byte ordering
+======================
+
+As you can imagine from the introduction, there are two ways you can
+affect the relationship between the byte ordering of the array and the
+underlying memory it is looking at:
+
+* Change the byte-ordering information in the array dtype so that it
+  interprets the undelying data as being in a different byte order.
+  This is the role of ``arr.newbyteorder()``
+* Change the byte-ordering of the underlying data, leaving the dtype
+  interpretation as it was.  This is what ``arr.byteswap()`` does.
+
+The common situations in which you need to change byte ordering are:
+
+#. Your data and dtype endianess don't match, and you want to change
+   the dtype so that it matches the data.
+#. Your data and dtype endianess don't match, and you want to swap the
+   data so that they match the dtype
+#. Your data and dtype endianess match, but you want the data swapped
+   and the dtype to reflect this
+
+Data and dtype endianness don't match, change dtype to match data
+-----------------------------------------------------------------
+
+We make something where they don't match:
+
+>>> wrong_end_dtype_arr = np.ndarray(shape=(2,),dtype='<i2', buffer=big_end_str)
+>>> wrong_end_dtype_arr[0]
+256
+
+The obvious fix for this situation is to change the dtype so it gives
+the correct endianness:
+
+>>> fixed_end_dtype_arr = wrong_end_dtype_arr.newbyteorder()
+>>> fixed_end_dtype_arr[0]
+1
+
+Note the the array has not changed in memory:
+
+>>> fixed_end_dtype_arr.tobytes() == big_end_str
+True
+
+Data and type endianness don't match, change data to match dtype
+----------------------------------------------------------------
+
+You might want to do this if you need the data in memory to be a certain
+ordering.  For example you might be writing the memory out to a file
+that needs a certain byte ordering.
+
+>>> fixed_end_mem_arr = wrong_end_dtype_arr.byteswap()
+>>> fixed_end_mem_arr[0]
+1
+
+Now the array *has* changed in memory:
+
+>>> fixed_end_mem_arr.tobytes() == big_end_str
+False
+
+Data and dtype endianness match, swap data and dtype
+----------------------------------------------------
+
+You may have a correctly specified array dtype, but you need the array
+to have the opposite byte order in memory, and you want the dtype to
+match so the array values make sense.  In this case you just do both of
+the previous operations:
+
+>>> swapped_end_arr = big_end_arr.byteswap().newbyteorder()
+>>> swapped_end_arr[0]
+1
+>>> swapped_end_arr.tobytes() == big_end_str
+False
+
+An easier way of casting the data to a specific dtype and byte ordering
+can be achieved with the ndarray astype method:
+
+>>> swapped_end_arr = big_end_arr.astype('<i2')
+>>> swapped_end_arr[0]
+1
+>>> swapped_end_arr.tobytes() == big_end_str
+False
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/constants.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/constants.py
new file mode 100644
index 0000000000..36f94d3070
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/constants.py
@@ -0,0 +1,393 @@
+"""
+=========
+Constants
+=========
+
+Numpy includes several constants:
+
+%(constant_list)s
+"""
+#
+# Note: the docstring is autogenerated.
+#
+from __future__ import division, absolute_import, print_function
+
+import textwrap, re
+
+# Maintain same format as in numpy.add_newdocs
+constants = []
+def add_newdoc(module, name, doc):
+    constants.append((name, doc))
+
+add_newdoc('numpy', 'Inf',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'Infinity',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'NAN',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    `NaN` and `NAN` are equivalent definitions of `nan`. Please use
+    `nan` instead of `NAN`.
+
+    See Also
+    --------
+    nan
+
+    """)
+
+add_newdoc('numpy', 'NINF',
+    """
+    IEEE 754 floating point representation of negative infinity.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of negative infinity.
+
+    See Also
+    --------
+    isinf : Shows which elements are positive or negative infinity
+
+    isposinf : Shows which elements are positive infinity
+
+    isneginf : Shows which elements are negative infinity
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Also that positive infinity is not equivalent to negative infinity. But
+    infinity is equivalent to positive infinity.
+
+    Examples
+    --------
+    >>> np.NINF
+    -inf
+    >>> np.log(0)
+    -inf
+
+    """)
+
+add_newdoc('numpy', 'NZERO',
+    """
+    IEEE 754 floating point representation of negative zero.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of negative zero.
+
+    See Also
+    --------
+    PZERO : Defines positive zero.
+
+    isinf : Shows which elements are positive or negative infinity.
+
+    isposinf : Shows which elements are positive infinity.
+
+    isneginf : Shows which elements are negative infinity.
+
+    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.
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). Negative zero is considered to be a finite number.
+
+    Examples
+    --------
+    >>> np.NZERO
+    -0.0
+    >>> np.PZERO
+    0.0
+
+    >>> np.isfinite([np.NZERO])
+    array([ True], dtype=bool)
+    >>> np.isnan([np.NZERO])
+    array([False], dtype=bool)
+    >>> np.isinf([np.NZERO])
+    array([False], dtype=bool)
+
+    """)
+
+add_newdoc('numpy', 'NaN',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    `NaN` and `NAN` are equivalent definitions of `nan`. Please use
+    `nan` instead of `NaN`.
+
+    See Also
+    --------
+    nan
+
+    """)
+
+add_newdoc('numpy', 'PINF',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'PZERO',
+    """
+    IEEE 754 floating point representation of positive zero.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of positive zero.
+
+    See Also
+    --------
+    NZERO : Defines negative zero.
+
+    isinf : Shows which elements are positive or negative infinity.
+
+    isposinf : Shows which elements are positive infinity.
+
+    isneginf : Shows which elements are negative infinity.
+
+    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.
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). Positive zero is considered to be a finite number.
+
+    Examples
+    --------
+    >>> np.PZERO
+    0.0
+    >>> np.NZERO
+    -0.0
+
+    >>> np.isfinite([np.PZERO])
+    array([ True], dtype=bool)
+    >>> np.isnan([np.PZERO])
+    array([False], dtype=bool)
+    >>> np.isinf([np.PZERO])
+    array([False], dtype=bool)
+
+    """)
+
+add_newdoc('numpy', 'e',
+    """
+    Euler's constant, base of natural logarithms, Napier's constant.
+
+    ``e = 2.71828182845904523536028747135266249775724709369995...``
+
+    See Also
+    --------
+    exp : Exponential function
+    log : Natural logarithm
+
+    References
+    ----------
+    .. [1] http://en.wikipedia.org/wiki/Napier_constant
+
+    """)
+
+add_newdoc('numpy', 'inf',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Returns
+    -------
+    y : float
+        A floating point representation of positive infinity.
+
+    See Also
+    --------
+    isinf : Shows which elements are positive or negative infinity
+
+    isposinf : Shows which elements are positive infinity
+
+    isneginf : Shows which elements are negative infinity
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Also that positive infinity is not equivalent to negative infinity. But
+    infinity is equivalent to positive infinity.
+
+    `Inf`, `Infinity`, `PINF` and `infty` are aliases for `inf`.
+
+    Examples
+    --------
+    >>> np.inf
+    inf
+    >>> np.array([1]) / 0.
+    array([ Inf])
+
+    """)
+
+add_newdoc('numpy', 'infty',
+    """
+    IEEE 754 floating point representation of (positive) infinity.
+
+    Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for
+    `inf`. For more details, see `inf`.
+
+    See Also
+    --------
+    inf
+
+    """)
+
+add_newdoc('numpy', 'nan',
+    """
+    IEEE 754 floating point representation of Not a Number (NaN).
+
+    Returns
+    -------
+    y : A floating point representation of Not a Number.
+
+    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)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+
+    `NaN` and `NAN` are aliases of `nan`.
+
+    Examples
+    --------
+    >>> np.nan
+    nan
+    >>> np.log(-1)
+    nan
+    >>> np.log([-1, 1, 2])
+    array([        NaN,  0.        ,  0.69314718])
+
+    """)
+
+add_newdoc('numpy', 'newaxis',
+    """
+    A convenient alias for None, useful for indexing arrays.
+
+    See Also
+    --------
+    `numpy.doc.indexing`
+
+    Examples
+    --------
+    >>> newaxis is None
+    True
+    >>> x = np.arange(3)
+    >>> x
+    array([0, 1, 2])
+    >>> x[:, newaxis]
+    array([[0],
+    [1],
+    [2]])
+    >>> x[:, newaxis, newaxis]
+    array([[[0]],
+    [[1]],
+    [[2]]])
+    >>> x[:, newaxis] * x
+    array([[0, 0, 0],
+    [0, 1, 2],
+    [0, 2, 4]])
+
+    Outer product, same as ``outer(x, y)``:
+
+    >>> y = np.arange(3, 6)
+    >>> x[:, newaxis] * y
+    array([[ 0,  0,  0],
+    [ 3,  4,  5],
+    [ 6,  8, 10]])
+
+    ``x[newaxis, :]`` is equivalent to ``x[newaxis]`` and ``x[None]``:
+
+    >>> x[newaxis, :].shape
+    (1, 3)
+    >>> x[newaxis].shape
+    (1, 3)
+    >>> x[None].shape
+    (1, 3)
+    >>> x[:, newaxis].shape
+    (3, 1)
+
+    """)
+
+if __doc__:
+    constants_str = []
+    constants.sort()
+    for name, doc in constants:
+        s = textwrap.dedent(doc).replace("\n", "\n    ")
+
+        # Replace sections by rubrics
+        lines = s.split("\n")
+        new_lines = []
+        for line in lines:
+            m = re.match(r'^(\s+)[-=]+\s*$', line)
+            if m and new_lines:
+                prev = textwrap.dedent(new_lines.pop())
+                new_lines.append('%s.. rubric:: %s' % (m.group(1), prev))
+                new_lines.append('')
+            else:
+                new_lines.append(line)
+        s = "\n".join(new_lines)
+
+        # Done.
+        constants_str.append(""".. const:: %s\n    %s""" % (name, s))
+    constants_str = "\n".join(constants_str)
+
+    __doc__ = __doc__ % dict(constant_list=constants_str)
+    del constants_str, name, doc
+    del line, lines, new_lines, m, s, prev
+
+del constants, add_newdoc
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/creation.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/creation.py
new file mode 100644
index 0000000000..b10d45d481
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/creation.py
@@ -0,0 +1,144 @@
+"""
+==============
+Array Creation
+==============
+
+Introduction
+============
+
+There are 5 general mechanisms for creating arrays:
+
+1) Conversion from other Python structures (e.g., lists, tuples)
+2) Intrinsic numpy array array creation objects (e.g., arange, ones, zeros,
+   etc.)
+3) Reading arrays from disk, either from standard or custom formats
+4) Creating arrays from raw bytes through the use of strings or buffers
+5) Use of special library functions (e.g., random)
+
+This section will not cover means of replicating, joining, or otherwise
+expanding or mutating existing arrays. Nor will it cover creating object
+arrays or structured arrays. Both of those are covered in their own sections.
+
+Converting Python array_like Objects to Numpy Arrays
+====================================================
+
+In general, numerical data arranged in an array-like structure in Python can
+be converted to arrays through the use of the array() function. The most
+obvious examples are lists and tuples. See the documentation for array() for
+details for its use. Some objects may support the array-protocol and allow
+conversion to arrays this way. A simple way to find out if the object can be
+converted to a numpy array using array() is simply to try it interactively and
+see if it works! (The Python Way).
+
+Examples: ::
+
+ >>> x = np.array([2,3,1,0])
+ >>> x = np.array([2, 3, 1, 0])
+ >>> x = np.array([[1,2.0],[0,0],(1+1j,3.)]) # note mix of tuple and lists,
+     and types
+ >>> x = np.array([[ 1.+0.j, 2.+0.j], [ 0.+0.j, 0.+0.j], [ 1.+1.j, 3.+0.j]])
+
+Intrinsic Numpy Array Creation
+==============================
+
+Numpy has built-in functions for creating arrays from scratch:
+
+zeros(shape) will create an array filled with 0 values with the specified
+shape. The default dtype is float64.
+
+``>>> np.zeros((2, 3))
+array([[ 0., 0., 0.], [ 0., 0., 0.]])``
+
+ones(shape) will create an array filled with 1 values. It is identical to
+zeros in all other respects.
+
+arange() will create arrays with regularly incrementing values. Check the
+docstring for complete information on the various ways it can be used. A few
+examples will be given here: ::
+
+ >>> np.arange(10)
+ array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+ >>> np.arange(2, 10, dtype=np.float)
+ array([ 2., 3., 4., 5., 6., 7., 8., 9.])
+ >>> np.arange(2, 3, 0.1)
+ array([ 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9])
+
+Note that there are some subtleties regarding the last usage that the user
+should be aware of that are described in the arange docstring.
+
+linspace() will create arrays with a specified number of elements, and
+spaced equally between the specified beginning and end values. For
+example: ::
+
+ >>> np.linspace(1., 4., 6)
+ array([ 1. ,  1.6,  2.2,  2.8,  3.4,  4. ])
+
+The advantage of this creation function is that one can guarantee the
+number of elements and the starting and end point, which arange()
+generally will not do for arbitrary start, stop, and step values.
+
+indices() will create a set of arrays (stacked as a one-higher dimensioned
+array), one per dimension with each representing variation in that dimension.
+An example illustrates much better than a verbal description: ::
+
+ >>> np.indices((3,3))
+ array([[[0, 0, 0], [1, 1, 1], [2, 2, 2]], [[0, 1, 2], [0, 1, 2], [0, 1, 2]]])
+
+This is particularly useful for evaluating functions of multiple dimensions on
+a regular grid.
+
+Reading Arrays From Disk
+========================
+
+This is presumably the most common case of large array creation. The details,
+of course, depend greatly on the format of data on disk and so this section
+can only give general pointers on how to handle various formats.
+
+Standard Binary Formats
+-----------------------
+
+Various fields have standard formats for array data. The following lists the
+ones with known python libraries to read them and return numpy arrays (there
+may be others for which it is possible to read and convert to numpy arrays so
+check the last section as well)
+::
+
+ HDF5: PyTables
+ FITS: PyFITS
+
+Examples of formats that cannot be read directly but for which it is not hard to
+convert are those formats supported by libraries like PIL (able to read and
+write many image formats such as jpg, png, etc).
+
+Common ASCII Formats
+------------------------
+
+Comma Separated Value files (CSV) are widely used (and an export and import
+option for programs like Excel). There are a number of ways of reading these
+files in Python. There are CSV functions in Python and functions in pylab
+(part of matplotlib).
+
+More generic ascii files can be read using the io package in scipy.
+
+Custom Binary Formats
+---------------------
+
+There are a variety of approaches one can use. If the file has a relatively
+simple format then one can write a simple I/O library and use the numpy
+fromfile() function and .tofile() method to read and write numpy arrays
+directly (mind your byteorder though!) If a good C or C++ library exists that
+read the data, one can wrap that library with a variety of techniques though
+that certainly is much more work and requires significantly more advanced
+knowledge to interface with C or C++.
+
+Use of Special Libraries
+------------------------
+
+There are libraries that can be used to generate arrays for special purposes
+and it isn't possible to enumerate all of them. The most common uses are use
+of the many array generation functions in random that can generate arrays of
+random values, and some utility functions to generate special matrices (e.g.
+diagonal).
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/glossary.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/glossary.py
new file mode 100644
index 0000000000..4a32384913
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/glossary.py
@@ -0,0 +1,423 @@
+"""
+========
+Glossary
+========
+
+.. glossary::
+
+   along an axis
+       Axes are defined for arrays with more than one dimension.  A
+       2-dimensional array has two corresponding axes: the first running
+       vertically downwards across rows (axis 0), and the second running
+       horizontally across columns (axis 1).
+
+       Many operation can take place along one of these axes.  For example,
+       we can sum each row of an array, in which case we operate along
+       columns, or axis 1::
+
+         >>> x = np.arange(12).reshape((3,4))
+
+         >>> x
+         array([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+
+         >>> x.sum(axis=1)
+         array([ 6, 22, 38])
+
+   array
+       A homogeneous container of numerical elements.  Each element in the
+       array occupies a fixed amount of memory (hence homogeneous), and
+       can be a numerical element of a single type (such as float, int
+       or complex) or a combination (such as ``(float, int, float)``).  Each
+       array has an associated data-type (or ``dtype``), which describes
+       the numerical type of its elements::
+
+         >>> x = np.array([1, 2, 3], float)
+
+         >>> x
+         array([ 1.,  2.,  3.])
+
+         >>> x.dtype # floating point number, 64 bits of memory per element
+         dtype('float64')
+
+
+         # More complicated data type: each array element is a combination of
+         # and integer and a floating point number
+         >>> np.array([(1, 2.0), (3, 4.0)], dtype=[('x', int), ('y', float)])
+         array([(1, 2.0), (3, 4.0)],
+               dtype=[('x', '<i4'), ('y', '<f8')])
+
+       Fast element-wise operations, called `ufuncs`_, operate on arrays.
+
+   array_like
+       Any sequence that can be interpreted as an ndarray.  This includes
+       nested lists, tuples, scalars and existing arrays.
+
+   attribute
+       A property of an object that can be accessed using ``obj.attribute``,
+       e.g., ``shape`` is an attribute of an array::
+
+         >>> x = np.array([1, 2, 3])
+         >>> x.shape
+         (3,)
+
+   BLAS
+       `Basic Linear Algebra Subprograms <http://en.wikipedia.org/wiki/BLAS>`_
+
+   broadcast
+       NumPy can do operations on arrays whose shapes are mismatched::
+
+         >>> x = np.array([1, 2])
+         >>> y = np.array([[3], [4]])
+
+         >>> x
+         array([1, 2])
+
+         >>> y
+         array([[3],
+                [4]])
+
+         >>> x + y
+         array([[4, 5],
+                [5, 6]])
+
+       See `doc.broadcasting`_ for more information.
+
+   C order
+       See `row-major`
+
+   column-major
+       A way to represent items in a N-dimensional array in the 1-dimensional
+       computer memory. In column-major order, the leftmost index "varies the
+       fastest": for example the array::
+
+            [[1, 2, 3],
+             [4, 5, 6]]
+
+       is represented in the column-major order as::
+
+           [1, 4, 2, 5, 3, 6]
+
+       Column-major order is also known as the Fortran order, as the Fortran
+       programming language uses it.
+
+   decorator
+       An operator that transforms a function.  For example, a ``log``
+       decorator may be defined to print debugging information upon
+       function execution::
+
+         >>> def log(f):
+         ...     def new_logging_func(*args, **kwargs):
+         ...         print("Logging call with parameters:", args, kwargs)
+         ...         return f(*args, **kwargs)
+         ...
+         ...     return new_logging_func
+
+       Now, when we define a function, we can "decorate" it using ``log``::
+
+         >>> @log
+         ... def add(a, b):
+         ...     return a + b
+
+       Calling ``add`` then yields:
+
+       >>> add(1, 2)
+       Logging call with parameters: (1, 2) {}
+       3
+
+   dictionary
+       Resembling a language dictionary, which provides a mapping between
+       words and descriptions thereof, a Python dictionary is a mapping
+       between two objects::
+
+         >>> x = {1: 'one', 'two': [1, 2]}
+
+       Here, `x` is a dictionary mapping keys to values, in this case
+       the integer 1 to the string "one", and the string "two" to
+       the list ``[1, 2]``.  The values may be accessed using their
+       corresponding keys::
+
+         >>> x[1]
+         'one'
+
+         >>> x['two']
+         [1, 2]
+
+       Note that dictionaries are not stored in any specific order.  Also,
+       most mutable (see *immutable* below) objects, such as lists, may not
+       be used as keys.
+
+       For more information on dictionaries, read the
+       `Python tutorial <http://docs.python.org/tut>`_.
+
+   Fortran order
+       See `column-major`
+
+   flattened
+       Collapsed to a one-dimensional array. See `ndarray.flatten`_ for details.
+
+   immutable
+       An object that cannot be modified after execution is called
+       immutable.  Two common examples are strings and tuples.
+
+   instance
+       A class definition gives the blueprint for constructing an object::
+
+         >>> class House(object):
+         ...     wall_colour = 'white'
+
+       Yet, we have to *build* a house before it exists::
+
+         >>> h = House() # build a house
+
+       Now, ``h`` is called a ``House`` instance.  An instance is therefore
+       a specific realisation of a class.
+
+   iterable
+       A sequence that allows "walking" (iterating) over items, typically
+       using a loop such as::
+
+         >>> x = [1, 2, 3]
+         >>> [item**2 for item in x]
+         [1, 4, 9]
+
+       It is often used in combintion with ``enumerate``::
+         >>> keys = ['a','b','c']
+         >>> for n, k in enumerate(keys):
+         ...     print("Key %d: %s" % (n, k))
+         ...
+         Key 0: a
+         Key 1: b
+         Key 2: c
+
+   list
+       A Python container that can hold any number of objects or items.
+       The items do not have to be of the same type, and can even be
+       lists themselves::
+
+         >>> x = [2, 2.0, "two", [2, 2.0]]
+
+       The list `x` contains 4 items, each which can be accessed individually::
+
+         >>> x[2] # the string 'two'
+         'two'
+
+         >>> x[3] # a list, containing an integer 2 and a float 2.0
+         [2, 2.0]
+
+       It is also possible to select more than one item at a time,
+       using *slicing*::
+
+         >>> x[0:2] # or, equivalently, x[:2]
+         [2, 2.0]
+
+       In code, arrays are often conveniently expressed as nested lists::
+
+
+         >>> np.array([[1, 2], [3, 4]])
+         array([[1, 2],
+                [3, 4]])
+
+       For more information, read the section on lists in the `Python
+       tutorial <http://docs.python.org/tut>`_.  For a mapping
+       type (key-value), see *dictionary*.
+
+   mask
+       A boolean array, used to select only certain elements for an operation::
+
+         >>> x = np.arange(5)
+         >>> x
+         array([0, 1, 2, 3, 4])
+
+         >>> mask = (x > 2)
+         >>> mask
+         array([False, False, False, True,  True], dtype=bool)
+
+         >>> x[mask] = -1
+         >>> x
+         array([ 0,  1,  2,  -1, -1])
+
+   masked array
+       Array that suppressed values indicated by a mask::
+
+         >>> x = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True])
+         >>> x
+         masked_array(data = [-- 2.0 --],
+                      mask = [ True False  True],
+                fill_value = 1e+20)
+         <BLANKLINE>
+
+         >>> x + [1, 2, 3]
+         masked_array(data = [-- 4.0 --],
+                      mask = [ True False  True],
+                fill_value = 1e+20)
+         <BLANKLINE>
+
+
+       Masked arrays are often used when operating on arrays containing
+       missing or invalid entries.
+
+   matrix
+       A 2-dimensional ndarray that preserves its two-dimensional nature
+       throughout operations.  It has certain special operations, such as ``*``
+       (matrix multiplication) and ``**`` (matrix power), defined::
+
+         >>> x = np.mat([[1, 2], [3, 4]])
+         >>> x
+         matrix([[1, 2],
+                 [3, 4]])
+
+         >>> x**2
+         matrix([[ 7, 10],
+               [15, 22]])
+
+   method
+       A function associated with an object.  For example, each ndarray has a
+       method called ``repeat``::
+
+         >>> x = np.array([1, 2, 3])
+         >>> x.repeat(2)
+         array([1, 1, 2, 2, 3, 3])
+
+   ndarray
+       See *array*.
+
+   record array
+       An `ndarray`_ with `structured data type`_ which has been subclassed as
+       np.recarray and whose dtype is of type np.record, making the
+       fields of its data type to be accessible by attribute.
+
+   reference
+       If ``a`` is a reference to ``b``, then ``(a is b) == True``.  Therefore,
+       ``a`` and ``b`` are different names for the same Python object.
+
+   row-major
+       A way to represent items in a N-dimensional array in the 1-dimensional
+       computer memory. In row-major order, the rightmost index "varies
+       the fastest": for example the array::
+
+            [[1, 2, 3],
+             [4, 5, 6]]
+
+       is represented in the row-major order as::
+
+           [1, 2, 3, 4, 5, 6]
+
+       Row-major order is also known as the C order, as the C programming
+       language uses it. New Numpy arrays are by default in row-major order.
+
+   self
+       Often seen in method signatures, ``self`` refers to the instance
+       of the associated class.  For example:
+
+         >>> class Paintbrush(object):
+         ...     color = 'blue'
+         ...
+         ...     def paint(self):
+         ...         print("Painting the city %s!" % self.color)
+         ...
+         >>> p = Paintbrush()
+         >>> p.color = 'red'
+         >>> p.paint() # self refers to 'p'
+         Painting the city red!
+
+   slice
+       Used to select only certain elements from a sequence::
+
+         >>> x = range(5)
+         >>> x
+         [0, 1, 2, 3, 4]
+
+         >>> x[1:3] # slice from 1 to 3 (excluding 3 itself)
+         [1, 2]
+
+         >>> x[1:5:2] # slice from 1 to 5, but skipping every second element
+         [1, 3]
+
+         >>> x[::-1] # slice a sequence in reverse
+         [4, 3, 2, 1, 0]
+
+       Arrays may have more than one dimension, each which can be sliced
+       individually::
+
+         >>> x = np.array([[1, 2], [3, 4]])
+         >>> x
+         array([[1, 2],
+                [3, 4]])
+
+         >>> x[:, 1]
+         array([2, 4])
+   
+   structured data type
+       A data type composed of other datatypes
+   
+   tuple
+       A sequence that may contain a variable number of types of any
+       kind.  A tuple is immutable, i.e., once constructed it cannot be
+       changed.  Similar to a list, it can be indexed and sliced::
+
+         >>> x = (1, 'one', [1, 2])
+         >>> x
+         (1, 'one', [1, 2])
+
+         >>> x[0]
+         1
+
+         >>> x[:2]
+         (1, 'one')
+
+       A useful concept is "tuple unpacking", which allows variables to
+       be assigned to the contents of a tuple::
+
+         >>> x, y = (1, 2)
+         >>> x, y = 1, 2
+
+       This is often used when a function returns multiple values:
+
+         >>> def return_many():
+         ...     return 1, 'alpha', None
+
+         >>> a, b, c = return_many()
+         >>> a, b, c
+         (1, 'alpha', None)
+
+         >>> a
+         1
+         >>> b
+         'alpha'
+
+   ufunc
+       Universal function.  A fast element-wise array operation.  Examples include
+       ``add``, ``sin`` and ``logical_or``.
+
+   view
+       An array that does not own its data, but refers to another array's
+       data instead.  For example, we may create a view that only shows
+       every second element of another array::
+
+         >>> x = np.arange(5)
+         >>> x
+         array([0, 1, 2, 3, 4])
+
+         >>> y = x[::2]
+         >>> y
+         array([0, 2, 4])
+
+         >>> x[0] = 3 # changing x changes y as well, since y is a view on x
+         >>> y
+         array([3, 2, 4])
+
+   wrapper
+       Python is a high-level (highly abstracted, or English-like) language.
+       This abstraction comes at a price in execution speed, and sometimes
+       it becomes necessary to use lower level languages to do fast
+       computations.  A wrapper is code that provides a bridge between
+       high and the low level languages, allowing, e.g., Python to execute
+       code written in C or Fortran.
+
+       Examples include ctypes, SWIG and Cython (which wraps C and C++)
+       and f2py (which wraps Fortran).
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/indexing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/indexing.py
new file mode 100644
index 0000000000..9e9f0a10cd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/indexing.py
@@ -0,0 +1,439 @@
+"""==============
+Array indexing
+==============
+
+Array indexing refers to any use of the square brackets ([]) to index
+array values. There are many options to indexing, which give numpy
+indexing great power, but with power comes some complexity and the
+potential for confusion. This section is just an overview of the
+various options and issues related to indexing. Aside from single
+element indexing, the details on most of these options are to be
+found in related sections.
+
+Assignment vs referencing
+=========================
+
+Most of the following examples show the use of indexing when
+referencing data in an array. The examples work just as well
+when assigning to an array. See the section at the end for
+specific examples and explanations on how assignments work.
+
+Single element indexing
+=======================
+
+Single element indexing for a 1-D array is what one expects. It work
+exactly like that for other standard Python sequences. It is 0-based,
+and accepts negative indices for indexing from the end of the array. ::
+
+    >>> x = np.arange(10)
+    >>> x[2]
+    2
+    >>> x[-2]
+    8
+
+Unlike lists and tuples, numpy arrays support multidimensional indexing
+for multidimensional arrays. That means that it is not necessary to
+separate each dimension's index into its own set of square brackets. ::
+
+    >>> x.shape = (2,5) # now x is 2-dimensional
+    >>> x[1,3]
+    8
+    >>> x[1,-1]
+    9
+
+Note that if one indexes a multidimensional array with fewer indices
+than dimensions, one gets a subdimensional array. For example: ::
+
+    >>> x[0]
+    array([0, 1, 2, 3, 4])
+
+That is, each index specified selects the array corresponding to the
+rest of the dimensions selected. In the above example, choosing 0
+means that the remaining dimension of length 5 is being left unspecified,
+and that what is returned is an array of that dimensionality and size.
+It must be noted that the returned array is not a copy of the original,
+but points to the same values in memory as does the original array.
+In  this case, the 1-D array at the first position (0) is returned.
+So using a single index on the returned array, results in a single
+element being returned. That is: ::
+
+    >>> x[0][2]
+    2
+
+So note that ``x[0,2] = x[0][2]`` though the second case is more
+inefficient as a new temporary array is created after the first index
+that is subsequently indexed by 2.
+
+Note to those used to IDL or Fortran memory order as it relates to
+indexing.  Numpy uses C-order indexing. That means that the last
+index usually represents the most rapidly changing memory location,
+unlike Fortran or IDL, where the first index represents the most
+rapidly changing location in memory. This difference represents a
+great potential for confusion.
+
+Other indexing options
+======================
+
+It is possible to slice and stride arrays to extract arrays of the
+same number of dimensions, but of different sizes than the original.
+The slicing and striding works exactly the same way it does for lists
+and tuples except that they can be applied to multiple dimensions as
+well. A few examples illustrates best: ::
+
+ >>> x = np.arange(10)
+ >>> x[2:5]
+ array([2, 3, 4])
+ >>> x[:-7]
+ array([0, 1, 2])
+ >>> x[1:7:2]
+ array([1, 3, 5])
+ >>> y = np.arange(35).reshape(5,7)
+ >>> y[1:5:2,::3]
+ array([[ 7, 10, 13],
+        [21, 24, 27]])
+
+Note that slices of arrays do not copy the internal array data but
+also produce new views of the original data.
+
+It is possible to index arrays with other arrays for the purposes of
+selecting lists of values out of arrays into new arrays. There are
+two different ways of accomplishing this. One uses one or more arrays
+of index values. The other involves giving a boolean array of the proper
+shape to indicate the values to be selected. Index arrays are a very
+powerful tool that allow one to avoid looping over individual elements in
+arrays and thus greatly improve performance.
+
+It is possible to use special features to effectively increase the
+number of dimensions in an array through indexing so the resulting
+array aquires the shape needed for use in an expression or with a
+specific function.
+
+Index arrays
+============
+
+Numpy arrays may be indexed with other arrays (or any other sequence-
+like object that can be converted to an array, such as lists, with the
+exception of tuples; see the end of this document for why this is). The
+use of index arrays ranges from simple, straightforward cases to
+complex, hard-to-understand cases. For all cases of index arrays, what
+is returned is a copy of the original data, not a view as one gets for
+slices.
+
+Index arrays must be of integer type. Each value in the array indicates
+which value in the array to use in place of the index. To illustrate: ::
+
+ >>> x = np.arange(10,1,-1)
+ >>> x
+ array([10,  9,  8,  7,  6,  5,  4,  3,  2])
+ >>> x[np.array([3, 3, 1, 8])]
+ array([7, 7, 9, 2])
+
+
+The index array consisting of the values 3, 3, 1 and 8 correspondingly
+create an array of length 4 (same as the index array) where each index
+is replaced by the value the index array has in the array being indexed.
+
+Negative values are permitted and work as they do with single indices
+or slices: ::
+
+ >>> x[np.array([3,3,-3,8])]
+ array([7, 7, 4, 2])
+
+It is an error to have index values out of bounds: ::
+
+ >>> x[np.array([3, 3, 20, 8])]
+ <type 'exceptions.IndexError'>: index 20 out of bounds 0<=index<9
+
+Generally speaking, what is returned when index arrays are used is
+an array with the same shape as the index array, but with the type
+and values of the array being indexed. As an example, we can use a
+multidimensional index array instead: ::
+
+ >>> x[np.array([[1,1],[2,3]])]
+ array([[9, 9],
+        [8, 7]])
+
+Indexing Multi-dimensional arrays
+=================================
+
+Things become more complex when multidimensional arrays are indexed,
+particularly with multidimensional index arrays. These tend to be
+more unusal uses, but theyare permitted, and they are useful for some
+problems. We'll  start with thesimplest multidimensional case (using
+the array y from the previous examples): ::
+
+ >>> y[np.array([0,2,4]), np.array([0,1,2])]
+ array([ 0, 15, 30])
+
+In this case, if the index arrays have a matching shape, and there is
+an index array for each dimension of the array being indexed, the
+resultant array has the same shape as the index arrays, and the values
+correspond to the index set for each position in the index arrays. In
+this example, the first index value is 0 for both index arrays, and
+thus the first value of the resultant array is y[0,0]. The next value
+is y[2,1], and the last is y[4,2].
+
+If the index arrays do not have the same shape, there is an attempt to
+broadcast them to the same shape.  If they cannot be broadcast to the
+same shape, an exception is raised: ::
+
+ >>> y[np.array([0,2,4]), np.array([0,1])]
+ <type 'exceptions.ValueError'>: shape mismatch: objects cannot be
+ broadcast to a single shape
+
+The broadcasting mechanism permits index arrays to be combined with
+scalars for other indices. The effect is that the scalar value is used
+for all the corresponding values of the index arrays: ::
+
+ >>> y[np.array([0,2,4]), 1]
+ array([ 1, 15, 29])
+
+Jumping to the next level of complexity, it is possible to only
+partially index an array with index arrays. It takes a bit of thought
+to understand what happens in such cases. For example if we just use
+one index array with y: ::
+
+ >>> y[np.array([0,2,4])]
+ array([[ 0,  1,  2,  3,  4,  5,  6],
+        [14, 15, 16, 17, 18, 19, 20],
+        [28, 29, 30, 31, 32, 33, 34]])
+
+What results is the construction of a new array where each value of
+the index array selects one row from the array being indexed and the
+resultant array has the resulting shape (size of row, number index
+elements).
+
+An example of where this may be useful is for a color lookup table
+where we want to map the values of an image into RGB triples for
+display. The lookup table could have a shape (nlookup, 3). Indexing
+such an array with an image with shape (ny, nx) with dtype=np.uint8
+(or any integer type so long as values are with the bounds of the
+lookup table) will result in an array of shape (ny, nx, 3) where a
+triple of RGB values is associated with each pixel location.
+
+In general, the shape of the resulant array will be the concatenation
+of the shape of the index array (or the shape that all the index arrays
+were broadcast to) with the shape of any unused dimensions (those not
+indexed) in the array being indexed.
+
+Boolean or "mask" index arrays
+==============================
+
+Boolean arrays used as indices are treated in a different manner
+entirely than index arrays. Boolean arrays must be of the same shape
+as the initial dimensions of the array being indexed. In the
+most straightforward case, the boolean array has the same shape: ::
+
+ >>> b = y>20
+ >>> y[b]
+ array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])
+
+Unlike in the case of integer index arrays, in the boolean case, the
+result is a 1-D array containing all the elements in the indexed array
+corresponding to all the true elements in the boolean array. The
+elements in the indexed array are always iterated and returned in
+:term:`row-major` (C-style) order. The result is also identical to
+``y[np.nonzero(b)]``. As with index arrays, what is returned is a copy
+of the data, not a view as one gets with slices.
+
+The result will be multidimensional if y has more dimensions than b.
+For example: ::
+
+ >>> b[:,5] # use a 1-D boolean whose first dim agrees with the first dim of y
+ array([False, False, False,  True,  True], dtype=bool)
+ >>> y[b[:,5]]
+ array([[21, 22, 23, 24, 25, 26, 27],
+        [28, 29, 30, 31, 32, 33, 34]])
+
+Here the 4th and 5th rows are selected from the indexed array and
+combined to make a 2-D array.
+
+In general, when the boolean array has fewer dimensions than the array
+being indexed, this is equivalent to y[b, ...], which means
+y is indexed by b followed by as many : as are needed to fill
+out the rank of y.
+Thus the shape of the result is one dimension containing the number
+of True elements of the boolean array, followed by the remaining
+dimensions of the array being indexed.
+
+For example, using a 2-D boolean array of shape (2,3)
+with four True elements to select rows from a 3-D array of shape
+(2,3,5) results in a 2-D result of shape (4,5): ::
+
+ >>> x = np.arange(30).reshape(2,3,5)
+ >>> x
+ array([[[ 0,  1,  2,  3,  4],
+         [ 5,  6,  7,  8,  9],
+         [10, 11, 12, 13, 14]],
+        [[15, 16, 17, 18, 19],
+         [20, 21, 22, 23, 24],
+         [25, 26, 27, 28, 29]]])
+ >>> b = np.array([[True, True, False], [False, True, True]])
+ >>> x[b]
+ array([[ 0,  1,  2,  3,  4],
+        [ 5,  6,  7,  8,  9],
+        [20, 21, 22, 23, 24],
+        [25, 26, 27, 28, 29]])
+
+For further details, consult the numpy reference documentation on array indexing.
+
+Combining index arrays with slices
+==================================
+
+Index arrays may be combined with slices. For example: ::
+
+ >>> y[np.array([0,2,4]),1:3]
+ array([[ 1,  2],
+        [15, 16],
+        [29, 30]])
+
+In effect, the slice is converted to an index array
+np.array([[1,2]]) (shape (1,2)) that is broadcast with the index array
+to produce a resultant array of shape (3,2).
+
+Likewise, slicing can be combined with broadcasted boolean indices: ::
+
+ >>> y[b[:,5],1:3]
+ array([[22, 23],
+        [29, 30]])
+
+Structural indexing tools
+=========================
+
+To facilitate easy matching of array shapes with expressions and in
+assignments, the np.newaxis object can be used within array indices
+to add new dimensions with a size of 1. For example: ::
+
+ >>> y.shape
+ (5, 7)
+ >>> y[:,np.newaxis,:].shape
+ (5, 1, 7)
+
+Note that there are no new elements in the array, just that the
+dimensionality is increased. This can be handy to combine two
+arrays in a way that otherwise would require explicitly reshaping
+operations. For example: ::
+
+ >>> x = np.arange(5)
+ >>> x[:,np.newaxis] + x[np.newaxis,:]
+ array([[0, 1, 2, 3, 4],
+        [1, 2, 3, 4, 5],
+        [2, 3, 4, 5, 6],
+        [3, 4, 5, 6, 7],
+        [4, 5, 6, 7, 8]])
+
+The ellipsis syntax maybe used to indicate selecting in full any
+remaining unspecified dimensions. For example: ::
+
+ >>> z = np.arange(81).reshape(3,3,3,3)
+ >>> z[1,...,2]
+ array([[29, 32, 35],
+        [38, 41, 44],
+        [47, 50, 53]])
+
+This is equivalent to: ::
+
+ >>> z[1,:,:,2]
+ array([[29, 32, 35],
+        [38, 41, 44],
+        [47, 50, 53]])
+
+Assigning values to indexed arrays
+==================================
+
+As mentioned, one can select a subset of an array to assign to using
+a single index, slices, and index and mask arrays. The value being
+assigned to the indexed array must be shape consistent (the same shape
+or broadcastable to the shape the index produces). For example, it is
+permitted to assign a constant to a slice: ::
+
+ >>> x = np.arange(10)
+ >>> x[2:7] = 1
+
+or an array of the right size: ::
+
+ >>> x[2:7] = np.arange(5)
+
+Note that assignments may result in changes if assigning
+higher types to lower types (like floats to ints) or even
+exceptions (assigning complex to floats or ints): ::
+
+ >>> x[1] = 1.2
+ >>> x[1]
+ 1
+ >>> x[1] = 1.2j
+ <type 'exceptions.TypeError'>: can't convert complex to long; use
+ long(abs(z))
+
+
+Unlike some of the references (such as array and mask indices)
+assignments are always made to the original data in the array
+(indeed, nothing else would make sense!). Note though, that some
+actions may not work as one may naively expect. This particular
+example is often surprising to people: ::
+
+ >>> x = np.arange(0, 50, 10)
+ >>> x
+ array([ 0, 10, 20, 30, 40])
+ >>> x[np.array([1, 1, 3, 1])] += 1
+ >>> x
+ array([ 0, 11, 20, 31, 40])
+
+Where people expect that the 1st location will be incremented by 3.
+In fact, it will only be incremented by 1. The reason is because
+a new array is extracted from the original (as a temporary) containing
+the values at 1, 1, 3, 1, then the value 1 is added to the temporary,
+and then the temporary is assigned back to the original array. Thus
+the value of the array at x[1]+1 is assigned to x[1] three times,
+rather than being incremented 3 times.
+
+Dealing with variable numbers of indices within programs
+========================================================
+
+The index syntax is very powerful but limiting when dealing with
+a variable number of indices. For example, if you want to write
+a function that can handle arguments with various numbers of
+dimensions without having to write special case code for each
+number of possible dimensions, how can that be done? If one
+supplies to the index a tuple, the tuple will be interpreted
+as a list of indices. For example (using the previous definition
+for the array z): ::
+
+ >>> indices = (1,1,1,1)
+ >>> z[indices]
+ 40
+
+So one can use code to construct tuples of any number of indices
+and then use these within an index.
+
+Slices can be specified within programs by using the slice() function
+in Python. For example: ::
+
+ >>> indices = (1,1,1,slice(0,2)) # same as [1,1,1,0:2]
+ >>> z[indices]
+ array([39, 40])
+
+Likewise, ellipsis can be specified by code by using the Ellipsis
+object: ::
+
+ >>> indices = (1, Ellipsis, 1) # same as [1,...,1]
+ >>> z[indices]
+ array([[28, 31, 34],
+        [37, 40, 43],
+        [46, 49, 52]])
+
+For this reason it is possible to use the output from the np.where()
+function directly as an index since it always returns a tuple of index
+arrays.
+
+Because the special treatment of tuples, they are not automatically
+converted to an array as a list would be. As an example: ::
+
+ >>> z[[1,1,1,1]] # produces a large array
+ array([[[[27, 28, 29],
+          [30, 31, 32], ...
+ >>> z[(1,1,1,1)] # returns a single value
+ 40
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/internals.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/internals.py
new file mode 100644
index 0000000000..6bd6b1ae94
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/internals.py
@@ -0,0 +1,163 @@
+"""
+===============
+Array Internals
+===============
+
+Internal organization of numpy arrays
+=====================================
+
+It helps to understand a bit about how numpy arrays are handled under the covers to help understand numpy better. This section will not go into great detail. Those wishing to understand the full details are referred to Travis Oliphant's book "Guide to Numpy".
+
+Numpy arrays consist of two major components, the raw array data (from now on,
+referred to as the data buffer), and the information about the raw array data.
+The data buffer is typically what people think of as arrays in C or Fortran,
+a contiguous (and fixed) block of memory containing fixed sized data items.
+Numpy also contains a significant set of data that describes how to interpret
+the data in the data buffer. This extra information contains (among other things):
+
+ 1) The basic data element's size in bytes
+ 2) The start of the data within the data buffer (an offset relative to the
+    beginning of the data buffer).
+ 3) The number of dimensions and the size of each dimension
+ 4) The separation between elements for each dimension (the 'stride'). This
+    does not have to be a multiple of the element size
+ 5) The byte order of the data (which may not be the native byte order)
+ 6) Whether the buffer is read-only
+ 7) Information (via the dtype object) about the interpretation of the basic
+    data element. The basic data element may be as simple as a int or a float,
+    or it may be a compound object (e.g., struct-like), a fixed character field,
+    or Python object pointers.
+ 8) Whether the array is to interpreted as C-order or Fortran-order.
+
+This arrangement allow for very flexible use of arrays. One thing that it allows
+is simple changes of the metadata to change the interpretation of the array buffer.
+Changing the byteorder of the array is a simple change involving no rearrangement
+of the data. The shape of the array can be changed very easily without changing
+anything in the data buffer or any data copying at all
+
+Among other things that are made possible is one can create a new array metadata
+object that uses the same data buffer
+to create a new view of that data buffer that has a different interpretation
+of the buffer (e.g., different shape, offset, byte order, strides, etc) but
+shares the same data bytes. Many operations in numpy do just this such as
+slices. Other operations, such as transpose, don't move data elements
+around in the array, but rather change the information about the shape and strides so that the indexing of the array changes, but the data in the doesn't move.
+
+Typically these new versions of the array metadata but the same data buffer are
+new 'views' into the data buffer. There is a different ndarray object, but it
+uses the same data buffer. This is why it is necessary to force copies through
+use of the .copy() method if one really wants to make a new and independent
+copy of the data buffer.
+
+New views into arrays mean the the object reference counts for the data buffer
+increase. Simply doing away with the original array object will not remove the
+data buffer if other views of it still exist.
+
+Multidimensional Array Indexing Order Issues
+============================================
+
+What is the right way to index
+multi-dimensional arrays? Before you jump to conclusions about the one and
+true way to index multi-dimensional arrays, it pays to understand why this is
+a confusing issue. This section will try to explain in detail how numpy
+indexing works and why we adopt the convention we do for images, and when it
+may be appropriate to adopt other conventions.
+
+The first thing to understand is
+that there are two conflicting conventions for indexing 2-dimensional arrays.
+Matrix notation uses the first index to indicate which row is being selected and
+the second index to indicate which column is selected. This is opposite the
+geometrically oriented-convention for images where people generally think the
+first index represents x position (i.e., column) and the second represents y
+position (i.e., row). This alone is the source of much confusion;
+matrix-oriented users and image-oriented users expect two different things with
+regard to indexing.
+
+The second issue to understand is how indices correspond
+to the order the array is stored in memory. In Fortran the first index is the
+most rapidly varying index when moving through the elements of a two
+dimensional array as it is stored in memory. If you adopt the matrix
+convention for indexing, then this means the matrix is stored one column at a
+time (since the first index moves to the next row as it changes). Thus Fortran
+is considered a Column-major language. C has just the opposite convention. In
+C, the last index changes most rapidly as one moves through the array as
+stored in memory. Thus C is a Row-major language. The matrix is stored by
+rows. Note that in both cases it presumes that the matrix convention for
+indexing is being used, i.e., for both Fortran and C, the first index is the
+row. Note this convention implies that the indexing convention is invariant
+and that the data order changes to keep that so.
+
+But that's not the only way
+to look at it. Suppose one has large two-dimensional arrays (images or
+matrices) stored in data files. Suppose the data are stored by rows rather than
+by columns. If we are to preserve our index convention (whether matrix or
+image) that means that depending on the language we use, we may be forced to
+reorder the data if it is read into memory to preserve our indexing
+convention. For example if we read row-ordered data into memory without
+reordering, it will match the matrix indexing convention for C, but not for
+Fortran. Conversely, it will match the image indexing convention for Fortran,
+but not for C. For C, if one is using data stored in row order, and one wants
+to preserve the image index convention, the data must be reordered when
+reading into memory.
+
+In the end, which you do for Fortran or C depends on
+which is more important, not reordering data or preserving the indexing
+convention. For large images, reordering data is potentially expensive, and
+often the indexing convention is inverted to avoid that.
+
+The situation with
+numpy makes this issue yet more complicated. The internal machinery of numpy
+arrays is flexible enough to accept any ordering of indices. One can simply
+reorder indices by manipulating the internal stride information for arrays
+without reordering the data at all. Numpy will know how to map the new index
+order to the data without moving the data.
+
+So if this is true, why not choose
+the index order that matches what you most expect? In particular, why not define
+row-ordered images to use the image convention? (This is sometimes referred
+to as the Fortran convention vs the C convention, thus the 'C' and 'FORTRAN'
+order options for array ordering in numpy.) The drawback of doing this is
+potential performance penalties. It's common to access the data sequentially,
+either implicitly in array operations or explicitly by looping over rows of an
+image. When that is done, then the data will be accessed in non-optimal order.
+As the first index is incremented, what is actually happening is that elements
+spaced far apart in memory are being sequentially accessed, with usually poor
+memory access speeds. For example, for a two dimensional image 'im' defined so
+that im[0, 10] represents the value at x=0, y=10. To be consistent with usual
+Python behavior then im[0] would represent a column at x=0. Yet that data
+would be spread over the whole array since the data are stored in row order.
+Despite the flexibility of numpy's indexing, it can't really paper over the fact
+basic operations are rendered inefficient because of data order or that getting
+contiguous subarrays is still awkward (e.g., im[:,0] for the first row, vs
+im[0]), thus one can't use an idiom such as for row in im; for col in im does
+work, but doesn't yield contiguous column data.
+
+As it turns out, numpy is
+smart enough when dealing with ufuncs to determine which index is the most
+rapidly varying one in memory and uses that for the innermost loop. Thus for
+ufuncs there is no large intrinsic advantage to either approach in most cases.
+On the other hand, use of .flat with an FORTRAN ordered array will lead to
+non-optimal memory access as adjacent elements in the flattened array (iterator,
+actually) are not contiguous in memory.
+
+Indeed, the fact is that Python
+indexing on lists and other sequences naturally leads to an outside-to inside
+ordering (the first index gets the largest grouping, the next the next largest,
+and the last gets the smallest element). Since image data are normally stored
+by rows, this corresponds to position within rows being the last item indexed.
+
+If you do want to use Fortran ordering realize that
+there are two approaches to consider: 1) accept that the first index is just not
+the most rapidly changing in memory and have all your I/O routines reorder
+your data when going from memory to disk or visa versa, or use numpy's
+mechanism for mapping the first index to the most rapidly varying data. We
+recommend the former if possible. The disadvantage of the latter is that many
+of numpy's functions will yield arrays without Fortran ordering unless you are
+careful to use the 'order' keyword. Doing this would be highly inconvenient.
+
+Otherwise we recommend simply learning to reverse the usual order of indices
+when accessing elements of an array. Granted, it goes against the grain, but
+it is more in line with Python semantics and the natural order of the data.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/misc.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/misc.py
new file mode 100644
index 0000000000..37ebca5724
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/misc.py
@@ -0,0 +1,226 @@
+"""
+=============
+Miscellaneous
+=============
+
+IEEE 754 Floating Point Special Values
+--------------------------------------
+
+Special values defined in numpy: nan, inf,
+
+NaNs can be used as a poor-man's mask (if you don't care what the
+original value was)
+
+Note: cannot use equality to test NaNs. E.g.: ::
+
+ >>> myarr = np.array([1., 0., np.nan, 3.])
+ >>> np.where(myarr == np.nan)
+ >>> np.nan == np.nan  # is always False! Use special numpy functions instead.
+ False
+ >>> myarr[myarr == np.nan] = 0. # doesn't work
+ >>> myarr
+ array([  1.,   0.,  NaN,   3.])
+ >>> myarr[np.isnan(myarr)] = 0. # use this instead find
+ >>> myarr
+ array([ 1.,  0.,  0.,  3.])
+
+Other related special value functions: ::
+
+ isinf():    True if value is inf
+ isfinite(): True if not nan or inf
+ nan_to_num(): Map nan to 0, inf to max float, -inf to min float
+
+The following corresponds to the usual functions except that nans are excluded
+from the results: ::
+
+ nansum()
+ nanmax()
+ nanmin()
+ nanargmax()
+ nanargmin()
+
+ >>> x = np.arange(10.)
+ >>> x[3] = np.nan
+ >>> x.sum()
+ nan
+ >>> np.nansum(x)
+ 42.0
+
+How numpy handles numerical exceptions
+--------------------------------------
+
+The default is to ``'warn'`` for ``invalid``, ``divide``, and ``overflow``
+and ``'ignore'`` for ``underflow``.  But this can be changed, and it can be
+set individually for different kinds of exceptions. The different behaviors
+are:
+
+ - 'ignore' : Take no action when the exception occurs.
+ - 'warn'   : Print a `RuntimeWarning` (via the Python `warnings` module).
+ - 'raise'  : Raise a `FloatingPointError`.
+ - 'call'   : Call a function specified using the `seterrcall` function.
+ - 'print'  : Print a warning directly to ``stdout``.
+ - 'log'    : Record error in a Log object specified by `seterrcall`.
+
+These behaviors can be set for all kinds of errors or specific ones:
+
+ - all       : apply to all numeric exceptions
+ - invalid   : when NaNs are generated
+ - divide    : divide by zero (for integers as well!)
+ - overflow  : floating point overflows
+ - underflow : floating point underflows
+
+Note that integer divide-by-zero is handled by the same machinery.
+These behaviors are set on a per-thread basis.
+
+Examples
+--------
+
+::
+
+ >>> oldsettings = np.seterr(all='warn')
+ >>> np.zeros(5,dtype=np.float32)/0.
+ invalid value encountered in divide
+ >>> j = np.seterr(under='ignore')
+ >>> np.array([1.e-100])**10
+ >>> j = np.seterr(invalid='raise')
+ >>> np.sqrt(np.array([-1.]))
+ FloatingPointError: invalid value encountered in sqrt
+ >>> def errorhandler(errstr, errflag):
+ ...      print("saw stupid error!")
+ >>> np.seterrcall(errorhandler)
+ <function err_handler at 0x...>
+ >>> j = np.seterr(all='call')
+ >>> np.zeros(5, dtype=np.int32)/0
+ FloatingPointError: invalid value encountered in divide
+ saw stupid error!
+ >>> j = np.seterr(**oldsettings) # restore previous
+ ...                              # error-handling settings
+
+Interfacing to C
+----------------
+Only a survey of the choices. Little detail on how each works.
+
+1) Bare metal, wrap your own C-code manually.
+
+ - Plusses:
+
+   - Efficient
+   - No dependencies on other tools
+
+ - Minuses:
+
+   - Lots of learning overhead:
+
+     - need to learn basics of Python C API
+     - need to learn basics of numpy C API
+     - need to learn how to handle reference counting and love it.
+
+   - Reference counting often difficult to get right.
+
+     - getting it wrong leads to memory leaks, and worse, segfaults
+
+   - API will change for Python 3.0!
+
+2) Cython
+
+ - Plusses:
+
+   - avoid learning C API's
+   - no dealing with reference counting
+   - can code in pseudo python and generate C code
+   - can also interface to existing C code
+   - should shield you from changes to Python C api
+   - has become the de-facto standard within the scientific Python community
+   - fast indexing support for arrays
+
+ - Minuses:
+
+   - Can write code in non-standard form which may become obsolete
+   - Not as flexible as manual wrapping
+
+3) ctypes
+
+ - Plusses:
+
+   - part of Python standard library
+   - good for interfacing to existing sharable libraries, particularly
+     Windows DLLs
+   - avoids API/reference counting issues
+   - good numpy support: arrays have all these in their ctypes
+     attribute: ::
+
+       a.ctypes.data              a.ctypes.get_strides
+       a.ctypes.data_as           a.ctypes.shape
+       a.ctypes.get_as_parameter  a.ctypes.shape_as
+       a.ctypes.get_data          a.ctypes.strides
+       a.ctypes.get_shape         a.ctypes.strides_as
+
+ - Minuses:
+
+   - can't use for writing code to be turned into C extensions, only a wrapper
+     tool.
+
+4) SWIG (automatic wrapper generator)
+
+ - Plusses:
+
+   - around a long time
+   - multiple scripting language support
+   - C++ support
+   - Good for wrapping large (many functions) existing C libraries
+
+ - Minuses:
+
+   - generates lots of code between Python and the C code
+   - can cause performance problems that are nearly impossible to optimize
+     out
+   - interface files can be hard to write
+   - doesn't necessarily avoid reference counting issues or needing to know
+     API's
+
+5) scipy.weave
+
+ - Plusses:
+
+   - can turn many numpy expressions into C code
+   - dynamic compiling and loading of generated C code
+   - can embed pure C code in Python module and have weave extract, generate
+     interfaces and compile, etc.
+
+ - Minuses:
+
+   - Future very uncertain: it's the only part of Scipy not ported to Python 3
+     and is effectively deprecated in favor of Cython.
+
+6) Psyco
+
+ - Plusses:
+
+   - Turns pure python into efficient machine code through jit-like
+     optimizations
+   - very fast when it optimizes well
+
+ - Minuses:
+
+   - Only on intel (windows?)
+   - Doesn't do much for numpy?
+
+Interfacing to Fortran:
+-----------------------
+The clear choice to wrap Fortran code is
+`f2py <http://docs.scipy.org/doc/numpy-dev/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
+longer.
+
+Interfacing to C++:
+-------------------
+ 1) Cython
+ 2) CXX
+ 3) Boost.python
+ 4) SWIG
+ 5) SIP (used mainly in PyQT)
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
new file mode 100644
index 0000000000..1135c1395c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
@@ -0,0 +1,290 @@
+"""
+=================
+Structured Arrays
+=================
+
+Introduction
+============
+
+Numpy provides powerful capabilities to create arrays of structured datatype.
+These arrays permit one to manipulate the data by named fields. A simple 
+example will show what is meant.: ::
+
+ >>> x = np.array([(1,2.,'Hello'), (2,3.,"World")],
+ ...              dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
+ >>> x
+ array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
+      dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+
+Here we have created a one-dimensional array of length 2. Each element of
+this array is a structure that contains three items, a 32-bit integer, a 32-bit
+float, and a string of length 10 or less. If we index this array at the second
+position we get the second structure: ::
+
+ >>> x[1]
+ (2,3.,"World")
+
+Conveniently, one can access any field of the array by indexing using the
+string that names that field. ::
+
+ >>> y = x['bar']
+ >>> y
+ array([ 2.,  3.], dtype=float32)
+ >>> y[:] = 2*y
+ >>> y
+ array([ 4.,  6.], dtype=float32)
+ >>> x
+ array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
+       dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+
+In these examples, y is a simple float array consisting of the 2nd field
+in the structured type. But, rather than being a copy of the data in the structured
+array, it is a view, i.e., it shares exactly the same memory locations.
+Thus, when we updated this array by doubling its values, the structured
+array shows the corresponding values as doubled as well. Likewise, if one
+changes the structured array, the field view also changes: ::
+
+ >>> x[1] = (-1,-1.,"Master")
+ >>> x
+ array([(1, 4.0, 'Hello'), (-1, -1.0, 'Master')],
+       dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
+ >>> y
+ array([ 4., -1.], dtype=float32)
+
+Defining Structured Arrays
+==========================
+
+One defines a structured array through the dtype object.  There are
+**several** alternative ways to define the fields of a record.  Some of
+these variants provide backward compatibility with Numeric, numarray, or
+another module, and should not be used except for such purposes. These
+will be so noted. One specifies record structure in
+one of four alternative ways, using an argument (as supplied to a dtype
+function keyword or a dtype object constructor itself).  This
+argument must be one of the following: 1) string, 2) tuple, 3) list, or
+4) dictionary.  Each of these is briefly described below.
+
+1) String argument.
+In this case, the constructor expects a comma-separated list of type
+specifiers, optionally with extra shape information. The fields are 
+given the default names 'f0', 'f1', 'f2' and so on.
+The type specifiers can take 4 different forms: ::
+
+  a) b1, i1, i2, i4, i8, u1, u2, u4, u8, f2, f4, f8, c8, c16, a<n>
+     (representing bytes, ints, unsigned ints, floats, complex and
+      fixed length strings of specified byte lengths)
+  b) int8,...,uint8,...,float16, float32, float64, complex64, complex128
+     (this time with bit sizes)
+  c) older Numeric/numarray type specifications (e.g. Float32).
+     Don't use these in new code!
+  d) Single character type specifiers (e.g H for unsigned short ints).
+     Avoid using these unless you must. Details can be found in the
+     Numpy book
+
+These different styles can be mixed within the same string (but why would you
+want to do that?). Furthermore, each type specifier can be prefixed
+with a repetition number, or a shape. In these cases an array
+element is created, i.e., an array within a record. That array
+is still referred to as a single field. An example: ::
+
+ >>> x = np.zeros(3, dtype='3int8, float32, (2,3)float64')
+ >>> x
+ array([([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
+        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
+        ([0, 0, 0], 0.0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])],
+       dtype=[('f0', '|i1', 3), ('f1', '>f4'), ('f2', '>f8', (2, 3))])
+
+By using strings to define the record structure, it precludes being
+able to name the fields in the original definition. The names can
+be changed as shown later, however.
+
+2) Tuple argument: The only relevant tuple case that applies to record
+structures is when a structure is mapped to an existing data type. This
+is done by pairing in a tuple, the existing data type with a matching
+dtype definition (using any of the variants being described here). As
+an example (using a definition using a list, so see 3) for further
+details): ::
+
+ >>> x = np.zeros(3, dtype=('i4',[('r','u1'), ('g','u1'), ('b','u1'), ('a','u1')]))
+ >>> x
+ array([0, 0, 0])
+ >>> x['r']
+ array([0, 0, 0], dtype=uint8)
+
+In this case, an array is produced that looks and acts like a simple int32 array,
+but also has definitions for fields that use only one byte of the int32 (a bit
+like Fortran equivalencing).
+
+3) List argument: In this case the record structure is defined with a list of
+tuples. Each tuple has 2 or 3 elements specifying: 1) The name of the field
+('' is permitted), 2) the type of the field, and 3) the shape (optional).
+For example::
+
+ >>> x = np.zeros(3, dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
+ >>> x
+ array([(0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
+        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]]),
+        (0.0, 0.0, [[0.0, 0.0], [0.0, 0.0]])],
+       dtype=[('x', '>f4'), ('y', '>f4'), ('value', '>f4', (2, 2))])
+
+4) Dictionary argument: two different forms are permitted. The first consists
+of a dictionary with two required keys ('names' and 'formats'), each having an
+equal sized list of values. The format list contains any type/shape specifier
+allowed in other contexts. The names must be strings. There are two optional
+keys: 'offsets' and 'titles'. Each must be a correspondingly matching list to
+the required two where offsets contain integer offsets for each field, and
+titles are objects containing metadata for each field (these do not have
+to be strings), where the value of None is permitted. As an example: ::
+
+ >>> x = np.zeros(3, dtype={'names':['col1', 'col2'], 'formats':['i4','f4']})
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+       dtype=[('col1', '>i4'), ('col2', '>f4')])
+
+The other dictionary form permitted is a dictionary of name keys with tuple
+values specifying type, offset, and an optional title. ::
+
+ >>> x = np.zeros(3, dtype={'col1':('i1',0,'title 1'), 'col2':('f4',1,'title 2')})
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+       dtype=[(('title 1', 'col1'), '|i1'), (('title 2', 'col2'), '>f4')])
+
+Accessing and modifying field names
+===================================
+
+The field names are an attribute of the dtype object defining the structure.
+For the last example: ::
+
+ >>> x.dtype.names
+ ('col1', 'col2')
+ >>> x.dtype.names = ('x', 'y')
+ >>> x
+ array([(0, 0.0), (0, 0.0), (0, 0.0)],
+      dtype=[(('title 1', 'x'), '|i1'), (('title 2', 'y'), '>f4')])
+ >>> x.dtype.names = ('x', 'y', 'z') # wrong number of names
+ <type 'exceptions.ValueError'>: must replace all names at once with a sequence of length 2
+
+Accessing field titles
+====================================
+
+The field titles provide a standard place to put associated info for fields.
+They do not have to be strings. ::
+
+ >>> x.dtype.fields['x'][2]
+ 'title 1'
+
+Accessing multiple fields at once
+====================================
+
+You can access multiple fields at once using a list of field names: ::
+
+ >>> x = np.array([(1.5,2.5,(1.0,2.0)),(3.,4.,(4.,5.)),(1.,3.,(2.,6.))],
+         dtype=[('x','f4'),('y',np.float32),('value','f4',(2,2))])
+
+Notice that `x` is created with a list of tuples. ::
+
+ >>> x[['x','y']]
+ array([(1.5, 2.5), (3.0, 4.0), (1.0, 3.0)],
+      dtype=[('x', '<f4'), ('y', '<f4')])
+ >>> x[['x','value']]
+ array([(1.5, [[1.0, 2.0], [1.0, 2.0]]), (3.0, [[4.0, 5.0], [4.0, 5.0]]),
+       (1.0, [[2.0, 6.0], [2.0, 6.0]])],
+      dtype=[('x', '<f4'), ('value', '<f4', (2, 2))])
+
+The fields are returned in the order they are asked for.::
+
+ >>> x[['y','x']]
+ array([(2.5, 1.5), (4.0, 3.0), (3.0, 1.0)],
+      dtype=[('y', '<f4'), ('x', '<f4')])
+
+Filling structured arrays
+=========================
+
+Structured arrays can be filled by field or row by row. ::
+
+ >>> arr = np.zeros((5,), dtype=[('var1','f8'),('var2','f8')])
+ >>> arr['var1'] = np.arange(5)
+
+If you fill it in row by row, it takes a take a tuple
+(but not a list or array!)::
+
+ >>> arr[0] = (10,20)
+ >>> arr
+ array([(10.0, 20.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0)],
+      dtype=[('var1', '<f8'), ('var2', '<f8')])
+
+Record Arrays
+=============
+
+For convenience, numpy provides "record arrays" which allow one to access
+fields of structured arrays by attribute rather than by index. Record arrays
+are structured arrays wrapped using a subclass of ndarray,
+:class:`numpy.recarray`, which allows field access by attribute on the array
+object, and record arrays also use a special datatype, :class:`numpy.record`,
+which allows field access by attribute on the individual elements of the array. 
+
+The simplest way to create a record array is with :func:`numpy.rec.array`: ::
+
+ >>> recordarr = np.rec.array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...                    dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr.bar
+ array([ 2.,  3.], dtype=float32)
+ >>> recordarr[1:2]
+ rec.array([(2, 3.0, 'World')], 
+       dtype=[('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')])
+ >>> recordarr[1:2].foo
+ array([2], dtype=int32)
+ >>> recordarr.foo[1:2]
+ array([2], dtype=int32)
+ >>> recordarr[1].baz
+ 'World'
+
+numpy.rec.array can convert a wide variety of arguments into record arrays,
+including normal structured arrays: ::
+
+ >>> arr = array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...             dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr = np.rec.array(arr)
+
+The numpy.rec module provides a number of other convenience functions for
+creating record arrays, see :ref:`record array creation routines
+<routines.array-creation.rec>`.
+
+A record array representation of a structured array can be obtained using the
+appropriate :ref:`view`: ::
+
+ >>> arr = np.array([(1,2.,'Hello'),(2,3.,"World")], 
+ ...                dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')])
+ >>> recordarr = arr.view(dtype=dtype((np.record, arr.dtype)), 
+ ...                      type=np.recarray)
+
+For convenience, viewing an ndarray as type `np.recarray` will automatically
+convert to `np.record` datatype, so the dtype can be left out of the view: ::
+
+ >>> recordarr = arr.view(np.recarray)
+ >>> recordarr.dtype
+ dtype((numpy.record, [('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')]))
+
+To get back to a plain ndarray both the dtype and type must be reset. The
+following view does so, taking into account the unusual case that the
+recordarr was not a structured type: ::
+
+ >>> arr2 = recordarr.view(recordarr.dtype.fields or recordarr.dtype, np.ndarray)
+
+Record array fields accessed by index or by attribute are returned as a record
+array if the field has a structured type but as a plain ndarray otherwise. ::
+
+ >>> recordarr = np.rec.array([('Hello', (1,2)),("World", (3,4))], 
+ ...                 dtype=[('foo', 'S6'),('bar', [('A', int), ('B', int)])])
+ >>> type(recordarr.foo)
+ <type 'numpy.ndarray'>
+ >>> type(recordarr.bar)
+ <class 'numpy.core.records.recarray'>
+
+Note that if a field has the same name as an ndarray attribute, the ndarray
+attribute takes precedence. Such fields will be inaccessible by attribute but
+may still be accessed by index.
+
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.py
new file mode 100644
index 0000000000..85327feab3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.py
@@ -0,0 +1,560 @@
+"""
+=============================
+Subclassing ndarray in python
+=============================
+
+Credits
+-------
+
+This page is based with thanks on the wiki page on subclassing by Pierre
+Gerard-Marchant - http://www.scipy.org/Subclasses.
+
+Introduction
+------------
+
+Subclassing ndarray is relatively simple, but it has some complications
+compared to other Python objects.  On this page we explain the machinery
+that allows you to subclass ndarray, and the implications for
+implementing a subclass.
+
+ndarrays and object creation
+============================
+
+Subclassing ndarray is complicated by the fact that new instances of
+ndarray classes can come about in three different ways.  These are:
+
+#. Explicit constructor call - as in ``MySubClass(params)``.  This is
+   the usual route to Python instance creation.
+#. View casting - casting an existing ndarray as a given subclass
+#. New from template - creating a new instance from a template
+   instance. Examples include returning slices from a subclassed array,
+   creating return types from ufuncs, and copying arrays.  See
+   :ref:`new-from-template` for more details
+
+The last two are characteristics of ndarrays - in order to support
+things like array slicing.  The complications of subclassing ndarray are
+due to the mechanisms numpy has to support these latter two routes of
+instance creation.
+
+.. _view-casting:
+
+View casting
+------------
+
+*View casting* is the standard ndarray mechanism by which you take an
+ndarray of any subclass, and return a view of the array as another
+(specified) subclass:
+
+>>> import numpy as np
+>>> # create a completely useless ndarray subclass
+>>> class C(np.ndarray): pass
+>>> # create a standard ndarray
+>>> arr = np.zeros((3,))
+>>> # take a view of it, as our useless subclass
+>>> c_arr = arr.view(C)
+>>> type(c_arr)
+<class 'C'>
+
+.. _new-from-template:
+
+Creating new from template
+--------------------------
+
+New instances of an ndarray subclass can also come about by a very
+similar mechanism to :ref:`view-casting`, when numpy finds it needs to
+create a new instance from a template instance.  The most obvious place
+this has to happen is when you are taking slices of subclassed arrays.
+For example:
+
+>>> v = c_arr[1:]
+>>> type(v) # the view is of type 'C'
+<class 'C'>
+>>> v is c_arr # but it's a new instance
+False
+
+The slice is a *view* onto the original ``c_arr`` data.  So, when we
+take a view from the ndarray, we return a new ndarray, of the same
+class, that points to the data in the original.
+
+There are other points in the use of ndarrays where we need such views,
+such as copying arrays (``c_arr.copy()``), creating ufunc output arrays
+(see also :ref:`array-wrap`), and reducing methods (like
+``c_arr.mean()``.
+
+Relationship of view casting and new-from-template
+--------------------------------------------------
+
+These paths both use the same machinery.  We make the distinction here,
+because they result in different input to your methods.  Specifically,
+:ref:`view-casting` means you have created a new instance of your array
+type from any potential subclass of ndarray.  :ref:`new-from-template`
+means you have created a new instance of your class from a pre-existing
+instance, allowing you - for example - to copy across attributes that
+are particular to your subclass.
+
+Implications for subclassing
+----------------------------
+
+If we subclass ndarray, we need to deal not only with explicit
+construction of our array type, but also :ref:`view-casting` or
+:ref:`new-from-template`.  Numpy has the machinery to do this, and this
+machinery that makes subclassing slightly non-standard.
+
+There are two aspects to the machinery that ndarray uses to support
+views and new-from-template in subclasses.
+
+The first is the use of the ``ndarray.__new__`` method for the main work
+of object initialization, rather then the more usual ``__init__``
+method.  The second is the use of the ``__array_finalize__`` method to
+allow subclasses to clean up after the creation of views and new
+instances from templates.
+
+A brief Python primer on ``__new__`` and ``__init__``
+=====================================================
+
+``__new__`` is a standard Python method, and, if present, is called
+before ``__init__`` when we create a class instance. See the `python
+__new__ documentation
+<http://docs.python.org/reference/datamodel.html#object.__new__>`_ for more detail.
+
+For example, consider the following Python code:
+
+.. testcode::
+
+  class C(object):
+      def __new__(cls, *args):
+          print('Cls in __new__:', cls)
+          print('Args in __new__:', args)
+          return object.__new__(cls, *args)
+
+      def __init__(self, *args):
+          print('type(self) in __init__:', type(self))
+          print('Args in __init__:', args)
+
+meaning that we get:
+
+>>> c = C('hello')
+Cls in __new__: <class 'C'>
+Args in __new__: ('hello',)
+type(self) in __init__: <class 'C'>
+Args in __init__: ('hello',)
+
+When we call ``C('hello')``, the ``__new__`` method gets its own class
+as first argument, and the passed argument, which is the string
+``'hello'``.  After python calls ``__new__``, it usually (see below)
+calls our ``__init__`` method, with the output of ``__new__`` as the
+first argument (now a class instance), and the passed arguments
+following.
+
+As you can see, the object can be initialized in the ``__new__``
+method or the ``__init__`` method, or both, and in fact ndarray does
+not have an ``__init__`` method, because all the initialization is
+done in the ``__new__`` method.
+
+Why use ``__new__`` rather than just the usual ``__init__``?  Because
+in some cases, as for ndarray, we want to be able to return an object
+of some other class.  Consider the following:
+
+.. testcode::
+
+  class D(C):
+      def __new__(cls, *args):
+          print('D cls is:', cls)
+          print('D args in __new__:', args)
+          return C.__new__(C, *args)
+
+      def __init__(self, *args):
+          # we never get here
+          print('In D __init__')
+
+meaning that:
+
+>>> obj = D('hello')
+D cls is: <class 'D'>
+D args in __new__: ('hello',)
+Cls in __new__: <class 'C'>
+Args in __new__: ('hello',)
+>>> type(obj)
+<class 'C'>
+
+The definition of ``C`` is the same as before, but for ``D``, the
+``__new__`` method returns an instance of class ``C`` rather than
+``D``.  Note that the ``__init__`` method of ``D`` does not get
+called.  In general, when the ``__new__`` method returns an object of
+class other than the class in which it is defined, the ``__init__``
+method of that class is not called.
+
+This is how subclasses of the ndarray class are able to return views
+that preserve the class type.  When taking a view, the standard
+ndarray machinery creates the new ndarray object with something
+like::
+
+  obj = ndarray.__new__(subtype, shape, ...
+
+where ``subdtype`` is the subclass.  Thus the returned view is of the
+same class as the subclass, rather than being of class ``ndarray``.
+
+That solves the problem of returning views of the same type, but now
+we have a new problem.  The machinery of ndarray can set the class
+this way, in its standard methods for taking views, but the ndarray
+``__new__`` method knows nothing of what we have done in our own
+``__new__`` method in order to set attributes, and so on.  (Aside -
+why not call ``obj = subdtype.__new__(...`` then?  Because we may not
+have a ``__new__`` method with the same call signature).
+
+The role of ``__array_finalize__``
+==================================
+
+``__array_finalize__`` is the mechanism that numpy provides to allow
+subclasses to handle the various ways that new instances get created.
+
+Remember that subclass instances can come about in these three ways:
+
+#. explicit constructor call (``obj = MySubClass(params)``).  This will
+   call the usual sequence of ``MySubClass.__new__`` then (if it exists)
+   ``MySubClass.__init__``.
+#. :ref:`view-casting`
+#. :ref:`new-from-template`
+
+Our ``MySubClass.__new__`` method only gets called in the case of the
+explicit constructor call, so we can't rely on ``MySubClass.__new__`` or
+``MySubClass.__init__`` to deal with the view casting and
+new-from-template.  It turns out that ``MySubClass.__array_finalize__``
+*does* get called for all three methods of object creation, so this is
+where our object creation housekeeping usually goes.
+
+* For the explicit constructor call, our subclass will need to create a
+  new ndarray instance of its own class.  In practice this means that
+  we, the authors of the code, will need to make a call to
+  ``ndarray.__new__(MySubClass,...)``, or do view casting of an existing
+  array (see below)
+* For view casting and new-from-template, the equivalent of
+  ``ndarray.__new__(MySubClass,...`` is called, at the C level.
+
+The arguments that ``__array_finalize__`` recieves differ for the three
+methods of instance creation above.
+
+The following code allows us to look at the call sequences and arguments:
+
+.. testcode::
+
+   import numpy as np
+
+   class C(np.ndarray):
+       def __new__(cls, *args, **kwargs):
+           print('In __new__ with class %s' % cls)
+           return np.ndarray.__new__(cls, *args, **kwargs)
+
+       def __init__(self, *args, **kwargs):
+           # in practice you probably will not need or want an __init__
+           # method for your subclass
+           print('In __init__ with class %s' % self.__class__)
+
+       def __array_finalize__(self, obj):
+           print('In array_finalize:')
+           print('   self type is %s' % type(self))
+           print('   obj type is %s' % type(obj))
+
+
+Now:
+
+>>> # Explicit constructor
+>>> c = C((10,))
+In __new__ with class <class 'C'>
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <type 'NoneType'>
+In __init__ with class <class 'C'>
+>>> # View casting
+>>> a = np.arange(10)
+>>> cast_a = a.view(C)
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <type 'numpy.ndarray'>
+>>> # Slicing (example of new-from-template)
+>>> cv = c[:1]
+In array_finalize:
+   self type is <class 'C'>
+   obj type is <class 'C'>
+
+The signature of ``__array_finalize__`` is::
+
+    def __array_finalize__(self, obj):
+
+``ndarray.__new__`` passes ``__array_finalize__`` the new object, of our
+own class (``self``) as well as the object from which the view has been
+taken (``obj``).  As you can see from the output above, the ``self`` is
+always a newly created instance of our subclass, and the type of ``obj``
+differs for the three instance creation methods:
+
+* When called from the explicit constructor, ``obj`` is ``None``
+* When called from view casting, ``obj`` can be an instance of any
+  subclass of ndarray, including our own.
+* When called in new-from-template, ``obj`` is another instance of our
+  own subclass, that we might use to update the new ``self`` instance.
+
+Because ``__array_finalize__`` is the only method that always sees new
+instances being created, it is the sensible place to fill in instance
+defaults for new object attributes, among other tasks.
+
+This may be clearer with an example.
+
+Simple example - adding an extra attribute to ndarray
+-----------------------------------------------------
+
+.. testcode::
+
+  import numpy as np
+
+  class InfoArray(np.ndarray):
+
+      def __new__(subtype, shape, dtype=float, buffer=None, offset=0,
+            strides=None, order=None, info=None):
+          # Create the ndarray instance of our type, given the usual
+          # ndarray input arguments.  This will call the standard
+          # ndarray constructor, but return an object of our type.
+          # It also triggers a call to InfoArray.__array_finalize__
+          obj = np.ndarray.__new__(subtype, shape, dtype, buffer, offset, strides,
+                           order)
+          # set the new 'info' attribute to the value passed
+          obj.info = info
+          # Finally, we must return the newly created object:
+          return obj
+
+      def __array_finalize__(self, obj):
+          # ``self`` is a new object resulting from
+          # ndarray.__new__(InfoArray, ...), therefore it only has
+          # attributes that the ndarray.__new__ constructor gave it -
+          # i.e. those of a standard ndarray.
+          #
+          # We could have got to the ndarray.__new__ call in 3 ways:
+          # From an explicit constructor - e.g. InfoArray():
+          #    obj is None
+          #    (we're in the middle of the InfoArray.__new__
+          #    constructor, and self.info will be set when we return to
+          #    InfoArray.__new__)
+          if obj is None: return
+          # From view casting - e.g arr.view(InfoArray):
+          #    obj is arr
+          #    (type(obj) can be InfoArray)
+          # From new-from-template - e.g infoarr[:3]
+          #    type(obj) is InfoArray
+          #
+          # Note that it is here, rather than in the __new__ method,
+          # that we set the default value for 'info', because this
+          # method sees all creation of default objects - with the
+          # InfoArray.__new__ constructor, but also with
+          # arr.view(InfoArray).
+          self.info = getattr(obj, 'info', None)
+          # We do not need to return anything
+
+
+Using the object looks like this:
+
+  >>> obj = InfoArray(shape=(3,)) # explicit constructor
+  >>> type(obj)
+  <class 'InfoArray'>
+  >>> obj.info is None
+  True
+  >>> obj = InfoArray(shape=(3,), info='information')
+  >>> obj.info
+  'information'
+  >>> v = obj[1:] # new-from-template - here - slicing
+  >>> type(v)
+  <class 'InfoArray'>
+  >>> v.info
+  'information'
+  >>> arr = np.arange(10)
+  >>> cast_arr = arr.view(InfoArray) # view casting
+  >>> type(cast_arr)
+  <class 'InfoArray'>
+  >>> cast_arr.info is None
+  True
+
+This class isn't very useful, because it has the same constructor as the
+bare ndarray object, including passing in buffers and shapes and so on.
+We would probably prefer the constructor to be able to take an already
+formed ndarray from the usual numpy calls to ``np.array`` and return an
+object.
+
+Slightly more realistic example - attribute added to existing array
+-------------------------------------------------------------------
+
+Here is a class that takes a standard ndarray that already exists, casts
+as our type, and adds an extra attribute.
+
+.. testcode::
+
+  import numpy as np
+
+  class RealisticInfoArray(np.ndarray):
+
+      def __new__(cls, input_array, info=None):
+          # Input array is an already formed ndarray instance
+          # We first cast to be our class type
+          obj = np.asarray(input_array).view(cls)
+          # add the new attribute to the created instance
+          obj.info = info
+          # Finally, we must return the newly created object:
+          return obj
+
+      def __array_finalize__(self, obj):
+          # see InfoArray.__array_finalize__ for comments
+          if obj is None: return
+          self.info = getattr(obj, 'info', None)
+
+
+So:
+
+  >>> arr = np.arange(5)
+  >>> obj = RealisticInfoArray(arr, info='information')
+  >>> type(obj)
+  <class 'RealisticInfoArray'>
+  >>> obj.info
+  'information'
+  >>> v = obj[1:]
+  >>> type(v)
+  <class 'RealisticInfoArray'>
+  >>> v.info
+  'information'
+
+.. _array-wrap:
+
+``__array_wrap__`` for ufuncs
+-------------------------------------------------------
+
+``__array_wrap__`` gets called at the end of numpy ufuncs and other numpy
+functions, to allow a subclass to set the type of the return value
+and update attributes and metadata. Let's show how this works with an example.
+First we make the same subclass as above, but with a different name and
+some print statements:
+
+.. testcode::
+
+  import numpy as np
+
+  class MySubClass(np.ndarray):
+
+      def __new__(cls, input_array, info=None):
+          obj = np.asarray(input_array).view(cls)
+          obj.info = info
+          return obj
+
+      def __array_finalize__(self, obj):
+          print('In __array_finalize__:')
+          print('   self is %s' % repr(self))
+          print('   obj is %s' % repr(obj))
+          if obj is None: return
+          self.info = getattr(obj, 'info', None)
+
+      def __array_wrap__(self, out_arr, context=None):
+          print('In __array_wrap__:')
+          print('   self is %s' % repr(self))
+          print('   arr is %s' % repr(out_arr))
+          # then just call the parent
+          return np.ndarray.__array_wrap__(self, out_arr, context)
+
+We run a ufunc on an instance of our new array:
+
+>>> obj = MySubClass(np.arange(5), info='spam')
+In __array_finalize__:
+   self is MySubClass([0, 1, 2, 3, 4])
+   obj is array([0, 1, 2, 3, 4])
+>>> arr2 = np.arange(5)+1
+>>> ret = np.add(arr2, obj)
+In __array_wrap__:
+   self is MySubClass([0, 1, 2, 3, 4])
+   arr is array([1, 3, 5, 7, 9])
+In __array_finalize__:
+   self is MySubClass([1, 3, 5, 7, 9])
+   obj is MySubClass([0, 1, 2, 3, 4])
+>>> ret
+MySubClass([1, 3, 5, 7, 9])
+>>> ret.info
+'spam'
+
+Note that the ufunc (``np.add``) has called the ``__array_wrap__`` method of the
+input with the highest ``__array_priority__`` value, in this case
+``MySubClass.__array_wrap__``, with arguments ``self`` as ``obj``, and
+``out_arr`` as the (ndarray) result of the addition.  In turn, the
+default ``__array_wrap__`` (``ndarray.__array_wrap__``) has cast the
+result to class ``MySubClass``, and called ``__array_finalize__`` -
+hence the copying of the ``info`` attribute.  This has all happened at the C level.
+
+But, we could do anything we wanted:
+
+.. testcode::
+
+  class SillySubClass(np.ndarray):
+
+      def __array_wrap__(self, arr, context=None):
+          return 'I lost your data'
+
+>>> arr1 = np.arange(5)
+>>> obj = arr1.view(SillySubClass)
+>>> arr2 = np.arange(5)
+>>> ret = np.multiply(obj, arr2)
+>>> ret
+'I lost your data'
+
+So, by defining a specific ``__array_wrap__`` method for our subclass,
+we can tweak the output from ufuncs. The ``__array_wrap__`` method
+requires ``self``, then an argument - which is the result of the ufunc -
+and an optional parameter *context*. This parameter is returned by some
+ufuncs as a 3-element tuple: (name of the ufunc, argument of the ufunc,
+domain of the ufunc). ``__array_wrap__`` should return an instance of
+its containing class.  See the masked array subclass for an
+implementation.
+
+In addition to ``__array_wrap__``, which is called on the way out of the
+ufunc, there is also an ``__array_prepare__`` method which is called on
+the way into the ufunc, after the output arrays are created but before any
+computation has been performed. The default implementation does nothing
+but pass through the array. ``__array_prepare__`` should not attempt to
+access the array data or resize the array, it is intended for setting the
+output array type, updating attributes and metadata, and performing any
+checks based on the input that may be desired before computation begins.
+Like ``__array_wrap__``, ``__array_prepare__`` must return an ndarray or
+subclass thereof or raise an error.
+
+Extra gotchas - custom ``__del__`` methods and ndarray.base
+-----------------------------------------------------------
+
+One of the problems that ndarray solves is keeping track of memory
+ownership of ndarrays and their views.  Consider the case where we have
+created an ndarray, ``arr`` and have taken a slice with ``v = arr[1:]``.
+The two objects are looking at the same memory.  Numpy keeps track of
+where the data came from for a particular array or view, with the
+``base`` attribute:
+
+>>> # A normal ndarray, that owns its own data
+>>> arr = np.zeros((4,))
+>>> # In this case, base is None
+>>> arr.base is None
+True
+>>> # We take a view
+>>> v1 = arr[1:]
+>>> # base now points to the array that it derived from
+>>> v1.base is arr
+True
+>>> # Take a view of a view
+>>> v2 = v1[1:]
+>>> # base points to the view it derived from
+>>> v2.base is v1
+True
+
+In general, if the array owns its own memory, as for ``arr`` in this
+case, then ``arr.base`` will be None - there are some exceptions to this
+- see the numpy book for more details.
+
+The ``base`` attribute is useful in being able to tell whether we have
+a view or the original array.  This in turn can be useful if we need
+to know whether or not to do some specific cleanup when the subclassed
+array is deleted.  For example, we may only want to do the cleanup if
+the original array is deleted, but not the views.  For an example of
+how this can work, have a look at the ``memmap`` class in
+``numpy.core``.
+
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.py
new file mode 100644
index 0000000000..0132202adc
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.py
@@ -0,0 +1,138 @@
+"""
+===================
+Universal Functions
+===================
+
+Ufuncs are, generally speaking, mathematical functions or operations that are
+applied element-by-element to the contents of an array. That is, the result
+in each output array element only depends on the value in the corresponding
+input array (or arrays) and on no other array elements. Numpy comes with a
+large suite of ufuncs, and scipy extends that suite substantially. The simplest
+example is the addition operator: ::
+
+ >>> np.array([0,2,3,4]) + np.array([1,1,-1,2])
+ array([1, 3, 2, 6])
+
+The unfunc module lists all the available ufuncs in numpy. Documentation on
+the specific ufuncs may be found in those modules. This documentation is
+intended to address the more general aspects of unfuncs common to most of
+them. All of the ufuncs that make use of Python operators (e.g., +, -, etc.)
+have equivalent functions defined (e.g. add() for +)
+
+Type coercion
+=============
+
+What happens when a binary operator (e.g., +,-,\\*,/, etc) deals with arrays of
+two different types? What is the type of the result? Typically, the result is
+the higher of the two types. For example: ::
+
+ float32 + float64 -> float64
+ int8 + int32 -> int32
+ int16 + float32 -> float32
+ float32 + complex64 -> complex64
+
+There are some less obvious cases generally involving mixes of types
+(e.g. uints, ints and floats) where equal bit sizes for each are not
+capable of saving all the information in a different type of equivalent
+bit size. Some examples are int32 vs float32 or uint32 vs int32.
+Generally, the result is the higher type of larger size than both
+(if available). So: ::
+
+ int32 + float32 -> float64
+ uint32 + int32 -> int64
+
+Finally, the type coercion behavior when expressions involve Python
+scalars is different than that seen for arrays. Since Python has a
+limited number of types, combining a Python int with a dtype=np.int8
+array does not coerce to the higher type but instead, the type of the
+array prevails. So the rules for Python scalars combined with arrays is
+that the result will be that of the array equivalent the Python scalar
+if the Python scalar is of a higher 'kind' than the array (e.g., float
+vs. int), otherwise the resultant type will be that of the array.
+For example: ::
+
+  Python int + int8 -> int8
+  Python float + int8 -> float64
+
+ufunc methods
+=============
+
+Binary ufuncs support 4 methods.
+
+**.reduce(arr)** applies the binary operator to elements of the array in
+  sequence. For example: ::
+
+ >>> np.add.reduce(np.arange(10))  # adds all elements of array
+ 45
+
+For multidimensional arrays, the first dimension is reduced by default: ::
+
+ >>> np.add.reduce(np.arange(10).reshape(2,5))
+     array([ 5,  7,  9, 11, 13])
+
+The axis keyword can be used to specify different axes to reduce: ::
+
+ >>> np.add.reduce(np.arange(10).reshape(2,5),axis=1)
+ array([10, 35])
+
+**.accumulate(arr)** applies the binary operator and generates an an
+equivalently shaped array that includes the accumulated amount for each
+element of the array. A couple examples: ::
+
+ >>> np.add.accumulate(np.arange(10))
+ array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45])
+ >>> np.multiply.accumulate(np.arange(1,9))
+ array([    1,     2,     6,    24,   120,   720,  5040, 40320])
+
+The behavior for multidimensional arrays is the same as for .reduce(),
+as is the use of the axis keyword).
+
+**.reduceat(arr,indices)** allows one to apply reduce to selected parts
+  of an array. It is a difficult method to understand. See the documentation
+  at:
+
+**.outer(arr1,arr2)** generates an outer operation on the two arrays arr1 and
+  arr2. It will work on multidimensional arrays (the shape of the result is
+  the concatenation of the two input shapes.: ::
+
+ >>> np.multiply.outer(np.arange(3),np.arange(4))
+ array([[0, 0, 0, 0],
+        [0, 1, 2, 3],
+        [0, 2, 4, 6]])
+
+Output arguments
+================
+
+All ufuncs accept an optional output array. The array must be of the expected
+output shape. Beware that if the type of the output array is of a different
+(and lower) type than the output result, the results may be silently truncated
+or otherwise corrupted in the downcast to the lower type. This usage is useful
+when one wants to avoid creating large temporary arrays and instead allows one
+to reuse the same array memory repeatedly (at the expense of not being able to
+use more convenient operator notation in expressions). Note that when the
+output argument is used, the ufunc still returns a reference to the result.
+
+ >>> x = np.arange(2)
+ >>> np.add(np.arange(2),np.arange(2.),x)
+ array([0, 2])
+ >>> x
+ array([0, 2])
+
+and & or as ufuncs
+==================
+
+Invariably people try to use the python 'and' and 'or' as logical operators
+(and quite understandably). But these operators do not behave as normal
+operators since Python treats these quite differently. They cannot be
+overloaded with array equivalents. Thus using 'and' or 'or' with an array
+results in an error. There are two alternatives:
+
+ 1) use the ufunc functions logical_and() and logical_or().
+ 2) use the bitwise operators & and \\|. The drawback of these is that if
+    the arguments to these operators are not boolean arrays, the result is
+    likely incorrect. On the other hand, most usages of logical_and and
+    logical_or are with boolean arrays. As long as one is careful, this is
+    a convenient way to apply these operators.
+
+"""
+from __future__ import division, absolute_import, print_function
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/dual.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/dual.py
new file mode 100644
index 0000000000..1517d84213
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/dual.py
@@ -0,0 +1,71 @@
+"""
+Aliases for functions which may be accelerated by Scipy.
+
+Scipy_ can be built to use accelerated or otherwise improved libraries
+for FFTs, linear algebra, and special functions. This module allows
+developers to transparently support these accelerated functions when
+scipy is available but still support users who have only installed
+Numpy.
+
+.. _Scipy : http://www.scipy.org
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# This module should be used for functions both in numpy and scipy if
+#  you want to use the numpy version if available but the scipy version
+#  otherwise.
+#  Usage  --- from numpy.dual import fft, inv
+
+__all__ = ['fft', 'ifft', 'fftn', 'ifftn', 'fft2', 'ifft2',
+           'norm', 'inv', 'svd', 'solve', 'det', 'eig', 'eigvals',
+           'eigh', 'eigvalsh', 'lstsq', 'pinv', 'cholesky', 'i0']
+
+import numpy.linalg as linpkg
+import numpy.fft as fftpkg
+from numpy.lib import i0
+import sys
+
+
+fft = fftpkg.fft
+ifft = fftpkg.ifft
+fftn = fftpkg.fftn
+ifftn = fftpkg.ifftn
+fft2 = fftpkg.fft2
+ifft2 = fftpkg.ifft2
+
+norm = linpkg.norm
+inv = linpkg.inv
+svd = linpkg.svd
+solve = linpkg.solve
+det = linpkg.det
+eig = linpkg.eig
+eigvals = linpkg.eigvals
+eigh = linpkg.eigh
+eigvalsh = linpkg.eigvalsh
+lstsq = linpkg.lstsq
+pinv = linpkg.pinv
+cholesky = linpkg.cholesky
+
+_restore_dict = {}
+
+def register_func(name, func):
+    if name not in __all__:
+        raise ValueError("%s not a dual function." % name)
+    f = sys._getframe(0).f_globals
+    _restore_dict[name] = f[name]
+    f[name] = func
+
+def restore_func(name):
+    if name not in __all__:
+        raise ValueError("%s not a dual function." % name)
+    try:
+        val = _restore_dict[name]
+    except KeyError:
+        return
+    else:
+        sys._getframe(0).f_globals[name] = val
+
+def restore_all():
+    for name in _restore_dict.keys():
+        restore_func(name)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.py
new file mode 100644
index 0000000000..4d1bc13766
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python2
+"""Fortran to Python Interface Generator.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['run_main', 'compile', 'f2py_testing']
+
+import sys
+
+from . import f2py2e
+from . import f2py_testing
+from . import diagnose
+
+run_main = f2py2e.run_main
+main = f2py2e.main
+
+
+def compile(source,
+            modulename='untitled',
+            extra_args='',
+            verbose=True,
+            source_fn=None,
+            extension='.f'
+            ):
+    ''' Build extension module from processing source with f2py.
+
+    Parameters
+    ----------
+    source : str
+        Fortran source of module / subroutine to compile
+    modulename : str, optional
+        the name of compiled python module
+    extra_args: str, optional
+        additional parameters passed to f2py
+    verbose: bool, optional
+        print f2py output to screen
+    extension: {'.f', '.f90'}, optional
+        filename extension influences the fortran compiler behavior
+
+        .. versionadded:: 1.11.0
+
+    '''
+    from numpy.distutils.exec_command import exec_command
+    import tempfile
+    if source_fn is None:
+        f = tempfile.NamedTemporaryFile(suffix=extension)
+    else:
+        f = open(source_fn, 'w')
+
+    try:
+        f.write(source)
+        f.flush()
+
+        args = ' -c -m {} {} {}'.format(modulename, f.name, extra_args)
+        c = '{} -c "import numpy.f2py as f2py2e;f2py2e.main()" {}'
+        c = c.format(sys.executable, args)
+        status, output = exec_command(c)
+        if verbose:
+            print(output)
+    finally:
+        f.close()
+    return status
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.py
new file mode 100644
index 0000000000..cb8f261c1b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.py
@@ -0,0 +1,27 @@
+# See http://cens.ioc.ee/projects/f2py2e/
+from __future__ import division, print_function
+
+import os
+import sys
+for mode in ["g3-numpy", "2e-numeric", "2e-numarray", "2e-numpy"]:
+    try:
+        i = sys.argv.index("--" + mode)
+        del sys.argv[i]
+        break
+    except ValueError:
+        pass
+os.environ["NO_SCIPY_IMPORT"] = "f2py"
+if mode == "g3-numpy":
+    sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
+    sys.exit(1)
+elif mode == "2e-numeric":
+    from f2py2e import main
+elif mode == "2e-numarray":
+    sys.argv.append("-DNUMARRAY")
+    from f2py2e import main
+elif mode == "2e-numpy":
+    from numpy.f2py import main
+else:
+    sys.stderr.write("Unknown mode: " + repr(mode) + "\\n")
+    sys.exit(1)
+main()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.py
new file mode 100644
index 0000000000..49a2199bf3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.py
@@ -0,0 +1,10 @@
+from __future__ import division, absolute_import, print_function
+
+major = 2
+
+try:
+    from __svn_version__ import version
+    version_info = (major, version)
+    version = '%s_%s' % version_info
+except (ImportError, ValueError):
+    version = str(major)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
new file mode 100644
index 0000000000..77a942e9ac
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
@@ -0,0 +1,854 @@
+#!/usr/bin/env python2
+"""
+
+Auxiliary functions for f2py2e.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy (BSD style) LICENSE.
+
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/07/24 19:01:55 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import pprint
+import sys
+import types
+from functools import reduce
+
+from . import __version__
+from . import cfuncs
+
+__all__ = [
+    'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle',
+    'getargs2', 'getcallprotoargument', 'getcallstatement',
+    'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode',
+    'getusercode1', 'hasbody', 'hascallstatement', 'hascommon',
+    'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote',
+    'isallocatable', 'isarray', 'isarrayofstrings', 'iscomplex',
+    'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn',
+    'isdouble', 'isdummyroutine', 'isexternal', 'isfunction',
+    'isfunction_wrap', 'isint1array', 'isinteger', 'isintent_aux',
+    'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict',
+    'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace',
+    'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical',
+    'islogicalfunction', 'islong_complex', 'islong_double',
+    'islong_doublefunction', 'islong_long', 'islong_longfunction',
+    'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isrequired',
+    'isroutine', 'isscalar', 'issigned_long_longarray', 'isstring',
+    'isstringarray', 'isstringfunction', 'issubroutine',
+    'issubroutine_wrap', 'isthreadsafe', 'isunsigned', 'isunsigned_char',
+    'isunsigned_chararray', 'isunsigned_long_long',
+    'isunsigned_long_longarray', 'isunsigned_short',
+    'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess',
+    'replace', 'show', 'stripcomma', 'throw_error',
+]
+
+
+f2py_version = __version__.version
+
+
+errmess = sys.stderr.write
+show = pprint.pprint
+
+options = {}
+debugoptions = []
+wrapfuncs = 1
+
+
+def outmess(t):
+    if options.get('verbose', 1):
+        sys.stdout.write(t)
+
+
+def debugcapi(var):
+    return 'capi' in debugoptions
+
+
+def _isstring(var):
+    return 'typespec' in var and var['typespec'] == 'character' and \
+           not isexternal(var)
+
+
+def isstring(var):
+    return _isstring(var) and not isarray(var)
+
+
+def ischaracter(var):
+    return isstring(var) and 'charselector' not in var
+
+
+def isstringarray(var):
+    return isarray(var) and _isstring(var)
+
+
+def isarrayofstrings(var):
+    # leaving out '*' for now so that `character*(*) a(m)` and `character
+    # a(m,*)` are treated differently. Luckily `character**` is illegal.
+    return isstringarray(var) and var['dimension'][-1] == '(*)'
+
+
+def isarray(var):
+    return 'dimension' in var and not isexternal(var)
+
+
+def isscalar(var):
+    return not (isarray(var) or isstring(var) or isexternal(var))
+
+
+def iscomplex(var):
+    return isscalar(var) and \
+           var.get('typespec') in ['complex', 'double complex']
+
+
+def islogical(var):
+    return isscalar(var) and var.get('typespec') == 'logical'
+
+
+def isinteger(var):
+    return isscalar(var) and var.get('typespec') == 'integer'
+
+
+def isreal(var):
+    return isscalar(var) and var.get('typespec') == 'real'
+
+
+def get_kind(var):
+    try:
+        return var['kindselector']['*']
+    except KeyError:
+        try:
+            return var['kindselector']['kind']
+        except KeyError:
+            pass
+
+
+def islong_long(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') not in ['integer', 'logical']:
+        return 0
+    return get_kind(var) == '8'
+
+
+def isunsigned_char(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-1'
+
+
+def isunsigned_short(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-2'
+
+
+def isunsigned(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-4'
+
+
+def isunsigned_long_long(var):
+    if not isscalar(var):
+        return 0
+    if var.get('typespec') != 'integer':
+        return 0
+    return get_kind(var) == '-8'
+
+
+def isdouble(var):
+    if not isscalar(var):
+        return 0
+    if not var.get('typespec') == 'real':
+        return 0
+    return get_kind(var) == '8'
+
+
+def islong_double(var):
+    if not isscalar(var):
+        return 0
+    if not var.get('typespec') == 'real':
+        return 0
+    return get_kind(var) == '16'
+
+
+def islong_complex(var):
+    if not iscomplex(var):
+        return 0
+    return get_kind(var) == '32'
+
+
+def iscomplexarray(var):
+    return isarray(var) and \
+           var.get('typespec') in ['complex', 'double complex']
+
+
+def isint1array(var):
+    return isarray(var) and var.get('typespec') == 'integer' \
+        and get_kind(var) == '1'
+
+
+def isunsigned_chararray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-1'
+
+
+def isunsigned_shortarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-2'
+
+
+def isunsignedarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-4'
+
+
+def isunsigned_long_longarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '-8'
+
+
+def issigned_chararray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '1'
+
+
+def issigned_shortarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '2'
+
+
+def issigned_array(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '4'
+
+
+def issigned_long_longarray(var):
+    return isarray(var) and var.get('typespec') in ['integer', 'logical']\
+        and get_kind(var) == '8'
+
+
+def isallocatable(var):
+    return 'attrspec' in var and 'allocatable' in var['attrspec']
+
+
+def ismutable(var):
+    return not ('dimension' not in var or isstring(var))
+
+
+def ismoduleroutine(rout):
+    return 'modulename' in rout
+
+
+def ismodule(rout):
+    return 'block' in rout and 'module' == rout['block']
+
+
+def isfunction(rout):
+    return 'block' in rout and 'function' == rout['block']
+
+def isfunction_wrap(rout):
+    if isintent_c(rout):
+        return 0
+    return wrapfuncs and isfunction(rout) and (not isexternal(rout))
+
+
+def issubroutine(rout):
+    return 'block' in rout and 'subroutine' == rout['block']
+
+
+def issubroutine_wrap(rout):
+    if isintent_c(rout):
+        return 0
+    return issubroutine(rout) and hasassumedshape(rout)
+
+
+def hasassumedshape(rout):
+    if rout.get('hasassumedshape'):
+        return True
+    for a in rout['args']:
+        for d in rout['vars'].get(a, {}).get('dimension', []):
+            if d == ':':
+                rout['hasassumedshape'] = True
+                return True
+    return False
+
+
+def isroutine(rout):
+    return isfunction(rout) or issubroutine(rout)
+
+
+def islogicalfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islogical(rout['vars'][a])
+    return 0
+
+
+def islong_longfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islong_long(rout['vars'][a])
+    return 0
+
+
+def islong_doublefunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return islong_double(rout['vars'][a])
+    return 0
+
+
+def iscomplexfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return iscomplex(rout['vars'][a])
+    return 0
+
+
+def iscomplexfunction_warn(rout):
+    if iscomplexfunction(rout):
+        outmess("""\
+    **************************************************************
+        Warning: code with a function returning complex value
+        may not work correctly with your Fortran compiler.
+        Run the following test before using it in your applications:
+        $(f2py install dir)/test-site/{b/runme_scalar,e/runme}
+        When using GNU gcc/g77 compilers, codes should work correctly.
+    **************************************************************\n""")
+        return 1
+    return 0
+
+
+def isstringfunction(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return isstring(rout['vars'][a])
+    return 0
+
+
+def hasexternals(rout):
+    return 'externals' in rout and rout['externals']
+
+
+def isthreadsafe(rout):
+    return 'f2pyenhancements' in rout and \
+           'threadsafe' in rout['f2pyenhancements']
+
+
+def hasvariables(rout):
+    return 'vars' in rout and rout['vars']
+
+
+def isoptional(var):
+    return ('attrspec' in var and 'optional' in var['attrspec'] and
+            'required' not in var['attrspec']) and isintent_nothide(var)
+
+
+def isexternal(var):
+    return 'attrspec' in var and 'external' in var['attrspec']
+
+
+def isrequired(var):
+    return not isoptional(var) and isintent_nothide(var)
+
+
+def isintent_in(var):
+    if 'intent' not in var:
+        return 1
+    if 'hide' in var['intent']:
+        return 0
+    if 'inplace' in var['intent']:
+        return 0
+    if 'in' in var['intent']:
+        return 1
+    if 'out' in var['intent']:
+        return 0
+    if 'inout' in var['intent']:
+        return 0
+    if 'outin' in var['intent']:
+        return 0
+    return 1
+
+
+def isintent_inout(var):
+    return ('intent' in var and ('inout' in var['intent'] or
+            'outin' in var['intent']) and 'in' not in var['intent'] and
+            'hide' not in var['intent'] and 'inplace' not in var['intent'])
+
+
+def isintent_out(var):
+    return 'out' in var.get('intent', [])
+
+
+def isintent_hide(var):
+    return ('intent' in var and ('hide' in var['intent'] or
+            ('out' in var['intent'] and 'in' not in var['intent'] and
+                (not l_or(isintent_inout, isintent_inplace)(var)))))
+
+def isintent_nothide(var):
+    return not isintent_hide(var)
+
+
+def isintent_c(var):
+    return 'c' in var.get('intent', [])
+
+
+def isintent_cache(var):
+    return 'cache' in var.get('intent', [])
+
+
+def isintent_copy(var):
+    return 'copy' in var.get('intent', [])
+
+
+def isintent_overwrite(var):
+    return 'overwrite' in var.get('intent', [])
+
+
+def isintent_callback(var):
+    return 'callback' in var.get('intent', [])
+
+
+def isintent_inplace(var):
+    return 'inplace' in var.get('intent', [])
+
+
+def isintent_aux(var):
+    return 'aux' in var.get('intent', [])
+
+
+def isintent_aligned4(var):
+    return 'aligned4' in var.get('intent', [])
+
+
+def isintent_aligned8(var):
+    return 'aligned8' in var.get('intent', [])
+
+
+def isintent_aligned16(var):
+    return 'aligned16' in var.get('intent', [])
+
+isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT',
+                 isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE',
+                 isintent_cache: 'INTENT_CACHE',
+                 isintent_c: 'INTENT_C', isoptional: 'OPTIONAL',
+                 isintent_inplace: 'INTENT_INPLACE',
+                 isintent_aligned4: 'INTENT_ALIGNED4',
+                 isintent_aligned8: 'INTENT_ALIGNED8',
+                 isintent_aligned16: 'INTENT_ALIGNED16',
+                 }
+
+
+def isprivate(var):
+    return 'attrspec' in var and 'private' in var['attrspec']
+
+
+def hasinitvalue(var):
+    return '=' in var
+
+
+def hasinitvalueasstring(var):
+    if not hasinitvalue(var):
+        return 0
+    return var['='][0] in ['"', "'"]
+
+
+def hasnote(var):
+    return 'note' in var
+
+
+def hasresultnote(rout):
+    if not isfunction(rout):
+        return 0
+    if 'result' in rout:
+        a = rout['result']
+    else:
+        a = rout['name']
+    if a in rout['vars']:
+        return hasnote(rout['vars'][a])
+    return 0
+
+
+def hascommon(rout):
+    return 'common' in rout
+
+
+def containscommon(rout):
+    if hascommon(rout):
+        return 1
+    if hasbody(rout):
+        for b in rout['body']:
+            if containscommon(b):
+                return 1
+    return 0
+
+
+def containsmodule(block):
+    if ismodule(block):
+        return 1
+    if not hasbody(block):
+        return 0
+    for b in block['body']:
+        if containsmodule(b):
+            return 1
+    return 0
+
+
+def hasbody(rout):
+    return 'body' in rout
+
+
+def hascallstatement(rout):
+    return getcallstatement(rout) is not None
+
+
+def istrue(var):
+    return 1
+
+
+def isfalse(var):
+    return 0
+
+
+class F2PYError(Exception):
+    pass
+
+
+class throw_error:
+
+    def __init__(self, mess):
+        self.mess = mess
+
+    def __call__(self, var):
+        mess = '\n\n  var = %s\n  Message: %s\n' % (var, self.mess)
+        raise F2PYError(mess)
+
+
+def l_and(*f):
+    l, l2 = 'lambda v', []
+    for i in range(len(f)):
+        l = '%s,f%d=f[%d]' % (l, i, i)
+        l2.append('f%d(v)' % (i))
+    return eval('%s:%s' % (l, ' and '.join(l2)))
+
+
+def l_or(*f):
+    l, l2 = 'lambda v', []
+    for i in range(len(f)):
+        l = '%s,f%d=f[%d]' % (l, i, i)
+        l2.append('f%d(v)' % (i))
+    return eval('%s:%s' % (l, ' or '.join(l2)))
+
+
+def l_not(f):
+    return eval('lambda v,f=f:not f(v)')
+
+
+def isdummyroutine(rout):
+    try:
+        return rout['f2pyenhancements']['fortranname'] == ''
+    except KeyError:
+        return 0
+
+
+def getfortranname(rout):
+    try:
+        name = rout['f2pyenhancements']['fortranname']
+        if name == '':
+            raise KeyError
+        if not name:
+            errmess('Failed to use fortranname from %s\n' %
+                    (rout['f2pyenhancements']))
+            raise KeyError
+    except KeyError:
+        name = rout['name']
+    return name
+
+
+def getmultilineblock(rout, blockname, comment=1, counter=0):
+    try:
+        r = rout['f2pyenhancements'].get(blockname)
+    except KeyError:
+        return
+    if not r:
+        return
+    if counter > 0 and isinstance(r, str):
+        return
+    if isinstance(r, list):
+        if counter >= len(r):
+            return
+        r = r[counter]
+    if r[:3] == "'''":
+        if comment:
+            r = '\t/* start ' + blockname + \
+                ' multiline (' + repr(counter) + ') */\n' + r[3:]
+        else:
+            r = r[3:]
+        if r[-3:] == "'''":
+            if comment:
+                r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/'
+            else:
+                r = r[:-3]
+        else:
+            errmess("%s multiline block should end with `'''`: %s\n"
+                    % (blockname, repr(r)))
+    return r
+
+
+def getcallstatement(rout):
+    return getmultilineblock(rout, 'callstatement')
+
+
+def getcallprotoargument(rout, cb_map={}):
+    r = getmultilineblock(rout, 'callprotoargument', comment=0)
+    if r:
+        return r
+    if hascallstatement(rout):
+        outmess(
+            'warning: callstatement is defined without callprotoargument\n')
+        return
+    from .capi_maps import getctype
+    arg_types, arg_types2 = [], []
+    if l_and(isstringfunction, l_not(isfunction_wrap))(rout):
+        arg_types.extend(['char*', 'size_t'])
+    for n in rout['args']:
+        var = rout['vars'][n]
+        if isintent_callback(var):
+            continue
+        if n in cb_map:
+            ctype = cb_map[n] + '_typedef'
+        else:
+            ctype = getctype(var)
+            if l_and(isintent_c, l_or(isscalar, iscomplex))(var):
+                pass
+            elif isstring(var):
+                pass
+            else:
+                ctype = ctype + '*'
+            if isstring(var) or isarrayofstrings(var):
+                arg_types2.append('size_t')
+        arg_types.append(ctype)
+
+    proto_args = ','.join(arg_types + arg_types2)
+    if not proto_args:
+        proto_args = 'void'
+    return proto_args
+
+
+def getusercode(rout):
+    return getmultilineblock(rout, 'usercode')
+
+
+def getusercode1(rout):
+    return getmultilineblock(rout, 'usercode', counter=1)
+
+
+def getpymethoddef(rout):
+    return getmultilineblock(rout, 'pymethoddef')
+
+
+def getargs(rout):
+    sortargs, args = [], []
+    if 'args' in rout:
+        args = rout['args']
+        if 'sortvars' in rout:
+            for a in rout['sortvars']:
+                if a in args:
+                    sortargs.append(a)
+            for a in args:
+                if a not in sortargs:
+                    sortargs.append(a)
+        else:
+            sortargs = rout['args']
+    return args, sortargs
+
+
+def getargs2(rout):
+    sortargs, args = [], rout.get('args', [])
+    auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])
+               and a not in args]
+    args = auxvars + args
+    if 'sortvars' in rout:
+        for a in rout['sortvars']:
+            if a in args:
+                sortargs.append(a)
+        for a in args:
+            if a not in sortargs:
+                sortargs.append(a)
+    else:
+        sortargs = auxvars + rout['args']
+    return args, sortargs
+
+
+def getrestdoc(rout):
+    if 'f2pymultilines' not in rout:
+        return None
+    k = None
+    if rout['block'] == 'python module':
+        k = rout['block'], rout['name']
+    return rout['f2pymultilines'].get(k, None)
+
+
+def gentitle(name):
+    l = (80 - len(name) - 6) // 2
+    return '/*%s %s %s*/' % (l * '*', name, l * '*')
+
+
+def flatlist(l):
+    if isinstance(l, list):
+        return reduce(lambda x, y, f=flatlist: x + f(y), l, [])
+    return [l]
+
+
+def stripcomma(s):
+    if s and s[-1] == ',':
+        return s[:-1]
+    return s
+
+
+def replace(str, d, defaultsep=''):
+    if isinstance(d, list):
+        return [replace(str, _m, defaultsep) for _m in d]
+    if isinstance(str, list):
+        return [replace(_m, d, defaultsep) for _m in str]
+    for k in 2 * list(d.keys()):
+        if k == 'separatorsfor':
+            continue
+        if 'separatorsfor' in d and k in d['separatorsfor']:
+            sep = d['separatorsfor'][k]
+        else:
+            sep = defaultsep
+        if isinstance(d[k], list):
+            str = str.replace('#%s#' % (k), sep.join(flatlist(d[k])))
+        else:
+            str = str.replace('#%s#' % (k), d[k])
+    return str
+
+
+def dictappend(rd, ar):
+    if isinstance(ar, list):
+        for a in ar:
+            rd = dictappend(rd, a)
+        return rd
+    for k in ar.keys():
+        if k[0] == '_':
+            continue
+        if k in rd:
+            if isinstance(rd[k], str):
+                rd[k] = [rd[k]]
+            if isinstance(rd[k], list):
+                if isinstance(ar[k], list):
+                    rd[k] = rd[k] + ar[k]
+                else:
+                    rd[k].append(ar[k])
+            elif isinstance(rd[k], dict):
+                if isinstance(ar[k], dict):
+                    if k == 'separatorsfor':
+                        for k1 in ar[k].keys():
+                            if k1 not in rd[k]:
+                                rd[k][k1] = ar[k][k1]
+                    else:
+                        rd[k] = dictappend(rd[k], ar[k])
+        else:
+            rd[k] = ar[k]
+    return rd
+
+
+def applyrules(rules, d, var={}):
+    ret = {}
+    if isinstance(rules, list):
+        for r in rules:
+            rr = applyrules(r, d, var)
+            ret = dictappend(ret, rr)
+            if '_break' in rr:
+                break
+        return ret
+    if '_check' in rules and (not rules['_check'](var)):
+        return ret
+    if 'need' in rules:
+        res = applyrules({'needs': rules['need']}, d, var)
+        if 'needs' in res:
+            cfuncs.append_needs(res['needs'])
+
+    for k in rules.keys():
+        if k == 'separatorsfor':
+            ret[k] = rules[k]
+            continue
+        if isinstance(rules[k], str):
+            ret[k] = replace(rules[k], d)
+        elif isinstance(rules[k], list):
+            ret[k] = []
+            for i in rules[k]:
+                ar = applyrules({k: i}, d, var)
+                if k in ar:
+                    ret[k].append(ar[k])
+        elif k[0] == '_':
+            continue
+        elif isinstance(rules[k], dict):
+            ret[k] = []
+            for k1 in rules[k].keys():
+                if isinstance(k1, types.FunctionType) and k1(var):
+                    if isinstance(rules[k][k1], list):
+                        for i in rules[k][k1]:
+                            if isinstance(i, dict):
+                                res = applyrules({'supertext': i}, d, var)
+                                if 'supertext' in res:
+                                    i = res['supertext']
+                                else:
+                                    i = ''
+                            ret[k].append(replace(i, d))
+                    else:
+                        i = rules[k][k1]
+                        if isinstance(i, dict):
+                            res = applyrules({'supertext': i}, d)
+                            if 'supertext' in res:
+                                i = res['supertext']
+                            else:
+                                i = ''
+                        ret[k].append(replace(i, d))
+        else:
+            errmess('applyrules: ignoring rule %s.\n' % repr(rules[k]))
+        if isinstance(ret[k], list):
+            if len(ret[k]) == 1:
+                ret[k] = ret[k][0]
+            if ret[k] == []:
+                del ret[k]
+    return ret
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
new file mode 100644
index 0000000000..28154dc805
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
@@ -0,0 +1,843 @@
+#!/usr/bin/env python2
+"""
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 10:57:33 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.60 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+import copy
+import re
+import os
+import sys
+from .crackfortran import markoutercomma
+from . import cb_rules
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+__all__ = [
+    'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
+    'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
+    'cb_sign2map', 'cb_routsign2map', 'common_sign2map'
+]
+
+
+# Numarray and Numeric users should set this False
+using_newcore = True
+
+depargs = []
+lcb_map = {}
+lcb2_map = {}
+# forced casting: mainly caused by the fact that Python or Numeric
+#                 C/APIs do not support the corresponding C types.
+c2py_map = {'double': 'float',
+            'float': 'float',                          # forced casting
+            'long_double': 'float',                    # forced casting
+            'char': 'int',                             # forced casting
+            'signed_char': 'int',                      # forced casting
+            'unsigned_char': 'int',                    # forced casting
+            'short': 'int',                            # forced casting
+            'unsigned_short': 'int',                   # forced casting
+            'int': 'int',                              # (forced casting)
+            'long': 'int',
+            'long_long': 'long',
+            'unsigned': 'int',                         # forced casting
+            'complex_float': 'complex',                # forced casting
+            'complex_double': 'complex',
+            'complex_long_double': 'complex',          # forced casting
+            'string': 'string',
+            }
+c2capi_map = {'double': 'NPY_DOUBLE',
+              'float': 'NPY_FLOAT',
+              'long_double': 'NPY_DOUBLE',           # forced casting
+              'char': 'NPY_CHAR',
+              'unsigned_char': 'NPY_UBYTE',
+              'signed_char': 'NPY_BYTE',
+              'short': 'NPY_SHORT',
+              'unsigned_short': 'NPY_USHORT',
+              'int': 'NPY_INT',
+              'unsigned': 'NPY_UINT',
+              'long': 'NPY_LONG',
+              'long_long': 'NPY_LONG',                # forced casting
+              'complex_float': 'NPY_CFLOAT',
+              'complex_double': 'NPY_CDOUBLE',
+              'complex_long_double': 'NPY_CDOUBLE',   # forced casting
+              'string': 'NPY_CHAR'}
+
+# These new maps aren't used anyhere yet, but should be by default
+#  unless building numeric or numarray extensions.
+if using_newcore:
+    c2capi_map = {'double': 'NPY_DOUBLE',
+                  'float': 'NPY_FLOAT',
+                  'long_double': 'NPY_LONGDOUBLE',
+                  'char': 'NPY_BYTE',
+                  'unsigned_char': 'NPY_UBYTE',
+                  'signed_char': 'NPY_BYTE',
+                  'short': 'NPY_SHORT',
+                  'unsigned_short': 'NPY_USHORT',
+                  'int': 'NPY_INT',
+                  'unsigned': 'NPY_UINT',
+                  'long': 'NPY_LONG',
+                  'unsigned_long': 'NPY_ULONG',
+                  'long_long': 'NPY_LONGLONG',
+                  'unsigned_long_long': 'NPY_ULONGLONG',
+                  'complex_float': 'NPY_CFLOAT',
+                  'complex_double': 'NPY_CDOUBLE',
+                  'complex_long_double': 'NPY_CDOUBLE',
+                  # f2py 2e is not ready for NPY_STRING (must set itemisize
+                  # etc)
+                  'string': 'NPY_CHAR',
+                  #'string':'NPY_STRING'
+
+                  }
+c2pycode_map = {'double': 'd',
+                'float': 'f',
+                'long_double': 'd',                       # forced casting
+                'char': '1',
+                'signed_char': '1',
+                'unsigned_char': 'b',
+                'short': 's',
+                'unsigned_short': 'w',
+                'int': 'i',
+                'unsigned': 'u',
+                'long': 'l',
+                'long_long': 'L',
+                'complex_float': 'F',
+                'complex_double': 'D',
+                'complex_long_double': 'D',               # forced casting
+                'string': 'c'
+                }
+if using_newcore:
+    c2pycode_map = {'double': 'd',
+                    'float': 'f',
+                    'long_double': 'g',
+                    'char': 'b',
+                    'unsigned_char': 'B',
+                    'signed_char': 'b',
+                    'short': 'h',
+                    'unsigned_short': 'H',
+                    'int': 'i',
+                    'unsigned': 'I',
+                    'long': 'l',
+                    'unsigned_long': 'L',
+                    'long_long': 'q',
+                    'unsigned_long_long': 'Q',
+                    'complex_float': 'F',
+                    'complex_double': 'D',
+                    'complex_long_double': 'G',
+                    'string': 'S'}
+c2buildvalue_map = {'double': 'd',
+                    'float': 'f',
+                    'char': 'b',
+                    'signed_char': 'b',
+                    'short': 'h',
+                    'int': 'i',
+                    'long': 'l',
+                    'long_long': 'L',
+                    'complex_float': 'N',
+                    'complex_double': 'N',
+                    'complex_long_double': 'N',
+                    'string': 'z'}
+
+if sys.version_info[0] >= 3:
+    # Bytes, not Unicode strings
+    c2buildvalue_map['string'] = 'y'
+
+if using_newcore:
+    # c2buildvalue_map=???
+    pass
+
+f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
+                       '12': 'long_double', '16': 'long_double'},
+              'integer': {'': 'int', '1': 'signed_char', '2': 'short',
+                          '4': 'int', '8': 'long_long',
+                          '-1': 'unsigned_char', '-2': 'unsigned_short',
+                          '-4': 'unsigned', '-8': 'unsigned_long_long'},
+              'complex': {'': 'complex_float', '8': 'complex_float',
+                          '16': 'complex_double', '24': 'complex_long_double',
+                          '32': 'complex_long_double'},
+              'complexkind': {'': 'complex_float', '4': 'complex_float',
+                              '8': 'complex_double', '12': 'complex_long_double',
+                              '16': 'complex_long_double'},
+              'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int',
+                          '8': 'long_long'},
+              'double complex': {'': 'complex_double'},
+              'double precision': {'': 'double'},
+              'byte': {'': 'char'},
+              'character': {'': 'string'}
+              }
+
+if os.path.isfile('.f2py_f2cmap'):
+    # User defined additions to f2cmap_all.
+    # .f2py_f2cmap must contain a dictionary of dictionaries, only.  For
+    # example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
+    # interpreted as C 'float'.  This feature is useful for F90/95 users if
+    # they use PARAMETERSs in type specifications.
+    try:
+        outmess('Reading .f2py_f2cmap ...\n')
+        f = open('.f2py_f2cmap', 'r')
+        d = eval(f.read(), {}, {})
+        f.close()
+        for k, d1 in list(d.items()):
+            for k1 in list(d1.keys()):
+                d1[k1.lower()] = d1[k1]
+            d[k.lower()] = d[k]
+        for k in list(d.keys()):
+            if k not in f2cmap_all:
+                f2cmap_all[k] = {}
+            for k1 in list(d[k].keys()):
+                if d[k][k1] in c2py_map:
+                    if k1 in f2cmap_all[k]:
+                        outmess(
+                            "\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n" % (k, k1, f2cmap_all[k][k1], d[k][k1]))
+                    f2cmap_all[k][k1] = d[k][k1]
+                    outmess('\tMapping "%s(kind=%s)" to "%s"\n' %
+                            (k, k1, d[k][k1]))
+                else:
+                    errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n" % (
+                        k, k1, d[k][k1], d[k][k1], list(c2py_map.keys())))
+        outmess('Succesfully applied user defined changes from .f2py_f2cmap\n')
+    except Exception as msg:
+        errmess(
+            'Failed to apply user defined changes from .f2py_f2cmap: %s. Skipping.\n' % (msg))
+
+cformat_map = {'double': '%g',
+               'float': '%g',
+               'long_double': '%Lg',
+               'char': '%d',
+               'signed_char': '%d',
+               'unsigned_char': '%hhu',
+               'short': '%hd',
+               'unsigned_short': '%hu',
+               'int': '%d',
+               'unsigned': '%u',
+               'long': '%ld',
+               'unsigned_long': '%lu',
+               'long_long': '%ld',
+               'complex_float': '(%g,%g)',
+               'complex_double': '(%g,%g)',
+               'complex_long_double': '(%Lg,%Lg)',
+               'string': '%s',
+               }
+
+# Auxiliary functions
+
+
+def getctype(var):
+    """
+    Determines C type
+    """
+    ctype = 'void'
+    if isfunction(var):
+        if 'result' in var:
+            a = var['result']
+        else:
+            a = var['name']
+        if a in var['vars']:
+            return getctype(var['vars'][a])
+        else:
+            errmess('getctype: function %s has no return value?!\n' % a)
+    elif issubroutine(var):
+        return ctype
+    elif 'typespec' in var and var['typespec'].lower() in f2cmap_all:
+        typespec = var['typespec'].lower()
+        f2cmap = f2cmap_all[typespec]
+        ctype = f2cmap['']  # default type
+        if 'kindselector' in var:
+            if '*' in var['kindselector']:
+                try:
+                    ctype = f2cmap[var['kindselector']['*']]
+                except KeyError:
+                    errmess('getctype: "%s %s %s" not supported.\n' %
+                            (var['typespec'], '*', var['kindselector']['*']))
+            elif 'kind' in var['kindselector']:
+                if typespec + 'kind' in f2cmap_all:
+                    f2cmap = f2cmap_all[typespec + 'kind']
+                try:
+                    ctype = f2cmap[var['kindselector']['kind']]
+                except KeyError:
+                    if typespec in f2cmap_all:
+                        f2cmap = f2cmap_all[typespec]
+                    try:
+                        ctype = f2cmap[str(var['kindselector']['kind'])]
+                    except KeyError:
+                        errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="<C typespec>")) in %s/.f2py_f2cmap file).\n'
+                                % (typespec, var['kindselector']['kind'], ctype,
+                                   typespec, var['kindselector']['kind'], os.getcwd()))
+
+    else:
+        if not isexternal(var):
+            errmess(
+                'getctype: No C-type found in "%s", assuming void.\n' % var)
+    return ctype
+
+
+def getstrlength(var):
+    if isstringfunction(var):
+        if 'result' in var:
+            a = var['result']
+        else:
+            a = var['name']
+        if a in var['vars']:
+            return getstrlength(var['vars'][a])
+        else:
+            errmess('getstrlength: function %s has no return value?!\n' % a)
+    if not isstring(var):
+        errmess(
+            'getstrlength: expected a signature of a string but got: %s\n' % (repr(var)))
+    len = '1'
+    if 'charselector' in var:
+        a = var['charselector']
+        if '*' in a:
+            len = a['*']
+        elif 'len' in a:
+            len = a['len']
+    if re.match(r'\(\s*([*]|[:])\s*\)', len) or re.match(r'([*]|[:])', len):
+        if isintent_hide(var):
+            errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
+                repr(var)))
+        len = '-1'
+    return len
+
+
+def getarrdims(a, var, verbose=0):
+    global depargs
+    ret = {}
+    if isstring(var) and not isarray(var):
+        ret['dims'] = getstrlength(var)
+        ret['size'] = ret['dims']
+        ret['rank'] = '1'
+    elif isscalar(var):
+        ret['size'] = '1'
+        ret['rank'] = '0'
+        ret['dims'] = ''
+    elif isarray(var):
+        dim = copy.copy(var['dimension'])
+        ret['size'] = '*'.join(dim)
+        try:
+            ret['size'] = repr(eval(ret['size']))
+        except:
+            pass
+        ret['dims'] = ','.join(dim)
+        ret['rank'] = repr(len(dim))
+        ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1]
+        for i in range(len(dim)):  # solve dim for dependecies
+            v = []
+            if dim[i] in depargs:
+                v = [dim[i]]
+            else:
+                for va in depargs:
+                    if re.match(r'.*?\b%s\b.*' % va, dim[i]):
+                        v.append(va)
+            for va in v:
+                if depargs.index(va) > depargs.index(a):
+                    dim[i] = '*'
+                    break
+        ret['setdims'], i = '', -1
+        for d in dim:
+            i = i + 1
+            if d not in ['*', ':', '(*)', '(:)']:
+                ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['setdims'], i, d)
+        if ret['setdims']:
+            ret['setdims'] = ret['setdims'][:-1]
+        ret['cbsetdims'], i = '', -1
+        for d in var['dimension']:
+            i = i + 1
+            if d not in ['*', ':', '(*)', '(:)']:
+                ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['cbsetdims'], i, d)
+            elif isintent_in(var):
+                outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n'
+                        % (d))
+                ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
+                    ret['cbsetdims'], i, 0)
+            elif verbose:
+                errmess(
+                    'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d)))
+        if ret['cbsetdims']:
+            ret['cbsetdims'] = ret['cbsetdims'][:-1]
+#         if not isintent_c(var):
+#             var['dimension'].reverse()
+    return ret
+
+
+def getpydocsign(a, var):
+    global lcb_map
+    if isfunction(var):
+        if 'result' in var:
+            af = var['result']
+        else:
+            af = var['name']
+        if af in var['vars']:
+            return getpydocsign(af, var['vars'][af])
+        else:
+            errmess('getctype: function %s has no return value?!\n' % af)
+        return '', ''
+    sig, sigout = a, a
+    opt = ''
+    if isintent_in(var):
+        opt = 'input'
+    elif isintent_inout(var):
+        opt = 'in/output'
+    out_a = a
+    if isintent_out(var):
+        for k in var['intent']:
+            if k[:4] == 'out=':
+                out_a = k[4:]
+                break
+    init = ''
+    ctype = getctype(var)
+
+    if hasinitvalue(var):
+        init, showinit = getinit(a, var)
+        init = ', optional\\n    Default: %s' % showinit
+    if isscalar(var):
+        if isintent_inout(var):
+            sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype],
+                                                         c2pycode_map[ctype], init)
+        else:
+            sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
+        sigout = '%s : %s' % (out_a, c2py_map[ctype])
+    elif isstring(var):
+        if isintent_inout(var):
+            sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % (
+                a, opt, getstrlength(var), init)
+        else:
+            sig = '%s : %s string(len=%s)%s' % (
+                a, opt, getstrlength(var), init)
+        sigout = '%s : string(len=%s)' % (out_a, getstrlength(var))
+    elif isarray(var):
+        dim = var['dimension']
+        rank = repr(len(dim))
+        sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank,
+                                                                    c2pycode_map[
+                                                                        ctype],
+                                                                    ','.join(dim), init)
+        if a == out_a:
+            sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\
+                % (a, rank, c2pycode_map[ctype], ','.join(dim))
+        else:
+            sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\
+                % (out_a, rank, c2pycode_map[ctype], ','.join(dim), a)
+    elif isexternal(var):
+        ua = ''
+        if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]:
+            ua = lcb2_map[lcb_map[a]]['argname']
+            if not ua == a:
+                ua = ' => %s' % ua
+            else:
+                ua = ''
+        sig = '%s : call-back function%s' % (a, ua)
+        sigout = sig
+    else:
+        errmess(
+            'getpydocsign: Could not resolve docsignature for "%s".\\n' % a)
+    return sig, sigout
+
+
+def getarrdocsign(a, var):
+    ctype = getctype(var)
+    if isstring(var) and (not isarray(var)):
+        sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a,
+                                                           getstrlength(var))
+    elif isscalar(var):
+        sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype],
+                                                c2pycode_map[ctype],)
+    elif isarray(var):
+        dim = var['dimension']
+        rank = repr(len(dim))
+        sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank,
+                                                               c2pycode_map[
+                                                                   ctype],
+                                                               ','.join(dim))
+    return sig
+
+
+def getinit(a, var):
+    if isstring(var):
+        init, showinit = '""', "''"
+    else:
+        init, showinit = '', ''
+    if hasinitvalue(var):
+        init = var['=']
+        showinit = init
+        if iscomplex(var) or iscomplexarray(var):
+            ret = {}
+
+            try:
+                v = var["="]
+                if ',' in v:
+                    ret['init.r'], ret['init.i'] = markoutercomma(
+                        v[1:-1]).split('@,@')
+                else:
+                    v = eval(v, {}, {})
+                    ret['init.r'], ret['init.i'] = str(v.real), str(v.imag)
+            except:
+                raise ValueError(
+                    'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a))
+            if isarray(var):
+                init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % (
+                    ret['init.r'], ret['init.i'])
+        elif isstring(var):
+            if not init:
+                init, showinit = '""', "''"
+            if init[0] == "'":
+                init = '"%s"' % (init[1:-1].replace('"', '\\"'))
+            if init[0] == '"':
+                showinit = "'%s'" % (init[1:-1])
+    return init, showinit
+
+
+def sign2map(a, var):
+    """
+    varname,ctype,atype
+    init,init.r,init.i,pytype
+    vardebuginfo,vardebugshowvalue,varshowvalue
+    varrfromat
+    intent
+    """
+    global lcb_map, cb_map
+    out_a = a
+    if isintent_out(var):
+        for k in var['intent']:
+            if k[:4] == 'out=':
+                out_a = k[4:]
+                break
+    ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)}
+    intent_flags = []
+    for f, s in isintent_dict.items():
+        if f(var):
+            intent_flags.append('F2PY_%s' % s)
+    if intent_flags:
+        # XXX: Evaluate intent_flags here.
+        ret['intent'] = '|'.join(intent_flags)
+    else:
+        ret['intent'] = 'F2PY_INTENT_IN'
+    if isarray(var):
+        ret['varrformat'] = 'N'
+    elif ret['ctype'] in c2buildvalue_map:
+        ret['varrformat'] = c2buildvalue_map[ret['ctype']]
+    else:
+        ret['varrformat'] = 'O'
+    ret['init'], ret['showinit'] = getinit(a, var)
+    if hasinitvalue(var) and iscomplex(var) and not isarray(var):
+        ret['init.r'], ret['init.i'] = markoutercomma(
+            ret['init'][1:-1]).split('@,@')
+    if isexternal(var):
+        ret['cbnamekey'] = a
+        if a in lcb_map:
+            ret['cbname'] = lcb_map[a]
+            ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs']
+            ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs']
+            ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr']
+            ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr']
+        else:
+            ret['cbname'] = a
+            errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % (
+                a, list(lcb_map.keys())))
+    if isstring(var):
+        ret['length'] = getstrlength(var)
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+        dim = copy.copy(var['dimension'])
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    # Debug info
+    if debugcapi(var):
+        il = [isintent_in, 'input', isintent_out, 'output',
+              isintent_inout, 'inoutput', isrequired, 'required',
+              isoptional, 'optional', isintent_hide, 'hidden',
+              iscomplex, 'complex scalar',
+              l_and(isscalar, l_not(iscomplex)), 'scalar',
+              isstring, 'string', isarray, 'array',
+              iscomplexarray, 'complex array', isstringarray, 'string array',
+              iscomplexfunction, 'complex function',
+              l_and(isfunction, l_not(iscomplexfunction)), 'function',
+              isexternal, 'callback',
+              isintent_callback, 'callback',
+              isintent_aux, 'auxiliary',
+              ]
+        rl = []
+        for i in range(0, len(il), 2):
+            if il[i](var):
+                rl.append(il[i + 1])
+        if isstring(var):
+            rl.append('slen(%s)=%s' % (a, ret['length']))
+        if isarray(var):
+            ddim = ','.join(
+                map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim))
+            rl.append('dims(%s)' % ddim)
+        if isexternal(var):
+            ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % (
+                a, ret['cbname'], ','.join(rl))
+        else:
+            ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % (
+                ret['ctype'], a, ret['showinit'], ','.join(rl))
+        if isscalar(var):
+            if ret['ctype'] in cformat_map:
+                ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % (
+                    a, cformat_map[ret['ctype']])
+        if isstring(var):
+            ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
+                a, a)
+        if isexternal(var):
+            ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a)
+    if ret['ctype'] in cformat_map:
+        ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']])
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isstring(var):
+        ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a)
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+    return ret
+
+
+def routsign2map(rout):
+    """
+    name,NAME,begintitle,endtitle
+    rname,ctype,rformat
+    routdebugshowvalue
+    """
+    global lcb_map
+    name = rout['name']
+    fname = getfortranname(rout)
+    ret = {'name': name,
+           'texname': name.replace('_', '\\_'),
+           'name_lower': name.lower(),
+           'NAME': name.upper(),
+           'begintitle': gentitle(name),
+           'endtitle': gentitle('end of %s' % name),
+           'fortranname': fname,
+           'FORTRANNAME': fname.upper(),
+           'callstatement': getcallstatement(rout) or '',
+           'usercode': getusercode(rout) or '',
+           'usercode1': getusercode1(rout) or '',
+           }
+    if '_' in fname:
+        ret['F_FUNC'] = 'F_FUNC_US'
+    else:
+        ret['F_FUNC'] = 'F_FUNC'
+    if '_' in name:
+        ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US'
+    else:
+        ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC'
+    lcb_map = {}
+    if 'use' in rout:
+        for u in rout['use'].keys():
+            if u in cb_rules.cb_map:
+                for un in cb_rules.cb_map[u]:
+                    ln = un[0]
+                    if 'map' in rout['use'][u]:
+                        for k in rout['use'][u]['map'].keys():
+                            if rout['use'][u]['map'][k] == un[0]:
+                                ln = k
+                                break
+                    lcb_map[ln] = un[1]
+    elif 'externals' in rout and rout['externals']:
+        errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % (
+            ret['name'], repr(rout['externals'])))
+    ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or ''
+    if isfunction(rout):
+        if 'result' in rout:
+            a = rout['result']
+        else:
+            a = rout['name']
+        ret['rname'] = a
+        ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
+        ret['ctype'] = getctype(rout['vars'][a])
+        if hasresultnote(rout):
+            ret['resultnote'] = rout['vars'][a]['note']
+            rout['vars'][a]['note'] = ['See elsewhere.']
+        if ret['ctype'] in c2buildvalue_map:
+            ret['rformat'] = c2buildvalue_map[ret['ctype']]
+        else:
+            ret['rformat'] = 'O'
+            errmess('routsign2map: no c2buildvalue key for type %s\n' %
+                    (repr(ret['ctype'])))
+        if debugcapi(rout):
+            if ret['ctype'] in cformat_map:
+                ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % (
+                    a, cformat_map[ret['ctype']])
+            if isstringfunction(rout):
+                ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
+                    a, a)
+        if isstringfunction(rout):
+            ret['rlength'] = getstrlength(rout['vars'][a])
+            if ret['rlength'] == '-1':
+                errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % (
+                    repr(rout['name'])))
+                ret['rlength'] = '10'
+    if hasnote(rout):
+        ret['note'] = rout['note']
+        rout['note'] = ['See elsewhere.']
+    return ret
+
+
+def modsign2map(m):
+    """
+    modulename
+    """
+    if ismodule(m):
+        ret = {'f90modulename': m['name'],
+               'F90MODULENAME': m['name'].upper(),
+               'texf90modulename': m['name'].replace('_', '\\_')}
+    else:
+        ret = {'modulename': m['name'],
+               'MODULENAME': m['name'].upper(),
+               'texmodulename': m['name'].replace('_', '\\_')}
+    ret['restdoc'] = getrestdoc(m) or []
+    if hasnote(m):
+        ret['note'] = m['note']
+    ret['usercode'] = getusercode(m) or ''
+    ret['usercode1'] = getusercode1(m) or ''
+    if m['body']:
+        ret['interface_usercode'] = getusercode(m['body'][0]) or ''
+    else:
+        ret['interface_usercode'] = ''
+    ret['pymethoddef'] = getpymethoddef(m) or ''
+    if 'coutput' in m:
+        ret['coutput'] = m['coutput']
+    if 'f2py_wrapper_output' in m:
+        ret['f2py_wrapper_output'] = m['f2py_wrapper_output']
+    return ret
+
+
+def cb_sign2map(a, var, index=None):
+    ret = {'varname': a}
+    if index is None or 1:  # disable 7712 patch
+        ret['varname_i'] = ret['varname']
+    else:
+        ret['varname_i'] = ret['varname'] + '_' + str(index)
+    ret['ctype'] = getctype(var)
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+        var['note'] = ['See elsewhere.']
+    return ret
+
+
+def cb_routsign2map(rout, um):
+    """
+    name,begintitle,endtitle,argname
+    ctype,rctype,maxnofargs,nofoptargs,returncptr
+    """
+    ret = {'name': 'cb_%s_in_%s' % (rout['name'], um),
+           'returncptr': ''}
+    if isintent_callback(rout):
+        if '_' in rout['name']:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        ret['callbackname'] = '%s(%s,%s)' \
+                              % (F_FUNC,
+                                 rout['name'].lower(),
+                                 rout['name'].upper(),
+                                 )
+        ret['static'] = 'extern'
+    else:
+        ret['callbackname'] = ret['name']
+        ret['static'] = 'static'
+    ret['argname'] = rout['name']
+    ret['begintitle'] = gentitle(ret['name'])
+    ret['endtitle'] = gentitle('end of %s' % ret['name'])
+    ret['ctype'] = getctype(rout)
+    ret['rctype'] = 'void'
+    if ret['ctype'] == 'string':
+        ret['rctype'] = 'void'
+    else:
+        ret['rctype'] = ret['ctype']
+    if ret['rctype'] != 'void':
+        if iscomplexfunction(rout):
+            ret['returncptr'] = """
+#ifdef F2PY_CB_RETURNCOMPLEX
+return_value=
+#endif
+"""
+        else:
+            ret['returncptr'] = 'return_value='
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isstringfunction(rout):
+        ret['strlength'] = getstrlength(rout)
+    if isfunction(rout):
+        if 'result' in rout:
+            a = rout['result']
+        else:
+            a = rout['name']
+        if hasnote(rout['vars'][a]):
+            ret['note'] = rout['vars'][a]['note']
+            rout['vars'][a]['note'] = ['See elsewhere.']
+        ret['rname'] = a
+        ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
+        if iscomplexfunction(rout):
+            ret['rctype'] = """
+#ifdef F2PY_CB_RETURNCOMPLEX
+#ctype#
+#else
+void
+#endif
+"""
+    else:
+        if hasnote(rout):
+            ret['note'] = rout['note']
+            rout['note'] = ['See elsewhere.']
+    nofargs = 0
+    nofoptargs = 0
+    if 'args' in rout and 'vars' in rout:
+        for a in rout['args']:
+            var = rout['vars'][a]
+            if l_or(isintent_in, isintent_inout)(var):
+                nofargs = nofargs + 1
+                if isoptional(var):
+                    nofoptargs = nofoptargs + 1
+    ret['maxnofargs'] = repr(nofargs)
+    ret['nofoptargs'] = repr(nofoptargs)
+    if hasnote(rout) and isfunction(rout) and 'result' in rout:
+        ret['routnote'] = rout['note']
+        rout['note'] = ['See elsewhere.']
+    return ret
+
+
+def common_sign2map(a, var):  # obsolute
+    ret = {'varname': a, 'ctype': getctype(var)}
+    if isstringarray(var):
+        ret['ctype'] = 'char'
+    if ret['ctype'] in c2capi_map:
+        ret['atype'] = c2capi_map[ret['ctype']]
+    if ret['ctype'] in cformat_map:
+        ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
+    if isarray(var):
+        ret = dictappend(ret, getarrdims(a, var))
+    elif isstring(var):
+        ret['size'] = getstrlength(var)
+        ret['rank'] = '1'
+    ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
+    if hasnote(var):
+        ret['note'] = var['note']
+        var['note'] = ['See elsewhere.']
+    # for strings this returns 0-rank but actually is 1-rank
+    ret['arrdocstr'] = getarrdocsign(a, var)
+    return ret
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
new file mode 100644
index 0000000000..e2b9c1efd9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
@@ -0,0 +1,554 @@
+#!/usr/bin/env python2
+"""
+
+Build call-back mechanism for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/07/20 11:27:58 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import __version__
+from .auxfuncs import (
+    applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray,
+    iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c,
+    isintent_hide, isintent_in, isintent_inout, isintent_nothide,
+    isintent_out, isoptional, isrequired, isscalar, isstring,
+    isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace,
+    stripcomma, throw_error
+)
+from . import cfuncs
+
+f2py_version = __version__.version
+
+
+################## Rules for callback function ##############
+
+cb_routine_rules = {
+    'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
+    'body': """
+#begintitle#
+PyObject *#name#_capi = NULL;/*was Py_None*/
+PyTupleObject *#name#_args_capi = NULL;
+int #name#_nofargs = 0;
+jmp_buf #name#_jmpbuf;
+/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
+#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
+\tPyTupleObject *capi_arglist = #name#_args_capi;
+\tPyObject *capi_return = NULL;
+\tPyObject *capi_tmp = NULL;
+\tint capi_j,capi_i = 0;
+\tint capi_longjmp_ok = 1;
+#decl#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_start_clock();
+#endif
+\tCFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
+\tCFUNCSMESSPY(\"cb:#name#_capi=\",#name#_capi);
+\tif (#name#_capi==NULL) {
+\t\tcapi_longjmp_ok = 0;
+\t\t#name#_capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
+\t}
+\tif (#name#_capi==NULL) {
+\t\tPyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
+\t\tgoto capi_fail;
+\t}
+\tif (F2PyCapsule_Check(#name#_capi)) {
+\t#name#_typedef #name#_cptr;
+\t#name#_cptr = F2PyCapsule_AsVoidPtr(#name#_capi);
+\t#returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
+\t#return#
+\t}
+\tif (capi_arglist==NULL) {
+\t\tcapi_longjmp_ok = 0;
+\t\tcapi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
+\t\tif (capi_tmp) {
+\t\t\tcapi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
+\t\t\tif (capi_arglist==NULL) {
+\t\t\t\tPyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
+\t\t\t\tgoto capi_fail;
+\t\t\t}
+\t\t} else {
+\t\t\tPyErr_Clear();
+\t\t\tcapi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
+\t\t}
+\t}
+\tif (capi_arglist == NULL) {
+\t\tPyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
+\t\tgoto capi_fail;
+\t}
+#setdims#
+#pyobjfrom#
+\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
+\tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_start_call_clock();
+#endif
+\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist);
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_stop_call_clock();
+#endif
+\tCFUNCSMESSPY(\"cb:capi_return=\",capi_return);
+\tif (capi_return == NULL) {
+\t\tfprintf(stderr,\"capi_return is NULL\\n\");
+\t\tgoto capi_fail;
+\t}
+\tif (capi_return == Py_None) {
+\t\tPy_DECREF(capi_return);
+\t\tcapi_return = Py_BuildValue(\"()\");
+\t}
+\telse if (!PyTuple_Check(capi_return)) {
+\t\tcapi_return = Py_BuildValue(\"(N)\",capi_return);
+\t}
+\tcapi_j = PyTuple_Size(capi_return);
+\tcapi_i = 0;
+#frompyobj#
+\tCFUNCSMESS(\"cb:#name#:successful\\n\");
+\tPy_DECREF(capi_return);
+#ifdef F2PY_REPORT_ATEXIT
+f2py_cb_stop_clock();
+#endif
+\tgoto capi_return_pt;
+capi_fail:
+\tfprintf(stderr,\"Call-back #name# failed.\\n\");
+\tPy_XDECREF(capi_return);
+\tif (capi_longjmp_ok)
+\t\tlongjmp(#name#_jmpbuf,-1);
+capi_return_pt:
+\t;
+#return#
+}
+#endtitle#
+""",
+    'need': ['setjmp.h', 'CFUNCSMESS'],
+    'maxnofargs': '#maxnofargs#',
+    'nofoptargs': '#nofoptargs#',
+    'docstr': """\
+\tdef #argname#(#docsignature#): return #docreturn#\\n\\
+#docstrsigns#""",
+    'latexdocstr': """
+{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
+#routnote#
+
+#latexdocstrsigns#""",
+    'docstrshort': 'def #argname#(#docsignature#): return #docreturn#'
+}
+cb_rout_rules = [
+    {  # Init
+        'separatorsfor': {'decl': '\n',
+                          'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
+                          'args_td': ',', 'optargs_td': '',
+                          'args_nm': ',', 'optargs_nm': '',
+                          'frompyobj': '\n', 'setdims': '\n',
+                          'docstrsigns': '\\n"\n"',
+                          'latexdocstrsigns': '\n',
+                          'latexdocstrreq': '\n', 'latexdocstropt': '\n',
+                          'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
+                          },
+        'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
+        'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
+        'args_td': [], 'optargs_td': '', 'strarglens_td': '',
+        'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
+        'noargs': '',
+        'setdims': '/*setdims*/',
+        'docstrsigns': '', 'latexdocstrsigns': '',
+        'docstrreq': '\tRequired arguments:',
+        'docstropt': '\tOptional arguments:',
+        'docstrout': '\tReturn objects:',
+        'docstrcbs': '\tCall-back functions:',
+        'docreturn': '', 'docsign': '', 'docsignopt': '',
+        'latexdocstrreq': '\\noindent Required arguments:',
+        'latexdocstropt': '\\noindent Optional arguments:',
+        'latexdocstrout': '\\noindent Return objects:',
+        'latexdocstrcbs': '\\noindent Call-back functions:',
+        'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
+    }, {  # Function
+        'decl': '\t#ctype# return_value;',
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
+                      '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");',
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#.\\n",return_value);'}
+                      ],
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
+        'return': '\treturn return_value;',
+        '_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
+    },
+    {  # String function
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
+        'args': '#ctype# return_value,int return_value_len',
+        'args_nm': 'return_value,&return_value_len',
+        'args_td': '#ctype# ,int',
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->\\"");'},
+                      """\tif (capi_j>capi_i)
+\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""",
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
+                      ],
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
+                 'string.h', 'GETSTRFROMPYTUPLE'],
+        'return': 'return;',
+        '_check': isstringfunction
+    },
+    {  # Complex function
+        'optargs': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+#ctype# *return_value
+#endif
+""",
+        'optargs_nm': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+return_value
+#endif
+""",
+        'optargs_td': """
+#ifndef F2PY_CB_RETURNCOMPLEX
+#ctype# *
+#endif
+""",
+        'decl': """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\t#ctype# return_value;
+#endif
+""",
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting return_value->");'},
+                      """\
+\tif (capi_j>capi_i)
+#ifdef F2PY_CB_RETURNCOMPLEX
+\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
+#else
+\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\");
+#endif
+""",
+                      {debugcapi: """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\tfprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
+#else
+\tfprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
+#endif
+
+"""}
+                      ],
+        'return': """
+#ifdef F2PY_CB_RETURNCOMPLEX
+\treturn return_value;
+#else
+\treturn;
+#endif
+""",
+        'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
+                 'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
+        '_check': iscomplexfunction
+    },
+    {'docstrout': '\t\t#pydocsignout#',
+     'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                        {hasnote: '--- #note#'}],
+     'docreturn': '#rname#,',
+     '_check': isfunction},
+    {'_check': issubroutine, 'return': 'return;'}
+]
+
+cb_arg_rules = [
+    {  # Doc
+        'docstropt': {l_and(isoptional, isintent_nothide): '\t\t#pydocsign#'},
+        'docstrreq': {l_and(isrequired, isintent_nothide): '\t\t#pydocsign#'},
+        'docstrout': {isintent_out: '\t\t#pydocsignout#'},
+        'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                                          {l_and(hasnote, isintent_hide): '--- #note#',
+                                           l_and(hasnote, isintent_nothide): '--- See above.'}]},
+        'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'},
+        'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'},
+        'depend': ''
+    },
+    {
+        'args': {
+            l_and(isscalar, isintent_c): '#ctype# #varname_i#',
+            l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi',
+            isarray: '#ctype# *#varname_i#',
+            isstring: '#ctype# #varname_i#'
+        },
+        'args_nm': {
+            l_and(isscalar, isintent_c): '#varname_i#',
+            l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi',
+            isarray: '#varname_i#',
+            isstring: '#varname_i#'
+        },
+        'args_td': {
+            l_and(isscalar, isintent_c): '#ctype#',
+            l_and(isscalar, l_not(isintent_c)): '#ctype# *',
+            isarray: '#ctype# *',
+            isstring: '#ctype#'
+        },
+        # untested with multiple args
+        'strarglens': {isstring: ',int #varname_i#_cb_len'},
+        'strarglens_td': {isstring: ',int'},  # untested with multiple args
+        # untested with multiple args
+        'strarglens_nm': {isstring: ',#varname_i#_cb_len'},
+    },
+    {  # Scalars
+        'decl': {l_not(isintent_c): '\t#ctype# #varname_i#=(*#varname_i#_cb_capi);'},
+        'error': {l_and(isintent_c, isintent_out,
+                        throw_error('intent(c,out) is forbidden for callback scalar arguments')):
+                  ''},
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
+                      {isintent_out:
+                       '\tif (capi_j>capi_i)\n\t\tGETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
+                      {l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
+                      {l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
+                      {l_and(debugcapi, l_and(iscomplex, isintent_c)):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
+                      {l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))):
+                          '\tfprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
+                      ],
+        'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
+                 {debugcapi: 'CFUNCSMESS'}],
+        '_check': isscalar
+    }, {
+        'pyobjfrom': [{isintent_in: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname_i#)))
+\t\t\tgoto capi_fail;"""},
+                      {isintent_inout: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
+\t\t\tgoto capi_fail;"""}],
+        'need': [{isintent_in: 'pyobj_from_#ctype#1'},
+                 {isintent_inout: 'pyarr_from_p_#ctype#1'},
+                 {iscomplex: '#ctype#'}],
+        '_check': l_and(isscalar, isintent_nothide),
+        '_optional': ''
+    }, {  # String
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->\\"");'},
+                      """\tif (capi_j>capi_i)
+\t\tGETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
+                      {debugcapi:
+                       '\tfprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
+                      ],
+        'need': ['#ctype#', 'GETSTRFROMPYTUPLE',
+                 {debugcapi: 'CFUNCSMESS'}, 'string.h'],
+        '_check': l_and(isstring, isintent_out)
+    }, {
+        'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'},
+                      {isintent_in: """\
+\tif (#name#_nofargs>capi_i)
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
+\t\t\tgoto capi_fail;"""},
+                      {isintent_inout: """\
+\tif (#name#_nofargs>capi_i) {
+\t\tint #varname_i#_cb_dims[] = {#varname_i#_cb_len};
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
+\t\t\tgoto capi_fail;
+\t}"""}],
+        'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
+                 {isintent_inout: 'pyarr_from_p_#ctype#1'}],
+        '_check': l_and(isstring, isintent_nothide),
+        '_optional': ''
+    },
+    # Array ...
+    {
+        'decl': '\tnpy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
+        'setdims': '\t#cbsetdims#;',
+        '_check': isarray,
+        '_depend': ''
+    },
+    {
+        'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#\\n");'},
+                      {isintent_c: """\
+\tif (#name#_nofargs>capi_i) {
+\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_CARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
+""",
+                       l_not(isintent_c): """\
+\tif (#name#_nofargs>capi_i) {
+\t\tPyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,0,NPY_ARRAY_FARRAY,NULL); /*XXX: Hmm, what will destroy this array??? */
+""",
+                       },
+                      """
+\t\tif (tmp_arr==NULL)
+\t\t\tgoto capi_fail;
+\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,(PyObject *)tmp_arr))
+\t\t\tgoto capi_fail;
+}"""],
+        '_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
+        '_optional': '',
+    }, {
+        'frompyobj': [{debugcapi: '\tCFUNCSMESS("cb:Getting #varname#->");'},
+                      """\tif (capi_j>capi_i) {
+\t\tPyArrayObject *rv_cb_arr = NULL;
+\t\tif ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
+\t\trv_cb_arr =  array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
+                      {isintent_c: '|F2PY_INTENT_C'},
+                      """,capi_tmp);
+\t\tif (rv_cb_arr == NULL) {
+\t\t\tfprintf(stderr,\"rv_cb_arr is NULL\\n\");
+\t\t\tgoto capi_fail;
+\t\t}
+\t\tMEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr));
+\t\tif (capi_tmp != (PyObject *)rv_cb_arr) {
+\t\t\tPy_DECREF(rv_cb_arr);
+\t\t}
+\t}""",
+                      {debugcapi: '\tfprintf(stderr,"<-.\\n");'},
+                      ],
+        'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}],
+        '_check': l_and(isarray, isintent_out)
+    }, {
+        'docreturn': '#varname#,',
+        '_check': isintent_out
+    }
+]
+
+################## Build call-back module #############
+cb_map = {}
+
+
+def buildcallbacks(m):
+    global cb_map
+    cb_map[m['name']] = []
+    for bi in m['body']:
+        if bi['block'] == 'interface':
+            for b in bi['body']:
+                if b:
+                    buildcallback(b, m['name'])
+                else:
+                    errmess('warning: empty body for %s\n' % (m['name']))
+
+
+def buildcallback(rout, um):
+    global cb_map
+    from . import capi_maps
+
+    outmess('\tConstructing call-back function "cb_%s_in_%s"\n' %
+            (rout['name'], um))
+    args, depargs = getargs(rout)
+    capi_maps.depargs = depargs
+    var = rout['vars']
+    vrd = capi_maps.cb_routsign2map(rout, um)
+    rd = dictappend({}, vrd)
+    cb_map[um].append([rout['name'], rd['name']])
+    for r in cb_rout_rules:
+        if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
+            ar = applyrules(r, vrd, rout)
+            rd = dictappend(rd, ar)
+    savevrd = {}
+    for i, a in enumerate(args):
+        vrd = capi_maps.cb_sign2map(a, var[a], index=i)
+        savevrd[a] = vrd
+        for r in cb_arg_rules:
+            if '_depend' in r:
+                continue
+            if '_optional' in r and isoptional(var[a]):
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in args:
+        vrd = savevrd[a]
+        for r in cb_arg_rules:
+            if '_depend' in r:
+                continue
+            if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in depargs:
+        vrd = savevrd[a]
+        for r in cb_arg_rules:
+            if '_depend' not in r:
+                continue
+            if '_optional' in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    if 'args' in rd and 'optargs' in rd:
+        if isinstance(rd['optargs'], list):
+            rd['optargs'] = rd['optargs'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+            rd['optargs_nm'] = rd['optargs_nm'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+            rd['optargs_td'] = rd['optargs_td'] + ["""
+#ifndef F2PY_CB_RETURNCOMPLEX
+,
+#endif
+"""]
+    if isinstance(rd['docreturn'], list):
+        rd['docreturn'] = stripcomma(
+            replace('#docreturn#', {'docreturn': rd['docreturn']}))
+    optargs = stripcomma(replace('#docsignopt#',
+                                 {'docsignopt': rd['docsignopt']}
+                                 ))
+    if optargs == '':
+        rd['docsignature'] = stripcomma(
+            replace('#docsign#', {'docsign': rd['docsign']}))
+    else:
+        rd['docsignature'] = replace('#docsign#[#docsignopt#]',
+                                     {'docsign': rd['docsign'],
+                                      'docsignopt': optargs,
+                                      })
+    rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_')
+    rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ')
+    rd['docstrsigns'] = []
+    rd['latexdocstrsigns'] = []
+    for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
+        if k in rd and isinstance(rd[k], list):
+            rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
+        k = 'latex' + k
+        if k in rd and isinstance(rd[k], list):
+            rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
+                ['\\begin{description}'] + rd[k][1:] +\
+                ['\\end{description}']
+    if 'args' not in rd:
+        rd['args'] = ''
+        rd['args_td'] = ''
+        rd['args_nm'] = ''
+    if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
+        rd['noargs'] = 'void'
+
+    ar = applyrules(cb_routine_rules, rd)
+    cfuncs.callbacks[rd['name']] = ar['body']
+    if isinstance(ar['need'], str):
+        ar['need'] = [ar['need']]
+
+    if 'need' in rd:
+        for t in cfuncs.typedefs.keys():
+            if t in rd['need']:
+                ar['need'].append(t)
+
+    cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs']
+    ar['need'].append(rd['name'] + '_typedef')
+    cfuncs.needs[rd['name']] = ar['need']
+
+    capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'],
+                                      'nofoptargs': ar['nofoptargs'],
+                                      'docstr': ar['docstr'],
+                                      'latexdocstr': ar['latexdocstr'],
+                                      'argname': rd['argname']
+                                      }
+    outmess('\t  %s\n' % (ar['docstrshort']))
+    return
+################## Build call-back function #############
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
new file mode 100644
index 0000000000..1d426bad37
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
@@ -0,0 +1,1261 @@
+#!/usr/bin/env python2
+"""
+
+C declarations, CPP macros, and C functions for f2py2e.
+Only required declarations/macros/functions will be used.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 11:42:34 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import copy
+
+from . import __version__
+
+f2py_version = __version__.version
+errmess = sys.stderr.write
+
+##################### Definitions ##################
+
+outneeds = {'includes0': [], 'includes': [], 'typedefs': [], 'typedefs_generated': [],
+            'userincludes': [],
+            'cppmacros': [], 'cfuncs': [], 'callbacks': [], 'f90modhooks': [],
+            'commonhooks': []}
+needs = {}
+includes0 = {'includes0': '/*need_includes0*/'}
+includes = {'includes': '/*need_includes*/'}
+userincludes = {'userincludes': '/*need_userincludes*/'}
+typedefs = {'typedefs': '/*need_typedefs*/'}
+typedefs_generated = {'typedefs_generated': '/*need_typedefs_generated*/'}
+cppmacros = {'cppmacros': '/*need_cppmacros*/'}
+cfuncs = {'cfuncs': '/*need_cfuncs*/'}
+callbacks = {'callbacks': '/*need_callbacks*/'}
+f90modhooks = {'f90modhooks': '/*need_f90modhooks*/',
+               'initf90modhooksstatic': '/*initf90modhooksstatic*/',
+               'initf90modhooksdynamic': '/*initf90modhooksdynamic*/',
+               }
+commonhooks = {'commonhooks': '/*need_commonhooks*/',
+               'initcommonhooks': '/*need_initcommonhooks*/',
+               }
+
+############ Includes ###################
+
+includes0['math.h'] = '#include <math.h>'
+includes0['string.h'] = '#include <string.h>'
+includes0['setjmp.h'] = '#include <setjmp.h>'
+
+includes['Python.h'] = '#include "Python.h"'
+needs['arrayobject.h'] = ['Python.h']
+includes['arrayobject.h'] = '''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
+#include "arrayobject.h"'''
+
+includes['arrayobject.h'] = '#include "fortranobject.h"'
+includes['stdarg.h'] = '#include <stdarg.h>'
+
+############# Type definitions ###############
+
+typedefs['unsigned_char'] = 'typedef unsigned char unsigned_char;'
+typedefs['unsigned_short'] = 'typedef unsigned short unsigned_short;'
+typedefs['unsigned_long'] = 'typedef unsigned long unsigned_long;'
+typedefs['signed_char'] = 'typedef signed char signed_char;'
+typedefs['long_long'] = """\
+#ifdef _WIN32
+typedef __int64 long_long;
+#else
+typedef long long long_long;
+typedef unsigned long long unsigned_long_long;
+#endif
+"""
+typedefs['unsigned_long_long'] = """\
+#ifdef _WIN32
+typedef __uint64 long_long;
+#else
+typedef unsigned long long unsigned_long_long;
+#endif
+"""
+typedefs['long_double'] = """\
+#ifndef _LONG_DOUBLE
+typedef long double long_double;
+#endif
+"""
+typedefs[
+    'complex_long_double'] = 'typedef struct {long double r,i;} complex_long_double;'
+typedefs['complex_float'] = 'typedef struct {float r,i;} complex_float;'
+typedefs['complex_double'] = 'typedef struct {double r,i;} complex_double;'
+typedefs['string'] = """typedef char * string;"""
+
+
+############### CPP macros ####################
+cppmacros['CFUNCSMESS'] = """\
+#ifdef DEBUGCFUNCS
+#define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess);
+#define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\
+\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
+\tfprintf(stderr,\"\\n\");
+#else
+#define CFUNCSMESS(mess)
+#define CFUNCSMESSPY(mess,obj)
+#endif
+"""
+cppmacros['F_FUNC'] = """\
+#if defined(PREPEND_FORTRAN)
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) _##F
+#else
+#define F_FUNC(f,F) _##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) _##F##_
+#else
+#define F_FUNC(f,F) _##f##_
+#endif
+#endif
+#else
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) F
+#else
+#define F_FUNC(f,F) f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_FUNC(f,F) F##_
+#else
+#define F_FUNC(f,F) f##_
+#endif
+#endif
+#endif
+#if defined(UNDERSCORE_G77)
+#define F_FUNC_US(f,F) F_FUNC(f##_,F##_)
+#else
+#define F_FUNC_US(f,F) F_FUNC(f,F)
+#endif
+"""
+cppmacros['F_WRAPPEDFUNC'] = """\
+#if defined(PREPEND_FORTRAN)
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F
+#else
+#define F_WRAPPEDFUNC(f,F) _f2pywrap##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_
+#else
+#define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_
+#endif
+#endif
+#else
+#if defined(NO_APPEND_FORTRAN)
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F
+#else
+#define F_WRAPPEDFUNC(f,F) f2pywrap##f
+#endif
+#else
+#if defined(UPPERCASE_FORTRAN)
+#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_
+#else
+#define F_WRAPPEDFUNC(f,F) f2pywrap##f##_
+#endif
+#endif
+#endif
+#if defined(UNDERSCORE_G77)
+#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_)
+#else
+#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F)
+#endif
+"""
+cppmacros['F_MODFUNC'] = """\
+#if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f
+#else
+#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _
+#endif
+#endif
+
+#if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f)  __ ## m ## _MOD_ ## f
+#else
+#define F_MODFUNCNAME(m,f)  __ ## m ## _MOD_ ## f ## _
+#endif
+#endif
+
+#if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */
+#if defined(NO_APPEND_FORTRAN)
+#define F_MODFUNCNAME(m,f)  f ## .in. ## m
+#else
+#define F_MODFUNCNAME(m,f)  f ## .in. ## m ## _
+#endif
+#endif
+/*
+#if defined(UPPERCASE_FORTRAN)
+#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F)
+#else
+#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f)
+#endif
+*/
+
+#define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f))
+"""
+cppmacros['SWAPUNSAFE'] = """\
+#define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\
+ (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\
+ (size_t)(a) = ((size_t)(a) ^ (size_t)(b))
+"""
+cppmacros['SWAP'] = """\
+#define SWAP(a,b,t) {\\
+\tt *c;\\
+\tc = a;\\
+\ta = b;\\
+\tb = c;}
+"""
+# cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) &
+# NPY_ARRAY_C_CONTIGUOUS)'
+cppmacros['PRINTPYOBJERR'] = """\
+#define PRINTPYOBJERR(obj)\\
+\tfprintf(stderr,\"#modulename#.error is related to \");\\
+\tPyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\
+\tfprintf(stderr,\"\\n\");
+"""
+cppmacros['MINMAX'] = """\
+#ifndef max
+#define max(a,b) ((a > b) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b) ((a < b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a > b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a < b) ? (a) : (b))
+#endif
+"""
+needs['len..'] = ['f2py_size']
+cppmacros['len..'] = """\
+#define rank(var) var ## _Rank
+#define shape(var,dim) var ## _Dims[dim]
+#define old_rank(var) (PyArray_NDIM((PyArrayObject *)(capi_ ## var ## _tmp)))
+#define old_shape(var,dim) PyArray_DIM(((PyArrayObject *)(capi_ ## var ## _tmp)),dim)
+#define fshape(var,dim) shape(var,rank(var)-dim-1)
+#define len(var) shape(var,0)
+#define flen(var) fshape(var,0)
+#define old_size(var) PyArray_SIZE((PyArrayObject *)(capi_ ## var ## _tmp))
+/* #define index(i) capi_i ## i */
+#define slen(var) capi_ ## var ## _len
+#define size(var, ...) f2py_size((PyArrayObject *)(capi_ ## var ## _tmp), ## __VA_ARGS__, -1)
+"""
+needs['f2py_size'] = ['stdarg.h']
+cfuncs['f2py_size'] = """\
+static int f2py_size(PyArrayObject* var, ...)
+{
+  npy_int sz = 0;
+  npy_int dim;
+  npy_int rank;
+  va_list argp;
+  va_start(argp, var);
+  dim = va_arg(argp, npy_int);
+  if (dim==-1)
+    {
+      sz = PyArray_SIZE(var);
+    }
+  else
+    {
+      rank = PyArray_NDIM(var);
+      if (dim>=1 && dim<=rank)
+        sz = PyArray_DIM(var, dim-1);
+      else
+        fprintf(stderr, \"f2py_size: 2nd argument value=%d fails to satisfy 1<=value<=%d. Result will be 0.\\n\", dim, rank);
+    }
+  va_end(argp);
+  return sz;
+}
+"""
+
+cppmacros[
+    'pyobj_from_char1'] = '#define pyobj_from_char1(v) (PyInt_FromLong(v))'
+cppmacros[
+    'pyobj_from_short1'] = '#define pyobj_from_short1(v) (PyInt_FromLong(v))'
+needs['pyobj_from_int1'] = ['signed_char']
+cppmacros['pyobj_from_int1'] = '#define pyobj_from_int1(v) (PyInt_FromLong(v))'
+cppmacros[
+    'pyobj_from_long1'] = '#define pyobj_from_long1(v) (PyLong_FromLong(v))'
+needs['pyobj_from_long_long1'] = ['long_long']
+cppmacros['pyobj_from_long_long1'] = """\
+#ifdef HAVE_LONG_LONG
+#define pyobj_from_long_long1(v) (PyLong_FromLongLong(v))
+#else
+#warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long.
+#define pyobj_from_long_long1(v) (PyLong_FromLong(v))
+#endif
+"""
+needs['pyobj_from_long_double1'] = ['long_double']
+cppmacros[
+    'pyobj_from_long_double1'] = '#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))'
+cppmacros[
+    'pyobj_from_double1'] = '#define pyobj_from_double1(v) (PyFloat_FromDouble(v))'
+cppmacros[
+    'pyobj_from_float1'] = '#define pyobj_from_float1(v) (PyFloat_FromDouble(v))'
+needs['pyobj_from_complex_long_double1'] = ['complex_long_double']
+cppmacros[
+    'pyobj_from_complex_long_double1'] = '#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_complex_double1'] = ['complex_double']
+cppmacros[
+    'pyobj_from_complex_double1'] = '#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_complex_float1'] = ['complex_float']
+cppmacros[
+    'pyobj_from_complex_float1'] = '#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))'
+needs['pyobj_from_string1'] = ['string']
+cppmacros[
+    'pyobj_from_string1'] = '#define pyobj_from_string1(v) (PyString_FromString((char *)v))'
+needs['pyobj_from_string1size'] = ['string']
+cppmacros[
+    'pyobj_from_string1size'] = '#define pyobj_from_string1size(v,len) (PyUString_FromStringAndSize((char *)v, len))'
+needs['TRYPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
+cppmacros['TRYPYARRAYTEMPLATE'] = """\
+/* New SciPy */
+#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break;
+#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;
+#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr)); break;
+
+#define TRYPYARRAYTEMPLATE(ctype,typecode) \\
+        PyArrayObject *arr = NULL;\\
+        if (!obj) return -2;\\
+        if (!PyArray_Check(obj)) return -1;\\
+        if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
+        if (PyArray_DESCR(arr)->type==typecode)  {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\
+        switch (PyArray_TYPE(arr)) {\\
+                case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_INT: *(int *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\
+                case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_SHORT: *(short *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\
+                case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_ ## ctype ## 1(*v),PyArray_DATA(arr), arr); break;\\
+        default: return -2;\\
+        };\\
+        return 1
+"""
+
+needs['TRYCOMPLEXPYARRAYTEMPLATE'] = ['PRINTPYOBJERR']
+cppmacros['TRYCOMPLEXPYARRAYTEMPLATE'] = """\
+#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break;
+#define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\
+        PyArrayObject *arr = NULL;\\
+        if (!obj) return -2;\\
+        if (!PyArray_Check(obj)) return -1;\\
+        if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\
+        if (PyArray_DESCR(arr)->type==typecode) {\\
+            *(ctype *)(PyArray_DATA(arr))=(*v).r;\\
+            *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\
+            return 1;\\
+        }\\
+        switch (PyArray_TYPE(arr)) {\\
+                case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r;*(double *)(PyArray_DATA(arr)+sizeof(double))=(*v).i;break;\\
+                case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=(*v).r;*(float *)(PyArray_DATA(arr)+sizeof(float))=(*v).i;break;\\
+                case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONG: *(long *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_INT: *(int *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_SHORT: *(short *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\
+                case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\
+                case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;*(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;break;\\
+                case NPY_OBJECT: (PyArray_DESCR(arr)->f->setitem)(pyobj_from_complex_ ## ctype ## 1((*v)),PyArray_DATA(arr), arr); break;\\
+                default: return -2;\\
+        };\\
+        return -1;
+"""
+# cppmacros['NUMFROMARROBJ']="""\
+# define NUMFROMARROBJ(typenum,ctype) \\
+# \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
+# \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
+# \tif (arr) {\\
+# \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\
+# \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
+# \t\t\tgoto capi_fail;\\
+# \t\t} else {\\
+# \t\t\t(PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\
+# \t\t}\\
+# \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
+# \t\treturn 1;\\
+# \t}
+# """
+# XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ
+# cppmacros['CNUMFROMARROBJ']="""\
+# define CNUMFROMARROBJ(typenum,ctype) \\
+# \tif (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\
+# \telse arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\
+# \tif (arr) {\\
+# \t\tif (PyArray_TYPE(arr)==NPY_OBJECT) {\\
+# \t\t\tif (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\
+# \t\t\tgoto capi_fail;\\
+# \t\t} else {\\
+# \t\t\t(PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\
+# \t\t}\\
+# \t\tif ((PyObject *)arr != obj) { Py_DECREF(arr); }\\
+# \t\treturn 1;\\
+# \t}
+# """
+
+
+needs['GETSTRFROMPYTUPLE'] = ['STRINGCOPYN', 'PRINTPYOBJERR']
+cppmacros['GETSTRFROMPYTUPLE'] = """\
+#define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\
+\t\tPyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\
+\t\tif (rv_cb_str == NULL)\\
+\t\t\tgoto capi_fail;\\
+\t\tif (PyString_Check(rv_cb_str)) {\\
+\t\t\tstr[len-1]='\\0';\\
+\t\t\tSTRINGCOPYN((str),PyString_AS_STRING((PyStringObject*)rv_cb_str),(len));\\
+\t\t} else {\\
+\t\t\tPRINTPYOBJERR(rv_cb_str);\\
+\t\t\tPyErr_SetString(#modulename#_error,\"string object expected\");\\
+\t\t\tgoto capi_fail;\\
+\t\t}\\
+\t}
+"""
+cppmacros['GETSCALARFROMPYTUPLE'] = """\
+#define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\
+\t\tif ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\
+\t\tif (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\
+\t\t\tgoto capi_fail;\\
+\t}
+"""
+
+cppmacros['FAILNULL'] = """\\
+#define FAILNULL(p) do {                                            \\
+    if ((p) == NULL) {                                              \\
+        PyErr_SetString(PyExc_MemoryError, "NULL pointer found");   \\
+        goto capi_fail;                                             \\
+    }                                                               \\
+} while (0)
+"""
+needs['MEMCOPY'] = ['string.h', 'FAILNULL']
+cppmacros['MEMCOPY'] = """\
+#define MEMCOPY(to,from,n)\\
+    do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0)
+"""
+cppmacros['STRINGMALLOC'] = """\
+#define STRINGMALLOC(str,len)\\
+\tif ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\
+\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
+\t\tgoto capi_fail;\\
+\t} else {\\
+\t\t(str)[len] = '\\0';\\
+\t}
+"""
+cppmacros['STRINGFREE'] = """\
+#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0)
+"""
+needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
+cppmacros['STRINGCOPYN'] = """\
+#define STRINGCOPYN(to,from,buf_size)                           \\
+    do {                                                        \\
+        int _m = (buf_size);                                    \\
+        char *_to = (to);                                       \\
+        char *_from = (from);                                   \\
+        FAILNULL(_to); FAILNULL(_from);                         \\
+        (void)strncpy(_to, _from, sizeof(char)*_m);             \\
+        _to[_m-1] = '\\0';                                      \\
+        /* Padding with spaces instead of nulls */              \\
+        for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) {      \\
+            _to[_m] = ' ';                                      \\
+        }                                                       \\
+    } while (0)
+"""
+needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
+cppmacros['STRINGCOPY'] = """\
+#define STRINGCOPY(to,from)\\
+    do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0)
+"""
+cppmacros['CHECKGENERIC'] = """\
+#define CHECKGENERIC(check,tcheck,name) \\
+\tif (!(check)) {\\
+\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKARRAY'] = """\
+#define CHECKARRAY(check,tcheck,name) \\
+\tif (!(check)) {\\
+\t\tPyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKSTRING'] = """\
+#define CHECKSTRING(check,tcheck,name,show,var)\\
+\tif (!(check)) {\\
+\t\tchar errstring[256];\\
+\t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\
+\t\tPyErr_SetString(#modulename#_error, errstring);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+cppmacros['CHECKSCALAR'] = """\
+#define CHECKSCALAR(check,tcheck,name,show,var)\\
+\tif (!(check)) {\\
+\t\tchar errstring[256];\\
+\t\tsprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\
+\t\tPyErr_SetString(#modulename#_error,errstring);\\
+\t\t/*goto capi_fail;*/\\
+\t} else """
+# cppmacros['CHECKDIMS']="""\
+# define CHECKDIMS(dims,rank) \\
+# \tfor (int i=0;i<(rank);i++)\\
+# \t\tif (dims[i]<0) {\\
+# \t\t\tfprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\
+# \t\t\tgoto capi_fail;\\
+# \t\t}
+# """
+cppmacros[
+    'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))'
+cppmacros['OLDPYNUM'] = """\
+#ifdef OLDPYNUM
+#error You need to intall Numeric Python version 13 or higher. Get it from http:/sourceforge.net/project/?group_id=1369
+#endif
+"""
+################# C functions ###############
+
+cfuncs['calcarrindex'] = """\
+static int calcarrindex(int *i,PyArrayObject *arr) {
+\tint k,ii = i[0];
+\tfor (k=1; k < PyArray_NDIM(arr); k++)
+\t\tii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */
+\treturn ii;
+}"""
+cfuncs['calcarrindextr'] = """\
+static int calcarrindextr(int *i,PyArrayObject *arr) {
+\tint k,ii = i[PyArray_NDIM(arr)-1];
+\tfor (k=1; k < PyArray_NDIM(arr); k++)
+\t\tii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */
+\treturn ii;
+}"""
+cfuncs['forcomb'] = """\
+static struct { int nd;npy_intp *d;int *i,*i_tr,tr; } forcombcache;
+static int initforcomb(npy_intp *dims,int nd,int tr) {
+  int k;
+  if (dims==NULL) return 0;
+  if (nd<0) return 0;
+  forcombcache.nd = nd;
+  forcombcache.d = dims;
+  forcombcache.tr = tr;
+  if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
+  if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0;
+  for (k=1;k<nd;k++) {
+    forcombcache.i[k] = forcombcache.i_tr[nd-k-1] = 0;
+  }
+  forcombcache.i[0] = forcombcache.i_tr[nd-1] = -1;
+  return 1;
+}
+static int *nextforcomb(void) {
+  int j,*i,*i_tr,k;
+  int nd=forcombcache.nd;
+  if ((i=forcombcache.i) == NULL) return NULL;
+  if ((i_tr=forcombcache.i_tr) == NULL) return NULL;
+  if (forcombcache.d == NULL) return NULL;
+  i[0]++;
+  if (i[0]==forcombcache.d[0]) {
+    j=1;
+    while ((j<nd) && (i[j]==forcombcache.d[j]-1)) j++;
+    if (j==nd) {
+      free(i);
+      free(i_tr);
+      return NULL;
+    }
+    for (k=0;k<j;k++) i[k] = i_tr[nd-k-1] = 0;
+    i[j]++;
+    i_tr[nd-j-1]++;
+  } else
+    i_tr[nd-1]++;
+  if (forcombcache.tr) return i_tr;
+  return i;
+}"""
+needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
+cfuncs['try_pyarr_from_string'] = """\
+static int try_pyarr_from_string(PyObject *obj,const string str) {
+\tPyArrayObject *arr = NULL;
+\tif (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL)))
+\t\t{ STRINGCOPYN(PyArray_DATA(arr),str,PyArray_NBYTES(arr)); }
+\treturn 1;
+capi_fail:
+\tPRINTPYOBJERR(obj);
+\tPyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\");
+\treturn 0;
+}
+"""
+needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
+cfuncs['string_from_pyobj'] = """\
+static int string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess) {
+\tPyArrayObject *arr = NULL;
+\tPyObject *tmp = NULL;
+#ifdef DEBUGCFUNCS
+fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj);
+#endif
+\tif (obj == Py_None) {
+\t\tif (*len == -1)
+\t\t\t*len = strlen(inistr); /* Will this cause problems? */
+\t\tSTRINGMALLOC(*str,*len);
+\t\tSTRINGCOPYN(*str,inistr,*len+1);
+\t\treturn 1;
+\t}
+\tif (PyArray_Check(obj)) {
+\t\tif ((arr = (PyArrayObject *)obj) == NULL)
+\t\t\tgoto capi_fail;
+\t\tif (!ISCONTIGUOUS(arr)) {
+\t\t\tPyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\");
+\t\t\tgoto capi_fail;
+\t\t}
+\t\tif (*len == -1)
+\t\t\t*len = (PyArray_ITEMSIZE(arr))*PyArray_SIZE(arr);
+\t\tSTRINGMALLOC(*str,*len);
+\t\tSTRINGCOPYN(*str,PyArray_DATA(arr),*len+1);
+\t\treturn 1;
+\t}
+\tif (PyString_Check(obj)) {
+\t\ttmp = obj;
+\t\tPy_INCREF(tmp);
+\t}
+#if PY_VERSION_HEX >= 0x03000000
+\telse if (PyUnicode_Check(obj)) {
+\t\ttmp = PyUnicode_AsASCIIString(obj);
+\t}
+\telse {
+\t\tPyObject *tmp2;
+\t\ttmp2 = PyObject_Str(obj);
+\t\tif (tmp2) {
+\t\t\ttmp = PyUnicode_AsASCIIString(tmp2);
+\t\t\tPy_DECREF(tmp2);
+\t\t}
+\t\telse {
+\t\t\ttmp = NULL;
+\t\t}
+\t}
+#else
+\telse {
+\t\ttmp = PyObject_Str(obj);
+\t}
+#endif
+\tif (tmp == NULL) goto capi_fail;
+\tif (*len == -1)
+\t\t*len = PyString_GET_SIZE(tmp);
+\tSTRINGMALLOC(*str,*len);
+\tSTRINGCOPYN(*str,PyString_AS_STRING(tmp),*len+1);
+\tPy_DECREF(tmp);
+\treturn 1;
+capi_fail:
+\tPy_XDECREF(tmp);
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['char_from_pyobj'] = ['int_from_pyobj']
+cfuncs['char_from_pyobj'] = """\
+static int char_from_pyobj(char* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (char)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['signed_char_from_pyobj'] = ['int_from_pyobj', 'signed_char']
+cfuncs['signed_char_from_pyobj'] = """\
+static int signed_char_from_pyobj(signed_char* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (signed_char)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['short_from_pyobj'] = ['int_from_pyobj']
+cfuncs['short_from_pyobj'] = """\
+static int short_from_pyobj(short* v,PyObject *obj,const char *errmess) {
+\tint i=0;
+\tif (int_from_pyobj(&i,obj,errmess)) {
+\t\t*v = (short)i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+cfuncs['int_from_pyobj'] = """\
+static int int_from_pyobj(int* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyInt_Check(obj)) {
+\t\t*v = (int)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Int(obj);
+\tif (tmp) {
+\t\t*v = PyInt_AS_LONG(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (int_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+cfuncs['long_from_pyobj'] = """\
+static int long_from_pyobj(long* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyInt_Check(obj)) {
+\t\t*v = PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Int(obj);
+\tif (tmp) {
+\t\t*v = PyInt_AS_LONG(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['long_long_from_pyobj'] = ['long_long']
+cfuncs['long_long_from_pyobj'] = """\
+static int long_long_from_pyobj(long_long* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyLong_Check(obj)) {
+\t\t*v = PyLong_AsLongLong(obj);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PyInt_Check(obj)) {
+\t\t*v = (long_long)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Long(obj);
+\tif (tmp) {
+\t\t*v = PyLong_AsLongLong(tmp);
+\t\tPy_DECREF(tmp);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (long_long_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['long_double_from_pyobj'] = ['double_from_pyobj', 'long_double']
+cfuncs['long_double_from_pyobj'] = """\
+static int long_double_from_pyobj(long_double* v,PyObject *obj,const char *errmess) {
+\tdouble d=0;
+\tif (PyArray_CheckScalar(obj)){
+\t\tif PyArray_IsScalar(obj, LongDouble) {
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t\treturn 1;
+\t\t}
+\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_LONGDOUBLE) {
+\t\t\t(*v) = *((npy_longdouble *)PyArray_DATA(obj));
+\t\t\treturn 1;
+\t\t}
+\t}
+\tif (double_from_pyobj(&d,obj,errmess)) {
+\t\t*v = (long_double)d;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+cfuncs['double_from_pyobj'] = """\
+static int double_from_pyobj(double* v,PyObject *obj,const char *errmess) {
+\tPyObject* tmp = NULL;
+\tif (PyFloat_Check(obj)) {
+#ifdef __sgi
+\t\t*v = PyFloat_AsDouble(obj);
+#else
+\t\t*v = PyFloat_AS_DOUBLE(obj);
+#endif
+\t\treturn 1;
+\t}
+\ttmp = PyNumber_Float(obj);
+\tif (tmp) {
+#ifdef __sgi
+\t\t*v = PyFloat_AsDouble(tmp);
+#else
+\t\t*v = PyFloat_AS_DOUBLE(tmp);
+#endif
+\t\tPy_DECREF(tmp);
+\t\treturn 1;
+\t}
+\tif (PyComplex_Check(obj))
+\t\ttmp = PyObject_GetAttrString(obj,\"real\");
+\telse if (PyString_Check(obj) || PyUnicode_Check(obj))
+\t\t/*pass*/;
+\telse if (PySequence_Check(obj))
+\t\ttmp = PySequence_GetItem(obj,0);
+\tif (tmp) {
+\t\tPyErr_Clear();
+\t\tif (double_from_pyobj(v,tmp,errmess)) {Py_DECREF(tmp); return 1;}
+\t\tPy_DECREF(tmp);
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL) err = #modulename#_error;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['float_from_pyobj'] = ['double_from_pyobj']
+cfuncs['float_from_pyobj'] = """\
+static int float_from_pyobj(float* v,PyObject *obj,const char *errmess) {
+\tdouble d=0.0;
+\tif (double_from_pyobj(&d,obj,errmess)) {
+\t\t*v = (float)d;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['complex_long_double_from_pyobj'] = ['complex_long_double', 'long_double',
+                                           'complex_double_from_pyobj']
+cfuncs['complex_long_double_from_pyobj'] = """\
+static int complex_long_double_from_pyobj(complex_long_double* v,PyObject *obj,const char *errmess) {
+\tcomplex_double cd={0.0,0.0};
+\tif (PyArray_CheckScalar(obj)){
+\t\tif PyArray_IsScalar(obj, CLongDouble) {
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t\treturn 1;
+\t\t}
+\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==NPY_CLONGDOUBLE) {
+\t\t\t(*v).r = ((npy_clongdouble *)PyArray_DATA(obj))->real;
+\t\t\t(*v).i = ((npy_clongdouble *)PyArray_DATA(obj))->imag;
+\t\t\treturn 1;
+\t\t}
+\t}
+\tif (complex_double_from_pyobj(&cd,obj,errmess)) {
+\t\t(*v).r = (long_double)cd.r;
+\t\t(*v).i = (long_double)cd.i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['complex_double_from_pyobj'] = ['complex_double']
+cfuncs['complex_double_from_pyobj'] = """\
+static int complex_double_from_pyobj(complex_double* v,PyObject *obj,const char *errmess) {
+\tPy_complex c;
+\tif (PyComplex_Check(obj)) {
+\t\tc=PyComplex_AsCComplex(obj);
+\t\t(*v).r=c.real, (*v).i=c.imag;
+\t\treturn 1;
+\t}
+\tif (PyArray_IsScalar(obj, ComplexFloating)) {
+\t\tif (PyArray_IsScalar(obj, CFloat)) {
+\t\t\tnpy_cfloat new;
+\t\t\tPyArray_ScalarAsCtype(obj, &new);
+\t\t\t(*v).r = (double)new.real;
+\t\t\t(*v).i = (double)new.imag;
+\t\t}
+\t\telse if (PyArray_IsScalar(obj, CLongDouble)) {
+\t\t\tnpy_clongdouble new;
+\t\t\tPyArray_ScalarAsCtype(obj, &new);
+\t\t\t(*v).r = (double)new.real;
+\t\t\t(*v).i = (double)new.imag;
+\t\t}
+\t\telse { /* if (PyArray_IsScalar(obj, CDouble)) */
+\t\t\tPyArray_ScalarAsCtype(obj, v);
+\t\t}
+\t\treturn 1;
+\t}
+\tif (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */
+\t\tPyObject *arr;
+\t\tif (PyArray_Check(obj)) {
+\t\t\tarr = PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE);
+\t\t}
+\t\telse {
+\t\t\tarr = PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE));
+\t\t}
+\t\tif (arr==NULL) return 0;
+\t\t(*v).r = ((npy_cdouble *)PyArray_DATA(arr))->real;
+\t\t(*v).i = ((npy_cdouble *)PyArray_DATA(arr))->imag;
+\t\treturn 1;
+\t}
+\t/* Python does not provide PyNumber_Complex function :-( */
+\t(*v).i=0.0;
+\tif (PyFloat_Check(obj)) {
+#ifdef __sgi
+\t\t(*v).r = PyFloat_AsDouble(obj);
+#else
+\t\t(*v).r = PyFloat_AS_DOUBLE(obj);
+#endif
+\t\treturn 1;
+\t}
+\tif (PyInt_Check(obj)) {
+\t\t(*v).r = (double)PyInt_AS_LONG(obj);
+\t\treturn 1;
+\t}
+\tif (PyLong_Check(obj)) {
+\t\t(*v).r = PyLong_AsDouble(obj);
+\t\treturn (!PyErr_Occurred());
+\t}
+\tif (PySequence_Check(obj) && !(PyString_Check(obj) || PyUnicode_Check(obj))) {
+\t\tPyObject *tmp = PySequence_GetItem(obj,0);
+\t\tif (tmp) {
+\t\t\tif (complex_double_from_pyobj(v,tmp,errmess)) {
+\t\t\t\tPy_DECREF(tmp);
+\t\t\t\treturn 1;
+\t\t\t}
+\t\t\tPy_DECREF(tmp);
+\t\t}
+\t}
+\t{
+\t\tPyObject* err = PyErr_Occurred();
+\t\tif (err==NULL)
+\t\t\terr = PyExc_TypeError;
+\t\tPyErr_SetString(err,errmess);
+\t}
+\treturn 0;
+}
+"""
+needs['complex_float_from_pyobj'] = [
+    'complex_float', 'complex_double_from_pyobj']
+cfuncs['complex_float_from_pyobj'] = """\
+static int complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess) {
+\tcomplex_double cd={0.0,0.0};
+\tif (complex_double_from_pyobj(&cd,obj,errmess)) {
+\t\t(*v).r = (float)cd.r;
+\t\t(*v).i = (float)cd.i;
+\t\treturn 1;
+\t}
+\treturn 0;
+}
+"""
+needs['try_pyarr_from_char'] = ['pyobj_from_char1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_char'] = 'static int try_pyarr_from_char(PyObject* obj,char* v) {\n\tTRYPYARRAYTEMPLATE(char,\'c\');\n}\n'
+needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'unsigned_char']
+cfuncs[
+    'try_pyarr_from_unsigned_char'] = 'static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n\tTRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n'
+needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'signed_char']
+cfuncs[
+    'try_pyarr_from_signed_char'] = 'static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n\tTRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n'
+needs['try_pyarr_from_short'] = ['pyobj_from_short1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_short'] = 'static int try_pyarr_from_short(PyObject* obj,short* v) {\n\tTRYPYARRAYTEMPLATE(short,\'s\');\n}\n'
+needs['try_pyarr_from_int'] = ['pyobj_from_int1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_int'] = 'static int try_pyarr_from_int(PyObject* obj,int* v) {\n\tTRYPYARRAYTEMPLATE(int,\'i\');\n}\n'
+needs['try_pyarr_from_long'] = ['pyobj_from_long1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_long'] = 'static int try_pyarr_from_long(PyObject* obj,long* v) {\n\tTRYPYARRAYTEMPLATE(long,\'l\');\n}\n'
+needs['try_pyarr_from_long_long'] = [
+    'pyobj_from_long_long1', 'TRYPYARRAYTEMPLATE', 'long_long']
+cfuncs[
+    'try_pyarr_from_long_long'] = 'static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n\tTRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n'
+needs['try_pyarr_from_float'] = ['pyobj_from_float1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_float'] = 'static int try_pyarr_from_float(PyObject* obj,float* v) {\n\tTRYPYARRAYTEMPLATE(float,\'f\');\n}\n'
+needs['try_pyarr_from_double'] = ['pyobj_from_double1', 'TRYPYARRAYTEMPLATE']
+cfuncs[
+    'try_pyarr_from_double'] = 'static int try_pyarr_from_double(PyObject* obj,double* v) {\n\tTRYPYARRAYTEMPLATE(double,\'d\');\n}\n'
+needs['try_pyarr_from_complex_float'] = [
+    'pyobj_from_complex_float1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_float']
+cfuncs[
+    'try_pyarr_from_complex_float'] = 'static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n'
+needs['try_pyarr_from_complex_double'] = [
+    'pyobj_from_complex_double1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_double']
+cfuncs[
+    'try_pyarr_from_complex_double'] = 'static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n\tTRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n'
+
+needs['create_cb_arglist'] = ['CFUNCSMESS', 'PRINTPYOBJERR', 'MINMAX']
+cfuncs['create_cb_arglist'] = """\
+static int create_cb_arglist(PyObject* fun,PyTupleObject* xa,const int maxnofargs,const int nofoptargs,int *nofargs,PyTupleObject **args,const char *errmess) {
+\tPyObject *tmp = NULL;
+\tPyObject *tmp_fun = NULL;
+\tint tot,opt,ext,siz,i,di=0;
+\tCFUNCSMESS(\"create_cb_arglist\\n\");
+\ttot=opt=ext=siz=0;
+\t/* Get the total number of arguments */
+\tif (PyFunction_Check(fun))
+\t\ttmp_fun = fun;
+\telse {
+\t\tdi = 1;
+\t\tif (PyObject_HasAttrString(fun,\"im_func\")) {
+\t\t\ttmp_fun = PyObject_GetAttrString(fun,\"im_func\");
+\t\t}
+\t\telse if (PyObject_HasAttrString(fun,\"__call__\")) {
+\t\t\ttmp = PyObject_GetAttrString(fun,\"__call__\");
+\t\t\tif (PyObject_HasAttrString(tmp,\"im_func\"))
+\t\t\t\ttmp_fun = PyObject_GetAttrString(tmp,\"im_func\");
+\t\t\telse {
+\t\t\t\ttmp_fun = fun; /* built-in function */
+\t\t\t\ttot = maxnofargs;
+\t\t\t\tif (xa != NULL)
+\t\t\t\t\ttot += PyTuple_Size((PyObject *)xa);
+\t\t\t}
+\t\t\tPy_XDECREF(tmp);
+\t\t}
+\t\telse if (PyFortran_Check(fun) || PyFortran_Check1(fun)) {
+\t\t\ttot = maxnofargs;
+\t\t\tif (xa != NULL)
+\t\t\t\ttot += PyTuple_Size((PyObject *)xa);
+\t\t\ttmp_fun = fun;
+\t\t}
+\t\telse if (F2PyCapsule_Check(fun)) {
+\t\t\ttot = maxnofargs;
+\t\t\tif (xa != NULL)
+\t\t\t\text = PyTuple_Size((PyObject *)xa);
+\t\t\tif(ext>0) {
+\t\t\t\tfprintf(stderr,\"extra arguments tuple cannot be used with CObject call-back\\n\");
+\t\t\t\tgoto capi_fail;
+\t\t\t}
+\t\t\ttmp_fun = fun;
+\t\t}
+\t}
+if (tmp_fun==NULL) {
+fprintf(stderr,\"Call-back argument must be function|instance|instance.__call__|f2py-function but got %s.\\n\",(fun==NULL?\"NULL\":Py_TYPE(fun)->tp_name));
+goto capi_fail;
+}
+#if PY_VERSION_HEX >= 0x03000000
+\tif (PyObject_HasAttrString(tmp_fun,\"__code__\")) {
+\t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\"))
+#else
+\tif (PyObject_HasAttrString(tmp_fun,\"func_code\")) {
+\t\tif (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"func_code\"),\"co_argcount\"))
+#endif
+\t\t\ttot = PyInt_AsLong(PyObject_GetAttrString(tmp,\"co_argcount\")) - di;
+\t\tPy_XDECREF(tmp);
+\t}
+\t/* Get the number of optional arguments */
+#if PY_VERSION_HEX >= 0x03000000
+\tif (PyObject_HasAttrString(tmp_fun,\"__defaults__\")) {
+\t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"__defaults__\")))
+#else
+\tif (PyObject_HasAttrString(tmp_fun,\"func_defaults\")) {
+\t\tif (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"func_defaults\")))
+#endif
+\t\t\topt = PyTuple_Size(tmp);
+\t\tPy_XDECREF(tmp);
+\t}
+\t/* Get the number of extra arguments */
+\tif (xa != NULL)
+\t\text = PyTuple_Size((PyObject *)xa);
+\t/* Calculate the size of call-backs argument list */
+\tsiz = MIN(maxnofargs+ext,tot);
+\t*nofargs = MAX(0,siz-ext);
+#ifdef DEBUGCFUNCS
+\tfprintf(stderr,\"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),tot,opt,ext,siz,nofargs=%d(-%d),%d,%d,%d,%d,%d\\n\",maxnofargs,nofoptargs,tot,opt,ext,siz,*nofargs);
+#endif
+\tif (siz<tot-opt) {
+\t\tfprintf(stderr,\"create_cb_arglist: Failed to build argument list (siz) with enough arguments (tot-opt) required by user-supplied function (siz,tot,opt=%d,%d,%d).\\n\",siz,tot,opt);
+\t\tgoto capi_fail;
+\t}
+\t/* Initialize argument list */
+\t*args = (PyTupleObject *)PyTuple_New(siz);
+\tfor (i=0;i<*nofargs;i++) {
+\t\tPy_INCREF(Py_None);
+\t\tPyTuple_SET_ITEM((PyObject *)(*args),i,Py_None);
+\t}
+\tif (xa != NULL)
+\t\tfor (i=(*nofargs);i<siz;i++) {
+\t\t\ttmp = PyTuple_GetItem((PyObject *)xa,i-(*nofargs));
+\t\t\tPy_INCREF(tmp);
+\t\t\tPyTuple_SET_ITEM(*args,i,tmp);
+\t\t}
+\tCFUNCSMESS(\"create_cb_arglist-end\\n\");
+\treturn 1;
+capi_fail:
+\tif ((PyErr_Occurred())==NULL)
+\t\tPyErr_SetString(#modulename#_error,errmess);
+\treturn 0;
+}
+"""
+
+
+def buildcfuncs():
+    from .capi_maps import c2capi_map
+    for k in c2capi_map.keys():
+        m = 'pyarr_from_p_%s1' % k
+        cppmacros[
+            m] = '#define %s(v) (PyArray_SimpleNewFromData(0,NULL,%s,(char *)v))' % (m, c2capi_map[k])
+    k = 'string'
+    m = 'pyarr_from_p_%s1' % k
+    cppmacros[
+        m] = '#define %s(v,dims) (PyArray_SimpleNewFromData(1,dims,NPY_CHAR,(char *)v))' % (m)
+
+
+############ Auxiliary functions for sorting needs ###################
+
+def append_needs(need, flag=1):
+    global outneeds, needs
+    if isinstance(need, list):
+        for n in need:
+            append_needs(n, flag)
+    elif isinstance(need, str):
+        if not need:
+            return
+        if need in includes0:
+            n = 'includes0'
+        elif need in includes:
+            n = 'includes'
+        elif need in typedefs:
+            n = 'typedefs'
+        elif need in typedefs_generated:
+            n = 'typedefs_generated'
+        elif need in cppmacros:
+            n = 'cppmacros'
+        elif need in cfuncs:
+            n = 'cfuncs'
+        elif need in callbacks:
+            n = 'callbacks'
+        elif need in f90modhooks:
+            n = 'f90modhooks'
+        elif need in commonhooks:
+            n = 'commonhooks'
+        else:
+            errmess('append_needs: unknown need %s\n' % (repr(need)))
+            return
+        if need in outneeds[n]:
+            return
+        if flag:
+            tmp = {}
+            if need in needs:
+                for nn in needs[need]:
+                    t = append_needs(nn, 0)
+                    if isinstance(t, dict):
+                        for nnn in t.keys():
+                            if nnn in tmp:
+                                tmp[nnn] = tmp[nnn] + t[nnn]
+                            else:
+                                tmp[nnn] = t[nnn]
+            for nn in tmp.keys():
+                for nnn in tmp[nn]:
+                    if nnn not in outneeds[nn]:
+                        outneeds[nn] = [nnn] + outneeds[nn]
+            outneeds[n].append(need)
+        else:
+            tmp = {}
+            if need in needs:
+                for nn in needs[need]:
+                    t = append_needs(nn, flag)
+                    if isinstance(t, dict):
+                        for nnn in t.keys():
+                            if nnn in tmp:
+                                tmp[nnn] = t[nnn] + tmp[nnn]
+                            else:
+                                tmp[nnn] = t[nnn]
+            if n not in tmp:
+                tmp[n] = []
+            tmp[n].append(need)
+            return tmp
+    else:
+        errmess('append_needs: expected list or string but got :%s\n' %
+                (repr(need)))
+
+
+def get_needs():
+    global outneeds, needs
+    res = {}
+    for n in outneeds.keys():
+        out = []
+        saveout = copy.copy(outneeds[n])
+        while len(outneeds[n]) > 0:
+            if outneeds[n][0] not in needs:
+                out.append(outneeds[n][0])
+                del outneeds[n][0]
+            else:
+                flag = 0
+                for k in outneeds[n][1:]:
+                    if k in needs[outneeds[n][0]]:
+                        flag = 1
+                        break
+                if flag:
+                    outneeds[n] = outneeds[n][1:] + [outneeds[n][0]]
+                else:
+                    out.append(outneeds[n][0])
+                    del outneeds[n][0]
+            if saveout and (0 not in map(lambda x, y: x == y, saveout, outneeds[n])) \
+                    and outneeds[n] != []:
+                print(n, saveout)
+                errmess(
+                    'get_needs: no progress in sorting needs, probably circular dependence, skipping.\n')
+                out = out + saveout
+                break
+            saveout = copy.copy(outneeds[n])
+        if out == []:
+            out = [n]
+        res[n] = out
+    return res
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.py
new file mode 100644
index 0000000000..1210064bc2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python2
+"""
+
+Build common block mechanism for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 10:57:33 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.19 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+from .auxfuncs import (
+    hasbody, hascommon, hasnote, isintent_hide, outmess
+)
+from . import capi_maps
+from . import func2subr
+from .crackfortran import rmbadname
+
+
+def findcommonblocks(block, top=1):
+    ret = []
+    if hascommon(block):
+        for n in block['common'].keys():
+            vars = {}
+            for v in block['common'][n]:
+                vars[v] = block['vars'][v]
+            ret.append((n, block['common'][n], vars))
+    elif hasbody(block):
+        for b in block['body']:
+            ret = ret + findcommonblocks(b, 0)
+    if top:
+        tret = []
+        names = []
+        for t in ret:
+            if t[0] not in names:
+                names.append(t[0])
+                tret.append(t)
+        return tret
+    return ret
+
+
+def buildhooks(m):
+    ret = {'commonhooks': [], 'initcommonhooks': [],
+           'docs': ['"COMMON blocks:\\n"']}
+    fwrap = ['']
+
+    def fadd(line, s=fwrap):
+        s[0] = '%s\n      %s' % (s[0], line)
+    chooks = ['']
+
+    def cadd(line, s=chooks):
+        s[0] = '%s\n%s' % (s[0], line)
+    ihooks = ['']
+
+    def iadd(line, s=ihooks):
+        s[0] = '%s\n%s' % (s[0], line)
+    doc = ['']
+
+    def dadd(line, s=doc):
+        s[0] = '%s\n%s' % (s[0], line)
+    for (name, vnames, vars) in findcommonblocks(m):
+        lower_name = name.lower()
+        hnames, inames = [], []
+        for n in vnames:
+            if isintent_hide(vars[n]):
+                hnames.append(n)
+            else:
+                inames.append(n)
+        if hnames:
+            outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t  %s\n\t\t  Hidden: %s\n' % (
+                name, ','.join(inames), ','.join(hnames)))
+        else:
+            outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t  %s\n' % (
+                name, ','.join(inames)))
+        fadd('subroutine f2pyinit%s(setupfunc)' % name)
+        fadd('external setupfunc')
+        for n in vnames:
+            fadd(func2subr.var2fixfortran(vars, n))
+        if name == '_BLNK_':
+            fadd('common %s' % (','.join(vnames)))
+        else:
+            fadd('common /%s/ %s' % (name, ','.join(vnames)))
+        fadd('call setupfunc(%s)' % (','.join(inames)))
+        fadd('end\n')
+        cadd('static FortranDataDef f2py_%s_def[] = {' % (name))
+        idims = []
+        for n in inames:
+            ct = capi_maps.getctype(vars[n])
+            at = capi_maps.c2capi_map[ct]
+            dm = capi_maps.getarrdims(n, vars[n])
+            if dm['dims']:
+                idims.append('(%s)' % (dm['dims']))
+            else:
+                idims.append('')
+            dms = dm['dims'].strip()
+            if not dms:
+                dms = '-1'
+            cadd('\t{\"%s\",%s,{{%s}},%s},' % (n, dm['rank'], dms, at))
+        cadd('\t{NULL}\n};')
+        inames1 = rmbadname(inames)
+        inames1_tps = ','.join(['char *' + s for s in inames1])
+        cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
+        cadd('\tint i_f2py=0;')
+        for n in inames1:
+            cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
+        cadd('}')
+        if '_' in lower_name:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
+             % (F_FUNC, lower_name, name.upper(),
+                ','.join(['char*'] * len(inames1))))
+        cadd('static void f2py_init_%s(void) {' % name)
+        cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
+             % (F_FUNC, lower_name, name.upper(), name))
+        cadd('}\n')
+        iadd('\tF2PyDict_SetItemString(d, \"%s\", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
+            name, name, name))
+        tname = name.replace('_', '\\_')
+        dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
+        dadd('\\begin{description}')
+        for n in inames:
+            dadd('\\item[]{{}\\verb@%s@{}}' %
+                 (capi_maps.getarrdocsign(n, vars[n])))
+            if hasnote(vars[n]):
+                note = vars[n]['note']
+                if isinstance(note, list):
+                    note = '\n'.join(note)
+                dadd('--- %s' % (note))
+        dadd('\\end{description}')
+        ret['docs'].append(
+            '"\t/%s/ %s\\n"' % (name, ','.join(map(lambda v, d: v + d, inames, idims))))
+    ret['commonhooks'] = chooks
+    ret['initcommonhooks'] = ihooks
+    ret['latexdoc'] = doc[0]
+    if len(ret['docs']) <= 1:
+        ret['docs'] = ''
+    return ret, fwrap[0]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
new file mode 100644
index 0000000000..5fd1d08c7f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
@@ -0,0 +1,3311 @@
+#!/usr/bin/env python2
+"""
+crackfortran --- read fortran (77,90) code and extract declaration information.
+
+Copyright 1999-2004 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/09/27 07:13:49 $
+Pearu Peterson
+
+
+Usage of crackfortran:
+======================
+Command line keys: -quiet,-verbose,-fix,-f77,-f90,-show,-h <pyffilename>
+                   -m <module name for f77 routines>,--ignore-contains
+Functions: crackfortran, crack2fortran
+The following Fortran statements/constructions are supported
+(or will be if needed):
+   block data,byte,call,character,common,complex,contains,data,
+   dimension,double complex,double precision,end,external,function,
+   implicit,integer,intent,interface,intrinsic,
+   logical,module,optional,parameter,private,public,
+   program,real,(sequence?),subroutine,type,use,virtual,
+   include,pythonmodule
+Note: 'virtual' is mapped to 'dimension'.
+Note: 'implicit integer (z) static (z)' is 'implicit static (z)' (this is minor bug).
+Note: code after 'contains' will be ignored until its scope ends.
+Note: 'common' statement is extended: dimensions are moved to variable definitions
+Note: f2py directive: <commentchar>f2py<line> is read as <line>
+Note: pythonmodule is introduced to represent Python module
+
+Usage:
+  `postlist=crackfortran(files,funcs)`
+  `postlist` contains declaration information read from the list of files `files`.
+  `crack2fortran(postlist)` returns a fortran code to be saved to pyf-file
+
+  `postlist` has the following structure:
+ *** it is a list of dictionaries containing `blocks':
+     B = {'block','body','vars','parent_block'[,'name','prefix','args','result',
+          'implicit','externals','interfaced','common','sortvars',
+          'commonvars','note']}
+     B['block'] = 'interface' | 'function' | 'subroutine' | 'module' |
+                  'program' | 'block data' | 'type' | 'pythonmodule'
+     B['body'] --- list containing `subblocks' with the same structure as `blocks'
+     B['parent_block'] --- dictionary of a parent block:
+                             C['body'][<index>]['parent_block'] is C
+     B['vars'] --- dictionary of variable definitions
+     B['sortvars'] --- dictionary of variable definitions sorted by dependence (independent first)
+     B['name'] --- name of the block (not if B['block']=='interface')
+     B['prefix'] --- prefix string (only if B['block']=='function')
+     B['args'] --- list of argument names if B['block']== 'function' | 'subroutine'
+     B['result'] --- name of the return value (only if B['block']=='function')
+     B['implicit'] --- dictionary {'a':<variable definition>,'b':...} | None
+     B['externals'] --- list of variables being external
+     B['interfaced'] --- list of variables being external and defined
+     B['common'] --- dictionary of common blocks (list of objects)
+     B['commonvars'] --- list of variables used in common blocks (dimensions are moved to variable definitions)
+     B['from'] --- string showing the 'parents' of the current block
+     B['use'] --- dictionary of modules used in current block:
+         {<modulename>:{['only':<0|1>],['map':{<local_name1>:<use_name1>,...}]}}
+     B['note'] --- list of LaTeX comments on the block
+     B['f2pyenhancements'] --- optional dictionary
+          {'threadsafe':'','fortranname':<name>,
+           'callstatement':<C-expr>|<multi-line block>,
+           'callprotoargument':<C-expr-list>,
+           'usercode':<multi-line block>|<list of multi-line blocks>,
+           'pymethoddef:<multi-line block>'
+           }
+     B['entry'] --- dictionary {entryname:argslist,..}
+     B['varnames'] --- list of variable names given in the order of reading the
+                       Fortran code, useful for derived types.
+     B['saved_interface'] --- a string of scanned routine signature, defines explicit interface
+ *** Variable definition is a dictionary
+     D = B['vars'][<variable name>] =
+     {'typespec'[,'attrspec','kindselector','charselector','=','typename']}
+     D['typespec'] = 'byte' | 'character' | 'complex' | 'double complex' |
+                     'double precision' | 'integer' | 'logical' | 'real' | 'type'
+     D['attrspec'] --- list of attributes (e.g. 'dimension(<arrayspec>)',
+                       'external','intent(in|out|inout|hide|c|callback|cache|aligned4|aligned8|aligned16)',
+                       'optional','required', etc)
+     K = D['kindselector'] = {['*','kind']} (only if D['typespec'] =
+                         'complex' | 'integer' | 'logical' | 'real' )
+     C = D['charselector'] = {['*','len','kind']}
+                             (only if D['typespec']=='character')
+     D['='] --- initialization expression string
+     D['typename'] --- name of the type if D['typespec']=='type'
+     D['dimension'] --- list of dimension bounds
+     D['intent'] --- list of intent specifications
+     D['depend'] --- list of variable names on which current variable depends on
+     D['check'] --- list of C-expressions; if C-expr returns zero, exception is raised
+     D['note'] --- list of LaTeX comments on the variable
+ *** Meaning of kind/char selectors (few examples):
+     D['typespec>']*K['*']
+     D['typespec'](kind=K['kind'])
+     character*C['*']
+     character(len=C['len'],kind=C['kind'])
+     (see also fortran type declaration statement formats below)
+
+Fortran 90 type declaration statement format (F77 is subset of F90)
+====================================================================
+(Main source: IBM XL Fortran 5.1 Language Reference Manual)
+type declaration = <typespec> [[<attrspec>]::] <entitydecl>
+<typespec> = byte                          |
+             character[<charselector>]     |
+             complex[<kindselector>]       |
+             double complex                |
+             double precision              |
+             integer[<kindselector>]       |
+             logical[<kindselector>]       |
+             real[<kindselector>]          |
+             type(<typename>)
+<charselector> = * <charlen>               |
+             ([len=]<len>[,[kind=]<kind>]) |
+             (kind=<kind>[,len=<len>])
+<kindselector> = * <intlen>                |
+             ([kind=]<kind>)
+<attrspec> = comma separated list of attributes.
+             Only the following attributes are used in
+             building up the interface:
+                external
+                (parameter --- affects '=' key)
+                optional
+                intent
+             Other attributes are ignored.
+<intentspec> = in | out | inout
+<arrayspec> = comma separated list of dimension bounds.
+<entitydecl> = <name> [[*<charlen>][(<arrayspec>)] | [(<arrayspec>)]*<charlen>]
+                      [/<init_expr>/ | =<init_expr>] [,<entitydecl>]
+
+In addition, the following attributes are used: check,depend,note
+
+TODO:
+    * Apply 'parameter' attribute (e.g. 'integer parameter :: i=2' 'real x(i)'
+                                   -> 'real x(2)')
+    The above may be solved by creating appropriate preprocessor program, for example.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import string
+import fileinput
+import re
+import os
+import copy
+import platform
+
+from . import __version__
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+
+f2py_version = __version__.version
+
+# Global flags:
+strictf77 = 1          # Ignore `!' comments unless line[0]=='!'
+sourcecodeform = 'fix'  # 'fix','free'
+quiet = 0              # Be verbose if 0 (Obsolete: not used any more)
+verbose = 1            # Be quiet if 0, extra verbose if > 1.
+tabchar = 4 * ' '
+pyffilename = ''
+f77modulename = ''
+skipemptyends = 0      # for old F77 programs without 'program' statement
+ignorecontains = 1
+dolowercase = 1
+debug = []
+
+# Global variables
+beginpattern = ''
+currentfilename = ''
+expectbegin = 1
+f90modulevars = {}
+filepositiontext = ''
+gotnextfile = 1
+groupcache = None
+groupcounter = 0
+grouplist = {groupcounter: []}
+groupname = ''
+include_paths = []
+neededmodule = -1
+onlyfuncs = []
+previous_context = None
+skipblocksuntil = -1
+skipfuncs = []
+skipfunctions = []
+usermodules = []
+
+
+def reset_global_f2py_vars():
+    global groupcounter, grouplist, neededmodule, expectbegin
+    global skipblocksuntil, usermodules, f90modulevars, gotnextfile
+    global filepositiontext, currentfilename, skipfunctions, skipfuncs
+    global onlyfuncs, include_paths, previous_context
+    global strictf77, sourcecodeform, quiet, verbose, tabchar, pyffilename
+    global f77modulename, skipemptyends, ignorecontains, dolowercase, debug
+
+    # flags
+    strictf77 = 1
+    sourcecodeform = 'fix'
+    quiet = 0
+    verbose = 1
+    tabchar = 4 * ' '
+    pyffilename = ''
+    f77modulename = ''
+    skipemptyends = 0
+    ignorecontains = 1
+    dolowercase = 1
+    debug = []
+    # variables
+    groupcounter = 0
+    grouplist = {groupcounter: []}
+    neededmodule = -1
+    expectbegin = 1
+    skipblocksuntil = -1
+    usermodules = []
+    f90modulevars = {}
+    gotnextfile = 1
+    filepositiontext = ''
+    currentfilename = ''
+    skipfunctions = []
+    skipfuncs = []
+    onlyfuncs = []
+    include_paths = []
+    previous_context = None
+
+
+def outmess(line, flag=1):
+    global filepositiontext
+
+    if not verbose:
+        return
+    if not quiet:
+        if flag:
+            sys.stdout.write(filepositiontext)
+        sys.stdout.write(line)
+
+re._MAXCACHE = 50
+defaultimplicitrules = {}
+for c in "abcdefghopqrstuvwxyz$_":
+    defaultimplicitrules[c] = {'typespec': 'real'}
+for c in "ijklmn":
+    defaultimplicitrules[c] = {'typespec': 'integer'}
+del c
+badnames = {}
+invbadnames = {}
+for n in ['int', 'double', 'float', 'char', 'short', 'long', 'void', 'case', 'while',
+          'return', 'signed', 'unsigned', 'if', 'for', 'typedef', 'sizeof', 'union',
+          'struct', 'static', 'register', 'new', 'break', 'do', 'goto', 'switch',
+          'continue', 'else', 'inline', 'extern', 'delete', 'const', 'auto',
+          'len', 'rank', 'shape', 'index', 'slen', 'size', '_i',
+          'max', 'min',
+          'flen', 'fshape',
+          'string', 'complex_double', 'float_double', 'stdin', 'stderr', 'stdout',
+          'type', 'default']:
+    badnames[n] = n + '_bn'
+    invbadnames[n + '_bn'] = n
+
+
+def rmbadname1(name):
+    if name in badnames:
+        errmess('rmbadname1: Replacing "%s" with "%s".\n' %
+                (name, badnames[name]))
+        return badnames[name]
+    return name
+
+
+def rmbadname(names):
+    return [rmbadname1(_m) for _m in names]
+
+
+def undo_rmbadname1(name):
+    if name in invbadnames:
+        errmess('undo_rmbadname1: Replacing "%s" with "%s".\n'
+                % (name, invbadnames[name]))
+        return invbadnames[name]
+    return name
+
+
+def undo_rmbadname(names):
+    return [undo_rmbadname1(_m) for _m in names]
+
+
+def getextension(name):
+    i = name.rfind('.')
+    if i == -1:
+        return ''
+    if '\\' in name[i:]:
+        return ''
+    if '/' in name[i:]:
+        return ''
+    return name[i + 1:]
+
+is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
+_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
+_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+_free_f90_start = re.compile(r'[^c*]\s*[^\s\d\t]', re.I).match
+
+
+def is_free_format(file):
+    """Check if file is in free format Fortran."""
+    # f90 allows both fixed and free format, assuming fixed unless
+    # signs of free format are detected.
+    result = 0
+    f = open(file, 'r')
+    line = f.readline()
+    n = 15  # the number of non-comment lines to scan for hints
+    if _has_f_header(line):
+        n = 0
+    elif _has_f90_header(line):
+        n = 0
+        result = 1
+    while n > 0 and line:
+        if line[0] != '!' and line.strip():
+            n -= 1
+            if (line[0] != '\t' and _free_f90_start(line[:5])) or line[-2:-1] == '&':
+                result = 1
+                break
+        line = f.readline()
+    f.close()
+    return result
+
+
+# Read fortran (77,90) code
+def readfortrancode(ffile, dowithline=show, istop=1):
+    """
+    Read fortran codes from files and
+     1) Get rid of comments, line continuations, and empty lines; lower cases.
+     2) Call dowithline(line) on every line.
+     3) Recursively call itself when statement \"include '<filename>'\" is met.
+    """
+    global gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77
+    global beginpattern, quiet, verbose, dolowercase, include_paths
+
+    if not istop:
+        saveglobals = gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\
+            beginpattern, quiet, verbose, dolowercase
+    if ffile == []:
+        return
+    localdolowercase = dolowercase
+    cont = 0
+    finalline = ''
+    ll = ''
+    commentline = re.compile(
+        r'(?P<line>([^"]*["][^"]*["][^"!]*|[^\']*\'[^\']*\'[^\'!]*|[^!\'"]*))!{1}(?P<rest>.*)')
+    includeline = re.compile(
+        r'\s*include\s*(\'|")(?P<name>[^\'"]*)(\'|")', re.I)
+    cont1 = re.compile(r'(?P<line>.*)&\s*\Z')
+    cont2 = re.compile(r'(\s*&|)(?P<line>.*)')
+    mline_mark = re.compile(r".*?'''")
+    if istop:
+        dowithline('', -1)
+    ll, l1 = '', ''
+    spacedigits = [' '] + [str(_m) for _m in range(10)]
+    filepositiontext = ''
+    fin = fileinput.FileInput(ffile)
+    while True:
+        l = fin.readline()
+        if not l:
+            break
+        if fin.isfirstline():
+            filepositiontext = ''
+            currentfilename = fin.filename()
+            gotnextfile = 1
+            l1 = l
+            strictf77 = 0
+            sourcecodeform = 'fix'
+            ext = os.path.splitext(currentfilename)[1]
+            if is_f_file(currentfilename) and \
+                    not (_has_f90_header(l) or _has_fix_header(l)):
+                strictf77 = 1
+            elif is_free_format(currentfilename) and not _has_fix_header(l):
+                sourcecodeform = 'free'
+            if strictf77:
+                beginpattern = beginpattern77
+            else:
+                beginpattern = beginpattern90
+            outmess('\tReading file %s (format:%s%s)\n'
+                    % (repr(currentfilename), sourcecodeform,
+                       strictf77 and ',strict' or ''))
+
+        l = l.expandtabs().replace('\xa0', ' ')
+        # Get rid of newline characters
+        while not l == '':
+            if l[-1] not in "\n\r\f":
+                break
+            l = l[:-1]
+        if not strictf77:
+            r = commentline.match(l)
+            if r:
+                l = r.group('line') + ' '  # Strip comments starting with `!'
+                rl = r.group('rest')
+                if rl[:4].lower() == 'f2py':  # f2py directive
+                    l = l + 4 * ' '
+                    r = commentline.match(rl[4:])
+                    if r:
+                        l = l + r.group('line')
+                    else:
+                        l = l + rl[4:]
+        if l.strip() == '':  # Skip empty line
+            cont = 0
+            continue
+        if sourcecodeform == 'fix':
+            if l[0] in ['*', 'c', '!', 'C', '#']:
+                if l[1:5].lower() == 'f2py':  # f2py directive
+                    l = '     ' + l[5:]
+                else:  # Skip comment line
+                    cont = 0
+                    continue
+            elif strictf77:
+                if len(l) > 72:
+                    l = l[:72]
+            if not (l[0] in spacedigits):
+                raise Exception('readfortrancode: Found non-(space,digit) char '
+                                'in the first column.\n\tAre you sure that '
+                                'this code is in fix form?\n\tline=%s' % repr(l))
+
+            if (not cont or strictf77) and (len(l) > 5 and not l[5] == ' '):
+                # Continuation of a previous line
+                ll = ll + l[6:]
+                finalline = ''
+                origfinalline = ''
+            else:
+                if not strictf77:
+                    # F90 continuation
+                    r = cont1.match(l)
+                    if r:
+                        l = r.group('line')  # Continuation follows ..
+                    if cont:
+                        ll = ll + cont2.match(l).group('line')
+                        finalline = ''
+                        origfinalline = ''
+                    else:
+                        # clean up line beginning from possible digits.
+                        l = '     ' + l[5:]
+                        if localdolowercase:
+                            finalline = ll.lower()
+                        else:
+                            finalline = ll
+                        origfinalline = ll
+                        ll = l
+                    cont = (r is not None)
+                else:
+                    # clean up line beginning from possible digits.
+                    l = '     ' + l[5:]
+                    if localdolowercase:
+                        finalline = ll.lower()
+                    else:
+                        finalline = ll
+                    origfinalline = ll
+                    ll = l
+
+        elif sourcecodeform == 'free':
+            if not cont and ext == '.pyf' and mline_mark.match(l):
+                l = l + '\n'
+                while True:
+                    lc = fin.readline()
+                    if not lc:
+                        errmess(
+                            'Unexpected end of file when reading multiline\n')
+                        break
+                    l = l + lc
+                    if mline_mark.match(lc):
+                        break
+                l = l.rstrip()
+            r = cont1.match(l)
+            if r:
+                l = r.group('line')  # Continuation follows ..
+            if cont:
+                ll = ll + cont2.match(l).group('line')
+                finalline = ''
+                origfinalline = ''
+            else:
+                if localdolowercase:
+                    finalline = ll.lower()
+                else:
+                    finalline = ll
+                origfinalline = ll
+                ll = l
+            cont = (r is not None)
+        else:
+            raise ValueError(
+                "Flag sourcecodeform must be either 'fix' or 'free': %s" % repr(sourcecodeform))
+        filepositiontext = 'Line #%d in %s:"%s"\n\t' % (
+            fin.filelineno() - 1, currentfilename, l1)
+        m = includeline.match(origfinalline)
+        if m:
+            fn = m.group('name')
+            if os.path.isfile(fn):
+                readfortrancode(fn, dowithline=dowithline, istop=0)
+            else:
+                include_dirs = [
+                    os.path.dirname(currentfilename)] + include_paths
+                foundfile = 0
+                for inc_dir in include_dirs:
+                    fn1 = os.path.join(inc_dir, fn)
+                    if os.path.isfile(fn1):
+                        foundfile = 1
+                        readfortrancode(fn1, dowithline=dowithline, istop=0)
+                        break
+                if not foundfile:
+                    outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % (
+                        repr(fn), os.pathsep.join(include_dirs)))
+        else:
+            dowithline(finalline)
+        l1 = ll
+    if localdolowercase:
+        finalline = ll.lower()
+    else:
+        finalline = ll
+    origfinalline = ll
+    filepositiontext = 'Line #%d in %s:"%s"\n\t' % (
+        fin.filelineno() - 1, currentfilename, l1)
+    m = includeline.match(origfinalline)
+    if m:
+        fn = m.group('name')
+        if os.path.isfile(fn):
+            readfortrancode(fn, dowithline=dowithline, istop=0)
+        else:
+            include_dirs = [os.path.dirname(currentfilename)] + include_paths
+            foundfile = 0
+            for inc_dir in include_dirs:
+                fn1 = os.path.join(inc_dir, fn)
+                if os.path.isfile(fn1):
+                    foundfile = 1
+                    readfortrancode(fn1, dowithline=dowithline, istop=0)
+                    break
+            if not foundfile:
+                outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % (
+                    repr(fn), os.pathsep.join(include_dirs)))
+    else:
+        dowithline(finalline)
+    filepositiontext = ''
+    fin.close()
+    if istop:
+        dowithline('', 1)
+    else:
+        gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\
+            beginpattern, quiet, verbose, dolowercase = saveglobals
+
+# Crack line
+beforethisafter = r'\s*(?P<before>%s(?=\s*(\b(%s)\b)))' + \
+    r'\s*(?P<this>(\b(%s)\b))' + \
+    r'\s*(?P<after>%s)\s*\Z'
+##
+fortrantypes = 'character|logical|integer|real|complex|double\s*(precision\s*(complex|)|complex)|type(?=\s*\([\w\s,=(*)]*\))|byte'
+typespattern = re.compile(
+    beforethisafter % ('', fortrantypes, fortrantypes, '.*'), re.I), 'type'
+typespattern4implicit = re.compile(beforethisafter % (
+    '', fortrantypes + '|static|automatic|undefined', fortrantypes + '|static|automatic|undefined', '.*'), re.I)
+#
+functionpattern = re.compile(beforethisafter % (
+    '([a-z]+[\w\s(=*+-/)]*?|)', 'function', 'function', '.*'), re.I), 'begin'
+subroutinepattern = re.compile(beforethisafter % (
+    '[a-z\s]*?', 'subroutine', 'subroutine', '.*'), re.I), 'begin'
+# modulepattern=re.compile(beforethisafter%('[a-z\s]*?','module','module','.*'),re.I),'begin'
+#
+groupbegins77 = r'program|block\s*data'
+beginpattern77 = re.compile(
+    beforethisafter % ('', groupbegins77, groupbegins77, '.*'), re.I), 'begin'
+groupbegins90 = groupbegins77 + \
+    r'|module(?!\s*procedure)|python\s*module|interface|type(?!\s*\()'
+beginpattern90 = re.compile(
+    beforethisafter % ('', groupbegins90, groupbegins90, '.*'), re.I), 'begin'
+groupends = r'end|endprogram|endblockdata|endmodule|endpythonmodule|endinterface'
+endpattern = re.compile(
+    beforethisafter % ('', groupends, groupends, '[\w\s]*'), re.I), 'end'
+# endifs='end\s*(if|do|where|select|while|forall)'
+endifs = '(end\s*(if|do|where|select|while|forall))|(module\s*procedure)'
+endifpattern = re.compile(
+    beforethisafter % ('[\w]*?', endifs, endifs, '[\w\s]*'), re.I), 'endif'
+#
+implicitpattern = re.compile(
+    beforethisafter % ('', 'implicit', 'implicit', '.*'), re.I), 'implicit'
+dimensionpattern = re.compile(beforethisafter % (
+    '', 'dimension|virtual', 'dimension|virtual', '.*'), re.I), 'dimension'
+externalpattern = re.compile(
+    beforethisafter % ('', 'external', 'external', '.*'), re.I), 'external'
+optionalpattern = re.compile(
+    beforethisafter % ('', 'optional', 'optional', '.*'), re.I), 'optional'
+requiredpattern = re.compile(
+    beforethisafter % ('', 'required', 'required', '.*'), re.I), 'required'
+publicpattern = re.compile(
+    beforethisafter % ('', 'public', 'public', '.*'), re.I), 'public'
+privatepattern = re.compile(
+    beforethisafter % ('', 'private', 'private', '.*'), re.I), 'private'
+intrisicpattern = re.compile(
+    beforethisafter % ('', 'intrisic', 'intrisic', '.*'), re.I), 'intrisic'
+intentpattern = re.compile(beforethisafter % (
+    '', 'intent|depend|note|check', 'intent|depend|note|check', '\s*\(.*?\).*'), re.I), 'intent'
+parameterpattern = re.compile(
+    beforethisafter % ('', 'parameter', 'parameter', '\s*\(.*'), re.I), 'parameter'
+datapattern = re.compile(
+    beforethisafter % ('', 'data', 'data', '.*'), re.I), 'data'
+callpattern = re.compile(
+    beforethisafter % ('', 'call', 'call', '.*'), re.I), 'call'
+entrypattern = re.compile(
+    beforethisafter % ('', 'entry', 'entry', '.*'), re.I), 'entry'
+callfunpattern = re.compile(
+    beforethisafter % ('', 'callfun', 'callfun', '.*'), re.I), 'callfun'
+commonpattern = re.compile(
+    beforethisafter % ('', 'common', 'common', '.*'), re.I), 'common'
+usepattern = re.compile(
+    beforethisafter % ('', 'use', 'use', '.*'), re.I), 'use'
+containspattern = re.compile(
+    beforethisafter % ('', 'contains', 'contains', ''), re.I), 'contains'
+formatpattern = re.compile(
+    beforethisafter % ('', 'format', 'format', '.*'), re.I), 'format'
+# Non-fortran and f2py-specific statements
+f2pyenhancementspattern = re.compile(beforethisafter % ('', 'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef',
+                                                        'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef', '.*'), re.I | re.S), 'f2pyenhancements'
+multilinepattern = re.compile(
+    r"\s*(?P<before>''')(?P<this>.*?)(?P<after>''')\s*\Z", re.S), 'multiline'
+##
+
+
+def _simplifyargs(argsline):
+    a = []
+    for n in markoutercomma(argsline).split('@,@'):
+        for r in '(),':
+            n = n.replace(r, '_')
+        a.append(n)
+    return ','.join(a)
+
+crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+[\w]*\b)\s*[=].*', re.I)
+
+
+def crackline(line, reset=0):
+    """
+    reset=-1  --- initialize
+    reset=0   --- crack the line
+    reset=1   --- final check if mismatch of blocks occured
+
+    Cracked data is saved in grouplist[0].
+    """
+    global beginpattern, groupcounter, groupname, groupcache, grouplist
+    global filepositiontext, currentfilename, neededmodule, expectbegin
+    global skipblocksuntil, skipemptyends, previous_context, gotnextfile
+
+    if ';' in line and not (f2pyenhancementspattern[0].match(line) or
+                            multilinepattern[0].match(line)):
+        for l in line.split(';'):
+            # XXX: non-zero reset values need testing
+            assert reset == 0, repr(reset)
+            crackline(l, reset)
+        return
+    if reset < 0:
+        groupcounter = 0
+        groupname = {groupcounter: ''}
+        groupcache = {groupcounter: {}}
+        grouplist = {groupcounter: []}
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['block'] = ''
+        groupcache[groupcounter]['name'] = ''
+        neededmodule = -1
+        skipblocksuntil = -1
+        return
+    if reset > 0:
+        fl = 0
+        if f77modulename and neededmodule == groupcounter:
+            fl = 2
+        while groupcounter > fl:
+            outmess('crackline: groupcounter=%s groupname=%s\n' %
+                    (repr(groupcounter), repr(groupname)))
+            outmess(
+                'crackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement.\n')
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1
+        if f77modulename and neededmodule == groupcounter:
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end interface
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end module
+            neededmodule = -1
+        return
+    if line == '':
+        return
+    flag = 0
+    for pat in [dimensionpattern, externalpattern, intentpattern, optionalpattern,
+                requiredpattern,
+                parameterpattern, datapattern, publicpattern, privatepattern,
+                intrisicpattern,
+                endifpattern, endpattern,
+                formatpattern,
+                beginpattern, functionpattern, subroutinepattern,
+                implicitpattern, typespattern, commonpattern,
+                callpattern, usepattern, containspattern,
+                entrypattern,
+                f2pyenhancementspattern,
+                multilinepattern
+                ]:
+        m = pat[0].match(line)
+        if m:
+            break
+        flag = flag + 1
+    if not m:
+        re_1 = crackline_re_1
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        if 'externals' in groupcache[groupcounter]:
+            for name in groupcache[groupcounter]['externals']:
+                if name in invbadnames:
+                    name = invbadnames[name]
+                if 'interfaced' in groupcache[groupcounter] and name in groupcache[groupcounter]['interfaced']:
+                    continue
+                m1 = re.match(
+                    r'(?P<before>[^"]*)\b%s\b\s*@\(@(?P<args>[^@]*)@\)@.*\Z' % name, markouterparen(line), re.I)
+                if m1:
+                    m2 = re_1.match(m1.group('before'))
+                    a = _simplifyargs(m1.group('args'))
+                    if m2:
+                        line = 'callfun %s(%s) result (%s)' % (
+                            name, a, m2.group('result'))
+                    else:
+                        line = 'callfun %s(%s)' % (name, a)
+                    m = callfunpattern[0].match(line)
+                    if not m:
+                        outmess(
+                            'crackline: could not resolve function call for line=%s.\n' % repr(line))
+                        return
+                    analyzeline(m, 'callfun', line)
+                    return
+        if verbose > 1 or (verbose == 1 and currentfilename.lower().endswith('.pyf')):
+            previous_context = None
+            outmess('crackline:%d: No pattern for line\n' % (groupcounter))
+        return
+    elif pat[1] == 'end':
+        if 0 <= skipblocksuntil < groupcounter:
+            groupcounter = groupcounter - 1
+            if skipblocksuntil <= groupcounter:
+                return
+        if groupcounter <= 0:
+            raise Exception('crackline: groupcounter(=%s) is nonpositive. '
+                            'Check the blocks.'
+                            % (groupcounter))
+        m1 = beginpattern[0].match((line))
+        if (m1) and (not m1.group('this') == groupname[groupcounter]):
+            raise Exception('crackline: End group %s does not match with '
+                            'previous Begin group %s\n\t%s' %
+                            (repr(m1.group('this')), repr(groupname[groupcounter]),
+                             filepositiontext)
+                            )
+        if skipblocksuntil == groupcounter:
+            skipblocksuntil = -1
+        grouplist[groupcounter - 1].append(groupcache[groupcounter])
+        grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+        del grouplist[groupcounter]
+        groupcounter = groupcounter - 1
+        if not skipemptyends:
+            expectbegin = 1
+    elif pat[1] == 'begin':
+        if 0 <= skipblocksuntil <= groupcounter:
+            groupcounter = groupcounter + 1
+            return
+        gotnextfile = 0
+        analyzeline(m, pat[1], line)
+        expectbegin = 0
+    elif pat[1] == 'endif':
+        pass
+    elif pat[1] == 'contains':
+        if ignorecontains:
+            return
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        skipblocksuntil = groupcounter
+    else:
+        if 0 <= skipblocksuntil <= groupcounter:
+            return
+        analyzeline(m, pat[1], line)
+
+
+def markouterparen(line):
+    l = ''
+    f = 0
+    for c in line:
+        if c == '(':
+            f = f + 1
+            if f == 1:
+                l = l + '@(@'
+                continue
+        elif c == ')':
+            f = f - 1
+            if f == 0:
+                l = l + '@)@'
+                continue
+        l = l + c
+    return l
+
+
+def markoutercomma(line, comma=','):
+    l = ''
+    f = 0
+    cc = ''
+    for c in line:
+        if (not cc or cc == ')') and c == '(':
+            f = f + 1
+            cc = ')'
+        elif not cc and c == '\'' and (not l or l[-1] != '\\'):
+            f = f + 1
+            cc = '\''
+        elif c == cc:
+            f = f - 1
+            if f == 0:
+                cc = ''
+        elif c == comma and f == 0:
+            l = l + '@' + comma + '@'
+            continue
+        l = l + c
+    assert not f, repr((f, line, l, cc))
+    return l
+
+
+def unmarkouterparen(line):
+    r = line.replace('@(@', '(').replace('@)@', ')')
+    return r
+
+
+def appenddecl(decl, decl2, force=1):
+    if not decl:
+        decl = {}
+    if not decl2:
+        return decl
+    if decl is decl2:
+        return decl
+    for k in list(decl2.keys()):
+        if k == 'typespec':
+            if force or k not in decl:
+                decl[k] = decl2[k]
+        elif k == 'attrspec':
+            for l in decl2[k]:
+                decl = setattrspec(decl, l, force)
+        elif k == 'kindselector':
+            decl = setkindselector(decl, decl2[k], force)
+        elif k == 'charselector':
+            decl = setcharselector(decl, decl2[k], force)
+        elif k in ['=', 'typename']:
+            if force or k not in decl:
+                decl[k] = decl2[k]
+        elif k == 'note':
+            pass
+        elif k in ['intent', 'check', 'dimension', 'optional', 'required']:
+            errmess('appenddecl: "%s" not implemented.\n' % k)
+        else:
+            raise Exception('appenddecl: Unknown variable definition key:' +
+                            str(k))
+    return decl
+
+selectpattern = re.compile(
+    r'\s*(?P<this>(@\(@.*?@\)@|[*][\d*]+|[*]\s*@\(@.*?@\)@|))(?P<after>.*)\Z', re.I)
+nameargspattern = re.compile(
+    r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P<bind>.*)\s*@\)@))*\s*\Z', re.I)
+callnameargspattern = re.compile(
+    r'\s*(?P<name>\b[\w$]+\b)\s*@\(@\s*(?P<args>.*)\s*@\)@\s*\Z', re.I)
+real16pattern = re.compile(
+    r'([-+]?(?:\d+(?:\.\d*)?|\d*\.\d+))[dD]((?:[-+]?\d+)?)')
+real8pattern = re.compile(
+    r'([-+]?((?:\d+(?:\.\d*)?|\d*\.\d+))[eE]((?:[-+]?\d+)?)|(\d+\.\d*))')
+
+_intentcallbackpattern = re.compile(r'intent\s*\(.*?\bcallback\b', re.I)
+
+
+def _is_intent_callback(vdecl):
+    for a in vdecl.get('attrspec', []):
+        if _intentcallbackpattern.match(a):
+            return 1
+    return 0
+
+
+def _resolvenameargspattern(line):
+    line = markouterparen(line)
+    m1 = nameargspattern.match(line)
+    if m1:
+        return m1.group('name'), m1.group('args'), m1.group('result'), m1.group('bind')
+    m1 = callnameargspattern.match(line)
+    if m1:
+        return m1.group('name'), m1.group('args'), None, None
+    return None, [], None, None
+
+
+def analyzeline(m, case, line):
+    global groupcounter, groupname, groupcache, grouplist, filepositiontext
+    global currentfilename, f77modulename, neededinterface, neededmodule
+    global expectbegin, gotnextfile, previous_context
+
+    block = m.group('this')
+    if case != 'multiline':
+        previous_context = None
+    if expectbegin and case not in ['begin', 'call', 'callfun', 'type'] \
+       and not skipemptyends and groupcounter < 1:
+        newname = os.path.basename(currentfilename).split('.')[0]
+        outmess(
+            'analyzeline: no group yet. Creating program group with name "%s".\n' % newname)
+        gotnextfile = 0
+        groupcounter = groupcounter + 1
+        groupname[groupcounter] = 'program'
+        groupcache[groupcounter] = {}
+        grouplist[groupcounter] = []
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['block'] = 'program'
+        groupcache[groupcounter]['name'] = newname
+        groupcache[groupcounter]['from'] = 'fromsky'
+        expectbegin = 0
+    if case in ['begin', 'call', 'callfun']:
+        # Crack line => block,name,args,result
+        block = block.lower()
+        if re.match(r'block\s*data', block, re.I):
+            block = 'block data'
+        if re.match(r'python\s*module', block, re.I):
+            block = 'python module'
+        name, args, result, bind = _resolvenameargspattern(m.group('after'))
+        if name is None:
+            if block == 'block data':
+                name = '_BLOCK_DATA_'
+            else:
+                name = ''
+            if block not in ['interface', 'block data']:
+                outmess('analyzeline: No name/args pattern found for line.\n')
+
+        previous_context = (block, name, groupcounter)
+        if args:
+            args = rmbadname([x.strip()
+                              for x in markoutercomma(args).split('@,@')])
+        else:
+            args = []
+        if '' in args:
+            while '' in args:
+                args.remove('')
+            outmess(
+                'analyzeline: argument list is malformed (missing argument).\n')
+
+        # end of crack line => block,name,args,result
+        needmodule = 0
+        needinterface = 0
+
+        if case in ['call', 'callfun']:
+            needinterface = 1
+            if 'args' not in groupcache[groupcounter]:
+                return
+            if name not in groupcache[groupcounter]['args']:
+                return
+            for it in grouplist[groupcounter]:
+                if it['name'] == name:
+                    return
+            if name in groupcache[groupcounter]['interfaced']:
+                return
+            block = {'call': 'subroutine', 'callfun': 'function'}[case]
+        if f77modulename and neededmodule == -1 and groupcounter <= 1:
+            neededmodule = groupcounter + 2
+            needmodule = 1
+            if block != 'interface':
+                needinterface = 1
+        # Create new block(s)
+        groupcounter = groupcounter + 1
+        groupcache[groupcounter] = {}
+        grouplist[groupcounter] = []
+        if needmodule:
+            if verbose > 1:
+                outmess('analyzeline: Creating module block %s\n' %
+                        repr(f77modulename), 0)
+            groupname[groupcounter] = 'module'
+            groupcache[groupcounter]['block'] = 'python module'
+            groupcache[groupcounter]['name'] = f77modulename
+            groupcache[groupcounter]['from'] = ''
+            groupcache[groupcounter]['body'] = []
+            groupcache[groupcounter]['externals'] = []
+            groupcache[groupcounter]['interfaced'] = []
+            groupcache[groupcounter]['vars'] = {}
+            groupcounter = groupcounter + 1
+            groupcache[groupcounter] = {}
+            grouplist[groupcounter] = []
+        if needinterface:
+            if verbose > 1:
+                outmess('analyzeline: Creating additional interface block (groupcounter=%s).\n' % (
+                    groupcounter), 0)
+            groupname[groupcounter] = 'interface'
+            groupcache[groupcounter]['block'] = 'interface'
+            groupcache[groupcounter]['name'] = 'unknown_interface'
+            groupcache[groupcounter]['from'] = '%s:%s' % (
+                groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name'])
+            groupcache[groupcounter]['body'] = []
+            groupcache[groupcounter]['externals'] = []
+            groupcache[groupcounter]['interfaced'] = []
+            groupcache[groupcounter]['vars'] = {}
+            groupcounter = groupcounter + 1
+            groupcache[groupcounter] = {}
+            grouplist[groupcounter] = []
+        groupname[groupcounter] = block
+        groupcache[groupcounter]['block'] = block
+        if not name:
+            name = 'unknown_' + block
+        groupcache[groupcounter]['prefix'] = m.group('before')
+        groupcache[groupcounter]['name'] = rmbadname1(name)
+        groupcache[groupcounter]['result'] = result
+        if groupcounter == 1:
+            groupcache[groupcounter]['from'] = currentfilename
+        else:
+            if f77modulename and groupcounter == 3:
+                groupcache[groupcounter]['from'] = '%s:%s' % (
+                    groupcache[groupcounter - 1]['from'], currentfilename)
+            else:
+                groupcache[groupcounter]['from'] = '%s:%s' % (
+                    groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name'])
+        for k in list(groupcache[groupcounter].keys()):
+            if not groupcache[groupcounter][k]:
+                del groupcache[groupcounter][k]
+
+        groupcache[groupcounter]['args'] = args
+        groupcache[groupcounter]['body'] = []
+        groupcache[groupcounter]['externals'] = []
+        groupcache[groupcounter]['interfaced'] = []
+        groupcache[groupcounter]['vars'] = {}
+        groupcache[groupcounter]['entry'] = {}
+        # end of creation
+        if block == 'type':
+            groupcache[groupcounter]['varnames'] = []
+
+        if case in ['call', 'callfun']:  # set parents variables
+            if name not in groupcache[groupcounter - 2]['externals']:
+                groupcache[groupcounter - 2]['externals'].append(name)
+            groupcache[groupcounter]['vars'] = copy.deepcopy(
+                groupcache[groupcounter - 2]['vars'])
+            try:
+                del groupcache[groupcounter]['vars'][name][
+                    groupcache[groupcounter]['vars'][name]['attrspec'].index('external')]
+            except:
+                pass
+        if block in ['function', 'subroutine']:  # set global attributes
+            try:
+                groupcache[groupcounter]['vars'][name] = appenddecl(
+                    groupcache[groupcounter]['vars'][name], groupcache[groupcounter - 2]['vars'][''])
+            except:
+                pass
+            if case == 'callfun':  # return type
+                if result and result in groupcache[groupcounter]['vars']:
+                    if not name == result:
+                        groupcache[groupcounter]['vars'][name] = appenddecl(
+                            groupcache[groupcounter]['vars'][name], groupcache[groupcounter]['vars'][result])
+            # if groupcounter>1: # name is interfaced
+            try:
+                groupcache[groupcounter - 2]['interfaced'].append(name)
+            except:
+                pass
+        if block == 'function':
+            t = typespattern[0].match(m.group('before') + ' ' + name)
+            if t:
+                typespec, selector, attr, edecl = cracktypespec0(
+                    t.group('this'), t.group('after'))
+                updatevars(typespec, selector, attr, edecl)
+
+        if case in ['call', 'callfun']:
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end routine
+            grouplist[groupcounter - 1].append(groupcache[groupcounter])
+            grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter]
+            del grouplist[groupcounter]
+            groupcounter = groupcounter - 1  # end interface
+
+    elif case == 'entry':
+        name, args, result, bind = _resolvenameargspattern(m.group('after'))
+        if name is not None:
+            if args:
+                args = rmbadname([x.strip()
+                                  for x in markoutercomma(args).split('@,@')])
+            else:
+                args = []
+            assert result is None, repr(result)
+            groupcache[groupcounter]['entry'][name] = args
+            previous_context = ('entry', name, groupcounter)
+    elif case == 'type':
+        typespec, selector, attr, edecl = cracktypespec0(
+            block, m.group('after'))
+        last_name = updatevars(typespec, selector, attr, edecl)
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case in ['dimension', 'intent', 'optional', 'required', 'external', 'public', 'private', 'intrisic']:
+        edecl = groupcache[groupcounter]['vars']
+        ll = m.group('after').strip()
+        i = ll.find('::')
+        if i < 0 and case == 'intent':
+            i = markouterparen(ll).find('@)@') - 2
+            ll = ll[:i + 1] + '::' + ll[i + 1:]
+            i = ll.find('::')
+            if ll[i:] == '::' and 'args' in groupcache[groupcounter]:
+                outmess('All arguments will have attribute %s%s\n' %
+                        (m.group('this'), ll[:i]))
+                ll = ll + ','.join(groupcache[groupcounter]['args'])
+        if i < 0:
+            i = 0
+            pl = ''
+        else:
+            pl = ll[:i].strip()
+            ll = ll[i + 2:]
+        ch = markoutercomma(pl).split('@,@')
+        if len(ch) > 1:
+            pl = ch[0]
+            outmess('analyzeline: cannot handle multiple attributes without type specification. Ignoring %r.\n' % (
+                ','.join(ch[1:])))
+        last_name = None
+
+        for e in [x.strip() for x in markoutercomma(ll).split('@,@')]:
+            m1 = namepattern.match(e)
+            if not m1:
+                if case in ['public', 'private']:
+                    k = ''
+                else:
+                    print(m.groupdict())
+                    outmess('analyzeline: no name pattern found in %s statement for %s. Skipping.\n' % (
+                        case, repr(e)))
+                    continue
+            else:
+                k = rmbadname1(m1.group('name'))
+            if k not in edecl:
+                edecl[k] = {}
+            if case == 'dimension':
+                ap = case + m1.group('after')
+            if case == 'intent':
+                ap = m.group('this') + pl
+                if _intentcallbackpattern.match(ap):
+                    if k not in groupcache[groupcounter]['args']:
+                        if groupcounter > 1:
+                            if '__user__' not in groupcache[groupcounter - 2]['name']:
+                                outmess(
+                                    'analyzeline: missing __user__ module (could be nothing)\n')
+                            # fixes ticket 1693
+                            if k != groupcache[groupcounter]['name']:
+                                outmess('analyzeline: appending intent(callback) %s'
+                                        ' to %s arguments\n' % (k, groupcache[groupcounter]['name']))
+                                groupcache[groupcounter]['args'].append(k)
+                        else:
+                            errmess(
+                                'analyzeline: intent(callback) %s is ignored' % (k))
+                    else:
+                        errmess('analyzeline: intent(callback) %s is already'
+                                ' in argument list' % (k))
+            if case in ['optional', 'required', 'public', 'external', 'private', 'intrisic']:
+                ap = case
+            if 'attrspec' in edecl[k]:
+                edecl[k]['attrspec'].append(ap)
+            else:
+                edecl[k]['attrspec'] = [ap]
+            if case == 'external':
+                if groupcache[groupcounter]['block'] == 'program':
+                    outmess('analyzeline: ignoring program arguments\n')
+                    continue
+                if k not in groupcache[groupcounter]['args']:
+                    continue
+                if 'externals' not in groupcache[groupcounter]:
+                    groupcache[groupcounter]['externals'] = []
+                groupcache[groupcounter]['externals'].append(k)
+            last_name = k
+        groupcache[groupcounter]['vars'] = edecl
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'parameter':
+        edecl = groupcache[groupcounter]['vars']
+        ll = m.group('after').strip()[1:-1]
+        last_name = None
+        for e in markoutercomma(ll).split('@,@'):
+            try:
+                k, initexpr = [x.strip() for x in e.split('=')]
+            except:
+                outmess(
+                    'analyzeline: could not extract name,expr in parameter statement "%s" of "%s"\n' % (e, ll))
+                continue
+            params = get_parameters(edecl)
+            k = rmbadname1(k)
+            if k not in edecl:
+                edecl[k] = {}
+            if '=' in edecl[k] and (not edecl[k]['='] == initexpr):
+                outmess('analyzeline: Overwriting the value of parameter "%s" ("%s") with "%s".\n' % (
+                    k, edecl[k]['='], initexpr))
+            t = determineexprtype(initexpr, params)
+            if t:
+                if t.get('typespec') == 'real':
+                    tt = list(initexpr)
+                    for m in real16pattern.finditer(initexpr):
+                        tt[m.start():m.end()] = list(
+                            initexpr[m.start():m.end()].lower().replace('d', 'e'))
+                    initexpr = ''.join(tt)
+                elif t.get('typespec') == 'complex':
+                    initexpr = initexpr[1:].lower().replace('d', 'e').\
+                        replace(',', '+1j*(')
+            try:
+                v = eval(initexpr, {}, params)
+            except (SyntaxError, NameError, TypeError) as msg:
+                errmess('analyzeline: Failed to evaluate %r. Ignoring: %s\n'
+                        % (initexpr, msg))
+                continue
+            edecl[k]['='] = repr(v)
+            if 'attrspec' in edecl[k]:
+                edecl[k]['attrspec'].append('parameter')
+            else:
+                edecl[k]['attrspec'] = ['parameter']
+            last_name = k
+        groupcache[groupcounter]['vars'] = edecl
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'implicit':
+        if m.group('after').strip().lower() == 'none':
+            groupcache[groupcounter]['implicit'] = None
+        elif m.group('after'):
+            if 'implicit' in groupcache[groupcounter]:
+                impl = groupcache[groupcounter]['implicit']
+            else:
+                impl = {}
+            if impl is None:
+                outmess(
+                    'analyzeline: Overwriting earlier "implicit none" statement.\n')
+                impl = {}
+            for e in markoutercomma(m.group('after')).split('@,@'):
+                decl = {}
+                m1 = re.match(
+                    r'\s*(?P<this>.*?)\s*(\(\s*(?P<after>[a-z-, ]+)\s*\)\s*|)\Z', e, re.I)
+                if not m1:
+                    outmess(
+                        'analyzeline: could not extract info of implicit statement part "%s"\n' % (e))
+                    continue
+                m2 = typespattern4implicit.match(m1.group('this'))
+                if not m2:
+                    outmess(
+                        'analyzeline: could not extract types pattern of implicit statement part "%s"\n' % (e))
+                    continue
+                typespec, selector, attr, edecl = cracktypespec0(
+                    m2.group('this'), m2.group('after'))
+                kindselect, charselect, typename = cracktypespec(
+                    typespec, selector)
+                decl['typespec'] = typespec
+                decl['kindselector'] = kindselect
+                decl['charselector'] = charselect
+                decl['typename'] = typename
+                for k in list(decl.keys()):
+                    if not decl[k]:
+                        del decl[k]
+                for r in markoutercomma(m1.group('after')).split('@,@'):
+                    if '-' in r:
+                        try:
+                            begc, endc = [x.strip() for x in r.split('-')]
+                        except:
+                            outmess(
+                                'analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement\n' % r)
+                            continue
+                    else:
+                        begc = endc = r.strip()
+                    if not len(begc) == len(endc) == 1:
+                        outmess(
+                            'analyzeline: expected "<char>-<char>" instead of "%s" in range list of implicit statement (2)\n' % r)
+                        continue
+                    for o in range(ord(begc), ord(endc) + 1):
+                        impl[chr(o)] = decl
+            groupcache[groupcounter]['implicit'] = impl
+    elif case == 'data':
+        ll = []
+        dl = ''
+        il = ''
+        f = 0
+        fc = 1
+        inp = 0
+        for c in m.group('after'):
+            if not inp:
+                if c == "'":
+                    fc = not fc
+                if c == '/' and fc:
+                    f = f + 1
+                    continue
+            if c == '(':
+                inp = inp + 1
+            elif c == ')':
+                inp = inp - 1
+            if f == 0:
+                dl = dl + c
+            elif f == 1:
+                il = il + c
+            elif f == 2:
+                dl = dl.strip()
+                if dl.startswith(','):
+                    dl = dl[1:].strip()
+                ll.append([dl, il])
+                dl = c
+                il = ''
+                f = 0
+        if f == 2:
+            dl = dl.strip()
+            if dl.startswith(','):
+                dl = dl[1:].strip()
+            ll.append([dl, il])
+        vars = {}
+        if 'vars' in groupcache[groupcounter]:
+            vars = groupcache[groupcounter]['vars']
+        last_name = None
+        for l in ll:
+            l = [x.strip() for x in l]
+            if l[0][0] == ',':
+                l[0] = l[0][1:]
+            if l[0][0] == '(':
+                outmess(
+                    'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % l[0])
+                continue
+            i = 0
+            j = 0
+            llen = len(l[1])
+            for v in rmbadname([x.strip() for x in markoutercomma(l[0]).split('@,@')]):
+                if v[0] == '(':
+                    outmess(
+                        'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % v)
+                    # XXX: subsequent init expressions may get wrong values.
+                    # Ignoring since data statements are irrelevant for
+                    # wrapping.
+                    continue
+                fc = 0
+                while (i < llen) and (fc or not l[1][i] == ','):
+                    if l[1][i] == "'":
+                        fc = not fc
+                    i = i + 1
+                i = i + 1
+                if v not in vars:
+                    vars[v] = {}
+                if '=' in vars[v] and not vars[v]['='] == l[1][j:i - 1]:
+                    outmess('analyzeline: changing init expression of "%s" ("%s") to "%s"\n' % (
+                        v, vars[v]['='], l[1][j:i - 1]))
+                vars[v]['='] = l[1][j:i - 1]
+                j = i
+                last_name = v
+        groupcache[groupcounter]['vars'] = vars
+        if last_name is not None:
+            previous_context = ('variable', last_name, groupcounter)
+    elif case == 'common':
+        line = m.group('after').strip()
+        if not line[0] == '/':
+            line = '//' + line
+        cl = []
+        f = 0
+        bn = ''
+        ol = ''
+        for c in line:
+            if c == '/':
+                f = f + 1
+                continue
+            if f >= 3:
+                bn = bn.strip()
+                if not bn:
+                    bn = '_BLNK_'
+                cl.append([bn, ol])
+                f = f - 2
+                bn = ''
+                ol = ''
+            if f % 2:
+                bn = bn + c
+            else:
+                ol = ol + c
+        bn = bn.strip()
+        if not bn:
+            bn = '_BLNK_'
+        cl.append([bn, ol])
+        commonkey = {}
+        if 'common' in groupcache[groupcounter]:
+            commonkey = groupcache[groupcounter]['common']
+        for c in cl:
+            if c[0] not in commonkey:
+                commonkey[c[0]] = []
+            for i in [x.strip() for x in markoutercomma(c[1]).split('@,@')]:
+                if i:
+                    commonkey[c[0]].append(i)
+        groupcache[groupcounter]['common'] = commonkey
+        previous_context = ('common', bn, groupcounter)
+    elif case == 'use':
+        m1 = re.match(
+            r'\A\s*(?P<name>\b[\w]+\b)\s*((,(\s*\bonly\b\s*:|(?P<notonly>))\s*(?P<list>.*))|)\s*\Z', m.group('after'), re.I)
+        if m1:
+            mm = m1.groupdict()
+            if 'use' not in groupcache[groupcounter]:
+                groupcache[groupcounter]['use'] = {}
+            name = m1.group('name')
+            groupcache[groupcounter]['use'][name] = {}
+            isonly = 0
+            if 'list' in mm and mm['list'] is not None:
+                if 'notonly' in mm and mm['notonly'] is None:
+                    isonly = 1
+                groupcache[groupcounter]['use'][name]['only'] = isonly
+                ll = [x.strip() for x in mm['list'].split(',')]
+                rl = {}
+                for l in ll:
+                    if '=' in l:
+                        m2 = re.match(
+                            r'\A\s*(?P<local>\b[\w]+\b)\s*=\s*>\s*(?P<use>\b[\w]+\b)\s*\Z', l, re.I)
+                        if m2:
+                            rl[m2.group('local').strip()] = m2.group(
+                                'use').strip()
+                        else:
+                            outmess(
+                                'analyzeline: Not local=>use pattern found in %s\n' % repr(l))
+                    else:
+                        rl[l] = l
+                    groupcache[groupcounter]['use'][name]['map'] = rl
+            else:
+                pass
+        else:
+            print(m.groupdict())
+            outmess('analyzeline: Could not crack the use statement.\n')
+    elif case in ['f2pyenhancements']:
+        if 'f2pyenhancements' not in groupcache[groupcounter]:
+            groupcache[groupcounter]['f2pyenhancements'] = {}
+        d = groupcache[groupcounter]['f2pyenhancements']
+        if m.group('this') == 'usercode' and 'usercode' in d:
+            if isinstance(d['usercode'], str):
+                d['usercode'] = [d['usercode']]
+            d['usercode'].append(m.group('after'))
+        else:
+            d[m.group('this')] = m.group('after')
+    elif case == 'multiline':
+        if previous_context is None:
+            if verbose:
+                outmess('analyzeline: No context for multiline block.\n')
+            return
+        gc = groupcounter
+        appendmultiline(groupcache[gc],
+                        previous_context[:2],
+                        m.group('this'))
+    else:
+        if verbose > 1:
+            print(m.groupdict())
+            outmess('analyzeline: No code implemented for line.\n')
+
+
+def appendmultiline(group, context_name, ml):
+    if 'f2pymultilines' not in group:
+        group['f2pymultilines'] = {}
+    d = group['f2pymultilines']
+    if context_name not in d:
+        d[context_name] = []
+    d[context_name].append(ml)
+    return
+
+
+def cracktypespec0(typespec, ll):
+    selector = None
+    attr = None
+    if re.match(r'double\s*complex', typespec, re.I):
+        typespec = 'double complex'
+    elif re.match(r'double\s*precision', typespec, re.I):
+        typespec = 'double precision'
+    else:
+        typespec = typespec.strip().lower()
+    m1 = selectpattern.match(markouterparen(ll))
+    if not m1:
+        outmess(
+            'cracktypespec0: no kind/char_selector pattern found for line.\n')
+        return
+    d = m1.groupdict()
+    for k in list(d.keys()):
+        d[k] = unmarkouterparen(d[k])
+    if typespec in ['complex', 'integer', 'logical', 'real', 'character', 'type']:
+        selector = d['this']
+        ll = d['after']
+    i = ll.find('::')
+    if i >= 0:
+        attr = ll[:i].strip()
+        ll = ll[i + 2:]
+    return typespec, selector, attr, ll
+#####
+namepattern = re.compile(r'\s*(?P<name>\b[\w]+\b)\s*(?P<after>.*)\s*\Z', re.I)
+kindselector = re.compile(
+    r'\s*(\(\s*(kind\s*=)?\s*(?P<kind>.*)\s*\)|[*]\s*(?P<kind2>.*?))\s*\Z', re.I)
+charselector = re.compile(
+    r'\s*(\((?P<lenkind>.*)\)|[*]\s*(?P<charlen>.*))\s*\Z', re.I)
+lenkindpattern = re.compile(
+    r'\s*(kind\s*=\s*(?P<kind>.*?)\s*(@,@\s*len\s*=\s*(?P<len>.*)|)|(len\s*=\s*|)(?P<len2>.*?)\s*(@,@\s*(kind\s*=\s*|)(?P<kind2>.*)|))\s*\Z', re.I)
+lenarraypattern = re.compile(
+    r'\s*(@\(@\s*(?!/)\s*(?P<array>.*?)\s*@\)@\s*[*]\s*(?P<len>.*?)|([*]\s*(?P<len2>.*?)|)\s*(@\(@\s*(?!/)\s*(?P<array2>.*?)\s*@\)@|))\s*(=\s*(?P<init>.*?)|(@\(@|)/\s*(?P<init2>.*?)\s*/(@\)@|)|)\s*\Z', re.I)
+
+
+def removespaces(expr):
+    expr = expr.strip()
+    if len(expr) <= 1:
+        return expr
+    expr2 = expr[0]
+    for i in range(1, len(expr) - 1):
+        if (expr[i] == ' ' and
+            ((expr[i + 1] in "()[]{}=+-/* ") or
+                (expr[i - 1] in "()[]{}=+-/* "))):
+            continue
+        expr2 = expr2 + expr[i]
+    expr2 = expr2 + expr[-1]
+    return expr2
+
+
+def markinnerspaces(line):
+    l = ''
+    f = 0
+    cc = '\''
+    cb = ''
+    for c in line:
+        if cb == '\\' and c in ['\\', '\'', '"']:
+            l = l + c
+            cb = c
+            continue
+        if f == 0 and c in ['\'', '"']:
+            cc = c
+        if c == cc:
+            f = f + 1
+        elif c == cc:
+            f = f - 1
+        elif c == ' ' and f == 1:
+            l = l + '@_@'
+            continue
+        l = l + c
+        cb = c
+    return l
+
+
+def updatevars(typespec, selector, attrspec, entitydecl):
+    global groupcache, groupcounter
+
+    last_name = None
+    kindselect, charselect, typename = cracktypespec(typespec, selector)
+    if attrspec:
+        attrspec = [x.strip() for x in markoutercomma(attrspec).split('@,@')]
+        l = []
+        c = re.compile(r'(?P<start>[a-zA-Z]+)')
+        for a in attrspec:
+            if not a:
+                continue
+            m = c.match(a)
+            if m:
+                s = m.group('start').lower()
+                a = s + a[len(s):]
+            l.append(a)
+        attrspec = l
+    el = [x.strip() for x in markoutercomma(entitydecl).split('@,@')]
+    el1 = []
+    for e in el:
+        for e1 in [x.strip() for x in markoutercomma(removespaces(markinnerspaces(e)), comma=' ').split('@ @')]:
+            if e1:
+                el1.append(e1.replace('@_@', ' '))
+    for e in el1:
+        m = namepattern.match(e)
+        if not m:
+            outmess(
+                'updatevars: no name pattern found for entity=%s. Skipping.\n' % (repr(e)))
+            continue
+        ename = rmbadname1(m.group('name'))
+        edecl = {}
+        if ename in groupcache[groupcounter]['vars']:
+            edecl = groupcache[groupcounter]['vars'][ename].copy()
+            not_has_typespec = 'typespec' not in edecl
+            if not_has_typespec:
+                edecl['typespec'] = typespec
+            elif typespec and (not typespec == edecl['typespec']):
+                outmess('updatevars: attempt to change the type of "%s" ("%s") to "%s". Ignoring.\n' % (
+                    ename, edecl['typespec'], typespec))
+            if 'kindselector' not in edecl:
+                edecl['kindselector'] = copy.copy(kindselect)
+            elif kindselect:
+                for k in list(kindselect.keys()):
+                    if k in edecl['kindselector'] and (not kindselect[k] == edecl['kindselector'][k]):
+                        outmess('updatevars: attempt to change the kindselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            k, ename, edecl['kindselector'][k], kindselect[k]))
+                    else:
+                        edecl['kindselector'][k] = copy.copy(kindselect[k])
+            if 'charselector' not in edecl and charselect:
+                if not_has_typespec:
+                    edecl['charselector'] = charselect
+                else:
+                    errmess('updatevars:%s: attempt to change empty charselector to %r. Ignoring.\n'
+                            % (ename, charselect))
+            elif charselect:
+                for k in list(charselect.keys()):
+                    if k in edecl['charselector'] and (not charselect[k] == edecl['charselector'][k]):
+                        outmess('updatevars: attempt to change the charselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            k, ename, edecl['charselector'][k], charselect[k]))
+                    else:
+                        edecl['charselector'][k] = copy.copy(charselect[k])
+            if 'typename' not in edecl:
+                edecl['typename'] = typename
+            elif typename and (not edecl['typename'] == typename):
+                outmess('updatevars: attempt to change the typename of "%s" ("%s") to "%s". Ignoring.\n' % (
+                    ename, edecl['typename'], typename))
+            if 'attrspec' not in edecl:
+                edecl['attrspec'] = copy.copy(attrspec)
+            elif attrspec:
+                for a in attrspec:
+                    if a not in edecl['attrspec']:
+                        edecl['attrspec'].append(a)
+        else:
+            edecl['typespec'] = copy.copy(typespec)
+            edecl['kindselector'] = copy.copy(kindselect)
+            edecl['charselector'] = copy.copy(charselect)
+            edecl['typename'] = typename
+            edecl['attrspec'] = copy.copy(attrspec)
+        if m.group('after'):
+            m1 = lenarraypattern.match(markouterparen(m.group('after')))
+            if m1:
+                d1 = m1.groupdict()
+                for lk in ['len', 'array', 'init']:
+                    if d1[lk + '2'] is not None:
+                        d1[lk] = d1[lk + '2']
+                        del d1[lk + '2']
+                for k in list(d1.keys()):
+                    if d1[k] is not None:
+                        d1[k] = unmarkouterparen(d1[k])
+                    else:
+                        del d1[k]
+                if 'len' in d1 and 'array' in d1:
+                    if d1['len'] == '':
+                        d1['len'] = d1['array']
+                        del d1['array']
+                    else:
+                        d1['array'] = d1['array'] + ',' + d1['len']
+                        del d1['len']
+                        errmess('updatevars: "%s %s" is mapped to "%s %s(%s)"\n' % (
+                            typespec, e, typespec, ename, d1['array']))
+                if 'array' in d1:
+                    dm = 'dimension(%s)' % d1['array']
+                    if 'attrspec' not in edecl or (not edecl['attrspec']):
+                        edecl['attrspec'] = [dm]
+                    else:
+                        edecl['attrspec'].append(dm)
+                        for dm1 in edecl['attrspec']:
+                            if dm1[:9] == 'dimension' and dm1 != dm:
+                                del edecl['attrspec'][-1]
+                                errmess('updatevars:%s: attempt to change %r to %r. Ignoring.\n'
+                                        % (ename, dm1, dm))
+                                break
+
+                if 'len' in d1:
+                    if typespec in ['complex', 'integer', 'logical', 'real']:
+                        if ('kindselector' not in edecl) or (not edecl['kindselector']):
+                            edecl['kindselector'] = {}
+                        edecl['kindselector']['*'] = d1['len']
+                    elif typespec == 'character':
+                        if ('charselector' not in edecl) or (not edecl['charselector']):
+                            edecl['charselector'] = {}
+                        if 'len' in edecl['charselector']:
+                            del edecl['charselector']['len']
+                        edecl['charselector']['*'] = d1['len']
+                if 'init' in d1:
+                    if '=' in edecl and (not edecl['='] == d1['init']):
+                        outmess('updatevars: attempt to change the init expression of "%s" ("%s") to "%s". Ignoring.\n' % (
+                            ename, edecl['='], d1['init']))
+                    else:
+                        edecl['='] = d1['init']
+            else:
+                outmess('updatevars: could not crack entity declaration "%s". Ignoring.\n' % (
+                    ename + m.group('after')))
+        for k in list(edecl.keys()):
+            if not edecl[k]:
+                del edecl[k]
+        groupcache[groupcounter]['vars'][ename] = edecl
+        if 'varnames' in groupcache[groupcounter]:
+            groupcache[groupcounter]['varnames'].append(ename)
+        last_name = ename
+    return last_name
+
+
+def cracktypespec(typespec, selector):
+    kindselect = None
+    charselect = None
+    typename = None
+    if selector:
+        if typespec in ['complex', 'integer', 'logical', 'real']:
+            kindselect = kindselector.match(selector)
+            if not kindselect:
+                outmess(
+                    'cracktypespec: no kindselector pattern found for %s\n' % (repr(selector)))
+                return
+            kindselect = kindselect.groupdict()
+            kindselect['*'] = kindselect['kind2']
+            del kindselect['kind2']
+            for k in list(kindselect.keys()):
+                if not kindselect[k]:
+                    del kindselect[k]
+            for k, i in list(kindselect.items()):
+                kindselect[k] = rmbadname1(i)
+        elif typespec == 'character':
+            charselect = charselector.match(selector)
+            if not charselect:
+                outmess(
+                    'cracktypespec: no charselector pattern found for %s\n' % (repr(selector)))
+                return
+            charselect = charselect.groupdict()
+            charselect['*'] = charselect['charlen']
+            del charselect['charlen']
+            if charselect['lenkind']:
+                lenkind = lenkindpattern.match(
+                    markoutercomma(charselect['lenkind']))
+                lenkind = lenkind.groupdict()
+                for lk in ['len', 'kind']:
+                    if lenkind[lk + '2']:
+                        lenkind[lk] = lenkind[lk + '2']
+                    charselect[lk] = lenkind[lk]
+                    del lenkind[lk + '2']
+            del charselect['lenkind']
+            for k in list(charselect.keys()):
+                if not charselect[k]:
+                    del charselect[k]
+            for k, i in list(charselect.items()):
+                charselect[k] = rmbadname1(i)
+        elif typespec == 'type':
+            typename = re.match(r'\s*\(\s*(?P<name>\w+)\s*\)', selector, re.I)
+            if typename:
+                typename = typename.group('name')
+            else:
+                outmess('cracktypespec: no typename found in %s\n' %
+                        (repr(typespec + selector)))
+        else:
+            outmess('cracktypespec: no selector used for %s\n' %
+                    (repr(selector)))
+    return kindselect, charselect, typename
+######
+
+
+def setattrspec(decl, attr, force=0):
+    if not decl:
+        decl = {}
+    if not attr:
+        return decl
+    if 'attrspec' not in decl:
+        decl['attrspec'] = [attr]
+        return decl
+    if force:
+        decl['attrspec'].append(attr)
+    if attr in decl['attrspec']:
+        return decl
+    if attr == 'static' and 'automatic' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'automatic' and 'static' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'public' and 'private' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    elif attr == 'private' and 'public' not in decl['attrspec']:
+        decl['attrspec'].append(attr)
+    else:
+        decl['attrspec'].append(attr)
+    return decl
+
+
+def setkindselector(decl, sel, force=0):
+    if not decl:
+        decl = {}
+    if not sel:
+        return decl
+    if 'kindselector' not in decl:
+        decl['kindselector'] = sel
+        return decl
+    for k in list(sel.keys()):
+        if force or k not in decl['kindselector']:
+            decl['kindselector'][k] = sel[k]
+    return decl
+
+
+def setcharselector(decl, sel, force=0):
+    if not decl:
+        decl = {}
+    if not sel:
+        return decl
+    if 'charselector' not in decl:
+        decl['charselector'] = sel
+        return decl
+    for k in list(sel.keys()):
+        if force or k not in decl['charselector']:
+            decl['charselector'][k] = sel[k]
+    return decl
+
+
+def getblockname(block, unknown='unknown'):
+    if 'name' in block:
+        return block['name']
+    return unknown
+
+# post processing
+
+
+def setmesstext(block):
+    global filepositiontext
+
+    try:
+        filepositiontext = 'In: %s:%s\n' % (block['from'], block['name'])
+    except:
+        pass
+
+
+def get_usedict(block):
+    usedict = {}
+    if 'parent_block' in block:
+        usedict = get_usedict(block['parent_block'])
+    if 'use' in block:
+        usedict.update(block['use'])
+    return usedict
+
+
+def get_useparameters(block, param_map=None):
+    global f90modulevars
+
+    if param_map is None:
+        param_map = {}
+    usedict = get_usedict(block)
+    if not usedict:
+        return param_map
+    for usename, mapping in list(usedict.items()):
+        usename = usename.lower()
+        if usename not in f90modulevars:
+            outmess('get_useparameters: no module %s info used by %s\n' %
+                    (usename, block.get('name')))
+            continue
+        mvars = f90modulevars[usename]
+        params = get_parameters(mvars)
+        if not params:
+            continue
+        # XXX: apply mapping
+        if mapping:
+            errmess('get_useparameters: mapping for %s not impl.' % (mapping))
+        for k, v in list(params.items()):
+            if k in param_map:
+                outmess('get_useparameters: overriding parameter %s with'
+                        ' value from module %s' % (repr(k), repr(usename)))
+            param_map[k] = v
+
+    return param_map
+
+
+def postcrack2(block, tab='', param_map=None):
+    global f90modulevars
+
+    if not f90modulevars:
+        return block
+    if isinstance(block, list):
+        ret = []
+        for g in block:
+            g = postcrack2(g, tab=tab + '\t', param_map=param_map)
+            ret.append(g)
+        return ret
+    setmesstext(block)
+    outmess('%sBlock: %s\n' % (tab, block['name']), 0)
+
+    if param_map is None:
+        param_map = get_useparameters(block)
+
+    if param_map is not None and 'vars' in block:
+        vars = block['vars']
+        for n in list(vars.keys()):
+            var = vars[n]
+            if 'kindselector' in var:
+                kind = var['kindselector']
+                if 'kind' in kind:
+                    val = kind['kind']
+                    if val in param_map:
+                        kind['kind'] = param_map[val]
+    new_body = []
+    for b in block['body']:
+        b = postcrack2(b, tab=tab + '\t', param_map=param_map)
+        new_body.append(b)
+    block['body'] = new_body
+
+    return block
+
+
+def postcrack(block, args=None, tab=''):
+    """
+    TODO:
+          function return values
+          determine expression types if in argument list
+    """
+    global usermodules, onlyfunctions
+
+    if isinstance(block, list):
+        gret = []
+        uret = []
+        for g in block:
+            setmesstext(g)
+            g = postcrack(g, tab=tab + '\t')
+            # sort user routines to appear first
+            if 'name' in g and '__user__' in g['name']:
+                uret.append(g)
+            else:
+                gret.append(g)
+        return uret + gret
+    setmesstext(block)
+    if not isinstance(block, dict) and 'block' not in block:
+        raise Exception('postcrack: Expected block dictionary instead of ' +
+                        str(block))
+    if 'name' in block and not block['name'] == 'unknown_interface':
+        outmess('%sBlock: %s\n' % (tab, block['name']), 0)
+    block = analyzeargs(block)
+    block = analyzecommon(block)
+    block['vars'] = analyzevars(block)
+    block['sortvars'] = sortvarnames(block['vars'])
+    if 'args' in block and block['args']:
+        args = block['args']
+    block['body'] = analyzebody(block, args, tab=tab)
+
+    userisdefined = []
+    if 'use' in block:
+        useblock = block['use']
+        for k in list(useblock.keys()):
+            if '__user__' in k:
+                userisdefined.append(k)
+    else:
+        useblock = {}
+    name = ''
+    if 'name' in block:
+        name = block['name']
+    # and not userisdefined: # Build a __user__ module
+    if 'externals' in block and block['externals']:
+        interfaced = []
+        if 'interfaced' in block:
+            interfaced = block['interfaced']
+        mvars = copy.copy(block['vars'])
+        if name:
+            mname = name + '__user__routines'
+        else:
+            mname = 'unknown__user__routines'
+        if mname in userisdefined:
+            i = 1
+            while '%s_%i' % (mname, i) in userisdefined:
+                i = i + 1
+            mname = '%s_%i' % (mname, i)
+        interface = {'block': 'interface', 'body': [],
+                     'vars': {}, 'name': name + '_user_interface'}
+        for e in block['externals']:
+            if e in interfaced:
+                edef = []
+                j = -1
+                for b in block['body']:
+                    j = j + 1
+                    if b['block'] == 'interface':
+                        i = -1
+                        for bb in b['body']:
+                            i = i + 1
+                            if 'name' in bb and bb['name'] == e:
+                                edef = copy.copy(bb)
+                                del b['body'][i]
+                                break
+                        if edef:
+                            if not b['body']:
+                                del block['body'][j]
+                            del interfaced[interfaced.index(e)]
+                            break
+                interface['body'].append(edef)
+            else:
+                if e in mvars and not isexternal(mvars[e]):
+                    interface['vars'][e] = mvars[e]
+        if interface['vars'] or interface['body']:
+            block['interfaced'] = interfaced
+            mblock = {'block': 'python module', 'body': [
+                interface], 'vars': {}, 'name': mname, 'interfaced': block['externals']}
+            useblock[mname] = {}
+            usermodules.append(mblock)
+    if useblock:
+        block['use'] = useblock
+    return block
+
+
+def sortvarnames(vars):
+    indep = []
+    dep = []
+    for v in list(vars.keys()):
+        if 'depend' in vars[v] and vars[v]['depend']:
+            dep.append(v)
+        else:
+            indep.append(v)
+    n = len(dep)
+    i = 0
+    while dep:  # XXX: How to catch dependence cycles correctly?
+        v = dep[0]
+        fl = 0
+        for w in dep[1:]:
+            if w in vars[v]['depend']:
+                fl = 1
+                break
+        if fl:
+            dep = dep[1:] + [v]
+            i = i + 1
+            if i > n:
+                errmess('sortvarnames: failed to compute dependencies because'
+                        ' of cyclic dependencies between '
+                        + ', '.join(dep) + '\n')
+                indep = indep + dep
+                break
+        else:
+            indep.append(v)
+            dep = dep[1:]
+            n = len(dep)
+            i = 0
+    return indep
+
+
+def analyzecommon(block):
+    if not hascommon(block):
+        return block
+    commonvars = []
+    for k in list(block['common'].keys()):
+        comvars = []
+        for e in block['common'][k]:
+            m = re.match(
+                r'\A\s*\b(?P<name>.*?)\b\s*(\((?P<dims>.*?)\)|)\s*\Z', e, re.I)
+            if m:
+                dims = []
+                if m.group('dims'):
+                    dims = [x.strip()
+                            for x in markoutercomma(m.group('dims')).split('@,@')]
+                n = m.group('name').strip()
+                if n in block['vars']:
+                    if 'attrspec' in block['vars'][n]:
+                        block['vars'][n]['attrspec'].append(
+                            'dimension(%s)' % (','.join(dims)))
+                    else:
+                        block['vars'][n]['attrspec'] = [
+                            'dimension(%s)' % (','.join(dims))]
+                else:
+                    if dims:
+                        block['vars'][n] = {
+                            'attrspec': ['dimension(%s)' % (','.join(dims))]}
+                    else:
+                        block['vars'][n] = {}
+                if n not in commonvars:
+                    commonvars.append(n)
+            else:
+                n = e
+                errmess(
+                    'analyzecommon: failed to extract "<name>[(<dims>)]" from "%s" in common /%s/.\n' % (e, k))
+            comvars.append(n)
+        block['common'][k] = comvars
+    if 'commonvars' not in block:
+        block['commonvars'] = commonvars
+    else:
+        block['commonvars'] = block['commonvars'] + commonvars
+    return block
+
+
+def analyzebody(block, args, tab=''):
+    global usermodules, skipfuncs, onlyfuncs, f90modulevars
+
+    setmesstext(block)
+    body = []
+    for b in block['body']:
+        b['parent_block'] = block
+        if b['block'] in ['function', 'subroutine']:
+            if args is not None and b['name'] not in args:
+                continue
+            else:
+                as_ = b['args']
+            if b['name'] in skipfuncs:
+                continue
+            if onlyfuncs and b['name'] not in onlyfuncs:
+                continue
+            b['saved_interface'] = crack2fortrangen(
+                b, '\n' + ' ' * 6, as_interface=True)
+
+        else:
+            as_ = args
+        b = postcrack(b, as_, tab=tab + '\t')
+        if b['block'] == 'interface' and not b['body']:
+            if 'f2pyenhancements' not in b:
+                continue
+        if b['block'].replace(' ', '') == 'pythonmodule':
+            usermodules.append(b)
+        else:
+            if b['block'] == 'module':
+                f90modulevars[b['name']] = b['vars']
+            body.append(b)
+    return body
+
+
+def buildimplicitrules(block):
+    setmesstext(block)
+    implicitrules = defaultimplicitrules
+    attrrules = {}
+    if 'implicit' in block:
+        if block['implicit'] is None:
+            implicitrules = None
+            if verbose > 1:
+                outmess(
+                    'buildimplicitrules: no implicit rules for routine %s.\n' % repr(block['name']))
+        else:
+            for k in list(block['implicit'].keys()):
+                if block['implicit'][k].get('typespec') not in ['static', 'automatic']:
+                    implicitrules[k] = block['implicit'][k]
+                else:
+                    attrrules[k] = block['implicit'][k]['typespec']
+    return implicitrules, attrrules
+
+
+def myeval(e, g=None, l=None):
+    r = eval(e, g, l)
+    if type(r) in [type(0), type(0.0)]:
+        return r
+    raise ValueError('r=%r' % (r))
+
+getlincoef_re_1 = re.compile(r'\A\b\w+\b\Z', re.I)
+
+
+def getlincoef(e, xset):  # e = a*x+b ; x in xset
+    try:
+        c = int(myeval(e, {}, {}))
+        return 0, c, None
+    except:
+        pass
+    if getlincoef_re_1.match(e):
+        return 1, 0, e
+    len_e = len(e)
+    for x in xset:
+        if len(x) > len_e:
+            continue
+        if re.search(r'\w\s*\([^)]*\b' + x + r'\b', e):
+            # skip function calls having x as an argument, e.g max(1, x)
+            continue
+        re_1 = re.compile(r'(?P<before>.*?)\b' + x + r'\b(?P<after>.*)', re.I)
+        m = re_1.match(e)
+        if m:
+            try:
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 0, m1.group('after'))
+                    m1 = re_1.match(ee)
+                b = myeval(ee, {}, {})
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 1, m1.group('after'))
+                    m1 = re_1.match(ee)
+                a = myeval(ee, {}, {}) - b
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 0.5, m1.group('after'))
+                    m1 = re_1.match(ee)
+                c = myeval(ee, {}, {})
+                # computing another point to be sure that expression is linear
+                m1 = re_1.match(e)
+                while m1:
+                    ee = '%s(%s)%s' % (
+                        m1.group('before'), 1.5, m1.group('after'))
+                    m1 = re_1.match(ee)
+                c2 = myeval(ee, {}, {})
+                if (a * 0.5 + b == c and a * 1.5 + b == c2):
+                    return a, b, x
+            except:
+                pass
+            break
+    return None, None, None
+
+_varname_match = re.compile(r'\A[a-z]\w*\Z').match
+
+
+def getarrlen(dl, args, star='*'):
+    edl = []
+    try:
+        edl.append(myeval(dl[0], {}, {}))
+    except:
+        edl.append(dl[0])
+    try:
+        edl.append(myeval(dl[1], {}, {}))
+    except:
+        edl.append(dl[1])
+    if isinstance(edl[0], int):
+        p1 = 1 - edl[0]
+        if p1 == 0:
+            d = str(dl[1])
+        elif p1 < 0:
+            d = '%s-%s' % (dl[1], -p1)
+        else:
+            d = '%s+%s' % (dl[1], p1)
+    elif isinstance(edl[1], int):
+        p1 = 1 + edl[1]
+        if p1 == 0:
+            d = '-(%s)' % (dl[0])
+        else:
+            d = '%s-(%s)' % (p1, dl[0])
+    else:
+        d = '%s-(%s)+1' % (dl[1], dl[0])
+    try:
+        return repr(myeval(d, {}, {})), None, None
+    except:
+        pass
+    d1, d2 = getlincoef(dl[0], args), getlincoef(dl[1], args)
+    if None not in [d1[0], d2[0]]:
+        if (d1[0], d2[0]) == (0, 0):
+            return repr(d2[1] - d1[1] + 1), None, None
+        b = d2[1] - d1[1] + 1
+        d1 = (d1[0], 0, d1[2])
+        d2 = (d2[0], b, d2[2])
+        if d1[0] == 0 and d2[2] in args:
+            if b < 0:
+                return '%s * %s - %s' % (d2[0], d2[2], -b), d2[2], '+%s)/(%s)' % (-b, d2[0])
+            elif b:
+                return '%s * %s + %s' % (d2[0], d2[2], b), d2[2], '-%s)/(%s)' % (b, d2[0])
+            else:
+                return '%s * %s' % (d2[0], d2[2]), d2[2], ')/(%s)' % (d2[0])
+        if d2[0] == 0 and d1[2] in args:
+
+            if b < 0:
+                return '%s * %s - %s' % (-d1[0], d1[2], -b), d1[2], '+%s)/(%s)' % (-b, -d1[0])
+            elif b:
+                return '%s * %s + %s' % (-d1[0], d1[2], b), d1[2], '-%s)/(%s)' % (b, -d1[0])
+            else:
+                return '%s * %s' % (-d1[0], d1[2]), d1[2], ')/(%s)' % (-d1[0])
+        if d1[2] == d2[2] and d1[2] in args:
+            a = d2[0] - d1[0]
+            if not a:
+                return repr(b), None, None
+            if b < 0:
+                return '%s * %s - %s' % (a, d1[2], -b), d2[2], '+%s)/(%s)' % (-b, a)
+            elif b:
+                return '%s * %s + %s' % (a, d1[2], b), d2[2], '-%s)/(%s)' % (b, a)
+            else:
+                return '%s * %s' % (a, d1[2]), d2[2], ')/(%s)' % (a)
+        if d1[0] == d2[0] == 1:
+            c = str(d1[2])
+            if c not in args:
+                if _varname_match(c):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c))
+                c = '(%s)' % c
+            if b == 0:
+                d = '%s-%s' % (d2[2], c)
+            elif b < 0:
+                d = '%s-%s-%s' % (d2[2], c, -b)
+            else:
+                d = '%s-%s+%s' % (d2[2], c, b)
+        elif d1[0] == 0:
+            c2 = str(d2[2])
+            if c2 not in args:
+                if _varname_match(c2):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c2))
+                c2 = '(%s)' % c2
+            if d2[0] == 1:
+                pass
+            elif d2[0] == -1:
+                c2 = '-%s' % c2
+            else:
+                c2 = '%s*%s' % (d2[0], c2)
+
+            if b == 0:
+                d = c2
+            elif b < 0:
+                d = '%s-%s' % (c2, -b)
+            else:
+                d = '%s+%s' % (c2, b)
+        elif d2[0] == 0:
+            c1 = str(d1[2])
+            if c1 not in args:
+                if _varname_match(c1):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c1))
+                c1 = '(%s)' % c1
+            if d1[0] == 1:
+                c1 = '-%s' % c1
+            elif d1[0] == -1:
+                c1 = '+%s' % c1
+            elif d1[0] < 0:
+                c1 = '+%s*%s' % (-d1[0], c1)
+            else:
+                c1 = '-%s*%s' % (d1[0], c1)
+
+            if b == 0:
+                d = c1
+            elif b < 0:
+                d = '%s-%s' % (c1, -b)
+            else:
+                d = '%s+%s' % (c1, b)
+        else:
+            c1 = str(d1[2])
+            if c1 not in args:
+                if _varname_match(c1):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c1))
+                c1 = '(%s)' % c1
+            if d1[0] == 1:
+                c1 = '-%s' % c1
+            elif d1[0] == -1:
+                c1 = '+%s' % c1
+            elif d1[0] < 0:
+                c1 = '+%s*%s' % (-d1[0], c1)
+            else:
+                c1 = '-%s*%s' % (d1[0], c1)
+
+            c2 = str(d2[2])
+            if c2 not in args:
+                if _varname_match(c2):
+                    outmess('\tgetarrlen:variable "%s" undefined\n' % (c2))
+                c2 = '(%s)' % c2
+            if d2[0] == 1:
+                pass
+            elif d2[0] == -1:
+                c2 = '-%s' % c2
+            else:
+                c2 = '%s*%s' % (d2[0], c2)
+
+            if b == 0:
+                d = '%s%s' % (c2, c1)
+            elif b < 0:
+                d = '%s%s-%s' % (c2, c1, -b)
+            else:
+                d = '%s%s+%s' % (c2, c1, b)
+    return d, None, None
+
+word_pattern = re.compile(r'\b[a-z][\w$]*\b', re.I)
+
+
+def _get_depend_dict(name, vars, deps):
+    if name in vars:
+        words = vars[name].get('depend', [])
+
+        if '=' in vars[name] and not isstring(vars[name]):
+            for word in word_pattern.findall(vars[name]['=']):
+                if word not in words and word in vars:
+                    words.append(word)
+        for word in words[:]:
+            for w in deps.get(word, []) \
+                    or _get_depend_dict(word, vars, deps):
+                if w not in words:
+                    words.append(w)
+    else:
+        outmess('_get_depend_dict: no dependence info for %s\n' % (repr(name)))
+        words = []
+    deps[name] = words
+    return words
+
+
+def _calc_depend_dict(vars):
+    names = list(vars.keys())
+    depend_dict = {}
+    for n in names:
+        _get_depend_dict(n, vars, depend_dict)
+    return depend_dict
+
+
+def get_sorted_names(vars):
+    """
+    """
+    depend_dict = _calc_depend_dict(vars)
+    names = []
+    for name in list(depend_dict.keys()):
+        if not depend_dict[name]:
+            names.append(name)
+            del depend_dict[name]
+    while depend_dict:
+        for name, lst in list(depend_dict.items()):
+            new_lst = [n for n in lst if n in depend_dict]
+            if not new_lst:
+                names.append(name)
+                del depend_dict[name]
+            else:
+                depend_dict[name] = new_lst
+    return [name for name in names if name in vars]
+
+
+def _kind_func(string):
+    # XXX: return something sensible.
+    if string[0] in "'\"":
+        string = string[1:-1]
+    if real16pattern.match(string):
+        return 8
+    elif real8pattern.match(string):
+        return 4
+    return 'kind(' + string + ')'
+
+
+def _selected_int_kind_func(r):
+    # XXX: This should be processor dependent
+    m = 10 ** r
+    if m <= 2 ** 8:
+        return 1
+    if m <= 2 ** 16:
+        return 2
+    if m <= 2 ** 32:
+        return 4
+    if m <= 2 ** 63:
+        return 8
+    if m <= 2 ** 128:
+        return 16
+    return -1
+
+
+def _selected_real_kind_func(p, r=0, radix=0):
+    # XXX: This should be processor dependent
+    # This is only good for 0 <= p <= 20
+    if p < 7:
+        return 4
+    if p < 16:
+        return 8
+    if platform.machine().lower().startswith('power'):
+        if p <= 20:
+            return 16
+    else:
+        if p < 19:
+            return 10
+        elif p <= 20:
+            return 16
+    return -1
+
+
+def get_parameters(vars, global_params={}):
+    params = copy.copy(global_params)
+    g_params = copy.copy(global_params)
+    for name, func in [('kind', _kind_func),
+                       ('selected_int_kind', _selected_int_kind_func),
+                       ('selected_real_kind', _selected_real_kind_func), ]:
+        if name not in g_params:
+            g_params[name] = func
+    param_names = []
+    for n in get_sorted_names(vars):
+        if 'attrspec' in vars[n] and 'parameter' in vars[n]['attrspec']:
+            param_names.append(n)
+    kind_re = re.compile(r'\bkind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    selected_int_kind_re = re.compile(
+        r'\bselected_int_kind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    selected_kind_re = re.compile(
+        r'\bselected_(int|real)_kind\s*\(\s*(?P<value>.*)\s*\)', re.I)
+    for n in param_names:
+        if '=' in vars[n]:
+            v = vars[n]['=']
+            if islogical(vars[n]):
+                v = v.lower()
+                for repl in [
+                    ('.false.', 'False'),
+                    ('.true.', 'True'),
+                    # TODO: test .eq., .neq., etc replacements.
+                ]:
+                    v = v.replace(*repl)
+            v = kind_re.sub(r'kind("\1")', v)
+            v = selected_int_kind_re.sub(r'selected_int_kind(\1)', v)
+            if isinteger(vars[n]) and not selected_kind_re.match(v):
+                v = v.split('_')[0]
+            if isdouble(vars[n]):
+                tt = list(v)
+                for m in real16pattern.finditer(v):
+                    tt[m.start():m.end()] = list(
+                        v[m.start():m.end()].lower().replace('d', 'e'))
+                v = ''.join(tt)
+            if iscomplex(vars[n]):
+                if v[0] == '(' and v[-1] == ')':
+                    # FIXME, unused l looks like potential bug
+                    l = markoutercomma(v[1:-1]).split('@,@')
+            try:
+                params[n] = eval(v, g_params, params)
+            except Exception as msg:
+                params[n] = v
+                outmess('get_parameters: got "%s" on %s\n' % (msg, repr(v)))
+            if isstring(vars[n]) and isinstance(params[n], int):
+                params[n] = chr(params[n])
+            nl = n.lower()
+            if nl != n:
+                params[nl] = params[n]
+        else:
+            print(vars[n])
+            outmess(
+                'get_parameters:parameter %s does not have value?!\n' % (repr(n)))
+    return params
+
+
+def _eval_length(length, params):
+    if length in ['(:)', '(*)', '*']:
+        return '(*)'
+    return _eval_scalar(length, params)
+
+_is_kind_number = re.compile(r'\d+_').match
+
+
+def _eval_scalar(value, params):
+    if _is_kind_number(value):
+        value = value.split('_')[0]
+    try:
+        value = str(eval(value, {}, params))
+    except (NameError, SyntaxError):
+        return value
+    except Exception as msg:
+        errmess('"%s" in evaluating %r '
+                '(available names: %s)\n'
+                % (msg, value, list(params.keys())))
+    return value
+
+
+def analyzevars(block):
+    global f90modulevars
+
+    setmesstext(block)
+    implicitrules, attrrules = buildimplicitrules(block)
+    vars = copy.copy(block['vars'])
+    if block['block'] == 'function' and block['name'] not in vars:
+        vars[block['name']] = {}
+    if '' in block['vars']:
+        del vars['']
+        if 'attrspec' in block['vars']['']:
+            gen = block['vars']['']['attrspec']
+            for n in list(vars.keys()):
+                for k in ['public', 'private']:
+                    if k in gen:
+                        vars[n] = setattrspec(vars[n], k)
+    svars = []
+    args = block['args']
+    for a in args:
+        try:
+            vars[a]
+            svars.append(a)
+        except KeyError:
+            pass
+    for n in list(vars.keys()):
+        if n not in args:
+            svars.append(n)
+
+    params = get_parameters(vars, get_useparameters(block))
+
+    dep_matches = {}
+    name_match = re.compile(r'\w[\w\d_$]*').match
+    for v in list(vars.keys()):
+        m = name_match(v)
+        if m:
+            n = v[m.start():m.end()]
+            try:
+                dep_matches[n]
+            except KeyError:
+                dep_matches[n] = re.compile(r'.*\b%s\b' % (v), re.I).match
+    for n in svars:
+        if n[0] in list(attrrules.keys()):
+            vars[n] = setattrspec(vars[n], attrrules[n[0]])
+        if 'typespec' not in vars[n]:
+            if not('attrspec' in vars[n] and 'external' in vars[n]['attrspec']):
+                if implicitrules:
+                    ln0 = n[0].lower()
+                    for k in list(implicitrules[ln0].keys()):
+                        if k == 'typespec' and implicitrules[ln0][k] == 'undefined':
+                            continue
+                        if k not in vars[n]:
+                            vars[n][k] = implicitrules[ln0][k]
+                        elif k == 'attrspec':
+                            for l in implicitrules[ln0][k]:
+                                vars[n] = setattrspec(vars[n], l)
+                elif n in block['args']:
+                    outmess('analyzevars: typespec of variable %s is not defined in routine %s.\n' % (
+                        repr(n), block['name']))
+
+        if 'charselector' in vars[n]:
+            if 'len' in vars[n]['charselector']:
+                l = vars[n]['charselector']['len']
+                try:
+                    l = str(eval(l, {}, params))
+                except:
+                    pass
+                vars[n]['charselector']['len'] = l
+
+        if 'kindselector' in vars[n]:
+            if 'kind' in vars[n]['kindselector']:
+                l = vars[n]['kindselector']['kind']
+                try:
+                    l = str(eval(l, {}, params))
+                except:
+                    pass
+                vars[n]['kindselector']['kind'] = l
+
+        savelindims = {}
+        if 'attrspec' in vars[n]:
+            attr = vars[n]['attrspec']
+            attr.reverse()
+            vars[n]['attrspec'] = []
+            dim, intent, depend, check, note = None, None, None, None, None
+            for a in attr:
+                if a[:9] == 'dimension':
+                    dim = (a[9:].strip())[1:-1]
+                elif a[:6] == 'intent':
+                    intent = (a[6:].strip())[1:-1]
+                elif a[:6] == 'depend':
+                    depend = (a[6:].strip())[1:-1]
+                elif a[:5] == 'check':
+                    check = (a[5:].strip())[1:-1]
+                elif a[:4] == 'note':
+                    note = (a[4:].strip())[1:-1]
+                else:
+                    vars[n] = setattrspec(vars[n], a)
+                if intent:
+                    if 'intent' not in vars[n]:
+                        vars[n]['intent'] = []
+                    for c in [x.strip() for x in markoutercomma(intent).split('@,@')]:
+                        # Remove spaces so that 'in out' becomes 'inout'
+                        tmp = c.replace(' ', '')
+                        if tmp not in vars[n]['intent']:
+                            vars[n]['intent'].append(tmp)
+                    intent = None
+                if note:
+                    note = note.replace('\\n\\n', '\n\n')
+                    note = note.replace('\\n ', '\n')
+                    if 'note' not in vars[n]:
+                        vars[n]['note'] = [note]
+                    else:
+                        vars[n]['note'].append(note)
+                    note = None
+                if depend is not None:
+                    if 'depend' not in vars[n]:
+                        vars[n]['depend'] = []
+                    for c in rmbadname([x.strip() for x in markoutercomma(depend).split('@,@')]):
+                        if c not in vars[n]['depend']:
+                            vars[n]['depend'].append(c)
+                    depend = None
+                if check is not None:
+                    if 'check' not in vars[n]:
+                        vars[n]['check'] = []
+                    for c in [x.strip() for x in markoutercomma(check).split('@,@')]:
+                        if c not in vars[n]['check']:
+                            vars[n]['check'].append(c)
+                    check = None
+            if dim and 'dimension' not in vars[n]:
+                vars[n]['dimension'] = []
+                for d in rmbadname([x.strip() for x in markoutercomma(dim).split('@,@')]):
+                    star = '*'
+                    if d == ':':
+                        star = ':'
+                    if d in params:
+                        d = str(params[d])
+                    for p in list(params.keys()):
+                        re_1 = re.compile(r'(?P<before>.*?)\b' + p + r'\b(?P<after>.*)', re.I)
+                        m = re_1.match(d)
+                        while m:
+                            d = m.group('before') + \
+                                str(params[p]) + m.group('after')
+                            m = re_1.match(d)
+                    if d == star:
+                        dl = [star]
+                    else:
+                        dl = markoutercomma(d, ':').split('@:@')
+                    if len(dl) == 2 and '*' in dl:  # e.g. dimension(5:*)
+                        dl = ['*']
+                        d = '*'
+                    if len(dl) == 1 and not dl[0] == star:
+                        dl = ['1', dl[0]]
+                    if len(dl) == 2:
+                        d, v, di = getarrlen(dl, list(block['vars'].keys()))
+                        if d[:4] == '1 * ':
+                            d = d[4:]
+                        if di and di[-4:] == '/(1)':
+                            di = di[:-4]
+                        if v:
+                            savelindims[d] = v, di
+                    vars[n]['dimension'].append(d)
+        if 'dimension' in vars[n]:
+            if isintent_c(vars[n]):
+                shape_macro = 'shape'
+            else:
+                shape_macro = 'shape'  # 'fshape'
+            if isstringarray(vars[n]):
+                if 'charselector' in vars[n]:
+                    d = vars[n]['charselector']
+                    if '*' in d:
+                        d = d['*']
+                        errmess('analyzevars: character array "character*%s %s(%s)" is considered as "character %s(%s)"; "intent(c)" is forced.\n'
+                                % (d, n,
+                                   ','.join(vars[n]['dimension']),
+                                   n, ','.join(vars[n]['dimension'] + [d])))
+                        vars[n]['dimension'].append(d)
+                        del vars[n]['charselector']
+                        if 'intent' not in vars[n]:
+                            vars[n]['intent'] = []
+                        if 'c' not in vars[n]['intent']:
+                            vars[n]['intent'].append('c')
+                    else:
+                        errmess(
+                            "analyzevars: charselector=%r unhandled." % (d))
+        if 'check' not in vars[n] and 'args' in block and n in block['args']:
+            flag = 'depend' not in vars[n]
+            if flag:
+                vars[n]['depend'] = []
+            vars[n]['check'] = []
+            if 'dimension' in vars[n]:
+                #/----< no check
+                i = -1
+                ni = len(vars[n]['dimension'])
+                for d in vars[n]['dimension']:
+                    ddeps = []  # dependecies of 'd'
+                    ad = ''
+                    pd = ''
+                    if d not in vars:
+                        if d in savelindims:
+                            pd, ad = '(', savelindims[d][1]
+                            d = savelindims[d][0]
+                        else:
+                            for r in block['args']:
+                                if r not in vars:
+                                    continue
+                                if re.match(r'.*?\b' + r + r'\b', d, re.I):
+                                    ddeps.append(r)
+                    if d in vars:
+                        if 'attrspec' in vars[d]:
+                            for aa in vars[d]['attrspec']:
+                                if aa[:6] == 'depend':
+                                    ddeps += aa[6:].strip()[1:-1].split(',')
+                        if 'depend' in vars[d]:
+                            ddeps = ddeps + vars[d]['depend']
+                    i = i + 1
+                    if d in vars and ('depend' not in vars[d]) \
+                       and ('=' not in vars[d]) and (d not in vars[n]['depend']) \
+                       and l_or(isintent_in, isintent_inout, isintent_inplace)(vars[n]):
+                        vars[d]['depend'] = [n]
+                        if ni > 1:
+                            vars[d]['='] = '%s%s(%s,%s)%s' % (
+                                pd, shape_macro, n, i, ad)
+                        else:
+                            vars[d]['='] = '%slen(%s)%s' % (pd, n, ad)
+                        #  /---< no check
+                        if 1 and 'check' not in vars[d]:
+                            if ni > 1:
+                                vars[d]['check'] = ['%s%s(%s,%i)%s==%s'
+                                                    % (pd, shape_macro, n, i, ad, d)]
+                            else:
+                                vars[d]['check'] = [
+                                    '%slen(%s)%s>=%s' % (pd, n, ad, d)]
+                        if 'attrspec' not in vars[d]:
+                            vars[d]['attrspec'] = ['optional']
+                        if ('optional' not in vars[d]['attrspec']) and\
+                           ('required' not in vars[d]['attrspec']):
+                            vars[d]['attrspec'].append('optional')
+                    elif d not in ['*', ':']:
+                        #/----< no check
+                        if flag:
+                            if d in vars:
+                                if n not in ddeps:
+                                    vars[n]['depend'].append(d)
+                            else:
+                                vars[n]['depend'] = vars[n]['depend'] + ddeps
+            elif isstring(vars[n]):
+                length = '1'
+                if 'charselector' in vars[n]:
+                    if '*' in vars[n]['charselector']:
+                        length = _eval_length(vars[n]['charselector']['*'],
+                                              params)
+                        vars[n]['charselector']['*'] = length
+                    elif 'len' in vars[n]['charselector']:
+                        length = _eval_length(vars[n]['charselector']['len'],
+                                              params)
+                        del vars[n]['charselector']['len']
+                        vars[n]['charselector']['*'] = length
+
+            if not vars[n]['check']:
+                del vars[n]['check']
+            if flag and not vars[n]['depend']:
+                del vars[n]['depend']
+        if '=' in vars[n]:
+            if 'attrspec' not in vars[n]:
+                vars[n]['attrspec'] = []
+            if ('optional' not in vars[n]['attrspec']) and \
+               ('required' not in vars[n]['attrspec']):
+                vars[n]['attrspec'].append('optional')
+            if 'depend' not in vars[n]:
+                vars[n]['depend'] = []
+                for v, m in list(dep_matches.items()):
+                    if m(vars[n]['=']):
+                        vars[n]['depend'].append(v)
+                if not vars[n]['depend']:
+                    del vars[n]['depend']
+            if isscalar(vars[n]):
+                vars[n]['='] = _eval_scalar(vars[n]['='], params)
+
+    for n in list(vars.keys()):
+        if n == block['name']:  # n is block name
+            if 'note' in vars[n]:
+                block['note'] = vars[n]['note']
+            if block['block'] == 'function':
+                if 'result' in block and block['result'] in vars:
+                    vars[n] = appenddecl(vars[n], vars[block['result']])
+                if 'prefix' in block:
+                    pr = block['prefix']
+                    ispure = 0
+                    isrec = 1
+                    pr1 = pr.replace('pure', '')
+                    ispure = (not pr == pr1)
+                    pr = pr1.replace('recursive', '')
+                    isrec = (not pr == pr1)
+                    m = typespattern[0].match(pr)
+                    if m:
+                        typespec, selector, attr, edecl = cracktypespec0(
+                            m.group('this'), m.group('after'))
+                        kindselect, charselect, typename = cracktypespec(
+                            typespec, selector)
+                        vars[n]['typespec'] = typespec
+                        if kindselect:
+                            if 'kind' in kindselect:
+                                try:
+                                    kindselect['kind'] = eval(
+                                        kindselect['kind'], {}, params)
+                                except:
+                                    pass
+                            vars[n]['kindselector'] = kindselect
+                        if charselect:
+                            vars[n]['charselector'] = charselect
+                        if typename:
+                            vars[n]['typename'] = typename
+                        if ispure:
+                            vars[n] = setattrspec(vars[n], 'pure')
+                        if isrec:
+                            vars[n] = setattrspec(vars[n], 'recursive')
+                    else:
+                        outmess(
+                            'analyzevars: prefix (%s) were not used\n' % repr(block['prefix']))
+    if not block['block'] in ['module', 'pythonmodule', 'python module', 'block data']:
+        if 'commonvars' in block:
+            neededvars = copy.copy(block['args'] + block['commonvars'])
+        else:
+            neededvars = copy.copy(block['args'])
+        for n in list(vars.keys()):
+            if l_or(isintent_callback, isintent_aux)(vars[n]):
+                neededvars.append(n)
+        if 'entry' in block:
+            neededvars.extend(list(block['entry'].keys()))
+            for k in list(block['entry'].keys()):
+                for n in block['entry'][k]:
+                    if n not in neededvars:
+                        neededvars.append(n)
+        if block['block'] == 'function':
+            if 'result' in block:
+                neededvars.append(block['result'])
+            else:
+                neededvars.append(block['name'])
+        if block['block'] in ['subroutine', 'function']:
+            name = block['name']
+            if name in vars and 'intent' in vars[name]:
+                block['intent'] = vars[name]['intent']
+        if block['block'] == 'type':
+            neededvars.extend(list(vars.keys()))
+        for n in list(vars.keys()):
+            if n not in neededvars:
+                del vars[n]
+    return vars
+
+analyzeargs_re_1 = re.compile(r'\A[a-z]+[\w$]*\Z', re.I)
+
+
+def expr2name(a, block, args=[]):
+    orig_a = a
+    a_is_expr = not analyzeargs_re_1.match(a)
+    if a_is_expr:  # `a` is an expression
+        implicitrules, attrrules = buildimplicitrules(block)
+        at = determineexprtype(a, block['vars'], implicitrules)
+        na = 'e_'
+        for c in a:
+            c = c.lower()
+            if c not in string.ascii_lowercase + string.digits:
+                c = '_'
+            na = na + c
+        if na[-1] == '_':
+            na = na + 'e'
+        else:
+            na = na + '_e'
+        a = na
+        while a in block['vars'] or a in block['args']:
+            a = a + 'r'
+    if a in args:
+        k = 1
+        while a + str(k) in args:
+            k = k + 1
+        a = a + str(k)
+    if a_is_expr:
+        block['vars'][a] = at
+    else:
+        if a not in block['vars']:
+            if orig_a in block['vars']:
+                block['vars'][a] = block['vars'][orig_a]
+            else:
+                block['vars'][a] = {}
+        if 'externals' in block and orig_a in block['externals'] + block['interfaced']:
+            block['vars'][a] = setattrspec(block['vars'][a], 'external')
+    return a
+
+
+def analyzeargs(block):
+    setmesstext(block)
+    implicitrules, attrrules = buildimplicitrules(block)
+    if 'args' not in block:
+        block['args'] = []
+    args = []
+    for a in block['args']:
+        a = expr2name(a, block, args)
+        args.append(a)
+    block['args'] = args
+    if 'entry' in block:
+        for k, args1 in list(block['entry'].items()):
+            for a in args1:
+                if a not in block['vars']:
+                    block['vars'][a] = {}
+
+    for b in block['body']:
+        if b['name'] in args:
+            if 'externals' not in block:
+                block['externals'] = []
+            if b['name'] not in block['externals']:
+                block['externals'].append(b['name'])
+    if 'result' in block and block['result'] not in block['vars']:
+        block['vars'][block['result']] = {}
+    return block
+
+determineexprtype_re_1 = re.compile(r'\A\(.+?[,].+?\)\Z', re.I)
+determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(P<name>[\w]+)|)\Z', re.I)
+determineexprtype_re_3 = re.compile(
+    r'\A[+-]?[\d.]+[\d+-de.]*(_(P<name>[\w]+)|)\Z', re.I)
+determineexprtype_re_4 = re.compile(r'\A\(.*\)\Z', re.I)
+determineexprtype_re_5 = re.compile(r'\A(?P<name>\w+)\s*\(.*?\)\s*\Z', re.I)
+
+
+def _ensure_exprdict(r):
+    if isinstance(r, int):
+        return {'typespec': 'integer'}
+    if isinstance(r, float):
+        return {'typespec': 'real'}
+    if isinstance(r, complex):
+        return {'typespec': 'complex'}
+    if isinstance(r, dict):
+        return r
+    raise AssertionError(repr(r))
+
+
+def determineexprtype(expr, vars, rules={}):
+    if expr in vars:
+        return _ensure_exprdict(vars[expr])
+    expr = expr.strip()
+    if determineexprtype_re_1.match(expr):
+        return {'typespec': 'complex'}
+    m = determineexprtype_re_2.match(expr)
+    if m:
+        if 'name' in m.groupdict() and m.group('name'):
+            outmess(
+                'determineexprtype: selected kind types not supported (%s)\n' % repr(expr))
+        return {'typespec': 'integer'}
+    m = determineexprtype_re_3.match(expr)
+    if m:
+        if 'name' in m.groupdict() and m.group('name'):
+            outmess(
+                'determineexprtype: selected kind types not supported (%s)\n' % repr(expr))
+        return {'typespec': 'real'}
+    for op in ['+', '-', '*', '/']:
+        for e in [x.strip() for x in markoutercomma(expr, comma=op).split('@' + op + '@')]:
+            if e in vars:
+                return _ensure_exprdict(vars[e])
+    t = {}
+    if determineexprtype_re_4.match(expr):  # in parenthesis
+        t = determineexprtype(expr[1:-1], vars, rules)
+    else:
+        m = determineexprtype_re_5.match(expr)
+        if m:
+            rn = m.group('name')
+            t = determineexprtype(m.group('name'), vars, rules)
+            if t and 'attrspec' in t:
+                del t['attrspec']
+            if not t:
+                if rn[0] in rules:
+                    return _ensure_exprdict(rules[rn[0]])
+    if expr[0] in '\'"':
+        return {'typespec': 'character', 'charselector': {'*': '*'}}
+    if not t:
+        outmess(
+            'determineexprtype: could not determine expressions (%s) type.\n' % (repr(expr)))
+    return t
+
+######
+
+
+def crack2fortrangen(block, tab='\n', as_interface=False):
+    global skipfuncs, onlyfuncs
+
+    setmesstext(block)
+    ret = ''
+    if isinstance(block, list):
+        for g in block:
+            if g and g['block'] in ['function', 'subroutine']:
+                if g['name'] in skipfuncs:
+                    continue
+                if onlyfuncs and g['name'] not in onlyfuncs:
+                    continue
+            ret = ret + crack2fortrangen(g, tab, as_interface=as_interface)
+        return ret
+    prefix = ''
+    name = ''
+    args = ''
+    blocktype = block['block']
+    if blocktype == 'program':
+        return ''
+    argsl = []
+    if 'name' in block:
+        name = block['name']
+    if 'args' in block:
+        vars = block['vars']
+        for a in block['args']:
+            a = expr2name(a, block, argsl)
+            if not isintent_callback(vars[a]):
+                argsl.append(a)
+        if block['block'] == 'function' or argsl:
+            args = '(%s)' % ','.join(argsl)
+    f2pyenhancements = ''
+    if 'f2pyenhancements' in block:
+        for k in list(block['f2pyenhancements'].keys()):
+            f2pyenhancements = '%s%s%s %s' % (
+                f2pyenhancements, tab + tabchar, k, block['f2pyenhancements'][k])
+    intent_lst = block.get('intent', [])[:]
+    if blocktype == 'function' and 'callback' in intent_lst:
+        intent_lst.remove('callback')
+    if intent_lst:
+        f2pyenhancements = '%s%sintent(%s) %s' %\
+                           (f2pyenhancements, tab + tabchar,
+                            ','.join(intent_lst), name)
+    use = ''
+    if 'use' in block:
+        use = use2fortran(block['use'], tab + tabchar)
+    common = ''
+    if 'common' in block:
+        common = common2fortran(block['common'], tab + tabchar)
+    if name == 'unknown_interface':
+        name = ''
+    result = ''
+    if 'result' in block:
+        result = ' result (%s)' % block['result']
+        if block['result'] not in argsl:
+            argsl.append(block['result'])
+    body = crack2fortrangen(block['body'], tab + tabchar)
+    vars = vars2fortran(
+        block, block['vars'], argsl, tab + tabchar, as_interface=as_interface)
+    mess = ''
+    if 'from' in block and not as_interface:
+        mess = '! in %s' % block['from']
+    if 'entry' in block:
+        entry_stmts = ''
+        for k, i in list(block['entry'].items()):
+            entry_stmts = '%s%sentry %s(%s)' \
+                          % (entry_stmts, tab + tabchar, k, ','.join(i))
+        body = body + entry_stmts
+    if blocktype == 'block data' and name == '_BLOCK_DATA_':
+        name = ''
+    ret = '%s%s%s %s%s%s %s%s%s%s%s%s%send %s %s' % (
+        tab, prefix, blocktype, name, args, result, mess, f2pyenhancements, use, vars, common, body, tab, blocktype, name)
+    return ret
+
+
+def common2fortran(common, tab=''):
+    ret = ''
+    for k in list(common.keys()):
+        if k == '_BLNK_':
+            ret = '%s%scommon %s' % (ret, tab, ','.join(common[k]))
+        else:
+            ret = '%s%scommon /%s/ %s' % (ret, tab, k, ','.join(common[k]))
+    return ret
+
+
+def use2fortran(use, tab=''):
+    ret = ''
+    for m in list(use.keys()):
+        ret = '%s%suse %s,' % (ret, tab, m)
+        if use[m] == {}:
+            if ret and ret[-1] == ',':
+                ret = ret[:-1]
+            continue
+        if 'only' in use[m] and use[m]['only']:
+            ret = '%s only:' % (ret)
+        if 'map' in use[m] and use[m]['map']:
+            c = ' '
+            for k in list(use[m]['map'].keys()):
+                if k == use[m]['map'][k]:
+                    ret = '%s%s%s' % (ret, c, k)
+                    c = ','
+                else:
+                    ret = '%s%s%s=>%s' % (ret, c, k, use[m]['map'][k])
+                    c = ','
+        if ret and ret[-1] == ',':
+            ret = ret[:-1]
+    return ret
+
+
+def true_intent_list(var):
+    lst = var['intent']
+    ret = []
+    for intent in lst:
+        try:
+            c = eval('isintent_%s(var)' % intent)
+        except NameError:
+            c = 0
+        if c:
+            ret.append(intent)
+    return ret
+
+
+def vars2fortran(block, vars, args, tab='', as_interface=False):
+    """
+    TODO:
+    public sub
+    ...
+    """
+    setmesstext(block)
+    ret = ''
+    nout = []
+    for a in args:
+        if a in block['vars']:
+            nout.append(a)
+    if 'commonvars' in block:
+        for a in block['commonvars']:
+            if a in vars:
+                if a not in nout:
+                    nout.append(a)
+            else:
+                errmess(
+                    'vars2fortran: Confused?!: "%s" is not defined in vars.\n' % a)
+    if 'varnames' in block:
+        nout.extend(block['varnames'])
+    if not as_interface:
+        for a in list(vars.keys()):
+            if a not in nout:
+                nout.append(a)
+    for a in nout:
+        if 'depend' in vars[a]:
+            for d in vars[a]['depend']:
+                if d in vars and 'depend' in vars[d] and a in vars[d]['depend']:
+                    errmess(
+                        'vars2fortran: Warning: cross-dependence between variables "%s" and "%s"\n' % (a, d))
+        if 'externals' in block and a in block['externals']:
+            if isintent_callback(vars[a]):
+                ret = '%s%sintent(callback) %s' % (ret, tab, a)
+            ret = '%s%sexternal %s' % (ret, tab, a)
+            if isoptional(vars[a]):
+                ret = '%s%soptional %s' % (ret, tab, a)
+            if a in vars and 'typespec' not in vars[a]:
+                continue
+            cont = 1
+            for b in block['body']:
+                if a == b['name'] and b['block'] == 'function':
+                    cont = 0
+                    break
+            if cont:
+                continue
+        if a not in vars:
+            show(vars)
+            outmess('vars2fortran: No definition for argument "%s".\n' % a)
+            continue
+        if a == block['name'] and not block['block'] == 'function':
+            continue
+        if 'typespec' not in vars[a]:
+            if 'attrspec' in vars[a] and 'external' in vars[a]['attrspec']:
+                if a in args:
+                    ret = '%s%sexternal %s' % (ret, tab, a)
+                continue
+            show(vars[a])
+            outmess('vars2fortran: No typespec for argument "%s".\n' % a)
+            continue
+        vardef = vars[a]['typespec']
+        if vardef == 'type' and 'typename' in vars[a]:
+            vardef = '%s(%s)' % (vardef, vars[a]['typename'])
+        selector = {}
+        if 'kindselector' in vars[a]:
+            selector = vars[a]['kindselector']
+        elif 'charselector' in vars[a]:
+            selector = vars[a]['charselector']
+        if '*' in selector:
+            if selector['*'] in ['*', ':']:
+                vardef = '%s*(%s)' % (vardef, selector['*'])
+            else:
+                vardef = '%s*%s' % (vardef, selector['*'])
+        else:
+            if 'len' in selector:
+                vardef = '%s(len=%s' % (vardef, selector['len'])
+                if 'kind' in selector:
+                    vardef = '%s,kind=%s)' % (vardef, selector['kind'])
+                else:
+                    vardef = '%s)' % (vardef)
+            elif 'kind' in selector:
+                vardef = '%s(kind=%s)' % (vardef, selector['kind'])
+        c = ' '
+        if 'attrspec' in vars[a]:
+            attr = []
+            for l in vars[a]['attrspec']:
+                if l not in ['external']:
+                    attr.append(l)
+            if attr:
+                vardef = '%s, %s' % (vardef, ','.join(attr))
+                c = ','
+        if 'dimension' in vars[a]:
+            vardef = '%s%sdimension(%s)' % (
+                vardef, c, ','.join(vars[a]['dimension']))
+            c = ','
+        if 'intent' in vars[a]:
+            lst = true_intent_list(vars[a])
+            if lst:
+                vardef = '%s%sintent(%s)' % (vardef, c, ','.join(lst))
+            c = ','
+        if 'check' in vars[a]:
+            vardef = '%s%scheck(%s)' % (vardef, c, ','.join(vars[a]['check']))
+            c = ','
+        if 'depend' in vars[a]:
+            vardef = '%s%sdepend(%s)' % (
+                vardef, c, ','.join(vars[a]['depend']))
+            c = ','
+        if '=' in vars[a]:
+            v = vars[a]['=']
+            if vars[a]['typespec'] in ['complex', 'double complex']:
+                try:
+                    v = eval(v)
+                    v = '(%s,%s)' % (v.real, v.imag)
+                except:
+                    pass
+            vardef = '%s :: %s=%s' % (vardef, a, v)
+        else:
+            vardef = '%s :: %s' % (vardef, a)
+        ret = '%s%s%s' % (ret, tab, vardef)
+    return ret
+######
+
+
+def crackfortran(files):
+    global usermodules
+
+    outmess('Reading fortran codes...\n', 0)
+    readfortrancode(files, crackline)
+    outmess('Post-processing...\n', 0)
+    usermodules = []
+    postlist = postcrack(grouplist[0])
+    outmess('Post-processing (stage 2)...\n', 0)
+    postlist = postcrack2(postlist)
+    return usermodules + postlist
+
+
+def crack2fortran(block):
+    global f2py_version
+
+    pyf = crack2fortrangen(block) + '\n'
+    header = """!    -*- f90 -*-
+! Note: the context of this file is case sensitive.
+"""
+    footer = """
+! This file was auto-generated with f2py (version:%s).
+! See http://cens.ioc.ee/projects/f2py2e/
+""" % (f2py_version)
+    return header + pyf + footer
+
+if __name__ == "__main__":
+    files = []
+    funcs = []
+    f = 1
+    f2 = 0
+    f3 = 0
+    showblocklist = 0
+    for l in sys.argv[1:]:
+        if l == '':
+            pass
+        elif l[0] == ':':
+            f = 0
+        elif l == '-quiet':
+            quiet = 1
+            verbose = 0
+        elif l == '-verbose':
+            verbose = 2
+            quiet = 0
+        elif l == '-fix':
+            if strictf77:
+                outmess(
+                    'Use option -f90 before -fix if Fortran 90 code is in fix form.\n', 0)
+            skipemptyends = 1
+            sourcecodeform = 'fix'
+        elif l == '-skipemptyends':
+            skipemptyends = 1
+        elif l == '--ignore-contains':
+            ignorecontains = 1
+        elif l == '-f77':
+            strictf77 = 1
+            sourcecodeform = 'fix'
+        elif l == '-f90':
+            strictf77 = 0
+            sourcecodeform = 'free'
+            skipemptyends = 1
+        elif l == '-h':
+            f2 = 1
+        elif l == '-show':
+            showblocklist = 1
+        elif l == '-m':
+            f3 = 1
+        elif l[0] == '-':
+            errmess('Unknown option %s\n' % repr(l))
+        elif f2:
+            f2 = 0
+            pyffilename = l
+        elif f3:
+            f3 = 0
+            f77modulename = l
+        elif f:
+            try:
+                open(l).close()
+                files.append(l)
+            except IOError as detail:
+                errmess('IOError: %s\n' % str(detail))
+        else:
+            funcs.append(l)
+    if not strictf77 and f77modulename and not skipemptyends:
+        outmess("""\
+  Warning: You have specifyied module name for non Fortran 77 code
+  that should not need one (expect if you are scanning F90 code
+  for non module blocks but then you should use flag -skipemptyends
+  and also be sure that the files do not contain programs without program statement).
+""", 0)
+
+    postlist = crackfortran(files, funcs)
+    if pyffilename:
+        outmess('Writing fortran code to file %s\n' % repr(pyffilename), 0)
+        pyf = crack2fortran(postlist)
+        f = open(pyffilename, 'w')
+        f.write(pyf)
+        f.close()
+    if showblocklist:
+        show(postlist)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.py
new file mode 100644
index 0000000000..e25573056b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python2
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import tempfile
+
+
+def run_command(cmd):
+    print('Running %r:' % (cmd))
+    os.system(cmd)
+    print('------')
+
+
+def run():
+    _path = os.getcwd()
+    os.chdir(tempfile.gettempdir())
+    print('------')
+    print('os.name=%r' % (os.name))
+    print('------')
+    print('sys.platform=%r' % (sys.platform))
+    print('------')
+    print('sys.version:')
+    print(sys.version)
+    print('------')
+    print('sys.prefix:')
+    print(sys.prefix)
+    print('------')
+    print('sys.path=%r' % (':'.join(sys.path)))
+    print('------')
+
+    try:
+        import numpy
+        has_newnumpy = 1
+    except ImportError:
+        print('Failed to import new numpy:', sys.exc_info()[1])
+        has_newnumpy = 0
+
+    try:
+        from numpy.f2py import f2py2e
+        has_f2py2e = 1
+    except ImportError:
+        print('Failed to import f2py2e:', sys.exc_info()[1])
+        has_f2py2e = 0
+
+    try:
+        import numpy.distutils
+        has_numpy_distutils = 2
+    except ImportError:
+        try:
+            import numpy_distutils
+            has_numpy_distutils = 1
+        except ImportError:
+            print('Failed to import numpy_distutils:', sys.exc_info()[1])
+            has_numpy_distutils = 0
+
+    if has_newnumpy:
+        try:
+            print('Found new numpy version %r in %s' %
+                  (numpy.__version__, numpy.__file__))
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+
+    if has_f2py2e:
+        try:
+            print('Found f2py2e version %r in %s' %
+                  (f2py2e.__version__.version, f2py2e.__file__))
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+
+    if has_numpy_distutils:
+        try:
+            if has_numpy_distutils == 2:
+                print('Found numpy.distutils version %r in %r' % (
+                    numpy.distutils.__version__,
+                    numpy.distutils.__file__))
+            else:
+                print('Found numpy_distutils version %r in %r' % (
+                    numpy_distutils.numpy_distutils_version.numpy_distutils_version,
+                    numpy_distutils.__file__))
+            print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+        try:
+            if has_numpy_distutils == 1:
+                print(
+                    'Importing numpy_distutils.command.build_flib ...', end=' ')
+                import numpy_distutils.command.build_flib as build_flib
+                print('ok')
+                print('------')
+                try:
+                    print(
+                        'Checking availability of supported Fortran compilers:')
+                    for compiler_class in build_flib.all_compilers:
+                        compiler_class(verbose=1).is_available()
+                        print('------')
+                except Exception as msg:
+                    print('error:', msg)
+                    print('------')
+        except Exception as msg:
+            print(
+                'error:', msg, '(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)')
+            print('------')
+        try:
+            if has_numpy_distutils == 2:
+                print('Importing numpy.distutils.fcompiler ...', end=' ')
+                import numpy.distutils.fcompiler as fcompiler
+            else:
+                print('Importing numpy_distutils.fcompiler ...', end=' ')
+                import numpy_distutils.fcompiler as fcompiler
+            print('ok')
+            print('------')
+            try:
+                print('Checking availability of supported Fortran compilers:')
+                fcompiler.show_fcompilers()
+                print('------')
+            except Exception as msg:
+                print('error:', msg)
+                print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+        try:
+            if has_numpy_distutils == 2:
+                print('Importing numpy.distutils.cpuinfo ...', end=' ')
+                from numpy.distutils.cpuinfo import cpuinfo
+                print('ok')
+                print('------')
+            else:
+                try:
+                    print(
+                        'Importing numpy_distutils.command.cpuinfo ...', end=' ')
+                    from numpy_distutils.command.cpuinfo import cpuinfo
+                    print('ok')
+                    print('------')
+                except Exception as msg:
+                    print('error:', msg, '(ignore it)')
+                    print('Importing numpy_distutils.cpuinfo ...', end=' ')
+                    from numpy_distutils.cpuinfo import cpuinfo
+                    print('ok')
+                    print('------')
+            cpu = cpuinfo()
+            print('CPU information:', end=' ')
+            for name in dir(cpuinfo):
+                if name[0] == '_' and name[1] != '_' and getattr(cpu, name[1:])():
+                    print(name[1:], end=' ')
+            print('------')
+        except Exception as msg:
+            print('error:', msg)
+            print('------')
+    os.chdir(_path)
+if __name__ == "__main__":
+    run()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
new file mode 100644
index 0000000000..8008e6bdb7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
@@ -0,0 +1,656 @@
+#!/usr/bin/env python2
+"""
+
+f2py2e - Fortran to Python C/API generator. 2nd Edition.
+         See __usage__ below.
+
+Copyright 1999--2011 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/05/06 08:31:19 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import pprint
+import re
+
+from . import crackfortran
+from . import rules
+from . import cb_rules
+from . import auxfuncs
+from . import cfuncs
+from . import f90mod_rules
+from . import __version__
+
+f2py_version = __version__.version
+errmess = sys.stderr.write
+# outmess=sys.stdout.write
+show = pprint.pprint
+outmess = auxfuncs.outmess
+
+try:
+    from numpy import __version__ as numpy_version
+except ImportError:
+    numpy_version = 'N/A'
+
+__usage__ = """\
+Usage:
+
+1) To construct extension module sources:
+
+      f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
+                                        <fortran functions> ] \\
+                                       [: <fortran files> ...]
+
+2) To compile fortran files and build extension modules:
+
+      f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
+
+3) To generate signature files:
+
+      f2py -h <filename.pyf> ...< same options as in (1) >
+
+Description: This program generates a Python C/API file (<modulename>module.c)
+             that contains wrappers for given fortran functions so that they
+             can be called from Python. With the -c option the corresponding
+             extension modules are built.
+
+Options:
+
+  --2d-numpy       Use numpy.f2py tool with NumPy support. [DEFAULT]
+  --2d-numeric     Use f2py2e tool with Numeric support.
+  --2d-numarray    Use f2py2e tool with Numarray support.
+  --g3-numpy       Use 3rd generation f2py from the separate f2py package.
+                   [NOT AVAILABLE YET]
+
+  -h <filename>    Write signatures of the fortran routines to file <filename>
+                   and exit. You can then edit <filename> and use it instead
+                   of <fortran files>. If <filename>==stdout then the
+                   signatures are printed to stdout.
+  <fortran functions>  Names of fortran routines for which Python C/API
+                   functions will be generated. Default is all that are found
+                   in <fortran files>.
+  <fortran files>  Paths to fortran/signature files that will be scanned for
+                   <fortran functions> in order to determine their signatures.
+  skip:            Ignore fortran functions that follow until `:'.
+  only:            Use only fortran functions that follow until `:'.
+  :                Get back to <fortran files> mode.
+
+  -m <modulename>  Name of the module; f2py generates a Python/C API
+                   file <modulename>module.c or extension module <modulename>.
+                   Default is 'untitled'.
+
+  --[no-]lower     Do [not] lower the cases in <fortran files>. By default,
+                   --lower is assumed with -h key, and --no-lower without -h key.
+
+  --build-dir <dirname>  All f2py generated files are created in <dirname>.
+                   Default is tempfile.mkdtemp().
+
+  --overwrite-signature  Overwrite existing signature file.
+
+  --[no-]latex-doc Create (or not) <modulename>module.tex.
+                   Default is --no-latex-doc.
+  --short-latex    Create 'incomplete' LaTeX document (without commands
+                   \\documentclass, \\tableofcontents, and \\begin{document},
+                   \\end{document}).
+
+  --[no-]rest-doc Create (or not) <modulename>module.rst.
+                   Default is --no-rest-doc.
+
+  --debug-capi     Create C/API code that reports the state of the wrappers
+                   during runtime. Useful for debugging.
+
+  --[no-]wrap-functions    Create Fortran subroutine wrappers to Fortran 77
+                   functions. --wrap-functions is default because it ensures
+                   maximum portability/compiler independence.
+
+  --include-paths <path1>:<path2>:...   Search include files from the given
+                   directories.
+
+  --help-link [..] List system resources found by system_info.py. See also
+                   --link-<resource> switch below. [..] is optional list
+                   of resources names. E.g. try 'f2py --help-link lapack_opt'.
+
+  --quiet          Run quietly.
+  --verbose        Run with extra verbosity.
+  -v               Print f2py version ID and exit.
+
+
+numpy.distutils options (only effective with -c):
+
+  --fcompiler=         Specify Fortran compiler type by vendor
+  --compiler=          Specify C compiler type (as defined by distutils)
+
+  --help-fcompiler     List available Fortran compilers and exit
+  --f77exec=           Specify the path to F77 compiler
+  --f90exec=           Specify the path to F90 compiler
+  --f77flags=          Specify F77 compiler flags
+  --f90flags=          Specify F90 compiler flags
+  --opt=               Specify optimization flags
+  --arch=              Specify architecture specific optimization flags
+  --noopt              Compile without optimization
+  --noarch             Compile without arch-dependent optimization
+  --debug              Compile with debugging information
+
+Extra options (only effective with -c):
+
+  --link-<resource>    Link extension module with <resource> as defined
+                       by numpy.distutils/system_info.py. E.g. to link
+                       with optimized LAPACK libraries (vecLib on MacOSX,
+                       ATLAS elsewhere), use --link-lapack_opt.
+                       See also --help-link switch.
+
+  -L/path/to/lib/ -l<libname>
+  -D<define> -U<name>
+  -I/path/to/include/
+  <filename>.o <filename>.so <filename>.a
+
+  Using the following macros may be required with non-gcc Fortran
+  compilers:
+    -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
+    -DUNDERSCORE_G77
+
+  When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
+  interface is printed out at exit (platforms: Linux).
+
+  When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
+  sent to stderr whenever F2PY interface makes a copy of an
+  array. Integer <int> sets the threshold for array sizes when
+  a message should be shown.
+
+Version:     %s
+numpy Version: %s
+Requires:    Python 2.3 or higher.
+License:     NumPy license (see LICENSE.txt in the NumPy source code)
+Copyright 1999 - 2011 Pearu Peterson all rights reserved.
+http://cens.ioc.ee/projects/f2py2e/""" % (f2py_version, numpy_version)
+
+
+def scaninputline(inputline):
+    files, skipfuncs, onlyfuncs, debug = [], [], [], []
+    f, f2, f3, f5, f6, f7, f8, f9 = 1, 0, 0, 0, 0, 0, 0, 0
+    verbose = 1
+    dolc = -1
+    dolatexdoc = 0
+    dorestdoc = 0
+    wrapfuncs = 1
+    buildpath = '.'
+    include_paths = []
+    signsfile, modulename = None, None
+    options = {'buildpath': buildpath,
+               'coutput': None,
+               'f2py_wrapper_output': None}
+    for l in inputline:
+        if l == '':
+            pass
+        elif l == 'only:':
+            f = 0
+        elif l == 'skip:':
+            f = -1
+        elif l == ':':
+            f = 1
+        elif l[:8] == '--debug-':
+            debug.append(l[8:])
+        elif l == '--lower':
+            dolc = 1
+        elif l == '--build-dir':
+            f6 = 1
+        elif l == '--no-lower':
+            dolc = 0
+        elif l == '--quiet':
+            verbose = 0
+        elif l == '--verbose':
+            verbose += 1
+        elif l == '--latex-doc':
+            dolatexdoc = 1
+        elif l == '--no-latex-doc':
+            dolatexdoc = 0
+        elif l == '--rest-doc':
+            dorestdoc = 1
+        elif l == '--no-rest-doc':
+            dorestdoc = 0
+        elif l == '--wrap-functions':
+            wrapfuncs = 1
+        elif l == '--no-wrap-functions':
+            wrapfuncs = 0
+        elif l == '--short-latex':
+            options['shortlatex'] = 1
+        elif l == '--coutput':
+            f8 = 1
+        elif l == '--f2py-wrapper-output':
+            f9 = 1
+        elif l == '--overwrite-signature':
+            options['h-overwrite'] = 1
+        elif l == '-h':
+            f2 = 1
+        elif l == '-m':
+            f3 = 1
+        elif l[:2] == '-v':
+            print(f2py_version)
+            sys.exit()
+        elif l == '--show-compilers':
+            f5 = 1
+        elif l[:8] == '-include':
+            cfuncs.outneeds['userincludes'].append(l[9:-1])
+            cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:]
+        elif l[:15] in '--include_paths':
+            outmess(
+                'f2py option --include_paths is deprecated, use --include-paths instead.\n')
+            f7 = 1
+        elif l[:15] in '--include-paths':
+            f7 = 1
+        elif l[0] == '-':
+            errmess('Unknown option %s\n' % repr(l))
+            sys.exit()
+        elif f2:
+            f2 = 0
+            signsfile = l
+        elif f3:
+            f3 = 0
+            modulename = l
+        elif f6:
+            f6 = 0
+            buildpath = l
+        elif f7:
+            f7 = 0
+            include_paths.extend(l.split(os.pathsep))
+        elif f8:
+            f8 = 0
+            options["coutput"] = l
+        elif f9:
+            f9 = 0
+            options["f2py_wrapper_output"] = l
+        elif f == 1:
+            try:
+                open(l).close()
+                files.append(l)
+            except IOError as detail:
+                errmess('IOError: %s. Skipping file "%s".\n' %
+                        (str(detail), l))
+        elif f == -1:
+            skipfuncs.append(l)
+        elif f == 0:
+            onlyfuncs.append(l)
+    if not f5 and not files and not modulename:
+        print(__usage__)
+        sys.exit()
+    if not os.path.isdir(buildpath):
+        if not verbose:
+            outmess('Creating build directory %s' % (buildpath))
+        os.mkdir(buildpath)
+    if signsfile:
+        signsfile = os.path.join(buildpath, signsfile)
+    if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options:
+        errmess(
+            'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
+        sys.exit()
+
+    options['debug'] = debug
+    options['verbose'] = verbose
+    if dolc == -1 and not signsfile:
+        options['do-lower'] = 0
+    else:
+        options['do-lower'] = dolc
+    if modulename:
+        options['module'] = modulename
+    if signsfile:
+        options['signsfile'] = signsfile
+    if onlyfuncs:
+        options['onlyfuncs'] = onlyfuncs
+    if skipfuncs:
+        options['skipfuncs'] = skipfuncs
+    options['dolatexdoc'] = dolatexdoc
+    options['dorestdoc'] = dorestdoc
+    options['wrapfuncs'] = wrapfuncs
+    options['buildpath'] = buildpath
+    options['include_paths'] = include_paths
+    return files, options
+
+
+def callcrackfortran(files, options):
+    rules.options = options
+    crackfortran.debug = options['debug']
+    crackfortran.verbose = options['verbose']
+    if 'module' in options:
+        crackfortran.f77modulename = options['module']
+    if 'skipfuncs' in options:
+        crackfortran.skipfuncs = options['skipfuncs']
+    if 'onlyfuncs' in options:
+        crackfortran.onlyfuncs = options['onlyfuncs']
+    crackfortran.include_paths[:] = options['include_paths']
+    crackfortran.dolowercase = options['do-lower']
+    postlist = crackfortran.crackfortran(files)
+    if 'signsfile' in options:
+        outmess('Saving signatures to file "%s"\n' % (options['signsfile']))
+        pyf = crackfortran.crack2fortran(postlist)
+        if options['signsfile'][-6:] == 'stdout':
+            sys.stdout.write(pyf)
+        else:
+            f = open(options['signsfile'], 'w')
+            f.write(pyf)
+            f.close()
+    if options["coutput"] is None:
+        for mod in postlist:
+            mod["coutput"] = "%smodule.c" % mod["name"]
+    else:
+        for mod in postlist:
+            mod["coutput"] = options["coutput"]
+    if options["f2py_wrapper_output"] is None:
+        for mod in postlist:
+            mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"]
+    else:
+        for mod in postlist:
+            mod["f2py_wrapper_output"] = options["f2py_wrapper_output"]
+    return postlist
+
+
+def buildmodules(lst):
+    cfuncs.buildcfuncs()
+    outmess('Building modules...\n')
+    modules, mnames, isusedby = [], [], {}
+    for i in range(len(lst)):
+        if '__user__' in lst[i]['name']:
+            cb_rules.buildcallbacks(lst[i])
+        else:
+            if 'use' in lst[i]:
+                for u in lst[i]['use'].keys():
+                    if u not in isusedby:
+                        isusedby[u] = []
+                    isusedby[u].append(lst[i]['name'])
+            modules.append(lst[i])
+            mnames.append(lst[i]['name'])
+    ret = {}
+    for i in range(len(mnames)):
+        if mnames[i] in isusedby:
+            outmess('\tSkipping module "%s" which is used by %s.\n' % (
+                mnames[i], ','.join(['"%s"' % s for s in isusedby[mnames[i]]])))
+        else:
+            um = []
+            if 'use' in modules[i]:
+                for u in modules[i]['use'].keys():
+                    if u in isusedby and u in mnames:
+                        um.append(modules[mnames.index(u)])
+                    else:
+                        outmess(
+                            '\tModule "%s" uses nonexisting "%s" which will be ignored.\n' % (mnames[i], u))
+            ret[mnames[i]] = {}
+            dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um))
+    return ret
+
+
+def dict_append(d_out, d_in):
+    for (k, v) in d_in.items():
+        if k not in d_out:
+            d_out[k] = []
+        if isinstance(v, list):
+            d_out[k] = d_out[k] + v
+        else:
+            d_out[k].append(v)
+
+
+def run_main(comline_list):
+    """Run f2py as if string.join(comline_list,' ') is used as a command line.
+    In case of using -h flag, return None.
+    """
+    crackfortran.reset_global_f2py_vars()
+    f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__))
+    fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h')
+    fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
+    files, options = scaninputline(comline_list)
+    auxfuncs.options = options
+    postlist = callcrackfortran(files, options)
+    isusedby = {}
+    for i in range(len(postlist)):
+        if 'use' in postlist[i]:
+            for u in postlist[i]['use'].keys():
+                if u not in isusedby:
+                    isusedby[u] = []
+                isusedby[u].append(postlist[i]['name'])
+    for i in range(len(postlist)):
+        if postlist[i]['block'] == 'python module' and '__user__' in postlist[i]['name']:
+            if postlist[i]['name'] in isusedby:
+                # if not quiet:
+                outmess('Skipping Makefile build for module "%s" which is used by %s\n' % (
+                    postlist[i]['name'], ','.join(['"%s"' % s for s in isusedby[postlist[i]['name']]])))
+    if 'signsfile' in options:
+        if options['verbose'] > 1:
+            outmess(
+                'Stopping. Edit the signature file and then run f2py on the signature file: ')
+            outmess('%s %s\n' %
+                    (os.path.basename(sys.argv[0]), options['signsfile']))
+        return
+    for i in range(len(postlist)):
+        if postlist[i]['block'] != 'python module':
+            if 'python module' not in options:
+                errmess(
+                    'Tip: If your original code is Fortran source then you must use -m option.\n')
+            raise TypeError('All blocks must be python module blocks but got %s' % (
+                repr(postlist[i]['block'])))
+    auxfuncs.debugoptions = options['debug']
+    f90mod_rules.options = options
+    auxfuncs.wrapfuncs = options['wrapfuncs']
+
+    ret = buildmodules(postlist)
+
+    for mn in ret.keys():
+        dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc})
+    return ret
+
+
+def filter_files(prefix, suffix, files, remove_prefix=None):
+    """
+    Filter files by prefix and suffix.
+    """
+    filtered, rest = [], []
+    match = re.compile(prefix + r'.*' + suffix + r'\Z').match
+    if remove_prefix:
+        ind = len(prefix)
+    else:
+        ind = 0
+    for file in [x.strip() for x in files]:
+        if match(file):
+            filtered.append(file[ind:])
+        else:
+            rest.append(file)
+    return filtered, rest
+
+
+def get_prefix(module):
+    p = os.path.dirname(os.path.dirname(module.__file__))
+    return p
+
+
+def run_compile():
+    """
+    Do it all in one call!
+    """
+    import tempfile
+
+    i = sys.argv.index('-c')
+    del sys.argv[i]
+
+    remove_build_dir = 0
+    try:
+        i = sys.argv.index('--build-dir')
+    except ValueError:
+        i = None
+    if i is not None:
+        build_dir = sys.argv[i + 1]
+        del sys.argv[i + 1]
+        del sys.argv[i]
+    else:
+        remove_build_dir = 1
+        build_dir = tempfile.mkdtemp()
+
+    _reg1 = re.compile(r'[-][-]link[-]')
+    sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
+    if sysinfo_flags:
+        sysinfo_flags = [f[7:] for f in sysinfo_flags]
+
+    _reg2 = re.compile(
+        r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include')
+    f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
+    f2py_flags2 = []
+    fl = 0
+    for a in sys.argv[1:]:
+        if a in ['only:', 'skip:']:
+            fl = 1
+        elif a == ':':
+            fl = 0
+        if fl or a == ':':
+            f2py_flags2.append(a)
+    if f2py_flags2 and f2py_flags2[-1] != ':':
+        f2py_flags2.append(':')
+    f2py_flags.extend(f2py_flags2)
+
+    sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
+    _reg3 = re.compile(
+        r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)')
+    flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
+    _reg4 = re.compile(
+        r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))')
+    fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in fc_flags]
+
+    if 1:
+        del_list = []
+        for s in flib_flags:
+            v = '--fcompiler='
+            if s[:len(v)] == v:
+                from numpy.distutils import fcompiler
+                fcompiler.load_all_fcompiler_classes()
+                allowed_keys = list(fcompiler.fcompiler_class.keys())
+                nv = ov = s[len(v):].lower()
+                if ov not in allowed_keys:
+                    vmap = {}  # XXX
+                    try:
+                        nv = vmap[ov]
+                    except KeyError:
+                        if ov not in vmap.values():
+                            print('Unknown vendor: "%s"' % (s[len(v):]))
+                    nv = ov
+                i = flib_flags.index(s)
+                flib_flags[i] = '--fcompiler=' + nv
+                continue
+        for s in del_list:
+            i = flib_flags.index(s)
+            del flib_flags[i]
+        assert len(flib_flags) <= 2, repr(flib_flags)
+
+    _reg5 = re.compile(r'[-][-](verbose)')
+    setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
+    sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
+
+    if '--quiet' in f2py_flags:
+        setup_flags.append('--quiet')
+
+    modulename = 'untitled'
+    sources = sys.argv[1:]
+
+    for optname in ['--include_paths', '--include-paths']:
+        if optname in sys.argv:
+            i = sys.argv.index(optname)
+            f2py_flags.extend(sys.argv[i:i + 2])
+            del sys.argv[i + 1], sys.argv[i]
+            sources = sys.argv[1:]
+
+    if '-m' in sys.argv:
+        i = sys.argv.index('-m')
+        modulename = sys.argv[i + 1]
+        del sys.argv[i + 1], sys.argv[i]
+        sources = sys.argv[1:]
+    else:
+        from numpy.distutils.command.build_src import get_f2py_modulename
+        pyf_files, sources = filter_files('', '[.]pyf([.]src|)', sources)
+        sources = pyf_files + sources
+        for f in pyf_files:
+            modulename = get_f2py_modulename(f)
+            if modulename:
+                break
+
+    extra_objects, sources = filter_files('', '[.](o|a|so)', sources)
+    include_dirs, sources = filter_files('-I', '', sources, remove_prefix=1)
+    library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1)
+    libraries, sources = filter_files('-l', '', sources, remove_prefix=1)
+    undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1)
+    define_macros, sources = filter_files('-D', '', sources, remove_prefix=1)
+    for i in range(len(define_macros)):
+        name_value = define_macros[i].split('=', 1)
+        if len(name_value) == 1:
+            name_value.append(None)
+        if len(name_value) == 2:
+            define_macros[i] = tuple(name_value)
+        else:
+            print('Invalid use of -D:', name_value)
+
+    from numpy.distutils.system_info import get_info
+
+    num_info = {}
+    if num_info:
+        include_dirs.extend(num_info.get('include_dirs', []))
+
+    from numpy.distutils.core import setup, Extension
+    ext_args = {'name': modulename, 'sources': sources,
+                'include_dirs': include_dirs,
+                'library_dirs': library_dirs,
+                'libraries': libraries,
+                'define_macros': define_macros,
+                'undef_macros': undef_macros,
+                'extra_objects': extra_objects,
+                'f2py_options': f2py_flags,
+                }
+
+    if sysinfo_flags:
+        from numpy.distutils.misc_util import dict_append
+        for n in sysinfo_flags:
+            i = get_info(n)
+            if not i:
+                outmess('No %s resources found in system'
+                        ' (try `f2py --help-link`)\n' % (repr(n)))
+            dict_append(ext_args, **i)
+
+    ext = Extension(**ext_args)
+    sys.argv = [sys.argv[0]] + setup_flags
+    sys.argv.extend(['build',
+                     '--build-temp', build_dir,
+                     '--build-base', build_dir,
+                     '--build-platlib', '.'])
+    if fc_flags:
+        sys.argv.extend(['config_fc'] + fc_flags)
+    if flib_flags:
+        sys.argv.extend(['build_ext'] + flib_flags)
+
+    setup(ext_modules=[ext])
+
+    if remove_build_dir and os.path.exists(build_dir):
+        import shutil
+        outmess('Removing build directory %s\n' % (build_dir))
+        shutil.rmtree(build_dir)
+
+
+def main():
+    if '--help-link' in sys.argv[1:]:
+        sys.argv.remove('--help-link')
+        from numpy.distutils.system_info import show_all
+        show_all()
+        return
+    if '-c' in sys.argv[1:]:
+        run_compile()
+    else:
+        run_main(sys.argv[1:])
+
+# if __name__ == "__main__":
+#    main()
+
+
+# EOF
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
new file mode 100644
index 0000000000..c7041fe25e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
@@ -0,0 +1,48 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import re
+
+from numpy.testing.utils import jiffies, memusage
+
+
+def cmdline():
+    m = re.compile(r'\A\d+\Z')
+    args = []
+    repeat = 1
+    for a in sys.argv[1:]:
+        if m.match(a):
+            repeat = eval(a)
+        else:
+            args.append(a)
+    f2py_opts = ' '.join(args)
+    return repeat, f2py_opts
+
+
+def run(runtest, test_functions, repeat=1):
+    l = [(t, repr(t.__doc__.split('\n')[1].strip())) for t in test_functions]
+    start_memusage = memusage()
+    diff_memusage = None
+    start_jiffies = jiffies()
+    i = 0
+    while i < repeat:
+        i += 1
+        for t, fname in l:
+            runtest(t)
+            if start_memusage is None:
+                continue
+            if diff_memusage is None:
+                diff_memusage = memusage() - start_memusage
+            else:
+                diff_memusage2 = memusage() - start_memusage
+                if diff_memusage2 != diff_memusage:
+                    print('memory usage change at step %i:' % i,
+                          diff_memusage2 - diff_memusage,
+                          fname)
+                    diff_memusage = diff_memusage2
+    current_memusage = memusage()
+    print('run', repeat * len(test_functions), 'tests',
+          'in %.2f seconds' % ((jiffies() - start_jiffies) / 100.0))
+    if start_memusage:
+        print('initial virtual memory size:', start_memusage, 'bytes')
+        print('current virtual memory size:', current_memusage, 'bytes')
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
new file mode 100644
index 0000000000..94a83e97d8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
@@ -0,0 +1,272 @@
+#!/usr/bin/env python2
+"""
+
+Build F90 module support for f2py2e.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/02/03 19:30:23 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.27 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+import numpy as np
+
+from . import capi_maps
+from . import func2subr
+from .crackfortran import undo_rmbadname, undo_rmbadname1
+
+# The eviroment provided by auxfuncs.py is needed for some calls to eval.
+# As the needed functions cannot be determined by static inspection of the
+# code, it is safest to use import * pending a major refactoring of f2py.
+from .auxfuncs import *
+
+options = {}
+
+
+def findf90modules(m):
+    if ismodule(m):
+        return [m]
+    if not hasbody(m):
+        return []
+    ret = []
+    for b in m['body']:
+        if ismodule(b):
+            ret.append(b)
+        else:
+            ret = ret + findf90modules(b)
+    return ret
+
+fgetdims1 = """\
+      external f2pysetdata
+      logical ns
+      integer r,i
+      integer(%d) s(*)
+      ns = .FALSE.
+      if (allocated(d)) then
+         do i=1,r
+            if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
+               ns = .TRUE.
+            end if
+         end do
+         if (ns) then
+            deallocate(d)
+         end if
+      end if
+      if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize
+
+fgetdims2 = """\
+      end if
+      if (allocated(d)) then
+         do i=1,r
+            s(i) = size(d,i)
+         end do
+      end if
+      flag = 1
+      call f2pysetdata(d,allocated(d))"""
+
+fgetdims2_sa = """\
+      end if
+      if (allocated(d)) then
+         do i=1,r
+            s(i) = size(d,i)
+         end do
+         !s(r) must be equal to len(d(1))
+      end if
+      flag = 2
+      call f2pysetdata(d,allocated(d))"""
+
+
+def buildhooks(pymod):
+    global fgetdims1, fgetdims2
+    from . import rules
+    ret = {'f90modhooks': [], 'initf90modhooks': [], 'body': [],
+           'need': ['F_FUNC', 'arrayobject.h'],
+           'separatorsfor': {'includes0': '\n', 'includes': '\n'},
+           'docs': ['"Fortran 90/95 modules:\\n"'],
+           'latexdoc': []}
+    fhooks = ['']
+
+    def fadd(line, s=fhooks):
+        s[0] = '%s\n      %s' % (s[0], line)
+    doc = ['']
+
+    def dadd(line, s=doc):
+        s[0] = '%s\n%s' % (s[0], line)
+    for m in findf90modules(pymod):
+        sargs, fargs, efargs, modobjs, notvars, onlyvars = [], [], [], [], [
+            m['name']], []
+        sargsp = []
+        ifargs = []
+        mfargs = []
+        if hasbody(m):
+            for b in m['body']:
+                notvars.append(b['name'])
+        for n in m['vars'].keys():
+            var = m['vars'][n]
+            if (n not in notvars) and (not l_or(isintent_hide, isprivate)(var)):
+                onlyvars.append(n)
+                mfargs.append(n)
+        outmess('\t\tConstructing F90 module support for "%s"...\n' %
+                (m['name']))
+        if onlyvars:
+            outmess('\t\t  Variables: %s\n' % (' '.join(onlyvars)))
+        chooks = ['']
+
+        def cadd(line, s=chooks):
+            s[0] = '%s\n%s' % (s[0], line)
+        ihooks = ['']
+
+        def iadd(line, s=ihooks):
+            s[0] = '%s\n%s' % (s[0], line)
+
+        vrd = capi_maps.modsign2map(m)
+        cadd('static FortranDataDef f2py_%s_def[] = {' % (m['name']))
+        dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n' % (m['name']))
+        if hasnote(m):
+            note = m['note']
+            if isinstance(note, list):
+                note = '\n'.join(note)
+            dadd(note)
+        if onlyvars:
+            dadd('\\begin{description}')
+        for n in onlyvars:
+            var = m['vars'][n]
+            modobjs.append(n)
+            ct = capi_maps.getctype(var)
+            at = capi_maps.c2capi_map[ct]
+            dm = capi_maps.getarrdims(n, var)
+            dms = dm['dims'].replace('*', '-1').strip()
+            dms = dms.replace(':', '-1').strip()
+            if not dms:
+                dms = '-1'
+            use_fgetdims2 = fgetdims2
+            if isstringarray(var):
+                if 'charselector' in var and 'len' in var['charselector']:
+                    cadd('\t{"%s",%s,{{%s,%s}},%s},'
+                         % (undo_rmbadname1(n), dm['rank'], dms, var['charselector']['len'], at))
+                    use_fgetdims2 = fgetdims2_sa
+                else:
+                    cadd('\t{"%s",%s,{{%s}},%s},' %
+                         (undo_rmbadname1(n), dm['rank'], dms, at))
+            else:
+                cadd('\t{"%s",%s,{{%s}},%s},' %
+                     (undo_rmbadname1(n), dm['rank'], dms, at))
+            dadd('\\item[]{{}\\verb@%s@{}}' %
+                 (capi_maps.getarrdocsign(n, var)))
+            if hasnote(var):
+                note = var['note']
+                if isinstance(note, list):
+                    note = '\n'.join(note)
+                dadd('--- %s' % (note))
+            if isallocatable(var):
+                fargs.append('f2py_%s_getdims_%s' % (m['name'], n))
+                efargs.append(fargs[-1])
+                sargs.append(
+                    'void (*%s)(int*,int*,void(*)(char*,int*),int*)' % (n))
+                sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)')
+                iadd('\tf2py_%s_def[i_f2py++].func = %s;' % (m['name'], n))
+                fadd('subroutine %s(r,s,f2pysetdata,flag)' % (fargs[-1]))
+                fadd('use %s, only: d => %s\n' %
+                     (m['name'], undo_rmbadname1(n)))
+                fadd('integer flag\n')
+                fhooks[0] = fhooks[0] + fgetdims1
+                dms = eval('range(1,%s+1)' % (dm['rank']))
+                fadd(' allocate(d(%s))\n' %
+                     (','.join(['s(%s)' % i for i in dms])))
+                fhooks[0] = fhooks[0] + use_fgetdims2
+                fadd('end subroutine %s' % (fargs[-1]))
+            else:
+                fargs.append(n)
+                sargs.append('char *%s' % (n))
+                sargsp.append('char*')
+                iadd('\tf2py_%s_def[i_f2py++].data = %s;' % (m['name'], n))
+        if onlyvars:
+            dadd('\\end{description}')
+        if hasbody(m):
+            for b in m['body']:
+                if not isroutine(b):
+                    print('Skipping', b['block'], b['name'])
+                    continue
+                modobjs.append('%s()' % (b['name']))
+                b['modulename'] = m['name']
+                api, wrap = rules.buildapi(b)
+                if isfunction(b):
+                    fhooks[0] = fhooks[0] + wrap
+                    fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
+                    ifargs.append(func2subr.createfuncwrapper(b, signature=1))
+                else:
+                    if wrap:
+                        fhooks[0] = fhooks[0] + wrap
+                        fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
+                        ifargs.append(
+                            func2subr.createsubrwrapper(b, signature=1))
+                    else:
+                        fargs.append(b['name'])
+                        mfargs.append(fargs[-1])
+                api['externroutines'] = []
+                ar = applyrules(api, vrd)
+                ar['docs'] = []
+                ar['docshort'] = []
+                ret = dictappend(ret, ar)
+                cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},' %
+                     (b['name'], m['name'], b['name'], m['name'], b['name']))
+                sargs.append('char *%s' % (b['name']))
+                sargsp.append('char *')
+                iadd('\tf2py_%s_def[i_f2py++].data = %s;' %
+                     (m['name'], b['name']))
+        cadd('\t{NULL}\n};\n')
+        iadd('}')
+        ihooks[0] = 'static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s' % (
+            m['name'], ','.join(sargs), ihooks[0])
+        if '_' in m['name']:
+            F_FUNC = 'F_FUNC_US'
+        else:
+            F_FUNC = 'F_FUNC'
+        iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'
+             % (F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp)))
+        iadd('static void f2py_init_%s(void) {' % (m['name']))
+        iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
+             % (F_FUNC, m['name'], m['name'].upper(), m['name']))
+        iadd('}\n')
+        ret['f90modhooks'] = ret['f90modhooks'] + chooks + ihooks
+        ret['initf90modhooks'] = ['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
+            m['name'], m['name'], m['name'])] + ret['initf90modhooks']
+        fadd('')
+        fadd('subroutine f2pyinit%s(f2pysetupfunc)' % (m['name']))
+        if mfargs:
+            for a in undo_rmbadname(mfargs):
+                fadd('use %s, only : %s' % (m['name'], a))
+        if ifargs:
+            fadd(' '.join(['interface'] + ifargs))
+            fadd('end interface')
+        fadd('external f2pysetupfunc')
+        if efargs:
+            for a in undo_rmbadname(efargs):
+                fadd('external %s' % (a))
+        fadd('call f2pysetupfunc(%s)' % (','.join(undo_rmbadname(fargs))))
+        fadd('end subroutine f2pyinit%s\n' % (m['name']))
+
+        dadd('\n'.join(ret['latexdoc']).replace(
+            r'\subsection{', r'\subsubsection{'))
+
+        ret['latexdoc'] = []
+        ret['docs'].append('"\t%s --- %s"' % (m['name'],
+                                              ','.join(undo_rmbadname(modobjs))))
+
+    ret['routine_defs'] = ''
+    ret['doc'] = []
+    ret['docshort'] = []
+    ret['latexdoc'] = doc[0]
+    if len(ret['docs']) <= 1:
+        ret['docs'] = ''
+    return ret, fhooks[0]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.py
new file mode 100644
index 0000000000..bb690bb419
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.py
@@ -0,0 +1,299 @@
+#!/usr/bin/env python2
+"""
+
+Rules for building C/API module with f2py2e.
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2004/11/26 11:13:06 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.16 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+import copy
+
+from .auxfuncs import (
+    getfortranname, isexternal, isfunction, isfunction_wrap, isintent_in,
+    isintent_out, islogicalfunction, ismoduleroutine, isscalar,
+    issubroutine, issubroutine_wrap, outmess, show
+)
+
+
+def var2fixfortran(vars, a, fa=None, f90mode=None):
+    if fa is None:
+        fa = a
+    if a not in vars:
+        show(vars)
+        outmess('var2fixfortran: No definition for argument "%s".\n' % a)
+        return ''
+    if 'typespec' not in vars[a]:
+        show(vars[a])
+        outmess('var2fixfortran: No typespec for argument "%s".\n' % a)
+        return ''
+    vardef = vars[a]['typespec']
+    if vardef == 'type' and 'typename' in vars[a]:
+        vardef = '%s(%s)' % (vardef, vars[a]['typename'])
+    selector = {}
+    lk = ''
+    if 'kindselector' in vars[a]:
+        selector = vars[a]['kindselector']
+        lk = 'kind'
+    elif 'charselector' in vars[a]:
+        selector = vars[a]['charselector']
+        lk = 'len'
+    if '*' in selector:
+        if f90mode:
+            if selector['*'] in ['*', ':', '(*)']:
+                vardef = '%s(len=*)' % (vardef)
+            else:
+                vardef = '%s(%s=%s)' % (vardef, lk, selector['*'])
+        else:
+            if selector['*'] in ['*', ':']:
+                vardef = '%s*(%s)' % (vardef, selector['*'])
+            else:
+                vardef = '%s*%s' % (vardef, selector['*'])
+    else:
+        if 'len' in selector:
+            vardef = '%s(len=%s' % (vardef, selector['len'])
+            if 'kind' in selector:
+                vardef = '%s,kind=%s)' % (vardef, selector['kind'])
+            else:
+                vardef = '%s)' % (vardef)
+        elif 'kind' in selector:
+            vardef = '%s(kind=%s)' % (vardef, selector['kind'])
+
+    vardef = '%s %s' % (vardef, fa)
+    if 'dimension' in vars[a]:
+        vardef = '%s(%s)' % (vardef, ','.join(vars[a]['dimension']))
+    return vardef
+
+
+def createfuncwrapper(rout, signature=0):
+    assert isfunction(rout)
+
+    extra_args = []
+    vars = rout['vars']
+    for a in rout['args']:
+        v = rout['vars'][a]
+        for i, d in enumerate(v.get('dimension', [])):
+            if d == ':':
+                dn = 'f2py_%s_d%s' % (a, i)
+                dv = dict(typespec='integer', intent=['hide'])
+                dv['='] = 'shape(%s, %s)' % (a, i)
+                extra_args.append(dn)
+                vars[dn] = dv
+                v['dimension'][i] = dn
+    rout['args'].extend(extra_args)
+    need_interface = bool(extra_args)
+
+    ret = ['']
+
+    def add(line, ret=ret):
+        ret[0] = '%s\n      %s' % (ret[0], line)
+    name = rout['name']
+    fortranname = getfortranname(rout)
+    f90mode = ismoduleroutine(rout)
+    newname = '%sf2pywrap' % (name)
+
+    if newname not in vars:
+        vars[newname] = vars[name]
+        args = [newname] + rout['args'][1:]
+    else:
+        args = [newname] + rout['args']
+
+    l = var2fixfortran(vars, name, newname, f90mode)
+    if l[:13] == 'character*(*)':
+        if f90mode:
+            l = 'character(len=10)' + l[13:]
+        else:
+            l = 'character*10' + l[13:]
+        charselect = vars[name]['charselector']
+        if charselect.get('*', '') == '(*)':
+            charselect['*'] = '10'
+    sargs = ', '.join(args)
+    if f90mode:
+        add('subroutine f2pywrap_%s_%s (%s)' %
+            (rout['modulename'], name, sargs))
+        if not signature:
+            add('use %s, only : %s' % (rout['modulename'], fortranname))
+    else:
+        add('subroutine f2pywrap%s (%s)' % (name, sargs))
+        if not need_interface:
+            add('external %s' % (fortranname))
+            l = l + ', ' + fortranname
+    if need_interface:
+        for line in rout['saved_interface'].split('\n'):
+            if line.lstrip().startswith('use '):
+                add(line)
+
+    args = args[1:]
+    dumped_args = []
+    for a in args:
+        if isexternal(vars[a]):
+            add('external %s' % (a))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isscalar(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isintent_in(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        add(var2fixfortran(vars, a, f90mode=f90mode))
+
+    add(l)
+
+    if need_interface:
+        if f90mode:
+            # f90 module already defines needed interface
+            pass
+        else:
+            add('interface')
+            add(rout['saved_interface'].lstrip())
+            add('end interface')
+
+    sargs = ', '.join([a for a in args if a not in extra_args])
+
+    if not signature:
+        if islogicalfunction(rout):
+            add('%s = .not.(.not.%s(%s))' % (newname, fortranname, sargs))
+        else:
+            add('%s = %s(%s)' % (newname, fortranname, sargs))
+    if f90mode:
+        add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
+    else:
+        add('end')
+    return ret[0]
+
+
+def createsubrwrapper(rout, signature=0):
+    assert issubroutine(rout)
+
+    extra_args = []
+    vars = rout['vars']
+    for a in rout['args']:
+        v = rout['vars'][a]
+        for i, d in enumerate(v.get('dimension', [])):
+            if d == ':':
+                dn = 'f2py_%s_d%s' % (a, i)
+                dv = dict(typespec='integer', intent=['hide'])
+                dv['='] = 'shape(%s, %s)' % (a, i)
+                extra_args.append(dn)
+                vars[dn] = dv
+                v['dimension'][i] = dn
+    rout['args'].extend(extra_args)
+    need_interface = bool(extra_args)
+
+    ret = ['']
+
+    def add(line, ret=ret):
+        ret[0] = '%s\n      %s' % (ret[0], line)
+    name = rout['name']
+    fortranname = getfortranname(rout)
+    f90mode = ismoduleroutine(rout)
+
+    args = rout['args']
+
+    sargs = ', '.join(args)
+    if f90mode:
+        add('subroutine f2pywrap_%s_%s (%s)' %
+            (rout['modulename'], name, sargs))
+        if not signature:
+            add('use %s, only : %s' % (rout['modulename'], fortranname))
+    else:
+        add('subroutine f2pywrap%s (%s)' % (name, sargs))
+        if not need_interface:
+            add('external %s' % (fortranname))
+
+    if need_interface:
+        for line in rout['saved_interface'].split('\n'):
+            if line.lstrip().startswith('use '):
+                add(line)
+
+    dumped_args = []
+    for a in args:
+        if isexternal(vars[a]):
+            add('external %s' % (a))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        if isscalar(vars[a]):
+            add(var2fixfortran(vars, a, f90mode=f90mode))
+            dumped_args.append(a)
+    for a in args:
+        if a in dumped_args:
+            continue
+        add(var2fixfortran(vars, a, f90mode=f90mode))
+
+    if need_interface:
+        if f90mode:
+            # f90 module already defines needed interface
+            pass
+        else:
+            add('interface')
+            add(rout['saved_interface'].lstrip())
+            add('end interface')
+
+    sargs = ', '.join([a for a in args if a not in extra_args])
+
+    if not signature:
+        add('call %s(%s)' % (fortranname, sargs))
+    if f90mode:
+        add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
+    else:
+        add('end')
+    return ret[0]
+
+
+def assubr(rout):
+    if isfunction_wrap(rout):
+        fortranname = getfortranname(rout)
+        name = rout['name']
+        outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n' % (
+            name, fortranname))
+        rout = copy.copy(rout)
+        fname = name
+        rname = fname
+        if 'result' in rout:
+            rname = rout['result']
+            rout['vars'][fname] = rout['vars'][rname]
+        fvar = rout['vars'][fname]
+        if not isintent_out(fvar):
+            if 'intent' not in fvar:
+                fvar['intent'] = []
+            fvar['intent'].append('out')
+            flag = 1
+            for i in fvar['intent']:
+                if i.startswith('out='):
+                    flag = 0
+                    break
+            if flag:
+                fvar['intent'].append('out=%s' % (rname))
+        rout['args'][:] = [fname] + rout['args']
+        return rout, createfuncwrapper(rout)
+    if issubroutine_wrap(rout):
+        fortranname = getfortranname(rout)
+        name = rout['name']
+        outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n' % (
+            name, fortranname))
+        rout = copy.copy(rout)
+        return rout, createsubrwrapper(rout)
+    return rout, ''
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/info.py
new file mode 100644
index 0000000000..c895c5de28
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/info.py
@@ -0,0 +1,6 @@
+"""Fortran to Python Interface Generator.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+postpone_import = True
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/rules.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/rules.py
new file mode 100644
index 0000000000..09b2a597a3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/rules.py
@@ -0,0 +1,1475 @@
+#!/usr/bin/env python2
+"""
+
+Rules for building C/API module with f2py2e.
+
+Here is a skeleton of a new wrapper function (13Dec2001):
+
+wrapper_function(args)
+  declarations
+  get_python_arguments, say, `a' and `b'
+
+  get_a_from_python
+  if (successful) {
+
+    get_b_from_python
+    if (successful) {
+
+      callfortran
+      if (succesful) {
+
+        put_a_to_python
+        if (succesful) {
+
+          put_b_to_python
+          if (succesful) {
+
+            buildvalue = ...
+
+          }
+
+        }
+
+      }
+
+    }
+    cleanup_b
+
+  }
+  cleanup_a
+
+  return buildvalue
+
+Copyright 1999,2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2005/08/30 08:58:42 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.129 $"[10:-1]
+
+from . import __version__
+f2py_version = __version__.version
+
+import os
+import time
+import copy
+
+from .auxfuncs import (
+    applyrules, debugcapi, dictappend, errmess, gentitle, getargs2,
+    hascallstatement, hasexternals, hasinitvalue, hasnote, hasresultnote,
+    isarray, isarrayofstrings, iscomplex, iscomplexarray,
+    iscomplexfunction, iscomplexfunction_warn, isdummyroutine, isexternal,
+    isfunction, isfunction_wrap, isint1array, isintent_aux, isintent_c,
+    isintent_callback, isintent_copy, isintent_hide, isintent_inout,
+    isintent_nothide, isintent_out, isintent_overwrite, islogical,
+    islong_complex, islong_double, islong_doublefunction, islong_long,
+    islong_longfunction, ismoduleroutine, isoptional, isrequired, isscalar,
+    issigned_long_longarray, isstring, isstringarray, isstringfunction,
+    issubroutine, issubroutine_wrap, isthreadsafe, isunsigned,
+    isunsigned_char, isunsigned_chararray, isunsigned_long_long,
+    isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray,
+    l_and, l_not, l_or, outmess, replace, stripcomma,
+)
+
+from . import capi_maps
+from . import cfuncs
+from . import common_rules
+from . import use_rules
+from . import f90mod_rules
+from . import func2subr
+
+options = {}
+sepdict = {}
+#for k in ['need_cfuncs']: sepdict[k]=','
+for k in ['decl',
+          'frompyobj',
+          'cleanupfrompyobj',
+          'topyarr', 'method',
+          'pyobjfrom', 'closepyobjfrom',
+          'freemem',
+          'userincludes',
+          'includes0', 'includes', 'typedefs', 'typedefs_generated',
+          'cppmacros', 'cfuncs', 'callbacks',
+          'latexdoc',
+          'restdoc',
+          'routine_defs', 'externroutines',
+          'initf2pywraphooks',
+          'commonhooks', 'initcommonhooks',
+          'f90modhooks', 'initf90modhooks']:
+    sepdict[k] = '\n'
+
+#################### Rules for C/API module #################
+
+module_rules = {
+    'modulebody': """\
+/* File: #modulename#module.c
+ * This file is auto-generated with f2py (version:#f2py_version#).
+ * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
+ * written by Pearu Peterson <pearu@cens.ioc.ee>.
+ * See http://cens.ioc.ee/projects/f2py2e/
+ * Generation date: """ + time.asctime(time.localtime(time.time())) + """
+ * $R""" + """evision:$
+ * $D""" + """ate:$
+ * Do not edit this file directly unless you know what you are doing!!!
+ */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+""" + gentitle("See f2py2e/cfuncs.py: includes") + """
+#includes#
+#includes0#
+
+""" + gentitle("See f2py2e/rules.py: mod_rules['modulebody']") + """
+static PyObject *#modulename#_error;
+static PyObject *#modulename#_module;
+
+""" + gentitle("See f2py2e/cfuncs.py: typedefs") + """
+#typedefs#
+
+""" + gentitle("See f2py2e/cfuncs.py: typedefs_generated") + """
+#typedefs_generated#
+
+""" + gentitle("See f2py2e/cfuncs.py: cppmacros") + """
+#cppmacros#
+
+""" + gentitle("See f2py2e/cfuncs.py: cfuncs") + """
+#cfuncs#
+
+""" + gentitle("See f2py2e/cfuncs.py: userincludes") + """
+#userincludes#
+
+""" + gentitle("See f2py2e/capi_rules.py: usercode") + """
+#usercode#
+
+/* See f2py2e/rules.py */
+#externroutines#
+
+""" + gentitle("See f2py2e/capi_rules.py: usercode1") + """
+#usercode1#
+
+""" + gentitle("See f2py2e/cb_rules.py: buildcallback") + """
+#callbacks#
+
+""" + gentitle("See f2py2e/rules.py: buildapi") + """
+#body#
+
+""" + gentitle("See f2py2e/f90mod_rules.py: buildhooks") + """
+#f90modhooks#
+
+""" + gentitle("See f2py2e/rules.py: module_rules['modulebody']") + """
+
+""" + gentitle("See f2py2e/common_rules.py: buildhooks") + """
+#commonhooks#
+
+""" + gentitle("See f2py2e/rules.py") + """
+
+static FortranDataDef f2py_routine_defs[] = {
+#routine_defs#
+\t{NULL}
+};
+
+static PyMethodDef f2py_module_methods[] = {
+#pymethoddef#
+\t{NULL,NULL}
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+static struct PyModuleDef moduledef = {
+\tPyModuleDef_HEAD_INIT,
+\t"#modulename#",
+\tNULL,
+\t-1,
+\tf2py_module_methods,
+\tNULL,
+\tNULL,
+\tNULL,
+\tNULL
+};
+#endif
+
+#if PY_VERSION_HEX >= 0x03000000
+#define RETVAL m
+PyMODINIT_FUNC PyInit_#modulename#(void) {
+#else
+#define RETVAL
+PyMODINIT_FUNC init#modulename#(void) {
+#endif
+\tint i;
+\tPyObject *m,*d, *s;
+#if PY_VERSION_HEX >= 0x03000000
+\tm = #modulename#_module = PyModule_Create(&moduledef);
+#else
+\tm = #modulename#_module = Py_InitModule(\"#modulename#\", f2py_module_methods);
+#endif
+\tPy_TYPE(&PyFortran_Type) = &PyType_Type;
+\timport_array();
+\tif (PyErr_Occurred())
+\t\t{PyErr_SetString(PyExc_ImportError, \"can't initialize module #modulename# (failed to import numpy)\"); return RETVAL;}
+\td = PyModule_GetDict(m);
+\ts = PyString_FromString(\"$R""" + """evision: $\");
+\tPyDict_SetItemString(d, \"__version__\", s);
+#if PY_VERSION_HEX >= 0x03000000
+\ts = PyUnicode_FromString(
+#else
+\ts = PyString_FromString(
+#endif
+\t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\");
+\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]));
+#initf2pywraphooks#
+#initf90modhooks#
+#initcommonhooks#
+#interface_usercode#
+
+#ifdef F2PY_REPORT_ATEXIT
+\tif (! PyErr_Occurred())
+\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\");
+#endif
+
+\treturn RETVAL;
+}
+#ifdef __cplusplus
+}
+#endif
+""",
+    'separatorsfor': {'latexdoc': '\n\n',
+                      'restdoc': '\n\n'},
+    'latexdoc': ['\\section{Module \\texttt{#texmodulename#}}\n',
+                 '#modnote#\n',
+                 '#latexdoc#'],
+    'restdoc': ['Module #modulename#\n' + '=' * 80,
+                '\n#restdoc#']
+}
+
+defmod_rules = [
+    {'body': '/*eof body*/',
+     'method': '/*eof method*/',
+     'externroutines': '/*eof externroutines*/',
+     'routine_defs': '/*eof routine_defs*/',
+     'initf90modhooks': '/*eof initf90modhooks*/',
+     'initf2pywraphooks': '/*eof initf2pywraphooks*/',
+     'initcommonhooks': '/*eof initcommonhooks*/',
+     'latexdoc': '',
+     'restdoc': '',
+     'modnote': {hasnote: '#note#', l_not(hasnote): ''},
+     }
+]
+
+routine_rules = {
+    'separatorsfor': sepdict,
+    'body': """
+#begintitle#
+static char doc_#apiname#[] = \"\\\n#docreturn##name#(#docsignatureshort#)\\n\\nWrapper for ``#name#``.\\\n\\n#docstrsigns#\";
+/* #declfortranroutine# */
+static PyObject *#apiname#(const PyObject *capi_self,
+                           PyObject *capi_args,
+                           PyObject *capi_keywds,
+                           #functype# (*f2py_func)(#callprotoargument#)) {
+\tPyObject * volatile capi_buildvalue = NULL;
+\tvolatile int f2py_success = 1;
+#decl#
+\tstatic char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL};
+#usercode#
+#routdebugenter#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_start_clock();
+#endif
+\tif (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\
+\t\t\"#argformat##keyformat##xaformat#:#pyname#\",\\
+\t\tcapi_kwlist#args_capi##keys_capi##keys_xa#))\n\t\treturn NULL;
+#frompyobj#
+/*end of frompyobj*/
+#ifdef F2PY_REPORT_ATEXIT
+f2py_start_call_clock();
+#endif
+#callfortranroutine#
+if (PyErr_Occurred())
+  f2py_success = 0;
+#ifdef F2PY_REPORT_ATEXIT
+f2py_stop_call_clock();
+#endif
+/*end of callfortranroutine*/
+\t\tif (f2py_success) {
+#pyobjfrom#
+/*end of pyobjfrom*/
+\t\tCFUNCSMESS(\"Building return value.\\n\");
+\t\tcapi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#);
+/*closepyobjfrom*/
+#closepyobjfrom#
+\t\t} /*if (f2py_success) after callfortranroutine*/
+/*cleanupfrompyobj*/
+#cleanupfrompyobj#
+\tif (capi_buildvalue == NULL) {
+#routdebugfailure#
+\t} else {
+#routdebugleave#
+\t}
+\tCFUNCSMESS(\"Freeing memory.\\n\");
+#freemem#
+#ifdef F2PY_REPORT_ATEXIT
+f2py_stop_clock();
+#endif
+\treturn capi_buildvalue;
+}
+#endtitle#
+""",
+    'routine_defs': '#routine_def#',
+    'initf2pywraphooks': '#initf2pywraphook#',
+    'externroutines': '#declfortranroutine#',
+    'doc': '#docreturn##name#(#docsignature#)',
+    'docshort': '#docreturn##name#(#docsignatureshort#)',
+    'docs': '"\t#docreturn##name#(#docsignature#)\\n"\n',
+    'need': ['arrayobject.h', 'CFUNCSMESS', 'MINMAX'],
+    'cppmacros': {debugcapi: '#define DEBUGCFUNCS'},
+    'latexdoc': ['\\subsection{Wrapper function \\texttt{#texname#}}\n',
+                 """
+\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)}
+#routnote#
+
+#latexdocstrsigns#
+"""],
+    'restdoc': ['Wrapped function ``#name#``\n' + '-' * 80,
+
+                ]
+}
+
+################## Rules for C/API function ##############
+
+rout_rules = [
+    {  # Init
+        'separatorsfor': {'callfortranroutine': '\n', 'routdebugenter': '\n', 'decl': '\n',
+                          'routdebugleave': '\n', 'routdebugfailure': '\n',
+                          'setjmpbuf': ' || ',
+                          'docstrreq': '\n', 'docstropt': '\n', 'docstrout': '\n',
+                          'docstrcbs': '\n', 'docstrsigns': '\\n"\n"',
+                          'latexdocstrsigns': '\n',
+                          'latexdocstrreq': '\n', 'latexdocstropt': '\n',
+                          'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
+                          },
+        'kwlist': '', 'kwlistopt': '', 'callfortran': '', 'callfortranappend': '',
+        'docsign': '', 'docsignopt': '', 'decl': '/*decl*/',
+        'freemem': '/*freemem*/',
+        'docsignshort': '', 'docsignoptshort': '',
+        'docstrsigns': '', 'latexdocstrsigns': '',
+        'docstrreq': '\\nParameters\\n----------',
+        'docstropt': '\\nOther Parameters\\n----------------',
+        'docstrout': '\\nReturns\\n-------',
+        'docstrcbs': '\\nNotes\\n-----\\nCall-back functions::\\n',
+        'latexdocstrreq': '\\noindent Required arguments:',
+        'latexdocstropt': '\\noindent Optional arguments:',
+        'latexdocstrout': '\\noindent Return objects:',
+        'latexdocstrcbs': '\\noindent Call-back functions:',
+        'args_capi': '', 'keys_capi': '', 'functype': '',
+        'frompyobj': '/*frompyobj*/',
+        # this list will be reversed
+        'cleanupfrompyobj': ['/*end of cleanupfrompyobj*/'],
+        'pyobjfrom': '/*pyobjfrom*/',
+        # this list will be reversed
+        'closepyobjfrom': ['/*end of closepyobjfrom*/'],
+        'topyarr': '/*topyarr*/', 'routdebugleave': '/*routdebugleave*/',
+        'routdebugenter': '/*routdebugenter*/',
+        'routdebugfailure': '/*routdebugfailure*/',
+        'callfortranroutine': '/*callfortranroutine*/',
+        'argformat': '', 'keyformat': '', 'need_cfuncs': '',
+        'docreturn': '', 'return': '', 'returnformat': '', 'rformat': '',
+        'kwlistxa': '', 'keys_xa': '', 'xaformat': '', 'docsignxa': '', 'docsignxashort': '',
+        'initf2pywraphook': '',
+        'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
+    }, {
+        'apiname': 'f2py_rout_#modulename#_#name#',
+        'pyname': '#modulename#.#name#',
+        'decl': '',
+        '_check': l_not(ismoduleroutine)
+    }, {
+        'apiname': 'f2py_rout_#modulename#_#f90modulename#_#name#',
+        'pyname': '#modulename#.#f90modulename#.#name#',
+        'decl': '',
+        '_check': ismoduleroutine
+    }, {  # Subroutine
+        'functype': 'void',
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);',
+                               ismoduleroutine: '',
+                               isdummyroutine: ''
+                               },
+        'routine_def': {l_not(l_or(ismoduleroutine, isintent_c, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isdummyroutine): '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'need': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'F_FUNC'},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\t\tif (#setjmpbuf#) {
+\t\t\tf2py_success = 0;
+\t\t} else {"""},
+            {isthreadsafe: '\t\t\tPy_BEGIN_ALLOW_THREADS'},
+            {hascallstatement: '''\t\t\t\t#callstatement#;
+\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t\t\t\t(*f2py_func)(#callfortran#);'},
+            {isthreadsafe: '\t\t\tPy_END_ALLOW_THREADS'},
+            {hasexternals: """\t\t}"""}
+        ],
+        '_check': l_and(issubroutine, l_not(issubroutine_wrap)),
+    }, {  # Wrapped function
+        'functype': 'void',
+        'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
+                               isdummyroutine: '',
+                               },
+
+        'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
+    {
+      extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void);
+      PyObject* o = PyDict_GetItemString(d,"#name#");
+      PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+#if PY_VERSION_HEX >= 0x03000000
+      PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+#else
+      PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+#endif
+    }
+    '''},
+        'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t(*f2py_func)(#callfortran#);'},
+            {hascallstatement:
+                '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'}
+        ],
+        '_check': isfunction_wrap,
+    }, {  # Wrapped subroutine
+        'functype': 'void',
+        'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);',
+                               isdummyroutine: '',
+                               },
+
+        'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): '''
+    {
+      extern void #F_FUNC#(#name_lower#,#NAME#)(void);
+      PyObject* o = PyDict_GetItemString(d,"#name#");
+      PyObject_SetAttrString(o,"_cpointer", F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL));
+#if PY_VERSION_HEX >= 0x03000000
+      PyObject_SetAttrString(o,"__name__", PyUnicode_FromString("#name#"));
+#else
+      PyObject_SetAttrString(o,"__name__", PyString_FromString("#name#"));
+#endif
+    }
+    '''},
+        'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']},
+        'callfortranroutine': [
+            {debugcapi: [
+                """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]},
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t(*f2py_func)(#callfortran#);'},
+            {hascallstatement:
+                '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'}
+        ],
+        '_check': issubroutine_wrap,
+    }, {  # Function
+        'functype': '#ctype#',
+        'docreturn': {l_not(isintent_hide): '#rname#,'},
+        'docstrout': '#pydocsignout#',
+        'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                           {hasresultnote: '--- #resultnote#'}],
+        'callfortranroutine': [{l_and(debugcapi, isstringfunction): """\
+#ifdef USESCOMPAQFORTRAN
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\");
+#else
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
+#endif
+"""},
+                               {l_and(debugcapi, l_not(isstringfunction)): """\
+\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\");
+"""}
+                               ],
+        '_check': l_and(isfunction, l_not(isfunction_wrap))
+    }, {  # Scalar function
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern #ctype# #fortranname#(#callprotoargument#);',
+                               isdummyroutine: ''
+                               },
+        'routine_def': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},',
+                        },
+        'decl': [{iscomplexfunction_warn: '\t#ctype# #name#_return_value={0,0};',
+                  l_not(iscomplexfunction): '\t#ctype# #name#_return_value=0;'},
+                 {iscomplexfunction:
+                  '\tPyObject *#name#_return_value_capi = Py_None;'}
+                 ],
+        'callfortranroutine': [
+            {hasexternals: """\
+\tif (#setjmpbuf#) {
+\t\tf2py_success = 0;
+\t} else {"""},
+            {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'},
+            {hascallstatement: '''\t#callstatement#;
+/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/
+'''},
+            {l_not(l_or(hascallstatement, isdummyroutine))
+                   : '\t#name#_return_value = (*f2py_func)(#callfortran#);'},
+            {isthreadsafe: '\tPy_END_ALLOW_THREADS'},
+            {hasexternals: '\t}'},
+            {l_and(debugcapi, iscomplexfunction)
+                   : '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'},
+            {l_and(debugcapi, l_not(iscomplexfunction)): '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}],
+        'pyobjfrom': {iscomplexfunction: '\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'},
+        'need': [{l_not(isdummyroutine): 'F_FUNC'},
+                 {iscomplexfunction: 'pyobj_from_#ctype#1'},
+                 {islong_longfunction: 'long_long'},
+                 {islong_doublefunction: 'long_double'}],
+        'returnformat': {l_not(isintent_hide): '#rformat#'},
+        'return': {iscomplexfunction: ',#name#_return_value_capi',
+                   l_not(l_or(iscomplexfunction, isintent_hide)): ',#name#_return_value'},
+        '_check': l_and(isfunction, l_not(isstringfunction), l_not(isfunction_wrap))
+    }, {  # String function # in use for --no-wrap
+        'declfortranroutine': 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+        'routine_def': {l_not(l_or(ismoduleroutine, isintent_c)):
+                        '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},',
+                        l_and(l_not(ismoduleroutine), isintent_c):
+                        '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},'
+                        },
+        'decl': ['\t#ctype# #name#_return_value = NULL;',
+                 '\tint #name#_return_value_len = 0;'],
+        'callfortran':'#name#_return_value,#name#_return_value_len,',
+        'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
+                              '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
+                              '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
+                              '\t\tf2py_success = 0;',
+                              '\t} else {',
+                              "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';",
+                              '\t}',
+                              '\tif (f2py_success) {',
+                              {hasexternals: """\
+\t\tif (#setjmpbuf#) {
+\t\t\tf2py_success = 0;
+\t\t} else {"""},
+                              {isthreadsafe: '\t\tPy_BEGIN_ALLOW_THREADS'},
+                              """\
+#ifdef USESCOMPAQFORTRAN
+\t\t(*f2py_func)(#callcompaqfortran#);
+#else
+\t\t(*f2py_func)(#callfortran#);
+#endif
+""",
+                              {isthreadsafe: '\t\tPy_END_ALLOW_THREADS'},
+                              {hasexternals: '\t\t}'},
+                              {debugcapi:
+                                  '\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'},
+                              '\t} /* if (f2py_success) after (string)malloc */',
+                              ],
+        'returnformat': '#rformat#',
+        'return': ',#name#_return_value',
+        'freemem': '\tSTRINGFREE(#name#_return_value);',
+        'need': ['F_FUNC', '#ctype#', 'STRINGFREE'],
+        '_check':l_and(isstringfunction, l_not(isfunction_wrap))  # ???obsolete
+    },
+    {  # Debugging
+        'routdebugenter': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");',
+        'routdebugleave': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");',
+        'routdebugfailure': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");',
+        '_check': debugcapi
+    }
+]
+
+################ Rules for arguments ##################
+
+typedef_need_dict = {islong_long: 'long_long',
+                     islong_double: 'long_double',
+                     islong_complex: 'complex_long_double',
+                     isunsigned_char: 'unsigned_char',
+                     isunsigned_short: 'unsigned_short',
+                     isunsigned: 'unsigned',
+                     isunsigned_long_long: 'unsigned_long_long',
+                     isunsigned_chararray: 'unsigned_char',
+                     isunsigned_shortarray: 'unsigned_short',
+                     isunsigned_long_longarray: 'unsigned_long_long',
+                     issigned_long_longarray: 'long_long',
+                     }
+
+aux_rules = [
+    {
+        'separatorsfor': sepdict
+    },
+    {  # Common
+        'frompyobj': ['\t/* Processing auxiliary variable #varname# */',
+                      {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
+        'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
+        'need': typedef_need_dict,
+    },
+    # Scalars (not complex)
+    {  # Common
+        'decl': '\t#ctype# #varname# = 0;',
+        'need': {hasinitvalue: 'math.h'},
+        'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+    },
+    {
+        'return': ',#varname#',
+        'docstrout': '#pydocsignout#',
+        'docreturn': '#outvarname#,',
+        'returnformat': '#varrformat#',
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_out),
+    },
+    # Complex scalars
+    {  # Common
+        'decl': '\t#ctype# #varname#;',
+        'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
+        '_check': iscomplex
+    },
+    # String
+    {  # Common
+        'decl': ['\t#ctype# #varname# = NULL;',
+                 '\tint slen(#varname#);',
+                 ],
+        'need':['len..'],
+        '_check':isstring
+    },
+    # Array
+    {  # Common
+        'decl': ['\t#ctype# *#varname# = NULL;',
+                 '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
+                 '\tconst int #varname#_Rank = #rank#;',
+                 ],
+        'need':['len..', {hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
+        '_check': isarray
+    },
+    # Scalararray
+    {  # Common
+        '_check': l_and(isarray, l_not(iscomplexarray))
+    }, {  # Not hidden
+        '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
+    },
+    # Integer*1 array
+    {'need': '#ctype#',
+     '_check': isint1array,
+     '_depend': ''
+     },
+    # Integer*-1 array
+    {'need': '#ctype#',
+     '_check': isunsigned_chararray,
+     '_depend': ''
+     },
+    # Integer*-2 array
+    {'need': '#ctype#',
+     '_check': isunsigned_shortarray,
+     '_depend': ''
+     },
+    # Integer*-8 array
+    {'need': '#ctype#',
+     '_check': isunsigned_long_longarray,
+     '_depend': ''
+     },
+    # Complexarray
+    {'need': '#ctype#',
+     '_check': iscomplexarray,
+     '_depend': ''
+     },
+    # Stringarray
+    {
+        'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
+        'need': 'string',
+        '_check': isstringarray
+    }
+]
+
+arg_rules = [
+    {
+        'separatorsfor': sepdict
+    },
+    {  # Common
+        'frompyobj': ['\t/* Processing variable #varname# */',
+                      {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ],
+        'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */',
+        '_depend': '',
+        'need': typedef_need_dict,
+    },
+    # Doc signatures
+    {
+        'docstropt': {l_and(isoptional, isintent_nothide): '#pydocsign#'},
+        'docstrreq': {l_and(isrequired, isintent_nothide): '#pydocsign#'},
+        'docstrout': {isintent_out: '#pydocsignout#'},
+        'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
+                                                                 {hasnote: '--- #note#'}]},
+        'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
+                                          {l_and(hasnote, isintent_hide): '--- #note#',
+                                           l_and(hasnote, isintent_nothide): '--- See above.'}]},
+        'depend': ''
+    },
+    # Required/Optional arguments
+    {
+        'kwlist': '"#varname#",',
+        'docsign': '#varname#,',
+        '_check': l_and(isintent_nothide, l_not(isoptional))
+    },
+    {
+        'kwlistopt': '"#varname#",',
+        'docsignopt': '#varname#=#showinit#,',
+        'docsignoptshort': '#varname#,',
+        '_check': l_and(isintent_nothide, isoptional)
+    },
+    # Docstring/BuildValue
+    {
+        'docreturn': '#outvarname#,',
+        'returnformat': '#varrformat#',
+        '_check': isintent_out
+    },
+    # Externals (call-back functions)
+    {  # Common
+        'docsignxa': {isintent_nothide: '#varname#_extra_args=(),'},
+        'docsignxashort': {isintent_nothide: '#varname#_extra_args,'},
+        'docstropt': {isintent_nothide: '#varname#_extra_args : input tuple, optional\\n    Default: ()'},
+        'docstrcbs': '#cbdocstr#',
+        'latexdocstrcbs': '\\item[] #cblatexdocstr#',
+        'latexdocstropt': {isintent_nothide: '\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'},
+        'decl': ['\tPyObject *#varname#_capi = Py_None;',
+                 '\tPyTupleObject *#varname#_xa_capi = NULL;',
+                 '\tPyTupleObject *#varname#_args_capi = NULL;',
+                 '\tint #varname#_nofargs_capi = 0;',
+                 {l_not(isintent_callback):
+                  '\t#cbname#_typedef #varname#_cptr;'}
+                 ],
+        'kwlistxa': {isintent_nothide: '"#varname#_extra_args",'},
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'xaformat': {isintent_nothide: 'O!'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'keys_xa': ',&PyTuple_Type,&#varname#_xa_capi',
+        'setjmpbuf': '(setjmp(#cbname#_jmpbuf))',
+        'callfortran': {l_not(isintent_callback): '#varname#_cptr,'},
+        'need': ['#cbname#', 'setjmp.h'],
+        '_check':isexternal
+    },
+    {
+        'frompyobj': [{l_not(isintent_callback): """\
+if(F2PyCapsule_Check(#varname#_capi)) {
+  #varname#_cptr = F2PyCapsule_AsVoidPtr(#varname#_capi);
+} else {
+  #varname#_cptr = #cbname#;
+}
+"""}, {isintent_callback: """\
+if (#varname#_capi==Py_None) {
+  #varname#_capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\");
+  if (#varname#_capi) {
+    if (#varname#_xa_capi==NULL) {
+      if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) {
+        PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\");
+        if (capi_tmp)
+          #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
+        else
+          #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\");
+        if (#varname#_xa_capi==NULL) {
+          PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\");
+          return NULL;
+        }
+      }
+    }
+  }
+  if (#varname#_capi==NULL) {
+    PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\");
+    return NULL;
+  }
+}
+"""},
+            """\
+\t#varname#_nofargs_capi = #cbname#_nofargs;
+\tif (create_cb_arglist(#varname#_capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#cbname#_nofargs,&#varname#_args_capi,\"failed in processing argument list for call-back #varname#.\")) {
+\t\tjmp_buf #varname#_jmpbuf;""",
+            {debugcapi: ["""\
+\t\tfprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#cbname#_nofargs);
+\t\tCFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""",
+                         {l_not(isintent_callback): """\t\tfprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]},
+            """\
+\t\tCFUNCSMESS(\"Saving jmpbuf for `#varname#`.\\n\");
+\t\tSWAP(#varname#_capi,#cbname#_capi,PyObject);
+\t\tSWAP(#varname#_args_capi,#cbname#_args_capi,PyTupleObject);
+\t\tmemcpy(&#varname#_jmpbuf,&#cbname#_jmpbuf,sizeof(jmp_buf));""",
+        ],
+        'cleanupfrompyobj':
+        """\
+\t\tCFUNCSMESS(\"Restoring jmpbuf for `#varname#`.\\n\");
+\t\t#cbname#_capi = #varname#_capi;
+\t\tPy_DECREF(#cbname#_args_capi);
+\t\t#cbname#_args_capi = #varname#_args_capi;
+\t\t#cbname#_nofargs = #varname#_nofargs_capi;
+\t\tmemcpy(&#cbname#_jmpbuf,&#varname#_jmpbuf,sizeof(jmp_buf));
+\t}""",
+        'need': ['SWAP', 'create_cb_arglist'],
+        '_check':isexternal,
+        '_depend':''
+    },
+    # Scalars (not complex)
+    {  # Common
+        'decl': '\t#ctype# #varname# = 0;',
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
+        'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
+        'return': {isintent_out: ',#varname#'},
+        '_check': l_and(isscalar, l_not(iscomplex))
+    }, {
+        'need': {hasinitvalue: 'math.h'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'pyobjfrom': {isintent_inout: """\
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
+\tif (f2py_success) {"""},
+        'closepyobjfrom': {isintent_inout: "\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide)
+    }, {
+        'frompyobj': [
+            # hasinitvalue...
+            #   if pyobj is None:
+            #     varname = init
+            #   else
+            #     from_pyobj(varname)
+            #
+            # isoptional and noinitvalue...
+            #   if pyobj is not None:
+            #     from_pyobj(varname)
+            #   else:
+            #     varname is uninitialized
+            #
+            # ...
+            #   from_pyobj(varname)
+            #
+            {hasinitvalue: '\tif (#varname#_capi == Py_None) #varname# = #init#; else',
+             '_depend': ''},
+            {l_and(isoptional, l_not(hasinitvalue)): '\tif (#varname#_capi != Py_None)',
+             '_depend': ''},
+            {l_not(islogical): '''\
+\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");
+\tif (f2py_success) {'''},
+            {islogical: '''\
+\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi);
+\t\tf2py_success = 1;
+\tif (f2py_success) {'''},
+        ],
+        'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname#*/',
+        'need': {l_not(islogical): '#ctype#_from_pyobj'},
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide),
+        '_depend': ''
+    }, {  # Hidden
+        'frompyobj': {hasinitvalue: '\t#varname# = #init#;'},
+        'need': typedef_need_dict,
+        '_check': l_and(isscalar, l_not(iscomplex), isintent_hide),
+        '_depend': ''
+    }, {  # Common
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'},
+        '_check': l_and(isscalar, l_not(iscomplex)),
+        '_depend': ''
+    },
+    # Complex scalars
+    {  # Common
+        'decl': '\t#ctype# #varname#;',
+        'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'},
+        'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
+        'return': {isintent_out: ',#varname#_capi'},
+        '_check': iscomplex
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        'pyobjfrom': {isintent_inout: """\
+\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#);
+\t\tif (f2py_success) {"""},
+        'closepyobjfrom': {isintent_inout: "\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"},
+        '_check': l_and(iscomplex, isintent_nothide)
+    }, {
+        'frompyobj': [{hasinitvalue: '\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'},
+                      {l_and(isoptional, l_not(hasinitvalue))
+                             : '\tif (#varname#_capi != Py_None)'},
+                      '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");'
+                      '\n\tif (f2py_success) {'],
+        'cleanupfrompyobj': '\t}  /*if (f2py_success) of #varname# frompyobj*/',
+        'need': ['#ctype#_from_pyobj'],
+        '_check': l_and(iscomplex, isintent_nothide),
+        '_depend': ''
+    }, {  # Hidden
+        'decl': {isintent_out: '\tPyObject *#varname#_capi = Py_None;'},
+        '_check': l_and(iscomplex, isintent_hide)
+    }, {
+        'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'},
+        '_check': l_and(iscomplex, isintent_hide),
+        '_depend': ''
+    }, {  # Common
+        'pyobjfrom': {isintent_out: '\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'},
+        'need': ['pyobj_from_#ctype#1'],
+        '_check': iscomplex
+    }, {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'},
+        '_check': iscomplex,
+        '_depend': ''
+    },
+    # String
+    {  # Common
+        'decl': ['\t#ctype# #varname# = NULL;',
+                 '\tint slen(#varname#);',
+                 '\tPyObject *#varname#_capi = Py_None;'],
+        'callfortran':'#varname#,',
+        'callfortranappend':'slen(#varname#),',
+        'pyobjfrom':{debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+        'return': {isintent_out: ',#varname#'},
+        'need': ['len..'],  # 'STRINGFREE'],
+        '_check':isstring
+    }, {  # Common
+        'frompyobj': """\
+\tslen(#varname#) = #length#;
+\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\");
+\tif (f2py_success) {""",
+        'cleanupfrompyobj': """\
+\t\tSTRINGFREE(#varname#);
+\t}  /*if (f2py_success) of #varname#*/""",
+        'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE'],
+        '_check':isstring,
+        '_depend':''
+    }, {  # Not hidden
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        'pyobjfrom': {isintent_inout: '''\
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
+\tif (f2py_success) {'''},
+        'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
+        'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+        '_check': l_and(isstring, isintent_nothide)
+    }, {  # Hidden
+        '_check': l_and(isstring, isintent_hide)
+    }, {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+        '_check': isstring,
+        '_depend': ''
+    },
+    # Array
+    {  # Common
+        'decl': ['\t#ctype# *#varname# = NULL;',
+                 '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};',
+                 '\tconst int #varname#_Rank = #rank#;',
+                 '\tPyArrayObject *capi_#varname#_tmp = NULL;',
+                 '\tint capi_#varname#_intent = 0;',
+                 ],
+        'callfortran':'#varname#,',
+        'return':{isintent_out: ',capi_#varname#_tmp'},
+        'need': 'len..',
+        '_check': isarray
+    }, {  # intent(overwrite) array
+        'decl': '\tint capi_overwrite_#varname# = 1;',
+        'kwlistxa': '"overwrite_#varname#",',
+        'xaformat': 'i',
+        'keys_xa': ',&capi_overwrite_#varname#',
+        'docsignxa': 'overwrite_#varname#=1,',
+        'docsignxashort': 'overwrite_#varname#,',
+        'docstropt': 'overwrite_#varname# : input int, optional\\n    Default: 1',
+        '_check': l_and(isarray, isintent_overwrite),
+    }, {
+        'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
+        '_check': l_and(isarray, isintent_overwrite),
+        '_depend': '',
+    },
+    {  # intent(copy) array
+        'decl': '\tint capi_overwrite_#varname# = 0;',
+        'kwlistxa': '"overwrite_#varname#",',
+        'xaformat': 'i',
+        'keys_xa': ',&capi_overwrite_#varname#',
+        'docsignxa': 'overwrite_#varname#=0,',
+        'docsignxashort': 'overwrite_#varname#,',
+        'docstropt': 'overwrite_#varname# : input int, optional\\n    Default: 0',
+        '_check': l_and(isarray, isintent_copy),
+    }, {
+        'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);',
+        '_check': l_and(isarray, isintent_copy),
+        '_depend': '',
+    }, {
+        'need': [{hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}],
+        '_check': isarray,
+        '_depend': ''
+    }, {  # Not hidden
+        'decl': '\tPyObject *#varname#_capi = Py_None;',
+        'argformat': {isrequired: 'O'},
+        'keyformat': {isoptional: 'O'},
+        'args_capi': {isrequired: ',&#varname#_capi'},
+        'keys_capi': {isoptional: ',&#varname#_capi'},
+        '_check': l_and(isarray, isintent_nothide)
+    }, {
+        'frompyobj': ['\t#setdims#;',
+                      '\tcapi_#varname#_intent |= #intent#;',
+                      {isintent_hide:
+                       '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'},
+                      {isintent_nothide:
+                       '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'},
+                      """\
+\tif (capi_#varname#_tmp == NULL) {
+\t\tif (!PyErr_Occurred())
+\t\t\tPyErr_SetString(#modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" );
+\t} else {
+\t\t#varname# = (#ctype# *)(PyArray_DATA(capi_#varname#_tmp));
+""",
+                      {hasinitvalue: [
+                          {isintent_nothide:
+                              '\tif (#varname#_capi == Py_None) {'},
+                          {isintent_hide: '\t{'},
+                          {iscomplexarray: '\t\t#ctype# capi_c;'},
+                          """\
+\t\tint *_i,capi_i=0;
+\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\");
+\t\tif (initforcomb(PyArray_DIMS(capi_#varname#_tmp),PyArray_NDIM(capi_#varname#_tmp),1)) {
+\t\t\twhile ((_i = nextforcomb()))
+\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */
+\t\t} else {
+\t\t\tif (!PyErr_Occurred())
+\t\t\t\tPyErr_SetString(#modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\");
+\t\t\tf2py_success = 0;
+\t\t}
+\t}
+\tif (f2py_success) {"""]},
+                      ],
+        'cleanupfrompyobj': [  # note that this list will be reversed
+            '\t}  /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/',
+            {l_not(l_or(isintent_out, isintent_hide)): """\
+\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) {
+\t\tPy_XDECREF(capi_#varname#_tmp); }"""},
+            {l_and(isintent_hide, l_not(isintent_out))
+                   : """\t\tPy_XDECREF(capi_#varname#_tmp);"""},
+            {hasinitvalue: '\t}  /*if (f2py_success) of #varname# init*/'},
+        ],
+        '_check': isarray,
+        '_depend': ''
+    },
+    # Scalararray
+    {  # Common
+        '_check': l_and(isarray, l_not(iscomplexarray))
+    }, {  # Not hidden
+        '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide)
+    },
+    # Integer*1 array
+    {'need': '#ctype#',
+     '_check': isint1array,
+     '_depend': ''
+     },
+    # Integer*-1 array
+    {'need': '#ctype#',
+     '_check': isunsigned_chararray,
+     '_depend': ''
+     },
+    # Integer*-2 array
+    {'need': '#ctype#',
+     '_check': isunsigned_shortarray,
+     '_depend': ''
+     },
+    # Integer*-8 array
+    {'need': '#ctype#',
+     '_check': isunsigned_long_longarray,
+     '_depend': ''
+     },
+    # Complexarray
+    {'need': '#ctype#',
+     '_check': iscomplexarray,
+     '_depend': ''
+     },
+    # Stringarray
+    {
+        'callfortranappend': {isarrayofstrings: 'flen(#varname#),'},
+        'need': 'string',
+        '_check': isstringarray
+    }
+]
+
+################# Rules for checking ###############
+
+check_rules = [
+    {
+        'frompyobj': {debugcapi: '\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'},
+        'need': 'len..'
+    }, {
+        'frompyobj': '\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
+        'cleanupfrompyobj': '\t} /*CHECKSCALAR(#check#)*/',
+        'need': 'CHECKSCALAR',
+        '_check': l_and(isscalar, l_not(iscomplex)),
+        '_break': ''
+    }, {
+        'frompyobj': '\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {',
+        'cleanupfrompyobj': '\t} /*CHECKSTRING(#check#)*/',
+        'need': 'CHECKSTRING',
+        '_check': isstring,
+        '_break': ''
+    }, {
+        'need': 'CHECKARRAY',
+        'frompyobj': '\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {',
+        'cleanupfrompyobj': '\t} /*CHECKARRAY(#check#)*/',
+        '_check': isarray,
+        '_break': ''
+    }, {
+        'need': 'CHECKGENERIC',
+        'frompyobj': '\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {',
+        'cleanupfrompyobj': '\t} /*CHECKGENERIC(#check#)*/',
+    }
+]
+
+########## Applying the rules. No need to modify what follows #############
+
+#################### Build C/API module #######################
+
+
+def buildmodule(m, um):
+    """
+    Return
+    """
+    global f2py_version, options
+    outmess('\tBuilding module "%s"...\n' % (m['name']))
+    ret = {}
+    mod_rules = defmod_rules[:]
+    vrd = capi_maps.modsign2map(m)
+    rd = dictappend({'f2py_version': f2py_version}, vrd)
+    funcwrappers = []
+    funcwrappers2 = []  # F90 codes
+    for n in m['interfaced']:
+        nb = None
+        for bi in m['body']:
+            if not bi['block'] == 'interface':
+                errmess('buildmodule: Expected interface block. Skipping.\n')
+                continue
+            for b in bi['body']:
+                if b['name'] == n:
+                    nb = b
+                    break
+
+        if not nb:
+            errmess(
+                'buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n' % (n))
+            continue
+        nb_list = [nb]
+        if 'entry' in nb:
+            for k, a in nb['entry'].items():
+                nb1 = copy.deepcopy(nb)
+                del nb1['entry']
+                nb1['name'] = k
+                nb1['args'] = a
+                nb_list.append(nb1)
+        for nb in nb_list:
+            api, wrap = buildapi(nb)
+            if wrap:
+                if ismoduleroutine(nb):
+                    funcwrappers2.append(wrap)
+                else:
+                    funcwrappers.append(wrap)
+            ar = applyrules(api, vrd)
+            rd = dictappend(rd, ar)
+
+    # Construct COMMON block support
+    cr, wrap = common_rules.buildhooks(m)
+    if wrap:
+        funcwrappers.append(wrap)
+    ar = applyrules(cr, vrd)
+    rd = dictappend(rd, ar)
+
+    # Construct F90 module support
+    mr, wrap = f90mod_rules.buildhooks(m)
+    if wrap:
+        funcwrappers2.append(wrap)
+    ar = applyrules(mr, vrd)
+    rd = dictappend(rd, ar)
+
+    for u in um:
+        ar = use_rules.buildusevars(u, m['use'][u['name']])
+        rd = dictappend(rd, ar)
+
+    needs = cfuncs.get_needs()
+    code = {}
+    for n in needs.keys():
+        code[n] = []
+        for k in needs[n]:
+            c = ''
+            if k in cfuncs.includes0:
+                c = cfuncs.includes0[k]
+            elif k in cfuncs.includes:
+                c = cfuncs.includes[k]
+            elif k in cfuncs.userincludes:
+                c = cfuncs.userincludes[k]
+            elif k in cfuncs.typedefs:
+                c = cfuncs.typedefs[k]
+            elif k in cfuncs.typedefs_generated:
+                c = cfuncs.typedefs_generated[k]
+            elif k in cfuncs.cppmacros:
+                c = cfuncs.cppmacros[k]
+            elif k in cfuncs.cfuncs:
+                c = cfuncs.cfuncs[k]
+            elif k in cfuncs.callbacks:
+                c = cfuncs.callbacks[k]
+            elif k in cfuncs.f90modhooks:
+                c = cfuncs.f90modhooks[k]
+            elif k in cfuncs.commonhooks:
+                c = cfuncs.commonhooks[k]
+            else:
+                errmess('buildmodule: unknown need %s.\n' % (repr(k)))
+                continue
+            code[n].append(c)
+    mod_rules.append(code)
+    for r in mod_rules:
+        if ('_check' in r and r['_check'](m)) or ('_check' not in r):
+            ar = applyrules(r, vrd, m)
+            rd = dictappend(rd, ar)
+    ar = applyrules(module_rules, rd)
+
+    fn = os.path.join(options['buildpath'], vrd['coutput'])
+    ret['csrc'] = fn
+    f = open(fn, 'w')
+    f.write(ar['modulebody'].replace('\t', 2 * ' '))
+    f.close()
+    outmess('\tWrote C/API module "%s" to file "%s"\n' % (m['name'], fn))
+
+    if options['dorestdoc']:
+        fn = os.path.join(
+            options['buildpath'], vrd['modulename'] + 'module.rest')
+        f = open(fn, 'w')
+        f.write('.. -*- rest -*-\n')
+        f.write('\n'.join(ar['restdoc']))
+        f.close()
+        outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n' %
+                (options['buildpath'], vrd['modulename']))
+    if options['dolatexdoc']:
+        fn = os.path.join(
+            options['buildpath'], vrd['modulename'] + 'module.tex')
+        ret['ltx'] = fn
+        f = open(fn, 'w')
+        f.write(
+            '%% This file is auto-generated with f2py (version:%s)\n' % (f2py_version))
+        if 'shortlatex' not in options:
+            f.write(
+                '\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n')
+        f.write('\n'.join(ar['latexdoc']))
+        if 'shortlatex' not in options:
+            f.write('\\end{document}')
+        f.close()
+        outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n' %
+                (options['buildpath'], vrd['modulename']))
+    if funcwrappers:
+        wn = os.path.join(options['buildpath'], vrd['f2py_wrapper_output'])
+        ret['fsrc'] = wn
+        f = open(wn, 'w')
+        f.write('C     -*- fortran -*-\n')
+        f.write(
+            'C     This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
+        f.write(
+            'C     It contains Fortran 77 wrappers to fortran functions.\n')
+        lines = []
+        for l in ('\n\n'.join(funcwrappers) + '\n').split('\n'):
+            if l and l[0] == ' ':
+                while len(l) >= 66:
+                    lines.append(l[:66] + '\n     &')
+                    l = l[66:]
+                lines.append(l + '\n')
+            else:
+                lines.append(l + '\n')
+        lines = ''.join(lines).replace('\n     &\n', '\n')
+        f.write(lines)
+        f.close()
+        outmess('\tFortran 77 wrappers are saved to "%s"\n' % (wn))
+    if funcwrappers2:
+        wn = os.path.join(
+            options['buildpath'], '%s-f2pywrappers2.f90' % (vrd['modulename']))
+        ret['fsrc'] = wn
+        f = open(wn, 'w')
+        f.write('!     -*- f90 -*-\n')
+        f.write(
+            '!     This file is autogenerated with f2py (version:%s)\n' % (f2py_version))
+        f.write(
+            '!     It contains Fortran 90 wrappers to fortran functions.\n')
+        lines = []
+        for l in ('\n\n'.join(funcwrappers2) + '\n').split('\n'):
+            if len(l) > 72 and l[0] == ' ':
+                lines.append(l[:72] + '&\n     &')
+                l = l[72:]
+                while len(l) > 66:
+                    lines.append(l[:66] + '&\n     &')
+                    l = l[66:]
+                lines.append(l + '\n')
+            else:
+                lines.append(l + '\n')
+        lines = ''.join(lines).replace('\n     &\n', '\n')
+        f.write(lines)
+        f.close()
+        outmess('\tFortran 90 wrappers are saved to "%s"\n' % (wn))
+    return ret
+
+################## Build C/API function #############
+
+stnd = {1: 'st', 2: 'nd', 3: 'rd', 4: 'th', 5: 'th',
+        6: 'th', 7: 'th', 8: 'th', 9: 'th', 0: 'th'}
+
+
+def buildapi(rout):
+    rout, wrap = func2subr.assubr(rout)
+    args, depargs = getargs2(rout)
+    capi_maps.depargs = depargs
+    var = rout['vars']
+
+    if ismoduleroutine(rout):
+        outmess('\t\t\tConstructing wrapper function "%s.%s"...\n' %
+                (rout['modulename'], rout['name']))
+    else:
+        outmess('\t\tConstructing wrapper function "%s"...\n' % (rout['name']))
+    # Routine
+    vrd = capi_maps.routsign2map(rout)
+    rd = dictappend({}, vrd)
+    for r in rout_rules:
+        if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
+            ar = applyrules(r, vrd, rout)
+            rd = dictappend(rd, ar)
+
+    # Args
+    nth, nthk = 0, 0
+    savevrd = {}
+    for a in args:
+        vrd = capi_maps.sign2map(a, var[a])
+        if isintent_aux(var[a]):
+            _rules = aux_rules
+        else:
+            _rules = arg_rules
+            if not isintent_hide(var[a]):
+                if not isoptional(var[a]):
+                    nth = nth + 1
+                    vrd['nth'] = repr(nth) + stnd[nth % 10] + ' argument'
+                else:
+                    nthk = nthk + 1
+                    vrd['nth'] = repr(nthk) + stnd[nthk % 10] + ' keyword'
+            else:
+                vrd['nth'] = 'hidden'
+        savevrd[a] = vrd
+        for r in _rules:
+            if '_depend' in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+    for a in depargs:
+        if isintent_aux(var[a]):
+            _rules = aux_rules
+        else:
+            _rules = arg_rules
+        vrd = savevrd[a]
+        for r in _rules:
+            if '_depend' not in r:
+                continue
+            if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
+                ar = applyrules(r, vrd, var[a])
+                rd = dictappend(rd, ar)
+                if '_break' in r:
+                    break
+        if 'check' in var[a]:
+            for c in var[a]['check']:
+                vrd['check'] = c
+                ar = applyrules(check_rules, vrd, var[a])
+                rd = dictappend(rd, ar)
+    if isinstance(rd['cleanupfrompyobj'], list):
+        rd['cleanupfrompyobj'].reverse()
+    if isinstance(rd['closepyobjfrom'], list):
+        rd['closepyobjfrom'].reverse()
+    rd['docsignature'] = stripcomma(replace('#docsign##docsignopt##docsignxa#',
+                                            {'docsign': rd['docsign'],
+                                             'docsignopt': rd['docsignopt'],
+                                             'docsignxa': rd['docsignxa']}))
+    optargs = stripcomma(replace('#docsignopt##docsignxa#',
+                                 {'docsignxa': rd['docsignxashort'],
+                                  'docsignopt': rd['docsignoptshort']}
+                                 ))
+    if optargs == '':
+        rd['docsignatureshort'] = stripcomma(
+            replace('#docsign#', {'docsign': rd['docsign']}))
+    else:
+        rd['docsignatureshort'] = replace('#docsign#[#docsignopt#]',
+                                          {'docsign': rd['docsign'],
+                                           'docsignopt': optargs,
+                                           })
+    rd['latexdocsignatureshort'] = rd['docsignatureshort'].replace('_', '\\_')
+    rd['latexdocsignatureshort'] = rd[
+        'latexdocsignatureshort'].replace(',', ', ')
+    cfs = stripcomma(replace('#callfortran##callfortranappend#', {
+                     'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
+    if len(rd['callfortranappend']) > 1:
+        rd['callcompaqfortran'] = stripcomma(replace('#callfortran# 0,#callfortranappend#', {
+                                             'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']}))
+    else:
+        rd['callcompaqfortran'] = cfs
+    rd['callfortran'] = cfs
+    if isinstance(rd['docreturn'], list):
+        rd['docreturn'] = stripcomma(
+            replace('#docreturn#', {'docreturn': rd['docreturn']})) + ' = '
+    rd['docstrsigns'] = []
+    rd['latexdocstrsigns'] = []
+    for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
+        if k in rd and isinstance(rd[k], list):
+            rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
+        k = 'latex' + k
+        if k in rd and isinstance(rd[k], list):
+            rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
+                ['\\begin{description}'] + rd[k][1:] +\
+                ['\\end{description}']
+
+    # Workaround for Python 2.6, 2.6.1 bug: http://bugs.python.org/issue4720
+    if rd['keyformat'] or rd['xaformat']:
+        argformat = rd['argformat']
+        if isinstance(argformat, list):
+            argformat.append('|')
+        else:
+            assert isinstance(argformat, str), repr(
+                (argformat, type(argformat)))
+            rd['argformat'] += '|'
+
+    ar = applyrules(routine_rules, rd)
+    if ismoduleroutine(rout):
+        outmess('\t\t\t  %s\n' % (ar['docshort']))
+    else:
+        outmess('\t\t  %s\n' % (ar['docshort']))
+    return ar, wrap
+
+
+#################### EOF rules.py #######################
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/setup.py
new file mode 100644
index 0000000000..fb68ed5a8a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/setup.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python2
+"""
+setup.py for installing F2PY
+
+Usage:
+   python setup.py install
+
+Copyright 2001-2005 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@cens.ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Revision: 1.32 $
+$Date: 2005/01/30 17:22:14 $
+Pearu Peterson
+
+"""
+from __future__ import division, print_function
+
+__version__ = "$Id: setup.py,v 1.32 2005/01/30 17:22:14 pearu Exp $"
+
+import os
+import sys
+from distutils.dep_util import newer
+from numpy.distutils import log
+from numpy.distutils.core import setup
+from numpy.distutils.misc_util import Configuration
+
+from __version__ import version
+
+
+def _get_f2py_shebang():
+    """ Return shebang line for f2py script
+
+    If we are building a binary distribution format, then the shebang line
+    should be ``#!python`` rather than ``#!`` followed by the contents of
+    ``sys.executable``.
+    """
+    if set(('bdist_wheel', 'bdist_egg', 'bdist_wininst',
+            'bdist_rpm')).intersection(sys.argv):
+        return '#!python'
+    return '#!' + sys.executable
+
+
+def configuration(parent_package='', top_path=None):
+    config = Configuration('f2py', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    config.add_data_files('src/fortranobject.c',
+                          'src/fortranobject.h',
+                          )
+
+    config.make_svn_version_py()
+
+    def generate_f2py_py(build_dir):
+        f2py_exe = 'f2py' + os.path.basename(sys.executable)[6:]
+        if f2py_exe[-4:] == '.exe':
+            f2py_exe = f2py_exe[:-4] + '.py'
+        if 'bdist_wininst' in sys.argv and f2py_exe[-3:] != '.py':
+            f2py_exe = f2py_exe + '.py'
+        target = os.path.join(build_dir, f2py_exe)
+        if newer(__file__, target):
+            log.info('Creating %s', target)
+            f = open(target, 'w')
+            f.write(_get_f2py_shebang() + '\n')
+            mainloc = os.path.join(os.path.dirname(__file__), "__main__.py")
+            with open(mainloc) as mf:
+                f.write(mf.read())
+            f.close()
+        return target
+
+    config.add_scripts(generate_f2py_py)
+
+    log.info('F2PY Version %s', config.get_version())
+
+    return config
+
+if __name__ == "__main__":
+
+    config = configuration(top_path='')
+    print('F2PY Version', version)
+    config = config.todict()
+
+    config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\
+                             "/F2PY-2-latest.tar.gz"
+    config['classifiers'] = [
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'Intended Audience :: Science/Research',
+        'License :: OSI Approved :: NumPy License',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Programming Language :: C',
+        'Programming Language :: Fortran',
+        'Programming Language :: Python',
+        'Topic :: Scientific/Engineering',
+        'Topic :: Software Development :: Code Generators',
+    ]
+    setup(version=version,
+          description="F2PY - Fortran to Python Interface Generaton",
+          author="Pearu Peterson",
+          author_email="pearu@cens.ioc.ee",
+          maintainer="Pearu Peterson",
+          maintainer_email="pearu@cens.ioc.ee",
+          license="BSD",
+          platforms="Unix, Windows (mingw|cygwin), Mac OSX",
+          long_description="""\
+The Fortran to Python Interface Generator, or F2PY for short, is a
+command line tool (f2py) for generating Python C/API modules for
+wrapping Fortran 77/90/95 subroutines, accessing common blocks from
+Python, and calling Python functions from Fortran (call-backs).
+Interfacing subroutines/data from Fortran 90/95 modules is supported.""",
+          url="http://cens.ioc.ee/projects/f2py2e/",
+          keywords=['Fortran', 'f2py'],
+          **config)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
new file mode 100644
index 0000000000..9024dd5b34
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
@@ -0,0 +1,1037 @@
+#define FORTRANOBJECT_C
+#include "fortranobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+  This file implements: FortranObject, array_from_pyobj, copy_ND_array
+
+  Author: Pearu Peterson <pearu@cens.ioc.ee>
+  $Revision: 1.52 $
+  $Date: 2005/07/11 07:44:20 $
+*/
+
+int
+F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj)
+{
+    if (obj==NULL) {
+        fprintf(stderr, "Error loading %s\n", name);
+        if (PyErr_Occurred()) {
+            PyErr_Print();
+            PyErr_Clear();
+        }
+        return -1;
+    }
+    return PyDict_SetItemString(dict, name, obj);
+}
+
+/************************* FortranObject *******************************/
+
+typedef PyObject *(*fortranfunc)(PyObject *,PyObject *,PyObject *,void *);
+
+PyObject *
+PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) {
+    int i;
+    PyFortranObject *fp = NULL;
+    PyObject *v = NULL;
+    if (init!=NULL)                           /* Initialize F90 module objects */
+        (*(init))();
+    if ((fp = PyObject_New(PyFortranObject, &PyFortran_Type))==NULL) return NULL;
+    if ((fp->dict = PyDict_New())==NULL) return NULL;
+    fp->len = 0;
+    while (defs[fp->len].name != NULL) fp->len++;
+    if (fp->len == 0) goto fail;
+    fp->defs = defs;
+    for (i=0;i<fp->len;i++)
+        if (fp->defs[i].rank == -1) {                      /* Is Fortran routine */
+            v = PyFortranObject_NewAsAttr(&(fp->defs[i]));
+            if (v==NULL) return NULL;
+            PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+        } else
+            if ((fp->defs[i].data)!=NULL) { /* Is Fortran variable or array (not allocatable) */
+                if (fp->defs[i].type == NPY_STRING) {
+                    int n = fp->defs[i].rank-1;
+                    v = PyArray_New(&PyArray_Type, n, fp->defs[i].dims.d,
+                                    NPY_STRING, NULL, fp->defs[i].data, fp->defs[i].dims.d[n],
+                                    NPY_ARRAY_FARRAY, NULL);
+                }
+                else {
+                    v = PyArray_New(&PyArray_Type, fp->defs[i].rank, fp->defs[i].dims.d,
+                                    fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY,
+                                    NULL);
+                }
+                if (v==NULL) return NULL;
+                PyDict_SetItemString(fp->dict,fp->defs[i].name,v);
+            }
+    Py_XDECREF(v);
+    return (PyObject *)fp;
+ fail:
+    Py_XDECREF(v);
+    return NULL;
+}
+
+PyObject *
+PyFortranObject_NewAsAttr(FortranDataDef* defs) { /* used for calling F90 module routines */
+    PyFortranObject *fp = NULL;
+    fp = PyObject_New(PyFortranObject, &PyFortran_Type);
+    if (fp == NULL) return NULL;
+    if ((fp->dict = PyDict_New())==NULL) return NULL;
+    fp->len = 1;
+    fp->defs = defs;
+    return (PyObject *)fp;
+}
+
+/* Fortran methods */
+
+static void
+fortran_dealloc(PyFortranObject *fp) {
+    Py_XDECREF(fp->dict);
+    PyMem_Del(fp);
+}
+
+
+#if PY_VERSION_HEX >= 0x03000000
+#else
+static PyMethodDef fortran_methods[] = {
+    {NULL,          NULL}           /* sentinel */
+};
+#endif
+
+
+/* Returns number of bytes consumed from buf, or -1 on error. */
+static Py_ssize_t
+format_def(char *buf, Py_ssize_t size, FortranDataDef def)
+{
+    char *p = buf;
+    int i, n;
+
+    n = PyOS_snprintf(p, size, "array(%" NPY_INTP_FMT, def.dims.d[0]);
+    if (n < 0 || n >= size) {
+        return -1;
+    }
+    p += n;
+    size -= n;
+
+    for (i = 1; i < def.rank; i++) {
+        n = PyOS_snprintf(p, size, ",%" NPY_INTP_FMT, def.dims.d[i]);
+        if (n < 0 || n >= size) {
+            return -1;
+        }
+        p += n;
+        size -= n;
+    }
+
+    if (size <= 0) {
+        return -1;
+    }
+
+    p[size] = ')';
+    p++;
+    size--;
+
+    if (def.data == NULL) {
+        static const char notalloc[] = ", not allocated";
+        if (size < sizeof(notalloc)) {
+            return -1;
+        }
+        memcpy(p, notalloc, sizeof(notalloc));
+    }
+
+    return p - buf;
+}
+
+static PyObject *
+fortran_doc(FortranDataDef def)
+{
+    char *buf, *p;
+    PyObject *s = NULL;
+    Py_ssize_t n, origsize, size = 100;
+
+    if (def.doc != NULL) {
+        size += strlen(def.doc);
+    }
+    origsize = size;
+    buf = p = (char *)PyMem_Malloc(size);
+    if (buf == NULL) {
+        return PyErr_NoMemory();
+    }
+
+    if (def.rank == -1) {
+        if (def.doc) {
+            n = strlen(def.doc);
+            if (n > size) {
+                goto fail;
+            }
+            memcpy(p, def.doc, n);
+            p += n;
+            size -= n;
+        }
+        else {
+            n = PyOS_snprintf(p, size, "%s - no docs available", def.name);
+            if (n < 0 || n >= size) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+    }
+    else {
+        PyArray_Descr *d = PyArray_DescrFromType(def.type);
+        n = PyOS_snprintf(p, size, "'%c'-", d->type);
+        Py_DECREF(d);
+        if (n < 0 || n >= size) {
+            goto fail;
+        }
+        p += n;
+        size -= n;
+
+        if (def.data == NULL) {
+            n = format_def(p, size, def) == -1;
+            if (n < 0) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+        else if (def.rank > 0) {
+            n = format_def(p, size, def);
+            if (n < 0) {
+                goto fail;
+            }
+            p += n;
+            size -= n;
+        }
+        else {
+            n = strlen("scalar");
+            if (size < n) {
+                goto fail;
+            }
+            memcpy(p, "scalar", n);
+            p += n;
+            size -= n;
+        }
+    }
+    if (size <= 1) {
+        goto fail;
+    }
+    *p++ = '\n';
+    size--;
+
+    /* p now points one beyond the last character of the string in buf */
+#if PY_VERSION_HEX >= 0x03000000
+    s = PyUnicode_FromStringAndSize(buf, p - buf);
+#else
+    s = PyString_FromStringAndSize(buf, p - buf);
+#endif
+
+    PyMem_Free(buf);
+    return s;
+
+ fail:
+    fprintf(stderr, "fortranobject.c: fortran_doc: len(p)=%zd>%zd=size:"
+                    " too long docstring required, increase size\n",
+            p - buf, origsize);
+    PyMem_Free(buf);
+    return NULL;
+}
+
+static FortranDataDef *save_def; /* save pointer of an allocatable array */
+static void set_data(char *d,npy_intp *f) {  /* callback from Fortran */
+    if (*f)                               /* In fortran f=allocated(d) */
+        save_def->data = d;
+    else
+        save_def->data = NULL;
+    /* printf("set_data: d=%p,f=%d\n",d,*f); */
+}
+
+static PyObject *
+fortran_getattr(PyFortranObject *fp, char *name) {
+    int i,j,k,flag;
+    if (fp->dict != NULL) {
+        PyObject *v = PyDict_GetItemString(fp->dict, name);
+        if (v != NULL) {
+            Py_INCREF(v);
+            return v;
+        }
+    }
+    for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++);
+    if (j==0)
+        if (fp->defs[i].rank!=-1) {                   /* F90 allocatable array */
+            if (fp->defs[i].func==NULL) return NULL;
+            for(k=0;k<fp->defs[i].rank;++k)
+                fp->defs[i].dims.d[k]=-1;
+            save_def = &fp->defs[i];
+            (*(fp->defs[i].func))(&fp->defs[i].rank,fp->defs[i].dims.d,set_data,&flag);
+            if (flag==2)
+                k = fp->defs[i].rank + 1;
+            else
+                k = fp->defs[i].rank;
+            if (fp->defs[i].data !=NULL) {              /* array is allocated */
+                PyObject *v = PyArray_New(&PyArray_Type, k, fp->defs[i].dims.d,
+                                          fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY,
+                                          NULL);
+                if (v==NULL) return NULL;
+                /* Py_INCREF(v); */
+                return v;
+            } else {                                    /* array is not allocated */
+                Py_RETURN_NONE;
+            }
+        }
+    if (strcmp(name,"__dict__")==0) {
+        Py_INCREF(fp->dict);
+        return fp->dict;
+    }
+    if (strcmp(name,"__doc__")==0) {
+#if PY_VERSION_HEX >= 0x03000000
+        PyObject *s = PyUnicode_FromString(""), *s2, *s3;
+        for (i=0;i<fp->len;i++) {
+            s2 = fortran_doc(fp->defs[i]);
+            s3 = PyUnicode_Concat(s, s2);
+            Py_DECREF(s2);
+            Py_DECREF(s);
+            s = s3;
+        }
+#else
+        PyObject *s = PyString_FromString("");
+        for (i=0;i<fp->len;i++)
+            PyString_ConcatAndDel(&s,fortran_doc(fp->defs[i]));
+#endif
+        if (PyDict_SetItemString(fp->dict, name, s))
+            return NULL;
+        return s;
+    }
+    if ((strcmp(name,"_cpointer")==0) && (fp->len==1)) {
+        PyObject *cobj = F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data),NULL);
+        if (PyDict_SetItemString(fp->dict, name, cobj))
+            return NULL;
+        return cobj;
+    }
+#if PY_VERSION_HEX >= 0x03000000
+    if (1) {
+        PyObject *str, *ret;
+        str = PyUnicode_FromString(name);
+        ret = PyObject_GenericGetAttr((PyObject *)fp, str);
+        Py_DECREF(str);
+        return ret;
+    }
+#else
+    return Py_FindMethod(fortran_methods, (PyObject *)fp, name);
+#endif
+}
+
+static int
+fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) {
+    int i,j,flag;
+    PyArrayObject *arr = NULL;
+    for (i=0,j=1;i<fp->len && (j=strcmp(name,fp->defs[i].name));i++);
+    if (j==0) {
+        if (fp->defs[i].rank==-1) {
+            PyErr_SetString(PyExc_AttributeError,"over-writing fortran routine");
+            return -1;
+        }
+        if (fp->defs[i].func!=NULL) { /* is allocatable array */
+            npy_intp dims[F2PY_MAX_DIMS];
+            int k;
+            save_def = &fp->defs[i];
+            if (v!=Py_None) {     /* set new value (reallocate if needed --
+                                     see f2py generated code for more
+                                     details ) */
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1;
+                if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL)
+                    return -1;
+                (*(fp->defs[i].func))(&fp->defs[i].rank,PyArray_DIMS(arr),set_data,&flag);
+            } else {             /* deallocate */
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=0;
+                (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag);
+                for(k=0;k<fp->defs[i].rank;k++) dims[k]=-1;
+            }
+            memcpy(fp->defs[i].dims.d,dims,fp->defs[i].rank*sizeof(npy_intp));
+        } else {                     /* not allocatable array */
+            if ((arr = array_from_pyobj(fp->defs[i].type,fp->defs[i].dims.d,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL)
+                return -1;
+        }
+        if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */
+            npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,PyArray_NDIM(arr));
+            if (s==-1)
+                s = PyArray_MultiplyList(PyArray_DIMS(arr),PyArray_NDIM(arr));
+            if (s<0 ||
+                (memcpy(fp->defs[i].data,PyArray_DATA(arr),s*PyArray_ITEMSIZE(arr)))==NULL) {
+                if ((PyObject*)arr!=v) {
+                    Py_DECREF(arr);
+                }
+                return -1;
+            }
+            if ((PyObject*)arr!=v) {
+                Py_DECREF(arr);
+            }
+        } else return (fp->defs[i].func==NULL?-1:0);
+        return 0; /* succesful */
+    }
+    if (fp->dict == NULL) {
+        fp->dict = PyDict_New();
+        if (fp->dict == NULL)
+            return -1;
+    }
+    if (v == NULL) {
+        int rv = PyDict_DelItemString(fp->dict, name);
+        if (rv < 0)
+            PyErr_SetString(PyExc_AttributeError,"delete non-existing fortran attribute");
+        return rv;
+    }
+    else
+        return PyDict_SetItemString(fp->dict, name, v);
+}
+
+static PyObject*
+fortran_call(PyFortranObject *fp, PyObject *arg, PyObject *kw) {
+    int i = 0;
+    /*  printf("fortran call
+        name=%s,func=%p,data=%p,%p\n",fp->defs[i].name,
+        fp->defs[i].func,fp->defs[i].data,&fp->defs[i].data); */
+    if (fp->defs[i].rank==-1) {/* is Fortran routine */
+        if (fp->defs[i].func==NULL) {
+            PyErr_Format(PyExc_RuntimeError, "no function to call");
+            return NULL;
+        }
+        else if (fp->defs[i].data==NULL)
+            /* dummy routine */
+            return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,NULL);
+        else
+            return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,
+                                                        (void *)fp->defs[i].data);
+    }
+    PyErr_Format(PyExc_TypeError, "this fortran object is not callable");
+    return NULL;
+}
+
+static PyObject *
+fortran_repr(PyFortranObject *fp)
+{
+    PyObject *name = NULL, *repr = NULL;
+    name = PyObject_GetAttrString((PyObject *)fp, "__name__");
+    PyErr_Clear();
+#if PY_VERSION_HEX >= 0x03000000
+    if (name != NULL && PyUnicode_Check(name)) {
+        repr = PyUnicode_FromFormat("<fortran %U>", name);
+    }
+    else {
+        repr = PyUnicode_FromString("<fortran object>");
+    }
+#else
+    if (name != NULL && PyString_Check(name)) {
+        repr = PyString_FromFormat("<fortran %s>", PyString_AsString(name));
+    }
+    else {
+        repr = PyString_FromString("<fortran object>");
+    }
+#endif
+    Py_XDECREF(name);
+    return repr;
+}
+
+
+PyTypeObject PyFortran_Type = {
+#if PY_VERSION_HEX >= 0x03000000
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
+    PyObject_HEAD_INIT(0)
+    0,                    /*ob_size*/
+#endif
+    "fortran",                    /*tp_name*/
+    sizeof(PyFortranObject),      /*tp_basicsize*/
+    0,                    /*tp_itemsize*/
+    /* methods */
+    (destructor)fortran_dealloc, /*tp_dealloc*/
+    0,                    /*tp_print*/
+    (getattrfunc)fortran_getattr, /*tp_getattr*/
+    (setattrfunc)fortran_setattr, /*tp_setattr*/
+    0,                    /*tp_compare/tp_reserved*/
+    (reprfunc)fortran_repr, /*tp_repr*/
+    0,                    /*tp_as_number*/
+    0,                    /*tp_as_sequence*/
+    0,                    /*tp_as_mapping*/
+    0,                    /*tp_hash*/
+    (ternaryfunc)fortran_call,                    /*tp_call*/
+};
+
+/************************* f2py_report_atexit *******************************/
+
+#ifdef F2PY_REPORT_ATEXIT
+static int passed_time = 0;
+static int passed_counter = 0;
+static int passed_call_time = 0;
+static struct timeb start_time;
+static struct timeb stop_time;
+static struct timeb start_call_time;
+static struct timeb stop_call_time;
+static int cb_passed_time = 0;
+static int cb_passed_counter = 0;
+static int cb_passed_call_time = 0;
+static struct timeb cb_start_time;
+static struct timeb cb_stop_time;
+static struct timeb cb_start_call_time;
+static struct timeb cb_stop_call_time;
+
+extern void f2py_start_clock(void) { ftime(&start_time); }
+extern
+void f2py_start_call_clock(void) {
+    f2py_stop_clock();
+    ftime(&start_call_time);
+}
+extern
+void f2py_stop_clock(void) {
+    ftime(&stop_time);
+    passed_time += 1000*(stop_time.time - start_time.time);
+    passed_time += stop_time.millitm - start_time.millitm;
+}
+extern
+void f2py_stop_call_clock(void) {
+    ftime(&stop_call_time);
+    passed_call_time += 1000*(stop_call_time.time - start_call_time.time);
+    passed_call_time += stop_call_time.millitm - start_call_time.millitm;
+    passed_counter += 1;
+    f2py_start_clock();
+}
+
+extern void f2py_cb_start_clock(void) { ftime(&cb_start_time); }
+extern
+void f2py_cb_start_call_clock(void) {
+    f2py_cb_stop_clock();
+    ftime(&cb_start_call_time);
+}
+extern
+void f2py_cb_stop_clock(void) {
+    ftime(&cb_stop_time);
+    cb_passed_time += 1000*(cb_stop_time.time - cb_start_time.time);
+    cb_passed_time += cb_stop_time.millitm - cb_start_time.millitm;
+}
+extern
+void f2py_cb_stop_call_clock(void) {
+    ftime(&cb_stop_call_time);
+    cb_passed_call_time += 1000*(cb_stop_call_time.time - cb_start_call_time.time);
+    cb_passed_call_time += cb_stop_call_time.millitm - cb_start_call_time.millitm;
+    cb_passed_counter += 1;
+    f2py_cb_start_clock();
+}
+
+static int f2py_report_on_exit_been_here = 0;
+extern
+void f2py_report_on_exit(int exit_flag,void *name) {
+    if (f2py_report_on_exit_been_here) {
+        fprintf(stderr,"             %s\n",(char*)name);
+        return;
+    }
+    f2py_report_on_exit_been_here = 1;
+    fprintf(stderr,"                      /-----------------------\\\n");
+    fprintf(stderr,"                     < F2PY performance report >\n");
+    fprintf(stderr,"                      \\-----------------------/\n");
+    fprintf(stderr,"Overall time spent in ...\n");
+    fprintf(stderr,"(a) wrapped (Fortran/C) functions           : %8d msec\n",
+            passed_call_time);
+    fprintf(stderr,"(b) f2py interface,           %6d calls  : %8d msec\n",
+            passed_counter,passed_time);
+    fprintf(stderr,"(c) call-back (Python) functions            : %8d msec\n",
+            cb_passed_call_time);
+    fprintf(stderr,"(d) f2py call-back interface, %6d calls  : %8d msec\n",
+            cb_passed_counter,cb_passed_time);
+
+    fprintf(stderr,"(e) wrapped (Fortran/C) functions (acctual) : %8d msec\n\n",
+            passed_call_time-cb_passed_call_time-cb_passed_time);
+    fprintf(stderr,"Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.\n");
+    fprintf(stderr,"Exit status: %d\n",exit_flag);
+    fprintf(stderr,"Modules    : %s\n",(char*)name);
+}
+#endif
+
+/********************** report on array copy ****************************/
+
+#ifdef F2PY_REPORT_ON_ARRAY_COPY
+static void f2py_report_on_array_copy(PyArrayObject* arr) {
+    const npy_intp arr_size = PyArray_Size((PyObject *)arr);
+    if (arr_size>F2PY_REPORT_ON_ARRAY_COPY) {
+        fprintf(stderr,"copied an array: size=%ld, elsize=%"NPY_INTP_FMT"\n",
+                arr_size, (npy_intp)PyArray_ITEMSIZE(arr));
+    }
+}
+static void f2py_report_on_array_copy_fromany(void) {
+    fprintf(stderr,"created an array from object\n");
+}
+
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR f2py_report_on_array_copy((PyArrayObject *)arr)
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY f2py_report_on_array_copy_fromany()
+#else
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR
+#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY
+#endif
+
+
+/************************* array_from_obj *******************************/
+
+/*
+ * File: array_from_pyobj.c
+ *
+ * Description:
+ * ------------
+ * Provides array_from_pyobj function that returns a contigious array
+ * object with the given dimensions and required storage order, either
+ * in row-major (C) or column-major (Fortran) order. The function
+ * array_from_pyobj is very flexible about its Python object argument
+ * that can be any number, list, tuple, or array.
+ *
+ * array_from_pyobj is used in f2py generated Python extension
+ * modules.
+ *
+ * Author: Pearu Peterson <pearu@cens.ioc.ee>
+ * Created: 13-16 January 2002
+ * $Id: fortranobject.c,v 1.52 2005/07/11 07:44:20 pearu Exp $
+ */
+
+static int
+count_nonpos(const int rank,
+             const npy_intp *dims) {
+    int i=0,r=0;
+    while (i<rank) {
+        if (dims[i] <= 0) ++r;
+        ++i;
+    }
+    return r;
+}
+
+static int check_and_fix_dimensions(const PyArrayObject* arr,
+                                    const int rank,
+                                    npy_intp *dims);
+
+#ifdef DEBUG_COPY_ND_ARRAY
+void dump_dims(int rank, npy_intp* dims) {
+    int i;
+    printf("[");
+    for(i=0;i<rank;++i) {
+        printf("%3" NPY_INTP_FMT, dims[i]);
+    }
+    printf("]\n");
+}
+void dump_attrs(const PyArrayObject* obj) {
+    const PyArrayObject_fields *arr = (const PyArrayObject_fields*) obj;
+    int rank = PyArray_NDIM(arr);
+    npy_intp size = PyArray_Size((PyObject *)arr);
+    printf("\trank = %d, flags = %d, size = %" NPY_INTP_FMT  "\n",
+           rank,arr->flags,size);
+    printf("\tstrides = ");
+    dump_dims(rank,arr->strides);
+    printf("\tdimensions = ");
+    dump_dims(rank,arr->dimensions);
+}
+#endif
+
+#define SWAPTYPE(a,b,t) {t c; c = (a); (a) = (b); (b) = c; }
+
+static int swap_arrays(PyArrayObject* obj1, PyArrayObject* obj2) {
+    PyArrayObject_fields *arr1 = (PyArrayObject_fields*) obj1,
+                         *arr2 = (PyArrayObject_fields*) obj2;
+    SWAPTYPE(arr1->data,arr2->data,char*);
+    SWAPTYPE(arr1->nd,arr2->nd,int);
+    SWAPTYPE(arr1->dimensions,arr2->dimensions,npy_intp*);
+    SWAPTYPE(arr1->strides,arr2->strides,npy_intp*);
+    SWAPTYPE(arr1->base,arr2->base,PyObject*);
+    SWAPTYPE(arr1->descr,arr2->descr,PyArray_Descr*);
+    SWAPTYPE(arr1->flags,arr2->flags,int);
+    /* SWAPTYPE(arr1->weakreflist,arr2->weakreflist,PyObject*); */
+    return 0;
+}
+
+#define ARRAY_ISCOMPATIBLE(arr,type_num)                                \
+    (  (PyArray_ISINTEGER(arr) && PyTypeNum_ISINTEGER(type_num))        \
+       ||(PyArray_ISFLOAT(arr) && PyTypeNum_ISFLOAT(type_num))          \
+       ||(PyArray_ISCOMPLEX(arr) && PyTypeNum_ISCOMPLEX(type_num))      \
+       ||(PyArray_ISBOOL(arr) && PyTypeNum_ISBOOL(type_num))            \
+       )
+
+extern
+PyArrayObject* array_from_pyobj(const int type_num,
+                                npy_intp *dims,
+                                const int rank,
+                                const int intent,
+                                PyObject *obj) {
+    /* Note about reference counting
+       -----------------------------
+       If the caller returns the array to Python, it must be done with
+       Py_BuildValue("N",arr).
+       Otherwise, if obj!=arr then the caller must call Py_DECREF(arr).
+
+       Note on intent(cache,out,..)
+       ---------------------
+       Don't expect correct data when returning intent(cache) array.
+
+    */
+    char mess[200];
+    PyArrayObject *arr = NULL;
+    PyArray_Descr *descr;
+    char typechar;
+    int elsize;
+
+    if ((intent & F2PY_INTENT_HIDE)
+        || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None))
+        || ((intent & F2PY_OPTIONAL) && (obj==Py_None))
+        ) {
+        /* intent(cache), optional, intent(hide) */
+        if (count_nonpos(rank,dims)) {
+            int i;
+            strcpy(mess, "failed to create intent(cache|hide)|optional array"
+                   "-- must have defined dimensions but got (");
+            for(i=0;i<rank;++i)
+                sprintf(mess+strlen(mess),"%" NPY_INTP_FMT ",",dims[i]);
+            strcat(mess, ")");
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+        arr = (PyArrayObject *)
+            PyArray_New(&PyArray_Type, rank, dims, type_num,
+                        NULL,NULL,0,
+                        !(intent&F2PY_INTENT_C),
+                        NULL);
+        if (arr==NULL) return NULL;
+        if (!(intent & F2PY_INTENT_CACHE))
+            PyArray_FILLWBYTE(arr, 0);
+        return arr;
+    }
+
+    descr = PyArray_DescrFromType(type_num);
+    elsize = descr->elsize;
+    typechar = descr->type;
+    Py_DECREF(descr);
+    if (PyArray_Check(obj)) {
+        arr = (PyArrayObject *)obj;
+
+        if (intent & F2PY_INTENT_CACHE) {
+            /* intent(cache) */
+            if (PyArray_ISONESEGMENT(arr)
+                && PyArray_ITEMSIZE(arr)>=elsize) {
+                if (check_and_fix_dimensions(arr,rank,dims)) {
+                    return NULL; /*XXX: set exception */
+                }
+                if (intent & F2PY_INTENT_OUT)
+                    Py_INCREF(arr);
+                return arr;
+            }
+            strcpy(mess, "failed to initialize intent(cache) array");
+            if (!PyArray_ISONESEGMENT(arr))
+                strcat(mess, " -- input must be in one segment");
+            if (PyArray_ITEMSIZE(arr)<elsize)
+                sprintf(mess+strlen(mess),
+                        " -- expected at least elsize=%d but got %" NPY_INTP_FMT,
+                        elsize,
+                        (npy_intp)PyArray_ITEMSIZE(arr)
+                        );
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+
+        /* here we have always intent(in) or intent(inout) or intent(inplace) */
+
+        if (check_and_fix_dimensions(arr,rank,dims)) {
+            return NULL; /*XXX: set exception */
+        }
+	/*
+	printf("intent alignement=%d\n", F2PY_GET_ALIGNMENT(intent));
+	printf("alignement check=%d\n", F2PY_CHECK_ALIGNMENT(arr, intent));
+	int i;
+	for (i=1;i<=16;i++)
+	  printf("i=%d isaligned=%d\n", i, ARRAY_ISALIGNED(arr, i));
+	*/
+        if ((! (intent & F2PY_INTENT_COPY))
+            && PyArray_ITEMSIZE(arr)==elsize
+            && ARRAY_ISCOMPATIBLE(arr,type_num)
+	    && F2PY_CHECK_ALIGNMENT(arr, intent)
+            ) {
+            if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) {
+                if ((intent & F2PY_INTENT_OUT)) {
+                    Py_INCREF(arr);
+                }
+                /* Returning input array */
+                return arr;
+            }
+        }
+
+        if (intent & F2PY_INTENT_INOUT) {
+            strcpy(mess, "failed to initialize intent(inout) array");
+            if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr))
+                strcat(mess, " -- input not contiguous");
+            if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr))
+                strcat(mess, " -- input not fortran contiguous");
+            if (PyArray_ITEMSIZE(arr)!=elsize)
+                sprintf(mess+strlen(mess),
+                        " -- expected elsize=%d but got %" NPY_INTP_FMT,
+                        elsize,
+                        (npy_intp)PyArray_ITEMSIZE(arr)
+                        );
+            if (!(ARRAY_ISCOMPATIBLE(arr,type_num)))
+                sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'",
+                        PyArray_DESCR(arr)->type,typechar);
+	    if (!(F2PY_CHECK_ALIGNMENT(arr, intent)))
+	      sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent));
+            PyErr_SetString(PyExc_ValueError,mess);
+            return NULL;
+        }
+
+        /* here we have always intent(in) or intent(inplace) */
+
+        {
+            PyArrayObject *retarr = (PyArrayObject *) \
+                PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num,
+                            NULL,NULL,0,
+                            !(intent&F2PY_INTENT_C),
+                            NULL);
+            if (retarr==NULL)
+                return NULL;
+            F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
+            if (PyArray_CopyInto(retarr, arr)) {
+                Py_DECREF(retarr);
+                return NULL;
+            }
+            if (intent & F2PY_INTENT_INPLACE) {
+                if (swap_arrays(arr,retarr))
+                    return NULL; /* XXX: set exception */
+                Py_XDECREF(retarr);
+                if (intent & F2PY_INTENT_OUT)
+                    Py_INCREF(arr);
+            } else {
+                arr = retarr;
+            }
+        }
+        return arr;
+    }
+
+    if ((intent & F2PY_INTENT_INOUT) ||
+            (intent & F2PY_INTENT_INPLACE) ||
+            (intent & F2PY_INTENT_CACHE)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "failed to initialize intent(inout|inplace|cache) "
+                        "array, input not an array");
+        return NULL;
+    }
+
+    {
+        F2PY_REPORT_ON_ARRAY_COPY_FROMANY;
+        arr = (PyArrayObject *) \
+            PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0,
+                            ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \
+                            | NPY_ARRAY_FORCECAST, NULL);
+        if (arr==NULL)
+            return NULL;
+        if (check_and_fix_dimensions(arr,rank,dims))
+            return NULL; /*XXX: set exception */
+        return arr;
+    }
+
+}
+
+/*****************************************/
+/* Helper functions for array_from_pyobj */
+/*****************************************/
+
+static
+int check_and_fix_dimensions(const PyArrayObject* arr,const int rank,npy_intp *dims) {
+    /*
+      This function fills in blanks (that are -1\'s) in dims list using
+      the dimensions from arr. It also checks that non-blank dims will
+      match with the corresponding values in arr dimensions.
+    */
+    const npy_intp arr_size = (PyArray_NDIM(arr))?PyArray_Size((PyObject *)arr):1;
+#ifdef DEBUG_COPY_ND_ARRAY
+    dump_attrs(arr);
+    printf("check_and_fix_dimensions:init: dims=");
+    dump_dims(rank,dims);
+#endif
+    if (rank > PyArray_NDIM(arr)) { /* [1,2] -> [[1],[2]]; 1 -> [[1]]  */
+        npy_intp new_size = 1;
+        int free_axe = -1;
+        int i;
+        npy_intp d;
+        /* Fill dims where -1 or 0; check dimensions; calc new_size; */
+        for(i=0;i<PyArray_NDIM(arr);++i) {
+            d = PyArray_DIM(arr,i);
+            if (dims[i] >= 0) {
+                if (d>1 && dims[i]!=d) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT "\n",
+                            i,dims[i], d);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else {
+                dims[i] = d ? d : 1;
+            }
+            new_size *= dims[i];
+        }
+        for(i=PyArray_NDIM(arr);i<rank;++i)
+            if (dims[i]>1) {
+                fprintf(stderr,"%d-th dimension must be %" NPY_INTP_FMT
+                        " but got 0 (not defined).\n",
+                        i,dims[i]);
+                return 1;
+            } else if (free_axe<0)
+                free_axe = i;
+            else
+                dims[i] = 1;
+        if (free_axe>=0) {
+            dims[free_axe] = arr_size/new_size;
+            new_size *= dims[free_axe];
+        }
+        if (new_size != arr_size) {
+            fprintf(stderr,"unexpected array size: new_size=%" NPY_INTP_FMT
+                    ", got array with arr_size=%" NPY_INTP_FMT " (maybe too many free"
+                    " indices)\n", new_size,arr_size);
+            return 1;
+        }
+    } else if (rank==PyArray_NDIM(arr)) {
+        npy_intp new_size = 1;
+        int i;
+        npy_intp d;
+        for (i=0; i<rank; ++i) {
+	    d = PyArray_DIM(arr,i);
+            if (dims[i]>=0) {
+                if (d > 1 && d!=dims[i]) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT "\n",
+                            i,dims[i],d);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else dims[i] = d;
+            new_size *= dims[i];
+        }
+        if (new_size != arr_size) {
+            fprintf(stderr,"unexpected array size: new_size=%" NPY_INTP_FMT
+                    ", got array with arr_size=%" NPY_INTP_FMT "\n", new_size,arr_size);
+            return 1;
+        }
+    } else { /* [[1,2]] -> [[1],[2]] */
+        int i,j;
+        npy_intp d;
+        int effrank;
+        npy_intp size;
+        for (i=0,effrank=0;i<PyArray_NDIM(arr);++i)
+            if (PyArray_DIM(arr,i)>1) ++effrank;
+        if (dims[rank-1]>=0)
+            if (effrank>rank) {
+                fprintf(stderr,"too many axes: %d (effrank=%d), expected rank=%d\n",
+                        PyArray_NDIM(arr),effrank,rank);
+                return 1;
+            }
+
+        for (i=0,j=0;i<rank;++i) {
+            while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j;
+            if (j>=PyArray_NDIM(arr)) d = 1;
+            else d = PyArray_DIM(arr,j++);
+            if (dims[i]>=0) {
+                if (d>1 && d!=dims[i]) {
+                    fprintf(stderr,"%d-th dimension must be fixed to %" NPY_INTP_FMT
+                            " but got %" NPY_INTP_FMT " (real index=%d)\n",
+                            i,dims[i],d,j-1);
+                    return 1;
+                }
+                if (!dims[i]) dims[i] = 1;
+            } else
+                dims[i] = d;
+        }
+
+        for (i=rank;i<PyArray_NDIM(arr);++i) { /* [[1,2],[3,4]] -> [1,2,3,4] */
+            while (j<PyArray_NDIM(arr) && PyArray_DIM(arr,j)<2) ++j;
+            if (j>=PyArray_NDIM(arr)) d = 1;
+            else d = PyArray_DIM(arr,j++);
+            dims[rank-1] *= d;
+        }
+        for (i=0,size=1;i<rank;++i) size *= dims[i];
+        if (size != arr_size) {
+            fprintf(stderr,"unexpected array size: size=%" NPY_INTP_FMT ", arr_size=%" NPY_INTP_FMT
+                    ", rank=%d, effrank=%d, arr.nd=%d, dims=[",
+                    size,arr_size,rank,effrank,PyArray_NDIM(arr));
+            for (i=0;i<rank;++i) fprintf(stderr," %" NPY_INTP_FMT,dims[i]);
+            fprintf(stderr," ], arr.dims=[");
+            for (i=0;i<PyArray_NDIM(arr);++i) fprintf(stderr," %" NPY_INTP_FMT,PyArray_DIM(arr,i));
+            fprintf(stderr," ]\n");
+            return 1;
+        }
+    }
+#ifdef DEBUG_COPY_ND_ARRAY
+    printf("check_and_fix_dimensions:end: dims=");
+    dump_dims(rank,dims);
+#endif
+    return 0;
+}
+
+/* End of file: array_from_pyobj.c */
+
+/************************* copy_ND_array *******************************/
+
+extern
+int copy_ND_array(const PyArrayObject *arr, PyArrayObject *out)
+{
+    F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
+    return PyArray_CopyInto(out, (PyArrayObject *)arr);
+}
+
+/*********************************************/
+/* Compatibility functions for Python >= 3.0 */
+/*********************************************/
+
+#if PY_VERSION_HEX >= 0x03000000
+
+PyObject *
+F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+void *
+F2PyCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+int
+F2PyCapsule_Check(PyObject *ptr)
+{
+    return PyCapsule_CheckExact(ptr);
+}
+
+#else
+
+PyObject *
+F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, dtor);
+}
+
+void *
+F2PyCapsule_AsVoidPtr(PyObject *ptr)
+{
+    return PyCObject_AsVoidPtr(ptr);
+}
+
+int
+F2PyCapsule_Check(PyObject *ptr)
+{
+    return PyCObject_Check(ptr);
+}
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+/************************* EOF fortranobject.c *******************************/
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
new file mode 100644
index 0000000000..c9b54e2594
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
@@ -0,0 +1,162 @@
+#ifndef Py_FORTRANOBJECT_H
+#define Py_FORTRANOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Python.h"
+
+#ifdef FORTRANOBJECT_C
+#define NO_IMPORT_ARRAY
+#endif
+#define PY_ARRAY_UNIQUE_SYMBOL _npy_f2py_ARRAY_API
+#include "numpy/arrayobject.h"
+
+/*
+ * Python 3 support macros
+ */
+#if PY_VERSION_HEX >= 0x03000000
+#define PyString_Check PyBytes_Check
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_FromString PyBytes_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+
+#define PyInt_Check PyLong_Check
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsLong PyLong_AsLong
+
+#define PyNumber_Int PyNumber_Long
+
+#else
+
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#endif
+
+
+#ifdef F2PY_REPORT_ATEXIT
+#include <sys/timeb.h>
+  extern void f2py_start_clock(void);
+  extern void f2py_stop_clock(void);
+  extern void f2py_start_call_clock(void);
+  extern void f2py_stop_call_clock(void);
+  extern void f2py_cb_start_clock(void);
+  extern void f2py_cb_stop_clock(void);
+  extern void f2py_cb_start_call_clock(void);
+  extern void f2py_cb_stop_call_clock(void);
+  extern void f2py_report_on_exit(int,void*);
+#endif
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/* Fortran object interface */
+
+/*
+123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
+
+PyFortranObject represents various Fortran objects:
+Fortran (module) routines, COMMON blocks, module data.
+
+Author: Pearu Peterson <pearu@cens.ioc.ee>
+*/
+
+#define F2PY_MAX_DIMS 40
+
+typedef void (*f2py_set_data_func)(char*,npy_intp*);
+typedef void (*f2py_void_func)(void);
+typedef void (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*);
+
+  /*typedef void* (*f2py_c_func)(void*,...);*/
+
+typedef void *(*f2pycfunc)(void);
+
+typedef struct {
+  char *name;                /* attribute (array||routine) name */
+  int rank;                  /* array rank, 0 for scalar, max is F2PY_MAX_DIMS,
+				|| rank=-1 for Fortran routine */
+  struct {npy_intp d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */
+  int type;                  /* PyArray_<type> || not used */
+  char *data;                /* pointer to array || Fortran routine */
+  f2py_init_func func;            /* initialization function for
+				allocatable arrays:
+				func(&rank,dims,set_ptr_func,name,len(name))
+				|| C/API wrapper for Fortran routine */
+  char *doc;                 /* documentation string; only recommended
+				for routines. */
+} FortranDataDef;
+
+typedef struct {
+  PyObject_HEAD
+  int len;                   /* Number of attributes */
+  FortranDataDef *defs;      /* An array of FortranDataDef's */
+  PyObject       *dict;      /* Fortran object attribute dictionary */
+} PyFortranObject;
+
+#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type)
+#define PyFortran_Check1(op) (0==strcmp(Py_TYPE(op)->tp_name,"fortran"))
+
+  extern PyTypeObject PyFortran_Type;
+  extern int F2PyDict_SetItemString(PyObject* dict, char *name, PyObject *obj);
+  extern PyObject * PyFortranObject_New(FortranDataDef* defs, f2py_void_func init);
+  extern PyObject * PyFortranObject_NewAsAttr(FortranDataDef* defs);
+
+#if PY_VERSION_HEX >= 0x03000000
+
+PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
+void * F2PyCapsule_AsVoidPtr(PyObject *obj);
+int F2PyCapsule_Check(PyObject *ptr);
+
+#else
+
+PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *));
+void * F2PyCapsule_AsVoidPtr(PyObject *ptr);
+int F2PyCapsule_Check(PyObject *ptr);
+
+#endif
+
+#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS)
+#define F2PY_INTENT_IN 1
+#define F2PY_INTENT_INOUT 2
+#define F2PY_INTENT_OUT 4
+#define F2PY_INTENT_HIDE 8
+#define F2PY_INTENT_CACHE 16
+#define F2PY_INTENT_COPY 32
+#define F2PY_INTENT_C 64
+#define F2PY_OPTIONAL 128
+#define F2PY_INTENT_INPLACE 256
+#define F2PY_INTENT_ALIGNED4 512
+#define F2PY_INTENT_ALIGNED8 1024
+#define F2PY_INTENT_ALIGNED16 2048
+
+#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0)
+#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4)
+#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8)
+#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16)
+
+#define F2PY_GET_ALIGNMENT(intent) \
+	(F2PY_ALIGN4(intent) ? 4 : \
+	 (F2PY_ALIGN8(intent) ? 8 : \
+	  (F2PY_ALIGN16(intent) ? 16 : 1) ))
+#define F2PY_CHECK_ALIGNMENT(arr, intent) ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent))
+
+  extern PyArrayObject* array_from_pyobj(const int type_num,
+					 npy_intp *dims,
+					 const int rank,
+					 const int intent,
+					 PyObject *obj);
+  extern int copy_ND_array(const PyArrayObject *in, PyArrayObject *out);
+
+#ifdef DEBUG_COPY_ND_ARRAY
+  extern void dump_attrs(const PyArrayObject* arr);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FORTRANOBJECT_H */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
new file mode 100644
index 0000000000..2da6a2c5de
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
@@ -0,0 +1,223 @@
+/* File: wrapmodule.c
+ * This file is auto-generated with f2py (version:2_1330).
+ * Hand edited by Pearu.
+ * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition,
+ * written by Pearu Peterson <pearu@cens.ioc.ee>.
+ * See http://cens.ioc.ee/projects/f2py2e/
+ * Generation date: Fri Oct 21 22:41:12 2005
+ * $Revision:$
+ * $Date:$
+ * Do not edit this file directly unless you know what you are doing!!!
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************** See f2py2e/cfuncs.py: includes ***********************/
+#include "Python.h"
+#include "fortranobject.h"
+#include <math.h>
+
+static PyObject *wrap_error;
+static PyObject *wrap_module;
+
+/************************************ call ************************************/
+static char doc_f2py_rout_wrap_call[] = "\
+Function signature:\n\
+  arr = call(type_num,dims,intent,obj)\n\
+Required arguments:\n"
+"  type_num : input int\n"
+"  dims : input int-sequence\n"
+"  intent : input int\n"
+"  obj : input python object\n"
+"Return objects:\n"
+"  arr : array";
+static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
+				     PyObject *capi_args) {
+  PyObject * volatile capi_buildvalue = NULL;
+  int type_num = 0;
+  npy_intp *dims = NULL;
+  PyObject *dims_capi = Py_None;
+  int rank = 0;
+  int intent = 0;
+  PyArrayObject *capi_arr_tmp = NULL;
+  PyObject *arr_capi = Py_None;
+  int i;
+
+  if (!PyArg_ParseTuple(capi_args,"iOiO|:wrap.call",\
+			&type_num,&dims_capi,&intent,&arr_capi))
+    return NULL;
+  rank = PySequence_Length(dims_capi);
+  dims = malloc(rank*sizeof(npy_intp));
+  for (i=0;i<rank;++i)
+    dims[i] = (npy_intp)PyInt_AsLong(PySequence_GetItem(dims_capi,i));
+
+  capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi);
+  if (capi_arr_tmp == NULL) {
+    free(dims);
+    return NULL;
+  }
+  capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
+  free(dims);
+  return capi_buildvalue;
+}
+
+static char doc_f2py_rout_wrap_attrs[] = "\
+Function signature:\n\
+  arr = array_attrs(arr)\n\
+Required arguments:\n"
+"  arr : input array object\n"
+"Return objects:\n"
+"  data : data address in hex\n"
+"  nd : int\n"
+"  dimensions : tuple\n"
+"  strides : tuple\n"
+"  base : python object\n"
+"  (kind,type,type_num,elsize,alignment) : 4-tuple\n"
+"  flags : int\n"
+"  itemsize : int\n"
+;
+static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
+				      PyObject *capi_args) {
+  PyObject *arr_capi = Py_None;
+  PyArrayObject *arr = NULL;
+  PyObject *dimensions = NULL;
+  PyObject *strides = NULL;
+  char s[100];
+  int i;
+  memset(s,0,100*sizeof(char));
+  if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
+			&PyArray_Type,&arr_capi))
+    return NULL;
+  arr = (PyArrayObject *)arr_capi;
+  sprintf(s,"%p",PyArray_DATA(arr));
+  dimensions = PyTuple_New(PyArray_NDIM(arr));
+  strides = PyTuple_New(PyArray_NDIM(arr));
+  for (i=0;i<PyArray_NDIM(arr);++i) {
+    PyTuple_SetItem(dimensions,i,PyInt_FromLong(PyArray_DIM(arr,i)));
+    PyTuple_SetItem(strides,i,PyInt_FromLong(PyArray_STRIDE(arr,i)));
+  }
+  return Py_BuildValue("siOOO(cciii)ii",s,PyArray_NDIM(arr),
+		       dimensions,strides,
+		       (PyArray_BASE(arr)==NULL?Py_None:PyArray_BASE(arr)),
+		       PyArray_DESCR(arr)->kind,
+		       PyArray_DESCR(arr)->type,
+		       PyArray_TYPE(arr),
+		       PyArray_ITEMSIZE(arr),
+		       PyArray_DESCR(arr)->alignment,
+		       PyArray_FLAGS(arr),
+		       PyArray_ITEMSIZE(arr));
+}
+
+static PyMethodDef f2py_module_methods[] = {
+
+  {"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call},
+  {"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs},
+  {NULL,NULL}
+};
+
+#if PY_VERSION_HEX >= 0x03000000
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "test_array_from_pyobj_ext",
+    NULL,
+    -1,
+    f2py_module_methods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+#endif
+
+#if PY_VERSION_HEX >= 0x03000000
+#define RETVAL m
+PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
+#else
+#define RETVAL
+PyMODINIT_FUNC inittest_array_from_pyobj_ext(void) {
+#endif
+  PyObject *m,*d, *s;
+#if PY_VERSION_HEX >= 0x03000000
+  m = wrap_module = PyModule_Create(&moduledef);
+#else
+  m = wrap_module = Py_InitModule("test_array_from_pyobj_ext", f2py_module_methods);
+#endif
+  Py_TYPE(&PyFortran_Type) = &PyType_Type;
+  import_array();
+  if (PyErr_Occurred())
+    Py_FatalError("can't initialize module wrap (failed to import numpy)");
+  d = PyModule_GetDict(m);
+  s = PyString_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n"
+"  arr = call(type_num,dims,intent,obj)\n"
+".");
+  PyDict_SetItemString(d, "__doc__", s);
+  wrap_error = PyErr_NewException ("wrap.error", NULL, NULL);
+  Py_DECREF(s);
+  PyDict_SetItemString(d, "F2PY_INTENT_IN", PyInt_FromLong(F2PY_INTENT_IN));
+  PyDict_SetItemString(d, "F2PY_INTENT_INOUT", PyInt_FromLong(F2PY_INTENT_INOUT));
+  PyDict_SetItemString(d, "F2PY_INTENT_OUT", PyInt_FromLong(F2PY_INTENT_OUT));
+  PyDict_SetItemString(d, "F2PY_INTENT_HIDE", PyInt_FromLong(F2PY_INTENT_HIDE));
+  PyDict_SetItemString(d, "F2PY_INTENT_CACHE", PyInt_FromLong(F2PY_INTENT_CACHE));
+  PyDict_SetItemString(d, "F2PY_INTENT_COPY", PyInt_FromLong(F2PY_INTENT_COPY));
+  PyDict_SetItemString(d, "F2PY_INTENT_C", PyInt_FromLong(F2PY_INTENT_C));
+  PyDict_SetItemString(d, "F2PY_OPTIONAL", PyInt_FromLong(F2PY_OPTIONAL));
+  PyDict_SetItemString(d, "F2PY_INTENT_INPLACE", PyInt_FromLong(F2PY_INTENT_INPLACE));
+  PyDict_SetItemString(d, "NPY_BOOL", PyInt_FromLong(NPY_BOOL));
+  PyDict_SetItemString(d, "NPY_BYTE", PyInt_FromLong(NPY_BYTE));
+  PyDict_SetItemString(d, "NPY_UBYTE", PyInt_FromLong(NPY_UBYTE));
+  PyDict_SetItemString(d, "NPY_SHORT", PyInt_FromLong(NPY_SHORT));
+  PyDict_SetItemString(d, "NPY_USHORT", PyInt_FromLong(NPY_USHORT));
+  PyDict_SetItemString(d, "NPY_INT", PyInt_FromLong(NPY_INT));
+  PyDict_SetItemString(d, "NPY_UINT", PyInt_FromLong(NPY_UINT));
+  PyDict_SetItemString(d, "NPY_INTP", PyInt_FromLong(NPY_INTP));
+  PyDict_SetItemString(d, "NPY_UINTP", PyInt_FromLong(NPY_UINTP));
+  PyDict_SetItemString(d, "NPY_LONG", PyInt_FromLong(NPY_LONG));
+  PyDict_SetItemString(d, "NPY_ULONG", PyInt_FromLong(NPY_ULONG));
+  PyDict_SetItemString(d, "NPY_LONGLONG", PyInt_FromLong(NPY_LONGLONG));
+  PyDict_SetItemString(d, "NPY_ULONGLONG", PyInt_FromLong(NPY_ULONGLONG));
+  PyDict_SetItemString(d, "NPY_FLOAT", PyInt_FromLong(NPY_FLOAT));
+  PyDict_SetItemString(d, "NPY_DOUBLE", PyInt_FromLong(NPY_DOUBLE));
+  PyDict_SetItemString(d, "NPY_LONGDOUBLE", PyInt_FromLong(NPY_LONGDOUBLE));
+  PyDict_SetItemString(d, "NPY_CFLOAT", PyInt_FromLong(NPY_CFLOAT));
+  PyDict_SetItemString(d, "NPY_CDOUBLE", PyInt_FromLong(NPY_CDOUBLE));
+  PyDict_SetItemString(d, "NPY_CLONGDOUBLE", PyInt_FromLong(NPY_CLONGDOUBLE));
+  PyDict_SetItemString(d, "NPY_OBJECT", PyInt_FromLong(NPY_OBJECT));
+  PyDict_SetItemString(d, "NPY_STRING", PyInt_FromLong(NPY_STRING));
+  PyDict_SetItemString(d, "NPY_UNICODE", PyInt_FromLong(NPY_UNICODE));
+  PyDict_SetItemString(d, "NPY_VOID", PyInt_FromLong(NPY_VOID));
+  PyDict_SetItemString(d, "NPY_NTYPES", PyInt_FromLong(NPY_NTYPES));
+  PyDict_SetItemString(d, "NPY_NOTYPE", PyInt_FromLong(NPY_NOTYPE));
+  PyDict_SetItemString(d, "NPY_USERDEF", PyInt_FromLong(NPY_USERDEF));
+
+  PyDict_SetItemString(d, "CONTIGUOUS", PyInt_FromLong(NPY_ARRAY_C_CONTIGUOUS));
+  PyDict_SetItemString(d, "FORTRAN", PyInt_FromLong(NPY_ARRAY_F_CONTIGUOUS));
+  PyDict_SetItemString(d, "OWNDATA", PyInt_FromLong(NPY_ARRAY_OWNDATA));
+  PyDict_SetItemString(d, "FORCECAST", PyInt_FromLong(NPY_ARRAY_FORCECAST));
+  PyDict_SetItemString(d, "ENSURECOPY", PyInt_FromLong(NPY_ARRAY_ENSURECOPY));
+  PyDict_SetItemString(d, "ENSUREARRAY", PyInt_FromLong(NPY_ARRAY_ENSUREARRAY));
+  PyDict_SetItemString(d, "ALIGNED", PyInt_FromLong(NPY_ARRAY_ALIGNED));
+  PyDict_SetItemString(d, "WRITEABLE", PyInt_FromLong(NPY_ARRAY_WRITEABLE));
+  PyDict_SetItemString(d, "UPDATEIFCOPY", PyInt_FromLong(NPY_ARRAY_UPDATEIFCOPY));
+
+  PyDict_SetItemString(d, "BEHAVED", PyInt_FromLong(NPY_ARRAY_BEHAVED));
+  PyDict_SetItemString(d, "BEHAVED_NS", PyInt_FromLong(NPY_ARRAY_BEHAVED_NS));
+  PyDict_SetItemString(d, "CARRAY", PyInt_FromLong(NPY_ARRAY_CARRAY));
+  PyDict_SetItemString(d, "FARRAY", PyInt_FromLong(NPY_ARRAY_FARRAY));
+  PyDict_SetItemString(d, "CARRAY_RO", PyInt_FromLong(NPY_ARRAY_CARRAY_RO));
+  PyDict_SetItemString(d, "FARRAY_RO", PyInt_FromLong(NPY_ARRAY_FARRAY_RO));
+  PyDict_SetItemString(d, "DEFAULT", PyInt_FromLong(NPY_ARRAY_DEFAULT));
+  PyDict_SetItemString(d, "UPDATE_ALL", PyInt_FromLong(NPY_ARRAY_UPDATE_ALL));
+
+  if (PyErr_Occurred())
+    Py_FatalError("can't initialize module wrap");
+
+#ifdef F2PY_REPORT_ATEXIT
+  on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
+#endif
+
+  return RETVAL;
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
new file mode 100644
index 0000000000..2665f89b52
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
@@ -0,0 +1 @@
+dict(real=dict(rk="double"))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
new file mode 100644
index 0000000000..b301710f5d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
@@ -0,0 +1,34 @@
+
+subroutine sum(x, res)
+  implicit none
+  real, intent(in) :: x(:)
+  real, intent(out) :: res
+
+  integer :: i
+
+  !print *, "sum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end subroutine sum
+
+function fsum(x) result (res)
+  implicit none
+  real, intent(in) :: x(:)
+  real :: res
+
+  integer :: i
+
+  !print *, "fsum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end function fsum
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
new file mode 100644
index 0000000000..cbe6317ed8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
@@ -0,0 +1,41 @@
+
+module mod
+
+contains
+
+subroutine sum(x, res)
+  implicit none
+  real, intent(in) :: x(:)
+  real, intent(out) :: res
+
+  integer :: i
+
+  !print *, "sum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end subroutine sum
+
+function fsum(x) result (res)
+  implicit none
+  real, intent(in) :: x(:)
+  real :: res
+
+  integer :: i
+
+  !print *, "fsum: size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+end function fsum
+
+
+end module mod
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
new file mode 100644
index 0000000000..337465ac54
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
@@ -0,0 +1,19 @@
+subroutine sum_with_use(x, res)
+  use precision
+
+  implicit none
+
+  real(kind=rk), intent(in) :: x(:)
+  real(kind=rk), intent(out) :: res
+
+  integer :: i
+
+  !print *, "size(x) = ", size(x)
+
+  res = 0.0
+
+  do i = 1, size(x)
+    res = res + x(i)
+  enddo
+
+ end subroutine
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
new file mode 100644
index 0000000000..ed6c70cbbe
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
@@ -0,0 +1,4 @@
+module precision
+  integer, parameter :: rk = selected_real_kind(8)
+  integer, parameter :: ik = selected_real_kind(4)
+end module
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
new file mode 100644
index 0000000000..d3d15cfb20
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
@@ -0,0 +1,20 @@
+
+
+subroutine selectedrealkind(p, r, res)
+  implicit none
+  
+  integer, intent(in) :: p, r
+  !f2py integer :: r=0
+  integer, intent(out) :: res
+  res = selected_real_kind(p, r)
+
+end subroutine
+
+subroutine selectedintkind(p, res)
+  implicit none
+
+  integer, intent(in) :: p
+  integer, intent(out) :: res
+  res = selected_int_kind(p)
+
+end subroutine
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
new file mode 100644
index 0000000000..c34742578f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
@@ -0,0 +1,5 @@
+      subroutine bar11(a)
+cf2py intent(out) a
+      integer a
+      a = 11
+      end
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
new file mode 100644
index 0000000000..7543a6acb7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
@@ -0,0 +1,8 @@
+      module foo_fixed
+      contains
+        subroutine bar12(a)
+!f2py intent(out) a
+          integer a
+          a = 12
+        end subroutine bar12
+      end module foo_fixed
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
new file mode 100644
index 0000000000..c1b641f13e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
@@ -0,0 +1,8 @@
+module foo_free
+contains
+  subroutine bar13(a)
+    !f2py intent(out) a
+    integer a
+    a = 13
+  end subroutine bar13
+end module foo_free
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
new file mode 100644
index 0000000000..80cdad90ce
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
@@ -0,0 +1,9 @@
+! Check that intent(in out) translates as intent(inout).
+! The separation seems to be a common usage.
+      subroutine foo(x)
+          implicit none
+          real(4), intent(in out) :: x
+          dimension x(3)
+          x(1) = x(1) + x(2) + x(3)
+          return
+      end
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90 b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
new file mode 100644
index 0000000000..5b66f8c430
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
@@ -0,0 +1,44 @@
+
+subroutine foo(a, n, m, b)
+  implicit none
+
+  real, intent(in) :: a(n, m)
+  integer, intent(in) :: n, m
+  real, intent(out) :: b(size(a, 1))
+
+  integer :: i
+
+  do i = 1, size(b)
+    b(i) = sum(a(i,:))
+  enddo
+end subroutine
+
+subroutine trans(x,y)
+  implicit none
+  real, intent(in), dimension(:,:) :: x
+  real, intent(out), dimension( size(x,2), size(x,1) ) :: y
+  integer :: N, M, i, j
+  N = size(x,1)
+  M = size(x,2)
+  DO i=1,N
+     do j=1,M
+        y(j,i) = x(i,j)
+     END DO
+  END DO
+end subroutine trans
+
+subroutine flatten(x,y)
+  implicit none
+  real, intent(in), dimension(:,:) :: x
+  real, intent(out), dimension( size(x) ) :: y
+  integer :: N, M, i, j, k
+  N = size(x,1)
+  M = size(x,2)
+  k = 1
+  DO i=1,N
+     do j=1,M
+        y(k) = x(i,j)
+        k = k + 1
+     END DO
+  END DO
+end subroutine flatten
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
new file mode 100644
index 0000000000..48bb7c0f4d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
@@ -0,0 +1,591 @@
+from __future__ import division, absolute_import, print_function
+
+import unittest
+import os
+import sys
+import copy
+
+from numpy import (
+    array, alltrue, ndarray, zeros, dtype, intp, clongdouble
+)
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, SkipTest
+)
+from numpy.core.multiarray import typeinfo
+import util
+
+wrap = None
+
+
+def setup():
+    """
+    Build the required testing extension module
+
+    """
+    global wrap
+
+    # Check compiler availability first
+    if not util.has_c_compiler():
+        raise SkipTest("No C compiler available")
+
+    if wrap is None:
+        config_code = """
+        config.add_extension('test_array_from_pyobj_ext',
+                             sources=['wrapmodule.c', 'fortranobject.c'],
+                             define_macros=[])
+        """
+        d = os.path.dirname(__file__)
+        src = [os.path.join(d, 'src', 'array_from_pyobj', 'wrapmodule.c'),
+               os.path.join(d, '..', 'src', 'fortranobject.c'),
+               os.path.join(d, '..', 'src', 'fortranobject.h')]
+        wrap = util.build_module_distutils(src, config_code,
+                                           'test_array_from_pyobj_ext')
+
+
+def flags_info(arr):
+    flags = wrap.array_attrs(arr)[6]
+    return flags2names(flags)
+
+
+def flags2names(flags):
+    info = []
+    for flagname in ['CONTIGUOUS', 'FORTRAN', 'OWNDATA', 'ENSURECOPY',
+                     'ENSUREARRAY', 'ALIGNED', 'NOTSWAPPED', 'WRITEABLE',
+                     'UPDATEIFCOPY', 'BEHAVED', 'BEHAVED_RO',
+                     'CARRAY', 'FARRAY'
+                     ]:
+        if abs(flags) & getattr(wrap, flagname, 0):
+            info.append(flagname)
+    return info
+
+
+class Intent(object):
+
+    def __init__(self, intent_list=[]):
+        self.intent_list = intent_list[:]
+        flags = 0
+        for i in intent_list:
+            if i == 'optional':
+                flags |= wrap.F2PY_OPTIONAL
+            else:
+                flags |= getattr(wrap, 'F2PY_INTENT_' + i.upper())
+        self.flags = flags
+
+    def __getattr__(self, name):
+        name = name.lower()
+        if name == 'in_':
+            name = 'in'
+        return self.__class__(self.intent_list + [name])
+
+    def __str__(self):
+        return 'intent(%s)' % (','.join(self.intent_list))
+
+    def __repr__(self):
+        return 'Intent(%r)' % (self.intent_list)
+
+    def is_intent(self, *names):
+        for name in names:
+            if name not in self.intent_list:
+                return False
+        return True
+
+    def is_intent_exact(self, *names):
+        return len(self.intent_list) == len(names) and self.is_intent(*names)
+
+intent = Intent()
+
+_type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT',
+               'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG',
+               'FLOAT', 'DOUBLE', 'CFLOAT']
+
+_cast_dict = {'BOOL': ['BOOL']}
+_cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE']
+_cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE']
+_cast_dict['BYTE'] = ['BYTE']
+_cast_dict['UBYTE'] = ['UBYTE']
+_cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT']
+_cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT']
+_cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT']
+_cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT']
+
+_cast_dict['LONG'] = _cast_dict['INT'] + ['LONG']
+_cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG']
+
+_cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG']
+_cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG']
+
+_cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT']
+_cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE']
+
+_cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT']
+
+# 32 bit system malloc typically does not provide the alignment required by
+# 16 byte long double types this means the inout intent cannot be satisfied
+# and several tests fail as the alignment flag can be randomly true or fals
+# when numpy gains an aligned allocator the tests could be enabled again
+if ((intp().dtype.itemsize != 4 or clongdouble().dtype.alignment <= 8) and
+        sys.platform != 'win32'):
+    _type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE'])
+    _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \
+        ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE']
+    _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + \
+        ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE']
+    _cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT', 'CDOUBLE']
+
+
+class Type(object):
+    _type_cache = {}
+
+    def __new__(cls, name):
+        if isinstance(name, dtype):
+            dtype0 = name
+            name = None
+            for n, i in typeinfo.items():
+                if isinstance(i, tuple) and dtype0.type is i[-1]:
+                    name = n
+                    break
+        obj = cls._type_cache.get(name.upper(), None)
+        if obj is not None:
+            return obj
+        obj = object.__new__(cls)
+        obj._init(name)
+        cls._type_cache[name.upper()] = obj
+        return obj
+
+    def _init(self, name):
+        self.NAME = name.upper()
+        self.type_num = getattr(wrap, 'NPY_' + self.NAME)
+        assert_equal(self.type_num, typeinfo[self.NAME][1])
+        self.dtype = typeinfo[self.NAME][-1]
+        self.elsize = typeinfo[self.NAME][2] / 8
+        self.dtypechar = typeinfo[self.NAME][0]
+
+    def cast_types(self):
+        return [self.__class__(_m) for _m in _cast_dict[self.NAME]]
+
+    def all_types(self):
+        return [self.__class__(_m) for _m in _type_names]
+
+    def smaller_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if typeinfo[name][3] < bits:
+                types.append(Type(name))
+        return types
+
+    def equal_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if name == self.NAME:
+                continue
+            if typeinfo[name][3] == bits:
+                types.append(Type(name))
+        return types
+
+    def larger_types(self):
+        bits = typeinfo[self.NAME][3]
+        types = []
+        for name in _type_names:
+            if typeinfo[name][3] > bits:
+                types.append(Type(name))
+        return types
+
+
+class Array(object):
+
+    def __init__(self, typ, dims, intent, obj):
+        self.type = typ
+        self.dims = dims
+        self.intent = intent
+        self.obj_copy = copy.deepcopy(obj)
+        self.obj = obj
+
+        # arr.dtypechar may be different from typ.dtypechar
+        self.arr = wrap.call(typ.type_num, dims, intent.flags, obj)
+
+        assert_(isinstance(self.arr, ndarray), repr(type(self.arr)))
+
+        self.arr_attr = wrap.array_attrs(self.arr)
+
+        if len(dims) > 1:
+            if self.intent.is_intent('c'):
+                assert_(intent.flags & wrap.F2PY_INTENT_C)
+                assert_(not self.arr.flags['FORTRAN'],
+                        repr((self.arr.flags, getattr(obj, 'flags', None))))
+                assert_(self.arr.flags['CONTIGUOUS'])
+                assert_(not self.arr_attr[6] & wrap.FORTRAN)
+            else:
+                assert_(not intent.flags & wrap.F2PY_INTENT_C)
+                assert_(self.arr.flags['FORTRAN'])
+                assert_(not self.arr.flags['CONTIGUOUS'])
+                assert_(self.arr_attr[6] & wrap.FORTRAN)
+
+        if obj is None:
+            self.pyarr = None
+            self.pyarr_attr = None
+            return
+
+        if intent.is_intent('cache'):
+            assert_(isinstance(obj, ndarray), repr(type(obj)))
+            self.pyarr = array(obj).reshape(*dims).copy()
+        else:
+            self.pyarr = array(array(obj, dtype=typ.dtypechar).reshape(*dims),
+                               order=self.intent.is_intent('c') and 'C' or 'F')
+            assert_(self.pyarr.dtype == typ,
+                    repr((self.pyarr.dtype, typ)))
+        assert_(self.pyarr.flags['OWNDATA'], (obj, intent))
+        self.pyarr_attr = wrap.array_attrs(self.pyarr)
+
+        if len(dims) > 1:
+            if self.intent.is_intent('c'):
+                assert_(not self.pyarr.flags['FORTRAN'])
+                assert_(self.pyarr.flags['CONTIGUOUS'])
+                assert_(not self.pyarr_attr[6] & wrap.FORTRAN)
+            else:
+                assert_(self.pyarr.flags['FORTRAN'])
+                assert_(not self.pyarr.flags['CONTIGUOUS'])
+                assert_(self.pyarr_attr[6] & wrap.FORTRAN)
+
+        assert_(self.arr_attr[1] == self.pyarr_attr[1])  # nd
+        assert_(self.arr_attr[2] == self.pyarr_attr[2])  # dimensions
+        if self.arr_attr[1] <= 1:
+            assert_(self.arr_attr[3] == self.pyarr_attr[3],
+                    repr((self.arr_attr[3], self.pyarr_attr[3],
+                          self.arr.tobytes(), self.pyarr.tobytes())))  # strides
+        assert_(self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:],
+                repr((self.arr_attr[5], self.pyarr_attr[5])))  # descr
+        assert_(self.arr_attr[6] == self.pyarr_attr[6],
+                repr((self.arr_attr[6], self.pyarr_attr[6],
+                      flags2names(0 * self.arr_attr[6] - self.pyarr_attr[6]),
+                      flags2names(self.arr_attr[6]), intent)))  # flags
+
+        if intent.is_intent('cache'):
+            assert_(self.arr_attr[5][3] >= self.type.elsize,
+                    repr((self.arr_attr[5][3], self.type.elsize)))
+        else:
+            assert_(self.arr_attr[5][3] == self.type.elsize,
+                    repr((self.arr_attr[5][3], self.type.elsize)))
+        assert_(self.arr_equal(self.pyarr, self.arr))
+
+        if isinstance(self.obj, ndarray):
+            if typ.elsize == Type(obj.dtype).elsize:
+                if not intent.is_intent('copy') and self.arr_attr[1] <= 1:
+                    assert_(self.has_shared_memory())
+
+    def arr_equal(self, arr1, arr2):
+        if arr1.shape != arr2.shape:
+            return False
+        s = arr1 == arr2
+        return alltrue(s.flatten())
+
+    def __str__(self):
+        return str(self.arr)
+
+    def has_shared_memory(self):
+        """Check that created array shares data with input array.
+        """
+        if self.obj is self.arr:
+            return True
+        if not isinstance(self.obj, ndarray):
+            return False
+        obj_attr = wrap.array_attrs(self.obj)
+        return obj_attr[0] == self.arr_attr[0]
+
+
+class test_intent(unittest.TestCase):
+
+    def test_in_out(self):
+        assert_equal(str(intent.in_.out), 'intent(in,out)')
+        assert_(intent.in_.c.is_intent('c'))
+        assert_(not intent.in_.c.is_intent_exact('c'))
+        assert_(intent.in_.c.is_intent_exact('c', 'in'))
+        assert_(intent.in_.c.is_intent_exact('in', 'c'))
+        assert_(not intent.in_.is_intent('c'))
+
+
+class _test_shared_memory:
+    num2seq = [1, 2]
+    num23seq = [[1, 2, 3], [4, 5, 6]]
+
+    def test_in_from_2seq(self):
+        a = self.array([2], intent.in_, self.num2seq)
+        assert_(not a.has_shared_memory())
+
+    def test_in_from_2casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num2seq, dtype=t.dtype)
+            a = self.array([len(self.num2seq)], intent.in_, obj)
+            if t.elsize == self.type.elsize:
+                assert_(
+                    a.has_shared_memory(), repr((self.type.dtype, t.dtype)))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_inout_2seq(self):
+        obj = array(self.num2seq, dtype=self.type.dtype)
+        a = self.array([len(self.num2seq)], intent.inout, obj)
+        assert_(a.has_shared_memory())
+
+        try:
+            a = self.array([2], intent.in_.inout, self.num2seq)
+        except TypeError as msg:
+            if not str(msg).startswith('failed to initialize intent'
+                                       '(inout|inplace|cache) array'):
+                raise
+        else:
+            raise SystemError('intent(inout) should have failed on sequence')
+
+    def test_f_inout_23seq(self):
+        obj = array(self.num23seq, dtype=self.type.dtype, order='F')
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        a = self.array(shape, intent.in_.inout, obj)
+        assert_(a.has_shared_memory())
+
+        obj = array(self.num23seq, dtype=self.type.dtype, order='C')
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        try:
+            a = self.array(shape, intent.in_.inout, obj)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to initialize intent'
+                                       '(inout) array'):
+                raise
+        else:
+            raise SystemError(
+                'intent(inout) should have failed on improper array')
+
+    def test_c_inout_23seq(self):
+        obj = array(self.num23seq, dtype=self.type.dtype)
+        shape = (len(self.num23seq), len(self.num23seq[0]))
+        a = self.array(shape, intent.in_.c.inout, obj)
+        assert_(a.has_shared_memory())
+
+    def test_in_copy_from_2casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num2seq, dtype=t.dtype)
+            a = self.array([len(self.num2seq)], intent.in_.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_in_from_23seq(self):
+        a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                       intent.in_, self.num23seq)
+        assert_(not a.has_shared_memory())
+
+    def test_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_f_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype, order='F')
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_, obj)
+            if t.elsize == self.type.elsize:
+                assert_(a.has_shared_memory(), repr(t.dtype))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.c, obj)
+            if t.elsize == self.type.elsize:
+                assert_(a.has_shared_memory(), repr(t.dtype))
+            else:
+                assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_f_copy_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype, order='F')
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_c_copy_in_from_23casttype(self):
+        for t in self.type.cast_types():
+            obj = array(self.num23seq, dtype=t.dtype)
+            a = self.array([len(self.num23seq), len(self.num23seq[0])],
+                           intent.in_.c.copy, obj)
+            assert_(not a.has_shared_memory(), repr(t.dtype))
+
+    def test_in_cache_from_2casttype(self):
+        for t in self.type.all_types():
+            if t.elsize != self.type.elsize:
+                continue
+            obj = array(self.num2seq, dtype=t.dtype)
+            shape = (len(self.num2seq),)
+            a = self.array(shape, intent.in_.c.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            a = self.array(shape, intent.in_.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            obj = array(self.num2seq, dtype=t.dtype, order='F')
+            a = self.array(shape, intent.in_.c.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            a = self.array(shape, intent.in_.cache, obj)
+            assert_(a.has_shared_memory(), repr(t.dtype))
+
+            try:
+                a = self.array(shape, intent.in_.cache, obj[::-1])
+            except ValueError as msg:
+                if not str(msg).startswith('failed to initialize'
+                                           ' intent(cache) array'):
+                    raise
+            else:
+                raise SystemError(
+                    'intent(cache) should have failed on multisegmented array')
+
+    def test_in_cache_from_2casttype_failure(self):
+        for t in self.type.all_types():
+            if t.elsize >= self.type.elsize:
+                continue
+            obj = array(self.num2seq, dtype=t.dtype)
+            shape = (len(self.num2seq),)
+            try:
+                self.array(shape, intent.in_.cache, obj)  # Should succeed
+            except ValueError as msg:
+                if not str(msg).startswith('failed to initialize'
+                                           ' intent(cache) array'):
+                    raise
+            else:
+                raise SystemError(
+                    'intent(cache) should have failed on smaller array')
+
+    def test_cache_hidden(self):
+        shape = (2,)
+        a = self.array(shape, intent.cache.hide, None)
+        assert_(a.arr.shape == shape)
+
+        shape = (2, 3)
+        a = self.array(shape, intent.cache.hide, None)
+        assert_(a.arr.shape == shape)
+
+        shape = (-1, 3)
+        try:
+            a = self.array(shape, intent.cache.hide, None)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to create intent'
+                                       '(cache|hide)|optional array'):
+                raise
+        else:
+            raise SystemError(
+                'intent(cache) should have failed on undefined dimensions')
+
+    def test_hidden(self):
+        shape = (2,)
+        a = self.array(shape, intent.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+
+        shape = (2, 3)
+        a = self.array(shape, intent.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
+
+        shape = (2, 3)
+        a = self.array(shape, intent.c.hide, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
+
+        shape = (-1, 3)
+        try:
+            a = self.array(shape, intent.hide, None)
+        except ValueError as msg:
+            if not str(msg).startswith('failed to create intent'
+                                       '(cache|hide)|optional array'):
+                raise
+        else:
+            raise SystemError('intent(hide) should have failed'
+                              ' on undefined dimensions')
+
+    def test_optional_none(self):
+        shape = (2,)
+        a = self.array(shape, intent.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+
+        shape = (2, 3)
+        a = self.array(shape, intent.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
+
+        shape = (2, 3)
+        a = self.array(shape, intent.c.optional, None)
+        assert_(a.arr.shape == shape)
+        assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+        assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
+
+    def test_optional_from_2seq(self):
+        obj = self.num2seq
+        shape = (len(obj),)
+        a = self.array(shape, intent.optional, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+    def test_optional_from_23seq(self):
+        obj = self.num23seq
+        shape = (len(obj), len(obj[0]))
+        a = self.array(shape, intent.optional, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+        a = self.array(shape, intent.optional.c, obj)
+        assert_(a.arr.shape == shape)
+        assert_(not a.has_shared_memory())
+
+    def test_inplace(self):
+        obj = array(self.num23seq, dtype=self.type.dtype)
+        assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
+        shape = obj.shape
+        a = self.array(shape, intent.inplace, obj)
+        assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
+        a.arr[1][2] = 54
+        assert_(obj[1][2] == a.arr[1][2] ==
+                array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+        assert_(a.arr is obj)
+        assert_(obj.flags['FORTRAN'])  # obj attributes are changed inplace!
+        assert_(not obj.flags['CONTIGUOUS'])
+
+    def test_inplace_from_casttype(self):
+        for t in self.type.cast_types():
+            if t is self.type:
+                continue
+            obj = array(self.num23seq, dtype=t.dtype)
+            assert_(obj.dtype.type == t.dtype)
+            assert_(obj.dtype.type is not self.type.dtype)
+            assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
+            shape = obj.shape
+            a = self.array(shape, intent.inplace, obj)
+            assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
+            a.arr[1][2] = 54
+            assert_(obj[1][2] == a.arr[1][2] ==
+                    array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+            assert_(a.arr is obj)
+            assert_(obj.flags['FORTRAN'])  # obj attributes changed inplace!
+            assert_(not obj.flags['CONTIGUOUS'])
+            assert_(obj.dtype.type is self.type.dtype)  # obj changed inplace!
+
+
+for t in _type_names:
+    exec('''\
+class test_%s_gen(unittest.TestCase,
+              _test_shared_memory
+              ):
+    def setUp(self):
+        self.type = Type(%r)
+    array = lambda self,dims,intent,obj: Array(Type(%r),dims,intent,obj)
+''' % (t, t, t))
+
+if __name__ == "__main__":
+    setup()
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
new file mode 100644
index 0000000000..725e7f0c1b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
@@ -0,0 +1,35 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestAssumedShapeSumExample(util.F2PyTest):
+    sources = [_path('src', 'assumed_shape', 'foo_free.f90'),
+               _path('src', 'assumed_shape', 'foo_use.f90'),
+               _path('src', 'assumed_shape', 'precision.f90'),
+               _path('src', 'assumed_shape', 'foo_mod.f90'),
+               ]
+
+    @dec.slow
+    def test_all(self):
+        r = self.module.fsum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.sum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.sum_with_use([1, 2])
+        assert_(r == 3, repr(r))
+
+        r = self.module.mod.sum([1, 2])
+        assert_(r == 3, repr(r))
+        r = self.module.mod.fsum([1, 2])
+        assert_(r == 3, repr(r))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
new file mode 100644
index 0000000000..6824a20424
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
@@ -0,0 +1,136 @@
+from __future__ import division, absolute_import, print_function
+
+import math
+import textwrap
+
+from numpy import array
+from numpy.testing import run_module_suite, assert_, assert_equal, dec
+import util
+
+
+class TestF77Callback(util.F2PyTest):
+    code = """
+       subroutine t(fun,a)
+       integer a
+cf2py  intent(out) a
+       external fun
+       call fun(a)
+       end
+
+       subroutine func(a)
+cf2py  intent(in,out) a
+       integer a
+       a = a + 11
+       end
+
+       subroutine func0(a)
+cf2py  intent(out) a
+       integer a
+       a = 11
+       end
+
+       subroutine t2(a)
+cf2py  intent(callback) fun
+       integer a
+cf2py  intent(out) a
+       external fun
+       call fun(a)
+       end
+
+       subroutine string_callback(callback, a)
+       external callback
+       double precision callback
+       double precision a
+       character*1 r
+cf2py  intent(out) a
+       r = 'r'
+       a = callback(r)
+       end
+
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t,t2".split(","):
+            self.check_function(name)
+
+    @dec.slow
+    def test_docstring(self):
+        expected = """
+        a = t(fun,[fun_extra_args])
+
+        Wrapper for ``t``.
+
+        Parameters
+        ----------
+        fun : call-back function
+
+        Other Parameters
+        ----------------
+        fun_extra_args : input tuple, optional
+            Default: ()
+
+        Returns
+        -------
+        a : int
+
+        Notes
+        -----
+        Call-back functions::
+
+          def fun(): return a
+          Return objects:
+            a : int
+        """
+        assert_equal(self.module.t.__doc__, textwrap.dedent(expected).lstrip())
+
+    def check_function(self, name):
+        t = getattr(self.module, name)
+        r = t(lambda: 4)
+        assert_(r == 4, repr(r))
+        r = t(lambda a: 5, fun_extra_args=(6,))
+        assert_(r == 5, repr(r))
+        r = t(lambda a: a, fun_extra_args=(6,))
+        assert_(r == 6, repr(r))
+        r = t(lambda a: 5 + a, fun_extra_args=(7,))
+        assert_(r == 12, repr(r))
+        r = t(lambda a: math.degrees(a), fun_extra_args=(math.pi,))
+        assert_(r == 180, repr(r))
+        r = t(math.degrees, fun_extra_args=(math.pi,))
+        assert_(r == 180, repr(r))
+
+        r = t(self.module.func, fun_extra_args=(6,))
+        assert_(r == 17, repr(r))
+        r = t(self.module.func0)
+        assert_(r == 11, repr(r))
+        r = t(self.module.func0._cpointer)
+        assert_(r == 11, repr(r))
+
+        class A(object):
+
+            def __call__(self):
+                return 7
+
+            def mth(self):
+                return 9
+        a = A()
+        r = t(a)
+        assert_(r == 7, repr(r))
+        r = t(a.mth)
+        assert_(r == 9, repr(r))
+
+    def test_string_callback(self):
+
+        def callback(code):
+            if code == 'r':
+                return 0
+            else:
+                return 1
+
+        f = getattr(self.module, 'string_callback')
+        r = f(callback)
+        assert_(r == 0, repr(r))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
new file mode 100644
index 0000000000..2552234a15
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
@@ -0,0 +1,36 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_, dec
+from numpy.f2py.crackfortran import (
+    _selected_int_kind_func as selected_int_kind,
+    _selected_real_kind_func as selected_real_kind
+)
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestKind(util.F2PyTest):
+    sources = [_path('src', 'kind', 'foo.f90')]
+
+    @dec.slow
+    def test_all(self):
+        selectedrealkind = self.module.selectedrealkind
+        selectedintkind = self.module.selectedintkind
+
+        for i in range(40):
+            assert_(selectedintkind(i) in [selected_int_kind(i), -1],
+                    'selectedintkind(%s): expected %r but got %r' %
+                    (i, selected_int_kind(i), selectedintkind(i)))
+
+        for i in range(20):
+            assert_(selectedrealkind(i) in [selected_real_kind(i), -1],
+                    'selectedrealkind(%s): expected %r but got %r' %
+                    (i, selected_real_kind(i), selectedrealkind(i)))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
new file mode 100644
index 0000000000..9055083bfc
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
@@ -0,0 +1,40 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import textwrap
+
+from numpy.testing import run_module_suite, assert_, assert_equal, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestMixed(util.F2PyTest):
+    sources = [_path('src', 'mixed', 'foo.f'),
+               _path('src', 'mixed', 'foo_fixed.f90'),
+               _path('src', 'mixed', 'foo_free.f90')]
+
+    @dec.slow
+    def test_all(self):
+        assert_(self.module.bar11() == 11)
+        assert_(self.module.foo_fixed.bar12() == 12)
+        assert_(self.module.foo_free.bar13() == 13)
+
+    @dec.slow
+    def test_docstring(self):
+        expected = """
+        a = bar11()
+
+        Wrapper for ``bar11``.
+
+        Returns
+        -------
+        a : int
+        """
+        assert_equal(self.module.bar11.__doc__,
+                     textwrap.dedent(expected).lstrip())
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
new file mode 100644
index 0000000000..b30af0c4ca
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
@@ -0,0 +1,34 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import math
+
+import numpy as np
+from numpy.testing import dec, assert_raises, assert_equal
+
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestIntentInOut(util.F2PyTest):
+    # Check that intent(in out) translates as intent(inout)
+    sources = [_path('src', 'regression', 'inout.f90')]
+
+    @dec.slow
+    def test_inout(self):
+        # non-contiguous should raise error
+        x = np.arange(6, dtype=np.float32)[::2]
+        assert_raises(ValueError, self.module.foo, x)
+
+        # check values with contiguous array
+        x = np.arange(3, dtype=np.float32)
+        self.module.foo(x)
+        assert_equal(x, [3, 1, 2])
+
+
+if __name__ == "__main__":
+    import nose
+    nose.runmodule()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
new file mode 100644
index 0000000000..e3e2b0d7e4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
@@ -0,0 +1,148 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import asbytes
+from numpy.testing import run_module_suite, assert_, dec
+import util
+
+
+class TestReturnCharacter(util.F2PyTest):
+
+    def check_function(self, t):
+        tname = t.__doc__.split()[0]
+        if tname in ['t0', 't1', 's0', 's1']:
+            assert_(t(23) == asbytes('2'))
+            r = t('ab')
+            assert_(r == asbytes('a'), repr(r))
+            r = t(array('ab'))
+            assert_(r == asbytes('a'), repr(r))
+            r = t(array(77, 'u1'))
+            assert_(r == asbytes('M'), repr(r))
+            #assert_(_raises(ValueError, t, array([77,87])))
+            #assert_(_raises(ValueError, t, array(77)))
+        elif tname in ['ts', 'ss']:
+            assert_(t(23) == asbytes('23        '), repr(t(23)))
+            assert_(t('123456789abcdef') == asbytes('123456789a'))
+        elif tname in ['t5', 's5']:
+            assert_(t(23) == asbytes('23   '), repr(t(23)))
+            assert_(t('ab') == asbytes('ab   '), repr(t('ab')))
+            assert_(t('123456789abcdef') == asbytes('12345'))
+        else:
+            raise NotImplementedError
+
+
+class TestF77ReturnCharacter(TestReturnCharacter):
+    code = """
+       function t0(value)
+         character value
+         character t0
+         t0 = value
+       end
+       function t1(value)
+         character*1 value
+         character*1 t1
+         t1 = value
+       end
+       function t5(value)
+         character*5 value
+         character*5 t5
+         t5 = value
+       end
+       function ts(value)
+         character*(*) value
+         character*(*) ts
+         ts = value
+       end
+
+       subroutine s0(t0,value)
+         character value
+         character t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         character*1 value
+         character*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s5(t5,value)
+         character*5 value
+         character*5 t5
+cf2py    intent(out) t5
+         t5 = value
+       end
+       subroutine ss(ts,value)
+         character*(*) value
+         character*10 ts
+cf2py    intent(out) ts
+         ts = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t5,s0,s1,s5,ss".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnCharacter(TestReturnCharacter):
+    suffix = ".f90"
+    code = """
+module f90_return_char
+  contains
+       function t0(value)
+         character :: value
+         character :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         character(len=1) :: value
+         character(len=1) :: t1
+         t1 = value
+       end function t1
+       function t5(value)
+         character(len=5) :: value
+         character(len=5) :: t5
+         t5 = value
+       end function t5
+       function ts(value)
+         character(len=*) :: value
+         character(len=10) :: ts
+         ts = value
+       end function ts
+
+       subroutine s0(t0,value)
+         character :: value
+         character :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         character(len=1) :: value
+         character(len=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s5(t5,value)
+         character(len=5) :: value
+         character(len=5) :: t5
+!f2py    intent(out) t5
+         t5 = value
+       end subroutine s5
+       subroutine ss(ts,value)
+         character(len=*) :: value
+         character(len=10) :: ts
+!f2py    intent(out) ts
+         ts = value
+       end subroutine ss
+end module f90_return_char
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t5,ts,s0,s1,s5,ss".split(","):
+            self.check_function(getattr(self.module.f90_return_char, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
new file mode 100644
index 0000000000..88ef83e940
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
@@ -0,0 +1,170 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnComplex(util.F2PyTest):
+
+    def check_function(self, t):
+        tname = t.__doc__.split()[0]
+        if tname in ['t0', 't8', 's0', 's8']:
+            err = 1e-5
+        else:
+            err = 0.0
+        assert_(abs(t(234j) - 234.0j) <= err)
+        assert_(abs(t(234.6) - 234.6) <= err)
+        assert_(abs(t(long(234)) - 234.0) <= err)
+        assert_(abs(t(234.6 + 3j) - (234.6 + 3j)) <= err)
+        #assert_( abs(t('234')-234.)<=err)
+        #assert_( abs(t('234.6')-234.6)<=err)
+        assert_(abs(t(-234) + 234.) <= err)
+        assert_(abs(t([234]) - 234.) <= err)
+        assert_(abs(t((234,)) - 234.) <= err)
+        assert_(abs(t(array(234)) - 234.) <= err)
+        assert_(abs(t(array(23 + 4j, 'F')) - (23 + 4j)) <= err)
+        assert_(abs(t(array([234])) - 234.) <= err)
+        assert_(abs(t(array([[234]])) - 234.) <= err)
+        assert_(abs(t(array([234], 'b')) + 22.) <= err)
+        assert_(abs(t(array([234], 'h')) - 234.) <= err)
+        assert_(abs(t(array([234], 'i')) - 234.) <= err)
+        assert_(abs(t(array([234], 'l')) - 234.) <= err)
+        assert_(abs(t(array([234], 'q')) - 234.) <= err)
+        assert_(abs(t(array([234], 'f')) - 234.) <= err)
+        assert_(abs(t(array([234], 'd')) - 234.) <= err)
+        assert_(abs(t(array([234 + 3j], 'F')) - (234 + 3j)) <= err)
+        assert_(abs(t(array([234], 'D')) - 234.) <= err)
+
+        #assert_raises(TypeError, t, array([234], 'a1'))
+        assert_raises(TypeError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(TypeError, t, t)
+        assert_raises(TypeError, t, {})
+
+        try:
+            r = t(10 ** 400)
+            assert_(repr(r) in ['(inf+0j)', '(Infinity+0j)'], repr(r))
+        except OverflowError:
+            pass
+
+
+class TestF77ReturnComplex(TestReturnComplex):
+    code = """
+       function t0(value)
+         complex value
+         complex t0
+         t0 = value
+       end
+       function t8(value)
+         complex*8 value
+         complex*8 t8
+         t8 = value
+       end
+       function t16(value)
+         complex*16 value
+         complex*16 t16
+         t16 = value
+       end
+       function td(value)
+         double complex value
+         double complex td
+         td = value
+       end
+
+       subroutine s0(t0,value)
+         complex value
+         complex t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s8(t8,value)
+         complex*8 value
+         complex*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+       subroutine s16(t16,value)
+         complex*16 value
+         complex*16 t16
+cf2py    intent(out) t16
+         t16 = value
+       end
+       subroutine sd(td,value)
+         double complex value
+         double complex td
+cf2py    intent(out) td
+         td = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnComplex(TestReturnComplex):
+    suffix = ".f90"
+    code = """
+module f90_return_complex
+  contains
+       function t0(value)
+         complex :: value
+         complex :: t0
+         t0 = value
+       end function t0
+       function t8(value)
+         complex(kind=4) :: value
+         complex(kind=4) :: t8
+         t8 = value
+       end function t8
+       function t16(value)
+         complex(kind=8) :: value
+         complex(kind=8) :: t16
+         t16 = value
+       end function t16
+       function td(value)
+         double complex :: value
+         double complex :: td
+         td = value
+       end function td
+
+       subroutine s0(t0,value)
+         complex :: value
+         complex :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s8(t8,value)
+         complex(kind=4) :: value
+         complex(kind=4) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+       subroutine s16(t16,value)
+         complex(kind=8) :: value
+         complex(kind=8) :: t16
+!f2py    intent(out) t16
+         t16 = value
+       end subroutine s16
+       subroutine sd(td,value)
+         double complex :: value
+         double complex :: td
+!f2py    intent(out) td
+         td = value
+       end subroutine sd
+end module f90_return_complex
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t8,t16,td,s0,s8,s16,sd".split(","):
+            self.check_function(getattr(self.module.f90_return_complex, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
new file mode 100644
index 0000000000..00033d6988
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
@@ -0,0 +1,180 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnInteger(util.F2PyTest):
+
+    def check_function(self, t):
+        assert_(t(123) == 123, repr(t(123)))
+        assert_(t(123.6) == 123)
+        assert_(t(long(123)) == 123)
+        assert_(t('123') == 123)
+        assert_(t(-123) == -123)
+        assert_(t([123]) == 123)
+        assert_(t((123,)) == 123)
+        assert_(t(array(123)) == 123)
+        assert_(t(array([123])) == 123)
+        assert_(t(array([[123]])) == 123)
+        assert_(t(array([123], 'b')) == 123)
+        assert_(t(array([123], 'h')) == 123)
+        assert_(t(array([123], 'i')) == 123)
+        assert_(t(array([123], 'l')) == 123)
+        assert_(t(array([123], 'B')) == 123)
+        assert_(t(array([123], 'f')) == 123)
+        assert_(t(array([123], 'd')) == 123)
+
+        #assert_raises(ValueError, t, array([123],'S3'))
+        assert_raises(ValueError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(Exception, t, t)
+        assert_raises(Exception, t, {})
+
+        if t.__doc__.split()[0] in ['t8', 's8']:
+            assert_raises(OverflowError, t, 100000000000000000000000)
+            assert_raises(OverflowError, t, 10000000011111111111111.23)
+
+
+class TestF77ReturnInteger(TestReturnInteger):
+    code = """
+       function t0(value)
+         integer value
+         integer t0
+         t0 = value
+       end
+       function t1(value)
+         integer*1 value
+         integer*1 t1
+         t1 = value
+       end
+       function t2(value)
+         integer*2 value
+         integer*2 t2
+         t2 = value
+       end
+       function t4(value)
+         integer*4 value
+         integer*4 t4
+         t4 = value
+       end
+       function t8(value)
+         integer*8 value
+         integer*8 t8
+         t8 = value
+       end
+
+       subroutine s0(t0,value)
+         integer value
+         integer t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         integer*1 value
+         integer*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s2(t2,value)
+         integer*2 value
+         integer*2 t2
+cf2py    intent(out) t2
+         t2 = value
+       end
+       subroutine s4(t4,value)
+         integer*4 value
+         integer*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+       subroutine s8(t8,value)
+         integer*8 value
+         integer*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnInteger(TestReturnInteger):
+    suffix = ".f90"
+    code = """
+module f90_return_integer
+  contains
+       function t0(value)
+         integer :: value
+         integer :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         integer(kind=1) :: value
+         integer(kind=1) :: t1
+         t1 = value
+       end function t1
+       function t2(value)
+         integer(kind=2) :: value
+         integer(kind=2) :: t2
+         t2 = value
+       end function t2
+       function t4(value)
+         integer(kind=4) :: value
+         integer(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         integer(kind=8) :: value
+         integer(kind=8) :: t8
+         t8 = value
+       end function t8
+
+       subroutine s0(t0,value)
+         integer :: value
+         integer :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         integer(kind=1) :: value
+         integer(kind=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s2(t2,value)
+         integer(kind=2) :: value
+         integer(kind=2) :: t2
+!f2py    intent(out) t2
+         t2 = value
+       end subroutine s2
+       subroutine s4(t4,value)
+         integer(kind=4) :: value
+         integer(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         integer(kind=8) :: value
+         integer(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+end module f90_return_integer
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module.f90_return_integer, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
new file mode 100644
index 0000000000..f88a25d7ae
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
@@ -0,0 +1,189 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnLogical(util.F2PyTest):
+
+    def check_function(self, t):
+        assert_(t(True) == 1, repr(t(True)))
+        assert_(t(False) == 0, repr(t(False)))
+        assert_(t(0) == 0)
+        assert_(t(None) == 0)
+        assert_(t(0.0) == 0)
+        assert_(t(0j) == 0)
+        assert_(t(1j) == 1)
+        assert_(t(234) == 1)
+        assert_(t(234.6) == 1)
+        assert_(t(long(234)) == 1)
+        assert_(t(234.6 + 3j) == 1)
+        assert_(t('234') == 1)
+        assert_(t('aaa') == 1)
+        assert_(t('') == 0)
+        assert_(t([]) == 0)
+        assert_(t(()) == 0)
+        assert_(t({}) == 0)
+        assert_(t(t) == 1)
+        assert_(t(-234) == 1)
+        assert_(t(10 ** 100) == 1)
+        assert_(t([234]) == 1)
+        assert_(t((234,)) == 1)
+        assert_(t(array(234)) == 1)
+        assert_(t(array([234])) == 1)
+        assert_(t(array([[234]])) == 1)
+        assert_(t(array([234], 'b')) == 1)
+        assert_(t(array([234], 'h')) == 1)
+        assert_(t(array([234], 'i')) == 1)
+        assert_(t(array([234], 'l')) == 1)
+        assert_(t(array([234], 'f')) == 1)
+        assert_(t(array([234], 'd')) == 1)
+        assert_(t(array([234 + 3j], 'F')) == 1)
+        assert_(t(array([234], 'D')) == 1)
+        assert_(t(array(0)) == 0)
+        assert_(t(array([0])) == 0)
+        assert_(t(array([[0]])) == 0)
+        assert_(t(array([0j])) == 0)
+        assert_(t(array([1])) == 1)
+        assert_raises(ValueError, t, array([0, 0]))
+
+
+class TestF77ReturnLogical(TestReturnLogical):
+    code = """
+       function t0(value)
+         logical value
+         logical t0
+         t0 = value
+       end
+       function t1(value)
+         logical*1 value
+         logical*1 t1
+         t1 = value
+       end
+       function t2(value)
+         logical*2 value
+         logical*2 t2
+         t2 = value
+       end
+       function t4(value)
+         logical*4 value
+         logical*4 t4
+         t4 = value
+       end
+c       function t8(value)
+c         logical*8 value
+c         logical*8 t8
+c         t8 = value
+c       end
+
+       subroutine s0(t0,value)
+         logical value
+         logical t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s1(t1,value)
+         logical*1 value
+         logical*1 t1
+cf2py    intent(out) t1
+         t1 = value
+       end
+       subroutine s2(t2,value)
+         logical*2 value
+         logical*2 t2
+cf2py    intent(out) t2
+         t2 = value
+       end
+       subroutine s4(t4,value)
+         logical*4 value
+         logical*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+c       subroutine s8(t8,value)
+c         logical*8 value
+c         logical*8 t8
+cf2py    intent(out) t8
+c         t8 = value
+c       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,s0,s1,s2,s4".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnLogical(TestReturnLogical):
+    suffix = ".f90"
+    code = """
+module f90_return_logical
+  contains
+       function t0(value)
+         logical :: value
+         logical :: t0
+         t0 = value
+       end function t0
+       function t1(value)
+         logical(kind=1) :: value
+         logical(kind=1) :: t1
+         t1 = value
+       end function t1
+       function t2(value)
+         logical(kind=2) :: value
+         logical(kind=2) :: t2
+         t2 = value
+       end function t2
+       function t4(value)
+         logical(kind=4) :: value
+         logical(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         logical(kind=8) :: value
+         logical(kind=8) :: t8
+         t8 = value
+       end function t8
+
+       subroutine s0(t0,value)
+         logical :: value
+         logical :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s1(t1,value)
+         logical(kind=1) :: value
+         logical(kind=1) :: t1
+!f2py    intent(out) t1
+         t1 = value
+       end subroutine s1
+       subroutine s2(t2,value)
+         logical(kind=2) :: value
+         logical(kind=2) :: t2
+!f2py    intent(out) t2
+         t2 = value
+       end subroutine s2
+       subroutine s4(t4,value)
+         logical(kind=4) :: value
+         logical(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         logical(kind=8) :: value
+         logical(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+end module f90_return_logical
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t1,t2,t4,t8,s0,s1,s2,s4,s8".split(","):
+            self.check_function(getattr(self.module.f90_return_logical, name))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
new file mode 100644
index 0000000000..57aa9badff
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
@@ -0,0 +1,206 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy import array
+from numpy.compat import long
+from numpy.testing import run_module_suite, assert_, assert_raises, dec
+import util
+
+
+class TestReturnReal(util.F2PyTest):
+
+    def check_function(self, t):
+        if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
+            err = 1e-5
+        else:
+            err = 0.0
+        assert_(abs(t(234) - 234.0) <= err)
+        assert_(abs(t(234.6) - 234.6) <= err)
+        assert_(abs(t(long(234)) - 234.0) <= err)
+        assert_(abs(t('234') - 234) <= err)
+        assert_(abs(t('234.6') - 234.6) <= err)
+        assert_(abs(t(-234) + 234) <= err)
+        assert_(abs(t([234]) - 234) <= err)
+        assert_(abs(t((234,)) - 234.) <= err)
+        assert_(abs(t(array(234)) - 234.) <= err)
+        assert_(abs(t(array([234])) - 234.) <= err)
+        assert_(abs(t(array([[234]])) - 234.) <= err)
+        assert_(abs(t(array([234], 'b')) + 22) <= err)
+        assert_(abs(t(array([234], 'h')) - 234.) <= err)
+        assert_(abs(t(array([234], 'i')) - 234.) <= err)
+        assert_(abs(t(array([234], 'l')) - 234.) <= err)
+        assert_(abs(t(array([234], 'B')) - 234.) <= err)
+        assert_(abs(t(array([234], 'f')) - 234.) <= err)
+        assert_(abs(t(array([234], 'd')) - 234.) <= err)
+        if t.__doc__.split()[0] in ['t0', 't4', 's0', 's4']:
+            assert_(t(1e200) == t(1e300))  # inf
+
+        #assert_raises(ValueError, t, array([234], 'S1'))
+        assert_raises(ValueError, t, 'abc')
+
+        assert_raises(IndexError, t, [])
+        assert_raises(IndexError, t, ())
+
+        assert_raises(Exception, t, t)
+        assert_raises(Exception, t, {})
+
+        try:
+            r = t(10 ** 400)
+            assert_(repr(r) in ['inf', 'Infinity'], repr(r))
+        except OverflowError:
+            pass
+
+
+class TestCReturnReal(TestReturnReal):
+    suffix = ".pyf"
+    module_name = "c_ext_return_real"
+    code = """
+python module c_ext_return_real
+usercode \'\'\'
+float t4(float value) { return value; }
+void s4(float *t4, float value) { *t4 = value; }
+double t8(double value) { return value; }
+void s8(double *t8, double value) { *t8 = value; }
+\'\'\'
+interface
+  function t4(value)
+    real*4 intent(c) :: t4,value
+  end
+  function t8(value)
+    real*8 intent(c) :: t8,value
+  end
+  subroutine s4(t4,value)
+    intent(c) s4
+    real*4 intent(out) :: t4
+    real*4 intent(c) :: value
+  end
+  subroutine s8(t8,value)
+    intent(c) s8
+    real*8 intent(out) :: t8
+    real*8 intent(c) :: value
+  end
+end interface
+end python module c_ext_return_real
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t4,t8,s4,s8".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF77ReturnReal(TestReturnReal):
+    code = """
+       function t0(value)
+         real value
+         real t0
+         t0 = value
+       end
+       function t4(value)
+         real*4 value
+         real*4 t4
+         t4 = value
+       end
+       function t8(value)
+         real*8 value
+         real*8 t8
+         t8 = value
+       end
+       function td(value)
+         double precision value
+         double precision td
+         td = value
+       end
+
+       subroutine s0(t0,value)
+         real value
+         real t0
+cf2py    intent(out) t0
+         t0 = value
+       end
+       subroutine s4(t4,value)
+         real*4 value
+         real*4 t4
+cf2py    intent(out) t4
+         t4 = value
+       end
+       subroutine s8(t8,value)
+         real*8 value
+         real*8 t8
+cf2py    intent(out) t8
+         t8 = value
+       end
+       subroutine sd(td,value)
+         double precision value
+         double precision td
+cf2py    intent(out) td
+         td = value
+       end
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
+            self.check_function(getattr(self.module, name))
+
+
+class TestF90ReturnReal(TestReturnReal):
+    suffix = ".f90"
+    code = """
+module f90_return_real
+  contains
+       function t0(value)
+         real :: value
+         real :: t0
+         t0 = value
+       end function t0
+       function t4(value)
+         real(kind=4) :: value
+         real(kind=4) :: t4
+         t4 = value
+       end function t4
+       function t8(value)
+         real(kind=8) :: value
+         real(kind=8) :: t8
+         t8 = value
+       end function t8
+       function td(value)
+         double precision :: value
+         double precision :: td
+         td = value
+       end function td
+
+       subroutine s0(t0,value)
+         real :: value
+         real :: t0
+!f2py    intent(out) t0
+         t0 = value
+       end subroutine s0
+       subroutine s4(t4,value)
+         real(kind=4) :: value
+         real(kind=4) :: t4
+!f2py    intent(out) t4
+         t4 = value
+       end subroutine s4
+       subroutine s8(t8,value)
+         real(kind=8) :: value
+         real(kind=8) :: t8
+!f2py    intent(out) t8
+         t8 = value
+       end subroutine s8
+       subroutine sd(td,value)
+         double precision :: value
+         double precision :: td
+!f2py    intent(out) td
+         td = value
+       end subroutine sd
+end module f90_return_real
+    """
+
+    @dec.slow
+    def test_all(self):
+        for name in "t0,t4,t8,td,s0,s4,s8,sd".split(","):
+            self.check_function(getattr(self.module.f90_return_real, name))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
new file mode 100644
index 0000000000..aeb70486a6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
@@ -0,0 +1,44 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+
+from numpy.testing import run_module_suite, assert_equal, dec
+import util
+
+
+def _path(*a):
+    return os.path.join(*((os.path.dirname(__file__),) + a))
+
+
+class TestSizeSumExample(util.F2PyTest):
+    sources = [_path('src', 'size', 'foo.f90')]
+
+    @dec.slow
+    def test_all(self):
+        r = self.module.foo([[1, 2]])
+        assert_equal(r, [3], repr(r))
+
+        r = self.module.foo([[1, 2], [3, 4]])
+        assert_equal(r, [3, 7], repr(r))
+
+        r = self.module.foo([[1, 2], [3, 4], [5, 6]])
+        assert_equal(r, [3, 7, 11], repr(r))
+
+    @dec.slow
+    def test_transpose(self):
+        r = self.module.trans([[1, 2]])
+        assert_equal(r, [[1], [2]], repr(r))
+
+        r = self.module.trans([[1, 2, 3], [4, 5, 6]])
+        assert_equal(r, [[1, 4], [2, 5], [3, 6]], repr(r))
+
+    @dec.slow
+    def test_flatten(self):
+        r = self.module.flatten([[1, 2]])
+        assert_equal(r, [1, 2], repr(r))
+
+        r = self.module.flatten([[1, 2, 3], [4, 5, 6]])
+        assert_equal(r, [1, 2, 3, 4, 5, 6], repr(r))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/util.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/util.py
new file mode 100644
index 0000000000..0c9e91568a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/tests/util.py
@@ -0,0 +1,358 @@
+"""
+Utility functions for
+
+- building and importing modules on test time, using a temporary location
+- detecting if compilers are present
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import subprocess
+import tempfile
+import shutil
+import atexit
+import textwrap
+import re
+import random
+
+from numpy.compat import asbytes, asstr
+import numpy.f2py
+from numpy.testing import SkipTest, temppath
+
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import new as md5
+
+#
+# Maintaining a temporary module directory
+#
+
+_module_dir = None
+
+
+def _cleanup():
+    global _module_dir
+    if _module_dir is not None:
+        try:
+            sys.path.remove(_module_dir)
+        except ValueError:
+            pass
+        try:
+            shutil.rmtree(_module_dir)
+        except (IOError, OSError):
+            pass
+        _module_dir = None
+
+
+def get_module_dir():
+    global _module_dir
+    if _module_dir is None:
+        _module_dir = tempfile.mkdtemp()
+        atexit.register(_cleanup)
+        if _module_dir not in sys.path:
+            sys.path.insert(0, _module_dir)
+    return _module_dir
+
+
+def get_temp_module_name():
+    # Assume single-threaded, and the module dir usable only by this thread
+    d = get_module_dir()
+    for j in range(5403, 9999999):
+        name = "_test_ext_module_%d" % j
+        fn = os.path.join(d, name)
+        if name not in sys.modules and not os.path.isfile(fn + '.py'):
+            return name
+    raise RuntimeError("Failed to create a temporary module name")
+
+
+def _memoize(func):
+    memo = {}
+
+    def wrapper(*a, **kw):
+        key = repr((a, kw))
+        if key not in memo:
+            try:
+                memo[key] = func(*a, **kw)
+            except Exception as e:
+                memo[key] = e
+                raise
+        ret = memo[key]
+        if isinstance(ret, Exception):
+            raise ret
+        return ret
+    wrapper.__name__ = func.__name__
+    return wrapper
+
+#
+# Building modules
+#
+
+
+@_memoize
+def build_module(source_files, options=[], skip=[], only=[], module_name=None):
+    """
+    Compile and import a f2py module, built from the given files.
+
+    """
+
+    code = ("import sys; sys.path = %s; import numpy.f2py as f2py2e; "
+            "f2py2e.main()" % repr(sys.path))
+
+    d = get_module_dir()
+
+    # Copy files
+    dst_sources = []
+    for fn in source_files:
+        if not os.path.isfile(fn):
+            raise RuntimeError("%s is not a file" % fn)
+        dst = os.path.join(d, os.path.basename(fn))
+        shutil.copyfile(fn, dst)
+        dst_sources.append(dst)
+
+        fn = os.path.join(os.path.dirname(fn), '.f2py_f2cmap')
+        if os.path.isfile(fn):
+            dst = os.path.join(d, os.path.basename(fn))
+            if not os.path.isfile(dst):
+                shutil.copyfile(fn, dst)
+
+    # Prepare options
+    if module_name is None:
+        module_name = get_temp_module_name()
+    f2py_opts = ['-c', '-m', module_name] + options + dst_sources
+    if skip:
+        f2py_opts += ['skip:'] + skip
+    if only:
+        f2py_opts += ['only:'] + only
+
+    # Build
+    cwd = os.getcwd()
+    try:
+        os.chdir(d)
+        cmd = [sys.executable, '-c', code] + f2py_opts
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+        if p.returncode != 0:
+            raise RuntimeError("Running f2py failed: %s\n%s"
+                               % (cmd[4:], asstr(out)))
+    finally:
+        os.chdir(cwd)
+
+        # Partial cleanup
+        for fn in dst_sources:
+            os.unlink(fn)
+
+    # Import
+    __import__(module_name)
+    return sys.modules[module_name]
+
+
+@_memoize
+def build_code(source_code, options=[], skip=[], only=[], suffix=None,
+               module_name=None):
+    """
+    Compile and import Fortran code using f2py.
+
+    """
+    if suffix is None:
+        suffix = '.f'
+    with temppath(suffix=suffix) as path:
+        with open(path, 'w') as f:
+            f.write(source_code)
+        return build_module([path], options=options, skip=skip, only=only,
+                            module_name=module_name)
+
+#
+# Check if compilers are available at all...
+#
+
+_compiler_status = None
+
+
+def _get_compiler_status():
+    global _compiler_status
+    if _compiler_status is not None:
+        return _compiler_status
+
+    _compiler_status = (False, False, False)
+
+    # XXX: this is really ugly. But I don't know how to invoke Distutils
+    #      in a safer way...
+    code = """
+import os
+import sys
+sys.path = %(syspath)s
+
+def configuration(parent_name='',top_path=None):
+    global config
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('', parent_name, top_path)
+    return config
+
+from numpy.distutils.core import setup
+setup(configuration=configuration)
+
+config_cmd = config.get_config_cmd()
+have_c = config_cmd.try_compile('void foo() {}')
+print('COMPILERS:%%d,%%d,%%d' %% (have_c,
+                                  config.have_f77c(),
+                                  config.have_f90c()))
+sys.exit(99)
+"""
+    code = code % dict(syspath=repr(sys.path))
+
+    with temppath(suffix='.py') as script:
+        with open(script, 'w') as f:
+            f.write(code)
+
+        cmd = [sys.executable, script, 'config']
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+
+    m = re.search(asbytes(r'COMPILERS:(\d+),(\d+),(\d+)'), out)
+    if m:
+        _compiler_status = (bool(int(m.group(1))), bool(int(m.group(2))),
+                            bool(int(m.group(3))))
+    # Finished
+    return _compiler_status
+
+
+def has_c_compiler():
+    return _get_compiler_status()[0]
+
+
+def has_f77_compiler():
+    return _get_compiler_status()[1]
+
+
+def has_f90_compiler():
+    return _get_compiler_status()[2]
+
+#
+# Building with distutils
+#
+
+
+@_memoize
+def build_module_distutils(source_files, config_code, module_name, **kw):
+    """
+    Build a module via distutils and import it.
+
+    """
+    from numpy.distutils.misc_util import Configuration
+    from numpy.distutils.core import setup
+
+    d = get_module_dir()
+
+    # Copy files
+    dst_sources = []
+    for fn in source_files:
+        if not os.path.isfile(fn):
+            raise RuntimeError("%s is not a file" % fn)
+        dst = os.path.join(d, os.path.basename(fn))
+        shutil.copyfile(fn, dst)
+        dst_sources.append(dst)
+
+    # Build script
+    config_code = textwrap.dedent(config_code).replace("\n", "\n    ")
+
+    code = """\
+import os
+import sys
+sys.path = %(syspath)s
+
+def configuration(parent_name='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('', parent_name, top_path)
+    %(config_code)s
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
+""" % dict(config_code=config_code, syspath=repr(sys.path))
+
+    script = os.path.join(d, get_temp_module_name() + '.py')
+    dst_sources.append(script)
+    f = open(script, 'wb')
+    f.write(asbytes(code))
+    f.close()
+
+    # Build
+    cwd = os.getcwd()
+    try:
+        os.chdir(d)
+        cmd = [sys.executable, script, 'build_ext', '-i']
+        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        out, err = p.communicate()
+        if p.returncode != 0:
+            raise RuntimeError("Running distutils build failed: %s\n%s"
+                               % (cmd[4:], asstr(out)))
+    finally:
+        os.chdir(cwd)
+
+        # Partial cleanup
+        for fn in dst_sources:
+            os.unlink(fn)
+
+    # Import
+    __import__(module_name)
+    return sys.modules[module_name]
+
+#
+# Unittest convenience
+#
+
+
+class F2PyTest(object):
+    code = None
+    sources = None
+    options = []
+    skip = []
+    only = []
+    suffix = '.f'
+    module = None
+    module_name = None
+
+    def setUp(self):
+        if self.module is not None:
+            return
+
+        # Check compiler availability first
+        if not has_c_compiler():
+            raise SkipTest("No C compiler available")
+
+        codes = []
+        if self.sources:
+            codes.extend(self.sources)
+        if self.code is not None:
+            codes.append(self.suffix)
+
+        needs_f77 = False
+        needs_f90 = False
+        for fn in codes:
+            if fn.endswith('.f'):
+                needs_f77 = True
+            elif fn.endswith('.f90'):
+                needs_f90 = True
+        if needs_f77 and not has_f77_compiler():
+            raise SkipTest("No Fortran 77 compiler available")
+        if needs_f90 and not has_f90_compiler():
+            raise SkipTest("No Fortran 90 compiler available")
+
+        # Build the module
+        if self.code is not None:
+            self.module = build_code(self.code, options=self.options,
+                                     skip=self.skip, only=self.only,
+                                     suffix=self.suffix,
+                                     module_name=self.module_name)
+
+        if self.sources is not None:
+            self.module = build_module(self.sources, options=self.options,
+                                       skip=self.skip, only=self.only,
+                                       module_name=self.module_name)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.py
new file mode 100644
index 0000000000..6acba44e2e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python2
+"""
+
+Build 'use others module data' mechanism for f2py2e.
+
+Unfinished.
+
+Copyright 2000 Pearu Peterson all rights reserved,
+Pearu Peterson <pearu@ioc.ee>
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+$Date: 2000/09/10 12:35:43 $
+Pearu Peterson
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__version__ = "$Revision: 1.3 $"[10:-1]
+
+f2py_version = 'See `f2py -v`'
+
+
+from .auxfuncs import (
+    applyrules, dictappend, gentitle, hasnote, outmess
+)
+
+
+usemodule_rules = {
+    'body': """
+#begintitle#
+static char doc_#apiname#[] = \"\\\nVariable wrapper signature:\\n\\
+\t #name# = get_#name#()\\n\\
+Arguments:\\n\\
+#docstr#\";
+extern F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#);
+static PyObject *#apiname#(PyObject *capi_self, PyObject *capi_args) {
+/*#decl#*/
+\tif (!PyArg_ParseTuple(capi_args, \"\")) goto capi_fail;
+printf(\"c: %d\\n\",F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#));
+\treturn Py_BuildValue(\"\");
+capi_fail:
+\treturn NULL;
+}
+""",
+    'method': '\t{\"get_#name#\",#apiname#,METH_VARARGS|METH_KEYWORDS,doc_#apiname#},',
+    'need': ['F_MODFUNC']
+}
+
+################
+
+
+def buildusevars(m, r):
+    ret = {}
+    outmess(
+        '\t\tBuilding use variable hooks for module "%s" (feature only for F90/F95)...\n' % (m['name']))
+    varsmap = {}
+    revmap = {}
+    if 'map' in r:
+        for k in r['map'].keys():
+            if r['map'][k] in revmap:
+                outmess('\t\t\tVariable "%s<=%s" is already mapped by "%s". Skipping.\n' % (
+                    r['map'][k], k, revmap[r['map'][k]]))
+            else:
+                revmap[r['map'][k]] = k
+    if 'only' in r and r['only']:
+        for v in r['map'].keys():
+            if r['map'][v] in m['vars']:
+
+                if revmap[r['map'][v]] == v:
+                    varsmap[v] = r['map'][v]
+                else:
+                    outmess('\t\t\tIgnoring map "%s=>%s". See above.\n' %
+                            (v, r['map'][v]))
+            else:
+                outmess(
+                    '\t\t\tNo definition for variable "%s=>%s". Skipping.\n' % (v, r['map'][v]))
+    else:
+        for v in m['vars'].keys():
+            if v in revmap:
+                varsmap[v] = revmap[v]
+            else:
+                varsmap[v] = v
+    for v in varsmap.keys():
+        ret = dictappend(ret, buildusevar(v, varsmap[v], m['vars'], m['name']))
+    return ret
+
+
+def buildusevar(name, realname, vars, usemodulename):
+    outmess('\t\t\tConstructing wrapper function for variable "%s=>%s"...\n' % (
+        name, realname))
+    ret = {}
+    vrd = {'name': name,
+           'realname': realname,
+           'REALNAME': realname.upper(),
+           'usemodulename': usemodulename,
+           'USEMODULENAME': usemodulename.upper(),
+           'texname': name.replace('_', '\\_'),
+           'begintitle': gentitle('%s=>%s' % (name, realname)),
+           'endtitle': gentitle('end of %s=>%s' % (name, realname)),
+           'apiname': '#modulename#_use_%s_from_%s' % (realname, usemodulename)
+           }
+    nummap = {0: 'Ro', 1: 'Ri', 2: 'Rii', 3: 'Riii', 4: 'Riv',
+              5: 'Rv', 6: 'Rvi', 7: 'Rvii', 8: 'Rviii', 9: 'Rix'}
+    vrd['texnamename'] = name
+    for i in nummap.keys():
+        vrd['texnamename'] = vrd['texnamename'].replace(repr(i), nummap[i])
+    if hasnote(vars[realname]):
+        vrd['note'] = vars[realname]['note']
+    rd = dictappend({}, vrd)
+
+    print(name, realname, vars[realname])
+    ret = applyrules(usemodule_rules, rd)
+    return ret
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/__init__.py
new file mode 100644
index 0000000000..a1f9e90e0a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/__init__.py
@@ -0,0 +1,11 @@
+from __future__ import division, absolute_import, print_function
+
+# To get sub-modules
+from .info import __doc__
+
+from .fftpack import *
+from .helper import *
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.py
new file mode 100644
index 0000000000..275be0d77a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.py
@@ -0,0 +1,1247 @@
+"""
+Discrete Fourier Transforms
+
+Routines in this module:
+
+fft(a, n=None, axis=-1)
+ifft(a, n=None, axis=-1)
+rfft(a, n=None, axis=-1)
+irfft(a, n=None, axis=-1)
+hfft(a, n=None, axis=-1)
+ihfft(a, n=None, axis=-1)
+fftn(a, s=None, axes=None)
+ifftn(a, s=None, axes=None)
+rfftn(a, s=None, axes=None)
+irfftn(a, s=None, axes=None)
+fft2(a, s=None, axes=(-2,-1))
+ifft2(a, s=None, axes=(-2, -1))
+rfft2(a, s=None, axes=(-2,-1))
+irfft2(a, s=None, axes=(-2, -1))
+
+i = inverse transform
+r = transform of purely real data
+h = Hermite transform
+n = n-dimensional transform
+2 = 2-dimensional transform
+(Note: 2D routines are just nD routines with different default
+behavior.)
+
+The underlying code for these functions is an f2c-translated and modified
+version of the FFTPACK routines.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['fft', 'ifft', 'rfft', 'irfft', 'hfft', 'ihfft', 'rfftn',
+           'irfftn', 'rfft2', 'irfft2', 'fft2', 'ifft2', 'fftn', 'ifftn']
+
+from numpy.core import (array, asarray, zeros, swapaxes, shape, conjugate,
+                        take, sqrt)
+from . import fftpack_lite as fftpack
+
+_fft_cache = {}
+_real_fft_cache = {}
+
+
+def _raw_fft(a, n=None, axis=-1, init_function=fftpack.cffti,
+             work_function=fftpack.cfftf, fft_cache=_fft_cache):
+    a = asarray(a)
+
+    if n is None:
+        n = a.shape[axis]
+
+    if n < 1:
+        raise ValueError("Invalid number of FFT data points (%d) specified."
+                         % n)
+
+    try:
+        # Thread-safety note: We rely on list.pop() here to atomically
+        # retrieve-and-remove a wsave from the cache.  This ensures that no
+        # other thread can get the same wsave while we're using it.
+        wsave = fft_cache.setdefault(n, []).pop()
+    except (IndexError):
+        wsave = init_function(n)
+
+    if a.shape[axis] != n:
+        s = list(a.shape)
+        if s[axis] > n:
+            index = [slice(None)]*len(s)
+            index[axis] = slice(0, n)
+            a = a[index]
+        else:
+            index = [slice(None)]*len(s)
+            index[axis] = slice(0, s[axis])
+            s[axis] = n
+            z = zeros(s, a.dtype.char)
+            z[index] = a
+            a = z
+
+    if axis != -1:
+        a = swapaxes(a, axis, -1)
+    r = work_function(a, wsave)
+    if axis != -1:
+        r = swapaxes(r, axis, -1)
+
+    # As soon as we put wsave back into the cache, another thread could pick it
+    # up and start using it, so we must not do this until after we're
+    # completely done using it ourselves.
+    fft_cache[n].append(wsave)
+
+    return r
+
+
+def _unitary(norm):
+    if norm not in (None, "ortho"):
+        raise ValueError("Invalid norm value %s, should be None or \"ortho\"."
+                         % norm)
+    return norm is not None
+
+
+def fft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional discrete Fourier Transform.
+
+    This function computes the one-dimensional *n*-point discrete Fourier
+    Transform (DFT) with the efficient Fast Fourier Transform (FFT)
+    algorithm [CT].
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    n : int, optional
+        Length of the transformed axis of the output.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros.  If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the FFT.  If not given, the last axis is
+        used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+
+    Raises
+    ------
+    IndexError
+        if `axes` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : for definition of the DFT and conventions used.
+    ifft : The inverse of `fft`.
+    fft2 : The two-dimensional FFT.
+    fftn : The *n*-dimensional FFT.
+    rfftn : The *n*-dimensional FFT of real input.
+    fftfreq : Frequency bins for given FFT parameters.
+
+    Notes
+    -----
+    FFT (Fast Fourier Transform) refers to a way the discrete Fourier
+    Transform (DFT) can be calculated efficiently, by using symmetries in the
+    calculated terms.  The symmetry is highest when `n` is a power of 2, and
+    the transform is therefore most efficient for these sizes.
+
+    The DFT is defined, with the conventions used in this implementation, in
+    the documentation for the `numpy.fft` module.
+
+    References
+    ----------
+    .. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the
+            machine calculation of complex Fourier series," *Math. Comput.*
+            19: 297-301.
+
+    Examples
+    --------
+    >>> np.fft.fft(np.exp(2j * np.pi * np.arange(8) / 8))
+    array([ -3.44505240e-16 +1.14383329e-17j,
+             8.00000000e+00 -5.71092652e-15j,
+             2.33482938e-16 +1.22460635e-16j,
+             1.64863782e-15 +1.77635684e-15j,
+             9.95839695e-17 +2.33482938e-16j,
+             0.00000000e+00 +1.66837030e-15j,
+             1.14383329e-17 +1.22460635e-16j,
+             -1.64863782e-15 +1.77635684e-15j])
+
+    >>> import matplotlib.pyplot as plt
+    >>> t = np.arange(256)
+    >>> sp = np.fft.fft(np.sin(t))
+    >>> freq = np.fft.fftfreq(t.shape[-1])
+    >>> plt.plot(freq, sp.real, freq, sp.imag)
+    [<matplotlib.lines.Line2D object at 0x...>, <matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.show()
+
+    In this example, real input has an FFT which is Hermitian, i.e., symmetric
+    in the real part and anti-symmetric in the imaginary part, as described in
+    the `numpy.fft` documentation.
+
+    """
+
+    a = asarray(a).astype(complex, copy=False)
+    if n is None:
+        n = a.shape[axis]
+    output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftf, _fft_cache)
+    if _unitary(norm):
+        output *= 1 / sqrt(n)
+    return output
+
+
+def ifft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the one-dimensional *n*-point
+    discrete Fourier transform computed by `fft`.  In other words,
+    ``ifft(fft(a)) == a`` to within numerical accuracy.
+    For a general description of the algorithm and definitions,
+    see `numpy.fft`.
+
+    The input should be ordered in the same way as is returned by `fft`,
+    i.e.,
+
+    * ``a[0]`` should contain the zero frequency term,
+    * ``a[1:n//2]`` should contain the positive-frequency terms,
+    * ``a[n//2 + 1:]`` should contain the negative-frequency terms, in
+      increasing order starting from the most negative frequency.
+
+    For an even number of input points, ``A[n//2]`` represents the sum of
+    the values at the positive and negative Nyquist frequencies, as the two
+    are aliased together. See `numpy.fft` for details.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    n : int, optional
+        Length of the transformed axis of the output.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros.  If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+        See notes about padding issues.
+    axis : int, optional
+        Axis over which to compute the inverse DFT.  If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+
+    Raises
+    ------
+    IndexError
+        If `axes` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : An introduction, with definitions and general explanations.
+    fft : The one-dimensional (forward) FFT, of which `ifft` is the inverse
+    ifft2 : The two-dimensional inverse FFT.
+    ifftn : The n-dimensional inverse FFT.
+
+    Notes
+    -----
+    If the input parameter `n` is larger than the size of the input, the input
+    is padded by appending zeros at the end.  Even though this is the common
+    approach, it might lead to surprising results.  If a different padding is
+    desired, it must be performed before calling `ifft`.
+
+    Examples
+    --------
+    >>> np.fft.ifft([0, 4, 0, 0])
+    array([ 1.+0.j,  0.+1.j, -1.+0.j,  0.-1.j])
+
+    Create and plot a band-limited signal with random phases:
+
+    >>> import matplotlib.pyplot as plt
+    >>> t = np.arange(400)
+    >>> n = np.zeros((400,), dtype=complex)
+    >>> n[40:60] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20,)))
+    >>> s = np.fft.ifft(n)
+    >>> plt.plot(t, s.real, 'b-', t, s.imag, 'r--')
+    ...
+    >>> plt.legend(('real', 'imaginary'))
+    ...
+    >>> plt.show()
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = a.shape[axis]
+    unitary = _unitary(norm)
+    output = _raw_fft(a, n, axis, fftpack.cffti, fftpack.cfftb, _fft_cache)
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def rfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the one-dimensional discrete Fourier Transform for real input.
+
+    This function computes the one-dimensional *n*-point discrete Fourier
+    Transform (DFT) of a real-valued array by means of an efficient algorithm
+    called the Fast Fourier Transform (FFT).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+    n : int, optional
+        Number of points along transformation axis in the input to use.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros. If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the FFT. If not given, the last axis is
+        used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        If `n` is even, the length of the transformed axis is ``(n/2)+1``.
+        If `n` is odd, the length is ``(n+1)/2``.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : For definition of the DFT and conventions used.
+    irfft : The inverse of `rfft`.
+    fft : The one-dimensional FFT of general (complex) input.
+    fftn : The *n*-dimensional FFT.
+    rfftn : The *n*-dimensional FFT of real input.
+
+    Notes
+    -----
+    When the DFT is computed for purely real input, the output is
+    Hermitian-symmetric, i.e. the negative frequency terms are just the complex
+    conjugates of the corresponding positive-frequency terms, and the
+    negative-frequency terms are therefore redundant.  This function does not
+    compute the negative frequency terms, and the length of the transformed
+    axis of the output is therefore ``n//2 + 1``.
+
+    When ``A = rfft(a)`` and fs is the sampling frequency, ``A[0]`` contains
+    the zero-frequency term 0*fs, which is real due to Hermitian symmetry.
+
+    If `n` is even, ``A[-1]`` contains the term representing both positive
+    and negative Nyquist frequency (+fs/2 and -fs/2), and must also be purely
+    real. If `n` is odd, there is no term at fs/2; ``A[-1]`` contains
+    the largest positive frequency (fs/2*(n-1)/n), and is complex in the
+    general case.
+
+    If the input `a` contains an imaginary part, it is silently discarded.
+
+    Examples
+    --------
+    >>> np.fft.fft([0, 1, 0, 0])
+    array([ 1.+0.j,  0.-1.j, -1.+0.j,  0.+1.j])
+    >>> np.fft.rfft([0, 1, 0, 0])
+    array([ 1.+0.j,  0.-1.j, -1.+0.j])
+
+    Notice how the final element of the `fft` output is the complex conjugate
+    of the second element, for real input. For `rfft`, this symmetry is
+    exploited to compute only the non-negative frequency terms.
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftf,
+                      _real_fft_cache)
+    if _unitary(norm):
+        output *= 1 / sqrt(a.shape[axis])
+    return output
+
+
+def irfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the inverse of the n-point DFT for real input.
+
+    This function computes the inverse of the one-dimensional *n*-point
+    discrete Fourier Transform of real input computed by `rfft`.
+    In other words, ``irfft(rfft(a), len(a)) == a`` to within numerical
+    accuracy. (See Notes below for why ``len(a)`` is necessary here.)
+
+    The input is expected to be in the form returned by `rfft`, i.e. the
+    real zero-frequency term followed by the complex positive frequency terms
+    in order of increasing frequency.  Since the discrete Fourier Transform of
+    real input is Hermitian-symmetric, the negative frequency terms are taken
+    to be the complex conjugates of the corresponding positive frequency terms.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    n : int, optional
+        Length of the transformed axis of the output.
+        For `n` output points, ``n//2+1`` input points are necessary.  If the
+        input is longer than this, it is cropped.  If it is shorter than this,
+        it is padded with zeros.  If `n` is not given, it is determined from
+        the length of the input along the axis specified by `axis`.
+    axis : int, optional
+        Axis over which to compute the inverse FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        The length of the transformed axis is `n`, or, if `n` is not given,
+        ``2*(m-1)`` where ``m`` is the length of the transformed axis of the
+        input. To get an odd number of output points, `n` must be specified.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See Also
+    --------
+    numpy.fft : For definition of the DFT and conventions used.
+    rfft : The one-dimensional FFT of real input, of which `irfft` is inverse.
+    fft : The one-dimensional FFT.
+    irfft2 : The inverse of the two-dimensional FFT of real input.
+    irfftn : The inverse of the *n*-dimensional FFT of real input.
+
+    Notes
+    -----
+    Returns the real valued `n`-point inverse discrete Fourier transform
+    of `a`, where `a` contains the non-negative frequency terms of a
+    Hermitian-symmetric sequence. `n` is the length of the result, not the
+    input.
+
+    If you specify an `n` such that `a` must be zero-padded or truncated, the
+    extra/removed values will be added/removed at high frequencies. One can
+    thus resample a series to `m` points via Fourier interpolation by:
+    ``a_resamp = irfft(rfft(a), m)``.
+
+    Examples
+    --------
+    >>> np.fft.ifft([1, -1j, -1, 1j])
+    array([ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j])
+    >>> np.fft.irfft([1, -1j, -1])
+    array([ 0.,  1.,  0.,  0.])
+
+    Notice how the last term in the input to the ordinary `ifft` is the
+    complex conjugate of the second term, and the output has zero imaginary
+    part everywhere.  When calling `irfft`, the negative frequencies are not
+    specified, and the output array is purely real.
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = (a.shape[axis] - 1) * 2
+    unitary = _unitary(norm)
+    output = _raw_fft(a, n, axis, fftpack.rffti, fftpack.rfftb,
+                      _real_fft_cache)
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def hfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the FFT of a signal which has Hermitian symmetry (real spectrum).
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    n : int, optional
+        Length of the transformed axis of the output.
+        For `n` output points, ``n//2+1`` input points are necessary.  If the
+        input is longer than this, it is cropped.  If it is shorter than this,
+        it is padded with zeros.  If `n` is not given, it is determined from
+        the length of the input along the axis specified by `axis`.
+    axis : int, optional
+        Axis over which to compute the FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        The length of the transformed axis is `n`, or, if `n` is not given,
+        ``2*(m-1)`` where ``m`` is the length of the transformed axis of the
+        input. To get an odd number of output points, `n` must be specified.
+
+    Raises
+    ------
+    IndexError
+        If `axis` is larger than the last axis of `a`.
+
+    See also
+    --------
+    rfft : Compute the one-dimensional FFT for real input.
+    ihfft : The inverse of `hfft`.
+
+    Notes
+    -----
+    `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
+    opposite case: here the signal has Hermitian symmetry in the time domain
+    and is real in the frequency domain. So here it's `hfft` for which
+    you must supply the length of the result if it is to be odd:
+    ``ihfft(hfft(a), len(a)) == a``, within numerical accuracy.
+
+    Examples
+    --------
+    >>> signal = np.array([1, 2, 3, 4, 3, 2])
+    >>> np.fft.fft(signal)
+    array([ 15.+0.j,  -4.+0.j,   0.+0.j,  -1.-0.j,   0.+0.j,  -4.+0.j])
+    >>> np.fft.hfft(signal[:4]) # Input first half of signal
+    array([ 15.,  -4.,   0.,  -1.,   0.,  -4.])
+    >>> np.fft.hfft(signal, 6)  # Input entire signal and truncate
+    array([ 15.,  -4.,   0.,  -1.,   0.,  -4.])
+
+
+    >>> signal = np.array([[1, 1.j], [-1.j, 2]])
+    >>> np.conj(signal.T) - signal   # check Hermitian symmetry
+    array([[ 0.-0.j,  0.+0.j],
+           [ 0.+0.j,  0.-0.j]])
+    >>> freq_spectrum = np.fft.hfft(signal)
+    >>> freq_spectrum
+    array([[ 1.,  1.],
+           [ 2., -2.]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    if n is None:
+        n = (a.shape[axis] - 1) * 2
+    unitary = _unitary(norm)
+    return irfft(conjugate(a), n, axis) * (sqrt(n) if unitary else n)
+
+
+def ihfft(a, n=None, axis=-1, norm=None):
+    """
+    Compute the inverse FFT of a signal which has Hermitian symmetry.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    n : int, optional
+        Length of the inverse FFT.
+        Number of points along transformation axis in the input to use.
+        If `n` is smaller than the length of the input, the input is cropped.
+        If it is larger, the input is padded with zeros. If `n` is not given,
+        the length of the input along the axis specified by `axis` is used.
+    axis : int, optional
+        Axis over which to compute the inverse FFT. If not given, the last
+        axis is used.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axis
+        indicated by `axis`, or the last one if `axis` is not specified.
+        If `n` is even, the length of the transformed axis is ``(n/2)+1``.
+        If `n` is odd, the length is ``(n+1)/2``.
+
+    See also
+    --------
+    hfft, irfft
+
+    Notes
+    -----
+    `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
+    opposite case: here the signal has Hermitian symmetry in the time domain
+    and is real in the frequency domain. So here it's `hfft` for which
+    you must supply the length of the result if it is to be odd:
+    ``ihfft(hfft(a), len(a)) == a``, within numerical accuracy.
+
+    Examples
+    --------
+    >>> spectrum = np.array([ 15, -4, 0, -1, 0, -4])
+    >>> np.fft.ifft(spectrum)
+    array([ 1.+0.j,  2.-0.j,  3.+0.j,  4.+0.j,  3.+0.j,  2.-0.j])
+    >>> np.fft.ihfft(spectrum)
+    array([ 1.-0.j,  2.-0.j,  3.-0.j,  4.-0.j])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    if n is None:
+        n = a.shape[axis]
+    unitary = _unitary(norm)
+    output = conjugate(rfft(a, n, axis))
+    return output * (1 / (sqrt(n) if unitary else n))
+
+
+def _cook_nd_args(a, s=None, axes=None, invreal=0):
+    if s is None:
+        shapeless = 1
+        if axes is None:
+            s = list(a.shape)
+        else:
+            s = take(a.shape, axes)
+    else:
+        shapeless = 0
+    s = list(s)
+    if axes is None:
+        axes = list(range(-len(s), 0))
+    if len(s) != len(axes):
+        raise ValueError("Shape and axes have different lengths.")
+    if invreal and shapeless:
+        s[-1] = (a.shape[axes[-1]] - 1) * 2
+    return s, axes
+
+
+def _raw_fftnd(a, s=None, axes=None, function=fft, norm=None):
+    a = asarray(a)
+    s, axes = _cook_nd_args(a, s, axes)
+    itl = list(range(len(axes)))
+    itl.reverse()
+    for ii in itl:
+        a = function(a, n=s[ii], axis=axes[ii], norm=norm)
+    return a
+
+
+def fftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional discrete Fourier Transform.
+
+    This function computes the *N*-dimensional discrete Fourier Transform over
+    any number of axes in an *M*-dimensional array by means of the Fast Fourier
+    Transform (FFT).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (`s[0]` refers to axis 0, `s[1]` to axis 1, etc.).
+        This corresponds to `n` for `fft(x, n)`.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the transform over that axis is
+        performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` and `a`,
+        as explained in the parameters section above.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+        and conventions used.
+    ifftn : The inverse of `fftn`, the inverse *n*-dimensional FFT.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    rfftn : The *n*-dimensional FFT of real input.
+    fft2 : The two-dimensional FFT.
+    fftshift : Shifts zero-frequency terms to centre of array
+
+    Notes
+    -----
+    The output, analogously to `fft`, contains the term for zero frequency in
+    the low-order corner of all axes, the positive frequency terms in the
+    first half of all axes, the term for the Nyquist frequency in the middle
+    of all axes and the negative frequency terms in the second half of all
+    axes, in order of decreasingly negative frequency.
+
+    See `numpy.fft` for details, definitions and conventions used.
+
+    Examples
+    --------
+    >>> a = np.mgrid[:3, :3, :3][0]
+    >>> np.fft.fftn(a, axes=(1, 2))
+    array([[[  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]],
+           [[  9.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]],
+           [[ 18.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j],
+            [  0.+0.j,   0.+0.j,   0.+0.j]]])
+    >>> np.fft.fftn(a, (2, 2), axes=(0, 1))
+    array([[[ 2.+0.j,  2.+0.j,  2.+0.j],
+            [ 0.+0.j,  0.+0.j,  0.+0.j]],
+           [[-2.+0.j, -2.+0.j, -2.+0.j],
+            [ 0.+0.j,  0.+0.j,  0.+0.j]]])
+
+    >>> import matplotlib.pyplot as plt
+    >>> [X, Y] = np.meshgrid(2 * np.pi * np.arange(200) / 12,
+    ...                      2 * np.pi * np.arange(200) / 34)
+    >>> S = np.sin(X) + np.cos(Y) + np.random.uniform(0, 1, X.shape)
+    >>> FS = np.fft.fftn(S)
+    >>> plt.imshow(np.log(np.abs(np.fft.fftshift(FS))**2))
+    <matplotlib.image.AxesImage object at 0x...>
+    >>> plt.show()
+
+    """
+
+    return _raw_fftnd(a, s, axes, fft, norm)
+
+
+def ifftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the N-dimensional discrete
+    Fourier Transform over any number of axes in an M-dimensional array by
+    means of the Fast Fourier Transform (FFT).  In other words,
+    ``ifftn(fftn(a)) == a`` to within numerical accuracy.
+    For a description of the definitions and conventions used, see `numpy.fft`.
+
+    The input, analogously to `ifft`, should be ordered in the same way as is
+    returned by `fftn`, i.e. it should have the term for zero frequency
+    in all axes in the low-order corner, the positive frequency terms in the
+    first half of all axes, the term for the Nyquist frequency in the middle
+    of all axes and the negative frequency terms in the second half of all
+    axes, in order of decreasingly negative frequency.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
+        This corresponds to ``n`` for ``ifft(x, n)``.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.  See notes for issue on `ifft` zero padding.
+    axes : sequence of ints, optional
+        Axes over which to compute the IFFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the inverse transform over that
+        axis is performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` or `a`,
+        as explained in the parameters section above.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    fftn : The forward *n*-dimensional FFT, of which `ifftn` is the inverse.
+    ifft : The one-dimensional inverse FFT.
+    ifft2 : The two-dimensional inverse FFT.
+    ifftshift : Undoes `fftshift`, shifts zero-frequency terms to beginning
+        of array.
+
+    Notes
+    -----
+    See `numpy.fft` for definitions and conventions used.
+
+    Zero-padding, analogously with `ifft`, is performed by appending zeros to
+    the input along the specified dimension.  Although this is the common
+    approach, it might lead to surprising results.  If another form of zero
+    padding is desired, it must be performed before `ifftn` is called.
+
+    Examples
+    --------
+    >>> a = np.eye(4)
+    >>> np.fft.ifftn(np.fft.fftn(a, axes=(0,)), axes=(1,))
+    array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j]])
+
+
+    Create and plot an image with band-limited frequency content:
+
+    >>> import matplotlib.pyplot as plt
+    >>> n = np.zeros((200,200), dtype=complex)
+    >>> n[60:80, 20:40] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20, 20)))
+    >>> im = np.fft.ifftn(n).real
+    >>> plt.imshow(im)
+    <matplotlib.image.AxesImage object at 0x...>
+    >>> plt.show()
+
+    """
+
+    return _raw_fftnd(a, s, axes, ifft, norm)
+
+
+def fft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional discrete Fourier Transform
+
+    This function computes the *n*-dimensional discrete Fourier Transform
+    over any axes in an *M*-dimensional array by means of the
+    Fast Fourier Transform (FFT).  By default, the transform is computed over
+    the last two axes of the input array, i.e., a 2-dimensional FFT.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (`s[0]` refers to axis 0, `s[1]` to axis 1, etc.).
+        This corresponds to `n` for `fft(x, n)`.
+        Along each axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last two
+        axes are used.  A repeated index in `axes` means the transform over
+        that axis is performed multiple times.  A one-element sequence means
+        that a one-dimensional FFT is performed.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or the last two axes if `axes` is not given.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length, or `axes` not given and
+        ``len(s) != 2``.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    ifft2 : The inverse two-dimensional FFT.
+    fft : The one-dimensional FFT.
+    fftn : The *n*-dimensional FFT.
+    fftshift : Shifts zero-frequency terms to the center of the array.
+        For two-dimensional input, swaps first and third quadrants, and second
+        and fourth quadrants.
+
+    Notes
+    -----
+    `fft2` is just `fftn` with a different default for `axes`.
+
+    The output, analogously to `fft`, contains the term for zero frequency in
+    the low-order corner of the transformed axes, the positive frequency terms
+    in the first half of these axes, the term for the Nyquist frequency in the
+    middle of the axes and the negative frequency terms in the second half of
+    the axes, in order of decreasingly negative frequency.
+
+    See `fftn` for details and a plotting example, and `numpy.fft` for
+    definitions and conventions used.
+
+
+    Examples
+    --------
+    >>> a = np.mgrid[:5, :5][0]
+    >>> np.fft.fft2(a)
+    array([[ 50.0 +0.j        ,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5+17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5 +4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5 -4.0614962j ,   0.0 +0.j        ,   0.0 +0.j        ,
+                0.0 +0.j        ,   0.0 +0.j        ],
+           [-12.5-17.20477401j,   0.0 +0.j        ,   0.0 +0.j        ,
+              0.0 +0.j        ,   0.0 +0.j        ]])
+
+    """
+
+    return _raw_fftnd(a, s, axes, fft, norm)
+
+
+def ifft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional inverse discrete Fourier Transform.
+
+    This function computes the inverse of the 2-dimensional discrete Fourier
+    Transform over any number of axes in an M-dimensional array by means of
+    the Fast Fourier Transform (FFT).  In other words, ``ifft2(fft2(a)) == a``
+    to within numerical accuracy.  By default, the inverse transform is
+    computed over the last two axes of the input array.
+
+    The input, analogously to `ifft`, should be ordered in the same way as is
+    returned by `fft2`, i.e. it should have the term for zero frequency
+    in the low-order corner of the two axes, the positive frequency terms in
+    the first half of these axes, the term for the Nyquist frequency in the
+    middle of the axes and the negative frequency terms in the second half of
+    both axes, in order of decreasingly negative frequency.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, can be complex.
+    s : sequence of ints, optional
+        Shape (length of each axis) of the output (``s[0]`` refers to axis 0,
+        ``s[1]`` to axis 1, etc.).  This corresponds to `n` for ``ifft(x, n)``.
+        Along each axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.  See notes for issue on `ifft` zero padding.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last two
+        axes are used.  A repeated index in `axes` means the transform over
+        that axis is performed multiple times.  A one-element sequence means
+        that a one-dimensional FFT is performed.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or the last two axes if `axes` is not given.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length, or `axes` not given and
+        ``len(s) != 2``.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    numpy.fft : Overall view of discrete Fourier transforms, with definitions
+         and conventions used.
+    fft2 : The forward 2-dimensional FFT, of which `ifft2` is the inverse.
+    ifftn : The inverse of the *n*-dimensional FFT.
+    fft : The one-dimensional FFT.
+    ifft : The one-dimensional inverse FFT.
+
+    Notes
+    -----
+    `ifft2` is just `ifftn` with a different default for `axes`.
+
+    See `ifftn` for details and a plotting example, and `numpy.fft` for
+    definition and conventions used.
+
+    Zero-padding, analogously with `ifft`, is performed by appending zeros to
+    the input along the specified dimension.  Although this is the common
+    approach, it might lead to surprising results.  If another form of zero
+    padding is desired, it must be performed before `ifft2` is called.
+
+    Examples
+    --------
+    >>> a = 4 * np.eye(4)
+    >>> np.fft.ifft2(a)
+    array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
+           [ 0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j],
+           [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
+           [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j]])
+
+    """
+
+    return _raw_fftnd(a, s, axes, ifft, norm)
+
+
+def rfftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the N-dimensional discrete Fourier Transform for real input.
+
+    This function computes the N-dimensional discrete Fourier Transform over
+    any number of axes in an M-dimensional real array by means of the Fast
+    Fourier Transform (FFT).  By default, all axes are transformed, with the
+    real transform performed over the last axis, while the remaining
+    transforms are complex.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, taken to be real.
+    s : sequence of ints, optional
+        Shape (length along each transformed axis) to use from the input.
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
+        The final element of `s` corresponds to `n` for ``rfft(x, n)``, while
+        for the remaining axes, it corresponds to `n` for ``fft(x, n)``.
+        Along any axis, if the given shape is smaller than that of the input,
+        the input is cropped.  If it is larger, the input is padded with zeros.
+        if `s` is not given, the shape of the input along the axes specified
+        by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.  If not given, the last ``len(s)``
+        axes are used, or all axes if `s` is also not specified.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : complex ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` and `a`,
+        as explained in the parameters section above.
+        The length of the last axis transformed will be ``s[-1]//2+1``,
+        while the remaining transformed axes will have lengths according to
+        `s`, or unchanged from the input.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    irfftn : The inverse of `rfftn`, i.e. the inverse of the n-dimensional FFT
+         of real input.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    rfft : The one-dimensional FFT of real input.
+    fftn : The n-dimensional FFT.
+    rfft2 : The two-dimensional FFT of real input.
+
+    Notes
+    -----
+    The transform for real input is performed over the last transformation
+    axis, as by `rfft`, then the transform over the remaining axes is
+    performed as by `fftn`.  The order of the output is as for `rfft` for the
+    final transformation axis, and as for `fftn` for the remaining
+    transformation axes.
+
+    See `fft` for details, definitions and conventions used.
+
+    Examples
+    --------
+    >>> a = np.ones((2, 2, 2))
+    >>> np.fft.rfftn(a)
+    array([[[ 8.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]],
+           [[ 0.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]]])
+
+    >>> np.fft.rfftn(a, axes=(2, 0))
+    array([[[ 4.+0.j,  0.+0.j],
+            [ 4.+0.j,  0.+0.j]],
+           [[ 0.+0.j,  0.+0.j],
+            [ 0.+0.j,  0.+0.j]]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=float)
+    s, axes = _cook_nd_args(a, s, axes)
+    a = rfft(a, s[-1], axes[-1], norm)
+    for ii in range(len(axes)-1):
+        a = fft(a, s[ii], axes[ii], norm)
+    return a
+
+
+def rfft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional FFT of a real array.
+
+    Parameters
+    ----------
+    a : array
+        Input array, taken to be real.
+    s : sequence of ints, optional
+        Shape of the FFT.
+    axes : sequence of ints, optional
+        Axes over which to compute the FFT.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The result of the real 2-D FFT.
+
+    See Also
+    --------
+    rfftn : Compute the N-dimensional discrete Fourier Transform for real
+            input.
+
+    Notes
+    -----
+    This is really just `rfftn` with different default behavior.
+    For more details see `rfftn`.
+
+    """
+
+    return rfftn(a, s, axes, norm)
+
+
+def irfftn(a, s=None, axes=None, norm=None):
+    """
+    Compute the inverse of the N-dimensional FFT of real input.
+
+    This function computes the inverse of the N-dimensional discrete
+    Fourier Transform for real input over any number of axes in an
+    M-dimensional array by means of the Fast Fourier Transform (FFT).  In
+    other words, ``irfftn(rfftn(a), a.shape) == a`` to within numerical
+    accuracy. (The ``a.shape`` is necessary like ``len(a)`` is for `irfft`,
+    and for the same reason.)
+
+    The input should be ordered in the same way as is returned by `rfftn`,
+    i.e. as for `irfft` for the final transformation axis, and as for `ifftn`
+    along all the other axes.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    s : sequence of ints, optional
+        Shape (length of each transformed axis) of the output
+        (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the
+        number of input points used along this axis, except for the last axis,
+        where ``s[-1]//2+1`` points of the input are used.
+        Along any axis, if the shape indicated by `s` is smaller than that of
+        the input, the input is cropped.  If it is larger, the input is padded
+        with zeros. If `s` is not given, the shape of the input along the
+        axes specified by `axes` is used.
+    axes : sequence of ints, optional
+        Axes over which to compute the inverse FFT. If not given, the last
+        `len(s)` axes are used, or all axes if `s` is also not specified.
+        Repeated indices in `axes` means that the inverse transform over that
+        axis is performed multiple times.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The truncated or zero-padded input, transformed along the axes
+        indicated by `axes`, or by a combination of `s` or `a`,
+        as explained in the parameters section above.
+        The length of each transformed axis is as given by the corresponding
+        element of `s`, or the length of the input in every axis except for the
+        last one if `s` is not given.  In the final transformed axis the length
+        of the output when `s` is not given is ``2*(m-1)`` where ``m`` is the
+        length of the final transformed axis of the input.  To get an odd
+        number of output points in the final axis, `s` must be specified.
+
+    Raises
+    ------
+    ValueError
+        If `s` and `axes` have different length.
+    IndexError
+        If an element of `axes` is larger than than the number of axes of `a`.
+
+    See Also
+    --------
+    rfftn : The forward n-dimensional FFT of real input,
+            of which `ifftn` is the inverse.
+    fft : The one-dimensional FFT, with definitions and conventions used.
+    irfft : The inverse of the one-dimensional FFT of real input.
+    irfft2 : The inverse of the two-dimensional FFT of real input.
+
+    Notes
+    -----
+    See `fft` for definitions and conventions used.
+
+    See `rfft` for definitions and conventions used for real input.
+
+    Examples
+    --------
+    >>> a = np.zeros((3, 2, 2))
+    >>> a[0, 0, 0] = 3 * 2 * 2
+    >>> np.fft.irfftn(a)
+    array([[[ 1.,  1.],
+            [ 1.,  1.]],
+           [[ 1.,  1.],
+            [ 1.,  1.]],
+           [[ 1.,  1.],
+            [ 1.,  1.]]])
+
+    """
+    # The copy may be required for multithreading.
+    a = array(a, copy=True, dtype=complex)
+    s, axes = _cook_nd_args(a, s, axes, invreal=1)
+    for ii in range(len(axes)-1):
+        a = ifft(a, s[ii], axes[ii], norm)
+    a = irfft(a, s[-1], axes[-1], norm)
+    return a
+
+
+def irfft2(a, s=None, axes=(-2, -1), norm=None):
+    """
+    Compute the 2-dimensional inverse FFT of a real array.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array
+    s : sequence of ints, optional
+        Shape of the inverse FFT.
+    axes : sequence of ints, optional
+        The axes over which to compute the inverse fft.
+        Default is the last two axes.
+    norm : {None, "ortho"}, optional
+        .. versionadded:: 1.10.0
+        Normalization mode (see `numpy.fft`). Default is None.
+
+    Returns
+    -------
+    out : ndarray
+        The result of the inverse real 2-D FFT.
+
+    See Also
+    --------
+    irfftn : Compute the inverse of the N-dimensional FFT of real input.
+
+    Notes
+    -----
+    This is really `irfftn` with different defaults.
+    For more details see `irfftn`.
+
+    """
+
+    return irfftn(a, s, axes, norm)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..86425f24a0fb6145a7d8f3c4cc38cbcd48e3cb0f
GIT binary patch
literal 49152
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
TNWTGu53&g=GW^4Pkogb*2Ol0+

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/helper.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/helper.py
new file mode 100644
index 0000000000..160120e585
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/helper.py
@@ -0,0 +1,224 @@
+"""
+Discrete Fourier Transforms - helper.py
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.compat import integer_types
+from numpy.core import (
+        asarray, concatenate, arange, take, integer, empty
+        )
+
+# Created by Pearu Peterson, September 2002
+
+__all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq']
+
+integer_types = integer_types + (integer,)
+
+
+def fftshift(x, axes=None):
+    """
+    Shift the zero-frequency component to the center of the spectrum.
+
+    This function swaps half-spaces for all axes listed (defaults to all).
+    Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+    axes : int or shape tuple, optional
+        Axes over which to shift.  Default is None, which shifts all axes.
+
+    Returns
+    -------
+    y : ndarray
+        The shifted array.
+
+    See Also
+    --------
+    ifftshift : The inverse of `fftshift`.
+
+    Examples
+    --------
+    >>> freqs = np.fft.fftfreq(10, 0.1)
+    >>> freqs
+    array([ 0.,  1.,  2.,  3.,  4., -5., -4., -3., -2., -1.])
+    >>> np.fft.fftshift(freqs)
+    array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
+
+    Shift the zero-frequency component only along the second axis:
+
+    >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
+    >>> freqs
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+    >>> np.fft.fftshift(freqs, axes=(1,))
+    array([[ 2.,  0.,  1.],
+           [-4.,  3.,  4.],
+           [-1., -3., -2.]])
+
+    """
+    tmp = asarray(x)
+    ndim = len(tmp.shape)
+    if axes is None:
+        axes = list(range(ndim))
+    elif isinstance(axes, integer_types):
+        axes = (axes,)
+    y = tmp
+    for k in axes:
+        n = tmp.shape[k]
+        p2 = (n+1)//2
+        mylist = concatenate((arange(p2, n), arange(p2)))
+        y = take(y, mylist, k)
+    return y
+
+
+def ifftshift(x, axes=None):
+    """
+    The inverse of `fftshift`. Although identical for even-length `x`, the
+    functions differ by one sample for odd-length `x`.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+    axes : int or shape tuple, optional
+        Axes over which to calculate.  Defaults to None, which shifts all axes.
+
+    Returns
+    -------
+    y : ndarray
+        The shifted array.
+
+    See Also
+    --------
+    fftshift : Shift zero-frequency component to the center of the spectrum.
+
+    Examples
+    --------
+    >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
+    >>> freqs
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+    >>> np.fft.ifftshift(np.fft.fftshift(freqs))
+    array([[ 0.,  1.,  2.],
+           [ 3.,  4., -4.],
+           [-3., -2., -1.]])
+
+    """
+    tmp = asarray(x)
+    ndim = len(tmp.shape)
+    if axes is None:
+        axes = list(range(ndim))
+    elif isinstance(axes, integer_types):
+        axes = (axes,)
+    y = tmp
+    for k in axes:
+        n = tmp.shape[k]
+        p2 = n-(n+1)//2
+        mylist = concatenate((arange(p2, n), arange(p2)))
+        y = take(y, mylist, k)
+    return y
+
+
+def fftfreq(n, d=1.0):
+    """
+    Return the Discrete Fourier Transform sample frequencies.
+
+    The returned float array `f` contains the frequency bin centers in cycles
+    per unit of the sample spacing (with zero at the start).  For instance, if
+    the sample spacing is in seconds, then the frequency unit is cycles/second.
+
+    Given a window length `n` and a sample spacing `d`::
+
+      f = [0, 1, ...,   n/2-1,     -n/2, ..., -1] / (d*n)   if n is even
+      f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n)   if n is odd
+
+    Parameters
+    ----------
+    n : int
+        Window length.
+    d : scalar, optional
+        Sample spacing (inverse of the sampling rate). Defaults to 1.
+
+    Returns
+    -------
+    f : ndarray
+        Array of length `n` containing the sample frequencies.
+
+    Examples
+    --------
+    >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
+    >>> fourier = np.fft.fft(signal)
+    >>> n = signal.size
+    >>> timestep = 0.1
+    >>> freq = np.fft.fftfreq(n, d=timestep)
+    >>> freq
+    array([ 0.  ,  1.25,  2.5 ,  3.75, -5.  , -3.75, -2.5 , -1.25])
+
+    """
+    if not isinstance(n, integer_types):
+        raise ValueError("n should be an integer")
+    val = 1.0 / (n * d)
+    results = empty(n, int)
+    N = (n-1)//2 + 1
+    p1 = arange(0, N, dtype=int)
+    results[:N] = p1
+    p2 = arange(-(n//2), 0, dtype=int)
+    results[N:] = p2
+    return results * val
+    #return hstack((arange(0,(n-1)/2 + 1), arange(-(n/2),0))) / (n*d)
+
+
+def rfftfreq(n, d=1.0):
+    """
+    Return the Discrete Fourier Transform sample frequencies
+    (for usage with rfft, irfft).
+
+    The returned float array `f` contains the frequency bin centers in cycles
+    per unit of the sample spacing (with zero at the start).  For instance, if
+    the sample spacing is in seconds, then the frequency unit is cycles/second.
+
+    Given a window length `n` and a sample spacing `d`::
+
+      f = [0, 1, ...,     n/2-1,     n/2] / (d*n)   if n is even
+      f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n)   if n is odd
+
+    Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`)
+    the Nyquist frequency component is considered to be positive.
+
+    Parameters
+    ----------
+    n : int
+        Window length.
+    d : scalar, optional
+        Sample spacing (inverse of the sampling rate). Defaults to 1.
+
+    Returns
+    -------
+    f : ndarray
+        Array of length ``n//2 + 1`` containing the sample frequencies.
+
+    Examples
+    --------
+    >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
+    >>> fourier = np.fft.rfft(signal)
+    >>> n = signal.size
+    >>> sample_rate = 100
+    >>> freq = np.fft.fftfreq(n, d=1./sample_rate)
+    >>> freq
+    array([  0.,  10.,  20.,  30.,  40., -50., -40., -30., -20., -10.])
+    >>> freq = np.fft.rfftfreq(n, d=1./sample_rate)
+    >>> freq
+    array([  0.,  10.,  20.,  30.,  40.,  50.])
+
+    """
+    if not isinstance(n, integer_types):
+        raise ValueError("n should be an integer")
+    val = 1.0/(n*d)
+    N = n//2 + 1
+    results = arange(0, N, dtype=int)
+    return results * val
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/info.py
new file mode 100644
index 0000000000..cb6526b447
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/info.py
@@ -0,0 +1,187 @@
+"""
+Discrete Fourier Transform (:mod:`numpy.fft`)
+=============================================
+
+.. currentmodule:: numpy.fft
+
+Standard FFTs
+-------------
+
+.. autosummary::
+   :toctree: generated/
+
+   fft       Discrete Fourier transform.
+   ifft      Inverse discrete Fourier transform.
+   fft2      Discrete Fourier transform in two dimensions.
+   ifft2     Inverse discrete Fourier transform in two dimensions.
+   fftn      Discrete Fourier transform in N-dimensions.
+   ifftn     Inverse discrete Fourier transform in N dimensions.
+
+Real FFTs
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   rfft      Real discrete Fourier transform.
+   irfft     Inverse real discrete Fourier transform.
+   rfft2     Real discrete Fourier transform in two dimensions.
+   irfft2    Inverse real discrete Fourier transform in two dimensions.
+   rfftn     Real discrete Fourier transform in N dimensions.
+   irfftn    Inverse real discrete Fourier transform in N dimensions.
+
+Hermitian FFTs
+--------------
+
+.. autosummary::
+   :toctree: generated/
+
+   hfft      Hermitian discrete Fourier transform.
+   ihfft     Inverse Hermitian discrete Fourier transform.
+
+Helper routines
+---------------
+
+.. autosummary::
+   :toctree: generated/
+
+   fftfreq   Discrete Fourier Transform sample frequencies.
+   rfftfreq  DFT sample frequencies (for usage with rfft, irfft).
+   fftshift  Shift zero-frequency component to center of spectrum.
+   ifftshift Inverse of fftshift.
+
+
+Background information
+----------------------
+
+Fourier analysis is fundamentally a method for expressing a function as a
+sum of periodic components, and for recovering the function from those
+components.  When both the function and its Fourier transform are
+replaced with discretized counterparts, it is called the discrete Fourier
+transform (DFT).  The DFT has become a mainstay of numerical computing in
+part because of a very fast algorithm for computing it, called the Fast
+Fourier Transform (FFT), which was known to Gauss (1805) and was brought
+to light in its current form by Cooley and Tukey [CT]_.  Press et al. [NR]_
+provide an accessible introduction to Fourier analysis and its
+applications.
+
+Because the discrete Fourier transform separates its input into
+components that contribute at discrete frequencies, it has a great number
+of applications in digital signal processing, e.g., for filtering, and in
+this context the discretized input to the transform is customarily
+referred to as a *signal*, which exists in the *time domain*.  The output
+is called a *spectrum* or *transform* and exists in the *frequency
+domain*.
+
+Implementation details
+----------------------
+
+There are many ways to define the DFT, varying in the sign of the
+exponent, normalization, etc.  In this implementation, the DFT is defined
+as
+
+.. math::
+   A_k =  \\sum_{m=0}^{n-1} a_m \\exp\\left\\{-2\\pi i{mk \\over n}\\right\\}
+   \\qquad k = 0,\\ldots,n-1.
+
+The DFT is in general defined for complex inputs and outputs, and a
+single-frequency component at linear frequency :math:`f` is
+represented by a complex exponential
+:math:`a_m = \\exp\\{2\\pi i\\,f m\\Delta t\\}`, where :math:`\\Delta t`
+is the sampling interval.
+
+The values in the result follow so-called "standard" order: If ``A =
+fft(a, n)``, then ``A[0]`` contains the zero-frequency term (the sum of
+the signal), which is always purely real for real inputs. Then ``A[1:n/2]``
+contains the positive-frequency terms, and ``A[n/2+1:]`` contains the
+negative-frequency terms, in order of decreasingly negative frequency.
+For an even number of input points, ``A[n/2]`` represents both positive and
+negative Nyquist frequency, and is also purely real for real input.  For
+an odd number of input points, ``A[(n-1)/2]`` contains the largest positive
+frequency, while ``A[(n+1)/2]`` contains the largest negative frequency.
+The routine ``np.fft.fftfreq(n)`` returns an array giving the frequencies
+of corresponding elements in the output.  The routine
+``np.fft.fftshift(A)`` shifts transforms and their frequencies to put the
+zero-frequency components in the middle, and ``np.fft.ifftshift(A)`` undoes
+that shift.
+
+When the input `a` is a time-domain signal and ``A = fft(a)``, ``np.abs(A)``
+is its amplitude spectrum and ``np.abs(A)**2`` is its power spectrum.
+The phase spectrum is obtained by ``np.angle(A)``.
+
+The inverse DFT is defined as
+
+.. math::
+   a_m = \\frac{1}{n}\\sum_{k=0}^{n-1}A_k\\exp\\left\\{2\\pi i{mk\\over n}\\right\\}
+   \\qquad m = 0,\\ldots,n-1.
+
+It differs from the forward transform by the sign of the exponential
+argument and the default normalization by :math:`1/n`.
+
+Normalization
+-------------
+The default normalization has the direct transforms unscaled and the inverse
+transforms are scaled by :math:`1/n`. It is possible to obtain unitary
+transforms by setting the keyword argument ``norm`` to ``"ortho"`` (default is
+`None`) so that both direct and inverse transforms will be scaled by
+:math:`1/\\sqrt{n}`.
+
+Real and Hermitian transforms
+-----------------------------
+
+When the input is purely real, its transform is Hermitian, i.e., the
+component at frequency :math:`f_k` is the complex conjugate of the
+component at frequency :math:`-f_k`, which means that for real
+inputs there is no information in the negative frequency components that
+is not already available from the positive frequency components.
+The family of `rfft` functions is
+designed to operate on real inputs, and exploits this symmetry by
+computing only the positive frequency components, up to and including the
+Nyquist frequency.  Thus, ``n`` input points produce ``n/2+1`` complex
+output points.  The inverses of this family assumes the same symmetry of
+its input, and for an output of ``n`` points uses ``n/2+1`` input points.
+
+Correspondingly, when the spectrum is purely real, the signal is
+Hermitian.  The `hfft` family of functions exploits this symmetry by
+using ``n/2+1`` complex points in the input (time) domain for ``n`` real
+points in the frequency domain.
+
+In higher dimensions, FFTs are used, e.g., for image analysis and
+filtering.  The computational efficiency of the FFT means that it can
+also be a faster way to compute large convolutions, using the property
+that a convolution in the time domain is equivalent to a point-by-point
+multiplication in the frequency domain.
+
+Higher dimensions
+-----------------
+
+In two dimensions, the DFT is defined as
+
+.. math::
+   A_{kl} =  \\sum_{m=0}^{M-1} \\sum_{n=0}^{N-1}
+   a_{mn}\\exp\\left\\{-2\\pi i \\left({mk\\over M}+{nl\\over N}\\right)\\right\\}
+   \\qquad k = 0, \\ldots, M-1;\\quad l = 0, \\ldots, N-1,
+
+which extends in the obvious way to higher dimensions, and the inverses
+in higher dimensions also extend in the same way.
+
+References
+----------
+
+.. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the
+        machine calculation of complex Fourier series," *Math. Comput.*
+        19: 297-301.
+
+.. [NR] Press, W., Teukolsky, S., Vetterline, W.T., and Flannery, B.P.,
+        2007, *Numerical Recipes: The Art of Scientific Computing*, ch.
+        12-13.  Cambridge Univ. Press, Cambridge, UK.
+
+Examples
+--------
+
+For examples, see the various functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/setup.py
new file mode 100644
index 0000000000..cd99a82d7b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/setup.py
@@ -0,0 +1,19 @@
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('fft', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    # Configure fftpack_lite
+    config.add_extension('fftpack_lite',
+                         sources=['fftpack_litemodule.c', 'fftpack.c']
+                         )
+
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
new file mode 100644
index 0000000000..2e6294252e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
@@ -0,0 +1,166 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.random import random
+from numpy.testing import TestCase, run_module_suite, assert_array_almost_equal
+from numpy.testing import assert_array_equal
+import threading
+import sys
+if sys.version_info[0] >= 3:
+    import queue
+else:
+    import Queue as queue
+
+
+def fft1(x):
+    L = len(x)
+    phase = -2j*np.pi*(np.arange(L)/float(L))
+    phase = np.arange(L).reshape(-1, 1) * phase
+    return np.sum(x*np.exp(phase), axis=1)
+
+
+class TestFFTShift(TestCase):
+
+    def test_fft_n(self):
+        self.assertRaises(ValueError, np.fft.fft, [1, 2, 3], 0)
+
+
+class TestFFT1D(TestCase):
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    def test_fftn(self):
+        x = random((30, 20, 10)) + 1j*random((30, 20, 10))
+        assert_array_almost_equal(
+            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"))
+
+    def test_ifftn(self):
+        x = random((30, 20, 10)) + 1j*random((30, 20, 10))
+        assert_array_almost_equal(
+            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"))
+
+    def test_rfft(self):
+        x = random(30)
+        assert_array_almost_equal(np.fft.fft(x)[:16], np.fft.rfft(x))
+        assert_array_almost_equal(np.fft.rfft(x) / np.sqrt(30),
+                                  np.fft.rfft(x, norm="ortho"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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"))
+
+    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(
+            x_herm, np.fft.ihfft(np.fft.hfft(x_herm, norm="ortho"),
+                                 norm="ortho"))
+
+
+class TestFFTThreadSafe(TestCase):
+    threads = 16
+    input_shape = (800, 200)
+
+    def _test_mtsame(self, func, *args):
+        def worker(args, q):
+            q.put(func(*args))
+
+        q = queue.Queue()
+        expected = func(*args)
+
+        # Spin off a bunch of threads to call the same function simultaneously
+        t = [threading.Thread(target=worker, args=(args, q))
+             for i in range(self.threads)]
+        [x.start() for x in t]
+
+        [x.join() for x in t]
+        # Make sure all threads returned the correct value
+        for i in range(self.threads):
+            assert_array_equal(q.get(timeout=5), expected,
+                'Function returned wrong value in multithreaded context')
+
+    def test_fft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.fft, a)
+
+    def test_ifft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.ifft, a)
+
+    def test_rfft(self):
+        a = np.ones(self.input_shape)
+        self._test_mtsame(np.fft.rfft, a)
+
+    def test_irfft(self):
+        a = np.ones(self.input_shape) * 1+0j
+        self._test_mtsame(np.fft.irfft, a)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
new file mode 100644
index 0000000000..1811571347
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python2
+"""Test functions for fftpack.helper module
+
+Copied from fftpack.helper by Pearu Peterson, October 2005
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_array_almost_equal
+from numpy import fft
+from numpy import pi
+
+
+class TestFFTShift(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4, -4, -3, -2, -1]
+        y = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
+        assert_array_almost_equal(fft.fftshift(x), y)
+        assert_array_almost_equal(fft.ifftshift(y), x)
+        x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1]
+        y = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
+        assert_array_almost_equal(fft.fftshift(x), y)
+        assert_array_almost_equal(fft.ifftshift(y), x)
+
+    def test_inverse(self):
+        for n in [1, 4, 9, 100, 211]:
+            x = np.random.random((n,))
+            assert_array_almost_equal(fft.ifftshift(fft.fftshift(x)), x)
+
+    def test_axes_keyword(self):
+        freqs = [[0, 1, 2], [3, 4, -4], [-3, -2, -1]]
+        shifted = [[-1, -3, -2], [2, 0, 1], [-4, 3, 4]]
+        assert_array_almost_equal(fft.fftshift(freqs, axes=(0, 1)), shifted)
+        assert_array_almost_equal(fft.fftshift(freqs, axes=0),
+                fft.fftshift(freqs, axes=(0,)))
+        assert_array_almost_equal(fft.ifftshift(shifted, axes=(0, 1)), freqs)
+        assert_array_almost_equal(fft.ifftshift(shifted, axes=0),
+                fft.ifftshift(shifted, axes=(0,)))
+
+
+class TestFFTFreq(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4, -4, -3, -2, -1]
+        assert_array_almost_equal(9*fft.fftfreq(9), x)
+        assert_array_almost_equal(9*pi*fft.fftfreq(9, pi), x)
+        x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1]
+        assert_array_almost_equal(10*fft.fftfreq(10), x)
+        assert_array_almost_equal(10*pi*fft.fftfreq(10, pi), x)
+
+
+class TestRFFTFreq(TestCase):
+
+    def test_definition(self):
+        x = [0, 1, 2, 3, 4]
+        assert_array_almost_equal(9*fft.rfftfreq(9), x)
+        assert_array_almost_equal(9*pi*fft.rfftfreq(9, pi), x)
+        x = [0, 1, 2, 3, 4, 5]
+        assert_array_almost_equal(10*fft.rfftfreq(10), x)
+        assert_array_almost_equal(10*pi*fft.rfftfreq(10, pi), x)
+
+
+class TestIRFFTN(TestCase):
+
+    def test_not_last_axis_success(self):
+        ar, ai = np.random.random((2, 16, 8, 32))
+        a = ar + 1j*ai
+
+        axes = (-2,)
+
+        # Should not raise error
+        fft.irfftn(a, axes=axes)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/__init__.py
new file mode 100644
index 0000000000..1d65db55e1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/__init__.py
@@ -0,0 +1,46 @@
+from __future__ import division, absolute_import, print_function
+
+import math
+
+from .info import __doc__
+from numpy.version import version as __version__
+
+from .type_check import *
+from .index_tricks import *
+from .function_base import *
+from .nanfunctions import *
+from .shape_base import *
+from .stride_tricks import *
+from .twodim_base import *
+from .ufunclike import *
+
+from . import scimath as emath
+from .polynomial import *
+#import convertcode
+from .utils import *
+from .arraysetops import *
+from .npyio import *
+from .financial import *
+from .arrayterator import Arrayterator
+from .arraypad import *
+from ._version import *
+
+__all__ = ['emath', 'math']
+__all__ += type_check.__all__
+__all__ += index_tricks.__all__
+__all__ += function_base.__all__
+__all__ += shape_base.__all__
+__all__ += stride_tricks.__all__
+__all__ += twodim_base.__all__
+__all__ += ufunclike.__all__
+__all__ += arraypad.__all__
+__all__ += polynomial.__all__
+__all__ += utils.__all__
+__all__ += arraysetops.__all__
+__all__ += npyio.__all__
+__all__ += financial.__all__
+__all__ += nanfunctions.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.py
new file mode 100644
index 0000000000..338c8b3311
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.py
@@ -0,0 +1,666 @@
+"""A file interface for handling local and remote data files.
+
+The goal of datasource is to abstract some of the file system operations
+when dealing with data files so the researcher doesn't have to know all the
+low-level details.  Through datasource, a researcher can obtain and use a
+file with one function call, regardless of location of the file.
+
+DataSource is meant to augment standard python libraries, not replace them.
+It should work seemlessly with standard file IO operations and the os
+module.
+
+DataSource files can originate locally or remotely:
+
+- local files : '/home/guido/src/local/data.txt'
+- URLs (http, ftp, ...) : 'http://www.scipy.org/not/real/data.txt'
+
+DataSource files can also be compressed or uncompressed.  Currently only
+gzip and bz2 are supported.
+
+Example::
+
+    >>> # Create a DataSource, use os.curdir (default) for local storage.
+    >>> ds = datasource.DataSource()
+    >>>
+    >>> # Open a remote file.
+    >>> # DataSource downloads the file, stores it locally in:
+    >>> #     './www.google.com/index.html'
+    >>> # opens the file and returns a file object.
+    >>> fp = ds.open('http://www.google.com/index.html')
+    >>>
+    >>> # Use the file as you normally would
+    >>> fp.read()
+    >>> fp.close()
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import shutil
+
+_open = open
+
+
+# Using a class instead of a module-level dictionary
+# to reduce the inital 'import numpy' overhead by
+# deferring the import of bz2 and gzip until needed
+
+# TODO: .zip support, .tar support?
+class _FileOpeners(object):
+    """
+    Container for different methods to open (un-)compressed files.
+
+    `_FileOpeners` contains a dictionary that holds one method for each
+    supported file format. Attribute lookup is implemented in such a way
+    that an instance of `_FileOpeners` itself can be indexed with the keys
+    of that dictionary. Currently uncompressed files as well as files
+    compressed with ``gzip`` or ``bz2`` compression are supported.
+
+    Notes
+    -----
+    `_file_openers`, an instance of `_FileOpeners`, is made available for
+    use in the `_datasource` module.
+
+    Examples
+    --------
+    >>> np.lib._datasource._file_openers.keys()
+    [None, '.bz2', '.gz']
+    >>> np.lib._datasource._file_openers['.gz'] is gzip.open
+    True
+
+    """
+
+    def __init__(self):
+        self._loaded = False
+        self._file_openers = {None: open}
+
+    def _load(self):
+        if self._loaded:
+            return
+        try:
+            import bz2
+            self._file_openers[".bz2"] = bz2.BZ2File
+        except ImportError:
+            pass
+        try:
+            import gzip
+            self._file_openers[".gz"] = gzip.open
+        except ImportError:
+            pass
+        self._loaded = True
+
+    def keys(self):
+        """
+        Return the keys of currently supported file openers.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        keys : list
+            The keys are None for uncompressed files and the file extension
+            strings (i.e. ``'.gz'``, ``'.bz2'``) for supported compression
+            methods.
+
+        """
+        self._load()
+        return list(self._file_openers.keys())
+
+    def __getitem__(self, key):
+        self._load()
+        return self._file_openers[key]
+
+_file_openers = _FileOpeners()
+
+def open(path, mode='r', destpath=os.curdir):
+    """
+    Open `path` with `mode` and return the file object.
+
+    If ``path`` is an URL, it will be downloaded, stored in the
+    `DataSource` `destpath` directory and opened from there.
+
+    Parameters
+    ----------
+    path : str
+        Local file path or URL to open.
+    mode : str, optional
+        Mode to open `path`. Mode 'r' for reading, 'w' for writing, 'a' to
+        append. Available modes depend on the type of object specified by
+        path.  Default is 'r'.
+    destpath : str, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Returns
+    -------
+    out : file object
+        The opened file.
+
+    Notes
+    -----
+    This is a convenience function that instantiates a `DataSource` and
+    returns the file object from ``DataSource.open(path)``.
+
+    """
+
+    ds = DataSource(destpath)
+    return ds.open(path, mode)
+
+
+class DataSource (object):
+    """
+    DataSource(destpath='.')
+
+    A generic data source file (file, http, ftp, ...).
+
+    DataSources can be local files or remote files/URLs.  The files may
+    also be compressed or uncompressed. DataSource hides some of the
+    low-level details of downloading the file, allowing you to simply pass
+    in a valid file path (or URL) and obtain a file object.
+
+    Parameters
+    ----------
+    destpath : str or None, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Notes
+    -----
+    URLs require a scheme string (``http://``) to be used, without it they
+    will fail::
+
+        >>> repos = DataSource()
+        >>> repos.exists('www.google.com/index.html')
+        False
+        >>> repos.exists('http://www.google.com/index.html')
+        True
+
+    Temporary directories are deleted when the DataSource is deleted.
+
+    Examples
+    --------
+    ::
+
+        >>> ds = DataSource('/home/guido')
+        >>> urlname = 'http://www.google.com/index.html'
+        >>> gfile = ds.open('http://www.google.com/index.html')  # remote file
+        >>> ds.abspath(urlname)
+        '/home/guido/www.google.com/site/index.html'
+
+        >>> ds = DataSource(None)  # use with temporary file
+        >>> ds.open('/home/guido/foobar.txt')
+        <open file '/home/guido.foobar.txt', mode 'r' at 0x91d4430>
+        >>> ds.abspath('/home/guido/foobar.txt')
+        '/tmp/tmpy4pgsP/home/guido/foobar.txt'
+
+    """
+
+    def __init__(self, destpath=os.curdir):
+        """Create a DataSource with a local path at destpath."""
+        if destpath:
+            self._destpath = os.path.abspath(destpath)
+            self._istmpdest = False
+        else:
+            import tempfile  # deferring import to improve startup time
+            self._destpath = tempfile.mkdtemp()
+            self._istmpdest = True
+
+    def __del__(self):
+        # Remove temp directories
+        if self._istmpdest:
+            shutil.rmtree(self._destpath)
+
+    def _iszip(self, filename):
+        """Test if the filename is a zip file by looking at the file extension.
+
+        """
+        fname, ext = os.path.splitext(filename)
+        return ext in _file_openers.keys()
+
+    def _iswritemode(self, mode):
+        """Test if the given mode will open a file for writing."""
+
+        # Currently only used to test the bz2 files.
+        _writemodes = ("w", "+")
+        for c in mode:
+            if c in _writemodes:
+                return True
+        return False
+
+    def _splitzipext(self, filename):
+        """Split zip extension from filename and return filename.
+
+        *Returns*:
+            base, zip_ext : {tuple}
+
+        """
+
+        if self._iszip(filename):
+            return os.path.splitext(filename)
+        else:
+            return filename, None
+
+    def _possible_names(self, filename):
+        """Return a tuple containing compressed filename variations."""
+        names = [filename]
+        if not self._iszip(filename):
+            for zipext in _file_openers.keys():
+                if zipext:
+                    names.append(filename+zipext)
+        return names
+
+    def _isurl(self, path):
+        """Test if path is a net location.  Tests the scheme and netloc."""
+
+        # We do this here to reduce the 'import numpy' initial import time.
+        if sys.version_info[0] >= 3:
+            from urllib.parse import urlparse
+        else:
+            from urlparse import urlparse
+
+        # BUG : URLs require a scheme string ('http://') to be used.
+        #       www.google.com will fail.
+        #       Should we prepend the scheme for those that don't have it and
+        #       test that also?  Similar to the way we append .gz and test for
+        #       for compressed versions of files.
+
+        scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
+        return bool(scheme and netloc)
+
+    def _cache(self, path):
+        """Cache the file specified by path.
+
+        Creates a copy of the file in the datasource cache.
+
+        """
+        # We import these here because importing urllib2 is slow and
+        # a significant fraction of numpy's total import time.
+        if sys.version_info[0] >= 3:
+            from urllib.request import urlopen
+            from urllib.error import URLError
+        else:
+            from urllib2 import urlopen
+            from urllib2 import URLError
+
+        upath = self.abspath(path)
+
+        # ensure directory exists
+        if not os.path.exists(os.path.dirname(upath)):
+            os.makedirs(os.path.dirname(upath))
+
+        # TODO: Doesn't handle compressed files!
+        if self._isurl(path):
+            try:
+                openedurl = urlopen(path)
+                f = _open(upath, 'wb')
+                try:
+                    shutil.copyfileobj(openedurl, f)
+                finally:
+                    f.close()
+                    openedurl.close()
+            except URLError:
+                raise URLError("URL not found: %s" % path)
+        else:
+            shutil.copyfile(path, upath)
+        return upath
+
+    def _findfile(self, path):
+        """Searches for ``path`` and returns full path if found.
+
+        If path is an URL, _findfile will cache a local copy and return the
+        path to the cached file.  If path is a local file, _findfile will
+        return a path to that local file.
+
+        The search will include possible compressed versions of the file
+        and return the first occurence found.
+
+        """
+
+        # Build list of possible local file paths
+        if not self._isurl(path):
+            # Valid local paths
+            filelist = self._possible_names(path)
+            # Paths in self._destpath
+            filelist += self._possible_names(self.abspath(path))
+        else:
+            # Cached URLs in self._destpath
+            filelist = self._possible_names(self.abspath(path))
+            # Remote URLs
+            filelist = filelist + self._possible_names(path)
+
+        for name in filelist:
+            if self.exists(name):
+                if self._isurl(name):
+                    name = self._cache(name)
+                return name
+        return None
+
+    def abspath(self, path):
+        """
+        Return absolute path of file in the DataSource directory.
+
+        If `path` is an URL, then `abspath` will return either the location
+        the file exists locally or the location it would exist when opened
+        using the `open` method.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL.
+
+        Returns
+        -------
+        out : str
+            Complete path, including the `DataSource` destination directory.
+
+        Notes
+        -----
+        The functionality is based on `os.path.abspath`.
+
+        """
+        # We do this here to reduce the 'import numpy' initial import time.
+        if sys.version_info[0] >= 3:
+            from urllib.parse import urlparse
+        else:
+            from urlparse import urlparse
+
+        # TODO:  This should be more robust.  Handles case where path includes
+        #        the destpath, but not other sub-paths. Failing case:
+        #        path = /home/guido/datafile.txt
+        #        destpath = /home/alex/
+        #        upath = self.abspath(path)
+        #        upath == '/home/alex/home/guido/datafile.txt'
+
+        # handle case where path includes self._destpath
+        splitpath = path.split(self._destpath, 2)
+        if len(splitpath) > 1:
+            path = splitpath[1]
+        scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
+        netloc = self._sanitize_relative_path(netloc)
+        upath = self._sanitize_relative_path(upath)
+        return os.path.join(self._destpath, netloc, upath)
+
+    def _sanitize_relative_path(self, path):
+        """Return a sanitised relative path for which
+        os.path.abspath(os.path.join(base, path)).startswith(base)
+        """
+        last = None
+        path = os.path.normpath(path)
+        while path != last:
+            last = path
+            # Note: os.path.join treats '/' as os.sep on Windows
+            path = path.lstrip(os.sep).lstrip('/')
+            path = path.lstrip(os.pardir).lstrip('..')
+            drive, path = os.path.splitdrive(path)  # for Windows
+        return path
+
+    def exists(self, path):
+        """
+        Test if path exists.
+
+        Test if `path` exists as (and in this order):
+
+        - a local file.
+        - a remote URL that has been downloaded and stored locally in the
+          `DataSource` directory.
+        - a remote URL that has not been downloaded, but is valid and
+          accessible.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL.
+
+        Returns
+        -------
+        out : bool
+            True if `path` exists.
+
+        Notes
+        -----
+        When `path` is an URL, `exists` will return True if it's either
+        stored locally in the `DataSource` directory, or is a valid remote
+        URL.  `DataSource` does not discriminate between the two, the file
+        is accessible if it exists in either location.
+
+        """
+        # We import this here because importing urllib2 is slow and
+        # a significant fraction of numpy's total import time.
+        if sys.version_info[0] >= 3:
+            from urllib.request import urlopen
+            from urllib.error import URLError
+        else:
+            from urllib2 import urlopen
+            from urllib2 import URLError
+
+        # Test local path
+        if os.path.exists(path):
+            return True
+
+        # Test cached url
+        upath = self.abspath(path)
+        if os.path.exists(upath):
+            return True
+
+        # Test remote url
+        if self._isurl(path):
+            try:
+                netfile = urlopen(path)
+                netfile.close()
+                del(netfile)
+                return True
+            except URLError:
+                return False
+        return False
+
+    def open(self, path, mode='r'):
+        """
+        Open and return file-like object.
+
+        If `path` is an URL, it will be downloaded, stored in the
+        `DataSource` directory and opened from there.
+
+        Parameters
+        ----------
+        path : str
+            Local file path or URL to open.
+        mode : {'r', 'w', 'a'}, optional
+            Mode to open `path`.  Mode 'r' for reading, 'w' for writing,
+            'a' to append. Available modes depend on the type of object
+            specified by `path`. Default is 'r'.
+
+        Returns
+        -------
+        out : file object
+            File object.
+
+        """
+
+        # TODO: There is no support for opening a file for writing which
+        #       doesn't exist yet (creating a file).  Should there be?
+
+        # TODO: Add a ``subdir`` parameter for specifying the subdirectory
+        #       used to store URLs in self._destpath.
+
+        if self._isurl(path) and self._iswritemode(mode):
+            raise ValueError("URLs are not writeable")
+
+        # NOTE: _findfile will fail on a new file opened for writing.
+        found = self._findfile(path)
+        if found:
+            _fname, ext = self._splitzipext(found)
+            if ext == 'bz2':
+                mode.replace("+", "")
+            return _file_openers[ext](found, mode=mode)
+        else:
+            raise IOError("%s not found." % path)
+
+
+class Repository (DataSource):
+    """
+    Repository(baseurl, destpath='.')
+
+    A data repository where multiple DataSource's share a base
+    URL/directory.
+
+    `Repository` extends `DataSource` by prepending a base URL (or
+    directory) to all the files it handles. Use `Repository` when you will
+    be working with multiple files from one base URL.  Initialize
+    `Repository` with the base URL, then refer to each file by its filename
+    only.
+
+    Parameters
+    ----------
+    baseurl : str
+        Path to the local directory or remote location that contains the
+        data files.
+    destpath : str or None, optional
+        Path to the directory where the source file gets downloaded to for
+        use.  If `destpath` is None, a temporary directory will be created.
+        The default path is the current directory.
+
+    Examples
+    --------
+    To analyze all files in the repository, do something like this
+    (note: this is not self-contained code)::
+
+        >>> repos = np.lib._datasource.Repository('/home/user/data/dir/')
+        >>> for filename in filelist:
+        ...     fp = repos.open(filename)
+        ...     fp.analyze()
+        ...     fp.close()
+
+    Similarly you could use a URL for a repository::
+
+        >>> repos = np.lib._datasource.Repository('http://www.xyz.edu/data')
+
+    """
+
+    def __init__(self, baseurl, destpath=os.curdir):
+        """Create a Repository with a shared url or directory of baseurl."""
+        DataSource.__init__(self, destpath=destpath)
+        self._baseurl = baseurl
+
+    def __del__(self):
+        DataSource.__del__(self)
+
+    def _fullpath(self, path):
+        """Return complete path for path.  Prepends baseurl if necessary."""
+        splitpath = path.split(self._baseurl, 2)
+        if len(splitpath) == 1:
+            result = os.path.join(self._baseurl, path)
+        else:
+            result = path    # path contains baseurl already
+        return result
+
+    def _findfile(self, path):
+        """Extend DataSource method to prepend baseurl to ``path``."""
+        return DataSource._findfile(self, self._fullpath(path))
+
+    def abspath(self, path):
+        """
+        Return absolute path of file in the Repository directory.
+
+        If `path` is an URL, then `abspath` will return either the location
+        the file exists locally or the location it would exist when opened
+        using the `open` method.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL. This may, but does not
+            have to, include the `baseurl` with which the `Repository` was
+            initialized.
+
+        Returns
+        -------
+        out : str
+            Complete path, including the `DataSource` destination directory.
+
+        """
+        return DataSource.abspath(self, self._fullpath(path))
+
+    def exists(self, path):
+        """
+        Test if path exists prepending Repository base URL to path.
+
+        Test if `path` exists as (and in this order):
+
+        - a local file.
+        - a remote URL that has been downloaded and stored locally in the
+          `DataSource` directory.
+        - a remote URL that has not been downloaded, but is valid and
+          accessible.
+
+        Parameters
+        ----------
+        path : str
+            Can be a local file or a remote URL. This may, but does not
+            have to, include the `baseurl` with which the `Repository` was
+            initialized.
+
+        Returns
+        -------
+        out : bool
+            True if `path` exists.
+
+        Notes
+        -----
+        When `path` is an URL, `exists` will return True if it's either
+        stored locally in the `DataSource` directory, or is a valid remote
+        URL.  `DataSource` does not discriminate between the two, the file
+        is accessible if it exists in either location.
+
+        """
+        return DataSource.exists(self, self._fullpath(path))
+
+    def open(self, path, mode='r'):
+        """
+        Open and return file-like object prepending Repository base URL.
+
+        If `path` is an URL, it will be downloaded, stored in the
+        DataSource directory and opened from there.
+
+        Parameters
+        ----------
+        path : str
+            Local file path or URL to open. This may, but does not have to,
+            include the `baseurl` with which the `Repository` was
+            initialized.
+        mode : {'r', 'w', 'a'}, optional
+            Mode to open `path`.  Mode 'r' for reading, 'w' for writing,
+            'a' to append. Available modes depend on the type of object
+            specified by `path`. Default is 'r'.
+
+        Returns
+        -------
+        out : file object
+            File object.
+
+        """
+        return DataSource.open(self, self._fullpath(path), mode)
+
+    def listdir(self):
+        """
+        List files in the source Repository.
+
+        Returns
+        -------
+        files : list of str
+            List of file names (not containing a directory part).
+
+        Notes
+        -----
+        Does not currently work for remote repositories.
+
+        """
+        if self._isurl(self._baseurl):
+            raise NotImplementedError(
+                  "Directory listing of URLs, not supported yet.")
+        else:
+            return os.listdir(self._baseurl)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.py
new file mode 100644
index 0000000000..dfdc38b72e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.py
@@ -0,0 +1,930 @@
+"""A collection of functions designed to help I/O with ascii files.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__docformat__ = "restructuredtext en"
+
+import sys
+import numpy as np
+import numpy.core.numeric as nx
+from numpy.compat import asbytes, bytes, asbytes_nested, basestring
+
+if sys.version_info[0] >= 3:
+    from builtins import bool, int, float, complex, object, str
+    unicode = str
+else:
+    from __builtin__ import bool, int, float, complex, object, unicode, str
+
+
+if sys.version_info[0] >= 3:
+    def _bytes_to_complex(s):
+        return complex(s.decode('ascii'))
+
+    def _bytes_to_name(s):
+        return s.decode('ascii')
+else:
+    _bytes_to_complex = complex
+    _bytes_to_name = str
+
+
+def _is_string_like(obj):
+    """
+    Check whether obj behaves like a string.
+    """
+    try:
+        obj + ''
+    except (TypeError, ValueError):
+        return False
+    return True
+
+
+def _is_bytes_like(obj):
+    """
+    Check whether obj behaves like a bytes object.
+    """
+    try:
+        obj + asbytes('')
+    except (TypeError, ValueError):
+        return False
+    return True
+
+
+def _to_filehandle(fname, flag='r', return_opened=False):
+    """
+    Returns the filehandle corresponding to a string or a file.
+    If the string ends in '.gz', the file is automatically unzipped.
+
+    Parameters
+    ----------
+    fname : string, filehandle
+        Name of the file whose filehandle must be returned.
+    flag : string, optional
+        Flag indicating the status of the file ('r' for read, 'w' for write).
+    return_opened : boolean, optional
+        Whether to return the opening status of the file.
+    """
+    if _is_string_like(fname):
+        if fname.endswith('.gz'):
+            import gzip
+            fhd = gzip.open(fname, flag)
+        elif fname.endswith('.bz2'):
+            import bz2
+            fhd = bz2.BZ2File(fname)
+        else:
+            fhd = file(fname, flag)
+        opened = True
+    elif hasattr(fname, 'seek'):
+        fhd = fname
+        opened = False
+    else:
+        raise ValueError('fname must be a string or file handle')
+    if return_opened:
+        return fhd, opened
+    return fhd
+
+
+def has_nested_fields(ndtype):
+    """
+    Returns whether one or several fields of a dtype are nested.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        Data-type of a structured array.
+
+    Raises
+    ------
+    AttributeError
+        If `ndtype` does not have a `names` attribute.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float)])
+    >>> np.lib._iotools.has_nested_fields(dt)
+    False
+
+    """
+    for name in ndtype.names or ():
+        if ndtype[name].names:
+            return True
+    return False
+
+
+def flatten_dtype(ndtype, flatten_base=False):
+    """
+    Unpack a structured data-type by collapsing nested fields and/or fields
+    with a shape.
+
+    Note that the field names are lost.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        The datatype to collapse
+    flatten_base : {False, True}, optional
+        Whether to transform a field with a shape into several fields or not.
+
+    Examples
+    --------
+    >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+    ...                ('block', int, (2, 3))])
+    >>> np.lib._iotools.flatten_dtype(dt)
+    [dtype('|S4'), dtype('float64'), dtype('float64'), dtype('int32')]
+    >>> np.lib._iotools.flatten_dtype(dt, flatten_base=True)
+    [dtype('|S4'), dtype('float64'), dtype('float64'), dtype('int32'),
+     dtype('int32'), dtype('int32'), dtype('int32'), dtype('int32'),
+     dtype('int32')]
+
+    """
+    names = ndtype.names
+    if names is None:
+        if flatten_base:
+            return [ndtype.base] * int(np.prod(ndtype.shape))
+        return [ndtype.base]
+    else:
+        types = []
+        for field in names:
+            info = ndtype.fields[field]
+            flat_dt = flatten_dtype(info[0], flatten_base)
+            types.extend(flat_dt)
+        return types
+
+
+class LineSplitter(object):
+    """
+    Object to split a string at a given delimiter or at given places.
+
+    Parameters
+    ----------
+    delimiter : str, int, or sequence of ints, optional
+        If a string, character used to delimit consecutive fields.
+        If an integer or a sequence of integers, width(s) of each field.
+    comments : str, optional
+        Character used to mark the beginning of a comment. Default is '#'.
+    autostrip : bool, optional
+        Whether to strip each individual field. Default is True.
+
+    """
+
+    def autostrip(self, method):
+        """
+        Wrapper to strip each member of the output of `method`.
+
+        Parameters
+        ----------
+        method : function
+            Function that takes a single argument and returns a sequence of
+            strings.
+
+        Returns
+        -------
+        wrapped : function
+            The result of wrapping `method`. `wrapped` takes a single input
+            argument and returns a list of strings that are stripped of
+            white-space.
+
+        """
+        return lambda input: [_.strip() for _ in method(input)]
+    #
+
+    def __init__(self, delimiter=None, comments=asbytes('#'), autostrip=True):
+        self.comments = comments
+        # Delimiter is a character
+        if isinstance(delimiter, unicode):
+            delimiter = delimiter.encode('ascii')
+        if (delimiter is None) or _is_bytes_like(delimiter):
+            delimiter = delimiter or None
+            _handyman = self._delimited_splitter
+        # Delimiter is a list of field widths
+        elif hasattr(delimiter, '__iter__'):
+            _handyman = self._variablewidth_splitter
+            idx = np.cumsum([0] + list(delimiter))
+            delimiter = [slice(i, j) for (i, j) in zip(idx[:-1], idx[1:])]
+        # Delimiter is a single integer
+        elif int(delimiter):
+            (_handyman, delimiter) = (
+                    self._fixedwidth_splitter, int(delimiter))
+        else:
+            (_handyman, delimiter) = (self._delimited_splitter, None)
+        self.delimiter = delimiter
+        if autostrip:
+            self._handyman = self.autostrip(_handyman)
+        else:
+            self._handyman = _handyman
+    #
+
+    def _delimited_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        line = line.strip(asbytes(" \r\n"))
+        if not line:
+            return []
+        return line.split(self.delimiter)
+    #
+
+    def _fixedwidth_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        line = line.strip(asbytes("\r\n"))
+        if not line:
+            return []
+        fixed = self.delimiter
+        slices = [slice(i, i + fixed) for i in range(0, len(line), fixed)]
+        return [line[s] for s in slices]
+    #
+
+    def _variablewidth_splitter(self, line):
+        if self.comments is not None:
+            line = line.split(self.comments)[0]
+        if not line:
+            return []
+        slices = self.delimiter
+        return [line[s] for s in slices]
+    #
+
+    def __call__(self, line):
+        return self._handyman(line)
+
+
+class NameValidator(object):
+    """
+    Object to validate a list of strings to use as field names.
+
+    The strings are stripped of any non alphanumeric character, and spaces
+    are replaced by '_'. During instantiation, the user can define a list
+    of names to exclude, as well as a list of invalid characters. Names in
+    the exclusion list are appended a '_' character.
+
+    Once an instance has been created, it can be called with a list of
+    names, and a list of valid names will be created.  The `__call__`
+    method accepts an optional keyword "default" that sets the default name
+    in case of ambiguity. By default this is 'f', so that names will
+    default to `f0`, `f1`, etc.
+
+    Parameters
+    ----------
+    excludelist : sequence, optional
+        A list of names to exclude. This list is appended to the default
+        list ['return', 'file', 'print']. Excluded names are appended an
+        underscore: for example, `file` becomes `file_` if supplied.
+    deletechars : str, optional
+        A string combining invalid characters that must be deleted from the
+        names.
+    case_sensitive : {True, False, 'upper', 'lower'}, optional
+        * If True, field names are case-sensitive.
+        * If False or 'upper', field names are converted to upper case.
+        * If 'lower', field names are converted to lower case.
+
+        The default value is True.
+    replace_space : '_', optional
+        Character(s) used in replacement of white spaces.
+
+    Notes
+    -----
+    Calling an instance of `NameValidator` is the same as calling its
+    method `validate`.
+
+    Examples
+    --------
+    >>> validator = np.lib._iotools.NameValidator()
+    >>> validator(['file', 'field2', 'with space', 'CaSe'])
+    ['file_', 'field2', 'with_space', 'CaSe']
+
+    >>> validator = np.lib._iotools.NameValidator(excludelist=['excl'],
+                                                  deletechars='q',
+                                                  case_sensitive='False')
+    >>> validator(['excl', 'field2', 'no_q', 'with space', 'CaSe'])
+    ['excl_', 'field2', 'no_', 'with_space', 'case']
+
+    """
+    #
+    defaultexcludelist = ['return', 'file', 'print']
+    defaultdeletechars = set("""~!@#$%^&*()-=+~\|]}[{';: /?.>,<""")
+    #
+
+    def __init__(self, excludelist=None, deletechars=None,
+                 case_sensitive=None, replace_space='_'):
+        # Process the exclusion list ..
+        if excludelist is None:
+            excludelist = []
+        excludelist.extend(self.defaultexcludelist)
+        self.excludelist = excludelist
+        # Process the list of characters to delete
+        if deletechars is None:
+            delete = self.defaultdeletechars
+        else:
+            delete = set(deletechars)
+        delete.add('"')
+        self.deletechars = delete
+        # Process the case option .....
+        if (case_sensitive is None) or (case_sensitive is True):
+            self.case_converter = lambda x: x
+        elif (case_sensitive is False) or case_sensitive.startswith('u'):
+            self.case_converter = lambda x: x.upper()
+        elif case_sensitive.startswith('l'):
+            self.case_converter = lambda x: x.lower()
+        else:
+            msg = 'unrecognized case_sensitive value %s.' % case_sensitive
+            raise ValueError(msg)
+        #
+        self.replace_space = replace_space
+
+    def validate(self, names, defaultfmt="f%i", nbfields=None):
+        """
+        Validate a list of strings as field names for a structured array.
+
+        Parameters
+        ----------
+        names : sequence of str
+            Strings to be validated.
+        defaultfmt : str, optional
+            Default format string, used if validating a given string
+            reduces its length to zero.
+        nbfields : integer, optional
+            Final number of validated names, used to expand or shrink the
+            initial list of names.
+
+        Returns
+        -------
+        validatednames : list of str
+            The list of validated field names.
+
+        Notes
+        -----
+        A `NameValidator` instance can be called directly, which is the
+        same as calling `validate`. For examples, see `NameValidator`.
+
+        """
+        # Initial checks ..............
+        if (names is None):
+            if (nbfields is None):
+                return None
+            names = []
+        if isinstance(names, basestring):
+            names = [names, ]
+        if nbfields is not None:
+            nbnames = len(names)
+            if (nbnames < nbfields):
+                names = list(names) + [''] * (nbfields - nbnames)
+            elif (nbnames > nbfields):
+                names = names[:nbfields]
+        # Set some shortcuts ...........
+        deletechars = self.deletechars
+        excludelist = self.excludelist
+        case_converter = self.case_converter
+        replace_space = self.replace_space
+        # Initializes some variables ...
+        validatednames = []
+        seen = dict()
+        nbempty = 0
+        #
+        for item in names:
+            item = case_converter(item).strip()
+            if replace_space:
+                item = item.replace(' ', replace_space)
+            item = ''.join([c for c in item if c not in deletechars])
+            if item == '':
+                item = defaultfmt % nbempty
+                while item in names:
+                    nbempty += 1
+                    item = defaultfmt % nbempty
+                nbempty += 1
+            elif item in excludelist:
+                item += '_'
+            cnt = seen.get(item, 0)
+            if cnt > 0:
+                validatednames.append(item + '_%d' % cnt)
+            else:
+                validatednames.append(item)
+            seen[item] = cnt + 1
+        return tuple(validatednames)
+    #
+
+    def __call__(self, names, defaultfmt="f%i", nbfields=None):
+        return self.validate(names, defaultfmt=defaultfmt, nbfields=nbfields)
+
+
+def str2bool(value):
+    """
+    Tries to transform a string supposed to represent a boolean to a boolean.
+
+    Parameters
+    ----------
+    value : str
+        The string that is transformed to a boolean.
+
+    Returns
+    -------
+    boolval : bool
+        The boolean representation of `value`.
+
+    Raises
+    ------
+    ValueError
+        If the string is not 'True' or 'False' (case independent)
+
+    Examples
+    --------
+    >>> np.lib._iotools.str2bool('TRUE')
+    True
+    >>> np.lib._iotools.str2bool('false')
+    False
+
+    """
+    value = value.upper()
+    if value == asbytes('TRUE'):
+        return True
+    elif value == asbytes('FALSE'):
+        return False
+    else:
+        raise ValueError("Invalid boolean")
+
+
+class ConverterError(Exception):
+    """
+    Exception raised when an error occurs in a converter for string values.
+
+    """
+    pass
+
+
+class ConverterLockError(ConverterError):
+    """
+    Exception raised when an attempt is made to upgrade a locked converter.
+
+    """
+    pass
+
+
+class ConversionWarning(UserWarning):
+    """
+    Warning issued when a string converter has a problem.
+
+    Notes
+    -----
+    In `genfromtxt` a `ConversionWarning` is issued if raising exceptions
+    is explicitly suppressed with the "invalid_raise" keyword.
+
+    """
+    pass
+
+
+class StringConverter(object):
+    """
+    Factory class for function transforming a string into another object
+    (int, float).
+
+    After initialization, an instance can be called to transform a string
+    into another object. If the string is recognized as representing a
+    missing value, a default value is returned.
+
+    Attributes
+    ----------
+    func : function
+        Function used for the conversion.
+    default : any
+        Default value to return when the input corresponds to a missing
+        value.
+    type : type
+        Type of the output.
+    _status : int
+        Integer representing the order of the conversion.
+    _mapper : sequence of tuples
+        Sequence of tuples (dtype, function, default value) to evaluate in
+        order.
+    _locked : bool
+        Holds `locked` parameter.
+
+    Parameters
+    ----------
+    dtype_or_func : {None, dtype, function}, optional
+        If a `dtype`, specifies the input data type, used to define a basic
+        function and a default value for missing data. For example, when
+        `dtype` is float, the `func` attribute is set to `float` and the
+        default value to `np.nan`.  If a function, this function is used to
+        convert a string to another object. In this case, it is recommended
+        to give an associated default value as input.
+    default : any, optional
+        Value to return by default, that is, when the string to be
+        converted is flagged as missing. If not given, `StringConverter`
+        tries to supply a reasonable default value.
+    missing_values : sequence of str, optional
+        Sequence of strings indicating a missing value.
+    locked : bool, optional
+        Whether the StringConverter should be locked to prevent automatic
+        upgrade or not. Default is False.
+
+    """
+    #
+    _mapper = [(nx.bool_, str2bool, False),
+               (nx.integer, int, -1)]
+
+    # On 32-bit systems, we need to make sure that we explicitly include
+    # nx.int64 since ns.integer is nx.int32.
+    if nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize:
+        _mapper.append((nx.int64, int, -1))
+
+    _mapper.extend([(nx.floating, float, nx.nan),
+                    (complex, _bytes_to_complex, nx.nan + 0j),
+                    (nx.longdouble, nx.longdouble, nx.nan),
+                    (nx.string_, bytes, asbytes('???'))])
+
+    (_defaulttype, _defaultfunc, _defaultfill) = zip(*_mapper)
+
+    @classmethod
+    def _getdtype(cls, val):
+        """Returns the dtype of the input variable."""
+        return np.array(val).dtype
+    #
+
+    @classmethod
+    def _getsubdtype(cls, val):
+        """Returns the type of the dtype of the input variable."""
+        return np.array(val).dtype.type
+    #
+    # This is a bit annoying. We want to return the "general" type in most
+    # cases (ie. "string" rather than "S10"), but we want to return the
+    # specific type for datetime64 (ie. "datetime64[us]" rather than
+    # "datetime64").
+
+    @classmethod
+    def _dtypeortype(cls, dtype):
+        """Returns dtype for datetime64 and type of dtype otherwise."""
+        if dtype.type == np.datetime64:
+            return dtype
+        return dtype.type
+    #
+
+    @classmethod
+    def upgrade_mapper(cls, func, default=None):
+        """
+    Upgrade the mapper of a StringConverter by adding a new function and
+    its corresponding default.
+
+    The input function (or sequence of functions) and its associated
+    default value (if any) is inserted in penultimate position of the
+    mapper.  The corresponding type is estimated from the dtype of the
+    default value.
+
+    Parameters
+    ----------
+    func : var
+        Function, or sequence of functions
+
+    Examples
+    --------
+    >>> import dateutil.parser
+    >>> import datetime
+    >>> dateparser = datetustil.parser.parse
+    >>> defaultdate = datetime.date(2000, 1, 1)
+    >>> StringConverter.upgrade_mapper(dateparser, default=defaultdate)
+        """
+        # Func is a single functions
+        if hasattr(func, '__call__'):
+            cls._mapper.insert(-1, (cls._getsubdtype(default), func, default))
+            return
+        elif hasattr(func, '__iter__'):
+            if isinstance(func[0], (tuple, list)):
+                for _ in func:
+                    cls._mapper.insert(-1, _)
+                return
+            if default is None:
+                default = [None] * len(func)
+            else:
+                default = list(default)
+                default.append([None] * (len(func) - len(default)))
+            for (fct, dft) in zip(func, default):
+                cls._mapper.insert(-1, (cls._getsubdtype(dft), fct, dft))
+    #
+
+    def __init__(self, dtype_or_func=None, default=None, missing_values=None,
+                 locked=False):
+        # Convert unicode (for Py3)
+        if isinstance(missing_values, unicode):
+            missing_values = asbytes(missing_values)
+        elif isinstance(missing_values, (list, tuple)):
+            missing_values = asbytes_nested(missing_values)
+        # Defines a lock for upgrade
+        self._locked = bool(locked)
+        # No input dtype: minimal initialization
+        if dtype_or_func is None:
+            self.func = str2bool
+            self._status = 0
+            self.default = default or False
+            dtype = np.dtype('bool')
+        else:
+            # Is the input a np.dtype ?
+            try:
+                self.func = None
+                dtype = np.dtype(dtype_or_func)
+            except TypeError:
+                # dtype_or_func must be a function, then
+                if not hasattr(dtype_or_func, '__call__'):
+                    errmsg = ("The input argument `dtype` is neither a"
+                              " function nor a dtype (got '%s' instead)")
+                    raise TypeError(errmsg % type(dtype_or_func))
+                # Set the function
+                self.func = dtype_or_func
+                # If we don't have a default, try to guess it or set it to
+                # None
+                if default is None:
+                    try:
+                        default = self.func(asbytes('0'))
+                    except ValueError:
+                        default = None
+                dtype = self._getdtype(default)
+            # Set the status according to the dtype
+            _status = -1
+            for (i, (deftype, func, default_def)) in enumerate(self._mapper):
+                if np.issubdtype(dtype.type, deftype):
+                    _status = i
+                    if default is None:
+                        self.default = default_def
+                    else:
+                        self.default = default
+                    break
+            # if a converter for the specific dtype is available use that
+            last_func = func
+            for (i, (deftype, func, default_def)) in enumerate(self._mapper):
+                if dtype.type == deftype:
+                    _status = i
+                    last_func = func
+                    if default is None:
+                        self.default = default_def
+                    else:
+                        self.default = default
+                    break
+            func = last_func
+            if _status == -1:
+                # We never found a match in the _mapper...
+                _status = 0
+                self.default = default
+            self._status = _status
+            # If the input was a dtype, set the function to the last we saw
+            if self.func is None:
+                self.func = func
+            # If the status is 1 (int), change the function to
+            # something more robust.
+            if self.func == self._mapper[1][1]:
+                if issubclass(dtype.type, np.uint64):
+                    self.func = np.uint64
+                elif issubclass(dtype.type, np.int64):
+                    self.func = np.int64
+                else:
+                    self.func = lambda x: int(float(x))
+        # Store the list of strings corresponding to missing values.
+        if missing_values is None:
+            self.missing_values = set([asbytes('')])
+        else:
+            if isinstance(missing_values, bytes):
+                missing_values = missing_values.split(asbytes(","))
+            self.missing_values = set(list(missing_values) + [asbytes('')])
+        #
+        self._callingfunction = self._strict_call
+        self.type = self._dtypeortype(dtype)
+        self._checked = False
+        self._initial_default = default
+    #
+
+    def _loose_call(self, value):
+        try:
+            return self.func(value)
+        except ValueError:
+            return self.default
+    #
+
+    def _strict_call(self, value):
+        try:
+
+            # We check if we can convert the value using the current function
+            new_value = self.func(value)
+
+            # In addition to having to check whether func can convert the
+            # value, we also have to make sure that we don't get overflow
+            # errors for integers.
+            if self.func is int:
+                try:
+                    np.array(value, dtype=self.type)
+                except OverflowError:
+                    raise ValueError
+
+            # We're still here so we can now return the new value
+            return new_value
+
+        except ValueError:
+            if value.strip() in self.missing_values:
+                if not self._status:
+                    self._checked = False
+                return self.default
+            raise ValueError("Cannot convert string '%s'" % value)
+    #
+
+    def __call__(self, value):
+        return self._callingfunction(value)
+    #
+
+    def upgrade(self, value):
+        """
+        Find the best converter for a given string, and return the result.
+
+        The supplied string `value` is converted by testing different
+        converters in order. First the `func` method of the
+        `StringConverter` instance is tried, if this fails other available
+        converters are tried.  The order in which these other converters
+        are tried is determined by the `_status` attribute of the instance.
+
+        Parameters
+        ----------
+        value : str
+            The string to convert.
+
+        Returns
+        -------
+        out : any
+            The result of converting `value` with the appropriate converter.
+
+        """
+        self._checked = True
+        try:
+            return self._strict_call(value)
+        except ValueError:
+            # Raise an exception if we locked the converter...
+            if self._locked:
+                errmsg = "Converter is locked and cannot be upgraded"
+                raise ConverterLockError(errmsg)
+            _statusmax = len(self._mapper)
+            # Complains if we try to upgrade by the maximum
+            _status = self._status
+            if _status == _statusmax:
+                errmsg = "Could not find a valid conversion function"
+                raise ConverterError(errmsg)
+            elif _status < _statusmax - 1:
+                _status += 1
+            (self.type, self.func, default) = self._mapper[_status]
+            self._status = _status
+            if self._initial_default is not None:
+                self.default = self._initial_default
+            else:
+                self.default = default
+            return self.upgrade(value)
+
+    def iterupgrade(self, value):
+        self._checked = True
+        if not hasattr(value, '__iter__'):
+            value = (value,)
+        _strict_call = self._strict_call
+        try:
+            for _m in value:
+                _strict_call(_m)
+        except ValueError:
+            # Raise an exception if we locked the converter...
+            if self._locked:
+                errmsg = "Converter is locked and cannot be upgraded"
+                raise ConverterLockError(errmsg)
+            _statusmax = len(self._mapper)
+            # Complains if we try to upgrade by the maximum
+            _status = self._status
+            if _status == _statusmax:
+                raise ConverterError(
+                    "Could not find a valid conversion function"
+                    )
+            elif _status < _statusmax - 1:
+                _status += 1
+            (self.type, self.func, default) = self._mapper[_status]
+            if self._initial_default is not None:
+                self.default = self._initial_default
+            else:
+                self.default = default
+            self._status = _status
+            self.iterupgrade(value)
+
+    def update(self, func, default=None, testing_value=None,
+               missing_values=asbytes(''), locked=False):
+        """
+        Set StringConverter attributes directly.
+
+        Parameters
+        ----------
+        func : function
+            Conversion function.
+        default : any, optional
+            Value to return by default, that is, when the string to be
+            converted is flagged as missing. If not given,
+            `StringConverter` tries to supply a reasonable default value.
+        testing_value : str, optional
+            A string representing a standard input value of the converter.
+            This string is used to help defining a reasonable default
+            value.
+        missing_values : sequence of str, optional
+            Sequence of strings indicating a missing value.
+        locked : bool, optional
+            Whether the StringConverter should be locked to prevent
+            automatic upgrade or not. Default is False.
+
+        Notes
+        -----
+        `update` takes the same parameters as the constructor of
+        `StringConverter`, except that `func` does not accept a `dtype`
+        whereas `dtype_or_func` in the constructor does.
+
+        """
+        self.func = func
+        self._locked = locked
+        # Don't reset the default to None if we can avoid it
+        if default is not None:
+            self.default = default
+            self.type = self._dtypeortype(self._getdtype(default))
+        else:
+            try:
+                tester = func(testing_value or asbytes('1'))
+            except (TypeError, ValueError):
+                tester = None
+            self.type = self._dtypeortype(self._getdtype(tester))
+        # Add the missing values to the existing set
+        if missing_values is not None:
+            if _is_bytes_like(missing_values):
+                self.missing_values.add(missing_values)
+            elif hasattr(missing_values, '__iter__'):
+                for val in missing_values:
+                    self.missing_values.add(val)
+        else:
+            self.missing_values = []
+
+
+def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs):
+    """
+    Convenience function to create a `np.dtype` object.
+
+    The function processes the input `dtype` and matches it with the given
+    names.
+
+    Parameters
+    ----------
+    ndtype : var
+        Definition of the dtype. Can be any string or dictionary recognized
+        by the `np.dtype` function, or a sequence of types.
+    names : str or sequence, optional
+        Sequence of strings to use as field names for a structured dtype.
+        For convenience, `names` can be a string of a comma-separated list
+        of names.
+    defaultfmt : str, optional
+        Format string used to define missing names, such as ``"f%i"``
+        (default) or ``"fields_%02i"``.
+    validationargs : optional
+        A series of optional arguments used to initialize a
+        `NameValidator`.
+
+    Examples
+    --------
+    >>> np.lib._iotools.easy_dtype(float)
+    dtype('float64')
+    >>> np.lib._iotools.easy_dtype("i4, f8")
+    dtype([('f0', '<i4'), ('f1', '<f8')])
+    >>> np.lib._iotools.easy_dtype("i4, f8", defaultfmt="field_%03i")
+    dtype([('field_000', '<i4'), ('field_001', '<f8')])
+
+    >>> np.lib._iotools.easy_dtype((int, float, float), names="a,b,c")
+    dtype([('a', '<i8'), ('b', '<f8'), ('c', '<f8')])
+    >>> np.lib._iotools.easy_dtype(float, names="a,b,c")
+    dtype([('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
+
+    """
+    try:
+        ndtype = np.dtype(ndtype)
+    except TypeError:
+        validate = NameValidator(**validationargs)
+        nbfields = len(ndtype)
+        if names is None:
+            names = [''] * len(ndtype)
+        elif isinstance(names, basestring):
+            names = names.split(",")
+        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:
+                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,
+                                        defaultfmt=defaultfmt)
+        # No implicit names
+        elif (nbtypes > 0):
+            validate = NameValidator(**validationargs)
+            # Default initial names : should we change the format ?
+            if ((ndtype.names == tuple("f%i" % i for i in range(nbtypes))) and
+                    (defaultfmt != "f%i")):
+                ndtype.names = validate([''] * nbtypes, defaultfmt=defaultfmt)
+            # Explicit initial names : just validate
+            else:
+                ndtype.names = validate(ndtype.names, defaultfmt=defaultfmt)
+    return ndtype
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_version.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_version.py
new file mode 100644
index 0000000000..54b9c1dc78
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/_version.py
@@ -0,0 +1,156 @@
+"""Utility to compare (Numpy) version strings.
+
+The NumpyVersion class allows properly comparing numpy version strings.
+The LooseVersion and StrictVersion classes that distutils provides don't
+work; they don't recognize anything like alpha/beta/rc/dev versions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import re
+
+from numpy.compat import basestring
+
+
+__all__ = ['NumpyVersion']
+
+
+class NumpyVersion():
+    """Parse and compare numpy version strings.
+
+    Numpy has the following versioning scheme (numbers given are examples; they
+    can be > 9) in principle):
+
+    - Released version: '1.8.0', '1.8.1', etc.
+    - Alpha: '1.8.0a1', '1.8.0a2', etc.
+    - Beta: '1.8.0b1', '1.8.0b2', etc.
+    - Release candidates: '1.8.0rc1', '1.8.0rc2', etc.
+    - Development versions: '1.8.0.dev-f1234afa' (git commit hash appended)
+    - Development versions after a1: '1.8.0a1.dev-f1234afa',
+                                     '1.8.0b2.dev-f1234afa',
+                                     '1.8.1rc1.dev-f1234afa', etc.
+    - Development versions (no git hash available): '1.8.0.dev-Unknown'
+
+    Comparing needs to be done against a valid version string or other
+    `NumpyVersion` instance. Note that all development versions of the same
+    (pre-)release compare equal.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    vstring : str
+        Numpy version string (``np.__version__``).
+
+    Examples
+    --------
+    >>> from numpy.lib import NumpyVersion
+    >>> if NumpyVersion(np.__version__) < '1.7.0'):
+    ...     print('skip')
+    skip
+
+    >>> NumpyVersion('1.7')  # raises ValueError, add ".0"
+
+    """
+
+    def __init__(self, vstring):
+        self.vstring = vstring
+        ver_main = re.match(r'\d[.]\d+[.]\d+', vstring)
+        if not ver_main:
+            raise ValueError("Not a valid numpy version string")
+
+        self.version = ver_main.group()
+        self.major, self.minor, self.bugfix = [int(x) for x in
+            self.version.split('.')]
+        if len(vstring) == ver_main.end():
+            self.pre_release = 'final'
+        else:
+            alpha = re.match(r'a\d', vstring[ver_main.end():])
+            beta = re.match(r'b\d', vstring[ver_main.end():])
+            rc = re.match(r'rc\d', vstring[ver_main.end():])
+            pre_rel = [m for m in [alpha, beta, rc] if m is not None]
+            if pre_rel:
+                self.pre_release = pre_rel[0].group()
+            else:
+                self.pre_release = ''
+
+        self.is_devversion = bool(re.search(r'.dev', vstring))
+
+    def _compare_version(self, other):
+        """Compare major.minor.bugfix"""
+        if self.major == other.major:
+            if self.minor == other.minor:
+                if self.bugfix == other.bugfix:
+                    vercmp = 0
+                elif self.bugfix > other.bugfix:
+                    vercmp = 1
+                else:
+                    vercmp = -1
+            elif self.minor > other.minor:
+                vercmp = 1
+            else:
+                vercmp = -1
+        elif self.major > other.major:
+            vercmp = 1
+        else:
+            vercmp = -1
+
+        return vercmp
+
+    def _compare_pre_release(self, other):
+        """Compare alpha/beta/rc/final."""
+        if self.pre_release == other.pre_release:
+            vercmp = 0
+        elif self.pre_release == 'final':
+            vercmp = 1
+        elif other.pre_release == 'final':
+            vercmp = -1
+        elif self.pre_release > other.pre_release:
+            vercmp = 1
+        else:
+            vercmp = -1
+
+        return vercmp
+
+    def _compare(self, other):
+        if not isinstance(other, (basestring, NumpyVersion)):
+            raise ValueError("Invalid object to compare with NumpyVersion.")
+
+        if isinstance(other, basestring):
+            other = NumpyVersion(other)
+
+        vercmp = self._compare_version(other)
+        if vercmp == 0:
+            # Same x.y.z version, check for alpha/beta/rc
+            vercmp = self._compare_pre_release(other)
+            if vercmp == 0:
+                # Same version and same pre-release, check if dev version
+                if self.is_devversion is other.is_devversion:
+                    vercmp = 0
+                elif self.is_devversion:
+                    vercmp = -1
+                else:
+                    vercmp = 1
+
+        return vercmp
+
+    def __lt__(self, other):
+        return self._compare(other) < 0
+
+    def __le__(self, other):
+        return self._compare(other) <= 0
+
+    def __eq__(self, other):
+        return self._compare(other) == 0
+
+    def __ne__(self, other):
+        return self._compare(other) != 0
+
+    def __gt__(self, other):
+        return self._compare(other) > 0
+
+    def __ge__(self, other):
+        return self._compare(other) >= 0
+
+    def __repr(self):
+        return "NumpyVersion(%s)" % self.vstring
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.py
new file mode 100644
index 0000000000..c30ef6bf58
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.py
@@ -0,0 +1,1494 @@
+"""
+The arraypad module contains a group of functions to pad values onto the edges
+of an n-dimensional array.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+
+__all__ = ['pad']
+
+
+###############################################################################
+# Private utility functions.
+
+
+def _arange_ndarray(arr, shape, axis, reverse=False):
+    """
+    Create an ndarray of `shape` with increments along specified `axis`
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    shape : tuple of ints
+        Shape of desired array. Should be equivalent to `arr.shape` except
+        `shape[axis]` which may have any positive value.
+    axis : int
+        Axis to increment along.
+    reverse : bool
+        If False, increment in a positive fashion from 1 to `shape[axis]`,
+        inclusive. If True, the bounds are the same but the order reversed.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array sized to pad `arr` along `axis`, with linear range from
+        1 to `shape[axis]` along specified `axis`.
+
+    Notes
+    -----
+    The range is deliberately 1-indexed for this specific use case. Think of
+    this algorithm as broadcasting `np.arange` to a single `axis` of an
+    arbitrarily shaped ndarray.
+
+    """
+    initshape = tuple(1 if i != axis else shape[axis]
+                      for (i, x) in enumerate(arr.shape))
+    if not reverse:
+        padarr = np.arange(1, shape[axis] + 1)
+    else:
+        padarr = np.arange(shape[axis], 0, -1)
+    padarr = padarr.reshape(initshape)
+    for i, dim in enumerate(shape):
+        if padarr.shape[i] != dim:
+            padarr = padarr.repeat(dim, axis=i)
+    return padarr
+
+
+def _round_ifneeded(arr, dtype):
+    """
+    Rounds arr inplace if destination dtype is integer.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array.
+    dtype : dtype
+        The dtype of the destination array.
+
+    """
+    if np.issubdtype(dtype, np.integer):
+        arr.round(out=arr)
+
+
+def _prepend_const(arr, pad_amt, val, axis=-1):
+    """
+    Prepend constant `val` along `axis` of `arr`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    val : scalar
+        Constant value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` constant `val` prepended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+    if val == 0:
+        return np.concatenate((np.zeros(padshape, dtype=arr.dtype), arr),
+                              axis=axis)
+    else:
+        return np.concatenate(((np.zeros(padshape) + val).astype(arr.dtype),
+                               arr), axis=axis)
+
+
+def _append_const(arr, pad_amt, val, axis=-1):
+    """
+    Append constant `val` along `axis` of `arr`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    val : scalar
+        Constant value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` constant `val` appended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+    if val == 0:
+        return np.concatenate((arr, np.zeros(padshape, dtype=arr.dtype)),
+                              axis=axis)
+    else:
+        return np.concatenate(
+            (arr, (np.zeros(padshape) + val).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_edge(arr, pad_amt, axis=-1):
+    """
+    Prepend `pad_amt` to `arr` along `axis` by extending edge values.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, extended by `pad_amt` edge values appended along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    edge_slice = tuple(slice(None) if i != axis else 0
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    edge_arr = arr[edge_slice].reshape(pad_singleton)
+    return np.concatenate((edge_arr.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_edge(arr, pad_amt, axis=-1):
+    """
+    Append `pad_amt` to `arr` along `axis` by extending edge values.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, extended by `pad_amt` edge values prepended along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    edge_slice = tuple(slice(None) if i != axis else arr.shape[axis] - 1
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    edge_arr = arr[edge_slice].reshape(pad_singleton)
+    return np.concatenate((arr, edge_arr.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _prepend_ramp(arr, pad_amt, end, axis=-1):
+    """
+    Prepend linear ramp along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    end : scalar
+        Constal value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region ramps linearly from the edge value to `end`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Generate shape for final concatenated array
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+
+    # Generate an n-dimensional array incrementing along `axis`
+    ramp_arr = _arange_ndarray(arr, padshape, axis,
+                               reverse=True).astype(np.float64)
+
+    # Appropriate slicing to extract n-dimensional edge along `axis`
+    edge_slice = tuple(slice(None) if i != axis else 0
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract edge, reshape to original rank, and extend along `axis`
+    edge_pad = arr[edge_slice].reshape(pad_singleton).repeat(pad_amt, axis)
+
+    # Linear ramp
+    slope = (end - edge_pad) / float(pad_amt)
+    ramp_arr = ramp_arr * slope
+    ramp_arr += edge_pad
+    _round_ifneeded(ramp_arr, arr.dtype)
+
+    # Ramp values will most likely be float, cast them to the same type as arr
+    return np.concatenate((ramp_arr.astype(arr.dtype), arr), axis=axis)
+
+
+def _append_ramp(arr, pad_amt, end, axis=-1):
+    """
+    Append linear ramp along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    end : scalar
+        Constal value to use. For best results should be of type `arr.dtype`;
+        if not `arr.dtype` will be cast to `arr.dtype`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region ramps linearly from the edge value to `end`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Generate shape for final concatenated array
+    padshape = tuple(x if i != axis else pad_amt
+                     for (i, x) in enumerate(arr.shape))
+
+    # Generate an n-dimensional array incrementing along `axis`
+    ramp_arr = _arange_ndarray(arr, padshape, axis,
+                               reverse=False).astype(np.float64)
+
+    # Slice a chunk from the edge to calculate stats on
+    edge_slice = tuple(slice(None) if i != axis else -1
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract edge, reshape to original rank, and extend along `axis`
+    edge_pad = arr[edge_slice].reshape(pad_singleton).repeat(pad_amt, axis)
+
+    # Linear ramp
+    slope = (end - edge_pad) / float(pad_amt)
+    ramp_arr = ramp_arr * slope
+    ramp_arr += edge_pad
+    _round_ifneeded(ramp_arr, arr.dtype)
+
+    # Ramp values will most likely be float, cast them to the same type as arr
+    return np.concatenate((arr, ramp_arr.astype(arr.dtype)), axis=axis)
+
+
+def _prepend_max(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` maximum values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate maximum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        prepended region is the maximum of the first `num` values along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    max_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate max, reshape to add singleton dimension back
+    max_chunk = arr[max_slice].max(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `max_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((max_chunk.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_max(arr, pad_amt, num, axis=-1):
+    """
+    Pad one `axis` of `arr` with the maximum of the last `num` elements.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate maximum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the maximum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        max_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        max_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate max, reshape to add singleton dimension back
+    max_chunk = arr[max_slice].max(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `max_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((arr, max_chunk.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _prepend_mean(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` mean values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate mean.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the mean of the first `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    mean_slice = tuple(slice(None) if i != axis else slice(num)
+                       for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate mean, reshape to add singleton dimension back
+    mean_chunk = arr[mean_slice].mean(axis).reshape(pad_singleton)
+    _round_ifneeded(mean_chunk, arr.dtype)
+
+    # Concatenate `arr` with `mean_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((mean_chunk.repeat(pad_amt, axis).astype(arr.dtype),
+                           arr), axis=axis)
+
+
+def _append_mean(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` mean values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate mean.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the maximum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        mean_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        mean_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate mean, reshape to add singleton dimension back
+    mean_chunk = arr[mean_slice].mean(axis=axis).reshape(pad_singleton)
+    _round_ifneeded(mean_chunk, arr.dtype)
+
+    # Concatenate `arr` with `mean_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (arr, mean_chunk.repeat(pad_amt, axis).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_med(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate median.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the median of the first `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    med_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate median, reshape to add singleton dimension back
+    med_chunk = np.median(arr[med_slice], axis=axis).reshape(pad_singleton)
+    _round_ifneeded(med_chunk, arr.dtype)
+
+    # Concatenate `arr` with `med_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (med_chunk.repeat(pad_amt, axis).astype(arr.dtype), arr), axis=axis)
+
+
+def _append_med(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate median.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the median of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        med_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        med_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate median, reshape to add singleton dimension back
+    med_chunk = np.median(arr[med_slice], axis=axis).reshape(pad_singleton)
+    _round_ifneeded(med_chunk, arr.dtype)
+
+    # Concatenate `arr` with `med_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate(
+        (arr, med_chunk.repeat(pad_amt, axis).astype(arr.dtype)), axis=axis)
+
+
+def _prepend_min(arr, pad_amt, num, axis=-1):
+    """
+    Prepend `pad_amt` minimum values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to prepend.
+    num : int
+        Depth into `arr` along `axis` to calculate minimum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values prepended along `axis`. The
+        prepended region is the minimum of the first `num` values along
+        `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _prepend_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    min_slice = tuple(slice(None) if i != axis else slice(num)
+                      for (i, x) in enumerate(arr.shape))
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate min, reshape to add singleton dimension back
+    min_chunk = arr[min_slice].min(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `min_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((min_chunk.repeat(pad_amt, axis=axis), arr),
+                          axis=axis)
+
+
+def _append_min(arr, pad_amt, num, axis=-1):
+    """
+    Append `pad_amt` median values along `axis`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : int
+        Amount of padding to append.
+    num : int
+        Depth into `arr` along `axis` to calculate minimum.
+        Range: [1, `arr.shape[axis]`] or None (entire axis)
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt` values appended along `axis`. The
+        appended region is the minimum of the final `num` values along `axis`.
+
+    """
+    if pad_amt == 0:
+        return arr
+
+    # Equivalent to edge padding for single value, so do that instead
+    if num == 1:
+        return _append_edge(arr, pad_amt, axis)
+
+    # Use entire array if `num` is too large
+    if num is not None:
+        if num >= arr.shape[axis]:
+            num = None
+
+    # Slice a chunk from the edge to calculate stats on
+    end = arr.shape[axis] - 1
+    if num is not None:
+        min_slice = tuple(
+            slice(None) if i != axis else slice(end, end - num, -1)
+            for (i, x) in enumerate(arr.shape))
+    else:
+        min_slice = tuple(slice(None) for x in arr.shape)
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+
+    # Extract slice, calculate min, reshape to add singleton dimension back
+    min_chunk = arr[min_slice].min(axis=axis).reshape(pad_singleton)
+
+    # Concatenate `arr` with `min_chunk`, extended along `axis` by `pad_amt`
+    return np.concatenate((arr, min_chunk.repeat(pad_amt, axis=axis)),
+                          axis=axis)
+
+
+def _pad_ref(arr, pad_amt, method, axis=-1):
+    """
+    Pad `axis` of `arr` by reflection.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    method : str
+        Controls method of reflection; options are 'even' or 'odd'.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded with reflected
+        values from the original array.
+
+    Notes
+    -----
+    This algorithm does not pad with repetition, i.e. the edges are not
+    repeated in the reflection. For that behavior, use `mode='symmetric'`.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    ref_slice = tuple(slice(None) if i != axis else slice(pad_amt[0], 0, -1)
+                      for (i, x) in enumerate(arr.shape))
+
+    ref_chunk1 = arr[ref_slice]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        ref_chunk1 = ref_chunk1.reshape(pad_singleton)
+
+    # Memory/computationally more expensive, only do this if `method='odd'`
+    if 'odd' in method and pad_amt[0] > 0:
+        edge_slice1 = tuple(slice(None) if i != axis else 0
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice1].reshape(pad_singleton)
+        ref_chunk1 = 2 * edge_chunk - ref_chunk1
+        del edge_chunk
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    start = arr.shape[axis] - pad_amt[1] - 1
+    end = arr.shape[axis] - 1
+    ref_slice = tuple(slice(None) if i != axis else slice(start, end)
+                      for (i, x) in enumerate(arr.shape))
+    rev_idx = tuple(slice(None) if i != axis else slice(None, None, -1)
+                    for (i, x) in enumerate(arr.shape))
+    ref_chunk2 = arr[ref_slice][rev_idx]
+
+    if pad_amt[1] == 1:
+        ref_chunk2 = ref_chunk2.reshape(pad_singleton)
+
+    if 'odd' in method:
+        edge_slice2 = tuple(slice(None) if i != axis else -1
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice2].reshape(pad_singleton)
+        ref_chunk2 = 2 * edge_chunk - ref_chunk2
+        del edge_chunk
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((ref_chunk1, arr, ref_chunk2), axis=axis)
+
+
+def _pad_sym(arr, pad_amt, method, axis=-1):
+    """
+    Pad `axis` of `arr` by symmetry.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    method : str
+        Controls method of symmetry; options are 'even' or 'odd'.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded with symmetric
+        values from the original array.
+
+    Notes
+    -----
+    This algorithm DOES pad with repetition, i.e. the edges are repeated.
+    For padding without repeated edges, use `mode='reflect'`.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    sym_slice = tuple(slice(None) if i != axis else slice(0, pad_amt[0])
+                      for (i, x) in enumerate(arr.shape))
+    rev_idx = tuple(slice(None) if i != axis else slice(None, None, -1)
+                    for (i, x) in enumerate(arr.shape))
+    sym_chunk1 = arr[sym_slice][rev_idx]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        sym_chunk1 = sym_chunk1.reshape(pad_singleton)
+
+    # Memory/computationally more expensive, only do this if `method='odd'`
+    if 'odd' in method and pad_amt[0] > 0:
+        edge_slice1 = tuple(slice(None) if i != axis else 0
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice1].reshape(pad_singleton)
+        sym_chunk1 = 2 * edge_chunk - sym_chunk1
+        del edge_chunk
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    start = arr.shape[axis] - pad_amt[1]
+    end = arr.shape[axis]
+    sym_slice = tuple(slice(None) if i != axis else slice(start, end)
+                      for (i, x) in enumerate(arr.shape))
+    sym_chunk2 = arr[sym_slice][rev_idx]
+
+    if pad_amt[1] == 1:
+        sym_chunk2 = sym_chunk2.reshape(pad_singleton)
+
+    if 'odd' in method:
+        edge_slice2 = tuple(slice(None) if i != axis else -1
+                            for (i, x) in enumerate(arr.shape))
+        edge_chunk = arr[edge_slice2].reshape(pad_singleton)
+        sym_chunk2 = 2 * edge_chunk - sym_chunk2
+        del edge_chunk
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((sym_chunk1, arr, sym_chunk2), axis=axis)
+
+
+def _pad_wrap(arr, pad_amt, axis=-1):
+    """
+    Pad `axis` of `arr` via wrapping.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Input array of arbitrary shape.
+    pad_amt : tuple of ints, length 2
+        Padding to (prepend, append) along `axis`.
+    axis : int
+        Axis along which to pad `arr`.
+
+    Returns
+    -------
+    padarr : ndarray
+        Output array, with `pad_amt[0]` values prepended and `pad_amt[1]`
+        values appended along `axis`. Both regions are padded wrapped values
+        from the opposite end of `axis`.
+
+    Notes
+    -----
+    This method of padding is also known as 'tile' or 'tiling'.
+
+    The modes 'reflect', 'symmetric', and 'wrap' must be padded with a
+    single function, lest the indexing tricks in non-integer multiples of the
+    original shape would violate repetition in the final iteration.
+
+    """
+    # Implicit booleanness to test for zero (or None) in any scalar type
+    if pad_amt[0] == 0 and pad_amt[1] == 0:
+        return arr
+
+    ##########################################################################
+    # Prepended region
+
+    # Slice off a reverse indexed chunk from near edge to pad `arr` before
+    start = arr.shape[axis] - pad_amt[0]
+    end = arr.shape[axis]
+    wrap_slice = tuple(slice(None) if i != axis else slice(start, end)
+                       for (i, x) in enumerate(arr.shape))
+    wrap_chunk1 = arr[wrap_slice]
+
+    # Shape to restore singleton dimension after slicing
+    pad_singleton = tuple(x if i != axis else 1
+                          for (i, x) in enumerate(arr.shape))
+    if pad_amt[0] == 1:
+        wrap_chunk1 = wrap_chunk1.reshape(pad_singleton)
+
+    ##########################################################################
+    # Appended region
+
+    # Slice off a reverse indexed chunk from far edge to pad `arr` after
+    wrap_slice = tuple(slice(None) if i != axis else slice(0, pad_amt[1])
+                       for (i, x) in enumerate(arr.shape))
+    wrap_chunk2 = arr[wrap_slice]
+
+    if pad_amt[1] == 1:
+        wrap_chunk2 = wrap_chunk2.reshape(pad_singleton)
+
+    # Concatenate `arr` with both chunks, extending along `axis`
+    return np.concatenate((wrap_chunk1, arr, wrap_chunk2), axis=axis)
+
+
+def _normalize_shape(ndarray, shape, cast_to_int=True):
+    """
+    Private function which does some checks and normalizes the possibly
+    much simpler representations of 'pad_width', 'stat_length',
+    'constant_values', 'end_values'.
+
+    Parameters
+    ----------
+    narray : ndarray
+        Input ndarray
+    shape : {sequence, array_like, float, int}, optional
+        The width of padding (pad_width), the number of elements on the
+        edge of the narray used for statistics (stat_length), the constant
+        value(s) to use when filling padded regions (constant_values), or the
+        endpoint target(s) for linear ramps (end_values).
+        ((before_1, after_1), ... (before_N, after_N)) unique number of
+        elements for each axis where `N` is rank of `narray`.
+        ((before, after),) yields same before and after constants for each
+        axis.
+        (constant,) or val is a shortcut for before = after = constant for
+        all axes.
+    cast_to_int : bool, optional
+        Controls if values in ``shape`` will be rounded and cast to int
+        before being returned.
+
+    Returns
+    -------
+    normalized_shape : tuple of tuples
+        val                               => ((val, val), (val, val), ...)
+        [[val1, val2], [val3, val4], ...] => ((val1, val2), (val3, val4), ...)
+        ((val1, val2), (val3, val4), ...) => no change
+        [[val1, val2], ]                  => ((val1, val2), (val1, val2), ...)
+        ((val1, val2), )                  => ((val1, val2), (val1, val2), ...)
+        [[val ,     ], ]                  => ((val, val), (val, val), ...)
+        ((val ,     ), )                  => ((val, val), (val, val), ...)
+
+    """
+    ndims = ndarray.ndim
+
+    # Shortcut shape=None
+    if shape is None:
+        return ((None, None), ) * ndims
+
+    # Convert any input `info` to a NumPy array
+    arr = np.asarray(shape)
+
+    # Switch based on what input looks like
+    if arr.ndim <= 1:
+        if arr.shape == () or arr.shape == (1,):
+            # Single scalar input
+            #   Create new array of ones, multiply by the scalar
+            arr = np.ones((ndims, 2), dtype=ndarray.dtype) * arr
+        elif arr.shape == (2,):
+            # Apply padding (before, after) each axis
+            #   Create new axis 0, repeat along it for every axis
+            arr = arr[np.newaxis, :].repeat(ndims, axis=0)
+        else:
+            fmt = "Unable to create correctly shaped tuple from %s"
+            raise ValueError(fmt % (shape,))
+
+    elif arr.ndim == 2:
+        if arr.shape[1] == 1 and arr.shape[0] == ndims:
+            # Padded before and after by the same amount
+            arr = arr.repeat(2, axis=1)
+        elif arr.shape[0] == ndims:
+            # Input correctly formatted, pass it on as `arr`
+            arr = shape
+        else:
+            fmt = "Unable to create correctly shaped tuple from %s"
+            raise ValueError(fmt % (shape,))
+
+    else:
+        fmt = "Unable to create correctly shaped tuple from %s"
+        raise ValueError(fmt % (shape,))
+
+    # Cast if necessary
+    if cast_to_int is True:
+        arr = np.round(arr).astype(int)
+
+    # Convert list of lists to tuple of tuples
+    return tuple(tuple(axis) for axis in arr.tolist())
+
+
+def _validate_lengths(narray, number_elements):
+    """
+    Private function which does some checks and reformats pad_width and
+    stat_length using _normalize_shape.
+
+    Parameters
+    ----------
+    narray : ndarray
+        Input ndarray
+    number_elements : {sequence, int}, optional
+        The width of padding (pad_width) or the number of elements on the edge
+        of the narray used for statistics (stat_length).
+        ((before_1, after_1), ... (before_N, after_N)) unique number of
+        elements for each axis.
+        ((before, after),) yields same before and after constants for each
+        axis.
+        (constant,) or int is a shortcut for before = after = constant for all
+        axes.
+
+    Returns
+    -------
+    _validate_lengths : tuple of tuples
+        int                               => ((int, int), (int, int), ...)
+        [[int1, int2], [int3, int4], ...] => ((int1, int2), (int3, int4), ...)
+        ((int1, int2), (int3, int4), ...) => no change
+        [[int1, int2], ]                  => ((int1, int2), (int1, int2), ...)
+        ((int1, int2), )                  => ((int1, int2), (int1, int2), ...)
+        [[int ,     ], ]                  => ((int, int), (int, int), ...)
+        ((int ,     ), )                  => ((int, int), (int, int), ...)
+
+    """
+    normshp = _normalize_shape(narray, number_elements)
+    for i in normshp:
+        chk = [1 if x is None else x for x in i]
+        chk = [1 if x >= 0 else -1 for x in chk]
+        if (chk[0] < 0) or (chk[1] < 0):
+            fmt = "%s cannot contain negative values."
+            raise ValueError(fmt % (number_elements,))
+    return normshp
+
+
+###############################################################################
+# Public functions
+
+
+def pad(array, pad_width, mode, **kwargs):
+    """
+    Pads an array.
+
+    Parameters
+    ----------
+    array : array_like of rank N
+        Input array
+    pad_width : {sequence, array_like, int}
+        Number of values padded to the edges of each axis.
+        ((before_1, after_1), ... (before_N, after_N)) unique pad widths
+        for each axis.
+        ((before, after),) yields same before and after pad for each axis.
+        (pad,) or int is a shortcut for before = after = pad width for all
+        axes.
+    mode : str or function
+        One of the following string values or a user supplied function.
+
+        'constant'
+            Pads with a constant value.
+        'edge'
+            Pads with the edge values of array.
+        'linear_ramp'
+            Pads with the linear ramp between end_value and the
+            array edge value.
+        'maximum'
+            Pads with the maximum value of all or part of the
+            vector along each axis.
+        'mean'
+            Pads with the mean value of all or part of the
+            vector along each axis.
+        'median'
+            Pads with the median value of all or part of the
+            vector along each axis.
+        'minimum'
+            Pads with the minimum value of all or part of the
+            vector along each axis.
+        'reflect'
+            Pads with the reflection of the vector mirrored on
+            the first and last values of the vector along each
+            axis.
+        'symmetric'
+            Pads with the reflection of the vector mirrored
+            along the edge of the array.
+        'wrap'
+            Pads with the wrap of the vector along the axis.
+            The first values are used to pad the end and the
+            end values are used to pad the beginning.
+        <function>
+            Padding function, see Notes.
+    stat_length : sequence or int, optional
+        Used in 'maximum', 'mean', 'median', and 'minimum'.  Number of
+        values at edge of each axis used to calculate the statistic value.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique statistic
+        lengths for each axis.
+
+        ((before, after),) yields same before and after statistic lengths
+        for each axis.
+
+        (stat_length,) or int is a shortcut for before = after = statistic
+        length for all axes.
+
+        Default is ``None``, to use the entire axis.
+    constant_values : sequence or int, optional
+        Used in 'constant'.  The values to set the padded values for each
+        axis.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique pad constants
+        for each axis.
+
+        ((before, after),) yields same before and after constants for each
+        axis.
+
+        (constant,) or int is a shortcut for before = after = constant for
+        all axes.
+
+        Default is 0.
+    end_values : sequence or int, optional
+        Used in 'linear_ramp'.  The values used for the ending value of the
+        linear_ramp and that will form the edge of the padded array.
+
+        ((before_1, after_1), ... (before_N, after_N)) unique end values
+        for each axis.
+
+        ((before, after),) yields same before and after end values for each
+        axis.
+
+        (constant,) or int is a shortcut for before = after = end value for
+        all axes.
+
+        Default is 0.
+    reflect_type : {'even', 'odd'}, optional
+        Used in 'reflect', and 'symmetric'.  The 'even' style is the
+        default with an unaltered reflection around the edge value.  For
+        the 'odd' style, the extented part of the array is created by
+        subtracting the reflected values from two times the edge value.
+
+    Returns
+    -------
+    pad : ndarray
+        Padded array of rank equal to `array` with shape increased
+        according to `pad_width`.
+
+    Notes
+    -----
+    .. versionadded:: 1.7.0
+
+    For an array with rank greater than 1, some of the padding of later
+    axes is calculated from padding of previous axes.  This is easiest to
+    think about with a rank 2 array where the corners of the padded array
+    are calculated by using padded values from the first axis.
+
+    The padding function, if used, should return a rank 1 array equal in
+    length to the vector argument with padded values replaced. It has the
+    following signature::
+
+        padding_func(vector, iaxis_pad_width, iaxis, **kwargs)
+
+    where
+
+        vector : ndarray
+            A rank 1 array already padded with zeros.  Padded values are
+            vector[:pad_tuple[0]] and vector[-pad_tuple[1]:].
+        iaxis_pad_width : tuple
+            A 2-tuple of ints, iaxis_pad_width[0] represents the number of
+            values padded at the beginning of vector where
+            iaxis_pad_width[1] represents the number of values padded at
+            the end of vector.
+        iaxis : int
+            The axis currently being calculated.
+        kwargs : misc
+            Any keyword arguments the function requires.
+
+    Examples
+    --------
+    >>> a = [1, 2, 3, 4, 5]
+    >>> np.lib.pad(a, (2,3), 'constant', constant_values=(4, 6))
+    array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])
+
+    >>> np.lib.pad(a, (2, 3), 'edge')
+    array([1, 1, 1, 2, 3, 4, 5, 5, 5, 5])
+
+    >>> np.lib.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
+    array([ 5,  3,  1,  2,  3,  4,  5,  2, -1, -4])
+
+    >>> np.lib.pad(a, (2,), 'maximum')
+    array([5, 5, 1, 2, 3, 4, 5, 5, 5])
+
+    >>> np.lib.pad(a, (2,), 'mean')
+    array([3, 3, 1, 2, 3, 4, 5, 3, 3])
+
+    >>> np.lib.pad(a, (2,), 'median')
+    array([3, 3, 1, 2, 3, 4, 5, 3, 3])
+
+    >>> a = [[1, 2], [3, 4]]
+    >>> np.lib.pad(a, ((3, 2), (2, 3)), 'minimum')
+    array([[1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1],
+           [3, 3, 3, 4, 3, 3, 3],
+           [1, 1, 1, 2, 1, 1, 1],
+           [1, 1, 1, 2, 1, 1, 1]])
+
+    >>> a = [1, 2, 3, 4, 5]
+    >>> np.lib.pad(a, (2, 3), 'reflect')
+    array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])
+
+    >>> np.lib.pad(a, (2, 3), 'reflect', reflect_type='odd')
+    array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8])
+
+    >>> np.lib.pad(a, (2, 3), 'symmetric')
+    array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])
+
+    >>> np.lib.pad(a, (2, 3), 'symmetric', reflect_type='odd')
+    array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
+
+    >>> np.lib.pad(a, (2, 3), 'wrap')
+    array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])
+
+    >>> def padwithtens(vector, pad_width, iaxis, kwargs):
+    ...     vector[:pad_width[0]] = 10
+    ...     vector[-pad_width[1]:] = 10
+    ...     return vector
+
+    >>> a = np.arange(6)
+    >>> a = a.reshape((2, 3))
+
+    >>> np.lib.pad(a, 2, padwithtens)
+    array([[10, 10, 10, 10, 10, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10],
+           [10, 10,  0,  1,  2, 10, 10],
+           [10, 10,  3,  4,  5, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10],
+           [10, 10, 10, 10, 10, 10, 10]])
+    """
+    if not np.asarray(pad_width).dtype.kind == 'i':
+        raise TypeError('`pad_width` must be of integral type.')
+
+    narray = np.array(array)
+    pad_width = _validate_lengths(narray, pad_width)
+
+    allowedkwargs = {
+        'constant': ['constant_values'],
+        'edge': [],
+        'linear_ramp': ['end_values'],
+        'maximum': ['stat_length'],
+        'mean': ['stat_length'],
+        'median': ['stat_length'],
+        'minimum': ['stat_length'],
+        'reflect': ['reflect_type'],
+        'symmetric': ['reflect_type'],
+        'wrap': [],
+        }
+
+    kwdefaults = {
+        'stat_length': None,
+        'constant_values': 0,
+        'end_values': 0,
+        'reflect_type': 'even',
+        }
+
+    if isinstance(mode, np.compat.basestring):
+        # Make sure have allowed kwargs appropriate for mode
+        for key in kwargs:
+            if key not in allowedkwargs[mode]:
+                raise ValueError('%s keyword not in allowed keywords %s' %
+                                 (key, allowedkwargs[mode]))
+
+        # Set kwarg defaults
+        for kw in allowedkwargs[mode]:
+            kwargs.setdefault(kw, kwdefaults[kw])
+
+        # Need to only normalize particular keywords.
+        for i in kwargs:
+            if i == 'stat_length':
+                kwargs[i] = _validate_lengths(narray, kwargs[i])
+            if i in ['end_values', 'constant_values']:
+                kwargs[i] = _normalize_shape(narray, kwargs[i],
+                                             cast_to_int=False)
+    else:
+        # Drop back to old, slower np.apply_along_axis mode for user-supplied
+        # vector function
+        function = mode
+
+        # Create a new padded array
+        rank = list(range(len(narray.shape)))
+        total_dim_increase = [np.sum(pad_width[i]) for i in rank]
+        offset_slices = [slice(pad_width[i][0],
+                               pad_width[i][0] + narray.shape[i])
+                         for i in rank]
+        new_shape = np.array(narray.shape) + total_dim_increase
+        newmat = np.zeros(new_shape, narray.dtype)
+
+        # Insert the original array into the padded array
+        newmat[offset_slices] = narray
+
+        # This is the core of pad ...
+        for iaxis in rank:
+            np.apply_along_axis(function,
+                                iaxis,
+                                newmat,
+                                pad_width[iaxis],
+                                iaxis,
+                                kwargs)
+        return newmat
+
+    # If we get here, use new padding method
+    newmat = narray.copy()
+
+    # API preserved, but completely new algorithm which pads by building the
+    # entire block to pad before/after `arr` with in one step, for each axis.
+    if mode == 'constant':
+        for axis, ((pad_before, pad_after), (before_val, after_val)) \
+                in enumerate(zip(pad_width, kwargs['constant_values'])):
+            newmat = _prepend_const(newmat, pad_before, before_val, axis)
+            newmat = _append_const(newmat, pad_after, after_val, axis)
+
+    elif mode == 'edge':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            newmat = _prepend_edge(newmat, pad_before, axis)
+            newmat = _append_edge(newmat, pad_after, axis)
+
+    elif mode == 'linear_ramp':
+        for axis, ((pad_before, pad_after), (before_val, after_val)) \
+                in enumerate(zip(pad_width, kwargs['end_values'])):
+            newmat = _prepend_ramp(newmat, pad_before, before_val, axis)
+            newmat = _append_ramp(newmat, pad_after, after_val, axis)
+
+    elif mode == 'maximum':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_max(newmat, pad_before, chunk_before, axis)
+            newmat = _append_max(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'mean':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_mean(newmat, pad_before, chunk_before, axis)
+            newmat = _append_mean(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'median':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_med(newmat, pad_before, chunk_before, axis)
+            newmat = _append_med(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'minimum':
+        for axis, ((pad_before, pad_after), (chunk_before, chunk_after)) \
+                in enumerate(zip(pad_width, kwargs['stat_length'])):
+            newmat = _prepend_min(newmat, pad_before, chunk_before, axis)
+            newmat = _append_min(newmat, pad_after, chunk_after, axis)
+
+    elif mode == 'reflect':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            if ((pad_before > 0) or
+                    (pad_after > 0)) and newmat.shape[axis] == 1:
+                # Extending singleton dimension for 'reflect' is legacy
+                # behavior; it really should raise an error.
+                newmat = _prepend_edge(newmat, pad_before, axis)
+                newmat = _append_edge(newmat, pad_after, axis)
+                continue
+
+            method = kwargs['reflect_type']
+            safe_pad = newmat.shape[axis] - 1
+            while ((pad_before > safe_pad) or (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_ref(newmat, (pad_iter_b,
+                                           pad_iter_a), method, axis)
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_ref(newmat, (pad_before, pad_after), method, axis)
+
+    elif mode == 'symmetric':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            method = kwargs['reflect_type']
+            safe_pad = newmat.shape[axis]
+            while ((pad_before > safe_pad) or
+                   (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_sym(newmat, (pad_iter_b,
+                                           pad_iter_a), method, axis)
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_sym(newmat, (pad_before, pad_after), method, axis)
+
+    elif mode == 'wrap':
+        for axis, (pad_before, pad_after) in enumerate(pad_width):
+            # Recursive padding along any axis where `pad_amt` is too large
+            # for indexing tricks. We can only safely pad the original axis
+            # length, to keep the period of the reflections consistent.
+            safe_pad = newmat.shape[axis]
+            while ((pad_before > safe_pad) or
+                   (pad_after > safe_pad)):
+                pad_iter_b = min(safe_pad,
+                                 safe_pad * (pad_before // safe_pad))
+                pad_iter_a = min(safe_pad, safe_pad * (pad_after // safe_pad))
+                newmat = _pad_wrap(newmat, (pad_iter_b, pad_iter_a), axis)
+
+                pad_before -= pad_iter_b
+                pad_after -= pad_iter_a
+                safe_pad += pad_iter_b + pad_iter_a
+            newmat = _pad_wrap(newmat, (pad_before, pad_after), axis)
+
+    return newmat
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.py
new file mode 100644
index 0000000000..17dfa7567e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.py
@@ -0,0 +1,480 @@
+"""
+Set operations for 1D numeric arrays based on sorting.
+
+:Contains:
+  ediff1d,
+  unique,
+  intersect1d,
+  setxor1d,
+  in1d,
+  union1d,
+  setdiff1d
+
+:Notes:
+
+For floating point arrays, inaccurate results may appear due to usual round-off
+and floating point comparison issues.
+
+Speed could be gained in some operations by an implementation of
+sort(), that can provide directly the permutation vectors, avoiding
+thus calls to argsort().
+
+To do: Optionally return indices analogously to unique for all functions.
+
+:Author: Robert Cimrman
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+
+__all__ = [
+    'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique',
+    'in1d'
+    ]
+
+
+def ediff1d(ary, to_end=None, to_begin=None):
+    """
+    The differences between consecutive elements of an array.
+
+    Parameters
+    ----------
+    ary : array_like
+        If necessary, will be flattened before the differences are taken.
+    to_end : array_like, optional
+        Number(s) to append at the end of the returned differences.
+    to_begin : array_like, optional
+        Number(s) to prepend at the beginning of the returned differences.
+
+    Returns
+    -------
+    ediff1d : ndarray
+        The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``.
+
+    See Also
+    --------
+    diff, gradient
+
+    Notes
+    -----
+    When applied to masked arrays, this function drops the mask information
+    if the `to_begin` and/or `to_end` parameters are used.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 0])
+    >>> np.ediff1d(x)
+    array([ 1,  2,  3, -7])
+
+    >>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99]))
+    array([-99,   1,   2,   3,  -7,  88,  99])
+
+    The returned array is always 1D.
+
+    >>> y = [[1, 2, 4], [1, 6, 24]]
+    >>> np.ediff1d(y)
+    array([ 1,  2, -3,  5, 18])
+
+    """
+    ary = np.asanyarray(ary).flat
+    ed = ary[1:] - ary[:-1]
+    arrays = [ed]
+    if to_begin is not None:
+        arrays.insert(0, to_begin)
+    if to_end is not None:
+        arrays.append(to_end)
+
+    if len(arrays) != 1:
+        # We'll save ourselves a copy of a potentially large array in
+        # the common case where neither to_begin or to_end was given.
+        ed = np.hstack(arrays)
+
+    return ed
+
+def unique(ar, return_index=False, return_inverse=False, return_counts=False):
+    """
+    Find the unique elements of an array.
+
+    Returns the sorted unique elements of an array. There are three optional
+    outputs in addition to the unique elements: the indices of the input array
+    that give the unique values, the indices of the unique array that
+    reconstruct the input array, and the number of times each unique value
+    comes up in the input array.
+
+    Parameters
+    ----------
+    ar : array_like
+        Input array. This will be flattened if it is not already 1-D.
+    return_index : bool, optional
+        If True, also return the indices of `ar` that result in the unique
+        array.
+    return_inverse : bool, optional
+        If True, also return the indices of the unique array that can be used
+        to reconstruct `ar`.
+    return_counts : bool, optional
+        If True, also return the number of times each unique value comes up
+        in `ar`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    unique : ndarray
+        The sorted unique values.
+    unique_indices : ndarray, optional
+        The indices of the first occurrences of the unique values in the
+        (flattened) original array. Only provided if `return_index` is True.
+    unique_inverse : ndarray, optional
+        The indices to reconstruct the (flattened) original array from the
+        unique array. Only provided if `return_inverse` is True.
+    unique_counts : ndarray, optional
+        The number of times each of the unique values comes up in the
+        original array. Only provided if `return_counts` is True.
+
+        .. versionadded:: 1.9.0
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.unique([1, 1, 2, 2, 3, 3])
+    array([1, 2, 3])
+    >>> a = np.array([[1, 1], [2, 3]])
+    >>> np.unique(a)
+    array([1, 2, 3])
+
+    Return the indices of the original array that give the unique values:
+
+    >>> a = np.array(['a', 'b', 'b', 'c', 'a'])
+    >>> u, indices = np.unique(a, return_index=True)
+    >>> u
+    array(['a', 'b', 'c'],
+           dtype='|S1')
+    >>> indices
+    array([0, 1, 3])
+    >>> a[indices]
+    array(['a', 'b', 'c'],
+           dtype='|S1')
+
+    Reconstruct the input array from the unique values:
+
+    >>> a = np.array([1, 2, 6, 4, 2, 3, 2])
+    >>> u, indices = np.unique(a, return_inverse=True)
+    >>> u
+    array([1, 2, 3, 4, 6])
+    >>> indices
+    array([0, 1, 4, 3, 1, 2, 1])
+    >>> u[indices]
+    array([1, 2, 6, 4, 2, 3, 2])
+
+    """
+    ar = np.asanyarray(ar).flatten()
+
+    optional_indices = return_index or return_inverse
+    optional_returns = optional_indices or return_counts
+
+    if ar.size == 0:
+        if not optional_returns:
+            ret = ar
+        else:
+            ret = (ar,)
+            if return_index:
+                ret += (np.empty(0, np.bool),)
+            if return_inverse:
+                ret += (np.empty(0, np.bool),)
+            if return_counts:
+                ret += (np.empty(0, np.intp),)
+        return ret
+
+    if optional_indices:
+        perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')
+        aux = ar[perm]
+    else:
+        ar.sort()
+        aux = ar
+    flag = np.concatenate(([True], aux[1:] != aux[:-1]))
+
+    if not optional_returns:
+        ret = aux[flag]
+    else:
+        ret = (aux[flag],)
+        if return_index:
+            ret += (perm[flag],)
+        if return_inverse:
+            iflag = np.cumsum(flag) - 1
+            inv_idx = np.empty(ar.shape, dtype=np.intp)
+            inv_idx[perm] = iflag
+            ret += (inv_idx,)
+        if return_counts:
+            idx = np.concatenate(np.nonzero(flag) + ([ar.size],))
+            ret += (np.diff(idx),)
+    return ret
+
+def intersect1d(ar1, ar2, assume_unique=False):
+    """
+    Find the intersection of two arrays.
+
+    Return the sorted, unique values that are in both of the input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    intersect1d : ndarray
+        Sorted 1D array of common and unique elements.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])
+    array([1, 3])
+
+    To intersect more than two arrays, use functools.reduce:
+
+    >>> from functools import reduce
+    >>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
+    array([3])
+    """
+    if not assume_unique:
+        # Might be faster than unique( intersect1d( ar1, ar2 ) )?
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    aux = np.concatenate((ar1, ar2))
+    aux.sort()
+    return aux[:-1][aux[1:] == aux[:-1]]
+
+def setxor1d(ar1, ar2, assume_unique=False):
+    """
+    Find the set exclusive-or of two arrays.
+
+    Return the sorted, unique values that are in only one (not both) of the
+    input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    setxor1d : ndarray
+        Sorted 1D array of unique values that are in only one of the input
+        arrays.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3, 2, 4])
+    >>> b = np.array([2, 3, 5, 7, 5])
+    >>> np.setxor1d(a,b)
+    array([1, 4, 5, 7])
+
+    """
+    if not assume_unique:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+
+    aux = np.concatenate((ar1, ar2))
+    if aux.size == 0:
+        return aux
+
+    aux.sort()
+#    flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
+    flag = np.concatenate(([True], aux[1:] != aux[:-1], [True]))
+#    flag2 = ediff1d( flag ) == 0
+    flag2 = flag[1:] == flag[:-1]
+    return aux[flag2]
+
+def in1d(ar1, ar2, assume_unique=False, invert=False):
+    """
+    Test whether each element of a 1-D array is also present in a second array.
+
+    Returns a boolean array the same length as `ar1` that is True
+    where an element of `ar1` is in `ar2` and False otherwise.
+
+    Parameters
+    ----------
+    ar1 : (M,) array_like
+        Input array.
+    ar2 : array_like
+        The values against which to test each value of `ar1`.
+    assume_unique : bool, optional
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+    invert : bool, optional
+        If True, the values in the returned array are inverted (that is,
+        False where an element of `ar1` is in `ar2` and True otherwise).
+        Default is False. ``np.in1d(a, b, invert=True)`` is equivalent
+        to (but is faster than) ``np.invert(in1d(a, b))``.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    in1d : (M,) ndarray, bool
+        The values `ar1[in1d]` are in `ar2`.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Notes
+    -----
+    `in1d` can be considered as an element-wise function version of the
+    python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly
+    equivalent to ``np.array([item in b for item in a])``.
+    However, this idea fails if `ar2` is a set, or similar (non-sequence)
+    container:  As ``ar2`` is converted to an array, in those cases
+    ``asarray(ar2)`` is an object array rather than the expected array of
+    contained values.
+
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    >>> test = np.array([0, 1, 2, 5, 0])
+    >>> states = [0, 2]
+    >>> mask = np.in1d(test, states)
+    >>> mask
+    array([ True, False,  True, False,  True], dtype=bool)
+    >>> test[mask]
+    array([0, 2, 0])
+    >>> mask = np.in1d(test, states, invert=True)
+    >>> mask
+    array([False,  True, False,  True, False], dtype=bool)
+    >>> test[mask]
+    array([1, 5])
+    """
+    # Ravel both arrays, behavior for the first array could be different
+    ar1 = np.asarray(ar1).ravel()
+    ar2 = np.asarray(ar2).ravel()
+
+    # This code is significantly faster when the condition is satisfied.
+    if len(ar2) < 10 * len(ar1) ** 0.145:
+        if invert:
+            mask = np.ones(len(ar1), dtype=np.bool)
+            for a in ar2:
+                mask &= (ar1 != a)
+        else:
+            mask = np.zeros(len(ar1), dtype=np.bool)
+            for a in ar2:
+                mask |= (ar1 == a)
+        return mask
+
+    # Otherwise use sorting
+    if not assume_unique:
+        ar1, rev_idx = np.unique(ar1, return_inverse=True)
+        ar2 = np.unique(ar2)
+
+    ar = np.concatenate((ar1, ar2))
+    # We need this to be a stable sort, so always use 'mergesort'
+    # here. The values from the first array should always come before
+    # the values from the second array.
+    order = ar.argsort(kind='mergesort')
+    sar = ar[order]
+    if invert:
+        bool_ar = (sar[1:] != sar[:-1])
+    else:
+        bool_ar = (sar[1:] == sar[:-1])
+    flag = np.concatenate((bool_ar, [invert]))
+    ret = np.empty(ar.shape, dtype=bool)
+    ret[order] = flag
+
+    if assume_unique:
+        return ret[:len(ar1)]
+    else:
+        return ret[rev_idx]
+
+def union1d(ar1, ar2):
+    """
+    Find the union of two arrays.
+
+    Return the unique, sorted array of values that are in either of the two
+    input arrays.
+
+    Parameters
+    ----------
+    ar1, ar2 : array_like
+        Input arrays. They are flattened if they are not already 1D.
+
+    Returns
+    -------
+    union1d : ndarray
+        Unique, sorted union of the input arrays.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> np.union1d([-1, 0, 1], [-2, 0, 2])
+    array([-2, -1,  0,  1,  2])
+
+    To find the union of more than two arrays, use functools.reduce:
+
+    >>> from functools import reduce
+    >>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
+    array([1, 2, 3, 4, 6])
+    """
+    return unique(np.concatenate((ar1, ar2)))
+
+def setdiff1d(ar1, ar2, assume_unique=False):
+    """
+    Find the set difference of two arrays.
+
+    Return the sorted, unique values in `ar1` that are not in `ar2`.
+
+    Parameters
+    ----------
+    ar1 : array_like
+        Input array.
+    ar2 : array_like
+        Input comparison array.
+    assume_unique : bool
+        If True, the input arrays are both assumed to be unique, which
+        can speed up the calculation.  Default is False.
+
+    Returns
+    -------
+    setdiff1d : ndarray
+        Sorted 1D array of values in `ar1` that are not in `ar2`.
+
+    See Also
+    --------
+    numpy.lib.arraysetops : Module with a number of other functions for
+                            performing set operations on arrays.
+
+    Examples
+    --------
+    >>> a = np.array([1, 2, 3, 2, 4, 1])
+    >>> b = np.array([3, 4, 5, 6])
+    >>> np.setdiff1d(a, b)
+    array([1, 2])
+
+    """
+    if assume_unique:
+        ar1 = np.asarray(ar1).ravel()
+    else:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.py
new file mode 100644
index 0000000000..fb52ada86c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.py
@@ -0,0 +1,225 @@
+"""
+A buffered iterator for big arrays.
+
+This module solves the problem of iterating over a big file-based array
+without having to read it into memory. The `Arrayterator` class wraps
+an array object, and when iterated it will return sub-arrays with at most
+a user-specified number of elements.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from operator import mul
+from functools import reduce
+
+from numpy.compat import long
+
+__all__ = ['Arrayterator']
+
+
+class Arrayterator(object):
+    """
+    Buffered iterator for big arrays.
+
+    `Arrayterator` creates a buffered iterator for reading big arrays in small
+    contiguous blocks. The class is useful for objects stored in the
+    file system. It allows iteration over the object *without* reading
+    everything in memory; instead, small blocks are read and iterated over.
+
+    `Arrayterator` can be used with any object that supports multidimensional
+    slices. This includes NumPy arrays, but also variables from
+    Scientific.IO.NetCDF or pynetcdf for example.
+
+    Parameters
+    ----------
+    var : array_like
+        The object to iterate over.
+    buf_size : int, optional
+        The buffer size. If `buf_size` is supplied, the maximum amount of
+        data that will be read into memory is `buf_size` elements.
+        Default is None, which will read as many element as possible
+        into memory.
+
+    Attributes
+    ----------
+    var
+    buf_size
+    start
+    stop
+    step
+    shape
+    flat
+
+    See Also
+    --------
+    ndenumerate : Multidimensional array iterator.
+    flatiter : Flat array iterator.
+    memmap : Create a memory-map to an array stored in a binary file on disk.
+
+    Notes
+    -----
+    The algorithm works by first finding a "running dimension", along which
+    the blocks will be extracted. Given an array of dimensions
+    ``(d1, d2, ..., dn)``, e.g. if `buf_size` is smaller than ``d1``, the
+    first dimension will be used. If, on the other hand,
+    ``d1 < buf_size < d1*d2`` the second dimension will be used, and so on.
+    Blocks are extracted along this dimension, and when the last block is
+    returned the process continues from the next dimension, until all
+    elements have been read.
+
+    Examples
+    --------
+    >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+    >>> a_itor = np.lib.Arrayterator(a, 2)
+    >>> a_itor.shape
+    (3, 4, 5, 6)
+
+    Now we can iterate over ``a_itor``, and it will return arrays of size
+    two. Since `buf_size` was smaller than any dimension, the first
+    dimension will be iterated over first:
+
+    >>> for subarr in a_itor:
+    ...     if not subarr.all():
+    ...         print(subarr, subarr.shape)
+    ...
+    [[[[0 1]]]] (1, 1, 1, 2)
+
+    """
+
+    def __init__(self, var, buf_size=None):
+        self.var = var
+        self.buf_size = buf_size
+
+        self.start = [0 for dim in var.shape]
+        self.stop = [dim for dim in var.shape]
+        self.step = [1 for dim in var.shape]
+
+    def __getattr__(self, attr):
+        return getattr(self.var, attr)
+
+    def __getitem__(self, index):
+        """
+        Return a new arrayterator.
+
+        """
+        # Fix index, handling ellipsis and incomplete slices.
+        if not isinstance(index, tuple):
+            index = (index,)
+        fixed = []
+        length, dims = len(index), len(self.shape)
+        for slice_ in index:
+            if slice_ is Ellipsis:
+                fixed.extend([slice(None)] * (dims-length+1))
+                length = len(fixed)
+            elif isinstance(slice_, (int, long)):
+                fixed.append(slice(slice_, slice_+1, 1))
+            else:
+                fixed.append(slice_)
+        index = tuple(fixed)
+        if len(index) < dims:
+            index += (slice(None),) * (dims-len(index))
+
+        # Return a new arrayterator object.
+        out = self.__class__(self.var, self.buf_size)
+        for i, (start, stop, step, slice_) in enumerate(
+                zip(self.start, self.stop, self.step, index)):
+            out.start[i] = start + (slice_.start or 0)
+            out.step[i] = step * (slice_.step or 1)
+            out.stop[i] = start + (slice_.stop or stop-start)
+            out.stop[i] = min(stop, out.stop[i])
+        return out
+
+    def __array__(self):
+        """
+        Return corresponding data.
+
+        """
+        slice_ = tuple(slice(*t) for t in zip(
+                self.start, self.stop, self.step))
+        return self.var[slice_]
+
+    @property
+    def flat(self):
+        """
+        A 1-D flat iterator for Arrayterator objects.
+
+        This iterator returns elements of the array to be iterated over in
+        `Arrayterator` one by one. It is similar to `flatiter`.
+
+        See Also
+        --------
+        Arrayterator
+        flatiter
+
+        Examples
+        --------
+        >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+        >>> a_itor = np.lib.Arrayterator(a, 2)
+
+        >>> for subarr in a_itor.flat:
+        ...     if not subarr:
+        ...         print(subarr, type(subarr))
+        ...
+        0 <type 'numpy.int32'>
+
+        """
+        for block in self:
+            for value in block.flat:
+                yield value
+
+    @property
+    def shape(self):
+        """
+        The shape of the array to be iterated over.
+
+        For an example, see `Arrayterator`.
+
+        """
+        return tuple(((stop-start-1)//step+1) for start, stop, step in
+                zip(self.start, self.stop, self.step))
+
+    def __iter__(self):
+        # Skip arrays with degenerate dimensions
+        if [dim for dim in self.shape if dim <= 0]:
+            return
+
+        start = self.start[:]
+        stop = self.stop[:]
+        step = self.step[:]
+        ndims = len(self.var.shape)
+
+        while True:
+            count = self.buf_size or reduce(mul, self.shape)
+
+            # iterate over each dimension, looking for the
+            # running dimension (ie, the dimension along which
+            # the blocks will be built from)
+            rundim = 0
+            for i in range(ndims-1, -1, -1):
+                # if count is zero we ran out of elements to read
+                # along higher dimensions, so we read only a single position
+                if count == 0:
+                    stop[i] = start[i]+1
+                elif count <= self.shape[i]:
+                    # limit along this dimension
+                    stop[i] = start[i] + count*step[i]
+                    rundim = i
+                else:
+                    # read everything along this dimension
+                    stop[i] = self.stop[i]
+                stop[i] = min(self.stop[i], stop[i])
+                count = count//self.shape[i]
+
+            # yield a block
+            slice_ = tuple(slice(*t) for t in zip(start, stop, step))
+            yield self.var[slice_]
+
+            # Update start position, taking care of overflow to
+            # other dimensions
+            start[rundim] = stop[rundim]  # start where we stopped
+            for i in range(ndims-1, 0, -1):
+                if start[i] >= self.stop[i]:
+                    start[i] = self.start[i]
+                    start[i-1] += self.step[i-1]
+            if start[0] >= self.stop[0]:
+                return
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/financial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/financial.py
new file mode 100644
index 0000000000..c42424da17
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/financial.py
@@ -0,0 +1,737 @@
+"""Some simple financial calculations
+
+patterned after spreadsheet computations.
+
+There is some complexity in each function
+so that the functions behave like ufuncs with
+broadcasting and being able to be called with scalars
+or arrays (or other sequences).
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = ['fv', 'pmt', 'nper', 'ipmt', 'ppmt', 'pv', 'rate',
+           'irr', 'npv', 'mirr']
+
+_when_to_num = {'end':0, 'begin':1,
+                'e':0, 'b':1,
+                0:0, 1:1,
+                'beginning':1,
+                'start':1,
+                'finish':0}
+
+def _convert_when(when):
+    #Test to see if when has already been converted to ndarray
+    #This will happen if one function calls another, for example ppmt
+    if isinstance(when, np.ndarray):
+        return when
+    try:
+        return _when_to_num[when]
+    except (KeyError, TypeError):
+        return [_when_to_num[x] for x in when]
+
+
+def fv(rate, nper, pmt, pv, when='end'):
+    """
+    Compute the future value.
+
+    Given:
+     * a present value, `pv`
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * a (fixed) payment, `pmt`, paid either
+     * at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the value at the end of the `nper` periods
+
+    Parameters
+    ----------
+    rate : scalar or array_like of shape(M, )
+        Rate of interest as decimal (not per cent) per period
+    nper : scalar or array_like of shape(M, )
+        Number of compounding periods
+    pmt : scalar or array_like of shape(M, )
+        Payment
+    pv : scalar or array_like of shape(M, )
+        Present value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0)).
+        Defaults to {'end', 0}.
+
+    Returns
+    -------
+    out : ndarray
+        Future values.  If all input is scalar, returns a scalar float.  If
+        any input is array_like, returns future values for each input element.
+        If multiple inputs are array_like, they all must have the same shape.
+
+    Notes
+    -----
+    The future value is computed by solving the equation::
+
+     fv +
+     pv*(1+rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
+
+    or, when ``rate == 0``::
+
+     fv + pv + pmt * nper == 0
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+       OpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the future value after 10 years of saving $100 now, with
+    an additional monthly savings of $100.  Assume the interest rate is
+    5% (annually) compounded monthly?
+
+    >>> np.fv(0.05/12, 10*12, -100, -100)
+    15692.928894335748
+
+    By convention, the negative sign represents cash flow out (i.e. money not
+    available today).  Thus, saving $100 a month at 5% annual interest leads
+    to $15,692.93 available to spend in 10 years.
+
+    If any input is array_like, returns an array of equal shape.  Let's
+    compare different interest rates from the example above.
+
+    >>> a = np.array((0.05, 0.06, 0.07))/12
+    >>> np.fv(a, 10*12, -100, -100)
+    array([ 15692.92889434,  16569.87435405,  17509.44688102])
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pmt, pv, when) = map(np.asarray, [rate, nper, pmt, pv, when])
+    temp = (1+rate)**nper
+    miter = np.broadcast(rate, nper, pmt, pv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate == zer, nper + zer,
+                    (1 + rate*when)*(temp - 1)/rate + zer)
+    return -(pv*temp + pmt*fact)
+
+def pmt(rate, nper, pv, fv=0, when='end'):
+    """
+    Compute the payment against loan principal plus interest.
+
+    Given:
+     * a present value, `pv` (e.g., an amount borrowed)
+     * a future value, `fv` (e.g., 0)
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * and (optional) specification of whether payment is made
+       at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the (fixed) periodic payment.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    nper : array_like
+        Number of compounding periods
+    pv : array_like
+        Present value
+    fv : array_like,  optional
+        Future value (default = 0)
+    when : {{'begin', 1}, {'end', 0}}, {string, int}
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Returns
+    -------
+    out : ndarray
+        Payment against loan plus interest.  If all input is scalar, returns a
+        scalar float.  If any input is array_like, returns payment for each
+        input element. If multiple inputs are array_like, they all must have
+        the same shape.
+
+    Notes
+    -----
+    The payment is computed by solving the equation::
+
+     fv +
+     pv*(1 + rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) == 0
+
+    or, when ``rate == 0``::
+
+      fv + pv + pmt * nper == 0
+
+    for ``pmt``.
+
+    Note that computing a monthly mortgage payment is only
+    one use for this function.  For example, pmt returns the
+    periodic deposit one must make to achieve a specified
+    future balance given an initial deposit, a fixed,
+    periodically compounded interest rate, and the total
+    number of periods.
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php
+       ?wg_abbrev=office-formulaOpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the monthly payment needed to pay off a $200,000 loan in 15
+    years at an annual interest rate of 7.5%?
+
+    >>> np.pmt(0.075/12, 12*15, 200000)
+    -1854.0247200054619
+
+    In order to pay-off (i.e., have a future-value of 0) the $200,000 obtained
+    today, a monthly payment of $1,854.02 would be required.  Note that this
+    example illustrates usage of `fv` having a default value of 0.
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pv, fv, when) = map(np.asarray, [rate, nper, pv, fv, when])
+    temp = (1 + rate)**nper
+    mask = (rate == 0.0)
+    np.copyto(rate, 1.0, where=mask)
+    z = np.zeros(np.broadcast(rate, nper, pv, fv, when).shape)
+    fact = np.where(mask != z, nper + z, (1 + rate*when)*(temp - 1)/rate + z)
+    return -(fv + pv*temp) / fact
+
+def nper(rate, pmt, pv, fv=0, when='end'):
+    """
+    Compute the number of periodic payments.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    pmt : array_like
+        Payment
+    pv : array_like
+        Present value
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Notes
+    -----
+    The number of periods ``nper`` is computed by solving the equation::
+
+     fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate*((1+rate)**nper-1) = 0
+
+    but if ``rate = 0`` then::
+
+     fv + pv + pmt*nper = 0
+
+    Examples
+    --------
+    If you only had $150/month to pay towards the loan, how long would it take
+    to pay-off a loan of $8,000 at 7% annual interest?
+
+    >>> print(round(np.nper(0.07/12, -150, 8000), 5))
+    64.07335
+
+    So, over 64 months would be required to pay off the loan.
+
+    The same analysis could be done with several different interest rates
+    and/or payments and/or total amounts to produce an entire table.
+
+    >>> np.nper(*(np.ogrid[0.07/12: 0.08/12: 0.01/12,
+    ...                    -150   : -99     : 50    ,
+    ...                    8000   : 9001    : 1000]))
+    array([[[  64.07334877,   74.06368256],
+            [ 108.07548412,  127.99022654]],
+           [[  66.12443902,   76.87897353],
+            [ 114.70165583,  137.90124779]]])
+
+    """
+    when = _convert_when(when)
+    (rate, pmt, pv, fv, when) = map(np.asarray, [rate, pmt, pv, fv, when])
+
+    use_zero_rate = False
+    with np.errstate(divide="raise"):
+        try:
+            z = pmt*(1.0+rate*when)/rate
+        except FloatingPointError:
+            use_zero_rate = True
+
+    if use_zero_rate:
+        return (-fv + pv) / (pmt + 0.0)
+    else:
+        A = -(fv + pv)/(pmt+0.0)
+        B = np.log((-fv+z) / (pv+z))/np.log(1.0+rate)
+        miter = np.broadcast(rate, pmt, pv, fv, when)
+        zer = np.zeros(miter.shape)
+        return np.where(rate == zer, A + zer, B + zer) + 0.0
+
+def ipmt(rate, per, nper, pv, fv=0.0, when='end'):
+    """
+    Compute the interest portion of a payment.
+
+    Parameters
+    ----------
+    rate : scalar or array_like of shape(M, )
+        Rate of interest as decimal (not per cent) per period
+    per : scalar or array_like of shape(M, )
+        Interest paid against the loan changes during the life or the loan.
+        The `per` is the payment period to calculate the interest amount.
+    nper : scalar or array_like of shape(M, )
+        Number of compounding periods
+    pv : scalar or array_like of shape(M, )
+        Present value
+    fv : scalar or array_like of shape(M, ), optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0)).
+        Defaults to {'end', 0}.
+
+    Returns
+    -------
+    out : ndarray
+        Interest portion of payment.  If all input is scalar, returns a scalar
+        float.  If any input is array_like, returns interest payment for each
+        input element. If multiple inputs are array_like, they all must have
+        the same shape.
+
+    See Also
+    --------
+    ppmt, pmt, pv
+
+    Notes
+    -----
+    The total payment is made up of payment against principal plus interest.
+
+    ``pmt = ppmt + ipmt``
+
+    Examples
+    --------
+    What is the amortization schedule for a 1 year loan of $2500 at
+    8.24% interest per year compounded monthly?
+
+    >>> principal = 2500.00
+
+    The 'per' variable represents the periods of the loan.  Remember that
+    financial equations start the period count at 1!
+
+    >>> per = np.arange(1*12) + 1
+    >>> ipmt = np.ipmt(0.0824/12, per, 1*12, principal)
+    >>> ppmt = np.ppmt(0.0824/12, per, 1*12, principal)
+
+    Each element of the sum of the 'ipmt' and 'ppmt' arrays should equal
+    'pmt'.
+
+    >>> pmt = np.pmt(0.0824/12, 1*12, principal)
+    >>> np.allclose(ipmt + ppmt, pmt)
+    True
+
+    >>> fmt = '{0:2d} {1:8.2f} {2:8.2f} {3:8.2f}'
+    >>> for payment in per:
+    ...     index = payment - 1
+    ...     principal = principal + ppmt[index]
+    ...     print(fmt.format(payment, ppmt[index], ipmt[index], principal))
+     1  -200.58   -17.17  2299.42
+     2  -201.96   -15.79  2097.46
+     3  -203.35   -14.40  1894.11
+     4  -204.74   -13.01  1689.37
+     5  -206.15   -11.60  1483.22
+     6  -207.56   -10.18  1275.66
+     7  -208.99    -8.76  1066.67
+     8  -210.42    -7.32   856.25
+     9  -211.87    -5.88   644.38
+    10  -213.32    -4.42   431.05
+    11  -214.79    -2.96   216.26
+    12  -216.26    -1.49    -0.00
+
+    >>> interestpd = np.sum(ipmt)
+    >>> np.round(interestpd, 2)
+    -112.98
+
+    """
+    when = _convert_when(when)
+    rate, per, nper, pv, fv, when = np.broadcast_arrays(rate, per, nper,
+                                                        pv, fv, when)
+    total_pmt = pmt(rate, nper, pv, fv, when)
+    ipmt = _rbl(rate, per, total_pmt, pv, when)*rate
+    try:
+        ipmt = np.where(when == 1, ipmt/(1 + rate), ipmt)
+        ipmt = np.where(np.logical_and(when == 1, per == 1), 0.0, ipmt)
+    except IndexError:
+        pass
+    return ipmt
+
+def _rbl(rate, per, pmt, pv, when):
+    """
+    This function is here to simply have a different name for the 'fv'
+    function to not interfere with the 'fv' keyword argument within the 'ipmt'
+    function.  It is the 'remaining balance on loan' which might be useful as
+    it's own function, but is easily calculated with the 'fv' function.
+    """
+    return fv(rate, (per - 1), pmt, pv, when)
+
+def ppmt(rate, per, nper, pv, fv=0.0, when='end'):
+    """
+    Compute the payment against loan principal.
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    per : array_like, int
+        Amount paid against the loan changes.  The `per` is the period of
+        interest.
+    nper : array_like
+        Number of compounding periods
+    pv : array_like
+        Present value
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}
+        When payments are due ('begin' (1) or 'end' (0))
+
+    See Also
+    --------
+    pmt, pv, ipmt
+
+    """
+    total = pmt(rate, nper, pv, fv, when)
+    return total - ipmt(rate, per, nper, pv, fv, when)
+
+def pv(rate, nper, pmt, fv=0.0, when='end'):
+    """
+    Compute the present value.
+
+    Given:
+     * a future value, `fv`
+     * an interest `rate` compounded once per period, of which
+       there are
+     * `nper` total
+     * a (fixed) payment, `pmt`, paid either
+     * at the beginning (`when` = {'begin', 1}) or the end
+       (`when` = {'end', 0}) of each period
+
+    Return:
+       the value now
+
+    Parameters
+    ----------
+    rate : array_like
+        Rate of interest (per period)
+    nper : array_like
+        Number of compounding periods
+    pmt : array_like
+        Payment
+    fv : array_like, optional
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+
+    Returns
+    -------
+    out : ndarray, float
+        Present value of a series of payments or investments.
+
+    Notes
+    -----
+    The present value is computed by solving the equation::
+
+     fv +
+     pv*(1 + rate)**nper +
+     pmt*(1 + rate*when)/rate*((1 + rate)**nper - 1) = 0
+
+    or, when ``rate = 0``::
+
+     fv + pv + pmt * nper = 0
+
+    for `pv`, which is then returned.
+
+    References
+    ----------
+    .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+       Open Document Format for Office Applications (OpenDocument)v1.2,
+       Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+       Pre-Draft 12. Organization for the Advancement of Structured Information
+       Standards (OASIS). Billerica, MA, USA. [ODT Document].
+       Available:
+       http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+       OpenDocument-formula-20090508.odt
+
+    Examples
+    --------
+    What is the present value (e.g., the initial investment)
+    of an investment that needs to total $15692.93
+    after 10 years of saving $100 every month?  Assume the
+    interest rate is 5% (annually) compounded monthly.
+
+    >>> np.pv(0.05/12, 10*12, -100, 15692.93)
+    -100.00067131625819
+
+    By convention, the negative sign represents cash flow out
+    (i.e., money not available today).  Thus, to end up with
+    $15,692.93 in 10 years saving $100 a month at 5% annual
+    interest, one's initial deposit should also be $100.
+
+    If any input is array_like, ``pv`` returns an array of equal shape.
+    Let's compare different interest rates in the example above:
+
+    >>> a = np.array((0.05, 0.04, 0.03))/12
+    >>> np.pv(a, 10*12, -100, 15692.93)
+    array([ -100.00067132,  -649.26771385, -1273.78633713])
+
+    So, to end up with the same $15692.93 under the same $100 per month
+    "savings plan," for annual interest rates of 4% and 3%, one would
+    need initial investments of $649.27 and $1273.79, respectively.
+
+    """
+    when = _convert_when(when)
+    (rate, nper, pmt, fv, when) = map(np.asarray, [rate, nper, pmt, fv, when])
+    temp = (1+rate)**nper
+    miter = np.broadcast(rate, nper, pmt, fv, when)
+    zer = np.zeros(miter.shape)
+    fact = np.where(rate == zer, nper+zer, (1+rate*when)*(temp-1)/rate+zer)
+    return -(fv + pmt*fact)/temp
+
+# Computed with Sage
+#  (y + (r + 1)^n*x + p*((r + 1)^n - 1)*(r*w + 1)/r)/(n*(r + 1)^(n - 1)*x -
+#  p*((r + 1)^n - 1)*(r*w + 1)/r^2 + n*p*(r + 1)^(n - 1)*(r*w + 1)/r +
+#  p*((r + 1)^n - 1)*w/r)
+
+def _g_div_gp(r, n, p, x, y, w):
+    t1 = (r+1)**n
+    t2 = (r+1)**(n-1)
+    return ((y + t1*x + p*(t1 - 1)*(r*w + 1)/r) /
+                (n*t2*x - p*(t1 - 1)*(r*w + 1)/(r**2) + n*p*t2*(r*w + 1)/r +
+                 p*(t1 - 1)*w/r))
+
+# Use Newton's iteration until the change is less than 1e-6
+#  for all values or a maximum of 100 iterations is reached.
+#  Newton's rule is
+#  r_{n+1} = r_{n} - g(r_n)/g'(r_n)
+#     where
+#  g(r) is the formula
+#  g'(r) is the derivative with respect to r.
+def rate(nper, pmt, pv, fv, when='end', guess=0.10, tol=1e-6, maxiter=100):
+    """
+    Compute the rate of interest per period.
+
+    Parameters
+    ----------
+    nper : array_like
+        Number of compounding periods
+    pmt : array_like
+        Payment
+    pv : array_like
+        Present value
+    fv : array_like
+        Future value
+    when : {{'begin', 1}, {'end', 0}}, {string, int}, optional
+        When payments are due ('begin' (1) or 'end' (0))
+    guess : float, optional
+        Starting guess for solving the rate of interest
+    tol : float, optional
+        Required tolerance for the solution
+    maxiter : int, optional
+        Maximum iterations in finding the solution
+
+    Notes
+    -----
+    The rate of interest is computed by iteratively solving the
+    (non-linear) equation::
+
+     fv + pv*(1+rate)**nper + pmt*(1+rate*when)/rate * ((1+rate)**nper - 1) = 0
+
+    for ``rate``.
+
+    References
+    ----------
+    Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May). Open Document
+    Format for Office Applications (OpenDocument)v1.2, Part 2: Recalculated
+    Formula (OpenFormula) Format - Annotated Version, Pre-Draft 12.
+    Organization for the Advancement of Structured Information Standards
+    (OASIS). Billerica, MA, USA. [ODT Document]. Available:
+    http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+    OpenDocument-formula-20090508.odt
+
+    """
+    when = _convert_when(when)
+    (nper, pmt, pv, fv, when) = map(np.asarray, [nper, pmt, pv, fv, when])
+    rn = guess
+    iter = 0
+    close = False
+    while (iter < maxiter) and not close:
+        rnp1 = rn - _g_div_gp(rn, nper, pmt, pv, fv, when)
+        diff = abs(rnp1-rn)
+        close = np.all(diff < tol)
+        iter += 1
+        rn = rnp1
+    if not close:
+        # Return nan's in array of the same shape as rn
+        return np.nan + rn
+    else:
+        return rn
+
+def irr(values):
+    """
+    Return the Internal Rate of Return (IRR).
+
+    This is the "average" periodically compounded rate of return
+    that gives a net present value of 0.0; for a more complete explanation,
+    see Notes below.
+
+    Parameters
+    ----------
+    values : array_like, shape(N,)
+        Input cash flows per time period.  By convention, net "deposits"
+        are negative and net "withdrawals" are positive.  Thus, for
+        example, at least the first element of `values`, which represents
+        the initial investment, will typically be negative.
+
+    Returns
+    -------
+    out : float
+        Internal Rate of Return for periodic input values.
+
+    Notes
+    -----
+    The IRR is perhaps best understood through an example (illustrated
+    using np.irr in the Examples section below).  Suppose one invests 100
+    units and then makes the following withdrawals at regular (fixed)
+    intervals: 39, 59, 55, 20.  Assuming the ending value is 0, one's 100
+    unit investment yields 173 units; however, due to the combination of
+    compounding and the periodic withdrawals, the "average" rate of return
+    is neither simply 0.73/4 nor (1.73)^0.25-1.  Rather, it is the solution
+    (for :math:`r`) of the equation:
+
+    .. math:: -100 + \\frac{39}{1+r} + \\frac{59}{(1+r)^2}
+     + \\frac{55}{(1+r)^3} + \\frac{20}{(1+r)^4} = 0
+
+    In general, for `values` :math:`= [v_0, v_1, ... v_M]`,
+    irr is the solution of the equation: [G]_
+
+    .. math:: \\sum_{t=0}^M{\\frac{v_t}{(1+irr)^{t}}} = 0
+
+    References
+    ----------
+    .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+       Addison-Wesley, 2003, pg. 348.
+
+    Examples
+    --------
+    >>> round(irr([-100, 39, 59, 55, 20]), 5)
+    0.28095
+    >>> round(irr([-100, 0, 0, 74]), 5)
+    -0.0955
+    >>> round(irr([-100, 100, 0, -7]), 5)
+    -0.0833
+    >>> round(irr([-100, 100, 0, 7]), 5)
+    0.06206
+    >>> round(irr([-5, 10.5, 1, -8, 1]), 5)
+    0.0886
+
+    (Compare with the Example given for numpy.lib.financial.npv)
+
+    """
+    res = np.roots(values[::-1])
+    mask = (res.imag == 0) & (res.real > 0)
+    if res.size == 0:
+        return np.nan
+    res = res[mask].real
+    # NPV(rate) = 0 can have more than one solution so we return
+    # only the solution closest to zero.
+    rate = 1.0/res - 1
+    rate = rate.item(np.argmin(np.abs(rate)))
+    return rate
+
+def npv(rate, values):
+    """
+    Returns the NPV (Net Present Value) of a cash flow series.
+
+    Parameters
+    ----------
+    rate : scalar
+        The discount rate.
+    values : array_like, shape(M, )
+        The values of the time series of cash flows.  The (fixed) time
+        interval between cash flow "events" must be the same as that for
+        which `rate` is given (i.e., if `rate` is per year, then precisely
+        a year is understood to elapse between each cash flow event).  By
+        convention, investments or "deposits" are negative, income or
+        "withdrawals" are positive; `values` must begin with the initial
+        investment, thus `values[0]` will typically be negative.
+
+    Returns
+    -------
+    out : float
+        The NPV of the input cash flow series `values` at the discount
+        `rate`.
+
+    Notes
+    -----
+    Returns the result of: [G]_
+
+    .. math :: \\sum_{t=0}^{M-1}{\\frac{values_t}{(1+rate)^{t}}}
+
+    References
+    ----------
+    .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+       Addison-Wesley, 2003, pg. 346.
+
+    Examples
+    --------
+    >>> np.npv(0.281,[-100, 39, 59, 55, 20])
+    -0.0084785916384548798
+
+    (Compare with the Example given for numpy.lib.financial.irr)
+
+    """
+    values = np.asarray(values)
+    return (values / (1+rate)**np.arange(0, len(values))).sum(axis=0)
+
+def mirr(values, finance_rate, reinvest_rate):
+    """
+    Modified internal rate of return.
+
+    Parameters
+    ----------
+    values : array_like
+        Cash flows (must contain at least one positive and one negative
+        value) or nan is returned.  The first value is considered a sunk
+        cost at time zero.
+    finance_rate : scalar
+        Interest rate paid on the cash flows
+    reinvest_rate : scalar
+        Interest rate received on the cash flows upon reinvestment
+
+    Returns
+    -------
+    out : float
+        Modified internal rate of return
+
+    """
+    values = np.asarray(values, dtype=np.double)
+    n = values.size
+    pos = values > 0
+    neg = values < 0
+    if not (pos.any() and neg.any()):
+        return np.nan
+    numer = np.abs(npv(reinvest_rate, values*pos))
+    denom = np.abs(npv(finance_rate, values*neg))
+    return (numer/denom)**(1.0/(n - 1))*(1 + reinvest_rate) - 1
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/format.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/format.py
new file mode 100644
index 0000000000..a0f2c54975
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/format.py
@@ -0,0 +1,813 @@
+"""
+Define a simple format for saving numpy arrays to disk with the full
+information about them.
+
+The ``.npy`` format is the standard binary file format in NumPy for
+persisting a *single* arbitrary NumPy array on disk. The format stores all
+of the shape and dtype information necessary to reconstruct the array
+correctly even on another machine with a different architecture.
+The format is designed to be as simple as possible while achieving
+its limited goals.
+
+The ``.npz`` format is the standard format for persisting *multiple* NumPy
+arrays on disk. A ``.npz`` file is a zip file containing multiple ``.npy``
+files, one for each array.
+
+Capabilities
+------------
+
+- Can represent all NumPy arrays including nested record arrays and
+  object arrays.
+
+- Represents the data in its native binary form.
+
+- Supports Fortran-contiguous arrays directly.
+
+- Stores all of the necessary information to reconstruct the array
+  including shape and dtype on a machine of a different
+  architecture.  Both little-endian and big-endian arrays are
+  supported, and a file with little-endian numbers will yield
+  a little-endian array on any machine reading the file. The
+  types are described in terms of their actual sizes. For example,
+  if a machine with a 64-bit C "long int" writes out an array with
+  "long ints", a reading machine with 32-bit C "long ints" will yield
+  an array with 64-bit integers.
+
+- Is straightforward to reverse engineer. Datasets often live longer than
+  the programs that created them. A competent developer should be
+  able to create a solution in their preferred programming language to
+  read most ``.npy`` files that he has been given without much
+  documentation.
+
+- Allows memory-mapping of the data. See `open_memmep`.
+
+- Can be read from a filelike stream object instead of an actual file.
+
+- Stores object arrays, i.e. arrays containing elements that are arbitrary
+  Python objects. Files with object arrays are not to be mmapable, but
+  can be read and written to disk.
+
+Limitations
+-----------
+
+- Arbitrary subclasses of numpy.ndarray are not completely preserved.
+  Subclasses will be accepted for writing, but only the array data will
+  be written out. A regular numpy.ndarray object will be created
+  upon reading the file.
+
+.. warning::
+
+  Due to limitations in the interpretation of structured dtypes, dtypes
+  with fields with empty names will have the names replaced by 'f0', 'f1',
+  etc. Such arrays will not round-trip through the format entirely
+  accurately. The data is intact; only the field names will differ. We are
+  working on a fix for this. This fix will not require a change in the
+  file format. The arrays with such structures can still be saved and
+  restored, and the correct dtype may be restored by using the
+  ``loadedarray.view(correct_dtype)`` method.
+
+File extensions
+---------------
+
+We recommend using the ``.npy`` and ``.npz`` extensions for files saved
+in this format. This is by no means a requirement; applications may wish
+to use these file formats but use an extension specific to the
+application. In the absence of an obvious alternative, however,
+we suggest using ``.npy`` and ``.npz``.
+
+Version numbering
+-----------------
+
+The version numbering of these formats is independent of NumPy version
+numbering. If the format is upgraded, the code in `numpy.io` will still
+be able to read and write Version 1.0 files.
+
+Format Version 1.0
+------------------
+
+The first 6 bytes are a magic string: exactly ``\\x93NUMPY``.
+
+The next 1 byte is an unsigned byte: the major version number of the file
+format, e.g. ``\\x01``.
+
+The next 1 byte is an unsigned byte: the minor version number of the file
+format, e.g. ``\\x00``. Note: the version of the file format is not tied
+to the version of the numpy package.
+
+The next 2 bytes form a little-endian unsigned short int: the length of
+the header data HEADER_LEN.
+
+The next HEADER_LEN bytes form the header data describing the array's
+format. It is an ASCII string which contains a Python literal expression
+of a dictionary. It is terminated by a newline (``\\n``) and padded with
+spaces (``\\x20``) to make the total length of
+``magic string + 4 + HEADER_LEN`` be evenly divisible by 16 for alignment
+purposes.
+
+The dictionary contains three keys:
+
+    "descr" : dtype.descr
+      An object that can be passed as an argument to the `numpy.dtype`
+      constructor to create the array's dtype.
+    "fortran_order" : bool
+      Whether the array data is Fortran-contiguous or not. Since
+      Fortran-contiguous arrays are a common form of non-C-contiguity,
+      we allow them to be written directly to disk for efficiency.
+    "shape" : tuple of int
+      The shape of the array.
+
+For repeatability and readability, the dictionary keys are sorted in
+alphabetic order. This is for convenience only. A writer SHOULD implement
+this if possible. A reader MUST NOT depend on this.
+
+Following the header comes the array data. If the dtype contains Python
+objects (i.e. ``dtype.hasobject is True``), then the data is a Python
+pickle of the array. Otherwise the data is the contiguous (either C-
+or Fortran-, depending on ``fortran_order``) bytes of the array.
+Consumers can figure out the number of bytes by multiplying the number
+of elements given by the shape (noting that ``shape=()`` means there is
+1 element) by ``dtype.itemsize``.
+
+Format Version 2.0
+------------------
+
+The version 1.0 format only allowed the array header to have a total size of
+65535 bytes.  This can be exceeded by structured arrays with a large number of
+columns.  The version 2.0 format extends the header size to 4 GiB.
+`numpy.save` will automatically save in 2.0 format if the data requires it,
+else it will always use the more compatible 1.0 format.
+
+The description of the fourth element of the header therefore has become:
+"The next 4 bytes form a little-endian unsigned int: the length of the header
+data HEADER_LEN."
+
+Notes
+-----
+The ``.npy`` format, including reasons for creating it and a comparison of
+alternatives, is described fully in the "npy-format" NEP.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy
+import sys
+import io
+import warnings
+from numpy.lib.utils import safe_eval
+from numpy.compat import asbytes, asstr, isfileobj, long, basestring
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+
+MAGIC_PREFIX = asbytes('\x93NUMPY')
+MAGIC_LEN = len(MAGIC_PREFIX) + 2
+BUFFER_SIZE = 2**18  # size of buffer for reading npz files in bytes
+
+# difference between version 1.0 and 2.0 is a 4 byte (I) header length
+# instead of 2 bytes (H) allowing storage of large structured arrays
+
+def _check_version(version):
+    if version not in [(1, 0), (2, 0), None]:
+        msg = "we only support format version (1,0) and (2, 0), not %s"
+        raise ValueError(msg % (version,))
+
+def magic(major, minor):
+    """ Return the magic string for the given file format version.
+
+    Parameters
+    ----------
+    major : int in [0, 255]
+    minor : int in [0, 255]
+
+    Returns
+    -------
+    magic : str
+
+    Raises
+    ------
+    ValueError if the version cannot be formatted.
+    """
+    if major < 0 or major > 255:
+        raise ValueError("major version must be 0 <= major < 256")
+    if minor < 0 or minor > 255:
+        raise ValueError("minor version must be 0 <= minor < 256")
+    if sys.version_info[0] < 3:
+        return MAGIC_PREFIX + chr(major) + chr(minor)
+    else:
+        return MAGIC_PREFIX + bytes([major, minor])
+
+def read_magic(fp):
+    """ Read the magic string to get the version of the file format.
+
+    Parameters
+    ----------
+    fp : filelike object
+
+    Returns
+    -------
+    major : int
+    minor : int
+    """
+    magic_str = _read_bytes(fp, MAGIC_LEN, "magic string")
+    if magic_str[:-2] != MAGIC_PREFIX:
+        msg = "the magic string is not correct; expected %r, got %r"
+        raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2]))
+    if sys.version_info[0] < 3:
+        major, minor = map(ord, magic_str[-2:])
+    else:
+        major, minor = magic_str[-2:]
+    return major, minor
+
+def dtype_to_descr(dtype):
+    """
+    Get a serializable descriptor from the dtype.
+
+    The .descr attribute of a dtype object cannot be round-tripped through
+    the dtype() constructor. Simple types, like dtype('float32'), have
+    a descr which looks like a record array with one field with '' as
+    a name. The dtype() constructor interprets this as a request to give
+    a default name.  Instead, we construct descriptor that can be passed to
+    dtype().
+
+    Parameters
+    ----------
+    dtype : dtype
+        The dtype of the array that will be written to disk.
+
+    Returns
+    -------
+    descr : object
+        An object that can be passed to `numpy.dtype()` in order to
+        replicate the input dtype.
+
+    """
+    if dtype.names is not None:
+        # This is a record array. The .descr is fine.  XXX: parts of the
+        # record array with an empty name, like padding bytes, still get
+        # fiddled with. This needs to be fixed in the C implementation of
+        # dtype().
+        return dtype.descr
+    else:
+        return dtype.str
+
+def header_data_from_array_1_0(array):
+    """ Get the dictionary of header metadata from a numpy.ndarray.
+
+    Parameters
+    ----------
+    array : numpy.ndarray
+
+    Returns
+    -------
+    d : dict
+        This has the appropriate entries for writing its string representation
+        to the header of the file.
+    """
+    d = {'shape': array.shape}
+    if array.flags.c_contiguous:
+        d['fortran_order'] = False
+    elif array.flags.f_contiguous:
+        d['fortran_order'] = True
+    else:
+        # Totally non-contiguous data. We will have to make it C-contiguous
+        # before writing. Note that we need to test for C_CONTIGUOUS first
+        # because a 1-D array is both C_CONTIGUOUS and F_CONTIGUOUS.
+        d['fortran_order'] = False
+
+    d['descr'] = dtype_to_descr(array.dtype)
+    return d
+
+def _write_array_header(fp, d, version=None):
+    """ Write the header for an array and returns the version used
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string representation
+        to the header of the file.
+    version: tuple or None
+        None means use oldest that works
+        explicit version will raise a ValueError if the format does not
+        allow saving this data.  Default: None
+    Returns
+    -------
+    version : tuple of int
+        the file version which needs to be used to store the data
+    """
+    import struct
+    header = ["{"]
+    for key, value in sorted(d.items()):
+        # Need to use repr here, since we eval these when reading
+        header.append("'%s': %s, " % (key, repr(value)))
+    header.append("}")
+    header = "".join(header)
+    # Pad the header with spaces and a final newline such that the magic
+    # string, the header-length short and the header are aligned on a
+    # 16-byte boundary.  Hopefully, some system, possibly memory-mapping,
+    # can take advantage of our premature optimization.
+    current_header_len = MAGIC_LEN + 2 + len(header) + 1  # 1 for the newline
+    topad = 16 - (current_header_len % 16)
+    header = header + ' '*topad + '\n'
+    header = asbytes(_filter_header(header))
+
+    hlen = len(header)
+    if hlen < 256*256 and version in (None, (1, 0)):
+        version = (1, 0)
+        header_prefix = magic(1, 0) + struct.pack('<H', hlen)
+    elif hlen < 2**32 and version in (None, (2, 0)):
+        version = (2, 0)
+        header_prefix = magic(2, 0) + struct.pack('<I', hlen)
+    else:
+        msg = "Header length %s too big for version=%s"
+        msg %= (hlen, version)
+        raise ValueError(msg)
+
+    fp.write(header_prefix)
+    fp.write(header)
+    return version
+
+def write_array_header_1_0(fp, d):
+    """ Write the header for an array using the 1.0 format.
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string
+        representation to the header of the file.
+    """
+    _write_array_header(fp, d, (1, 0))
+
+
+def write_array_header_2_0(fp, d):
+    """ Write the header for an array using the 2.0 format.
+        The 2.0 format allows storing very large structured arrays.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    fp : filelike object
+    d : dict
+        This has the appropriate entries for writing its string
+        representation to the header of the file.
+    """
+    _write_array_header(fp, d, (2, 0))
+
+def read_array_header_1_0(fp):
+    """
+    Read an array header from a filelike object using the 1.0 file format
+    version.
+
+    This will leave the file object located just after the header.
+
+    Parameters
+    ----------
+    fp : filelike object
+        A file object or something with a `.read()` method like a file.
+
+    Returns
+    -------
+    shape : tuple of int
+        The shape of the array.
+    fortran_order : bool
+        The array data will be written out directly if it is either
+        C-contiguous or Fortran-contiguous. Otherwise, it will be made
+        contiguous before writing it out.
+    dtype : dtype
+        The dtype of the file's data.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid.
+
+    """
+    return _read_array_header(fp, version=(1, 0))
+
+def read_array_header_2_0(fp):
+    """
+    Read an array header from a filelike object using the 2.0 file format
+    version.
+
+    This will leave the file object located just after the header.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    fp : filelike object
+        A file object or something with a `.read()` method like a file.
+
+    Returns
+    -------
+    shape : tuple of int
+        The shape of the array.
+    fortran_order : bool
+        The array data will be written out directly if it is either
+        C-contiguous or Fortran-contiguous. Otherwise, it will be made
+        contiguous before writing it out.
+    dtype : dtype
+        The dtype of the file's data.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid.
+
+    """
+    return _read_array_header(fp, version=(2, 0))
+
+
+def _filter_header(s):
+    """Clean up 'L' in npz header ints.
+
+    Cleans up the 'L' in strings representing integers. Needed to allow npz
+    headers produced in Python2 to be read in Python3.
+
+    Parameters
+    ----------
+    s : byte string
+        Npy file header.
+
+    Returns
+    -------
+    header : str
+        Cleaned up header.
+
+    """
+    import tokenize
+    if sys.version_info[0] >= 3:
+        from io import StringIO
+    else:
+        from StringIO import StringIO
+
+    tokens = []
+    last_token_was_number = False
+    for token in tokenize.generate_tokens(StringIO(asstr(s)).read):
+        token_type = token[0]
+        token_string = token[1]
+        if (last_token_was_number and
+                token_type == tokenize.NAME and
+                token_string == "L"):
+            continue
+        else:
+            tokens.append(token)
+        last_token_was_number = (token_type == tokenize.NUMBER)
+    return tokenize.untokenize(tokens)
+
+
+def _read_array_header(fp, version):
+    """
+    see read_array_header_1_0
+    """
+    # Read an unsigned, little-endian short int which has the length of the
+    # header.
+    import struct
+    if version == (1, 0):
+        hlength_str = _read_bytes(fp, 2, "array header length")
+        header_length = struct.unpack('<H', hlength_str)[0]
+        header = _read_bytes(fp, header_length, "array header")
+    elif version == (2, 0):
+        hlength_str = _read_bytes(fp, 4, "array header length")
+        header_length = struct.unpack('<I', hlength_str)[0]
+        header = _read_bytes(fp, header_length, "array header")
+    else:
+        raise ValueError("Invalid version %r" % version)
+
+    # The header is a pretty-printed string representation of a literal
+    # Python dictionary with trailing newlines padded to a 16-byte
+    # boundary. The keys are strings.
+    #   "shape" : tuple of int
+    #   "fortran_order" : bool
+    #   "descr" : dtype.descr
+    header = _filter_header(header)
+    try:
+        d = safe_eval(header)
+    except SyntaxError as e:
+        msg = "Cannot parse header: %r\nException: %r"
+        raise ValueError(msg % (header, e))
+    if not isinstance(d, dict):
+        msg = "Header is not a dictionary: %r"
+        raise ValueError(msg % d)
+    keys = sorted(d.keys())
+    if keys != ['descr', 'fortran_order', 'shape']:
+        msg = "Header does not contain the correct keys: %r"
+        raise ValueError(msg % (keys,))
+
+    # Sanity-check the values.
+    if (not isinstance(d['shape'], tuple) or
+            not numpy.all([isinstance(x, (int, long)) for x in d['shape']])):
+        msg = "shape is not valid: %r"
+        raise ValueError(msg % (d['shape'],))
+    if not isinstance(d['fortran_order'], bool):
+        msg = "fortran_order is not a valid bool: %r"
+        raise ValueError(msg % (d['fortran_order'],))
+    try:
+        dtype = numpy.dtype(d['descr'])
+    except TypeError as e:
+        msg = "descr is not a valid dtype descriptor: %r"
+        raise ValueError(msg % (d['descr'],))
+
+    return d['shape'], d['fortran_order'], dtype
+
+def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None):
+    """
+    Write an array to an NPY file, including a header.
+
+    If the array is neither C-contiguous nor Fortran-contiguous AND the
+    file_like object is not a real file object, this function will have to
+    copy data in memory.
+
+    Parameters
+    ----------
+    fp : file_like object
+        An open, writable file object, or similar object with a
+        ``.write()`` method.
+    array : ndarray
+        The array to write to disk.
+    version : (int, int) or None, optional
+        The version number of the format. None means use the oldest
+        supported version that is able to store the data.  Default: None
+    allow_pickle : bool, optional
+        Whether to allow writing pickled data. Default: True
+    pickle_kwargs : dict, optional
+        Additional keyword arguments to pass to pickle.dump, excluding
+        'protocol'. These are only useful when pickling objects in object
+        arrays on Python 3 to Python 2 compatible format.
+
+    Raises
+    ------
+    ValueError
+        If the array cannot be persisted. This includes the case of
+        allow_pickle=False and array being an object array.
+    Various other errors
+        If the array contains Python objects as part of its dtype, the
+        process of pickling them may raise various errors if the objects
+        are not picklable.
+
+    """
+    _check_version(version)
+    used_ver = _write_array_header(fp, header_data_from_array_1_0(array),
+                                   version)
+    # this warning can be removed when 1.9 has aged enough
+    if version != (2, 0) and used_ver == (2, 0):
+        warnings.warn("Stored array in format 2.0. It can only be"
+                      "read by NumPy >= 1.9", UserWarning)
+
+    # Set buffer size to 16 MiB to hide the Python loop overhead.
+    buffersize = max(16 * 1024 ** 2 // array.itemsize, 1)
+
+    if array.dtype.hasobject:
+        # We contain Python objects so we cannot write out the data
+        # directly.  Instead, we will pickle it out with version 2 of the
+        # pickle protocol.
+        if not allow_pickle:
+            raise ValueError("Object arrays cannot be saved when "
+                             "allow_pickle=False")
+        if pickle_kwargs is None:
+            pickle_kwargs = {}
+        pickle.dump(array, fp, protocol=2, **pickle_kwargs)
+    elif array.flags.f_contiguous and not array.flags.c_contiguous:
+        if isfileobj(fp):
+            array.T.tofile(fp)
+        else:
+            for chunk in numpy.nditer(
+                    array, flags=['external_loop', 'buffered', 'zerosize_ok'],
+                    buffersize=buffersize, order='F'):
+                fp.write(chunk.tobytes('C'))
+    else:
+        if isfileobj(fp):
+            array.tofile(fp)
+        else:
+            for chunk in numpy.nditer(
+                    array, flags=['external_loop', 'buffered', 'zerosize_ok'],
+                    buffersize=buffersize, order='C'):
+                fp.write(chunk.tobytes('C'))
+
+
+def read_array(fp, allow_pickle=True, pickle_kwargs=None):
+    """
+    Read an array from an NPY file.
+
+    Parameters
+    ----------
+    fp : file_like object
+        If this is not a real file object, then this may take extra memory
+        and time.
+    allow_pickle : bool, optional
+        Whether to allow reading pickled data. Default: True
+    pickle_kwargs : dict
+        Additional keyword arguments to pass to pickle.load. These are only
+        useful when loading object arrays saved on Python 2 when using
+        Python 3.
+
+    Returns
+    -------
+    array : ndarray
+        The array from the data on disk.
+
+    Raises
+    ------
+    ValueError
+        If the data is invalid, or allow_pickle=False and the file contains
+        an object array.
+
+    """
+    version = read_magic(fp)
+    _check_version(version)
+    shape, fortran_order, dtype = _read_array_header(fp, version)
+    if len(shape) == 0:
+        count = 1
+    else:
+        count = numpy.multiply.reduce(shape)
+
+    # Now read the actual data.
+    if dtype.hasobject:
+        # The array contained Python objects. We need to unpickle the data.
+        if not allow_pickle:
+            raise ValueError("Object arrays cannot be loaded when "
+                             "allow_pickle=False")
+        if pickle_kwargs is None:
+            pickle_kwargs = {}
+        try:
+            array = pickle.load(fp, **pickle_kwargs)
+        except UnicodeError as err:
+            if sys.version_info[0] >= 3:
+                # Friendlier error message
+                raise UnicodeError("Unpickling a python object failed: %r\n"
+                                   "You may need to pass the encoding= option "
+                                   "to numpy.load" % (err,))
+            raise
+    else:
+        if isfileobj(fp):
+            # We can use the fast fromfile() function.
+            array = numpy.fromfile(fp, dtype=dtype, count=count)
+        else:
+            # This is not a real file. We have to read it the
+            # memory-intensive way.
+            # crc32 module fails on reads greater than 2 ** 32 bytes,
+            # breaking large reads from gzip streams. Chunk reads to
+            # BUFFER_SIZE bytes to avoid issue and reduce memory overhead
+            # of the read. In non-chunked case count < max_read_count, so
+            # only one read is performed.
+
+            max_read_count = BUFFER_SIZE // min(BUFFER_SIZE, dtype.itemsize)
+
+            array = numpy.empty(count, dtype=dtype)
+            for i in range(0, count, max_read_count):
+                read_count = min(max_read_count, count - i)
+                read_size = int(read_count * dtype.itemsize)
+                data = _read_bytes(fp, read_size, "array data")
+                array[i:i+read_count] = numpy.frombuffer(data, dtype=dtype,
+                                                         count=read_count)
+
+        if fortran_order:
+            array.shape = shape[::-1]
+            array = array.transpose()
+        else:
+            array.shape = shape
+
+    return array
+
+
+def open_memmap(filename, mode='r+', dtype=None, shape=None,
+                fortran_order=False, version=None):
+    """
+    Open a .npy file as a memory-mapped array.
+
+    This may be used to read an existing file or create a new one.
+
+    Parameters
+    ----------
+    filename : str
+        The name of the file on disk.  This may *not* be a file-like
+        object.
+    mode : str, optional
+        The mode in which to open the file; the default is 'r+'.  In
+        addition to the standard file modes, 'c' is also accepted to mean
+        "copy on write."  See `memmap` for the available mode strings.
+    dtype : data-type, optional
+        The data type of the array if we are creating a new file in "write"
+        mode, if not, `dtype` is ignored.  The default value is None, which
+        results in a data-type of `float64`.
+    shape : tuple of int
+        The shape of the array if we are creating a new file in "write"
+        mode, in which case this parameter is required.  Otherwise, this
+        parameter is ignored and is thus optional.
+    fortran_order : bool, optional
+        Whether the array should be Fortran-contiguous (True) or
+        C-contiguous (False, the default) if we are creating a new file in
+        "write" mode.
+    version : tuple of int (major, minor) or None
+        If the mode is a "write" mode, then this is the version of the file
+        format used to create the file.  None means use the oldest
+        supported version that is able to store the data.  Default: None
+
+    Returns
+    -------
+    marray : memmap
+        The memory-mapped array.
+
+    Raises
+    ------
+    ValueError
+        If the data or the mode is invalid.
+    IOError
+        If the file is not found or cannot be opened correctly.
+
+    See Also
+    --------
+    memmap
+
+    """
+    if not isinstance(filename, basestring):
+        raise ValueError("Filename must be a string.  Memmap cannot use"
+                         " existing file handles.")
+
+    if 'w' in mode:
+        # We are creating the file, not reading it.
+        # Check if we ought to create the file.
+        _check_version(version)
+        # Ensure that the given dtype is an authentic dtype object rather
+        # than just something that can be interpreted as a dtype object.
+        dtype = numpy.dtype(dtype)
+        if dtype.hasobject:
+            msg = "Array can't be memory-mapped: Python objects in dtype."
+            raise ValueError(msg)
+        d = dict(
+            descr=dtype_to_descr(dtype),
+            fortran_order=fortran_order,
+            shape=shape,
+        )
+        # If we got here, then it should be safe to create the file.
+        fp = open(filename, mode+'b')
+        try:
+            used_ver = _write_array_header(fp, d, version)
+            # this warning can be removed when 1.9 has aged enough
+            if version != (2, 0) and used_ver == (2, 0):
+                warnings.warn("Stored array in format 2.0. It can only be"
+                              "read by NumPy >= 1.9", UserWarning)
+            offset = fp.tell()
+        finally:
+            fp.close()
+    else:
+        # Read the header of the file first.
+        fp = open(filename, 'rb')
+        try:
+            version = read_magic(fp)
+            _check_version(version)
+
+            shape, fortran_order, dtype = _read_array_header(fp, version)
+            if dtype.hasobject:
+                msg = "Array can't be memory-mapped: Python objects in dtype."
+                raise ValueError(msg)
+            offset = fp.tell()
+        finally:
+            fp.close()
+
+    if fortran_order:
+        order = 'F'
+    else:
+        order = 'C'
+
+    # We need to change a write-only mode to a read-write mode since we've
+    # already written data to the file.
+    if mode == 'w+':
+        mode = 'r+'
+
+    marray = numpy.memmap(filename, dtype=dtype, shape=shape, order=order,
+        mode=mode, offset=offset)
+
+    return marray
+
+
+def _read_bytes(fp, size, error_template="ran out of data"):
+    """
+    Read from file-like object until size bytes are read.
+    Raises ValueError if not EOF is encountered before size bytes are read.
+    Non-blocking objects only supported if they derive from io objects.
+
+    Required as e.g. ZipExtFile in python 2.6 can return less data than
+    requested.
+    """
+    data = bytes()
+    while True:
+        # io files (default in python3) return None or raise on
+        # would-block, python2 file will truncate, probably nothing can be
+        # done about that.  note that regular files can't be non-blocking
+        try:
+            r = fp.read(size - len(data))
+            data += r
+            if len(r) == 0 or len(data) == size:
+                break
+        except io.BlockingIOError:
+            pass
+    if len(data) != size:
+        msg = "EOF: reading %s, expected %d bytes got %d"
+        raise ValueError(msg % (error_template, size, len(data)))
+    else:
+        return data
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/function_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/function_base.py
new file mode 100644
index 0000000000..44e0d5ce6b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/function_base.py
@@ -0,0 +1,4576 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+import collections
+import operator
+
+import numpy as np
+import numpy.core.numeric as _nx
+from numpy.core import linspace, atleast_1d, atleast_2d
+from numpy.core.numeric import (
+    ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
+    empty_like, ndarray, around, floor, ceil, take, dot, where, intp,
+    integer, isscalar
+    )
+from numpy.core.umath import (
+    pi, multiply, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin,
+    mod, exp, log10
+    )
+from numpy.core.fromnumeric import (
+    ravel, nonzero, sort, partition, mean, any, sum
+    )
+from numpy.core.numerictypes import typecodes, number
+from numpy.lib.twodim_base import diag
+from .utils import deprecate
+from numpy.core.multiarray import _insert, add_docstring
+from numpy.core.multiarray import digitize, bincount, interp as compiled_interp
+from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
+from numpy.compat import long
+from numpy.compat.py3k import basestring
+
+# Force range to be a generator, for np.delete's usage.
+if sys.version_info[0] < 3:
+    range = xrange
+
+
+__all__ = [
+    'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
+    'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp',
+    'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
+    'histogram', 'histogramdd', 'bincount', 'digitize', 'cov', 'corrcoef',
+    'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
+    'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring',
+    'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc'
+    ]
+
+
+def iterable(y):
+    """
+    Check whether or not an object can be iterated over.
+
+    Parameters
+    ----------
+    y : object
+      Input object.
+
+    Returns
+    -------
+    b : {0, 1}
+      Return 1 if the object has an iterator method or is a sequence,
+      and 0 otherwise.
+
+
+    Examples
+    --------
+    >>> np.iterable([1, 2, 3])
+    1
+    >>> np.iterable(2)
+    0
+
+    """
+    try:
+        iter(y)
+    except:
+        return 0
+    return 1
+
+
+def _hist_bin_sqrt(x):
+    """
+    Square root histogram bin estimator.
+
+    Bin width is inversely proportional to the data size. Used by many
+    programs for its simplicity.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / np.sqrt(x.size)
+
+
+def _hist_bin_sturges(x):
+    """
+    Sturges histogram bin estimator.
+
+    A very simplistic estimator based on the assumption of normality of
+    the data. This estimator has poor performance for non-normal data,
+    which becomes especially obvious for large data sets. The estimate
+    depends only on size of the data.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / (np.log2(x.size) + 1.0)
+
+
+def _hist_bin_rice(x):
+    """
+    Rice histogram bin estimator.
+
+    Another simple estimator with no normality assumption. It has better
+    performance for large data than Sturges, but tends to overestimate
+    the number of bins. The number of bins is proportional to the cube
+    root of data size (asymptotically optimal). The estimate depends
+    only on size of the data.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return x.ptp() / (2.0 * x.size ** (1.0 / 3))
+
+
+def _hist_bin_scott(x):
+    """
+    Scott histogram bin estimator.
+
+    The binwidth is proportional to the standard deviation of the data
+    and inversely proportional to the cube root of data size
+    (asymptotically optimal).
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    return (24.0 * np.pi**0.5 / x.size)**(1.0 / 3.0) * np.std(x)
+
+
+def _hist_bin_doane(x):
+    """
+    Doane's histogram bin estimator.
+
+    Improved version of Sturges' formula which works better for
+    non-normal data. See
+    http://stats.stackexchange.com/questions/55134/doanes-formula-for-histogram-binning
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    if x.size > 2:
+        sg1 = np.sqrt(6.0 * (x.size - 2) / ((x.size + 1.0) * (x.size + 3)))
+        sigma = np.std(x)
+        if sigma > 0.0:
+            # These three operations add up to
+            # g1 = np.mean(((x - np.mean(x)) / sigma)**3)
+            # but use only one temp array instead of three
+            temp = x - np.mean(x)
+            np.true_divide(temp, sigma, temp)
+            np.power(temp, 3, temp)
+            g1 = np.mean(temp)
+            return x.ptp() / (1.0 + np.log2(x.size) +
+                                    np.log2(1.0 + np.absolute(g1) / sg1))
+    return 0.0
+
+
+def _hist_bin_fd(x):
+    """
+    The Freedman-Diaconis histogram bin estimator.
+
+    The Freedman-Diaconis rule uses interquartile range (IQR) to
+    estimate binwidth. It is considered a variation of the Scott rule
+    with more robustness as the IQR is less affected by outliers than
+    the standard deviation. However, the IQR depends on fewer points
+    than the standard deviation, so it is less accurate, especially for
+    long tailed distributions.
+
+    If the IQR is 0, this function returns 1 for the number of bins.
+    Binwidth is inversely proportional to the cube root of data size
+    (asymptotically optimal).
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+    """
+    iqr = np.subtract(*np.percentile(x, [75, 25]))
+    return 2.0 * iqr * x.size ** (-1.0 / 3.0)
+
+
+def _hist_bin_auto(x):
+    """
+    Histogram bin estimator that uses the minimum width of the
+    Freedman-Diaconis and Sturges estimators.
+
+    The FD estimator is usually the most robust method, but its width
+    estimate tends to be too large for small `x`. The Sturges estimator
+    is quite good for small (<1000) datasets and is the default in the R
+    language. This method gives good off the shelf behaviour.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data that is to be histogrammed, trimmed to range. May not
+        be empty.
+
+    Returns
+    -------
+    h : An estimate of the optimal bin width for the given data.
+
+    See Also
+    --------
+    _hist_bin_fd, _hist_bin_sturges
+    """
+    # There is no need to check for zero here. If ptp is, so is IQR and
+    # vice versa. Either both are zero or neither one is.
+    return min(_hist_bin_fd(x), _hist_bin_sturges(x))
+
+
+# Private dict initialized at module load time
+_hist_bin_selectors = {'auto': _hist_bin_auto,
+                       'doane': _hist_bin_doane,
+                       'fd': _hist_bin_fd,
+                       'rice': _hist_bin_rice,
+                       'scott': _hist_bin_scott,
+                       'sqrt': _hist_bin_sqrt,
+                       'sturges': _hist_bin_sturges}
+
+
+def histogram(a, bins=10, range=None, normed=False, weights=None,
+              density=None):
+    r"""
+    Compute the histogram of a set of data.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data. The histogram is computed over the flattened array.
+    bins : int or sequence of scalars or str, optional
+        If `bins` is an int, it defines the number of equal-width
+        bins in the given range (10, by default). If `bins` is a
+        sequence, it defines the bin edges, including the rightmost
+        edge, allowing for non-uniform bin widths.
+
+        .. versionadded:: 1.11.0
+
+        If `bins` is a string from the list below, `histogram` will use
+        the method chosen to calculate the optimal bin width and
+        consequently the number of bins (see `Notes` for more detail on
+        the estimators) from the data that falls within the requested
+        range. While the bin width will be optimal for the actual data
+        in the range, the number of bins will be computed to fill the
+        entire range, including the empty portions. For visualisation,
+        using the 'auto' option is suggested. Weighted data is not
+        supported for automated bin size selection.
+
+        'auto'
+            Maximum of the 'sturges' and 'fd' estimators. Provides good
+            all round performance
+
+        'fd' (Freedman Diaconis Estimator)
+            Robust (resilient to outliers) estimator that takes into
+            account data variability and data size .
+
+        'doane'
+            An improved version of Sturges' estimator that works better
+            with non-normal datasets.
+
+        'scott'
+            Less robust estimator that that takes into account data
+            variability and data size.
+
+        'rice'
+            Estimator does not take variability into account, only data
+            size. Commonly overestimates number of bins required.
+
+        'sturges'
+            R's default method, only accounts for data size. Only
+            optimal for gaussian data and underestimates number of bins
+            for large non-gaussian datasets.
+
+        'sqrt'
+            Square root (of data size) estimator, used by Excel and
+            other programs for its speed and simplicity.
+
+    range : (float, float), optional
+        The lower and upper range of the bins.  If not provided, range
+        is simply ``(a.min(), a.max())``.  Values outside the range are
+        ignored. The first element of the range must be less than or
+        equal to the second. `range` affects the automatic bin
+        computation as well. While bin width is computed to be optimal
+        based on the actual data within `range`, the bin count will fill
+        the entire range including portions containing no data.
+    normed : bool, optional
+        This keyword is deprecated in Numpy 1.6 due to confusing/buggy
+        behavior. It will be removed in Numpy 2.0. Use the ``density``
+        keyword instead. If ``False``, the result will contain the
+        number of samples in each bin. If ``True``, the result is the
+        value of the probability *density* function at the bin,
+        normalized such that the *integral* over the range is 1. Note
+        that this latter behavior is known to be buggy with unequal bin
+        widths; use ``density`` instead.
+    weights : array_like, optional
+        An array of weights, of the same shape as `a`.  Each value in
+        `a` only contributes its associated weight towards the bin count
+        (instead of 1). If `density` is True, the weights are
+        normalized, so that the integral of the density over the range
+        remains 1.
+    density : bool, optional
+        If ``False``, the result will contain the number of samples in
+        each bin. If ``True``, the result is the value of the
+        probability *density* function at the bin, normalized such that
+        the *integral* over the range is 1. Note that the sum of the
+        histogram values will not be equal to 1 unless bins of unity
+        width are chosen; it is not a probability *mass* function.
+
+        Overrides the ``normed`` keyword if given.
+
+    Returns
+    -------
+    hist : array
+        The values of the histogram. See `density` and `weights` for a
+        description of the possible semantics.
+    bin_edges : array of dtype float
+        Return the bin edges ``(length(hist)+1)``.
+
+
+    See Also
+    --------
+    histogramdd, bincount, searchsorted, digitize
+
+    Notes
+    -----
+    All but the last (righthand-most) bin is half-open.  In other words,
+    if `bins` is::
+
+      [1, 2, 3, 4]
+
+    then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
+    the second ``[2, 3)``.  The last bin, however, is ``[3, 4]``, which
+    *includes* 4.
+
+    .. versionadded:: 1.11.0
+
+    The methods to estimate the optimal number of bins are well founded
+    in literature, and are inspired by the choices R provides for
+    histogram visualisation. Note that having the number of bins
+    proportional to :math:`n^{1/3}` is asymptotically optimal, which is
+    why it appears in most estimators. These are simply plug-in methods
+    that give good starting points for number of bins. In the equations
+    below, :math:`h` is the binwidth and :math:`n_h` is the number of
+    bins. All estimators that compute bin counts are recast to bin width
+    using the `ptp` of the data. The final bin count is obtained from
+    ``np.round(np.ceil(range / h))`.
+
+    'Auto' (maximum of the 'Sturges' and 'FD' estimators)
+        A compromise to get a good value. For small datasets the Sturges
+        value will usually be chosen, while larger datasets will usually
+        default to FD.  Avoids the overly conservative behaviour of FD
+        and Sturges for small and large datasets respectively.
+        Switchover point is usually :math:`a.size \approx 1000`.
+
+    'FD' (Freedman Diaconis Estimator)
+        .. math:: h = 2 \frac{IQR}{n^{1/3}}
+
+        The binwidth is proportional to the interquartile range (IQR)
+        and inversely proportional to cube root of a.size. Can be too
+        conservative for small datasets, but is quite good for large
+        datasets. The IQR is very robust to outliers.
+
+    'Scott'
+        .. math:: h = \sigma \sqrt[3]{\frac{24 * \sqrt{\pi}}{n}}
+
+        The binwidth is proportional to the standard deviation of the
+        data and inversely proportional to cube root of ``x.size``. Can
+        be too conservative for small datasets, but is quite good for
+        large datasets. The standard deviation is not very robust to
+        outliers. Values are very similar to the Freedman-Diaconis
+        estimator in the absence of outliers.
+
+    'Rice'
+        .. math:: n_h = 2n^{1/3}
+
+        The number of bins is only proportional to cube root of
+        ``a.size``. It tends to overestimate the number of bins and it
+        does not take into account data variability.
+
+    'Sturges'
+        .. math:: n_h = \log _{2}n+1
+
+        The number of bins is the base 2 log of ``a.size``.  This
+        estimator assumes normality of data and is too conservative for
+        larger, non-normal datasets. This is the default method in R's
+        ``hist`` method.
+
+    'Doane'
+        .. math:: n_h = 1 + \log_{2}(n) +
+                        \log_{2}(1 + \frac{|g_1|}{\sigma_{g_1})}
+
+            g_1 = mean[(\frac{x - \mu}{\sigma})^3]
+
+            \sigma_{g_1} = \sqrt{\frac{6(n - 2)}{(n + 1)(n + 3)}}
+
+        An improved version of Sturges' formula that produces better
+        estimates for non-normal datasets. This estimator attempts to
+        account for the skew of the data.
+
+    'Sqrt'
+        .. math:: n_h = \sqrt n
+        The simplest and fastest estimator. Only takes into account the
+        data size.
+
+    Examples
+    --------
+    >>> np.histogram([1, 2, 1], bins=[0, 1, 2, 3])
+    (array([0, 2, 1]), array([0, 1, 2, 3]))
+    >>> np.histogram(np.arange(4), bins=np.arange(5), density=True)
+    (array([ 0.25,  0.25,  0.25,  0.25]), array([0, 1, 2, 3, 4]))
+    >>> np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3])
+    (array([1, 4, 1]), array([0, 1, 2, 3]))
+
+    >>> a = np.arange(5)
+    >>> hist, bin_edges = np.histogram(a, density=True)
+    >>> hist
+    array([ 0.5,  0. ,  0.5,  0. ,  0. ,  0.5,  0. ,  0.5,  0. ,  0.5])
+    >>> hist.sum()
+    2.4999999999999996
+    >>> np.sum(hist*np.diff(bin_edges))
+    1.0
+
+    .. versionadded:: 1.11.0
+
+    Automated Bin Selection Methods example, using 2 peak random data
+    with 2000 points:
+
+    >>> import matplotlib.pyplot as plt
+    >>> rng = np.random.RandomState(10)  # deterministic random data
+    >>> a = np.hstack((rng.normal(size=1000),
+    ...                rng.normal(loc=5, scale=2, size=1000)))
+    >>> plt.hist(a, bins='auto')  # plt.hist passes it's arguments to np.histogram
+    >>> plt.title("Histogram with 'auto' bins")
+    >>> plt.show()
+
+    """
+    a = asarray(a)
+    if weights is not None:
+        weights = asarray(weights)
+        if np.any(weights.shape != a.shape):
+            raise ValueError(
+                'weights should have the same shape as a.')
+        weights = weights.ravel()
+    a = a.ravel()
+
+    # Do not modify the original value of range so we can check for `None`
+    if range is None:
+        if a.size == 0:
+            # handle empty arrays. Can't determine range, so use 0-1.
+            mn, mx = 0.0, 1.0
+        else:
+            mn, mx = a.min() + 0.0, a.max() + 0.0
+    else:
+        mn, mx = [mi + 0.0 for mi in range]
+    if mn > mx:
+        raise ValueError(
+            'max must be larger than min in range parameter.')
+    if not np.all(np.isfinite([mn, mx])):
+        raise ValueError(
+            'range parameter must be finite.')
+    if mn == mx:
+        mn -= 0.5
+        mx += 0.5
+
+    if isinstance(bins, basestring):
+        # if `bins` is a string for an automatic method,
+        # this will replace it with the number of bins calculated
+        if bins not in _hist_bin_selectors:
+            raise ValueError("{0} not a valid estimator for bins".format(bins))
+        if weights is not None:
+            raise TypeError("Automated estimation of the number of "
+                            "bins is not supported for weighted data")
+        # Make a reference to `a`
+        b = a
+        # Update the reference if the range needs truncation
+        if range is not None:
+            keep = (a >= mn)
+            keep &= (a <= mx)
+            if not np.logical_and.reduce(keep):
+                b = a[keep]
+
+        if b.size == 0:
+            bins = 1
+        else:
+            # Do not call selectors on empty arrays
+            width = _hist_bin_selectors[bins](b)
+            if width:
+                bins = int(np.ceil((mx - mn) / width))
+            else:
+                # Width can be zero for some estimators, e.g. FD when
+                # the IQR of the data is zero.
+                bins = 1
+
+    # Histogram is an integer or a float array depending on the weights.
+    if weights is None:
+        ntype = np.dtype(np.intp)
+    else:
+        ntype = weights.dtype
+
+    # We set a block size, as this allows us to iterate over chunks when
+    # computing histograms, to minimize memory usage.
+    BLOCK = 65536
+
+    if not iterable(bins):
+        if np.isscalar(bins) and bins < 1:
+            raise ValueError(
+                '`bins` should be a positive integer.')
+        # At this point, if the weights are not integer, floating point, or
+        # complex, we have to use the slow algorithm.
+        if weights is not None and not (np.can_cast(weights.dtype, np.double) or
+                                        np.can_cast(weights.dtype, np.complex)):
+            bins = linspace(mn, mx, bins + 1, endpoint=True)
+
+    if not iterable(bins):
+        # We now convert values of a to bin indices, under the assumption of
+        # equal bin widths (which is valid here).
+
+        # Initialize empty histogram
+        n = np.zeros(bins, ntype)
+        # Pre-compute histogram scaling factor
+        norm = bins / (mx - mn)
+
+        # We iterate over blocks here for two reasons: the first is that for
+        # large arrays, it is actually faster (for example for a 10^8 array it
+        # is 2x as fast) and it results in a memory footprint 3x lower in the
+        # limit of large arrays.
+        for i in arange(0, len(a), BLOCK):
+            tmp_a = a[i:i+BLOCK]
+            if weights is None:
+                tmp_w = None
+            else:
+                tmp_w = weights[i:i + BLOCK]
+
+            # Only include values in the right range
+            keep = (tmp_a >= mn)
+            keep &= (tmp_a <= mx)
+            if not np.logical_and.reduce(keep):
+                tmp_a = tmp_a[keep]
+                if tmp_w is not None:
+                    tmp_w = tmp_w[keep]
+            tmp_a = tmp_a.astype(float)
+            tmp_a -= mn
+            tmp_a *= norm
+
+            # Compute the bin indices, and for values that lie exactly on mx we
+            # need to subtract one
+            indices = tmp_a.astype(np.intp)
+            indices[indices == bins] -= 1
+
+            # We now compute the histogram using bincount
+            if ntype.kind == 'c':
+                n.real += np.bincount(indices, weights=tmp_w.real, minlength=bins)
+                n.imag += np.bincount(indices, weights=tmp_w.imag, minlength=bins)
+            else:
+                n += np.bincount(indices, weights=tmp_w, minlength=bins).astype(ntype)
+
+        # We now compute the bin edges since these are returned
+        bins = linspace(mn, mx, bins + 1, endpoint=True)
+    else:
+        bins = asarray(bins)
+        if (np.diff(bins) < 0).any():
+            raise ValueError(
+                'bins must increase monotonically.')
+
+        # Initialize empty histogram
+        n = np.zeros(bins.shape, ntype)
+
+        if weights is None:
+            for i in arange(0, len(a), BLOCK):
+                sa = sort(a[i:i+BLOCK])
+                n += np.r_[sa.searchsorted(bins[:-1], 'left'),
+                           sa.searchsorted(bins[-1], 'right')]
+        else:
+            zero = array(0, dtype=ntype)
+            for i in arange(0, len(a), BLOCK):
+                tmp_a = a[i:i+BLOCK]
+                tmp_w = weights[i:i+BLOCK]
+                sorting_index = np.argsort(tmp_a)
+                sa = tmp_a[sorting_index]
+                sw = tmp_w[sorting_index]
+                cw = np.concatenate(([zero, ], sw.cumsum()))
+                bin_index = np.r_[sa.searchsorted(bins[:-1], 'left'),
+                                  sa.searchsorted(bins[-1], 'right')]
+                n += cw[bin_index]
+
+
+        n = np.diff(n)
+
+    if density is not None:
+        if density:
+            db = array(np.diff(bins), float)
+            return n/db/n.sum(), bins
+        else:
+            return n, bins
+    else:
+        # deprecated, buggy behavior. Remove for Numpy 2.0
+        if normed:
+            db = array(np.diff(bins), float)
+            return n/(n*db).sum(), bins
+        else:
+            return n, bins
+
+
+def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
+    """
+    Compute the multidimensional histogram of some data.
+
+    Parameters
+    ----------
+    sample : array_like
+        The data to be histogrammed. It must be an (N,D) array or data
+        that can be converted to such. The rows of the resulting array
+        are the coordinates of points in a D dimensional polytope.
+    bins : sequence or int, optional
+        The bin specification:
+
+        * A sequence of arrays describing the bin edges along each dimension.
+        * The number of bins for each dimension (nx, ny, ... =bins)
+        * The number of bins for all dimensions (nx=ny=...=bins).
+
+    range : sequence, optional
+        A sequence of lower and upper bin edges to be used if the edges are
+        not given explicitly in `bins`. Defaults to the minimum and maximum
+        values along each dimension.
+    normed : bool, optional
+        If False, returns the number of samples in each bin. If True,
+        returns the bin density ``bin_count / sample_count / bin_volume``.
+    weights : (N,) array_like, optional
+        An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
+        Weights are normalized to 1 if normed is True. If normed is False,
+        the values of the returned histogram are equal to the sum of the
+        weights belonging to the samples falling into each bin.
+
+    Returns
+    -------
+    H : ndarray
+        The multidimensional histogram of sample x. See normed and weights
+        for the different possible semantics.
+    edges : list
+        A list of D arrays describing the bin edges for each dimension.
+
+    See Also
+    --------
+    histogram: 1-D histogram
+    histogram2d: 2-D histogram
+
+    Examples
+    --------
+    >>> r = np.random.randn(100,3)
+    >>> H, edges = np.histogramdd(r, bins = (5, 8, 4))
+    >>> H.shape, edges[0].size, edges[1].size, edges[2].size
+    ((5, 8, 4), 6, 9, 5)
+
+    """
+
+    try:
+        # Sample is an ND-array.
+        N, D = sample.shape
+    except (AttributeError, ValueError):
+        # Sample is a sequence of 1D arrays.
+        sample = atleast_2d(sample).T
+        N, D = sample.shape
+
+    nbin = empty(D, int)
+    edges = D*[None]
+    dedges = D*[None]
+    if weights is not None:
+        weights = asarray(weights)
+
+    try:
+        M = len(bins)
+        if M != D:
+            raise ValueError(
+                'The dimension of bins must be equal to the dimension of the '
+                ' sample x.')
+    except TypeError:
+        # bins is an integer
+        bins = D*[bins]
+
+    # Select range for each dimension
+    # Used only if number of bins is given.
+    if range is None:
+        # Handle empty input. Range can't be determined in that case, use 0-1.
+        if N == 0:
+            smin = zeros(D)
+            smax = ones(D)
+        else:
+            smin = atleast_1d(array(sample.min(0), float))
+            smax = atleast_1d(array(sample.max(0), float))
+    else:
+        if not np.all(np.isfinite(range)):
+            raise ValueError(
+                'range parameter must be finite.')
+        smin = zeros(D)
+        smax = zeros(D)
+        for i in arange(D):
+            smin[i], smax[i] = range[i]
+
+    # Make sure the bins have a finite width.
+    for i in arange(len(smin)):
+        if smin[i] == smax[i]:
+            smin[i] = smin[i] - .5
+            smax[i] = smax[i] + .5
+
+    # avoid rounding issues for comparisons when dealing with inexact types
+    if np.issubdtype(sample.dtype, np.inexact):
+        edge_dt = sample.dtype
+    else:
+        edge_dt = float
+    # Create edge arrays
+    for i in arange(D):
+        if isscalar(bins[i]):
+            if bins[i] < 1:
+                raise ValueError(
+                    "Element at index %s in `bins` should be a positive "
+                    "integer." % i)
+            nbin[i] = bins[i] + 2  # +2 for outlier bins
+            edges[i] = linspace(smin[i], smax[i], nbin[i]-1, dtype=edge_dt)
+        else:
+            edges[i] = asarray(bins[i], edge_dt)
+            nbin[i] = len(edges[i]) + 1  # +1 for outlier bins
+        dedges[i] = diff(edges[i])
+        if np.any(np.asarray(dedges[i]) <= 0):
+            raise ValueError(
+                "Found bin edge of size <= 0. Did you specify `bins` with"
+                "non-monotonic sequence?")
+
+    nbin = asarray(nbin)
+
+    # Handle empty input.
+    if N == 0:
+        return np.zeros(nbin-2), edges
+
+    # Compute the bin number each sample falls into.
+    Ncount = {}
+    for i in arange(D):
+        Ncount[i] = digitize(sample[:, i], edges[i])
+
+    # Using digitize, values that fall on an edge are put in the right bin.
+    # For the rightmost bin, we want values equal to the right edge to be
+    # counted in the last bin, and not as an outlier.
+    for i in arange(D):
+        # Rounding precision
+        mindiff = dedges[i].min()
+        if not np.isinf(mindiff):
+            decimal = int(-log10(mindiff)) + 6
+            # Find which points are on the rightmost edge.
+            not_smaller_than_edge = (sample[:, i] >= edges[i][-1])
+            on_edge = (around(sample[:, i], decimal) ==
+                       around(edges[i][-1], decimal))
+            # Shift these points one bin to the left.
+            Ncount[i][where(on_edge & not_smaller_than_edge)[0]] -= 1
+
+    # Flattened histogram matrix (1D)
+    # Reshape is used so that overlarge arrays
+    # will raise an error.
+    hist = zeros(nbin, float).reshape(-1)
+
+    # Compute the sample indices in the flattened histogram matrix.
+    ni = nbin.argsort()
+    xy = zeros(N, int)
+    for i in arange(0, D-1):
+        xy += Ncount[ni[i]] * nbin[ni[i+1:]].prod()
+    xy += Ncount[ni[-1]]
+
+    # Compute the number of repetitions in xy and assign it to the
+    # flattened histmat.
+    if len(xy) == 0:
+        return zeros(nbin-2, int), edges
+
+    flatcount = bincount(xy, weights)
+    a = arange(len(flatcount))
+    hist[a] = flatcount
+
+    # Shape into a proper matrix
+    hist = hist.reshape(sort(nbin))
+    for i in arange(nbin.size):
+        j = ni.argsort()[i]
+        hist = hist.swapaxes(i, j)
+        ni[i], ni[j] = ni[j], ni[i]
+
+    # Remove outliers (indices 0 and -1 for each dimension).
+    core = D*[slice(1, -1)]
+    hist = hist[core]
+
+    # Normalize if normed is True
+    if normed:
+        s = hist.sum()
+        for i in arange(D):
+            shape = ones(D, int)
+            shape[i] = nbin[i] - 2
+            hist = hist / dedges[i].reshape(shape)
+        hist /= s
+
+    if (hist.shape != nbin - 2).any():
+        raise RuntimeError(
+            "Internal Shape Error")
+    return hist, edges
+
+
+def average(a, axis=None, weights=None, returned=False):
+    """
+    Compute the weighted average along the specified axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing data to be averaged. If `a` is not an array, a
+        conversion is attempted.
+    axis : int, optional
+        Axis along which to average `a`. If `None`, averaging is done over
+        the flattened array.
+    weights : array_like, optional
+        An array of weights associated with the values in `a`. Each value in
+        `a` contributes to the average according to its associated weight.
+        The weights array can either be 1-D (in which case its length must be
+        the size of `a` along the given axis) or of the same shape as `a`.
+        If `weights=None`, then all data in `a` are assumed to have a
+        weight equal to one.
+    returned : bool, optional
+        Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
+        is returned, otherwise only the average is returned.
+        If `weights=None`, `sum_of_weights` is equivalent to the number of
+        elements over which the average is taken.
+
+
+    Returns
+    -------
+    average, [sum_of_weights] : array_type or double
+        Return the average along the specified axis. When returned is `True`,
+        return a tuple with the average as the first element and the sum
+        of the weights as the second element. The return type is `Float`
+        if `a` is of integer type, otherwise it is of the same type as `a`.
+        `sum_of_weights` is of the same type as `average`.
+
+    Raises
+    ------
+    ZeroDivisionError
+        When all weights along axis are zero. See `numpy.ma.average` for a
+        version robust to this type of error.
+    TypeError
+        When the length of 1D `weights` is not the same as the shape of `a`
+        along axis.
+
+    See Also
+    --------
+    mean
+
+    ma.average : average for masked arrays -- useful if your data contains
+                 "missing" values
+
+    Examples
+    --------
+    >>> data = range(1,5)
+    >>> data
+    [1, 2, 3, 4]
+    >>> np.average(data)
+    2.5
+    >>> np.average(range(1,11), weights=range(10,0,-1))
+    4.0
+
+    >>> data = np.arange(6).reshape((3,2))
+    >>> data
+    array([[0, 1],
+           [2, 3],
+           [4, 5]])
+    >>> np.average(data, axis=1, weights=[1./4, 3./4])
+    array([ 0.75,  2.75,  4.75])
+    >>> np.average(data, weights=[1./4, 3./4])
+    Traceback (most recent call last):
+    ...
+    TypeError: Axis must be specified when shapes of a and weights differ.
+
+    """
+    if not isinstance(a, np.matrix):
+        a = np.asarray(a)
+
+    if weights is None:
+        avg = a.mean(axis)
+        scl = avg.dtype.type(a.size/avg.size)
+    else:
+        a = a + 0.0
+        wgt = np.asarray(weights)
+        # Sanity checks
+        if a.shape != wgt.shape:
+            if axis is None:
+                raise TypeError(
+                    "Axis must be specified when shapes of a and weights "
+                    "differ.")
+            if wgt.ndim != 1:
+                raise TypeError(
+                    "1D weights expected when shapes of a and weights differ.")
+            if wgt.shape[0] != a.shape[axis]:
+                raise ValueError(
+                    "Length of weights not compatible with specified axis.")
+
+            # setup wgt to broadcast along axis
+            wgt = np.array(wgt, copy=0, ndmin=a.ndim).swapaxes(-1, axis)
+
+        scl = wgt.sum(axis=axis, dtype=np.result_type(a.dtype, wgt.dtype))
+        if (scl == 0.0).any():
+            raise ZeroDivisionError(
+                "Weights sum to zero, can't be normalized")
+
+        avg = np.multiply(a, wgt).sum(axis)/scl
+
+    if returned:
+        scl = np.multiply(avg, 0) + scl
+        return avg, scl
+    else:
+        return avg
+
+
+def asarray_chkfinite(a, dtype=None, order=None):
+    """Convert the input to an array, checking for NaNs or Infs.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists and ndarrays.  Success requires no NaNs or Infs.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+         Whether to use row-major (C-style) or
+         column-major (Fortran-style) memory representation.
+         Defaults to 'C'.
+
+    Returns
+    -------
+    out : ndarray
+        Array interpretation of `a`.  No copy is performed if the input
+        is already an ndarray.  If `a` is a subclass of ndarray, a base
+        class ndarray is returned.
+
+    Raises
+    ------
+    ValueError
+        Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).
+
+    See Also
+    --------
+    asarray : Create and array.
+    asanyarray : Similar function which passes through subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array.  If all elements are finite
+    ``asarray_chkfinite`` is identical to ``asarray``.
+
+    >>> a = [1, 2]
+    >>> np.asarray_chkfinite(a, dtype=float)
+    array([1., 2.])
+
+    Raises ValueError if array_like contains Nans or Infs.
+
+    >>> a = [1, 2, np.inf]
+    >>> try:
+    ...     np.asarray_chkfinite(a)
+    ... except ValueError:
+    ...     print('ValueError')
+    ...
+    ValueError
+
+    """
+    a = asarray(a, dtype=dtype, order=order)
+    if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
+        raise ValueError(
+            "array must not contain infs or NaNs")
+    return a
+
+
+def piecewise(x, condlist, funclist, *args, **kw):
+    """
+    Evaluate a piecewise-defined function.
+
+    Given a set of conditions and corresponding functions, evaluate each
+    function on the input data wherever its condition is true.
+
+    Parameters
+    ----------
+    x : ndarray
+        The input domain.
+    condlist : list of bool arrays
+        Each boolean array corresponds to a function in `funclist`.  Wherever
+        `condlist[i]` is True, `funclist[i](x)` is used as the output value.
+
+        Each boolean array in `condlist` selects a piece of `x`,
+        and should therefore be of the same shape as `x`.
+
+        The length of `condlist` must correspond to that of `funclist`.
+        If one extra function is given, i.e. if
+        ``len(funclist) - len(condlist) == 1``, then that extra function
+        is the default value, used wherever all conditions are false.
+    funclist : list of callables, f(x,*args,**kw), or scalars
+        Each function is evaluated over `x` wherever its corresponding
+        condition is True.  It should take an array as input and give an array
+        or a scalar value as output.  If, instead of a callable,
+        a scalar is provided then a constant function (``lambda x: scalar``) is
+        assumed.
+    args : tuple, optional
+        Any further arguments given to `piecewise` are passed to the functions
+        upon execution, i.e., if called ``piecewise(..., ..., 1, 'a')``, then
+        each function is called as ``f(x, 1, 'a')``.
+    kw : dict, optional
+        Keyword arguments used in calling `piecewise` are passed to the
+        functions upon execution, i.e., if called
+        ``piecewise(..., ..., lambda=1)``, then each function is called as
+        ``f(x, lambda=1)``.
+
+    Returns
+    -------
+    out : ndarray
+        The output is the same shape and type as x and is found by
+        calling the functions in `funclist` on the appropriate portions of `x`,
+        as defined by the boolean arrays in `condlist`.  Portions not covered
+        by any condition have a default value of 0.
+
+
+    See Also
+    --------
+    choose, select, where
+
+    Notes
+    -----
+    This is similar to choose or select, except that functions are
+    evaluated on elements of `x` that satisfy the corresponding condition from
+    `condlist`.
+
+    The result is::
+
+            |--
+            |funclist[0](x[condlist[0]])
+      out = |funclist[1](x[condlist[1]])
+            |...
+            |funclist[n2](x[condlist[n2]])
+            |--
+
+    Examples
+    --------
+    Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``.
+
+    >>> x = np.linspace(-2.5, 2.5, 6)
+    >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1])
+    array([-1., -1., -1.,  1.,  1.,  1.])
+
+    Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for
+    ``x >= 0``.
+
+    >>> np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x])
+    array([ 2.5,  1.5,  0.5,  0.5,  1.5,  2.5])
+
+    """
+    x = asanyarray(x)
+    n2 = len(funclist)
+    if (isscalar(condlist) or not (isinstance(condlist[0], list) or
+                                   isinstance(condlist[0], ndarray))):
+        condlist = [condlist]
+    condlist = array(condlist, dtype=bool)
+    n = len(condlist)
+    # This is a hack to work around problems with NumPy's
+    #  handling of 0-d arrays and boolean indexing with
+    #  numpy.bool_ scalars
+    zerod = False
+    if x.ndim == 0:
+        x = x[None]
+        zerod = True
+        if condlist.shape[-1] != 1:
+            condlist = condlist.T
+    if n == n2 - 1:  # compute the "otherwise" condition.
+        totlist = np.logical_or.reduce(condlist, axis=0)
+        # Only able to stack vertically if the array is 1d or less
+        if x.ndim <= 1:
+            condlist = np.vstack([condlist, ~totlist])
+        else:
+            condlist = [asarray(c, dtype=bool) for c in condlist]
+            totlist = condlist[0]
+            for k in range(1, n):
+                totlist |= condlist[k]
+            condlist.append(~totlist)
+        n += 1
+
+    y = zeros(x.shape, x.dtype)
+    for k in range(n):
+        item = funclist[k]
+        if not isinstance(item, collections.Callable):
+            y[condlist[k]] = item
+        else:
+            vals = x[condlist[k]]
+            if vals.size > 0:
+                y[condlist[k]] = item(vals, *args, **kw)
+    if zerod:
+        y = y.squeeze()
+    return y
+
+
+def select(condlist, choicelist, default=0):
+    """
+    Return an array drawn from elements in choicelist, depending on conditions.
+
+    Parameters
+    ----------
+    condlist : list of bool ndarrays
+        The list of conditions which determine from which array in `choicelist`
+        the output elements are taken. When multiple conditions are satisfied,
+        the first one encountered in `condlist` is used.
+    choicelist : list of ndarrays
+        The list of arrays from which the output elements are taken. It has
+        to be of the same length as `condlist`.
+    default : scalar, optional
+        The element inserted in `output` when all conditions evaluate to False.
+
+    Returns
+    -------
+    output : ndarray
+        The output at position m is the m-th element of the array in
+        `choicelist` where the m-th element of the corresponding array in
+        `condlist` is True.
+
+    See Also
+    --------
+    where : Return elements from one of two arrays depending on condition.
+    take, choose, compress, diag, diagonal
+
+    Examples
+    --------
+    >>> x = np.arange(10)
+    >>> condlist = [x<3, x>5]
+    >>> choicelist = [x, x**2]
+    >>> np.select(condlist, choicelist)
+    array([ 0,  1,  2,  0,  0,  0, 36, 49, 64, 81])
+
+    """
+    # Check the size of condlist and choicelist are the same, or abort.
+    if len(condlist) != len(choicelist):
+        raise ValueError(
+            'list of cases must be same length as list of conditions')
+
+    # Now that the dtype is known, handle the deprecated select([], []) case
+    if len(condlist) == 0:
+        # 2014-02-24, 1.9
+        warnings.warn("select with an empty condition list is not possible"
+                      "and will be deprecated",
+                      DeprecationWarning)
+        return np.asarray(default)[()]
+
+    choicelist = [np.asarray(choice) for choice in choicelist]
+    choicelist.append(np.asarray(default))
+
+    # need to get the result type before broadcasting for correct scalar
+    # behaviour
+    dtype = np.result_type(*choicelist)
+
+    # Convert conditions to arrays and broadcast conditions and choices
+    # as the shape is needed for the result. Doing it separately optimizes
+    # for example when all choices are scalars.
+    condlist = np.broadcast_arrays(*condlist)
+    choicelist = np.broadcast_arrays(*choicelist)
+
+    # If cond array is not an ndarray in boolean format or scalar bool, abort.
+    deprecated_ints = False
+    for i in range(len(condlist)):
+        cond = condlist[i]
+        if cond.dtype.type is not np.bool_:
+            if np.issubdtype(cond.dtype, np.integer):
+                # A previous implementation accepted int ndarrays accidentally.
+                # Supported here deliberately, but deprecated.
+                condlist[i] = condlist[i].astype(bool)
+                deprecated_ints = True
+            else:
+                raise ValueError(
+                    'invalid entry in choicelist: should be boolean ndarray')
+
+    if deprecated_ints:
+        # 2014-02-24, 1.9
+        msg = "select condlists containing integer ndarrays is deprecated " \
+            "and will be removed in the future. Use `.astype(bool)` to " \
+            "convert to bools."
+        warnings.warn(msg, DeprecationWarning)
+
+    if choicelist[0].ndim == 0:
+        # This may be common, so avoid the call.
+        result_shape = condlist[0].shape
+    else:
+        result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape
+
+    result = np.full(result_shape, choicelist[-1], dtype)
+
+    # Use np.copyto to burn each choicelist array onto result, using the
+    # corresponding condlist as a boolean mask. This is done in reverse
+    # order since the first choice should take precedence.
+    choicelist = choicelist[-2::-1]
+    condlist = condlist[::-1]
+    for choice, cond in zip(choicelist, condlist):
+        np.copyto(result, choice, where=cond)
+
+    return result
+
+
+def copy(a, order='K'):
+    """
+    Return an array copy of the given object.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    order : {'C', 'F', 'A', 'K'}, optional
+        Controls the memory layout of the copy. 'C' means C-order,
+        'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
+        'C' otherwise. 'K' means match the layout of `a` as closely
+        as possible. (Note that this function and :meth:ndarray.copy are very
+        similar, but have different default values for their order=
+        arguments.)
+
+    Returns
+    -------
+    arr : ndarray
+        Array interpretation of `a`.
+
+    Notes
+    -----
+    This is equivalent to
+
+    >>> np.array(a, copy=True)                              #doctest: +SKIP
+
+    Examples
+    --------
+    Create an array x, with a reference y and a copy z:
+
+    >>> x = np.array([1, 2, 3])
+    >>> y = x
+    >>> z = np.copy(x)
+
+    Note that, when we modify x, y changes, but not z:
+
+    >>> x[0] = 10
+    >>> x[0] == y[0]
+    True
+    >>> x[0] == z[0]
+    False
+
+    """
+    return array(a, order=order, copy=True)
+
+# Basic operations
+
+
+def gradient(f, *varargs, **kwargs):
+    """
+    Return the gradient of an N-dimensional array.
+
+    The gradient is computed using second order accurate central differences
+    in the interior and either first differences or second order accurate
+    one-sides (forward or backwards) differences at the boundaries. The
+    returned gradient hence has the same shape as the input array.
+
+    Parameters
+    ----------
+    f : array_like
+        An N-dimensional array containing samples of a scalar function.
+    varargs : scalar or list of scalar, optional
+        N scalars specifying the sample distances for each dimension,
+        i.e. `dx`, `dy`, `dz`, ... Default distance: 1.
+        single scalar specifies sample distance for all dimensions.
+        if `axis` is given, the number of varargs must equal the number of axes.
+    edge_order : {1, 2}, optional
+        Gradient is calculated using N\ :sup:`th` order accurate differences
+        at the boundaries. Default: 1.
+
+        .. versionadded:: 1.9.1
+
+    axis : None or int or tuple of ints, optional
+        Gradient is calculated only along the given axis or axes
+        The default (axis = None) is to calculate the gradient for all the axes of the input array.
+        axis may be negative, in which case it counts from the last to the first axis.
+
+        .. versionadded:: 1.11.0
+
+    Returns
+    -------
+    gradient : list of ndarray
+        Each element of `list` has the same shape as `f` giving the derivative
+        of `f` with respect to each dimension.
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 11, 16], dtype=np.float)
+    >>> np.gradient(x)
+    array([ 1. ,  1.5,  2.5,  3.5,  4.5,  5. ])
+    >>> np.gradient(x, 2)
+    array([ 0.5 ,  0.75,  1.25,  1.75,  2.25,  2.5 ])
+
+    For two dimensional arrays, the return will be two arrays ordered by
+    axis. In this example the first array stands for the gradient in
+    rows and the second one in columns direction:
+
+    >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float))
+    [array([[ 2.,  2., -1.],
+            [ 2.,  2., -1.]]), array([[ 1. ,  2.5,  4. ],
+            [ 1. ,  1. ,  1. ]])]
+
+    >>> x = np.array([0, 1, 2, 3, 4])
+    >>> dx = np.gradient(x)
+    >>> y = x**2
+    >>> np.gradient(y, dx, edge_order=2)
+    array([-0.,  2.,  4.,  6.,  8.])
+
+    The axis keyword can be used to specify a subset of axes of which the gradient is calculated
+    >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float), axis=0)
+    array([[ 2.,  2., -1.],
+           [ 2.,  2., -1.]])
+    """
+    f = np.asanyarray(f)
+    N = len(f.shape)  # number of dimensions
+
+    axes = kwargs.pop('axis', None)
+    if axes is None:
+        axes = tuple(range(N))
+    # check axes to have correct type and no duplicate entries
+    if isinstance(axes, int):
+        axes = (axes,)
+    if not isinstance(axes, tuple):
+        raise TypeError("A tuple of integers or a single integer is required")
+
+    # normalize axis values:
+    axes = tuple(x + N if x < 0 else x for x in axes)
+    if max(axes) >= N or min(axes) < 0:
+        raise ValueError("'axis' entry is out of bounds")
+
+    if len(set(axes)) != len(axes):
+        raise ValueError("duplicate value in 'axis'")
+
+    n = len(varargs)
+    if n == 0:
+        dx = [1.0]*N
+    elif n == 1:
+        dx = [varargs[0]]*N
+    elif n == len(axes):
+        dx = list(varargs)
+    else:
+        raise SyntaxError(
+            "invalid number of arguments")
+
+    edge_order = kwargs.pop('edge_order', 1)
+    if kwargs:
+        raise TypeError('"{}" are not valid keyword arguments.'.format(
+                                                  '", "'.join(kwargs.keys())))
+    if edge_order > 2:
+        raise ValueError("'edge_order' greater than 2 not supported")
+
+    # use central differences on interior and one-sided differences on the
+    # endpoints. This preserves second order-accuracy over the full domain.
+
+    outvals = []
+
+    # create slice objects --- initially all are [:, :, ..., :]
+    slice1 = [slice(None)]*N
+    slice2 = [slice(None)]*N
+    slice3 = [slice(None)]*N
+    slice4 = [slice(None)]*N
+
+    otype = f.dtype.char
+    if otype not in ['f', 'd', 'F', 'D', 'm', 'M']:
+        otype = 'd'
+
+    # Difference of datetime64 elements results in timedelta64
+    if otype == 'M':
+        # Need to use the full dtype name because it contains unit information
+        otype = f.dtype.name.replace('datetime', 'timedelta')
+    elif otype == 'm':
+        # Needs to keep the specific units, can't be a general unit
+        otype = f.dtype
+
+    # Convert datetime64 data into ints. Make dummy variable `y`
+    # that is a view of ints if the data is datetime64, otherwise
+    # just set y equal to the array `f`.
+    if f.dtype.char in ["M", "m"]:
+        y = f.view('int64')
+    else:
+        y = f
+
+    for i, axis in enumerate(axes):
+
+        if y.shape[axis] < 2:
+            raise ValueError(
+                "Shape of array too small to calculate a numerical gradient, "
+                "at least two elements are required.")
+
+        # Numerical differentiation: 1st order edges, 2nd order interior
+        if y.shape[axis] == 2 or edge_order == 1:
+            # Use first order differences for time data
+            out = np.empty_like(y, dtype=otype)
+
+            slice1[axis] = slice(1, -1)
+            slice2[axis] = slice(2, None)
+            slice3[axis] = slice(None, -2)
+            # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
+            out[slice1] = (y[slice2] - y[slice3])/2.0
+
+            slice1[axis] = 0
+            slice2[axis] = 1
+            slice3[axis] = 0
+            # 1D equivalent -- out[0] = (y[1] - y[0])
+            out[slice1] = (y[slice2] - y[slice3])
+
+            slice1[axis] = -1
+            slice2[axis] = -1
+            slice3[axis] = -2
+            # 1D equivalent -- out[-1] = (y[-1] - y[-2])
+            out[slice1] = (y[slice2] - y[slice3])
+
+        # Numerical differentiation: 2st order edges, 2nd order interior
+        else:
+            # Use second order differences where possible
+            out = np.empty_like(y, dtype=otype)
+
+            slice1[axis] = slice(1, -1)
+            slice2[axis] = slice(2, None)
+            slice3[axis] = slice(None, -2)
+            # 1D equivalent -- out[1:-1] = (y[2:] - y[:-2])/2.0
+            out[slice1] = (y[slice2] - y[slice3])/2.0
+
+            slice1[axis] = 0
+            slice2[axis] = 0
+            slice3[axis] = 1
+            slice4[axis] = 2
+            # 1D equivalent -- out[0] = -(3*y[0] - 4*y[1] + y[2]) / 2.0
+            out[slice1] = -(3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
+
+            slice1[axis] = -1
+            slice2[axis] = -1
+            slice3[axis] = -2
+            slice4[axis] = -3
+            # 1D equivalent -- out[-1] = (3*y[-1] - 4*y[-2] + y[-3])
+            out[slice1] = (3.0*y[slice2] - 4.0*y[slice3] + y[slice4])/2.0
+
+        # divide by step size
+        out /= dx[i]
+        outvals.append(out)
+
+        # reset the slice object in this dimension to ":"
+        slice1[axis] = slice(None)
+        slice2[axis] = slice(None)
+        slice3[axis] = slice(None)
+        slice4[axis] = slice(None)
+
+    if len(axes) == 1:
+        return outvals[0]
+    else:
+        return outvals
+
+
+def diff(a, n=1, axis=-1):
+    """
+    Calculate the n-th discrete difference along given axis.
+
+    The first difference is given by ``out[n] = a[n+1] - a[n]`` along
+    the given axis, higher differences are calculated by using `diff`
+    recursively.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+    n : int, optional
+        The number of times values are differenced.
+    axis : int, optional
+        The axis along which the difference is taken, default is the last axis.
+
+    Returns
+    -------
+    diff : ndarray
+        The n-th differences. The shape of the output is the same as `a`
+        except along `axis` where the dimension is smaller by `n`.
+.
+
+    See Also
+    --------
+    gradient, ediff1d, cumsum
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 4, 7, 0])
+    >>> np.diff(x)
+    array([ 1,  2,  3, -7])
+    >>> np.diff(x, n=2)
+    array([  1,   1, -10])
+
+    >>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]])
+    >>> np.diff(x)
+    array([[2, 3, 4],
+           [5, 1, 2]])
+    >>> np.diff(x, axis=0)
+    array([[-1,  2,  0, -2]])
+
+    """
+    if n == 0:
+        return a
+    if n < 0:
+        raise ValueError(
+            "order must be non-negative but got " + repr(n))
+    a = asanyarray(a)
+    nd = len(a.shape)
+    slice1 = [slice(None)]*nd
+    slice2 = [slice(None)]*nd
+    slice1[axis] = slice(1, None)
+    slice2[axis] = slice(None, -1)
+    slice1 = tuple(slice1)
+    slice2 = tuple(slice2)
+    if n > 1:
+        return diff(a[slice1]-a[slice2], n-1, axis=axis)
+    else:
+        return a[slice1]-a[slice2]
+
+
+def interp(x, xp, fp, left=None, right=None, period=None):
+    """
+    One-dimensional linear interpolation.
+
+    Returns the one-dimensional piecewise linear interpolant to a function
+    with given values at discrete data-points.
+
+    Parameters
+    ----------
+    x : array_like
+        The x-coordinates of the interpolated values.
+
+    xp : 1-D sequence of floats
+        The x-coordinates of the data points, must be increasing if argument
+        `period` is not specified. Otherwise, `xp` is internally sorted after
+        normalizing the periodic boundaries with ``xp = xp % period``.
+
+    fp : 1-D sequence of floats
+        The y-coordinates of the data points, same length as `xp`.
+
+    left : float, optional
+        Value to return for `x < xp[0]`, default is `fp[0]`.
+
+    right : float, optional
+        Value to return for `x > xp[-1]`, default is `fp[-1]`.
+
+    period : None or float, optional
+        A period for the x-coordinates. This parameter allows the proper
+        interpolation of angular x-coordinates. Parameters `left` and `right`
+        are ignored if `period` is specified.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    y : float or ndarray
+        The interpolated values, same shape as `x`.
+
+    Raises
+    ------
+    ValueError
+        If `xp` and `fp` have different length
+        If `xp` or `fp` are not 1-D sequences
+        If `period == 0`
+
+    Notes
+    -----
+    Does not check that the x-coordinate sequence `xp` is increasing.
+    If `xp` is not increasing, the results are nonsense.
+    A simple check for increasing is::
+
+        np.all(np.diff(xp) > 0)
+
+    Examples
+    --------
+    >>> xp = [1, 2, 3]
+    >>> fp = [3, 2, 0]
+    >>> np.interp(2.5, xp, fp)
+    1.0
+    >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
+    array([ 3. ,  3. ,  2.5 ,  0.56,  0. ])
+    >>> UNDEF = -99.0
+    >>> np.interp(3.14, xp, fp, right=UNDEF)
+    -99.0
+
+    Plot an interpolant to the sine function:
+
+    >>> x = np.linspace(0, 2*np.pi, 10)
+    >>> y = np.sin(x)
+    >>> xvals = np.linspace(0, 2*np.pi, 50)
+    >>> yinterp = np.interp(xvals, x, y)
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot(x, y, 'o')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.plot(xvals, yinterp, '-x')
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.show()
+
+    Interpolation with periodic x-coordinates:
+
+    >>> x = [-180, -170, -185, 185, -10, -5, 0, 365]
+    >>> xp = [190, -190, 350, -350]
+    >>> fp = [5, 10, 3, 4]
+    >>> np.interp(x, xp, fp, period=360)
+    array([7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75])
+
+    """
+    if period is None:
+        if isinstance(x, (float, int, number)):
+            return compiled_interp([x], xp, fp, left, right).item()
+        elif isinstance(x, np.ndarray) and x.ndim == 0:
+            return compiled_interp([x], xp, fp, left, right).item()
+        else:
+            return compiled_interp(x, xp, fp, left, right)
+    else:
+        if period == 0:
+            raise ValueError("period must be a non-zero value")
+        period = abs(period)
+        left = None
+        right = None
+        return_array = True
+        if isinstance(x, (float, int, number)):
+            return_array = False
+            x = [x]
+        x = np.asarray(x, dtype=np.float64)
+        xp = np.asarray(xp, dtype=np.float64)
+        fp = np.asarray(fp, dtype=np.float64)
+        if xp.ndim != 1 or fp.ndim != 1:
+            raise ValueError("Data points must be 1-D sequences")
+        if xp.shape[0] != fp.shape[0]:
+            raise ValueError("fp and xp are not of the same length")
+        # normalizing periodic boundaries
+        x = x % period
+        xp = xp % period
+        asort_xp = np.argsort(xp)
+        xp = xp[asort_xp]
+        fp = fp[asort_xp]
+        xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
+        fp = np.concatenate((fp[-1:], fp, fp[0:1]))
+        if return_array:
+            return compiled_interp(x, xp, fp, left, right)
+        else:
+            return compiled_interp(x, xp, fp, left, right).item()
+
+
+def angle(z, deg=0):
+    """
+    Return the angle of the complex argument.
+
+    Parameters
+    ----------
+    z : array_like
+        A complex number or sequence of complex numbers.
+    deg : bool, optional
+        Return angle in degrees if True, radians if False (default).
+
+    Returns
+    -------
+    angle : ndarray or scalar
+        The counterclockwise angle from the positive real axis on
+        the complex plane, with dtype as numpy.float64.
+
+    See Also
+    --------
+    arctan2
+    absolute
+
+
+
+    Examples
+    --------
+    >>> np.angle([1.0, 1.0j, 1+1j])               # in radians
+    array([ 0.        ,  1.57079633,  0.78539816])
+    >>> np.angle(1+1j, deg=True)                  # in degrees
+    45.0
+
+    """
+    if deg:
+        fact = 180/pi
+    else:
+        fact = 1.0
+    z = asarray(z)
+    if (issubclass(z.dtype.type, _nx.complexfloating)):
+        zimag = z.imag
+        zreal = z.real
+    else:
+        zimag = 0
+        zreal = z
+    return arctan2(zimag, zreal) * fact
+
+
+def unwrap(p, discont=pi, axis=-1):
+    """
+    Unwrap by changing deltas between values to 2*pi complement.
+
+    Unwrap radian phase `p` by changing absolute jumps greater than
+    `discont` to their 2*pi complement along the given axis.
+
+    Parameters
+    ----------
+    p : array_like
+        Input array.
+    discont : float, optional
+        Maximum discontinuity between values, default is ``pi``.
+    axis : int, optional
+        Axis along which unwrap will operate, default is the last axis.
+
+    Returns
+    -------
+    out : ndarray
+        Output array.
+
+    See Also
+    --------
+    rad2deg, deg2rad
+
+    Notes
+    -----
+    If the discontinuity in `p` is smaller than ``pi``, but larger than
+    `discont`, no unwrapping is done because taking the 2*pi complement
+    would only make the discontinuity larger.
+
+    Examples
+    --------
+    >>> phase = np.linspace(0, np.pi, num=5)
+    >>> phase[3:] += np.pi
+    >>> phase
+    array([ 0.        ,  0.78539816,  1.57079633,  5.49778714,  6.28318531])
+    >>> np.unwrap(phase)
+    array([ 0.        ,  0.78539816,  1.57079633, -0.78539816,  0.        ])
+
+    """
+    p = asarray(p)
+    nd = len(p.shape)
+    dd = diff(p, axis=axis)
+    slice1 = [slice(None, None)]*nd     # full slices
+    slice1[axis] = slice(1, None)
+    ddmod = mod(dd + pi, 2*pi) - pi
+    _nx.copyto(ddmod, pi, where=(ddmod == -pi) & (dd > 0))
+    ph_correct = ddmod - dd
+    _nx.copyto(ph_correct, 0, where=abs(dd) < discont)
+    up = array(p, copy=True, dtype='d')
+    up[slice1] = p[slice1] + ph_correct.cumsum(axis)
+    return up
+
+
+def sort_complex(a):
+    """
+    Sort a complex array using the real part first, then the imaginary part.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array
+
+    Returns
+    -------
+    out : complex ndarray
+        Always returns a sorted complex array.
+
+    Examples
+    --------
+    >>> np.sort_complex([5, 3, 6, 2, 1])
+    array([ 1.+0.j,  2.+0.j,  3.+0.j,  5.+0.j,  6.+0.j])
+
+    >>> np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
+    array([ 1.+2.j,  2.-1.j,  3.-3.j,  3.-2.j,  3.+5.j])
+
+    """
+    b = array(a, copy=True)
+    b.sort()
+    if not issubclass(b.dtype.type, _nx.complexfloating):
+        if b.dtype.char in 'bhBH':
+            return b.astype('F')
+        elif b.dtype.char == 'g':
+            return b.astype('G')
+        else:
+            return b.astype('D')
+    else:
+        return b
+
+
+def trim_zeros(filt, trim='fb'):
+    """
+    Trim the leading and/or trailing zeros from a 1-D array or sequence.
+
+    Parameters
+    ----------
+    filt : 1-D array or sequence
+        Input array.
+    trim : str, optional
+        A string with 'f' representing trim from front and 'b' to trim from
+        back. Default is 'fb', trim zeros from both front and back of the
+        array.
+
+    Returns
+    -------
+    trimmed : 1-D array or sequence
+        The result of trimming the input. The input data type is preserved.
+
+    Examples
+    --------
+    >>> a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))
+    >>> np.trim_zeros(a)
+    array([1, 2, 3, 0, 2, 1])
+
+    >>> np.trim_zeros(a, 'b')
+    array([0, 0, 0, 1, 2, 3, 0, 2, 1])
+
+    The input data type is preserved, list/tuple in means list/tuple out.
+
+    >>> np.trim_zeros([0, 1, 2, 0])
+    [1, 2]
+
+    """
+    first = 0
+    trim = trim.upper()
+    if 'F' in trim:
+        for i in filt:
+            if i != 0.:
+                break
+            else:
+                first = first + 1
+    last = len(filt)
+    if 'B' in trim:
+        for i in filt[::-1]:
+            if i != 0.:
+                break
+            else:
+                last = last - 1
+    return filt[first:last]
+
+
+@deprecate
+def unique(x):
+    """
+    This function is deprecated.  Use numpy.lib.arraysetops.unique()
+    instead.
+    """
+    try:
+        tmp = x.flatten()
+        if tmp.size == 0:
+            return tmp
+        tmp.sort()
+        idx = concatenate(([True], tmp[1:] != tmp[:-1]))
+        return tmp[idx]
+    except AttributeError:
+        items = sorted(set(x))
+        return asarray(items)
+
+
+def extract(condition, arr):
+    """
+    Return the elements of an array that satisfy some condition.
+
+    This is equivalent to ``np.compress(ravel(condition), ravel(arr))``.  If
+    `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``.
+
+    Note that `place` does the exact opposite of `extract`.
+
+    Parameters
+    ----------
+    condition : array_like
+        An array whose nonzero or True entries indicate the elements of `arr`
+        to extract.
+    arr : array_like
+        Input array of the same size as `condition`.
+
+    Returns
+    -------
+    extract : ndarray
+        Rank 1 array of values from `arr` where `condition` is True.
+
+    See Also
+    --------
+    take, put, copyto, compress, place
+
+    Examples
+    --------
+    >>> arr = np.arange(12).reshape((3, 4))
+    >>> arr
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11]])
+    >>> condition = np.mod(arr, 3)==0
+    >>> condition
+    array([[ True, False, False,  True],
+           [False, False,  True, False],
+           [False,  True, False, False]], dtype=bool)
+    >>> np.extract(condition, arr)
+    array([0, 3, 6, 9])
+
+
+    If `condition` is boolean:
+
+    >>> arr[condition]
+    array([0, 3, 6, 9])
+
+    """
+    return _nx.take(ravel(arr), nonzero(ravel(condition))[0])
+
+
+def place(arr, mask, vals):
+    """
+    Change elements of an array based on conditional and input values.
+
+    Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that
+    `place` uses the first N elements of `vals`, where N is the number of
+    True values in `mask`, while `copyto` uses the elements where `mask`
+    is True.
+
+    Note that `extract` does the exact opposite of `place`.
+
+    Parameters
+    ----------
+    arr : ndarray
+        Array to put data into.
+    mask : array_like
+        Boolean mask array. Must have the same size as `a`.
+    vals : 1-D sequence
+        Values to put into `a`. Only the first N elements are used, where
+        N is the number of True values in `mask`. If `vals` is smaller
+        than N it will be repeated.
+
+    See Also
+    --------
+    copyto, put, take, extract
+
+    Examples
+    --------
+    >>> arr = np.arange(6).reshape(2, 3)
+    >>> np.place(arr, arr>2, [44, 55])
+    >>> arr
+    array([[ 0,  1,  2],
+           [44, 55, 44]])
+
+    """
+    if not isinstance(arr, np.ndarray):
+        raise TypeError("argument 1 must be numpy.ndarray, "
+                        "not {name}".format(name=type(arr).__name__))
+
+    return _insert(arr, mask, vals)
+
+
+def disp(mesg, device=None, linefeed=True):
+    """
+    Display a message on a device.
+
+    Parameters
+    ----------
+    mesg : str
+        Message to display.
+    device : object
+        Device to write message. If None, defaults to ``sys.stdout`` which is
+        very similar to ``print``. `device` needs to have ``write()`` and
+        ``flush()`` methods.
+    linefeed : bool, optional
+        Option whether to print a line feed or not. Defaults to True.
+
+    Raises
+    ------
+    AttributeError
+        If `device` does not have a ``write()`` or ``flush()`` method.
+
+    Examples
+    --------
+    Besides ``sys.stdout``, a file-like object can also be used as it has
+    both required methods:
+
+    >>> from StringIO import StringIO
+    >>> buf = StringIO()
+    >>> np.disp('"Display" in a file', device=buf)
+    >>> buf.getvalue()
+    '"Display" in a file\\n'
+
+    """
+    if device is None:
+        device = sys.stdout
+    if linefeed:
+        device.write('%s\n' % mesg)
+    else:
+        device.write('%s' % mesg)
+    device.flush()
+    return
+
+
+class vectorize(object):
+    """
+    vectorize(pyfunc, otypes='', doc=None, excluded=None, cache=False)
+
+    Generalized function class.
+
+    Define a vectorized function which takes a nested sequence
+    of objects or numpy arrays as inputs and returns a
+    numpy array as output. The vectorized function evaluates `pyfunc` over
+    successive tuples of the input arrays like the python map function,
+    except it uses the broadcasting rules of numpy.
+
+    The data type of the output of `vectorized` is determined by calling
+    the function with the first element of the input.  This can be avoided
+    by specifying the `otypes` argument.
+
+    Parameters
+    ----------
+    pyfunc : callable
+        A python function or method.
+    otypes : str or list of dtypes, optional
+        The output data type. It must be specified as either a string of
+        typecode characters or a list of data type specifiers. There should
+        be one data type specifier for each output.
+    doc : str, optional
+        The docstring for the function. If `None`, the docstring will be the
+        ``pyfunc.__doc__``.
+    excluded : set, optional
+        Set of strings or integers representing the positional or keyword
+        arguments for which the function will not be vectorized.  These will be
+        passed directly to `pyfunc` unmodified.
+
+        .. versionadded:: 1.7.0
+
+    cache : bool, optional
+       If `True`, then cache the first function call that determines the number
+       of outputs if `otypes` is not provided.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    vectorized : callable
+        Vectorized function.
+
+    Examples
+    --------
+    >>> def myfunc(a, b):
+    ...     "Return a-b if a>b, otherwise return a+b"
+    ...     if a > b:
+    ...         return a - b
+    ...     else:
+    ...         return a + b
+
+    >>> vfunc = np.vectorize(myfunc)
+    >>> vfunc([1, 2, 3, 4], 2)
+    array([3, 4, 1, 2])
+
+    The docstring is taken from the input function to `vectorize` unless it
+    is specified
+
+    >>> vfunc.__doc__
+    'Return a-b if a>b, otherwise return a+b'
+    >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')
+    >>> vfunc.__doc__
+    'Vectorized `myfunc`'
+
+    The output type is determined by evaluating the first element of the input,
+    unless it is specified
+
+    >>> out = vfunc([1, 2, 3, 4], 2)
+    >>> type(out[0])
+    <type 'numpy.int32'>
+    >>> vfunc = np.vectorize(myfunc, otypes=[np.float])
+    >>> out = vfunc([1, 2, 3, 4], 2)
+    >>> type(out[0])
+    <type 'numpy.float64'>
+
+    The `excluded` argument can be used to prevent vectorizing over certain
+    arguments.  This can be useful for array-like arguments of a fixed length
+    such as the coefficients for a polynomial as in `polyval`:
+
+    >>> def mypolyval(p, x):
+    ...     _p = list(p)
+    ...     res = _p.pop(0)
+    ...     while _p:
+    ...         res = res*x + _p.pop(0)
+    ...     return res
+    >>> vpolyval = np.vectorize(mypolyval, excluded=['p'])
+    >>> vpolyval(p=[1, 2, 3], x=[0, 1])
+    array([3, 6])
+
+    Positional arguments may also be excluded by specifying their position:
+
+    >>> vpolyval.excluded.add(0)
+    >>> vpolyval([1, 2, 3], x=[0, 1])
+    array([3, 6])
+
+    Notes
+    -----
+    The `vectorize` function is provided primarily for convenience, not for
+    performance. The implementation is essentially a for loop.
+
+    If `otypes` is not specified, then a call to the function with the
+    first argument will be used to determine the number of outputs.  The
+    results of this call will be cached if `cache` is `True` to prevent
+    calling the function twice.  However, to implement the cache, the
+    original function must be wrapped which will slow down subsequent
+    calls, so only do this if your function is expensive.
+
+    The new keyword argument interface and `excluded` argument support
+    further degrades performance.
+
+    """
+
+    def __init__(self, pyfunc, otypes='', doc=None, excluded=None,
+                 cache=False):
+        self.pyfunc = pyfunc
+        self.cache = cache
+        self._ufunc = None    # Caching to improve default performance
+
+        if doc is None:
+            self.__doc__ = pyfunc.__doc__
+        else:
+            self.__doc__ = doc
+
+        if isinstance(otypes, str):
+            self.otypes = otypes
+            for char in self.otypes:
+                if char not in typecodes['All']:
+                    raise ValueError(
+                        "Invalid otype specified: %s" % (char,))
+        elif iterable(otypes):
+            self.otypes = ''.join([_nx.dtype(x).char for x in otypes])
+        else:
+            raise ValueError(
+                "Invalid otype specification")
+
+        # Excluded variable support
+        if excluded is None:
+            excluded = set()
+        self.excluded = set(excluded)
+
+    def __call__(self, *args, **kwargs):
+        """
+        Return arrays with the results of `pyfunc` broadcast (vectorized) over
+        `args` and `kwargs` not in `excluded`.
+        """
+        excluded = self.excluded
+        if not kwargs and not excluded:
+            func = self.pyfunc
+            vargs = args
+        else:
+            # The wrapper accepts only positional arguments: we use `names` and
+            # `inds` to mutate `the_args` and `kwargs` to pass to the original
+            # function.
+            nargs = len(args)
+
+            names = [_n for _n in kwargs if _n not in excluded]
+            inds = [_i for _i in range(nargs) if _i not in excluded]
+            the_args = list(args)
+
+            def func(*vargs):
+                for _n, _i in enumerate(inds):
+                    the_args[_i] = vargs[_n]
+                kwargs.update(zip(names, vargs[len(inds):]))
+                return self.pyfunc(*the_args, **kwargs)
+
+            vargs = [args[_i] for _i in inds]
+            vargs.extend([kwargs[_n] for _n in names])
+
+        return self._vectorize_call(func=func, args=vargs)
+
+    def _get_ufunc_and_otypes(self, func, args):
+        """Return (ufunc, otypes)."""
+        # frompyfunc will fail if args is empty
+        if not args:
+            raise ValueError('args can not be empty')
+
+        if self.otypes:
+            otypes = self.otypes
+            nout = len(otypes)
+
+            # Note logic here: We only *use* self._ufunc if func is self.pyfunc
+            # even though we set self._ufunc regardless.
+            if func is self.pyfunc and self._ufunc is not None:
+                ufunc = self._ufunc
+            else:
+                ufunc = self._ufunc = frompyfunc(func, len(args), nout)
+        else:
+            # Get number of outputs and output types by calling the function on
+            # the first entries of args.  We also cache the result to prevent
+            # the subsequent call when the ufunc is evaluated.
+            # Assumes that ufunc first evaluates the 0th elements in the input
+            # arrays (the input values are not checked to ensure this)
+            inputs = [asarray(_a).flat[0] for _a in args]
+            outputs = func(*inputs)
+
+            # Performance note: profiling indicates that -- for simple
+            # functions at least -- this wrapping can almost double the
+            # execution time.
+            # Hence we make it optional.
+            if self.cache:
+                _cache = [outputs]
+
+                def _func(*vargs):
+                    if _cache:
+                        return _cache.pop()
+                    else:
+                        return func(*vargs)
+            else:
+                _func = func
+
+            if isinstance(outputs, tuple):
+                nout = len(outputs)
+            else:
+                nout = 1
+                outputs = (outputs,)
+
+            otypes = ''.join([asarray(outputs[_k]).dtype.char
+                              for _k in range(nout)])
+
+            # Performance note: profiling indicates that creating the ufunc is
+            # not a significant cost compared with wrapping so it seems not
+            # worth trying to cache this.
+            ufunc = frompyfunc(_func, len(args), nout)
+
+        return ufunc, otypes
+
+    def _vectorize_call(self, func, args):
+        """Vectorized call to `func` over positional `args`."""
+        if not args:
+            _res = func()
+        else:
+            ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
+
+            # Convert args to object arrays first
+            inputs = [array(_a, copy=False, subok=True, dtype=object)
+                      for _a in args]
+
+            outputs = ufunc(*inputs)
+
+            if ufunc.nout == 1:
+                _res = array(outputs,
+                             copy=False, subok=True, dtype=otypes[0])
+            else:
+                _res = tuple([array(_x, copy=False, subok=True, dtype=_t)
+                              for _x, _t in zip(outputs, otypes)])
+        return _res
+
+
+def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None,
+        aweights=None):
+    """
+    Estimate a covariance matrix, given data and weights.
+
+    Covariance indicates the level to which two variables vary together.
+    If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`,
+    then the covariance matrix element :math:`C_{ij}` is the covariance of
+    :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance
+    of :math:`x_i`.
+
+    See the notes for an outline of the algorithm.
+
+    Parameters
+    ----------
+    m : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `m` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same form
+        as that of `m`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : bool, optional
+        Default normalization (False) is by ``(N - 1)``, where ``N`` is the
+        number of observations given (unbiased estimate). If `bias` is True, then
+        normalization is by ``N``. These values can be overridden by using the
+        keyword ``ddof`` in numpy versions >= 1.5.
+    ddof : int, optional
+        If not ``None`` the default value implied by `bias` is overridden.
+        Note that ``ddof=1`` will return the unbiased estimate, even if both
+        `fweights` and `aweights` are specified, and ``ddof=0`` will return
+        the simple average. See the notes for the details. The default value
+        is ``None``.
+
+        .. versionadded:: 1.5
+    fweights : array_like, int, optional
+        1-D array of integer freguency weights; the number of times each
+        observation vector should be repeated.
+
+        .. versionadded:: 1.10
+    aweights : array_like, optional
+        1-D array of observation vector weights. These relative weights are
+        typically large for observations considered "important" and smaller for
+        observations considered less "important". If ``ddof=0`` the array of
+        weights can be used to assign probabilities to observation vectors.
+
+        .. versionadded:: 1.10
+
+    Returns
+    -------
+    out : ndarray
+        The covariance matrix of the variables.
+
+    See Also
+    --------
+    corrcoef : Normalized covariance matrix
+
+    Notes
+    -----
+    Assume that the observations are in the columns of the observation
+    array `m` and let ``f = fweights`` and ``a = aweights`` for brevity. The
+    steps to compute the weighted covariance are as follows::
+
+        >>> w = f * a
+        >>> v1 = np.sum(w)
+        >>> v2 = np.sum(w * a)
+        >>> m -= np.sum(m * w, axis=1, keepdims=True) / v1
+        >>> cov = np.dot(m * w, m.T) * v1 / (v1**2 - ddof * v2)
+
+    Note that when ``a == 1``, the normalization factor
+    ``v1 / (v1**2 - ddof * v2)`` goes over to ``1 / (np.sum(f) - ddof)``
+    as it should.
+
+    Examples
+    --------
+    Consider two variables, :math:`x_0` and :math:`x_1`, which
+    correlate perfectly, but in opposite directions:
+
+    >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T
+    >>> x
+    array([[0, 1, 2],
+           [2, 1, 0]])
+
+    Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance
+    matrix shows this clearly:
+
+    >>> np.cov(x)
+    array([[ 1., -1.],
+           [-1.,  1.]])
+
+    Note that element :math:`C_{0,1}`, which shows the correlation between
+    :math:`x_0` and :math:`x_1`, is negative.
+
+    Further, note how `x` and `y` are combined:
+
+    >>> x = [-2.1, -1,  4.3]
+    >>> y = [3,  1.1,  0.12]
+    >>> X = np.vstack((x,y))
+    >>> print(np.cov(X))
+    [[ 11.71        -4.286     ]
+     [ -4.286        2.14413333]]
+    >>> print(np.cov(x, y))
+    [[ 11.71        -4.286     ]
+     [ -4.286        2.14413333]]
+    >>> print(np.cov(x))
+    11.71
+
+    """
+    # Check inputs
+    if ddof is not None and ddof != int(ddof):
+        raise ValueError(
+            "ddof must be integer")
+
+    # Handles complex arrays too
+    m = np.asarray(m)
+    if y is None:
+        dtype = np.result_type(m, np.float64)
+    else:
+        y = np.asarray(y)
+        dtype = np.result_type(m, y, np.float64)
+    X = array(m, ndmin=2, dtype=dtype)
+    if rowvar == 0 and X.shape[0] != 1:
+        X = X.T
+    if X.shape[0] == 0:
+        return np.array([]).reshape(0, 0)
+    if y is not None:
+        y = array(y, copy=False, ndmin=2, dtype=dtype)
+        if rowvar == 0 and y.shape[0] != 1:
+            y = y.T
+        X = np.vstack((X, y))
+
+    if ddof is None:
+        if bias == 0:
+            ddof = 1
+        else:
+            ddof = 0
+
+    # Get the product of frequencies and weights
+    w = None
+    if fweights is not None:
+        fweights = np.asarray(fweights, dtype=np.float)
+        if not np.all(fweights == np.around(fweights)):
+            raise TypeError(
+                "fweights must be integer")
+        if fweights.ndim > 1:
+            raise RuntimeError(
+                "cannot handle multidimensional fweights")
+        if fweights.shape[0] != X.shape[1]:
+            raise RuntimeError(
+                "incompatible numbers of samples and fweights")
+        if any(fweights < 0):
+            raise ValueError(
+                "fweights cannot be negative")
+        w = fweights
+    if aweights is not None:
+        aweights = np.asarray(aweights, dtype=np.float)
+        if aweights.ndim > 1:
+            raise RuntimeError(
+                "cannot handle multidimensional aweights")
+        if aweights.shape[0] != X.shape[1]:
+            raise RuntimeError(
+                "incompatible numbers of samples and aweights")
+        if any(aweights < 0):
+            raise ValueError(
+                "aweights cannot be negative")
+        if w is None:
+            w = aweights
+        else:
+            w *= aweights
+
+    avg, w_sum = average(X, axis=1, weights=w, returned=True)
+    w_sum = w_sum[0]
+
+    # Determine the normalization
+    if w is None:
+        fact = X.shape[1] - ddof
+    elif ddof == 0:
+        fact = w_sum
+    elif aweights is None:
+        fact = w_sum - ddof
+    else:
+        fact = w_sum - ddof*sum(w*aweights)/w_sum
+
+    if fact <= 0:
+        warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
+        fact = 0.0
+
+    X -= avg[:, None]
+    if w is None:
+        X_T = X.T
+    else:
+        X_T = (X*w).T
+    c = dot(X, X_T.conj())
+    c *= 1. / np.float64(fact)
+    return c.squeeze()
+
+
+def corrcoef(x, y=None, rowvar=1, bias=np._NoValue, ddof=np._NoValue):
+    """
+    Return Pearson product-moment correlation coefficients.
+
+    Please refer to the documentation for `cov` for more detail.  The
+    relationship between the correlation coefficient matrix, `R`, and the
+    covariance matrix, `C`, is
+
+    .. math:: R_{ij} = \\frac{ C_{ij} } { \\sqrt{ C_{ii} * C_{jj} } }
+
+    The values of `R` are between -1 and 1, inclusive.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        shape as `x`.
+    rowvar : int, optional
+        If `rowvar` is non-zero (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+    ddof : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+
+    Returns
+    -------
+    R : ndarray
+        The correlation coefficient matrix of the variables.
+
+    See Also
+    --------
+    cov : Covariance matrix
+
+    Notes
+    -----
+    Due to floating point rounding the resulting array may not be Hermitian,
+    the diagonal elements may not be 1, and the elements may not satisfy the
+    inequality abs(a) <= 1. The real and imaginary parts are clipped to the
+    interval [-1,  1] in an attempt to improve on that situation but is not
+    much help in the complex case.
+
+    This function accepts but discards arguments `bias` and `ddof`.  This is
+    for backwards compatibility with previous versions of this function.  These
+    arguments had no effect on the return values of the function and can be
+    safely ignored in this and previous versions of numpy.
+    """
+    if bias is not np._NoValue or ddof is not np._NoValue:
+        # 2015-03-15, 1.10
+        warnings.warn('bias and ddof have no effect and are deprecated',
+                      DeprecationWarning)
+    c = cov(x, y, rowvar)
+    try:
+        d = diag(c)
+    except ValueError:
+        # scalar covariance
+        # nan if incorrect value (nan, inf, 0), 1 otherwise
+        return c / c
+    stddev = sqrt(d.real)
+    c /= stddev[:, None]
+    c /= stddev[None, :]
+
+    # Clip real and imaginary parts to [-1, 1].  This does not guarantee
+    # abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without
+    # excessive work.
+    np.clip(c.real, -1, 1, out=c.real)
+    if np.iscomplexobj(c):
+        np.clip(c.imag, -1, 1, out=c.imag)
+
+    return c
+
+
+def blackman(M):
+    """
+    Return the Blackman window.
+
+    The Blackman window is a taper formed by using the first three
+    terms of a summation of cosines. It was designed to have close to the
+    minimal leakage possible.  It is close to optimal, only slightly worse
+    than a Kaiser window.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an empty
+        array is returned.
+
+    Returns
+    -------
+    out : ndarray
+        The window, with the maximum value normalized to one (the value one
+        appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, hamming, hanning, kaiser
+
+    Notes
+    -----
+    The Blackman window is defined as
+
+    .. math::  w(n) = 0.42 - 0.5 \\cos(2\\pi n/M) + 0.08 \\cos(4\\pi n/M)
+
+    Most references to the Blackman window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function. It is known as a
+    "near optimal" tapering function, almost as good (by some measures)
+    as the kaiser window.
+
+    References
+    ----------
+    Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra,
+    Dover Publications, New York.
+
+    Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing.
+    Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471.
+
+    Examples
+    --------
+    >>> np.blackman(12)
+    array([ -1.38777878e-17,   3.26064346e-02,   1.59903635e-01,
+             4.14397981e-01,   7.36045180e-01,   9.67046769e-01,
+             9.67046769e-01,   7.36045180e-01,   4.14397981e-01,
+             1.59903635e-01,   3.26064346e-02,  -1.38777878e-17])
+
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.blackman(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Blackman window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Blackman window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.42 - 0.5*cos(2.0*pi*n/(M-1)) + 0.08*cos(4.0*pi*n/(M-1))
+
+
+def bartlett(M):
+    """
+    Return the Bartlett window.
+
+    The Bartlett window is very similar to a triangular window, except
+    that the end points are at zero.  It is often used in signal
+    processing for tapering a signal, without generating too much
+    ripple in the frequency domain.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : array
+        The triangular window, with the maximum value normalized to one
+        (the value one appears only if the number of samples is odd), with
+        the first and last samples equal to zero.
+
+    See Also
+    --------
+    blackman, hamming, hanning, kaiser
+
+    Notes
+    -----
+    The Bartlett window is defined as
+
+    .. math:: w(n) = \\frac{2}{M-1} \\left(
+              \\frac{M-1}{2} - \\left|n - \\frac{M-1}{2}\\right|
+              \\right)
+
+    Most references to the Bartlett window come from the signal
+    processing literature, where it is used as one of many windowing
+    functions for smoothing values.  Note that convolution with this
+    window produces linear interpolation.  It is also known as an
+    apodization (which means"removing the foot", i.e. smoothing
+    discontinuities at the beginning and end of the sampled signal) or
+    tapering function. The fourier transform of the Bartlett is the product
+    of two sinc functions.
+    Note the excellent discussion in Kanasewich.
+
+    References
+    ----------
+    .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
+           Biometrika 37, 1-16, 1950.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
+           The University of Alberta Press, 1975, pp. 109-110.
+    .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal
+           Processing", Prentice-Hall, 1999, pp. 468-471.
+    .. [4] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [5] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 429.
+
+
+    Examples
+    --------
+    >>> np.bartlett(12)
+    array([ 0.        ,  0.18181818,  0.36363636,  0.54545455,  0.72727273,
+            0.90909091,  0.90909091,  0.72727273,  0.54545455,  0.36363636,
+            0.18181818,  0.        ])
+
+    Plot the window and its frequency response (requires SciPy and matplotlib):
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.bartlett(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Bartlett window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Bartlett window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return where(less_equal(n, (M-1)/2.0), 2.0*n/(M-1), 2.0 - 2.0*n/(M-1))
+
+
+def hanning(M):
+    """
+    Return the Hanning window.
+
+    The Hanning window is a taper formed by using a weighted cosine.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : ndarray, shape(M,)
+        The window, with the maximum value normalized to one (the value
+        one appears only if `M` is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hamming, kaiser
+
+    Notes
+    -----
+    The Hanning window is defined as
+
+    .. math::  w(n) = 0.5 - 0.5cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
+               \\qquad 0 \\leq n \\leq M-1
+
+    The Hanning was named for Julius von Hann, an Austrian meteorologist.
+    It is also known as the Cosine Bell. Some authors prefer that it be
+    called a Hann window, to help avoid confusion with the very similar
+    Hamming window.
+
+    Most references to the Hanning window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
+           spectra, Dover Publications, New York.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
+           The University of Alberta Press, 1975, pp. 106-108.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [4] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 425.
+
+    Examples
+    --------
+    >>> np.hanning(12)
+    array([ 0.        ,  0.07937323,  0.29229249,  0.57115742,  0.82743037,
+            0.97974649,  0.97974649,  0.82743037,  0.57115742,  0.29229249,
+            0.07937323,  0.        ])
+
+    Plot the window and its frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.hanning(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Hann window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of the Hann window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.5 - 0.5*cos(2.0*pi*n/(M-1))
+
+
+def hamming(M):
+    """
+    Return the Hamming window.
+
+    The Hamming window is a taper formed by using a weighted cosine.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+
+    Returns
+    -------
+    out : ndarray
+        The window, with the maximum value normalized to one (the value
+        one appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hanning, kaiser
+
+    Notes
+    -----
+    The Hamming window is defined as
+
+    .. math::  w(n) = 0.54 - 0.46cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
+               \\qquad 0 \\leq n \\leq M-1
+
+    The Hamming was named for R. W. Hamming, an associate of J. W. Tukey
+    and is described in Blackman and Tukey. It was recommended for
+    smoothing the truncated autocovariance function in the time domain.
+    Most references to the Hamming window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
+           spectra, Dover Publications, New York.
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
+           University of Alberta Press, 1975, pp. 109-110.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+    .. [4] W.H. Press,  B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
+           "Numerical Recipes", Cambridge University Press, 1986, page 425.
+
+    Examples
+    --------
+    >>> np.hamming(12)
+    array([ 0.08      ,  0.15302337,  0.34890909,  0.60546483,  0.84123594,
+            0.98136677,  0.98136677,  0.84123594,  0.60546483,  0.34890909,
+            0.15302337,  0.08      ])
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.hamming(51)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Hamming window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Hamming window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    if M < 1:
+        return array([])
+    if M == 1:
+        return ones(1, float)
+    n = arange(0, M)
+    return 0.54 - 0.46*cos(2.0*pi*n/(M-1))
+
+## Code from cephes for i0
+
+_i0A = [
+    -4.41534164647933937950E-18,
+    3.33079451882223809783E-17,
+    -2.43127984654795469359E-16,
+    1.71539128555513303061E-15,
+    -1.16853328779934516808E-14,
+    7.67618549860493561688E-14,
+    -4.85644678311192946090E-13,
+    2.95505266312963983461E-12,
+    -1.72682629144155570723E-11,
+    9.67580903537323691224E-11,
+    -5.18979560163526290666E-10,
+    2.65982372468238665035E-9,
+    -1.30002500998624804212E-8,
+    6.04699502254191894932E-8,
+    -2.67079385394061173391E-7,
+    1.11738753912010371815E-6,
+    -4.41673835845875056359E-6,
+    1.64484480707288970893E-5,
+    -5.75419501008210370398E-5,
+    1.88502885095841655729E-4,
+    -5.76375574538582365885E-4,
+    1.63947561694133579842E-3,
+    -4.32430999505057594430E-3,
+    1.05464603945949983183E-2,
+    -2.37374148058994688156E-2,
+    4.93052842396707084878E-2,
+    -9.49010970480476444210E-2,
+    1.71620901522208775349E-1,
+    -3.04682672343198398683E-1,
+    6.76795274409476084995E-1
+    ]
+
+_i0B = [
+    -7.23318048787475395456E-18,
+    -4.83050448594418207126E-18,
+    4.46562142029675999901E-17,
+    3.46122286769746109310E-17,
+    -2.82762398051658348494E-16,
+    -3.42548561967721913462E-16,
+    1.77256013305652638360E-15,
+    3.81168066935262242075E-15,
+    -9.55484669882830764870E-15,
+    -4.15056934728722208663E-14,
+    1.54008621752140982691E-14,
+    3.85277838274214270114E-13,
+    7.18012445138366623367E-13,
+    -1.79417853150680611778E-12,
+    -1.32158118404477131188E-11,
+    -3.14991652796324136454E-11,
+    1.18891471078464383424E-11,
+    4.94060238822496958910E-10,
+    3.39623202570838634515E-9,
+    2.26666899049817806459E-8,
+    2.04891858946906374183E-7,
+    2.89137052083475648297E-6,
+    6.88975834691682398426E-5,
+    3.36911647825569408990E-3,
+    8.04490411014108831608E-1
+    ]
+
+
+def _chbevl(x, vals):
+    b0 = vals[0]
+    b1 = 0.0
+
+    for i in range(1, len(vals)):
+        b2 = b1
+        b1 = b0
+        b0 = x*b1 - b2 + vals[i]
+
+    return 0.5*(b0 - b2)
+
+
+def _i0_1(x):
+    return exp(x) * _chbevl(x/2.0-2, _i0A)
+
+
+def _i0_2(x):
+    return exp(x) * _chbevl(32.0/x - 2.0, _i0B) / sqrt(x)
+
+
+def i0(x):
+    """
+    Modified Bessel function of the first kind, order 0.
+
+    Usually denoted :math:`I_0`.  This function does broadcast, but will *not*
+    "up-cast" int dtype arguments unless accompanied by at least one float or
+    complex dtype argument (see Raises below).
+
+    Parameters
+    ----------
+    x : array_like, dtype float or complex
+        Argument of the Bessel function.
+
+    Returns
+    -------
+    out : ndarray, shape = x.shape, dtype = x.dtype
+        The modified Bessel function evaluated at each of the elements of `x`.
+
+    Raises
+    ------
+    TypeError: array cannot be safely cast to required type
+        If argument consists exclusively of int dtypes.
+
+    See Also
+    --------
+    scipy.special.iv, scipy.special.ive
+
+    Notes
+    -----
+    We use the algorithm published by Clenshaw [1]_ and referenced by
+    Abramowitz and Stegun [2]_, for which the function domain is
+    partitioned into the two intervals [0,8] and (8,inf), and Chebyshev
+    polynomial expansions are employed in each interval. Relative error on
+    the domain [0,30] using IEEE arithmetic is documented [3]_ as having a
+    peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000).
+
+    References
+    ----------
+    .. [1] C. W. Clenshaw, "Chebyshev series for mathematical functions", in
+           *National Physical Laboratory Mathematical Tables*, vol. 5, London:
+           Her Majesty's Stationery Office, 1962.
+    .. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical
+           Functions*, 10th printing, New York: Dover, 1964, pp. 379.
+           http://www.math.sfu.ca/~cbm/aands/page_379.htm
+    .. [3] http://kobesearch.cpan.org/htdocs/Math-Cephes/Math/Cephes.html
+
+    Examples
+    --------
+    >>> np.i0([0.])
+    array(1.0)
+    >>> np.i0([0., 1. + 2j])
+    array([ 1.00000000+0.j        ,  0.18785373+0.64616944j])
+
+    """
+    x = atleast_1d(x).copy()
+    y = empty_like(x)
+    ind = (x < 0)
+    x[ind] = -x[ind]
+    ind = (x <= 8.0)
+    y[ind] = _i0_1(x[ind])
+    ind2 = ~ind
+    y[ind2] = _i0_2(x[ind2])
+    return y.squeeze()
+
+## End of cephes code for i0
+
+
+def kaiser(M, beta):
+    """
+    Return the Kaiser window.
+
+    The Kaiser window is a taper formed by using a Bessel function.
+
+    Parameters
+    ----------
+    M : int
+        Number of points in the output window. If zero or less, an
+        empty array is returned.
+    beta : float
+        Shape parameter for window.
+
+    Returns
+    -------
+    out : array
+        The window, with the maximum value normalized to one (the value
+        one appears only if the number of samples is odd).
+
+    See Also
+    --------
+    bartlett, blackman, hamming, hanning
+
+    Notes
+    -----
+    The Kaiser window is defined as
+
+    .. math::  w(n) = I_0\\left( \\beta \\sqrt{1-\\frac{4n^2}{(M-1)^2}}
+               \\right)/I_0(\\beta)
+
+    with
+
+    .. math:: \\quad -\\frac{M-1}{2} \\leq n \\leq \\frac{M-1}{2},
+
+    where :math:`I_0` is the modified zeroth-order Bessel function.
+
+    The Kaiser was named for Jim Kaiser, who discovered a simple
+    approximation to the DPSS window based on Bessel functions.  The Kaiser
+    window is a very good approximation to the Digital Prolate Spheroidal
+    Sequence, or Slepian window, which is the transform which maximizes the
+    energy in the main lobe of the window relative to total energy.
+
+    The Kaiser can approximate many other windows by varying the beta
+    parameter.
+
+    ====  =======================
+    beta  Window shape
+    ====  =======================
+    0     Rectangular
+    5     Similar to a Hamming
+    6     Similar to a Hanning
+    8.6   Similar to a Blackman
+    ====  =======================
+
+    A beta value of 14 is probably a good starting point. Note that as beta
+    gets large, the window narrows, and so the number of samples needs to be
+    large enough to sample the increasingly narrow spike, otherwise NaNs will
+    get returned.
+
+    Most references to the Kaiser window come from the signal processing
+    literature, where it is used as one of many windowing functions for
+    smoothing values.  It is also known as an apodization (which means
+    "removing the foot", i.e. smoothing discontinuities at the beginning
+    and end of the sampled signal) or tapering function.
+
+    References
+    ----------
+    .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by
+           digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285.
+           John Wiley and Sons, New York, (1966).
+    .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
+           University of Alberta Press, 1975, pp. 177-178.
+    .. [3] Wikipedia, "Window function",
+           http://en.wikipedia.org/wiki/Window_function
+
+    Examples
+    --------
+    >>> np.kaiser(12, 14)
+    array([  7.72686684e-06,   3.46009194e-03,   4.65200189e-02,
+             2.29737120e-01,   5.99885316e-01,   9.45674898e-01,
+             9.45674898e-01,   5.99885316e-01,   2.29737120e-01,
+             4.65200189e-02,   3.46009194e-03,   7.72686684e-06])
+
+
+    Plot the window and the frequency response:
+
+    >>> from numpy.fft import fft, fftshift
+    >>> window = np.kaiser(51, 14)
+    >>> plt.plot(window)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Kaiser window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Sample")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    >>> plt.figure()
+    <matplotlib.figure.Figure object at 0x...>
+    >>> A = fft(window, 2048) / 25.5
+    >>> mag = np.abs(fftshift(A))
+    >>> freq = np.linspace(-0.5, 0.5, len(A))
+    >>> response = 20 * np.log10(mag)
+    >>> response = np.clip(response, -100, 100)
+    >>> plt.plot(freq, response)
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Frequency response of Kaiser window")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Magnitude [dB]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("Normalized frequency [cycles per sample]")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.axis('tight')
+    (-0.5, 0.5, -100.0, ...)
+    >>> plt.show()
+
+    """
+    from numpy.dual import i0
+    if M == 1:
+        return np.array([1.])
+    n = arange(0, M)
+    alpha = (M-1)/2.0
+    return i0(beta * sqrt(1-((n-alpha)/alpha)**2.0))/i0(float(beta))
+
+
+def sinc(x):
+    """
+    Return the sinc function.
+
+    The sinc function is :math:`\\sin(\\pi x)/(\\pi x)`.
+
+    Parameters
+    ----------
+    x : ndarray
+        Array (possibly multi-dimensional) of values for which to to
+        calculate ``sinc(x)``.
+
+    Returns
+    -------
+    out : ndarray
+        ``sinc(x)``, which has the same shape as the input.
+
+    Notes
+    -----
+    ``sinc(0)`` is the limit value 1.
+
+    The name sinc is short for "sine cardinal" or "sinus cardinalis".
+
+    The sinc function is used in various signal processing applications,
+    including in anti-aliasing, in the construction of a Lanczos resampling
+    filter, and in interpolation.
+
+    For bandlimited interpolation of discrete-time signals, the ideal
+    interpolation kernel is proportional to the sinc function.
+
+    References
+    ----------
+    .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
+           Resource. http://mathworld.wolfram.com/SincFunction.html
+    .. [2] Wikipedia, "Sinc function",
+           http://en.wikipedia.org/wiki/Sinc_function
+
+    Examples
+    --------
+    >>> x = np.linspace(-4, 4, 41)
+    >>> np.sinc(x)
+    array([ -3.89804309e-17,  -4.92362781e-02,  -8.40918587e-02,
+            -8.90384387e-02,  -5.84680802e-02,   3.89804309e-17,
+             6.68206631e-02,   1.16434881e-01,   1.26137788e-01,
+             8.50444803e-02,  -3.89804309e-17,  -1.03943254e-01,
+            -1.89206682e-01,  -2.16236208e-01,  -1.55914881e-01,
+             3.89804309e-17,   2.33872321e-01,   5.04551152e-01,
+             7.56826729e-01,   9.35489284e-01,   1.00000000e+00,
+             9.35489284e-01,   7.56826729e-01,   5.04551152e-01,
+             2.33872321e-01,   3.89804309e-17,  -1.55914881e-01,
+            -2.16236208e-01,  -1.89206682e-01,  -1.03943254e-01,
+            -3.89804309e-17,   8.50444803e-02,   1.26137788e-01,
+             1.16434881e-01,   6.68206631e-02,   3.89804309e-17,
+            -5.84680802e-02,  -8.90384387e-02,  -8.40918587e-02,
+            -4.92362781e-02,  -3.89804309e-17])
+
+    >>> plt.plot(x, np.sinc(x))
+    [<matplotlib.lines.Line2D object at 0x...>]
+    >>> plt.title("Sinc Function")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.ylabel("Amplitude")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.xlabel("X")
+    <matplotlib.text.Text object at 0x...>
+    >>> plt.show()
+
+    It works in 2-D as well:
+
+    >>> x = np.linspace(-4, 4, 401)
+    >>> xx = np.outer(x, x)
+    >>> plt.imshow(np.sinc(xx))
+    <matplotlib.image.AxesImage object at 0x...>
+
+    """
+    x = np.asanyarray(x)
+    y = pi * where(x == 0, 1.0e-20, x)
+    return sin(y)/y
+
+
+def msort(a):
+    """
+    Return a copy of an array sorted along the first axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Array to be sorted.
+
+    Returns
+    -------
+    sorted_array : ndarray
+        Array of the same type and shape as `a`.
+
+    See Also
+    --------
+    sort
+
+    Notes
+    -----
+    ``np.msort(a)`` is equivalent to  ``np.sort(a, axis=0)``.
+
+    """
+    b = array(a, subok=True, copy=True)
+    b.sort(0)
+    return b
+
+
+def _ureduce(a, func, **kwargs):
+    """
+    Internal Function.
+    Call `func` with `a` as first argument swapping the axes to use extended
+    axis on functions that don't support it natively.
+
+    Returns result and a.shape with axis dims set to 1.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    func : callable
+        Reduction function Kapable of receiving an axis argument.
+        It is is called with `a` as first argument followed by `kwargs`.
+     kwargs : keyword arguments
+        additional keyword arguments to pass to `func`.
+
+    Returns
+    -------
+    result : tuple
+        Result of func(a, **kwargs) and a.shape with axis dims set to 1
+        which can be used to reshape the result to the same shape a ufunc with
+        keepdims=True would produce.
+
+    """
+    a = np.asanyarray(a)
+    axis = kwargs.get('axis', None)
+    if axis is not None:
+        keepdim = list(a.shape)
+        nd = a.ndim
+        try:
+            axis = operator.index(axis)
+            if axis >= nd or axis < -nd:
+                raise IndexError("axis %d out of bounds (%d)" % (axis, a.ndim))
+            keepdim[axis] = 1
+        except TypeError:
+            sax = set()
+            for x in axis:
+                if x >= nd or x < -nd:
+                    raise IndexError("axis %d out of bounds (%d)" % (x, nd))
+                if x in sax:
+                    raise ValueError("duplicate value in axis")
+                sax.add(x % nd)
+                keepdim[x] = 1
+            keep = sax.symmetric_difference(frozenset(range(nd)))
+            nkeep = len(keep)
+            # swap axis that should not be reduced to front
+            for i, s in enumerate(sorted(keep)):
+                a = a.swapaxes(i, s)
+            # merge reduced axis
+            a = a.reshape(a.shape[:nkeep] + (-1,))
+            kwargs['axis'] = -1
+    else:
+        keepdim = [1] * a.ndim
+
+    r = func(a, **kwargs)
+    return r, keepdim
+
+
+def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
+    """
+    Compute the median along the specified axis.
+
+    Returns the median of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the medians are computed. The default
+        is to compute the median along a flattened version of the array.
+        A sequence of axes is supported since version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+       If True, then allow use of memory of input array `a` for
+       calculations. The input array will be modified by the call to
+       `median`. This will save memory when you do not need to preserve
+       the contents of the input array. Treat the input as undefined,
+       but it will probably be fully or partially sorted. Default is
+       False. If `overwrite_input` is ``True`` and `a` is not already an
+       `ndarray`, an error will be raised.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result. If the input contains integers
+        or floats smaller than ``float64``, then the output data-type is
+        ``np.float64``.  Otherwise, the data-type of the output is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, percentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the median of ``V`` is the
+    middle value of a sorted copy of ``V``, ``V_sorted`` - i
+    e., ``V_sorted[(N-1)/2]``, when ``N`` is odd, and the average of the
+    two middle values of ``V_sorted`` when ``N`` is even.
+
+    Examples
+    --------
+    >>> a = np.array([[10, 7, 4], [3, 2, 1]])
+    >>> a
+    array([[10,  7,  4],
+           [ 3,  2,  1]])
+    >>> np.median(a)
+    3.5
+    >>> np.median(a, axis=0)
+    array([ 6.5,  4.5,  2.5])
+    >>> np.median(a, axis=1)
+    array([ 7.,  2.])
+    >>> m = np.median(a, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.median(a, axis=0, out=m)
+    array([ 6.5,  4.5,  2.5])
+    >>> m
+    array([ 6.5,  4.5,  2.5])
+    >>> b = a.copy()
+    >>> np.median(b, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a==b)
+    >>> b = a.copy()
+    >>> np.median(b, axis=None, overwrite_input=True)
+    3.5
+    >>> assert not np.all(a==b)
+
+    """
+    r, k = _ureduce(a, func=_median, axis=axis, out=out,
+                    overwrite_input=overwrite_input)
+    if keepdims:
+        return r.reshape(k)
+    else:
+        return r
+
+def _median(a, axis=None, out=None, overwrite_input=False):
+    # can't be reasonably be implemented in terms of percentile as we have to
+    # call mean to not break astropy
+    a = np.asanyarray(a)
+
+    # Set the partition indexes
+    if axis is None:
+        sz = a.size
+    else:
+        sz = a.shape[axis]
+    if sz % 2 == 0:
+        szh = sz // 2
+        kth = [szh - 1, szh]
+    else:
+        kth = [(sz - 1) // 2]
+    # Check if the array contains any nan's
+    if np.issubdtype(a.dtype, np.inexact):
+        kth.append(-1)
+
+    if overwrite_input:
+        if axis is None:
+            part = a.ravel()
+            part.partition(kth)
+        else:
+            a.partition(kth, axis=axis)
+            part = a
+    else:
+        part = partition(a, kth, axis=axis)
+
+    if part.shape == ():
+        # make 0-D arrays work
+        return part.item()
+    if axis is None:
+        axis = 0
+
+    indexer = [slice(None)] * part.ndim
+    index = part.shape[axis] // 2
+    if part.shape[axis] % 2 == 1:
+        # index with slice to allow mean (below) to work
+        indexer[axis] = slice(index, index+1)
+    else:
+        indexer[axis] = slice(index-1, index+1)
+
+    # Check if the array contains any nan's
+    if np.issubdtype(a.dtype, np.inexact) and sz > 0:
+        # warn and return nans like mean would
+        rout = mean(part[indexer], axis=axis, out=out)
+        part = np.rollaxis(part, axis, part.ndim)
+        n = np.isnan(part[..., -1])
+        if rout.ndim == 0:
+            if n == True:
+                warnings.warn("Invalid value encountered in median",
+                              RuntimeWarning)
+                if out is not None:
+                    out[...] = a.dtype.type(np.nan)
+                    rout = out
+                else:
+                    rout = a.dtype.type(np.nan)
+        elif np.count_nonzero(n.ravel()) > 0:
+            warnings.warn("Invalid value encountered in median for" +
+                          " %d results" % np.count_nonzero(n.ravel()),
+                          RuntimeWarning)
+            rout[n] = np.nan
+        return rout
+    else:
+        # if there are no nans
+        # Use mean in odd and even case to coerce data type
+        # and check, use out array.
+        return mean(part[indexer], axis=axis, out=out)
+
+
+def percentile(a, q, axis=None, out=None,
+               overwrite_input=False, interpolation='linear', keepdims=False):
+    """
+    Compute the qth percentile of the data along the specified axis.
+
+    Returns the qth percentile(s) of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    q : float in range of [0,100] (or sequence of floats)
+        Percentile to compute, which must be between 0 and 100 inclusive.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the percentiles are computed. The
+        default is to compute the percentile(s) along a flattened
+        version of the array. A sequence of axes is supported since
+        version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array `a` 
+        calculations. The input array will be modified by the call to
+        `percentile`. This will save memory when you do not need to
+        preserve the contents of the input array. In this case you
+        should not make any assumptions about the contents of the input
+        `a` after this function completes -- treat it as undefined.
+        Default is False. If `a` is not already an array, this parameter
+        will have no effect as `a` will be converted to an array
+        internally regardless of the value of this parameter.
+    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``.
+
+        .. versionadded:: 1.9.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original array `a`.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    percentile : scalar or ndarray
+        If `q` is a single percentile and `axis=None`, then the result
+        is a scalar. If multiple percentiles are given, first axis of
+        the result corresponds to the percentiles. The other axes are
+        the axes that remain after the reduction of `a`. If the input 
+        contains integers or floats smaller than ``float64``, the output
+        data-type is ``float64``. Otherwise, the output data-type is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, median, nanpercentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the ``q``-th percentile of
+    ``V`` is the value ``q/100`` of the way from the mimumum to the
+    maximum in in a sorted copy of ``V``. The values and distances of
+    the two nearest neighbors as well as the `interpolation` parameter
+    will determine the percentile if the normalized ranking does not
+    match the location of ``q`` exactly. This function is the same as
+    the median if ``q=50``, the same as the minimum if ``q=0`` and the
+    same as the maximum if ``q=100``.
+
+    Examples
+    --------
+    >>> a = np.array([[10, 7, 4], [3, 2, 1]])
+    >>> a
+    array([[10,  7,  4],
+           [ 3,  2,  1]])
+    >>> np.percentile(a, 50)
+    3.5
+    >>> np.percentile(a, 50, axis=0)
+    array([[ 6.5,  4.5,  2.5]])
+    >>> np.percentile(a, 50, axis=1)
+    array([ 7.,  2.])
+    >>> np.percentile(a, 50, axis=1, keepdims=True)
+    array([[ 7.],
+           [ 2.]])
+
+    >>> m = np.percentile(a, 50, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.percentile(a, 50, axis=0, out=out)
+    array([[ 6.5,  4.5,  2.5]])
+    >>> m
+    array([[ 6.5,  4.5,  2.5]])
+
+    >>> b = a.copy()
+    >>> np.percentile(b, 50, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a == b)
+
+    """
+    q = array(q, dtype=np.float64, copy=True)
+    r, k = _ureduce(a, func=_percentile, q=q, axis=axis, out=out,
+                    overwrite_input=overwrite_input,
+                    interpolation=interpolation)
+    if keepdims:
+        if q.ndim == 0:
+            return r.reshape(k)
+        else:
+            return r.reshape([len(q)] + k)
+    else:
+        return r
+
+
+def _percentile(a, q, axis=None, out=None,
+                overwrite_input=False, interpolation='linear', keepdims=False):
+    a = asarray(a)
+    if q.ndim == 0:
+        # Do not allow 0-d arrays because following code fails for scalar
+        zerod = True
+        q = q[None]
+    else:
+        zerod = False
+
+    # avoid expensive reductions, relevant for arrays with < O(1000) elements
+    if q.size < 10:
+        for i in range(q.size):
+            if q[i] < 0. or q[i] > 100.:
+                raise ValueError("Percentiles must be in the range [0,100]")
+            q[i] /= 100.
+    else:
+        # faster than any()
+        if np.count_nonzero(q < 0.) or np.count_nonzero(q > 100.):
+            raise ValueError("Percentiles must be in the range [0,100]")
+        q /= 100.
+
+    # prepare a for partioning
+    if overwrite_input:
+        if axis is None:
+            ap = a.ravel()
+        else:
+            ap = a
+    else:
+        if axis is None:
+            ap = a.flatten()
+        else:
+            ap = a.copy()
+
+    if axis is None:
+        axis = 0
+
+    Nx = ap.shape[axis]
+    indices = q * (Nx - 1)
+
+    # round fractional indices according to interpolation method
+    if interpolation == 'lower':
+        indices = floor(indices).astype(intp)
+    elif interpolation == 'higher':
+        indices = ceil(indices).astype(intp)
+    elif interpolation == 'midpoint':
+        indices = 0.5 * (floor(indices) + ceil(indices))
+    elif interpolation == 'nearest':
+        indices = around(indices).astype(intp)
+    elif interpolation == 'linear':
+        pass  # keep index as fraction and interpolate
+    else:
+        raise ValueError(
+            "interpolation can only be 'linear', 'lower' 'higher', "
+            "'midpoint', or 'nearest'")
+
+    n = np.array(False, dtype=bool) # check for nan's flag
+    if indices.dtype == intp:  # take the points along axis
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices = concatenate((indices, [-1]))
+
+        ap.partition(indices, axis=axis)
+        # ensure axis with qth is first
+        ap = np.rollaxis(ap, axis, 0)
+        axis = 0
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices = indices[:-1]
+            n = np.isnan(ap[-1:, ...])
+
+        if zerod:
+            indices = indices[0]
+        r = take(ap, indices, axis=axis, out=out)
+
+
+    else:  # weight the points above and below the indices
+        indices_below = floor(indices).astype(intp)
+        indices_above = indices_below + 1
+        indices_above[indices_above > Nx - 1] = Nx - 1
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices_above = concatenate((indices_above, [-1]))
+
+        weights_above = indices - indices_below
+        weights_below = 1.0 - weights_above
+
+        weights_shape = [1, ] * ap.ndim
+        weights_shape[axis] = len(indices)
+        weights_below.shape = weights_shape
+        weights_above.shape = weights_shape
+
+        ap.partition(concatenate((indices_below, indices_above)), axis=axis)
+
+        # ensure axis with qth is first
+        ap = np.rollaxis(ap, axis, 0)
+        weights_below = np.rollaxis(weights_below, axis, 0)
+        weights_above = np.rollaxis(weights_above, axis, 0)
+        axis = 0
+
+        # Check if the array contains any nan's
+        if np.issubdtype(a.dtype, np.inexact):
+            indices_above = indices_above[:-1]
+            n = np.isnan(ap[-1:, ...])
+
+        x1 = take(ap, indices_below, axis=axis) * weights_below
+        x2 = take(ap, indices_above, axis=axis) * weights_above
+
+        # ensure axis with qth is first
+        x1 = np.rollaxis(x1, axis, 0)
+        x2 = np.rollaxis(x2, axis, 0)
+
+        if zerod:
+            x1 = x1.squeeze(0)
+            x2 = x2.squeeze(0)
+
+        if out is not None:
+            r = add(x1, x2, out=out)
+        else:
+            r = add(x1, x2)
+
+    if np.any(n):
+        warnings.warn("Invalid value encountered in percentile",
+                              RuntimeWarning)
+        if zerod:
+            if ap.ndim == 1:
+                if out is not None:
+                    out[...] = a.dtype.type(np.nan)
+                    r = out
+                else:
+                    r = a.dtype.type(np.nan)
+            else:
+                r[..., n.squeeze(0)] = a.dtype.type(np.nan)
+        else:
+            if r.ndim == 1:
+                r[:] = a.dtype.type(np.nan)
+            else:
+                r[..., n.repeat(q.size, 0)] = a.dtype.type(np.nan)
+
+    return r
+
+
+def trapz(y, x=None, dx=1.0, axis=-1):
+    """
+    Integrate along the given axis using the composite trapezoidal rule.
+
+    Integrate `y` (`x`) along given axis.
+
+    Parameters
+    ----------
+    y : array_like
+        Input array to integrate.
+    x : array_like, optional
+        The sample points corresponding to the `y` values. If `x` is None,
+        the sample points are assumed to be evenly spaced `dx` apart. The
+        default is None.
+    dx : scalar, optional
+        The spacing between sample points when `x` is None. The default is 1.
+    axis : int, optional
+        The axis along which to integrate.
+
+    Returns
+    -------
+    trapz : float
+        Definite integral as approximated by trapezoidal rule.
+
+    See Also
+    --------
+    sum, cumsum
+
+    Notes
+    -----
+    Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
+    will be taken from `y` array, by default x-axis distances between
+    points will be 1.0, alternatively they can be provided with `x` array
+    or with `dx` scalar.  Return value will be equal to combined area under
+    the red lines.
+
+
+    References
+    ----------
+    .. [1] Wikipedia page: http://en.wikipedia.org/wiki/Trapezoidal_rule
+
+    .. [2] Illustration image:
+           http://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
+
+    Examples
+    --------
+    >>> np.trapz([1,2,3])
+    4.0
+    >>> np.trapz([1,2,3], x=[4,6,8])
+    8.0
+    >>> np.trapz([1,2,3], dx=2)
+    8.0
+    >>> a = np.arange(6).reshape(2, 3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5]])
+    >>> np.trapz(a, axis=0)
+    array([ 1.5,  2.5,  3.5])
+    >>> np.trapz(a, axis=1)
+    array([ 2.,  8.])
+
+    """
+    y = asanyarray(y)
+    if x is None:
+        d = dx
+    else:
+        x = asanyarray(x)
+        if x.ndim == 1:
+            d = diff(x)
+            # reshape to correct shape
+            shape = [1]*y.ndim
+            shape[axis] = d.shape[0]
+            d = d.reshape(shape)
+        else:
+            d = diff(x, axis=axis)
+    nd = len(y.shape)
+    slice1 = [slice(None)]*nd
+    slice2 = [slice(None)]*nd
+    slice1[axis] = slice(1, None)
+    slice2[axis] = slice(None, -1)
+    try:
+        ret = (d * (y[slice1] + y[slice2]) / 2.0).sum(axis)
+    except ValueError:
+        # Operations didn't work, cast to ndarray
+        d = np.asarray(d)
+        y = np.asarray(y)
+        ret = add.reduce(d * (y[slice1]+y[slice2])/2.0, axis)
+    return ret
+
+
+#always succeed
+def add_newdoc(place, obj, doc):
+    """
+    Adds documentation to obj which is in module place.
+
+    If doc is a string add it to obj as a docstring
+
+    If doc is a tuple, then the first element is interpreted as
+       an attribute of obj and the second as the docstring
+          (method, docstring)
+
+    If doc is a list, then each element of the list should be a
+       sequence of length two --> [(method1, docstring1),
+       (method2, docstring2), ...]
+
+    This routine never raises an error.
+
+    This routine cannot modify read-only docstrings, as appear
+    in new-style classes or built-in functions. Because this
+    routine never raises an error the caller must check manually
+    that the docstrings were changed.
+    """
+    try:
+        new = getattr(__import__(place, globals(), {}, [obj]), obj)
+        if isinstance(doc, str):
+            add_docstring(new, doc.strip())
+        elif isinstance(doc, tuple):
+            add_docstring(getattr(new, doc[0]), doc[1].strip())
+        elif isinstance(doc, list):
+            for val in doc:
+                add_docstring(getattr(new, val[0]), val[1].strip())
+    except:
+        pass
+
+
+# Based on scitools meshgrid
+def meshgrid(*xi, **kwargs):
+    """
+    Return coordinate matrices from coordinate vectors.
+
+    Make N-D coordinate arrays for vectorized evaluations of
+    N-D scalar/vector fields over N-D grids, given
+    one-dimensional coordinate arrays x1, x2,..., xn.
+
+    .. versionchanged:: 1.9
+       1-D and 0-D cases are allowed.
+
+    Parameters
+    ----------
+    x1, x2,..., xn : array_like
+        1-D arrays representing the coordinates of a grid.
+    indexing : {'xy', 'ij'}, optional
+        Cartesian ('xy', default) or matrix ('ij') indexing of output.
+        See Notes for more details.
+
+        .. versionadded:: 1.7.0
+    sparse : bool, optional
+        If True a sparse grid is returned in order to conserve memory.
+        Default is False.
+
+        .. versionadded:: 1.7.0
+    copy : bool, optional
+        If False, a view into the original arrays are returned in order to
+        conserve memory.  Default is True.  Please note that
+        ``sparse=False, copy=False`` will likely return non-contiguous
+        arrays.  Furthermore, more than one element of a broadcast array
+        may refer to a single memory location.  If you need to write to the
+        arrays, make copies first.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    X1, X2,..., XN : ndarray
+        For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` ,
+        return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij'
+        or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy'
+        with the elements of `xi` repeated to fill the matrix along
+        the first dimension for `x1`, the second for `x2` and so on.
+
+    Notes
+    -----
+    This function supports both indexing conventions through the indexing
+    keyword argument.  Giving the string 'ij' returns a meshgrid with
+    matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
+    In the 2-D case with inputs of length M and N, the outputs are of shape
+    (N, M) for 'xy' indexing and (M, N) for 'ij' indexing.  In the 3-D case
+    with inputs of length M, N and P, outputs are of shape (N, M, P) for
+    'xy' indexing and (M, N, P) for 'ij' indexing.  The difference is
+    illustrated by the following code snippet::
+
+        xv, yv = meshgrid(x, y, sparse=False, indexing='ij')
+        for i in range(nx):
+            for j in range(ny):
+                # treat xv[i,j], yv[i,j]
+
+        xv, yv = meshgrid(x, y, sparse=False, indexing='xy')
+        for i in range(nx):
+            for j in range(ny):
+                # treat xv[j,i], yv[j,i]
+
+    In the 1-D and 0-D case, the indexing and sparse keywords have no effect.
+
+    See Also
+    --------
+    index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
+                     using indexing notation.
+    index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
+                     using indexing notation.
+
+    Examples
+    --------
+    >>> nx, ny = (3, 2)
+    >>> x = np.linspace(0, 1, nx)
+    >>> y = np.linspace(0, 1, ny)
+    >>> xv, yv = meshgrid(x, y)
+    >>> xv
+    array([[ 0. ,  0.5,  1. ],
+           [ 0. ,  0.5,  1. ]])
+    >>> yv
+    array([[ 0.,  0.,  0.],
+           [ 1.,  1.,  1.]])
+    >>> xv, yv = meshgrid(x, y, sparse=True)  # make sparse output arrays
+    >>> xv
+    array([[ 0. ,  0.5,  1. ]])
+    >>> yv
+    array([[ 0.],
+           [ 1.]])
+
+    `meshgrid` is very useful to evaluate functions on a grid.
+
+    >>> x = np.arange(-5, 5, 0.1)
+    >>> y = np.arange(-5, 5, 0.1)
+    >>> xx, yy = meshgrid(x, y, sparse=True)
+    >>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
+    >>> h = plt.contourf(x,y,z)
+
+    """
+    ndim = len(xi)
+
+    copy_ = kwargs.pop('copy', True)
+    sparse = kwargs.pop('sparse', False)
+    indexing = kwargs.pop('indexing', 'xy')
+
+    if kwargs:
+        raise TypeError("meshgrid() got an unexpected keyword argument '%s'"
+                        % (list(kwargs)[0],))
+
+    if indexing not in ['xy', 'ij']:
+        raise ValueError(
+            "Valid values for `indexing` are 'xy' and 'ij'.")
+
+    s0 = (1,) * ndim
+    output = [np.asanyarray(x).reshape(s0[:i] + (-1,) + s0[i + 1::])
+              for i, x in enumerate(xi)]
+
+    shape = [x.size for x in output]
+
+    if indexing == 'xy' and ndim > 1:
+        # switch first and second axis
+        output[0].shape = (1, -1) + (1,)*(ndim - 2)
+        output[1].shape = (-1, 1) + (1,)*(ndim - 2)
+        shape[0], shape[1] = shape[1], shape[0]
+
+    if sparse:
+        if copy_:
+            return [x.copy() for x in output]
+        else:
+            return output
+    else:
+        # Return the full N-D matrix (not only the 1-D vector)
+        if copy_:
+            mult_fact = np.ones(shape, dtype=int)
+            return [x * mult_fact for x in output]
+        else:
+            return np.broadcast_arrays(*output)
+
+
+def delete(arr, obj, axis=None):
+    """
+    Return a new array with sub-arrays along an axis deleted. For a one
+    dimensional array, this returns those entries not returned by
+    `arr[obj]`.
+
+    Parameters
+    ----------
+    arr : array_like
+      Input array.
+    obj : slice, int or array of ints
+      Indicate which sub-arrays to remove.
+    axis : int, optional
+      The axis along which to delete the subarray defined by `obj`.
+      If `axis` is None, `obj` is applied to the flattened array.
+
+    Returns
+    -------
+    out : ndarray
+        A copy of `arr` with the elements specified by `obj` removed. Note
+        that `delete` does not occur in-place. If `axis` is None, `out` is
+        a flattened array.
+
+    See Also
+    --------
+    insert : Insert elements into an array.
+    append : Append elements at the end of an array.
+
+    Notes
+    -----
+    Often it is preferable to use a boolean mask. For example:
+
+    >>> mask = np.ones(len(arr), dtype=bool)
+    >>> mask[[0,2,4]] = False
+    >>> result = arr[mask,...]
+
+    Is equivalent to `np.delete(arr, [0,2,4], axis=0)`, but allows further
+    use of `mask`.
+
+    Examples
+    --------
+    >>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
+    >>> arr
+    array([[ 1,  2,  3,  4],
+           [ 5,  6,  7,  8],
+           [ 9, 10, 11, 12]])
+    >>> np.delete(arr, 1, 0)
+    array([[ 1,  2,  3,  4],
+           [ 9, 10, 11, 12]])
+
+    >>> np.delete(arr, np.s_[::2], 1)
+    array([[ 2,  4],
+           [ 6,  8],
+           [10, 12]])
+    >>> np.delete(arr, [1,3,5], None)
+    array([ 1,  3,  5,  7,  8,  9, 10, 11, 12])
+
+    """
+    wrap = None
+    if type(arr) is not ndarray:
+        try:
+            wrap = arr.__array_wrap__
+        except AttributeError:
+            pass
+
+    arr = asarray(arr)
+    ndim = arr.ndim
+    arrorder = 'F' if arr.flags.fnc else 'C'
+    if axis is None:
+        if ndim != 1:
+            arr = arr.ravel()
+        ndim = arr.ndim
+        axis = ndim - 1
+    if ndim == 0:
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "in the future the special handling of scalars will be removed "
+            "from delete and raise an error", DeprecationWarning)
+        if wrap:
+            return wrap(arr)
+        else:
+            return arr.copy()
+
+    slobj = [slice(None)]*ndim
+    N = arr.shape[axis]
+    newshape = list(arr.shape)
+
+    if isinstance(obj, slice):
+        start, stop, step = obj.indices(N)
+        xr = range(start, stop, step)
+        numtodel = len(xr)
+
+        if numtodel <= 0:
+            if wrap:
+                return wrap(arr.copy())
+            else:
+                return arr.copy()
+
+        # Invert if step is negative:
+        if step < 0:
+            step = -step
+            start = xr[-1]
+            stop = xr[0] + 1
+
+        newshape[axis] -= numtodel
+        new = empty(newshape, arr.dtype, arrorder)
+        # copy initial chunk
+        if start == 0:
+            pass
+        else:
+            slobj[axis] = slice(None, start)
+            new[slobj] = arr[slobj]
+        # copy end chunck
+        if stop == N:
+            pass
+        else:
+            slobj[axis] = slice(stop-numtodel, None)
+            slobj2 = [slice(None)]*ndim
+            slobj2[axis] = slice(stop, None)
+            new[slobj] = arr[slobj2]
+        # copy middle pieces
+        if step == 1:
+            pass
+        else:  # use array indexing.
+            keep = ones(stop-start, dtype=bool)
+            keep[:stop-start:step] = False
+            slobj[axis] = slice(start, stop-numtodel)
+            slobj2 = [slice(None)]*ndim
+            slobj2[axis] = slice(start, stop)
+            arr = arr[slobj2]
+            slobj2[axis] = keep
+            new[slobj] = arr[slobj2]
+        if wrap:
+            return wrap(new)
+        else:
+            return new
+
+    _obj = obj
+    obj = np.asarray(obj)
+    # After removing the special handling of booleans and out of
+    # bounds values, the conversion to the array can be removed.
+    if obj.dtype == bool:
+        warnings.warn(
+            "in the future insert will treat boolean arrays and array-likes "
+            "as boolean index instead of casting it to integer", FutureWarning)
+        obj = obj.astype(intp)
+    if isinstance(_obj, (int, long, integer)):
+        # optimization for a single value
+        obj = obj.item()
+        if (obj < -N or obj >= N):
+            raise IndexError(
+                "index %i is out of bounds for axis %i with "
+                "size %i" % (obj, axis, N))
+        if (obj < 0):
+            obj += N
+        newshape[axis] -= 1
+        new = empty(newshape, arr.dtype, arrorder)
+        slobj[axis] = slice(None, obj)
+        new[slobj] = arr[slobj]
+        slobj[axis] = slice(obj, None)
+        slobj2 = [slice(None)]*ndim
+        slobj2[axis] = slice(obj+1, None)
+        new[slobj] = arr[slobj2]
+    else:
+        if obj.size == 0 and not isinstance(_obj, np.ndarray):
+            obj = obj.astype(intp)
+        if not np.can_cast(obj, intp, 'same_kind'):
+            # obj.size = 1 special case always failed and would just
+            # give superfluous warnings.
+            # 2013-09-24, 1.9
+            warnings.warn(
+                "using a non-integer array as obj in delete will result in an "
+                "error in the future", DeprecationWarning)
+            obj = obj.astype(intp)
+        keep = ones(N, dtype=bool)
+
+        # Test if there are out of bound indices, this is deprecated
+        inside_bounds = (obj < N) & (obj >= -N)
+        if not inside_bounds.all():
+            # 2013-09-24, 1.9
+            warnings.warn(
+                "in the future out of bounds indices will raise an error "
+                "instead of being ignored by `numpy.delete`.",
+                DeprecationWarning)
+            obj = obj[inside_bounds]
+        positive_indices = obj >= 0
+        if not positive_indices.all():
+            warnings.warn(
+                "in the future negative indices will not be ignored by "
+                "`numpy.delete`.", FutureWarning)
+            obj = obj[positive_indices]
+
+        keep[obj, ] = False
+        slobj[axis] = keep
+        new = arr[slobj]
+
+    if wrap:
+        return wrap(new)
+    else:
+        return new
+
+
+def insert(arr, obj, values, axis=None):
+    """
+    Insert values along the given axis before the given indices.
+
+    Parameters
+    ----------
+    arr : array_like
+        Input array.
+    obj : int, slice or sequence of ints
+        Object that defines the index or indices before which `values` is
+        inserted.
+
+        .. versionadded:: 1.8.0
+
+        Support for multiple insertions when `obj` is a single scalar or a
+        sequence with one element (similar to calling insert multiple
+        times).
+    values : array_like
+        Values to insert into `arr`. If the type of `values` is different
+        from that of `arr`, `values` is converted to the type of `arr`.
+        `values` should be shaped so that ``arr[...,obj,...] = values``
+        is legal.
+    axis : int, optional
+        Axis along which to insert `values`.  If `axis` is None then `arr`
+        is flattened first.
+
+    Returns
+    -------
+    out : ndarray
+        A copy of `arr` with `values` inserted.  Note that `insert`
+        does not occur in-place: a new array is returned. If
+        `axis` is None, `out` is a flattened array.
+
+    See Also
+    --------
+    append : Append elements at the end of an array.
+    concatenate : Join a sequence of arrays along an existing axis.
+    delete : Delete elements from an array.
+
+    Notes
+    -----
+    Note that for higher dimensional inserts `obj=0` behaves very different
+    from `obj=[0]` just like `arr[:,0,:] = values` is different from
+    `arr[:,[0],:] = values`.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 1], [2, 2], [3, 3]])
+    >>> a
+    array([[1, 1],
+           [2, 2],
+           [3, 3]])
+    >>> np.insert(a, 1, 5)
+    array([1, 5, 1, 2, 2, 3, 3])
+    >>> np.insert(a, 1, 5, axis=1)
+    array([[1, 5, 1],
+           [2, 5, 2],
+           [3, 5, 3]])
+
+    Difference between sequence and scalars:
+
+    >>> np.insert(a, [1], [[1],[2],[3]], axis=1)
+    array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])
+    >>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1),
+    ...                np.insert(a, [1], [[1],[2],[3]], axis=1))
+    True
+
+    >>> b = a.flatten()
+    >>> b
+    array([1, 1, 2, 2, 3, 3])
+    >>> np.insert(b, [2, 2], [5, 6])
+    array([1, 1, 5, 6, 2, 2, 3, 3])
+
+    >>> np.insert(b, slice(2, 4), [5, 6])
+    array([1, 1, 5, 2, 6, 2, 3, 3])
+
+    >>> np.insert(b, [2, 2], [7.13, False]) # type casting
+    array([1, 1, 7, 0, 2, 2, 3, 3])
+
+    >>> x = np.arange(8).reshape(2, 4)
+    >>> idx = (1, 3)
+    >>> np.insert(x, idx, 999, axis=1)
+    array([[  0, 999,   1,   2, 999,   3],
+           [  4, 999,   5,   6, 999,   7]])
+
+    """
+    wrap = None
+    if type(arr) is not ndarray:
+        try:
+            wrap = arr.__array_wrap__
+        except AttributeError:
+            pass
+
+    arr = asarray(arr)
+    ndim = arr.ndim
+    arrorder = 'F' if arr.flags.fnc else 'C'
+    if axis is None:
+        if ndim != 1:
+            arr = arr.ravel()
+        ndim = arr.ndim
+        axis = ndim - 1
+    else:
+        if ndim > 0 and (axis < -ndim or axis >= ndim):
+            raise IndexError(
+                "axis %i is out of bounds for an array of "
+                "dimension %i" % (axis, ndim))
+        if (axis < 0):
+            axis += ndim
+    if (ndim == 0):
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "in the future the special handling of scalars will be removed "
+            "from insert and raise an error", DeprecationWarning)
+        arr = arr.copy()
+        arr[...] = values
+        if wrap:
+            return wrap(arr)
+        else:
+            return arr
+    slobj = [slice(None)]*ndim
+    N = arr.shape[axis]
+    newshape = list(arr.shape)
+
+    if isinstance(obj, slice):
+        # turn it into a range object
+        indices = arange(*obj.indices(N), **{'dtype': intp})
+    else:
+        # need to copy obj, because indices will be changed in-place
+        indices = np.array(obj)
+        if indices.dtype == bool:
+            # See also delete
+            warnings.warn(
+                "in the future insert will treat boolean arrays and "
+                "array-likes as a boolean index instead of casting it to "
+                "integer", FutureWarning)
+            indices = indices.astype(intp)
+            # Code after warning period:
+            #if obj.ndim != 1:
+            #    raise ValueError('boolean array argument obj to insert '
+            #                     'must be one dimensional')
+            #indices = np.flatnonzero(obj)
+        elif indices.ndim > 1:
+            raise ValueError(
+                "index array argument obj to insert must be one dimensional "
+                "or scalar")
+    if indices.size == 1:
+        index = indices.item()
+        if index < -N or index > N:
+            raise IndexError(
+                "index %i is out of bounds for axis %i with "
+                "size %i" % (obj, axis, N))
+        if (index < 0):
+            index += N
+
+        # There are some object array corner cases here, but we cannot avoid
+        # that:
+        values = array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype)
+        if indices.ndim == 0:
+            # broadcasting is very different here, since a[:,0,:] = ... behaves
+            # very different from a[:,[0],:] = ...! This changes values so that
+            # it works likes the second case. (here a[:,0:1,:])
+            values = np.rollaxis(values, 0, (axis % values.ndim) + 1)
+        numnew = values.shape[axis]
+        newshape[axis] += numnew
+        new = empty(newshape, arr.dtype, arrorder)
+        slobj[axis] = slice(None, index)
+        new[slobj] = arr[slobj]
+        slobj[axis] = slice(index, index+numnew)
+        new[slobj] = values
+        slobj[axis] = slice(index+numnew, None)
+        slobj2 = [slice(None)] * ndim
+        slobj2[axis] = slice(index, None)
+        new[slobj] = arr[slobj2]
+        if wrap:
+            return wrap(new)
+        return new
+    elif indices.size == 0 and not isinstance(obj, np.ndarray):
+        # Can safely cast the empty list to intp
+        indices = indices.astype(intp)
+
+    if not np.can_cast(indices, intp, 'same_kind'):
+        # 2013-09-24, 1.9
+        warnings.warn(
+            "using a non-integer array as obj in insert will result in an "
+            "error in the future", DeprecationWarning)
+        indices = indices.astype(intp)
+
+    indices[indices < 0] += N
+
+    numnew = len(indices)
+    order = indices.argsort(kind='mergesort')   # stable sort
+    indices[order] += np.arange(numnew)
+
+    newshape[axis] += numnew
+    old_mask = ones(newshape[axis], dtype=bool)
+    old_mask[indices] = False
+
+    new = empty(newshape, arr.dtype, arrorder)
+    slobj2 = [slice(None)]*ndim
+    slobj[axis] = indices
+    slobj2[axis] = old_mask
+    new[slobj] = values
+    new[slobj2] = arr
+
+    if wrap:
+        return wrap(new)
+    return new
+
+
+def append(arr, values, axis=None):
+    """
+    Append values to the end of an array.
+
+    Parameters
+    ----------
+    arr : array_like
+        Values are appended to a copy of this array.
+    values : array_like
+        These values are appended to a copy of `arr`.  It must be of the
+        correct shape (the same shape as `arr`, excluding `axis`).  If
+        `axis` is not specified, `values` can be any shape and will be
+        flattened before use.
+    axis : int, optional
+        The axis along which `values` are appended.  If `axis` is not
+        given, both `arr` and `values` are flattened before use.
+
+    Returns
+    -------
+    append : ndarray
+        A copy of `arr` with `values` appended to `axis`.  Note that
+        `append` does not occur in-place: a new array is allocated and
+        filled.  If `axis` is None, `out` is a flattened array.
+
+    See Also
+    --------
+    insert : Insert elements into an array.
+    delete : Delete elements from an array.
+
+    Examples
+    --------
+    >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
+    array([1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    When `axis` is specified, `values` must have the correct shape.
+
+    >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
+    array([[1, 2, 3],
+           [4, 5, 6],
+           [7, 8, 9]])
+    >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
+    Traceback (most recent call last):
+    ...
+    ValueError: arrays must have same number of dimensions
+
+    """
+    arr = asanyarray(arr)
+    if axis is None:
+        if arr.ndim != 1:
+            arr = arr.ravel()
+        values = ravel(values)
+        axis = arr.ndim-1
+    return concatenate((arr, values), axis=axis)
+
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.py
new file mode 100644
index 0000000000..a0875a25fd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.py
@@ -0,0 +1,874 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import math
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import (
+    asarray, ScalarType, array, alltrue, cumprod, arange
+    )
+from numpy.core.numerictypes import find_common_type, issubdtype
+
+from . import function_base
+import numpy.matrixlib as matrix
+from .function_base import diff
+from numpy.core.multiarray import ravel_multi_index, unravel_index
+from numpy.lib.stride_tricks import as_strided
+
+makemat = matrix.matrix
+
+
+__all__ = [
+    'ravel_multi_index', 'unravel_index', 'mgrid', 'ogrid', 'r_', 'c_',
+    's_', 'index_exp', 'ix_', 'ndenumerate', 'ndindex', 'fill_diagonal',
+    'diag_indices', 'diag_indices_from'
+    ]
+
+
+def ix_(*args):
+    """
+    Construct an open mesh from multiple sequences.
+
+    This function takes N 1-D sequences and returns N outputs with N
+    dimensions each, such that the shape is 1 in all but one dimension
+    and the dimension with the non-unit shape value cycles through all
+    N dimensions.
+
+    Using `ix_` one can quickly construct index arrays that will index
+    the cross product. ``a[np.ix_([1,3],[2,5])]`` returns the array
+    ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``.
+
+    Parameters
+    ----------
+    args : 1-D sequences
+
+    Returns
+    -------
+    out : tuple of ndarrays
+        N arrays with N dimensions each, with N the number of input
+        sequences. Together these arrays form an open mesh.
+
+    See Also
+    --------
+    ogrid, mgrid, meshgrid
+
+    Examples
+    --------
+    >>> a = np.arange(10).reshape(2, 5)
+    >>> a
+    array([[0, 1, 2, 3, 4],
+           [5, 6, 7, 8, 9]])
+    >>> ixgrid = np.ix_([0,1], [2,4])
+    >>> ixgrid
+    (array([[0],
+           [1]]), array([[2, 4]]))
+    >>> ixgrid[0].shape, ixgrid[1].shape
+    ((2, 1), (1, 2))
+    >>> a[ixgrid]
+    array([[2, 4],
+           [7, 9]])
+
+    """
+    out = []
+    nd = len(args)
+    for k, new in enumerate(args):
+        new = asarray(new)
+        if new.ndim != 1:
+            raise ValueError("Cross index must be 1 dimensional")
+        if new.size == 0:
+            # Explicitly type empty arrays to avoid float default
+            new = new.astype(_nx.intp)
+        if issubdtype(new.dtype, _nx.bool_):
+            new, = new.nonzero()
+        new = new.reshape((1,)*k + (new.size,) + (1,)*(nd-k-1))
+        out.append(new)
+    return tuple(out)
+
+class nd_grid(object):
+    """
+    Construct a multi-dimensional "meshgrid".
+
+    ``grid = nd_grid()`` creates an instance which will return a mesh-grid
+    when indexed.  The dimension and number of the output arrays are equal
+    to the number of indexing dimensions.  If the step length is not a
+    complex number, then the stop is not inclusive.
+
+    However, if the step length is a **complex number** (e.g. 5j), then the
+    integer part of its magnitude is interpreted as specifying the
+    number of points to create between the start and stop values, where
+    the stop value **is inclusive**.
+
+    If instantiated with an argument of ``sparse=True``, the mesh-grid is
+    open (or not fleshed out) so that only one-dimension of each returned
+    argument is greater than 1.
+
+    Parameters
+    ----------
+    sparse : bool, optional
+        Whether the grid is sparse or not. Default is False.
+
+    Notes
+    -----
+    Two instances of `nd_grid` are made available in the NumPy namespace,
+    `mgrid` and `ogrid`::
+
+        mgrid = nd_grid(sparse=False)
+        ogrid = nd_grid(sparse=True)
+
+    Users should use these pre-defined instances instead of using `nd_grid`
+    directly.
+
+    Examples
+    --------
+    >>> mgrid = np.lib.index_tricks.nd_grid()
+    >>> mgrid[0:5,0:5]
+    array([[[0, 0, 0, 0, 0],
+            [1, 1, 1, 1, 1],
+            [2, 2, 2, 2, 2],
+            [3, 3, 3, 3, 3],
+            [4, 4, 4, 4, 4]],
+           [[0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4],
+            [0, 1, 2, 3, 4]]])
+    >>> mgrid[-1:1:5j]
+    array([-1. , -0.5,  0. ,  0.5,  1. ])
+
+    >>> ogrid = np.lib.index_tricks.nd_grid(sparse=True)
+    >>> ogrid[0:5,0:5]
+    [array([[0],
+            [1],
+            [2],
+            [3],
+            [4]]), array([[0, 1, 2, 3, 4]])]
+
+    """
+
+    def __init__(self, sparse=False):
+        self.sparse = sparse
+
+    def __getitem__(self, key):
+        try:
+            size = []
+            typ = int
+            for k in range(len(key)):
+                step = key[k].step
+                start = key[k].start
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size.append(int(abs(step)))
+                    typ = float
+                else:
+                    size.append(
+                        int(math.ceil((key[k].stop - start)/(step*1.0))))
+                if (isinstance(step, float) or
+                        isinstance(start, float) or
+                        isinstance(key[k].stop, float)):
+                    typ = float
+            if self.sparse:
+                nn = [_nx.arange(_x, dtype=_t)
+                        for _x, _t in zip(size, (typ,)*len(size))]
+            else:
+                nn = _nx.indices(size, typ)
+            for k in range(len(size)):
+                step = key[k].step
+                start = key[k].start
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    step = int(abs(step))
+                    if step != 1:
+                        step = (key[k].stop - start)/float(step-1)
+                nn[k] = (nn[k]*step+start)
+            if self.sparse:
+                slobj = [_nx.newaxis]*len(size)
+                for k in range(len(size)):
+                    slobj[k] = slice(None, None)
+                    nn[k] = nn[k][slobj]
+                    slobj[k] = _nx.newaxis
+            return nn
+        except (IndexError, TypeError):
+            step = key.step
+            stop = key.stop
+            start = key.start
+            if start is None:
+                start = 0
+            if isinstance(step, complex):
+                step = abs(step)
+                length = int(step)
+                if step != 1:
+                    step = (key.stop-start)/float(step-1)
+                stop = key.stop + step
+                return _nx.arange(0, length, 1, float)*step + start
+            else:
+                return _nx.arange(start, stop, step)
+
+    def __getslice__(self, i, j):
+        return _nx.arange(i, j)
+
+    def __len__(self):
+        return 0
+
+mgrid = nd_grid(sparse=False)
+ogrid = nd_grid(sparse=True)
+mgrid.__doc__ = None  # set in numpy.add_newdocs
+ogrid.__doc__ = None  # set in numpy.add_newdocs
+
+class AxisConcatenator(object):
+    """
+    Translates slice objects to concatenation along an axis.
+
+    For detailed documentation on usage, see `r_`.
+
+    """
+
+    def _retval(self, res):
+        if self.matrix:
+            oldndim = res.ndim
+            res = makemat(res)
+            if oldndim == 1 and self.col:
+                res = res.T
+        self.axis = self._axis
+        self.matrix = self._matrix
+        self.col = 0
+        return res
+
+    def __init__(self, axis=0, matrix=False, ndmin=1, trans1d=-1):
+        self._axis = axis
+        self._matrix = matrix
+        self.axis = axis
+        self.matrix = matrix
+        self.col = 0
+        self.trans1d = trans1d
+        self.ndmin = ndmin
+
+    def __getitem__(self, key):
+        trans1d = self.trans1d
+        ndmin = self.ndmin
+        if isinstance(key, str):
+            frame = sys._getframe().f_back
+            mymat = matrix.bmat(key, frame.f_globals, frame.f_locals)
+            return mymat
+        if not isinstance(key, tuple):
+            key = (key,)
+        objs = []
+        scalars = []
+        arraytypes = []
+        scalartypes = []
+        for k in range(len(key)):
+            scalar = False
+            if isinstance(key[k], slice):
+                step = key[k].step
+                start = key[k].start
+                stop = key[k].stop
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size = int(abs(step))
+                    newobj = function_base.linspace(start, stop, num=size)
+                else:
+                    newobj = _nx.arange(start, stop, step)
+                if ndmin > 1:
+                    newobj = array(newobj, copy=False, ndmin=ndmin)
+                    if trans1d != -1:
+                        newobj = newobj.swapaxes(-1, trans1d)
+            elif isinstance(key[k], str):
+                if k != 0:
+                    raise ValueError("special directives must be the "
+                            "first entry.")
+                key0 = key[0]
+                if key0 in 'rc':
+                    self.matrix = True
+                    self.col = (key0 == 'c')
+                    continue
+                if ',' in key0:
+                    vec = key0.split(',')
+                    try:
+                        self.axis, ndmin = \
+                                   [int(x) for x in vec[:2]]
+                        if len(vec) == 3:
+                            trans1d = int(vec[2])
+                        continue
+                    except:
+                        raise ValueError("unknown special directive")
+                try:
+                    self.axis = int(key[k])
+                    continue
+                except (ValueError, TypeError):
+                    raise ValueError("unknown special directive")
+            elif type(key[k]) in ScalarType:
+                newobj = array(key[k], ndmin=ndmin)
+                scalars.append(k)
+                scalar = True
+                scalartypes.append(newobj.dtype)
+            else:
+                newobj = key[k]
+                if ndmin > 1:
+                    tempobj = array(newobj, copy=False, subok=True)
+                    newobj = array(newobj, copy=False, subok=True,
+                                   ndmin=ndmin)
+                    if trans1d != -1 and tempobj.ndim < ndmin:
+                        k2 = ndmin-tempobj.ndim
+                        if (trans1d < 0):
+                            trans1d += k2 + 1
+                        defaxes = list(range(ndmin))
+                        k1 = trans1d
+                        axes = defaxes[:k1] + defaxes[k2:] + \
+                               defaxes[k1:k2]
+                        newobj = newobj.transpose(axes)
+                    del tempobj
+            objs.append(newobj)
+            if not scalar and isinstance(newobj, _nx.ndarray):
+                arraytypes.append(newobj.dtype)
+
+        #  Esure that scalars won't up-cast unless warranted
+        final_dtype = find_common_type(arraytypes, scalartypes)
+        if final_dtype is not None:
+            for k in scalars:
+                objs[k] = objs[k].astype(final_dtype)
+
+        res = _nx.concatenate(tuple(objs), axis=self.axis)
+        return self._retval(res)
+
+    def __getslice__(self, i, j):
+        res = _nx.arange(i, j)
+        return self._retval(res)
+
+    def __len__(self):
+        return 0
+
+# separate classes are used here instead of just making r_ = concatentor(0),
+# etc. because otherwise we couldn't get the doc string to come out right
+# in help(r_)
+
+class RClass(AxisConcatenator):
+    """
+    Translates slice objects to concatenation along the first axis.
+
+    This is a simple way to build up arrays quickly. There are two use cases.
+
+    1. If the index expression contains comma separated arrays, then stack
+       them along their first axis.
+    2. If the index expression contains slice notation or scalars then create
+       a 1-D array with a range indicated by the slice notation.
+
+    If slice notation is used, the syntax ``start:stop:step`` is equivalent
+    to ``np.arange(start, stop, step)`` inside of the brackets. However, if
+    ``step`` is an imaginary number (i.e. 100j) then its integer portion is
+    interpreted as a number-of-points desired and the start and stop are
+    inclusive. In other words ``start:stop:stepj`` is interpreted as
+    ``np.linspace(start, stop, step, endpoint=1)`` inside of the brackets.
+    After expansion of slice notation, all comma separated sequences are
+    concatenated together.
+
+    Optional character strings placed as the first element of the index
+    expression can be used to change the output. The strings 'r' or 'c' result
+    in matrix output. If the result is 1-D and 'r' is specified a 1 x N (row)
+    matrix is produced. If the result is 1-D and 'c' is specified, then a N x 1
+    (column) matrix is produced. If the result is 2-D then both provide the
+    same matrix result.
+
+    A string integer specifies which axis to stack multiple comma separated
+    arrays along. A string of two comma-separated integers allows indication
+    of the minimum number of dimensions to force each entry into as the
+    second integer (the axis to concatenate along is still the first integer).
+
+    A string with three comma-separated integers allows specification of the
+    axis to concatenate along, the minimum number of dimensions to force the
+    entries to, and which axis should contain the start of the arrays which
+    are less than the specified number of dimensions. In other words the third
+    integer allows you to specify where the 1's should be placed in the shape
+    of the arrays that have their shapes upgraded. By default, they are placed
+    in the front of the shape tuple. The third argument allows you to specify
+    where the start of the array should be instead. Thus, a third argument of
+    '0' would place the 1's at the end of the array shape. Negative integers
+    specify where in the new shape tuple the last dimension of upgraded arrays
+    should be placed, so the default is '-1'.
+
+    Parameters
+    ----------
+    Not a function, so takes no parameters
+
+
+    Returns
+    -------
+    A concatenated ndarray or matrix.
+
+    See Also
+    --------
+    concatenate : Join a sequence of arrays along an existing axis.
+    c_ : Translates slice objects to concatenation along the second axis.
+
+    Examples
+    --------
+    >>> np.r_[np.array([1,2,3]), 0, 0, np.array([4,5,6])]
+    array([1, 2, 3, 0, 0, 4, 5, 6])
+    >>> np.r_[-1:1:6j, [0]*3, 5, 6]
+    array([-1. , -0.6, -0.2,  0.2,  0.6,  1. ,  0. ,  0. ,  0. ,  5. ,  6. ])
+
+    String integers specify the axis to concatenate along or the minimum
+    number of dimensions to force entries into.
+
+    >>> a = np.array([[0, 1, 2], [3, 4, 5]])
+    >>> np.r_['-1', a, a] # concatenate along last axis
+    array([[0, 1, 2, 0, 1, 2],
+           [3, 4, 5, 3, 4, 5]])
+    >>> np.r_['0,2', [1,2,3], [4,5,6]] # concatenate along first axis, dim>=2
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    >>> np.r_['0,2,0', [1,2,3], [4,5,6]]
+    array([[1],
+           [2],
+           [3],
+           [4],
+           [5],
+           [6]])
+    >>> np.r_['1,2,0', [1,2,3], [4,5,6]]
+    array([[1, 4],
+           [2, 5],
+           [3, 6]])
+
+    Using 'r' or 'c' as a first string argument creates a matrix.
+
+    >>> np.r_['r',[1,2,3], [4,5,6]]
+    matrix([[1, 2, 3, 4, 5, 6]])
+
+    """
+
+    def __init__(self):
+        AxisConcatenator.__init__(self, 0)
+
+r_ = RClass()
+
+class CClass(AxisConcatenator):
+    """
+    Translates slice objects to concatenation along the second axis.
+
+    This is short-hand for ``np.r_['-1,2,0', index expression]``, which is
+    useful because of its common occurrence. In particular, arrays will be
+    stacked along their last axis after being upgraded to at least 2-D with
+    1's post-pended to the shape (column vectors made out of 1-D arrays).
+
+    For detailed documentation, see `r_`.
+
+    Examples
+    --------
+    >>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]
+    array([[1, 2, 3, 0, 0, 4, 5, 6]])
+
+    """
+
+    def __init__(self):
+        AxisConcatenator.__init__(self, -1, ndmin=2, trans1d=0)
+
+c_ = CClass()
+
+class ndenumerate(object):
+    """
+    Multidimensional index iterator.
+
+    Return an iterator yielding pairs of array coordinates and values.
+
+    Parameters
+    ----------
+    arr : ndarray
+      Input array.
+
+    See Also
+    --------
+    ndindex, flatiter
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> for index, x in np.ndenumerate(a):
+    ...     print(index, x)
+    (0, 0) 1
+    (0, 1) 2
+    (1, 0) 3
+    (1, 1) 4
+
+    """
+
+    def __init__(self, arr):
+        self.iter = asarray(arr).flat
+
+    def __next__(self):
+        """
+        Standard iterator method, returns the index tuple and array value.
+
+        Returns
+        -------
+        coords : tuple of ints
+            The indices of the current iteration.
+        val : scalar
+            The array element of the current iteration.
+
+        """
+        return self.iter.coords, next(self.iter)
+
+    def __iter__(self):
+        return self
+
+    next = __next__
+
+
+class ndindex(object):
+    """
+    An N-dimensional iterator object to index arrays.
+
+    Given the shape of an array, an `ndindex` instance iterates over
+    the N-dimensional index of the array. At each iteration a tuple
+    of indices is returned, the last dimension is iterated over first.
+
+    Parameters
+    ----------
+    `*args` : ints
+      The size of each dimension of the array.
+
+    See Also
+    --------
+    ndenumerate, flatiter
+
+    Examples
+    --------
+    >>> for index in np.ndindex(3, 2, 1):
+    ...     print(index)
+    (0, 0, 0)
+    (0, 1, 0)
+    (1, 0, 0)
+    (1, 1, 0)
+    (2, 0, 0)
+    (2, 1, 0)
+
+    """
+
+    def __init__(self, *shape):
+        if len(shape) == 1 and isinstance(shape[0], tuple):
+            shape = shape[0]
+        x = as_strided(_nx.zeros(1), shape=shape,
+                       strides=_nx.zeros_like(shape))
+        self._it = _nx.nditer(x, flags=['multi_index', 'zerosize_ok'],
+                              order='C')
+
+    def __iter__(self):
+        return self
+
+    def ndincr(self):
+        """
+        Increment the multi-dimensional index by one.
+
+        This method is for backward compatibility only: do not use.
+        """
+        next(self)
+
+    def __next__(self):
+        """
+        Standard iterator method, updates the index and returns the index
+        tuple.
+
+        Returns
+        -------
+        val : tuple of ints
+            Returns a tuple containing the indices of the current
+            iteration.
+
+        """
+        next(self._it)
+        return self._it.multi_index
+
+    next = __next__
+
+
+# You can do all this with slice() plus a few special objects,
+# but there's a lot to remember. This version is simpler because
+# it uses the standard array indexing syntax.
+#
+# Written by Konrad Hinsen <hinsen@cnrs-orleans.fr>
+# last revision: 1999-7-23
+#
+# Cosmetic changes by T. Oliphant 2001
+#
+#
+
+class IndexExpression(object):
+    """
+    A nicer way to build up index tuples for arrays.
+
+    .. note::
+       Use one of the two predefined instances `index_exp` or `s_`
+       rather than directly using `IndexExpression`.
+
+    For any index combination, including slicing and axis insertion,
+    ``a[indices]`` is the same as ``a[np.index_exp[indices]]`` for any
+    array `a`. However, ``np.index_exp[indices]`` can be used anywhere
+    in Python code and returns a tuple of slice objects that can be
+    used in the construction of complex index expressions.
+
+    Parameters
+    ----------
+    maketuple : bool
+        If True, always returns a tuple.
+
+    See Also
+    --------
+    index_exp : Predefined instance that always returns a tuple:
+       `index_exp = IndexExpression(maketuple=True)`.
+    s_ : Predefined instance without tuple conversion:
+       `s_ = IndexExpression(maketuple=False)`.
+
+    Notes
+    -----
+    You can do all this with `slice()` plus a few special objects,
+    but there's a lot to remember and this version is simpler because
+    it uses the standard array indexing syntax.
+
+    Examples
+    --------
+    >>> np.s_[2::2]
+    slice(2, None, 2)
+    >>> np.index_exp[2::2]
+    (slice(2, None, 2),)
+
+    >>> np.array([0, 1, 2, 3, 4])[np.s_[2::2]]
+    array([2, 4])
+
+    """
+
+    def __init__(self, maketuple):
+        self.maketuple = maketuple
+
+    def __getitem__(self, item):
+        if self.maketuple and not isinstance(item, tuple):
+            return (item,)
+        else:
+            return item
+
+index_exp = IndexExpression(maketuple=True)
+s_ = IndexExpression(maketuple=False)
+
+# End contribution from Konrad.
+
+
+# The following functions complement those in twodim_base, but are
+# applicable to N-dimensions.
+
+def fill_diagonal(a, val, wrap=False):
+    """Fill the main diagonal of the given array of any dimensionality.
+
+    For an array `a` with ``a.ndim > 2``, the diagonal is the list of
+    locations with indices ``a[i, i, ..., i]`` all identical. This function
+    modifies the input array in-place, it does not return a value.
+
+    Parameters
+    ----------
+    a : array, at least 2-D.
+      Array whose diagonal is to be filled, it gets modified in-place.
+
+    val : scalar
+      Value to be written on the diagonal, its type must be compatible with
+      that of the array a.
+
+    wrap : bool
+      For tall matrices in NumPy version up to 1.6.2, the
+      diagonal "wrapped" after N columns. You can have this behavior
+      with this option. This affects only tall matrices.
+
+    See also
+    --------
+    diag_indices, diag_indices_from
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    This functionality can be obtained via `diag_indices`, but internally
+    this version uses a much faster implementation that never constructs the
+    indices and uses simple slicing.
+
+    Examples
+    --------
+    >>> a = np.zeros((3, 3), int)
+    >>> np.fill_diagonal(a, 5)
+    >>> a
+    array([[5, 0, 0],
+           [0, 5, 0],
+           [0, 0, 5]])
+
+    The same function can operate on a 4-D array:
+
+    >>> a = np.zeros((3, 3, 3, 3), int)
+    >>> np.fill_diagonal(a, 4)
+
+    We only show a few blocks for clarity:
+
+    >>> a[0, 0]
+    array([[4, 0, 0],
+           [0, 0, 0],
+           [0, 0, 0]])
+    >>> a[1, 1]
+    array([[0, 0, 0],
+           [0, 4, 0],
+           [0, 0, 0]])
+    >>> a[2, 2]
+    array([[0, 0, 0],
+           [0, 0, 0],
+           [0, 0, 4]])
+
+    The wrap option affects only tall matrices:
+
+    >>> # tall matrices no wrap
+    >>> a = np.zeros((5, 3),int)
+    >>> fill_diagonal(a, 4)
+    >>> a
+    array([[4, 0, 0],
+           [0, 4, 0],
+           [0, 0, 4],
+           [0, 0, 0],
+           [0, 0, 0]])
+
+    >>> # tall matrices wrap
+    >>> a = np.zeros((5, 3),int)
+    >>> fill_diagonal(a, 4, wrap=True)
+    >>> a
+    array([[4, 0, 0],
+           [0, 4, 0],
+           [0, 0, 4],
+           [0, 0, 0],
+           [4, 0, 0]])
+
+    >>> # wide matrices
+    >>> a = np.zeros((3, 5),int)
+    >>> fill_diagonal(a, 4, wrap=True)
+    >>> a
+    array([[4, 0, 0, 0, 0],
+           [0, 4, 0, 0, 0],
+           [0, 0, 4, 0, 0]])
+
+    """
+    if a.ndim < 2:
+        raise ValueError("array must be at least 2-d")
+    end = None
+    if a.ndim == 2:
+        # Explicit, fast formula for the common case.  For 2-d arrays, we
+        # accept rectangular ones.
+        step = a.shape[1] + 1
+        #This is needed to don't have tall matrix have the diagonal wrap.
+        if not wrap:
+            end = a.shape[1] * a.shape[1]
+    else:
+        # For more than d=2, the strided formula is only valid for arrays with
+        # all dimensions equal, so we check first.
+        if not alltrue(diff(a.shape) == 0):
+            raise ValueError("All dimensions of input must be of equal length")
+        step = 1 + (cumprod(a.shape[:-1])).sum()
+
+    # Write the value out into the diagonal.
+    a.flat[:end:step] = val
+
+
+def diag_indices(n, ndim=2):
+    """
+    Return the indices to access the main diagonal of an array.
+
+    This returns a tuple of indices that can be used to access the main
+    diagonal of an array `a` with ``a.ndim >= 2`` dimensions and shape
+    (n, n, ..., n). For ``a.ndim = 2`` this is the usual diagonal, for
+    ``a.ndim > 2`` this is the set of indices to access ``a[i, i, ..., i]``
+    for ``i = [0..n-1]``.
+
+    Parameters
+    ----------
+    n : int
+      The size, along each dimension, of the arrays for which the returned
+      indices can be used.
+
+    ndim : int, optional
+      The number of dimensions.
+
+    See also
+    --------
+    diag_indices_from
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Create a set of indices to access the diagonal of a (4, 4) array:
+
+    >>> di = np.diag_indices(4)
+    >>> di
+    (array([0, 1, 2, 3]), array([0, 1, 2, 3]))
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+    >>> a[di] = 100
+    >>> a
+    array([[100,   1,   2,   3],
+           [  4, 100,   6,   7],
+           [  8,   9, 100,  11],
+           [ 12,  13,  14, 100]])
+
+    Now, we create indices to manipulate a 3-D array:
+
+    >>> d3 = np.diag_indices(2, 3)
+    >>> d3
+    (array([0, 1]), array([0, 1]), array([0, 1]))
+
+    And use it to set the diagonal of an array of zeros to 1:
+
+    >>> a = np.zeros((2, 2, 2), dtype=np.int)
+    >>> a[d3] = 1
+    >>> a
+    array([[[1, 0],
+            [0, 0]],
+           [[0, 0],
+            [0, 1]]])
+
+    """
+    idx = arange(n)
+    return (idx,) * ndim
+
+
+def diag_indices_from(arr):
+    """
+    Return the indices to access the main diagonal of an n-dimensional array.
+
+    See `diag_indices` for full details.
+
+    Parameters
+    ----------
+    arr : array, at least 2-D
+
+    See Also
+    --------
+    diag_indices
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+
+    if not arr.ndim >= 2:
+        raise ValueError("input array must be at least 2-d")
+    # For more than d=2, the strided formula is only valid for arrays with
+    # all dimensions equal, so we check first.
+    if not alltrue(diff(arr.shape) == 0):
+        raise ValueError("All dimensions of input must be of equal length")
+
+    return diag_indices(arr.shape[0], arr.ndim)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/info.py
new file mode 100644
index 0000000000..ca1e723975
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/info.py
@@ -0,0 +1,158 @@
+"""
+Basic functions used by several sub-packages and
+useful to have in the main name-space.
+
+Type Handling
+-------------
+================ ===================
+iscomplexobj     Test for complex object, scalar result
+isrealobj        Test for real object, scalar result
+iscomplex        Test for complex elements, array result
+isreal           Test for real elements, array result
+imag             Imaginary part
+real             Real part
+real_if_close    Turns complex number with tiny imaginary part to real
+isneginf         Tests for negative infinity, array result
+isposinf         Tests for positive infinity, array result
+isnan            Tests for nans, array result
+isinf            Tests for infinity, array result
+isfinite         Tests for finite numbers, array result
+isscalar         True if argument is a scalar
+nan_to_num       Replaces NaN's with 0 and infinities with large numbers
+cast             Dictionary of functions to force cast to each type
+common_type      Determine the minimum common type code for a group
+                 of arrays
+mintypecode      Return minimal allowed common typecode.
+================ ===================
+
+Index Tricks
+------------
+================ ===================
+mgrid            Method which allows easy construction of N-d
+                 'mesh-grids'
+``r_``           Append and construct arrays: turns slice objects into
+                 ranges and concatenates them, for 2d arrays appends rows.
+index_exp        Konrad Hinsen's index_expression class instance which
+                 can be useful for building complicated slicing syntax.
+================ ===================
+
+Useful Functions
+----------------
+================ ===================
+select           Extension of where to multiple conditions and choices
+extract          Extract 1d array from flattened array according to mask
+insert           Insert 1d array of values into Nd array according to mask
+linspace         Evenly spaced samples in linear space
+logspace         Evenly spaced samples in logarithmic space
+fix              Round x to nearest integer towards zero
+mod              Modulo mod(x,y) = x % y except keeps sign of y
+amax             Array maximum along axis
+amin             Array minimum along axis
+ptp              Array max-min along axis
+cumsum           Cumulative sum along axis
+prod             Product of elements along axis
+cumprod          Cumluative product along axis
+diff             Discrete differences along axis
+angle            Returns angle of complex argument
+unwrap           Unwrap phase along given axis (1-d algorithm)
+sort_complex     Sort a complex-array (based on real, then imaginary)
+trim_zeros       Trim the leading and trailing zeros from 1D array.
+vectorize        A class that wraps a Python function taking scalar
+                 arguments into a generalized function which can handle
+                 arrays of arguments using the broadcast rules of
+                 numerix Python.
+================ ===================
+
+Shape Manipulation
+------------------
+================ ===================
+squeeze          Return a with length-one dimensions removed.
+atleast_1d       Force arrays to be > 1D
+atleast_2d       Force arrays to be > 2D
+atleast_3d       Force arrays to be > 3D
+vstack           Stack arrays vertically (row on row)
+hstack           Stack arrays horizontally (column on column)
+column_stack     Stack 1D arrays as columns into 2D array
+dstack           Stack arrays depthwise (along third dimension)
+stack            Stack arrays along a new axis
+split            Divide array into a list of sub-arrays
+hsplit           Split into columns
+vsplit           Split into rows
+dsplit           Split along third dimension
+================ ===================
+
+Matrix (2D Array) Manipulations
+-------------------------------
+================ ===================
+fliplr           2D array with columns flipped
+flipud           2D array with rows flipped
+rot90            Rotate a 2D array a multiple of 90 degrees
+eye              Return a 2D array with ones down a given diagonal
+diag             Construct a 2D array from a vector, or return a given
+                 diagonal from a 2D array.
+mat              Construct a Matrix
+bmat             Build a Matrix from blocks
+================ ===================
+
+Polynomials
+-----------
+================ ===================
+poly1d           A one-dimensional polynomial class
+poly             Return polynomial coefficients from roots
+roots            Find roots of polynomial given coefficients
+polyint          Integrate polynomial
+polyder          Differentiate polynomial
+polyadd          Add polynomials
+polysub          Substract polynomials
+polymul          Multiply polynomials
+polydiv          Divide polynomials
+polyval          Evaluate polynomial at given argument
+================ ===================
+
+Iterators
+---------
+================ ===================
+Arrayterator     A buffered iterator for big arrays.
+================ ===================
+
+Import Tricks
+-------------
+================ ===================
+ppimport         Postpone module import until trying to use it
+ppimport_attr    Postpone module import until trying to use its attribute
+ppresolve        Import postponed module and return it.
+================ ===================
+
+Machine Arithmetics
+-------------------
+================ ===================
+machar_single    Single precision floating point arithmetic parameters
+machar_double    Double precision floating point arithmetic parameters
+================ ===================
+
+Threading Tricks
+----------------
+================ ===================
+ParallelExec     Execute commands in parallel thread.
+================ ===================
+
+1D Array Set Operations
+-----------------------
+Set operations for 1D numeric arrays based on sort() function.
+
+================ ===================
+ediff1d          Array difference (auxiliary function).
+unique           Unique elements of an array.
+intersect1d      Intersection of 1D arrays with unique elements.
+setxor1d         Set exclusive-or of 1D arrays with unique elements.
+in1d             Test whether elements in a 1D array are also present in
+                 another array.
+union1d          Union of 1D arrays with unique elements.
+setdiff1d        Set difference of 1D arrays with unique elements.
+================ ===================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core', 'testing']
+global_symbols = ['*']
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
new file mode 100644
index 0000000000..8fe7afd46f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
@@ -0,0 +1,1248 @@
+"""
+Functions that ignore NaN.
+
+Functions
+---------
+
+- `nanmin` -- minimum non-NaN value
+- `nanmax` -- maximum non-NaN value
+- `nanargmin` -- index of minimum non-NaN value
+- `nanargmax` -- index of maximum non-NaN value
+- `nansum` -- sum of non-NaN values
+- `nanprod` -- product of non-NaN values
+- `nanmean` -- mean of non-NaN values
+- `nanvar` -- variance of non-NaN values
+- `nanstd` -- standard deviation of non-NaN values
+- `nanmedian` -- median of non-NaN values
+- `nanpercentile` -- qth percentile of non-NaN values
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+from numpy.lib.function_base import _ureduce as _ureduce
+
+__all__ = [
+    'nansum', 'nanmax', 'nanmin', 'nanargmax', 'nanargmin', 'nanmean',
+    'nanmedian', 'nanpercentile', 'nanvar', 'nanstd', 'nanprod',
+    ]
+
+
+def _replace_nan(a, val):
+    """
+    If `a` is of inexact type, make a copy of `a`, replace NaNs with
+    the `val` value, and return the copy together with a boolean mask
+    marking the locations where NaNs were present. If `a` is not of
+    inexact type, do nothing and return `a` together with a mask of None.
+
+    Note that scalars will end up as array scalars, which is important
+    for using the result as the value of the out argument in some
+    operations.
+
+    Parameters
+    ----------
+    a : array-like
+        Input array.
+    val : float
+        NaN values are set to val before doing the operation.
+
+    Returns
+    -------
+    y : ndarray
+        If `a` is of inexact type, return a copy of `a` with the NaNs
+        replaced by the fill value, otherwise return `a`.
+    mask: {bool, None}
+        If `a` is of inexact type, return a boolean mask marking locations of
+        NaNs, otherwise return None.
+
+    """
+    is_new = not isinstance(a, np.ndarray)
+    if is_new:
+        a = np.array(a)
+    if not issubclass(a.dtype.type, np.inexact):
+        return a, None
+    if not is_new:
+        # need copy
+        a = np.array(a, subok=True)
+
+    mask = np.isnan(a)
+    np.copyto(a, val, where=mask)
+    return a, mask
+
+
+def _copyto(a, val, mask):
+    """
+    Replace values in `a` with NaN where `mask` is True.  This differs from
+    copyto in that it will deal with the case where `a` is a numpy scalar.
+
+    Parameters
+    ----------
+    a : ndarray or numpy scalar
+        Array or numpy scalar some of whose values are to be replaced
+        by val.
+    val : numpy scalar
+        Value used a replacement.
+    mask : ndarray, scalar
+        Boolean array. Where True the corresponding element of `a` is
+        replaced by `val`. Broadcasts.
+
+    Returns
+    -------
+    res : ndarray, scalar
+        Array with elements replaced or scalar `val`.
+
+    """
+    if isinstance(a, np.ndarray):
+        np.copyto(a, val, where=mask, casting='unsafe')
+    else:
+        a = a.dtype.type(val)
+    return a
+
+
+def _divide_by_count(a, b, out=None):
+    """
+    Compute a/b ignoring invalid results. If `a` is an array the division
+    is done in place. If `a` is a scalar, then its type is preserved in the
+    output. If out is None, then then a is used instead so that the
+    division is in place. Note that this is only called with `a` an inexact
+    type.
+
+    Parameters
+    ----------
+    a : {ndarray, numpy scalar}
+        Numerator. Expected to be of inexact type but not checked.
+    b : {ndarray, numpy scalar}
+        Denominator.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.
+
+    Returns
+    -------
+    ret : {ndarray, numpy scalar}
+        The return value is a/b. If `a` was an ndarray the division is done
+        in place. If `a` is a numpy scalar, the division preserves its type.
+
+    """
+    with np.errstate(invalid='ignore'):
+        if isinstance(a, np.ndarray):
+            if out is None:
+                return np.divide(a, b, out=a, casting='unsafe')
+            else:
+                return np.divide(a, b, out=out, casting='unsafe')
+        else:
+            if out is None:
+                return a.dtype.type(a / b)
+            else:
+                # This is questionable, but currently a numpy scalar can
+                # be output to a zero dimensional array.
+                return np.divide(a, b, out=out, casting='unsafe')
+
+
+def nanmin(a, axis=None, out=None, keepdims=False):
+    """
+    Return minimum of an array or minimum along an axis, ignoring any NaNs.
+    When all-NaN slices are encountered a ``RuntimeWarning`` is raised and
+    Nan is returned for that slice.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose minimum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the minimum is computed. The default is to compute
+        the minimum of the flattened array.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `a`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    nanmin : ndarray
+        An array with the same shape as `a`, with the specified axis
+        removed.  If `a` is a 0-d array, or if axis is None, an ndarray
+        scalar is returned.  The same dtype as `a` is returned.
+
+    See Also
+    --------
+    nanmax :
+        The maximum value of an array along a given axis, ignoring any NaNs.
+    amin :
+        The minimum value of an array along a given axis, propagating any NaNs.
+    fmin :
+        Element-wise minimum of two arrays, ignoring any NaNs.
+    minimum :
+        Element-wise minimum of two arrays, propagating any NaNs.
+    isnan :
+        Shows which elements are Not a Number (NaN).
+    isfinite:
+        Shows which elements are neither NaN nor infinity.
+
+    amax, fmax, maximum
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Positive infinity is treated as a very large number and negative
+    infinity is treated as a very small (i.e. negative) number.
+
+    If the input has a integer type the function is equivalent to np.min.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanmin(a)
+    1.0
+    >>> np.nanmin(a, axis=0)
+    array([ 1.,  2.])
+    >>> np.nanmin(a, axis=1)
+    array([ 1.,  3.])
+
+    When positive infinity and negative infinity are present:
+
+    >>> np.nanmin([1, 2, np.nan, np.inf])
+    1.0
+    >>> np.nanmin([1, 2, np.nan, np.NINF])
+    -inf
+
+    """
+    if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
+        # Fast, but not safe for subclasses of ndarray
+        res = np.fmin.reduce(a, axis=axis, out=out, keepdims=keepdims)
+        if np.isnan(res).any():
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    else:
+        # Slow, but safe for subclasses of ndarray
+        a, mask = _replace_nan(a, +np.inf)
+        res = np.amin(a, axis=axis, out=out, keepdims=keepdims)
+        if mask is None:
+            return res
+
+        # Check for all-NaN axis
+        mask = np.all(mask, axis=axis, keepdims=keepdims)
+        if np.any(mask):
+            res = _copyto(res, np.nan, mask)
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    return res
+
+
+def nanmax(a, axis=None, out=None, keepdims=False):
+    """
+    Return the maximum of an array or maximum along an axis, ignoring any
+    NaNs.  When all-NaN slices are encountered a ``RuntimeWarning`` is
+    raised and NaN is returned for that slice.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose maximum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the maximum is computed. The default is to compute
+        the maximum of the flattened array.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `a`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    nanmax : ndarray
+        An array with the same shape as `a`, with the specified axis removed.
+        If `a` is a 0-d array, or if axis is None, an ndarray scalar is
+        returned.  The same dtype as `a` is returned.
+
+    See Also
+    --------
+    nanmin :
+        The minimum value of an array along a given axis, ignoring any NaNs.
+    amax :
+        The maximum value of an array along a given axis, propagating any NaNs.
+    fmax :
+        Element-wise maximum of two arrays, ignoring any NaNs.
+    maximum :
+        Element-wise maximum of two arrays, propagating any NaNs.
+    isnan :
+        Shows which elements are Not a Number (NaN).
+    isfinite:
+        Shows which elements are neither NaN nor infinity.
+
+    amin, fmin, minimum
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+    Positive infinity is treated as a very large number and negative
+    infinity is treated as a very small (i.e. negative) number.
+
+    If the input has a integer type the function is equivalent to np.max.
+
+    Examples
+    --------
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanmax(a)
+    3.0
+    >>> np.nanmax(a, axis=0)
+    array([ 3.,  2.])
+    >>> np.nanmax(a, axis=1)
+    array([ 2.,  3.])
+
+    When positive infinity and negative infinity are present:
+
+    >>> np.nanmax([1, 2, np.nan, np.NINF])
+    2.0
+    >>> np.nanmax([1, 2, np.nan, np.inf])
+    inf
+
+    """
+    if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
+        # Fast, but not safe for subclasses of ndarray
+        res = np.fmax.reduce(a, axis=axis, out=out, keepdims=keepdims)
+        if np.isnan(res).any():
+            warnings.warn("All-NaN slice encountered", RuntimeWarning)
+    else:
+        # Slow, but safe for subclasses of ndarray
+        a, mask = _replace_nan(a, -np.inf)
+        res = np.amax(a, axis=axis, out=out, keepdims=keepdims)
+        if mask is None:
+            return res
+
+        # Check for all-NaN axis
+        mask = np.all(mask, axis=axis, keepdims=keepdims)
+        if np.any(mask):
+            res = _copyto(res, np.nan, mask)
+            warnings.warn("All-NaN axis encountered", RuntimeWarning)
+    return res
+
+
+def nanargmin(a, axis=None):
+    """
+    Return the indices of the minimum values in the specified axis ignoring
+    NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the results
+    cannot be trusted if a slice contains only NaNs and Infs.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which to operate.  By default flattened input is used.
+
+    Returns
+    -------
+    index_array : ndarray
+        An array of indices or a single index value.
+
+    See Also
+    --------
+    argmin, nanargmax
+
+    Examples
+    --------
+    >>> a = np.array([[np.nan, 4], [2, 3]])
+    >>> np.argmin(a)
+    0
+    >>> np.nanargmin(a)
+    2
+    >>> np.nanargmin(a, axis=0)
+    array([1, 1])
+    >>> np.nanargmin(a, axis=1)
+    array([1, 0])
+
+    """
+    a, mask = _replace_nan(a, np.inf)
+    res = np.argmin(a, axis=axis)
+    if mask is not None:
+        mask = np.all(mask, axis=axis)
+        if np.any(mask):
+            raise ValueError("All-NaN slice encountered")
+    return res
+
+
+def nanargmax(a, axis=None):
+    """
+    Return the indices of the maximum values in the specified axis ignoring
+    NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the
+    results cannot be trusted if a slice contains only NaNs and -Infs.
+
+
+    Parameters
+    ----------
+    a : array_like
+        Input data.
+    axis : int, optional
+        Axis along which to operate.  By default flattened input is used.
+
+    Returns
+    -------
+    index_array : ndarray
+        An array of indices or a single index value.
+
+    See Also
+    --------
+    argmax, nanargmin
+
+    Examples
+    --------
+    >>> a = np.array([[np.nan, 4], [2, 3]])
+    >>> np.argmax(a)
+    0
+    >>> np.nanargmax(a)
+    1
+    >>> np.nanargmax(a, axis=0)
+    array([1, 0])
+    >>> np.nanargmax(a, axis=1)
+    array([1, 1])
+
+    """
+    a, mask = _replace_nan(a, -np.inf)
+    res = np.argmax(a, axis=axis)
+    if mask is not None:
+        mask = np.all(mask, axis=axis)
+        if np.any(mask):
+            raise ValueError("All-NaN slice encountered")
+    return res
+
+
+def nansum(a, axis=None, dtype=None, out=None, keepdims=0):
+    """
+    Return the sum of array elements over a given axis treating Not a
+    Numbers (NaNs) as zero.
+
+    In Numpy versions <= 1.8 Nan is returned for slices that are all-NaN or
+    empty. In later versions zero is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose sum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the sum is computed. The default is to compute the
+        sum of the flattened array.
+    dtype : data-type, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  By default, the dtype of `a` is used.  An
+        exception is when `a` has an integer type with less precision than
+        the platform (u)intp. In that case, the default will be either
+        (u)int32 or (u)int64 depending on whether the platform is 32 or 64
+        bits. For inexact inputs, dtype must be inexact.
+
+        .. versionadded:: 1.8.0
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``. If provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details. The casting of NaN to integer can yield
+        unexpected results.
+
+        .. versionadded:: 1.8.0
+    keepdims : bool, optional
+        If True, the axes which are reduced are left in the result as
+        dimensions with size one. With this option, the result will
+        broadcast correctly against the original `arr`.
+
+        .. versionadded:: 1.8.0
+
+    Returns
+    -------
+    y : ndarray or numpy scalar
+
+    See Also
+    --------
+    numpy.sum : Sum across array propagating NaNs.
+    isnan : Show which elements are NaN.
+    isfinite: Show which elements are not NaN or +/-inf.
+
+    Notes
+    -----
+    If both positive and negative infinity are present, the sum will be Not
+    A Number (NaN).
+
+    Numpy integer arithmetic is modular. If the size of a sum exceeds the
+    size of an integer accumulator, its value will wrap around and the
+    result will be incorrect. Specifying ``dtype=double`` can alleviate
+    that problem.
+
+    Examples
+    --------
+    >>> np.nansum(1)
+    1
+    >>> np.nansum([1])
+    1
+    >>> np.nansum([1, np.nan])
+    1.0
+    >>> a = np.array([[1, 1], [1, np.nan]])
+    >>> np.nansum(a)
+    3.0
+    >>> np.nansum(a, axis=0)
+    array([ 2.,  1.])
+    >>> np.nansum([1, np.nan, np.inf])
+    inf
+    >>> np.nansum([1, np.nan, np.NINF])
+    -inf
+    >>> np.nansum([1, np.nan, np.inf, -np.inf]) # both +/- infinity present
+    nan
+
+    """
+    a, mask = _replace_nan(a, 0)
+    return np.sum(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+
+def nanprod(a, axis=None, dtype=None, out=None, keepdims=0):
+    """
+    Return the product of array elements over a given axis treating Not a
+    Numbers (NaNs) as zero.
+
+    One is returned for slices that are all-NaN or empty.
+
+    .. versionadded:: 1.10.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose sum is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the product is computed. The default is to compute
+        the product of the flattened array.
+    dtype : data-type, optional
+        The type of the returned array and of the accumulator in which the
+        elements are summed.  By default, the dtype of `a` is used.  An
+        exception is when `a` has an integer type with less precision than
+        the platform (u)intp. In that case, the default will be either
+        (u)int32 or (u)int64 depending on whether the platform is 32 or 64
+        bits. For inexact inputs, dtype must be inexact.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``. If provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details. The casting of NaN to integer can yield
+        unexpected results.
+    keepdims : bool, optional
+        If True, the axes which are reduced are left in the result as
+        dimensions with size one. With this option, the result will
+        broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    y : ndarray or numpy scalar
+
+    See Also
+    --------
+    numpy.prod : Product across array propagating NaNs.
+    isnan : Show which elements are NaN.
+
+    Notes
+    -----
+    Numpy integer arithmetic is modular. If the size of a product exceeds
+    the size of an integer accumulator, its value will wrap around and the
+    result will be incorrect. Specifying ``dtype=double`` can alleviate
+    that problem.
+
+    Examples
+    --------
+    >>> np.nanprod(1)
+    1
+    >>> np.nanprod([1])
+    1
+    >>> np.nanprod([1, np.nan])
+    1.0
+    >>> a = np.array([[1, 2], [3, np.nan]])
+    >>> np.nanprod(a)
+    6.0
+    >>> np.nanprod(a, axis=0)
+    array([ 3.,  2.])
+
+    """
+    a, mask = _replace_nan(a, 1)
+    return np.prod(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+
+def nanmean(a, axis=None, dtype=None, out=None, keepdims=False):
+    """
+    Compute the arithmetic mean along the specified axis, ignoring NaNs.
+
+    Returns the average of the array elements.  The average is taken over
+    the flattened array by default, otherwise over the specified axis.
+    `float64` intermediate and return values are used for integer inputs.
+
+    For all-NaN slices, NaN is returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose mean is desired. If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the means are computed. The default is to compute
+        the mean of the flattened array.
+    dtype : data-type, optional
+        Type to use in computing the mean.  For integer inputs, the default
+        is `float64`; for inexact inputs, it is the same as the input
+        dtype.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  The default
+        is ``None``; if provided, it must have the same shape as the
+        expected output, but the type will be cast if necessary.  See
+        `doc.ufuncs` for details.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in the
+        result as dimensions with size one. With this option, the result
+        will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    m : ndarray, see dtype parameter above
+        If `out=None`, returns a new array containing the mean values,
+        otherwise a reference to the output array is returned. Nan is
+        returned for slices that contain only NaNs.
+
+    See Also
+    --------
+    average : Weighted average
+    mean : Arithmetic mean taken while not ignoring NaNs
+    var, nanvar
+
+    Notes
+    -----
+    The arithmetic mean is the sum of the non-NaN elements along the axis
+    divided by the number of non-NaN elements.
+
+    Note that for floating-point input, the mean is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32`.  Specifying a
+    higher-precision accumulator using the `dtype` keyword can alleviate
+    this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.nanmean(a)
+    2.6666666666666665
+    >>> np.nanmean(a, axis=0)
+    array([ 2.,  4.])
+    >>> np.nanmean(a, axis=1)
+    array([ 1.,  3.5])
+
+    """
+    arr, mask = _replace_nan(a, 0)
+    if mask is None:
+        return np.mean(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+
+    if dtype is not None:
+        dtype = np.dtype(dtype)
+    if dtype is not None and not issubclass(dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then dtype must be inexact")
+    if out is not None and not issubclass(out.dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then out must be inexact")
+
+    # The warning context speeds things up.
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+        cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims)
+        tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+        avg = _divide_by_count(tot, cnt, out=out)
+
+    isbad = (cnt == 0)
+    if isbad.any():
+        warnings.warn("Mean of empty slice", RuntimeWarning)
+        # NaN is the only possible bad value, so no further
+        # action is needed to handle bad results.
+    return avg
+
+
+def _nanmedian1d(arr1d, overwrite_input=False):
+    """
+    Private function for rank 1 arrays. Compute the median ignoring NaNs.
+    See nanmedian for parameter usage
+    """
+    c = np.isnan(arr1d)
+    s = np.where(c)[0]
+    if s.size == arr1d.size:
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+        return np.nan
+    elif s.size == 0:
+        return np.median(arr1d, overwrite_input=overwrite_input)
+    else:
+        if overwrite_input:
+            x = arr1d
+        else:
+            x = arr1d.copy()
+        # select non-nans at end of array
+        enonan = arr1d[-s.size:][~c[-s.size:]]
+        # fill nans in beginning of array with non-nans of end
+        x[s[:enonan.size]] = enonan
+        # slice nans away
+        return np.median(x[:-s.size], overwrite_input=True)
+
+
+def _nanmedian(a, axis=None, out=None, overwrite_input=False):
+    """
+    Private function that doesn't support extended axis or keepdims.
+    These methods are extended to this function using _ureduce
+    See nanmedian for parameter usage
+
+    """
+    if axis is None or a.ndim == 1:
+        part = a.ravel()
+        if out is None:
+            return _nanmedian1d(part, overwrite_input)
+        else:
+            out[...] = _nanmedian1d(part, overwrite_input)
+            return out
+    else:
+        # for small medians use sort + indexing which is still faster than
+        # apply_along_axis
+        if a.shape[axis] < 400:
+            return _nanmedian_small(a, axis, out, overwrite_input)
+        result = np.apply_along_axis(_nanmedian1d, axis, a, overwrite_input)
+        if out is not None:
+            out[...] = result
+        return result
+
+def _nanmedian_small(a, axis=None, out=None, overwrite_input=False):
+    """
+    sort + indexing median, faster for small medians along multiple
+    dimensions due to the high overhead of apply_along_axis
+
+    see nanmedian for parameter usage
+    """
+    a = np.ma.masked_array(a, np.isnan(a))
+    m = np.ma.median(a, axis=axis, overwrite_input=overwrite_input)
+    for i in range(np.count_nonzero(m.mask.ravel())):
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+    if out is not None:
+        out[...] = m.filled(np.nan)
+        return out
+    return m.filled(np.nan)
+
+def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=False):
+    """
+    Compute the median along the specified axis, while ignoring NaNs.
+
+    Returns the median of the array elements.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the medians are computed. The default
+        is to compute the median along a flattened version of the array.
+        A sequence of axes is supported since version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+       If True, then allow use of memory of input array `a` for
+       calculations. The input array will be modified by the call to
+       `median`. This will save memory when you do not need to preserve
+       the contents of the input array. Treat the input as undefined,
+       but it will probably be fully or partially sorted. Default is
+       False. If `overwrite_input` is ``True`` and `a` is not already an
+       `ndarray`, an error will be raised.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result. If the input contains integers
+        or floats smaller than ``float64``, then the output data-type is
+        ``np.float64``.  Otherwise, the data-type of the output is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    mean, median, percentile
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the median of ``V`` is the
+    middle value of a sorted copy of ``V``, ``V_sorted`` - i.e.,
+    ``V_sorted[(N-1)/2]``, when ``N`` is odd and the average of the two
+    middle values of ``V_sorted`` when ``N`` is even.
+
+    Examples
+    --------
+    >>> a = np.array([[10.0, 7, 4], [3, 2, 1]])
+    >>> a[0, 1] = np.nan
+    >>> a
+    array([[ 10.,  nan,   4.],
+       [  3.,   2.,   1.]])
+    >>> np.median(a)
+    nan
+    >>> np.nanmedian(a)
+    3.0
+    >>> np.nanmedian(a, axis=0)
+    array([ 6.5,  2.,  2.5])
+    >>> np.median(a, axis=1)
+    array([ 7.,  2.])
+    >>> b = a.copy()
+    >>> np.nanmedian(b, axis=1, overwrite_input=True)
+    array([ 7.,  2.])
+    >>> assert not np.all(a==b)
+    >>> b = a.copy()
+    >>> np.nanmedian(b, axis=None, overwrite_input=True)
+    3.0
+    >>> assert not np.all(a==b)
+
+    """
+    a = np.asanyarray(a)
+    # apply_along_axis in _nanmedian doesn't handle empty arrays well,
+    # so deal them upfront
+    if a.size == 0:
+        return np.nanmean(a, axis, out=out, keepdims=keepdims)
+
+    r, k = _ureduce(a, func=_nanmedian, axis=axis, out=out,
+                    overwrite_input=overwrite_input)
+    if keepdims:
+        return r.reshape(k)
+    else:
+        return r
+
+
+def nanpercentile(a, q, axis=None, out=None, overwrite_input=False,
+                  interpolation='linear', keepdims=False):
+    """
+    Compute the qth percentile of the data along the specified axis,
+    while ignoring nan values.
+
+    Returns the qth percentile(s) of the array elements.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    q : float in range of [0,100] (or sequence of floats)
+        Percentile to compute, which must be between 0 and 100
+        inclusive.
+    axis : {int, sequence of int, None}, optional
+        Axis or axes along which the percentiles are computed. The
+        default is to compute the percentile(s) along a flattened
+        version of the array. A sequence of axes is supported since
+        version 1.9.0.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output,
+        but the type (of the output) will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array `a` for
+        calculations. The input array will be modified by the call to
+        `percentile`. This will save memory when you do not need to
+        preserve the contents of the input array. In this case you
+        should not make any assumptions about the contents of the input
+        `a` after this function completes -- treat it as undefined.
+        Default is False. If `a` is not already an array, this parameter
+        will have no effect as `a` will be converted to an array
+        internally regardless of the value of this parameter.
+    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``.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left in
+        the result as dimensions with size one. With this option, the
+        result will broadcast correctly against the original array `a`.
+
+    Returns
+    -------
+    percentile : scalar or ndarray
+        If `q` is a single percentile and `axis=None`, then the result
+        is a scalar. If multiple percentiles are given, first axis of
+        the result corresponds to the percentiles. The other axes are
+        the axes that remain after the reduction of `a`. If the input 
+        contains integers or floats smaller than ``float64``, the output
+        data-type is ``float64``. Otherwise, the output data-type is the
+        same as that of the input. If `out` is specified, that array is
+        returned instead.
+
+    See Also
+    --------
+    nanmean, nanmedian, percentile, median, mean
+
+    Notes
+    -----
+    Given a vector ``V`` of length ``N``, the ``q``-th percentile of
+    ``V`` is the value ``q/100`` of the way from the mimumum to the
+    maximum in in a sorted copy of ``V``. The values and distances of
+    the two nearest neighbors as well as the `interpolation` parameter
+    will determine the percentile if the normalized ranking does not
+    match the location of ``q`` exactly. This function is the same as
+    the median if ``q=50``, the same as the minimum if ``q=0`` and the
+    same as the maximum if ``q=100``.
+
+    Examples
+    --------
+    >>> a = np.array([[10., 7., 4.], [3., 2., 1.]])
+    >>> a[0][1] = np.nan
+    >>> a
+    array([[ 10.,  nan,   4.],
+       [  3.,   2.,   1.]])
+    >>> np.percentile(a, 50)
+    nan
+    >>> np.nanpercentile(a, 50)
+    3.5
+    >>> np.nanpercentile(a, 50, axis=0)
+    array([ 6.5,  2.,   2.5])
+    >>> np.nanpercentile(a, 50, axis=1, keepdims=True)
+    array([[ 7.],
+           [ 2.]])
+    >>> m = np.nanpercentile(a, 50, axis=0)
+    >>> out = np.zeros_like(m)
+    >>> np.nanpercentile(a, 50, axis=0, out=out)
+    array([ 6.5,  2.,   2.5])
+    >>> m
+    array([ 6.5,  2. ,  2.5])
+
+    >>> b = a.copy()
+    >>> np.nanpercentile(b, 50, axis=1, overwrite_input=True)
+    array([  7.,  2.])
+    >>> assert not np.all(a==b)
+
+    """
+
+    a = np.asanyarray(a)
+    q = np.asanyarray(q)
+    # apply_along_axis in _nanpercentile doesn't handle empty arrays well,
+    # so deal them upfront
+    if a.size == 0:
+        return np.nanmean(a, axis, out=out, keepdims=keepdims)
+
+    r, k = _ureduce(a, func=_nanpercentile, q=q, axis=axis, out=out,
+                    overwrite_input=overwrite_input,
+                    interpolation=interpolation)
+    if keepdims:
+        if q.ndim == 0:
+            return r.reshape(k)
+        else:
+            return r.reshape([len(q)] + k)
+    else:
+        return r
+
+
+def _nanpercentile(a, q, axis=None, out=None, overwrite_input=False,
+                   interpolation='linear', keepdims=False):
+    """
+    Private function that doesn't support extended axis or keepdims.
+    These methods are extended to this function using _ureduce
+    See nanpercentile for parameter usage
+
+    """
+    if axis is None:
+        part = a.ravel()
+        result = _nanpercentile1d(part, q, overwrite_input, interpolation)
+    else:
+        result = np.apply_along_axis(_nanpercentile1d, axis, a, q,
+                                     overwrite_input, interpolation)
+        # apply_along_axis fills in collapsed axis with results.
+        # Move that axis to the beginning to match percentile's
+        # convention.
+        if q.ndim != 0:
+            result = np.rollaxis(result, axis)   
+
+    if out is not None:
+        out[...] = result
+    return result
+
+
+def _nanpercentile1d(arr1d, q, overwrite_input=False, interpolation='linear'):
+    """
+    Private function for rank 1 arrays. Compute percentile ignoring
+    NaNs.
+
+    See nanpercentile for parameter usage
+    """
+    c = np.isnan(arr1d)
+    s = np.where(c)[0]
+    if s.size == arr1d.size:
+        warnings.warn("All-NaN slice encountered", RuntimeWarning)
+        if q.ndim == 0:
+            return np.nan
+        else:
+            return np.nan * np.ones((len(q),))
+    elif s.size == 0:
+        return np.percentile(arr1d, q, overwrite_input=overwrite_input,
+                             interpolation=interpolation)
+    else:
+        if overwrite_input:
+            x = arr1d
+        else:
+            x = arr1d.copy()
+        # select non-nans at end of array
+        enonan = arr1d[-s.size:][~c[-s.size:]]
+        # fill nans in beginning of array with non-nans of end
+        x[s[:enonan.size]] = enonan
+        # slice nans away
+        return np.percentile(x[:-s.size], q, overwrite_input=True,
+                             interpolation=interpolation)
+
+
+def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the variance along the specified axis, while ignoring NaNs.
+
+    Returns the variance of the array elements, a measure of the spread of
+    a distribution.  The variance is computed for the flattened array by
+    default, otherwise over the specified axis.
+
+    For all-NaN slices or slices with zero degrees of freedom, NaN is
+    returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Array containing numbers whose variance is desired.  If `a` is not an
+        array, a conversion is attempted.
+    axis : int, optional
+        Axis along which the variance is computed.  The default is to compute
+        the variance of the flattened array.
+    dtype : data-type, optional
+        Type to use in computing the variance.  For arrays of integer type
+        the default is `float32`; for arrays of float types it is the same as
+        the array type.
+    out : ndarray, optional
+        Alternate output array in which to place the result.  It must have
+        the same shape as the expected output, but the type is cast if
+        necessary.
+    ddof : int, optional
+        "Delta Degrees of Freedom": the divisor used in the calculation is
+        ``N - ddof``, where ``N`` represents the number of non-NaN
+        elements. By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    variance : ndarray, see dtype parameter above
+        If `out` is None, return a new array containing the variance,
+        otherwise return a reference to the output array. If ddof is >= the
+        number of non-NaN elements in a slice or the slice contains only
+        NaNs, then the result for that slice is NaN.
+
+    See Also
+    --------
+    std : Standard deviation
+    mean : Average
+    var : Variance while not ignoring NaNs
+    nanstd, nanmean
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The variance is the average of the squared deviations from the mean,
+    i.e.,  ``var = mean(abs(x - x.mean())**2)``.
+
+    The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``.
+    If, however, `ddof` is specified, the divisor ``N - ddof`` is used
+    instead.  In standard statistical practice, ``ddof=1`` provides an
+    unbiased estimator of the variance of a hypothetical infinite
+    population.  ``ddof=0`` provides a maximum likelihood estimate of the
+    variance for normally distributed variables.
+
+    Note that for complex numbers, the absolute value is taken before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the variance is computed using the same
+    precision the input has.  Depending on the input data, this can cause
+    the results to be inaccurate, especially for `float32` (see example
+    below).  Specifying a higher-accuracy accumulator using the ``dtype``
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.var(a)
+    1.5555555555555554
+    >>> np.nanvar(a, axis=0)
+    array([ 1.,  0.])
+    >>> np.nanvar(a, axis=1)
+    array([ 0.,  0.25])
+
+    """
+    arr, mask = _replace_nan(a, 0)
+    if mask is None:
+        return np.var(arr, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                      keepdims=keepdims)
+
+    if dtype is not None:
+        dtype = np.dtype(dtype)
+    if dtype is not None and not issubclass(dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then dtype must be inexact")
+    if out is not None and not issubclass(out.dtype.type, np.inexact):
+        raise TypeError("If a is inexact, then out must be inexact")
+
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+
+        # Compute mean
+        cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=True)
+        avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=True)
+        avg = _divide_by_count(avg, cnt)
+
+        # Compute squared deviation from mean.
+        np.subtract(arr, avg, out=arr, casting='unsafe')
+        arr = _copyto(arr, 0, mask)
+        if issubclass(arr.dtype.type, np.complexfloating):
+            sqr = np.multiply(arr, arr.conj(), out=arr).real
+        else:
+            sqr = np.multiply(arr, arr, out=arr)
+
+        # Compute variance.
+        var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
+        if var.ndim < cnt.ndim:
+            # Subclasses of ndarray may ignore keepdims, so check here.
+            cnt = cnt.squeeze(axis)
+        dof = cnt - ddof
+        var = _divide_by_count(var, dof)
+
+    isbad = (dof <= 0)
+    if np.any(isbad):
+        warnings.warn("Degrees of freedom <= 0 for slice.", RuntimeWarning)
+        # NaN, inf, or negative numbers are all possible bad
+        # values, so explicitly replace them with NaN.
+        var = _copyto(var, np.nan, isbad)
+    return var
+
+
+def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
+    """
+    Compute the standard deviation along the specified axis, while
+    ignoring NaNs.
+
+    Returns the standard deviation, a measure of the spread of a
+    distribution, of the non-NaN array elements. The standard deviation is
+    computed for the flattened array by default, otherwise over the
+    specified axis.
+
+    For all-NaN slices or slices with zero degrees of freedom, NaN is
+    returned and a `RuntimeWarning` is raised.
+
+    .. versionadded:: 1.8.0
+
+    Parameters
+    ----------
+    a : array_like
+        Calculate the standard deviation of the non-NaN values.
+    axis : int, optional
+        Axis along which the standard deviation is computed. The default is
+        to compute the standard deviation of the flattened array.
+    dtype : dtype, optional
+        Type to use in computing the standard deviation. For arrays of
+        integer type the default is float64, for arrays of float types it
+        is the same as the array type.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must have
+        the same shape as the expected output but the type (of the
+        calculated values) will be cast if necessary.
+    ddof : int, optional
+        Means Delta Degrees of Freedom.  The divisor used in calculations
+        is ``N - ddof``, where ``N`` represents the number of non-NaN
+        elements.  By default `ddof` is zero.
+    keepdims : bool, optional
+        If this is set to True, the axes which are reduced are left
+        in the result as dimensions with size one. With this option,
+        the result will broadcast correctly against the original `arr`.
+
+    Returns
+    -------
+    standard_deviation : ndarray, see dtype parameter above.
+        If `out` is None, return a new array containing the standard
+        deviation, otherwise return a reference to the output array. If
+        ddof is >= the number of non-NaN elements in a slice or the slice
+        contains only NaNs, then the result for that slice is NaN.
+
+    See Also
+    --------
+    var, mean, std
+    nanvar, nanmean
+    numpy.doc.ufuncs : Section "Output arguments"
+
+    Notes
+    -----
+    The standard deviation is the square root of the average of the squared
+    deviations from the mean: ``std = sqrt(mean(abs(x - x.mean())**2))``.
+
+    The average squared deviation is normally calculated as
+    ``x.sum() / N``, where ``N = len(x)``.  If, however, `ddof` is
+    specified, the divisor ``N - ddof`` is used instead. In standard
+    statistical practice, ``ddof=1`` provides an unbiased estimator of the
+    variance of the infinite population. ``ddof=0`` provides a maximum
+    likelihood estimate of the variance for normally distributed variables.
+    The standard deviation computed in this function is the square root of
+    the estimated variance, so even with ``ddof=1``, it will not be an
+    unbiased estimate of the standard deviation per se.
+
+    Note that, for complex numbers, `std` takes the absolute value before
+    squaring, so that the result is always real and nonnegative.
+
+    For floating-point input, the *std* is computed using the same
+    precision the input has. Depending on the input data, this can cause
+    the results to be inaccurate, especially for float32 (see example
+    below).  Specifying a higher-accuracy accumulator using the `dtype`
+    keyword can alleviate this issue.
+
+    Examples
+    --------
+    >>> a = np.array([[1, np.nan], [3, 4]])
+    >>> np.nanstd(a)
+    1.247219128924647
+    >>> np.nanstd(a, axis=0)
+    array([ 1.,  0.])
+    >>> np.nanstd(a, axis=1)
+    array([ 0.,  0.5])
+
+    """
+    var = nanvar(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+                 keepdims=keepdims)
+    if isinstance(var, np.ndarray):
+        std = np.sqrt(var, out=var)
+    else:
+        std = var.dtype.type(np.sqrt(var))
+    return std
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/npyio.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/npyio.py
new file mode 100644
index 0000000000..640f4fa32d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/npyio.py
@@ -0,0 +1,1995 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import os
+import re
+import itertools
+import warnings
+import weakref
+from operator import itemgetter
+
+import numpy as np
+from . import format
+from ._datasource import DataSource
+from numpy.core.multiarray import packbits, unpackbits
+from ._iotools import (
+    LineSplitter, NameValidator, StringConverter, ConverterError,
+    ConverterLockError, ConversionWarning, _is_string_like, has_nested_fields,
+    flatten_dtype, easy_dtype, _bytes_to_name
+    )
+
+from numpy.compat import (
+    asbytes, asstr, asbytes_nested, bytes, basestring, unicode
+    )
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+    from future_builtins import map
+
+loads = pickle.loads
+
+__all__ = [
+    'savetxt', 'loadtxt', 'genfromtxt', 'ndfromtxt', 'mafromtxt',
+    'recfromtxt', 'recfromcsv', 'load', 'loads', 'save', 'savez',
+    'savez_compressed', 'packbits', 'unpackbits', 'fromregex', 'DataSource'
+    ]
+
+
+class BagObj(object):
+    """
+    BagObj(obj)
+
+    Convert attribute look-ups to getitems on the object passed in.
+
+    Parameters
+    ----------
+    obj : class instance
+        Object on which attribute look-up is performed.
+
+    Examples
+    --------
+    >>> from numpy.lib.npyio import BagObj as BO
+    >>> class BagDemo(object):
+    ...     def __getitem__(self, key): # An instance of BagObj(BagDemo)
+    ...                                 # will call this method when any
+    ...                                 # attribute look-up is required
+    ...         result = "Doesn't matter what you want, "
+    ...         return result + "you're gonna get this"
+    ...
+    >>> demo_obj = BagDemo()
+    >>> bagobj = BO(demo_obj)
+    >>> bagobj.hello_there
+    "Doesn't matter what you want, you're gonna get this"
+    >>> bagobj.I_can_be_anything
+    "Doesn't matter what you want, you're gonna get this"
+
+    """
+
+    def __init__(self, obj):
+        # Use weakref to make NpzFile objects collectable by refcount
+        self._obj = weakref.proxy(obj)
+
+    def __getattribute__(self, key):
+        try:
+            return object.__getattribute__(self, '_obj')[key]
+        except KeyError:
+            raise AttributeError(key)
+
+    def __dir__(self):
+        """
+        Enables dir(bagobj) to list the files in an NpzFile.
+
+        This also enables tab-completion in an interpreter or IPython.
+        """
+        return object.__getattribute__(self, '_obj').keys()
+
+
+def zipfile_factory(*args, **kwargs):
+    import zipfile
+    kwargs['allowZip64'] = True
+    return zipfile.ZipFile(*args, **kwargs)
+
+
+class NpzFile(object):
+    """
+    NpzFile(fid)
+
+    A dictionary-like object with lazy-loading of files in the zipped
+    archive provided on construction.
+
+    `NpzFile` is used to load files in the NumPy ``.npz`` data archive
+    format. It assumes that files in the archive have a ``.npy`` extension,
+    other files are ignored.
+
+    The arrays and file strings are lazily loaded on either
+    getitem access using ``obj['key']`` or attribute lookup using
+    ``obj.f.key``. A list of all files (without ``.npy`` extensions) can
+    be obtained with ``obj.files`` and the ZipFile object itself using
+    ``obj.zip``.
+
+    Attributes
+    ----------
+    files : list of str
+        List of all files in the archive with a ``.npy`` extension.
+    zip : ZipFile instance
+        The ZipFile object initialized with the zipped archive.
+    f : BagObj instance
+        An object on which attribute can be performed as an alternative
+        to getitem access on the `NpzFile` instance itself.
+    allow_pickle : bool, optional
+        Allow loading pickled data. Default: True
+    pickle_kwargs : dict, optional
+        Additional keyword arguments to pass on to pickle.load.
+        These are only useful when loading object arrays saved on
+        Python 2 when using Python 3.
+
+    Parameters
+    ----------
+    fid : file or str
+        The zipped archive to open. This is either a file-like object
+        or a string containing the path to the archive.
+    own_fid : bool, optional
+        Whether NpzFile should close the file handle.
+        Requires that `fid` is a file-like object.
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+    >>> x = np.arange(10)
+    >>> y = np.sin(x)
+    >>> np.savez(outfile, x=x, y=y)
+    >>> outfile.seek(0)
+
+    >>> npz = np.load(outfile)
+    >>> isinstance(npz, np.lib.io.NpzFile)
+    True
+    >>> npz.files
+    ['y', 'x']
+    >>> npz['x']  # getitem access
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+    >>> npz.f.x  # attribute lookup
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+
+    def __init__(self, fid, own_fid=False, allow_pickle=True,
+                 pickle_kwargs=None):
+        # Import is postponed to here since zipfile depends on gzip, an
+        # optional component of the so-called standard library.
+        _zip = zipfile_factory(fid)
+        self._files = _zip.namelist()
+        self.files = []
+        self.allow_pickle = allow_pickle
+        self.pickle_kwargs = pickle_kwargs
+        for x in self._files:
+            if x.endswith('.npy'):
+                self.files.append(x[:-4])
+            else:
+                self.files.append(x)
+        self.zip = _zip
+        self.f = BagObj(self)
+        if own_fid:
+            self.fid = fid
+        else:
+            self.fid = None
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.close()
+
+    def close(self):
+        """
+        Close the file.
+
+        """
+        if self.zip is not None:
+            self.zip.close()
+            self.zip = None
+        if self.fid is not None:
+            self.fid.close()
+            self.fid = None
+        self.f = None  # break reference cycle
+
+    def __del__(self):
+        self.close()
+
+    def __getitem__(self, key):
+        # FIXME: This seems like it will copy strings around
+        #   more than is strictly necessary.  The zipfile
+        #   will read the string and then
+        #   the format.read_array will copy the string
+        #   to another place in memory.
+        #   It would be better if the zipfile could read
+        #   (or at least uncompress) the data
+        #   directly into the array memory.
+        member = 0
+        if key in self._files:
+            member = 1
+        elif key in self.files:
+            member = 1
+            key += '.npy'
+        if member:
+            bytes = self.zip.open(key)
+            magic = bytes.read(len(format.MAGIC_PREFIX))
+            bytes.close()
+            if magic == format.MAGIC_PREFIX:
+                bytes = self.zip.open(key)
+                return format.read_array(bytes,
+                                         allow_pickle=self.allow_pickle,
+                                         pickle_kwargs=self.pickle_kwargs)
+            else:
+                return self.zip.read(key)
+        else:
+            raise KeyError("%s is not a file in the archive" % key)
+
+    def __iter__(self):
+        return iter(self.files)
+
+    def items(self):
+        """
+        Return a list of tuples, with each tuple (filename, array in file).
+
+        """
+        return [(f, self[f]) for f in self.files]
+
+    def iteritems(self):
+        """Generator that returns tuples (filename, array in file)."""
+        for f in self.files:
+            yield (f, self[f])
+
+    def keys(self):
+        """Return files in the archive with a ``.npy`` extension."""
+        return self.files
+
+    def iterkeys(self):
+        """Return an iterator over the files in the archive."""
+        return self.__iter__()
+
+    def __contains__(self, key):
+        return self.files.__contains__(key)
+
+
+def load(file, mmap_mode=None, allow_pickle=True, fix_imports=True,
+         encoding='ASCII'):
+    """
+    Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.
+
+    Parameters
+    ----------
+    file : file-like object or string
+        The file to read. File-like objects must support the
+        ``seek()`` and ``read()`` methods. Pickled files require that the
+        file-like object support the ``readline()`` method as well.
+    mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional
+        If not None, then memory-map the file, using the given mode (see
+        `numpy.memmap` for a detailed description of the modes).  A
+        memory-mapped array is kept on disk. However, it can be accessed
+        and sliced like any ndarray.  Memory mapping is especially useful
+        for accessing small fragments of large files without reading the
+        entire file into memory.
+    allow_pickle : bool, optional
+        Allow loading pickled object arrays stored in npy files. Reasons for
+        disallowing pickles include security, as loading pickled data can
+        execute arbitrary code. If pickles are disallowed, loading object
+        arrays will fail.
+        Default: True
+    fix_imports : bool, optional
+        Only useful when loading Python 2 generated pickled files on Python 3,
+        which includes npy/npz files containing object arrays. If `fix_imports`
+        is True, pickle will try to map the old Python 2 names to the new names
+        used in Python 3.
+    encoding : str, optional
+        What encoding to use when reading Python 2 strings. Only useful when
+        loading Python 2 generated pickled files on Python 3, which includes
+        npy/npz files containing object arrays. Values other than 'latin1',
+        'ASCII', and 'bytes' are not allowed, as they can corrupt numerical
+        data. Default: 'ASCII'
+
+    Returns
+    -------
+    result : array, tuple, dict, etc.
+        Data stored in the file. For ``.npz`` files, the returned instance
+        of NpzFile class must be closed to avoid leaking file descriptors.
+
+    Raises
+    ------
+    IOError
+        If the input file does not exist or cannot be read.
+    ValueError
+        The file contains an object array, but allow_pickle=False given.
+
+    See Also
+    --------
+    save, savez, savez_compressed, loadtxt
+    memmap : Create a memory-map to an array stored in a file on disk.
+
+    Notes
+    -----
+    - If the file contains pickle data, then whatever object is stored
+      in the pickle is returned.
+    - If the file is a ``.npy`` file, then a single array is returned.
+    - If the file is a ``.npz`` file, then a dictionary-like object is
+      returned, containing ``{filename: array}`` key-value pairs, one for
+      each file in the archive.
+    - If the file is a ``.npz`` file, the returned value supports the
+      context manager protocol in a similar fashion to the open function::
+
+        with load('foo.npz') as data:
+            a = data['a']
+
+      The underlying file descriptor is closed when exiting the 'with'
+      block.
+
+    Examples
+    --------
+    Store data to disk, and load it again:
+
+    >>> np.save('/tmp/123', np.array([[1, 2, 3], [4, 5, 6]]))
+    >>> np.load('/tmp/123.npy')
+    array([[1, 2, 3],
+           [4, 5, 6]])
+
+    Store compressed data to disk, and load it again:
+
+    >>> a=np.array([[1, 2, 3], [4, 5, 6]])
+    >>> b=np.array([1, 2])
+    >>> np.savez('/tmp/123.npz', a=a, b=b)
+    >>> data = np.load('/tmp/123.npz')
+    >>> data['a']
+    array([[1, 2, 3],
+           [4, 5, 6]])
+    >>> data['b']
+    array([1, 2])
+    >>> data.close()
+
+    Mem-map the stored array, and then access the second row
+    directly from disk:
+
+    >>> X = np.load('/tmp/123.npy', mmap_mode='r')
+    >>> X[1, :]
+    memmap([4, 5, 6])
+
+    """
+    import gzip
+
+    own_fid = False
+    if isinstance(file, basestring):
+        fid = open(file, "rb")
+        own_fid = True
+    else:
+        fid = file
+
+    if encoding not in ('ASCII', 'latin1', 'bytes'):
+        # The 'encoding' value for pickle also affects what encoding
+        # the serialized binary data of Numpy arrays is loaded
+        # in. Pickle does not pass on the encoding information to
+        # Numpy. The unpickling code in numpy.core.multiarray is
+        # written to assume that unicode data appearing where binary
+        # should be is in 'latin1'. 'bytes' is also safe, as is 'ASCII'.
+        #
+        # Other encoding values can corrupt binary data, and we
+        # purposefully disallow them. For the same reason, the errors=
+        # argument is not exposed, as values other than 'strict'
+        # result can similarly silently corrupt numerical data.
+        raise ValueError("encoding must be 'ASCII', 'latin1', or 'bytes'")
+
+    if sys.version_info[0] >= 3:
+        pickle_kwargs = dict(encoding=encoding, fix_imports=fix_imports)
+    else:
+        # Nothing to do on Python 2
+        pickle_kwargs = {}
+
+    try:
+        # Code to distinguish from NumPy binary files and pickles.
+        _ZIP_PREFIX = asbytes('PK\x03\x04')
+        N = len(format.MAGIC_PREFIX)
+        magic = fid.read(N)
+        fid.seek(-N, 1)  # back-up
+        if magic.startswith(_ZIP_PREFIX):
+            # zip-file (assume .npz)
+            # Transfer file ownership to NpzFile
+            tmp = own_fid
+            own_fid = False
+            return NpzFile(fid, own_fid=tmp, allow_pickle=allow_pickle,
+                           pickle_kwargs=pickle_kwargs)
+        elif magic == format.MAGIC_PREFIX:
+            # .npy file
+            if mmap_mode:
+                return format.open_memmap(file, mode=mmap_mode)
+            else:
+                return format.read_array(fid, allow_pickle=allow_pickle,
+                                         pickle_kwargs=pickle_kwargs)
+        else:
+            # Try a pickle
+            if not allow_pickle:
+                raise ValueError("allow_pickle=False, but file does not contain "
+                                 "non-pickled data")
+            try:
+                return pickle.load(fid, **pickle_kwargs)
+            except:
+                raise IOError(
+                    "Failed to interpret file %s as a pickle" % repr(file))
+    finally:
+        if own_fid:
+            fid.close()
+
+
+def save(file, arr, allow_pickle=True, fix_imports=True):
+    """
+    Save an array to a binary file in NumPy ``.npy`` format.
+
+    Parameters
+    ----------
+    file : file or str
+        File or filename to which the data is saved.  If file is a file-object,
+        then the filename is unchanged.  If file is a string, a ``.npy``
+        extension will be appended to the file name if it does not already
+        have one.
+    allow_pickle : bool, optional
+        Allow saving object arrays using Python pickles. Reasons for disallowing
+        pickles include security (loading pickled data can execute arbitrary
+        code) and portability (pickled objects may not be loadable on different
+        Python installations, for example if the stored objects require libraries
+        that are not available, and not all pickled data is compatible between
+        Python 2 and Python 3).
+        Default: True
+    fix_imports : bool, optional
+        Only useful in forcing objects in object arrays on Python 3 to be
+        pickled in a Python 2 compatible way. If `fix_imports` is True, pickle
+        will try to map the new Python 3 names to the old module names used in
+        Python 2, so that the pickle data stream is readable with Python 2.
+    arr : array_like
+        Array data to be saved.
+
+    See Also
+    --------
+    savez : Save several arrays into a ``.npz`` archive
+    savetxt, load
+
+    Notes
+    -----
+    For a description of the ``.npy`` format, see the module docstring
+    of `numpy.lib.format` or the Numpy Enhancement Proposal
+    http://docs.scipy.org/doc/numpy/neps/npy-format.html
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+
+    >>> x = np.arange(10)
+    >>> np.save(outfile, x)
+
+    >>> outfile.seek(0) # Only needed here to simulate closing & reopening file
+    >>> np.load(outfile)
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+    own_fid = False
+    if isinstance(file, basestring):
+        if not file.endswith('.npy'):
+            file = file + '.npy'
+        fid = open(file, "wb")
+        own_fid = True
+    else:
+        fid = file
+
+    if sys.version_info[0] >= 3:
+        pickle_kwargs = dict(fix_imports=fix_imports)
+    else:
+        # Nothing to do on Python 2
+        pickle_kwargs = None
+
+    try:
+        arr = np.asanyarray(arr)
+        format.write_array(fid, arr, allow_pickle=allow_pickle,
+                           pickle_kwargs=pickle_kwargs)
+    finally:
+        if own_fid:
+            fid.close()
+
+
+def savez(file, *args, **kwds):
+    """
+    Save several arrays into a single file in uncompressed ``.npz`` format.
+
+    If arguments are passed in with no keywords, the corresponding variable
+    names, in the ``.npz`` file, are 'arr_0', 'arr_1', etc. If keyword
+    arguments are given, the corresponding variable names, in the ``.npz``
+    file will match the keyword names.
+
+    Parameters
+    ----------
+    file : str or file
+        Either the file name (string) or an open file (file-like object)
+        where the data will be saved. If file is a string, the ``.npz``
+        extension will be appended to the file name if it is not already there.
+    args : Arguments, optional
+        Arrays to save to the file. Since it is not possible for Python to
+        know the names of the arrays outside `savez`, the arrays will be saved
+        with names "arr_0", "arr_1", and so on. These arguments can be any
+        expression.
+    kwds : Keyword arguments, optional
+        Arrays to save to the file. Arrays will be saved in the file with the
+        keyword names.
+
+    Returns
+    -------
+    None
+
+    See Also
+    --------
+    save : Save a single array to a binary file in NumPy format.
+    savetxt : Save an array to a file as plain text.
+    savez_compressed : Save several arrays into a compressed ``.npz`` archive
+
+    Notes
+    -----
+    The ``.npz`` file format is a zipped archive of files named after the
+    variables they contain.  The archive is not compressed and each file
+    in the archive contains one variable in ``.npy`` format. For a
+    description of the ``.npy`` format, see `numpy.lib.format` or the
+    Numpy Enhancement Proposal
+    http://docs.scipy.org/doc/numpy/neps/npy-format.html
+
+    When opening the saved ``.npz`` file with `load` a `NpzFile` object is
+    returned. This is a dictionary-like object which can be queried for
+    its list of arrays (with the ``.files`` attribute), and for the arrays
+    themselves.
+
+    Examples
+    --------
+    >>> from tempfile import TemporaryFile
+    >>> outfile = TemporaryFile()
+    >>> x = np.arange(10)
+    >>> y = np.sin(x)
+
+    Using `savez` with \\*args, the arrays are saved with default names.
+
+    >>> np.savez(outfile, x, y)
+    >>> outfile.seek(0) # Only needed here to simulate closing & reopening file
+    >>> npzfile = np.load(outfile)
+    >>> npzfile.files
+    ['arr_1', 'arr_0']
+    >>> npzfile['arr_0']
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    Using `savez` with \\**kwds, the arrays are saved with the keyword names.
+
+    >>> outfile = TemporaryFile()
+    >>> np.savez(outfile, x=x, y=y)
+    >>> outfile.seek(0)
+    >>> npzfile = np.load(outfile)
+    >>> npzfile.files
+    ['y', 'x']
+    >>> npzfile['x']
+    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+    """
+    _savez(file, args, kwds, False)
+
+
+def savez_compressed(file, *args, **kwds):
+    """
+    Save several arrays into a single file in compressed ``.npz`` format.
+
+    If keyword arguments are given, then filenames are taken from the keywords.
+    If arguments are passed in with no keywords, then stored file names are
+    arr_0, arr_1, etc.
+
+    Parameters
+    ----------
+    file : str
+        File name of ``.npz`` file.
+    args : Arguments
+        Function arguments.
+    kwds : Keyword arguments
+        Keywords.
+
+    See Also
+    --------
+    numpy.savez : Save several arrays into an uncompressed ``.npz`` file format
+    numpy.load : Load the files created by savez_compressed.
+
+    """
+    _savez(file, args, kwds, True)
+
+
+def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None):
+    # Import is postponed to here since zipfile depends on gzip, an optional
+    # component of the so-called standard library.
+    import zipfile
+    # Import deferred for startup time improvement
+    import tempfile
+
+    if isinstance(file, basestring):
+        if not file.endswith('.npz'):
+            file = file + '.npz'
+
+    namedict = kwds
+    for i, val in enumerate(args):
+        key = 'arr_%d' % i
+        if key in namedict.keys():
+            raise ValueError(
+                "Cannot use un-named variables and keyword %s" % key)
+        namedict[key] = val
+
+    if compress:
+        compression = zipfile.ZIP_DEFLATED
+    else:
+        compression = zipfile.ZIP_STORED
+
+    zipf = zipfile_factory(file, mode="w", compression=compression)
+
+    # Stage arrays in a temporary file on disk, before writing to zip.
+    fd, tmpfile = tempfile.mkstemp(suffix='-numpy.npy')
+    os.close(fd)
+    try:
+        for key, val in namedict.items():
+            fname = key + '.npy'
+            fid = open(tmpfile, 'wb')
+            try:
+                format.write_array(fid, np.asanyarray(val),
+                                   allow_pickle=allow_pickle,
+                                   pickle_kwargs=pickle_kwargs)
+                fid.close()
+                fid = None
+                zipf.write(tmpfile, arcname=fname)
+            finally:
+                if fid:
+                    fid.close()
+    finally:
+        os.remove(tmpfile)
+
+    zipf.close()
+
+
+def _getconv(dtype):
+    """ Find the correct dtype converter. Adapted from matplotlib """
+
+    def floatconv(x):
+        x.lower()
+        if b'0x' in x:
+            return float.fromhex(asstr(x))
+        return float(x)
+
+    typ = dtype.type
+    if issubclass(typ, np.bool_):
+        return lambda x: bool(int(x))
+    if issubclass(typ, np.uint64):
+        return np.uint64
+    if issubclass(typ, np.int64):
+        return np.int64
+    if issubclass(typ, np.integer):
+        return lambda x: int(float(x))
+    elif issubclass(typ, np.longdouble):
+        return np.longdouble
+    elif issubclass(typ, np.floating):
+        return floatconv
+    elif issubclass(typ, np.complex):
+        return lambda x: complex(asstr(x))
+    elif issubclass(typ, np.bytes_):
+        return bytes
+    else:
+        return str
+
+
+def loadtxt(fname, dtype=float, comments='#', delimiter=None,
+            converters=None, skiprows=0, usecols=None, unpack=False,
+            ndmin=0):
+    """
+    Load data from a text file.
+
+    Each row in the text file must have the same number of values.
+
+    Parameters
+    ----------
+    fname : file or str
+        File, filename, or generator to read.  If the filename extension is
+        ``.gz`` or ``.bz2``, the file is first decompressed. Note that
+        generators should return byte strings for Python 3k.
+    dtype : data-type, optional
+        Data-type of the resulting array; default: float.  If this is a
+        structured data-type, the resulting array will be 1-dimensional, and
+        each row will be interpreted as an element of the array.  In this
+        case, the number of columns used must match the number of fields in
+        the data-type.
+    comments : str or sequence, optional
+        The characters or list of characters used to indicate the start of a
+        comment;
+        default: '#'.
+    delimiter : str, optional
+        The string used to separate values.  By default, this is any
+        whitespace.
+    converters : dict, optional
+        A dictionary mapping column number to a function that will convert
+        that column to a float.  E.g., if column 0 is a date string:
+        ``converters = {0: datestr2num}``.  Converters can also be used to
+        provide a default value for missing data (but see also `genfromtxt`):
+        ``converters = {3: lambda s: float(s.strip() or 0)}``.  Default: None.
+    skiprows : int, optional
+        Skip the first `skiprows` lines; default: 0.
+    usecols : sequence, optional
+        Which columns to read, with 0 being the first.  For example,
+        ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
+        The default, None, results in all columns being read.
+    unpack : bool, optional
+        If True, the returned array is transposed, so that arguments may be
+        unpacked using ``x, y, z = loadtxt(...)``.  When used with a structured
+        data-type, arrays are returned for each field.  Default is False.
+    ndmin : int, optional
+        The returned array will have at least `ndmin` dimensions.
+        Otherwise mono-dimensional axes will be squeezed.
+        Legal values: 0 (default), 1 or 2.
+
+        .. versionadded:: 1.6.0
+
+    Returns
+    -------
+    out : ndarray
+        Data read from the text file.
+
+    See Also
+    --------
+    load, fromstring, fromregex
+    genfromtxt : Load data with missing values handled as specified.
+    scipy.io.loadmat : reads MATLAB data files
+
+    Notes
+    -----
+    This function aims to be a fast reader for simply formatted files.  The
+    `genfromtxt` function provides more sophisticated handling of, e.g.,
+    lines with missing values.
+
+    .. versionadded:: 1.10.0
+
+    The strings produced by the Python float.hex method can be used as
+    input for floats.
+
+    Examples
+    --------
+    >>> from io import StringIO   # StringIO behaves like a file object
+    >>> c = StringIO("0 1\\n2 3")
+    >>> np.loadtxt(c)
+    array([[ 0.,  1.],
+           [ 2.,  3.]])
+
+    >>> d = StringIO("M 21 72\\nF 35 58")
+    >>> np.loadtxt(d, dtype={'names': ('gender', 'age', 'weight'),
+    ...                      'formats': ('S1', 'i4', 'f4')})
+    array([('M', 21, 72.0), ('F', 35, 58.0)],
+          dtype=[('gender', '|S1'), ('age', '<i4'), ('weight', '<f4')])
+
+    >>> c = StringIO("1,0,2\\n3,0,4")
+    >>> x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True)
+    >>> x
+    array([ 1.,  3.])
+    >>> y
+    array([ 2.,  4.])
+
+    """
+    # Type conversions for Py3 convenience
+    if comments is not None:
+        if isinstance(comments, (basestring, bytes)):
+            comments = [asbytes(comments)]
+        else:
+            comments = [asbytes(comment) for comment in comments]
+
+        # Compile regex for comments beforehand
+        comments = (re.escape(comment) for comment in comments)
+        regex_comments = re.compile(asbytes('|').join(comments))
+    user_converters = converters
+    if delimiter is not None:
+        delimiter = asbytes(delimiter)
+    if usecols is not None:
+        usecols = list(usecols)
+
+    fown = False
+    try:
+        if _is_string_like(fname):
+            fown = True
+            if fname.endswith('.gz'):
+                import gzip
+                fh = iter(gzip.GzipFile(fname))
+            elif fname.endswith('.bz2'):
+                import bz2
+                fh = iter(bz2.BZ2File(fname))
+            elif sys.version_info[0] == 2:
+                fh = iter(open(fname, 'U'))
+            else:
+                fh = iter(open(fname))
+        else:
+            fh = iter(fname)
+    except TypeError:
+        raise ValueError('fname must be a string, file handle, or generator')
+    X = []
+
+    def flatten_dtype(dt):
+        """Unpack a structured data-type, and produce re-packing info."""
+        if dt.names is None:
+            # If the dtype is flattened, return.
+            # If the dtype has a shape, the dtype occurs
+            # in the list more than once.
+            shape = dt.shape
+            if len(shape) == 0:
+                return ([dt.base], None)
+            else:
+                packing = [(shape[-1], list)]
+                if len(shape) > 1:
+                    for dim in dt.shape[-2::-1]:
+                        packing = [(dim*packing[0][0], packing*dim)]
+                return ([dt.base] * int(np.prod(dt.shape)), packing)
+        else:
+            types = []
+            packing = []
+            for field in dt.names:
+                tp, bytes = dt.fields[field]
+                flat_dt, flat_packing = flatten_dtype(tp)
+                types.extend(flat_dt)
+                # Avoid extra nesting for subarrays
+                if len(tp.shape) > 0:
+                    packing.extend(flat_packing)
+                else:
+                    packing.append((len(flat_dt), flat_packing))
+            return (types, packing)
+
+    def pack_items(items, packing):
+        """Pack items into nested lists based on re-packing info."""
+        if packing is None:
+            return items[0]
+        elif packing is tuple:
+            return tuple(items)
+        elif packing is list:
+            return list(items)
+        else:
+            start = 0
+            ret = []
+            for length, subpacking in packing:
+                ret.append(pack_items(items[start:start+length], subpacking))
+                start += length
+            return tuple(ret)
+
+    def split_line(line):
+        """Chop off comments, strip, and split at delimiter.
+
+        Note that although the file is opened as text, this function
+        returns bytes.
+
+        """
+        line = asbytes(line)
+        if comments is not None:
+            line = regex_comments.split(asbytes(line), maxsplit=1)[0]
+        line = line.strip(asbytes('\r\n'))
+        if line:
+            return line.split(delimiter)
+        else:
+            return []
+
+    try:
+        # Make sure we're dealing with a proper dtype
+        dtype = np.dtype(dtype)
+        defconv = _getconv(dtype)
+
+        # Skip the first `skiprows` lines
+        for i in range(skiprows):
+            next(fh)
+
+        # Read until we find a line with some values, and use
+        # it to estimate the number of columns, N.
+        first_vals = None
+        try:
+            while not first_vals:
+                first_line = next(fh)
+                first_vals = split_line(first_line)
+        except StopIteration:
+            # End of lines reached
+            first_line = ''
+            first_vals = []
+            warnings.warn('loadtxt: Empty input file: "%s"' % fname)
+        N = len(usecols or first_vals)
+
+        dtype_types, packing = flatten_dtype(dtype)
+        if len(dtype_types) > 1:
+            # We're dealing with a structured array, each field of
+            # the dtype matches a column
+            converters = [_getconv(dt) for dt in dtype_types]
+        else:
+            # All fields have the same dtype
+            converters = [defconv for i in range(N)]
+            if N > 1:
+                packing = [(N, tuple)]
+
+        # By preference, use the converters specified by the user
+        for i, conv in (user_converters or {}).items():
+            if usecols:
+                try:
+                    i = usecols.index(i)
+                except ValueError:
+                    # Unused converter specified
+                    continue
+            converters[i] = conv
+
+        # Parse each line, including the first
+        for i, line in enumerate(itertools.chain([first_line], fh)):
+            vals = split_line(line)
+            if len(vals) == 0:
+                continue
+            if usecols:
+                vals = [vals[i] for i in usecols]
+            if len(vals) != N:
+                line_num = i + skiprows + 1
+                raise ValueError("Wrong number of columns at line %d"
+                                 % line_num)
+
+            # Convert each value according to its column and store
+            items = [conv(val) for (conv, val) in zip(converters, vals)]
+            # Then pack it according to the dtype's nesting
+            items = pack_items(items, packing)
+            X.append(items)
+    finally:
+        if fown:
+            fh.close()
+
+    X = np.array(X, dtype)
+    # Multicolumn data are returned with shape (1, N, M), i.e.
+    # (1, 1, M) for a single row - remove the singleton dimension there
+    if X.ndim == 3 and X.shape[:2] == (1, 1):
+        X.shape = (1, -1)
+
+    # Verify that the array has at least dimensions `ndmin`.
+    # Check correctness of the values of `ndmin`
+    if ndmin not in [0, 1, 2]:
+        raise ValueError('Illegal value of ndmin keyword: %s' % ndmin)
+    # Tweak the size and shape of the arrays - remove extraneous dimensions
+    if X.ndim > ndmin:
+        X = np.squeeze(X)
+    # and ensure we have the minimum number of dimensions asked for
+    # - has to be in this order for the odd case ndmin=1, X.squeeze().ndim=0
+    if X.ndim < ndmin:
+        if ndmin == 1:
+            X = np.atleast_1d(X)
+        elif ndmin == 2:
+            X = np.atleast_2d(X).T
+
+    if unpack:
+        if len(dtype_types) > 1:
+            # For structured arrays, return an array for each field.
+            return [X[field] for field in dtype.names]
+        else:
+            return X.T
+    else:
+        return X
+
+
+def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='',
+            footer='', comments='# '):
+    """
+    Save an array to a text file.
+
+    Parameters
+    ----------
+    fname : filename or file handle
+        If the filename ends in ``.gz``, the file is automatically saved in
+        compressed gzip format.  `loadtxt` understands gzipped files
+        transparently.
+    X : array_like
+        Data to be saved to a text file.
+    fmt : str or sequence of strs, optional
+        A single format (%10.5f), a sequence of formats, or a
+        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 %+.4j %.4e %+.4j %.4e %+.4j'` 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
+    delimiter : str, optional
+        String or character separating columns.
+    newline : str, optional
+        String or character separating lines.
+
+        .. versionadded:: 1.5.0
+    header : str, optional
+        String that will be written at the beginning of the file.
+
+        .. versionadded:: 1.7.0
+    footer : str, optional
+        String that will be written at the end of the file.
+
+        .. versionadded:: 1.7.0
+    comments : str, optional
+        String that will be prepended to the ``header`` and ``footer`` strings,
+        to mark them as comments. Default: '# ',  as expected by e.g.
+        ``numpy.loadtxt``.
+
+        .. versionadded:: 1.7.0
+
+
+    See Also
+    --------
+    save : Save an array to a binary file in NumPy ``.npy`` format
+    savez : Save several arrays into an uncompressed ``.npz`` archive
+    savez_compressed : Save several arrays into a compressed ``.npz`` archive
+
+    Notes
+    -----
+    Further explanation of the `fmt` parameter
+    (``%[flag]width[.precision]specifier``):
+
+    flags:
+        ``-`` : left justify
+
+        ``+`` : Forces to precede result with + or -.
+
+        ``0`` : Left pad the number with zeros instead of space (see width).
+
+    width:
+        Minimum number of characters to be printed. The value is not truncated
+        if it has more characters.
+
+    precision:
+        - For integer specifiers (eg. ``d,i,o,x``), the minimum number of
+          digits.
+        - For ``e, E`` and ``f`` specifiers, the number of digits to print
+          after the decimal point.
+        - For ``g`` and ``G``, the maximum number of significant digits.
+        - For ``s``, the maximum number of characters.
+
+    specifiers:
+        ``c`` : character
+
+        ``d`` or ``i`` : signed decimal integer
+
+        ``e`` or ``E`` : scientific notation with ``e`` or ``E``.
+
+        ``f`` : decimal floating point
+
+        ``g,G`` : use the shorter of ``e,E`` or ``f``
+
+        ``o`` : signed octal
+
+        ``s`` : string of characters
+
+        ``u`` : unsigned decimal integer
+
+        ``x,X`` : unsigned hexadecimal integer
+
+    This explanation of ``fmt`` is not complete, for an exhaustive
+    specification see [1]_.
+
+    References
+    ----------
+    .. [1] `Format Specification Mini-Language
+           <http://docs.python.org/library/string.html#
+           format-specification-mini-language>`_, Python Documentation.
+
+    Examples
+    --------
+    >>> x = y = z = np.arange(0.0,5.0,1.0)
+    >>> np.savetxt('test.out', x, delimiter=',')   # X is an array
+    >>> np.savetxt('test.out', (x,y,z))   # x,y,z equal sized 1D arrays
+    >>> np.savetxt('test.out', x, fmt='%1.4e')   # use exponential notation
+
+    """
+
+    # Py3 conversions first
+    if isinstance(fmt, bytes):
+        fmt = asstr(fmt)
+    delimiter = asstr(delimiter)
+
+    own_fh = False
+    if _is_string_like(fname):
+        own_fh = True
+        if fname.endswith('.gz'):
+            import gzip
+            fh = gzip.open(fname, 'wb')
+        else:
+            if sys.version_info[0] >= 3:
+                fh = open(fname, 'wb')
+            else:
+                fh = open(fname, 'w')
+    elif hasattr(fname, 'write'):
+        fh = fname
+    else:
+        raise ValueError('fname must be a string or file handle')
+
+    try:
+        X = np.asarray(X)
+
+        # Handle 1-dimensional arrays
+        if X.ndim == 1:
+            # Common case -- 1d array of numbers
+            if X.dtype.names is None:
+                X = np.atleast_2d(X).T
+                ncol = 1
+
+            # Complex dtype -- each field indicates a separate column
+            else:
+                ncol = len(X.dtype.descr)
+        else:
+            ncol = X.shape[1]
+
+        iscomplex_X = np.iscomplexobj(X)
+        # `fmt` can be a string with multiple insertion points or a
+        # list of formats.  E.g. '%10.5f\t%10d' or ('%10.5f', '$10d')
+        if type(fmt) in (list, tuple):
+            if len(fmt) != ncol:
+                raise AttributeError('fmt has wrong shape.  %s' % str(fmt))
+            format = asstr(delimiter).join(map(asstr, fmt))
+        elif isinstance(fmt, str):
+            n_fmt_chars = fmt.count('%')
+            error = ValueError('fmt has wrong number of %% formats:  %s' % fmt)
+            if n_fmt_chars == 1:
+                if iscomplex_X:
+                    fmt = [' (%s+%sj)' % (fmt, fmt), ] * ncol
+                else:
+                    fmt = [fmt, ] * ncol
+                format = delimiter.join(fmt)
+            elif iscomplex_X and n_fmt_chars != (2 * ncol):
+                raise error
+            elif ((not iscomplex_X) and n_fmt_chars != ncol):
+                raise error
+            else:
+                format = fmt
+        else:
+            raise ValueError('invalid fmt: %r' % (fmt,))
+
+        if len(header) > 0:
+            header = header.replace('\n', '\n' + comments)
+            fh.write(asbytes(comments + header + newline))
+        if iscomplex_X:
+            for row in X:
+                row2 = []
+                for number in row:
+                    row2.append(number.real)
+                    row2.append(number.imag)
+                fh.write(asbytes(format % tuple(row2) + newline))
+        else:
+            for row in X:
+                try:
+                    fh.write(asbytes(format % tuple(row) + newline))
+                except TypeError:
+                    raise TypeError("Mismatch between array dtype ('%s') and "
+                                    "format specifier ('%s')"
+                                    % (str(X.dtype), format))
+        if len(footer) > 0:
+            footer = footer.replace('\n', '\n' + comments)
+            fh.write(asbytes(comments + footer + newline))
+    finally:
+        if own_fh:
+            fh.close()
+
+
+def fromregex(file, regexp, dtype):
+    """
+    Construct an array from a text file, using regular expression parsing.
+
+    The returned array is always a structured array, and is constructed from
+    all matches of the regular expression in the file. Groups in the regular
+    expression are converted to fields of the structured array.
+
+    Parameters
+    ----------
+    file : str or file
+        File name or file object to read.
+    regexp : str or regexp
+        Regular expression used to parse the file.
+        Groups in the regular expression correspond to fields in the dtype.
+    dtype : dtype or list of dtypes
+        Dtype for the structured array.
+
+    Returns
+    -------
+    output : ndarray
+        The output array, containing the part of the content of `file` that
+        was matched by `regexp`. `output` is always a structured array.
+
+    Raises
+    ------
+    TypeError
+        When `dtype` is not a valid dtype for a structured array.
+
+    See Also
+    --------
+    fromstring, loadtxt
+
+    Notes
+    -----
+    Dtypes for structured arrays can be specified in several forms, but all
+    forms specify at least the data type and field name. For details see
+    `doc.structured_arrays`.
+
+    Examples
+    --------
+    >>> f = open('test.dat', 'w')
+    >>> f.write("1312 foo\\n1534  bar\\n444   qux")
+    >>> f.close()
+
+    >>> regexp = r"(\\d+)\\s+(...)"  # match [digits, whitespace, anything]
+    >>> output = np.fromregex('test.dat', regexp,
+    ...                       [('num', np.int64), ('key', 'S3')])
+    >>> output
+    array([(1312L, 'foo'), (1534L, 'bar'), (444L, 'qux')],
+          dtype=[('num', '<i8'), ('key', '|S3')])
+    >>> output['num']
+    array([1312, 1534,  444], dtype=int64)
+
+    """
+    own_fh = False
+    if not hasattr(file, "read"):
+        file = open(file, 'rb')
+        own_fh = True
+
+    try:
+        if not hasattr(regexp, 'match'):
+            regexp = re.compile(asbytes(regexp))
+        if not isinstance(dtype, np.dtype):
+            dtype = np.dtype(dtype)
+
+        seq = regexp.findall(file.read())
+        if seq and not isinstance(seq[0], tuple):
+            # Only one group is in the regexp.
+            # Create the new array as a single data-type and then
+            #   re-interpret as a single-field structured array.
+            newdtype = np.dtype(dtype[dtype.names[0]])
+            output = np.array(seq, dtype=newdtype)
+            output.dtype = dtype
+        else:
+            output = np.array(seq, dtype=dtype)
+
+        return output
+    finally:
+        if own_fh:
+            file.close()
+
+
+#####--------------------------------------------------------------------------
+#---- --- ASCII functions ---
+#####--------------------------------------------------------------------------
+
+
+def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
+               skip_header=0, skip_footer=0, converters=None,
+               missing_values=None, filling_values=None, usecols=None,
+               names=None, excludelist=None, deletechars=None,
+               replace_space='_', autostrip=False, case_sensitive=True,
+               defaultfmt="f%i", unpack=None, usemask=False, loose=True,
+               invalid_raise=True, max_rows=None):
+    """
+    Load data from a text file, with missing values handled as specified.
+
+    Each line past the first `skip_header` lines is split at the `delimiter`
+    character, and characters following the `comments` character are discarded.
+
+    Parameters
+    ----------
+    fname : file, str, list of str, generator
+        File, filename, list, or generator to read.  If the filename
+        extension is `.gz` or `.bz2`, the file is first decompressed. Mote
+        that generators must return byte strings in Python 3k.  The strings
+        in a list or produced by a generator are treated as lines.
+    dtype : dtype, optional
+        Data type of the resulting array.
+        If None, the dtypes will be determined by the contents of each
+        column, individually.
+    comments : str, optional
+        The character used to indicate the start of a comment.
+        All the characters occurring on a line after a comment are discarded
+    delimiter : str, int, or sequence, optional
+        The string used to separate values.  By default, any consecutive
+        whitespaces act as delimiter.  An integer or sequence of integers
+        can also be provided as width(s) of each field.
+    skiprows : int, optional
+        `skiprows` was removed in numpy 1.10. Please use `skip_header` instead.
+    skip_header : int, optional
+        The number of lines to skip at the beginning of the file.
+    skip_footer : int, optional
+        The number of lines to skip at the end of the file.
+    converters : variable, optional
+        The set of functions that convert the data of a column to a value.
+        The converters can also be used to provide a default value
+        for missing data: ``converters = {3: lambda s: float(s or 0)}``.
+    missing : variable, optional
+        `missing` was removed in numpy 1.10. Please use `missing_values`
+        instead.
+    missing_values : variable, optional
+        The set of strings corresponding to missing data.
+    filling_values : variable, optional
+        The set of values to be used as default when the data are missing.
+    usecols : sequence, optional
+        Which columns to read, with 0 being the first.  For example,
+        ``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns.
+    names : {None, True, str, sequence}, optional
+        If `names` is True, the field names are read from the first valid line
+        after the first `skip_header` lines.
+        If `names` is a sequence or a single-string of comma-separated names,
+        the names will be used to define the field names in a structured dtype.
+        If `names` is None, the names of the dtype fields will be used, if any.
+    excludelist : sequence, optional
+        A list of names to exclude. This list is appended to the default list
+        ['return','file','print']. Excluded names are appended an underscore:
+        for example, `file` would become `file_`.
+    deletechars : str, optional
+        A string combining invalid characters that must be deleted from the
+        names.
+    defaultfmt : str, optional
+        A format used to define default field names, such as "f%i" or "f_%02i".
+    autostrip : bool, optional
+        Whether to automatically strip white spaces from the variables.
+    replace_space : char, optional
+        Character(s) used in replacement of white spaces in the variables
+        names. By default, use a '_'.
+    case_sensitive : {True, False, 'upper', 'lower'}, optional
+        If True, field names are case sensitive.
+        If False or 'upper', field names are converted to upper case.
+        If 'lower', field names are converted to lower case.
+    unpack : bool, optional
+        If True, the returned array is transposed, so that arguments may be
+        unpacked using ``x, y, z = loadtxt(...)``
+    usemask : bool, optional
+        If True, return a masked array.
+        If False, return a regular array.
+    loose : bool, optional
+        If True, do not raise errors for invalid values.
+    invalid_raise : bool, optional
+        If True, an exception is raised if an inconsistency is detected in the
+        number of columns.
+        If False, a warning is emitted and the offending lines are skipped.
+    max_rows : int,  optional
+        The maximum number of rows to read. Must not be used with skip_footer
+        at the same time.  If given, the value must be at least 1. Default is
+        to read the entire file.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    out : ndarray
+        Data read from the text file. If `usemask` is True, this is a
+        masked array.
+
+    See Also
+    --------
+    numpy.loadtxt : equivalent function when no data is missing.
+
+    Notes
+    -----
+    * When spaces are used as delimiters, or when no delimiter has been given
+      as input, there should not be any missing data between two fields.
+    * When the variables are named (either by a flexible dtype or with `names`,
+      there must not be any header in the file (else a ValueError
+      exception is raised).
+    * Individual values are not stripped of spaces by default.
+      When using a custom converter, make sure the function does remove spaces.
+
+    References
+    ----------
+    .. [1] Numpy User Guide, section `I/O with Numpy
+           <http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html>`_.
+
+    Examples
+    ---------
+    >>> from io import StringIO
+    >>> import numpy as np
+
+    Comma delimited file with mixed dtype
+
+    >>> s = StringIO("1,1.3,abcde")
+    >>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
+    ... ('mystring','S5')], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    Using dtype = None
+
+    >>> s.seek(0) # needed for StringIO example only
+    >>> data = np.genfromtxt(s, dtype=None,
+    ... names = ['myint','myfloat','mystring'], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    Specifying dtype and names
+
+    >>> s.seek(0)
+    >>> data = np.genfromtxt(s, dtype="i8,f8,S5",
+    ... names=['myint','myfloat','mystring'], delimiter=",")
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
+
+    An example with fixed-width columns
+
+    >>> s = StringIO("11.3abcde")
+    >>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'],
+    ...     delimiter=[1,3,5])
+    >>> data
+    array((1, 1.3, 'abcde'),
+          dtype=[('intvar', '<i8'), ('fltvar', '<f8'), ('strvar', '|S5')])
+
+    """
+    if max_rows is not None:
+        if skip_footer:
+            raise ValueError(
+                    "The keywords 'skip_footer' and 'max_rows' can not be "
+                    "specified at the same time.")
+        if max_rows < 1:
+            raise ValueError("'max_rows' must be at least 1.")
+
+    # Py3 data conversions to bytes, for convenience
+    if comments is not None:
+        comments = asbytes(comments)
+    if isinstance(delimiter, unicode):
+        delimiter = asbytes(delimiter)
+    if isinstance(missing_values, (unicode, list, tuple)):
+        missing_values = asbytes_nested(missing_values)
+
+    #
+    if usemask:
+        from numpy.ma import MaskedArray, make_mask_descr
+    # Check the input dictionary of converters
+    user_converters = converters or {}
+    if not isinstance(user_converters, dict):
+        raise TypeError(
+            "The input argument 'converter' should be a valid dictionary "
+            "(got '%s' instead)" % type(user_converters))
+
+    # Initialize the filehandle, the LineSplitter and the NameValidator
+    own_fhd = False
+    try:
+        if isinstance(fname, basestring):
+            if sys.version_info[0] == 2:
+                fhd = iter(np.lib._datasource.open(fname, 'rbU'))
+            else:
+                fhd = iter(np.lib._datasource.open(fname, 'rb'))
+            own_fhd = True
+        else:
+            fhd = iter(fname)
+    except TypeError:
+        raise TypeError(
+            "fname must be a string, filehandle, list of strings, "
+            "or generator. Got %s instead." % type(fname))
+
+    split_line = LineSplitter(delimiter=delimiter, comments=comments,
+                              autostrip=autostrip)._handyman
+    validate_names = NameValidator(excludelist=excludelist,
+                                   deletechars=deletechars,
+                                   case_sensitive=case_sensitive,
+                                   replace_space=replace_space)
+
+    # Skip the first `skip_header` rows
+    for i in range(skip_header):
+        next(fhd)
+
+    # Keep on until we find the first valid values
+    first_values = None
+    try:
+        while not first_values:
+            first_line = next(fhd)
+            if names is True:
+                if comments in first_line:
+                    first_line = (
+                        asbytes('').join(first_line.split(comments)[1:]))
+            first_values = split_line(first_line)
+    except StopIteration:
+        # return an empty array if the datafile is empty
+        first_line = asbytes('')
+        first_values = []
+        warnings.warn('genfromtxt: Empty input file: "%s"' % fname)
+
+    # Should we take the first values as names ?
+    if names is True:
+        fval = first_values[0].strip()
+        if fval in comments:
+            del first_values[0]
+
+    # Check the columns to use: make sure `usecols` is a list
+    if usecols is not None:
+        try:
+            usecols = [_.strip() for _ in usecols.split(",")]
+        except AttributeError:
+            try:
+                usecols = list(usecols)
+            except TypeError:
+                usecols = [usecols, ]
+    nbcols = len(usecols or first_values)
+
+    # Check the names and overwrite the dtype.names if needed
+    if names is True:
+        names = validate_names([_bytes_to_name(_.strip())
+                                for _ in first_values])
+        first_line = asbytes('')
+    elif _is_string_like(names):
+        names = validate_names([_.strip() for _ in names.split(',')])
+    elif names:
+        names = validate_names(names)
+    # Get the dtype
+    if dtype is not None:
+        dtype = easy_dtype(dtype, defaultfmt=defaultfmt, names=names,
+                           excludelist=excludelist,
+                           deletechars=deletechars,
+                           case_sensitive=case_sensitive,
+                           replace_space=replace_space)
+    # Make sure the names is a list (for 2.5)
+    if names is not None:
+        names = list(names)
+
+    if usecols:
+        for (i, current) in enumerate(usecols):
+            # if usecols is a list of names, convert to a list of indices
+            if _is_string_like(current):
+                usecols[i] = names.index(current)
+            elif current < 0:
+                usecols[i] = current + len(first_values)
+        # If the dtype is not None, make sure we update it
+        if (dtype is not None) and (len(dtype) > nbcols):
+            descr = dtype.descr
+            dtype = np.dtype([descr[_] for _ in usecols])
+            names = list(dtype.names)
+        # If `names` is not None, update the names
+        elif (names is not None) and (len(names) > nbcols):
+            names = [names[_] for _ in usecols]
+    elif (names is not None) and (dtype is not None):
+        names = list(dtype.names)
+
+    # Process the missing values ...............................
+    # Rename missing_values for convenience
+    user_missing_values = missing_values or ()
+
+    # Define the list of missing_values (one column: one list)
+    missing_values = [list([asbytes('')]) for _ in range(nbcols)]
+
+    # We have a dictionary: process it field by field
+    if isinstance(user_missing_values, dict):
+        # Loop on the items
+        for (key, val) in user_missing_values.items():
+            # Is the key a string ?
+            if _is_string_like(key):
+                try:
+                    # Transform it into an integer
+                    key = names.index(key)
+                except ValueError:
+                    # We couldn't find it: the name must have been dropped
+                    continue
+            # Redefine the key as needed if it's a column number
+            if usecols:
+                try:
+                    key = usecols.index(key)
+                except ValueError:
+                    pass
+            # Transform the value as a list of string
+            if isinstance(val, (list, tuple)):
+                val = [str(_) for _ in val]
+            else:
+                val = [str(val), ]
+            # Add the value(s) to the current list of missing
+            if key is None:
+                # None acts as default
+                for miss in missing_values:
+                    miss.extend(val)
+            else:
+                missing_values[key].extend(val)
+    # We have a sequence : each item matches a column
+    elif isinstance(user_missing_values, (list, tuple)):
+        for (value, entry) in zip(user_missing_values, missing_values):
+            value = str(value)
+            if value not in entry:
+                entry.append(value)
+    # We have a string : apply it to all entries
+    elif isinstance(user_missing_values, bytes):
+        user_value = user_missing_values.split(asbytes(","))
+        for entry in missing_values:
+            entry.extend(user_value)
+    # We have something else: apply it to all entries
+    else:
+        for entry in missing_values:
+            entry.extend([str(user_missing_values)])
+
+    # Process the filling_values ...............................
+    # Rename the input for convenience
+    user_filling_values = filling_values
+    if user_filling_values is None:
+        user_filling_values = []
+    # Define the default
+    filling_values = [None] * nbcols
+    # We have a dictionary : update each entry individually
+    if isinstance(user_filling_values, dict):
+        for (key, val) in user_filling_values.items():
+            if _is_string_like(key):
+                try:
+                    # Transform it into an integer
+                    key = names.index(key)
+                except ValueError:
+                    # We couldn't find it: the name must have been dropped,
+                    continue
+            # Redefine the key if it's a column number and usecols is defined
+            if usecols:
+                try:
+                    key = usecols.index(key)
+                except ValueError:
+                    pass
+            # Add the value to the list
+            filling_values[key] = val
+    # We have a sequence : update on a one-to-one basis
+    elif isinstance(user_filling_values, (list, tuple)):
+        n = len(user_filling_values)
+        if (n <= nbcols):
+            filling_values[:n] = user_filling_values
+        else:
+            filling_values = user_filling_values[:nbcols]
+    # We have something else : use it for all entries
+    else:
+        filling_values = [user_filling_values] * nbcols
+
+    # Initialize the converters ................................
+    if dtype is None:
+        # Note: we can't use a [...]*nbcols, as we would have 3 times the same
+        # ... converter, instead of 3 different converters.
+        converters = [StringConverter(None, missing_values=miss, default=fill)
+                      for (miss, fill) in zip(missing_values, filling_values)]
+    else:
+        dtype_flat = flatten_dtype(dtype, flatten_base=True)
+        # Initialize the converters
+        if len(dtype_flat) > 1:
+            # Flexible type : get a converter from each dtype
+            zipit = zip(dtype_flat, missing_values, filling_values)
+            converters = [StringConverter(dt, locked=True,
+                                          missing_values=miss, default=fill)
+                          for (dt, miss, fill) in zipit]
+        else:
+            # Set to a default converter (but w/ different missing values)
+            zipit = zip(missing_values, filling_values)
+            converters = [StringConverter(dtype, locked=True,
+                                          missing_values=miss, default=fill)
+                          for (miss, fill) in zipit]
+    # Update the converters to use the user-defined ones
+    uc_update = []
+    for (j, conv) in user_converters.items():
+        # If the converter is specified by column names, use the index instead
+        if _is_string_like(j):
+            try:
+                j = names.index(j)
+                i = j
+            except ValueError:
+                continue
+        elif usecols:
+            try:
+                i = usecols.index(j)
+            except ValueError:
+                # Unused converter specified
+                continue
+        else:
+            i = j
+        # Find the value to test - first_line is not filtered by usecols:
+        if len(first_line):
+            testing_value = first_values[j]
+        else:
+            testing_value = None
+        converters[i].update(conv, locked=True,
+                             testing_value=testing_value,
+                             default=filling_values[i],
+                             missing_values=missing_values[i],)
+        uc_update.append((i, conv))
+    # Make sure we have the corrected keys in user_converters...
+    user_converters.update(uc_update)
+
+    # Fixme: possible error as following variable never used.
+    #miss_chars = [_.missing_values for _ in converters]
+
+    # Initialize the output lists ...
+    # ... rows
+    rows = []
+    append_to_rows = rows.append
+    # ... masks
+    if usemask:
+        masks = []
+        append_to_masks = masks.append
+    # ... invalid
+    invalid = []
+    append_to_invalid = invalid.append
+
+    # Parse each line
+    for (i, line) in enumerate(itertools.chain([first_line, ], fhd)):
+        values = split_line(line)
+        nbvalues = len(values)
+        # Skip an empty line
+        if nbvalues == 0:
+            continue
+        if usecols:
+            # Select only the columns we need
+            try:
+                values = [values[_] for _ in usecols]
+            except IndexError:
+                append_to_invalid((i + skip_header + 1, nbvalues))
+                continue
+        elif nbvalues != nbcols:
+            append_to_invalid((i + skip_header + 1, nbvalues))
+            continue
+        # Store the values
+        append_to_rows(tuple(values))
+        if usemask:
+            append_to_masks(tuple([v.strip() in m
+                                   for (v, m) in zip(values,
+                                                     missing_values)]))
+        if len(rows) == max_rows:
+            break
+
+    if own_fhd:
+        fhd.close()
+
+    # Upgrade the converters (if needed)
+    if dtype is None:
+        for (i, converter) in enumerate(converters):
+            current_column = [itemgetter(i)(_m) for _m in rows]
+            try:
+                converter.iterupgrade(current_column)
+            except ConverterLockError:
+                errmsg = "Converter #%i is locked and cannot be upgraded: " % i
+                current_column = map(itemgetter(i), rows)
+                for (j, value) in enumerate(current_column):
+                    try:
+                        converter.upgrade(value)
+                    except (ConverterError, ValueError):
+                        errmsg += "(occurred line #%i for value '%s')"
+                        errmsg %= (j + 1 + skip_header, value)
+                        raise ConverterError(errmsg)
+
+    # Check that we don't have invalid values
+    nbinvalid = len(invalid)
+    if nbinvalid > 0:
+        nbrows = len(rows) + nbinvalid - skip_footer
+        # Construct the error message
+        template = "    Line #%%i (got %%i columns instead of %i)" % nbcols
+        if skip_footer > 0:
+            nbinvalid_skipped = len([_ for _ in invalid
+                                     if _[0] > nbrows + skip_header])
+            invalid = invalid[:nbinvalid - nbinvalid_skipped]
+            skip_footer -= nbinvalid_skipped
+#
+#            nbrows -= skip_footer
+#            errmsg = [template % (i, nb)
+#                      for (i, nb) in invalid if i < nbrows]
+#        else:
+        errmsg = [template % (i, nb)
+                  for (i, nb) in invalid]
+        if len(errmsg):
+            errmsg.insert(0, "Some errors were detected !")
+            errmsg = "\n".join(errmsg)
+            # Raise an exception ?
+            if invalid_raise:
+                raise ValueError(errmsg)
+            # Issue a warning ?
+            else:
+                warnings.warn(errmsg, ConversionWarning)
+
+    # Strip the last skip_footer data
+    if skip_footer > 0:
+        rows = rows[:-skip_footer]
+        if usemask:
+            masks = masks[:-skip_footer]
+
+    # Convert each value according to the converter:
+    # We want to modify the list in place to avoid creating a new one...
+    if loose:
+        rows = list(
+            zip(*[[conv._loose_call(_r) for _r in map(itemgetter(i), rows)]
+                  for (i, conv) in enumerate(converters)]))
+    else:
+        rows = list(
+            zip(*[[conv._strict_call(_r) for _r in map(itemgetter(i), rows)]
+                  for (i, conv) in enumerate(converters)]))
+
+    # Reset the dtype
+    data = rows
+    if dtype is None:
+        # Get the dtypes from the types of the converters
+        column_types = [conv.type for conv in converters]
+        # Find the columns with strings...
+        strcolidx = [i for (i, v) in enumerate(column_types)
+                     if v in (type('S'), np.string_)]
+        # ... and take the largest number of chars.
+        for i in strcolidx:
+            column_types[i] = "|S%i" % max(len(row[i]) for row in data)
+        #
+        if names is None:
+            # If the dtype is uniform, don't define names, else use ''
+            base = set([c.type for c in converters if c._checked])
+            if len(base) == 1:
+                (ddtype, mdtype) = (list(base)[0], np.bool)
+            else:
+                ddtype = [(defaultfmt % i, dt)
+                          for (i, dt) in enumerate(column_types)]
+                if usemask:
+                    mdtype = [(defaultfmt % i, np.bool)
+                              for (i, dt) in enumerate(column_types)]
+        else:
+            ddtype = list(zip(names, column_types))
+            mdtype = list(zip(names, [np.bool] * len(column_types)))
+        output = np.array(data, dtype=ddtype)
+        if usemask:
+            outputmask = np.array(masks, dtype=mdtype)
+    else:
+        # Overwrite the initial dtype names if needed
+        if names and dtype.names:
+            dtype.names = names
+        # Case 1. We have a structured type
+        if len(dtype_flat) > 1:
+            # Nested dtype, eg [('a', int), ('b', [('b0', int), ('b1', 'f4')])]
+            # First, create the array using a flattened dtype:
+            # [('a', int), ('b1', int), ('b2', float)]
+            # Then, view the array using the specified dtype.
+            if 'O' in (_.char for _ in dtype_flat):
+                if has_nested_fields(dtype):
+                    raise NotImplementedError(
+                        "Nested fields involving objects are not supported...")
+                else:
+                    output = np.array(data, dtype=dtype)
+            else:
+                rows = np.array(data, dtype=[('', _) for _ in dtype_flat])
+                output = rows.view(dtype)
+            # Now, process the rowmasks the same way
+            if usemask:
+                rowmasks = np.array(
+                    masks, dtype=np.dtype([('', np.bool) for t in dtype_flat]))
+                # Construct the new dtype
+                mdtype = make_mask_descr(dtype)
+                outputmask = rowmasks.view(mdtype)
+        # Case #2. We have a basic dtype
+        else:
+            # We used some user-defined converters
+            if user_converters:
+                ishomogeneous = True
+                descr = []
+                for i, ttype in enumerate([conv.type for conv in converters]):
+                    # Keep the dtype of the current converter
+                    if i in user_converters:
+                        ishomogeneous &= (ttype == dtype.type)
+                        if ttype == np.string_:
+                            ttype = "|S%i" % max(len(row[i]) for row in data)
+                        descr.append(('', ttype))
+                    else:
+                        descr.append(('', dtype))
+                # So we changed the dtype ?
+                if not ishomogeneous:
+                    # We have more than one field
+                    if len(descr) > 1:
+                        dtype = np.dtype(descr)
+                    # We have only one field: drop the name if not needed.
+                    else:
+                        dtype = np.dtype(ttype)
+            #
+            output = np.array(data, dtype)
+            if usemask:
+                if dtype.names:
+                    mdtype = [(_, np.bool) for _ in dtype.names]
+                else:
+                    mdtype = np.bool
+                outputmask = np.array(masks, dtype=mdtype)
+    # Try to take care of the missing data we missed
+    names = output.dtype.names
+    if usemask and names:
+        for (name, conv) in zip(names or (), converters):
+            missing_values = [conv(_) for _ in conv.missing_values
+                              if _ != asbytes('')]
+            for mval in missing_values:
+                outputmask[name] |= (output[name] == mval)
+    # Construct the final array
+    if usemask:
+        output = output.view(MaskedArray)
+        output._mask = outputmask
+    if unpack:
+        return output.squeeze().T
+    return output.squeeze()
+
+
+def ndfromtxt(fname, **kwargs):
+    """
+    Load ASCII data stored in a file and return it as a single array.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function.
+
+    """
+    kwargs['usemask'] = False
+    return genfromtxt(fname, **kwargs)
+
+
+def mafromtxt(fname, **kwargs):
+    """
+    Load ASCII data stored in a text file and return a masked array.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function to load ASCII data.
+
+    """
+    kwargs['usemask'] = True
+    return genfromtxt(fname, **kwargs)
+
+
+def recfromtxt(fname, **kwargs):
+    """
+    Load ASCII data from a file and return it in a record array.
+
+    If ``usemask=False`` a standard `recarray` is returned,
+    if ``usemask=True`` a MaskedRecords array is returned.
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function
+
+    Notes
+    -----
+    By default, `dtype` is None, which means that the data-type of the output
+    array will be determined from the data.
+
+    """
+    kwargs.setdefault("dtype", None)
+    usemask = kwargs.get('usemask', False)
+    output = genfromtxt(fname, **kwargs)
+    if usemask:
+        from numpy.ma.mrecords import MaskedRecords
+        output = output.view(MaskedRecords)
+    else:
+        output = output.view(np.recarray)
+    return output
+
+
+def recfromcsv(fname, **kwargs):
+    """
+    Load ASCII data stored in a comma-separated file.
+
+    The returned array is a record array (if ``usemask=False``, see
+    `recarray`) or a masked record array (if ``usemask=True``,
+    see `ma.mrecords.MaskedRecords`).
+
+    Parameters
+    ----------
+    fname, kwargs : For a description of input parameters, see `genfromtxt`.
+
+    See Also
+    --------
+    numpy.genfromtxt : generic function to load ASCII data.
+
+    Notes
+    -----
+    By default, `dtype` is None, which means that the data-type of the output
+    array will be determined from the data.
+
+    """
+    # Set default kwargs for genfromtxt as relevant to csv import.
+    kwargs.setdefault("case_sensitive", "lower")
+    kwargs.setdefault("names", True)
+    kwargs.setdefault("delimiter", ",")
+    kwargs.setdefault("dtype", None)
+    output = genfromtxt(fname, **kwargs)
+
+    usemask = kwargs.get("usemask", False)
+    if usemask:
+        from numpy.ma.mrecords import MaskedRecords
+        output = output.view(MaskedRecords)
+    else:
+        output = output.view(np.recarray)
+    return output
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.py
new file mode 100644
index 0000000000..189e59154d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.py
@@ -0,0 +1,1278 @@
+"""
+Functions to operate on polynomials.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['poly', 'roots', 'polyint', 'polyder', 'polyadd',
+           'polysub', 'polymul', 'polydiv', 'polyval', 'poly1d',
+           'polyfit', 'RankWarning']
+
+import re
+import warnings
+import numpy.core.numeric as NX
+
+from numpy.core import (isscalar, abs, finfo, atleast_1d, hstack, dot, array,
+                        ones)
+from numpy.lib.twodim_base import diag, vander
+from numpy.lib.function_base import trim_zeros, sort_complex
+from numpy.lib.type_check import iscomplex, real, imag, mintypecode
+from numpy.linalg import eigvals, lstsq, inv
+
+class RankWarning(UserWarning):
+    """
+    Issued by `polyfit` when the Vandermonde matrix is rank deficient.
+
+    For more information, a way to suppress the warning, and an example of
+    `RankWarning` being issued, see `polyfit`.
+
+    """
+    pass
+
+def poly(seq_of_zeros):
+    """
+    Find the coefficients of a polynomial with the given sequence of roots.
+
+    Returns the coefficients of the polynomial whose leading coefficient
+    is one for the given sequence of zeros (multiple roots must be included
+    in the sequence as many times as their multiplicity; see Examples).
+    A square matrix (or array, which will be treated as a matrix) can also
+    be given, in which case the coefficients of the characteristic polynomial
+    of the matrix are returned.
+
+    Parameters
+    ----------
+    seq_of_zeros : array_like, shape (N,) or (N, N)
+        A sequence of polynomial roots, or a square array or matrix object.
+
+    Returns
+    -------
+    c : ndarray
+        1D array of polynomial coefficients from highest to lowest degree:
+
+        ``c[0] * x**(N) + c[1] * x**(N-1) + ... + c[N-1] * x + c[N]``
+        where c[0] always equals 1.
+
+    Raises
+    ------
+    ValueError
+        If input is the wrong shape (the input must be a 1-D or square
+        2-D array).
+
+    See Also
+    --------
+    polyval : Compute polynomial values.
+    roots : Return the roots of a polynomial.
+    polyfit : Least squares polynomial fit.
+    poly1d : A one-dimensional polynomial class.
+
+    Notes
+    -----
+    Specifying the roots of a polynomial still leaves one degree of
+    freedom, typically represented by an undetermined leading
+    coefficient. [1]_ In the case of this function, that coefficient -
+    the first one in the returned array - is always taken as one. (If
+    for some reason you have one other point, the only automatic way
+    presently to leverage that information is to use ``polyfit``.)
+
+    The characteristic polynomial, :math:`p_a(t)`, of an `n`-by-`n`
+    matrix **A** is given by
+
+        :math:`p_a(t) = \\mathrm{det}(t\\, \\mathbf{I} - \\mathbf{A})`,
+
+    where **I** is the `n`-by-`n` identity matrix. [2]_
+
+    References
+    ----------
+    .. [1] M. Sullivan and M. Sullivan, III, "Algebra and Trignometry,
+       Enhanced With Graphing Utilities," Prentice-Hall, pg. 318, 1996.
+
+    .. [2] G. Strang, "Linear Algebra and Its Applications, 2nd Edition,"
+       Academic Press, pg. 182, 1980.
+
+    Examples
+    --------
+    Given a sequence of a polynomial's zeros:
+
+    >>> np.poly((0, 0, 0)) # Multiple root example
+    array([1, 0, 0, 0])
+
+    The line above represents z**3 + 0*z**2 + 0*z + 0.
+
+    >>> np.poly((-1./2, 0, 1./2))
+    array([ 1.  ,  0.  , -0.25,  0.  ])
+
+    The line above represents z**3 - z/4
+
+    >>> np.poly((np.random.random(1.)[0], 0, np.random.random(1.)[0]))
+    array([ 1.        , -0.77086955,  0.08618131,  0.        ]) #random
+
+    Given a square array object:
+
+    >>> P = np.array([[0, 1./3], [-1./2, 0]])
+    >>> np.poly(P)
+    array([ 1.        ,  0.        ,  0.16666667])
+
+    Or a square matrix object:
+
+    >>> np.poly(np.matrix(P))
+    array([ 1.        ,  0.        ,  0.16666667])
+
+    Note how in all cases the leading coefficient is always 1.
+
+    """
+    seq_of_zeros = atleast_1d(seq_of_zeros)
+    sh = seq_of_zeros.shape
+
+    if len(sh) == 2 and sh[0] == sh[1] and sh[0] != 0:
+        seq_of_zeros = eigvals(seq_of_zeros)
+    elif len(sh) == 1:
+        dt = seq_of_zeros.dtype
+        # Let object arrays slip through, e.g. for arbitrary precision
+        if dt != object:
+            seq_of_zeros = seq_of_zeros.astype(mintypecode(dt.char))
+    else:
+        raise ValueError("input must be 1d or non-empty square 2d array.")
+
+    if len(seq_of_zeros) == 0:
+        return 1.0
+    dt = seq_of_zeros.dtype
+    a = ones((1,), dtype=dt)
+    for k in range(len(seq_of_zeros)):
+        a = NX.convolve(a, array([1, -seq_of_zeros[k]], dtype=dt),
+                        mode='full')
+
+    if issubclass(a.dtype.type, NX.complexfloating):
+        # if complex roots are all complex conjugates, the roots are real.
+        roots = NX.asarray(seq_of_zeros, complex)
+        pos_roots = sort_complex(NX.compress(roots.imag > 0, roots))
+        neg_roots = NX.conjugate(sort_complex(
+                                        NX.compress(roots.imag < 0, roots)))
+        if (len(pos_roots) == len(neg_roots) and
+                NX.alltrue(neg_roots == pos_roots)):
+            a = a.real.copy()
+
+    return a
+
+def roots(p):
+    """
+    Return the roots of a polynomial with coefficients given in p.
+
+    The values in the rank-1 array `p` are coefficients of a polynomial.
+    If the length of `p` is n+1 then the polynomial is described by::
+
+      p[0] * x**n + p[1] * x**(n-1) + ... + p[n-1]*x + p[n]
+
+    Parameters
+    ----------
+    p : array_like
+        Rank-1 array of polynomial coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        An array containing the complex roots of the polynomial.
+
+    Raises
+    ------
+    ValueError
+        When `p` cannot be converted to a rank-1 array.
+
+    See also
+    --------
+    poly : Find the coefficients of a polynomial with a given sequence
+           of roots.
+    polyval : Compute polynomial values.
+    polyfit : Least squares polynomial fit.
+    poly1d : A one-dimensional polynomial class.
+
+    Notes
+    -----
+    The algorithm relies on computing the eigenvalues of the
+    companion matrix [1]_.
+
+    References
+    ----------
+    .. [1] R. A. Horn & C. R. Johnson, *Matrix Analysis*.  Cambridge, UK:
+        Cambridge University Press, 1999, pp. 146-7.
+
+    Examples
+    --------
+    >>> coeff = [3.2, 2, 1]
+    >>> np.roots(coeff)
+    array([-0.3125+0.46351241j, -0.3125-0.46351241j])
+
+    """
+    # If input is scalar, this makes it an array
+    p = atleast_1d(p)
+    if len(p.shape) != 1:
+        raise ValueError("Input must be a rank-1 array.")
+
+    # find non-zero array entries
+    non_zero = NX.nonzero(NX.ravel(p))[0]
+
+    # Return an empty array if polynomial is all zeros
+    if len(non_zero) == 0:
+        return NX.array([])
+
+    # find the number of trailing zeros -- this is the number of roots at 0.
+    trailing_zeros = len(p) - non_zero[-1] - 1
+
+    # strip leading and trailing zeros
+    p = p[int(non_zero[0]):int(non_zero[-1])+1]
+
+    # casting: if incoming array isn't floating point, make it floating point.
+    if not issubclass(p.dtype.type, (NX.floating, NX.complexfloating)):
+        p = p.astype(float)
+
+    N = len(p)
+    if N > 1:
+        # build companion matrix and find its eigenvalues (the roots)
+        A = diag(NX.ones((N-2,), p.dtype), -1)
+        A[0,:] = -p[1:] / p[0]
+        roots = eigvals(A)
+    else:
+        roots = NX.array([])
+
+    # tack any zeros onto the back of the array
+    roots = hstack((roots, NX.zeros(trailing_zeros, roots.dtype)))
+    return roots
+
+def polyint(p, m=1, k=None):
+    """
+    Return an antiderivative (indefinite integral) of a polynomial.
+
+    The returned order `m` antiderivative `P` of polynomial `p` satisfies
+    :math:`\\frac{d^m}{dx^m}P(x) = p(x)` and is defined up to `m - 1`
+    integration constants `k`. The constants determine the low-order
+    polynomial part
+
+    .. math:: \\frac{k_{m-1}}{0!} x^0 + \\ldots + \\frac{k_0}{(m-1)!}x^{m-1}
+
+    of `P` so that :math:`P^{(j)}(0) = k_{m-j-1}`.
+
+    Parameters
+    ----------
+    p : array_like or poly1d
+        Polynomial to differentiate.
+        A sequence is interpreted as polynomial coefficients, see `poly1d`.
+    m : int, optional
+        Order of the antiderivative. (Default: 1)
+    k : list of `m` scalars or scalar, optional
+        Integration constants. They are given in the order of integration:
+        those corresponding to highest-order terms come first.
+
+        If ``None`` (default), all constants are assumed to be zero.
+        If `m = 1`, a single scalar can be given instead of a list.
+
+    See Also
+    --------
+    polyder : derivative of a polynomial
+    poly1d.integ : equivalent method
+
+    Examples
+    --------
+    The defining property of the antiderivative:
+
+    >>> p = np.poly1d([1,1,1])
+    >>> P = np.polyint(p)
+    >>> P
+    poly1d([ 0.33333333,  0.5       ,  1.        ,  0.        ])
+    >>> np.polyder(P) == p
+    True
+
+    The integration constants default to zero, but can be specified:
+
+    >>> P = np.polyint(p, 3)
+    >>> P(0)
+    0.0
+    >>> np.polyder(P)(0)
+    0.0
+    >>> np.polyder(P, 2)(0)
+    0.0
+    >>> P = np.polyint(p, 3, k=[6,5,3])
+    >>> P
+    poly1d([ 0.01666667,  0.04166667,  0.16666667,  3. ,  5. ,  3. ])
+
+    Note that 3 = 6 / 2!, and that the constants are given in the order of
+    integrations. Constant of the highest-order polynomial term comes first:
+
+    >>> np.polyder(P, 2)(0)
+    6.0
+    >>> np.polyder(P, 1)(0)
+    5.0
+    >>> P(0)
+    3.0
+
+    """
+    m = int(m)
+    if m < 0:
+        raise ValueError("Order of integral must be positive (see polyder)")
+    if k is None:
+        k = NX.zeros(m, float)
+    k = atleast_1d(k)
+    if len(k) == 1 and m > 1:
+        k = k[0]*NX.ones(m, float)
+    if len(k) < m:
+        raise ValueError(
+              "k must be a scalar or a rank-1 array of length 1 or >m.")
+
+    truepoly = isinstance(p, poly1d)
+    p = NX.asarray(p)
+    if m == 0:
+        if truepoly:
+            return poly1d(p)
+        return p
+    else:
+        # Note: this must work also with object and integer arrays
+        y = NX.concatenate((p.__truediv__(NX.arange(len(p), 0, -1)), [k[0]]))
+        val = polyint(y, m - 1, k=k[1:])
+        if truepoly:
+            return poly1d(val)
+        return val
+
+def polyder(p, m=1):
+    """
+    Return the derivative of the specified order of a polynomial.
+
+    Parameters
+    ----------
+    p : poly1d or sequence
+        Polynomial to differentiate.
+        A sequence is interpreted as polynomial coefficients, see `poly1d`.
+    m : int, optional
+        Order of differentiation (default: 1)
+
+    Returns
+    -------
+    der : poly1d
+        A new polynomial representing the derivative.
+
+    See Also
+    --------
+    polyint : Anti-derivative of a polynomial.
+    poly1d : Class for one-dimensional polynomials.
+
+    Examples
+    --------
+    The derivative of the polynomial :math:`x^3 + x^2 + x^1 + 1` is:
+
+    >>> p = np.poly1d([1,1,1,1])
+    >>> p2 = np.polyder(p)
+    >>> p2
+    poly1d([3, 2, 1])
+
+    which evaluates to:
+
+    >>> p2(2.)
+    17.0
+
+    We can verify this, approximating the derivative with
+    ``(f(x + h) - f(x))/h``:
+
+    >>> (p(2. + 0.001) - p(2.)) / 0.001
+    17.007000999997857
+
+    The fourth-order derivative of a 3rd-order polynomial is zero:
+
+    >>> np.polyder(p, 2)
+    poly1d([6, 2])
+    >>> np.polyder(p, 3)
+    poly1d([6])
+    >>> np.polyder(p, 4)
+    poly1d([ 0.])
+
+    """
+    m = int(m)
+    if m < 0:
+        raise ValueError("Order of derivative must be positive (see polyint)")
+
+    truepoly = isinstance(p, poly1d)
+    p = NX.asarray(p)
+    n = len(p) - 1
+    y = p[:-1] * NX.arange(n, 0, -1)
+    if m == 0:
+        val = p
+    else:
+        val = polyder(y, m - 1)
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
+    """
+    Least squares polynomial fit.
+
+    Fit a polynomial ``p(x) = p[0] * x**deg + ... + p[deg]`` of degree `deg`
+    to points `(x, y)`. Returns a vector of coefficients `p` that minimises
+    the squared error.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int
+        Degree of the fitting polynomial
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (M,), optional
+        Weights to apply to the y-coordinates of the sample points. For
+        gaussian uncertainties, use 1/sigma (not 1/sigma**2).
+    cov : bool, optional
+        Return the estimate and the covariance matrix of the estimate
+        If full is True, then cov is not returned.
+
+    Returns
+    -------
+    p : ndarray, shape (M,) or (M, K)
+        Polynomial coefficients, highest power first.  If `y` was 2-D, the
+        coefficients for `k`-th data set are in ``p[:,k]``.
+
+    residuals, rank, singular_values, rcond :
+        Present only if `full` = True.  Residuals of the least-squares fit,
+        the effective rank of the scaled Vandermonde coefficient matrix,
+        its singular values, and the specified value of `rcond`. For more
+        details, see `linalg.lstsq`.
+
+    V : ndarray, shape (M,M) or (M,M,K)
+        Present only if `full` = False and `cov`=True.  The covariance
+        matrix of the polynomial coefficient estimates.  The diagonal of
+        this matrix are the variance estimates for each coefficient.  If y
+        is a 2-D array, then the covariance matrix for the `k`-th data set
+        are in ``V[:,:,k]``
+
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.
+
+        The warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', np.RankWarning)
+
+    See Also
+    --------
+    polyval : Compute polynomial values.
+    linalg.lstsq : Computes a least-squares fit.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution minimizes the squared error
+
+    .. math ::
+        E = \\sum_{j=0}^k |p(x_j) - y_j|^2
+
+    in the equations::
+
+        x[0]**n * p[0] + ... + x[0] * p[n-1] + p[n] = y[0]
+        x[1]**n * p[0] + ... + x[1] * p[n-1] + p[n] = y[1]
+        ...
+        x[k]**n * p[0] + ... + x[k] * p[n-1] + p[n] = y[k]
+
+    The coefficient matrix of the coefficients `p` is a Vandermonde matrix.
+
+    `polyfit` issues a `RankWarning` when the least-squares fit is badly
+    conditioned. This implies that the best fit is not well-defined due
+    to numerical error. The results may be improved by lowering the polynomial
+    degree or by replacing `x` by `x` - `x`.mean(). The `rcond` parameter
+    can also be set to a value smaller than its default, but the resulting
+    fit may be spurious: including contributions from the small singular
+    values can add numerical noise to the result.
+
+    Note that fitting polynomial coefficients is inherently badly conditioned
+    when the degree of the polynomial is large or the interval of sample points
+    is badly centered. The quality of the fit should always be checked in these
+    cases. When polynomial fits are not satisfactory, splines may be a good
+    alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+    .. [2] Wikipedia, "Polynomial interpolation",
+           http://en.wikipedia.org/wiki/Polynomial_interpolation
+
+    Examples
+    --------
+    >>> x = np.array([0.0, 1.0, 2.0, 3.0,  4.0,  5.0])
+    >>> y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0])
+    >>> z = np.polyfit(x, y, 3)
+    >>> z
+    array([ 0.08703704, -0.81349206,  1.69312169, -0.03968254])
+
+    It is convenient to use `poly1d` objects for dealing with polynomials:
+
+    >>> p = np.poly1d(z)
+    >>> p(0.5)
+    0.6143849206349179
+    >>> p(3.5)
+    -0.34732142857143039
+    >>> p(10)
+    22.579365079365115
+
+    High-order polynomials may oscillate wildly:
+
+    >>> p30 = np.poly1d(np.polyfit(x, y, 30))
+    /... RankWarning: Polyfit may be poorly conditioned...
+    >>> p30(4)
+    -0.80000000000000204
+    >>> p30(5)
+    -0.99999999999999445
+    >>> p30(4.5)
+    -0.10547061179440398
+
+    Illustration:
+
+    >>> import matplotlib.pyplot as plt
+    >>> xp = np.linspace(-2, 6, 100)
+    >>> _ = plt.plot(x, y, '.', xp, p(xp), '-', xp, p30(xp), '--')
+    >>> plt.ylim(-2,2)
+    (-2, 2)
+    >>> plt.show()
+
+    """
+    order = int(deg) + 1
+    x = NX.asarray(x) + 0.0
+    y = NX.asarray(y) + 0.0
+
+    # check arguments.
+    if deg < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if x.shape[0] != y.shape[0]:
+        raise TypeError("expected x and y to have same length")
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*finfo(x.dtype).eps
+
+    # set up least squares equation for powers of x
+    lhs = vander(x, order)
+    rhs = y
+
+    # apply weighting
+    if w is not None:
+        w = NX.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected a 1-d array for weights")
+        if w.shape[0] != y.shape[0]:
+            raise TypeError("expected w and y to have the same length")
+        lhs *= w[:, NX.newaxis]
+        if rhs.ndim == 2:
+            rhs *= w[:, NX.newaxis]
+        else:
+            rhs *= w
+
+    # scale lhs to improve condition number and solve
+    scale = NX.sqrt((lhs*lhs).sum(axis=0))
+    lhs /= scale
+    c, resids, rank, s = lstsq(lhs, rhs, rcond)
+    c = (c.T/scale).T  # broadcast scale coefficients
+
+    # warn on rank reduction, which indicates an ill conditioned matrix
+    if rank != order and not full:
+        msg = "Polyfit may be poorly conditioned"
+        warnings.warn(msg, RankWarning)
+
+    if full:
+        return c, resids, rank, s, rcond
+    elif cov:
+        Vbase = inv(dot(lhs.T, lhs))
+        Vbase /= NX.outer(scale, scale)
+        # Some literature ignores the extra -2.0 factor in the denominator, but
+        #  it is included here because the covariance of Multivariate Student-T
+        #  (which is implied by a Bayesian uncertainty analysis) includes it.
+        #  Plus, it gives a slightly more conservative estimate of uncertainty.
+        fac = resids / (len(x) - order - 2.0)
+        if y.ndim == 1:
+            return c, Vbase * fac
+        else:
+            return c, Vbase[:,:, NX.newaxis] * fac
+    else:
+        return c
+
+
+def polyval(p, x):
+    """
+    Evaluate a polynomial at specific values.
+
+    If `p` is of length N, this function returns the value:
+
+        ``p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]``
+
+    If `x` is a sequence, then `p(x)` is returned for each element of `x`.
+    If `x` is another polynomial then the composite polynomial `p(x(t))`
+    is returned.
+
+    Parameters
+    ----------
+    p : array_like or poly1d object
+       1D array of polynomial coefficients (including coefficients equal
+       to zero) from highest degree to the constant term, or an
+       instance of poly1d.
+    x : array_like or poly1d object
+       A number, an array of numbers, or an instance of poly1d, at
+       which to evaluate `p`.
+
+    Returns
+    -------
+    values : ndarray or poly1d
+       If `x` is a poly1d instance, the result is the composition of the two
+       polynomials, i.e., `x` is "substituted" in `p` and the simplified
+       result is returned. In addition, the type of `x` - array_like or
+       poly1d - governs the type of the output: `x` array_like => `values`
+       array_like, `x` a poly1d object => `values` is also.
+
+    See Also
+    --------
+    poly1d: A polynomial class.
+
+    Notes
+    -----
+    Horner's scheme [1]_ is used to evaluate the polynomial. Even so,
+    for polynomials of high degree the values may be inaccurate due to
+    rounding errors. Use carefully.
+
+    References
+    ----------
+    .. [1] I. N. Bronshtein, K. A. Semendyayev, and K. A. Hirsch (Eng.
+       trans. Ed.), *Handbook of Mathematics*, New York, Van Nostrand
+       Reinhold Co., 1985, pg. 720.
+
+    Examples
+    --------
+    >>> np.polyval([3,0,1], 5)  # 3 * 5**2 + 0 * 5**1 + 1
+    76
+    >>> np.polyval([3,0,1], np.poly1d(5))
+    poly1d([ 76.])
+    >>> np.polyval(np.poly1d([3,0,1]), 5)
+    76
+    >>> np.polyval(np.poly1d([3,0,1]), np.poly1d(5))
+    poly1d([ 76.])
+
+    """
+    p = NX.asarray(p)
+    if isinstance(x, poly1d):
+        y = 0
+    else:
+        x = NX.asarray(x)
+        y = NX.zeros_like(x)
+    for i in range(len(p)):
+        y = y * x + p[i]
+    return y
+
+def polyadd(a1, a2):
+    """
+    Find the sum of two polynomials.
+
+    Returns the polynomial resulting from the sum of two input polynomials.
+    Each input must be either a poly1d object or a 1D sequence of polynomial
+    coefficients, from highest to lowest degree.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d object
+        Input polynomials.
+
+    Returns
+    -------
+    out : ndarray or poly1d object
+        The sum of the inputs. If either input is a poly1d object, then the
+        output is also a poly1d object. Otherwise, it is a 1D array of
+        polynomial coefficients from highest to lowest degree.
+
+    See Also
+    --------
+    poly1d : A one-dimensional polynomial class.
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval
+
+    Examples
+    --------
+    >>> np.polyadd([1, 2], [9, 5, 4])
+    array([9, 6, 6])
+
+    Using poly1d objects:
+
+    >>> p1 = np.poly1d([1, 2])
+    >>> p2 = np.poly1d([9, 5, 4])
+    >>> print(p1)
+    1 x + 2
+    >>> print(p2)
+       2
+    9 x + 5 x + 4
+    >>> print(np.polyadd(p1, p2))
+       2
+    9 x + 6 x + 6
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1 = atleast_1d(a1)
+    a2 = atleast_1d(a2)
+    diff = len(a2) - len(a1)
+    if diff == 0:
+        val = a1 + a2
+    elif diff > 0:
+        zr = NX.zeros(diff, a1.dtype)
+        val = NX.concatenate((zr, a1)) + a2
+    else:
+        zr = NX.zeros(abs(diff), a2.dtype)
+        val = a1 + NX.concatenate((zr, a2))
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polysub(a1, a2):
+    """
+    Difference (subtraction) of two polynomials.
+
+    Given two polynomials `a1` and `a2`, returns ``a1 - a2``.
+    `a1` and `a2` can be either array_like sequences of the polynomials'
+    coefficients (including coefficients equal to zero), or `poly1d` objects.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d
+        Minuend and subtrahend polynomials, respectively.
+
+    Returns
+    -------
+    out : ndarray or poly1d
+        Array or `poly1d` object of the difference polynomial's coefficients.
+
+    See Also
+    --------
+    polyval, polydiv, polymul, polyadd
+
+    Examples
+    --------
+    .. math:: (2 x^2 + 10 x - 2) - (3 x^2 + 10 x -4) = (-x^2 + 2)
+
+    >>> np.polysub([2, 10, -2], [3, 10, -4])
+    array([-1,  0,  2])
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1 = atleast_1d(a1)
+    a2 = atleast_1d(a2)
+    diff = len(a2) - len(a1)
+    if diff == 0:
+        val = a1 - a2
+    elif diff > 0:
+        zr = NX.zeros(diff, a1.dtype)
+        val = NX.concatenate((zr, a1)) - a2
+    else:
+        zr = NX.zeros(abs(diff), a2.dtype)
+        val = a1 - NX.concatenate((zr, a2))
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+
+def polymul(a1, a2):
+    """
+    Find the product of two polynomials.
+
+    Finds the polynomial resulting from the multiplication of the two input
+    polynomials. Each input must be either a poly1d object or a 1D sequence
+    of polynomial coefficients, from highest to lowest degree.
+
+    Parameters
+    ----------
+    a1, a2 : array_like or poly1d object
+        Input polynomials.
+
+    Returns
+    -------
+    out : ndarray or poly1d object
+        The polynomial resulting from the multiplication of the inputs. If
+        either inputs is a poly1d object, then the output is also a poly1d
+        object. Otherwise, it is a 1D array of polynomial coefficients from
+        highest to lowest degree.
+
+    See Also
+    --------
+    poly1d : A one-dimensional polynomial class.
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polysub,
+    polyval
+    convolve : Array convolution. Same output as polymul, but has parameter
+               for overlap mode.
+
+    Examples
+    --------
+    >>> np.polymul([1, 2, 3], [9, 5, 1])
+    array([ 9, 23, 38, 17,  3])
+
+    Using poly1d objects:
+
+    >>> p1 = np.poly1d([1, 2, 3])
+    >>> p2 = np.poly1d([9, 5, 1])
+    >>> print(p1)
+       2
+    1 x + 2 x + 3
+    >>> print(p2)
+       2
+    9 x + 5 x + 1
+    >>> print(np.polymul(p1, p2))
+       4      3      2
+    9 x + 23 x + 38 x + 17 x + 3
+
+    """
+    truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d))
+    a1, a2 = poly1d(a1), poly1d(a2)
+    val = NX.convolve(a1, a2)
+    if truepoly:
+        val = poly1d(val)
+    return val
+
+def polydiv(u, v):
+    """
+    Returns the quotient and remainder of polynomial division.
+
+    The input arrays are the coefficients (including any coefficients
+    equal to zero) of the "numerator" (dividend) and "denominator"
+    (divisor) polynomials, respectively.
+
+    Parameters
+    ----------
+    u : array_like or poly1d
+        Dividend polynomial's coefficients.
+
+    v : array_like or poly1d
+        Divisor polynomial's coefficients.
+
+    Returns
+    -------
+    q : ndarray
+        Coefficients, including those equal to zero, of the quotient.
+    r : ndarray
+        Coefficients, including those equal to zero, of the remainder.
+
+    See Also
+    --------
+    poly, polyadd, polyder, polydiv, polyfit, polyint, polymul, polysub,
+    polyval
+
+    Notes
+    -----
+    Both `u` and `v` must be 0-d or 1-d (ndim = 0 or 1), but `u.ndim` need
+    not equal `v.ndim`. In other words, all four possible combinations -
+    ``u.ndim = v.ndim = 0``, ``u.ndim = v.ndim = 1``,
+    ``u.ndim = 1, v.ndim = 0``, and ``u.ndim = 0, v.ndim = 1`` - work.
+
+    Examples
+    --------
+    .. math:: \\frac{3x^2 + 5x + 2}{2x + 1} = 1.5x + 1.75, remainder 0.25
+
+    >>> x = np.array([3.0, 5.0, 2.0])
+    >>> y = np.array([2.0, 1.0])
+    >>> np.polydiv(x, y)
+    (array([ 1.5 ,  1.75]), array([ 0.25]))
+
+    """
+    truepoly = (isinstance(u, poly1d) or isinstance(u, poly1d))
+    u = atleast_1d(u) + 0.0
+    v = atleast_1d(v) + 0.0
+    # w has the common type
+    w = u[0] + v[0]
+    m = len(u) - 1
+    n = len(v) - 1
+    scale = 1. / v[0]
+    q = NX.zeros((max(m - n + 1, 1),), w.dtype)
+    r = u.copy()
+    for k in range(0, m-n+1):
+        d = scale * r[k]
+        q[k] = d
+        r[k:k+n+1] -= d*v
+    while NX.allclose(r[0], 0, rtol=1e-14) and (r.shape[-1] > 1):
+        r = r[1:]
+    if truepoly:
+        return poly1d(q), poly1d(r)
+    return q, r
+
+_poly_mat = re.compile(r"[*][*]([0-9]*)")
+def _raise_power(astr, wrap=70):
+    n = 0
+    line1 = ''
+    line2 = ''
+    output = ' '
+    while True:
+        mat = _poly_mat.search(astr, n)
+        if mat is None:
+            break
+        span = mat.span()
+        power = mat.groups()[0]
+        partstr = astr[n:span[0]]
+        n = span[1]
+        toadd2 = partstr + ' '*(len(power)-1)
+        toadd1 = ' '*(len(partstr)-1) + power
+        if ((len(line2) + len(toadd2) > wrap) or
+                (len(line1) + len(toadd1) > wrap)):
+            output += line1 + "\n" + line2 + "\n "
+            line1 = toadd1
+            line2 = toadd2
+        else:
+            line2 += partstr + ' '*(len(power)-1)
+            line1 += ' '*(len(partstr)-1) + power
+    output += line1 + "\n" + line2
+    return output + astr[n:]
+
+
+class poly1d(object):
+    """
+    A one-dimensional polynomial class.
+
+    A convenience class, used to encapsulate "natural" operations on
+    polynomials so that said operations may take on their customary
+    form in code (see Examples).
+
+    Parameters
+    ----------
+    c_or_r : array_like
+        The polynomial's coefficients, in decreasing powers, or if
+        the value of the second parameter is True, the polynomial's
+        roots (values where the polynomial evaluates to 0).  For example,
+        ``poly1d([1, 2, 3])`` returns an object that represents
+        :math:`x^2 + 2x + 3`, whereas ``poly1d([1, 2, 3], True)`` returns
+        one that represents :math:`(x-1)(x-2)(x-3) = x^3 - 6x^2 + 11x -6`.
+    r : bool, optional
+        If True, `c_or_r` specifies the polynomial's roots; the default
+        is False.
+    variable : str, optional
+        Changes the variable used when printing `p` from `x` to `variable`
+        (see Examples).
+
+    Examples
+    --------
+    Construct the polynomial :math:`x^2 + 2x + 3`:
+
+    >>> p = np.poly1d([1, 2, 3])
+    >>> print(np.poly1d(p))
+       2
+    1 x + 2 x + 3
+
+    Evaluate the polynomial at :math:`x = 0.5`:
+
+    >>> p(0.5)
+    4.25
+
+    Find the roots:
+
+    >>> p.r
+    array([-1.+1.41421356j, -1.-1.41421356j])
+    >>> p(p.r)
+    array([ -4.44089210e-16+0.j,  -4.44089210e-16+0.j])
+
+    These numbers in the previous line represent (0, 0) to machine precision
+
+    Show the coefficients:
+
+    >>> p.c
+    array([1, 2, 3])
+
+    Display the order (the leading zero-coefficients are removed):
+
+    >>> p.order
+    2
+
+    Show the coefficient of the k-th power in the polynomial
+    (which is equivalent to ``p.c[-(i+1)]``):
+
+    >>> p[1]
+    2
+
+    Polynomials can be added, subtracted, multiplied, and divided
+    (returns quotient and remainder):
+
+    >>> p * p
+    poly1d([ 1,  4, 10, 12,  9])
+
+    >>> (p**3 + 4) / p
+    (poly1d([  1.,   4.,  10.,  12.,   9.]), poly1d([ 4.]))
+
+    ``asarray(p)`` gives the coefficient array, so polynomials can be
+    used in all functions that accept arrays:
+
+    >>> p**2 # square of polynomial
+    poly1d([ 1,  4, 10, 12,  9])
+
+    >>> np.square(p) # square of individual coefficients
+    array([1, 4, 9])
+
+    The variable used in the string representation of `p` can be modified,
+    using the `variable` parameter:
+
+    >>> p = np.poly1d([1,2,3], variable='z')
+    >>> print(p)
+       2
+    1 z + 2 z + 3
+
+    Construct a polynomial from its roots:
+
+    >>> np.poly1d([1, 2], True)
+    poly1d([ 1, -3,  2])
+
+    This is the same polynomial as obtained by:
+
+    >>> np.poly1d([1, -1]) * np.poly1d([1, -2])
+    poly1d([ 1, -3,  2])
+
+    """
+    coeffs = None
+    order = None
+    variable = None
+    __hash__ = None
+
+    def __init__(self, c_or_r, r=0, variable=None):
+        if isinstance(c_or_r, poly1d):
+            for key in c_or_r.__dict__.keys():
+                self.__dict__[key] = c_or_r.__dict__[key]
+            if variable is not None:
+                self.__dict__['variable'] = variable
+            return
+        if r:
+            c_or_r = poly(c_or_r)
+        c_or_r = atleast_1d(c_or_r)
+        if len(c_or_r.shape) > 1:
+            raise ValueError("Polynomial must be 1d only.")
+        c_or_r = trim_zeros(c_or_r, trim='f')
+        if len(c_or_r) == 0:
+            c_or_r = NX.array([0.])
+        self.__dict__['coeffs'] = c_or_r
+        self.__dict__['order'] = len(c_or_r) - 1
+        if variable is None:
+            variable = 'x'
+        self.__dict__['variable'] = variable
+
+    def __array__(self, t=None):
+        if t:
+            return NX.asarray(self.coeffs, t)
+        else:
+            return NX.asarray(self.coeffs)
+
+    def __repr__(self):
+        vals = repr(self.coeffs)
+        vals = vals[6:-1]
+        return "poly1d(%s)" % vals
+
+    def __len__(self):
+        return self.order
+
+    def __str__(self):
+        thestr = "0"
+        var = self.variable
+
+        # Remove leading zeros
+        coeffs = self.coeffs[NX.logical_or.accumulate(self.coeffs != 0)]
+        N = len(coeffs)-1
+
+        def fmt_float(q):
+            s = '%.4g' % q
+            if s.endswith('.0000'):
+                s = s[:-5]
+            return s
+
+        for k in range(len(coeffs)):
+            if not iscomplex(coeffs[k]):
+                coefstr = fmt_float(real(coeffs[k]))
+            elif real(coeffs[k]) == 0:
+                coefstr = '%sj' % fmt_float(imag(coeffs[k]))
+            else:
+                coefstr = '(%s + %sj)' % (fmt_float(real(coeffs[k])),
+                                          fmt_float(imag(coeffs[k])))
+
+            power = (N-k)
+            if power == 0:
+                if coefstr != '0':
+                    newstr = '%s' % (coefstr,)
+                else:
+                    if k == 0:
+                        newstr = '0'
+                    else:
+                        newstr = ''
+            elif power == 1:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == 'b':
+                    newstr = var
+                else:
+                    newstr = '%s %s' % (coefstr, var)
+            else:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == 'b':
+                    newstr = '%s**%d' % (var, power,)
+                else:
+                    newstr = '%s %s**%d' % (coefstr, var, power)
+
+            if k > 0:
+                if newstr != '':
+                    if newstr.startswith('-'):
+                        thestr = "%s - %s" % (thestr, newstr[1:])
+                    else:
+                        thestr = "%s + %s" % (thestr, newstr)
+            else:
+                thestr = newstr
+        return _raise_power(thestr)
+
+    def __call__(self, val):
+        return polyval(self.coeffs, val)
+
+    def __neg__(self):
+        return poly1d(-self.coeffs)
+
+    def __pos__(self):
+        return self
+
+    def __mul__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs * other)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))
+
+    def __rmul__(self, other):
+        if isscalar(other):
+            return poly1d(other * self.coeffs)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))
+
+    def __add__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))
+
+    def __radd__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))
+
+    def __pow__(self, val):
+        if not isscalar(val) or int(val) != val or val < 0:
+            raise ValueError("Power to non-negative integers only.")
+        res = [1]
+        for _ in range(val):
+            res = polymul(self.coeffs, res)
+        return poly1d(res)
+
+    def __sub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(self.coeffs, other.coeffs))
+
+    def __rsub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(other.coeffs, self.coeffs))
+
+    def __div__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs/other)
+        else:
+            other = poly1d(other)
+            return polydiv(self, other)
+
+    __truediv__ = __div__
+
+    def __rdiv__(self, other):
+        if isscalar(other):
+            return poly1d(other/self.coeffs)
+        else:
+            other = poly1d(other)
+            return polydiv(other, self)
+
+    __rtruediv__ = __rdiv__
+
+    def __eq__(self, other):
+        if self.coeffs.shape != other.coeffs.shape:
+            return False
+        return (self.coeffs == other.coeffs).all()
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __setattr__(self, key, val):
+        raise ValueError("Attributes cannot be changed this way.")
+
+    def __getattr__(self, key):
+        if key in ['r', 'roots']:
+            return roots(self.coeffs)
+        elif key in ['c', 'coef', 'coefficients']:
+            return self.coeffs
+        elif key in ['o']:
+            return self.order
+        else:
+            try:
+                return self.__dict__[key]
+            except KeyError:
+                raise AttributeError(
+                    "'%s' has no attribute '%s'" % (self.__class__, key))
+
+    def __getitem__(self, val):
+        ind = self.order - val
+        if val > self.order:
+            return 0
+        if val < 0:
+            return 0
+        return self.coeffs[ind]
+
+    def __setitem__(self, key, val):
+        ind = self.order - key
+        if key < 0:
+            raise ValueError("Does not support negative powers.")
+        if key > self.order:
+            zr = NX.zeros(key-self.order, self.coeffs.dtype)
+            self.__dict__['coeffs'] = NX.concatenate((zr, self.coeffs))
+            self.__dict__['order'] = key
+            ind = 0
+        self.__dict__['coeffs'][ind] = val
+        return
+
+    def __iter__(self):
+        return iter(self.coeffs)
+
+    def integ(self, m=1, k=0):
+        """
+        Return an antiderivative (indefinite integral) of this polynomial.
+
+        Refer to `polyint` for full documentation.
+
+        See Also
+        --------
+        polyint : equivalent function
+
+        """
+        return poly1d(polyint(self.coeffs, m=m, k=k))
+
+    def deriv(self, m=1):
+        """
+        Return a derivative of this polynomial.
+
+        Refer to `polyder` for full documentation.
+
+        See Also
+        --------
+        polyder : equivalent function
+
+        """
+        return poly1d(polyder(self.coeffs, m=m))
+
+# Stuff to do on module import
+
+warnings.simplefilter('always', RankWarning)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.py
new file mode 100644
index 0000000000..4ae1079d28
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.py
@@ -0,0 +1,1003 @@
+"""
+Collection of utilities to manipulate structured arrays.
+
+Most of these functions were initially implemented by John Hunter for
+matplotlib.  They have been rewritten and extended for convenience.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import sys
+import itertools
+import numpy as np
+import numpy.ma as ma
+from numpy import ndarray, recarray
+from numpy.ma import MaskedArray
+from numpy.ma.mrecords import MaskedRecords
+from numpy.lib._iotools import _is_string_like
+from numpy.compat import basestring
+
+if sys.version_info[0] < 3:
+    from future_builtins import zip
+
+_check_fill_value = np.ma.core._check_fill_value
+
+
+__all__ = [
+    'append_fields', 'drop_fields', 'find_duplicates',
+    'get_fieldstructure', 'join_by', 'merge_arrays',
+    'rec_append_fields', 'rec_drop_fields', 'rec_join',
+    'recursive_fill_fields', 'rename_fields', 'stack_arrays',
+    ]
+
+
+def recursive_fill_fields(input, output):
+    """
+    Fills fields from output with fields from input,
+    with support for nested structures.
+
+    Parameters
+    ----------
+    input : ndarray
+        Input array.
+    output : ndarray
+        Output array.
+
+    Notes
+    -----
+    * `output` should be at least the same size as `input`
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)])
+    >>> b = np.zeros((3,), dtype=a.dtype)
+    >>> rfn.recursive_fill_fields(a, b)
+    array([(1, 10.0), (2, 20.0), (0, 0.0)],
+          dtype=[('A', '<i4'), ('B', '<f8')])
+
+    """
+    newdtype = output.dtype
+    for field in newdtype.names:
+        try:
+            current = input[field]
+        except ValueError:
+            continue
+        if current.dtype.names:
+            recursive_fill_fields(current, output[field])
+        else:
+            output[field][:len(current)] = current
+    return output
+
+
+def get_names(adtype):
+    """
+    Returns the field names of the input datatype as a tuple.
+
+    Parameters
+    ----------
+    adtype : dtype
+        Input datatype
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.get_names(np.empty((1,), dtype=int)) is None
+    True
+    >>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)]))
+    ('A', 'B')
+    >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
+    >>> rfn.get_names(adtype)
+    ('a', ('b', ('ba', 'bb')))
+    """
+    listnames = []
+    names = adtype.names
+    for name in names:
+        current = adtype[name]
+        if current.names:
+            listnames.append((name, tuple(get_names(current))))
+        else:
+            listnames.append(name)
+    return tuple(listnames) or None
+
+
+def get_names_flat(adtype):
+    """
+    Returns the field names of the input datatype as a tuple. Nested structure
+    are flattend beforehand.
+
+    Parameters
+    ----------
+    adtype : dtype
+        Input datatype
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.get_names_flat(np.empty((1,), dtype=int)) is None
+    True
+    >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', float)]))
+    ('A', 'B')
+    >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])])
+    >>> rfn.get_names_flat(adtype)
+    ('a', 'b', 'ba', 'bb')
+    """
+    listnames = []
+    names = adtype.names
+    for name in names:
+        listnames.append(name)
+        current = adtype[name]
+        if current.names:
+            listnames.extend(get_names_flat(current))
+    return tuple(listnames) or None
+
+
+def flatten_descr(ndtype):
+    """
+    Flatten a structured data-type description.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype = np.dtype([('a', '<i4'), ('b', [('ba', '<f8'), ('bb', '<i4')])])
+    >>> rfn.flatten_descr(ndtype)
+    (('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))
+
+    """
+    names = ndtype.names
+    if names is None:
+        return ndtype.descr
+    else:
+        descr = []
+        for field in names:
+            (typ, _) = ndtype.fields[field]
+            if typ.names:
+                descr.extend(flatten_descr(typ))
+            else:
+                descr.append((field, typ))
+        return tuple(descr)
+
+
+def zip_descr(seqarrays, flatten=False):
+    """
+    Combine the dtype description of a series of arrays.
+
+    Parameters
+    ----------
+    seqarrays : sequence of arrays
+        Sequence of arrays
+    flatten : {boolean}, optional
+        Whether to collapse nested descriptions.
+    """
+    newdtype = []
+    if flatten:
+        for a in seqarrays:
+            newdtype.extend(flatten_descr(a.dtype))
+    else:
+        for a in seqarrays:
+            current = a.dtype
+            names = current.names or ()
+            if len(names) > 1:
+                newdtype.append(('', current.descr))
+            else:
+                newdtype.extend(current.descr)
+    return np.dtype(newdtype).descr
+
+
+def get_fieldstructure(adtype, lastname=None, parents=None,):
+    """
+    Returns a dictionary with fields indexing lists of their parent fields.
+
+    This function is used to simplify access to fields nested in other fields.
+
+    Parameters
+    ----------
+    adtype : np.dtype
+        Input datatype
+    lastname : optional
+        Last processed field name (used internally during recursion).
+    parents : dictionary
+        Dictionary of parent fields (used interbally during recursion).
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype =  np.dtype([('A', int),
+    ...                     ('B', [('BA', int),
+    ...                            ('BB', [('BBA', int), ('BBB', int)])])])
+    >>> rfn.get_fieldstructure(ndtype)
+    ... # XXX: possible regression, order of BBA and BBB is swapped
+    {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
+
+    """
+    if parents is None:
+        parents = {}
+    names = adtype.names
+    for name in names:
+        current = adtype[name]
+        if current.names:
+            if lastname:
+                parents[name] = [lastname, ]
+            else:
+                parents[name] = []
+            parents.update(get_fieldstructure(current, name, parents))
+        else:
+            lastparent = [_ for _ in (parents.get(lastname, []) or [])]
+            if lastparent:
+                lastparent.append(lastname)
+            elif lastname:
+                lastparent = [lastname, ]
+            parents[name] = lastparent or []
+    return parents or None
+
+
+def _izip_fields_flat(iterable):
+    """
+    Returns an iterator of concatenated fields from a sequence of arrays,
+    collapsing any nested structure.
+
+    """
+    for element in iterable:
+        if isinstance(element, np.void):
+            for f in _izip_fields_flat(tuple(element)):
+                yield f
+        else:
+            yield element
+
+
+def _izip_fields(iterable):
+    """
+    Returns an iterator of concatenated fields from a sequence of arrays.
+
+    """
+    for element in iterable:
+        if (hasattr(element, '__iter__') and
+                not isinstance(element, basestring)):
+            for f in _izip_fields(element):
+                yield f
+        elif isinstance(element, np.void) and len(tuple(element)) == 1:
+            for f in _izip_fields(element):
+                yield f
+        else:
+            yield element
+
+
+def izip_records(seqarrays, fill_value=None, flatten=True):
+    """
+    Returns an iterator of concatenated items from a sequence of arrays.
+
+    Parameters
+    ----------
+    seqarrays : sequence of arrays
+        Sequence of arrays.
+    fill_value : {None, integer}
+        Value used to pad shorter iterables.
+    flatten : {True, False},
+        Whether to
+    """
+    # OK, that's a complete ripoff from Python2.6 itertools.izip_longest
+    def sentinel(counter=([fill_value] * (len(seqarrays) - 1)).pop):
+        "Yields the fill_value or raises IndexError"
+        yield counter()
+    #
+    fillers = itertools.repeat(fill_value)
+    iters = [itertools.chain(it, sentinel(), fillers) for it in seqarrays]
+    # Should we flatten the items, or just use a nested approach
+    if flatten:
+        zipfunc = _izip_fields_flat
+    else:
+        zipfunc = _izip_fields
+    #
+    try:
+        for tup in zip(*iters):
+            yield tuple(zipfunc(tup))
+    except IndexError:
+        pass
+
+
+def _fix_output(output, usemask=True, asrecarray=False):
+    """
+    Private function: return a recarray, a ndarray, a MaskedArray
+    or a MaskedRecords depending on the input parameters
+    """
+    if not isinstance(output, MaskedArray):
+        usemask = False
+    if usemask:
+        if asrecarray:
+            output = output.view(MaskedRecords)
+    else:
+        output = ma.filled(output)
+        if asrecarray:
+            output = output.view(recarray)
+    return output
+
+
+def _fix_defaults(output, defaults=None):
+    """
+    Update the fill_value and masked data of `output`
+    from the default given in a dictionary defaults.
+    """
+    names = output.dtype.names
+    (data, mask, fill_value) = (output.data, output.mask, output.fill_value)
+    for (k, v) in (defaults or {}).items():
+        if k in names:
+            fill_value[k] = v
+            data[k][mask[k]] = v
+    return output
+
+
+def merge_arrays(seqarrays, fill_value=-1, flatten=False,
+                 usemask=False, asrecarray=False):
+    """
+    Merge arrays field by field.
+
+    Parameters
+    ----------
+    seqarrays : sequence of ndarrays
+        Sequence of arrays
+    fill_value : {float}, optional
+        Filling value used to pad missing data on the shorter arrays.
+    flatten : {False, True}, optional
+        Whether to collapse nested fields.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (MaskedRecords) or not.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])))
+    masked_array(data = [(1, 10.0) (2, 20.0) (--, 30.0)],
+                 mask = [(False, False) (False, False) (True, False)],
+           fill_value = (999999, 1e+20),
+                dtype = [('f0', '<i4'), ('f1', '<f8')])
+
+    >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.])),
+    ...              usemask=False)
+    array([(1, 10.0), (2, 20.0), (-1, 30.0)],
+          dtype=[('f0', '<i4'), ('f1', '<f8')])
+    >>> rfn.merge_arrays((np.array([1, 2]).view([('a', int)]),
+    ...               np.array([10., 20., 30.])),
+    ...              usemask=False, asrecarray=True)
+    rec.array([(1, 10.0), (2, 20.0), (-1, 30.0)],
+              dtype=[('a', '<i4'), ('f1', '<f8')])
+
+    Notes
+    -----
+    * Without a mask, the missing value will be filled with something,
+    * depending on what its corresponding type:
+            -1      for integers
+            -1.0    for floating point numbers
+            '-'     for characters
+            '-1'    for strings
+            True    for boolean values
+    * XXX: I just obtained these values empirically
+    """
+    # Only one item in the input sequence ?
+    if (len(seqarrays) == 1):
+        seqarrays = np.asanyarray(seqarrays[0])
+    # Do we have a single ndarray as input ?
+    if isinstance(seqarrays, (ndarray, np.void)):
+        seqdtype = seqarrays.dtype
+        if (not flatten) or \
+           (zip_descr((seqarrays,), flatten=True) == seqdtype.descr):
+            # Minimal processing needed: just make sure everythng's a-ok
+            seqarrays = seqarrays.ravel()
+            # Make sure we have named fields
+            if not seqdtype.names:
+                seqdtype = [('', seqdtype)]
+            # Find what type of array we must return
+            if usemask:
+                if asrecarray:
+                    seqtype = MaskedRecords
+                else:
+                    seqtype = MaskedArray
+            elif asrecarray:
+                seqtype = recarray
+            else:
+                seqtype = ndarray
+            return seqarrays.view(dtype=seqdtype, type=seqtype)
+        else:
+            seqarrays = (seqarrays,)
+    else:
+        # Make sure we have arrays in the input sequence
+        seqarrays = [np.asanyarray(_m) for _m in seqarrays]
+    # Find the sizes of the inputs and their maximum
+    sizes = tuple(a.size for a in seqarrays)
+    maxlength = max(sizes)
+    # Get the dtype of the output (flattening if needed)
+    newdtype = zip_descr(seqarrays, flatten=flatten)
+    # Initialize the sequences for data and mask
+    seqdata = []
+    seqmask = []
+    # If we expect some kind of MaskedArray, make a special loop.
+    if usemask:
+        for (a, n) in zip(seqarrays, sizes):
+            nbmissing = (maxlength - n)
+            # Get the data and mask
+            data = a.ravel().__array__()
+            mask = ma.getmaskarray(a).ravel()
+            # Get the filling value (if needed)
+            if nbmissing:
+                fval = _check_fill_value(fill_value, a.dtype)
+                if isinstance(fval, (ndarray, np.void)):
+                    if len(fval.dtype) == 1:
+                        fval = fval.item()[0]
+                        fmsk = True
+                    else:
+                        fval = np.array(fval, dtype=a.dtype, ndmin=1)
+                        fmsk = np.ones((1,), dtype=mask.dtype)
+            else:
+                fval = None
+                fmsk = True
+            # Store an iterator padding the input to the expected length
+            seqdata.append(itertools.chain(data, [fval] * nbmissing))
+            seqmask.append(itertools.chain(mask, [fmsk] * nbmissing))
+        # Create an iterator for the data
+        data = tuple(izip_records(seqdata, flatten=flatten))
+        output = ma.array(np.fromiter(data, dtype=newdtype, count=maxlength),
+                          mask=list(izip_records(seqmask, flatten=flatten)))
+        if asrecarray:
+            output = output.view(MaskedRecords)
+    else:
+        # Same as before, without the mask we don't need...
+        for (a, n) in zip(seqarrays, sizes):
+            nbmissing = (maxlength - n)
+            data = a.ravel().__array__()
+            if nbmissing:
+                fval = _check_fill_value(fill_value, a.dtype)
+                if isinstance(fval, (ndarray, np.void)):
+                    if len(fval.dtype) == 1:
+                        fval = fval.item()[0]
+                    else:
+                        fval = np.array(fval, dtype=a.dtype, ndmin=1)
+            else:
+                fval = None
+            seqdata.append(itertools.chain(data, [fval] * nbmissing))
+        output = np.fromiter(tuple(izip_records(seqdata, flatten=flatten)),
+                             dtype=newdtype, count=maxlength)
+        if asrecarray:
+            output = output.view(recarray)
+    # And we're done...
+    return output
+
+
+def drop_fields(base, drop_names, usemask=True, asrecarray=False):
+    """
+    Return a new array with fields in `drop_names` dropped.
+
+    Nested fields are supported.
+
+    Parameters
+    ----------
+    base : array
+        Input array
+    drop_names : string or sequence
+        String or sequence of strings corresponding to the names of the
+        fields to drop.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : string or sequence, optional
+        Whether to return a recarray or a mrecarray (`asrecarray=True`) or
+        a plain ndarray or masked array with flexible dtype. The default
+        is False.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+    ...   dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+    >>> rfn.drop_fields(a, 'a')
+    array([((2.0, 3),), ((5.0, 6),)],
+          dtype=[('b', [('ba', '<f8'), ('bb', '<i4')])])
+    >>> rfn.drop_fields(a, 'ba')
+    array([(1, (3,)), (4, (6,))],
+          dtype=[('a', '<i4'), ('b', [('bb', '<i4')])])
+    >>> rfn.drop_fields(a, ['ba', 'bb'])
+    array([(1,), (4,)],
+          dtype=[('a', '<i4')])
+    """
+    if _is_string_like(drop_names):
+        drop_names = [drop_names, ]
+    else:
+        drop_names = set(drop_names)
+
+    def _drop_descr(ndtype, drop_names):
+        names = ndtype.names
+        newdtype = []
+        for name in names:
+            current = ndtype[name]
+            if name in drop_names:
+                continue
+            if current.names:
+                descr = _drop_descr(current, drop_names)
+                if descr:
+                    newdtype.append((name, descr))
+            else:
+                newdtype.append((name, current))
+        return newdtype
+
+    newdtype = _drop_descr(base.dtype, drop_names)
+    if not newdtype:
+        return None
+
+    output = np.empty(base.shape, dtype=newdtype)
+    output = recursive_fill_fields(base, output)
+    return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
+
+
+def rec_drop_fields(base, drop_names):
+    """
+    Returns a new numpy.recarray with fields in `drop_names` dropped.
+    """
+    return drop_fields(base, drop_names, usemask=False, asrecarray=True)
+
+
+def rename_fields(base, namemapper):
+    """
+    Rename the fields from a flexible-datatype ndarray or recarray.
+
+    Nested fields are supported.
+
+    Parameters
+    ----------
+    base : ndarray
+        Input array whose fields must be modified.
+    namemapper : dictionary
+        Dictionary mapping old field names to their new version.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
+    ...   dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])])
+    >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'})
+    array([(1, (2.0, [3.0, 30.0])), (4, (5.0, [6.0, 60.0]))],
+          dtype=[('A', '<i4'), ('b', [('ba', '<f8'), ('BB', '<f8', 2)])])
+
+    """
+    def _recursive_rename_fields(ndtype, namemapper):
+        newdtype = []
+        for name in ndtype.names:
+            newname = namemapper.get(name, name)
+            current = ndtype[name]
+            if current.names:
+                newdtype.append(
+                    (newname, _recursive_rename_fields(current, namemapper))
+                    )
+            else:
+                newdtype.append((newname, current))
+        return newdtype
+    newdtype = _recursive_rename_fields(base.dtype, namemapper)
+    return base.view(newdtype)
+
+
+def append_fields(base, names, data, dtypes=None,
+                  fill_value=-1, usemask=True, asrecarray=False):
+    """
+    Add new fields to an existing array.
+
+    The names of the fields are given with the `names` arguments,
+    the corresponding values with the `data` arguments.
+    If a single field is appended, `names`, `data` and `dtypes` do not have
+    to be lists but just values.
+
+    Parameters
+    ----------
+    base : array
+        Input array to extend.
+    names : string, sequence
+        String or sequence of strings corresponding to the names
+        of the new fields.
+    data : array or sequence of arrays
+        Array or sequence of arrays storing the fields to add to the base.
+    dtypes : sequence of datatypes, optional
+        Datatype or sequence of datatypes.
+        If None, the datatypes are estimated from the `data`.
+    fill_value : {float}, optional
+        Filling value used to pad missing data on the shorter arrays.
+    usemask : {False, True}, optional
+        Whether to return a masked array or not.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (MaskedRecords) or not.
+
+    """
+    # Check the names
+    if isinstance(names, (tuple, list)):
+        if len(names) != len(data):
+            msg = "The number of arrays does not match the number of names"
+            raise ValueError(msg)
+    elif isinstance(names, basestring):
+        names = [names, ]
+        data = [data, ]
+    #
+    if dtypes is None:
+        data = [np.array(a, copy=False, subok=True) for a in data]
+        data = [a.view([(name, a.dtype)]) for (name, a) in zip(names, data)]
+    else:
+        if not isinstance(dtypes, (tuple, list)):
+            dtypes = [dtypes, ]
+        if len(data) != len(dtypes):
+            if len(dtypes) == 1:
+                dtypes = dtypes * len(data)
+            else:
+                msg = "The dtypes argument must be None, a dtype, or a list."
+                raise ValueError(msg)
+        data = [np.array(a, copy=False, subok=True, dtype=d).view([(n, d)])
+                for (a, n, d) in zip(data, names, dtypes)]
+    #
+    base = merge_arrays(base, usemask=usemask, fill_value=fill_value)
+    if len(data) > 1:
+        data = merge_arrays(data, flatten=True, usemask=usemask,
+                            fill_value=fill_value)
+    else:
+        data = data.pop()
+    #
+    output = ma.masked_all(max(len(base), len(data)),
+                           dtype=base.dtype.descr + data.dtype.descr)
+    output = recursive_fill_fields(base, output)
+    output = recursive_fill_fields(data, output)
+    #
+    return _fix_output(output, usemask=usemask, asrecarray=asrecarray)
+
+
+def rec_append_fields(base, names, data, dtypes=None):
+    """
+    Add new fields to an existing array.
+
+    The names of the fields are given with the `names` arguments,
+    the corresponding values with the `data` arguments.
+    If a single field is appended, `names`, `data` and `dtypes` do not have
+    to be lists but just values.
+
+    Parameters
+    ----------
+    base : array
+        Input array to extend.
+    names : string, sequence
+        String or sequence of strings corresponding to the names
+        of the new fields.
+    data : array or sequence of arrays
+        Array or sequence of arrays storing the fields to add to the base.
+    dtypes : sequence of datatypes, optional
+        Datatype or sequence of datatypes.
+        If None, the datatypes are estimated from the `data`.
+
+    See Also
+    --------
+    append_fields
+
+    Returns
+    -------
+    appended_array : np.recarray
+    """
+    return append_fields(base, names, data=data, dtypes=dtypes,
+                         asrecarray=True, usemask=False)
+
+
+def stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False,
+                 autoconvert=False):
+    """
+    Superposes arrays fields by fields
+
+    Parameters
+    ----------
+    arrays : array or sequence
+        Sequence of input arrays.
+    defaults : dictionary, optional
+        Dictionary mapping field names to the corresponding default values.
+    usemask : {True, False}, optional
+        Whether to return a MaskedArray (or MaskedRecords is
+        `asrecarray==True`) or a ndarray.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (or MaskedRecords if `usemask==True`)
+        or just a flexible-type ndarray.
+    autoconvert : {False, True}, optional
+        Whether automatically cast the type of the field to the maximum.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> x = np.array([1, 2,])
+    >>> rfn.stack_arrays(x) is x
+    True
+    >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)])
+    >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+    ...   dtype=[('A', '|S3'), ('B', float), ('C', float)])
+    >>> test = rfn.stack_arrays((z,zz))
+    >>> test
+    masked_array(data = [('A', 1.0, --) ('B', 2.0, --) ('a', 10.0, 100.0) ('b', 20.0, 200.0)
+     ('c', 30.0, 300.0)],
+                 mask = [(False, False, True) (False, False, True) (False, False, False)
+     (False, False, False) (False, False, False)],
+           fill_value = ('N/A', 1e+20, 1e+20),
+                dtype = [('A', '|S3'), ('B', '<f8'), ('C', '<f8')])
+
+    """
+    if isinstance(arrays, ndarray):
+        return arrays
+    elif len(arrays) == 1:
+        return arrays[0]
+    seqarrays = [np.asanyarray(a).ravel() for a in arrays]
+    nrecords = [len(a) for a in seqarrays]
+    ndtype = [a.dtype for a in seqarrays]
+    fldnames = [d.names for d in ndtype]
+    #
+    dtype_l = ndtype[0]
+    newdescr = dtype_l.descr
+    names = [_[0] for _ in newdescr]
+    for dtype_n in ndtype[1:]:
+        for descr in dtype_n.descr:
+            name = descr[0] or ''
+            if name not in names:
+                newdescr.append(descr)
+                names.append(name)
+            else:
+                nameidx = names.index(name)
+                current_descr = newdescr[nameidx]
+                if autoconvert:
+                    if np.dtype(descr[1]) > np.dtype(current_descr[-1]):
+                        current_descr = list(current_descr)
+                        current_descr[-1] = descr[1]
+                        newdescr[nameidx] = tuple(current_descr)
+                elif descr[1] != current_descr[-1]:
+                    raise TypeError("Incompatible type '%s' <> '%s'" %
+                                    (dict(newdescr)[name], descr[1]))
+    # Only one field: use concatenate
+    if len(newdescr) == 1:
+        output = ma.concatenate(seqarrays)
+    else:
+        #
+        output = ma.masked_all((np.sum(nrecords),), newdescr)
+        offset = np.cumsum(np.r_[0, nrecords])
+        seen = []
+        for (a, n, i, j) in zip(seqarrays, fldnames, offset[:-1], offset[1:]):
+            names = a.dtype.names
+            if names is None:
+                output['f%i' % len(seen)][i:j] = a
+            else:
+                for name in n:
+                    output[name][i:j] = a[name]
+                    if name not in seen:
+                        seen.append(name)
+    #
+    return _fix_output(_fix_defaults(output, defaults),
+                       usemask=usemask, asrecarray=asrecarray)
+
+
+def find_duplicates(a, key=None, ignoremask=True, return_index=False):
+    """
+    Find the duplicates in a structured array along a given key
+
+    Parameters
+    ----------
+    a : array-like
+        Input array
+    key : {string, None}, optional
+        Name of the fields along which to check the duplicates.
+        If None, the search is performed by records
+    ignoremask : {True, False}, optional
+        Whether masked data should be discarded or considered as duplicates.
+    return_index : {False, True}, optional
+        Whether to return the indices of the duplicated values.
+
+    Examples
+    --------
+    >>> from numpy.lib import recfunctions as rfn
+    >>> ndtype = [('a', int)]
+    >>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3],
+    ...         mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype)
+    >>> rfn.find_duplicates(a, ignoremask=True, return_index=True)
+    ... # XXX: judging by the output, the ignoremask flag has no effect
+    """
+    a = np.asanyarray(a).ravel()
+    # Get a dictionary of fields
+    fields = get_fieldstructure(a.dtype)
+    # Get the sorting data (by selecting the corresponding field)
+    base = a
+    if key:
+        for f in fields[key]:
+            base = base[f]
+        base = base[key]
+    # Get the sorting indices and the sorted data
+    sortidx = base.argsort()
+    sortedbase = base[sortidx]
+    sorteddata = sortedbase.filled()
+    # Compare the sorting data
+    flag = (sorteddata[:-1] == sorteddata[1:])
+    # If masked data must be ignored, set the flag to false where needed
+    if ignoremask:
+        sortedmask = sortedbase.recordmask
+        flag[sortedmask[1:]] = False
+    flag = np.concatenate(([False], flag))
+    # We need to take the point on the left as well (else we're missing it)
+    flag[:-1] = flag[:-1] + flag[1:]
+    duplicates = a[sortidx][flag]
+    if return_index:
+        return (duplicates, sortidx[flag])
+    else:
+        return duplicates
+
+
+def join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
+                defaults=None, usemask=True, asrecarray=False):
+    """
+    Join arrays `r1` and `r2` on key `key`.
+
+    The key should be either a string or a sequence of string corresponding
+    to the fields used to join the array.  An exception is raised if the
+    `key` field cannot be found in the two input arrays.  Neither `r1` nor
+    `r2` should have any duplicates along `key`: the presence of duplicates
+    will make the output quite unreliable. Note that duplicates are not
+    looked for by the algorithm.
+
+    Parameters
+    ----------
+    key : {string, sequence}
+        A string or a sequence of strings corresponding to the fields used
+        for comparison.
+    r1, r2 : arrays
+        Structured arrays.
+    jointype : {'inner', 'outer', 'leftouter'}, optional
+        If 'inner', returns the elements common to both r1 and r2.
+        If 'outer', returns the common elements as well as the elements of
+        r1 not in r2 and the elements of not in r2.
+        If 'leftouter', returns the common elements and the elements of r1
+        not in r2.
+    r1postfix : string, optional
+        String appended to the names of the fields of r1 that are present
+        in r2 but absent of the key.
+    r2postfix : string, optional
+        String appended to the names of the fields of r2 that are present
+        in r1 but absent of the key.
+    defaults : {dictionary}, optional
+        Dictionary mapping field names to the corresponding default values.
+    usemask : {True, False}, optional
+        Whether to return a MaskedArray (or MaskedRecords is
+        `asrecarray==True`) or a ndarray.
+    asrecarray : {False, True}, optional
+        Whether to return a recarray (or MaskedRecords if `usemask==True`)
+        or just a flexible-type ndarray.
+
+    Notes
+    -----
+    * The output is sorted along the key.
+    * A temporary array is formed by dropping the fields not in the key for
+      the two arrays and concatenating the result. This array is then
+      sorted, and the common entries selected. The output is constructed by
+      filling the fields with the selected entries. Matching is not
+      preserved if there are some duplicates...
+
+    """
+    # Check jointype
+    if jointype not in ('inner', 'outer', 'leftouter'):
+        raise ValueError(
+                "The 'jointype' argument should be in 'inner', "
+                "'outer' or 'leftouter' (got '%s' instead)" % jointype
+                )
+    # If we have a single key, put it in a tuple
+    if isinstance(key, basestring):
+        key = (key,)
+
+    # Check the keys
+    for name in key:
+        if name not in r1.dtype.names:
+            raise ValueError('r1 does not have key field %s' % name)
+        if name not in r2.dtype.names:
+            raise ValueError('r2 does not have key field %s' % name)
+
+    # Make sure we work with ravelled arrays
+    r1 = r1.ravel()
+    r2 = r2.ravel()
+    # Fixme: nb2 below is never used. Commenting out for pyflakes.
+    # (nb1, nb2) = (len(r1), len(r2))
+    nb1 = len(r1)
+    (r1names, r2names) = (r1.dtype.names, r2.dtype.names)
+
+    # Check the names for collision
+    if (set.intersection(set(r1names), set(r2names)).difference(key) and
+            not (r1postfix or r2postfix)):
+        msg = "r1 and r2 contain common names, r1postfix and r2postfix "
+        msg += "can't be empty"
+        raise ValueError(msg)
+
+    # Make temporary arrays of just the keys
+    r1k = drop_fields(r1, [n for n in r1names if n not in key])
+    r2k = drop_fields(r2, [n for n in r2names if n not in key])
+
+    # Concatenate the two arrays for comparison
+    aux = ma.concatenate((r1k, r2k))
+    idx_sort = aux.argsort(order=key)
+    aux = aux[idx_sort]
+    #
+    # Get the common keys
+    flag_in = ma.concatenate(([False], aux[1:] == aux[:-1]))
+    flag_in[:-1] = flag_in[1:] + flag_in[:-1]
+    idx_in = idx_sort[flag_in]
+    idx_1 = idx_in[(idx_in < nb1)]
+    idx_2 = idx_in[(idx_in >= nb1)] - nb1
+    (r1cmn, r2cmn) = (len(idx_1), len(idx_2))
+    if jointype == 'inner':
+        (r1spc, r2spc) = (0, 0)
+    elif jointype == 'outer':
+        idx_out = idx_sort[~flag_in]
+        idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
+        idx_2 = np.concatenate((idx_2, idx_out[(idx_out >= nb1)] - nb1))
+        (r1spc, r2spc) = (len(idx_1) - r1cmn, len(idx_2) - r2cmn)
+    elif jointype == 'leftouter':
+        idx_out = idx_sort[~flag_in]
+        idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)]))
+        (r1spc, r2spc) = (len(idx_1) - r1cmn, 0)
+    # Select the entries from each input
+    (s1, s2) = (r1[idx_1], r2[idx_2])
+    #
+    # Build the new description of the output array .......
+    # Start with the key fields
+    ndtype = [list(_) for _ in r1k.dtype.descr]
+    # Add the other fields
+    ndtype.extend(list(_) for _ in r1.dtype.descr if _[0] not in key)
+    # Find the new list of names (it may be different from r1names)
+    names = list(_[0] for _ in ndtype)
+    for desc in r2.dtype.descr:
+        desc = list(desc)
+        name = desc[0]
+        # Have we seen the current name already ?
+        if name in names:
+            nameidx = ndtype.index(desc)
+            current = ndtype[nameidx]
+            # The current field is part of the key: take the largest dtype
+            if name in key:
+                current[-1] = max(desc[1], current[-1])
+            # The current field is not part of the key: add the suffixes
+            else:
+                current[0] += r1postfix
+                desc[0] += r2postfix
+                ndtype.insert(nameidx + 1, desc)
+        #... we haven't: just add the description to the current list
+        else:
+            names.extend(desc[0])
+            ndtype.append(desc)
+    # Revert the elements to tuples
+    ndtype = [tuple(_) for _ in ndtype]
+    # Find the largest nb of common fields :
+    # r1cmn and r2cmn should be equal, but...
+    cmn = max(r1cmn, r2cmn)
+    # Construct an empty array
+    output = ma.masked_all((cmn + r1spc + r2spc,), dtype=ndtype)
+    names = output.dtype.names
+    for f in r1names:
+        selected = s1[f]
+        if f not in names or (f in r2names and not r2postfix and f not in key):
+            f += r1postfix
+        current = output[f]
+        current[:r1cmn] = selected[:r1cmn]
+        if jointype in ('outer', 'leftouter'):
+            current[cmn:cmn + r1spc] = selected[r1cmn:]
+    for f in r2names:
+        selected = s2[f]
+        if f not in names or (f in r1names and not r1postfix and f not in key):
+            f += r2postfix
+        current = output[f]
+        current[:r2cmn] = selected[:r2cmn]
+        if (jointype == 'outer') and r2spc:
+            current[-r2spc:] = selected[r2cmn:]
+    # Sort and finalize the output
+    output.sort(order=key)
+    kwargs = dict(usemask=usemask, asrecarray=asrecarray)
+    return _fix_output(_fix_defaults(output, defaults), **kwargs)
+
+
+def rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
+             defaults=None):
+    """
+    Join arrays `r1` and `r2` on keys.
+    Alternative to join_by, that always returns a np.recarray.
+
+    See Also
+    --------
+    join_by : equivalent function
+    """
+    kwargs = dict(jointype=jointype, r1postfix=r1postfix, r2postfix=r2postfix,
+                  defaults=defaults, usemask=False, asrecarray=True)
+    return join_by(key, r1, r2, **kwargs)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/scimath.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/scimath.py
new file mode 100644
index 0000000000..e07caf805e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/scimath.py
@@ -0,0 +1,566 @@
+"""
+Wrapper functions to more user-friendly calling of certain math functions
+whose output data-type is different than the input data-type in certain
+domains of the input.
+
+For example, for functions like `log` with branch cuts, the versions in this
+module provide the mathematically valid answers in the complex plane::
+
+  >>> import math
+  >>> from numpy.lib import scimath
+  >>> scimath.log(-math.exp(1)) == (1+1j*math.pi)
+  True
+
+Similarly, `sqrt`, other base logarithms, `power` and trig functions are
+correctly handled.  See their respective docstrings for specific examples.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy.core.numeric as nx
+import numpy.core.numerictypes as nt
+from numpy.core.numeric import asarray, any
+from numpy.lib.type_check import isreal
+
+
+__all__ = [
+    'sqrt', 'log', 'log2', 'logn', 'log10', 'power', 'arccos', 'arcsin',
+    'arctanh'
+    ]
+
+
+_ln2 = nx.log(2.0)
+
+
+def _tocomplex(arr):
+    """Convert its input `arr` to a complex array.
+
+    The input is returned as a complex array of the smallest type that will fit
+    the original data: types like single, byte, short, etc. become csingle,
+    while others become cdouble.
+
+    A copy of the input is always made.
+
+    Parameters
+    ----------
+    arr : array
+
+    Returns
+    -------
+    array
+        An array with the same input data as the input but in complex form.
+
+    Examples
+    --------
+
+    First, consider an input of type short:
+
+    >>> a = np.array([1,2,3],np.short)
+
+    >>> ac = np.lib.scimath._tocomplex(a); ac
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+
+    >>> ac.dtype
+    dtype('complex64')
+
+    If the input is of type double, the output is correspondingly of the
+    complex double type as well:
+
+    >>> b = np.array([1,2,3],np.double)
+
+    >>> bc = np.lib.scimath._tocomplex(b); bc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j])
+
+    >>> bc.dtype
+    dtype('complex128')
+
+    Note that even if the input was complex to begin with, a copy is still
+    made, since the astype() method always copies:
+
+    >>> c = np.array([1,2,3],np.csingle)
+
+    >>> cc = np.lib.scimath._tocomplex(c); cc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+
+    >>> c *= 2; c
+    array([ 2.+0.j,  4.+0.j,  6.+0.j], dtype=complex64)
+
+    >>> cc
+    array([ 1.+0.j,  2.+0.j,  3.+0.j], dtype=complex64)
+    """
+    if issubclass(arr.dtype.type, (nt.single, nt.byte, nt.short, nt.ubyte,
+                                   nt.ushort, nt.csingle)):
+        return arr.astype(nt.csingle)
+    else:
+        return arr.astype(nt.cdouble)
+
+def _fix_real_lt_zero(x):
+    """Convert `x` to complex if it has real, negative components.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_real_lt_zero([1,2])
+    array([1, 2])
+
+    >>> np.lib.scimath._fix_real_lt_zero([-1,2])
+    array([-1.+0.j,  2.+0.j])
+
+    """
+    x = asarray(x)
+    if any(isreal(x) & (x < 0)):
+        x = _tocomplex(x)
+    return x
+
+def _fix_int_lt_zero(x):
+    """Convert `x` to double if it has real, negative components.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_int_lt_zero([1,2])
+    array([1, 2])
+
+    >>> np.lib.scimath._fix_int_lt_zero([-1,2])
+    array([-1.,  2.])
+    """
+    x = asarray(x)
+    if any(isreal(x) & (x < 0)):
+        x = x * 1.0
+    return x
+
+def _fix_real_abs_gt_1(x):
+    """Convert `x` to complex if it has real components x_i with abs(x_i)>1.
+
+    Otherwise, output is just the array version of the input (via asarray).
+
+    Parameters
+    ----------
+    x : array_like
+
+    Returns
+    -------
+    array
+
+    Examples
+    --------
+    >>> np.lib.scimath._fix_real_abs_gt_1([0,1])
+    array([0, 1])
+
+    >>> np.lib.scimath._fix_real_abs_gt_1([0,2])
+    array([ 0.+0.j,  2.+0.j])
+    """
+    x = asarray(x)
+    if any(isreal(x) & (abs(x) > 1)):
+        x = _tocomplex(x)
+    return x
+
+def sqrt(x):
+    """
+    Compute the square root of x.
+
+    For negative input elements, a complex value is returned
+    (unlike `numpy.sqrt` which returns NaN).
+
+    Parameters
+    ----------
+    x : array_like
+       The input value(s).
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The square root of `x`. If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.sqrt
+
+    Examples
+    --------
+    For real, non-negative inputs this works just like `numpy.sqrt`:
+
+    >>> np.lib.scimath.sqrt(1)
+    1.0
+    >>> np.lib.scimath.sqrt([1, 4])
+    array([ 1.,  2.])
+
+    But it automatically handles negative inputs:
+
+    >>> np.lib.scimath.sqrt(-1)
+    (0.0+1.0j)
+    >>> np.lib.scimath.sqrt([-1,4])
+    array([ 0.+1.j,  2.+0.j])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.sqrt(x)
+
+def log(x):
+    """
+    Compute the natural logarithm of `x`.
+
+    Return the "principal value" (for a description of this, see `numpy.log`)
+    of :math:`log_e(x)`. For real `x > 0`, this is a real number (``log(0)``
+    returns ``-inf`` and ``log(np.inf)`` returns ``inf``). Otherwise, the
+    complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose log is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.log
+
+    Notes
+    -----
+    For a log() that returns ``NAN`` when real `x < 0`, use `numpy.log`
+    (note, however, that otherwise `numpy.log` and this `log` are identical,
+    i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`, and,
+    notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+    >>> np.emath.log(np.exp(1))
+    1.0
+
+    Negative arguments are handled "correctly" (recall that
+    ``exp(log(x)) == x`` does *not* hold for real ``x < 0``):
+
+    >>> np.emath.log(-np.exp(1)) == (1 + np.pi * 1j)
+    True
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log(x)
+
+def log10(x):
+    """
+    Compute the logarithm base 10 of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.log10`) of :math:`log_{10}(x)`. For real `x > 0`, this
+    is a real number (``log10(0)`` returns ``-inf`` and ``log10(np.inf)``
+    returns ``inf``). Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose log base 10 is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base 10 of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.log10
+
+    Notes
+    -----
+    For a log10() that returns ``NAN`` when real `x < 0`, use `numpy.log10`
+    (note, however, that otherwise `numpy.log10` and this `log10` are
+    identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`,
+    and, notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+
+    (We set the printing precision so the example can be auto-tested)
+
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.log10(10**1)
+    1.0
+
+    >>> np.emath.log10([-10**1, -10**2, 10**2])
+    array([ 1.+1.3644j,  2.+1.3644j,  2.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log10(x)
+
+def logn(n, x):
+    """
+    Take log base n of x.
+
+    If `x` contains negative inputs, the answer is computed and returned in the
+    complex domain.
+
+    Parameters
+    ----------
+    n : int
+       The base in which the log is taken.
+    x : array_like
+       The value(s) whose log base `n` is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base `n` of the `x` value(s). If `x` was a scalar, so is
+       `out`, otherwise an array is returned.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.lib.scimath.logn(2, [4, 8])
+    array([ 2.,  3.])
+    >>> np.lib.scimath.logn(2, [-4, -8, 8])
+    array([ 2.+4.5324j,  3.+4.5324j,  3.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    n = _fix_real_lt_zero(n)
+    return nx.log(x)/nx.log(n)
+
+def log2(x):
+    """
+    Compute the logarithm base 2 of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.log2`) of :math:`log_2(x)`. For real `x > 0`, this is
+    a real number (``log2(0)`` returns ``-inf`` and ``log2(np.inf)`` returns
+    ``inf``). Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose log base 2 is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The log base 2 of the `x` value(s). If `x` was a scalar, so is `out`,
+       otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.log2
+
+    Notes
+    -----
+    For a log2() that returns ``NAN`` when real `x < 0`, use `numpy.log2`
+    (note, however, that otherwise `numpy.log2` and this `log2` are
+    identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`,
+    and, notably, the complex principle value if ``x.imag != 0``).
+
+    Examples
+    --------
+    We set the printing precision so the example can be auto-tested:
+
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.log2(8)
+    3.0
+    >>> np.emath.log2([-4, -8, 8])
+    array([ 2.+4.5324j,  3.+4.5324j,  3.+0.j    ])
+
+    """
+    x = _fix_real_lt_zero(x)
+    return nx.log2(x)
+
+def power(x, p):
+    """
+    Return x to the power p, (x**p).
+
+    If `x` contains negative values, the output is converted to the
+    complex domain.
+
+    Parameters
+    ----------
+    x : array_like
+        The input value(s).
+    p : array_like of ints
+        The power(s) to which `x` is raised. If `x` contains multiple values,
+        `p` has to either be a scalar, or contain the same number of values
+        as `x`. In the latter case, the result is
+        ``x[0]**p[0], x[1]**p[1], ...``.
+
+    Returns
+    -------
+    out : ndarray or scalar
+        The result of ``x**p``. If `x` and `p` are scalars, so is `out`,
+        otherwise an array is returned.
+
+    See Also
+    --------
+    numpy.power
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.lib.scimath.power([2, 4], 2)
+    array([ 4, 16])
+    >>> np.lib.scimath.power([2, 4], -2)
+    array([ 0.25  ,  0.0625])
+    >>> np.lib.scimath.power([-2, 4], 2)
+    array([  4.+0.j,  16.+0.j])
+
+    """
+    x = _fix_real_lt_zero(x)
+    p = _fix_int_lt_zero(p)
+    return nx.power(x, p)
+
+def arccos(x):
+    """
+    Compute the inverse cosine of x.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arccos`) of the inverse cosine of `x`. For real `x` such that
+    `abs(x) <= 1`, this is a real number in the closed interval
+    :math:`[0, \\pi]`.  Otherwise, the complex principle value is returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose arccos is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse cosine(s) of the `x` value(s). If `x` was a scalar, so
+       is `out`, otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.arccos
+
+    Notes
+    -----
+    For an arccos() that returns ``NAN`` when real `x` is not in the
+    interval ``[-1,1]``, use `numpy.arccos`.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arccos(1) # a scalar is returned
+    0.0
+
+    >>> np.emath.arccos([1,2])
+    array([ 0.-0.j   ,  0.+1.317j])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arccos(x)
+
+def arcsin(x):
+    """
+    Compute the inverse sine of x.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arcsin`) of the inverse sine of `x`. For real `x` such that
+    `abs(x) <= 1`, this is a real number in the closed interval
+    :math:`[-\\pi/2, \\pi/2]`.  Otherwise, the complex principle value is
+    returned.
+
+    Parameters
+    ----------
+    x : array_like or scalar
+       The value(s) whose arcsin is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse sine(s) of the `x` value(s). If `x` was a scalar, so
+       is `out`, otherwise an array object is returned.
+
+    See Also
+    --------
+    numpy.arcsin
+
+    Notes
+    -----
+    For an arcsin() that returns ``NAN`` when real `x` is not in the
+    interval ``[-1,1]``, use `numpy.arcsin`.
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arcsin(0)
+    0.0
+
+    >>> np.emath.arcsin([0,1])
+    array([ 0.    ,  1.5708])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arcsin(x)
+
+def arctanh(x):
+    """
+    Compute the inverse hyperbolic tangent of `x`.
+
+    Return the "principal value" (for a description of this, see
+    `numpy.arctanh`) of `arctanh(x)`. For real `x` such that
+    `abs(x) < 1`, this is a real number.  If `abs(x) > 1`, or if `x` is
+    complex, the result is complex. Finally, `x = 1` returns``inf`` and
+    `x=-1` returns ``-inf``.
+
+    Parameters
+    ----------
+    x : array_like
+       The value(s) whose arctanh is (are) required.
+
+    Returns
+    -------
+    out : ndarray or scalar
+       The inverse hyperbolic tangent(s) of the `x` value(s). If `x` was
+       a scalar so is `out`, otherwise an array is returned.
+
+
+    See Also
+    --------
+    numpy.arctanh
+
+    Notes
+    -----
+    For an arctanh() that returns ``NAN`` when real `x` is not in the
+    interval ``(-1,1)``, use `numpy.arctanh` (this latter, however, does
+    return +/-inf for `x = +/-1`).
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=4)
+
+    >>> np.emath.arctanh(np.matrix(np.eye(2)))
+    array([[ Inf,   0.],
+           [  0.,  Inf]])
+    >>> np.emath.arctanh([1j])
+    array([ 0.+0.7854j])
+
+    """
+    x = _fix_real_abs_gt_1(x)
+    return nx.arctanh(x)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/setup.py
new file mode 100644
index 0000000000..d342410b8a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/setup.py
@@ -0,0 +1,12 @@
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+
+    config = Configuration('lib', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.py
new file mode 100644
index 0000000000..ffbe567216
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.py
@@ -0,0 +1,873 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import (
+    asarray, zeros, outer, concatenate, isscalar, array, asanyarray
+    )
+from numpy.core.fromnumeric import product, reshape
+from numpy.core import vstack, atleast_3d
+
+
+__all__ = [
+    'column_stack', 'row_stack', 'dstack', 'array_split', 'split',
+    'hsplit', 'vsplit', 'dsplit', 'apply_over_axes', 'expand_dims',
+    'apply_along_axis', 'kron', 'tile', 'get_array_wrap'
+    ]
+
+
+def apply_along_axis(func1d, axis, arr, *args, **kwargs):
+    """
+    Apply a function to 1-D slices along the given axis.
+
+    Execute `func1d(a, *args)` where `func1d` operates on 1-D arrays and `a`
+    is a 1-D slice of `arr` along `axis`.
+
+    Parameters
+    ----------
+    func1d : function
+        This function should accept 1-D arrays. It is applied to 1-D
+        slices of `arr` along the specified axis.
+    axis : integer
+        Axis along which `arr` is sliced.
+    arr : ndarray
+        Input array.
+    args : any
+        Additional arguments to `func1d`.
+    kwargs: any
+        Additional named arguments to `func1d`.
+
+        .. versionadded:: 1.9.0
+
+
+    Returns
+    -------
+    apply_along_axis : ndarray
+        The output array. The shape of `outarr` is identical to the shape of
+        `arr`, except along the `axis` dimension, where the length of `outarr`
+        is equal to the size of the return value of `func1d`.  If `func1d`
+        returns a scalar `outarr` will have one fewer dimensions than `arr`.
+
+    See Also
+    --------
+    apply_over_axes : Apply a function repeatedly over multiple axes.
+
+    Examples
+    --------
+    >>> def my_func(a):
+    ...     \"\"\"Average first and last element of a 1-D array\"\"\"
+    ...     return (a[0] + a[-1]) * 0.5
+    >>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])
+    >>> np.apply_along_axis(my_func, 0, b)
+    array([ 4.,  5.,  6.])
+    >>> np.apply_along_axis(my_func, 1, b)
+    array([ 2.,  5.,  8.])
+
+    For a function that doesn't return a scalar, the number of dimensions in
+    `outarr` is the same as `arr`.
+
+    >>> b = np.array([[8,1,7], [4,3,9], [5,2,6]])
+    >>> np.apply_along_axis(sorted, 1, b)
+    array([[1, 7, 8],
+           [3, 4, 9],
+           [2, 5, 6]])
+
+    """
+    arr = asarray(arr)
+    nd = arr.ndim
+    if axis < 0:
+        axis += nd
+    if (axis >= nd):
+        raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d."
+            % (axis, nd))
+    ind = [0]*(nd-1)
+    i = zeros(nd, 'O')
+    indlist = list(range(nd))
+    indlist.remove(axis)
+    i[axis] = slice(None, None)
+    outshape = asarray(arr.shape).take(indlist)
+    i.put(indlist, ind)
+    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+    #  if res is a number, then we have a smaller output array
+    if isscalar(res):
+        outarr = zeros(outshape, asarray(res).dtype)
+        outarr[tuple(ind)] = res
+        Ntot = product(outshape)
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= outshape[n]) and (n > (1-nd)):
+                ind[n-1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(ind)] = res
+            k += 1
+        return outarr
+    else:
+        Ntot = product(outshape)
+        holdshape = outshape
+        outshape = list(arr.shape)
+        outshape[axis] = len(res)
+        outarr = zeros(outshape, asarray(res).dtype)
+        outarr[tuple(i.tolist())] = res
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= holdshape[n]) and (n > (1-nd)):
+                ind[n-1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(i.tolist())] = res
+            k += 1
+        return outarr
+
+
+def apply_over_axes(func, a, axes):
+    """
+    Apply a function repeatedly over multiple axes.
+
+    `func` is called as `res = func(a, axis)`, where `axis` is the first
+    element of `axes`.  The result `res` of the function call must have
+    either the same dimensions as `a` or one less dimension.  If `res`
+    has one less dimension than `a`, a dimension is inserted before
+    `axis`.  The call to `func` is then repeated for each axis in `axes`,
+    with `res` as the first argument.
+
+    Parameters
+    ----------
+    func : function
+        This function must take two arguments, `func(a, axis)`.
+    a : array_like
+        Input array.
+    axes : array_like
+        Axes over which `func` is applied; the elements must be integers.
+
+    Returns
+    -------
+    apply_over_axis : ndarray
+        The output array.  The number of dimensions is the same as `a`,
+        but the shape can be different.  This depends on whether `func`
+        changes the shape of its output with respect to its input.
+
+    See Also
+    --------
+    apply_along_axis :
+        Apply a function to 1-D slices of an array along the given axis.
+
+    Notes
+    ------
+    This function is equivalent to tuple axis arguments to reorderable ufuncs
+    with keepdims=True. Tuple axis arguments to ufuncs have been availabe since
+    version 1.7.0.
+
+    Examples
+    --------
+    >>> a = np.arange(24).reshape(2,3,4)
+    >>> a
+    array([[[ 0,  1,  2,  3],
+            [ 4,  5,  6,  7],
+            [ 8,  9, 10, 11]],
+           [[12, 13, 14, 15],
+            [16, 17, 18, 19],
+            [20, 21, 22, 23]]])
+
+    Sum over axes 0 and 2. The result has same number of dimensions
+    as the original array:
+
+    >>> np.apply_over_axes(np.sum, a, [0,2])
+    array([[[ 60],
+            [ 92],
+            [124]]])
+
+    Tuple axis arguments to ufuncs are equivalent:
+
+    >>> np.sum(a, axis=(0,2), keepdims=True)
+    array([[[ 60],
+            [ 92],
+            [124]]])
+
+    """
+    val = asarray(a)
+    N = a.ndim
+    if array(axes).ndim == 0:
+        axes = (axes,)
+    for axis in axes:
+        if axis < 0:
+            axis = N + axis
+        args = (val, axis)
+        res = func(*args)
+        if res.ndim == val.ndim:
+            val = res
+        else:
+            res = expand_dims(res, axis)
+            if res.ndim == val.ndim:
+                val = res
+            else:
+                raise ValueError("function is not returning "
+                        "an array of the correct shape")
+    return val
+
+def expand_dims(a, axis):
+    """
+    Expand the shape of an array.
+
+    Insert a new axis, corresponding to a given position in the array shape.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    axis : int
+        Position (amongst axes) where new axis is to be inserted.
+
+    Returns
+    -------
+    res : ndarray
+        Output array. The number of dimensions is one greater than that of
+        the input array.
+
+    See Also
+    --------
+    doc.indexing, atleast_1d, atleast_2d, atleast_3d
+
+    Examples
+    --------
+    >>> x = np.array([1,2])
+    >>> x.shape
+    (2,)
+
+    The following is equivalent to ``x[np.newaxis,:]`` or ``x[np.newaxis]``:
+
+    >>> y = np.expand_dims(x, axis=0)
+    >>> y
+    array([[1, 2]])
+    >>> y.shape
+    (1, 2)
+
+    >>> y = np.expand_dims(x, axis=1)  # Equivalent to x[:,newaxis]
+    >>> y
+    array([[1],
+           [2]])
+    >>> y.shape
+    (2, 1)
+
+    Note that some examples may use ``None`` instead of ``np.newaxis``.  These
+    are the same objects:
+
+    >>> np.newaxis is None
+    True
+
+    """
+    a = asarray(a)
+    shape = a.shape
+    if axis < 0:
+        axis = axis + len(shape) + 1
+    return a.reshape(shape[:axis] + (1,) + shape[axis:])
+
+row_stack = vstack
+
+def column_stack(tup):
+    """
+    Stack 1-D arrays as columns into a 2-D array.
+
+    Take a sequence of 1-D arrays and stack them as columns
+    to make a single 2-D array. 2-D arrays are stacked as-is,
+    just like with `hstack`.  1-D arrays are turned into 2-D columns
+    first.
+
+    Parameters
+    ----------
+    tup : sequence of 1-D or 2-D arrays.
+        Arrays to stack. All of them must have the same first dimension.
+
+    Returns
+    -------
+    stacked : 2-D array
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    hstack, vstack, concatenate
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.column_stack((a,b))
+    array([[1, 2],
+           [2, 3],
+           [3, 4]])
+
+    """
+    arrays = []
+    for v in tup:
+        arr = array(v, copy=False, subok=True)
+        if arr.ndim < 2:
+            arr = array(arr, copy=False, subok=True, ndmin=2).T
+        arrays.append(arr)
+    return _nx.concatenate(arrays, 1)
+
+def dstack(tup):
+    """
+    Stack arrays in sequence depth wise (along third axis).
+
+    Takes a sequence of arrays and stack them along the third axis
+    to make a single array. Rebuilds arrays divided by `dsplit`.
+    This is a simple way to stack 2D arrays (images) into a single
+    3D array for processing.
+
+    Parameters
+    ----------
+    tup : sequence of arrays
+        Arrays to stack. All of them must have the same shape along all
+        but the third axis.
+
+    Returns
+    -------
+    stacked : ndarray
+        The array formed by stacking the given arrays.
+
+    See Also
+    --------
+    stack : Join a sequence of arrays along a new axis.
+    vstack : Stack along first axis.
+    hstack : Stack along second axis.
+    concatenate : Join a sequence of arrays along an existing axis.
+    dsplit : Split array along third axis.
+
+    Notes
+    -----
+    Equivalent to ``np.concatenate(tup, axis=2)``.
+
+    Examples
+    --------
+    >>> a = np.array((1,2,3))
+    >>> b = np.array((2,3,4))
+    >>> np.dstack((a,b))
+    array([[[1, 2],
+            [2, 3],
+            [3, 4]]])
+
+    >>> a = np.array([[1],[2],[3]])
+    >>> b = np.array([[2],[3],[4]])
+    >>> np.dstack((a,b))
+    array([[[1, 2]],
+           [[2, 3]],
+           [[3, 4]]])
+
+    """
+    return _nx.concatenate([atleast_3d(_m) for _m in tup], 2)
+
+def _replace_zero_by_x_arrays(sub_arys):
+    for i in range(len(sub_arys)):
+        if len(_nx.shape(sub_arys[i])) == 0:
+            sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
+        elif _nx.sometrue(_nx.equal(_nx.shape(sub_arys[i]), 0)):
+            sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype)
+    return sub_arys
+
+def array_split(ary, indices_or_sections, axis=0):
+    """
+    Split an array into multiple sub-arrays.
+
+    Please refer to the ``split`` documentation.  The only difference
+    between these functions is that ``array_split`` allows
+    `indices_or_sections` to be an integer that does *not* equally
+    divide the axis.
+
+    See Also
+    --------
+    split : Split array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(8.0)
+    >>> np.array_split(x, 3)
+        [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.])]
+
+    """
+    try:
+        Ntotal = ary.shape[axis]
+    except AttributeError:
+        Ntotal = len(ary)
+    try:
+        # handle scalar case.
+        Nsections = len(indices_or_sections) + 1
+        div_points = [0] + list(indices_or_sections) + [Ntotal]
+    except TypeError:
+        # indices_or_sections is a scalar, not an array.
+        Nsections = int(indices_or_sections)
+        if Nsections <= 0:
+            raise ValueError('number sections must be larger than 0.')
+        Neach_section, extras = divmod(Ntotal, Nsections)
+        section_sizes = ([0] +
+                         extras * [Neach_section+1] +
+                         (Nsections-extras) * [Neach_section])
+        div_points = _nx.array(section_sizes).cumsum()
+
+    sub_arys = []
+    sary = _nx.swapaxes(ary, axis, 0)
+    for i in range(Nsections):
+        st = div_points[i]
+        end = div_points[i + 1]
+        sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0))
+
+    return sub_arys
+
+
+def split(ary,indices_or_sections,axis=0):
+    """
+    Split an array into multiple sub-arrays.
+
+    Parameters
+    ----------
+    ary : ndarray
+        Array to be divided into sub-arrays.
+    indices_or_sections : int or 1-D array
+        If `indices_or_sections` is an integer, N, the array will be divided
+        into N equal arrays along `axis`.  If such a split is not possible,
+        an error is raised.
+
+        If `indices_or_sections` is a 1-D array of sorted integers, the entries
+        indicate where along `axis` the array is split.  For example,
+        ``[2, 3]`` would, for ``axis=0``, result in
+
+          - ary[:2]
+          - ary[2:3]
+          - ary[3:]
+
+        If an index exceeds the dimension of the array along `axis`,
+        an empty sub-array is returned correspondingly.
+    axis : int, optional
+        The axis along which to split, default is 0.
+
+    Returns
+    -------
+    sub-arrays : list of ndarrays
+        A list of sub-arrays.
+
+    Raises
+    ------
+    ValueError
+        If `indices_or_sections` is given as an integer, but
+        a split does not result in equal division.
+
+    See Also
+    --------
+    array_split : Split an array into multiple sub-arrays of equal or
+                  near-equal size.  Does not raise an exception if
+                  an equal division cannot be made.
+    hsplit : Split array into multiple sub-arrays horizontally (column-wise).
+    vsplit : Split array into multiple sub-arrays vertically (row wise).
+    dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
+    concatenate : Join a sequence of arrays along an existing axis.
+    stack : Join a sequence of arrays along a new axis.
+    hstack : Stack arrays in sequence horizontally (column wise).
+    vstack : Stack arrays in sequence vertically (row wise).
+    dstack : Stack arrays in sequence depth wise (along third dimension).
+
+    Examples
+    --------
+    >>> x = np.arange(9.0)
+    >>> np.split(x, 3)
+    [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.,  8.])]
+
+    >>> x = np.arange(8.0)
+    >>> np.split(x, [3, 5, 6, 10])
+    [array([ 0.,  1.,  2.]),
+     array([ 3.,  4.]),
+     array([ 5.]),
+     array([ 6.,  7.]),
+     array([], dtype=float64)]
+
+    """
+    try:
+        len(indices_or_sections)
+    except TypeError:
+        sections = indices_or_sections
+        N = ary.shape[axis]
+        if N % sections:
+            raise ValueError(
+                'array split does not result in an equal division')
+    res = array_split(ary, indices_or_sections, axis)
+    return res
+
+def hsplit(ary, indices_or_sections):
+    """
+    Split an array into multiple sub-arrays horizontally (column-wise).
+
+    Please refer to the `split` documentation.  `hsplit` is equivalent
+    to `split` with ``axis=1``, the array is always split along the second
+    axis regardless of the array dimension.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(4, 4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+    >>> np.hsplit(x, 2)
+    [array([[  0.,   1.],
+           [  4.,   5.],
+           [  8.,   9.],
+           [ 12.,  13.]]),
+     array([[  2.,   3.],
+           [  6.,   7.],
+           [ 10.,  11.],
+           [ 14.,  15.]])]
+    >>> np.hsplit(x, np.array([3, 6]))
+    [array([[  0.,   1.,   2.],
+           [  4.,   5.,   6.],
+           [  8.,   9.,  10.],
+           [ 12.,  13.,  14.]]),
+     array([[  3.],
+           [  7.],
+           [ 11.],
+           [ 15.]]),
+     array([], dtype=float64)]
+
+    With a higher dimensional array the split is still along the second axis.
+
+    >>> x = np.arange(8.0).reshape(2, 2, 2)
+    >>> x
+    array([[[ 0.,  1.],
+            [ 2.,  3.]],
+           [[ 4.,  5.],
+            [ 6.,  7.]]])
+    >>> np.hsplit(x, 2)
+    [array([[[ 0.,  1.]],
+           [[ 4.,  5.]]]),
+     array([[[ 2.,  3.]],
+           [[ 6.,  7.]]])]
+
+    """
+    if len(_nx.shape(ary)) == 0:
+        raise ValueError('hsplit only works on arrays of 1 or more dimensions')
+    if len(ary.shape) > 1:
+        return split(ary, indices_or_sections, 1)
+    else:
+        return split(ary, indices_or_sections, 0)
+
+def vsplit(ary, indices_or_sections):
+    """
+    Split an array into multiple sub-arrays vertically (row-wise).
+
+    Please refer to the ``split`` documentation.  ``vsplit`` is equivalent
+    to ``split`` with `axis=0` (default), the array is always split along the
+    first axis regardless of the array dimension.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(4, 4)
+    >>> x
+    array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])
+    >>> np.vsplit(x, 2)
+    [array([[ 0.,  1.,  2.,  3.],
+           [ 4.,  5.,  6.,  7.]]),
+     array([[  8.,   9.,  10.,  11.],
+           [ 12.,  13.,  14.,  15.]])]
+    >>> np.vsplit(x, np.array([3, 6]))
+    [array([[  0.,   1.,   2.,   3.],
+           [  4.,   5.,   6.,   7.],
+           [  8.,   9.,  10.,  11.]]),
+     array([[ 12.,  13.,  14.,  15.]]),
+     array([], dtype=float64)]
+
+    With a higher dimensional array the split is still along the first axis.
+
+    >>> x = np.arange(8.0).reshape(2, 2, 2)
+    >>> x
+    array([[[ 0.,  1.],
+            [ 2.,  3.]],
+           [[ 4.,  5.],
+            [ 6.,  7.]]])
+    >>> np.vsplit(x, 2)
+    [array([[[ 0.,  1.],
+            [ 2.,  3.]]]),
+     array([[[ 4.,  5.],
+            [ 6.,  7.]]])]
+
+    """
+    if len(_nx.shape(ary)) < 2:
+        raise ValueError('vsplit only works on arrays of 2 or more dimensions')
+    return split(ary, indices_or_sections, 0)
+
+def dsplit(ary, indices_or_sections):
+    """
+    Split array into multiple sub-arrays along the 3rd axis (depth).
+
+    Please refer to the `split` documentation.  `dsplit` is equivalent
+    to `split` with ``axis=2``, the array is always split along the third
+    axis provided the array dimension is greater than or equal to 3.
+
+    See Also
+    --------
+    split : Split an array into multiple sub-arrays of equal size.
+
+    Examples
+    --------
+    >>> x = np.arange(16.0).reshape(2, 2, 4)
+    >>> x
+    array([[[  0.,   1.,   2.,   3.],
+            [  4.,   5.,   6.,   7.]],
+           [[  8.,   9.,  10.,  11.],
+            [ 12.,  13.,  14.,  15.]]])
+    >>> np.dsplit(x, 2)
+    [array([[[  0.,   1.],
+            [  4.,   5.]],
+           [[  8.,   9.],
+            [ 12.,  13.]]]),
+     array([[[  2.,   3.],
+            [  6.,   7.]],
+           [[ 10.,  11.],
+            [ 14.,  15.]]])]
+    >>> np.dsplit(x, np.array([3, 6]))
+    [array([[[  0.,   1.,   2.],
+            [  4.,   5.,   6.]],
+           [[  8.,   9.,  10.],
+            [ 12.,  13.,  14.]]]),
+     array([[[  3.],
+            [  7.]],
+           [[ 11.],
+            [ 15.]]]),
+     array([], dtype=float64)]
+
+    """
+    if len(_nx.shape(ary)) < 3:
+        raise ValueError('dsplit only works on arrays of 3 or more dimensions')
+    return split(ary, indices_or_sections, 2)
+
+def get_array_prepare(*args):
+    """Find the wrapper for the array with the highest priority.
+
+    In case of ties, leftmost wins. If no wrapper is found, return None
+    """
+    wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
+                 x.__array_prepare__) for i, x in enumerate(args)
+                                   if hasattr(x, '__array_prepare__'))
+    if wrappers:
+        return wrappers[-1][-1]
+    return None
+
+def get_array_wrap(*args):
+    """Find the wrapper for the array with the highest priority.
+
+    In case of ties, leftmost wins. If no wrapper is found, return None
+    """
+    wrappers = sorted((getattr(x, '__array_priority__', 0), -i,
+                 x.__array_wrap__) for i, x in enumerate(args)
+                                   if hasattr(x, '__array_wrap__'))
+    if wrappers:
+        return wrappers[-1][-1]
+    return None
+
+def kron(a, b):
+    """
+    Kronecker product of two arrays.
+
+    Computes the Kronecker product, a composite array made of blocks of the
+    second array scaled by the first.
+
+    Parameters
+    ----------
+    a, b : array_like
+
+    Returns
+    -------
+    out : ndarray
+
+    See Also
+    --------
+    outer : The outer product
+
+    Notes
+    -----
+    The function assumes that the number of dimensions of `a` and `b`
+    are the same, if necessary prepending the smallest with ones.
+    If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`,
+    the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`.
+    The elements are products of elements from `a` and `b`, organized
+    explicitly by::
+
+        kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN]
+
+    where::
+
+        kt = it * st + jt,  t = 0,...,N
+
+    In the common 2-D case (N=1), the block structure can be visualized::
+
+        [[ a[0,0]*b,   a[0,1]*b,  ... , a[0,-1]*b  ],
+         [  ...                              ...   ],
+         [ a[-1,0]*b,  a[-1,1]*b, ... , a[-1,-1]*b ]]
+
+
+    Examples
+    --------
+    >>> np.kron([1,10,100], [5,6,7])
+    array([  5,   6,   7,  50,  60,  70, 500, 600, 700])
+    >>> np.kron([5,6,7], [1,10,100])
+    array([  5,  50, 500,   6,  60, 600,   7,  70, 700])
+
+    >>> np.kron(np.eye(2), np.ones((2,2)))
+    array([[ 1.,  1.,  0.,  0.],
+           [ 1.,  1.,  0.,  0.],
+           [ 0.,  0.,  1.,  1.],
+           [ 0.,  0.,  1.,  1.]])
+
+    >>> a = np.arange(100).reshape((2,5,2,5))
+    >>> b = np.arange(24).reshape((2,3,4))
+    >>> c = np.kron(a,b)
+    >>> c.shape
+    (2, 10, 6, 20)
+    >>> I = (1,3,0,2)
+    >>> J = (0,2,1)
+    >>> J1 = (0,) + J             # extend to ndim=4
+    >>> S1 = (1,) + b.shape
+    >>> K = tuple(np.array(I) * np.array(S1) + np.array(J1))
+    >>> c[K] == a[I]*b[J]
+    True
+
+    """
+    b = asanyarray(b)
+    a = array(a, copy=False, subok=True, ndmin=b.ndim)
+    ndb, nda = b.ndim, a.ndim
+    if (nda == 0 or ndb == 0):
+        return _nx.multiply(a, b)
+    as_ = a.shape
+    bs = b.shape
+    if not a.flags.contiguous:
+        a = reshape(a, as_)
+    if not b.flags.contiguous:
+        b = reshape(b, bs)
+    nd = ndb
+    if (ndb != nda):
+        if (ndb > nda):
+            as_ = (1,)*(ndb-nda) + as_
+        else:
+            bs = (1,)*(nda-ndb) + bs
+            nd = nda
+    result = outer(a, b).reshape(as_+bs)
+    axis = nd-1
+    for _ in range(nd):
+        result = concatenate(result, axis=axis)
+    wrapper = get_array_prepare(a, b)
+    if wrapper is not None:
+        result = wrapper(result)
+    wrapper = get_array_wrap(a, b)
+    if wrapper is not None:
+        result = wrapper(result)
+    return result
+
+
+def tile(A, reps):
+    """
+    Construct an array by repeating A the number of times given by reps.
+
+    If `reps` has length ``d``, the result will have dimension of
+    ``max(d, A.ndim)``.
+
+    If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
+    axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
+    or shape (1, 1, 3) for 3-D replication. If this is not the desired
+    behavior, promote `A` to d-dimensions manually before calling this
+    function.
+
+    If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
+    Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
+    (1, 1, 2, 2).
+
+    Note : Although tile may be used for broadcasting, it is strongly
+    recommended to use numpy's broadcasting operations and functions.
+
+    Parameters
+    ----------
+    A : array_like
+        The input array.
+    reps : array_like
+        The number of repetitions of `A` along each axis.
+
+    Returns
+    -------
+    c : ndarray
+        The tiled output array.
+
+    See Also
+    --------
+    repeat : Repeat elements of an array.
+    broadcast_to : Broadcast an array to a new shape
+
+    Examples
+    --------
+    >>> a = np.array([0, 1, 2])
+    >>> np.tile(a, 2)
+    array([0, 1, 2, 0, 1, 2])
+    >>> np.tile(a, (2, 2))
+    array([[0, 1, 2, 0, 1, 2],
+           [0, 1, 2, 0, 1, 2]])
+    >>> np.tile(a, (2, 1, 2))
+    array([[[0, 1, 2, 0, 1, 2]],
+           [[0, 1, 2, 0, 1, 2]]])
+
+    >>> b = np.array([[1, 2], [3, 4]])
+    >>> np.tile(b, 2)
+    array([[1, 2, 1, 2],
+           [3, 4, 3, 4]])
+    >>> np.tile(b, (2, 1))
+    array([[1, 2],
+           [3, 4],
+           [1, 2],
+           [3, 4]])
+
+    >>> c = np.array([1,2,3,4])
+    >>> np.tile(c,(4,1))
+    array([[1, 2, 3, 4],
+           [1, 2, 3, 4],
+           [1, 2, 3, 4],
+           [1, 2, 3, 4]])
+    """
+    try:
+        tup = tuple(reps)
+    except TypeError:
+        tup = (reps,)
+    d = len(tup)
+    if all(x == 1 for x in tup) and isinstance(A, _nx.ndarray):
+        # Fixes the problem that the function does not make a copy if A is a
+        # numpy array and the repetitions are 1 in all dimensions
+        return _nx.array(A, copy=True, subok=True, ndmin=d)
+    else:
+        # Note that no copy of zero-sized arrays is made. However since they
+        # have no data there is no risk of an inadvertent overwrite.
+        c = _nx.array(A, copy=False, subok=True, ndmin=d)
+    if (d < c.ndim):
+        tup = (1,)*(c.ndim-d) + tup
+    shape_out = tuple(s*t for s, t in zip(c.shape, tup))
+    n = c.size
+    if n > 0:
+        for dim_in, nrep in zip(c.shape, tup):
+            if nrep != 1:
+                c = c.reshape(-1, n).repeat(nrep, 0)
+            n //= dim_in
+    return c.reshape(shape_out)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
new file mode 100644
index 0000000000..4c23ab3555
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
@@ -0,0 +1,200 @@
+"""
+Utilities that manipulate strides to achieve desirable effects.
+
+An explanation of strides can be found in the "ndarray.rst" file in the
+NumPy reference guide.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = ['broadcast_to', 'broadcast_arrays']
+
+
+class DummyArray(object):
+    """Dummy object that just exists to hang __array_interface__ dictionaries
+    and possibly keep alive a reference to a base array.
+    """
+
+    def __init__(self, interface, base=None):
+        self.__array_interface__ = interface
+        self.base = base
+
+
+def _maybe_view_as_subclass(original_array, new_array):
+    if type(original_array) is not type(new_array):
+        # if input was an ndarray subclass and subclasses were OK,
+        # then view the result as that subclass.
+        new_array = new_array.view(type=type(original_array))
+        # Since we have done something akin to a view from original_array, we
+        # should let the subclass finalize (if it has it implemented, i.e., is
+        # not None).
+        if new_array.__array_finalize__:
+            new_array.__array_finalize__(original_array)
+    return new_array
+
+
+def as_strided(x, shape=None, strides=None, subok=False):
+    """ Make an ndarray from the given array with the given shape and strides.
+    """
+    # first convert input to array, possibly keeping subclass
+    x = np.array(x, copy=False, subok=subok)
+    interface = dict(x.__array_interface__)
+    if shape is not None:
+        interface['shape'] = tuple(shape)
+    if strides is not None:
+        interface['strides'] = tuple(strides)
+    array = np.asarray(DummyArray(interface, base=x))
+
+    if array.dtype.fields is None and x.dtype.fields is not None:
+        # This should only happen if x.dtype is [('', 'Vx')]
+        array.dtype = x.dtype
+
+    return _maybe_view_as_subclass(x, array)
+
+
+def _broadcast_to(array, shape, subok, readonly):
+    shape = tuple(shape) if np.iterable(shape) else (shape,)
+    array = np.array(array, copy=False, subok=subok)
+    if not shape and array.shape:
+        raise ValueError('cannot broadcast a non-scalar to a scalar array')
+    if any(size < 0 for size in shape):
+        raise ValueError('all elements of broadcast shape must be non-'
+                         'negative')
+    needs_writeable = not readonly and array.flags.writeable
+    extras = ['reduce_ok'] if needs_writeable else []
+    op_flag = 'readwrite' if needs_writeable else 'readonly'
+    broadcast = np.nditer(
+        (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
+        op_flags=[op_flag], itershape=shape, order='C').itviews[0]
+    result = _maybe_view_as_subclass(array, broadcast)
+    if needs_writeable and not result.flags.writeable:
+        result.flags.writeable = True
+    return result
+
+
+def broadcast_to(array, shape, subok=False):
+    """Broadcast an array to a new shape.
+
+    Parameters
+    ----------
+    array : array_like
+        The array to broadcast.
+    shape : tuple
+        The shape of the desired array.
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned array will be forced to be a base-class array (default).
+
+    Returns
+    -------
+    broadcast : array
+        A readonly view on the original array with the given shape. It is
+        typically not contiguous. Furthermore, more than one element of a
+        broadcasted array may refer to a single memory location.
+
+    Raises
+    ------
+    ValueError
+        If the array is not compatible with the new shape according to NumPy's
+        broadcasting rules.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3])
+    >>> np.broadcast_to(x, (3, 3))
+    array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]])
+    """
+    return _broadcast_to(array, shape, subok=subok, readonly=True)
+
+
+def _broadcast_shape(*args):
+    """Returns the shape of the ararys that would result from broadcasting the
+    supplied arrays against each other.
+    """
+    if not args:
+        raise ValueError('must provide at least one argument')
+    # use the old-iterator because np.nditer does not handle size 0 arrays
+    # consistently
+    b = np.broadcast(*args[:32])
+    # unfortunately, it cannot handle 32 or more arguments directly
+    for pos in range(32, len(args), 31):
+        # ironically, np.broadcast does not properly handle np.broadcast
+        # objects (it treats them as scalars)
+        # use broadcasting to avoid allocating the full array
+        b = broadcast_to(0, b.shape)
+        b = np.broadcast(b, *args[pos:(pos + 31)])
+    return b.shape
+
+
+def broadcast_arrays(*args, **kwargs):
+    """
+    Broadcast any number of arrays against each other.
+
+    Parameters
+    ----------
+    `*args` : array_likes
+        The arrays to broadcast.
+
+    subok : bool, optional
+        If True, then sub-classes will be passed-through, otherwise
+        the returned arrays will be forced to be a base-class array (default).
+
+    Returns
+    -------
+    broadcasted : list of arrays
+        These arrays are views on the original arrays.  They are typically
+        not contiguous.  Furthermore, more than one element of a
+        broadcasted array may refer to a single memory location.  If you
+        need to write to the arrays, make copies first.
+
+    Examples
+    --------
+    >>> x = np.array([[1,2,3]])
+    >>> y = np.array([[1],[2],[3]])
+    >>> np.broadcast_arrays(x, y)
+    [array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]]), array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])]
+
+    Here is a useful idiom for getting contiguous copies instead of
+    non-contiguous views.
+
+    >>> [np.array(a) for a in np.broadcast_arrays(x, y)]
+    [array([[1, 2, 3],
+           [1, 2, 3],
+           [1, 2, 3]]), array([[1, 1, 1],
+           [2, 2, 2],
+           [3, 3, 3]])]
+
+    """
+    # nditer is not used here to avoid the limit of 32 arrays.
+    # Otherwise, something like the following one-liner would suffice:
+    # return np.nditer(args, flags=['multi_index', 'zerosize_ok'],
+    #                  order='C').itviews
+
+    subok = kwargs.pop('subok', False)
+    if kwargs:
+        raise TypeError('broadcast_arrays() got an unexpected keyword '
+                        'argument {}'.format(kwargs.pop()))
+    args = [np.array(_m, copy=False, subok=subok) for _m in args]
+
+    shape = _broadcast_shape(*args)
+
+    if all(array.shape == shape for array in args):
+        # Common case where nothing needs to be broadcasted.
+        return args
+
+    # TODO: consider making the results of broadcast_arrays readonly to match
+    # broadcast_to. This will require a deprecation cycle.
+    return [_broadcast_to(array, shape, subok=subok, readonly=False)
+            for array in args]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
new file mode 100644
index 0000000000000000000000000000000000000000..12936c92d8f8a122f2342a7782f56e7506010c40
GIT binary patch
literal 258
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1J<8Ps^qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
zFV09TNL9B|&@j=_)KREaKmuG1Ov!nrxdoMa$@xX8dby=JC7FpuMTwPM@kOc0`FX`9
zMWx9lT!oAfRa|)~5ZOW|Z-&-T#-#S3LS_wbMsJo@sDhM|%7Rp`LY7b_e+zF0Z^rhZ
zLRJlL=1|5OKR-XO|NsC02NT}*B}tvJg=`vr$?@??rI|S;nR)T?Topx$dFiQKh3pY*
c3=9lUTUNd3Twll$%JyVOFNnpNT9Tv(01#|g4*&oF

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
new file mode 100644
index 0000000000000000000000000000000000000000..68a3b53a1df0574ad05b0e8bc53279e1110db9af
GIT binary patch
literal 366
zcmWIWW@Zs#00A||bhju0i}g&53=AO5%D})-p_f-sIoU7NHz1Oc!HuC>Jteg`xk%kg
zLA}P`LS08eJuSbeq$n{jKEEg>6(sJKm{Xjpqo7`#kywzbZl$1MqNAy!P^*9hxEh#}
z^Gb6ID)o}{i&FJ+OLIyx6N`!xE4ku}Qj_!Zic5-0lS{Y?86m2;@=_qOg-qTIt)Yxb
z?Lmdi8s3cFEUi!lDJ7K!sa%CDp-lc3-VEN1?LmdC8s5yIj5U6KeqR6o|NjpryzNVp
zI%5mjH2jj|<C97=b4oJv;^Vn0iW2kEQ@IM+BiI-i7@oGQdeOPQkRz1s$&OwSi!-$(
qNiV>gkx7IZcQAp14}=>UK_ocP0=!v4<}olbFftf3Ffgbxf}{Z9Ph;u;

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
new file mode 100644
index 0000000000000000000000000000000000000000..6776074b421bc04842c0389a7c237ad49cd0992a
GIT binary patch
literal 341
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1J<8Ps^qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
zFV09TNL9B|&@j=_)KREaKmuG1Ov!nrxdoMa$@xX8dby=JC7FpuMTwPM@kOc0`FX`9
zMWx9lT!jn}Ra|)~5ZOXTZ-&-FrsVkK{FKz>Vy@IY5QD3bIf9Xafg!1oC4!BCfgvZc
zBs0&jkhQIlEvS&ay^tfQkW<5((VL~UkPB*HN=aowDpw(Q1QP=TgTF-~k2ixiV|yWQ
zP$8d&H^j7>LViC#Kd=A)|NjRQ-u5Mh0!f{*g@PJ>$?@??rI|S;nR)T?Topx$dFiQK
zg+gG<pSG-e(Yd}*ID<KYhk=3N@RCD24)q>haj5gq`a+Qm*0w^?phB_Kl0xw$Jpi4U
BZkYf8

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
new file mode 100644
index 0000000000000000000000000000000000000000..05eac0b76d8a034ffa25a9af78d12a85d5d99d0f
GIT binary patch
literal 449
zcmWIWW@Zs#009NYbhnl7|EvjRWMBYcRt5%!3cb97%E^AAz5$Vp3~mh7>M5zk$wlf`
z3hFif7V0_*>S_5!B}IvO@%cq5sUUH;#GK+(9R>B`jKqRebt?r86CF(*g<1t9z}3K%
zoL8D#P^p)kUzDnsTbfgnnOIbmSjiP%l$xBMS6ot5nq0zF$N*8rm6rmMEoAg&Xf0$)
zj!(`{Nlh;1O3ec?xC)sg7#SECk_uTO*cccXauQ22^9&1F+X~r&3fbEWIf4o~HM|+U
zSy~IZpa!OtR2HOi6>>)~F)%RrTNLtmGk7z$7xD%b@@aTOOsgs6_w)1f`v3p`e=y-~
zUs5QL)EQeSsNt6!AD>j3nNyOP7az}6QIwdMp2}4y1h)KX%c>Wh>kEZ5m?L-?7#I#O
zIke+Y@8K1PIuETc6v<$1D-;bX6iY2B6i?C%@MdHZVa6Tupcnz+hDHzxj)wqmR*(-F
P7#SEDj6snD@;3tjQc{2A

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
new file mode 100644
index 0000000000000000000000000000000000000000..7c6997dd69eef019d6745dee125e92434b7954e3
GIT binary patch
literal 96
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
hFV09TNL9B|&@j@`)KREaKmuG0VDP~nOfh`02LKL&7mEM@

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
new file mode 100644
index 0000000000000000000000000000000000000000..d9bc36af7392dbee12a43c436e2178235ac60b13
GIT binary patch
literal 96
zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEPSsIR
iFV09TNL9B|&@l4R(bQ3>RX_kP1~B+w52hGC*aH9)+!wb1

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
new file mode 100644
index 0000000000..f4bece352b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
@@ -0,0 +1,349 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+from tempfile import mkdtemp, mkstemp, NamedTemporaryFile
+from shutil import rmtree
+
+from numpy.compat import asbytes
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, SkipTest
+    )
+import numpy.lib._datasource as datasource
+
+if sys.version_info[0] >= 3:
+    import urllib.request as urllib_request
+    from urllib.parse import urlparse
+    from urllib.error import URLError
+else:
+    import urllib2 as urllib_request
+    from urlparse import urlparse
+    from urllib2 import URLError
+
+
+def urlopen_stub(url, data=None):
+    '''Stub to replace urlopen for testing.'''
+    if url == valid_httpurl():
+        tmpfile = NamedTemporaryFile(prefix='urltmp_')
+        return tmpfile
+    else:
+        raise URLError('Name or service not known')
+
+# setup and teardown
+old_urlopen = None
+
+
+def setup():
+    global old_urlopen
+
+    old_urlopen = urllib_request.urlopen
+    urllib_request.urlopen = urlopen_stub
+
+
+def teardown():
+    urllib_request.urlopen = old_urlopen
+
+# A valid website for more robust testing
+http_path = 'http://www.google.com/'
+http_file = 'index.html'
+
+http_fakepath = 'http://fake.abc.web/site/'
+http_fakefile = 'fake.txt'
+
+malicious_files = ['/etc/shadow', '../../shadow',
+                   '..\\system.dat', 'c:\\windows\\system.dat']
+
+magic_line = asbytes('three is the magic number')
+
+
+# Utility functions used by many TestCases
+def valid_textfile(filedir):
+    # Generate and return a valid temporary file.
+    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir, text=True)
+    os.close(fd)
+    return path
+
+
+def invalid_textfile(filedir):
+    # Generate and return an invalid filename.
+    fd, path = mkstemp(suffix='.txt', prefix='dstmp_', dir=filedir)
+    os.close(fd)
+    os.remove(path)
+    return path
+
+
+def valid_httpurl():
+    return http_path+http_file
+
+
+def invalid_httpurl():
+    return http_fakepath+http_fakefile
+
+
+def valid_baseurl():
+    return http_path
+
+
+def invalid_baseurl():
+    return http_fakepath
+
+
+def valid_httpfile():
+    return http_file
+
+
+def invalid_httpfile():
+    return http_fakefile
+
+
+class TestDataSourceOpen(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        fh = self.ds.open(valid_httpurl())
+        assert_(fh)
+        fh.close()
+
+    def test_InvalidHTTP(self):
+        url = invalid_httpurl()
+        self.assertRaises(IOError, self.ds.open, url)
+        try:
+            self.ds.open(url)
+        except IOError as e:
+            # Regression test for bug fixed in r4342.
+            assert_(e.errno is None)
+
+    def test_InvalidHTTPCacheURLError(self):
+        self.assertRaises(URLError, self.ds._cache, invalid_httpurl())
+
+    def test_ValidFile(self):
+        local_file = valid_textfile(self.tmpdir)
+        fh = self.ds.open(local_file)
+        assert_(fh)
+        fh.close()
+
+    def test_InvalidFile(self):
+        invalid_file = invalid_textfile(self.tmpdir)
+        self.assertRaises(IOError, self.ds.open, invalid_file)
+
+    def test_ValidGzipFile(self):
+        try:
+            import gzip
+        except ImportError:
+            # We don't have the gzip capabilities to test.
+            raise SkipTest
+        # Test datasource's internal file_opener for Gzip files.
+        filepath = os.path.join(self.tmpdir, 'foobar.txt.gz')
+        fp = gzip.open(filepath, 'w')
+        fp.write(magic_line)
+        fp.close()
+        fp = self.ds.open(filepath)
+        result = fp.readline()
+        fp.close()
+        self.assertEqual(magic_line, result)
+
+    def test_ValidBz2File(self):
+        try:
+            import bz2
+        except ImportError:
+            # We don't have the bz2 capabilities to test.
+            raise SkipTest
+        # Test datasource's internal file_opener for BZip2 files.
+        filepath = os.path.join(self.tmpdir, 'foobar.txt.bz2')
+        fp = bz2.BZ2File(filepath, 'w')
+        fp.write(magic_line)
+        fp.close()
+        fp = self.ds.open(filepath)
+        result = fp.readline()
+        fp.close()
+        self.assertEqual(magic_line, result)
+
+
+class TestDataSourceExists(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        assert_(self.ds.exists(valid_httpurl()))
+
+    def test_InvalidHTTP(self):
+        self.assertEqual(self.ds.exists(invalid_httpurl()), False)
+
+    def test_ValidFile(self):
+        # Test valid file in destpath
+        tmpfile = valid_textfile(self.tmpdir)
+        assert_(self.ds.exists(tmpfile))
+        # Test valid local file not in destpath
+        localdir = mkdtemp()
+        tmpfile = valid_textfile(localdir)
+        assert_(self.ds.exists(tmpfile))
+        rmtree(localdir)
+
+    def test_InvalidFile(self):
+        tmpfile = invalid_textfile(self.tmpdir)
+        self.assertEqual(self.ds.exists(tmpfile), False)
+
+
+class TestDataSourceAbspath(TestCase):
+    def setUp(self):
+        self.tmpdir = os.path.abspath(mkdtemp())
+        self.ds = datasource.DataSource(self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.ds
+
+    def test_ValidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(valid_httpurl())
+        local_path = os.path.join(self.tmpdir, netloc,
+                                  upath.strip(os.sep).strip('/'))
+        self.assertEqual(local_path, self.ds.abspath(valid_httpurl()))
+
+    def test_ValidFile(self):
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+        # Test with filename only
+        self.assertEqual(tmpfile, self.ds.abspath(tmpfilename))
+        # Test filename with complete path
+        self.assertEqual(tmpfile, self.ds.abspath(tmpfile))
+
+    def test_InvalidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(invalid_httpurl())
+        invalidhttp = os.path.join(self.tmpdir, netloc,
+                                   upath.strip(os.sep).strip('/'))
+        self.assertNotEqual(invalidhttp, self.ds.abspath(valid_httpurl()))
+
+    def test_InvalidFile(self):
+        invalidfile = valid_textfile(self.tmpdir)
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+        # Test with filename only
+        self.assertNotEqual(invalidfile, self.ds.abspath(tmpfilename))
+        # Test filename with complete path
+        self.assertNotEqual(invalidfile, self.ds.abspath(tmpfile))
+
+    def test_sandboxing(self):
+        tmpfile = valid_textfile(self.tmpdir)
+        tmpfilename = os.path.split(tmpfile)[-1]
+
+        tmp_path = lambda x: os.path.abspath(self.ds.abspath(x))
+
+        assert_(tmp_path(valid_httpurl()).startswith(self.tmpdir))
+        assert_(tmp_path(invalid_httpurl()).startswith(self.tmpdir))
+        assert_(tmp_path(tmpfile).startswith(self.tmpdir))
+        assert_(tmp_path(tmpfilename).startswith(self.tmpdir))
+        for fn in malicious_files:
+            assert_(tmp_path(http_path+fn).startswith(self.tmpdir))
+            assert_(tmp_path(fn).startswith(self.tmpdir))
+
+    def test_windows_os_sep(self):
+        orig_os_sep = os.sep
+        try:
+            os.sep = '\\'
+            self.test_ValidHTTP()
+            self.test_ValidFile()
+            self.test_InvalidHTTP()
+            self.test_InvalidFile()
+            self.test_sandboxing()
+        finally:
+            os.sep = orig_os_sep
+
+
+class TestRepositoryAbspath(TestCase):
+    def setUp(self):
+        self.tmpdir = os.path.abspath(mkdtemp())
+        self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.repos
+
+    def test_ValidHTTP(self):
+        scheme, netloc, upath, pms, qry, frg = urlparse(valid_httpurl())
+        local_path = os.path.join(self.repos._destpath, netloc,
+                                  upath.strip(os.sep).strip('/'))
+        filepath = self.repos.abspath(valid_httpfile())
+        self.assertEqual(local_path, filepath)
+
+    def test_sandboxing(self):
+        tmp_path = lambda x: os.path.abspath(self.repos.abspath(x))
+        assert_(tmp_path(valid_httpfile()).startswith(self.tmpdir))
+        for fn in malicious_files:
+            assert_(tmp_path(http_path+fn).startswith(self.tmpdir))
+            assert_(tmp_path(fn).startswith(self.tmpdir))
+
+    def test_windows_os_sep(self):
+        orig_os_sep = os.sep
+        try:
+            os.sep = '\\'
+            self.test_ValidHTTP()
+            self.test_sandboxing()
+        finally:
+            os.sep = orig_os_sep
+
+
+class TestRepositoryExists(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+        self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+        del self.repos
+
+    def test_ValidFile(self):
+        # Create local temp file
+        tmpfile = valid_textfile(self.tmpdir)
+        assert_(self.repos.exists(tmpfile))
+
+    def test_InvalidFile(self):
+        tmpfile = invalid_textfile(self.tmpdir)
+        self.assertEqual(self.repos.exists(tmpfile), False)
+
+    def test_RemoveHTTPFile(self):
+        assert_(self.repos.exists(valid_httpurl()))
+
+    def test_CachedHTTPFile(self):
+        localfile = valid_httpurl()
+        # Create a locally cached temp file with an URL based
+        # directory structure.  This is similar to what Repository.open
+        # would do.
+        scheme, netloc, upath, pms, qry, frg = urlparse(localfile)
+        local_path = os.path.join(self.repos._destpath, netloc)
+        os.mkdir(local_path, 0o0700)
+        tmpfile = valid_textfile(local_path)
+        assert_(self.repos.exists(tmpfile))
+
+
+class TestOpenFunc(TestCase):
+    def setUp(self):
+        self.tmpdir = mkdtemp()
+
+    def tearDown(self):
+        rmtree(self.tmpdir)
+
+    def test_DataSourceOpen(self):
+        local_file = valid_textfile(self.tmpdir)
+        # Test case where destpath is passed in
+        fp = datasource.open(local_file, destpath=self.tmpdir)
+        assert_(fp)
+        fp.close()
+        # Test case where default destpath is used
+        fp = datasource.open(local_file)
+        assert_(fp)
+        fp.close()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
new file mode 100644
index 0000000000..e0a917a216
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
@@ -0,0 +1,348 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import time
+from datetime import date
+
+import numpy as np
+from numpy.compat import asbytes, asbytes_nested
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_allclose,
+    assert_raises
+    )
+from numpy.lib._iotools import (
+    LineSplitter, NameValidator, StringConverter,
+    has_nested_fields, easy_dtype, flatten_dtype
+    )
+
+
+class TestLineSplitter(TestCase):
+    "Tests the LineSplitter class."
+
+    def test_no_delimiter(self):
+        "Test LineSplitter w/o delimiter"
+        strg = asbytes(" 1 2 3 4  5 # test")
+        test = LineSplitter()(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5']))
+        test = LineSplitter('')(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5']))
+
+    def test_space_delimiter(self):
+        "Test space delimiter"
+        strg = asbytes(" 1 2 3 4  5 # test")
+        test = LineSplitter(asbytes(' '))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+        test = LineSplitter(asbytes('  '))(strg)
+        assert_equal(test, asbytes_nested(['1 2 3 4', '5']))
+
+    def test_tab_delimiter(self):
+        "Test tab delimiter"
+        strg = asbytes(" 1\t 2\t 3\t 4\t 5  6")
+        test = LineSplitter(asbytes('\t'))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '5  6']))
+        strg = asbytes(" 1  2\t 3  4\t 5  6")
+        test = LineSplitter(asbytes('\t'))(strg)
+        assert_equal(test, asbytes_nested(['1  2', '3  4', '5  6']))
+
+    def test_other_delimiter(self):
+        "Test LineSplitter on delimiter"
+        strg = asbytes("1,2,3,4,,5")
+        test = LineSplitter(asbytes(','))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+        #
+        strg = asbytes(" 1,2,3,4,,5 # test")
+        test = LineSplitter(asbytes(','))(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5']))
+
+    def test_constant_fixed_width(self):
+        "Test LineSplitter w/ fixed-width fields"
+        strg = asbytes("  1  2  3  4     5   # test")
+        test = LineSplitter(3)(strg)
+        assert_equal(test, asbytes_nested(['1', '2', '3', '4', '', '5', '']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter(20)(strg)
+        assert_equal(test, asbytes_nested(['1     3  4  5  6']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter(30)(strg)
+        assert_equal(test, asbytes_nested(['1     3  4  5  6']))
+
+    def test_variable_fixed_width(self):
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter((3, 6, 6, 3))(strg)
+        assert_equal(test, asbytes_nested(['1', '3', '4  5', '6']))
+        #
+        strg = asbytes("  1     3  4  5  6# test")
+        test = LineSplitter((6, 6, 9))(strg)
+        assert_equal(test, asbytes_nested(['1', '3  4', '5  6']))
+
+# -----------------------------------------------------------------------------
+
+
+class TestNameValidator(TestCase):
+
+    def test_case_sensitivity(self):
+        "Test case sensitivity"
+        names = ['A', 'a', 'b', 'c']
+        test = NameValidator().validate(names)
+        assert_equal(test, ['A', 'a', 'b', 'c'])
+        test = NameValidator(case_sensitive=False).validate(names)
+        assert_equal(test, ['A', 'A_1', 'B', 'C'])
+        test = NameValidator(case_sensitive='upper').validate(names)
+        assert_equal(test, ['A', 'A_1', 'B', 'C'])
+        test = NameValidator(case_sensitive='lower').validate(names)
+        assert_equal(test, ['a', 'a_1', 'b', 'c'])
+
+        # check exceptions
+        assert_raises(ValueError, NameValidator, case_sensitive='foobar')
+
+    def test_excludelist(self):
+        "Test excludelist"
+        names = ['dates', 'data', 'Other Data', 'mask']
+        validator = NameValidator(excludelist=['dates', 'data', 'mask'])
+        test = validator.validate(names)
+        assert_equal(test, ['dates_', 'data_', 'Other_Data', 'mask_'])
+
+    def test_missing_names(self):
+        "Test validate missing names"
+        namelist = ('a', 'b', 'c')
+        validator = NameValidator()
+        assert_equal(validator(namelist), ['a', 'b', 'c'])
+        namelist = ('', 'b', 'c')
+        assert_equal(validator(namelist), ['f0', 'b', 'c'])
+        namelist = ('a', 'b', '')
+        assert_equal(validator(namelist), ['a', 'b', 'f0'])
+        namelist = ('', 'f0', '')
+        assert_equal(validator(namelist), ['f1', 'f0', 'f2'])
+
+    def test_validate_nb_names(self):
+        "Test validate nb names"
+        namelist = ('a', 'b', 'c')
+        validator = NameValidator()
+        assert_equal(validator(namelist, nbfields=1), ('a',))
+        assert_equal(validator(namelist, nbfields=5, defaultfmt="g%i"),
+                     ['a', 'b', 'c', 'g0', 'g1'])
+
+    def test_validate_wo_names(self):
+        "Test validate no names"
+        namelist = None
+        validator = NameValidator()
+        assert_(validator(namelist) is None)
+        assert_equal(validator(namelist, nbfields=3), ['f0', 'f1', 'f2'])
+
+# -----------------------------------------------------------------------------
+
+
+def _bytes_to_date(s):
+    if sys.version_info[0] >= 3:
+        return date(*time.strptime(s.decode('latin1'), "%Y-%m-%d")[:3])
+    else:
+        return date(*time.strptime(s, "%Y-%m-%d")[:3])
+
+
+class TestStringConverter(TestCase):
+    "Test StringConverter"
+
+    def test_creation(self):
+        "Test creation of a StringConverter"
+        converter = StringConverter(int, -99999)
+        assert_equal(converter._status, 1)
+        assert_equal(converter.default, -99999)
+
+    def test_upgrade(self):
+        "Tests the upgrade method."
+
+        converter = StringConverter()
+        assert_equal(converter._status, 0)
+
+        # test int
+        assert_equal(converter.upgrade(asbytes('0')), 0)
+        assert_equal(converter._status, 1)
+
+        # On systems where integer defaults to 32-bit, the statuses will be
+        # offset by one, so we check for this here.
+        import numpy.core.numeric as nx
+        status_offset = int(nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize)
+
+        # test int > 2**32
+        assert_equal(converter.upgrade(asbytes('17179869184')), 17179869184)
+        assert_equal(converter._status, 1 + status_offset)
+
+        # test float
+        assert_allclose(converter.upgrade(asbytes('0.')), 0.0)
+        assert_equal(converter._status, 2 + status_offset)
+
+        # test complex
+        assert_equal(converter.upgrade(asbytes('0j')), complex('0j'))
+        assert_equal(converter._status, 3 + status_offset)
+
+        # test str
+        assert_equal(converter.upgrade(asbytes('a')), asbytes('a'))
+        assert_equal(converter._status, len(converter._mapper) - 1)
+
+    def test_missing(self):
+        "Tests the use of missing values."
+        converter = StringConverter(missing_values=(asbytes('missing'),
+                                                    asbytes('missed')))
+        converter.upgrade(asbytes('0'))
+        assert_equal(converter(asbytes('0')), 0)
+        assert_equal(converter(asbytes('')), converter.default)
+        assert_equal(converter(asbytes('missing')), converter.default)
+        assert_equal(converter(asbytes('missed')), converter.default)
+        try:
+            converter('miss')
+        except ValueError:
+            pass
+
+    def test_upgrademapper(self):
+        "Tests updatemapper"
+        dateparser = _bytes_to_date
+        StringConverter.upgrade_mapper(dateparser, date(2000, 1, 1))
+        convert = StringConverter(dateparser, date(2000, 1, 1))
+        test = convert(asbytes('2001-01-01'))
+        assert_equal(test, date(2001, 1, 1))
+        test = convert(asbytes('2009-01-01'))
+        assert_equal(test, date(2009, 1, 1))
+        test = convert(asbytes(''))
+        assert_equal(test, date(2000, 1, 1))
+
+    def test_string_to_object(self):
+        "Make sure that string-to-object functions are properly recognized"
+        conv = StringConverter(_bytes_to_date)
+        assert_equal(conv._mapper[-2][0](0), 0j)
+        assert_(hasattr(conv, 'default'))
+
+    def test_keep_default(self):
+        "Make sure we don't lose an explicit default"
+        converter = StringConverter(None, missing_values=asbytes(''),
+                                    default=-999)
+        converter.upgrade(asbytes('3.14159265'))
+        assert_equal(converter.default, -999)
+        assert_equal(converter.type, np.dtype(float))
+        #
+        converter = StringConverter(
+            None, missing_values=asbytes(''), default=0)
+        converter.upgrade(asbytes('3.14159265'))
+        assert_equal(converter.default, 0)
+        assert_equal(converter.type, np.dtype(float))
+
+    def test_keep_default_zero(self):
+        "Check that we don't lose a default of 0"
+        converter = StringConverter(int, default=0,
+                                    missing_values=asbytes("N/A"))
+        assert_equal(converter.default, 0)
+
+    def test_keep_missing_values(self):
+        "Check that we're not losing missing values"
+        converter = StringConverter(int, default=0,
+                                    missing_values=asbytes("N/A"))
+        assert_equal(
+            converter.missing_values, set(asbytes_nested(['', 'N/A'])))
+
+    def test_int64_dtype(self):
+        "Check that int64 integer types can be specified"
+        converter = StringConverter(np.int64, default=0)
+        val = asbytes("-9223372036854775807")
+        assert_(converter(val) == -9223372036854775807)
+        val = asbytes("9223372036854775807")
+        assert_(converter(val) == 9223372036854775807)
+
+    def test_uint64_dtype(self):
+        "Check that uint64 integer types can be specified"
+        converter = StringConverter(np.uint64, default=0)
+        val = asbytes("9223372043271415339")
+        assert_(converter(val) == 9223372043271415339)
+
+
+class TestMiscFunctions(TestCase):
+
+    def test_has_nested_dtype(self):
+        "Test has_nested_dtype"
+        ndtype = np.dtype(np.float)
+        assert_equal(has_nested_fields(ndtype), False)
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        assert_equal(has_nested_fields(ndtype), False)
+        ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+        assert_equal(has_nested_fields(ndtype), True)
+
+    def test_easy_dtype(self):
+        "Test ndtype on dtypes"
+        # Simple case
+        ndtype = float
+        assert_equal(easy_dtype(ndtype), np.dtype(float))
+        # As string w/o names
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype),
+                     np.dtype([('f0', "i4"), ('f1', "f8")]))
+        # As string w/o names but different default format
+        assert_equal(easy_dtype(ndtype, defaultfmt="field_%03i"),
+                     np.dtype([('field_000', "i4"), ('field_001', "f8")]))
+        # As string w/ names
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names="a, b"),
+                     np.dtype([('a', "i4"), ('b', "f8")]))
+        # As string w/ names (too many)
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([('a', "i4"), ('b', "f8")]))
+        # As string w/ names (not enough)
+        ndtype = "i4, f8"
+        assert_equal(easy_dtype(ndtype, names=", b"),
+                     np.dtype([('f0', "i4"), ('b', "f8")]))
+        # ... (with different default format)
+        assert_equal(easy_dtype(ndtype, names="a", defaultfmt="f%02i"),
+                     np.dtype([('a', "i4"), ('f00', "f8")]))
+        # As list of tuples w/o names
+        ndtype = [('A', int), ('B', float)]
+        assert_equal(easy_dtype(ndtype), np.dtype([('A', int), ('B', float)]))
+        # As list of tuples w/ names
+        assert_equal(easy_dtype(ndtype, names="a,b"),
+                     np.dtype([('a', int), ('b', float)]))
+        # As list of tuples w/ not enough names
+        assert_equal(easy_dtype(ndtype, names="a"),
+                     np.dtype([('a', int), ('f0', float)]))
+        # As list of tuples w/ too many names
+        assert_equal(easy_dtype(ndtype, names="a,b,c"),
+                     np.dtype([('a', int), ('b', float)]))
+        # As list of types w/o names
+        ndtype = (int, float, float)
+        assert_equal(easy_dtype(ndtype),
+                     np.dtype([('f0', int), ('f1', float), ('f2', float)]))
+        # As list of types w names
+        ndtype = (int, float, float)
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([('a', int), ('b', float), ('c', float)]))
+        # As simple dtype w/ names
+        ndtype = np.dtype(float)
+        assert_equal(easy_dtype(ndtype, names="a, b, c"),
+                     np.dtype([(_, float) for _ in ('a', 'b', 'c')]))
+        # As simple dtype w/o names (but multiple fields)
+        ndtype = np.dtype(float)
+        assert_equal(
+            easy_dtype(ndtype, names=['', '', ''], defaultfmt="f%02i"),
+            np.dtype([(_, float) for _ in ('f00', 'f01', 'f02')]))
+
+    def test_flatten_dtype(self):
+        "Testing flatten_dtype"
+        # Standard dtype
+        dt = np.dtype([("a", "f8"), ("b", "f8")])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, float])
+        # Recursive dtype
+        dt = np.dtype([("a", [("aa", '|S1'), ("ab", '|S2')]), ("b", int)])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [np.dtype('|S1'), np.dtype('|S2'), int])
+        # dtype with shaped fields
+        dt = np.dtype([("a", (float, 2)), ("b", (int, 3))])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, int])
+        dt_flat = flatten_dtype(dt, True)
+        assert_equal(dt_flat, [float] * 2 + [int] * 3)
+        # dtype w/ titles
+        dt = np.dtype([(("a", "A"), "f8"), (("b", "B"), "f8")])
+        dt_flat = flatten_dtype(dt)
+        assert_equal(dt_flat, [float, float])
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__version.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
new file mode 100644
index 0000000000..993c9d5070
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
@@ -0,0 +1,70 @@
+"""Tests for the NumpyVersion class.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import assert_, run_module_suite, assert_raises
+from numpy.lib import NumpyVersion
+
+
+def test_main_versions():
+    assert_(NumpyVersion('1.8.0') == '1.8.0')
+    for ver in ['1.9.0', '2.0.0', '1.8.1']:
+        assert_(NumpyVersion('1.8.0') < ver)
+
+    for ver in ['1.7.0', '1.7.1', '0.9.9']:
+        assert_(NumpyVersion('1.8.0') > ver)
+
+
+def test_version_1_point_10():
+    # regression test for gh-2998.
+    assert_(NumpyVersion('1.9.0') < '1.10.0')
+    assert_(NumpyVersion('1.11.0') < '1.11.1')
+    assert_(NumpyVersion('1.11.0') == '1.11.0')
+    assert_(NumpyVersion('1.99.11') < '1.99.12')
+
+
+def test_alpha_beta_rc():
+    assert_(NumpyVersion('1.8.0rc1') == '1.8.0rc1')
+    for ver in ['1.8.0', '1.8.0rc2']:
+        assert_(NumpyVersion('1.8.0rc1') < ver)
+
+    for ver in ['1.8.0a2', '1.8.0b3', '1.7.2rc4']:
+        assert_(NumpyVersion('1.8.0rc1') > ver)
+
+    assert_(NumpyVersion('1.8.0b1') > '1.8.0a2')
+
+
+def test_dev_version():
+    assert_(NumpyVersion('1.9.0.dev-Unknown') < '1.9.0')
+    for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev-ffffffff']:
+        assert_(NumpyVersion('1.9.0.dev-f16acvda') < ver)
+
+    assert_(NumpyVersion('1.9.0.dev-f16acvda') == '1.9.0.dev-11111111')
+
+
+def test_dev_a_b_rc_mixed():
+    assert_(NumpyVersion('1.9.0a2.dev-f16acvda') == '1.9.0a2.dev-11111111')
+    assert_(NumpyVersion('1.9.0a2.dev-6acvda54') < '1.9.0a2')
+
+
+def test_dev0_version():
+    assert_(NumpyVersion('1.9.0.dev0+Unknown') < '1.9.0')
+    for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev0+ffffffff']:
+        assert_(NumpyVersion('1.9.0.dev0+f16acvda') < ver)
+
+    assert_(NumpyVersion('1.9.0.dev0+f16acvda') == '1.9.0.dev0+11111111')
+
+
+def test_dev0_a_b_rc_mixed():
+    assert_(NumpyVersion('1.9.0a2.dev0+f16acvda') == '1.9.0a2.dev0+11111111')
+    assert_(NumpyVersion('1.9.0a2.dev0+6acvda54') < '1.9.0a2')
+
+
+def test_raises():
+    for ver in ['1.9', '1,9.0', '1.7.x']:
+        assert_raises(ValueError, NumpyVersion, ver)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
new file mode 100644
index 0000000000..f19a0b13ab
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
@@ -0,0 +1,1058 @@
+"""Tests for the array padding functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (assert_array_equal, assert_raises, assert_allclose,
+                           TestCase)
+from numpy.lib import pad
+
+
+class TestConditionalShortcuts(TestCase):
+    def test_zero_padding_shortcuts(self):
+        test = np.arange(120).reshape(4, 5, 6)
+        pad_amt = [(0, 0) for axis in test.shape]
+        modes = ['constant',
+                 'edge',
+                 'linear_ramp',
+                 'maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 'reflect',
+                 'symmetric',
+                 'wrap',
+                 ]
+        for mode in modes:
+            assert_array_equal(test, pad(test, pad_amt, mode=mode))
+
+    def test_shallow_statistic_range(self):
+        test = np.arange(120).reshape(4, 5, 6)
+        pad_amt = [(1, 1) for axis in test.shape]
+        modes = ['maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 ]
+        for mode in modes:
+            assert_array_equal(pad(test, pad_amt, mode='edge'),
+                               pad(test, pad_amt, mode=mode, stat_length=1))
+
+    def test_clip_statistic_range(self):
+        test = np.arange(30).reshape(5, 6)
+        pad_amt = [(3, 3) for axis in test.shape]
+        modes = ['maximum',
+                 'mean',
+                 'median',
+                 'minimum',
+                 ]
+        for mode in modes:
+            assert_array_equal(pad(test, pad_amt, mode=mode),
+                               pad(test, pad_amt, mode=mode, stat_length=30))
+
+
+class TestStatistic(TestCase):
+    def test_check_mean_stat_length(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), ))
+        b = np.array(
+            [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+             0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
+             0.5, 0.5, 0.5, 0.5, 0.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             98., 98., 98., 98., 98., 98., 98., 98., 98., 98.,
+             98., 98., 98., 98., 98., 98., 98., 98., 98., 98.
+             ])
+        assert_array_equal(a, b)
+
+    def test_check_maximum_1(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'maximum')
+        b = np.array(
+            [99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+             99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_maximum_2(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'maximum')
+        b = np.array(
+            [100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100,
+
+             1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_maximum_stat_length(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'maximum', stat_length=10)
+        b = np.array(
+            [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10,
+
+              1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+             100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_1(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'minimum')
+        b = np.array(
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+             0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_2(self):
+        a = np.arange(100) + 2
+        a = pad(a, (25, 20), 'minimum')
+        b = np.array(
+            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2,
+
+             2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+             12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+             22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+             32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+             42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+             52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+             62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+             72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+             82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+             92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+             2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_minimum_stat_length(self):
+        a = np.arange(100) + 1
+        a = pad(a, (25, 20), 'minimum', stat_length=10)
+        b = np.array(
+            [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+              1,  1,  1,  1,  1,
+
+              1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
+             11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+             21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+             31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+             41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+             51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+             61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+             71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+             81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+             91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+
+             91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+             91, 91, 91, 91, 91, 91, 91, 91, 91, 91]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'median')
+        b = np.array(
+            [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_01(self):
+        a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
+        a = pad(a, 1, 'median')
+        b = np.array(
+            [[4, 4, 5, 4, 4],
+
+             [3, 3, 1, 4, 3],
+             [5, 4, 5, 9, 5],
+             [8, 9, 8, 2, 8],
+
+             [4, 4, 5, 4, 4]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_02(self):
+        a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
+        a = pad(a.T, 1, 'median').T
+        b = np.array(
+            [[5, 4, 5, 4, 5],
+
+             [3, 3, 1, 4, 3],
+             [5, 4, 5, 9, 5],
+             [8, 9, 8, 2, 8],
+
+             [5, 4, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_median_stat_length(self):
+        a = np.arange(100).astype('f')
+        a[1] = 2.
+        a[97] = 96.
+        a = pad(a, (25, 20), 'median', stat_length=(3, 5))
+        b = np.array(
+            [ 2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,
+              2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,
+              2.,  2.,  2.,  2.,  2.,
+
+              0.,  2.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 96., 98., 99.,
+
+             96., 96., 96., 96., 96., 96., 96., 96., 96., 96.,
+             96., 96., 96., 96., 96., 96., 96., 96., 96., 96.]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_mean_shape_one(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'mean', stat_length=2)
+        b = np.array(
+            [[4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
+             [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_mean_2(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'mean')
+        b = np.array(
+            [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5,
+
+             0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
+             10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
+             20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
+             30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
+             40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
+             50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
+             60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
+             70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
+             80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
+             90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
+
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
+             49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
+            )
+        assert_array_equal(a, b)
+
+
+class TestConstant(TestCase):
+    def test_check_constant(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'constant', constant_values=(10, 20))
+        b = np.array(
+            [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+             10, 10, 10, 10, 10,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+             20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_constant_zeros(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'constant')
+        b = np.array(
+            [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+              0,  0,  0,  0,  0,  0,  0,  0,  0,  0]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_constant_float(self):
+        # If input array is int, but constant_values are float, the dtype of
+        # the array to be padded is kept
+        arr = np.arange(30).reshape(5, 6)
+        test = pad(arr, (1, 2), mode='constant',
+                   constant_values=1.1)
+        expected = np.array(
+            [[ 1,  1,  1,  1,  1,  1,  1,  1,  1],
+
+             [ 1,  0,  1,  2,  3,  4,  5,  1,  1],
+             [ 1,  6,  7,  8,  9, 10, 11,  1,  1],
+             [ 1, 12, 13, 14, 15, 16, 17,  1,  1],
+             [ 1, 18, 19, 20, 21, 22, 23,  1,  1],
+             [ 1, 24, 25, 26, 27, 28, 29,  1,  1],
+
+             [ 1,  1,  1,  1,  1,  1,  1,  1,  1],
+             [ 1,  1,  1,  1,  1,  1,  1,  1,  1]]
+            )
+        assert_allclose(test, expected)
+
+    def test_check_constant_float2(self):
+        # If input array is float, and constant_values are float, the dtype of
+        # the array to be padded is kept - here retaining the float constants
+        arr = np.arange(30).reshape(5, 6)
+        arr_float = arr.astype(np.float64)
+        test = pad(arr_float, ((1, 2), (1, 2)), mode='constant',
+                   constant_values=1.1)
+        expected = np.array(
+            [[  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1],
+
+             [  1.1,   0. ,   1. ,   2. ,   3. ,   4. ,   5. ,   1.1,   1.1],
+             [  1.1,   6. ,   7. ,   8. ,   9. ,  10. ,  11. ,   1.1,   1.1],
+             [  1.1,  12. ,  13. ,  14. ,  15. ,  16. ,  17. ,   1.1,   1.1],
+             [  1.1,  18. ,  19. ,  20. ,  21. ,  22. ,  23. ,   1.1,   1.1],
+             [  1.1,  24. ,  25. ,  26. ,  27. ,  28. ,  29. ,   1.1,   1.1],
+
+             [  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1],
+             [  1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1,   1.1]]
+            )
+        assert_allclose(test, expected)
+
+    def test_check_constant_float3(self):
+        a = np.arange(100, dtype=float)
+        a = pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2))
+        b = np.array(
+            [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
+             -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
+             -1.1, -1.1, -1.1, -1.1, -1.1,
+
+             0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2,
+             -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2]
+            )
+        assert_allclose(a, b)
+
+    def test_check_constant_odd_pad_amount(self):
+        arr = np.arange(30).reshape(5, 6)
+        test = pad(arr, ((1,), (2,)), mode='constant',
+                   constant_values=3)
+        expected = np.array(
+            [[ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
+
+             [ 3,  3,  0,  1,  2,  3,  4,  5,  3,  3],
+             [ 3,  3,  6,  7,  8,  9, 10, 11,  3,  3],
+             [ 3,  3, 12, 13, 14, 15, 16, 17,  3,  3],
+             [ 3,  3, 18, 19, 20, 21, 22, 23,  3,  3],
+             [ 3,  3, 24, 25, 26, 27, 28, 29,  3,  3],
+
+             [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3]]
+            )
+        assert_allclose(test, expected)
+
+
+class TestLinearRamp(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100).astype('f')
+        a = pad(a, (25, 20), 'linear_ramp', end_values=(4, 5))
+        b = np.array(
+            [4.00, 3.84, 3.68, 3.52, 3.36, 3.20, 3.04, 2.88, 2.72, 2.56,
+             2.40, 2.24, 2.08, 1.92, 1.76, 1.60, 1.44, 1.28, 1.12, 0.96,
+             0.80, 0.64, 0.48, 0.32, 0.16,
+
+             0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00,
+             10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
+             20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
+             30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
+             40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0,
+             50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0,
+             60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0,
+             70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
+             80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0,
+             90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0,
+
+             94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0,
+             47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.]
+            )
+        assert_allclose(a, b, rtol=1e-5, atol=1e-5)
+
+    def test_check_2d(self):
+        arr = np.arange(20).reshape(4, 5).astype(np.float64)
+        test = pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0))
+        expected = np.array(
+            [[0.,   0.,   0.,   0.,   0.,   0.,   0.,    0.,   0.],
+             [0.,   0.,   0.,  0.5,   1.,  1.5,   2.,    1.,   0.],
+             [0.,   0.,   0.,   1.,   2.,   3.,   4.,    2.,   0.],
+             [0.,  2.5,   5.,   6.,   7.,   8.,   9.,   4.5,   0.],
+             [0.,   5.,  10.,  11.,  12.,  13.,  14.,    7.,   0.],
+             [0.,  7.5,  15.,  16.,  17.,  18.,  19.,   9.5,   0.],
+             [0., 3.75,  7.5,   8.,  8.5,   9.,  9.5,  4.75,   0.],
+             [0.,   0.,   0.,   0.,   0.,   0.,   0.,    0.,   0.]])
+        assert_allclose(test, expected)
+
+
+class TestReflect(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'reflect')
+        b = np.array(
+            [25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
+             15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+             5, 4, 3, 2, 1,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             98, 97, 96, 95, 94, 93, 92, 91, 90, 89,
+             88, 87, 86, 85, 84, 83, 82, 81, 80, 79]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_odd_method(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'reflect', reflect_type='odd')
+        b = np.array(
+            [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16,
+             -15, -14, -13, -12, -11, -10, -9, -8, -7, -6,
+             -5, -4, -3, -2, -1,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+             110, 111, 112, 113, 114, 115, 116, 117, 118, 119]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'reflect')
+        b = np.array(
+            [[7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_shape(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'reflect')
+        b = np.array(
+            [[5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
+             [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 2, 'reflect')
+        b = np.array([3, 2, 1, 2, 3, 2, 1])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 3, 'reflect')
+        b = np.array([2, 3, 2, 1, 2, 3, 2, 1, 2])
+        assert_array_equal(a, b)
+
+    def test_check_03(self):
+        a = pad([1, 2, 3], 4, 'reflect')
+        b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
+        assert_array_equal(a, b)
+
+
+class TestSymmetric(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'symmetric')
+        b = np.array(
+            [24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
+             14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
+             4, 3, 2, 1, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 98, 97, 96, 95, 94, 93, 92, 91, 90,
+             89, 88, 87, 86, 85, 84, 83, 82, 81, 80]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_odd_method(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'symmetric', reflect_type='odd')
+        b = np.array(
+            [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15,
+             -14, -13, -12, -11, -10, -9, -8, -7, -6, -5,
+             -4, -3, -2, -1, 0,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+             109, 110, 111, 112, 113, 114, 115, 116, 117, 118]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'symmetric')
+        b = np.array(
+            [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
+            )
+
+        assert_array_equal(a, b)
+
+    def test_check_large_pad_odd(self):
+        a = [[4, 5, 6], [6, 7, 8]]
+        a = pad(a, (5, 7), 'symmetric', reflect_type='odd')
+        b = np.array(
+            [[-3, -2, -2, -1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6],
+             [-3, -2, -2, -1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6],
+             [-1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8],
+             [-1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8],
+             [ 1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10],
+
+             [ 1,  2,  2,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10],
+             [ 3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12],
+
+             [ 3,  4,  4,  5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12],
+             [ 5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14],
+             [ 5,  6,  6,  7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14],
+             [ 7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
+             [ 7,  8,  8,  9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
+             [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18],
+             [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_shape(self):
+        a = [[4, 5, 6]]
+        a = pad(a, (5, 7), 'symmetric')
+        b = np.array(
+            [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
+             [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 2, 'symmetric')
+        b = np.array([2, 1, 1, 2, 3, 3, 2])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 3, 'symmetric')
+        b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1])
+        assert_array_equal(a, b)
+
+    def test_check_03(self):
+        a = pad([1, 2, 3], 6, 'symmetric')
+        b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3])
+        assert_array_equal(a, b)
+
+
+class TestWrap(TestCase):
+    def test_check_simple(self):
+        a = np.arange(100)
+        a = pad(a, (25, 20), 'wrap')
+        b = np.array(
+            [75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+             85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+             95, 96, 97, 98, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+             30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+             40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+             50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+             60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+             70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+             80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+             90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+             0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+             10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_large_pad(self):
+        a = np.arange(12)
+        a = np.reshape(a, (3, 4))
+        a = pad(a, (10, 12), 'wrap')
+        b = np.array(
+            [[10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11],
+             [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
+              3, 0, 1, 2, 3, 0, 1, 2, 3],
+             [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
+              7, 4, 5, 6, 7, 4, 5, 6, 7],
+             [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
+              11, 8, 9, 10, 11, 8, 9, 10, 11]]
+            )
+        assert_array_equal(a, b)
+
+    def test_check_01(self):
+        a = pad([1, 2, 3], 3, 'wrap')
+        b = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
+        assert_array_equal(a, b)
+
+    def test_check_02(self):
+        a = pad([1, 2, 3], 4, 'wrap')
+        b = np.array([3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1])
+        assert_array_equal(a, b)
+
+
+class TestStatLen(TestCase):
+    def test_check_simple(self):
+        a = np.arange(30)
+        a = np.reshape(a, (6, 5))
+        a = pad(a, ((2, 3), (3, 2)), mode='mean', stat_length=(3,))
+        b = np.array(
+            [[6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+             [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+
+             [1, 1, 1, 0, 1, 2, 3, 4, 3, 3],
+             [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
+             [11, 11, 11, 10, 11, 12, 13, 14, 13, 13],
+             [16, 16, 16, 15, 16, 17, 18, 19, 18, 18],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [26, 26, 26, 25, 26, 27, 28, 29, 28, 28],
+
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
+             [21, 21, 21, 20, 21, 22, 23, 24, 23, 23]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestEdge(TestCase):
+    def test_check_simple(self):
+        a = np.arange(12)
+        a = np.reshape(a, (4, 3))
+        a = pad(a, ((2, 3), (3, 2)), 'edge')
+        b = np.array(
+            [[0, 0, 0, 0, 1, 2, 2, 2],
+             [0, 0, 0, 0, 1, 2, 2, 2],
+
+             [0, 0, 0, 0, 1, 2, 2, 2],
+             [3, 3, 3, 3, 4, 5, 5, 5],
+             [6, 6, 6, 6, 7, 8, 8, 8],
+             [9, 9, 9, 9, 10, 11, 11, 11],
+
+             [9, 9, 9, 9, 10, 11, 11, 11],
+             [9, 9, 9, 9, 10, 11, 11, 11],
+             [9, 9, 9, 9, 10, 11, 11, 11]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestZeroPadWidth(TestCase):
+    def test_zero_pad_width(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        for pad_width in (0, (0, 0), ((0, 0), (0, 0))):
+            assert_array_equal(arr, pad(arr, pad_width, mode='constant'))
+
+
+class TestLegacyVectorFunction(TestCase):
+    def test_legacy_vector_functionality(self):
+        def _padwithtens(vector, pad_width, iaxis, kwargs):
+            vector[:pad_width[0]] = 10
+            vector[-pad_width[1]:] = 10
+            return vector
+
+        a = np.arange(6).reshape(2, 3)
+        a = pad(a, 2, _padwithtens)
+        b = np.array(
+            [[10, 10, 10, 10, 10, 10, 10],
+             [10, 10, 10, 10, 10, 10, 10],
+
+             [10, 10,  0,  1,  2, 10, 10],
+             [10, 10,  3,  4,  5, 10, 10],
+
+             [10, 10, 10, 10, 10, 10, 10],
+             [10, 10, 10, 10, 10, 10, 10]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestNdarrayPadWidth(TestCase):
+    def test_check_simple(self):
+        a = np.arange(12)
+        a = np.reshape(a, (4, 3))
+        a = pad(a, np.array(((2, 3), (3, 2))), 'edge')
+        b = np.array(
+            [[0,  0,  0,    0,  1,  2,    2,  2],
+             [0,  0,  0,    0,  1,  2,    2,  2],
+
+             [0,  0,  0,    0,  1,  2,    2,  2],
+             [3,  3,  3,    3,  4,  5,    5,  5],
+             [6,  6,  6,    6,  7,  8,    8,  8],
+             [9,  9,  9,    9, 10, 11,   11, 11],
+
+             [9,  9,  9,    9, 10, 11,   11, 11],
+             [9,  9,  9,    9, 10, 11,   11, 11],
+             [9,  9,  9,    9, 10, 11,   11, 11]]
+            )
+        assert_array_equal(a, b)
+
+
+class TestUnicodeInput(TestCase):
+    def test_unicode_mode(self):
+        try:
+            constant_mode = unicode('constant')
+        except NameError:
+            constant_mode = 'constant'
+        a = np.pad([1], 2, mode=constant_mode)
+        b = np.array([0, 0, 1, 0, 0])
+        assert_array_equal(a, b)
+
+
+class ValueError1(TestCase):
+    def test_check_simple(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((2, 3), (3, 2), (4, 5)),
+                      **kwargs)
+
+    def test_check_negative_stat_length(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(-3, ))
+        assert_raises(ValueError, pad, arr, ((2, 3), (3, 2)),
+                      **kwargs)
+
+    def test_check_negative_pad_width(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)),
+                      **kwargs)
+
+
+class ValueError2(TestCase):
+    def test_check_negative_pad_amount(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(ValueError, pad, arr, ((-2, 3), (3, 2)),
+                      **kwargs)
+
+
+class ValueError3(TestCase):
+    def test_check_kwarg_not_allowed(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, 4, mode='mean',
+                      reflect_type='odd')
+
+    def test_mode_not_set(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(TypeError, pad, arr, 4)
+
+    def test_malformed_pad_amount(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, (4, 5, 6, 7), mode='constant')
+
+    def test_malformed_pad_amount2(self):
+        arr = np.arange(30).reshape(5, 6)
+        assert_raises(ValueError, pad, arr, ((3, 4, 5), (0, 1, 2)),
+                      mode='constant')
+
+    def test_pad_too_many_axes(self):
+        arr = np.arange(30).reshape(5, 6)
+
+        # Attempt to pad using a 3D array equivalent
+        bad_shape = (((3,), (4,), (5,)), ((0,), (1,), (2,)))
+        assert_raises(ValueError, pad, arr, bad_shape,
+                      mode='constant')
+
+
+class TypeError1(TestCase):
+    def test_float(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, ((-2.1, 3), (3, 2)))
+        assert_raises(TypeError, pad, arr, np.array(((-2.1, 3), (3, 2))))
+
+    def test_str(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, 'foo')
+        assert_raises(TypeError, pad, arr, np.array('foo'))
+
+    def test_object(self):
+        class FooBar(object):
+            pass
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, FooBar())
+
+    def test_complex(self):
+        arr = np.arange(30)
+        assert_raises(TypeError, pad, arr, complex(1, -1))
+        assert_raises(TypeError, pad, arr, np.array(complex(1, -1)))
+
+    def test_check_wrong_pad_amount(self):
+        arr = np.arange(30)
+        arr = np.reshape(arr, (6, 5))
+        kwargs = dict(mode='mean', stat_length=(3, ))
+        assert_raises(TypeError, pad, arr, ((2, 3, 4), (3, 2)),
+                      **kwargs)
+
+
+if __name__ == "__main__":
+    np.testing.run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
new file mode 100644
index 0000000000..852183ffec
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
@@ -0,0 +1,309 @@
+"""Test functions for 1D array set operations.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_array_equal, assert_equal
+    )
+from numpy.lib.arraysetops import (
+    ediff1d, intersect1d, setxor1d, union1d, setdiff1d, unique, in1d
+    )
+
+
+class TestSetOps(TestCase):
+
+    def test_unique(self):
+
+        def check_all(a, b, i1, i2, c, dt):
+            base_msg = 'check {0} failed for type {1}'
+
+            msg = base_msg.format('values', dt)
+            v = unique(a)
+            assert_array_equal(v, b, msg)
+
+            msg = base_msg.format('return_index', dt)
+            v, j = unique(a, 1, 0, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, i1, msg)
+
+            msg = base_msg.format('return_inverse', dt)
+            v, j = unique(a, 0, 1, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, i2, msg)
+
+            msg = base_msg.format('return_counts', dt)
+            v, j = unique(a, 0, 0, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j, c, msg)
+
+            msg = base_msg.format('return_index and return_inverse', dt)
+            v, j1, j2 = unique(a, 1, 1, 0)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, i2, msg)
+
+            msg = base_msg.format('return_index and return_counts', dt)
+            v, j1, j2 = unique(a, 1, 0, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, c, msg)
+
+            msg = base_msg.format('return_inverse and return_counts', dt)
+            v, j1, j2 = unique(a, 0, 1, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i2, msg)
+            assert_array_equal(j2, c, msg)
+
+            msg = base_msg.format(('return_index, return_inverse '
+                                   'and return_counts'), dt)
+            v, j1, j2, j3 = unique(a, 1, 1, 1)
+            assert_array_equal(v, b, msg)
+            assert_array_equal(j1, i1, msg)
+            assert_array_equal(j2, i2, msg)
+            assert_array_equal(j3, c, msg)
+
+        a = [5, 7, 1, 2, 1, 5, 7]*10
+        b = [1, 2, 5, 7]
+        i1 = [2, 3, 0, 1]
+        i2 = [2, 3, 0, 1, 0, 2, 3]*10
+        c = np.multiply([2, 1, 2, 2], 10)
+
+        # test for numeric arrays
+        types = []
+        types.extend(np.typecodes['AllInteger'])
+        types.extend(np.typecodes['AllFloat'])
+        types.append('datetime64[D]')
+        types.append('timedelta64[D]')
+        for dt in types:
+            aa = np.array(a, dt)
+            bb = np.array(b, dt)
+            check_all(aa, bb, i1, i2, c, dt)
+
+        # test for object arrays
+        dt = 'O'
+        aa = np.empty(len(a), dt)
+        aa[:] = a
+        bb = np.empty(len(b), dt)
+        bb[:] = b
+        check_all(aa, bb, i1, i2, c, dt)
+
+        # test for structured arrays
+        dt = [('', 'i'), ('', 'i')]
+        aa = np.array(list(zip(a, a)), dt)
+        bb = np.array(list(zip(b, b)), dt)
+        check_all(aa, bb, i1, i2, c, dt)
+
+        # test for ticket #2799
+        aa = [1. + 0.j, 1 - 1.j, 1]
+        assert_array_equal(np.unique(aa), [1. - 1.j, 1. + 0.j])
+
+        # test for ticket #4785
+        a = [(1, 2), (1, 2), (2, 3)]
+        unq = [1, 2, 3]
+        inv = [0, 1, 0, 1, 1, 2]
+        a1 = unique(a)
+        assert_array_equal(a1, unq)
+        a2, a2_inv = unique(a, return_inverse=True)
+        assert_array_equal(a2, unq)
+        assert_array_equal(a2_inv, inv)
+
+        # test for chararrays with return_inverse (gh-5099)
+        a = np.chararray(5)
+        a[...] = ''
+        a2, a2_inv = np.unique(a, return_inverse=True)
+        assert_array_equal(a2_inv, np.zeros(5))
+
+    def test_intersect1d(self):
+        # unique inputs
+        a = np.array([5, 7, 1, 2])
+        b = np.array([2, 4, 3, 1, 5])
+
+        ec = np.array([1, 2, 5])
+        c = intersect1d(a, b, assume_unique=True)
+        assert_array_equal(c, ec)
+
+        # non-unique inputs
+        a = np.array([5, 5, 7, 1, 2])
+        b = np.array([2, 1, 4, 3, 3, 1, 5])
+
+        ed = np.array([1, 2, 5])
+        c = intersect1d(a, b)
+        assert_array_equal(c, ed)
+
+        assert_array_equal([], intersect1d([], []))
+
+    def test_setxor1d(self):
+        a = np.array([5, 7, 1, 2])
+        b = np.array([2, 4, 3, 1, 5])
+
+        ec = np.array([3, 4, 7])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.array([1, 2, 3])
+        b = np.array([6, 5, 4])
+
+        ec = np.array([1, 2, 3, 4, 5, 6])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.array([1, 8, 2, 3])
+        b = np.array([6, 5, 4, 8])
+
+        ec = np.array([1, 2, 3, 4, 5, 6])
+        c = setxor1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], setxor1d([], []))
+
+    def test_ediff1d(self):
+        zero_elem = np.array([])
+        one_elem = np.array([1])
+        two_elem = np.array([1, 2])
+
+        assert_array_equal([], ediff1d(zero_elem))
+        assert_array_equal([0], ediff1d(zero_elem, to_begin=0))
+        assert_array_equal([0], ediff1d(zero_elem, to_end=0))
+        assert_array_equal([-1, 0], ediff1d(zero_elem, to_begin=-1, to_end=0))
+        assert_array_equal([], ediff1d(one_elem))
+        assert_array_equal([1], ediff1d(two_elem))
+
+    def test_in1d(self):
+        # we use two different sizes for the b array here to test the
+        # two different paths in in1d().
+        for mult in (1, 10):
+            # One check without np.array, to make sure lists are handled correct
+            a = [5, 7, 1, 2]
+            b = [2, 4, 3, 1, 5] * mult
+            ec = np.array([True, False, True, True])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a[0] = 8
+            ec = np.array([False, False, True, True])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a[0], a[3] = 4, 8
+            ec = np.array([True, False, True, False])
+            c = in1d(a, b, assume_unique=True)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
+            b = [2, 3, 4] * mult
+            ec = [False, True, False, True, True, True, True, True, True, False,
+                  True, False, False, False]
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            b = b + [5, 5, 4] * mult
+            ec = [True, True, True, True, True, True, True, True, True, True,
+                  True, False, True, True]
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 7, 1, 2])
+            b = np.array([2, 4, 3, 1, 5] * mult)
+            ec = np.array([True, False, True, True])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 7, 1, 1, 2])
+            b = np.array([2, 4, 3, 3, 1, 5] * mult)
+            ec = np.array([True, False, True, True, True])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+            a = np.array([5, 5])
+            b = np.array([2, 2] * mult)
+            ec = np.array([False, False])
+            c = in1d(a, b)
+            assert_array_equal(c, ec)
+
+        a = np.array([5])
+        b = np.array([2])
+        ec = np.array([False])
+        c = in1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal(in1d([], []), [])
+
+    def test_in1d_char_array(self):
+        a = np.array(['a', 'b', 'c', 'd', 'e', 'c', 'e', 'b'])
+        b = np.array(['a', 'c'])
+
+        ec = np.array([True, False, True, False, False, True, False, False])
+        c = in1d(a, b)
+
+        assert_array_equal(c, ec)
+
+    def test_in1d_invert(self):
+        "Test in1d's invert parameter"
+        # We use two different sizes for the b array here to test the
+        # two different paths in in1d().
+        for mult in (1, 10):
+            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
+            b = [2, 3, 4] * mult
+            assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+    def test_in1d_ravel(self):
+        # Test that in1d ravels its input arrays. This is not documented
+        # behavior however. The test is to ensure consistentency.
+        a = np.arange(6).reshape(2, 3)
+        b = np.arange(3, 9).reshape(3, 2)
+        long_b = np.arange(3, 63).reshape(30, 2)
+        ec = np.array([False, False, False, True, True, True])
+
+        assert_array_equal(in1d(a, b, assume_unique=True), ec)
+        assert_array_equal(in1d(a, b, assume_unique=False), ec)
+        assert_array_equal(in1d(a, long_b, assume_unique=True), ec)
+        assert_array_equal(in1d(a, long_b, assume_unique=False), ec)
+
+    def test_union1d(self):
+        a = np.array([5, 4, 7, 1, 2])
+        b = np.array([2, 4, 3, 3, 2, 1, 5])
+
+        ec = np.array([1, 2, 3, 4, 5, 7])
+        c = union1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], union1d([], []))
+
+    def test_setdiff1d(self):
+        a = np.array([6, 5, 4, 7, 1, 2, 7, 4])
+        b = np.array([2, 4, 3, 3, 2, 1, 5])
+
+        ec = np.array([6, 7])
+        c = setdiff1d(a, b)
+        assert_array_equal(c, ec)
+
+        a = np.arange(21)
+        b = np.arange(19)
+        ec = np.array([19, 20])
+        c = setdiff1d(a, b)
+        assert_array_equal(c, ec)
+
+        assert_array_equal([], setdiff1d([], []))
+        a = np.array((), np.uint32)
+        assert_equal(setdiff1d(a, []).dtype, np.uint32)
+
+    def test_setdiff1d_char_array(self):
+        a = np.array(['a', 'b', 'c'])
+        b = np.array(['a', 'b', 's'])
+        assert_array_equal(setdiff1d(a, b), np.array(['c']))
+
+    def test_manyways(self):
+        a = np.array([5, 7, 1, 2, 8])
+        b = np.array([9, 8, 2, 4, 3, 1, 5])
+
+        c1 = setxor1d(a, b)
+        aux1 = intersect1d(a, b)
+        aux2 = union1d(a, b)
+        c2 = setdiff1d(aux2, aux1)
+        assert_array_equal(c1, c2)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
new file mode 100644
index 0000000000..64ad7f4de4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
@@ -0,0 +1,52 @@
+from __future__ import division, absolute_import, print_function
+
+from operator import mul
+from functools import reduce
+
+import numpy as np
+from numpy.random import randint
+from numpy.lib import Arrayterator
+from numpy.testing import assert_
+
+
+def test():
+    np.random.seed(np.arange(10))
+
+    # Create a random array
+    ndims = randint(5)+1
+    shape = tuple(randint(10)+1 for dim in range(ndims))
+    els = reduce(mul, shape)
+    a = np.arange(els)
+    a.shape = shape
+
+    buf_size = randint(2*els)
+    b = Arrayterator(a, buf_size)
+
+    # Check that each block has at most ``buf_size`` elements
+    for block in b:
+        assert_(len(block.flat) <= (buf_size or els))
+
+    # Check that all elements are iterated correctly
+    assert_(list(b.flat) == list(a.flat))
+
+    # Slice arrayterator
+    start = [randint(dim) for dim in shape]
+    stop = [randint(dim)+1 for dim in shape]
+    step = [randint(dim)+1 for dim in shape]
+    slice_ = tuple(slice(*t) for t in zip(start, stop, step))
+    c = b[slice_]
+    d = a[slice_]
+
+    # Check that each block has at most ``buf_size`` elements
+    for block in c:
+        assert_(len(block.flat) <= (buf_size or els))
+
+    # Check that the arrayterator is sliced correctly
+    assert_(np.all(c.__array__() == d))
+
+    # Check that all elements are iterated correctly
+    assert_(list(c.flat) == list(d.flat))
+
+if __name__ == '__main__':
+    from numpy.testing import run_module_suite
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
new file mode 100644
index 0000000000..baa785424a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
@@ -0,0 +1,163 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_almost_equal,
+    assert_allclose
+    )
+
+
+class TestFinancial(TestCase):
+    def test_rate(self):
+        assert_almost_equal(np.rate(10, 0, -3500, 10000),
+                            0.1107, 4)
+
+    def test_irr(self):
+        v = [-150000, 15000, 25000, 35000, 45000, 60000]
+        assert_almost_equal(np.irr(v), 0.0524, 2)
+        v = [-100, 0, 0, 74]
+        assert_almost_equal(np.irr(v), -0.0955, 2)
+        v = [-100, 39, 59, 55, 20]
+        assert_almost_equal(np.irr(v), 0.28095, 2)
+        v = [-100, 100, 0, -7]
+        assert_almost_equal(np.irr(v), -0.0833, 2)
+        v = [-100, 100, 0, 7]
+        assert_almost_equal(np.irr(v), 0.06206, 2)
+        v = [-5, 10.5, 1, -8, 1]
+        assert_almost_equal(np.irr(v), 0.0886, 2)
+
+    def test_pv(self):
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0), -127128.17, 2)
+
+    def test_fv(self):
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0), 86609.36, 2)
+
+    def test_pmt(self):
+        res = np.pmt(0.08/12, 5*12, 15000)
+        tgt = -304.145914
+        assert_allclose(res, tgt)
+        # Test the edge case where rate == 0.0
+        res = np.pmt(0.0, 5*12, 15000)
+        tgt = -250.0
+        assert_allclose(res, tgt)
+        # Test the case where we use broadcast and
+        # the arguments passed in are arrays.
+        res = np.pmt([[0.0, 0.8],[0.3, 0.8]],[12, 3],[2000, 20000])
+        tgt = np.array([[-166.66667, -19311.258],[-626.90814, -19311.258]])
+        assert_allclose(res, tgt)
+
+    def test_ppmt(self):
+        np.round(np.ppmt(0.1/12, 1, 60, 55000), 2) == 710.25
+
+    def test_ipmt(self):
+        np.round(np.ipmt(0.1/12, 1, 24, 2000), 2) == 16.67
+
+    def test_nper(self):
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
+                            21.54, 2)
+
+    def test_nper2(self):
+        assert_almost_equal(np.nper(0.0, -2000, 0, 100000.),
+                            50.0, 1)
+
+    def test_npv(self):
+        assert_almost_equal(
+            np.npv(0.05, [-15000, 1500, 2500, 3500, 4500, 6000]),
+            122.89, 2)
+
+    def test_mirr(self):
+        val = [-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000]
+        assert_almost_equal(np.mirr(val, 0.08, 0.055), 0.0666, 4)
+
+        val = [-120000, 39000, 30000, 21000, 37000, 46000]
+        assert_almost_equal(np.mirr(val, 0.10, 0.12), 0.126094, 6)
+
+        val = [100, 200, -50, 300, -200]
+        assert_almost_equal(np.mirr(val, 0.05, 0.06), 0.3428, 4)
+
+        val = [39000, 30000, 21000, 37000, 46000]
+        assert_(np.isnan(np.mirr(val, 0.10, 0.12)))
+
+    def test_when(self):
+        #begin
+        assert_almost_equal(np.rate(10, 20, -3500, 10000, 1),
+                            np.rate(10, 20, -3500, 10000, 'begin'), 4)
+        #end
+        assert_almost_equal(np.rate(10, 20, -3500, 10000),
+                            np.rate(10, 20, -3500, 10000, 'end'), 4)
+        assert_almost_equal(np.rate(10, 20, -3500, 10000, 0),
+                            np.rate(10, 20, -3500, 10000, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 1),
+                            np.pv(0.07, 20, 12000, 0, 'begin'), 2)
+        # end
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0),
+                            np.pv(0.07, 20, 12000, 0, 'end'), 2)
+        assert_almost_equal(np.pv(0.07, 20, 12000, 0, 0),
+                            np.pv(0.07, 20, 12000, 0, 'end'), 2)
+
+        # begin
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 1),
+                            np.fv(0.075, 20, -2000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0),
+                            np.fv(0.075, 20, -2000, 0, 'end'), 4)
+        assert_almost_equal(np.fv(0.075, 20, -2000, 0, 0),
+                            np.fv(0.075, 20, -2000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0, 1),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'end'), 4)
+        assert_almost_equal(np.pmt(0.08/12, 5*12, 15000., 0, 0),
+                            np.pmt(0.08/12, 5*12, 15000., 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0, 1),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'end'), 4)
+        assert_almost_equal(np.ppmt(0.1/12, 1, 60, 55000, 0, 0),
+                            np.ppmt(0.1/12, 1, 60, 55000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0, 1),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'begin'), 4)
+        # end
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'end'), 4)
+        assert_almost_equal(np.ipmt(0.1/12, 1, 24, 2000, 0, 0),
+                            np.ipmt(0.1/12, 1, 24, 2000, 0, 'end'), 4)
+
+        # begin
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., 1),
+                            np.nper(0.075, -2000, 0, 100000., 'begin'), 4)
+        # end
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
+                            np.nper(0.075, -2000, 0, 100000., 'end'), 4)
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., 0),
+                            np.nper(0.075, -2000, 0, 100000., 'end'), 4)
+
+    def test_broadcast(self):
+        assert_almost_equal(np.nper(0.075, -2000, 0, 100000., [0, 1]),
+                            [21.5449442, 20.76156441], 4)
+
+        assert_almost_equal(np.ipmt(0.1/12, list(range(5)), 24, 2000),
+                            [-17.29165168, -16.66666667, -16.03647345,
+                                -15.40102862, -14.76028842], 4)
+
+        assert_almost_equal(np.ppmt(0.1/12, list(range(5)), 24, 2000),
+                            [-74.998201, -75.62318601, -76.25337923,
+                                -76.88882405, -77.52956425], 4)
+
+        assert_almost_equal(np.ppmt(0.1/12, list(range(5)), 24, 2000, 0,
+                                    [0, 0, 1, 'end', 'begin']),
+                            [-74.998201, -75.62318601, -75.62318601,
+                                -76.88882405, -76.88882405], 4)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_format.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
new file mode 100644
index 0000000000..a091ef5b3f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
@@ -0,0 +1,840 @@
+from __future__ import division, absolute_import, print_function
+
+r''' Test the .npy file format.
+
+Set up:
+
+    >>> import sys
+    >>> from io import BytesIO
+    >>> from numpy.lib import format
+    >>>
+    >>> scalars = [
+    ...     np.uint8,
+    ...     np.int8,
+    ...     np.uint16,
+    ...     np.int16,
+    ...     np.uint32,
+    ...     np.int32,
+    ...     np.uint64,
+    ...     np.int64,
+    ...     np.float32,
+    ...     np.float64,
+    ...     np.complex64,
+    ...     np.complex128,
+    ...     object,
+    ... ]
+    >>>
+    >>> basic_arrays = []
+    >>>
+    >>> for scalar in scalars:
+    ...     for endian in '<>':
+    ...         dtype = np.dtype(scalar).newbyteorder(endian)
+    ...         basic = np.arange(15).astype(dtype)
+    ...         basic_arrays.extend([
+    ...             np.array([], dtype=dtype),
+    ...             np.array(10, dtype=dtype),
+    ...             basic,
+    ...             basic.reshape((3,5)),
+    ...             basic.reshape((3,5)).T,
+    ...             basic.reshape((3,5))[::-1,::2],
+    ...         ])
+    ...
+    >>>
+    >>> Pdescr = [
+    ...     ('x', 'i4', (2,)),
+    ...     ('y', 'f8', (2, 2)),
+    ...     ('z', 'u1')]
+    >>>
+    >>>
+    >>> PbufferT = [
+    ...     ([3,2], [[6.,4.],[6.,4.]], 8),
+    ...     ([4,3], [[7.,5.],[7.,5.]], 9),
+    ...     ]
+    >>>
+    >>>
+    >>> Ndescr = [
+    ...     ('x', 'i4', (2,)),
+    ...     ('Info', [
+    ...         ('value', 'c16'),
+    ...         ('y2', 'f8'),
+    ...         ('Info2', [
+    ...             ('name', 'S2'),
+    ...             ('value', 'c16', (2,)),
+    ...             ('y3', 'f8', (2,)),
+    ...             ('z3', 'u4', (2,))]),
+    ...         ('name', 'S2'),
+    ...         ('z2', 'b1')]),
+    ...     ('color', 'S2'),
+    ...     ('info', [
+    ...         ('Name', 'U8'),
+    ...         ('Value', 'c16')]),
+    ...     ('y', 'f8', (2, 2)),
+    ...     ('z', 'u1')]
+    >>>
+    >>>
+    >>> NbufferT = [
+    ...     ([3,2], (6j, 6., ('nn', [6j,4j], [6.,4.], [1,2]), 'NN', True), 'cc', ('NN', 6j), [[6.,4.],[6.,4.]], 8),
+    ...     ([4,3], (7j, 7., ('oo', [7j,5j], [7.,5.], [2,1]), 'OO', False), 'dd', ('OO', 7j), [[7.,5.],[7.,5.]], 9),
+    ...     ]
+    >>>
+    >>>
+    >>> record_arrays = [
+    ...     np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')),
+    ...     np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')),
+    ...     np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')),
+    ...     np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')),
+    ... ]
+
+Test the magic string writing.
+
+    >>> format.magic(1, 0)
+    '\x93NUMPY\x01\x00'
+    >>> format.magic(0, 0)
+    '\x93NUMPY\x00\x00'
+    >>> format.magic(255, 255)
+    '\x93NUMPY\xff\xff'
+    >>> format.magic(2, 5)
+    '\x93NUMPY\x02\x05'
+
+Test the magic string reading.
+
+    >>> format.read_magic(BytesIO(format.magic(1, 0)))
+    (1, 0)
+    >>> format.read_magic(BytesIO(format.magic(0, 0)))
+    (0, 0)
+    >>> format.read_magic(BytesIO(format.magic(255, 255)))
+    (255, 255)
+    >>> format.read_magic(BytesIO(format.magic(2, 5)))
+    (2, 5)
+
+Test the header writing.
+
+    >>> for arr in basic_arrays + record_arrays:
+    ...     f = BytesIO()
+    ...     format.write_array_header_1_0(f, arr)   # XXX: arr is not a dict, items gets called on it
+    ...     print(repr(f.getvalue()))
+    ...
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i2', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<u8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<u8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>u8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<i8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<i8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>i8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<f4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<f4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>f4', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<f8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<f8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>f8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '<c8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '<c8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': '>c8', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (0,)}             \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': ()}               \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (15,)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (3, 5)}           \n"
+    "F\x00{'descr': '<c16', 'fortran_order': True, 'shape': (5, 3)}            \n"
+    "F\x00{'descr': '<c16', 'fortran_order': False, 'shape': (3, 3)}           \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (0,)}             \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': ()}               \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (15,)}            \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 5)}           \n"
+    "F\x00{'descr': '>c16', 'fortran_order': True, 'shape': (5, 3)}            \n"
+    "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 3)}           \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)}              \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()}                \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)}            \n"
+    "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)}             \n"
+    "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)}            \n"
+    "v\x00{'descr': [('x', '<i4', (2,)), ('y', '<f8', (2, 2)), ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}         \n"
+    "\x16\x02{'descr': [('x', '<i4', (2,)),\n           ('Info',\n            [('value', '<c16'),\n             ('y2', '<f8'),\n             ('Info2',\n              [('name', '|S2'),\n               ('value', '<c16', (2,)),\n               ('y3', '<f8', (2,)),\n               ('z3', '<u4', (2,))]),\n             ('name', '|S2'),\n             ('z2', '|b1')]),\n           ('color', '|S2'),\n           ('info', [('Name', '<U8'), ('Value', '<c16')]),\n           ('y', '<f8', (2, 2)),\n           ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}      \n"
+    "v\x00{'descr': [('x', '>i4', (2,)), ('y', '>f8', (2, 2)), ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}         \n"
+    "\x16\x02{'descr': [('x', '>i4', (2,)),\n           ('Info',\n            [('value', '>c16'),\n             ('y2', '>f8'),\n             ('Info2',\n              [('name', '|S2'),\n               ('value', '>c16', (2,)),\n               ('y3', '>f8', (2,)),\n               ('z3', '>u4', (2,))]),\n             ('name', '|S2'),\n             ('z2', '|b1')]),\n           ('color', '|S2'),\n           ('info', [('Name', '>U8'), ('Value', '>c16')]),\n           ('y', '>f8', (2, 2)),\n           ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)}      \n"
+'''
+
+import sys
+import os
+import shutil
+import tempfile
+import warnings
+from io import BytesIO
+
+import numpy as np
+from numpy.compat import asbytes, asbytes_nested, sixu
+from numpy.testing import (
+    run_module_suite, assert_, assert_array_equal, assert_raises, raises,
+    dec, SkipTest
+    )
+from numpy.lib import format
+
+
+tempdir = None
+
+# Module-level setup.
+
+
+def setup_module():
+    global tempdir
+    tempdir = tempfile.mkdtemp()
+
+
+def teardown_module():
+    global tempdir
+    if tempdir is not None and os.path.isdir(tempdir):
+        shutil.rmtree(tempdir)
+        tempdir = None
+
+
+# Generate some basic arrays to test with.
+scalars = [
+    np.uint8,
+    np.int8,
+    np.uint16,
+    np.int16,
+    np.uint32,
+    np.int32,
+    np.uint64,
+    np.int64,
+    np.float32,
+    np.float64,
+    np.complex64,
+    np.complex128,
+    object,
+]
+basic_arrays = []
+for scalar in scalars:
+    for endian in '<>':
+        dtype = np.dtype(scalar).newbyteorder(endian)
+        basic = np.arange(1500).astype(dtype)
+        basic_arrays.extend([
+            # Empty
+            np.array([], dtype=dtype),
+            # Rank-0
+            np.array(10, dtype=dtype),
+            # 1-D
+            basic,
+            # 2-D C-contiguous
+            basic.reshape((30, 50)),
+            # 2-D F-contiguous
+            basic.reshape((30, 50)).T,
+            # 2-D non-contiguous
+            basic.reshape((30, 50))[::-1, ::2],
+        ])
+
+# More complicated record arrays.
+# This is the structure of the table used for plain objects:
+#
+# +-+-+-+
+# |x|y|z|
+# +-+-+-+
+
+# Structure of a plain array description:
+Pdescr = [
+    ('x', 'i4', (2,)),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+# A plain list of tuples with values for testing:
+PbufferT = [
+    # x     y                  z
+    ([3, 2], [[6., 4.], [6., 4.]], 8),
+    ([4, 3], [[7., 5.], [7., 5.]], 9),
+    ]
+
+
+# This is the structure of the table used for nested objects (DON'T PANIC!):
+#
+# +-+---------------------------------+-----+----------+-+-+
+# |x|Info                             |color|info      |y|z|
+# | +-----+--+----------------+----+--+     +----+-----+ | |
+# | |value|y2|Info2           |name|z2|     |Name|Value| | |
+# | |     |  +----+-----+--+--+    |  |     |    |     | | |
+# | |     |  |name|value|y3|z3|    |  |     |    |     | | |
+# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+
+#
+
+# The corresponding nested array description:
+Ndescr = [
+    ('x', 'i4', (2,)),
+    ('Info', [
+        ('value', 'c16'),
+        ('y2', 'f8'),
+        ('Info2', [
+            ('name', 'S2'),
+            ('value', 'c16', (2,)),
+            ('y3', 'f8', (2,)),
+            ('z3', 'u4', (2,))]),
+        ('name', 'S2'),
+        ('z2', 'b1')]),
+    ('color', 'S2'),
+    ('info', [
+        ('Name', 'U8'),
+        ('Value', 'c16')]),
+    ('y', 'f8', (2, 2)),
+    ('z', 'u1')]
+
+NbufferT = [
+    # x     Info                                                color info        y                  z
+    #       value y2 Info2                            name z2         Name Value
+    #                name   value    y3       z3
+    ([3, 2], (6j, 6., ('nn', [6j, 4j], [6., 4.], [1, 2]), 'NN', True),
+     'cc', ('NN', 6j), [[6., 4.], [6., 4.]], 8),
+    ([4, 3], (7j, 7., ('oo', [7j, 5j], [7., 5.], [2, 1]), 'OO', False),
+     'dd', ('OO', 7j), [[7., 5.], [7., 5.]], 9),
+    ]
+
+record_arrays = [
+    np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')),
+    np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')),
+    np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')),
+    np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')),
+]
+
+
+#BytesIO that reads a random number of bytes at a time
+class BytesIOSRandomSize(BytesIO):
+    def read(self, size=None):
+        import random
+        size = random.randint(1, size)
+        return super(BytesIOSRandomSize, self).read(size)
+
+
+def roundtrip(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    f2 = BytesIO(f.getvalue())
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def roundtrip_randsize(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    f2 = BytesIOSRandomSize(f.getvalue())
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def roundtrip_truncated(arr):
+    f = BytesIO()
+    format.write_array(f, arr)
+    #BytesIO is one byte short
+    f2 = BytesIO(f.getvalue()[0:-1])
+    arr2 = format.read_array(f2)
+    return arr2
+
+
+def assert_equal_(o1, o2):
+    assert_(o1 == o2)
+
+
+def test_roundtrip():
+    for arr in basic_arrays + record_arrays:
+        arr2 = roundtrip(arr)
+        yield assert_array_equal, arr, arr2
+
+
+def test_roundtrip_randsize():
+    for arr in basic_arrays + record_arrays:
+        if arr.dtype != object:
+            arr2 = roundtrip_randsize(arr)
+            yield assert_array_equal, arr, arr2
+
+
+def test_roundtrip_truncated():
+    for arr in basic_arrays:
+        if arr.dtype != object:
+            yield assert_raises, ValueError, roundtrip_truncated, arr
+
+
+def test_long_str():
+    # check items larger than internal buffer size, gh-4027
+    long_str_arr = np.ones(1, dtype=np.dtype((str, format.BUFFER_SIZE + 1)))
+    long_str_arr2 = roundtrip(long_str_arr)
+    assert_array_equal(long_str_arr, long_str_arr2)
+
+
+@dec.slow
+def test_memmap_roundtrip():
+    # Fixme: test crashes nose on windows.
+    if not (sys.platform == 'win32' or sys.platform == 'cygwin'):
+        for arr in basic_arrays + record_arrays:
+            if arr.dtype.hasobject:
+                # Skip these since they can't be mmap'ed.
+                continue
+            # Write it out normally and through mmap.
+            nfn = os.path.join(tempdir, 'normal.npy')
+            mfn = os.path.join(tempdir, 'memmap.npy')
+            fp = open(nfn, 'wb')
+            try:
+                format.write_array(fp, arr)
+            finally:
+                fp.close()
+
+            fortran_order = (
+                arr.flags.f_contiguous and not arr.flags.c_contiguous)
+            ma = format.open_memmap(mfn, mode='w+', dtype=arr.dtype,
+                                    shape=arr.shape, fortran_order=fortran_order)
+            ma[...] = arr
+            del ma
+
+            # Check that both of these files' contents are the same.
+            fp = open(nfn, 'rb')
+            normal_bytes = fp.read()
+            fp.close()
+            fp = open(mfn, 'rb')
+            memmap_bytes = fp.read()
+            fp.close()
+            yield assert_equal_, normal_bytes, memmap_bytes
+
+            # Check that reading the file using memmap works.
+            ma = format.open_memmap(nfn, mode='r')
+            del ma
+
+
+def test_compressed_roundtrip():
+    arr = np.random.rand(200, 200)
+    npz_file = os.path.join(tempdir, 'compressed.npz')
+    np.savez_compressed(npz_file, arr=arr)
+    arr1 = np.load(npz_file)['arr']
+    assert_array_equal(arr, arr1)
+
+
+def test_python2_python3_interoperability():
+    if sys.version_info[0] >= 3:
+        fname = 'win64python2.npy'
+    else:
+        fname = 'python3.npy'
+    path = os.path.join(os.path.dirname(__file__), 'data', fname)
+    data = np.load(path)
+    assert_array_equal(data, np.ones(2))
+
+
+def test_pickle_python2_python3():
+    # Test that loading object arrays saved on Python 2 works both on
+    # Python 2 and Python 3 and vice versa
+    data_dir = os.path.join(os.path.dirname(__file__), 'data')
+
+    if sys.version_info[0] >= 3:
+        xrange = range
+    else:
+        import __builtin__
+        xrange = __builtin__.xrange
+
+    expected = np.array([None, xrange, sixu('\u512a\u826f'),
+                         asbytes('\xe4\xb8\x8d\xe8\x89\xaf')],
+                        dtype=object)
+
+    for fname in ['py2-objarr.npy', 'py2-objarr.npz',
+                  'py3-objarr.npy', 'py3-objarr.npz']:
+        path = os.path.join(data_dir, fname)
+
+        if (fname.endswith('.npz') and sys.version_info[0] == 2 and
+                sys.version_info[1] < 7):
+            # Reading object arrays directly from zipfile appears to fail
+            # on Py2.6, see cfae0143b4
+            continue
+
+        for encoding in ['bytes', 'latin1']:
+            if (sys.version_info[0] >= 3 and sys.version_info[1] < 4 and
+                    encoding == 'bytes'):
+                # The bytes encoding is available starting from Python 3.4
+                continue
+
+            data_f = np.load(path, encoding=encoding)
+            if fname.endswith('.npz'):
+                data = data_f['x']
+                data_f.close()
+            else:
+                data = data_f
+
+            if sys.version_info[0] >= 3:
+                if encoding == 'latin1' and fname.startswith('py2'):
+                    assert_(isinstance(data[3], str))
+                    assert_array_equal(data[:-1], expected[:-1])
+                    # mojibake occurs
+                    assert_array_equal(data[-1].encode(encoding), expected[-1])
+                else:
+                    assert_(isinstance(data[3], bytes))
+                    assert_array_equal(data, expected)
+            else:
+                assert_array_equal(data, expected)
+
+        if sys.version_info[0] >= 3:
+            if fname.startswith('py2'):
+                if fname.endswith('.npz'):
+                    data = np.load(path)
+                    assert_raises(UnicodeError, data.__getitem__, 'x')
+                    data.close()
+                    data = np.load(path, fix_imports=False, encoding='latin1')
+                    assert_raises(ImportError, data.__getitem__, 'x')
+                    data.close()
+                else:
+                    assert_raises(UnicodeError, np.load, path)
+                    assert_raises(ImportError, np.load, path,
+                                  encoding='latin1', fix_imports=False)
+
+
+def test_pickle_disallow():
+    data_dir = os.path.join(os.path.dirname(__file__), 'data')
+
+    path = os.path.join(data_dir, 'py2-objarr.npy')
+    assert_raises(ValueError, np.load, path,
+                  allow_pickle=False, encoding='latin1')
+
+    path = os.path.join(data_dir, 'py2-objarr.npz')
+    f = np.load(path, allow_pickle=False, encoding='latin1')
+    assert_raises(ValueError, f.__getitem__, 'x')
+
+    path = os.path.join(tempdir, 'pickle-disabled.npy')
+    assert_raises(ValueError, np.save, path, np.array([None], dtype=object),
+                  allow_pickle=False)
+
+
+def test_version_2_0():
+    f = BytesIO()
+    # requires more than 2 byte for header
+    dt = [(("%d" % i) * 100, float) for i in range(500)]
+    d = np.ones(1000, dtype=dt)
+
+    format.write_array(f, d, version=(2, 0))
+    with warnings.catch_warnings(record=True) as w:
+        warnings.filterwarnings('always', '', UserWarning)
+        format.write_array(f, d)
+        assert_(w[0].category is UserWarning)
+
+    f.seek(0)
+    n = format.read_array(f)
+    assert_array_equal(d, n)
+
+    # 1.0 requested but data cannot be saved this way
+    assert_raises(ValueError, format.write_array, f, d, (1, 0))
+
+
+def test_version_2_0_memmap():
+    # requires more than 2 byte for header
+    dt = [(("%d" % i) * 100, float) for i in range(500)]
+    d = np.ones(1000, dtype=dt)
+    tf = tempfile.mktemp('', 'mmap', dir=tempdir)
+
+    # 1.0 requested but data cannot be saved this way
+    assert_raises(ValueError, format.open_memmap, tf, mode='w+', dtype=d.dtype,
+                            shape=d.shape, version=(1, 0))
+
+    ma = format.open_memmap(tf, mode='w+', dtype=d.dtype,
+                            shape=d.shape, version=(2, 0))
+    ma[...] = d
+    del ma
+
+    with warnings.catch_warnings(record=True) as w:
+        warnings.filterwarnings('always', '', UserWarning)
+        ma = format.open_memmap(tf, mode='w+', dtype=d.dtype,
+                                shape=d.shape, version=None)
+        assert_(w[0].category is UserWarning)
+        ma[...] = d
+        del ma
+
+    ma = format.open_memmap(tf, mode='r')
+    assert_array_equal(ma, d)
+
+
+def test_write_version():
+    f = BytesIO()
+    arr = np.arange(1)
+    # These should pass.
+    format.write_array(f, arr, version=(1, 0))
+    format.write_array(f, arr)
+
+    format.write_array(f, arr, version=None)
+    format.write_array(f, arr)
+
+    format.write_array(f, arr, version=(2, 0))
+    format.write_array(f, arr)
+
+    # These should all fail.
+    bad_versions = [
+        (1, 1),
+        (0, 0),
+        (0, 1),
+        (2, 2),
+        (255, 255),
+    ]
+    for version in bad_versions:
+        try:
+            format.write_array(f, arr, version=version)
+        except ValueError:
+            pass
+        else:
+            raise AssertionError("we should have raised a ValueError for the bad version %r" % (version,))
+
+
+bad_version_magic = asbytes_nested([
+    '\x93NUMPY\x01\x01',
+    '\x93NUMPY\x00\x00',
+    '\x93NUMPY\x00\x01',
+    '\x93NUMPY\x02\x00',
+    '\x93NUMPY\x02\x02',
+    '\x93NUMPY\xff\xff',
+])
+malformed_magic = asbytes_nested([
+    '\x92NUMPY\x01\x00',
+    '\x00NUMPY\x01\x00',
+    '\x93numpy\x01\x00',
+    '\x93MATLB\x01\x00',
+    '\x93NUMPY\x01',
+    '\x93NUMPY',
+    '',
+])
+
+def test_read_magic():
+    s1 = BytesIO()
+    s2 = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+
+    format.write_array(s1, arr, version=(1, 0))
+    format.write_array(s2, arr, version=(2, 0))
+
+    s1.seek(0)
+    s2.seek(0)
+
+    version1 = format.read_magic(s1)
+    version2 = format.read_magic(s2)
+
+    assert_(version1 == (1, 0))
+    assert_(version2 == (2, 0))
+
+    assert_(s1.tell() == format.MAGIC_LEN)
+    assert_(s2.tell() == format.MAGIC_LEN)
+
+def test_read_magic_bad_magic():
+    for magic in malformed_magic:
+        f = BytesIO(magic)
+        yield raises(ValueError)(format.read_magic), f
+
+
+def test_read_version_1_0_bad_magic():
+    for magic in bad_version_magic + malformed_magic:
+        f = BytesIO(magic)
+        yield raises(ValueError)(format.read_array), f
+
+
+def test_bad_magic_args():
+    assert_raises(ValueError, format.magic, -1, 1)
+    assert_raises(ValueError, format.magic, 256, 1)
+    assert_raises(ValueError, format.magic, 1, -1)
+    assert_raises(ValueError, format.magic, 1, 256)
+
+
+def test_large_header():
+    s = BytesIO()
+    d = {'a': 1, 'b': 2}
+    format.write_array_header_1_0(s, d)
+
+    s = BytesIO()
+    d = {'a': 1, 'b': 2, 'c': 'x'*256*256}
+    assert_raises(ValueError, format.write_array_header_1_0, s, d)
+
+
+def test_read_array_header_1_0():
+    s = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+    format.write_array(s, arr, version=(1, 0))
+
+    s.seek(format.MAGIC_LEN)
+    shape, fortran, dtype = format.read_array_header_1_0(s)
+
+    assert_((shape, fortran, dtype) == ((3, 6), False, float))
+
+
+def test_read_array_header_2_0():
+    s = BytesIO()
+
+    arr = np.ones((3, 6), dtype=float)
+    format.write_array(s, arr, version=(2, 0))
+
+    s.seek(format.MAGIC_LEN)
+    shape, fortran, dtype = format.read_array_header_2_0(s)
+
+    assert_((shape, fortran, dtype) == ((3, 6), False, float))
+
+
+def test_bad_header():
+    # header of length less than 2 should fail
+    s = BytesIO()
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+    s = BytesIO(asbytes('1'))
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    # header shorter than indicated size should fail
+    s = BytesIO(asbytes('\x01\x00'))
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    # headers without the exact keys required should fail
+    d = {"shape": (1, 2),
+         "descr": "x"}
+    s = BytesIO()
+    format.write_array_header_1_0(s, d)
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+    d = {"shape": (1, 2),
+         "fortran_order": False,
+         "descr": "x",
+         "extrakey": -1}
+    s = BytesIO()
+    format.write_array_header_1_0(s, d)
+    assert_raises(ValueError, format.read_array_header_1_0, s)
+
+
+def test_large_file_support():
+    if (sys.platform == 'win32' or sys.platform == 'cygwin'):
+        raise SkipTest("Unknown if Windows has sparse filesystems")
+    # try creating a large sparse file
+    tf_name = os.path.join(tempdir, 'sparse_file')
+    try:
+        # seek past end would work too, but linux truncate somewhat
+        # increases the chances that we have a sparse filesystem and can
+        # avoid actually writing 5GB
+        import subprocess as sp
+        sp.check_call(["truncate", "-s", "5368709120", tf_name])
+    except:
+        raise SkipTest("Could not create 5GB large file")
+    # write a small array to the end
+    with open(tf_name, "wb") as f:
+        f.seek(5368709120)
+        d = np.arange(5)
+        np.save(f, d)
+    # read it back
+    with open(tf_name, "rb") as f:
+        f.seek(5368709120)
+        r = np.load(f)
+    assert_array_equal(r, d)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
new file mode 100644
index 0000000000..ea10cbc761
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
@@ -0,0 +1,2824 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, assert_array_almost_equal, assert_raises,
+    assert_allclose, assert_array_max_ulp, assert_warns,
+    assert_raises_regex, dec, clear_and_catch_warnings
+)
+import numpy.lib.function_base as nfb
+from numpy.random import rand
+from numpy.lib import (
+    add_newdoc_ufunc, angle, average, bartlett, blackman, corrcoef, cov,
+    delete, diff, digitize, extract, flipud, gradient, hamming, hanning,
+    histogram, histogramdd, i0, insert, interp, kaiser, meshgrid, msort,
+    piecewise, place, select, setxor1d, sinc, split, trapz, trim_zeros,
+    unwrap, unique, vectorize,
+)
+
+from numpy.compat import long
+
+
+class TestAny(TestCase):
+
+    def test_basic(self):
+        y1 = [0, 0, 1, 0]
+        y2 = [0, 0, 0, 0]
+        y3 = [1, 0, 1, 0]
+        assert_(np.any(y1))
+        assert_(np.any(y3))
+        assert_(not np.any(y2))
+
+    def test_nd(self):
+        y1 = [[0, 0, 0], [0, 1, 0], [1, 1, 0]]
+        assert_(np.any(y1))
+        assert_array_equal(np.sometrue(y1, axis=0), [1, 1, 0])
+        assert_array_equal(np.sometrue(y1, axis=1), [0, 1, 1])
+
+
+class TestAll(TestCase):
+
+    def test_basic(self):
+        y1 = [0, 1, 1, 0]
+        y2 = [0, 0, 0, 0]
+        y3 = [1, 1, 1, 1]
+        assert_(not np.all(y1))
+        assert_(np.all(y3))
+        assert_(not np.all(y2))
+        assert_(np.all(~np.array(y2)))
+
+    def test_nd(self):
+        y1 = [[0, 0, 1], [0, 1, 1], [1, 1, 1]]
+        assert_(not np.all(y1))
+        assert_array_equal(np.alltrue(y1, axis=0), [0, 0, 1])
+        assert_array_equal(np.alltrue(y1, axis=1), [0, 0, 1])
+
+
+class TestCopy(TestCase):
+
+    def test_basic(self):
+        a = np.array([[1, 2], [3, 4]])
+        a_copy = np.copy(a)
+        assert_array_equal(a, a_copy)
+        a_copy[0, 0] = 10
+        assert_equal(a[0, 0], 1)
+        assert_equal(a_copy[0, 0], 10)
+
+    def test_order(self):
+        # It turns out that people rely on np.copy() preserving order by
+        # default; changing this broke scikit-learn:
+        #   https://github.com/scikit-learn/scikit-learn/commit/7842748cf777412c506a8c0ed28090711d3a3783
+        a = np.array([[1, 2], [3, 4]])
+        assert_(a.flags.c_contiguous)
+        assert_(not a.flags.f_contiguous)
+        a_fort = np.array([[1, 2], [3, 4]], order="F")
+        assert_(not a_fort.flags.c_contiguous)
+        assert_(a_fort.flags.f_contiguous)
+        a_copy = np.copy(a)
+        assert_(a_copy.flags.c_contiguous)
+        assert_(not a_copy.flags.f_contiguous)
+        a_fort_copy = np.copy(a_fort)
+        assert_(not a_fort_copy.flags.c_contiguous)
+        assert_(a_fort_copy.flags.f_contiguous)
+
+
+class TestAverage(TestCase):
+
+    def test_basic(self):
+        y1 = np.array([1, 2, 3])
+        assert_(average(y1, axis=0) == 2.)
+        y2 = np.array([1., 2., 3.])
+        assert_(average(y2, axis=0) == 2.)
+        y3 = [0., 0., 0.]
+        assert_(average(y3, axis=0) == 0.)
+
+        y4 = np.ones((4, 4))
+        y4[0, 1] = 0
+        y4[1, 0] = 2
+        assert_almost_equal(y4.mean(0), average(y4, 0))
+        assert_almost_equal(y4.mean(1), average(y4, 1))
+
+        y5 = rand(5, 5)
+        assert_almost_equal(y5.mean(0), average(y5, 0))
+        assert_almost_equal(y5.mean(1), average(y5, 1))
+
+        y6 = np.matrix(rand(5, 5))
+        assert_array_equal(y6.mean(0), average(y6, 0))
+
+    def test_weights(self):
+        y = np.arange(10)
+        w = np.arange(10)
+        actual = average(y, weights=w)
+        desired = (np.arange(10) ** 2).sum() * 1. / np.arange(10).sum()
+        assert_almost_equal(actual, desired)
+
+        y1 = np.array([[1, 2, 3], [4, 5, 6]])
+        w0 = [1, 2]
+        actual = average(y1, weights=w0, axis=0)
+        desired = np.array([3., 4., 5.])
+        assert_almost_equal(actual, desired)
+
+        w1 = [0, 0, 1]
+        actual = average(y1, weights=w1, axis=1)
+        desired = np.array([3., 6.])
+        assert_almost_equal(actual, desired)
+
+        # This should raise an error. Can we test for that ?
+        # assert_equal(average(y1, weights=w1), 9./2.)
+
+        # 2D Case
+        w2 = [[0, 0, 1], [0, 0, 2]]
+        desired = np.array([3., 6.])
+        assert_array_equal(average(y1, weights=w2, axis=1), desired)
+        assert_equal(average(y1, weights=w2), 5.)
+
+        y3 = rand(5).astype(np.float32)
+        w3 = rand(5).astype(np.float64)
+
+        assert_(np.average(y3, weights=w3).dtype == np.result_type(y3, w3))
+
+    def test_returned(self):
+        y = np.array([[1, 2, 3], [4, 5, 6]])
+
+        # No weights
+        avg, scl = average(y, returned=True)
+        assert_equal(scl, 6.)
+
+        avg, scl = average(y, 0, returned=True)
+        assert_array_equal(scl, np.array([2., 2., 2.]))
+
+        avg, scl = average(y, 1, returned=True)
+        assert_array_equal(scl, np.array([3., 3.]))
+
+        # With weights
+        w0 = [1, 2]
+        avg, scl = average(y, weights=w0, axis=0, returned=True)
+        assert_array_equal(scl, np.array([3., 3., 3.]))
+
+        w1 = [1, 2, 3]
+        avg, scl = average(y, weights=w1, axis=1, returned=True)
+        assert_array_equal(scl, np.array([6., 6.]))
+
+        w2 = [[0, 0, 1], [1, 2, 3]]
+        avg, scl = average(y, weights=w2, axis=1, returned=True)
+        assert_array_equal(scl, np.array([1., 6.]))
+
+
+class TestSelect(TestCase):
+    choices = [np.array([1, 2, 3]),
+               np.array([4, 5, 6]),
+               np.array([7, 8, 9])]
+    conditions = [np.array([False, False, False]),
+                  np.array([False, True, False]),
+                  np.array([False, False, True])]
+
+    def _select(self, cond, values, default=0):
+        output = []
+        for m in range(len(cond)):
+            output += [V[m] for V, C in zip(values, cond) if C[m]] or [default]
+        return output
+
+    def test_basic(self):
+        choices = self.choices
+        conditions = self.conditions
+        assert_array_equal(select(conditions, choices, default=15),
+                           self._select(conditions, choices, default=15))
+
+        assert_equal(len(choices), 3)
+        assert_equal(len(conditions), 3)
+
+    def test_broadcasting(self):
+        conditions = [np.array(True), np.array([False, True, False])]
+        choices = [1, np.arange(12).reshape(4, 3)]
+        assert_array_equal(select(conditions, choices), np.ones((4, 3)))
+        # default can broadcast too:
+        assert_equal(select([True], [0], default=[0]).shape, (1,))
+
+    def test_return_dtype(self):
+        assert_equal(select(self.conditions, self.choices, 1j).dtype,
+                     np.complex_)
+        # But the conditions need to be stronger then the scalar default
+        # if it is scalar.
+        choices = [choice.astype(np.int8) for choice in self.choices]
+        assert_equal(select(self.conditions, choices).dtype, np.int8)
+
+        d = np.array([1, 2, 3, np.nan, 5, 7])
+        m = np.isnan(d)
+        assert_equal(select([m], [d]), [0, 0, 0, np.nan, 0, 0])
+
+    def test_deprecated_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter("always")
+            assert_equal(select([], [], 3j), 3j)
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, select, [], [])
+            warnings.simplefilter("error")
+            assert_raises(DeprecationWarning, select, [], [])
+
+    def test_non_bool_deprecation(self):
+        choices = self.choices
+        conditions = self.conditions[:]
+        with warnings.catch_warnings():
+            warnings.filterwarnings("always")
+            conditions[0] = conditions[0].astype(np.int_)
+            assert_warns(DeprecationWarning, select, conditions, choices)
+            conditions[0] = conditions[0].astype(np.uint8)
+            assert_warns(DeprecationWarning, select, conditions, choices)
+            warnings.filterwarnings("error")
+            assert_raises(DeprecationWarning, select, conditions, choices)
+
+    def test_many_arguments(self):
+        # This used to be limited by NPY_MAXARGS == 32
+        conditions = [np.array([False])] * 100
+        choices = [np.array([1])] * 100
+        select(conditions, choices)
+
+
+class TestInsert(TestCase):
+
+    def test_basic(self):
+        a = [1, 2, 3]
+        assert_equal(insert(a, 0, 1), [1, 1, 2, 3])
+        assert_equal(insert(a, 3, 1), [1, 2, 3, 1])
+        assert_equal(insert(a, [1, 1, 1], [1, 2, 3]), [1, 1, 2, 3, 2, 3])
+        assert_equal(insert(a, 1, [1, 2, 3]), [1, 1, 2, 3, 2, 3])
+        assert_equal(insert(a, [1, -1, 3], 9), [1, 9, 2, 9, 3, 9])
+        assert_equal(insert(a, slice(-1, None, -1), 9), [9, 1, 9, 2, 9, 3])
+        assert_equal(insert(a, [-1, 1, 3], [7, 8, 9]), [1, 8, 2, 7, 3, 9])
+        b = np.array([0, 1], dtype=np.float64)
+        assert_equal(insert(b, 0, b[0]), [0., 0., 1.])
+        assert_equal(insert(b, [], []), b)
+        # Bools will be treated differently in the future:
+        # assert_equal(insert(a, np.array([True]*4), 9), [9, 1, 9, 2, 9, 3, 9])
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', FutureWarning)
+            assert_equal(
+                insert(a, np.array([True] * 4), 9), [1, 9, 9, 9, 9, 2, 3])
+            assert_(w[0].category is FutureWarning)
+
+    def test_multidim(self):
+        a = [[1, 1, 1]]
+        r = [[2, 2, 2],
+             [1, 1, 1]]
+        assert_equal(insert(a, 0, [1]), [1, 1, 1, 1])
+        assert_equal(insert(a, 0, [2, 2, 2], axis=0), r)
+        assert_equal(insert(a, 0, 2, axis=0), r)
+        assert_equal(insert(a, 2, 2, axis=1), [[1, 1, 2, 1]])
+
+        a = np.array([[1, 1], [2, 2], [3, 3]])
+        b = np.arange(1, 4).repeat(3).reshape(3, 3)
+        c = np.concatenate(
+            (a[:, 0:1], np.arange(1, 4).repeat(3).reshape(3, 3).T,
+             a[:, 1:2]), axis=1)
+        assert_equal(insert(a, [1], [[1], [2], [3]], axis=1), b)
+        assert_equal(insert(a, [1], [1, 2, 3], axis=1), c)
+        # scalars behave differently, in this case exactly opposite:
+        assert_equal(insert(a, 1, [1, 2, 3], axis=1), b)
+        assert_equal(insert(a, 1, [[1], [2], [3]], axis=1), c)
+
+        a = np.arange(4).reshape(2, 2)
+        assert_equal(insert(a[:, :1], 1, a[:, 1], axis=1), a)
+        assert_equal(insert(a[:1,:], 1, a[1,:], axis=0), a)
+
+        # negative axis value
+        a = np.arange(24).reshape((2, 3, 4))
+        assert_equal(insert(a, 1, a[:,:, 3], axis=-1),
+                     insert(a, 1, a[:,:, 3], axis=2))
+        assert_equal(insert(a, 1, a[:, 2,:], axis=-2),
+                     insert(a, 1, a[:, 2,:], axis=1))
+
+        # invalid axis value
+        assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=3)
+        assert_raises(IndexError, insert, a, 1, a[:, 2, :], axis=-4)
+
+        # negative axis value
+        a = np.arange(24).reshape((2, 3, 4))
+        assert_equal(insert(a, 1, a[:, :, 3], axis=-1),
+                     insert(a, 1, a[:, :, 3], axis=2))
+        assert_equal(insert(a, 1, a[:, 2, :], axis=-2),
+                     insert(a, 1, a[:, 2, :], axis=1))
+
+    def test_0d(self):
+        # This is an error in the future
+        a = np.array(1)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', DeprecationWarning)
+            assert_equal(insert(a, [], 2, axis=0), np.array(2))
+            assert_(w[0].category is DeprecationWarning)
+
+    def test_subclass(self):
+        class SubClass(np.ndarray):
+            pass
+        a = np.arange(10).view(SubClass)
+        assert_(isinstance(np.insert(a, 0, [0]), SubClass))
+        assert_(isinstance(np.insert(a, [], []), SubClass))
+        assert_(isinstance(np.insert(a, [0, 1], [1, 2]), SubClass))
+        assert_(isinstance(np.insert(a, slice(1, 2), [1, 2]), SubClass))
+        assert_(isinstance(np.insert(a, slice(1, -2, -1), []), SubClass))
+        # This is an error in the future:
+        a = np.array(1).view(SubClass)
+        assert_(isinstance(np.insert(a, 0, [0]), SubClass))
+
+    def test_index_array_copied(self):
+        x = np.array([1, 1, 1])
+        np.insert([0, 1, 2], x, [3, 4, 5])
+        assert_equal(x, np.array([1, 1, 1]))
+
+    def test_structured_array(self):
+        a = np.array([(1, 'a'), (2, 'b'), (3, 'c')],
+                     dtype=[('foo', 'i'), ('bar', 'a1')])
+        val = (4, 'd')
+        b = np.insert(a, 0, val)
+        assert_array_equal(b[0], np.array(val, dtype=b.dtype))
+        val = [(4, 'd')] * 2
+        b = np.insert(a, [0, 2], val)
+        assert_array_equal(b[[0, 3]], np.array(val, dtype=b.dtype))
+
+
+class TestAmax(TestCase):
+
+    def test_basic(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.amax(a), 10.0)
+        b = [[3, 6.0, 9.0],
+             [4, 10.0, 5.0],
+             [8, 3.0, 2.0]]
+        assert_equal(np.amax(b, axis=0), [8.0, 10.0, 9.0])
+        assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
+
+
+class TestAmin(TestCase):
+
+    def test_basic(self):
+        a = [3, 4, 5, 10, -3, -5, 6.0]
+        assert_equal(np.amin(a), -5.0)
+        b = [[3, 6.0, 9.0],
+             [4, 10.0, 5.0],
+             [8, 3.0, 2.0]]
+        assert_equal(np.amin(b, axis=0), [3.0, 3.0, 2.0])
+        assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
+
+
+class TestPtp(TestCase):
+
+    def test_basic(self):
+        a = np.array([3, 4, 5, 10, -3, -5, 6.0])
+        assert_equal(a.ptp(axis=0), 15.0)
+        b = np.array([[3, 6.0, 9.0],
+                      [4, 10.0, 5.0],
+                      [8, 3.0, 2.0]])
+        assert_equal(b.ptp(axis=0), [5.0, 7.0, 7.0])
+        assert_equal(b.ptp(axis=-1), [6.0, 6.0, 6.0])
+
+
+class TestCumsum(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int8, np.uint8, np.int16, np.uint16, np.int32,
+                      np.uint32, np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+
+            tgt = np.array([1, 3, 13, 24, 30, 35, 39], ctype)
+            assert_array_equal(np.cumsum(a, axis=0), tgt)
+
+            tgt = np.array(
+                [[1, 2, 3, 4], [6, 8, 10, 13], [16, 11, 14, 18]], ctype)
+            assert_array_equal(np.cumsum(a2, axis=0), tgt)
+
+            tgt = np.array(
+                [[1, 3, 6, 10], [5, 11, 18, 27], [10, 13, 17, 22]], ctype)
+            assert_array_equal(np.cumsum(a2, axis=1), tgt)
+
+
+class TestProd(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, np.prod, a)
+                self.assertRaises(ArithmeticError, np.prod, a2, 1)
+            else:
+                assert_equal(a.prod(axis=0), 26400)
+                assert_array_equal(a2.prod(axis=0),
+                                   np.array([50, 36, 84, 180], ctype))
+                assert_array_equal(a2.prod(axis=-1),
+                                   np.array([24, 1890, 600], ctype))
+
+
+class TestCumprod(TestCase):
+
+    def test_basic(self):
+        ba = [1, 2, 10, 11, 6, 5, 4]
+        ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
+        for ctype in [np.int16, np.uint16, np.int32, np.uint32,
+                      np.float32, np.float64, np.complex64, np.complex128]:
+            a = np.array(ba, ctype)
+            a2 = np.array(ba2, ctype)
+            if ctype in ['1', 'b']:
+                self.assertRaises(ArithmeticError, np.cumprod, a)
+                self.assertRaises(ArithmeticError, np.cumprod, a2, 1)
+                self.assertRaises(ArithmeticError, np.cumprod, a)
+            else:
+                assert_array_equal(np.cumprod(a, axis=-1),
+                                   np.array([1, 2, 20, 220,
+                                             1320, 6600, 26400], ctype))
+                assert_array_equal(np.cumprod(a2, axis=0),
+                                   np.array([[1, 2, 3, 4],
+                                             [5, 12, 21, 36],
+                                             [50, 36, 84, 180]], ctype))
+                assert_array_equal(np.cumprod(a2, axis=-1),
+                                   np.array([[1, 2, 6, 24],
+                                             [5, 30, 210, 1890],
+                                             [10, 30, 120, 600]], ctype))
+
+
+class TestDiff(TestCase):
+
+    def test_basic(self):
+        x = [1, 4, 6, 7, 12]
+        out = np.array([3, 2, 1, 5])
+        out2 = np.array([-1, -1, 4])
+        out3 = np.array([0, 5])
+        assert_array_equal(diff(x), out)
+        assert_array_equal(diff(x, n=2), out2)
+        assert_array_equal(diff(x, n=3), out3)
+
+    def test_nd(self):
+        x = 20 * rand(10, 20, 30)
+        out1 = x[:, :, 1:] - x[:, :, :-1]
+        out2 = out1[:, :, 1:] - out1[:, :, :-1]
+        out3 = x[1:, :, :] - x[:-1, :, :]
+        out4 = out3[1:, :, :] - out3[:-1, :, :]
+        assert_array_equal(diff(x), out1)
+        assert_array_equal(diff(x, n=2), out2)
+        assert_array_equal(diff(x, axis=0), out3)
+        assert_array_equal(diff(x, n=2, axis=0), out4)
+
+
+class TestDelete(TestCase):
+
+    def setUp(self):
+        self.a = np.arange(5)
+        self.nd_a = np.arange(5).repeat(2).reshape(1, 5, 2)
+
+    def _check_inverse_of_slicing(self, indices):
+        a_del = delete(self.a, indices)
+        nd_a_del = delete(self.nd_a, indices, axis=1)
+        msg = 'Delete failed for obj: %r' % indices
+        # NOTE: The cast should be removed after warning phase for bools
+        if not isinstance(indices, (slice, int, long, np.integer)):
+            indices = np.asarray(indices, dtype=np.intp)
+            indices = indices[(indices >= 0) & (indices < 5)]
+        assert_array_equal(setxor1d(a_del, self.a[indices, ]), self.a,
+                           err_msg=msg)
+        xor = setxor1d(nd_a_del[0,:, 0], self.nd_a[0, indices, 0])
+        assert_array_equal(xor, self.nd_a[0,:, 0], err_msg=msg)
+
+    def test_slices(self):
+        lims = [-6, -2, 0, 1, 2, 4, 5]
+        steps = [-3, -1, 1, 3]
+        for start in lims:
+            for stop in lims:
+                for step in steps:
+                    s = slice(start, stop, step)
+                    self._check_inverse_of_slicing(s)
+
+    def test_fancy(self):
+        # Deprecation/FutureWarning tests should be kept after change.
+        self._check_inverse_of_slicing(np.array([[0, 1], [2, 1]]))
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', category=DeprecationWarning)
+            assert_raises(DeprecationWarning, delete, self.a, [100])
+            assert_raises(DeprecationWarning, delete, self.a, [-100])
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', category=FutureWarning)
+            self._check_inverse_of_slicing([0, -1, 2, 2])
+            obj = np.array([True, False, False], dtype=bool)
+            self._check_inverse_of_slicing(obj)
+            assert_(w[0].category is FutureWarning)
+            assert_(w[1].category is FutureWarning)
+
+    def test_single(self):
+        self._check_inverse_of_slicing(0)
+        self._check_inverse_of_slicing(-4)
+
+    def test_0d(self):
+        a = np.array(1)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', DeprecationWarning)
+            assert_equal(delete(a, [], axis=0), a)
+            assert_(w[0].category is DeprecationWarning)
+
+    def test_subclass(self):
+        class SubClass(np.ndarray):
+            pass
+        a = self.a.view(SubClass)
+        assert_(isinstance(delete(a, 0), SubClass))
+        assert_(isinstance(delete(a, []), SubClass))
+        assert_(isinstance(delete(a, [0, 1]), SubClass))
+        assert_(isinstance(delete(a, slice(1, 2)), SubClass))
+        assert_(isinstance(delete(a, slice(1, -2)), SubClass))
+
+
+class TestGradient(TestCase):
+
+    def test_basic(self):
+        v = [[1, 1], [3, 4]]
+        x = np.array(v)
+        dx = [np.array([[2., 3.], [2., 3.]]),
+              np.array([[0., 0.], [1., 1.]])]
+        assert_array_equal(gradient(x), dx)
+        assert_array_equal(gradient(v), dx)
+
+    def test_badargs(self):
+        # for 2D array, gradient can take 0, 1, or 2 extra args
+        x = np.array([[1, 1], [3, 4]])
+        assert_raises(SyntaxError, gradient, x, np.array([1., 1.]),
+                      np.array([1., 1.]), np.array([1., 1.]))
+
+    def test_masked(self):
+        # Make sure that gradient supports subclasses like masked arrays
+        x = np.ma.array([[1, 1], [3, 4]],
+                        mask=[[False, False], [False, False]])
+        out = gradient(x)[0]
+        assert_equal(type(out), type(x))
+        # And make sure that the output and input don't have aliased mask
+        # arrays
+        assert_(x.mask is not out.mask)
+        # Also check that edge_order=2 doesn't alter the original mask
+        x2 = np.ma.arange(5)
+        x2[2] = np.ma.masked
+        np.gradient(x2, edge_order=2)
+        assert_array_equal(x2.mask, [False, False, True, False, False])
+
+    def test_datetime64(self):
+        # Make sure gradient() can handle special types like datetime64
+        x = np.array(
+            ['1910-08-16', '1910-08-11', '1910-08-10', '1910-08-12',
+             '1910-10-12', '1910-12-12', '1912-12-12'],
+            dtype='datetime64[D]')
+        dx = np.array(
+            [-5, -3, 0, 31, 61, 396, 731],
+            dtype='timedelta64[D]')
+        assert_array_equal(gradient(x), dx)
+        assert_(dx.dtype == np.dtype('timedelta64[D]'))
+
+    def test_timedelta64(self):
+        # Make sure gradient() can handle special types like timedelta64
+        x = np.array(
+            [-5, -3, 10, 12, 61, 321, 300],
+            dtype='timedelta64[D]')
+        dx = np.array(
+            [2, 7, 7, 25, 154, 119, -21],
+            dtype='timedelta64[D]')
+        assert_array_equal(gradient(x), dx)
+        assert_(dx.dtype == np.dtype('timedelta64[D]'))
+
+    def test_second_order_accurate(self):
+        # Testing that the relative numerical error is less that 3% for
+        # this example problem. This corresponds to second order
+        # accurate finite differences for all interior and boundary
+        # points.
+        x = np.linspace(0, 1, 10)
+        dx = x[1] - x[0]
+        y = 2 * x ** 3 + 4 * x ** 2 + 2 * x
+        analytical = 6 * x ** 2 + 8 * x + 2
+        num_error = np.abs((np.gradient(y, dx, edge_order=2) / analytical) - 1)
+        assert_(np.all(num_error < 0.03) == True)
+
+    def test_specific_axes(self):
+        # Testing that gradient can work on a given axis only
+        v = [[1, 1], [3, 4]]
+        x = np.array(v)
+        dx = [np.array([[2., 3.], [2., 3.]]),
+              np.array([[0., 0.], [1., 1.]])]
+        assert_array_equal(gradient(x, axis=0), dx[0])
+        assert_array_equal(gradient(x, axis=1), dx[1])
+        assert_array_equal(gradient(x, axis=-1), dx[1])
+        assert_array_equal(gradient(x, axis=(1, 0)), [dx[1], dx[0]])
+
+        # test axis=None which means all axes
+        assert_almost_equal(gradient(x, axis=None), [dx[0], dx[1]])
+        # and is the same as no axis keyword given
+        assert_almost_equal(gradient(x, axis=None), gradient(x))
+
+        # test vararg order
+        assert_array_equal(gradient(x, 2, 3, axis=(1, 0)), [dx[1]/2.0, dx[0]/3.0])
+        # test maximal number of varargs
+        assert_raises(SyntaxError, gradient, x, 1, 2, axis=1)
+
+        assert_raises(ValueError, gradient, x, axis=3)
+        assert_raises(ValueError, gradient, x, axis=-3)
+        assert_raises(TypeError, gradient, x, axis=[1,])
+
+
+class TestAngle(TestCase):
+
+    def test_basic(self):
+        x = [1 + 3j, np.sqrt(2) / 2.0 + 1j * np.sqrt(2) / 2,
+             1, 1j, -1, -1j, 1 - 3j, -1 + 3j]
+        y = angle(x)
+        yo = [
+            np.arctan(3.0 / 1.0),
+            np.arctan(1.0), 0, np.pi / 2, np.pi, -np.pi / 2.0,
+            -np.arctan(3.0 / 1.0), np.pi - np.arctan(3.0 / 1.0)]
+        z = angle(x, deg=1)
+        zo = np.array(yo) * 180 / np.pi
+        assert_array_almost_equal(y, yo, 11)
+        assert_array_almost_equal(z, zo, 11)
+
+
+class TestTrimZeros(TestCase):
+
+    """
+    Only testing for integer splits.
+
+    """
+
+    def test_basic(self):
+        a = np.array([0, 0, 1, 2, 3, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 2, 3, 4]))
+
+    def test_leading_skip(self):
+        a = np.array([0, 0, 1, 0, 2, 3, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 0, 2, 3, 4]))
+
+    def test_trailing_skip(self):
+        a = np.array([0, 0, 1, 0, 2, 3, 0, 4, 0])
+        res = trim_zeros(a)
+        assert_array_equal(res, np.array([1, 0, 2, 3, 0, 4]))
+
+
+class TestExtins(TestCase):
+
+    def test_basic(self):
+        a = np.array([1, 3, 2, 1, 2, 3, 3])
+        b = extract(a > 1, a)
+        assert_array_equal(b, [3, 2, 2, 3, 3])
+
+    def test_place(self):
+        # Make sure that non-np.ndarray objects
+        # raise an error instead of doing nothing
+        assert_raises(TypeError, place, [1, 2, 3], [True, False], [0, 1])
+
+        a = np.array([1, 4, 3, 2, 5, 8, 7])
+        place(a, [0, 1, 0, 1, 0, 1, 0], [2, 4, 6])
+        assert_array_equal(a, [1, 2, 3, 4, 5, 6, 7])
+
+        place(a, np.zeros(7), [])
+        assert_array_equal(a, np.arange(1, 8))
+
+        place(a, [1, 0, 1, 0, 1, 0, 1], [8, 9])
+        assert_array_equal(a, [8, 2, 9, 4, 8, 6, 9])
+        assert_raises_regex(ValueError, "Cannot insert from an empty array",
+                            lambda: place(a, [0, 0, 0, 0, 0, 1, 0], []))
+
+    def test_both(self):
+        a = rand(10)
+        mask = a > 0.5
+        ac = a.copy()
+        c = extract(mask, a)
+        place(a, mask, 0)
+        place(a, mask, c)
+        assert_array_equal(a, ac)
+
+
+class TestVectorize(TestCase):
+
+    def test_simple(self):
+        def addsubtract(a, b):
+            if a > b:
+                return a - b
+            else:
+                return a + b
+
+        f = vectorize(addsubtract)
+        r = f([0, 3, 6, 9], [1, 3, 5, 7])
+        assert_array_equal(r, [1, 6, 1, 2])
+
+    def test_scalar(self):
+        def addsubtract(a, b):
+            if a > b:
+                return a - b
+            else:
+                return a + b
+
+        f = vectorize(addsubtract)
+        r = f([0, 3, 6, 9], 5)
+        assert_array_equal(r, [5, 8, 1, 4])
+
+    def test_large(self):
+        x = np.linspace(-3, 2, 10000)
+        f = vectorize(lambda x: x)
+        y = f(x)
+        assert_array_equal(y, x)
+
+    def test_ufunc(self):
+        import math
+        f = vectorize(math.cos)
+        args = np.array([0, 0.5 * np.pi, np.pi, 1.5 * np.pi, 2 * np.pi])
+        r1 = f(args)
+        r2 = np.cos(args)
+        assert_array_almost_equal(r1, r2)
+
+    def test_keywords(self):
+
+        def foo(a, b=1):
+            return a + b
+
+        f = vectorize(foo)
+        args = np.array([1, 2, 3])
+        r1 = f(args)
+        r2 = np.array([2, 3, 4])
+        assert_array_equal(r1, r2)
+        r1 = f(args, 2)
+        r2 = np.array([3, 4, 5])
+        assert_array_equal(r1, r2)
+
+    def test_keywords_no_func_code(self):
+        # This needs to test a function that has keywords but
+        # no func_code attribute, since otherwise vectorize will
+        # inspect the func_code.
+        import random
+        try:
+            vectorize(random.randrange)  # Should succeed
+        except:
+            raise AssertionError()
+
+    def test_keywords2_ticket_2100(self):
+        # Test kwarg support: enhancement ticket 2100
+
+        def foo(a, b=1):
+            return a + b
+
+        f = vectorize(foo)
+        args = np.array([1, 2, 3])
+        r1 = f(a=args)
+        r2 = np.array([2, 3, 4])
+        assert_array_equal(r1, r2)
+        r1 = f(b=1, a=args)
+        assert_array_equal(r1, r2)
+        r1 = f(args, b=2)
+        r2 = np.array([3, 4, 5])
+        assert_array_equal(r1, r2)
+
+    def test_keywords3_ticket_2100(self):
+        # Test excluded with mixed positional and kwargs: ticket 2100
+        def mypolyval(x, p):
+            _p = list(p)
+            res = _p.pop(0)
+            while _p:
+                res = res * x + _p.pop(0)
+            return res
+
+        vpolyval = np.vectorize(mypolyval, excluded=['p', 1])
+        ans = [3, 6]
+        assert_array_equal(ans, vpolyval(x=[0, 1], p=[1, 2, 3]))
+        assert_array_equal(ans, vpolyval([0, 1], p=[1, 2, 3]))
+        assert_array_equal(ans, vpolyval([0, 1], [1, 2, 3]))
+
+    def test_keywords4_ticket_2100(self):
+        # Test vectorizing function with no positional args.
+        @vectorize
+        def f(**kw):
+            res = 1.0
+            for _k in kw:
+                res *= kw[_k]
+            return res
+
+        assert_array_equal(f(a=[1, 2], b=[3, 4]), [3, 8])
+
+    def test_keywords5_ticket_2100(self):
+        # Test vectorizing function with no kwargs args.
+        @vectorize
+        def f(*v):
+            return np.prod(v)
+
+        assert_array_equal(f([1, 2], [3, 4]), [3, 8])
+
+    def test_coverage1_ticket_2100(self):
+        def foo():
+            return 1
+
+        f = vectorize(foo)
+        assert_array_equal(f(), 1)
+
+    def test_assigning_docstring(self):
+        def foo(x):
+            return x
+
+        doc = "Provided documentation"
+        f = vectorize(foo, doc=doc)
+        assert_equal(f.__doc__, doc)
+
+    def test_UnboundMethod_ticket_1156(self):
+        # Regression test for issue 1156
+        class Foo:
+            b = 2
+
+            def bar(self, a):
+                return a ** self.b
+
+        assert_array_equal(vectorize(Foo().bar)(np.arange(9)),
+                           np.arange(9) ** 2)
+        assert_array_equal(vectorize(Foo.bar)(Foo(), np.arange(9)),
+                           np.arange(9) ** 2)
+
+    def test_execution_order_ticket_1487(self):
+        # Regression test for dependence on execution order: issue 1487
+        f1 = vectorize(lambda x: x)
+        res1a = f1(np.arange(3))
+        res1b = f1(np.arange(0.1, 3))
+        f2 = vectorize(lambda x: x)
+        res2b = f2(np.arange(0.1, 3))
+        res2a = f2(np.arange(3))
+        assert_equal(res1a, res2a)
+        assert_equal(res1b, res2b)
+
+    def test_string_ticket_1892(self):
+        # Test vectorization over strings: issue 1892.
+        f = np.vectorize(lambda x: x)
+        s = '0123456789' * 10
+        assert_equal(s, f(s))
+
+    def test_cache(self):
+        # Ensure that vectorized func called exactly once per argument.
+        _calls = [0]
+
+        @vectorize
+        def f(x):
+            _calls[0] += 1
+            return x ** 2
+
+        f.cache = True
+        x = np.arange(5)
+        assert_array_equal(f(x), x * x)
+        assert_equal(_calls[0], len(x))
+
+    def test_otypes(self):
+        f = np.vectorize(lambda x: x)
+        f.otypes = 'i'
+        x = np.arange(5)
+        assert_array_equal(f(x), x)
+
+
+class TestDigitize(TestCase):
+
+    def test_forward(self):
+        x = np.arange(-6, 5)
+        bins = np.arange(-5, 5)
+        assert_array_equal(digitize(x, bins), np.arange(11))
+
+    def test_reverse(self):
+        x = np.arange(5, -6, -1)
+        bins = np.arange(5, -5, -1)
+        assert_array_equal(digitize(x, bins), np.arange(11))
+
+    def test_random(self):
+        x = rand(10)
+        bin = np.linspace(x.min(), x.max(), 10)
+        assert_(np.all(digitize(x, bin) != 0))
+
+    def test_right_basic(self):
+        x = [1, 5, 4, 10, 8, 11, 0]
+        bins = [1, 5, 10]
+        default_answer = [1, 2, 1, 3, 2, 3, 0]
+        assert_array_equal(digitize(x, bins), default_answer)
+        right_answer = [0, 1, 1, 2, 2, 3, 0]
+        assert_array_equal(digitize(x, bins, True), right_answer)
+
+    def test_right_open(self):
+        x = np.arange(-6, 5)
+        bins = np.arange(-6, 4)
+        assert_array_equal(digitize(x, bins, True), np.arange(11))
+
+    def test_right_open_reverse(self):
+        x = np.arange(5, -6, -1)
+        bins = np.arange(4, -6, -1)
+        assert_array_equal(digitize(x, bins, True), np.arange(11))
+
+    def test_right_open_random(self):
+        x = rand(10)
+        bins = np.linspace(x.min(), x.max(), 10)
+        assert_(np.all(digitize(x, bins, True) != 10))
+
+    def test_monotonic(self):
+        x = [-1, 0, 1, 2]
+        bins = [0, 0, 1]
+        assert_array_equal(digitize(x, bins, False), [0, 2, 3, 3])
+        assert_array_equal(digitize(x, bins, True), [0, 0, 2, 3])
+        bins = [1, 1, 0]
+        assert_array_equal(digitize(x, bins, False), [3, 2, 0, 0])
+        assert_array_equal(digitize(x, bins, True), [3, 3, 2, 0])
+        bins = [1, 1, 1, 1]
+        assert_array_equal(digitize(x, bins, False), [0, 0, 4, 4])
+        assert_array_equal(digitize(x, bins, True), [0, 0, 0, 4])
+        bins = [0, 0, 1, 0]
+        assert_raises(ValueError, digitize, x, bins)
+        bins = [1, 1, 0, 1]
+        assert_raises(ValueError, digitize, x, bins)
+
+    def test_casting_error(self):
+        x = [1, 2, 3 + 1.j]
+        bins = [1, 2, 3]
+        assert_raises(TypeError, digitize, x, bins)
+        x, bins = bins, x
+        assert_raises(TypeError, digitize, x, bins)
+
+    def test_return_type(self):
+        # Functions returning indices should always return base ndarrays
+        class A(np.ndarray):
+            pass
+        a = np.arange(5).view(A)
+        b = np.arange(1, 3).view(A)
+        assert_(not isinstance(digitize(b, a, False), A))
+        assert_(not isinstance(digitize(b, a, True), A))
+
+
+class TestUnwrap(TestCase):
+
+    def test_simple(self):
+        # check that unwrap removes jumps greather that 2*pi
+        assert_array_equal(unwrap([1, 1 + 2 * np.pi]), [1, 1])
+        # check that unwrap maintans continuity
+        assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi))
+
+
+class TestFilterwindows(TestCase):
+
+    def test_hanning(self):
+        # check symmetry
+        w = hanning(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.500, 4)
+
+    def test_hamming(self):
+        # check symmetry
+        w = hamming(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.9400, 4)
+
+    def test_bartlett(self):
+        # check symmetry
+        w = bartlett(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 4.4444, 4)
+
+    def test_blackman(self):
+        # check symmetry
+        w = blackman(10)
+        assert_array_almost_equal(w, flipud(w), 7)
+        # check known value
+        assert_almost_equal(np.sum(w, axis=0), 3.7800, 4)
+
+
+class TestTrapz(TestCase):
+
+    def test_simple(self):
+        x = np.arange(-10, 10, .1)
+        r = trapz(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1)
+        # check integral of normal equals 1
+        assert_almost_equal(r, 1, 7)
+
+    def test_ndim(self):
+        x = np.linspace(0, 1, 3)
+        y = np.linspace(0, 2, 8)
+        z = np.linspace(0, 3, 13)
+
+        wx = np.ones_like(x) * (x[1] - x[0])
+        wx[0] /= 2
+        wx[-1] /= 2
+        wy = np.ones_like(y) * (y[1] - y[0])
+        wy[0] /= 2
+        wy[-1] /= 2
+        wz = np.ones_like(z) * (z[1] - z[0])
+        wz[0] /= 2
+        wz[-1] /= 2
+
+        q = x[:, None, None] + y[None,:, None] + z[None, None,:]
+
+        qx = (q * wx[:, None, None]).sum(axis=0)
+        qy = (q * wy[None, :, None]).sum(axis=1)
+        qz = (q * wz[None, None, :]).sum(axis=2)
+
+        # n-d `x`
+        r = trapz(q, x=x[:, None, None], axis=0)
+        assert_almost_equal(r, qx)
+        r = trapz(q, x=y[None,:, None], axis=1)
+        assert_almost_equal(r, qy)
+        r = trapz(q, x=z[None, None,:], axis=2)
+        assert_almost_equal(r, qz)
+
+        # 1-d `x`
+        r = trapz(q, x=x, axis=0)
+        assert_almost_equal(r, qx)
+        r = trapz(q, x=y, axis=1)
+        assert_almost_equal(r, qy)
+        r = trapz(q, x=z, axis=2)
+        assert_almost_equal(r, qz)
+
+    def test_masked(self):
+        # Testing that masked arrays behave as if the function is 0 where
+        # masked
+        x = np.arange(5)
+        y = x * x
+        mask = x == 2
+        ym = np.ma.array(y, mask=mask)
+        r = 13.0  # sum(0.5 * (0 + 1) * 1.0 + 0.5 * (9 + 16))
+        assert_almost_equal(trapz(ym, x), r)
+
+        xm = np.ma.array(x, mask=mask)
+        assert_almost_equal(trapz(ym, xm), r)
+
+        xm = np.ma.array(x, mask=mask)
+        assert_almost_equal(trapz(y, xm), r)
+
+    def test_matrix(self):
+        # Test to make sure matrices give the same answer as ndarrays
+        x = np.linspace(0, 5)
+        y = x * x
+        r = trapz(y, x)
+        mx = np.matrix(x)
+        my = np.matrix(y)
+        mr = trapz(my, mx)
+        assert_almost_equal(mr, r)
+
+
+class TestSinc(TestCase):
+
+    def test_simple(self):
+        assert_(sinc(0) == 1)
+        w = sinc(np.linspace(-1, 1, 100))
+        # check symmetry
+        assert_array_almost_equal(w, flipud(w), 7)
+
+    def test_array_like(self):
+        x = [0, 0.5]
+        y1 = sinc(np.array(x))
+        y2 = sinc(list(x))
+        y3 = sinc(tuple(x))
+        assert_array_equal(y1, y2)
+        assert_array_equal(y1, y3)
+
+
+class TestHistogram(TestCase):
+
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def test_simple(self):
+        n = 100
+        v = rand(n)
+        (a, b) = histogram(v)
+        # check if the sum of the bins equals the number of samples
+        assert_equal(np.sum(a, axis=0), n)
+        # check that the bin counts are evenly spaced when the data is from
+        # a linear function
+        (a, b) = histogram(np.linspace(0, 10, 100))
+        assert_array_equal(a, 10)
+
+    def test_one_bin(self):
+        # Ticket 632
+        hist, edges = histogram([1, 2, 3, 4], [1, 2])
+        assert_array_equal(hist, [2, ])
+        assert_array_equal(edges, [1, 2])
+        assert_raises(ValueError, histogram, [1, 2], bins=0)
+        h, e = histogram([1, 2], bins=1)
+        assert_equal(h, np.array([2]))
+        assert_allclose(e, np.array([1., 2.]))
+
+    def test_normed(self):
+        # Check that the integral of the density equals 1.
+        n = 100
+        v = rand(n)
+        a, b = histogram(v, normed=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+        # Check with non-constant bin widths (buggy but backwards
+        # compatible)
+        v = np.arange(10)
+        bins = [0, 1, 5, 9, 10]
+        a, b = histogram(v, bins, normed=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+    def test_density(self):
+        # Check that the integral of the density equals 1.
+        n = 100
+        v = rand(n)
+        a, b = histogram(v, density=True)
+        area = np.sum(a * diff(b))
+        assert_almost_equal(area, 1)
+
+        # Check with non-constant bin widths
+        v = np.arange(10)
+        bins = [0, 1, 3, 6, 10]
+        a, b = histogram(v, bins, density=True)
+        assert_array_equal(a, .1)
+        assert_equal(np.sum(a * diff(b)), 1)
+
+        # Variale bin widths are especially useful to deal with
+        # infinities.
+        v = np.arange(10)
+        bins = [0, 1, 3, 6, np.inf]
+        a, b = histogram(v, bins, density=True)
+        assert_array_equal(a, [.1, .1, .1, 0.])
+
+        # Taken from a bug report from N. Becker on the numpy-discussion
+        # mailing list Aug. 6, 2010.
+        counts, dmy = np.histogram(
+            [1, 2, 3, 4], [0.5, 1.5, np.inf], density=True)
+        assert_equal(counts, [.25, 0])
+
+    def test_outliers(self):
+        # Check that outliers are not tallied
+        a = np.arange(10) + .5
+
+        # Lower outliers
+        h, b = histogram(a, range=[0, 9])
+        assert_equal(h.sum(), 9)
+
+        # Upper outliers
+        h, b = histogram(a, range=[1, 10])
+        assert_equal(h.sum(), 9)
+
+        # Normalization
+        h, b = histogram(a, range=[1, 9], normed=True)
+        assert_almost_equal((h * diff(b)).sum(), 1, decimal=15)
+
+        # Weights
+        w = np.arange(10) + .5
+        h, b = histogram(a, range=[1, 9], weights=w, normed=True)
+        assert_equal((h * diff(b)).sum(), 1)
+
+        h, b = histogram(a, bins=8, range=[1, 9], weights=w)
+        assert_equal(h, w[1:-1])
+
+    def test_type(self):
+        # Check the type of the returned histogram
+        a = np.arange(10) + .5
+        h, b = histogram(a)
+        assert_(np.issubdtype(h.dtype, int))
+
+        h, b = histogram(a, normed=True)
+        assert_(np.issubdtype(h.dtype, float))
+
+        h, b = histogram(a, weights=np.ones(10, int))
+        assert_(np.issubdtype(h.dtype, int))
+
+        h, b = histogram(a, weights=np.ones(10, float))
+        assert_(np.issubdtype(h.dtype, float))
+
+    def test_f32_rounding(self):
+        # gh-4799, check that the rounding of the edges works with float32
+        x = np.array([276.318359, -69.593948, 21.329449], dtype=np.float32)
+        y = np.array([5005.689453, 4481.327637, 6010.369629], dtype=np.float32)
+        counts_hist, xedges, yedges = np.histogram2d(x, y, bins=100)
+        assert_equal(counts_hist.sum(), 3.)
+
+    def test_weights(self):
+        v = rand(100)
+        w = np.ones(100) * 5
+        a, b = histogram(v)
+        na, nb = histogram(v, normed=True)
+        wa, wb = histogram(v, weights=w)
+        nwa, nwb = histogram(v, weights=w, normed=True)
+        assert_array_almost_equal(a * 5, wa)
+        assert_array_almost_equal(na, nwa)
+
+        # Check weights are properly applied.
+        v = np.linspace(0, 10, 10)
+        w = np.concatenate((np.zeros(5), np.ones(5)))
+        wa, wb = histogram(v, bins=np.arange(11), weights=w)
+        assert_array_almost_equal(wa, w)
+
+        # Check with integer weights
+        wa, wb = histogram([1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1])
+        assert_array_equal(wa, [4, 5, 0, 1])
+        wa, wb = histogram(
+            [1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1], normed=True)
+        assert_array_almost_equal(wa, np.array([4, 5, 0, 1]) / 10. / 3. * 4)
+
+        # Check weights with non-uniform bin widths
+        a, b = histogram(
+            np.arange(9), [0, 1, 3, 6, 10],
+            weights=[2, 1, 1, 1, 1, 1, 1, 1, 1], density=True)
+        assert_almost_equal(a, [.2, .1, .1, .075])
+
+    def test_exotic_weights(self):
+
+        # Test the use of weights that are not integer or floats, but e.g.
+        # complex numbers or object types.
+
+        # Complex weights
+        values = np.array([1.3, 2.5, 2.3])
+        weights = np.array([1, -1, 2]) + 1j * np.array([2, 1, 2])
+
+        # Check with custom bins
+        wa, wb = histogram(values, bins=[0, 2, 3], weights=weights)
+        assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3]))
+
+        # Check with even bins
+        wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights)
+        assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3]))
+
+        # Decimal weights
+        from decimal import Decimal
+        values = np.array([1.3, 2.5, 2.3])
+        weights = np.array([Decimal(1), Decimal(2), Decimal(3)])
+
+        # Check with custom bins
+        wa, wb = histogram(values, bins=[0, 2, 3], weights=weights)
+        assert_array_almost_equal(wa, [Decimal(1), Decimal(5)])
+
+        # Check with even bins
+        wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights)
+        assert_array_almost_equal(wa, [Decimal(1), Decimal(5)])
+
+    def test_no_side_effects(self):
+        # This is a regression test that ensures that values passed to
+        # ``histogram`` are unchanged.
+        values = np.array([1.3, 2.5, 2.3])
+        np.histogram(values, range=[-10, 10], bins=100)
+        assert_array_almost_equal(values, [1.3, 2.5, 2.3])
+
+    def test_empty(self):
+        a, b = histogram([], bins=([0, 1]))
+        assert_array_equal(a, np.array([0]))
+        assert_array_equal(b, np.array([0, 1]))
+
+    def test_finite_range(self):
+        # Normal ranges should be fine
+        vals = np.linspace(0.0, 1.0, num=100)
+        histogram(vals, range=[0.25,0.75])
+        assert_raises(ValueError, histogram, vals, range=[np.nan,0.75])
+        assert_raises(ValueError, histogram, vals, range=[0.25,np.inf])
+        
+
+class TestHistogramOptimBinNums(TestCase):
+    """
+    Provide test coverage when using provided estimators for optimal number of
+    bins
+    """
+
+    def test_empty(self):
+        estimator_list = ['fd', 'scott', 'rice', 'sturges',
+                          'doane', 'sqrt', 'auto']
+        # check it can deal with empty data
+        for estimator in estimator_list:
+            a, b = histogram([], bins=estimator)
+            assert_array_equal(a, np.array([0]))
+            assert_array_equal(b, np.array([0, 1]))
+
+    def test_simple(self):
+        """
+        Straightforward testing with a mixture of linspace data (for
+        consistency). All test values have been precomputed and the values
+        shouldn't change
+        """
+        # Some basic sanity checking, with some fixed data.
+        # Checking for the correct number of bins
+        basic_test = {50:   {'fd': 4,  'scott': 4,  'rice': 8,  'sturges': 7, 
+                             'doane': 8, 'sqrt': 8, 'auto': 7},
+                      500:  {'fd': 8,  'scott': 8,  'rice': 16, 'sturges': 10,
+                             'doane': 12, 'sqrt': 23, 'auto': 10},
+                      5000: {'fd': 17, 'scott': 17, 'rice': 35, 'sturges': 14,
+                             'doane': 17, 'sqrt': 71, 'auto': 17}}
+
+        for testlen, expectedResults in basic_test.items():
+            # Create some sort of non uniform data to test with
+            # (2 peak uniform mixture)
+            x1 = np.linspace(-10, -1, testlen // 5 * 2)
+            x2 = np.linspace(1, 10, testlen // 5 * 3)
+            x = np.concatenate((x1, x2))
+            for estimator, numbins in expectedResults.items():
+                a, b = np.histogram(x, estimator)
+                assert_equal(len(a), numbins, err_msg="For the {0} estimator "
+                             "with datasize of {1}".format(estimator, testlen))
+
+    def test_small(self):
+        """
+        Smaller datasets have the potential to cause issues with the data
+        adaptive methods, especially the FD method. All bin numbers have been
+        precalculated.
+        """
+        small_dat = {1: {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1,
+                         'doane': 1, 'sqrt': 1},
+                     2: {'fd': 2, 'scott': 1, 'rice': 3, 'sturges': 2,
+                         'doane': 1, 'sqrt': 2},
+                     3: {'fd': 2, 'scott': 2, 'rice': 3, 'sturges': 3,
+                         'doane': 3, 'sqrt': 2}}
+
+        for testlen, expectedResults in small_dat.items():
+            testdat = np.arange(testlen)
+            for estimator, expbins in expectedResults.items():
+                a, b = np.histogram(testdat, estimator)
+                assert_equal(len(a), expbins, err_msg="For the {0} estimator "
+                             "with datasize of {1}".format(estimator, testlen))
+
+    def test_incorrect_methods(self):
+        """
+        Check a Value Error is thrown when an unknown string is passed in
+        """
+        check_list = ['mad', 'freeman', 'histograms', 'IQR']
+        for estimator in check_list:
+            assert_raises(ValueError, histogram, [1, 2, 3], estimator)
+
+    def test_novariance(self):
+        """
+        Check that methods handle no variance in data
+        Primarily for Scott and FD as the SD and IQR are both 0 in this case
+        """
+        novar_dataset = np.ones(100)
+        novar_resultdict = {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1,
+                            'doane': 1, 'sqrt': 1, 'auto': 1}
+
+        for estimator, numbins in novar_resultdict.items():
+            a, b = np.histogram(novar_dataset, estimator)
+            assert_equal(len(a), numbins, err_msg="{0} estimator, "
+                         "No Variance test".format(estimator))
+
+    def test_outlier(self):
+        """
+        Check the FD, Scott and Doane with outliers.
+
+        The FD estimates a smaller binwidth since it's less affected by
+        outliers. Since the range is so (artificially) large, this means more
+        bins, most of which will be empty, but the data of interest usually is
+        unaffected. The Scott estimator is more affected and returns fewer bins,
+        despite most of the variance being in one area of the data. The Doane
+        estimator lies somewhere between the other two.
+        """
+        xcenter = np.linspace(-10, 10, 50)
+        outlier_dataset = np.hstack((np.linspace(-110, -100, 5), xcenter))
+
+        outlier_resultdict = {'fd': 21, 'scott': 5, 'doane': 11}
+
+        for estimator, numbins in outlier_resultdict.items():
+            a, b = np.histogram(outlier_dataset, estimator)
+            assert_equal(len(a), numbins)
+
+    def test_simple_range(self):
+        """
+        Straightforward testing with a mixture of linspace data (for
+        consistency). Adding in a 3rd mixture that will then be
+        completely ignored. All test values have been precomputed and
+        the shouldn't change.
+        """
+        # some basic sanity checking, with some fixed data. Checking for the correct number of bins
+        basic_test = {50:   {'fd': 8,  'scott': 8,  'rice': 15, 'sturges': 14, 'auto': 14},
+                      500:  {'fd': 15, 'scott': 16, 'rice': 32, 'sturges': 20, 'auto': 20},
+                      5000: {'fd': 33, 'scott': 33, 'rice': 69, 'sturges': 27, 'auto': 33}}
+
+        for testlen, expectedResults in basic_test.items():
+            # create some sort of non uniform data to test with (3 peak uniform mixture)
+            x1 = np.linspace(-10, -1, testlen // 5 * 2)
+            x2 = np.linspace(1, 10, testlen // 5 * 3)
+            x3 = np.linspace(-100, -50, testlen)
+            x = np.hstack((x1, x2, x3))
+            for estimator, numbins in expectedResults.items():
+                a, b = np.histogram(x, estimator, range = (-20, 20))
+                msg = "For the {0} estimator with datasize of {1}".format(estimator, testlen)
+                assert_equal(len(a), numbins, err_msg=msg)
+
+    def test_simple_weighted(self):
+        """
+        Check that weighted data raises a TypeError
+        """
+        estimator_list = ['fd', 'scott', 'rice', 'sturges', 'auto']
+        for estimator in estimator_list:
+            assert_raises(TypeError, histogram, [1, 2, 3], estimator, weights=[1, 2, 3])
+
+
+class TestHistogramdd(TestCase):
+
+    def test_simple(self):
+        x = np.array([[-.5, .5, 1.5], [-.5, 1.5, 2.5], [-.5, 2.5, .5],
+                      [.5,  .5, 1.5], [.5,  1.5, 2.5], [.5,  2.5, 2.5]])
+        H, edges = histogramdd(x, (2, 3, 3),
+                               range=[[-1, 1], [0, 3], [0, 3]])
+        answer = np.array([[[0, 1, 0], [0, 0, 1], [1, 0, 0]],
+                           [[0, 1, 0], [0, 0, 1], [0, 0, 1]]])
+        assert_array_equal(H, answer)
+
+        # Check normalization
+        ed = [[-2, 0, 2], [0, 1, 2, 3], [0, 1, 2, 3]]
+        H, edges = histogramdd(x, bins=ed, normed=True)
+        assert_(np.all(H == answer / 12.))
+
+        # Check that H has the correct shape.
+        H, edges = histogramdd(x, (2, 3, 4),
+                               range=[[-1, 1], [0, 3], [0, 4]],
+                               normed=True)
+        answer = np.array([[[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]],
+                           [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0]]])
+        assert_array_almost_equal(H, answer / 6., 4)
+        # Check that a sequence of arrays is accepted and H has the correct
+        # shape.
+        z = [np.squeeze(y) for y in split(x, 3, axis=1)]
+        H, edges = histogramdd(
+            z, bins=(4, 3, 2), range=[[-2, 2], [0, 3], [0, 2]])
+        answer = np.array([[[0, 0], [0, 0], [0, 0]],
+                           [[0, 1], [0, 0], [1, 0]],
+                           [[0, 1], [0, 0], [0, 0]],
+                           [[0, 0], [0, 0], [0, 0]]])
+        assert_array_equal(H, answer)
+
+        Z = np.zeros((5, 5, 5))
+        Z[list(range(5)), list(range(5)), list(range(5))] = 1.
+        H, edges = histogramdd([np.arange(5), np.arange(5), np.arange(5)], 5)
+        assert_array_equal(H, Z)
+
+    def test_shape_3d(self):
+        # All possible permutations for bins of different lengths in 3D.
+        bins = ((5, 4, 6), (6, 4, 5), (5, 6, 4), (4, 6, 5), (6, 5, 4),
+                (4, 5, 6))
+        r = rand(10, 3)
+        for b in bins:
+            H, edges = histogramdd(r, b)
+            assert_(H.shape == b)
+
+    def test_shape_4d(self):
+        # All possible permutations for bins of different lengths in 4D.
+        bins = ((7, 4, 5, 6), (4, 5, 7, 6), (5, 6, 4, 7), (7, 6, 5, 4),
+                (5, 7, 6, 4), (4, 6, 7, 5), (6, 5, 7, 4), (7, 5, 4, 6),
+                (7, 4, 6, 5), (6, 4, 7, 5), (6, 7, 5, 4), (4, 6, 5, 7),
+                (4, 7, 5, 6), (5, 4, 6, 7), (5, 7, 4, 6), (6, 7, 4, 5),
+                (6, 5, 4, 7), (4, 7, 6, 5), (4, 5, 6, 7), (7, 6, 4, 5),
+                (5, 4, 7, 6), (5, 6, 7, 4), (6, 4, 5, 7), (7, 5, 6, 4))
+
+        r = rand(10, 4)
+        for b in bins:
+            H, edges = histogramdd(r, b)
+            assert_(H.shape == b)
+
+    def test_weights(self):
+        v = rand(100, 2)
+        hist, edges = histogramdd(v)
+        n_hist, edges = histogramdd(v, normed=True)
+        w_hist, edges = histogramdd(v, weights=np.ones(100))
+        assert_array_equal(w_hist, hist)
+        w_hist, edges = histogramdd(v, weights=np.ones(100) * 2, normed=True)
+        assert_array_equal(w_hist, n_hist)
+        w_hist, edges = histogramdd(v, weights=np.ones(100, int) * 2)
+        assert_array_equal(w_hist, 2 * hist)
+
+    def test_identical_samples(self):
+        x = np.zeros((10, 2), int)
+        hist, edges = histogramdd(x, bins=2)
+        assert_array_equal(edges[0], np.array([-0.5, 0., 0.5]))
+
+    def test_empty(self):
+        a, b = histogramdd([[], []], bins=([0, 1], [0, 1]))
+        assert_array_max_ulp(a, np.array([[0.]]))
+        a, b = np.histogramdd([[], [], []], bins=2)
+        assert_array_max_ulp(a, np.zeros((2, 2, 2)))
+
+    def test_bins_errors(self):
+        # There are two ways to specify bins. Check for the right errors
+        # when mixing those.
+        x = np.arange(8).reshape(2, 4)
+        assert_raises(ValueError, np.histogramdd, x, bins=[-1, 2, 4, 5])
+        assert_raises(ValueError, np.histogramdd, x, bins=[1, 0.99, 1, 1])
+        assert_raises(
+            ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 2, 3]])
+        assert_raises(
+            ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 3, -3]])
+        assert_(np.histogramdd(x, bins=[1, 1, 1, [1, 2, 3, 4]]))
+
+    def test_inf_edges(self):
+        # Test using +/-inf bin edges works. See #1788.
+        with np.errstate(invalid='ignore'):
+            x = np.arange(6).reshape(3, 2)
+            expected = np.array([[1, 0], [0, 1], [0, 1]])
+            h, e = np.histogramdd(x, bins=[3, [-np.inf, 2, 10]])
+            assert_allclose(h, expected)
+            h, e = np.histogramdd(x, bins=[3, np.array([-1, 2, np.inf])])
+            assert_allclose(h, expected)
+            h, e = np.histogramdd(x, bins=[3, [-np.inf, 3, np.inf]])
+            assert_allclose(h, expected)
+
+    def test_rightmost_binedge(self):
+        # Test event very close to rightmost binedge. See Github issue #4266
+        x = [0.9999999995]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0000000001]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 1.)
+        x = [1.0001]
+        bins = [[0., 0.5, 1.0]]
+        hist, _ = histogramdd(x, bins=bins)
+        assert_(hist[0] == 0.0)
+        assert_(hist[1] == 0.0)
+
+    def test_finite_range(self):
+        vals = np.random.random((100, 3))
+        histogramdd(vals, range=[[0.0, 1.0], [0.25, 0.75], [0.25, 0.5]])
+        assert_raises(ValueError, histogramdd, vals, 
+                      range=[[0.0, 1.0], [0.25, 0.75], [0.25, np.inf]])
+        assert_raises(ValueError, histogramdd, vals, 
+                      range=[[0.0, 1.0], [np.nan, 0.75], [0.25, 0.5]])
+
+
+class TestUnique(TestCase):
+
+    def test_simple(self):
+        x = np.array([4, 3, 2, 1, 1, 2, 3, 4, 0])
+        assert_(np.all(unique(x) == [0, 1, 2, 3, 4]))
+        assert_(unique(np.array([1, 1, 1, 1, 1])) == np.array([1]))
+        x = ['widget', 'ham', 'foo', 'bar', 'foo', 'ham']
+        assert_(np.all(unique(x) == ['bar', 'foo', 'ham', 'widget']))
+        x = np.array([5 + 6j, 1 + 1j, 1 + 10j, 10, 5 + 6j])
+        assert_(np.all(unique(x) == [1 + 1j, 1 + 10j, 5 + 6j, 10]))
+
+
+class TestCheckFinite(TestCase):
+
+    def test_simple(self):
+        a = [1, 2, 3]
+        b = [1, 2, np.inf]
+        c = [1, 2, np.nan]
+        np.lib.asarray_chkfinite(a)
+        assert_raises(ValueError, np.lib.asarray_chkfinite, b)
+        assert_raises(ValueError, np.lib.asarray_chkfinite, c)
+
+    def test_dtype_order(self):
+        # Regression test for missing dtype and order arguments
+        a = [1, 2, 3]
+        a = np.lib.asarray_chkfinite(a, order='F', dtype=np.float64)
+        assert_(a.dtype == np.float64)
+
+
+class catch_warn_nfb(clear_and_catch_warnings):
+
+    """
+    Context manager to catch, reset warnings in function_base module
+
+    """
+    class_modules = (nfb,)
+
+
+class TestCorrCoef(TestCase):
+    A = np.array(
+        [[0.15391142, 0.18045767, 0.14197213],
+         [0.70461506, 0.96474128, 0.27906989],
+         [0.9297531, 0.32296769, 0.19267156]])
+    B = np.array(
+        [[0.10377691, 0.5417086, 0.49807457],
+         [0.82872117, 0.77801674, 0.39226705],
+         [0.9314666, 0.66800209, 0.03538394]])
+    res1 = np.array(
+        [[1., 0.9379533, -0.04931983],
+         [0.9379533, 1., 0.30007991],
+         [-0.04931983, 0.30007991, 1.]])
+    res2 = np.array(
+        [[1., 0.9379533, -0.04931983, 0.30151751, 0.66318558, 0.51532523],
+         [0.9379533, 1., 0.30007991, -0.04781421, 0.88157256, 0.78052386],
+         [-0.04931983, 0.30007991, 1., -0.96717111, 0.71483595, 0.83053601],
+         [0.30151751, -0.04781421, -0.96717111, 1., -0.51366032, -0.66173113],
+         [0.66318558, 0.88157256, 0.71483595, -0.51366032, 1., 0.98317823],
+         [0.51532523, 0.78052386, 0.83053601, -0.66173113, 0.98317823, 1.]])
+
+    def test_non_array(self):
+        assert_almost_equal(np.corrcoef([0, 1, 0], [1, 0, 1]),
+                            [[1., -1.], [-1.,  1.]])
+
+    def test_simple(self):
+        tgt1 = corrcoef(self.A)
+        assert_almost_equal(tgt1, self.res1)
+        assert_(np.all(np.abs(tgt1) <= 1.0))
+
+        tgt2 = corrcoef(self.A, self.B)
+        assert_almost_equal(tgt2, self.res2)
+        assert_(np.all(np.abs(tgt2) <= 1.0))
+
+    def test_ddof(self):
+        # ddof raises DeprecationWarning
+        with catch_warn_nfb():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, self.A, ddof=-1)
+            warnings.simplefilter("ignore")
+            # ddof has no or negligible effect on the function
+            assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1)
+            assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2)
+            assert_almost_equal(corrcoef(self.A, ddof=3), self.res1)
+            assert_almost_equal(corrcoef(self.A, self.B, ddof=3), self.res2)
+
+    def test_bias(self):
+        # bias raises DeprecationWarning
+        with catch_warn_nfb():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, self.A, self.B, 1, 0)
+            assert_warns(DeprecationWarning, corrcoef, self.A, bias=0)
+            warnings.simplefilter("ignore")
+            # bias has no or negligible effect on the function
+            assert_almost_equal(corrcoef(self.A, bias=1), self.res1)
+
+    def test_complex(self):
+        x = np.array([[1, 2, 3], [1j, 2j, 3j]])
+        res = corrcoef(x)
+        tgt = np.array([[1., -1.j], [1.j, 1.]])
+        assert_allclose(res, tgt)
+        assert_(np.all(np.abs(res) <= 1.0))
+
+    def test_xy(self):
+        x = np.array([[1, 2, 3]])
+        y = np.array([[1j, 2j, 3j]])
+        assert_allclose(np.corrcoef(x, y), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(corrcoef(np.array([])), np.nan)
+            assert_array_equal(corrcoef(np.array([]).reshape(0, 2)),
+                               np.array([]).reshape(0, 0))
+            assert_array_equal(corrcoef(np.array([]).reshape(2, 0)),
+                               np.array([[np.nan, np.nan], [np.nan, np.nan]]))
+
+    def test_extreme(self):
+        x = [[1e-100, 1e100], [1e100, 1e-100]]
+        with np.errstate(all='raise'):
+            c = corrcoef(x)
+        assert_array_almost_equal(c, np.array([[1., -1.], [-1., 1.]]))
+        assert_(np.all(np.abs(c) <= 1.0))
+
+
+class TestCov(TestCase):
+    x1 = np.array([[0, 2], [1, 1], [2, 0]]).T
+    res1 = np.array([[1., -1.], [-1., 1.]])
+    x2 = np.array([0.0, 1.0, 2.0], ndmin=2)
+    frequencies = np.array([1, 4, 1])
+    x2_repeats = np.array([[0.0], [1.0], [1.0], [1.0], [1.0], [2.0]]).T
+    res2 = np.array([[0.4, -0.4], [-0.4, 0.4]])
+    unit_frequencies = np.ones(3, dtype=np.integer)
+    weights = np.array([1.0, 4.0, 1.0])
+    res3 = np.array([[2. / 3., -2. / 3.], [-2. / 3., 2. / 3.]])
+    unit_weights = np.ones(3)
+    x3 = np.array([0.3942, 0.5969, 0.7730, 0.9918, 0.7964])
+
+    def test_basic(self):
+        assert_allclose(cov(self.x1), self.res1)
+
+    def test_complex(self):
+        x = np.array([[1, 2, 3], [1j, 2j, 3j]])
+        assert_allclose(cov(x), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_xy(self):
+        x = np.array([[1, 2, 3]])
+        y = np.array([[1j, 2j, 3j]])
+        assert_allclose(cov(x, y), np.array([[1., -1.j], [1.j, 1.]]))
+
+    def test_empty(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(cov(np.array([])), np.nan)
+            assert_array_equal(cov(np.array([]).reshape(0, 2)),
+                               np.array([]).reshape(0, 0))
+            assert_array_equal(cov(np.array([]).reshape(2, 0)),
+                               np.array([[np.nan, np.nan], [np.nan, np.nan]]))
+
+    def test_wrong_ddof(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('always', RuntimeWarning)
+            assert_array_equal(cov(self.x1, ddof=5),
+                               np.array([[np.inf, -np.inf],
+                                         [-np.inf, np.inf]]))
+
+    def test_1D_rowvar(self):
+        assert_allclose(cov(self.x3), cov(self.x3, rowvar=0))
+        y = np.array([0.0780, 0.3107, 0.2111, 0.0334, 0.8501])
+        assert_allclose(cov(self.x3, y), cov(self.x3, y, rowvar=0))
+
+    def test_1D_variance(self):
+        assert_allclose(cov(self.x3, ddof=1), np.var(self.x3, ddof=1))
+
+    def test_fweights(self):
+        assert_allclose(cov(self.x2, fweights=self.frequencies),
+                        cov(self.x2_repeats))
+        assert_allclose(cov(self.x1, fweights=self.frequencies),
+                        self.res2)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies),
+                        self.res1)
+        nonint = self.frequencies + 0.5
+        assert_raises(TypeError, cov, self.x1, fweights=nonint)
+        f = np.ones((2, 3), dtype=np.integer)
+        assert_raises(RuntimeError, cov, self.x1, fweights=f)
+        f = np.ones(2, dtype=np.integer)
+        assert_raises(RuntimeError, cov, self.x1, fweights=f)
+        f = -1 * np.ones(3, dtype=np.integer)
+        assert_raises(ValueError, cov, self.x1, fweights=f)
+
+    def test_aweights(self):
+        assert_allclose(cov(self.x1, aweights=self.weights), self.res3)
+        assert_allclose(cov(self.x1, aweights=3.0 * self.weights),
+                        cov(self.x1, aweights=self.weights))
+        assert_allclose(cov(self.x1, aweights=self.unit_weights), self.res1)
+        w = np.ones((2, 3))
+        assert_raises(RuntimeError, cov, self.x1, aweights=w)
+        w = np.ones(2)
+        assert_raises(RuntimeError, cov, self.x1, aweights=w)
+        w = -1.0 * np.ones(3)
+        assert_raises(ValueError, cov, self.x1, aweights=w)
+
+    def test_unit_fweights_and_aweights(self):
+        assert_allclose(cov(self.x2, fweights=self.frequencies,
+                            aweights=self.unit_weights),
+                        cov(self.x2_repeats))
+        assert_allclose(cov(self.x1, fweights=self.frequencies,
+                            aweights=self.unit_weights),
+                        self.res2)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.unit_weights),
+                        self.res1)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.weights),
+                        self.res3)
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=3.0 * self.weights),
+                        cov(self.x1, aweights=self.weights))
+        assert_allclose(cov(self.x1, fweights=self.unit_frequencies,
+                            aweights=self.unit_weights),
+                        self.res1)
+
+
+class Test_I0(TestCase):
+
+    def test_simple(self):
+        assert_almost_equal(
+            i0(0.5),
+            np.array(1.0634833707413234))
+
+        A = np.array([0.49842636, 0.6969809, 0.22011976, 0.0155549])
+        assert_almost_equal(
+            i0(A),
+            np.array([1.06307822, 1.12518299, 1.01214991, 1.00006049]))
+
+        B = np.array([[0.827002, 0.99959078],
+                      [0.89694769, 0.39298162],
+                      [0.37954418, 0.05206293],
+                      [0.36465447, 0.72446427],
+                      [0.48164949, 0.50324519]])
+        assert_almost_equal(
+            i0(B),
+            np.array([[1.17843223, 1.26583466],
+                      [1.21147086, 1.03898290],
+                      [1.03633899, 1.00067775],
+                      [1.03352052, 1.13557954],
+                      [1.05884290, 1.06432317]]))
+
+
+class TestKaiser(TestCase):
+
+    def test_simple(self):
+        assert_(np.isfinite(kaiser(1, 1.0)))
+        assert_almost_equal(kaiser(0, 1.0),
+                            np.array([]))
+        assert_almost_equal(kaiser(2, 1.0),
+                            np.array([0.78984831, 0.78984831]))
+        assert_almost_equal(kaiser(5, 1.0),
+                            np.array([0.78984831, 0.94503323, 1.,
+                                      0.94503323, 0.78984831]))
+        assert_almost_equal(kaiser(5, 1.56789),
+                            np.array([0.58285404, 0.88409679, 1.,
+                                      0.88409679, 0.58285404]))
+
+    def test_int_beta(self):
+        kaiser(3, 4)
+
+
+class TestMsort(TestCase):
+
+    def test_simple(self):
+        A = np.array([[0.44567325, 0.79115165, 0.54900530],
+                      [0.36844147, 0.37325583, 0.96098397],
+                      [0.64864341, 0.52929049, 0.39172155]])
+        assert_almost_equal(
+            msort(A),
+            np.array([[0.36844147, 0.37325583, 0.39172155],
+                      [0.44567325, 0.52929049, 0.54900530],
+                      [0.64864341, 0.79115165, 0.96098397]]))
+
+
+class TestMeshgrid(TestCase):
+
+    def test_simple(self):
+        [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7])
+        assert_array_equal(X, np.array([[1, 2, 3],
+                                        [1, 2, 3],
+                                        [1, 2, 3],
+                                        [1, 2, 3]]))
+        assert_array_equal(Y, np.array([[4, 4, 4],
+                                        [5, 5, 5],
+                                        [6, 6, 6],
+                                        [7, 7, 7]]))
+
+    def test_single_input(self):
+        [X] = meshgrid([1, 2, 3, 4])
+        assert_array_equal(X, np.array([1, 2, 3, 4]))
+
+    def test_no_input(self):
+        args = []
+        assert_array_equal([], meshgrid(*args))
+
+    def test_indexing(self):
+        x = [1, 2, 3]
+        y = [4, 5, 6, 7]
+        [X, Y] = meshgrid(x, y, indexing='ij')
+        assert_array_equal(X, np.array([[1, 1, 1, 1],
+                                        [2, 2, 2, 2],
+                                        [3, 3, 3, 3]]))
+        assert_array_equal(Y, np.array([[4, 5, 6, 7],
+                                        [4, 5, 6, 7],
+                                        [4, 5, 6, 7]]))
+
+        # Test expected shapes:
+        z = [8, 9]
+        assert_(meshgrid(x, y)[0].shape == (4, 3))
+        assert_(meshgrid(x, y, indexing='ij')[0].shape == (3, 4))
+        assert_(meshgrid(x, y, z)[0].shape == (4, 3, 2))
+        assert_(meshgrid(x, y, z, indexing='ij')[0].shape == (3, 4, 2))
+
+        assert_raises(ValueError, meshgrid, x, y, indexing='notvalid')
+
+    def test_sparse(self):
+        [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7], sparse=True)
+        assert_array_equal(X, np.array([[1, 2, 3]]))
+        assert_array_equal(Y, np.array([[4], [5], [6], [7]]))
+
+    def test_invalid_arguments(self):
+        # Test that meshgrid complains about invalid arguments
+        # Regression test for issue #4755:
+        # https://github.com/numpy/numpy/issues/4755
+        assert_raises(TypeError, meshgrid,
+                      [1, 2, 3], [4, 5, 6, 7], indices='ij')
+
+
+class TestPiecewise(TestCase):
+
+    def test_simple(self):
+        # Condition is single bool list
+        x = piecewise([0, 0], [True, False], [1])
+        assert_array_equal(x, [1, 0])
+
+        # List of conditions: single bool list
+        x = piecewise([0, 0], [[True, False]], [1])
+        assert_array_equal(x, [1, 0])
+
+        # Conditions is single bool array
+        x = piecewise([0, 0], np.array([True, False]), [1])
+        assert_array_equal(x, [1, 0])
+
+        # Condition is single int array
+        x = piecewise([0, 0], np.array([1, 0]), [1])
+        assert_array_equal(x, [1, 0])
+
+        # List of conditions: int array
+        x = piecewise([0, 0], [np.array([1, 0])], [1])
+        assert_array_equal(x, [1, 0])
+
+        x = piecewise([0, 0], [[False, True]], [lambda x:-1])
+        assert_array_equal(x, [0, -1])
+
+    def test_two_conditions(self):
+        x = piecewise([1, 2], [[True, False], [False, True]], [3, 4])
+        assert_array_equal(x, [3, 4])
+
+    def test_scalar_domains_three_conditions(self):
+        x = piecewise(3, [True, False, False], [4, 2, 0])
+        assert_equal(x, 4)
+
+    def test_default(self):
+        # No value specified for x[1], should be 0
+        x = piecewise([1, 2], [True, False], [2])
+        assert_array_equal(x, [2, 0])
+
+        # Should set x[1] to 3
+        x = piecewise([1, 2], [True, False], [2, 3])
+        assert_array_equal(x, [2, 3])
+
+    def test_0d(self):
+        x = np.array(3)
+        y = piecewise(x, x > 3, [4, 0])
+        assert_(y.ndim == 0)
+        assert_(y == 0)
+
+        x = 5
+        y = piecewise(x, [[True], [False]], [1, 0])
+        assert_(y.ndim == 0)
+        assert_(y == 1)
+
+    def test_0d_comparison(self):
+        x = 3
+        piecewise(x, [x <= 3, x > 3], [4, 0])  # Should succeed.
+
+    def test_multidimensional_extrafunc(self):
+        x = np.array([[-2.5, -1.5, -0.5],
+                      [0.5, 1.5, 2.5]])
+        y = piecewise(x, [x < 0, x >= 2], [-1, 1, 3])
+        assert_array_equal(y, np.array([[-1., -1., -1.],
+                                        [3., 3., 1.]]))
+
+
+class TestBincount(TestCase):
+
+    def test_simple(self):
+        y = np.bincount(np.arange(4))
+        assert_array_equal(y, np.ones(4))
+
+    def test_simple2(self):
+        y = np.bincount(np.array([1, 5, 2, 4, 1]))
+        assert_array_equal(y, np.array([0, 2, 1, 0, 1, 1]))
+
+    def test_simple_weight(self):
+        x = np.arange(4)
+        w = np.array([0.2, 0.3, 0.5, 0.1])
+        y = np.bincount(x, w)
+        assert_array_equal(y, w)
+
+    def test_simple_weight2(self):
+        x = np.array([1, 2, 4, 5, 2])
+        w = np.array([0.2, 0.3, 0.5, 0.1, 0.2])
+        y = np.bincount(x, w)
+        assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1]))
+
+    def test_with_minlength(self):
+        x = np.array([0, 1, 0, 1, 1])
+        y = np.bincount(x, minlength=3)
+        assert_array_equal(y, np.array([2, 3, 0]))
+
+    def test_with_minlength_smaller_than_maxvalue(self):
+        x = np.array([0, 1, 1, 2, 2, 3, 3])
+        y = np.bincount(x, minlength=2)
+        assert_array_equal(y, np.array([1, 2, 2, 2]))
+
+    def test_with_minlength_and_weights(self):
+        x = np.array([1, 2, 4, 5, 2])
+        w = np.array([0.2, 0.3, 0.5, 0.1, 0.2])
+        y = np.bincount(x, w, 8)
+        assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1, 0, 0]))
+
+    def test_empty(self):
+        x = np.array([], dtype=int)
+        y = np.bincount(x)
+        assert_array_equal(x, y)
+
+    def test_empty_with_minlength(self):
+        x = np.array([], dtype=int)
+        y = np.bincount(x, minlength=5)
+        assert_array_equal(y, np.zeros(5, dtype=int))
+
+    def test_with_incorrect_minlength(self):
+        x = np.array([], dtype=int)
+        assert_raises_regex(TypeError, "an integer is required",
+                            lambda: np.bincount(x, minlength="foobar"))
+        assert_raises_regex(ValueError, "must be positive",
+                            lambda: np.bincount(x, minlength=-1))
+        assert_raises_regex(ValueError, "must be positive",
+                            lambda: np.bincount(x, minlength=0))
+
+        x = np.arange(5)
+        assert_raises_regex(TypeError, "an integer is required",
+                            lambda: np.bincount(x, minlength="foobar"))
+        assert_raises_regex(ValueError, "minlength must be positive",
+                            lambda: np.bincount(x, minlength=-1))
+        assert_raises_regex(ValueError, "minlength must be positive",
+                            lambda: np.bincount(x, minlength=0))
+
+
+class TestInterp(TestCase):
+
+    def test_exceptions(self):
+        assert_raises(ValueError, interp, 0, [], [])
+        assert_raises(ValueError, interp, 0, [0], [1, 2])
+        assert_raises(ValueError, interp, 0, [0, 1], [1, 2], period=0)
+        assert_raises(ValueError, interp, 0, [], [], period=360)
+        assert_raises(ValueError, interp, 0, [0], [1, 2], period=360)
+
+    def test_basic(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = np.linspace(0, 1, 50)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+
+    def test_right_left_behavior(self):
+        # Needs range of sizes to test different code paths.
+        # size ==1 is special cased, 1 < size < 5 is linear search, and
+        # size >= 5 goes through local search and possibly binary search.
+        for size in range(1, 10):
+            xp = np.arange(size, dtype=np.double)
+            yp = np.ones(size, dtype=np.double)
+            incpts = np.array([-1, 0, size - 1, size], dtype=np.double)
+            decpts = incpts[::-1]
+
+            incres = interp(incpts, xp, yp)
+            decres = interp(decpts, xp, yp)
+            inctgt = np.array([1, 1, 1, 1], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, left=0)
+            decres = interp(decpts, xp, yp, left=0)
+            inctgt = np.array([0, 1, 1, 1], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, right=2)
+            decres = interp(decpts, xp, yp, right=2)
+            inctgt = np.array([1, 1, 1, 2], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+            incres = interp(incpts, xp, yp, left=0, right=2)
+            decres = interp(decpts, xp, yp, left=0, right=2)
+            inctgt = np.array([0, 1, 1, 2], dtype=np.float)
+            dectgt = inctgt[::-1]
+            assert_equal(incres, inctgt)
+            assert_equal(decres, dectgt)
+
+    def test_scalar_interpolation_point(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = 0
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = .3
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.float32(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.float64(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.nan
+        assert_almost_equal(np.interp(x0, x, y), x0)
+
+    def test_zero_dimensional_interpolation_point(self):
+        x = np.linspace(0, 1, 5)
+        y = np.linspace(0, 1, 5)
+        x0 = np.array(.3)
+        assert_almost_equal(np.interp(x0, x, y), x0)
+        x0 = np.array(.3, dtype=object)
+        assert_almost_equal(np.interp(x0, x, y), .3)
+
+    def test_if_len_x_is_small(self):
+        xp = np.arange(0, 10, 0.0001)
+        fp = np.sin(xp)
+        assert_almost_equal(np.interp(np.pi, xp, fp), 0.0)
+
+    def test_period(self):
+        x = [-180, -170, -185, 185, -10, -5, 0, 365]
+        xp = [190, -190, 350, -350]
+        fp = [5, 10, 3, 4]
+        y = [7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75]
+        assert_almost_equal(np.interp(x, xp, fp, period=360), y)
+        x = np.array(x, order='F').reshape(2, -1)
+        y = np.array(y, order='C').reshape(2, -1)
+        assert_almost_equal(np.interp(x, xp, fp, period=360), y)
+
+
+def compare_results(res, desired):
+    for i in range(len(desired)):
+        assert_array_equal(res[i], desired[i])
+
+
+class TestPercentile(TestCase):
+
+    def test_basic(self):
+        x = np.arange(8) * 0.5
+        assert_equal(np.percentile(x, 0), 0.)
+        assert_equal(np.percentile(x, 100), 3.5)
+        assert_equal(np.percentile(x, 50), 1.75)
+        x[1] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(x, 0), np.nan)
+            assert_equal(np.percentile(x, 0, interpolation='nearest'), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_api(self):
+        d = np.ones(5)
+        np.percentile(d, 5, None, None, False)
+        np.percentile(d, 5, None, None, False, 'linear')
+        o = np.ones((1,))
+        np.percentile(d, 5, None, o, False, 'linear')
+
+    def test_2D(self):
+        x = np.array([[1, 1, 1],
+                      [1, 1, 1],
+                      [4, 4, 3],
+                      [1, 1, 1],
+                      [1, 1, 1]])
+        assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1])
+
+    def test_linear(self):
+
+        # Test defaults
+        assert_equal(np.percentile(range(10), 50), 4.5)
+
+        # explicitly specify interpolation_method 'linear' (the default)
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='linear'), 4.5)
+
+    def test_lower_higher(self):
+
+        # interpolation_method 'lower'/'higher'
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='lower'), 4)
+        assert_equal(np.percentile(range(10), 50,
+                                   interpolation='higher'), 5)
+
+    def test_midpoint(self):
+        assert_equal(np.percentile(range(10), 51,
+                                   interpolation='midpoint'), 4.5)
+        assert_equal(np.percentile(range(11), 51,
+                                   interpolation='midpoint'), 5.5)
+        assert_equal(np.percentile(range(11), 50,
+                                   interpolation='midpoint'), 5)
+
+    def test_nearest(self):
+        assert_equal(np.percentile(range(10), 51,
+                                   interpolation='nearest'), 5)
+        assert_equal(np.percentile(range(10), 49,
+                                   interpolation='nearest'), 4)
+
+    def test_sequence(self):
+        x = np.arange(8) * 0.5
+        assert_equal(np.percentile(x, [0, 100, 50]), [0, 3.5, 1.75])
+
+    def test_axis(self):
+        x = np.arange(12).reshape(3, 4)
+
+        assert_equal(np.percentile(x, (25, 50, 100)), [2.75, 5.5, 11.0])
+
+        r0 = [[2, 3, 4, 5], [4, 5, 6, 7], [8, 9, 10, 11]]
+        assert_equal(np.percentile(x, (25, 50, 100), axis=0), r0)
+
+        r1 = [[0.75, 1.5, 3], [4.75, 5.5, 7], [8.75, 9.5, 11]]
+        assert_equal(np.percentile(x, (25, 50, 100), axis=1), np.array(r1).T)
+
+        # ensure qth axis is always first as with np.array(old_percentile(..))
+        x = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6)
+        assert_equal(np.percentile(x, (25, 50)).shape, (2,))
+        assert_equal(np.percentile(x, (25, 50, 75)).shape, (3,))
+        assert_equal(np.percentile(x, (25, 50), axis=0).shape, (2, 4, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=1).shape, (2, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=2).shape, (2, 3, 4, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=3).shape, (2, 3, 4, 5))
+        assert_equal(
+            np.percentile(x, (25, 50, 75), axis=1).shape, (3, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50),
+                                   interpolation="higher").shape, (2,))
+        assert_equal(np.percentile(x, (25, 50, 75),
+                                   interpolation="higher").shape, (3,))
+        assert_equal(np.percentile(x, (25, 50), axis=0,
+                                   interpolation="higher").shape, (2, 4, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=1,
+                                   interpolation="higher").shape, (2, 3, 5, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=2,
+                                   interpolation="higher").shape, (2, 3, 4, 6))
+        assert_equal(np.percentile(x, (25, 50), axis=3,
+                                   interpolation="higher").shape, (2, 3, 4, 5))
+        assert_equal(np.percentile(x, (25, 50, 75), axis=1,
+                                   interpolation="higher").shape, (3, 3, 5, 6))
+
+    def test_scalar_q(self):
+        # test for no empty dimensions for compatiblity with old percentile
+        x = np.arange(12).reshape(3, 4)
+        assert_equal(np.percentile(x, 50), 5.5)
+        self.assertTrue(np.isscalar(np.percentile(x, 50)))
+        r0 = np.array([4.,  5.,  6.,  7.])
+        assert_equal(np.percentile(x, 50, axis=0), r0)
+        assert_equal(np.percentile(x, 50, axis=0).shape, r0.shape)
+        r1 = np.array([1.5,  5.5,  9.5])
+        assert_almost_equal(np.percentile(x, 50, axis=1), r1)
+        assert_equal(np.percentile(x, 50, axis=1).shape, r1.shape)
+
+        out = np.empty(1)
+        assert_equal(np.percentile(x, 50, out=out), 5.5)
+        assert_equal(out, 5.5)
+        out = np.empty(4)
+        assert_equal(np.percentile(x, 50, axis=0, out=out), r0)
+        assert_equal(out, r0)
+        out = np.empty(3)
+        assert_equal(np.percentile(x, 50, axis=1, out=out), r1)
+        assert_equal(out, r1)
+
+        # test for no empty dimensions for compatiblity with old percentile
+        x = np.arange(12).reshape(3, 4)
+        assert_equal(np.percentile(x, 50, interpolation='lower'), 5.)
+        self.assertTrue(np.isscalar(np.percentile(x, 50)))
+        r0 = np.array([4.,  5.,  6.,  7.])
+        c0 = np.percentile(x, 50, interpolation='lower', axis=0)
+        assert_equal(c0, r0)
+        assert_equal(c0.shape, r0.shape)
+        r1 = np.array([1.,  5.,  9.])
+        c1 = np.percentile(x, 50, interpolation='lower', axis=1)
+        assert_almost_equal(c1, r1)
+        assert_equal(c1.shape, r1.shape)
+
+        out = np.empty((), dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', out=out)
+        assert_equal(c, 5)
+        assert_equal(out, 5)
+        out = np.empty(4, dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', axis=0, out=out)
+        assert_equal(c, r0)
+        assert_equal(out, r0)
+        out = np.empty(3, dtype=x.dtype)
+        c = np.percentile(x, 50, interpolation='lower', axis=1, out=out)
+        assert_equal(c, r1)
+        assert_equal(out, r1)
+
+    def test_exception(self):
+        assert_raises(ValueError, np.percentile, [1, 2], 56,
+                      interpolation='foobar')
+        assert_raises(ValueError, np.percentile, [1], 101)
+        assert_raises(ValueError, np.percentile, [1], -1)
+        assert_raises(ValueError, np.percentile, [1], list(range(50)) + [101])
+        assert_raises(ValueError, np.percentile, [1], list(range(50)) + [-0.1])
+
+    def test_percentile_list(self):
+        assert_equal(np.percentile([1, 2, 3], 0), 1)
+
+    def test_percentile_out(self):
+        x = np.array([1, 2, 3])
+        y = np.zeros((3,))
+        p = (1, 2, 3)
+        np.percentile(x, p, out=y)
+        assert_equal(y, np.percentile(x, p))
+
+        x = np.array([[1, 2, 3],
+                      [4, 5, 6]])
+
+        y = np.zeros((3, 3))
+        np.percentile(x, p, axis=0, out=y)
+        assert_equal(y, np.percentile(x, p, axis=0))
+
+        y = np.zeros((3, 2))
+        np.percentile(x, p, axis=1, out=y)
+        assert_equal(y, np.percentile(x, p, axis=1))
+
+        x = np.arange(12).reshape(3, 4)
+        # q.dim > 1, float
+        r0 = np.array([[2.,  3.,  4., 5.], [4., 5., 6., 7.]])
+        out = np.empty((2, 4))
+        assert_equal(np.percentile(x, (25, 50), axis=0, out=out), r0)
+        assert_equal(out, r0)
+        r1 = np.array([[0.75,  4.75,  8.75], [1.5,  5.5,  9.5]])
+        out = np.empty((2, 3))
+        assert_equal(np.percentile(x, (25, 50), axis=1, out=out), r1)
+        assert_equal(out, r1)
+
+        # q.dim > 1, int
+        r0 = np.array([[0,  1,  2, 3], [4, 5, 6, 7]])
+        out = np.empty((2, 4), dtype=x.dtype)
+        c = np.percentile(x, (25, 50), interpolation='lower', axis=0, out=out)
+        assert_equal(c, r0)
+        assert_equal(out, r0)
+        r1 = np.array([[0,  4,  8], [1,  5,  9]])
+        out = np.empty((2, 3), dtype=x.dtype)
+        c = np.percentile(x, (25, 50), interpolation='lower', axis=1, out=out)
+        assert_equal(c, r1)
+        assert_equal(out, r1)
+
+    def test_percentile_empty_dim(self):
+        # empty dims are preserved
+        d = np.arange(11 * 2).reshape(11, 1, 2, 1)
+        assert_array_equal(np.percentile(d, 50, axis=0).shape, (1, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=1).shape, (11, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=2).shape, (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=3).shape, (11, 1, 2))
+        assert_array_equal(np.percentile(d, 50, axis=-1).shape, (11, 1, 2))
+        assert_array_equal(np.percentile(d, 50, axis=-2).shape, (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-3).shape, (11, 2, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-4).shape, (1, 2, 1))
+
+        assert_array_equal(np.percentile(d, 50, axis=2,
+                                         interpolation='midpoint').shape,
+                           (11, 1, 1))
+        assert_array_equal(np.percentile(d, 50, axis=-2,
+                                         interpolation='midpoint').shape,
+                           (11, 1, 1))
+
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=0)).shape,
+                           (2, 1, 2, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=1)).shape,
+                           (2, 11, 2, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=2)).shape,
+                           (2, 11, 1, 1))
+        assert_array_equal(np.array(np.percentile(d, [10, 50], axis=3)).shape,
+                           (2, 11, 1, 2))
+
+    def test_percentile_no_overwrite(self):
+        a = np.array([2, 3, 4, 1])
+        np.percentile(a, [50], overwrite_input=False)
+        assert_equal(a, np.array([2, 3, 4, 1]))
+
+        a = np.array([2, 3, 4, 1])
+        np.percentile(a, [50])
+        assert_equal(a, np.array([2, 3, 4, 1]))
+
+    def test_no_p_overwrite(self):
+        p = np.linspace(0., 100., num=5)
+        np.percentile(np.arange(100.), p, interpolation="midpoint")
+        assert_array_equal(p, np.linspace(0., 100., num=5))
+        p = np.linspace(0., 100., num=5).tolist()
+        np.percentile(np.arange(100.), p, interpolation="midpoint")
+        assert_array_equal(p, np.linspace(0., 100., num=5).tolist())
+
+    def test_percentile_overwrite(self):
+        a = np.array([2, 3, 4, 1])
+        b = np.percentile(a, [50], overwrite_input=True)
+        assert_equal(b, np.array([2.5]))
+
+        b = np.percentile([2, 3, 4, 1], [50], overwrite_input=True)
+        assert_equal(b, np.array([2.5]))
+
+    def test_extended_axis(self):
+        o = np.random.normal(size=(71, 23))
+        x = np.dstack([o] * 10)
+        assert_equal(np.percentile(x, 30, axis=(0, 1)), np.percentile(o, 30))
+        x = np.rollaxis(x, -1, 0)
+        assert_equal(np.percentile(x, 30, axis=(-2, -1)), np.percentile(o, 30))
+        x = x.swapaxes(0, 1).copy()
+        assert_equal(np.percentile(x, 30, axis=(0, -1)), np.percentile(o, 30))
+        x = x.swapaxes(0, 1).copy()
+
+        assert_equal(np.percentile(x, [25, 60], axis=(0, 1, 2)),
+                     np.percentile(x, [25, 60], axis=None))
+        assert_equal(np.percentile(x, [25, 60], axis=(0,)),
+                     np.percentile(x, [25, 60], axis=0))
+
+        d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11)
+        np.random.shuffle(d)
+        assert_equal(np.percentile(d, 25,  axis=(0, 1, 2))[0],
+                     np.percentile(d[:,:,:, 0].flatten(), 25))
+        assert_equal(np.percentile(d, [10, 90], axis=(0, 1, 3))[:, 1],
+                     np.percentile(d[:,:, 1,:].flatten(), [10, 90]))
+        assert_equal(np.percentile(d, 25, axis=(3, 1, -4))[2],
+                     np.percentile(d[:,:, 2,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(3, 1, 2))[2],
+                     np.percentile(d[2,:,:,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(3, 2))[2, 1],
+                     np.percentile(d[2, 1,:,:].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(1, -2))[2, 1],
+                     np.percentile(d[2,:,:, 1].flatten(), 25))
+        assert_equal(np.percentile(d, 25, axis=(1, 3))[2, 2],
+                     np.percentile(d[2,:, 2,:].flatten(), 25))
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.percentile, d, axis=-5, q=25)
+        assert_raises(IndexError, np.percentile, d, axis=(0, -5), q=25)
+        assert_raises(IndexError, np.percentile, d, axis=4, q=25)
+        assert_raises(IndexError, np.percentile, d, axis=(0, 4), q=25)
+        assert_raises(ValueError, np.percentile, d, axis=(1, 1), q=25)
+
+    def test_keepdims(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_equal(np.percentile(d, 7, axis=None, keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.percentile(d, 7, axis=(0, 1), keepdims=True).shape,
+                     (1, 1, 7, 11))
+        assert_equal(np.percentile(d, 7, axis=(0, 3), keepdims=True).shape,
+                     (1, 5, 7, 1))
+        assert_equal(np.percentile(d, 7, axis=(1,), keepdims=True).shape,
+                     (3, 1, 7, 11))
+        assert_equal(np.percentile(d, 7, (0, 1, 2, 3), keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.percentile(d, 7, axis=(0, 1, 3), keepdims=True).shape,
+                     (1, 1, 7, 1))
+
+        assert_equal(np.percentile(d, [1, 7], axis=(0, 1, 3),
+                                   keepdims=True).shape, (2, 1, 1, 7, 1))
+        assert_equal(np.percentile(d, [1, 7], axis=(0, 3),
+                                   keepdims=True).shape, (2, 1, 5, 7, 1))
+
+    def test_out(self):
+        o = np.zeros((4,))
+        d = np.ones((3, 4))
+        assert_equal(np.percentile(d, 0, 0, out=o), o)
+        assert_equal(np.percentile(d, 0, 0, interpolation='nearest', out=o), o)
+        o = np.zeros((3,))
+        assert_equal(np.percentile(d, 1, 1, out=o), o)
+        assert_equal(np.percentile(d, 1, 1, interpolation='nearest', out=o), o)
+
+        o = np.zeros(())
+        assert_equal(np.percentile(d, 2, out=o), o)
+        assert_equal(np.percentile(d, 2, interpolation='nearest', out=o), o)
+
+    def test_out_nan(self):
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            o = np.zeros((4,))
+            d = np.ones((3, 4))
+            d[2, 1] = np.nan
+            assert_equal(np.percentile(d, 0, 0, out=o), o)
+            assert_equal(
+                np.percentile(d, 0, 0, interpolation='nearest', out=o), o)
+            o = np.zeros((3,))
+            assert_equal(np.percentile(d, 1, 1, out=o), o)
+            assert_equal(
+                np.percentile(d, 1, 1, interpolation='nearest', out=o), o)
+            o = np.zeros(())
+            assert_equal(np.percentile(d, 1, out=o), o)
+            assert_equal(
+                np.percentile(d, 1, interpolation='nearest', out=o), o)
+
+    def test_nan_behavior(self):
+        a = np.arange(24, dtype=float)
+        a[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3), np.nan)
+            assert_equal(np.percentile(a, 0.3, axis=0), np.nan)
+            assert_equal(np.percentile(a, [0.3, 0.6], axis=0),
+                         np.array([np.nan] * 2))
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+            assert_(w[2].category is RuntimeWarning)
+
+        a = np.arange(24, dtype=float).reshape(2, 3, 4)
+        a[1, 2, 3] = np.nan
+        a[1, 1, 2] = np.nan
+
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3), np.nan)
+            assert_equal(np.percentile(a, 0.3).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis0 zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 0)
+        b[2, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, 0), b)
+
+        # axis0 not zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], 0)
+        b[:, 2, 3] = np.nan
+        b[:, 1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], 0), b)
+
+        # axis1 zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 1)
+        b[1, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, 1), b)
+        # axis1 not zerod
+        b = np.percentile(
+            np.arange(24, dtype=float).reshape(2, 3, 4), [0.3, 0.6], 1)
+        b[:, 1, 3] = np.nan
+        b[:, 1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], 1), b)
+
+        # axis02 zerod
+        b = np.percentile(
+            np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, (0, 2))
+        b[1] = np.nan
+        b[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, 0.3, (0, 2)), b)
+        # axis02 not zerod
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], (0, 2))
+        b[:, 1] = np.nan
+        b[:, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(a, [0.3, 0.6], (0, 2)), b)
+        # axis02 not zerod with nearest interpolation
+        b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4),
+                          [0.3, 0.6], (0, 2), interpolation='nearest')
+        b[:, 1] = np.nan
+        b[:, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.percentile(
+                a, [0.3, 0.6], (0, 2), interpolation='nearest'), b)
+
+
+class TestMedian(TestCase):
+
+    def test_basic(self):
+        a0 = np.array(1)
+        a1 = np.arange(2)
+        a2 = np.arange(6).reshape(2, 3)
+        assert_equal(np.median(a0), 1)
+        assert_allclose(np.median(a1), 0.5)
+        assert_allclose(np.median(a2), 2.5)
+        assert_allclose(np.median(a2, axis=0), [1.5,  2.5,  3.5])
+        assert_equal(np.median(a2, axis=1), [1, 4])
+        assert_allclose(np.median(a2, axis=None), 2.5)
+
+        a = np.array([0.0444502, 0.0463301, 0.141249, 0.0606775])
+        assert_almost_equal((a[1] + a[3]) / 2., np.median(a))
+        a = np.array([0.0463301, 0.0444502, 0.141249])
+        assert_equal(a[0], np.median(a))
+        a = np.array([0.0444502, 0.141249, 0.0463301])
+        assert_equal(a[-1], np.median(a))
+        # check array scalar result
+        assert_equal(np.median(a).ndim, 0)
+        a[1] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_axis_keyword(self):
+        a3 = np.array([[2, 3],
+                       [0, 1],
+                       [6, 7],
+                       [4, 5]])
+        for a in [a3, np.random.randint(0, 100, size=(2, 3, 4))]:
+            orig = a.copy()
+            np.median(a, axis=None)
+            for ax in range(a.ndim):
+                np.median(a, axis=ax)
+            assert_array_equal(a, orig)
+
+        assert_allclose(np.median(a3, axis=0), [3,  4])
+        assert_allclose(np.median(a3.T, axis=1), [3,  4])
+        assert_allclose(np.median(a3), 3.5)
+        assert_allclose(np.median(a3, axis=None), 3.5)
+        assert_allclose(np.median(a3.T), 3.5)
+
+    def test_overwrite_keyword(self):
+        a3 = np.array([[2, 3],
+                       [0, 1],
+                       [6, 7],
+                       [4, 5]])
+        a0 = np.array(1)
+        a1 = np.arange(2)
+        a2 = np.arange(6).reshape(2, 3)
+        assert_allclose(np.median(a0.copy(), overwrite_input=True), 1)
+        assert_allclose(np.median(a1.copy(), overwrite_input=True), 0.5)
+        assert_allclose(np.median(a2.copy(), overwrite_input=True), 2.5)
+        assert_allclose(np.median(a2.copy(), overwrite_input=True, axis=0),
+                        [1.5,  2.5,  3.5])
+        assert_allclose(
+            np.median(a2.copy(), overwrite_input=True, axis=1), [1, 4])
+        assert_allclose(
+            np.median(a2.copy(), overwrite_input=True, axis=None), 2.5)
+        assert_allclose(
+            np.median(a3.copy(), overwrite_input=True, axis=0), [3,  4])
+        assert_allclose(np.median(a3.T.copy(), overwrite_input=True, axis=1),
+                        [3,  4])
+
+        a4 = np.arange(3 * 4 * 5, dtype=np.float32).reshape((3, 4, 5))
+        map(np.random.shuffle, a4)
+        assert_allclose(np.median(a4, axis=None),
+                        np.median(a4.copy(), axis=None, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=0),
+                        np.median(a4.copy(), axis=0, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=1),
+                        np.median(a4.copy(), axis=1, overwrite_input=True))
+        assert_allclose(np.median(a4, axis=2),
+                        np.median(a4.copy(), axis=2, overwrite_input=True))
+
+    def test_array_like(self):
+        x = [1, 2, 3]
+        assert_almost_equal(np.median(x), 2)
+        x2 = [x]
+        assert_almost_equal(np.median(x2), 2)
+        assert_allclose(np.median(x2, axis=0), x)
+
+    def test_subclass(self):
+        # gh-3846
+        class MySubClass(np.ndarray):
+
+            def __new__(cls, input_array, info=None):
+                obj = np.asarray(input_array).view(cls)
+                obj.info = info
+                return obj
+
+            def mean(self, axis=None, dtype=None, out=None):
+                return -7
+
+        a = MySubClass([1, 2, 3])
+        assert_equal(np.median(a), -7)
+
+    def test_out(self):
+        o = np.zeros((4,))
+        d = np.ones((3, 4))
+        assert_equal(np.median(d, 0, out=o), o)
+        o = np.zeros((3,))
+        assert_equal(np.median(d, 1, out=o), o)
+        o = np.zeros(())
+        assert_equal(np.median(d, out=o), o)
+
+    def test_out_nan(self):
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            o = np.zeros((4,))
+            d = np.ones((3, 4))
+            d[2, 1] = np.nan
+            assert_equal(np.median(d, 0, out=o), o)
+            o = np.zeros((3,))
+            assert_equal(np.median(d, 1, out=o), o)
+            o = np.zeros(())
+            assert_equal(np.median(d, out=o), o)
+
+    def test_nan_behavior(self):
+        a = np.arange(24, dtype=float)
+        a[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_equal(np.median(a, axis=0), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+            assert_(w[1].category is RuntimeWarning)
+
+        a = np.arange(24, dtype=float).reshape(2, 3, 4)
+        a[1, 2, 3] = np.nan
+        a[1, 1, 2] = np.nan
+
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_equal(np.median(a).ndim, 0)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis0
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 0)
+        b[2, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, 0), b)
+            assert_equal(len(w), 1)
+
+        # axis1
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 1)
+        b[1, 3] = np.nan
+        b[1, 2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, 1), b)
+            assert_equal(len(w), 1)
+
+        # axis02
+        b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), (0, 2))
+        b[1] = np.nan
+        b[2] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, (0, 2)), b)
+            assert_equal(len(w), 1)
+
+    def test_empty(self):
+        # empty arrays
+        a = np.array([], dtype=float)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+        # multiple dimensions
+        a = np.array([], dtype=float, ndmin=3)
+        # no axis
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a), np.nan)
+            assert_(w[0].category is RuntimeWarning)
+
+        # axis 0 and 1
+        b = np.array([], dtype=float, ndmin=2)
+        assert_equal(np.median(a, axis=0), b)
+        assert_equal(np.median(a, axis=1), b)
+
+        # axis 2
+        b = np.array(np.nan, dtype=float, ndmin=2)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.filterwarnings('always', '', RuntimeWarning)
+            assert_equal(np.median(a, axis=2), b)
+            assert_(w[0].category is RuntimeWarning)
+
+    def test_object(self):
+        o = np.arange(7.)
+        assert_(type(np.median(o.astype(object))), float)
+        o[2] = np.nan
+        assert_(type(np.median(o.astype(object))), float)
+
+    def test_extended_axis(self):
+        o = np.random.normal(size=(71, 23))
+        x = np.dstack([o] * 10)
+        assert_equal(np.median(x, axis=(0, 1)), np.median(o))
+        x = np.rollaxis(x, -1, 0)
+        assert_equal(np.median(x, axis=(-2, -1)), np.median(o))
+        x = x.swapaxes(0, 1).copy()
+        assert_equal(np.median(x, axis=(0, -1)), np.median(o))
+
+        assert_equal(np.median(x, axis=(0, 1, 2)), np.median(x, axis=None))
+        assert_equal(np.median(x, axis=(0, )), np.median(x, axis=0))
+        assert_equal(np.median(x, axis=(-1, )), np.median(x, axis=-1))
+
+        d = np.arange(3 * 5 * 7 * 11).reshape(3, 5, 7, 11)
+        np.random.shuffle(d)
+        assert_equal(np.median(d, axis=(0, 1, 2))[0],
+                     np.median(d[:,:,:, 0].flatten()))
+        assert_equal(np.median(d, axis=(0, 1, 3))[1],
+                     np.median(d[:,:, 1,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 1, -4))[2],
+                     np.median(d[:,:, 2,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 1, 2))[2],
+                     np.median(d[2,:,:,:].flatten()))
+        assert_equal(np.median(d, axis=(3, 2))[2, 1],
+                     np.median(d[2, 1,:,:].flatten()))
+        assert_equal(np.median(d, axis=(1, -2))[2, 1],
+                     np.median(d[2,:,:, 1].flatten()))
+        assert_equal(np.median(d, axis=(1, 3))[2, 2],
+                     np.median(d[2,:, 2,:].flatten()))
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.median, d, axis=-5)
+        assert_raises(IndexError, np.median, d, axis=(0, -5))
+        assert_raises(IndexError, np.median, d, axis=4)
+        assert_raises(IndexError, np.median, d, axis=(0, 4))
+        assert_raises(ValueError, np.median, d, axis=(1, 1))
+
+    def test_keepdims(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_equal(np.median(d, axis=None, keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.median(d, axis=(0, 1), keepdims=True).shape,
+                     (1, 1, 7, 11))
+        assert_equal(np.median(d, axis=(0, 3), keepdims=True).shape,
+                     (1, 5, 7, 1))
+        assert_equal(np.median(d, axis=(1,), keepdims=True).shape,
+                     (3, 1, 7, 11))
+        assert_equal(np.median(d, axis=(0, 1, 2, 3), keepdims=True).shape,
+                     (1, 1, 1, 1))
+        assert_equal(np.median(d, axis=(0, 1, 3), keepdims=True).shape,
+                     (1, 1, 7, 1))
+
+
+class TestAdd_newdoc_ufunc(TestCase):
+
+    def test_ufunc_arg(self):
+        assert_raises(TypeError, add_newdoc_ufunc, 2, "blah")
+        assert_raises(ValueError, add_newdoc_ufunc, np.add, "blah")
+
+    def test_string_arg(self):
+        assert_raises(TypeError, add_newdoc_ufunc, np.add, 3)
+
+
+class TestAdd_newdoc(TestCase):
+
+    @dec.skipif(sys.flags.optimize == 2)
+    def test_add_doc(self):
+        # test np.add_newdoc
+        tgt = "Current flat index into the array."
+        self.assertEqual(np.core.flatiter.index.__doc__[:len(tgt)], tgt)
+        self.assertTrue(len(np.core.ufunc.identity.__doc__) > 300)
+        self.assertTrue(len(np.lib.index_tricks.mgrid.__doc__) > 300)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
new file mode 100644
index 0000000000..bb2ae15096
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
@@ -0,0 +1,326 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, assert_array_almost_equal, assert_raises
+    )
+from numpy.lib.index_tricks import (
+    mgrid, ndenumerate, fill_diagonal, diag_indices, diag_indices_from,
+    index_exp, ndindex, r_, s_, ix_
+    )
+
+
+class TestRavelUnravelIndex(TestCase):
+    def test_basic(self):
+        assert_equal(np.unravel_index(2, (2, 2)), (1, 0))
+        assert_equal(np.ravel_multi_index((1, 0), (2, 2)), 2)
+        assert_equal(np.unravel_index(254, (17, 94)), (2, 66))
+        assert_equal(np.ravel_multi_index((2, 66), (17, 94)), 254)
+        assert_raises(ValueError, np.unravel_index, -1, (2, 2))
+        assert_raises(TypeError, np.unravel_index, 0.5, (2, 2))
+        assert_raises(ValueError, np.unravel_index, 4, (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (-3, 1), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (2, 1), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (0, -3), (2, 2))
+        assert_raises(ValueError, np.ravel_multi_index, (0, 2), (2, 2))
+        assert_raises(TypeError, np.ravel_multi_index, (0.1, 0.), (2, 2))
+
+        assert_equal(np.unravel_index((2*3 + 1)*6 + 4, (4, 3, 6)), [2, 1, 4])
+        assert_equal(
+            np.ravel_multi_index([2, 1, 4], (4, 3, 6)), (2*3 + 1)*6 + 4)
+
+        arr = np.array([[3, 6, 6], [4, 5, 1]])
+        assert_equal(np.ravel_multi_index(arr, (7, 6)), [22, 41, 37])
+        assert_equal(
+            np.ravel_multi_index(arr, (7, 6), order='F'), [31, 41, 13])
+        assert_equal(
+            np.ravel_multi_index(arr, (4, 6), mode='clip'), [22, 23, 19])
+        assert_equal(np.ravel_multi_index(arr, (4, 4), mode=('clip', 'wrap')),
+                     [12, 13, 13])
+        assert_equal(np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9)), 1621)
+
+        assert_equal(np.unravel_index(np.array([22, 41, 37]), (7, 6)),
+                     [[3, 6, 6], [4, 5, 1]])
+        assert_equal(
+            np.unravel_index(np.array([31, 41, 13]), (7, 6), order='F'),
+            [[3, 6, 6], [4, 5, 1]])
+        assert_equal(np.unravel_index(1621, (6, 7, 8, 9)), [3, 1, 4, 1])
+
+    def test_dtypes(self):
+        # Test with different data types
+        for dtype in [np.int16, np.uint16, np.int32,
+                      np.uint32, np.int64, np.uint64]:
+            coords = np.array(
+                [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0]], dtype=dtype)
+            shape = (5, 8)
+            uncoords = 8*coords[0]+coords[1]
+            assert_equal(np.ravel_multi_index(coords, shape), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape))
+            uncoords = coords[0]+5*coords[1]
+            assert_equal(
+                np.ravel_multi_index(coords, shape, order='F'), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape, order='F'))
+
+            coords = np.array(
+                [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0], [1, 3, 1, 0, 9, 5]],
+                dtype=dtype)
+            shape = (5, 8, 10)
+            uncoords = 10*(8*coords[0]+coords[1])+coords[2]
+            assert_equal(np.ravel_multi_index(coords, shape), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape))
+            uncoords = coords[0]+5*(coords[1]+8*coords[2])
+            assert_equal(
+                np.ravel_multi_index(coords, shape, order='F'), uncoords)
+            assert_equal(coords, np.unravel_index(uncoords, shape, order='F'))
+
+    def test_clipmodes(self):
+        # Test clipmodes
+        assert_equal(
+            np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12), mode='wrap'),
+            np.ravel_multi_index([1, 1, 6, 2], (4, 3, 7, 12)))
+        assert_equal(np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12),
+                                          mode=(
+                                              'wrap', 'raise', 'clip', 'raise')),
+                     np.ravel_multi_index([1, 1, 0, 2], (4, 3, 7, 12)))
+        assert_raises(
+            ValueError, np.ravel_multi_index, [5, 1, -1, 2], (4, 3, 7, 12))
+
+
+class TestGrid(TestCase):
+    def test_basic(self):
+        a = mgrid[-1:1:10j]
+        b = mgrid[-1:1:0.1]
+        assert_(a.shape == (10,))
+        assert_(b.shape == (20,))
+        assert_(a[0] == -1)
+        assert_almost_equal(a[-1], 1)
+        assert_(b[0] == -1)
+        assert_almost_equal(b[1]-b[0], 0.1, 11)
+        assert_almost_equal(b[-1], b[0]+19*0.1, 11)
+        assert_almost_equal(a[1]-a[0], 2.0/9.0, 11)
+
+    def test_linspace_equivalence(self):
+        y, st = np.linspace(2, 10, retstep=1)
+        assert_almost_equal(st, 8/49.0)
+        assert_array_almost_equal(y, mgrid[2:10:50j], 13)
+
+    def test_nd(self):
+        c = mgrid[-1:1:10j, -2:2:10j]
+        d = mgrid[-1:1:0.1, -2:2:0.2]
+        assert_(c.shape == (2, 10, 10))
+        assert_(d.shape == (2, 20, 20))
+        assert_array_equal(c[0][0, :], -np.ones(10, 'd'))
+        assert_array_equal(c[1][:, 0], -2*np.ones(10, 'd'))
+        assert_array_almost_equal(c[0][-1, :], np.ones(10, 'd'), 11)
+        assert_array_almost_equal(c[1][:, -1], 2*np.ones(10, 'd'), 11)
+        assert_array_almost_equal(d[0, 1, :] - d[0, 0, :],
+                                  0.1*np.ones(20, 'd'), 11)
+        assert_array_almost_equal(d[1, :, 1] - d[1, :, 0],
+                                  0.2*np.ones(20, 'd'), 11)
+
+
+class TestConcatenator(TestCase):
+    def test_1d(self):
+        assert_array_equal(r_[1, 2, 3, 4, 5, 6], np.array([1, 2, 3, 4, 5, 6]))
+        b = np.ones(5)
+        c = r_[b, 0, 0, b]
+        assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1])
+
+    def test_mixed_type(self):
+        g = r_[10.1, 1:10]
+        assert_(g.dtype == 'f8')
+
+    def test_more_mixed_type(self):
+        g = r_[-10.1, np.array([1]), np.array([2, 3, 4]), 10.0]
+        assert_(g.dtype == 'f8')
+
+    def test_2d(self):
+        b = np.random.rand(5, 5)
+        c = np.random.rand(5, 5)
+        d = r_['1', b, c]  # append columns
+        assert_(d.shape == (5, 10))
+        assert_array_equal(d[:, :5], b)
+        assert_array_equal(d[:, 5:], c)
+        d = r_[b, c]
+        assert_(d.shape == (10, 5))
+        assert_array_equal(d[:5, :], b)
+        assert_array_equal(d[5:, :], c)
+
+
+class TestNdenumerate(TestCase):
+    def test_basic(self):
+        a = np.array([[1, 2], [3, 4]])
+        assert_equal(list(ndenumerate(a)),
+                     [((0, 0), 1), ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)])
+
+
+class TestIndexExpression(TestCase):
+    def test_regression_1(self):
+        # ticket #1196
+        a = np.arange(2)
+        assert_equal(a[:-1], a[s_[:-1]])
+        assert_equal(a[:-1], a[index_exp[:-1]])
+
+    def test_simple_1(self):
+        a = np.random.rand(4, 5, 6)
+
+        assert_equal(a[:, :3, [1, 2]], a[index_exp[:, :3, [1, 2]]])
+        assert_equal(a[:, :3, [1, 2]], a[s_[:, :3, [1, 2]]])
+
+
+class TestIx_(TestCase):
+    def test_regression_1(self):
+        # Test empty inputs create ouputs of indexing type, gh-5804
+        # Test both lists and arrays
+        for func in (range, np.arange):
+            a, = np.ix_(func(0))
+            assert_equal(a.dtype, np.intp)
+
+    def test_shape_and_dtype(self):
+        sizes = (4, 5, 3, 2)
+        # Test both lists and arrays
+        for func in (range, np.arange):
+            arrays = np.ix_(*[func(sz) for sz in sizes])
+            for k, (a, sz) in enumerate(zip(arrays, sizes)):
+                assert_equal(a.shape[k], sz)
+                assert_(all(sh == 1 for j, sh in enumerate(a.shape) if j != k))
+                assert_(np.issubdtype(a.dtype, int))
+
+    def test_bool(self):
+        bool_a = [True, False, True, True]
+        int_a, = np.nonzero(bool_a)
+        assert_equal(np.ix_(bool_a)[0], int_a)
+
+    def test_1d_only(self):
+        idx2d = [[1, 2, 3], [4, 5, 6]]
+        assert_raises(ValueError, np.ix_, idx2d)
+
+    def test_repeated_input(self):
+        length_of_vector = 5
+        x = np.arange(length_of_vector)
+        out = ix_(x, x)
+        assert_equal(out[0].shape, (length_of_vector, 1))
+        assert_equal(out[1].shape, (1, length_of_vector))
+        # check that input shape is not modified
+        assert_equal(x.shape, (length_of_vector,))
+
+
+def test_c_():
+    a = np.c_[np.array([[1, 2, 3]]), 0, 0, np.array([[4, 5, 6]])]
+    assert_equal(a, [[1, 2, 3, 0, 0, 4, 5, 6]])
+
+
+def test_fill_diagonal():
+    a = np.zeros((3, 3), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5]]))
+
+    #Test tall matrix
+    a = np.zeros((10, 3), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0],
+                  [0, 0, 0]]))
+
+    #Test tall matrix wrap
+    a = np.zeros((10, 3), int)
+    fill_diagonal(a, 5, True)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [5, 0, 0],
+                  [0, 5, 0],
+                  [0, 0, 5],
+                  [0, 0, 0],
+                  [5, 0, 0],
+                  [0, 5, 0]]))
+
+    #Test wide matrix
+    a = np.zeros((3, 10), int)
+    fill_diagonal(a, 5)
+    yield (assert_array_equal, a,
+           np.array([[5, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+                  [0, 5, 0, 0, 0, 0, 0, 0, 0, 0],
+                  [0, 0, 5, 0, 0, 0, 0, 0, 0, 0]]))
+
+    # The same function can operate on a 4-d array:
+    a = np.zeros((3, 3, 3, 3), int)
+    fill_diagonal(a, 4)
+    i = np.array([0, 1, 2])
+    yield (assert_equal, np.where(a != 0), (i, i, i, i))
+
+
+def test_diag_indices():
+    di = diag_indices(4)
+    a = np.array([[1, 2, 3, 4],
+               [5, 6, 7, 8],
+               [9, 10, 11, 12],
+               [13, 14, 15, 16]])
+    a[di] = 100
+    yield (assert_array_equal, a,
+           np.array([[100, 2, 3, 4],
+                  [5, 100, 7, 8],
+                  [9, 10, 100, 12],
+                  [13, 14, 15, 100]]))
+
+    # Now, we create indices to manipulate a 3-d array:
+    d3 = diag_indices(2, 3)
+
+    # And use it to set the diagonal of a zeros array to 1:
+    a = np.zeros((2, 2, 2), int)
+    a[d3] = 1
+    yield (assert_array_equal, a,
+           np.array([[[1, 0],
+                   [0, 0]],
+
+                  [[0, 0],
+                   [0, 1]]]))
+
+
+def test_diag_indices_from():
+    x = np.random.random((4, 4))
+    r, c = diag_indices_from(x)
+    assert_array_equal(r, np.arange(4))
+    assert_array_equal(c, np.arange(4))
+
+
+def test_ndindex():
+    x = list(ndindex(1, 2, 3))
+    expected = [ix for ix, e in ndenumerate(np.zeros((1, 2, 3)))]
+    assert_array_equal(x, expected)
+
+    x = list(ndindex((1, 2, 3)))
+    assert_array_equal(x, expected)
+
+    # Test use of scalars and tuples
+    x = list(ndindex((3,)))
+    assert_array_equal(x, list(ndindex(3)))
+
+    # Make sure size argument is optional
+    x = list(ndindex())
+    assert_equal(x, [()])
+
+    x = list(ndindex(()))
+    assert_equal(x, [()])
+
+    # Make sure 0-sized ndindex works correctly
+    x = list(ndindex(*[0]))
+    assert_equal(x, [])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_io.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
new file mode 100644
index 0000000000..226dc88faa
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
@@ -0,0 +1,1888 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import gzip
+import os
+import threading
+from tempfile import NamedTemporaryFile
+import time
+import warnings
+import gc
+from io import BytesIO
+from datetime import datetime
+
+import numpy as np
+import numpy.ma as ma
+from numpy.lib._iotools import ConverterError, ConversionWarning
+from numpy.compat import asbytes, bytes, unicode
+from numpy.ma.testutils import assert_equal
+from numpy.testing import (
+    TestCase, run_module_suite, assert_warns, assert_,
+    assert_raises_regex, assert_raises, assert_allclose,
+    assert_array_equal,temppath
+)
+from numpy.testing.utils import tempdir
+
+
+class TextIO(BytesIO):
+    """Helper IO class.
+
+    Writes encode strings to bytes if needed, reads return bytes.
+    This makes it easier to emulate files opened in binary mode
+    without needing to explicitly convert strings to bytes in
+    setting up the test data.
+
+    """
+    def __init__(self, s=""):
+        BytesIO.__init__(self, asbytes(s))
+
+    def write(self, s):
+        BytesIO.write(self, asbytes(s))
+
+    def writelines(self, lines):
+        BytesIO.writelines(self, [asbytes(s) for s in lines])
+
+
+MAJVER, MINVER = sys.version_info[:2]
+IS_64BIT = sys.maxsize > 2**32
+
+
+def strptime(s, fmt=None):
+    """
+    This function is available in the datetime module only from Python >=
+    2.5.
+
+    """
+    if sys.version_info[0] >= 3:
+        return datetime(*time.strptime(s.decode('latin1'), fmt)[:3])
+    else:
+        return datetime(*time.strptime(s, fmt)[:3])
+
+
+class RoundtripTest(object):
+    def roundtrip(self, save_func, *args, **kwargs):
+        """
+        save_func : callable
+            Function used to save arrays to file.
+        file_on_disk : bool
+            If true, store the file on disk, instead of in a
+            string buffer.
+        save_kwds : dict
+            Parameters passed to `save_func`.
+        load_kwds : dict
+            Parameters passed to `numpy.load`.
+        args : tuple of arrays
+            Arrays stored to file.
+
+        """
+        save_kwds = kwargs.get('save_kwds', {})
+        load_kwds = kwargs.get('load_kwds', {})
+        file_on_disk = kwargs.get('file_on_disk', False)
+
+        if file_on_disk:
+            target_file = NamedTemporaryFile(delete=False)
+            load_file = target_file.name
+        else:
+            target_file = BytesIO()
+            load_file = target_file
+
+        try:
+            arr = args
+
+            save_func(target_file, *arr, **save_kwds)
+            target_file.flush()
+            target_file.seek(0)
+
+            if sys.platform == 'win32' and not isinstance(target_file, BytesIO):
+                target_file.close()
+
+            arr_reloaded = np.load(load_file, **load_kwds)
+
+            self.arr = arr
+            self.arr_reloaded = arr_reloaded
+        finally:
+            if not isinstance(target_file, BytesIO):
+                target_file.close()
+                # holds an open file descriptor so it can't be deleted on win
+                if not isinstance(arr_reloaded, np.lib.npyio.NpzFile):
+                    os.remove(target_file.name)
+
+    def check_roundtrips(self, a):
+        self.roundtrip(a)
+        self.roundtrip(a, file_on_disk=True)
+        self.roundtrip(np.asfortranarray(a))
+        self.roundtrip(np.asfortranarray(a), file_on_disk=True)
+        if a.shape[0] > 1:
+            # neither C nor Fortran contiguous for 2D arrays or more
+            self.roundtrip(np.asfortranarray(a)[1:])
+            self.roundtrip(np.asfortranarray(a)[1:], file_on_disk=True)
+
+    def test_array(self):
+        a = np.array([], float)
+        self.check_roundtrips(a)
+
+        a = np.array([[1, 2], [3, 4]], float)
+        self.check_roundtrips(a)
+
+        a = np.array([[1, 2], [3, 4]], int)
+        self.check_roundtrips(a)
+
+        a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.csingle)
+        self.check_roundtrips(a)
+
+        a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.cdouble)
+        self.check_roundtrips(a)
+
+    def test_array_object(self):
+        if sys.version_info[:2] >= (2, 7):
+            a = np.array([], object)
+            self.check_roundtrips(a)
+
+            a = np.array([[1, 2], [3, 4]], object)
+            self.check_roundtrips(a)
+        # Fails with UnpicklingError: could not find MARK on Python 2.6
+
+    def test_1D(self):
+        a = np.array([1, 2, 3, 4], int)
+        self.roundtrip(a)
+
+    @np.testing.dec.knownfailureif(sys.platform == 'win32', "Fail on Win32")
+    def test_mmap(self):
+        a = np.array([[1, 2.5], [4, 7.3]])
+        self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'})
+
+        a = np.asfortranarray([[1, 2.5], [4, 7.3]])
+        self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'})
+
+    def test_record(self):
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        self.check_roundtrips(a)
+
+    def test_format_2_0(self):
+        dt = [(("%d" % i) * 100, float) for i in range(500)]
+        a = np.ones(1000, dtype=dt)
+        with warnings.catch_warnings(record=True):
+            warnings.filterwarnings('always', '', UserWarning)
+            self.check_roundtrips(a)
+
+
+class TestSaveLoad(RoundtripTest, TestCase):
+    def roundtrip(self, *args, **kwargs):
+        RoundtripTest.roundtrip(self, np.save, *args, **kwargs)
+        assert_equal(self.arr[0], self.arr_reloaded)
+        assert_equal(self.arr[0].dtype, self.arr_reloaded.dtype)
+        assert_equal(self.arr[0].flags.fnc, self.arr_reloaded.flags.fnc)
+
+
+class TestSavezLoad(RoundtripTest, TestCase):
+    def roundtrip(self, *args, **kwargs):
+        RoundtripTest.roundtrip(self, np.savez, *args, **kwargs)
+        try:
+            for n, arr in enumerate(self.arr):
+                reloaded = self.arr_reloaded['arr_%d' % n]
+                assert_equal(arr, reloaded)
+                assert_equal(arr.dtype, reloaded.dtype)
+                assert_equal(arr.flags.fnc, reloaded.flags.fnc)
+        finally:
+            # delete tempfile, must be done here on windows
+            if self.arr_reloaded.fid:
+                self.arr_reloaded.fid.close()
+                os.remove(self.arr_reloaded.fid.name)
+
+    @np.testing.dec.skipif(not IS_64BIT, "Works only with 64bit systems")
+    @np.testing.dec.slow
+    def test_big_arrays(self):
+        L = (1 << 31) + 100000
+        a = np.empty(L, dtype=np.uint8)
+        with temppath(prefix="numpy_test_big_arrays_", suffix=".npz") as tmp:
+            np.savez(tmp, a=a)
+            del a
+            npfile = np.load(tmp)
+            a = npfile['a']  # Should succeed
+            npfile.close()
+            del a  # Avoid pyflakes unused variable warning.
+
+    def test_multiple_arrays(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        self.roundtrip(a, b)
+
+    def test_named_arrays(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        c = BytesIO()
+        np.savez(c, file_a=a, file_b=b)
+        c.seek(0)
+        l = np.load(c)
+        assert_equal(a, l['file_a'])
+        assert_equal(b, l['file_b'])
+
+    def test_BagObj(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex)
+        c = BytesIO()
+        np.savez(c, file_a=a, file_b=b)
+        c.seek(0)
+        l = np.load(c)
+        assert_equal(sorted(dir(l.f)), ['file_a','file_b'])
+        assert_equal(a, l.f.file_a)
+        assert_equal(b, l.f.file_b)
+
+    def test_savez_filename_clashes(self):
+        # Test that issue #852 is fixed
+        # and savez functions in multithreaded environment
+
+        def writer(error_list):
+            with temppath(suffix='.npz') as tmp:
+                arr = np.random.randn(500, 500)
+                try:
+                    np.savez(tmp, arr=arr)
+                except OSError as err:
+                    error_list.append(err)
+
+        errors = []
+        threads = [threading.Thread(target=writer, args=(errors,))
+                   for j in range(3)]
+        for t in threads:
+            t.start()
+        for t in threads:
+            t.join()
+
+        if errors:
+            raise AssertionError(errors)
+
+    def test_not_closing_opened_fid(self):
+        # Test that issue #2178 is fixed:
+        # verify could seek on 'loaded' file
+        with temppath(suffix='.npz') as tmp:
+            with open(tmp, 'wb') as fp:
+                np.savez(fp, data='LOVELY LOAD')
+            with open(tmp, 'rb', 10000) as fp:
+                fp.seek(0)
+                assert_(not fp.closed)
+                np.load(fp)['data']
+                # fp must not get closed by .load
+                assert_(not fp.closed)
+                fp.seek(0)
+                assert_(not fp.closed)
+
+    def test_closing_fid(self):
+        # Test that issue #1517 (too many opened files) remains closed
+        # It might be a "weak" test since failed to get triggered on
+        # e.g. Debian sid of 2012 Jul 05 but was reported to
+        # trigger the failure on Ubuntu 10.04:
+        # http://projects.scipy.org/numpy/ticket/1517#comment:2
+        with temppath(suffix='.npz') as tmp:
+            np.savez(tmp, data='LOVELY LOAD')
+            # We need to check if the garbage collector can properly close
+            # numpy npz file returned by np.load when their reference count
+            # goes to zero.  Python 3 running in debug mode raises a
+            # ResourceWarning when file closing is left to the garbage
+            # collector, so we catch the warnings.  Because ResourceWarning
+            # is unknown in Python < 3.x, we take the easy way out and
+            # catch all warnings.
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore")
+                for i in range(1, 1025):
+                    try:
+                        np.load(tmp)["data"]
+                    except Exception as e:
+                        msg = "Failed to load data from a file: %s" % e
+                        raise AssertionError(msg)
+
+    def test_closing_zipfile_after_load(self):
+        # Check that zipfile owns file and can close it.  This needs to
+        # pass a file name to load for the test. On windows failure will
+        # cause a second error will be raised when the attempt to remove
+        # the open file is made.
+        prefix = 'numpy_test_closing_zipfile_after_load_'
+        with temppath(suffix='.npz', prefix=prefix) as tmp:
+            np.savez(tmp, lab='place holder')
+            data = np.load(tmp)
+            fp = data.zip.fp
+            data.close()
+            assert_(fp.closed)
+
+
+class TestSaveTxt(TestCase):
+    def test_array(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        fmt = "%.18e"
+        c = BytesIO()
+        np.savetxt(c, a, fmt=fmt)
+        c.seek(0)
+        assert_equal(c.readlines(),
+                     [asbytes((fmt + ' ' + fmt + '\n') % (1, 2)),
+                      asbytes((fmt + ' ' + fmt + '\n') % (3, 4))])
+
+        a = np.array([[1, 2], [3, 4]], int)
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1 2\n', b'3 4\n'])
+
+    def test_1D(self):
+        a = np.array([1, 2, 3, 4], int)
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'1\n', b'2\n', b'3\n', b'4\n'])
+
+    def test_record(self):
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1 2\n', b'3 4\n'])
+
+    def test_delimiter(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        c = BytesIO()
+        np.savetxt(c, a, delimiter=',', fmt='%d')
+        c.seek(0)
+        assert_equal(c.readlines(), [b'1,2\n', b'3,4\n'])
+
+    def test_format(self):
+        a = np.array([(1, 2), (3, 4)])
+        c = BytesIO()
+        # Sequence of formats
+        np.savetxt(c, a, fmt=['%02d', '%3.1f'])
+        c.seek(0)
+        assert_equal(c.readlines(), [b'01 2.0\n', b'03 4.0\n'])
+
+        # A single multiformat string
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%02d : %3.1f')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n'])
+
+        # Specify delimiter, should be overiden
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%02d : %3.1f', delimiter=',')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n'])
+
+        # Bad fmt, should raise a ValueError
+        c = BytesIO()
+        assert_raises(ValueError, np.savetxt, c, a, fmt=99)
+
+    def test_header_footer(self):
+        # Test the functionality of the header and footer keyword argument.
+
+        c = BytesIO()
+        a = np.array([(1, 2), (3, 4)], dtype=np.int)
+        test_header_footer = 'Test header / footer'
+        # Test the header keyword argument
+        np.savetxt(c, a, fmt='%1d', header=test_header_footer)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('# ' + test_header_footer + '\n1 2\n3 4\n'))
+        # Test the footer keyword argument
+        c = BytesIO()
+        np.savetxt(c, a, fmt='%1d', footer=test_header_footer)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('1 2\n3 4\n# ' + test_header_footer + '\n'))
+        # Test the commentstr keyword argument used on the header
+        c = BytesIO()
+        commentstr = '% '
+        np.savetxt(c, a, fmt='%1d',
+                   header=test_header_footer, comments=commentstr)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes(commentstr + test_header_footer + '\n' + '1 2\n3 4\n'))
+        # Test the commentstr keyword argument used on the footer
+        c = BytesIO()
+        commentstr = '% '
+        np.savetxt(c, a, fmt='%1d',
+                   footer=test_header_footer, comments=commentstr)
+        c.seek(0)
+        assert_equal(c.read(),
+                     asbytes('1 2\n3 4\n' + commentstr + test_header_footer + '\n'))
+
+    def test_file_roundtrip(self):
+        with temppath() as name:
+            a = np.array([(1, 2), (3, 4)])
+            np.savetxt(name, a)
+            b = np.loadtxt(name)
+            assert_array_equal(a, b)
+
+    def test_complex_arrays(self):
+        ncols = 2
+        nrows = 2
+        a = np.zeros((ncols, nrows), dtype=np.complex128)
+        re = np.pi
+        im = np.e
+        a[:] = re + 1.0j * im
+
+        # One format only
+        c = BytesIO()
+        np.savetxt(c, a, fmt=' %+.3e')
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b' ( +3.142e+00+ +2.718e+00j)  ( +3.142e+00+ +2.718e+00j)\n',
+             b' ( +3.142e+00+ +2.718e+00j)  ( +3.142e+00+ +2.718e+00j)\n'])
+
+        # One format for each real and imaginary part
+        c = BytesIO()
+        np.savetxt(c, a, fmt='  %+.3e' * 2 * ncols)
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b'  +3.142e+00  +2.718e+00  +3.142e+00  +2.718e+00\n',
+             b'  +3.142e+00  +2.718e+00  +3.142e+00  +2.718e+00\n'])
+
+        # One format for each complex number
+        c = BytesIO()
+        np.savetxt(c, a, fmt=['(%.3e%+.3ej)'] * ncols)
+        c.seek(0)
+        lines = c.readlines()
+        assert_equal(
+            lines,
+            [b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n',
+             b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n'])
+
+    def test_custom_writer(self):
+
+        class CustomWriter(list):
+            def write(self, text):
+                self.extend(text.split(b'\n'))
+
+        w = CustomWriter()
+        a = np.array([(1, 2), (3, 4)])
+        np.savetxt(w, a)
+        b = np.loadtxt(w)
+        assert_array_equal(a, b)
+
+
+class TestLoadTxt(TestCase):
+    def test_record(self):
+        c = TextIO()
+        c.write('1 2\n3 4')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=[('x', np.int32), ('y', np.int32)])
+        a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        assert_array_equal(x, a)
+
+        d = TextIO()
+        d.write('M 64.0 75.0\nF 25.0 60.0')
+        d.seek(0)
+        mydescriptor = {'names': ('gender', 'age', 'weight'),
+                        'formats': ('S1', 'i4', 'f4')}
+        b = np.array([('M', 64.0, 75.0),
+                      ('F', 25.0, 60.0)], dtype=mydescriptor)
+        y = np.loadtxt(d, dtype=mydescriptor)
+        assert_array_equal(y, b)
+
+    def test_array(self):
+        c = TextIO()
+        c.write('1 2\n3 4')
+
+        c.seek(0)
+        x = np.loadtxt(c, dtype=np.int)
+        a = np.array([[1, 2], [3, 4]], int)
+        assert_array_equal(x, a)
+
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float)
+        a = np.array([[1, 2], [3, 4]], float)
+        assert_array_equal(x, a)
+
+    def test_1D(self):
+        c = TextIO()
+        c.write('1\n2\n3\n4\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int)
+        a = np.array([1, 2, 3, 4], int)
+        assert_array_equal(x, a)
+
+        c = TextIO()
+        c.write('1,2,3,4\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',')
+        a = np.array([1, 2, 3, 4], int)
+        assert_array_equal(x, a)
+
+    def test_missing(self):
+        c = TextIO()
+        c.write('1,2,3,,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       converters={3: lambda s: int(s or - 999)})
+        a = np.array([1, 2, 3, -999, 5], int)
+        assert_array_equal(x, a)
+
+    def test_converters_with_usecols(self):
+        c = TextIO()
+        c.write('1,2,3,,5\n6,7,8,9,10\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       converters={3: lambda s: int(s or - 999)},
+                       usecols=(1, 3,))
+        a = np.array([[2, -999], [7, 9]], int)
+        assert_array_equal(x, a)
+
+    def test_comments_unicode(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=unicode('#'))
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_comments_byte(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=b'#')
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_comments_multiple(self):
+        c = TextIO()
+        c.write('# comment\n1,2,3\n@ comment2\n4,5,6 // comment3')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments=['#', '@', '//'])
+        a = np.array([[1, 2, 3], [4, 5, 6]], int)
+        assert_array_equal(x, a)
+
+    def test_comments_multi_chars(self):
+        c = TextIO()
+        c.write('/* comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       comments='/*')
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+        # Check that '/*' is not transformed to ['/', '*']
+        c = TextIO()
+        c.write('*/ comment\n1,2,3,5\n')
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, dtype=int, delimiter=',',
+                      comments='/*')
+
+    def test_skiprows(self):
+        c = TextIO()
+        c.write('comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       skiprows=1)
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+        c = TextIO()
+        c.write('# comment\n1,2,3,5\n')
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',',
+                       skiprows=1)
+        a = np.array([1, 2, 3, 5], int)
+        assert_array_equal(x, a)
+
+    def test_usecols(self):
+        a = np.array([[1, 2], [3, 4]], float)
+        c = BytesIO()
+        np.savetxt(c, a)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=(1,))
+        assert_array_equal(x, a[:, 1])
+
+        a = np.array([[1, 2, 3], [3, 4, 5]], float)
+        c = BytesIO()
+        np.savetxt(c, a)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=(1, 2))
+        assert_array_equal(x, a[:, 1:])
+
+        # Testing with arrays instead of tuples.
+        c.seek(0)
+        x = np.loadtxt(c, dtype=float, usecols=np.array([1, 2]))
+        assert_array_equal(x, a[:, 1:])
+
+        # Checking with dtypes defined converters.
+        data = '''JOE 70.1 25.3
+                BOB 60.5 27.9
+                '''
+        c = TextIO(data)
+        names = ['stid', 'temp']
+        dtypes = ['S4', 'f8']
+        arr = np.loadtxt(c, usecols=(0, 2), dtype=list(zip(names, dtypes)))
+        assert_equal(arr['stid'], [b"JOE", b"BOB"])
+        assert_equal(arr['temp'], [25.3, 27.9])
+
+    def test_fancy_dtype(self):
+        c = TextIO()
+        c.write('1,2,3.0\n4,5,6.0\n')
+        c.seek(0)
+        dt = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        x = np.loadtxt(c, dtype=dt, delimiter=',')
+        a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dt)
+        assert_array_equal(x, a)
+
+    def test_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 3))])
+        x = np.loadtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_3d_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6 7 8 9 10 11 12")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 2, 3))])
+        x = np.loadtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0,
+                       [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_empty_file(self):
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="loadtxt: Empty input file:")
+            c = TextIO()
+            x = np.loadtxt(c)
+            assert_equal(x.shape, (0,))
+            x = np.loadtxt(c, dtype=np.int64)
+            assert_equal(x.shape, (0,))
+            assert_(x.dtype == np.int64)
+
+    def test_unused_converter(self):
+        c = TextIO()
+        c.writelines(['1 21\n', '3 42\n'])
+        c.seek(0)
+        data = np.loadtxt(c, usecols=(1,),
+                          converters={0: lambda s: int(s, 16)})
+        assert_array_equal(data, [21, 42])
+
+        c.seek(0)
+        data = np.loadtxt(c, usecols=(1,),
+                          converters={1: lambda s: int(s, 16)})
+        assert_array_equal(data, [33, 66])
+
+    def test_dtype_with_object(self):
+        # Test using an explicit dtype with an object
+        data = """ 1; 2001-01-01
+                   2; 2002-01-31 """
+        ndtype = [('idx', int), ('code', np.object)]
+        func = lambda s: strptime(s.strip(), "%Y-%m-%d")
+        converters = {1: func}
+        test = np.loadtxt(TextIO(data), delimiter=";", dtype=ndtype,
+                          converters=converters)
+        control = np.array(
+            [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))],
+            dtype=ndtype)
+        assert_equal(test, control)
+
+    def test_uint64_type(self):
+        tgt = (9223372043271415339, 9223372043271415853)
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.uint64)
+        assert_equal(res, tgt)
+
+    def test_int64_type(self):
+        tgt = (-9223372036854775807, 9223372036854775807)
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.int64)
+        assert_equal(res, tgt)
+
+    def test_from_float_hex(self):
+        # IEEE doubles and floats only, otherwise the float32
+        # conversion may fail.
+        tgt = np.logspace(-10, 10, 5).astype(np.float32)
+        tgt = np.hstack((tgt, -tgt)).astype(np.float)
+        inp = '\n'.join(map(float.hex, tgt))
+        c = TextIO()
+        c.write(inp)
+        for dt in [np.float, np.float32]:
+            c.seek(0)
+            res = np.loadtxt(c, dtype=dt)
+            assert_equal(res, tgt, err_msg="%s" % dt)
+
+    def test_from_complex(self):
+        tgt = (complex(1, 1), complex(1, -1))
+        c = TextIO()
+        c.write("%s %s" % tgt)
+        c.seek(0)
+        res = np.loadtxt(c, dtype=np.complex)
+        assert_equal(res, tgt)
+
+    def test_universal_newline(self):
+        with temppath() as name:
+            with open(name, 'w') as f:
+                f.write('1 21\r3 42\r')
+            data = np.loadtxt(name)
+        assert_array_equal(data, [[1, 21], [3, 42]])
+
+    def test_empty_field_after_tab(self):
+        c = TextIO()
+        c.write('1 \t2 \t3\tstart \n4\t5\t6\t  \n7\t8\t9.5\t')
+        c.seek(0)
+        dt = {'names': ('x', 'y', 'z', 'comment'),
+              'formats': ('<i4', '<i4', '<f4', '|S8')}
+        x = np.loadtxt(c, dtype=dt, delimiter='\t')
+        a = np.array([b'start ', b'  ', b''])
+        assert_array_equal(x['comment'], a)
+
+    def test_structure_unpack(self):
+        txt = TextIO("M 21 72\nF 35 58")
+        dt = {'names': ('a', 'b', 'c'), 'formats': ('|S1', '<i4', '<f4')}
+        a, b, c = np.loadtxt(txt, dtype=dt, unpack=True)
+        assert_(a.dtype.str == '|S1')
+        assert_(b.dtype.str == '<i4')
+        assert_(c.dtype.str == '<f4')
+        assert_array_equal(a, np.array([b'M', b'F']))
+        assert_array_equal(b, np.array([21, 35]))
+        assert_array_equal(c, np.array([72.,  58.]))
+
+    def test_ndmin_keyword(self):
+        c = TextIO()
+        c.write('1,2,3\n4,5,6')
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, ndmin=3)
+        c.seek(0)
+        assert_raises(ValueError, np.loadtxt, c, ndmin=1.5)
+        c.seek(0)
+        x = np.loadtxt(c, dtype=int, delimiter=',', ndmin=1)
+        a = np.array([[1, 2, 3], [4, 5, 6]])
+        assert_array_equal(x, a)
+
+        d = TextIO()
+        d.write('0,1,2')
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=2)
+        assert_(x.shape == (1, 3))
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=1)
+        assert_(x.shape == (3,))
+        d.seek(0)
+        x = np.loadtxt(d, dtype=int, delimiter=',', ndmin=0)
+        assert_(x.shape == (3,))
+
+        e = TextIO()
+        e.write('0\n1\n2')
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=2)
+        assert_(x.shape == (3, 1))
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=1)
+        assert_(x.shape == (3,))
+        e.seek(0)
+        x = np.loadtxt(e, dtype=int, delimiter=',', ndmin=0)
+        assert_(x.shape == (3,))
+
+        # Test ndmin kw with empty file.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="loadtxt: Empty input file:")
+            f = TextIO()
+            assert_(np.loadtxt(f, ndmin=2).shape == (0, 1,))
+            assert_(np.loadtxt(f, ndmin=1).shape == (0,))
+
+    def test_generator_source(self):
+        def count():
+            for i in range(10):
+                yield "%d" % i
+
+        res = np.loadtxt(count())
+        assert_array_equal(res, np.arange(10))
+
+    def test_bad_line(self):
+        c = TextIO()
+        c.write('1 2 3\n4 5 6\n2 3')
+        c.seek(0)
+
+        # Check for exception and that exception contains line number
+        assert_raises_regex(ValueError, "3", np.loadtxt, c)
+
+    def test_none_as_string(self):
+        # gh-5155, None should work as string when format demands it
+        c = TextIO()
+        c.write('100,foo,200\n300,None,400')
+        c.seek(0)
+        dt = np.dtype([('x', int), ('a', 'S10'), ('y', int)])
+        np.loadtxt(c, delimiter=',', dtype=dt, comments=None)  # Should succeed
+
+
+class Testfromregex(TestCase):
+    # np.fromregex expects files opened in binary mode.
+    def test_record(self):
+        c = TextIO()
+        c.write('1.312 foo\n1.534 bar\n4.444 qux')
+        c.seek(0)
+
+        dt = [('num', np.float64), ('val', 'S3')]
+        x = np.fromregex(c, r"([0-9.]+)\s+(...)", dt)
+        a = np.array([(1.312, 'foo'), (1.534, 'bar'), (4.444, 'qux')],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_record_2(self):
+        c = TextIO()
+        c.write('1312 foo\n1534 bar\n4444 qux')
+        c.seek(0)
+
+        dt = [('num', np.int32), ('val', 'S3')]
+        x = np.fromregex(c, r"(\d+)\s+(...)", dt)
+        a = np.array([(1312, 'foo'), (1534, 'bar'), (4444, 'qux')],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_record_3(self):
+        c = TextIO()
+        c.write('1312 foo\n1534 bar\n4444 qux')
+        c.seek(0)
+
+        dt = [('num', np.float64)]
+        x = np.fromregex(c, r"(\d+)\s+...", dt)
+        a = np.array([(1312,), (1534,), (4444,)], dtype=dt)
+        assert_array_equal(x, a)
+
+
+#####--------------------------------------------------------------------------
+
+
+class TestFromTxt(TestCase):
+    #
+    def test_record(self):
+        # Test w/ explicit dtype
+        data = TextIO('1 2\n3 4')
+        test = np.ndfromtxt(data, dtype=[('x', np.int32), ('y', np.int32)])
+        control = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+        assert_equal(test, control)
+        #
+        data = TextIO('M 64.0 75.0\nF 25.0 60.0')
+        descriptor = {'names': ('gender', 'age', 'weight'),
+                      'formats': ('S1', 'i4', 'f4')}
+        control = np.array([('M', 64.0, 75.0), ('F', 25.0, 60.0)],
+                           dtype=descriptor)
+        test = np.ndfromtxt(data, dtype=descriptor)
+        assert_equal(test, control)
+
+    def test_array(self):
+        # Test outputing a standard ndarray
+        data = TextIO('1 2\n3 4')
+        control = np.array([[1, 2], [3, 4]], dtype=int)
+        test = np.ndfromtxt(data, dtype=int)
+        assert_array_equal(test, control)
+        #
+        data.seek(0)
+        control = np.array([[1, 2], [3, 4]], dtype=float)
+        test = np.loadtxt(data, dtype=float)
+        assert_array_equal(test, control)
+
+    def test_1D(self):
+        # Test squeezing to 1D
+        control = np.array([1, 2, 3, 4], int)
+        #
+        data = TextIO('1\n2\n3\n4\n')
+        test = np.ndfromtxt(data, dtype=int)
+        assert_array_equal(test, control)
+        #
+        data = TextIO('1,2,3,4\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',')
+        assert_array_equal(test, control)
+
+    def test_comments(self):
+        # Test the stripping of comments
+        control = np.array([1, 2, 3, 5], int)
+        # Comment on its own line
+        data = TextIO('# comment\n1,2,3,5\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',', comments='#')
+        assert_equal(test, control)
+        # Comment at the end of a line
+        data = TextIO('1,2,3,5# comment\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',', comments='#')
+        assert_equal(test, control)
+
+    def test_skiprows(self):
+        # Test row skipping
+        control = np.array([1, 2, 3, 5], int)
+        kwargs = dict(dtype=int, delimiter=',')
+        #
+        data = TextIO('comment\n1,2,3,5\n')
+        test = np.ndfromtxt(data, skip_header=1, **kwargs)
+        assert_equal(test, control)
+        #
+        data = TextIO('# comment\n1,2,3,5\n')
+        test = np.loadtxt(data, skiprows=1, **kwargs)
+        assert_equal(test, control)
+
+    def test_skip_footer(self):
+        data = ["# %i" % i for i in range(1, 6)]
+        data.append("A, B, C")
+        data.extend(["%i,%3.1f,%03s" % (i, i, i) for i in range(51)])
+        data[-1] = "99,99"
+        kwargs = dict(delimiter=",", names=True, skip_header=5, skip_footer=10)
+        test = np.genfromtxt(TextIO("\n".join(data)), **kwargs)
+        ctrl = np.array([("%f" % i, "%f" % i, "%f" % i) for i in range(41)],
+                        dtype=[(_, float) for _ in "ABC"])
+        assert_equal(test, ctrl)
+
+    def test_skip_footer_with_invalid(self):
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore")
+            basestr = '1 1\n2 2\n3 3\n4 4\n5  \n6  \n7  \n'
+            # Footer too small to get rid of all invalid values
+            assert_raises(ValueError, np.genfromtxt,
+                          TextIO(basestr), skip_footer=1)
+    #        except ValueError:
+    #            pass
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=1, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]))
+            #
+            a = np.genfromtxt(TextIO(basestr), skip_footer=3)
+            assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]))
+            #
+            basestr = '1 1\n2  \n3 3\n4 4\n5  \n6 6\n7 7\n'
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=1, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.], [6., 6.]]))
+            a = np.genfromtxt(
+                TextIO(basestr), skip_footer=3, invalid_raise=False)
+            assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.]]))
+
+    def test_header(self):
+        # Test retrieving a header
+        data = TextIO('gender age weight\nM 64.0 75.0\nF 25.0 60.0')
+        test = np.ndfromtxt(data, dtype=None, names=True)
+        control = {'gender': np.array([b'M', b'F']),
+                   'age': np.array([64.0, 25.0]),
+                   'weight': np.array([75.0, 60.0])}
+        assert_equal(test['gender'], control['gender'])
+        assert_equal(test['age'], control['age'])
+        assert_equal(test['weight'], control['weight'])
+
+    def test_auto_dtype(self):
+        # Test the automatic definition of the output dtype
+        data = TextIO('A 64 75.0 3+4j True\nBCD 25 60.0 5+6j False')
+        test = np.ndfromtxt(data, dtype=None)
+        control = [np.array([b'A', b'BCD']),
+                   np.array([64, 25]),
+                   np.array([75.0, 60.0]),
+                   np.array([3 + 4j, 5 + 6j]),
+                   np.array([True, False]), ]
+        assert_equal(test.dtype.names, ['f0', 'f1', 'f2', 'f3', 'f4'])
+        for (i, ctrl) in enumerate(control):
+            assert_equal(test['f%i' % i], ctrl)
+
+    def test_auto_dtype_uniform(self):
+        # Tests whether the output dtype can be uniformized
+        data = TextIO('1 2 3 4\n5 6 7 8\n')
+        test = np.ndfromtxt(data, dtype=None)
+        control = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
+        assert_equal(test, control)
+
+    def test_fancy_dtype(self):
+        # Check that a nested dtype isn't MIA
+        data = TextIO('1,2,3.0\n4,5,6.0\n')
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = np.ndfromtxt(data, dtype=fancydtype, delimiter=',')
+        control = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype)
+        assert_equal(test, control)
+
+    def test_names_overwrite(self):
+        # Test overwriting the names of the dtype
+        descriptor = {'names': ('g', 'a', 'w'),
+                      'formats': ('S1', 'i4', 'f4')}
+        data = TextIO(b'M 64.0 75.0\nF 25.0 60.0')
+        names = ('gender', 'age', 'weight')
+        test = np.ndfromtxt(data, dtype=descriptor, names=names)
+        descriptor['names'] = names
+        control = np.array([('M', 64.0, 75.0),
+                            ('F', 25.0, 60.0)], dtype=descriptor)
+        assert_equal(test, control)
+
+    def test_commented_header(self):
+        # Check that names can be retrieved even if the line is commented out.
+        data = TextIO("""
+#gender age weight
+M   21  72.100000
+F   35  58.330000
+M   33  21.99
+        """)
+        # The # is part of the first name and should be deleted automatically.
+        test = np.genfromtxt(data, names=True, dtype=None)
+        ctrl = np.array([('M', 21, 72.1), ('F', 35, 58.33), ('M', 33, 21.99)],
+                        dtype=[('gender', '|S1'), ('age', int), ('weight', float)])
+        assert_equal(test, ctrl)
+        # Ditto, but we should get rid of the first element
+        data = TextIO(b"""
+# gender age weight
+M   21  72.100000
+F   35  58.330000
+M   33  21.99
+        """)
+        test = np.genfromtxt(data, names=True, dtype=None)
+        assert_equal(test, ctrl)
+
+    def test_autonames_and_usecols(self):
+        # Tests names and usecols
+        data = TextIO('A B C D\n aaaa 121 45 9.1')
+        test = np.ndfromtxt(data, usecols=('A', 'C', 'D'),
+                            names=True, dtype=None)
+        control = np.array(('aaaa', 45, 9.1),
+                           dtype=[('A', '|S4'), ('C', int), ('D', float)])
+        assert_equal(test, control)
+
+    def test_converters_with_usecols(self):
+        # Test the combination user-defined converters and usecol
+        data = TextIO('1,2,3,,5\n6,7,8,9,10\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',',
+                            converters={3: lambda s: int(s or - 999)},
+                            usecols=(1, 3,))
+        control = np.array([[2, -999], [7, 9]], int)
+        assert_equal(test, control)
+
+    def test_converters_with_usecols_and_names(self):
+        # Tests names and usecols
+        data = TextIO('A B C D\n aaaa 121 45 9.1')
+        test = np.ndfromtxt(data, usecols=('A', 'C', 'D'), names=True,
+                            dtype=None, converters={'C': lambda s: 2 * int(s)})
+        control = np.array(('aaaa', 90, 9.1),
+                           dtype=[('A', '|S4'), ('C', int), ('D', float)])
+        assert_equal(test, control)
+
+    def test_converters_cornercases(self):
+        # Test the conversion to datetime.
+        converter = {
+            'date': lambda s: strptime(s, '%Y-%m-%d %H:%M:%SZ')}
+        data = TextIO('2009-02-03 12:00:00Z, 72214.0')
+        test = np.ndfromtxt(data, delimiter=',', dtype=None,
+                            names=['date', 'stid'], converters=converter)
+        control = np.array((datetime(2009, 2, 3), 72214.),
+                           dtype=[('date', np.object_), ('stid', float)])
+        assert_equal(test, control)
+
+    def test_converters_cornercases2(self):
+        # Test the conversion to datetime64.
+        converter = {
+            'date': lambda s: np.datetime64(strptime(s, '%Y-%m-%d %H:%M:%SZ'))}
+        data = TextIO('2009-02-03 12:00:00Z, 72214.0')
+        test = np.ndfromtxt(data, delimiter=',', dtype=None,
+                            names=['date', 'stid'], converters=converter)
+        control = np.array((datetime(2009, 2, 3), 72214.),
+                           dtype=[('date', 'datetime64[us]'), ('stid', float)])
+        assert_equal(test, control)
+
+    def test_unused_converter(self):
+        # Test whether unused converters are forgotten
+        data = TextIO("1 21\n  3 42\n")
+        test = np.ndfromtxt(data, usecols=(1,),
+                            converters={0: lambda s: int(s, 16)})
+        assert_equal(test, [21, 42])
+        #
+        data.seek(0)
+        test = np.ndfromtxt(data, usecols=(1,),
+                            converters={1: lambda s: int(s, 16)})
+        assert_equal(test, [33, 66])
+
+    def test_invalid_converter(self):
+        strip_rand = lambda x: float((b'r' in x.lower() and x.split()[-1]) or
+                                     (b'r' not in x.lower() and x.strip() or 0.0))
+        strip_per = lambda x: float((b'%' in x.lower() and x.split()[0]) or
+                                    (b'%' not in x.lower() and x.strip() or 0.0))
+        s = TextIO("D01N01,10/1/2003 ,1 %,R 75,400,600\r\n"
+                   "L24U05,12/5/2003, 2 %,1,300, 150.5\r\n"
+                   "D02N03,10/10/2004,R 1,,7,145.55")
+        kwargs = dict(
+            converters={2: strip_per, 3: strip_rand}, delimiter=",",
+            dtype=None)
+        assert_raises(ConverterError, np.genfromtxt, s, **kwargs)
+
+    def test_tricky_converter_bug1666(self):
+        # Test some corner cases
+        s = TextIO('q1,2\nq3,4')
+        cnv = lambda s: float(s[1:])
+        test = np.genfromtxt(s, delimiter=',', converters={0: cnv})
+        control = np.array([[1., 2.], [3., 4.]])
+        assert_equal(test, control)
+
+    def test_dtype_with_converters(self):
+        dstr = "2009; 23; 46"
+        test = np.ndfromtxt(TextIO(dstr,),
+                            delimiter=";", dtype=float, converters={0: bytes})
+        control = np.array([('2009', 23., 46)],
+                           dtype=[('f0', '|S4'), ('f1', float), ('f2', float)])
+        assert_equal(test, control)
+        test = np.ndfromtxt(TextIO(dstr,),
+                            delimiter=";", dtype=float, converters={0: float})
+        control = np.array([2009., 23., 46],)
+        assert_equal(test, control)
+
+    def test_dtype_with_converters_and_usecols(self):
+        dstr = "1,5,-1,1:1\n2,8,-1,1:n\n3,3,-2,m:n\n"
+        dmap = {'1:1':0, '1:n':1, 'm:1':2, 'm:n':3}
+        dtyp = [('e1','i4'),('e2','i4'),('e3','i2'),('n', 'i1')]
+        conv = {0: int, 1: int, 2: int, 3: lambda r: dmap[r.decode()]}
+        test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',',
+                             names=None, converters=conv)
+        control = np.rec.array([[1,5,-1,0], [2,8,-1,1], [3,3,-2,3]], dtype=dtyp)
+        assert_equal(test, control)
+        dtyp = [('e1','i4'),('e2','i4'),('n', 'i1')]
+        test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',',
+                             usecols=(0,1,3), names=None, converters=conv)
+        control = np.rec.array([[1,5,0], [2,8,1], [3,3,3]], dtype=dtyp)
+        assert_equal(test, control)
+
+    def test_dtype_with_object(self):
+        # Test using an explicit dtype with an object
+        data = """ 1; 2001-01-01
+                   2; 2002-01-31 """
+        ndtype = [('idx', int), ('code', np.object)]
+        func = lambda s: strptime(s.strip(), "%Y-%m-%d")
+        converters = {1: func}
+        test = np.genfromtxt(TextIO(data), delimiter=";", dtype=ndtype,
+                             converters=converters)
+        control = np.array(
+            [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))],
+            dtype=ndtype)
+        assert_equal(test, control)
+
+        ndtype = [('nest', [('idx', int), ('code', np.object)])]
+        try:
+            test = np.genfromtxt(TextIO(data), delimiter=";",
+                                 dtype=ndtype, converters=converters)
+        except NotImplementedError:
+            pass
+        else:
+            errmsg = "Nested dtype involving objects should be supported."
+            raise AssertionError(errmsg)
+
+    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 = np.genfromtxt(data, delimiter=",", names=None, dtype=float,
+                             usecols=(2, 3), converters={2: bytes})
+        control = np.array([('2001-01-01', 1.)],
+                           dtype=[('', '|S10'), ('', float)])
+        assert_equal(test, control)
+
+    def test_spacedelimiter(self):
+        # Test space delimiter
+        data = TextIO("1  2  3  4   5\n6  7  8  9  10")
+        test = np.ndfromtxt(data)
+        control = np.array([[1., 2., 3., 4., 5.],
+                            [6., 7., 8., 9., 10.]])
+        assert_equal(test, control)
+
+    def test_integer_delimiter(self):
+        # Test using an integer for delimiter
+        data = "  1  2  3\n  4  5 67\n890123  4"
+        test = np.genfromtxt(TextIO(data), delimiter=3)
+        control = np.array([[1, 2, 3], [4, 5, 67], [890, 123, 4]])
+        assert_equal(test, control)
+
+    def test_missing(self):
+        data = TextIO('1,2,3,,5\n')
+        test = np.ndfromtxt(data, dtype=int, delimiter=',',
+                            converters={3: lambda s: int(s or - 999)})
+        control = np.array([1, 2, 3, -999, 5], int)
+        assert_equal(test, control)
+
+    def test_missing_with_tabs(self):
+        # Test w/ a delimiter tab
+        txt = "1\t2\t3\n\t2\t\n1\t\t3"
+        test = np.genfromtxt(TextIO(txt), delimiter="\t",
+                             usemask=True,)
+        ctrl_d = np.array([(1, 2, 3), (np.nan, 2, np.nan), (1, np.nan, 3)],)
+        ctrl_m = np.array([(0, 0, 0), (1, 0, 1), (0, 1, 0)], dtype=bool)
+        assert_equal(test.data, ctrl_d)
+        assert_equal(test.mask, ctrl_m)
+
+    def test_usecols(self):
+        # Test the selection of columns
+        # Select 1 column
+        control = np.array([[1, 2], [3, 4]], float)
+        data = TextIO()
+        np.savetxt(data, control)
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=(1,))
+        assert_equal(test, control[:, 1])
+        #
+        control = np.array([[1, 2, 3], [3, 4, 5]], float)
+        data = TextIO()
+        np.savetxt(data, control)
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=(1, 2))
+        assert_equal(test, control[:, 1:])
+        # Testing with arrays instead of tuples.
+        data.seek(0)
+        test = np.ndfromtxt(data, dtype=float, usecols=np.array([1, 2]))
+        assert_equal(test, control[:, 1:])
+
+    def test_usecols_as_css(self):
+        # Test giving usecols with a comma-separated string
+        data = "1 2 3\n4 5 6"
+        test = np.genfromtxt(TextIO(data),
+                             names="a, b, c", usecols="a, c")
+        ctrl = np.array([(1, 3), (4, 6)], dtype=[(_, float) for _ in "ac"])
+        assert_equal(test, ctrl)
+
+    def test_usecols_with_structured_dtype(self):
+        # Test usecols with an explicit structured dtype
+        data = TextIO("JOE 70.1 25.3\nBOB 60.5 27.9")
+        names = ['stid', 'temp']
+        dtypes = ['S4', 'f8']
+        test = np.ndfromtxt(
+            data, usecols=(0, 2), dtype=list(zip(names, dtypes)))
+        assert_equal(test['stid'], [b"JOE", b"BOB"])
+        assert_equal(test['temp'], [25.3, 27.9])
+
+    def test_usecols_with_integer(self):
+        # Test usecols with an integer
+        test = np.genfromtxt(TextIO(b"1 2 3\n4 5 6"), usecols=0)
+        assert_equal(test, np.array([1., 4.]))
+
+    def test_usecols_with_named_columns(self):
+        # Test usecols with named columns
+        ctrl = np.array([(1, 3), (4, 6)], dtype=[('a', float), ('c', float)])
+        data = "1 2 3\n4 5 6"
+        kwargs = dict(names="a, b, c")
+        test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs)
+        assert_equal(test, ctrl)
+        test = np.genfromtxt(TextIO(data),
+                             usecols=('a', 'c'), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_empty_file(self):
+        # Test that an empty file raises the proper warning.
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore",
+                                    message="genfromtxt: Empty input file:")
+            data = TextIO()
+            test = np.genfromtxt(data)
+            assert_equal(test, np.array([]))
+
+    def test_fancy_dtype_alt(self):
+        # Check that a nested dtype isn't MIA
+        data = TextIO('1,2,3.0\n4,5,6.0\n')
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = np.mafromtxt(data, dtype=fancydtype, delimiter=',')
+        control = ma.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype)
+        assert_equal(test, control)
+
+    def test_shaped_dtype(self):
+        c = TextIO("aaaa  1.0  8.0  1 2 3 4 5 6")
+        dt = np.dtype([('name', 'S4'), ('x', float), ('y', float),
+                       ('block', int, (2, 3))])
+        x = np.ndfromtxt(c, dtype=dt)
+        a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])],
+                     dtype=dt)
+        assert_array_equal(x, a)
+
+    def test_withmissing(self):
+        data = TextIO('A,B\n0,1\n2,N/A')
+        kwargs = dict(delimiter=",", missing_values="N/A", names=True)
+        test = np.mafromtxt(data, dtype=None, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        #
+        data.seek(0)
+        test = np.mafromtxt(data, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.float), ('B', np.float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_user_missing_values(self):
+        data = "A, B, C\n0, 0., 0j\n1, N/A, 1j\n-9, 2.2, N/A\n3, -99, 3j"
+        basekwargs = dict(dtype=None, delimiter=",", names=True,)
+        mdtype = [('A', int), ('B', float), ('C', complex)]
+        #
+        test = np.mafromtxt(TextIO(data), missing_values="N/A",
+                            **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+        #
+        basekwargs['dtype'] = mdtype
+        test = np.mafromtxt(TextIO(data),
+                            missing_values={0: -9, 1: -99, 2: -999j}, **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+        #
+        test = np.mafromtxt(TextIO(data),
+                            missing_values={0: -9, 'B': -99, 'C': -999j},
+                            **basekwargs)
+        control = ma.array([(0, 0.0, 0j), (1, -999, 1j),
+                            (-9, 2.2, -999j), (3, -99, 3j)],
+                           mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)],
+                           dtype=mdtype)
+        assert_equal(test, control)
+
+    def test_user_filling_values(self):
+        # Test with missing and filling values
+        ctrl = np.array([(0, 3), (4, -999)], dtype=[('a', int), ('b', int)])
+        data = "N/A, 2, 3\n4, ,???"
+        kwargs = dict(delimiter=",",
+                      dtype=int,
+                      names="a,b,c",
+                      missing_values={0: "N/A", 'b': " ", 2: "???"},
+                      filling_values={0: 0, 'b': 0, 2: -999})
+        test = np.genfromtxt(TextIO(data), **kwargs)
+        ctrl = np.array([(0, 2, 3), (4, 0, -999)],
+                        dtype=[(_, int) for _ in "abc"])
+        assert_equal(test, ctrl)
+        #
+        test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs)
+        ctrl = np.array([(0, 3), (4, -999)], dtype=[(_, int) for _ in "ac"])
+        assert_equal(test, ctrl)
+
+        data2 = "1,2,*,4\n5,*,7,8\n"
+        test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int,
+                             missing_values="*", filling_values=0)
+        ctrl = np.array([[1, 2, 0, 4], [5, 0, 7, 8]])
+        assert_equal(test, ctrl)
+        test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int,
+                             missing_values="*", filling_values=-1)
+        ctrl = np.array([[1, 2, -1, 4], [5, -1, 7, 8]])
+        assert_equal(test, ctrl)
+
+    def test_withmissing_float(self):
+        data = TextIO('A,B\n0,1.5\n2,-999.00')
+        test = np.mafromtxt(data, dtype=None, delimiter=',',
+                            missing_values='-999.0', names=True,)
+        control = ma.array([(0, 1.5), (2, -1.)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_with_masked_column_uniform(self):
+        # Test masked column
+        data = TextIO('1 2 3\n4 5 6\n')
+        test = np.genfromtxt(data, dtype=None,
+                             missing_values='2,5', usemask=True)
+        control = ma.array([[1, 2, 3], [4, 5, 6]], mask=[[0, 1, 0], [0, 1, 0]])
+        assert_equal(test, control)
+
+    def test_with_masked_column_various(self):
+        # Test masked column
+        data = TextIO('True 2 3\nFalse 5 6\n')
+        test = np.genfromtxt(data, dtype=None,
+                             missing_values='2,5', usemask=True)
+        control = ma.array([(1, 2, 3), (0, 5, 6)],
+                           mask=[(0, 1, 0), (0, 1, 0)],
+                           dtype=[('f0', bool), ('f1', bool), ('f2', int)])
+        assert_equal(test, control)
+
+    def test_invalid_raise(self):
+        # Test invalid raise
+        data = ["1, 1, 1, 1, 1"] * 50
+        for i in range(5):
+            data[10 * i] = "2, 2, 2, 2 2"
+        data.insert(0, "a, b, c, d, e")
+        mdata = TextIO("\n".join(data))
+        #
+        kwargs = dict(delimiter=",", dtype=None, names=True)
+        # XXX: is there a better way to get the return value of the
+        # callable in assert_warns ?
+        ret = {}
+
+        def f(_ret={}):
+            _ret['mtest'] = np.ndfromtxt(mdata, invalid_raise=False, **kwargs)
+        assert_warns(ConversionWarning, f, _ret=ret)
+        mtest = ret['mtest']
+        assert_equal(len(mtest), 45)
+        assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'abcde']))
+        #
+        mdata.seek(0)
+        assert_raises(ValueError, np.ndfromtxt, mdata,
+                      delimiter=",", names=True)
+
+    def test_invalid_raise_with_usecols(self):
+        # Test invalid_raise with usecols
+        data = ["1, 1, 1, 1, 1"] * 50
+        for i in range(5):
+            data[10 * i] = "2, 2, 2, 2 2"
+        data.insert(0, "a, b, c, d, e")
+        mdata = TextIO("\n".join(data))
+        kwargs = dict(delimiter=",", dtype=None, names=True,
+                      invalid_raise=False)
+        # XXX: is there a better way to get the return value of the
+        # callable in assert_warns ?
+        ret = {}
+
+        def f(_ret={}):
+            _ret['mtest'] = np.ndfromtxt(mdata, usecols=(0, 4), **kwargs)
+        assert_warns(ConversionWarning, f, _ret=ret)
+        mtest = ret['mtest']
+        assert_equal(len(mtest), 45)
+        assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'ae']))
+        #
+        mdata.seek(0)
+        mtest = np.ndfromtxt(mdata, usecols=(0, 1), **kwargs)
+        assert_equal(len(mtest), 50)
+        control = np.ones(50, dtype=[(_, int) for _ in 'ab'])
+        control[[10 * _ for _ in range(5)]] = (2, 2)
+        assert_equal(mtest, control)
+
+    def test_inconsistent_dtype(self):
+        # Test inconsistent dtype
+        data = ["1, 1, 1, 1, -1.1"] * 50
+        mdata = TextIO("\n".join(data))
+
+        converters = {4: lambda x: "(%s)" % x}
+        kwargs = dict(delimiter=",", converters=converters,
+                      dtype=[(_, int) for _ in 'abcde'],)
+        assert_raises(ValueError, np.genfromtxt, mdata, **kwargs)
+
+    def test_default_field_format(self):
+        # Test default format
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=None, defaultfmt="f%02i")
+        ctrl = np.array([(0, 1, 2.3), (4, 5, 6.7)],
+                        dtype=[("f00", int), ("f01", int), ("f02", float)])
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_wo_names(self):
+        # Test single dtype w/o names
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, defaultfmt="f%02i")
+        ctrl = np.array([[0., 1., 2.3], [4., 5., 6.7]], dtype=float)
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_w_explicit_names(self):
+        # Test single dtype w explicit names
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, names="a, b, c")
+        ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)],
+                        dtype=[(_, float) for _ in "abc"])
+        assert_equal(mtest, ctrl)
+
+    def test_single_dtype_w_implicit_names(self):
+        # Test single dtype w implicit names
+        data = "a, b, c\n0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data),
+                             delimiter=",", dtype=float, names=True)
+        ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)],
+                        dtype=[(_, float) for _ in "abc"])
+        assert_equal(mtest, ctrl)
+
+    def test_easy_structured_dtype(self):
+        # Test easy structured dtype
+        data = "0, 1, 2.3\n4, 5, 6.7"
+        mtest = np.ndfromtxt(TextIO(data), delimiter=",",
+                             dtype=(int, float, float), defaultfmt="f_%02i")
+        ctrl = np.array([(0, 1., 2.3), (4, 5., 6.7)],
+                        dtype=[("f_00", int), ("f_01", float), ("f_02", float)])
+        assert_equal(mtest, ctrl)
+
+    def test_autostrip(self):
+        # Test autostrip
+        data = "01/01/2003  , 1.3,   abcde"
+        kwargs = dict(delimiter=",", dtype=None)
+        mtest = np.ndfromtxt(TextIO(data), **kwargs)
+        ctrl = np.array([('01/01/2003  ', 1.3, '   abcde')],
+                        dtype=[('f0', '|S12'), ('f1', float), ('f2', '|S8')])
+        assert_equal(mtest, ctrl)
+        mtest = np.ndfromtxt(TextIO(data), autostrip=True, **kwargs)
+        ctrl = np.array([('01/01/2003', 1.3, 'abcde')],
+                        dtype=[('f0', '|S10'), ('f1', float), ('f2', '|S5')])
+        assert_equal(mtest, ctrl)
+
+    def test_replace_space(self):
+        # Test the 'replace_space' option
+        txt = "A.A, B (B), C:C\n1, 2, 3.14"
+        # Test default: replace ' ' by '_' and delete non-alphanum chars
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None)
+        ctrl_dtype = [("AA", int), ("B_B", int), ("CC", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no replace, no delete
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None,
+                             replace_space='', deletechars='')
+        ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no delete (spaces are replaced by _)
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=None,
+                             deletechars='')
+        ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", float)]
+        ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+
+    def test_replace_space_known_dtype(self):
+        # Test the 'replace_space' (and related) options when dtype != None
+        txt = "A.A, B (B), C:C\n1, 2, 3"
+        # Test default: replace ' ' by '_' and delete non-alphanum chars
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int)
+        ctrl_dtype = [("AA", int), ("B_B", int), ("CC", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no replace, no delete
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int,
+                             replace_space='', deletechars='')
+        ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+        # Test: no delete (spaces are replaced by _)
+        test = np.genfromtxt(TextIO(txt),
+                             delimiter=",", names=True, dtype=int,
+                             deletechars='')
+        ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", int)]
+        ctrl = np.array((1, 2, 3), dtype=ctrl_dtype)
+        assert_equal(test, ctrl)
+
+    def test_incomplete_names(self):
+        # Test w/ incomplete names
+        data = "A,,C\n0,1,2\n3,4,5"
+        kwargs = dict(delimiter=",", names=True)
+        # w/ dtype=None
+        ctrl = np.array([(0, 1, 2), (3, 4, 5)],
+                        dtype=[(_, int) for _ in ('A', 'f0', 'C')])
+        test = np.ndfromtxt(TextIO(data), dtype=None, **kwargs)
+        assert_equal(test, ctrl)
+        # w/ default dtype
+        ctrl = np.array([(0, 1, 2), (3, 4, 5)],
+                        dtype=[(_, float) for _ in ('A', 'f0', 'C')])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+
+    def test_names_auto_completion(self):
+        # Make sure that names are properly completed
+        data = "1 2 3\n 4 5 6"
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, float, int), names="a")
+        ctrl = np.array([(1, 2, 3), (4, 5, 6)],
+                        dtype=[('a', int), ('f0', float), ('f1', int)])
+        assert_equal(test, ctrl)
+
+    def test_names_with_usecols_bug1636(self):
+        # Make sure we pick up the right names w/ usecols
+        data = "A,B,C,D,E\n0,1,2,3,4\n0,1,2,3,4\n0,1,2,3,4"
+        ctrl_names = ("A", "C", "E")
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, int, int), delimiter=",",
+                             usecols=(0, 2, 4), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+        #
+        test = np.genfromtxt(TextIO(data),
+                             dtype=(int, int, int), delimiter=",",
+                             usecols=("A", "C", "E"), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+        #
+        test = np.genfromtxt(TextIO(data),
+                             dtype=int, delimiter=",",
+                             usecols=("A", "C", "E"), names=True)
+        assert_equal(test.dtype.names, ctrl_names)
+
+    def test_fixed_width_names(self):
+        # Test fix-width w/ names
+        data = "    A    B   C\n    0    1 2.3\n   45   67   9."
+        kwargs = dict(delimiter=(5, 5, 4), names=True, dtype=None)
+        ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)],
+                        dtype=[('A', int), ('B', int), ('C', float)])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+        #
+        kwargs = dict(delimiter=5, names=True, dtype=None)
+        ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)],
+                        dtype=[('A', int), ('B', int), ('C', float)])
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_filling_values(self):
+        # Test missing values
+        data = b"1, 2, 3\n1, , 5\n0, 6, \n"
+        kwargs = dict(delimiter=",", dtype=None, filling_values=-999)
+        ctrl = np.array([[1, 2, 3], [1, -999, 5], [0, 6, -999]], dtype=int)
+        test = np.ndfromtxt(TextIO(data), **kwargs)
+        assert_equal(test, ctrl)
+
+    def test_comments_is_none(self):
+        # Github issue 329 (None was previously being converted to 'None').
+        test = np.genfromtxt(TextIO("test1,testNonetherestofthedata"),
+                             dtype=None, comments=None, delimiter=',')
+        assert_equal(test[1], b'testNonetherestofthedata')
+        test = np.genfromtxt(TextIO("test1, testNonetherestofthedata"),
+                             dtype=None, comments=None, delimiter=',')
+        assert_equal(test[1], b' testNonetherestofthedata')
+
+    def test_recfromtxt(self):
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        kwargs = dict(delimiter=",", missing_values="N/A", names=True)
+        test = np.recfromtxt(data, **kwargs)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,N/A')
+        test = np.recfromtxt(data, dtype=None, usemask=True, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(test.A, [0, 2])
+
+    def test_recfromcsv(self):
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        kwargs = dict(missing_values="N/A", names=True, case_sensitive=True)
+        test = np.recfromcsv(data, dtype=None, **kwargs)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,N/A')
+        test = np.recfromcsv(data, dtype=None, usemask=True, **kwargs)
+        control = ma.array([(0, 1), (2, -1)],
+                           mask=[(False, False), (False, True)],
+                           dtype=[('A', np.int), ('B', np.int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(test.A, [0, 2])
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        test = np.recfromcsv(data, missing_values='N/A',)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=[('a', np.int), ('b', np.int)])
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+        #
+        data = TextIO('A,B\n0,1\n2,3')
+        dtype = [('a', np.int), ('b', np.float)]
+        test = np.recfromcsv(data, missing_values='N/A', dtype=dtype)
+        control = np.array([(0, 1), (2, 3)],
+                           dtype=dtype)
+        self.assertTrue(isinstance(test, np.recarray))
+        assert_equal(test, control)
+
+    def test_max_rows(self):
+        # Test the `max_rows` keyword argument.
+        data = '1 2\n3 4\n5 6\n7 8\n9 10\n'
+        txt = TextIO(data)
+        a1 = np.genfromtxt(txt, max_rows=3)
+        a2 = np.genfromtxt(txt)
+        assert_equal(a1, [[1, 2], [3, 4], [5, 6]])
+        assert_equal(a2, [[7, 8], [9, 10]])
+
+        # max_rows must be at least 1.
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=0)
+
+        # An input with several invalid rows.
+        data = '1 1\n2 2\n0 \n3 3\n4 4\n5  \n6  \n7  \n'
+
+        test = np.genfromtxt(TextIO(data), max_rows=2)
+        control = np.array([[1., 1.], [2., 2.]])
+        assert_equal(test, control)
+
+        # Test keywords conflict
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), skip_footer=1,
+                      max_rows=4)
+
+        # Test with invalid value
+        assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=4)
+
+        # Test with invalid not raise
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore")
+
+            test = np.genfromtxt(TextIO(data), max_rows=4, invalid_raise=False)
+            control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])
+            assert_equal(test, control)
+
+            test = np.genfromtxt(TextIO(data), max_rows=5, invalid_raise=False)
+            control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])
+            assert_equal(test, control)
+
+        # Structured array with field names.
+        data = 'a b\n#c d\n1 1\n2 2\n#0 \n3 3\n4 4\n5  5\n'
+
+        # Test with header, names and comments
+        txt = TextIO(data)
+        test = np.genfromtxt(txt, skip_header=1, max_rows=3, names=True)
+        control = np.array([(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)],
+                      dtype=[('c', '<f8'), ('d', '<f8')])
+        assert_equal(test, control)
+        # To continue reading the same "file", don't use skip_header or
+        # names, and use the previously determined dtype.
+        test = np.genfromtxt(txt, max_rows=None, dtype=test.dtype)
+        control = np.array([(4.0, 4.0), (5.0, 5.0)],
+                      dtype=[('c', '<f8'), ('d', '<f8')])
+        assert_equal(test, control)
+
+    def test_gft_using_filename(self):
+        # Test that we can load data from a filename as well as a file
+        # object
+        tgt = np.arange(6).reshape((2, 3))
+        if sys.version_info[0] >= 3:
+            # python 3k is known to fail for '\r'
+            linesep = ('\n', '\r\n')
+        else:
+            linesep = ('\n', '\r\n', '\r')
+
+        for sep in linesep:
+            data = '0 1 2' + sep + '3 4 5'
+            with temppath() as name:
+                with open(name, 'w') as f:
+                    f.write(data)
+                res = np.genfromtxt(name)
+            assert_array_equal(res, tgt)
+
+    def test_gft_using_generator(self):
+        # gft doesn't work with unicode.
+        def count():
+            for i in range(10):
+                yield asbytes("%d" % i)
+
+        res = np.genfromtxt(count())
+        assert_array_equal(res, np.arange(10))
+
+    def test_auto_dtype_largeint(self):
+        # Regression test for numpy/numpy#5635 whereby large integers could
+        # cause OverflowErrors.
+
+        # Test the automatic definition of the output dtype
+        #
+        # 2**66 = 73786976294838206464 => should convert to float
+        # 2**34 = 17179869184 => should convert to int64
+        # 2**10 = 1024 => should convert to int (int32 on 32-bit systems,
+        #                 int64 on 64-bit systems)
+
+        data = TextIO('73786976294838206464 17179869184 1024')
+
+        test = np.ndfromtxt(data, dtype=None)
+
+        assert_equal(test.dtype.names, ['f0', 'f1', 'f2'])
+
+        assert_(test.dtype['f0'] == np.float)
+        assert_(test.dtype['f1'] == np.int64)
+        assert_(test.dtype['f2'] == np.integer)
+
+        assert_allclose(test['f0'], 73786976294838206464.)
+        assert_equal(test['f1'], 17179869184)
+        assert_equal(test['f2'], 1024)
+
+def test_gzip_load():
+    a = np.random.random((5, 5))
+
+    s = BytesIO()
+    f = gzip.GzipFile(fileobj=s, mode="w")
+
+    np.save(f, a)
+    f.close()
+    s.seek(0)
+
+    f = gzip.GzipFile(fileobj=s, mode="r")
+    assert_array_equal(np.load(f), a)
+
+
+def test_gzip_loadtxt():
+    # Thanks to another windows brokeness, we can't use
+    # NamedTemporaryFile: a file created from this function cannot be
+    # reopened by another open call. So we first put the gzipped string
+    # of the test reference array, write it to a securely opened file,
+    # which is then read from by the loadtxt function
+    s = BytesIO()
+    g = gzip.GzipFile(fileobj=s, mode='w')
+    g.write(b'1 2 3\n')
+    g.close()
+
+    s.seek(0)
+    with temppath(suffix='.gz') as name:
+        with open(name, 'wb') as f:
+            f.write(s.read())
+        res = np.loadtxt(name)
+    s.close()
+
+    assert_array_equal(res, [1, 2, 3])
+
+
+def test_gzip_loadtxt_from_string():
+    s = BytesIO()
+    f = gzip.GzipFile(fileobj=s, mode="w")
+    f.write(b'1 2 3\n')
+    f.close()
+    s.seek(0)
+
+    f = gzip.GzipFile(fileobj=s, mode="r")
+    assert_array_equal(np.loadtxt(f), [1, 2, 3])
+
+
+def test_npzfile_dict():
+    s = BytesIO()
+    x = np.zeros((3, 3))
+    y = np.zeros((3, 3))
+
+    np.savez(s, x=x, y=y)
+    s.seek(0)
+
+    z = np.load(s)
+
+    assert_('x' in z)
+    assert_('y' in z)
+    assert_('x' in z.keys())
+    assert_('y' in z.keys())
+
+    for f, a in z.items():
+        assert_(f in ['x', 'y'])
+        assert_equal(a.shape, (3, 3))
+
+    assert_(len(z.items()) == 2)
+
+    for f in z:
+        assert_(f in ['x', 'y'])
+
+    assert_('x' in z.keys())
+
+
+def test_load_refcount():
+    # Check that objects returned by np.load are directly freed based on
+    # their refcount, rather than needing the gc to collect them.
+
+    f = BytesIO()
+    np.savez(f, [1, 2, 3])
+    f.seek(0)
+
+    assert_(gc.isenabled())
+    gc.disable()
+    try:
+        gc.collect()
+        np.load(f)
+        # gc.collect returns the number of unreachable objects in cycles that
+        # were found -- we are checking that no cycles were created by np.load
+        n_objects_in_cycles = gc.collect()
+    finally:
+        gc.enable()
+    assert_equal(n_objects_in_cycles, 0)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
new file mode 100644
index 0000000000..989c563d99
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
@@ -0,0 +1,735 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal,
+    assert_raises, assert_array_equal
+    )
+
+
+# Test data
+_ndat = np.array([[0.6244, np.nan, 0.2692, 0.0116, np.nan, 0.1170],
+                  [0.5351, -0.9403, np.nan, 0.2100, 0.4759, 0.2833],
+                  [np.nan, np.nan, np.nan, 0.1042, np.nan, -0.5954],
+                  [0.1610, np.nan, np.nan, 0.1859, 0.3146, np.nan]])
+
+
+# Rows of _ndat with nans removed
+_rdat = [np.array([0.6244, 0.2692, 0.0116, 0.1170]),
+         np.array([0.5351, -0.9403, 0.2100, 0.4759, 0.2833]),
+         np.array([0.1042, -0.5954]),
+         np.array([0.1610, 0.1859, 0.3146])]
+
+
+class TestNanFunctions_MinMax(TestCase):
+
+    nanfuncs = [np.nanmin, np.nanmax]
+    stdfuncs = [np.min, np.max]
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for axis in [None, 0, 1]:
+                tgt = rf(mat, axis=axis, keepdims=True)
+                res = nf(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == tgt.ndim)
+
+    def test_out(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            resout = np.zeros(3)
+            tgt = rf(mat, axis=1)
+            res = nf(mat, axis=1, out=resout)
+            assert_almost_equal(res, resout)
+            assert_almost_equal(res, tgt)
+
+    def test_dtype_from_input(self):
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                mat = np.eye(3, dtype=c)
+                tgt = rf(mat, axis=1).dtype.type
+                res = nf(mat, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, axis=None).dtype.type
+                res = nf(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_result_values(self):
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            tgt = [rf(d) for d in _rdat]
+            res = nf(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1, 'no warning raised')
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            # Check scalars
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(f(np.nan)))
+                assert_(len(w) == 1, 'no warning raised')
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_masked(self):
+        mat = np.ma.fix_invalid(_ndat)
+        msk = mat._mask.copy()
+        for f in [np.nanmin]:
+            res = f(mat, axis=1)
+            tgt = f(_ndat, axis=1)
+            assert_equal(res, tgt)
+            assert_equal(mat._mask, msk)
+            assert_(not np.isinf(mat).any())
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+        # check that rows of nan are dealt with for subclasses (#4628)
+        mat[1] = np.nan
+        for f in self.nanfuncs:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat, axis=0)
+                assert_(isinstance(res, np.matrix))
+                assert_(not np.any(np.isnan(res)))
+                assert_(len(w) == 0)
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat, axis=1)
+                assert_(isinstance(res, np.matrix))
+                assert_(np.isnan(res[1, 0]) and not np.isnan(res[0, 0])
+                        and not np.isnan(res[2, 0]))
+                assert_(len(w) == 1, 'no warning raised')
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                res = f(mat)
+                assert_(np.isscalar(res))
+                assert_(res != np.nan)
+                assert_(len(w) == 0)
+
+
+class TestNanFunctions_ArgminArgmax(TestCase):
+
+    nanfuncs = [np.nanargmin, np.nanargmax]
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_result_values(self):
+        for f, fcmp in zip(self.nanfuncs, [np.greater, np.less]):
+            for row in _ndat:
+                with warnings.catch_warnings(record=True):
+                    warnings.simplefilter('always')
+                    ind = f(row)
+                    val = row[ind]
+                    # comparing with NaN is tricky as the result
+                    # is always false except for NaN != NaN
+                    assert_(not np.isnan(val))
+                    assert_(not fcmp(val, row).any())
+                    assert_(not np.equal(val, row[:ind]).any())
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                assert_raises(ValueError, f, mat, axis=axis)
+            assert_raises(ValueError, f, np.nan)
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for f in self.nanfuncs:
+            for axis in [0, None]:
+                assert_raises(ValueError, f, mat, axis=axis)
+            for axis in [1]:
+                res = f(mat, axis=axis)
+                assert_equal(res, np.zeros(0))
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+
+
+class TestNanFunctions_IntTypes(TestCase):
+
+    int_types = (np.int8, np.int16, np.int32, np.int64, np.uint8,
+                 np.uint16, np.uint32, np.uint64)
+
+    mat = np.array([127, 39, 93, 87, 46])
+
+    def integer_arrays(self):
+        for dtype in self.int_types:
+            yield self.mat.astype(dtype)
+
+    def test_nanmin(self):
+        tgt = np.min(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmin(mat), tgt)
+
+    def test_nanmax(self):
+        tgt = np.max(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmax(mat), tgt)
+
+    def test_nanargmin(self):
+        tgt = np.argmin(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanargmin(mat), tgt)
+
+    def test_nanargmax(self):
+        tgt = np.argmax(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanargmax(mat), tgt)
+
+    def test_nansum(self):
+        tgt = np.sum(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nansum(mat), tgt)
+
+    def test_nanprod(self):
+        tgt = np.prod(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanprod(mat), tgt)
+
+    def test_nanmean(self):
+        tgt = np.mean(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanmean(mat), tgt)
+
+    def test_nanvar(self):
+        tgt = np.var(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanvar(mat), tgt)
+
+        tgt = np.var(mat, ddof=1)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanvar(mat, ddof=1), tgt)
+
+    def test_nanstd(self):
+        tgt = np.std(self.mat)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanstd(mat), tgt)
+
+        tgt = np.std(self.mat, ddof=1)
+        for mat in self.integer_arrays():
+            assert_equal(np.nanstd(mat, ddof=1), tgt)
+
+
+class SharedNanFunctionsTestsMixin(object):
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        for f in self.nanfuncs:
+            f(ndat)
+            assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for axis in [None, 0, 1]:
+                tgt = rf(mat, axis=axis, keepdims=True)
+                res = nf(mat, axis=axis, keepdims=True)
+                assert_(res.ndim == tgt.ndim)
+
+    def test_out(self):
+        mat = np.eye(3)
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            resout = np.zeros(3)
+            tgt = rf(mat, axis=1)
+            res = nf(mat, axis=1, out=resout)
+            assert_almost_equal(res, resout)
+            assert_almost_equal(res, tgt)
+
+    def test_dtype_from_dtype(self):
+        mat = np.eye(3)
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type
+                res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type
+                res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_char(self):
+        mat = np.eye(3)
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                tgt = rf(mat, dtype=c, axis=1).dtype.type
+                res = nf(mat, dtype=c, axis=1).dtype.type
+                assert_(res is tgt)
+                # scalar case
+                tgt = rf(mat, dtype=c, axis=None).dtype.type
+                res = nf(mat, dtype=c, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_dtype_from_input(self):
+        codes = 'efdgFDG'
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            for c in codes:
+                mat = np.eye(3, dtype=c)
+                tgt = rf(mat, axis=1).dtype.type
+                res = nf(mat, axis=1).dtype.type
+                assert_(res is tgt, "res %s, tgt %s" % (res, tgt))
+                # scalar case
+                tgt = rf(mat, axis=None).dtype.type
+                res = nf(mat, axis=None).dtype.type
+                assert_(res is tgt)
+
+    def test_result_values(self):
+        for nf, rf in zip(self.nanfuncs, self.stdfuncs):
+            tgt = [rf(d) for d in _rdat]
+            res = nf(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_scalar(self):
+        for f in self.nanfuncs:
+            assert_(f(0.) == 0.)
+
+    def test_matrices(self):
+        # Check that it works and that type and
+        # shape are preserved
+        mat = np.matrix(np.eye(3))
+        for f in self.nanfuncs:
+            res = f(mat, axis=0)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (1, 3))
+            res = f(mat, axis=1)
+            assert_(isinstance(res, np.matrix))
+            assert_(res.shape == (3, 1))
+            res = f(mat)
+            assert_(np.isscalar(res))
+
+
+class TestNanFunctions_SumProd(TestCase, SharedNanFunctionsTestsMixin):
+
+    nanfuncs = [np.nansum, np.nanprod]
+    stdfuncs = [np.sum, np.prod]
+
+    def test_allnans(self):
+        # Check for FutureWarning
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always')
+            res = np.nansum([np.nan]*3, axis=None)
+            assert_(res == 0, 'result is not 0')
+            assert_(len(w) == 0, 'warning raised')
+            # Check scalar
+            res = np.nansum(np.nan)
+            assert_(res == 0, 'result is not 0')
+            assert_(len(w) == 0, 'warning raised')
+            # Check there is no warning for not all-nan
+            np.nansum([0]*3, axis=None)
+            assert_(len(w) == 0, 'unwanted warning raised')
+
+    def test_empty(self):
+        for f, tgt_value in zip([np.nansum, np.nanprod], [0, 1]):
+            mat = np.zeros((0, 3))
+            tgt = [tgt_value]*3
+            res = f(mat, axis=0)
+            assert_equal(res, tgt)
+            tgt = []
+            res = f(mat, axis=1)
+            assert_equal(res, tgt)
+            tgt = tgt_value
+            res = f(mat, axis=None)
+            assert_equal(res, tgt)
+
+
+class TestNanFunctions_MeanVarStd(TestCase, SharedNanFunctionsTestsMixin):
+
+    nanfuncs = [np.nanmean, np.nanvar, np.nanstd]
+    stdfuncs = [np.mean, np.var, np.std]
+
+    def test_dtype_error(self):
+        for f in self.nanfuncs:
+            for dtype in [np.bool_, np.int_, np.object_]:
+                assert_raises(TypeError, f, _ndat, axis=1, dtype=dtype)
+
+    def test_out_dtype_error(self):
+        for f in self.nanfuncs:
+            for dtype in [np.bool_, np.int_, np.object_]:
+                out = np.empty(_ndat.shape[0], dtype=dtype)
+                assert_raises(TypeError, f, _ndat, axis=1, out=out)
+
+    def test_ddof(self):
+        nanfuncs = [np.nanvar, np.nanstd]
+        stdfuncs = [np.var, np.std]
+        for nf, rf in zip(nanfuncs, stdfuncs):
+            for ddof in [0, 1]:
+                tgt = [rf(d, ddof=ddof) for d in _rdat]
+                res = nf(_ndat, axis=1, ddof=ddof)
+                assert_almost_equal(res, tgt)
+
+    def test_ddof_too_big(self):
+        nanfuncs = [np.nanvar, np.nanstd]
+        stdfuncs = [np.var, np.std]
+        dsize = [len(d) for d in _rdat]
+        for nf, rf in zip(nanfuncs, stdfuncs):
+            for ddof in range(5):
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    tgt = [ddof >= d for d in dsize]
+                    res = nf(_ndat, axis=1, ddof=ddof)
+                    assert_equal(np.isnan(res), tgt)
+                    if any(tgt):
+                        assert_(len(w) == 1)
+                        assert_(issubclass(w[0].category, RuntimeWarning))
+                    else:
+                        assert_(len(w) == 0)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for f in self.nanfuncs:
+            for axis in [None, 0, 1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+                    # Check scalar
+                    assert_(np.isnan(f(np.nan)))
+                    assert_(len(w) == 2)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for f in self.nanfuncs:
+            for axis in [0, None]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_(np.isnan(f(mat, axis=axis)).all())
+                    assert_(len(w) == 1)
+                    assert_(issubclass(w[0].category, RuntimeWarning))
+            for axis in [1]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    assert_equal(f(mat, axis=axis), np.zeros([]))
+                    assert_(len(w) == 0)
+
+
+class TestNanFunctions_Median(TestCase):
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        np.nanmedian(ndat)
+        assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for axis in [None, 0, 1]:
+            tgt = np.median(mat, axis=axis, out=None, overwrite_input=False)
+            res = np.nanmedian(mat, axis=axis, out=None, overwrite_input=False)
+            assert_(res.ndim == tgt.ndim)
+
+        d = np.ones((3, 5, 7, 11))
+        # Randomly set some elements to NaN:
+        w = np.random.random((4, 200)) * np.array(d.shape)[:, None]
+        w = w.astype(np.intp)
+        d[tuple(w)] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', RuntimeWarning)
+            res = np.nanmedian(d, axis=None, keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanmedian(d, axis=(0, 1), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 11))
+            res = np.nanmedian(d, axis=(0, 3), keepdims=True)
+            assert_equal(res.shape, (1, 5, 7, 1))
+            res = np.nanmedian(d, axis=(1,), keepdims=True)
+            assert_equal(res.shape, (3, 1, 7, 11))
+            res = np.nanmedian(d, axis=(0, 1, 2, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanmedian(d, axis=(0, 1, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 1))
+
+    def test_out(self):
+        mat = np.random.rand(3, 3)
+        nan_mat = np.insert(mat, [0, 2], np.nan, axis=1)
+        resout = np.zeros(3)
+        tgt = np.median(mat, axis=1)
+        res = np.nanmedian(nan_mat, axis=1, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        # 0-d output:
+        resout = np.zeros(())
+        tgt = np.median(mat, axis=None)
+        res = np.nanmedian(nan_mat, axis=None, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        res = np.nanmedian(nan_mat, axis=(0, 1), out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+
+    def test_small_large(self):
+        # test the small and large code paths, current cutoff 400 elements
+        for s in [5, 20, 51, 200, 1000]:
+            d = np.random.randn(4, s)
+            # Randomly set some elements to NaN:
+            w = np.random.randint(0, d.size, size=d.size // 5)
+            d.ravel()[w] = np.nan
+            d[:,0] = 1.  # ensure at least one good value
+            # use normal median without nans to compare
+            tgt = []
+            for x in d:
+                nonan = np.compress(~np.isnan(x), x)
+                tgt.append(np.median(nonan, overwrite_input=True))
+
+            assert_array_equal(np.nanmedian(d, axis=-1), tgt)
+
+    def test_result_values(self):
+            tgt = [np.median(d) for d in _rdat]
+            res = np.nanmedian(_ndat, axis=1)
+            assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for axis in [None, 0, 1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                warnings.simplefilter('ignore', FutureWarning)
+                assert_(np.isnan(np.nanmedian(mat, axis=axis)).all())
+                if axis is None:
+                    assert_(len(w) == 1)
+                else:
+                    assert_(len(w) == 3)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+                # Check scalar
+                assert_(np.isnan(np.nanmedian(np.nan)))
+                if axis is None:
+                    assert_(len(w) == 2)
+                else:
+                    assert_(len(w) == 4)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for axis in [0, None]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanmedian(mat, axis=axis)).all())
+                assert_(len(w) == 1)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+        for axis in [1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_equal(np.nanmedian(mat, axis=axis), np.zeros([]))
+                assert_(len(w) == 0)
+
+    def test_scalar(self):
+        assert_(np.nanmedian(0.) == 0.)
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.nanmedian, d, axis=-5)
+        assert_raises(IndexError, np.nanmedian, d, axis=(0, -5))
+        assert_raises(IndexError, np.nanmedian, d, axis=4)
+        assert_raises(IndexError, np.nanmedian, d, axis=(0, 4))
+        assert_raises(ValueError, np.nanmedian, d, axis=(1, 1))
+
+    def test_float_special(self):
+        with warnings.catch_warnings(record=True):
+            warnings.simplefilter('ignore', RuntimeWarning)
+            a = np.array([[np.inf,  np.nan], [np.nan, np.nan]])
+            assert_equal(np.nanmedian(a, axis=0), [np.inf,  np.nan])
+            assert_equal(np.nanmedian(a, axis=1), [np.inf,  np.nan])
+            assert_equal(np.nanmedian(a), np.inf)
+
+            # minimum fill value check
+            a = np.array([[np.nan, np.nan, np.inf], [np.nan, np.nan, np.inf]])
+            assert_equal(np.nanmedian(a, axis=1), np.inf)
+
+            # no mask path
+            a = np.array([[np.inf, np.inf], [np.inf, np.inf]])
+            assert_equal(np.nanmedian(a, axis=1), np.inf)
+
+
+class TestNanFunctions_Percentile(TestCase):
+
+    def test_mutation(self):
+        # Check that passed array is not modified.
+        ndat = _ndat.copy()
+        np.nanpercentile(ndat, 30)
+        assert_equal(ndat, _ndat)
+
+    def test_keepdims(self):
+        mat = np.eye(3)
+        for axis in [None, 0, 1]:
+            tgt = np.percentile(mat, 70, axis=axis, out=None,
+                                overwrite_input=False)
+            res = np.nanpercentile(mat, 70, axis=axis, out=None,
+                                   overwrite_input=False)
+            assert_(res.ndim == tgt.ndim)
+
+        d = np.ones((3, 5, 7, 11))
+        # Randomly set some elements to NaN:
+        w = np.random.random((4, 200)) * np.array(d.shape)[:, None]
+        w = w.astype(np.intp)
+        d[tuple(w)] = np.nan
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always', RuntimeWarning)
+            res = np.nanpercentile(d, 90, axis=None, keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanpercentile(d, 90, axis=(0, 1), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 11))
+            res = np.nanpercentile(d, 90, axis=(0, 3), keepdims=True)
+            assert_equal(res.shape, (1, 5, 7, 1))
+            res = np.nanpercentile(d, 90, axis=(1,), keepdims=True)
+            assert_equal(res.shape, (3, 1, 7, 11))
+            res = np.nanpercentile(d, 90, axis=(0, 1, 2, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 1, 1))
+            res = np.nanpercentile(d, 90, axis=(0, 1, 3), keepdims=True)
+            assert_equal(res.shape, (1, 1, 7, 1))
+
+    def test_out(self):
+        mat = np.random.rand(3, 3)
+        nan_mat = np.insert(mat, [0, 2], np.nan, axis=1)
+        resout = np.zeros(3)
+        tgt = np.percentile(mat, 42, axis=1)
+        res = np.nanpercentile(nan_mat, 42, axis=1, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        # 0-d output:
+        resout = np.zeros(())
+        tgt = np.percentile(mat, 42, axis=None)
+        res = np.nanpercentile(nan_mat, 42, axis=None, out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+        res = np.nanpercentile(nan_mat, 42, axis=(0, 1), out=resout)
+        assert_almost_equal(res, resout)
+        assert_almost_equal(res, tgt)
+
+    def test_result_values(self):
+        tgt = [np.percentile(d, 28) for d in _rdat]
+        res = np.nanpercentile(_ndat, 28, axis=1)
+        assert_almost_equal(res, tgt)
+        # Transpose the array to fit the output convention of numpy.percentile
+        tgt = np.transpose([np.percentile(d, (28, 98)) for d in _rdat])
+        res = np.nanpercentile(_ndat, (28, 98), axis=1)
+        assert_almost_equal(res, tgt)
+
+    def test_allnans(self):
+        mat = np.array([np.nan]*9).reshape(3, 3)
+        for axis in [None, 0, 1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanpercentile(mat, 60, axis=axis)).all())
+                if axis is None:
+                    assert_(len(w) == 1)
+                else:
+                    assert_(len(w) == 3)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+                # Check scalar
+                assert_(np.isnan(np.nanpercentile(np.nan, 60)))
+                if axis is None:
+                    assert_(len(w) == 2)
+                else:
+                    assert_(len(w) == 4)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+
+    def test_empty(self):
+        mat = np.zeros((0, 3))
+        for axis in [0, None]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_(np.isnan(np.nanpercentile(mat, 40, axis=axis)).all())
+                assert_(len(w) == 1)
+                assert_(issubclass(w[0].category, RuntimeWarning))
+        for axis in [1]:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter('always')
+                assert_equal(np.nanpercentile(mat, 40, axis=axis), np.zeros([]))
+                assert_(len(w) == 0)
+
+    def test_scalar(self):
+        assert_(np.nanpercentile(0., 100) == 0.)
+
+    def test_extended_axis_invalid(self):
+        d = np.ones((3, 5, 7, 11))
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=-5)
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=(0, -5))
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=4)
+        assert_raises(IndexError, np.nanpercentile, d, q=5, axis=(0, 4))
+        assert_raises(ValueError, np.nanpercentile, d, q=5, axis=(1, 1))
+
+    def test_multiple_percentiles(self):
+        perc = [50, 100]
+        mat = np.ones((4, 3))
+        nan_mat = np.nan * mat
+        # For checking consistency in higher dimensional case
+        large_mat = np.ones((3, 4, 5))
+        large_mat[:, 0:2:4, :] = 0
+        large_mat[:, :, 3:] *= 2
+        for axis in [None, 0, 1]:
+            for keepdim in [False, True]:
+                with warnings.catch_warnings(record=True) as w:
+                    warnings.simplefilter('always')
+                    val = np.percentile(mat, perc, axis=axis, keepdims=keepdim)
+                    nan_val = np.nanpercentile(nan_mat, perc, axis=axis,
+                                               keepdims=keepdim)
+                    assert_equal(nan_val.shape, val.shape)
+
+                    val = np.percentile(large_mat, perc, axis=axis,
+                                        keepdims=keepdim)
+                    nan_val = np.nanpercentile(large_mat, perc, axis=axis,
+                                               keepdims=keepdim)
+                    assert_equal(nan_val, val)
+
+        megamat = np.ones((3, 4, 5, 6))
+        assert_equal(np.nanpercentile(megamat, perc, axis=(1, 2)).shape, (2, 3, 6))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
new file mode 100644
index 0000000000..0de084ef9a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
@@ -0,0 +1,27 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_array_equal, assert_equal, assert_raises
+
+
+def test_packbits():
+    # Copied from the docstring.
+    a = [[[1, 0, 1], [0, 1, 0]],
+         [[1, 1, 0], [0, 0, 1]]]
+    for dtype in [np.bool, np.uint8, np.int]:
+        arr = np.array(a, dtype=dtype)
+        b = np.packbits(arr, axis=-1)
+        assert_equal(b.dtype, np.uint8)
+        assert_array_equal(b, np.array([[[160], [64]], [[192], [32]]]))
+
+    assert_raises(TypeError, np.packbits, np.array(a, dtype=float))
+
+
+def test_unpackbits():
+    # Copied from the docstring.
+    a = np.array([[2], [7], [23]], dtype=np.uint8)
+    b = np.unpackbits(a, axis=1)
+    assert_equal(b.dtype, np.uint8)
+    assert_array_equal(b, np.array([[0, 0, 0, 0, 0, 0, 1, 0],
+                                    [0, 0, 0, 0, 0, 1, 1, 1],
+                                    [0, 0, 0, 1, 0, 1, 1, 1]]))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
new file mode 100644
index 0000000000..5c15941e68
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
@@ -0,0 +1,188 @@
+from __future__ import division, absolute_import, print_function
+
+'''
+>>> p = np.poly1d([1.,2,3])
+>>> p
+poly1d([ 1.,  2.,  3.])
+>>> print(p)
+   2
+1 x + 2 x + 3
+>>> q = np.poly1d([3.,2,1])
+>>> q
+poly1d([ 3.,  2.,  1.])
+>>> print(q)
+   2
+3 x + 2 x + 1
+>>> print(np.poly1d([1.89999+2j, -3j, -5.12345678, 2+1j]))
+            3      2
+(1.9 + 2j) x - 3j x - 5.123 x + (2 + 1j)
+>>> print(np.poly1d([-3, -2, -1]))
+    2
+-3 x - 2 x - 1
+
+>>> p(0)
+3.0
+>>> p(5)
+38.0
+>>> q(0)
+1.0
+>>> q(5)
+86.0
+
+>>> p * q
+poly1d([  3.,   8.,  14.,   8.,   3.])
+>>> p / q
+(poly1d([ 0.33333333]), poly1d([ 1.33333333,  2.66666667]))
+>>> p + q
+poly1d([ 4.,  4.,  4.])
+>>> p - q
+poly1d([-2.,  0.,  2.])
+>>> p ** 4
+poly1d([   1.,    8.,   36.,  104.,  214.,  312.,  324.,  216.,   81.])
+
+>>> p(q)
+poly1d([  9.,  12.,  16.,   8.,   6.])
+>>> q(p)
+poly1d([  3.,  12.,  32.,  40.,  34.])
+
+>>> np.asarray(p)
+array([ 1.,  2.,  3.])
+>>> len(p)
+2
+
+>>> p[0], p[1], p[2], p[3]
+(3.0, 2.0, 1.0, 0)
+
+>>> p.integ()
+poly1d([ 0.33333333,  1.        ,  3.        ,  0.        ])
+>>> p.integ(1)
+poly1d([ 0.33333333,  1.        ,  3.        ,  0.        ])
+>>> p.integ(5)
+poly1d([ 0.00039683,  0.00277778,  0.025     ,  0.        ,  0.        ,
+        0.        ,  0.        ,  0.        ])
+>>> p.deriv()
+poly1d([ 2.,  2.])
+>>> p.deriv(2)
+poly1d([ 2.])
+
+>>> q = np.poly1d([1.,2,3], variable='y')
+>>> print(q)
+   2
+1 y + 2 y + 3
+>>> q = np.poly1d([1.,2,3], variable='lambda')
+>>> print(q)
+        2
+1 lambda + 2 lambda + 3
+
+>>> np.polydiv(np.poly1d([1,0,-1]), np.poly1d([1,1]))
+(poly1d([ 1., -1.]), poly1d([ 0.]))
+
+'''
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_almost_equal, rundocs
+    )
+
+
+class TestDocs(TestCase):
+    def test_doctests(self):
+        return rundocs()
+
+    def test_roots(self):
+        assert_array_equal(np.roots([1, 0, 0]), [0, 0])
+
+    def test_str_leading_zeros(self):
+        p = np.poly1d([4, 3, 2, 1])
+        p[3] = 0
+        assert_equal(str(p),
+                     "   2\n"
+                     "3 x + 2 x + 1")
+
+        p = np.poly1d([1, 2])
+        p[0] = 0
+        p[1] = 0
+        assert_equal(str(p), " \n0")
+
+    def test_polyfit(self):
+        c = np.array([3., 2., 1.])
+        x = np.linspace(0, 2, 7)
+        y = np.polyval(c, x)
+        err = [1, -1, 1, -1, 1, -1, 1]
+        weights = np.arange(8, 1, -1)**2/7.0
+
+        # check 1D case
+        m, cov = np.polyfit(x, y+err, 2, cov=True)
+        est = [3.8571, 0.2857, 1.619]
+        assert_almost_equal(est, m, decimal=4)
+        val0 = [[2.9388, -5.8776, 1.6327],
+                [-5.8776, 12.7347, -4.2449],
+                [1.6327, -4.2449, 2.3220]]
+        assert_almost_equal(val0, cov, decimal=4)
+
+        m2, cov2 = np.polyfit(x, y+err, 2, w=weights, cov=True)
+        assert_almost_equal([4.8927, -1.0177, 1.7768], m2, decimal=4)
+        val = [[8.7929, -10.0103, 0.9756],
+               [-10.0103, 13.6134, -1.8178],
+               [0.9756, -1.8178, 0.6674]]
+        assert_almost_equal(val, cov2, decimal=4)
+
+        # check 2D (n,1) case
+        y = y[:, np.newaxis]
+        c = c[:, np.newaxis]
+        assert_almost_equal(c, np.polyfit(x, y, 2))
+        # check 2D (n,2) case
+        yy = np.concatenate((y, y), axis=1)
+        cc = np.concatenate((c, c), axis=1)
+        assert_almost_equal(cc, np.polyfit(x, yy, 2))
+
+        m, cov = np.polyfit(x, yy + np.array(err)[:, np.newaxis], 2, cov=True)
+        assert_almost_equal(est, m[:, 0], decimal=4)
+        assert_almost_equal(est, m[:, 1], decimal=4)
+        assert_almost_equal(val0, cov[:, :, 0], decimal=4)
+        assert_almost_equal(val0, cov[:, :, 1], decimal=4)
+
+    def test_objects(self):
+        from decimal import Decimal
+        p = np.poly1d([Decimal('4.0'), Decimal('3.0'), Decimal('2.0')])
+        p2 = p * Decimal('1.333333333333333')
+        assert_(p2[1] == Decimal("3.9999999999999990"))
+        p2 = p.deriv()
+        assert_(p2[1] == Decimal('8.0'))
+        p2 = p.integ()
+        assert_(p2[3] == Decimal("1.333333333333333333333333333"))
+        assert_(p2[2] == Decimal('1.5'))
+        assert_(np.issubdtype(p2.coeffs.dtype, np.object_))
+        p = np.poly([Decimal(1), Decimal(2)])
+        assert_equal(np.poly([Decimal(1), Decimal(2)]),
+                     [1, Decimal(-3), Decimal(2)])
+
+    def test_complex(self):
+        p = np.poly1d([3j, 2j, 1j])
+        p2 = p.integ()
+        assert_((p2.coeffs == [1j, 1j, 1j, 0]).all())
+        p2 = p.deriv()
+        assert_((p2.coeffs == [6j, 2j]).all())
+
+    def test_integ_coeffs(self):
+        p = np.poly1d([3, 2, 1])
+        p2 = p.integ(3, k=[9, 7, 6])
+        assert_(
+            (p2.coeffs == [1/4./5., 1/3./4., 1/2./3., 9/1./2., 7, 6]).all())
+
+    def test_zero_dims(self):
+        try:
+            np.poly(np.zeros((0, 0)))
+        except ValueError:
+            pass
+
+    def test_poly_int_overflow(self):
+        """
+        Regression test for gh-5096.
+        """
+        v = np.arange(1, 21)
+        assert_almost_equal(np.poly(v), np.poly(np.diag(v)))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
new file mode 100644
index 0000000000..699a04716d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
@@ -0,0 +1,724 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.ma as ma
+from numpy.ma.mrecords import MaskedRecords
+from numpy.ma.testutils import assert_equal
+from numpy.testing import TestCase, run_module_suite, assert_
+from numpy.lib.recfunctions import (
+    drop_fields, rename_fields, get_fieldstructure, recursive_fill_fields,
+    find_duplicates, merge_arrays, append_fields, stack_arrays, join_by
+    )
+get_names = np.lib.recfunctions.get_names
+get_names_flat = np.lib.recfunctions.get_names_flat
+zip_descr = np.lib.recfunctions.zip_descr
+
+
+class TestRecFunctions(TestCase):
+    # Misc tests
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array([('A', 1.), ('B', 2.)],
+                     dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_zip_descr(self):
+        # Test zip_descr
+        (w, x, y, z) = self.data
+
+        # Std array
+        test = zip_descr((x, x), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int), ('', int)]))
+        test = zip_descr((x, x), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int), ('', int)]))
+
+        # Std & flexible-dtype
+        test = zip_descr((x, z), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int), ('A', '|S3'), ('B', float)]))
+        test = zip_descr((x, z), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('', [('A', '|S3'), ('B', float)])]))
+
+        # Standard & nested dtype
+        test = zip_descr((x, w), flatten=True)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('a', int),
+                               ('ba', float), ('bb', int)]))
+        test = zip_descr((x, w), flatten=False)
+        assert_equal(test,
+                     np.dtype([('', int),
+                               ('', [('a', int),
+                                     ('b', [('ba', float), ('bb', int)])])]))
+
+    def test_drop_fields(self):
+        # Test drop_fields
+        a = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+
+        # A basic field
+        test = drop_fields(a, 'a')
+        control = np.array([((2, 3.0),), ((5, 6.0),)],
+                           dtype=[('b', [('ba', float), ('bb', int)])])
+        assert_equal(test, control)
+
+        # Another basic field (but nesting two fields)
+        test = drop_fields(a, 'b')
+        control = np.array([(1,), (4,)], dtype=[('a', int)])
+        assert_equal(test, control)
+
+        # A nested sub-field
+        test = drop_fields(a, ['ba', ])
+        control = np.array([(1, (3.0,)), (4, (6.0,))],
+                           dtype=[('a', int), ('b', [('bb', int)])])
+        assert_equal(test, control)
+
+        # All the nested sub-field from a field: zap that field
+        test = drop_fields(a, ['ba', 'bb'])
+        control = np.array([(1,), (4,)], dtype=[('a', int)])
+        assert_equal(test, control)
+
+        test = drop_fields(a, ['a', 'b'])
+        assert_(test is None)
+
+    def test_rename_fields(self):
+        # Test rename fields
+        a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))],
+                     dtype=[('a', int),
+                            ('b', [('ba', float), ('bb', (float, 2))])])
+        test = rename_fields(a, {'a': 'A', 'bb': 'BB'})
+        newdtype = [('A', int), ('b', [('ba', float), ('BB', (float, 2))])]
+        control = a.view(newdtype)
+        assert_equal(test.dtype, newdtype)
+        assert_equal(test, control)
+
+    def test_get_names(self):
+        # Test get_names
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        test = get_names(ndtype)
+        assert_equal(test, ('A', 'B'))
+
+        ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])])
+        test = get_names(ndtype)
+        assert_equal(test, ('a', ('b', ('ba', 'bb'))))
+
+    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'))
+
+        ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])])
+        test = get_names_flat(ndtype)
+        assert_equal(test, ('a', 'b', 'ba', 'bb'))
+
+    def test_get_fieldstructure(self):
+        # Test get_fieldstructure
+
+        # No nested fields
+        ndtype = np.dtype([('A', '|S3'), ('B', float)])
+        test = get_fieldstructure(ndtype)
+        assert_equal(test, {'A': [], 'B': []})
+
+        # One 1-nested field
+        ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+        test = get_fieldstructure(ndtype)
+        assert_equal(test, {'A': [], 'B': [], 'BA': ['B', ], 'BB': ['B']})
+
+        # One 2-nested fields
+        ndtype = np.dtype([('A', int),
+                           ('B', [('BA', int),
+                                  ('BB', [('BBA', int), ('BBB', int)])])])
+        test = get_fieldstructure(ndtype)
+        control = {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'],
+                   'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
+        assert_equal(test, control)
+
+    def test_find_duplicates(self):
+        # Test find_duplicates
+        a = ma.array([(2, (2., 'B')), (1, (2., 'B')), (2, (2., 'B')),
+                      (1, (1., 'B')), (2, (2., 'B')), (2, (2., 'C'))],
+                     mask=[(0, (0, 0)), (0, (0, 0)), (0, (0, 0)),
+                           (0, (0, 0)), (1, (0, 0)), (0, (1, 0))],
+                     dtype=[('A', int), ('B', [('BA', float), ('BB', '|S1')])])
+
+        test = find_duplicates(a, ignoremask=False, return_index=True)
+        control = [0, 2]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='A', return_index=True)
+        control = [0, 1, 2, 3, 5]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='B', return_index=True)
+        control = [0, 1, 2, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='BA', return_index=True)
+        control = [0, 1, 2, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, key='BB', return_index=True)
+        control = [0, 1, 2, 3, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+    def test_find_duplicates_ignoremask(self):
+        # Test the ignoremask option of find_duplicates
+        ndtype = [('a', int)]
+        a = ma.array([1, 1, 1, 2, 2, 3, 3],
+                     mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype)
+        test = find_duplicates(a, ignoremask=True, return_index=True)
+        control = [0, 1, 3, 4]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+        test = find_duplicates(a, ignoremask=False, return_index=True)
+        control = [0, 1, 2, 3, 4, 6]
+        assert_equal(sorted(test[-1]), control)
+        assert_equal(test[0], a[test[-1]])
+
+
+class TestRecursiveFillFields(TestCase):
+    # Test recursive_fill_fields.
+    def test_simple_flexible(self):
+        # Test recursive_fill_fields on flexible-array
+        a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)])
+        b = np.zeros((3,), dtype=a.dtype)
+        test = recursive_fill_fields(a, b)
+        control = np.array([(1, 10.), (2, 20.), (0, 0.)],
+                           dtype=[('A', int), ('B', float)])
+        assert_equal(test, control)
+
+    def test_masked_flexible(self):
+        # Test recursive_fill_fields on masked flexible-array
+        a = ma.array([(1, 10.), (2, 20.)], mask=[(0, 1), (1, 0)],
+                     dtype=[('A', int), ('B', float)])
+        b = ma.zeros((3,), dtype=a.dtype)
+        test = recursive_fill_fields(a, b)
+        control = ma.array([(1, 10.), (2, 20.), (0, 0.)],
+                           mask=[(0, 1), (1, 0), (0, 0)],
+                           dtype=[('A', int), ('B', float)])
+        assert_equal(test, control)
+
+
+class TestMergeArrays(TestCase):
+    # Test merge_arrays
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array(
+            [(1, (2, 3.0)), (4, (5, 6.0))],
+            dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_solo(self):
+        # Test merge_arrays on a single array.
+        (_, x, _, z) = self.data
+
+        test = merge_arrays(x)
+        control = np.array([(1,), (2,)], dtype=[('f0', int)])
+        assert_equal(test, control)
+        test = merge_arrays((x,))
+        assert_equal(test, control)
+
+        test = merge_arrays(z, flatten=False)
+        assert_equal(test, z)
+        test = merge_arrays(z, flatten=True)
+        assert_equal(test, z)
+
+    def test_solo_w_flatten(self):
+        # Test merge_arrays on a single array w & w/o flattening
+        w = self.data[0]
+        test = merge_arrays(w, flatten=False)
+        assert_equal(test, w)
+
+        test = merge_arrays(w, flatten=True)
+        control = np.array([(1, 2, 3.0), (4, 5, 6.0)],
+                           dtype=[('a', int), ('ba', float), ('bb', int)])
+        assert_equal(test, control)
+
+    def test_standard(self):
+        # Test standard & standard
+        # Test merge arrays
+        (_, x, y, _) = self.data
+        test = merge_arrays((x, y), usemask=False)
+        control = np.array([(1, 10), (2, 20), (-1, 30)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, y), usemask=True)
+        control = ma.array([(1, 10), (2, 20), (-1, 30)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_flatten(self):
+        # Test standard & flexible
+        (_, x, _, z) = self.data
+        test = merge_arrays((x, z), flatten=True)
+        control = np.array([(1, 'A', 1.), (2, 'B', 2.)],
+                           dtype=[('f0', int), ('A', '|S3'), ('B', float)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, z), flatten=False)
+        control = np.array([(1, ('A', 1.)), (2, ('B', 2.))],
+                           dtype=[('f0', int),
+                                  ('f1', [('A', '|S3'), ('B', float)])])
+        assert_equal(test, control)
+
+    def test_flatten_wflexible(self):
+        # Test flatten standard & nested
+        (w, x, _, _) = self.data
+        test = merge_arrays((x, w), flatten=True)
+        control = np.array([(1, 1, 2, 3.0), (2, 4, 5, 6.0)],
+                           dtype=[('f0', int),
+                                  ('a', int), ('ba', float), ('bb', int)])
+        assert_equal(test, control)
+
+        test = merge_arrays((x, w), flatten=False)
+        controldtype = [('f0', int),
+                                ('f1', [('a', int),
+                                        ('b', [('ba', float), ('bb', int)])])]
+        control = np.array([(1., (1, (2, 3.0))), (2, (4, (5, 6.0)))],
+                           dtype=controldtype)
+        assert_equal(test, control)
+
+    def test_wmasked_arrays(self):
+        # Test merge_arrays masked arrays
+        (_, x, _, _) = self.data
+        mx = ma.array([1, 2, 3], mask=[1, 0, 0])
+        test = merge_arrays((x, mx), usemask=True)
+        control = ma.array([(1, 1), (2, 2), (-1, 3)],
+                           mask=[(0, 1), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('f1', int)])
+        assert_equal(test, control)
+        test = merge_arrays((x, mx), usemask=True, asrecarray=True)
+        assert_equal(test, control)
+        assert_(isinstance(test, MaskedRecords))
+
+    def test_w_singlefield(self):
+        # Test single field
+        test = merge_arrays((np.array([1, 2]).view([('a', int)]),
+                             np.array([10., 20., 30.])),)
+        control = ma.array([(1, 10.), (2, 20.), (-1, 30.)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('a', int), ('f1', float)])
+        assert_equal(test, control)
+
+    def test_w_shorter_flex(self):
+        # Test merge_arrays w/ a shorter flexndarray.
+        z = self.data[-1]
+
+        # Fixme, this test looks incomplete and broken
+        #test = merge_arrays((z, np.array([10, 20, 30]).view([('C', int)])))
+        #control = np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)],
+        #                   dtype=[('A', '|S3'), ('B', float), ('C', int)])
+        #assert_equal(test, control)
+
+        # Hack to avoid pyflakes warnings about unused variables
+        merge_arrays((z, np.array([10, 20, 30]).view([('C', int)])))
+        np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)],
+                 dtype=[('A', '|S3'), ('B', float), ('C', int)])
+
+    def test_singlerecord(self):
+        (_, x, y, z) = self.data
+        test = merge_arrays((x[0], y[0], z[0]), usemask=False)
+        control = np.array([(1, 10, ('A', 1))],
+                           dtype=[('f0', int),
+                                  ('f1', int),
+                                  ('f2', [('A', '|S3'), ('B', float)])])
+        assert_equal(test, control)
+
+
+class TestAppendFields(TestCase):
+    # Test append_fields
+
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_append_single(self):
+        # Test simple case
+        (_, x, _, _) = self.data
+        test = append_fields(x, 'A', data=[10, 20, 30])
+        control = ma.array([(1, 10), (2, 20), (-1, 30)],
+                           mask=[(0, 0), (0, 0), (1, 0)],
+                           dtype=[('f0', int), ('A', int)],)
+        assert_equal(test, control)
+
+    def test_append_double(self):
+        # Test simple case
+        (_, x, _, _) = self.data
+        test = append_fields(x, ('A', 'B'), data=[[10, 20, 30], [100, 200]])
+        control = ma.array([(1, 10, 100), (2, 20, 200), (-1, 30, -1)],
+                           mask=[(0, 0, 0), (0, 0, 0), (1, 0, 1)],
+                           dtype=[('f0', int), ('A', int), ('B', int)],)
+        assert_equal(test, control)
+
+    def test_append_on_flex(self):
+        # Test append_fields on flexible type arrays
+        z = self.data[-1]
+        test = append_fields(z, 'C', data=[10, 20, 30])
+        control = ma.array([('A', 1., 10), ('B', 2., 20), (-1, -1., 30)],
+                           mask=[(0, 0, 0), (0, 0, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', int)],)
+        assert_equal(test, control)
+
+    def test_append_on_nested(self):
+        # Test append_fields on nested fields
+        w = self.data[0]
+        test = append_fields(w, 'C', data=[10, 20, 30])
+        control = ma.array([(1, (2, 3.0), 10),
+                            (4, (5, 6.0), 20),
+                            (-1, (-1, -1.), 30)],
+                           mask=[(
+                               0, (0, 0), 0), (0, (0, 0), 0), (1, (1, 1), 0)],
+                           dtype=[('a', int),
+                                  ('b', [('ba', float), ('bb', int)]),
+                                  ('C', int)],)
+        assert_equal(test, control)
+
+
+class TestStackArrays(TestCase):
+    # Test stack_arrays
+    def setUp(self):
+        x = np.array([1, 2, ])
+        y = np.array([10, 20, 30])
+        z = np.array(
+            [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)])
+        w = np.array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     dtype=[('a', int), ('b', [('ba', float), ('bb', int)])])
+        self.data = (w, x, y, z)
+
+    def test_solo(self):
+        # Test stack_arrays on single arrays
+        (_, x, _, _) = self.data
+        test = stack_arrays((x,))
+        assert_equal(test, x)
+        self.assertTrue(test is x)
+
+        test = stack_arrays(x)
+        assert_equal(test, x)
+        self.assertTrue(test is x)
+
+    def test_unnamed_fields(self):
+        # Tests combinations of arrays w/o named fields
+        (_, x, y, _) = self.data
+
+        test = stack_arrays((x, x), usemask=False)
+        control = np.array([1, 2, 1, 2])
+        assert_equal(test, control)
+
+        test = stack_arrays((x, y), usemask=False)
+        control = np.array([1, 2, 10, 20, 30])
+        assert_equal(test, control)
+
+        test = stack_arrays((y, x), usemask=False)
+        control = np.array([10, 20, 30, 1, 2])
+        assert_equal(test, control)
+
+    def test_unnamed_and_named_fields(self):
+        # Test combination of arrays w/ & w/o named fields
+        (_, x, _, z) = self.data
+
+        test = stack_arrays((x, z))
+        control = ma.array([(1, -1, -1), (2, -1, -1),
+                            (-1, 'A', 1), (-1, 'B', 2)],
+                           mask=[(0, 1, 1), (0, 1, 1),
+                                 (1, 0, 0), (1, 0, 0)],
+                           dtype=[('f0', int), ('A', '|S3'), ('B', float)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, x))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            (-1, -1, 1), (-1, -1, 2), ],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (1, 1, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('f2', int)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, z, x))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            ('A', 1, -1), ('B', 2, -1),
+                            (-1, -1, 1), (-1, -1, 2), ],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 1), (0, 0, 1),
+                                 (1, 1, 0), (1, 1, 0)],
+                           dtype=[('A', '|S3'), ('B', float), ('f2', int)])
+        assert_equal(test, control)
+
+    def test_matching_named_fields(self):
+        # Test combination of arrays w/ matching field names
+        (_, x, _, z) = self.data
+        zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                      dtype=[('A', '|S3'), ('B', float), ('C', float)])
+        test = stack_arrays((z, zz))
+        control = ma.array([('A', 1, -1), ('B', 2, -1),
+                            (
+                                'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', float)],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 0), (0, 0, 0), (0, 0, 0)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+        test = stack_arrays((z, zz, x))
+        ndtype = [('A', '|S3'), ('B', float), ('C', float), ('f3', int)]
+        control = ma.array([('A', 1, -1, -1), ('B', 2, -1, -1),
+                            ('a', 10., 100., -1), ('b', 20., 200., -1),
+                            ('c', 30., 300., -1),
+                            (-1, -1, -1, 1), (-1, -1, -1, 2)],
+                           dtype=ndtype,
+                           mask=[(0, 0, 1, 1), (0, 0, 1, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (1, 1, 1, 0), (1, 1, 1, 0)])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+    def test_defaults(self):
+        # Test defaults: no exception raised if keys of defaults are not fields.
+        (_, _, _, z) = self.data
+        zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                      dtype=[('A', '|S3'), ('B', float), ('C', float)])
+        defaults = {'A': '???', 'B': -999., 'C': -9999., 'D': -99999.}
+        test = stack_arrays((z, zz), defaults=defaults)
+        control = ma.array([('A', 1, -9999.), ('B', 2, -9999.),
+                            (
+                                'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)],
+                           dtype=[('A', '|S3'), ('B', float), ('C', float)],
+                           mask=[(0, 0, 1), (0, 0, 1),
+                                 (0, 0, 0), (0, 0, 0), (0, 0, 0)])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_autoconversion(self):
+        # Tests autoconversion
+        adtype = [('A', int), ('B', bool), ('C', float)]
+        a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype)
+        bdtype = [('A', int), ('B', float), ('C', float)]
+        b = ma.array([(4, 5, 6)], dtype=bdtype)
+        control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)],
+                           dtype=bdtype)
+        test = stack_arrays((a, b), autoconvert=True)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        try:
+            test = stack_arrays((a, b), autoconvert=False)
+        except TypeError:
+            pass
+        else:
+            raise AssertionError
+
+    def test_checktitles(self):
+        # Test using titles in the field names
+        adtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)]
+        a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype)
+        bdtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)]
+        b = ma.array([(4, 5, 6)], dtype=bdtype)
+        test = stack_arrays((a, b))
+        control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)],
+                           dtype=bdtype)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+
+
+class TestJoinBy(TestCase):
+    def setUp(self):
+        self.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
+                                   np.arange(100, 110))),
+                          dtype=[('a', int), ('b', int), ('c', int)])
+        self.b = np.array(list(zip(np.arange(5, 15), np.arange(65, 75),
+                                   np.arange(100, 110))),
+                          dtype=[('a', int), ('b', int), ('d', int)])
+
+    def test_inner_join(self):
+        # Basic test of join_by
+        a, b = self.a, self.b
+
+        test = join_by('a', a, b, jointype='inner')
+        control = np.array([(5, 55, 65, 105, 100), (6, 56, 66, 106, 101),
+                            (7, 57, 67, 107, 102), (8, 58, 68, 108, 103),
+                            (9, 59, 69, 109, 104)],
+                           dtype=[('a', int), ('b1', int), ('b2', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_join(self):
+        a, b = self.a, self.b
+
+        # Fixme, this test is broken
+        #test = join_by(('a', 'b'), a, b)
+        #control = np.array([(5, 55, 105, 100), (6, 56, 106, 101),
+        #                    (7, 57, 107, 102), (8, 58, 108, 103),
+        #                    (9, 59, 109, 104)],
+        #                   dtype=[('a', int), ('b', int),
+        #                          ('c', int), ('d', int)])
+        #assert_equal(test, control)
+
+        # Hack to avoid pyflakes unused variable warnings
+        join_by(('a', 'b'), a, b)
+        np.array([(5, 55, 105, 100), (6, 56, 106, 101),
+                  (7, 57, 107, 102), (8, 58, 108, 103),
+                  (9, 59, 109, 104)],
+                  dtype=[('a', int), ('b', int),
+                         ('c', int), ('d', int)])
+
+    def test_outer_join(self):
+        a, b = self.a, self.b
+
+        test = join_by(('a', 'b'), a, b, 'outer')
+        control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1),
+                            (2, 52, 102, -1), (3, 53, 103, -1),
+                            (4, 54, 104, -1), (5, 55, 105, -1),
+                            (5, 65, -1, 100), (6, 56, 106, -1),
+                            (6, 66, -1, 101), (7, 57, 107, -1),
+                            (7, 67, -1, 102), (8, 58, 108, -1),
+                            (8, 68, -1, 103), (9, 59, 109, -1),
+                            (9, 69, -1, 104), (10, 70, -1, 105),
+                            (11, 71, -1, 106), (12, 72, -1, 107),
+                            (13, 73, -1, 108), (14, 74, -1, 109)],
+                           mask=[(0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 0, 1),
+                                 (0, 0, 1, 0), (0, 0, 1, 0),
+                                 (0, 0, 1, 0), (0, 0, 1, 0),
+                                 (0, 0, 1, 0), (0, 0, 1, 0)],
+                           dtype=[('a', int), ('b', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_leftouter_join(self):
+        a, b = self.a, self.b
+
+        test = join_by(('a', 'b'), a, b, 'leftouter')
+        control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1),
+                            (2, 52, 102, -1), (3, 53, 103, -1),
+                            (4, 54, 104, -1), (5, 55, 105, -1),
+                            (6, 56, 106, -1), (7, 57, 107, -1),
+                            (8, 58, 108, -1), (9, 59, 109, -1)],
+                           mask=[(0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1),
+                                 (0, 0, 0, 1), (0, 0, 0, 1)],
+                           dtype=[('a', int), ('b', int), ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+
+class TestJoinBy2(TestCase):
+    @classmethod
+    def setUp(cls):
+        cls.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
+                                  np.arange(100, 110))),
+                         dtype=[('a', int), ('b', int), ('c', int)])
+        cls.b = np.array(list(zip(np.arange(10), np.arange(65, 75),
+                                  np.arange(100, 110))),
+                         dtype=[('a', int), ('b', int), ('d', int)])
+
+    def test_no_r1postfix(self):
+        # Basic test of join_by no_r1postfix
+        a, b = self.a, self.b
+
+        test = join_by(
+            'a', a, b, r1postfix='', r2postfix='2', jointype='inner')
+        control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101),
+                            (2, 52, 67, 102, 102), (3, 53, 68, 103, 103),
+                            (4, 54, 69, 104, 104), (5, 55, 70, 105, 105),
+                            (6, 56, 71, 106, 106), (7, 57, 72, 107, 107),
+                            (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)],
+                           dtype=[('a', int), ('b', int), ('b2', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_no_postfix(self):
+        self.assertRaises(ValueError, join_by, 'a', self.a, self.b,
+                          r1postfix='', r2postfix='')
+
+    def test_no_r2postfix(self):
+        # Basic test of join_by no_r2postfix
+        a, b = self.a, self.b
+
+        test = join_by(
+            'a', a, b, r1postfix='1', r2postfix='', jointype='inner')
+        control = np.array([(0, 50, 65, 100, 100), (1, 51, 66, 101, 101),
+                            (2, 52, 67, 102, 102), (3, 53, 68, 103, 103),
+                            (4, 54, 69, 104, 104), (5, 55, 70, 105, 105),
+                            (6, 56, 71, 106, 106), (7, 57, 72, 107, 107),
+                            (8, 58, 73, 108, 108), (9, 59, 74, 109, 109)],
+                           dtype=[('a', int), ('b1', int), ('b', int),
+                                  ('c', int), ('d', int)])
+        assert_equal(test, control)
+
+    def test_two_keys_two_vars(self):
+        a = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2),
+                              np.arange(50, 60), np.arange(10, 20))),
+                     dtype=[('k', int), ('a', int), ('b', int), ('c', int)])
+
+        b = np.array(list(zip(np.tile([10, 11], 5), np.repeat(np.arange(5), 2),
+                              np.arange(65, 75), np.arange(0, 10))),
+                     dtype=[('k', int), ('a', int), ('b', int), ('c', int)])
+
+        control = np.array([(10, 0, 50, 65, 10, 0), (11, 0, 51, 66, 11, 1),
+                            (10, 1, 52, 67, 12, 2), (11, 1, 53, 68, 13, 3),
+                            (10, 2, 54, 69, 14, 4), (11, 2, 55, 70, 15, 5),
+                            (10, 3, 56, 71, 16, 6), (11, 3, 57, 72, 17, 7),
+                            (10, 4, 58, 73, 18, 8), (11, 4, 59, 74, 19, 9)],
+                           dtype=[('k', int), ('a', int), ('b1', int),
+                                  ('b2', int), ('c1', int), ('c2', int)])
+        test = join_by(
+            ['a', 'k'], a, b, r1postfix='1', r2postfix='2', jointype='inner')
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test, control)
+
+class TestAppendFieldsObj(TestCase):
+    """
+    Test append_fields with arrays containing objects
+    """
+    # https://github.com/numpy/numpy/issues/2346
+
+    def setUp(self):
+        from datetime import date
+        self.data = dict(obj=date(2000, 1, 1))
+
+    def test_append_to_objects(self):
+        "Test append_fields when the base array contains objects"
+        obj = self.data['obj']
+        x = np.array([(obj, 1.), (obj, 2.)],
+                      dtype=[('A', object), ('B', float)])
+        y = np.array([10, 20], dtype=int)
+        test = append_fields(x, 'C', data=y, usemask=False)
+        control = np.array([(obj, 1.0, 10), (obj, 2.0, 20)],
+                           dtype=[('A', object), ('B', float), ('C', int)])
+        assert_equal(test, control)
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
new file mode 100644
index 0000000000..ee50dcfa4e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
@@ -0,0 +1,261 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_raises
+    )
+from numpy.testing.utils import _assert_valid_refcount
+from numpy.compat import unicode
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+    def test_poly1d(self, level=rlevel):
+        # Ticket #28
+        assert_equal(np.poly1d([1]) - np.poly1d([1, 0]),
+                     np.poly1d([-1, 1]))
+
+    def test_cov_parameters(self, level=rlevel):
+        # Ticket #91
+        x = np.random.random((3, 3))
+        y = x.copy()
+        np.cov(x, rowvar=1)
+        np.cov(y, rowvar=0)
+        assert_array_equal(x, y)
+
+    def test_mem_digitize(self, level=rlevel):
+        # Ticket #95
+        for i in range(100):
+            np.digitize([1, 2, 3, 4], [1, 3])
+            np.digitize([0, 1, 2, 3, 4], [1, 3])
+
+    def test_unique_zero_sized(self, level=rlevel):
+        # Ticket #205
+        assert_array_equal([], np.unique(np.array([])))
+
+    def test_mem_vectorise(self, level=rlevel):
+        # Ticket #325
+        vt = np.vectorize(lambda *args: args)
+        vt(np.zeros((1, 2, 1)), np.zeros((2, 1, 1)), np.zeros((1, 1, 2)))
+        vt(np.zeros((1, 2, 1)), np.zeros((2, 1, 1)), np.zeros((1,
+           1, 2)), np.zeros((2, 2)))
+
+    def test_mgrid_single_element(self, level=rlevel):
+        # Ticket #339
+        assert_array_equal(np.mgrid[0:0:1j], [0])
+        assert_array_equal(np.mgrid[0:0], [])
+
+    def test_refcount_vectorize(self, level=rlevel):
+        # Ticket #378
+        def p(x, y):
+            return 123
+        v = np.vectorize(p)
+        _assert_valid_refcount(v)
+
+    def test_poly1d_nan_roots(self, level=rlevel):
+        # Ticket #396
+        p = np.poly1d([np.nan, np.nan, 1], r=0)
+        self.assertRaises(np.linalg.LinAlgError, getattr, p, "r")
+
+    def test_mem_polymul(self, level=rlevel):
+        # Ticket #448
+        np.polymul([], [1.])
+
+    def test_mem_string_concat(self, level=rlevel):
+        # Ticket #469
+        x = np.array([])
+        np.append(x, 'asdasd\tasdasd')
+
+    def test_poly_div(self, level=rlevel):
+        # Ticket #553
+        u = np.poly1d([1, 2, 3])
+        v = np.poly1d([1, 2, 3, 4, 5])
+        q, r = np.polydiv(u, v)
+        assert_equal(q*v + r, u)
+
+    def test_poly_eq(self, level=rlevel):
+        # Ticket #554
+        x = np.poly1d([1, 2, 3])
+        y = np.poly1d([3, 4])
+        assert_(x != y)
+        assert_(x == x)
+
+    def test_polyfit_build(self):
+        # Ticket #628
+        ref = [-1.06123820e-06, 5.70886914e-04, -1.13822012e-01,
+               9.95368241e+00, -3.14526520e+02]
+        x = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+             104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+             116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129,
+             130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
+             146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
+             158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+             170, 171, 172, 173, 174, 175, 176]
+        y = [9.0, 3.0, 7.0, 4.0, 4.0, 8.0, 6.0, 11.0, 9.0, 8.0, 11.0, 5.0,
+             6.0, 5.0, 9.0, 8.0, 6.0, 10.0, 6.0, 10.0, 7.0, 6.0, 6.0, 6.0,
+             13.0, 4.0, 9.0, 11.0, 4.0, 5.0, 8.0, 5.0, 7.0, 7.0, 6.0, 12.0,
+             7.0, 7.0, 9.0, 4.0, 12.0, 6.0, 6.0, 4.0, 3.0, 9.0, 8.0, 8.0,
+             6.0, 7.0, 9.0, 10.0, 6.0, 8.0, 4.0, 7.0, 7.0, 10.0, 8.0, 8.0,
+             6.0, 3.0, 8.0, 4.0, 5.0, 7.0, 8.0, 6.0, 6.0, 4.0, 12.0, 9.0,
+             8.0, 8.0, 8.0, 6.0, 7.0, 4.0, 4.0, 5.0, 7.0]
+        tested = np.polyfit(x, y, 4)
+        assert_array_almost_equal(ref, tested)
+
+    def test_polydiv_type(self):
+        # Make polydiv work for complex types
+        msg = "Wrong type, should be complex"
+        x = np.ones(3, dtype=np.complex)
+        q, r = np.polydiv(x, x)
+        assert_(q.dtype == np.complex, msg)
+        msg = "Wrong type, should be float"
+        x = np.ones(3, dtype=np.int)
+        q, r = np.polydiv(x, x)
+        assert_(q.dtype == np.float, msg)
+
+    def test_histogramdd_too_many_bins(self):
+        # Ticket 928.
+        assert_raises(ValueError, np.histogramdd, np.ones((1, 10)), bins=2**10)
+
+    def test_polyint_type(self):
+        # Ticket #944
+        msg = "Wrong type, should be complex"
+        x = np.ones(3, dtype=np.complex)
+        assert_(np.polyint(x).dtype == np.complex, msg)
+        msg = "Wrong type, should be float"
+        x = np.ones(3, dtype=np.int)
+        assert_(np.polyint(x).dtype == np.float, msg)
+
+    def test_ndenumerate_crash(self):
+        # Ticket 1140
+        # Shouldn't crash:
+        list(np.ndenumerate(np.array([[]])))
+
+    def test_asfarray_none(self, level=rlevel):
+        # Test for changeset r5065
+        assert_array_equal(np.array([np.nan]), np.asfarray([None]))
+
+    def test_large_fancy_indexing(self, level=rlevel):
+        # Large enough to fail on 64-bit.
+        nbits = np.dtype(np.intp).itemsize * 8
+        thesize = int((2**nbits)**(1.0/5.0)+1)
+
+        def dp():
+            n = 3
+            a = np.ones((n,)*5)
+            i = np.random.randint(0, n, size=thesize)
+            a[np.ix_(i, i, i, i, i)] = 0
+
+        def dp2():
+            n = 3
+            a = np.ones((n,)*5)
+            i = np.random.randint(0, n, size=thesize)
+            a[np.ix_(i, i, i, i, i)]
+
+        self.assertRaises(ValueError, dp)
+        self.assertRaises(ValueError, dp2)
+
+    def test_void_coercion(self, level=rlevel):
+        dt = np.dtype([('a', 'f4'), ('b', 'i4')])
+        x = np.zeros((1,), dt)
+        assert_(np.r_[x, x].dtype == dt)
+
+    def test_who_with_0dim_array(self, level=rlevel):
+        # ticket #1243
+        import os
+        import sys
+
+        oldstdout = sys.stdout
+        sys.stdout = open(os.devnull, 'w')
+        try:
+            try:
+                np.who({'foo': np.array(1)})
+            except:
+                raise AssertionError("ticket #1243")
+        finally:
+            sys.stdout.close()
+            sys.stdout = oldstdout
+
+    def test_include_dirs(self):
+        # As a sanity check, just test that get_include
+        # includes something reasonable.  Somewhat
+        # related to ticket #1405.
+        include_dirs = [np.get_include()]
+        for path in include_dirs:
+            assert_(isinstance(path, (str, unicode)))
+            assert_(path != '')
+
+    def test_polyder_return_type(self):
+        # Ticket #1249
+        assert_(isinstance(np.polyder(np.poly1d([1]), 0), np.poly1d))
+        assert_(isinstance(np.polyder([1], 0), np.ndarray))
+        assert_(isinstance(np.polyder(np.poly1d([1]), 1), np.poly1d))
+        assert_(isinstance(np.polyder([1], 1), np.ndarray))
+
+    def test_append_fields_dtype_list(self):
+        # Ticket #1676
+        from numpy.lib.recfunctions import append_fields
+
+        base = np.array([1, 2, 3], dtype=np.int32)
+        names = ['a', 'b', 'c']
+        data = np.eye(3).astype(np.int32)
+        dlist = [np.float64, np.int32, np.int32]
+        try:
+            append_fields(base, names, data, dlist)
+        except:
+            raise AssertionError()
+
+    def test_loadtxt_fields_subarrays(self):
+        # For ticket #1936
+        if sys.version_info[0] >= 3:
+            from io import StringIO
+        else:
+            from StringIO import StringIO
+
+        dt = [("a", 'u1', 2), ("b", 'u1', 2)]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([((0, 1), (2, 3))], dtype=dt))
+
+        dt = [("a", [("a", 'u1', (1, 3)), ("b", 'u1')])]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([(((0, 1, 2), 3),)], dtype=dt))
+
+        dt = [("a", 'u1', (2, 2))]
+        x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
+        assert_equal(x, np.array([(((0, 1), (2, 3)),)], dtype=dt))
+
+        dt = [("a", 'u1', (2, 3, 2))]
+        x = np.loadtxt(StringIO("0 1 2 3 4 5 6 7 8 9 10 11"), dtype=dt)
+        data = [((((0, 1), (2, 3), (4, 5)), ((6, 7), (8, 9), (10, 11))),)]
+        assert_equal(x, np.array(data, dtype=dt))
+
+    def test_nansum_with_boolean(self):
+        # gh-2978
+        a = np.zeros(2, dtype=np.bool)
+        try:
+            np.nansum(a)
+        except:
+            raise AssertionError()
+
+    def test_py3_compat(self):
+        # gh-2561
+        # Test if the oldstyle class test is bypassed in python3
+        class C():
+            """Old-style class in python2, normal class in python3"""
+            pass
+
+        out = open(os.devnull, 'w')
+        try:
+            np.info(C(), output=out)
+        except AttributeError:
+            raise AssertionError()
+        finally:
+            out.close()
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
new file mode 100644
index 0000000000..3f05f80c0b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
@@ -0,0 +1,380 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.lib.shape_base import (
+    apply_along_axis, apply_over_axes, array_split, split, hsplit, dsplit,
+    vsplit, dstack, kron, tile
+    )
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal,
+    assert_raises, assert_warns
+    )
+
+
+class TestApplyAlongAxis(TestCase):
+    def test_simple(self):
+        a = np.ones((20, 10), 'd')
+        assert_array_equal(
+            apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1]))
+
+    def test_simple101(self, level=11):
+        a = np.ones((10, 101), 'd')
+        assert_array_equal(
+            apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1]))
+
+    def test_3d(self):
+        a = np.arange(27).reshape((3, 3, 3))
+        assert_array_equal(apply_along_axis(np.sum, 0, a),
+                           [[27, 30, 33], [36, 39, 42], [45, 48, 51]])
+
+
+class TestApplyOverAxes(TestCase):
+    def test_simple(self):
+        a = np.arange(24).reshape(2, 3, 4)
+        aoa_a = apply_over_axes(np.sum, a, [0, 2])
+        assert_array_equal(aoa_a, np.array([[[60], [92], [124]]]))
+
+
+class TestArraySplit(TestCase):
+    def test_integer_0_split(self):
+        a = np.arange(10)
+        assert_raises(ValueError, array_split, a, 0)
+
+    def test_integer_split(self):
+        a = np.arange(10)
+        res = array_split(a, 1)
+        desired = [np.arange(10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 2)
+        desired = [np.arange(5), np.arange(5, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 3)
+        desired = [np.arange(4), np.arange(4, 7), np.arange(7, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 4)
+        desired = [np.arange(3), np.arange(3, 6), np.arange(6, 8),
+                   np.arange(8, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 5)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 8), np.arange(8, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 6)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 8), np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 7)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 8)
+        desired = [np.arange(2), np.arange(2, 4), np.arange(4, 5),
+                   np.arange(5, 6), np.arange(6, 7), np.arange(7, 8),
+                   np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 9)
+        desired = [np.arange(2), np.arange(2, 3), np.arange(3, 4),
+                   np.arange(4, 5), np.arange(5, 6), np.arange(6, 7),
+                   np.arange(7, 8), np.arange(8, 9), np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 10)
+        desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3),
+                   np.arange(3, 4), np.arange(4, 5), np.arange(5, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10)]
+        compare_results(res, desired)
+
+        res = array_split(a, 11)
+        desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3),
+                   np.arange(3, 4), np.arange(4, 5), np.arange(5, 6),
+                   np.arange(6, 7), np.arange(7, 8), np.arange(8, 9),
+                   np.arange(9, 10), np.array([])]
+        compare_results(res, desired)
+
+    def test_integer_split_2D_rows(self):
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3, axis=0)
+        tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]),
+                   np.zeros((0, 10))]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+
+        # Same thing for manual splits:
+        res = array_split(a, [0, 1, 2], axis=0)
+        tgt = [np.zeros((0, 10)), np.array([np.arange(10)]),
+               np.array([np.arange(10)])]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+
+    def test_integer_split_2D_cols(self):
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3, axis=-1)
+        desired = [np.array([np.arange(4), np.arange(4)]),
+                   np.array([np.arange(4, 7), np.arange(4, 7)]),
+                   np.array([np.arange(7, 10), np.arange(7, 10)])]
+        compare_results(res, desired)
+
+    def test_integer_split_2D_default(self):
+        """ This will fail if we change default axis
+        """
+        a = np.array([np.arange(10), np.arange(10)])
+        res = array_split(a, 3)
+        tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]),
+                   np.zeros((0, 10))]
+        compare_results(res, tgt)
+        assert_(a.dtype.type is res[-1].dtype.type)
+        # perhaps should check higher dimensions
+
+    def test_index_split_simple(self):
+        a = np.arange(10)
+        indices = [1, 5, 7]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.arange(0, 1), np.arange(1, 5), np.arange(5, 7),
+                   np.arange(7, 10)]
+        compare_results(res, desired)
+
+    def test_index_split_low_bound(self):
+        a = np.arange(10)
+        indices = [0, 5, 7]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.array([]), np.arange(0, 5), np.arange(5, 7),
+                   np.arange(7, 10)]
+        compare_results(res, desired)
+
+    def test_index_split_high_bound(self):
+        a = np.arange(10)
+        indices = [0, 5, 7, 10, 12]
+        res = array_split(a, indices, axis=-1)
+        desired = [np.array([]), np.arange(0, 5), np.arange(5, 7),
+                   np.arange(7, 10), np.array([]), np.array([])]
+        compare_results(res, desired)
+
+
+class TestSplit(TestCase):
+    # The split function is essentially the same as array_split,
+    # except that it test if splitting will result in an
+    # equal split.  Only test for this case.
+
+    def test_equal_split(self):
+        a = np.arange(10)
+        res = split(a, 2)
+        desired = [np.arange(5), np.arange(5, 10)]
+        compare_results(res, desired)
+
+    def test_unequal_split(self):
+        a = np.arange(10)
+        assert_raises(ValueError, split, a, 3)
+
+
+class TestDstack(TestCase):
+    def test_0D_array(self):
+        a = np.array(1)
+        b = np.array(2)
+        res = dstack([a, b])
+        desired = np.array([[[1, 2]]])
+        assert_array_equal(res, desired)
+
+    def test_1D_array(self):
+        a = np.array([1])
+        b = np.array([2])
+        res = dstack([a, b])
+        desired = np.array([[[1, 2]]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array(self):
+        a = np.array([[1], [2]])
+        b = np.array([[1], [2]])
+        res = dstack([a, b])
+        desired = np.array([[[1, 1]], [[2, 2, ]]])
+        assert_array_equal(res, desired)
+
+    def test_2D_array2(self):
+        a = np.array([1, 2])
+        b = np.array([1, 2])
+        res = dstack([a, b])
+        desired = np.array([[[1, 1], [2, 2]]])
+        assert_array_equal(res, desired)
+
+
+# array_split has more comprehensive test of splitting.
+# only do simple test on hsplit, vsplit, and dsplit
+class TestHsplit(TestCase):
+    """Only testing for integer splits.
+
+    """
+    def test_0D_array(self):
+        a = np.array(1)
+        try:
+            hsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_1D_array(self):
+        a = np.array([1, 2, 3, 4])
+        res = hsplit(a, 2)
+        desired = [np.array([1, 2]), np.array([3, 4])]
+        compare_results(res, desired)
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        res = hsplit(a, 2)
+        desired = [np.array([[1, 2], [1, 2]]), np.array([[3, 4], [3, 4]])]
+        compare_results(res, desired)
+
+
+class TestVsplit(TestCase):
+    """Only testing for integer splits.
+
+    """
+    def test_1D_array(self):
+        a = np.array([1, 2, 3, 4])
+        try:
+            vsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        res = vsplit(a, 2)
+        desired = [np.array([[1, 2, 3, 4]]), np.array([[1, 2, 3, 4]])]
+        compare_results(res, desired)
+
+
+class TestDsplit(TestCase):
+    # Only testing for integer splits.
+
+    def test_2D_array(self):
+        a = np.array([[1, 2, 3, 4],
+                  [1, 2, 3, 4]])
+        try:
+            dsplit(a, 2)
+            assert_(0)
+        except ValueError:
+            pass
+
+    def test_3D_array(self):
+        a = np.array([[[1, 2, 3, 4],
+                   [1, 2, 3, 4]],
+                  [[1, 2, 3, 4],
+                   [1, 2, 3, 4]]])
+        res = dsplit(a, 2)
+        desired = [np.array([[[1, 2], [1, 2]], [[1, 2], [1, 2]]]),
+                   np.array([[[3, 4], [3, 4]], [[3, 4], [3, 4]]])]
+        compare_results(res, desired)
+
+
+class TestSqueeze(TestCase):
+    def test_basic(self):
+        from numpy.random import rand
+
+        a = rand(20, 10, 10, 1, 1)
+        b = rand(20, 1, 10, 1, 20)
+        c = rand(1, 1, 20, 10)
+        assert_array_equal(np.squeeze(a), np.reshape(a, (20, 10, 10)))
+        assert_array_equal(np.squeeze(b), np.reshape(b, (20, 10, 20)))
+        assert_array_equal(np.squeeze(c), np.reshape(c, (20, 10)))
+
+        # Squeezing to 0-dim should still give an ndarray
+        a = [[[1.5]]]
+        res = np.squeeze(a)
+        assert_equal(res, 1.5)
+        assert_equal(res.ndim, 0)
+        assert_equal(type(res), np.ndarray)
+
+
+class TestKron(TestCase):
+    def test_return_type(self):
+        a = np.ones([2, 2])
+        m = np.asmatrix(a)
+        assert_equal(type(kron(a, a)), np.ndarray)
+        assert_equal(type(kron(m, m)), np.matrix)
+        assert_equal(type(kron(a, m)), np.matrix)
+        assert_equal(type(kron(m, a)), np.matrix)
+
+        class myarray(np.ndarray):
+            __array_priority__ = 0.0
+
+        ma = myarray(a.shape, a.dtype, a.data)
+        assert_equal(type(kron(a, a)), np.ndarray)
+        assert_equal(type(kron(ma, ma)), myarray)
+        assert_equal(type(kron(a, ma)), np.ndarray)
+        assert_equal(type(kron(ma, a)), myarray)
+
+
+class TestTile(TestCase):
+    def test_basic(self):
+        a = np.array([0, 1, 2])
+        b = [[1, 2], [3, 4]]
+        assert_equal(tile(a, 2), [0, 1, 2, 0, 1, 2])
+        assert_equal(tile(a, (2, 2)), [[0, 1, 2, 0, 1, 2], [0, 1, 2, 0, 1, 2]])
+        assert_equal(tile(a, (1, 2)), [[0, 1, 2, 0, 1, 2]])
+        assert_equal(tile(b, 2), [[1, 2, 1, 2], [3, 4, 3, 4]])
+        assert_equal(tile(b, (2, 1)), [[1, 2], [3, 4], [1, 2], [3, 4]])
+        assert_equal(tile(b, (2, 2)), [[1, 2, 1, 2], [3, 4, 3, 4],
+                                       [1, 2, 1, 2], [3, 4, 3, 4]])
+
+    def test_tile_one_repetition_on_array_gh4679(self):
+        a = np.arange(5)
+        b = tile(a, 1)
+        b += 2
+        assert_equal(a, np.arange(5))
+
+    def test_empty(self):
+        a = np.array([[[]]])
+        b = np.array([[], []])
+        c = tile(b, 2).shape
+        d = tile(a, (3, 2, 5)).shape
+        assert_equal(c, (2, 0))
+        assert_equal(d, (3, 2, 0))
+
+    def test_kroncompare(self):
+        from numpy.random import randint
+
+        reps = [(2,), (1, 2), (2, 1), (2, 2), (2, 3, 2), (3, 2)]
+        shape = [(3,), (2, 3), (3, 4, 3), (3, 2, 3), (4, 3, 2, 4), (2, 2)]
+        for s in shape:
+            b = randint(0, 10, size=s)
+            for r in reps:
+                a = np.ones(r, b.dtype)
+                large = tile(b, r)
+                klarge = kron(a, b)
+                assert_equal(large, klarge)
+
+
+class TestMayShareMemory(TestCase):
+    def test_basic(self):
+        d = np.ones((50, 60))
+        d2 = np.ones((30, 60, 6))
+        self.assertTrue(np.may_share_memory(d, d))
+        self.assertTrue(np.may_share_memory(d, d[::-1]))
+        self.assertTrue(np.may_share_memory(d, d[::2]))
+        self.assertTrue(np.may_share_memory(d, d[1:, ::-1]))
+
+        self.assertFalse(np.may_share_memory(d[::-1], d2))
+        self.assertFalse(np.may_share_memory(d[::2], d2))
+        self.assertFalse(np.may_share_memory(d[1:, ::-1], d2))
+        self.assertTrue(np.may_share_memory(d2[1:, ::-1], d2))
+
+
+# Utility
+def compare_results(res, desired):
+    for i in range(len(desired)):
+        assert_array_equal(res[i], desired[i])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
new file mode 100644
index 0000000000..06e6590023
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
@@ -0,0 +1,413 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    run_module_suite, assert_equal, assert_array_equal,
+    assert_raises, assert_
+    )
+from numpy.lib.stride_tricks import (
+    as_strided, broadcast_arrays, _broadcast_shape, broadcast_to
+)
+
+def assert_shapes_correct(input_shapes, expected_shape):
+    # Broadcast a list of arrays with the given input shapes and check the
+    # common output shape.
+
+    inarrays = [np.zeros(s) for s in input_shapes]
+    outarrays = broadcast_arrays(*inarrays)
+    outshapes = [a.shape for a in outarrays]
+    expected = [expected_shape] * len(inarrays)
+    assert_equal(outshapes, expected)
+
+
+def assert_incompatible_shapes_raise(input_shapes):
+    # Broadcast a list of arrays with the given (incompatible) input shapes
+    # and check that they raise a ValueError.
+
+    inarrays = [np.zeros(s) for s in input_shapes]
+    assert_raises(ValueError, broadcast_arrays, *inarrays)
+
+
+def assert_same_as_ufunc(shape0, shape1, transposed=False, flipped=False):
+    # Broadcast two shapes against each other and check that the data layout
+    # is the same as if a ufunc did the broadcasting.
+
+    x0 = np.zeros(shape0, dtype=int)
+    # Note that multiply.reduce's identity element is 1.0, so when shape1==(),
+    # this gives the desired n==1.
+    n = int(np.multiply.reduce(shape1))
+    x1 = np.arange(n).reshape(shape1)
+    if transposed:
+        x0 = x0.T
+        x1 = x1.T
+    if flipped:
+        x0 = x0[::-1]
+        x1 = x1[::-1]
+    # Use the add ufunc to do the broadcasting. Since we're adding 0s to x1, the
+    # result should be exactly the same as the broadcasted view of x1.
+    y = x0 + x1
+    b0, b1 = broadcast_arrays(x0, x1)
+    assert_array_equal(y, b1)
+
+
+def test_same():
+    x = np.arange(10)
+    y = np.arange(10)
+    bx, by = broadcast_arrays(x, y)
+    assert_array_equal(x, bx)
+    assert_array_equal(y, by)
+
+
+def test_one_off():
+    x = np.array([[1, 2, 3]])
+    y = np.array([[1], [2], [3]])
+    bx, by = broadcast_arrays(x, y)
+    bx0 = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
+    by0 = bx0.T
+    assert_array_equal(bx0, bx)
+    assert_array_equal(by0, by)
+
+
+def test_same_input_shapes():
+    # Check that the final shape is just the input shape.
+
+    data = [
+        (),
+        (1,),
+        (3,),
+        (0, 1),
+        (0, 3),
+        (1, 0),
+        (3, 0),
+        (1, 3),
+        (3, 1),
+        (3, 3),
+    ]
+    for shape in data:
+        input_shapes = [shape]
+        # Single input.
+        assert_shapes_correct(input_shapes, shape)
+        # Double input.
+        input_shapes2 = [shape, shape]
+        assert_shapes_correct(input_shapes2, shape)
+        # Triple input.
+        input_shapes3 = [shape, shape, shape]
+        assert_shapes_correct(input_shapes3, shape)
+
+
+def test_two_compatible_by_ones_input_shapes():
+    # Check that two different input shapes of the same length, but some have
+    # ones, broadcast to the correct shape.
+
+    data = [
+        [[(1,), (3,)], (3,)],
+        [[(1, 3), (3, 3)], (3, 3)],
+        [[(3, 1), (3, 3)], (3, 3)],
+        [[(1, 3), (3, 1)], (3, 3)],
+        [[(1, 1), (3, 3)], (3, 3)],
+        [[(1, 1), (1, 3)], (1, 3)],
+        [[(1, 1), (3, 1)], (3, 1)],
+        [[(1, 0), (0, 0)], (0, 0)],
+        [[(0, 1), (0, 0)], (0, 0)],
+        [[(1, 0), (0, 1)], (0, 0)],
+        [[(1, 1), (0, 0)], (0, 0)],
+        [[(1, 1), (1, 0)], (1, 0)],
+        [[(1, 1), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_shapes_correct(input_shapes, expected_shape)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_shapes_correct(input_shapes[::-1], expected_shape)
+
+
+def test_two_compatible_by_prepending_ones_input_shapes():
+    # Check that two different input shapes (of different lengths) broadcast
+    # to the correct shape.
+
+    data = [
+        [[(), (3,)], (3,)],
+        [[(3,), (3, 3)], (3, 3)],
+        [[(3,), (3, 1)], (3, 3)],
+        [[(1,), (3, 3)], (3, 3)],
+        [[(), (3, 3)], (3, 3)],
+        [[(1, 1), (3,)], (1, 3)],
+        [[(1,), (3, 1)], (3, 1)],
+        [[(1,), (1, 3)], (1, 3)],
+        [[(), (1, 3)], (1, 3)],
+        [[(), (3, 1)], (3, 1)],
+        [[(), (0,)], (0,)],
+        [[(0,), (0, 0)], (0, 0)],
+        [[(0,), (0, 1)], (0, 0)],
+        [[(1,), (0, 0)], (0, 0)],
+        [[(), (0, 0)], (0, 0)],
+        [[(1, 1), (0,)], (1, 0)],
+        [[(1,), (0, 1)], (0, 1)],
+        [[(1,), (1, 0)], (1, 0)],
+        [[(), (1, 0)], (1, 0)],
+        [[(), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_shapes_correct(input_shapes, expected_shape)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_shapes_correct(input_shapes[::-1], expected_shape)
+
+
+def test_incompatible_shapes_raise_valueerror():
+    # Check that a ValueError is raised for incompatible shapes.
+
+    data = [
+        [(3,), (4,)],
+        [(2, 3), (2,)],
+        [(3,), (3,), (4,)],
+        [(1, 3, 4), (2, 3, 3)],
+    ]
+    for input_shapes in data:
+        assert_incompatible_shapes_raise(input_shapes)
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_incompatible_shapes_raise(input_shapes[::-1])
+
+
+def test_same_as_ufunc():
+    # Check that the data layout is the same as if a ufunc did the operation.
+
+    data = [
+        [[(1,), (3,)], (3,)],
+        [[(1, 3), (3, 3)], (3, 3)],
+        [[(3, 1), (3, 3)], (3, 3)],
+        [[(1, 3), (3, 1)], (3, 3)],
+        [[(1, 1), (3, 3)], (3, 3)],
+        [[(1, 1), (1, 3)], (1, 3)],
+        [[(1, 1), (3, 1)], (3, 1)],
+        [[(1, 0), (0, 0)], (0, 0)],
+        [[(0, 1), (0, 0)], (0, 0)],
+        [[(1, 0), (0, 1)], (0, 0)],
+        [[(1, 1), (0, 0)], (0, 0)],
+        [[(1, 1), (1, 0)], (1, 0)],
+        [[(1, 1), (0, 1)], (0, 1)],
+        [[(), (3,)], (3,)],
+        [[(3,), (3, 3)], (3, 3)],
+        [[(3,), (3, 1)], (3, 3)],
+        [[(1,), (3, 3)], (3, 3)],
+        [[(), (3, 3)], (3, 3)],
+        [[(1, 1), (3,)], (1, 3)],
+        [[(1,), (3, 1)], (3, 1)],
+        [[(1,), (1, 3)], (1, 3)],
+        [[(), (1, 3)], (1, 3)],
+        [[(), (3, 1)], (3, 1)],
+        [[(), (0,)], (0,)],
+        [[(0,), (0, 0)], (0, 0)],
+        [[(0,), (0, 1)], (0, 0)],
+        [[(1,), (0, 0)], (0, 0)],
+        [[(), (0, 0)], (0, 0)],
+        [[(1, 1), (0,)], (1, 0)],
+        [[(1,), (0, 1)], (0, 1)],
+        [[(1,), (1, 0)], (1, 0)],
+        [[(), (1, 0)], (1, 0)],
+        [[(), (0, 1)], (0, 1)],
+    ]
+    for input_shapes, expected_shape in data:
+        assert_same_as_ufunc(input_shapes[0], input_shapes[1],
+                             "Shapes: %s %s" % (input_shapes[0], input_shapes[1]))
+        # Reverse the input shapes since broadcasting should be symmetric.
+        assert_same_as_ufunc(input_shapes[1], input_shapes[0])
+        # Try them transposed, too.
+        assert_same_as_ufunc(input_shapes[0], input_shapes[1], True)
+        # ... and flipped for non-rank-0 inputs in order to test negative
+        # strides.
+        if () not in input_shapes:
+            assert_same_as_ufunc(input_shapes[0], input_shapes[1], False, True)
+            assert_same_as_ufunc(input_shapes[0], input_shapes[1], True, True)
+
+
+def test_broadcast_to_succeeds():
+    data = [
+        [np.array(0), (0,), np.array(0)],
+        [np.array(0), (1,), np.zeros(1)],
+        [np.array(0), (3,), np.zeros(3)],
+        [np.ones(1), (1,), np.ones(1)],
+        [np.ones(1), (2,), np.ones(2)],
+        [np.ones(1), (1, 2, 3), np.ones((1, 2, 3))],
+        [np.arange(3), (3,), np.arange(3)],
+        [np.arange(3), (1, 3), np.arange(3).reshape(1, -1)],
+        [np.arange(3), (2, 3), np.array([[0, 1, 2], [0, 1, 2]])],
+        # test if shape is not a tuple
+        [np.ones(0), 0, np.ones(0)],
+        [np.ones(1), 1, np.ones(1)],
+        [np.ones(1), 2, np.ones(2)],
+        # these cases with size 0 are strange, but they reproduce the behavior
+        # of broadcasting with ufuncs (see test_same_as_ufunc above)
+        [np.ones(1), (0,), np.ones(0)],
+        [np.ones((1, 2)), (0, 2), np.ones((0, 2))],
+        [np.ones((2, 1)), (2, 0), np.ones((2, 0))],
+    ]
+    for input_array, shape, expected in data:
+        actual = broadcast_to(input_array, shape)
+        assert_array_equal(expected, actual)
+
+
+def test_broadcast_to_raises():
+    data = [
+        [(0,), ()],
+        [(1,), ()],
+        [(3,), ()],
+        [(3,), (1,)],
+        [(3,), (2,)],
+        [(3,), (4,)],
+        [(1, 2), (2, 1)],
+        [(1, 1), (1,)],
+        [(1,), -1],
+        [(1,), (-1,)],
+        [(1, 2), (-1, 2)],
+    ]
+    for orig_shape, target_shape in data:
+        arr = np.zeros(orig_shape)
+        assert_raises(ValueError, lambda: broadcast_to(arr, target_shape))
+
+
+def test_broadcast_shape():
+    # broadcast_shape is already exercized indirectly by broadcast_arrays
+    assert_raises(ValueError, _broadcast_shape)
+    assert_equal(_broadcast_shape([1, 2]), (2,))
+    assert_equal(_broadcast_shape(np.ones((1, 1))), (1, 1))
+    assert_equal(_broadcast_shape(np.ones((1, 1)), np.ones((3, 4))), (3, 4))
+    assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 32)), (1, 2))
+    assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 100)), (1, 2))
+
+    # regression tests for gh-5862
+    assert_equal(_broadcast_shape(*([np.ones(2)] * 32 + [1])), (2,))
+    bad_args = [np.ones(2)] * 32 + [np.ones(3)] * 32
+    assert_raises(ValueError, lambda: _broadcast_shape(*bad_args))
+
+
+def test_as_strided():
+    a = np.array([None])
+    a_view = as_strided(a)
+    expected = np.array([None])
+    assert_array_equal(a_view, np.array([None]))
+
+    a = np.array([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,))
+    expected = np.array([1, 3])
+    assert_array_equal(a_view, expected)
+
+    a = np.array([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(3, 4), strides=(0, 1 * a.itemsize))
+    expected = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
+    assert_array_equal(a_view, expected)
+
+    # Regression test for gh-5081
+    dt = np.dtype([('num', 'i4'), ('obj', 'O')])
+    a = np.empty((4,), dtype=dt)
+    a['num'] = np.arange(1, 5)
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    expected_num = [[1, 2, 3, 4]] * 3
+    expected_obj = [[None]*4]*3
+    assert_equal(a_view.dtype, dt)
+    assert_array_equal(expected_num, a_view['num'])
+    assert_array_equal(expected_obj, a_view['obj'])
+
+    # Make sure that void types without fields are kept unchanged
+    a = np.empty((4,), dtype='V4')
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    assert_equal(a.dtype, a_view.dtype)
+
+    # Make sure that the only type that could fail is properly handled
+    dt = np.dtype({'names': [''], 'formats': ['V4']})
+    a = np.empty((4,), dtype=dt)
+    a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize))
+    assert_equal(a.dtype, a_view.dtype)
+
+
+class VerySimpleSubClass(np.ndarray):
+    def __new__(cls, *args, **kwargs):
+        kwargs['subok'] = True
+        return np.array(*args, **kwargs).view(cls)
+
+
+class SimpleSubClass(VerySimpleSubClass):
+    def __new__(cls, *args, **kwargs):
+        kwargs['subok'] = True
+        self = np.array(*args, **kwargs).view(cls)
+        self.info = 'simple'
+        return self
+
+    def __array_finalize__(self, obj):
+        self.info = getattr(obj, 'info', '') + ' finalized'
+
+
+def test_subclasses():
+    # test that subclass is preserved only if subok=True
+    a = VerySimpleSubClass([1, 2, 3, 4])
+    assert_(type(a) is VerySimpleSubClass)
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,))
+    assert_(type(a_view) is np.ndarray)
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True)
+    assert_(type(a_view) is VerySimpleSubClass)
+    # test that if a subclass has __array_finalize__, it is used
+    a = SimpleSubClass([1, 2, 3, 4])
+    a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+
+    # similar tests for broadcast_arrays
+    b = np.arange(len(a)).reshape(-1, 1)
+    a_view, b_view = broadcast_arrays(a, b)
+    assert_(type(a_view) is np.ndarray)
+    assert_(type(b_view) is np.ndarray)
+    assert_(a_view.shape == b_view.shape)
+    a_view, b_view = broadcast_arrays(a, b, subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+    assert_(type(b_view) is np.ndarray)
+    assert_(a_view.shape == b_view.shape)
+
+    # and for broadcast_to
+    shape = (2, 4)
+    a_view = broadcast_to(a, shape)
+    assert_(type(a_view) is np.ndarray)
+    assert_(a_view.shape == shape)
+    a_view = broadcast_to(a, shape, subok=True)
+    assert_(type(a_view) is SimpleSubClass)
+    assert_(a_view.info == 'simple finalized')
+    assert_(a_view.shape == shape)
+
+
+def test_writeable():
+    # broadcast_to should return a readonly array
+    original = np.array([1, 2, 3])
+    result = broadcast_to(original, (2, 3))
+    assert_equal(result.flags.writeable, False)
+    assert_raises(ValueError, result.__setitem__, slice(None), 0)
+
+    # but the result of broadcast_arrays needs to be writeable (for now), to
+    # preserve backwards compatibility
+    for results in [broadcast_arrays(original),
+                    broadcast_arrays(0, original)]:
+        for result in results:
+            assert_equal(result.flags.writeable, True)
+    # keep readonly input readonly
+    original.flags.writeable = False
+    _, result = broadcast_arrays(0, original)
+    assert_equal(result.flags.writeable, False)
+
+    # regresssion test for GH6491
+    shape = (2,)
+    strides = [0]
+    tricky_array = as_strided(np.array(0), shape, strides)
+    other = np.zeros((1,))
+    first, second = broadcast_arrays(tricky_array, other)
+    assert_(first.shape == second.shape)
+
+
+def test_reference_types():
+    input_array = np.array('a', dtype=object)
+    expected = np.array(['a'] * 3, dtype=object)
+    actual = broadcast_to(input_array, (3,))
+    assert_array_equal(expected, actual)
+
+    actual, _ = broadcast_arrays(input_array, np.ones(3))
+    assert_array_equal(expected, actual)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
new file mode 100644
index 0000000000..b65a8df97d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
@@ -0,0 +1,535 @@
+"""Test functions for matrix module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_array_max_ulp, assert_array_almost_equal, assert_raises, rand,
+    )
+
+from numpy import (
+    arange, rot90, add, fliplr, flipud, zeros, ones, eye, array, diag,
+    histogram2d, tri, mask_indices, triu_indices, triu_indices_from,
+    tril_indices, tril_indices_from, vander,
+    )
+
+import numpy as np
+from numpy.compat import asbytes_nested
+
+
+def get_mat(n):
+    data = arange(n)
+    data = add.outer(data, data)
+    return data
+
+
+class TestEye(TestCase):
+    def test_basic(self):
+        assert_equal(eye(4),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1]]))
+
+        assert_equal(eye(4, dtype='f'),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1]], 'f'))
+
+        assert_equal(eye(3) == 1,
+                     eye(3, dtype=bool))
+
+    def test_diag(self):
+        assert_equal(eye(4, k=1),
+                     array([[0, 1, 0, 0],
+                            [0, 0, 1, 0],
+                            [0, 0, 0, 1],
+                            [0, 0, 0, 0]]))
+
+        assert_equal(eye(4, k=-1),
+                     array([[0, 0, 0, 0],
+                            [1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0]]))
+
+    def test_2d(self):
+        assert_equal(eye(4, 3),
+                     array([[1, 0, 0],
+                            [0, 1, 0],
+                            [0, 0, 1],
+                            [0, 0, 0]]))
+
+        assert_equal(eye(3, 4),
+                     array([[1, 0, 0, 0],
+                            [0, 1, 0, 0],
+                            [0, 0, 1, 0]]))
+
+    def test_diag2d(self):
+        assert_equal(eye(3, 4, k=2),
+                     array([[0, 0, 1, 0],
+                            [0, 0, 0, 1],
+                            [0, 0, 0, 0]]))
+
+        assert_equal(eye(4, 3, k=-2),
+                     array([[0, 0, 0],
+                            [0, 0, 0],
+                            [1, 0, 0],
+                            [0, 1, 0]]))
+
+    def test_eye_bounds(self):
+        assert_equal(eye(2, 2, 1), [[0, 1], [0, 0]])
+        assert_equal(eye(2, 2, -1), [[0, 0], [1, 0]])
+        assert_equal(eye(2, 2, 2), [[0, 0], [0, 0]])
+        assert_equal(eye(2, 2, -2), [[0, 0], [0, 0]])
+        assert_equal(eye(3, 2, 2), [[0, 0], [0, 0], [0, 0]])
+        assert_equal(eye(3, 2, 1), [[0, 1], [0, 0], [0, 0]])
+        assert_equal(eye(3, 2, -1), [[0, 0], [1, 0], [0, 1]])
+        assert_equal(eye(3, 2, -2), [[0, 0], [0, 0], [1, 0]])
+        assert_equal(eye(3, 2, -3), [[0, 0], [0, 0], [0, 0]])
+
+    def test_strings(self):
+        assert_equal(eye(2, 2, dtype='S3'),
+                     asbytes_nested([['1', ''], ['', '1']]))
+
+    def test_bool(self):
+        assert_equal(eye(2, 2, dtype=bool), [[True, False], [False, True]])
+
+
+class TestDiag(TestCase):
+    def test_vector(self):
+        vals = (100 * arange(5)).astype('l')
+        b = zeros((5, 5))
+        for k in range(5):
+            b[k, k] = vals[k]
+        assert_equal(diag(vals), b)
+        b = zeros((7, 7))
+        c = b.copy()
+        for k in range(5):
+            b[k, k + 2] = vals[k]
+            c[k + 2, k] = vals[k]
+        assert_equal(diag(vals, k=2), b)
+        assert_equal(diag(vals, k=-2), c)
+
+    def test_matrix(self, vals=None):
+        if vals is None:
+            vals = (100 * get_mat(5) + 1).astype('l')
+        b = zeros((5,))
+        for k in range(5):
+            b[k] = vals[k, k]
+        assert_equal(diag(vals), b)
+        b = b * 0
+        for k in range(3):
+            b[k] = vals[k, k + 2]
+        assert_equal(diag(vals, 2), b[:3])
+        for k in range(3):
+            b[k] = vals[k + 2, k]
+        assert_equal(diag(vals, -2), b[:3])
+
+    def test_fortran_order(self):
+        vals = array((100 * get_mat(5) + 1), order='F', dtype='l')
+        self.test_matrix(vals)
+
+    def test_diag_bounds(self):
+        A = [[1, 2], [3, 4], [5, 6]]
+        assert_equal(diag(A, k=2), [])
+        assert_equal(diag(A, k=1), [2])
+        assert_equal(diag(A, k=0), [1, 4])
+        assert_equal(diag(A, k=-1), [3, 6])
+        assert_equal(diag(A, k=-2), [5])
+        assert_equal(diag(A, k=-3), [])
+
+    def test_failure(self):
+        self.assertRaises(ValueError, diag, [[[1]]])
+
+
+class TestFliplr(TestCase):
+    def test_basic(self):
+        self.assertRaises(ValueError, fliplr, ones(4))
+        a = get_mat(4)
+        b = a[:, ::-1]
+        assert_equal(fliplr(a), b)
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b = [[2, 1, 0],
+             [5, 4, 3]]
+        assert_equal(fliplr(a), b)
+
+
+class TestFlipud(TestCase):
+    def test_basic(self):
+        a = get_mat(4)
+        b = a[::-1, :]
+        assert_equal(flipud(a), b)
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b = [[3, 4, 5],
+             [0, 1, 2]]
+        assert_equal(flipud(a), b)
+
+
+class TestRot90(TestCase):
+    def test_basic(self):
+        self.assertRaises(ValueError, rot90, ones(4))
+
+        a = [[0, 1, 2],
+             [3, 4, 5]]
+        b1 = [[2, 5],
+              [1, 4],
+              [0, 3]]
+        b2 = [[5, 4, 3],
+              [2, 1, 0]]
+        b3 = [[3, 0],
+              [4, 1],
+              [5, 2]]
+        b4 = [[0, 1, 2],
+              [3, 4, 5]]
+
+        for k in range(-3, 13, 4):
+            assert_equal(rot90(a, k=k), b1)
+        for k in range(-2, 13, 4):
+            assert_equal(rot90(a, k=k), b2)
+        for k in range(-1, 13, 4):
+            assert_equal(rot90(a, k=k), b3)
+        for k in range(0, 13, 4):
+            assert_equal(rot90(a, k=k), b4)
+
+    def test_axes(self):
+        a = ones((50, 40, 3))
+        assert_equal(rot90(a).shape, (40, 50, 3))
+
+
+class TestHistogram2d(TestCase):
+    def test_simple(self):
+        x = array(
+            [0.41702200, 0.72032449, 1.1437481e-4, 0.302332573, 0.146755891])
+        y = array(
+            [0.09233859, 0.18626021, 0.34556073, 0.39676747, 0.53881673])
+        xedges = np.linspace(0, 1, 10)
+        yedges = np.linspace(0, 1, 10)
+        H = histogram2d(x, y, (xedges, yedges))[0]
+        answer = array(
+            [[0, 0, 0, 1, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 1, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [1, 0, 1, 0, 0, 0, 0, 0, 0],
+             [0, 1, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0],
+             [0, 0, 0, 0, 0, 0, 0, 0, 0]])
+        assert_array_equal(H.T, answer)
+        H = histogram2d(x, y, xedges)[0]
+        assert_array_equal(H.T, answer)
+        H, xedges, yedges = histogram2d(list(range(10)), list(range(10)))
+        assert_array_equal(H, eye(10, 10))
+        assert_array_equal(xedges, np.linspace(0, 9, 11))
+        assert_array_equal(yedges, np.linspace(0, 9, 11))
+
+    def test_asym(self):
+        x = array([1, 1, 2, 3, 4, 4, 4, 5])
+        y = array([1, 3, 2, 0, 1, 2, 3, 4])
+        H, xed, yed = histogram2d(
+            x, y, (6, 5), range=[[0, 6], [0, 5]], normed=True)
+        answer = array(
+            [[0., 0, 0, 0, 0],
+             [0, 1, 0, 1, 0],
+             [0, 0, 1, 0, 0],
+             [1, 0, 0, 0, 0],
+             [0, 1, 1, 1, 0],
+             [0, 0, 0, 0, 1]])
+        assert_array_almost_equal(H, answer/8., 3)
+        assert_array_equal(xed, np.linspace(0, 6, 7))
+        assert_array_equal(yed, np.linspace(0, 5, 6))
+
+    def test_norm(self):
+        x = array([1, 2, 3, 1, 2, 3, 1, 2, 3])
+        y = array([1, 1, 1, 2, 2, 2, 3, 3, 3])
+        H, xed, yed = histogram2d(
+            x, y, [[1, 2, 3, 5], [1, 2, 3, 5]], normed=True)
+        answer = array([[1, 1, .5],
+                        [1, 1, .5],
+                        [.5, .5, .25]])/9.
+        assert_array_almost_equal(H, answer, 3)
+
+    def test_all_outliers(self):
+        r = rand(100) + 1. + 1e6  # histogramdd rounds by decimal=6
+        H, xed, yed = histogram2d(r, r, (4, 5), range=([0, 1], [0, 1]))
+        assert_array_equal(H, 0)
+
+    def test_empty(self):
+        a, edge1, edge2 = histogram2d([], [], bins=([0, 1], [0, 1]))
+        assert_array_max_ulp(a, array([[0.]]))
+
+        a, edge1, edge2 = histogram2d([], [], bins=4)
+        assert_array_max_ulp(a, np.zeros((4, 4)))
+
+    def test_binparameter_combination(self):
+        x = array(
+            [0, 0.09207008,  0.64575234,  0.12875982,  0.47390599,  
+             0.59944483, 1])
+        y = array(
+            [0, 0.14344267,  0.48988575,  0.30558665,  0.44700682,  
+             0.15886423, 1])
+        edges = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1)
+        H, xe, ye = histogram2d(x, y, (edges, 4))
+        answer = array(
+            [[ 2.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 1.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  1.]])
+        assert_array_equal(H, answer)
+        assert_array_equal(ye, array([0., 0.25, 0.5, 0.75, 1]))
+        H, xe, ye = histogram2d(x, y, (4, edges))
+        answer = array(
+            [[ 1.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
+             [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])
+        assert_array_equal(H, answer)
+        assert_array_equal(xe, array([0., 0.25, 0.5, 0.75, 1]))
+
+
+class TestTri(TestCase):
+    def test_dtype(self):
+        out = array([[1, 0, 0],
+                     [1, 1, 0],
+                     [1, 1, 1]])
+        assert_array_equal(tri(3), out)
+        assert_array_equal(tri(3, dtype=bool), out.astype(bool))
+
+
+def test_tril_triu_ndim2():
+    for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']:
+        a = np.ones((2, 2), dtype=dtype)
+        b = np.tril(a)
+        c = np.triu(a)
+        yield assert_array_equal, b, [[1, 0], [1, 1]]
+        yield assert_array_equal, c, b.T
+        # should return the same dtype as the original array
+        yield assert_equal, b.dtype, a.dtype
+        yield assert_equal, c.dtype, a.dtype
+
+
+def test_tril_triu_ndim3():
+    for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']:
+        a = np.array([
+            [[1, 1], [1, 1]],
+            [[1, 1], [1, 0]],
+            [[1, 1], [0, 0]],
+            ], dtype=dtype)
+        a_tril_desired = np.array([
+            [[1, 0], [1, 1]],
+            [[1, 0], [1, 0]],
+            [[1, 0], [0, 0]],
+            ], dtype=dtype)
+        a_triu_desired = np.array([
+            [[1, 1], [0, 1]],
+            [[1, 1], [0, 0]],
+            [[1, 1], [0, 0]],
+            ], dtype=dtype)
+        a_triu_observed = np.triu(a)
+        a_tril_observed = np.tril(a)
+        yield assert_array_equal, a_triu_observed, a_triu_desired
+        yield assert_array_equal, a_tril_observed, a_tril_desired
+        yield assert_equal, a_triu_observed.dtype, a.dtype
+        yield assert_equal, a_tril_observed.dtype, a.dtype
+
+def test_tril_triu_with_inf():
+    # Issue 4859
+    arr = np.array([[1, 1, np.inf],
+                    [1, 1, 1],
+                    [np.inf, 1, 1]])
+    out_tril = np.array([[1, 0, 0],
+                         [1, 1, 0],
+                         [np.inf, 1, 1]])
+    out_triu = out_tril.T
+    assert_array_equal(np.triu(arr), out_triu)
+    assert_array_equal(np.tril(arr), out_tril)
+
+
+def test_tril_triu_dtype():
+    # Issue 4916
+    # tril and triu should return the same dtype as input
+    for c in np.typecodes['All']:
+        if c == 'V':
+            continue
+        arr = np.zeros((3, 3), dtype=c)
+        assert_equal(np.triu(arr).dtype, arr.dtype)
+        assert_equal(np.tril(arr).dtype, arr.dtype)
+
+    # check special cases
+    arr = np.array([['2001-01-01T12:00', '2002-02-03T13:56'],
+                    ['2004-01-01T12:00', '2003-01-03T13:45']],
+                   dtype='datetime64')
+    assert_equal(np.triu(arr).dtype, arr.dtype)
+    assert_equal(np.tril(arr).dtype, arr.dtype)
+
+    arr = np.zeros((3,3), dtype='f4,f4')
+    assert_equal(np.triu(arr).dtype, arr.dtype)
+    assert_equal(np.tril(arr).dtype, arr.dtype)
+
+
+def test_mask_indices():
+    # simple test without offset
+    iu = mask_indices(3, np.triu)
+    a = np.arange(9).reshape(3, 3)
+    yield (assert_array_equal, a[iu], array([0, 1, 2, 4, 5, 8]))
+    # Now with an offset
+    iu1 = mask_indices(3, np.triu, 1)
+    yield (assert_array_equal, a[iu1], array([1, 2, 5]))
+
+
+def test_tril_indices():
+    # indices without and with offset
+    il1 = tril_indices(4)
+    il2 = tril_indices(4, k=2)
+    il3 = tril_indices(4, m=5)
+    il4 = tril_indices(4, k=2, m=5)
+
+    a = np.array([[1, 2, 3, 4],
+                  [5, 6, 7, 8],
+                  [9, 10, 11, 12],
+                  [13, 14, 15, 16]])
+    b = np.arange(1, 21).reshape(4, 5)
+
+    # indexing:
+    yield (assert_array_equal, a[il1],
+           array([1, 5, 6, 9, 10, 11, 13, 14, 15, 16]))
+    yield (assert_array_equal, b[il3],
+           array([1, 6, 7, 11, 12, 13, 16, 17, 18, 19]))
+
+    # And for assigning values:
+    a[il1] = -1
+    yield (assert_array_equal, a,
+           array([[-1, 2, 3, 4],
+                  [-1, -1, 7, 8],
+                  [-1, -1, -1, 12],
+                  [-1, -1, -1, -1]]))
+    b[il3] = -1
+    yield (assert_array_equal, b,
+           array([[-1, 2, 3, 4, 5],
+                  [-1, -1, 8, 9, 10],
+                  [-1, -1, -1, 14, 15],
+                  [-1, -1, -1, -1, 20]]))
+    # These cover almost the whole array (two diagonals right of the main one):
+    a[il2] = -10
+    yield (assert_array_equal, a,
+           array([[-10, -10, -10, 4],
+                  [-10, -10, -10, -10],
+                  [-10, -10, -10, -10],
+                  [-10, -10, -10, -10]]))
+    b[il4] = -10
+    yield (assert_array_equal, b,
+           array([[-10, -10, -10, 4, 5],
+                  [-10, -10, -10, -10, 10],
+                  [-10, -10, -10, -10, -10],
+                  [-10, -10, -10, -10, -10]]))
+
+
+class TestTriuIndices(object):
+    def test_triu_indices(self):
+        iu1 = triu_indices(4)
+        iu2 = triu_indices(4, k=2)
+        iu3 = triu_indices(4, m=5)
+        iu4 = triu_indices(4, k=2, m=5)
+
+        a = np.array([[1, 2, 3, 4],
+                      [5, 6, 7, 8],
+                      [9, 10, 11, 12],
+                      [13, 14, 15, 16]])
+        b = np.arange(1, 21).reshape(4, 5)
+
+        # Both for indexing:
+        yield (assert_array_equal, a[iu1],
+               array([1, 2, 3, 4, 6, 7, 8, 11, 12, 16]))
+        yield (assert_array_equal, b[iu3],
+               array([1, 2, 3, 4, 5, 7, 8, 9, 10, 13, 14, 15, 19, 20]))
+
+        # And for assigning values:
+        a[iu1] = -1
+        yield (assert_array_equal, a,
+               array([[-1, -1, -1, -1],
+                      [5, -1, -1, -1],
+                      [9, 10, -1, -1],
+                      [13, 14, 15, -1]]))
+        b[iu3] = -1
+        yield (assert_array_equal, b,
+               array([[-1, -1, -1, -1, -1],
+                      [6, -1, -1, -1, -1],
+                      [11, 12, -1, -1, -1],
+                      [16, 17, 18, -1, -1]]))
+
+        # These cover almost the whole array (two diagonals right of the
+        # main one):
+        a[iu2] = -10
+        yield (assert_array_equal, a,
+               array([[-1, -1, -10, -10],
+                      [5, -1, -1, -10],
+                      [9, 10, -1, -1],
+                      [13, 14, 15, -1]]))
+        b[iu4] = -10
+        yield (assert_array_equal, b,
+               array([[-1, -1, -10, -10, -10],
+                      [6, -1, -1, -10, -10],
+                      [11, 12, -1, -1, -10],
+                      [16, 17, 18, -1, -1]]))
+
+
+class TestTrilIndicesFrom(object):
+    def test_exceptions(self):
+        assert_raises(ValueError, tril_indices_from, np.ones((2,)))
+        assert_raises(ValueError, tril_indices_from, np.ones((2, 2, 2)))
+        # assert_raises(ValueError, tril_indices_from, np.ones((2, 3)))
+
+
+class TestTriuIndicesFrom(object):
+    def test_exceptions(self):
+        assert_raises(ValueError, triu_indices_from, np.ones((2,)))
+        assert_raises(ValueError, triu_indices_from, np.ones((2, 2, 2)))
+        # assert_raises(ValueError, triu_indices_from, np.ones((2, 3)))
+
+
+class TestVander(object):
+    def test_basic(self):
+        c = np.array([0, 1, -2, 3])
+        v = vander(c)
+        powers = np.array([[0, 0, 0, 0, 1],
+                           [1, 1, 1, 1, 1],
+                           [16, -8, 4, -2, 1],
+                           [81, 27, 9, 3, 1]])
+        # Check default value of N:
+        yield (assert_array_equal, v, powers[:, 1:])
+        # Check a range of N values, including 0 and 5 (greater than default)
+        m = powers.shape[1]
+        for n in range(6):
+            v = vander(c, N=n)
+            yield (assert_array_equal, v, powers[:, m-n:m])
+
+    def test_dtypes(self):
+        c = array([11, -12, 13], dtype=np.int8)
+        v = vander(c)
+        expected = np.array([[121, 11, 1],
+                             [144, -12, 1],
+                             [169, 13, 1]])
+        yield (assert_array_equal, v, expected)
+
+        c = array([1.0+1j, 1.0-1j])
+        v = vander(c, N=3)
+        expected = np.array([[2j, 1+1j, 1],
+                             [-2j, 1-1j, 1]])
+        # The data is floating point, but the values are small integers,
+        # so assert_array_equal *should* be safe here (rather than, say,
+        # assert_array_almost_equal).
+        yield (assert_array_equal, v, expected)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
new file mode 100644
index 0000000000..f7430c27d1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
@@ -0,0 +1,332 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.compat import long
+from numpy.testing import (
+    TestCase, assert_, assert_equal, assert_array_equal, run_module_suite
+    )
+from numpy.lib.type_check import (
+    common_type, mintypecode, isreal, iscomplex, isposinf, isneginf,
+    nan_to_num, isrealobj, iscomplexobj, asfarray, real_if_close
+    )
+
+
+def assert_all(x):
+    assert_(np.all(x), x)
+
+
+class TestCommonType(TestCase):
+    def test_basic(self):
+        ai32 = np.array([[1, 2], [3, 4]], dtype=np.int32)
+        af16 = np.array([[1, 2], [3, 4]], dtype=np.float16)
+        af32 = np.array([[1, 2], [3, 4]], dtype=np.float32)
+        af64 = np.array([[1, 2], [3, 4]], dtype=np.float64)
+        acs = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.csingle)
+        acd = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.cdouble)
+        assert_(common_type(ai32) == np.float64)
+        assert_(common_type(af16) == np.float16)
+        assert_(common_type(af32) == np.float32)
+        assert_(common_type(af64) == np.float64)
+        assert_(common_type(acs) == np.csingle)
+        assert_(common_type(acd) == np.cdouble)
+
+
+class TestMintypecode(TestCase):
+
+    def test_default_1(self):
+        for itype in '1bcsuwil':
+            assert_equal(mintypecode(itype), 'd')
+        assert_equal(mintypecode('f'), 'f')
+        assert_equal(mintypecode('d'), 'd')
+        assert_equal(mintypecode('F'), 'F')
+        assert_equal(mintypecode('D'), 'D')
+
+    def test_default_2(self):
+        for itype in '1bcsuwil':
+            assert_equal(mintypecode(itype+'f'), 'f')
+            assert_equal(mintypecode(itype+'d'), 'd')
+            assert_equal(mintypecode(itype+'F'), 'F')
+            assert_equal(mintypecode(itype+'D'), 'D')
+        assert_equal(mintypecode('ff'), 'f')
+        assert_equal(mintypecode('fd'), 'd')
+        assert_equal(mintypecode('fF'), 'F')
+        assert_equal(mintypecode('fD'), 'D')
+        assert_equal(mintypecode('df'), 'd')
+        assert_equal(mintypecode('dd'), 'd')
+        #assert_equal(mintypecode('dF',savespace=1),'F')
+        assert_equal(mintypecode('dF'), 'D')
+        assert_equal(mintypecode('dD'), 'D')
+        assert_equal(mintypecode('Ff'), 'F')
+        #assert_equal(mintypecode('Fd',savespace=1),'F')
+        assert_equal(mintypecode('Fd'), 'D')
+        assert_equal(mintypecode('FF'), 'F')
+        assert_equal(mintypecode('FD'), 'D')
+        assert_equal(mintypecode('Df'), 'D')
+        assert_equal(mintypecode('Dd'), 'D')
+        assert_equal(mintypecode('DF'), 'D')
+        assert_equal(mintypecode('DD'), 'D')
+
+    def test_default_3(self):
+        assert_equal(mintypecode('fdF'), 'D')
+        #assert_equal(mintypecode('fdF',savespace=1),'F')
+        assert_equal(mintypecode('fdD'), 'D')
+        assert_equal(mintypecode('fFD'), 'D')
+        assert_equal(mintypecode('dFD'), 'D')
+
+        assert_equal(mintypecode('ifd'), 'd')
+        assert_equal(mintypecode('ifF'), 'F')
+        assert_equal(mintypecode('ifD'), 'D')
+        assert_equal(mintypecode('idF'), 'D')
+        #assert_equal(mintypecode('idF',savespace=1),'F')
+        assert_equal(mintypecode('idD'), 'D')
+
+
+class TestIsscalar(TestCase):
+
+    def test_basic(self):
+        assert_(np.isscalar(3))
+        assert_(not np.isscalar([3]))
+        assert_(not np.isscalar((3,)))
+        assert_(np.isscalar(3j))
+        assert_(np.isscalar(long(10)))
+        assert_(np.isscalar(4.0))
+
+
+class TestReal(TestCase):
+
+    def test_real(self):
+        y = np.random.rand(10,)
+        assert_array_equal(y, np.real(y))
+
+    def test_cmplx(self):
+        y = np.random.rand(10,)+1j*np.random.rand(10,)
+        assert_array_equal(y.real, np.real(y))
+
+
+class TestImag(TestCase):
+
+    def test_real(self):
+        y = np.random.rand(10,)
+        assert_array_equal(0, np.imag(y))
+
+    def test_cmplx(self):
+        y = np.random.rand(10,)+1j*np.random.rand(10,)
+        assert_array_equal(y.imag, np.imag(y))
+
+
+class TestIscomplex(TestCase):
+
+    def test_fail(self):
+        z = np.array([-1, 0, 1])
+        res = iscomplex(z)
+        assert_(not np.sometrue(res, axis=0))
+
+    def test_pass(self):
+        z = np.array([-1j, 1, 0])
+        res = iscomplex(z)
+        assert_array_equal(res, [1, 0, 0])
+
+
+class TestIsreal(TestCase):
+
+    def test_pass(self):
+        z = np.array([-1, 0, 1j])
+        res = isreal(z)
+        assert_array_equal(res, [1, 1, 0])
+
+    def test_fail(self):
+        z = np.array([-1j, 1, 0])
+        res = isreal(z)
+        assert_array_equal(res, [0, 1, 1])
+
+
+class TestIscomplexobj(TestCase):
+
+    def test_basic(self):
+        z = np.array([-1, 0, 1])
+        assert_(not iscomplexobj(z))
+        z = np.array([-1j, 0, -1])
+        assert_(iscomplexobj(z))
+
+
+class TestIsrealobj(TestCase):
+    def test_basic(self):
+        z = np.array([-1, 0, 1])
+        assert_(isrealobj(z))
+        z = np.array([-1j, 0, -1])
+        assert_(not isrealobj(z))
+
+
+class TestIsnan(TestCase):
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isnan(z) == 0
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore'):
+            assert_all(np.isnan(np.array((1.,))/0.) == 0)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore'):
+            assert_all(np.isnan(np.array((-1.,))/0.) == 0)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isnan(np.array((0.,))/0.) == 1)
+
+    def test_integer(self):
+        assert_all(np.isnan(1) == 0)
+
+    def test_complex(self):
+        assert_all(np.isnan(1+1j) == 0)
+
+    def test_complex1(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isnan(np.array(0+0j)/0.) == 1)
+
+
+class TestIsfinite(TestCase):
+    # Fixme, wrong place, isfinite now ufunc
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isfinite(z) == 1
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((1.,))/0.) == 0)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((-1.,))/0.) == 0)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array((0.,))/0.) == 0)
+
+    def test_integer(self):
+        assert_all(np.isfinite(1) == 1)
+
+    def test_complex(self):
+        assert_all(np.isfinite(1+1j) == 1)
+
+    def test_complex1(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isfinite(np.array(1+1j)/0.) == 0)
+
+
+class TestIsinf(TestCase):
+    # Fixme, wrong place, isinf now ufunc
+
+    def test_goodvalues(self):
+        z = np.array((-1., 0., 1.))
+        res = np.isinf(z) == 0
+        assert_all(np.all(res, axis=0))
+
+    def test_posinf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((1.,))/0.) == 1)
+
+    def test_posinf_scalar(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array(1.,)/0.) == 1)
+
+    def test_neginf(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((-1.,))/0.) == 1)
+
+    def test_neginf_scalar(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array(-1.)/0.) == 1)
+
+    def test_ind(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            assert_all(np.isinf(np.array((0.,))/0.) == 0)
+
+
+class TestIsposinf(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = isposinf(np.array((-1., 0, 1))/0.)
+        assert_(vals[0] == 0)
+        assert_(vals[1] == 0)
+        assert_(vals[2] == 1)
+
+
+class TestIsneginf(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = isneginf(np.array((-1., 0, 1))/0.)
+        assert_(vals[0] == 1)
+        assert_(vals[1] == 0)
+        assert_(vals[2] == 0)
+
+
+class TestNanToNum(TestCase):
+
+    def test_generic(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            vals = nan_to_num(np.array((-1., 0, 1))/0.)
+        assert_all(vals[0] < -1e10) and assert_all(np.isfinite(vals[0]))
+        assert_(vals[1] == 0)
+        assert_all(vals[2] > 1e10) and assert_all(np.isfinite(vals[2]))
+
+    def test_integer(self):
+        vals = nan_to_num(1)
+        assert_all(vals == 1)
+        vals = nan_to_num([1])
+        assert_array_equal(vals, np.array([1], np.int))
+
+    def test_complex_good(self):
+        vals = nan_to_num(1+1j)
+        assert_all(vals == 1+1j)
+
+    def test_complex_bad(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            v = 1 + 1j
+            v += np.array(0+1.j)/0.
+        vals = nan_to_num(v)
+        # !! This is actually (unexpectedly) zero
+        assert_all(np.isfinite(vals))
+
+    def test_complex_bad2(self):
+        with np.errstate(divide='ignore', invalid='ignore'):
+            v = 1 + 1j
+            v += np.array(-1+1.j)/0.
+        vals = nan_to_num(v)
+        assert_all(np.isfinite(vals))
+        # Fixme
+        #assert_all(vals.imag > 1e10)  and assert_all(np.isfinite(vals))
+        # !! This is actually (unexpectedly) positive
+        # !! inf.  Comment out for now, and see if it
+        # !! changes
+        #assert_all(vals.real < -1e10) and assert_all(np.isfinite(vals))
+
+
+class TestRealIfClose(TestCase):
+
+    def test_basic(self):
+        a = np.random.rand(10)
+        b = real_if_close(a+1e-15j)
+        assert_all(isrealobj(b))
+        assert_array_equal(a, b)
+        b = real_if_close(a+1e-7j)
+        assert_all(iscomplexobj(b))
+        b = real_if_close(a+1e-7j, tol=1e-6)
+        assert_all(isrealobj(b))
+
+
+class TestArrayConversion(TestCase):
+
+    def test_asfarray(self):
+        a = asfarray(np.array([1, 2, 3]))
+        assert_equal(a.__class__, np.ndarray)
+        assert_(np.issubdtype(a.dtype, np.float))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
new file mode 100644
index 0000000000..97d608ecfa
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
@@ -0,0 +1,65 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.core as nx
+import numpy.lib.ufunclike as ufl
+from numpy.testing import (
+    run_module_suite, TestCase, assert_, assert_equal, assert_array_equal
+    )
+
+
+class TestUfunclike(TestCase):
+
+    def test_isposinf(self):
+        a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0])
+        out = nx.zeros(a.shape, bool)
+        tgt = nx.array([True, False, False, False, False, False])
+
+        res = ufl.isposinf(a)
+        assert_equal(res, tgt)
+        res = ufl.isposinf(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+
+    def test_isneginf(self):
+        a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0])
+        out = nx.zeros(a.shape, bool)
+        tgt = nx.array([False, True, False, False, False, False])
+
+        res = ufl.isneginf(a)
+        assert_equal(res, tgt)
+        res = ufl.isneginf(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+
+    def test_fix(self):
+        a = nx.array([[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]])
+        out = nx.zeros(a.shape, float)
+        tgt = nx.array([[1., 1., 1., 1.], [-1., -1., -1., -1.]])
+
+        res = ufl.fix(a)
+        assert_equal(res, tgt)
+        res = ufl.fix(a, out)
+        assert_equal(res, tgt)
+        assert_equal(out, tgt)
+        assert_equal(ufl.fix(3.14), 3)
+
+    def test_fix_with_subclass(self):
+        class MyArray(nx.ndarray):
+            def __new__(cls, data, metadata=None):
+                res = nx.array(data, copy=True).view(cls)
+                res.metadata = metadata
+                return res
+
+            def __array_wrap__(self, obj, context=None):
+                obj.metadata = self.metadata
+                return obj
+
+        a = nx.array([1.1, -1.1])
+        m = MyArray(a, metadata='foo')
+        f = ufl.fix(m)
+        assert_array_equal(f, nx.array([1, -1]))
+        assert_(isinstance(f, MyArray))
+        assert_equal(f.metadata, 'foo')
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
new file mode 100644
index 0000000000..8fbd1c4457
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
@@ -0,0 +1,66 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.core import arange
+from numpy.testing import (
+    run_module_suite, assert_, assert_equal, dec
+    )
+from numpy.lib import deprecate
+import numpy.lib.utils as utils
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+
+@dec.skipif(sys.flags.optimize == 2)
+def test_lookfor():
+    out = StringIO()
+    utils.lookfor('eigenvalue', module='numpy', output=out,
+                  import_modules=False)
+    out = out.getvalue()
+    assert_('numpy.linalg.eig' in out)
+
+
+@deprecate
+def old_func(self, x):
+    return x
+
+
+@deprecate(message="Rather use new_func2")
+def old_func2(self, x):
+    return x
+
+
+def old_func3(self, x):
+    return x
+new_func3 = deprecate(old_func3, old_name="old_func3", new_name="new_func3")
+
+
+def test_deprecate_decorator():
+    assert_('deprecated' in old_func.__doc__)
+
+
+def test_deprecate_decorator_message():
+    assert_('Rather use new_func2' in old_func2.__doc__)
+
+
+def test_deprecate_fn():
+    assert_('old_func3' in new_func3.__doc__)
+    assert_('new_func3' in new_func3.__doc__)
+
+
+def test_safe_eval_nameconstant():
+    # Test if safe_eval supports Python 3.4 _ast.NameConstant
+    utils.safe_eval('None')
+
+
+def test_byte_bounds():
+    a = arange(12).reshape(3, 4)
+    low, high = utils.byte_bounds(a)
+    assert_equal(high - low, a.size * a.itemsize)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.py
new file mode 100644
index 0000000000..b2f350bb74
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.py
@@ -0,0 +1,1007 @@
+""" Basic functions for manipulating 2d arrays
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.core.numeric import (
+    asanyarray, arange, zeros, greater_equal, multiply, ones, asarray,
+    where, int8, int16, int32, int64, empty, promote_types, diagonal,
+    )
+from numpy.core import iinfo
+
+
+__all__ = [
+    'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'rot90', 'tri', 'triu',
+    'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices',
+    'tril_indices_from', 'triu_indices', 'triu_indices_from', ]
+
+
+i1 = iinfo(int8)
+i2 = iinfo(int16)
+i4 = iinfo(int32)
+
+
+def _min_int(low, high):
+    """ get small int that fits the range """
+    if high <= i1.max and low >= i1.min:
+        return int8
+    if high <= i2.max and low >= i2.min:
+        return int16
+    if high <= i4.max and low >= i4.min:
+        return int32
+    return int64
+
+
+def fliplr(m):
+    """
+    Flip array in the left/right direction.
+
+    Flip the entries in each row in the left/right direction.
+    Columns are preserved, but appear in a different order than before.
+
+    Parameters
+    ----------
+    m : array_like
+        Input array, must be at least 2-D.
+
+    Returns
+    -------
+    f : ndarray
+        A view of `m` with the columns reversed.  Since a view
+        is returned, this operation is :math:`\\mathcal O(1)`.
+
+    See Also
+    --------
+    flipud : Flip array in the up/down direction.
+    rot90 : Rotate array counterclockwise.
+
+    Notes
+    -----
+    Equivalent to A[:,::-1]. Requires the array to be at least 2-D.
+
+    Examples
+    --------
+    >>> A = np.diag([1.,2.,3.])
+    >>> A
+    array([[ 1.,  0.,  0.],
+           [ 0.,  2.,  0.],
+           [ 0.,  0.,  3.]])
+    >>> np.fliplr(A)
+    array([[ 0.,  0.,  1.],
+           [ 0.,  2.,  0.],
+           [ 3.,  0.,  0.]])
+
+    >>> A = np.random.randn(2,3,5)
+    >>> np.all(np.fliplr(A)==A[:,::-1,...])
+    True
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 2:
+        raise ValueError("Input must be >= 2-d.")
+    return m[:, ::-1]
+
+
+def flipud(m):
+    """
+    Flip array in the up/down direction.
+
+    Flip the entries in each column in the up/down direction.
+    Rows are preserved, but appear in a different order than before.
+
+    Parameters
+    ----------
+    m : array_like
+        Input array.
+
+    Returns
+    -------
+    out : array_like
+        A view of `m` with the rows reversed.  Since a view is
+        returned, this operation is :math:`\\mathcal O(1)`.
+
+    See Also
+    --------
+    fliplr : Flip array in the left/right direction.
+    rot90 : Rotate array counterclockwise.
+
+    Notes
+    -----
+    Equivalent to ``A[::-1,...]``.
+    Does not require the array to be two-dimensional.
+
+    Examples
+    --------
+    >>> A = np.diag([1.0, 2, 3])
+    >>> A
+    array([[ 1.,  0.,  0.],
+           [ 0.,  2.,  0.],
+           [ 0.,  0.,  3.]])
+    >>> np.flipud(A)
+    array([[ 0.,  0.,  3.],
+           [ 0.,  2.,  0.],
+           [ 1.,  0.,  0.]])
+
+    >>> A = np.random.randn(2,3,5)
+    >>> np.all(np.flipud(A)==A[::-1,...])
+    True
+
+    >>> np.flipud([1,2])
+    array([2, 1])
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 1:
+        raise ValueError("Input must be >= 1-d.")
+    return m[::-1, ...]
+
+
+def rot90(m, k=1):
+    """
+    Rotate an array by 90 degrees in the counter-clockwise direction.
+
+    The first two dimensions are rotated; therefore, the array must be at
+    least 2-D.
+
+    Parameters
+    ----------
+    m : array_like
+        Array of two or more dimensions.
+    k : integer
+        Number of times the array is rotated by 90 degrees.
+
+    Returns
+    -------
+    y : ndarray
+        Rotated array.
+
+    See Also
+    --------
+    fliplr : Flip an array horizontally.
+    flipud : Flip an array vertically.
+
+    Examples
+    --------
+    >>> m = np.array([[1,2],[3,4]], int)
+    >>> m
+    array([[1, 2],
+           [3, 4]])
+    >>> np.rot90(m)
+    array([[2, 4],
+           [1, 3]])
+    >>> np.rot90(m, 2)
+    array([[4, 3],
+           [2, 1]])
+
+    """
+    m = asanyarray(m)
+    if m.ndim < 2:
+        raise ValueError("Input must >= 2-d.")
+    k = k % 4
+    if k == 0:
+        return m
+    elif k == 1:
+        return fliplr(m).swapaxes(0, 1)
+    elif k == 2:
+        return fliplr(flipud(m))
+    else:
+        # k == 3
+        return fliplr(m.swapaxes(0, 1))
+
+
+def eye(N, M=None, k=0, dtype=float):
+    """
+    Return a 2-D array with ones on the diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    N : int
+      Number of rows in the output.
+    M : int, optional
+      Number of columns in the output. If None, defaults to `N`.
+    k : int, optional
+      Index of the diagonal: 0 (the default) refers to the main diagonal,
+      a positive value refers to an upper diagonal, and a negative value
+      to a lower diagonal.
+    dtype : data-type, optional
+      Data-type of the returned array.
+
+    Returns
+    -------
+    I : ndarray of shape (N,M)
+      An array where all elements are equal to zero, except for the `k`-th
+      diagonal, whose values are equal to one.
+
+    See Also
+    --------
+    identity : (almost) equivalent function
+    diag : diagonal 2-D array from a 1-D array specified by the user.
+
+    Examples
+    --------
+    >>> np.eye(2, dtype=int)
+    array([[1, 0],
+           [0, 1]])
+    >>> np.eye(3, k=1)
+    array([[ 0.,  1.,  0.],
+           [ 0.,  0.,  1.],
+           [ 0.,  0.,  0.]])
+
+    """
+    if M is None:
+        M = N
+    m = zeros((N, M), dtype=dtype)
+    if k >= M:
+        return m
+    if k >= 0:
+        i = k
+    else:
+        i = (-k) * M
+    m[:M-k].flat[i::M+1] = 1
+    return m
+
+
+def diag(v, k=0):
+    """
+    Extract a diagonal or construct a diagonal array.
+
+    See the more detailed documentation for ``numpy.diagonal`` if you use this
+    function to extract a diagonal and wish to write to the resulting array;
+    whether it returns a copy or a view depends on what version of numpy you
+    are using.
+
+    Parameters
+    ----------
+    v : array_like
+        If `v` is a 2-D array, return a copy of its `k`-th diagonal.
+        If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
+        diagonal.
+    k : int, optional
+        Diagonal in question. The default is 0. Use `k>0` for diagonals
+        above the main diagonal, and `k<0` for diagonals below the main
+        diagonal.
+
+    Returns
+    -------
+    out : ndarray
+        The extracted diagonal or constructed diagonal array.
+
+    See Also
+    --------
+    diagonal : Return specified diagonals.
+    diagflat : Create a 2-D array with the flattened input as a diagonal.
+    trace : Sum along diagonals.
+    triu : Upper triangle of an array.
+    tril : Lower triangle of an array.
+
+    Examples
+    --------
+    >>> x = np.arange(9).reshape((3,3))
+    >>> x
+    array([[0, 1, 2],
+           [3, 4, 5],
+           [6, 7, 8]])
+
+    >>> np.diag(x)
+    array([0, 4, 8])
+    >>> np.diag(x, k=1)
+    array([1, 5])
+    >>> np.diag(x, k=-1)
+    array([3, 7])
+
+    >>> np.diag(np.diag(x))
+    array([[0, 0, 0],
+           [0, 4, 0],
+           [0, 0, 8]])
+
+    """
+    v = asanyarray(v)
+    s = v.shape
+    if len(s) == 1:
+        n = s[0]+abs(k)
+        res = zeros((n, n), v.dtype)
+        if k >= 0:
+            i = k
+        else:
+            i = (-k) * n
+        res[:n-k].flat[i::n+1] = v
+        return res
+    elif len(s) == 2:
+        return diagonal(v, k)
+    else:
+        raise ValueError("Input must be 1- or 2-d.")
+
+
+def diagflat(v, k=0):
+    """
+    Create a two-dimensional array with the flattened input as a diagonal.
+
+    Parameters
+    ----------
+    v : array_like
+        Input data, which is flattened and set as the `k`-th
+        diagonal of the output.
+    k : int, optional
+        Diagonal to set; 0, the default, corresponds to the "main" diagonal,
+        a positive (negative) `k` giving the number of the diagonal above
+        (below) the main.
+
+    Returns
+    -------
+    out : ndarray
+        The 2-D output array.
+
+    See Also
+    --------
+    diag : MATLAB work-alike for 1-D and 2-D arrays.
+    diagonal : Return specified diagonals.
+    trace : Sum along diagonals.
+
+    Examples
+    --------
+    >>> np.diagflat([[1,2], [3,4]])
+    array([[1, 0, 0, 0],
+           [0, 2, 0, 0],
+           [0, 0, 3, 0],
+           [0, 0, 0, 4]])
+
+    >>> np.diagflat([1,2], 1)
+    array([[0, 1, 0],
+           [0, 0, 2],
+           [0, 0, 0]])
+
+    """
+    try:
+        wrap = v.__array_wrap__
+    except AttributeError:
+        wrap = None
+    v = asarray(v).ravel()
+    s = len(v)
+    n = s + abs(k)
+    res = zeros((n, n), v.dtype)
+    if (k >= 0):
+        i = arange(0, n-k)
+        fi = i+k+i*n
+    else:
+        i = arange(0, n+k)
+        fi = i+(i-k)*n
+    res.flat[fi] = v
+    if not wrap:
+        return res
+    return wrap(res)
+
+
+def tri(N, M=None, k=0, dtype=float):
+    """
+    An array with ones at and below the given diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    N : int
+        Number of rows in the array.
+    M : int, optional
+        Number of columns in the array.
+        By default, `M` is taken equal to `N`.
+    k : int, optional
+        The sub-diagonal at and below which the array is filled.
+        `k` = 0 is the main diagonal, while `k` < 0 is below it,
+        and `k` > 0 is above.  The default is 0.
+    dtype : dtype, optional
+        Data type of the returned array.  The default is float.
+
+    Returns
+    -------
+    tri : ndarray of shape (N, M)
+        Array with its lower triangle filled with ones and zero elsewhere;
+        in other words ``T[i,j] == 1`` for ``i <= j + k``, 0 otherwise.
+
+    Examples
+    --------
+    >>> np.tri(3, 5, 2, dtype=int)
+    array([[1, 1, 1, 0, 0],
+           [1, 1, 1, 1, 0],
+           [1, 1, 1, 1, 1]])
+
+    >>> np.tri(3, 5, -1)
+    array([[ 0.,  0.,  0.,  0.,  0.],
+           [ 1.,  0.,  0.,  0.,  0.],
+           [ 1.,  1.,  0.,  0.,  0.]])
+
+    """
+    if M is None:
+        M = N
+
+    m = greater_equal.outer(arange(N, dtype=_min_int(0, N)),
+                            arange(-k, M-k, dtype=_min_int(-k, M - k)))
+
+    # Avoid making a copy if the requested type is already bool
+    m = m.astype(dtype, copy=False)
+
+    return m
+
+
+def tril(m, k=0):
+    """
+    Lower triangle of an array.
+
+    Return a copy of an array with elements above the `k`-th diagonal zeroed.
+
+    Parameters
+    ----------
+    m : array_like, shape (M, N)
+        Input array.
+    k : int, optional
+        Diagonal above which to zero elements.  `k = 0` (the default) is the
+        main diagonal, `k < 0` is below it and `k > 0` is above.
+
+    Returns
+    -------
+    tril : ndarray, shape (M, N)
+        Lower triangle of `m`, of same shape and data-type as `m`.
+
+    See Also
+    --------
+    triu : same thing, only for the upper triangle
+
+    Examples
+    --------
+    >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
+    array([[ 0,  0,  0],
+           [ 4,  0,  0],
+           [ 7,  8,  0],
+           [10, 11, 12]])
+
+    """
+    m = asanyarray(m)
+    mask = tri(*m.shape[-2:], k=k, dtype=bool)
+
+    return where(mask, m, zeros(1, m.dtype))
+
+
+def triu(m, k=0):
+    """
+    Upper triangle of an array.
+
+    Return a copy of a matrix with the elements below the `k`-th diagonal
+    zeroed.
+
+    Please refer to the documentation for `tril` for further details.
+
+    See Also
+    --------
+    tril : lower triangle of an array
+
+    Examples
+    --------
+    >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
+    array([[ 1,  2,  3],
+           [ 4,  5,  6],
+           [ 0,  8,  9],
+           [ 0,  0, 12]])
+
+    """
+    m = asanyarray(m)
+    mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
+
+    return where(mask, zeros(1, m.dtype), m)
+
+
+# Originally borrowed from John Hunter and matplotlib
+def vander(x, N=None, increasing=False):
+    """
+    Generate a Vandermonde matrix.
+
+    The columns of the output matrix are powers of the input vector. The
+    order of the powers is determined by the `increasing` boolean argument.
+    Specifically, when `increasing` is False, the `i`-th output column is
+    the input vector raised element-wise to the power of ``N - i - 1``. Such
+    a matrix with a geometric progression in each row is named for Alexandre-
+    Theophile Vandermonde.
+
+    Parameters
+    ----------
+    x : array_like
+        1-D input array.
+    N : int, optional
+        Number of columns in the output.  If `N` is not specified, a square
+        array is returned (``N = len(x)``).
+    increasing : bool, optional
+        Order of the powers of the columns.  If True, the powers increase
+        from left to right, if False (the default) they are reversed.
+
+        .. versionadded:: 1.9.0
+
+    Returns
+    -------
+    out : ndarray
+        Vandermonde matrix.  If `increasing` is False, the first column is
+        ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is
+        True, the columns are ``x^0, x^1, ..., x^(N-1)``.
+
+    See Also
+    --------
+    polynomial.polynomial.polyvander
+
+    Examples
+    --------
+    >>> x = np.array([1, 2, 3, 5])
+    >>> N = 3
+    >>> np.vander(x, N)
+    array([[ 1,  1,  1],
+           [ 4,  2,  1],
+           [ 9,  3,  1],
+           [25,  5,  1]])
+
+    >>> np.column_stack([x**(N-1-i) for i in range(N)])
+    array([[ 1,  1,  1],
+           [ 4,  2,  1],
+           [ 9,  3,  1],
+           [25,  5,  1]])
+
+    >>> x = np.array([1, 2, 3, 5])
+    >>> np.vander(x)
+    array([[  1,   1,   1,   1],
+           [  8,   4,   2,   1],
+           [ 27,   9,   3,   1],
+           [125,  25,   5,   1]])
+    >>> np.vander(x, increasing=True)
+    array([[  1,   1,   1,   1],
+           [  1,   2,   4,   8],
+           [  1,   3,   9,  27],
+           [  1,   5,  25, 125]])
+
+    The determinant of a square Vandermonde matrix is the product
+    of the differences between the values of the input vector:
+
+    >>> np.linalg.det(np.vander(x))
+    48.000000000000043
+    >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1)
+    48
+
+    """
+    x = asarray(x)
+    if x.ndim != 1:
+        raise ValueError("x must be a one-dimensional array or sequence.")
+    if N is None:
+        N = len(x)
+
+    v = empty((len(x), N), dtype=promote_types(x.dtype, int))
+    tmp = v[:, ::-1] if not increasing else v
+
+    if N > 0:
+        tmp[:, 0] = 1
+    if N > 1:
+        tmp[:, 1:] = x[:, None]
+        multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1)
+
+    return v
+
+
+def histogram2d(x, y, bins=10, range=None, normed=False, weights=None):
+    """
+    Compute the bi-dimensional histogram of two data samples.
+
+    Parameters
+    ----------
+    x : array_like, shape (N,)
+        An array containing the x coordinates of the points to be
+        histogrammed.
+    y : array_like, shape (N,)
+        An array containing the y coordinates of the points to be
+        histogrammed.
+    bins : int or array_like or [int, int] or [array, array], optional
+        The bin specification:
+
+          * If int, the number of bins for the two dimensions (nx=ny=bins).
+          * If array_like, the bin edges for the two dimensions
+            (x_edges=y_edges=bins).
+          * If [int, int], the number of bins in each dimension
+            (nx, ny = bins).
+          * If [array, array], the bin edges in each dimension
+            (x_edges, y_edges = bins).
+          * A combination [int, array] or [array, int], where int
+            is the number of bins and array is the bin edges.
+
+    range : array_like, shape(2,2), optional
+        The leftmost and rightmost edges of the bins along each dimension
+        (if not specified explicitly in the `bins` parameters):
+        ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
+        will be considered outliers and not tallied in the histogram.
+    normed : bool, optional
+        If False, returns the number of samples in each bin. If True,
+        returns the bin density ``bin_count / sample_count / bin_area``.
+    weights : array_like, shape(N,), optional
+        An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
+        Weights are normalized to 1 if `normed` is True. If `normed` is
+        False, the values of the returned histogram are equal to the sum of
+        the weights belonging to the samples falling into each bin.
+
+    Returns
+    -------
+    H : ndarray, shape(nx, ny)
+        The bi-dimensional histogram of samples `x` and `y`. Values in `x`
+        are histogrammed along the first dimension and values in `y` are
+        histogrammed along the second dimension.
+    xedges : ndarray, shape(nx,)
+        The bin edges along the first dimension.
+    yedges : ndarray, shape(ny,)
+        The bin edges along the second dimension.
+
+    See Also
+    --------
+    histogram : 1D histogram
+    histogramdd : Multidimensional histogram
+
+    Notes
+    -----
+    When `normed` is True, then the returned histogram is the sample
+    density, defined such that the sum over bins of the product
+    ``bin_value * bin_area`` is 1.
+
+    Please note that the histogram does not follow the Cartesian convention
+    where `x` values are on the abscissa and `y` values on the ordinate
+    axis.  Rather, `x` is histogrammed along the first dimension of the
+    array (vertical), and `y` along the second dimension of the array
+    (horizontal).  This ensures compatibility with `histogramdd`.
+
+    Examples
+    --------
+    >>> import matplotlib as mpl
+    >>> import matplotlib.pyplot as plt
+
+    Construct a 2D-histogram with variable bin width. First define the bin
+    edges:
+
+    >>> xedges = [0, 1, 1.5, 3, 5]
+    >>> yedges = [0, 2, 3, 4, 6]
+
+    Next we create a histogram H with random bin content:
+
+    >>> x = np.random.normal(3, 1, 100)
+    >>> y = np.random.normal(1, 1, 100)
+    >>> H, xedges, yedges = np.histogram2d(y, x, bins=(xedges, yedges))
+
+    Or we fill the histogram H with a determined bin content:
+
+    >>> H = np.ones((4, 4)).cumsum().reshape(4, 4)
+    >>> print(H[::-1])  # This shows the bin content in the order as plotted
+    [[ 13.  14.  15.  16.]
+     [  9.  10.  11.  12.]
+     [  5.   6.   7.   8.]
+     [  1.   2.   3.   4.]]
+
+    Imshow can only do an equidistant representation of bins:
+
+    >>> fig = plt.figure(figsize=(7, 3))
+    >>> ax = fig.add_subplot(131)
+    >>> ax.set_title('imshow: equidistant')
+    >>> im = plt.imshow(H, interpolation='nearest', origin='low',
+                    extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
+
+    pcolormesh can display exact bin edges:
+
+    >>> ax = fig.add_subplot(132)
+    >>> ax.set_title('pcolormesh: exact bin edges')
+    >>> X, Y = np.meshgrid(xedges, yedges)
+    >>> ax.pcolormesh(X, Y, H)
+    >>> ax.set_aspect('equal')
+
+    NonUniformImage displays exact bin edges with interpolation:
+
+    >>> ax = fig.add_subplot(133)
+    >>> ax.set_title('NonUniformImage: interpolated')
+    >>> im = mpl.image.NonUniformImage(ax, interpolation='bilinear')
+    >>> xcenters = xedges[:-1] + 0.5 * (xedges[1:] - xedges[:-1])
+    >>> ycenters = yedges[:-1] + 0.5 * (yedges[1:] - yedges[:-1])
+    >>> im.set_data(xcenters, ycenters, H)
+    >>> ax.images.append(im)
+    >>> ax.set_xlim(xedges[0], xedges[-1])
+    >>> ax.set_ylim(yedges[0], yedges[-1])
+    >>> ax.set_aspect('equal')
+    >>> plt.show()
+
+    """
+    from numpy import histogramdd
+
+    try:
+        N = len(bins)
+    except TypeError:
+        N = 1
+
+    if N != 1 and N != 2:
+        xedges = yedges = asarray(bins, float)
+        bins = [xedges, yedges]
+    hist, edges = histogramdd([x, y], bins, range, normed, weights)
+    return hist, edges[0], edges[1]
+
+
+def mask_indices(n, mask_func, k=0):
+    """
+    Return the indices to access (n, n) arrays, given a masking function.
+
+    Assume `mask_func` is a function that, for a square array a of size
+    ``(n, n)`` with a possible offset argument `k`, when called as
+    ``mask_func(a, k)`` returns a new array with zeros in certain locations
+    (functions like `triu` or `tril` do precisely this). Then this function
+    returns the indices where the non-zero values would be located.
+
+    Parameters
+    ----------
+    n : int
+        The returned indices will be valid to access arrays of shape (n, n).
+    mask_func : callable
+        A function whose call signature is similar to that of `triu`, `tril`.
+        That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`.
+        `k` is an optional argument to the function.
+    k : scalar
+        An optional argument which is passed through to `mask_func`. Functions
+        like `triu`, `tril` take a second argument that is interpreted as an
+        offset.
+
+    Returns
+    -------
+    indices : tuple of arrays.
+        The `n` arrays of indices corresponding to the locations where
+        ``mask_func(np.ones((n, n)), k)`` is True.
+
+    See Also
+    --------
+    triu, tril, triu_indices, tril_indices
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    These are the indices that would allow you to access the upper triangular
+    part of any 3x3 array:
+
+    >>> iu = np.mask_indices(3, np.triu)
+
+    For example, if `a` is a 3x3 array:
+
+    >>> a = np.arange(9).reshape(3, 3)
+    >>> a
+    array([[0, 1, 2],
+           [3, 4, 5],
+           [6, 7, 8]])
+    >>> a[iu]
+    array([0, 1, 2, 4, 5, 8])
+
+    An offset can be passed also to the masking function.  This gets us the
+    indices starting on the first diagonal right of the main one:
+
+    >>> iu1 = np.mask_indices(3, np.triu, 1)
+
+    with which we now extract only three elements:
+
+    >>> a[iu1]
+    array([1, 2, 5])
+
+    """
+    m = ones((n, n), int)
+    a = mask_func(m, k)
+    return where(a != 0)
+
+
+def tril_indices(n, k=0, m=None):
+    """
+    Return the indices for the lower-triangle of an (n, m) array.
+
+    Parameters
+    ----------
+    n : int
+        The row dimension of the arrays for which the returned
+        indices will be valid.
+    k : int, optional
+        Diagonal offset (see `tril` for details).
+    m : int, optional
+        .. versionadded:: 1.9.0
+
+        The column dimension of the arrays for which the returned
+        arrays will be valid.
+        By default `m` is taken equal to `n`.
+
+
+    Returns
+    -------
+    inds : tuple of arrays
+        The indices for the triangle. The returned tuple contains two arrays,
+        each with the indices along one dimension of the array.
+
+    See also
+    --------
+    triu_indices : similar function, for upper-triangular.
+    mask_indices : generic function accepting an arbitrary mask function.
+    tril, triu
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Compute two different sets of indices to access 4x4 arrays, one for the
+    lower triangular part starting at the main diagonal, and one starting two
+    diagonals further right:
+
+    >>> il1 = np.tril_indices(4)
+    >>> il2 = np.tril_indices(4, 2)
+
+    Here is how they can be used with a sample array:
+
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+
+    Both for indexing:
+
+    >>> a[il1]
+    array([ 0,  4,  5,  8,  9, 10, 12, 13, 14, 15])
+
+    And for assigning values:
+
+    >>> a[il1] = -1
+    >>> a
+    array([[-1,  1,  2,  3],
+           [-1, -1,  6,  7],
+           [-1, -1, -1, 11],
+           [-1, -1, -1, -1]])
+
+    These cover almost the whole array (two diagonals right of the main one):
+
+    >>> a[il2] = -10
+    >>> a
+    array([[-10, -10, -10,   3],
+           [-10, -10, -10, -10],
+           [-10, -10, -10, -10],
+           [-10, -10, -10, -10]])
+
+    """
+    return where(tri(n, m, k=k, dtype=bool))
+
+
+def tril_indices_from(arr, k=0):
+    """
+    Return the indices for the lower-triangle of arr.
+
+    See `tril_indices` for full details.
+
+    Parameters
+    ----------
+    arr : array_like
+        The indices will be valid for square arrays whose dimensions are
+        the same as arr.
+    k : int, optional
+        Diagonal offset (see `tril` for details).
+
+    See Also
+    --------
+    tril_indices, tril
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if arr.ndim != 2:
+        raise ValueError("input array must be 2-d")
+    return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1])
+
+
+def triu_indices(n, k=0, m=None):
+    """
+    Return the indices for the upper-triangle of an (n, m) array.
+
+    Parameters
+    ----------
+    n : int
+        The size of the arrays for which the returned indices will
+        be valid.
+    k : int, optional
+        Diagonal offset (see `triu` for details).
+    m : int, optional
+        .. versionadded:: 1.9.0
+
+        The column dimension of the arrays for which the returned
+        arrays will be valid.
+        By default `m` is taken equal to `n`.
+
+
+    Returns
+    -------
+    inds : tuple, shape(2) of ndarrays, shape(`n`)
+        The indices for the triangle. The returned tuple contains two arrays,
+        each with the indices along one dimension of the array.  Can be used
+        to slice a ndarray of shape(`n`, `n`).
+
+    See also
+    --------
+    tril_indices : similar function, for lower-triangular.
+    mask_indices : generic function accepting an arbitrary mask function.
+    triu, tril
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    Examples
+    --------
+    Compute two different sets of indices to access 4x4 arrays, one for the
+    upper triangular part starting at the main diagonal, and one starting two
+    diagonals further right:
+
+    >>> iu1 = np.triu_indices(4)
+    >>> iu2 = np.triu_indices(4, 2)
+
+    Here is how they can be used with a sample array:
+
+    >>> a = np.arange(16).reshape(4, 4)
+    >>> a
+    array([[ 0,  1,  2,  3],
+           [ 4,  5,  6,  7],
+           [ 8,  9, 10, 11],
+           [12, 13, 14, 15]])
+
+    Both for indexing:
+
+    >>> a[iu1]
+    array([ 0,  1,  2,  3,  5,  6,  7, 10, 11, 15])
+
+    And for assigning values:
+
+    >>> a[iu1] = -1
+    >>> a
+    array([[-1, -1, -1, -1],
+           [ 4, -1, -1, -1],
+           [ 8,  9, -1, -1],
+           [12, 13, 14, -1]])
+
+    These cover only a small part of the whole array (two diagonals right
+    of the main one):
+
+    >>> a[iu2] = -10
+    >>> a
+    array([[ -1,  -1, -10, -10],
+           [  4,  -1,  -1, -10],
+           [  8,   9,  -1,  -1],
+           [ 12,  13,  14,  -1]])
+
+    """
+    return where(~tri(n, m, k=k-1, dtype=bool))
+
+
+def triu_indices_from(arr, k=0):
+    """
+    Return the indices for the upper-triangle of arr.
+
+    See `triu_indices` for full details.
+
+    Parameters
+    ----------
+    arr : ndarray, shape(N, N)
+        The indices will be valid for square arrays.
+    k : int, optional
+        Diagonal offset (see `triu` for details).
+
+    Returns
+    -------
+    triu_indices_from : tuple, shape(2) of ndarray, shape(N)
+        Indices for the upper-triangle of `arr`.
+
+    See Also
+    --------
+    triu_indices, triu
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if arr.ndim != 2:
+        raise ValueError("input array must be 2-d")
+    return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/type_check.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/type_check.py
new file mode 100644
index 0000000000..1313adff71
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/type_check.py
@@ -0,0 +1,596 @@
+"""Automatically adapted for numpy Sep 19, 2005 by convertcode.py
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['iscomplexobj', 'isrealobj', 'imag', 'iscomplex',
+           'isreal', 'nan_to_num', 'real', 'real_if_close',
+           'typename', 'asfarray', 'mintypecode', 'asscalar',
+           'common_type']
+
+import numpy.core.numeric as _nx
+from numpy.core.numeric import asarray, asanyarray, array, isnan, \
+                obj2sctype, zeros
+from .ufunclike import isneginf, isposinf
+
+_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb?'
+
+def mintypecode(typechars,typeset='GDFgdf',default='d'):
+    """
+    Return the character for the minimum-size type to which given types can
+    be safely cast.
+
+    The returned type character must represent the smallest size dtype such
+    that an array of the returned type can handle the data from an array of
+    all types in `typechars` (or if `typechars` is an array, then its
+    dtype.char).
+
+    Parameters
+    ----------
+    typechars : list of str or array_like
+        If a list of strings, each string should represent a dtype.
+        If array_like, the character representation of the array dtype is used.
+    typeset : str or list of str, optional
+        The set of characters that the returned character is chosen from.
+        The default set is 'GDFgdf'.
+    default : str, optional
+        The default character, this is returned if none of the characters in
+        `typechars` matches a character in `typeset`.
+
+    Returns
+    -------
+    typechar : str
+        The character representing the minimum-size type that was found.
+
+    See Also
+    --------
+    dtype, sctype2char, maximum_sctype
+
+    Examples
+    --------
+    >>> np.mintypecode(['d', 'f', 'S'])
+    'd'
+    >>> x = np.array([1.1, 2-3.j])
+    >>> np.mintypecode(x)
+    'D'
+
+    >>> np.mintypecode('abceh', default='G')
+    'G'
+
+    """
+    typecodes = [(isinstance(t, str) and t) or asarray(t).dtype.char
+                 for t in typechars]
+    intersection = [t for t in typecodes if t in typeset]
+    if not intersection:
+        return default
+    if 'F' in intersection and 'd' in intersection:
+        return 'D'
+    l = []
+    for t in intersection:
+        i = _typecodes_by_elsize.index(t)
+        l.append((i, t))
+    l.sort()
+    return l[0][1]
+
+def asfarray(a, dtype=_nx.float_):
+    """
+    Return an array converted to a float type.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    dtype : str or dtype object, optional
+        Float type code to coerce input array `a`.  If `dtype` is one of the
+        'int' dtypes, it is replaced with float64.
+
+    Returns
+    -------
+    out : ndarray
+        The input `a` as a float ndarray.
+
+    Examples
+    --------
+    >>> np.asfarray([2, 3])
+    array([ 2.,  3.])
+    >>> np.asfarray([2, 3], dtype='float')
+    array([ 2.,  3.])
+    >>> np.asfarray([2, 3], dtype='int8')
+    array([ 2.,  3.])
+
+    """
+    dtype = _nx.obj2sctype(dtype)
+    if not issubclass(dtype, _nx.inexact):
+        dtype = _nx.float_
+    return asarray(a, dtype=dtype)
+
+def real(val):
+    """
+    Return the real part of the elements of the array.
+
+    Parameters
+    ----------
+    val : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array. If `val` is real, the type of `val` is used for the
+        output.  If `val` has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real_if_close, imag, angle
+
+    Examples
+    --------
+    >>> a = np.array([1+2j, 3+4j, 5+6j])
+    >>> a.real
+    array([ 1.,  3.,  5.])
+    >>> a.real = 9
+    >>> a
+    array([ 9.+2.j,  9.+4.j,  9.+6.j])
+    >>> a.real = np.array([9, 8, 7])
+    >>> a
+    array([ 9.+2.j,  8.+4.j,  7.+6.j])
+
+    """
+    return asanyarray(val).real
+
+def imag(val):
+    """
+    Return the imaginary part of the elements of the array.
+
+    Parameters
+    ----------
+    val : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray
+        Output array. If `val` is real, the type of `val` is used for the
+        output.  If `val` has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real, angle, real_if_close
+
+    Examples
+    --------
+    >>> a = np.array([1+2j, 3+4j, 5+6j])
+    >>> a.imag
+    array([ 2.,  4.,  6.])
+    >>> a.imag = np.array([8, 10, 12])
+    >>> a
+    array([ 1. +8.j,  3.+10.j,  5.+12.j])
+
+    """
+    return asanyarray(val).imag
+
+def iscomplex(x):
+    """
+    Returns a bool array, where True if input element is complex.
+
+    What is tested is whether the input has a non-zero imaginary part, not if
+    the input type is complex.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray of bools
+        Output array.
+
+    See Also
+    --------
+    isreal
+    iscomplexobj : Return True if x is a complex type or an array of complex
+                   numbers.
+
+    Examples
+    --------
+    >>> np.iscomplex([1+1j, 1+0j, 4.5, 3, 2, 2j])
+    array([ True, False, False, False, False,  True], dtype=bool)
+
+    """
+    ax = asanyarray(x)
+    if issubclass(ax.dtype.type, _nx.complexfloating):
+        return ax.imag != 0
+    res = zeros(ax.shape, bool)
+    return +res  # convet to array-scalar if needed
+
+def isreal(x):
+    """
+    Returns a bool array, where True if input element is real.
+
+    If element has complex type with zero complex part, the return value
+    for that element is True.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.
+
+    Returns
+    -------
+    out : ndarray, bool
+        Boolean array of same shape as `x`.
+
+    See Also
+    --------
+    iscomplex
+    isrealobj : Return True if x is not a complex type.
+
+    Examples
+    --------
+    >>> np.isreal([1+1j, 1+0j, 4.5, 3, 2, 2j])
+    array([False,  True,  True,  True,  True, False], dtype=bool)
+
+    """
+    return imag(x) == 0
+
+def iscomplexobj(x):
+    """
+    Check for a complex type or an array of complex numbers.
+
+    The type of the input is checked, not the value. Even if the input
+    has an imaginary part equal to zero, `iscomplexobj` evaluates to True.
+
+    Parameters
+    ----------
+    x : any
+        The input can be of any type and shape.
+
+    Returns
+    -------
+    iscomplexobj : bool
+        The return value, True if `x` is of a complex type or has at least
+        one complex element.
+
+    See Also
+    --------
+    isrealobj, iscomplex
+
+    Examples
+    --------
+    >>> np.iscomplexobj(1)
+    False
+    >>> np.iscomplexobj(1+0j)
+    True
+    >>> np.iscomplexobj([3, 1+0j, True])
+    True
+
+    """
+    return issubclass(asarray(x).dtype.type, _nx.complexfloating)
+
+def isrealobj(x):
+    """
+    Return True if x is a not complex type or an array of complex numbers.
+
+    The type of the input is checked, not the value. So even if the input
+    has an imaginary part equal to zero, `isrealobj` evaluates to False
+    if the data type is complex.
+
+    Parameters
+    ----------
+    x : any
+        The input can be of any type and shape.
+
+    Returns
+    -------
+    y : bool
+        The return value, False if `x` is of a complex type.
+
+    See Also
+    --------
+    iscomplexobj, isreal
+
+    Examples
+    --------
+    >>> np.isrealobj(1)
+    True
+    >>> np.isrealobj(1+0j)
+    False
+    >>> np.isrealobj([3, 1+0j, True])
+    False
+
+    """
+    return not issubclass(asarray(x).dtype.type, _nx.complexfloating)
+
+#-----------------------------------------------------------------------------
+
+def _getmaxmin(t):
+    from numpy.core import getlimits
+    f = getlimits.finfo(t)
+    return f.max, f.min
+
+def nan_to_num(x):
+    """
+    Replace nan with zero and inf with finite numbers.
+
+    Returns an array or scalar replacing Not a Number (NaN) with zero,
+    (positive) infinity with a very large number and negative infinity
+    with a very small (or negative) number.
+
+    Parameters
+    ----------
+    x : array_like
+        Input data.
+
+    Returns
+    -------
+    out : ndarray
+        New Array with the same shape as `x` and dtype of the element in
+        `x`  with the greatest precision. If `x` is inexact, then NaN is
+        replaced by zero, and infinity (-infinity) is replaced by the
+        largest (smallest or most negative) floating point value that fits
+        in the output dtype. If `x` is not inexact, then a copy of `x` is
+        returned.
+
+    See Also
+    --------
+    isinf : Shows which elements are negative or negative infinity.
+    isneginf : Shows which elements are negative infinity.
+    isposinf : Shows which elements are positive infinity.
+    isnan : Shows which elements are Not a Number (NaN).
+    isfinite : Shows which elements are finite (not NaN, not infinity)
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754). This means that Not a Number is not equivalent to infinity.
+
+
+    Examples
+    --------
+    >>> np.set_printoptions(precision=8)
+    >>> x = np.array([np.inf, -np.inf, np.nan, -128, 128])
+    >>> np.nan_to_num(x)
+    array([  1.79769313e+308,  -1.79769313e+308,   0.00000000e+000,
+            -1.28000000e+002,   1.28000000e+002])
+
+    """
+    x = _nx.array(x, subok=True)
+    xtype = x.dtype.type
+    if not issubclass(xtype, _nx.inexact):
+        return x
+
+    iscomplex = issubclass(xtype, _nx.complexfloating)
+    isscalar = (x.ndim == 0)
+
+    x = x[None] if isscalar else x
+    dest = (x.real, x.imag) if iscomplex else (x,)
+    maxf, minf = _getmaxmin(x.real.dtype)
+    for d in dest:
+        _nx.copyto(d, 0.0, where=isnan(d))
+        _nx.copyto(d, maxf, where=isposinf(d))
+        _nx.copyto(d, minf, where=isneginf(d))
+    return x[0] if isscalar else x
+
+#-----------------------------------------------------------------------------
+
+def real_if_close(a,tol=100):
+    """
+    If complex input returns a real array if complex parts are close to zero.
+
+    "Close to zero" is defined as `tol` * (machine epsilon of the type for
+    `a`).
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    tol : float
+        Tolerance in machine epsilons for the complex part of the elements
+        in the array.
+
+    Returns
+    -------
+    out : ndarray
+        If `a` is real, the type of `a` is used for the output.  If `a`
+        has complex elements, the returned type is float.
+
+    See Also
+    --------
+    real, imag, angle
+
+    Notes
+    -----
+    Machine epsilon varies from machine to machine and between data types
+    but Python floats on most platforms have a machine epsilon equal to
+    2.2204460492503131e-16.  You can use 'np.finfo(np.float).eps' to print
+    out the machine epsilon for floats.
+
+    Examples
+    --------
+    >>> np.finfo(np.float).eps
+    2.2204460492503131e-16
+
+    >>> np.real_if_close([2.1 + 4e-14j], tol=1000)
+    array([ 2.1])
+    >>> np.real_if_close([2.1 + 4e-13j], tol=1000)
+    array([ 2.1 +4.00000000e-13j])
+
+    """
+    a = asanyarray(a)
+    if not issubclass(a.dtype.type, _nx.complexfloating):
+        return a
+    if tol > 1:
+        from numpy.core import getlimits
+        f = getlimits.finfo(a.dtype.type)
+        tol = f.eps * tol
+    if _nx.allclose(a.imag, 0, atol=tol):
+        a = a.real
+    return a
+
+
+def asscalar(a):
+    """
+    Convert an array of size 1 to its scalar equivalent.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array of size 1.
+
+    Returns
+    -------
+    out : scalar
+        Scalar representation of `a`. The output data type is the same type
+        returned by the input's `item` method.
+
+    Examples
+    --------
+    >>> np.asscalar(np.array([24]))
+    24
+
+    """
+    return a.item()
+
+#-----------------------------------------------------------------------------
+
+_namefromtype = {'S1': 'character',
+                 '?': 'bool',
+                 'b': 'signed char',
+                 'B': 'unsigned char',
+                 'h': 'short',
+                 'H': 'unsigned short',
+                 'i': 'integer',
+                 'I': 'unsigned integer',
+                 'l': 'long integer',
+                 'L': 'unsigned long integer',
+                 'q': 'long long integer',
+                 'Q': 'unsigned long long integer',
+                 'f': 'single precision',
+                 'd': 'double precision',
+                 'g': 'long precision',
+                 'F': 'complex single precision',
+                 'D': 'complex double precision',
+                 'G': 'complex long double precision',
+                 'S': 'string',
+                 'U': 'unicode',
+                 'V': 'void',
+                 'O': 'object'
+                 }
+
+def typename(char):
+    """
+    Return a description for the given data type code.
+
+    Parameters
+    ----------
+    char : str
+        Data type code.
+
+    Returns
+    -------
+    out : str
+        Description of the input data type code.
+
+    See Also
+    --------
+    dtype, typecodes
+
+    Examples
+    --------
+    >>> typechars = ['S1', '?', 'B', 'D', 'G', 'F', 'I', 'H', 'L', 'O', 'Q',
+    ...              'S', 'U', 'V', 'b', 'd', 'g', 'f', 'i', 'h', 'l', 'q']
+    >>> for typechar in typechars:
+    ...     print(typechar, ' : ', np.typename(typechar))
+    ...
+    S1  :  character
+    ?  :  bool
+    B  :  unsigned char
+    D  :  complex double precision
+    G  :  complex long double precision
+    F  :  complex single precision
+    I  :  unsigned integer
+    H  :  unsigned short
+    L  :  unsigned long integer
+    O  :  object
+    Q  :  unsigned long long integer
+    S  :  string
+    U  :  unicode
+    V  :  void
+    b  :  signed char
+    d  :  double precision
+    g  :  long precision
+    f  :  single precision
+    i  :  integer
+    h  :  short
+    l  :  long integer
+    q  :  long long integer
+
+    """
+    return _namefromtype[char]
+
+#-----------------------------------------------------------------------------
+
+#determine the "minimum common type" for a group of arrays.
+array_type = [[_nx.half, _nx.single, _nx.double, _nx.longdouble],
+              [None, _nx.csingle, _nx.cdouble, _nx.clongdouble]]
+array_precision = {_nx.half: 0,
+                   _nx.single: 1,
+                   _nx.double: 2,
+                   _nx.longdouble: 3,
+                   _nx.csingle: 1,
+                   _nx.cdouble: 2,
+                   _nx.clongdouble: 3}
+def common_type(*arrays):
+    """
+    Return a scalar type which is common to the input arrays.
+
+    The return type will always be an inexact (i.e. floating point) scalar
+    type, even if all the arrays are integer arrays. If one of the inputs is
+    an integer array, the minimum precision type that is returned is a
+    64-bit floating point dtype.
+
+    All input arrays can be safely cast to the returned dtype without loss
+    of information.
+
+    Parameters
+    ----------
+    array1, array2, ... : ndarrays
+        Input arrays.
+
+    Returns
+    -------
+    out : data type code
+        Data type code.
+
+    See Also
+    --------
+    dtype, mintypecode
+
+    Examples
+    --------
+    >>> np.common_type(np.arange(2, dtype=np.float32))
+    <type 'numpy.float32'>
+    >>> np.common_type(np.arange(2, dtype=np.float32), np.arange(2))
+    <type 'numpy.float64'>
+    >>> np.common_type(np.arange(4), np.array([45, 6.j]), np.array([45.0]))
+    <type 'numpy.complex128'>
+
+    """
+    is_complex = False
+    precision = 0
+    for a in arrays:
+        t = a.dtype.type
+        if iscomplexobj(a):
+            is_complex = True
+        if issubclass(t, _nx.integer):
+            p = 2  # array_precision[_nx.double]
+        else:
+            p = array_precision.get(t, None)
+            if p is None:
+                raise TypeError("can't get common type for non-numeric array")
+        precision = max(precision, p)
+    if is_complex:
+        return array_type[1][precision]
+    else:
+        return array_type[0][precision]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.py
new file mode 100644
index 0000000000..e91f64d0ef
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.py
@@ -0,0 +1,177 @@
+"""
+Module of functions that are like ufuncs in acting on arrays and optionally
+storing results in an output array.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['fix', 'isneginf', 'isposinf']
+
+import numpy.core.numeric as nx
+
+def fix(x, y=None):
+    """
+    Round to nearest integer towards zero.
+
+    Round an array of floats element-wise to nearest integer towards zero.
+    The rounded values are returned as floats.
+
+    Parameters
+    ----------
+    x : array_like
+        An array of floats to be rounded
+    y : ndarray, optional
+        Output array
+
+    Returns
+    -------
+    out : ndarray of floats
+        The array of rounded numbers
+
+    See Also
+    --------
+    trunc, floor, ceil
+    around : Round to given number of decimals
+
+    Examples
+    --------
+    >>> np.fix(3.14)
+    3.0
+    >>> np.fix(3)
+    3.0
+    >>> np.fix([2.1, 2.9, -2.1, -2.9])
+    array([ 2.,  2., -2., -2.])
+
+    """
+    x = nx.asanyarray(x)
+    y1 = nx.floor(x)
+    y2 = nx.ceil(x)
+    if y is None:
+        y = nx.asanyarray(y1)
+    y[...] = nx.where(x >= 0, y1, y2)
+    return y
+
+def isposinf(x, y=None):
+    """
+    Test element-wise for positive infinity, return result as bool array.
+
+    Parameters
+    ----------
+    x : array_like
+        The input array.
+    y : array_like, optional
+        A boolean array with the same shape as `x` to store the result.
+
+    Returns
+    -------
+    y : ndarray
+        A boolean array with the same dimensions as the input.
+        If second argument is not supplied then a boolean array is returned
+        with values True where the corresponding element of the input is
+        positive infinity and values False where the element of the input is
+        not positive infinity.
+
+        If a second argument is supplied the result is stored there. If the
+        type of that array is a numeric type the result is represented as zeros
+        and ones, if the type is boolean then as False and True.
+        The return value `y` is then a reference to that array.
+
+    See Also
+    --------
+    isinf, isneginf, isfinite, isnan
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754).
+
+    Errors result if the second argument is also supplied when `x` is a
+    scalar input, or if first and second arguments have different shapes.
+
+    Examples
+    --------
+    >>> np.isposinf(np.PINF)
+    array(True, dtype=bool)
+    >>> np.isposinf(np.inf)
+    array(True, dtype=bool)
+    >>> np.isposinf(np.NINF)
+    array(False, dtype=bool)
+    >>> np.isposinf([-np.inf, 0., np.inf])
+    array([False, False,  True], dtype=bool)
+
+    >>> x = np.array([-np.inf, 0., np.inf])
+    >>> y = np.array([2, 2, 2])
+    >>> np.isposinf(x, y)
+    array([0, 0, 1])
+    >>> y
+    array([0, 0, 1])
+
+    """
+    if y is None:
+        x = nx.asarray(x)
+        y = nx.empty(x.shape, dtype=nx.bool_)
+    nx.logical_and(nx.isinf(x), ~nx.signbit(x), y)
+    return y
+
+def isneginf(x, y=None):
+    """
+    Test element-wise for negative infinity, return result as bool array.
+
+    Parameters
+    ----------
+    x : array_like
+        The input array.
+    y : array_like, optional
+        A boolean array with the same shape and type as `x` to store the
+        result.
+
+    Returns
+    -------
+    y : ndarray
+        A boolean array with the same dimensions as the input.
+        If second argument is not supplied then a numpy boolean array is
+        returned with values True where the corresponding element of the
+        input is negative infinity and values False where the element of
+        the input is not negative infinity.
+
+        If a second argument is supplied the result is stored there. If the
+        type of that array is a numeric type the result is represented as
+        zeros and ones, if the type is boolean then as False and True. The
+        return value `y` is then a reference to that array.
+
+    See Also
+    --------
+    isinf, isposinf, isnan, isfinite
+
+    Notes
+    -----
+    Numpy uses the IEEE Standard for Binary Floating-Point for Arithmetic
+    (IEEE 754).
+
+    Errors result if the second argument is also supplied when x is a scalar
+    input, or if first and second arguments have different shapes.
+
+    Examples
+    --------
+    >>> np.isneginf(np.NINF)
+    array(True, dtype=bool)
+    >>> np.isneginf(np.inf)
+    array(False, dtype=bool)
+    >>> np.isneginf(np.PINF)
+    array(False, dtype=bool)
+    >>> np.isneginf([-np.inf, 0., np.inf])
+    array([ True, False, False], dtype=bool)
+
+    >>> x = np.array([-np.inf, 0., np.inf])
+    >>> y = np.array([2, 2, 2])
+    >>> np.isneginf(x, y)
+    array([1, 0, 0])
+    >>> y
+    array([1, 0, 0])
+
+    """
+    if y is None:
+        x = nx.asarray(x)
+        y = nx.empty(x.shape, dtype=nx.bool_)
+    nx.logical_and(nx.isinf(x), nx.signbit(x), y)
+    return y
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/user_array.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/user_array.py
new file mode 100644
index 0000000000..3103da57b7
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/user_array.py
@@ -0,0 +1,294 @@
+"""
+Standard container-class for easy multiple-inheritance.
+
+Try to inherit from the ndarray instead of using this class as this is not
+complete.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from numpy.core import (
+    array, asarray, absolute, add, subtract, multiply, divide,
+    remainder, power, left_shift, right_shift, bitwise_and, bitwise_or,
+    bitwise_xor, invert, less, less_equal, not_equal, equal, greater,
+    greater_equal, shape, reshape, arange, sin, sqrt, transpose
+)
+from numpy.compat import long
+
+
+class container(object):
+    """
+    container(data, dtype=None, copy=True)
+
+    Standard container-class for easy multiple-inheritance.
+
+    Methods
+    -------
+    copy
+    tostring
+    byteswap
+    astype
+
+    """
+    def __init__(self, data, dtype=None, copy=True):
+        self.array = array(data, dtype, copy=copy)
+
+    def __repr__(self):
+        if len(self.shape) > 0:
+            return self.__class__.__name__ + repr(self.array)[len("array"):]
+        else:
+            return self.__class__.__name__ + "(" + repr(self.array) + ")"
+
+    def __array__(self, t=None):
+        if t:
+            return self.array.astype(t)
+        return self.array
+
+    # Array as sequence
+    def __len__(self):
+        return len(self.array)
+
+    def __getitem__(self, index):
+        return self._rc(self.array[index])
+
+    def __getslice__(self, i, j):
+        return self._rc(self.array[i:j])
+
+    def __setitem__(self, index, value):
+        self.array[index] = asarray(value, self.dtype)
+
+    def __setslice__(self, i, j, value):
+        self.array[i:j] = asarray(value, self.dtype)
+
+    def __abs__(self):
+        return self._rc(absolute(self.array))
+
+    def __neg__(self):
+        return self._rc(-self.array)
+
+    def __add__(self, other):
+        return self._rc(self.array + asarray(other))
+
+    __radd__ = __add__
+
+    def __iadd__(self, other):
+        add(self.array, other, self.array)
+        return self
+
+    def __sub__(self, other):
+        return self._rc(self.array - asarray(other))
+
+    def __rsub__(self, other):
+        return self._rc(asarray(other) - self.array)
+
+    def __isub__(self, other):
+        subtract(self.array, other, self.array)
+        return self
+
+    def __mul__(self, other):
+        return self._rc(multiply(self.array, asarray(other)))
+
+    __rmul__ = __mul__
+
+    def __imul__(self, other):
+        multiply(self.array, other, self.array)
+        return self
+
+    def __div__(self, other):
+        return self._rc(divide(self.array, asarray(other)))
+
+    def __rdiv__(self, other):
+        return self._rc(divide(asarray(other), self.array))
+
+    def __idiv__(self, other):
+        divide(self.array, other, self.array)
+        return self
+
+    def __mod__(self, other):
+        return self._rc(remainder(self.array, other))
+
+    def __rmod__(self, other):
+        return self._rc(remainder(other, self.array))
+
+    def __imod__(self, other):
+        remainder(self.array, other, self.array)
+        return self
+
+    def __divmod__(self, other):
+        return (self._rc(divide(self.array, other)),
+                self._rc(remainder(self.array, other)))
+
+    def __rdivmod__(self, other):
+        return (self._rc(divide(other, self.array)),
+                self._rc(remainder(other, self.array)))
+
+    def __pow__(self, other):
+        return self._rc(power(self.array, asarray(other)))
+
+    def __rpow__(self, other):
+        return self._rc(power(asarray(other), self.array))
+
+    def __ipow__(self, other):
+        power(self.array, other, self.array)
+        return self
+
+    def __lshift__(self, other):
+        return self._rc(left_shift(self.array, other))
+
+    def __rshift__(self, other):
+        return self._rc(right_shift(self.array, other))
+
+    def __rlshift__(self, other):
+        return self._rc(left_shift(other, self.array))
+
+    def __rrshift__(self, other):
+        return self._rc(right_shift(other, self.array))
+
+    def __ilshift__(self, other):
+        left_shift(self.array, other, self.array)
+        return self
+
+    def __irshift__(self, other):
+        right_shift(self.array, other, self.array)
+        return self
+
+    def __and__(self, other):
+        return self._rc(bitwise_and(self.array, other))
+
+    def __rand__(self, other):
+        return self._rc(bitwise_and(other, self.array))
+
+    def __iand__(self, other):
+        bitwise_and(self.array, other, self.array)
+        return self
+
+    def __xor__(self, other):
+        return self._rc(bitwise_xor(self.array, other))
+
+    def __rxor__(self, other):
+        return self._rc(bitwise_xor(other, self.array))
+
+    def __ixor__(self, other):
+        bitwise_xor(self.array, other, self.array)
+        return self
+
+    def __or__(self, other):
+        return self._rc(bitwise_or(self.array, other))
+
+    def __ror__(self, other):
+        return self._rc(bitwise_or(other, self.array))
+
+    def __ior__(self, other):
+        bitwise_or(self.array, other, self.array)
+        return self
+
+    def __pos__(self):
+        return self._rc(self.array)
+
+    def __invert__(self):
+        return self._rc(invert(self.array))
+
+    def _scalarfunc(self, func):
+        if len(self.shape) == 0:
+            return func(self[0])
+        else:
+            raise TypeError(
+                "only rank-0 arrays can be converted to Python scalars.")
+
+    def __complex__(self):
+        return self._scalarfunc(complex)
+
+    def __float__(self):
+        return self._scalarfunc(float)
+
+    def __int__(self):
+        return self._scalarfunc(int)
+
+    def __long__(self):
+        return self._scalarfunc(long)
+
+    def __hex__(self):
+        return self._scalarfunc(hex)
+
+    def __oct__(self):
+        return self._scalarfunc(oct)
+
+    def __lt__(self, other):
+        return self._rc(less(self.array, other))
+
+    def __le__(self, other):
+        return self._rc(less_equal(self.array, other))
+
+    def __eq__(self, other):
+        return self._rc(equal(self.array, other))
+
+    def __ne__(self, other):
+        return self._rc(not_equal(self.array, other))
+
+    def __gt__(self, other):
+        return self._rc(greater(self.array, other))
+
+    def __ge__(self, other):
+        return self._rc(greater_equal(self.array, other))
+
+    def copy(self):
+        ""
+        return self._rc(self.array.copy())
+
+    def tostring(self):
+        ""
+        return self.array.tostring()
+
+    def byteswap(self):
+        ""
+        return self._rc(self.array.byteswap())
+
+    def astype(self, typecode):
+        ""
+        return self._rc(self.array.astype(typecode))
+
+    def _rc(self, a):
+        if len(shape(a)) == 0:
+            return a
+        else:
+            return self.__class__(a)
+
+    def __array_wrap__(self, *args):
+        return self.__class__(args[0])
+
+    def __setattr__(self, attr, value):
+        if attr == 'array':
+            object.__setattr__(self, attr, value)
+            return
+        try:
+            self.array.__setattr__(attr, value)
+        except AttributeError:
+            object.__setattr__(self, attr, value)
+
+    # Only called after other approaches fail.
+    def __getattr__(self, attr):
+        if (attr == 'array'):
+            return object.__getattribute__(self, attr)
+        return self.array.__getattribute__(attr)
+
+#############################################################
+# Test of class container
+#############################################################
+if __name__ == '__main__':
+    temp = reshape(arange(10000), (100, 100))
+
+    ua = container(temp)
+    # new object created begin test
+    print(dir(ua))
+    print(shape(ua), ua.shape)  # I have changed Numeric.py
+
+    ua_small = ua[:3, :5]
+    print(ua_small)
+    # this did not change ua[0,0], which is not normal behavior
+    ua_small[0, 0] = 10
+    print(ua_small[0, 0], ua[0, 0])
+    print(sin(ua_small) / 3. * 6. + sqrt(ua_small ** 2))
+    print(less(ua_small, 103), type(less(ua_small, 103)))
+    print(type(ua_small * reshape(arange(15), shape(ua_small))))
+    print(reshape(ua_small, (5, 3)))
+    print(transpose(ua_small))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/utils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/utils.py
new file mode 100644
index 0000000000..3f29699e97
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/lib/utils.py
@@ -0,0 +1,1122 @@
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import types
+import re
+import warnings
+
+from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype
+from numpy.core import ndarray, ufunc, asarray
+
+# getargspec and formatargspec were removed in Python 3.6
+from numpy.compat import getargspec, formatargspec
+
+__all__ = [
+    'issubclass_', 'issubsctype', 'issubdtype', 'deprecate',
+    'deprecate_with_doc', 'get_include', 'info', 'source', 'who',
+    'lookfor', 'byte_bounds', 'safe_eval'
+    ]
+
+def get_include():
+    """
+    Return the directory that contains the NumPy \\*.h header files.
+
+    Extension modules that need to compile against NumPy should use this
+    function to locate the appropriate include directory.
+
+    Notes
+    -----
+    When using ``distutils``, for example in ``setup.py``.
+    ::
+
+        import numpy as np
+        ...
+        Extension('extension_name', ...
+                include_dirs=[np.get_include()])
+        ...
+
+    """
+    import numpy
+    if numpy.show_config is None:
+        # running from numpy source directory
+        d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include')
+    else:
+        # using installed numpy core headers
+        import numpy.core as core
+        d = os.path.join(os.path.dirname(core.__file__), 'include')
+    return d
+
+
+def _set_function_name(func, name):
+    func.__name__ = name
+    return func
+
+
+class _Deprecate(object):
+    """
+    Decorator class to deprecate old functions.
+
+    Refer to `deprecate` for details.
+
+    See Also
+    --------
+    deprecate
+
+    """
+
+    def __init__(self, old_name=None, new_name=None, message=None):
+        self.old_name = old_name
+        self.new_name = new_name
+        self.message = message
+
+    def __call__(self, func, *args, **kwargs):
+        """
+        Decorator call.  Refer to ``decorate``.
+
+        """
+        old_name = self.old_name
+        new_name = self.new_name
+        message = self.message
+
+        import warnings
+        if old_name is None:
+            try:
+                old_name = func.__name__
+            except AttributeError:
+                old_name = func.__name__
+        if new_name is None:
+            depdoc = "`%s` is deprecated!" % old_name
+        else:
+            depdoc = "`%s` is deprecated, use `%s` instead!" % \
+                     (old_name, new_name)
+
+        if message is not None:
+            depdoc += "\n" + message
+
+        def newfunc(*args,**kwds):
+            """`arrayrange` is deprecated, use `arange` instead!"""
+            warnings.warn(depdoc, DeprecationWarning)
+            return func(*args, **kwds)
+
+        newfunc = _set_function_name(newfunc, old_name)
+        doc = func.__doc__
+        if doc is None:
+            doc = depdoc
+        else:
+            doc = '\n\n'.join([depdoc, doc])
+        newfunc.__doc__ = doc
+        try:
+            d = func.__dict__
+        except AttributeError:
+            pass
+        else:
+            newfunc.__dict__.update(d)
+        return newfunc
+
+def deprecate(*args, **kwargs):
+    """
+    Issues a DeprecationWarning, adds warning to `old_name`'s
+    docstring, rebinds ``old_name.__name__`` and returns the new
+    function object.
+
+    This function may also be used as a decorator.
+
+    Parameters
+    ----------
+    func : function
+        The function to be deprecated.
+    old_name : str, optional
+        The name of the function to be deprecated. Default is None, in
+        which case the name of `func` is used.
+    new_name : str, optional
+        The new name for the function. Default is None, in which case the
+        deprecation message is that `old_name` is deprecated. If given, the
+        deprecation message is that `old_name` is deprecated and `new_name`
+        should be used instead.
+    message : str, optional
+        Additional explanation of the deprecation.  Displayed in the
+        docstring after the warning.
+
+    Returns
+    -------
+    old_func : function
+        The deprecated function.
+
+    Examples
+    --------
+    Note that ``olduint`` returns a value after printing Deprecation
+    Warning:
+
+    >>> olduint = np.deprecate(np.uint)
+    >>> olduint(6)
+    /usr/lib/python2.5/site-packages/numpy/lib/utils.py:114:
+    DeprecationWarning: uint32 is deprecated
+      warnings.warn(str1, DeprecationWarning)
+    6
+
+    """
+    # Deprecate may be run as a function or as a decorator
+    # If run as a function, we initialise the decorator class
+    # and execute its __call__ method.
+
+    if args:
+        fn = args[0]
+        args = args[1:]
+
+        # backward compatibility -- can be removed
+        # after next release
+        if 'newname' in kwargs:
+            kwargs['new_name'] = kwargs.pop('newname')
+        if 'oldname' in kwargs:
+            kwargs['old_name'] = kwargs.pop('oldname')
+
+        return _Deprecate(*args, **kwargs)(fn)
+    else:
+        return _Deprecate(*args, **kwargs)
+
+deprecate_with_doc = lambda msg: _Deprecate(message=msg)
+
+
+#--------------------------------------------
+# Determine if two arrays can share memory
+#--------------------------------------------
+
+def byte_bounds(a):
+    """
+    Returns pointers to the end-points of an array.
+
+    Parameters
+    ----------
+    a : ndarray
+        Input array. It must conform to the Python-side of the array
+        interface.
+
+    Returns
+    -------
+    (low, high) : tuple of 2 integers
+        The first integer is the first byte of the array, the second
+        integer is just past the last byte of the array.  If `a` is not
+        contiguous it will not use every byte between the (`low`, `high`)
+        values.
+
+    Examples
+    --------
+    >>> I = np.eye(2, dtype='f'); I.dtype
+    dtype('float32')
+    >>> low, high = np.byte_bounds(I)
+    >>> high - low == I.size*I.itemsize
+    True
+    >>> I = np.eye(2, dtype='G'); I.dtype
+    dtype('complex192')
+    >>> low, high = np.byte_bounds(I)
+    >>> high - low == I.size*I.itemsize
+    True
+
+    """
+    ai = a.__array_interface__
+    a_data = ai['data'][0]
+    astrides = ai['strides']
+    ashape = ai['shape']
+    bytes_a = asarray(a).dtype.itemsize
+
+    a_low = a_high = a_data
+    if astrides is None:
+        # contiguous case
+        a_high += a.size * bytes_a
+    else:
+        for shape, stride in zip(ashape, astrides):
+            if stride < 0:
+                a_low += (shape-1)*stride
+            else:
+                a_high += (shape-1)*stride
+        a_high += bytes_a
+    return a_low, a_high
+
+
+#-----------------------------------------------------------------------------
+# Function for output and information on the variables used.
+#-----------------------------------------------------------------------------
+
+
+def who(vardict=None):
+    """
+    Print the Numpy arrays in the given dictionary.
+
+    If there is no dictionary passed in or `vardict` is None then returns
+    Numpy arrays in the globals() dictionary (all Numpy arrays in the
+    namespace).
+
+    Parameters
+    ----------
+    vardict : dict, optional
+        A dictionary possibly containing ndarrays.  Default is globals().
+
+    Returns
+    -------
+    out : None
+        Returns 'None'.
+
+    Notes
+    -----
+    Prints out the name, shape, bytes and type of all of the ndarrays
+    present in `vardict`.
+
+    Examples
+    --------
+    >>> a = np.arange(10)
+    >>> b = np.ones(20)
+    >>> np.who()
+    Name            Shape            Bytes            Type
+    ===========================================================
+    a               10               40               int32
+    b               20               160              float64
+    Upper bound on total bytes  =       200
+
+    >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str',
+    ... 'idx':5}
+    >>> np.who(d)
+    Name            Shape            Bytes            Type
+    ===========================================================
+    y               3                24               float64
+    x               2                16               float64
+    Upper bound on total bytes  =       40
+
+    """
+    if vardict is None:
+        frame = sys._getframe().f_back
+        vardict = frame.f_globals
+    sta = []
+    cache = {}
+    for name in vardict.keys():
+        if isinstance(vardict[name], ndarray):
+            var = vardict[name]
+            idv = id(var)
+            if idv in cache.keys():
+                namestr = name + " (%s)" % cache[idv]
+                original = 0
+            else:
+                cache[idv] = name
+                namestr = name
+                original = 1
+            shapestr = " x ".join(map(str, var.shape))
+            bytestr = str(var.nbytes)
+            sta.append([namestr, shapestr, bytestr, var.dtype.name,
+                        original])
+
+    maxname = 0
+    maxshape = 0
+    maxbyte = 0
+    totalbytes = 0
+    for k in range(len(sta)):
+        val = sta[k]
+        if maxname < len(val[0]):
+            maxname = len(val[0])
+        if maxshape < len(val[1]):
+            maxshape = len(val[1])
+        if maxbyte < len(val[2]):
+            maxbyte = len(val[2])
+        if val[4]:
+            totalbytes += int(val[2])
+
+    if len(sta) > 0:
+        sp1 = max(10, maxname)
+        sp2 = max(10, maxshape)
+        sp3 = max(10, maxbyte)
+        prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
+        print(prval + "\n" + "="*(len(prval)+5) + "\n")
+
+    for k in range(len(sta)):
+        val = sta[k]
+        print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
+                                        val[1], ' '*(sp2-len(val[1])+5),
+                                        val[2], ' '*(sp3-len(val[2])+5),
+                                        val[3]))
+    print("\nUpper bound on total bytes  =       %d" % totalbytes)
+    return
+
+#-----------------------------------------------------------------------------
+
+
+# NOTE:  pydoc defines a help function which works simliarly to this
+#  except it uses a pager to take over the screen.
+
+# combine name and arguments and split to multiple lines of width
+# characters.  End lines on a comma and begin argument list indented with
+# the rest of the arguments.
+def _split_line(name, arguments, width):
+    firstwidth = len(name)
+    k = firstwidth
+    newstr = name
+    sepstr = ", "
+    arglist = arguments.split(sepstr)
+    for argument in arglist:
+        if k == firstwidth:
+            addstr = ""
+        else:
+            addstr = sepstr
+        k = k + len(argument) + len(addstr)
+        if k > width:
+            k = firstwidth + 1 + len(argument)
+            newstr = newstr + ",\n" + " "*(firstwidth+2) + argument
+        else:
+            newstr = newstr + addstr + argument
+    return newstr
+
+_namedict = None
+_dictlist = None
+
+# Traverse all module directories underneath globals
+# to see if something is defined
+def _makenamedict(module='numpy'):
+    module = __import__(module, globals(), locals(), [])
+    thedict = {module.__name__:module.__dict__}
+    dictlist = [module.__name__]
+    totraverse = [module.__dict__]
+    while True:
+        if len(totraverse) == 0:
+            break
+        thisdict = totraverse.pop(0)
+        for x in thisdict.keys():
+            if isinstance(thisdict[x], types.ModuleType):
+                modname = thisdict[x].__name__
+                if modname not in dictlist:
+                    moddict = thisdict[x].__dict__
+                    dictlist.append(modname)
+                    totraverse.append(moddict)
+                    thedict[modname] = moddict
+    return thedict, dictlist
+
+
+def _info(obj, output=sys.stdout):
+    """Provide information about ndarray obj.
+
+    Parameters
+    ----------
+    obj: ndarray
+        Must be ndarray, not checked.
+    output:
+        Where printed output goes.
+
+    Notes
+    -----
+    Copied over from the numarray module prior to its removal.
+    Adapted somewhat as only numpy is an option now.
+
+    Called by info.
+
+    """
+    extra = ""
+    tic = ""
+    bp = lambda x: x
+    cls = getattr(obj, '__class__', type(obj))
+    nm = getattr(cls, '__name__', cls)
+    strides = obj.strides
+    endian = obj.dtype.byteorder
+
+    print("class: ", nm, file=output)
+    print("shape: ", obj.shape, file=output)
+    print("strides: ", strides, file=output)
+    print("itemsize: ", obj.itemsize, file=output)
+    print("aligned: ", bp(obj.flags.aligned), file=output)
+    print("contiguous: ", bp(obj.flags.contiguous), file=output)
+    print("fortran: ", obj.flags.fortran, file=output)
+    print(
+        "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra),
+        file=output
+        )
+    print("byteorder: ", end=' ', file=output)
+    if endian in ['|', '=']:
+        print("%s%s%s" % (tic, sys.byteorder, tic), file=output)
+        byteswap = False
+    elif endian == '>':
+        print("%sbig%s" % (tic, tic), file=output)
+        byteswap = sys.byteorder != "big"
+    else:
+        print("%slittle%s" % (tic, tic), file=output)
+        byteswap = sys.byteorder != "little"
+    print("byteswap: ", bp(byteswap), file=output)
+    print("type: %s" % obj.dtype, file=output)
+
+
+def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'):
+    """
+    Get help information for a function, class, or module.
+
+    Parameters
+    ----------
+    object : object or str, optional
+        Input object or name to get information about. If `object` is a
+        numpy object, its docstring is given. If it is a string, available
+        modules are searched for matching objects.  If None, information
+        about `info` itself is returned.
+    maxwidth : int, optional
+        Printing width.
+    output : file like object, optional
+        File like object that the output is written to, default is
+        ``stdout``.  The object has to be opened in 'w' or 'a' mode.
+    toplevel : str, optional
+        Start search at this level.
+
+    See Also
+    --------
+    source, lookfor
+
+    Notes
+    -----
+    When used interactively with an object, ``np.info(obj)`` is equivalent
+    to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython
+    prompt.
+
+    Examples
+    --------
+    >>> np.info(np.polyval) # doctest: +SKIP
+       polyval(p, x)
+         Evaluate the polynomial p at x.
+         ...
+
+    When using a string for `object` it is possible to get multiple results.
+
+    >>> np.info('fft') # doctest: +SKIP
+         *** Found in numpy ***
+    Core FFT routines
+    ...
+         *** Found in numpy.fft ***
+     fft(a, n=None, axis=-1)
+    ...
+         *** Repeat reference found in numpy.fft.fftpack ***
+         *** Total of 3 references found. ***
+
+    """
+    global _namedict, _dictlist
+    # Local import to speed up numpy's import time.
+    import pydoc
+    import inspect
+
+    if (hasattr(object, '_ppimport_importer') or
+           hasattr(object, '_ppimport_module')):
+        object = object._ppimport_module
+    elif hasattr(object, '_ppimport_attr'):
+        object = object._ppimport_attr
+
+    if object is None:
+        info(info)
+    elif isinstance(object, ndarray):
+        _info(object, output=output)
+    elif isinstance(object, str):
+        if _namedict is None:
+            _namedict, _dictlist = _makenamedict(toplevel)
+        numfound = 0
+        objlist = []
+        for namestr in _dictlist:
+            try:
+                obj = _namedict[namestr][object]
+                if id(obj) in objlist:
+                    print("\n     "
+                          "*** Repeat reference found in %s *** " % namestr,
+                          file=output
+                          )
+                else:
+                    objlist.append(id(obj))
+                    print("     *** Found in %s ***" % namestr, file=output)
+                    info(obj)
+                    print("-"*maxwidth, file=output)
+                numfound += 1
+            except KeyError:
+                pass
+        if numfound == 0:
+            print("Help for %s not found." % object, file=output)
+        else:
+            print("\n     "
+                  "*** Total of %d references found. ***" % numfound,
+                  file=output
+                  )
+
+    elif inspect.isfunction(object):
+        name = object.__name__
+        arguments = formatargspec(*getargspec(object))
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        print(inspect.getdoc(object), file=output)
+
+    elif inspect.isclass(object):
+        name = object.__name__
+        arguments = "()"
+        try:
+            if hasattr(object, '__init__'):
+                arguments = formatargspec(
+                        *getargspec(object.__init__.__func__)
+                        )
+                arglist = arguments.split(', ')
+                if len(arglist) > 1:
+                    arglist[1] = "("+arglist[1]
+                    arguments = ", ".join(arglist[1:])
+        except:
+            pass
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        doc1 = inspect.getdoc(object)
+        if doc1 is None:
+            if hasattr(object, '__init__'):
+                print(inspect.getdoc(object.__init__), file=output)
+        else:
+            print(inspect.getdoc(object), file=output)
+
+        methods = pydoc.allmethods(object)
+        if methods != []:
+            print("\n\nMethods:\n", file=output)
+            for meth in methods:
+                if meth[0] == '_':
+                    continue
+                thisobj = getattr(object, meth, None)
+                if thisobj is not None:
+                    methstr, other = pydoc.splitdoc(
+                            inspect.getdoc(thisobj) or "None"
+                            )
+                print("  %s  --  %s" % (meth, methstr), file=output)
+
+    elif (sys.version_info[0] < 3
+            and isinstance(object, types.InstanceType)):
+        # check for __call__ method
+        # types.InstanceType is the type of the instances of oldstyle classes
+        print("Instance of class: ", object.__class__.__name__, file=output)
+        print(file=output)
+        if hasattr(object, '__call__'):
+            arguments = formatargspec(
+                    *getargspec(object.__call__.__func__)
+                    )
+            arglist = arguments.split(', ')
+            if len(arglist) > 1:
+                arglist[1] = "("+arglist[1]
+                arguments = ", ".join(arglist[1:])
+            else:
+                arguments = "()"
+
+            if hasattr(object, 'name'):
+                name = "%s" % object.name
+            else:
+                name = "<name>"
+            if len(name+arguments) > maxwidth:
+                argstr = _split_line(name, arguments, maxwidth)
+            else:
+                argstr = name + arguments
+
+            print(" " + argstr + "\n", file=output)
+            doc = inspect.getdoc(object.__call__)
+            if doc is not None:
+                print(inspect.getdoc(object.__call__), file=output)
+            print(inspect.getdoc(object), file=output)
+
+        else:
+            print(inspect.getdoc(object), file=output)
+
+    elif inspect.ismethod(object):
+        name = object.__name__
+        arguments = formatargspec(
+                *getargspec(object.__func__)
+                )
+        arglist = arguments.split(', ')
+        if len(arglist) > 1:
+            arglist[1] = "("+arglist[1]
+            arguments = ", ".join(arglist[1:])
+        else:
+            arguments = "()"
+
+        if len(name+arguments) > maxwidth:
+            argstr = _split_line(name, arguments, maxwidth)
+        else:
+            argstr = name + arguments
+
+        print(" " + argstr + "\n", file=output)
+        print(inspect.getdoc(object), file=output)
+
+    elif hasattr(object, '__doc__'):
+        print(inspect.getdoc(object), file=output)
+
+
+def source(object, output=sys.stdout):
+    """
+    Print or write to a file the source code for a Numpy object.
+
+    The source code is only returned for objects written in Python. Many
+    functions and classes are defined in C and will therefore not return
+    useful information.
+
+    Parameters
+    ----------
+    object : numpy object
+        Input object. This can be any object (function, class, module,
+        ...).
+    output : file object, optional
+        If `output` not supplied then source code is printed to screen
+        (sys.stdout).  File object must be created with either write 'w' or
+        append 'a' modes.
+
+    See Also
+    --------
+    lookfor, info
+
+    Examples
+    --------
+    >>> np.source(np.interp)                        #doctest: +SKIP
+    In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
+    def interp(x, xp, fp, left=None, right=None):
+        \"\"\".... (full docstring printed)\"\"\"
+        if isinstance(x, (float, int, number)):
+            return compiled_interp([x], xp, fp, left, right).item()
+        else:
+            return compiled_interp(x, xp, fp, left, right)
+
+    The source code is only returned for objects written in Python.
+
+    >>> np.source(np.array)                         #doctest: +SKIP
+    Not available for this object.
+
+    """
+    # Local import to speed up numpy's import time.
+    import inspect
+    try:
+        print("In file: %s\n" % inspect.getsourcefile(object), file=output)
+        print(inspect.getsource(object), file=output)
+    except:
+        print("Not available for this object.", file=output)
+
+
+# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...}
+# where kind: "func", "class", "module", "object"
+# and index: index in breadth-first namespace traversal
+_lookfor_caches = {}
+
+# regexp whose match indicates that the string may contain a function
+# signature
+_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I)
+
+def lookfor(what, module=None, import_modules=True, regenerate=False,
+            output=None):
+    """
+    Do a keyword search on docstrings.
+
+    A list of of objects that matched the search is displayed,
+    sorted by relevance. All given keywords need to be found in the
+    docstring for it to be returned as a result, but the order does
+    not matter.
+
+    Parameters
+    ----------
+    what : str
+        String containing words to look for.
+    module : str or list, optional
+        Name of module(s) whose docstrings to go through.
+    import_modules : bool, optional
+        Whether to import sub-modules in packages. Default is True.
+    regenerate : bool, optional
+        Whether to re-generate the docstring cache. Default is False.
+    output : file-like, optional
+        File-like object to write the output to. If omitted, use a pager.
+
+    See Also
+    --------
+    source, info
+
+    Notes
+    -----
+    Relevance is determined only roughly, by checking if the keywords occur
+    in the function name, at the start of a docstring, etc.
+
+    Examples
+    --------
+    >>> np.lookfor('binary representation')
+    Search results for 'binary representation'
+    ------------------------------------------
+    numpy.binary_repr
+        Return the binary representation of the input number as a string.
+    numpy.core.setup_common.long_double_representation
+        Given a binary dump as given by GNU od -b, look for long double
+    numpy.base_repr
+        Return a string representation of a number in the given base system.
+    ...
+
+    """
+    import pydoc
+
+    # Cache
+    cache = _lookfor_generate_cache(module, import_modules, regenerate)
+
+    # Search
+    # XXX: maybe using a real stemming search engine would be better?
+    found = []
+    whats = str(what).lower().split()
+    if not whats:
+        return
+
+    for name, (docstring, kind, index) in cache.items():
+        if kind in ('module', 'object'):
+            # don't show modules or objects
+            continue
+        ok = True
+        doc = docstring.lower()
+        for w in whats:
+            if w not in doc:
+                ok = False
+                break
+        if ok:
+            found.append(name)
+
+    # Relevance sort
+    # XXX: this is full Harrison-Stetson heuristics now,
+    # XXX: it probably could be improved
+
+    kind_relevance = {'func': 1000, 'class': 1000,
+                      'module': -1000, 'object': -1000}
+
+    def relevance(name, docstr, kind, index):
+        r = 0
+        # do the keywords occur within the start of the docstring?
+        first_doc = "\n".join(docstr.lower().strip().split("\n")[:3])
+        r += sum([200 for w in whats if w in first_doc])
+        # do the keywords occur in the function name?
+        r += sum([30 for w in whats if w in name])
+        # is the full name long?
+        r += -len(name) * 5
+        # is the object of bad type?
+        r += kind_relevance.get(kind, -1000)
+        # is the object deep in namespace hierarchy?
+        r += -name.count('.') * 10
+        r += max(-index / 100, -100)
+        return r
+
+    def relevance_value(a):
+        return relevance(a, *cache[a])
+    found.sort(key=relevance_value)
+
+    # Pretty-print
+    s = "Search results for '%s'" % (' '.join(whats))
+    help_text = [s, "-"*len(s)]
+    for name in found[::-1]:
+        doc, kind, ix = cache[name]
+
+        doclines = [line.strip() for line in doc.strip().split("\n")
+                    if line.strip()]
+
+        # find a suitable short description
+        try:
+            first_doc = doclines[0].strip()
+            if _function_signature_re.search(first_doc):
+                first_doc = doclines[1].strip()
+        except IndexError:
+            first_doc = ""
+        help_text.append("%s\n    %s" % (name, first_doc))
+
+    if not found:
+        help_text.append("Nothing found.")
+
+    # Output
+    if output is not None:
+        output.write("\n".join(help_text))
+    elif len(help_text) > 10:
+        pager = pydoc.getpager()
+        pager("\n".join(help_text))
+    else:
+        print("\n".join(help_text))
+
+def _lookfor_generate_cache(module, import_modules, regenerate):
+    """
+    Generate docstring cache for given module.
+
+    Parameters
+    ----------
+    module : str, None, module
+        Module for which to generate docstring cache
+    import_modules : bool
+        Whether to import sub-modules in packages.
+    regenerate : bool
+        Re-generate the docstring cache
+
+    Returns
+    -------
+    cache : dict {obj_full_name: (docstring, kind, index), ...}
+        Docstring cache for the module, either cached one (regenerate=False)
+        or newly generated.
+
+    """
+    global _lookfor_caches
+    # Local import to speed up numpy's import time.
+    import inspect
+
+    if sys.version_info[0] >= 3:
+        # In Python3 stderr, stdout are text files.
+        from io import StringIO
+    else:
+        from StringIO import StringIO
+
+    if module is None:
+        module = "numpy"
+
+    if isinstance(module, str):
+        try:
+            __import__(module)
+        except ImportError:
+            return {}
+        module = sys.modules[module]
+    elif isinstance(module, list) or isinstance(module, tuple):
+        cache = {}
+        for mod in module:
+            cache.update(_lookfor_generate_cache(mod, import_modules,
+                                                 regenerate))
+        return cache
+
+    if id(module) in _lookfor_caches and not regenerate:
+        return _lookfor_caches[id(module)]
+
+    # walk items and collect docstrings
+    cache = {}
+    _lookfor_caches[id(module)] = cache
+    seen = {}
+    index = 0
+    stack = [(module.__name__, module)]
+    while stack:
+        name, item = stack.pop(0)
+        if id(item) in seen:
+            continue
+        seen[id(item)] = True
+
+        index += 1
+        kind = "object"
+
+        if inspect.ismodule(item):
+            kind = "module"
+            try:
+                _all = item.__all__
+            except AttributeError:
+                _all = None
+
+            # import sub-packages
+            if import_modules and hasattr(item, '__path__'):
+                for pth in item.__path__:
+                    for mod_path in os.listdir(pth):
+                        this_py = os.path.join(pth, mod_path)
+                        init_py = os.path.join(pth, mod_path, '__init__.py')
+                        if (os.path.isfile(this_py) and
+                                mod_path.endswith('.py')):
+                            to_import = mod_path[:-3]
+                        elif os.path.isfile(init_py):
+                            to_import = mod_path
+                        else:
+                            continue
+                        if to_import == '__init__':
+                            continue
+
+                        try:
+                            # Catch SystemExit, too
+                            base_exc = BaseException
+                        except NameError:
+                            # Python 2.4 doesn't have BaseException
+                            base_exc = Exception
+
+                        try:
+                            old_stdout = sys.stdout
+                            old_stderr = sys.stderr
+                            try:
+                                sys.stdout = StringIO()
+                                sys.stderr = StringIO()
+                                __import__("%s.%s" % (name, to_import))
+                            finally:
+                                sys.stdout = old_stdout
+                                sys.stderr = old_stderr
+                        except base_exc:
+                            continue
+
+            for n, v in _getmembers(item):
+                try:
+                    item_name = getattr(v, '__name__', "%s.%s" % (name, n))
+                    mod_name = getattr(v, '__module__', None)
+                except NameError:
+                    # ref. SWIG's global cvars
+                    #    NameError: Unknown C global variable
+                    item_name = "%s.%s" % (name, n)
+                    mod_name = None
+                if '.' not in item_name and mod_name:
+                    item_name = "%s.%s" % (mod_name, item_name)
+
+                if not item_name.startswith(name + '.'):
+                    # don't crawl "foreign" objects
+                    if isinstance(v, ufunc):
+                        # ... unless they are ufuncs
+                        pass
+                    else:
+                        continue
+                elif not (inspect.ismodule(v) or _all is None or n in _all):
+                    continue
+                stack.append(("%s.%s" % (name, n), v))
+        elif inspect.isclass(item):
+            kind = "class"
+            for n, v in _getmembers(item):
+                stack.append(("%s.%s" % (name, n), v))
+        elif hasattr(item, "__call__"):
+            kind = "func"
+
+        try:
+            doc = inspect.getdoc(item)
+        except NameError:
+            # ref SWIG's NameError: Unknown C global variable
+            doc = None
+        if doc is not None:
+            cache[name] = (doc, kind, index)
+
+    return cache
+
+def _getmembers(item):
+    import inspect
+    try:
+        members = inspect.getmembers(item)
+    except Exception:
+        members = [(x, getattr(item, x)) for x in dir(item)
+                   if hasattr(item, x)]
+    return members
+
+#-----------------------------------------------------------------------------
+
+# The following SafeEval class and company are adapted from Michael Spencer's
+# ASPN Python Cookbook recipe:
+#   http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/364469
+# Accordingly it is mostly Copyright 2006 by Michael Spencer.
+# The recipe, like most of the other ASPN Python Cookbook recipes was made
+# available under the Python license.
+#   http://www.python.org/license
+
+# It has been modified to:
+#   * handle unary -/+
+#   * support True/False/None
+#   * raise SyntaxError instead of a custom exception.
+
+class SafeEval(object):
+    """
+    Object to evaluate constant string expressions.
+
+    This includes strings with lists, dicts and tuples using the abstract
+    syntax tree created by ``compiler.parse``.
+
+    .. deprecated:: 1.10.0
+
+    See Also
+    --------
+    safe_eval
+
+    """
+    def __init__(self):
+        # 2014-10-15, 1.10
+        warnings.warn("SafeEval is deprecated in 1.10 and will be removed.",
+                      DeprecationWarning)
+
+    def visit(self, node):
+        cls = node.__class__
+        meth = getattr(self, 'visit' + cls.__name__, self.default)
+        return meth(node)
+
+    def default(self, node):
+        raise SyntaxError("Unsupported source construct: %s"
+                          % node.__class__)
+
+    def visitExpression(self, node):
+        return self.visit(node.body)
+
+    def visitNum(self, node):
+        return node.n
+
+    def visitStr(self, node):
+        return node.s
+
+    def visitBytes(self, node):
+        return node.s
+
+    def visitDict(self, node,**kw):
+        return dict([(self.visit(k), self.visit(v))
+                     for k, v in zip(node.keys, node.values)])
+
+    def visitTuple(self, node):
+        return tuple([self.visit(i) for i in node.elts])
+
+    def visitList(self, node):
+        return [self.visit(i) for i in node.elts]
+
+    def visitUnaryOp(self, node):
+        import ast
+        if isinstance(node.op, ast.UAdd):
+            return +self.visit(node.operand)
+        elif isinstance(node.op, ast.USub):
+            return -self.visit(node.operand)
+        else:
+            raise SyntaxError("Unknown unary op: %r" % node.op)
+
+    def visitName(self, node):
+        if node.id == 'False':
+            return False
+        elif node.id == 'True':
+            return True
+        elif node.id == 'None':
+            return None
+        else:
+            raise SyntaxError("Unknown name: %s" % node.id)
+
+    def visitNameConstant(self, node):
+        return node.value
+
+
+def safe_eval(source):
+    """
+    Protected string evaluation.
+
+    Evaluate a string containing a Python literal expression without
+    allowing the execution of arbitrary non-literal code.
+
+    Parameters
+    ----------
+    source : str
+        The string to evaluate.
+
+    Returns
+    -------
+    obj : object
+       The result of evaluating `source`.
+
+    Raises
+    ------
+    SyntaxError
+        If the code has invalid Python syntax, or if it contains
+        non-literal code.
+
+    Examples
+    --------
+    >>> np.safe_eval('1')
+    1
+    >>> np.safe_eval('[1, 2, 3]')
+    [1, 2, 3]
+    >>> np.safe_eval('{"foo": ("bar", 10.0)}')
+    {'foo': ('bar', 10.0)}
+
+    >>> np.safe_eval('import os')
+    Traceback (most recent call last):
+      ...
+    SyntaxError: invalid syntax
+
+    >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()')
+    Traceback (most recent call last):
+      ...
+    SyntaxError: Unsupported source construct: compiler.ast.CallFunc
+
+    """
+    # Local import to speed up numpy's import time.
+    import ast
+
+    return ast.literal_eval(source)
+#-----------------------------------------------------------------------------
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.py
new file mode 100644
index 0000000000..69445f541d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.py
@@ -0,0 +1,55 @@
+"""
+Core Linear Algebra Tools
+=========================
+
+=============== ==========================================================
+Linear algebra basics
+==========================================================================
+norm            Vector or matrix norm
+inv             Inverse of a square matrix
+solve           Solve a linear system of equations
+det             Determinant of a square matrix
+slogdet         Logarithm of the determinant of a square matrix
+lstsq           Solve linear least-squares problem
+pinv            Pseudo-inverse (Moore-Penrose) calculated using a singular
+                value decomposition
+matrix_power    Integer power of a square matrix
+matrix_rank     Calculate matrix rank using an SVD-based method
+=============== ==========================================================
+
+=============== ==========================================================
+Eigenvalues and decompositions
+==========================================================================
+eig             Eigenvalues and vectors of a square matrix
+eigh            Eigenvalues and eigenvectors of a Hermitian matrix
+eigvals         Eigenvalues of a square matrix
+eigvalsh        Eigenvalues of a Hermitian matrix
+qr              QR decomposition of a matrix
+svd             Singular value decomposition of a matrix
+cholesky        Cholesky decomposition of a matrix
+=============== ==========================================================
+
+=============== ==========================================================
+Tensor operations
+==========================================================================
+tensorsolve     Solve a linear tensor equation
+tensorinv       Calculate an inverse of a tensor
+=============== ==========================================================
+
+=============== ==========================================================
+Exceptions
+==========================================================================
+LinAlgError     Indicates a failed linear algebra operation
+=============== ==========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# To get sub-modules
+from .info import __doc__
+
+from .linalg import *
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..0edfd6ee01cfc58457ddd68c0a0d9ab68f68eb41
GIT binary patch
literal 201216
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

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/info.py
new file mode 100644
index 0000000000..646ecda04a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/info.py
@@ -0,0 +1,37 @@
+"""\
+Core Linear Algebra Tools
+-------------------------
+Linear algebra basics:
+
+- norm            Vector or matrix norm
+- inv             Inverse of a square matrix
+- solve           Solve a linear system of equations
+- det             Determinant of a square matrix
+- lstsq           Solve linear least-squares problem
+- pinv            Pseudo-inverse (Moore-Penrose) calculated using a singular
+                  value decomposition
+- matrix_power    Integer power of a square matrix
+
+Eigenvalues and decompositions:
+
+- eig             Eigenvalues and vectors of a square matrix
+- eigh            Eigenvalues and eigenvectors of a Hermitian matrix
+- eigvals         Eigenvalues of a square matrix
+- eigvalsh        Eigenvalues of a Hermitian matrix
+- qr              QR decomposition of a matrix
+- svd             Singular value decomposition of a matrix
+- cholesky        Cholesky decomposition of a matrix
+
+Tensor operations:
+
+- tensorsolve     Solve a linear tensor equation
+- tensorinv       Calculate an inverse of a tensor
+
+Exceptions:
+
+- LinAlgError     Indicates a failed linear algebra operation
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..44ef32b6c70d21cb1f9e979129eb49fb2f11ca23
GIT binary patch
literal 24064
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
acS|fVSYQFF!wx|BAUmKUBQM+siH`wROE=g6

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.py
new file mode 100644
index 0000000000..9d486d2a5d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.py
@@ -0,0 +1,2409 @@
+"""Lite version of scipy.linalg.
+
+Notes
+-----
+This module is a lite version of the linalg.py module in SciPy which
+contains high-level Python interface to the LAPACK library.  The lite
+version only accesses the following LAPACK functions: dgesv, zgesv,
+dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf,
+zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr.
+"""
+from __future__ import division, absolute_import, print_function
+
+
+__all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv',
+           'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det',
+           'svd', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond', 'matrix_rank',
+           'LinAlgError', 'multi_dot']
+
+import warnings
+
+from numpy.core import (
+    array, asarray, zeros, empty, empty_like, transpose, intc, single, double,
+    csingle, cdouble, inexact, complexfloating, newaxis, ravel, all, Inf, dot,
+    add, multiply, sqrt, maximum, fastCopyAndTranspose, sum, isfinite, size,
+    finfo, errstate, geterrobj, longdouble, rollaxis, amin, amax, product, abs,
+    broadcast, atleast_2d, intp, asanyarray, isscalar
+    )
+from numpy.lib import triu, asfarray
+from numpy.linalg import lapack_lite, _umath_linalg
+from numpy.matrixlib.defmatrix import matrix_power
+from numpy.compat import asbytes
+
+# For Python2/3 compatibility
+_N = asbytes('N')
+_V = asbytes('V')
+_A = asbytes('A')
+_S = asbytes('S')
+_L = asbytes('L')
+
+fortran_int = intc
+
+# Error object
+class LinAlgError(Exception):
+    """
+    Generic Python-exception-derived object raised by linalg functions.
+
+    General purpose exception class, derived from Python's exception.Exception
+    class, programmatically raised in linalg functions when a Linear
+    Algebra-related condition would prevent further correct execution of the
+    function.
+
+    Parameters
+    ----------
+    None
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> LA.inv(np.zeros((2,2)))
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+      File "...linalg.py", line 350,
+        in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
+      File "...linalg.py", line 249,
+        in solve
+        raise LinAlgError('Singular matrix')
+    numpy.linalg.LinAlgError: Singular matrix
+
+    """
+    pass
+
+# Dealing with errors in _umath_linalg
+
+_linalg_error_extobj = None
+
+def _determine_error_states():
+    global _linalg_error_extobj
+    errobj = geterrobj()
+    bufsize = errobj[0]
+
+    with errstate(invalid='call', over='ignore',
+                  divide='ignore', under='ignore'):
+        invalid_call_errmask = geterrobj()[1]
+
+    _linalg_error_extobj = [bufsize, invalid_call_errmask, None]
+
+_determine_error_states()
+
+def _raise_linalgerror_singular(err, flag):
+    raise LinAlgError("Singular matrix")
+
+def _raise_linalgerror_nonposdef(err, flag):
+    raise LinAlgError("Matrix is not positive definite")
+
+def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
+    raise LinAlgError("Eigenvalues did not converge")
+
+def _raise_linalgerror_svd_nonconvergence(err, flag):
+    raise LinAlgError("SVD did not converge")
+
+def get_linalg_error_extobj(callback):
+    extobj = list(_linalg_error_extobj)
+    extobj[2] = callback
+    return extobj
+
+def _makearray(a):
+    new = asarray(a)
+    wrap = getattr(a, "__array_prepare__", new.__array_wrap__)
+    return new, wrap
+
+def isComplexType(t):
+    return issubclass(t, complexfloating)
+
+_real_types_map = {single : single,
+                   double : double,
+                   csingle : single,
+                   cdouble : double}
+
+_complex_types_map = {single : csingle,
+                      double : cdouble,
+                      csingle : csingle,
+                      cdouble : cdouble}
+
+def _realType(t, default=double):
+    return _real_types_map.get(t, default)
+
+def _complexType(t, default=cdouble):
+    return _complex_types_map.get(t, default)
+
+def _linalgRealType(t):
+    """Cast the type t to either double or cdouble."""
+    return double
+
+_complex_types_map = {single : csingle,
+                      double : cdouble,
+                      csingle : csingle,
+                      cdouble : cdouble}
+
+def _commonType(*arrays):
+    # in lite version, use higher precision (always double or cdouble)
+    result_type = single
+    is_complex = False
+    for a in arrays:
+        if issubclass(a.dtype.type, inexact):
+            if isComplexType(a.dtype.type):
+                is_complex = True
+            rt = _realType(a.dtype.type, default=None)
+            if rt is None:
+                # unsupported inexact scalar
+                raise TypeError("array type %s is unsupported in linalg" %
+                        (a.dtype.name,))
+        else:
+            rt = double
+        if rt is double:
+            result_type = double
+    if is_complex:
+        t = cdouble
+        result_type = _complex_types_map[result_type]
+    else:
+        t = double
+    return t, result_type
+
+
+# _fastCopyAndTranpose assumes the input is 2D (as all the calls in here are).
+
+_fastCT = fastCopyAndTranspose
+
+def _to_native_byte_order(*arrays):
+    ret = []
+    for arr in arrays:
+        if arr.dtype.byteorder not in ('=', '|'):
+            ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('=')))
+        else:
+            ret.append(arr)
+    if len(ret) == 1:
+        return ret[0]
+    else:
+        return ret
+
+def _fastCopyAndTranspose(type, *arrays):
+    cast_arrays = ()
+    for a in arrays:
+        if a.dtype.type is type:
+            cast_arrays = cast_arrays + (_fastCT(a),)
+        else:
+            cast_arrays = cast_arrays + (_fastCT(a.astype(type)),)
+    if len(cast_arrays) == 1:
+        return cast_arrays[0]
+    else:
+        return cast_arrays
+
+def _assertRank2(*arrays):
+    for a in arrays:
+        if len(a.shape) != 2:
+            raise LinAlgError('%d-dimensional array given. Array must be '
+                    'two-dimensional' % len(a.shape))
+
+def _assertRankAtLeast2(*arrays):
+    for a in arrays:
+        if len(a.shape) < 2:
+            raise LinAlgError('%d-dimensional array given. Array must be '
+                    'at least two-dimensional' % len(a.shape))
+
+def _assertSquareness(*arrays):
+    for a in arrays:
+        if max(a.shape) != min(a.shape):
+            raise LinAlgError('Array must be square')
+
+def _assertNdSquareness(*arrays):
+    for a in arrays:
+        if max(a.shape[-2:]) != min(a.shape[-2:]):
+            raise LinAlgError('Last 2 dimensions of the array must be square')
+
+def _assertFinite(*arrays):
+    for a in arrays:
+        if not (isfinite(a).all()):
+            raise LinAlgError("Array must not contain infs or NaNs")
+
+def _assertNoEmpty2d(*arrays):
+    for a in arrays:
+        if a.size == 0 and product(a.shape[-2:]) == 0:
+            raise LinAlgError("Arrays cannot be empty")
+
+
+# Linear equations
+
+def tensorsolve(a, b, axes=None):
+    """
+    Solve the tensor equation ``a x = b`` for x.
+
+    It is assumed that all indices of `x` are summed over in the product,
+    together with the rightmost indices of `a`, as is done in, for example,
+    ``tensordot(a, x, axes=len(b.shape))``.
+
+    Parameters
+    ----------
+    a : array_like
+        Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals
+        the shape of that sub-tensor of `a` consisting of the appropriate
+        number of its rightmost indices, and must be such that
+        ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be
+        'square').
+    b : array_like
+        Right-hand tensor, which can be of any shape.
+    axes : tuple of ints, optional
+        Axes in `a` to reorder to the right, before inversion.
+        If None (default), no reordering is done.
+
+    Returns
+    -------
+    x : ndarray, shape Q
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not 'square' (in the above sense).
+
+    See Also
+    --------
+    tensordot, tensorinv, einsum
+
+    Examples
+    --------
+    >>> a = np.eye(2*3*4)
+    >>> a.shape = (2*3, 4, 2, 3, 4)
+    >>> b = np.random.randn(2*3, 4)
+    >>> x = np.linalg.tensorsolve(a, b)
+    >>> x.shape
+    (2, 3, 4)
+    >>> np.allclose(np.tensordot(a, x, axes=3), b)
+    True
+
+    """
+    a, wrap = _makearray(a)
+    b = asarray(b)
+    an = a.ndim
+
+    if axes is not None:
+        allaxes = list(range(0, an))
+        for k in axes:
+            allaxes.remove(k)
+            allaxes.insert(an, k)
+        a = a.transpose(allaxes)
+
+    oldshape = a.shape[-(an-b.ndim):]
+    prod = 1
+    for k in oldshape:
+        prod *= k
+
+    a = a.reshape(-1, prod)
+    b = b.ravel()
+    res = wrap(solve(a, b))
+    res.shape = oldshape
+    return res
+
+def solve(a, b):
+    """
+    Solve a linear matrix equation, or system of linear scalar equations.
+
+    Computes the "exact" solution, `x`, of the well-determined, i.e., full
+    rank, linear matrix equation `ax = b`.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Coefficient matrix.
+    b : {(..., M,), (..., M, K)}, array_like
+        Ordinate or "dependent variable" values.
+
+    Returns
+    -------
+    x : {(..., M,), (..., M, K)} ndarray
+        Solution to the system a x = b.  Returned shape is identical to `b`.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not square.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The solutions are computed using LAPACK routine _gesv
+
+    `a` must be square and of full-rank, i.e., all rows (or, equivalently,
+    columns) must be linearly independent; if either is not true, use
+    `lstsq` for the least-squares best "solution" of the
+    system/equation.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pg. 22.
+
+    Examples
+    --------
+    Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``:
+
+    >>> a = np.array([[3,1], [1,2]])
+    >>> b = np.array([9,8])
+    >>> x = np.linalg.solve(a, b)
+    >>> x
+    array([ 2.,  3.])
+
+    Check that the solution is correct:
+
+    >>> np.allclose(np.dot(a, x), b)
+    True
+
+    """
+    a, _ = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    b, wrap = _makearray(b)
+    t, result_t = _commonType(a, b)
+
+    # We use the b = (..., M,) logic, only if the number of extra dimensions
+    # match exactly
+    if b.ndim == a.ndim - 1:
+        if a.shape[-1] == 0 and b.shape[-1] == 0:
+            # Legal, but the ufunc cannot handle the 0-sized inner dims
+            # let the ufunc handle all wrong cases.
+            a = a.reshape(a.shape[:-1])
+            bc = broadcast(a, b)
+            return wrap(empty(bc.shape, dtype=result_t))
+
+        gufunc = _umath_linalg.solve1
+    else:
+        if b.size == 0:
+            if (a.shape[-1] == 0 and b.shape[-2] == 0) or b.shape[-1] == 0:
+                a = a[:,:1].reshape(a.shape[:-1] + (1,))
+                bc = broadcast(a, b)
+                return wrap(empty(bc.shape, dtype=result_t))
+
+        gufunc = _umath_linalg.solve
+
+    signature = 'DD->D' if isComplexType(t) else 'dd->d'
+    extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
+    r = gufunc(a, b, signature=signature, extobj=extobj)
+
+    return wrap(r.astype(result_t, copy=False))
+
+
+def tensorinv(a, ind=2):
+    """
+    Compute the 'inverse' of an N-dimensional array.
+
+    The result is an inverse for `a` relative to the tensordot operation
+    ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy,
+    ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the
+    tensordot operation.
+
+    Parameters
+    ----------
+    a : array_like
+        Tensor to 'invert'. Its shape must be 'square', i. e.,
+        ``prod(a.shape[:ind]) == prod(a.shape[ind:])``.
+    ind : int, optional
+        Number of first indices that are involved in the inverse sum.
+        Must be a positive integer, default is 2.
+
+    Returns
+    -------
+    b : ndarray
+        `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is singular or not 'square' (in the above sense).
+
+    See Also
+    --------
+    tensordot, tensorsolve
+
+    Examples
+    --------
+    >>> a = np.eye(4*6)
+    >>> a.shape = (4, 6, 8, 3)
+    >>> ainv = np.linalg.tensorinv(a, ind=2)
+    >>> ainv.shape
+    (8, 3, 4, 6)
+    >>> b = np.random.randn(4, 6)
+    >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b))
+    True
+
+    >>> a = np.eye(4*6)
+    >>> a.shape = (24, 8, 3)
+    >>> ainv = np.linalg.tensorinv(a, ind=1)
+    >>> ainv.shape
+    (8, 3, 24)
+    >>> b = np.random.randn(24)
+    >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b))
+    True
+
+    """
+    a = asarray(a)
+    oldshape = a.shape
+    prod = 1
+    if ind > 0:
+        invshape = oldshape[ind:] + oldshape[:ind]
+        for k in oldshape[ind:]:
+            prod *= k
+    else:
+        raise ValueError("Invalid ind argument.")
+    a = a.reshape(prod, -1)
+    ia = inv(a)
+    return ia.reshape(*invshape)
+
+
+# Matrix inversion
+
+def inv(a):
+    """
+    Compute the (multiplicative) inverse of a matrix.
+
+    Given a square matrix `a`, return the matrix `ainv` satisfying
+    ``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Matrix to be inverted.
+
+    Returns
+    -------
+    ainv : (..., M, M) ndarray or matrix
+        (Multiplicative) inverse of the matrix `a`.
+
+    Raises
+    ------
+    LinAlgError
+        If `a` is not square or inversion fails.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    Examples
+    --------
+    >>> from numpy.linalg import inv
+    >>> a = np.array([[1., 2.], [3., 4.]])
+    >>> ainv = inv(a)
+    >>> np.allclose(np.dot(a, ainv), np.eye(2))
+    True
+    >>> np.allclose(np.dot(ainv, a), np.eye(2))
+    True
+
+    If a is a matrix object, then the return value is a matrix as well:
+
+    >>> ainv = inv(np.matrix(a))
+    >>> ainv
+    matrix([[-2. ,  1. ],
+            [ 1.5, -0.5]])
+
+    Inverses of several matrices can be computed at once:
+
+    >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
+    >>> inv(a)
+    array([[[-2. ,  1. ],
+            [ 1.5, -0.5]],
+           [[-5. ,  2. ],
+            [ 3. , -1. ]]])
+
+    """
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+
+    if a.shape[-1] == 0:
+        # The inner array is 0x0, the ufunc cannot handle this case
+        return wrap(empty_like(a, dtype=result_t))
+
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
+    ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
+    return wrap(ainv.astype(result_t, copy=False))
+
+
+# Cholesky decomposition
+
+def cholesky(a):
+    """
+    Cholesky decomposition.
+
+    Return the Cholesky decomposition, `L * L.H`, of the square matrix `a`,
+    where `L` is lower-triangular and .H is the conjugate transpose operator
+    (which is the ordinary transpose if `a` is real-valued).  `a` must be
+    Hermitian (symmetric if real-valued) and positive-definite.  Only `L` is
+    actually returned.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Hermitian (symmetric if all elements are real), positive-definite
+        input matrix.
+
+    Returns
+    -------
+    L : (..., M, M) array_like
+        Upper or lower-triangular Cholesky factor of `a`.  Returns a
+        matrix object if `a` is a matrix object.
+
+    Raises
+    ------
+    LinAlgError
+       If the decomposition fails, for example, if `a` is not
+       positive-definite.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The Cholesky decomposition is often used as a fast way of solving
+
+    .. math:: A \\mathbf{x} = \\mathbf{b}
+
+    (when `A` is both Hermitian/symmetric and positive-definite).
+
+    First, we solve for :math:`\\mathbf{y}` in
+
+    .. math:: L \\mathbf{y} = \\mathbf{b},
+
+    and then for :math:`\\mathbf{x}` in
+
+    .. math:: L.H \\mathbf{x} = \\mathbf{y}.
+
+    Examples
+    --------
+    >>> A = np.array([[1,-2j],[2j,5]])
+    >>> A
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> L = np.linalg.cholesky(A)
+    >>> L
+    array([[ 1.+0.j,  0.+0.j],
+           [ 0.+2.j,  1.+0.j]])
+    >>> np.dot(L, L.T.conj()) # verify that L * L.H = A
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like?
+    >>> np.linalg.cholesky(A) # an ndarray object is returned
+    array([[ 1.+0.j,  0.+0.j],
+           [ 0.+2.j,  1.+0.j]])
+    >>> # But a matrix object is returned if A is a matrix object
+    >>> LA.cholesky(np.matrix(A))
+    matrix([[ 1.+0.j,  0.+0.j],
+            [ 0.+2.j,  1.+0.j]])
+
+    """
+    extobj = get_linalg_error_extobj(_raise_linalgerror_nonposdef)
+    gufunc = _umath_linalg.cholesky_lo
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    r = gufunc(a, signature=signature, extobj=extobj)
+    return wrap(r.astype(result_t, copy=False))
+
+# QR decompostion
+
+def qr(a, mode='reduced'):
+    """
+    Compute the qr factorization of a matrix.
+
+    Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is
+    upper-triangular.
+
+    Parameters
+    ----------
+    a : array_like, shape (M, N)
+        Matrix to be factored.
+    mode : {'reduced', 'complete', 'r', 'raw', 'full', 'economic'}, optional
+        If K = min(M, N), then
+
+        'reduced'  : returns q, r with dimensions (M, K), (K, N) (default)
+        'complete' : returns q, r with dimensions (M, M), (M, N)
+        'r'        : returns r only with dimensions (K, N)
+        'raw'      : returns h, tau with dimensions (N, M), (K,)
+        'full'     : alias of 'reduced', deprecated
+        'economic' : returns h from 'raw', deprecated.
+
+        The options 'reduced', 'complete, and 'raw' are new in numpy 1.8,
+        see the notes for more information. The default is 'reduced' and to
+        maintain backward compatibility with earlier versions of numpy both
+        it and the old default 'full' can be omitted. Note that array h
+        returned in 'raw' mode is transposed for calling Fortran. The
+        'economic' mode is deprecated.  The modes 'full' and 'economic' may
+        be passed using only the first letter for backwards compatibility,
+        but all others must be spelled out. See the Notes for more
+        explanation.
+
+
+    Returns
+    -------
+    q : ndarray of float or complex, optional
+        A matrix with orthonormal columns. When mode = 'complete' the
+        result is an orthogonal/unitary matrix depending on whether or not
+        a is real/complex. The determinant may be either +/- 1 in that
+        case.
+    r : ndarray of float or complex, optional
+        The upper-triangular matrix.
+    (h, tau) : ndarrays of np.double or np.cdouble, optional
+        The array h contains the Householder reflectors that generate q
+        along with r. The tau array contains scaling factors for the
+        reflectors. In the deprecated  'economic' mode only h is returned.
+
+    Raises
+    ------
+    LinAlgError
+        If factoring fails.
+
+    Notes
+    -----
+    This is an interface to the LAPACK routines dgeqrf, zgeqrf,
+    dorgqr, and zungqr.
+
+    For more information on the qr factorization, see for example:
+    http://en.wikipedia.org/wiki/QR_factorization
+
+    Subclasses of `ndarray` are preserved except for the 'raw' mode. So if
+    `a` is of type `matrix`, all the return values will be matrices too.
+
+    New 'reduced', 'complete', and 'raw' options for mode were added in
+    Numpy 1.8 and the old option 'full' was made an alias of 'reduced'.  In
+    addition the options 'full' and 'economic' were deprecated.  Because
+    'full' was the previous default and 'reduced' is the new default,
+    backward compatibility can be maintained by letting `mode` default.
+    The 'raw' option was added so that LAPACK routines that can multiply
+    arrays by q using the Householder reflectors can be used. Note that in
+    this case the returned arrays are of type np.double or np.cdouble and
+    the h array is transposed to be FORTRAN compatible.  No routines using
+    the 'raw' return are currently exposed by numpy, but some are available
+    in lapack_lite and just await the necessary work.
+
+    Examples
+    --------
+    >>> a = np.random.randn(9, 6)
+    >>> q, r = np.linalg.qr(a)
+    >>> np.allclose(a, np.dot(q, r))  # a does equal qr
+    True
+    >>> r2 = np.linalg.qr(a, mode='r')
+    >>> r3 = np.linalg.qr(a, mode='economic')
+    >>> np.allclose(r, r2)  # mode='r' returns the same r as mode='full'
+    True
+    >>> # But only triu parts are guaranteed equal when mode='economic'
+    >>> np.allclose(r, np.triu(r3[:6,:6], k=0))
+    True
+
+    Example illustrating a common use of `qr`: solving of least squares
+    problems
+
+    What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for
+    the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points
+    and you'll see that it should be y0 = 0, m = 1.)  The answer is provided
+    by solving the over-determined matrix equation ``Ax = b``, where::
+
+      A = array([[0, 1], [1, 1], [1, 1], [2, 1]])
+      x = array([[y0], [m]])
+      b = array([[1], [0], [2], [1]])
+
+    If A = qr such that q is orthonormal (which is always possible via
+    Gram-Schmidt), then ``x = inv(r) * (q.T) * b``.  (In numpy practice,
+    however, we simply use `lstsq`.)
+
+    >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]])
+    >>> A
+    array([[0, 1],
+           [1, 1],
+           [1, 1],
+           [2, 1]])
+    >>> b = np.array([1, 0, 2, 1])
+    >>> q, r = LA.qr(A)
+    >>> p = np.dot(q.T, b)
+    >>> np.dot(LA.inv(r), p)
+    array([  1.1e-16,   1.0e+00])
+
+    """
+    if mode not in ('reduced', 'complete', 'r', 'raw'):
+        if mode in ('f', 'full'):
+            # 2013-04-01, 1.8
+            msg = "".join((
+                    "The 'full' option is deprecated in favor of 'reduced'.\n",
+                    "For backward compatibility let mode default."))
+            warnings.warn(msg, DeprecationWarning)
+            mode = 'reduced'
+        elif mode in ('e', 'economic'):
+            # 2013-04-01, 1.8
+            msg = "The 'economic' option is deprecated.",
+            warnings.warn(msg, DeprecationWarning)
+            mode = 'economic'
+        else:
+            raise ValueError("Unrecognized mode '%s'" % mode)
+
+    a, wrap = _makearray(a)
+    _assertRank2(a)
+    _assertNoEmpty2d(a)
+    m, n = a.shape
+    t, result_t = _commonType(a)
+    a = _fastCopyAndTranspose(t, a)
+    a = _to_native_byte_order(a)
+    mn = min(m, n)
+    tau = zeros((mn,), t)
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zgeqrf
+        routine_name = 'zgeqrf'
+    else:
+        lapack_routine = lapack_lite.dgeqrf
+        routine_name = 'dgeqrf'
+
+    # calculate optimal size of work data 'work'
+    lwork = 1
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, n, a, m, tau, work, -1, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # do qr decomposition
+    lwork = int(abs(work[0]))
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, n, a, m, tau, work, lwork, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # handle modes that don't return q
+    if mode == 'r':
+        r = _fastCopyAndTranspose(result_t, a[:, :mn])
+        return wrap(triu(r))
+
+    if mode == 'raw':
+        return a, tau
+
+    if mode == 'economic':
+        if t != result_t :
+            a = a.astype(result_t, copy=False)
+        return wrap(a.T)
+
+    #  generate q from a
+    if mode == 'complete' and m > n:
+        mc = m
+        q = empty((m, m), t)
+    else:
+        mc = mn
+        q = empty((n, m), t)
+    q[:n] = a
+
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zungqr
+        routine_name = 'zungqr'
+    else:
+        lapack_routine = lapack_lite.dorgqr
+        routine_name = 'dorgqr'
+
+    # determine optimal lwork
+    lwork = 1
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, mc, mn, q, m, tau, work, -1, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    # compute q
+    lwork = int(abs(work[0]))
+    work = zeros((lwork,), t)
+    results = lapack_routine(m, mc, mn, q, m, tau, work, lwork, 0)
+    if results['info'] != 0:
+        raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+
+    q = _fastCopyAndTranspose(result_t, q[:mc])
+    r = _fastCopyAndTranspose(result_t, a[:, :mc])
+
+    return wrap(q), wrap(triu(r))
+
+
+# Eigenvalues
+
+
+def eigvals(a):
+    """
+    Compute the eigenvalues of a general matrix.
+
+    Main difference between `eigvals` and `eig`: the eigenvectors aren't
+    returned.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        A complex- or real-valued matrix whose eigenvalues will be computed.
+
+    Returns
+    -------
+    w : (..., M,) ndarray
+        The eigenvalues, each repeated according to its multiplicity.
+        They are not necessarily ordered, nor are they necessarily
+        real for real matrices.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eig : eigenvalues and right eigenvectors of general arrays
+    eigvalsh : eigenvalues of symmetric or Hermitian arrays.
+    eigh : eigenvalues and eigenvectors of symmetric/Hermitian arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    This is implemented using the _geev LAPACK routines which compute
+    the eigenvalues and eigenvectors of general square arrays.
+
+    Examples
+    --------
+    Illustration, using the fact that the eigenvalues of a diagonal matrix
+    are its diagonal elements, that multiplying a matrix on the left
+    by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose
+    of `Q`), preserves the eigenvalues of the "middle" matrix.  In other words,
+    if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as
+    ``A``:
+
+    >>> from numpy import linalg as LA
+    >>> x = np.random.random()
+    >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]])
+    >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :])
+    (1.0, 1.0, 0.0)
+
+    Now multiply a diagonal matrix by Q on one side and by Q.T on the other:
+
+    >>> D = np.diag((-1,1))
+    >>> LA.eigvals(D)
+    array([-1.,  1.])
+    >>> A = np.dot(Q, D)
+    >>> A = np.dot(A, Q.T)
+    >>> LA.eigvals(A)
+    array([ 1., -1.])
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    _assertFinite(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    signature = 'D->D' if isComplexType(t) else 'd->D'
+    w = _umath_linalg.eigvals(a, signature=signature, extobj=extobj)
+
+    if not isComplexType(t):
+        if all(w.imag == 0):
+            w = w.real
+            result_t = _realType(result_t)
+        else:
+            result_t = _complexType(result_t)
+
+    return w.astype(result_t, copy=False)
+
+def eigvalsh(a, UPLO='L'):
+    """
+    Compute the eigenvalues of a Hermitian or real symmetric matrix.
+
+    Main difference from eigh: the eigenvectors are not computed.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        A complex- or real-valued matrix whose eigenvalues are to be
+        computed.
+    UPLO : {'L', 'U'}, optional
+        Same as `lower`, with 'L' for lower and 'U' for upper triangular.
+        Deprecated.
+
+    Returns
+    -------
+    w : (..., M,) ndarray
+        The eigenvalues in ascending order, each repeated according to
+        its multiplicity.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigh : eigenvalues and eigenvectors of symmetric/Hermitian arrays.
+    eigvals : eigenvalues of general real or complex arrays.
+    eig : eigenvalues and right eigenvectors of general real or complex
+          arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The eigenvalues are computed using LAPACK routines _syevd, _heevd
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, -2j], [2j, 5]])
+    >>> LA.eigvalsh(a)
+    array([ 0.17157288,  5.82842712])
+
+    """
+    UPLO = UPLO.upper()
+    if UPLO not in ('L', 'U'):
+        raise ValueError("UPLO argument must be 'L' or 'U'")
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    if UPLO == 'L':
+        gufunc = _umath_linalg.eigvalsh_lo
+    else:
+        gufunc = _umath_linalg.eigvalsh_up
+
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->d' if isComplexType(t) else 'd->d'
+    w = gufunc(a, signature=signature, extobj=extobj)
+    return w.astype(_realType(result_t), copy=False)
+
+def _convertarray(a):
+    t, result_t = _commonType(a)
+    a = _fastCT(a.astype(t))
+    return a, t, result_t
+
+
+# Eigenvectors
+
+
+def eig(a):
+    """
+    Compute the eigenvalues and right eigenvectors of a square array.
+
+    Parameters
+    ----------
+    a : (..., M, M) array
+        Matrices for which the eigenvalues and right eigenvectors will
+        be computed
+
+    Returns
+    -------
+    w : (..., M) array
+        The eigenvalues, each repeated according to its multiplicity.
+        The eigenvalues are not necessarily ordered. The resulting
+        array will be of complex type, unless the imaginary part is
+        zero in which case it will be cast to a real type. When `a`
+        is real the resulting eigenvalues will be real (0 imaginary
+        part) or occur in conjugate pairs
+
+    v : (..., M, M) array
+        The normalized (unit "length") eigenvectors, such that the
+        column ``v[:,i]`` is the eigenvector corresponding to the
+        eigenvalue ``w[i]``.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigvals : eigenvalues of a non-symmetric array.
+
+    eigh : eigenvalues and eigenvectors of a symmetric or Hermitian
+           (conjugate symmetric) array.
+
+    eigvalsh : eigenvalues of a symmetric or Hermitian (conjugate symmetric)
+               array.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    This is implemented using the _geev LAPACK routines which compute
+    the eigenvalues and eigenvectors of general square arrays.
+
+    The number `w` is an eigenvalue of `a` if there exists a vector
+    `v` such that ``dot(a,v) = w * v``. Thus, the arrays `a`, `w`, and
+    `v` satisfy the equations ``dot(a[:,:], v[:,i]) = w[i] * v[:,i]``
+    for :math:`i \\in \\{0,...,M-1\\}`.
+
+    The array `v` of eigenvectors may not be of maximum rank, that is, some
+    of the columns may be linearly dependent, although round-off error may
+    obscure that fact. If the eigenvalues are all different, then theoretically
+    the eigenvectors are linearly independent. Likewise, the (complex-valued)
+    matrix of eigenvectors `v` is unitary if the matrix `a` is normal, i.e.,
+    if ``dot(a, a.H) = dot(a.H, a)``, where `a.H` denotes the conjugate
+    transpose of `a`.
+
+    Finally, it is emphasized that `v` consists of the *right* (as in
+    right-hand side) eigenvectors of `a`.  A vector `y` satisfying
+    ``dot(y.T, a) = z * y.T`` for some number `z` is called a *left*
+    eigenvector of `a`, and, in general, the left and right eigenvectors
+    of a matrix are not necessarily the (perhaps conjugate) transposes
+    of each other.
+
+    References
+    ----------
+    G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL,
+    Academic Press, Inc., 1980, Various pp.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+
+    (Almost) trivial example with real e-values and e-vectors.
+
+    >>> w, v = LA.eig(np.diag((1, 2, 3)))
+    >>> w; v
+    array([ 1.,  2.,  3.])
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+
+    Real matrix possessing complex e-values and e-vectors; note that the
+    e-values are complex conjugates of each other.
+
+    >>> w, v = LA.eig(np.array([[1, -1], [1, 1]]))
+    >>> w; v
+    array([ 1. + 1.j,  1. - 1.j])
+    array([[ 0.70710678+0.j        ,  0.70710678+0.j        ],
+           [ 0.00000000-0.70710678j,  0.00000000+0.70710678j]])
+
+    Complex-valued matrix with real e-values (but complex-valued e-vectors);
+    note that a.conj().T = a, i.e., a is Hermitian.
+
+    >>> a = np.array([[1, 1j], [-1j, 1]])
+    >>> w, v = LA.eig(a)
+    >>> w; v
+    array([  2.00000000e+00+0.j,   5.98651912e-36+0.j]) # i.e., {2, 0}
+    array([[ 0.00000000+0.70710678j,  0.70710678+0.j        ],
+           [ 0.70710678+0.j        ,  0.00000000+0.70710678j]])
+
+    Be careful about round-off error!
+
+    >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]])
+    >>> # Theor. e-values are 1 +/- 1e-9
+    >>> w, v = LA.eig(a)
+    >>> w; v
+    array([ 1.,  1.])
+    array([[ 1.,  0.],
+           [ 0.,  1.]])
+
+    """
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    _assertFinite(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    signature = 'D->DD' if isComplexType(t) else 'd->DD'
+    w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj)
+
+    if not isComplexType(t) and all(w.imag == 0.0):
+        w = w.real
+        vt = vt.real
+        result_t = _realType(result_t)
+    else:
+        result_t = _complexType(result_t)
+
+    vt = vt.astype(result_t, copy=False)
+    return w.astype(result_t, copy=False), wrap(vt)
+
+
+def eigh(a, UPLO='L'):
+    """
+    Return the eigenvalues and eigenvectors of a Hermitian or symmetric matrix.
+
+    Returns two objects, a 1-D array containing the eigenvalues of `a`, and
+    a 2-D square array or matrix (depending on the input type) of the
+    corresponding eigenvectors (in columns).
+
+    Parameters
+    ----------
+    a : (..., M, M) array
+        Hermitian/Symmetric matrices whose eigenvalues and
+        eigenvectors are to be computed.
+    UPLO : {'L', 'U'}, optional
+        Specifies whether the calculation is done with the lower triangular
+        part of `a` ('L', default) or the upper triangular part ('U').
+
+    Returns
+    -------
+    w : (..., M) ndarray
+        The eigenvalues in ascending order, each repeated according to
+        its multiplicity.
+    v : {(..., M, M) ndarray, (..., M, M) matrix}
+        The column ``v[:, i]`` is the normalized eigenvector corresponding
+        to the eigenvalue ``w[i]``.  Will return a matrix object if `a` is
+        a matrix object.
+
+    Raises
+    ------
+    LinAlgError
+        If the eigenvalue computation does not converge.
+
+    See Also
+    --------
+    eigvalsh : eigenvalues of symmetric or Hermitian arrays.
+    eig : eigenvalues and right eigenvectors for non-symmetric arrays.
+    eigvals : eigenvalues of non-symmetric arrays.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The eigenvalues/eigenvectors are computed using LAPACK routines _syevd,
+    _heevd
+
+    The eigenvalues of real symmetric or complex Hermitian matrices are
+    always real. [1]_ The array `v` of (column) eigenvectors is unitary
+    and `a`, `w`, and `v` satisfy the equations
+    ``dot(a, v[:, i]) = w[i] * v[:, i]``.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pg. 222.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, -2j], [2j, 5]])
+    >>> a
+    array([[ 1.+0.j,  0.-2.j],
+           [ 0.+2.j,  5.+0.j]])
+    >>> w, v = LA.eigh(a)
+    >>> w; v
+    array([ 0.17157288,  5.82842712])
+    array([[-0.92387953+0.j        , -0.38268343+0.j        ],
+           [ 0.00000000+0.38268343j,  0.00000000-0.92387953j]])
+
+    >>> np.dot(a, v[:, 0]) - w[0] * v[:, 0] # verify 1st e-val/vec pair
+    array([2.77555756e-17 + 0.j, 0. + 1.38777878e-16j])
+    >>> np.dot(a, v[:, 1]) - w[1] * v[:, 1] # verify 2nd e-val/vec pair
+    array([ 0.+0.j,  0.+0.j])
+
+    >>> A = np.matrix(a) # what happens if input is a matrix object
+    >>> A
+    matrix([[ 1.+0.j,  0.-2.j],
+            [ 0.+2.j,  5.+0.j]])
+    >>> w, v = LA.eigh(A)
+    >>> w; v
+    array([ 0.17157288,  5.82842712])
+    matrix([[-0.92387953+0.j        , -0.38268343+0.j        ],
+            [ 0.00000000+0.38268343j,  0.00000000-0.92387953j]])
+
+    """
+    UPLO = UPLO.upper()
+    if UPLO not in ('L', 'U'):
+        raise ValueError("UPLO argument must be 'L' or 'U'")
+
+    a, wrap = _makearray(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(
+        _raise_linalgerror_eigenvalues_nonconvergence)
+    if UPLO == 'L':
+        gufunc = _umath_linalg.eigh_lo
+    else:
+        gufunc = _umath_linalg.eigh_up
+
+    signature = 'D->dD' if isComplexType(t) else 'd->dd'
+    w, vt = gufunc(a, signature=signature, extobj=extobj)
+    w = w.astype(_realType(result_t), copy=False)
+    vt = vt.astype(result_t, copy=False)
+    return w, wrap(vt)
+
+
+# Singular value decomposition
+
+def svd(a, full_matrices=1, compute_uv=1):
+    """
+    Singular Value Decomposition.
+
+    Factors the matrix `a` as ``u * np.diag(s) * v``, where `u` and `v`
+    are unitary and `s` is a 1-d array of `a`'s singular values.
+
+    Parameters
+    ----------
+    a : (..., M, N) array_like
+        A real or complex matrix of shape (`M`, `N`) .
+    full_matrices : bool, optional
+        If True (default), `u` and `v` have the shapes (`M`, `M`) and
+        (`N`, `N`), respectively.  Otherwise, the shapes are (`M`, `K`)
+        and (`K`, `N`), respectively, where `K` = min(`M`, `N`).
+    compute_uv : bool, optional
+        Whether or not to compute `u` and `v` in addition to `s`.  True
+        by default.
+
+    Returns
+    -------
+    u : { (..., M, M), (..., M, K) } array
+        Unitary matrices. The actual shape depends on the value of
+        ``full_matrices``. Only returned when ``compute_uv`` is True.
+    s : (..., K) array
+        The singular values for every matrix, sorted in descending order.
+    v : { (..., N, N), (..., K, N) } array
+        Unitary matrices. The actual shape depends on the value of
+        ``full_matrices``. Only returned when ``compute_uv`` is True.
+
+    Raises
+    ------
+    LinAlgError
+        If SVD computation does not converge.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The decomposition is performed using LAPACK routine _gesdd
+
+    The SVD is commonly written as ``a = U S V.H``.  The `v` returned
+    by this function is ``V.H`` and ``u = U``.
+
+    If ``U`` is a unitary matrix, it means that it
+    satisfies ``U.H = inv(U)``.
+
+    The rows of `v` are the eigenvectors of ``a.H a``. The columns
+    of `u` are the eigenvectors of ``a a.H``.  For row ``i`` in
+    `v` and column ``i`` in `u`, the corresponding eigenvalue is
+    ``s[i]**2``.
+
+    If `a` is a `matrix` object (as opposed to an `ndarray`), then so
+    are all the return values.
+
+    Examples
+    --------
+    >>> a = np.random.randn(9, 6) + 1j*np.random.randn(9, 6)
+
+    Reconstruction based on full SVD:
+
+    >>> U, s, V = np.linalg.svd(a, full_matrices=True)
+    >>> U.shape, V.shape, s.shape
+    ((9, 9), (6, 6), (6,))
+    >>> S = np.zeros((9, 6), dtype=complex)
+    >>> S[:6, :6] = np.diag(s)
+    >>> np.allclose(a, np.dot(U, np.dot(S, V)))
+    True
+
+    Reconstruction based on reduced SVD:
+
+    >>> U, s, V = np.linalg.svd(a, full_matrices=False)
+    >>> U.shape, V.shape, s.shape
+    ((9, 6), (6, 6), (6,))
+    >>> S = np.diag(s)
+    >>> np.allclose(a, np.dot(U, np.dot(S, V)))
+    True
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    t, result_t = _commonType(a)
+
+    extobj = get_linalg_error_extobj(_raise_linalgerror_svd_nonconvergence)
+
+    m = a.shape[-2]
+    n = a.shape[-1]
+    if compute_uv:
+        if full_matrices:
+            if m < n:
+                gufunc = _umath_linalg.svd_m_f
+            else:
+                gufunc = _umath_linalg.svd_n_f
+        else:
+            if m < n:
+                gufunc = _umath_linalg.svd_m_s
+            else:
+                gufunc = _umath_linalg.svd_n_s
+
+        signature = 'D->DdD' if isComplexType(t) else 'd->ddd'
+        u, s, vt = gufunc(a, signature=signature, extobj=extobj)
+        u = u.astype(result_t, copy=False)
+        s = s.astype(_realType(result_t), copy=False)
+        vt = vt.astype(result_t, copy=False)
+        return wrap(u), s, wrap(vt)
+    else:
+        if m < n:
+            gufunc = _umath_linalg.svd_m
+        else:
+            gufunc = _umath_linalg.svd_n
+
+        signature = 'D->d' if isComplexType(t) else 'd->d'
+        s = gufunc(a, signature=signature, extobj=extobj)
+        s = s.astype(_realType(result_t), copy=False)
+        return s
+
+def cond(x, p=None):
+    """
+    Compute the condition number of a matrix.
+
+    This function is capable of returning the condition number using
+    one of seven different norms, depending on the value of `p` (see
+    Parameters below).
+
+    Parameters
+    ----------
+    x : (..., M, N) array_like
+        The matrix whose condition number is sought.
+    p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional
+        Order of the norm:
+
+        =====  ============================
+        p      norm for matrices
+        =====  ============================
+        None   2-norm, computed directly using the ``SVD``
+        'fro'  Frobenius norm
+        inf    max(sum(abs(x), axis=1))
+        -inf   min(sum(abs(x), axis=1))
+        1      max(sum(abs(x), axis=0))
+        -1     min(sum(abs(x), axis=0))
+        2      2-norm (largest sing. value)
+        -2     smallest singular value
+        =====  ============================
+
+        inf means the numpy.inf object, and the Frobenius norm is
+        the root-of-sum-of-squares norm.
+
+    Returns
+    -------
+    c : {float, inf}
+        The condition number of the matrix. May be infinite.
+
+    See Also
+    --------
+    numpy.linalg.norm
+
+    Notes
+    -----
+    The condition number of `x` is defined as the norm of `x` times the
+    norm of the inverse of `x` [1]_; the norm can be the usual L2-norm
+    (root-of-sum-of-squares) or one of a number of other matrix norms.
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL,
+           Academic Press, Inc., 1980, pg. 285.
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]])
+    >>> a
+    array([[ 1,  0, -1],
+           [ 0,  1,  0],
+           [ 1,  0,  1]])
+    >>> LA.cond(a)
+    1.4142135623730951
+    >>> LA.cond(a, 'fro')
+    3.1622776601683795
+    >>> LA.cond(a, np.inf)
+    2.0
+    >>> LA.cond(a, -np.inf)
+    1.0
+    >>> LA.cond(a, 1)
+    2.0
+    >>> LA.cond(a, -1)
+    1.0
+    >>> LA.cond(a, 2)
+    1.4142135623730951
+    >>> LA.cond(a, -2)
+    0.70710678118654746
+    >>> min(LA.svd(a, compute_uv=0))*min(LA.svd(LA.inv(a), compute_uv=0))
+    0.70710678118654746
+
+    """
+    x = asarray(x)  # in case we have a matrix
+    if p is None:
+        s = svd(x, compute_uv=False)
+        return s[..., 0]/s[..., -1]
+    else:
+        return norm(x, p, axis=(-2, -1)) * norm(inv(x), p, axis=(-2, -1))
+
+
+def matrix_rank(M, tol=None):
+    """
+    Return matrix rank of array using SVD method
+
+    Rank of the array is the number of SVD singular values of the array that are
+    greater than `tol`.
+
+    Parameters
+    ----------
+    M : {(M,), (M, N)} array_like
+        array of <=2 dimensions
+    tol : {None, float}, optional
+       threshold below which SVD values are considered zero. If `tol` is
+       None, and ``S`` is an array with singular values for `M`, and
+       ``eps`` is the epsilon value for datatype of ``S``, then `tol` is
+       set to ``S.max() * max(M.shape) * eps``.
+
+    Notes
+    -----
+    The default threshold to detect rank deficiency is a test on the magnitude
+    of the singular values of `M`.  By default, we identify singular values less
+    than ``S.max() * max(M.shape) * eps`` as indicating rank deficiency (with
+    the symbols defined above). This is the algorithm MATLAB uses [1].  It also
+    appears in *Numerical recipes* in the discussion of SVD solutions for linear
+    least squares [2].
+
+    This default threshold is designed to detect rank deficiency accounting for
+    the numerical errors of the SVD computation.  Imagine that there is a column
+    in `M` that is an exact (in floating point) linear combination of other
+    columns in `M`. Computing the SVD on `M` will not produce a singular value
+    exactly equal to 0 in general: any difference of the smallest SVD value from
+    0 will be caused by numerical imprecision in the calculation of the SVD.
+    Our threshold for small SVD values takes this numerical imprecision into
+    account, and the default threshold will detect such numerical rank
+    deficiency.  The threshold may declare a matrix `M` rank deficient even if
+    the linear combination of some columns of `M` is not exactly equal to
+    another column of `M` but only numerically very close to another column of
+    `M`.
+
+    We chose our default threshold because it is in wide use.  Other thresholds
+    are possible.  For example, elsewhere in the 2007 edition of *Numerical
+    recipes* there is an alternative threshold of ``S.max() *
+    np.finfo(M.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
+    this threshold as being based on "expected roundoff error" (p 71).
+
+    The thresholds above deal with floating point roundoff error in the
+    calculation of the SVD.  However, you may have more information about the
+    sources of error in `M` that would make you consider other tolerance values
+    to detect *effective* rank deficiency.  The most useful measure of the
+    tolerance depends on the operations you intend to use on your matrix.  For
+    example, if your data come from uncertain measurements with uncertainties
+    greater than floating point epsilon, choosing a tolerance near that
+    uncertainty may be preferable.  The tolerance may be absolute if the
+    uncertainties are absolute rather than relative.
+
+    References
+    ----------
+    .. [1] MATLAB reference documention, "Rank"
+           http://www.mathworks.com/help/techdoc/ref/rank.html
+    .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery,
+           "Numerical Recipes (3rd edition)", Cambridge University Press, 2007,
+           page 795.
+
+    Examples
+    --------
+    >>> from numpy.linalg import matrix_rank
+    >>> matrix_rank(np.eye(4)) # Full rank matrix
+    4
+    >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
+    >>> matrix_rank(I)
+    3
+    >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
+    1
+    >>> matrix_rank(np.zeros((4,)))
+    0
+    """
+    M = asarray(M)
+    if M.ndim > 2:
+        raise TypeError('array should have 2 or fewer dimensions')
+    if M.ndim < 2:
+        return int(not all(M==0))
+    S = svd(M, compute_uv=False)
+    if tol is None:
+        tol = S.max() * max(M.shape) * finfo(S.dtype).eps
+    return sum(S > tol)
+
+
+# Generalized inverse
+
+def pinv(a, rcond=1e-15 ):
+    """
+    Compute the (Moore-Penrose) pseudo-inverse of a matrix.
+
+    Calculate the generalized inverse of a matrix using its
+    singular-value decomposition (SVD) and including all
+    *large* singular values.
+
+    Parameters
+    ----------
+    a : (M, N) array_like
+      Matrix to be pseudo-inverted.
+    rcond : float
+      Cutoff for small singular values.
+      Singular values smaller (in modulus) than
+      `rcond` * largest_singular_value (again, in modulus)
+      are set to zero.
+
+    Returns
+    -------
+    B : (N, M) ndarray
+      The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so
+      is `B`.
+
+    Raises
+    ------
+    LinAlgError
+      If the SVD computation does not converge.
+
+    Notes
+    -----
+    The pseudo-inverse of a matrix A, denoted :math:`A^+`, is
+    defined as: "the matrix that 'solves' [the least-squares problem]
+    :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then
+    :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`.
+
+    It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular
+    value decomposition of A, then
+    :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are
+    orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting
+    of A's so-called singular values, (followed, typically, by
+    zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix
+    consisting of the reciprocals of A's singular values
+    (again, followed by zeros). [1]_
+
+    References
+    ----------
+    .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando,
+           FL, Academic Press, Inc., 1980, pp. 139-142.
+
+    Examples
+    --------
+    The following example checks that ``a * a+ * a == a`` and
+    ``a+ * a * a+ == a+``:
+
+    >>> a = np.random.randn(9, 6)
+    >>> B = np.linalg.pinv(a)
+    >>> np.allclose(a, np.dot(a, np.dot(B, a)))
+    True
+    >>> np.allclose(B, np.dot(B, np.dot(a, B)))
+    True
+
+    """
+    a, wrap = _makearray(a)
+    _assertNoEmpty2d(a)
+    a = a.conjugate()
+    u, s, vt = svd(a, 0)
+    m = u.shape[0]
+    n = vt.shape[1]
+    cutoff = rcond*maximum.reduce(s)
+    for i in range(min(n, m)):
+        if s[i] > cutoff:
+            s[i] = 1./s[i]
+        else:
+            s[i] = 0.
+    res = dot(transpose(vt), multiply(s[:, newaxis], transpose(u)))
+    return wrap(res)
+
+# Determinant
+
+def slogdet(a):
+    """
+    Compute the sign and (natural) logarithm of the determinant of an array.
+
+    If an array has a very small or very large determinant, then a call to
+    `det` may overflow or underflow. This routine is more robust against such
+    issues, because it computes the logarithm of the determinant rather than
+    the determinant itself.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Input array, has to be a square 2-D array.
+
+    Returns
+    -------
+    sign : (...) array_like
+        A number representing the sign of the determinant. For a real matrix,
+        this is 1, 0, or -1. For a complex matrix, this is a complex number
+        with absolute value 1 (i.e., it is on the unit circle), or else 0.
+    logdet : (...) array_like
+        The natural log of the absolute value of the determinant.
+
+    If the determinant is zero, then `sign` will be 0 and `logdet` will be
+    -Inf. In all cases, the determinant is equal to ``sign * np.exp(logdet)``.
+
+    See Also
+    --------
+    det
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    .. versionadded:: 1.6.0.
+
+    The determinant is computed via LU factorization using the LAPACK
+    routine z/dgetrf.
+
+
+    Examples
+    --------
+    The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``:
+
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> (sign, logdet) = np.linalg.slogdet(a)
+    >>> (sign, logdet)
+    (-1, 0.69314718055994529)
+    >>> sign * np.exp(logdet)
+    -2.0
+
+    Computing log-determinants for a stack of matrices:
+
+    >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
+    >>> a.shape
+    (3, 2, 2)
+    >>> sign, logdet = np.linalg.slogdet(a)
+    >>> (sign, logdet)
+    (array([-1., -1., -1.]), array([ 0.69314718,  1.09861229,  2.07944154]))
+    >>> sign * np.exp(logdet)
+    array([-2., -3., -8.])
+
+    This routine succeeds where ordinary `det` does not:
+
+    >>> np.linalg.det(np.eye(500) * 0.1)
+    0.0
+    >>> np.linalg.slogdet(np.eye(500) * 0.1)
+    (1, -1151.2925464970228)
+
+    """
+    a = asarray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    real_t = _realType(result_t)
+    signature = 'D->Dd' if isComplexType(t) else 'd->dd'
+    sign, logdet = _umath_linalg.slogdet(a, signature=signature)
+    if isscalar(sign):
+        sign = sign.astype(result_t)
+    else:
+        sign = sign.astype(result_t, copy=False)
+    if isscalar(logdet):
+        logdet = logdet.astype(real_t)
+    else:
+        logdet = logdet.astype(real_t, copy=False)
+    return sign, logdet
+
+def det(a):
+    """
+    Compute the determinant of an array.
+
+    Parameters
+    ----------
+    a : (..., M, M) array_like
+        Input array to compute determinants for.
+
+    Returns
+    -------
+    det : (...) array_like
+        Determinant of `a`.
+
+    See Also
+    --------
+    slogdet : Another way to representing the determinant, more suitable
+      for large matrices where underflow/overflow may occur.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.8.0
+
+    Broadcasting rules apply, see the `numpy.linalg` documentation for
+    details.
+
+    The determinant is computed via LU factorization using the LAPACK
+    routine z/dgetrf.
+
+    Examples
+    --------
+    The determinant of a 2-D array [[a, b], [c, d]] is ad - bc:
+
+    >>> a = np.array([[1, 2], [3, 4]])
+    >>> np.linalg.det(a)
+    -2.0
+
+    Computing determinants for a stack of matrices:
+
+    >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ])
+    >>> a.shape
+    (3, 2, 2)
+    >>> np.linalg.det(a)
+    array([-2., -3., -8.])
+
+    """
+    a = asarray(a)
+    _assertNoEmpty2d(a)
+    _assertRankAtLeast2(a)
+    _assertNdSquareness(a)
+    t, result_t = _commonType(a)
+    signature = 'D->D' if isComplexType(t) else 'd->d'
+    r = _umath_linalg.det(a, signature=signature)
+    if isscalar(r):
+        r = r.astype(result_t)
+    else:
+        r = r.astype(result_t, copy=False)
+    return r
+
+# Linear Least Squares
+
+def lstsq(a, b, rcond=-1):
+    """
+    Return the least-squares solution to a linear matrix equation.
+
+    Solves the equation `a x = b` by computing a vector `x` that
+    minimizes the Euclidean 2-norm `|| b - a x ||^2`.  The equation may
+    be under-, well-, or over- determined (i.e., the number of
+    linearly independent rows of `a` can be less than, equal to, or
+    greater than its number of linearly independent columns).  If `a`
+    is square and of full rank, then `x` (but for round-off error) is
+    the "exact" solution of the equation.
+
+    Parameters
+    ----------
+    a : (M, N) array_like
+        "Coefficient" matrix.
+    b : {(M,), (M, K)} array_like
+        Ordinate or "dependent variable" values. If `b` is two-dimensional,
+        the least-squares solution is calculated for each of the `K` columns
+        of `b`.
+    rcond : float, optional
+        Cut-off ratio for small singular values of `a`.
+        Singular values are set to zero if they are smaller than `rcond`
+        times the largest singular value of `a`.
+
+    Returns
+    -------
+    x : {(N,), (N, K)} ndarray
+        Least-squares solution. If `b` is two-dimensional,
+        the solutions are in the `K` columns of `x`.
+    residuals : {(), (1,), (K,)} ndarray
+        Sums of residuals; squared Euclidean 2-norm for each column in
+        ``b - a*x``.
+        If the rank of `a` is < N or M <= N, this is an empty array.
+        If `b` is 1-dimensional, this is a (1,) shape array.
+        Otherwise the shape is (K,).
+    rank : int
+        Rank of matrix `a`.
+    s : (min(M, N),) ndarray
+        Singular values of `a`.
+
+    Raises
+    ------
+    LinAlgError
+        If computation does not converge.
+
+    Notes
+    -----
+    If `b` is a matrix, then all array results are returned as matrices.
+
+    Examples
+    --------
+    Fit a line, ``y = mx + c``, through some noisy data-points:
+
+    >>> x = np.array([0, 1, 2, 3])
+    >>> y = np.array([-1, 0.2, 0.9, 2.1])
+
+    By examining the coefficients, we see that the line should have a
+    gradient of roughly 1 and cut the y-axis at, more or less, -1.
+
+    We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]``
+    and ``p = [[m], [c]]``.  Now use `lstsq` to solve for `p`:
+
+    >>> A = np.vstack([x, np.ones(len(x))]).T
+    >>> A
+    array([[ 0.,  1.],
+           [ 1.,  1.],
+           [ 2.,  1.],
+           [ 3.,  1.]])
+
+    >>> m, c = np.linalg.lstsq(A, y)[0]
+    >>> print(m, c)
+    1.0 -0.95
+
+    Plot the data along with the fitted line:
+
+    >>> import matplotlib.pyplot as plt
+    >>> plt.plot(x, y, 'o', label='Original data', markersize=10)
+    >>> plt.plot(x, m*x + c, 'r', label='Fitted line')
+    >>> plt.legend()
+    >>> plt.show()
+
+    """
+    import math
+    a, _ = _makearray(a)
+    b, wrap = _makearray(b)
+    is_1d = len(b.shape) == 1
+    if is_1d:
+        b = b[:, newaxis]
+    _assertRank2(a, b)
+    m  = a.shape[0]
+    n  = a.shape[1]
+    n_rhs = b.shape[1]
+    ldb = max(n, m)
+    if m != b.shape[0]:
+        raise LinAlgError('Incompatible dimensions')
+    t, result_t = _commonType(a, b)
+    result_real_t = _realType(result_t)
+    real_t = _linalgRealType(t)
+    bstar = zeros((ldb, n_rhs), t)
+    bstar[:b.shape[0], :n_rhs] = b.copy()
+    a, bstar = _fastCopyAndTranspose(t, a, bstar)
+    a, bstar = _to_native_byte_order(a, bstar)
+    s = zeros((min(m, n),), real_t)
+    nlvl = max( 0, int( math.log( float(min(m, n))/2. ) ) + 1 )
+    iwork = zeros((3*min(m, n)*nlvl+11*min(m, n),), fortran_int)
+    if isComplexType(t):
+        lapack_routine = lapack_lite.zgelsd
+        lwork = 1
+        rwork = zeros((lwork,), real_t)
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, -1, rwork, iwork, 0)
+        lwork = int(abs(work[0]))
+        rwork = zeros((lwork,), real_t)
+        a_real = zeros((m, n), real_t)
+        bstar_real = zeros((ldb, n_rhs,), real_t)
+        results = lapack_lite.dgelsd(m, n, n_rhs, a_real, m,
+                                     bstar_real, ldb, s, rcond,
+                                     0, rwork, -1, iwork, 0)
+        lrwork = int(rwork[0])
+        work = zeros((lwork,), t)
+        rwork = zeros((lrwork,), real_t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, lwork, rwork, iwork, 0)
+    else:
+        lapack_routine = lapack_lite.dgelsd
+        lwork = 1
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, -1, iwork, 0)
+        lwork = int(work[0])
+        work = zeros((lwork,), t)
+        results = lapack_routine(m, n, n_rhs, a, m, bstar, ldb, s, rcond,
+                                 0, work, lwork, iwork, 0)
+    if results['info'] > 0:
+        raise LinAlgError('SVD did not converge in Linear Least Squares')
+    resids = array([], result_real_t)
+    if is_1d:
+        x = array(ravel(bstar)[:n], dtype=result_t, copy=True)
+        if results['rank'] == n and m > n:
+            if isComplexType(t):
+                resids = array([sum(abs(ravel(bstar)[n:])**2)],
+                               dtype=result_real_t)
+            else:
+                resids = array([sum((ravel(bstar)[n:])**2)],
+                               dtype=result_real_t)
+    else:
+        x = array(transpose(bstar)[:n,:], dtype=result_t, copy=True)
+        if results['rank'] == n and m > n:
+            if isComplexType(t):
+                resids = sum(abs(transpose(bstar)[n:,:])**2, axis=0).astype(
+                    result_real_t, copy=False)
+            else:
+                resids = sum((transpose(bstar)[n:,:])**2, axis=0).astype(
+                    result_real_t, copy=False)
+
+    st = s[:min(n, m)].astype(result_real_t, copy=True)
+    return wrap(x), wrap(resids), results['rank'], st
+
+
+def _multi_svd_norm(x, row_axis, col_axis, op):
+    """Compute a function of the singular values of the 2-D matrices in `x`.
+
+    This is a private utility function used by numpy.linalg.norm().
+
+    Parameters
+    ----------
+    x : ndarray
+    row_axis, col_axis : int
+        The axes of `x` that hold the 2-D matrices.
+    op : callable
+        This should be either numpy.amin or numpy.amax or numpy.sum.
+
+    Returns
+    -------
+    result : float or ndarray
+        If `x` is 2-D, the return values is a float.
+        Otherwise, it is an array with ``x.ndim - 2`` dimensions.
+        The return values are either the minimum or maximum or sum of the
+        singular values of the matrices, depending on whether `op`
+        is `numpy.amin` or `numpy.amax` or `numpy.sum`.
+
+    """
+    if row_axis > col_axis:
+        row_axis -= 1
+    y = rollaxis(rollaxis(x, col_axis, x.ndim), row_axis, -1)
+    result = op(svd(y, compute_uv=0), axis=-1)
+    return result
+
+
+def norm(x, ord=None, axis=None, keepdims=False):
+    """
+    Matrix or vector norm.
+
+    This function is able to return one of eight different matrix norms,
+    or one of an infinite number of vector norms (described below), depending
+    on the value of the ``ord`` parameter.
+
+    Parameters
+    ----------
+    x : array_like
+        Input array.  If `axis` is None, `x` must be 1-D or 2-D.
+    ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional
+        Order of the norm (see table under ``Notes``). inf means numpy's
+        `inf` object.
+    axis : {int, 2-tuple of ints, None}, optional
+        If `axis` is an integer, it specifies the axis of `x` along which to
+        compute the vector norms.  If `axis` is a 2-tuple, it specifies the
+        axes that hold 2-D matrices, and the matrix norms of these matrices
+        are computed.  If `axis` is None then either a vector norm (when `x`
+        is 1-D) or a matrix norm (when `x` is 2-D) is returned.
+    keepdims : bool, optional
+        If this is set to True, the axes which are normed over are left in the
+        result as dimensions with size one.  With this option the result will
+        broadcast correctly against the original `x`.
+
+        .. versionadded:: 1.10.0
+
+    Returns
+    -------
+    n : float or ndarray
+        Norm of the matrix or vector(s).
+
+    Notes
+    -----
+    For values of ``ord <= 0``, the result is, strictly speaking, not a
+    mathematical 'norm', but it may still be useful for various numerical
+    purposes.
+
+    The following norms can be calculated:
+
+    =====  ============================  ==========================
+    ord    norm for matrices             norm for vectors
+    =====  ============================  ==========================
+    None   Frobenius norm                2-norm
+    'fro'  Frobenius norm                --
+    'nuc'  nuclear norm                  --
+    inf    max(sum(abs(x), axis=1))      max(abs(x))
+    -inf   min(sum(abs(x), axis=1))      min(abs(x))
+    0      --                            sum(x != 0)
+    1      max(sum(abs(x), axis=0))      as below
+    -1     min(sum(abs(x), axis=0))      as below
+    2      2-norm (largest sing. value)  as below
+    -2     smallest singular value       as below
+    other  --                            sum(abs(x)**ord)**(1./ord)
+    =====  ============================  ==========================
+
+    The Frobenius norm is given by [1]_:
+
+        :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`
+
+    The nuclear norm is the sum of the singular values.
+
+    References
+    ----------
+    .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
+           Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> a = np.arange(9) - 4
+    >>> a
+    array([-4, -3, -2, -1,  0,  1,  2,  3,  4])
+    >>> b = a.reshape((3, 3))
+    >>> b
+    array([[-4, -3, -2],
+           [-1,  0,  1],
+           [ 2,  3,  4]])
+
+    >>> LA.norm(a)
+    7.745966692414834
+    >>> LA.norm(b)
+    7.745966692414834
+    >>> LA.norm(b, 'fro')
+    7.745966692414834
+    >>> LA.norm(a, np.inf)
+    4.0
+    >>> LA.norm(b, np.inf)
+    9.0
+    >>> LA.norm(a, -np.inf)
+    0.0
+    >>> LA.norm(b, -np.inf)
+    2.0
+
+    >>> LA.norm(a, 1)
+    20.0
+    >>> LA.norm(b, 1)
+    7.0
+    >>> LA.norm(a, -1)
+    -4.6566128774142013e-010
+    >>> LA.norm(b, -1)
+    6.0
+    >>> LA.norm(a, 2)
+    7.745966692414834
+    >>> LA.norm(b, 2)
+    7.3484692283495345
+
+    >>> LA.norm(a, -2)
+    nan
+    >>> LA.norm(b, -2)
+    1.8570331885190563e-016
+    >>> LA.norm(a, 3)
+    5.8480354764257312
+    >>> LA.norm(a, -3)
+    nan
+
+    Using the `axis` argument to compute vector norms:
+
+    >>> c = np.array([[ 1, 2, 3],
+    ...               [-1, 1, 4]])
+    >>> LA.norm(c, axis=0)
+    array([ 1.41421356,  2.23606798,  5.        ])
+    >>> LA.norm(c, axis=1)
+    array([ 3.74165739,  4.24264069])
+    >>> LA.norm(c, ord=1, axis=1)
+    array([ 6.,  6.])
+
+    Using the `axis` argument to compute matrix norms:
+
+    >>> m = np.arange(8).reshape(2,2,2)
+    >>> LA.norm(m, axis=(1,2))
+    array([  3.74165739,  11.22497216])
+    >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :])
+    (3.7416573867739413, 11.224972160321824)
+
+    """
+    x = asarray(x)
+
+    if not issubclass(x.dtype.type, inexact):
+        x = x.astype(float)
+
+    # Immediately handle some default, simple, fast, and common cases.
+    if axis is None:
+        ndim = x.ndim
+        if ((ord is None) or
+            (ord in ('f', 'fro') and ndim == 2) or
+            (ord == 2 and ndim == 1)):
+
+            x = x.ravel(order='K')
+            if isComplexType(x.dtype.type):
+                sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag)
+            else:
+                sqnorm = dot(x, x)
+            ret = sqrt(sqnorm)
+            if keepdims:
+                ret = ret.reshape(ndim*[1])
+            return ret
+
+    # Normalize the `axis` argument to a tuple.
+    nd = x.ndim
+    if axis is None:
+        axis = tuple(range(nd))
+    elif not isinstance(axis, tuple):
+        try:
+            axis = int(axis)
+        except:
+            raise TypeError("'axis' must be None, an integer or a tuple of integers")
+        axis = (axis,)
+
+    if len(axis) == 1:
+        if ord == Inf:
+            return abs(x).max(axis=axis, keepdims=keepdims)
+        elif ord == -Inf:
+            return abs(x).min(axis=axis, keepdims=keepdims)
+        elif ord == 0:
+            # Zero norm
+            return (x != 0).astype(float).sum(axis=axis, keepdims=keepdims)
+        elif ord == 1:
+            # special case for speedup
+            return add.reduce(abs(x), axis=axis, keepdims=keepdims)
+        elif ord is None or ord == 2:
+            # special case for speedup
+            s = (x.conj() * x).real
+            return sqrt(add.reduce(s, axis=axis, keepdims=keepdims))
+        else:
+            try:
+                ord + 1
+            except TypeError:
+                raise ValueError("Invalid norm order for vectors.")
+            if x.dtype.type is longdouble:
+                # Convert to a float type, so integer arrays give
+                # float results.  Don't apply asfarray to longdouble arrays,
+                # because it will downcast to float64.
+                absx = abs(x)
+            else:
+                absx = x if isComplexType(x.dtype.type) else asfarray(x)
+                if absx.dtype is x.dtype:
+                    absx = abs(absx)
+                else:
+                    # if the type changed, we can safely overwrite absx
+                    abs(absx, out=absx)
+            absx **= ord
+            return add.reduce(absx, axis=axis, keepdims=keepdims) ** (1.0 / ord)
+    elif len(axis) == 2:
+        row_axis, col_axis = axis
+        if row_axis < 0:
+            row_axis += nd
+        if col_axis < 0:
+            col_axis += nd
+        if not (0 <= row_axis < nd and 0 <= col_axis < nd):
+            raise ValueError('Invalid axis %r for an array with shape %r' %
+                             (axis, x.shape))
+        if row_axis == col_axis:
+            raise ValueError('Duplicate axes given.')
+        if ord == 2:
+            ret =  _multi_svd_norm(x, row_axis, col_axis, amax)
+        elif ord == -2:
+            ret = _multi_svd_norm(x, row_axis, col_axis, amin)
+        elif ord == 1:
+            if col_axis > row_axis:
+                col_axis -= 1
+            ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis)
+        elif ord == Inf:
+            if row_axis > col_axis:
+                row_axis -= 1
+            ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis)
+        elif ord == -1:
+            if col_axis > row_axis:
+                col_axis -= 1
+            ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis)
+        elif ord == -Inf:
+            if row_axis > col_axis:
+                row_axis -= 1
+            ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis)
+        elif ord in [None, 'fro', 'f']:
+            ret = sqrt(add.reduce((x.conj() * x).real, axis=axis))
+        elif ord == 'nuc':
+            ret = _multi_svd_norm(x, row_axis, col_axis, sum)
+        else:
+            raise ValueError("Invalid norm order for matrices.")
+        if keepdims:
+            ret_shape = list(x.shape)
+            ret_shape[axis[0]] = 1
+            ret_shape[axis[1]] = 1
+            ret = ret.reshape(ret_shape)
+        return ret
+    else:
+        raise ValueError("Improper number of dimensions to norm.")
+
+
+# multi_dot
+
+def multi_dot(arrays):
+    """
+    Compute the dot product of two or more arrays in a single function call,
+    while automatically selecting the fastest evaluation order.
+
+    `multi_dot` chains `numpy.dot` and uses optimal parenthesization
+    of the matrices [1]_ [2]_. Depending on the shapes of the matrices,
+    this can speed up the multiplication a lot.
+
+    If the first argument is 1-D it is treated as a row vector.
+    If the last argument is 1-D it is treated as a column vector.
+    The other arguments must be 2-D.
+
+    Think of `multi_dot` as::
+
+        def multi_dot(arrays): return functools.reduce(np.dot, arrays)
+
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        If the first argument is 1-D it is treated as row vector.
+        If the last argument is 1-D it is treated as column vector.
+        The other arguments must be 2-D.
+
+    Returns
+    -------
+    output : ndarray
+        Returns the dot product of the supplied arrays.
+
+    See Also
+    --------
+    dot : dot multiplication with two arguments.
+
+    References
+    ----------
+
+    .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378
+    .. [2] http://en.wikipedia.org/wiki/Matrix_chain_multiplication
+
+    Examples
+    --------
+    `multi_dot` allows you to write::
+
+    >>> from numpy.linalg import multi_dot
+    >>> # Prepare some data
+    >>> A = np.random.random(10000, 100)
+    >>> B = np.random.random(100, 1000)
+    >>> C = np.random.random(1000, 5)
+    >>> D = np.random.random(5, 333)
+    >>> # the actual dot multiplication
+    >>> multi_dot([A, B, C, D])
+
+    instead of::
+
+    >>> np.dot(np.dot(np.dot(A, B), C), D)
+    >>> # or
+    >>> A.dot(B).dot(C).dot(D)
+
+
+    Example: multiplication costs of different parenthesizations
+    ------------------------------------------------------------
+
+    The cost for a matrix multiplication can be calculated with the
+    following function::
+
+        def cost(A, B): return A.shape[0] * A.shape[1] * B.shape[1]
+
+    Let's assume we have three matrices
+    :math:`A_{10x100}, B_{100x5}, C_{5x50}$`.
+
+    The costs for the two different parenthesizations are as follows::
+
+        cost((AB)C) = 10*100*5 + 10*5*50   = 5000 + 2500   = 7500
+        cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000
+
+    """
+    n = len(arrays)
+    # optimization only makes sense for len(arrays) > 2
+    if n < 2:
+        raise ValueError("Expecting at least two arrays.")
+    elif n == 2:
+        return dot(arrays[0], arrays[1])
+
+    arrays = [asanyarray(a) for a in arrays]
+
+    # save original ndim to reshape the result array into the proper form later
+    ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim
+    # Explicitly convert vectors to 2D arrays to keep the logic of the internal
+    # _multi_dot_* functions as simple as possible.
+    if arrays[0].ndim == 1:
+        arrays[0] = atleast_2d(arrays[0])
+    if arrays[-1].ndim == 1:
+        arrays[-1] = atleast_2d(arrays[-1]).T
+    _assertRank2(*arrays)
+
+    # _multi_dot_three is much faster than _multi_dot_matrix_chain_order
+    if n == 3:
+        result = _multi_dot_three(arrays[0], arrays[1], arrays[2])
+    else:
+        order = _multi_dot_matrix_chain_order(arrays)
+        result = _multi_dot(arrays, order, 0, n - 1)
+
+    # return proper shape
+    if ndim_first == 1 and ndim_last == 1:
+        return result[0, 0]  # scalar
+    elif ndim_first == 1 or ndim_last == 1:
+        return result.ravel()  # 1-D
+    else:
+        return result
+
+
+def _multi_dot_three(A, B, C):
+    """
+    Find the best order for three arrays and do the multiplication.
+
+    For three arguments `_multi_dot_three` is approximately 15 times faster
+    than `_multi_dot_matrix_chain_order`
+
+    """
+    # cost1 = cost((AB)C)
+    cost1 = (A.shape[0] * A.shape[1] * B.shape[1] +  # (AB)
+             A.shape[0] * B.shape[1] * C.shape[1])   # (--)C
+    # cost2 = cost((AB)C)
+    cost2 = (B.shape[0] * B.shape[1] * C.shape[1] +  #  (BC)
+             A.shape[0] * A.shape[1] * C.shape[1])   # A(--)
+
+    if cost1 < cost2:
+        return dot(dot(A, B), C)
+    else:
+        return dot(A, dot(B, C))
+
+
+def _multi_dot_matrix_chain_order(arrays, return_costs=False):
+    """
+    Return a np.array that encodes the optimal order of mutiplications.
+
+    The optimal order array is then used by `_multi_dot()` to do the
+    multiplication.
+
+    Also return the cost matrix if `return_costs` is `True`
+
+    The implementation CLOSELY follows Cormen, "Introduction to Algorithms",
+    Chapter 15.2, p. 370-378.  Note that Cormen uses 1-based indices.
+
+        cost[i, j] = min([
+            cost[prefix] + cost[suffix] + cost_mult(prefix, suffix)
+            for k in range(i, j)])
+
+    """
+    n = len(arrays)
+    # p stores the dimensions of the matrices
+    # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50]
+    p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]]
+    # m is a matrix of costs of the subproblems
+    # m[i,j]: min number of scalar multiplications needed to compute A_{i..j}
+    m = zeros((n, n), dtype=double)
+    # s is the actual ordering
+    # s[i, j] is the value of k at which we split the product A_i..A_j
+    s = empty((n, n), dtype=intp)
+
+    for l in range(1, n):
+        for i in range(n - l):
+            j = i + l
+            m[i, j] = Inf
+            for k in range(i, j):
+                q = m[i, k] + m[k+1, j] + p[i]*p[k+1]*p[j+1]
+                if q < m[i, j]:
+                    m[i, j] = q
+                    s[i, j] = k  # Note that Cormen uses 1-based index
+
+    return (s, m) if return_costs else s
+
+
+def _multi_dot(arrays, order, i, j):
+    """Actually do the multiplication with the given order."""
+    if i == j:
+        return arrays[i]
+    else:
+        return dot(_multi_dot(arrays, order, i, order[i, j]),
+                   _multi_dot(arrays, order, order[i, j] + 1, j))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/setup.py
new file mode 100644
index 0000000000..adc8f17848
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/setup.py
@@ -0,0 +1,57 @@
+from __future__ import division, print_function
+
+import os
+import sys
+
+def configuration(parent_package='', top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    from numpy.distutils.system_info import get_info
+    config = Configuration('linalg', parent_package, top_path)
+
+    config.add_data_dir('tests')
+
+    # Configure lapack_lite
+
+    src_dir = 'lapack_lite'
+    lapack_lite_src = [
+        os.path.join(src_dir, 'python_xerbla.c'),
+        os.path.join(src_dir, 'zlapack_lite.c'),
+        os.path.join(src_dir, 'dlapack_lite.c'),
+        os.path.join(src_dir, 'blas_lite.c'),
+        os.path.join(src_dir, 'dlamch.c'),
+        os.path.join(src_dir, 'f2c_lite.c'),
+    ]
+    all_sources = config.paths(lapack_lite_src)
+
+    lapack_info = get_info('lapack_opt', 0)  # and {}
+
+    def get_lapack_lite_sources(ext, build_dir):
+        if not lapack_info:
+            print("### Warning:  Using unoptimized lapack ###")
+            return all_sources
+        else:
+            if sys.platform == 'win32':
+                print("### Warning:  python_xerbla.c is disabled ###")
+                return []
+            return [all_sources[0]]
+
+    config.add_extension(
+        'lapack_lite',
+        sources=['lapack_litemodule.c', get_lapack_lite_sources],
+        depends=['lapack_lite/f2c.h'],
+        extra_info=lapack_info,
+    )
+
+    # umath_linalg module
+    config.add_extension(
+        '_umath_linalg',
+        sources=['umath_linalg.c.src', get_lapack_lite_sources],
+        depends=['lapack_lite/f2c.h'],
+        extra_info=lapack_info,
+        libraries=['npymath'],
+    )
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
new file mode 100644
index 0000000000..dfb154190b
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
@@ -0,0 +1,59 @@
+from __future__ import division, absolute_import, print_function
+
+from subprocess import PIPE, Popen
+import sys
+import re
+
+from numpy.linalg import lapack_lite
+from numpy.testing import TestCase, dec, run_module_suite
+
+from numpy.compat import asbytes_nested
+
+
+class FindDependenciesLdd(object):
+
+    def __init__(self):
+        self.cmd = ['ldd']
+
+        try:
+            p = Popen(self.cmd, stdout=PIPE, stderr=PIPE)
+            stdout, stderr = p.communicate()
+        except OSError:
+            raise RuntimeError("command %s cannot be run" % self.cmd)
+
+    def get_dependencies(self, lfile):
+        p = Popen(self.cmd + [lfile], stdout=PIPE, stderr=PIPE)
+        stdout, stderr = p.communicate()
+        if not (p.returncode == 0):
+            raise RuntimeError("failed dependencies check for %s" % lfile)
+
+        return stdout
+
+    def grep_dependencies(self, lfile, deps):
+        stdout = self.get_dependencies(lfile)
+
+        rdeps = dict([(dep, re.compile(dep)) for dep in deps])
+        founds = []
+        for l in stdout.splitlines():
+            for k, v in rdeps.items():
+                if v.search(l):
+                    founds.append(k)
+
+        return founds
+
+
+class TestF77Mismatch(TestCase):
+
+    @dec.skipif(not(sys.platform[:5] == 'linux'),
+                "Skipping fortran compiler mismatch on non Linux platform")
+    def test_lapack(self):
+        f = FindDependenciesLdd()
+        deps = f.grep_dependencies(lapack_lite.__file__,
+                                   asbytes_nested(['libg2c', 'libgfortran']))
+        self.assertFalse(len(deps) > 1,
+                         """Both g77 and gfortran runtimes linked in lapack_lite ! This is likely to
+cause random crashes and wrong results. See numpy INSTALL.txt for more
+information.""")
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
new file mode 100644
index 0000000000..9b6fe343f5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
@@ -0,0 +1,26 @@
+"""Test deprecation and future warnings.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_warns, run_module_suite
+
+
+def test_qr_mode_full_future_warning():
+    """Check mode='full' FutureWarning.
+
+    In numpy 1.8 the mode options 'full' and 'economic' in linalg.qr were
+    deprecated. The release date will probably be sometime in the summer
+    of 2013.
+
+    """
+    a = np.eye(2)
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='full')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='f')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='economic')
+    assert_warns(DeprecationWarning, np.linalg.qr, a, mode='e')
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
new file mode 100644
index 0000000000..60486d4cec
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
@@ -0,0 +1,1443 @@
+""" Test functions for linalg module
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import itertools
+import traceback
+import warnings
+
+import numpy as np
+from numpy import array, single, double, csingle, cdouble, dot, identity
+from numpy import multiply, atleast_2d, inf, asarray, matrix
+from numpy import linalg
+from numpy.linalg import matrix_power, norm, matrix_rank, multi_dot
+from numpy.linalg.linalg import _multi_dot_matrix_chain_order
+from numpy.testing import (
+    assert_, assert_equal, assert_raises, assert_array_equal,
+    assert_almost_equal, assert_allclose, run_module_suite,
+    dec, SkipTest
+)
+
+
+def ifthen(a, b):
+    return not a or b
+
+
+def imply(a, b):
+    return not a or b
+
+
+old_assert_almost_equal = assert_almost_equal
+
+
+def assert_almost_equal(a, b, **kw):
+    if asarray(a).dtype.type in (single, csingle):
+        decimal = 6
+    else:
+        decimal = 12
+    old_assert_almost_equal(a, b, decimal=decimal, **kw)
+
+
+def get_real_dtype(dtype):
+    return {single: single, double: double,
+            csingle: single, cdouble: double}[dtype]
+
+
+def get_complex_dtype(dtype):
+    return {single: csingle, double: cdouble,
+            csingle: csingle, cdouble: cdouble}[dtype]
+
+
+def get_rtol(dtype):
+    # Choose a safe rtol
+    if dtype in (single, csingle):
+        return 1e-5
+    else:
+        return 1e-11
+
+
+class LinalgCase(object):
+
+    def __init__(self, name, a, b, exception_cls=None):
+        assert_(isinstance(name, str))
+        self.name = name
+        self.a = a
+        self.b = b
+        self.exception_cls = exception_cls
+
+    def check(self, do):
+        if self.exception_cls is None:
+            do(self.a, self.b)
+        else:
+            assert_raises(self.exception_cls, do, self.a, self.b)
+
+    def __repr__(self):
+        return "<LinalgCase: %s>" % (self.name,)
+
+
+#
+# Base test cases
+#
+
+np.random.seed(1234)
+
+SQUARE_CASES = [
+    LinalgCase("single",
+               array([[1., 2.], [3., 4.]], dtype=single),
+               array([2., 1.], dtype=single)),
+    LinalgCase("double",
+               array([[1., 2.], [3., 4.]], dtype=double),
+               array([2., 1.], dtype=double)),
+    LinalgCase("double_2",
+               array([[1., 2.], [3., 4.]], dtype=double),
+               array([[2., 1., 4.], [3., 4., 6.]], dtype=double)),
+    LinalgCase("csingle",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j], dtype=csingle)),
+    LinalgCase("cdouble",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j], dtype=cdouble)),
+    LinalgCase("cdouble_2",
+               array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j, 1 + 3j], [1 - 2j, 1 - 3j, 1 - 6j]], dtype=cdouble)),
+    LinalgCase("empty",
+               atleast_2d(array([], dtype=double)),
+               atleast_2d(array([], dtype=double)),
+               linalg.LinAlgError),
+    LinalgCase("8x8",
+               np.random.rand(8, 8),
+               np.random.rand(8)),
+    LinalgCase("1x1",
+               np.random.rand(1, 1),
+               np.random.rand(1)),
+    LinalgCase("nonarray",
+               [[1, 2], [3, 4]],
+               [2, 1]),
+    LinalgCase("matrix_b_only",
+               array([[1., 2.], [3., 4.]]),
+               matrix([2., 1.]).T),
+    LinalgCase("matrix_a_and_b",
+               matrix([[1., 2.], [3., 4.]]),
+               matrix([2., 1.]).T),
+]
+
+NONSQUARE_CASES = [
+    LinalgCase("single_nsq_1",
+               array([[1., 2., 3.], [3., 4., 6.]], dtype=single),
+               array([2., 1.], dtype=single)),
+    LinalgCase("single_nsq_2",
+               array([[1., 2.], [3., 4.], [5., 6.]], dtype=single),
+               array([2., 1., 3.], dtype=single)),
+    LinalgCase("double_nsq_1",
+               array([[1., 2., 3.], [3., 4., 6.]], dtype=double),
+               array([2., 1.], dtype=double)),
+    LinalgCase("double_nsq_2",
+               array([[1., 2.], [3., 4.], [5., 6.]], dtype=double),
+               array([2., 1., 3.], dtype=double)),
+    LinalgCase("csingle_nsq_1",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j], dtype=csingle)),
+    LinalgCase("csingle_nsq_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=csingle),
+               array([2. + 1j, 1. + 2j, 3. - 3j], dtype=csingle)),
+    LinalgCase("cdouble_nsq_1",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble),
+               array([2. + 1j, 1. + 2j, 3. - 3j], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_1_2",
+               array(
+                   [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)),
+    LinalgCase("cdouble_nsq_2_2",
+               array(
+                   [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble),
+               array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)),
+    LinalgCase("8x11",
+               np.random.rand(8, 11),
+               np.random.rand(11)),
+    LinalgCase("1x5",
+               np.random.rand(1, 5),
+               np.random.rand(5)),
+    LinalgCase("5x1",
+               np.random.rand(5, 1),
+               np.random.rand(1)),
+]
+
+HERMITIAN_CASES = [
+    LinalgCase("hsingle",
+               array([[1., 2.], [2., 1.]], dtype=single),
+               None),
+    LinalgCase("hdouble",
+               array([[1., 2.], [2., 1.]], dtype=double),
+               None),
+    LinalgCase("hcsingle",
+               array([[1., 2 + 3j], [2 - 3j, 1]], dtype=csingle),
+               None),
+    LinalgCase("hcdouble",
+               array([[1., 2 + 3j], [2 - 3j, 1]], dtype=cdouble),
+               None),
+    LinalgCase("hempty",
+               atleast_2d(array([], dtype=double)),
+               None,
+               linalg.LinAlgError),
+    LinalgCase("hnonarray",
+               [[1, 2], [2, 1]],
+               None),
+    LinalgCase("matrix_b_only",
+               array([[1., 2.], [2., 1.]]),
+               None),
+    LinalgCase("hmatrix_a_and_b",
+               matrix([[1., 2.], [2., 1.]]),
+               None),
+    LinalgCase("hmatrix_1x1",
+               np.random.rand(1, 1),
+               None),
+]
+
+
+#
+# Gufunc test cases
+#
+
+GENERALIZED_SQUARE_CASES = []
+GENERALIZED_NONSQUARE_CASES = []
+GENERALIZED_HERMITIAN_CASES = []
+
+for tgt, src in ((GENERALIZED_SQUARE_CASES, SQUARE_CASES),
+                 (GENERALIZED_NONSQUARE_CASES, NONSQUARE_CASES),
+                 (GENERALIZED_HERMITIAN_CASES, HERMITIAN_CASES)):
+    for case in src:
+        if not isinstance(case.a, np.ndarray):
+            continue
+
+        a = np.array([case.a, 2 * case.a, 3 * case.a])
+        if case.b is None:
+            b = None
+        else:
+            b = np.array([case.b, 7 * case.b, 6 * case.b])
+        new_case = LinalgCase(case.name + "_tile3", a, b,
+                              case.exception_cls)
+        tgt.append(new_case)
+
+        a = np.array([case.a] * 2 * 3).reshape((3, 2) + case.a.shape)
+        if case.b is None:
+            b = None
+        else:
+            b = np.array([case.b] * 2 * 3).reshape((3, 2) + case.b.shape)
+        new_case = LinalgCase(case.name + "_tile213", a, b,
+                              case.exception_cls)
+        tgt.append(new_case)
+
+#
+# Generate stride combination variations of the above
+#
+
+
+def _stride_comb_iter(x):
+    """
+    Generate cartesian product of strides for all axes
+    """
+
+    if not isinstance(x, np.ndarray):
+        yield x, "nop"
+        return
+
+    stride_set = [(1,)] * x.ndim
+    stride_set[-1] = (1, 3, -4)
+    if x.ndim > 1:
+        stride_set[-2] = (1, 3, -4)
+    if x.ndim > 2:
+        stride_set[-3] = (1, -4)
+
+    for repeats in itertools.product(*tuple(stride_set)):
+        new_shape = [abs(a * b) for a, b in zip(x.shape, repeats)]
+        slices = tuple([slice(None, None, repeat) for repeat in repeats])
+
+        # new array with different strides, but same data
+        xi = np.empty(new_shape, dtype=x.dtype)
+        xi.view(np.uint32).fill(0xdeadbeef)
+        xi = xi[slices]
+        xi[...] = x
+        xi = xi.view(x.__class__)
+        assert_(np.all(xi == x))
+        yield xi, "stride_" + "_".join(["%+d" % j for j in repeats])
+
+        # generate also zero strides if possible
+        if x.ndim >= 1 and x.shape[-1] == 1:
+            s = list(x.strides)
+            s[-1] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0"
+        if x.ndim >= 2 and x.shape[-2] == 1:
+            s = list(x.strides)
+            s[-2] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0_x"
+        if x.ndim >= 2 and x.shape[:-2] == (1, 1):
+            s = list(x.strides)
+            s[-1] = 0
+            s[-2] = 0
+            xi = np.lib.stride_tricks.as_strided(x, strides=s)
+            yield xi, "stride_xxx_0_0"
+
+for src in (SQUARE_CASES,
+            NONSQUARE_CASES,
+            HERMITIAN_CASES,
+            GENERALIZED_SQUARE_CASES,
+            GENERALIZED_NONSQUARE_CASES,
+            GENERALIZED_HERMITIAN_CASES):
+
+    new_cases = []
+    for case in src:
+        for a, a_tag in _stride_comb_iter(case.a):
+            for b, b_tag in _stride_comb_iter(case.b):
+                new_case = LinalgCase(case.name + "_" + a_tag + "_" + b_tag, a, b,
+                                      exception_cls=case.exception_cls)
+                new_cases.append(new_case)
+    src.extend(new_cases)
+
+
+#
+# Test different routines against the above cases
+#
+
+def _check_cases(func, cases):
+    for case in cases:
+        try:
+            case.check(func)
+        except Exception:
+            msg = "In test case: %r\n\n" % case
+            msg += traceback.format_exc()
+            raise AssertionError(msg)
+
+
+class LinalgTestCase(object):
+
+    def test_sq_cases(self):
+        _check_cases(self.do, SQUARE_CASES)
+
+
+class LinalgNonsquareTestCase(object):
+
+    def test_sq_cases(self):
+        _check_cases(self.do, NONSQUARE_CASES)
+
+
+class LinalgGeneralizedTestCase(object):
+
+    @dec.slow
+    def test_generalized_sq_cases(self):
+        _check_cases(self.do, GENERALIZED_SQUARE_CASES)
+
+
+class LinalgGeneralizedNonsquareTestCase(object):
+
+    @dec.slow
+    def test_generalized_nonsq_cases(self):
+        _check_cases(self.do, GENERALIZED_NONSQUARE_CASES)
+
+
+class HermitianTestCase(object):
+
+    def test_herm_cases(self):
+        _check_cases(self.do, HERMITIAN_CASES)
+
+
+class HermitianGeneralizedTestCase(object):
+
+    @dec.slow
+    def test_generalized_herm_cases(self):
+        _check_cases(self.do, GENERALIZED_HERMITIAN_CASES)
+
+
+def dot_generalized(a, b):
+    a = asarray(a)
+    if a.ndim >= 3:
+        if a.ndim == b.ndim:
+            # matrix x matrix
+            new_shape = a.shape[:-1] + b.shape[-1:]
+        elif a.ndim == b.ndim + 1:
+            # matrix x vector
+            new_shape = a.shape[:-1]
+        else:
+            raise ValueError("Not implemented...")
+        r = np.empty(new_shape, dtype=np.common_type(a, b))
+        for c in itertools.product(*map(range, a.shape[:-2])):
+            r[c] = dot(a[c], b[c])
+        return r
+    else:
+        return dot(a, b)
+
+
+def identity_like_generalized(a):
+    a = asarray(a)
+    if a.ndim >= 3:
+        r = np.empty(a.shape, dtype=a.dtype)
+        for c in itertools.product(*map(range, a.shape[:-2])):
+            r[c] = identity(a.shape[-2])
+        return r
+    else:
+        return identity(a.shape[0])
+
+
+class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        x = linalg.solve(a, b)
+        assert_almost_equal(b, dot_generalized(a, x))
+        assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.solve(x, x).dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_0_size(self):
+        class ArraySubclass(np.ndarray):
+            pass
+        # Test system of 0x0 matrices
+        a = np.arange(8).reshape(2, 2, 2)
+        b = np.arange(6).reshape(1, 2, 3).view(ArraySubclass)
+
+        expected = linalg.solve(a, b)[:, 0:0, :]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, :])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        # Test errors for non-square and only b's dimension being 0
+        assert_raises(linalg.LinAlgError, linalg.solve, a[:, 0:0, 0:1], b)
+        assert_raises(ValueError, linalg.solve, a, b[:, 0:0, :])
+
+        # Test broadcasting error
+        b = np.arange(6).reshape(1, 3, 2)  # broadcasting error
+        assert_raises(ValueError, linalg.solve, a, b)
+        assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
+
+        # Test zero "single equations" with 0x0 matrices.
+        b = np.arange(2).reshape(1, 2).view(ArraySubclass)
+        expected = linalg.solve(a, b)[:, 0:0]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        b = np.arange(3).reshape(1, 3)
+        assert_raises(ValueError, linalg.solve, a, b)
+        assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
+        assert_raises(ValueError, linalg.solve, a[:, 0:0, 0:0], b)
+
+    def test_0_size_k(self):
+        # test zero multiple equation (K=0) case.
+        class ArraySubclass(np.ndarray):
+            pass
+        a = np.arange(4).reshape(1, 2, 2)
+        b = np.arange(6).reshape(3, 2, 1).view(ArraySubclass)
+
+        expected = linalg.solve(a, b)[:, :, 0:0]
+        result = linalg.solve(a, b[:, :, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+        # test both zero.
+        expected = linalg.solve(a, b)[:, 0:0, 0:0]
+        result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, 0:0])
+        assert_array_equal(result, expected)
+        assert_(isinstance(result, ArraySubclass))
+
+
+class TestInv(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        a_inv = linalg.inv(a)
+        assert_almost_equal(dot_generalized(a, a_inv),
+                            identity_like_generalized(a))
+        assert_(imply(isinstance(a, matrix), isinstance(a_inv, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.inv(x).dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_0_size(self):
+        # Check that all kinds of 0-sized arrays work
+        class ArraySubclass(np.ndarray):
+            pass
+        a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass)
+        res = linalg.inv(a)
+        assert_(res.dtype.type is np.float64)
+        assert_equal(a.shape, res.shape)
+        assert_(isinstance(a, ArraySubclass))
+
+        a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass)
+        res = linalg.inv(a)
+        assert_(res.dtype.type is np.complex64)
+        assert_equal(a.shape, res.shape)
+
+
+class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        ev = linalg.eigvals(a)
+        evalues, evectors = linalg.eig(a)
+        assert_almost_equal(ev, evalues)
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(linalg.eigvals(x).dtype, dtype)
+            x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+            assert_equal(linalg.eigvals(x).dtype, get_complex_dtype(dtype))
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestEig(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        evalues, evectors = linalg.eig(a)
+        assert_allclose(dot_generalized(a, evectors),
+                        np.asarray(evectors) * np.asarray(evalues)[..., None, :],
+                        rtol=get_rtol(evalues.dtype))
+        assert_(imply(isinstance(a, matrix), isinstance(evectors, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w, v = np.linalg.eig(x)
+            assert_equal(w.dtype, dtype)
+            assert_equal(v.dtype, dtype)
+
+            x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+            w, v = np.linalg.eig(x)
+            assert_equal(w.dtype, get_complex_dtype(dtype))
+            assert_equal(v.dtype, get_complex_dtype(dtype))
+
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        u, s, vt = linalg.svd(a, 0)
+        assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[..., None, :],
+                                           np.asarray(vt)),
+                        rtol=get_rtol(u.dtype))
+        assert_(imply(isinstance(a, matrix), isinstance(u, matrix)))
+        assert_(imply(isinstance(a, matrix), isinstance(vt, matrix)))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            u, s, vh = linalg.svd(x)
+            assert_equal(u.dtype, dtype)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+            assert_equal(vh.dtype, dtype)
+            s = linalg.svd(x, compute_uv=False)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        c = asarray(a)  # a might be a matrix
+        s = linalg.svd(c, compute_uv=False)
+        old_assert_almost_equal(
+            s[..., 0] / s[..., -1], linalg.cond(a), decimal=5)
+
+    def test_stacked_arrays_explicitly(self):
+        A = np.array([[1., 2., 1.], [0, -2., 0], [6., 2., 3.]])
+        assert_equal(linalg.cond(A), linalg.cond(A[None, ...])[0])
+
+
+class TestCond2(LinalgTestCase):
+
+    def do(self, a, b):
+        c = asarray(a)  # a might be a matrix
+        s = linalg.svd(c, compute_uv=False)
+        old_assert_almost_equal(
+            s[..., 0] / s[..., -1], linalg.cond(a, 2), decimal=5)
+
+    def test_stacked_arrays_explicitly(self):
+        A = np.array([[1., 2., 1.], [0, -2., 0], [6., 2., 3.]])
+        assert_equal(linalg.cond(A, 2), linalg.cond(A[None, ...], 2)[0])
+
+
+class TestCondInf(object):
+
+    def test(self):
+        A = array([[1., 0, 0], [0, -2., 0], [0, 0, 3.]])
+        assert_almost_equal(linalg.cond(A, inf), 3.)
+
+
+class TestPinv(LinalgTestCase):
+
+    def do(self, a, b):
+        a_ginv = linalg.pinv(a)
+        assert_almost_equal(dot(a, a_ginv), identity(asarray(a).shape[0]))
+        assert_(imply(isinstance(a, matrix), isinstance(a_ginv, matrix)))
+
+
+class TestDet(LinalgTestCase, LinalgGeneralizedTestCase):
+
+    def do(self, a, b):
+        d = linalg.det(a)
+        (s, ld) = linalg.slogdet(a)
+        if asarray(a).dtype.type in (single, double):
+            ad = asarray(a).astype(double)
+        else:
+            ad = asarray(a).astype(cdouble)
+        ev = linalg.eigvals(ad)
+        assert_almost_equal(d, multiply.reduce(ev, axis=-1))
+        assert_almost_equal(s * np.exp(ld), multiply.reduce(ev, axis=-1))
+
+        s = np.atleast_1d(s)
+        ld = np.atleast_1d(ld)
+        m = (s != 0)
+        assert_almost_equal(np.abs(s[m]), 1)
+        assert_equal(ld[~m], -inf)
+
+    def test_zero(self):
+        assert_equal(linalg.det([[0.0]]), 0.0)
+        assert_equal(type(linalg.det([[0.0]])), double)
+        assert_equal(linalg.det([[0.0j]]), 0.0)
+        assert_equal(type(linalg.det([[0.0j]])), cdouble)
+
+        assert_equal(linalg.slogdet([[0.0]]), (0.0, -inf))
+        assert_equal(type(linalg.slogdet([[0.0]])[0]), double)
+        assert_equal(type(linalg.slogdet([[0.0]])[1]), double)
+        assert_equal(linalg.slogdet([[0.0j]]), (0.0j, -inf))
+        assert_equal(type(linalg.slogdet([[0.0j]])[0]), cdouble)
+        assert_equal(type(linalg.slogdet([[0.0j]])[1]), double)
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            assert_equal(np.linalg.det(x).dtype, dtype)
+            ph, s = np.linalg.slogdet(x)
+            assert_equal(s.dtype, get_real_dtype(dtype))
+            assert_equal(ph.dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+
+class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase):
+
+    def do(self, a, b):
+        arr = np.asarray(a)
+        m, n = arr.shape
+        u, s, vt = linalg.svd(a, 0)
+        x, residuals, rank, sv = linalg.lstsq(a, b)
+        if m <= n:
+            assert_almost_equal(b, dot(a, x))
+            assert_equal(rank, m)
+        else:
+            assert_equal(rank, n)
+        assert_almost_equal(sv, sv.__array_wrap__(s))
+        if rank == n and m > n:
+            expect_resids = (
+                np.asarray(abs(np.dot(a, x) - b)) ** 2).sum(axis=0)
+            expect_resids = np.asarray(expect_resids)
+            if len(np.asarray(b).shape) == 1:
+                expect_resids.shape = (1,)
+                assert_equal(residuals.shape, expect_resids.shape)
+        else:
+            expect_resids = np.array([]).view(type(x))
+        assert_almost_equal(residuals, expect_resids)
+        assert_(np.issubdtype(residuals.dtype, np.floating))
+        assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+        assert_(imply(isinstance(b, matrix), isinstance(residuals, matrix)))
+
+
+class TestMatrixPower(object):
+    R90 = array([[0, 1], [-1, 0]])
+    Arb22 = array([[4, -7], [-2, 10]])
+    noninv = array([[1, 0], [0, 0]])
+    arbfloat = array([[0.1, 3.2], [1.2, 0.7]])
+
+    large = identity(10)
+    t = large[1, :].copy()
+    large[1, :] = large[0,:]
+    large[0, :] = t
+
+    def test_large_power(self):
+        assert_equal(
+            matrix_power(self.R90, 2 ** 100 + 2 ** 10 + 2 ** 5 + 1), self.R90)
+
+    def test_large_power_trailing_zero(self):
+        assert_equal(
+            matrix_power(self.R90, 2 ** 100 + 2 ** 10 + 2 ** 5), identity(2))
+
+    def testip_zero(self):
+        def tz(M):
+            mz = matrix_power(M, 0)
+            assert_equal(mz, identity(M.shape[0]))
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_one(self):
+        def tz(M):
+            mz = matrix_power(M, 1)
+            assert_equal(mz, M)
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_two(self):
+        def tz(M):
+            mz = matrix_power(M, 2)
+            assert_equal(mz, dot(M, M))
+            assert_equal(mz.dtype, M.dtype)
+        for M in [self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def testip_invert(self):
+        def tz(M):
+            mz = matrix_power(M, -1)
+            assert_almost_equal(identity(M.shape[0]), dot(mz, M))
+        for M in [self.R90, self.Arb22, self.arbfloat, self.large]:
+            yield tz, M
+
+    def test_invert_noninvertible(self):
+        import numpy.linalg
+        assert_raises(numpy.linalg.linalg.LinAlgError,
+                      lambda: matrix_power(self.noninv, -1))
+
+
+class TestBoolPower(object):
+
+    def test_square(self):
+        A = array([[True, False], [True, True]])
+        assert_equal(matrix_power(A, 2), A)
+
+
+class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase):
+
+    def do(self, a, b):
+        # note that eigenvalue arrays returned by eig must be sorted since
+        # their order isn't guaranteed.
+        ev = linalg.eigvalsh(a, 'L')
+        evalues, evectors = linalg.eig(a)
+        evalues.sort(axis=-1)
+        assert_allclose(ev, evalues, rtol=get_rtol(ev.dtype))
+
+        ev2 = linalg.eigvalsh(a, 'U')
+        assert_allclose(ev2, evalues, rtol=get_rtol(ev.dtype))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w = np.linalg.eigvalsh(x)
+            assert_equal(w.dtype, get_real_dtype(dtype))
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_invalid(self):
+        x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+        assert_raises(ValueError, np.linalg.eigvalsh, x, UPLO="lrong")
+        assert_raises(ValueError, np.linalg.eigvalsh, x, "lower")
+        assert_raises(ValueError, np.linalg.eigvalsh, x, "upper")
+
+    def test_UPLO(self):
+        Klo = np.array([[0, 0], [1, 0]], dtype=np.double)
+        Kup = np.array([[0, 1], [0, 0]], dtype=np.double)
+        tgt = np.array([-1, 1], dtype=np.double)
+        rtol = get_rtol(np.double)
+
+        # Check default is 'L'
+        w = np.linalg.eigvalsh(Klo)
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'L'
+        w = np.linalg.eigvalsh(Klo, UPLO='L')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'l'
+        w = np.linalg.eigvalsh(Klo, UPLO='l')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'U'
+        w = np.linalg.eigvalsh(Kup, UPLO='U')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'u'
+        w = np.linalg.eigvalsh(Kup, UPLO='u')
+        assert_allclose(w, tgt, rtol=rtol)
+
+
+class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
+
+    def do(self, a, b):
+        # note that eigenvalue arrays returned by eig must be sorted since
+        # their order isn't guaranteed.
+        ev, evc = linalg.eigh(a)
+        evalues, evectors = linalg.eig(a)
+        evalues.sort(axis=-1)
+        assert_almost_equal(ev, evalues)
+
+        assert_allclose(dot_generalized(a, evc),
+                        np.asarray(ev)[..., None, :] * np.asarray(evc),
+                        rtol=get_rtol(ev.dtype))
+
+        ev2, evc2 = linalg.eigh(a, 'U')
+        assert_almost_equal(ev2, evalues)
+
+        assert_allclose(dot_generalized(a, evc2),
+                        np.asarray(ev2)[..., None, :] * np.asarray(evc2),
+                        rtol=get_rtol(ev.dtype), err_msg=repr(a))
+
+    def test_types(self):
+        def check(dtype):
+            x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+            w, v = np.linalg.eigh(x)
+            assert_equal(w.dtype, get_real_dtype(dtype))
+            assert_equal(v.dtype, dtype)
+        for dtype in [single, double, csingle, cdouble]:
+            yield check, dtype
+
+    def test_invalid(self):
+        x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+        assert_raises(ValueError, np.linalg.eigh, x, UPLO="lrong")
+        assert_raises(ValueError, np.linalg.eigh, x, "lower")
+        assert_raises(ValueError, np.linalg.eigh, x, "upper")
+
+    def test_UPLO(self):
+        Klo = np.array([[0, 0], [1, 0]], dtype=np.double)
+        Kup = np.array([[0, 1], [0, 0]], dtype=np.double)
+        tgt = np.array([-1, 1], dtype=np.double)
+        rtol = get_rtol(np.double)
+
+        # Check default is 'L'
+        w, v = np.linalg.eigh(Klo)
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'L'
+        w, v = np.linalg.eigh(Klo, UPLO='L')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'l'
+        w, v = np.linalg.eigh(Klo, UPLO='l')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'U'
+        w, v = np.linalg.eigh(Kup, UPLO='U')
+        assert_allclose(w, tgt, rtol=rtol)
+        # Check 'u'
+        w, v = np.linalg.eigh(Kup, UPLO='u')
+        assert_allclose(w, tgt, rtol=rtol)
+
+
+class _TestNorm(object):
+
+    dt = None
+    dec = None
+
+    def test_empty(self):
+        assert_equal(norm([]), 0.0)
+        assert_equal(norm(array([], dtype=self.dt)), 0.0)
+        assert_equal(norm(atleast_2d(array([], dtype=self.dt))), 0.0)
+
+    def test_vector_return_type(self):
+        a = np.array([1, 0, 1])
+
+        exact_types = np.typecodes['AllInteger']
+        inexact_types = np.typecodes['AllFloat']
+
+        all_types = exact_types + inexact_types
+
+        for each_inexact_types in all_types:
+            at = a.astype(each_inexact_types)
+
+            an = norm(at, -np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 0.0)
+
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", RuntimeWarning)
+                an = norm(at, -1)
+                assert_(issubclass(an.dtype.type, np.floating))
+                assert_almost_equal(an, 0.0)
+
+            an = norm(at, 0)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2)
+
+            an = norm(at, 1)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0**(1.0/2.0))
+
+            an = norm(at, 4)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0**(1.0/4.0))
+
+            an = norm(at, np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 1.0)
+
+    def test_matrix_return_type(self):
+        a = np.array([[1, 0, 1], [0, 1, 1]])
+
+        exact_types = np.typecodes['AllInteger']
+
+        # float32, complex64, float64, complex128 types are the only types
+        # allowed by `linalg`, which performs the matrix operations used
+        # within `norm`.
+        inexact_types = 'fdFD'
+
+        all_types = exact_types + inexact_types
+
+        for each_inexact_types in all_types:
+            at = a.astype(each_inexact_types)
+
+            an = norm(at, -np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            with warnings.catch_warnings():
+                warnings.simplefilter("ignore", RuntimeWarning)
+                an = norm(at, -1)
+                assert_(issubclass(an.dtype.type, np.floating))
+                assert_almost_equal(an, 1.0)
+
+            an = norm(at, 1)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 3.0**(1.0/2.0))
+
+            an = norm(at, -2)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 1.0)
+
+            an = norm(at, np.inf)
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 'fro')
+            assert_(issubclass(an.dtype.type, np.floating))
+            assert_almost_equal(an, 2.0)
+
+            an = norm(at, 'nuc')
+            assert_(issubclass(an.dtype.type, np.floating))
+            # Lower bar needed to support low precision floats.
+            # They end up being off by 1 in the 7th place.
+            old_assert_almost_equal(an, 2.7320508075688772, decimal=6)
+
+    def test_vector(self):
+        a = [1, 2, 3, 4]
+        b = [-1, -2, -3, -4]
+        c = [-1, 2, -3, 4]
+
+        def _test(v):
+            np.testing.assert_almost_equal(norm(v), 30 ** 0.5,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, inf), 4.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -inf), 1.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 1), 10.0,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -1), 12.0 / 25,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 2), 30 ** 0.5,
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, -2), ((205. / 144) ** -0.5),
+                                           decimal=self.dec)
+            np.testing.assert_almost_equal(norm(v, 0), 4,
+                                           decimal=self.dec)
+
+        for v in (a, b, c,):
+            _test(v)
+
+        for v in (array(a, dtype=self.dt), array(b, dtype=self.dt),
+                  array(c, dtype=self.dt)):
+            _test(v)
+
+    def test_matrix_2x2(self):
+        A = matrix([[1, 3], [5, 7]], dtype=self.dt)
+        assert_almost_equal(norm(A), 84 ** 0.5)
+        assert_almost_equal(norm(A, 'fro'), 84 ** 0.5)
+        assert_almost_equal(norm(A, 'nuc'), 10.0)
+        assert_almost_equal(norm(A, inf), 12.0)
+        assert_almost_equal(norm(A, -inf), 4.0)
+        assert_almost_equal(norm(A, 1), 10.0)
+        assert_almost_equal(norm(A, -1), 6.0)
+        assert_almost_equal(norm(A, 2), 9.1231056256176615)
+        assert_almost_equal(norm(A, -2), 0.87689437438234041)
+
+        assert_raises(ValueError, norm, A, 'nofro')
+        assert_raises(ValueError, norm, A, -3)
+        assert_raises(ValueError, norm, A, 0)
+
+    def test_matrix_3x3(self):
+        # This test has been added because the 2x2 example
+        # happened to have equal nuclear norm and induced 1-norm.
+        # The 1/10 scaling factor accommodates the absolute tolerance
+        # used in assert_almost_equal.
+        A = (1 / 10) * \
+            np.array([[1, 2, 3], [6, 0, 5], [3, 2, 1]], dtype=self.dt)
+        assert_almost_equal(norm(A), (1 / 10) * 89 ** 0.5)
+        assert_almost_equal(norm(A, 'fro'), (1 / 10) * 89 ** 0.5)
+        assert_almost_equal(norm(A, 'nuc'), 1.3366836911774836)
+        assert_almost_equal(norm(A, inf), 1.1)
+        assert_almost_equal(norm(A, -inf), 0.6)
+        assert_almost_equal(norm(A, 1), 1.0)
+        assert_almost_equal(norm(A, -1), 0.4)
+        assert_almost_equal(norm(A, 2), 0.88722940323461277)
+        assert_almost_equal(norm(A, -2), 0.19456584790481812)
+
+    def test_axis(self):
+        # Vector norms.
+        # Compare the use of `axis` with computing the norm of each row
+        # or column separately.
+        A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
+        for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]:
+            expected0 = [norm(A[:, k], ord=order) for k in range(A.shape[1])]
+            assert_almost_equal(norm(A, ord=order, axis=0), expected0)
+            expected1 = [norm(A[k, :], ord=order) for k in range(A.shape[0])]
+            assert_almost_equal(norm(A, ord=order, axis=1), expected1)
+
+        # Matrix norms.
+        B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+        nd = B.ndim
+        for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro']:
+            for axis in itertools.combinations(range(-nd, nd), 2):
+                row_axis, col_axis = axis
+                if row_axis < 0:
+                    row_axis += nd
+                if col_axis < 0:
+                    col_axis += nd
+                if row_axis == col_axis:
+                    assert_raises(ValueError, norm, B, ord=order, axis=axis)
+                else:
+                    n = norm(B, ord=order, axis=axis)
+
+                    # The logic using k_index only works for nd = 3.
+                    # This has to be changed if nd is increased.
+                    k_index = nd - (row_axis + col_axis)
+                    if row_axis < col_axis:
+                        expected = [norm(B[:].take(k, axis=k_index), ord=order)
+                                    for k in range(B.shape[k_index])]
+                    else:
+                        expected = [norm(B[:].take(k, axis=k_index).T, ord=order)
+                                    for k in range(B.shape[k_index])]
+                    assert_almost_equal(n, expected)
+
+    def test_keepdims(self):
+        A = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+
+        allclose_err = 'order {0}, axis = {1}'
+        shape_err = 'Shape mismatch found {0}, expected {1}, order={2}, axis={3}'
+
+        # check the order=None, axis=None case
+        expected = norm(A, ord=None, axis=None)
+        found = norm(A, ord=None, axis=None, keepdims=True)
+        assert_allclose(np.squeeze(found), expected,
+                        err_msg=allclose_err.format(None, None))
+        expected_shape = (1, 1, 1)
+        assert_(found.shape == expected_shape,
+                shape_err.format(found.shape, expected_shape, None, None))
+
+        # Vector norms.
+        for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]:
+            for k in range(A.ndim):
+                expected = norm(A, ord=order, axis=k)
+                found = norm(A, ord=order, axis=k, keepdims=True)
+                assert_allclose(np.squeeze(found), expected,
+                                err_msg=allclose_err.format(order, k))
+                expected_shape = list(A.shape)
+                expected_shape[k] = 1
+                expected_shape = tuple(expected_shape)
+                assert_(found.shape == expected_shape,
+                        shape_err.format(found.shape, expected_shape, order, k))
+
+        # Matrix norms.
+        for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro', 'nuc']:
+            for k in itertools.permutations(range(A.ndim), 2):
+                expected = norm(A, ord=order, axis=k)
+                found = norm(A, ord=order, axis=k, keepdims=True)
+                assert_allclose(np.squeeze(found), expected,
+                                err_msg=allclose_err.format(order, k))
+                expected_shape = list(A.shape)
+                expected_shape[k[0]] = 1
+                expected_shape[k[1]] = 1
+                expected_shape = tuple(expected_shape)
+                assert_(found.shape == expected_shape,
+                        shape_err.format(found.shape, expected_shape, order, k))
+
+    def test_bad_args(self):
+        # Check that bad arguments raise the appropriate exceptions.
+
+        A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
+        B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
+
+        # Using `axis=<integer>` or passing in a 1-D array implies vector
+        # norms are being computed, so also using `ord='fro'`
+        # or `ord='nuc'` raises a ValueError.
+        assert_raises(ValueError, norm, A, 'fro', 0)
+        assert_raises(ValueError, norm, A, 'nuc', 0)
+        assert_raises(ValueError, norm, [3, 4], 'fro', None)
+        assert_raises(ValueError, norm, [3, 4], 'nuc', None)
+
+        # Similarly, norm should raise an exception when ord is any finite
+        # number other than 1, 2, -1 or -2 when computing matrix norms.
+        for order in [0, 3]:
+            assert_raises(ValueError, norm, A, order, None)
+            assert_raises(ValueError, norm, A, order, (0, 1))
+            assert_raises(ValueError, norm, B, order, (1, 2))
+
+        # Invalid axis
+        assert_raises(ValueError, norm, B, None, 3)
+        assert_raises(ValueError, norm, B, None, (2, 3))
+        assert_raises(ValueError, norm, B, None, (0, 1, 2))
+
+
+class TestNorm_NonSystematic(object):
+
+    def test_longdouble_norm(self):
+        # Non-regression test: p-norm of longdouble would previously raise
+        # UnboundLocalError.
+        x = np.arange(10, dtype=np.longdouble)
+        old_assert_almost_equal(norm(x, ord=3), 12.65, decimal=2)
+
+    def test_intmin(self):
+        # Non-regression test: p-norm of signed integer would previously do
+        # float cast and abs in the wrong order.
+        x = np.array([-2 ** 31], dtype=np.int32)
+        old_assert_almost_equal(norm(x, ord=3), 2 ** 31, decimal=5)
+
+    def test_complex_high_ord(self):
+        # gh-4156
+        d = np.empty((2,), dtype=np.clongdouble)
+        d[0] = 6 + 7j
+        d[1] = -6 + 7j
+        res = 11.615898132184
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=10)
+        d = d.astype(np.complex128)
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=9)
+        d = d.astype(np.complex64)
+        old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=5)
+
+
+class TestNormDouble(_TestNorm):
+    dt = np.double
+    dec = 12
+
+
+class TestNormSingle(_TestNorm):
+    dt = np.float32
+    dec = 6
+
+
+class TestNormInt64(_TestNorm):
+    dt = np.int64
+    dec = 12
+
+
+class TestMatrixRank(object):
+
+    def test_matrix_rank(self):
+        # Full rank matrix
+        yield assert_equal, 4, matrix_rank(np.eye(4))
+        # rank deficient matrix
+        I = np.eye(4)
+        I[-1, -1] = 0.
+        yield assert_equal, matrix_rank(I), 3
+        # All zeros - zero rank
+        yield assert_equal, matrix_rank(np.zeros((4, 4))), 0
+        # 1 dimension - rank 1 unless all 0
+        yield assert_equal, matrix_rank([1, 0, 0, 0]), 1
+        yield assert_equal, matrix_rank(np.zeros((4,))), 0
+        # accepts array-like
+        yield assert_equal, matrix_rank([1]), 1
+        # greater than 2 dimensions raises error
+        yield assert_raises, TypeError, matrix_rank, np.zeros((2, 2, 2))
+        # works on scalar
+        yield assert_equal, matrix_rank(1), 1
+
+
+def test_reduced_rank():
+    # Test matrices with reduced rank
+    rng = np.random.RandomState(20120714)
+    for i in range(100):
+        # Make a rank deficient matrix
+        X = rng.normal(size=(40, 10))
+        X[:, 0] = X[:, 1] + X[:, 2]
+        # Assert that matrix_rank detected deficiency
+        assert_equal(matrix_rank(X), 9)
+        X[:, 3] = X[:, 4] + X[:, 5]
+        assert_equal(matrix_rank(X), 8)
+
+
+class TestQR(object):
+
+    def check_qr(self, a):
+        # This test expects the argument `a` to be an ndarray or
+        # a subclass of an ndarray of inexact type.
+        a_type = type(a)
+        a_dtype = a.dtype
+        m, n = a.shape
+        k = min(m, n)
+
+        # mode == 'complete'
+        q, r = linalg.qr(a, mode='complete')
+        assert_(q.dtype == a_dtype)
+        assert_(r.dtype == a_dtype)
+        assert_(isinstance(q, a_type))
+        assert_(isinstance(r, a_type))
+        assert_(q.shape == (m, m))
+        assert_(r.shape == (m, n))
+        assert_almost_equal(dot(q, r), a)
+        assert_almost_equal(dot(q.T.conj(), q), np.eye(m))
+        assert_almost_equal(np.triu(r), r)
+
+        # mode == 'reduced'
+        q1, r1 = linalg.qr(a, mode='reduced')
+        assert_(q1.dtype == a_dtype)
+        assert_(r1.dtype == a_dtype)
+        assert_(isinstance(q1, a_type))
+        assert_(isinstance(r1, a_type))
+        assert_(q1.shape == (m, k))
+        assert_(r1.shape == (k, n))
+        assert_almost_equal(dot(q1, r1), a)
+        assert_almost_equal(dot(q1.T.conj(), q1), np.eye(k))
+        assert_almost_equal(np.triu(r1), r1)
+
+        # mode == 'r'
+        r2 = linalg.qr(a, mode='r')
+        assert_(r2.dtype == a_dtype)
+        assert_(isinstance(r2, a_type))
+        assert_almost_equal(r2, r1)
+
+    def test_qr_empty(self):
+        a = np.zeros((0, 2))
+        assert_raises(linalg.LinAlgError, linalg.qr, a)
+
+    def test_mode_raw(self):
+        # The factorization is not unique and varies between libraries,
+        # so it is not possible to check against known values. Functional
+        # testing is a possibility, but awaits the exposure of more
+        # of the functions in lapack_lite. Consequently, this test is
+        # very limited in scope. Note that the results are in FORTRAN
+        # order, hence the h arrays are transposed.
+        a = array([[1, 2], [3, 4], [5, 6]], dtype=np.double)
+
+        # Test double
+        h, tau = linalg.qr(a, mode='raw')
+        assert_(h.dtype == np.double)
+        assert_(tau.dtype == np.double)
+        assert_(h.shape == (2, 3))
+        assert_(tau.shape == (2,))
+
+        h, tau = linalg.qr(a.T, mode='raw')
+        assert_(h.dtype == np.double)
+        assert_(tau.dtype == np.double)
+        assert_(h.shape == (3, 2))
+        assert_(tau.shape == (2,))
+
+    def test_mode_all_but_economic(self):
+        a = array([[1, 2], [3, 4]])
+        b = array([[1, 2], [3, 4], [5, 6]])
+        for dt in "fd":
+            m1 = a.astype(dt)
+            m2 = b.astype(dt)
+            self.check_qr(m1)
+            self.check_qr(m2)
+            self.check_qr(m2.T)
+            self.check_qr(matrix(m1))
+        for dt in "fd":
+            m1 = 1 + 1j * a.astype(dt)
+            m2 = 1 + 1j * b.astype(dt)
+            self.check_qr(m1)
+            self.check_qr(m2)
+            self.check_qr(m2.T)
+            self.check_qr(matrix(m1))
+
+
+def test_byteorder_check():
+    # Byte order check should pass for native order
+    if sys.byteorder == 'little':
+        native = '<'
+    else:
+        native = '>'
+
+    for dtt in (np.float32, np.float64):
+        arr = np.eye(4, dtype=dtt)
+        n_arr = arr.newbyteorder(native)
+        sw_arr = arr.newbyteorder('S').byteswap()
+        assert_equal(arr.dtype.byteorder, '=')
+        for routine in (linalg.inv, linalg.det, linalg.pinv):
+            # Normal call
+            res = routine(arr)
+            # Native but not '='
+            assert_array_equal(res, routine(n_arr))
+            # Swapped
+            assert_array_equal(res, routine(sw_arr))
+
+
+def test_generalized_raise_multiloop():
+    # It should raise an error even if the error doesn't occur in the
+    # last iteration of the ufunc inner loop
+
+    invertible = np.array([[1, 2], [3, 4]])
+    non_invertible = np.array([[1, 1], [1, 1]])
+
+    x = np.zeros([4, 4, 2, 2])[1::2]
+    x[...] = invertible
+    x[0, 0] = non_invertible
+
+    assert_raises(np.linalg.LinAlgError, np.linalg.inv, x)
+
+
+def test_xerbla_override():
+    # Check that our xerbla has been successfully linked in. If it is not,
+    # the default xerbla routine is called, which prints a message to stdout
+    # and may, or may not, abort the process depending on the LAPACK package.
+
+    XERBLA_OK = 255
+
+    try:
+        pid = os.fork()
+    except (OSError, AttributeError):
+        # fork failed, or not running on POSIX
+        raise SkipTest("Not POSIX or fork failed.")
+
+    if pid == 0:
+        # child; close i/o file handles
+        os.close(1)
+        os.close(0)
+        # Avoid producing core files.
+        import resource
+        resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
+        # These calls may abort.
+        try:
+            np.linalg.lapack_lite.xerbla()
+        except ValueError:
+            pass
+        except:
+            os._exit(os.EX_CONFIG)
+
+        try:
+            a = np.array([[1.]])
+            np.linalg.lapack_lite.dorgqr(
+                1, 1, 1, a,
+                0,  # <- invalid value
+                a, a, 0, 0)
+        except ValueError as e:
+            if "DORGQR parameter number 5" in str(e):
+                # success, reuse error code to mark success as
+                # FORTRAN STOP returns as success.
+                os._exit(XERBLA_OK)
+
+        # Did not abort, but our xerbla was not linked in.
+        os._exit(os.EX_CONFIG)
+    else:
+        # parent
+        pid, status = os.wait()
+        if os.WEXITSTATUS(status) != XERBLA_OK:
+            raise SkipTest('Numpy xerbla not linked in.')
+
+
+class TestMultiDot(object):
+
+    def test_basic_function_with_three_arguments(self):
+        # multi_dot with three arguments uses a fast hand coded algorithm to
+        # determine the optimal order. Therefore test it separately.
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+
+        assert_almost_equal(multi_dot([A, B, C]), A.dot(B).dot(C))
+        assert_almost_equal(multi_dot([A, B, C]), np.dot(A, np.dot(B, C)))
+
+    def test_basic_function_with_dynamic_programing_optimization(self):
+        # multi_dot with four or more arguments uses the dynamic programing
+        # optimization and therefore deserve a separate
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D = np.random.random((2, 1))
+        assert_almost_equal(multi_dot([A, B, C, D]), A.dot(B).dot(C).dot(D))
+
+    def test_vector_as_first_argument(self):
+        # The first argument can be 1-D
+        A1d = np.random.random(2)  # 1-D
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D = np.random.random((2, 2))
+
+        # the result should be 1-D
+        assert_equal(multi_dot([A1d, B, C, D]).shape, (2,))
+
+    def test_vector_as_last_argument(self):
+        # The last argument can be 1-D
+        A = np.random.random((6, 2))
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D1d = np.random.random(2)  # 1-D
+
+        # the result should be 1-D
+        assert_equal(multi_dot([A, B, C, D1d]).shape, (6,))
+
+    def test_vector_as_first_and_last_argument(self):
+        # The first and last arguments can be 1-D
+        A1d = np.random.random(2)  # 1-D
+        B = np.random.random((2, 6))
+        C = np.random.random((6, 2))
+        D1d = np.random.random(2)  # 1-D
+
+        # the result should be a scalar
+        assert_equal(multi_dot([A1d, B, C, D1d]).shape, ())
+
+    def test_dynamic_programming_logic(self):
+        # Test for the dynamic programming part
+        # This test is directly taken from Cormen page 376.
+        arrays = [np.random.random((30, 35)),
+                  np.random.random((35, 15)),
+                  np.random.random((15, 5)),
+                  np.random.random((5, 10)),
+                  np.random.random((10, 20)),
+                  np.random.random((20, 25))]
+        m_expected = np.array([[0., 15750., 7875., 9375., 11875., 15125.],
+                               [0.,     0., 2625., 4375.,  7125., 10500.],
+                               [0.,     0.,    0.,  750.,  2500.,  5375.],
+                               [0.,     0.,    0.,    0.,  1000.,  3500.],
+                               [0.,     0.,    0.,    0.,     0.,  5000.],
+                               [0.,     0.,    0.,    0.,     0.,     0.]])
+        s_expected = np.array([[0,  1,  1,  3,  3,  3],
+                               [0,  0,  2,  3,  3,  3],
+                               [0,  0,  0,  3,  3,  3],
+                               [0,  0,  0,  0,  4,  5],
+                               [0,  0,  0,  0,  0,  5],
+                               [0,  0,  0,  0,  0,  0]], dtype=np.int)
+        s_expected -= 1  # Cormen uses 1-based index, python does not.
+
+        s, m = _multi_dot_matrix_chain_order(arrays, return_costs=True)
+
+        # Only the upper triangular part (without the diagonal) is interesting.
+        assert_almost_equal(np.triu(s[:-1, 1:]),
+                            np.triu(s_expected[:-1, 1:]))
+        assert_almost_equal(np.triu(m), np.triu(m_expected))
+
+    def test_too_few_input_arrays(self):
+        assert_raises(ValueError, multi_dot, [])
+        assert_raises(ValueError, multi_dot, [np.random.random((3, 3))])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
new file mode 100644
index 0000000000..54a67bce3e
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
@@ -0,0 +1,95 @@
+""" Test functions for linalg module
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy import linalg, arange, float64, array, dot, transpose
+from numpy.testing import (
+    TestCase, run_module_suite, assert_equal, assert_array_equal,
+    assert_array_almost_equal, assert_array_less
+)
+
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+
+    def test_eig_build(self, level=rlevel):
+        # Ticket #652
+        rva = array([1.03221168e+02 + 0.j,
+                     -1.91843603e+01 + 0.j,
+                     -6.04004526e-01 + 15.84422474j,
+                     -6.04004526e-01 - 15.84422474j,
+                     -1.13692929e+01 + 0.j,
+                     -6.57612485e-01 + 10.41755503j,
+                     -6.57612485e-01 - 10.41755503j,
+                     1.82126812e+01 + 0.j,
+                     1.06011014e+01 + 0.j,
+                     7.80732773e+00 + 0.j,
+                     -7.65390898e-01 + 0.j,
+                     1.51971555e-15 + 0.j,
+                     -1.51308713e-15 + 0.j])
+        a = arange(13 * 13, dtype=float64)
+        a.shape = (13, 13)
+        a = a % 17
+        va, ve = linalg.eig(a)
+        va.sort()
+        rva.sort()
+        assert_array_almost_equal(va, rva)
+
+    def test_eigh_build(self, level=rlevel):
+        # Ticket 662.
+        rvals = [68.60568999, 89.57756725, 106.67185574]
+
+        cov = array([[77.70273908,   3.51489954,  15.64602427],
+                     [3.51489954,  88.97013878,  -1.07431931],
+                     [15.64602427,  -1.07431931,  98.18223512]])
+
+        vals, vecs = linalg.eigh(cov)
+        assert_array_almost_equal(vals, rvals)
+
+    def test_svd_build(self, level=rlevel):
+        # Ticket 627.
+        a = array([[0., 1.], [1., 1.], [2., 1.], [3., 1.]])
+        m, n = a.shape
+        u, s, vh = linalg.svd(a)
+
+        b = dot(transpose(u[:, n:]), a)
+
+        assert_array_almost_equal(b, np.zeros((2, 2)))
+
+    def test_norm_vector_badarg(self):
+        # Regression for #786: Froebenius norm for vectors raises
+        # TypeError.
+        self.assertRaises(ValueError, linalg.norm, array([1., 2., 3.]), 'fro')
+
+    def test_lapack_endian(self):
+        # For bug #1482
+        a = array([[5.7998084,  -2.1825367],
+                   [-2.1825367,   9.85910595]], dtype='>f8')
+        b = array(a, dtype='<f8')
+
+        ap = linalg.cholesky(a)
+        bp = linalg.cholesky(b)
+        assert_array_equal(ap, bp)
+
+    def test_large_svd_32bit(self):
+        # See gh-4442, 64bit would require very large/slow matrices.
+        x = np.eye(1000, 66)
+        np.linalg.svd(x)
+
+    def test_svd_no_uv(self):
+        # gh-4733
+        for shape in (3, 4), (4, 4), (4, 3):
+            for t in float, complex:
+                a = np.ones(shape, dtype=t)
+                w = linalg.svd(a, compute_uv=False)
+                c = np.count_nonzero(np.absolute(w) > 0.5)
+                assert_equal(c, 1)
+                assert_equal(np.linalg.matrix_rank(a), 1)
+                assert_array_less(1, np.linalg.norm(a, ord=2))
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/__init__.py
new file mode 100644
index 0000000000..af3468b01c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/__init__.py
@@ -0,0 +1,56 @@
+"""
+=============
+Masked Arrays
+=============
+
+Arrays sometimes contain invalid or missing data.  When doing operations
+on such arrays, we wish to suppress invalid values, which is the purpose masked
+arrays fulfill (an example of typical use is given below).
+
+For example, examine the following array:
+
+>>> x = np.array([2, 1, 3, np.nan, 5, 2, 3, np.nan])
+
+When we try to calculate the mean of the data, the result is undetermined:
+
+>>> np.mean(x)
+nan
+
+The mean is calculated using roughly ``np.sum(x)/len(x)``, but since
+any number added to ``NaN`` [1]_ produces ``NaN``, this doesn't work.  Enter
+masked arrays:
+
+>>> m = np.ma.masked_array(x, np.isnan(x))
+>>> m
+masked_array(data = [2.0 1.0 3.0 -- 5.0 2.0 3.0 --],
+      mask = [False False False  True False False False  True],
+      fill_value=1e+20)
+
+Here, we construct a masked array that suppress all ``NaN`` values.  We
+may now proceed to calculate the mean of the other values:
+
+>>> np.mean(m)
+2.6666666666666665
+
+.. [1] Not-a-Number, a floating point value that is the result of an
+       invalid operation.
+
+.. moduleauthor:: Pierre Gerard-Marchant
+.. moduleauthor:: Jarrod Millman
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from . import core
+from .core import *
+
+from . import extras
+from .extras import *
+
+__all__ = ['core', 'extras']
+__all__ += core.__all__
+__all__ += extras.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/bench.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/bench.py
new file mode 100644
index 0000000000..0c1ee28528
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/bench.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+import timeit
+import numpy
+
+
+###############################################################################
+#                               Global variables                              #
+###############################################################################
+
+
+# Small arrays
+xs = numpy.random.uniform(-1, 1, 6).reshape(2, 3)
+ys = numpy.random.uniform(-1, 1, 6).reshape(2, 3)
+zs = xs + 1j * ys
+m1 = [[True, False, False], [False, False, True]]
+m2 = [[True, False, True], [False, False, True]]
+nmxs = numpy.ma.array(xs, mask=m1)
+nmys = numpy.ma.array(ys, mask=m2)
+nmzs = numpy.ma.array(zs, mask=m1)
+
+# Big arrays
+xl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100)
+yl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100)
+zl = xl + 1j * yl
+maskx = xl > 0.8
+masky = yl < -0.8
+nmxl = numpy.ma.array(xl, mask=maskx)
+nmyl = numpy.ma.array(yl, mask=masky)
+nmzl = numpy.ma.array(zl, mask=maskx)
+
+
+###############################################################################
+#                                 Functions                                   #
+###############################################################################
+
+
+def timer(s, v='', nloop=500, nrep=3):
+    units = ["s", "ms", "µs", "ns"]
+    scaling = [1, 1e3, 1e6, 1e9]
+    print("%s : %-50s : " % (v, s), end=' ')
+    varnames = ["%ss,nm%ss,%sl,nm%sl" % tuple(x*4) for x in 'xyz']
+    setup = 'from __main__ import numpy, ma, %s' % ','.join(varnames)
+    Timer = timeit.Timer(stmt=s, setup=setup)
+    best = min(Timer.repeat(nrep, nloop)) / nloop
+    if best > 0.0:
+        order = min(-int(numpy.floor(numpy.log10(best)) // 3), 3)
+    else:
+        order = 3
+    print("%d loops, best of %d: %.*g %s per loop" % (nloop, nrep,
+                                                      3,
+                                                      best * scaling[order],
+                                                      units[order]))
+
+
+def compare_functions_1v(func, nloop=500,
+                       xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl):
+    funcname = func.__name__
+    print("-"*50)
+    print("%s on small arrays" % funcname)
+    module, data = "numpy.ma", "nmxs"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+
+    print("%s on large arrays" % funcname)
+    module, data = "numpy.ma", "nmxl"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+    return
+
+def compare_methods(methodname, args, vars='x', nloop=500, test=True,
+                    xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl):
+    print("-"*50)
+    print("%s on small arrays" % methodname)
+    data, ver = "nm%ss" % vars, 'numpy.ma'
+    timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop)
+
+    print("%s on large arrays" % methodname)
+    data, ver = "nm%sl" % vars, 'numpy.ma'
+    timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop)
+    return
+
+def compare_functions_2v(func, nloop=500, test=True,
+                       xs=xs, nmxs=nmxs,
+                       ys=ys, nmys=nmys,
+                       xl=xl, nmxl=nmxl,
+                       yl=yl, nmyl=nmyl):
+    funcname = func.__name__
+    print("-"*50)
+    print("%s on small arrays" % funcname)
+    module, data = "numpy.ma", "nmxs,nmys"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+
+    print("%s on large arrays" % funcname)
+    module, data = "numpy.ma", "nmxl,nmyl"
+    timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop)
+    return
+
+
+if __name__ == '__main__':
+    compare_functions_1v(numpy.sin)
+    compare_functions_1v(numpy.log)
+    compare_functions_1v(numpy.sqrt)
+
+    compare_functions_2v(numpy.multiply)
+    compare_functions_2v(numpy.divide)
+    compare_functions_2v(numpy.power)
+
+    compare_methods('ravel', '', nloop=1000)
+    compare_methods('conjugate', '', 'z', nloop=1000)
+    compare_methods('transpose', '', nloop=1000)
+    compare_methods('compressed', '', nloop=1000)
+    compare_methods('__getitem__', '0', nloop=1000)
+    compare_methods('__getitem__', '(0,0)', nloop=1000)
+    compare_methods('__getitem__', '[0,-1]', nloop=1000)
+    compare_methods('__setitem__', '0, 17', nloop=1000, test=False)
+    compare_methods('__setitem__', '(0,0), 17', nloop=1000, test=False)
+
+    print("-"*50)
+    print("__setitem__ on small arrays")
+    timer('nmxs.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma   ', nloop=10000)
+
+    print("-"*50)
+    print("__setitem__ on large arrays")
+    timer('nmxl.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma   ', nloop=10000)
+
+    print("-"*50)
+    print("where on small arrays")
+    timer('numpy.ma.where(nmxs>2,nmxs,nmys)', 'numpy.ma   ', nloop=1000)
+    print("-"*50)
+    print("where on large arrays")
+    timer('numpy.ma.where(nmxl>2,nmxl,nmyl)', 'numpy.ma   ', nloop=100)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/core.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/core.py
new file mode 100644
index 0000000000..5740771852
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/core.py
@@ -0,0 +1,7863 @@
+"""
+numpy.ma : a package to handle missing or invalid values.
+
+This package was initially written for numarray by Paul F. Dubois
+at Lawrence Livermore National Laboratory.
+In 2006, the package was completely rewritten by Pierre Gerard-Marchant
+(University of Georgia) to make the MaskedArray class a subclass of ndarray,
+and to improve support of structured arrays.
+
+
+Copyright 1999, 2000, 2001 Regents of the University of California.
+Released for unlimited redistribution.
+
+* Adapted for numpy_core 2005 by Travis Oliphant and (mainly) Paul Dubois.
+* Subclassing of the base `ndarray` 2006 by Pierre Gerard-Marchant
+  (pgmdevlist_AT_gmail_DOT_com)
+* Improvements suggested by Reggie Dugard (reggie_AT_merfinllc_DOT_com)
+
+.. moduleauthor:: Pierre Gerard-Marchant
+
+"""
+# pylint: disable-msg=E1002
+from __future__ import division, absolute_import, print_function
+
+import sys
+import warnings
+from functools import reduce
+
+import numpy as np
+import numpy.core.umath as umath
+import numpy.core.numerictypes as ntypes
+from numpy import ndarray, amax, amin, iscomplexobj, bool_, _NoValue
+from numpy import array as narray
+from numpy.lib.function_base import angle
+from numpy.compat import (
+    getargspec, formatargspec, long, basestring, unicode, bytes, sixu
+    )
+from numpy import expand_dims as n_expand_dims
+
+
+if sys.version_info[0] >= 3:
+    import pickle
+else:
+    import cPickle as pickle
+
+__all__ = [
+    'MAError', 'MaskError', 'MaskType', 'MaskedArray', 'abs', 'absolute',
+    'add', 'all', 'allclose', 'allequal', 'alltrue', 'amax', 'amin',
+    'angle', 'anom', 'anomalies', 'any', 'append', 'arange', 'arccos',
+    'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh',
+    'argmax', 'argmin', 'argsort', 'around', 'array', 'asanyarray',
+    'asarray', 'bitwise_and', 'bitwise_or', 'bitwise_xor', 'bool_', 'ceil',
+    'choose', 'clip', 'common_fill_value', 'compress', 'compressed',
+    'concatenate', 'conjugate', 'copy', 'cos', 'cosh', 'count', 'cumprod',
+    'cumsum', 'default_fill_value', 'diag', 'diagonal', 'diff', 'divide',
+    'dump', 'dumps', 'empty', 'empty_like', 'equal', 'exp', 'expand_dims',
+    'fabs', 'filled', 'fix_invalid', 'flatten_mask',
+    'flatten_structured_array', 'floor', 'floor_divide', 'fmod',
+    'frombuffer', 'fromflex', 'fromfunction', 'getdata', 'getmask',
+    'getmaskarray', 'greater', 'greater_equal', 'harden_mask', 'hypot',
+    'identity', 'ids', 'indices', 'inner', 'innerproduct', 'isMA',
+    'isMaskedArray', 'is_mask', 'is_masked', 'isarray', 'left_shift',
+    'less', 'less_equal', 'load', 'loads', 'log', 'log10', 'log2',
+    'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'make_mask',
+    'make_mask_descr', 'make_mask_none', 'mask_or', 'masked',
+    'masked_array', 'masked_equal', 'masked_greater',
+    'masked_greater_equal', 'masked_inside', 'masked_invalid',
+    'masked_less', 'masked_less_equal', 'masked_not_equal',
+    'masked_object', 'masked_outside', 'masked_print_option',
+    'masked_singleton', 'masked_values', 'masked_where', 'max', 'maximum',
+    'maximum_fill_value', 'mean', 'min', 'minimum', 'minimum_fill_value',
+    'mod', 'multiply', 'mvoid', 'ndim', 'negative', 'nomask', 'nonzero',
+    'not_equal', 'ones', 'outer', 'outerproduct', 'power', 'prod',
+    'product', 'ptp', 'put', 'putmask', 'rank', 'ravel', 'remainder',
+    'repeat', 'reshape', 'resize', 'right_shift', 'round', 'round_',
+    'set_fill_value', 'shape', 'sin', 'sinh', 'size', 'soften_mask',
+    'sometrue', 'sort', 'sqrt', 'squeeze', 'std', 'subtract', 'sum',
+    'swapaxes', 'take', 'tan', 'tanh', 'trace', 'transpose', 'true_divide',
+    'var', 'where', 'zeros',
+    ]
+
+MaskType = np.bool_
+nomask = MaskType(0)
+
+class MaskedArrayFutureWarning(FutureWarning):
+    pass
+
+
+def doc_note(initialdoc, note):
+    """
+    Adds a Notes section to an existing docstring.
+
+    """
+    if initialdoc is None:
+        return
+    if note is None:
+        return initialdoc
+    newdoc = """
+    %s
+
+    Notes
+    -----
+    %s
+    """
+    return newdoc % (initialdoc, note)
+
+
+def get_object_signature(obj):
+    """
+    Get the signature from obj
+
+    """
+    try:
+        sig = formatargspec(*getargspec(obj))
+    except TypeError:
+        sig = ''
+    return sig
+
+
+###############################################################################
+#                              Exceptions                                     #
+###############################################################################
+
+
+class MAError(Exception):
+    """
+    Class for masked array related errors.
+
+    """
+    pass
+
+
+class MaskError(MAError):
+    """
+    Class for mask related errors.
+
+    """
+    pass
+
+
+###############################################################################
+#                           Filling options                                   #
+###############################################################################
+
+
+# b: boolean - c: complex - f: floats - i: integer - O: object - S: string
+default_filler = {'b': True,
+                  'c': 1.e20 + 0.0j,
+                  'f': 1.e20,
+                  'i': 999999,
+                  'O': '?',
+                  'S': b'N/A',
+                  'u': 999999,
+                  'V': '???',
+                  'U': sixu('N/A')
+                  }
+
+# Add datetime64 and timedelta64 types
+for v in ["Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps",
+          "fs", "as"]:
+    default_filler["M8[" + v + "]"] = np.datetime64("NaT", v)
+    default_filler["m8[" + v + "]"] = np.timedelta64("NaT", v)
+
+max_filler = ntypes._minvals
+max_filler.update([(k, -np.inf) for k in [np.float32, np.float64]])
+min_filler = ntypes._maxvals
+min_filler.update([(k, +np.inf) for k in [np.float32, np.float64]])
+if 'float128' in ntypes.typeDict:
+    max_filler.update([(np.float128, -np.inf)])
+    min_filler.update([(np.float128, +np.inf)])
+
+
+def default_fill_value(obj):
+    """
+    Return the default fill value for the argument object.
+
+    The default filling value depends on the datatype of the input
+    array or the type of the input scalar:
+
+       ========  ========
+       datatype  default
+       ========  ========
+       bool      True
+       int       999999
+       float     1.e20
+       complex   1.e20+0j
+       object    '?'
+       string    'N/A'
+       ========  ========
+
+
+    Parameters
+    ----------
+    obj : ndarray, dtype or scalar
+        The array data-type or scalar for which the default fill value
+        is returned.
+
+    Returns
+    -------
+    fill_value : scalar
+        The default fill value.
+
+    Examples
+    --------
+    >>> np.ma.default_fill_value(1)
+    999999
+    >>> np.ma.default_fill_value(np.array([1.1, 2., np.pi]))
+    1e+20
+    >>> np.ma.default_fill_value(np.dtype(complex))
+    (1e+20+0j)
+
+    """
+    if hasattr(obj, 'dtype'):
+        defval = _check_fill_value(None, obj.dtype)
+    elif isinstance(obj, np.dtype):
+        if obj.subdtype:
+            defval = default_filler.get(obj.subdtype[0].kind, '?')
+        elif obj.kind in 'Mm':
+            defval = default_filler.get(obj.str[1:], '?')
+        else:
+            defval = default_filler.get(obj.kind, '?')
+    elif isinstance(obj, float):
+        defval = default_filler['f']
+    elif isinstance(obj, int) or isinstance(obj, long):
+        defval = default_filler['i']
+    elif isinstance(obj, bytes):
+        defval = default_filler['S']
+    elif isinstance(obj, unicode):
+        defval = default_filler['U']
+    elif isinstance(obj, complex):
+        defval = default_filler['c']
+    else:
+        defval = default_filler['O']
+    return defval
+
+
+def _recursive_extremum_fill_value(ndtype, extremum):
+    names = ndtype.names
+    if names:
+        deflist = []
+        for name in names:
+            fval = _recursive_extremum_fill_value(ndtype[name], extremum)
+            deflist.append(fval)
+        return tuple(deflist)
+    return extremum[ndtype]
+
+
+def minimum_fill_value(obj):
+    """
+    Return the maximum value that can be represented by the dtype of an object.
+
+    This function is useful for calculating a fill value suitable for
+    taking the minimum of an array with a given dtype.
+
+    Parameters
+    ----------
+    obj : ndarray or dtype
+        An object that can be queried for it's numeric type.
+
+    Returns
+    -------
+    val : scalar
+        The maximum representable value.
+
+    Raises
+    ------
+    TypeError
+        If `obj` isn't a suitable numeric type.
+
+    See Also
+    --------
+    maximum_fill_value : The inverse function.
+    set_fill_value : Set the filling value of a masked array.
+    MaskedArray.fill_value : Return current fill value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.int8()
+    >>> ma.minimum_fill_value(a)
+    127
+    >>> a = np.int32()
+    >>> ma.minimum_fill_value(a)
+    2147483647
+
+    An array of numeric data can also be passed.
+
+    >>> a = np.array([1, 2, 3], dtype=np.int8)
+    >>> ma.minimum_fill_value(a)
+    127
+    >>> a = np.array([1, 2, 3], dtype=np.float32)
+    >>> ma.minimum_fill_value(a)
+    inf
+
+    """
+    errmsg = "Unsuitable type for calculating minimum."
+    if hasattr(obj, 'dtype'):
+        return _recursive_extremum_fill_value(obj.dtype, min_filler)
+    elif isinstance(obj, float):
+        return min_filler[ntypes.typeDict['float_']]
+    elif isinstance(obj, int):
+        return min_filler[ntypes.typeDict['int_']]
+    elif isinstance(obj, long):
+        return min_filler[ntypes.typeDict['uint']]
+    elif isinstance(obj, np.dtype):
+        return min_filler[obj]
+    else:
+        raise TypeError(errmsg)
+
+
+def maximum_fill_value(obj):
+    """
+    Return the minimum value that can be represented by the dtype of an object.
+
+    This function is useful for calculating a fill value suitable for
+    taking the maximum of an array with a given dtype.
+
+    Parameters
+    ----------
+    obj : {ndarray, dtype}
+        An object that can be queried for it's numeric type.
+
+    Returns
+    -------
+    val : scalar
+        The minimum representable value.
+
+    Raises
+    ------
+    TypeError
+        If `obj` isn't a suitable numeric type.
+
+    See Also
+    --------
+    minimum_fill_value : The inverse function.
+    set_fill_value : Set the filling value of a masked array.
+    MaskedArray.fill_value : Return current fill value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.int8()
+    >>> ma.maximum_fill_value(a)
+    -128
+    >>> a = np.int32()
+    >>> ma.maximum_fill_value(a)
+    -2147483648
+
+    An array of numeric data can also be passed.
+
+    >>> a = np.array([1, 2, 3], dtype=np.int8)
+    >>> ma.maximum_fill_value(a)
+    -128
+    >>> a = np.array([1, 2, 3], dtype=np.float32)
+    >>> ma.maximum_fill_value(a)
+    -inf
+
+    """
+    errmsg = "Unsuitable type for calculating maximum."
+    if hasattr(obj, 'dtype'):
+        return _recursive_extremum_fill_value(obj.dtype, max_filler)
+    elif isinstance(obj, float):
+        return max_filler[ntypes.typeDict['float_']]
+    elif isinstance(obj, int):
+        return max_filler[ntypes.typeDict['int_']]
+    elif isinstance(obj, long):
+        return max_filler[ntypes.typeDict['uint']]
+    elif isinstance(obj, np.dtype):
+        return max_filler[obj]
+    else:
+        raise TypeError(errmsg)
+
+
+def _recursive_set_default_fill_value(dtypedescr):
+    deflist = []
+    for currentdescr in dtypedescr:
+        currenttype = currentdescr[1]
+        if isinstance(currenttype, list):
+            deflist.append(
+                tuple(_recursive_set_default_fill_value(currenttype)))
+        else:
+            deflist.append(default_fill_value(np.dtype(currenttype)))
+    return tuple(deflist)
+
+
+def _recursive_set_fill_value(fillvalue, dtypedescr):
+    fillvalue = np.resize(fillvalue, len(dtypedescr))
+    output_value = []
+    for (fval, descr) in zip(fillvalue, dtypedescr):
+        cdtype = descr[1]
+        if isinstance(cdtype, list):
+            output_value.append(tuple(_recursive_set_fill_value(fval, cdtype)))
+        else:
+            output_value.append(np.array(fval, dtype=cdtype).item())
+    return tuple(output_value)
+
+
+def _check_fill_value(fill_value, ndtype):
+    """
+    Private function validating the given `fill_value` for the given dtype.
+
+    If fill_value is None, it is set to the default corresponding to the dtype
+    if this latter is standard (no fields). If the datatype is flexible (named
+    fields), fill_value is set to a tuple whose elements are the default fill
+    values corresponding to each field.
+
+    If fill_value is not None, its value is forced to the given dtype.
+
+    """
+    ndtype = np.dtype(ndtype)
+    fields = ndtype.fields
+    if fill_value is None:
+        if fields:
+            descr = ndtype.descr
+            fill_value = np.array(_recursive_set_default_fill_value(descr),
+                                  dtype=ndtype,)
+        else:
+            fill_value = default_fill_value(ndtype)
+    elif fields:
+        fdtype = [(_[0], _[1]) for _ in ndtype.descr]
+        if isinstance(fill_value, (ndarray, np.void)):
+            try:
+                fill_value = np.array(fill_value, copy=False, dtype=fdtype)
+            except ValueError:
+                err_msg = "Unable to transform %s to dtype %s"
+                raise ValueError(err_msg % (fill_value, fdtype))
+        else:
+            descr = ndtype.descr
+            fill_value = np.asarray(fill_value, dtype=object)
+            fill_value = np.array(_recursive_set_fill_value(fill_value, descr),
+                                  dtype=ndtype)
+    else:
+        if isinstance(fill_value, basestring) and (ndtype.char not in 'OSVU'):
+            err_msg = "Cannot set fill value of string with array of dtype %s"
+            raise TypeError(err_msg % ndtype)
+        else:
+            # In case we want to convert 1e20 to int.
+            try:
+                fill_value = np.array(fill_value, copy=False, dtype=ndtype)
+            except OverflowError:
+                # Raise TypeError instead of OverflowError. OverflowError
+                # is seldom used, and the real problem here is that the
+                # passed fill_value is not compatible with the ndtype.
+                err_msg = "Fill value %s overflows dtype %s"
+                raise TypeError(err_msg % (fill_value, ndtype))
+    return np.array(fill_value)
+
+
+def set_fill_value(a, fill_value):
+    """
+    Set the filling value of a, if a is a masked array.
+
+    This function changes the fill value of the masked array `a` in place.
+    If `a` is not a masked array, the function returns silently, without
+    doing anything.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array.
+    fill_value : dtype
+        Filling value. A consistency test is performed to make sure
+        the value is compatible with the dtype of `a`.
+
+    Returns
+    -------
+    None
+        Nothing returned by this function.
+
+    See Also
+    --------
+    maximum_fill_value : Return the default fill value for a dtype.
+    MaskedArray.fill_value : Return current fill value.
+    MaskedArray.set_fill_value : Equivalent method.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(5)
+    >>> a
+    array([0, 1, 2, 3, 4])
+    >>> a = ma.masked_where(a < 3, a)
+    >>> a
+    masked_array(data = [-- -- -- 3 4],
+          mask = [ True  True  True False False],
+          fill_value=999999)
+    >>> ma.set_fill_value(a, -999)
+    >>> a
+    masked_array(data = [-- -- -- 3 4],
+          mask = [ True  True  True False False],
+          fill_value=-999)
+
+    Nothing happens if `a` is not a masked array.
+
+    >>> a = range(5)
+    >>> a
+    [0, 1, 2, 3, 4]
+    >>> ma.set_fill_value(a, 100)
+    >>> a
+    [0, 1, 2, 3, 4]
+    >>> a = np.arange(5)
+    >>> a
+    array([0, 1, 2, 3, 4])
+    >>> ma.set_fill_value(a, 100)
+    >>> a
+    array([0, 1, 2, 3, 4])
+
+    """
+    if isinstance(a, MaskedArray):
+        a.set_fill_value(fill_value)
+    return
+
+
+def get_fill_value(a):
+    """
+    Return the filling value of a, if any.  Otherwise, returns the
+    default filling value for that type.
+
+    """
+    if isinstance(a, MaskedArray):
+        result = a.fill_value
+    else:
+        result = default_fill_value(a)
+    return result
+
+
+def common_fill_value(a, b):
+    """
+    Return the common filling value of two masked arrays, if any.
+
+    If ``a.fill_value == b.fill_value``, return the fill value,
+    otherwise return None.
+
+    Parameters
+    ----------
+    a, b : MaskedArray
+        The masked arrays for which to compare fill values.
+
+    Returns
+    -------
+    fill_value : scalar or None
+        The common fill value, or None.
+
+    Examples
+    --------
+    >>> x = np.ma.array([0, 1.], fill_value=3)
+    >>> y = np.ma.array([0, 1.], fill_value=3)
+    >>> np.ma.common_fill_value(x, y)
+    3.0
+
+    """
+    t1 = get_fill_value(a)
+    t2 = get_fill_value(b)
+    if t1 == t2:
+        return t1
+    return None
+
+
+def filled(a, fill_value=None):
+    """
+    Return input as an array with masked data replaced by a fill value.
+
+    If `a` is not a `MaskedArray`, `a` itself is returned.
+    If `a` is a `MaskedArray` and `fill_value` is None, `fill_value` is set to
+    ``a.fill_value``.
+
+    Parameters
+    ----------
+    a : MaskedArray or array_like
+        An input object.
+    fill_value : scalar, optional
+        Filling value. Default is None.
+
+    Returns
+    -------
+    a : ndarray
+        The filled array.
+
+    See Also
+    --------
+    compressed
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
+    ...                                                   [1, 0, 0],
+    ...                                                   [0, 0, 0]])
+    >>> x.filled()
+    array([[999999,      1,      2],
+           [999999,      4,      5],
+           [     6,      7,      8]])
+
+    """
+    if hasattr(a, 'filled'):
+        return a.filled(fill_value)
+    elif isinstance(a, ndarray):
+        # Should we check for contiguity ? and a.flags['CONTIGUOUS']:
+        return a
+    elif isinstance(a, dict):
+        return np.array(a, 'O')
+    else:
+        return np.array(a)
+
+
+def get_masked_subclass(*arrays):
+    """
+    Return the youngest subclass of MaskedArray from a list of (masked) arrays.
+
+    In case of siblings, the first listed takes over.
+
+    """
+    if len(arrays) == 1:
+        arr = arrays[0]
+        if isinstance(arr, MaskedArray):
+            rcls = type(arr)
+        else:
+            rcls = MaskedArray
+    else:
+        arrcls = [type(a) for a in arrays]
+        rcls = arrcls[0]
+        if not issubclass(rcls, MaskedArray):
+            rcls = MaskedArray
+        for cls in arrcls[1:]:
+            if issubclass(cls, rcls):
+                rcls = cls
+    # Don't return MaskedConstant as result: revert to MaskedArray
+    if rcls.__name__ == 'MaskedConstant':
+        return MaskedArray
+    return rcls
+
+
+def getdata(a, subok=True):
+    """
+    Return the data of a masked array as an ndarray.
+
+    Return the data of `a` (if any) as an ndarray if `a` is a ``MaskedArray``,
+    else return `a` as a ndarray or subclass (depending on `subok`) if not.
+
+    Parameters
+    ----------
+    a : array_like
+        Input ``MaskedArray``, alternatively a ndarray or a subclass thereof.
+    subok : bool
+        Whether to force the output to be a `pure` ndarray (False) or to
+        return a subclass of ndarray if appropriate (True, default).
+
+    See Also
+    --------
+    getmask : Return the mask of a masked array, or nomask.
+    getmaskarray : Return the mask of a masked array, or full array of False.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getdata(a)
+    array([[1, 2],
+           [3, 4]])
+
+    Equivalently use the ``MaskedArray`` `data` attribute.
+
+    >>> a.data
+    array([[1, 2],
+           [3, 4]])
+
+    """
+    try:
+        data = a._data
+    except AttributeError:
+        data = np.array(a, copy=False, subok=subok)
+    if not subok:
+        return data.view(ndarray)
+    return data
+
+
+get_data = getdata
+
+
+def fix_invalid(a, mask=nomask, copy=True, fill_value=None):
+    """
+    Return input with invalid data masked and replaced by a fill value.
+
+    Invalid data means values of `nan`, `inf`, etc.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array, a (subclass of) ndarray.
+    mask : sequence, optional
+        Mask. Must be convertible to an array of booleans with the same
+        shape as `data`. True indicates a masked (i.e. invalid) data.
+    copy : bool, optional
+        Whether to use a copy of `a` (True) or to fix `a` in place (False).
+        Default is True.
+    fill_value : scalar, optional
+        Value used for fixing invalid data. Default is None, in which case
+        the ``a.fill_value`` is used.
+
+    Returns
+    -------
+    b : MaskedArray
+        The input array with invalid entries fixed.
+
+    Notes
+    -----
+    A copy is performed by default.
+
+    Examples
+    --------
+    >>> x = np.ma.array([1., -1, np.nan, np.inf], mask=[1] + [0]*3)
+    >>> x
+    masked_array(data = [-- -1.0 nan inf],
+                 mask = [ True False False False],
+           fill_value = 1e+20)
+    >>> np.ma.fix_invalid(x)
+    masked_array(data = [-- -1.0 -- --],
+                 mask = [ True False  True  True],
+           fill_value = 1e+20)
+
+    >>> fixed = np.ma.fix_invalid(x)
+    >>> fixed.data
+    array([  1.00000000e+00,  -1.00000000e+00,   1.00000000e+20,
+             1.00000000e+20])
+    >>> x.data
+    array([  1.,  -1.,  NaN,  Inf])
+
+    """
+    a = masked_array(a, copy=copy, mask=mask, subok=True)
+    invalid = np.logical_not(np.isfinite(a._data))
+    if not invalid.any():
+        return a
+    a._mask |= invalid
+    if fill_value is None:
+        fill_value = a.fill_value
+    a._data[invalid] = fill_value
+    return a
+
+
+###############################################################################
+#                                  Ufuncs                                     #
+###############################################################################
+
+
+ufunc_domain = {}
+ufunc_fills = {}
+
+
+class _DomainCheckInterval:
+    """
+    Define a valid interval, so that :
+
+    ``domain_check_interval(a,b)(x) == True`` where
+    ``x < a`` or ``x > b``.
+
+    """
+
+    def __init__(self, a, b):
+        "domain_check_interval(a,b)(x) = true where x < a or y > b"
+        if (a > b):
+            (a, b) = (b, a)
+        self.a = a
+        self.b = b
+
+    def __call__(self, x):
+        "Execute the call behavior."
+        return umath.logical_or(umath.greater(x, self.b),
+                                umath.less(x, self.a))
+
+
+class _DomainTan:
+    """
+    Define a valid interval for the `tan` function, so that:
+
+    ``domain_tan(eps) = True`` where ``abs(cos(x)) < eps``
+
+    """
+
+    def __init__(self, eps):
+        "domain_tan(eps) = true where abs(cos(x)) < eps)"
+        self.eps = eps
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less(umath.absolute(umath.cos(x)), self.eps)
+
+
+class _DomainSafeDivide:
+    """
+    Define a domain for safe division.
+
+    """
+
+    def __init__(self, tolerance=None):
+        self.tolerance = tolerance
+
+    def __call__(self, a, b):
+        # Delay the selection of the tolerance to here in order to reduce numpy
+        # import times. The calculation of these parameters is a substantial
+        # component of numpy's import time.
+        if self.tolerance is None:
+            self.tolerance = np.finfo(float).tiny
+        # don't call ma ufuncs from __array_wrap__ which would fail for scalars
+        a, b = np.asarray(a), np.asarray(b)
+        return umath.absolute(a) * self.tolerance >= umath.absolute(b)
+
+
+class _DomainGreater:
+    """
+    DomainGreater(v)(x) is True where x <= v.
+
+    """
+
+    def __init__(self, critical_value):
+        "DomainGreater(v)(x) = true where x <= v"
+        self.critical_value = critical_value
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less_equal(x, self.critical_value)
+
+
+class _DomainGreaterEqual:
+    """
+    DomainGreaterEqual(v)(x) is True where x < v.
+
+    """
+
+    def __init__(self, critical_value):
+        "DomainGreaterEqual(v)(x) = true where x < v"
+        self.critical_value = critical_value
+
+    def __call__(self, x):
+        "Executes the call behavior."
+        return umath.less(x, self.critical_value)
+
+
+class _MaskedUnaryOperation:
+    """
+    Defines masked version of unary operations, where invalid values are
+    pre-masked.
+
+    Parameters
+    ----------
+    mufunc : callable
+        The function for which to define a masked version. Made available
+        as ``_MaskedUnaryOperation.f``.
+    fill : scalar, optional
+        Filling value, default is 0.
+    domain : class instance
+        Domain for the function. Should be one of the ``_Domain*``
+        classes. Default is None.
+
+    """
+
+    def __init__(self, mufunc, fill=0, domain=None):
+        self.f = mufunc
+        self.fill = fill
+        self.domain = domain
+        self.__doc__ = getattr(mufunc, "__doc__", str(mufunc))
+        self.__name__ = getattr(mufunc, "__name__", str(mufunc))
+        ufunc_domain[mufunc] = domain
+        ufunc_fills[mufunc] = fill
+
+    def __call__(self, a, *args, **kwargs):
+        """
+        Execute the call behavior.
+
+        """
+        d = getdata(a)
+        # Deal with domain
+        if self.domain is not None:
+            # Case 1.1. : Domained function
+            with np.errstate(divide='ignore', invalid='ignore'):
+                result = self.f(d, *args, **kwargs)
+            # Make a mask
+            m = ~umath.isfinite(result)
+            m |= self.domain(d)
+            m |= getmask(a)
+        else:
+            # Case 1.2. : Function without a domain
+            # Get the result and the mask
+            result = self.f(d, *args, **kwargs)
+            m = getmask(a)
+
+        if not result.ndim:
+            # Case 2.1. : The result is scalarscalar
+            if m:
+                return masked
+            return result
+
+        if m is not nomask:
+            # Case 2.2. The result is an array
+            # We need to fill the invalid data back w/ the input Now,
+            # that's plain silly: in C, we would just skip the element and
+            # keep the original, but we do have to do it that way in Python
+
+            # In case result has a lower dtype than the inputs (as in
+            # equal)
+            try:
+                np.copyto(result, d, where=m)
+            except TypeError:
+                pass
+        # Transform to
+        masked_result = result.view(get_masked_subclass(a))
+        masked_result._mask = m
+        masked_result._update_from(a)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of %s. [Invalid values are masked]" % str(self.f)
+
+
+class _MaskedBinaryOperation:
+    """
+    Define masked version of binary operations, where invalid
+    values are pre-masked.
+
+    Parameters
+    ----------
+    mbfunc : function
+        The function for which to define a masked version. Made available
+        as ``_MaskedBinaryOperation.f``.
+    domain : class instance
+        Default domain for the function. Should be one of the ``_Domain*``
+        classes. Default is None.
+    fillx : scalar, optional
+        Filling value for the first argument, default is 0.
+    filly : scalar, optional
+        Filling value for the second argument, default is 0.
+
+    """
+
+    def __init__(self, mbfunc, fillx=0, filly=0):
+        """
+        abfunc(fillx, filly) must be defined.
+
+        abfunc(x, filly) = x for all x to enable reduce.
+
+        """
+        self.f = mbfunc
+        self.fillx = fillx
+        self.filly = filly
+        self.__doc__ = getattr(mbfunc, "__doc__", str(mbfunc))
+        self.__name__ = getattr(mbfunc, "__name__", str(mbfunc))
+        ufunc_domain[mbfunc] = None
+        ufunc_fills[mbfunc] = (fillx, filly)
+
+    def __call__(self, a, b, *args, **kwargs):
+        """
+        Execute the call behavior.
+
+        """
+        # Get the data, as ndarray
+        (da, db) = (getdata(a), getdata(b))
+        # Get the result
+        with np.errstate():
+            np.seterr(divide='ignore', invalid='ignore')
+            result = self.f(da, db, *args, **kwargs)
+        # Get the mask for the result
+        (ma, mb) = (getmask(a), getmask(b))
+        if ma is nomask:
+            if mb is nomask:
+                m = nomask
+            else:
+                m = umath.logical_or(getmaskarray(a), mb)
+        elif mb is nomask:
+            m = umath.logical_or(ma, getmaskarray(b))
+        else:
+            m = umath.logical_or(ma, mb)
+
+        # Case 1. : scalar
+        if not result.ndim:
+            if m:
+                return masked
+            return result
+
+        # Case 2. : array
+        # Revert result to da where masked
+        if m is not nomask and m.any():
+            # any errors, just abort; impossible to guarantee masked values
+            try:
+                np.copyto(result, 0, casting='unsafe', where=m)
+                # avoid using "*" since this may be overlaid
+                masked_da = umath.multiply(m, da)
+                # only add back if it can be cast safely
+                if np.can_cast(masked_da.dtype, result.dtype, casting='safe'):
+                    result += masked_da
+            except:
+                pass
+
+        # Transforms to a (subclass of) MaskedArray
+        masked_result = result.view(get_masked_subclass(a, b))
+        masked_result._mask = m
+        if isinstance(a, MaskedArray):
+            masked_result._update_from(a)
+        elif isinstance(b, MaskedArray):
+            masked_result._update_from(b)
+        return masked_result
+
+    def reduce(self, target, axis=0, dtype=None):
+        """
+        Reduce `target` along the given `axis`.
+
+        """
+        tclass = get_masked_subclass(target)
+        m = getmask(target)
+        t = filled(target, self.filly)
+        if t.shape == ():
+            t = t.reshape(1)
+            if m is not nomask:
+                m = make_mask(m, copy=1)
+                m.shape = (1,)
+
+        if m is nomask:
+            tr = self.f.reduce(t, axis)
+            mr = nomask
+        else:
+            tr = self.f.reduce(t, axis, dtype=dtype or t.dtype)
+            mr = umath.logical_and.reduce(m, axis)
+
+        if not tr.shape:
+            if mr:
+                return masked
+            else:
+                return tr
+        masked_tr = tr.view(tclass)
+        masked_tr._mask = mr
+        return masked_tr
+
+    def outer(self, a, b):
+        """
+        Return the function applied to the outer product of a and b.
+
+        """
+        (da, db) = (getdata(a), getdata(b))
+        d = self.f.outer(da, db)
+        ma = getmask(a)
+        mb = getmask(b)
+        if ma is nomask and mb is nomask:
+            m = nomask
+        else:
+            ma = getmaskarray(a)
+            mb = getmaskarray(b)
+            m = umath.logical_or.outer(ma, mb)
+        if (not m.ndim) and m:
+            return masked
+        if m is not nomask:
+            np.copyto(d, da, where=m)
+        if not d.shape:
+            return d
+        masked_d = d.view(get_masked_subclass(a, b))
+        masked_d._mask = m
+        return masked_d
+
+    def accumulate(self, target, axis=0):
+        """Accumulate `target` along `axis` after filling with y fill
+        value.
+
+        """
+        tclass = get_masked_subclass(target)
+        t = filled(target, self.filly)
+        result = self.f.accumulate(t, axis)
+        masked_result = result.view(tclass)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of " + str(self.f)
+
+
+class _DomainedBinaryOperation:
+    """
+    Define binary operations that have a domain, like divide.
+
+    They have no reduce, outer or accumulate.
+
+    Parameters
+    ----------
+    mbfunc : function
+        The function for which to define a masked version. Made available
+        as ``_DomainedBinaryOperation.f``.
+    domain : class instance
+        Default domain for the function. Should be one of the ``_Domain*``
+        classes.
+    fillx : scalar, optional
+        Filling value for the first argument, default is 0.
+    filly : scalar, optional
+        Filling value for the second argument, default is 0.
+
+    """
+
+    def __init__(self, dbfunc, domain, fillx=0, filly=0):
+        """abfunc(fillx, filly) must be defined.
+           abfunc(x, filly) = x for all x to enable reduce.
+        """
+        self.f = dbfunc
+        self.domain = domain
+        self.fillx = fillx
+        self.filly = filly
+        self.__doc__ = getattr(dbfunc, "__doc__", str(dbfunc))
+        self.__name__ = getattr(dbfunc, "__name__", str(dbfunc))
+        ufunc_domain[dbfunc] = domain
+        ufunc_fills[dbfunc] = (fillx, filly)
+
+    def __call__(self, a, b, *args, **kwargs):
+        "Execute the call behavior."
+        # Get the data
+        (da, db) = (getdata(a), getdata(b))
+        # Get the result
+        with np.errstate(divide='ignore', invalid='ignore'):
+            result = self.f(da, db, *args, **kwargs)
+        # Get the mask as a combination of the source masks and invalid
+        m = ~umath.isfinite(result)
+        m |= getmask(a)
+        m |= getmask(b)
+        # Apply the domain
+        domain = ufunc_domain.get(self.f, None)
+        if domain is not None:
+            m |= filled(domain(da, db), True)
+        # Take care of the scalar case first
+        if (not m.ndim):
+            if m:
+                return masked
+            else:
+                return result
+        # When the mask is True, put back da if possible
+        # any errors, just abort; impossible to guarantee masked values
+        try:
+            np.copyto(result, 0, casting='unsafe', where=m)
+            # avoid using "*" since this may be overlaid
+            masked_da = umath.multiply(m, da)
+            # only add back if it can be cast safely
+            if np.can_cast(masked_da.dtype, result.dtype, casting='safe'):
+                result += masked_da
+        except:
+            pass
+
+        # Transforms to a (subclass of) MaskedArray
+        masked_result = result.view(get_masked_subclass(a, b))
+        masked_result._mask = m
+        if isinstance(a, MaskedArray):
+            masked_result._update_from(a)
+        elif isinstance(b, MaskedArray):
+            masked_result._update_from(b)
+        return masked_result
+
+    def __str__(self):
+        return "Masked version of " + str(self.f)
+
+
+# Unary ufuncs
+exp = _MaskedUnaryOperation(umath.exp)
+conjugate = _MaskedUnaryOperation(umath.conjugate)
+sin = _MaskedUnaryOperation(umath.sin)
+cos = _MaskedUnaryOperation(umath.cos)
+tan = _MaskedUnaryOperation(umath.tan)
+arctan = _MaskedUnaryOperation(umath.arctan)
+arcsinh = _MaskedUnaryOperation(umath.arcsinh)
+sinh = _MaskedUnaryOperation(umath.sinh)
+cosh = _MaskedUnaryOperation(umath.cosh)
+tanh = _MaskedUnaryOperation(umath.tanh)
+abs = absolute = _MaskedUnaryOperation(umath.absolute)
+angle = _MaskedUnaryOperation(angle)  # from numpy.lib.function_base
+fabs = _MaskedUnaryOperation(umath.fabs)
+negative = _MaskedUnaryOperation(umath.negative)
+floor = _MaskedUnaryOperation(umath.floor)
+ceil = _MaskedUnaryOperation(umath.ceil)
+around = _MaskedUnaryOperation(np.round_)
+logical_not = _MaskedUnaryOperation(umath.logical_not)
+
+# Domained unary ufuncs
+sqrt = _MaskedUnaryOperation(umath.sqrt, 0.0,
+                             _DomainGreaterEqual(0.0))
+log = _MaskedUnaryOperation(umath.log, 1.0,
+                            _DomainGreater(0.0))
+log2 = _MaskedUnaryOperation(umath.log2, 1.0,
+                             _DomainGreater(0.0))
+log10 = _MaskedUnaryOperation(umath.log10, 1.0,
+                              _DomainGreater(0.0))
+tan = _MaskedUnaryOperation(umath.tan, 0.0,
+                            _DomainTan(1e-35))
+arcsin = _MaskedUnaryOperation(umath.arcsin, 0.0,
+                               _DomainCheckInterval(-1.0, 1.0))
+arccos = _MaskedUnaryOperation(umath.arccos, 0.0,
+                               _DomainCheckInterval(-1.0, 1.0))
+arccosh = _MaskedUnaryOperation(umath.arccosh, 1.0,
+                                _DomainGreaterEqual(1.0))
+arctanh = _MaskedUnaryOperation(umath.arctanh, 0.0,
+                                _DomainCheckInterval(-1.0 + 1e-15, 1.0 - 1e-15))
+
+# Binary ufuncs
+add = _MaskedBinaryOperation(umath.add)
+subtract = _MaskedBinaryOperation(umath.subtract)
+multiply = _MaskedBinaryOperation(umath.multiply, 1, 1)
+arctan2 = _MaskedBinaryOperation(umath.arctan2, 0.0, 1.0)
+equal = _MaskedBinaryOperation(umath.equal)
+equal.reduce = None
+not_equal = _MaskedBinaryOperation(umath.not_equal)
+not_equal.reduce = None
+less_equal = _MaskedBinaryOperation(umath.less_equal)
+less_equal.reduce = None
+greater_equal = _MaskedBinaryOperation(umath.greater_equal)
+greater_equal.reduce = None
+less = _MaskedBinaryOperation(umath.less)
+less.reduce = None
+greater = _MaskedBinaryOperation(umath.greater)
+greater.reduce = None
+logical_and = _MaskedBinaryOperation(umath.logical_and)
+alltrue = _MaskedBinaryOperation(umath.logical_and, 1, 1).reduce
+logical_or = _MaskedBinaryOperation(umath.logical_or)
+sometrue = logical_or.reduce
+logical_xor = _MaskedBinaryOperation(umath.logical_xor)
+bitwise_and = _MaskedBinaryOperation(umath.bitwise_and)
+bitwise_or = _MaskedBinaryOperation(umath.bitwise_or)
+bitwise_xor = _MaskedBinaryOperation(umath.bitwise_xor)
+hypot = _MaskedBinaryOperation(umath.hypot)
+
+# Domained binary ufuncs
+divide = _DomainedBinaryOperation(umath.divide, _DomainSafeDivide(), 0, 1)
+true_divide = _DomainedBinaryOperation(umath.true_divide,
+                                       _DomainSafeDivide(), 0, 1)
+floor_divide = _DomainedBinaryOperation(umath.floor_divide,
+                                        _DomainSafeDivide(), 0, 1)
+remainder = _DomainedBinaryOperation(umath.remainder,
+                                     _DomainSafeDivide(), 0, 1)
+fmod = _DomainedBinaryOperation(umath.fmod, _DomainSafeDivide(), 0, 1)
+mod = _DomainedBinaryOperation(umath.mod, _DomainSafeDivide(), 0, 1)
+
+
+###############################################################################
+#                        Mask creation functions                              #
+###############################################################################
+
+
+def _recursive_make_descr(datatype, newtype=bool_):
+    "Private function allowing recursion in make_descr."
+    # Do we have some name fields ?
+    if datatype.names:
+        descr = []
+        for name in datatype.names:
+            field = datatype.fields[name]
+            if len(field) == 3:
+                # Prepend the title to the name
+                name = (field[-1], name)
+            descr.append((name, _recursive_make_descr(field[0], newtype)))
+        return descr
+    # Is this some kind of composite a la (np.float,2)
+    elif datatype.subdtype:
+        mdescr = list(datatype.subdtype)
+        mdescr[0] = _recursive_make_descr(datatype.subdtype[0], newtype)
+        return tuple(mdescr)
+    else:
+        return newtype
+
+
+def make_mask_descr(ndtype):
+    """
+    Construct a dtype description list from a given dtype.
+
+    Returns a new dtype object, with the type of all fields in `ndtype` to a
+    boolean type. Field names are not altered.
+
+    Parameters
+    ----------
+    ndtype : dtype
+        The dtype to convert.
+
+    Returns
+    -------
+    result : dtype
+        A dtype that looks like `ndtype`, the type of all fields is boolean.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> dtype = np.dtype({'names':['foo', 'bar'],
+                          'formats':[np.float32, np.int]})
+    >>> dtype
+    dtype([('foo', '<f4'), ('bar', '<i4')])
+    >>> ma.make_mask_descr(dtype)
+    dtype([('foo', '|b1'), ('bar', '|b1')])
+    >>> ma.make_mask_descr(np.float32)
+    <type 'numpy.bool_'>
+
+    """
+    # Make sure we do have a dtype
+    if not isinstance(ndtype, np.dtype):
+        ndtype = np.dtype(ndtype)
+    return np.dtype(_recursive_make_descr(ndtype, np.bool))
+
+
+def getmask(a):
+    """
+    Return the mask of a masked array, or nomask.
+
+    Return the mask of `a` as an ndarray if `a` is a `MaskedArray` and the
+    mask is not `nomask`, else return `nomask`. To guarantee a full array
+    of booleans of the same shape as a, use `getmaskarray`.
+
+    Parameters
+    ----------
+    a : array_like
+        Input `MaskedArray` for which the mask is required.
+
+    See Also
+    --------
+    getdata : Return the data of a masked array as an ndarray.
+    getmaskarray : Return the mask of a masked array, or full array of False.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getmask(a)
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Equivalently use the `MaskedArray` `mask` attribute.
+
+    >>> a.mask
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Result when mask == `nomask`
+
+    >>> b = ma.masked_array([[1,2],[3,4]])
+    >>> b
+    masked_array(data =
+     [[1 2]
+     [3 4]],
+          mask =
+     False,
+          fill_value=999999)
+    >>> ma.nomask
+    False
+    >>> ma.getmask(b) == ma.nomask
+    True
+    >>> b.mask == ma.nomask
+    True
+
+    """
+    return getattr(a, '_mask', nomask)
+
+
+get_mask = getmask
+
+
+def getmaskarray(arr):
+    """
+    Return the mask of a masked array, or full boolean array of False.
+
+    Return the mask of `arr` as an ndarray if `arr` is a `MaskedArray` and
+    the mask is not `nomask`, else return a full boolean array of False of
+    the same shape as `arr`.
+
+    Parameters
+    ----------
+    arr : array_like
+        Input `MaskedArray` for which the mask is required.
+
+    See Also
+    --------
+    getmask : Return the mask of a masked array, or nomask.
+    getdata : Return the data of a masked array as an ndarray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_equal([[1,2],[3,4]], 2)
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+          mask =
+     [[False  True]
+     [False False]],
+          fill_value=999999)
+    >>> ma.getmaskarray(a)
+    array([[False,  True],
+           [False, False]], dtype=bool)
+
+    Result when mask == ``nomask``
+
+    >>> b = ma.masked_array([[1,2],[3,4]])
+    >>> b
+    masked_array(data =
+     [[1 2]
+     [3 4]],
+          mask =
+     False,
+          fill_value=999999)
+    >>> >ma.getmaskarray(b)
+    array([[False, False],
+           [False, False]], dtype=bool)
+
+    """
+    mask = getmask(arr)
+    if mask is nomask:
+        mask = make_mask_none(np.shape(arr), getattr(arr, 'dtype', None))
+    return mask
+
+
+def is_mask(m):
+    """
+    Return True if m is a valid, standard mask.
+
+    This function does not check the contents of the input, only that the
+    type is MaskType. In particular, this function returns False if the
+    mask has a flexible dtype.
+
+    Parameters
+    ----------
+    m : array_like
+        Array to test.
+
+    Returns
+    -------
+    result : bool
+        True if `m.dtype.type` is MaskType, False otherwise.
+
+    See Also
+    --------
+    isMaskedArray : Test whether input is an instance of MaskedArray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> m = ma.masked_equal([0, 1, 0, 2, 3], 0)
+    >>> m
+    masked_array(data = [-- 1 -- 2 3],
+          mask = [ True False  True False False],
+          fill_value=999999)
+    >>> ma.is_mask(m)
+    False
+    >>> ma.is_mask(m.mask)
+    True
+
+    Input must be an ndarray (or have similar attributes)
+    for it to be considered a valid mask.
+
+    >>> m = [False, True, False]
+    >>> ma.is_mask(m)
+    False
+    >>> m = np.array([False, True, False])
+    >>> m
+    array([False,  True, False], dtype=bool)
+    >>> ma.is_mask(m)
+    True
+
+    Arrays with complex dtypes don't return True.
+
+    >>> dtype = np.dtype({'names':['monty', 'pithon'],
+                          'formats':[np.bool, np.bool]})
+    >>> dtype
+    dtype([('monty', '|b1'), ('pithon', '|b1')])
+    >>> m = np.array([(True, False), (False, True), (True, False)],
+                     dtype=dtype)
+    >>> m
+    array([(True, False), (False, True), (True, False)],
+          dtype=[('monty', '|b1'), ('pithon', '|b1')])
+    >>> ma.is_mask(m)
+    False
+
+    """
+    try:
+        return m.dtype.type is MaskType
+    except AttributeError:
+        return False
+
+
+def make_mask(m, copy=False, shrink=True, dtype=MaskType):
+    """
+    Create a boolean mask from an array.
+
+    Return `m` as a boolean mask, creating a copy if necessary or requested.
+    The function can accept any sequence that is convertible to integers,
+    or ``nomask``.  Does not require that contents must be 0s and 1s, values
+    of 0 are interepreted as False, everything else as True.
+
+    Parameters
+    ----------
+    m : array_like
+        Potential mask.
+    copy : bool, optional
+        Whether to return a copy of `m` (True) or `m` itself (False).
+    shrink : bool, optional
+        Whether to shrink `m` to ``nomask`` if all its values are False.
+    dtype : dtype, optional
+        Data-type of the output mask. By default, the output mask has a
+        dtype of MaskType (bool). If the dtype is flexible, each field has
+        a boolean dtype. This is ignored when `m` is ``nomask``, in which
+        case ``nomask`` is always returned.
+
+    Returns
+    -------
+    result : ndarray
+        A boolean mask derived from `m`.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> m = [True, False, True, True]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+    >>> m = [1, 0, 1, 1]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+    >>> m = [1, 0, 2, -3]
+    >>> ma.make_mask(m)
+    array([ True, False,  True,  True], dtype=bool)
+
+    Effect of the `shrink` parameter.
+
+    >>> m = np.zeros(4)
+    >>> m
+    array([ 0.,  0.,  0.,  0.])
+    >>> ma.make_mask(m)
+    False
+    >>> ma.make_mask(m, shrink=False)
+    array([False, False, False, False], dtype=bool)
+
+    Using a flexible `dtype`.
+
+    >>> m = [1, 0, 1, 1]
+    >>> n = [0, 1, 0, 0]
+    >>> arr = []
+    >>> for man, mouse in zip(m, n):
+    ...     arr.append((man, mouse))
+    >>> arr
+    [(1, 0), (0, 1), (1, 0), (1, 0)]
+    >>> dtype = np.dtype({'names':['man', 'mouse'],
+                          'formats':[np.int, np.int]})
+    >>> arr = np.array(arr, dtype=dtype)
+    >>> arr
+    array([(1, 0), (0, 1), (1, 0), (1, 0)],
+          dtype=[('man', '<i4'), ('mouse', '<i4')])
+    >>> ma.make_mask(arr, dtype=dtype)
+    array([(True, False), (False, True), (True, False), (True, False)],
+          dtype=[('man', '|b1'), ('mouse', '|b1')])
+
+    """
+    if m is nomask:
+        return nomask
+    elif isinstance(m, ndarray):
+        # We won't return after this point to make sure we can shrink the mask
+        # Fill the mask in case there are missing data
+        m = filled(m, True)
+        # Make sure the input dtype is valid
+        dtype = make_mask_descr(dtype)
+        if m.dtype == dtype:
+            if copy:
+                result = m.copy()
+            else:
+                result = m
+        else:
+            result = np.array(m, dtype=dtype, copy=copy)
+    else:
+        result = np.array(filled(m, True), dtype=MaskType)
+    # Bas les masques !
+    if shrink and (not result.dtype.names) and (not result.any()):
+        return nomask
+    else:
+        return result
+
+
+def make_mask_none(newshape, dtype=None):
+    """
+    Return a boolean mask of the given shape, filled with False.
+
+    This function returns a boolean ndarray with all entries False, that can
+    be used in common mask manipulations. If a complex dtype is specified, the
+    type of each field is converted to a boolean type.
+
+    Parameters
+    ----------
+    newshape : tuple
+        A tuple indicating the shape of the mask.
+    dtype : {None, dtype}, optional
+        If None, use a MaskType instance. Otherwise, use a new datatype with
+        the same fields as `dtype`, converted to boolean types.
+
+    Returns
+    -------
+    result : ndarray
+        An ndarray of appropriate shape and dtype, filled with False.
+
+    See Also
+    --------
+    make_mask : Create a boolean mask from an array.
+    make_mask_descr : Construct a dtype description list from a given dtype.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> ma.make_mask_none((3,))
+    array([False, False, False], dtype=bool)
+
+    Defining a more complex dtype.
+
+    >>> dtype = np.dtype({'names':['foo', 'bar'],
+                          'formats':[np.float32, np.int]})
+    >>> dtype
+    dtype([('foo', '<f4'), ('bar', '<i4')])
+    >>> ma.make_mask_none((3,), dtype=dtype)
+    array([(False, False), (False, False), (False, False)],
+          dtype=[('foo', '|b1'), ('bar', '|b1')])
+
+    """
+    if dtype is None:
+        result = np.zeros(newshape, dtype=MaskType)
+    else:
+        result = np.zeros(newshape, dtype=make_mask_descr(dtype))
+    return result
+
+
+def mask_or(m1, m2, copy=False, shrink=True):
+    """
+    Combine two masks with the ``logical_or`` operator.
+
+    The result may be a view on `m1` or `m2` if the other is `nomask`
+    (i.e. False).
+
+    Parameters
+    ----------
+    m1, m2 : array_like
+        Input masks.
+    copy : bool, optional
+        If copy is False and one of the inputs is `nomask`, return a view
+        of the other input mask. Defaults to False.
+    shrink : bool, optional
+        Whether to shrink the output to `nomask` if all its values are
+        False. Defaults to True.
+
+    Returns
+    -------
+    mask : output mask
+        The result masks values that are masked in either `m1` or `m2`.
+
+    Raises
+    ------
+    ValueError
+        If `m1` and `m2` have different flexible dtypes.
+
+    Examples
+    --------
+    >>> m1 = np.ma.make_mask([0, 1, 1, 0])
+    >>> m2 = np.ma.make_mask([1, 0, 0, 0])
+    >>> np.ma.mask_or(m1, m2)
+    array([ True,  True,  True, False], dtype=bool)
+
+    """
+
+    def _recursive_mask_or(m1, m2, newmask):
+        names = m1.dtype.names
+        for name in names:
+            current1 = m1[name]
+            if current1.dtype.names:
+                _recursive_mask_or(current1, m2[name], newmask[name])
+            else:
+                umath.logical_or(current1, m2[name], newmask[name])
+        return
+
+    if (m1 is nomask) or (m1 is False):
+        dtype = getattr(m2, 'dtype', MaskType)
+        return make_mask(m2, copy=copy, shrink=shrink, dtype=dtype)
+    if (m2 is nomask) or (m2 is False):
+        dtype = getattr(m1, 'dtype', MaskType)
+        return make_mask(m1, copy=copy, shrink=shrink, dtype=dtype)
+    if m1 is m2 and is_mask(m1):
+        return m1
+    (dtype1, dtype2) = (getattr(m1, 'dtype', None), getattr(m2, 'dtype', None))
+    if (dtype1 != dtype2):
+        raise ValueError("Incompatible dtypes '%s'<>'%s'" % (dtype1, dtype2))
+    if dtype1.names:
+        newmask = np.empty_like(m1)
+        _recursive_mask_or(m1, m2, newmask)
+        return newmask
+    return make_mask(umath.logical_or(m1, m2), copy=copy, shrink=shrink)
+
+
+def flatten_mask(mask):
+    """
+    Returns a completely flattened version of the mask, where nested fields
+    are collapsed.
+
+    Parameters
+    ----------
+    mask : array_like
+        Input array, which will be interpreted as booleans.
+
+    Returns
+    -------
+    flattened_mask : ndarray of bools
+        The flattened input.
+
+    Examples
+    --------
+    >>> mask = np.array([0, 0, 1], dtype=np.bool)
+    >>> flatten_mask(mask)
+    array([False, False,  True], dtype=bool)
+
+    >>> mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
+    >>> flatten_mask(mask)
+    array([False, False, False,  True], dtype=bool)
+
+    >>> mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
+    >>> mask = np.array([(0, (0, 0)), (0, (0, 1))], dtype=mdtype)
+    >>> flatten_mask(mask)
+    array([False, False, False, False, False,  True], dtype=bool)
+
+    """
+
+    def _flatmask(mask):
+        "Flatten the mask and returns a (maybe nested) sequence of booleans."
+        mnames = mask.dtype.names
+        if mnames:
+            return [flatten_mask(mask[name]) for name in mnames]
+        else:
+            return mask
+
+    def _flatsequence(sequence):
+        "Generates a flattened version of the sequence."
+        try:
+            for element in sequence:
+                if hasattr(element, '__iter__'):
+                    for f in _flatsequence(element):
+                        yield f
+                else:
+                    yield element
+        except TypeError:
+            yield sequence
+
+    mask = np.asarray(mask)
+    flattened = _flatsequence(_flatmask(mask))
+    return np.array([_ for _ in flattened], dtype=bool)
+
+
+def _check_mask_axis(mask, axis):
+    "Check whether there are masked values along the given axis"
+    if mask is not nomask:
+        return mask.all(axis=axis)
+    return nomask
+
+
+###############################################################################
+#                             Masking functions                               #
+###############################################################################
+
+def masked_where(condition, a, copy=True):
+    """
+    Mask an array where a condition is met.
+
+    Return `a` as an array masked where `condition` is True.
+    Any masked values of `a` or `condition` are also masked in the output.
+
+    Parameters
+    ----------
+    condition : array_like
+        Masking condition.  When `condition` tests floating point values for
+        equality, consider using ``masked_values`` instead.
+    a : array_like
+        Array to mask.
+    copy : bool
+        If True (default) make a copy of `a` in the result.  If False modify
+        `a` in place and return a view.
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `a` where `condition` is True.
+
+    See Also
+    --------
+    masked_values : Mask using floating point equality.
+    masked_equal : Mask where equal to a given value.
+    masked_not_equal : Mask where `not` equal to a given value.
+    masked_less_equal : Mask where less than or equal to a given value.
+    masked_greater_equal : Mask where greater than or equal to a given value.
+    masked_less : Mask where less than a given value.
+    masked_greater : Mask where greater than a given value.
+    masked_inside : Mask inside a given interval.
+    masked_outside : Mask outside a given interval.
+    masked_invalid : Mask invalid values (NaNs or infs).
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_where(a <= 2, a)
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+
+    Mask array `b` conditional on `a`.
+
+    >>> b = ['a', 'b', 'c', 'd']
+    >>> ma.masked_where(a == 2, b)
+    masked_array(data = [a b -- d],
+          mask = [False False  True False],
+          fill_value=N/A)
+
+    Effect of the `copy` argument.
+
+    >>> c = ma.masked_where(a <= 2, a)
+    >>> c
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+    >>> c[0] = 99
+    >>> c
+    masked_array(data = [99 -- -- 3],
+          mask = [False  True  True False],
+          fill_value=999999)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> c = ma.masked_where(a <= 2, a, copy=False)
+    >>> c[0] = 99
+    >>> c
+    masked_array(data = [99 -- -- 3],
+          mask = [False  True  True False],
+          fill_value=999999)
+    >>> a
+    array([99,  1,  2,  3])
+
+    When `condition` or `a` contain masked values.
+
+    >>> a = np.arange(4)
+    >>> a = ma.masked_where(a == 2, a)
+    >>> a
+    masked_array(data = [0 1 -- 3],
+          mask = [False False  True False],
+          fill_value=999999)
+    >>> b = np.arange(4)
+    >>> b = ma.masked_where(b == 0, b)
+    >>> b
+    masked_array(data = [-- 1 2 3],
+          mask = [ True False False False],
+          fill_value=999999)
+    >>> ma.masked_where(a == 3, b)
+    masked_array(data = [-- 1 -- --],
+          mask = [ True False  True  True],
+          fill_value=999999)
+
+    """
+    # Make sure that condition is a valid standard-type mask.
+    cond = make_mask(condition)
+    a = np.array(a, copy=copy, subok=True)
+
+    (cshape, ashape) = (cond.shape, a.shape)
+    if cshape and cshape != ashape:
+        raise IndexError("Inconsistant shape between the condition and the input"
+                         " (got %s and %s)" % (cshape, ashape))
+    if hasattr(a, '_mask'):
+        cond = mask_or(cond, a._mask)
+        cls = type(a)
+    else:
+        cls = MaskedArray
+    result = a.view(cls)
+    # Assign to *.mask so that structured masks are handled correctly.
+    result.mask = cond
+    return result
+
+
+def masked_greater(x, value, copy=True):
+    """
+    Mask an array where greater than a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x > value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_greater(a, 2)
+    masked_array(data = [0 1 2 --],
+          mask = [False False False  True],
+          fill_value=999999)
+
+    """
+    return masked_where(greater(x, value), x, copy=copy)
+
+
+def masked_greater_equal(x, value, copy=True):
+    """
+    Mask an array where greater than or equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x >= value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_greater_equal(a, 2)
+    masked_array(data = [0 1 -- --],
+          mask = [False False  True  True],
+          fill_value=999999)
+
+    """
+    return masked_where(greater_equal(x, value), x, copy=copy)
+
+
+def masked_less(x, value, copy=True):
+    """
+    Mask an array where less than a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x < value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_less(a, 2)
+    masked_array(data = [-- -- 2 3],
+          mask = [ True  True False False],
+          fill_value=999999)
+
+    """
+    return masked_where(less(x, value), x, copy=copy)
+
+
+def masked_less_equal(x, value, copy=True):
+    """
+    Mask an array where less than or equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x <= value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_less_equal(a, 2)
+    masked_array(data = [-- -- -- 3],
+          mask = [ True  True  True False],
+          fill_value=999999)
+
+    """
+    return masked_where(less_equal(x, value), x, copy=copy)
+
+
+def masked_not_equal(x, value, copy=True):
+    """
+    Mask an array where `not` equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x != value).
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_not_equal(a, 2)
+    masked_array(data = [-- -- 2 --],
+          mask = [ True  True False  True],
+          fill_value=999999)
+
+    """
+    return masked_where(not_equal(x, value), x, copy=copy)
+
+
+def masked_equal(x, value, copy=True):
+    """
+    Mask an array where equal to a given value.
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = (x == value).  For floating point arrays,
+    consider using ``masked_values(x, value)``.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_values : Mask using floating point equality.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(4)
+    >>> a
+    array([0, 1, 2, 3])
+    >>> ma.masked_equal(a, 2)
+    masked_array(data = [0 1 -- 3],
+          mask = [False False  True False],
+          fill_value=999999)
+
+    """
+    output = masked_where(equal(x, value), x, copy=copy)
+    output.fill_value = value
+    return output
+
+
+def masked_inside(x, v1, v2, copy=True):
+    """
+    Mask an array inside a given interval.
+
+    Shortcut to ``masked_where``, where `condition` is True for `x` inside
+    the interval [v1,v2] (v1 <= x <= v2).  The boundaries `v1` and `v2`
+    can be given in either order.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The array `x` is prefilled with its filling value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
+    >>> ma.masked_inside(x, -0.3, 0.3)
+    masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
+          mask = [False False  True  True False False],
+          fill_value=1e+20)
+
+    The order of `v1` and `v2` doesn't matter.
+
+    >>> ma.masked_inside(x, 0.3, -0.3)
+    masked_array(data = [0.31 1.2 -- -- -0.4 -1.1],
+          mask = [False False  True  True False False],
+          fill_value=1e+20)
+
+    """
+    if v2 < v1:
+        (v1, v2) = (v2, v1)
+    xf = filled(x)
+    condition = (xf >= v1) & (xf <= v2)
+    return masked_where(condition, x, copy=copy)
+
+
+def masked_outside(x, v1, v2, copy=True):
+    """
+    Mask an array outside a given interval.
+
+    Shortcut to ``masked_where``, where `condition` is True for `x` outside
+    the interval [v1,v2] (x < v1)|(x > v2).
+    The boundaries `v1` and `v2` can be given in either order.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The array `x` is prefilled with its filling value.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1]
+    >>> ma.masked_outside(x, -0.3, 0.3)
+    masked_array(data = [-- -- 0.01 0.2 -- --],
+          mask = [ True  True False False  True  True],
+          fill_value=1e+20)
+
+    The order of `v1` and `v2` doesn't matter.
+
+    >>> ma.masked_outside(x, 0.3, -0.3)
+    masked_array(data = [-- -- 0.01 0.2 -- --],
+          mask = [ True  True False False  True  True],
+          fill_value=1e+20)
+
+    """
+    if v2 < v1:
+        (v1, v2) = (v2, v1)
+    xf = filled(x)
+    condition = (xf < v1) | (xf > v2)
+    return masked_where(condition, x, copy=copy)
+
+
+def masked_object(x, value, copy=True, shrink=True):
+    """
+    Mask the array `x` where the data are exactly equal to value.
+
+    This function is similar to `masked_values`, but only suitable
+    for object arrays: for floating point, use `masked_values` instead.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to mask
+    value : object
+        Comparison value
+    copy : {True, False}, optional
+        Whether to return a copy of `x`.
+    shrink : {True, False}, optional
+        Whether to collapse a mask full of False to nomask
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `x` where equal to `value`.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_equal : Mask where equal to a given value (integers).
+    masked_values : Mask using floating point equality.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> food = np.array(['green_eggs', 'ham'], dtype=object)
+    >>> # don't eat spoiled food
+    >>> eat = ma.masked_object(food, 'green_eggs')
+    >>> print(eat)
+    [-- ham]
+    >>> # plain ol` ham is boring
+    >>> fresh_food = np.array(['cheese', 'ham', 'pineapple'], dtype=object)
+    >>> eat = ma.masked_object(fresh_food, 'green_eggs')
+    >>> print(eat)
+    [cheese ham pineapple]
+
+    Note that `mask` is set to ``nomask`` if possible.
+
+    >>> eat
+    masked_array(data = [cheese ham pineapple],
+          mask = False,
+          fill_value=?)
+
+    """
+    if isMaskedArray(x):
+        condition = umath.equal(x._data, value)
+        mask = x._mask
+    else:
+        condition = umath.equal(np.asarray(x), value)
+        mask = nomask
+    mask = mask_or(mask, make_mask(condition, shrink=shrink))
+    return masked_array(x, mask=mask, copy=copy, fill_value=value)
+
+
+def masked_values(x, value, rtol=1e-5, atol=1e-8, copy=True, shrink=True):
+    """
+    Mask using floating point equality.
+
+    Return a MaskedArray, masked where the data in array `x` are approximately
+    equal to `value`, i.e. where the following condition is True
+
+    (abs(x - value) <= atol+rtol*abs(value))
+
+    The fill_value is set to `value` and the mask is set to ``nomask`` if
+    possible.  For integers, consider using ``masked_equal``.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to mask.
+    value : float
+        Masking value.
+    rtol : float, optional
+        Tolerance parameter.
+    atol : float, optional
+        Tolerance parameter (1e-8).
+    copy : bool, optional
+        Whether to return a copy of `x`.
+    shrink : bool, optional
+        Whether to collapse a mask full of False to ``nomask``.
+
+    Returns
+    -------
+    result : MaskedArray
+        The result of masking `x` where approximately equal to `value`.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+    masked_equal : Mask where equal to a given value (integers).
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = np.array([1, 1.1, 2, 1.1, 3])
+    >>> ma.masked_values(x, 1.1)
+    masked_array(data = [1.0 -- 2.0 -- 3.0],
+          mask = [False  True False  True False],
+          fill_value=1.1)
+
+    Note that `mask` is set to ``nomask`` if possible.
+
+    >>> ma.masked_values(x, 1.5)
+    masked_array(data = [ 1.   1.1  2.   1.1  3. ],
+          mask = False,
+          fill_value=1.5)
+
+    For integers, the fill value will be different in general to the
+    result of ``masked_equal``.
+
+    >>> x = np.arange(5)
+    >>> x
+    array([0, 1, 2, 3, 4])
+    >>> ma.masked_values(x, 2)
+    masked_array(data = [0 1 -- 3 4],
+          mask = [False False  True False False],
+          fill_value=2)
+    >>> ma.masked_equal(x, 2)
+    masked_array(data = [0 1 -- 3 4],
+          mask = [False False  True False False],
+          fill_value=999999)
+
+    """
+    mabs = umath.absolute
+    xnew = filled(x, value)
+    if issubclass(xnew.dtype.type, np.floating):
+        condition = umath.less_equal(
+            mabs(xnew - value), atol + rtol * mabs(value))
+        mask = getattr(x, '_mask', nomask)
+    else:
+        condition = umath.equal(xnew, value)
+        mask = nomask
+    mask = mask_or(mask, make_mask(condition, shrink=shrink), shrink=shrink)
+    return masked_array(xnew, mask=mask, copy=copy, fill_value=value)
+
+
+def masked_invalid(a, copy=True):
+    """
+    Mask an array where invalid values occur (NaNs or infs).
+
+    This function is a shortcut to ``masked_where``, with
+    `condition` = ~(np.isfinite(a)). Any pre-existing mask is conserved.
+    Only applies to arrays with a dtype where NaNs or infs make sense
+    (i.e. floating point types), but accepts any array_like object.
+
+    See Also
+    --------
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(5, dtype=np.float)
+    >>> a[2] = np.NaN
+    >>> a[3] = np.PINF
+    >>> a
+    array([  0.,   1.,  NaN,  Inf,   4.])
+    >>> ma.masked_invalid(a)
+    masked_array(data = [0.0 1.0 -- -- 4.0],
+          mask = [False False  True  True False],
+          fill_value=1e+20)
+
+    """
+    a = np.array(a, copy=copy, subok=True)
+    mask = getattr(a, '_mask', None)
+    if mask is not None:
+        condition = ~(np.isfinite(getdata(a)))
+        if mask is not nomask:
+            condition |= mask
+        cls = type(a)
+    else:
+        condition = ~(np.isfinite(a))
+        cls = MaskedArray
+    result = a.view(cls)
+    result._mask = condition
+    return result
+
+
+###############################################################################
+#                            Printing options                                 #
+###############################################################################
+
+
+class _MaskedPrintOption:
+    """
+    Handle the string used to represent missing data in a masked array.
+
+    """
+
+    def __init__(self, display):
+        """
+        Create the masked_print_option object.
+
+        """
+        self._display = display
+        self._enabled = True
+
+    def display(self):
+        """
+        Display the string to print for masked values.
+
+        """
+        return self._display
+
+    def set_display(self, s):
+        """
+        Set the string to print for masked values.
+
+        """
+        self._display = s
+
+    def enabled(self):
+        """
+        Is the use of the display value enabled?
+
+        """
+        return self._enabled
+
+    def enable(self, shrink=1):
+        """
+        Set the enabling shrink to `shrink`.
+
+        """
+        self._enabled = shrink
+
+    def __str__(self):
+        return str(self._display)
+
+    __repr__ = __str__
+
+# if you single index into a masked location you get this object.
+masked_print_option = _MaskedPrintOption('--')
+
+
+def _recursive_printoption(result, mask, printopt):
+    """
+    Puts printoptions in result where mask is True.
+
+    Private function allowing for recursion
+
+    """
+    names = result.dtype.names
+    for name in names:
+        (curdata, curmask) = (result[name], mask[name])
+        if curdata.dtype.names:
+            _recursive_printoption(curdata, curmask, printopt)
+        else:
+            np.copyto(curdata, printopt, where=curmask)
+    return
+
+_print_templates = dict(long_std="""\
+masked_%(name)s(data =
+ %(data)s,
+       %(nlen)s mask =
+ %(mask)s,
+ %(nlen)s fill_value = %(fill)s)
+""",
+                        short_std="""\
+masked_%(name)s(data = %(data)s,
+       %(nlen)s mask = %(mask)s,
+%(nlen)s  fill_value = %(fill)s)
+""",
+                        long_flx="""\
+masked_%(name)s(data =
+ %(data)s,
+       %(nlen)s mask =
+ %(mask)s,
+%(nlen)s  fill_value = %(fill)s,
+      %(nlen)s dtype = %(dtype)s)
+""",
+                        short_flx="""\
+masked_%(name)s(data = %(data)s,
+%(nlen)s        mask = %(mask)s,
+%(nlen)s  fill_value = %(fill)s,
+%(nlen)s       dtype = %(dtype)s)
+""")
+
+###############################################################################
+#                          MaskedArray class                                  #
+###############################################################################
+
+
+def _recursive_filled(a, mask, fill_value):
+    """
+    Recursively fill `a` with `fill_value`.
+
+    """
+    names = a.dtype.names
+    for name in names:
+        current = a[name]
+        if current.dtype.names:
+            _recursive_filled(current, mask[name], fill_value[name])
+        else:
+            np.copyto(current, fill_value[name], where=mask[name])
+
+
+def flatten_structured_array(a):
+    """
+    Flatten a structured array.
+
+    The data type of the output is chosen such that it can represent all of the
+    (nested) fields.
+
+    Parameters
+    ----------
+    a : structured array
+
+    Returns
+    -------
+    output : masked array or ndarray
+        A flattened masked array if the input is a masked array, otherwise a
+        standard ndarray.
+
+    Examples
+    --------
+    >>> ndtype = [('a', int), ('b', float)]
+    >>> a = np.array([(1, 1), (2, 2)], dtype=ndtype)
+    >>> flatten_structured_array(a)
+    array([[1., 1.],
+           [2., 2.]])
+
+    """
+
+    def flatten_sequence(iterable):
+        """
+        Flattens a compound of nested iterables.
+
+        """
+        for elm in iter(iterable):
+            if hasattr(elm, '__iter__'):
+                for f in flatten_sequence(elm):
+                    yield f
+            else:
+                yield elm
+
+    a = np.asanyarray(a)
+    inishape = a.shape
+    a = a.ravel()
+    if isinstance(a, MaskedArray):
+        out = np.array([tuple(flatten_sequence(d.item())) for d in a._data])
+        out = out.view(MaskedArray)
+        out._mask = np.array([tuple(flatten_sequence(d.item()))
+                              for d in getmaskarray(a)])
+    else:
+        out = np.array([tuple(flatten_sequence(d.item())) for d in a])
+    if len(inishape) > 1:
+        newshape = list(out.shape)
+        newshape[0] = inishape
+        out.shape = tuple(flatten_sequence(newshape))
+    return out
+
+
+def _arraymethod(funcname, onmask=True):
+    """
+    Return a class method wrapper around a basic array method.
+
+    Creates a class method which returns a masked array, where the new
+    ``_data`` array is the output of the corresponding basic method called
+    on the original ``_data``.
+
+    If `onmask` is True, the new mask is the output of the method called
+    on the initial mask. Otherwise, the new mask is just a reference
+    to the initial mask.
+
+    Parameters
+    ----------
+    funcname : str
+        Name of the function to apply on data.
+    onmask : bool
+        Whether the mask must be processed also (True) or left
+        alone (False). Default is True. Make available as `_onmask`
+        attribute.
+
+    Returns
+    -------
+    method : instancemethod
+        Class method wrapper of the specified basic array method.
+
+    """
+    def wrapped_method(self, *args, **params):
+        result = getattr(self._data, funcname)(*args, **params)
+        result = result.view(type(self))
+        result._update_from(self)
+        mask = self._mask
+        if result.ndim:
+            if not onmask:
+                result.__setmask__(mask)
+            elif mask is not nomask:
+                result.__setmask__(getattr(mask, funcname)(*args, **params))
+        else:
+            if mask.ndim and (not mask.dtype.names and mask.all()):
+                return masked
+        return result
+    methdoc = getattr(ndarray, funcname, None) or getattr(np, funcname, None)
+    if methdoc is not None:
+        wrapped_method.__doc__ = methdoc.__doc__
+    wrapped_method.__name__ = funcname
+    return wrapped_method
+
+
+class MaskedIterator(object):
+    """
+    Flat iterator object to iterate over masked arrays.
+
+    A `MaskedIterator` iterator is returned by ``x.flat`` for any masked array
+    `x`. It allows iterating over the array as if it were a 1-D array,
+    either in a for-loop or by calling its `next` method.
+
+    Iteration is done in C-contiguous style, with the last index varying the
+    fastest. The iterator can also be indexed using basic slicing or
+    advanced indexing.
+
+    See Also
+    --------
+    MaskedArray.flat : Return a flat iterator over an array.
+    MaskedArray.flatten : Returns a flattened copy of an array.
+
+    Notes
+    -----
+    `MaskedIterator` is not exported by the `ma` module. Instead of
+    instantiating a `MaskedIterator` directly, use `MaskedArray.flat`.
+
+    Examples
+    --------
+    >>> x = np.ma.array(arange(6).reshape(2, 3))
+    >>> fl = x.flat
+    >>> type(fl)
+    <class 'numpy.ma.core.MaskedIterator'>
+    >>> for item in fl:
+    ...     print(item)
+    ...
+    0
+    1
+    2
+    3
+    4
+    5
+
+    Extracting more than a single element b indexing the `MaskedIterator`
+    returns a masked array:
+
+    >>> fl[2:4]
+    masked_array(data = [2 3],
+                 mask = False,
+           fill_value = 999999)
+
+    """
+
+    def __init__(self, ma):
+        self.ma = ma
+        self.dataiter = ma._data.flat
+
+        if ma._mask is nomask:
+            self.maskiter = None
+        else:
+            self.maskiter = ma._mask.flat
+
+    def __iter__(self):
+        return self
+
+    def __getitem__(self, indx):
+        result = self.dataiter.__getitem__(indx).view(type(self.ma))
+        if self.maskiter is not None:
+            _mask = self.maskiter.__getitem__(indx)
+            if isinstance(_mask, ndarray):
+                # set shape to match that of data; this is needed for matrices
+                _mask.shape = result.shape
+                result._mask = _mask
+            elif isinstance(_mask, np.void):
+                return mvoid(result, mask=_mask, hardmask=self.ma._hardmask)
+            elif _mask:  # Just a scalar, masked
+                return masked
+        return result
+
+    # This won't work if ravel makes a copy
+    def __setitem__(self, index, value):
+        self.dataiter[index] = getdata(value)
+        if self.maskiter is not None:
+            self.maskiter[index] = getmaskarray(value)
+
+    def __next__(self):
+        """
+        Return the next value, or raise StopIteration.
+
+        Examples
+        --------
+        >>> x = np.ma.array([3, 2], mask=[0, 1])
+        >>> fl = x.flat
+        >>> fl.next()
+        3
+        >>> fl.next()
+        masked_array(data = --,
+                     mask = True,
+               fill_value = 1e+20)
+        >>> fl.next()
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          File "/home/ralf/python/numpy/numpy/ma/core.py", line 2243, in next
+            d = self.dataiter.next()
+        StopIteration
+
+        """
+        d = next(self.dataiter)
+        if self.maskiter is not None:
+            m = next(self.maskiter)
+            if isinstance(m, np.void):
+                return mvoid(d, mask=m, hardmask=self.ma._hardmask)
+            elif m:  # Just a scalar, masked
+                return masked
+        return d
+
+    next = __next__
+
+
+class MaskedArray(ndarray):
+    """
+    An array class with possibly masked values.
+
+    Masked values of True exclude the corresponding element from any
+    computation.
+
+    Construction::
+
+      x = MaskedArray(data, mask=nomask, dtype=None, copy=False, subok=True,
+                      ndmin=0, fill_value=None, keep_mask=True, hard_mask=None,
+                      shrink=True, order=None)
+
+    Parameters
+    ----------
+    data : array_like
+        Input data.
+    mask : sequence, optional
+        Mask. Must be convertible to an array of booleans with the same
+        shape as `data`. True indicates a masked (i.e. invalid) data.
+    dtype : dtype, optional
+        Data type of the output.
+        If `dtype` is None, the type of the data argument (``data.dtype``)
+        is used. If `dtype` is not None and different from ``data.dtype``,
+        a copy is performed.
+    copy : bool, optional
+        Whether to copy the input data (True), or to use a reference instead.
+        Default is False.
+    subok : bool, optional
+        Whether to return a subclass of `MaskedArray` if possible (True) or a
+        plain `MaskedArray`. Default is True.
+    ndmin : int, optional
+        Minimum number of dimensions. Default is 0.
+    fill_value : scalar, optional
+        Value used to fill in the masked values when necessary.
+        If None, a default based on the data-type is used.
+    keep_mask : bool, optional
+        Whether to combine `mask` with the mask of the input data, if any
+        (True), or to use only `mask` for the output (False). Default is True.
+    hard_mask : bool, optional
+        Whether to use a hard mask or not. With a hard mask, masked values
+        cannot be unmasked. Default is False.
+    shrink : bool, optional
+        Whether to force compression of an empty mask. Default is True.
+    order : {'C', 'F', 'A'}, optional
+        Specify the order of the array.  If order is 'C', then the array
+        will be in C-contiguous order (last-index varies the fastest).
+        If order is 'F', then the returned array will be in
+        Fortran-contiguous order (first-index varies the fastest).
+        If order is 'A' (default), then the returned array may be
+        in any order (either C-, Fortran-contiguous, or even discontiguous),
+        unless a copy is required, in which case it will be C-contiguous.
+
+    """
+
+    __array_priority__ = 15
+    _defaultmask = nomask
+    _defaulthardmask = False
+    _baseclass = ndarray
+    # Maximum number of elements per axis used when printing an array.
+    _print_width = 100
+
+    def __new__(cls, data=None, mask=nomask, dtype=None, copy=False,
+                subok=True, ndmin=0, fill_value=None, keep_mask=True,
+                hard_mask=None, shrink=True, order=None, **options):
+        """
+        Create a new masked array from scratch.
+
+        Notes
+        -----
+        A masked array can also be created by taking a .view(MaskedArray).
+
+        """
+        # Process data.
+        _data = np.array(data, dtype=dtype, copy=copy,
+                         order=order, subok=True, ndmin=ndmin)
+        _baseclass = getattr(data, '_baseclass', type(_data))
+        # Check that we're not erasing the mask.
+        if isinstance(data, MaskedArray) and (data.shape != _data.shape):
+            copy = True
+        # Careful, cls might not always be MaskedArray.
+        if not isinstance(data, cls) or not subok:
+            _data = ndarray.view(_data, cls)
+        else:
+            _data = ndarray.view(_data, type(data))
+        # Backwards compatibility w/ numpy.core.ma.
+        if hasattr(data, '_mask') and not isinstance(data, ndarray):
+            _data._mask = data._mask
+            # FIXME _sharedmask is never used.
+            _sharedmask = True
+        # Process mask.
+        # Number of named fields (or zero if none)
+        names_ = _data.dtype.names or ()
+        # Type of the mask
+        if names_:
+            mdtype = make_mask_descr(_data.dtype)
+        else:
+            mdtype = MaskType
+
+        if mask is nomask:
+            # Case 1. : no mask in input.
+            # Erase the current mask ?
+            if not keep_mask:
+                # With a reduced version
+                if shrink:
+                    _data._mask = nomask
+                # With full version
+                else:
+                    _data._mask = np.zeros(_data.shape, dtype=mdtype)
+            # Check whether we missed something
+            elif isinstance(data, (tuple, list)):
+                try:
+                    # If data is a sequence of masked array
+                    mask = np.array([getmaskarray(m) for m in data],
+                                    dtype=mdtype)
+                except ValueError:
+                    # If data is nested
+                    mask = nomask
+                # Force shrinking of the mask if needed (and possible)
+                if (mdtype == MaskType) and mask.any():
+                    _data._mask = mask
+                    _data._sharedmask = False
+            else:
+                if copy:
+                    _data._mask = _data._mask.copy()
+                    _data._sharedmask = False
+                    # Reset the shape of the original mask
+                    if getmask(data) is not nomask:
+                        data._mask.shape = data.shape
+                else:
+                    _data._sharedmask = True
+        else:
+            # Case 2. : With a mask in input.
+            # If mask is boolean, create an array of True or False
+            if mask is True and mdtype == MaskType:
+                mask = np.ones(_data.shape, dtype=mdtype)
+            elif mask is False and mdtype == MaskType:
+                mask = np.zeros(_data.shape, dtype=mdtype)
+            else:
+                # Read the mask with the current mdtype
+                try:
+                    mask = np.array(mask, copy=copy, dtype=mdtype)
+                # Or assume it's a sequence of bool/int
+                except TypeError:
+                    mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                    dtype=mdtype)
+            # Make sure the mask and the data have the same shape
+            if mask.shape != _data.shape:
+                (nd, nm) = (_data.size, mask.size)
+                if nm == 1:
+                    mask = np.resize(mask, _data.shape)
+                elif nm == nd:
+                    mask = np.reshape(mask, _data.shape)
+                else:
+                    msg = "Mask and data not compatible: data size is %i, " + \
+                          "mask size is %i."
+                    raise MaskError(msg % (nd, nm))
+                copy = True
+            # Set the mask to the new value
+            if _data._mask is nomask:
+                _data._mask = mask
+                _data._sharedmask = not copy
+            else:
+                if not keep_mask:
+                    _data._mask = mask
+                    _data._sharedmask = not copy
+                else:
+                    if names_:
+                        def _recursive_or(a, b):
+                            "do a|=b on each field of a, recursively"
+                            for name in a.dtype.names:
+                                (af, bf) = (a[name], b[name])
+                                if af.dtype.names:
+                                    _recursive_or(af, bf)
+                                else:
+                                    af |= bf
+                            return
+                        _recursive_or(_data._mask, mask)
+                    else:
+                        _data._mask = np.logical_or(mask, _data._mask)
+                    _data._sharedmask = False
+        # Update fill_value.
+        if fill_value is None:
+            fill_value = getattr(data, '_fill_value', None)
+        # But don't run the check unless we have something to check.
+        if fill_value is not None:
+            _data._fill_value = _check_fill_value(fill_value, _data.dtype)
+        # Process extra options ..
+        if hard_mask is None:
+            _data._hardmask = getattr(data, '_hardmask', False)
+        else:
+            _data._hardmask = hard_mask
+        _data._baseclass = _baseclass
+        return _data
+
+
+    def _update_from(self, obj):
+        """
+        Copies some attributes of obj to self.
+
+        """
+        if obj is not None and isinstance(obj, ndarray):
+            _baseclass = type(obj)
+        else:
+            _baseclass = ndarray
+        # We need to copy the _basedict to avoid backward propagation
+        _optinfo = {}
+        _optinfo.update(getattr(obj, '_optinfo', {}))
+        _optinfo.update(getattr(obj, '_basedict', {}))
+        if not isinstance(obj, MaskedArray):
+            _optinfo.update(getattr(obj, '__dict__', {}))
+        _dict = dict(_fill_value=getattr(obj, '_fill_value', None),
+                     _hardmask=getattr(obj, '_hardmask', False),
+                     _sharedmask=getattr(obj, '_sharedmask', False),
+                     _isfield=getattr(obj, '_isfield', False),
+                     _baseclass=getattr(obj, '_baseclass', _baseclass),
+                     _optinfo=_optinfo,
+                     _basedict=_optinfo)
+        self.__dict__.update(_dict)
+        self.__dict__.update(_optinfo)
+        return
+
+    def __array_finalize__(self, obj):
+        """
+        Finalizes the masked array.
+
+        """
+        # Get main attributes.
+        self._update_from(obj)
+
+        # We have to decide how to initialize self.mask, based on
+        # obj.mask. This is very difficult.  There might be some
+        # correspondence between the elements in the array we are being
+        # created from (= obj) and us. Or there might not. This method can
+        # be called in all kinds of places for all kinds of reasons -- could
+        # be empty_like, could be slicing, could be a ufunc, could be a view.
+        # The numpy subclassing interface simply doesn't give us any way
+        # to know, which means that at best this method will be based on
+        # guesswork and heuristics. To make things worse, there isn't even any
+        # clear consensus about what the desired behavior is. For instance,
+        # most users think that np.empty_like(marr) -- which goes via this
+        # method -- should return a masked array with an empty mask (see
+        # gh-3404 and linked discussions), but others disagree, and they have
+        # existing code which depends on empty_like returning an array that
+        # matches the input mask.
+        #
+        # Historically our algorithm was: if the template object mask had the
+        # same *number of elements* as us, then we used *it's mask object
+        # itself* as our mask, so that writes to us would also write to the
+        # original array. This is horribly broken in multiple ways.
+        #
+        # Now what we do instead is, if the template object mask has the same
+        # number of elements as us, and we do not have the same base pointer
+        # as the template object (b/c views like arr[...] should keep the same
+        # mask), then we make a copy of the template object mask and use
+        # that. This is also horribly broken but somewhat less so. Maybe.
+        if isinstance(obj, ndarray):
+            # XX: This looks like a bug -- shouldn't it check self.dtype
+            # instead?
+            if obj.dtype.names:
+                _mask = getattr(obj, '_mask',
+                                make_mask_none(obj.shape, obj.dtype))
+            else:
+                _mask = getattr(obj, '_mask', nomask)
+
+            # If self and obj point to exactly the same data, then probably
+            # self is a simple view of obj (e.g., self = obj[...]), so they
+            # should share the same mask. (This isn't 100% reliable, e.g. self
+            # could be the first row of obj, or have strange strides, but as a
+            # heuristic it's not bad.) In all other cases, we make a copy of
+            # the mask, so that future modifications to 'self' do not end up
+            # side-effecting 'obj' as well.
+            if (obj.__array_interface__["data"][0]
+                    != self.__array_interface__["data"][0]):
+                _mask = _mask.copy()
+        else:
+            _mask = nomask
+        self._mask = _mask
+        # Finalize the mask
+        if self._mask is not nomask:
+            try:
+                self._mask.shape = self.shape
+            except ValueError:
+                self._mask = nomask
+            except (TypeError, AttributeError):
+                # When _mask.shape is not writable (because it's a void)
+                pass
+        # Finalize the fill_value for structured arrays
+        if self.dtype.names:
+            if self._fill_value is None:
+                self._fill_value = _check_fill_value(None, self.dtype)
+        return
+
+    def __array_wrap__(self, obj, context=None):
+        """
+        Special hook for ufuncs.
+
+        Wraps the numpy array and sets the mask according to context.
+
+        """
+        result = obj.view(type(self))
+        result._update_from(self)
+
+        if context is not None:
+            result._mask = result._mask.copy()
+            (func, args, _) = context
+            m = reduce(mask_or, [getmaskarray(arg) for arg in args])
+            # Get the domain mask
+            domain = ufunc_domain.get(func, None)
+            if domain is not None:
+                # Take the domain, and make sure it's a ndarray
+                if len(args) > 2:
+                    d = filled(reduce(domain, args), True)
+                else:
+                    d = filled(domain(*args), True)
+                # Fill the result where the domain is wrong
+                try:
+                    # Binary domain: take the last value
+                    fill_value = ufunc_fills[func][-1]
+                except TypeError:
+                    # Unary domain: just use this one
+                    fill_value = ufunc_fills[func]
+                except KeyError:
+                    # Domain not recognized, use fill_value instead
+                    fill_value = self.fill_value
+                result = result.copy()
+                np.copyto(result, fill_value, where=d)
+                # Update the mask
+                if m is nomask:
+                    if d is not nomask:
+                        m = d
+                else:
+                    # Don't modify inplace, we risk back-propagation
+                    m = (m | d)
+            # Make sure the mask has the proper size
+            if result.shape == () and m:
+                return masked
+            else:
+                result._mask = m
+                result._sharedmask = False
+
+        return result
+
+    def view(self, dtype=None, type=None, fill_value=None):
+        """
+        Return a view of the MaskedArray data
+
+        Parameters
+        ----------
+        dtype : data-type or ndarray sub-class, optional
+            Data-type descriptor of the returned view, e.g., float32 or int16.
+            The default, None, results in the view having the same data-type
+            as `a`. As with ``ndarray.view``, dtype can also be specified as
+            an ndarray sub-class, which then specifies the type of the
+            returned object (this is equivalent to setting the ``type``
+            parameter).
+        type : Python type, optional
+            Type of the returned view, e.g., ndarray or matrix.  Again, the
+            default None results in type preservation.
+
+        Notes
+        -----
+
+        ``a.view()`` is used two different ways:
+
+        ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
+        of the array's memory with a different data-type.  This can cause a
+        reinterpretation of the bytes of memory.
+
+        ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
+        returns an instance of `ndarray_subclass` that looks at the same array
+        (same shape, dtype, etc.)  This does not cause a reinterpretation of the
+        memory.
+
+        If `fill_value` is not specified, but `dtype` is specified (and is not
+        an ndarray sub-class), the `fill_value` of the MaskedArray will be
+        reset. If neither `fill_value` nor `dtype` are specified (or if
+        `dtype` is an ndarray sub-class), then the fill value is preserved.
+        Finally, if `fill_value` is specified, but `dtype` is not, the fill
+        value is set to the specified value.
+
+        For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
+        bytes per entry than the previous dtype (for example, converting a
+        regular array to a structured array), then the behavior of the view
+        cannot be predicted just from the superficial appearance of ``a`` (shown
+        by ``print(a)``). It also depends on exactly how ``a`` is stored in
+        memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
+        defined as a slice or transpose, etc., the view may give different
+        results.
+        """
+
+        if dtype is None:
+            if type is None:
+                output = ndarray.view(self)
+            else:
+                output = ndarray.view(self, type)
+        elif type is None:
+            try:
+                if issubclass(dtype, ndarray):
+                    output = ndarray.view(self, dtype)
+                    dtype = None
+                else:
+                    output = ndarray.view(self, dtype)
+            except TypeError:
+                output = ndarray.view(self, dtype)
+        else:
+            output = ndarray.view(self, dtype, type)
+
+        # also make the mask be a view (so attr changes to the view's
+        # mask do no affect original object's mask)
+        # (especially important to avoid affecting np.masked singleton)
+        if (getattr(output, '_mask', nomask) is not nomask):
+            output._mask = output._mask.view()
+
+        # Make sure to reset the _fill_value if needed
+        if getattr(output, '_fill_value', None) is not None:
+            if fill_value is None:
+                if dtype is None:
+                    pass  # leave _fill_value as is
+                else:
+                    output._fill_value = None
+            else:
+                output.fill_value = fill_value
+        return output
+    view.__doc__ = ndarray.view.__doc__
+
+    def astype(self, newtype):
+        """
+        Returns a copy of the MaskedArray cast to given newtype.
+
+        Returns
+        -------
+        output : MaskedArray
+            A copy of self cast to input newtype.
+            The returned record shape matches self.shape.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3.1],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1.0 -- 3.1]
+         [-- 5.0 --]
+         [7.0 -- 9.0]]
+        >>> print(x.astype(int32))
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+
+        """
+        newtype = np.dtype(newtype)
+        output = self._data.astype(newtype).view(type(self))
+        output._update_from(self)
+        names = output.dtype.names
+        if names is None:
+            output._mask = self._mask.astype(bool)
+        else:
+            if self._mask is nomask:
+                output._mask = nomask
+            else:
+                output._mask = self._mask.astype([(n, bool) for n in names])
+        # Don't check _fill_value if it's None, that'll speed things up
+        if self._fill_value is not None:
+            output._fill_value = _check_fill_value(self._fill_value, newtype)
+        return output
+
+    def __getitem__(self, indx):
+        """
+        x.__getitem__(y) <==> x[y]
+
+        Return the item described by i, as a masked array.
+
+        """
+        dout = self.data[indx]
+        # We could directly use ndarray.__getitem__ on self.
+        # But then we would have to modify __array_finalize__ to prevent the
+        # mask of being reshaped if it hasn't been set up properly yet
+        # So it's easier to stick to the current version
+        _mask = self._mask
+        # Did we extract a single item?
+        if not getattr(dout, 'ndim', False):
+            # A record
+            if isinstance(dout, np.void):
+                mask = _mask[indx]
+                # We should always re-cast to mvoid, otherwise users can
+                # change masks on rows that already have masked values, but not
+                # on rows that have no masked values, which is inconsistent.
+                dout = mvoid(dout, mask=mask, hardmask=self._hardmask)
+            # Just a scalar
+            elif _mask is not nomask and _mask[indx]:
+                return masked
+        elif self.dtype.type is np.object_ and self.dtype is not dout.dtype:
+            # self contains an object array of arrays (yes, that happens).
+            # If masked, turn into a MaskedArray, with everything masked.
+            if _mask is not nomask and _mask[indx]:
+                return MaskedArray(dout, mask=True)
+        else:
+            # Force dout to MA
+            dout = dout.view(type(self))
+            # Inherit attributes from self
+            dout._update_from(self)
+            # Check the fill_value
+            if isinstance(indx, basestring):
+                if self._fill_value is not None:
+                    dout._fill_value = self._fill_value[indx]
+
+                    # If we're indexing a multidimensional field in a 
+                    # structured array (such as dtype("(2,)i2,(2,)i1")),
+                    # dimensionality goes up (M[field].ndim == M.ndim +
+                    # len(M.dtype[field].shape)).  That's fine for 
+                    # M[field] but problematic for M[field].fill_value 
+                    # which should have shape () to avoid breaking several
+                    # methods. There is no great way out, so set to
+                    # first element.  See issue #6723.
+                    if dout._fill_value.ndim > 0:
+                        if not (dout._fill_value ==
+                                dout._fill_value.flat[0]).all():
+                            warnings.warn(
+                                "Upon accessing multidimensional field "
+                                "{indx:s}, need to keep dimensionality "
+                                "of fill_value at 0. Discarding "
+                                "heterogeneous fill_value and setting "
+                                "all to {fv!s}.".format(indx=indx,
+                                    fv=dout._fill_value[0]))
+                        dout._fill_value = dout._fill_value.flat[0]
+                dout._isfield = True
+            # Update the mask if needed
+            if _mask is not nomask:
+                dout._mask = _mask[indx]
+                # set shape to match that of data; this is needed for matrices
+                dout._mask.shape = dout.shape
+                dout._sharedmask = True
+                # Note: Don't try to check for m.any(), that'll take too long
+        return dout
+
+    def __setitem__(self, indx, value):
+        """
+        x.__setitem__(i, y) <==> x[i]=y
+
+        Set item described by index. If value is masked, masks those
+        locations.
+
+        """
+        if self is masked:
+            raise MaskError('Cannot alter the masked element.')
+        _data = self._data
+        _mask = self._mask
+        if isinstance(indx, basestring):
+            _data[indx] = value
+            if _mask is nomask:
+                self._mask = _mask = make_mask_none(self.shape, self.dtype)
+            _mask[indx] = getmask(value)
+            return
+
+        _dtype = _data.dtype
+        nbfields = len(_dtype.names or ())
+
+        if value is masked:
+            # The mask wasn't set: create a full version.
+            if _mask is nomask:
+                _mask = self._mask = make_mask_none(self.shape, _dtype)
+            # Now, set the mask to its value.
+            if nbfields:
+                _mask[indx] = tuple([True] * nbfields)
+            else:
+                _mask[indx] = True
+            if not self._isfield:
+                self._sharedmask = False
+            return
+
+        # Get the _data part of the new value
+        dval = value
+        # Get the _mask part of the new value
+        mval = getattr(value, '_mask', nomask)
+        if nbfields and mval is nomask:
+            mval = tuple([False] * nbfields)
+        if _mask is nomask:
+            # Set the data, then the mask
+            _data[indx] = dval
+            if mval is not nomask:
+                _mask = self._mask = make_mask_none(self.shape, _dtype)
+                _mask[indx] = mval
+        elif not self._hardmask:
+            # Unshare the mask if necessary to avoid propagation
+            # We want to remove the unshare logic from this place in the
+            # future. Note that _sharedmask has lots of false positives.
+            if not self._isfield:
+                if self._sharedmask and not (
+                        # If no one else holds a reference (we have two
+                        # references (_mask and self._mask) -- add one for
+                        # getrefcount) and the array owns its own data
+                        # copying the mask should do nothing.
+                        (sys.getrefcount(_mask) == 3) and _mask.flags.owndata):
+                    # 2016.01.15 -- v1.11.0
+                    warnings.warn(
+                       "setting an item on a masked array which has a shared "
+                       "mask will not copy the mask and also change the "
+                       "original mask array in the future.\n"
+                       "Check the NumPy 1.11 release notes for more "
+                       "information.",
+                       MaskedArrayFutureWarning, stacklevel=2)
+                self.unshare_mask()
+                _mask = self._mask
+            # Set the data, then the mask
+            _data[indx] = dval
+            _mask[indx] = mval
+        elif hasattr(indx, 'dtype') and (indx.dtype == MaskType):
+            indx = indx * umath.logical_not(_mask)
+            _data[indx] = dval
+        else:
+            if nbfields:
+                err_msg = "Flexible 'hard' masks are not yet supported."
+                raise NotImplementedError(err_msg)
+            mindx = mask_or(_mask[indx], mval, copy=True)
+            dindx = self._data[indx]
+            if dindx.size > 1:
+                np.copyto(dindx, dval, where=~mindx)
+            elif mindx is nomask:
+                dindx = dval
+            _data[indx] = dindx
+            _mask[indx] = mindx
+        return
+
+    def __setattr__(self, attr, value):
+        super(MaskedArray, self).__setattr__(attr, value)
+        if attr == 'dtype' and self._mask is not nomask:
+            self._mask = self._mask.view(make_mask_descr(value), ndarray)
+            # Try to reset the shape of the mask (if we don't have a void)
+            # This raises a ValueError if the dtype change won't work
+            try:
+                self._mask.shape = self.shape
+            except (AttributeError, TypeError):
+                pass
+
+    def __getslice__(self, i, j):
+        """
+        x.__getslice__(i, j) <==> x[i:j]
+
+        Return the slice described by (i, j).  The use of negative indices
+        is not supported.
+
+        """
+        return self.__getitem__(slice(i, j))
+
+    def __setslice__(self, i, j, value):
+        """
+        x.__setslice__(i, j, value) <==> x[i:j]=value
+
+        Set the slice (i,j) of a to value. If value is masked, mask those
+        locations.
+
+        """
+        self.__setitem__(slice(i, j), value)
+
+    def __setmask__(self, mask, copy=False):
+        """
+        Set the mask.
+
+        """
+        idtype = self.dtype
+        current_mask = self._mask
+        if mask is masked:
+            mask = True
+
+        if (current_mask is nomask):
+            # Make sure the mask is set
+            # Just don't do anything if there's nothing to do.
+            if mask is nomask:
+                return
+            current_mask = self._mask = make_mask_none(self.shape, idtype)
+
+        if idtype.names is None:
+            # No named fields.
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                current_mask |= mask
+            # Softmask: set everything to False
+            # If it's obviously a compatible scalar, use a quick update
+            # method.
+            elif isinstance(mask, (int, float, np.bool_, np.number)):
+                current_mask[...] = mask
+            # Otherwise fall back to the slower, general purpose way.
+            else:
+                current_mask.flat = mask
+        else:
+            # Named fields w/
+            mdtype = current_mask.dtype
+            mask = np.array(mask, copy=False)
+            # Mask is a singleton
+            if not mask.ndim:
+                # It's a boolean : make a record
+                if mask.dtype.kind == 'b':
+                    mask = np.array(tuple([mask.item()] * len(mdtype)),
+                                    dtype=mdtype)
+                # It's a record: make sure the dtype is correct
+                else:
+                    mask = mask.astype(mdtype)
+            # Mask is a sequence
+            else:
+                # Make sure the new mask is a ndarray with the proper dtype
+                try:
+                    mask = np.array(mask, copy=copy, dtype=mdtype)
+                # Or assume it's a sequence of bool/int
+                except TypeError:
+                    mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                    dtype=mdtype)
+            # Hardmask: don't unmask the data
+            if self._hardmask:
+                for n in idtype.names:
+                    current_mask[n] |= mask[n]
+            # Softmask: set everything to False
+            # If it's obviously a compatible scalar, use a quick update
+            # method.
+            elif isinstance(mask, (int, float, np.bool_, np.number)):
+                current_mask[...] = mask
+            # Otherwise fall back to the slower, general purpose way.
+            else:
+                current_mask.flat = mask
+        # Reshape if needed
+        if current_mask.shape:
+            current_mask.shape = self.shape
+        return
+
+    _set_mask = __setmask__
+
+    def _get_mask(self):
+        """Return the current mask.
+
+        """
+        # We could try to force a reshape, but that wouldn't work in some
+        # cases.
+        return self._mask
+
+    mask = property(fget=_get_mask, fset=__setmask__, doc="Mask")
+
+    def _get_recordmask(self):
+        """
+        Return the mask of the records.
+
+        A record is masked when all the fields are masked.
+
+        """
+        _mask = self._mask.view(ndarray)
+        if _mask.dtype.names is None:
+            return _mask
+        return np.all(flatten_structured_array(_mask), axis=-1)
+
+    def _set_recordmask(self):
+        """
+        Return the mask of the records.
+
+        A record is masked when all the fields are masked.
+
+        """
+        raise NotImplementedError("Coming soon: setting the mask per records!")
+
+    recordmask = property(fget=_get_recordmask)
+
+    def harden_mask(self):
+        """
+        Force the mask to hard.
+
+        Whether the mask of a masked array is hard or soft is determined by
+        its `hardmask` property. `harden_mask` sets `hardmask` to True.
+
+        See Also
+        --------
+        hardmask
+
+        """
+        self._hardmask = True
+        return self
+
+    def soften_mask(self):
+        """
+        Force the mask to soft.
+
+        Whether the mask of a masked array is hard or soft is determined by
+        its `hardmask` property. `soften_mask` sets `hardmask` to False.
+
+        See Also
+        --------
+        hardmask
+
+        """
+        self._hardmask = False
+        return self
+
+    hardmask = property(fget=lambda self: self._hardmask,
+                        doc="Hardness of the mask")
+
+    def unshare_mask(self):
+        """
+        Copy the mask and set the sharedmask flag to False.
+
+        Whether the mask is shared between masked arrays can be seen from
+        the `sharedmask` property. `unshare_mask` ensures the mask is not shared.
+        A copy of the mask is only made if it was shared.
+
+        See Also
+        --------
+        sharedmask
+
+        """
+        if self._sharedmask:
+            self._mask = self._mask.copy()
+            self._sharedmask = False
+        return self
+
+    sharedmask = property(fget=lambda self: self._sharedmask,
+                          doc="Share status of the mask (read-only).")
+
+    def shrink_mask(self):
+        """
+        Reduce a mask to nomask when possible.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2 ], [3, 4]], mask=[0]*4)
+        >>> x.mask
+        array([[False, False],
+               [False, False]], dtype=bool)
+        >>> x.shrink_mask()
+        >>> x.mask
+        False
+
+        """
+        m = self._mask
+        if m.ndim and not m.any():
+            self._mask = nomask
+        return self
+
+    baseclass = property(fget=lambda self: self._baseclass,
+                         doc="Class of the underlying data (read-only).")
+
+    def _get_data(self):
+        """Return the current data, as a view of the original
+        underlying data.
+
+        """
+        return ndarray.view(self, self._baseclass)
+
+    _data = property(fget=_get_data)
+    data = property(fget=_get_data)
+
+    def _get_flat(self):
+        "Return a flat iterator."
+        return MaskedIterator(self)
+
+    def _set_flat(self, value):
+        "Set a flattened version of self to value."
+        y = self.ravel()
+        y[:] = value
+
+    flat = property(fget=_get_flat, fset=_set_flat,
+                    doc="Flat version of the array.")
+
+    def get_fill_value(self):
+        """
+        Return the filling value of the masked array.
+
+        Returns
+        -------
+        fill_value : scalar
+            The filling value.
+
+        Examples
+        --------
+        >>> for dt in [np.int32, np.int64, np.float64, np.complex128]:
+        ...     np.ma.array([0, 1], dtype=dt).get_fill_value()
+        ...
+        999999
+        999999
+        1e+20
+        (1e+20+0j)
+
+        >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
+        >>> x.get_fill_value()
+        -inf
+
+        """
+        if self._fill_value is None:
+            self._fill_value = _check_fill_value(None, self.dtype)
+        return self._fill_value[()]
+
+    def set_fill_value(self, value=None):
+        """
+        Set the filling value of the masked array.
+
+        Parameters
+        ----------
+        value : scalar, optional
+            The new filling value. Default is None, in which case a default
+            based on the data type is used.
+
+        See Also
+        --------
+        ma.set_fill_value : Equivalent function.
+
+        Examples
+        --------
+        >>> x = np.ma.array([0, 1.], fill_value=-np.inf)
+        >>> x.fill_value
+        -inf
+        >>> x.set_fill_value(np.pi)
+        >>> x.fill_value
+        3.1415926535897931
+
+        Reset to default:
+
+        >>> x.set_fill_value()
+        >>> x.fill_value
+        1e+20
+
+        """
+        target = _check_fill_value(value, self.dtype)
+        _fill_value = self._fill_value
+        if _fill_value is None:
+            # Create the attribute if it was undefined
+            self._fill_value = target
+        else:
+            # Don't overwrite the attribute, just fill it (for propagation)
+            _fill_value[()] = target
+
+    fill_value = property(fget=get_fill_value, fset=set_fill_value,
+                          doc="Filling value.")
+
+    def filled(self, fill_value=None):
+        """
+        Return a copy of self, with masked values filled with a given value.
+        **However**, if there are no masked values to fill, self will be
+        returned instead as an ndarray.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries (None by default).
+            If None, the `fill_value` attribute of the array is used instead.
+
+        Returns
+        -------
+        filled_array : ndarray
+            A copy of ``self`` with invalid entries replaced by *fill_value*
+            (be it the function argument or the attribute of ``self``), or
+            ``self`` itself as an ndarray if there are no invalid entries to
+            be replaced.
+
+        Notes
+        -----
+        The result is **not** a MaskedArray!
+
+        Examples
+        --------
+        >>> x = np.ma.array([1,2,3,4,5], mask=[0,0,1,0,1], fill_value=-999)
+        >>> x.filled()
+        array([1, 2, -999, 4, -999])
+        >>> type(x.filled())
+        <type 'numpy.ndarray'>
+
+        Subclassing is preserved. This means that if the data part of the masked
+        array is a matrix, `filled` returns a matrix:
+
+        >>> x = np.ma.array(np.matrix([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
+        >>> x.filled()
+        matrix([[     1, 999999],
+                [999999,      4]])
+
+        """
+        m = self._mask
+        if m is nomask:
+            return self._data
+
+        if fill_value is None:
+            fill_value = self.fill_value
+        else:
+            fill_value = _check_fill_value(fill_value, self.dtype)
+
+        if self is masked_singleton:
+            return np.asanyarray(fill_value)
+
+        if m.dtype.names:
+            result = self._data.copy('K')
+            _recursive_filled(result, self._mask, fill_value)
+        elif not m.any():
+            return self._data
+        else:
+            result = self._data.copy('K')
+            try:
+                np.copyto(result, fill_value, where=m)
+            except (TypeError, AttributeError):
+                fill_value = narray(fill_value, dtype=object)
+                d = result.astype(object)
+                result = np.choose(m, (d, fill_value))
+            except IndexError:
+                # ok, if scalar
+                if self._data.shape:
+                    raise
+                elif m:
+                    result = np.array(fill_value, dtype=self.dtype)
+                else:
+                    result = self._data
+        return result
+
+    def compressed(self):
+        """
+        Return all the non-masked data as a 1-D array.
+
+        Returns
+        -------
+        data : ndarray
+            A new `ndarray` holding the non-masked data is returned.
+
+        Notes
+        -----
+        The result is **not** a MaskedArray!
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.arange(5), mask=[0]*2 + [1]*3)
+        >>> x.compressed()
+        array([0, 1])
+        >>> type(x.compressed())
+        <type 'numpy.ndarray'>
+
+        """
+        data = ndarray.ravel(self._data)
+        if self._mask is not nomask:
+            data = data.compress(np.logical_not(ndarray.ravel(self._mask)))
+        return data
+
+    def compress(self, condition, axis=None, out=None):
+        """
+        Return `a` where condition is ``True``.
+
+        If condition is a `MaskedArray`, missing values are considered
+        as ``False``.
+
+        Parameters
+        ----------
+        condition : var
+            Boolean 1-d array selecting which entries to return. If len(condition)
+            is less than the size of a along the axis, then output is truncated
+            to length of condition array.
+        axis : {None, int}, optional
+            Axis along which the operation must be performed.
+        out : {None, ndarray}, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        result : MaskedArray
+            A :class:`MaskedArray` object.
+
+        Notes
+        -----
+        Please note the difference with :meth:`compressed` !
+        The output of :meth:`compress` has a mask, the output of
+        :meth:`compressed` does not.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> x.compress([1, 0, 1])
+        masked_array(data = [1 3],
+              mask = [False False],
+              fill_value=999999)
+
+        >>> x.compress([1, 0, 1], axis=1)
+        masked_array(data =
+         [[1 3]
+         [-- --]
+         [7 9]],
+              mask =
+         [[False False]
+         [ True  True]
+         [False False]],
+              fill_value=999999)
+
+        """
+        # Get the basic components
+        (_data, _mask) = (self._data, self._mask)
+
+        # Force the condition to a regular ndarray and forget the missing
+        # values.
+        condition = np.array(condition, copy=False, subok=False)
+
+        _new = _data.compress(condition, axis=axis, out=out).view(type(self))
+        _new._update_from(self)
+        if _mask is not nomask:
+            _new._mask = _mask.compress(condition, axis=axis)
+        return _new
+
+    def __str__(self):
+        """
+        String representation.
+
+        """
+        if masked_print_option.enabled():
+            f = masked_print_option
+            if self is masked:
+                return str(f)
+            m = self._mask
+            if m is nomask:
+                res = self._data
+            else:
+                if m.shape == () and m.itemsize==len(m.dtype):
+                    if m.dtype.names:
+                        m = m.view((bool, len(m.dtype)))
+                        if m.any():
+                            return str(tuple((f if _m else _d) for _d, _m in
+                                             zip(self._data.tolist(), m)))
+                        else:
+                            return str(self._data)
+                    elif m:
+                        return str(f)
+                    else:
+                        return str(self._data)
+                # convert to object array to make filled work
+                names = self.dtype.names
+                if names is None:
+                    data = self._data
+                    mask = m
+                    # For big arrays, to avoid a costly conversion to the
+                    # object dtype, extract the corners before the conversion.
+                    for axis in range(self.ndim):
+                        if data.shape[axis] > self._print_width:
+                            ind = self._print_width // 2
+                            arr = np.split(data, (ind, -ind), axis=axis)
+                            data = np.concatenate((arr[0], arr[2]), axis=axis)
+                            arr = np.split(mask, (ind, -ind), axis=axis)
+                            mask = np.concatenate((arr[0], arr[2]), axis=axis)
+                    res = data.astype("O")
+                    res.view(ndarray)[mask] = f
+                else:
+                    rdtype = _recursive_make_descr(self.dtype, "O")
+                    res = self._data.astype(rdtype)
+                    _recursive_printoption(res, m, f)
+        else:
+            res = self.filled(self.fill_value)
+        return str(res)
+
+    def __repr__(self):
+        """
+        Literal string representation.
+
+        """
+        n = len(self.shape)
+        if self._baseclass is np.ndarray:
+            name = 'array'
+        else:
+            name = self._baseclass.__name__
+
+        parameters = dict(name=name, nlen=" " * len(name),
+                          data=str(self), mask=str(self._mask),
+                          fill=str(self.fill_value), dtype=str(self.dtype))
+        if self.dtype.names:
+            if n <= 1:
+                return _print_templates['short_flx'] % parameters
+            return _print_templates['long_flx'] % parameters
+        elif n <= 1:
+            return _print_templates['short_std'] % parameters
+        return _print_templates['long_std'] % parameters
+
+    def _delegate_binop(self, other):
+        # This emulates the logic in
+        # multiarray/number.c:PyArray_GenericBinaryFunction
+        if (not isinstance(other, np.ndarray)
+                and not hasattr(other, "__numpy_ufunc__")):
+            other_priority = getattr(other, "__array_priority__", -1000000)
+            if self.__array_priority__ < other_priority:
+                return True
+        return False
+
+    def __eq__(self, other):
+        """
+        Check whether other equals self elementwise.
+
+        """
+        if self is masked:
+            return masked
+        omask = getattr(other, '_mask', nomask)
+        if omask is nomask:
+            check = self.filled(0).__eq__(other)
+            try:
+                check = check.view(type(self))
+                check._mask = self._mask
+            except AttributeError:
+                # Dang, we have a bool instead of an array: return the bool
+                return check
+        else:
+            odata = filled(other, 0)
+            check = self.filled(0).__eq__(odata).view(type(self))
+            if self._mask is nomask:
+                check._mask = omask
+            else:
+                mask = mask_or(self._mask, omask)
+                if mask.dtype.names:
+                    if mask.size > 1:
+                        axis = 1
+                    else:
+                        axis = None
+                    try:
+                        mask = mask.view((bool_, len(self.dtype))).all(axis)
+                    except ValueError:
+                        mask = np.all([[f[n].all() for n in mask.dtype.names]
+                                       for f in mask], axis=axis)
+                check._mask = mask
+        return check
+
+    def __ne__(self, other):
+        """
+        Check whether other doesn't equal self elementwise
+
+        """
+        if self is masked:
+            return masked
+        omask = getattr(other, '_mask', nomask)
+        if omask is nomask:
+            check = self.filled(0).__ne__(other)
+            try:
+                check = check.view(type(self))
+                check._mask = self._mask
+            except AttributeError:
+                # In case check is a boolean (or a numpy.bool)
+                return check
+        else:
+            odata = filled(other, 0)
+            check = self.filled(0).__ne__(odata).view(type(self))
+            if self._mask is nomask:
+                check._mask = omask
+            else:
+                mask = mask_or(self._mask, omask)
+                if mask.dtype.names:
+                    if mask.size > 1:
+                        axis = 1
+                    else:
+                        axis = None
+                    try:
+                        mask = mask.view((bool_, len(self.dtype))).all(axis)
+                    except ValueError:
+                        mask = np.all([[f[n].all() for n in mask.dtype.names]
+                                       for f in mask], axis=axis)
+                check._mask = mask
+        return check
+
+    def __add__(self, other):
+        """
+        Add self to other, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return add(self, other)
+
+    def __radd__(self, other):
+        """
+        Add other to self, and return a new masked array.
+
+        """
+        # In analogy with __rsub__ and __rdiv__, use original order:
+        # we get here from `other + self`.
+        return add(other, self)
+
+    def __sub__(self, other):
+        """
+        Subtract other from self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return subtract(self, other)
+
+    def __rsub__(self, other):
+        """
+        Subtract self from other, and return a new masked array.
+
+        """
+        return subtract(other, self)
+
+    def __mul__(self, other):
+        "Multiply self by other, and return a new masked array."
+        if self._delegate_binop(other):
+            return NotImplemented
+        return multiply(self, other)
+
+    def __rmul__(self, other):
+        """
+        Multiply other by self, and return a new masked array.
+
+        """
+        # In analogy with __rsub__ and __rdiv__, use original order:
+        # we get here from `other * self`.
+        return multiply(other, self)
+
+    def __div__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return divide(self, other)
+
+    def __truediv__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return true_divide(self, other)
+
+    def __rtruediv__(self, other):
+        """
+        Divide self into other, and return a new masked array.
+
+        """
+        return true_divide(other, self)
+
+    def __floordiv__(self, other):
+        """
+        Divide other into self, and return a new masked array.
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return floor_divide(self, other)
+
+    def __rfloordiv__(self, other):
+        """
+        Divide self into other, and return a new masked array.
+
+        """
+        return floor_divide(other, self)
+
+    def __pow__(self, other):
+        """
+        Raise self to the power other, masking the potential NaNs/Infs
+
+        """
+        if self._delegate_binop(other):
+            return NotImplemented
+        return power(self, other)
+
+    def __rpow__(self, other):
+        """
+        Raise other to the power self, masking the potential NaNs/Infs
+
+        """
+        return power(other, self)
+
+    def __iadd__(self, other):
+        """
+        Add other to self in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        else:
+            if m is not nomask:
+                self._mask += m
+        self._data.__iadd__(np.where(self._mask, self.dtype.type(0),
+                                     getdata(other)))
+        return self
+
+    def __isub__(self, other):
+        """
+        Subtract other from self in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        elif m is not nomask:
+            self._mask += m
+        self._data.__isub__(np.where(self._mask, self.dtype.type(0),
+                                     getdata(other)))
+        return self
+
+    def __imul__(self, other):
+        """
+        Multiply self by other in-place.
+
+        """
+        m = getmask(other)
+        if self._mask is nomask:
+            if m is not nomask and m.any():
+                self._mask = make_mask_none(self.shape, self.dtype)
+                self._mask += m
+        elif m is not nomask:
+            self._mask += m
+        self._data.__imul__(np.where(self._mask, self.dtype.type(1),
+                                     getdata(other)))
+        return self
+
+    def __idiv__(self, other):
+        """
+        Divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__idiv__(np.where(self._mask, self.dtype.type(1),
+                                     other_data))
+        return self
+
+    def __ifloordiv__(self, other):
+        """
+        Floor divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.floor_divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__ifloordiv__(np.where(self._mask, self.dtype.type(1),
+                                          other_data))
+        return self
+
+    def __itruediv__(self, other):
+        """
+        True divide self by other in-place.
+
+        """
+        other_data = getdata(other)
+        dom_mask = _DomainSafeDivide().__call__(self._data, other_data)
+        other_mask = getmask(other)
+        new_mask = mask_or(other_mask, dom_mask)
+        # The following 3 lines control the domain filling
+        if dom_mask.any():
+            (_, fval) = ufunc_fills[np.true_divide]
+            other_data = np.where(dom_mask, fval, other_data)
+        self._mask |= new_mask
+        self._data.__itruediv__(np.where(self._mask, self.dtype.type(1),
+                                         other_data))
+        return self
+
+    def __ipow__(self, other):
+        """
+        Raise self to the power other, in place.
+
+        """
+        other_data = getdata(other)
+        other_mask = getmask(other)
+        with np.errstate(divide='ignore', invalid='ignore'):
+            self._data.__ipow__(np.where(self._mask, self.dtype.type(1),
+                                         other_data))
+        invalid = np.logical_not(np.isfinite(self._data))
+        if invalid.any():
+            if self._mask is not nomask:
+                self._mask |= invalid
+            else:
+                self._mask = invalid
+            np.copyto(self._data, self.fill_value, where=invalid)
+        new_mask = mask_or(other_mask, invalid)
+        self._mask = mask_or(self._mask, new_mask)
+        return self
+
+    def __float__(self):
+        """
+        Convert to float.
+
+        """
+        if self.size > 1:
+            raise TypeError("Only length-1 arrays can be converted "
+                            "to Python scalars")
+        elif self._mask:
+            warnings.warn("Warning: converting a masked element to nan.")
+            return np.nan
+        return float(self.item())
+
+    def __int__(self):
+        """
+        Convert to int.
+
+        """
+        if self.size > 1:
+            raise TypeError("Only length-1 arrays can be converted "
+                            "to Python scalars")
+        elif self._mask:
+            raise MaskError('Cannot convert masked element to a Python int.')
+        return int(self.item())
+
+    def get_imag(self):
+        """
+        Return the imaginary part of the masked array.
+
+        The returned array is a view on the imaginary part of the `MaskedArray`
+        whose `get_imag` method is called.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        result : MaskedArray
+            The imaginary part of the masked array.
+
+        See Also
+        --------
+        get_real, real, imag
+
+        Examples
+        --------
+        >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
+        >>> x.get_imag()
+        masked_array(data = [1.0 -- 1.6],
+                     mask = [False  True False],
+               fill_value = 1e+20)
+
+        """
+        result = self._data.imag.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    imag = property(fget=get_imag, doc="Imaginary part.")
+
+    def get_real(self):
+        """
+        Return the real part of the masked array.
+
+        The returned array is a view on the real part of the `MaskedArray`
+        whose `get_real` method is called.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        result : MaskedArray
+            The real part of the masked array.
+
+        See Also
+        --------
+        get_imag, real, imag
+
+        Examples
+        --------
+        >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False])
+        >>> x.get_real()
+        masked_array(data = [1.0 -- 3.45],
+                     mask = [False  True False],
+               fill_value = 1e+20)
+
+        """
+        result = self._data.real.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+    real = property(fget=get_real, doc="Real part")
+
+    def count(self, axis=None):
+        """
+        Count the non-masked elements of the array along the given axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which to count the non-masked elements. If `axis` is
+            `None`, all non-masked elements are counted.
+
+        Returns
+        -------
+        result : int or ndarray
+            If `axis` is `None`, an integer count is returned. When `axis` is
+            not `None`, an array with shape determined by the lengths of the
+            remaining axes, is returned.
+
+        See Also
+        --------
+        count_masked : Count masked elements in array or along a given axis.
+
+        Examples
+        --------
+        >>> import numpy.ma as ma
+        >>> a = ma.arange(6).reshape((2, 3))
+        >>> a[1, :] = ma.masked
+        >>> a
+        masked_array(data =
+         [[0 1 2]
+         [-- -- --]],
+                     mask =
+         [[False False False]
+         [ True  True  True]],
+               fill_value = 999999)
+        >>> a.count()
+        3
+
+        When the `axis` keyword is specified an array of appropriate size is
+        returned.
+
+        >>> a.count(axis=0)
+        array([1, 1, 1])
+        >>> a.count(axis=1)
+        array([3, 0])
+
+        """
+        m = self._mask
+        s = self.shape
+        if m is nomask:
+            if axis is None:
+                return self.size
+            else:
+                n = s[axis]
+                t = list(s)
+                del t[axis]
+                return np.full(t, n, dtype=np.intp)
+        n1 = np.size(m, axis)
+        n2 = np.sum(m, axis=axis, dtype=np.intp)
+        if axis is None:
+            return (n1 - n2)
+        else:
+            return narray(n1 - n2)
+
+    flatten = _arraymethod('flatten')
+
+    def ravel(self, order='C'):
+        """
+        Returns a 1D version of self, as a view.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            The elements of `a` are read using this index order. 'C' means to
+            index the elements in C-like order, with the last axis index
+            changing fastest, back to the first axis index changing slowest.
+            'F' means to index the elements in Fortran-like index order, with
+            the first index changing fastest, and the last index changing
+            slowest. Note that the 'C' and 'F' options take no account of the
+            memory layout of the underlying array, and only refer to the order
+            of axis indexing.  'A' means to read the elements in Fortran-like
+            index order if `m` is Fortran *contiguous* in memory, C-like order
+            otherwise.  'K' means to read the elements in the order they occur
+            in memory, except for reversing the data when strides are negative.
+            By default, 'C' index order is used.
+
+        Returns
+        -------
+        MaskedArray
+            Output view is of shape ``(self.size,)`` (or
+            ``(np.ma.product(self.shape),)``).
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.ravel())
+        [1 -- 3 -- 5 -- 7 -- 9]
+
+        """
+        r = ndarray.ravel(self._data, order=order).view(type(self))
+        r._update_from(self)
+        if self._mask is not nomask:
+            r._mask = ndarray.ravel(self._mask, order=order).reshape(r.shape)
+        else:
+            r._mask = nomask
+        return r
+
+    repeat = _arraymethod('repeat')
+
+
+    def reshape(self, *s, **kwargs):
+        """
+        Give a new shape to the array without changing its data.
+
+        Returns a masked array containing the same data, but with a new shape.
+        The result is a view on the original array; if this is not possible, a
+        ValueError is raised.
+
+        Parameters
+        ----------
+        shape : int or tuple of ints
+            The new shape should be compatible with the original shape. If an
+            integer is supplied, then the result will be a 1-D array of that
+            length.
+        order : {'C', 'F'}, optional
+            Determines whether the array data should be viewed as in C
+            (row-major) or FORTRAN (column-major) order.
+
+        Returns
+        -------
+        reshaped_array : array
+            A new view on the array.
+
+        See Also
+        --------
+        reshape : Equivalent function in the masked array module.
+        numpy.ndarray.reshape : Equivalent method on ndarray object.
+        numpy.reshape : Equivalent function in the NumPy module.
+
+        Notes
+        -----
+        The reshaping operation cannot guarantee that a copy will not be made,
+        to modify the shape in place, use ``a.shape = s``
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2],[3,4]], mask=[1,0,0,1])
+        >>> print(x)
+        [[-- 2]
+         [3 --]]
+        >>> x = x.reshape((4,1))
+        >>> print(x)
+        [[--]
+         [2]
+         [3]
+         [--]]
+
+        """
+        kwargs.update(order=kwargs.get('order', 'C'))
+        result = self._data.reshape(*s, **kwargs).view(type(self))
+        result._update_from(self)
+        mask = self._mask
+        if mask is not nomask:
+            result._mask = mask.reshape(*s, **kwargs)
+        return result
+
+    def resize(self, newshape, refcheck=True, order=False):
+        """
+        .. warning::
+
+            This method does nothing, except raise a ValueError exception. A
+            masked array does not own its data and therefore cannot safely be
+            resized in place. Use the `numpy.ma.resize` function instead.
+
+        This method is difficult to implement safely and may be deprecated in
+        future releases of NumPy.
+
+        """
+        # Note : the 'order' keyword looks broken, let's just drop it
+        errmsg = "A masked array does not own its data "\
+                 "and therefore cannot be resized.\n" \
+                 "Use the numpy.ma.resize function instead."
+        raise ValueError(errmsg)
+
+    def put(self, indices, values, mode='raise'):
+        """
+        Set storage-indexed locations to corresponding values.
+
+        Sets self._data.flat[n] = values[n] for each n in indices.
+        If `values` is shorter than `indices` then it will repeat.
+        If `values` has some masked values, the initial mask is updated
+        in consequence, else the corresponding values are unmasked.
+
+        Parameters
+        ----------
+        indices : 1-D array_like
+            Target indices, interpreted as integers.
+        values : array_like
+            Values to place in self._data copy at target indices.
+        mode : {'raise', 'wrap', 'clip'}, optional
+            Specifies how out-of-bounds indices will behave.
+            'raise' : raise an error.
+            'wrap' : wrap around.
+            'clip' : clip to the range.
+
+        Notes
+        -----
+        `values` can be a scalar or length 1 array.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> x.put([0,4,8],[10,20,30])
+        >>> print(x)
+        [[10 -- 3]
+         [-- 20 --]
+         [7 -- 30]]
+
+        >>> x.put(4,999)
+        >>> print(x)
+        [[10 -- 3]
+         [-- 999 --]
+         [7 -- 30]]
+
+        """
+        # Hard mask: Get rid of the values/indices that fall on masked data
+        if self._hardmask and self._mask is not nomask:
+            mask = self._mask[indices]
+            indices = narray(indices, copy=False)
+            values = narray(values, copy=False, subok=True)
+            values.resize(indices.shape)
+            indices = indices[~mask]
+            values = values[~mask]
+
+        self._data.put(indices, values, mode=mode)
+
+        # short circut if neither self nor values are masked
+        if self._mask is nomask and getmask(values) is nomask:
+            return
+
+        m = getmaskarray(self).copy()
+
+        if getmask(values) is nomask:
+            m.put(indices, False, mode=mode)
+        else:
+            m.put(indices, values._mask, mode=mode)
+        m = make_mask(m, copy=False, shrink=True)
+        self._mask = m
+        return
+
+    def ids(self):
+        """
+        Return the addresses of the data and mask areas.
+
+        Parameters
+        ----------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([1, 2, 3], mask=[0, 1, 1])
+        >>> x.ids()
+        (166670640, 166659832)
+
+        If the array has no mask, the address of `nomask` is returned. This address
+        is typically not close to the data in memory:
+
+        >>> x = np.ma.array([1, 2, 3])
+        >>> x.ids()
+        (166691080, 3083169284L)
+
+        """
+        if self._mask is nomask:
+            return (self.ctypes.data, id(nomask))
+        return (self.ctypes.data, self._mask.ctypes.data)
+
+    def iscontiguous(self):
+        """
+        Return a boolean indicating whether the data is contiguous.
+
+        Parameters
+        ----------
+        None
+
+        Examples
+        --------
+        >>> x = np.ma.array([1, 2, 3])
+        >>> x.iscontiguous()
+        True
+
+        `iscontiguous` returns one of the flags of the masked array:
+
+        >>> x.flags
+          C_CONTIGUOUS : True
+          F_CONTIGUOUS : True
+          OWNDATA : False
+          WRITEABLE : True
+          ALIGNED : True
+          UPDATEIFCOPY : False
+
+        """
+        return self.flags['CONTIGUOUS']
+
+    def all(self, axis=None, out=None):
+        """
+        Check if all of the elements of `a` are true.
+
+        Performs a :func:`logical_and` over the given axis and returns the result.
+        Masked values are considered as True during computation.
+        For convenience, the output array is masked where ALL the values along the
+        current axis are masked: if the output would have been a scalar and that
+        all the values are masked, then the output is `masked`.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            Axis to perform the operation over.
+            If None, perform over flattened array.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        See Also
+        --------
+        all : equivalent function
+
+        Examples
+        --------
+        >>> np.ma.array([1,2,3]).all()
+        True
+        >>> a = np.ma.array([1,2,3], mask=True)
+        >>> (a.all() is np.ma.masked)
+        True
+
+        """
+        mask = _check_mask_axis(self._mask, axis)
+        if out is None:
+            d = self.filled(True).all(axis=axis).view(type(self))
+            if d.ndim:
+                d.__setmask__(mask)
+            elif mask:
+                return masked
+            return d
+        self.filled(True).all(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            if out.ndim or mask:
+                out.__setmask__(mask)
+        return out
+
+    def any(self, axis=None, out=None):
+        """
+        Check if any of the elements of `a` are true.
+
+        Performs a logical_or over the given axis and returns the result.
+        Masked values are considered as False during computation.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            Axis to perform the operation over.
+            If None, perform over flattened array and return a scalar.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        See Also
+        --------
+        any : equivalent function
+
+        """
+        mask = _check_mask_axis(self._mask, axis)
+        if out is None:
+            d = self.filled(False).any(axis=axis).view(type(self))
+            if d.ndim:
+                d.__setmask__(mask)
+            elif mask:
+                d = masked
+            return d
+        self.filled(False).any(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            if out.ndim or mask:
+                out.__setmask__(mask)
+        return out
+
+    def nonzero(self):
+        """
+        Return the indices of unmasked elements that are not zero.
+
+        Returns a tuple of arrays, one for each dimension, containing the
+        indices of the non-zero elements in that dimension. The corresponding
+        non-zero values can be obtained with::
+
+            a[a.nonzero()]
+
+        To group the indices by element, rather than dimension, use
+        instead::
+
+            np.transpose(a.nonzero())
+
+        The result of this is always a 2d array, with a row for each non-zero
+        element.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        tuple_of_arrays : tuple
+            Indices of elements that are non-zero.
+
+        See Also
+        --------
+        numpy.nonzero :
+            Function operating on ndarrays.
+        flatnonzero :
+            Return indices that are non-zero in the flattened version of the input
+            array.
+        ndarray.nonzero :
+            Equivalent ndarray method.
+        count_nonzero :
+            Counts the number of non-zero elements in the input array.
+
+        Examples
+        --------
+        >>> import numpy.ma as ma
+        >>> x = ma.array(np.eye(3))
+        >>> x
+        masked_array(data =
+         [[ 1.  0.  0.]
+         [ 0.  1.  0.]
+         [ 0.  0.  1.]],
+              mask =
+         False,
+              fill_value=1e+20)
+        >>> x.nonzero()
+        (array([0, 1, 2]), array([0, 1, 2]))
+
+        Masked elements are ignored.
+
+        >>> x[1, 1] = ma.masked
+        >>> x
+        masked_array(data =
+         [[1.0 0.0 0.0]
+         [0.0 -- 0.0]
+         [0.0 0.0 1.0]],
+              mask =
+         [[False False False]
+         [False  True False]
+         [False False False]],
+              fill_value=1e+20)
+        >>> x.nonzero()
+        (array([0, 2]), array([0, 2]))
+
+        Indices can also be grouped by element.
+
+        >>> np.transpose(x.nonzero())
+        array([[0, 0],
+               [2, 2]])
+
+        A common use for ``nonzero`` is to find the indices of an array, where
+        a condition is True.  Given an array `a`, the condition `a` > 3 is a
+        boolean array and since False is interpreted as 0, ma.nonzero(a > 3)
+        yields the indices of the `a` where the condition is true.
+
+        >>> a = ma.array([[1,2,3],[4,5,6],[7,8,9]])
+        >>> a > 3
+        masked_array(data =
+         [[False False False]
+         [ True  True  True]
+         [ True  True  True]],
+              mask =
+         False,
+              fill_value=999999)
+        >>> ma.nonzero(a > 3)
+        (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+        The ``nonzero`` method of the condition array can also be called.
+
+        >>> (a > 3).nonzero()
+        (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+
+        """
+        return narray(self.filled(0), copy=False).nonzero()
+
+    def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None):
+        """
+        (this docstring should be overwritten)
+        """
+        #!!!: implement out + test!
+        m = self._mask
+        if m is nomask:
+            result = super(MaskedArray, self).trace(offset=offset, axis1=axis1,
+                                                    axis2=axis2, out=out)
+            return result.astype(dtype)
+        else:
+            D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
+            return D.astype(dtype).filled(0).sum(axis=None, out=out)
+    trace.__doc__ = ndarray.trace.__doc__
+
+    def dot(self, b, out=None, strict=False):
+        """
+        a.dot(b, out=None)
+
+        Masked dot product of two arrays. Note that `out` and `strict` are
+        located in different positions than in `ma.dot`. In order to
+        maintain compatibility with the functional version, it is
+        recommended that the optional arguments be treated as keyword only.
+        At some point that may be mandatory.
+
+        .. versionadded:: 1.10.0
+
+        Parameters
+        ----------
+        b : masked_array_like
+            Inputs array.
+        out : masked_array, optional
+            Output argument. This must have the exact kind that would be
+            returned if it was not used. In particular, it must have the
+            right type, must be C-contiguous, and its dtype must be the
+            dtype that would be returned for `ma.dot(a,b)`. This is a
+            performance feature. Therefore, if these conditions are not
+            met, an exception is raised, instead of attempting to be
+            flexible.
+        strict : bool, optional
+            Whether masked data are propagated (True) or set to 0 (False)
+            for the computation. Default is False.  Propagating the mask
+            means that if a masked value appears in a row or column, the
+            whole row or column is considered masked.
+
+            .. versionadded:: 1.10.2
+
+        See Also
+        --------
+        numpy.ma.dot : equivalent function
+
+        """
+        return dot(self, b, out=out, strict=strict)
+
+    def sum(self, axis=None, dtype=None, out=None):
+        """
+        Return the sum of the array elements over the given axis.
+        Masked elements are set to 0 internally.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the sum is computed. The default
+            (`axis` = None) is to compute over the flattened array.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are summed. If dtype has the value None and
+            the type of a is an integer type of precision less than the default
+            platform integer, then the default platform integer precision is
+            used.  Otherwise, the dtype is the same as that of a.
+        out :  {None, ndarray}, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        sum_along_axis : MaskedArray or scalar
+            An array with the same shape as self, with the specified
+            axis removed.   If self is a 0-d array, or if `axis` is None, a scalar
+            is returned.  If an output array is specified, a reference to
+            `out` is returned.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.sum())
+        25
+        >>> print(x.sum(axis=1))
+        [4 5 16]
+        >>> print(x.sum(axis=0))
+        [8 5 12]
+        >>> print(type(x.sum(axis=0, dtype=np.int64)[0]))
+        <type 'numpy.int64'>
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        # No explicit output
+        if out is None:
+            result = self.filled(0).sum(axis, dtype=dtype)
+            rndim = getattr(result, 'ndim', 0)
+            if rndim:
+                result = result.view(type(self))
+                result.__setmask__(newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(0).sum(axis, dtype=dtype, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        return out
+
+    def cumsum(self, axis=None, dtype=None, out=None):
+        """
+        Return the cumulative sum of the elements along the given axis.
+        The cumulative sum is calculated over the flattened array by
+        default, otherwise over the specified axis.
+
+        Masked values are set to 0 internally during the computation.
+        However, their position is saved, and the result will be masked at
+        the same locations.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the sum is computed. The default (`axis` = None) is to
+            compute over the flattened array. `axis` may be negative, in which case
+            it counts from the   last to the first axis.
+        dtype : {None, dtype}, optional
+            Type of the returned array and of the accumulator in which the
+            elements are summed.  If `dtype` is not specified, it defaults
+            to the dtype of `a`, unless `a` has an integer dtype with a
+            precision less than that of the default platform integer.  In
+            that case, the default platform integer is used.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        cumsum : ndarray.
+            A new array holding the result is returned unless ``out`` is
+            specified, in which case a reference to ``out`` is returned.
+
+        Notes
+        -----
+        The mask is lost if `out` is not a valid :class:`MaskedArray` !
+
+        Arithmetic is modular when using integer types, and no error is
+        raised on overflow.
+
+        Examples
+        --------
+        >>> marr = np.ma.array(np.arange(10), mask=[0,0,0,1,1,1,0,0,0,0])
+        >>> print(marr.cumsum())
+        [0 1 3 -- -- -- 9 16 24 33]
+
+        """
+        result = self.filled(0).cumsum(axis=axis, dtype=dtype, out=out)
+        if out is not None:
+            if isinstance(out, MaskedArray):
+                out.__setmask__(self.mask)
+            return out
+        result = result.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    def prod(self, axis=None, dtype=None, out=None):
+        """
+        Return the product of the array elements over the given axis.
+        Masked elements are set to 1 internally for computation.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis over which the product is taken. If None is used, then the
+            product is over all the array elements.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are multiplied. If ``dtype`` has the value ``None``
+            and the type of a is an integer type of precision less than the default
+            platform integer, then the default platform integer precision is
+            used.  Otherwise, the dtype is the same as that of a.
+        out : {None, array}, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        product_along_axis : {array, scalar}, see dtype parameter above.
+            Returns an array whose shape is the same as a with the specified
+            axis removed. Returns a 0d array when a is 1d or axis=None.
+            Returns a reference to the specified output array if specified.
+
+        See Also
+        --------
+        prod : equivalent function
+
+        Notes
+        -----
+        Arithmetic is modular when using integer types, and no error is raised
+        on overflow.
+
+        Examples
+        --------
+        >>> np.prod([1.,2.])
+        2.0
+        >>> np.prod([1.,2.], dtype=np.int32)
+        2
+        >>> np.prod([[1.,2.],[3.,4.]])
+        24.0
+        >>> np.prod([[1.,2.],[3.,4.]], axis=1)
+        array([  2.,  12.])
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        # No explicit output
+        if out is None:
+            result = self.filled(1).prod(axis, dtype=dtype)
+            rndim = getattr(result, 'ndim', 0)
+            if rndim:
+                result = result.view(type(self))
+                result.__setmask__(newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(1).prod(axis, dtype=dtype, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        return out
+
+    product = prod
+
+    def cumprod(self, axis=None, dtype=None, out=None):
+        """
+        Return the cumulative product of the elements along the given axis.
+        The cumulative product is taken over the flattened array by
+        default, otherwise over the specified axis.
+
+        Masked values are set to 1 internally during the computation.
+        However, their position is saved, and the result will be masked at
+        the same locations.
+
+        Parameters
+        ----------
+        axis : {None, -1, int}, optional
+            Axis along which the product is computed. The default
+            (`axis` = None) is to compute over the flattened array.
+        dtype : {None, dtype}, optional
+            Determines the type of the returned array and of the accumulator
+            where the elements are multiplied. If ``dtype`` has the value ``None``
+            and the type of ``a`` is an integer type of precision less than the
+            default platform integer, then the default platform integer precision
+            is used.  Otherwise, the dtype is the same as that of ``a``.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+
+        Returns
+        -------
+        cumprod : ndarray
+            A new array holding the result is returned unless out is specified,
+            in which case a reference to out is returned.
+
+        Notes
+        -----
+        The mask is lost if `out` is not a valid MaskedArray !
+
+        Arithmetic is modular when using integer types, and no error is
+        raised on overflow.
+
+        """
+        result = self.filled(1).cumprod(axis=axis, dtype=dtype, out=out)
+        if out is not None:
+            if isinstance(out, MaskedArray):
+                out.__setmask__(self._mask)
+            return out
+        result = result.view(type(self))
+        result.__setmask__(self._mask)
+        return result
+
+    def mean(self, axis=None, dtype=None, out=None):
+        """
+        Returns the average of the array elements.
+
+        Masked entries are ignored.
+        The average is taken over the flattened array by default, otherwise over
+        the specified axis. Refer to `numpy.mean` for the full documentation.
+
+        Parameters
+        ----------
+        a : array_like
+            Array containing numbers whose mean is desired. If `a` is not an
+            array, a conversion is attempted.
+        axis : int, optional
+            Axis along which the means are computed. The default is to compute
+            the mean of the flattened array.
+        dtype : dtype, optional
+            Type to use in computing the mean. For integer inputs, the default
+            is float64; for floating point, inputs it is the same as the input
+            dtype.
+        out : ndarray, optional
+            Alternative output array in which to place the result. It must have
+            the same shape as the expected output but the type will be cast if
+            necessary.
+
+        Returns
+        -------
+        mean : ndarray, see dtype parameter above
+            If `out=None`, returns a new array containing the mean values,
+            otherwise a reference to the output array is returned.
+
+        See Also
+        --------
+        numpy.ma.mean : Equivalent function.
+        numpy.mean : Equivalent function on non-masked arrays.
+        numpy.ma.average: Weighted average.
+
+        Examples
+        --------
+        >>> a = np.ma.array([1,2,3], mask=[False, False, True])
+        >>> a
+        masked_array(data = [1 2 --],
+                     mask = [False False  True],
+               fill_value = 999999)
+        >>> a.mean()
+        1.5
+
+        """
+        if self._mask is nomask:
+            result = super(MaskedArray, self).mean(axis=axis, dtype=dtype)
+        else:
+            dsum = self.sum(axis=axis, dtype=dtype)
+            cnt = self.count(axis=axis)
+            if cnt.shape == () and (cnt == 0):
+                result = masked
+            else:
+                result = dsum * 1. / cnt
+        if out is not None:
+            out.flat = result
+            if isinstance(out, MaskedArray):
+                outmask = getattr(out, '_mask', nomask)
+                if (outmask is nomask):
+                    outmask = out._mask = make_mask_none(out.shape)
+                outmask.flat = getattr(result, '_mask', nomask)
+            return out
+        return result
+
+    def anom(self, axis=None, dtype=None):
+        """
+        Compute the anomalies (deviations from the arithmetic mean)
+        along the given axis.
+
+        Returns an array of anomalies, with the same shape as the input and
+        where the arithmetic mean is computed along the given axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis over which the anomalies are taken.
+            The default is to use the mean of the flattened array as reference.
+        dtype : dtype, optional
+            Type to use in computing the variance. For arrays of integer type
+             the default is float32; for arrays of float types it is the same as
+             the array type.
+
+        See Also
+        --------
+        mean : Compute the mean of the array.
+
+        Examples
+        --------
+        >>> a = np.ma.array([1,2,3])
+        >>> a.anom()
+        masked_array(data = [-1.  0.  1.],
+                     mask = False,
+               fill_value = 1e+20)
+
+        """
+        m = self.mean(axis, dtype)
+        if m is masked:
+            return m
+
+        if not axis:
+            return (self - m)
+        else:
+            return (self - expand_dims(m, axis))
+
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        ""
+        # Easy case: nomask, business as usual
+        if self._mask is nomask:
+            return self._data.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        # Some data are masked, yay!
+        cnt = self.count(axis=axis) - ddof
+        danom = self.anom(axis=axis, dtype=dtype)
+        if iscomplexobj(self):
+            danom = umath.absolute(danom) ** 2
+        else:
+            danom *= danom
+        dvar = divide(danom.sum(axis), cnt).view(type(self))
+        # Apply the mask if it's not a scalar
+        if dvar.ndim:
+            dvar._mask = mask_or(self._mask.all(axis), (cnt <= 0))
+            dvar._update_from(self)
+        elif getattr(dvar, '_mask', False):
+            # Make sure that masked is returned when the scalar is masked.
+            dvar = masked
+            if out is not None:
+                if isinstance(out, MaskedArray):
+                    out.flat = 0
+                    out.__setmask__(True)
+                elif out.dtype.kind in 'biu':
+                    errmsg = "Masked data information would be lost in one or "\
+                             "more location."
+                    raise MaskError(errmsg)
+                else:
+                    out.flat = np.nan
+                return out
+        # In case with have an explicit output
+        if out is not None:
+            # Set the data
+            out.flat = dvar
+            # Set the mask if needed
+            if isinstance(out, MaskedArray):
+                out.__setmask__(dvar.mask)
+            return out
+        return dvar
+    var.__doc__ = np.var.__doc__
+
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        ""
+        dvar = self.var(axis=axis, dtype=dtype, out=out, ddof=ddof)
+        if dvar is not masked:
+            if out is not None:
+                np.power(out, 0.5, out=out, casting='unsafe')
+                return out
+            dvar = sqrt(dvar)
+        return dvar
+    std.__doc__ = np.std.__doc__
+
+    def round(self, decimals=0, out=None):
+        """
+        Return an array rounded a to the given number of decimals.
+
+        Refer to `numpy.around` for full documentation.
+
+        See Also
+        --------
+        numpy.around : equivalent function
+
+        """
+        result = self._data.round(decimals=decimals, out=out).view(type(self))
+        if result.ndim > 0:
+            result._mask = self._mask
+            result._update_from(self)
+        elif self._mask:
+            # Return masked when the scalar is masked
+            result = masked
+        # No explicit output: we're done
+        if out is None:
+            return result
+        if isinstance(out, MaskedArray):
+            out.__setmask__(self._mask)
+        return out
+    round.__doc__ = ndarray.round.__doc__
+
+    def argsort(self, axis=None, kind='quicksort', order=None, fill_value=None):
+        """
+        Return an ndarray of indices that sort the array along the
+        specified axis.  Masked values are filled beforehand to
+        `fill_value`.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which to sort.  The default is -1 (last axis).
+            If None, the flattened array is used.
+        fill_value : var, optional
+            Value used to fill the array before sorting.
+            The default is the `fill_value` attribute of the input array.
+        kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+            Sorting algorithm.
+        order : list, optional
+            When `a` is an array with fields defined, this argument specifies
+            which fields to compare first, second, etc.  Not all fields need be
+            specified.
+
+        Returns
+        -------
+        index_array : ndarray, int
+            Array of indices that sort `a` along the specified axis.
+            In other words, ``a[index_array]`` yields a sorted `a`.
+
+        See Also
+        --------
+        sort : Describes sorting algorithms used.
+        lexsort : Indirect stable sort with multiple keys.
+        ndarray.sort : Inplace sort.
+
+        Notes
+        -----
+        See `sort` for notes on the different sorting algorithms.
+
+        Examples
+        --------
+        >>> a = np.ma.array([3,2,1], mask=[False, False, True])
+        >>> a
+        masked_array(data = [3 2 --],
+                     mask = [False False  True],
+               fill_value = 999999)
+        >>> a.argsort()
+        array([1, 0, 2])
+
+        """
+        if fill_value is None:
+            fill_value = default_fill_value(self)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argsort(axis=axis, kind=kind, order=order)
+
+    def argmin(self, axis=None, fill_value=None, out=None):
+        """
+        Return array of indices to the minimum values along the given axis.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            If None, the index is into the flattened array, otherwise along
+            the specified axis
+        fill_value : {var}, optional
+            Value used to fill in the masked values.  If None, the output of
+            minimum_fill_value(self._data) is used instead.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        Returns
+        -------
+        ndarray or scalar
+            If multi-dimension input, returns a new ndarray of indices to the
+            minimum values along the given axis.  Otherwise, returns a scalar
+            of index to the minimum values along the given axis.
+
+        Examples
+        --------
+        >>> x = np.ma.array(arange(4), mask=[1,1,0,0])
+        >>> x.shape = (2,2)
+        >>> print(x)
+        [[-- --]
+         [2 3]]
+        >>> print(x.argmin(axis=0, fill_value=-1))
+        [0 0]
+        >>> print(x.argmin(axis=0, fill_value=9))
+        [1 1]
+
+        """
+        if fill_value is None:
+            fill_value = minimum_fill_value(self)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argmin(axis, out=out)
+
+    def argmax(self, axis=None, fill_value=None, out=None):
+        """
+        Returns array of indices of the maximum values along the given axis.
+        Masked values are treated as if they had the value fill_value.
+
+        Parameters
+        ----------
+        axis : {None, integer}
+            If None, the index is into the flattened array, otherwise along
+            the specified axis
+        fill_value : {var}, optional
+            Value used to fill in the masked values.  If None, the output of
+            maximum_fill_value(self._data) is used instead.
+        out : {None, array}, optional
+            Array into which the result can be placed. Its type is preserved
+            and it must be of the right shape to hold the output.
+
+        Returns
+        -------
+        index_array : {integer_array}
+
+        Examples
+        --------
+        >>> a = np.arange(6).reshape(2,3)
+        >>> a.argmax()
+        5
+        >>> a.argmax(0)
+        array([1, 1, 1])
+        >>> a.argmax(1)
+        array([2, 2])
+
+        """
+        if fill_value is None:
+            fill_value = maximum_fill_value(self._data)
+        d = self.filled(fill_value).view(ndarray)
+        return d.argmax(axis, out=out)
+
+    def sort(self, axis=-1, kind='quicksort', order=None,
+             endwith=True, fill_value=None):
+        """
+        Sort the array, in-place
+
+        Parameters
+        ----------
+        a : array_like
+            Array to be sorted.
+        axis : int, optional
+            Axis along which to sort. If None, the array is flattened before
+            sorting. The default is -1, which sorts along the last axis.
+        kind : {'quicksort', 'mergesort', 'heapsort'}, optional
+            Sorting algorithm. Default is 'quicksort'.
+        order : list, optional
+            When `a` is a structured array, this argument specifies which fields
+            to compare first, second, and so on.  This list does not need to
+            include all of the fields.
+        endwith : {True, False}, optional
+            Whether missing values (if any) should be forced in the upper indices
+            (at the end of the array) (True) or lower indices (at the beginning).
+            When the array contains unmasked values of the largest (or smallest if
+            False) representable value of the datatype the ordering of these values
+            and the masked values is undefined.  To enforce the masked values are
+            at the end (beginning) in this case one must sort the mask.
+        fill_value : {var}, optional
+            Value used internally for the masked values.
+            If ``fill_value`` is not None, it supersedes ``endwith``.
+
+        Returns
+        -------
+        sorted_array : ndarray
+            Array of the same type and shape as `a`.
+
+        See Also
+        --------
+        ndarray.sort : Method to sort an array in-place.
+        argsort : Indirect sort.
+        lexsort : Indirect stable sort on multiple keys.
+        searchsorted : Find elements in a sorted array.
+
+        Notes
+        -----
+        See ``sort`` for notes on the different sorting algorithms.
+
+        Examples
+        --------
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # Default
+        >>> a.sort()
+        >>> print(a)
+        [1 3 5 -- --]
+
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # Put missing values in the front
+        >>> a.sort(endwith=False)
+        >>> print(a)
+        [-- -- 1 3 5]
+
+        >>> a = ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0])
+        >>> # fill_value takes over endwith
+        >>> a.sort(endwith=False, fill_value=3)
+        >>> print(a)
+        [1 -- -- 3 5]
+
+        """
+        if self._mask is nomask:
+            ndarray.sort(self, axis=axis, kind=kind, order=order)
+        else:
+            if self is masked:
+                return self
+            if fill_value is None:
+                if endwith:
+                    # nan > inf
+                    if np.issubdtype(self.dtype, np.floating):
+                        filler = np.nan
+                    else:
+                        filler = minimum_fill_value(self)
+                else:
+                    filler = maximum_fill_value(self)
+            else:
+                filler = fill_value
+
+            sidx = self.filled(filler).argsort(axis=axis, kind=kind,
+                                               order=order)
+            # save meshgrid memory for 1d arrays
+            if self.ndim == 1:
+                idx = sidx
+            else:
+                idx = np.meshgrid(*[np.arange(x) for x in self.shape], sparse=True,
+                                  indexing='ij')
+                idx[axis] = sidx
+            tmp_mask = self._mask[idx].flat
+            tmp_data = self._data[idx].flat
+            self._data.flat = tmp_data
+            self._mask.flat = tmp_mask
+        return
+
+    def min(self, axis=None, out=None, fill_value=None):
+        """
+        Return the minimum along a given axis.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to operate.  By default, ``axis`` is None and the
+            flattened input is used.
+        out : array_like, optional
+            Alternative output array in which to place the result.  Must be of
+            the same shape and buffer length as the expected output.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+            If None, use the output of `minimum_fill_value`.
+
+        Returns
+        -------
+        amin : array_like
+            New array holding the result.
+            If ``out`` was specified, ``out`` is returned.
+
+        See Also
+        --------
+        minimum_fill_value
+            Returns the minimum filling value for a given datatype.
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        if fill_value is None:
+            fill_value = minimum_fill_value(self)
+        # No explicit output
+        if out is None:
+            result = self.filled(fill_value).min(
+                axis=axis, out=out).view(type(self))
+            if result.ndim:
+                # Set the mask
+                result.__setmask__(newmask)
+                # Get rid of Infs
+                if newmask.ndim:
+                    np.copyto(result, result.fill_value, where=newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(fill_value).min(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        else:
+            if out.dtype.kind in 'biu':
+                errmsg = "Masked data information would be lost in one or more"\
+                         " location."
+                raise MaskError(errmsg)
+            np.copyto(out, np.nan, where=newmask)
+        return out
+
+    def mini(self, axis=None):
+        """
+        Return the array minimum along the specified axis.
+
+        Parameters
+        ----------
+        axis : int, optional
+            The axis along which to find the minima. Default is None, in which case
+            the minimum value in the whole array is returned.
+
+        Returns
+        -------
+        min : scalar or MaskedArray
+            If `axis` is None, the result is a scalar. Otherwise, if `axis` is
+            given and the array is at least 2-D, the result is a masked array with
+            dimension one smaller than the array on which `mini` is called.
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.arange(6), mask=[0 ,1, 0, 0, 0 ,1]).reshape(3, 2)
+        >>> print(x)
+        [[0 --]
+         [2 3]
+         [4 --]]
+        >>> x.mini()
+        0
+        >>> x.mini(axis=0)
+        masked_array(data = [0 3],
+                     mask = [False False],
+               fill_value = 999999)
+        >>> print(x.mini(axis=1))
+        [0 2 4]
+
+        """
+        if axis is None:
+            return minimum(self)
+        else:
+            return minimum.reduce(self, axis)
+
+    def max(self, axis=None, out=None, fill_value=None):
+        """
+        Return the maximum along a given axis.
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to operate.  By default, ``axis`` is None and the
+            flattened input is used.
+        out : array_like, optional
+            Alternative output array in which to place the result.  Must
+            be of the same shape and buffer length as the expected output.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+            If None, use the output of maximum_fill_value().
+
+        Returns
+        -------
+        amax : array_like
+            New array holding the result.
+            If ``out`` was specified, ``out`` is returned.
+
+        See Also
+        --------
+        maximum_fill_value
+            Returns the maximum filling value for a given datatype.
+
+        """
+        _mask = self._mask
+        newmask = _check_mask_axis(_mask, axis)
+        if fill_value is None:
+            fill_value = maximum_fill_value(self)
+        # No explicit output
+        if out is None:
+            result = self.filled(fill_value).max(
+                axis=axis, out=out).view(type(self))
+            if result.ndim:
+                # Set the mask
+                result.__setmask__(newmask)
+                # Get rid of Infs
+                if newmask.ndim:
+                    np.copyto(result, result.fill_value, where=newmask)
+            elif newmask:
+                result = masked
+            return result
+        # Explicit output
+        result = self.filled(fill_value).max(axis=axis, out=out)
+        if isinstance(out, MaskedArray):
+            outmask = getattr(out, '_mask', nomask)
+            if (outmask is nomask):
+                outmask = out._mask = make_mask_none(out.shape)
+            outmask.flat = newmask
+        else:
+
+            if out.dtype.kind in 'biu':
+                errmsg = "Masked data information would be lost in one or more"\
+                         " location."
+                raise MaskError(errmsg)
+            np.copyto(out, np.nan, where=newmask)
+        return out
+
+    def ptp(self, axis=None, out=None, fill_value=None):
+        """
+        Return (maximum - minimum) along the the given dimension
+        (i.e. peak-to-peak value).
+
+        Parameters
+        ----------
+        axis : {None, int}, optional
+            Axis along which to find the peaks.  If None (default) the
+            flattened array is used.
+        out : {None, array_like}, optional
+            Alternative output array in which to place the result. It must
+            have the same shape and buffer length as the expected output
+            but the type will be cast if necessary.
+        fill_value : {var}, optional
+            Value used to fill in the masked values.
+
+        Returns
+        -------
+        ptp : ndarray.
+            A new array holding the result, unless ``out`` was
+            specified, in which case a reference to ``out`` is returned.
+
+        """
+        if out is None:
+            result = self.max(axis=axis, fill_value=fill_value)
+            result -= self.min(axis=axis, fill_value=fill_value)
+            return result
+        out.flat = self.max(axis=axis, out=out, fill_value=fill_value)
+        min_value = self.min(axis=axis, fill_value=fill_value)
+        np.subtract(out, min_value, out=out, casting='unsafe')
+        return out
+
+    def take(self, indices, axis=None, out=None, mode='raise'):
+        """
+        """
+        (_data, _mask) = (self._data, self._mask)
+        cls = type(self)
+        # Make sure the indices are not masked
+        maskindices = getattr(indices, '_mask', nomask)
+        if maskindices is not nomask:
+            indices = indices.filled(0)
+        # Get the data
+        if out is None:
+            out = _data.take(indices, axis=axis, mode=mode).view(cls)
+        else:
+            np.take(_data, indices, axis=axis, mode=mode, out=out)
+        # Get the mask
+        if isinstance(out, MaskedArray):
+            if _mask is nomask:
+                outmask = maskindices
+            else:
+                outmask = _mask.take(indices, axis=axis, mode=mode)
+                outmask |= maskindices
+            out.__setmask__(outmask)
+        return out
+
+    # Array methods
+    copy = _arraymethod('copy')
+    diagonal = _arraymethod('diagonal')
+    transpose = _arraymethod('transpose')
+    T = property(fget=lambda self: self.transpose())
+    swapaxes = _arraymethod('swapaxes')
+    clip = _arraymethod('clip', onmask=False)
+    copy = _arraymethod('copy')
+    squeeze = _arraymethod('squeeze')
+
+    def tolist(self, fill_value=None):
+        """
+        Return the data portion of the masked array as a hierarchical Python list.
+
+        Data items are converted to the nearest compatible Python type.
+        Masked values are converted to `fill_value`. If `fill_value` is None,
+        the corresponding entries in the output list will be ``None``.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries. Default is None.
+
+        Returns
+        -------
+        result : list
+            The Python list representation of the masked array.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3], [4,5,6], [7,8,9]], mask=[0] + [1,0]*4)
+        >>> x.tolist()
+        [[1, None, 3], [None, 5, None], [7, None, 9]]
+        >>> x.tolist(-999)
+        [[1, -999, 3], [-999, 5, -999], [7, -999, 9]]
+
+        """
+        _mask = self._mask
+        # No mask ? Just return .data.tolist ?
+        if _mask is nomask:
+            return self._data.tolist()
+        # Explicit fill_value: fill the array and get the list
+        if fill_value is not None:
+            return self.filled(fill_value).tolist()
+        # Structured array.
+        names = self.dtype.names
+        if names:
+            result = self._data.astype([(_, object) for _ in names])
+            for n in names:
+                result[n][_mask[n]] = None
+            return result.tolist()
+        # Standard arrays.
+        if _mask is nomask:
+            return [None]
+        # Set temps to save time when dealing w/ marrays.
+        inishape = self.shape
+        result = np.array(self._data.ravel(), dtype=object)
+        result[_mask.ravel()] = None
+        result.shape = inishape
+        return result.tolist()
+
+    def tostring(self, fill_value=None, order='C'):
+        """
+        This function is a compatibility alias for tobytes. Despite its name it
+        returns bytes not strings.
+        """
+
+        return self.tobytes(fill_value, order='C')
+
+    def tobytes(self, fill_value=None, order='C'):
+        """
+        Return the array data as a string containing the raw bytes in the array.
+
+        The array is filled with a fill value before the string conversion.
+
+        .. versionadded:: 1.9.0
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            Value used to fill in the masked values. Deafult is None, in which
+            case `MaskedArray.fill_value` is used.
+        order : {'C','F','A'}, optional
+            Order of the data item in the copy. Default is 'C'.
+
+            - 'C'   -- C order (row major).
+            - 'F'   -- Fortran order (column major).
+            - 'A'   -- Any, current order of array.
+            - None  -- Same as 'A'.
+
+        See Also
+        --------
+        ndarray.tobytes
+        tolist, tofile
+
+        Notes
+        -----
+        As for `ndarray.tobytes`, information about the shape, dtype, etc.,
+        but also about `fill_value`, will be lost.
+
+        Examples
+        --------
+        >>> x = np.ma.array(np.array([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]])
+        >>> x.tobytes()
+        '\\x01\\x00\\x00\\x00?B\\x0f\\x00?B\\x0f\\x00\\x04\\x00\\x00\\x00'
+
+        """
+        return self.filled(fill_value).tobytes(order=order)
+
+    def tofile(self, fid, sep="", format="%s"):
+        """
+        Save a masked array to a file in binary format.
+
+        .. warning::
+          This function is not implemented yet.
+
+        Raises
+        ------
+        NotImplementedError
+            When `tofile` is called.
+
+        """
+        raise NotImplementedError("MaskedArray.tofile() not implemented yet.")
+
+    def toflex(self):
+        """
+        Transforms a masked array into a flexible-type array.
+
+        The flexible type array that is returned will have two fields:
+
+        * the ``_data`` field stores the ``_data`` part of the array.
+        * the ``_mask`` field stores the ``_mask`` part of the array.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        record : ndarray
+            A new flexible-type `ndarray` with two fields: the first element
+            containing a value, the second element containing the corresponding
+            mask boolean. The returned record shape matches self.shape.
+
+        Notes
+        -----
+        A side-effect of transforming a masked array into a flexible `ndarray` is
+        that meta information (``fill_value``, ...) will be lost.
+
+        Examples
+        --------
+        >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4)
+        >>> print(x)
+        [[1 -- 3]
+         [-- 5 --]
+         [7 -- 9]]
+        >>> print(x.toflex())
+        [[(1, False) (2, True) (3, False)]
+         [(4, True) (5, False) (6, True)]
+         [(7, False) (8, True) (9, False)]]
+
+        """
+        # Get the basic dtype.
+        ddtype = self.dtype
+        # Make sure we have a mask
+        _mask = self._mask
+        if _mask is None:
+            _mask = make_mask_none(self.shape, ddtype)
+        # And get its dtype
+        mdtype = self._mask.dtype
+
+        record = np.ndarray(shape=self.shape,
+                            dtype=[('_data', ddtype), ('_mask', mdtype)])
+        record['_data'] = self._data
+        record['_mask'] = self._mask
+        return record
+    torecords = toflex
+
+    # Pickling
+    def __getstate__(self):
+        """Return the internal state of the masked array, for pickling
+        purposes.
+
+        """
+        cf = 'CF'[self.flags.fnc]
+        state = (1,
+                 self.shape,
+                 self.dtype,
+                 self.flags.fnc,
+                 self._data.tobytes(cf),
+                 # self._data.tolist(),
+                 getmaskarray(self).tobytes(cf),
+                 # getmaskarray(self).tolist(),
+                 self._fill_value,
+                 )
+        return state
+
+    def __setstate__(self, state):
+        """Restore the internal state of the masked array, for
+        pickling purposes.  ``state`` is typically the output of the
+        ``__getstate__`` output, and is a 5-tuple:
+
+        - class name
+        - a tuple giving the shape of the data
+        - a typecode for the data
+        - a binary string for the data
+        - a binary string for the mask.
+
+        """
+        (_, shp, typ, isf, raw, msk, flv) = state
+        super(MaskedArray, self).__setstate__((shp, typ, isf, raw))
+        self._mask.__setstate__((shp, make_mask_descr(typ), isf, msk))
+        self.fill_value = flv
+
+    def __reduce__(self):
+        """Return a 3-tuple for pickling a MaskedArray.
+
+        """
+        return (_mareconstruct,
+                (self.__class__, self._baseclass, (0,), 'b',),
+                self.__getstate__())
+
+    def __deepcopy__(self, memo=None):
+        from copy import deepcopy
+        copied = MaskedArray.__new__(type(self), self, copy=True)
+        if memo is None:
+            memo = {}
+        memo[id(self)] = copied
+        for (k, v) in self.__dict__.items():
+            copied.__dict__[k] = deepcopy(v, memo)
+        return copied
+
+
+def _mareconstruct(subtype, baseclass, baseshape, basetype,):
+    """Internal function that builds a new MaskedArray from the
+    information stored in a pickle.
+
+    """
+    _data = ndarray.__new__(baseclass, baseshape, basetype)
+    _mask = ndarray.__new__(ndarray, baseshape, make_mask_descr(basetype))
+    return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
+
+class mvoid(MaskedArray):
+    """
+    Fake a 'void' object to use for masked array with structured dtypes.
+    """
+
+    def __new__(self, data, mask=nomask, dtype=None, fill_value=None,
+                hardmask=False, copy=False, subok=True):
+        _data = np.array(data, copy=copy, subok=subok, dtype=dtype)
+        _data = _data.view(self)
+        _data._hardmask = hardmask
+        if mask is not nomask:
+            if isinstance(mask, np.void):
+                _data._mask = mask
+            else:
+                try:
+                    # Mask is already a 0D array
+                    _data._mask = np.void(mask)
+                except TypeError:
+                    # Transform the mask to a void
+                    mdtype = make_mask_descr(dtype)
+                    _data._mask = np.array(mask, dtype=mdtype)[()]
+        if fill_value is not None:
+            _data.fill_value = fill_value
+        return _data
+
+    def _get_data(self):
+        # Make sure that the _data part is a np.void
+        return self.view(ndarray)[()]
+
+    _data = property(fget=_get_data)
+
+    def __getitem__(self, indx):
+        """
+        Get the index.
+
+        """
+        m = self._mask
+        if isinstance(m[indx], ndarray):
+            # Can happen when indx is a multi-dimensional field:
+            # A = ma.masked_array(data=[([0,1],)], mask=[([True,
+            #                     False],)], dtype=[("A", ">i2", (2,))])
+            # x = A[0]; y = x["A"]; then y.mask["A"].size==2
+            # and we can not say masked/unmasked.
+            # The result is no longer mvoid!
+            # See also issue #6724.
+            return masked_array(
+                data=self._data[indx], mask=m[indx],
+                fill_value=self._fill_value[indx],
+                hard_mask=self._hardmask)
+        if m is not nomask and m[indx]:
+            return masked
+        return self._data[indx]
+
+    def __setitem__(self, indx, value):
+        self._data[indx] = value
+        if self._hardmask:
+            self._mask[indx] |= getattr(value, "_mask", False)
+        else:
+            self._mask[indx] = getattr(value, "_mask", False)
+
+    def __str__(self):
+        m = self._mask
+        if m is nomask:
+            return self._data.__str__()
+        printopt = masked_print_option
+        rdtype = _recursive_make_descr(self._data.dtype, "O")
+        res = np.array([self._data]).astype(rdtype)
+        _recursive_printoption(res, self._mask, printopt)
+        return str(res[0])
+
+    __repr__ = __str__
+
+    def __iter__(self):
+        "Defines an iterator for mvoid"
+        (_data, _mask) = (self._data, self._mask)
+        if _mask is nomask:
+            for d in _data:
+                yield d
+        else:
+            for (d, m) in zip(_data, _mask):
+                if m:
+                    yield masked
+                else:
+                    yield d
+
+    def __len__(self):
+        return self._data.__len__()
+
+    def filled(self, fill_value=None):
+        """
+        Return a copy with masked fields filled with a given value.
+
+        Parameters
+        ----------
+        fill_value : scalar, optional
+            The value to use for invalid entries (None by default).
+            If None, the `fill_value` attribute is used instead.
+
+        Returns
+        -------
+        filled_void
+            A `np.void` object
+
+        See Also
+        --------
+        MaskedArray.filled
+
+        """
+        return asarray(self).filled(fill_value)[()]
+
+    def tolist(self):
+        """
+    Transforms the mvoid object into a tuple.
+
+    Masked fields are replaced by None.
+
+    Returns
+    -------
+    returned_tuple
+        Tuple of fields
+        """
+        _mask = self._mask
+        if _mask is nomask:
+            return self._data.tolist()
+        result = []
+        for (d, m) in zip(self._data, self._mask):
+            if m:
+                result.append(None)
+            else:
+                # .item() makes sure we return a standard Python object
+                result.append(d.item())
+        return tuple(result)
+
+
+##############################################################################
+#                                Shortcuts                                   #
+##############################################################################
+
+
+def isMaskedArray(x):
+    """
+    Test whether input is an instance of MaskedArray.
+
+    This function returns True if `x` is an instance of MaskedArray
+    and returns False otherwise.  Any object is accepted as input.
+
+    Parameters
+    ----------
+    x : object
+        Object to test.
+
+    Returns
+    -------
+    result : bool
+        True if `x` is a MaskedArray.
+
+    See Also
+    --------
+    isMA : Alias to isMaskedArray.
+    isarray : Alias to isMaskedArray.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.eye(3, 3)
+    >>> a
+    array([[ 1.,  0.,  0.],
+           [ 0.,  1.,  0.],
+           [ 0.,  0.,  1.]])
+    >>> m = ma.masked_values(a, 0)
+    >>> m
+    masked_array(data =
+     [[1.0 -- --]
+     [-- 1.0 --]
+     [-- -- 1.0]],
+          mask =
+     [[False  True  True]
+     [ True False  True]
+     [ True  True False]],
+          fill_value=0.0)
+    >>> ma.isMaskedArray(a)
+    False
+    >>> ma.isMaskedArray(m)
+    True
+    >>> ma.isMaskedArray([0, 1, 2])
+    False
+
+    """
+    return isinstance(x, MaskedArray)
+
+
+isarray = isMaskedArray
+isMA = isMaskedArray  # backward compatibility
+
+
+class MaskedConstant(MaskedArray):
+    # We define the masked singleton as a float for higher precedence.
+    # Note that it can be tricky sometimes w/ type comparison
+    _data = data = np.array(0.)
+    _mask = mask = np.array(True)
+    _baseclass = ndarray
+
+    def __new__(self):
+        return self._data.view(self)
+
+    def __array_finalize__(self, obj):
+        return
+
+    def __array_wrap__(self, obj):
+        return self
+
+    def __str__(self):
+        return str(masked_print_option._display)
+
+    def __repr__(self):
+        return 'masked'
+
+    def flatten(self):
+        return masked_array([self._data], dtype=float, mask=[True])
+
+    def __reduce__(self):
+        """Override of MaskedArray's __reduce__.
+        """
+        return (self.__class__, ())
+
+
+masked = masked_singleton = MaskedConstant()
+masked_array = MaskedArray
+
+
+def array(data, dtype=None, copy=False, order=None,
+          mask=nomask, fill_value=None, keep_mask=True,
+          hard_mask=False, shrink=True, subok=True, ndmin=0):
+    """
+    Shortcut to MaskedArray.
+
+    The options are in a different order for convenience and backwards
+    compatibility.
+
+    """
+    return MaskedArray(data, mask=mask, dtype=dtype, copy=copy,
+                       subok=subok, keep_mask=keep_mask,
+                       hard_mask=hard_mask, fill_value=fill_value,
+                       ndmin=ndmin, shrink=shrink, order=order)
+array.__doc__ = masked_array.__doc__
+
+
+def is_masked(x):
+    """
+    Determine whether input has masked values.
+
+    Accepts any object as input, but always returns False unless the
+    input is a MaskedArray containing masked values.
+
+    Parameters
+    ----------
+    x : array_like
+        Array to check for masked values.
+
+    Returns
+    -------
+    result : bool
+        True if `x` is a MaskedArray with masked values, False otherwise.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.masked_equal([0, 1, 0, 2, 3], 0)
+    >>> x
+    masked_array(data = [-- 1 -- 2 3],
+          mask = [ True False  True False False],
+          fill_value=999999)
+    >>> ma.is_masked(x)
+    True
+    >>> x = ma.masked_equal([0, 1, 0, 2, 3], 42)
+    >>> x
+    masked_array(data = [0 1 0 2 3],
+          mask = False,
+          fill_value=999999)
+    >>> ma.is_masked(x)
+    False
+
+    Always returns False if `x` isn't a MaskedArray.
+
+    >>> x = [False, True, False]
+    >>> ma.is_masked(x)
+    False
+    >>> x = 'a string'
+    >>> ma.is_masked(x)
+    False
+
+    """
+    m = getmask(x)
+    if m is nomask:
+        return False
+    elif m.any():
+        return True
+    return False
+
+
+##############################################################################
+#                             Extrema functions                              #
+##############################################################################
+
+
+class _extrema_operation(object):
+    """
+    Generic class for maximum/minimum functions.
+
+    .. note::
+      This is the base class for `_maximum_operation` and
+      `_minimum_operation`.
+
+    """
+
+    def __call__(self, a, b=None):
+        "Executes the call behavior."
+        if b is None:
+            return self.reduce(a)
+        return where(self.compare(a, b), a, b)
+
+    def reduce(self, target, axis=None):
+        "Reduce target along the given axis."
+        target = narray(target, copy=False, subok=True)
+        m = getmask(target)
+        if axis is not None:
+            kargs = {'axis': axis}
+        else:
+            kargs = {}
+            target = target.ravel()
+            if not (m is nomask):
+                m = m.ravel()
+        if m is nomask:
+            t = self.ufunc.reduce(target, **kargs)
+        else:
+            target = target.filled(
+                self.fill_value_func(target)).view(type(target))
+            t = self.ufunc.reduce(target, **kargs)
+            m = umath.logical_and.reduce(m, **kargs)
+            if hasattr(t, '_mask'):
+                t._mask = m
+            elif m:
+                t = masked
+        return t
+
+    def outer(self, a, b):
+        "Return the function applied to the outer product of a and b."
+        ma = getmask(a)
+        mb = getmask(b)
+        if ma is nomask and mb is nomask:
+            m = nomask
+        else:
+            ma = getmaskarray(a)
+            mb = getmaskarray(b)
+            m = logical_or.outer(ma, mb)
+        result = self.ufunc.outer(filled(a), filled(b))
+        if not isinstance(result, MaskedArray):
+            result = result.view(MaskedArray)
+        result._mask = m
+        return result
+
+
+class _minimum_operation(_extrema_operation):
+
+    "Object to calculate minima"
+
+    def __init__(self):
+        """minimum(a, b) or minimum(a)
+In one argument case, returns the scalar minimum.
+        """
+        self.ufunc = umath.minimum
+        self.afunc = amin
+        self.compare = less
+        self.fill_value_func = minimum_fill_value
+
+
+class _maximum_operation(_extrema_operation):
+
+    "Object to calculate maxima"
+
+    def __init__(self):
+        """maximum(a, b) or maximum(a)
+           In one argument case returns the scalar maximum.
+        """
+        self.ufunc = umath.maximum
+        self.afunc = amax
+        self.compare = greater
+        self.fill_value_func = maximum_fill_value
+
+
+def min(obj, axis=None, out=None, fill_value=None):
+    try:
+        return obj.min(axis=axis, fill_value=fill_value, out=out)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a min method or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).min(axis=axis, fill_value=fill_value, out=out)
+min.__doc__ = MaskedArray.min.__doc__
+
+
+def max(obj, axis=None, out=None, fill_value=None):
+    try:
+        return obj.max(axis=axis, fill_value=fill_value, out=out)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a max method, or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).max(axis=axis, fill_value=fill_value, out=out)
+max.__doc__ = MaskedArray.max.__doc__
+
+
+def ptp(obj, axis=None, out=None, fill_value=None):
+    """
+    a.ptp(axis=None) =  a.max(axis) - a.min(axis)
+
+    """
+    try:
+        return obj.ptp(axis, out=out, fill_value=fill_value)
+    except (AttributeError, TypeError):
+        # If obj doesn't have a ptp method or if the method doesn't accept
+        # a fill_value argument
+        return asanyarray(obj).ptp(axis=axis, fill_value=fill_value, out=out)
+ptp.__doc__ = MaskedArray.ptp.__doc__
+
+
+##############################################################################
+#           Definition of functions from the corresponding methods           #
+##############################################################################
+
+
+class _frommethod:
+    """
+    Define functions from existing MaskedArray methods.
+
+    Parameters
+    ----------
+    methodname : str
+        Name of the method to transform.
+
+    """
+
+    def __init__(self, methodname, reversed=False):
+        self.__name__ = methodname
+        self.__doc__ = self.getdoc()
+        self.reversed = reversed
+
+    def getdoc(self):
+        "Return the doc of the function (from the doc of the method)."
+        meth = getattr(MaskedArray, self.__name__, None) or\
+            getattr(np, self.__name__, None)
+        signature = self.__name__ + get_object_signature(meth)
+        if meth is not None:
+            doc = """    %s\n%s""" % (
+                signature, getattr(meth, '__doc__', None))
+            return doc
+
+    def __call__(self, a, *args, **params):
+        if self.reversed:
+            args = list(args)
+            arr = args[0]
+            args[0] = a
+            a = arr
+        # Get the method from the array (if possible)
+        method_name = self.__name__
+        method = getattr(a, method_name, None)
+        if method is not None:
+            return method(*args, **params)
+        # Still here ? Then a is not a MaskedArray
+        method = getattr(MaskedArray, method_name, None)
+        if method is not None:
+            return method(MaskedArray(a), *args, **params)
+        # Still here ? OK, let's call the corresponding np function
+        method = getattr(np, method_name)
+        return method(a, *args, **params)
+
+
+all = _frommethod('all')
+anomalies = anom = _frommethod('anom')
+any = _frommethod('any')
+compress = _frommethod('compress', reversed=True)
+cumprod = _frommethod('cumprod')
+cumsum = _frommethod('cumsum')
+copy = _frommethod('copy')
+diagonal = _frommethod('diagonal')
+harden_mask = _frommethod('harden_mask')
+ids = _frommethod('ids')
+maximum = _maximum_operation()
+mean = _frommethod('mean')
+minimum = _minimum_operation()
+nonzero = _frommethod('nonzero')
+prod = _frommethod('prod')
+product = _frommethod('prod')
+ravel = _frommethod('ravel')
+repeat = _frommethod('repeat')
+shrink_mask = _frommethod('shrink_mask')
+soften_mask = _frommethod('soften_mask')
+std = _frommethod('std')
+sum = _frommethod('sum')
+swapaxes = _frommethod('swapaxes')
+#take = _frommethod('take')
+trace = _frommethod('trace')
+var = _frommethod('var')
+
+
+def take(a, indices, axis=None, out=None, mode='raise'):
+    """
+    """
+    a = masked_array(a)
+    return a.take(indices, axis=axis, out=out, mode=mode)
+
+
+def power(a, b, third=None):
+    """
+    Returns element-wise base array raised to power from second array.
+
+    This is the masked array version of `numpy.power`. For details see
+    `numpy.power`.
+
+    See Also
+    --------
+    numpy.power
+
+    Notes
+    -----
+    The *out* argument to `numpy.power` is not supported, `third` has to be
+    None.
+
+    """
+    if third is not None:
+        raise MaskError("3-argument power not supported.")
+    # Get the masks
+    ma = getmask(a)
+    mb = getmask(b)
+    m = mask_or(ma, mb)
+    # Get the rawdata
+    fa = getdata(a)
+    fb = getdata(b)
+    # Get the type of the result (so that we preserve subclasses)
+    if isinstance(a, MaskedArray):
+        basetype = type(a)
+    else:
+        basetype = MaskedArray
+    # Get the result and view it as a (subclass of) MaskedArray
+    with np.errstate(divide='ignore', invalid='ignore'):
+        result = np.where(m, fa, umath.power(fa, fb)).view(basetype)
+    result._update_from(a)
+    # Find where we're in trouble w/ NaNs and Infs
+    invalid = np.logical_not(np.isfinite(result.view(ndarray)))
+    # Add the initial mask
+    if m is not nomask:
+        if not (result.ndim):
+            return masked
+        result._mask = np.logical_or(m, invalid)
+    # Fix the invalid parts
+    if invalid.any():
+        if not result.ndim:
+            return masked
+        elif result._mask is nomask:
+            result._mask = invalid
+        result._data[invalid] = result.fill_value
+    return result
+
+
+def argsort(a, axis=None, kind='quicksort', order=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+    d = filled(a, fill_value)
+    if axis is None:
+        return d.argsort(kind=kind, order=order)
+    return d.argsort(axis, kind=kind, order=order)
+argsort.__doc__ = MaskedArray.argsort.__doc__
+
+
+def argmin(a, axis=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+    d = filled(a, fill_value)
+    return d.argmin(axis=axis)
+argmin.__doc__ = MaskedArray.argmin.__doc__
+
+
+def argmax(a, axis=None, fill_value=None):
+    "Function version of the eponymous method."
+    if fill_value is None:
+        fill_value = default_fill_value(a)
+        try:
+            fill_value = -fill_value
+        except:
+            pass
+    d = filled(a, fill_value)
+    return d.argmax(axis=axis)
+argmax.__doc__ = MaskedArray.argmax.__doc__
+
+
+def sort(a, axis=-1, kind='quicksort', order=None, endwith=True, fill_value=None):
+    "Function version of the eponymous method."
+    a = narray(a, copy=True, subok=True)
+    if axis is None:
+        a = a.flatten()
+        axis = 0
+    if fill_value is None:
+        if endwith:
+            # nan > inf
+            if np.issubdtype(a.dtype, np.floating):
+                filler = np.nan
+            else:
+                filler = minimum_fill_value(a)
+        else:
+            filler = maximum_fill_value(a)
+    else:
+        filler = fill_value
+
+    sindx = filled(a, filler).argsort(axis=axis, kind=kind, order=order)
+
+    # save meshgrid memory for 1d arrays
+    if a.ndim == 1:
+        indx = sindx
+    else:
+        indx = np.meshgrid(*[np.arange(x) for x in a.shape], sparse=True,
+                           indexing='ij')
+        indx[axis] = sindx
+    return a[indx]
+sort.__doc__ = MaskedArray.sort.__doc__
+
+
+def compressed(x):
+    """
+    Return all the non-masked data as a 1-D array.
+
+    This function is equivalent to calling the "compressed" method of a
+    `MaskedArray`, see `MaskedArray.compressed` for details.
+
+    See Also
+    --------
+    MaskedArray.compressed
+        Equivalent method.
+
+    """
+    if not isinstance(x, MaskedArray):
+        x = asanyarray(x)
+    return x.compressed()
+
+
+def concatenate(arrays, axis=0):
+    """
+    Concatenate a sequence of arrays along the given axis.
+
+    Parameters
+    ----------
+    arrays : sequence of array_like
+        The arrays must have the same shape, except in the dimension
+        corresponding to `axis` (the first, by default).
+    axis : int, optional
+        The axis along which the arrays will be joined. Default is 0.
+
+    Returns
+    -------
+    result : MaskedArray
+        The concatenated array with any masked entries preserved.
+
+    See Also
+    --------
+    numpy.concatenate : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.arange(3)
+    >>> a[1] = ma.masked
+    >>> b = ma.arange(2, 5)
+    >>> a
+    masked_array(data = [0 -- 2],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> b
+    masked_array(data = [2 3 4],
+                 mask = False,
+           fill_value = 999999)
+    >>> ma.concatenate([a, b])
+    masked_array(data = [0 -- 2 2 3 4],
+                 mask = [False  True False False False False],
+           fill_value = 999999)
+
+    """
+    d = np.concatenate([getdata(a) for a in arrays], axis)
+    rcls = get_masked_subclass(*arrays)
+    data = d.view(rcls)
+    # Check whether one of the arrays has a non-empty mask.
+    for x in arrays:
+        if getmask(x) is not nomask:
+            break
+    else:
+        return data
+    # OK, so we have to concatenate the masks
+    dm = np.concatenate([getmaskarray(a) for a in arrays], axis)
+    # If we decide to keep a '_shrinkmask' option, we want to check that
+    # all of them are True, and then check for dm.any()
+    if not dm.dtype.fields and not dm.any():
+        data._mask = nomask
+    else:
+        data._mask = dm.reshape(d.shape)
+    return data
+
+
+def count(a, axis=None):
+    if isinstance(a, MaskedArray):
+        return a.count(axis)
+    return masked_array(a, copy=False).count(axis)
+count.__doc__ = MaskedArray.count.__doc__
+
+
+def diag(v, k=0):
+    """
+    Extract a diagonal or construct a diagonal array.
+
+    This function is the equivalent of `numpy.diag` that takes masked
+    values into account, see `numpy.diag` for details.
+
+    See Also
+    --------
+    numpy.diag : Equivalent function for ndarrays.
+
+    """
+    output = np.diag(v, k).view(MaskedArray)
+    if getmask(v) is not nomask:
+        output._mask = np.diag(v._mask, k)
+    return output
+
+
+def expand_dims(x, axis):
+    """
+    Expand the shape of an array.
+
+    Expands the shape of the array by including a new axis before the one
+    specified by the `axis` parameter. This function behaves the same as
+    `numpy.expand_dims` but preserves masked elements.
+
+    See Also
+    --------
+    numpy.expand_dims : Equivalent function in top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.array([1, 2, 4])
+    >>> x[1] = ma.masked
+    >>> x
+    masked_array(data = [1 -- 4],
+                 mask = [False  True False],
+           fill_value = 999999)
+    >>> np.expand_dims(x, axis=0)
+    array([[1, 2, 4]])
+    >>> ma.expand_dims(x, axis=0)
+    masked_array(data =
+     [[1 -- 4]],
+                 mask =
+     [[False  True False]],
+           fill_value = 999999)
+
+    The same result can be achieved using slicing syntax with `np.newaxis`.
+
+    >>> x[np.newaxis, :]
+    masked_array(data =
+     [[1 -- 4]],
+                 mask =
+     [[False  True False]],
+           fill_value = 999999)
+
+    """
+    result = n_expand_dims(x, axis)
+    if isinstance(x, MaskedArray):
+        new_shape = result.shape
+        result = x.view()
+        result.shape = new_shape
+        if result._mask is not nomask:
+            result._mask.shape = new_shape
+    return result
+
+
+def left_shift(a, n):
+    """
+    Shift the bits of an integer to the left.
+
+    This is the masked array version of `numpy.left_shift`, for details
+    see that function.
+
+    See Also
+    --------
+    numpy.left_shift
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        d = umath.left_shift(filled(a), n)
+        return masked_array(d)
+    else:
+        d = umath.left_shift(filled(a, 0), n)
+        return masked_array(d, mask=m)
+
+
+def right_shift(a, n):
+    """
+    Shift the bits of an integer to the right.
+
+    This is the masked array version of `numpy.right_shift`, for details
+    see that function.
+
+    See Also
+    --------
+    numpy.right_shift
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        d = umath.right_shift(filled(a), n)
+        return masked_array(d)
+    else:
+        d = umath.right_shift(filled(a, 0), n)
+        return masked_array(d, mask=m)
+
+
+def put(a, indices, values, mode='raise'):
+    """
+    Set storage-indexed locations to corresponding values.
+
+    This function is equivalent to `MaskedArray.put`, see that method
+    for details.
+
+    See Also
+    --------
+    MaskedArray.put
+
+    """
+    # We can't use 'frommethod', the order of arguments is different
+    try:
+        return a.put(indices, values, mode=mode)
+    except AttributeError:
+        return narray(a, copy=False).put(indices, values, mode=mode)
+
+
+def putmask(a, mask, values):  # , mode='raise'):
+    """
+    Changes elements of an array based on conditional and input values.
+
+    This is the masked array version of `numpy.putmask`, for details see
+    `numpy.putmask`.
+
+    See Also
+    --------
+    numpy.putmask
+
+    Notes
+    -----
+    Using a masked array as `values` will **not** transform a `ndarray` into
+    a `MaskedArray`.
+
+    """
+    # We can't use 'frommethod', the order of arguments is different
+    if not isinstance(a, MaskedArray):
+        a = a.view(MaskedArray)
+    (valdata, valmask) = (getdata(values), getmask(values))
+    if getmask(a) is nomask:
+        if valmask is not nomask:
+            a._sharedmask = True
+            a._mask = make_mask_none(a.shape, a.dtype)
+            np.copyto(a._mask, valmask, where=mask)
+    elif a._hardmask:
+        if valmask is not nomask:
+            m = a._mask.copy()
+            np.copyto(m, valmask, where=mask)
+            a.mask |= m
+    else:
+        if valmask is nomask:
+            valmask = getmaskarray(values)
+        np.copyto(a._mask, valmask, where=mask)
+    np.copyto(a._data, valdata, where=mask)
+    return
+
+
+def transpose(a, axes=None):
+    """
+    Permute the dimensions of an array.
+
+    This function is exactly equivalent to `numpy.transpose`.
+
+    See Also
+    --------
+    numpy.transpose : Equivalent function in top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> x = ma.arange(4).reshape((2,2))
+    >>> x[1, 1] = ma.masked
+    >>>> x
+    masked_array(data =
+     [[0 1]
+     [2 --]],
+                 mask =
+     [[False False]
+     [False  True]],
+           fill_value = 999999)
+    >>> ma.transpose(x)
+    masked_array(data =
+     [[0 2]
+     [1 --]],
+                 mask =
+     [[False False]
+     [False  True]],
+           fill_value = 999999)
+
+    """
+    # We can't use 'frommethod', as 'transpose' doesn't take keywords
+    try:
+        return a.transpose(axes)
+    except AttributeError:
+        return narray(a, copy=False).transpose(axes).view(MaskedArray)
+
+
+def reshape(a, new_shape, order='C'):
+    """
+    Returns an array containing the same data with a new shape.
+
+    Refer to `MaskedArray.reshape` for full documentation.
+
+    See Also
+    --------
+    MaskedArray.reshape : equivalent function
+
+    """
+    # We can't use 'frommethod', it whine about some parameters. Dmmit.
+    try:
+        return a.reshape(new_shape, order=order)
+    except AttributeError:
+        _tmp = narray(a, copy=False).reshape(new_shape, order=order)
+        return _tmp.view(MaskedArray)
+
+
+def resize(x, new_shape):
+    """
+    Return a new masked array with the specified size and shape.
+
+    This is the masked equivalent of the `numpy.resize` function. The new
+    array is filled with repeated copies of `x` (in the order that the
+    data are stored in memory). If `x` is masked, the new array will be
+    masked, and the new mask will be a repetition of the old one.
+
+    See Also
+    --------
+    numpy.resize : Equivalent function in the top level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.array([[1, 2] ,[3, 4]])
+    >>> a[0, 1] = ma.masked
+    >>> a
+    masked_array(data =
+     [[1 --]
+     [3 4]],
+                 mask =
+     [[False  True]
+     [False False]],
+           fill_value = 999999)
+    >>> np.resize(a, (3, 3))
+    array([[1, 2, 3],
+           [4, 1, 2],
+           [3, 4, 1]])
+    >>> ma.resize(a, (3, 3))
+    masked_array(data =
+     [[1 -- 3]
+     [4 1 --]
+     [3 4 1]],
+                 mask =
+     [[False  True False]
+     [False False  True]
+     [False False False]],
+           fill_value = 999999)
+
+    A MaskedArray is always returned, regardless of the input type.
+
+    >>> a = np.array([[1, 2] ,[3, 4]])
+    >>> ma.resize(a, (3, 3))
+    masked_array(data =
+     [[1 2 3]
+     [4 1 2]
+     [3 4 1]],
+                 mask =
+     False,
+           fill_value = 999999)
+
+    """
+    # We can't use _frommethods here, as N.resize is notoriously whiny.
+    m = getmask(x)
+    if m is not nomask:
+        m = np.resize(m, new_shape)
+    result = np.resize(x, new_shape).view(get_masked_subclass(x))
+    if result.ndim:
+        result._mask = m
+    return result
+
+
+def rank(obj):
+    """
+    maskedarray version of the numpy function.
+
+    .. note::
+        Deprecated since 1.10.0
+
+    """
+    # 2015-04-12, 1.10.0
+    warnings.warn(
+        "`rank` is deprecated; use the `ndim` function instead. ",
+        np.VisibleDeprecationWarning)
+    return np.ndim(getdata(obj))
+
+rank.__doc__ = np.rank.__doc__
+
+
+def ndim(obj):
+    """
+    maskedarray version of the numpy function.
+
+    """
+    return np.ndim(getdata(obj))
+
+ndim.__doc__ = np.ndim.__doc__
+
+
+def shape(obj):
+    "maskedarray version of the numpy function."
+    return np.shape(getdata(obj))
+shape.__doc__ = np.shape.__doc__
+
+
+def size(obj, axis=None):
+    "maskedarray version of the numpy function."
+    return np.size(getdata(obj), axis)
+size.__doc__ = np.size.__doc__
+
+
+##############################################################################
+#                            Extra functions                                 #
+##############################################################################
+
+
+def where(condition, x=_NoValue, y=_NoValue):
+    """
+    Return a masked array with elements from x or y, depending on condition.
+
+    Returns a masked array, shaped like condition, where the elements
+    are from `x` when `condition` is True, and from `y` otherwise.
+    If neither `x` nor `y` are given, the function returns a tuple of
+    indices where `condition` is True (the result of
+    ``condition.nonzero()``).
+
+    Parameters
+    ----------
+    condition : array_like, bool
+        The condition to meet. For each True element, yield the corresponding
+        element from `x`, otherwise from `y`.
+    x, y : array_like, optional
+        Values from which to choose. `x` and `y` need to have the same shape
+        as condition, or be broadcast-able to that shape.
+
+    Returns
+    -------
+    out : MaskedArray or tuple of ndarrays
+        The resulting masked array if `x` and `y` were given, otherwise
+        the result of ``condition.nonzero()``.
+
+    See Also
+    --------
+    numpy.where : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9.).reshape(3, 3), mask=[[0, 1, 0],
+    ...                                                    [1, 0, 1],
+    ...                                                    [0, 1, 0]])
+    >>> print(x)
+    [[0.0 -- 2.0]
+     [-- 4.0 --]
+     [6.0 -- 8.0]]
+    >>> np.ma.where(x > 5)    # return the indices where x > 5
+    (array([2, 2]), array([0, 2]))
+
+    >>> print(np.ma.where(x > 5, x, -3.1416))
+    [[-3.1416 -- -3.1416]
+     [-- -3.1416 --]
+     [6.0 -- 8.0]]
+
+    """
+    missing = (x is _NoValue, y is _NoValue).count(True)
+
+    if missing == 1:
+        raise ValueError("Must provide both 'x' and 'y' or neither.")
+    if missing == 2:
+        return filled(condition, 0).nonzero()
+
+    # Both x and y are provided
+
+    # Get the condition
+    fc = filled(condition, 0).astype(MaskType)
+    notfc = np.logical_not(fc)
+
+    # Get the data
+    xv = getdata(x)
+    yv = getdata(y)
+    if x is masked:
+        ndtype = yv.dtype
+    elif y is masked:
+        ndtype = xv.dtype
+    else:
+        ndtype = np.find_common_type([xv.dtype, yv.dtype], [])
+
+    # Construct an empty array and fill it
+    d = np.empty(fc.shape, dtype=ndtype).view(MaskedArray)
+    np.copyto(d._data, xv.astype(ndtype), where=fc)
+    np.copyto(d._data, yv.astype(ndtype), where=notfc)
+
+    # Create an empty mask and fill it
+    mask = np.zeros(fc.shape, dtype=MaskType)
+    np.copyto(mask, getmask(x), where=fc)
+    np.copyto(mask, getmask(y), where=notfc)
+    mask |= getmaskarray(condition)
+
+    # Use d._mask instead of d.mask to avoid copies
+    d._mask = mask if mask.any() else nomask
+
+    return d
+
+
+def choose(indices, choices, out=None, mode='raise'):
+    """
+    Use an index array to construct a new array from a set of choices.
+
+    Given an array of integers and a set of n choice arrays, this method
+    will create a new array that merges each of the choice arrays.  Where a
+    value in `a` is i, the new array will have the value that choices[i]
+    contains in the same place.
+
+    Parameters
+    ----------
+    a : ndarray of ints
+        This array must contain integers in ``[0, n-1]``, where n is the
+        number of choices.
+    choices : sequence of arrays
+        Choice arrays. The index array and all of the choices should be
+        broadcastable to the same shape.
+    out : array, optional
+        If provided, the result will be inserted into this array. It should
+        be of the appropriate shape and `dtype`.
+    mode : {'raise', 'wrap', 'clip'}, optional
+        Specifies how out-of-bounds indices will behave.
+
+        * 'raise' : raise an error
+        * 'wrap' : wrap around
+        * 'clip' : clip to the range
+
+    Returns
+    -------
+    merged_array : array
+
+    See Also
+    --------
+    choose : equivalent function
+
+    Examples
+    --------
+    >>> choice = np.array([[1,1,1], [2,2,2], [3,3,3]])
+    >>> a = np.array([2, 1, 0])
+    >>> np.ma.choose(a, choice)
+    masked_array(data = [3 2 1],
+          mask = False,
+          fill_value=999999)
+
+    """
+    def fmask(x):
+        "Returns the filled array, or True if masked."
+        if x is masked:
+            return True
+        return filled(x)
+
+    def nmask(x):
+        "Returns the mask, True if ``masked``, False if ``nomask``."
+        if x is masked:
+            return True
+        return getmask(x)
+    # Get the indices.
+    c = filled(indices, 0)
+    # Get the masks.
+    masks = [nmask(x) for x in choices]
+    data = [fmask(x) for x in choices]
+    # Construct the mask
+    outputmask = np.choose(c, masks, mode=mode)
+    outputmask = make_mask(mask_or(outputmask, getmask(indices)),
+                           copy=0, shrink=True)
+    # Get the choices.
+    d = np.choose(c, data, mode=mode, out=out).view(MaskedArray)
+    if out is not None:
+        if isinstance(out, MaskedArray):
+            out.__setmask__(outputmask)
+        return out
+    d.__setmask__(outputmask)
+    return d
+
+
+def round_(a, decimals=0, out=None):
+    """
+    Return a copy of a, rounded to 'decimals' places.
+
+    When 'decimals' is negative, it specifies the number of positions
+    to the left of the decimal point.  The real and imaginary parts of
+    complex numbers are rounded separately. Nothing is done if the
+    array is not of float type and 'decimals' is greater than or equal
+    to 0.
+
+    Parameters
+    ----------
+    decimals : int
+        Number of decimals to round to. May be negative.
+    out : array_like
+        Existing array to use for output.
+        If not given, returns a default copy of a.
+
+    Notes
+    -----
+    If out is given and does not have a mask attribute, the mask of a
+    is lost!
+
+    """
+    if out is None:
+        return np.round_(a, decimals, out)
+    else:
+        np.round_(getdata(a), decimals, out)
+        if hasattr(out, '_mask'):
+            out._mask = getmask(a)
+        return out
+round = round_
+
+
+# Needed by dot, so move here from extras.py. It will still be exported
+# from extras.py for compatibility.
+def mask_rowcols(a, axis=None):
+    """
+    Mask rows and/or columns of a 2D array that contain masked values.
+
+    Mask whole rows and/or columns of a 2D array that contain
+    masked values.  The masking behavior is selected using the
+    `axis` parameter.
+
+      - If `axis` is None, rows *and* columns are masked.
+      - If `axis` is 0, only rows are masked.
+      - If `axis` is 1 or -1, only columns are masked.
+
+    Parameters
+    ----------
+    a : array_like, MaskedArray
+        The array to mask.  If not a MaskedArray instance (or if no array
+        elements are masked).  The result is a MaskedArray with `mask` set
+        to `nomask` (False). Must be a 2D array.
+    axis : int, optional
+        Axis along which to perform the operation. If None, applies to a
+        flattened version of the array.
+
+    Returns
+    -------
+    a : MaskedArray
+        A modified version of the input array, masked depending on the value
+        of the `axis` parameter.
+
+    Raises
+    ------
+    NotImplementedError
+        If input array `a` is not 2D.
+
+    See Also
+    --------
+    mask_rows : Mask rows of a 2D array that contain masked values.
+    mask_cols : Mask cols of a 2D array that contain masked values.
+    masked_where : Mask where a condition is met.
+
+    Notes
+    -----
+    The input array's mask is modified by this function.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_rowcols(a)
+    masked_array(data =
+     [[0 -- 0]
+     [-- -- --]
+     [0 -- 0]],
+          mask =
+     [[False  True False]
+     [ True  True  True]
+     [False  True False]],
+          fill_value=999999)
+
+    """
+    a = array(a, subok=False)
+    if a.ndim != 2:
+        raise NotImplementedError("mask_rowcols works for 2D arrays only.")
+    m = getmask(a)
+    # Nothing is masked: return a
+    if m is nomask or not m.any():
+        return a
+    maskedval = m.nonzero()
+    a._mask = a._mask.copy()
+    if not axis:
+        a[np.unique(maskedval[0])] = masked
+    if axis in [None, 1, -1]:
+        a[:, np.unique(maskedval[1])] = masked
+    return a
+
+
+# Include masked dot here to avoid import problems in getting it from
+# extras.py. Note that it is not included in __all__, but rather exported
+# from extras in order to avoid backward compatibility problems.
+def dot(a, b, strict=False, out=None):
+    """
+    Return the dot product of two arrays.
+
+    This function is the equivalent of `numpy.dot` that takes masked values
+    into account. Note that `strict` and `out` are in different position
+    than in the method version. In order to maintain compatibility with the
+    corresponding method, it is recommended that the optional arguments be
+    treated as keyword only.  At some point that may be mandatory.
+
+    .. note::
+      Works only with 2-D arrays at the moment.
+
+
+    Parameters
+    ----------
+    a, b : masked_array_like
+        Inputs arrays.
+    strict : bool, optional
+        Whether masked data are propagated (True) or set to 0 (False) for
+        the computation. Default is False.  Propagating the mask means that
+        if a masked value appears in a row or column, the whole row or
+        column is considered masked.
+    out : masked_array, optional
+        Output argument. This must have the exact kind that would be returned
+        if it was not used. In particular, it must have the right type, must be
+        C-contiguous, and its dtype must be the dtype that would be returned
+        for `dot(a,b)`. This is a performance feature. Therefore, if these
+        conditions are not met, an exception is raised, instead of attempting
+        to be flexible.
+
+        .. versionadded:: 1.10.2
+
+    See Also
+    --------
+    numpy.dot : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> a = ma.array([[1, 2, 3], [4, 5, 6]], mask=[[1, 0, 0], [0, 0, 0]])
+    >>> b = ma.array([[1, 2], [3, 4], [5, 6]], mask=[[1, 0], [0, 0], [0, 0]])
+    >>> np.ma.dot(a, b)
+    masked_array(data =
+     [[21 26]
+     [45 64]],
+                 mask =
+     [[False False]
+     [False False]],
+           fill_value = 999999)
+    >>> np.ma.dot(a, b, strict=True)
+    masked_array(data =
+     [[-- --]
+     [-- 64]],
+                 mask =
+     [[ True  True]
+     [ True False]],
+           fill_value = 999999)
+
+    """
+    # !!!: Works only with 2D arrays. There should be a way to get it to run
+    # with higher dimension
+    if strict and (a.ndim == 2) and (b.ndim == 2):
+        a = mask_rowcols(a, 0)
+        b = mask_rowcols(b, 1)
+    am = ~getmaskarray(a)
+    bm = ~getmaskarray(b)
+
+    if out is None:
+        d = np.dot(filled(a, 0), filled(b, 0))
+        m = ~np.dot(am, bm)
+        if d.ndim == 0:
+            d = np.asarray(d)
+        r = d.view(get_masked_subclass(a, b))
+        r.__setmask__(m)
+        return r
+    else:
+        d = np.dot(filled(a, 0), filled(b, 0), out._data)
+        if out.mask.shape != d.shape:
+            out._mask = np.empty(d.shape, MaskType)
+        np.dot(am, bm, out._mask)
+        np.logical_not(out._mask, out._mask)
+        return out
+
+
+def inner(a, b):
+    """
+    Returns the inner product of a and b for arrays of floating point types.
+
+    Like the generic NumPy equivalent the product sum is over the last dimension
+    of a and b.
+
+    Notes
+    -----
+    The first argument is not conjugated.
+
+    """
+    fa = filled(a, 0)
+    fb = filled(b, 0)
+    if len(fa.shape) == 0:
+        fa.shape = (1,)
+    if len(fb.shape) == 0:
+        fb.shape = (1,)
+    return np.inner(fa, fb).view(MaskedArray)
+inner.__doc__ = doc_note(np.inner.__doc__,
+                         "Masked values are replaced by 0.")
+innerproduct = inner
+
+
+def outer(a, b):
+    "maskedarray version of the numpy function."
+    fa = filled(a, 0).ravel()
+    fb = filled(b, 0).ravel()
+    d = np.outer(fa, fb)
+    ma = getmask(a)
+    mb = getmask(b)
+    if ma is nomask and mb is nomask:
+        return masked_array(d)
+    ma = getmaskarray(a)
+    mb = getmaskarray(b)
+    m = make_mask(1 - np.outer(1 - ma, 1 - mb), copy=0)
+    return masked_array(d, mask=m)
+outer.__doc__ = doc_note(np.outer.__doc__,
+                         "Masked values are replaced by 0.")
+outerproduct = outer
+
+
+def allequal(a, b, fill_value=True):
+    """
+    Return True if all entries of a and b are equal, using
+    fill_value as a truth value where either or both are masked.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    fill_value : bool, optional
+        Whether masked values in a or b are considered equal (True) or not
+        (False).
+
+    Returns
+    -------
+    y : bool
+        Returns True if the two arrays are equal within the given
+        tolerance, False otherwise. If either array contains NaN,
+        then False is returned.
+
+    See Also
+    --------
+    all, any
+    numpy.ma.allclose
+
+    Examples
+    --------
+    >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
+    >>> a
+    masked_array(data = [10000000000.0 1e-07 --],
+          mask = [False False  True],
+          fill_value=1e+20)
+
+    >>> b = array([1e10, 1e-7, -42.0])
+    >>> b
+    array([  1.00000000e+10,   1.00000000e-07,  -4.20000000e+01])
+    >>> ma.allequal(a, b, fill_value=False)
+    False
+    >>> ma.allequal(a, b)
+    True
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    if m is nomask:
+        x = getdata(a)
+        y = getdata(b)
+        d = umath.equal(x, y)
+        return d.all()
+    elif fill_value:
+        x = getdata(a)
+        y = getdata(b)
+        d = umath.equal(x, y)
+        dm = array(d, mask=m, copy=False)
+        return dm.filled(True).all(None)
+    else:
+        return False
+
+
+def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8):
+    """
+    Returns True if two arrays are element-wise equal within a tolerance.
+
+    This function is equivalent to `allclose` except that masked values
+    are treated as equal (default) or unequal, depending on the `masked_equal`
+    argument.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to compare.
+    masked_equal : bool, optional
+        Whether masked values in `a` and `b` are considered equal (True) or not
+        (False). They are considered equal by default.
+    rtol : float, optional
+        Relative tolerance. The relative difference is equal to ``rtol * b``.
+        Default is 1e-5.
+    atol : float, optional
+        Absolute tolerance. The absolute difference is equal to `atol`.
+        Default is 1e-8.
+
+    Returns
+    -------
+    y : bool
+        Returns True if the two arrays are equal within the given
+        tolerance, False otherwise. If either array contains NaN, then
+        False is returned.
+
+    See Also
+    --------
+    all, any
+    numpy.allclose : the non-masked `allclose`.
+
+    Notes
+    -----
+    If the following equation is element-wise True, then `allclose` returns
+    True::
+
+      absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+
+    Return True if all elements of `a` and `b` are equal subject to
+    given tolerances.
+
+    Examples
+    --------
+    >>> a = ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1])
+    >>> a
+    masked_array(data = [10000000000.0 1e-07 --],
+                 mask = [False False  True],
+           fill_value = 1e+20)
+    >>> b = ma.array([1e10, 1e-8, -42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    False
+
+    >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
+    >>> b = ma.array([1.00001e10, 1e-9, -42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    True
+    >>> ma.allclose(a, b, masked_equal=False)
+    False
+
+    Masked values are not compared directly.
+
+    >>> a = ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1])
+    >>> b = ma.array([1.00001e10, 1e-9, 42.0], mask=[0, 0, 1])
+    >>> ma.allclose(a, b)
+    True
+    >>> ma.allclose(a, b, masked_equal=False)
+    False
+
+    """
+    x = masked_array(a, copy=False)
+    y = masked_array(b, copy=False)
+
+    # make sure y is an inexact type to avoid abs(MIN_INT); will cause
+    # casting of x later.
+    dtype = np.result_type(y, 1.)
+    if y.dtype != dtype:
+        y = masked_array(y, dtype=dtype, copy=False)
+
+    m = mask_or(getmask(x), getmask(y))
+    xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False)
+    # If we have some infs, they should fall at the same place.
+    if not np.all(xinf == filled(np.isinf(y), False)):
+        return False
+    # No infs at all
+    if not np.any(xinf):
+        d = filled(umath.less_equal(umath.absolute(x - y),
+                                    atol + rtol * umath.absolute(y)),
+                   masked_equal)
+        return np.all(d)
+
+    if not np.all(filled(x[xinf] == y[xinf], masked_equal)):
+        return False
+    x = x[~xinf]
+    y = y[~xinf]
+
+    d = filled(umath.less_equal(umath.absolute(x - y),
+                                atol + rtol * umath.absolute(y)),
+               masked_equal)
+
+    return np.all(d)
+
+
+def asarray(a, dtype=None, order=None):
+    """
+    Convert the input to a masked array of the given data-type.
+
+    No copy is performed if the input is already an `ndarray`. If `a` is
+    a subclass of `MaskedArray`, a base class `MaskedArray` is returned.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to a masked array. This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists, ndarrays and masked arrays.
+    dtype : dtype, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major ('C') or column-major ('FORTRAN') memory
+        representation.  Default is 'C'.
+
+    Returns
+    -------
+    out : MaskedArray
+        Masked array interpretation of `a`.
+
+    See Also
+    --------
+    asanyarray : Similar to `asarray`, but conserves subclasses.
+
+    Examples
+    --------
+    >>> x = np.arange(10.).reshape(2, 5)
+    >>> x
+    array([[ 0.,  1.,  2.,  3.,  4.],
+           [ 5.,  6.,  7.,  8.,  9.]])
+    >>> np.ma.asarray(x)
+    masked_array(data =
+     [[ 0.  1.  2.  3.  4.]
+     [ 5.  6.  7.  8.  9.]],
+                 mask =
+     False,
+           fill_value = 1e+20)
+    >>> type(np.ma.asarray(x))
+    <class 'numpy.ma.core.MaskedArray'>
+
+    """
+    order = order or 'C'
+    return masked_array(a, dtype=dtype, copy=False, keep_mask=True,
+                        subok=False, order=order)
+
+
+def asanyarray(a, dtype=None):
+    """
+    Convert the input to a masked array, conserving subclasses.
+
+    If `a` is a subclass of `MaskedArray`, its class is conserved.
+    No copy is performed if the input is already an `ndarray`.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.
+    dtype : dtype, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major ('C') or column-major ('FORTRAN') memory
+        representation.  Default is 'C'.
+
+    Returns
+    -------
+    out : MaskedArray
+        MaskedArray interpretation of `a`.
+
+    See Also
+    --------
+    asarray : Similar to `asanyarray`, but does not conserve subclass.
+
+    Examples
+    --------
+    >>> x = np.arange(10.).reshape(2, 5)
+    >>> x
+    array([[ 0.,  1.,  2.,  3.,  4.],
+           [ 5.,  6.,  7.,  8.,  9.]])
+    >>> np.ma.asanyarray(x)
+    masked_array(data =
+     [[ 0.  1.  2.  3.  4.]
+     [ 5.  6.  7.  8.  9.]],
+                 mask =
+     False,
+           fill_value = 1e+20)
+    >>> type(np.ma.asanyarray(x))
+    <class 'numpy.ma.core.MaskedArray'>
+
+    """
+    return masked_array(a, dtype=dtype, copy=False, keep_mask=True, subok=True)
+
+
+##############################################################################
+#                               Pickling                                     #
+##############################################################################
+def dump(a, F):
+    """
+    Pickle a masked array to a file.
+
+    This is a wrapper around ``cPickle.dump``.
+
+    Parameters
+    ----------
+    a : MaskedArray
+        The array to be pickled.
+    F : str or file-like object
+        The file to pickle `a` to. If a string, the full path to the file.
+
+    """
+    if not hasattr(F, 'readline'):
+        F = open(F, 'w')
+    return pickle.dump(a, F)
+
+
+def dumps(a):
+    """
+    Return a string corresponding to the pickling of a masked array.
+
+    This is a wrapper around ``cPickle.dumps``.
+
+    Parameters
+    ----------
+    a : MaskedArray
+        The array for which the string representation of the pickle is
+        returned.
+
+    """
+    return pickle.dumps(a)
+
+
+def load(F):
+    """
+    Wrapper around ``cPickle.load`` which accepts either a file-like object
+    or a filename.
+
+    Parameters
+    ----------
+    F : str or file
+        The file or file name to load.
+
+    See Also
+    --------
+    dump : Pickle an array
+
+    Notes
+    -----
+    This is different from `numpy.load`, which does not use cPickle but loads
+    the NumPy binary .npy format.
+
+    """
+    if not hasattr(F, 'readline'):
+        F = open(F, 'r')
+    return pickle.load(F)
+
+
+def loads(strg):
+    """
+    Load a pickle from the current string.
+
+    The result of ``cPickle.loads(strg)`` is returned.
+
+    Parameters
+    ----------
+    strg : str
+        The string to load.
+
+    See Also
+    --------
+    dumps : Return a string corresponding to the pickling of a masked array.
+
+    """
+    return pickle.loads(strg)
+
+
+def fromfile(file, dtype=float, count=-1, sep=''):
+    raise NotImplementedError(
+        "fromfile() not yet implemented for a MaskedArray.")
+
+
+def fromflex(fxarray):
+    """
+    Build a masked array from a suitable flexible-type array.
+
+    The input array has to have a data-type with ``_data`` and ``_mask``
+    fields. This type of array is output by `MaskedArray.toflex`.
+
+    Parameters
+    ----------
+    fxarray : ndarray
+        The structured input array, containing ``_data`` and ``_mask``
+        fields. If present, other fields are discarded.
+
+    Returns
+    -------
+    result : MaskedArray
+        The constructed masked array.
+
+    See Also
+    --------
+    MaskedArray.toflex : Build a flexible-type array from a masked array.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[0] + [1, 0] * 4)
+    >>> rec = x.toflex()
+    >>> rec
+    array([[(0, False), (1, True), (2, False)],
+           [(3, True), (4, False), (5, True)],
+           [(6, False), (7, True), (8, False)]],
+          dtype=[('_data', '<i4'), ('_mask', '|b1')])
+    >>> x2 = np.ma.fromflex(rec)
+    >>> x2
+    masked_array(data =
+     [[0 -- 2]
+     [-- 4 --]
+     [6 -- 8]],
+                 mask =
+     [[False  True False]
+     [ True False  True]
+     [False  True False]],
+           fill_value = 999999)
+
+    Extra fields can be present in the structured array but are discarded:
+
+    >>> dt = [('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')]
+    >>> rec2 = np.zeros((2, 2), dtype=dt)
+    >>> rec2
+    array([[(0, False, 0.0), (0, False, 0.0)],
+           [(0, False, 0.0), (0, False, 0.0)]],
+          dtype=[('_data', '<i4'), ('_mask', '|b1'), ('field3', '<f4')])
+    >>> y = np.ma.fromflex(rec2)
+    >>> y
+    masked_array(data =
+     [[0 0]
+     [0 0]],
+                 mask =
+     [[False False]
+     [False False]],
+           fill_value = 999999)
+
+    """
+    return masked_array(fxarray['_data'], mask=fxarray['_mask'])
+
+
+class _convert2ma:
+
+    """
+    Convert functions from numpy to numpy.ma.
+
+    Parameters
+    ----------
+        _methodname : string
+            Name of the method to transform.
+
+    """
+    __doc__ = None
+
+    def __init__(self, funcname, params=None):
+        self._func = getattr(np, funcname)
+        self.__doc__ = self.getdoc()
+        self._extras = params or {}
+
+    def getdoc(self):
+        "Return the doc of the function (from the doc of the method)."
+        doc = getattr(self._func, '__doc__', None)
+        sig = get_object_signature(self._func)
+        if doc:
+            # Add the signature of the function at the beginning of the doc
+            if sig:
+                sig = "%s%s\n" % (self._func.__name__, sig)
+            doc = sig + doc
+        return doc
+
+    def __call__(self, *args, **params):
+        # Find the common parameters to the call and the definition
+        _extras = self._extras
+        common_params = set(params).intersection(_extras)
+        # Drop the common parameters from the call
+        for p in common_params:
+            _extras[p] = params.pop(p)
+        # Get the result
+        result = self._func.__call__(*args, **params).view(MaskedArray)
+        if "fill_value" in common_params:
+            result.fill_value = _extras.get("fill_value", None)
+        if "hardmask" in common_params:
+            result._hardmask = bool(_extras.get("hard_mask", False))
+        return result
+
+arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False))
+clip = np.clip
+diff = np.diff
+empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False))
+empty_like = _convert2ma('empty_like')
+frombuffer = _convert2ma('frombuffer')
+fromfunction = _convert2ma('fromfunction')
+identity = _convert2ma(
+    'identity', params=dict(fill_value=None, hardmask=False))
+indices = np.indices
+ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False))
+ones_like = np.ones_like
+squeeze = np.squeeze
+zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False))
+zeros_like = np.zeros_like
+
+
+def append(a, b, axis=None):
+    """Append values to the end of an array.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    a : array_like
+        Values are appended to a copy of this array.
+    b : array_like
+        These values are appended to a copy of `a`.  It must be of the
+        correct shape (the same shape as `a`, excluding `axis`).  If `axis`
+        is not specified, `b` can be any shape and will be flattened
+        before use.
+    axis : int, optional
+        The axis along which `v` are appended.  If `axis` is not given,
+        both `a` and `b` are flattened before use.
+
+    Returns
+    -------
+    append : MaskedArray
+        A copy of `a` with `b` appended to `axis`.  Note that `append`
+        does not occur in-place: a new array is allocated and filled.  If
+        `axis` is None, the result is a flattened array.
+
+    See Also
+    --------
+    numpy.append : Equivalent function in the top-level NumPy module.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = ma.masked_values([1, 2, 3], 2)
+    >>> b = ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
+    >>> print(ma.append(a, b))
+    [1 -- 3 4 5 6 -- 8 9]
+    """
+    return concatenate([a, b], axis)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/extras.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/extras.py
new file mode 100644
index 0000000000..6e091652e5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/extras.py
@@ -0,0 +1,1819 @@
+"""
+Masked arrays add-ons.
+
+A collection of utilities for `numpy.ma`.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = [
+    'apply_along_axis', 'apply_over_axes', 'atleast_1d', 'atleast_2d',
+    'atleast_3d', 'average', 'clump_masked', 'clump_unmasked',
+    'column_stack', 'compress_cols', 'compress_nd', 'compress_rowcols',
+    'compress_rows', 'count_masked', 'corrcoef', 'cov', 'diagflat', 'dot',
+    'dstack', 'ediff1d', 'flatnotmasked_contiguous', 'flatnotmasked_edges',
+    'hsplit', 'hstack', 'in1d', 'intersect1d', 'mask_cols', 'mask_rowcols',
+    'mask_rows', 'masked_all', 'masked_all_like', 'median', 'mr_',
+    'notmasked_contiguous', 'notmasked_edges', 'polyfit', 'row_stack',
+    'setdiff1d', 'setxor1d', 'unique', 'union1d', 'vander', 'vstack',
+    ]
+
+import itertools
+import warnings
+
+from . import core as ma
+from .core import (
+    MaskedArray, MAError, add, array, asarray, concatenate, filled,
+    getmask, getmaskarray, make_mask_descr, masked, masked_array, mask_or,
+    nomask, ones, sort, zeros, getdata, get_masked_subclass, dot,
+    mask_rowcols
+    )
+
+import numpy as np
+from numpy import ndarray, array as nxarray
+import numpy.core.umath as umath
+from numpy.lib.index_tricks import AxisConcatenator
+
+
+def issequence(seq):
+    """
+    Is seq a sequence (ndarray, list or tuple)?
+
+    """
+    if isinstance(seq, (ndarray, tuple, list)):
+        return True
+    return False
+
+def count_masked(arr, axis=None):
+    """
+    Count the number of masked elements along the given axis.
+
+    Parameters
+    ----------
+    arr : array_like
+        An array with (possibly) masked elements.
+    axis : int, optional
+        Axis along which to count. If None (default), a flattened
+        version of the array is used.
+
+    Returns
+    -------
+    count : int, ndarray
+        The total number of masked elements (axis=None) or the number
+        of masked elements along each slice of the given axis.
+
+    See Also
+    --------
+    MaskedArray.count : Count non-masked elements.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.arange(9).reshape((3,3))
+    >>> a = ma.array(a)
+    >>> a[1, 0] = ma.masked
+    >>> a[1, 2] = ma.masked
+    >>> a[2, 1] = ma.masked
+    >>> a
+    masked_array(data =
+     [[0 1 2]
+     [-- 4 --]
+     [6 -- 8]],
+          mask =
+     [[False False False]
+     [ True False  True]
+     [False  True False]],
+          fill_value=999999)
+    >>> ma.count_masked(a)
+    3
+
+    When the `axis` keyword is used an array is returned.
+
+    >>> ma.count_masked(a, axis=0)
+    array([1, 1, 1])
+    >>> ma.count_masked(a, axis=1)
+    array([0, 2, 1])
+
+    """
+    m = getmaskarray(arr)
+    return m.sum(axis)
+
+def masked_all(shape, dtype=float):
+    """
+    Empty masked array with all elements masked.
+
+    Return an empty masked array of the given shape and dtype, where all the
+    data are masked.
+
+    Parameters
+    ----------
+    shape : tuple
+        Shape of the required MaskedArray.
+    dtype : dtype, optional
+        Data type of the output.
+
+    Returns
+    -------
+    a : MaskedArray
+        A masked array with all data masked.
+
+    See Also
+    --------
+    masked_all_like : Empty masked array modelled on an existing array.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> ma.masked_all((3, 3))
+    masked_array(data =
+     [[-- -- --]
+     [-- -- --]
+     [-- -- --]],
+          mask =
+     [[ True  True  True]
+     [ True  True  True]
+     [ True  True  True]],
+          fill_value=1e+20)
+
+    The `dtype` parameter defines the underlying data type.
+
+    >>> a = ma.masked_all((3, 3))
+    >>> a.dtype
+    dtype('float64')
+    >>> a = ma.masked_all((3, 3), dtype=np.int32)
+    >>> a.dtype
+    dtype('int32')
+
+    """
+    a = masked_array(np.empty(shape, dtype),
+                     mask=np.ones(shape, make_mask_descr(dtype)))
+    return a
+
+def masked_all_like(arr):
+    """
+    Empty masked array with the properties of an existing array.
+
+    Return an empty masked array of the same shape and dtype as
+    the array `arr`, where all the data are masked.
+
+    Parameters
+    ----------
+    arr : ndarray
+        An array describing the shape and dtype of the required MaskedArray.
+
+    Returns
+    -------
+    a : MaskedArray
+        A masked array with all data masked.
+
+    Raises
+    ------
+    AttributeError
+        If `arr` doesn't have a shape attribute (i.e. not an ndarray)
+
+    See Also
+    --------
+    masked_all : Empty masked array with all elements masked.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> arr = np.zeros((2, 3), dtype=np.float32)
+    >>> arr
+    array([[ 0.,  0.,  0.],
+           [ 0.,  0.,  0.]], dtype=float32)
+    >>> ma.masked_all_like(arr)
+    masked_array(data =
+     [[-- -- --]
+     [-- -- --]],
+          mask =
+     [[ True  True  True]
+     [ True  True  True]],
+          fill_value=1e+20)
+
+    The dtype of the masked array matches the dtype of `arr`.
+
+    >>> arr.dtype
+    dtype('float32')
+    >>> ma.masked_all_like(arr).dtype
+    dtype('float32')
+
+    """
+    a = np.empty_like(arr).view(MaskedArray)
+    a._mask = np.ones(a.shape, dtype=make_mask_descr(a.dtype))
+    return a
+
+
+#####--------------------------------------------------------------------------
+#---- --- Standard functions ---
+#####--------------------------------------------------------------------------
+class _fromnxfunction:
+    """
+    Defines a wrapper to adapt NumPy functions to masked arrays.
+
+
+    An instance of `_fromnxfunction` can be called with the same parameters
+    as the wrapped NumPy function. The docstring of `newfunc` is adapted from
+    the wrapped function as well, see `getdoc`.
+
+    Parameters
+    ----------
+    funcname : str
+        The name of the function to be adapted. The function should be
+        in the NumPy namespace (i.e. ``np.funcname``).
+
+    """
+
+    def __init__(self, funcname):
+        self.__name__ = funcname
+        self.__doc__ = self.getdoc()
+
+    def getdoc(self):
+        """
+        Retrieve the docstring and signature from the function.
+
+        The ``__doc__`` attribute of the function is used as the docstring for
+        the new masked array version of the function. A note on application
+        of the function to the mask is appended.
+
+        .. warning::
+          If the function docstring already contained a Notes section, the
+          new docstring will have two Notes sections instead of appending a note
+          to the existing section.
+
+        Parameters
+        ----------
+        None
+
+        """
+        npfunc = getattr(np, self.__name__, None)
+        doc = getattr(npfunc, '__doc__', None)
+        if doc:
+            sig = self.__name__ + ma.get_object_signature(npfunc)
+            locdoc = "Notes\n-----\nThe function is applied to both the _data"\
+                     " and the _mask, if any."
+            return '\n'.join((sig, doc, locdoc))
+        return
+
+    def __call__(self, *args, **params):
+        func = getattr(np, self.__name__)
+        if len(args) == 1:
+            x = args[0]
+            if isinstance(x, ndarray):
+                _d = func(x.__array__(), **params)
+                _m = func(getmaskarray(x), **params)
+                return masked_array(_d, mask=_m)
+            elif isinstance(x, tuple) or isinstance(x, list):
+                _d = func(tuple([np.asarray(a) for a in x]), **params)
+                _m = func(tuple([getmaskarray(a) for a in x]), **params)
+                return masked_array(_d, mask=_m)
+            else:
+                _d = func(np.asarray(x), **params)
+                _m = func(getmaskarray(x), **params)
+                return masked_array(_d, mask=_m)
+        else:
+            arrays = []
+            args = list(args)
+            while len(args) > 0 and issequence(args[0]):
+                arrays.append(args.pop(0))
+            res = []
+            for x in arrays:
+                _d = func(np.asarray(x), *args, **params)
+                _m = func(getmaskarray(x), *args, **params)
+                res.append(masked_array(_d, mask=_m))
+            return res
+
+atleast_1d = _fromnxfunction('atleast_1d')
+atleast_2d = _fromnxfunction('atleast_2d')
+atleast_3d = _fromnxfunction('atleast_3d')
+#atleast_1d = np.atleast_1d
+#atleast_2d = np.atleast_2d
+#atleast_3d = np.atleast_3d
+
+vstack = row_stack = _fromnxfunction('vstack')
+hstack = _fromnxfunction('hstack')
+column_stack = _fromnxfunction('column_stack')
+dstack = _fromnxfunction('dstack')
+
+hsplit = _fromnxfunction('hsplit')
+
+diagflat = _fromnxfunction('diagflat')
+
+
+#####--------------------------------------------------------------------------
+#----
+#####--------------------------------------------------------------------------
+def flatten_inplace(seq):
+    """Flatten a sequence in place."""
+    k = 0
+    while (k != len(seq)):
+        while hasattr(seq[k], '__iter__'):
+            seq[k:(k + 1)] = seq[k]
+        k += 1
+    return seq
+
+
+def apply_along_axis(func1d, axis, arr, *args, **kwargs):
+    """
+    (This docstring should be overwritten)
+    """
+    arr = array(arr, copy=False, subok=True)
+    nd = arr.ndim
+    if axis < 0:
+        axis += nd
+    if (axis >= nd):
+        raise ValueError("axis must be less than arr.ndim; axis=%d, rank=%d."
+            % (axis, nd))
+    ind = [0] * (nd - 1)
+    i = np.zeros(nd, 'O')
+    indlist = list(range(nd))
+    indlist.remove(axis)
+    i[axis] = slice(None, None)
+    outshape = np.asarray(arr.shape).take(indlist)
+    i.put(indlist, ind)
+    j = i.copy()
+    res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+    #  if res is a number, then we have a smaller output array
+    asscalar = np.isscalar(res)
+    if not asscalar:
+        try:
+            len(res)
+        except TypeError:
+            asscalar = True
+    # Note: we shouldn't set the dtype of the output from the first result
+    # so we force the type to object, and build a list of dtypes.  We'll
+    # just take the largest, to avoid some downcasting
+    dtypes = []
+    if asscalar:
+        dtypes.append(np.asarray(res).dtype)
+        outarr = zeros(outshape, object)
+        outarr[tuple(ind)] = res
+        Ntot = np.product(outshape)
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= outshape[n]) and (n > (1 - nd)):
+                ind[n - 1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(ind)] = res
+            dtypes.append(asarray(res).dtype)
+            k += 1
+    else:
+        res = array(res, copy=False, subok=True)
+        j = i.copy()
+        j[axis] = ([slice(None, None)] * res.ndim)
+        j.put(indlist, ind)
+        Ntot = np.product(outshape)
+        holdshape = outshape
+        outshape = list(arr.shape)
+        outshape[axis] = res.shape
+        dtypes.append(asarray(res).dtype)
+        outshape = flatten_inplace(outshape)
+        outarr = zeros(outshape, object)
+        outarr[tuple(flatten_inplace(j.tolist()))] = res
+        k = 1
+        while k < Ntot:
+            # increment the index
+            ind[-1] += 1
+            n = -1
+            while (ind[n] >= holdshape[n]) and (n > (1 - nd)):
+                ind[n - 1] += 1
+                ind[n] = 0
+                n -= 1
+            i.put(indlist, ind)
+            j.put(indlist, ind)
+            res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
+            outarr[tuple(flatten_inplace(j.tolist()))] = res
+            dtypes.append(asarray(res).dtype)
+            k += 1
+    max_dtypes = np.dtype(np.asarray(dtypes).max())
+    if not hasattr(arr, '_mask'):
+        result = np.asarray(outarr, dtype=max_dtypes)
+    else:
+        result = asarray(outarr, dtype=max_dtypes)
+        result.fill_value = ma.default_fill_value(result)
+    return result
+apply_along_axis.__doc__ = np.apply_along_axis.__doc__
+
+
+def apply_over_axes(func, a, axes):
+    """
+    (This docstring will be overwritten)
+    """
+    val = asarray(a)
+    N = a.ndim
+    if array(axes).ndim == 0:
+        axes = (axes,)
+    for axis in axes:
+        if axis < 0:
+            axis = N + axis
+        args = (val, axis)
+        res = func(*args)
+        if res.ndim == val.ndim:
+            val = res
+        else:
+            res = ma.expand_dims(res, axis)
+            if res.ndim == val.ndim:
+                val = res
+            else:
+                raise ValueError("function is not returning "
+                        "an array of the correct shape")
+    return val
+
+if apply_over_axes.__doc__ is not None:
+    apply_over_axes.__doc__ = np.apply_over_axes.__doc__[
+        :np.apply_over_axes.__doc__.find('Notes')].rstrip() + \
+    """
+
+    Examples
+    --------
+    >>> a = ma.arange(24).reshape(2,3,4)
+    >>> a[:,0,1] = ma.masked
+    >>> a[:,1,:] = ma.masked
+    >>> print(a)
+    [[[0 -- 2 3]
+      [-- -- -- --]
+      [8 9 10 11]]
+
+     [[12 -- 14 15]
+      [-- -- -- --]
+      [20 21 22 23]]]
+    >>> print(ma.apply_over_axes(ma.sum, a, [0,2]))
+    [[[46]
+      [--]
+      [124]]]
+
+    Tuple axis arguments to ufuncs are equivalent:
+
+    >>> print(ma.sum(a, axis=(0,2)).reshape((1,-1,1)))
+    [[[46]
+      [--]
+      [124]]]
+    """
+
+
+def average(a, axis=None, weights=None, returned=False):
+    """
+    Return the weighted average of array over the given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        Data to be averaged.
+        Masked entries are not taken into account in the computation.
+    axis : int, optional
+        Axis along which the average is computed. The default is to compute
+        the average of the flattened array.
+    weights : array_like, optional
+        The importance that each element has in the computation of the average.
+        The weights array can either be 1-D (in which case its length must be
+        the size of `a` along the given axis) or of the same shape as `a`.
+        If ``weights=None``, then all data in `a` are assumed to have a
+        weight equal to one.   If `weights` is complex, the imaginary parts
+        are ignored.
+    returned : bool, optional
+        Flag indicating whether a tuple ``(result, sum of weights)``
+        should be returned as output (True), or just the result (False).
+        Default is False.
+
+    Returns
+    -------
+    average, [sum_of_weights] : (tuple of) scalar or MaskedArray
+        The average along the specified axis. When returned is `True`,
+        return a tuple with the average as the first element and the sum
+        of the weights as the second element. The return type is `np.float64`
+        if `a` is of integer type and floats smaller than `float64`, or the
+        input data-type, otherwise. If returned, `sum_of_weights` is always
+        `float64`.
+
+    Examples
+    --------
+    >>> a = np.ma.array([1., 2., 3., 4.], mask=[False, False, True, True])
+    >>> np.ma.average(a, weights=[3, 1, 0, 0])
+    1.25
+
+    >>> x = np.ma.arange(6.).reshape(3, 2)
+    >>> print(x)
+    [[ 0.  1.]
+     [ 2.  3.]
+     [ 4.  5.]]
+    >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3],
+    ...                                 returned=True)
+    >>> print(avg)
+    [2.66666666667 3.66666666667]
+
+    """
+    a = asarray(a)
+    mask = a.mask
+    ash = a.shape
+    if ash == ():
+        ash = (1,)
+    if axis is None:
+        if mask is nomask:
+            if weights is None:
+                n = a.sum(axis=None)
+                d = float(a.size)
+            else:
+                w = filled(weights, 0.0).ravel()
+                n = umath.add.reduce(a._data.ravel() * w)
+                d = umath.add.reduce(w)
+                del w
+        else:
+            if weights is None:
+                n = a.filled(0).sum(axis=None)
+                d = float(umath.add.reduce((~mask).ravel()))
+            else:
+                w = array(filled(weights, 0.0), float, mask=mask).ravel()
+                n = add.reduce(a.ravel() * w)
+                d = add.reduce(w)
+                del w
+    else:
+        if mask is nomask:
+            if weights is None:
+                d = ash[axis] * 1.0
+                n = add.reduce(a._data, axis)
+            else:
+                w = filled(weights, 0.0)
+                wsh = w.shape
+                if wsh == ():
+                    wsh = (1,)
+                if wsh == ash:
+                    w = np.array(w, float, copy=0)
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis)
+                    del w
+                elif wsh == (ash[axis],):
+                    r = [None] * len(ash)
+                    r[axis] = slice(None, None, 1)
+                    w = eval("w[" + repr(tuple(r)) + "] * ones(ash, float)")
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                    del w, r
+                else:
+                    raise ValueError('average: weights wrong shape.')
+        else:
+            if weights is None:
+                n = add.reduce(a, axis)
+                d = umath.add.reduce((~mask), axis=axis, dtype=float)
+            else:
+                w = filled(weights, 0.0)
+                wsh = w.shape
+                if wsh == ():
+                    wsh = (1,)
+                if wsh == ash:
+                    w = array(w, dtype=float, mask=mask, copy=0)
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                elif wsh == (ash[axis],):
+                    r = [None] * len(ash)
+                    r[axis] = slice(None, None, 1)
+                    w = eval("w[" + repr(tuple(r)) +
+                             "] * masked_array(ones(ash, float), mask)")
+                    n = add.reduce(a * w, axis)
+                    d = add.reduce(w, axis, dtype=float)
+                else:
+                    raise ValueError('average: weights wrong shape.')
+                del w
+    if n is masked or d is masked:
+        return masked
+    result = n / d
+    del n
+
+    if isinstance(result, MaskedArray):
+        if ((axis is None) or (axis == 0 and a.ndim == 1)) and \
+           (result.mask is nomask):
+            result = result._data
+        if returned:
+            if not isinstance(d, MaskedArray):
+                d = masked_array(d)
+            if isinstance(d, ndarray) and (not d.shape == result.shape):
+                d = ones(result.shape, dtype=float) * d
+    if returned:
+        return result, d
+    else:
+        return result
+
+
+def median(a, axis=None, out=None, overwrite_input=False):
+    """
+    Compute the median along the specified axis.
+
+    Returns the median of the array elements.
+
+    Parameters
+    ----------
+    a : array_like
+        Input array or object that can be converted to an array.
+    axis : int, optional
+        Axis along which the medians are computed. The default (None) is
+        to compute the median along a flattened version of the array.
+    out : ndarray, optional
+        Alternative output array in which to place the result. It must
+        have the same shape and buffer length as the expected output
+        but the type will be cast if necessary.
+    overwrite_input : bool, optional
+        If True, then allow use of memory of input array (a) for
+        calculations. The input array will be modified by the call to
+        median. This will save memory when you do not need to preserve
+        the contents of the input array. Treat the input as undefined,
+        but it will probably be fully or partially sorted. Default is
+        False. Note that, if `overwrite_input` is True, and the input
+        is not already an `ndarray`, an error will be raised.
+
+    Returns
+    -------
+    median : ndarray
+        A new array holding the result is returned unless out is
+        specified, in which case a reference to out is returned.
+        Return data-type is `float64` for integers and floats smaller than
+        `float64`, or the input data-type, otherwise.
+
+    See Also
+    --------
+    mean
+
+    Notes
+    -----
+    Given a vector ``V`` with ``N`` non masked values, the median of ``V``
+    is the middle value of a sorted copy of ``V`` (``Vs``) - i.e.
+    ``Vs[(N-1)/2]``, when ``N`` is odd, or ``{Vs[N/2 - 1] + Vs[N/2]}/2``
+    when ``N`` is even.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(8), mask=[0]*4 + [1]*4)
+    >>> np.ma.median(x)
+    1.5
+
+    >>> x = np.ma.array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4)
+    >>> np.ma.median(x)
+    2.5
+    >>> np.ma.median(x, axis=-1, overwrite_input=True)
+    masked_array(data = [ 2.  5.],
+                 mask = False,
+           fill_value = 1e+20)
+
+    """
+    if not hasattr(a, 'mask') or np.count_nonzero(a.mask) == 0:
+        return masked_array(np.median(getdata(a, subok=True), axis=axis,
+                      out=out, overwrite_input=overwrite_input), copy=False)
+    if overwrite_input:
+        if axis is None:
+            asorted = a.ravel()
+            asorted.sort()
+        else:
+            a.sort(axis=axis)
+            asorted = a
+    else:
+        asorted = sort(a, axis=axis)
+    if axis is None:
+        axis = 0
+    elif axis < 0:
+        axis += a.ndim
+
+    counts = asorted.shape[axis] - (asorted.mask).sum(axis=axis)
+    h = counts // 2
+    # create indexing mesh grid for all but reduced axis
+    axes_grid = [np.arange(x) for i, x in enumerate(asorted.shape)
+                 if i != axis]
+    ind = np.meshgrid(*axes_grid, sparse=True, indexing='ij')
+    # insert indices of low and high median
+    ind.insert(axis, h - 1)
+    low = asorted[ind]
+    low._sharedmask = False
+    ind[axis] = h
+    high = asorted[ind]
+    # duplicate high if odd number of elements so mean does nothing
+    odd = counts % 2 == 1
+    if asorted.ndim == 1:
+        if odd:
+            low = high
+    else:
+        low[odd] = high[odd]
+
+    if np.issubdtype(asorted.dtype, np.inexact):
+        # avoid inf / x = masked
+        s = np.ma.sum([low, high], axis=0, out=out)
+        np.true_divide(s.data, 2., casting='unsafe', out=s.data)
+    else:
+        s = np.ma.mean([low, high], axis=0, out=out)
+    return s
+
+
+def compress_nd(x, axis=None):
+    """Supress slices from multiple dimensions which contain masked values.
+
+    Parameters
+    ----------
+    x : array_like, MaskedArray
+        The array to operate on. If not a MaskedArray instance (or if no array
+        elements are masked, `x` is interpreted as a MaskedArray with `mask`
+        set to `nomask`.
+    axis : tuple of ints or int, optional
+        Which dimensions to supress slices from can be configured with this
+        parameter.
+        - If axis is a tuple of ints, those are the axes to supress slices from.
+        - If axis is an int, then that is the only axis to supress slices from.
+        - If axis is None, all axis are selected.
+
+    Returns
+    -------
+    compress_array : ndarray
+        The compressed array.
+    """
+    x = asarray(x)
+    m = getmask(x)
+    # Set axis to tuple of ints
+    if isinstance(axis, int):
+        axis = (axis,)
+    elif axis is None:
+        axis = tuple(range(x.ndim))
+    elif not isinstance(axis, tuple):
+        raise ValueError('Invalid type for axis argument')
+    # Check axis input
+    axis = [ax + x.ndim if ax < 0 else ax for ax in axis]
+    if not all(0 <= ax < x.ndim for ax in axis):
+        raise ValueError("'axis' entry is out of bounds")
+    if len(axis) != len(set(axis)):
+        raise ValueError("duplicate value in 'axis'")
+    # Nothing is masked: return x
+    if m is nomask or not m.any():
+        return x._data
+    # All is masked: return empty
+    if m.all():
+        return nxarray([])
+    # Filter elements through boolean indexing
+    data = x._data
+    for ax in axis:
+        axes = tuple(list(range(ax)) + list(range(ax + 1, x.ndim)))
+        data = data[(slice(None),)*ax + (~m.any(axis=axes),)]
+    return data
+
+def compress_rowcols(x, axis=None):
+    """
+    Suppress the rows and/or columns of a 2-D array that contain
+    masked values.
+
+    The suppression behavior is selected with the `axis` parameter.
+
+    - If axis is None, both rows and columns are suppressed.
+    - If axis is 0, only rows are suppressed.
+    - If axis is 1 or -1, only columns are suppressed.
+
+    Parameters
+    ----------
+    x : array_like, MaskedArray
+        The array to operate on.  If not a MaskedArray instance (or if no array
+        elements are masked), `x` is interpreted as a MaskedArray with
+        `mask` set to `nomask`. Must be a 2D array.
+    axis : int, optional
+        Axis along which to perform the operation. Default is None.
+
+    Returns
+    -------
+    compressed_array : ndarray
+        The compressed array.
+
+    Examples
+    --------
+    >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
+    ...                                                   [1, 0, 0],
+    ...                                                   [0, 0, 0]])
+    >>> x
+    masked_array(data =
+     [[-- 1 2]
+     [-- 4 5]
+     [6 7 8]],
+                 mask =
+     [[ True False False]
+     [ True False False]
+     [False False False]],
+           fill_value = 999999)
+
+    >>> np.ma.compress_rowcols(x)
+    array([[7, 8]])
+    >>> np.ma.compress_rowcols(x, 0)
+    array([[6, 7, 8]])
+    >>> np.ma.compress_rowcols(x, 1)
+    array([[1, 2],
+           [4, 5],
+           [7, 8]])
+
+    """
+    if asarray(x).ndim != 2:
+        raise NotImplementedError("compress_rowcols works for 2D arrays only.")
+    return compress_nd(x, axis=axis)
+
+
+def compress_rows(a):
+    """
+    Suppress whole rows of a 2-D array that contain masked values.
+
+    This is equivalent to ``np.ma.compress_rowcols(a, 0)``, see
+    `extras.compress_rowcols` for details.
+
+    See Also
+    --------
+    extras.compress_rowcols
+
+    """
+    a = asarray(a)
+    if a.ndim != 2:
+        raise NotImplementedError("compress_rows works for 2D arrays only.")
+    return compress_rowcols(a, 0)
+
+def compress_cols(a):
+    """
+    Suppress whole columns of a 2-D array that contain masked values.
+
+    This is equivalent to ``np.ma.compress_rowcols(a, 1)``, see
+    `extras.compress_rowcols` for details.
+
+    See Also
+    --------
+    extras.compress_rowcols
+
+    """
+    a = asarray(a)
+    if a.ndim != 2:
+        raise NotImplementedError("compress_cols works for 2D arrays only.")
+    return compress_rowcols(a, 1)
+
+def mask_rows(a, axis=None):
+    """
+    Mask rows of a 2D array that contain masked values.
+
+    This function is a shortcut to ``mask_rowcols`` with `axis` equal to 0.
+
+    See Also
+    --------
+    mask_rowcols : Mask rows and/or columns of a 2D array.
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_rows(a)
+    masked_array(data =
+     [[0 0 0]
+     [-- -- --]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [ True  True  True]
+     [False False False]],
+          fill_value=999999)
+
+    """
+    return mask_rowcols(a, 0)
+
+def mask_cols(a, axis=None):
+    """
+    Mask columns of a 2D array that contain masked values.
+
+    This function is a shortcut to ``mask_rowcols`` with `axis` equal to 1.
+
+    See Also
+    --------
+    mask_rowcols : Mask rows and/or columns of a 2D array.
+    masked_where : Mask where a condition is met.
+
+    Examples
+    --------
+    >>> import numpy.ma as ma
+    >>> a = np.zeros((3, 3), dtype=np.int)
+    >>> a[1, 1] = 1
+    >>> a
+    array([[0, 0, 0],
+           [0, 1, 0],
+           [0, 0, 0]])
+    >>> a = ma.masked_equal(a, 1)
+    >>> a
+    masked_array(data =
+     [[0 0 0]
+     [0 -- 0]
+     [0 0 0]],
+          mask =
+     [[False False False]
+     [False  True False]
+     [False False False]],
+          fill_value=999999)
+    >>> ma.mask_cols(a)
+    masked_array(data =
+     [[0 -- 0]
+     [0 -- 0]
+     [0 -- 0]],
+          mask =
+     [[False  True False]
+     [False  True False]
+     [False  True False]],
+          fill_value=999999)
+
+    """
+    return mask_rowcols(a, 1)
+
+
+#####--------------------------------------------------------------------------
+#---- --- arraysetops ---
+#####--------------------------------------------------------------------------
+
+def ediff1d(arr, to_end=None, to_begin=None):
+    """
+    Compute the differences between consecutive elements of an array.
+
+    This function is the equivalent of `numpy.ediff1d` that takes masked
+    values into account, see `numpy.ediff1d` for details.
+
+    See Also
+    --------
+    numpy.ediff1d : Equivalent function for ndarrays.
+
+    """
+    arr = ma.asanyarray(arr).flat
+    ed = arr[1:] - arr[:-1]
+    arrays = [ed]
+    #
+    if to_begin is not None:
+        arrays.insert(0, to_begin)
+    if to_end is not None:
+        arrays.append(to_end)
+    #
+    if len(arrays) != 1:
+        # We'll save ourselves a copy of a potentially large array in the common
+        # case where neither to_begin or to_end was given.
+        ed = hstack(arrays)
+    #
+    return ed
+
+
+def unique(ar1, return_index=False, return_inverse=False):
+    """
+    Finds the unique elements of an array.
+
+    Masked values are considered the same element (masked). The output array
+    is always a masked array. See `numpy.unique` for more details.
+
+    See Also
+    --------
+    numpy.unique : Equivalent function for ndarrays.
+
+    """
+    output = np.unique(ar1,
+                       return_index=return_index,
+                       return_inverse=return_inverse)
+    if isinstance(output, tuple):
+        output = list(output)
+        output[0] = output[0].view(MaskedArray)
+        output = tuple(output)
+    else:
+        output = output.view(MaskedArray)
+    return output
+
+
+def intersect1d(ar1, ar2, assume_unique=False):
+    """
+    Returns the unique elements common to both arrays.
+
+    Masked values are considered equal one to the other.
+    The output is always a masked array.
+
+    See `numpy.intersect1d` for more details.
+
+    See Also
+    --------
+    numpy.intersect1d : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> x = array([1, 3, 3, 3], mask=[0, 0, 0, 1])
+    >>> y = array([3, 1, 1, 1], mask=[0, 0, 0, 1])
+    >>> intersect1d(x, y)
+    masked_array(data = [1 3 --],
+                 mask = [False False  True],
+           fill_value = 999999)
+
+    """
+    if assume_unique:
+        aux = ma.concatenate((ar1, ar2))
+    else:
+        # Might be faster than unique( intersect1d( ar1, ar2 ) )?
+        aux = ma.concatenate((unique(ar1), unique(ar2)))
+    aux.sort()
+    return aux[:-1][aux[1:] == aux[:-1]]
+
+
+def setxor1d(ar1, ar2, assume_unique=False):
+    """
+    Set exclusive-or of 1-D arrays with unique elements.
+
+    The output is always a masked array. See `numpy.setxor1d` for more details.
+
+    See Also
+    --------
+    numpy.setxor1d : Equivalent function for ndarrays.
+
+    """
+    if not assume_unique:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+
+    aux = ma.concatenate((ar1, ar2))
+    if aux.size == 0:
+        return aux
+    aux.sort()
+    auxf = aux.filled()
+#    flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
+    flag = ma.concatenate(([True], (auxf[1:] != auxf[:-1]), [True]))
+#    flag2 = ediff1d( flag ) == 0
+    flag2 = (flag[1:] == flag[:-1])
+    return aux[flag2]
+
+def in1d(ar1, ar2, assume_unique=False, invert=False):
+    """
+    Test whether each element of an array is also present in a second
+    array.
+
+    The output is always a masked array. See `numpy.in1d` for more details.
+
+    See Also
+    --------
+    numpy.in1d : Equivalent function for ndarrays.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    if not assume_unique:
+        ar1, rev_idx = unique(ar1, return_inverse=True)
+        ar2 = unique(ar2)
+
+    ar = ma.concatenate((ar1, ar2))
+    # We need this to be a stable sort, so always use 'mergesort'
+    # here. The values from the first array should always come before
+    # the values from the second array.
+    order = ar.argsort(kind='mergesort')
+    sar = ar[order]
+    if invert:
+        bool_ar = (sar[1:] != sar[:-1])
+    else:
+        bool_ar = (sar[1:] == sar[:-1])
+    flag = ma.concatenate((bool_ar, [invert]))
+    indx = order.argsort(kind='mergesort')[:len(ar1)]
+
+    if assume_unique:
+        return flag[indx]
+    else:
+        return flag[indx][rev_idx]
+
+
+def union1d(ar1, ar2):
+    """
+    Union of two arrays.
+
+    The output is always a masked array. See `numpy.union1d` for more details.
+
+    See also
+    --------
+    numpy.union1d : Equivalent function for ndarrays.
+
+    """
+    return unique(ma.concatenate((ar1, ar2)))
+
+
+def setdiff1d(ar1, ar2, assume_unique=False):
+    """
+    Set difference of 1D arrays with unique elements.
+
+    The output is always a masked array. See `numpy.setdiff1d` for more
+    details.
+
+    See Also
+    --------
+    numpy.setdiff1d : Equivalent function for ndarrays.
+
+    Examples
+    --------
+    >>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
+    >>> np.ma.setdiff1d(x, [1, 2])
+    masked_array(data = [3 --],
+                 mask = [False  True],
+           fill_value = 999999)
+
+    """
+    if assume_unique:
+        ar1 = ma.asarray(ar1).ravel()
+    else:
+        ar1 = unique(ar1)
+        ar2 = unique(ar2)
+    return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
+
+
+###############################################################################
+#                                Covariance                                   #
+###############################################################################
+
+
+def _covhelper(x, y=None, rowvar=True, allow_masked=True):
+    """
+    Private function for the computation of covariance and correlation
+    coefficients.
+
+    """
+    x = ma.array(x, ndmin=2, copy=True, dtype=float)
+    xmask = ma.getmaskarray(x)
+    # Quick exit if we can't process masked data
+    if not allow_masked and xmask.any():
+        raise ValueError("Cannot process masked data.")
+    #
+    if x.shape[0] == 1:
+        rowvar = True
+    # Make sure that rowvar is either 0 or 1
+    rowvar = int(bool(rowvar))
+    axis = 1 - rowvar
+    if rowvar:
+        tup = (slice(None), None)
+    else:
+        tup = (None, slice(None))
+    #
+    if y is None:
+        xnotmask = np.logical_not(xmask).astype(int)
+    else:
+        y = array(y, copy=False, ndmin=2, dtype=float)
+        ymask = ma.getmaskarray(y)
+        if not allow_masked and ymask.any():
+            raise ValueError("Cannot process masked data.")
+        if xmask.any() or ymask.any():
+            if y.shape == x.shape:
+                # Define some common mask
+                common_mask = np.logical_or(xmask, ymask)
+                if common_mask is not nomask:
+                    xmask = x._mask = y._mask = ymask = common_mask
+                    x._sharedmask = False
+                    y._sharedmask = False
+        x = ma.concatenate((x, y), axis)
+        xnotmask = np.logical_not(np.concatenate((xmask, ymask), axis)).astype(int)
+    x -= x.mean(axis=rowvar)[tup]
+    return (x, xnotmask, rowvar)
+
+
+def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None):
+    """
+    Estimate the covariance matrix.
+
+    Except for the handling of missing data this function does the same as
+    `numpy.cov`. For more details and examples, see `numpy.cov`.
+
+    By default, masked values are recognized as such. If `x` and `y` have the
+    same shape, a common mask is allocated: if ``x[i,j]`` is masked, then
+    ``y[i,j]`` will also be masked.
+    Setting `allow_masked` to False will raise an exception if values are
+    missing in either of the input arrays.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        form as `x`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : bool, optional
+        Default normalization (False) is by ``(N-1)``, where ``N`` is the
+        number of observations given (unbiased estimate). If `bias` is True,
+        then normalization is by ``N``. This keyword can be overridden by
+        the keyword ``ddof`` in numpy versions >= 1.5.
+    allow_masked : bool, optional
+        If True, masked values are propagated pair-wise: if a value is masked
+        in `x`, the corresponding value is masked in `y`.
+        If False, raises a `ValueError` exception when some values are missing.
+    ddof : {None, int}, optional
+        If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
+        the number of observations; this overrides the value implied by
+        ``bias``. The default value is ``None``.
+
+        .. versionadded:: 1.5
+
+    Raises
+    ------
+    ValueError
+        Raised if some values are missing and `allow_masked` is False.
+
+    See Also
+    --------
+    numpy.cov
+
+    """
+    # Check inputs
+    if ddof is not None and ddof != int(ddof):
+        raise ValueError("ddof must be an integer")
+    # Set up ddof
+    if ddof is None:
+        if bias:
+            ddof = 0
+        else:
+            ddof = 1
+
+    (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
+    if not rowvar:
+        fact = np.dot(xnotmask.T, xnotmask) * 1. - ddof
+        result = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
+    else:
+        fact = np.dot(xnotmask, xnotmask.T) * 1. - ddof
+        result = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
+    return result
+
+
+def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, allow_masked=True,
+             ddof=np._NoValue):
+    """
+    Return Pearson product-moment correlation coefficients.
+
+    Except for the handling of missing data this function does the same as
+    `numpy.corrcoef`. For more details and examples, see `numpy.corrcoef`.
+
+    Parameters
+    ----------
+    x : array_like
+        A 1-D or 2-D array containing multiple variables and observations.
+        Each row of `x` represents a variable, and each column a single
+        observation of all those variables. Also see `rowvar` below.
+    y : array_like, optional
+        An additional set of variables and observations. `y` has the same
+        shape as `x`.
+    rowvar : bool, optional
+        If `rowvar` is True (default), then each row represents a
+        variable, with observations in the columns. Otherwise, the relationship
+        is transposed: each column represents a variable, while the rows
+        contain observations.
+    bias : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+    allow_masked : bool, optional
+        If True, masked values are propagated pair-wise: if a value is masked
+        in `x`, the corresponding value is masked in `y`.
+        If False, raises an exception.  Because `bias` is deprecated, this
+        argument needs to be treated as keyword only to avoid a warning.
+    ddof : _NoValue, optional
+        Has no effect, do not use.
+
+        .. deprecated:: 1.10.0
+
+    See Also
+    --------
+    numpy.corrcoef : Equivalent function in top-level NumPy module.
+    cov : Estimate the covariance matrix.
+
+    Notes
+    -----
+    This function accepts but discards arguments `bias` and `ddof`.  This is
+    for backwards compatibility with previous versions of this function.  These
+    arguments had no effect on the return values of the function and can be
+    safely ignored in this and previous versions of numpy.
+    """
+    msg = 'bias and ddof have no effect and are deprecated'
+    if bias is not np._NoValue or ddof is not np._NoValue:
+        # 2015-03-15, 1.10
+        warnings.warn(msg, DeprecationWarning)
+    # Get the data
+    (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
+    # Compute the covariance matrix
+    if not rowvar:
+        fact = np.dot(xnotmask.T, xnotmask) * 1.
+        c = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
+    else:
+        fact = np.dot(xnotmask, xnotmask.T) * 1.
+        c = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
+    # Check whether we have a scalar
+    try:
+        diag = ma.diagonal(c)
+    except ValueError:
+        return 1
+    #
+    if xnotmask.all():
+        _denom = ma.sqrt(ma.multiply.outer(diag, diag))
+    else:
+        _denom = diagflat(diag)
+        _denom._sharedmask = False  # We know return is always a copy
+        n = x.shape[1 - rowvar]
+        if rowvar:
+            for i in range(n - 1):
+                for j in range(i + 1, n):
+                    _x = mask_cols(vstack((x[i], x[j]))).var(axis=1)
+                    _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
+        else:
+            for i in range(n - 1):
+                for j in range(i + 1, n):
+                    _x = mask_cols(
+                            vstack((x[:, i], x[:, j]))).var(axis=1)
+                    _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
+    return c / _denom
+
+#####--------------------------------------------------------------------------
+#---- --- Concatenation helpers ---
+#####--------------------------------------------------------------------------
+
+class MAxisConcatenator(AxisConcatenator):
+    """
+    Translate slice objects to concatenation along an axis.
+
+    For documentation on usage, see `mr_class`.
+
+    See Also
+    --------
+    mr_class
+
+    """
+
+    def __init__(self, axis=0):
+        AxisConcatenator.__init__(self, axis, matrix=False)
+
+    def __getitem__(self, key):
+        if isinstance(key, str):
+            raise MAError("Unavailable for masked array.")
+        if not isinstance(key, tuple):
+            key = (key,)
+        objs = []
+        scalars = []
+        final_dtypedescr = None
+        for k in range(len(key)):
+            scalar = False
+            if isinstance(key[k], slice):
+                step = key[k].step
+                start = key[k].start
+                stop = key[k].stop
+                if start is None:
+                    start = 0
+                if step is None:
+                    step = 1
+                if isinstance(step, complex):
+                    size = int(abs(step))
+                    newobj = np.linspace(start, stop, num=size)
+                else:
+                    newobj = np.arange(start, stop, step)
+            elif isinstance(key[k], str):
+                if (key[k] in 'rc'):
+                    self.matrix = True
+                    self.col = (key[k] == 'c')
+                    continue
+                try:
+                    self.axis = int(key[k])
+                    continue
+                except (ValueError, TypeError):
+                    raise ValueError("Unknown special directive")
+            elif type(key[k]) in np.ScalarType:
+                newobj = asarray([key[k]])
+                scalars.append(k)
+                scalar = True
+            else:
+                newobj = key[k]
+            objs.append(newobj)
+            if isinstance(newobj, ndarray) and not scalar:
+                if final_dtypedescr is None:
+                    final_dtypedescr = newobj.dtype
+                elif newobj.dtype > final_dtypedescr:
+                    final_dtypedescr = newobj.dtype
+        if final_dtypedescr is not None:
+            for k in scalars:
+                objs[k] = objs[k].astype(final_dtypedescr)
+        res = concatenate(tuple(objs), axis=self.axis)
+        return self._retval(res)
+
+class mr_class(MAxisConcatenator):
+    """
+    Translate slice objects to concatenation along the first axis.
+
+    This is the masked array version of `lib.index_tricks.RClass`.
+
+    See Also
+    --------
+    lib.index_tricks.RClass
+
+    Examples
+    --------
+    >>> np.ma.mr_[np.ma.array([1,2,3]), 0, 0, np.ma.array([4,5,6])]
+    array([1, 2, 3, 0, 0, 4, 5, 6])
+
+    """
+    def __init__(self):
+        MAxisConcatenator.__init__(self, 0)
+
+mr_ = mr_class()
+
+#####--------------------------------------------------------------------------
+#---- Find unmasked data ---
+#####--------------------------------------------------------------------------
+
+def flatnotmasked_edges(a):
+    """
+    Find the indices of the first and last unmasked values.
+
+    Expects a 1-D `MaskedArray`, returns None if all values are masked.
+
+    Parameters
+    ----------
+    a : array_like
+        Input 1-D `MaskedArray`
+
+    Returns
+    -------
+    edges : ndarray or None
+        The indices of first and last non-masked value in the array.
+        Returns None if all values are masked.
+
+    See Also
+    --------
+    flatnotmasked_contiguous, notmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 1-D arrays.
+
+    Examples
+    --------
+    >>> a = np.ma.arange(10)
+    >>> flatnotmasked_edges(a)
+    [0,-1]
+
+    >>> mask = (a < 3) | (a > 8) | (a == 5)
+    >>> a[mask] = np.ma.masked
+    >>> np.array(a[~a.mask])
+    array([3, 4, 6, 7, 8])
+
+    >>> flatnotmasked_edges(a)
+    array([3, 8])
+
+    >>> a[:] = np.ma.masked
+    >>> print(flatnotmasked_edges(ma))
+    None
+
+    """
+    m = getmask(a)
+    if m is nomask or not np.any(m):
+        return np.array([0, a.size - 1])
+    unmasked = np.flatnonzero(~m)
+    if len(unmasked) > 0:
+        return unmasked[[0, -1]]
+    else:
+        return None
+
+
+def notmasked_edges(a, axis=None):
+    """
+    Find the indices of the first and last unmasked values along an axis.
+
+    If all values are masked, return None.  Otherwise, return a list
+    of two tuples, corresponding to the indices of the first and last
+    unmasked values respectively.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None (default), applies to a flattened version of the array.
+
+    Returns
+    -------
+    edges : ndarray or list
+        An array of start and end indexes if there are any masked data in
+        the array. If there are no masked data in the array, `edges` is a
+        list of the first and last index.
+
+    See Also
+    --------
+    flatnotmasked_contiguous, flatnotmasked_edges, notmasked_contiguous,
+    clump_masked, clump_unmasked
+
+    Examples
+    --------
+    >>> a = np.arange(9).reshape((3, 3))
+    >>> m = np.zeros_like(a)
+    >>> m[1:, 1:] = 1
+
+    >>> am = np.ma.array(a, mask=m)
+    >>> np.array(am[~am.mask])
+    array([0, 1, 2, 3, 6])
+
+    >>> np.ma.notmasked_edges(ma)
+    array([0, 6])
+
+    """
+    a = asarray(a)
+    if axis is None or a.ndim == 1:
+        return flatnotmasked_edges(a)
+    m = getmaskarray(a)
+    idx = array(np.indices(a.shape), mask=np.asarray([m] * a.ndim))
+    return [tuple([idx[i].min(axis).compressed() for i in range(a.ndim)]),
+            tuple([idx[i].max(axis).compressed() for i in range(a.ndim)]), ]
+
+
+def flatnotmasked_contiguous(a):
+    """
+    Find contiguous unmasked data in a masked array along the given axis.
+
+    Parameters
+    ----------
+    a : narray
+        The input array.
+
+    Returns
+    -------
+    slice_list : list
+        A sorted sequence of slices (start index, end index).
+
+    See Also
+    --------
+    flatnotmasked_edges, notmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 2-D arrays at most.
+
+    Examples
+    --------
+    >>> a = np.ma.arange(10)
+    >>> np.ma.flatnotmasked_contiguous(a)
+    slice(0, 10, None)
+
+    >>> mask = (a < 3) | (a > 8) | (a == 5)
+    >>> a[mask] = np.ma.masked
+    >>> np.array(a[~a.mask])
+    array([3, 4, 6, 7, 8])
+
+    >>> np.ma.flatnotmasked_contiguous(a)
+    [slice(3, 5, None), slice(6, 9, None)]
+    >>> a[:] = np.ma.masked
+    >>> print(np.ma.flatnotmasked_edges(a))
+    None
+
+    """
+    m = getmask(a)
+    if m is nomask:
+        return slice(0, a.size, None)
+    i = 0
+    result = []
+    for (k, g) in itertools.groupby(m.ravel()):
+        n = len(list(g))
+        if not k:
+            result.append(slice(i, i + n))
+        i += n
+    return result or None
+
+def notmasked_contiguous(a, axis=None):
+    """
+    Find contiguous unmasked data in a masked array along the given axis.
+
+    Parameters
+    ----------
+    a : array_like
+        The input array.
+    axis : int, optional
+        Axis along which to perform the operation.
+        If None (default), applies to a flattened version of the array.
+
+    Returns
+    -------
+    endpoints : list
+        A list of slices (start and end indexes) of unmasked indexes
+        in the array.
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    clump_masked, clump_unmasked
+
+    Notes
+    -----
+    Only accepts 2-D arrays at most.
+
+    Examples
+    --------
+    >>> a = np.arange(9).reshape((3, 3))
+    >>> mask = np.zeros_like(a)
+    >>> mask[1:, 1:] = 1
+
+    >>> ma = np.ma.array(a, mask=mask)
+    >>> np.array(ma[~ma.mask])
+    array([0, 1, 2, 3, 6])
+
+    >>> np.ma.notmasked_contiguous(ma)
+    [slice(0, 4, None), slice(6, 7, None)]
+
+    """
+    a = asarray(a)
+    nd = a.ndim
+    if nd > 2:
+        raise NotImplementedError("Currently limited to atmost 2D array.")
+    if axis is None or nd == 1:
+        return flatnotmasked_contiguous(a)
+    #
+    result = []
+    #
+    other = (axis + 1) % 2
+    idx = [0, 0]
+    idx[axis] = slice(None, None)
+    #
+    for i in range(a.shape[other]):
+        idx[other] = i
+        result.append(flatnotmasked_contiguous(a[idx]) or None)
+    return result
+
+
+def _ezclump(mask):
+    """
+    Finds the clumps (groups of data with the same values) for a 1D bool array.
+
+    Returns a series of slices.
+    """
+    if mask.ndim > 1:
+        mask = mask.ravel()
+    idx = (mask[1:] ^ mask[:-1]).nonzero()
+    idx = idx[0] + 1
+
+    if mask[0]:
+        if len(idx) == 0:
+            return [slice(0, mask.size)]
+
+        r = [slice(0, idx[0])]
+        r.extend((slice(left, right)
+                  for left, right in zip(idx[1:-1:2], idx[2::2])))
+    else:
+        if len(idx) == 0:
+            return []
+
+        r = [slice(left, right) for left, right in zip(idx[:-1:2], idx[1::2])]
+
+    if mask[-1]:
+        r.append(slice(idx[-1], mask.size))
+    return r
+
+
+def clump_unmasked(a):
+    """
+    Return list of slices corresponding to the unmasked clumps of a 1-D array.
+    (A "clump" is defined as a contiguous region of the array).
+
+    Parameters
+    ----------
+    a : ndarray
+        A one-dimensional masked array.
+
+    Returns
+    -------
+    slices : list of slice
+        The list of slices, one for each continuous region of unmasked
+        elements in `a`.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    notmasked_contiguous, clump_masked
+
+    Examples
+    --------
+    >>> a = np.ma.masked_array(np.arange(10))
+    >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
+    >>> np.ma.clump_unmasked(a)
+    [slice(3, 6, None), slice(7, 8, None)]
+
+    """
+    mask = getattr(a, '_mask', nomask)
+    if mask is nomask:
+        return [slice(0, a.size)]
+    return _ezclump(~mask)
+
+
+def clump_masked(a):
+    """
+    Returns a list of slices corresponding to the masked clumps of a 1-D array.
+    (A "clump" is defined as a contiguous region of the array).
+
+    Parameters
+    ----------
+    a : ndarray
+        A one-dimensional masked array.
+
+    Returns
+    -------
+    slices : list of slice
+        The list of slices, one for each continuous region of masked elements
+        in `a`.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    See Also
+    --------
+    flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges,
+    notmasked_contiguous, clump_unmasked
+
+    Examples
+    --------
+    >>> a = np.ma.masked_array(np.arange(10))
+    >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
+    >>> np.ma.clump_masked(a)
+    [slice(0, 3, None), slice(6, 7, None), slice(8, 10, None)]
+
+    """
+    mask = ma.getmask(a)
+    if mask is nomask:
+        return []
+    return _ezclump(mask)
+
+
+###############################################################################
+#                              Polynomial fit                                 #
+###############################################################################
+
+
+def vander(x, n=None):
+    """
+    Masked values in the input array result in rows of zeros.
+
+    """
+    _vander = np.vander(x, n)
+    m = getmask(x)
+    if m is not nomask:
+        _vander[m] = 0
+    return _vander
+
+vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__)
+
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
+    """
+    Any masked values in x is propagated in y, and vice-versa.
+
+    """
+    x = asarray(x)
+    y = asarray(y)
+
+    m = getmask(x)
+    if y.ndim == 1:
+        m = mask_or(m, getmask(y))
+    elif y.ndim == 2:
+        my = getmask(mask_rows(y))
+        if my is not nomask:
+            m = mask_or(m, my[:, 0])
+    else:
+        raise TypeError("Expected a 1D or 2D array for y!")
+
+    if w is not None:
+        w = asarray(w)
+        if w.ndim != 1:
+            raise TypeError("expected a 1-d array for weights")
+        if w.shape[0] != y.shape[0]:
+            raise TypeError("expected w and y to have the same length")
+        m = mask_or(m, getmask(w))
+
+    if m is not nomask:
+        not_m = ~m
+        if w is not None:
+            w = w[not_m]
+        return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov)
+    else:
+        return np.polyfit(x, y, deg, rcond, full, w, cov)
+
+polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.py
new file mode 100644
index 0000000000..382bcc9727
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.py
@@ -0,0 +1,796 @@
+""":mod:`numpy.ma..mrecords`
+
+Defines the equivalent of :class:`numpy.recarrays` for masked arrays,
+where fields can be accessed as attributes.
+Note that :class:`numpy.ma.MaskedArray` already supports structured datatypes
+and the masking of individual fields.
+
+.. moduleauthor:: Pierre Gerard-Marchant
+
+"""
+from __future__ import division, absolute_import, print_function
+
+#  We should make sure that no field is called '_mask','mask','_fieldmask',
+#  or whatever restricted keywords.  An idea would be to no bother in the
+#  first place, and then rename the invalid fields with a trailing
+#  underscore. Maybe we could just overload the parser function ?
+
+import sys
+import warnings
+
+import numpy as np
+import numpy.core.numerictypes as ntypes
+from numpy.compat import basestring
+from numpy import (
+        bool_, dtype, ndarray, recarray, array as narray
+        )
+from numpy.core.records import (
+        fromarrays as recfromarrays, fromrecords as recfromrecords
+        )
+
+_byteorderconv = np.core.records._byteorderconv
+_typestr = ntypes._typestr
+
+import numpy.ma as ma
+from numpy.ma import (
+        MAError, MaskedArray, masked, nomask, masked_array, getdata,
+        getmaskarray, filled
+        )
+
+_check_fill_value = ma.core._check_fill_value
+
+
+__all__ = [
+    'MaskedRecords', 'mrecarray', 'fromarrays', 'fromrecords',
+    'fromtextfile', 'addfield',
+    ]
+
+reserved_fields = ['_data', '_mask', '_fieldmask', 'dtype']
+
+
+def _getformats(data):
+    """
+    Returns the formats of arrays in arraylist as a comma-separated string.
+
+    """
+    if hasattr(data, 'dtype'):
+        return ",".join([desc[1] for desc in data.dtype.descr])
+
+    formats = ''
+    for obj in data:
+        obj = np.asarray(obj)
+        formats += _typestr[obj.dtype.type]
+        if issubclass(obj.dtype.type, ntypes.flexible):
+            formats += repr(obj.itemsize)
+        formats += ','
+    return formats[:-1]
+
+
+def _checknames(descr, names=None):
+    """
+    Checks that field names ``descr`` are not reserved keywords.
+
+    If this is the case, a default 'f%i' is substituted.  If the argument
+    `names` is not None, updates the field names to valid names.
+
+    """
+    ndescr = len(descr)
+    default_names = ['f%i' % i for i in range(ndescr)]
+    if names is None:
+        new_names = default_names
+    else:
+        if isinstance(names, (tuple, list)):
+            new_names = names
+        elif isinstance(names, str):
+            new_names = names.split(',')
+        else:
+            raise NameError("illegal input names %s" % repr(names))
+        nnames = len(new_names)
+        if nnames < ndescr:
+            new_names += default_names[nnames:]
+    ndescr = []
+    for (n, d, t) in zip(new_names, default_names, descr.descr):
+        if n in reserved_fields:
+            if t[0] in reserved_fields:
+                ndescr.append((d, t[1]))
+            else:
+                ndescr.append(t)
+        else:
+            ndescr.append((n, t[1]))
+    return np.dtype(ndescr)
+
+
+def _get_fieldmask(self):
+    mdescr = [(n, '|b1') for n in self.dtype.names]
+    fdmask = np.empty(self.shape, dtype=mdescr)
+    fdmask.flat = tuple([False] * len(mdescr))
+    return fdmask
+
+
+class MaskedRecords(MaskedArray, object):
+    """
+
+    Attributes
+    ----------
+    _data : recarray
+        Underlying data, as a record array.
+    _mask : boolean array
+        Mask of the records. A record is masked when all its fields are
+        masked.
+    _fieldmask : boolean recarray
+        Record array of booleans, setting the mask of each individual field
+        of each record.
+    _fill_value : record
+        Filling values for each field.
+
+    """
+
+    def __new__(cls, shape, dtype=None, buf=None, offset=0, strides=None,
+                formats=None, names=None, titles=None,
+                byteorder=None, aligned=False,
+                mask=nomask, hard_mask=False, fill_value=None, keep_mask=True,
+                copy=False,
+                **options):
+
+        self = recarray.__new__(cls, shape, dtype=dtype, buf=buf, offset=offset,
+                                strides=strides, formats=formats, names=names,
+                                titles=titles, byteorder=byteorder,
+                                aligned=aligned,)
+
+        mdtype = ma.make_mask_descr(self.dtype)
+        if mask is nomask or not np.size(mask):
+            if not keep_mask:
+                self._mask = tuple([False] * len(mdtype))
+        else:
+            mask = np.array(mask, copy=copy)
+            if mask.shape != self.shape:
+                (nd, nm) = (self.size, mask.size)
+                if nm == 1:
+                    mask = np.resize(mask, self.shape)
+                elif nm == nd:
+                    mask = np.reshape(mask, self.shape)
+                else:
+                    msg = "Mask and data not compatible: data size is %i, " + \
+                          "mask size is %i."
+                    raise MAError(msg % (nd, nm))
+                copy = True
+            if not keep_mask:
+                self.__setmask__(mask)
+                self._sharedmask = True
+            else:
+                if mask.dtype == mdtype:
+                    _mask = mask
+                else:
+                    _mask = np.array([tuple([m] * len(mdtype)) for m in mask],
+                                     dtype=mdtype)
+                self._mask = _mask
+        return self
+
+    def __array_finalize__(self, obj):
+        # Make sure we have a _fieldmask by default
+        _mask = getattr(obj, '_mask', None)
+        if _mask is None:
+            objmask = getattr(obj, '_mask', nomask)
+            _dtype = ndarray.__getattribute__(self, 'dtype')
+            if objmask is nomask:
+                _mask = ma.make_mask_none(self.shape, dtype=_dtype)
+            else:
+                mdescr = ma.make_mask_descr(_dtype)
+                _mask = narray([tuple([m] * len(mdescr)) for m in objmask],
+                               dtype=mdescr).view(recarray)
+        # Update some of the attributes
+        _dict = self.__dict__
+        _dict.update(_mask=_mask)
+        self._update_from(obj)
+        if _dict['_baseclass'] == ndarray:
+            _dict['_baseclass'] = recarray
+        return
+
+    def _getdata(self):
+        """
+        Returns the data as a recarray.
+
+        """
+        return ndarray.view(self, recarray)
+
+    _data = property(fget=_getdata)
+
+    def _getfieldmask(self):
+        """
+        Alias to mask.
+
+        """
+        return self._mask
+
+    _fieldmask = property(fget=_getfieldmask)
+
+    def __len__(self):
+        """
+        Returns the length
+
+        """
+        # We have more than one record
+        if self.ndim:
+            return len(self._data)
+        # We have only one record: return the nb of fields
+        return len(self.dtype)
+
+    def __getattribute__(self, attr):
+        try:
+            return object.__getattribute__(self, attr)
+        except AttributeError:
+            # attr must be a fieldname
+            pass
+        fielddict = ndarray.__getattribute__(self, 'dtype').fields
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+        # So far, so good
+        _localdict = ndarray.__getattribute__(self, '__dict__')
+        _data = ndarray.view(self, _localdict['_baseclass'])
+        obj = _data.getfield(*res)
+        if obj.dtype.fields:
+            raise NotImplementedError("MaskedRecords is currently limited to"
+                                      "simple records.")
+        # Get some special attributes
+        # Reset the object's mask
+        hasmasked = False
+        _mask = _localdict.get('_mask', None)
+        if _mask is not None:
+            try:
+                _mask = _mask[attr]
+            except IndexError:
+                # Couldn't find a mask: use the default (nomask)
+                pass
+            hasmasked = _mask.view((np.bool, (len(_mask.dtype) or 1))).any()
+        if (obj.shape or hasmasked):
+            obj = obj.view(MaskedArray)
+            obj._baseclass = ndarray
+            obj._isfield = True
+            obj._mask = _mask
+            # Reset the field values
+            _fill_value = _localdict.get('_fill_value', None)
+            if _fill_value is not None:
+                try:
+                    obj._fill_value = _fill_value[attr]
+                except ValueError:
+                    obj._fill_value = None
+        else:
+            obj = obj.item()
+        return obj
+
+    def __setattr__(self, attr, val):
+        """
+        Sets the attribute attr to the value val.
+
+        """
+        # Should we call __setmask__ first ?
+        if attr in ['mask', 'fieldmask']:
+            self.__setmask__(val)
+            return
+        # Create a shortcut (so that we don't have to call getattr all the time)
+        _localdict = object.__getattribute__(self, '__dict__')
+        # Check whether we're creating a new field
+        newattr = attr not in _localdict
+        try:
+            # Is attr a generic attribute ?
+            ret = object.__setattr__(self, attr, val)
+        except:
+            # Not a generic attribute: exit if it's not a valid field
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            optinfo = ndarray.__getattribute__(self, '_optinfo') or {}
+            if not (attr in fielddict or attr in optinfo):
+                exctype, value = sys.exc_info()[:2]
+                raise exctype(value)
+        else:
+            # Get the list of names
+            fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
+            # Check the attribute
+            if attr not in fielddict:
+                return ret
+            if newattr:
+                # We just added this one or this setattr worked on an
+                # internal attribute.
+                try:
+                    object.__delattr__(self, attr)
+                except:
+                    return ret
+        # Let's try to set the field
+        try:
+            res = fielddict[attr][:2]
+        except (TypeError, KeyError):
+            raise AttributeError("record array has no attribute %s" % attr)
+
+        if val is masked:
+            _fill_value = _localdict['_fill_value']
+            if _fill_value is not None:
+                dval = _localdict['_fill_value'][attr]
+            else:
+                dval = val
+            mval = True
+        else:
+            dval = filled(val)
+            mval = getmaskarray(val)
+        obj = ndarray.__getattribute__(self, '_data').setfield(dval, *res)
+        _localdict['_mask'].__setitem__(attr, mval)
+        return obj
+
+    def __getitem__(self, indx):
+        """
+        Returns all the fields sharing the same fieldname base.
+
+        The fieldname base is either `_data` or `_mask`.
+
+        """
+        _localdict = self.__dict__
+        _mask = ndarray.__getattribute__(self, '_mask')
+        _data = ndarray.view(self, _localdict['_baseclass'])
+        # We want a field
+        if isinstance(indx, basestring):
+            # Make sure _sharedmask is True to propagate back to _fieldmask
+            # Don't use _set_mask, there are some copies being made that
+            # break propagation Don't force the mask to nomask, that wreaks
+            # easy masking
+            obj = _data[indx].view(MaskedArray)
+            obj._mask = _mask[indx]
+            obj._sharedmask = True
+            fval = _localdict['_fill_value']
+            if fval is not None:
+                obj._fill_value = fval[indx]
+            # Force to masked if the mask is True
+            if not obj.ndim and obj._mask:
+                return masked
+            return obj
+        # We want some elements.
+        # First, the data.
+        obj = np.array(_data[indx], copy=False).view(mrecarray)
+        obj._mask = np.array(_mask[indx], copy=False).view(recarray)
+        return obj
+
+    def __setitem__(self, indx, value):
+        """
+        Sets the given record to value.
+
+        """
+        MaskedArray.__setitem__(self, indx, value)
+        if isinstance(indx, basestring):
+            self._mask[indx] = ma.getmaskarray(value)
+
+    def __str__(self):
+        """
+        Calculates the string representation.
+
+        """
+        if self.size > 1:
+            mstr = ["(%s)" % ",".join([str(i) for i in s])
+                    for s in zip(*[getattr(self, f) for f in self.dtype.names])]
+            return "[%s]" % ", ".join(mstr)
+        else:
+            mstr = ["%s" % ",".join([str(i) for i in s])
+                    for s in zip([getattr(self, f) for f in self.dtype.names])]
+            return "(%s)" % ", ".join(mstr)
+
+    def __repr__(self):
+        """
+        Calculates the repr representation.
+
+        """
+        _names = self.dtype.names
+        fmt = "%%%is : %%s" % (max([len(n) for n in _names]) + 4,)
+        reprstr = [fmt % (f, getattr(self, f)) for f in self.dtype.names]
+        reprstr.insert(0, 'masked_records(')
+        reprstr.extend([fmt % ('    fill_value', self.fill_value),
+                         '              )'])
+        return str("\n".join(reprstr))
+
+    def view(self, dtype=None, type=None):
+        """
+        Returns a view of the mrecarray.
+
+        """
+        # OK, basic copy-paste from MaskedArray.view.
+        if dtype is None:
+            if type is None:
+                output = ndarray.view(self)
+            else:
+                output = ndarray.view(self, type)
+        # Here again.
+        elif type is None:
+            try:
+                if issubclass(dtype, ndarray):
+                    output = ndarray.view(self, dtype)
+                    dtype = None
+                else:
+                    output = ndarray.view(self, dtype)
+            # OK, there's the change
+            except TypeError:
+                dtype = np.dtype(dtype)
+                # we need to revert to MaskedArray, but keeping the possibility
+                # of subclasses (eg, TimeSeriesRecords), so we'll force a type
+                # set to the first parent
+                if dtype.fields is None:
+                    basetype = self.__class__.__bases__[0]
+                    output = self.__array__().view(dtype, basetype)
+                    output._update_from(self)
+                else:
+                    output = ndarray.view(self, dtype)
+                output._fill_value = None
+        else:
+            output = ndarray.view(self, dtype, type)
+        # Update the mask, just like in MaskedArray.view
+        if (getattr(output, '_mask', nomask) is not nomask):
+            mdtype = ma.make_mask_descr(output.dtype)
+            output._mask = self._mask.view(mdtype, ndarray)
+            output._mask.shape = output.shape
+        return output
+
+    def harden_mask(self):
+        """
+        Forces the mask to hard.
+
+        """
+        self._hardmask = True
+
+    def soften_mask(self):
+        """
+        Forces the mask to soft
+
+        """
+        self._hardmask = False
+
+    def copy(self):
+        """
+        Returns a copy of the masked record.
+
+        """
+        copied = self._data.copy().view(type(self))
+        copied._mask = self._mask.copy()
+        return copied
+
+    def tolist(self, fill_value=None):
+        """
+        Return the data portion of the array as a list.
+
+        Data items are converted to the nearest compatible Python type.
+        Masked values are converted to fill_value. If fill_value is None,
+        the corresponding entries in the output list will be ``None``.
+
+        """
+        if fill_value is not None:
+            return self.filled(fill_value).tolist()
+        result = narray(self.filled().tolist(), dtype=object)
+        mask = narray(self._mask.tolist())
+        result[mask] = None
+        return result.tolist()
+
+    def __getstate__(self):
+        """Return the internal state of the masked array.
+
+        This is for pickling.
+
+        """
+        state = (1,
+                 self.shape,
+                 self.dtype,
+                 self.flags.fnc,
+                 self._data.tobytes(),
+                 self._mask.tobytes(),
+                 self._fill_value,
+                 )
+        return state
+
+    def __setstate__(self, state):
+        """
+        Restore the internal state of the masked array.
+
+        This is for pickling.  ``state`` is typically the output of the
+        ``__getstate__`` output, and is a 5-tuple:
+
+        - class name
+        - a tuple giving the shape of the data
+        - a typecode for the data
+        - a binary string for the data
+        - a binary string for the mask.
+
+        """
+        (ver, shp, typ, isf, raw, msk, flv) = state
+        ndarray.__setstate__(self, (shp, typ, isf, raw))
+        mdtype = dtype([(k, bool_) for (k, _) in self.dtype.descr])
+        self.__dict__['_mask'].__setstate__((shp, mdtype, isf, msk))
+        self.fill_value = flv
+
+    def __reduce__(self):
+        """
+        Return a 3-tuple for pickling a MaskedArray.
+
+        """
+        return (_mrreconstruct,
+                (self.__class__, self._baseclass, (0,), 'b',),
+                self.__getstate__())
+
+def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
+    """
+    Build a new MaskedArray from the information stored in a pickle.
+
+    """
+    _data = ndarray.__new__(baseclass, baseshape, basetype).view(subtype)
+    _mask = ndarray.__new__(ndarray, baseshape, 'b1')
+    return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
+mrecarray = MaskedRecords
+
+
+###############################################################################
+#                             Constructors                                    #
+###############################################################################
+
+
+def fromarrays(arraylist, dtype=None, shape=None, formats=None,
+               names=None, titles=None, aligned=False, byteorder=None,
+               fill_value=None):
+    """
+    Creates a mrecarray from a (flat) list of masked arrays.
+
+    Parameters
+    ----------
+    arraylist : sequence
+        A list of (masked) arrays. Each element of the sequence is first converted
+        to a masked array if needed. If a 2D array is passed as argument, it is
+        processed line by line
+    dtype : {None, dtype}, optional
+        Data type descriptor.
+    shape : {None, integer}, optional
+        Number of records. If None, shape is defined from the shape of the
+        first array in the list.
+    formats : {None, sequence}, optional
+        Sequence of formats for each individual field. If None, the formats will
+        be autodetected by inspecting the fields and selecting the highest dtype
+        possible.
+    names : {None, sequence}, optional
+        Sequence of the names of each field.
+    fill_value : {None, sequence}, optional
+        Sequence of data to be used as filling values.
+
+    Notes
+    -----
+    Lists of tuples should be preferred over lists of lists for faster processing.
+
+    """
+    datalist = [getdata(x) for x in arraylist]
+    masklist = [np.atleast_1d(getmaskarray(x)) for x in arraylist]
+    _array = recfromarrays(datalist,
+                           dtype=dtype, shape=shape, formats=formats,
+                           names=names, titles=titles, aligned=aligned,
+                           byteorder=byteorder).view(mrecarray)
+    _array._mask.flat = list(zip(*masklist))
+    if fill_value is not None:
+        _array.fill_value = fill_value
+    return _array
+
+
+def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None,
+                titles=None, aligned=False, byteorder=None,
+                fill_value=None, mask=nomask):
+    """
+    Creates a MaskedRecords from a list of records.
+
+    Parameters
+    ----------
+    reclist : sequence
+        A list of records. Each element of the sequence is first converted
+        to a masked array if needed. If a 2D array is passed as argument, it is
+        processed line by line
+    dtype : {None, dtype}, optional
+        Data type descriptor.
+    shape : {None,int}, optional
+        Number of records. If None, ``shape`` is defined from the shape of the
+        first array in the list.
+    formats : {None, sequence}, optional
+        Sequence of formats for each individual field. If None, the formats will
+        be autodetected by inspecting the fields and selecting the highest dtype
+        possible.
+    names : {None, sequence}, optional
+        Sequence of the names of each field.
+    fill_value : {None, sequence}, optional
+        Sequence of data to be used as filling values.
+    mask : {nomask, sequence}, optional.
+        External mask to apply on the data.
+
+    Notes
+    -----
+    Lists of tuples should be preferred over lists of lists for faster processing.
+
+    """
+    # Grab the initial _fieldmask, if needed:
+    _mask = getattr(reclist, '_mask', None)
+    # Get the list of records.
+    if isinstance(reclist, ndarray):
+        # Make sure we don't have some hidden mask
+        if isinstance(reclist, MaskedArray):
+            reclist = reclist.filled().view(ndarray)
+        # Grab the initial dtype, just in case
+        if dtype is None:
+            dtype = reclist.dtype
+        reclist = reclist.tolist()
+    mrec = recfromrecords(reclist, dtype=dtype, shape=shape, formats=formats,
+                          names=names, titles=titles,
+                          aligned=aligned, byteorder=byteorder).view(mrecarray)
+    # Set the fill_value if needed
+    if fill_value is not None:
+        mrec.fill_value = fill_value
+    # Now, let's deal w/ the mask
+    if mask is not nomask:
+        mask = np.array(mask, copy=False)
+        maskrecordlength = len(mask.dtype)
+        if maskrecordlength:
+            mrec._mask.flat = mask
+        elif len(mask.shape) == 2:
+            mrec._mask.flat = [tuple(m) for m in mask]
+        else:
+            mrec.__setmask__(mask)
+    if _mask is not None:
+        mrec._mask[:] = _mask
+    return mrec
+
+
+def _guessvartypes(arr):
+    """
+    Tries to guess the dtypes of the str_ ndarray `arr`.
+
+    Guesses by testing element-wise conversion. Returns a list of dtypes.
+    The array is first converted to ndarray. If the array is 2D, the test
+    is performed on the first line. An exception is raised if the file is
+    3D or more.
+
+    """
+    vartypes = []
+    arr = np.asarray(arr)
+    if len(arr.shape) == 2:
+        arr = arr[0]
+    elif len(arr.shape) > 2:
+        raise ValueError("The array should be 2D at most!")
+    # Start the conversion loop.
+    for f in arr:
+        try:
+            int(f)
+        except ValueError:
+            try:
+                float(f)
+            except ValueError:
+                try:
+                    complex(f)
+                except ValueError:
+                    vartypes.append(arr.dtype)
+                else:
+                    vartypes.append(np.dtype(complex))
+            else:
+                vartypes.append(np.dtype(float))
+        else:
+            vartypes.append(np.dtype(int))
+    return vartypes
+
+
+def openfile(fname):
+    """
+    Opens the file handle of file `fname`.
+
+    """
+    # A file handle
+    if hasattr(fname, 'readline'):
+        return fname
+    # Try to open the file and guess its type
+    try:
+        f = open(fname)
+    except IOError:
+        raise IOError("No such file: '%s'" % fname)
+    if f.readline()[:2] != "\\x":
+        f.seek(0, 0)
+        return f
+    f.close()
+    raise NotImplementedError("Wow, binary file")
+
+
+def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='',
+                 varnames=None, vartypes=None):
+    """
+    Creates a mrecarray from data stored in the file `filename`.
+
+    Parameters
+    ----------
+    fname : {file name/handle}
+        Handle of an opened file.
+    delimitor : {None, string}, optional
+        Alphanumeric character used to separate columns in the file.
+        If None, any (group of) white spacestring(s) will be used.
+    commentchar : {'#', string}, optional
+        Alphanumeric character used to mark the start of a comment.
+    missingchar : {'', string}, optional
+        String indicating missing data, and used to create the masks.
+    varnames : {None, sequence}, optional
+        Sequence of the variable names. If None, a list will be created from
+        the first non empty line of the file.
+    vartypes : {None, sequence}, optional
+        Sequence of the variables dtypes. If None, it will be estimated from
+        the first non-commented line.
+
+
+    Ultra simple: the varnames are in the header, one line"""
+    # Try to open the file.
+    ftext = openfile(fname)
+
+    # Get the first non-empty line as the varnames
+    while True:
+        line = ftext.readline()
+        firstline = line[:line.find(commentchar)].strip()
+        _varnames = firstline.split(delimitor)
+        if len(_varnames) > 1:
+            break
+    if varnames is None:
+        varnames = _varnames
+
+    # Get the data.
+    _variables = masked_array([line.strip().split(delimitor) for line in ftext
+                               if line[0] != commentchar and len(line) > 1])
+    (_, nfields) = _variables.shape
+    ftext.close()
+
+    # Try to guess the dtype.
+    if vartypes is None:
+        vartypes = _guessvartypes(_variables[0])
+    else:
+        vartypes = [np.dtype(v) for v in vartypes]
+        if len(vartypes) != nfields:
+            msg = "Attempting to %i dtypes for %i fields!"
+            msg += " Reverting to default."
+            warnings.warn(msg % (len(vartypes), nfields))
+            vartypes = _guessvartypes(_variables[0])
+
+    # Construct the descriptor.
+    mdescr = [(n, f) for (n, f) in zip(varnames, vartypes)]
+    mfillv = [ma.default_fill_value(f) for f in vartypes]
+
+    # Get the data and the mask.
+    # We just need a list of masked_arrays. It's easier to create it like that:
+    _mask = (_variables.T == missingchar)
+    _datalist = [masked_array(a, mask=m, dtype=t, fill_value=f)
+                 for (a, m, t, f) in zip(_variables.T, _mask, vartypes, mfillv)]
+
+    return fromarrays(_datalist, dtype=mdescr)
+
+
+def addfield(mrecord, newfield, newfieldname=None):
+    """Adds a new field to the masked record array
+
+    Uses `newfield` as data and `newfieldname` as name. If `newfieldname`
+    is None, the new field name is set to 'fi', where `i` is the number of
+    existing fields.
+
+    """
+    _data = mrecord._data
+    _mask = mrecord._mask
+    if newfieldname is None or newfieldname in reserved_fields:
+        newfieldname = 'f%i' % len(_data.dtype)
+    newfield = ma.array(newfield)
+    # Get the new data.
+    # Create a new empty recarray
+    newdtype = np.dtype(_data.dtype.descr + [(newfieldname, newfield.dtype)])
+    newdata = recarray(_data.shape, newdtype)
+    # Add the exisintg field
+    [newdata.setfield(_data.getfield(*f), *f)
+         for f in _data.dtype.fields.values()]
+    # Add the new field
+    newdata.setfield(newfield._data, *newdata.dtype.fields[newfieldname])
+    newdata = newdata.view(MaskedRecords)
+    # Get the new mask
+    # Create a new empty recarray
+    newmdtype = np.dtype([(n, bool_) for n in newdtype.names])
+    newmask = recarray(_data.shape, newmdtype)
+    # Add the old masks
+    [newmask.setfield(_mask.getfield(*f), *f)
+         for f in _mask.dtype.fields.values()]
+    # Add the mask of the new field
+    newmask.setfield(getmaskarray(newfield),
+                     *newmask.dtype.fields[newfieldname])
+    newdata._mask = newmask
+    return newdata
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/setup.py
new file mode 100644
index 0000000000..6c6a52abad
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('ma', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    config = configuration(top_path='').todict()
+    setup(**config)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_core.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
new file mode 100644
index 0000000000..b163d3b264
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
@@ -0,0 +1,4260 @@
+# pylint: disable-msg=W0401,W0511,W0611,W0612,W0614,R0201,E1102
+"""Tests suite for MaskedArray & subclassing.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+"""
+from __future__ import division, absolute_import, print_function
+
+__author__ = "Pierre GF Gerard-Marchant"
+
+import warnings
+import pickle
+import operator
+import itertools
+from functools import reduce
+
+
+import numpy as np
+import numpy.ma.core
+import numpy.core.fromnumeric as fromnumeric
+import numpy.core.umath as umath
+from numpy.testing import TestCase, run_module_suite, assert_raises
+from numpy import ndarray
+from numpy.compat import asbytes, asbytes_nested
+from numpy.ma.testutils import (
+    assert_, assert_array_equal, assert_equal, assert_almost_equal,
+    assert_equal_records, fail_if_equal, assert_not_equal,
+    assert_mask_equal,
+    )
+from numpy.ma.core import (
+    MAError, MaskError, MaskType, MaskedArray, abs, absolute, add, all,
+    allclose, allequal, alltrue, angle, anom, arange, arccos, arctan2,
+    arcsin, arctan, argsort, array, asarray, choose, concatenate,
+    conjugate, cos, cosh, count, default_fill_value, diag, divide, empty,
+    empty_like, equal, exp, flatten_mask, filled, fix_invalid,
+    flatten_structured_array, fromflex, getmask, getmaskarray, greater,
+    greater_equal, identity, inner, isMaskedArray, less, less_equal, log,
+    log10, make_mask, make_mask_descr, mask_or, masked, masked_array,
+    masked_equal, masked_greater, masked_greater_equal, masked_inside,
+    masked_less, masked_less_equal, masked_not_equal, masked_outside,
+    masked_print_option, masked_values, masked_where, max, maximum,
+    maximum_fill_value, min, minimum, minimum_fill_value, mod, multiply,
+    mvoid, nomask, not_equal, ones, outer, power, product, put, putmask,
+    ravel, repeat, reshape, resize, shape, sin, sinh, sometrue, sort, sqrt,
+    subtract, sum, take, tan, tanh, transpose, where, zeros,
+    )
+
+pi = np.pi
+
+
+class TestMaskedArray(TestCase):
+    # Base test class for MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
+
+    def test_basicattributes(self):
+        # Tests some basic array attributes.
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        assert_equal(a.ndim, 1)
+        assert_equal(b.ndim, 1)
+        assert_equal(a.size, 3)
+        assert_equal(b.size, 3)
+        assert_equal(a.shape, (3,))
+        assert_equal(b.shape, (3,))
+
+    def test_basic0d(self):
+        # Checks masking a scalar
+        x = masked_array(0)
+        assert_equal(str(x), '0')
+        x = masked_array(0, mask=True)
+        assert_equal(str(x), str(masked_print_option))
+        x = masked_array(0, mask=False)
+        assert_equal(str(x), '0')
+        x = array(0, mask=1)
+        self.assertTrue(x.filled().dtype is x._data.dtype)
+
+    def test_basic1d(self):
+        # Test of basic array creation and properties in 1 dimension.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        self.assertTrue(not isMaskedArray(x))
+        self.assertTrue(isMaskedArray(xm))
+        self.assertTrue((xm - ym).filled(0).any())
+        fail_if_equal(xm.mask.astype(int), ym.mask.astype(int))
+        s = x.shape
+        assert_equal(np.shape(xm), s)
+        assert_equal(xm.shape, s)
+        assert_equal(xm.dtype, x.dtype)
+        assert_equal(zm.dtype, z.dtype)
+        assert_equal(xm.size, reduce(lambda x, y:x * y, s))
+        assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+        assert_array_equal(xm, xf)
+        assert_array_equal(filled(xm, 1.e20), xf)
+        assert_array_equal(x, xm)
+
+    def test_basic2d(self):
+        # Test of basic array creation and properties in 2 dimensions.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        for s in [(4, 3), (6, 2)]:
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+
+            self.assertTrue(not isMaskedArray(x))
+            self.assertTrue(isMaskedArray(xm))
+            assert_equal(shape(xm), s)
+            assert_equal(xm.shape, s)
+            assert_equal(xm.size, reduce(lambda x, y:x * y, s))
+            assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+            assert_equal(xm, xf)
+            assert_equal(filled(xm, 1.e20), xf)
+            assert_equal(x, xm)
+
+    def test_concatenate_basic(self):
+        # Tests concatenations.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # basic concatenation
+        assert_equal(np.concatenate((x, y)), concatenate((xm, ym)))
+        assert_equal(np.concatenate((x, y)), concatenate((x, y)))
+        assert_equal(np.concatenate((x, y)), concatenate((xm, y)))
+        assert_equal(np.concatenate((x, y, x)), concatenate((x, ym, x)))
+
+    def test_concatenate_alongaxis(self):
+        # Tests concatenations.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # Concatenation along an axis
+        s = (3, 4)
+        x.shape = y.shape = xm.shape = ym.shape = s
+        assert_equal(xm.mask, np.reshape(m1, s))
+        assert_equal(ym.mask, np.reshape(m2, s))
+        xmym = concatenate((xm, ym), 1)
+        assert_equal(np.concatenate((x, y), 1), xmym)
+        assert_equal(np.concatenate((xm.mask, ym.mask), 1), xmym._mask)
+
+        x = zeros(2)
+        y = array(ones(2), mask=[False, True])
+        z = concatenate((x, y))
+        assert_array_equal(z, [0, 0, 1, 1])
+        assert_array_equal(z.mask, [False, False, False, True])
+        z = concatenate((y, x))
+        assert_array_equal(z, [1, 1, 0, 0])
+        assert_array_equal(z.mask, [False, True, False, False])
+
+    def test_concatenate_flexible(self):
+        # Tests the concatenation on flexible arrays.
+        data = masked_array(list(zip(np.random.rand(10),
+                                     np.arange(10))),
+                            dtype=[('a', float), ('b', int)])
+
+        test = concatenate([data[:5], data[5:]])
+        assert_equal_records(test, data)
+
+    def test_creation_ndmin(self):
+        # Check the use of ndmin
+        x = array([1, 2, 3], mask=[1, 0, 0], ndmin=2)
+        assert_equal(x.shape, (1, 3))
+        assert_equal(x._data, [[1, 2, 3]])
+        assert_equal(x._mask, [[1, 0, 0]])
+
+    def test_creation_ndmin_from_maskedarray(self):
+        # Make sure we're not losing the original mask w/ ndmin
+        x = array([1, 2, 3])
+        x[-1] = masked
+        xx = array(x, ndmin=2, dtype=float)
+        assert_equal(x.shape, x._mask.shape)
+        assert_equal(xx.shape, xx._mask.shape)
+
+    def test_creation_maskcreation(self):
+        # Tests how masks are initialized at the creation of Maskedarrays.
+        data = arange(24, dtype=float)
+        data[[3, 6, 15]] = masked
+        dma_1 = MaskedArray(data)
+        assert_equal(dma_1.mask, data.mask)
+        dma_2 = MaskedArray(dma_1)
+        assert_equal(dma_2.mask, dma_1.mask)
+        dma_3 = MaskedArray(dma_1, mask=[1, 0, 0, 0] * 6)
+        fail_if_equal(dma_3.mask, dma_1.mask)
+
+        x = array([1, 2, 3], mask=True)
+        assert_equal(x._mask, [True, True, True])
+        x = array([1, 2, 3], mask=False)
+        assert_equal(x._mask, [False, False, False])
+        y = array([1, 2, 3], mask=x._mask, copy=False)
+        assert_(np.may_share_memory(x.mask, y.mask))
+        y = array([1, 2, 3], mask=x._mask, copy=True)
+        assert_(not np.may_share_memory(x.mask, y.mask))
+
+    def test_creation_with_list_of_maskedarrays(self):
+        # Tests creating a masked array from a list of masked arrays.
+        x = array(np.arange(5), mask=[1, 0, 0, 0, 0])
+        data = array((x, x[::-1]))
+        assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
+        assert_equal(data._mask, [[1, 0, 0, 0, 0], [0, 0, 0, 0, 1]])
+
+        x.mask = nomask
+        data = array((x, x[::-1]))
+        assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
+        self.assertTrue(data.mask is nomask)
+
+    def test_asarray(self):
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        xm.fill_value = -9999
+        xm._hardmask = True
+        xmm = asarray(xm)
+        assert_equal(xmm._data, xm._data)
+        assert_equal(xmm._mask, xm._mask)
+        assert_equal(xmm.fill_value, xm.fill_value)
+        assert_equal(xmm._hardmask, xm._hardmask)
+
+    def test_asarray_default_order(self):
+        # See Issue #6646
+        m = np.eye(3).T
+        self.assertFalse(m.flags.c_contiguous)
+
+        new_m = asarray(m)
+        self.assertTrue(new_m.flags.c_contiguous)
+
+    def test_asarray_enforce_order(self):
+        # See Issue #6646
+        m = np.eye(3).T
+        self.assertFalse(m.flags.c_contiguous)
+
+        new_m = asarray(m, order='C')
+        self.assertTrue(new_m.flags.c_contiguous)
+
+    def test_fix_invalid(self):
+        # Checks fix_invalid.
+        with np.errstate(invalid='ignore'):
+            data = masked_array([np.nan, 0., 1.], mask=[0, 0, 1])
+            data_fixed = fix_invalid(data)
+            assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
+            assert_equal(data_fixed._mask, [1., 0., 1.])
+
+    def test_maskedelement(self):
+        # Test of masked element
+        x = arange(6)
+        x[1] = masked
+        self.assertTrue(str(masked) == '--')
+        self.assertTrue(x[1] is masked)
+        assert_equal(filled(x[1], 0), 0)
+
+    def test_set_element_as_object(self):
+        # Tests setting elements with object
+        a = empty(1, dtype=object)
+        x = (1, 2, 3, 4, 5)
+        a[0] = x
+        assert_equal(a[0], x)
+        self.assertTrue(a[0] is x)
+
+        import datetime
+        dt = datetime.datetime.now()
+        a[0] = dt
+        self.assertTrue(a[0] is dt)
+
+    def test_indexing(self):
+        # Tests conversions and indexing
+        x1 = np.array([1, 2, 4, 3])
+        x2 = array(x1, mask=[1, 0, 0, 0])
+        x3 = array(x1, mask=[0, 1, 0, 1])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        assert_equal(np.sort(x1), sort(x2, endwith=False))
+        # tests of indexing
+        assert_(type(x2[1]) is type(x1[1]))
+        assert_(x1[1] == x2[1])
+        assert_(x2[0] is masked)
+        assert_equal(x1[2], x2[2])
+        assert_equal(x1[2:5], x2[2:5])
+        assert_equal(x1[:], x2[:])
+        assert_equal(x1[1:], x3[1:])
+        x1[2] = 9
+        x2[2] = 9
+        assert_equal(x1, x2)
+        x1[1:3] = 99
+        x2[1:3] = 99
+        assert_equal(x1, x2)
+        x2[1] = masked
+        assert_equal(x1, x2)
+        x2[1:3] = masked
+        assert_equal(x1, x2)
+        x2[:] = x1
+        x2[1] = masked
+        assert_(allequal(getmask(x2), array([0, 1, 0, 0])))
+        x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x3), array([0, 1, 1, 0])))
+        x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x4), array([0, 1, 1, 0])))
+        assert_(allequal(x4, array([1, 2, 3, 4])))
+        x1 = np.arange(5) * 1.0
+        x2 = masked_values(x1, 3.0)
+        assert_equal(x1, x2)
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_equal(3.0, x2.fill_value)
+        x1 = array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        s1 = x1[1]
+        s2 = x2[1]
+        assert_equal(type(s2), str)
+        assert_equal(type(s1), str)
+        assert_equal(s1, s2)
+        assert_(x1[1:1].shape == (0,))
+
+    def test_matrix_indexing(self):
+        # Tests conversions and indexing
+        x1 = np.matrix([[1, 2, 3], [4, 3, 2]])
+        x2 = array(x1, mask=[[1, 0, 0], [0, 1, 0]])
+        x3 = array(x1, mask=[[0, 1, 0], [1, 0, 0]])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        # tests of indexing
+        assert_(type(x2[1, 0]) is type(x1[1, 0]))
+        assert_(x1[1, 0] == x2[1, 0])
+        assert_(x2[1, 1] is masked)
+        assert_equal(x1[0, 2], x2[0, 2])
+        assert_equal(x1[0, 1:], x2[0, 1:])
+        assert_equal(x1[:, 2], x2[:, 2])
+        assert_equal(x1[:], x2[:])
+        assert_equal(x1[1:], x3[1:])
+        x1[0, 2] = 9
+        x2[0, 2] = 9
+        assert_equal(x1, x2)
+        x1[0, 1:] = 99
+        x2[0, 1:] = 99
+        assert_equal(x1, x2)
+        x2[0, 1] = masked
+        assert_equal(x1, x2)
+        x2[0, 1:] = masked
+        assert_equal(x1, x2)
+        x2[0, :] = x1[0, :]
+        x2[0, 1] = masked
+        assert_(allequal(getmask(x2), np.array([[0, 1, 0], [0, 1, 0]])))
+        x3[1, :] = masked_array([1, 2, 3], [1, 1, 0])
+        assert_(allequal(getmask(x3)[1], array([1, 1, 0])))
+        assert_(allequal(getmask(x3[1]), array([1, 1, 0])))
+        x4[1, :] = masked_array([1, 2, 3], [1, 1, 0])
+        assert_(allequal(getmask(x4[1]), array([1, 1, 0])))
+        assert_(allequal(x4[1], array([1, 2, 3])))
+        x1 = np.matrix(np.arange(5) * 1.0)
+        x2 = masked_values(x1, 3.0)
+        assert_equal(x1, x2)
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_equal(3.0, x2.fill_value)
+
+    def test_copy(self):
+        # Tests of some subtle points of copying and sizing.
+        n = [0, 0, 1, 0, 0]
+        m = make_mask(n)
+        m2 = make_mask(m)
+        self.assertTrue(m is m2)
+        m3 = make_mask(m, copy=1)
+        self.assertTrue(m is not m3)
+
+        x1 = np.arange(5)
+        y1 = array(x1, mask=m)
+        assert_equal(y1._data.__array_interface__, x1.__array_interface__)
+        self.assertTrue(allequal(x1, y1.data))
+        assert_equal(y1._mask.__array_interface__, m.__array_interface__)
+
+        y1a = array(y1)
+        self.assertTrue(y1a._data.__array_interface__ ==
+                        y1._data.__array_interface__)
+        self.assertTrue(y1a.mask is y1.mask)
+
+        y2 = array(x1, mask=m)
+        self.assertTrue(y2._data.__array_interface__ == x1.__array_interface__)
+        self.assertTrue(y2._mask.__array_interface__ == m.__array_interface__)
+        self.assertTrue(y2[2] is masked)
+        y2[2] = 9
+        self.assertTrue(y2[2] is not masked)
+        self.assertTrue(y2._mask.__array_interface__ != m.__array_interface__)
+        self.assertTrue(allequal(y2.mask, 0))
+
+        y3 = array(x1 * 1.0, mask=m)
+        self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype)
+
+        x4 = arange(4)
+        x4[2] = masked
+        y4 = resize(x4, (8,))
+        assert_equal(concatenate([x4, x4]), y4)
+        assert_equal(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
+        y5 = repeat(x4, (2, 2, 2, 2), axis=0)
+        assert_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
+        y6 = repeat(x4, 2, axis=0)
+        assert_equal(y5, y6)
+        y7 = x4.repeat((2, 2, 2, 2), axis=0)
+        assert_equal(y5, y7)
+        y8 = x4.repeat(2, 0)
+        assert_equal(y5, y8)
+
+        y9 = x4.copy()
+        assert_equal(y9._data, x4._data)
+        assert_equal(y9._mask, x4._mask)
+
+        x = masked_array([1, 2, 3], mask=[0, 1, 0])
+        # Copy is False by default
+        y = masked_array(x)
+        assert_equal(y._data.ctypes.data, x._data.ctypes.data)
+        assert_equal(y._mask.ctypes.data, x._mask.ctypes.data)
+        y = masked_array(x, copy=True)
+        assert_not_equal(y._data.ctypes.data, x._data.ctypes.data)
+        assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data)
+
+    def test_copy_immutable(self):
+        # Tests that the copy method is immutable, GitHub issue #5247
+        a = np.ma.array([1, 2, 3])
+        b = np.ma.array([4, 5, 6])
+        a_copy_method = a.copy
+        b.copy
+        assert_equal(a_copy_method(), [1, 2, 3])
+
+    def test_deepcopy(self):
+        from copy import deepcopy
+        a = array([0, 1, 2], mask=[False, True, False])
+        copied = deepcopy(a)
+        assert_equal(copied.mask, a.mask)
+        assert_not_equal(id(a._mask), id(copied._mask))
+
+        copied[1] = 1
+        assert_equal(copied.mask, [0, 0, 0])
+        assert_equal(a.mask, [0, 1, 0])
+
+        copied = deepcopy(a)
+        assert_equal(copied.mask, a.mask)
+        copied.mask[1] = False
+        assert_equal(copied.mask, [0, 0, 0])
+        assert_equal(a.mask, [0, 1, 0])
+
+    def test_str_repr(self):
+        a = array([0, 1, 2], mask=[False, True, False])
+        assert_equal(str(a), '[0 -- 2]')
+        assert_equal(repr(a), 'masked_array(data = [0 -- 2],\n'
+                              '             mask = [False  True False],\n'
+                              '       fill_value = 999999)\n')
+
+    def test_pickling(self):
+        # Tests pickling
+        a = arange(10)
+        a[::3] = masked
+        a.fill_value = 999
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled._data, a._data)
+        assert_equal(a_pickled.fill_value, 999)
+
+    def test_pickling_subbaseclass(self):
+        # Test pickling w/ a subclass of ndarray
+        a = array(np.matrix(list(range(10))), mask=[1, 0, 1, 0, 0] * 2)
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled, a)
+        self.assertTrue(isinstance(a_pickled._data, np.matrix))
+
+    def test_pickling_maskedconstant(self):
+        # Test pickling MaskedConstant
+        mc = np.ma.masked
+        mc_pickled = pickle.loads(mc.dumps())
+        assert_equal(mc_pickled._baseclass, mc._baseclass)
+        assert_equal(mc_pickled._mask, mc._mask)
+        assert_equal(mc_pickled._data, mc._data)
+
+    def test_pickling_wstructured(self):
+        # Tests pickling w/ structured array
+        a = array([(1, 1.), (2, 2.)], mask=[(0, 0), (0, 1)],
+                  dtype=[('a', int), ('b', float)])
+        a_pickled = pickle.loads(a.dumps())
+        assert_equal(a_pickled._mask, a._mask)
+        assert_equal(a_pickled, a)
+
+    def test_pickling_keepalignment(self):
+        # Tests pickling w/ F_CONTIGUOUS arrays
+        a = arange(10)
+        a.shape = (-1, 2)
+        b = a.T
+        test = pickle.loads(pickle.dumps(b))
+        assert_equal(test, b)
+
+    def test_single_element_subscript(self):
+        # Tests single element subscripts of Maskedarrays.
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        assert_equal(a[0].shape, ())
+        assert_equal(b[0].shape, ())
+        assert_equal(b[1].shape, ())
+
+    def test_topython(self):
+        # Tests some communication issues with Python.
+        assert_equal(1, int(array(1)))
+        assert_equal(1.0, float(array(1)))
+        assert_equal(1, int(array([[[1]]])))
+        assert_equal(1.0, float(array([[1]])))
+        self.assertRaises(TypeError, float, array([1, 1]))
+
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', UserWarning)
+            assert_(np.isnan(float(array([1], mask=[1]))))
+
+        a = array([1, 2, 3], mask=[1, 0, 0])
+        self.assertRaises(TypeError, lambda:float(a))
+        assert_equal(float(a[-1]), 3.)
+        self.assertTrue(np.isnan(float(a[0])))
+        self.assertRaises(TypeError, int, a)
+        assert_equal(int(a[-1]), 3)
+        self.assertRaises(MAError, lambda:int(a[0]))
+
+    def test_oddfeatures_1(self):
+        # Test of other odd features
+        x = arange(20)
+        x = x.reshape(4, 5)
+        x.flat[5] = 12
+        assert_(x[1, 0] == 12)
+        z = x + 10j * x
+        assert_equal(z.real, x)
+        assert_equal(z.imag, 10 * x)
+        assert_equal((z * conjugate(z)).real, 101 * x * x)
+        z.imag[...] = 0.0
+
+        x = arange(10)
+        x[3] = masked
+        assert_(str(x[3]) == str(masked))
+        c = x >= 8
+        assert_(count(where(c, masked, masked)) == 0)
+        assert_(shape(where(c, masked, masked)) == c.shape)
+
+        z = masked_where(c, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        assert_equal(x, z)
+
+    def test_oddfeatures_2(self):
+        # Tests some more features.
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+    def test_oddfeatures_3(self):
+        # Tests some generic features
+        atest = array([10], mask=True)
+        btest = array([20])
+        idx = atest.mask
+        atest[idx] = btest[idx]
+        assert_equal(atest, [20])
+
+    def test_filled_w_object_dtype(self):
+        a = np.ma.masked_all(1, dtype='O')
+        assert_equal(a.filled('x')[0], 'x')
+
+    def test_filled_w_flexible_dtype(self):
+        # Test filled w/ flexible dtype
+        flexi = array([(1, 1, 1)],
+                      dtype=[('i', int), ('s', '|S8'), ('f', float)])
+        flexi[0] = masked
+        assert_equal(flexi.filled(),
+                     np.array([(default_fill_value(0),
+                                default_fill_value('0'),
+                                default_fill_value(0.),)], dtype=flexi.dtype))
+        flexi[0] = masked
+        assert_equal(flexi.filled(1),
+                     np.array([(1, '1', 1.)], dtype=flexi.dtype))
+
+    def test_filled_w_mvoid(self):
+        # Test filled w/ mvoid
+        ndtype = [('a', int), ('b', float)]
+        a = mvoid((1, 2.), mask=[(0, 1)], dtype=ndtype)
+        # Filled using default
+        test = a.filled()
+        assert_equal(tuple(test), (1, default_fill_value(1.)))
+        # Explicit fill_value
+        test = a.filled((-1, -1))
+        assert_equal(tuple(test), (1, -1))
+        # Using predefined filling values
+        a.fill_value = (-999, -999)
+        assert_equal(tuple(a.filled()), (1, -999))
+
+    def test_filled_w_nested_dtype(self):
+        # Test filled w/ nested dtype
+        ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])]
+        a = array([(1, (1, 1)), (2, (2, 2))],
+                  mask=[(0, (1, 0)), (0, (0, 1))], dtype=ndtype)
+        test = a.filled(0)
+        control = np.array([(1, (0, 1)), (2, (2, 0))], dtype=ndtype)
+        assert_equal(test, control)
+
+        test = a['B'].filled(0)
+        control = np.array([(0, 1), (2, 0)], dtype=a['B'].dtype)
+        assert_equal(test, control)
+
+        # test if mask gets set correctly (see #6760)
+        Z = numpy.ma.zeros(2, numpy.dtype([("A", "(2,2)i1,(2,2)i1", (2,2))]))
+        assert_equal(Z.data.dtype, numpy.dtype([('A', [('f0', 'i1', (2, 2)),
+                                          ('f1', 'i1', (2, 2))], (2, 2))]))
+        assert_equal(Z.mask.dtype, numpy.dtype([('A', [('f0', '?', (2, 2)),
+                                          ('f1', '?', (2, 2))], (2, 2))]))
+
+    def test_filled_w_f_order(self):
+        # Test filled w/ F-contiguous array
+        a = array(np.array([(0, 1, 2), (4, 5, 6)], order='F'),
+                  mask=np.array([(0, 0, 1), (1, 0, 0)], order='F'),
+                  order='F')  # this is currently ignored
+        self.assertTrue(a.flags['F_CONTIGUOUS'])
+        self.assertTrue(a.filled(0).flags['F_CONTIGUOUS'])
+
+    def test_optinfo_propagation(self):
+        # Checks that _optinfo dictionary isn't back-propagated
+        x = array([1, 2, 3, ], dtype=float)
+        x._optinfo['info'] = '???'
+        y = x.copy()
+        assert_equal(y._optinfo['info'], '???')
+        y._optinfo['info'] = '!!!'
+        assert_equal(x._optinfo['info'], '???')
+
+    def test_fancy_printoptions(self):
+        # Test printing a masked array w/ fancy dtype.
+        fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])])
+        test = array([(1, (2, 3.0)), (4, (5, 6.0))],
+                     mask=[(1, (0, 1)), (0, (1, 0))],
+                     dtype=fancydtype)
+        control = "[(--, (2, --)) (4, (--, 6.0))]"
+        assert_equal(str(test), control)
+
+        # Test 0-d array with multi-dimensional dtype
+        t_2d0 = masked_array(data = (0, [[0.0, 0.0, 0.0],
+                                        [0.0, 0.0, 0.0]],
+                                    0.0),
+                             mask = (False, [[True, False, True],
+                                             [False, False, True]],
+                                     False),
+                             dtype = "int, (2,3)float, float")
+        control = "(0, [[--, 0.0, --], [0.0, 0.0, --]], 0.0)"
+        assert_equal(str(t_2d0), control)
+
+
+    def test_flatten_structured_array(self):
+        # Test flatten_structured_array on arrays
+        # On ndarray
+        ndtype = [('a', int), ('b', float)]
+        a = np.array([(1, 1), (2, 2)], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = np.array([[1., 1.], [2., 2.]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        # On masked_array
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = array([[1., 1.], [2., 2.]],
+                        mask=[[0, 1], [1, 0]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test.mask, control.mask)
+        # On masked array with nested structure
+        ndtype = [('a', int), ('b', [('ba', int), ('bb', float)])]
+        a = array([(1, (1, 1.1)), (2, (2, 2.2))],
+                  mask=[(0, (1, 0)), (1, (0, 1))], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = array([[1., 1., 1.1], [2., 2., 2.2]],
+                        mask=[[0, 1, 0], [1, 0, 1]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+        assert_equal(test.mask, control.mask)
+        # Keeping the initial shape
+        ndtype = [('a', int), ('b', float)]
+        a = np.array([[(1, 1), ], [(2, 2), ]], dtype=ndtype)
+        test = flatten_structured_array(a)
+        control = np.array([[[1., 1.], ], [[2., 2.], ]], dtype=np.float)
+        assert_equal(test, control)
+        assert_equal(test.dtype, control.dtype)
+
+    def test_void0d(self):
+        # Test creating a mvoid object
+        ndtype = [('a', int), ('b', int)]
+        a = np.array([(1, 2,)], dtype=ndtype)[0]
+        f = mvoid(a)
+        assert_(isinstance(f, mvoid))
+
+        a = masked_array([(1, 2)], mask=[(1, 0)], dtype=ndtype)[0]
+        assert_(isinstance(a, mvoid))
+
+        a = masked_array([(1, 2), (1, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        f = mvoid(a._data[0], a._mask[0])
+        assert_(isinstance(f, mvoid))
+
+    def test_mvoid_getitem(self):
+        # Test mvoid.__getitem__
+        ndtype = [('a', int), ('b', int)]
+        a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
+                         dtype=ndtype)
+        # w/o mask
+        f = a[0]
+        self.assertTrue(isinstance(f, mvoid))
+        assert_equal((f[0], f['a']), (1, 1))
+        assert_equal(f['b'], 2)
+        # w/ mask
+        f = a[1]
+        self.assertTrue(isinstance(f, mvoid))
+        self.assertTrue(f[0] is masked)
+        self.assertTrue(f['a'] is masked)
+        assert_equal(f[1], 4)
+
+        # exotic dtype
+        A = masked_array(data=[([0,1],)],
+                         mask=[([True, False],)],
+                         dtype=[("A", ">i2", (2,))])
+        assert_equal(A[0]["A"], A["A"][0])
+        assert_equal(A[0]["A"], masked_array(data=[0, 1],
+                         mask=[True, False], dtype=">i2"))
+
+    def test_mvoid_iter(self):
+        # Test iteration on __getitem__
+        ndtype = [('a', int), ('b', int)]
+        a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)],
+                         dtype=ndtype)
+        # w/o mask
+        assert_equal(list(a[0]), [1, 2])
+        # w/ mask
+        assert_equal(list(a[1]), [masked, 4])
+
+    def test_mvoid_print(self):
+        # Test printing a mvoid
+        mx = array([(1, 1), (2, 2)], dtype=[('a', int), ('b', int)])
+        assert_equal(str(mx[0]), "(1, 1)")
+        mx['b'][0] = masked
+        ini_display = masked_print_option._display
+        masked_print_option.set_display("-X-")
+        try:
+            assert_equal(str(mx[0]), "(1, -X-)")
+            assert_equal(repr(mx[0]), "(1, -X-)")
+        finally:
+            masked_print_option.set_display(ini_display)
+
+    def test_mvoid_multidim_print(self):
+
+        # regression test for gh-6019
+        t_ma = masked_array(data = [([1, 2, 3],)],
+                            mask = [([False, True, False],)],
+                            fill_value = ([999999, 999999, 999999],),
+                            dtype = [('a', '<i4', (3,))])
+        assert_(str(t_ma[0]) == "([1, --, 3],)")
+        assert_(repr(t_ma[0]) == "([1, --, 3],)")
+
+        # additonal tests with structured arrays
+
+        t_2d = masked_array(data = [([[1, 2], [3,4]],)],
+                            mask = [([[False, True], [True, False]],)],
+                            dtype = [('a', '<i4', (2,2))])
+        assert_(str(t_2d[0]) == "([[1, --], [--, 4]],)")
+        assert_(repr(t_2d[0]) == "([[1, --], [--, 4]],)")
+
+        t_0d = masked_array(data = [(1,2)],
+                            mask = [(True,False)],
+                            dtype = [('a', '<i4'), ('b', '<i4')])
+        assert_(str(t_0d[0]) == "(--, 2)")
+        assert_(repr(t_0d[0]) == "(--, 2)")
+
+        t_2d = masked_array(data = [([[1, 2], [3,4]], 1)],
+                            mask = [([[False, True], [True, False]], False)],
+                            dtype = [('a', '<i4', (2,2)), ('b', float)])
+        assert_(str(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
+        assert_(repr(t_2d[0]) == "([[1, --], [--, 4]], 1.0)")
+
+        t_ne = masked_array(data=[(1, (1, 1))],
+                            mask=[(True, (True, False))],
+                            dtype = [('a', '<i4'), ('b', 'i4,i4')])
+        assert_(str(t_ne[0]) == "(--, (--, 1))")
+        assert_(repr(t_ne[0]) == "(--, (--, 1))")
+
+    def test_object_with_array(self):
+        mx1 = masked_array([1.], mask=[True])
+        mx2 = masked_array([1., 2.])
+        mx = masked_array([mx1, mx2], mask=[False, True])
+        assert_(mx[0] is mx1)
+        assert_(mx[1] is not mx2)
+        assert_(np.all(mx[1].data == mx2.data))
+        assert_(np.all(mx[1].mask))
+        # check that we return a view.
+        mx[1].data[0] = 0.
+        assert_(mx2[0] == 0.)
+
+
+class TestMaskedArrayArithmetic(TestCase):
+    # Base test class for MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = masked_array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf)
+        self.err_status = np.geterr()
+        np.seterr(divide='ignore', invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.err_status)
+
+    def test_basic_arithmetic(self):
+        # Test of basic arithmetic.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        a2d = array([[1, 2], [0, 4]])
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        assert_equal(a2d * a2d, a2d * a2dm)
+        assert_equal(a2d + a2d, a2d + a2dm)
+        assert_equal(a2d - a2d, a2d - a2dm)
+        for s in [(12,), (4, 3), (2, 6)]:
+            x = x.reshape(s)
+            y = y.reshape(s)
+            xm = xm.reshape(s)
+            ym = ym.reshape(s)
+            xf = xf.reshape(s)
+            assert_equal(-x, -xm)
+            assert_equal(x + y, xm + ym)
+            assert_equal(x - y, xm - ym)
+            assert_equal(x * y, xm * ym)
+            assert_equal(x / y, xm / ym)
+            assert_equal(a10 + y, a10 + ym)
+            assert_equal(a10 - y, a10 - ym)
+            assert_equal(a10 * y, a10 * ym)
+            assert_equal(a10 / y, a10 / ym)
+            assert_equal(x + a10, xm + a10)
+            assert_equal(x - a10, xm - a10)
+            assert_equal(x * a10, xm * a10)
+            assert_equal(x / a10, xm / a10)
+            assert_equal(x ** 2, xm ** 2)
+            assert_equal(abs(x) ** 2.5, abs(xm) ** 2.5)
+            assert_equal(x ** y, xm ** ym)
+            assert_equal(np.add(x, y), add(xm, ym))
+            assert_equal(np.subtract(x, y), subtract(xm, ym))
+            assert_equal(np.multiply(x, y), multiply(xm, ym))
+            assert_equal(np.divide(x, y), divide(xm, ym))
+
+    def test_divide_on_different_shapes(self):
+        x = arange(6, dtype=float)
+        x.shape = (2, 3)
+        y = arange(3, dtype=float)
+
+        z = x / y
+        assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
+        assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
+
+        z = x / y[None,:]
+        assert_equal(z, [[-1., 1., 1.], [-1., 4., 2.5]])
+        assert_equal(z.mask, [[1, 0, 0], [1, 0, 0]])
+
+        y = arange(2, dtype=float)
+        z = x / y[:, None]
+        assert_equal(z, [[-1., -1., -1.], [3., 4., 5.]])
+        assert_equal(z.mask, [[1, 1, 1], [0, 0, 0]])
+
+    def test_mixed_arithmetic(self):
+        # Tests mixed arithmetics.
+        na = np.array([1])
+        ma = array([1])
+        self.assertTrue(isinstance(na + ma, MaskedArray))
+        self.assertTrue(isinstance(ma + na, MaskedArray))
+
+    def test_limits_arithmetic(self):
+        tiny = np.finfo(float).tiny
+        a = array([tiny, 1. / tiny, 0.])
+        assert_equal(getmaskarray(a / 2), [0, 0, 0])
+        assert_equal(getmaskarray(2 / a), [1, 0, 1])
+
+    def test_masked_singleton_arithmetic(self):
+        # Tests some scalar arithmetics on MaskedArrays.
+        # Masked singleton should remain masked no matter what
+        xm = array(0, mask=1)
+        self.assertTrue((1 / array(0)).mask)
+        self.assertTrue((1 + xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue(maximum(xm, xm).mask)
+        self.assertTrue(minimum(xm, xm).mask)
+
+    def test_masked_singleton_equality(self):
+        # Tests (in)equality on masked snigleton
+        a = array([1, 2, 3], mask=[1, 1, 0])
+        assert_((a[0] == 0) is masked)
+        assert_((a[0] != 0) is masked)
+        assert_equal((a[-1] == 0), False)
+        assert_equal((a[-1] != 0), True)
+
+    def test_arithmetic_with_masked_singleton(self):
+        # Checks that there's no collapsing to masked
+        x = masked_array([1, 2])
+        y = x * masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+        y = x[0] * masked
+        assert_(y is masked)
+        y = x + masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y._mask, [True, True])
+
+    def test_arithmetic_with_masked_singleton_on_1d_singleton(self):
+        # Check that we're not losing the shape of a singleton
+        x = masked_array([1, ])
+        y = x + masked
+        assert_equal(y.shape, x.shape)
+        assert_equal(y.mask, [True, ])
+
+    def test_scalar_arithmetic(self):
+        x = array(0, mask=0)
+        assert_equal(x.filled().ctypes.data, x.ctypes.data)
+        # Make sure we don't lose the shape in some circumstances
+        xm = array((0, 0)) / 0.
+        assert_equal(xm.shape, (2,))
+        assert_equal(xm.mask, [1, 1])
+
+    def test_basic_ufuncs(self):
+        # Test various functions such as sin, cos.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.cos(x), cos(xm))
+        assert_equal(np.cosh(x), cosh(xm))
+        assert_equal(np.sin(x), sin(xm))
+        assert_equal(np.sinh(x), sinh(xm))
+        assert_equal(np.tan(x), tan(xm))
+        assert_equal(np.tanh(x), tanh(xm))
+        assert_equal(np.sqrt(abs(x)), sqrt(xm))
+        assert_equal(np.log(abs(x)), log(xm))
+        assert_equal(np.log10(abs(x)), log10(xm))
+        assert_equal(np.exp(x), exp(xm))
+        assert_equal(np.arcsin(z), arcsin(zm))
+        assert_equal(np.arccos(z), arccos(zm))
+        assert_equal(np.arctan(z), arctan(zm))
+        assert_equal(np.arctan2(x, y), arctan2(xm, ym))
+        assert_equal(np.absolute(x), absolute(xm))
+        assert_equal(np.angle(x + 1j*y), angle(xm + 1j*ym))
+        assert_equal(np.angle(x + 1j*y, deg=True), angle(xm + 1j*ym, deg=True))
+        assert_equal(np.equal(x, y), equal(xm, ym))
+        assert_equal(np.not_equal(x, y), not_equal(xm, ym))
+        assert_equal(np.less(x, y), less(xm, ym))
+        assert_equal(np.greater(x, y), greater(xm, ym))
+        assert_equal(np.less_equal(x, y), less_equal(xm, ym))
+        assert_equal(np.greater_equal(x, y), greater_equal(xm, ym))
+        assert_equal(np.conjugate(x), conjugate(xm))
+
+    def test_count_func(self):
+        # Tests count
+        assert_equal(1, count(1))
+        assert_equal(0, array(1, mask=[1]))
+
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        res = count(ott)
+        self.assertTrue(res.dtype.type is np.intp)
+        assert_equal(3, res)
+
+        ott = ott.reshape((2, 2))
+        res = count(ott)
+        assert_(res.dtype.type is np.intp)
+        assert_equal(3, res)
+        res = count(ott, 0)
+        assert_(isinstance(res, ndarray))
+        assert_equal([1, 2], res)
+        assert_(getmask(res) is nomask)
+
+        ott = array([0., 1., 2., 3.])
+        res = count(ott, 0)
+        assert_(isinstance(res, ndarray))
+        assert_(res.dtype.type is np.intp)
+
+        assert_raises(IndexError, ott.count, 1)
+
+    def test_minmax_func(self):
+        # Tests minimum and maximum.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        # max doesn't work if shaped
+        xr = np.ravel(x)
+        xmr = ravel(xm)
+        # following are true because of careful selection of data
+        assert_equal(max(xr), maximum(xmr))
+        assert_equal(min(xr), minimum(xmr))
+
+        assert_equal(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3])
+        assert_equal(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9])
+        x = arange(5)
+        y = arange(5) - 2
+        x[3] = masked
+        y[0] = masked
+        assert_equal(minimum(x, y), where(less(x, y), x, y))
+        assert_equal(maximum(x, y), where(greater(x, y), x, y))
+        assert_(minimum(x) == 0)
+        assert_(maximum(x) == 4)
+
+        x = arange(4).reshape(2, 2)
+        x[-1, -1] = masked
+        assert_equal(maximum(x), 2)
+
+    def test_minimummaximum_func(self):
+        a = np.ones((2, 2))
+        aminimum = minimum(a, a)
+        self.assertTrue(isinstance(aminimum, MaskedArray))
+        assert_equal(aminimum, np.minimum(a, a))
+
+        aminimum = minimum.outer(a, a)
+        self.assertTrue(isinstance(aminimum, MaskedArray))
+        assert_equal(aminimum, np.minimum.outer(a, a))
+
+        amaximum = maximum(a, a)
+        self.assertTrue(isinstance(amaximum, MaskedArray))
+        assert_equal(amaximum, np.maximum(a, a))
+
+        amaximum = maximum.outer(a, a)
+        self.assertTrue(isinstance(amaximum, MaskedArray))
+        assert_equal(amaximum, np.maximum.outer(a, a))
+
+    def test_minmax_reduce(self):
+        # Test np.min/maximum.reduce on array w/ full False mask
+        a = array([1, 2, 3], mask=[False, False, False])
+        b = np.maximum.reduce(a)
+        assert_equal(b, 3)
+
+    def test_minmax_funcs_with_output(self):
+        # Tests the min/max functions with explicit outputs
+        mask = np.random.rand(12).round()
+        xm = array(np.random.uniform(0, 10, 12), mask=mask)
+        xm.shape = (3, 4)
+        for funcname in ('min', 'max'):
+            # Initialize
+            npfunc = getattr(np, funcname)
+            mafunc = getattr(numpy.ma.core, funcname)
+            # Use the np version
+            nout = np.empty((4,), dtype=int)
+            try:
+                result = npfunc(xm, axis=0, out=nout)
+            except MaskError:
+                pass
+            nout = np.empty((4,), dtype=float)
+            result = npfunc(xm, axis=0, out=nout)
+            self.assertTrue(result is nout)
+            # Use the ma version
+            nout.fill(-999)
+            result = mafunc(xm, axis=0, out=nout)
+            self.assertTrue(result is nout)
+
+    def test_minmax_methods(self):
+        # Additional tests on max/min
+        (_, _, _, _, _, xm, _, _, _, _) = self.d
+        xm.shape = (xm.size,)
+        assert_equal(xm.max(), 10)
+        self.assertTrue(xm[0].max() is masked)
+        self.assertTrue(xm[0].max(0) is masked)
+        self.assertTrue(xm[0].max(-1) is masked)
+        assert_equal(xm.min(), -10.)
+        self.assertTrue(xm[0].min() is masked)
+        self.assertTrue(xm[0].min(0) is masked)
+        self.assertTrue(xm[0].min(-1) is masked)
+        assert_equal(xm.ptp(), 20.)
+        self.assertTrue(xm[0].ptp() is masked)
+        self.assertTrue(xm[0].ptp(0) is masked)
+        self.assertTrue(xm[0].ptp(-1) is masked)
+
+        x = array([1, 2, 3], mask=True)
+        self.assertTrue(x.min() is masked)
+        self.assertTrue(x.max() is masked)
+        self.assertTrue(x.ptp() is masked)
+
+    def test_addsumprod(self):
+        # Tests add, sum, product.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(np.add.reduce(x), add.reduce(x))
+        assert_equal(np.add.accumulate(x), add.accumulate(x))
+        assert_equal(4, sum(array(4), axis=0))
+        assert_equal(4, sum(array(4), axis=0))
+        assert_equal(np.sum(x, axis=0), sum(x, axis=0))
+        assert_equal(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0))
+        assert_equal(np.sum(x, 0), sum(x, 0))
+        assert_equal(np.product(x, axis=0), product(x, axis=0))
+        assert_equal(np.product(x, 0), product(x, 0))
+        assert_equal(np.product(filled(xm, 1), axis=0), product(xm, axis=0))
+        s = (3, 4)
+        x.shape = y.shape = xm.shape = ym.shape = s
+        if len(s) > 1:
+            assert_equal(np.concatenate((x, y), 1), concatenate((xm, ym), 1))
+            assert_equal(np.add.reduce(x, 1), add.reduce(x, 1))
+            assert_equal(np.sum(x, 1), sum(x, 1))
+            assert_equal(np.product(x, 1), product(x, 1))
+
+    def test_binops_d2D(self):
+        # Test binary operations on 2D data
+        a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]])
+
+        test = a * b
+        control = array([[2., 3.], [2., 2.], [3., 3.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b * a
+        control = array([[2., 3.], [4., 5.], [6., 7.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        a = array([[1.], [2.], [3.]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]],
+                  mask=[[0, 0], [0, 0], [0, 1]])
+        test = a * b
+        control = array([[2, 3], [8, 10], [18, 3]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b * a
+        control = array([[2, 3], [8, 10], [18, 7]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_domained_binops_d2D(self):
+        # Test domained binary operations on 2D data
+        a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]])
+
+        test = a / b
+        control = array([[1. / 2., 1. / 3.], [2., 2.], [3., 3.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b / a
+        control = array([[2. / 1., 3. / 1.], [4., 5.], [6., 7.]],
+                        mask=[[0, 0], [1, 1], [1, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        a = array([[1.], [2.], [3.]])
+        b = array([[2., 3.], [4., 5.], [6., 7.]],
+                  mask=[[0, 0], [0, 0], [0, 1]])
+        test = a / b
+        control = array([[1. / 2, 1. / 3], [2. / 4, 2. / 5], [3. / 6, 3]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+        test = b / a
+        control = array([[2 / 1., 3 / 1.], [4 / 2., 5 / 2.], [6 / 3., 7]],
+                        mask=[[0, 0], [0, 0], [0, 1]])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_noshrinking(self):
+        # Check that we don't shrink a mask when not wanted
+        # Binary operations
+        a = masked_array([1., 2., 3.], mask=[False, False, False],
+                         shrink=False)
+        b = a + 1
+        assert_equal(b.mask, [0, 0, 0])
+        # In place binary operation
+        a += 1
+        assert_equal(a.mask, [0, 0, 0])
+        # Domained binary operation
+        b = a / 1.
+        assert_equal(b.mask, [0, 0, 0])
+        # In place binary operation
+        a /= 1.
+        assert_equal(a.mask, [0, 0, 0])
+
+    def test_noshink_on_creation(self):
+        # Check that the mask is not shrunk on array creation when not wanted
+        a = np.ma.masked_values([1., 2.5, 3.1], 1.5, shrink=False)
+        assert_equal(a.mask, [0, 0, 0])
+
+    def test_mod(self):
+        # Tests mod
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
+        assert_equal(mod(x, y), mod(xm, ym))
+        test = mod(ym, xm)
+        assert_equal(test, np.mod(ym, xm))
+        assert_equal(test.mask, mask_or(xm.mask, ym.mask))
+        test = mod(xm, ym)
+        assert_equal(test, np.mod(xm, ym))
+        assert_equal(test.mask, mask_or(mask_or(xm.mask, ym.mask), (ym == 0)))
+
+    def test_TakeTransposeInnerOuter(self):
+        # Test of take, transpose, inner, outer products
+        x = arange(24)
+        y = np.arange(24)
+        x[5:6] = masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert_equal(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1)))
+        assert_equal(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1))
+        assert_equal(np.inner(filled(x, 0), filled(y, 0)),
+                     inner(x, y))
+        assert_equal(np.outer(filled(x, 0), filled(y, 0)),
+                     outer(x, y))
+        y = array(['abc', 1, 'def', 2, 3], object)
+        y[2] = masked
+        t = take(y, [0, 3, 4])
+        assert_(t[0] == 'abc')
+        assert_(t[1] == 2)
+        assert_(t[2] == 3)
+
+    def test_imag_real(self):
+        # Check complex
+        xx = array([1 + 10j, 20 + 2j], mask=[1, 0])
+        assert_equal(xx.imag, [10, 2])
+        assert_equal(xx.imag.filled(), [1e+20, 2])
+        assert_equal(xx.imag.dtype, xx._data.imag.dtype)
+        assert_equal(xx.real, [1, 20])
+        assert_equal(xx.real.filled(), [1e+20, 20])
+        assert_equal(xx.real.dtype, xx._data.real.dtype)
+
+    def test_methods_with_output(self):
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        funclist = ('sum', 'prod', 'var', 'std', 'max', 'min', 'ptp', 'mean',)
+
+        for funcname in funclist:
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+            # A ndarray as explicit input
+            output = np.empty(4, dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0, out=output)
+            # ... the result should be the given output
+            assert_(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+
+            output = empty(4, dtype=int)
+            result = xmmeth(axis=0, out=output)
+            assert_(result is output)
+            assert_(output[0] is masked)
+
+    def test_eq_on_structured(self):
+        # Test the equality of structured arrays
+        ndtype = [('A', int), ('B', int)]
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
+        test = (a == a)
+        assert_equal(test, [True, True])
+        assert_equal(test.mask, [False, False])
+        b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        test = (a == b)
+        assert_equal(test, [False, True])
+        assert_equal(test.mask, [True, False])
+        b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = (a == b)
+        assert_equal(test, [True, False])
+        assert_equal(test.mask, [False, False])
+
+    def test_ne_on_structured(self):
+        # Test the equality of structured arrays
+        ndtype = [('A', int), ('B', int)]
+        a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype)
+        test = (a != a)
+        assert_equal(test, [False, False])
+        assert_equal(test.mask, [False, False])
+        b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype)
+        test = (a != b)
+        assert_equal(test, [True, False])
+        assert_equal(test.mask, [True, False])
+        b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype)
+        test = (a != b)
+        assert_equal(test, [False, True])
+        assert_equal(test.mask, [False, False])
+
+    def test_eq_w_None(self):
+        # Really, comparisons with None should not be done, but check them
+        # anyway. Note that pep8 will flag these tests.
+
+        # With partial mask
+        a = array([1, 2], mask=[0, 1])
+        assert_equal(a == None, False)
+        assert_equal(a.data == None, False)
+        assert_equal(a.mask == None, False)
+        assert_equal(a != None, True)
+        # With nomask
+        a = array([1, 2], mask=False)
+        assert_equal(a == None, False)
+        assert_equal(a != None, True)
+        # With complete mask
+        a = array([1, 2], mask=True)
+        assert_equal(a == None, False)
+        assert_equal(a != None, True)
+        # Fully masked, even comparison to None should return "masked"
+        a = masked
+        assert_equal(a == None, masked)
+
+    def test_eq_w_scalar(self):
+        a = array(1)
+        assert_equal(a == 1, True)
+        assert_equal(a == 0, False)
+        assert_equal(a != 1, False)
+        assert_equal(a != 0, True)
+
+    def test_numpyarithmetics(self):
+        # Check that the mask is not back-propagated when using numpy functions
+        a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
+        control = masked_array([np.nan, np.nan, 0, np.log(2), -1],
+                               mask=[1, 1, 0, 0, 1])
+
+        test = log(a)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(a.mask, [0, 0, 0, 0, 1])
+
+        test = np.log(a)
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        assert_equal(a.mask, [0, 0, 0, 0, 1])
+
+
+class TestMaskedArrayAttributes(TestCase):
+
+    def test_keepmask(self):
+        # Tests the keep mask flag
+        x = masked_array([1, 2, 3], mask=[1, 0, 0])
+        mx = masked_array(x)
+        assert_equal(mx.mask, x.mask)
+        mx = masked_array(x, mask=[0, 1, 0], keep_mask=False)
+        assert_equal(mx.mask, [0, 1, 0])
+        mx = masked_array(x, mask=[0, 1, 0], keep_mask=True)
+        assert_equal(mx.mask, [1, 1, 0])
+        # We default to true
+        mx = masked_array(x, mask=[0, 1, 0])
+        assert_equal(mx.mask, [1, 1, 0])
+
+    def test_hardmask(self):
+        # Test hard_mask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d, mask=m, hard_mask=True)
+        # We need to copy, to avoid updating d in xh !
+        xs = array(d, mask=m, hard_mask=False, copy=True)
+        xh[[1, 4]] = [10, 40]
+        xs[[1, 4]] = [10, 40]
+        assert_equal(xh._data, [0, 10, 2, 3, 4])
+        assert_equal(xs._data, [0, 10, 2, 3, 40])
+        assert_equal(xs.mask, [0, 0, 0, 1, 0])
+        self.assertTrue(xh._hardmask)
+        self.assertTrue(not xs._hardmask)
+        xh[1:4] = [10, 20, 30]
+        xs[1:4] = [10, 20, 30]
+        assert_equal(xh._data, [0, 10, 20, 3, 4])
+        assert_equal(xs._data, [0, 10, 20, 30, 40])
+        assert_equal(xs.mask, nomask)
+        xh[0] = masked
+        xs[0] = masked
+        assert_equal(xh.mask, [1, 0, 0, 1, 1])
+        assert_equal(xs.mask, [1, 0, 0, 0, 0])
+        xh[:] = 1
+        xs[:] = 1
+        assert_equal(xh._data, [0, 1, 1, 3, 4])
+        assert_equal(xs._data, [1, 1, 1, 1, 1])
+        assert_equal(xh.mask, [1, 0, 0, 1, 1])
+        assert_equal(xs.mask, nomask)
+        # Switch to soft mask
+        xh.soften_mask()
+        xh[:] = arange(5)
+        assert_equal(xh._data, [0, 1, 2, 3, 4])
+        assert_equal(xh.mask, nomask)
+        # Switch back to hard mask
+        xh.harden_mask()
+        xh[xh < 3] = masked
+        assert_equal(xh._data, [0, 1, 2, 3, 4])
+        assert_equal(xh._mask, [1, 1, 1, 0, 0])
+        xh[filled(xh > 1, False)] = 5
+        assert_equal(xh._data, [0, 1, 2, 5, 5])
+        assert_equal(xh._mask, [1, 1, 1, 0, 0])
+
+        xh = array([[1, 2], [3, 4]], mask=[[1, 0], [0, 0]], hard_mask=True)
+        xh[0] = 0
+        assert_equal(xh._data, [[1, 0], [3, 4]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+        xh[-1, -1] = 5
+        assert_equal(xh._data, [[1, 0], [3, 5]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+        xh[filled(xh < 5, False)] = 2
+        assert_equal(xh._data, [[1, 2], [2, 5]])
+        assert_equal(xh._mask, [[1, 0], [0, 0]])
+
+    def test_hardmask_again(self):
+        # Another test of hardmask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d, mask=m, hard_mask=True)
+        xh[4:5] = 999
+        xh[0:1] = 999
+        assert_equal(xh._data, [999, 1, 2, 3, 4])
+
+    def test_hardmask_oncemore_yay(self):
+        # OK, yet another test of hardmask
+        # Make sure that harden_mask/soften_mask//unshare_mask returns self
+        a = array([1, 2, 3], mask=[1, 0, 0])
+        b = a.harden_mask()
+        assert_equal(a, b)
+        b[0] = 0
+        assert_equal(a, b)
+        assert_equal(b, array([1, 2, 3], mask=[1, 0, 0]))
+        a = b.soften_mask()
+        a[0] = 0
+        assert_equal(a, b)
+        assert_equal(b, array([0, 2, 3], mask=[0, 0, 0]))
+
+    def test_smallmask(self):
+        # Checks the behaviour of _smallmask
+        a = arange(10)
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, nomask)
+        a = arange(10)
+        a._smallmask = False
+        a[1] = masked
+        a[1] = 1
+        assert_equal(a._mask, zeros(10))
+
+    def test_shrink_mask(self):
+        # Tests .shrink_mask()
+        a = array([1, 2, 3], mask=[0, 0, 0])
+        b = a.shrink_mask()
+        assert_equal(a, b)
+        assert_equal(a.mask, nomask)
+
+    def test_flat(self):
+        # Test that flat can return all types of items [#4585, #4615]
+        # test simple access
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        assert_equal(test.flat[1], 2)
+        assert_equal(test.flat[2], masked)
+        self.assertTrue(np.all(test.flat[0:2] == test[0, 0:2]))
+        # Test flat on masked_matrices
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        test.flat = masked_array([3, 2, 1], mask=[1, 0, 0])
+        control = masked_array(np.matrix([[3, 2, 1]]), mask=[1, 0, 0])
+        assert_equal(test, control)
+        # Test setting
+        test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1])
+        testflat = test.flat
+        testflat[:] = testflat[[2, 1, 0]]
+        assert_equal(test, control)
+        testflat[0] = 9
+        assert_equal(test[0, 0], 9)
+        # test 2-D record array
+        # ... on structured array w/ masked records
+        x = array([[(1, 1.1, 'one'), (2, 2.2, 'two'), (3, 3.3, 'thr')],
+                   [(4, 4.4, 'fou'), (5, 5.5, 'fiv'), (6, 6.6, 'six')]],
+                  dtype=[('a', int), ('b', float), ('c', '|S8')])
+        x['a'][0, 1] = masked
+        x['b'][1, 0] = masked
+        x['c'][0, 2] = masked
+        x[-1, -1] = masked
+        xflat = x.flat
+        assert_equal(xflat[0], x[0, 0])
+        assert_equal(xflat[1], x[0, 1])
+        assert_equal(xflat[2], x[0, 2])
+        assert_equal(xflat[:3], x[0])
+        assert_equal(xflat[3], x[1, 0])
+        assert_equal(xflat[4], x[1, 1])
+        assert_equal(xflat[5], x[1, 2])
+        assert_equal(xflat[3:], x[1])
+        assert_equal(xflat[-1], x[-1, -1])
+        i = 0
+        j = 0
+        for xf in xflat:
+            assert_equal(xf, x[j, i])
+            i += 1
+            if i >= x.shape[-1]:
+                i = 0
+                j += 1
+        # test that matrices keep the correct shape (#4615)
+        a = masked_array(np.matrix(np.eye(2)), mask=0)
+        b = a.flat
+        b01 = b[:2]
+        assert_equal(b01.data, array([[1., 0.]]))
+        assert_equal(b01.mask, array([[False, False]]))
+
+    def test_assign_dtype(self):
+        # check that the mask's dtype is updated when dtype is changed
+        a = np.zeros(4, dtype='f4,i4')
+
+        m = np.ma.array(a)
+        m.dtype = np.dtype('f4')
+        repr(m)  # raises?
+        assert_equal(m.dtype, np.dtype('f4'))
+
+        # check that dtype changes that change shape of mask too much
+        # are not allowed
+        def assign():
+            m = np.ma.array(a)
+            m.dtype = np.dtype('f8')
+        assert_raises(ValueError, assign)
+
+        b = a.view(dtype='f4', type=np.ma.MaskedArray)  # raises?
+        assert_equal(b.dtype, np.dtype('f4'))
+
+        # check that nomask is preserved
+        a = np.zeros(4, dtype='f4')
+        m = np.ma.array(a)
+        m.dtype = np.dtype('f4,i4')
+        assert_equal(m.dtype, np.dtype('f4,i4'))
+        assert_equal(m._mask, np.ma.nomask)
+
+
+class TestFillingValues(TestCase):
+
+    def test_check_on_scalar(self):
+        # Test _check_fill_value set to valid and invalid values
+        _check_fill_value = np.ma.core._check_fill_value
+
+        fval = _check_fill_value(0, int)
+        assert_equal(fval, 0)
+        fval = _check_fill_value(None, int)
+        assert_equal(fval, default_fill_value(0))
+
+        fval = _check_fill_value(0, "|S3")
+        assert_equal(fval, asbytes("0"))
+        fval = _check_fill_value(None, "|S3")
+        assert_equal(fval, default_fill_value(b"camelot!"))
+        self.assertRaises(TypeError, _check_fill_value, 1e+20, int)
+        self.assertRaises(TypeError, _check_fill_value, 'stuff', int)
+
+    def test_check_on_fields(self):
+        # Tests _check_fill_value with records
+        _check_fill_value = np.ma.core._check_fill_value
+        ndtype = [('a', int), ('b', float), ('c', "|S3")]
+        # A check on a list should return a single record
+        fval = _check_fill_value([-999, -12345678.9, "???"], ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        # A check on None should output the defaults
+        fval = _check_fill_value(None, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [default_fill_value(0),
+                                   default_fill_value(0.),
+                                   asbytes(default_fill_value("0"))])
+        #.....Using a structured type as fill_value should work
+        fill_val = np.array((-999, -12345678.9, "???"), dtype=ndtype)
+        fval = _check_fill_value(fill_val, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+
+        #.....Using a flexible type w/ a different type shouldn't matter
+        # BEHAVIOR in 1.5 and earlier: match structured types by position
+        #fill_val = np.array((-999, -12345678.9, "???"),
+        #                    dtype=[("A", int), ("B", float), ("C", "|S3")])
+        # BEHAVIOR in 1.6 and later: match structured types by name
+        fill_val = np.array(("???", -999, -12345678.9),
+                            dtype=[("c", "|S3"), ("a", int), ("b", float), ])
+        fval = _check_fill_value(fill_val, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+
+        #.....Using an object-array shouldn't matter either
+        fill_val = np.ndarray(shape=(1,), dtype=object)
+        fill_val[0] = (-999, -12345678.9, asbytes("???"))
+        fval = _check_fill_value(fill_val, object)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        # NOTE: This test was never run properly as "fill_value" rather than
+        # "fill_val" was assigned.  Written properly, it fails.
+        #fill_val = np.array((-999, -12345678.9, "???"))
+        #fval = _check_fill_value(fill_val, ndtype)
+        #self.assertTrue(isinstance(fval, ndarray))
+        #assert_equal(fval.item(), [-999, -12345678.9, asbytes("???")])
+        #.....One-field-only flexible type should work as well
+        ndtype = [("a", int)]
+        fval = _check_fill_value(-999999999, ndtype)
+        self.assertTrue(isinstance(fval, ndarray))
+        assert_equal(fval.item(), (-999999999,))
+
+    def test_fillvalue_conversion(self):
+        # Tests the behavior of fill_value during conversion
+        # We had a tailored comment to make sure special attributes are
+        # properly dealt with
+        a = array(asbytes_nested(['3', '4', '5']))
+        a._optinfo.update({'comment':"updated!"})
+
+        b = array(a, dtype=int)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0))
+
+        b = array(a, dtype=float)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0.))
+
+        b = a.astype(int)
+        assert_equal(b._data, [3, 4, 5])
+        assert_equal(b.fill_value, default_fill_value(0))
+        assert_equal(b._optinfo['comment'], "updated!")
+
+        b = a.astype([('a', '|S3')])
+        assert_equal(b['a']._data, a._data)
+        assert_equal(b['a'].fill_value, a.fill_value)
+
+    def test_fillvalue(self):
+        # Yet more fun with the fill_value
+        data = masked_array([1, 2, 3], fill_value=-999)
+        series = data[[0, 2, 1]]
+        assert_equal(series._fill_value, data._fill_value)
+
+        mtype = [('f', float), ('s', '|S3')]
+        x = array([(1, 'a'), (2, 'b'), (pi, 'pi')], dtype=mtype)
+        x.fill_value = 999
+        assert_equal(x.fill_value.item(), [999., asbytes('999')])
+        assert_equal(x['f'].fill_value, 999)
+        assert_equal(x['s'].fill_value, asbytes('999'))
+
+        x.fill_value = (9, '???')
+        assert_equal(x.fill_value.item(), (9, asbytes('???')))
+        assert_equal(x['f'].fill_value, 9)
+        assert_equal(x['s'].fill_value, asbytes('???'))
+
+        x = array([1, 2, 3.1])
+        x.fill_value = 999
+        assert_equal(np.asarray(x.fill_value).dtype, float)
+        assert_equal(x.fill_value, 999.)
+        assert_equal(x._fill_value, np.array(999.))
+
+    def test_fillvalue_exotic_dtype(self):
+        # Tests yet more exotic flexible dtypes
+        _check_fill_value = np.ma.core._check_fill_value
+        ndtype = [('i', int), ('s', '|S8'), ('f', float)]
+        control = np.array((default_fill_value(0),
+                            default_fill_value('0'),
+                            default_fill_value(0.),),
+                           dtype=ndtype)
+        assert_equal(_check_fill_value(None, ndtype), control)
+        # The shape shouldn't matter
+        ndtype = [('f0', float, (2, 2))]
+        control = np.array((default_fill_value(0.),),
+                           dtype=[('f0', float)]).astype(ndtype)
+        assert_equal(_check_fill_value(None, ndtype), control)
+        control = np.array((0,), dtype=[('f0', float)]).astype(ndtype)
+        assert_equal(_check_fill_value(0, ndtype), control)
+
+        ndtype = np.dtype("int, (2,3)float, float")
+        control = np.array((default_fill_value(0),
+                            default_fill_value(0.),
+                            default_fill_value(0.),),
+                           dtype="int, float, float").astype(ndtype)
+        test = _check_fill_value(None, ndtype)
+        assert_equal(test, control)
+        control = np.array((0, 0, 0), dtype="int, float, float").astype(ndtype)
+        assert_equal(_check_fill_value(0, ndtype), control)
+        # but when indexing, fill value should become scalar not tuple
+        # See issue #6723
+        M = masked_array(control)
+        assert_equal(M["f1"].fill_value.ndim, 0)
+
+    def test_fillvalue_datetime_timedelta(self):
+        # Test default fillvalue for datetime64 and timedelta64 types.
+        # See issue #4476, this would return '?' which would cause errors
+        # elsewhere
+
+        for timecode in ("as", "fs", "ps", "ns", "us", "ms", "s", "m",
+                         "h", "D", "W", "M", "Y"):
+            control = numpy.datetime64("NaT", timecode)
+            test = default_fill_value(numpy.dtype("<M8[" + timecode + "]"))
+            assert_equal(test, control)
+
+            control = numpy.timedelta64("NaT", timecode)
+            test = default_fill_value(numpy.dtype("<m8[" + timecode + "]"))
+            assert_equal(test, control)
+
+    def test_extremum_fill_value(self):
+        # Tests extremum fill values for flexible type.
+        a = array([(1, (2, 3)), (4, (5, 6))],
+                  dtype=[('A', int), ('B', [('BA', int), ('BB', int)])])
+        test = a.fill_value
+        assert_equal(test['A'], default_fill_value(a['A']))
+        assert_equal(test['B']['BA'], default_fill_value(a['B']['BA']))
+        assert_equal(test['B']['BB'], default_fill_value(a['B']['BB']))
+
+        test = minimum_fill_value(a)
+        assert_equal(test[0], minimum_fill_value(a['A']))
+        assert_equal(test[1][0], minimum_fill_value(a['B']['BA']))
+        assert_equal(test[1][1], minimum_fill_value(a['B']['BB']))
+        assert_equal(test[1], minimum_fill_value(a['B']))
+
+        test = maximum_fill_value(a)
+        assert_equal(test[0], maximum_fill_value(a['A']))
+        assert_equal(test[1][0], maximum_fill_value(a['B']['BA']))
+        assert_equal(test[1][1], maximum_fill_value(a['B']['BB']))
+        assert_equal(test[1], maximum_fill_value(a['B']))
+
+    def test_fillvalue_individual_fields(self):
+        # Test setting fill_value on individual fields
+        ndtype = [('a', int), ('b', int)]
+        # Explicit fill_value
+        a = array(list(zip([1, 2, 3], [4, 5, 6])),
+                  fill_value=(-999, -999), dtype=ndtype)
+        aa = a['a']
+        aa.set_fill_value(10)
+        assert_equal(aa._fill_value, np.array(10))
+        assert_equal(tuple(a.fill_value), (10, -999))
+        a.fill_value['b'] = -10
+        assert_equal(tuple(a.fill_value), (10, -10))
+        # Implicit fill_value
+        t = array(list(zip([1, 2, 3], [4, 5, 6])), dtype=ndtype)
+        tt = t['a']
+        tt.set_fill_value(10)
+        assert_equal(tt._fill_value, np.array(10))
+        assert_equal(tuple(t.fill_value), (10, default_fill_value(0)))
+
+    def test_fillvalue_implicit_structured_array(self):
+        # Check that fill_value is always defined for structured arrays
+        ndtype = ('b', float)
+        adtype = ('a', float)
+        a = array([(1.,), (2.,)], mask=[(False,), (False,)],
+                  fill_value=(np.nan,), dtype=np.dtype([adtype]))
+        b = empty(a.shape, dtype=[adtype, ndtype])
+        b['a'] = a['a']
+        b['a'].set_fill_value(a['a'].fill_value)
+        f = b._fill_value[()]
+        assert_(np.isnan(f[0]))
+        assert_equal(f[-1], default_fill_value(1.))
+
+    def test_fillvalue_as_arguments(self):
+        # Test adding a fill_value parameter to empty/ones/zeros
+        a = empty(3, fill_value=999.)
+        assert_equal(a.fill_value, 999.)
+
+        a = ones(3, fill_value=999., dtype=float)
+        assert_equal(a.fill_value, 999.)
+
+        a = zeros(3, fill_value=0., dtype=complex)
+        assert_equal(a.fill_value, 0.)
+
+        a = identity(3, fill_value=0., dtype=complex)
+        assert_equal(a.fill_value, 0.)
+
+    def test_shape_argument(self):
+        # Test that shape can be provides as an argument
+        # GH issue 6106
+        a = empty(shape=(3, ))
+        assert_equal(a.shape, (3, ))
+
+        a = ones(shape=(3, ), dtype=float)
+        assert_equal(a.shape, (3, ))
+
+        a = zeros(shape=(3, ), dtype=complex)
+        assert_equal(a.shape, (3, ))
+
+    def test_fillvalue_in_view(self):
+        # Test the behavior of fill_value in view
+
+        # Create initial masked array
+        x = array([1, 2, 3], fill_value=1, dtype=np.int64)
+
+        # Check that fill_value is preserved by default
+        y = x.view()
+        assert_(y.fill_value == 1)
+
+        # Check that fill_value is preserved if dtype is specified and the
+        # dtype is an ndarray sub-class and has a _fill_value attribute
+        y = x.view(MaskedArray)
+        assert_(y.fill_value == 1)
+
+        # Check that fill_value is preserved if type is specified and the
+        # dtype is an ndarray sub-class and has a _fill_value attribute (by
+        # default, the first argument is dtype, not type)
+        y = x.view(type=MaskedArray)
+        assert_(y.fill_value == 1)
+
+        # Check that code does not crash if passed an ndarray sub-class that
+        # does not have a _fill_value attribute
+        y = x.view(np.ndarray)
+        y = x.view(type=np.ndarray)
+
+        # Check that fill_value can be overriden with view
+        y = x.view(MaskedArray, fill_value=2)
+        assert_(y.fill_value == 2)
+
+        # Check that fill_value can be overriden with view (using type=)
+        y = x.view(type=MaskedArray, fill_value=2)
+        assert_(y.fill_value == 2)
+
+        # Check that fill_value gets reset if passed a dtype but not a
+        # fill_value. This is because even though in some cases one can safely
+        # cast the fill_value, e.g. if taking an int64 view of an int32 array,
+        # in other cases, this cannot be done (e.g. int32 view of an int64
+        # array with a large fill_value).
+        y = x.view(dtype=np.int32)
+        assert_(y.fill_value == 999999)
+
+
+class TestUfuncs(TestCase):
+    # Test class for the application of ufuncs on MaskedArrays.
+
+    def setUp(self):
+        # Base data definition.
+        self.d = (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6),
+                  array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),)
+        self.err_status = np.geterr()
+        np.seterr(divide='ignore', invalid='ignore')
+
+    def tearDown(self):
+        np.seterr(**self.err_status)
+
+    def test_testUfuncRegression(self):
+        # Tests new ufuncs on MaskedArrays.
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+                  'sin', 'cos', 'tan',
+                  'arcsin', 'arccos', 'arctan',
+                  'sinh', 'cosh', 'tanh',
+                  'arcsinh',
+                  'arccosh',
+                  'arctanh',
+                  'absolute', 'fabs', 'negative',
+                  'floor', 'ceil',
+                  'logical_not',
+                  'add', 'subtract', 'multiply',
+                  'divide', 'true_divide', 'floor_divide',
+                  'remainder', 'fmod', 'hypot', 'arctan2',
+                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+                  'less', 'greater',
+                  'logical_and', 'logical_or', 'logical_xor',
+                  ]:
+            try:
+                uf = getattr(umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(numpy.ma.core, f)
+            args = self.d[:uf.nin]
+            ur = uf(*args)
+            mr = mf(*args)
+            assert_equal(ur.filled(0), mr.filled(0), f)
+            assert_mask_equal(ur.mask, mr.mask, err_msg=f)
+
+    def test_reduce(self):
+        # Tests reduce on MaskedArrays.
+        a = self.d[0]
+        self.assertTrue(not alltrue(a, axis=0))
+        self.assertTrue(sometrue(a, axis=0))
+        assert_equal(sum(a[:3], axis=0), 0)
+        assert_equal(product(a, axis=0), 0)
+        assert_equal(add.reduce(a), pi)
+
+    def test_minmax(self):
+        # Tests extrema on MaskedArrays.
+        a = arange(1, 13).reshape(3, 4)
+        amask = masked_where(a < 5, a)
+        assert_equal(amask.max(), a.max())
+        assert_equal(amask.min(), 5)
+        assert_equal(amask.max(0), a.max(0))
+        assert_equal(amask.min(0), [5, 6, 7, 8])
+        self.assertTrue(amask.max(1)[0].mask)
+        self.assertTrue(amask.min(1)[0].mask)
+
+    def test_ndarray_mask(self):
+        # Check that the mask of the result is a ndarray (not a MaskedArray...)
+        a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1])
+        test = np.sqrt(a)
+        control = masked_array([-1, 0, 1, np.sqrt(2), -1],
+                               mask=[1, 0, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.mask, control.mask)
+        self.assertTrue(not isinstance(test.mask, MaskedArray))
+
+    def test_treatment_of_NotImplemented(self):
+        # Check that NotImplemented is returned at appropriate places
+
+        a = masked_array([1., 2.], mask=[1, 0])
+        self.assertRaises(TypeError, operator.mul, a, "abc")
+        self.assertRaises(TypeError, operator.truediv, a, "abc")
+
+        class MyClass(object):
+            __array_priority__ = a.__array_priority__ + 1
+
+            def __mul__(self, other):
+                return "My mul"
+
+            def __rmul__(self, other):
+                return "My rmul"
+
+        me = MyClass()
+        assert_(me * a == "My mul")
+        assert_(a * me == "My rmul")
+
+        # and that __array_priority__ is respected
+        class MyClass2(object):
+            __array_priority__ = 100
+
+            def __mul__(self, other):
+                return "Me2mul"
+
+            def __rmul__(self, other):
+                return "Me2rmul"
+
+            def __rdiv__(self, other):
+                return "Me2rdiv"
+
+            __rtruediv__ = __rdiv__
+
+        me_too = MyClass2()
+        assert_(a.__mul__(me_too) is NotImplemented)
+        assert_(all(multiply.outer(a, me_too) == "Me2rmul"))
+        assert_(a.__truediv__(me_too) is NotImplemented)
+        assert_(me_too * a == "Me2mul")
+        assert_(a * me_too == "Me2rmul")
+        assert_(a / me_too == "Me2rdiv")
+
+
+class TestMaskedArrayInPlaceArithmetics(TestCase):
+    # Test MaskedArray Arithmetics
+
+    def setUp(self):
+        x = arange(10)
+        y = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        self.intdata = (x, y, xm)
+        self.floatdata = (x.astype(float), y.astype(float), xm.astype(float))
+        self.othertypes = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
+        self.othertypes = [np.dtype(_).type for _ in self.othertypes]
+        self.uint8data = (
+            x.astype(np.uint8),
+            y.astype(np.uint8),
+            xm.astype(np.uint8)
+        )
+
+    def test_inplace_addition_scalar(self):
+        # Test of inplace additions
+        (x, y, xm) = self.intdata
+        xm[2] = masked
+        x += 1
+        assert_equal(x, y + 1)
+        xm += 1
+        assert_equal(xm, y + 1)
+
+        (x, _, xm) = self.floatdata
+        id1 = x.data.ctypes._data
+        x += 1.
+        assert_(id1 == x.data.ctypes._data)
+        assert_equal(x, y + 1.)
+
+    def test_inplace_addition_array(self):
+        # Test of inplace additions
+        (x, y, xm) = self.intdata
+        m = xm.mask
+        a = arange(10, dtype=np.int16)
+        a[-1] = masked
+        x += a
+        xm += a
+        assert_equal(x, y + a)
+        assert_equal(xm, y + a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_subtraction_scalar(self):
+        # Test of inplace subtractions
+        (x, y, xm) = self.intdata
+        x -= 1
+        assert_equal(x, y - 1)
+        xm -= 1
+        assert_equal(xm, y - 1)
+
+    def test_inplace_subtraction_array(self):
+        # Test of inplace subtractions
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x -= a
+        xm -= a
+        assert_equal(x, y - a)
+        assert_equal(xm, y - a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_multiplication_scalar(self):
+        # Test of inplace multiplication
+        (x, y, xm) = self.floatdata
+        x *= 2.0
+        assert_equal(x, y * 2)
+        xm *= 2.0
+        assert_equal(xm, y * 2)
+
+    def test_inplace_multiplication_array(self):
+        # Test of inplace multiplication
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x *= a
+        xm *= a
+        assert_equal(x, y * a)
+        assert_equal(xm, y * a)
+        assert_equal(xm.mask, mask_or(m, a.mask))
+
+    def test_inplace_division_scalar_int(self):
+        # Test of inplace division
+        (x, y, xm) = self.intdata
+        x = arange(10) * 2
+        xm = arange(10) * 2
+        xm[2] = masked
+        x //= 2
+        assert_equal(x, y)
+        xm //= 2
+        assert_equal(xm, y)
+
+    def test_inplace_division_scalar_float(self):
+        # Test of inplace division
+        (x, y, xm) = self.floatdata
+        x /= 2.0
+        assert_equal(x, y / 2.0)
+        xm /= arange(10)
+        assert_equal(xm, ones((10,)))
+
+    def test_inplace_division_array_float(self):
+        # Test of inplace division
+        (x, y, xm) = self.floatdata
+        m = xm.mask
+        a = arange(10, dtype=float)
+        a[-1] = masked
+        x /= a
+        xm /= a
+        assert_equal(x, y / a)
+        assert_equal(xm, y / a)
+        assert_equal(xm.mask, mask_or(mask_or(m, a.mask), (a == 0)))
+
+    def test_inplace_division_misc(self):
+
+        x = [1., 1., 1., -2., pi / 2., 4., 5., -10., 10., 1., 2., 3.]
+        y = [5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+
+        z = xm / ym
+        assert_equal(z._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
+        assert_equal(z._data,
+                     [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
+
+        xm = xm.copy()
+        xm /= ym
+        assert_equal(xm._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
+        assert_equal(z._data,
+                     [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.])
+
+    def test_datafriendly_add(self):
+        # Test keeping data w/ (inplace) addition
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        # Test add w/ scalar
+        xx = x + 1
+        assert_equal(xx.data, [2, 3, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test iadd w/ scalar
+        x += 1
+        assert_equal(x.data, [2, 3, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test add w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x + array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 4, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test iadd w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x += array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 4, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_sub(self):
+        # Test keeping data w/ (inplace) subtraction
+        # Test sub w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x - 1
+        assert_equal(xx.data, [0, 1, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test isub w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x -= 1
+        assert_equal(x.data, [0, 1, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test sub w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x - array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 0, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test isub w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x -= array([1, 2, 3], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 0, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_mul(self):
+        # Test keeping data w/ (inplace) multiplication
+        # Test mul w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x * 2
+        assert_equal(xx.data, [2, 4, 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test imul w/ scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x *= 2
+        assert_equal(x.data, [2, 4, 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test mul w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x * array([10, 20, 30], mask=[1, 0, 0])
+        assert_equal(xx.data, [1, 40, 3])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test imul w/ array
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        x *= array([10, 20, 30], mask=[1, 0, 0])
+        assert_equal(x.data, [1, 40, 3])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_div(self):
+        # Test keeping data w/ (inplace) division
+        # Test div on scalar
+        x = array([1, 2, 3], mask=[0, 0, 1])
+        xx = x / 2.
+        assert_equal(xx.data, [1 / 2., 2 / 2., 3])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test idiv on scalar
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        x /= 2.
+        assert_equal(x.data, [1 / 2., 2 / 2., 3])
+        assert_equal(x.mask, [0, 0, 1])
+        # Test div on array
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        xx = x / array([10., 20., 30.], mask=[1, 0, 0])
+        assert_equal(xx.data, [1., 2. / 20., 3.])
+        assert_equal(xx.mask, [1, 0, 1])
+        # Test idiv on array
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        x /= array([10., 20., 30.], mask=[1, 0, 0])
+        assert_equal(x.data, [1., 2 / 20., 3.])
+        assert_equal(x.mask, [1, 0, 1])
+
+    def test_datafriendly_pow(self):
+        # Test keeping data w/ (inplace) power
+        # Test pow on scalar
+        x = array([1., 2., 3.], mask=[0, 0, 1])
+        xx = x ** 2.5
+        assert_equal(xx.data, [1., 2. ** 2.5, 3.])
+        assert_equal(xx.mask, [0, 0, 1])
+        # Test ipow on scalar
+        x **= 2.5
+        assert_equal(x.data, [1., 2. ** 2.5, 3])
+        assert_equal(x.mask, [0, 0, 1])
+
+    def test_datafriendly_add_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a += b
+        assert_equal(a, [[2, 2], [4, 4]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a += b
+        assert_equal(a, [[2, 2], [4, 4]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_datafriendly_sub_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a -= b
+        assert_equal(a, [[0, 0], [2, 2]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a -= b
+        assert_equal(a, [[0, 0], [2, 2]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_datafriendly_mul_arrays(self):
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 0])
+        a *= b
+        assert_equal(a, [[1, 1], [3, 3]])
+        if a.mask is not nomask:
+            assert_equal(a.mask, [[0, 0], [0, 0]])
+
+        a = array([[1, 1], [3, 3]])
+        b = array([1, 1], mask=[0, 1])
+        a *= b
+        assert_equal(a, [[1, 1], [3, 3]])
+        assert_equal(a.mask, [[0, 1], [0, 1]])
+
+    def test_inplace_addition_scalar_type(self):
+        # Test of inplace additions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                xm[2] = masked
+                x += t(1)
+                assert_equal(x, y + t(1))
+                xm += t(1)
+                assert_equal(xm, y + t(1))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_addition_array_type(self):
+        # Test of inplace additions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x += a
+                xm += a
+                assert_equal(x, y + a)
+                assert_equal(xm, y + a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_subtraction_scalar_type(self):
+        # Test of inplace subtractions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x -= t(1)
+                assert_equal(x, y - t(1))
+                xm -= t(1)
+                assert_equal(xm, y - t(1))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_subtraction_array_type(self):
+        # Test of inplace subtractions
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x -= a
+                xm -= a
+                assert_equal(x, y - a)
+                assert_equal(xm, y - a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_multiplication_scalar_type(self):
+        # Test of inplace multiplication
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x *= t(2)
+                assert_equal(x, y * t(2))
+                xm *= t(2)
+                assert_equal(xm, y * t(2))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_multiplication_array_type(self):
+        # Test of inplace multiplication
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x *= a
+                xm *= a
+                assert_equal(x, y * a)
+                assert_equal(xm, y * a)
+                assert_equal(xm.mask, mask_or(m, a.mask))
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_floor_division_scalar_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x = arange(10, dtype=t) * t(2)
+                xm = arange(10, dtype=t) * t(2)
+                xm[2] = masked
+                x //= t(2)
+                xm //= t(2)
+                assert_equal(x, y)
+                assert_equal(xm, y)
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_floor_division_array_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+                x //= a
+                xm //= a
+                assert_equal(x, y // a)
+                assert_equal(xm, y // a)
+                assert_equal(
+                    xm.mask,
+                    mask_or(mask_or(m, a.mask), (a == t(0)))
+                )
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_division_scalar_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                x = arange(10, dtype=t) * t(2)
+                xm = arange(10, dtype=t) * t(2)
+                xm[2] = masked
+
+                # May get a DeprecationWarning or a TypeError.
+                #
+                # This is a consequence of the fact that this is true divide
+                # and will require casting to float for calculation and
+                # casting back to the original type. This will only be raised
+                # with integers. Whether it is an error or warning is only
+                # dependent on how stringent the casting rules are.
+                #
+                # Will handle the same way.
+                try:
+                    x /= t(2)
+                    assert_equal(x, y)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+                try:
+                    xm /= t(2)
+                    assert_equal(xm, y)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+
+                if issubclass(t, np.integer):
+                    assert_equal(len(w), 2, "Failed on type=%s." % t)
+                else:
+                    assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_division_array_type(self):
+        # Test of inplace division
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                (x, y, xm) = (_.astype(t) for _ in self.uint8data)
+                m = xm.mask
+                a = arange(10, dtype=t)
+                a[-1] = masked
+
+                # May get a DeprecationWarning or a TypeError.
+                #
+                # This is a consequence of the fact that this is true divide
+                # and will require casting to float for calculation and
+                # casting back to the original type. This will only be raised
+                # with integers. Whether it is an error or warning is only
+                # dependent on how stringent the casting rules are.
+                #
+                # Will handle the same way.
+                try:
+                    x /= a
+                    assert_equal(x, y / a)
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+                try:
+                    xm /= a
+                    assert_equal(xm, y / a)
+                    assert_equal(
+                        xm.mask,
+                        mask_or(mask_or(m, a.mask), (a == t(0)))
+                    )
+                except (DeprecationWarning, TypeError) as e:
+                    warnings.warn(str(e))
+
+                if issubclass(t, np.integer):
+                    assert_equal(len(w), 2, "Failed on type=%s." % t)
+                else:
+                    assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+    def test_inplace_pow_type(self):
+        # Test keeping data w/ (inplace) power
+        for t in self.othertypes:
+            with warnings.catch_warnings(record=True) as w:
+                warnings.filterwarnings("always")
+                # Test pow on scalar
+                x = array([1, 2, 3], mask=[0, 0, 1], dtype=t)
+                xx = x ** t(2)
+                xx_r = array([1, 2 ** 2, 3], mask=[0, 0, 1], dtype=t)
+                assert_equal(xx.data, xx_r.data)
+                assert_equal(xx.mask, xx_r.mask)
+                # Test ipow on scalar
+                x **= t(2)
+                assert_equal(x.data, xx_r.data)
+                assert_equal(x.mask, xx_r.mask)
+
+                assert_equal(len(w), 0, "Failed on type=%s." % t)
+
+
+class TestMaskedArrayMethods(TestCase):
+    # Test class for miscellaneous MaskedArrays methods.
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_generic_methods(self):
+        # Tests some MaskedArray methods.
+        a = array([1, 3, 2])
+        assert_equal(a.any(), a._data.any())
+        assert_equal(a.all(), a._data.all())
+        assert_equal(a.argmax(), a._data.argmax())
+        assert_equal(a.argmin(), a._data.argmin())
+        assert_equal(a.choose(0, 1, 2, 3, 4), a._data.choose(0, 1, 2, 3, 4))
+        assert_equal(a.compress([1, 0, 1]), a._data.compress([1, 0, 1]))
+        assert_equal(a.conj(), a._data.conj())
+        assert_equal(a.conjugate(), a._data.conjugate())
+
+        m = array([[1, 2], [3, 4]])
+        assert_equal(m.diagonal(), m._data.diagonal())
+        assert_equal(a.sum(), a._data.sum())
+        assert_equal(a.take([1, 2]), a._data.take([1, 2]))
+        assert_equal(m.transpose(), m._data.transpose())
+
+    def test_allclose(self):
+        # Tests allclose on arrays
+        a = np.random.rand(10)
+        b = a + np.random.rand(10) * 1e-8
+        self.assertTrue(allclose(a, b))
+        # Test allclose w/ infs
+        a[0] = np.inf
+        self.assertTrue(not allclose(a, b))
+        b[0] = np.inf
+        self.assertTrue(allclose(a, b))
+        # Test allclose w/ masked
+        a = masked_array(a)
+        a[-1] = masked
+        self.assertTrue(allclose(a, b, masked_equal=True))
+        self.assertTrue(not allclose(a, b, masked_equal=False))
+        # Test comparison w/ scalar
+        a *= 1e-8
+        a[0] = 0
+        self.assertTrue(allclose(a, 0, masked_equal=True))
+
+        # Test that the function works for MIN_INT integer typed arrays
+        a = masked_array([np.iinfo(np.int_).min], dtype=np.int_)
+        self.assertTrue(allclose(a, a))
+
+    def test_allany(self):
+        # Checks the any/all methods/functions.
+        x = np.array([[0.13, 0.26, 0.90],
+                      [0.28, 0.33, 0.63],
+                      [0.31, 0.87, 0.70]])
+        m = np.array([[True, False, False],
+                      [False, False, False],
+                      [True, True, False]], dtype=np.bool_)
+        mx = masked_array(x, mask=m)
+        mxbig = (mx > 0.5)
+        mxsmall = (mx < 0.5)
+
+        self.assertFalse(mxbig.all())
+        self.assertTrue(mxbig.any())
+        assert_equal(mxbig.all(0), [False, False, True])
+        assert_equal(mxbig.all(1), [False, False, True])
+        assert_equal(mxbig.any(0), [False, False, True])
+        assert_equal(mxbig.any(1), [True, True, True])
+
+        self.assertFalse(mxsmall.all())
+        self.assertTrue(mxsmall.any())
+        assert_equal(mxsmall.all(0), [True, True, False])
+        assert_equal(mxsmall.all(1), [False, False, False])
+        assert_equal(mxsmall.any(0), [True, True, False])
+        assert_equal(mxsmall.any(1), [True, True, False])
+
+    def test_allany_onmatrices(self):
+        x = np.array([[0.13, 0.26, 0.90],
+                      [0.28, 0.33, 0.63],
+                      [0.31, 0.87, 0.70]])
+        X = np.matrix(x)
+        m = np.array([[True, False, False],
+                      [False, False, False],
+                      [True, True, False]], dtype=np.bool_)
+        mX = masked_array(X, mask=m)
+        mXbig = (mX > 0.5)
+        mXsmall = (mX < 0.5)
+
+        self.assertFalse(mXbig.all())
+        self.assertTrue(mXbig.any())
+        assert_equal(mXbig.all(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.all(1), np.matrix([False, False, True]).T)
+        assert_equal(mXbig.any(0), np.matrix([False, False, True]))
+        assert_equal(mXbig.any(1), np.matrix([True, True, True]).T)
+
+        self.assertFalse(mXsmall.all())
+        self.assertTrue(mXsmall.any())
+        assert_equal(mXsmall.all(0), np.matrix([True, True, False]))
+        assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T)
+        assert_equal(mXsmall.any(0), np.matrix([True, True, False]))
+        assert_equal(mXsmall.any(1), np.matrix([True, True, False]).T)
+
+    def test_allany_oddities(self):
+        # Some fun with all and any
+        store = empty((), dtype=bool)
+        full = array([1, 2, 3], mask=True)
+
+        self.assertTrue(full.all() is masked)
+        full.all(out=store)
+        self.assertTrue(store)
+        self.assertTrue(store._mask, True)
+        self.assertTrue(store is not masked)
+
+        store = empty((), dtype=bool)
+        self.assertTrue(full.any() is masked)
+        full.any(out=store)
+        self.assertTrue(not store)
+        self.assertTrue(store._mask, True)
+        self.assertTrue(store is not masked)
+
+    def test_argmax_argmin(self):
+        # Tests argmin & argmax on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+
+        assert_equal(mx.argmin(), 35)
+        assert_equal(mX.argmin(), 35)
+        assert_equal(m2x.argmin(), 4)
+        assert_equal(m2X.argmin(), 4)
+        assert_equal(mx.argmax(), 28)
+        assert_equal(mX.argmax(), 28)
+        assert_equal(m2x.argmax(), 31)
+        assert_equal(m2X.argmax(), 31)
+
+        assert_equal(mX.argmin(0), [2, 2, 2, 5, 0, 5])
+        assert_equal(m2X.argmin(0), [2, 2, 4, 5, 0, 4])
+        assert_equal(mX.argmax(0), [0, 5, 0, 5, 4, 0])
+        assert_equal(m2X.argmax(0), [5, 5, 0, 5, 1, 0])
+
+        assert_equal(mX.argmin(1), [4, 1, 0, 0, 5, 5, ])
+        assert_equal(m2X.argmin(1), [4, 4, 0, 0, 5, 3])
+        assert_equal(mX.argmax(1), [2, 4, 1, 1, 4, 1])
+        assert_equal(m2X.argmax(1), [2, 4, 1, 1, 1, 1])
+
+    def test_clip(self):
+        # Tests clip on MaskedArrays.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0])
+        mx = array(x, mask=m)
+        clipped = mx.clip(2, 8)
+        assert_equal(clipped.mask, mx.mask)
+        assert_equal(clipped._data, x.clip(2, 8))
+        assert_equal(clipped._data, mx._data.clip(2, 8))
+
+    def test_compress(self):
+        # test compress
+        a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
+        condition = (a > 1.5) & (a < 3.5)
+        assert_equal(a.compress(condition), [2., 3.])
+
+        a[[2, 3]] = masked
+        b = a.compress(condition)
+        assert_equal(b._data, [2., 3.])
+        assert_equal(b._mask, [0, 1])
+        assert_equal(b.fill_value, 9999)
+        assert_equal(b, a[condition])
+
+        condition = (a < 4.)
+        b = a.compress(condition)
+        assert_equal(b._data, [1., 2., 3.])
+        assert_equal(b._mask, [0, 0, 1])
+        assert_equal(b.fill_value, 9999)
+        assert_equal(b, a[condition])
+
+        a = masked_array([[10, 20, 30], [40, 50, 60]],
+                         mask=[[0, 0, 1], [1, 0, 0]])
+        b = a.compress(a.ravel() >= 22)
+        assert_equal(b._data, [30, 40, 50, 60])
+        assert_equal(b._mask, [1, 1, 0, 0])
+
+        x = np.array([3, 1, 2])
+        b = a.compress(x >= 2, axis=1)
+        assert_equal(b._data, [[10, 30], [40, 60]])
+        assert_equal(b._mask, [[0, 1], [1, 0]])
+
+    def test_compressed(self):
+        # Tests compressed
+        a = array([1, 2, 3, 4], mask=[0, 0, 0, 0])
+        b = a.compressed()
+        assert_equal(b, a)
+        a[0] = masked
+        b = a.compressed()
+        assert_equal(b, [2, 3, 4])
+
+        a = array(np.matrix([1, 2, 3, 4]), mask=[0, 0, 0, 0])
+        b = a.compressed()
+        assert_equal(b, a)
+        self.assertTrue(isinstance(b, np.matrix))
+        a[0, 0] = masked
+        b = a.compressed()
+        assert_equal(b, [[2, 3, 4]])
+
+    def test_empty(self):
+        # Tests empty/like
+        datatype = [('a', int), ('b', float), ('c', '|S8')]
+        a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')],
+                         dtype=datatype)
+        assert_equal(len(a.fill_value.item()), len(datatype))
+
+        b = empty_like(a)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+
+        b = empty(len(a), dtype=datatype)
+        assert_equal(b.shape, a.shape)
+        assert_equal(b.fill_value, a.fill_value)
+
+        # check empty_like mask handling
+        a = masked_array([1, 2, 3], mask=[False, True, False])
+        b = empty_like(a)
+        assert_(not np.may_share_memory(a.mask, b.mask))
+        b = a.view(masked_array)
+        assert_(np.may_share_memory(a.mask, b.mask))
+
+    def test_put(self):
+        # Tests put.
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        x = array(d, mask=m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+        x[[1, 4]] = [10, 40]
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is not masked)
+        assert_equal(x, [0, 10, 2, -1, 40])
+
+        x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
+        i = [0, 2, 4, 6]
+        x.put(i, [6, 4, 2, 0])
+        assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
+        assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
+        x.put(i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
+        assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
+        assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
+
+        x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2)
+        put(x, i, [6, 4, 2, 0])
+        assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ]))
+        assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
+        put(x, i, masked_array([0, 2, 4, 6], [1, 0, 1, 0]))
+        assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ])
+        assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
+
+    def test_put_nomask(self):
+        # GitHub issue 6425
+        x = zeros(10)
+        z = array([3., -1.], mask=[False, True])
+
+        x.put([1, 2], z)
+        self.assertTrue(x[0] is not masked)
+        assert_equal(x[0], 0)
+        self.assertTrue(x[1] is not masked)
+        assert_equal(x[1], 3)
+        self.assertTrue(x[2] is masked)
+        self.assertTrue(x[3] is not masked)
+        assert_equal(x[3], 0)
+
+    def test_put_hardmask(self):
+        # Tests put on hardmask
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        xh = array(d + 1, mask=m, hard_mask=True, copy=True)
+        xh.put([4, 2, 0, 1, 3], [1, 2, 3, 4, 5])
+        assert_equal(xh._data, [3, 4, 2, 4, 5])
+
+    def test_putmask(self):
+        x = arange(6) + 1
+        mx = array(x, mask=[0, 0, 0, 1, 1, 1])
+        mask = [0, 0, 1, 0, 0, 1]
+        # w/o mask, w/o masked values
+        xx = x.copy()
+        putmask(xx, mask, 99)
+        assert_equal(xx, [1, 2, 99, 4, 5, 99])
+        # w/ mask, w/o masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, 99)
+        assert_equal(mxx._data, [1, 2, 99, 4, 5, 99])
+        assert_equal(mxx._mask, [0, 0, 0, 1, 1, 0])
+        # w/o mask, w/ masked values
+        values = array([10, 20, 30, 40, 50, 60], mask=[1, 1, 1, 0, 0, 0])
+        xx = x.copy()
+        putmask(xx, mask, values)
+        assert_equal(xx._data, [1, 2, 30, 4, 5, 60])
+        assert_equal(xx._mask, [0, 0, 1, 0, 0, 0])
+        # w/ mask, w/ masked values
+        mxx = mx.copy()
+        putmask(mxx, mask, values)
+        assert_equal(mxx._data, [1, 2, 30, 4, 5, 60])
+        assert_equal(mxx._mask, [0, 0, 1, 1, 1, 0])
+        # w/ mask, w/ masked values + hardmask
+        mxx = mx.copy()
+        mxx.harden_mask()
+        putmask(mxx, mask, values)
+        assert_equal(mxx, [1, 2, 30, 4, 5, 60])
+
+    def test_ravel(self):
+        # Tests ravel
+        a = array([[1, 2, 3, 4, 5]], mask=[[0, 1, 0, 0, 0]])
+        aravel = a.ravel()
+        assert_equal(aravel._mask.shape, aravel.shape)
+        a = array([0, 0], mask=[1, 1])
+        aravel = a.ravel()
+        assert_equal(aravel._mask.shape, a.shape)
+        a = array(np.matrix([1, 2, 3, 4, 5]), mask=[[0, 1, 0, 0, 0]])
+        aravel = a.ravel()
+        assert_equal(aravel.shape, (1, 5))
+        assert_equal(aravel._mask.shape, a.shape)
+        # Checks that small_mask is preserved
+        a = array([1, 2, 3, 4], mask=[0, 0, 0, 0], shrink=False)
+        assert_equal(a.ravel()._mask, [0, 0, 0, 0])
+        # Test that the fill_value is preserved
+        a.fill_value = -99
+        a.shape = (2, 2)
+        ar = a.ravel()
+        assert_equal(ar._mask, [0, 0, 0, 0])
+        assert_equal(ar._data, [1, 2, 3, 4])
+        assert_equal(ar.fill_value, -99)
+        # Test index ordering
+        assert_equal(a.ravel(order='C'), [1, 2, 3, 4])
+        assert_equal(a.ravel(order='F'), [1, 3, 2, 4])
+
+    def test_reshape(self):
+        # Tests reshape
+        x = arange(4)
+        x[0] = masked
+        y = x.reshape(2, 2)
+        assert_equal(y.shape, (2, 2,))
+        assert_equal(y._mask.shape, (2, 2,))
+        assert_equal(x.shape, (4,))
+        assert_equal(x._mask.shape, (4,))
+
+    def test_sort(self):
+        # Test sort
+        x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
+
+        sortedx = sort(x)
+        assert_equal(sortedx._data, [1, 2, 3, 4])
+        assert_equal(sortedx._mask, [0, 0, 0, 1])
+
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [4, 1, 2, 3])
+        assert_equal(sortedx._mask, [1, 0, 0, 0])
+
+        x.sort()
+        assert_equal(x._data, [1, 2, 3, 4])
+        assert_equal(x._mask, [0, 0, 0, 1])
+
+        x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8)
+        x.sort(endwith=False)
+        assert_equal(x._data, [4, 1, 2, 3])
+        assert_equal(x._mask, [1, 0, 0, 0])
+
+        x = [1, 4, 2, 3]
+        sortedx = sort(x)
+        self.assertTrue(not isinstance(sorted, MaskedArray))
+
+        x = array([0, 1, -1, -2, 2], mask=nomask, dtype=np.int8)
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [-2, -1, 0, 1, 2])
+        x = array([0, 1, -1, -2, 2], mask=[0, 1, 0, 0, 1], dtype=np.int8)
+        sortedx = sort(x, endwith=False)
+        assert_equal(sortedx._data, [1, 2, -2, -1, 0])
+        assert_equal(sortedx._mask, [1, 1, 0, 0, 0])
+
+    def test_sort_2d(self):
+        # Check sort of 2D array.
+        # 2D array w/o mask
+        a = masked_array([[8, 4, 1], [2, 0, 9]])
+        a.sort(0)
+        assert_equal(a, [[2, 0, 1], [8, 4, 9]])
+        a = masked_array([[8, 4, 1], [2, 0, 9]])
+        a.sort(1)
+        assert_equal(a, [[1, 4, 8], [0, 2, 9]])
+        # 2D array w/mask
+        a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
+        a.sort(0)
+        assert_equal(a, [[2, 0, 1], [8, 4, 9]])
+        assert_equal(a._mask, [[0, 0, 0], [1, 0, 1]])
+        a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]])
+        a.sort(1)
+        assert_equal(a, [[1, 4, 8], [0, 2, 9]])
+        assert_equal(a._mask, [[0, 0, 1], [0, 0, 1]])
+        # 3D
+        a = masked_array([[[7, 8, 9], [4, 5, 6], [1, 2, 3]],
+                          [[1, 2, 3], [7, 8, 9], [4, 5, 6]],
+                          [[7, 8, 9], [1, 2, 3], [4, 5, 6]],
+                          [[4, 5, 6], [1, 2, 3], [7, 8, 9]]])
+        a[a % 4 == 0] = masked
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(0)
+        an.sort(0)
+        assert_equal(am, an)
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(1)
+        an.sort(1)
+        assert_equal(am, an)
+        am = a.copy()
+        an = a.filled(99)
+        am.sort(2)
+        an.sort(2)
+        assert_equal(am, an)
+
+    def test_sort_flexible(self):
+        # Test sort on flexible dtype.
+        a = array(
+            data=[(3, 3), (3, 2), (2, 2), (2, 1), (1, 0), (1, 1), (1, 2)],
+            mask=[(0, 0), (0, 1), (0, 0), (0, 0), (1, 0), (0, 0), (0, 0)],
+            dtype=[('A', int), ('B', int)])
+
+        test = sort(a)
+        b = array(
+            data=[(1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (3, 2), (1, 0)],
+            mask=[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (1, 0)],
+            dtype=[('A', int), ('B', int)])
+        assert_equal(test, b)
+        assert_equal(test.mask, b.mask)
+
+        test = sort(a, endwith=False)
+        b = array(
+            data=[(1, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 2), (3, 3), ],
+            mask=[(1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (0, 0), ],
+            dtype=[('A', int), ('B', int)])
+        assert_equal(test, b)
+        assert_equal(test.mask, b.mask)
+
+    def test_argsort(self):
+        # Test argsort
+        a = array([1, 5, 2, 4, 3], mask=[1, 0, 0, 1, 0])
+        assert_equal(np.argsort(a), argsort(a))
+
+    def test_squeeze(self):
+        # Check squeeze
+        data = masked_array([[1, 2, 3]])
+        assert_equal(data.squeeze(), [1, 2, 3])
+        data = masked_array([[1, 2, 3]], mask=[[1, 1, 1]])
+        assert_equal(data.squeeze(), [1, 2, 3])
+        assert_equal(data.squeeze()._mask, [1, 1, 1])
+        data = masked_array([[1]], mask=True)
+        self.assertTrue(data.squeeze() is masked)
+
+    def test_swapaxes(self):
+        # Tests swapaxes on MaskedArrays.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        m = np.array([0, 1, 0, 1, 0, 0,
+                      1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0,
+                      0, 0, 1, 0, 1, 0])
+        mX = array(x, mask=m).reshape(6, 6)
+        mXX = mX.reshape(3, 2, 2, 3)
+
+        mXswapped = mX.swapaxes(0, 1)
+        assert_equal(mXswapped[-1], mX[:, -1])
+
+        mXXswapped = mXX.swapaxes(0, 2)
+        assert_equal(mXXswapped.shape, (2, 2, 3, 3))
+
+    def test_take(self):
+        # Tests take
+        x = masked_array([10, 20, 30, 40], [0, 1, 0, 1])
+        assert_equal(x.take([0, 0, 3]), masked_array([10, 10, 40], [0, 0, 1]))
+        assert_equal(x.take([0, 0, 3]), x[[0, 0, 3]])
+        assert_equal(x.take([[0, 1], [0, 1]]),
+                     masked_array([[10, 20], [10, 20]], [[0, 1], [0, 1]]))
+
+        x = array([[10, 20, 30], [40, 50, 60]], mask=[[0, 0, 1], [1, 0, 0, ]])
+        assert_equal(x.take([0, 2], axis=1),
+                     array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
+        assert_equal(take(x, [0, 2], axis=1),
+                     array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]]))
+
+    def test_take_masked_indices(self):
+        # Test take w/ masked indices
+        a = np.array((40, 18, 37, 9, 22))
+        indices = np.arange(3)[None,:] + np.arange(5)[:, None]
+        mindices = array(indices, mask=(indices >= len(a)))
+        # No mask
+        test = take(a, mindices, mode='clip')
+        ctrl = array([[40, 18, 37],
+                      [18, 37, 9],
+                      [37, 9, 22],
+                      [9, 22, 22],
+                      [22, 22, 22]])
+        assert_equal(test, ctrl)
+        # Masked indices
+        test = take(a, mindices)
+        ctrl = array([[40, 18, 37],
+                      [18, 37, 9],
+                      [37, 9, 22],
+                      [9, 22, 40],
+                      [22, 40, 40]])
+        ctrl[3, 2] = ctrl[4, 1] = ctrl[4, 2] = masked
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        # Masked input + masked indices
+        a = array((40, 18, 37, 9, 22), mask=(0, 1, 0, 0, 0))
+        test = take(a, mindices)
+        ctrl[0, 1] = ctrl[1, 0] = masked
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+
+    def test_tolist(self):
+        # Tests to list
+        # ... on 1D
+        x = array(np.arange(12))
+        x[[1, -2]] = masked
+        xlist = x.tolist()
+        self.assertTrue(xlist[1] is None)
+        self.assertTrue(xlist[-2] is None)
+        # ... on 2D
+        x.shape = (3, 4)
+        xlist = x.tolist()
+        ctrl = [[0, None, 2, 3], [4, 5, 6, 7], [8, 9, None, 11]]
+        assert_equal(xlist[0], [0, None, 2, 3])
+        assert_equal(xlist[1], [4, 5, 6, 7])
+        assert_equal(xlist[2], [8, 9, None, 11])
+        assert_equal(xlist, ctrl)
+        # ... on structured array w/ masked records
+        x = array(list(zip([1, 2, 3],
+                           [1.1, 2.2, 3.3],
+                           ['one', 'two', 'thr'])),
+                  dtype=[('a', int), ('b', float), ('c', '|S8')])
+        x[-1] = masked
+        assert_equal(x.tolist(),
+                     [(1, 1.1, asbytes('one')),
+                      (2, 2.2, asbytes('two')),
+                      (None, None, None)])
+        # ... on structured array w/ masked fields
+        a = array([(1, 2,), (3, 4)], mask=[(0, 1), (0, 0)],
+                  dtype=[('a', int), ('b', int)])
+        test = a.tolist()
+        assert_equal(test, [[1, None], [3, 4]])
+        # ... on mvoid
+        a = a[0]
+        test = a.tolist()
+        assert_equal(test, [1, None])
+
+    def test_tolist_specialcase(self):
+        # Test mvoid.tolist: make sure we return a standard Python object
+        a = array([(0, 1), (2, 3)], dtype=[('a', int), ('b', int)])
+        # w/o mask: each entry is a np.void whose elements are standard Python
+        for entry in a:
+            for item in entry.tolist():
+                assert_(not isinstance(item, np.generic))
+        # w/ mask: each entry is a ma.void whose elements should be
+        # standard Python
+        a.mask[0] = (0, 1)
+        for entry in a:
+            for item in entry.tolist():
+                assert_(not isinstance(item, np.generic))
+
+    def test_toflex(self):
+        # Test the conversion to records
+        data = arange(10)
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        ndtype = [('i', int), ('s', '|S3'), ('f', float)]
+        data = array([(i, s, f) for (i, s, f) in zip(np.arange(10),
+                                                     'ABCDEFGHIJKLM',
+                                                     np.random.rand(10))],
+                     dtype=ndtype)
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal(record['_data'], data._data)
+        assert_equal(record['_mask'], data._mask)
+
+        ndtype = np.dtype("int, (2,3)float, float")
+        data = array([(i, f, ff) for (i, f, ff) in zip(np.arange(10),
+                                                       np.random.rand(10),
+                                                       np.random.rand(10))],
+                     dtype=ndtype)
+        data[[0, 1, 2, -1]] = masked
+        record = data.toflex()
+        assert_equal_records(record['_data'], data._data)
+        assert_equal_records(record['_mask'], data._mask)
+
+    def test_fromflex(self):
+        # Test the reconstruction of a masked_array from a record
+        a = array([1, 2, 3])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.mask, a.mask)
+
+        a = array([1, 2, 3], mask=[0, 0, 1])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.mask, a.mask)
+
+        a = array([(1, 1.), (2, 2.), (3, 3.)], mask=[(1, 0), (0, 0), (0, 1)],
+                  dtype=[('A', int), ('B', float)])
+        test = fromflex(a.toflex())
+        assert_equal(test, a)
+        assert_equal(test.data, a.data)
+
+    def test_arraymethod(self):
+        # Test a _arraymethod w/ n argument
+        marray = masked_array([[1, 2, 3, 4, 5]], mask=[0, 0, 1, 0, 0])
+        control = masked_array([[1], [2], [3], [4], [5]],
+                               mask=[0, 0, 1, 0, 0])
+        assert_equal(marray.T, control)
+        assert_equal(marray.transpose(), control)
+
+        assert_equal(MaskedArray.cumsum(marray.T, 0), control.cumsum(0))
+
+
+class TestMaskedArrayMathMethods(TestCase):
+
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_cumsumprod(self):
+        # Tests cumsum & cumprod on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        mXcp = mX.cumsum(0)
+        assert_equal(mXcp._data, mX.filled(0).cumsum(0))
+        mXcp = mX.cumsum(1)
+        assert_equal(mXcp._data, mX.filled(0).cumsum(1))
+
+        mXcp = mX.cumprod(0)
+        assert_equal(mXcp._data, mX.filled(1).cumprod(0))
+        mXcp = mX.cumprod(1)
+        assert_equal(mXcp._data, mX.filled(1).cumprod(1))
+
+    def test_cumsumprod_with_output(self):
+        # Tests cumsum/cumprod w/ output
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        for funcname in ('cumsum', 'cumprod'):
+            npfunc = getattr(np, funcname)
+            xmmeth = getattr(xm, funcname)
+
+            # A ndarray as explicit input
+            output = np.empty((3, 4), dtype=float)
+            output.fill(-9999)
+            result = npfunc(xm, axis=0, out=output)
+            # ... the result should be the given output
+            self.assertTrue(result is output)
+            assert_equal(result, xmmeth(axis=0, out=output))
+
+            output = empty((3, 4), dtype=int)
+            result = xmmeth(axis=0, out=output)
+            self.assertTrue(result is output)
+
+    def test_ptp(self):
+        # Tests ptp on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        (n, m) = X.shape
+        assert_equal(mx.ptp(), mx.compressed().ptp())
+        rows = np.zeros(n, np.float)
+        cols = np.zeros(m, np.float)
+        for k in range(m):
+            cols[k] = mX[:, k].compressed().ptp()
+        for k in range(n):
+            rows[k] = mX[k].compressed().ptp()
+        assert_equal(mX.ptp(0), cols)
+        assert_equal(mX.ptp(1), rows)
+
+    def test_add_object(self):
+        x = masked_array(['a', 'b'], mask=[1, 0], dtype=object)
+        y = x + 'x'
+        assert_equal(y[1], 'bx')
+        assert_(y.mask[0])
+
+    def test_sum_object(self):
+        # Test sum on object dtype
+        a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=np.object)
+        assert_equal(a.sum(), 5)
+        a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
+        assert_equal(a.sum(axis=0), [5, 7, 9])
+
+    def test_prod_object(self):
+        # Test prod on object dtype
+        a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=np.object)
+        assert_equal(a.prod(), 2 * 3)
+        a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object)
+        assert_equal(a.prod(axis=0), [4, 10, 18])
+
+    def test_meananom_object(self):
+        # Test mean/anom on object dtype
+        a = masked_array([1, 2, 3], dtype=np.object)
+        assert_equal(a.mean(), 2)
+        assert_equal(a.anom(), [-1, 0, 1])
+
+    def test_trace(self):
+        # Tests trace on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        mXdiag = mX.diagonal()
+        assert_equal(mX.trace(), mX.diagonal().compressed().sum())
+        assert_almost_equal(mX.trace(),
+                            X.trace() - sum(mXdiag.mask * X.diagonal(),
+                                            axis=0))
+        assert_equal(np.trace(mX), mX.trace())
+
+    def test_dot(self):
+        # Tests dot on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        fx = mx.filled(0)
+        r = mx.dot(mx)
+        assert_almost_equal(r.filled(0), fx.dot(fx))
+        assert_(r.mask is nomask)
+
+        fX = mX.filled(0)
+        r = mX.dot(mX)
+        assert_almost_equal(r.filled(0), fX.dot(fX))
+        assert_(r.mask[1,3])
+        r1 = empty_like(r)
+        mX.dot(mX, out=r1)
+        assert_almost_equal(r, r1)
+
+        mYY = mXX.swapaxes(-1, -2)
+        fXX, fYY = mXX.filled(0), mYY.filled(0)
+        r = mXX.dot(mYY)
+        assert_almost_equal(r.filled(0), fXX.dot(fYY))
+        r1 = empty_like(r)
+        mXX.dot(mYY, out=r1)
+        assert_almost_equal(r, r1)
+
+    def test_dot_shape_mismatch(self):
+        # regression test
+        x = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]])
+        y = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]])
+        z = masked_array([[0,1],[3,3]])
+        x.dot(y, out=z)
+        assert_almost_equal(z.filled(0), [[1, 0], [15, 16]])
+        assert_almost_equal(z.mask, [[0, 1], [0, 0]])
+
+    def test_varstd(self):
+        # Tests var & std on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        assert_almost_equal(mX.var(axis=None), mX.compressed().var())
+        assert_almost_equal(mX.std(axis=None), mX.compressed().std())
+        assert_almost_equal(mX.std(axis=None, ddof=1),
+                            mX.compressed().std(ddof=1))
+        assert_almost_equal(mX.var(axis=None, ddof=1),
+                            mX.compressed().var(ddof=1))
+        assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
+        assert_equal(mX.var().shape, X.var().shape)
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        assert_almost_equal(mX.var(axis=None, ddof=2),
+                            mX.compressed().var(ddof=2))
+        assert_almost_equal(mX.std(axis=None, ddof=2),
+                            mX.compressed().std(ddof=2))
+        for k in range(6):
+            assert_almost_equal(mXvar1[k], mX[k].compressed().var())
+            assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
+            assert_almost_equal(np.sqrt(mXvar0[k]),
+                                mX[:, k].compressed().std())
+
+    def test_varstd_specialcases(self):
+        # Test a special case for var
+        nout = np.array(-1, dtype=float)
+        mout = array(-1, dtype=float)
+
+        x = array(arange(10), mask=True)
+        for methodname in ('var', 'std'):
+            method = getattr(x, methodname)
+            self.assertTrue(method() is masked)
+            self.assertTrue(method(0) is masked)
+            self.assertTrue(method(-1) is masked)
+            # Using a masked array as explicit output
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                method(out=mout)
+            self.assertTrue(mout is not masked)
+            assert_equal(mout.mask, True)
+            # Using a ndarray as explicit output
+            with warnings.catch_warnings():
+                warnings.simplefilter('ignore')
+                method(out=nout)
+            self.assertTrue(np.isnan(nout))
+
+        x = array(arange(10), mask=True)
+        x[-1] = 9
+        for methodname in ('var', 'std'):
+            method = getattr(x, methodname)
+            self.assertTrue(method(ddof=1) is masked)
+            self.assertTrue(method(0, ddof=1) is masked)
+            self.assertTrue(method(-1, ddof=1) is masked)
+            # Using a masked array as explicit output
+            method(out=mout, ddof=1)
+            self.assertTrue(mout is not masked)
+            assert_equal(mout.mask, True)
+            # Using a ndarray as explicit output
+            method(out=nout, ddof=1)
+            self.assertTrue(np.isnan(nout))
+
+    def test_varstd_ddof(self):
+        a = array([[1, 1, 0], [1, 1, 0]], mask=[[0, 0, 1], [0, 0, 1]])
+        test = a.std(axis=0, ddof=0)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [0, 0, 1])
+        test = a.std(axis=0, ddof=1)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [0, 0, 1])
+        test = a.std(axis=0, ddof=2)
+        assert_equal(test.filled(0), [0, 0, 0])
+        assert_equal(test.mask, [1, 1, 1])
+
+    def test_diag(self):
+        # Test diag
+        x = arange(9).reshape((3, 3))
+        x[1, 1] = masked
+        out = np.diag(x)
+        assert_equal(out, [0, 4, 8])
+        out = diag(x)
+        assert_equal(out, [0, 4, 8])
+        assert_equal(out.mask, [0, 1, 0])
+        out = diag(out)
+        control = array([[0, 0, 0], [0, 4, 0], [0, 0, 8]],
+                        mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(out, control)
+
+    def test_axis_methods_nomask(self):
+        # Test the combination nomask & methods w/ axis
+        a = array([[1, 2, 3], [4, 5, 6]])
+
+        assert_equal(a.sum(0), [5, 7, 9])
+        assert_equal(a.sum(-1), [6, 15])
+        assert_equal(a.sum(1), [6, 15])
+
+        assert_equal(a.prod(0), [4, 10, 18])
+        assert_equal(a.prod(-1), [6, 120])
+        assert_equal(a.prod(1), [6, 120])
+
+        assert_equal(a.min(0), [1, 2, 3])
+        assert_equal(a.min(-1), [1, 4])
+        assert_equal(a.min(1), [1, 4])
+
+        assert_equal(a.max(0), [4, 5, 6])
+        assert_equal(a.max(-1), [3, 6])
+        assert_equal(a.max(1), [3, 6])
+
+
+class TestMaskedArrayMathMethodsComplex(TestCase):
+    # Test class for miscellaneous MaskedArrays methods.
+    def setUp(self):
+        # Base data definition.
+        x = np.array([8.375j, 7.545j, 8.828j, 8.5j, 1.757j, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479j,
+                      7.189j, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993j])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                     1, 0, 1, 1, 0, 1,
+                     0, 0, 0, 1, 0, 1,
+                     0, 0, 0, 1, 1, 1,
+                     1, 0, 0, 1, 0, 0,
+                     0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        m2 = np.array([1, 1, 0, 1, 0, 0,
+                      1, 1, 1, 1, 0, 1,
+                      0, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 1, 0,
+                      0, 0, 1, 0, 1, 1])
+        m2x = array(data=x, mask=m2)
+        m2X = array(data=X, mask=m2.reshape(X.shape))
+        m2XX = array(data=XX, mask=m2.reshape(XX.shape))
+        self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX)
+
+    def test_varstd(self):
+        # Tests var & std on MaskedArrays.
+        (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
+        assert_almost_equal(mX.var(axis=None), mX.compressed().var())
+        assert_almost_equal(mX.std(axis=None), mX.compressed().std())
+        assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape)
+        assert_equal(mX.var().shape, X.var().shape)
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        assert_almost_equal(mX.var(axis=None, ddof=2),
+                            mX.compressed().var(ddof=2))
+        assert_almost_equal(mX.std(axis=None, ddof=2),
+                            mX.compressed().std(ddof=2))
+        for k in range(6):
+            assert_almost_equal(mXvar1[k], mX[k].compressed().var())
+            assert_almost_equal(mXvar0[k], mX[:, k].compressed().var())
+            assert_almost_equal(np.sqrt(mXvar0[k]),
+                                mX[:, k].compressed().std())
+
+
+class TestMaskedArrayFunctions(TestCase):
+    # Test class for miscellaneous functions.
+
+    def setUp(self):
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        xm.set_fill_value(1e+20)
+        self.info = (xm, ym)
+
+    def test_masked_where_bool(self):
+        x = [1, 2]
+        y = masked_where(False, x)
+        assert_equal(y, [1, 2])
+        assert_equal(y[1], 2)
+
+    def test_masked_equal_wlist(self):
+        x = [1, 2, 3]
+        mx = masked_equal(x, 3)
+        assert_equal(mx, x)
+        assert_equal(mx._mask, [0, 0, 1])
+        mx = masked_not_equal(x, 3)
+        assert_equal(mx, x)
+        assert_equal(mx._mask, [1, 1, 0])
+
+    def test_masked_equal_fill_value(self):
+        x = [1, 2, 3]
+        mx = masked_equal(x, 3)
+        assert_equal(mx._mask, [0, 0, 1])
+        assert_equal(mx.fill_value, 3)
+
+    def test_masked_where_condition(self):
+        # Tests masking functions.
+        x = array([1., 2., 3., 4., 5.])
+        x[2] = masked
+        assert_equal(masked_where(greater(x, 2), x), masked_greater(x, 2))
+        assert_equal(masked_where(greater_equal(x, 2), x),
+                     masked_greater_equal(x, 2))
+        assert_equal(masked_where(less(x, 2), x), masked_less(x, 2))
+        assert_equal(masked_where(less_equal(x, 2), x),
+                     masked_less_equal(x, 2))
+        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
+        assert_equal(masked_where(equal(x, 2), x), masked_equal(x, 2))
+        assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))
+        assert_equal(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]),
+                     [99, 99, 3, 4, 5])
+
+    def test_masked_where_oddities(self):
+        # Tests some generic features.
+        atest = ones((10, 10, 10), dtype=float)
+        btest = zeros(atest.shape, MaskType)
+        ctest = masked_where(btest, atest)
+        assert_equal(atest, ctest)
+
+    def test_masked_where_shape_constraint(self):
+        a = arange(10)
+        try:
+            test = masked_equal(1, a)
+        except IndexError:
+            pass
+        else:
+            raise AssertionError("Should have failed...")
+        test = masked_equal(a, 1)
+        assert_equal(test.mask, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0])
+
+    def test_masked_where_structured(self):
+        # test that masked_where on a structured array sets a structured
+        # mask (see issue #2972)
+        a = np.zeros(10, dtype=[("A", "<f2"), ("B", "<f4")])
+        am = np.ma.masked_where(a["A"] < 5, a)
+        assert_equal(am.mask.dtype.names, am.dtype.names)
+        assert_equal(am["A"],
+                    np.ma.masked_array(np.zeros(10), np.ones(10)))
+
+    def test_masked_otherfunctions(self):
+        assert_equal(masked_inside(list(range(5)), 1, 3),
+                     [0, 199, 199, 199, 4])
+        assert_equal(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199])
+        assert_equal(masked_inside(array(list(range(5)),
+                                         mask=[1, 0, 0, 0, 0]), 1, 3).mask,
+                     [1, 1, 1, 1, 0])
+        assert_equal(masked_outside(array(list(range(5)),
+                                          mask=[0, 1, 0, 0, 0]), 1, 3).mask,
+                     [1, 1, 0, 0, 1])
+        assert_equal(masked_equal(array(list(range(5)),
+                                        mask=[1, 0, 0, 0, 0]), 2).mask,
+                     [1, 0, 1, 0, 0])
+        assert_equal(masked_not_equal(array([2, 2, 1, 2, 1],
+                                            mask=[1, 0, 0, 0, 0]), 2).mask,
+                     [1, 0, 1, 0, 1])
+
+    def test_round(self):
+        a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890],
+                  mask=[0, 1, 0, 0, 0])
+        assert_equal(a.round(), [1., 2., 3., 5., 6.])
+        assert_equal(a.round(1), [1.2, 2.3, 3.5, 4.6, 5.7])
+        assert_equal(a.round(3), [1.235, 2.346, 3.457, 4.568, 5.679])
+        b = empty_like(a)
+        a.round(out=b)
+        assert_equal(b, [1., 2., 3., 5., 6.])
+
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+    def test_round_with_output(self):
+        # Testing round with an explicit output
+
+        xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4)
+        xm[:, 0] = xm[0] = xm[-1, -1] = masked
+
+        # A ndarray as explicit input
+        output = np.empty((3, 4), dtype=float)
+        output.fill(-9999)
+        result = np.round(xm, decimals=2, out=output)
+        # ... the result should be the given output
+        self.assertTrue(result is output)
+        assert_equal(result, xm.round(decimals=2, out=output))
+
+        output = empty((3, 4), dtype=float)
+        result = xm.round(decimals=2, out=output)
+        self.assertTrue(result is output)
+
+    def test_round_with_scalar(self):
+        # Testing round with scalar/zero dimension input
+        # GH issue 2244
+        a = array(1.1, mask=[False])
+        assert_equal(a.round(), 1)
+
+        a = array(1.1, mask=[True])
+        assert_(a.round() is masked)
+
+        a = array(1.1, mask=[False])
+        output = np.empty(1, dtype=float)
+        output.fill(-9999)
+        a.round(out=output)
+        assert_equal(output, 1)
+
+        a = array(1.1, mask=[False])
+        output = array(-9999., mask=[True])
+        a.round(out=output)
+        assert_equal(output[()], 1)
+
+        a = array(1.1, mask=[True])
+        output = array(-9999., mask=[False])
+        a.round(out=output)
+        assert_(output[()] is masked)
+
+    def test_identity(self):
+        a = identity(5)
+        self.assertTrue(isinstance(a, MaskedArray))
+        assert_equal(a, np.identity(5))
+
+    def test_power(self):
+        x = -1.1
+        assert_almost_equal(power(x, 2.), 1.21)
+        self.assertTrue(power(x, masked) is masked)
+        x = array([-1.1, -1.1, 1.1, 1.1, 0.])
+        b = array([0.5, 2., 0.5, 2., -1.], mask=[0, 0, 0, 0, 1])
+        y = power(x, b)
+        assert_almost_equal(y, [0, 1.21, 1.04880884817, 1.21, 0.])
+        assert_equal(y._mask, [1, 0, 0, 0, 1])
+        b.mask = nomask
+        y = power(x, b)
+        assert_equal(y._mask, [1, 0, 0, 0, 1])
+        z = x ** b
+        assert_equal(z._mask, y._mask)
+        assert_almost_equal(z, y)
+        assert_almost_equal(z._data, y._data)
+        x **= b
+        assert_equal(x._mask, y._mask)
+        assert_almost_equal(x, y)
+        assert_almost_equal(x._data, y._data)
+
+    def test_power_w_broadcasting(self):
+        # Test power w/ broadcasting
+        a2 = np.array([[1., 2., 3.], [4., 5., 6.]])
+        a2m = array(a2, mask=[[1, 0, 0], [0, 0, 1]])
+        b1 = np.array([2, 4, 3])
+        b2 = np.array([b1, b1])
+        b2m = array(b2, mask=[[0, 1, 0], [0, 1, 0]])
+
+        ctrl = array([[1 ** 2, 2 ** 4, 3 ** 3], [4 ** 2, 5 ** 4, 6 ** 3]],
+                     mask=[[1, 1, 0], [0, 1, 1]])
+        # No broadcasting, base & exp w/ mask
+        test = a2m ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        # No broadcasting, base w/ mask, exp w/o mask
+        test = a2m ** b2
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, a2m.mask)
+        # No broadcasting, base w/o mask, exp w/ mask
+        test = a2 ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, b2m.mask)
+
+        ctrl = array([[2 ** 2, 4 ** 4, 3 ** 3], [2 ** 2, 4 ** 4, 3 ** 3]],
+                     mask=[[0, 1, 0], [0, 1, 0]])
+        test = b1 ** b2m
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+        test = b2m ** b1
+        assert_equal(test, ctrl)
+        assert_equal(test.mask, ctrl.mask)
+
+    def test_where(self):
+        # Test the where function
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = masked_array(x, mask=m1)
+        ym = masked_array(y, mask=m2)
+        xm.set_fill_value(1e+20)
+
+        d = where(xm > 2, xm, -9)
+        assert_equal(d, [-9., -9., -9., -9., -9., 4.,
+                         -9., -9., 10., -9., -9., 3.])
+        assert_equal(d._mask, xm._mask)
+        d = where(xm > 2, -9, ym)
+        assert_equal(d, [5., 0., 3., 2., -1., -9.,
+                         -9., -10., -9., 1., 0., -9.])
+        assert_equal(d._mask, [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0])
+        d = where(xm > 2, xm, masked)
+        assert_equal(d, [-9., -9., -9., -9., -9., 4.,
+                         -9., -9., 10., -9., -9., 3.])
+        tmp = xm._mask.copy()
+        tmp[(xm <= 2).filled(True)] = True
+        assert_equal(d._mask, tmp)
+
+        ixm = xm.astype(int)
+        d = where(ixm > 2, ixm, masked)
+        assert_equal(d, [-9, -9, -9, -9, -9, 4, -9, -9, 10, -9, -9, 3])
+        assert_equal(d.dtype, ixm.dtype)
+
+    def test_where_object(self):
+        a = np.array(None)
+        b = masked_array(None)
+        r = b.copy()
+        assert_equal(np.ma.where(True, a, a), r)
+        assert_equal(np.ma.where(True, b, b), r)
+
+    def test_where_with_masked_choice(self):
+        x = arange(10)
+        x[3] = masked
+        c = x >= 8
+        # Set False to masked
+        z = where(c, x, masked)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is masked)
+        assert_(z[7] is masked)
+        assert_(z[8] is not masked)
+        assert_(z[9] is not masked)
+        assert_equal(x, z)
+        # Set True to masked
+        z = where(c, masked, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+
+    def test_where_with_masked_condition(self):
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_equal(z, [1., 2., 0., -4., -5])
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+
+        x = arange(1, 6)
+        x[-1] = masked
+        y = arange(1, 6) * 10
+        y[2] = masked
+        c = array([1, 1, 1, 0, 0], mask=[1, 0, 0, 0, 0])
+        cm = c.filled(1)
+        z = where(c, x, y)
+        zm = where(cm, x, y)
+        assert_equal(z, zm)
+        assert_(getmask(zm) is nomask)
+        assert_equal(zm, [1, 2, 3, 40, 50])
+        z = where(c, masked, 1)
+        assert_equal(z, [99, 99, 99, 1, 1])
+        z = where(c, 1, masked)
+        assert_equal(z, [99, 1, 1, 99, 99])
+
+    def test_where_type(self):
+        # Test the type conservation with where
+        x = np.arange(4, dtype=np.int32)
+        y = np.arange(4, dtype=np.float32) * 2.2
+        test = where(x > 1.5, y, x).dtype
+        control = np.find_common_type([np.int32, np.float32], [])
+        assert_equal(test, control)
+
+    def test_choose(self):
+        # Test choose
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        chosen = choose([2, 3, 1, 0], choices)
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        chosen = choose([2, 4, 1, 0], choices, mode='clip')
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        chosen = choose([2, 4, 1, 0], choices, mode='wrap')
+        assert_equal(chosen, array([20, 1, 12, 3]))
+        # Check with some masked indices
+        indices_ = array([2, 4, 1, 0], mask=[1, 0, 0, 1])
+        chosen = choose(indices_, choices, mode='wrap')
+        assert_equal(chosen, array([99, 1, 12, 99]))
+        assert_equal(chosen.mask, [1, 0, 0, 1])
+        # Check with some masked choices
+        choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
+                                       [1, 0, 0, 0], [0, 0, 0, 0]])
+        indices_ = [2, 3, 1, 0]
+        chosen = choose(indices_, choices, mode='wrap')
+        assert_equal(chosen, array([20, 31, 12, 3]))
+        assert_equal(chosen.mask, [1, 0, 0, 1])
+
+    def test_choose_with_out(self):
+        # Test choose with an explicit out keyword
+        choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+                   [20, 21, 22, 23], [30, 31, 32, 33]]
+        store = empty(4, dtype=int)
+        chosen = choose([2, 3, 1, 0], choices, out=store)
+        assert_equal(store, array([20, 31, 12, 3]))
+        self.assertTrue(store is chosen)
+        # Check with some masked indices + out
+        store = empty(4, dtype=int)
+        indices_ = array([2, 3, 1, 0], mask=[1, 0, 0, 1])
+        chosen = choose(indices_, choices, mode='wrap', out=store)
+        assert_equal(store, array([99, 31, 12, 99]))
+        assert_equal(store.mask, [1, 0, 0, 1])
+        # Check with some masked choices + out ina ndarray !
+        choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1],
+                                       [1, 0, 0, 0], [0, 0, 0, 0]])
+        indices_ = [2, 3, 1, 0]
+        store = empty(4, dtype=int).view(ndarray)
+        chosen = choose(indices_, choices, mode='wrap', out=store)
+        assert_equal(store, array([999999, 31, 12, 999999]))
+
+    def test_reshape(self):
+        a = arange(10)
+        a[0] = masked
+        # Try the default
+        b = a.reshape((5, 2))
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['C'])
+        # Try w/ arguments as list instead of tuple
+        b = a.reshape(5, 2)
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['C'])
+        # Try w/ order
+        b = a.reshape((5, 2), order='F')
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['F'])
+        # Try w/ order
+        b = a.reshape(5, 2, order='F')
+        assert_equal(b.shape, (5, 2))
+        self.assertTrue(b.flags['F'])
+
+        c = np.reshape(a, (2, 5))
+        self.assertTrue(isinstance(c, MaskedArray))
+        assert_equal(c.shape, (2, 5))
+        self.assertTrue(c[0, 0] is masked)
+        self.assertTrue(c.flags['C'])
+
+    def test_make_mask_descr(self):
+        # Test make_mask_descr
+        # Flexible
+        ntype = [('a', np.float), ('b', np.float)]
+        test = make_mask_descr(ntype)
+        assert_equal(test, [('a', np.bool), ('b', np.bool)])
+        # Standard w/ shape
+        ntype = (np.float, 2)
+        test = make_mask_descr(ntype)
+        assert_equal(test, (np.bool, 2))
+        # Standard standard
+        ntype = np.float
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype(np.bool))
+        # Nested
+        ntype = [('a', np.float), ('b', [('ba', np.float), ('bb', np.float)])]
+        test = make_mask_descr(ntype)
+        control = np.dtype([('a', 'b1'), ('b', [('ba', 'b1'), ('bb', 'b1')])])
+        assert_equal(test, control)
+        # Named+ shape
+        ntype = [('a', (np.float, 2))]
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype([('a', (np.bool, 2))]))
+        # 2 names
+        ntype = [(('A', 'a'), float)]
+        test = make_mask_descr(ntype)
+        assert_equal(test, np.dtype([(('A', 'a'), bool)]))
+
+    def test_make_mask(self):
+        # Test make_mask
+        # w/ a list as an input
+        mask = [0, 1]
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [0, 1])
+        # w/ a ndarray as an input
+        mask = np.array([0, 1], dtype=np.bool)
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [0, 1])
+        # w/ a flexible-type ndarray as an input - use default
+        mdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask)
+        assert_equal(test.dtype, MaskType)
+        assert_equal(test, [1, 1])
+        # w/ a flexible-type ndarray as an input - use input dtype
+        mdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask, dtype=mask.dtype)
+        assert_equal(test.dtype, mdtype)
+        assert_equal(test, mask)
+        # w/ a flexible-type ndarray as an input - use input dtype
+        mdtype = [('a', np.float), ('b', np.float)]
+        bdtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+        test = make_mask(mask, dtype=mask.dtype)
+        assert_equal(test.dtype, bdtype)
+        assert_equal(test, np.array([(0, 0), (0, 1)], dtype=bdtype))
+
+        # test that nomask is returned when m is nomask.
+        bools = [True, False]
+        dtypes = [MaskType, np.float]
+        msgformat = 'copy=%s, shrink=%s, dtype=%s'
+        for cpy, shr, dt in itertools.product(bools, bools, dtypes):
+            res = make_mask(nomask, copy=cpy, shrink=shr, dtype=dt)
+            assert_(res is nomask, msgformat % (cpy, shr, dt))
+
+
+    def test_mask_or(self):
+        # Initialize
+        mtype = [('a', np.bool), ('b', np.bool)]
+        mask = np.array([(0, 0), (0, 1), (1, 0), (0, 0)], dtype=mtype)
+        # Test using nomask as input
+        test = mask_or(mask, nomask)
+        assert_equal(test, mask)
+        test = mask_or(nomask, mask)
+        assert_equal(test, mask)
+        # Using False as input
+        test = mask_or(mask, False)
+        assert_equal(test, mask)
+        # Using another array w / the same dtype
+        other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=mtype)
+        test = mask_or(mask, other)
+        control = np.array([(0, 1), (0, 1), (1, 1), (0, 1)], dtype=mtype)
+        assert_equal(test, control)
+        # Using another array w / a different dtype
+        othertype = [('A', np.bool), ('B', np.bool)]
+        other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=othertype)
+        try:
+            test = mask_or(mask, other)
+        except ValueError:
+            pass
+        # Using nested arrays
+        dtype = [('a', np.bool), ('b', [('ba', np.bool), ('bb', np.bool)])]
+        amask = np.array([(0, (1, 0)), (0, (1, 0))], dtype=dtype)
+        bmask = np.array([(1, (0, 1)), (0, (0, 0))], dtype=dtype)
+        cntrl = np.array([(1, (1, 1)), (0, (1, 0))], dtype=dtype)
+        assert_equal(mask_or(amask, bmask), cntrl)
+
+    def test_flatten_mask(self):
+        # Tests flatten mask
+        # Standarad dtype
+        mask = np.array([0, 0, 1], dtype=np.bool)
+        assert_equal(flatten_mask(mask), mask)
+        # Flexible dtype
+        mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)])
+        test = flatten_mask(mask)
+        control = np.array([0, 0, 0, 1], dtype=bool)
+        assert_equal(test, control)
+
+        mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])]
+        data = [(0, (0, 0)), (0, (0, 1))]
+        mask = np.array(data, dtype=mdtype)
+        test = flatten_mask(mask)
+        control = np.array([0, 0, 0, 0, 0, 1], dtype=bool)
+        assert_equal(test, control)
+
+    def test_on_ndarray(self):
+        # Test functions on ndarrays
+        a = np.array([1, 2, 3, 4])
+        m = array(a, mask=False)
+        test = anom(a)
+        assert_equal(test, m.anom())
+        test = reshape(a, (2, 2))
+        assert_equal(test, m.reshape(2, 2))
+
+    def test_compress(self):
+        # Test compress function on ndarray and masked array
+        # Address Github #2495.
+        arr = np.arange(8)
+        arr.shape = 4, 2
+        cond = np.array([True, False, True, True])
+        control = arr[[0, 2, 3]]
+        test = np.ma.compress(cond, arr, axis=0)
+        assert_equal(test, control)
+        marr = np.ma.array(arr)
+        test = np.ma.compress(cond, marr, axis=0)
+        assert_equal(test, control)
+
+    def test_compressed(self):
+        # Test ma.compressed function.
+        # Address gh-4026
+        a = np.ma.array([1, 2])
+        test = np.ma.compressed(a)
+        assert_(type(test) is np.ndarray)
+
+        # Test case when input data is ndarray subclass
+        class A(np.ndarray):
+            pass
+
+        a = np.ma.array(A(shape=0))
+        test = np.ma.compressed(a)
+        assert_(type(test) is A)
+
+        # Test that compress flattens
+        test = np.ma.compressed([[1],[2]])
+        assert_equal(test.ndim, 1)
+        test = np.ma.compressed([[[[[1]]]]])
+        assert_equal(test.ndim, 1)
+
+        # Test case when input is MaskedArray subclass
+        class M(MaskedArray):
+            pass
+
+        test = np.ma.compressed(M(shape=(0,1,2)))
+        assert_equal(test.ndim, 1)
+
+        # with .compessed() overriden
+        class M(MaskedArray):
+            def compressed(self):
+                return 42
+
+        test = np.ma.compressed(M(shape=(0,1,2)))
+        assert_equal(test, 42)
+
+
+class TestMaskedFields(TestCase):
+
+    def setUp(self):
+        ilist = [1, 2, 3, 4, 5]
+        flist = [1.1, 2.2, 3.3, 4.4, 5.5]
+        slist = ['one', 'two', 'three', 'four', 'five']
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mdtype = [('a', bool), ('b', bool), ('c', bool)]
+        mask = [0, 1, 0, 0, 1]
+        base = array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype)
+        self.data = dict(base=base, mask=mask, ddtype=ddtype, mdtype=mdtype)
+
+    def test_set_records_masks(self):
+        base = self.data['base']
+        mdtype = self.data['mdtype']
+        # Set w/ nomask or masked
+        base.mask = nomask
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = masked
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ simple boolean
+        base.mask = False
+        assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype))
+        base.mask = True
+        assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype))
+        # Set w/ list
+        base.mask = [0, 0, 0, 1, 1]
+        assert_equal_records(base._mask,
+                             np.array([(x, x, x) for x in [0, 0, 0, 1, 1]],
+                                      dtype=mdtype))
+
+    def test_set_record_element(self):
+        # Check setting an element of a record)
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[0] = (pi, pi, 'pi')
+
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a._data, [3, 2, 3, 4, 5])
+
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b._data, [pi, 2.2, 3.3, 4.4, 5.5])
+
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c._data,
+                     asbytes_nested(['pi', 'two', 'three', 'four', 'five']))
+
+    def test_set_record_slice(self):
+        base = self.data['base']
+        (base_a, base_b, base_c) = (base['a'], base['b'], base['c'])
+        base[:3] = (pi, pi, 'pi')
+
+        assert_equal(base_a.dtype, int)
+        assert_equal(base_a._data, [3, 3, 3, 4, 5])
+
+        assert_equal(base_b.dtype, float)
+        assert_equal(base_b._data, [pi, pi, pi, 4.4, 5.5])
+
+        assert_equal(base_c.dtype, '|S8')
+        assert_equal(base_c._data,
+                     asbytes_nested(['pi', 'pi', 'pi', 'four', 'five']))
+
+    def test_mask_element(self):
+        "Check record access"
+        base = self.data['base']
+        base[0] = masked
+
+        for n in ('a', 'b', 'c'):
+            assert_equal(base[n].mask, [1, 1, 0, 0, 1])
+            assert_equal(base[n]._data, base._data[n])
+
+    def test_getmaskarray(self):
+        # Test getmaskarray on flexible dtype
+        ndtype = [('a', int), ('b', float)]
+        test = empty(3, dtype=ndtype)
+        assert_equal(getmaskarray(test),
+                     np.array([(0, 0), (0, 0), (0, 0)],
+                              dtype=[('a', '|b1'), ('b', '|b1')]))
+        test[:] = masked
+        assert_equal(getmaskarray(test),
+                     np.array([(1, 1), (1, 1), (1, 1)],
+                              dtype=[('a', '|b1'), ('b', '|b1')]))
+
+    def test_view(self):
+        # Test view w/ flexible dtype
+        iterator = list(zip(np.arange(10), np.random.rand(10)))
+        data = np.array(iterator)
+        a = array(iterator, dtype=[('a', float), ('b', float)])
+        a.mask[0] = (1, 0)
+        controlmask = np.array([1] + 19 * [0], dtype=bool)
+        # Transform globally to simple dtype
+        test = a.view(float)
+        assert_equal(test, data.ravel())
+        assert_equal(test.mask, controlmask)
+        # Transform globally to dty
+        test = a.view((float, 2))
+        assert_equal(test, data)
+        assert_equal(test.mask, controlmask.reshape(-1, 2))
+
+        test = a.view((float, 2), np.matrix)
+        assert_equal(test, data)
+        self.assertTrue(isinstance(test, np.matrix))
+
+    def test_getitem(self):
+        ndtype = [('a', float), ('b', float)]
+        a = array(list(zip(np.random.rand(10), np.arange(10))), dtype=ndtype)
+        a.mask = np.array(list(zip([0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
+                                   [1, 0, 0, 0, 0, 0, 0, 0, 1, 0])),
+                          dtype=[('a', bool), ('b', bool)])
+        # No mask
+        self.assertTrue(isinstance(a[1], MaskedArray))
+        # One element masked
+        self.assertTrue(isinstance(a[0], MaskedArray))
+        assert_equal_records(a[0]._data, a._data[0])
+        assert_equal_records(a[0]._mask, a._mask[0])
+        # All element masked
+        self.assertTrue(isinstance(a[-2], MaskedArray))
+        assert_equal_records(a[-2]._data, a._data[-2])
+        assert_equal_records(a[-2]._mask, a._mask[-2])
+
+    def test_setitem(self):
+        # Issue 4866: check that one can set individual items in [record][col]
+        # and [col][record] order
+        ndtype = np.dtype([('a', float), ('b', int)])
+        ma = np.ma.MaskedArray([(1.0, 1), (2.0, 2)], dtype=ndtype)
+        ma['a'][1] = 3.0
+        assert_equal(ma['a'], np.array([1.0, 3.0]))
+        ma[1]['a'] = 4.0
+        assert_equal(ma['a'], np.array([1.0, 4.0]))
+        # Issue 2403
+        mdtype = np.dtype([('a', bool), ('b', bool)])
+        # soft mask
+        control = np.array([(False, True), (True, True)], dtype=mdtype)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a['a'][0] = 2
+        assert_equal(a.mask, control)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a[0]['a'] = 2
+        assert_equal(a.mask, control)
+        # hard mask
+        control = np.array([(True, True), (True, True)], dtype=mdtype)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a.harden_mask()
+        a['a'][0] = 2
+        assert_equal(a.mask, control)
+        a = np.ma.masked_all((2,), dtype=ndtype)
+        a.harden_mask()
+        a[0]['a'] = 2
+        assert_equal(a.mask, control)
+
+    def test_element_len(self):
+        # check that len() works for mvoid (Github issue #576)
+        for rec in self.data['base']:
+            assert_equal(len(rec), len(self.data['ddtype']))
+
+
+class TestMaskedView(TestCase):
+
+    def setUp(self):
+        iterator = list(zip(np.arange(10), np.random.rand(10)))
+        data = np.array(iterator)
+        a = array(iterator, dtype=[('a', float), ('b', float)])
+        a.mask[0] = (1, 0)
+        controlmask = np.array([1] + 19 * [0], dtype=bool)
+        self.data = (data, a, controlmask)
+
+    def test_view_to_nothing(self):
+        (data, a, controlmask) = self.data
+        test = a.view()
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test._data, a._data)
+        assert_equal(test._mask, a._mask)
+
+    def test_view_to_type(self):
+        (data, a, controlmask) = self.data
+        test = a.view(np.ndarray)
+        self.assertTrue(not isinstance(test, MaskedArray))
+        assert_equal(test, a._data)
+        assert_equal_records(test, data.view(a.dtype).squeeze())
+
+    def test_view_to_simple_dtype(self):
+        (data, a, controlmask) = self.data
+        # View globally
+        test = a.view(float)
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data.ravel())
+        assert_equal(test.mask, controlmask)
+
+    def test_view_to_flexible_dtype(self):
+        (data, a, controlmask) = self.data
+
+        test = a.view([('A', float), ('B', float)])
+        assert_equal(test.mask.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'])
+        assert_equal(test['B'], a['b'])
+
+        test = a[0].view([('A', float), ('B', float)])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.mask.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'][0])
+        assert_equal(test['B'], a['b'][0])
+
+        test = a[-1].view([('A', float), ('B', float)])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.dtype.names, ('A', 'B'))
+        assert_equal(test['A'], a['a'][-1])
+        assert_equal(test['B'], a['b'][-1])
+
+    def test_view_to_subdtype(self):
+        (data, a, controlmask) = self.data
+        # View globally
+        test = a.view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data)
+        assert_equal(test.mask, controlmask.reshape(-1, 2))
+        # View on 1 masked element
+        test = a[0].view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data[0])
+        assert_equal(test.mask, (1, 0))
+        # View on 1 unmasked element
+        test = a[-1].view((float, 2))
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test, data[-1])
+
+    def test_view_to_dtype_and_type(self):
+        (data, a, controlmask) = self.data
+
+        test = a.view((float, 2), np.matrix)
+        assert_equal(test, data)
+        self.assertTrue(isinstance(test, np.matrix))
+        self.assertTrue(not isinstance(test, MaskedArray))
+
+
+def test_masked_array():
+    a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0])
+    assert_equal(np.argwhere(a), [[1], [3]])
+
+def test_append_masked_array():
+    a = np.ma.masked_equal([1,2,3], value=2)
+    b = np.ma.masked_equal([4,3,2], value=2)
+
+    result = np.ma.append(a, b)
+    expected_data = [1, 2, 3, 4, 3, 2]
+    expected_mask = [False, True, False, False, False, True]
+    assert_array_equal(result.data, expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+    a = np.ma.masked_all((2,2))
+    b = np.ma.ones((3,1))
+
+    result = np.ma.append(a, b)
+    expected_data = [1] * 3
+    expected_mask = [True] * 4 + [False] * 3
+    assert_array_equal(result.data[-3], expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+    result = np.ma.append(a, b, axis=None)
+    assert_array_equal(result.data[-3], expected_data)
+    assert_array_equal(result.mask, expected_mask)
+
+
+def test_append_masked_array_along_axis():
+    a = np.ma.masked_equal([1,2,3], value=2)
+    b = np.ma.masked_values([[4, 5, 6], [7, 8, 9]], 7)
+
+    # When `axis` is specified, `values` must have the correct shape.
+    assert_raises(ValueError, np.ma.append, a, b, axis=0)
+
+    result = np.ma.append(a[np.newaxis,:], b, axis=0)
+    expected = np.ma.arange(1, 10)
+    expected[[1, 6]] = np.ma.masked
+    expected = expected.reshape((3,3))
+    assert_array_equal(result.data, expected.data)
+    assert_array_equal(result.mask, expected.mask)
+
+
+def test_default_fill_value_complex():
+    # regression test for Python 3, where 'unicode' was not defined
+    assert_(default_fill_value(1 + 1j) == 1.e20 + 0.0j)
+
+###############################################################################
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
new file mode 100644
index 0000000000..6138d05739
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
@@ -0,0 +1,1188 @@
+# pylint: disable-msg=W0611, W0612, W0511
+"""Tests suite for MaskedArray.
+Adapted from the original test_ma by Pierre Gerard-Marchant
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: test_extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_warns, clear_and_catch_warnings
+    )
+from numpy.ma.testutils import (
+    assert_, assert_array_equal, assert_equal, assert_almost_equal
+    )
+from numpy.ma.core import (
+    array, arange, masked, MaskedArray, masked_array, getmaskarray, shape,
+    nomask, ones, zeros, count
+    )
+from numpy.ma.extras import (
+    atleast_1d, atleast_2d, atleast_3d, mr_, dot, polyfit, cov, corrcoef,
+    median, average, unique, setxor1d, setdiff1d, union1d, intersect1d, in1d,
+    ediff1d, apply_over_axes, apply_along_axis, compress_nd, compress_rowcols,
+    mask_rowcols, clump_masked, clump_unmasked, flatnotmasked_contiguous,
+    notmasked_contiguous, notmasked_edges, masked_all, masked_all_like,
+    diagflat
+    )
+import numpy.ma.extras as mae
+
+
+class TestGeneric(TestCase):
+    #
+    def test_masked_all(self):
+        # Tests masked_all
+        # Standard dtype
+        test = masked_all((2,), dtype=float)
+        control = array([1, 1], mask=[1, 1], dtype=float)
+        assert_equal(test, control)
+        # Flexible dtype
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']})
+        test = masked_all((2,), dtype=dt)
+        control = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((2, 2), dtype=dt)
+        control = array([[(0, 0), (0, 0)], [(0, 0), (0, 0)]],
+                        mask=[[(1, 1), (1, 1)], [(1, 1), (1, 1)]],
+                        dtype=dt)
+        assert_equal(test, control)
+        # Nested dtype
+        dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])])
+        test = masked_all((2,), dtype=dt)
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((2,), dtype=dt)
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        assert_equal(test, control)
+        test = masked_all((1, 1), dtype=dt)
+        control = array([[(1, (1, 1))]], mask=[[(1, (1, 1))]], dtype=dt)
+        assert_equal(test, control)
+
+    def test_masked_all_like(self):
+        # Tests masked_all
+        # Standard dtype
+        base = array([1, 2], dtype=float)
+        test = masked_all_like(base)
+        control = array([1, 1], mask=[1, 1], dtype=float)
+        assert_equal(test, control)
+        # Flexible dtype
+        dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']})
+        base = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt)
+        test = masked_all_like(base)
+        control = array([(10, 10), (10, 10)], mask=[(1, 1), (1, 1)], dtype=dt)
+        assert_equal(test, control)
+        # Nested dtype
+        dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])])
+        control = array([(1, (1, 1)), (1, (1, 1))],
+                        mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt)
+        test = masked_all_like(control)
+        assert_equal(test, control)
+
+    def check_clump(self, f):
+        for i in range(1, 7):
+            for j in range(2**i):
+                k = np.arange(i, dtype=int)
+                ja = np.full(i, j, dtype=int)
+                a = masked_array(2**k)
+                a.mask = (ja & (2**k)) != 0
+                s = 0
+                for sl in f(a):
+                    s += a.data[sl].sum()
+                if f == clump_unmasked:
+                    assert_equal(a.compressed().sum(), s)
+                else:
+                    a.mask = ~a.mask
+                    assert_equal(a.compressed().sum(), s)
+
+    def test_clump_masked(self):
+        # Test clump_masked
+        a = masked_array(np.arange(10))
+        a[[0, 1, 2, 6, 8, 9]] = masked
+        #
+        test = clump_masked(a)
+        control = [slice(0, 3), slice(6, 7), slice(8, 10)]
+        assert_equal(test, control)
+
+        self.check_clump(clump_masked)
+
+    def test_clump_unmasked(self):
+        # Test clump_unmasked
+        a = masked_array(np.arange(10))
+        a[[0, 1, 2, 6, 8, 9]] = masked
+        test = clump_unmasked(a)
+        control = [slice(3, 6), slice(7, 8), ]
+        assert_equal(test, control)
+
+        self.check_clump(clump_unmasked)
+
+    def test_flatnotmasked_contiguous(self):
+        # Test flatnotmasked_contiguous
+        a = arange(10)
+        # No mask
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, slice(0, a.size))
+        # Some mask
+        a[(a < 3) | (a > 8) | (a == 5)] = masked
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, [slice(3, 5), slice(6, 9)])
+        #
+        a[:] = masked
+        test = flatnotmasked_contiguous(a)
+        assert_equal(test, None)
+
+
+class TestAverage(TestCase):
+    # Several tests of average. Why so many ? Good point...
+    def test_testAverage1(self):
+        # Test of average.
+        ott = array([0., 1., 2., 3.], mask=[True, False, False, False])
+        assert_equal(2.0, average(ott, axis=0))
+        assert_equal(2.0, average(ott, weights=[1., 1., 2., 1.]))
+        result, wts = average(ott, weights=[1., 1., 2., 1.], returned=1)
+        assert_equal(2.0, result)
+        self.assertTrue(wts == 4.0)
+        ott[:] = masked
+        assert_equal(average(ott, axis=0).mask, [True])
+        ott = array([0., 1., 2., 3.], mask=[True, False, False, False])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = masked
+        assert_equal(average(ott, axis=0), [2.0, 0.0])
+        assert_equal(average(ott, axis=1).mask[0], [True])
+        assert_equal([2., 0.], average(ott, axis=0))
+        result, wts = average(ott, axis=0, returned=1)
+        assert_equal(wts, [1., 0.])
+
+    def test_testAverage2(self):
+        # More tests of average.
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = arange(6, dtype=np.float_)
+        assert_equal(average(x, axis=0), 2.5)
+        assert_equal(average(x, axis=0, weights=w1), 2.5)
+        y = array([arange(6, dtype=np.float_), 2.0 * arange(6)])
+        assert_equal(average(y, None), np.add.reduce(np.arange(6)) * 3. / 12.)
+        assert_equal(average(y, axis=0), np.arange(6) * 3. / 2.)
+        assert_equal(average(y, axis=1),
+                     [average(x, axis=0), average(x, axis=0) * 2.0])
+        assert_equal(average(y, None, weights=w2), 20. / 6.)
+        assert_equal(average(y, axis=0, weights=w2),
+                     [0., 1., 2., 3., 4., 10.])
+        assert_equal(average(y, axis=1),
+                     [average(x, axis=0), average(x, axis=0) * 2.0])
+        m1 = zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        assert_equal(average(masked_array(x, m1), axis=0), 2.5)
+        assert_equal(average(masked_array(x, m2), axis=0), 2.5)
+        assert_equal(average(masked_array(x, m4), axis=0).mask, [True])
+        assert_equal(average(masked_array(x, m5), axis=0), 0.0)
+        assert_equal(count(average(masked_array(x, m4), axis=0)), 0)
+        z = masked_array(y, m3)
+        assert_equal(average(z, None), 20. / 6.)
+        assert_equal(average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5])
+        assert_equal(average(z, axis=1), [2.5, 5.0])
+        assert_equal(average(z, axis=0, weights=w2),
+                     [0., 1., 99., 99., 4.0, 10.0])
+
+    def test_testAverage3(self):
+        # Yet more tests of average!
+        a = arange(6)
+        b = arange(6) * 3
+        r1, w1 = average([[a, b], [b, a]], axis=1, returned=1)
+        assert_equal(shape(r1), shape(w1))
+        assert_equal(r1.shape, w1.shape)
+        r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=1)
+        assert_equal(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), returned=1)
+        assert_equal(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=1)
+        assert_equal(shape(w2), shape(r2))
+        a2d = array([[1, 2], [0, 4]], float)
+        a2dm = masked_array(a2d, [[False, False], [True, False]])
+        a2da = average(a2d, axis=0)
+        assert_equal(a2da, [0.5, 3.0])
+        a2dma = average(a2dm, axis=0)
+        assert_equal(a2dma, [1.0, 3.0])
+        a2dma = average(a2dm, axis=None)
+        assert_equal(a2dma, 7. / 3.)
+        a2dma = average(a2dm, axis=1)
+        assert_equal(a2dma, [1.5, 4.0])
+
+    def test_onintegers_with_mask(self):
+        # Test average on integers with mask
+        a = average(array([1, 2]))
+        assert_equal(a, 1.5)
+        a = average(array([1, 2, 3, 4], mask=[False, False, True, True]))
+        assert_equal(a, 1.5)
+
+    def test_complex(self):
+        # Test with complex data.
+        # (Regression test for https://github.com/numpy/numpy/issues/2684)
+        mask = np.array([[0, 0, 0, 1, 0],
+                         [0, 1, 0, 0, 0]], dtype=bool)
+        a = masked_array([[0, 1+2j, 3+4j, 5+6j, 7+8j],
+                          [9j, 0+1j, 2+3j, 4+5j, 7+7j]],
+                         mask=mask)
+
+        av = average(a)
+        expected = np.average(a.compressed())
+        assert_almost_equal(av.real, expected.real)
+        assert_almost_equal(av.imag, expected.imag)
+
+        av0 = average(a, axis=0)
+        expected0 = average(a.real, axis=0) + average(a.imag, axis=0)*1j
+        assert_almost_equal(av0.real, expected0.real)
+        assert_almost_equal(av0.imag, expected0.imag)
+
+        av1 = average(a, axis=1)
+        expected1 = average(a.real, axis=1) + average(a.imag, axis=1)*1j
+        assert_almost_equal(av1.real, expected1.real)
+        assert_almost_equal(av1.imag, expected1.imag)
+
+        # Test with the 'weights' argument.
+        wts = np.array([[0.5, 1.0, 2.0, 1.0, 0.5],
+                        [1.0, 1.0, 1.0, 1.0, 1.0]])
+        wav = average(a, weights=wts)
+        expected = np.average(a.compressed(), weights=wts[~mask])
+        assert_almost_equal(wav.real, expected.real)
+        assert_almost_equal(wav.imag, expected.imag)
+
+        wav0 = average(a, weights=wts, axis=0)
+        expected0 = (average(a.real, weights=wts, axis=0) +
+                     average(a.imag, weights=wts, axis=0)*1j)
+        assert_almost_equal(wav0.real, expected0.real)
+        assert_almost_equal(wav0.imag, expected0.imag)
+
+        wav1 = average(a, weights=wts, axis=1)
+        expected1 = (average(a.real, weights=wts, axis=1) +
+                     average(a.imag, weights=wts, axis=1)*1j)
+        assert_almost_equal(wav1.real, expected1.real)
+        assert_almost_equal(wav1.imag, expected1.imag)
+
+
+class TestConcatenator(TestCase):
+    # Tests for mr_, the equivalent of r_ for masked arrays.
+
+    def test_1d(self):
+        # Tests mr_ on 1D arrays.
+        assert_array_equal(mr_[1, 2, 3, 4, 5, 6], array([1, 2, 3, 4, 5, 6]))
+        b = ones(5)
+        m = [1, 0, 0, 0, 0]
+        d = masked_array(b, mask=m)
+        c = mr_[d, 0, 0, d]
+        self.assertTrue(isinstance(c, MaskedArray))
+        assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1])
+        assert_array_equal(c.mask, mr_[m, 0, 0, m])
+
+    def test_2d(self):
+        # Tests mr_ on 2D arrays.
+        a_1 = np.random.rand(5, 5)
+        a_2 = np.random.rand(5, 5)
+        m_1 = np.round_(np.random.rand(5, 5), 0)
+        m_2 = np.round_(np.random.rand(5, 5), 0)
+        b_1 = masked_array(a_1, mask=m_1)
+        b_2 = masked_array(a_2, mask=m_2)
+        # append columns
+        d = mr_['1', b_1, b_2]
+        self.assertTrue(d.shape == (5, 10))
+        assert_array_equal(d[:, :5], b_1)
+        assert_array_equal(d[:, 5:], b_2)
+        assert_array_equal(d.mask, np.r_['1', m_1, m_2])
+        d = mr_[b_1, b_2]
+        self.assertTrue(d.shape == (10, 5))
+        assert_array_equal(d[:5,:], b_1)
+        assert_array_equal(d[5:,:], b_2)
+        assert_array_equal(d.mask, np.r_[m_1, m_2])
+
+
+class TestNotMasked(TestCase):
+    # Tests notmasked_edges and notmasked_contiguous.
+
+    def test_edges(self):
+        # Tests unmasked_edges
+        data = masked_array(np.arange(25).reshape(5, 5),
+                            mask=[[0, 0, 1, 0, 0],
+                                  [0, 0, 0, 1, 1],
+                                  [1, 1, 0, 0, 0],
+                                  [0, 0, 0, 0, 0],
+                                  [1, 1, 1, 0, 0]],)
+        test = notmasked_edges(data, None)
+        assert_equal(test, [0, 24])
+        test = notmasked_edges(data, 0)
+        assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(3, 3, 3, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data, 1)
+        assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 2, 0, 3)])
+        assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 2, 4, 4, 4)])
+        #
+        test = notmasked_edges(data.data, None)
+        assert_equal(test, [0, 24])
+        test = notmasked_edges(data.data, 0)
+        assert_equal(test[0], [(0, 0, 0, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(4, 4, 4, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data.data, -1)
+        assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 0, 0, 0)])
+        assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 4, 4, 4, 4)])
+        #
+        data[-2] = masked
+        test = notmasked_edges(data, 0)
+        assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)])
+        assert_equal(test[1], [(1, 1, 2, 4, 4), (0, 1, 2, 3, 4)])
+        test = notmasked_edges(data, -1)
+        assert_equal(test[0], [(0, 1, 2, 4), (0, 0, 2, 3)])
+        assert_equal(test[1], [(0, 1, 2, 4), (4, 2, 4, 4)])
+
+    def test_contiguous(self):
+        # Tests notmasked_contiguous
+        a = masked_array(np.arange(24).reshape(3, 8),
+                         mask=[[0, 0, 0, 0, 1, 1, 1, 1],
+                               [1, 1, 1, 1, 1, 1, 1, 1],
+                               [0, 0, 0, 0, 0, 0, 1, 0], ])
+        tmp = notmasked_contiguous(a, None)
+        assert_equal(tmp[-1], slice(23, 24, None))
+        assert_equal(tmp[-2], slice(16, 22, None))
+        assert_equal(tmp[-3], slice(0, 4, None))
+        #
+        tmp = notmasked_contiguous(a, 0)
+        self.assertTrue(len(tmp[-1]) == 1)
+        self.assertTrue(tmp[-2] is None)
+        assert_equal(tmp[-3], tmp[-1])
+        self.assertTrue(len(tmp[0]) == 2)
+        #
+        tmp = notmasked_contiguous(a, 1)
+        assert_equal(tmp[0][-1], slice(0, 4, None))
+        self.assertTrue(tmp[1] is None)
+        assert_equal(tmp[2][-1], slice(7, 8, None))
+        assert_equal(tmp[2][-2], slice(0, 6, None))
+
+
+class TestCompressFunctions(TestCase):
+
+    def test_compress_nd(self):
+        # Tests compress_nd
+        x = np.array(list(range(3*4*5))).reshape(3, 4, 5)
+        m = np.zeros((3,4,5)).astype(bool)
+        m[1,1,1] = True
+        x = array(x, mask=m)
+
+        # axis=None
+        a = compress_nd(x)
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[40, 42, 43, 44],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        # axis=0
+        a = compress_nd(x, 0)
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [ 5,  6,  7,  8,  9],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[40, 41, 42, 43, 44],
+                          [45, 46, 47, 48, 49],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+
+        # axis=1
+        a = compress_nd(x, 1)
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[20, 21, 22, 23, 24],
+                          [30, 31, 32, 33, 34],
+                          [35, 36, 37, 38, 39]],
+                         [[40, 41, 42, 43, 44],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (1,))
+        a3 = compress_nd(x, -2)
+        a4 = compress_nd(x, (-2,))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=2
+        a = compress_nd(x, 2)
+        assert_equal(a, [[[ 0, 2,  3,  4],
+                          [ 5, 7,  8,  9],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[20, 22, 23, 24],
+                          [25, 27, 28, 29],
+                          [30, 32, 33, 34],
+                          [35, 37, 38, 39]],
+                         [[40, 42, 43, 44],
+                          [45, 47, 48, 49],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (2,))
+        a3 = compress_nd(x, -1)
+        a4 = compress_nd(x, (-1,))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=(0, 1)
+        a = compress_nd(x, (0, 1))
+        assert_equal(a, [[[ 0,  1,  2,  3,  4],
+                          [10, 11, 12, 13, 14],
+                          [15, 16, 17, 18, 19]],
+                         [[40, 41, 42, 43, 44],
+                          [50, 51, 52, 53, 54],
+                          [55, 56, 57, 58, 59]]])
+        a2 = compress_nd(x, (0, -2))
+        assert_equal(a, a2)
+
+        # axis=(1, 2)
+        a = compress_nd(x, (1, 2))
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[20, 22, 23, 24],
+                          [30, 32, 33, 34],
+                          [35, 37, 38, 39]],
+                         [[40, 42, 43, 44],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (-2, 2))
+        a3 = compress_nd(x, (1, -1))
+        a4 = compress_nd(x, (-2, -1))
+        assert_equal(a, a2)
+        assert_equal(a, a3)
+        assert_equal(a, a4)
+
+        # axis=(0, 2)
+        a = compress_nd(x, (0, 2))
+        assert_equal(a, [[[ 0,  2,  3,  4],
+                          [ 5,  7,  8,  9],
+                          [10, 12, 13, 14],
+                          [15, 17, 18, 19]],
+                         [[40, 42, 43, 44],
+                          [45, 47, 48, 49],
+                          [50, 52, 53, 54],
+                          [55, 57, 58, 59]]])
+
+        a2 = compress_nd(x, (0, -1))
+        assert_equal(a, a2)
+
+    def test_compress_rowcols(self):
+        # Tests compress_rowcols
+        x = array(np.arange(9).reshape(3, 3),
+                  mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[4, 5], [7, 8]])
+        assert_equal(compress_rowcols(x, 0), [[3, 4, 5], [6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1), [[1, 2], [4, 5], [7, 8]])
+        x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[0, 2], [6, 8]])
+        assert_equal(compress_rowcols(x, 0), [[0, 1, 2], [6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1), [[0, 2], [3, 5], [6, 8]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(compress_rowcols(x), [[8]])
+        assert_equal(compress_rowcols(x, 0), [[6, 7, 8]])
+        assert_equal(compress_rowcols(x, 1,), [[2], [5], [8]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        assert_equal(compress_rowcols(x).size, 0)
+        assert_equal(compress_rowcols(x, 0).size, 0)
+        assert_equal(compress_rowcols(x, 1).size, 0)
+
+    def test_mask_rowcols(self):
+        # Tests mask_rowcols.
+        x = array(np.arange(9).reshape(3, 3),
+                  mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[1, 1, 1], [1, 0, 0], [1, 0, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[1, 1, 1], [0, 0, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1).mask,
+                     [[1, 0, 0], [1, 0, 0], [1, 0, 0]])
+        x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[0, 1, 0], [1, 1, 1], [0, 1, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[0, 0, 0], [1, 1, 1], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1).mask,
+                     [[0, 1, 0], [0, 1, 0], [0, 1, 0]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]])
+        assert_equal(mask_rowcols(x).mask,
+                     [[1, 1, 1], [1, 1, 1], [1, 1, 0]])
+        assert_equal(mask_rowcols(x, 0).mask,
+                     [[1, 1, 1], [1, 1, 1], [0, 0, 0]])
+        assert_equal(mask_rowcols(x, 1,).mask,
+                     [[1, 1, 0], [1, 1, 0], [1, 1, 0]])
+        x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])
+        self.assertTrue(mask_rowcols(x).all() is masked)
+        self.assertTrue(mask_rowcols(x, 0).all() is masked)
+        self.assertTrue(mask_rowcols(x, 1).all() is masked)
+        self.assertTrue(mask_rowcols(x).mask.all())
+        self.assertTrue(mask_rowcols(x, 0).mask.all())
+        self.assertTrue(mask_rowcols(x, 1).mask.all())
+
+    def test_dot(self):
+        # Tests dot product
+        n = np.arange(1, 7)
+        #
+        m = [1, 0, 0, 0, 0, 0]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 1], [1, 0]])
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[1, 1, 1], [1, 0, 0], [1, 0, 0]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        m = [0, 0, 0, 0, 0, 1]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[0, 1], [1, 1]])
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [1, 1, 1]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        assert_equal(c, dot(a, b))
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        m = [0, 0, 0, 0, 0, 0]
+        a = masked_array(n, mask=m).reshape(2, 3)
+        b = masked_array(n, mask=m).reshape(3, 2)
+        c = dot(a, b)
+        assert_equal(c.mask, nomask)
+        c = dot(b, a)
+        assert_equal(c.mask, nomask)
+        #
+        a = masked_array(n, mask=[1, 0, 0, 0, 0, 0]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 1], [0, 0]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[1, 0, 0], [1, 0, 0], [1, 0, 0]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[0, 0], [1, 1]])
+        c = dot(a, b)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [0, 0, 1]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+        #
+        a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3)
+        b = masked_array(n, mask=[0, 0, 1, 0, 0, 0]).reshape(3, 2)
+        c = dot(a, b, strict=True)
+        assert_equal(c.mask, [[1, 0], [1, 1]])
+        c = dot(a, b, strict=False)
+        assert_equal(c, np.dot(a.filled(0), b.filled(0)))
+        c = dot(b, a, strict=True)
+        assert_equal(c.mask, [[0, 0, 1], [1, 1, 1], [0, 0, 1]])
+        c = dot(b, a, strict=False)
+        assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+
+    def test_dot_returns_maskedarray(self):
+        # See gh-6611
+        a = np.eye(3)
+        b = array(a)
+        assert_(type(dot(a, a)) is MaskedArray)
+        assert_(type(dot(a, b)) is MaskedArray)
+        assert_(type(dot(b, a)) is MaskedArray)
+        assert_(type(dot(b, b)) is MaskedArray)
+
+    def test_dot_out(self):
+        a = array(np.eye(3))
+        out = array(np.zeros((3, 3)))
+        res = dot(a, a, out=out)
+        assert_(res is out)
+        assert_equal(a, res)
+
+
+class TestApplyAlongAxis(TestCase):
+    # Tests 2D functions
+    def test_3d(self):
+        a = arange(12.).reshape(2, 2, 3)
+
+        def myfunc(b):
+            return b[1]
+
+        xa = apply_along_axis(myfunc, 2, a)
+        assert_equal(xa, [[1, 4], [7, 10]])
+
+    # Tests kwargs functions
+    def test_3d_kwargs(self):
+        a = arange(12).reshape(2, 2, 3)
+
+        def myfunc(b, offset=0):
+            return b[1+offset]
+
+        xa = apply_along_axis(myfunc, 2, a, offset=1)
+        assert_equal(xa, [[2, 5], [8, 11]])
+
+
+class TestApplyOverAxes(TestCase):
+    # Tests apply_over_axes
+    def test_basic(self):
+        a = arange(24).reshape(2, 3, 4)
+        test = apply_over_axes(np.sum, a, [0, 2])
+        ctrl = np.array([[[60], [92], [124]]])
+        assert_equal(test, ctrl)
+        a[(a % 2).astype(np.bool)] = masked
+        test = apply_over_axes(np.sum, a, [0, 2])
+        ctrl = np.array([[[28], [44], [60]]])
+        assert_equal(test, ctrl)
+
+
+class TestMedian(TestCase):
+    def test_pytype(self):
+        r = np.ma.median([[np.inf, np.inf], [np.inf, np.inf]], axis=-1)
+        assert_equal(r, np.inf)
+
+    def test_non_masked(self):
+        assert_equal(np.ma.median(np.arange(9)), 4.)
+        assert_equal(np.ma.median(range(9)), 4)
+
+    def test_2d(self):
+        # Tests median w/ 2D
+        (n, p) = (101, 30)
+        x = masked_array(np.linspace(-1., 1., n),)
+        x[:10] = x[-10:] = masked
+        z = masked_array(np.empty((n, p), dtype=float))
+        z[:, 0] = x[:]
+        idx = np.arange(len(x))
+        for i in range(1, p):
+            np.random.shuffle(idx)
+            z[:, i] = x[idx]
+        assert_equal(median(z[:, 0]), 0)
+        assert_equal(median(z), 0)
+        assert_equal(median(z, axis=0), np.zeros(p))
+        assert_equal(median(z.T, axis=1), np.zeros(p))
+
+    def test_2d_waxis(self):
+        # Tests median w/ 2D arrays and different axis.
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        assert_equal(median(x), 14.5)
+        assert_equal(median(x, axis=0), [13.5, 14.5, 15.5])
+        assert_equal(median(x, axis=1), [0, 0, 0, 10, 13, 16, 19, 0, 0, 0])
+        assert_equal(median(x, axis=1).mask, [1, 1, 1, 0, 0, 0, 0, 1, 1, 1])
+
+    def test_3d(self):
+        # Tests median w/ 3D
+        x = np.ma.arange(24).reshape(3, 4, 2)
+        x[x % 3 == 0] = masked
+        assert_equal(median(x, 0), [[12, 9], [6, 15], [12, 9], [18, 15]])
+        x.shape = (4, 3, 2)
+        assert_equal(median(x, 0), [[99, 10], [11, 99], [13, 14]])
+        x = np.ma.arange(24).reshape(4, 3, 2)
+        x[x % 5 == 0] = masked
+        assert_equal(median(x, 0), [[12, 10], [8, 9], [16, 17]])
+
+    def test_neg_axis(self):
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        assert_equal(median(x, axis=-1), median(x, axis=1))
+
+    def test_out(self):
+        x = masked_array(np.arange(30).reshape(10, 3))
+        x[:3] = x[-3:] = masked
+        out = masked_array(np.ones(10))
+        r = median(x, axis=1, out=out)
+        assert_equal(r, out)
+        assert_(type(r) == MaskedArray)
+
+
+class TestCov(TestCase):
+
+    def setUp(self):
+        self.data = array(np.random.rand(12))
+
+    def test_1d_wo_missing(self):
+        # Test cov on 1D variable w/o missing values
+        x = self.data
+        assert_almost_equal(np.cov(x), cov(x))
+        assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(x, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+
+    def test_2d_wo_missing(self):
+        # Test cov on 1 2D variable w/o missing values
+        x = self.data.reshape(3, 4)
+        assert_almost_equal(np.cov(x), cov(x))
+        assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(x, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+
+    def test_1d_w_missing(self):
+        # Test cov 1 1D variable w/missing values
+        x = self.data
+        x[-1] = masked
+        x -= x.mean()
+        nx = x.compressed()
+        assert_almost_equal(np.cov(nx), cov(x))
+        assert_almost_equal(np.cov(nx, rowvar=False), cov(x, rowvar=False))
+        assert_almost_equal(np.cov(nx, rowvar=False, bias=True),
+                            cov(x, rowvar=False, bias=True))
+        #
+        try:
+            cov(x, allow_masked=False)
+        except ValueError:
+            pass
+        #
+        # 2 1D variables w/ missing values
+        nx = x[1:-1]
+        assert_almost_equal(np.cov(nx, nx[::-1]), cov(x, x[::-1]))
+        assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False),
+                            cov(x, x[::-1], rowvar=False))
+        assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False, bias=True),
+                            cov(x, x[::-1], rowvar=False, bias=True))
+
+    def test_2d_w_missing(self):
+        # Test cov on 2D variable w/ missing value
+        x = self.data
+        x[-1] = masked
+        x = x.reshape(3, 4)
+        valid = np.logical_not(getmaskarray(x)).astype(int)
+        frac = np.dot(valid, valid.T)
+        xf = (x - x.mean(1)[:, None]).filled(0)
+        assert_almost_equal(cov(x),
+                            np.cov(xf) * (x.shape[1] - 1) / (frac - 1.))
+        assert_almost_equal(cov(x, bias=True),
+                            np.cov(xf, bias=True) * x.shape[1] / frac)
+        frac = np.dot(valid.T, valid)
+        xf = (x - x.mean(0)).filled(0)
+        assert_almost_equal(cov(x, rowvar=False),
+                            (np.cov(xf, rowvar=False) *
+                             (x.shape[0] - 1) / (frac - 1.)))
+        assert_almost_equal(cov(x, rowvar=False, bias=True),
+                            (np.cov(xf, rowvar=False, bias=True) *
+                             x.shape[0] / frac))
+
+
+class catch_warn_mae(clear_and_catch_warnings):
+    """ Context manager to catch, reset warnings in ma.extras module
+    """
+    class_modules = (mae,)
+
+
+class TestCorrcoef(TestCase):
+
+    def setUp(self):
+        self.data = array(np.random.rand(12))
+        self.data2 = array(np.random.rand(12))
+
+    def test_ddof(self):
+        # ddof raises DeprecationWarning
+        x, y = self.data, self.data2
+        expected = np.corrcoef(x)
+        expected2 = np.corrcoef(x, y)
+        with catch_warn_mae():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, x, ddof=-1)
+            warnings.simplefilter("ignore")
+            # ddof has no or negligible effect on the function
+            assert_almost_equal(np.corrcoef(x, ddof=0), corrcoef(x, ddof=0))
+            assert_almost_equal(corrcoef(x, ddof=-1), expected)
+            assert_almost_equal(corrcoef(x, y, ddof=-1), expected2)
+            assert_almost_equal(corrcoef(x, ddof=3), expected)
+            assert_almost_equal(corrcoef(x, y, ddof=3), expected2)
+
+    def test_bias(self):
+        x, y = self.data, self.data2
+        expected = np.corrcoef(x)
+        # bias raises DeprecationWarning
+        with catch_warn_mae():
+            warnings.simplefilter("always")
+            assert_warns(DeprecationWarning, corrcoef, x, y, True, False)
+            assert_warns(DeprecationWarning, corrcoef, x, y, True, True)
+            assert_warns(DeprecationWarning, corrcoef, x, bias=False)
+            warnings.simplefilter("ignore")
+            # bias has no or negligible effect on the function
+            assert_almost_equal(corrcoef(x, bias=1), expected)
+
+    def test_1d_wo_missing(self):
+        # Test cov on 1D variable w/o missing values
+        x = self.data
+        assert_almost_equal(np.corrcoef(x), corrcoef(x))
+        assert_almost_equal(np.corrcoef(x, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+
+    def test_2d_wo_missing(self):
+        # Test corrcoef on 1 2D variable w/o missing values
+        x = self.data.reshape(3, 4)
+        assert_almost_equal(np.corrcoef(x), corrcoef(x))
+        assert_almost_equal(np.corrcoef(x, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+
+    def test_1d_w_missing(self):
+        # Test corrcoef 1 1D variable w/missing values
+        x = self.data
+        x[-1] = masked
+        x -= x.mean()
+        nx = x.compressed()
+        assert_almost_equal(np.corrcoef(nx), corrcoef(x))
+        assert_almost_equal(np.corrcoef(nx, rowvar=False),
+                            corrcoef(x, rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            assert_almost_equal(np.corrcoef(nx, rowvar=False, bias=True),
+                                corrcoef(x, rowvar=False, bias=True))
+        try:
+            corrcoef(x, allow_masked=False)
+        except ValueError:
+            pass
+        # 2 1D variables w/ missing values
+        nx = x[1:-1]
+        assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1]))
+        assert_almost_equal(np.corrcoef(nx, nx[::-1], rowvar=False),
+                            corrcoef(x, x[::-1], rowvar=False))
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            # ddof and bias have no or negligible effect on the function
+            assert_almost_equal(np.corrcoef(nx, nx[::-1]),
+                                corrcoef(x, x[::-1], bias=1))
+            assert_almost_equal(np.corrcoef(nx, nx[::-1]),
+                                corrcoef(x, x[::-1], ddof=2))
+
+    def test_2d_w_missing(self):
+        # Test corrcoef on 2D variable w/ missing value
+        x = self.data
+        x[-1] = masked
+        x = x.reshape(3, 4)
+
+        test = corrcoef(x)
+        control = np.corrcoef(x)
+        assert_almost_equal(test[:-1, :-1], control[:-1, :-1])
+        with catch_warn_mae():
+            warnings.simplefilter("ignore")
+            # ddof and bias have no or negligible effect on the function
+            assert_almost_equal(corrcoef(x, ddof=-2)[:-1, :-1],
+                                control[:-1, :-1])
+            assert_almost_equal(corrcoef(x, ddof=3)[:-1, :-1],
+                                control[:-1, :-1])
+            assert_almost_equal(corrcoef(x, bias=1)[:-1, :-1],
+                                control[:-1, :-1])
+
+
+class TestPolynomial(TestCase):
+    #
+    def test_polyfit(self):
+        # Tests polyfit
+        # On ndarrays
+        x = np.random.rand(10)
+        y = np.random.rand(20).reshape(-1, 2)
+        assert_almost_equal(polyfit(x, y, 3), np.polyfit(x, y, 3))
+        # ON 1D maskedarrays
+        x = x.view(MaskedArray)
+        x[0] = masked
+        y = y.view(MaskedArray)
+        y[0, 0] = y[-1, -1] = masked
+        #
+        (C, R, K, S, D) = polyfit(x, y[:, 0], 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:], y[1:, 0].compressed(), 3,
+                                     full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        (C, R, K, S, D) = polyfit(x, y[:, -1], 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1, -1], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+        #
+        w = np.random.rand(10) + 1
+        wo = w.copy()
+        xs = x[1:-1]
+        ys = y[1:-1]
+        ws = w[1:-1]
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True, w=w)
+        (c, r, k, s, d) = np.polyfit(xs, ys, 3, full=True, w=ws)
+        assert_equal(w, wo)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+
+    def test_polyfit_with_masked_NaNs(self):
+        x = np.random.rand(10)
+        y = np.random.rand(20).reshape(-1, 2)
+
+        x[0] = np.nan
+        y[-1,-1] = np.nan
+        x = x.view(MaskedArray)
+        y = y.view(MaskedArray)
+        x[0] = masked
+        y[-1,-1] = masked
+
+        (C, R, K, S, D) = polyfit(x, y, 3, full=True)
+        (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True)
+        for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)):
+            assert_almost_equal(a, a_)
+
+
+class TestArraySetOps(TestCase):
+
+    def test_unique_onlist(self):
+        # Test unique on list
+        data = [1, 1, 1, 2, 2, 3]
+        test = unique(data, return_index=True, return_inverse=True)
+        self.assertTrue(isinstance(test[0], MaskedArray))
+        assert_equal(test[0], masked_array([1, 2, 3], mask=[0, 0, 0]))
+        assert_equal(test[1], [0, 3, 5])
+        assert_equal(test[2], [0, 0, 0, 1, 1, 2])
+
+    def test_unique_onmaskedarray(self):
+        # Test unique on masked data w/use_mask=True
+        data = masked_array([1, 1, 1, 2, 2, 3], mask=[0, 0, 1, 0, 1, 0])
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1]))
+        assert_equal(test[1], [0, 3, 5, 2])
+        assert_equal(test[2], [0, 0, 3, 1, 3, 2])
+        #
+        data.fill_value = 3
+        data = masked_array(data=[1, 1, 1, 2, 2, 3],
+                            mask=[0, 0, 1, 0, 1, 0], fill_value=3)
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1]))
+        assert_equal(test[1], [0, 3, 5, 2])
+        assert_equal(test[2], [0, 0, 3, 1, 3, 2])
+
+    def test_unique_allmasked(self):
+        # Test all masked
+        data = masked_array([1, 1, 1], mask=True)
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array([1, ], mask=[True]))
+        assert_equal(test[1], [0])
+        assert_equal(test[2], [0, 0, 0])
+        #
+        # Test masked
+        data = masked
+        test = unique(data, return_index=True, return_inverse=True)
+        assert_equal(test[0], masked_array(masked))
+        assert_equal(test[1], [0])
+        assert_equal(test[2], [0])
+
+    def test_ediff1d(self):
+        # Tests mediff1d
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        control = array([1, 1, 1, 4], mask=[1, 0, 0, 1])
+        test = ediff1d(x)
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_tobegin(self):
+        # Test ediff1d w/ to_begin
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_begin=masked)
+        control = array([0, 1, 1, 1, 4], mask=[1, 1, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_begin=[1, 2, 3])
+        control = array([1, 2, 3, 1, 1, 1, 4], mask=[0, 0, 0, 1, 0, 0, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_toend(self):
+        # Test ediff1d w/ to_end
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_end=masked)
+        control = array([1, 1, 1, 4, 0], mask=[1, 0, 0, 1, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=[1, 2, 3])
+        control = array([1, 1, 1, 4, 1, 2, 3], mask=[1, 0, 0, 1, 0, 0, 0])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_tobegin_toend(self):
+        # Test ediff1d w/ to_begin and to_end
+        x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1])
+        test = ediff1d(x, to_end=masked, to_begin=masked)
+        control = array([0, 1, 1, 1, 4, 0], mask=[1, 1, 0, 0, 1, 1])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=[1, 2, 3], to_begin=masked)
+        control = array([0, 1, 1, 1, 4, 1, 2, 3],
+                        mask=[1, 1, 0, 0, 1, 0, 0, 0])
+        assert_equal(test, control)
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_ediff1d_ndarray(self):
+        # Test ediff1d w/ a ndarray
+        x = np.arange(5)
+        test = ediff1d(x)
+        control = array([1, 1, 1, 1], mask=[0, 0, 0, 0])
+        assert_equal(test, control)
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+        #
+        test = ediff1d(x, to_end=masked, to_begin=masked)
+        control = array([0, 1, 1, 1, 1, 0], mask=[1, 0, 0, 0, 0, 1])
+        self.assertTrue(isinstance(test, MaskedArray))
+        assert_equal(test.data, control.data)
+        assert_equal(test.mask, control.mask)
+
+    def test_intersect1d(self):
+        # Test intersect1d
+        x = array([1, 3, 3, 3], mask=[0, 0, 0, 1])
+        y = array([3, 1, 1, 1], mask=[0, 0, 0, 1])
+        test = intersect1d(x, y)
+        control = array([1, 3, -1], mask=[0, 0, 1])
+        assert_equal(test, control)
+
+    def test_setxor1d(self):
+        # Test setxor1d
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = setxor1d(a, b)
+        assert_equal(test, array([3, 4, 7]))
+        #
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = [1, 2, 3, 4, 5]
+        test = setxor1d(a, b)
+        assert_equal(test, array([3, 4, 7, -1], mask=[0, 0, 0, 1]))
+        #
+        a = array([1, 2, 3])
+        b = array([6, 5, 4])
+        test = setxor1d(a, b)
+        assert_(isinstance(test, MaskedArray))
+        assert_equal(test, [1, 2, 3, 4, 5, 6])
+        #
+        a = array([1, 8, 2, 3], mask=[0, 1, 0, 0])
+        b = array([6, 5, 4, 8], mask=[0, 0, 0, 1])
+        test = setxor1d(a, b)
+        assert_(isinstance(test, MaskedArray))
+        assert_equal(test, [1, 2, 3, 4, 5, 6])
+        #
+        assert_array_equal([], setxor1d([], []))
+
+    def test_in1d(self):
+        # Test in1d
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = in1d(a, b)
+        assert_equal(test, [True, True, True, False, True])
+        #
+        a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 5, -1], mask=[0, 0, 1])
+        test = in1d(a, b)
+        assert_equal(test, [True, True, False, True, True])
+        #
+        assert_array_equal([], in1d([], []))
+
+    def test_in1d_invert(self):
+        # Test in1d's invert parameter
+        a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+        a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1])
+        b = array([1, 5, -1], mask=[0, 0, 1])
+        assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+        assert_array_equal([], in1d([], [], invert=True))
+
+    def test_union1d(self):
+        # Test union1d
+        a = array([1, 2, 5, 7, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+        test = union1d(a, b)
+        control = array([1, 2, 3, 4, 5, 7, -1], mask=[0, 0, 0, 0, 0, 0, 1])
+        assert_equal(test, control)
+        #
+        assert_array_equal([], union1d([], []))
+
+    def test_setdiff1d(self):
+        # Test setdiff1d
+        a = array([6, 5, 4, 7, 7, 1, 2, 1], mask=[0, 0, 0, 0, 0, 0, 0, 1])
+        b = array([2, 4, 3, 3, 2, 1, 5])
+        test = setdiff1d(a, b)
+        assert_equal(test, array([6, 7, -1], mask=[0, 0, 1]))
+        #
+        a = arange(10)
+        b = arange(8)
+        assert_equal(setdiff1d(a, b), array([8, 9]))
+        a = array([], np.uint32, mask=[])
+        assert_equal(setdiff1d(a, []).dtype, np.uint32)
+
+    def test_setdiff1d_char_array(self):
+        # Test setdiff1d_charray
+        a = np.array(['a', 'b', 'c'])
+        b = np.array(['a', 'b', 's'])
+        assert_array_equal(setdiff1d(a, b), np.array(['c']))
+
+
+class TestShapeBase(TestCase):
+
+    def test_atleast2d(self):
+        # Test atleast_2d
+        a = masked_array([0, 1, 2], mask=[0, 1, 0])
+        b = atleast_2d(a)
+        assert_equal(b.shape, (1, 3))
+        assert_equal(b.mask.shape, b.data.shape)
+        assert_equal(a.shape, (3,))
+        assert_equal(a.mask.shape, a.data.shape)
+
+    def test_shape_scalar(self):
+        # the atleast and diagflat function should work with scalars
+        # GitHub issue #3367
+        b = atleast_1d(1.0)
+        assert_equal(b.shape, (1, ))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = atleast_2d(1.0)
+        assert_equal(b.shape, (1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = atleast_3d(1.0)
+        assert_equal(b.shape, (1, 1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+        b = diagflat(1.0)
+        assert_equal(b.shape, (1, 1))
+        assert_equal(b.mask.shape, b.data.shape)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
new file mode 100644
index 0000000000..574c652710
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
@@ -0,0 +1,516 @@
+# pylint: disable-msg=W0611, W0612, W0511,R0201
+"""Tests suite for mrecords.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import pickle
+
+import numpy as np
+import numpy.ma as ma
+from numpy import recarray
+from numpy.compat import asbytes, asbytes_nested
+from numpy.ma import masked, nomask
+from numpy.testing import TestCase, run_module_suite, temppath
+from numpy.core.records import (
+    fromrecords as recfromrecords, fromarrays as recfromarrays
+    )
+from numpy.ma.mrecords import (
+    MaskedRecords, mrecarray, fromarrays, fromtextfile, fromrecords,
+    addfield
+    )
+from numpy.ma.testutils import (
+    assert_, assert_equal,
+    assert_equal_records,
+    )
+
+
+class TestMRecords(TestCase):
+    # Base test class for MaskedArrays.
+    def __init__(self, *args, **kwds):
+        TestCase.__init__(self, *args, **kwds)
+        self.setup()
+
+    def setup(self):
+        # Generic setup
+        ilist = [1, 2, 3, 4, 5]
+        flist = [1.1, 2.2, 3.3, 4.4, 5.5]
+        slist = asbytes_nested(['one', 'two', 'three', 'four', 'five'])
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mask = [0, 1, 0, 0, 1]
+        self.base = ma.array(list(zip(ilist, flist, slist)),
+                             mask=mask, dtype=ddtype)
+
+    def test_byview(self):
+        # Test creation by view
+        base = self.base
+        mbase = base.view(mrecarray)
+        assert_equal(mbase.recordmask, base.recordmask)
+        assert_equal_records(mbase._mask, base._mask)
+        assert_(isinstance(mbase._data, recarray))
+        assert_equal_records(mbase._data, base._data.view(recarray))
+        for field in ('a', 'b', 'c'):
+            assert_equal(base[field], mbase[field])
+        assert_equal_records(mbase.view(mrecarray), mbase)
+
+    def test_get(self):
+        # Tests fields retrieval
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # As fields..........
+        for field in ('a', 'b', 'c'):
+            assert_equal(getattr(mbase, field), mbase[field])
+            assert_equal(base[field], mbase[field])
+        # as elements .......
+        mbase_first = mbase[0]
+        assert_(isinstance(mbase_first, mrecarray))
+        assert_equal(mbase_first.dtype, mbase.dtype)
+        assert_equal(mbase_first.tolist(), (1, 1.1, asbytes('one')))
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_first.recordmask, nomask)
+        assert_equal(mbase_first._mask.item(), (False, False, False))
+        assert_equal(mbase_first['a'], mbase['a'][0])
+        mbase_last = mbase[-1]
+        assert_(isinstance(mbase_last, mrecarray))
+        assert_equal(mbase_last.dtype, mbase.dtype)
+        assert_equal(mbase_last.tolist(), (None, None, None))
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_last.recordmask, True)
+        assert_equal(mbase_last._mask.item(), (True, True, True))
+        assert_equal(mbase_last['a'], mbase['a'][-1])
+        assert_((mbase_last['a'] is masked))
+        # as slice ..........
+        mbase_sl = mbase[:2]
+        assert_(isinstance(mbase_sl, mrecarray))
+        assert_equal(mbase_sl.dtype, mbase.dtype)
+        # Used to be mask, now it's recordmask
+        assert_equal(mbase_sl.recordmask, [0, 1])
+        assert_equal_records(mbase_sl.mask,
+                             np.array([(False, False, False),
+                                       (True, True, True)],
+                                      dtype=mbase._mask.dtype))
+        assert_equal_records(mbase_sl, base[:2].view(mrecarray))
+        for field in ('a', 'b', 'c'):
+            assert_equal(getattr(mbase_sl, field), base[:2][field])
+
+    def test_set_fields(self):
+        # Tests setting fields.
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase = mbase.copy()
+        mbase.fill_value = (999999, 1e20, 'N/A')
+        # Change the data, the mask should be conserved
+        mbase.a._data[:] = 5
+        assert_equal(mbase['a']._data, [5, 5, 5, 5, 5])
+        assert_equal(mbase['a']._mask, [0, 1, 0, 0, 1])
+        # Change the elements, and the mask will follow
+        mbase.a = 1
+        assert_equal(mbase['a']._data, [1]*5)
+        assert_equal(ma.getmaskarray(mbase['a']), [0]*5)
+        # Use to be _mask, now it's recordmask
+        assert_equal(mbase.recordmask, [False]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 0),
+                               (0, 1, 1),
+                               (0, 0, 0),
+                               (0, 0, 0),
+                               (0, 1, 1)],
+                              dtype=bool))
+        # Set a field to mask ........................
+        mbase.c = masked
+        # Use to be mask, and now it's still mask !
+        assert_equal(mbase.c.mask, [1]*5)
+        assert_equal(mbase.c.recordmask, [1]*5)
+        assert_equal(ma.getmaskarray(mbase['c']), [1]*5)
+        assert_equal(ma.getdata(mbase['c']), [asbytes('N/A')]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 1),
+                               (0, 1, 1),
+                               (0, 0, 1),
+                               (0, 0, 1),
+                               (0, 1, 1)],
+                              dtype=bool))
+        # Set fields by slices .......................
+        mbase = base.view(mrecarray).copy()
+        mbase.a[3:] = 5
+        assert_equal(mbase.a, [1, 2, 3, 5, 5])
+        assert_equal(mbase.a._mask, [0, 1, 0, 0, 0])
+        mbase.b[3:] = masked
+        assert_equal(mbase.b, base['b'])
+        assert_equal(mbase.b._mask, [0, 1, 0, 1, 1])
+        # Set fields globally..........................
+        ndtype = [('alpha', '|S1'), ('num', int)]
+        data = ma.array([('a', 1), ('b', 2), ('c', 3)], dtype=ndtype)
+        rdata = data.view(MaskedRecords)
+        val = ma.array([10, 20, 30], mask=[1, 0, 0])
+
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            rdata['num'] = val
+            assert_equal(rdata.num, val)
+            assert_equal(rdata.num.mask, [1, 0, 0])
+
+    def test_set_fields_mask(self):
+        # Tests setting the mask of a field.
+        base = self.base.copy()
+        # This one has already a mask....
+        mbase = base.view(mrecarray)
+        mbase['a'][-2] = masked
+        assert_equal(mbase.a, [1, 2, 3, 4, 5])
+        assert_equal(mbase.a._mask, [0, 1, 0, 1, 1])
+        # This one has not yet
+        mbase = fromarrays([np.arange(5), np.random.rand(5)],
+                           dtype=[('a', int), ('b', float)])
+        mbase['a'][-2] = masked
+        assert_equal(mbase.a, [0, 1, 2, 3, 4])
+        assert_equal(mbase.a._mask, [0, 0, 0, 1, 0])
+
+    def test_set_mask(self):
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # Set the mask to True .......................
+        mbase.mask = masked
+        assert_equal(ma.getmaskarray(mbase['b']), [1]*5)
+        assert_equal(mbase['a']._mask, mbase['b']._mask)
+        assert_equal(mbase['a']._mask, mbase['c']._mask)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(1, 1, 1)]*5, dtype=bool))
+        # Delete the mask ............................
+        mbase.mask = nomask
+        assert_equal(ma.getmaskarray(mbase['c']), [0]*5)
+        assert_equal(mbase._mask.tolist(),
+                     np.array([(0, 0, 0)]*5, dtype=bool))
+
+    def test_set_mask_fromarray(self):
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        # Sets the mask w/ an array
+        mbase.mask = [1, 0, 0, 0, 1]
+        assert_equal(mbase.a.mask, [1, 0, 0, 0, 1])
+        assert_equal(mbase.b.mask, [1, 0, 0, 0, 1])
+        assert_equal(mbase.c.mask, [1, 0, 0, 0, 1])
+        # Yay, once more !
+        mbase.mask = [0, 0, 0, 0, 1]
+        assert_equal(mbase.a.mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.b.mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.c.mask, [0, 0, 0, 0, 1])
+
+    def test_set_mask_fromfields(self):
+        mbase = self.base.copy().view(mrecarray)
+
+        nmask = np.array(
+            [(0, 1, 0), (0, 1, 0), (1, 0, 1), (1, 0, 1), (0, 0, 0)],
+            dtype=[('a', bool), ('b', bool), ('c', bool)])
+        mbase.mask = nmask
+        assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
+        assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
+        assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
+        # Reinitalizes and redo
+        mbase.mask = False
+        mbase.fieldmask = nmask
+        assert_equal(mbase.a.mask, [0, 0, 1, 1, 0])
+        assert_equal(mbase.b.mask, [1, 1, 0, 0, 0])
+        assert_equal(mbase.c.mask, [0, 0, 1, 1, 0])
+
+    def test_set_elements(self):
+        base = self.base.copy()
+        # Set an element to mask .....................
+        mbase = base.view(mrecarray).copy()
+        mbase[-2] = masked
+        assert_equal(
+            mbase._mask.tolist(),
+            np.array([(0, 0, 0), (1, 1, 1), (0, 0, 0), (1, 1, 1), (1, 1, 1)],
+                     dtype=bool))
+        # Used to be mask, now it's recordmask!
+        assert_equal(mbase.recordmask, [0, 1, 0, 1, 1])
+        # Set slices .................................
+        mbase = base.view(mrecarray).copy()
+        mbase[:2] = (5, 5, 5)
+        assert_equal(mbase.a._data, [5, 5, 3, 4, 5])
+        assert_equal(mbase.a._mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.b._data, [5., 5., 3.3, 4.4, 5.5])
+        assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
+        assert_equal(mbase.c._data,
+                     asbytes_nested(['5', '5', 'three', 'four', 'five']))
+        assert_equal(mbase.b._mask, [0, 0, 0, 0, 1])
+
+        mbase = base.view(mrecarray).copy()
+        mbase[:2] = masked
+        assert_equal(mbase.a._data, [1, 2, 3, 4, 5])
+        assert_equal(mbase.a._mask, [1, 1, 0, 0, 1])
+        assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 4.4, 5.5])
+        assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
+        assert_equal(mbase.c._data,
+                     asbytes_nested(['one', 'two', 'three', 'four', 'five']))
+        assert_equal(mbase.b._mask, [1, 1, 0, 0, 1])
+
+    def test_setslices_hardmask(self):
+        # Tests setting slices w/ hardmask.
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase.harden_mask()
+        try:
+            mbase[-2:] = (5, 5, 5)
+            assert_equal(mbase.a._data, [1, 2, 3, 5, 5])
+            assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 5, 5.5])
+            assert_equal(mbase.c._data,
+                         asbytes_nested(['one', 'two', 'three', '5', 'five']))
+            assert_equal(mbase.a._mask, [0, 1, 0, 0, 1])
+            assert_equal(mbase.b._mask, mbase.a._mask)
+            assert_equal(mbase.b._mask, mbase.c._mask)
+        except NotImplementedError:
+            # OK, not implemented yet...
+            pass
+        except AssertionError:
+            raise
+        else:
+            raise Exception("Flexible hard masks should be supported !")
+        # Not using a tuple should crash
+        try:
+            mbase[-2:] = 3
+        except (NotImplementedError, TypeError):
+            pass
+        else:
+            raise TypeError("Should have expected a readable buffer object!")
+
+    def test_hardmask(self):
+        # Test hardmask
+        base = self.base.copy()
+        mbase = base.view(mrecarray)
+        mbase.harden_mask()
+        self.assertTrue(mbase._hardmask)
+        mbase.mask = nomask
+        assert_equal_records(mbase._mask, base._mask)
+        mbase.soften_mask()
+        self.assertTrue(not mbase._hardmask)
+        mbase.mask = nomask
+        # So, the mask of a field is no longer set to nomask...
+        assert_equal_records(mbase._mask,
+                             ma.make_mask_none(base.shape, base.dtype))
+        self.assertTrue(ma.make_mask(mbase['b']._mask) is nomask)
+        assert_equal(mbase['a']._mask, mbase['b']._mask)
+
+    def test_pickling(self):
+        # Test pickling
+        base = self.base.copy()
+        mrec = base.view(mrecarray)
+        _ = pickle.dumps(mrec)
+        mrec_ = pickle.loads(_)
+        assert_equal(mrec_.dtype, mrec.dtype)
+        assert_equal_records(mrec_._data, mrec._data)
+        assert_equal(mrec_._mask, mrec._mask)
+        assert_equal_records(mrec_._mask, mrec._mask)
+
+    def test_filled(self):
+        # Test filling the array
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(99999, 99999., 'N/A'))
+        mrecfilled = mrec.filled()
+        assert_equal(mrecfilled['a'], np.array((1, 2, 99999), dtype=int))
+        assert_equal(mrecfilled['b'], np.array((1.1, 2.2, 99999.),
+                                               dtype=float))
+        assert_equal(mrecfilled['c'], np.array(('one', 'two', 'N/A'),
+                                               dtype='|S8'))
+
+    def test_tolist(self):
+        # Test tolist.
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[1, 0, 0], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(99999, 99999., 'N/A'))
+
+        assert_equal(mrec.tolist(),
+                     [(1, 1.1, None), (2, 2.2, asbytes('two')),
+                      (None, None, asbytes('three'))])
+
+    def test_withnames(self):
+        # Test the creation w/ format and names
+        x = mrecarray(1, formats=float, names='base')
+        x[0]['base'] = 10
+        assert_equal(x['base'][0], 10)
+
+    def test_exotic_formats(self):
+        # Test that 'exotic' formats are processed properly
+        easy = mrecarray(1, dtype=[('i', int), ('s', '|S8'), ('f', float)])
+        easy[0] = masked
+        assert_equal(easy.filled(1).item(), (1, asbytes('1'), 1.))
+
+        solo = mrecarray(1, dtype=[('f0', '<f8', (2, 2))])
+        solo[0] = masked
+        assert_equal(solo.filled(1).item(),
+                     np.array((1,), dtype=solo.dtype).item())
+
+        mult = mrecarray(2, dtype="i4, (2,3)float, float")
+        mult[0] = masked
+        mult[1] = (1, 1, 1)
+        mult.filled(0)
+        assert_equal_records(mult.filled(0),
+                             np.array([(0, 0, 0), (1, 1, 1)],
+                                      dtype=mult.dtype))
+
+
+class TestView(TestCase):
+
+    def setUp(self):
+        (a, b) = (np.arange(10), np.random.rand(10))
+        ndtype = [('a', np.float), ('b', np.float)]
+        arr = np.array(list(zip(a, b)), dtype=ndtype)
+
+        mrec = fromarrays([a, b], dtype=ndtype, fill_value=(-9., -99.))
+        mrec.mask[3] = (False, True)
+        self.data = (mrec, a, b, arr)
+
+    def test_view_by_itself(self):
+        (mrec, a, b, arr) = self.data
+        test = mrec.view()
+        self.assertTrue(isinstance(test, MaskedRecords))
+        assert_equal_records(test, mrec)
+        assert_equal_records(test._mask, mrec._mask)
+
+    def test_view_simple_dtype(self):
+        (mrec, a, b, arr) = self.data
+        ntype = (np.float, 2)
+        test = mrec.view(ntype)
+        self.assertTrue(isinstance(test, ma.MaskedArray))
+        assert_equal(test, np.array(list(zip(a, b)), dtype=np.float))
+        self.assertTrue(test[3, 1] is ma.masked)
+
+    def test_view_flexible_type(self):
+        (mrec, a, b, arr) = self.data
+        alttype = [('A', np.float), ('B', np.float)]
+        test = mrec.view(alttype)
+        self.assertTrue(isinstance(test, MaskedRecords))
+        assert_equal_records(test, arr.view(alttype))
+        self.assertTrue(test['B'][3] is masked)
+        assert_equal(test.dtype, np.dtype(alttype))
+        self.assertTrue(test._fill_value is None)
+
+
+##############################################################################
+class TestMRecordsImport(TestCase):
+    # Base test class for MaskedArrays.
+    def __init__(self, *args, **kwds):
+        TestCase.__init__(self, *args, **kwds)
+        self.setup()
+
+    def setup(self):
+        # Generic setup
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(list(map(asbytes, ['one', 'two', 'three'])),
+                      mask=[0, 0, 1], dtype='|S8')
+        ddtype = [('a', int), ('b', float), ('c', '|S8')]
+        mrec = fromarrays([_a, _b, _c], dtype=ddtype,
+                          fill_value=(asbytes('99999'), asbytes('99999.'),
+                                      asbytes('N/A')))
+        nrec = recfromarrays((_a._data, _b._data, _c._data), dtype=ddtype)
+        self.data = (mrec, nrec, ddtype)
+
+    def test_fromarrays(self):
+        _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int)
+        _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float)
+        _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8')
+        (mrec, nrec, _) = self.data
+        for (f, l) in zip(('a', 'b', 'c'), (_a, _b, _c)):
+            assert_equal(getattr(mrec, f)._mask, l._mask)
+        # One record only
+        _x = ma.array([1, 1.1, 'one'], mask=[1, 0, 0],)
+        assert_equal_records(fromarrays(_x, dtype=mrec.dtype), mrec[0])
+
+    def test_fromrecords(self):
+        # Test construction from records.
+        (mrec, nrec, ddtype) = self.data
+        #......
+        palist = [(1, 'abc', 3.7000002861022949, 0),
+                  (2, 'xy', 6.6999998092651367, 1),
+                  (0, ' ', 0.40000000596046448, 0)]
+        pa = recfromrecords(palist, names='c1, c2, c3, c4')
+        mpa = fromrecords(palist, names='c1, c2, c3, c4')
+        assert_equal_records(pa, mpa)
+        #.....
+        _mrec = fromrecords(nrec)
+        assert_equal(_mrec.dtype, mrec.dtype)
+        for field in _mrec.dtype.names:
+            assert_equal(getattr(_mrec, field), getattr(mrec._data, field))
+
+        _mrec = fromrecords(nrec.tolist(), names='c1,c2,c3')
+        assert_equal(_mrec.dtype, [('c1', int), ('c2', float), ('c3', '|S5')])
+        for (f, n) in zip(('c1', 'c2', 'c3'), ('a', 'b', 'c')):
+            assert_equal(getattr(_mrec, f), getattr(mrec._data, n))
+
+        _mrec = fromrecords(mrec)
+        assert_equal(_mrec.dtype, mrec.dtype)
+        assert_equal_records(_mrec._data, mrec.filled())
+        assert_equal_records(_mrec._mask, mrec._mask)
+
+    def test_fromrecords_wmask(self):
+        # Tests construction from records w/ mask.
+        (mrec, nrec, ddtype) = self.data
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=[0, 1, 0,])
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), [(0, 0, 0), (1, 1, 1), (0, 0, 0)])
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=True)
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), [(1, 1, 1), (1, 1, 1), (1, 1, 1)])
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=mrec._mask)
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
+
+        _mrec = fromrecords(nrec.tolist(), dtype=ddtype,
+                            mask=mrec._mask.tolist())
+        assert_equal_records(_mrec._data, mrec._data)
+        assert_equal(_mrec._mask.tolist(), mrec._mask.tolist())
+
+    def test_fromtextfile(self):
+        # Tests reading from a text file.
+        fcontent = (
+"""#
+'One (S)','Two (I)','Three (F)','Four (M)','Five (-)','Six (C)'
+'strings',1,1.0,'mixed column',,1
+'with embedded "double quotes"',2,2.0,1.0,,1
+'strings',3,3.0E5,3,,1
+'strings',4,-1e-10,,,1
+""")
+        with temppath() as path:
+            with open(path, 'w') as f:
+                f.write(fcontent)
+            mrectxt = fromtextfile(path, delimitor=',', varnames='ABCDEFG')
+        self.assertTrue(isinstance(mrectxt, MaskedRecords))
+        assert_equal(mrectxt.F, [1, 1, 1, 1])
+        assert_equal(mrectxt.E._mask, [1, 1, 1, 1])
+        assert_equal(mrectxt.C, [1, 2, 3.e+5, -1e-10])
+
+    def test_addfield(self):
+        # Tests addfield
+        (mrec, nrec, ddtype) = self.data
+        (d, m) = ([100, 200, 300], [1, 0, 0])
+        mrec = addfield(mrec, ma.array(d, mask=m))
+        assert_equal(mrec.f3, d)
+        assert_equal(mrec.f3._mask, m)
+
+
+def test_record_array_with_object_field():
+    # Trac #1839
+    y = ma.masked_array(
+        [(1, '2'), (3, '4')],
+        mask=[(0, 0), (0, 1)],
+        dtype=[('a', int), ('b', np.object)])
+    # getting an item used to fail
+    y[1]
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
new file mode 100644
index 0000000000..6ce29cc030
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
@@ -0,0 +1,821 @@
+from __future__ import division, absolute_import, print_function
+
+from functools import reduce
+
+import numpy as np
+import numpy.core.umath as umath
+import numpy.core.fromnumeric as fromnumeric
+from numpy.testing import TestCase, run_module_suite, assert_
+from numpy.ma.testutils import assert_array_equal
+from numpy.ma import (
+    MaskType, MaskedArray, absolute, add, all, allclose, allequal, alltrue,
+    arange, arccos, arcsin, arctan, arctan2, array, average, choose,
+    concatenate, conjugate, cos, cosh, count, divide, equal, exp, filled,
+    getmask, greater, greater_equal, inner, isMaskedArray, less,
+    less_equal, log, log10, make_mask, masked, masked_array, masked_equal,
+    masked_greater, masked_greater_equal, masked_inside, masked_less,
+    masked_less_equal, masked_not_equal, masked_outside,
+    masked_print_option, masked_values, masked_where, maximum, minimum,
+    multiply, nomask, nonzero, not_equal, ones, outer, product, put, ravel,
+    repeat, resize, shape, sin, sinh, sometrue, sort, sqrt, subtract, sum,
+    take, tan, tanh, transpose, where, zeros,
+    )
+
+pi = np.pi
+
+
+def eq(v, w, msg=''):
+    result = allclose(v, w)
+    if not result:
+        print("Not eq:%s\n%s\n----%s" % (msg, str(v), str(w)))
+    return result
+
+
+class TestMa(TestCase):
+
+    def setUp(self):
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        a10 = 10.
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = array(x, mask=m1)
+        ym = array(y, mask=m2)
+        z = np.array([-.5, 0., .5, .8])
+        zm = array(z, mask=[0, 1, 0, 0])
+        xf = np.where(m1, 1e+20, x)
+        s = x.shape
+        xm.set_fill_value(1e+20)
+        self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf, s)
+
+    def test_testBasic1d(self):
+        # Test of basic array creation and properties in 1 dimension.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertFalse(isMaskedArray(x))
+        self.assertTrue(isMaskedArray(xm))
+        self.assertEqual(shape(xm), s)
+        self.assertEqual(xm.shape, s)
+        self.assertEqual(xm.dtype, x.dtype)
+        self.assertEqual(xm.size, reduce(lambda x, y:x * y, s))
+        self.assertEqual(count(xm), len(m1) - reduce(lambda x, y:x + y, m1))
+        self.assertTrue(eq(xm, xf))
+        self.assertTrue(eq(filled(xm, 1.e20), xf))
+        self.assertTrue(eq(x, xm))
+
+    def test_testBasic2d(self):
+        # Test of basic array creation and properties in 2 dimensions.
+        for s in [(4, 3), (6, 2)]:
+            (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+
+            self.assertFalse(isMaskedArray(x))
+            self.assertTrue(isMaskedArray(xm))
+            self.assertEqual(shape(xm), s)
+            self.assertEqual(xm.shape, s)
+            self.assertEqual(xm.size, reduce(lambda x, y:x * y, s))
+            self.assertEqual(count(xm),
+                             len(m1) - reduce(lambda x, y:x + y, m1))
+            self.assertTrue(eq(xm, xf))
+            self.assertTrue(eq(filled(xm, 1.e20), xf))
+            self.assertTrue(eq(x, xm))
+            self.setUp()
+
+    def test_testArithmetic(self):
+        # Test of basic arithmetic.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        a2d = array([[1, 2], [0, 4]])
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        self.assertTrue(eq(a2d * a2d, a2d * a2dm))
+        self.assertTrue(eq(a2d + a2d, a2d + a2dm))
+        self.assertTrue(eq(a2d - a2d, a2d - a2dm))
+        for s in [(12,), (4, 3), (2, 6)]:
+            x = x.reshape(s)
+            y = y.reshape(s)
+            xm = xm.reshape(s)
+            ym = ym.reshape(s)
+            xf = xf.reshape(s)
+            self.assertTrue(eq(-x, -xm))
+            self.assertTrue(eq(x + y, xm + ym))
+            self.assertTrue(eq(x - y, xm - ym))
+            self.assertTrue(eq(x * y, xm * ym))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(x / y, xm / ym))
+            self.assertTrue(eq(a10 + y, a10 + ym))
+            self.assertTrue(eq(a10 - y, a10 - ym))
+            self.assertTrue(eq(a10 * y, a10 * ym))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(a10 / y, a10 / ym))
+            self.assertTrue(eq(x + a10, xm + a10))
+            self.assertTrue(eq(x - a10, xm - a10))
+            self.assertTrue(eq(x * a10, xm * a10))
+            self.assertTrue(eq(x / a10, xm / a10))
+            self.assertTrue(eq(x ** 2, xm ** 2))
+            self.assertTrue(eq(abs(x) ** 2.5, abs(xm) ** 2.5))
+            self.assertTrue(eq(x ** y, xm ** ym))
+            self.assertTrue(eq(np.add(x, y), add(xm, ym)))
+            self.assertTrue(eq(np.subtract(x, y), subtract(xm, ym)))
+            self.assertTrue(eq(np.multiply(x, y), multiply(xm, ym)))
+            with np.errstate(divide='ignore', invalid='ignore'):
+                self.assertTrue(eq(np.divide(x, y), divide(xm, ym)))
+
+    def test_testMixedArithmetic(self):
+        na = np.array([1])
+        ma = array([1])
+        self.assertTrue(isinstance(na + ma, MaskedArray))
+        self.assertTrue(isinstance(ma + na, MaskedArray))
+
+    def test_testUfuncs1(self):
+        # Test various functions such as sin, cos.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertTrue(eq(np.cos(x), cos(xm)))
+        self.assertTrue(eq(np.cosh(x), cosh(xm)))
+        self.assertTrue(eq(np.sin(x), sin(xm)))
+        self.assertTrue(eq(np.sinh(x), sinh(xm)))
+        self.assertTrue(eq(np.tan(x), tan(xm)))
+        self.assertTrue(eq(np.tanh(x), tanh(xm)))
+        with np.errstate(divide='ignore', invalid='ignore'):
+            self.assertTrue(eq(np.sqrt(abs(x)), sqrt(xm)))
+            self.assertTrue(eq(np.log(abs(x)), log(xm)))
+            self.assertTrue(eq(np.log10(abs(x)), log10(xm)))
+        self.assertTrue(eq(np.exp(x), exp(xm)))
+        self.assertTrue(eq(np.arcsin(z), arcsin(zm)))
+        self.assertTrue(eq(np.arccos(z), arccos(zm)))
+        self.assertTrue(eq(np.arctan(z), arctan(zm)))
+        self.assertTrue(eq(np.arctan2(x, y), arctan2(xm, ym)))
+        self.assertTrue(eq(np.absolute(x), absolute(xm)))
+        self.assertTrue(eq(np.equal(x, y), equal(xm, ym)))
+        self.assertTrue(eq(np.not_equal(x, y), not_equal(xm, ym)))
+        self.assertTrue(eq(np.less(x, y), less(xm, ym)))
+        self.assertTrue(eq(np.greater(x, y), greater(xm, ym)))
+        self.assertTrue(eq(np.less_equal(x, y), less_equal(xm, ym)))
+        self.assertTrue(eq(np.greater_equal(x, y), greater_equal(xm, ym)))
+        self.assertTrue(eq(np.conjugate(x), conjugate(xm)))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((xm, ym))))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((x, y))))
+        self.assertTrue(eq(np.concatenate((x, y)), concatenate((xm, y))))
+        self.assertTrue(eq(np.concatenate((x, y, x)), concatenate((x, ym, x))))
+
+    def test_xtestCount(self):
+        # Test count
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        self.assertEqual(3, count(ott))
+        self.assertEqual(1, count(1))
+        self.assertTrue(eq(0, array(1, mask=[1])))
+        ott = ott.reshape((2, 2))
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        assert_(isinstance(count(ott, 0), np.ndarray))
+        self.assertTrue(count(ott).dtype.type is np.intp)
+        self.assertTrue(eq(3, count(ott)))
+        assert_(getmask(count(ott, 0)) is nomask)
+        self.assertTrue(eq([1, 2], count(ott, 0)))
+
+    def test_testMinMax(self):
+        # Test minimum and maximum.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        xr = np.ravel(x)  # max doesn't work if shaped
+        xmr = ravel(xm)
+
+        # true because of careful selection of data
+        self.assertTrue(eq(max(xr), maximum(xmr)))
+        self.assertTrue(eq(min(xr), minimum(xmr)))
+
+    def test_testAddSumProd(self):
+        # Test add, sum, product.
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        self.assertTrue(eq(np.add.reduce(x), add.reduce(x)))
+        self.assertTrue(eq(np.add.accumulate(x), add.accumulate(x)))
+        self.assertTrue(eq(4, sum(array(4), axis=0)))
+        self.assertTrue(eq(4, sum(array(4), axis=0)))
+        self.assertTrue(eq(np.sum(x, axis=0), sum(x, axis=0)))
+        self.assertTrue(eq(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0)))
+        self.assertTrue(eq(np.sum(x, 0), sum(x, 0)))
+        self.assertTrue(eq(np.product(x, axis=0), product(x, axis=0)))
+        self.assertTrue(eq(np.product(x, 0), product(x, 0)))
+        self.assertTrue(eq(np.product(filled(xm, 1), axis=0),
+                           product(xm, axis=0)))
+        if len(s) > 1:
+            self.assertTrue(eq(np.concatenate((x, y), 1),
+                               concatenate((xm, ym), 1)))
+            self.assertTrue(eq(np.add.reduce(x, 1), add.reduce(x, 1)))
+            self.assertTrue(eq(np.sum(x, 1), sum(x, 1)))
+            self.assertTrue(eq(np.product(x, 1), product(x, 1)))
+
+    def test_testCI(self):
+        # Test of conversions and indexing
+        x1 = np.array([1, 2, 4, 3])
+        x2 = array(x1, mask=[1, 0, 0, 0])
+        x3 = array(x1, mask=[0, 1, 0, 1])
+        x4 = array(x1)
+        # test conversion to strings
+        str(x2)  # raises?
+        repr(x2)  # raises?
+        assert_(eq(np.sort(x1), sort(x2, fill_value=0)))
+        # tests of indexing
+        assert_(type(x2[1]) is type(x1[1]))
+        assert_(x1[1] == x2[1])
+        assert_(x2[0] is masked)
+        assert_(eq(x1[2], x2[2]))
+        assert_(eq(x1[2:5], x2[2:5]))
+        assert_(eq(x1[:], x2[:]))
+        assert_(eq(x1[1:], x3[1:]))
+        x1[2] = 9
+        x2[2] = 9
+        assert_(eq(x1, x2))
+        x1[1:3] = 99
+        x2[1:3] = 99
+        assert_(eq(x1, x2))
+        x2[1] = masked
+        assert_(eq(x1, x2))
+        x2[1:3] = masked
+        assert_(eq(x1, x2))
+        x2[:] = x1
+        x2[1] = masked
+        assert_(allequal(getmask(x2), array([0, 1, 0, 0])))
+        x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x3), array([0, 1, 1, 0])))
+        x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        assert_(allequal(getmask(x4), array([0, 1, 1, 0])))
+        assert_(allequal(x4, array([1, 2, 3, 4])))
+        x1 = np.arange(5) * 1.0
+        x2 = masked_values(x1, 3.0)
+        assert_(eq(x1, x2))
+        assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask))
+        assert_(eq(3.0, x2.fill_value))
+        x1 = array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        s1 = x1[1]
+        s2 = x2[1]
+        self.assertEqual(type(s2), str)
+        self.assertEqual(type(s1), str)
+        self.assertEqual(s1, s2)
+        assert_(x1[1:1].shape == (0,))
+
+    def test_testCopySize(self):
+        # Tests of some subtle points of copying and sizing.
+        n = [0, 0, 1, 0, 0]
+        m = make_mask(n)
+        m2 = make_mask(m)
+        self.assertTrue(m is m2)
+        m3 = make_mask(m, copy=1)
+        self.assertTrue(m is not m3)
+
+        x1 = np.arange(5)
+        y1 = array(x1, mask=m)
+        self.assertTrue(y1._data is not x1)
+        self.assertTrue(allequal(x1, y1._data))
+        self.assertTrue(y1.mask is m)
+
+        y1a = array(y1, copy=0)
+        self.assertTrue(y1a.mask is y1.mask)
+
+        y2 = array(x1, mask=m, copy=0)
+        self.assertTrue(y2.mask is m)
+        self.assertTrue(y2[2] is masked)
+        y2[2] = 9
+        self.assertTrue(y2[2] is not masked)
+        self.assertTrue(y2.mask is not m)
+        self.assertTrue(allequal(y2.mask, 0))
+
+        y3 = array(x1 * 1.0, mask=m)
+        self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype)
+
+        x4 = arange(4)
+        x4[2] = masked
+        y4 = resize(x4, (8,))
+        self.assertTrue(eq(concatenate([x4, x4]), y4))
+        self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0]))
+        y5 = repeat(x4, (2, 2, 2, 2), axis=0)
+        self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3]))
+        y6 = repeat(x4, 2, axis=0)
+        self.assertTrue(eq(y5, y6))
+
+    def test_testPut(self):
+        # Test of put
+        d = arange(5)
+        n = [0, 0, 0, 1, 1]
+        m = make_mask(n)
+        x = array(d, mask=m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+        x[[1, 4]] = [10, 40]
+        self.assertTrue(x.mask is not m)
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is not masked)
+        self.assertTrue(eq(x, [0, 10, 2, -1, 40]))
+
+        x = array(d, mask=m)
+        x.put([0, 1, 2], [-1, 100, 200])
+        self.assertTrue(eq(x, [-1, 100, 200, 0, 0]))
+        self.assertTrue(x[3] is masked)
+        self.assertTrue(x[4] is masked)
+
+    def test_testMaPut(self):
+        (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d
+        m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
+        i = np.nonzero(m)[0]
+        put(ym, i, zm)
+        assert_(all(take(ym, i, axis=0) == zm))
+
+    def test_testOddFeatures(self):
+        # Test of other odd features
+        x = arange(20)
+        x = x.reshape(4, 5)
+        x.flat[5] = 12
+        assert_(x[1, 0] == 12)
+        z = x + 10j * x
+        assert_(eq(z.real, x))
+        assert_(eq(z.imag, 10 * x))
+        assert_(eq((z * conjugate(z)).real, 101 * x * x))
+        z.imag[...] = 0.0
+
+        x = arange(10)
+        x[3] = masked
+        assert_(str(x[3]) == str(masked))
+        c = x >= 8
+        assert_(count(where(c, masked, masked)) == 0)
+        assert_(shape(where(c, masked, masked)) == c.shape)
+        z = where(c, x, masked)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is masked)
+        assert_(z[7] is masked)
+        assert_(z[8] is not masked)
+        assert_(z[9] is not masked)
+        assert_(eq(x, z))
+        z = where(c, masked, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        z = masked_where(c, x)
+        assert_(z.dtype is x.dtype)
+        assert_(z[3] is masked)
+        assert_(z[4] is not masked)
+        assert_(z[7] is not masked)
+        assert_(z[8] is masked)
+        assert_(z[9] is masked)
+        assert_(eq(x, z))
+        x = array([1., 2., 3., 4., 5.])
+        c = array([1, 1, 1, 0, 0])
+        x[2] = masked
+        z = where(c, x, -x)
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        c[0] = masked
+        z = where(c, x, -x)
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+        assert_(eq(masked_where(greater(x, 2), x), masked_greater(x, 2)))
+        assert_(eq(masked_where(greater_equal(x, 2), x),
+                   masked_greater_equal(x, 2)))
+        assert_(eq(masked_where(less(x, 2), x), masked_less(x, 2)))
+        assert_(eq(masked_where(less_equal(x, 2), x), masked_less_equal(x, 2)))
+        assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)))
+        assert_(eq(masked_where(equal(x, 2), x), masked_equal(x, 2)))
+        assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)))
+        assert_(eq(masked_inside(list(range(5)), 1, 3), [0, 199, 199, 199, 4]))
+        assert_(eq(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199]))
+        assert_(eq(masked_inside(array(list(range(5)),
+                                       mask=[1, 0, 0, 0, 0]), 1, 3).mask,
+                   [1, 1, 1, 1, 0]))
+        assert_(eq(masked_outside(array(list(range(5)),
+                                        mask=[0, 1, 0, 0, 0]), 1, 3).mask,
+                   [1, 1, 0, 0, 1]))
+        assert_(eq(masked_equal(array(list(range(5)),
+                                      mask=[1, 0, 0, 0, 0]), 2).mask,
+                   [1, 0, 1, 0, 0]))
+        assert_(eq(masked_not_equal(array([2, 2, 1, 2, 1],
+                                          mask=[1, 0, 0, 0, 0]), 2).mask,
+                   [1, 0, 1, 0, 1]))
+        assert_(eq(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]),
+                   [99, 99, 3, 4, 5]))
+        atest = ones((10, 10, 10), dtype=np.float32)
+        btest = zeros(atest.shape, MaskType)
+        ctest = masked_where(btest, atest)
+        assert_(eq(atest, ctest))
+        z = choose(c, (-x, x))
+        assert_(eq(z, [1., 2., 0., -4., -5]))
+        assert_(z[0] is masked)
+        assert_(z[1] is not masked)
+        assert_(z[2] is masked)
+        x = arange(6)
+        x[5] = masked
+        y = arange(6) * 10
+        y[2] = masked
+        c = array([1, 1, 1, 0, 0, 0], mask=[1, 0, 0, 0, 0, 0])
+        cm = c.filled(1)
+        z = where(c, x, y)
+        zm = where(cm, x, y)
+        assert_(eq(z, zm))
+        assert_(getmask(zm) is nomask)
+        assert_(eq(zm, [0, 1, 2, 30, 40, 50]))
+        z = where(c, masked, 1)
+        assert_(eq(z, [99, 99, 99, 1, 1, 1]))
+        z = where(c, 1, masked)
+        assert_(eq(z, [99, 1, 1, 99, 99, 99]))
+
+    def test_testMinMax2(self):
+        # Test of minumum, maximum.
+        assert_(eq(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3]))
+        assert_(eq(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9]))
+        x = arange(5)
+        y = arange(5) - 2
+        x[3] = masked
+        y[0] = masked
+        assert_(eq(minimum(x, y), where(less(x, y), x, y)))
+        assert_(eq(maximum(x, y), where(greater(x, y), x, y)))
+        assert_(minimum(x) == 0)
+        assert_(maximum(x) == 4)
+
+    def test_testTakeTransposeInnerOuter(self):
+        # Test of take, transpose, inner, outer products
+        x = arange(24)
+        y = np.arange(24)
+        x[5:6] = masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert_(eq(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1))))
+        assert_(eq(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1)))
+        assert_(eq(np.inner(filled(x, 0), filled(y, 0)),
+                   inner(x, y)))
+        assert_(eq(np.outer(filled(x, 0), filled(y, 0)),
+                   outer(x, y)))
+        y = array(['abc', 1, 'def', 2, 3], object)
+        y[2] = masked
+        t = take(y, [0, 3, 4])
+        assert_(t[0] == 'abc')
+        assert_(t[1] == 2)
+        assert_(t[2] == 3)
+
+    def test_testInplace(self):
+        # Test of inplace operations and rich comparisons
+        y = arange(10)
+
+        x = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        x += 1
+        assert_(eq(x, y + 1))
+        xm += 1
+        assert_(eq(x, y + 1))
+
+        x = arange(10)
+        xm = arange(10)
+        xm[2] = masked
+        x -= 1
+        assert_(eq(x, y - 1))
+        xm -= 1
+        assert_(eq(xm, y - 1))
+
+        x = arange(10) * 1.0
+        xm = arange(10) * 1.0
+        xm[2] = masked
+        x *= 2.0
+        assert_(eq(x, y * 2))
+        xm *= 2.0
+        assert_(eq(xm, y * 2))
+
+        x = arange(10) * 2
+        xm = arange(10)
+        xm[2] = masked
+        x //= 2
+        assert_(eq(x, y))
+        xm //= 2
+        assert_(eq(x, y))
+
+        x = arange(10) * 1.0
+        xm = arange(10) * 1.0
+        xm[2] = masked
+        x /= 2.0
+        assert_(eq(x, y / 2.0))
+        xm /= arange(10)
+        assert_(eq(xm, ones((10,))))
+
+        x = arange(10).astype(np.float32)
+        xm = arange(10)
+        xm[2] = masked
+        x += 1.
+        assert_(eq(x, y + 1.))
+
+    def test_testPickle(self):
+        # Test of pickling
+        import pickle
+        x = arange(12)
+        x[4:10:2] = masked
+        x = x.reshape(4, 3)
+        s = pickle.dumps(x)
+        y = pickle.loads(s)
+        assert_(eq(x, y))
+
+    def test_testMasked(self):
+        # Test of masked element
+        xx = arange(6)
+        xx[1] = masked
+        self.assertTrue(str(masked) == '--')
+        self.assertTrue(xx[1] is masked)
+        self.assertEqual(filled(xx[1], 0), 0)
+
+    def test_testAverage1(self):
+        # Test of average.
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assertTrue(eq(2.0, average(ott, axis=0)))
+        self.assertTrue(eq(2.0, average(ott, weights=[1., 1., 2., 1.])))
+        result, wts = average(ott, weights=[1., 1., 2., 1.], returned=1)
+        self.assertTrue(eq(2.0, result))
+        self.assertTrue(wts == 4.0)
+        ott[:] = masked
+        self.assertTrue(average(ott, axis=0) is masked)
+        ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = masked
+        self.assertTrue(eq(average(ott, axis=0), [2.0, 0.0]))
+        self.assertTrue(average(ott, axis=1)[0] is masked)
+        self.assertTrue(eq([2., 0.], average(ott, axis=0)))
+        result, wts = average(ott, axis=0, returned=1)
+        self.assertTrue(eq(wts, [1., 0.]))
+
+    def test_testAverage2(self):
+        # More tests of average.
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = arange(6)
+        self.assertTrue(allclose(average(x, axis=0), 2.5))
+        self.assertTrue(allclose(average(x, axis=0, weights=w1), 2.5))
+        y = array([arange(6), 2.0 * arange(6)])
+        self.assertTrue(allclose(average(y, None),
+                                 np.add.reduce(np.arange(6)) * 3. / 12.))
+        self.assertTrue(allclose(average(y, axis=0), np.arange(6) * 3. / 2.))
+        self.assertTrue(allclose(average(y, axis=1),
+                                 [average(x, axis=0), average(x, axis=0)*2.0]))
+        self.assertTrue(allclose(average(y, None, weights=w2), 20. / 6.))
+        self.assertTrue(allclose(average(y, axis=0, weights=w2),
+                                 [0., 1., 2., 3., 4., 10.]))
+        self.assertTrue(allclose(average(y, axis=1),
+                                 [average(x, axis=0), average(x, axis=0)*2.0]))
+        m1 = zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        self.assertTrue(allclose(average(masked_array(x, m1), axis=0), 2.5))
+        self.assertTrue(allclose(average(masked_array(x, m2), axis=0), 2.5))
+        self.assertTrue(average(masked_array(x, m4), axis=0) is masked)
+        self.assertEqual(average(masked_array(x, m5), axis=0), 0.0)
+        self.assertEqual(count(average(masked_array(x, m4), axis=0)), 0)
+        z = masked_array(y, m3)
+        self.assertTrue(allclose(average(z, None), 20. / 6.))
+        self.assertTrue(allclose(average(z, axis=0),
+                                 [0., 1., 99., 99., 4.0, 7.5]))
+        self.assertTrue(allclose(average(z, axis=1), [2.5, 5.0]))
+        self.assertTrue(allclose(average(z, axis=0, weights=w2),
+                                 [0., 1., 99., 99., 4.0, 10.0]))
+
+        a = arange(6)
+        b = arange(6) * 3
+        r1, w1 = average([[a, b], [b, a]], axis=1, returned=1)
+        self.assertEqual(shape(r1), shape(w1))
+        self.assertEqual(r1.shape, w1.shape)
+        r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=1)
+        self.assertEqual(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), returned=1)
+        self.assertEqual(shape(w2), shape(r2))
+        r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=1)
+        self.assertTrue(shape(w2) == shape(r2))
+        a2d = array([[1, 2], [0, 4]], float)
+        a2dm = masked_array(a2d, [[0, 0], [1, 0]])
+        a2da = average(a2d, axis=0)
+        self.assertTrue(eq(a2da, [0.5, 3.0]))
+        a2dma = average(a2dm, axis=0)
+        self.assertTrue(eq(a2dma, [1.0, 3.0]))
+        a2dma = average(a2dm, axis=None)
+        self.assertTrue(eq(a2dma, 7. / 3.))
+        a2dma = average(a2dm, axis=1)
+        self.assertTrue(eq(a2dma, [1.5, 4.0]))
+
+    def test_testToPython(self):
+        self.assertEqual(1, int(array(1)))
+        self.assertEqual(1.0, float(array(1)))
+        self.assertEqual(1, int(array([[[1]]])))
+        self.assertEqual(1.0, float(array([[1]])))
+        self.assertRaises(TypeError, float, array([1, 1]))
+        self.assertRaises(ValueError, bool, array([0, 1]))
+        self.assertRaises(ValueError, bool, array([0, 0], mask=[0, 1]))
+
+    def test_testScalarArithmetic(self):
+        xm = array(0, mask=1)
+        #TODO FIXME: Find out what the following raises a warning in r8247
+        with np.errstate(divide='ignore'):
+            self.assertTrue((1 / array(0)).mask)
+        self.assertTrue((1 + xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue((-xm).mask)
+        self.assertTrue(maximum(xm, xm).mask)
+        self.assertTrue(minimum(xm, xm).mask)
+        self.assertTrue(xm.filled().dtype is xm._data.dtype)
+        x = array(0, mask=0)
+        self.assertTrue(x.filled() == x._data)
+        self.assertEqual(str(xm), str(masked_print_option))
+
+    def test_testArrayMethods(self):
+        a = array([1, 3, 2])
+        self.assertTrue(eq(a.any(), a._data.any()))
+        self.assertTrue(eq(a.all(), a._data.all()))
+        self.assertTrue(eq(a.argmax(), a._data.argmax()))
+        self.assertTrue(eq(a.argmin(), a._data.argmin()))
+        self.assertTrue(eq(a.choose(0, 1, 2, 3, 4),
+                           a._data.choose(0, 1, 2, 3, 4)))
+        self.assertTrue(eq(a.compress([1, 0, 1]), a._data.compress([1, 0, 1])))
+        self.assertTrue(eq(a.conj(), a._data.conj()))
+        self.assertTrue(eq(a.conjugate(), a._data.conjugate()))
+        m = array([[1, 2], [3, 4]])
+        self.assertTrue(eq(m.diagonal(), m._data.diagonal()))
+        self.assertTrue(eq(a.sum(), a._data.sum()))
+        self.assertTrue(eq(a.take([1, 2]), a._data.take([1, 2])))
+        self.assertTrue(eq(m.transpose(), m._data.transpose()))
+
+    def test_testArrayAttributes(self):
+        a = array([1, 3, 2])
+        self.assertEqual(a.ndim, 1)
+
+    def test_testAPI(self):
+        self.assertFalse([m for m in dir(np.ndarray)
+                          if m not in dir(MaskedArray) and
+                          not m.startswith('_')])
+
+    def test_testSingleElementSubscript(self):
+        a = array([1, 3, 2])
+        b = array([1, 3, 2], mask=[1, 0, 1])
+        self.assertEqual(a[0].shape, ())
+        self.assertEqual(b[0].shape, ())
+        self.assertEqual(b[1].shape, ())
+
+
+class TestUfuncs(TestCase):
+    def setUp(self):
+        self.d = (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6),
+                  array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),)
+
+    def test_testUfuncRegression(self):
+        f_invalid_ignore = [
+            'sqrt', 'arctanh', 'arcsin', 'arccos',
+            'arccosh', 'arctanh', 'log', 'log10', 'divide',
+            'true_divide', 'floor_divide', 'remainder', 'fmod']
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+                  'sin', 'cos', 'tan',
+                  'arcsin', 'arccos', 'arctan',
+                  'sinh', 'cosh', 'tanh',
+                  'arcsinh',
+                  'arccosh',
+                  'arctanh',
+                  'absolute', 'fabs', 'negative',
+                  'floor', 'ceil',
+                  'logical_not',
+                  'add', 'subtract', 'multiply',
+                  'divide', 'true_divide', 'floor_divide',
+                  'remainder', 'fmod', 'hypot', 'arctan2',
+                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+                  'less', 'greater',
+                  'logical_and', 'logical_or', 'logical_xor']:
+            try:
+                uf = getattr(umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(np.ma, f)
+            args = self.d[:uf.nin]
+            with np.errstate():
+                if f in f_invalid_ignore:
+                    np.seterr(invalid='ignore')
+                if f in ['arctanh', 'log', 'log10']:
+                    np.seterr(divide='ignore')
+                ur = uf(*args)
+                mr = mf(*args)
+            self.assertTrue(eq(ur.filled(0), mr.filled(0), f))
+            self.assertTrue(eqmask(ur.mask, mr.mask))
+
+    def test_reduce(self):
+        a = self.d[0]
+        self.assertFalse(alltrue(a, axis=0))
+        self.assertTrue(sometrue(a, axis=0))
+        self.assertEqual(sum(a[:3], axis=0), 0)
+        self.assertEqual(product(a, axis=0), 0)
+
+    def test_minmax(self):
+        a = arange(1, 13).reshape(3, 4)
+        amask = masked_where(a < 5, a)
+        self.assertEqual(amask.max(), a.max())
+        self.assertEqual(amask.min(), 5)
+        self.assertTrue((amask.max(0) == a.max(0)).all())
+        self.assertTrue((amask.min(0) == [5, 6, 7, 8]).all())
+        self.assertTrue(amask.max(1)[0].mask)
+        self.assertTrue(amask.min(1)[0].mask)
+
+    def test_nonzero(self):
+        for t in "?bhilqpBHILQPfdgFDGO":
+            x = array([1, 0, 2, 0], mask=[0, 0, 1, 1])
+            self.assertTrue(eq(nonzero(x), [0]))
+
+
+class TestArrayMethods(TestCase):
+
+    def setUp(self):
+        x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928,
+                      8.43, 7.78, 9.865, 5.878, 8.979, 4.732,
+                      3.012, 6.022, 5.095, 3.116, 5.238, 3.957,
+                      6.04, 9.63, 7.712, 3.382, 4.489, 6.479,
+                      7.189, 9.645, 5.395, 4.961, 9.894, 2.893,
+                      7.357, 9.828, 6.272, 3.758, 6.693, 0.993])
+        X = x.reshape(6, 6)
+        XX = x.reshape(3, 2, 2, 3)
+
+        m = np.array([0, 1, 0, 1, 0, 0,
+                      1, 0, 1, 1, 0, 1,
+                      0, 0, 0, 1, 0, 1,
+                      0, 0, 0, 1, 1, 1,
+                      1, 0, 0, 1, 0, 0,
+                      0, 0, 1, 0, 1, 0])
+        mx = array(data=x, mask=m)
+        mX = array(data=X, mask=m.reshape(X.shape))
+        mXX = array(data=XX, mask=m.reshape(XX.shape))
+
+        self.d = (x, X, XX, m, mx, mX, mXX)
+
+    def test_trace(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXdiag = mX.diagonal()
+        self.assertEqual(mX.trace(), mX.diagonal().compressed().sum())
+        self.assertTrue(eq(mX.trace(),
+                           X.trace() - sum(mXdiag.mask * X.diagonal(),
+                                           axis=0)))
+
+    def test_clip(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        clipped = mx.clip(2, 8)
+        self.assertTrue(eq(clipped.mask, mx.mask))
+        self.assertTrue(eq(clipped._data, x.clip(2, 8)))
+        self.assertTrue(eq(clipped._data, mx._data.clip(2, 8)))
+
+    def test_ptp(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        (n, m) = X.shape
+        self.assertEqual(mx.ptp(), mx.compressed().ptp())
+        rows = np.zeros(n, np.float_)
+        cols = np.zeros(m, np.float_)
+        for k in range(m):
+            cols[k] = mX[:, k].compressed().ptp()
+        for k in range(n):
+            rows[k] = mX[k].compressed().ptp()
+        self.assertTrue(eq(mX.ptp(0), cols))
+        self.assertTrue(eq(mX.ptp(1), rows))
+
+    def test_swapaxes(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXswapped = mX.swapaxes(0, 1)
+        self.assertTrue(eq(mXswapped[-1], mX[:, -1]))
+        mXXswapped = mXX.swapaxes(0, 2)
+        self.assertEqual(mXXswapped.shape, (2, 2, 3, 3))
+
+    def test_cumprod(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXcp = mX.cumprod(0)
+        self.assertTrue(eq(mXcp._data, mX.filled(1).cumprod(0)))
+        mXcp = mX.cumprod(1)
+        self.assertTrue(eq(mXcp._data, mX.filled(1).cumprod(1)))
+
+    def test_cumsum(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        mXcp = mX.cumsum(0)
+        self.assertTrue(eq(mXcp._data, mX.filled(0).cumsum(0)))
+        mXcp = mX.cumsum(1)
+        self.assertTrue(eq(mXcp._data, mX.filled(0).cumsum(1)))
+
+    def test_varstd(self):
+        (x, X, XX, m, mx, mX, mXX,) = self.d
+        self.assertTrue(eq(mX.var(axis=None), mX.compressed().var()))
+        self.assertTrue(eq(mX.std(axis=None), mX.compressed().std()))
+        self.assertTrue(eq(mXX.var(axis=3).shape, XX.var(axis=3).shape))
+        self.assertTrue(eq(mX.var().shape, X.var().shape))
+        (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1))
+        for k in range(6):
+            self.assertTrue(eq(mXvar1[k], mX[k].compressed().var()))
+            self.assertTrue(eq(mXvar0[k], mX[:, k].compressed().var()))
+            self.assertTrue(eq(np.sqrt(mXvar0[k]),
+                               mX[:, k].compressed().std()))
+
+
+def eqmask(m1, m2):
+    if m1 is nomask:
+        return m2 is nomask
+    if m2 is nomask:
+        return m1 is nomask
+    return (m1 == m2).all()
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
new file mode 100644
index 0000000000..dba74d357c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
@@ -0,0 +1,80 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+import numpy as np
+from numpy.testing import (assert_, TestCase, assert_array_equal,
+                           assert_allclose, run_module_suite)
+from numpy.compat import sixu
+
+rlevel = 1
+
+
+class TestRegression(TestCase):
+    def test_masked_array_create(self,level=rlevel):
+        # Ticket #17
+        x = np.ma.masked_array([0, 1, 2, 3, 0, 4, 5, 6],
+                               mask=[0, 0, 0, 1, 1, 1, 0, 0])
+        assert_array_equal(np.ma.nonzero(x), [[1, 2, 6, 7]])
+
+    def test_masked_array(self,level=rlevel):
+        # Ticket #61
+        np.ma.array(1, mask=[1])
+
+    def test_mem_masked_where(self,level=rlevel):
+        # Ticket #62
+        from numpy.ma import masked_where, MaskType
+        a = np.zeros((1, 1))
+        b = np.zeros(a.shape, MaskType)
+        c = masked_where(b, a)
+        a-c
+
+    def test_masked_array_multiply(self,level=rlevel):
+        # Ticket #254
+        a = np.ma.zeros((4, 1))
+        a[2, 0] = np.ma.masked
+        b = np.zeros((4, 2))
+        a*b
+        b*a
+
+    def test_masked_array_repeat(self, level=rlevel):
+        # Ticket #271
+        np.ma.array([1], mask=False).repeat(10)
+
+    def test_masked_array_repr_unicode(self):
+        # Ticket #1256
+        repr(np.ma.array(sixu("Unicode")))
+
+    def test_atleast_2d(self):
+        # Ticket #1559
+        a = np.ma.masked_array([0.0, 1.2, 3.5], mask=[False, True, False])
+        b = np.atleast_2d(a)
+        assert_(a.mask.ndim == 1)
+        assert_(b.mask.ndim == 2)
+
+    def test_set_fill_value_unicode_py3(self):
+        # Ticket #2733
+        a = np.ma.masked_array(['a', 'b', 'c'], mask=[1, 0, 0])
+        a.fill_value = 'X'
+        assert_(a.fill_value == 'X')
+
+    def test_var_sets_maskedarray_scalar(self):
+        # Issue gh-2757
+        a = np.ma.array(np.arange(5), mask=True)
+        mout = np.ma.array(-1, dtype=float)
+        a.var(out=mout)
+        assert_(mout._data == 0)
+
+    def test_ddof_corrcoef(self):
+        # See gh-3336
+        x = np.ma.masked_equal([1, 2, 3, 4, 5], 4)
+        y = np.array([2, 2.5, 3.1, 3, 5])
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore")
+            r0 = np.ma.corrcoef(x, y, ddof=0)
+            r1 = np.ma.corrcoef(x, y, ddof=1)
+            # ddof should not have an effect (it gets cancelled out)
+            assert_allclose(r0.data, r1.data)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
new file mode 100644
index 0000000000..814ed5977f
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
@@ -0,0 +1,358 @@
+# pylint: disable-msg=W0611, W0612, W0511,R0201
+"""Tests suite for MaskedArray & subclassing.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: test_subclassing.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_raises
+from numpy.ma.testutils import assert_equal
+from numpy.ma.core import (
+    array, arange, masked, MaskedArray, masked_array, log, add, hypot,
+    divide, asarray, asanyarray, nomask
+    )
+# from numpy.ma.core import (
+
+
+class SubArray(np.ndarray):
+    # Defines a generic np.ndarray subclass, that stores some metadata
+    # in the  dictionary `info`.
+    def __new__(cls,arr,info={}):
+        x = np.asanyarray(arr).view(cls)
+        x.info = info.copy()
+        return x
+
+    def __array_finalize__(self, obj):
+        if callable(getattr(super(SubArray, self),
+                            '__array_finalize__', None)):
+            super(SubArray, self).__array_finalize__(obj)
+        self.info = getattr(obj, 'info', {}).copy()
+        return
+
+    def __add__(self, other):
+        result = super(SubArray, self).__add__(other)
+        result.info['added'] = result.info.get('added', 0) + 1
+        return result
+
+    def __iadd__(self, other):
+        result = super(SubArray, self).__iadd__(other)
+        result.info['iadded'] = result.info.get('iadded', 0) + 1
+        return result
+
+
+subarray = SubArray
+
+
+class SubMaskedArray(MaskedArray):
+    """Pure subclass of MaskedArray, keeping some info on subclass."""
+    def __new__(cls, info=None, **kwargs):
+        obj = super(SubMaskedArray, cls).__new__(cls, **kwargs)
+        obj._optinfo['info'] = info
+        return obj
+
+
+class MSubArray(SubArray, MaskedArray):
+
+    def __new__(cls, data, info={}, mask=nomask):
+        subarr = SubArray(data, info)
+        _data = MaskedArray.__new__(cls, data=subarr, mask=mask)
+        _data.info = subarr.info
+        return _data
+
+    def _get_series(self):
+        _view = self.view(MaskedArray)
+        _view._sharedmask = False
+        return _view
+    _series = property(fget=_get_series)
+
+msubarray = MSubArray
+
+
+class MMatrix(MaskedArray, np.matrix,):
+
+    def __new__(cls, data, mask=nomask):
+        mat = np.matrix(data)
+        _data = MaskedArray.__new__(cls, data=mat, mask=mask)
+        return _data
+
+    def __array_finalize__(self, obj):
+        np.matrix.__array_finalize__(self, obj)
+        MaskedArray.__array_finalize__(self, obj)
+        return
+
+    def _get_series(self):
+        _view = self.view(MaskedArray)
+        _view._sharedmask = False
+        return _view
+    _series = property(fget=_get_series)
+
+mmatrix = MMatrix
+
+
+# Also a subclass that overrides __str__, __repr__ and __setitem__, disallowing
+# setting to non-class values (and thus np.ma.core.masked_print_option)
+# and overrides __array_wrap__, updating the info dict, to check that this
+# doesn't get destroyed by MaskedArray._update_from.  But this one also needs
+# its own iterator...
+class CSAIterator(object):
+    """
+    Flat iterator object that uses its own setter/getter
+    (works around ndarray.flat not propagating subclass setters/getters
+    see https://github.com/numpy/numpy/issues/4564)
+    roughly following MaskedIterator
+    """
+    def __init__(self, a):
+        self._original = a
+        self._dataiter = a.view(np.ndarray).flat
+
+    def __iter__(self):
+        return self
+
+    def __getitem__(self, indx):
+        out = self._dataiter.__getitem__(indx)
+        if not isinstance(out, np.ndarray):
+            out = out.__array__()
+        out = out.view(type(self._original))
+        return out
+
+    def __setitem__(self, index, value):
+        self._dataiter[index] = self._original._validate_input(value)
+
+    def __next__(self):
+        return next(self._dataiter).__array__().view(type(self._original))
+
+    next = __next__
+
+
+class ComplicatedSubArray(SubArray):
+
+    def __str__(self):
+        return 'myprefix {0} mypostfix'.format(self.view(SubArray))
+
+    def __repr__(self):
+        # Return a repr that does not start with 'name('
+        return '<{0} {1}>'.format(self.__class__.__name__, self)
+
+    def _validate_input(self, value):
+        if not isinstance(value, ComplicatedSubArray):
+            raise ValueError("Can only set to MySubArray values")
+        return value
+
+    def __setitem__(self, item, value):
+        # validation ensures direct assignment with ndarray or
+        # masked_print_option will fail
+        super(ComplicatedSubArray, self).__setitem__(
+            item, self._validate_input(value))
+
+    def __getitem__(self, item):
+        # ensure getter returns our own class also for scalars
+        value = super(ComplicatedSubArray, self).__getitem__(item)
+        if not isinstance(value, np.ndarray):  # scalar
+            value = value.__array__().view(ComplicatedSubArray)
+        return value
+
+    @property
+    def flat(self):
+        return CSAIterator(self)
+
+    @flat.setter
+    def flat(self, value):
+        y = self.ravel()
+        y[:] = value
+
+    def __array_wrap__(self, obj, context=None):
+        obj = super(ComplicatedSubArray, self).__array_wrap__(obj, context)
+        if context is not None and context[0] is np.multiply:
+            obj.info['multiplied'] = obj.info.get('multiplied', 0) + 1
+
+        return obj
+
+
+class TestSubclassing(TestCase):
+    # Test suite for masked subclasses of ndarray.
+
+    def setUp(self):
+        x = np.arange(5)
+        mx = mmatrix(x, mask=[0, 1, 0, 0, 0])
+        self.data = (x, mx)
+
+    def test_data_subclassing(self):
+        # Tests whether the subclass is kept.
+        x = np.arange(5)
+        m = [0, 0, 1, 0, 0]
+        xsub = SubArray(x)
+        xmsub = masked_array(xsub, mask=m)
+        self.assertTrue(isinstance(xmsub, MaskedArray))
+        assert_equal(xmsub._data, xsub)
+        self.assertTrue(isinstance(xmsub._data, SubArray))
+
+    def test_maskedarray_subclassing(self):
+        # Tests subclassing MaskedArray
+        (x, mx) = self.data
+        self.assertTrue(isinstance(mx._data, np.matrix))
+
+    def test_masked_unary_operations(self):
+        # Tests masked_unary_operation
+        (x, mx) = self.data
+        with np.errstate(divide='ignore'):
+            self.assertTrue(isinstance(log(mx), mmatrix))
+            assert_equal(log(x), np.log(x))
+
+    def test_masked_binary_operations(self):
+        # Tests masked_binary_operation
+        (x, mx) = self.data
+        # Result should be a mmatrix
+        self.assertTrue(isinstance(add(mx, mx), mmatrix))
+        self.assertTrue(isinstance(add(mx, x), mmatrix))
+        # Result should work
+        assert_equal(add(mx, x), mx+x)
+        self.assertTrue(isinstance(add(mx, mx)._data, np.matrix))
+        self.assertTrue(isinstance(add.outer(mx, mx), mmatrix))
+        self.assertTrue(isinstance(hypot(mx, mx), mmatrix))
+        self.assertTrue(isinstance(hypot(mx, x), mmatrix))
+
+    def test_masked_binary_operations2(self):
+        # Tests domained_masked_binary_operation
+        (x, mx) = self.data
+        xmx = masked_array(mx.data.__array__(), mask=mx.mask)
+        self.assertTrue(isinstance(divide(mx, mx), mmatrix))
+        self.assertTrue(isinstance(divide(mx, x), mmatrix))
+        assert_equal(divide(mx, mx), divide(xmx, xmx))
+
+    def test_attributepropagation(self):
+        x = array(arange(5), mask=[0]+[1]*4)
+        my = masked_array(subarray(x))
+        ym = msubarray(x)
+        #
+        z = (my+1)
+        self.assertTrue(isinstance(z, MaskedArray))
+        self.assertTrue(not isinstance(z, MSubArray))
+        self.assertTrue(isinstance(z._data, SubArray))
+        assert_equal(z._data.info, {})
+        #
+        z = (ym+1)
+        self.assertTrue(isinstance(z, MaskedArray))
+        self.assertTrue(isinstance(z, MSubArray))
+        self.assertTrue(isinstance(z._data, SubArray))
+        self.assertTrue(z._data.info['added'] > 0)
+        # Test that inplace methods from data get used (gh-4617)
+        ym += 1
+        self.assertTrue(isinstance(ym, MaskedArray))
+        self.assertTrue(isinstance(ym, MSubArray))
+        self.assertTrue(isinstance(ym._data, SubArray))
+        self.assertTrue(ym._data.info['iadded'] > 0)
+        #
+        ym._set_mask([1, 0, 0, 0, 1])
+        assert_equal(ym._mask, [1, 0, 0, 0, 1])
+        ym._series._set_mask([0, 0, 0, 0, 1])
+        assert_equal(ym._mask, [0, 0, 0, 0, 1])
+        #
+        xsub = subarray(x, info={'name':'x'})
+        mxsub = masked_array(xsub)
+        self.assertTrue(hasattr(mxsub, 'info'))
+        assert_equal(mxsub.info, xsub.info)
+
+    def test_subclasspreservation(self):
+        # Checks that masked_array(...,subok=True) preserves the class.
+        x = np.arange(5)
+        m = [0, 0, 1, 0, 0]
+        xinfo = [(i, j) for (i, j) in zip(x, m)]
+        xsub = MSubArray(x, mask=m, info={'xsub':xinfo})
+        #
+        mxsub = masked_array(xsub, subok=False)
+        self.assertTrue(not isinstance(mxsub, MSubArray))
+        self.assertTrue(isinstance(mxsub, MaskedArray))
+        assert_equal(mxsub._mask, m)
+        #
+        mxsub = asarray(xsub)
+        self.assertTrue(not isinstance(mxsub, MSubArray))
+        self.assertTrue(isinstance(mxsub, MaskedArray))
+        assert_equal(mxsub._mask, m)
+        #
+        mxsub = masked_array(xsub, subok=True)
+        self.assertTrue(isinstance(mxsub, MSubArray))
+        assert_equal(mxsub.info, xsub.info)
+        assert_equal(mxsub._mask, xsub._mask)
+        #
+        mxsub = asanyarray(xsub)
+        self.assertTrue(isinstance(mxsub, MSubArray))
+        assert_equal(mxsub.info, xsub.info)
+        assert_equal(mxsub._mask, m)
+
+    def test_subclass_items(self):
+        """test that getter and setter go via baseclass"""
+        x = np.arange(5)
+        xcsub = ComplicatedSubArray(x)
+        mxcsub = masked_array(xcsub, mask=[True, False, True, False, False])
+        # getter should  return a ComplicatedSubArray, even for single item
+        # first check we wrote ComplicatedSubArray correctly
+        self.assertTrue(isinstance(xcsub[1], ComplicatedSubArray))
+        self.assertTrue(isinstance(xcsub[1:4], ComplicatedSubArray))
+        # now that it propagates inside the MaskedArray
+        self.assertTrue(isinstance(mxcsub[1], ComplicatedSubArray))
+        self.assertTrue(mxcsub[0] is masked)
+        self.assertTrue(isinstance(mxcsub[1:4].data, ComplicatedSubArray))
+        # also for flattened version (which goes via MaskedIterator)
+        self.assertTrue(isinstance(mxcsub.flat[1].data, ComplicatedSubArray))
+        self.assertTrue(mxcsub[0] is masked)
+        self.assertTrue(isinstance(mxcsub.flat[1:4].base, ComplicatedSubArray))
+
+        # setter should only work with ComplicatedSubArray input
+        # first check we wrote ComplicatedSubArray correctly
+        assert_raises(ValueError, xcsub.__setitem__, 1, x[4])
+        # now that it propagates inside the MaskedArray
+        assert_raises(ValueError, mxcsub.__setitem__, 1, x[4])
+        assert_raises(ValueError, mxcsub.__setitem__, slice(1, 4), x[1:4])
+        mxcsub[1] = xcsub[4]
+        mxcsub[1:4] = xcsub[1:4]
+        # also for flattened version (which goes via MaskedIterator)
+        assert_raises(ValueError, mxcsub.flat.__setitem__, 1, x[4])
+        assert_raises(ValueError, mxcsub.flat.__setitem__, slice(1, 4), x[1:4])
+        mxcsub.flat[1] = xcsub[4]
+        mxcsub.flat[1:4] = xcsub[1:4]
+
+    def test_subclass_repr(self):
+        """test that repr uses the name of the subclass
+        and 'array' for np.ndarray"""
+        x = np.arange(5)
+        mx = masked_array(x, mask=[True, False, True, False, False])
+        self.assertTrue(repr(mx).startswith('masked_array'))
+        xsub = SubArray(x)
+        mxsub = masked_array(xsub, mask=[True, False, True, False, False])
+        self.assertTrue(repr(mxsub).startswith(
+            'masked_{0}(data = [-- 1 -- 3 4]'.format(SubArray.__name__)))
+
+    def test_subclass_str(self):
+        """test str with subclass that has overridden str, setitem"""
+        # first without override
+        x = np.arange(5)
+        xsub = SubArray(x)
+        mxsub = masked_array(xsub, mask=[True, False, True, False, False])
+        self.assertTrue(str(mxsub) == '[-- 1 -- 3 4]')
+
+        xcsub = ComplicatedSubArray(x)
+        assert_raises(ValueError, xcsub.__setitem__, 0,
+                      np.ma.core.masked_print_option)
+        mxcsub = masked_array(xcsub, mask=[True, False, True, False, False])
+        self.assertTrue(str(mxcsub) == 'myprefix [-- 1 -- 3 4] mypostfix')
+
+    def test_pure_subclass_info_preservation(self):
+        # Test that ufuncs and methods conserve extra information consistently;
+        # see gh-7122.
+        arr1 = SubMaskedArray('test', data=[1,2,3,4,5,6])
+        arr2 = SubMaskedArray(data=[0,1,2,3,4,5])
+        diff1 = np.subtract(arr1, arr2)
+        self.assertTrue('info' in diff1._optinfo)
+        self.assertTrue(diff1._optinfo['info'] == 'test')
+        diff2 = arr1 - arr2
+        self.assertTrue('info' in diff2._optinfo)
+        self.assertTrue(diff2._optinfo['info'] == 'test')
+
+
+###############################################################################
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/testutils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/testutils.py
new file mode 100644
index 0000000000..8dc8218784
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/testutils.py
@@ -0,0 +1,289 @@
+"""Miscellaneous functions for testing masked arrays and subclasses
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id: testutils.py 3529 2007-11-13 08:01:14Z jarrod.millman $
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import operator
+
+import numpy as np
+from numpy import ndarray, float_
+import numpy.core.umath as umath
+from numpy.testing import (
+    TestCase, assert_, assert_allclose, assert_array_almost_equal_nulp,
+    assert_raises, build_err_msg, run_module_suite,
+    )
+import numpy.testing.utils as utils
+from .core import mask_or, getmask, masked_array, nomask, masked, filled
+
+__all__masked = [
+    'almost', 'approx', 'assert_almost_equal', 'assert_array_almost_equal',
+    'assert_array_approx_equal', 'assert_array_compare',
+    'assert_array_equal', 'assert_array_less', 'assert_close',
+    'assert_equal', 'assert_equal_records', 'assert_mask_equal',
+    'assert_not_equal', 'fail_if_array_equal',
+    ]
+
+# Include some normal test functions to avoid breaking other projects who
+# have mistakenly included them from this file. SciPy is one. That is
+# unfortunate, as some of these functions are not intended to work with
+# masked arrays. But there was no way to tell before.
+__some__from_testing = [
+    'TestCase', 'assert_', 'assert_allclose',
+    'assert_array_almost_equal_nulp', 'assert_raises', 'run_module_suite',
+    ]
+
+__all__ = __all__masked + __some__from_testing
+
+
+def approx(a, b, fill_value=True, rtol=1e-5, atol=1e-8):
+    """
+    Returns true if all components of a and b are equal to given tolerances.
+
+    If fill_value is True, masked values considered equal. Otherwise,
+    masked values are considered unequal.  The relative error rtol should
+    be positive and << 1.0 The absolute error atol comes into play for
+    those elements of b that are very small or zero; it says how small a
+    must be also.
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    d1 = filled(a)
+    d2 = filled(b)
+    if d1.dtype.char == "O" or d2.dtype.char == "O":
+        return np.equal(d1, d2).ravel()
+    x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_)
+    y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_)
+    d = np.less_equal(umath.absolute(x - y), atol + rtol * umath.absolute(y))
+    return d.ravel()
+
+
+def almost(a, b, decimal=6, fill_value=True):
+    """
+    Returns True if a and b are equal up to decimal places.
+
+    If fill_value is True, masked values considered equal. Otherwise,
+    masked values are considered unequal.
+
+    """
+    m = mask_or(getmask(a), getmask(b))
+    d1 = filled(a)
+    d2 = filled(b)
+    if d1.dtype.char == "O" or d2.dtype.char == "O":
+        return np.equal(d1, d2).ravel()
+    x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_)
+    y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_)
+    d = np.around(np.abs(x - y), decimal) <= 10.0 ** (-decimal)
+    return d.ravel()
+
+
+def _assert_equal_on_sequences(actual, desired, err_msg=''):
+    """
+    Asserts the equality of two non-array sequences.
+
+    """
+    assert_equal(len(actual), len(desired), err_msg)
+    for k in range(len(desired)):
+        assert_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg))
+    return
+
+
+def assert_equal_records(a, b):
+    """
+    Asserts that two records are equal.
+
+    Pretty crude for now.
+
+    """
+    assert_equal(a.dtype, b.dtype)
+    for f in a.dtype.names:
+        (af, bf) = (operator.getitem(a, f), operator.getitem(b, f))
+        if not (af is masked) and not (bf is masked):
+            assert_equal(operator.getitem(a, f), operator.getitem(b, f))
+    return
+
+
+def assert_equal(actual, desired, err_msg=''):
+    """
+    Asserts that two items are equal.
+
+    """
+    # Case #1: dictionary .....
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        assert_equal(len(actual), len(desired), err_msg)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError("%s not in %s" % (k, actual))
+            assert_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg))
+        return
+    # Case #2: lists .....
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        return _assert_equal_on_sequences(actual, desired, err_msg='')
+    if not (isinstance(actual, ndarray) or isinstance(desired, ndarray)):
+        msg = build_err_msg([actual, desired], err_msg,)
+        if not desired == actual:
+            raise AssertionError(msg)
+        return
+    # Case #4. arrays or equivalent
+    if ((actual is masked) and not (desired is masked)) or \
+            ((desired is masked) and not (actual is masked)):
+        msg = build_err_msg([actual, desired],
+                            err_msg, header='', names=('x', 'y'))
+        raise ValueError(msg)
+    actual = np.array(actual, copy=False, subok=True)
+    desired = np.array(desired, copy=False, subok=True)
+    (actual_dtype, desired_dtype) = (actual.dtype, desired.dtype)
+    if actual_dtype.char == "S" and desired_dtype.char == "S":
+        return _assert_equal_on_sequences(actual.tolist(),
+                                          desired.tolist(),
+                                          err_msg='')
+    return assert_array_equal(actual, desired, err_msg)
+
+
+def fail_if_equal(actual, desired, err_msg='',):
+    """
+    Raises an assertion error if two items are equal.
+
+    """
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        fail_if_equal(len(actual), len(desired), err_msg)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError(repr(k))
+            fail_if_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg))
+        return
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        fail_if_equal(len(actual), len(desired), err_msg)
+        for k in range(len(desired)):
+            fail_if_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg))
+        return
+    if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray):
+        return fail_if_array_equal(actual, desired, err_msg)
+    msg = build_err_msg([actual, desired], err_msg)
+    if not desired != actual:
+        raise AssertionError(msg)
+
+
+assert_not_equal = fail_if_equal
+
+
+def assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True):
+    """
+    Asserts that two items are almost equal.
+
+    The test is equivalent to abs(desired-actual) < 0.5 * 10**(-decimal).
+
+    """
+    if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray):
+        return assert_array_almost_equal(actual, desired, decimal=decimal,
+                                         err_msg=err_msg, verbose=verbose)
+    msg = build_err_msg([actual, desired],
+                        err_msg=err_msg, verbose=verbose)
+    if not round(abs(desired - actual), decimal) == 0:
+        raise AssertionError(msg)
+
+
+assert_close = assert_almost_equal
+
+
+def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='',
+                         fill_value=True):
+    """
+    Asserts that comparison between two masked arrays is satisfied.
+
+    The comparison is elementwise.
+
+    """
+    # Allocate a common mask and refill
+    m = mask_or(getmask(x), getmask(y))
+    x = masked_array(x, copy=False, mask=m, keep_mask=False, subok=False)
+    y = masked_array(y, copy=False, mask=m, keep_mask=False, subok=False)
+    if ((x is masked) and not (y is masked)) or \
+            ((y is masked) and not (x is masked)):
+        msg = build_err_msg([x, y], err_msg=err_msg, verbose=verbose,
+                            header=header, names=('x', 'y'))
+        raise ValueError(msg)
+    # OK, now run the basic tests on filled versions
+    return utils.assert_array_compare(comparison,
+                                      x.filled(fill_value),
+                                      y.filled(fill_value),
+                                      err_msg=err_msg,
+                                      verbose=verbose, header=header)
+
+
+def assert_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Checks the elementwise equality of two masked arrays.
+
+    """
+    assert_array_compare(operator.__eq__, x, y,
+                         err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not equal')
+
+
+def fail_if_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Raises an assertion error if two masked arrays are not equal elementwise.
+
+    """
+    def compare(x, y):
+        return (not np.alltrue(approx(x, y)))
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not equal')
+
+
+def assert_array_approx_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Checks the equality of two masked arrays, up to given number odecimals.
+
+    The equality is checked elementwise.
+
+    """
+    def compare(x, y):
+        "Returns the result of the loose comparison between x and y)."
+        return approx(x, y, rtol=10. ** -decimal)
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not almost equal')
+
+
+def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Checks the equality of two masked arrays, up to given number odecimals.
+
+    The equality is checked elementwise.
+
+    """
+    def compare(x, y):
+        "Returns the result of the loose comparison between x and y)."
+        return almost(x, y, decimal)
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not almost equal')
+
+
+def assert_array_less(x, y, err_msg='', verbose=True):
+    """
+    Checks that x is smaller than y elementwise.
+
+    """
+    assert_array_compare(operator.__lt__, x, y,
+                         err_msg=err_msg, verbose=verbose,
+                         header='Arrays are not less-ordered')
+
+
+def assert_mask_equal(m1, m2, err_msg=''):
+    """
+    Asserts the equality of two masks.
+
+    """
+    if m1 is nomask:
+        assert_(m2 is nomask)
+    if m2 is nomask:
+        assert_(m1 is nomask)
+    assert_array_equal(m1, m2, err_msg=err_msg)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
new file mode 100644
index 0000000000..dae4b141b0
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
@@ -0,0 +1,440 @@
+from __future__ import division, absolute_import, print_function
+
+import timeit
+from functools import reduce
+
+import numpy as np
+from numpy import float_
+import numpy.core.fromnumeric as fromnumeric
+
+from numpy.testing.utils import build_err_msg
+
+# Fixme: this does not look right.
+np.seterr(all='ignore')
+
+pi = np.pi
+
+
+class ModuleTester(object):
+    def __init__(self, module):
+        self.module = module
+        self.allequal = module.allequal
+        self.arange = module.arange
+        self.array = module.array
+        self.concatenate = module.concatenate
+        self.count = module.count
+        self.equal = module.equal
+        self.filled = module.filled
+        self.getmask = module.getmask
+        self.getmaskarray = module.getmaskarray
+        self.id = id
+        self.inner = module.inner
+        self.make_mask = module.make_mask
+        self.masked = module.masked
+        self.masked_array = module.masked_array
+        self.masked_values = module.masked_values
+        self.mask_or = module.mask_or
+        self.nomask = module.nomask
+        self.ones = module.ones
+        self.outer = module.outer
+        self.repeat = module.repeat
+        self.resize = module.resize
+        self.sort = module.sort
+        self.take = module.take
+        self.transpose = module.transpose
+        self.zeros = module.zeros
+        self.MaskType = module.MaskType
+        try:
+            self.umath = module.umath
+        except AttributeError:
+            self.umath = module.core.umath
+        self.testnames = []
+
+    def assert_array_compare(self, comparison, x, y, err_msg='', header='',
+                         fill_value=True):
+        """
+        Assert that a comparison of two masked arrays is satisfied elementwise.
+
+        """
+        xf = self.filled(x)
+        yf = self.filled(y)
+        m = self.mask_or(self.getmask(x), self.getmask(y))
+
+        x = self.filled(self.masked_array(xf, mask=m), fill_value)
+        y = self.filled(self.masked_array(yf, mask=m), fill_value)
+        if (x.dtype.char != "O"):
+            x = x.astype(float_)
+            if isinstance(x, np.ndarray) and x.size > 1:
+                x[np.isnan(x)] = 0
+            elif np.isnan(x):
+                x = 0
+        if (y.dtype.char != "O"):
+            y = y.astype(float_)
+            if isinstance(y, np.ndarray) and y.size > 1:
+                y[np.isnan(y)] = 0
+            elif np.isnan(y):
+                y = 0
+        try:
+            cond = (x.shape == () or y.shape == ()) or x.shape == y.shape
+            if not cond:
+                msg = build_err_msg([x, y],
+                                    err_msg
+                                    + '\n(shapes %s, %s mismatch)' % (x.shape,
+                                                                      y.shape),
+                                    header=header,
+                                    names=('x', 'y'))
+                assert cond, msg
+            val = comparison(x, y)
+            if m is not self.nomask and fill_value:
+                val = self.masked_array(val, mask=m)
+            if isinstance(val, bool):
+                cond = val
+                reduced = [0]
+            else:
+                reduced = val.ravel()
+                cond = reduced.all()
+                reduced = reduced.tolist()
+            if not cond:
+                match = 100-100.0*reduced.count(1)/len(reduced)
+                msg = build_err_msg([x, y],
+                                    err_msg
+                                    + '\n(mismatch %s%%)' % (match,),
+                                    header=header,
+                                    names=('x', 'y'))
+                assert cond, msg
+        except ValueError:
+            msg = build_err_msg([x, y], err_msg, header=header, names=('x', 'y'))
+            raise ValueError(msg)
+
+    def assert_array_equal(self, x, y, err_msg=''):
+        """
+        Checks the elementwise equality of two masked arrays.
+
+        """
+        self.assert_array_compare(self.equal, x, y, err_msg=err_msg,
+                                  header='Arrays are not equal')
+
+    def test_0(self):
+        """
+        Tests creation
+
+        """
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        xm = self.masked_array(x, mask=m)
+        xm[0]
+
+    def test_1(self):
+        """
+        Tests creation
+
+        """
+        x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
+        y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
+        m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
+        m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
+        xm = self.masked_array(x, mask=m1)
+        ym = self.masked_array(y, mask=m2)
+        xf = np.where(m1, 1.e+20, x)
+        xm.set_fill_value(1.e+20)
+
+        assert((xm-ym).filled(0).any())
+        s = x.shape
+        assert(xm.size == reduce(lambda x, y:x*y, s))
+        assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
+
+        for s in [(4, 3), (6, 2)]:
+            x.shape = s
+            y.shape = s
+            xm.shape = s
+            ym.shape = s
+            xf.shape = s
+            assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
+
+    def test_2(self):
+        """
+        Tests conversions and indexing.
+
+        """
+        x1 = np.array([1, 2, 4, 3])
+        x2 = self.array(x1, mask=[1, 0, 0, 0])
+        x3 = self.array(x1, mask=[0, 1, 0, 1])
+        x4 = self.array(x1)
+        # test conversion to strings, no errors
+        str(x2)
+        repr(x2)
+        # tests of indexing
+        assert type(x2[1]) is type(x1[1])
+        assert x1[1] == x2[1]
+        x1[2] = 9
+        x2[2] = 9
+        self.assert_array_equal(x1, x2)
+        x1[1:3] = 99
+        x2[1:3] = 99
+        x2[1] = self.masked
+        x2[1:3] = self.masked
+        x2[:] = x1
+        x2[1] = self.masked
+        x3[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        x4[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
+        x1 = np.arange(5)*1.0
+        x2 = self.masked_values(x1, 3.0)
+        x1 = self.array([1, 'hello', 2, 3], object)
+        x2 = np.array([1, 'hello', 2, 3], object)
+        # check that no error occurs.
+        x1[1]
+        x2[1]
+        assert x1[1:1].shape == (0,)
+        # Tests copy-size
+        n = [0, 0, 1, 0, 0]
+        m = self.make_mask(n)
+        m2 = self.make_mask(m)
+        assert(m is m2)
+        m3 = self.make_mask(m, copy=1)
+        assert(m is not m3)
+
+    def test_3(self):
+        """
+        Tests resize/repeat
+
+        """
+        x4 = self.arange(4)
+        x4[2] = self.masked
+        y4 = self.resize(x4, (8,))
+        assert self.allequal(self.concatenate([x4, x4]), y4)
+        assert self.allequal(self.getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
+        y5 = self.repeat(x4, (2, 2, 2, 2), axis=0)
+        self.assert_array_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
+        y6 = self.repeat(x4, 2, axis=0)
+        assert self.allequal(y5, y6)
+        y7 = x4.repeat((2, 2, 2, 2), axis=0)
+        assert self.allequal(y5, y7)
+        y8 = x4.repeat(2, 0)
+        assert self.allequal(y5, y8)
+
+    def test_4(self):
+        """
+        Test of take, transpose, inner, outer products.
+
+        """
+        x = self.arange(24)
+        y = np.arange(24)
+        x[5:6] = self.masked
+        x = x.reshape(2, 3, 4)
+        y = y.reshape(2, 3, 4)
+        assert self.allequal(np.transpose(y, (2, 0, 1)), self.transpose(x, (2, 0, 1)))
+        assert self.allequal(np.take(y, (2, 0, 1), 1), self.take(x, (2, 0, 1), 1))
+        assert self.allequal(np.inner(self.filled(x, 0), self.filled(y, 0)),
+                            self.inner(x, y))
+        assert self.allequal(np.outer(self.filled(x, 0), self.filled(y, 0)),
+                            self.outer(x, y))
+        y = self.array(['abc', 1, 'def', 2, 3], object)
+        y[2] = self.masked
+        t = self.take(y, [0, 3, 4])
+        assert t[0] == 'abc'
+        assert t[1] == 2
+        assert t[2] == 3
+
+    def test_5(self):
+        """
+        Tests inplace w/ scalar
+
+        """
+        x = self.arange(10)
+        y = self.arange(10)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x += 1
+        assert self.allequal(x, y+1)
+        xm += 1
+        assert self.allequal(xm, y+1)
+
+        x = self.arange(10)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x -= 1
+        assert self.allequal(x, y-1)
+        xm -= 1
+        assert self.allequal(xm, y-1)
+
+        x = self.arange(10)*1.0
+        xm = self.arange(10)*1.0
+        xm[2] = self.masked
+        x *= 2.0
+        assert self.allequal(x, y*2)
+        xm *= 2.0
+        assert self.allequal(xm, y*2)
+
+        x = self.arange(10)*2
+        xm = self.arange(10)*2
+        xm[2] = self.masked
+        x /= 2
+        assert self.allequal(x, y)
+        xm /= 2
+        assert self.allequal(xm, y)
+
+        x = self.arange(10)*1.0
+        xm = self.arange(10)*1.0
+        xm[2] = self.masked
+        x /= 2.0
+        assert self.allequal(x, y/2.0)
+        xm /= self.arange(10)
+        self.assert_array_equal(xm, self.ones((10,)))
+
+        x = self.arange(10).astype(float_)
+        xm = self.arange(10)
+        xm[2] = self.masked
+        x += 1.
+        assert self.allequal(x, y + 1.)
+
+    def test_6(self):
+        """
+        Tests inplace w/ array
+
+        """
+        x = self.arange(10, dtype=float_)
+        y = self.arange(10)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x += a
+        xm += a
+        assert self.allequal(x, y+a)
+        assert self.allequal(xm, y+a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x -= a
+        xm -= a
+        assert self.allequal(x, y-a)
+        assert self.allequal(xm, y-a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x *= a
+        xm *= a
+        assert self.allequal(x, y*a)
+        assert self.allequal(xm, y*a)
+        assert self.allequal(xm.mask, self.mask_or(m, a.mask))
+
+        x = self.arange(10, dtype=float_)
+        xm = self.arange(10, dtype=float_)
+        xm[2] = self.masked
+        m = xm.mask
+        a = self.arange(10, dtype=float_)
+        a[-1] = self.masked
+        x /= a
+        xm /= a
+
+    def test_7(self):
+        "Tests ufunc"
+        d = (self.array([1.0, 0, -1, pi/2]*2, mask=[0, 1]+[0]*6),
+             self.array([1.0, 0, -1, pi/2]*2, mask=[1, 0]+[0]*6),)
+        for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
+#                  'sin', 'cos', 'tan',
+#                  'arcsin', 'arccos', 'arctan',
+#                  'sinh', 'cosh', 'tanh',
+#                  'arcsinh',
+#                  'arccosh',
+#                  'arctanh',
+#                  'absolute', 'fabs', 'negative',
+#                  # 'nonzero', 'around',
+#                  'floor', 'ceil',
+#                  # 'sometrue', 'alltrue',
+#                  'logical_not',
+#                  'add', 'subtract', 'multiply',
+#                  'divide', 'true_divide', 'floor_divide',
+#                  'remainder', 'fmod', 'hypot', 'arctan2',
+#                  'equal', 'not_equal', 'less_equal', 'greater_equal',
+#                  'less', 'greater',
+#                  'logical_and', 'logical_or', 'logical_xor',
+                  ]:
+            try:
+                uf = getattr(self.umath, f)
+            except AttributeError:
+                uf = getattr(fromnumeric, f)
+            mf = getattr(self.module, f)
+            args = d[:uf.nin]
+            ur = uf(*args)
+            mr = mf(*args)
+            self.assert_array_equal(ur.filled(0), mr.filled(0), f)
+            self.assert_array_equal(ur._mask, mr._mask)
+
+    def test_99(self):
+        # test average
+        ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        self.assert_array_equal(2.0, self.average(ott, axis=0))
+        self.assert_array_equal(2.0, self.average(ott, weights=[1., 1., 2., 1.]))
+        result, wts = self.average(ott, weights=[1., 1., 2., 1.], returned=1)
+        self.assert_array_equal(2.0, result)
+        assert(wts == 4.0)
+        ott[:] = self.masked
+        assert(self.average(ott, axis=0) is self.masked)
+        ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
+        ott = ott.reshape(2, 2)
+        ott[:, 1] = self.masked
+        self.assert_array_equal(self.average(ott, axis=0), [2.0, 0.0])
+        assert(self.average(ott, axis=1)[0] is self.masked)
+        self.assert_array_equal([2., 0.], self.average(ott, axis=0))
+        result, wts = self.average(ott, axis=0, returned=1)
+        self.assert_array_equal(wts, [1., 0.])
+        w1 = [0, 1, 1, 1, 1, 0]
+        w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
+        x = self.arange(6)
+        self.assert_array_equal(self.average(x, axis=0), 2.5)
+        self.assert_array_equal(self.average(x, axis=0, weights=w1), 2.5)
+        y = self.array([self.arange(6), 2.0*self.arange(6)])
+        self.assert_array_equal(self.average(y, None), np.add.reduce(np.arange(6))*3./12.)
+        self.assert_array_equal(self.average(y, axis=0), np.arange(6) * 3./2.)
+        self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
+        self.assert_array_equal(self.average(y, None, weights=w2), 20./6.)
+        self.assert_array_equal(self.average(y, axis=0, weights=w2), [0., 1., 2., 3., 4., 10.])
+        self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
+        m1 = self.zeros(6)
+        m2 = [0, 0, 1, 1, 0, 0]
+        m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
+        m4 = self.ones(6)
+        m5 = [0, 1, 1, 1, 1, 1]
+        self.assert_array_equal(self.average(self.masked_array(x, m1), axis=0), 2.5)
+        self.assert_array_equal(self.average(self.masked_array(x, m2), axis=0), 2.5)
+        self.assert_array_equal(self.average(self.masked_array(x, m5), axis=0), 0.0)
+        self.assert_array_equal(self.count(self.average(self.masked_array(x, m4), axis=0)), 0)
+        z = self.masked_array(y, m3)
+        self.assert_array_equal(self.average(z, None), 20./6.)
+        self.assert_array_equal(self.average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5])
+        self.assert_array_equal(self.average(z, axis=1), [2.5, 5.0])
+        self.assert_array_equal(self.average(z, axis=0, weights=w2), [0., 1., 99., 99., 4.0, 10.0])
+
+    def test_A(self):
+        x = self.arange(24)
+        x[5:6] = self.masked
+        x = x.reshape(2, 3, 4)
+
+
+if __name__ == '__main__':
+    setup_base = ("from __main__ import ModuleTester \n"
+                  "import numpy\n"
+                  "tester = ModuleTester(module)\n")
+    setup_cur = "import numpy.ma.core as module\n" + setup_base
+    (nrepeat, nloop) = (10, 10)
+
+    if 1:
+        for i in range(1, 8):
+            func = 'tester.test_%i()' % i
+            cur = timeit.Timer(func, setup_cur).repeat(nrepeat, nloop*10)
+            cur = np.sort(cur)
+            print("#%i" % i + 50*'.')
+            print(eval("ModuleTester.test_%i.__doc__" % i))
+            print("core_current : %.3f - %.3f" % (cur[0], cur[1]))
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/version.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/version.py
new file mode 100644
index 0000000000..a2c5c42a80
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/ma/version.py
@@ -0,0 +1,14 @@
+"""Version number
+
+"""
+from __future__ import division, absolute_import, print_function
+
+version = '1.00'
+release = False
+
+if not release:
+    from . import core
+    from . import extras
+    revision = [core.__revision__.split(':')[-1][:-1].strip(),
+                extras.__revision__.split(':')[-1][:-1].strip(),]
+    version += '.dev%04i' % max([int(rev) for rev in revision])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matlib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matlib.py
new file mode 100644
index 0000000000..656ca34588
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matlib.py
@@ -0,0 +1,358 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.matrixlib.defmatrix import matrix, asmatrix
+# need * as we're copying the numpy namespace
+from numpy import *
+
+__version__ = np.__version__
+
+__all__ = np.__all__[:] # copy numpy namespace
+__all__ += ['rand', 'randn', 'repmat']
+
+def empty(shape, dtype=None, order='C'):
+    """Return a new matrix of given shape and type, without initializing entries.
+
+    Parameters
+    ----------
+    shape : int or tuple of int
+        Shape of the empty matrix.
+    dtype : data-type, optional
+        Desired output data-type.
+    order : {'C', 'F'}, optional
+        Whether to store multi-dimensional data in row-major
+        (C-style) or column-major (Fortran-style) order in
+        memory.
+
+    See Also
+    --------
+    empty_like, zeros
+
+    Notes
+    -----
+    `empty`, unlike `zeros`, does not set the matrix values to zero,
+    and may therefore be marginally faster.  On the other hand, it requires
+    the user to manually set all the values in the array, and should be
+    used with caution.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.empty((2, 2))    # filled with random data
+    matrix([[  6.76425276e-320,   9.79033856e-307],
+            [  7.39337286e-309,   3.22135945e-309]])        #random
+    >>> np.matlib.empty((2, 2), dtype=int)
+    matrix([[ 6600475,        0],
+            [ 6586976, 22740995]])                          #random
+
+    """
+    return ndarray.__new__(matrix, shape, dtype, order=order)
+
+def ones(shape, dtype=None, order='C'):
+    """
+    Matrix of ones.
+
+    Return a matrix of given shape and type, filled with ones.
+
+    Parameters
+    ----------
+    shape : {sequence of ints, int}
+        Shape of the matrix
+    dtype : data-type, optional
+        The desired data-type for the matrix, default is np.float64.
+    order : {'C', 'F'}, optional
+        Whether to store matrix in C- or Fortran-contiguous order,
+        default is 'C'.
+
+    Returns
+    -------
+    out : matrix
+        Matrix of ones of given shape, dtype, and order.
+
+    See Also
+    --------
+    ones : Array of ones.
+    matlib.zeros : Zero matrix.
+
+    Notes
+    -----
+    If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
+    `out` becomes a single row matrix of shape ``(1,N)``.
+
+    Examples
+    --------
+    >>> np.matlib.ones((2,3))
+    matrix([[ 1.,  1.,  1.],
+            [ 1.,  1.,  1.]])
+
+    >>> np.matlib.ones(2)
+    matrix([[ 1.,  1.]])
+
+    """
+    a = ndarray.__new__(matrix, shape, dtype, order=order)
+    a.fill(1)
+    return a
+
+def zeros(shape, dtype=None, order='C'):
+    """
+    Return a matrix of given shape and type, filled with zeros.
+
+    Parameters
+    ----------
+    shape : int or sequence of ints
+        Shape of the matrix
+    dtype : data-type, optional
+        The desired data-type for the matrix, default is float.
+    order : {'C', 'F'}, optional
+        Whether to store the result in C- or Fortran-contiguous order,
+        default is 'C'.
+
+    Returns
+    -------
+    out : matrix
+        Zero matrix of given shape, dtype, and order.
+
+    See Also
+    --------
+    numpy.zeros : Equivalent array function.
+    matlib.ones : Return a matrix of ones.
+
+    Notes
+    -----
+    If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``,
+    `out` becomes a single row matrix of shape ``(1,N)``.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.zeros((2, 3))
+    matrix([[ 0.,  0.,  0.],
+            [ 0.,  0.,  0.]])
+
+    >>> np.matlib.zeros(2)
+    matrix([[ 0.,  0.]])
+
+    """
+    a = ndarray.__new__(matrix, shape, dtype, order=order)
+    a.fill(0)
+    return a
+
+def identity(n,dtype=None):
+    """
+    Returns the square identity matrix of given size.
+
+    Parameters
+    ----------
+    n : int
+        Size of the returned identity matrix.
+    dtype : data-type, optional
+        Data-type of the output. Defaults to ``float``.
+
+    Returns
+    -------
+    out : matrix
+        `n` x `n` matrix with its main diagonal set to one,
+        and all other elements zero.
+
+    See Also
+    --------
+    numpy.identity : Equivalent array function.
+    matlib.eye : More general matrix identity function.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.identity(3, dtype=int)
+    matrix([[1, 0, 0],
+            [0, 1, 0],
+            [0, 0, 1]])
+
+    """
+    a = array([1]+n*[0], dtype=dtype)
+    b = empty((n, n), dtype=dtype)
+    b.flat = a
+    return b
+
+def eye(n,M=None, k=0, dtype=float):
+    """
+    Return a matrix with ones on the diagonal and zeros elsewhere.
+
+    Parameters
+    ----------
+    n : int
+        Number of rows in the output.
+    M : int, optional
+        Number of columns in the output, defaults to `n`.
+    k : int, optional
+        Index of the diagonal: 0 refers to the main diagonal,
+        a positive value refers to an upper diagonal,
+        and a negative value to a lower diagonal.
+    dtype : dtype, optional
+        Data-type of the returned matrix.
+
+    Returns
+    -------
+    I : matrix
+        A `n` x `M` matrix where all elements are equal to zero,
+        except for the `k`-th diagonal, whose values are equal to one.
+
+    See Also
+    --------
+    numpy.eye : Equivalent array function.
+    identity : Square identity matrix.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.eye(3, k=1, dtype=float)
+    matrix([[ 0.,  1.,  0.],
+            [ 0.,  0.,  1.],
+            [ 0.,  0.,  0.]])
+
+    """
+    return asmatrix(np.eye(n, M, k, dtype))
+
+def rand(*args):
+    """
+    Return a matrix of random values with given shape.
+
+    Create a matrix of the given shape and propagate it with
+    random samples from a uniform distribution over ``[0, 1)``.
+
+    Parameters
+    ----------
+    \\*args : Arguments
+        Shape of the output.
+        If given as N integers, each integer specifies the size of one
+        dimension.
+        If given as a tuple, this tuple gives the complete shape.
+
+    Returns
+    -------
+    out : ndarray
+        The matrix of random values with shape given by `\\*args`.
+
+    See Also
+    --------
+    randn, numpy.random.rand
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.rand(2, 3)
+    matrix([[ 0.68340382,  0.67926887,  0.83271405],
+            [ 0.00793551,  0.20468222,  0.95253525]])       #random
+    >>> np.matlib.rand((2, 3))
+    matrix([[ 0.84682055,  0.73626594,  0.11308016],
+            [ 0.85429008,  0.3294825 ,  0.89139555]])       #random
+
+    If the first argument is a tuple, other arguments are ignored:
+
+    >>> np.matlib.rand((2, 3), 4)
+    matrix([[ 0.46898646,  0.15163588,  0.95188261],
+            [ 0.59208621,  0.09561818,  0.00583606]])       #random
+
+    """
+    if isinstance(args[0], tuple):
+        args = args[0]
+    return asmatrix(np.random.rand(*args))
+
+def randn(*args):
+    """
+    Return a random matrix with data from the "standard normal" distribution.
+
+    `randn` generates a matrix filled with random floats sampled from a
+    univariate "normal" (Gaussian) distribution of mean 0 and variance 1.
+
+    Parameters
+    ----------
+    \\*args : Arguments
+        Shape of the output.
+        If given as N integers, each integer specifies the size of one
+        dimension. If given as a tuple, this tuple gives the complete shape.
+
+    Returns
+    -------
+    Z : matrix of floats
+        A matrix of floating-point samples drawn from the standard normal
+        distribution.
+
+    See Also
+    --------
+    rand, random.randn
+
+    Notes
+    -----
+    For random samples from :math:`N(\\mu, \\sigma^2)`, use:
+
+    ``sigma * np.matlib.randn(...) + mu``
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> np.matlib.randn(1)
+    matrix([[-0.09542833]])                                 #random
+    >>> np.matlib.randn(1, 2, 3)
+    matrix([[ 0.16198284,  0.0194571 ,  0.18312985],
+            [-0.7509172 ,  1.61055   ,  0.45298599]])       #random
+
+    Two-by-four matrix of samples from :math:`N(3, 6.25)`:
+
+    >>> 2.5 * np.matlib.randn((2, 4)) + 3
+    matrix([[ 4.74085004,  8.89381862,  4.09042411,  4.83721922],
+            [ 7.52373709,  5.07933944, -2.64043543,  0.45610557]])  #random
+
+    """
+    if isinstance(args[0], tuple):
+        args = args[0]
+    return asmatrix(np.random.randn(*args))
+
+def repmat(a, m, n):
+    """
+    Repeat a 0-D to 2-D array or matrix MxN times.
+
+    Parameters
+    ----------
+    a : array_like
+        The array or matrix to be repeated.
+    m, n : int
+        The number of times `a` is repeated along the first and second axes.
+
+    Returns
+    -------
+    out : ndarray
+        The result of repeating `a`.
+
+    Examples
+    --------
+    >>> import numpy.matlib
+    >>> a0 = np.array(1)
+    >>> np.matlib.repmat(a0, 2, 3)
+    array([[1, 1, 1],
+           [1, 1, 1]])
+
+    >>> a1 = np.arange(4)
+    >>> np.matlib.repmat(a1, 2, 2)
+    array([[0, 1, 2, 3, 0, 1, 2, 3],
+           [0, 1, 2, 3, 0, 1, 2, 3]])
+
+    >>> a2 = np.asmatrix(np.arange(6).reshape(2, 3))
+    >>> np.matlib.repmat(a2, 2, 3)
+    matrix([[0, 1, 2, 0, 1, 2, 0, 1, 2],
+            [3, 4, 5, 3, 4, 5, 3, 4, 5],
+            [0, 1, 2, 0, 1, 2, 0, 1, 2],
+            [3, 4, 5, 3, 4, 5, 3, 4, 5]])
+
+    """
+    a = asanyarray(a)
+    ndim = a.ndim
+    if ndim == 0:
+        origrows, origcols = (1, 1)
+    elif ndim == 1:
+        origrows, origcols = (1, a.shape[0])
+    else:
+        origrows, origcols = a.shape
+    rows = origrows * m
+    cols = origcols * n
+    c = a.reshape(1, a.size).repeat(m, 0).reshape(rows, origcols).repeat(n, 0)
+    return c.reshape(rows, cols)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
new file mode 100644
index 0000000000..b2b76837a8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
@@ -0,0 +1,12 @@
+"""Sub-package containing the matrix class and related functions.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from .defmatrix import *
+
+__all__ = defmatrix.__all__
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
new file mode 100644
index 0000000000..1a29fb67b0
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
@@ -0,0 +1,1242 @@
+from __future__ import division, absolute_import, print_function
+
+__all__ = ['matrix', 'bmat', 'mat', 'asmatrix']
+
+import sys
+import numpy.core.numeric as N
+from numpy.core.numeric import concatenate, isscalar, binary_repr, identity, asanyarray
+from numpy.core.numerictypes import issubdtype
+
+# make translation table
+_numchars = '0123456789.-+jeEL'
+
+if sys.version_info[0] >= 3:
+    class _NumCharTable:
+        def __getitem__(self, i):
+            if chr(i) in _numchars:
+                return chr(i)
+            else:
+                return None
+    _table = _NumCharTable()
+    def _eval(astr):
+        str_ = astr.translate(_table)
+        if not str_:
+            raise TypeError("Invalid data string supplied: " + astr)
+        else:
+            return eval(str_)
+
+else:
+    _table = [None]*256
+    for k in range(256):
+        _table[k] = chr(k)
+    _table = ''.join(_table)
+
+    _todelete = []
+    for k in _table:
+        if k not in _numchars:
+            _todelete.append(k)
+    _todelete = ''.join(_todelete)
+    del k
+
+    def _eval(astr):
+        str_ = astr.translate(_table, _todelete)
+        if not str_:
+            raise TypeError("Invalid data string supplied: " + astr)
+        else:
+            return eval(str_)
+
+def _convert_from_string(data):
+    rows = data.split(';')
+    newdata = []
+    count = 0
+    for row in rows:
+        trow = row.split(',')
+        newrow = []
+        for col in trow:
+            temp = col.split()
+            newrow.extend(map(_eval, temp))
+        if count == 0:
+            Ncols = len(newrow)
+        elif len(newrow) != Ncols:
+            raise ValueError("Rows not the same size.")
+        count += 1
+        newdata.append(newrow)
+    return newdata
+
+def asmatrix(data, dtype=None):
+    """
+    Interpret the input as a matrix.
+
+    Unlike `matrix`, `asmatrix` does not make a copy if the input is already
+    a matrix or an ndarray.  Equivalent to ``matrix(data, copy=False)``.
+
+    Parameters
+    ----------
+    data : array_like
+        Input data.
+    dtype : data-type
+       Data-type of the output matrix.
+
+    Returns
+    -------
+    mat : matrix
+        `data` interpreted as a matrix.
+
+    Examples
+    --------
+    >>> x = np.array([[1, 2], [3, 4]])
+
+    >>> m = np.asmatrix(x)
+
+    >>> x[0,0] = 5
+
+    >>> m
+    matrix([[5, 2],
+            [3, 4]])
+
+    """
+    return matrix(data, dtype=dtype, copy=False)
+
+def matrix_power(M, n):
+    """
+    Raise a square matrix to the (integer) power `n`.
+
+    For positive integers `n`, the power is computed by repeated matrix
+    squarings and matrix multiplications. If ``n == 0``, the identity matrix
+    of the same shape as M is returned. If ``n < 0``, the inverse
+    is computed and then raised to the ``abs(n)``.
+
+    Parameters
+    ----------
+    M : ndarray or matrix object
+        Matrix to be "powered."  Must be square, i.e. ``M.shape == (m, m)``,
+        with `m` a positive integer.
+    n : int
+        The exponent can be any integer or long integer, positive,
+        negative, or zero.
+
+    Returns
+    -------
+    M**n : ndarray or matrix object
+        The return value is the same shape and type as `M`;
+        if the exponent is positive or zero then the type of the
+        elements is the same as those of `M`. If the exponent is
+        negative the elements are floating-point.
+
+    Raises
+    ------
+    LinAlgError
+        If the matrix is not numerically invertible.
+
+    See Also
+    --------
+    matrix
+        Provides an equivalent function as the exponentiation operator
+        (``**``, not ``^``).
+
+    Examples
+    --------
+    >>> from numpy import linalg as LA
+    >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit
+    >>> LA.matrix_power(i, 3) # should = -i
+    array([[ 0, -1],
+           [ 1,  0]])
+    >>> LA.matrix_power(np.matrix(i), 3) # matrix arg returns matrix
+    matrix([[ 0, -1],
+            [ 1,  0]])
+    >>> LA.matrix_power(i, 0)
+    array([[1, 0],
+           [0, 1]])
+    >>> LA.matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements
+    array([[ 0.,  1.],
+           [-1.,  0.]])
+
+    Somewhat more sophisticated example
+
+    >>> q = np.zeros((4, 4))
+    >>> q[0:2, 0:2] = -i
+    >>> q[2:4, 2:4] = i
+    >>> q # one of the three quarternion units not equal to 1
+    array([[ 0., -1.,  0.,  0.],
+           [ 1.,  0.,  0.,  0.],
+           [ 0.,  0.,  0.,  1.],
+           [ 0.,  0., -1.,  0.]])
+    >>> LA.matrix_power(q, 2) # = -np.eye(4)
+    array([[-1.,  0.,  0.,  0.],
+           [ 0., -1.,  0.,  0.],
+           [ 0.,  0., -1.,  0.],
+           [ 0.,  0.,  0., -1.]])
+
+    """
+    M = asanyarray(M)
+    if len(M.shape) != 2 or M.shape[0] != M.shape[1]:
+        raise ValueError("input must be a square array")
+    if not issubdtype(type(n), int):
+        raise TypeError("exponent must be an integer")
+
+    from numpy.linalg import inv
+
+    if n==0:
+        M = M.copy()
+        M[:] = identity(M.shape[0])
+        return M
+    elif n<0:
+        M = inv(M)
+        n *= -1
+
+    result = M
+    if n <= 3:
+        for _ in range(n-1):
+            result=N.dot(result, M)
+        return result
+
+    # binary decomposition to reduce the number of Matrix
+    # multiplications for n > 3.
+    beta = binary_repr(n)
+    Z, q, t = M, 0, len(beta)
+    while beta[t-q-1] == '0':
+        Z = N.dot(Z, Z)
+        q += 1
+    result = Z
+    for k in range(q+1, t):
+        Z = N.dot(Z, Z)
+        if beta[t-k-1] == '1':
+            result = N.dot(result, Z)
+    return result
+
+
+class matrix(N.ndarray):
+    """
+    matrix(data, dtype=None, copy=True)
+
+    Returns a matrix from an array-like object, or from a string of data.
+    A matrix is a specialized 2-D array that retains its 2-D nature
+    through operations.  It has certain special operators, such as ``*``
+    (matrix multiplication) and ``**`` (matrix power).
+
+    Parameters
+    ----------
+    data : array_like or string
+       If `data` is a string, it is interpreted as a matrix with commas
+       or spaces separating columns, and semicolons separating rows.
+    dtype : data-type
+       Data-type of the output matrix.
+    copy : bool
+       If `data` is already an `ndarray`, then this flag determines
+       whether the data is copied (the default), or whether a view is
+       constructed.
+
+    See Also
+    --------
+    array
+
+    Examples
+    --------
+    >>> a = np.matrix('1 2; 3 4')
+    >>> print(a)
+    [[1 2]
+     [3 4]]
+
+    >>> np.matrix([[1, 2], [3, 4]])
+    matrix([[1, 2],
+            [3, 4]])
+
+    """
+    __array_priority__ = 10.0
+    def __new__(subtype, data, dtype=None, copy=True):
+        if isinstance(data, matrix):
+            dtype2 = data.dtype
+            if (dtype is None):
+                dtype = dtype2
+            if (dtype2 == dtype) and (not copy):
+                return data
+            return data.astype(dtype)
+
+        if isinstance(data, N.ndarray):
+            if dtype is None:
+                intype = data.dtype
+            else:
+                intype = N.dtype(dtype)
+            new = data.view(subtype)
+            if intype != data.dtype:
+                return new.astype(intype)
+            if copy: return new.copy()
+            else: return new
+
+        if isinstance(data, str):
+            data = _convert_from_string(data)
+
+        # now convert data to an array
+        arr = N.array(data, dtype=dtype, copy=copy)
+        ndim = arr.ndim
+        shape = arr.shape
+        if (ndim > 2):
+            raise ValueError("matrix must be 2-dimensional")
+        elif ndim == 0:
+            shape = (1, 1)
+        elif ndim == 1:
+            shape = (1, shape[0])
+
+        order = 'C'
+        if (ndim == 2) and arr.flags.fortran:
+            order = 'F'
+
+        if not (order or arr.flags.contiguous):
+            arr = arr.copy()
+
+        ret = N.ndarray.__new__(subtype, shape, arr.dtype,
+                                buffer=arr,
+                                order=order)
+        return ret
+
+    def __array_finalize__(self, obj):
+        self._getitem = False
+        if (isinstance(obj, matrix) and obj._getitem): return
+        ndim = self.ndim
+        if (ndim == 2):
+            return
+        if (ndim > 2):
+            newshape = tuple([x for x in self.shape if x > 1])
+            ndim = len(newshape)
+            if ndim == 2:
+                self.shape = newshape
+                return
+            elif (ndim > 2):
+                raise ValueError("shape too large to be a matrix.")
+        else:
+            newshape = self.shape
+        if ndim == 0:
+            self.shape = (1, 1)
+        elif ndim == 1:
+            self.shape = (1, newshape[0])
+        return
+
+    def __getitem__(self, index):
+        self._getitem = True
+
+        try:
+            out = N.ndarray.__getitem__(self, index)
+        finally:
+            self._getitem = False
+
+        if not isinstance(out, N.ndarray):
+            return out
+
+        if out.ndim == 0:
+            return out[()]
+        if out.ndim == 1:
+            sh = out.shape[0]
+            # Determine when we should have a column array
+            try:
+                n = len(index)
+            except:
+                n = 0
+            if n > 1 and isscalar(index[1]):
+                out.shape = (sh, 1)
+            else:
+                out.shape = (1, sh)
+        return out
+
+    def __mul__(self, other):
+        if isinstance(other, (N.ndarray, list, tuple)) :
+            # This promotes 1-D vectors to row vectors
+            return N.dot(self, asmatrix(other))
+        if isscalar(other) or not hasattr(other, '__rmul__') :
+            return N.dot(self, other)
+        return NotImplemented
+
+    def __rmul__(self, other):
+        return N.dot(other, self)
+
+    def __imul__(self, other):
+        self[:] = self * other
+        return self
+
+    def __pow__(self, other):
+        return matrix_power(self, other)
+
+    def __ipow__(self, other):
+        self[:] = self ** other
+        return self
+
+    def __rpow__(self, other):
+        return NotImplemented
+
+    def __repr__(self):
+        s = repr(self.__array__()).replace('array', 'matrix')
+        # now, 'matrix' has 6 letters, and 'array' 5, so the columns don't
+        # line up anymore. We need to add a space.
+        l = s.splitlines()
+        for i in range(1, len(l)):
+            if l[i]:
+                l[i] = ' ' + l[i]
+        return '\n'.join(l)
+
+    def __str__(self):
+        return str(self.__array__())
+
+    def _align(self, axis):
+        """A convenience function for operations that need to preserve axis
+        orientation.
+        """
+        if axis is None:
+            return self[0, 0]
+        elif axis==0:
+            return self
+        elif axis==1:
+            return self.transpose()
+        else:
+            raise ValueError("unsupported axis")
+
+    def _collapse(self, axis):
+        """A convenience function for operations that want to collapse
+        to a scalar like _align, but are using keepdims=True
+        """
+        if axis is None:
+            return self[0, 0]
+        else:
+            return self
+
+    # Necessary because base-class tolist expects dimension
+    #  reduction by x[0]
+    def tolist(self):
+        """
+        Return the matrix as a (possibly nested) list.
+
+        See `ndarray.tolist` for full documentation.
+
+        See Also
+        --------
+        ndarray.tolist
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.tolist()
+        [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
+
+        """
+        return self.__array__().tolist()
+
+    # To preserve orientation of result...
+    def sum(self, axis=None, dtype=None, out=None):
+        """
+        Returns the sum of the matrix elements, along the given axis.
+
+        Refer to `numpy.sum` for full documentation.
+
+        See Also
+        --------
+        numpy.sum
+
+        Notes
+        -----
+        This is the same as `ndarray.sum`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix([[1, 2], [4, 3]])
+        >>> x.sum()
+        10
+        >>> x.sum(axis=1)
+        matrix([[3],
+                [7]])
+        >>> x.sum(axis=1, dtype='float')
+        matrix([[ 3.],
+                [ 7.]])
+        >>> out = np.zeros((1, 2), dtype='float')
+        >>> x.sum(axis=1, dtype='float', out=out)
+        matrix([[ 3.],
+                [ 7.]])
+
+        """
+        return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+
+    # To update docstring from array to matrix...
+    def squeeze(self, axis=None):
+        """
+        Return a possibly reshaped matrix.
+
+        Refer to `numpy.squeeze` for more documentation.
+
+        Parameters
+        ----------
+        axis : None or int or tuple of ints, optional
+            Selects a subset of the single-dimensional entries in the shape.
+            If an axis is selected with shape entry greater than one,
+            an error is raised.
+
+        Returns
+        -------
+        squeezed : matrix
+            The matrix, but as a (1, N) matrix if it had shape (N, 1).
+
+        See Also
+        --------
+        numpy.squeeze : related function
+
+        Notes
+        -----
+        If `m` has a single column then that column is returned
+        as the single row of a matrix.  Otherwise `m` is returned.
+        The returned matrix is always either `m` itself or a view into `m`.
+        Supplying an axis keyword argument will not affect the returned matrix
+        but it may cause an error to be raised.
+
+        Examples
+        --------
+        >>> c = np.matrix([[1], [2]])
+        >>> c
+        matrix([[1],
+                [2]])
+        >>> c.squeeze()
+        matrix([[1, 2]])
+        >>> r = c.T
+        >>> r
+        matrix([[1, 2]])
+        >>> r.squeeze()
+        matrix([[1, 2]])
+        >>> m = np.matrix([[1, 2], [3, 4]])
+        >>> m.squeeze()
+        matrix([[1, 2],
+                [3, 4]])
+
+        """
+        return N.ndarray.squeeze(self, axis=axis)
+
+
+    # To update docstring from array to matrix...
+    def flatten(self, order='C'):
+        """
+        Return a flattened copy of the matrix.
+
+        All `N` elements of the matrix are placed into a single row.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            'C' means to flatten in row-major (C-style) order. 'F' means to
+            flatten in column-major (Fortran-style) order. 'A' means to
+            flatten in column-major order if `m` is Fortran *contiguous* in
+            memory, row-major order otherwise. 'K' means to flatten `m` in
+            the order the elements occur in memory. The default is 'C'.
+
+        Returns
+        -------
+        y : matrix
+            A copy of the matrix, flattened to a `(1, N)` matrix where `N`
+            is the number of elements in the original matrix.
+
+        See Also
+        --------
+        ravel : Return a flattened array.
+        flat : A 1-D flat iterator over the matrix.
+
+        Examples
+        --------
+        >>> m = np.matrix([[1,2], [3,4]])
+        >>> m.flatten()
+        matrix([[1, 2, 3, 4]])
+        >>> m.flatten('F')
+        matrix([[1, 3, 2, 4]])
+
+        """
+        return N.ndarray.flatten(self, order=order)
+
+    def mean(self, axis=None, dtype=None, out=None):
+        """
+        Returns the average of the matrix elements along the given axis.
+
+        Refer to `numpy.mean` for full documentation.
+
+        See Also
+        --------
+        numpy.mean
+
+        Notes
+        -----
+        Same as `ndarray.mean` except that, where that returns an `ndarray`,
+        this returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.mean()
+        5.5
+        >>> x.mean(0)
+        matrix([[ 4.,  5.,  6.,  7.]])
+        >>> x.mean(1)
+        matrix([[ 1.5],
+                [ 5.5],
+                [ 9.5]])
+
+        """
+        return N.ndarray.mean(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+    def std(self, axis=None, dtype=None, out=None, ddof=0):
+        """
+        Return the standard deviation of the array elements along the given axis.
+
+        Refer to `numpy.std` for full documentation.
+
+        See Also
+        --------
+        numpy.std
+
+        Notes
+        -----
+        This is the same as `ndarray.std`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.std()
+        3.4520525295346629
+        >>> x.std(0)
+        matrix([[ 3.26598632,  3.26598632,  3.26598632,  3.26598632]])
+        >>> x.std(1)
+        matrix([[ 1.11803399],
+                [ 1.11803399],
+                [ 1.11803399]])
+
+        """
+        return N.ndarray.std(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
+
+    def var(self, axis=None, dtype=None, out=None, ddof=0):
+        """
+        Returns the variance of the matrix elements, along the given axis.
+
+        Refer to `numpy.var` for full documentation.
+
+        See Also
+        --------
+        numpy.var
+
+        Notes
+        -----
+        This is the same as `ndarray.var`, except that where an `ndarray` would
+        be returned, a `matrix` object is returned instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3, 4)))
+        >>> x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.var()
+        11.916666666666666
+        >>> x.var(0)
+        matrix([[ 10.66666667,  10.66666667,  10.66666667,  10.66666667]])
+        >>> x.var(1)
+        matrix([[ 1.25],
+                [ 1.25],
+                [ 1.25]])
+
+        """
+        return N.ndarray.var(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis)
+
+    def prod(self, axis=None, dtype=None, out=None):
+        """
+        Return the product of the array elements over the given axis.
+
+        Refer to `prod` for full documentation.
+
+        See Also
+        --------
+        prod, ndarray.prod
+
+        Notes
+        -----
+        Same as `ndarray.prod`, except, where that returns an `ndarray`, this
+        returns a `matrix` object instead.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.prod()
+        0
+        >>> x.prod(0)
+        matrix([[  0,  45, 120, 231]])
+        >>> x.prod(1)
+        matrix([[   0],
+                [ 840],
+                [7920]])
+
+        """
+        return N.ndarray.prod(self, axis, dtype, out, keepdims=True)._collapse(axis)
+
+    def any(self, axis=None, out=None):
+        """
+        Test whether any array element along a given axis evaluates to True.
+
+        Refer to `numpy.any` for full documentation.
+
+        Parameters
+        ----------
+        axis : int, optional
+            Axis along which logical OR is performed
+        out : ndarray, optional
+            Output to existing array instead of creating new one, must have
+            same shape as expected output
+
+        Returns
+        -------
+            any : bool, ndarray
+                Returns a single bool if `axis` is ``None``; otherwise,
+                returns `ndarray`
+
+        """
+        return N.ndarray.any(self, axis, out, keepdims=True)._collapse(axis)
+
+    def all(self, axis=None, out=None):
+        """
+        Test whether all matrix elements along a given axis evaluate to True.
+
+        Parameters
+        ----------
+        See `numpy.all` for complete descriptions
+
+        See Also
+        --------
+        numpy.all
+
+        Notes
+        -----
+        This is the same as `ndarray.all`, but it returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> y = x[0]; y
+        matrix([[0, 1, 2, 3]])
+        >>> (x == y)
+        matrix([[ True,  True,  True,  True],
+                [False, False, False, False],
+                [False, False, False, False]], dtype=bool)
+        >>> (x == y).all()
+        False
+        >>> (x == y).all(0)
+        matrix([[False, False, False, False]], dtype=bool)
+        >>> (x == y).all(1)
+        matrix([[ True],
+                [False],
+                [False]], dtype=bool)
+
+        """
+        return N.ndarray.all(self, axis, out, keepdims=True)._collapse(axis)
+
+    def max(self, axis=None, out=None):
+        """
+        Return the maximum value along an axis.
+
+        Parameters
+        ----------
+        See `amax` for complete descriptions
+
+        See Also
+        --------
+        amax, ndarray.max
+
+        Notes
+        -----
+        This is the same as `ndarray.max`, but returns a `matrix` object
+        where `ndarray.max` would return an ndarray.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.max()
+        11
+        >>> x.max(0)
+        matrix([[ 8,  9, 10, 11]])
+        >>> x.max(1)
+        matrix([[ 3],
+                [ 7],
+                [11]])
+
+        """
+        return N.ndarray.max(self, axis, out, keepdims=True)._collapse(axis)
+
+    def argmax(self, axis=None, out=None):
+        """
+        Indexes of the maximum values along an axis.
+
+        Return the indexes of the first occurrences of the maximum values
+        along the specified axis.  If axis is None, the index is for the
+        flattened matrix.
+
+        Parameters
+        ----------
+        See `numpy.argmax` for complete descriptions
+
+        See Also
+        --------
+        numpy.argmax
+
+        Notes
+        -----
+        This is the same as `ndarray.argmax`, but returns a `matrix` object
+        where `ndarray.argmax` would return an `ndarray`.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.argmax()
+        11
+        >>> x.argmax(0)
+        matrix([[2, 2, 2, 2]])
+        >>> x.argmax(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.argmax(self, axis, out)._align(axis)
+
+    def min(self, axis=None, out=None):
+        """
+        Return the minimum value along an axis.
+
+        Parameters
+        ----------
+        See `amin` for complete descriptions.
+
+        See Also
+        --------
+        amin, ndarray.min
+
+        Notes
+        -----
+        This is the same as `ndarray.min`, but returns a `matrix` object
+        where `ndarray.min` would return an ndarray.
+
+        Examples
+        --------
+        >>> x = -np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[  0,  -1,  -2,  -3],
+                [ -4,  -5,  -6,  -7],
+                [ -8,  -9, -10, -11]])
+        >>> x.min()
+        -11
+        >>> x.min(0)
+        matrix([[ -8,  -9, -10, -11]])
+        >>> x.min(1)
+        matrix([[ -3],
+                [ -7],
+                [-11]])
+
+        """
+        return N.ndarray.min(self, axis, out, keepdims=True)._collapse(axis)
+
+    def argmin(self, axis=None, out=None):
+        """
+        Indexes of the minimum values along an axis.
+
+        Return the indexes of the first occurrences of the minimum values
+        along the specified axis.  If axis is None, the index is for the
+        flattened matrix.
+
+        Parameters
+        ----------
+        See `numpy.argmin` for complete descriptions.
+
+        See Also
+        --------
+        numpy.argmin
+
+        Notes
+        -----
+        This is the same as `ndarray.argmin`, but returns a `matrix` object
+        where `ndarray.argmin` would return an `ndarray`.
+
+        Examples
+        --------
+        >>> x = -np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[  0,  -1,  -2,  -3],
+                [ -4,  -5,  -6,  -7],
+                [ -8,  -9, -10, -11]])
+        >>> x.argmin()
+        11
+        >>> x.argmin(0)
+        matrix([[2, 2, 2, 2]])
+        >>> x.argmin(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.argmin(self, axis, out)._align(axis)
+
+    def ptp(self, axis=None, out=None):
+        """
+        Peak-to-peak (maximum - minimum) value along the given axis.
+
+        Refer to `numpy.ptp` for full documentation.
+
+        See Also
+        --------
+        numpy.ptp
+
+        Notes
+        -----
+        Same as `ndarray.ptp`, except, where that would return an `ndarray` object,
+        this returns a `matrix` object.
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.ptp()
+        11
+        >>> x.ptp(0)
+        matrix([[8, 8, 8, 8]])
+        >>> x.ptp(1)
+        matrix([[3],
+                [3],
+                [3]])
+
+        """
+        return N.ndarray.ptp(self, axis, out)._align(axis)
+
+    def getI(self):
+        """
+        Returns the (multiplicative) inverse of invertible `self`.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            If `self` is non-singular, `ret` is such that ``ret * self`` ==
+            ``self * ret`` == ``np.matrix(np.eye(self[0,:].size)`` all return
+            ``True``.
+
+        Raises
+        ------
+        numpy.linalg.LinAlgError: Singular matrix
+            If `self` is singular.
+
+        See Also
+        --------
+        linalg.inv
+
+        Examples
+        --------
+        >>> m = np.matrix('[1, 2; 3, 4]'); m
+        matrix([[1, 2],
+                [3, 4]])
+        >>> m.getI()
+        matrix([[-2. ,  1. ],
+                [ 1.5, -0.5]])
+        >>> m.getI() * m
+        matrix([[ 1.,  0.],
+                [ 0.,  1.]])
+
+        """
+        M, N = self.shape
+        if M == N:
+            from numpy.dual import inv as func
+        else:
+            from numpy.dual import pinv as func
+        return asmatrix(func(self))
+
+    def getA(self):
+        """
+        Return `self` as an `ndarray` object.
+
+        Equivalent to ``np.asarray(self)``.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : ndarray
+            `self` as an `ndarray`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.getA()
+        array([[ 0,  1,  2,  3],
+               [ 4,  5,  6,  7],
+               [ 8,  9, 10, 11]])
+
+        """
+        return self.__array__()
+
+    def getA1(self):
+        """
+        Return `self` as a flattened `ndarray`.
+
+        Equivalent to ``np.asarray(x).ravel()``
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : ndarray
+            `self`, 1-D, as an `ndarray`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4))); x
+        matrix([[ 0,  1,  2,  3],
+                [ 4,  5,  6,  7],
+                [ 8,  9, 10, 11]])
+        >>> x.getA1()
+        array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
+
+        """
+        return self.__array__().ravel()
+
+
+    def ravel(self, order='C'):
+        """
+        Return a flattened matrix.
+
+        Refer to `numpy.ravel` for more documentation.
+
+        Parameters
+        ----------
+        order : {'C', 'F', 'A', 'K'}, optional
+            The elements of `m` are read using this index order. 'C' means to
+            index the elements in C-like order, with the last axis index
+            changing fastest, back to the first axis index changing slowest.
+            'F' means to index the elements in Fortran-like index order, with
+            the first index changing fastest, and the last index changing
+            slowest. Note that the 'C' and 'F' options take no account of the
+            memory layout of the underlying array, and only refer to the order
+            of axis indexing.  'A' means to read the elements in Fortran-like
+            index order if `m` is Fortran *contiguous* in memory, C-like order
+            otherwise.  'K' means to read the elements in the order they occur
+            in memory, except for reversing the data when strides are negative.
+            By default, 'C' index order is used.
+
+        Returns
+        -------
+        ret : matrix
+            Return the matrix flattened to shape `(1, N)` where `N`
+            is the number of elements in the original matrix.
+            A copy is made only if necessary.
+
+        See Also
+        --------
+        matrix.flatten : returns a similar output matrix but always a copy
+        matrix.flat : a flat iterator on the array.
+        numpy.ravel : related function which returns an ndarray
+
+        """
+        return N.ndarray.ravel(self, order=order)
+
+
+    def getT(self):
+        """
+        Returns the transpose of the matrix.
+
+        Does *not* conjugate!  For the complex conjugate transpose, use ``.H``.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            The (non-conjugated) transpose of the matrix.
+
+        See Also
+        --------
+        transpose, getH
+
+        Examples
+        --------
+        >>> m = np.matrix('[1, 2; 3, 4]')
+        >>> m
+        matrix([[1, 2],
+                [3, 4]])
+        >>> m.getT()
+        matrix([[1, 3],
+                [2, 4]])
+
+        """
+        return self.transpose()
+
+    def getH(self):
+        """
+        Returns the (complex) conjugate transpose of `self`.
+
+        Equivalent to ``np.transpose(self)`` if `self` is real-valued.
+
+        Parameters
+        ----------
+        None
+
+        Returns
+        -------
+        ret : matrix object
+            complex conjugate transpose of `self`
+
+        Examples
+        --------
+        >>> x = np.matrix(np.arange(12).reshape((3,4)))
+        >>> z = x - 1j*x; z
+        matrix([[  0. +0.j,   1. -1.j,   2. -2.j,   3. -3.j],
+                [  4. -4.j,   5. -5.j,   6. -6.j,   7. -7.j],
+                [  8. -8.j,   9. -9.j,  10.-10.j,  11.-11.j]])
+        >>> z.getH()
+        matrix([[  0. +0.j,   4. +4.j,   8. +8.j],
+                [  1. +1.j,   5. +5.j,   9. +9.j],
+                [  2. +2.j,   6. +6.j,  10.+10.j],
+                [  3. +3.j,   7. +7.j,  11.+11.j]])
+
+        """
+        if issubclass(self.dtype.type, N.complexfloating):
+            return self.transpose().conjugate()
+        else:
+            return self.transpose()
+
+    T = property(getT, None)
+    A = property(getA, None)
+    A1 = property(getA1, None)
+    H = property(getH, None)
+    I = property(getI, None)
+
+def _from_string(str, gdict, ldict):
+    rows = str.split(';')
+    rowtup = []
+    for row in rows:
+        trow = row.split(',')
+        newrow = []
+        for x in trow:
+            newrow.extend(x.split())
+        trow = newrow
+        coltup = []
+        for col in trow:
+            col = col.strip()
+            try:
+                thismat = ldict[col]
+            except KeyError:
+                try:
+                    thismat = gdict[col]
+                except KeyError:
+                    raise KeyError("%s not found" % (col,))
+
+            coltup.append(thismat)
+        rowtup.append(concatenate(coltup, axis=-1))
+    return concatenate(rowtup, axis=0)
+
+
+def bmat(obj, ldict=None, gdict=None):
+    """
+    Build a matrix object from a string, nested sequence, or array.
+
+    Parameters
+    ----------
+    obj : str or array_like
+        Input data.  Names of variables in the current scope may be
+        referenced, even if `obj` is a string.
+    ldict : dict, optional
+        A dictionary that replaces local operands in current frame.
+        Ignored if `obj` is not a string or `gdict` is `None`.
+    gdict : dict, optional
+        A dictionary that replaces global operands in current frame.
+        Ignored if `obj` is not a string.
+
+    Returns
+    -------
+    out : matrix
+        Returns a matrix object, which is a specialized 2-D array.
+
+    See Also
+    --------
+    matrix
+
+    Examples
+    --------
+    >>> A = np.mat('1 1; 1 1')
+    >>> B = np.mat('2 2; 2 2')
+    >>> C = np.mat('3 4; 5 6')
+    >>> D = np.mat('7 8; 9 0')
+
+    All the following expressions construct the same block matrix:
+
+    >>> np.bmat([[A, B], [C, D]])
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+    >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]])
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+    >>> np.bmat('A,B; C,D')
+    matrix([[1, 1, 2, 2],
+            [1, 1, 2, 2],
+            [3, 4, 7, 8],
+            [5, 6, 9, 0]])
+
+    """
+    if isinstance(obj, str):
+        if gdict is None:
+            # get previous frame
+            frame = sys._getframe().f_back
+            glob_dict = frame.f_globals
+            loc_dict = frame.f_locals
+        else:
+            glob_dict = gdict
+            loc_dict = ldict
+
+        return matrix(_from_string(obj, glob_dict, loc_dict))
+
+    if isinstance(obj, (tuple, list)):
+        # [[A,B],[C,D]]
+        arr_rows = []
+        for row in obj:
+            if isinstance(row, N.ndarray):  # not 2-d
+                return matrix(concatenate(obj, axis=-1))
+            else:
+                arr_rows.append(concatenate(row, axis=-1))
+        return matrix(concatenate(arr_rows, axis=0))
+    if isinstance(obj, N.ndarray):
+        return matrix(obj)
+
+mat = asmatrix
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.py
new file mode 100644
index 0000000000..aa8e0a09be
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+import os
+
+def configuration(parent_package='', top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('matrixlib', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == "__main__":
+    from numpy.distutils.core import setup
+    config = configuration(top_path='').todict()
+    setup(**config)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
new file mode 100644
index 0000000000..6aa24e4ff1
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
@@ -0,0 +1,449 @@
+from __future__ import division, absolute_import, print_function
+
+import collections
+
+import numpy as np
+from numpy import matrix, asmatrix, bmat
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_almost_equal,
+    assert_array_equal, assert_array_almost_equal, assert_raises
+)
+from numpy.matrixlib.defmatrix import matrix_power
+from numpy.matrixlib import mat
+
+class TestCtor(TestCase):
+    def test_basic(self):
+        A = np.array([[1, 2], [3, 4]])
+        mA = matrix(A)
+        assert_(np.all(mA.A == A))
+
+        B = bmat("A,A;A,A")
+        C = bmat([[A, A], [A, A]])
+        D = np.array([[1, 2, 1, 2],
+                      [3, 4, 3, 4],
+                      [1, 2, 1, 2],
+                      [3, 4, 3, 4]])
+        assert_(np.all(B.A == D))
+        assert_(np.all(C.A == D))
+
+        E = np.array([[5, 6], [7, 8]])
+        AEresult = matrix([[1, 2, 5, 6], [3, 4, 7, 8]])
+        assert_(np.all(bmat([A, E]) == AEresult))
+
+        vec = np.arange(5)
+        mvec = matrix(vec)
+        assert_(mvec.shape == (1, 5))
+
+    def test_exceptions(self):
+        # Check for TypeError when called with invalid string data.
+        assert_raises(TypeError, matrix, "invalid")
+
+    def test_bmat_nondefault_str(self):
+        A = np.array([[1, 2], [3, 4]])
+        B = np.array([[5, 6], [7, 8]])
+        Aresult = np.array([[1, 2, 1, 2],
+                            [3, 4, 3, 4],
+                            [1, 2, 1, 2],
+                            [3, 4, 3, 4]])
+        mixresult = np.array([[1, 2, 5, 6],
+                              [3, 4, 7, 8],
+                              [5, 6, 1, 2],
+                              [7, 8, 3, 4]])
+        assert_(np.all(bmat("A,A;A,A") == Aresult))
+        assert_(np.all(bmat("A,A;A,A", ldict={'A':B}) == Aresult))
+        assert_raises(TypeError, bmat, "A,A;A,A", gdict={'A':B})
+        assert_(
+            np.all(bmat("A,A;A,A", ldict={'A':A}, gdict={'A':B}) == Aresult))
+        b2 = bmat("A,B;C,D", ldict={'A':A,'B':B}, gdict={'C':B,'D':A})
+        assert_(np.all(b2 == mixresult))
+
+
+class TestProperties(TestCase):
+    def test_sum(self):
+        """Test whether matrix.sum(axis=1) preserves orientation.
+        Fails in NumPy <= 0.9.6.2127.
+        """
+        M = matrix([[1, 2, 0, 0],
+                   [3, 4, 0, 0],
+                   [1, 2, 1, 2],
+                   [3, 4, 3, 4]])
+        sum0 = matrix([8, 12, 4, 6])
+        sum1 = matrix([3, 7, 6, 14]).T
+        sumall = 30
+        assert_array_equal(sum0, M.sum(axis=0))
+        assert_array_equal(sum1, M.sum(axis=1))
+        assert_equal(sumall, M.sum())
+
+        assert_array_equal(sum0, np.sum(M, axis=0))
+        assert_array_equal(sum1, np.sum(M, axis=1))
+        assert_equal(sumall, np.sum(M))
+
+    def test_prod(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.prod(), 720)
+        assert_equal(x.prod(0), matrix([[4, 10, 18]]))
+        assert_equal(x.prod(1), matrix([[6], [120]]))
+
+        assert_equal(np.prod(x), 720)
+        assert_equal(np.prod(x, axis=0), matrix([[4, 10, 18]]))
+        assert_equal(np.prod(x, axis=1), matrix([[6], [120]]))
+
+        y = matrix([0, 1, 3])
+        assert_(y.prod() == 0)
+
+    def test_max(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.max(), 6)
+        assert_equal(x.max(0), matrix([[4, 5, 6]]))
+        assert_equal(x.max(1), matrix([[3], [6]]))
+
+        assert_equal(np.max(x), 6)
+        assert_equal(np.max(x, axis=0), matrix([[4, 5, 6]]))
+        assert_equal(np.max(x, axis=1), matrix([[3], [6]]))
+
+    def test_min(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.min(), 1)
+        assert_equal(x.min(0), matrix([[1, 2, 3]]))
+        assert_equal(x.min(1), matrix([[1], [4]]))
+
+        assert_equal(np.min(x), 1)
+        assert_equal(np.min(x, axis=0), matrix([[1, 2, 3]]))
+        assert_equal(np.min(x, axis=1), matrix([[1], [4]]))
+
+    def test_ptp(self):
+        x = np.arange(4).reshape((2, 2))
+        assert_(x.ptp() == 3)
+        assert_(np.all(x.ptp(0) == np.array([2, 2])))
+        assert_(np.all(x.ptp(1) == np.array([1, 1])))
+
+    def test_var(self):
+        x = np.arange(9).reshape((3, 3))
+        mx = x.view(np.matrix)
+        assert_equal(x.var(ddof=0), mx.var(ddof=0))
+        assert_equal(x.var(ddof=1), mx.var(ddof=1))
+
+    def test_basic(self):
+        import numpy.linalg as linalg
+
+        A = np.array([[1., 2.],
+                      [3., 4.]])
+        mA = matrix(A)
+        assert_(np.allclose(linalg.inv(A), mA.I))
+        assert_(np.all(np.array(np.transpose(A) == mA.T)))
+        assert_(np.all(np.array(np.transpose(A) == mA.H)))
+        assert_(np.all(A == mA.A))
+
+        B = A + 2j*A
+        mB = matrix(B)
+        assert_(np.allclose(linalg.inv(B), mB.I))
+        assert_(np.all(np.array(np.transpose(B) == mB.T)))
+        assert_(np.all(np.array(np.transpose(B).conj() == mB.H)))
+
+    def test_pinv(self):
+        x = matrix(np.arange(6).reshape(2, 3))
+        xpinv = matrix([[-0.77777778,  0.27777778],
+                        [-0.11111111,  0.11111111],
+                        [ 0.55555556, -0.05555556]])
+        assert_almost_equal(x.I, xpinv)
+
+    def test_comparisons(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = matrix(A)
+        mB = matrix(A) + 0.1
+        assert_(np.all(mB == A+0.1))
+        assert_(np.all(mB == matrix(A+0.1)))
+        assert_(not np.any(mB == matrix(A-0.1)))
+        assert_(np.all(mA < mB))
+        assert_(np.all(mA <= mB))
+        assert_(np.all(mA <= mA))
+        assert_(not np.any(mA < mA))
+
+        assert_(not np.any(mB < mA))
+        assert_(np.all(mB >= mA))
+        assert_(np.all(mB >= mB))
+        assert_(not np.any(mB > mB))
+
+        assert_(np.all(mA == mA))
+        assert_(not np.any(mA == mB))
+        assert_(np.all(mB != mA))
+
+        assert_(not np.all(abs(mA) > 0))
+        assert_(np.all(abs(mB > 0)))
+
+    def test_asmatrix(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = asmatrix(A)
+        A[0, 0] = -10
+        assert_(A[0, 0] == mA[0, 0])
+
+    def test_noaxis(self):
+        A = matrix([[1, 0], [0, 1]])
+        assert_(A.sum() == matrix(2))
+        assert_(A.mean() == matrix(0.5))
+
+    def test_repr(self):
+        A = matrix([[1, 0], [0, 1]])
+        assert_(repr(A) == "matrix([[1, 0],\n        [0, 1]])")
+
+class TestCasting(TestCase):
+    def test_basic(self):
+        A = np.arange(100).reshape(10, 10)
+        mA = matrix(A)
+
+        mB = mA.copy()
+        O = np.ones((10, 10), np.float64) * 0.1
+        mB = mB + O
+        assert_(mB.dtype.type == np.float64)
+        assert_(np.all(mA != mB))
+        assert_(np.all(mB == mA+0.1))
+
+        mC = mA.copy()
+        O = np.ones((10, 10), np.complex128)
+        mC = mC * O
+        assert_(mC.dtype.type == np.complex128)
+        assert_(np.all(mA != mB))
+
+
+class TestAlgebra(TestCase):
+    def test_basic(self):
+        import numpy.linalg as linalg
+
+        A = np.array([[1., 2.], [3., 4.]])
+        mA = matrix(A)
+
+        B = np.identity(2)
+        for i in range(6):
+            assert_(np.allclose((mA ** i).A, B))
+            B = np.dot(B, A)
+
+        Ainv = linalg.inv(A)
+        B = np.identity(2)
+        for i in range(6):
+            assert_(np.allclose((mA ** -i).A, B))
+            B = np.dot(B, Ainv)
+
+        assert_(np.allclose((mA * mA).A, np.dot(A, A)))
+        assert_(np.allclose((mA + mA).A, (A + A)))
+        assert_(np.allclose((3*mA).A, (3*A)))
+
+        mA2 = matrix(A)
+        mA2 *= 3
+        assert_(np.allclose(mA2.A, 3*A))
+
+    def test_pow(self):
+        """Test raising a matrix to an integer power works as expected."""
+        m = matrix("1. 2.; 3. 4.")
+        m2 = m.copy()
+        m2 **= 2
+        mi = m.copy()
+        mi **= -1
+        m4 = m2.copy()
+        m4 **= 2
+        assert_array_almost_equal(m2, m**2)
+        assert_array_almost_equal(m4, np.dot(m2, m2))
+        assert_array_almost_equal(np.dot(mi, m), np.eye(2))
+
+    def test_notimplemented(self):
+        '''Check that 'not implemented' operations produce a failure.'''
+        A = matrix([[1., 2.],
+                    [3., 4.]])
+
+        # __rpow__
+        try:
+            1.0**A
+        except TypeError:
+            pass
+        else:
+            self.fail("matrix.__rpow__ doesn't raise a TypeError")
+
+        # __mul__ with something not a list, ndarray, tuple, or scalar
+        try:
+            A*object()
+        except TypeError:
+            pass
+        else:
+            self.fail("matrix.__mul__ with non-numeric object doesn't raise"
+                      "a TypeError")
+
+class TestMatrixReturn(TestCase):
+    def test_instance_methods(self):
+        a = matrix([1.0], dtype='f8')
+        methodargs = {
+            'astype': ('intc',),
+            'clip': (0.0, 1.0),
+            'compress': ([1],),
+            'repeat': (1,),
+            'reshape': (1,),
+            'swapaxes': (0, 0),
+            'dot': np.array([1.0]),
+            }
+        excluded_methods = [
+            'argmin', 'choose', 'dump', 'dumps', 'fill', 'getfield',
+            'getA', 'getA1', 'item', 'nonzero', 'put', 'putmask', 'resize',
+            'searchsorted', 'setflags', 'setfield', 'sort',
+            'partition', 'argpartition',
+            'take', 'tofile', 'tolist', 'tostring', 'tobytes', 'all', 'any',
+            'sum', 'argmax', 'argmin', 'min', 'max', 'mean', 'var', 'ptp',
+            'prod', 'std', 'ctypes', 'itemset',
+            ]
+        for attrib in dir(a):
+            if attrib.startswith('_') or attrib in excluded_methods:
+                continue
+            f = getattr(a, attrib)
+            if isinstance(f, collections.Callable):
+                # reset contents of a
+                a.astype('f8')
+                a.fill(1.0)
+                if attrib in methodargs:
+                    args = methodargs[attrib]
+                else:
+                    args = ()
+                b = f(*args)
+                assert_(type(b) is matrix, "%s" % attrib)
+        assert_(type(a.real) is matrix)
+        assert_(type(a.imag) is matrix)
+        c, d = matrix([0.0]).nonzero()
+        assert_(type(c) is np.ndarray)
+        assert_(type(d) is np.ndarray)
+
+
+class TestIndexing(TestCase):
+    def test_basic(self):
+        x = asmatrix(np.zeros((3, 2), float))
+        y = np.zeros((3, 1), float)
+        y[:, 0] = [0.8, 0.2, 0.3]
+        x[:, 1] = y > 0.5
+        assert_equal(x, [[0, 1], [0, 0], [0, 0]])
+
+
+class TestNewScalarIndexing(TestCase):
+    def setUp(self):
+        self.a = matrix([[1, 2], [3, 4]])
+
+    def test_dimesions(self):
+        a = self.a
+        x = a[0]
+        assert_equal(x.ndim, 2)
+
+    def test_array_from_matrix_list(self):
+        a = self.a
+        x = np.array([a, a])
+        assert_equal(x.shape, [2, 2, 2])
+
+    def test_array_to_list(self):
+        a = self.a
+        assert_equal(a.tolist(), [[1, 2], [3, 4]])
+
+    def test_fancy_indexing(self):
+        a = self.a
+        x = a[1, [0, 1, 0]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[3,  4,  3]]))
+        x = a[[1, 0]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[3,  4], [1, 2]]))
+        x = a[[[1], [0]], [[1, 0], [0, 1]]]
+        assert_(isinstance(x, matrix))
+        assert_equal(x, matrix([[4,  3], [1,  2]]))
+
+    def test_matrix_element(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x[0][0], matrix([[1, 2, 3]]))
+        assert_equal(x[0][0].shape, (1, 3))
+        assert_equal(x[0].shape, (1, 3))
+        assert_equal(x[:, 0].shape, (2, 1))
+
+        x = matrix(0)
+        assert_equal(x[0, 0], 0)
+        assert_equal(x[0], 0)
+        assert_equal(x[:, 0].shape, x.shape)
+
+    def test_scalar_indexing(self):
+        x = asmatrix(np.zeros((3, 2), float))
+        assert_equal(x[0, 0], x[0][0])
+
+    def test_row_column_indexing(self):
+        x = asmatrix(np.eye(2))
+        assert_array_equal(x[0,:], [[1, 0]])
+        assert_array_equal(x[1,:], [[0, 1]])
+        assert_array_equal(x[:, 0], [[1], [0]])
+        assert_array_equal(x[:, 1], [[0], [1]])
+
+    def test_boolean_indexing(self):
+        A = np.arange(6)
+        A.shape = (3, 2)
+        x = asmatrix(A)
+        assert_array_equal(x[:, np.array([True, False])], x[:, 0])
+        assert_array_equal(x[np.array([True, False, False]),:], x[0,:])
+
+    def test_list_indexing(self):
+        A = np.arange(6)
+        A.shape = (3, 2)
+        x = asmatrix(A)
+        assert_array_equal(x[:, [1, 0]], x[:, ::-1])
+        assert_array_equal(x[[2, 1, 0],:], x[::-1,:])
+
+
+class TestPower(TestCase):
+    def test_returntype(self):
+        a = np.array([[0, 1], [0, 0]])
+        assert_(type(matrix_power(a, 2)) is np.ndarray)
+        a = mat(a)
+        assert_(type(matrix_power(a, 2)) is matrix)
+
+    def test_list(self):
+        assert_array_equal(matrix_power([[0, 1], [0, 0]], 2), [[0, 0], [0, 0]])
+
+
+class TestShape(TestCase):
+    def setUp(self):
+        self.a = np.array([[1], [2]])
+        self.m = matrix([[1], [2]])
+
+    def test_shape(self):
+        assert_equal(self.a.shape, (2, 1))
+        assert_equal(self.m.shape, (2, 1))
+
+    def test_numpy_ravel(self):
+        assert_equal(np.ravel(self.a).shape, (2,))
+        assert_equal(np.ravel(self.m).shape, (2,))
+
+    def test_member_ravel(self):
+        assert_equal(self.a.ravel().shape, (2,))
+        assert_equal(self.m.ravel().shape, (1, 2))
+
+    def test_member_flatten(self):
+        assert_equal(self.a.flatten().shape, (2,))
+        assert_equal(self.m.flatten().shape, (1, 2))
+
+    def test_numpy_ravel_order(self):
+        x = np.array([[1, 2, 3], [4, 5, 6]])
+        assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
+        assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6])
+        assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6])
+        assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6])
+
+    def test_matrix_ravel_order(self):
+        x = matrix([[1, 2, 3], [4, 5, 6]])
+        assert_equal(x.ravel(), [[1, 2, 3, 4, 5, 6]])
+        assert_equal(x.ravel(order='F'), [[1, 4, 2, 5, 3, 6]])
+        assert_equal(x.T.ravel(), [[1, 4, 2, 5, 3, 6]])
+        assert_equal(x.T.ravel(order='A'), [[1, 2, 3, 4, 5, 6]])
+
+    def test_array_memory_sharing(self):
+        assert_(np.may_share_memory(self.a, self.a.ravel()))
+        assert_(not np.may_share_memory(self.a, self.a.flatten()))
+
+    def test_matrix_memory_sharing(self):
+        assert_(np.may_share_memory(self.m, self.m.ravel()))
+        assert_(not np.may_share_memory(self.m, self.m.flatten()))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
new file mode 100644
index 0000000000..d27e24ec96
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+    TestCase, run_module_suite, assert_, assert_equal, assert_array_equal
+)
+
+class TestView(TestCase):
+    def test_type(self):
+        x = np.array([1, 2, 3])
+        assert_(isinstance(x.view(np.matrix), np.matrix))
+
+    def test_keywords(self):
+        x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
+        # We must be specific about the endianness here:
+        y = x.view(dtype='<i2', type=np.matrix)
+        assert_array_equal(y, [[513]])
+
+        assert_(isinstance(y, np.matrix))
+        assert_equal(y.dtype, np.dtype('<i2'))
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
new file mode 100644
index 0000000000..28329da393
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import assert_equal, TestCase, run_module_suite
+
+class TestDot(TestCase):
+    def test_matscalar(self):
+        b1 = np.matrix(np.ones((3, 3), dtype=complex))
+        assert_equal(b1*1.0, b1)
+
+
+def test_diagonal():
+    b1 = np.matrix([[1,2],[3,4]])
+    diag_b1 = np.matrix([[1, 4]])
+    array_b1 = np.array([1, 4])
+
+    assert_equal(b1.diagonal(), diag_b1)
+    assert_equal(np.diagonal(b1), array_b1)
+    assert_equal(np.diag(b1), array_b1)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
new file mode 100644
index 0000000000..0839fbf28a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
@@ -0,0 +1,37 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import TestCase, run_module_suite, assert_, assert_equal
+
+rlevel = 1
+
+class TestRegression(TestCase):
+    def test_kron_matrix(self, level=rlevel):
+        # Ticket #71
+        x = np.matrix('[1 0; 1 0]')
+        assert_equal(type(np.kron(x, x)), type(x))
+
+    def test_matrix_properties(self,level=rlevel):
+        # Ticket #125
+        a = np.matrix([1.0], dtype=float)
+        assert_(type(a.real) is np.matrix)
+        assert_(type(a.imag) is np.matrix)
+        c, d = np.matrix([0.0]).nonzero()
+        assert_(type(c) is np.ndarray)
+        assert_(type(d) is np.ndarray)
+
+    def test_matrix_multiply_by_1d_vector(self, level=rlevel):
+        # Ticket #473
+        def mul():
+            np.mat(np.eye(2))*np.ones(2)
+
+        self.assertRaises(ValueError, mul)
+
+    def test_matrix_std_argmax(self,level=rlevel):
+        # Ticket #83
+        x = np.asmatrix(np.random.uniform(0, 1, (3, 3)))
+        self.assertEqual(x.std().shape, ())
+        self.assertEqual(x.argmax().shape, ())
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.py
new file mode 100644
index 0000000000..82c350e9b2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.py
@@ -0,0 +1,27 @@
+"""
+A sub-package for efficiently dealing with polynomials.
+
+Within the documentation for this sub-package, a "finite power series,"
+i.e., a polynomial (also referred to simply as a "series") is represented
+by a 1-D numpy array of the polynomial's coefficients, ordered from lowest
+order term to highest.  For example, array([1,2,3]) represents
+``P_0 + 2*P_1 + 3*P_2``, where P_n is the n-th order basis polynomial
+applicable to the specific module in question, e.g., `polynomial` (which
+"wraps" the "standard" basis) or `chebyshev`.  For optimal performance,
+all operations on polynomials, including evaluation at an argument, are
+implemented as operations on the coefficients.  Additional (module-specific)
+information can be found in the docstring for the module of interest.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from .polynomial import Polynomial
+from .chebyshev import Chebyshev
+from .legendre import Legendre
+from .hermite import Hermite
+from .hermite_e import HermiteE
+from .laguerre import Laguerre
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
new file mode 100644
index 0000000000..6fa72b6f92
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
@@ -0,0 +1,965 @@
+"""
+Abstract base class for the various polynomial Classes.
+
+The ABCPolyBase class provides the methods needed to implement the common API
+for the various polynomial classes. It operates as a mixin, but uses the
+abc module from the stdlib, hence it is only available for Python >= 2.6.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from abc import ABCMeta, abstractmethod, abstractproperty
+from numbers import Number
+
+import numpy as np
+from . import polyutils as pu
+
+__all__ = ['ABCPolyBase']
+
+class ABCPolyBase(object):
+    """An abstract base class for series classes.
+
+    ABCPolyBase provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' along with the
+    methods listed below.
+
+    .. versionadded:: 1.9.0
+
+    Parameters
+    ----------
+    coef : array_like
+        Series coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``, where
+        ``P_i`` is the basis polynomials of degree ``i``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is the derived class domain.
+    window : (2,) array_like, optional
+        Window, see domain for its use. The default value is the
+        derived class window.
+
+    Attributes
+    ----------
+    coef : (N,) ndarray
+        Series coefficients in order of increasing degree.
+    domain : (2,) ndarray
+        Domain that is mapped to window.
+    window : (2,) ndarray
+        Window that domain is mapped to.
+
+    Class Attributes
+    ----------------
+    maxpower : int
+        Maximum power allowed, i.e., the largest number ``n`` such that
+        ``p(x)**n`` is allowed. This is to limit runaway polynomial size.
+    domain : (2,) ndarray
+        Default domain of the class.
+    window : (2,) ndarray
+        Default window of the class.
+
+    """
+    __metaclass__ = ABCMeta
+
+    # Not hashable
+    __hash__ = None
+
+    # Don't let participate in array operations. Value doesn't matter.
+    __array_priority__ = 1000
+
+    # Limit runaway size. T_n^m has degree n*m
+    maxpower = 100
+
+    @abstractproperty
+    def domain(self):
+        pass
+
+    @abstractproperty
+    def window(self):
+        pass
+
+    @abstractproperty
+    def nickname(self):
+        pass
+
+    @abstractmethod
+    def _add(self):
+        pass
+
+    @abstractmethod
+    def _sub(self):
+        pass
+
+    @abstractmethod
+    def _mul(self):
+        pass
+
+    @abstractmethod
+    def _div(self):
+        pass
+
+    @abstractmethod
+    def _pow(self):
+        pass
+
+    @abstractmethod
+    def _val(self):
+        pass
+
+    @abstractmethod
+    def _int(self):
+        pass
+
+    @abstractmethod
+    def _der(self):
+        pass
+
+    @abstractmethod
+    def _fit(self):
+        pass
+
+    @abstractmethod
+    def _line(self):
+        pass
+
+    @abstractmethod
+    def _roots(self):
+        pass
+
+    @abstractmethod
+    def _fromroots(self):
+        pass
+
+    def has_samecoef(self, other):
+        """Check if coefficients match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``coef`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the coefficients are the same, False otherwise.
+
+        """
+        if len(self.coef) != len(other.coef):
+            return False
+        elif not np.all(self.coef == other.coef):
+            return False
+        else:
+            return True
+
+    def has_samedomain(self, other):
+        """Check if domains match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``domain`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the domains are the same, False otherwise.
+
+        """
+        return np.all(self.domain == other.domain)
+
+    def has_samewindow(self, other):
+        """Check if windows match.
+
+        .. versionadded:: 1.6.0
+
+        Parameters
+        ----------
+        other : class instance
+            The other class must have the ``window`` attribute.
+
+        Returns
+        -------
+        bool : boolean
+            True if the windows are the same, False otherwise.
+
+        """
+        return np.all(self.window == other.window)
+
+    def has_sametype(self, other):
+        """Check if types match.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        other : object
+            Class instance.
+
+        Returns
+        -------
+        bool : boolean
+            True if other is same class as self
+
+        """
+        return isinstance(other, self.__class__)
+
+    def _get_coefficients(self, other):
+        """Interpret other as polynomial coefficients.
+
+        The `other` argument is checked to see if it is of the same
+        class as self with identical domain and window. If so,
+        return its coefficients, otherwise return `other`.
+
+        .. versionadded:: 1.9.0
+
+        Parameters
+        ----------
+        other : anything
+            Object to be checked.
+
+        Returns
+        -------
+        coef:
+            The coefficients of`other` if it is a compatible instance,
+            of ABCPolyBase, otherwise `other`.
+
+        Raises
+        ------
+        TypeError:
+            When `other` is an incompatible instance of ABCPolyBase.
+
+        """
+        if isinstance(other, ABCPolyBase):
+            if not isinstance(other, self.__class__):
+                raise TypeError("Polynomial types differ")
+            elif not np.all(self.domain == other.domain):
+                raise TypeError("Domains differ")
+            elif not np.all(self.window == other.window):
+                raise TypeError("Windows differ")
+            return other.coef
+        return other
+
+    def __init__(self, coef, domain=None, window=None):
+        [coef] = pu.as_series([coef], trim=False)
+        self.coef = coef
+
+        if domain is not None:
+            [domain] = pu.as_series([domain], trim=False)
+            if len(domain) != 2:
+                raise ValueError("Domain has wrong number of elements.")
+            self.domain = domain
+
+        if window is not None:
+            [window] = pu.as_series([window], trim=False)
+            if len(window) != 2:
+                raise ValueError("Window has wrong number of elements.")
+            self.window = window
+
+    def __repr__(self):
+        format = "%s(%s, %s, %s)"
+        coef = repr(self.coef)[6:-1]
+        domain = repr(self.domain)[6:-1]
+        window = repr(self.window)[6:-1]
+        name = self.__class__.__name__
+        return format % (name, coef, domain, window)
+
+    def __str__(self):
+        format = "%s(%s)"
+        coef = str(self.coef)
+        name = self.nickname
+        return format % (name, coef)
+
+    # Pickle and copy
+
+    def __getstate__(self):
+        ret = self.__dict__.copy()
+        ret['coef'] = self.coef.copy()
+        ret['domain'] = self.domain.copy()
+        ret['window'] = self.window.copy()
+        return ret
+
+    def __setstate__(self, dict):
+        self.__dict__ = dict
+
+    # Call
+
+    def __call__(self, arg):
+        off, scl = pu.mapparms(self.domain, self.window)
+        arg = off + scl*arg
+        return self._val(arg, self.coef)
+
+    def __iter__(self):
+        return iter(self.coef)
+
+    def __len__(self):
+        return len(self.coef)
+
+    # Numeric properties.
+
+    def __neg__(self):
+        return self.__class__(-self.coef, self.domain, self.window)
+
+    def __pos__(self):
+        return self
+
+    def __add__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._add(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __sub__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._sub(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __mul__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            coef = self._mul(self.coef, othercoef)
+        except TypeError as e:
+            raise e
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __div__(self, other):
+        # set to __floordiv__,  /, for now.
+        return self.__floordiv__(other)
+
+    def __truediv__(self, other):
+        # there is no true divide if the rhs is not a Number, although it
+        # could return the first n elements of an infinite series.
+        # It is hard to see where n would come from, though.
+        if not isinstance(other, Number) or isinstance(other, bool):
+            form = "unsupported types for true division: '%s', '%s'"
+            raise TypeError(form % (type(self), type(other)))
+        return self.__floordiv__(other)
+
+    def __floordiv__(self, other):
+        res = self.__divmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[0]
+
+    def __mod__(self, other):
+        res = self.__divmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[1]
+
+    def __divmod__(self, other):
+        try:
+            othercoef = self._get_coefficients(other)
+            quo, rem = self._div(self.coef, othercoef)
+        except (TypeError, ZeroDivisionError) as e:
+            raise e
+        except:
+            return NotImplemented
+        quo = self.__class__(quo, self.domain, self.window)
+        rem = self.__class__(rem, self.domain, self.window)
+        return quo, rem
+
+    def __pow__(self, other):
+        coef = self._pow(self.coef, other, maxpower=self.maxpower)
+        res = self.__class__(coef, self.domain, self.window)
+        return res
+
+    def __radd__(self, other):
+        try:
+            coef = self._add(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rsub__(self, other):
+        try:
+            coef = self._sub(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rmul__(self, other):
+        try:
+            coef = self._mul(other, self.coef)
+        except:
+            return NotImplemented
+        return self.__class__(coef, self.domain, self.window)
+
+    def __rdiv__(self, other):
+        # set to __floordiv__ /.
+        return self.__rfloordiv__(other)
+
+    def __rtruediv__(self, other):
+        # An instance of ABCPolyBase is not considered a
+        # Number.
+        return NotImplemented
+
+    def __rfloordiv__(self, other):
+        res = self.__rdivmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[0]
+
+    def __rmod__(self, other):
+        res = self.__rdivmod__(other)
+        if res is NotImplemented:
+            return res
+        return res[1]
+
+    def __rdivmod__(self, other):
+        try:
+            quo, rem = self._div(other, self.coef)
+        except ZeroDivisionError as e:
+            raise e
+        except:
+            return NotImplemented
+        quo = self.__class__(quo, self.domain, self.window)
+        rem = self.__class__(rem, self.domain, self.window)
+        return quo, rem
+
+    # Enhance me
+    # some augmented arithmetic operations could be added here
+
+    def __eq__(self, other):
+        res = (isinstance(other, self.__class__) and
+               np.all(self.domain == other.domain) and
+               np.all(self.window == other.window) and
+               (self.coef.shape == other.coef.shape) and
+               np.all(self.coef == other.coef))
+        return res
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    #
+    # Extra methods.
+    #
+
+    def copy(self):
+        """Return a copy.
+
+        Returns
+        -------
+        new_series : series
+            Copy of self.
+
+        """
+        return self.__class__(self.coef, self.domain, self.window)
+
+    def degree(self):
+        """The degree of the series.
+
+        .. versionadded:: 1.5.0
+
+        Returns
+        -------
+        degree : int
+            Degree of the series, one less than the number of coefficients.
+
+        """
+        return len(self) - 1
+
+    def cutdeg(self, deg):
+        """Truncate series to the given degree.
+
+        Reduce the degree of the series to `deg` by discarding the
+        high order terms. If `deg` is greater than the current degree a
+        copy of the current series is returned. This can be useful in least
+        squares where the coefficients of the high degree terms may be very
+        small.
+
+        .. versionadded:: 1.5.0
+
+        Parameters
+        ----------
+        deg : non-negative int
+            The series is reduced to degree `deg` by discarding the high
+            order terms. The value of `deg` must be a non-negative integer.
+
+        Returns
+        -------
+        new_series : series
+            New instance of series with reduced degree.
+
+        """
+        return self.truncate(deg + 1)
+
+    def trim(self, tol=0):
+        """Remove trailing coefficients
+
+        Remove trailing coefficients until a coefficient is reached whose
+        absolute value greater than `tol` or the beginning of the series is
+        reached. If all the coefficients would be removed the series is set
+        to ``[0]``. A new series instance is returned with the new
+        coefficients.  The current instance remains unchanged.
+
+        Parameters
+        ----------
+        tol : non-negative number.
+            All trailing coefficients less than `tol` will be removed.
+
+        Returns
+        -------
+        new_series : series
+            Contains the new set of coefficients.
+
+        """
+        coef = pu.trimcoef(self.coef, tol)
+        return self.__class__(coef, self.domain, self.window)
+
+    def truncate(self, size):
+        """Truncate series to length `size`.
+
+        Reduce the series to length `size` by discarding the high
+        degree terms. The value of `size` must be a positive integer. This
+        can be useful in least squares where the coefficients of the
+        high degree terms may be very small.
+
+        Parameters
+        ----------
+        size : positive int
+            The series is reduced to length `size` by discarding the high
+            degree terms. The value of `size` must be a positive integer.
+
+        Returns
+        -------
+        new_series : series
+            New instance of series with truncated coefficients.
+
+        """
+        isize = int(size)
+        if isize != size or isize < 1:
+            raise ValueError("size must be a positive integer")
+        if isize >= len(self.coef):
+            coef = self.coef
+        else:
+            coef = self.coef[:isize]
+        return self.__class__(coef, self.domain, self.window)
+
+    def convert(self, domain=None, kind=None, window=None):
+        """Convert series to a different kind and/or domain and/or window.
+
+        Parameters
+        ----------
+        domain : array_like, optional
+            The domain of the converted series. If the value is None,
+            the default domain of `kind` is used.
+        kind : class, optional
+            The polynomial series type class to which the current instance
+            should be converted. If kind is None, then the class of the
+            current instance is used.
+        window : array_like, optional
+            The window of the converted series. If the value is None,
+            the default window of `kind` is used.
+
+        Returns
+        -------
+        new_series : series
+            The returned class can be of different type than the current
+            instance and/or have a different domain and/or different
+            window.
+
+        Notes
+        -----
+        Conversion between domains and class types can result in
+        numerically ill defined series.
+
+        Examples
+        --------
+
+        """
+        if kind is None:
+            kind = self.__class__
+        if domain is None:
+            domain = kind.domain
+        if window is None:
+            window = kind.window
+        return self(kind.identity(domain, window=window))
+
+    def mapparms(self):
+        """Return the mapping parameters.
+
+        The returned values define a linear map ``off + scl*x`` that is
+        applied to the input arguments before the series is evaluated. The
+        map depends on the ``domain`` and ``window``; if the current
+        ``domain`` is equal to the ``window`` the resulting map is the
+        identity.  If the coefficients of the series instance are to be
+        used by themselves outside this class, then the linear function
+        must be substituted for the ``x`` in the standard representation of
+        the base polynomials.
+
+        Returns
+        -------
+        off, scl : float or complex
+            The mapping function is defined by ``off + scl*x``.
+
+        Notes
+        -----
+        If the current domain is the interval ``[l1, r1]`` and the window
+        is ``[l2, r2]``, then the linear mapping function ``L`` is
+        defined by the equations::
+
+            L(l1) = l2
+            L(r1) = r2
+
+        """
+        return pu.mapparms(self.domain, self.window)
+
+    def integ(self, m=1, k=[], lbnd=None):
+        """Integrate.
+
+        Return a series instance that is the definite integral of the
+        current series.
+
+        Parameters
+        ----------
+        m : non-negative int
+            The number of integrations to perform.
+        k : array_like
+            Integration constants. The first constant is applied to the
+            first integration, the second to the second, and so on. The
+            list of values must less than or equal to `m` in length and any
+            missing values are set to zero.
+        lbnd : Scalar
+            The lower bound of the definite integral.
+
+        Returns
+        -------
+        new_series : series
+            A new series representing the integral. The domain is the same
+            as the domain of the integrated series.
+
+        """
+        off, scl = self.mapparms()
+        if lbnd is None:
+            lbnd = 0
+        else:
+            lbnd = off + scl*lbnd
+        coef = self._int(self.coef, m, k, lbnd, 1./scl)
+        return self.__class__(coef, self.domain, self.window)
+
+    def deriv(self, m=1):
+        """Differentiate.
+
+        Return a series instance of that is the derivative of the current
+        series.
+
+        Parameters
+        ----------
+        m : non-negative int
+            Find the derivative of order `m`.
+
+        Returns
+        -------
+        new_series : series
+            A new series representing the derivative. The domain is the same
+            as the domain of the differentiated series.
+
+        """
+        off, scl = self.mapparms()
+        coef = self._der(self.coef, m, scl)
+        return self.__class__(coef, self.domain, self.window)
+
+    def roots(self):
+        """Return the roots of the series polynomial.
+
+        Compute the roots for the series. Note that the accuracy of the
+        roots decrease the further outside the domain they lie.
+
+        Returns
+        -------
+        roots : ndarray
+            Array containing the roots of the series.
+
+        """
+        roots = self._roots(self.coef)
+        return pu.mapdomain(roots, self.window, self.domain)
+
+    def linspace(self, n=100, domain=None):
+        """Return x, y values at equally spaced points in domain.
+
+        Returns the x, y values at `n` linearly spaced points across the
+        domain.  Here y is the value of the polynomial at the points x. By
+        default the domain is the same as that of the series instance.
+        This method is intended mostly as a plotting aid.
+
+        .. versionadded:: 1.5.0
+
+        Parameters
+        ----------
+        n : int, optional
+            Number of point pairs to return. The default value is 100.
+        domain : {None, array_like}, optional
+            If not None, the specified domain is used instead of that of
+            the calling instance. It should be of the form ``[beg,end]``.
+            The default is None which case the class domain is used.
+
+        Returns
+        -------
+        x, y : ndarray
+            x is equal to linspace(self.domain[0], self.domain[1], n) and
+            y is the series evaluated at element of x.
+
+        """
+        if domain is None:
+            domain = self.domain
+        x = np.linspace(domain[0], domain[1], n)
+        y = self(x)
+        return x, y
+
+    @classmethod
+    def fit(cls, x, y, deg, domain=None, rcond=None, full=False, w=None,
+        window=None):
+        """Least squares fit to data.
+
+        Return a series instance that is the least squares fit to the data
+        `y` sampled at `x`. The domain of the returned instance can be
+        specified and this will often result in a superior fit with less
+        chance of ill conditioning.
+
+        Parameters
+        ----------
+        x : array_like, shape (M,)
+            x-coordinates of the M sample points ``(x[i], y[i])``.
+        y : array_like, shape (M,) or (M, K)
+            y-coordinates of the sample points. Several data sets of sample
+            points sharing the same x-coordinates can be fitted at once by
+            passing in a 2D-array that contains one dataset per column.
+        deg : int or 1-D array_like
+            Degree(s) of the fitting polynomials. If `deg` is a single integer
+            all terms up to and including the `deg`'th term are included in the
+            fit. For Numpy versions >= 1.11 a list of integers specifying the
+            degrees of the terms to include may be used instead.
+        domain : {None, [beg, end], []}, optional
+            Domain to use for the returned series. If ``None``,
+            then a minimal domain that covers the points `x` is chosen.  If
+            ``[]`` the class domain is used. The default value was the
+            class domain in NumPy 1.4 and ``None`` in later versions.
+            The ``[]`` option was added in numpy 1.5.0.
+        rcond : float, optional
+            Relative condition number of the fit. Singular values smaller
+            than this relative to the largest singular value will be
+            ignored. The default value is len(x)*eps, where eps is the
+            relative precision of the float type, about 2e-16 in most
+            cases.
+        full : bool, optional
+            Switch determining nature of return value. When it is False
+            (the default) just the coefficients are returned, when True
+            diagnostic information from the singular value decomposition is
+            also returned.
+        w : array_like, shape (M,), optional
+            Weights. If not None the contribution of each point
+            ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+            weights are chosen so that the errors of the products
+            ``w[i]*y[i]`` all have the same variance.  The default value is
+            None.
+
+            .. versionadded:: 1.5.0
+        window : {[beg, end]}, optional
+            Window to use for the returned series. The default
+            value is the default class domain
+
+            .. versionadded:: 1.6.0
+
+        Returns
+        -------
+        new_series : series
+            A series that represents the least squares fit to the data and
+            has the domain specified in the call.
+
+        [resid, rank, sv, rcond] : list
+            These values are only returned if `full` = True
+
+            resid -- sum of squared residuals of the least squares fit
+            rank -- the numerical rank of the scaled Vandermonde matrix
+            sv -- singular values of the scaled Vandermonde matrix
+            rcond -- value of `rcond`.
+
+            For more details, see `linalg.lstsq`.
+
+        """
+        if domain is None:
+            domain = pu.getdomain(x)
+        elif type(domain) is list and len(domain) == 0:
+            domain = cls.domain
+
+        if window is None:
+            window = cls.window
+
+        xnew = pu.mapdomain(x, domain, window)
+        res = cls._fit(xnew, y, deg, w=w, rcond=rcond, full=full)
+        if full:
+            [coef, status] = res
+            return cls(coef, domain=domain, window=window), status
+        else:
+            coef = res
+            return cls(coef, domain=domain, window=window)
+
+    @classmethod
+    def fromroots(cls, roots, domain=[], window=None):
+        """Return series instance that has the specified roots.
+
+        Returns a series representing the product
+        ``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is a
+        list of roots.
+
+        Parameters
+        ----------
+        roots : array_like
+            List of roots.
+        domain : {[], None, array_like}, optional
+            Domain for the resulting series. If None the domain is the
+            interval from the smallest root to the largest. If [] the
+            domain is the class domain. The default is [].
+        window : {None, array_like}, optional
+            Window for the returned series. If None the class window is
+            used. The default is None.
+
+        Returns
+        -------
+        new_series : series
+            Series with the specified roots.
+
+        """
+        [roots] = pu.as_series([roots], trim=False)
+        if domain is None:
+            domain = pu.getdomain(roots)
+        elif type(domain) is list and len(domain) == 0:
+            domain = cls.domain
+
+        if window is None:
+            window = cls.window
+
+        deg = len(roots)
+        off, scl = pu.mapparms(domain, window)
+        rnew = off + scl*roots
+        coef = cls._fromroots(rnew) / scl**deg
+        return cls(coef, domain=domain, window=window)
+
+    @classmethod
+    def identity(cls, domain=None, window=None):
+        """Identity function.
+
+        If ``p`` is the returned series, then ``p(x) == x`` for all
+        values of x.
+
+        Parameters
+        ----------
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+             Series of representing the identity.
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        off, scl = pu.mapparms(window, domain)
+        coef = cls._line(off, scl)
+        return cls(coef, domain, window)
+
+    @classmethod
+    def basis(cls, deg, domain=None, window=None):
+        """Series basis polynomial of degree `deg`.
+
+        Returns the series representing the basis polynomial of degree `deg`.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        deg : int
+            Degree of the basis polynomial for the series. Must be >= 0.
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+            A series with the coefficient of the `deg` term set to one and
+            all others zero.
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        ideg = int(deg)
+
+        if ideg != deg or ideg < 0:
+            raise ValueError("deg must be non-negative integer")
+        return cls([0]*ideg + [1], domain, window)
+
+    @classmethod
+    def cast(cls, series, domain=None, window=None):
+        """Convert series to series of this class.
+
+        The `series` is expected to be an instance of some polynomial
+        series of one of the types supported by by the numpy.polynomial
+        module, but could be some other class that supports the convert
+        method.
+
+        .. versionadded:: 1.7.0
+
+        Parameters
+        ----------
+        series : series
+            The series instance to be converted.
+        domain : {None, array_like}, optional
+            If given, the array must be of the form ``[beg, end]``, where
+            ``beg`` and ``end`` are the endpoints of the domain. If None is
+            given then the class domain is used. The default is None.
+        window : {None, array_like}, optional
+            If given, the resulting array must be if the form
+            ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of
+            the window. If None is given then the class window is used. The
+            default is None.
+
+        Returns
+        -------
+        new_series : series
+            A series of the same kind as the calling class and equal to
+            `series` when evaluated.
+
+        See Also
+        --------
+        convert : similar instance method
+
+        """
+        if domain is None:
+            domain = cls.domain
+        if window is None:
+            window = cls.window
+        return series.convert(domain, cls, window)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
new file mode 100644
index 0000000000..2537bea32d
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
@@ -0,0 +1,2080 @@
+"""
+Objects for dealing with Chebyshev series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Chebyshev series, including a `Chebyshev` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `chebdomain` -- Chebyshev series default domain, [-1,1].
+- `chebzero` -- (Coefficients of the) Chebyshev series that evaluates
+  identically to 0.
+- `chebone` -- (Coefficients of the) Chebyshev series that evaluates
+  identically to 1.
+- `chebx` -- (Coefficients of the) Chebyshev series for the identity map,
+  ``f(x) = x``.
+
+Arithmetic
+----------
+- `chebadd` -- add two Chebyshev series.
+- `chebsub` -- subtract one Chebyshev series from another.
+- `chebmul` -- multiply two Chebyshev series.
+- `chebdiv` -- divide one Chebyshev series by another.
+- `chebpow` -- raise a Chebyshev series to an positive integer power
+- `chebval` -- evaluate a Chebyshev series at given points.
+- `chebval2d` -- evaluate a 2D Chebyshev series at given points.
+- `chebval3d` -- evaluate a 3D Chebyshev series at given points.
+- `chebgrid2d` -- evaluate a 2D Chebyshev series on a Cartesian product.
+- `chebgrid3d` -- evaluate a 3D Chebyshev series on a Cartesian product.
+
+Calculus
+--------
+- `chebder` -- differentiate a Chebyshev series.
+- `chebint` -- integrate a Chebyshev series.
+
+Misc Functions
+--------------
+- `chebfromroots` -- create a Chebyshev series with specified roots.
+- `chebroots` -- find the roots of a Chebyshev series.
+- `chebvander` -- Vandermonde-like matrix for Chebyshev polynomials.
+- `chebvander2d` -- Vandermonde-like matrix for 2D power series.
+- `chebvander3d` -- Vandermonde-like matrix for 3D power series.
+- `chebgauss` -- Gauss-Chebyshev quadrature, points and weights.
+- `chebweight` -- Chebyshev weight function.
+- `chebcompanion` -- symmetrized companion matrix in Chebyshev form.
+- `chebfit` -- least-squares fit returning a Chebyshev series.
+- `chebpts1` -- Chebyshev points of the first kind.
+- `chebpts2` -- Chebyshev points of the second kind.
+- `chebtrim` -- trim leading coefficients from a Chebyshev series.
+- `chebline` -- Chebyshev series representing given straight line.
+- `cheb2poly` -- convert a Chebyshev series to a polynomial.
+- `poly2cheb` -- convert a polynomial to a Chebyshev series.
+
+Classes
+-------
+- `Chebyshev` -- A Chebyshev series class.
+
+See also
+--------
+`numpy.polynomial`
+
+Notes
+-----
+The implementations of multiplication, division, integration, and
+differentiation use the algebraic identities [1]_:
+
+.. math ::
+    T_n(x) = \\frac{z^n + z^{-n}}{2} \\\\
+    z\\frac{dx}{dz} = \\frac{z - z^{-1}}{2}.
+
+where
+
+.. math :: x = \\frac{z + z^{-1}}{2}.
+
+These identities allow a Chebyshev series to be expressed as a finite,
+symmetric Laurent series.  In this module, this sort of Laurent series
+is referred to as a "z-series."
+
+References
+----------
+.. [1] A. T. Benjamin, et al., "Combinatorial Trigonometry with Chebyshev
+  Polynomials," *Journal of Statistical Planning and Inference 14*, 2008
+  (preprint: http://www.math.hmc.edu/~benjamin/papers/CombTrig.pdf, pg. 4)
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'chebzero', 'chebone', 'chebx', 'chebdomain', 'chebline', 'chebadd',
+    'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval',
+    'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots',
+    'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1',
+    'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d',
+    'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion',
+    'chebgauss', 'chebweight']
+
+chebtrim = pu.trimcoef
+
+#
+# A collection of functions for manipulating z-series. These are private
+# functions and do minimal error checking.
+#
+
+def _cseries_to_zseries(c):
+    """Covert Chebyshev series to z-series.
+
+    Covert a Chebyshev series to the equivalent z-series. The result is
+    never an empty array. The dtype of the return is the same as that of
+    the input. No checks are run on the arguments as this routine is for
+    internal use.
+
+    Parameters
+    ----------
+    c : 1-D ndarray
+        Chebyshev coefficients, ordered from low to high
+
+    Returns
+    -------
+    zs : 1-D ndarray
+        Odd length symmetric z-series, ordered from  low to high.
+
+    """
+    n = c.size
+    zs = np.zeros(2*n-1, dtype=c.dtype)
+    zs[n-1:] = c/2
+    return zs + zs[::-1]
+
+
+def _zseries_to_cseries(zs):
+    """Covert z-series to a Chebyshev series.
+
+    Covert a z series to the equivalent Chebyshev series. The result is
+    never an empty array. The dtype of the return is the same as that of
+    the input. No checks are run on the arguments as this routine is for
+    internal use.
+
+    Parameters
+    ----------
+    zs : 1-D ndarray
+        Odd length symmetric z-series, ordered from  low to high.
+
+    Returns
+    -------
+    c : 1-D ndarray
+        Chebyshev coefficients, ordered from  low to high.
+
+    """
+    n = (zs.size + 1)//2
+    c = zs[n-1:].copy()
+    c[1:n] *= 2
+    return c
+
+
+def _zseries_mul(z1, z2):
+    """Multiply two z-series.
+
+    Multiply two z-series to produce a z-series.
+
+    Parameters
+    ----------
+    z1, z2 : 1-D ndarray
+        The arrays must be 1-D but this is not checked.
+
+    Returns
+    -------
+    product : 1-D ndarray
+        The product z-series.
+
+    Notes
+    -----
+    This is simply convolution. If symmetric/anti-symmetric z-series are
+    denoted by S/A then the following rules apply:
+
+    S*S, A*A -> S
+    S*A, A*S -> A
+
+    """
+    return np.convolve(z1, z2)
+
+
+def _zseries_div(z1, z2):
+    """Divide the first z-series by the second.
+
+    Divide `z1` by `z2` and return the quotient and remainder as z-series.
+    Warning: this implementation only applies when both z1 and z2 have the
+    same symmetry, which is sufficient for present purposes.
+
+    Parameters
+    ----------
+    z1, z2 : 1-D ndarray
+        The arrays must be 1-D and have the same symmetry, but this is not
+        checked.
+
+    Returns
+    -------
+
+    (quotient, remainder) : 1-D ndarrays
+        Quotient and remainder as z-series.
+
+    Notes
+    -----
+    This is not the same as polynomial division on account of the desired form
+    of the remainder. If symmetric/anti-symmetric z-series are denoted by S/A
+    then the following rules apply:
+
+    S/S -> S,S
+    A/A -> S,A
+
+    The restriction to types of the same symmetry could be fixed but seems like
+    unneeded generality. There is no natural form for the remainder in the case
+    where there is no symmetry.
+
+    """
+    z1 = z1.copy()
+    z2 = z2.copy()
+    len1 = len(z1)
+    len2 = len(z2)
+    if len2 == 1:
+        z1 /= z2
+        return z1, z1[:1]*0
+    elif len1 < len2:
+        return z1[:1]*0, z1
+    else:
+        dlen = len1 - len2
+        scl = z2[0]
+        z2 /= scl
+        quo = np.empty(dlen + 1, dtype=z1.dtype)
+        i = 0
+        j = dlen
+        while i < j:
+            r = z1[i]
+            quo[i] = z1[i]
+            quo[dlen - i] = r
+            tmp = r*z2
+            z1[i:i+len2] -= tmp
+            z1[j:j+len2] -= tmp
+            i += 1
+            j -= 1
+        r = z1[i]
+        quo[i] = r
+        tmp = r*z2
+        z1[i:i+len2] -= tmp
+        quo /= scl
+        rem = z1[i+1:i-1+len2].copy()
+        return quo, rem
+
+
+def _zseries_der(zs):
+    """Differentiate a z-series.
+
+    The derivative is with respect to x, not z. This is achieved using the
+    chain rule and the value of dx/dz given in the module notes.
+
+    Parameters
+    ----------
+    zs : z-series
+        The z-series to differentiate.
+
+    Returns
+    -------
+    derivative : z-series
+        The derivative
+
+    Notes
+    -----
+    The zseries for x (ns) has been multiplied by two in order to avoid
+    using floats that are incompatible with Decimal and likely other
+    specialized scalar types. This scaling has been compensated by
+    multiplying the value of zs by two also so that the two cancels in the
+    division.
+
+    """
+    n = len(zs)//2
+    ns = np.array([-1, 0, 1], dtype=zs.dtype)
+    zs *= np.arange(-n, n+1)*2
+    d, r = _zseries_div(zs, ns)
+    return d
+
+
+def _zseries_int(zs):
+    """Integrate a z-series.
+
+    The integral is with respect to x, not z. This is achieved by a change
+    of variable using dx/dz given in the module notes.
+
+    Parameters
+    ----------
+    zs : z-series
+        The z-series to integrate
+
+    Returns
+    -------
+    integral : z-series
+        The indefinite integral
+
+    Notes
+    -----
+    The zseries for x (ns) has been multiplied by two in order to avoid
+    using floats that are incompatible with Decimal and likely other
+    specialized scalar types. This scaling has been compensated by
+    dividing the resulting zs by two.
+
+    """
+    n = 1 + len(zs)//2
+    ns = np.array([-1, 0, 1], dtype=zs.dtype)
+    zs = _zseries_mul(zs, ns)
+    div = np.arange(-n, n+1)*2
+    zs[:n] /= div[:n]
+    zs[n+1:] /= div[n+1:]
+    zs[n] = 0
+    return zs
+
+#
+# Chebyshev series functions
+#
+
+
+def poly2cheb(pol):
+    """
+    Convert a polynomial to a Chebyshev series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Chebyshev series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Chebyshev
+        series.
+
+    See Also
+    --------
+    cheb2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> p = P.Polynomial(range(4))
+    >>> p
+    Polynomial([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> c = p.convert(kind=P.Chebyshev)
+    >>> c
+    Chebyshev([ 1.  ,  3.25,  1.  ,  0.75], [-1.,  1.])
+    >>> P.poly2cheb(range(4))
+    array([ 1.  ,  3.25,  1.  ,  0.75])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = chebadd(chebmulx(res), pol[i])
+    return res
+
+
+def cheb2poly(c):
+    """
+    Convert a Chebyshev series to a polynomial.
+
+    Convert an array representing the coefficients of a Chebyshev series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Chebyshev series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2cheb
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> c = P.Chebyshev(range(4))
+    >>> c
+    Chebyshev([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> p = c.convert(kind=P.Polynomial)
+    >>> p
+    Polynomial([ -2.,  -8.,   4.,  12.], [-1.,  1.])
+    >>> P.cheb2poly(range(4))
+    array([ -2.,  -8.,   4.,  12.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n < 3:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1)
+            c1 = polyadd(tmp, polymulx(c1)*2)
+        return polyadd(c0, polymulx(c1))
+
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Chebyshev default domain.
+chebdomain = np.array([-1, 1])
+
+# Chebyshev coefficients representing zero.
+chebzero = np.array([0])
+
+# Chebyshev coefficients representing one.
+chebone = np.array([1])
+
+# Chebyshev coefficients representing the identity x.
+chebx = np.array([0, 1])
+
+
+def chebline(off, scl):
+    """
+    Chebyshev series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Chebyshev series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as C
+    >>> C.chebline(3,2)
+    array([3, 2])
+    >>> C.chebval(-3, C.chebline(3,2)) # should be -3
+    -3.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def chebfromroots(roots):
+    """
+    Generate a Chebyshev series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Chebyshev form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * T_1(x) + ... +  c_n * T_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Chebyshev form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as C
+    >>> C.chebfromroots((-1,0,1)) # x^3 - x relative to the standard basis
+    array([ 0.  , -0.25,  0.  ,  0.25])
+    >>> j = complex(0,1)
+    >>> C.chebfromroots((-j,j)) # x^2 + 1 relative to the standard basis
+    array([ 1.5+0.j,  0.0+0.j,  0.5+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [chebline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [chebmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = chebmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def chebadd(c1, c2):
+    """
+    Add one Chebyshev series to another.
+
+    Returns the sum of two Chebyshev series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Chebyshev series of their sum.
+
+    See Also
+    --------
+    chebsub, chebmul, chebdiv, chebpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Chebyshev series
+    is a Chebyshev series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebadd(c1,c2)
+    array([ 4.,  4.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def chebsub(c1, c2):
+    """
+    Subtract one Chebyshev series from another.
+
+    Returns the difference of two Chebyshev series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Chebyshev series coefficients representing their difference.
+
+    See Also
+    --------
+    chebadd, chebmul, chebdiv, chebpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Chebyshev
+    series is a Chebyshev series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebsub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> C.chebsub(c2,c1) # -C.chebsub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def chebmulx(c):
+    """Multiply a Chebyshev series by x.
+
+    Multiply the polynomial `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    if len(c) > 1:
+        tmp = c[1:]/2
+        prd[2:] = tmp
+        prd[0:-2] += tmp
+    return prd
+
+
+def chebmul(c1, c2):
+    """
+    Multiply one Chebyshev series by another.
+
+    Returns the product of two Chebyshev series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Chebyshev series coefficients representing their product.
+
+    See Also
+    --------
+    chebadd, chebsub, chebdiv, chebpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Chebyshev polynomial basis set.  Thus, to express
+    the product as a C-series, it is typically necessary to "reproject"
+    the product onto said basis set, which typically produces
+    "unintuitive live" (but correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebmul(c1,c2) # multiplication requires "reprojection"
+    array([  6.5,  12. ,  12. ,   4. ,   1.5])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    z1 = _cseries_to_zseries(c1)
+    z2 = _cseries_to_zseries(c2)
+    prd = _zseries_mul(z1, z2)
+    ret = _zseries_to_cseries(prd)
+    return pu.trimseq(ret)
+
+
+def chebdiv(c1, c2):
+    """
+    Divide one Chebyshev series by another.
+
+    Returns the quotient-with-remainder of two Chebyshev series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``T_0 + 2*T_1 + 3*T_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Chebyshev series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Chebyshev series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    chebadd, chebsub, chebmul, chebpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one C-series by another
+    results in quotient and remainder terms that are not in the Chebyshev
+    polynomial basis set.  Thus, to express these results as C-series, it
+    is typically necessary to "reproject" the results onto said basis
+    set, which typically produces "unintuitive" (but correct) results;
+    see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> C.chebdiv(c1,c2) # quotient "intuitive," remainder not
+    (array([ 3.]), array([-8., -4.]))
+    >>> c2 = (0,1,2,3)
+    >>> C.chebdiv(c2,c1) # neither "intuitive"
+    (array([ 0.,  2.]), array([-2., -4.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        z1 = _cseries_to_zseries(c1)
+        z2 = _cseries_to_zseries(c2)
+        quo, rem = _zseries_div(z1, z2)
+        quo = pu.trimseq(_zseries_to_cseries(quo))
+        rem = pu.trimseq(_zseries_to_cseries(rem))
+        return quo, rem
+
+
+def chebpow(c, pow, maxpower=16):
+    """Raise a Chebyshev series to a power.
+
+    Returns the Chebyshev series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``T_0 + 2*T_1 + 3*T_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Chebyshev series of power.
+
+    See Also
+    --------
+    chebadd, chebsub, chebmul, chebdiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        zs = _cseries_to_zseries(c)
+        prd = zs
+        for i in range(2, power + 1):
+            prd = np.convolve(prd, zs)
+        return _zseries_to_cseries(prd)
+
+
+def chebder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Chebyshev series.
+
+    Returns the Chebyshev series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*T_0 + 2*T_1 + 3*T_2``
+    while [[1,2],[1,2]] represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) +
+    2*T_0(x)*T_1(y) + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Chebyshev series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Chebyshev series of the derivative.
+
+    See Also
+    --------
+    chebint
+
+    Notes
+    -----
+    In general, the result of differentiating a C-series needs to be
+    "reprojected" onto the C-series basis set. Thus, typically, the
+    result of this function is "unintuitive," albeit correct; see Examples
+    section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c = (1,2,3,4)
+    >>> C.chebder(c)
+    array([ 14.,  12.,  24.])
+    >>> C.chebder(c,3)
+    array([ 96.])
+    >>> C.chebder(c,scl=-1)
+    array([-14., -12., -24.])
+    >>> C.chebder(c,2,-1)
+    array([ 12.,  96.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 2, -1):
+                der[j - 1] = (2*j)*c[j]
+                c[j - 2] += (j*c[j])/(j - 2)
+            if n > 1:
+                der[1] = 4*c[2]
+            der[0] = c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Chebyshev series.
+
+    Returns the Chebyshev series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``T_0 + 2*T_1 + 3*T_2`` while [[1,2],[1,2]]
+    represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 2*T_0(x)*T_1(y) +
+    2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Chebyshev series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at zero
+        is the first value in the list, the value of the second integral
+        at zero is the second value, etc.  If ``k == []`` (the default),
+        all constants are set to zero.  If ``m == 1``, a single scalar can
+        be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        C-series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 1``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    chebder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a`- perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import chebyshev as C
+    >>> c = (1,2,3)
+    >>> C.chebint(c)
+    array([ 0.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,3)
+    array([ 0.03125   , -0.1875    ,  0.04166667, -0.05208333,  0.01041667,
+            0.00625   ])
+    >>> C.chebint(c, k=3)
+    array([ 3.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,lbnd=-2)
+    array([ 8.5, -0.5,  0.5,  0.5])
+    >>> C.chebint(c,scl=-2)
+    array([-1.,  1., -1., -1.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            if n > 1:
+                tmp[2] = c[1]/4
+            for j in range(2, n):
+                t = c[j]/(2*j + 1)
+                tmp[j + 1] = c[j]/(2*(j + 1))
+                tmp[j - 1] -= c[j]/(2*(j - 1))
+            tmp[0] += k[i] - chebval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def chebval(x, c, tensor=True):
+    """
+    Evaluate a Chebyshev series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * T_0(x) + c_1 * T_1(x) + ... + c_n * T_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    chebval2d, chebgrid2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        x2 = 2*x
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            c0 = c[-i] - c1
+            c1 = tmp + c1*x2
+    return c0 + c1*x
+
+
+def chebval2d(x, y, c):
+    """
+    Evaluate a 2-D Chebyshev series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * T_i(x) * T_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than 2 the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points formed
+        from pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebgrid2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = chebval(x, c)
+    c = chebval(y, c, tensor=False)
+    return c
+
+
+def chebgrid2d(x, y, c):
+    """
+    Evaluate a 2-D Chebyshev series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * T_i(a) * T_j(b),
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebval3d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = chebval(x, c)
+    c = chebval(y, c)
+    return c
+
+
+def chebval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Chebyshev series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * T_i(x) * T_j(y) * T_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebgrid2d, chebgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = chebval(x, c)
+    c = chebval(y, c, tensor=False)
+    c = chebval(z, c, tensor=False)
+    return c
+
+
+def chebgrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * T_i(a) * T_j(b) * T_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    chebval, chebval2d, chebgrid2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = chebval(x, c)
+    c = chebval(y, c)
+    c = chebval(z, c)
+    return c
+
+
+def chebvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = T_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Chebyshev polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    matrix ``V = chebvander(x, n)``, then ``np.dot(V, c)`` and
+    ``chebval(x, c)`` are the same up to roundoff.  This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Chebyshev series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Chebyshev polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    # Use forward recursion to generate the entries.
+    v[0] = x*0 + 1
+    if ideg > 0:
+        x2 = 2*x
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = v[i-1]*x2 - v[i-2]
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def chebvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = T_i(x) * T_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Chebyshev polynomials.
+
+    If ``V = chebvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``chebval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Chebyshev
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    chebvander, chebvander3d. chebval2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = chebvander(x, degx)
+    vy = chebvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def chebvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = T_i(x)*T_j(y)*T_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Chebyshev polynomials.
+
+    If ``V = chebvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and ``np.dot(V, c.flat)`` and ``chebval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Chebyshev
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    chebvander, chebvander3d. chebval2d, chebval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = chebvander(x, degx)
+    vy = chebvander(y, degy)
+    vz = chebvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def chebfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Chebyshev series to data.
+
+    Return the coefficients of a Legendre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Chebyshev coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    polyfit, legfit, lagfit, hermfit, hermefit
+    chebval : Evaluates a Chebyshev series.
+    chebvander : Vandermonde matrix of Chebyshev series.
+    chebweight : Chebyshev weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Chebyshev series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where :math:`w_j` are the weights. This problem is solved by setting up
+    as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Chebyshev series are usually better conditioned than fits
+    using power series, but much can depend on the distribution of the
+    sample points and the smoothness of the data. If the quality of the fit
+    is inadequate splines may be a good alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = chebvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = chebvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax + 1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax + 1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def chebcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is a Chebyshev basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Chebyshev series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.array([1.] + [np.sqrt(.5)]*(n-1))
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[0] = np.sqrt(.5)
+    top[1:] = 1/2
+    bot[...] = top
+    mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*.5
+    return mat
+
+
+def chebroots(c):
+    """
+    Compute the roots of a Chebyshev series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * T_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Chebyshev series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.chebyshev as cheb
+    >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots
+    array([ -5.00000000e-01,   2.60860684e-17,   1.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = chebcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def chebgauss(deg):
+    """
+    Gauss-Chebyshev quadrature.
+
+    Computes the sample points and weights for Gauss-Chebyshev quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
+    the weight function :math:`f(x) = 1/\sqrt{1 - x^2}`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. For Gauss-Chebyshev there are closed form solutions for
+    the sample points and weights. If n = `deg`, then
+
+    .. math:: x_i = \cos(\pi (2 i - 1) / (2 n))
+
+    .. math:: w_i = \pi / n
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    x = np.cos(np.pi * np.arange(1, 2*ideg, 2) / (2.0*ideg))
+    w = np.ones(ideg)*(np.pi/ideg)
+
+    return x, w
+
+
+def chebweight(x):
+    """
+    The weight function of the Chebyshev polynomials.
+
+    The weight function is :math:`1/\sqrt{1 - x^2}` and the interval of
+    integration is :math:`[-1, 1]`. The Chebyshev polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    w = 1./(np.sqrt(1. + x) * np.sqrt(1. - x))
+    return w
+
+
+def chebpts1(npts):
+    """
+    Chebyshev points of the first kind.
+
+    The Chebyshev points of the first kind are the points ``cos(x)``,
+    where ``x = [pi*(k + .5)/npts for k in range(npts)]``.
+
+    Parameters
+    ----------
+    npts : int
+        Number of sample points desired.
+
+    Returns
+    -------
+    pts : ndarray
+        The Chebyshev points of the first kind.
+
+    See Also
+    --------
+    chebpts2
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    _npts = int(npts)
+    if _npts != npts:
+        raise ValueError("npts must be integer")
+    if _npts < 1:
+        raise ValueError("npts must be >= 1")
+
+    x = np.linspace(-np.pi, 0, _npts, endpoint=False) + np.pi/(2*_npts)
+    return np.cos(x)
+
+
+def chebpts2(npts):
+    """
+    Chebyshev points of the second kind.
+
+    The Chebyshev points of the second kind are the points ``cos(x)``,
+    where ``x = [pi*k/(npts - 1) for k in range(npts)]``.
+
+    Parameters
+    ----------
+    npts : int
+        Number of sample points desired.
+
+    Returns
+    -------
+    pts : ndarray
+        The Chebyshev points of the second kind.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    _npts = int(npts)
+    if _npts != npts:
+        raise ValueError("npts must be integer")
+    if _npts < 2:
+        raise ValueError("npts must be >= 2")
+
+    x = np.linspace(-np.pi, 0, _npts)
+    return np.cos(x)
+
+
+#
+# Chebyshev series class
+#
+
+class Chebyshev(ABCPolyBase):
+    """A Chebyshev series class.
+
+    The Chebyshev class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    methods listed below.
+
+    Parameters
+    ----------
+    coef : array_like
+        Chebyshev coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*T_0(x) + 2*T_1(x) + 3*T_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(chebadd)
+    _sub = staticmethod(chebsub)
+    _mul = staticmethod(chebmul)
+    _div = staticmethod(chebdiv)
+    _pow = staticmethod(chebpow)
+    _val = staticmethod(chebval)
+    _int = staticmethod(chebint)
+    _der = staticmethod(chebder)
+    _fit = staticmethod(chebfit)
+    _line = staticmethod(chebline)
+    _roots = staticmethod(chebroots)
+    _fromroots = staticmethod(chebfromroots)
+
+    # Virtual properties
+    nickname = 'cheb'
+    domain = np.array(chebdomain)
+    window = np.array(chebdomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.py
new file mode 100644
index 0000000000..e234c8e231
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.py
@@ -0,0 +1,1854 @@
+"""
+Objects for dealing with Hermite series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Hermite series, including a `Hermite` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `hermdomain` -- Hermite series default domain, [-1,1].
+- `hermzero` -- Hermite series that evaluates identically to 0.
+- `hermone` -- Hermite series that evaluates identically to 1.
+- `hermx` -- Hermite series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `hermmulx` -- multiply a Hermite series in ``P_i(x)`` by ``x``.
+- `hermadd` -- add two Hermite series.
+- `hermsub` -- subtract one Hermite series from another.
+- `hermmul` -- multiply two Hermite series.
+- `hermdiv` -- divide one Hermite series by another.
+- `hermval` -- evaluate a Hermite series at given points.
+- `hermval2d` -- evaluate a 2D Hermite series at given points.
+- `hermval3d` -- evaluate a 3D Hermite series at given points.
+- `hermgrid2d` -- evaluate a 2D Hermite series on a Cartesian product.
+- `hermgrid3d` -- evaluate a 3D Hermite series on a Cartesian product.
+
+Calculus
+--------
+- `hermder` -- differentiate a Hermite series.
+- `hermint` -- integrate a Hermite series.
+
+Misc Functions
+--------------
+- `hermfromroots` -- create a Hermite series with specified roots.
+- `hermroots` -- find the roots of a Hermite series.
+- `hermvander` -- Vandermonde-like matrix for Hermite polynomials.
+- `hermvander2d` -- Vandermonde-like matrix for 2D power series.
+- `hermvander3d` -- Vandermonde-like matrix for 3D power series.
+- `hermgauss` -- Gauss-Hermite quadrature, points and weights.
+- `hermweight` -- Hermite weight function.
+- `hermcompanion` -- symmetrized companion matrix in Hermite form.
+- `hermfit` -- least-squares fit returning a Hermite series.
+- `hermtrim` -- trim leading coefficients from a Hermite series.
+- `hermline` -- Hermite series of given straight line.
+- `herm2poly` -- convert a Hermite series to a polynomial.
+- `poly2herm` -- convert a polynomial to a Hermite series.
+
+Classes
+-------
+- `Hermite` -- A Hermite series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd',
+    'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
+    'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
+    'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
+    'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
+    'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
+
+hermtrim = pu.trimcoef
+
+
+def poly2herm(pol):
+    """
+    poly2herm(pol)
+
+    Convert a polynomial to a Hermite series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Hermite series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Hermite
+        series.
+
+    See Also
+    --------
+    herm2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import poly2herm
+    >>> poly2herm(np.arange(4))
+    array([ 1.   ,  2.75 ,  0.5  ,  0.375])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = hermadd(hermmulx(res), pol[i])
+    return res
+
+
+def herm2poly(c):
+    """
+    Convert a Hermite series to a polynomial.
+
+    Convert an array representing the coefficients of a Hermite series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Hermite series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2herm
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import herm2poly
+    >>> herm2poly([ 1.   ,  2.75 ,  0.5  ,  0.375])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    if n == 2:
+        c[1] *= 2
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1*(2*(i - 1)))
+            c1 = polyadd(tmp, polymulx(c1)*2)
+        return polyadd(c0, polymulx(c1)*2)
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Hermite
+hermdomain = np.array([-1, 1])
+
+# Hermite coefficients representing zero.
+hermzero = np.array([0])
+
+# Hermite coefficients representing one.
+hermone = np.array([1])
+
+# Hermite coefficients representing the identity x.
+hermx = np.array([0, 1/2])
+
+
+def hermline(off, scl):
+    """
+    Hermite series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Hermite series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermline, hermval
+    >>> hermval(0,hermline(3, 2))
+    3.0
+    >>> hermval(1,hermline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl/2])
+    else:
+        return np.array([off])
+
+
+def hermfromroots(roots):
+    """
+    Generate a Hermite series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Hermite form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * H_1(x) + ... +  c_n * H_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Hermite form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, chebfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermfromroots, hermval
+    >>> coef = hermfromroots((-1, 0, 1))
+    >>> hermval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = hermfromroots((-1j, 1j))
+    >>> hermval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [hermline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [hermmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = hermmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def hermadd(c1, c2):
+    """
+    Add one Hermite series to another.
+
+    Returns the sum of two Hermite series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Hermite series of their sum.
+
+    See Also
+    --------
+    hermsub, hermmul, hermdiv, hermpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Hermite series
+    is a Hermite series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermadd
+    >>> hermadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermsub(c1, c2):
+    """
+    Subtract one Hermite series from another.
+
+    Returns the difference of two Hermite series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their difference.
+
+    See Also
+    --------
+    hermadd, hermmul, hermdiv, hermpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Hermite
+    series is a Hermite series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermsub
+    >>> hermsub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermmulx(c):
+    """Multiply a Hermite series by x.
+
+    Multiply the Hermite series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Hermite
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (P_{i + 1}(x)/2 + i*P_{i - 1}(x))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermmulx
+    >>> hermmulx([1, 2, 3])
+    array([ 2. ,  6.5,  1. ,  1.5])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]/2
+    for i in range(1, len(c)):
+        prd[i + 1] = c[i]/2
+        prd[i - 1] += c[i]*i
+    return prd
+
+
+def hermmul(c1, c2):
+    """
+    Multiply one Hermite series by another.
+
+    Returns the product of two Hermite series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their product.
+
+    See Also
+    --------
+    hermadd, hermsub, hermdiv, hermpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Hermite polynomial basis set.  Thus, to express
+    the product as a Hermite series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermmul
+    >>> hermmul([1, 2, 3], [0, 1, 2])
+    array([ 52.,  29.,  52.,   7.,   6.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = hermsub(c[-i]*xs, c1*(2*(nd - 1)))
+            c1 = hermadd(tmp, hermmulx(c1)*2)
+    return hermadd(c0, hermmulx(c1)*2)
+
+
+def hermdiv(c1, c2):
+    """
+    Divide one Hermite series by another.
+
+    Returns the quotient-with-remainder of two Hermite series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Hermite series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    hermadd, hermsub, hermmul, hermpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Hermite series by another
+    results in quotient and remainder terms that are not in the Hermite
+    polynomial basis set.  Thus, to express these results as a Hermite
+    series, it is necessary to "reproject" the results onto the Hermite
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermdiv
+    >>> hermdiv([ 52.,  29.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> hermdiv([ 54.,  31.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 2.,  2.]))
+    >>> hermdiv([ 53.,  30.,  52.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  1.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = hermmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def hermpow(c, pow, maxpower=16):
+    """Raise a Hermite series to a power.
+
+    Returns the Hermite series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Hermite series of power.
+
+    See Also
+    --------
+    hermadd, hermsub, hermmul, hermdiv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermpow
+    >>> hermpow([1, 2, 3], 2)
+    array([ 81.,  52.,  82.,  12.,   9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = hermmul(prd, c)
+        return prd
+
+
+def hermder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Hermite series.
+
+    Returns the Hermite series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2``
+    while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) +
+    2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite series coefficients. If `c` is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Hermite series of the derivative.
+
+    See Also
+    --------
+    hermint
+
+    Notes
+    -----
+    In general, the result of differentiating a Hermite series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermder
+    >>> hermder([ 1. ,  0.5,  0.5,  0.5])
+    array([ 1.,  2.,  3.])
+    >>> hermder([-0.5,  1./2.,  1./8.,  1./12.,  1./16.], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 0, -1):
+                der[j - 1] = (2*j)*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Hermite series.
+
+    Returns the Hermite series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
+    represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
+    2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Hermite series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    hermder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermint
+    >>> hermint([1,2,3]) # integrate once, value 0 at 0.
+    array([ 1. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0
+    array([-0.5       ,  0.5       ,  0.125     ,  0.08333333,  0.0625    ])
+    >>> hermint([1,2,3], k=1) # integrate once, value 1 at 0.
+    array([ 2. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1
+    array([-2. ,  0.5,  0.5,  0.5])
+    >>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1)
+    array([ 1.66666667, -0.5       ,  0.125     ,  0.08333333,  0.0625    ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]/2
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(2*(j + 1))
+            tmp[0] += k[i] - hermval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermval(x, c, tensor=True):
+    """
+    Evaluate an Hermite series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    hermval2d, hermgrid2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermval
+    >>> coef = [1,2,3]
+    >>> hermval(1, coef)
+    11.0
+    >>> hermval([[1,2],[3,4]], coef)
+    array([[  11.,   51.],
+           [ 115.,  203.]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    x2 = x*2
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - c1*(2*(nd - 1))
+            c1 = tmp + c1*x2
+    return c0 + c1*x2
+
+
+def hermval2d(x, y, c):
+    """
+    Evaluate a 2-D Hermite series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermgrid2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = hermval(x, c)
+    c = hermval(y, c, tensor=False)
+    return c
+
+
+def hermgrid2d(x, y, c):
+    """
+    Evaluate a 2-D Hermite series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermval3d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermval(x, c)
+    c = hermval(y, c)
+    return c
+
+
+def hermval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermgrid2d, hermgrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = hermval(x, c)
+    c = hermval(y, c, tensor=False)
+    c = hermval(z, c, tensor=False)
+    return c
+
+
+def hermgrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermval, hermval2d, hermgrid2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermval(x, c)
+    c = hermval(y, c)
+    c = hermval(z, c)
+    return c
+
+
+def hermvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = H_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Hermite polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and
+    ``hermval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Hermite series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Hermite polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermvander
+    >>> x = np.array([-1, 0, 1])
+    >>> hermvander(x, 3)
+    array([[ 1., -2.,  2.,  4.],
+           [ 1.,  0., -2., -0.],
+           [ 1.,  2.,  2., -4.]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        x2 = x*2
+        v[1] = x2
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x2 - v[i-2]*(2*(i - 1)))
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def hermvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = H_i(x) * H_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Hermite polynomials.
+
+    If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``hermval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Hermite
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    hermvander, hermvander3d. hermval2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = hermvander(x, degx)
+    vy = hermvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def hermvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = H_i(x)*H_j(y)*H_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Hermite polynomials.
+
+    If ``V = hermvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``hermval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Hermite
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermvander, hermvander3d. hermval2d, hermval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = hermvander(x, degx)
+    vy = hermvander(y, degy)
+    vz = hermvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def hermfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Hermite series to data.
+
+    Return the coefficients of a Hermite series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Hermite coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, lagfit, polyfit, hermefit
+    hermval : Evaluates a Hermite series.
+    hermvander : Vandermonde matrix of Hermite series.
+    hermweight : Hermite weight function
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Hermite series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Hermite series are probably most useful when the data can be
+    approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Hermite
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `hermweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermfit, hermval
+    >>> x = np.linspace(-10, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = hermval(x, [1, 2, 3]) + err
+    >>> hermfit(x, y, 2)
+    array([ 0.97902637,  1.99849131,  3.00006   ])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = hermvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = hermvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def hermcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an Hermite basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-.5*c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.hstack((1., 1./np.sqrt(2.*np.arange(n - 1, 0, -1))))
+    scl = np.multiply.accumulate(scl)[::-1]
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.sqrt(.5*np.arange(1, n))
+    bot[...] = top
+    mat[:, -1] -= scl*c[:-1]/(2.0*c[-1])
+    return mat
+
+
+def hermroots(c):
+    """
+    Compute the roots of a Hermite series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * H_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, chebroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Hermite series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite import hermroots, hermfromroots
+    >>> coef = hermfromroots([-1, 0, 1])
+    >>> coef
+    array([ 0.   ,  0.25 ,  0.   ,  0.125])
+    >>> hermroots(coef)
+    array([ -1.00000000e+00,  -1.38777878e-17,   1.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-.5*c[0]/c[1]])
+
+    m = hermcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def _normed_hermite_n(x, n):
+    """
+    Evaluate a normalized Hermite polynomial.
+
+    Compute the value of the normalized Hermite polynomial of degree ``n``
+    at the points ``x``.
+
+
+    Parameters
+    ----------
+    x : ndarray of double.
+        Points at which to evaluate the function
+    n : int
+        Degree of the normalized Hermite function to be evaluated.
+
+    Returns
+    -------
+    values : ndarray
+        The shape of the return value is described above.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    This function is needed for finding the Gauss points and integration
+    weights for high degrees. The values of the standard Hermite functions
+    overflow when n >= 207.
+
+    """
+    if n == 0:
+        return np.ones(x.shape)/np.sqrt(np.sqrt(np.pi))
+
+    c0 = 0.
+    c1 = 1./np.sqrt(np.sqrt(np.pi))
+    nd = float(n)
+    for i in range(n - 1):
+        tmp = c0
+        c0 = -c1*np.sqrt((nd - 1.)/nd)
+        c1 = tmp + c1*x*np.sqrt(2./nd)
+        nd = nd - 1.0
+    return c0 + c1*x*np.sqrt(2)
+
+
+def hermgauss(deg):
+    """
+    Gauss-Hermite quadrature.
+
+    Computes the sample points and weights for Gauss-Hermite quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-\inf, \inf]`
+    with the weight function :math:`f(x) = \exp(-x^2)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (H'_n(x_k) * H_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`H_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1], dtype=np.float64)
+    m = hermcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = _normed_hermite_n(x, ideg)
+    df = _normed_hermite_n(x, ideg - 1) * np.sqrt(2*ideg)
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = _normed_hermite_n(x, ideg - 1)
+    fm /= np.abs(fm).max()
+    w = 1/(fm * fm)
+
+    # for Hermite we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= np.sqrt(np.pi) / w.sum()
+
+    return x, w
+
+
+def hermweight(x):
+    """
+    Weight function of the Hermite polynomials.
+
+    The weight function is :math:`\exp(-x^2)` and the interval of
+    integration is :math:`[-\inf, \inf]`. the Hermite polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-x**2)
+    return w
+
+
+#
+# Hermite series class
+#
+
+class Hermite(ABCPolyBase):
+    """An Hermite series class.
+
+    The Hermite class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Hermite coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*H_0(x) + 2*H_1(X) + 3*H_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(hermadd)
+    _sub = staticmethod(hermsub)
+    _mul = staticmethod(hermmul)
+    _div = staticmethod(hermdiv)
+    _pow = staticmethod(hermpow)
+    _val = staticmethod(hermval)
+    _int = staticmethod(hermint)
+    _der = staticmethod(hermder)
+    _fit = staticmethod(hermfit)
+    _line = staticmethod(hermline)
+    _roots = staticmethod(hermroots)
+    _fromroots = staticmethod(hermfromroots)
+
+    # Virtual properties
+    nickname = 'herm'
+    domain = np.array(hermdomain)
+    window = np.array(hermdomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
new file mode 100644
index 0000000000..08e83899aa
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
@@ -0,0 +1,1851 @@
+"""
+Objects for dealing with Hermite_e series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Hermite_e series, including a `HermiteE` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `hermedomain` -- Hermite_e series default domain, [-1,1].
+- `hermezero` -- Hermite_e series that evaluates identically to 0.
+- `hermeone` -- Hermite_e series that evaluates identically to 1.
+- `hermex` -- Hermite_e series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `hermemulx` -- multiply a Hermite_e series in ``P_i(x)`` by ``x``.
+- `hermeadd` -- add two Hermite_e series.
+- `hermesub` -- subtract one Hermite_e series from another.
+- `hermemul` -- multiply two Hermite_e series.
+- `hermediv` -- divide one Hermite_e series by another.
+- `hermeval` -- evaluate a Hermite_e series at given points.
+- `hermeval2d` -- evaluate a 2D Hermite_e series at given points.
+- `hermeval3d` -- evaluate a 3D Hermite_e series at given points.
+- `hermegrid2d` -- evaluate a 2D Hermite_e series on a Cartesian product.
+- `hermegrid3d` -- evaluate a 3D Hermite_e series on a Cartesian product.
+
+Calculus
+--------
+- `hermeder` -- differentiate a Hermite_e series.
+- `hermeint` -- integrate a Hermite_e series.
+
+Misc Functions
+--------------
+- `hermefromroots` -- create a Hermite_e series with specified roots.
+- `hermeroots` -- find the roots of a Hermite_e series.
+- `hermevander` -- Vandermonde-like matrix for Hermite_e polynomials.
+- `hermevander2d` -- Vandermonde-like matrix for 2D power series.
+- `hermevander3d` -- Vandermonde-like matrix for 3D power series.
+- `hermegauss` -- Gauss-Hermite_e quadrature, points and weights.
+- `hermeweight` -- Hermite_e weight function.
+- `hermecompanion` -- symmetrized companion matrix in Hermite_e form.
+- `hermefit` -- least-squares fit returning a Hermite_e series.
+- `hermetrim` -- trim leading coefficients from a Hermite_e series.
+- `hermeline` -- Hermite_e series of given straight line.
+- `herme2poly` -- convert a Hermite_e series to a polynomial.
+- `poly2herme` -- convert a polynomial to a Hermite_e series.
+
+Classes
+-------
+- `HermiteE` -- A Hermite_e series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'hermezero', 'hermeone', 'hermex', 'hermedomain', 'hermeline',
+    'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv',
+    'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly',
+    'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim',
+    'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d',
+    'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion',
+    'hermegauss', 'hermeweight']
+
+hermetrim = pu.trimcoef
+
+
+def poly2herme(pol):
+    """
+    poly2herme(pol)
+
+    Convert a polynomial to a Hermite series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Hermite series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Hermite
+        series.
+
+    See Also
+    --------
+    herme2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import poly2herme
+    >>> poly2herme(np.arange(4))
+    array([  2.,  10.,   2.,   3.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = hermeadd(hermemulx(res), pol[i])
+    return res
+
+
+def herme2poly(c):
+    """
+    Convert a Hermite series to a polynomial.
+
+    Convert an array representing the coefficients of a Hermite series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Hermite series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2herme
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import herme2poly
+    >>> herme2poly([  2.,  10.,   2.,   3.])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    if n == 2:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], c1*(i - 1))
+            c1 = polyadd(tmp, polymulx(c1))
+        return polyadd(c0, polymulx(c1))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Hermite
+hermedomain = np.array([-1, 1])
+
+# Hermite coefficients representing zero.
+hermezero = np.array([0])
+
+# Hermite coefficients representing one.
+hermeone = np.array([1])
+
+# Hermite coefficients representing the identity x.
+hermex = np.array([0, 1])
+
+
+def hermeline(off, scl):
+    """
+    Hermite series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Hermite series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeline
+    >>> from numpy.polynomial.hermite_e import hermeline, hermeval
+    >>> hermeval(0,hermeline(3, 2))
+    3.0
+    >>> hermeval(1,hermeline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def hermefromroots(roots):
+    """
+    Generate a HermiteE series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in HermiteE form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * He_1(x) + ... +  c_n * He_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in HermiteE form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, lagfromroots, hermfromroots,
+    chebfromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermefromroots, hermeval
+    >>> coef = hermefromroots((-1, 0, 1))
+    >>> hermeval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = hermefromroots((-1j, 1j))
+    >>> hermeval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [hermeline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [hermemul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = hermemul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def hermeadd(c1, c2):
+    """
+    Add one Hermite series to another.
+
+    Returns the sum of two Hermite series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Hermite series of their sum.
+
+    See Also
+    --------
+    hermesub, hermemul, hermediv, hermepow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Hermite series
+    is a Hermite series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeadd
+    >>> hermeadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermesub(c1, c2):
+    """
+    Subtract one Hermite series from another.
+
+    Returns the difference of two Hermite series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their difference.
+
+    See Also
+    --------
+    hermeadd, hermemul, hermediv, hermepow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Hermite
+    series is a Hermite series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermesub
+    >>> hermesub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def hermemulx(c):
+    """Multiply a Hermite series by x.
+
+    Multiply the Hermite series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Hermite
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (P_{i + 1}(x) + iP_{i - 1}(x)))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermemulx
+    >>> hermemulx([1, 2, 3])
+    array([ 2.,  7.,  2.,  3.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    for i in range(1, len(c)):
+        prd[i + 1] = c[i]
+        prd[i - 1] += c[i]*i
+    return prd
+
+
+def hermemul(c1, c2):
+    """
+    Multiply one Hermite series by another.
+
+    Returns the product of two Hermite series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Hermite series coefficients representing their product.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermediv, hermepow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Hermite polynomial basis set.  Thus, to express
+    the product as a Hermite series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermemul
+    >>> hermemul([1, 2, 3], [0, 1, 2])
+    array([ 14.,  15.,  28.,   7.,   6.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = hermesub(c[-i]*xs, c1*(nd - 1))
+            c1 = hermeadd(tmp, hermemulx(c1))
+    return hermeadd(c0, hermemulx(c1))
+
+
+def hermediv(c1, c2):
+    """
+    Divide one Hermite series by another.
+
+    Returns the quotient-with-remainder of two Hermite series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Hermite series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Hermite series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermemul, hermepow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Hermite series by another
+    results in quotient and remainder terms that are not in the Hermite
+    polynomial basis set.  Thus, to express these results as a Hermite
+    series, it is necessary to "reproject" the results onto the Hermite
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermediv
+    >>> hermediv([ 14.,  15.,  28.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> hermediv([ 15.,  17.,  28.,   7.,   6.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  2.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = hermemul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def hermepow(c, pow, maxpower=16):
+    """Raise a Hermite series to a power.
+
+    Returns the Hermite series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Hermite series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Hermite series of power.
+
+    See Also
+    --------
+    hermeadd, hermesub, hermemul, hermediv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermepow
+    >>> hermepow([1, 2, 3], 2)
+    array([ 23.,  28.,  46.,  12.,   9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = hermemul(prd, c)
+        return prd
+
+
+def hermeder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Hermite_e series.
+
+    Returns the series coefficients `c` differentiated `m` times along
+    `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*He_0 + 2*He_1 + 3*He_2``
+    while [[1,2],[1,2]] represents ``1*He_0(x)*He_0(y) + 1*He_1(x)*He_0(y)
+    + 2*He_0(x)*He_1(y) + 2*He_1(x)*He_1(y)`` if axis=0 is ``x`` and axis=1
+    is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite_e series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Hermite series of the derivative.
+
+    See Also
+    --------
+    hermeint
+
+    Notes
+    -----
+    In general, the result of differentiating a Hermite series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeder
+    >>> hermeder([ 1.,  1.,  1.,  1.])
+    array([ 1.,  2.,  3.])
+    >>> hermeder([-0.25,  1.,  1./2.,  1./3.,  1./4 ], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        return c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 0, -1):
+                der[j - 1] = j*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermeint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Hermite_e series.
+
+    Returns the Hermite_e series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
+    represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
+    2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Hermite_e series coefficients. If c is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Hermite_e series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    hermeder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeint
+    >>> hermeint([1, 2, 3]) # integrate once, value 0 at 0.
+    array([ 1.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], m=2) # integrate twice, value & deriv 0 at 0
+    array([-0.25      ,  1.        ,  0.5       ,  0.33333333,  0.25      ])
+    >>> hermeint([1, 2, 3], k=1) # integrate once, value 1 at 0.
+    array([ 2.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], lbnd=-1) # integrate once, value 0 at -1
+    array([-1.,  1.,  1.,  1.])
+    >>> hermeint([1, 2, 3], m=2, k=[1, 2], lbnd=-1)
+    array([ 1.83333333,  0.        ,  0.5       ,  0.33333333,  0.25      ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(j + 1)
+            tmp[0] += k[i] - hermeval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def hermeval(x, c, tensor=True):
+    """
+    Evaluate an HermiteE series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * He_0(x) + c_1 * He_1(x) + ... + c_n * He_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    hermeval2d, hermegrid2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeval
+    >>> coef = [1,2,3]
+    >>> hermeval(1, coef)
+    3.0
+    >>> hermeval([[1,2],[3,4]], coef)
+    array([[  3.,  14.],
+           [ 31.,  54.]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - c1*(nd - 1)
+            c1 = tmp + c1*x
+    return c0 + c1*x
+
+
+def hermeval2d(x, y, c):
+    """
+    Evaluate a 2-D HermiteE series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * He_i(x) * He_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermegrid2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = hermeval(x, c)
+    c = hermeval(y, c, tensor=False)
+    return c
+
+
+def hermegrid2d(x, y, c):
+    """
+    Evaluate a 2-D HermiteE series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermeval3d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermeval(x, c)
+    c = hermeval(y, c)
+    return c
+
+
+def hermeval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Hermite_e series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * He_i(x) * He_j(y) * He_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermegrid2d, hermegrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = hermeval(x, c)
+    c = hermeval(y, c, tensor=False)
+    c = hermeval(z, c, tensor=False)
+    return c
+
+
+def hermegrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * He_i(a) * He_j(b) * He_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    hermeval, hermeval2d, hermegrid2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = hermeval(x, c)
+    c = hermeval(y, c)
+    c = hermeval(z, c)
+    return c
+
+
+def hermevander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = He_i(x),
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the HermiteE polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = hermevander(x, n)``, then ``np.dot(V, c)`` and
+    ``hermeval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of HermiteE series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding HermiteE polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermevander
+    >>> x = np.array([-1, 0, 1])
+    >>> hermevander(x, 3)
+    array([[ 1., -1.,  0.,  2.],
+           [ 1.,  0., -1., -0.],
+           [ 1.,  1.,  0., -2.]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x - v[i-2]*(i - 1))
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def hermevander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = He_i(x) * He_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the HermiteE polynomials.
+
+    If ``V = hermevander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``hermeval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D HermiteE
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    hermevander, hermevander3d. hermeval2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = hermevander(x, degx)
+    vy = hermevander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def hermevander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then Hehe pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = He_i(x)*He_j(y)*He_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the HermiteE polynomials.
+
+    If ``V = hermevander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``hermeval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D HermiteE
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    hermevander, hermevander3d. hermeval2d, hermeval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = hermevander(x, degx)
+    vy = hermevander(y, degy)
+    vz = hermevander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def hermefit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Hermite series to data.
+
+    Return the coefficients of a HermiteE series of degree `deg` that is
+    the least squares fit to the data values `y` given at points `x`. If
+    `y` is 1-D the returned coefficients will also be 1-D. If `y` is 2-D
+    multiple fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Hermite coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, polyfit, hermfit, polyfit
+    hermeval : Evaluates a Hermite series.
+    hermevander : pseudo Vandermonde matrix of Hermite series.
+    hermeweight : HermiteE weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the HermiteE series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the pseudo Vandermonde matrix of `x`, the elements of `c`
+    are the coefficients to be solved for, and the elements of `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using HermiteE series are probably most useful when the data can
+    be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the HermiteE
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `hermeweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermefik, hermeval
+    >>> x = np.linspace(-10, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = hermeval(x, [1, 2, 3]) + err
+    >>> hermefit(x, y, 2)
+    array([ 1.01690445,  1.99951418,  2.99948696])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = hermevander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = hermevander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def hermecompanion(c):
+    """
+    Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an HermiteE basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of HermiteE series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = np.hstack((1., 1./np.sqrt(np.arange(n - 1, 0, -1))))
+    scl = np.multiply.accumulate(scl)[::-1]
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.sqrt(np.arange(1, n))
+    bot[...] = top
+    mat[:, -1] -= scl*c[:-1]/c[-1]
+    return mat
+
+
+def hermeroots(c):
+    """
+    Compute the roots of a HermiteE series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * He_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, lagroots, hermroots, chebroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The HermiteE series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.hermite_e import hermeroots, hermefromroots
+    >>> coef = hermefromroots([-1, 0, 1])
+    >>> coef
+    array([ 0.,  2.,  0.,  1.])
+    >>> hermeroots(coef)
+    array([-1.,  0.,  1.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = hermecompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def _normed_hermite_e_n(x, n):
+    """
+    Evaluate a normalized HermiteE polynomial.
+
+    Compute the value of the normalized HermiteE polynomial of degree ``n``
+    at the points ``x``.
+
+
+    Parameters
+    ----------
+    x : ndarray of double.
+        Points at which to evaluate the function
+    n : int
+        Degree of the normalized HermiteE function to be evaluated.
+
+    Returns
+    -------
+    values : ndarray
+        The shape of the return value is described above.
+
+    Notes
+    -----
+    .. versionadded:: 1.10.0
+
+    This function is needed for finding the Gauss points and integration
+    weights for high degrees. The values of the standard HermiteE functions
+    overflow when n >= 207.
+
+    """
+    if n == 0:
+        return np.ones(x.shape)/np.sqrt(np.sqrt(2*np.pi))
+
+    c0 = 0.
+    c1 = 1./np.sqrt(np.sqrt(2*np.pi))
+    nd = float(n)
+    for i in range(n - 1):
+        tmp = c0
+        c0 = -c1*np.sqrt((nd - 1.)/nd)
+        c1 = tmp + c1*x*np.sqrt(1./nd)
+        nd = nd - 1.0
+    return c0 + c1*x
+
+
+def hermegauss(deg):
+    """
+    Gauss-HermiteE quadrature.
+
+    Computes the sample points and weights for Gauss-HermiteE quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-\inf, \inf]`
+    with the weight function :math:`f(x) = \exp(-x^2/2)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (He'_n(x_k) * He_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`He_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = hermecompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = _normed_hermite_e_n(x, ideg)
+    df = _normed_hermite_e_n(x, ideg - 1) * np.sqrt(ideg)
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = _normed_hermite_e_n(x, ideg - 1)
+    fm /= np.abs(fm).max()
+    w = 1/(fm * fm)
+
+    # for Hermite_e we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= np.sqrt(2*np.pi) / w.sum()
+
+    return x, w
+
+
+def hermeweight(x):
+    """Weight function of the Hermite_e polynomials.
+
+    The weight function is :math:`\exp(-x^2/2)` and the interval of
+    integration is :math:`[-\inf, \inf]`. the HermiteE polynomials are
+    orthogonal, but not normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-.5*x**2)
+    return w
+
+
+#
+# HermiteE series class
+#
+
+class HermiteE(ABCPolyBase):
+    """An HermiteE series class.
+
+    The HermiteE class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        HermiteE coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*He_0(x) + 2*He_1(X) + 3*He_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(hermeadd)
+    _sub = staticmethod(hermesub)
+    _mul = staticmethod(hermemul)
+    _div = staticmethod(hermediv)
+    _pow = staticmethod(hermepow)
+    _val = staticmethod(hermeval)
+    _int = staticmethod(hermeint)
+    _der = staticmethod(hermeder)
+    _fit = staticmethod(hermefit)
+    _line = staticmethod(hermeline)
+    _roots = staticmethod(hermeroots)
+    _fromroots = staticmethod(hermefromroots)
+
+    # Virtual properties
+    nickname = 'herme'
+    domain = np.array(hermedomain)
+    window = np.array(hermedomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
new file mode 100644
index 0000000000..d459551ae8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
@@ -0,0 +1,1804 @@
+"""
+Objects for dealing with Laguerre series.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Laguerre series, including a `Laguerre` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `lagdomain` -- Laguerre series default domain, [-1,1].
+- `lagzero` -- Laguerre series that evaluates identically to 0.
+- `lagone` -- Laguerre series that evaluates identically to 1.
+- `lagx` -- Laguerre series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+- `lagmulx` -- multiply a Laguerre series in ``P_i(x)`` by ``x``.
+- `lagadd` -- add two Laguerre series.
+- `lagsub` -- subtract one Laguerre series from another.
+- `lagmul` -- multiply two Laguerre series.
+- `lagdiv` -- divide one Laguerre series by another.
+- `lagval` -- evaluate a Laguerre series at given points.
+- `lagval2d` -- evaluate a 2D Laguerre series at given points.
+- `lagval3d` -- evaluate a 3D Laguerre series at given points.
+- `laggrid2d` -- evaluate a 2D Laguerre series on a Cartesian product.
+- `laggrid3d` -- evaluate a 3D Laguerre series on a Cartesian product.
+
+Calculus
+--------
+- `lagder` -- differentiate a Laguerre series.
+- `lagint` -- integrate a Laguerre series.
+
+Misc Functions
+--------------
+- `lagfromroots` -- create a Laguerre series with specified roots.
+- `lagroots` -- find the roots of a Laguerre series.
+- `lagvander` -- Vandermonde-like matrix for Laguerre polynomials.
+- `lagvander2d` -- Vandermonde-like matrix for 2D power series.
+- `lagvander3d` -- Vandermonde-like matrix for 3D power series.
+- `laggauss` -- Gauss-Laguerre quadrature, points and weights.
+- `lagweight` -- Laguerre weight function.
+- `lagcompanion` -- symmetrized companion matrix in Laguerre form.
+- `lagfit` -- least-squares fit returning a Laguerre series.
+- `lagtrim` -- trim leading coefficients from a Laguerre series.
+- `lagline` -- Laguerre series of given straight line.
+- `lag2poly` -- convert a Laguerre series to a polynomial.
+- `poly2lag` -- convert a polynomial to a Laguerre series.
+
+Classes
+-------
+- `Laguerre` -- A Laguerre series class.
+
+See also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd',
+    'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder',
+    'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander',
+    'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d',
+    'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion',
+    'laggauss', 'lagweight']
+
+lagtrim = pu.trimcoef
+
+
+def poly2lag(pol):
+    """
+    poly2lag(pol)
+
+    Convert a polynomial to a Laguerre series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Laguerre series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Laguerre
+        series.
+
+    See Also
+    --------
+    lag2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import poly2lag
+    >>> poly2lag(np.arange(4))
+    array([ 23., -63.,  58., -18.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = lagadd(lagmulx(res), pol[i])
+    return res
+
+
+def lag2poly(c):
+    """
+    Convert a Laguerre series to a polynomial.
+
+    Convert an array representing the coefficients of a Laguerre series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Laguerre series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2lag
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lag2poly
+    >>> lag2poly([ 23., -63.,  58., -18.])
+    array([ 0.,  1.,  2.,  3.])
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n == 1:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], (c1*(i - 1))/i)
+            c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i)
+        return polyadd(c0, polysub(c1, polymulx(c1)))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Laguerre
+lagdomain = np.array([0, 1])
+
+# Laguerre coefficients representing zero.
+lagzero = np.array([0])
+
+# Laguerre coefficients representing one.
+lagone = np.array([1])
+
+# Laguerre coefficients representing the identity x.
+lagx = np.array([1, -1])
+
+
+def lagline(off, scl):
+    """
+    Laguerre series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Laguerre series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagline, lagval
+    >>> lagval(0,lagline(3, 2))
+    3.0
+    >>> lagval(1,lagline(3, 2))
+    5.0
+
+    """
+    if scl != 0:
+        return np.array([off + scl, -scl])
+    else:
+        return np.array([off])
+
+
+def lagfromroots(roots):
+    """
+    Generate a Laguerre series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Laguerre form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * L_1(x) + ... +  c_n * L_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Laguerre form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, legfromroots, chebfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagfromroots, lagval
+    >>> coef = lagfromroots((-1, 0, 1))
+    >>> lagval((-1, 0, 1), coef)
+    array([ 0.,  0.,  0.])
+    >>> coef = lagfromroots((-1j, 1j))
+    >>> lagval((-1j, 1j), coef)
+    array([ 0.+0.j,  0.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [lagline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [lagmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = lagmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def lagadd(c1, c2):
+    """
+    Add one Laguerre series to another.
+
+    Returns the sum of two Laguerre series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Laguerre series of their sum.
+
+    See Also
+    --------
+    lagsub, lagmul, lagdiv, lagpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Laguerre series
+    is a Laguerre series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagadd
+    >>> lagadd([1, 2, 3], [1, 2, 3, 4])
+    array([ 2.,  4.,  6.,  4.])
+
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def lagsub(c1, c2):
+    """
+    Subtract one Laguerre series from another.
+
+    Returns the difference of two Laguerre series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Laguerre series coefficients representing their difference.
+
+    See Also
+    --------
+    lagadd, lagmul, lagdiv, lagpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Laguerre
+    series is a Laguerre series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagsub
+    >>> lagsub([1, 2, 3, 4], [1, 2, 3])
+    array([ 0.,  0.,  0.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def lagmulx(c):
+    """Multiply a Laguerre series by x.
+
+    Multiply the Laguerre series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Laguerre
+    polynomials in the form
+
+    .. math::
+
+    xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x))
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagmulx
+    >>> lagmulx([1, 2, 3])
+    array([ -1.,  -1.,  11.,  -9.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]
+    prd[1] = -c[0]
+    for i in range(1, len(c)):
+        prd[i + 1] = -c[i]*(i + 1)
+        prd[i] += c[i]*(2*i + 1)
+        prd[i - 1] -= c[i]*i
+    return prd
+
+
+def lagmul(c1, c2):
+    """
+    Multiply one Laguerre series by another.
+
+    Returns the product of two Laguerre series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Laguerre series coefficients representing their product.
+
+    See Also
+    --------
+    lagadd, lagsub, lagdiv, lagpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Laguerre polynomial basis set.  Thus, to express
+    the product as a Laguerre series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagmul
+    >>> lagmul([1, 2, 3], [0, 1, 2])
+    array([  8., -13.,  38., -51.,  36.])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd)
+            c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd)
+    return lagadd(c0, lagsub(c1, lagmulx(c1)))
+
+
+def lagdiv(c1, c2):
+    """
+    Divide one Laguerre series by another.
+
+    Returns the quotient-with-remainder of two Laguerre series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Laguerre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of Laguerre series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    lagadd, lagsub, lagmul, lagpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Laguerre series by another
+    results in quotient and remainder terms that are not in the Laguerre
+    polynomial basis set.  Thus, to express these results as a Laguerre
+    series, it is necessary to "reproject" the results onto the Laguerre
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagdiv
+    >>> lagdiv([  8., -13.,  38., -51.,  36.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 0.]))
+    >>> lagdiv([  9., -12.,  38., -51.,  36.], [0, 1, 2])
+    (array([ 1.,  2.,  3.]), array([ 1.,  1.]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = lagmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def lagpow(c, pow, maxpower=16):
+    """Raise a Laguerre series to a power.
+
+    Returns the Laguerre series `c` raised to the power `pow`. The
+    argument `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Laguerre series of power.
+
+    See Also
+    --------
+    lagadd, lagsub, lagmul, lagdiv
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagpow
+    >>> lagpow([1, 2, 3], 2)
+    array([ 14., -16.,  56., -72.,  54.])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = lagmul(prd, c)
+        return prd
+
+
+def lagder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Laguerre series.
+
+    Returns the Laguerre series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
+    while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
+    2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Laguerre series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Laguerre series of the derivative.
+
+    See Also
+    --------
+    lagint
+
+    Notes
+    -----
+    In general, the result of differentiating a Laguerre series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagder
+    >>> lagder([ 1.,  1.,  1., -3.])
+    array([ 1.,  2.,  3.])
+    >>> lagder([ 1.,  0.,  0., -4.,  3.], m=2)
+    array([ 1.,  2.,  3.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 1, -1):
+                der[j - 1] = -c[j]
+                c[j - 1] += c[j]
+            der[0] = -c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def lagint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Laguerre series.
+
+    Returns the Laguerre series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
+    represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
+    2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Laguerre series coefficients. If `c` is multidimensional
+        the different axis correspond to different variables with the
+        degree in each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Laguerre series coefficients of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    lagder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagint
+    >>> lagint([1,2,3])
+    array([ 1.,  1.,  1., -3.])
+    >>> lagint([1,2,3], m=2)
+    array([ 1.,  0.,  0., -4.,  3.])
+    >>> lagint([1,2,3], k=1)
+    array([ 2.,  1.,  1., -3.])
+    >>> lagint([1,2,3], lbnd=-1)
+    array([ 11.5,   1. ,   1. ,  -3. ])
+    >>> lagint([1,2], m=2, k=[1,2], lbnd=-1)
+    array([ 11.16666667,  -5.        ,  -3.        ,   2.        ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]
+            tmp[1] = -c[0]
+            for j in range(1, n):
+                tmp[j] += c[j]
+                tmp[j + 1] = -c[j]
+            tmp[0] += k[i] - lagval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def lagval(x, c, tensor=True):
+    """
+    Evaluate a Laguerre series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    lagval2d, laggrid2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagval
+    >>> coef = [1,2,3]
+    >>> lagval(1, coef)
+    -0.5
+    >>> lagval([[1,2],[3,4]], coef)
+    array([[-0.5, -4. ],
+           [-4.5, -2. ]])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - (c1*(nd - 1))/nd
+            c1 = tmp + (c1*((2*nd - 1) - x))/nd
+    return c0 + c1*(1 - x)
+
+
+def lagval2d(x, y, c):
+    """
+    Evaluate a 2-D Laguerre series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    lagval, laggrid2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = lagval(x, c)
+    c = lagval(y, c, tensor=False)
+    return c
+
+
+def laggrid2d(x, y, c):
+    """
+    Evaluate a 2-D Laguerre series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    lagval, lagval2d, lagval3d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = lagval(x, c)
+    c = lagval(y, c)
+    return c
+
+
+def lagval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Laguerre series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimension polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    lagval, lagval2d, laggrid2d, laggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = lagval(x, c)
+    c = lagval(y, c, tensor=False)
+    c = lagval(z, c, tensor=False)
+    return c
+
+
+def laggrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Laguerre series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    lagval, lagval2d, laggrid2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = lagval(x, c)
+    c = lagval(y, c)
+    c = lagval(z, c)
+    return c
+
+
+def lagvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = L_i(x)
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Laguerre polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and
+    ``lagval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Laguerre series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Laguerre polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagvander
+    >>> x = np.array([0, 1, 2])
+    >>> lagvander(x, 3)
+    array([[ 1.        ,  1.        ,  1.        ,  1.        ],
+           [ 1.        ,  0.        , -0.5       , -0.66666667],
+           [ 1.        , -1.        , -1.        , -0.33333333]])
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = 1 - x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def lagvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = L_i(x) * L_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Laguerre polynomials.
+
+    If ``V = lagvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``lagval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Laguerre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    lagvander, lagvander3d. lagval2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = lagvander(x, degx)
+    vy = lagvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def lagvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Laguerre polynomials.
+
+    If ``V = lagvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``lagval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Laguerre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    lagvander, lagvander3d. lagval2d, lagval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = lagvander(x, degx)
+    vy = lagvander(y, degy)
+    vz = lagvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def lagfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Laguerre series to data.
+
+    Return the coefficients of a Laguerre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Laguerre coefficients ordered from low to high. If `y` was 2-D,
+        the coefficients for the data in column k  of `y` are in column
+        `k`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, polyfit, hermfit, hermefit
+    lagval : Evaluates a Laguerre series.
+    lagvander : pseudo Vandermonde matrix of Laguerre series.
+    lagweight : Laguerre weight function.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Laguerre series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Laguerre series are probably most useful when the data can
+    be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Laguerre
+    weight. In that case the weight ``sqrt(w(x[i])`` should be used
+    together with data values ``y[i]/sqrt(w(x[i])``. The weight function is
+    available as `lagweight`.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagfit, lagval
+    >>> x = np.linspace(0, 10)
+    >>> err = np.random.randn(len(x))/10
+    >>> y = lagval(x, [1, 2, 3]) + err
+    >>> lagfit(x, y, 2)
+    array([ 0.96971004,  2.00193749,  3.00288744])
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = lagvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = lagvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def lagcompanion(c):
+    """
+    Return the companion matrix of c.
+
+    The usual companion matrix of the Laguerre polynomials is already
+    symmetric when `c` is a basis Laguerre polynomial, so no scaling is
+    applied.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Laguerre series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[1 + c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    top = mat.reshape(-1)[1::n+1]
+    mid = mat.reshape(-1)[0::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = -np.arange(1, n)
+    mid[...] = 2.*np.arange(n) + 1.
+    bot[...] = top
+    mat[:, -1] += (c[:-1]/c[-1])*n
+    return mat
+
+
+def lagroots(c):
+    """
+    Compute the roots of a Laguerre series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * L_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, legroots, chebroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    The Laguerre series basis polynomials aren't powers of `x` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.laguerre import lagroots, lagfromroots
+    >>> coef = lagfromroots([0, 1, 2])
+    >>> coef
+    array([  2.,  -8.,  12.,  -6.])
+    >>> lagroots(coef)
+    array([ -4.44089210e-16,   1.00000000e+00,   2.00000000e+00])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) <= 1:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([1 + c[0]/c[1]])
+
+    m = lagcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def laggauss(deg):
+    """
+    Gauss-Laguerre quadrature.
+
+    Computes the sample points and weights for Gauss-Laguerre quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[0, \inf]`
+    with the weight function :math:`f(x) = \exp(-x)`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100 higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`L_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = lagcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = lagval(x, c)
+    df = lagval(x, lagder(c))
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = lagval(x, c[1:])
+    fm /= np.abs(fm).max()
+    df /= np.abs(df).max()
+    w = 1/(fm * df)
+
+    # scale w to get the right value, 1 in this case
+    w /= w.sum()
+
+    return x, w
+
+
+def lagweight(x):
+    """Weight function of the Laguerre polynomials.
+
+    The weight function is :math:`exp(-x)` and the interval of integration
+    is :math:`[0, \inf]`. The Laguerre polynomials are orthogonal, but not
+    normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = np.exp(-x)
+    return w
+
+#
+# Laguerre series class
+#
+
+class Laguerre(ABCPolyBase):
+    """A Laguerre series class.
+
+    The Laguerre class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Laguerre coefficients in order of increasing degree, i.e,
+        ``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [0, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [0, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(lagadd)
+    _sub = staticmethod(lagsub)
+    _mul = staticmethod(lagmul)
+    _div = staticmethod(lagdiv)
+    _pow = staticmethod(lagpow)
+    _val = staticmethod(lagval)
+    _int = staticmethod(lagint)
+    _der = staticmethod(lagder)
+    _fit = staticmethod(lagfit)
+    _line = staticmethod(lagline)
+    _roots = staticmethod(lagroots)
+    _fromroots = staticmethod(lagfromroots)
+
+    # Virtual properties
+    nickname = 'lag'
+    domain = np.array(lagdomain)
+    window = np.array(lagdomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.py
new file mode 100644
index 0000000000..54e9895db9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.py
@@ -0,0 +1,1834 @@
+"""
+Legendre Series (:mod: `numpy.polynomial.legendre`)
+===================================================
+
+.. currentmodule:: numpy.polynomial.polynomial
+
+This module provides a number of objects (mostly functions) useful for
+dealing with Legendre series, including a `Legendre` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with such polynomials is in the
+docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   legdomain            Legendre series default domain, [-1,1].
+   legzero              Legendre series that evaluates identically to 0.
+   legone               Legendre series that evaluates identically to 1.
+   legx                 Legendre series for the identity map, ``f(x) = x``.
+
+Arithmetic
+----------
+
+.. autosummary::
+   :toctree: generated/
+
+   legmulx              multiply a Legendre series in P_i(x) by x.
+   legadd               add two Legendre series.
+   legsub               subtract one Legendre series from another.
+   legmul               multiply two Legendre series.
+   legdiv               divide one Legendre series by another.
+   legpow               raise a Legendre series to an positive integer power
+   legval               evaluate a Legendre series at given points.
+   legval2d             evaluate a 2D Legendre series at given points.
+   legval3d             evaluate a 3D Legendre series at given points.
+   leggrid2d            evaluate a 2D Legendre series on a Cartesian product.
+   leggrid3d            evaluate a 3D Legendre series on a Cartesian product.
+
+Calculus
+--------
+
+.. autosummary::
+   :toctree: generated/
+
+   legder               differentiate a Legendre series.
+   legint               integrate a Legendre series.
+
+Misc Functions
+--------------
+
+.. autosummary::
+   :toctree: generated/
+
+   legfromroots          create a Legendre series with specified roots.
+   legroots              find the roots of a Legendre series.
+   legvander             Vandermonde-like matrix for Legendre polynomials.
+   legvander2d           Vandermonde-like matrix for 2D power series.
+   legvander3d           Vandermonde-like matrix for 3D power series.
+   leggauss              Gauss-Legendre quadrature, points and weights.
+   legweight             Legendre weight function.
+   legcompanion          symmetrized companion matrix in Legendre form.
+   legfit                least-squares fit returning a Legendre series.
+   legtrim               trim leading coefficients from a Legendre series.
+   legline               Legendre series representing given straight line.
+   leg2poly              convert a Legendre series to a polynomial.
+   poly2leg              convert a polynomial to a Legendre series.
+
+Classes
+-------
+    Legendre            A Legendre series class.
+
+See also
+--------
+numpy.polynomial.polynomial
+numpy.polynomial.chebyshev
+numpy.polynomial.laguerre
+numpy.polynomial.hermite
+numpy.polynomial.hermite_e
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+__all__ = [
+    'legzero', 'legone', 'legx', 'legdomain', 'legline', 'legadd',
+    'legsub', 'legmulx', 'legmul', 'legdiv', 'legpow', 'legval', 'legder',
+    'legint', 'leg2poly', 'poly2leg', 'legfromroots', 'legvander',
+    'legfit', 'legtrim', 'legroots', 'Legendre', 'legval2d', 'legval3d',
+    'leggrid2d', 'leggrid3d', 'legvander2d', 'legvander3d', 'legcompanion',
+    'leggauss', 'legweight']
+
+legtrim = pu.trimcoef
+
+
+def poly2leg(pol):
+    """
+    Convert a polynomial to a Legendre series.
+
+    Convert an array representing the coefficients of a polynomial (relative
+    to the "standard" basis) ordered from lowest degree to highest, to an
+    array of the coefficients of the equivalent Legendre series, ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    pol : array_like
+        1-D array containing the polynomial coefficients
+
+    Returns
+    -------
+    c : ndarray
+        1-D array containing the coefficients of the equivalent Legendre
+        series.
+
+    See Also
+    --------
+    leg2poly
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> p = P.Polynomial(np.arange(4))
+    >>> p
+    Polynomial([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> c = P.Legendre(P.poly2leg(p.coef))
+    >>> c
+    Legendre([ 1.  ,  3.25,  1.  ,  0.75], [-1.,  1.])
+
+    """
+    [pol] = pu.as_series([pol])
+    deg = len(pol) - 1
+    res = 0
+    for i in range(deg, -1, -1):
+        res = legadd(legmulx(res), pol[i])
+    return res
+
+
+def leg2poly(c):
+    """
+    Convert a Legendre series to a polynomial.
+
+    Convert an array representing the coefficients of a Legendre series,
+    ordered from lowest degree to highest, to an array of the coefficients
+    of the equivalent polynomial (relative to the "standard" basis) ordered
+    from lowest to highest degree.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array containing the Legendre series coefficients, ordered
+        from lowest order term to highest.
+
+    Returns
+    -------
+    pol : ndarray
+        1-D array containing the coefficients of the equivalent polynomial
+        (relative to the "standard" basis) ordered from lowest order term
+        to highest.
+
+    See Also
+    --------
+    poly2leg
+
+    Notes
+    -----
+    The easy way to do conversions between polynomial basis sets
+    is to use the convert method of a class instance.
+
+    Examples
+    --------
+    >>> c = P.Legendre(range(4))
+    >>> c
+    Legendre([ 0.,  1.,  2.,  3.], [-1.,  1.])
+    >>> p = c.convert(kind=P.Polynomial)
+    >>> p
+    Polynomial([-1. , -3.5,  3. ,  7.5], [-1.,  1.])
+    >>> P.leg2poly(range(4))
+    array([-1. , -3.5,  3. ,  7.5])
+
+
+    """
+    from .polynomial import polyadd, polysub, polymulx
+
+    [c] = pu.as_series([c])
+    n = len(c)
+    if n < 3:
+        return c
+    else:
+        c0 = c[-2]
+        c1 = c[-1]
+        # i is the current degree of c1
+        for i in range(n - 1, 1, -1):
+            tmp = c0
+            c0 = polysub(c[i - 2], (c1*(i - 1))/i)
+            c1 = polyadd(tmp, (polymulx(c1)*(2*i - 1))/i)
+        return polyadd(c0, polymulx(c1))
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Legendre
+legdomain = np.array([-1, 1])
+
+# Legendre coefficients representing zero.
+legzero = np.array([0])
+
+# Legendre coefficients representing one.
+legone = np.array([1])
+
+# Legendre coefficients representing the identity x.
+legx = np.array([0, 1])
+
+
+def legline(off, scl):
+    """
+    Legendre series whose graph is a straight line.
+
+
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The specified line is given by ``off + scl*x``.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the Legendre series for
+        ``off + scl*x``.
+
+    See Also
+    --------
+    polyline, chebline
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as L
+    >>> L.legline(3,2)
+    array([3, 2])
+    >>> L.legval(-3, L.legline(3,2)) # should be -3
+    -3.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def legfromroots(roots):
+    """
+    Generate a Legendre series with given roots.
+
+    The function returns the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    in Legendre form, where the `r_n` are the roots specified in `roots`.
+    If a zero has multiplicity n, then it must appear in `roots` n times.
+    For instance, if 2 is a root of multiplicity three and 3 is a root of
+    multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
+    roots can appear in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * L_1(x) + ... +  c_n * L_n(x)
+
+    The coefficient of the last term is not generally 1 for monic
+    polynomials in Legendre form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of coefficients.  If all roots are real then `out` is a
+        real array, if some of the roots are complex, then `out` is complex
+        even if all the coefficients in the result are real (see Examples
+        below).
+
+    See Also
+    --------
+    polyfromroots, chebfromroots, lagfromroots, hermfromroots,
+    hermefromroots.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as L
+    >>> L.legfromroots((-1,0,1)) # x^3 - x relative to the standard basis
+    array([ 0. , -0.4,  0. ,  0.4])
+    >>> j = complex(0,1)
+    >>> L.legfromroots((-j,j)) # x^2 + 1 relative to the standard basis
+    array([ 1.33333333+0.j,  0.00000000+0.j,  0.66666667+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [legline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [legmul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = legmul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def legadd(c1, c2):
+    """
+    Add one Legendre series to another.
+
+    Returns the sum of two Legendre series `c1` + `c2`.  The arguments
+    are sequences of coefficients ordered from lowest order term to
+    highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the Legendre series of their sum.
+
+    See Also
+    --------
+    legsub, legmul, legdiv, legpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the sum of two Legendre series
+    is a Legendre series (without having to "reproject" the result onto
+    the basis set) so addition, just like that of "standard" polynomials,
+    is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legadd(c1,c2)
+    array([ 4.,  4.,  4.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def legsub(c1, c2):
+    """
+    Subtract one Legendre series from another.
+
+    Returns the difference of two Legendre series `c1` - `c2`.  The
+    sequences of coefficients are from lowest order term to highest, i.e.,
+    [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Legendre series coefficients representing their difference.
+
+    See Also
+    --------
+    legadd, legmul, legdiv, legpow
+
+    Notes
+    -----
+    Unlike multiplication, division, etc., the difference of two Legendre
+    series is a Legendre series (without having to "reproject" the result
+    onto the basis set) so subtraction, just like that of "standard"
+    polynomials, is simply "component-wise."
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legsub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> L.legsub(c2,c1) # -C.legsub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def legmulx(c):
+    """Multiply a Legendre series by x.
+
+    Multiply the Legendre series `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+    The multiplication uses the recursion relationship for Legendre
+    polynomials in the form
+
+    .. math::
+
+      xP_i(x) = ((i + 1)*P_{i + 1}(x) + i*P_{i - 1}(x))/(2i + 1)
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1] = c[0]
+    for i in range(1, len(c)):
+        j = i + 1
+        k = i - 1
+        s = i + j
+        prd[j] = (c[i]*j)/s
+        prd[k] += (c[i]*i)/s
+    return prd
+
+
+def legmul(c1, c2):
+    """
+    Multiply one Legendre series by another.
+
+    Returns the product of two Legendre series `c1` * `c2`.  The arguments
+    are sequences of coefficients, from lowest order "term" to highest,
+    e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of Legendre series coefficients representing their product.
+
+    See Also
+    --------
+    legadd, legsub, legdiv, legpow
+
+    Notes
+    -----
+    In general, the (polynomial) product of two C-series results in terms
+    that are not in the Legendre polynomial basis set.  Thus, to express
+    the product as a Legendre series, it is necessary to "reproject" the
+    product onto said basis set, which may produce "unintuitive" (but
+    correct) results; see Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2)
+    >>> P.legmul(c1,c2) # multiplication requires "reprojection"
+    array([  4.33333333,  10.4       ,  11.66666667,   3.6       ])
+
+    """
+    # s1, s2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+
+    if len(c1) > len(c2):
+        c = c2
+        xs = c1
+    else:
+        c = c1
+        xs = c2
+
+    if len(c) == 1:
+        c0 = c[0]*xs
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]*xs
+        c1 = c[1]*xs
+    else:
+        nd = len(c)
+        c0 = c[-2]*xs
+        c1 = c[-1]*xs
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = legsub(c[-i]*xs, (c1*(nd - 1))/nd)
+            c1 = legadd(tmp, (legmulx(c1)*(2*nd - 1))/nd)
+    return legadd(c0, legmulx(c1))
+
+
+def legdiv(c1, c2):
+    """
+    Divide one Legendre series by another.
+
+    Returns the quotient-with-remainder of two Legendre series
+    `c1` / `c2`.  The arguments are sequences of coefficients from lowest
+    order "term" to highest, e.g., [1,2,3] represents the series
+    ``P_0 + 2*P_1 + 3*P_2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of Legendre series coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    quo, rem : ndarrays
+        Of Legendre series coefficients representing the quotient and
+        remainder.
+
+    See Also
+    --------
+    legadd, legsub, legmul, legpow
+
+    Notes
+    -----
+    In general, the (polynomial) division of one Legendre series by another
+    results in quotient and remainder terms that are not in the Legendre
+    polynomial basis set.  Thus, to express these results as a Legendre
+    series, it is necessary to "reproject" the results onto the Legendre
+    basis set, which may produce "unintuitive" (but correct) results; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> L.legdiv(c1,c2) # quotient "intuitive," remainder not
+    (array([ 3.]), array([-8., -4.]))
+    >>> c2 = (0,1,2,3)
+    >>> L.legdiv(c2,c1) # neither "intuitive"
+    (array([-0.07407407,  1.66666667]), array([-1.03703704, -2.51851852]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    lc1 = len(c1)
+    lc2 = len(c2)
+    if lc1 < lc2:
+        return c1[:1]*0, c1
+    elif lc2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    else:
+        quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype)
+        rem = c1
+        for i in range(lc1 - lc2, - 1, -1):
+            p = legmul([0]*i + [1], c2)
+            q = rem[-1]/p[-1]
+            rem = rem[:-1] - q*p[:-1]
+            quo[i] = q
+        return quo, pu.trimseq(rem)
+
+
+def legpow(c, pow, maxpower=16):
+    """Raise a Legendre series to a power.
+
+    Returns the Legendre series `c` raised to the power `pow`. The
+    arguement `c` is a sequence of coefficients ordered from low to high.
+    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to
+        high.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Legendre series of power.
+
+    See Also
+    --------
+    legadd, legsub, legmul, legdiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = legmul(prd, c)
+        return prd
+
+
+def legder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a Legendre series.
+
+    Returns the Legendre series coefficients `c` differentiated `m` times
+    along `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable). The argument
+    `c` is an array of coefficients from low to high degree along each
+    axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
+    while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
+    2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Legendre series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change of
+        variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Legendre series of the derivative.
+
+    See Also
+    --------
+    legint
+
+    Notes
+    -----
+    In general, the result of differentiating a Legendre series does not
+    resemble the same operation on a power series. Thus the result of this
+    function may be "unintuitive," albeit correct; see Examples section
+    below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c = (1,2,3,4)
+    >>> L.legder(c)
+    array([  6.,   9.,  20.])
+    >>> L.legder(c, 3)
+    array([ 60.])
+    >>> L.legder(c, scl=-1)
+    array([ -6.,  -9., -20.])
+    >>> L.legder(c, 2,-1)
+    array([  9.,  60.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
+            for j in range(n, 2, -1):
+                der[j - 1] = (2*j - 1)*c[j]
+                c[j - 2] += c[j]
+            if n > 1:
+                der[1] = 3*c[2]
+            der[0] = c[1]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def legint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a Legendre series.
+
+    Returns the Legendre series coefficients `c` integrated `m` times from
+    `lbnd` along `axis`. At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.)  The argument `c` is an array of
+    coefficients from low to high degree along each axis, e.g., [1,2,3]
+    represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
+    represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
+    2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of Legendre series coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree in
+        each axis given by the corresponding index.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at
+        ``lbnd`` is the first value in the list, the value of the second
+        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
+        default), all constants are set to zero.  If ``m == 1``, a single
+        scalar can be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Legendre series coefficient array of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 0``, ``len(k) > m``, ``np.isscalar(lbnd) == False``, or
+        ``np.isscalar(scl) == False``.
+
+    See Also
+    --------
+    legder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.
+    Why is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`.  Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Also note that, in general, the result of integrating a C-series needs
+    to be "reprojected" onto the C-series basis set.  Thus, typically,
+    the result of this function is "unintuitive," albeit correct; see
+    Examples section below.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import legendre as L
+    >>> c = (1,2,3)
+    >>> L.legint(c)
+    array([ 0.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, 3)
+    array([  1.66666667e-02,  -1.78571429e-02,   4.76190476e-02,
+            -1.73472348e-18,   1.90476190e-02,   9.52380952e-03])
+    >>> L.legint(c, k=3)
+    array([ 3.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, lbnd=-2)
+    array([ 7.33333333,  0.4       ,  0.66666667,  0.6       ])
+    >>> L.legint(c, scl=2)
+    array([ 0.66666667,  0.8       ,  1.33333333,  1.2       ])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    k = list(k) + [0]*(cnt - len(k))
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            if n > 1:
+                tmp[2] = c[1]/3
+            for j in range(2, n):
+                t = c[j]/(2*j + 1)
+                tmp[j + 1] = t
+                tmp[j - 1] -= t
+            tmp[0] += k[i] - legval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def legval(x, c, tensor=True):
+    """
+    Evaluate a Legendre series at points x.
+
+    If `c` is of length `n + 1`, this function returns the value:
+
+    .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, algebra_like
+        The shape of the return value is described above.
+
+    See Also
+    --------
+    legval2d, leggrid2d, legval3d, leggrid3d
+
+    Notes
+    -----
+    The evaluation uses Clenshaw recursion, aka synthetic division.
+
+    Examples
+    --------
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        c = c.astype(np.double)
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    if len(c) == 1:
+        c0 = c[0]
+        c1 = 0
+    elif len(c) == 2:
+        c0 = c[0]
+        c1 = c[1]
+    else:
+        nd = len(c)
+        c0 = c[-2]
+        c1 = c[-1]
+        for i in range(3, len(c) + 1):
+            tmp = c0
+            nd = nd - 1
+            c0 = c[-i] - (c1*(nd - 1))/nd
+            c1 = tmp + (c1*x*(2*nd - 1))/nd
+    return c0 + c1*x
+
+
+def legval2d(x, y, c):
+    """
+    Evaluate a 2-D Legendre series at points (x, y).
+
+    This function returns the values:
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` is a 1-D array a one is implicitly appended to its shape to make
+    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and if it isn't an ndarray it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Legendre series at points formed
+        from pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    legval, leggrid2d, legval3d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = legval(x, c)
+    c = legval(y, c, tensor=False)
+    return c
+
+
+def leggrid2d(x, y, c):
+    """
+    Evaluate a 2-D Legendre series on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional Chebyshev series at points in the
+        Cartesian product of `x` and `y`.
+
+    See Also
+    --------
+    legval, legval2d, legval3d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = legval(x, c)
+    c = legval(y, c)
+    return c
+
+
+def legval3d(x, y, z, c):
+    """
+    Evaluate a 3-D Legendre series at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    legval, legval2d, leggrid2d, leggrid3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = legval(x, c)
+    c = legval(y, c, tensor=False)
+    c = legval(z, c, tensor=False)
+    return c
+
+
+def leggrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D Legendre series on the Cartesian product of x, y, and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    legval, legval2d, leggrid2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    c = legval(x, c)
+    c = legval(y, c)
+    c = legval(z, c)
+    return c
+
+
+def legvander(x, deg):
+    """Pseudo-Vandermonde matrix of given degree.
+
+    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
+    `x`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = L_i(x)
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the degree of the Legendre polynomial.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    array ``V = legvander(x, n)``, then ``np.dot(V, c)`` and
+    ``legval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of Legendre series of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray
+        The pseudo-Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where The last index is the degree of the
+        corresponding Legendre polynomial.  The dtype will be the same as
+        the converted `x`.
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    # Use forward recursion to generate the entries. This is not as accurate
+    # as reverse recursion in this application but it is more efficient.
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = (v[i-1]*x*(2*i - 1) - v[i-2]*(i - 1))/i
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def legvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = L_i(x) * L_j(y),
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the degrees of
+    the Legendre polynomials.
+
+    If ``V = legvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``legval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D Legendre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    legvander, legvander3d. legval2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = legvander(x, degx)
+    vy = legvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def legvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the degrees of the Legendre polynomials.
+
+    If ``V = legvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and ``np.dot(V, c.flat)`` and ``legval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D Legendre
+    series of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    legvander, legvander3d. legval2d, legval3d
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = legvander(x, degx)
+    vy = legvander(y, degy)
+    vz = legvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def legfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least squares fit of Legendre series to data.
+
+    Return the coefficients of a Legendre series of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (M,)
+        x-coordinates of the M sample points ``(x[i], y[i])``.
+    y : array_like, shape (M,) or (M, K)
+        y-coordinates of the sample points. Several data sets of sample
+        points sharing the same x-coordinates can be fitted at once by
+        passing in a 2D-array that contains one dataset per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit. Singular values smaller than
+        this relative to the largest singular value will be ignored. The
+        default value is len(x)*eps, where eps is the relative precision of
+        the float type, about 2e-16 in most cases.
+    full : bool, optional
+        Switch determining nature of return value. When it is False (the
+        default) just the coefficients are returned, when True diagnostic
+        information from the singular value decomposition is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (M,) or (M, K)
+        Legendre coefficients ordered from low to high. If `y` was
+        2-D, the coefficients for the data in column k of `y` are in
+        column `k`. If `deg` is specified as a list, coefficients for
+        terms not included in the fit are set equal to zero in the
+        returned `coef`.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Warns
+    -----
+    RankWarning
+        The rank of the coefficient matrix in the least-squares fit is
+        deficient. The warning is only raised if `full` = False.  The
+        warnings can be turned off by
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, polyfit, lagfit, hermfit, hermefit
+    legval : Evaluates a Legendre series.
+    legvander : Vandermonde matrix of Legendre series.
+    legweight : Legendre weight function (= 1).
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the Legendre series `p` that
+    minimizes the sum of the weighted squared errors
+
+    .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where :math:`w_j` are the weights. This problem is solved by setting up
+    as the (typically) overdetermined matrix equation
+
+    .. math:: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected, then a `RankWarning` will be issued. This means that the
+    coefficient values may be poorly determined. Using a lower order fit
+    will usually get rid of the warning.  The `rcond` parameter can also be
+    set to a value smaller than its default, but the resulting fit may be
+    spurious and have large contributions from roundoff error.
+
+    Fits using Legendre series are usually better conditioned than fits
+    using power series, but much can depend on the distribution of the
+    sample points and the smoothness of the data. If the quality of the fit
+    is inadequate splines may be a good alternative.
+
+    References
+    ----------
+    .. [1] Wikipedia, "Curve fitting",
+           http://en.wikipedia.org/wiki/Curve_fitting
+
+    Examples
+    --------
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = legvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = legvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim > 0:
+        if c.ndim == 2:
+            cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax+1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def legcompanion(c):
+    """Return the scaled companion matrix of c.
+
+    The basis polynomials are scaled so that the companion matrix is
+    symmetric when `c` is an Legendre basis polynomial. This provides
+    better eigenvalue estimates than the unscaled case and for basis
+    polynomials the eigenvalues are guaranteed to be real if
+    `numpy.linalg.eigvalsh` is used to obtain them.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of Legendre series coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Scaled companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    scl = 1./np.sqrt(2*np.arange(n) + 1)
+    top = mat.reshape(-1)[1::n+1]
+    bot = mat.reshape(-1)[n::n+1]
+    top[...] = np.arange(1, n)*scl[:n-1]*scl[1:n]
+    bot[...] = top
+    mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*(n/(2*n - 1))
+    return mat
+
+
+def legroots(c):
+    """
+    Compute the roots of a Legendre series.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * L_i(x).
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the series. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    polyroots, chebroots, lagroots, hermroots, hermeroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the series for such values.
+    Roots with multiplicity greater than 1 will also show larger errors as
+    the value of the series near such points is relatively insensitive to
+    errors in the roots. Isolated roots near the origin can be improved by
+    a few iterations of Newton's method.
+
+    The Legendre series basis polynomials aren't powers of ``x`` so the
+    results of this function may seem unintuitive.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.legendre as leg
+    >>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0, all real roots
+    array([-0.85099543, -0.11407192,  0.51506735])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = legcompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+def leggauss(deg):
+    """
+    Gauss-Legendre quadrature.
+
+    Computes the sample points and weights for Gauss-Legendre quadrature.
+    These sample points and weights will correctly integrate polynomials of
+    degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with
+    the weight function :math:`f(x) = 1`.
+
+    Parameters
+    ----------
+    deg : int
+        Number of sample points and weights. It must be >= 1.
+
+    Returns
+    -------
+    x : ndarray
+        1-D ndarray containing the sample points.
+    y : ndarray
+        1-D ndarray containing the weights.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    The results have only been tested up to degree 100, higher degrees may
+    be problematic. The weights are determined by using the fact that
+
+    .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
+
+    where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
+    is the k'th root of :math:`L_n`, and then scaling the results to get
+    the right value when integrating 1.
+
+    """
+    ideg = int(deg)
+    if ideg != deg or ideg < 1:
+        raise ValueError("deg must be a non-negative integer")
+
+    # first approximation of roots. We use the fact that the companion
+    # matrix is symmetric in this case in order to obtain better zeros.
+    c = np.array([0]*deg + [1])
+    m = legcompanion(c)
+    x = la.eigvalsh(m)
+
+    # improve roots by one application of Newton
+    dy = legval(x, c)
+    df = legval(x, legder(c))
+    x -= dy/df
+
+    # compute the weights. We scale the factor to avoid possible numerical
+    # overflow.
+    fm = legval(x, c[1:])
+    fm /= np.abs(fm).max()
+    df /= np.abs(df).max()
+    w = 1/(fm * df)
+
+    # for Legendre we can also symmetrize
+    w = (w + w[::-1])/2
+    x = (x - x[::-1])/2
+
+    # scale w to get the right value
+    w *= 2. / w.sum()
+
+    return x, w
+
+
+def legweight(x):
+    """
+    Weight function of the Legendre polynomials.
+
+    The weight function is :math:`1` and the interval of integration is
+    :math:`[-1, 1]`. The Legendre polynomials are orthogonal, but not
+    normalized, with respect to this weight function.
+
+    Parameters
+    ----------
+    x : array_like
+       Values at which the weight function will be computed.
+
+    Returns
+    -------
+    w : ndarray
+       The weight function at `x`.
+
+    Notes
+    -----
+
+    .. versionadded::1.7.0
+
+    """
+    w = x*0.0 + 1.0
+    return w
+
+#
+# Legendre series class
+#
+
+class Legendre(ABCPolyBase):
+    """A Legendre series class.
+
+    The Legendre class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Legendre coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(legadd)
+    _sub = staticmethod(legsub)
+    _mul = staticmethod(legmul)
+    _div = staticmethod(legdiv)
+    _pow = staticmethod(legpow)
+    _val = staticmethod(legval)
+    _int = staticmethod(legint)
+    _der = staticmethod(legder)
+    _fit = staticmethod(legfit)
+    _line = staticmethod(legline)
+    _roots = staticmethod(legroots)
+    _fromroots = staticmethod(legfromroots)
+
+    # Virtual properties
+    nickname = 'leg'
+    domain = np.array(legdomain)
+    window = np.array(legdomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
new file mode 100644
index 0000000000..5d05f59919
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
@@ -0,0 +1,1556 @@
+"""
+Objects for dealing with polynomials.
+
+This module provides a number of objects (mostly functions) useful for
+dealing with polynomials, including a `Polynomial` class that
+encapsulates the usual arithmetic operations.  (General information
+on how this module represents and works with polynomial objects is in
+the docstring for its "parent" sub-package, `numpy.polynomial`).
+
+Constants
+---------
+- `polydomain` -- Polynomial default domain, [-1,1].
+- `polyzero` -- (Coefficients of the) "zero polynomial."
+- `polyone` -- (Coefficients of the) constant polynomial 1.
+- `polyx` -- (Coefficients of the) identity map polynomial, ``f(x) = x``.
+
+Arithmetic
+----------
+- `polyadd` -- add two polynomials.
+- `polysub` -- subtract one polynomial from another.
+- `polymul` -- multiply two polynomials.
+- `polydiv` -- divide one polynomial by another.
+- `polypow` -- raise a polynomial to an positive integer power
+- `polyval` -- evaluate a polynomial at given points.
+- `polyval2d` -- evaluate a 2D polynomial at given points.
+- `polyval3d` -- evaluate a 3D polynomial at given points.
+- `polygrid2d` -- evaluate a 2D polynomial on a Cartesian product.
+- `polygrid3d` -- evaluate a 3D polynomial on a Cartesian product.
+
+Calculus
+--------
+- `polyder` -- differentiate a polynomial.
+- `polyint` -- integrate a polynomial.
+
+Misc Functions
+--------------
+- `polyfromroots` -- create a polynomial with specified roots.
+- `polyroots` -- find the roots of a polynomial.
+- `polyvander` -- Vandermonde-like matrix for powers.
+- `polyvander2d` -- Vandermonde-like matrix for 2D power series.
+- `polyvander3d` -- Vandermonde-like matrix for 3D power series.
+- `polycompanion` -- companion matrix in power series form.
+- `polyfit` -- least-squares fit returning a polynomial.
+- `polytrim` -- trim leading coefficients from a polynomial.
+- `polyline` -- polynomial representing given straight line.
+
+Classes
+-------
+- `Polynomial` -- polynomial class.
+
+See Also
+--------
+`numpy.polynomial`
+
+"""
+from __future__ import division, absolute_import, print_function
+
+__all__ = [
+    'polyzero', 'polyone', 'polyx', 'polydomain', 'polyline', 'polyadd',
+    'polysub', 'polymulx', 'polymul', 'polydiv', 'polypow', 'polyval',
+    'polyder', 'polyint', 'polyfromroots', 'polyvander', 'polyfit',
+    'polytrim', 'polyroots', 'Polynomial', 'polyval2d', 'polyval3d',
+    'polygrid2d', 'polygrid3d', 'polyvander2d', 'polyvander3d']
+
+import warnings
+import numpy as np
+import numpy.linalg as la
+
+from . import polyutils as pu
+from ._polybase import ABCPolyBase
+
+polytrim = pu.trimcoef
+
+#
+# These are constant arrays are of integer type so as to be compatible
+# with the widest range of other types, such as Decimal.
+#
+
+# Polynomial default domain.
+polydomain = np.array([-1, 1])
+
+# Polynomial coefficients representing zero.
+polyzero = np.array([0])
+
+# Polynomial coefficients representing one.
+polyone = np.array([1])
+
+# Polynomial coefficients representing the identity x.
+polyx = np.array([0, 1])
+
+#
+# Polynomial series functions
+#
+
+
+def polyline(off, scl):
+    """
+    Returns an array representing a linear polynomial.
+
+    Parameters
+    ----------
+    off, scl : scalars
+        The "y-intercept" and "slope" of the line, respectively.
+
+    Returns
+    -------
+    y : ndarray
+        This module's representation of the linear polynomial ``off +
+        scl*x``.
+
+    See Also
+    --------
+    chebline
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> P.polyline(1,-1)
+    array([ 1, -1])
+    >>> P.polyval(1, P.polyline(1,-1)) # should be 0
+    0.0
+
+    """
+    if scl != 0:
+        return np.array([off, scl])
+    else:
+        return np.array([off])
+
+
+def polyfromroots(roots):
+    """
+    Generate a monic polynomial with given roots.
+
+    Return the coefficients of the polynomial
+
+    .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
+
+    where the `r_n` are the roots specified in `roots`.  If a zero has
+    multiplicity n, then it must appear in `roots` n times. For instance,
+    if 2 is a root of multiplicity three and 3 is a root of multiplicity 2,
+    then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear
+    in any order.
+
+    If the returned coefficients are `c`, then
+
+    .. math:: p(x) = c_0 + c_1 * x + ... +  x^n
+
+    The coefficient of the last term is 1 for monic polynomials in this
+    form.
+
+    Parameters
+    ----------
+    roots : array_like
+        Sequence containing the roots.
+
+    Returns
+    -------
+    out : ndarray
+        1-D array of the polynomial's coefficients If all the roots are
+        real, then `out` is also real, otherwise it is complex.  (see
+        Examples below).
+
+    See Also
+    --------
+    chebfromroots, legfromroots, lagfromroots, hermfromroots
+    hermefromroots
+
+    Notes
+    -----
+    The coefficients are determined by multiplying together linear factors
+    of the form `(x - r_i)`, i.e.
+
+    .. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n)
+
+    where ``n == len(roots) - 1``; note that this implies that `1` is always
+    returned for :math:`a_n`.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x
+    array([ 0., -1.,  0.,  1.])
+    >>> j = complex(0,1)
+    >>> P.polyfromroots((-j,j)) # complex returned, though values are real
+    array([ 1.+0.j,  0.+0.j,  1.+0.j])
+
+    """
+    if len(roots) == 0:
+        return np.ones(1)
+    else:
+        [roots] = pu.as_series([roots], trim=False)
+        roots.sort()
+        p = [polyline(-r, 1) for r in roots]
+        n = len(p)
+        while n > 1:
+            m, r = divmod(n, 2)
+            tmp = [polymul(p[i], p[i+m]) for i in range(m)]
+            if r:
+                tmp[0] = polymul(tmp[0], p[-1])
+            p = tmp
+            n = m
+        return p[0]
+
+
+def polyadd(c1, c2):
+    """
+    Add one polynomial to another.
+
+    Returns the sum of two polynomials `c1` + `c2`.  The arguments are
+    sequences of coefficients from lowest order term to highest, i.e.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to high.
+
+    Returns
+    -------
+    out : ndarray
+        The coefficient array representing their sum.
+
+    See Also
+    --------
+    polysub, polymul, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> sum = P.polyadd(c1,c2); sum
+    array([ 4.,  4.,  4.])
+    >>> P.polyval(2, sum) # 4 + 4(2) + 4(2**2)
+    28.0
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] += c2
+        ret = c1
+    else:
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def polysub(c1, c2):
+    """
+    Subtract one polynomial from another.
+
+    Returns the difference of two polynomials `c1` - `c2`.  The arguments
+    are sequences of coefficients from lowest order term to highest, i.e.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Of coefficients representing their difference.
+
+    See Also
+    --------
+    polyadd, polymul, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polysub(c1,c2)
+    array([-2.,  0.,  2.])
+    >>> P.polysub(c2,c1) # -P.polysub(c1,c2)
+    array([ 2.,  0., -2.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if len(c1) > len(c2):
+        c1[:c2.size] -= c2
+        ret = c1
+    else:
+        c2 = -c2
+        c2[:c1.size] += c1
+        ret = c2
+    return pu.trimseq(ret)
+
+
+def polymulx(c):
+    """Multiply a polynomial by x.
+
+    Multiply the polynomial `c` by x, where x is the independent
+    variable.
+
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients ordered from low to
+        high.
+
+    Returns
+    -------
+    out : ndarray
+        Array representing the result of the multiplication.
+
+    Notes
+    -----
+
+    .. versionadded:: 1.5.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    # The zero series needs special treatment
+    if len(c) == 1 and c[0] == 0:
+        return c
+
+    prd = np.empty(len(c) + 1, dtype=c.dtype)
+    prd[0] = c[0]*0
+    prd[1:] = c
+    return prd
+
+
+def polymul(c1, c2):
+    """
+    Multiply one polynomial by another.
+
+    Returns the product of two polynomials `c1` * `c2`.  The arguments are
+    sequences of coefficients, from lowest order term to highest, e.g.,
+    [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2.``
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of coefficients representing a polynomial, relative to the
+        "standard" basis, and ordered from lowest order term to highest.
+
+    Returns
+    -------
+    out : ndarray
+        Of the coefficients of their product.
+
+    See Also
+    --------
+    polyadd, polysub, polydiv, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polymul(c1,c2)
+    array([  3.,   8.,  14.,   8.,   3.])
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    ret = np.convolve(c1, c2)
+    return pu.trimseq(ret)
+
+
+def polydiv(c1, c2):
+    """
+    Divide one polynomial by another.
+
+    Returns the quotient-with-remainder of two polynomials `c1` / `c2`.
+    The arguments are sequences of coefficients, from lowest order term
+    to highest, e.g., [1,2,3] represents ``1 + 2*x + 3*x**2``.
+
+    Parameters
+    ----------
+    c1, c2 : array_like
+        1-D arrays of polynomial coefficients ordered from low to high.
+
+    Returns
+    -------
+    [quo, rem] : ndarrays
+        Of coefficient series representing the quotient and remainder.
+
+    See Also
+    --------
+    polyadd, polysub, polymul, polypow
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c1 = (1,2,3)
+    >>> c2 = (3,2,1)
+    >>> P.polydiv(c1,c2)
+    (array([ 3.]), array([-8., -4.]))
+    >>> P.polydiv(c2,c1)
+    (array([ 0.33333333]), array([ 2.66666667,  1.33333333]))
+
+    """
+    # c1, c2 are trimmed copies
+    [c1, c2] = pu.as_series([c1, c2])
+    if c2[-1] == 0:
+        raise ZeroDivisionError()
+
+    len1 = len(c1)
+    len2 = len(c2)
+    if len2 == 1:
+        return c1/c2[-1], c1[:1]*0
+    elif len1 < len2:
+        return c1[:1]*0, c1
+    else:
+        dlen = len1 - len2
+        scl = c2[-1]
+        c2 = c2[:-1]/scl
+        i = dlen
+        j = len1 - 1
+        while i >= 0:
+            c1[i:j] -= c2*c1[j]
+            i -= 1
+            j -= 1
+        return c1[j+1:]/scl, pu.trimseq(c1[:j+1])
+
+
+def polypow(c, pow, maxpower=None):
+    """Raise a polynomial to a power.
+
+    Returns the polynomial `c` raised to the power `pow`. The argument
+    `c` is a sequence of coefficients ordered from low to high. i.e.,
+    [1,2,3] is the series  ``1 + 2*x + 3*x**2.``
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of array of series coefficients ordered from low to
+        high degree.
+    pow : integer
+        Power to which the series will be raised
+    maxpower : integer, optional
+        Maximum power allowed. This is mainly to limit growth of the series
+        to unmanageable size. Default is 16
+
+    Returns
+    -------
+    coef : ndarray
+        Power series of power.
+
+    See Also
+    --------
+    polyadd, polysub, polymul, polydiv
+
+    Examples
+    --------
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    power = int(pow)
+    if power != pow or power < 0:
+        raise ValueError("Power must be a non-negative integer.")
+    elif maxpower is not None and power > maxpower:
+        raise ValueError("Power is too large")
+    elif power == 0:
+        return np.array([1], dtype=c.dtype)
+    elif power == 1:
+        return c
+    else:
+        # This can be made more efficient by using powers of two
+        # in the usual way.
+        prd = c
+        for i in range(2, power + 1):
+            prd = np.convolve(prd, c)
+        return prd
+
+
+def polyder(c, m=1, scl=1, axis=0):
+    """
+    Differentiate a polynomial.
+
+    Returns the polynomial coefficients `c` differentiated `m` times along
+    `axis`.  At each iteration the result is multiplied by `scl` (the
+    scaling factor is for use in a linear change of variable).  The
+    argument `c` is an array of coefficients from low to high degree along
+    each axis, e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``
+    while [[1,2],[1,2]] represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is
+    ``x`` and axis=1 is ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        Array of polynomial coefficients. If c is multidimensional the
+        different axis correspond to different variables with the degree
+        in each axis given by the corresponding index.
+    m : int, optional
+        Number of derivatives taken, must be non-negative. (Default: 1)
+    scl : scalar, optional
+        Each differentiation is multiplied by `scl`.  The end result is
+        multiplication by ``scl**m``.  This is for use in a linear change
+        of variable. (Default: 1)
+    axis : int, optional
+        Axis over which the derivative is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    der : ndarray
+        Polynomial coefficients of the derivative.
+
+    See Also
+    --------
+    polyint
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3
+    >>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2
+    array([  2.,   6.,  12.])
+    >>> P.polyder(c,3) # (d**3/dx**3)(c) = 24
+    array([ 24.])
+    >>> P.polyder(c,scl=-1) # (d/d(-x))(c) = -2 - 6x - 12x**2
+    array([ -2.,  -6., -12.])
+    >>> P.polyder(c,2,-1) # (d**2/d(-x)**2)(c) = 6 + 24x
+    array([  6.,  24.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype fails with NA
+        c = c + 0.0
+    cdt = c.dtype
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of derivation must be integer")
+    if cnt < 0:
+        raise ValueError("The order of derivation must be non-negative")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    c = np.rollaxis(c, iaxis)
+    n = len(c)
+    if cnt >= n:
+        c = c[:1]*0
+    else:
+        for i in range(cnt):
+            n = n - 1
+            c *= scl
+            der = np.empty((n,) + c.shape[1:], dtype=cdt)
+            for j in range(n, 0, -1):
+                der[j - 1] = j*c[j]
+            c = der
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
+    """
+    Integrate a polynomial.
+
+    Returns the polynomial coefficients `c` integrated `m` times from
+    `lbnd` along `axis`.  At each iteration the resulting series is
+    **multiplied** by `scl` and an integration constant, `k`, is added.
+    The scaling factor is for use in a linear change of variable.  ("Buyer
+    beware": note that, depending on what one is doing, one may want `scl`
+    to be the reciprocal of what one might expect; for more information,
+    see the Notes section below.) The argument `c` is an array of
+    coefficients, from low to high degree along each axis, e.g., [1,2,3]
+    represents the polynomial ``1 + 2*x + 3*x**2`` while [[1,2],[1,2]]
+    represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is ``x`` and axis=1 is
+    ``y``.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients, ordered from low to high.
+    m : int, optional
+        Order of integration, must be positive. (Default: 1)
+    k : {[], list, scalar}, optional
+        Integration constant(s).  The value of the first integral at zero
+        is the first value in the list, the value of the second integral
+        at zero is the second value, etc.  If ``k == []`` (the default),
+        all constants are set to zero.  If ``m == 1``, a single scalar can
+        be given instead of a list.
+    lbnd : scalar, optional
+        The lower bound of the integral. (Default: 0)
+    scl : scalar, optional
+        Following each integration the result is *multiplied* by `scl`
+        before the integration constant is added. (Default: 1)
+    axis : int, optional
+        Axis over which the integral is taken. (Default: 0).
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    S : ndarray
+        Coefficient array of the integral.
+
+    Raises
+    ------
+    ValueError
+        If ``m < 1``, ``len(k) > m``.
+
+    See Also
+    --------
+    polyder
+
+    Notes
+    -----
+    Note that the result of each integration is *multiplied* by `scl`.  Why
+    is this important to note?  Say one is making a linear change of
+    variable :math:`u = ax + b` in an integral relative to `x`. Then
+    .. math::`dx = du/a`, so one will need to set `scl` equal to
+    :math:`1/a` - perhaps not what one would have first thought.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> c = (1,2,3)
+    >>> P.polyint(c) # should return array([0, 1, 1, 1])
+    array([ 0.,  1.,  1.,  1.])
+    >>> P.polyint(c,3) # should return array([0, 0, 0, 1/6, 1/12, 1/20])
+    array([ 0.        ,  0.        ,  0.        ,  0.16666667,  0.08333333,
+            0.05      ])
+    >>> P.polyint(c,k=3) # should return array([3, 1, 1, 1])
+    array([ 3.,  1.,  1.,  1.])
+    >>> P.polyint(c,lbnd=-2) # should return array([6, 1, 1, 1])
+    array([ 6.,  1.,  1.,  1.])
+    >>> P.polyint(c,scl=-2) # should return array([0, -2, -2, -2])
+    array([ 0., -2., -2., -2.])
+
+    """
+    c = np.array(c, ndmin=1, copy=1)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype doesn't preserve mask attribute.
+        c = c + 0.0
+    cdt = c.dtype
+    if not np.iterable(k):
+        k = [k]
+    cnt, iaxis = [int(t) for t in [m, axis]]
+
+    if cnt != m:
+        raise ValueError("The order of integration must be integer")
+    if cnt < 0:
+        raise ValueError("The order of integration must be non-negative")
+    if len(k) > cnt:
+        raise ValueError("Too many integration constants")
+    if iaxis != axis:
+        raise ValueError("The axis must be integer")
+    if not -c.ndim <= iaxis < c.ndim:
+        raise ValueError("The axis is out of range")
+    if iaxis < 0:
+        iaxis += c.ndim
+
+    if cnt == 0:
+        return c
+
+    k = list(k) + [0]*(cnt - len(k))
+    c = np.rollaxis(c, iaxis)
+    for i in range(cnt):
+        n = len(c)
+        c *= scl
+        if n == 1 and np.all(c[0] == 0):
+            c[0] += k[i]
+        else:
+            tmp = np.empty((n + 1,) + c.shape[1:], dtype=cdt)
+            tmp[0] = c[0]*0
+            tmp[1] = c[0]
+            for j in range(1, n):
+                tmp[j + 1] = c[j]/(j + 1)
+            tmp[0] += k[i] - polyval(lbnd, tmp)
+            c = tmp
+    c = np.rollaxis(c, 0, iaxis + 1)
+    return c
+
+
+def polyval(x, c, tensor=True):
+    """
+    Evaluate a polynomial at points x.
+
+    If `c` is of length `n + 1`, this function returns the value
+
+    .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n
+
+    The parameter `x` is converted to an array only if it is a tuple or a
+    list, otherwise it is treated as a scalar. In either case, either `x`
+    or its elements must support multiplication and addition both with
+    themselves and with the elements of `c`.
+
+    If `c` is a 1-D array, then `p(x)` will have the same shape as `x`.  If
+    `c` is multidimensional, then the shape of the result depends on the
+    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
+    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
+    scalars have shape (,).
+
+    Trailing zeros in the coefficients will be used in the evaluation, so
+    they should be avoided if efficiency is a concern.
+
+    Parameters
+    ----------
+    x : array_like, compatible object
+        If `x` is a list or tuple, it is converted to an ndarray, otherwise
+        it is left unchanged and treated as a scalar. In either case, `x`
+        or its elements must support addition and multiplication with
+        with themselves and with the elements of `c`.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree n are contained in c[n]. If `c` is multidimensional the
+        remaining indices enumerate multiple polynomials. In the two
+        dimensional case the coefficients may be thought of as stored in
+        the columns of `c`.
+    tensor : boolean, optional
+        If True, the shape of the coefficient array is extended with ones
+        on the right, one for each dimension of `x`. Scalars have dimension 0
+        for this action. The result is that every column of coefficients in
+        `c` is evaluated for every element of `x`. If False, `x` is broadcast
+        over the columns of `c` for the evaluation.  This keyword is useful
+        when `c` is multidimensional. The default value is True.
+
+        .. versionadded:: 1.7.0
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The shape of the returned array is described above.
+
+    See Also
+    --------
+    polyval2d, polygrid2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+    The evaluation uses Horner's method.
+
+    Examples
+    --------
+    >>> from numpy.polynomial.polynomial import polyval
+    >>> polyval(1, [1,2,3])
+    6.0
+    >>> a = np.arange(4).reshape(2,2)
+    >>> a
+    array([[0, 1],
+           [2, 3]])
+    >>> polyval(a, [1,2,3])
+    array([[  1.,   6.],
+           [ 17.,  34.]])
+    >>> coef = np.arange(4).reshape(2,2) # multidimensional coefficients
+    >>> coef
+    array([[0, 1],
+           [2, 3]])
+    >>> polyval([1,2], coef, tensor=True)
+    array([[ 2.,  4.],
+           [ 4.,  7.]])
+    >>> polyval([1,2], coef, tensor=False)
+    array([ 2.,  7.])
+
+    """
+    c = np.array(c, ndmin=1, copy=0)
+    if c.dtype.char in '?bBhHiIlLqQpP':
+        # astype fails with NA
+        c = c + 0.0
+    if isinstance(x, (tuple, list)):
+        x = np.asarray(x)
+    if isinstance(x, np.ndarray) and tensor:
+        c = c.reshape(c.shape + (1,)*x.ndim)
+
+    c0 = c[-1] + x*0
+    for i in range(2, len(c) + 1):
+        c0 = c[-i] + c0*x
+    return c0
+
+
+def polyval2d(x, y, c):
+    """
+    Evaluate a 2-D polynomial at points (x, y).
+
+    This function returns the value
+
+    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * x^i * y^j
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars and they
+    must have the same shape after conversion. In either case, either `x`
+    and `y` or their elements must support multiplication and addition both
+    with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points `(x, y)`,
+        where `x` and `y` must have the same shape. If `x` or `y` is a list
+        or tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term
+        of multi-degree i,j is contained in `c[i,j]`. If `c` has
+        dimension greater than two the remaining indices enumerate multiple
+        sets of coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points formed with
+        pairs of corresponding values from `x` and `y`.
+
+    See Also
+    --------
+    polyval, polygrid2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    try:
+        x, y = np.array((x, y), copy=0)
+    except:
+        raise ValueError('x, y are incompatible')
+
+    c = polyval(x, c)
+    c = polyval(y, c, tensor=False)
+    return c
+
+
+def polygrid2d(x, y, c):
+    """
+    Evaluate a 2-D polynomial on the Cartesian product of x and y.
+
+    This function returns the values:
+
+    .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * a^i * b^j
+
+    where the points `(a, b)` consist of all pairs formed by taking
+    `a` from `x` and `b` from `y`. The resulting points form a grid with
+    `x` in the first dimension and `y` in the second.
+
+    The parameters `x` and `y` are converted to arrays only if they are
+    tuples or a lists, otherwise they are treated as a scalars. In either
+    case, either `x` and `y` or their elements must support multiplication
+    and addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than two dimensions, ones are implicitly appended to
+    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
+    x.shape + y.shape.
+
+    Parameters
+    ----------
+    x, y : array_like, compatible objects
+        The two dimensional series is evaluated at the points in the
+        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
+        tuple, it is first converted to an ndarray, otherwise it is left
+        unchanged and, if it isn't an ndarray, it is treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    polyval, polyval2d, polyval3d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    c = polyval(x, c)
+    c = polyval(y, c)
+    return c
+
+
+def polyval3d(x, y, z, c):
+    """
+    Evaluate a 3-D polynomial at points (x, y, z).
+
+    This function returns the values:
+
+    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * x^i * y^j * z^k
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if
+    they are tuples or a lists, otherwise they are treated as a scalars and
+    they must have the same shape after conversion. In either case, either
+    `x`, `y`, and `z` or their elements must support multiplication and
+    addition both with themselves and with the elements of `c`.
+
+    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
+    shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible object
+        The three dimensional series is evaluated at the points
+        `(x, y, z)`, where `x`, `y`, and `z` must have the same shape.  If
+        any of `x`, `y`, or `z` is a list or tuple, it is first converted
+        to an ndarray, otherwise it is left unchanged and if it isn't an
+        ndarray it is  treated as a scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficient of the term of
+        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
+        greater than 3 the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the multidimensional polynomial on points formed with
+        triples of corresponding values from `x`, `y`, and `z`.
+
+    See Also
+    --------
+    polyval, polyval2d, polygrid2d, polygrid3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    try:
+        x, y, z = np.array((x, y, z), copy=0)
+    except:
+        raise ValueError('x, y, z are incompatible')
+
+    c = polyval(x, c)
+    c = polyval(y, c, tensor=False)
+    c = polyval(z, c, tensor=False)
+    return c
+
+
+def polygrid3d(x, y, z, c):
+    """
+    Evaluate a 3-D polynomial on the Cartesian product of x, y and z.
+
+    This function returns the values:
+
+    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * a^i * b^j * c^k
+
+    where the points `(a, b, c)` consist of all triples formed by taking
+    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
+    a grid with `x` in the first dimension, `y` in the second, and `z` in
+    the third.
+
+    The parameters `x`, `y`, and `z` are converted to arrays only if they
+    are tuples or a lists, otherwise they are treated as a scalars. In
+    either case, either `x`, `y`, and `z` or their elements must support
+    multiplication and addition both with themselves and with the elements
+    of `c`.
+
+    If `c` has fewer than three dimensions, ones are implicitly appended to
+    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
+    x.shape + y.shape + z.shape.
+
+    Parameters
+    ----------
+    x, y, z : array_like, compatible objects
+        The three dimensional series is evaluated at the points in the
+        Cartesian product of `x`, `y`, and `z`.  If `x`,`y`, or `z` is a
+        list or tuple, it is first converted to an ndarray, otherwise it is
+        left unchanged and, if it isn't an ndarray, it is treated as a
+        scalar.
+    c : array_like
+        Array of coefficients ordered so that the coefficients for terms of
+        degree i,j are contained in ``c[i,j]``. If `c` has dimension
+        greater than two the remaining indices enumerate multiple sets of
+        coefficients.
+
+    Returns
+    -------
+    values : ndarray, compatible object
+        The values of the two dimensional polynomial at points in the Cartesian
+        product of `x` and `y`.
+
+    See Also
+    --------
+    polyval, polyval2d, polygrid2d, polyval3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    c = polyval(x, c)
+    c = polyval(y, c)
+    c = polyval(z, c)
+    return c
+
+
+def polyvander(x, deg):
+    """Vandermonde matrix of given degree.
+
+    Returns the Vandermonde matrix of degree `deg` and sample points
+    `x`. The Vandermonde matrix is defined by
+
+    .. math:: V[..., i] = x^i,
+
+    where `0 <= i <= deg`. The leading indices of `V` index the elements of
+    `x` and the last index is the power of `x`.
+
+    If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
+    matrix ``V = polyvander(x, n)``, then ``np.dot(V, c)`` and
+    ``polyval(x, c)`` are the same up to roundoff. This equivalence is
+    useful both for least squares fitting and for the evaluation of a large
+    number of polynomials of the same degree and sample points.
+
+    Parameters
+    ----------
+    x : array_like
+        Array of points. The dtype is converted to float64 or complex128
+        depending on whether any of the elements are complex. If `x` is
+        scalar it is converted to a 1-D array.
+    deg : int
+        Degree of the resulting matrix.
+
+    Returns
+    -------
+    vander : ndarray.
+        The Vandermonde matrix. The shape of the returned matrix is
+        ``x.shape + (deg + 1,)``, where the last index is the power of `x`.
+        The dtype will be the same as the converted `x`.
+
+    See Also
+    --------
+    polyvander2d, polyvander3d
+
+    """
+    ideg = int(deg)
+    if ideg != deg:
+        raise ValueError("deg must be integer")
+    if ideg < 0:
+        raise ValueError("deg must be non-negative")
+
+    x = np.array(x, copy=0, ndmin=1) + 0.0
+    dims = (ideg + 1,) + x.shape
+    dtyp = x.dtype
+    v = np.empty(dims, dtype=dtyp)
+    v[0] = x*0 + 1
+    if ideg > 0:
+        v[1] = x
+        for i in range(2, ideg + 1):
+            v[i] = v[i-1]*x
+    return np.rollaxis(v, 0, v.ndim)
+
+
+def polyvander2d(x, y, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y)`. The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., deg[1]*i + j] = x^i * y^j,
+
+    where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
+    `V` index the points `(x, y)` and the last index encodes the powers of
+    `x` and `y`.
+
+    If ``V = polyvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
+    correspond to the elements of a 2-D coefficient array `c` of shape
+    (xdeg + 1, ydeg + 1) in the order
+
+    .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
+
+    and ``np.dot(V, c.flat)`` and ``polyval2d(x, y, c)`` will be the same
+    up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 2-D polynomials
+    of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes
+        will be converted to either float64 or complex128 depending on
+        whether any of the elements are complex. Scalars are converted to
+        1-D arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg].
+
+    Returns
+    -------
+    vander2d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)`.  The dtype will be the same
+        as the converted `x` and `y`.
+
+    See Also
+    --------
+    polyvander, polyvander3d. polyval2d, polyval3d
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy = ideg
+    x, y = np.array((x, y), copy=0) + 0.0
+
+    vx = polyvander(x, degx)
+    vy = polyvander(y, degy)
+    v = vx[..., None]*vy[..., None,:]
+    # einsum bug
+    #v = np.einsum("...i,...j->...ij", vx, vy)
+    return v.reshape(v.shape[:-2] + (-1,))
+
+
+def polyvander3d(x, y, z, deg):
+    """Pseudo-Vandermonde matrix of given degrees.
+
+    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
+    points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
+    then The pseudo-Vandermonde matrix is defined by
+
+    .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = x^i * y^j * z^k,
+
+    where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`.  The leading
+    indices of `V` index the points `(x, y, z)` and the last index encodes
+    the powers of `x`, `y`, and `z`.
+
+    If ``V = polyvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
+    of `V` correspond to the elements of a 3-D coefficient array `c` of
+    shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
+
+    .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
+
+    and  ``np.dot(V, c.flat)`` and ``polyval3d(x, y, z, c)`` will be the
+    same up to roundoff. This equivalence is useful both for least squares
+    fitting and for the evaluation of a large number of 3-D polynomials
+    of the same degrees and sample points.
+
+    Parameters
+    ----------
+    x, y, z : array_like
+        Arrays of point coordinates, all of the same shape. The dtypes will
+        be converted to either float64 or complex128 depending on whether
+        any of the elements are complex. Scalars are converted to 1-D
+        arrays.
+    deg : list of ints
+        List of maximum degrees of the form [x_deg, y_deg, z_deg].
+
+    Returns
+    -------
+    vander3d : ndarray
+        The shape of the returned matrix is ``x.shape + (order,)``, where
+        :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`.  The dtype will
+        be the same as the converted `x`, `y`, and `z`.
+
+    See Also
+    --------
+    polyvander, polyvander3d. polyval2d, polyval3d
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    ideg = [int(d) for d in deg]
+    is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)]
+    if is_valid != [1, 1, 1]:
+        raise ValueError("degrees must be non-negative integers")
+    degx, degy, degz = ideg
+    x, y, z = np.array((x, y, z), copy=0) + 0.0
+
+    vx = polyvander(x, degx)
+    vy = polyvander(y, degy)
+    vz = polyvander(z, degz)
+    v = vx[..., None, None]*vy[..., None,:, None]*vz[..., None, None,:]
+    # einsum bug
+    #v = np.einsum("...i, ...j, ...k->...ijk", vx, vy, vz)
+    return v.reshape(v.shape[:-3] + (-1,))
+
+
+def polyfit(x, y, deg, rcond=None, full=False, w=None):
+    """
+    Least-squares fit of a polynomial to data.
+
+    Return the coefficients of a polynomial of degree `deg` that is the
+    least squares fit to the data values `y` given at points `x`. If `y` is
+    1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
+    fits are done, one for each column of `y`, and the resulting
+    coefficients are stored in the corresponding columns of a 2-D return.
+    The fitted polynomial(s) are in the form
+
+    .. math::  p(x) = c_0 + c_1 * x + ... + c_n * x^n,
+
+    where `n` is `deg`.
+
+    Parameters
+    ----------
+    x : array_like, shape (`M`,)
+        x-coordinates of the `M` sample (data) points ``(x[i], y[i])``.
+    y : array_like, shape (`M`,) or (`M`, `K`)
+        y-coordinates of the sample points.  Several sets of sample points
+        sharing the same x-coordinates can be (independently) fit with one
+        call to `polyfit` by passing in for `y` a 2-D array that contains
+        one data set per column.
+    deg : int or 1-D array_like
+        Degree(s) of the fitting polynomials. If `deg` is a single integer
+        all terms up to and including the `deg`'th term are included in the
+        fit. For Numpy versions >= 1.11 a list of integers specifying the
+        degrees of the terms to include may be used instead.
+    rcond : float, optional
+        Relative condition number of the fit.  Singular values smaller
+        than `rcond`, relative to the largest singular value, will be
+        ignored.  The default value is ``len(x)*eps``, where `eps` is the
+        relative precision of the platform's float type, about 2e-16 in
+        most cases.
+    full : bool, optional
+        Switch determining the nature of the return value.  When ``False``
+        (the default) just the coefficients are returned; when ``True``,
+        diagnostic information from the singular value decomposition (used
+        to solve the fit's matrix equation) is also returned.
+    w : array_like, shape (`M`,), optional
+        Weights. If not None, the contribution of each point
+        ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
+        weights are chosen so that the errors of the products ``w[i]*y[i]``
+        all have the same variance.  The default value is None.
+
+        .. versionadded:: 1.5.0
+
+    Returns
+    -------
+    coef : ndarray, shape (`deg` + 1,) or (`deg` + 1, `K`)
+        Polynomial coefficients ordered from low to high.  If `y` was 2-D,
+        the coefficients in column `k` of `coef` represent the polynomial
+        fit to the data in `y`'s `k`-th column.
+
+    [residuals, rank, singular_values, rcond] : list
+        These values are only returned if `full` = True
+
+        resid -- sum of squared residuals of the least squares fit
+        rank -- the numerical rank of the scaled Vandermonde matrix
+        sv -- singular values of the scaled Vandermonde matrix
+        rcond -- value of `rcond`.
+
+        For more details, see `linalg.lstsq`.
+
+    Raises
+    ------
+    RankWarning
+        Raised if the matrix in the least-squares fit is rank deficient.
+        The warning is only raised if `full` == False.  The warnings can
+        be turned off by:
+
+        >>> import warnings
+        >>> warnings.simplefilter('ignore', RankWarning)
+
+    See Also
+    --------
+    chebfit, legfit, lagfit, hermfit, hermefit
+    polyval : Evaluates a polynomial.
+    polyvander : Vandermonde matrix for powers.
+    linalg.lstsq : Computes a least-squares fit from the matrix.
+    scipy.interpolate.UnivariateSpline : Computes spline fits.
+
+    Notes
+    -----
+    The solution is the coefficients of the polynomial `p` that minimizes
+    the sum of the weighted squared errors
+
+    .. math :: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
+
+    where the :math:`w_j` are the weights. This problem is solved by
+    setting up the (typically) over-determined matrix equation:
+
+    .. math :: V(x) * c = w * y,
+
+    where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
+    coefficients to be solved for, `w` are the weights, and `y` are the
+    observed values.  This equation is then solved using the singular value
+    decomposition of `V`.
+
+    If some of the singular values of `V` are so small that they are
+    neglected (and `full` == ``False``), a `RankWarning` will be raised.
+    This means that the coefficient values may be poorly determined.
+    Fitting to a lower order polynomial will usually get rid of the warning
+    (but may not be what you want, of course; if you have independent
+    reason(s) for choosing the degree which isn't working, you may have to:
+    a) reconsider those reasons, and/or b) reconsider the quality of your
+    data).  The `rcond` parameter can also be set to a value smaller than
+    its default, but the resulting fit may be spurious and have large
+    contributions from roundoff error.
+
+    Polynomial fits using double precision tend to "fail" at about
+    (polynomial) degree 20. Fits using Chebyshev or Legendre series are
+    generally better conditioned, but much can still depend on the
+    distribution of the sample points and the smoothness of the data.  If
+    the quality of the fit is inadequate, splines may be a good
+    alternative.
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polynomial as P
+    >>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1]
+    >>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + N(0,1) "noise"
+    >>> c, stats = P.polyfit(x,y,3,full=True)
+    >>> c # c[0], c[2] should be approx. 0, c[1] approx. -1, c[3] approx. 1
+    array([ 0.01909725, -1.30598256, -0.00577963,  1.02644286])
+    >>> stats # note the large SSR, explaining the rather poor results
+    [array([ 38.06116253]), 4, array([ 1.38446749,  1.32119158,  0.50443316,
+    0.28853036]), 1.1324274851176597e-014]
+
+    Same thing without the added noise
+
+    >>> y = x**3 - x
+    >>> c, stats = P.polyfit(x,y,3,full=True)
+    >>> c # c[0], c[2] should be "very close to 0", c[1] ~= -1, c[3] ~= 1
+    array([ -1.73362882e-17,  -1.00000000e+00,  -2.67471909e-16,
+             1.00000000e+00])
+    >>> stats # note the minuscule SSR
+    [array([  7.46346754e-31]), 4, array([ 1.38446749,  1.32119158,
+    0.50443316,  0.28853036]), 1.1324274851176597e-014]
+
+    """
+    x = np.asarray(x) + 0.0
+    y = np.asarray(y) + 0.0
+    deg = np.asarray(deg)
+
+    # check arguments.
+    if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0:
+        raise TypeError("deg must be an int or non-empty 1-D array of int")
+    if deg.min() < 0:
+        raise ValueError("expected deg >= 0")
+    if x.ndim != 1:
+        raise TypeError("expected 1D vector for x")
+    if x.size == 0:
+        raise TypeError("expected non-empty vector for x")
+    if y.ndim < 1 or y.ndim > 2:
+        raise TypeError("expected 1D or 2D array for y")
+    if len(x) != len(y):
+        raise TypeError("expected x and y to have same length")
+
+    if deg.ndim == 0:
+        lmax = deg
+        order = lmax + 1
+        van = polyvander(x, lmax)
+    else:
+        deg = np.sort(deg)
+        lmax = deg[-1]
+        order = len(deg)
+        van = polyvander(x, lmax)[:, deg]
+
+    # set up the least squares matrices in transposed form
+    lhs = van.T
+    rhs = y.T
+    if w is not None:
+        w = np.asarray(w) + 0.0
+        if w.ndim != 1:
+            raise TypeError("expected 1D vector for w")
+        if len(x) != len(w):
+            raise TypeError("expected x and w to have same length")
+        # apply weights. Don't use inplace operations as they
+        # can cause problems with NA.
+        lhs = lhs * w
+        rhs = rhs * w
+
+    # set rcond
+    if rcond is None:
+        rcond = len(x)*np.finfo(x.dtype).eps
+
+    # Determine the norms of the design matrix columns.
+    if issubclass(lhs.dtype.type, np.complexfloating):
+        scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1))
+    else:
+        scl = np.sqrt(np.square(lhs).sum(1))
+    scl[scl == 0] = 1
+
+    # Solve the least squares problem.
+    c, resids, rank, s = la.lstsq(lhs.T/scl, rhs.T, rcond)
+    c = (c.T/scl).T
+
+    # Expand c to include non-fitted coefficients which are set to zero
+    if deg.ndim == 1:
+        if c.ndim == 2:
+            cc = np.zeros((lmax + 1, c.shape[1]), dtype=c.dtype)
+        else:
+            cc = np.zeros(lmax + 1, dtype=c.dtype)
+        cc[deg] = c
+        c = cc
+
+    # warn on rank reduction
+    if rank != order and not full:
+        msg = "The fit may be poorly conditioned"
+        warnings.warn(msg, pu.RankWarning)
+
+    if full:
+        return c, [resids, rank, s, rcond]
+    else:
+        return c
+
+
+def polycompanion(c):
+    """
+    Return the companion matrix of c.
+
+    The companion matrix for power series cannot be made symmetric by
+    scaling the basis, so this function differs from those for the
+    orthogonal polynomials.
+
+    Parameters
+    ----------
+    c : array_like
+        1-D array of polynomial coefficients ordered from low to high
+        degree.
+
+    Returns
+    -------
+    mat : ndarray
+        Companion matrix of dimensions (deg, deg).
+
+    Notes
+    -----
+
+    .. versionadded:: 1.7.0
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        raise ValueError('Series must have maximum degree of at least 1.')
+    if len(c) == 2:
+        return np.array([[-c[0]/c[1]]])
+
+    n = len(c) - 1
+    mat = np.zeros((n, n), dtype=c.dtype)
+    bot = mat.reshape(-1)[n::n+1]
+    bot[...] = 1
+    mat[:, -1] -= c[:-1]/c[-1]
+    return mat
+
+
+def polyroots(c):
+    """
+    Compute the roots of a polynomial.
+
+    Return the roots (a.k.a. "zeros") of the polynomial
+
+    .. math:: p(x) = \\sum_i c[i] * x^i.
+
+    Parameters
+    ----------
+    c : 1-D array_like
+        1-D array of polynomial coefficients.
+
+    Returns
+    -------
+    out : ndarray
+        Array of the roots of the polynomial. If all the roots are real,
+        then `out` is also real, otherwise it is complex.
+
+    See Also
+    --------
+    chebroots
+
+    Notes
+    -----
+    The root estimates are obtained as the eigenvalues of the companion
+    matrix, Roots far from the origin of the complex plane may have large
+    errors due to the numerical instability of the power series for such
+    values. Roots with multiplicity greater than 1 will also show larger
+    errors as the value of the series near such points is relatively
+    insensitive to errors in the roots. Isolated roots near the origin can
+    be improved by a few iterations of Newton's method.
+
+    Examples
+    --------
+    >>> import numpy.polynomial.polynomial as poly
+    >>> poly.polyroots(poly.polyfromroots((-1,0,1)))
+    array([-1.,  0.,  1.])
+    >>> poly.polyroots(poly.polyfromroots((-1,0,1))).dtype
+    dtype('float64')
+    >>> j = complex(0,1)
+    >>> poly.polyroots(poly.polyfromroots((-j,0,j)))
+    array([  0.00000000e+00+0.j,   0.00000000e+00+1.j,   2.77555756e-17-1.j])
+
+    """
+    # c is a trimmed copy
+    [c] = pu.as_series([c])
+    if len(c) < 2:
+        return np.array([], dtype=c.dtype)
+    if len(c) == 2:
+        return np.array([-c[0]/c[1]])
+
+    m = polycompanion(c)
+    r = la.eigvals(m)
+    r.sort()
+    return r
+
+
+#
+# polynomial class
+#
+
+class Polynomial(ABCPolyBase):
+    """A power series class.
+
+    The Polynomial class provides the standard Python numerical methods
+    '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
+    attributes and methods listed in the `ABCPolyBase` documentation.
+
+    Parameters
+    ----------
+    coef : array_like
+        Polynomial coefficients in order of increasing degree, i.e.,
+        ``(1, 2, 3)`` give ``1 + 2*x + 3*x**2``.
+    domain : (2,) array_like, optional
+        Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
+        to the interval ``[window[0], window[1]]`` by shifting and scaling.
+        The default value is [-1, 1].
+    window : (2,) array_like, optional
+        Window, see `domain` for its use. The default value is [-1, 1].
+
+        .. versionadded:: 1.6.0
+
+    """
+    # Virtual Functions
+    _add = staticmethod(polyadd)
+    _sub = staticmethod(polysub)
+    _mul = staticmethod(polymul)
+    _div = staticmethod(polydiv)
+    _pow = staticmethod(polypow)
+    _val = staticmethod(polyval)
+    _int = staticmethod(polyint)
+    _der = staticmethod(polyder)
+    _fit = staticmethod(polyfit)
+    _line = staticmethod(polyline)
+    _roots = staticmethod(polyroots)
+    _fromroots = staticmethod(polyfromroots)
+
+    # Virtual properties
+    nickname = 'poly'
+    domain = np.array(polydomain)
+    window = np.array(polydomain)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
new file mode 100644
index 0000000000..c1b7528d5a
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
@@ -0,0 +1,403 @@
+"""
+Utililty classes and functions for the polynomial modules.
+
+This module provides: error and warning objects; a polynomial base class;
+and some routines used in both the `polynomial` and `chebyshev` modules.
+
+Error objects
+-------------
+
+.. autosummary::
+   :toctree: generated/
+
+   PolyError            base class for this sub-package's errors.
+   PolyDomainError      raised when domains are mismatched.
+
+Warning objects
+---------------
+
+.. autosummary::
+   :toctree: generated/
+
+   RankWarning  raised in least-squares fit for rank-deficient matrix.
+
+Base class
+----------
+
+.. autosummary::
+   :toctree: generated/
+
+   PolyBase Obsolete base class for the polynomial classes. Do not use.
+
+Functions
+---------
+
+.. autosummary::
+   :toctree: generated/
+
+   as_series    convert list of array_likes into 1-D arrays of common type.
+   trimseq      remove trailing zeros.
+   trimcoef     remove small trailing coefficients.
+   getdomain    return the domain appropriate for a given set of abscissae.
+   mapdomain    maps points between domains.
+   mapparms     parameters of the linear map between domains.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+__all__ = [
+    'RankWarning', 'PolyError', 'PolyDomainError', 'as_series', 'trimseq',
+    'trimcoef', 'getdomain', 'mapdomain', 'mapparms', 'PolyBase']
+
+#
+# Warnings and Exceptions
+#
+
+class RankWarning(UserWarning):
+    """Issued by chebfit when the design matrix is rank deficient."""
+    pass
+
+class PolyError(Exception):
+    """Base class for errors in this module."""
+    pass
+
+class PolyDomainError(PolyError):
+    """Issued by the generic Poly class when two domains don't match.
+
+    This is raised when an binary operation is passed Poly objects with
+    different domains.
+
+    """
+    pass
+
+#
+# Base class for all polynomial types
+#
+
+class PolyBase(object):
+    """
+    Base class for all polynomial types.
+
+    Deprecated in numpy 1.9.0, use the abstract
+    ABCPolyBase class instead. Note that the latter
+    reguires a number of virtual functions to be
+    implemented.
+
+    """
+    pass
+
+#
+# Helper functions to convert inputs to 1-D arrays
+#
+def trimseq(seq):
+    """Remove small Poly series coefficients.
+
+    Parameters
+    ----------
+    seq : sequence
+        Sequence of Poly series coefficients. This routine fails for
+        empty sequences.
+
+    Returns
+    -------
+    series : sequence
+        Subsequence with trailing zeros removed. If the resulting sequence
+        would be empty, return the first element. The returned sequence may
+        or may not be a view.
+
+    Notes
+    -----
+    Do not lose the type info if the sequence contains unknown objects.
+
+    """
+    if len(seq) == 0:
+        return seq
+    else:
+        for i in range(len(seq) - 1, -1, -1):
+            if seq[i] != 0:
+                break
+        return seq[:i+1]
+
+
+def as_series(alist, trim=True):
+    """
+    Return argument as a list of 1-d arrays.
+
+    The returned list contains array(s) of dtype double, complex double, or
+    object.  A 1-d argument of shape ``(N,)`` is parsed into ``N`` arrays of
+    size one; a 2-d argument of shape ``(M,N)`` is parsed into ``M`` arrays
+    of size ``N`` (i.e., is "parsed by row"); and a higher dimensional array
+    raises a Value Error if it is not first reshaped into either a 1-d or 2-d
+    array.
+
+    Parameters
+    ----------
+    alist : array_like
+        A 1- or 2-d array_like
+    trim : boolean, optional
+        When True, trailing zeros are removed from the inputs.
+        When False, the inputs are passed through intact.
+
+    Returns
+    -------
+    [a1, a2,...] : list of 1-D arrays
+        A copy of the input data as a list of 1-d arrays.
+
+    Raises
+    ------
+    ValueError
+        Raised when `as_series` cannot convert its input to 1-d arrays, or at
+        least one of the resulting arrays is empty.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> a = np.arange(4)
+    >>> P.as_series(a)
+    [array([ 0.]), array([ 1.]), array([ 2.]), array([ 3.])]
+    >>> b = np.arange(6).reshape((2,3))
+    >>> P.as_series(b)
+    [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.])]
+
+    """
+    arrays = [np.array(a, ndmin=1, copy=0) for a in alist]
+    if min([a.size for a in arrays]) == 0:
+        raise ValueError("Coefficient array is empty")
+    if any([a.ndim != 1 for a in arrays]):
+        raise ValueError("Coefficient array is not 1-d")
+    if trim:
+        arrays = [trimseq(a) for a in arrays]
+
+    if any([a.dtype == np.dtype(object) for a in arrays]):
+        ret = []
+        for a in arrays:
+            if a.dtype != np.dtype(object):
+                tmp = np.empty(len(a), dtype=np.dtype(object))
+                tmp[:] = a[:]
+                ret.append(tmp)
+            else:
+                ret.append(a.copy())
+    else:
+        try:
+            dtype = np.common_type(*arrays)
+        except:
+            raise ValueError("Coefficient arrays have no common type")
+        ret = [np.array(a, copy=1, dtype=dtype) for a in arrays]
+    return ret
+
+
+def trimcoef(c, tol=0):
+    """
+    Remove "small" "trailing" coefficients from a polynomial.
+
+    "Small" means "small in absolute value" and is controlled by the
+    parameter `tol`; "trailing" means highest order coefficient(s), e.g., in
+    ``[0, 1, 1, 0, 0]`` (which represents ``0 + x + x**2 + 0*x**3 + 0*x**4``)
+    both the 3-rd and 4-th order coefficients would be "trimmed."
+
+    Parameters
+    ----------
+    c : array_like
+        1-d array of coefficients, ordered from lowest order to highest.
+    tol : number, optional
+        Trailing (i.e., highest order) elements with absolute value less
+        than or equal to `tol` (default value is zero) are removed.
+
+    Returns
+    -------
+    trimmed : ndarray
+        1-d array with trailing zeros removed.  If the resulting series
+        would be empty, a series containing a single zero is returned.
+
+    Raises
+    ------
+    ValueError
+        If `tol` < 0
+
+    See Also
+    --------
+    trimseq
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> P.trimcoef((0,0,3,0,5,0,0))
+    array([ 0.,  0.,  3.,  0.,  5.])
+    >>> P.trimcoef((0,0,1e-3,0,1e-5,0,0),1e-3) # item == tol is trimmed
+    array([ 0.])
+    >>> i = complex(0,1) # works for complex
+    >>> P.trimcoef((3e-4,1e-3*(1-i),5e-4,2e-5*(1+i)), 1e-3)
+    array([ 0.0003+0.j   ,  0.0010-0.001j])
+
+    """
+    if tol < 0:
+        raise ValueError("tol must be non-negative")
+
+    [c] = as_series([c])
+    [ind] = np.where(np.abs(c) > tol)
+    if len(ind) == 0:
+        return c[:1]*0
+    else:
+        return c[:ind[-1] + 1].copy()
+
+def getdomain(x):
+    """
+    Return a domain suitable for given abscissae.
+
+    Find a domain suitable for a polynomial or Chebyshev series
+    defined at the values supplied.
+
+    Parameters
+    ----------
+    x : array_like
+        1-d array of abscissae whose domain will be determined.
+
+    Returns
+    -------
+    domain : ndarray
+        1-d array containing two values.  If the inputs are complex, then
+        the two returned points are the lower left and upper right corners
+        of the smallest rectangle (aligned with the axes) in the complex
+        plane containing the points `x`. If the inputs are real, then the
+        two points are the ends of the smallest interval containing the
+        points `x`.
+
+    See Also
+    --------
+    mapparms, mapdomain
+
+    Examples
+    --------
+    >>> from numpy.polynomial import polyutils as pu
+    >>> points = np.arange(4)**2 - 5; points
+    array([-5, -4, -1,  4])
+    >>> pu.getdomain(points)
+    array([-5.,  4.])
+    >>> c = np.exp(complex(0,1)*np.pi*np.arange(12)/6) # unit circle
+    >>> pu.getdomain(c)
+    array([-1.-1.j,  1.+1.j])
+
+    """
+    [x] = as_series([x], trim=False)
+    if x.dtype.char in np.typecodes['Complex']:
+        rmin, rmax = x.real.min(), x.real.max()
+        imin, imax = x.imag.min(), x.imag.max()
+        return np.array((complex(rmin, imin), complex(rmax, imax)))
+    else:
+        return np.array((x.min(), x.max()))
+
+def mapparms(old, new):
+    """
+    Linear map parameters between domains.
+
+    Return the parameters of the linear map ``offset + scale*x`` that maps
+    `old` to `new` such that ``old[i] -> new[i]``, ``i = 0, 1``.
+
+    Parameters
+    ----------
+    old, new : array_like
+        Domains. Each domain must (successfully) convert to a 1-d array
+        containing precisely two values.
+
+    Returns
+    -------
+    offset, scale : scalars
+        The map ``L(x) = offset + scale*x`` maps the first domain to the
+        second.
+
+    See Also
+    --------
+    getdomain, mapdomain
+
+    Notes
+    -----
+    Also works for complex numbers, and thus can be used to calculate the
+    parameters required to map any line in the complex plane to any other
+    line therein.
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> P.mapparms((-1,1),(-1,1))
+    (0.0, 1.0)
+    >>> P.mapparms((1,-1),(-1,1))
+    (0.0, -1.0)
+    >>> i = complex(0,1)
+    >>> P.mapparms((-i,-1),(1,i))
+    ((1+1j), (1+0j))
+
+    """
+    oldlen = old[1] - old[0]
+    newlen = new[1] - new[0]
+    off = (old[1]*new[0] - old[0]*new[1])/oldlen
+    scl = newlen/oldlen
+    return off, scl
+
+def mapdomain(x, old, new):
+    """
+    Apply linear map to input points.
+
+    The linear map ``offset + scale*x`` that maps the domain `old` to
+    the domain `new` is applied to the points `x`.
+
+    Parameters
+    ----------
+    x : array_like
+        Points to be mapped. If `x` is a subtype of ndarray the subtype
+        will be preserved.
+    old, new : array_like
+        The two domains that determine the map.  Each must (successfully)
+        convert to 1-d arrays containing precisely two values.
+
+    Returns
+    -------
+    x_out : ndarray
+        Array of points of the same shape as `x`, after application of the
+        linear map between the two domains.
+
+    See Also
+    --------
+    getdomain, mapparms
+
+    Notes
+    -----
+    Effectively, this implements:
+
+    .. math ::
+        x\\_out = new[0] + m(x - old[0])
+
+    where
+
+    .. math ::
+        m = \\frac{new[1]-new[0]}{old[1]-old[0]}
+
+    Examples
+    --------
+    >>> from numpy import polynomial as P
+    >>> old_domain = (-1,1)
+    >>> new_domain = (0,2*np.pi)
+    >>> x = np.linspace(-1,1,6); x
+    array([-1. , -0.6, -0.2,  0.2,  0.6,  1. ])
+    >>> x_out = P.mapdomain(x, old_domain, new_domain); x_out
+    array([ 0.        ,  1.25663706,  2.51327412,  3.76991118,  5.02654825,
+            6.28318531])
+    >>> x - P.mapdomain(x_out, new_domain, old_domain)
+    array([ 0.,  0.,  0.,  0.,  0.,  0.])
+
+    Also works for complex numbers (and thus can be used to map any line in
+    the complex plane to any other line therein).
+
+    >>> i = complex(0,1)
+    >>> old = (-1 - i, 1 + i)
+    >>> new = (-1 + i, 1 - i)
+    >>> z = np.linspace(old[0], old[1], 6); z
+    array([-1.0-1.j , -0.6-0.6j, -0.2-0.2j,  0.2+0.2j,  0.6+0.6j,  1.0+1.j ])
+    >>> new_z = P.mapdomain(z, old, new); new_z
+    array([-1.0+1.j , -0.6+0.6j, -0.2+0.2j,  0.2-0.2j,  0.6-0.6j,  1.0-1.j ])
+
+    """
+    x = np.asanyarray(x)
+    off, scl = mapparms(old, new)
+    return off + scl*x
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.py
new file mode 100644
index 0000000000..cb59ee1e56
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.py
@@ -0,0 +1,11 @@
+from __future__ import division, print_function
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('polynomial', parent_package, top_path)
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
new file mode 100644
index 0000000000..8d992c4f09
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
@@ -0,0 +1,585 @@
+"""Tests for chebyshev module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.chebyshev as cheb
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+def trim(x):
+    return cheb.chebtrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestPrivate(TestCase):
+
+    def test__cseries_to_zseries(self):
+        for i in range(5):
+            inp = np.array([2] + [1]*i, np.double)
+            tgt = np.array([.5]*i + [2] + [.5]*i, np.double)
+            res = cheb._cseries_to_zseries(inp)
+            assert_equal(res, tgt)
+
+    def test__zseries_to_cseries(self):
+        for i in range(5):
+            inp = np.array([.5]*i + [2] + [.5]*i, np.double)
+            tgt = np.array([2] + [1]*i, np.double)
+            res = cheb._zseries_to_cseries(inp)
+            assert_equal(res, tgt)
+
+
+class TestConstants(TestCase):
+
+    def test_chebdomain(self):
+        assert_equal(cheb.chebdomain, [-1, 1])
+
+    def test_chebzero(self):
+        assert_equal(cheb.chebzero, [0])
+
+    def test_chebone(self):
+        assert_equal(cheb.chebone, [1])
+
+    def test_chebx(self):
+        assert_equal(cheb.chebx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+
+    def test_chebadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = cheb.chebadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = cheb.chebsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebmulx(self):
+        assert_equal(cheb.chebmulx([0]), [0])
+        assert_equal(cheb.chebmulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [.5, 0, .5]
+            assert_equal(cheb.chebmulx(ser), tgt)
+
+    def test_chebmul(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(i + j + 1)
+                tgt[i + j] += .5
+                tgt[abs(i - j)] += .5
+                res = cheb.chebmul([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_chebdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = cheb.chebadd(ci, cj)
+                quo, rem = cheb.chebdiv(tgt, ci)
+                res = cheb.chebadd(cheb.chebmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2.5, 2., 1.5])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_chebval(self):
+        #check empty input
+        assert_equal(cheb.chebval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Tlist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = cheb.chebval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(cheb.chebval(x, [1]).shape, dims)
+            assert_equal(cheb.chebval(x, [1, 0]).shape, dims)
+            assert_equal(cheb.chebval(x, [1, 0, 0]).shape, dims)
+
+    def test_chebval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, cheb.chebval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = cheb.chebval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_chebval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, cheb.chebval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = cheb.chebval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_chebgrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = cheb.chebgrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebgrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_chebgrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = cheb.chebgrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = cheb.chebgrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_chebint(self):
+        # check exceptions
+        assert_raises(ValueError, cheb.chebint, [0], .5)
+        assert_raises(ValueError, cheb.chebint, [0], -1)
+        assert_raises(ValueError, cheb.chebint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = cheb.chebint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i])
+            res = cheb.cheb2poly(chebint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(cheb.chebval(-1, chebint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            chebpol = cheb.poly2cheb(pol)
+            chebint = cheb.chebint(chebpol, m=1, k=[i], scl=2)
+            res = cheb.cheb2poly(chebint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1)
+                res = cheb.chebint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k])
+                res = cheb.chebint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k], lbnd=-1)
+                res = cheb.chebint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = cheb.chebint(tgt, m=1, k=[k], scl=2)
+                res = cheb.chebint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([cheb.chebint(c) for c in c2d.T]).T
+        res = cheb.chebint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebint(c) for c in c2d])
+        res = cheb.chebint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebint(c, k=3) for c in c2d])
+        res = cheb.chebint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_chebder(self):
+        # check exceptions
+        assert_raises(ValueError, cheb.chebder, [0], .5)
+        assert_raises(ValueError, cheb.chebder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = cheb.chebder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = cheb.chebder(cheb.chebint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = cheb.chebder(cheb.chebint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([cheb.chebder(c) for c in c2d.T]).T
+        res = cheb.chebder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([cheb.chebder(c) for c in c2d])
+        res = cheb.chebder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_chebvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = cheb.chebvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = cheb.chebvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], cheb.chebval(x, coef))
+
+    def test_chebvander2d(self):
+        # also tests chebval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = cheb.chebvander2d(x1, x2, [1, 2])
+        tgt = cheb.chebval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = cheb.chebvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_chebvander3d(self):
+        # also tests chebval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = cheb.chebvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = cheb.chebval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = cheb.chebvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_chebfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, cheb.chebfit, [1], [1], -1)
+        assert_raises(TypeError, cheb.chebfit, [[1]], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, cheb.chebfit, [1, 2], [1], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [1, 2], 0)
+        assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, cheb.chebfit, [1], [1], [-1,])
+        assert_raises(ValueError, cheb.chebfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, cheb.chebfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = cheb.chebfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(cheb.chebval(x, coef3), y)
+        coef3 = cheb.chebfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(cheb.chebval(x, coef3), y)
+        #
+        coef4 = cheb.chebfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        coef4 = cheb.chebfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = cheb.chebfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(cheb.chebval(x, coef4), y)
+        #
+        coef2d = cheb.chebfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = cheb.chebfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = cheb.chebfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = cheb.chebfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(cheb.chebfit(x, x, 1), [0, 1])
+        assert_almost_equal(cheb.chebfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = cheb.chebfit(x, y, 4)
+        assert_almost_equal(cheb.chebval(x, coef1), y)
+        coef2 = cheb.chebfit(x, y, [0, 2, 4])
+        assert_almost_equal(cheb.chebval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, cheb.chebcompanion, [])
+        assert_raises(ValueError, cheb.chebcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(cheb.chebcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(cheb.chebcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = cheb.chebgauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = cheb.chebvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.pi
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_chebfromroots(self):
+        res = cheb.chebfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            tgt = [0]*i + [1]
+            res = cheb.chebfromroots(roots)*2**(i-1)
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebroots(self):
+        assert_almost_equal(cheb.chebroots([1]), [])
+        assert_almost_equal(cheb.chebroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = cheb.chebroots(cheb.chebfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_chebtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, cheb.chebtrim, coef, -1)
+
+        # Test results
+        assert_equal(cheb.chebtrim(coef), coef[:-1])
+        assert_equal(cheb.chebtrim(coef, 1), coef[:-3])
+        assert_equal(cheb.chebtrim(coef, 2), [0])
+
+    def test_chebline(self):
+        assert_equal(cheb.chebline(3, 4), [3, 4])
+
+    def test_cheb2poly(self):
+        for i in range(10):
+            assert_almost_equal(cheb.cheb2poly([0]*i + [1]), Tlist[i])
+
+    def test_poly2cheb(self):
+        for i in range(10):
+            assert_almost_equal(cheb.poly2cheb(Tlist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-1, 1, 11)[1:-1]
+        tgt = 1./(np.sqrt(1 + x) * np.sqrt(1 - x))
+        res = cheb.chebweight(x)
+        assert_almost_equal(res, tgt)
+
+    def test_chebpts1(self):
+        #test exceptions
+        assert_raises(ValueError, cheb.chebpts1, 1.5)
+        assert_raises(ValueError, cheb.chebpts1, 0)
+
+        #test points
+        tgt = [0]
+        assert_almost_equal(cheb.chebpts1(1), tgt)
+        tgt = [-0.70710678118654746, 0.70710678118654746]
+        assert_almost_equal(cheb.chebpts1(2), tgt)
+        tgt = [-0.86602540378443871, 0, 0.86602540378443871]
+        assert_almost_equal(cheb.chebpts1(3), tgt)
+        tgt = [-0.9238795325, -0.3826834323, 0.3826834323, 0.9238795325]
+        assert_almost_equal(cheb.chebpts1(4), tgt)
+
+    def test_chebpts2(self):
+        #test exceptions
+        assert_raises(ValueError, cheb.chebpts2, 1.5)
+        assert_raises(ValueError, cheb.chebpts2, 1)
+
+        #test points
+        tgt = [-1, 1]
+        assert_almost_equal(cheb.chebpts2(2), tgt)
+        tgt = [-1, 0, 1]
+        assert_almost_equal(cheb.chebpts2(3), tgt)
+        tgt = [-1, -0.5, .5, 1]
+        assert_almost_equal(cheb.chebpts2(4), tgt)
+        tgt = [-1.0, -0.707106781187, 0, 0.707106781187, 1.0]
+        assert_almost_equal(cheb.chebpts2(5), tgt)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
new file mode 100644
index 0000000000..a7cf7209c6
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
@@ -0,0 +1,579 @@
+"""Test inter-conversion of different polynomial classes.
+
+This tests the convert and cast methods of all the polynomial classes.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import operator as op
+from numbers import Number
+
+import numpy as np
+from numpy.polynomial import (
+    Polynomial, Legendre, Chebyshev, Laguerre, Hermite, HermiteE)
+from numpy.testing import (
+    assert_almost_equal, assert_raises, assert_equal, assert_,
+    run_module_suite)
+from numpy.compat import long
+
+
+classes = (
+    Polynomial, Legendre, Chebyshev, Laguerre,
+    Hermite, HermiteE)
+
+
+def test_class_methods():
+    for Poly1 in classes:
+        for Poly2 in classes:
+            yield check_conversion, Poly1, Poly2
+            yield check_cast, Poly1, Poly2
+    for Poly in classes:
+        yield check_call, Poly
+        yield check_identity, Poly
+        yield check_basis, Poly
+        yield check_fromroots, Poly
+        yield check_fit, Poly
+        yield check_equal, Poly
+        yield check_not_equal, Poly
+        yield check_add, Poly
+        yield check_sub, Poly
+        yield check_mul, Poly
+        yield check_floordiv, Poly
+        yield check_truediv, Poly
+        yield check_mod, Poly
+        yield check_divmod, Poly
+        yield check_pow, Poly
+        yield check_integ, Poly
+        yield check_deriv, Poly
+        yield check_roots, Poly
+        yield check_linspace, Poly
+        yield check_mapparms, Poly
+        yield check_degree, Poly
+        yield check_copy, Poly
+        yield check_cutdeg, Poly
+        yield check_truncate, Poly
+        yield check_trim, Poly
+
+
+#
+# helper functions
+#
+random = np.random.random
+
+
+def assert_poly_almost_equal(p1, p2, msg=""):
+    try:
+        assert_(np.all(p1.domain == p2.domain))
+        assert_(np.all(p1.window == p2.window))
+        assert_almost_equal(p1.coef, p2.coef)
+    except AssertionError:
+        msg = "Result: %s\nTarget: %s", (p1, p2)
+        raise AssertionError(msg)
+
+
+#
+# conversion methods that depend on two classes
+#
+
+
+def check_conversion(Poly1, Poly2):
+    x = np.linspace(0, 1, 10)
+    coef = random((3,))
+
+    d1 = Poly1.domain + random((2,))*.25
+    w1 = Poly1.window + random((2,))*.25
+    p1 = Poly1(coef, domain=d1, window=w1)
+
+    d2 = Poly2.domain + random((2,))*.25
+    w2 = Poly2.window + random((2,))*.25
+    p2 = p1.convert(kind=Poly2, domain=d2, window=w2)
+
+    assert_almost_equal(p2.domain, d2)
+    assert_almost_equal(p2.window, w2)
+    assert_almost_equal(p2(x), p1(x))
+
+
+def check_cast(Poly1, Poly2):
+    x = np.linspace(0, 1, 10)
+    coef = random((3,))
+
+    d1 = Poly1.domain + random((2,))*.25
+    w1 = Poly1.window + random((2,))*.25
+    p1 = Poly1(coef, domain=d1, window=w1)
+
+    d2 = Poly2.domain + random((2,))*.25
+    w2 = Poly2.window + random((2,))*.25
+    p2 = Poly2.cast(p1, domain=d2, window=w2)
+
+    assert_almost_equal(p2.domain, d2)
+    assert_almost_equal(p2.window, w2)
+    assert_almost_equal(p2(x), p1(x))
+
+
+#
+# methods that depend on one class
+#
+
+
+def check_identity(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    x = np.linspace(d[0], d[1], 11)
+    p = Poly.identity(domain=d, window=w)
+    assert_equal(p.domain, d)
+    assert_equal(p.window, w)
+    assert_almost_equal(p(x), x)
+
+
+def check_basis(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly.basis(5, domain=d, window=w)
+    assert_equal(p.domain, d)
+    assert_equal(p.window, w)
+    assert_equal(p.coef, [0]*5 + [1])
+
+
+def check_fromroots(Poly):
+    # check that requested roots are zeros of a polynomial
+    # of correct degree, domain, and window.
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    r = random((5,))
+    p1 = Poly.fromroots(r, domain=d, window=w)
+    assert_equal(p1.degree(), len(r))
+    assert_equal(p1.domain, d)
+    assert_equal(p1.window, w)
+    assert_almost_equal(p1(r), 0)
+
+    # check that polynomial is monic
+    pdom = Polynomial.domain
+    pwin = Polynomial.window
+    p2 = Polynomial.cast(p1, domain=pdom, window=pwin)
+    assert_almost_equal(p2.coef[-1], 1)
+
+
+def check_fit(Poly):
+
+    def f(x):
+        return x*(x - 1)*(x - 2)
+    x = np.linspace(0, 3)
+    y = f(x)
+
+    # check default value of domain and window
+    p = Poly.fit(x, y, 3)
+    assert_almost_equal(p.domain, [0, 3])
+    assert_almost_equal(p(x), y)
+    assert_equal(p.degree(), 3)
+
+    # check with given domains and window
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly.fit(x, y, 3, domain=d, window=w)
+    assert_almost_equal(p(x), y)
+    assert_almost_equal(p.domain, d)
+    assert_almost_equal(p.window, w)
+    p = Poly.fit(x, y, [0, 1, 2, 3], domain=d, window=w)
+    assert_almost_equal(p(x), y)
+    assert_almost_equal(p.domain, d)
+    assert_almost_equal(p.window, w)
+
+    # check with class domain default
+    p = Poly.fit(x, y, 3, [])
+    assert_equal(p.domain, Poly.domain)
+    assert_equal(p.window, Poly.window)
+    p = Poly.fit(x, y, [0, 1, 2, 3], [])
+    assert_equal(p.domain, Poly.domain)
+    assert_equal(p.window, Poly.window)
+
+    # check that fit accepts weights.
+    w = np.zeros_like(x)
+    z = y + random(y.shape)*.25
+    w[::2] = 1
+    p1 = Poly.fit(x[::2], z[::2], 3)
+    p2 = Poly.fit(x, z, 3, w=w)
+    p3 = Poly.fit(x, z, [0, 1, 2, 3], w=w)
+    assert_almost_equal(p1(x), p2(x))
+    assert_almost_equal(p2(x), p3(x))
+
+
+def check_equal(Poly):
+    p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+    p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+    p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+    p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+    assert_(p1 == p1)
+    assert_(not p1 == p2)
+    assert_(not p1 == p3)
+    assert_(not p1 == p4)
+
+
+def check_not_equal(Poly):
+    p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
+    p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
+    p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
+    p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
+    assert_(not p1 != p1)
+    assert_(p1 != p2)
+    assert_(p1 != p3)
+    assert_(p1 != p4)
+
+
+def check_add(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 + p2
+    assert_poly_almost_equal(p2 + p1, p3)
+    assert_poly_almost_equal(p1 + c2, p3)
+    assert_poly_almost_equal(c2 + p1, p3)
+    assert_poly_almost_equal(p1 + tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) + p1, p3)
+    assert_poly_almost_equal(p1 + np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) + p1, p3)
+    assert_raises(TypeError, op.add, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.add, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.add, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.add, p1, Polynomial([0]))
+
+
+def check_sub(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 - p2
+    assert_poly_almost_equal(p2 - p1, -p3)
+    assert_poly_almost_equal(p1 - c2, p3)
+    assert_poly_almost_equal(c2 - p1, -p3)
+    assert_poly_almost_equal(p1 - tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) - p1, -p3)
+    assert_poly_almost_equal(p1 - np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) - p1, -p3)
+    assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.sub, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.sub, p1, Polynomial([0]))
+
+
+def check_mul(Poly):
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = p1 * p2
+    assert_poly_almost_equal(p2 * p1, p3)
+    assert_poly_almost_equal(p1 * c2, p3)
+    assert_poly_almost_equal(c2 * p1, p3)
+    assert_poly_almost_equal(p1 * tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c2) * p1, p3)
+    assert_poly_almost_equal(p1 * np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c2) * p1, p3)
+    assert_poly_almost_equal(p1 * 2, p1 * Poly([2]))
+    assert_poly_almost_equal(2 * p1, p1 * Poly([2]))
+    assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.mul, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.mul, p1, Polynomial([0]))
+
+
+def check_floordiv(Poly):
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    assert_poly_almost_equal(p4 // p2, p1)
+    assert_poly_almost_equal(p4 // c2, p1)
+    assert_poly_almost_equal(c4 // p2, p1)
+    assert_poly_almost_equal(p4 // tuple(c2), p1)
+    assert_poly_almost_equal(tuple(c4) // p2, p1)
+    assert_poly_almost_equal(p4 // np.array(c2), p1)
+    assert_poly_almost_equal(np.array(c4) // p2, p1)
+    assert_poly_almost_equal(2 // p2, Poly([0]))
+    assert_poly_almost_equal(p2 // 2, 0.5*p2)
+    assert_raises(
+        TypeError, op.floordiv, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(
+        TypeError, op.floordiv, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.floordiv, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.floordiv, p1, Polynomial([0]))
+
+
+def check_truediv(Poly):
+    # true division is valid only if the denominator is a Number and
+    # not a python bool.
+    p1 = Poly([1,2,3])
+    p2 = p1 * 5
+
+    for stype in np.ScalarType:
+        if not issubclass(stype, Number) or issubclass(stype, bool):
+            continue
+        s = stype(5)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for stype in (int, long, float):
+        s = stype(5)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for stype in [complex]:
+        s = stype(5, 0)
+        assert_poly_almost_equal(op.truediv(p2, s), p1)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for s in [tuple(), list(), dict(), bool(), np.array([1])]:
+        assert_raises(TypeError, op.truediv, p2, s)
+        assert_raises(TypeError, op.truediv, s, p2)
+    for ptype in classes:
+        assert_raises(TypeError, op.truediv, p2, ptype(1))
+
+
+def check_mod(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    assert_poly_almost_equal(p4 % p2, p3)
+    assert_poly_almost_equal(p4 % c2, p3)
+    assert_poly_almost_equal(c4 % p2, p3)
+    assert_poly_almost_equal(p4 % tuple(c2), p3)
+    assert_poly_almost_equal(tuple(c4) % p2, p3)
+    assert_poly_almost_equal(p4 % np.array(c2), p3)
+    assert_poly_almost_equal(np.array(c4) % p2, p3)
+    assert_poly_almost_equal(2 % p2, Poly([2]))
+    assert_poly_almost_equal(p2 % 2, Poly([0]))
+    assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, op.mod, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, op.mod, p1, Polynomial([0]))
+
+
+def check_divmod(Poly):
+    # This checks commutation, not numerical correctness
+    c1 = list(random((4,)) + .5)
+    c2 = list(random((3,)) + .5)
+    c3 = list(random((2,)) + .5)
+    p1 = Poly(c1)
+    p2 = Poly(c2)
+    p3 = Poly(c3)
+    p4 = p1 * p2 + p3
+    c4 = list(p4.coef)
+    quo, rem = divmod(p4, p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, c2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(c4, p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, tuple(c2))
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(tuple(c4), p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p4, np.array(c2))
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(np.array(c4), p2)
+    assert_poly_almost_equal(quo, p1)
+    assert_poly_almost_equal(rem, p3)
+    quo, rem = divmod(p2, 2)
+    assert_poly_almost_equal(quo, 0.5*p2)
+    assert_poly_almost_equal(rem, Poly([0]))
+    quo, rem = divmod(2, p2)
+    assert_poly_almost_equal(quo, Poly([0]))
+    assert_poly_almost_equal(rem, Poly([2]))
+    assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1))
+    assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1))
+    if Poly is Polynomial:
+        assert_raises(TypeError, divmod, p1, Chebyshev([0]))
+    else:
+        assert_raises(TypeError, divmod, p1, Polynomial([0]))
+
+
+def check_roots(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    tgt = np.sort(random((5,)))
+    res = np.sort(Poly.fromroots(tgt, domain=d, window=w).roots())
+    assert_almost_equal(res, tgt)
+    # default domain and window
+    res = np.sort(Poly.fromroots(tgt).roots())
+    assert_almost_equal(res, tgt)
+
+
+def check_degree(Poly):
+    p = Poly.basis(5)
+    assert_equal(p.degree(), 5)
+
+
+def check_copy(Poly):
+    p1 = Poly.basis(5)
+    p2 = p1.copy()
+    assert_(p1 == p2)
+    assert_(p1 is not p2)
+    assert_(p1.coef is not p2.coef)
+    assert_(p1.domain is not p2.domain)
+    assert_(p1.window is not p2.window)
+
+
+def check_integ(Poly):
+    P = Polynomial
+    # Check defaults
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ())
+    p2 = P.cast(p0.integ(2))
+    assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+    # Check with k
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ(k=1))
+    p2 = P.cast(p0.integ(2, k=[1, 1]))
+    assert_poly_almost_equal(p1, P([1, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([1, 1, 1, 1, 1]))
+    # Check with lbnd
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]))
+    p1 = P.cast(p0.integ(lbnd=1))
+    p2 = P.cast(p0.integ(2, lbnd=1))
+    assert_poly_almost_equal(p1, P([-9, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([6, -9, 1, 1, 1]))
+    # Check scaling
+    d = 2*Poly.domain
+    p0 = Poly.cast(P([1*2, 2*3, 3*4]), domain=d)
+    p1 = P.cast(p0.integ())
+    p2 = P.cast(p0.integ(2))
+    assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
+    assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
+
+
+def check_deriv(Poly):
+    # Check that the derivative is the inverse of integration. It is
+    # assumes that the integration has been checked elsewhere.
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p1 = Poly([1, 2, 3], domain=d, window=w)
+    p2 = p1.integ(2, k=[1, 2])
+    p3 = p1.integ(1, k=[1])
+    assert_almost_equal(p2.deriv(1).coef, p3.coef)
+    assert_almost_equal(p2.deriv(2).coef, p1.coef)
+    # default domain and window
+    p1 = Poly([1, 2, 3])
+    p2 = p1.integ(2, k=[1, 2])
+    p3 = p1.integ(1, k=[1])
+    assert_almost_equal(p2.deriv(1).coef, p3.coef)
+    assert_almost_equal(p2.deriv(2).coef, p1.coef)
+
+
+def check_linspace(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    p = Poly([1, 2, 3], domain=d, window=w)
+    # check default domain
+    xtgt = np.linspace(d[0], d[1], 20)
+    ytgt = p(xtgt)
+    xres, yres = p.linspace(20)
+    assert_almost_equal(xres, xtgt)
+    assert_almost_equal(yres, ytgt)
+    # check specified domain
+    xtgt = np.linspace(0, 2, 20)
+    ytgt = p(xtgt)
+    xres, yres = p.linspace(20, domain=[0, 2])
+    assert_almost_equal(xres, xtgt)
+    assert_almost_equal(yres, ytgt)
+
+
+def check_pow(Poly):
+    d = Poly.domain + random((2,))*.25
+    w = Poly.window + random((2,))*.25
+    tgt = Poly([1], domain=d, window=w)
+    tst = Poly([1, 2, 3], domain=d, window=w)
+    for i in range(5):
+        assert_poly_almost_equal(tst**i, tgt)
+        tgt = tgt * tst
+    # default domain and window
+    tgt = Poly([1])
+    tst = Poly([1, 2, 3])
+    for i in range(5):
+        assert_poly_almost_equal(tst**i, tgt)
+        tgt = tgt * tst
+    # check error for invalid powers
+    assert_raises(ValueError, op.pow, tgt, 1.5)
+    assert_raises(ValueError, op.pow, tgt, -1)
+
+
+def check_call(Poly):
+    P = Polynomial
+    d = Poly.domain
+    x = np.linspace(d[0], d[1], 11)
+
+    # Check defaults
+    p = Poly.cast(P([1, 2, 3]))
+    tgt = 1 + x*(2 + 3*x)
+    res = p(x)
+    assert_almost_equal(res, tgt)
+
+
+def check_cutdeg(Poly):
+    p = Poly([1, 2, 3])
+    assert_raises(ValueError, p.cutdeg, .5)
+    assert_raises(ValueError, p.cutdeg, -1)
+    assert_equal(len(p.cutdeg(3)), 3)
+    assert_equal(len(p.cutdeg(2)), 3)
+    assert_equal(len(p.cutdeg(1)), 2)
+    assert_equal(len(p.cutdeg(0)), 1)
+
+
+def check_truncate(Poly):
+    p = Poly([1, 2, 3])
+    assert_raises(ValueError, p.truncate, .5)
+    assert_raises(ValueError, p.truncate, 0)
+    assert_equal(len(p.truncate(4)), 3)
+    assert_equal(len(p.truncate(3)), 3)
+    assert_equal(len(p.truncate(2)), 2)
+    assert_equal(len(p.truncate(1)), 1)
+
+
+def check_trim(Poly):
+    c = [1, 1e-6, 1e-12, 0]
+    p = Poly(c)
+    assert_equal(p.trim().coef, c[:3])
+    assert_equal(p.trim(1e-10).coef, c[:2])
+    assert_equal(p.trim(1e-5).coef, c[:1])
+
+
+def check_mapparms(Poly):
+    # check with defaults. Should be identity.
+    d = Poly.domain
+    w = Poly.window
+    p = Poly([1], domain=d, window=w)
+    assert_almost_equal([0, 1], p.mapparms())
+    #
+    w = 2*d + 1
+    p = Poly([1], domain=d, window=w)
+    assert_almost_equal([1, 2], p.mapparms())
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
new file mode 100644
index 0000000000..04da72b265
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
@@ -0,0 +1,547 @@
+"""Tests for hermite module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.hermite as herm
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+H0 = np.array([1])
+H1 = np.array([0, 2])
+H2 = np.array([-2, 0, 4])
+H3 = np.array([0, -12, 0, 8])
+H4 = np.array([12, 0, -48, 0, 16])
+H5 = np.array([0, 120, 0, -160, 0, 32])
+H6 = np.array([-120, 0, 720, 0, -480, 0, 64])
+H7 = np.array([0, -1680, 0, 3360, 0, -1344, 0, 128])
+H8 = np.array([1680, 0, -13440, 0, 13440, 0, -3584, 0, 256])
+H9 = np.array([0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512])
+
+Hlist = [H0, H1, H2, H3, H4, H5, H6, H7, H8, H9]
+
+
+def trim(x):
+    return herm.hermtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_hermdomain(self):
+        assert_equal(herm.hermdomain, [-1, 1])
+
+    def test_hermzero(self):
+        assert_equal(herm.hermzero, [0])
+
+    def test_hermone(self):
+        assert_equal(herm.hermone, [1])
+
+    def test_hermx(self):
+        assert_equal(herm.hermx, [0, .5])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_hermadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = herm.hermadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = herm.hermsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermmulx(self):
+        assert_equal(herm.hermmulx([0]), [0])
+        assert_equal(herm.hermmulx([1]), [0, .5])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i, 0, .5]
+            assert_equal(herm.hermmulx(ser), tgt)
+
+    def test_hermmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = herm.hermval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = herm.hermval(self.x, pol2)
+                pol3 = herm.hermmul(pol1, pol2)
+                val3 = herm.hermval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_hermdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = herm.hermadd(ci, cj)
+                quo, rem = herm.hermdiv(tgt, ci)
+                res = herm.hermadd(herm.hermmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2.5, 1., .75])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_hermval(self):
+        #check empty input
+        assert_equal(herm.hermval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Hlist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = herm.hermval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(herm.hermval(x, [1]).shape, dims)
+            assert_equal(herm.hermval(x, [1, 0]).shape, dims)
+            assert_equal(herm.hermval(x, [1, 0, 0]).shape, dims)
+
+    def test_hermval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herm.hermval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = herm.hermval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herm.hermval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = herm.hermval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermgrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = herm.hermgrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermgrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_hermgrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = herm.hermgrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herm.hermgrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_hermint(self):
+        # check exceptions
+        assert_raises(ValueError, herm.hermint, [0], .5)
+        assert_raises(ValueError, herm.hermint, [0], -1)
+        assert_raises(ValueError, herm.hermint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = herm.hermint([0], m=i, k=k)
+            assert_almost_equal(res, [0, .5])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i])
+            res = herm.herm2poly(hermint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(herm.hermval(-1, hermint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            hermpol = herm.poly2herm(pol)
+            hermint = herm.hermint(hermpol, m=1, k=[i], scl=2)
+            res = herm.herm2poly(hermint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1)
+                res = herm.hermint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k])
+                res = herm.hermint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k], lbnd=-1)
+                res = herm.hermint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herm.hermint(tgt, m=1, k=[k], scl=2)
+                res = herm.hermint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herm.hermint(c) for c in c2d.T]).T
+        res = herm.hermint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermint(c) for c in c2d])
+        res = herm.hermint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermint(c, k=3) for c in c2d])
+        res = herm.hermint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_hermder(self):
+        # check exceptions
+        assert_raises(ValueError, herm.hermder, [0], .5)
+        assert_raises(ValueError, herm.hermder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = herm.hermder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herm.hermder(herm.hermint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herm.hermder(herm.hermint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herm.hermder(c) for c in c2d.T]).T
+        res = herm.hermder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herm.hermder(c) for c in c2d])
+        res = herm.hermder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_hermvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = herm.hermvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = herm.hermvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herm.hermval(x, coef))
+
+    def test_hermvander2d(self):
+        # also tests hermval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = herm.hermvander2d(x1, x2, [1, 2])
+        tgt = herm.hermval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herm.hermvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_hermvander3d(self):
+        # also tests hermval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = herm.hermvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = herm.hermval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herm.hermvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_hermfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, herm.hermfit, [1], [1], -1)
+        assert_raises(TypeError, herm.hermfit, [[1]], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, herm.hermfit, [1, 2], [1], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [1, 2], 0)
+        assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, herm.hermfit, [1], [1], [-1,])
+        assert_raises(ValueError, herm.hermfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, herm.hermfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = herm.hermfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herm.hermval(x, coef3), y)
+        coef3 = herm.hermfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herm.hermval(x, coef3), y)
+        #
+        coef4 = herm.hermfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        coef4 = herm.hermfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = herm.hermfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herm.hermval(x, coef4), y)
+        #
+        coef2d = herm.hermfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = herm.hermfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = herm.hermfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = herm.hermfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(herm.hermfit(x, x, 1), [0, .5])
+        assert_almost_equal(herm.hermfit(x, x, [0, 1]), [0, .5])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = herm.hermfit(x, y, 4)
+        assert_almost_equal(herm.hermval(x, coef1), y)
+        coef2 = herm.hermfit(x, y, [0, 2, 4])
+        assert_almost_equal(herm.hermval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, herm.hermcompanion, [])
+        assert_raises(ValueError, herm.hermcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(herm.hermcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(herm.hermcompanion([1, 2])[0, 0] == -.25)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = herm.hermgauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = herm.hermvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.sqrt(np.pi)
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_hermfromroots(self):
+        res = herm.hermfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = herm.hermfromroots(roots)
+            res = herm.hermval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(herm.herm2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_hermroots(self):
+        assert_almost_equal(herm.hermroots([1]), [])
+        assert_almost_equal(herm.hermroots([1, 1]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = herm.hermroots(herm.hermfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, herm.hermtrim, coef, -1)
+
+        # Test results
+        assert_equal(herm.hermtrim(coef), coef[:-1])
+        assert_equal(herm.hermtrim(coef, 1), coef[:-3])
+        assert_equal(herm.hermtrim(coef, 2), [0])
+
+    def test_hermline(self):
+        assert_equal(herm.hermline(3, 4), [3, 2])
+
+    def test_herm2poly(self):
+        for i in range(10):
+            assert_almost_equal(herm.herm2poly([0]*i + [1]), Hlist[i])
+
+    def test_poly2herm(self):
+        for i in range(10):
+            assert_almost_equal(herm.poly2herm(Hlist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-5, 5, 11)
+        tgt = np.exp(-x**2)
+        res = herm.hermweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
new file mode 100644
index 0000000000..1162502dc5
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
@@ -0,0 +1,548 @@
+"""Tests for hermite_e module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.hermite_e as herme
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+He0 = np.array([1])
+He1 = np.array([0, 1])
+He2 = np.array([-1, 0, 1])
+He3 = np.array([0, -3, 0, 1])
+He4 = np.array([3, 0, -6, 0, 1])
+He5 = np.array([0, 15, 0, -10, 0, 1])
+He6 = np.array([-15, 0, 45, 0, -15, 0, 1])
+He7 = np.array([0, -105, 0, 105, 0, -21, 0, 1])
+He8 = np.array([105, 0, -420, 0, 210, 0, -28, 0, 1])
+He9 = np.array([0, 945, 0, -1260, 0, 378, 0, -36, 0, 1])
+
+Helist = [He0, He1, He2, He3, He4, He5, He6, He7, He8, He9]
+
+
+def trim(x):
+    return herme.hermetrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_hermedomain(self):
+        assert_equal(herme.hermedomain, [-1, 1])
+
+    def test_hermezero(self):
+        assert_equal(herme.hermezero, [0])
+
+    def test_hermeone(self):
+        assert_equal(herme.hermeone, [1])
+
+    def test_hermex(self):
+        assert_equal(herme.hermex, [0, 1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_hermeadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = herme.hermeadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermesub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = herme.hermesub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_hermemulx(self):
+        assert_equal(herme.hermemulx([0]), [0])
+        assert_equal(herme.hermemulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i, 0, 1]
+            assert_equal(herme.hermemulx(ser), tgt)
+
+    def test_hermemul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = herme.hermeval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = herme.hermeval(self.x, pol2)
+                pol3 = herme.hermemul(pol1, pol2)
+                val3 = herme.hermeval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_hermediv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = herme.hermeadd(ci, cj)
+                quo, rem = herme.hermediv(tgt, ci)
+                res = herme.hermeadd(herme.hermemul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([4., 2., 3.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_hermeval(self):
+        #check empty input
+        assert_equal(herme.hermeval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Helist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = herme.hermeval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(herme.hermeval(x, [1]).shape, dims)
+            assert_equal(herme.hermeval(x, [1, 0]).shape, dims)
+            assert_equal(herme.hermeval(x, [1, 0, 0]).shape, dims)
+
+    def test_hermeval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herme.hermeval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = herme.hermeval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermeval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermeval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, herme.hermeval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = herme.hermeval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermeval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_hermegrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = herme.hermegrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermegrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_hermegrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = herme.hermegrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = herme.hermegrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_hermeint(self):
+        # check exceptions
+        assert_raises(ValueError, herme.hermeint, [0], .5)
+        assert_raises(ValueError, herme.hermeint, [0], -1)
+        assert_raises(ValueError, herme.hermeint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = herme.hermeint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i])
+            res = herme.herme2poly(hermeint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(herme.hermeval(-1, hermeint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            hermepol = herme.poly2herme(pol)
+            hermeint = herme.hermeint(hermepol, m=1, k=[i], scl=2)
+            res = herme.herme2poly(hermeint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1)
+                res = herme.hermeint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k])
+                res = herme.hermeint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k], lbnd=-1)
+                res = herme.hermeint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = herme.hermeint(tgt, m=1, k=[k], scl=2)
+                res = herme.hermeint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermeint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herme.hermeint(c) for c in c2d.T]).T
+        res = herme.hermeint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeint(c) for c in c2d])
+        res = herme.hermeint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeint(c, k=3) for c in c2d])
+        res = herme.hermeint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_hermeder(self):
+        # check exceptions
+        assert_raises(ValueError, herme.hermeder, [0], .5)
+        assert_raises(ValueError, herme.hermeder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = herme.hermeder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herme.hermeder(herme.hermeint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = herme.hermeder(
+                    herme.hermeint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermeder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([herme.hermeder(c) for c in c2d.T]).T
+        res = herme.hermeder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([herme.hermeder(c) for c in c2d])
+        res = herme.hermeder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_hermevander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = herme.hermevander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = herme.hermevander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], herme.hermeval(x, coef))
+
+    def test_hermevander2d(self):
+        # also tests hermeval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = herme.hermevander2d(x1, x2, [1, 2])
+        tgt = herme.hermeval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herme.hermevander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_hermevander3d(self):
+        # also tests hermeval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = herme.hermevander3d(x1, x2, x3, [1, 2, 3])
+        tgt = herme.hermeval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = herme.hermevander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_hermefit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, herme.hermefit, [1], [1], -1)
+        assert_raises(TypeError, herme.hermefit, [[1]], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [[[1]]], 0)
+        assert_raises(TypeError, herme.hermefit, [1, 2], [1], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [1, 2], 0)
+        assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, herme.hermefit, [1], [1], [-1,])
+        assert_raises(ValueError, herme.hermefit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, herme.hermefit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = herme.hermefit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herme.hermeval(x, coef3), y)
+        coef3 = herme.hermefit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(herme.hermeval(x, coef3), y)
+        #
+        coef4 = herme.hermefit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        coef4 = herme.hermefit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = herme.hermefit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(herme.hermeval(x, coef4), y)
+        #
+        coef2d = herme.hermefit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = herme.hermefit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = herme.hermefit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = herme.hermefit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(herme.hermefit(x, x, 1), [0, 1])
+        assert_almost_equal(herme.hermefit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = herme.hermefit(x, y, 4)
+        assert_almost_equal(herme.hermeval(x, coef1), y)
+        coef2 = herme.hermefit(x, y, [0, 2, 4])
+        assert_almost_equal(herme.hermeval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, herme.hermecompanion, [])
+        assert_raises(ValueError, herme.hermecompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(herme.hermecompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(herme.hermecompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = herme.hermegauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = herme.hermevander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = np.sqrt(2*np.pi)
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_hermefromroots(self):
+        res = herme.hermefromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = herme.hermefromroots(roots)
+            res = herme.hermeval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(herme.herme2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_hermeroots(self):
+        assert_almost_equal(herme.hermeroots([1]), [])
+        assert_almost_equal(herme.hermeroots([1, 1]), [-1])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = herme.hermeroots(herme.hermefromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_hermetrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, herme.hermetrim, coef, -1)
+
+        # Test results
+        assert_equal(herme.hermetrim(coef), coef[:-1])
+        assert_equal(herme.hermetrim(coef, 1), coef[:-3])
+        assert_equal(herme.hermetrim(coef, 2), [0])
+
+    def test_hermeline(self):
+        assert_equal(herme.hermeline(3, 4), [3, 4])
+
+    def test_herme2poly(self):
+        for i in range(10):
+            assert_almost_equal(herme.herme2poly([0]*i + [1]), Helist[i])
+
+    def test_poly2herme(self):
+        for i in range(10):
+            assert_almost_equal(herme.poly2herme(Helist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-5, 5, 11)
+        tgt = np.exp(-.5*x**2)
+        res = herme.hermeweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
new file mode 100644
index 0000000000..c254760888
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
@@ -0,0 +1,529 @@
+"""Tests for laguerre module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.laguerre as lag
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+L0 = np.array([1])/1
+L1 = np.array([1, -1])/1
+L2 = np.array([2, -4, 1])/2
+L3 = np.array([6, -18, 9, -1])/6
+L4 = np.array([24, -96, 72, -16, 1])/24
+L5 = np.array([120, -600, 600, -200, 25, -1])/120
+L6 = np.array([720, -4320, 5400, -2400, 450, -36, 1])/720
+
+Llist = [L0, L1, L2, L3, L4, L5, L6]
+
+
+def trim(x):
+    return lag.lagtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_lagdomain(self):
+        assert_equal(lag.lagdomain, [0, 1])
+
+    def test_lagzero(self):
+        assert_equal(lag.lagzero, [0])
+
+    def test_lagone(self):
+        assert_equal(lag.lagone, [1])
+
+    def test_lagx(self):
+        assert_equal(lag.lagx, [1, -1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-3, 3, 100)
+
+    def test_lagadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = lag.lagadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_lagsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = lag.lagsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_lagmulx(self):
+        assert_equal(lag.lagmulx([0]), [0])
+        assert_equal(lag.lagmulx([1]), [1, -1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [-i, 2*i + 1, -(i + 1)]
+            assert_almost_equal(lag.lagmulx(ser), tgt)
+
+    def test_lagmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = lag.lagval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = lag.lagval(self.x, pol2)
+                pol3 = lag.lagmul(pol1, pol2)
+                val3 = lag.lagval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_lagdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = lag.lagadd(ci, cj)
+                quo, rem = lag.lagdiv(tgt, ci)
+                res = lag.lagadd(lag.lagmul(quo, ci), rem)
+                assert_almost_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([9., -14., 6.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_lagval(self):
+        #check empty input
+        assert_equal(lag.lagval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Llist]
+        for i in range(7):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = lag.lagval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(lag.lagval(x, [1]).shape, dims)
+            assert_equal(lag.lagval(x, [1, 0]).shape, dims)
+            assert_equal(lag.lagval(x, [1, 0, 0]).shape, dims)
+
+    def test_lagval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, lag.lagval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = lag.lagval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.lagval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_lagval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, lag.lagval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = lag.lagval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.lagval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_laggrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = lag.laggrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.laggrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_laggrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = lag.laggrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = lag.laggrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_lagint(self):
+        # check exceptions
+        assert_raises(ValueError, lag.lagint, [0], .5)
+        assert_raises(ValueError, lag.lagint, [0], -1)
+        assert_raises(ValueError, lag.lagint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = lag.lagint([0], m=i, k=k)
+            assert_almost_equal(res, [1, -1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i])
+            res = lag.lag2poly(lagint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(lag.lagval(-1, lagint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            lagpol = lag.poly2lag(pol)
+            lagint = lag.lagint(lagpol, m=1, k=[i], scl=2)
+            res = lag.lag2poly(lagint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1)
+                res = lag.lagint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k])
+                res = lag.lagint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k], lbnd=-1)
+                res = lag.lagint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = lag.lagint(tgt, m=1, k=[k], scl=2)
+                res = lag.lagint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([lag.lagint(c) for c in c2d.T]).T
+        res = lag.lagint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagint(c) for c in c2d])
+        res = lag.lagint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagint(c, k=3) for c in c2d])
+        res = lag.lagint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_lagder(self):
+        # check exceptions
+        assert_raises(ValueError, lag.lagder, [0], .5)
+        assert_raises(ValueError, lag.lagder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = lag.lagder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = lag.lagder(lag.lagint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = lag.lagder(lag.lagint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([lag.lagder(c) for c in c2d.T]).T
+        res = lag.lagder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([lag.lagder(c) for c in c2d])
+        res = lag.lagder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_lagvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = lag.lagvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = lag.lagvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], lag.lagval(x, coef))
+
+    def test_lagvander2d(self):
+        # also tests lagval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = lag.lagvander2d(x1, x2, [1, 2])
+        tgt = lag.lagval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = lag.lagvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_lagvander3d(self):
+        # also tests lagval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = lag.lagvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = lag.lagval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = lag.lagvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_lagfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        # Test exceptions
+        assert_raises(ValueError, lag.lagfit, [1], [1], -1)
+        assert_raises(TypeError, lag.lagfit, [[1]], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, lag.lagfit, [1, 2], [1], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [1, 2], 0)
+        assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, lag.lagfit, [1], [1], [-1,])
+        assert_raises(ValueError, lag.lagfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, lag.lagfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = lag.lagfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(lag.lagval(x, coef3), y)
+        coef3 = lag.lagfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(lag.lagval(x, coef3), y)
+        #
+        coef4 = lag.lagfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(lag.lagval(x, coef4), y)
+        coef4 = lag.lagfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(lag.lagval(x, coef4), y)
+        #
+        coef2d = lag.lagfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = lag.lagfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = lag.lagfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = lag.lagfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(lag.lagfit(x, x, 1), [1, -1])
+        assert_almost_equal(lag.lagfit(x, x, [0, 1]), [1, -1])
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, lag.lagcompanion, [])
+        assert_raises(ValueError, lag.lagcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(lag.lagcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(lag.lagcompanion([1, 2])[0, 0] == 1.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = lag.laggauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = lag.lagvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = 1.0
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_lagfromroots(self):
+        res = lag.lagfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = lag.lagfromroots(roots)
+            res = lag.lagval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(lag.lag2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_lagroots(self):
+        assert_almost_equal(lag.lagroots([1]), [])
+        assert_almost_equal(lag.lagroots([0, 1]), [1])
+        for i in range(2, 5):
+            tgt = np.linspace(0, 3, i)
+            res = lag.lagroots(lag.lagfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_lagtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, lag.lagtrim, coef, -1)
+
+        # Test results
+        assert_equal(lag.lagtrim(coef), coef[:-1])
+        assert_equal(lag.lagtrim(coef, 1), coef[:-3])
+        assert_equal(lag.lagtrim(coef, 2), [0])
+
+    def test_lagline(self):
+        assert_equal(lag.lagline(3, 4), [7, -4])
+
+    def test_lag2poly(self):
+        for i in range(7):
+            assert_almost_equal(lag.lag2poly([0]*i + [1]), Llist[i])
+
+    def test_poly2lag(self):
+        for i in range(7):
+            assert_almost_equal(lag.poly2lag(Llist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(0, 10, 11)
+        tgt = np.exp(-x)
+        res = lag.lagweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
new file mode 100644
index 0000000000..9c259d14c4
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
@@ -0,0 +1,548 @@
+"""Tests for legendre module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.legendre as leg
+from numpy.polynomial.polynomial import polyval
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+L0 = np.array([1])
+L1 = np.array([0, 1])
+L2 = np.array([-1, 0, 3])/2
+L3 = np.array([0, -3, 0, 5])/2
+L4 = np.array([3, 0, -30, 0, 35])/8
+L5 = np.array([0, 15, 0, -70, 0, 63])/8
+L6 = np.array([-5, 0, 105, 0, -315, 0, 231])/16
+L7 = np.array([0, -35, 0, 315, 0, -693, 0, 429])/16
+L8 = np.array([35, 0, -1260, 0, 6930, 0, -12012, 0, 6435])/128
+L9 = np.array([0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155])/128
+
+Llist = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9]
+
+
+def trim(x):
+    return leg.legtrim(x, tol=1e-6)
+
+
+class TestConstants(TestCase):
+
+    def test_legdomain(self):
+        assert_equal(leg.legdomain, [-1, 1])
+
+    def test_legzero(self):
+        assert_equal(leg.legzero, [0])
+
+    def test_legone(self):
+        assert_equal(leg.legone, [1])
+
+    def test_legx(self):
+        assert_equal(leg.legx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+    x = np.linspace(-1, 1, 100)
+
+    def test_legadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = leg.legadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_legsub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = leg.legsub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_legmulx(self):
+        assert_equal(leg.legmulx([0]), [0])
+        assert_equal(leg.legmulx([1]), [0, 1])
+        for i in range(1, 5):
+            tmp = 2*i + 1
+            ser = [0]*i + [1]
+            tgt = [0]*(i - 1) + [i/tmp, 0, (i + 1)/tmp]
+            assert_equal(leg.legmulx(ser), tgt)
+
+    def test_legmul(self):
+        # check values of result
+        for i in range(5):
+            pol1 = [0]*i + [1]
+            val1 = leg.legval(self.x, pol1)
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                pol2 = [0]*j + [1]
+                val2 = leg.legval(self.x, pol2)
+                pol3 = leg.legmul(pol1, pol2)
+                val3 = leg.legval(self.x, pol3)
+                assert_(len(pol3) == i + j + 1, msg)
+                assert_almost_equal(val3, val1*val2, err_msg=msg)
+
+    def test_legdiv(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1]
+                cj = [0]*j + [1]
+                tgt = leg.legadd(ci, cj)
+                quo, rem = leg.legdiv(tgt, ci)
+                res = leg.legadd(leg.legmul(quo, ci), rem)
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([2., 2., 2.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = polyval(x, [1., 2., 3.])
+
+    def test_legval(self):
+        #check empty input
+        assert_equal(leg.legval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [polyval(x, c) for c in Llist]
+        for i in range(10):
+            msg = "At i=%d" % i
+            tgt = y[i]
+            res = leg.legval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt, err_msg=msg)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(leg.legval(x, [1]).shape, dims)
+            assert_equal(leg.legval(x, [1, 0]).shape, dims)
+            assert_equal(leg.legval(x, [1, 0, 0]).shape, dims)
+
+    def test_legval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, leg.legval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = leg.legval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.legval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_legval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, leg.legval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = leg.legval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.legval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_leggrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = leg.leggrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.leggrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_leggrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = leg.leggrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = leg.leggrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_legint(self):
+        # check exceptions
+        assert_raises(ValueError, leg.legint, [0], .5)
+        assert_raises(ValueError, leg.legint, [0], -1)
+        assert_raises(ValueError, leg.legint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = leg.legint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i])
+            res = leg.leg2poly(legint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(leg.legval(-1, legint), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            legpol = leg.poly2leg(pol)
+            legint = leg.legint(legpol, m=1, k=[i], scl=2)
+            res = leg.leg2poly(legint)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1)
+                res = leg.legint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k])
+                res = leg.legint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k], lbnd=-1)
+                res = leg.legint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = leg.legint(tgt, m=1, k=[k], scl=2)
+                res = leg.legint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([leg.legint(c) for c in c2d.T]).T
+        res = leg.legint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legint(c) for c in c2d])
+        res = leg.legint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legint(c, k=3) for c in c2d])
+        res = leg.legint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_legder(self):
+        # check exceptions
+        assert_raises(ValueError, leg.legder, [0], .5)
+        assert_raises(ValueError, leg.legder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = leg.legder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = leg.legder(leg.legint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([leg.legder(c) for c in c2d.T]).T
+        res = leg.legder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([leg.legder(c) for c in c2d])
+        res = leg.legder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_legvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = leg.legvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = leg.legvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], leg.legval(x, coef))
+
+    def test_legvander2d(self):
+        # also tests polyval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = leg.legvander2d(x1, x2, [1, 2])
+        tgt = leg.legval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = leg.legvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_legvander3d(self):
+        # also tests polyval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = leg.legvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = leg.legval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = leg.legvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestFitting(TestCase):
+
+    def test_legfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, leg.legfit, [1], [1], -1)
+        assert_raises(TypeError, leg.legfit, [[1]], [1], 0)
+        assert_raises(TypeError, leg.legfit, [], [1], 0)
+        assert_raises(TypeError, leg.legfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, leg.legfit, [1, 2], [1], 0)
+        assert_raises(TypeError, leg.legfit, [1], [1, 2], 0)
+        assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, leg.legfit, [1], [1], [-1,])
+        assert_raises(ValueError, leg.legfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, leg.legfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = leg.legfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(leg.legval(x, coef3), y)
+        coef3 = leg.legfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(leg.legval(x, coef3), y)
+        #
+        coef4 = leg.legfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        coef4 = leg.legfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        # check things still work if deg is not in strict increasing
+        coef4 = leg.legfit(x, y, [2, 3, 4, 1, 0])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(leg.legval(x, coef4), y)
+        #
+        coef2d = leg.legfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = leg.legfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        y[0::2] = 0
+        wcoef3 = leg.legfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = leg.legfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = leg.legfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = leg.legfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(leg.legfit(x, x, 1), [0, 1])
+        assert_almost_equal(leg.legfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Legendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = leg.legfit(x, y, 4)
+        assert_almost_equal(leg.legval(x, coef1), y)
+        coef2 = leg.legfit(x, y, [0, 2, 4])
+        assert_almost_equal(leg.legval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, leg.legcompanion, [])
+        assert_raises(ValueError, leg.legcompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(leg.legcompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(leg.legcompanion([1, 2])[0, 0] == -.5)
+
+
+class TestGauss(TestCase):
+
+    def test_100(self):
+        x, w = leg.leggauss(100)
+
+        # test orthogonality. Note that the results need to be normalized,
+        # otherwise the huge values that can arise from fast growing
+        # functions like Laguerre can be very confusing.
+        v = leg.legvander(x, 99)
+        vv = np.dot(v.T * w, v)
+        vd = 1/np.sqrt(vv.diagonal())
+        vv = vd[:, None] * vv * vd
+        assert_almost_equal(vv, np.eye(100))
+
+        # check that the integral of 1 is correct
+        tgt = 2.0
+        assert_almost_equal(w.sum(), tgt)
+
+
+class TestMisc(TestCase):
+
+    def test_legfromroots(self):
+        res = leg.legfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            pol = leg.legfromroots(roots)
+            res = leg.legval(roots, pol)
+            tgt = 0
+            assert_(len(pol) == i + 1)
+            assert_almost_equal(leg.leg2poly(pol)[-1], 1)
+            assert_almost_equal(res, tgt)
+
+    def test_legroots(self):
+        assert_almost_equal(leg.legroots([1]), [])
+        assert_almost_equal(leg.legroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = leg.legroots(leg.legfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_legtrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, leg.legtrim, coef, -1)
+
+        # Test results
+        assert_equal(leg.legtrim(coef), coef[:-1])
+        assert_equal(leg.legtrim(coef, 1), coef[:-3])
+        assert_equal(leg.legtrim(coef, 2), [0])
+
+    def test_legline(self):
+        assert_equal(leg.legline(3, 4), [3, 4])
+
+    def test_leg2poly(self):
+        for i in range(10):
+            assert_almost_equal(leg.leg2poly([0]*i + [1]), Llist[i])
+
+    def test_poly2leg(self):
+        for i in range(10):
+            assert_almost_equal(leg.poly2leg(Llist[i]), [0]*i + [1])
+
+    def test_weight(self):
+        x = np.linspace(-1, 1, 11)
+        tgt = 1.
+        res = leg.legweight(x)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
new file mode 100644
index 0000000000..00a52ebce8
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
@@ -0,0 +1,504 @@
+"""Tests for polynomial module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.polynomial as poly
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+def trim(x):
+    return poly.polytrim(x, tol=1e-6)
+
+T0 = [1]
+T1 = [0, 1]
+T2 = [-1, 0, 2]
+T3 = [0, -3, 0, 4]
+T4 = [1, 0, -8, 0, 8]
+T5 = [0, 5, 0, -20, 0, 16]
+T6 = [-1, 0, 18, 0, -48, 0, 32]
+T7 = [0, -7, 0, 56, 0, -112, 0, 64]
+T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
+T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
+
+Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
+
+
+class TestConstants(TestCase):
+
+    def test_polydomain(self):
+        assert_equal(poly.polydomain, [-1, 1])
+
+    def test_polyzero(self):
+        assert_equal(poly.polyzero, [0])
+
+    def test_polyone(self):
+        assert_equal(poly.polyone, [1])
+
+    def test_polyx(self):
+        assert_equal(poly.polyx, [0, 1])
+
+
+class TestArithmetic(TestCase):
+
+    def test_polyadd(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] += 1
+                res = poly.polyadd([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polysub(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(max(i, j) + 1)
+                tgt[i] += 1
+                tgt[j] -= 1
+                res = poly.polysub([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polymulx(self):
+        assert_equal(poly.polymulx([0]), [0])
+        assert_equal(poly.polymulx([1]), [0, 1])
+        for i in range(1, 5):
+            ser = [0]*i + [1]
+            tgt = [0]*(i + 1) + [1]
+            assert_equal(poly.polymulx(ser), tgt)
+
+    def test_polymul(self):
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                tgt = np.zeros(i + j + 1)
+                tgt[i + j] += 1
+                res = poly.polymul([0]*i + [1], [0]*j + [1])
+                assert_equal(trim(res), trim(tgt), err_msg=msg)
+
+    def test_polydiv(self):
+        # check zero division
+        assert_raises(ZeroDivisionError, poly.polydiv, [1], [0])
+
+        # check scalar division
+        quo, rem = poly.polydiv([2], [2])
+        assert_equal((quo, rem), (1, 0))
+        quo, rem = poly.polydiv([2, 2], [2])
+        assert_equal((quo, rem), ((1, 1), 0))
+
+        # check rest.
+        for i in range(5):
+            for j in range(5):
+                msg = "At i=%d, j=%d" % (i, j)
+                ci = [0]*i + [1, 2]
+                cj = [0]*j + [1, 2]
+                tgt = poly.polyadd(ci, cj)
+                quo, rem = poly.polydiv(tgt, ci)
+                res = poly.polyadd(poly.polymul(quo, ci), rem)
+                assert_equal(res, tgt, err_msg=msg)
+
+
+class TestEvaluation(TestCase):
+    # coefficients of 1 + 2*x + 3*x**2
+    c1d = np.array([1., 2., 3.])
+    c2d = np.einsum('i,j->ij', c1d, c1d)
+    c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
+
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+    y = poly.polyval(x, [1., 2., 3.])
+
+    def test_polyval(self):
+        #check empty input
+        assert_equal(poly.polyval([], [1]).size, 0)
+
+        #check normal input)
+        x = np.linspace(-1, 1)
+        y = [x**i for i in range(5)]
+        for i in range(5):
+            tgt = y[i]
+            res = poly.polyval(x, [0]*i + [1])
+            assert_almost_equal(res, tgt)
+        tgt = x*(x**2 - 1)
+        res = poly.polyval(x, [0, -1, 0, 1])
+        assert_almost_equal(res, tgt)
+
+        #check that shape is preserved
+        for i in range(3):
+            dims = [2]*i
+            x = np.zeros(dims)
+            assert_equal(poly.polyval(x, [1]).shape, dims)
+            assert_equal(poly.polyval(x, [1, 0]).shape, dims)
+            assert_equal(poly.polyval(x, [1, 0, 0]).shape, dims)
+
+    def test_polyval2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, poly.polyval2d, x1, x2[:2], self.c2d)
+
+        #test values
+        tgt = y1*y2
+        res = poly.polyval2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polyval2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3))
+
+    def test_polyval3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test exceptions
+        assert_raises(ValueError, poly.polyval3d, x1, x2, x3[:2], self.c3d)
+
+        #test values
+        tgt = y1*y2*y3
+        res = poly.polyval3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polyval3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3))
+
+    def test_polygrid2d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j->ij', y1, y2)
+        res = poly.polygrid2d(x1, x2, self.c2d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polygrid2d(z, z, self.c2d)
+        assert_(res.shape == (2, 3)*2)
+
+    def test_polygrid3d(self):
+        x1, x2, x3 = self.x
+        y1, y2, y3 = self.y
+
+        #test values
+        tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
+        res = poly.polygrid3d(x1, x2, x3, self.c3d)
+        assert_almost_equal(res, tgt)
+
+        #test shape
+        z = np.ones((2, 3))
+        res = poly.polygrid3d(z, z, z, self.c3d)
+        assert_(res.shape == (2, 3)*3)
+
+
+class TestIntegral(TestCase):
+
+    def test_polyint(self):
+        # check exceptions
+        assert_raises(ValueError, poly.polyint, [0], .5)
+        assert_raises(ValueError, poly.polyint, [0], -1)
+        assert_raises(ValueError, poly.polyint, [0], 1, [0, 0])
+
+        # test integration of zero polynomial
+        for i in range(2, 5):
+            k = [0]*(i - 2) + [1]
+            res = poly.polyint([0], m=i, k=k)
+            assert_almost_equal(res, [0, 1])
+
+        # check single integration with integration constant
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [1/scl]
+            res = poly.polyint(pol, m=1, k=[i])
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check single integration with integration constant and lbnd
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            res = poly.polyint(pol, m=1, k=[i], lbnd=-1)
+            assert_almost_equal(poly.polyval(-1, res), i)
+
+        # check single integration with integration constant and scaling
+        for i in range(5):
+            scl = i + 1
+            pol = [0]*i + [1]
+            tgt = [i] + [0]*i + [2/scl]
+            res = poly.polyint(pol, m=1, k=[i], scl=2)
+            assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with default k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1)
+                res = poly.polyint(pol, m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with defined k
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k])
+                res = poly.polyint(pol, m=j, k=list(range(j)))
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with lbnd
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k], lbnd=-1)
+                res = poly.polyint(pol, m=j, k=list(range(j)), lbnd=-1)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check multiple integrations with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                pol = [0]*i + [1]
+                tgt = pol[:]
+                for k in range(j):
+                    tgt = poly.polyint(tgt, m=1, k=[k], scl=2)
+                res = poly.polyint(pol, m=j, k=list(range(j)), scl=2)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyint_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([poly.polyint(c) for c in c2d.T]).T
+        res = poly.polyint(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyint(c) for c in c2d])
+        res = poly.polyint(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyint(c, k=3) for c in c2d])
+        res = poly.polyint(c2d, k=3, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestDerivative(TestCase):
+
+    def test_polyder(self):
+        # check exceptions
+        assert_raises(ValueError, poly.polyder, [0], .5)
+        assert_raises(ValueError, poly.polyder, [0], -1)
+
+        # check that zeroth deriviative does nothing
+        for i in range(5):
+            tgt = [0]*i + [1]
+            res = poly.polyder(tgt, m=0)
+            assert_equal(trim(res), trim(tgt))
+
+        # check that derivation is the inverse of integration
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = poly.polyder(poly.polyint(tgt, m=j), m=j)
+                assert_almost_equal(trim(res), trim(tgt))
+
+        # check derivation with scaling
+        for i in range(5):
+            for j in range(2, 5):
+                tgt = [0]*i + [1]
+                res = poly.polyder(poly.polyint(tgt, m=j, scl=2), m=j, scl=.5)
+                assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyder_axis(self):
+        # check that axis keyword works
+        c2d = np.random.random((3, 4))
+
+        tgt = np.vstack([poly.polyder(c) for c in c2d.T]).T
+        res = poly.polyder(c2d, axis=0)
+        assert_almost_equal(res, tgt)
+
+        tgt = np.vstack([poly.polyder(c) for c in c2d])
+        res = poly.polyder(c2d, axis=1)
+        assert_almost_equal(res, tgt)
+
+
+class TestVander(TestCase):
+    # some random values in [-1, 1)
+    x = np.random.random((3, 5))*2 - 1
+
+    def test_polyvander(self):
+        # check for 1d x
+        x = np.arange(3)
+        v = poly.polyvander(x, 3)
+        assert_(v.shape == (3, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+        # check for 2d x
+        x = np.array([[1, 2], [3, 4], [5, 6]])
+        v = poly.polyvander(x, 3)
+        assert_(v.shape == (3, 2, 4))
+        for i in range(4):
+            coef = [0]*i + [1]
+            assert_almost_equal(v[..., i], poly.polyval(x, coef))
+
+    def test_polyvander2d(self):
+        # also tests polyval2d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3))
+        van = poly.polyvander2d(x1, x2, [1, 2])
+        tgt = poly.polyval2d(x1, x2, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = poly.polyvander2d([x1], [x2], [1, 2])
+        assert_(van.shape == (1, 5, 6))
+
+    def test_polyvander3d(self):
+        # also tests polyval3d for non-square coefficient array
+        x1, x2, x3 = self.x
+        c = np.random.random((2, 3, 4))
+        van = poly.polyvander3d(x1, x2, x3, [1, 2, 3])
+        tgt = poly.polyval3d(x1, x2, x3, c)
+        res = np.dot(van, c.flat)
+        assert_almost_equal(res, tgt)
+
+        # check shape
+        van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3])
+        assert_(van.shape == (1, 5, 24))
+
+
+class TestCompanion(TestCase):
+
+    def test_raises(self):
+        assert_raises(ValueError, poly.polycompanion, [])
+        assert_raises(ValueError, poly.polycompanion, [1])
+
+    def test_dimensions(self):
+        for i in range(1, 5):
+            coef = [0]*i + [1]
+            assert_(poly.polycompanion(coef).shape == (i, i))
+
+    def test_linear_root(self):
+        assert_(poly.polycompanion([1, 2])[0, 0] == -.5)
+
+
+class TestMisc(TestCase):
+
+    def test_polyfromroots(self):
+        res = poly.polyfromroots([])
+        assert_almost_equal(trim(res), [1])
+        for i in range(1, 5):
+            roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2])
+            tgt = Tlist[i]
+            res = poly.polyfromroots(roots)*2**(i-1)
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyroots(self):
+        assert_almost_equal(poly.polyroots([1]), [])
+        assert_almost_equal(poly.polyroots([1, 2]), [-.5])
+        for i in range(2, 5):
+            tgt = np.linspace(-1, 1, i)
+            res = poly.polyroots(poly.polyfromroots(tgt))
+            assert_almost_equal(trim(res), trim(tgt))
+
+    def test_polyfit(self):
+        def f(x):
+            return x*(x - 1)*(x - 2)
+
+        def f2(x):
+            return x**4 + x**2 + 1
+
+        # Test exceptions
+        assert_raises(ValueError, poly.polyfit, [1], [1], -1)
+        assert_raises(TypeError, poly.polyfit, [[1]], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [[[1]]], 0)
+        assert_raises(TypeError, poly.polyfit, [1, 2], [1], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [1, 2], 0)
+        assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[[1]])
+        assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[1, 1])
+        assert_raises(ValueError, poly.polyfit, [1], [1], [-1,])
+        assert_raises(ValueError, poly.polyfit, [1], [1], [2, -1, 6])
+        assert_raises(TypeError, poly.polyfit, [1], [1], [])
+
+        # Test fit
+        x = np.linspace(0, 2)
+        y = f(x)
+        #
+        coef3 = poly.polyfit(x, y, 3)
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(poly.polyval(x, coef3), y)
+        coef3 = poly.polyfit(x, y, [0, 1, 2, 3])
+        assert_equal(len(coef3), 4)
+        assert_almost_equal(poly.polyval(x, coef3), y)
+        #
+        coef4 = poly.polyfit(x, y, 4)
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(poly.polyval(x, coef4), y)
+        coef4 = poly.polyfit(x, y, [0, 1, 2, 3, 4])
+        assert_equal(len(coef4), 5)
+        assert_almost_equal(poly.polyval(x, coef4), y)
+        #
+        coef2d = poly.polyfit(x, np.array([y, y]).T, 3)
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        coef2d = poly.polyfit(x, np.array([y, y]).T, [0, 1, 2, 3])
+        assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
+        # test weighting
+        w = np.zeros_like(x)
+        yw = y.copy()
+        w[1::2] = 1
+        yw[0::2] = 0
+        wcoef3 = poly.polyfit(x, yw, 3, w=w)
+        assert_almost_equal(wcoef3, coef3)
+        wcoef3 = poly.polyfit(x, yw, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef3, coef3)
+        #
+        wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, 3, w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
+        assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
+        # test scaling with complex values x points whose square
+        # is zero when summed.
+        x = [1, 1j, -1, -1j]
+        assert_almost_equal(poly.polyfit(x, x, 1), [0, 1])
+        assert_almost_equal(poly.polyfit(x, x, [0, 1]), [0, 1])
+        # test fitting only even Polyendre polynomials
+        x = np.linspace(-1, 1)
+        y = f2(x)
+        coef1 = poly.polyfit(x, y, 4)
+        assert_almost_equal(poly.polyval(x, coef1), y)
+        coef2 = poly.polyfit(x, y, [0, 2, 4])
+        assert_almost_equal(poly.polyval(x, coef2), y)
+        assert_almost_equal(coef1, coef2)
+
+    def test_polytrim(self):
+        coef = [2, -1, 1, 0]
+
+        # Test exceptions
+        assert_raises(ValueError, poly.polytrim, coef, -1)
+
+        # Test results
+        assert_equal(poly.polytrim(coef), coef[:-1])
+        assert_equal(poly.polytrim(coef, 1), coef[:-3])
+        assert_equal(poly.polytrim(coef, 2), [0])
+
+    def test_polyline(self):
+        assert_equal(poly.polyline(3, 4), [3, 4])
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
new file mode 100644
index 0000000000..974e2e09a3
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
@@ -0,0 +1,109 @@
+"""Tests for polyutils module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.polynomial.polyutils as pu
+from numpy.testing import (
+    TestCase, assert_almost_equal, assert_raises,
+    assert_equal, assert_, run_module_suite)
+
+
+class TestMisc(TestCase):
+
+    def test_trimseq(self):
+        for i in range(5):
+            tgt = [1]
+            res = pu.trimseq([1] + [0]*5)
+            assert_equal(res, tgt)
+
+    def test_as_series(self):
+        # check exceptions
+        assert_raises(ValueError, pu.as_series, [[]])
+        assert_raises(ValueError, pu.as_series, [[[1, 2]]])
+        assert_raises(ValueError, pu.as_series, [[1], ['a']])
+        # check common types
+        types = ['i', 'd', 'O']
+        for i in range(len(types)):
+            for j in range(i):
+                ci = np.ones(1, types[i])
+                cj = np.ones(1, types[j])
+                [resi, resj] = pu.as_series([ci, cj])
+                assert_(resi.dtype.char == resj.dtype.char)
+                assert_(resj.dtype.char == types[i])
+
+    def test_trimcoef(self):
+        coef = [2, -1, 1, 0]
+        # Test exceptions
+        assert_raises(ValueError, pu.trimcoef, coef, -1)
+        # Test results
+        assert_equal(pu.trimcoef(coef), coef[:-1])
+        assert_equal(pu.trimcoef(coef, 1), coef[:-3])
+        assert_equal(pu.trimcoef(coef, 2), [0])
+
+
+class TestDomain(TestCase):
+
+    def test_getdomain(self):
+        # test for real values
+        x = [1, 10, 3, -1]
+        tgt = [-1, 10]
+        res = pu.getdomain(x)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        x = [1 + 1j, 1 - 1j, 0, 2]
+        tgt = [-1j, 2 + 1j]
+        res = pu.getdomain(x)
+        assert_almost_equal(res, tgt)
+
+    def test_mapdomain(self):
+        # test for real values
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = dom2
+        res = pu. mapdomain(dom1, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        dom1 = [0 - 1j, 2 + 1j]
+        dom2 = [-2, 2]
+        tgt = dom2
+        x = dom1
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for multidimensional arrays
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = np.array([dom2, dom2])
+        x = np.array([dom1, dom1])
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test that subtypes are preserved.
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        x = np.matrix([dom1, dom1])
+        res = pu.mapdomain(x, dom1, dom2)
+        assert_(isinstance(res, np.matrix))
+
+    def test_mapparms(self):
+        # test for real values
+        dom1 = [0, 4]
+        dom2 = [1, 3]
+        tgt = [1, .5]
+        res = pu. mapparms(dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+        # test for complex values
+        dom1 = [0 - 1j, 2 + 1j]
+        dom2 = [-2, 2]
+        tgt = [-1 + 1j, 1 - 1j]
+        res = pu.mapparms(dom1, dom2)
+        assert_almost_equal(res, tgt)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
new file mode 100644
index 0000000000..86cd257328
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
@@ -0,0 +1,74 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy.polynomial as poly
+from numpy.testing import TestCase, run_module_suite, assert_
+
+
+class test_str(TestCase):
+    def test_polynomial_str(self):
+        res = str(poly.Polynomial([0, 1]))
+        tgt = 'poly([0., 1.])'
+        assert_(res, tgt)
+
+    def test_chebyshev_str(self):
+        res = str(poly.Chebyshev([0, 1]))
+        tgt = 'leg([0., 1.])'
+        assert_(res, tgt)
+
+    def test_legendre_str(self):
+        res = str(poly.Legendre([0, 1]))
+        tgt = 'leg([0., 1.])'
+        assert_(res, tgt)
+
+    def test_hermite_str(self):
+        res = str(poly.Hermite([0, 1]))
+        tgt = 'herm([0., 1.])'
+        assert_(res, tgt)
+
+    def test_hermiteE_str(self):
+        res = str(poly.HermiteE([0, 1]))
+        tgt = 'herme([0., 1.])'
+        assert_(res, tgt)
+
+    def test_laguerre_str(self):
+        res = str(poly.Laguerre([0, 1]))
+        tgt = 'lag([0., 1.])'
+        assert_(res, tgt)
+
+
+class test_repr(TestCase):
+    def test_polynomial_str(self):
+        res = repr(poly.Polynomial([0, 1]))
+        tgt = 'Polynomial([0., 1.])'
+        assert_(res, tgt)
+
+    def test_chebyshev_str(self):
+        res = repr(poly.Chebyshev([0, 1]))
+        tgt = 'Chebyshev([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_legendre_repr(self):
+        res = repr(poly.Legendre([0, 1]))
+        tgt = 'Legendre([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_hermite_repr(self):
+        res = repr(poly.Hermite([0, 1]))
+        tgt = 'Hermite([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_hermiteE_repr(self):
+        res = repr(poly.HermiteE([0, 1]))
+        tgt = 'HermiteE([0., 1.], [-1., 1.], [-1., 1.])'
+        assert_(res, tgt)
+
+    def test_laguerre_repr(self):
+        res = repr(poly.Laguerre([0, 1]))
+        tgt = 'Laguerre([0., 1.], [0., 1.], [0., 1.])'
+        assert_(res, tgt)
+
+
+#
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/__init__.py
new file mode 100644
index 0000000000..6c7d3140fe
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/__init__.py
@@ -0,0 +1,122 @@
+"""
+========================
+Random Number Generation
+========================
+
+==================== =========================================================
+Utility functions
+==============================================================================
+random               Uniformly distributed values of a given shape.
+bytes                Uniformly distributed random bytes.
+random_integers      Uniformly distributed integers in a given range.
+random_sample        Uniformly distributed floats in a given range.
+random               Alias for random_sample
+ranf                 Alias for random_sample
+sample               Alias for random_sample
+choice               Generate a weighted random sample from a given array-like
+permutation          Randomly permute a sequence / generate a random sequence.
+shuffle              Randomly permute a sequence in place.
+seed                 Seed the random number generator.
+==================== =========================================================
+
+==================== =========================================================
+Compatibility functions
+==============================================================================
+rand                 Uniformly distributed values.
+randn                Normally distributed values.
+ranf                 Uniformly distributed floating point numbers.
+randint              Uniformly distributed integers in a given range.
+==================== =========================================================
+
+==================== =========================================================
+Univariate distributions
+==============================================================================
+beta                 Beta distribution over ``[0, 1]``.
+binomial             Binomial distribution.
+chisquare            :math:`\\chi^2` distribution.
+exponential          Exponential distribution.
+f                    F (Fisher-Snedecor) distribution.
+gamma                Gamma distribution.
+geometric            Geometric distribution.
+gumbel               Gumbel distribution.
+hypergeometric       Hypergeometric distribution.
+laplace              Laplace distribution.
+logistic             Logistic distribution.
+lognormal            Log-normal distribution.
+logseries            Logarithmic series distribution.
+negative_binomial    Negative binomial distribution.
+noncentral_chisquare Non-central chi-square distribution.
+noncentral_f         Non-central F distribution.
+normal               Normal / Gaussian distribution.
+pareto               Pareto distribution.
+poisson              Poisson distribution.
+power                Power distribution.
+rayleigh             Rayleigh distribution.
+triangular           Triangular distribution.
+uniform              Uniform distribution.
+vonmises             Von Mises circular distribution.
+wald                 Wald (inverse Gaussian) distribution.
+weibull              Weibull distribution.
+zipf                 Zipf's distribution over ranked data.
+==================== =========================================================
+
+==================== =========================================================
+Multivariate distributions
+==============================================================================
+dirichlet            Multivariate generalization of Beta distribution.
+multinomial          Multivariate generalization of the binomial distribution.
+multivariate_normal  Multivariate generalization of the normal distribution.
+==================== =========================================================
+
+==================== =========================================================
+Standard distributions
+==============================================================================
+standard_cauchy      Standard Cauchy-Lorentz distribution.
+standard_exponential Standard exponential distribution.
+standard_gamma       Standard Gamma distribution.
+standard_normal      Standard normal distribution.
+standard_t           Standard Student's t-distribution.
+==================== =========================================================
+
+==================== =========================================================
+Internal functions
+==============================================================================
+get_state            Get tuple representing internal state of generator.
+set_state            Set state of generator.
+==================== =========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+
+# To get sub-modules
+from .info import __doc__, __all__
+
+
+with warnings.catch_warnings():
+    warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
+    from .mtrand import *
+
+# Some aliases:
+ranf = random = sample = random_sample
+__all__.extend(['ranf', 'random', 'sample'])
+
+def __RandomState_ctor():
+    """Return a RandomState instance.
+
+    This function exists solely to assist (un)pickling.
+
+    Note that the state of the RandomState returned here is irrelevant, as this function's
+    entire purpose is to return a newly allocated RandomState whose state pickle can set.
+    Consequently the RandomState returned by this function is a freshly allocated copy
+    with a seed=0.
+
+    See https://github.com/numpy/numpy/issues/4763 for a detailed discussion
+
+    """
+    return RandomState(seed=0)
+
+from numpy.testing.nosetester import _numpy_tester
+test = _numpy_tester().test
+bench = _numpy_tester().bench
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/info.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/info.py
new file mode 100644
index 0000000000..be9c8d9bd2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/info.py
@@ -0,0 +1,139 @@
+"""
+========================
+Random Number Generation
+========================
+
+==================== =========================================================
+Utility functions
+==============================================================================
+random_sample        Uniformly distributed floats over ``[0, 1)``.
+random               Alias for `random_sample`.
+bytes                Uniformly distributed random bytes.
+random_integers      Uniformly distributed integers in a given range.
+permutation          Randomly permute a sequence / generate a random sequence.
+shuffle              Randomly permute a sequence in place.
+seed                 Seed the random number generator.
+choice               Random sample from 1-D array.
+
+==================== =========================================================
+
+==================== =========================================================
+Compatibility functions
+==============================================================================
+rand                 Uniformly distributed values.
+randn                Normally distributed values.
+ranf                 Uniformly distributed floating point numbers.
+randint              Uniformly distributed integers in a given range.
+==================== =========================================================
+
+==================== =========================================================
+Univariate distributions
+==============================================================================
+beta                 Beta distribution over ``[0, 1]``.
+binomial             Binomial distribution.
+chisquare            :math:`\\chi^2` distribution.
+exponential          Exponential distribution.
+f                    F (Fisher-Snedecor) distribution.
+gamma                Gamma distribution.
+geometric            Geometric distribution.
+gumbel               Gumbel distribution.
+hypergeometric       Hypergeometric distribution.
+laplace              Laplace distribution.
+logistic             Logistic distribution.
+lognormal            Log-normal distribution.
+logseries            Logarithmic series distribution.
+negative_binomial    Negative binomial distribution.
+noncentral_chisquare Non-central chi-square distribution.
+noncentral_f         Non-central F distribution.
+normal               Normal / Gaussian distribution.
+pareto               Pareto distribution.
+poisson              Poisson distribution.
+power                Power distribution.
+rayleigh             Rayleigh distribution.
+triangular           Triangular distribution.
+uniform              Uniform distribution.
+vonmises             Von Mises circular distribution.
+wald                 Wald (inverse Gaussian) distribution.
+weibull              Weibull distribution.
+zipf                 Zipf's distribution over ranked data.
+==================== =========================================================
+
+==================== =========================================================
+Multivariate distributions
+==============================================================================
+dirichlet            Multivariate generalization of Beta distribution.
+multinomial          Multivariate generalization of the binomial distribution.
+multivariate_normal  Multivariate generalization of the normal distribution.
+==================== =========================================================
+
+==================== =========================================================
+Standard distributions
+==============================================================================
+standard_cauchy      Standard Cauchy-Lorentz distribution.
+standard_exponential Standard exponential distribution.
+standard_gamma       Standard Gamma distribution.
+standard_normal      Standard normal distribution.
+standard_t           Standard Student's t-distribution.
+==================== =========================================================
+
+==================== =========================================================
+Internal functions
+==============================================================================
+get_state            Get tuple representing internal state of generator.
+set_state            Set state of generator.
+==================== =========================================================
+
+"""
+from __future__ import division, absolute_import, print_function
+
+depends = ['core']
+
+__all__ = [
+    'beta',
+    'binomial',
+    'bytes',
+    'chisquare',
+    'choice',
+    'dirichlet',
+    'exponential',
+    'f',
+    'gamma',
+    'geometric',
+    'get_state',
+    'gumbel',
+    'hypergeometric',
+    'laplace',
+    'logistic',
+    'lognormal',
+    'logseries',
+    'multinomial',
+    'multivariate_normal',
+    'negative_binomial',
+    'noncentral_chisquare',
+    'noncentral_f',
+    'normal',
+    'pareto',
+    'permutation',
+    'poisson',
+    'power',
+    'rand',
+    'randint',
+    'randn',
+    'random_integers',
+    'random_sample',
+    'rayleigh',
+    'seed',
+    'set_state',
+    'shuffle',
+    'standard_cauchy',
+    'standard_exponential',
+    'standard_gamma',
+    'standard_normal',
+    'standard_t',
+    'triangular',
+    'uniform',
+    'vonmises',
+    'wald',
+    'weibull',
+    'zipf'
+]
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/mtrand.pyd b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/mtrand.pyd
new file mode 100644
index 0000000000000000000000000000000000000000..56983cbfa0853d27213ad9227bb7f19bfb25a046
GIT binary patch
literal 684544
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
bu~!0IS~4&&T!8RFITKWVf?PU^Q9}R#y2ku>

literal 0
HcmV?d00001

diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/randomkit.h b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/randomkit.h
new file mode 100644
index 0000000000..fcdd606a14
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/randomkit.h
@@ -0,0 +1,226 @@
+/* Random kit 1.3 */
+
+/*
+ * Copyright (c) 2003-2005, Jean-Sebastien Roy (js@jeannot.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* @(#) $Jeannot: randomkit.h,v 1.24 2005/07/21 22:14:09 js Exp $ */
+
+/*
+ * Typical use:
+ *
+ * {
+ *  rk_state state;
+ *  unsigned long seed = 1, random_value;
+ *
+ *  rk_seed(seed, &state); // Initialize the RNG
+ *  ...
+ *  random_value = rk_random(&state); // Generate random values in [0..RK_MAX]
+ * }
+ *
+ * Instead of rk_seed, you can use rk_randomseed which will get a random seed
+ * from /dev/urandom (or the clock, if /dev/urandom is unavailable):
+ *
+ * {
+ *  rk_state state;
+ *  unsigned long random_value;
+ *
+ *  rk_randomseed(&state); // Initialize the RNG with a random seed
+ *  ...
+ *  random_value = rk_random(&state); // Generate random values in [0..RK_MAX]
+ * }
+ */
+
+/*
+ * Useful macro:
+ *  RK_DEV_RANDOM: the device used for random seeding.
+ *                 defaults to "/dev/urandom"
+ */
+
+#ifndef _RANDOMKIT_
+#define _RANDOMKIT_
+
+#include <stddef.h>
+#include <numpy/npy_common.h>
+
+
+#define RK_STATE_LEN 624
+
+typedef struct rk_state_
+{
+    unsigned long key[RK_STATE_LEN];
+    int pos;
+    int has_gauss; /* !=0: gauss contains a gaussian deviate */
+    double gauss;
+
+    /* The rk_state structure has been extended to store the following
+     * information for the binomial generator. If the input values of n or p
+     * are different than nsave and psave, then the other parameters will be
+     * recomputed. RTK 2005-09-02 */
+
+    int has_binomial; /* !=0: following parameters initialized for
+                              binomial */
+    double psave;
+    long nsave;
+    double r;
+    double q;
+    double fm;
+    long m;
+    double p1;
+    double xm;
+    double xl;
+    double xr;
+    double c;
+    double laml;
+    double lamr;
+    double p2;
+    double p3;
+    double p4;
+
+}
+rk_state;
+
+typedef enum {
+    RK_NOERR = 0, /* no error */
+    RK_ENODEV = 1, /* no RK_DEV_RANDOM device */
+    RK_ERR_MAX = 2
+} rk_error;
+
+/* error strings */
+extern char *rk_strerror[RK_ERR_MAX];
+
+/* Maximum generated random value */
+#define RK_MAX 0xFFFFFFFFUL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Initialize the RNG state using the given seed.
+ */
+extern void rk_seed(unsigned long seed, rk_state *state);
+
+/*
+ * Initialize the RNG state using a random seed.
+ * Uses /dev/random or, when unavailable, the clock (see randomkit.c).
+ * Returns RK_NOERR when no errors occurs.
+ * Returns RK_ENODEV when the use of RK_DEV_RANDOM failed (for example because
+ * there is no such device). In this case, the RNG was initialized using the
+ * clock.
+ */
+extern rk_error rk_randomseed(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and RK_MAX inclusive
+ */
+extern unsigned long rk_random(rk_state *state);
+
+/*
+ * Returns a random long between 0 and LONG_MAX inclusive
+ */
+extern long rk_long(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and ULONG_MAX inclusive
+ */
+extern unsigned long rk_ulong(rk_state *state);
+
+/*
+ * Returns a random unsigned long between 0 and max inclusive.
+ */
+extern unsigned long rk_interval(unsigned long max, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint64 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint64(npy_uint64 off, npy_uint64 rng, npy_intp cnt,
+                             npy_uint64 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint32 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint32(npy_uint32 off, npy_uint32 rng, npy_intp cnt,
+                             npy_uint32 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint16 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint16(npy_uint16 off, npy_uint16 rng, npy_intp cnt,
+                             npy_uint16 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_uint8 between off and off + rng
+ * inclusive. The numbers wrap if rng is sufficiently large.
+ */
+extern void rk_random_uint8(npy_uint8 off, npy_uint8 rng, npy_intp cnt,
+                            npy_uint8 *out, rk_state *state);
+
+/*
+ * Fills an array with cnt random npy_bool between off and off + rng
+ * inclusive. It is assumed tha npy_bool as the same size as npy_uint8.
+ */
+extern void rk_random_bool(npy_bool off, npy_bool rng, npy_intp cnt,
+                           npy_bool *out, rk_state *state);
+
+/*
+ * Returns a random double between 0.0 and 1.0, 1.0 excluded.
+ */
+extern double rk_double(rk_state *state);
+
+/*
+ * fill the buffer with size random bytes
+ */
+extern void rk_fill(void *buffer, size_t size, rk_state *state);
+
+/*
+ * fill the buffer with randombytes from the random device
+ * Returns RK_ENODEV if the device is unavailable, or RK_NOERR if it is
+ * On Unix, if strong is defined, RK_DEV_RANDOM is used. If not, RK_DEV_URANDOM
+ * is used instead. This parameter has no effect on Windows.
+ * Warning: on most unixes RK_DEV_RANDOM will wait for enough entropy to answer
+ * which can take a very long time on quiet systems.
+ */
+extern rk_error rk_devfill(void *buffer, size_t size, int strong);
+
+/*
+ * fill the buffer using rk_devfill if the random device is available and using
+ * rk_fill if is is not
+ * parameters have the same meaning as rk_fill and rk_devfill
+ * Returns RK_ENODEV if the device is unavailable, or RK_NOERR if it is
+ */
+extern rk_error rk_altfill(void *buffer, size_t size, int strong,
+                            rk_state *state);
+
+/*
+ * return a random gaussian deviate with variance unity and zero mean.
+ */
+extern double rk_gauss(rk_state *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RANDOMKIT_ */
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/setup.py
new file mode 100644
index 0000000000..9d905900cd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/setup.py
@@ -0,0 +1,61 @@
+from __future__ import division, print_function
+
+from os.path import join, split, dirname
+import os
+import sys
+from distutils.dep_util import newer
+from distutils.msvccompiler import get_build_version as get_msvc_build_version
+
+def needs_mingw_ftime_workaround():
+    # We need the mingw workaround for _ftime if the msvc runtime version is
+    # 7.1 or above and we build with mingw ...
+    # ... but we can't easily detect compiler version outside distutils command
+    # context, so we will need to detect in randomkit whether we build with gcc
+    msver = get_msvc_build_version()
+    if msver and msver >= 8:
+        return True
+
+    return False
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration, get_mathlibs
+    config = Configuration('random', parent_package, top_path)
+
+    def generate_libraries(ext, build_dir):
+        config_cmd = config.get_config_cmd()
+        libs = get_mathlibs()
+        if sys.platform == 'win32':
+            libs.append('Advapi32')
+        ext.libraries.extend(libs)
+        return None
+
+    # enable unix large file support on 32 bit systems
+    # (64 bit off_t, lseek -> lseek64 etc.)
+    defs = [('_FILE_OFFSET_BITS', '64'),
+            ('_LARGEFILE_SOURCE', '1'),
+            ('_LARGEFILE64_SOURCE', '1')]
+    if needs_mingw_ftime_workaround():
+        defs.append(("NPY_NEEDS_MINGW_TIME_WORKAROUND", None))
+
+    libs = []
+    # Configure mtrand
+    config.add_extension('mtrand',
+                         sources=[join('mtrand', x) for x in
+                                  ['mtrand.c', 'randomkit.c', 'initarray.c',
+                                   'distributions.c']]+[generate_libraries],
+                         libraries=libs,
+                         depends=[join('mtrand', '*.h'),
+                                  join('mtrand', '*.pyx'),
+                                  join('mtrand', '*.pxi'),],
+                         define_macros=defs,
+                         )
+
+    config.add_data_files(('.', join('mtrand', 'randomkit.h')))
+    config.add_data_dir('tests')
+
+    return config
+
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(configuration=configuration)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_random.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_random.py
new file mode 100644
index 0000000000..4ad94505cd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_random.py
@@ -0,0 +1,856 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+from numpy.testing import (
+        TestCase, run_module_suite, assert_, assert_raises, assert_equal,
+        assert_warns)
+from numpy import random
+from numpy.compat import asbytes
+import sys
+import warnings
+
+
+
+class TestSeed(TestCase):
+    def test_scalar(self):
+        s = np.random.RandomState(0)
+        assert_equal(s.randint(1000), 684)
+        s = np.random.RandomState(4294967295)
+        assert_equal(s.randint(1000), 419)
+
+    def test_array(self):
+        s = np.random.RandomState(range(10))
+        assert_equal(s.randint(1000), 468)
+        s = np.random.RandomState(np.arange(10))
+        assert_equal(s.randint(1000), 468)
+        s = np.random.RandomState([0])
+        assert_equal(s.randint(1000), 973)
+        s = np.random.RandomState([4294967295])
+        assert_equal(s.randint(1000), 265)
+
+    def test_invalid_scalar(self):
+        # seed must be an unsigned 32 bit integer
+        assert_raises(TypeError, np.random.RandomState, -0.5)
+        assert_raises(ValueError, np.random.RandomState, -1)
+
+    def test_invalid_array(self):
+        # seed must be an unsigned 32 bit integer
+        assert_raises(TypeError, np.random.RandomState, [-0.5])
+        assert_raises(ValueError, np.random.RandomState, [-1])
+        assert_raises(ValueError, np.random.RandomState, [4294967296])
+        assert_raises(ValueError, np.random.RandomState, [1, 2, 4294967296])
+        assert_raises(ValueError, np.random.RandomState, [1, -2, 4294967296])
+
+
+class TestBinomial(TestCase):
+    def test_n_zero(self):
+        # Tests the corner case of n == 0 for the binomial distribution.
+        # binomial(0, p) should be zero for any p in [0, 1].
+        # This test addresses issue #3480.
+        zeros = np.zeros(2, dtype='int')
+        for p in [0, .5, 1]:
+            assert_(random.binomial(0, p) == 0)
+            np.testing.assert_array_equal(random.binomial(zeros, p), zeros)
+
+    def test_p_is_nan(self):
+        # Issue #4571.
+        assert_raises(ValueError, random.binomial, 1, np.nan)
+
+
+class TestMultinomial(TestCase):
+    def test_basic(self):
+        random.multinomial(100, [0.2, 0.8])
+
+    def test_zero_probability(self):
+        random.multinomial(100, [0.2, 0.8, 0.0, 0.0, 0.0])
+
+    def test_int_negative_interval(self):
+        assert_(-5 <= random.randint(-5, -1) < -1)
+        x = random.randint(-5, -1, 5)
+        assert_(np.all(-5 <= x))
+        assert_(np.all(x < -1))
+
+    def test_size(self):
+        # gh-3173
+        p = [0.5, 0.5]
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.multinomial(1, p, [2, 2]).shape, (2, 2, 2))
+        assert_equal(np.random.multinomial(1, p, (2, 2)).shape, (2, 2, 2))
+        assert_equal(np.random.multinomial(1, p, np.array((2, 2))).shape,
+                     (2, 2, 2))
+
+        assert_raises(TypeError, np.random.multinomial, 1, p,
+                      np.float(1))
+
+
+class TestSetState(TestCase):
+    def setUp(self):
+        self.seed = 1234567890
+        self.prng = random.RandomState(self.seed)
+        self.state = self.prng.get_state()
+
+    def test_basic(self):
+        old = self.prng.tomaxint(16)
+        self.prng.set_state(self.state)
+        new = self.prng.tomaxint(16)
+        assert_(np.all(old == new))
+
+    def test_gaussian_reset(self):
+        # Make sure the cached every-other-Gaussian is reset.
+        old = self.prng.standard_normal(size=3)
+        self.prng.set_state(self.state)
+        new = self.prng.standard_normal(size=3)
+        assert_(np.all(old == new))
+
+    def test_gaussian_reset_in_media_res(self):
+        # When the state is saved with a cached Gaussian, make sure the
+        # cached Gaussian is restored.
+
+        self.prng.standard_normal()
+        state = self.prng.get_state()
+        old = self.prng.standard_normal(size=3)
+        self.prng.set_state(state)
+        new = self.prng.standard_normal(size=3)
+        assert_(np.all(old == new))
+
+    def test_backwards_compatibility(self):
+        # Make sure we can accept old state tuples that do not have the
+        # cached Gaussian value.
+        old_state = self.state[:-2]
+        x1 = self.prng.standard_normal(size=16)
+        self.prng.set_state(old_state)
+        x2 = self.prng.standard_normal(size=16)
+        self.prng.set_state(self.state)
+        x3 = self.prng.standard_normal(size=16)
+        assert_(np.all(x1 == x2))
+        assert_(np.all(x1 == x3))
+
+    def test_negative_binomial(self):
+        # Ensure that the negative binomial results take floating point
+        # arguments without truncation.
+        self.prng.negative_binomial(0.5, 0.5)
+
+
+class TestRandint(TestCase):
+
+    rfunc = np.random.randint
+
+    # valid integer/boolean types
+    itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16,
+             np.int32, np.uint32, np.int64, np.uint64]
+
+    def test_unsupported_type(self):
+        assert_raises(TypeError, self.rfunc, 1, dtype=np.float)
+
+    def test_bounds_checking(self):
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+            assert_raises(ValueError, self.rfunc, lbnd - 1, ubnd, dtype=dt)
+            assert_raises(ValueError, self.rfunc, lbnd, ubnd + 1, dtype=dt)
+            assert_raises(ValueError, self.rfunc, ubnd, lbnd, dtype=dt)
+            assert_raises(ValueError, self.rfunc, 1, 0, dtype=dt)
+
+    def test_rng_zero_and_extremes(self):
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+            tgt = ubnd - 1
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+            tgt = lbnd
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+            tgt = (lbnd + ubnd)//2
+            assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt)
+
+    def test_in_bounds_fuzz(self):
+        # Don't use fixed seed
+        np.random.seed()
+        for dt in self.itype[1:]:
+            for ubnd in [4, 8, 16]:
+                vals = self.rfunc(2, ubnd, size=2**16, dtype=dt)
+                assert_(vals.max() < ubnd)
+                assert_(vals.min() >= 2)
+        vals = self.rfunc(0, 2, size=2**16, dtype=np.bool)
+        assert_(vals.max() < 2)
+        assert_(vals.min() >= 0)
+
+    def test_repeatability(self):
+        import hashlib
+        # We use a md5 hash of generated sequences of 1000 samples
+        # in the range [0, 6) for all but np.bool, where the range
+        # is [0, 2). Hashes are for little endian numbers.
+        tgt = {'bool': '7dd3170d7aa461d201a65f8bcf3944b0',
+               'int16': '1b7741b80964bb190c50d541dca1cac1',
+               'int32': '4dc9fcc2b395577ebb51793e58ed1a05',
+               'int64': '17db902806f448331b5a758d7d2ee672',
+               'int8': '27dd30c4e08a797063dffac2490b0be6',
+               'uint16': '1b7741b80964bb190c50d541dca1cac1',
+               'uint32': '4dc9fcc2b395577ebb51793e58ed1a05',
+               'uint64': '17db902806f448331b5a758d7d2ee672',
+               'uint8': '27dd30c4e08a797063dffac2490b0be6'}
+
+        for dt in self.itype[1:]:
+            np.random.seed(1234)
+
+            # view as little endian for hash
+            if sys.byteorder == 'little':
+                val = self.rfunc(0, 6, size=1000, dtype=dt)
+            else:
+                val = self.rfunc(0, 6, size=1000, dtype=dt).byteswap()
+
+            res = hashlib.md5(val.view(np.int8)).hexdigest()
+            assert_(tgt[np.dtype(dt).name] == res)
+
+        # bools do not depend on endianess
+        np.random.seed(1234)
+        val = self.rfunc(0, 2, size=1000, dtype=np.bool).view(np.int8)
+        res = hashlib.md5(val).hexdigest()
+        assert_(tgt[np.dtype(np.bool).name] == res)
+
+    def test_respect_dtype_singleton(self):
+        # See gh-7203
+        for dt in self.itype:
+            lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1
+
+            sample = self.rfunc(lbnd, ubnd, dtype=dt)
+            self.assertEqual(sample.dtype, np.dtype(dt))
+
+        for dt in (np.bool, np.int, np.long):
+            lbnd = 0 if dt is np.bool else np.iinfo(dt).min
+            ubnd = 2 if dt is np.bool else np.iinfo(dt).max + 1
+
+            # gh-7284: Ensure that we get Python data types
+            sample = self.rfunc(lbnd, ubnd, dtype=dt)
+            self.assertFalse(hasattr(sample, 'dtype'))
+            self.assertEqual(type(sample), dt)
+
+
+class TestRandomDist(TestCase):
+    # Make sure the random distribution returns the correct value for a
+    # given seed
+
+    def setUp(self):
+        self.seed = 1234567890
+
+    def test_rand(self):
+        np.random.seed(self.seed)
+        actual = np.random.rand(3, 2)
+        desired = np.array([[0.61879477158567997, 0.59162362775974664],
+                            [0.88868358904449662, 0.89165480011560816],
+                            [0.4575674820298663, 0.7781880808593471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_randn(self):
+        np.random.seed(self.seed)
+        actual = np.random.randn(3, 2)
+        desired = np.array([[1.34016345771863121, 1.73759122771936081],
+                           [1.498988344300628, -0.2286433324536169],
+                           [2.031033998682787, 2.17032494605655257]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_randint(self):
+        np.random.seed(self.seed)
+        actual = np.random.randint(-99, 99, size=(3, 2))
+        desired = np.array([[31, 3],
+                            [-52, 41],
+                            [-48, -66]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_random_integers(self):
+        np.random.seed(self.seed)
+        actual = np.random.random_integers(-99, 99, size=(3, 2))
+        desired = np.array([[31, 3],
+                            [-52, 41],
+                            [-48, -66]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_random_integers_max_int(self):
+        # Tests whether random_integers can generate the
+        # maximum allowed Python int that can be converted
+        # into a C long. Previous implementations of this
+        # method have thrown an OverflowError when attempting
+        # to generate this integer.
+        actual = np.random.random_integers(np.iinfo('l').max,
+                                           np.iinfo('l').max)
+        desired = np.iinfo('l').max
+        np.testing.assert_equal(actual, desired)
+
+    def test_random_integers_deprecated(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", DeprecationWarning)
+
+            # DeprecationWarning raised with high == None
+            assert_raises(DeprecationWarning,
+                          np.random.random_integers,
+                          np.iinfo('l').max)
+
+            # DeprecationWarning raised with high != None
+            assert_raises(DeprecationWarning,
+                          np.random.random_integers,
+                          np.iinfo('l').max, np.iinfo('l').max)
+
+    def test_random_sample(self):
+        np.random.seed(self.seed)
+        actual = np.random.random_sample((3, 2))
+        desired = np.array([[0.61879477158567997, 0.59162362775974664],
+                            [0.88868358904449662, 0.89165480011560816],
+                            [0.4575674820298663, 0.7781880808593471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_choice_uniform_replace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 4)
+        desired = np.array([2, 3, 2, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_nonuniform_replace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 4, p=[0.4, 0.4, 0.1, 0.1])
+        desired = np.array([1, 1, 2, 2])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_uniform_noreplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 3, replace=False)
+        desired = np.array([0, 1, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_nonuniform_noreplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(4, 3, replace=False,
+                                  p=[0.1, 0.3, 0.5, 0.1])
+        desired = np.array([2, 3, 1])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_noninteger(self):
+        np.random.seed(self.seed)
+        actual = np.random.choice(['a', 'b', 'c', 'd'], 4)
+        desired = np.array(['c', 'd', 'c', 'd'])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_choice_exceptions(self):
+        sample = np.random.choice
+        assert_raises(ValueError, sample, -1, 3)
+        assert_raises(ValueError, sample, 3., 3)
+        assert_raises(ValueError, sample, [[1, 2], [3, 4]], 3)
+        assert_raises(ValueError, sample, [], 3)
+        assert_raises(ValueError, sample, [1, 2, 3, 4], 3,
+                                          p=[[0.25, 0.25], [0.25, 0.25]])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4, 0.2])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[1.1, -0.1])
+        assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4])
+        assert_raises(ValueError, sample, [1, 2, 3], 4, replace=False)
+        assert_raises(ValueError, sample, [1, 2, 3], 2, replace=False,
+                                          p=[1, 0, 0])
+
+    def test_choice_return_shape(self):
+        p = [0.1, 0.9]
+        # Check scalar
+        assert_(np.isscalar(np.random.choice(2, replace=True)))
+        assert_(np.isscalar(np.random.choice(2, replace=False)))
+        assert_(np.isscalar(np.random.choice(2, replace=True, p=p)))
+        assert_(np.isscalar(np.random.choice(2, replace=False, p=p)))
+        assert_(np.isscalar(np.random.choice([1, 2], replace=True)))
+        assert_(np.random.choice([None], replace=True) is None)
+        a = np.array([1, 2])
+        arr = np.empty(1, dtype=object)
+        arr[0] = a
+        assert_(np.random.choice(arr, replace=True) is a)
+
+        # Check 0-d array
+        s = tuple()
+        assert_(not np.isscalar(np.random.choice(2, s, replace=True)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=False)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=True, p=p)))
+        assert_(not np.isscalar(np.random.choice(2, s, replace=False, p=p)))
+        assert_(not np.isscalar(np.random.choice([1, 2], s, replace=True)))
+        assert_(np.random.choice([None], s, replace=True).ndim == 0)
+        a = np.array([1, 2])
+        arr = np.empty(1, dtype=object)
+        arr[0] = a
+        assert_(np.random.choice(arr, s, replace=True).item() is a)
+
+        # Check multi dimensional array
+        s = (2, 3)
+        p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2]
+        assert_(np.random.choice(6, s, replace=True).shape, s)
+        assert_(np.random.choice(6, s, replace=False).shape, s)
+        assert_(np.random.choice(6, s, replace=True, p=p).shape, s)
+        assert_(np.random.choice(6, s, replace=False, p=p).shape, s)
+        assert_(np.random.choice(np.arange(6), s, replace=True).shape, s)
+
+    def test_bytes(self):
+        np.random.seed(self.seed)
+        actual = np.random.bytes(10)
+        desired = asbytes('\x82Ui\x9e\xff\x97+Wf\xa5')
+        np.testing.assert_equal(actual, desired)
+
+    def test_shuffle(self):
+        # Test lists, arrays (of various dtypes), and multidimensional versions
+        # of both, c-contiguous or not:
+        for conv in [lambda x: np.array([]),
+                     lambda x: x,
+                     lambda x: np.asarray(x).astype(np.int8),
+                     lambda x: np.asarray(x).astype(np.float32),
+                     lambda x: np.asarray(x).astype(np.complex64),
+                     lambda x: np.asarray(x).astype(object),
+                     lambda x: [(i, i) for i in x],
+                     lambda x: np.asarray([[i, i] for i in x]),
+                     lambda x: np.vstack([x, x]).T,
+                     # gh-4270
+                     lambda x: np.asarray([(i, i) for i in x],
+                                          [("a", object, 1),
+                                           ("b", np.int32, 1)])]:
+            np.random.seed(self.seed)
+            alist = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
+            np.random.shuffle(alist)
+            actual = alist
+            desired = conv([0, 1, 9, 6, 2, 4, 5, 8, 7, 3])
+            np.testing.assert_array_equal(actual, desired)
+
+    def test_shuffle_masked(self):
+        # gh-3263
+        a = np.ma.masked_values(np.reshape(range(20), (5,4)) % 3 - 1, -1)
+        b = np.ma.masked_values(np.arange(20) % 3 - 1, -1)
+        a_orig = a.copy()
+        b_orig = b.copy()
+        for i in range(50):
+            np.random.shuffle(a)
+            assert_equal(
+                sorted(a.data[~a.mask]), sorted(a_orig.data[~a_orig.mask]))
+            np.random.shuffle(b)
+            assert_equal(
+                sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask]))
+
+    def test_beta(self):
+        np.random.seed(self.seed)
+        actual = np.random.beta(.1, .9, size=(3, 2))
+        desired = np.array(
+                [[1.45341850513746058e-02, 5.31297615662868145e-04],
+                 [1.85366619058432324e-06, 4.19214516800110563e-03],
+                 [1.58405155108498093e-04, 1.26252891949397652e-04]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_binomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.binomial(100.123, .456, size=(3, 2))
+        desired = np.array([[37, 43],
+                         [42, 48],
+                         [46, 45]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_chisquare(self):
+        np.random.seed(self.seed)
+        actual = np.random.chisquare(50, size=(3, 2))
+        desired = np.array([[63.87858175501090585, 68.68407748911370447],
+                            [65.77116116901505904, 47.09686762438974483],
+                            [72.3828403199695174, 74.18408615260374006]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=13)
+
+    def test_dirichlet(self):
+        np.random.seed(self.seed)
+        alpha = np.array([51.72840233779265162, 39.74494232180943953])
+        actual = np.random.mtrand.dirichlet(alpha, size=(3, 2))
+        desired = np.array([[[0.54539444573611562, 0.45460555426388438],
+                             [0.62345816822039413, 0.37654183177960598]],
+                            [[0.55206000085785778, 0.44793999914214233],
+                             [0.58964023305154301, 0.41035976694845688]],
+                            [[0.59266909280647828, 0.40733090719352177],
+                             [0.56974431743975207, 0.43025568256024799]]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_dirichlet_size(self):
+        # gh-3173
+        p = np.array([51.72840233779265162, 39.74494232180943953])
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2))
+        assert_equal(np.random.dirichlet(p, [2, 2]).shape, (2, 2, 2))
+        assert_equal(np.random.dirichlet(p, (2, 2)).shape, (2, 2, 2))
+        assert_equal(np.random.dirichlet(p, np.array((2, 2))).shape, (2, 2, 2))
+
+        assert_raises(TypeError, np.random.dirichlet, p, np.float(1))
+
+    def test_exponential(self):
+        np.random.seed(self.seed)
+        actual = np.random.exponential(1.1234, size=(3, 2))
+        desired = np.array([[1.08342649775011624, 1.00607889924557314],
+                            [2.46628830085216721, 2.49668106809923884],
+                            [0.68717433461363442, 1.69175666993575979]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_f(self):
+        np.random.seed(self.seed)
+        actual = np.random.f(12, 77, size=(3, 2))
+        desired = np.array([[1.21975394418575878, 1.75135759791559775],
+                            [1.44803115017146489, 1.22108959480396262],
+                            [1.02176975757740629, 1.34431827623300415]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_gamma(self):
+        np.random.seed(self.seed)
+        actual = np.random.gamma(5, 3, size=(3, 2))
+        desired = np.array([[24.60509188649287182, 28.54993563207210627],
+                            [26.13476110204064184, 12.56988482927716078],
+                            [31.71863275789960568, 33.30143302795922011]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_geometric(self):
+        np.random.seed(self.seed)
+        actual = np.random.geometric(.123456789, size=(3, 2))
+        desired = np.array([[8, 7],
+                            [17, 17],
+                            [5, 12]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_gumbel(self):
+        np.random.seed(self.seed)
+        actual = np.random.gumbel(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[0.19591898743416816, 0.34405539668096674],
+                            [-1.4492522252274278, -1.47374816298446865],
+                            [1.10651090478803416, -0.69535848626236174]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_hypergeometric(self):
+        np.random.seed(self.seed)
+        actual = np.random.hypergeometric(10.1, 5.5, 14, size=(3, 2))
+        desired = np.array([[10, 10],
+                            [10, 10],
+                            [9, 9]])
+        np.testing.assert_array_equal(actual, desired)
+
+        # Test nbad = 0
+        actual = np.random.hypergeometric(5, 0, 3, size=4)
+        desired = np.array([3, 3, 3, 3])
+        np.testing.assert_array_equal(actual, desired)
+
+        actual = np.random.hypergeometric(15, 0, 12, size=4)
+        desired = np.array([12, 12, 12, 12])
+        np.testing.assert_array_equal(actual, desired)
+
+        # Test ngood = 0
+        actual = np.random.hypergeometric(0, 5, 3, size=4)
+        desired = np.array([0, 0, 0, 0])
+        np.testing.assert_array_equal(actual, desired)
+
+        actual = np.random.hypergeometric(0, 15, 12, size=4)
+        desired = np.array([0, 0, 0, 0])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_laplace(self):
+        np.random.seed(self.seed)
+        actual = np.random.laplace(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[0.66599721112760157, 0.52829452552221945],
+                            [3.12791959514407125, 3.18202813572992005],
+                            [-0.05391065675859356, 1.74901336242837324]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_logistic(self):
+        np.random.seed(self.seed)
+        actual = np.random.logistic(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[1.09232835305011444, 0.8648196662399954],
+                            [4.27818590694950185, 4.33897006346929714],
+                            [-0.21682183359214885, 2.63373365386060332]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_lognormal(self):
+        np.random.seed(self.seed)
+        actual = np.random.lognormal(mean=.123456789, sigma=2.0, size=(3, 2))
+        desired = np.array([[16.50698631688883822, 36.54846706092654784],
+                            [22.67886599981281748, 0.71617561058995771],
+                            [65.72798501792723869, 86.84341601437161273]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=13)
+
+    def test_logseries(self):
+        np.random.seed(self.seed)
+        actual = np.random.logseries(p=.923456789, size=(3, 2))
+        desired = np.array([[2, 2],
+                            [6, 17],
+                            [3, 6]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_multinomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.multinomial(20, [1/6.]*6, size=(3, 2))
+        desired = np.array([[[4, 3, 5, 4, 2, 2],
+                             [5, 2, 8, 2, 2, 1]],
+                            [[3, 4, 3, 6, 0, 4],
+                             [2, 1, 4, 3, 6, 4]],
+                            [[4, 4, 2, 5, 2, 3],
+                             [4, 3, 4, 2, 3, 4]]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_multivariate_normal(self):
+        np.random.seed(self.seed)
+        mean = (.123456789, 10)
+        # Hmm... not even symmetric.
+        cov = [[1, 0], [1, 0]]
+        size = (3, 2)
+        actual = np.random.multivariate_normal(mean, cov, size)
+        desired = np.array([[[-1.47027513018564449, 10.],
+                             [-1.65915081534845532, 10.]],
+                            [[-2.29186329304599745, 10.],
+                             [-1.77505606019580053, 10.]],
+                            [[-0.54970369430044119, 10.],
+                             [0.29768848031692957, 10.]]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+        # Check for default size, was raising deprecation warning
+        actual = np.random.multivariate_normal(mean, cov)
+        desired = np.array([-0.79441224511977482, 10.])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+        # Check that non positive-semidefinite covariance raises warning
+        mean = [0, 0]
+        cov = [[1, 1 + 1e-10], [1 + 1e-10, 1]]
+        assert_warns(RuntimeWarning, np.random.multivariate_normal, mean, cov)
+
+    def test_negative_binomial(self):
+        np.random.seed(self.seed)
+        actual = np.random.negative_binomial(n=100, p=.12345, size=(3, 2))
+        desired = np.array([[848, 841],
+                            [892, 611],
+                            [779, 647]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_noncentral_chisquare(self):
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_chisquare(df=5, nonc=5, size=(3, 2))
+        desired = np.array([[23.91905354498517511, 13.35324692733826346],
+                            [31.22452661329736401, 16.60047399466177254],
+                            [5.03461598262724586, 17.94973089023519464]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+        actual = np.random.noncentral_chisquare(df=.5, nonc=.2, size=(3, 2))
+        desired = np.array([[ 1.47145377828516666,  0.15052899268012659],
+                            [ 0.00943803056963588,  1.02647251615666169],
+                            [ 0.332334982684171  ,  0.15451287602753125]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_chisquare(df=5, nonc=0, size=(3, 2))
+        desired = np.array([[9.597154162763948, 11.725484450296079],
+                            [10.413711048138335, 3.694475922923986],
+                            [13.484222138963087, 14.377255424602957]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_noncentral_f(self):
+        np.random.seed(self.seed)
+        actual = np.random.noncentral_f(dfnum=5, dfden=2, nonc=1,
+                                        size=(3, 2))
+        desired = np.array([[1.40598099674926669, 0.34207973179285761],
+                            [3.57715069265772545, 7.92632662577829805],
+                            [0.43741599463544162, 1.1774208752428319]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_normal(self):
+        np.random.seed(self.seed)
+        actual = np.random.normal(loc=.123456789, scale=2.0, size=(3, 2))
+        desired = np.array([[2.80378370443726244, 3.59863924443872163],
+                            [3.121433477601256, -0.33382987590723379],
+                            [4.18552478636557357, 4.46410668111310471]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_pareto(self):
+        np.random.seed(self.seed)
+        actual = np.random.pareto(a=.123456789, size=(3, 2))
+        desired = np.array(
+                [[2.46852460439034849e+03, 1.41286880810518346e+03],
+                 [5.28287797029485181e+07, 6.57720981047328785e+07],
+                 [1.40840323350391515e+02, 1.98390255135251704e+05]])
+        # For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this
+        # matrix differs by 24 nulps. Discussion:
+        #   http://mail.scipy.org/pipermail/numpy-discussion/2012-September/063801.html
+        # Consensus is that this is probably some gcc quirk that affects
+        # rounding but not in any important way, so we just use a looser
+        # tolerance on this test:
+        np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=30)
+
+    def test_poisson(self):
+        np.random.seed(self.seed)
+        actual = np.random.poisson(lam=.123456789, size=(3, 2))
+        desired = np.array([[0, 0],
+                         [1, 0],
+                         [0, 0]])
+        np.testing.assert_array_equal(actual, desired)
+
+    def test_poisson_exceptions(self):
+        lambig = np.iinfo('l').max
+        lamneg = -1
+        assert_raises(ValueError, np.random.poisson, lamneg)
+        assert_raises(ValueError, np.random.poisson, [lamneg]*10)
+        assert_raises(ValueError, np.random.poisson, lambig)
+        assert_raises(ValueError, np.random.poisson, [lambig]*10)
+
+    def test_power(self):
+        np.random.seed(self.seed)
+        actual = np.random.power(a=.123456789, size=(3, 2))
+        desired = np.array([[0.02048932883240791, 0.01424192241128213],
+                            [0.38446073748535298, 0.39499689943484395],
+                            [0.00177699707563439, 0.13115505880863756]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_rayleigh(self):
+        np.random.seed(self.seed)
+        actual = np.random.rayleigh(scale=10, size=(3, 2))
+        desired = np.array([[13.8882496494248393, 13.383318339044731],
+                            [20.95413364294492098, 21.08285015800712614],
+                            [11.06066537006854311, 17.35468505778271009]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_standard_cauchy(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_cauchy(size=(3, 2))
+        desired = np.array([[0.77127660196445336, -6.55601161955910605],
+                            [0.93582023391158309, -2.07479293013759447],
+                            [-4.74601644297011926, 0.18338989290760804]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_exponential(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_exponential(size=(3, 2))
+        desired = np.array([[0.96441739162374596, 0.89556604882105506],
+                            [2.1953785836319808, 2.22243285392490542],
+                            [0.6116915921431676, 1.50592546727413201]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_gamma(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_gamma(shape=3, size=(3, 2))
+        desired = np.array([[5.50841531318455058, 6.62953470301903103],
+                            [5.93988484943779227, 2.31044849402133989],
+                            [7.54838614231317084, 8.012756093271868]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_standard_normal(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_normal(size=(3, 2))
+        desired = np.array([[1.34016345771863121, 1.73759122771936081],
+                            [1.498988344300628, -0.2286433324536169],
+                            [2.031033998682787, 2.17032494605655257]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_standard_t(self):
+        np.random.seed(self.seed)
+        actual = np.random.standard_t(df=10, size=(3, 2))
+        desired = np.array([[0.97140611862659965, -0.08830486548450577],
+                            [1.36311143689505321, -0.55317463909867071],
+                            [-0.18473749069684214, 0.61181537341755321]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_triangular(self):
+        np.random.seed(self.seed)
+        actual = np.random.triangular(left=5.12, mode=10.23, right=20.34,
+                                      size=(3, 2))
+        desired = np.array([[12.68117178949215784, 12.4129206149193152],
+                            [16.20131377335158263, 16.25692138747600524],
+                            [11.20400690911820263, 14.4978144835829923]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_uniform(self):
+        np.random.seed(self.seed)
+        actual = np.random.uniform(low=1.23, high=10.54, size=(3, 2))
+        desired = np.array([[6.99097932346268003, 6.73801597444323974],
+                            [9.50364421400426274, 9.53130618907631089],
+                            [5.48995325769805476, 8.47493103280052118]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_uniform_range_bounds(self):
+        fmin = np.finfo('float').min
+        fmax = np.finfo('float').max
+
+        func = np.random.uniform
+        np.testing.assert_raises(OverflowError, func, -np.inf, 0)
+        np.testing.assert_raises(OverflowError, func,  0,      np.inf)
+        np.testing.assert_raises(OverflowError, func,  fmin,   fmax)
+
+        # (fmax / 1e17) - fmin is within range, so this should not throw
+        np.random.uniform(low=fmin, high=fmax / 1e17)
+
+    def test_vonmises(self):
+        np.random.seed(self.seed)
+        actual = np.random.vonmises(mu=1.23, kappa=1.54, size=(3, 2))
+        desired = np.array([[2.28567572673902042, 2.89163838442285037],
+                            [0.38198375564286025, 2.57638023113890746],
+                            [1.19153771588353052, 1.83509849681825354]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_vonmises_small(self):
+        # check infinite loop, gh-4720
+        np.random.seed(self.seed)
+        r = np.random.vonmises(mu=0., kappa=1.1e-8, size=10**6)
+        np.testing.assert_(np.isfinite(r).all())
+
+    def test_wald(self):
+        np.random.seed(self.seed)
+        actual = np.random.wald(mean=1.23, scale=1.54, size=(3, 2))
+        desired = np.array([[3.82935265715889983, 5.13125249184285526],
+                            [0.35045403618358717, 1.50832396872003538],
+                            [0.24124319895843183, 0.22031101461955038]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=14)
+
+    def test_weibull(self):
+        np.random.seed(self.seed)
+        actual = np.random.weibull(a=1.23, size=(3, 2))
+        desired = np.array([[0.97097342648766727, 0.91422896443565516],
+                            [1.89517770034962929, 1.91414357960479564],
+                            [0.67057783752390987, 1.39494046635066793]])
+        np.testing.assert_array_almost_equal(actual, desired, decimal=15)
+
+    def test_zipf(self):
+        np.random.seed(self.seed)
+        actual = np.random.zipf(a=1.23, size=(3, 2))
+        desired = np.array([[66, 29],
+                            [1, 1],
+                            [3, 13]])
+        np.testing.assert_array_equal(actual, desired)
+
+
+class TestThread(object):
+    # make sure each state produces the same sequence even in threads
+    def setUp(self):
+        self.seeds = range(4)
+
+    def check_function(self, function, sz):
+        from threading import Thread
+
+        out1 = np.empty((len(self.seeds),) + sz)
+        out2 = np.empty((len(self.seeds),) + sz)
+
+        # threaded generation
+        t = [Thread(target=function, args=(np.random.RandomState(s), o))
+             for s, o in zip(self.seeds, out1)]
+        [x.start() for x in t]
+        [x.join() for x in t]
+
+        # the same serial
+        for s, o in zip(self.seeds, out2):
+            function(np.random.RandomState(s), o)
+
+        # these platforms change x87 fpu precision mode in threads
+        if (np.intp().dtype.itemsize == 4 and sys.platform == "win32"):
+            np.testing.assert_array_almost_equal(out1, out2)
+        else:
+            np.testing.assert_array_equal(out1, out2)
+
+    def test_normal(self):
+        def gen_random(state, out):
+            out[...] = state.normal(size=10000)
+        self.check_function(gen_random, sz=(10000,))
+
+    def test_exp(self):
+        def gen_random(state, out):
+            out[...] = state.exponential(scale=np.ones((100, 1000)))
+        self.check_function(gen_random, sz=(100, 1000))
+
+    def test_multinomial(self):
+        def gen_random(state, out):
+            out[...] = state.multinomial(10, [1/6.]*6, size=10000)
+        self.check_function(gen_random, sz=(10000,6))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_regression.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
new file mode 100644
index 0000000000..133a1aa5ad
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
@@ -0,0 +1,117 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+from numpy.testing import (TestCase, run_module_suite, assert_,
+                           assert_array_equal, assert_raises)
+from numpy import random
+from numpy.compat import long
+import numpy as np
+
+
+class TestRegression(TestCase):
+
+    def test_VonMises_range(self):
+        # Make sure generated random variables are in [-pi, pi].
+        # Regression test for ticket #986.
+        for mu in np.linspace(-7., 7., 5):
+            r = random.mtrand.vonmises(mu, 1, 50)
+            assert_(np.all(r > -np.pi) and np.all(r <= np.pi))
+
+    def test_hypergeometric_range(self):
+        # Test for ticket #921
+        assert_(np.all(np.random.hypergeometric(3, 18, 11, size=10) < 4))
+        assert_(np.all(np.random.hypergeometric(18, 3, 11, size=10) > 0))
+
+        # Test for ticket #5623
+        args = [
+            (2**20 - 2, 2**20 - 2, 2**20 - 2),  # Check for 32-bit systems
+        ]
+        is_64bits = sys.maxsize > 2**32
+        if is_64bits and sys.platform != 'win32':
+            args.append((2**40 - 2, 2**40 - 2, 2**40 - 2)) # Check for 64-bit systems
+        for arg in args:
+            assert_(np.random.hypergeometric(*arg) > 0)
+
+    def test_logseries_convergence(self):
+        # Test for ticket #923
+        N = 1000
+        np.random.seed(0)
+        rvsn = np.random.logseries(0.8, size=N)
+        # these two frequency counts should be close to theoretical
+        # numbers with this large sample
+        # theoretical large N result is 0.49706795
+        freq = np.sum(rvsn == 1) / float(N)
+        msg = "Frequency was %f, should be > 0.45" % freq
+        assert_(freq > 0.45, msg)
+        # theoretical large N result is 0.19882718
+        freq = np.sum(rvsn == 2) / float(N)
+        msg = "Frequency was %f, should be < 0.23" % freq
+        assert_(freq < 0.23, msg)
+
+    def test_permutation_longs(self):
+        np.random.seed(1234)
+        a = np.random.permutation(12)
+        np.random.seed(1234)
+        b = np.random.permutation(long(12))
+        assert_array_equal(a, b)
+
+    def test_randint_range(self):
+        # Test for ticket #1690
+        lmax = np.iinfo('l').max
+        lmin = np.iinfo('l').min
+        try:
+            random.randint(lmin, lmax)
+        except:
+            raise AssertionError
+
+    def test_shuffle_mixed_dimension(self):
+        # Test for trac ticket #2074
+        for t in [[1, 2, 3, None],
+                  [(1, 1), (2, 2), (3, 3), None],
+                  [1, (2, 2), (3, 3), None],
+                  [(1, 1), 2, 3, None]]:
+            np.random.seed(12345)
+            shuffled = list(t)
+            random.shuffle(shuffled)
+            assert_array_equal(shuffled, [t[0], t[3], t[1], t[2]])
+
+    def test_call_within_randomstate(self):
+        # Check that custom RandomState does not call into global state
+        m = np.random.RandomState()
+        res = np.array([0, 8, 7, 2, 1, 9, 4, 7, 0, 3])
+        for i in range(3):
+            np.random.seed(i)
+            m.seed(4321)
+            # If m.state is not honored, the result will change
+            assert_array_equal(m.choice(10, size=10, p=np.ones(10)/10.), res)
+
+    def test_multivariate_normal_size_types(self):
+        # Test for multivariate_normal issue with 'size' argument.
+        # Check that the multivariate_normal size argument can be a
+        # numpy integer.
+        np.random.multivariate_normal([0], [[0]], size=1)
+        np.random.multivariate_normal([0], [[0]], size=np.int_(1))
+        np.random.multivariate_normal([0], [[0]], size=np.int64(1))
+
+    def test_beta_small_parameters(self):
+        # Test that beta with small a and b parameters does not produce
+        # NaNs due to roundoff errors causing 0 / 0, gh-5851
+        np.random.seed(1234567890)
+        x = np.random.beta(0.0001, 0.0001, size=100)
+        assert_(not np.any(np.isnan(x)), 'Nans in np.random.beta')
+
+    def test_choice_sum_of_probs_tolerance(self):
+        # The sum of probs should be 1.0 with some tolerance.
+        # For low precision dtypes the tolerance was too tight.
+        # See numpy github issue 6123.
+        np.random.seed(1234)
+        a = [1, 2, 3]
+        counts = [4, 4, 2]
+        for dt in np.float16, np.float32, np.float64:
+            probs = np.array(counts, dtype=dt) / sum(counts)
+            c = np.random.choice(a, p=probs)
+            assert_(c in a)
+            assert_raises(ValueError, np.random.choice, a, p=probs*0.9)
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/setup.py
new file mode 100644
index 0000000000..dcb87721cd
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/setup.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('numpy', parent_package, top_path)
+
+    config.add_subpackage('compat')
+    config.add_subpackage('core')
+    config.add_subpackage('distutils')
+    config.add_subpackage('doc')
+    config.add_subpackage('f2py')
+    config.add_subpackage('fft')
+    config.add_subpackage('lib')
+    config.add_subpackage('linalg')
+    config.add_subpackage('ma')
+    config.add_subpackage('matrixlib')
+    config.add_subpackage('polynomial')
+    config.add_subpackage('random')
+    config.add_subpackage('testing')
+    config.add_data_dir('doc')
+    config.add_data_dir('tests')
+    config.make_config_py() # installs __config__.py
+    return config
+
+if __name__ == '__main__':
+    print('This is the wrong setup.py file to run')
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/__init__.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/__init__.py
new file mode 100644
index 0000000000..625fdecdc9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/__init__.py
@@ -0,0 +1,15 @@
+"""Common test support for all numpy test scripts.
+
+This single module should provide all the common functionality for numpy tests
+in a single location, so that test scripts can just import it and work right
+away.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+from unittest import TestCase
+
+from . import decorators as dec
+from .nosetester import run_module_suite, NoseTester as Tester
+from .utils import *
+test = nosetester._numpy_tester().test
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/decorators.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/decorators.py
new file mode 100644
index 0000000000..6cde298e1c
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/decorators.py
@@ -0,0 +1,272 @@
+"""
+Decorators for labeling and modifying behavior of test objects.
+
+Decorators that merely return a modified version of the original
+function object are straightforward. Decorators that return a new
+function object need to use
+::
+
+  nose.tools.make_decorator(original_function)(decorator)
+
+in returning the decorator, in order to preserve meta-data such as
+function name, setup and teardown functions and so on - see
+``nose.tools`` for more information.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import collections
+
+from .utils import SkipTest
+
+def slow(t):
+    """
+    Label a test as 'slow'.
+
+    The exact definition of a slow test is obviously both subjective and
+    hardware-dependent, but in general any individual test that requires more
+    than a second or two should be labeled as slow (the whole suite consits of
+    thousands of tests, so even a second is significant).
+
+    Parameters
+    ----------
+    t : callable
+        The test to label as slow.
+
+    Returns
+    -------
+    t : callable
+        The decorated test `t`.
+
+    Examples
+    --------
+    The `numpy.testing` module includes ``import decorators as dec``.
+    A test can be decorated as slow like this::
+
+      from numpy.testing import *
+
+      @dec.slow
+      def test_big(self):
+          print('Big, slow test')
+
+    """
+
+    t.slow = True
+    return t
+
+def setastest(tf=True):
+    """
+    Signals to nose that this function is or is not a test.
+
+    Parameters
+    ----------
+    tf : bool
+        If True, specifies that the decorated callable is a test.
+        If False, specifies that the decorated callable is not a test.
+        Default is True.
+
+    Notes
+    -----
+    This decorator can't use the nose namespace, because it can be
+    called from a non-test module. See also ``istest`` and ``nottest`` in
+    ``nose.tools``.
+
+    Examples
+    --------
+    `setastest` can be used in the following way::
+
+      from numpy.testing.decorators import setastest
+
+      @setastest(False)
+      def func_with_test_in_name(arg1, arg2):
+          pass
+
+    """
+    def set_test(t):
+        t.__test__ = tf
+        return t
+    return set_test
+
+def skipif(skip_condition, msg=None):
+    """
+    Make function raise SkipTest exception if a given condition is true.
+
+    If the condition is a callable, it is used at runtime to dynamically
+    make the decision. This is useful for tests that may require costly
+    imports, to delay the cost until the test suite is actually executed.
+
+    Parameters
+    ----------
+    skip_condition : bool or callable
+        Flag to determine whether to skip the decorated test.
+    msg : str, optional
+        Message to give on raising a SkipTest exception. Default is None.
+
+    Returns
+    -------
+    decorator : function
+        Decorator which, when applied to a function, causes SkipTest
+        to be raised when `skip_condition` is True, and the function
+        to be called normally otherwise.
+
+    Notes
+    -----
+    The decorator itself is decorated with the ``nose.tools.make_decorator``
+    function in order to transmit function name, and various other metadata.
+
+    """
+
+    def skip_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+
+        # Allow for both boolean or callable skip conditions.
+        if isinstance(skip_condition, collections.Callable):
+            skip_val = lambda: skip_condition()
+        else:
+            skip_val = lambda: skip_condition
+
+        def get_msg(func,msg=None):
+            """Skip message with information about function being skipped."""
+            if msg is None:
+                out = 'Test skipped due to test condition'
+            else:
+                out = msg
+
+            return "Skipping test: %s: %s" % (func.__name__, out)
+
+        # We need to define *two* skippers because Python doesn't allow both
+        # return with value and yield inside the same function.
+        def skipper_func(*args, **kwargs):
+            """Skipper for normal test functions."""
+            if skip_val():
+                raise SkipTest(get_msg(f, msg))
+            else:
+                return f(*args, **kwargs)
+
+        def skipper_gen(*args, **kwargs):
+            """Skipper for test generators."""
+            if skip_val():
+                raise SkipTest(get_msg(f, msg))
+            else:
+                for x in f(*args, **kwargs):
+                    yield x
+
+        # Choose the right skipper to use when building the actual decorator.
+        if nose.util.isgenerator(f):
+            skipper = skipper_gen
+        else:
+            skipper = skipper_func
+
+        return nose.tools.make_decorator(f)(skipper)
+
+    return skip_decorator
+
+
+def knownfailureif(fail_condition, msg=None):
+    """
+    Make function raise KnownFailureException exception if given condition is true.
+
+    If the condition is a callable, it is used at runtime to dynamically
+    make the decision. This is useful for tests that may require costly
+    imports, to delay the cost until the test suite is actually executed.
+
+    Parameters
+    ----------
+    fail_condition : bool or callable
+        Flag to determine whether to mark the decorated test as a known
+        failure (if True) or not (if False).
+    msg : str, optional
+        Message to give on raising a KnownFailureException exception.
+        Default is None.
+
+    Returns
+    -------
+    decorator : function
+        Decorator, which, when applied to a function, causes
+        KnownFailureException to be raised when `fail_condition` is True,
+        and the function to be called normally otherwise.
+
+    Notes
+    -----
+    The decorator itself is decorated with the ``nose.tools.make_decorator``
+    function in order to transmit function name, and various other metadata.
+
+    """
+    if msg is None:
+        msg = 'Test skipped due to known failure'
+
+    # Allow for both boolean or callable known failure conditions.
+    if isinstance(fail_condition, collections.Callable):
+        fail_val = lambda: fail_condition()
+    else:
+        fail_val = lambda: fail_condition
+
+    def knownfail_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+        from .noseclasses import KnownFailureException
+
+        def knownfailer(*args, **kwargs):
+            if fail_val():
+                raise KnownFailureException(msg)
+            else:
+                return f(*args, **kwargs)
+        return nose.tools.make_decorator(f)(knownfailer)
+
+    return knownfail_decorator
+
+def deprecated(conditional=True):
+    """
+    Filter deprecation warnings while running the test suite.
+
+    This decorator can be used to filter DeprecationWarning's, to avoid
+    printing them during the test suite run, while checking that the test
+    actually raises a DeprecationWarning.
+
+    Parameters
+    ----------
+    conditional : bool or callable, optional
+        Flag to determine whether to mark test as deprecated or not. If the
+        condition is a callable, it is used at runtime to dynamically make the
+        decision. Default is True.
+
+    Returns
+    -------
+    decorator : function
+        The `deprecated` decorator itself.
+
+    Notes
+    -----
+    .. versionadded:: 1.4.0
+
+    """
+    def deprecate_decorator(f):
+        # Local import to avoid a hard nose dependency and only incur the
+        # import time overhead at actual test-time.
+        import nose
+
+        def _deprecated_imp(*args, **kwargs):
+            # Poor man's replacement for the with statement
+            with warnings.catch_warnings(record=True) as l:
+                warnings.simplefilter('always')
+                f(*args, **kwargs)
+                if not len(l) > 0:
+                    raise AssertionError("No warning raised when calling %s"
+                            % f.__name__)
+                if not l[0].category is DeprecationWarning:
+                    raise AssertionError("First warning for %s is not a "
+                            "DeprecationWarning( is %s)" % (f.__name__, l[0]))
+
+        if isinstance(conditional, collections.Callable):
+            cond = conditional()
+        else:
+            cond = conditional
+        if cond:
+            return nose.tools.make_decorator(f)(_deprecated_imp)
+        else:
+            return f
+    return deprecate_decorator
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.py
new file mode 100644
index 0000000000..ee9d1b4dfe
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.py
@@ -0,0 +1,340 @@
+# These classes implement a doctest runner plugin for nose, a "known failure"
+# error class, and a customized TestProgram for NumPy.
+
+# Because this module imports nose directly, it should not
+# be used except by nosetester.py to avoid a general NumPy
+# dependency on nose.
+from __future__ import division, absolute_import, print_function
+
+import os
+import doctest
+import inspect
+
+import nose
+from nose.plugins import doctests as npd
+from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
+from nose.plugins.base import Plugin
+from nose.util import src
+import numpy
+from .nosetester import get_package_name
+from .utils import KnownFailureException, KnownFailureTest
+
+
+# Some of the classes in this module begin with 'Numpy' to clearly distinguish
+# them from the plethora of very similar names from nose/unittest/doctest
+
+#-----------------------------------------------------------------------------
+# Modified version of the one in the stdlib, that fixes a python bug (doctests
+# not found in extension modules, http://bugs.python.org/issue3158)
+class NumpyDocTestFinder(doctest.DocTestFinder):
+
+    def _from_module(self, module, object):
+        """
+        Return true if the given object is defined in the given
+        module.
+        """
+        if module is None:
+            return True
+        elif inspect.isfunction(object):
+            return module.__dict__ is object.__globals__
+        elif inspect.isbuiltin(object):
+            return module.__name__ == object.__module__
+        elif inspect.isclass(object):
+            return module.__name__ == object.__module__
+        elif inspect.ismethod(object):
+            # This one may be a bug in cython that fails to correctly set the
+            # __module__ attribute of methods, but since the same error is easy
+            # to make by extension code writers, having this safety in place
+            # isn't such a bad idea
+            return module.__name__ == object.__self__.__class__.__module__
+        elif inspect.getmodule(object) is not None:
+            return module is inspect.getmodule(object)
+        elif hasattr(object, '__module__'):
+            return module.__name__ == object.__module__
+        elif isinstance(object, property):
+            return True  # [XX] no way not be sure.
+        else:
+            raise ValueError("object must be a class or function")
+
+    def _find(self, tests, obj, name, module, source_lines, globs, seen):
+        """
+        Find tests for the given object and any contained objects, and
+        add them to `tests`.
+        """
+
+        doctest.DocTestFinder._find(self, tests, obj, name, module,
+                                    source_lines, globs, seen)
+
+        # Below we re-run pieces of the above method with manual modifications,
+        # because the original code is buggy and fails to correctly identify
+        # doctests in extension modules.
+
+        # Local shorthands
+        from inspect import (
+            isroutine, isclass, ismodule, isfunction, ismethod
+            )
+
+        # Look for tests in a module's contained objects.
+        if ismodule(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                valname1 = '%s.%s' % (name, valname)
+                if ( (isroutine(val) or isclass(val))
+                     and self._from_module(module, val)):
+
+                    self._find(tests, val, valname1, module, source_lines,
+                               globs, seen)
+
+        # Look for tests in a class's contained objects.
+        if isclass(obj) and self._recurse:
+            for valname, val in obj.__dict__.items():
+                # Special handling for staticmethod/classmethod.
+                if isinstance(val, staticmethod):
+                    val = getattr(obj, valname)
+                if isinstance(val, classmethod):
+                    val = getattr(obj, valname).__func__
+
+                # Recurse to methods, properties, and nested classes.
+                if ((isfunction(val) or isclass(val) or
+                     ismethod(val) or isinstance(val, property)) and
+                      self._from_module(module, val)):
+                    valname = '%s.%s' % (name, valname)
+                    self._find(tests, val, valname, module, source_lines,
+                               globs, seen)
+
+
+# second-chance checker; if the default comparison doesn't
+# pass, then see if the expected output string contains flags that
+# tell us to ignore the output
+class NumpyOutputChecker(doctest.OutputChecker):
+    def check_output(self, want, got, optionflags):
+        ret = doctest.OutputChecker.check_output(self, want, got,
+                                                 optionflags)
+        if not ret:
+            if "#random" in want:
+                return True
+
+            # it would be useful to normalize endianness so that
+            # bigendian machines don't fail all the tests (and there are
+            # actually some bigendian examples in the doctests). Let's try
+            # making them all little endian
+            got = got.replace("'>", "'<")
+            want = want.replace("'>", "'<")
+
+            # try to normalize out 32 and 64 bit default int sizes
+            for sz in [4, 8]:
+                got = got.replace("'<i%d'" % sz, "int")
+                want = want.replace("'<i%d'" % sz, "int")
+
+            ret = doctest.OutputChecker.check_output(self, want,
+                    got, optionflags)
+
+        return ret
+
+
+# Subclass nose.plugins.doctests.DocTestCase to work around a bug in
+# its constructor that blocks non-default arguments from being passed
+# down into doctest.DocTestCase
+class NumpyDocTestCase(npd.DocTestCase):
+    def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
+                 checker=None, obj=None, result_var='_'):
+        self._result_var = result_var
+        self._nose_obj = obj
+        doctest.DocTestCase.__init__(self, test,
+                                     optionflags=optionflags,
+                                     setUp=setUp, tearDown=tearDown,
+                                     checker=checker)
+
+
+print_state = numpy.get_printoptions()
+
+class NumpyDoctest(npd.Doctest):
+    name = 'numpydoctest'   # call nosetests with --with-numpydoctest
+    score = 1000  # load late, after doctest builtin
+
+    # always use whitespace and ellipsis options for doctests
+    doctest_optflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
+
+    # files that should be ignored for doctests
+    doctest_ignore = ['generate_numpy_api.py',
+                      'setup.py']
+
+    # Custom classes; class variables to allow subclassing
+    doctest_case_class = NumpyDocTestCase
+    out_check_class = NumpyOutputChecker
+    test_finder_class = NumpyDocTestFinder
+
+    # Don't use the standard doctest option handler; hard-code the option values
+    def options(self, parser, env=os.environ):
+        Plugin.options(self, parser, env)
+        # Test doctests in 'test' files / directories. Standard plugin default
+        # is False
+        self.doctest_tests = True
+        # Variable name; if defined, doctest results stored in this variable in
+        # the top-level namespace.  None is the standard default
+        self.doctest_result_var = None
+
+    def configure(self, options, config):
+        # parent method sets enabled flag from command line --with-numpydoctest
+        Plugin.configure(self, options, config)
+        self.finder = self.test_finder_class()
+        self.parser = doctest.DocTestParser()
+        if self.enabled:
+            # Pull standard doctest out of plugin list; there's no reason to run
+            # both.  In practice the Unplugger plugin above would cover us when
+            # run from a standard numpy.test() call; this is just in case
+            # someone wants to run our plugin outside the numpy.test() machinery
+            config.plugins.plugins = [p for p in config.plugins.plugins
+                                      if p.name != 'doctest']
+
+    def set_test_context(self, test):
+        """ Configure `test` object to set test context
+
+        We set the numpy / scipy standard doctest namespace
+
+        Parameters
+        ----------
+        test : test object
+            with ``globs`` dictionary defining namespace
+
+        Returns
+        -------
+        None
+
+        Notes
+        -----
+        `test` object modified in place
+        """
+        # set the namespace for tests
+        pkg_name = get_package_name(os.path.dirname(test.filename))
+
+        # Each doctest should execute in an environment equivalent to
+        # starting Python and executing "import numpy as np", and,
+        # for SciPy packages, an additional import of the local
+        # package (so that scipy.linalg.basic.py's doctests have an
+        # implicit "from scipy import linalg" as well.
+        #
+        # Note: __file__ allows the doctest in NoseTester to run
+        # without producing an error
+        test.globs = {'__builtins__':__builtins__,
+                      '__file__':'__main__',
+                      '__name__':'__main__',
+                      'np':numpy}
+        # add appropriate scipy import for SciPy tests
+        if 'scipy' in pkg_name:
+            p = pkg_name.split('.')
+            p2 = p[-1]
+            test.globs[p2] = __import__(pkg_name, test.globs, {}, [p2])
+
+    # Override test loading to customize test context (with set_test_context
+    # method), set standard docstring options, and install our own test output
+    # checker
+    def loadTestsFromModule(self, module):
+        if not self.matches(module.__name__):
+            npd.log.debug("Doctest doesn't want module %s", module)
+            return
+        try:
+            tests = self.finder.find(module)
+        except AttributeError:
+            # nose allows module.__test__ = False; doctest does not and
+            # throws AttributeError
+            return
+        if not tests:
+            return
+        tests.sort()
+        module_file = src(module.__file__)
+        for test in tests:
+            if not test.examples:
+                continue
+            if not test.filename:
+                test.filename = module_file
+            # Set test namespace; test altered in place
+            self.set_test_context(test)
+            yield self.doctest_case_class(test,
+                                          optionflags=self.doctest_optflags,
+                                          checker=self.out_check_class(),
+                                          result_var=self.doctest_result_var)
+
+    # Add an afterContext method to nose.plugins.doctests.Doctest in order
+    # to restore print options to the original state after each doctest
+    def afterContext(self):
+        numpy.set_printoptions(**print_state)
+
+    # Ignore NumPy-specific build files that shouldn't be searched for tests
+    def wantFile(self, file):
+        bn = os.path.basename(file)
+        if bn in self.doctest_ignore:
+            return False
+        return npd.Doctest.wantFile(self, file)
+
+
+class Unplugger(object):
+    """ Nose plugin to remove named plugin late in loading
+
+    By default it removes the "doctest" plugin.
+    """
+    name = 'unplugger'
+    enabled = True  # always enabled
+    score = 4000  # load late in order to be after builtins
+
+    def __init__(self, to_unplug='doctest'):
+        self.to_unplug = to_unplug
+
+    def options(self, parser, env):
+        pass
+
+    def configure(self, options, config):
+        # Pull named plugin out of plugins list
+        config.plugins.plugins = [p for p in config.plugins.plugins
+                                  if p.name != self.to_unplug]
+
+
+class KnownFailurePlugin(ErrorClassPlugin):
+    '''Plugin that installs a KNOWNFAIL error class for the
+    KnownFailureClass exception.  When KnownFailure is raised,
+    the exception will be logged in the knownfail attribute of the
+    result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the
+    exception will not be counted as an error or failure.'''
+    enabled = True
+    knownfail = ErrorClass(KnownFailureException,
+                           label='KNOWNFAIL',
+                           isfailure=False)
+
+    def options(self, parser, env=os.environ):
+        env_opt = 'NOSE_WITHOUT_KNOWNFAIL'
+        parser.add_option('--no-knownfail', action='store_true',
+                          dest='noKnownFail', default=env.get(env_opt, False),
+                          help='Disable special handling of KnownFailure '
+                               'exceptions')
+
+    def configure(self, options, conf):
+        if not self.can_configure:
+            return
+        self.conf = conf
+        disable = getattr(options, 'noKnownFail', False)
+        if disable:
+            self.enabled = False
+
+KnownFailure = KnownFailurePlugin   # backwards compat
+
+
+# Class allows us to save the results of the tests in runTests - see runTests
+# method docstring for details
+class NumpyTestProgram(nose.core.TestProgram):
+    def runTests(self):
+        """Run Tests. Returns true on success, false on failure, and
+        sets self.success to the same value.
+
+        Because nose currently discards the test result object, but we need
+        to return it to the user, override TestProgram.runTests to retain
+        the result
+        """
+        if self.testRunner is None:
+            self.testRunner = nose.core.TextTestRunner(stream=self.config.stream,
+                                                       verbosity=self.config.verbosity,
+                                                       config=self.config)
+        plug_runner = self.config.plugins.prepareTestRunner(self.testRunner)
+        if plug_runner is not None:
+            self.testRunner = plug_runner
+        self.result = self.testRunner.run(self.test)
+        self.success = self.result.wasSuccessful()
+        return self.success
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.py
new file mode 100644
index 0000000000..e3205837c9
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.py
@@ -0,0 +1,516 @@
+"""
+Nose test running.
+
+This module implements ``test()`` and ``bench()`` functions for NumPy modules.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import warnings
+from numpy.compat import basestring
+import numpy as np
+
+
+def get_package_name(filepath):
+    """
+    Given a path where a package is installed, determine its name.
+
+    Parameters
+    ----------
+    filepath : str
+        Path to a file. If the determination fails, "numpy" is returned.
+
+    Examples
+    --------
+    >>> np.testing.nosetester.get_package_name('nonsense')
+    'numpy'
+
+    """
+
+    fullpath = filepath[:]
+    pkg_name = []
+    while 'site-packages' in filepath or 'dist-packages' in filepath:
+        filepath, p2 = os.path.split(filepath)
+        if p2 in ('site-packages', 'dist-packages'):
+            break
+        pkg_name.append(p2)
+
+    # if package name determination failed, just default to numpy/scipy
+    if not pkg_name:
+        if 'scipy' in fullpath:
+            return 'scipy'
+        else:
+            return 'numpy'
+
+    # otherwise, reverse to get correct order and return
+    pkg_name.reverse()
+
+    # don't include the outer egg directory
+    if pkg_name[0].endswith('.egg'):
+        pkg_name.pop(0)
+
+    return '.'.join(pkg_name)
+
+def import_nose():
+    """ Import nose only when needed.
+    """
+    fine_nose = True
+    minimum_nose_version = (1, 0, 0)
+    try:
+        import nose
+    except ImportError:
+        fine_nose = False
+    else:
+        if nose.__versioninfo__ < minimum_nose_version:
+            fine_nose = False
+
+    if not fine_nose:
+        msg = ('Need nose >= %d.%d.%d for tests - see '
+               'http://somethingaboutorange.com/mrl/projects/nose' %
+               minimum_nose_version)
+        raise ImportError(msg)
+
+    return nose
+
+def run_module_suite(file_to_run=None, argv=None):
+    """
+    Run a test module.
+
+    Equivalent to calling ``$ nosetests <argv> <file_to_run>`` from
+    the command line
+
+    Parameters
+    ----------
+    file_to_run : str, optional
+        Path to test module, or None.
+        By default, run the module from which this function is called.
+    argv : list of strings
+        Arguments to be passed to the nose test runner. ``argv[0]`` is
+        ignored. All command line arguments accepted by ``nosetests``
+        will work. If it is the default value None, sys.argv is used.
+
+        .. versionadded:: 1.9.0
+
+    Examples
+    --------
+    Adding the following::
+
+        if __name__ == "__main__" :
+            run_module_suite(argv=sys.argv)
+
+    at the end of a test module will run the tests when that module is
+    called in the python interpreter.
+
+    Alternatively, calling::
+
+    >>> run_module_suite(file_to_run="numpy/tests/test_matlib.py")
+
+    from an interpreter will run all the test routine in 'test_matlib.py'.
+    """
+    if file_to_run is None:
+        f = sys._getframe(1)
+        file_to_run = f.f_locals.get('__file__', None)
+        if file_to_run is None:
+            raise AssertionError
+
+    if argv is None:
+        argv = sys.argv + [file_to_run]
+    else:
+        argv = argv + [file_to_run]
+
+    nose = import_nose()
+    from .noseclasses import KnownFailurePlugin
+    nose.run(argv=argv, addplugins=[KnownFailurePlugin()])
+
+
+class NoseTester(object):
+    """
+    Nose test runner.
+
+    This class is made available as numpy.testing.Tester, and a test function
+    is typically added to a package's __init__.py like so::
+
+      from numpy.testing import Tester
+      test = Tester().test
+
+    Calling this test function finds and runs all tests associated with the
+    package and all its sub-packages.
+
+    Attributes
+    ----------
+    package_path : str
+        Full path to the package to test.
+    package_name : str
+        Name of the package to test.
+
+    Parameters
+    ----------
+    package : module, str or None, optional
+        The package to test. If a string, this should be the full path to
+        the package. If None (default), `package` is set to the module from
+        which `NoseTester` is initialized.
+    raise_warnings : None, str or sequence of warnings, optional
+        This specifies which warnings to configure as 'raise' instead
+        of 'warn' during the test execution.  Valid strings are:
+
+          - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
+          - "release" : equals ``()``, don't raise on any warnings.
+
+        Default is "release".
+    depth : int, optional
+        If `package` is None, then this can be used to initialize from the
+        module of the caller of (the caller of (...)) the code that
+        initializes `NoseTester`. Default of 0 means the module of the
+        immediate caller; higher values are useful for utility routines that
+        want to initialize `NoseTester` objects on behalf of other code.
+
+    """
+    def __init__(self, package=None, raise_warnings="release", depth=0):
+        # Back-compat: 'None' used to mean either "release" or "develop"
+        # depending on whether this was a release or develop version of
+        # numpy. Those semantics were fine for testing numpy, but not so
+        # helpful for downstream projects like scipy that use
+        # numpy.testing. (They want to set this based on whether *they* are a
+        # release or develop version, not whether numpy is.) So we continue to
+        # accept 'None' for back-compat, but it's now just an alias for the
+        # default "release".
+        if raise_warnings is None:
+            raise_warnings = "release"
+
+        package_name = None
+        if package is None:
+            f = sys._getframe(1 + depth)
+            package_path = f.f_locals.get('__file__', None)
+            if package_path is None:
+                raise AssertionError
+            package_path = os.path.dirname(package_path)
+            package_name = f.f_locals.get('__name__', None)
+        elif isinstance(package, type(os)):
+            package_path = os.path.dirname(package.__file__)
+            package_name = getattr(package, '__name__', None)
+        else:
+            package_path = str(package)
+
+        self.package_path = package_path
+
+        # Find the package name under test; this name is used to limit coverage
+        # reporting (if enabled).
+        if package_name is None:
+            package_name = get_package_name(package_path)
+        self.package_name = package_name
+
+        # Set to "release" in constructor in maintenance branches.
+        self.raise_warnings = raise_warnings
+
+    def _test_argv(self, label, verbose, extra_argv):
+        ''' Generate argv for nosetest command
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            see ``test`` docstring
+        verbose : int, optional
+            Verbosity value for test outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+
+        Returns
+        -------
+        argv : list
+            command line arguments that will be passed to nose
+        '''
+        argv = [__file__, self.package_path, '-s']
+        if label and label != 'full':
+            if not isinstance(label, basestring):
+                raise TypeError('Selection label should be a string')
+            if label == 'fast':
+                label = 'not slow'
+            argv += ['-A', label]
+        argv += ['--verbosity', str(verbose)]
+
+        # When installing with setuptools, and also in some other cases, the
+        # test_*.py files end up marked +x executable. Nose, by default, does
+        # not run files marked with +x as they might be scripts. However, in
+        # our case nose only looks for test_*.py files under the package
+        # directory, which should be safe.
+        argv += ['--exe']
+
+        if extra_argv:
+            argv += extra_argv
+        return argv
+
+    def _show_system_info(self):
+        nose = import_nose()
+
+        import numpy
+        print("NumPy version %s" % numpy.__version__)
+        relaxed_strides = numpy.ones((10, 1), order="C").flags.f_contiguous
+        print("NumPy relaxed strides checking option:", relaxed_strides)
+        npdir = os.path.dirname(numpy.__file__)
+        print("NumPy is installed in %s" % npdir)
+
+        if 'scipy' in self.package_name:
+            import scipy
+            print("SciPy version %s" % scipy.__version__)
+            spdir = os.path.dirname(scipy.__file__)
+            print("SciPy is installed in %s" % spdir)
+
+        pyversion = sys.version.replace('\n', '')
+        print("Python version %s" % pyversion)
+        print("nose version %d.%d.%d" % nose.__versioninfo__)
+
+    def _get_custom_doctester(self):
+        """ Return instantiated plugin for doctests
+
+        Allows subclassing of this class to override doctester
+
+        A return value of None means use the nose builtin doctest plugin
+        """
+        from .noseclasses import NumpyDoctest
+        return NumpyDoctest()
+
+    def prepare_test_args(self, label='fast', verbose=1, extra_argv=None,
+                          doctests=False, coverage=False):
+        """
+        Run tests for module using nose.
+
+        This method does the heavy lifting for the `test` method. It takes all
+        the same arguments, for details see `test`.
+
+        See Also
+        --------
+        test
+
+        """
+        # fail with nice error message if nose is not present
+        import_nose()
+        # compile argv
+        argv = self._test_argv(label, verbose, extra_argv)
+        # our way of doing coverage
+        if coverage:
+            argv += ['--cover-package=%s' % self.package_name, '--with-coverage',
+                   '--cover-tests', '--cover-erase']
+        # construct list of plugins
+        import nose.plugins.builtin
+        from .noseclasses import KnownFailurePlugin, Unplugger
+        plugins = [KnownFailurePlugin()]
+        plugins += [p() for p in nose.plugins.builtin.plugins]
+        # add doctesting if required
+        doctest_argv = '--with-doctest' in argv
+        if doctests == False and doctest_argv:
+            doctests = True
+        plug = self._get_custom_doctester()
+        if plug is None:
+            # use standard doctesting
+            if doctests and not doctest_argv:
+                argv += ['--with-doctest']
+        else:  # custom doctesting
+            if doctest_argv:  # in fact the unplugger would take care of this
+                argv.remove('--with-doctest')
+            plugins += [Unplugger('doctest'), plug]
+            if doctests:
+                argv += ['--with-' + plug.name]
+        return argv, plugins
+
+    def test(self, label='fast', verbose=1, extra_argv=None,
+            doctests=False, coverage=False,
+            raise_warnings=None):
+        """
+        Run tests for module using nose.
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            Identifies the tests to run. This can be a string to pass to
+            the nosetests executable with the '-A' option, or one of several
+            special values.  Special values are:
+            * 'fast' - the default - which corresponds to the ``nosetests -A``
+              option of 'not slow'.
+            * 'full' - fast (as above) and slow tests as in the
+              'no -A' option to nosetests - this is the same as ''.
+            * None or '' - run all tests.
+            attribute_identifier - string passed directly to nosetests as '-A'.
+        verbose : int, optional
+            Verbosity value for test outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+        doctests : bool, optional
+            If True, run doctests in module. Default is False.
+        coverage : bool, optional
+            If True, report coverage of NumPy code. Default is False.
+            (This requires the `coverage module:
+             <http://nedbatchelder.com/code/modules/coverage.html>`_).
+        raise_warnings : str or sequence of warnings, optional
+            This specifies which warnings to configure as 'raise' instead
+            of 'warn' during the test execution.  Valid strings are:
+
+              - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
+              - "release" : equals ``()``, don't raise on any warnings.
+
+        Returns
+        -------
+        result : object
+            Returns the result of running the tests as a
+            ``nose.result.TextTestResult`` object.
+
+        Notes
+        -----
+        Each NumPy module exposes `test` in its namespace to run all tests for it.
+        For example, to run all tests for numpy.lib:
+
+        >>> np.lib.test() #doctest: +SKIP
+
+        Examples
+        --------
+        >>> result = np.lib.test() #doctest: +SKIP
+        Running unit tests for numpy.lib
+        ...
+        Ran 976 tests in 3.933s
+
+        OK
+
+        >>> result.errors #doctest: +SKIP
+        []
+        >>> result.knownfail #doctest: +SKIP
+        []
+        """
+
+        # cap verbosity at 3 because nose becomes *very* verbose beyond that
+        verbose = min(verbose, 3)
+
+        from . import utils
+        utils.verbose = verbose
+
+        if doctests:
+            print("Running unit tests and doctests for %s" % self.package_name)
+        else:
+            print("Running unit tests for %s" % self.package_name)
+
+        self._show_system_info()
+
+        # reset doctest state on every run
+        import doctest
+        doctest.master = None
+
+        if raise_warnings is None:
+            raise_warnings = self.raise_warnings
+
+        _warn_opts = dict(develop=(DeprecationWarning, RuntimeWarning),
+                          release=())
+        if isinstance(raise_warnings, basestring):
+            raise_warnings = _warn_opts[raise_warnings]
+
+        with warnings.catch_warnings():
+            # Reset the warning filters to the default state,
+            # so that running the tests is more repeatable.
+            warnings.resetwarnings()
+            # Set all warnings to 'warn', this is because the default 'once'
+            # has the bad property of possibly shadowing later warnings.
+            warnings.filterwarnings('always')
+            # Force the requested warnings to raise
+            for warningtype in raise_warnings:
+                warnings.filterwarnings('error', category=warningtype)
+            # Filter out annoying import messages.
+            warnings.filterwarnings('ignore', message='Not importing directory')
+            warnings.filterwarnings("ignore", message="numpy.dtype size changed")
+            warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
+            warnings.filterwarnings("ignore", category=np.ModuleDeprecationWarning)
+            warnings.filterwarnings("ignore", category=FutureWarning)
+            # Filter out boolean '-' deprecation messages. This allows
+            # older versions of scipy to test without a flood of messages.
+            warnings.filterwarnings("ignore", message=".*boolean negative.*")
+            warnings.filterwarnings("ignore", message=".*boolean subtract.*")
+            # Filter out some deprecation warnings inside nose 1.3.7 when run
+            # on python 3.5b2. See
+            #     https://github.com/nose-devs/nose/issues/929
+            warnings.filterwarnings("ignore", message=".*getargspec.*",
+                                    category=DeprecationWarning,
+                                    module="nose\.")
+
+            from .noseclasses import NumpyTestProgram
+
+            argv, plugins = self.prepare_test_args(
+                    label, verbose, extra_argv, doctests, coverage)
+            t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins)
+
+        return t.result
+
+    def bench(self, label='fast', verbose=1, extra_argv=None):
+        """
+        Run benchmarks for module using nose.
+
+        Parameters
+        ----------
+        label : {'fast', 'full', '', attribute identifier}, optional
+            Identifies the benchmarks to run. This can be a string to pass to
+            the nosetests executable with the '-A' option, or one of several
+            special values.  Special values are:
+            * 'fast' - the default - which corresponds to the ``nosetests -A``
+              option of 'not slow'.
+            * 'full' - fast (as above) and slow benchmarks as in the
+              'no -A' option to nosetests - this is the same as ''.
+            * None or '' - run all tests.
+            attribute_identifier - string passed directly to nosetests as '-A'.
+        verbose : int, optional
+            Verbosity value for benchmark outputs, in the range 1-10. Default is 1.
+        extra_argv : list, optional
+            List with any extra arguments to pass to nosetests.
+
+        Returns
+        -------
+        success : bool
+            Returns True if running the benchmarks works, False if an error
+            occurred.
+
+        Notes
+        -----
+        Benchmarks are like tests, but have names starting with "bench" instead
+        of "test", and can be found under the "benchmarks" sub-directory of the
+        module.
+
+        Each NumPy module exposes `bench` in its namespace to run all benchmarks
+        for it.
+
+        Examples
+        --------
+        >>> success = np.lib.bench() #doctest: +SKIP
+        Running benchmarks for numpy.lib
+        ...
+        using 562341 items:
+        unique:
+        0.11
+        unique1d:
+        0.11
+        ratio: 1.0
+        nUnique: 56230 == 56230
+        ...
+        OK
+
+        >>> success #doctest: +SKIP
+        True
+
+        """
+
+        print("Running benchmarks for %s" % self.package_name)
+        self._show_system_info()
+
+        argv = self._test_argv(label, verbose, extra_argv)
+        argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep]
+
+        # import nose or make informative error
+        nose = import_nose()
+
+        # get plugin to disable doctests
+        from .noseclasses import Unplugger
+        add_plugins = [Unplugger('doctest')]
+
+        return nose.run(argv=argv, addplugins=add_plugins)
+
+def _numpy_tester():
+    if hasattr(np, "__version__") and ".dev0" in np.__version__:
+        mode = "develop"
+    else:
+        mode = "release"
+    return NoseTester(raise_warnings=mode, depth=1)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
new file mode 100644
index 0000000000..634b8ae542
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2
+"""Prints type-coercion tables for the built-in NumPy types
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+
+# Generic object that can be added, but doesn't do anything else
+class GenericObject(object):
+    def __init__(self, v):
+        self.v = v
+
+    def __add__(self, other):
+        return self
+
+    def __radd__(self, other):
+        return self
+
+    dtype = np.dtype('O')
+
+def print_cancast_table(ntypes):
+    print('X', end=' ')
+    for char in ntypes:
+        print(char, end=' ')
+    print()
+    for row in ntypes:
+        print(row, end=' ')
+        for col in ntypes:
+            print(int(np.can_cast(row, col)), end=' ')
+        print()
+
+def print_coercion_table(ntypes, inputfirstvalue, inputsecondvalue, firstarray, use_promote_types=False):
+    print('+', end=' ')
+    for char in ntypes:
+        print(char, end=' ')
+    print()
+    for row in ntypes:
+        if row == 'O':
+            rowtype = GenericObject
+        else:
+            rowtype = np.obj2sctype(row)
+
+        print(row, end=' ')
+        for col in ntypes:
+            if col == 'O':
+                coltype = GenericObject
+            else:
+                coltype = np.obj2sctype(col)
+            try:
+                if firstarray:
+                    rowvalue = np.array([rowtype(inputfirstvalue)], dtype=rowtype)
+                else:
+                    rowvalue = rowtype(inputfirstvalue)
+                colvalue = coltype(inputsecondvalue)
+                if use_promote_types:
+                    char = np.promote_types(rowvalue.dtype, colvalue.dtype).char
+                else:
+                    value = np.add(rowvalue, colvalue)
+                    if isinstance(value, np.ndarray):
+                        char = value.dtype.char
+                    else:
+                        char = np.dtype(type(value)).char
+            except ValueError:
+                char = '!'
+            except OverflowError:
+                char = '@'
+            except TypeError:
+                char = '#'
+            print(char, end=' ')
+        print()
+
+print("can cast")
+print_cancast_table(np.typecodes['All'])
+print()
+print("In these tables, ValueError is '!', OverflowError is '@', TypeError is '#'")
+print()
+print("scalar + scalar")
+print_coercion_table(np.typecodes['All'], 0, 0, False)
+print()
+print("scalar + neg scalar")
+print_coercion_table(np.typecodes['All'], 0, -1, False)
+print()
+print("array + scalar")
+print_coercion_table(np.typecodes['All'], 0, 0, True)
+print()
+print("array + neg scalar")
+print_coercion_table(np.typecodes['All'], 0, -1, True)
+print()
+print("promote_types")
+print_coercion_table(np.typecodes['All'], 0, 0, False, True)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/setup.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/setup.py
new file mode 100644
index 0000000000..32c7413aae
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/setup.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python2
+from __future__ import division, print_function
+
+
+def configuration(parent_package='',top_path=None):
+    from numpy.distutils.misc_util import Configuration
+    config = Configuration('testing', parent_package, top_path)
+
+    config.add_data_dir('tests')
+    return config
+
+if __name__ == '__main__':
+    from numpy.distutils.core import setup
+    setup(maintainer="NumPy Developers",
+          maintainer_email="numpy-dev@numpy.org",
+          description="NumPy test module",
+          url="http://www.numpy.org",
+          license="NumPy License (BSD Style)",
+          configuration=configuration,
+          )
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
new file mode 100644
index 0000000000..7dbb5a8286
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
@@ -0,0 +1,182 @@
+from __future__ import division, absolute_import, print_function
+
+from numpy.testing import (dec, assert_, assert_raises, run_module_suite,
+                           SkipTest, KnownFailureException)
+import nose
+
+def test_slow():
+    @dec.slow
+    def slow_func(x, y, z):
+        pass
+
+    assert_(slow_func.slow)
+
+def test_setastest():
+    @dec.setastest()
+    def f_default(a):
+        pass
+
+    @dec.setastest(True)
+    def f_istest(a):
+        pass
+
+    @dec.setastest(False)
+    def f_isnottest(a):
+        pass
+
+    assert_(f_default.__test__)
+    assert_(f_istest.__test__)
+    assert_(not f_isnottest.__test__)
+
+class DidntSkipException(Exception):
+    pass
+
+def test_skip_functions_hardcoded():
+    @dec.skipif(True)
+    def f1(x):
+        raise DidntSkipException
+
+    try:
+        f1('a')
+    except DidntSkipException:
+        raise Exception('Failed to skip')
+    except SkipTest:
+        pass
+
+    @dec.skipif(False)
+    def f2(x):
+        raise DidntSkipException
+
+    try:
+        f2('a')
+    except DidntSkipException:
+        pass
+    except SkipTest:
+        raise Exception('Skipped when not expected to')
+
+
+def test_skip_functions_callable():
+    def skip_tester():
+        return skip_flag == 'skip me!'
+
+    @dec.skipif(skip_tester)
+    def f1(x):
+        raise DidntSkipException
+
+    try:
+        skip_flag = 'skip me!'
+        f1('a')
+    except DidntSkipException:
+        raise Exception('Failed to skip')
+    except SkipTest:
+        pass
+
+    @dec.skipif(skip_tester)
+    def f2(x):
+        raise DidntSkipException
+
+    try:
+        skip_flag = 'five is right out!'
+        f2('a')
+    except DidntSkipException:
+        pass
+    except SkipTest:
+        raise Exception('Skipped when not expected to')
+
+
+def test_skip_generators_hardcoded():
+    @dec.knownfailureif(True, "This test is known to fail")
+    def g1(x):
+        for i in range(x):
+            yield i
+
+    try:
+        for j in g1(10):
+            pass
+    except KnownFailureException:
+        pass
+    else:
+        raise Exception('Failed to mark as known failure')
+
+    @dec.knownfailureif(False, "This test is NOT known to fail")
+    def g2(x):
+        for i in range(x):
+            yield i
+        raise DidntSkipException('FAIL')
+
+    try:
+        for j in g2(10):
+            pass
+    except KnownFailureException:
+        raise Exception('Marked incorretly as known failure')
+    except DidntSkipException:
+        pass
+
+
+def test_skip_generators_callable():
+    def skip_tester():
+        return skip_flag == 'skip me!'
+
+    @dec.knownfailureif(skip_tester, "This test is known to fail")
+    def g1(x):
+        for i in range(x):
+            yield i
+
+    try:
+        skip_flag = 'skip me!'
+        for j in g1(10):
+            pass
+    except KnownFailureException:
+        pass
+    else:
+        raise Exception('Failed to mark as known failure')
+
+    @dec.knownfailureif(skip_tester, "This test is NOT known to fail")
+    def g2(x):
+        for i in range(x):
+            yield i
+        raise DidntSkipException('FAIL')
+
+    try:
+        skip_flag = 'do not skip'
+        for j in g2(10):
+            pass
+    except KnownFailureException:
+        raise Exception('Marked incorretly as known failure')
+    except DidntSkipException:
+        pass
+
+
+def test_deprecated():
+    @dec.deprecated(True)
+    def non_deprecated_func():
+        pass
+
+    @dec.deprecated()
+    def deprecated_func():
+        import warnings
+        warnings.warn("TEST: deprecated func", DeprecationWarning)
+
+    @dec.deprecated()
+    def deprecated_func2():
+        import warnings
+        warnings.warn("AHHHH")
+        raise ValueError
+
+    @dec.deprecated()
+    def deprecated_func3():
+        import warnings
+        warnings.warn("AHHHH")
+
+    # marked as deprecated, but does not raise DeprecationWarning
+    assert_raises(AssertionError, non_deprecated_func)
+    # should be silent
+    deprecated_func()
+    # fails if deprecated decorator just disables test. See #1453.
+    assert_raises(ValueError, deprecated_func2)
+    # first warnings is not a DeprecationWarning
+    assert_raises(AssertionError, deprecated_func3)
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
new file mode 100644
index 0000000000..43f9fb6ceb
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
@@ -0,0 +1,56 @@
+""" Doctests for NumPy-specific nose/doctest modifications
+
+"""
+from __future__ import division, absolute_import, print_function
+
+# try the #random directive on the output line
+def check_random_directive():
+    '''
+    >>> 2+2
+    <BadExample object at 0x084D05AC>  #random: may vary on your system
+    '''
+
+# check the implicit "import numpy as np"
+def check_implicit_np():
+    '''
+    >>> np.array([1,2,3])
+    array([1, 2, 3])
+    '''
+
+# there's some extraneous whitespace around the correct responses
+def check_whitespace_enabled():
+    '''
+    # whitespace after the 3
+    >>> 1+2
+    3
+
+    # whitespace before the 7
+    >>> 3+4
+     7
+    '''
+
+def check_empty_output():
+    """ Check that no output does not cause an error.
+
+    This is related to nose bug 445; the numpy plugin changed the
+    doctest-result-variable default and therefore hit this bug:
+    http://code.google.com/p/python-nose/issues/detail?id=445
+
+    >>> a = 10
+    """
+
+def check_skip():
+    """ Check skip directive
+
+    The test below should not run
+
+    >>> 1/0 #doctest: +SKIP
+    """
+
+
+if __name__ == '__main__':
+    # Run tests outside numpy test rig
+    import nose
+    from numpy.testing.noseclasses import NumpyDoctest
+    argv = ['', __file__, '--with-numpydoctest']
+    nose.core.TestProgram(argv=argv, addplugins=[NumpyDoctest()])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
new file mode 100644
index 0000000000..7de57d4080
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
@@ -0,0 +1,848 @@
+from __future__ import division, absolute_import, print_function
+
+import warnings
+import sys
+import os
+
+import numpy as np
+from numpy.testing import (
+    assert_equal, assert_array_equal, assert_almost_equal,
+    assert_array_almost_equal, build_err_msg, raises, assert_raises,
+    assert_warns, assert_no_warnings, assert_allclose, assert_approx_equal,
+    assert_array_almost_equal_nulp, assert_array_max_ulp,
+    clear_and_catch_warnings, run_module_suite,
+    assert_string_equal, assert_, tempdir, temppath, 
+    )
+import unittest
+
+
+class _GenericTest(object):
+
+    def _test_equal(self, a, b):
+        self._assert_func(a, b)
+
+    def _test_not_equal(self, a, b):
+        try:
+            self._assert_func(a, b)
+        except AssertionError:
+            pass
+        else:
+            raise AssertionError("a and b are found equal but are not")
+
+    def test_array_rank1_eq(self):
+        """Test two equal array of rank 1 are found equal."""
+        a = np.array([1, 2])
+        b = np.array([1, 2])
+
+        self._test_equal(a, b)
+
+    def test_array_rank1_noteq(self):
+        """Test two different array of rank 1 are found not equal."""
+        a = np.array([1, 2])
+        b = np.array([2, 2])
+
+        self._test_not_equal(a, b)
+
+    def test_array_rank2_eq(self):
+        """Test two equal array of rank 2 are found equal."""
+        a = np.array([[1, 2], [3, 4]])
+        b = np.array([[1, 2], [3, 4]])
+
+        self._test_equal(a, b)
+
+    def test_array_diffshape(self):
+        """Test two arrays with different shapes are found not equal."""
+        a = np.array([1, 2])
+        b = np.array([[1, 2], [1, 2]])
+
+        self._test_not_equal(a, b)
+
+    def test_objarray(self):
+        """Test object arrays."""
+        a = np.array([1, 1], dtype=np.object)
+        self._test_equal(a, 1)
+
+    def test_array_likes(self):
+        self._test_equal([1, 2, 3], (1, 2, 3))
+
+
+class TestArrayEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_array_equal
+
+    def test_generic_rank1(self):
+        """Test rank 1 array for all dtypes."""
+        def foo(t):
+            a = np.empty(2, t)
+            a.fill(1)
+            b = a.copy()
+            c = a.copy()
+            c.fill(0)
+            self._test_equal(a, b)
+            self._test_not_equal(c, b)
+
+        # Test numeric types and object
+        for t in '?bhilqpBHILQPfdgFDG':
+            foo(t)
+
+        # Test strings
+        for t in ['S1', 'U1']:
+            foo(t)
+
+    def test_generic_rank3(self):
+        """Test rank 3 array for all dtypes."""
+        def foo(t):
+            a = np.empty((4, 2, 3), t)
+            a.fill(1)
+            b = a.copy()
+            c = a.copy()
+            c.fill(0)
+            self._test_equal(a, b)
+            self._test_not_equal(c, b)
+
+        # Test numeric types and object
+        for t in '?bhilqpBHILQPfdgFDG':
+            foo(t)
+
+        # Test strings
+        for t in ['S1', 'U1']:
+            foo(t)
+
+    def test_nan_array(self):
+        """Test arrays with nan values in them."""
+        a = np.array([1, 2, np.nan])
+        b = np.array([1, 2, np.nan])
+
+        self._test_equal(a, b)
+
+        c = np.array([1, 2, 3])
+        self._test_not_equal(c, b)
+
+    def test_string_arrays(self):
+        """Test two arrays with different shapes are found not equal."""
+        a = np.array(['floupi', 'floupa'])
+        b = np.array(['floupi', 'floupa'])
+
+        self._test_equal(a, b)
+
+        c = np.array(['floupipi', 'floupa'])
+
+        self._test_not_equal(c, b)
+
+    def test_recarrays(self):
+        """Test record arrays."""
+        a = np.empty(2, [('floupi', np.float), ('floupa', np.float)])
+        a['floupi'] = [1, 2]
+        a['floupa'] = [1, 2]
+        b = a.copy()
+
+        self._test_equal(a, b)
+
+        c = np.empty(2, [('floupipi', np.float), ('floupa', np.float)])
+        c['floupipi'] = a['floupi'].copy()
+        c['floupa'] = a['floupa'].copy()
+
+        self._test_not_equal(c, b)
+
+
+class TestBuildErrorMessage(unittest.TestCase):
+
+    def test_build_err_msg_defaults(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg)
+        b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([ '
+             '1.00001,  2.00002,  3.00003])\n DESIRED: array([ 1.00002,  '
+             '2.00003,  3.00004])')
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_no_verbose(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, verbose=False)
+        b = '\nItems are not equal: There is a mismatch'
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_custom_names(self):
+        x = np.array([1.00001, 2.00002, 3.00003])
+        y = np.array([1.00002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, names=('FOO', 'BAR'))
+        b = ('\nItems are not equal: There is a mismatch\n FOO: array([ '
+             '1.00001,  2.00002,  3.00003])\n BAR: array([ 1.00002,  2.00003,  '
+             '3.00004])')
+        self.assertEqual(a, b)
+
+    def test_build_err_msg_custom_precision(self):
+        x = np.array([1.000000001, 2.00002, 3.00003])
+        y = np.array([1.000000002, 2.00003, 3.00004])
+        err_msg = 'There is a mismatch'
+
+        a = build_err_msg([x, y], err_msg, precision=10)
+        b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([ '
+             '1.000000001,  2.00002    ,  3.00003    ])\n DESIRED: array([ '
+             '1.000000002,  2.00003    ,  3.00004    ])')
+        self.assertEqual(a, b)
+
+
+class TestEqual(TestArrayEqual):
+
+    def setUp(self):
+        self._assert_func = assert_equal
+
+    def test_nan_items(self):
+        self._assert_func(np.nan, np.nan)
+        self._assert_func([np.nan], [np.nan])
+        self._test_not_equal(np.nan, [np.nan])
+        self._test_not_equal(np.nan, 1)
+
+    def test_inf_items(self):
+        self._assert_func(np.inf, np.inf)
+        self._assert_func([np.inf], [np.inf])
+        self._test_not_equal(np.inf, [np.inf])
+
+    def test_non_numeric(self):
+        self._assert_func('ab', 'ab')
+        self._test_not_equal('ab', 'abb')
+
+    def test_complex_item(self):
+        self._assert_func(complex(1, 2), complex(1, 2))
+        self._assert_func(complex(1, np.nan), complex(1, np.nan))
+        self._test_not_equal(complex(1, np.nan), complex(1, 2))
+        self._test_not_equal(complex(np.nan, 1), complex(1, np.nan))
+        self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2))
+
+    def test_negative_zero(self):
+        self._test_not_equal(np.PZERO, np.NZERO)
+
+    def test_complex(self):
+        x = np.array([complex(1, 2), complex(1, np.nan)])
+        y = np.array([complex(1, 2), complex(1, 2)])
+        self._assert_func(x, x)
+        self._test_not_equal(x, y)
+
+
+class TestArrayAlmostEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_array_almost_equal
+
+    def test_simple(self):
+        x = np.array([1234.2222])
+        y = np.array([1234.2223])
+
+        self._assert_func(x, y, decimal=3)
+        self._assert_func(x, y, decimal=4)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, decimal=5))
+
+    def test_nan(self):
+        anan = np.array([np.nan])
+        aone = np.array([1])
+        ainf = np.array([np.inf])
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+    def test_inf(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        b = a.copy()
+        a[0, 0] = np.inf
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(a, b))
+
+    def test_subclass(self):
+        a = np.array([[1., 2.], [3., 4.]])
+        b = np.ma.masked_array([[1., 2.], [0., 4.]],
+                               [[False, False], [True, False]])
+        assert_array_almost_equal(a, b)
+        assert_array_almost_equal(b, a)
+        assert_array_almost_equal(b, b)
+
+
+class TestAlmostEqual(_GenericTest, unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_almost_equal
+
+    def test_nan_item(self):
+        self._assert_func(np.nan, np.nan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.nan, 1))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.nan, np.inf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.inf, np.nan))
+
+    def test_inf_item(self):
+        self._assert_func(np.inf, np.inf)
+        self._assert_func(-np.inf, -np.inf)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(np.inf, 1))
+
+    def test_simple_item(self):
+        self._test_not_equal(1, 2)
+
+    def test_complex_item(self):
+        self._assert_func(complex(1, 2), complex(1, 2))
+        self._assert_func(complex(1, np.nan), complex(1, np.nan))
+        self._assert_func(complex(np.inf, np.nan), complex(np.inf, np.nan))
+        self._test_not_equal(complex(1, np.nan), complex(1, 2))
+        self._test_not_equal(complex(np.nan, 1), complex(1, np.nan))
+        self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2))
+
+    def test_complex(self):
+        x = np.array([complex(1, 2), complex(1, np.nan)])
+        z = np.array([complex(1, 2), complex(np.nan, 1)])
+        y = np.array([complex(1, 2), complex(1, 2)])
+        self._assert_func(x, x)
+        self._test_not_equal(x, y)
+        self._test_not_equal(x, z)
+
+    def test_error_message(self):
+        """Check the message is formatted correctly for the decimal value"""
+        x = np.array([1.00000000001, 2.00000000002, 3.00003])
+        y = np.array([1.00000000002, 2.00000000003, 3.00004])
+
+        # test with a different amount of decimal digits
+        # note that we only check for the formatting of the arrays themselves
+        b = ('x: array([ 1.00000000001,  2.00000000002,  3.00003     '
+             ' ])\n y: array([ 1.00000000002,  2.00000000003,  3.00004      ])')
+        try:
+            self._assert_func(x, y, decimal=12)
+        except AssertionError as e:
+            # remove anything that's not the array string
+            self.assertEqual(str(e).split('%)\n ')[1], b)
+
+        # with the default value of decimal digits, only the 3rd element differs
+        # note that we only check for the formatting of the arrays themselves
+        b = ('x: array([ 1.     ,  2.     ,  3.00003])\n y: array([ 1.     ,  '
+             '2.     ,  3.00004])')
+        try:
+            self._assert_func(x, y)
+        except AssertionError as e:
+            # remove anything that's not the array string
+            self.assertEqual(str(e).split('%)\n ')[1], b)
+
+
+class TestApproxEqual(unittest.TestCase):
+
+    def setUp(self):
+        self._assert_func = assert_approx_equal
+
+    def test_simple_arrays(self):
+        x = np.array([1234.22])
+        y = np.array([1234.23])
+
+        self._assert_func(x, y, significant=5)
+        self._assert_func(x, y, significant=6)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, significant=7))
+
+    def test_simple_items(self):
+        x = 1234.22
+        y = 1234.23
+
+        self._assert_func(x, y, significant=4)
+        self._assert_func(x, y, significant=5)
+        self._assert_func(x, y, significant=6)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(x, y, significant=7))
+
+    def test_nan_array(self):
+        anan = np.array(np.nan)
+        aone = np.array(1)
+        ainf = np.array(np.inf)
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+    def test_nan_items(self):
+        anan = np.array(np.nan)
+        aone = np.array(1)
+        ainf = np.array(np.inf)
+        self._assert_func(anan, anan)
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, aone))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(anan, ainf))
+        self.assertRaises(AssertionError,
+                lambda: self._assert_func(ainf, anan))
+
+
+class TestRaises(unittest.TestCase):
+
+    def setUp(self):
+        class MyException(Exception):
+            pass
+
+        self.e = MyException
+
+    def raises_exception(self, e):
+        raise e
+
+    def does_not_raise_exception(self):
+        pass
+
+    def test_correct_catch(self):
+        raises(self.e)(self.raises_exception)(self.e)  # raises?
+
+    def test_wrong_exception(self):
+        try:
+            raises(self.e)(self.raises_exception)(RuntimeError)  # raises?
+        except RuntimeError:
+            return
+        else:
+            raise AssertionError("should have caught RuntimeError")
+
+    def test_catch_no_raise(self):
+        try:
+            raises(self.e)(self.does_not_raise_exception)()  # raises?
+        except AssertionError:
+            return
+        else:
+            raise AssertionError("should have raised an AssertionError")
+
+
+class TestWarns(unittest.TestCase):
+
+    def test_warn(self):
+        def f():
+            warnings.warn("yo")
+            return 3
+
+        before_filters = sys.modules['warnings'].filters[:]
+        assert_equal(assert_warns(UserWarning, f), 3)
+        after_filters = sys.modules['warnings'].filters
+
+        assert_raises(AssertionError, assert_no_warnings, f)
+        assert_equal(assert_no_warnings(lambda x: x, 1), 1)
+
+        # Check that the warnings state is unchanged
+        assert_equal(before_filters, after_filters,
+                     "assert_warns does not preserver warnings state")
+
+    def test_context_manager(self):
+
+        before_filters = sys.modules['warnings'].filters[:]
+        with assert_warns(UserWarning):
+            warnings.warn("yo")
+        after_filters = sys.modules['warnings'].filters
+
+        def no_warnings():
+            with assert_no_warnings():
+                warnings.warn("yo")
+
+        assert_raises(AssertionError, no_warnings)
+        assert_equal(before_filters, after_filters,
+                     "assert_warns does not preserver warnings state")
+
+    def test_warn_wrong_warning(self):
+        def f():
+            warnings.warn("yo", DeprecationWarning)
+
+        failed = False
+        filters = sys.modules['warnings'].filters[:]
+        try:
+            try:
+                # Should raise an AssertionError
+                assert_warns(UserWarning, f)
+                failed = True
+            except AssertionError:
+                pass
+        finally:
+            sys.modules['warnings'].filters = filters
+
+        if failed:
+            raise AssertionError("wrong warning caught by assert_warn")
+
+
+class TestAssertAllclose(unittest.TestCase):
+    
+    def test_simple(self):
+        x = 1e-3
+        y = 1e-9
+
+        assert_allclose(x, y, atol=1)
+        self.assertRaises(AssertionError, assert_allclose, x, y)
+
+        a = np.array([x, y, x, y])
+        b = np.array([x, y, x, x])
+
+        assert_allclose(a, b, atol=1)
+        self.assertRaises(AssertionError, assert_allclose, a, b)
+
+        b[-1] = y * (1 + 1e-8)
+        assert_allclose(a, b)
+        self.assertRaises(AssertionError, assert_allclose, a, b,
+                          rtol=1e-9)
+
+        assert_allclose(6, 10, rtol=0.5)
+        self.assertRaises(AssertionError, assert_allclose, 10, 6, rtol=0.5)
+
+    def test_min_int(self):
+        a = np.array([np.iinfo(np.int_).min], dtype=np.int_)
+        # Should not raise:
+        assert_allclose(a, a)
+
+    def test_report_fail_percentage(self):
+        a = np.array([1, 1, 1, 1])
+        b = np.array([1, 1, 1, 2])
+        try:
+            assert_allclose(a, b)
+            msg = ''
+        except AssertionError as exc:
+            msg = exc.args[0]
+        self.assertTrue("mismatch 25.0%" in msg)
+
+
+class TestArrayAlmostEqualNulp(unittest.TestCase):
+
+    def test_float64_pass(self):
+        # The number of units of least precision
+        # In this case, use a few places above the lowest level (ie nulp=1)
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        # Addition
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+        # Subtraction
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+    def test_float64_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+    def test_float32_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(x, y, nulp)
+
+    def test_float32_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          x, y, nulp)
+
+    def test_complex128_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        # The test condition needs to be at least a factor of sqrt(2) smaller
+        # because the real and imaginary parts both change
+        y = x + x*eps*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+    def test_complex128_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float64)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        # The test condition needs to be at least a factor of sqrt(2) smaller
+        # because the real and imaginary parts both change
+        y = x + x*eps*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+    def test_complex64_pass(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x + x*eps*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp/2.
+        assert_array_almost_equal_nulp(xi, x + y*1j, nulp)
+        assert_array_almost_equal_nulp(xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp/4.
+        assert_array_almost_equal_nulp(xi, y + y*1j, nulp)
+
+    def test_complex64_fail(self):
+        nulp = 5
+        x = np.linspace(-20, 20, 50, dtype=np.float32)
+        x = 10**x
+        x = np.r_[-x, x]
+        xi = x + x*1j
+
+        eps = np.finfo(x.dtype).eps
+        y = x + x*eps*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x + x*eps*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+        epsneg = np.finfo(x.dtype).epsneg
+        y = x - x*epsneg*nulp*2.
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, x + y*1j, nulp)
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + x*1j, nulp)
+        y = x - x*epsneg*nulp
+        self.assertRaises(AssertionError, assert_array_almost_equal_nulp,
+                          xi, y + y*1j, nulp)
+
+
+class TestULP(unittest.TestCase):
+
+    def test_equal(self):
+        x = np.random.randn(10)
+        assert_array_max_ulp(x, x, maxulp=0)
+
+    def test_single(self):
+        # Generate 1 + small deviation, check that adding eps gives a few UNL
+        x = np.ones(10).astype(np.float32)
+        x += 0.01 * np.random.randn(10).astype(np.float32)
+        eps = np.finfo(np.float32).eps
+        assert_array_max_ulp(x, x+eps, maxulp=20)
+
+    def test_double(self):
+        # Generate 1 + small deviation, check that adding eps gives a few UNL
+        x = np.ones(10).astype(np.float64)
+        x += 0.01 * np.random.randn(10).astype(np.float64)
+        eps = np.finfo(np.float64).eps
+        assert_array_max_ulp(x, x+eps, maxulp=200)
+
+    def test_inf(self):
+        for dt in [np.float32, np.float64]:
+            inf = np.array([np.inf]).astype(dt)
+            big = np.array([np.finfo(dt).max])
+            assert_array_max_ulp(inf, big, maxulp=200)
+
+    def test_nan(self):
+        # Test that nan is 'far' from small, tiny, inf, max and min
+        for dt in [np.float32, np.float64]:
+            if dt == np.float32:
+                maxulp = 1e6
+            else:
+                maxulp = 1e12
+            inf = np.array([np.inf]).astype(dt)
+            nan = np.array([np.nan]).astype(dt)
+            big = np.array([np.finfo(dt).max])
+            tiny = np.array([np.finfo(dt).tiny])
+            zero = np.array([np.PZERO]).astype(dt)
+            nzero = np.array([np.NZERO]).astype(dt)
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, inf,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, big,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, tiny,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, zero,
+                                                               maxulp=maxulp))
+            self.assertRaises(AssertionError,
+                                  lambda: assert_array_max_ulp(nan, nzero,
+                                                               maxulp=maxulp))
+
+class TestStringEqual(unittest.TestCase):
+    def test_simple(self):
+        assert_string_equal("hello", "hello")
+        assert_string_equal("hello\nmultiline", "hello\nmultiline")
+
+        try:
+            assert_string_equal("foo\nbar", "hello\nbar")
+        except AssertionError as exc:
+            assert_equal(str(exc), "Differences in strings:\n- foo\n+ hello")
+        else:
+            raise AssertionError("exception not raised")
+
+        self.assertRaises(AssertionError,
+                          lambda: assert_string_equal("foo", "hello"))
+
+
+def assert_warn_len_equal(mod, n_in_context):
+    mod_warns = mod.__warningregistry__
+    # Python 3.4 appears to clear any pre-existing warnings of the same type,
+    # when raising warnings inside a catch_warnings block. So, there is a
+    # warning generated by the tests within the context manager, but no
+    # previous warnings.
+    if 'version' in mod_warns:
+        assert_equal(len(mod_warns), 2)  # including 'version'
+    else:
+        assert_equal(len(mod_warns), n_in_context)
+
+
+def _get_fresh_mod():
+    # Get this module, with warning registry empty
+    my_mod = sys.modules[__name__]
+    try:
+        my_mod.__warningregistry__.clear()
+    except AttributeError:
+        pass
+    return my_mod
+
+
+def test_clear_and_catch_warnings():
+    # Initial state of module, no warnings
+    my_mod = _get_fresh_mod()
+    assert_equal(getattr(my_mod, '__warningregistry__', {}), {})
+    with clear_and_catch_warnings(modules=[my_mod]):
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_equal(my_mod.__warningregistry__, {})
+    # Without specified modules, don't clear warnings during context
+    with clear_and_catch_warnings():
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_warn_len_equal(my_mod, 1)
+    # Confirm that specifying module keeps old warning, does not add new
+    with clear_and_catch_warnings(modules=[my_mod]):
+        warnings.simplefilter('ignore')
+        warnings.warn('Another warning')
+    assert_warn_len_equal(my_mod, 1)
+    # Another warning, no module spec does add to warnings dict, except on
+    # Python 3.4 (see comments in `assert_warn_len_equal`)
+    with clear_and_catch_warnings():
+        warnings.simplefilter('ignore')
+        warnings.warn('Another warning')
+    assert_warn_len_equal(my_mod, 2)
+
+
+def test_tempdir():
+    with tempdir() as tdir:
+        fpath = os.path.join(tdir, 'tmp')
+        with open(fpath, 'w'):
+            pass
+    assert_(not os.path.isdir(tdir))
+
+    raised = False
+    try:
+        with tempdir() as tdir:
+            raise ValueError()
+    except ValueError:
+        raised = True
+    assert_(raised)
+    assert_(not os.path.isdir(tdir))
+
+
+
+def test_temppath():
+    with temppath() as fpath:
+        with open(fpath, 'w') as f:
+            pass
+    assert_(not os.path.isfile(fpath))
+
+    raised = False
+    try:
+        with temppath() as fpath:
+            raise ValueError()
+    except ValueError:
+        raised = True
+    assert_(raised)
+    assert_(not os.path.isfile(fpath))
+
+
+class my_cacw(clear_and_catch_warnings):
+
+    class_modules = (sys.modules[__name__],)
+
+
+def test_clear_and_catch_warnings_inherit():
+    # Test can subclass and add default modules
+    my_mod = _get_fresh_mod()
+    with my_cacw():
+        warnings.simplefilter('ignore')
+        warnings.warn('Some warning')
+    assert_equal(my_mod.__warningregistry__, {})
+
+
+if __name__ == '__main__':
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/utils.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/utils.py
new file mode 100644
index 0000000000..f2588788df
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/testing/utils.py
@@ -0,0 +1,1939 @@
+"""
+Utility function to facilitate testing.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+import os
+import sys
+import re
+import operator
+import warnings
+from functools import partial
+import shutil
+import contextlib
+from tempfile import mkdtemp, mkstemp
+
+from .nosetester import import_nose
+from numpy.core import float32, empty, arange, array_repr, ndarray
+from numpy.lib.utils import deprecate
+
+if sys.version_info[0] >= 3:
+    from io import StringIO
+else:
+    from StringIO import StringIO
+
+__all__ = ['assert_equal', 'assert_almost_equal', 'assert_approx_equal',
+           'assert_array_equal', 'assert_array_less', 'assert_string_equal',
+           'assert_array_almost_equal', 'assert_raises', 'build_err_msg',
+           'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal',
+           'raises', 'rand', 'rundocs', 'runstring', 'verbose', 'measure',
+           'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex',
+           'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings',
+           'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings',
+           'SkipTest', 'KnownFailureException', 'temppath', 'tempdir']
+
+
+class KnownFailureException(Exception):
+    '''Raise this exception to mark a test as a known failing test.'''
+    pass
+
+KnownFailureTest = KnownFailureException  # backwards compat
+
+
+# nose.SkipTest is unittest.case.SkipTest
+# import it into the namespace, so that it's available as np.testing.SkipTest
+try:
+    from unittest.case import SkipTest
+except ImportError:
+    # on py2.6 unittest.case is not available. Ask nose for a replacement.
+    SkipTest = import_nose().SkipTest
+
+
+verbose = 0
+
+def assert_(val, msg=''):
+    """
+    Assert that works in release mode.
+    Accepts callable msg to allow deferring evaluation until failure.
+
+    The Python built-in ``assert`` does not work when executing code in
+    optimized mode (the ``-O`` flag) - no byte-code is generated for it.
+
+    For documentation on usage, refer to the Python documentation.
+
+    """
+    if not val:
+        try:
+            smsg = msg()
+        except TypeError:
+            smsg = msg
+        raise AssertionError(smsg)
+
+def gisnan(x):
+    """like isnan, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isnan and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isnan
+    st = isnan(x)
+    if isinstance(st, type(NotImplemented)):
+        raise TypeError("isnan not supported for this type")
+    return st
+
+def gisfinite(x):
+    """like isfinite, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isfinite and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isfinite, errstate
+    with errstate(invalid='ignore'):
+        st = isfinite(x)
+        if isinstance(st, type(NotImplemented)):
+            raise TypeError("isfinite not supported for this type")
+    return st
+
+def gisinf(x):
+    """like isinf, but always raise an error if type not supported instead of
+    returning a TypeError object.
+
+    Notes
+    -----
+    isinf and other ufunc sometimes return a NotImplementedType object instead
+    of raising any exception. This function is a wrapper to make sure an
+    exception is always raised.
+
+    This should be removed once this problem is solved at the Ufunc level."""
+    from numpy.core import isinf, errstate
+    with errstate(invalid='ignore'):
+        st = isinf(x)
+        if isinstance(st, type(NotImplemented)):
+            raise TypeError("isinf not supported for this type")
+    return st
+
+@deprecate(message="numpy.testing.rand is deprecated in numpy 1.11. "
+                   "Use numpy.random.rand instead.")
+def rand(*args):
+    """Returns an array of random numbers with the given shape.
+
+    This only uses the standard library, so it is useful for testing purposes.
+    """
+    import random
+    from numpy.core import zeros, float64
+    results = zeros(args, float64)
+    f = results.flat
+    for i in range(len(f)):
+        f[i] = random.random()
+    return results
+
+if os.name == 'nt':
+    # Code "stolen" from enthought/debug/memusage.py
+    def GetPerformanceAttributes(object, counter, instance=None,
+                                 inum=-1, format=None, machine=None):
+        # NOTE: Many counters require 2 samples to give accurate results,
+        # including "% Processor Time" (as by definition, at any instant, a
+        # thread's CPU usage is either 0 or 100).  To read counters like this,
+        # you should copy this function, but keep the counter open, and call
+        # CollectQueryData() each time you need to know.
+        # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
+        # My older explanation for this was that the "AddCounter" process forced
+        # the CPU to 100%, but the above makes more sense :)
+        import win32pdh
+        if format is None:
+            format = win32pdh.PDH_FMT_LONG
+        path = win32pdh.MakeCounterPath( (machine, object, instance, None, inum, counter))
+        hq = win32pdh.OpenQuery()
+        try:
+            hc = win32pdh.AddCounter(hq, path)
+            try:
+                win32pdh.CollectQueryData(hq)
+                type, val = win32pdh.GetFormattedCounterValue(hc, format)
+                return val
+            finally:
+                win32pdh.RemoveCounter(hc)
+        finally:
+            win32pdh.CloseQuery(hq)
+
+    def memusage(processName="python", instance=0):
+        # from win32pdhutil, part of the win32all package
+        import win32pdh
+        return GetPerformanceAttributes("Process", "Virtual Bytes",
+                                        processName, instance,
+                                        win32pdh.PDH_FMT_LONG, None)
+elif sys.platform[:5] == 'linux':
+
+    def memusage(_proc_pid_stat='/proc/%s/stat' % (os.getpid())):
+        """
+        Return virtual memory size in bytes of the running python.
+
+        """
+        try:
+            f = open(_proc_pid_stat, 'r')
+            l = f.readline().split(' ')
+            f.close()
+            return int(l[22])
+        except:
+            return
+else:
+    def memusage():
+        """
+        Return memory usage of running python. [Not implemented]
+
+        """
+        raise NotImplementedError
+
+
+if sys.platform[:5] == 'linux':
+    def jiffies(_proc_pid_stat='/proc/%s/stat' % (os.getpid()),
+                _load_time=[]):
+        """
+        Return number of jiffies elapsed.
+
+        Return number of jiffies (1/100ths of a second) that this
+        process has been scheduled in user mode. See man 5 proc.
+
+        """
+        import time
+        if not _load_time:
+            _load_time.append(time.time())
+        try:
+            f = open(_proc_pid_stat, 'r')
+            l = f.readline().split(' ')
+            f.close()
+            return int(l[13])
+        except:
+            return int(100*(time.time()-_load_time[0]))
+else:
+    # os.getpid is not in all platforms available.
+    # Using time is safe but inaccurate, especially when process
+    # was suspended or sleeping.
+    def jiffies(_load_time=[]):
+        """
+        Return number of jiffies elapsed.
+
+        Return number of jiffies (1/100ths of a second) that this
+        process has been scheduled in user mode. See man 5 proc.
+
+        """
+        import time
+        if not _load_time:
+            _load_time.append(time.time())
+        return int(100*(time.time()-_load_time[0]))
+
+
+def build_err_msg(arrays, err_msg, header='Items are not equal:',
+                  verbose=True, names=('ACTUAL', 'DESIRED'), precision=8):
+    msg = ['\n' + header]
+    if err_msg:
+        if err_msg.find('\n') == -1 and len(err_msg) < 79-len(header):
+            msg = [msg[0] + ' ' + err_msg]
+        else:
+            msg.append(err_msg)
+    if verbose:
+        for i, a in enumerate(arrays):
+
+            if isinstance(a, ndarray):
+                # precision argument is only needed if the objects are ndarrays
+                r_func = partial(array_repr, precision=precision)
+            else:
+                r_func = repr
+
+            try:
+                r = r_func(a)
+            except:
+                r = '[repr failed]'
+            if r.count('\n') > 3:
+                r = '\n'.join(r.splitlines()[:3])
+                r += '...'
+            msg.append(' %s: %s' % (names[i], r))
+    return '\n'.join(msg)
+
+def assert_equal(actual,desired,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal.
+
+    Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
+    check that all elements of these objects are equal. An exception is raised
+    at the first conflicting values.
+
+    Parameters
+    ----------
+    actual : array_like
+        The object to check.
+    desired : array_like
+        The expected object.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal.
+
+    Examples
+    --------
+    >>> np.testing.assert_equal([4,5], [4,6])
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal:
+    item=1
+     ACTUAL: 5
+     DESIRED: 6
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    if isinstance(desired, dict):
+        if not isinstance(actual, dict):
+            raise AssertionError(repr(type(actual)))
+        assert_equal(len(actual), len(desired), err_msg, verbose)
+        for k, i in desired.items():
+            if k not in actual:
+                raise AssertionError(repr(k))
+            assert_equal(actual[k], desired[k], 'key=%r\n%s' % (k, err_msg), verbose)
+        return
+    if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)):
+        assert_equal(len(actual), len(desired), err_msg, verbose)
+        for k in range(len(desired)):
+            assert_equal(actual[k], desired[k], 'item=%r\n%s' % (k, err_msg), verbose)
+        return
+    from numpy.core import ndarray, isscalar, signbit
+    from numpy.lib import iscomplexobj, real, imag
+    if isinstance(actual, ndarray) or isinstance(desired, ndarray):
+        return assert_array_equal(actual, desired, err_msg, verbose)
+    msg = build_err_msg([actual, desired], err_msg, verbose=verbose)
+
+    # Handle complex numbers: separate into real/imag to handle
+    # nan/inf/negative zero correctly
+    # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
+    try:
+        usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
+    except ValueError:
+        usecomplex = False
+
+    if usecomplex:
+        if iscomplexobj(actual):
+            actualr = real(actual)
+            actuali = imag(actual)
+        else:
+            actualr = actual
+            actuali = 0
+        if iscomplexobj(desired):
+            desiredr = real(desired)
+            desiredi = imag(desired)
+        else:
+            desiredr = desired
+            desiredi = 0
+        try:
+            assert_equal(actualr, desiredr)
+            assert_equal(actuali, desiredi)
+        except AssertionError:
+            raise AssertionError(msg)
+
+    # Inf/nan/negative zero handling
+    try:
+        # isscalar test to check cases such as [np.nan] != np.nan
+        if isscalar(desired) != isscalar(actual):
+            raise AssertionError(msg)
+
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            isdesnan = gisnan(desired)
+            isactnan = gisnan(actual)
+            if isdesnan or isactnan:
+                if not (isdesnan and isactnan):
+                    raise AssertionError(msg)
+            else:
+                if not desired == actual:
+                    raise AssertionError(msg)
+            return
+        elif desired == 0 and actual == 0:
+            if not signbit(desired) == signbit(actual):
+                raise AssertionError(msg)
+    # If TypeError or ValueError raised while using isnan and co, just handle
+    # as before
+    except (TypeError, ValueError, NotImplementedError):
+        pass
+
+    # Explicitly use __eq__ for comparison, ticket #2552
+    if not (desired == actual):
+        raise AssertionError(msg)
+
+def print_assert_equal(test_string, actual, desired):
+    """
+    Test if two objects are equal, and print an error message if test fails.
+
+    The test is performed with ``actual == desired``.
+
+    Parameters
+    ----------
+    test_string : str
+        The message supplied to AssertionError.
+    actual : object
+        The object to test for equality against `desired`.
+    desired : object
+        The expected result.
+
+    Examples
+    --------
+    >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1])
+    >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 2])
+    Traceback (most recent call last):
+    ...
+    AssertionError: Test XYZ of func xyz failed
+    ACTUAL:
+    [0, 1]
+    DESIRED:
+    [0, 2]
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import pprint
+
+    if not (actual == desired):
+        msg = StringIO()
+        msg.write(test_string)
+        msg.write(' failed\nACTUAL: \n')
+        pprint.pprint(actual, msg)
+        msg.write('DESIRED: \n')
+        pprint.pprint(desired, msg)
+        raise AssertionError(msg.getvalue())
+
+def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two items are not equal up to desired
+    precision.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    The test is equivalent to ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
+
+    Given two objects (numbers or ndarrays), check that all elements of these
+    objects are almost equal. An exception is raised at conflicting values.
+    For ndarrays this delegates to assert_array_almost_equal
+
+    Parameters
+    ----------
+    actual : array_like
+        The object to check.
+    desired : array_like
+        The expected object.
+    decimal : int, optional
+        Desired precision, default is 7.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    >>> import numpy.testing as npt
+    >>> npt.assert_almost_equal(2.3333333333333, 2.33333334)
+    >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal:
+     ACTUAL: 2.3333333333333002
+     DESIRED: 2.3333333399999998
+
+    >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]),
+    ...                         np.array([1.0,2.33333334]), decimal=9)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Arrays are not almost equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.        ,  2.33333333])
+     y: array([ 1.        ,  2.33333334])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import ndarray
+    from numpy.lib import iscomplexobj, real, imag
+
+    # Handle complex numbers: separate into real/imag to handle
+    # nan/inf/negative zero correctly
+    # XXX: catch ValueError for subclasses of ndarray where iscomplex fail
+    try:
+        usecomplex = iscomplexobj(actual) or iscomplexobj(desired)
+    except ValueError:
+        usecomplex = False
+
+    def _build_err_msg():
+        header = ('Arrays are not almost equal to %d decimals' % decimal)
+        return build_err_msg([actual, desired], err_msg, verbose=verbose,
+                             header=header)
+
+    if usecomplex:
+        if iscomplexobj(actual):
+            actualr = real(actual)
+            actuali = imag(actual)
+        else:
+            actualr = actual
+            actuali = 0
+        if iscomplexobj(desired):
+            desiredr = real(desired)
+            desiredi = imag(desired)
+        else:
+            desiredr = desired
+            desiredi = 0
+        try:
+            assert_almost_equal(actualr, desiredr, decimal=decimal)
+            assert_almost_equal(actuali, desiredi, decimal=decimal)
+        except AssertionError:
+            raise AssertionError(_build_err_msg())
+
+    if isinstance(actual, (ndarray, tuple, list)) \
+            or isinstance(desired, (ndarray, tuple, list)):
+        return assert_array_almost_equal(actual, desired, decimal, err_msg)
+    try:
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            if gisnan(desired) or gisnan(actual):
+                if not (gisnan(desired) and gisnan(actual)):
+                    raise AssertionError(_build_err_msg())
+            else:
+                if not desired == actual:
+                    raise AssertionError(_build_err_msg())
+            return
+    except (NotImplementedError, TypeError):
+        pass
+    if round(abs(desired - actual), decimal) != 0:
+        raise AssertionError(_build_err_msg())
+
+
+def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True):
+    """
+    Raises an AssertionError if two items are not equal up to significant
+    digits.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    Given two numbers, check that they are approximately equal.
+    Approximately equal is defined as the number of significant digits
+    that agree.
+
+    Parameters
+    ----------
+    actual : scalar
+        The object to check.
+    desired : scalar
+        The expected object.
+    significant : int, optional
+        Desired precision, default is 7.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    >>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20)
+    >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20,
+                                       significant=8)
+    >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20,
+                                       significant=8)
+    ...
+    <type 'exceptions.AssertionError'>:
+    Items are not equal to 8 significant digits:
+     ACTUAL: 1.234567e-021
+     DESIRED: 1.2345672000000001e-021
+
+    the evaluated condition that raises the exception is
+
+    >>> abs(0.12345670e-20/1e-21 - 0.12345672e-20/1e-21) >= 10**-(8-1)
+    True
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+
+    (actual, desired) = map(float, (actual, desired))
+    if desired == actual:
+        return
+    # Normalized the numbers to be in range (-10.0,10.0)
+    # scale = float(pow(10,math.floor(math.log10(0.5*(abs(desired)+abs(actual))))))
+    with np.errstate(invalid='ignore'):
+        scale = 0.5*(np.abs(desired) + np.abs(actual))
+        scale = np.power(10, np.floor(np.log10(scale)))
+    try:
+        sc_desired = desired/scale
+    except ZeroDivisionError:
+        sc_desired = 0.0
+    try:
+        sc_actual = actual/scale
+    except ZeroDivisionError:
+        sc_actual = 0.0
+    msg = build_err_msg([actual, desired], err_msg,
+                header='Items are not equal to %d significant digits:' %
+                                 significant,
+                verbose=verbose)
+    try:
+        # If one of desired/actual is not finite, handle it specially here:
+        # check that both are nan if any is a nan, and test for equality
+        # otherwise
+        if not (gisfinite(desired) and gisfinite(actual)):
+            if gisnan(desired) or gisnan(actual):
+                if not (gisnan(desired) and gisnan(actual)):
+                    raise AssertionError(msg)
+            else:
+                if not desired == actual:
+                    raise AssertionError(msg)
+            return
+    except (TypeError, NotImplementedError):
+        pass
+    if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant-1)):
+        raise AssertionError(msg)
+
+def assert_array_compare(comparison, x, y, err_msg='', verbose=True,
+                         header='', precision=6):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import array, isnan, isinf, any, all, inf
+    x = array(x, copy=False, subok=True)
+    y = array(y, copy=False, subok=True)
+
+    def safe_comparison(*args, **kwargs):
+        # There are a number of cases where comparing two arrays hits special
+        # cases in array_richcompare, specifically around strings and void
+        # dtypes. Basically, we just can't do comparisons involving these
+        # types, unless both arrays have exactly the *same* type. So
+        # e.g. you can apply == to two string arrays, or two arrays with
+        # identical structured dtypes. But if you compare a non-string array
+        # to a string array, or two arrays with non-identical structured
+        # dtypes, or anything like that, then internally stuff blows up.
+        # Currently, when things blow up, we just return a scalar False or
+        # True. But we also emit a DeprecationWarning, b/c eventually we
+        # should raise an error here. (Ideally we might even make this work
+        # properly, but since that will require rewriting a bunch of how
+        # ufuncs work then we are not counting on that.)
+        #
+        # The point of this little function is to let the DeprecationWarning
+        # pass (or maybe eventually catch the errors and return False, I
+        # dunno, that's a little trickier and we can figure that out when the
+        # time comes).
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            return comparison(*args, **kwargs)
+
+    def isnumber(x):
+        return x.dtype.char in '?bhilqpBHILQPefdgFDG'
+
+    def chk_same_position(x_id, y_id, hasval='nan'):
+        """Handling nan/inf: check that x and y have the nan/inf at the same
+        locations."""
+        try:
+            assert_array_equal(x_id, y_id)
+        except AssertionError:
+            msg = build_err_msg([x, y],
+                                err_msg + '\nx and y %s location mismatch:'
+                                % (hasval), verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            raise AssertionError(msg)
+
+    try:
+        cond = (x.shape == () or y.shape == ()) or x.shape == y.shape
+        if not cond:
+            msg = build_err_msg([x, y],
+                                err_msg
+                                + '\n(shapes %s, %s mismatch)' % (x.shape,
+                                                                  y.shape),
+                                verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            if not cond:
+                raise AssertionError(msg)
+
+        if isnumber(x) and isnumber(y):
+            x_isnan, y_isnan = isnan(x), isnan(y)
+            x_isinf, y_isinf = isinf(x), isinf(y)
+
+            # Validate that the special values are in the same place
+            if any(x_isnan) or any(y_isnan):
+                chk_same_position(x_isnan, y_isnan, hasval='nan')
+            if any(x_isinf) or any(y_isinf):
+                # Check +inf and -inf separately, since they are different
+                chk_same_position(x == +inf, y == +inf, hasval='+inf')
+                chk_same_position(x == -inf, y == -inf, hasval='-inf')
+
+            # Combine all the special values
+            x_id, y_id = x_isnan, y_isnan
+            x_id |= x_isinf
+            y_id |= y_isinf
+
+            # Only do the comparison if actual values are left
+            if all(x_id):
+                return
+
+            if any(x_id):
+                val = safe_comparison(x[~x_id], y[~y_id])
+            else:
+                val = safe_comparison(x, y)
+        else:
+            val = safe_comparison(x, y)
+
+        if isinstance(val, bool):
+            cond = val
+            reduced = [0]
+        else:
+            reduced = val.ravel()
+            cond = reduced.all()
+            reduced = reduced.tolist()
+        if not cond:
+            match = 100-100.0*reduced.count(1)/len(reduced)
+            msg = build_err_msg([x, y],
+                                err_msg
+                                + '\n(mismatch %s%%)' % (match,),
+                                verbose=verbose, header=header,
+                                names=('x', 'y'), precision=precision)
+            if not cond:
+                raise AssertionError(msg)
+    except ValueError:
+        import traceback
+        efmt = traceback.format_exc()
+        header = 'error during assertion:\n\n%s\n\n%s' % (efmt, header)
+
+        msg = build_err_msg([x, y], err_msg, verbose=verbose, header=header,
+                            names=('x', 'y'), precision=precision)
+        raise ValueError(msg)
+
+def assert_array_equal(x, y, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two array_like objects are not equal.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of these objects are equal. An exception is raised at
+    shape mismatch or conflicting values. In contrast to the standard usage
+    in numpy, NaNs are compared like numbers, no assertion is raised if
+    both objects have NaNs in the same positions.
+
+    The usual caution for verifying equality with floating point numbers is
+    advised.
+
+    Parameters
+    ----------
+    x : array_like
+        The actual object to check.
+    y : array_like
+        The desired, expected object.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired objects are not equal.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    The first assert does not raise an exception:
+
+    >>> np.testing.assert_array_equal([1.0,2.33333,np.nan],
+    ...                               [np.exp(0),2.33333, np.nan])
+
+    Assert fails with numerical inprecision with floats:
+
+    >>> np.testing.assert_array_equal([1.0,np.pi,np.nan],
+    ...                               [1, np.sqrt(np.pi)**2, np.nan])
+    ...
+    <type 'exceptions.ValueError'>:
+    AssertionError:
+    Arrays are not equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.        ,  3.14159265,         NaN])
+     y: array([ 1.        ,  3.14159265,         NaN])
+
+    Use `assert_allclose` or one of the nulp (number of floating point values)
+    functions for these cases instead:
+
+    >>> np.testing.assert_allclose([1.0,np.pi,np.nan],
+    ...                            [1, np.sqrt(np.pi)**2, np.nan],
+    ...                            rtol=1e-10, atol=0)
+
+    """
+    assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
+                         verbose=verbose, header='Arrays are not equal')
+
+def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal up to desired
+    precision.
+
+    .. note:: It is recommended to use one of `assert_allclose`,
+              `assert_array_almost_equal_nulp` or `assert_array_max_ulp`
+              instead of this function for more consistent floating point
+              comparisons.
+
+    The test verifies identical shapes and verifies values with
+    ``abs(desired-actual) < 0.5 * 10**(-decimal)``.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of these objects are almost equal. An exception is raised at
+    shape mismatch or conflicting values. In contrast to the standard usage
+    in numpy, NaNs are compared like numbers, no assertion is raised if
+    both objects have NaNs in the same positions.
+
+    Parameters
+    ----------
+    x : array_like
+        The actual object to check.
+    y : array_like
+        The desired, expected object.
+    decimal : int, optional
+        Desired precision, default is 6.
+    err_msg : str, optional
+      The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_allclose: Compare two array_like objects for equality with desired
+                     relative and/or absolute precision.
+    assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal
+
+    Examples
+    --------
+    the first assert does not raise an exception
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan],
+                                             [1.0,2.333,np.nan])
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
+    ...                                      [1.0,2.33339,np.nan], decimal=5)
+    ...
+    <type 'exceptions.AssertionError'>:
+    AssertionError:
+    Arrays are not almost equal
+    <BLANKLINE>
+    (mismatch 50.0%)
+     x: array([ 1.     ,  2.33333,      NaN])
+     y: array([ 1.     ,  2.33339,      NaN])
+
+    >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan],
+    ...                                      [1.0,2.33333, 5], decimal=5)
+    <type 'exceptions.ValueError'>:
+    ValueError:
+    Arrays are not almost equal
+     x: array([ 1.     ,  2.33333,      NaN])
+     y: array([ 1.     ,  2.33333,  5.     ])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    from numpy.core import around, number, float_, result_type, array
+    from numpy.core.numerictypes import issubdtype
+    from numpy.core.fromnumeric import any as npany
+
+    def compare(x, y):
+        try:
+            if npany(gisinf(x)) or npany( gisinf(y)):
+                xinfid = gisinf(x)
+                yinfid = gisinf(y)
+                if not xinfid == yinfid:
+                    return False
+                # if one item, x and y is +- inf
+                if x.size == y.size == 1:
+                    return x == y
+                x = x[~xinfid]
+                y = y[~yinfid]
+        except (TypeError, NotImplementedError):
+            pass
+
+        # make sure y is an inexact type to avoid abs(MIN_INT); will cause
+        # casting of x later.
+        dtype = result_type(y, 1.)
+        y = array(y, dtype=dtype, copy=False, subok=True)
+        z = abs(x-y)
+
+        if not issubdtype(z.dtype, number):
+            z = z.astype(float_)  # handle object arrays
+
+        return around(z, decimal) <= 10.0**(-decimal)
+
+    assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose,
+             header=('Arrays are not almost equal to %d decimals' % decimal),
+             precision=decimal)
+
+
+def assert_array_less(x, y, err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two array_like objects are not ordered by less
+    than.
+
+    Given two array_like objects, check that the shape is equal and all
+    elements of the first object are strictly smaller than those of the
+    second object. An exception is raised at shape mismatch or incorrectly
+    ordered values. Shape mismatch does not raise if an object has zero
+    dimension. In contrast to the standard usage in numpy, NaNs are
+    compared, no assertion is raised if both objects have NaNs in the same
+    positions.
+
+
+
+    Parameters
+    ----------
+    x : array_like
+      The smaller object to check.
+    y : array_like
+      The larger object to compare.
+    err_msg : string
+      The error message to be printed in case of failure.
+    verbose : bool
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+      If actual and desired objects are not equal.
+
+    See Also
+    --------
+    assert_array_equal: tests objects for equality
+    assert_array_almost_equal: test objects for equality up to precision
+
+
+
+    Examples
+    --------
+    >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan])
+    >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan])
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (mismatch 50.0%)
+     x: array([  1.,   1.,  NaN])
+     y: array([  1.,   2.,  NaN])
+
+    >>> np.testing.assert_array_less([1.0, 4.0], 3)
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (mismatch 50.0%)
+     x: array([ 1.,  4.])
+     y: array(3)
+
+    >>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4])
+    ...
+    <type 'exceptions.ValueError'>:
+    Arrays are not less-ordered
+    (shapes (3,), (1,) mismatch)
+     x: array([ 1.,  2.,  3.])
+     y: array([4])
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    assert_array_compare(operator.__lt__, x, y, err_msg=err_msg,
+                         verbose=verbose,
+                         header='Arrays are not less-ordered')
+
+def runstring(astr, dict):
+    exec(astr, dict)
+
+def assert_string_equal(actual, desired):
+    """
+    Test if two strings are equal.
+
+    If the given strings are equal, `assert_string_equal` does nothing.
+    If they are not equal, an AssertionError is raised, and the diff
+    between the strings is shown.
+
+    Parameters
+    ----------
+    actual : str
+        The string to test for equality against the expected string.
+    desired : str
+        The expected string.
+
+    Examples
+    --------
+    >>> np.testing.assert_string_equal('abc', 'abc')
+    >>> np.testing.assert_string_equal('abc', 'abcd')
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    ...
+    AssertionError: Differences in strings:
+    - abc+ abcd?    +
+
+    """
+    # delay import of difflib to reduce startup time
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import difflib
+
+    if not isinstance(actual, str):
+        raise AssertionError(repr(type(actual)))
+    if not isinstance(desired, str):
+        raise AssertionError(repr(type(desired)))
+    if re.match(r'\A'+desired+r'\Z', actual, re.M):
+        return
+
+    diff = list(difflib.Differ().compare(actual.splitlines(1), desired.splitlines(1)))
+    diff_list = []
+    while diff:
+        d1 = diff.pop(0)
+        if d1.startswith('  '):
+            continue
+        if d1.startswith('- '):
+            l = [d1]
+            d2 = diff.pop(0)
+            if d2.startswith('? '):
+                l.append(d2)
+                d2 = diff.pop(0)
+            if not d2.startswith('+ '):
+                raise AssertionError(repr(d2))
+            l.append(d2)
+            if diff:
+                d3 = diff.pop(0)
+                if d3.startswith('? '):
+                    l.append(d3)
+                else:
+                    diff.insert(0, d3)
+            if re.match(r'\A'+d2[2:]+r'\Z', d1[2:]):
+                continue
+            diff_list.extend(l)
+            continue
+        raise AssertionError(repr(d1))
+    if not diff_list:
+        return
+    msg = 'Differences in strings:\n%s' % (''.join(diff_list)).rstrip()
+    if actual != desired:
+        raise AssertionError(msg)
+
+
+def rundocs(filename=None, raise_on_error=True):
+    """
+    Run doctests found in the given file.
+
+    By default `rundocs` raises an AssertionError on failure.
+
+    Parameters
+    ----------
+    filename : str
+        The path to the file for which the doctests are run.
+    raise_on_error : bool
+        Whether to raise an AssertionError when a doctest fails. Default is
+        True.
+
+    Notes
+    -----
+    The doctests can be run by the user/developer by adding the ``doctests``
+    argument to the ``test()`` call. For example, to run all tests (including
+    doctests) for `numpy.lib`:
+
+    >>> np.lib.test(doctests=True) #doctest: +SKIP
+    """
+    import doctest
+    import imp
+    if filename is None:
+        f = sys._getframe(1)
+        filename = f.f_globals['__file__']
+    name = os.path.splitext(os.path.basename(filename))[0]
+    path = [os.path.dirname(filename)]
+    file, pathname, description = imp.find_module(name, path)
+    try:
+        m = imp.load_module(name, file, pathname, description)
+    finally:
+        file.close()
+
+    tests = doctest.DocTestFinder().find(m)
+    runner = doctest.DocTestRunner(verbose=False)
+
+    msg = []
+    if raise_on_error:
+        out = lambda s: msg.append(s)
+    else:
+        out = None
+
+    for test in tests:
+        runner.run(test, out=out)
+
+    if runner.failures > 0 and raise_on_error:
+        raise AssertionError("Some doctests failed:\n%s" % "\n".join(msg))
+
+
+def raises(*args,**kwargs):
+    nose = import_nose()
+    return nose.tools.raises(*args,**kwargs)
+
+
+def assert_raises(*args,**kwargs):
+    """
+    assert_raises(exception_class, callable, *args, **kwargs)
+
+    Fail unless an exception of class exception_class is thrown
+    by callable when invoked with arguments args and keyword
+    arguments kwargs. If a different type of exception is
+    thrown, it will not be caught, and the test case will be
+    deemed to have suffered an error, exactly as for an
+    unexpected exception.
+
+    Alternatively, `assert_raises` can be used as a context manager:
+
+    >>> from numpy.testing import assert_raises
+    >>> with assert_raises(ZeroDivisionError):
+    ...   1 / 0
+
+    is equivalent to
+
+    >>> def div(x, y):
+    ...    return x / y
+    >>> assert_raises(ZeroDivisionError, div, 1, 0)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    nose = import_nose()
+    return nose.tools.assert_raises(*args,**kwargs)
+
+
+assert_raises_regex_impl = None
+
+
+def assert_raises_regex(exception_class, expected_regexp,
+                        callable_obj=None, *args, **kwargs):
+    """
+    Fail unless an exception of class exception_class and with message that
+    matches expected_regexp is thrown by callable when invoked with arguments
+    args and keyword arguments kwargs.
+
+    Name of this function adheres to Python 3.2+ reference, but should work in
+    all versions down to 2.6.
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    nose = import_nose()
+
+    global assert_raises_regex_impl
+    if assert_raises_regex_impl is None:
+        try:
+            # Python 3.2+
+            assert_raises_regex_impl = nose.tools.assert_raises_regex
+        except AttributeError:
+            try:
+                # 2.7+
+                assert_raises_regex_impl = nose.tools.assert_raises_regexp
+            except AttributeError:
+                # 2.6
+
+                # This class is copied from Python2.7 stdlib almost verbatim
+                class _AssertRaisesContext(object):
+                    """A context manager used to implement TestCase.assertRaises* methods."""
+
+                    def __init__(self, expected, expected_regexp=None):
+                        self.expected = expected
+                        self.expected_regexp = expected_regexp
+
+                    def failureException(self, msg):
+                        return AssertionError(msg)
+
+                    def __enter__(self):
+                        return self
+
+                    def __exit__(self, exc_type, exc_value, tb):
+                        if exc_type is None:
+                            try:
+                                exc_name = self.expected.__name__
+                            except AttributeError:
+                                exc_name = str(self.expected)
+                            raise self.failureException(
+                                "{0} not raised".format(exc_name))
+                        if not issubclass(exc_type, self.expected):
+                            # let unexpected exceptions pass through
+                            return False
+                        self.exception = exc_value  # store for later retrieval
+                        if self.expected_regexp is None:
+                            return True
+
+                        expected_regexp = self.expected_regexp
+                        if isinstance(expected_regexp, basestring):
+                            expected_regexp = re.compile(expected_regexp)
+                        if not expected_regexp.search(str(exc_value)):
+                            raise self.failureException(
+                                '"%s" does not match "%s"' %
+                                (expected_regexp.pattern, str(exc_value)))
+                        return True
+
+                def impl(cls, regex, callable_obj, *a, **kw):
+                    mgr = _AssertRaisesContext(cls, regex)
+                    if callable_obj is None:
+                        return mgr
+                    with mgr:
+                        callable_obj(*a, **kw)
+                assert_raises_regex_impl = impl
+
+    return assert_raises_regex_impl(exception_class, expected_regexp,
+                                    callable_obj, *args, **kwargs)
+
+
+def decorate_methods(cls, decorator, testmatch=None):
+    """
+    Apply a decorator to all methods in a class matching a regular expression.
+
+    The given decorator is applied to all public methods of `cls` that are
+    matched by the regular expression `testmatch`
+    (``testmatch.search(methodname)``). Methods that are private, i.e. start
+    with an underscore, are ignored.
+
+    Parameters
+    ----------
+    cls : class
+        Class whose methods to decorate.
+    decorator : function
+        Decorator to apply to methods
+    testmatch : compiled regexp or str, optional
+        The regular expression. Default value is None, in which case the
+        nose default (``re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)``)
+        is used.
+        If `testmatch` is a string, it is compiled to a regular expression
+        first.
+
+    """
+    if testmatch is None:
+        testmatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
+    else:
+        testmatch = re.compile(testmatch)
+    cls_attr = cls.__dict__
+
+    # delayed import to reduce startup time
+    from inspect import isfunction
+
+    methods = [_m for _m in cls_attr.values() if isfunction(_m)]
+    for function in methods:
+        try:
+            if hasattr(function, 'compat_func_name'):
+                funcname = function.compat_func_name
+            else:
+                funcname = function.__name__
+        except AttributeError:
+            # not a function
+            continue
+        if testmatch.search(funcname) and not funcname.startswith('_'):
+            setattr(cls, funcname, decorator(function))
+    return
+
+
+def measure(code_str,times=1,label=None):
+    """
+    Return elapsed time for executing code in the namespace of the caller.
+
+    The supplied code string is compiled with the Python builtin ``compile``.
+    The precision of the timing is 10 milli-seconds. If the code will execute
+    fast on this timescale, it can be executed many times to get reasonable
+    timing accuracy.
+
+    Parameters
+    ----------
+    code_str : str
+        The code to be timed.
+    times : int, optional
+        The number of times the code is executed. Default is 1. The code is
+        only compiled once.
+    label : str, optional
+        A label to identify `code_str` with. This is passed into ``compile``
+        as the second argument (for run-time error messages).
+
+    Returns
+    -------
+    elapsed : float
+        Total elapsed time in seconds for executing `code_str` `times` times.
+
+    Examples
+    --------
+    >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)',
+    ...                            times=times)
+    >>> print("Time for a single execution : ", etime / times, "s")
+    Time for a single execution :  0.005 s
+
+    """
+    frame = sys._getframe(1)
+    locs, globs = frame.f_locals, frame.f_globals
+
+    code = compile(code_str,
+                   'Test name: %s ' % label,
+                   'exec')
+    i = 0
+    elapsed = jiffies()
+    while i < times:
+        i += 1
+        exec(code, globs, locs)
+    elapsed = jiffies() - elapsed
+    return 0.01*elapsed
+
+
+def _assert_valid_refcount(op):
+    """
+    Check that ufuncs don't mishandle refcount of object `1`.
+    Used in a few regression tests.
+    """
+    import numpy as np
+
+    b = np.arange(100*100).reshape(100, 100)
+    c = b
+    i = 1
+
+    rc = sys.getrefcount(i)
+    for j in range(15):
+        d = op(b, c)
+    assert_(sys.getrefcount(i) >= rc)
+    del d  # for pyflakes
+
+
+def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=False,
+                    err_msg='', verbose=True):
+    """
+    Raises an AssertionError if two objects are not equal up to desired
+    tolerance.
+
+    The test is equivalent to ``allclose(actual, desired, rtol, atol)``.
+    It compares the difference between `actual` and `desired` to
+    ``atol + rtol * abs(desired)``.
+
+    .. versionadded:: 1.5.0
+
+    Parameters
+    ----------
+    actual : array_like
+        Array obtained.
+    desired : array_like
+        Array desired.
+    rtol : float, optional
+        Relative tolerance.
+    atol : float, optional
+        Absolute tolerance.
+    equal_nan : bool, optional.
+        If True, NaNs will compare equal.
+    err_msg : str, optional
+        The error message to be printed in case of failure.
+    verbose : bool, optional
+        If True, the conflicting values are appended to the error message.
+
+    Raises
+    ------
+    AssertionError
+        If actual and desired are not equal up to specified precision.
+
+    See Also
+    --------
+    assert_array_almost_equal_nulp, assert_array_max_ulp
+
+    Examples
+    --------
+    >>> x = [1e-5, 1e-3, 1e-1]
+    >>> y = np.arccos(np.cos(x))
+    >>> assert_allclose(x, y, rtol=1e-5, atol=0)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+
+    def compare(x, y):
+        return np.core.numeric.isclose(x, y, rtol=rtol, atol=atol,
+                                       equal_nan=equal_nan)
+
+    actual, desired = np.asanyarray(actual), np.asanyarray(desired)
+    header = 'Not equal to tolerance rtol=%g, atol=%g' % (rtol, atol)
+    assert_array_compare(compare, actual, desired, err_msg=str(err_msg),
+                         verbose=verbose, header=header)
+
+def assert_array_almost_equal_nulp(x, y, nulp=1):
+    """
+    Compare two arrays relatively to their spacing.
+
+    This is a relatively robust method to compare two arrays whose amplitude
+    is variable.
+
+    Parameters
+    ----------
+    x, y : array_like
+        Input arrays.
+    nulp : int, optional
+        The maximum number of unit in the last place for tolerance (see Notes).
+        Default is 1.
+
+    Returns
+    -------
+    None
+
+    Raises
+    ------
+    AssertionError
+        If the spacing between `x` and `y` for one or more elements is larger
+        than `nulp`.
+
+    See Also
+    --------
+    assert_array_max_ulp : Check that all items of arrays differ in at most
+        N Units in the Last Place.
+    spacing : Return the distance between x and the nearest adjacent number.
+
+    Notes
+    -----
+    An assertion is raised if the following condition is not met::
+
+        abs(x - y) <= nulps * spacing(maximum(abs(x), abs(y)))
+
+    Examples
+    --------
+    >>> x = np.array([1., 1e-10, 1e-20])
+    >>> eps = np.finfo(x.dtype).eps
+    >>> np.testing.assert_array_almost_equal_nulp(x, x*eps/2 + x)
+
+    >>> np.testing.assert_array_almost_equal_nulp(x, x*eps + x)
+    Traceback (most recent call last):
+      ...
+    AssertionError: X and Y are not equal to 1 ULP (max is 2)
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+    ax = np.abs(x)
+    ay = np.abs(y)
+    ref = nulp * np.spacing(np.where(ax > ay, ax, ay))
+    if not np.all(np.abs(x-y) <= ref):
+        if np.iscomplexobj(x) or np.iscomplexobj(y):
+            msg = "X and Y are not equal to %d ULP" % nulp
+        else:
+            max_nulp = np.max(nulp_diff(x, y))
+            msg = "X and Y are not equal to %d ULP (max is %g)" % (nulp, max_nulp)
+        raise AssertionError(msg)
+
+def assert_array_max_ulp(a, b, maxulp=1, dtype=None):
+    """
+    Check that all items of arrays differ in at most N Units in the Last Place.
+
+    Parameters
+    ----------
+    a, b : array_like
+        Input arrays to be compared.
+    maxulp : int, optional
+        The maximum number of units in the last place that elements of `a` and
+        `b` can differ. Default is 1.
+    dtype : dtype, optional
+        Data-type to convert `a` and `b` to if given. Default is None.
+
+    Returns
+    -------
+    ret : ndarray
+        Array containing number of representable floating point numbers between
+        items in `a` and `b`.
+
+    Raises
+    ------
+    AssertionError
+        If one or more elements differ by more than `maxulp`.
+
+    See Also
+    --------
+    assert_array_almost_equal_nulp : Compare two arrays relatively to their
+        spacing.
+
+    Examples
+    --------
+    >>> a = np.linspace(0., 1., 100)
+    >>> res = np.testing.assert_array_max_ulp(a, np.arcsin(np.sin(a)))
+
+    """
+    __tracebackhide__ = True  # Hide traceback for py.test
+    import numpy as np
+    ret = nulp_diff(a, b, dtype)
+    if not np.all(ret <= maxulp):
+        raise AssertionError("Arrays are not almost equal up to %g ULP" %
+                             maxulp)
+    return ret
+
+def nulp_diff(x, y, dtype=None):
+    """For each item in x and y, return the number of representable floating
+    points between them.
+
+    Parameters
+    ----------
+    x : array_like
+        first input array
+    y : array_like
+        second input array
+    dtype : dtype, optional
+        Data-type to convert `x` and `y` to if given. Default is None.
+
+    Returns
+    -------
+    nulp : array_like
+        number of representable floating point numbers between each item in x
+        and y.
+
+    Examples
+    --------
+    # By definition, epsilon is the smallest number such as 1 + eps != 1, so
+    # there should be exactly one ULP between 1 and 1 + eps
+    >>> nulp_diff(1, 1 + np.finfo(x.dtype).eps)
+    1.0
+    """
+    import numpy as np
+    if dtype:
+        x = np.array(x, dtype=dtype)
+        y = np.array(y, dtype=dtype)
+    else:
+        x = np.array(x)
+        y = np.array(y)
+
+    t = np.common_type(x, y)
+    if np.iscomplexobj(x) or np.iscomplexobj(y):
+        raise NotImplementedError("_nulp not implemented for complex array")
+
+    x = np.array(x, dtype=t)
+    y = np.array(y, dtype=t)
+
+    if not x.shape == y.shape:
+        raise ValueError("x and y do not have the same shape: %s - %s" %
+                         (x.shape, y.shape))
+
+    def _diff(rx, ry, vdt):
+        diff = np.array(rx-ry, dtype=vdt)
+        return np.abs(diff)
+
+    rx = integer_repr(x)
+    ry = integer_repr(y)
+    return _diff(rx, ry, t)
+
+def _integer_repr(x, vdt, comp):
+    # Reinterpret binary representation of the float as sign-magnitude:
+    # take into account two-complement representation
+    # See also
+    # http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
+    rx = x.view(vdt)
+    if not (rx.size == 1):
+        rx[rx < 0] = comp - rx[rx < 0]
+    else:
+        if rx < 0:
+            rx = comp - rx
+
+    return rx
+
+def integer_repr(x):
+    """Return the signed-magnitude interpretation of the binary representation of
+    x."""
+    import numpy as np
+    if x.dtype == np.float32:
+        return _integer_repr(x, np.int32, np.int32(-2**31))
+    elif x.dtype == np.float64:
+        return _integer_repr(x, np.int64, np.int64(-2**63))
+    else:
+        raise ValueError("Unsupported dtype %s" % x.dtype)
+
+# The following two classes are copied from python 2.6 warnings module (context
+# manager)
+class WarningMessage(object):
+
+    """
+    Holds the result of a single showwarning() call.
+
+    Deprecated in 1.8.0
+
+    Notes
+    -----
+    `WarningMessage` is copied from the Python 2.6 warnings module,
+    so it can be used in NumPy with older Python versions.
+
+    """
+
+    _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
+                        "line")
+
+    def __init__(self, message, category, filename, lineno, file=None,
+                    line=None):
+        local_values = locals()
+        for attr in self._WARNING_DETAILS:
+            setattr(self, attr, local_values[attr])
+        if category:
+            self._category_name = category.__name__
+        else:
+            self._category_name = None
+
+    def __str__(self):
+        return ("{message : %r, category : %r, filename : %r, lineno : %s, "
+                    "line : %r}" % (self.message, self._category_name,
+                                    self.filename, self.lineno, self.line))
+
+class WarningManager(object):
+    """
+    A context manager that copies and restores the warnings filter upon
+    exiting the context.
+
+    The 'record' argument specifies whether warnings should be captured by a
+    custom implementation of ``warnings.showwarning()`` and be appended to a
+    list returned by the context manager. Otherwise None is returned by the
+    context manager. The objects appended to the list are arguments whose
+    attributes mirror the arguments to ``showwarning()``.
+
+    The 'module' argument is to specify an alternative module to the module
+    named 'warnings' and imported under that name. This argument is only useful
+    when testing the warnings module itself.
+
+    Deprecated in 1.8.0
+
+    Notes
+    -----
+    `WarningManager` is a copy of the ``catch_warnings`` context manager
+    from the Python 2.6 warnings module, with slight modifications.
+    It is copied so it can be used in NumPy with older Python versions.
+
+    """
+
+    def __init__(self, record=False, module=None):
+        self._record = record
+        if module is None:
+            self._module = sys.modules['warnings']
+        else:
+            self._module = module
+        self._entered = False
+
+    def __enter__(self):
+        if self._entered:
+            raise RuntimeError("Cannot enter %r twice" % self)
+        self._entered = True
+        self._filters = self._module.filters
+        self._module.filters = self._filters[:]
+        self._showwarning = self._module.showwarning
+        if self._record:
+            log = []
+
+            def showwarning(*args, **kwargs):
+                log.append(WarningMessage(*args, **kwargs))
+            self._module.showwarning = showwarning
+            return log
+        else:
+            return None
+
+    def __exit__(self):
+        if not self._entered:
+            raise RuntimeError("Cannot exit %r without entering first" % self)
+        self._module.filters = self._filters
+        self._module.showwarning = self._showwarning
+
+
+@contextlib.contextmanager
+def _assert_warns_context(warning_class, name=None):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    with warnings.catch_warnings(record=True) as l:
+        warnings.simplefilter('always')
+        yield
+        if not len(l) > 0:
+            name_str = " when calling %s" % name if name is not None else ""
+            raise AssertionError("No warning raised" + name_str)
+        if not l[0].category is warning_class:
+            name_str = "%s " % name if name is not None else ""
+            raise AssertionError("First warning %sis not a %s (is %s)"
+                                 % (name_str, warning_class, l[0]))
+
+
+def assert_warns(warning_class, *args, **kwargs):
+    """
+    Fail unless the given callable throws the specified warning.
+
+    A warning of class warning_class should be thrown by the callable when
+    invoked with arguments args and keyword arguments kwargs.
+    If a different type of warning is thrown, it will not be caught, and the
+    test case will be deemed to have suffered an error.
+
+    If called with all arguments other than the warning class omitted, may be
+    used as a context manager:
+
+        with assert_warns(SomeWarning):
+            do_something()
+
+    The ability to be used as a context manager is new in NumPy v1.11.0.
+
+    .. versionadded:: 1.4.0
+
+    Parameters
+    ----------
+    warning_class : class
+        The class defining the warning that `func` is expected to throw.
+    func : callable
+        The callable to test.
+    \\*args : Arguments
+        Arguments passed to `func`.
+    \\*\\*kwargs : Kwargs
+        Keyword arguments passed to `func`.
+
+    Returns
+    -------
+    The value returned by `func`.
+
+    """
+    if not args:
+        return _assert_warns_context(warning_class)
+
+    func = args[0]
+    args = args[1:]
+    with _assert_warns_context(warning_class, name=func.__name__):
+        return func(*args, **kwargs)
+
+
+@contextlib.contextmanager
+def _assert_no_warnings_context(name=None):
+    __tracebackhide__ = True  # Hide traceback for py.test
+    with warnings.catch_warnings(record=True) as l:
+        warnings.simplefilter('always')
+        yield
+        if len(l) > 0:
+            name_str = " when calling %s" % name if name is not None else ""
+            raise AssertionError("Got warnings%s: %s" % (name_str, l))
+
+
+def assert_no_warnings(*args, **kwargs):
+    """
+    Fail if the given callable produces any warnings.
+
+    If called with all arguments omitted, may be used as a context manager:
+
+        with assert_no_warnings():
+            do_something()
+
+    The ability to be used as a context manager is new in NumPy v1.11.0.
+
+    .. versionadded:: 1.7.0
+
+    Parameters
+    ----------
+    func : callable
+        The callable to test.
+    \\*args : Arguments
+        Arguments passed to `func`.
+    \\*\\*kwargs : Kwargs
+        Keyword arguments passed to `func`.
+
+    Returns
+    -------
+    The value returned by `func`.
+
+    """
+    if not args:
+        return _assert_no_warnings_context()
+
+    func = args[0]
+    args = args[1:]
+    with _assert_no_warnings_context(name=func.__name__):
+        return func(*args, **kwargs)
+
+
+def _gen_alignment_data(dtype=float32, type='binary', max_size=24):
+    """
+    generator producing data with different alignment and offsets
+    to test simd vectorization
+
+    Parameters
+    ----------
+    dtype : dtype
+        data type to produce
+    type : string
+        'unary': create data for unary operations, creates one input
+                 and output array
+        'binary': create data for unary operations, creates two input
+                 and output array
+    max_size : integer
+        maximum size of data to produce
+
+    Returns
+    -------
+    if type is 'unary' yields one output, one input array and a message
+    containing information on the data
+    if type is 'binary' yields one output array, two input array and a message
+    containing information on the data
+
+    """
+    ufmt = 'unary offset=(%d, %d), size=%d, dtype=%r, %s'
+    bfmt = 'binary offset=(%d, %d, %d), size=%d, dtype=%r, %s'
+    for o in range(3):
+        for s in range(o + 2, max(o + 3, max_size)):
+            if type == 'unary':
+                inp = lambda: arange(s, dtype=dtype)[o:]
+                out = empty((s,), dtype=dtype)[o:]
+                yield out, inp(), ufmt % (o, o, s, dtype, 'out of place')
+                yield inp(), inp(), ufmt % (o, o, s, dtype, 'in place')
+                yield out[1:], inp()[:-1], ufmt % \
+                    (o + 1, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp()[1:], ufmt % \
+                    (o, o + 1, s - 1, dtype, 'out of place')
+                yield inp()[:-1], inp()[1:], ufmt % \
+                    (o, o + 1, s - 1, dtype, 'aliased')
+                yield inp()[1:], inp()[:-1], ufmt % \
+                    (o + 1, o, s - 1, dtype, 'aliased')
+            if type == 'binary':
+                inp1 = lambda: arange(s, dtype=dtype)[o:]
+                inp2 = lambda: arange(s, dtype=dtype)[o:]
+                out = empty((s,), dtype=dtype)[o:]
+                yield out, inp1(), inp2(),  bfmt % \
+                    (o, o, o, s, dtype, 'out of place')
+                yield inp1(), inp1(), inp2(), bfmt % \
+                    (o, o, o, s, dtype, 'in place1')
+                yield inp2(), inp1(), inp2(), bfmt % \
+                    (o, o, o, s, dtype, 'in place2')
+                yield out[1:], inp1()[:-1], inp2()[:-1], bfmt % \
+                    (o + 1, o, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp1()[1:], inp2()[:-1], bfmt % \
+                    (o, o + 1, o, s - 1, dtype, 'out of place')
+                yield out[:-1], inp1()[:-1], inp2()[1:], bfmt % \
+                    (o, o, o + 1, s - 1, dtype, 'out of place')
+                yield inp1()[1:], inp1()[:-1], inp2()[:-1], bfmt % \
+                    (o + 1, o, o, s - 1, dtype, 'aliased')
+                yield inp1()[:-1], inp1()[1:], inp2()[:-1], bfmt % \
+                    (o, o + 1, o, s - 1, dtype, 'aliased')
+                yield inp1()[:-1], inp1()[:-1], inp2()[1:], bfmt % \
+                    (o, o, o + 1, s - 1, dtype, 'aliased')
+
+
+class IgnoreException(Exception):
+    "Ignoring this exception due to disabled feature"
+
+
+@contextlib.contextmanager
+def tempdir(*args, **kwargs):
+    """Context manager to provide a temporary test folder.
+
+    All arguments are passed as this to the underlying tempfile.mkdtemp
+    function.
+
+    """
+    tmpdir = mkdtemp(*args, **kwargs)
+    try:
+        yield tmpdir
+    finally:
+        shutil.rmtree(tmpdir)
+
+@contextlib.contextmanager
+def temppath(*args, **kwargs):
+    """Context manager for temporary files.
+
+    Context manager that returns the path to a closed temporary file. Its
+    parameters are the same as for tempfile.mkstemp and are passed directly
+    to that function. The underlying file is removed when the context is
+    exited, so it should be closed at that time.
+  
+    Windows does not allow a temporary file to be opened if it is already
+    open, so the underlying file must be closed after opening before it
+    can be opened again.
+
+    """
+    fd, path = mkstemp(*args, **kwargs)
+    os.close(fd)
+    try:
+        yield path
+    finally:
+        os.remove(path)
+
+
+class clear_and_catch_warnings(warnings.catch_warnings):
+    """ Context manager that resets warning registry for catching warnings
+
+    Warnings can be slippery, because, whenever a warning is triggered, Python
+    adds a ``__warningregistry__`` member to the *calling* module.  This makes
+    it impossible to retrigger the warning in this module, whatever you put in
+    the warnings filters.  This context manager accepts a sequence of `modules`
+    as a keyword argument to its constructor and:
+
+    * stores and removes any ``__warningregistry__`` entries in given `modules`
+      on entry;
+    * resets ``__warningregistry__`` to its previous state on exit.
+
+    This makes it possible to trigger any warning afresh inside the context
+    manager without disturbing the state of warnings outside.
+
+    For compatibility with Python 3.0, please consider all arguments to be
+    keyword-only.
+
+    Parameters
+    ----------
+    record : bool, optional
+        Specifies whether warnings should be captured by a custom
+        implementation of ``warnings.showwarning()`` and be appended to a list
+        returned by the context manager. Otherwise None is returned by the
+        context manager. The objects appended to the list are arguments whose
+        attributes mirror the arguments to ``showwarning()``.
+    modules : sequence, optional
+        Sequence of modules for which to reset warnings registry on entry and
+        restore on exit
+
+    Examples
+    --------
+    >>> import warnings
+    >>> with clear_and_catch_warnings(modules=[np.core.fromnumeric]):
+    ...     warnings.simplefilter('always')
+    ...     # do something that raises a warning in np.core.fromnumeric
+    """
+    class_modules = ()
+
+    def __init__(self, record=False, modules=()):
+        self.modules = set(modules).union(self.class_modules)
+        self._warnreg_copies = {}
+        super(clear_and_catch_warnings, self).__init__(record=record)
+
+    def __enter__(self):
+        for mod in self.modules:
+            if hasattr(mod, '__warningregistry__'):
+                mod_reg = mod.__warningregistry__
+                self._warnreg_copies[mod] = mod_reg.copy()
+                mod_reg.clear()
+        return super(clear_and_catch_warnings, self).__enter__()
+
+    def __exit__(self, *exc_info):
+        super(clear_and_catch_warnings, self).__exit__(*exc_info)
+        for mod in self.modules:
+            if hasattr(mod, '__warningregistry__'):
+                mod.__warningregistry__.clear()
+            if mod in self._warnreg_copies:
+                mod.__warningregistry__.update(self._warnreg_copies[mod])
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
new file mode 100644
index 0000000000..5e888eb652
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
@@ -0,0 +1,106 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+import numpy as np
+from numpy.ctypeslib import ndpointer, load_library
+from numpy.distutils.misc_util import get_shared_lib_extension
+from numpy.testing import TestCase, run_module_suite, dec
+
+try:
+    cdll = load_library('multiarray', np.core.multiarray.__file__)
+    _HAS_CTYPE = True
+except ImportError:
+    _HAS_CTYPE = False
+
+class TestLoadLibrary(TestCase):
+    @dec.skipif(not _HAS_CTYPE,
+                "ctypes not available on this python installation")
+    @dec.knownfailureif(sys.platform ==
+                        'cygwin', "This test is known to fail on cygwin")
+    def test_basic(self):
+        try:
+            # Should succeed
+            load_library('multiarray', np.core.multiarray.__file__)
+        except ImportError as e:
+            msg = ("ctypes is not available on this python: skipping the test"
+                   " (import error was: %s)" % str(e))
+            print(msg)
+
+    @dec.skipif(not _HAS_CTYPE,
+                "ctypes not available on this python installation")
+    @dec.knownfailureif(sys.platform ==
+                        'cygwin', "This test is known to fail on cygwin")
+    def test_basic2(self):
+        # Regression for #801: load_library with a full library name
+        # (including extension) does not work.
+        try:
+            try:
+                so = get_shared_lib_extension(is_python_ext=True)
+                # Should succeed
+                load_library('multiarray%s' % so, np.core.multiarray.__file__)
+            except ImportError:
+                print("No distutils available, skipping test.")
+        except ImportError as e:
+            msg = ("ctypes is not available on this python: skipping the test"
+                   " (import error was: %s)" % str(e))
+            print(msg)
+
+class TestNdpointer(TestCase):
+    def test_dtype(self):
+        dt = np.intc
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.array([1], dt)))
+        dt = '<i4'
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.array([1], dt)))
+        dt = np.dtype('>i4')
+        p = ndpointer(dtype=dt)
+        p.from_param(np.array([1], dt))
+        self.assertRaises(TypeError, p.from_param,
+                          np.array([1], dt.newbyteorder('swap')))
+        dtnames = ['x', 'y']
+        dtformats = [np.intc, np.float64]
+        dtdescr = {'names': dtnames, 'formats': dtformats}
+        dt = np.dtype(dtdescr)
+        p = ndpointer(dtype=dt)
+        self.assertTrue(p.from_param(np.zeros((10,), dt)))
+        samedt = np.dtype(dtdescr)
+        p = ndpointer(dtype=samedt)
+        self.assertTrue(p.from_param(np.zeros((10,), dt)))
+        dt2 = np.dtype(dtdescr, align=True)
+        if dt.itemsize != dt2.itemsize:
+            self.assertRaises(TypeError, p.from_param, np.zeros((10,), dt2))
+        else:
+            self.assertTrue(p.from_param(np.zeros((10,), dt2)))
+
+    def test_ndim(self):
+        p = ndpointer(ndim=0)
+        self.assertTrue(p.from_param(np.array(1)))
+        self.assertRaises(TypeError, p.from_param, np.array([1]))
+        p = ndpointer(ndim=1)
+        self.assertRaises(TypeError, p.from_param, np.array(1))
+        self.assertTrue(p.from_param(np.array([1])))
+        p = ndpointer(ndim=2)
+        self.assertTrue(p.from_param(np.array([[1]])))
+
+    def test_shape(self):
+        p = ndpointer(shape=(1, 2))
+        self.assertTrue(p.from_param(np.array([[1, 2]])))
+        self.assertRaises(TypeError, p.from_param, np.array([[1], [2]]))
+        p = ndpointer(shape=())
+        self.assertTrue(p.from_param(np.array(1)))
+
+    def test_flags(self):
+        x = np.array([[1, 2], [3, 4]], order='F')
+        p = ndpointer(flags='FORTRAN')
+        self.assertTrue(p.from_param(x))
+        p = ndpointer(flags='CONTIGUOUS')
+        self.assertRaises(TypeError, p.from_param, x)
+        p = ndpointer(flags=x.flags.num)
+        self.assertTrue(p.from_param(x))
+        self.assertRaises(TypeError, p.from_param, np.array([[1, 2], [3, 4]]))
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_matlib.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_matlib.py
new file mode 100644
index 0000000000..3ff6cd7ed2
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_matlib.py
@@ -0,0 +1,55 @@
+from __future__ import division, absolute_import, print_function
+
+import numpy as np
+import numpy.matlib
+from numpy.testing import assert_array_equal, assert_, run_module_suite
+
+def test_empty():
+    x = numpy.matlib.empty((2,))
+    assert_(isinstance(x, np.matrix))
+    assert_(x.shape, (1, 2))
+
+def test_ones():
+    assert_array_equal(numpy.matlib.ones((2, 3)),
+                       np.matrix([[ 1.,  1.,  1.],
+                                 [ 1.,  1.,  1.]]))
+
+    assert_array_equal(numpy.matlib.ones(2), np.matrix([[ 1.,  1.]]))
+
+def test_zeros():
+    assert_array_equal(numpy.matlib.zeros((2, 3)),
+                       np.matrix([[ 0.,  0.,  0.],
+                                 [ 0.,  0.,  0.]]))
+
+    assert_array_equal(numpy.matlib.zeros(2), np.matrix([[ 0.,  0.]]))
+
+def test_identity():
+    x = numpy.matlib.identity(2, dtype=np.int)
+    assert_array_equal(x, np.matrix([[1, 0], [0, 1]]))
+
+def test_eye():
+    x = numpy.matlib.eye(3, k=1, dtype=int)
+    assert_array_equal(x, np.matrix([[ 0,  1,  0],
+                                     [ 0,  0,  1],
+                                     [ 0,  0,  0]]))
+
+def test_rand():
+    x = numpy.matlib.rand(3)
+    # check matrix type, array would have shape (3,)
+    assert_(x.ndim == 2)
+
+def test_randn():
+    x = np.matlib.randn(3)
+    # check matrix type, array would have shape (3,)
+    assert_(x.ndim == 2)
+
+def test_repmat():
+    a1 = np.arange(4)
+    x = numpy.matlib.repmat(a1, 2, 2)
+    y = np.array([[0, 1, 2, 3, 0, 1, 2, 3],
+                  [0, 1, 2, 3, 0, 1, 2, 3]])
+    assert_array_equal(x, y)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
new file mode 100644
index 0000000000..b61d0d5f19
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
@@ -0,0 +1,23 @@
+from __future__ import division, absolute_import, print_function
+
+import re
+
+import numpy as np
+from numpy.testing import assert_, run_module_suite
+
+
+def test_valid_numpy_version():
+    # Verify that the numpy version is a valid one (no .post suffix or other
+    # nonsense).  See gh-6431 for an issue caused by an invalid version.
+    version_pattern = r"^[0-9]+\.[0-9]+\.[0-9]+(|a[0-9]|b[0-9]|rc[0-9])"
+    dev_suffix = r"(\.dev0\+([0-9a-f]{7}|Unknown))"
+    if np.version.release:
+        res = re.match(version_pattern, np.__version__)
+    else:
+        res = re.match(version_pattern + dev_suffix, np.__version__)
+
+    assert_(res is not None, np.__version__)
+
+
+if __name__ == "__main__":
+    run_module_suite()
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_scripts.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_scripts.py
new file mode 100644
index 0000000000..19ddff0d36
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/tests/test_scripts.py
@@ -0,0 +1,99 @@
+""" Test scripts
+
+Test that we can run executable scripts that have been installed with numpy.
+"""
+from __future__ import division, print_function, absolute_import
+
+import os
+from os.path import join as pathjoin, isfile, dirname, basename
+import sys
+from subprocess import Popen, PIPE
+import numpy as np
+from numpy.compat.py3k import basestring, asbytes
+from nose.tools import assert_equal
+from numpy.testing.decorators import skipif
+from numpy.testing import assert_
+
+is_inplace = isfile(pathjoin(dirname(np.__file__),  '..', 'setup.py'))
+
+def run_command(cmd, check_code=True):
+    """ Run command sequence `cmd` returning exit code, stdout, stderr
+
+    Parameters
+    ----------
+    cmd : str or sequence
+        string with command name or sequence of strings defining command
+    check_code : {True, False}, optional
+        If True, raise error for non-zero return code
+
+    Returns
+    -------
+    returncode : int
+        return code from execution of `cmd`
+    stdout : bytes (python 3) or str (python 2)
+        stdout from `cmd`
+    stderr : bytes (python 3) or str (python 2)
+        stderr from `cmd`
+
+    Raises
+    ------
+    RuntimeError
+        If `check_code` is True, and return code !=0
+    """
+    cmd = [cmd] if isinstance(cmd, basestring) else list(cmd)
+    if os.name == 'nt':
+        # Quote any arguments with spaces. The quotes delimit the arguments
+        # on Windows, and the arguments might be file paths with spaces.
+        # On Unix the list elements are each separate arguments.
+        cmd = ['"{0}"'.format(c) if ' ' in c else c for c in cmd]
+    proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
+    stdout, stderr = proc.communicate()
+    if proc.poll() == None:
+        proc.terminate()
+    if check_code and proc.returncode != 0:
+        raise RuntimeError('\n'.join(
+            ['Command "{0}" failed with',
+             'stdout', '------', '{1}', '',
+             'stderr', '------', '{2}']).format(cmd, stdout, stderr))
+    return proc.returncode, stdout, stderr
+
+
+@skipif(is_inplace)
+def test_f2py():
+    # test that we can run f2py script
+    if sys.platform == 'win32':
+        exe_dir = dirname(sys.executable)
+
+        if exe_dir.endswith('Scripts'): # virtualenv
+            f2py_cmd = r"%s\f2py.py" % exe_dir
+        else:
+            f2py_cmd = r"%s\Scripts\f2py.py" % exe_dir
+
+        code, stdout, stderr = run_command([sys.executable, f2py_cmd, '-v'])
+        success = stdout.strip() == asbytes('2')
+        assert_(success, "Warning: f2py not found in path")
+    else:
+        version = sys.version_info
+
+        # Python 2.6 'sys.version_info'
+        # is just a tuple, but this changes
+        # in Python 2.7 to have a more user-
+        # friendly interface with version[0]
+        # being the 'major' version and
+        # version[1] being the minor version
+        major = str(version[0])
+        minor = str(version[1])
+
+        f2py_cmds = ('f2py', 'f2py' + major, 'f2py' + major + '.' + minor)
+        success = False
+
+        for f2py_cmd in f2py_cmds:
+            try:
+                code, stdout, stderr = run_command([f2py_cmd, '-v'])
+                assert_equal(stdout.strip(), asbytes('2'))
+                success = True
+                break
+            except:
+                pass
+        msg = "Warning: neither %s nor %s nor %s found in path" % f2py_cmds
+        assert_(success, msg)
diff --git a/tools/msys/mingw64/lib/python2.7/site-packages/numpy/version.py b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/version.py
new file mode 100644
index 0000000000..7c29e33627
--- /dev/null
+++ b/tools/msys/mingw64/lib/python2.7/site-packages/numpy/version.py
@@ -0,0 +1,12 @@
+
+# THIS FILE IS GENERATED FROM NUMPY SETUP.PY
+#
+# To compare versions robustly, use `numpy.lib.NumpyVersion`
+short_version = '1.11.0'
+version = '1.11.0'
+full_version = '1.11.0'
+git_revision = '4092a9e160cc247a4a45724579a0c829733688ca'
+release = True
+
+if not release:
+    version = full_version
diff --git a/tools/msys/mingw64/share/licenses/python2-numpy/LICENSE.txt b/tools/msys/mingw64/share/licenses/python2-numpy/LICENSE.txt
new file mode 100644
index 0000000000..9014534ab4
--- /dev/null
+++ b/tools/msys/mingw64/share/licenses/python2-numpy/LICENSE.txt
@@ -0,0 +1,30 @@
+Copyright (c) 2005-2016, NumPy Developers.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+
+    * Neither the name of the NumPy Developers nor the names of any
+       contributors may be used to endorse or promote products derived
+       from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/desc
new file mode 100644
index 0000000000..31f2b4d9e4
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/desc
@@ -0,0 +1,43 @@
+%NAME%
+mingw-w64-i686-python2-numpy
+
+%VERSION%
+1.11.0-1
+
+%BASE%
+mingw-w64-python-numpy
+
+%DESC%
+Scientific tools for Python (mingw-w64)
+
+%URL%
+http://www.numpy.org/
+
+%ARCH%
+any
+
+%BUILDDATE%
+1459935234
+
+%INSTALLDATE%
+1481327648
+
+%PACKAGER%
+Alexey Pavlov <alexpux@gmail.com>
+
+%SIZE%
+16917504
+
+%LICENSE%
+BSD
+
+%VALIDATION%
+pgp
+
+%DEPENDS%
+mingw-w64-i686-openblas
+mingw-w64-i686-python2
+
+%OPTDEPENDS%
+mingw-w64-i686-python2-nose: testsuite
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/files
new file mode 100644
index 0000000000..eb246e4ae3
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/files
@@ -0,0 +1,835 @@
+%FILES%
+mingw32/
+mingw32/bin/
+mingw32/bin/f2py2.py
+mingw32/include/
+mingw32/include/python2.7/
+mingw32/include/python2.7/numpy/
+mingw32/include/python2.7/numpy/__multiarray_api.h
+mingw32/include/python2.7/numpy/__ufunc_api.h
+mingw32/include/python2.7/numpy/_neighborhood_iterator_imp.h
+mingw32/include/python2.7/numpy/_numpyconfig.h
+mingw32/include/python2.7/numpy/arrayobject.h
+mingw32/include/python2.7/numpy/arrayscalars.h
+mingw32/include/python2.7/numpy/halffloat.h
+mingw32/include/python2.7/numpy/multiarray_api.txt
+mingw32/include/python2.7/numpy/ndarrayobject.h
+mingw32/include/python2.7/numpy/ndarraytypes.h
+mingw32/include/python2.7/numpy/noprefix.h
+mingw32/include/python2.7/numpy/npy_1_7_deprecated_api.h
+mingw32/include/python2.7/numpy/npy_3kcompat.h
+mingw32/include/python2.7/numpy/npy_common.h
+mingw32/include/python2.7/numpy/npy_cpu.h
+mingw32/include/python2.7/numpy/npy_endian.h
+mingw32/include/python2.7/numpy/npy_interrupt.h
+mingw32/include/python2.7/numpy/npy_math.h
+mingw32/include/python2.7/numpy/npy_no_deprecated_api.h
+mingw32/include/python2.7/numpy/npy_os.h
+mingw32/include/python2.7/numpy/numpyconfig.h
+mingw32/include/python2.7/numpy/old_defines.h
+mingw32/include/python2.7/numpy/oldnumeric.h
+mingw32/include/python2.7/numpy/ufunc_api.txt
+mingw32/include/python2.7/numpy/ufuncobject.h
+mingw32/include/python2.7/numpy/utils.h
+mingw32/lib/
+mingw32/lib/python2.7/
+mingw32/lib/python2.7/site-packages/
+mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/
+mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
+mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
+mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
+mingw32/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
+mingw32/lib/python2.7/site-packages/numpy/
+mingw32/lib/python2.7/site-packages/numpy/__config__.py
+mingw32/lib/python2.7/site-packages/numpy/__config__.pyc
+mingw32/lib/python2.7/site-packages/numpy/__config__.pyo
+mingw32/lib/python2.7/site-packages/numpy/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/_import_tools.py
+mingw32/lib/python2.7/site-packages/numpy/_import_tools.pyc
+mingw32/lib/python2.7/site-packages/numpy/_import_tools.pyo
+mingw32/lib/python2.7/site-packages/numpy/add_newdocs.py
+mingw32/lib/python2.7/site-packages/numpy/add_newdocs.pyc
+mingw32/lib/python2.7/site-packages/numpy/add_newdocs.pyo
+mingw32/lib/python2.7/site-packages/numpy/compat/
+mingw32/lib/python2.7/site-packages/numpy/compat/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/compat/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/compat/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.py
+mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.pyc
+mingw32/lib/python2.7/site-packages/numpy/compat/_inspect.pyo
+mingw32/lib/python2.7/site-packages/numpy/compat/py3k.py
+mingw32/lib/python2.7/site-packages/numpy/compat/py3k.pyc
+mingw32/lib/python2.7/site-packages/numpy/compat/py3k.pyo
+mingw32/lib/python2.7/site-packages/numpy/compat/setup.py
+mingw32/lib/python2.7/site-packages/numpy/compat/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/compat/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/
+mingw32/lib/python2.7/site-packages/numpy/core/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/core/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/_dummy.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/_internal.py
+mingw32/lib/python2.7/site-packages/numpy/core/_internal.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/_internal.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/_methods.py
+mingw32/lib/python2.7/site-packages/numpy/core/_methods.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/_methods.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.py
+mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/arrayprint.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/cversions.py
+mingw32/lib/python2.7/site-packages/numpy/core/cversions.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/cversions.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/defchararray.py
+mingw32/lib/python2.7/site-packages/numpy/core/defchararray.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/defchararray.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.py
+mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/fromnumeric.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/function_base.py
+mingw32/lib/python2.7/site-packages/numpy/core/function_base.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/function_base.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
+mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/generate_numpy_api.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/getlimits.py
+mingw32/lib/python2.7/site-packages/numpy/core/getlimits.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/getlimits.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/include/
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
+mingw32/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
+mingw32/lib/python2.7/site-packages/numpy/core/info.py
+mingw32/lib/python2.7/site-packages/numpy/core/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/lib/
+mingw32/lib/python2.7/site-packages/numpy/core/lib/libnpymath.a
+mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/
+mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
+mingw32/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
+mingw32/lib/python2.7/site-packages/numpy/core/machar.py
+mingw32/lib/python2.7/site-packages/numpy/core/machar.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/machar.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/memmap.py
+mingw32/lib/python2.7/site-packages/numpy/core/memmap.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/memmap.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/multiarray.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/numeric.py
+mingw32/lib/python2.7/site-packages/numpy/core/numeric.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/numeric.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.py
+mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/numerictypes.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/records.py
+mingw32/lib/python2.7/site-packages/numpy/core/records.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/records.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/setup.py
+mingw32/lib/python2.7/site-packages/numpy/core/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/setup_common.py
+mingw32/lib/python2.7/site-packages/numpy/core/setup_common.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/setup_common.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/shape_base.py
+mingw32/lib/python2.7/site-packages/numpy/core/shape_base.pyc
+mingw32/lib/python2.7/site-packages/numpy/core/shape_base.pyo
+mingw32/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/test_rational.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/tests/
+mingw32/lib/python2.7/site-packages/numpy/core/tests/data/
+mingw32/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
+mingw32/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_api.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_half.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_print.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_records.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
+mingw32/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
+mingw32/lib/python2.7/site-packages/numpy/core/umath.pyd
+mingw32/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
+mingw32/lib/python2.7/site-packages/numpy/ctypeslib.py
+mingw32/lib/python2.7/site-packages/numpy/ctypeslib.pyc
+mingw32/lib/python2.7/site-packages/numpy/ctypeslib.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/
+mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/__config__.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/__version__.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/ccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/autodist.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_clib.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_ext.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_py.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/build_src.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/develop.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/egg_info.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_clib.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_data.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/install_headers.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/command/sdist.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/compat.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/compat.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/compat.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/conv_template.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/core.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/core.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/core.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/cpuinfo.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/environment.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/environment.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/environment.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/exec_command.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/extension.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/extension.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/extension.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/from_template.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/info.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/intelccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/lib2def.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/line_endings.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/log.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/log.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/log.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/
+mingw32/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
+mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/misc_util.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/msvccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/pathccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/setup.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/system_info.pyo
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
+mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.pyc
+mingw32/lib/python2.7/site-packages/numpy/distutils/unixccompiler.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/
+mingw32/lib/python2.7/site-packages/numpy/doc/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/doc/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/basics.py
+mingw32/lib/python2.7/site-packages/numpy/doc/basics.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/basics.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.py
+mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/broadcasting.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.py
+mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/byteswapping.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/constants.py
+mingw32/lib/python2.7/site-packages/numpy/doc/constants.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/constants.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/creation.py
+mingw32/lib/python2.7/site-packages/numpy/doc/creation.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/creation.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/glossary.py
+mingw32/lib/python2.7/site-packages/numpy/doc/glossary.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/glossary.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/indexing.py
+mingw32/lib/python2.7/site-packages/numpy/doc/indexing.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/indexing.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/internals.py
+mingw32/lib/python2.7/site-packages/numpy/doc/internals.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/internals.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/misc.py
+mingw32/lib/python2.7/site-packages/numpy/doc/misc.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/misc.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
+mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/structured_arrays.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.py
+mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/subclassing.pyo
+mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.py
+mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.pyc
+mingw32/lib/python2.7/site-packages/numpy/doc/ufuncs.pyo
+mingw32/lib/python2.7/site-packages/numpy/dual.py
+mingw32/lib/python2.7/site-packages/numpy/dual.pyc
+mingw32/lib/python2.7/site-packages/numpy/dual.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/
+mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/__main__.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/__version__.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/auxfuncs.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/capi_maps.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/cb_rules.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/cfuncs.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/common_rules.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/crackfortran.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/diagnose.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py2e.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/f2py_testing.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/func2subr.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/info.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/rules.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/rules.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/rules.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/setup.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/f2py/src/
+mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
+mingw32/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/tests/util.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.py
+mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.pyc
+mingw32/lib/python2.7/site-packages/numpy/f2py/use_rules.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/
+mingw32/lib/python2.7/site-packages/numpy/fft/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/fft/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/fft/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.py
+mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.pyc
+mingw32/lib/python2.7/site-packages/numpy/fft/fftpack.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
+mingw32/lib/python2.7/site-packages/numpy/fft/helper.py
+mingw32/lib/python2.7/site-packages/numpy/fft/helper.pyc
+mingw32/lib/python2.7/site-packages/numpy/fft/helper.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/info.py
+mingw32/lib/python2.7/site-packages/numpy/fft/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/fft/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/setup.py
+mingw32/lib/python2.7/site-packages/numpy/fft/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/fft/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/fft/tests/
+mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
+mingw32/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
+mingw32/lib/python2.7/site-packages/numpy/lib/
+mingw32/lib/python2.7/site-packages/numpy/lib/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/lib/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.py
+mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/_datasource.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.py
+mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/_iotools.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/_version.py
+mingw32/lib/python2.7/site-packages/numpy/lib/_version.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/_version.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.py
+mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/arraypad.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.py
+mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/arraysetops.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.py
+mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/arrayterator.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/financial.py
+mingw32/lib/python2.7/site-packages/numpy/lib/financial.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/financial.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/format.py
+mingw32/lib/python2.7/site-packages/numpy/lib/format.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/format.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/function_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/function_base.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/function_base.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.py
+mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/index_tricks.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/info.py
+mingw32/lib/python2.7/site-packages/numpy/lib/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
+mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/nanfunctions.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/npyio.py
+mingw32/lib/python2.7/site-packages/numpy/lib/npyio.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/npyio.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.py
+mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/polynomial.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.py
+mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/recfunctions.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/scimath.py
+mingw32/lib/python2.7/site-packages/numpy/lib/scimath.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/scimath.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/setup.py
+mingw32/lib/python2.7/site-packages/numpy/lib/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/shape_base.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
+mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/stride_tricks.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
+mingw32/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
+mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.py
+mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/twodim_base.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/type_check.py
+mingw32/lib/python2.7/site-packages/numpy/lib/type_check.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/type_check.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.py
+mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/ufunclike.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/user_array.py
+mingw32/lib/python2.7/site-packages/numpy/lib/user_array.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/user_array.pyo
+mingw32/lib/python2.7/site-packages/numpy/lib/utils.py
+mingw32/lib/python2.7/site-packages/numpy/lib/utils.pyc
+mingw32/lib/python2.7/site-packages/numpy/lib/utils.pyo
+mingw32/lib/python2.7/site-packages/numpy/linalg/
+mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/linalg/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
+mingw32/lib/python2.7/site-packages/numpy/linalg/info.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/linalg/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
+mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.pyc
+mingw32/lib/python2.7/site-packages/numpy/linalg/linalg.pyo
+mingw32/lib/python2.7/site-packages/numpy/linalg/setup.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/linalg/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/linalg/tests/
+mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
+mingw32/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/ma/
+mingw32/lib/python2.7/site-packages/numpy/ma/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/ma/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/bench.py
+mingw32/lib/python2.7/site-packages/numpy/ma/bench.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/bench.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/core.py
+mingw32/lib/python2.7/site-packages/numpy/ma/core.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/core.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/extras.py
+mingw32/lib/python2.7/site-packages/numpy/ma/extras.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/extras.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.py
+mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/mrecords.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/setup.py
+mingw32/lib/python2.7/site-packages/numpy/ma/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
+mingw32/lib/python2.7/site-packages/numpy/ma/testutils.py
+mingw32/lib/python2.7/site-packages/numpy/ma/testutils.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/testutils.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
+mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/timer_comparison.pyo
+mingw32/lib/python2.7/site-packages/numpy/ma/version.py
+mingw32/lib/python2.7/site-packages/numpy/ma/version.pyc
+mingw32/lib/python2.7/site-packages/numpy/ma/version.pyo
+mingw32/lib/python2.7/site-packages/numpy/matlib.py
+mingw32/lib/python2.7/site-packages/numpy/matlib.pyc
+mingw32/lib/python2.7/site-packages/numpy/matlib.pyo
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyc
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyo
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
+mingw32/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/
+mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/_polybase.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/chebyshev.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/hermite_e.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/laguerre.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/legendre.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polynomial.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/polyutils.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/polynomial/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
+mingw32/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
+mingw32/lib/python2.7/site-packages/numpy/random/
+mingw32/lib/python2.7/site-packages/numpy/random/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/random/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/random/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/random/info.py
+mingw32/lib/python2.7/site-packages/numpy/random/info.pyc
+mingw32/lib/python2.7/site-packages/numpy/random/info.pyo
+mingw32/lib/python2.7/site-packages/numpy/random/mtrand.pyd
+mingw32/lib/python2.7/site-packages/numpy/random/randomkit.h
+mingw32/lib/python2.7/site-packages/numpy/random/setup.py
+mingw32/lib/python2.7/site-packages/numpy/random/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/random/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/random/tests/
+mingw32/lib/python2.7/site-packages/numpy/random/tests/test_random.py
+mingw32/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
+mingw32/lib/python2.7/site-packages/numpy/setup.py
+mingw32/lib/python2.7/site-packages/numpy/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/
+mingw32/lib/python2.7/site-packages/numpy/testing/__init__.py
+mingw32/lib/python2.7/site-packages/numpy/testing/__init__.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/__init__.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/decorators.py
+mingw32/lib/python2.7/site-packages/numpy/testing/decorators.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/decorators.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.py
+mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/noseclasses.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.py
+mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/nosetester.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
+mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/setup.py
+mingw32/lib/python2.7/site-packages/numpy/testing/setup.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/setup.pyo
+mingw32/lib/python2.7/site-packages/numpy/testing/tests/
+mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
+mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
+mingw32/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
+mingw32/lib/python2.7/site-packages/numpy/testing/utils.py
+mingw32/lib/python2.7/site-packages/numpy/testing/utils.pyc
+mingw32/lib/python2.7/site-packages/numpy/testing/utils.pyo
+mingw32/lib/python2.7/site-packages/numpy/tests/
+mingw32/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
+mingw32/lib/python2.7/site-packages/numpy/tests/test_matlib.py
+mingw32/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
+mingw32/lib/python2.7/site-packages/numpy/tests/test_scripts.py
+mingw32/lib/python2.7/site-packages/numpy/version.py
+mingw32/lib/python2.7/site-packages/numpy/version.pyc
+mingw32/lib/python2.7/site-packages/numpy/version.pyo
+mingw32/share/
+mingw32/share/licenses/
+mingw32/share/licenses/python2-numpy/
+mingw32/share/licenses/python2-numpy/LICENSE.txt
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-i686-python2-numpy-1.11.0-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..4af2c5973f6ed480e0c7424f480befab70db014e
GIT binary patch
literal 47192
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
A6#xJL

literal 0
HcmV?d00001

diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/desc
new file mode 100644
index 0000000000..120b79f721
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/desc
@@ -0,0 +1,43 @@
+%NAME%
+mingw-w64-x86_64-python2-numpy
+
+%VERSION%
+1.11.0-1
+
+%BASE%
+mingw-w64-python-numpy
+
+%DESC%
+Scientific tools for Python (mingw-w64)
+
+%URL%
+http://www.numpy.org/
+
+%ARCH%
+any
+
+%BUILDDATE%
+1459934990
+
+%INSTALLDATE%
+1481327683
+
+%PACKAGER%
+Alexey Pavlov <alexpux@gmail.com>
+
+%SIZE%
+17059840
+
+%LICENSE%
+BSD
+
+%VALIDATION%
+pgp
+
+%DEPENDS%
+mingw-w64-x86_64-openblas
+mingw-w64-x86_64-python2
+
+%OPTDEPENDS%
+mingw-w64-x86_64-python2-nose: testsuite
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/files
new file mode 100644
index 0000000000..b9100160a2
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/files
@@ -0,0 +1,835 @@
+%FILES%
+mingw64/
+mingw64/bin/
+mingw64/bin/f2py2.py
+mingw64/include/
+mingw64/include/python2.7/
+mingw64/include/python2.7/numpy/
+mingw64/include/python2.7/numpy/__multiarray_api.h
+mingw64/include/python2.7/numpy/__ufunc_api.h
+mingw64/include/python2.7/numpy/_neighborhood_iterator_imp.h
+mingw64/include/python2.7/numpy/_numpyconfig.h
+mingw64/include/python2.7/numpy/arrayobject.h
+mingw64/include/python2.7/numpy/arrayscalars.h
+mingw64/include/python2.7/numpy/halffloat.h
+mingw64/include/python2.7/numpy/multiarray_api.txt
+mingw64/include/python2.7/numpy/ndarrayobject.h
+mingw64/include/python2.7/numpy/ndarraytypes.h
+mingw64/include/python2.7/numpy/noprefix.h
+mingw64/include/python2.7/numpy/npy_1_7_deprecated_api.h
+mingw64/include/python2.7/numpy/npy_3kcompat.h
+mingw64/include/python2.7/numpy/npy_common.h
+mingw64/include/python2.7/numpy/npy_cpu.h
+mingw64/include/python2.7/numpy/npy_endian.h
+mingw64/include/python2.7/numpy/npy_interrupt.h
+mingw64/include/python2.7/numpy/npy_math.h
+mingw64/include/python2.7/numpy/npy_no_deprecated_api.h
+mingw64/include/python2.7/numpy/npy_os.h
+mingw64/include/python2.7/numpy/numpyconfig.h
+mingw64/include/python2.7/numpy/old_defines.h
+mingw64/include/python2.7/numpy/oldnumeric.h
+mingw64/include/python2.7/numpy/ufunc_api.txt
+mingw64/include/python2.7/numpy/ufuncobject.h
+mingw64/include/python2.7/numpy/utils.h
+mingw64/lib/
+mingw64/lib/python2.7/
+mingw64/lib/python2.7/site-packages/
+mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/
+mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/PKG-INFO
+mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/SOURCES.txt
+mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/dependency_links.txt
+mingw64/lib/python2.7/site-packages/numpy-1.11.0-py2.7.egg-info/top_level.txt
+mingw64/lib/python2.7/site-packages/numpy/
+mingw64/lib/python2.7/site-packages/numpy/__config__.py
+mingw64/lib/python2.7/site-packages/numpy/__config__.pyc
+mingw64/lib/python2.7/site-packages/numpy/__config__.pyo
+mingw64/lib/python2.7/site-packages/numpy/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/_import_tools.py
+mingw64/lib/python2.7/site-packages/numpy/_import_tools.pyc
+mingw64/lib/python2.7/site-packages/numpy/_import_tools.pyo
+mingw64/lib/python2.7/site-packages/numpy/add_newdocs.py
+mingw64/lib/python2.7/site-packages/numpy/add_newdocs.pyc
+mingw64/lib/python2.7/site-packages/numpy/add_newdocs.pyo
+mingw64/lib/python2.7/site-packages/numpy/compat/
+mingw64/lib/python2.7/site-packages/numpy/compat/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/compat/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/compat/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.py
+mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.pyc
+mingw64/lib/python2.7/site-packages/numpy/compat/_inspect.pyo
+mingw64/lib/python2.7/site-packages/numpy/compat/py3k.py
+mingw64/lib/python2.7/site-packages/numpy/compat/py3k.pyc
+mingw64/lib/python2.7/site-packages/numpy/compat/py3k.pyo
+mingw64/lib/python2.7/site-packages/numpy/compat/setup.py
+mingw64/lib/python2.7/site-packages/numpy/compat/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/compat/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/
+mingw64/lib/python2.7/site-packages/numpy/core/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/core/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/_dummy.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/_internal.py
+mingw64/lib/python2.7/site-packages/numpy/core/_internal.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/_internal.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/_methods.py
+mingw64/lib/python2.7/site-packages/numpy/core/_methods.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/_methods.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.py
+mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/arrayprint.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/cversions.py
+mingw64/lib/python2.7/site-packages/numpy/core/cversions.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/cversions.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/defchararray.py
+mingw64/lib/python2.7/site-packages/numpy/core/defchararray.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/defchararray.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.py
+mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/fromnumeric.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/function_base.py
+mingw64/lib/python2.7/site-packages/numpy/core/function_base.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/function_base.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.py
+mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/generate_numpy_api.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/getlimits.py
+mingw64/lib/python2.7/site-packages/numpy/core/getlimits.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/getlimits.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/include/
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/_numpyconfig.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/arrayscalars.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/halffloat.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/multiarray_api.txt
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/noprefix.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_3kcompat.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_common.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_cpu.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_endian.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_interrupt.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_math.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/npy_os.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/numpyconfig.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/old_defines.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/oldnumeric.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufunc_api.txt
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h
+mingw64/lib/python2.7/site-packages/numpy/core/include/numpy/utils.h
+mingw64/lib/python2.7/site-packages/numpy/core/info.py
+mingw64/lib/python2.7/site-packages/numpy/core/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/lib/
+mingw64/lib/python2.7/site-packages/numpy/core/lib/libnpymath.a
+mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/
+mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini
+mingw64/lib/python2.7/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini
+mingw64/lib/python2.7/site-packages/numpy/core/machar.py
+mingw64/lib/python2.7/site-packages/numpy/core/machar.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/machar.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/memmap.py
+mingw64/lib/python2.7/site-packages/numpy/core/memmap.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/memmap.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/multiarray.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/multiarray_tests.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/numeric.py
+mingw64/lib/python2.7/site-packages/numpy/core/numeric.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/numeric.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.py
+mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/numerictypes.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/operand_flag_tests.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/records.py
+mingw64/lib/python2.7/site-packages/numpy/core/records.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/records.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/setup.py
+mingw64/lib/python2.7/site-packages/numpy/core/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/setup_common.py
+mingw64/lib/python2.7/site-packages/numpy/core/setup_common.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/setup_common.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/shape_base.py
+mingw64/lib/python2.7/site-packages/numpy/core/shape_base.pyc
+mingw64/lib/python2.7/site-packages/numpy/core/shape_base.pyo
+mingw64/lib/python2.7/site-packages/numpy/core/struct_ufunc_test.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/test_rational.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/tests/
+mingw64/lib/python2.7/site-packages/numpy/core/tests/data/
+mingw64/lib/python2.7/site-packages/numpy/core/tests/data/astype_copy.pkl
+mingw64/lib/python2.7/site-packages/numpy/core/tests/data/recarray_from_file.fits
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_abc.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_api.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_arrayprint.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_datetime.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_defchararray.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_deprecations.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_dtype.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_einsum.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_errstate.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_extint128.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_function_base.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_getlimits.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_half.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexerrors.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_indexing.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_item_selection.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_longdouble.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_machar.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_mem_overlap.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_memmap.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_multiarray.py.orig
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_nditer.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numeric.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_numerictypes.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_print.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_records.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarinherit.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarmath.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_scalarprint.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_shape_base.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_ufunc.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_umath_complex.py
+mingw64/lib/python2.7/site-packages/numpy/core/tests/test_unicode.py
+mingw64/lib/python2.7/site-packages/numpy/core/umath.pyd
+mingw64/lib/python2.7/site-packages/numpy/core/umath_tests.pyd
+mingw64/lib/python2.7/site-packages/numpy/ctypeslib.py
+mingw64/lib/python2.7/site-packages/numpy/ctypeslib.pyc
+mingw64/lib/python2.7/site-packages/numpy/ctypeslib.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/
+mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/__config__.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/__version__.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/ccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/autodist.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/bdist_rpm.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_clib.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_ext.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_py.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_scripts.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/build_src.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/config_compiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/develop.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/egg_info.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_clib.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_data.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/install_headers.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/command/sdist.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/compat.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/compat.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/compat.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/conv_template.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/core.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/core.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/core.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/cpuinfo.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/environment.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/environment.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/environment.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/exec_command.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/extension.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/extension.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/extension.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/absoft.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/compaq.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/g95.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/gnu.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/hpux.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/ibm.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/intel.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/lahey.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/mips.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/nag.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/none.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pathf95.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/pg.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/sun.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/fcompiler/vast.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/from_template.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/info.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/intelccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/lib2def.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/line_endings.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/log.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/log.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/log.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/
+mingw64/lib/python2.7/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c
+mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/mingw32ccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/misc_util.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvc9compiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/msvccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/npy_pkg_config.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/numpy_distribution.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/pathccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/setup.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/system_info.pyo
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_exec_command.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_fcompiler_intel.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_misc_util.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_npy_pkg_config.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/tests/test_system_info.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.py
+mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.pyc
+mingw64/lib/python2.7/site-packages/numpy/distutils/unixccompiler.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/
+mingw64/lib/python2.7/site-packages/numpy/doc/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/doc/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/basics.py
+mingw64/lib/python2.7/site-packages/numpy/doc/basics.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/basics.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.py
+mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/broadcasting.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.py
+mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/byteswapping.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/constants.py
+mingw64/lib/python2.7/site-packages/numpy/doc/constants.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/constants.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/creation.py
+mingw64/lib/python2.7/site-packages/numpy/doc/creation.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/creation.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/glossary.py
+mingw64/lib/python2.7/site-packages/numpy/doc/glossary.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/glossary.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/indexing.py
+mingw64/lib/python2.7/site-packages/numpy/doc/indexing.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/indexing.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/internals.py
+mingw64/lib/python2.7/site-packages/numpy/doc/internals.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/internals.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/misc.py
+mingw64/lib/python2.7/site-packages/numpy/doc/misc.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/misc.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.py
+mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/structured_arrays.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.py
+mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/subclassing.pyo
+mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.py
+mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.pyc
+mingw64/lib/python2.7/site-packages/numpy/doc/ufuncs.pyo
+mingw64/lib/python2.7/site-packages/numpy/dual.py
+mingw64/lib/python2.7/site-packages/numpy/dual.pyc
+mingw64/lib/python2.7/site-packages/numpy/dual.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/
+mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/__main__.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/__version__.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/auxfuncs.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/capi_maps.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/cb_rules.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/cfuncs.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/common_rules.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/crackfortran.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/diagnose.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py2e.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/f2py_testing.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/f90mod_rules.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/func2subr.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/info.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/rules.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/rules.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/rules.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/setup.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/f2py/src/
+mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c
+mingw64/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/kind/foo.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo.f
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/regression/inout.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/src/size/foo.f90
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_array_from_pyobj.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_assumed_shape.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_callback.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_kind.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_mixed.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_character.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_complex.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_integer.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_logical.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_return_real.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/test_size.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/tests/util.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.py
+mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.pyc
+mingw64/lib/python2.7/site-packages/numpy/f2py/use_rules.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/
+mingw64/lib/python2.7/site-packages/numpy/fft/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/fft/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/fft/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.py
+mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.pyc
+mingw64/lib/python2.7/site-packages/numpy/fft/fftpack.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/fftpack_lite.pyd
+mingw64/lib/python2.7/site-packages/numpy/fft/helper.py
+mingw64/lib/python2.7/site-packages/numpy/fft/helper.pyc
+mingw64/lib/python2.7/site-packages/numpy/fft/helper.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/info.py
+mingw64/lib/python2.7/site-packages/numpy/fft/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/fft/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/setup.py
+mingw64/lib/python2.7/site-packages/numpy/fft/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/fft/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/fft/tests/
+mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_fftpack.py
+mingw64/lib/python2.7/site-packages/numpy/fft/tests/test_helper.py
+mingw64/lib/python2.7/site-packages/numpy/lib/
+mingw64/lib/python2.7/site-packages/numpy/lib/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/lib/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.py
+mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/_datasource.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.py
+mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/_iotools.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/_version.py
+mingw64/lib/python2.7/site-packages/numpy/lib/_version.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/_version.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.py
+mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/arraypad.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.py
+mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/arraysetops.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.py
+mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/arrayterator.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/financial.py
+mingw64/lib/python2.7/site-packages/numpy/lib/financial.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/financial.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/format.py
+mingw64/lib/python2.7/site-packages/numpy/lib/format.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/format.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/function_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/function_base.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/function_base.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.py
+mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/index_tricks.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/info.py
+mingw64/lib/python2.7/site-packages/numpy/lib/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.py
+mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/nanfunctions.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/npyio.py
+mingw64/lib/python2.7/site-packages/numpy/lib/npyio.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/npyio.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.py
+mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/polynomial.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.py
+mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/recfunctions.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/scimath.py
+mingw64/lib/python2.7/site-packages/numpy/lib/scimath.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/scimath.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/setup.py
+mingw64/lib/python2.7/site-packages/numpy/lib/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/shape_base.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.py
+mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/stride_tricks.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npy
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py2-objarr.npz
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npy
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/py3-objarr.npz
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/python3.npy
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/data/win64python2.npy
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__datasource.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__iotools.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test__version.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraypad.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arraysetops.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_arrayterator.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_financial.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_format.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_function_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_index_tricks.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_io.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_nanfunctions.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_packbits.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_polynomial.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_recfunctions.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_shape_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_stride_tricks.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_twodim_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_type_check.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_ufunclike.py
+mingw64/lib/python2.7/site-packages/numpy/lib/tests/test_utils.py
+mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.py
+mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/twodim_base.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/type_check.py
+mingw64/lib/python2.7/site-packages/numpy/lib/type_check.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/type_check.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.py
+mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/ufunclike.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/user_array.py
+mingw64/lib/python2.7/site-packages/numpy/lib/user_array.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/user_array.pyo
+mingw64/lib/python2.7/site-packages/numpy/lib/utils.py
+mingw64/lib/python2.7/site-packages/numpy/lib/utils.pyc
+mingw64/lib/python2.7/site-packages/numpy/lib/utils.pyo
+mingw64/lib/python2.7/site-packages/numpy/linalg/
+mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/linalg/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/linalg/_umath_linalg.pyd
+mingw64/lib/python2.7/site-packages/numpy/linalg/info.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/linalg/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/linalg/lapack_lite.pyd
+mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.pyc
+mingw64/lib/python2.7/site-packages/numpy/linalg/linalg.pyo
+mingw64/lib/python2.7/site-packages/numpy/linalg/setup.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/linalg/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/linalg/tests/
+mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_build.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_deprecations.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_linalg.py
+mingw64/lib/python2.7/site-packages/numpy/linalg/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/ma/
+mingw64/lib/python2.7/site-packages/numpy/ma/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/ma/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/bench.py
+mingw64/lib/python2.7/site-packages/numpy/ma/bench.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/bench.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/core.py
+mingw64/lib/python2.7/site-packages/numpy/ma/core.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/core.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/extras.py
+mingw64/lib/python2.7/site-packages/numpy/ma/extras.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/extras.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.py
+mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/mrecords.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/setup.py
+mingw64/lib/python2.7/site-packages/numpy/ma/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_core.py
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_extras.py
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_mrecords.py
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_old_ma.py
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/ma/tests/test_subclassing.py
+mingw64/lib/python2.7/site-packages/numpy/ma/testutils.py
+mingw64/lib/python2.7/site-packages/numpy/ma/testutils.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/testutils.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.py
+mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/timer_comparison.pyo
+mingw64/lib/python2.7/site-packages/numpy/ma/version.py
+mingw64/lib/python2.7/site-packages/numpy/ma/version.pyc
+mingw64/lib/python2.7/site-packages/numpy/ma/version.pyo
+mingw64/lib/python2.7/site-packages/numpy/matlib.py
+mingw64/lib/python2.7/site-packages/numpy/matlib.pyc
+mingw64/lib/python2.7/site-packages/numpy/matlib.pyo
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyc
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyo
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_defmatrix.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_multiarray.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_numeric.py
+mingw64/lib/python2.7/site-packages/numpy/matrixlib/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/
+mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/_polybase.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/chebyshev.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/hermite_e.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/laguerre.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/legendre.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polynomial.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/polyutils.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/polynomial/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_chebyshev.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_classes.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_hermite_e.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_laguerre.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_legendre.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polynomial.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_polyutils.py
+mingw64/lib/python2.7/site-packages/numpy/polynomial/tests/test_printing.py
+mingw64/lib/python2.7/site-packages/numpy/random/
+mingw64/lib/python2.7/site-packages/numpy/random/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/random/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/random/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/random/info.py
+mingw64/lib/python2.7/site-packages/numpy/random/info.pyc
+mingw64/lib/python2.7/site-packages/numpy/random/info.pyo
+mingw64/lib/python2.7/site-packages/numpy/random/mtrand.pyd
+mingw64/lib/python2.7/site-packages/numpy/random/randomkit.h
+mingw64/lib/python2.7/site-packages/numpy/random/setup.py
+mingw64/lib/python2.7/site-packages/numpy/random/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/random/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/random/tests/
+mingw64/lib/python2.7/site-packages/numpy/random/tests/test_random.py
+mingw64/lib/python2.7/site-packages/numpy/random/tests/test_regression.py
+mingw64/lib/python2.7/site-packages/numpy/setup.py
+mingw64/lib/python2.7/site-packages/numpy/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/
+mingw64/lib/python2.7/site-packages/numpy/testing/__init__.py
+mingw64/lib/python2.7/site-packages/numpy/testing/__init__.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/__init__.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/decorators.py
+mingw64/lib/python2.7/site-packages/numpy/testing/decorators.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/decorators.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.py
+mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/noseclasses.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.py
+mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/nosetester.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.py
+mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/print_coercion_tables.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/setup.py
+mingw64/lib/python2.7/site-packages/numpy/testing/setup.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/setup.pyo
+mingw64/lib/python2.7/site-packages/numpy/testing/tests/
+mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_decorators.py
+mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_doctesting.py
+mingw64/lib/python2.7/site-packages/numpy/testing/tests/test_utils.py
+mingw64/lib/python2.7/site-packages/numpy/testing/utils.py
+mingw64/lib/python2.7/site-packages/numpy/testing/utils.pyc
+mingw64/lib/python2.7/site-packages/numpy/testing/utils.pyo
+mingw64/lib/python2.7/site-packages/numpy/tests/
+mingw64/lib/python2.7/site-packages/numpy/tests/test_ctypeslib.py
+mingw64/lib/python2.7/site-packages/numpy/tests/test_matlib.py
+mingw64/lib/python2.7/site-packages/numpy/tests/test_numpy_version.py
+mingw64/lib/python2.7/site-packages/numpy/tests/test_scripts.py
+mingw64/lib/python2.7/site-packages/numpy/version.py
+mingw64/lib/python2.7/site-packages/numpy/version.pyc
+mingw64/lib/python2.7/site-packages/numpy/version.pyo
+mingw64/share/
+mingw64/share/licenses/
+mingw64/share/licenses/python2-numpy/
+mingw64/share/licenses/python2-numpy/LICENSE.txt
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-python2-numpy-1.11.0-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..807e7ddac269f79decbf48c8785871ee9a3d5dc6
GIT binary patch
literal 47184
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
I8e5qd07Ui(;Q#;t

literal 0
HcmV?d00001

-- 
GitLab